summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorEndi Sukma Dewata <edewata@redhat.com>2012-03-24 02:27:47 -0500
committerEndi Sukma Dewata <edewata@redhat.com>2012-03-26 11:43:54 -0500
commit621d9e5c413e561293d7484b93882d985b3fe15f (patch)
tree638f3d75761c121d9a8fb50b52a12a6686c5ac5c /base
parent40d3643b8d91886bf210aa27f711731c81a11e49 (diff)
downloadpki-621d9e5c413e561293d7484b93882d985b3fe15f.tar.gz
pki-621d9e5c413e561293d7484b93882d985b3fe15f.tar.xz
pki-621d9e5c413e561293d7484b93882d985b3fe15f.zip
Removed unnecessary pki folder.
Previously the source code was located inside a pki folder. This folder was created during svn migration and is no longer needed. This folder has now been removed and the contents have been moved up one level. Ticket #131
Diffstat (limited to 'base')
-rw-r--r--base/CMakeLists.txt33
-rw-r--r--base/ca/CMakeLists.txt64
-rw-r--r--base/ca/LICENSE291
-rw-r--r--base/ca/setup/CMakeLists.txt8
-rw-r--r--base/ca/setup/registry_instance63
-rw-r--r--base/ca/shared/conf/CMakeLists.txt12
-rw-r--r--base/ca/shared/conf/CS.cfg.in1108
-rw-r--r--base/ca/shared/conf/acl.ldif53
-rw-r--r--base/ca/shared/conf/adminCert.profile39
-rw-r--r--base/ca/shared/conf/caAuditSigningCert.profile35
-rw-r--r--base/ca/shared/conf/caCert.profile44
-rw-r--r--base/ca/shared/conf/caOCSPCert.profile42
-rw-r--r--base/ca/shared/conf/catalina.policy184
-rw-r--r--base/ca/shared/conf/catalina.properties87
-rw-r--r--base/ca/shared/conf/context.xml40
-rw-r--r--base/ca/shared/conf/database.ldif4
-rw-r--r--base/ca/shared/conf/db.ldif163
-rw-r--r--base/ca/shared/conf/flatfile.txt2
-rw-r--r--base/ca/shared/conf/index.ldif198
-rw-r--r--base/ca/shared/conf/jk2.manifest2
-rw-r--r--base/ca/shared/conf/jk2.properties26
-rw-r--r--base/ca/shared/conf/jkconf.ant.xml51
-rw-r--r--base/ca/shared/conf/jkconfig.manifest2
-rw-r--r--base/ca/shared/conf/logging.properties70
-rw-r--r--base/ca/shared/conf/manager.ldif48
-rw-r--r--base/ca/shared/conf/proxy.conf34
-rw-r--r--base/ca/shared/conf/registry.cfg232
-rw-r--r--base/ca/shared/conf/schema.ldif489
-rw-r--r--base/ca/shared/conf/server-minimal.xml25
-rw-r--r--base/ca/shared/conf/server.xml277
-rw-r--r--base/ca/shared/conf/serverCert.profile39
-rw-r--r--base/ca/shared/conf/serverCertNick.conf1
-rw-r--r--base/ca/shared/conf/shm.manifest2
-rw-r--r--base/ca/shared/conf/subsystemCert.profile39
-rw-r--r--base/ca/shared/conf/tomcat-jk2.manifest7
-rw-r--r--base/ca/shared/conf/tomcat-users.xml45
-rw-r--r--base/ca/shared/conf/tomcat6.conf58
-rw-r--r--base/ca/shared/conf/uriworkermap.properties13
-rw-r--r--base/ca/shared/conf/vlv.ldif544
-rw-r--r--base/ca/shared/conf/vlvtasks.ldif40
-rw-r--r--base/ca/shared/conf/web.xml989
-rw-r--r--base/ca/shared/conf/workers.properties206
-rw-r--r--base/ca/shared/conf/workers.properties.minimal17
-rw-r--r--base/ca/shared/conf/workers2.properties132
-rw-r--r--base/ca/shared/conf/workers2.properties.minimal55
-rw-r--r--base/ca/shared/emails/ExpiredUnpublishJob6
-rw-r--r--base/ca/shared/emails/ExpiredUnpublishJobItem2
-rw-r--r--base/ca/shared/emails/certIssued_CA12
-rw-r--r--base/ca/shared/emails/certIssued_CA.html17
-rw-r--r--base/ca/shared/emails/certIssued_RA12
-rw-r--r--base/ca/shared/emails/certIssued_RA.html17
-rw-r--r--base/ca/shared/emails/certRequestRejected.html10
-rw-r--r--base/ca/shared/emails/certRevoked_CA12
-rw-r--r--base/ca/shared/emails/certRevoked_CA.html13
-rw-r--r--base/ca/shared/emails/certRevoked_RA12
-rw-r--r--base/ca/shared/emails/certRevoked_RA.html13
-rw-r--r--base/ca/shared/emails/euJob1.html29
-rw-r--r--base/ca/shared/emails/euJob1Item.html11
-rw-r--r--base/ca/shared/emails/publishCerts.html29
-rw-r--r--base/ca/shared/emails/publishCertsItem.html11
-rw-r--r--base/ca/shared/emails/reqInQueue_CA5
-rw-r--r--base/ca/shared/emails/reqInQueue_CA.html12
-rw-r--r--base/ca/shared/emails/reqInQueue_RA5
-rw-r--r--base/ca/shared/emails/reqInQueue_RA.html12
-rw-r--r--base/ca/shared/emails/riq1Item.html5
-rw-r--r--base/ca/shared/emails/riq1Summary.html12
-rw-r--r--base/ca/shared/emails/rnJob1.txt8
-rw-r--r--base/ca/shared/emails/rnJob1Item.txt8
-rw-r--r--base/ca/shared/emails/rnJob1Summary.txt7
-rwxr-xr-xbase/ca/shared/etc/init.d/pki-cad87
-rw-r--r--base/ca/shared/lib/systemd/system/pki-cad.target8
-rw-r--r--base/ca/shared/lib/systemd/system/pki-cad@.service13
-rw-r--r--base/ca/shared/profiles/ca/DomainController.cfg130
-rw-r--r--base/ca/shared/profiles/ca/caAdminCert.cfg87
-rw-r--r--base/ca/shared/profiles/ca/caAgentFileSigning.cfg86
-rw-r--r--base/ca/shared/profiles/ca/caAgentServerCert.cfg85
-rw-r--r--base/ca/shared/profiles/ca/caCACert.cfg95
-rw-r--r--base/ca/shared/profiles/ca/caCMCUserCert.cfg86
-rw-r--r--base/ca/shared/profiles/ca/caDirUserCert.cfg99
-rwxr-xr-xbase/ca/shared/profiles/ca/caDirUserRenewal.cfg12
-rw-r--r--base/ca/shared/profiles/ca/caDualCert.cfg168
-rw-r--r--base/ca/shared/profiles/ca/caDualRAuserCert.cfg94
-rw-r--r--base/ca/shared/profiles/ca/caECDualCert.cfg168
-rw-r--r--base/ca/shared/profiles/ca/caECUserCert.cfg101
-rw-r--r--base/ca/shared/profiles/ca/caEncECUserCert.cfg93
-rw-r--r--base/ca/shared/profiles/ca/caEncUserCert.cfg96
-rw-r--r--base/ca/shared/profiles/ca/caFullCMCUserCert.cfg85
-rw-r--r--base/ca/shared/profiles/ca/caIPAserviceCert.cfg97
-rw-r--r--base/ca/shared/profiles/ca/caInstallCACert.cfg96
-rw-r--r--base/ca/shared/profiles/ca/caInternalAuthAuditSigningCert.cfg80
-rw-r--r--base/ca/shared/profiles/ca/caInternalAuthDRMstorageCert.cfg86
-rw-r--r--base/ca/shared/profiles/ca/caInternalAuthOCSPCert.cfg71
-rw-r--r--base/ca/shared/profiles/ca/caInternalAuthServerCert.cfg86
-rw-r--r--base/ca/shared/profiles/ca/caInternalAuthSubsystemCert.cfg88
-rw-r--r--base/ca/shared/profiles/ca/caInternalAuthTransportCert.cfg86
-rw-r--r--base/ca/shared/profiles/ca/caJarSigningCert.cfg86
-rwxr-xr-xbase/ca/shared/profiles/ca/caManualRenewal.cfg11
-rw-r--r--base/ca/shared/profiles/ca/caOCSPCert.cfg70
-rw-r--r--base/ca/shared/profiles/ca/caOtherCert.cfg85
-rw-r--r--base/ca/shared/profiles/ca/caRACert.cfg85
-rw-r--r--base/ca/shared/profiles/ca/caRARouterCert.cfg85
-rw-r--r--base/ca/shared/profiles/ca/caRAagentCert.cfg95
-rw-r--r--base/ca/shared/profiles/ca/caRAserverCert.cfg85
-rw-r--r--base/ca/shared/profiles/ca/caRouterCert.cfg85
-rwxr-xr-xbase/ca/shared/profiles/ca/caSSLClientSelfRenewal.cfg9
-rw-r--r--base/ca/shared/profiles/ca/caServerCert.cfg85
-rw-r--r--base/ca/shared/profiles/ca/caSignedLogCert.cfg74
-rw-r--r--base/ca/shared/profiles/ca/caSimpleCMCUserCert.cfg84
-rw-r--r--base/ca/shared/profiles/ca/caTPSCert.cfg85
-rw-r--r--base/ca/shared/profiles/ca/caTempTokenDeviceKeyEnrollment.cfg144
-rw-r--r--base/ca/shared/profiles/ca/caTempTokenUserEncryptionKeyEnrollment.cfg166
-rw-r--r--base/ca/shared/profiles/ca/caTempTokenUserSigningKeyEnrollment.cfg166
-rw-r--r--base/ca/shared/profiles/ca/caTokenDeviceKeyEnrollment.cfg143
-rw-r--r--base/ca/shared/profiles/ca/caTokenMSLoginEnrollment.cfg171
-rw-r--r--base/ca/shared/profiles/ca/caTokenUserEncryptionKeyEnrollment.cfg170
-rw-r--r--base/ca/shared/profiles/ca/caTokenUserEncryptionKeyRenewal.cfg11
-rw-r--r--base/ca/shared/profiles/ca/caTokenUserSigningKeyEnrollment.cfg170
-rw-r--r--base/ca/shared/profiles/ca/caTokenUserSigningKeyRenewal.cfg11
-rw-r--r--base/ca/shared/profiles/ca/caTransportCert.cfg85
-rw-r--r--base/ca/shared/profiles/ca/caUUIDdeviceCert.cfg99
-rw-r--r--base/ca/shared/profiles/ca/caUserCert.cfg101
-rw-r--r--base/ca/shared/profiles/ca/caUserSMIMEcapCert.cfg107
-rw-r--r--base/ca/shared/webapps/ROOT/WEB-INF/web.xml29
-rw-r--r--base/ca/shared/webapps/ROOT/index.jsp94
-rw-r--r--base/ca/shared/webapps/ca/WEB-INF/velocity.properties8
-rw-r--r--base/ca/shared/webapps/ca/WEB-INF/web.xml2480
-rw-r--r--base/ca/src/CMakeLists.txt57
-rw-r--r--base/ca/src/com/netscape/ca/CAPolicy.java138
-rw-r--r--base/ca/src/com/netscape/ca/CAService.java2122
-rw-r--r--base/ca/src/com/netscape/ca/CMSCRLExtensions.java711
-rw-r--r--base/ca/src/com/netscape/ca/CRLIssuingPoint.java3140
-rw-r--r--base/ca/src/com/netscape/ca/CRLWithExpiredCerts.java68
-rw-r--r--base/ca/src/com/netscape/ca/CertificateAuthority.java2024
-rw-r--r--base/ca/src/com/netscape/ca/SigningUnit.java389
-rw-r--r--base/common/CMakeLists.txt16
-rw-r--r--base/common/LICENSE291
-rw-r--r--base/common/setup/CertServer.directory23
-rw-r--r--base/common/setup/menu.xml10
-rw-r--r--base/common/setup/web-app_2_3.dtd1063
-rw-r--r--base/common/src/CMakeLists.txt1095
-rw-r--r--base/common/src/LogMessages.properties2475
-rw-r--r--base/common/src/UserMessages.properties1133
-rw-r--r--base/common/src/com/netscape/certsrv/acls/ACL.java194
-rw-r--r--base/common/src/com/netscape/certsrv/acls/ACLEntry.java245
-rw-r--r--base/common/src/com/netscape/certsrv/acls/ACLsResources.java45
-rw-r--r--base/common/src/com/netscape/certsrv/acls/EACLsException.java148
-rw-r--r--base/common/src/com/netscape/certsrv/acls/IACL.java68
-rw-r--r--base/common/src/com/netscape/certsrv/acls/IACLEntry.java34
-rw-r--r--base/common/src/com/netscape/certsrv/apps/CMS.java1649
-rw-r--r--base/common/src/com/netscape/certsrv/apps/ICMSEngine.java1126
-rw-r--r--base/common/src/com/netscape/certsrv/apps/ICommandQueue.java48
-rw-r--r--base/common/src/com/netscape/certsrv/authentication/AuthCredentials.java105
-rw-r--r--base/common/src/com/netscape/certsrv/authentication/AuthManagerProxy.java59
-rw-r--r--base/common/src/com/netscape/certsrv/authentication/AuthMgrPlugin.java82
-rw-r--r--base/common/src/com/netscape/certsrv/authentication/AuthResources.java44
-rw-r--r--base/common/src/com/netscape/certsrv/authentication/AuthToken.java451
-rw-r--r--base/common/src/com/netscape/certsrv/authentication/EAuthException.java91
-rw-r--r--base/common/src/com/netscape/certsrv/authentication/EAuthInternalError.java39
-rw-r--r--base/common/src/com/netscape/certsrv/authentication/EAuthMgrNotFound.java38
-rw-r--r--base/common/src/com/netscape/certsrv/authentication/EAuthMgrPluginNotFound.java38
-rw-r--r--base/common/src/com/netscape/certsrv/authentication/EAuthUserError.java38
-rw-r--r--base/common/src/com/netscape/certsrv/authentication/ECompSyntaxErr.java38
-rw-r--r--base/common/src/com/netscape/certsrv/authentication/EFormSubjectDN.java38
-rw-r--r--base/common/src/com/netscape/certsrv/authentication/EInvalidCredentials.java38
-rw-r--r--base/common/src/com/netscape/certsrv/authentication/EMissingCredential.java38
-rw-r--r--base/common/src/com/netscape/certsrv/authentication/IAuthCredentials.java45
-rw-r--r--base/common/src/com/netscape/certsrv/authentication/IAuthManager.java112
-rw-r--r--base/common/src/com/netscape/certsrv/authentication/IAuthSubsystem.java239
-rw-r--r--base/common/src/com/netscape/certsrv/authentication/IAuthToken.java225
-rw-r--r--base/common/src/com/netscape/certsrv/authentication/ISSLClientCertProvider.java42
-rw-r--r--base/common/src/com/netscape/certsrv/authentication/ISharedToken.java32
-rw-r--r--base/common/src/com/netscape/certsrv/authority/IAuthority.java64
-rw-r--r--base/common/src/com/netscape/certsrv/authority/ICertAuthority.java101
-rw-r--r--base/common/src/com/netscape/certsrv/authorization/AuthzManagerProxy.java59
-rw-r--r--base/common/src/com/netscape/certsrv/authorization/AuthzMgrPlugin.java77
-rw-r--r--base/common/src/com/netscape/certsrv/authorization/AuthzResources.java44
-rw-r--r--base/common/src/com/netscape/certsrv/authorization/AuthzToken.java174
-rw-r--r--base/common/src/com/netscape/certsrv/authorization/EAuthzAccessDenied.java38
-rw-r--r--base/common/src/com/netscape/certsrv/authorization/EAuthzException.java91
-rw-r--r--base/common/src/com/netscape/certsrv/authorization/EAuthzInternalError.java38
-rw-r--r--base/common/src/com/netscape/certsrv/authorization/EAuthzMgrNotFound.java38
-rw-r--r--base/common/src/com/netscape/certsrv/authorization/EAuthzMgrPluginNotFound.java38
-rw-r--r--base/common/src/com/netscape/certsrv/authorization/EAuthzUnknownOperation.java38
-rw-r--r--base/common/src/com/netscape/certsrv/authorization/EAuthzUnknownProtectedRes.java38
-rw-r--r--base/common/src/com/netscape/certsrv/authorization/IAuthzManager.java182
-rw-r--r--base/common/src/com/netscape/certsrv/authorization/IAuthzSubsystem.java162
-rw-r--r--base/common/src/com/netscape/certsrv/base/ASubsystem.java70
-rw-r--r--base/common/src/com/netscape/certsrv/base/AttributeNameHelper.java68
-rw-r--r--base/common/src/com/netscape/certsrv/base/BaseResources.java45
-rw-r--r--base/common/src/com/netscape/certsrv/base/EBaseException.java159
-rw-r--r--base/common/src/com/netscape/certsrv/base/EPropertyNotDefined.java46
-rw-r--r--base/common/src/com/netscape/certsrv/base/EPropertyNotFound.java46
-rw-r--r--base/common/src/com/netscape/certsrv/base/ExtendedPluginInfo.java88
-rw-r--r--base/common/src/com/netscape/certsrv/base/IArgBlock.java283
-rw-r--r--base/common/src/com/netscape/certsrv/base/IAttrSet.java70
-rw-r--r--base/common/src/com/netscape/certsrv/base/IAuthInfo.java31
-rw-r--r--base/common/src/com/netscape/certsrv/base/ICRLPrettyPrint.java48
-rw-r--r--base/common/src/com/netscape/certsrv/base/ICertPrettyPrint.java38
-rw-r--r--base/common/src/com/netscape/certsrv/base/IConfigStore.java297
-rw-r--r--base/common/src/com/netscape/certsrv/base/IConfigStoreEventListener.java48
-rw-r--r--base/common/src/com/netscape/certsrv/base/IExtPrettyPrint.java34
-rw-r--r--base/common/src/com/netscape/certsrv/base/IExtendedPluginInfo.java79
-rw-r--r--base/common/src/com/netscape/certsrv/base/IPluginImpl.java104
-rw-r--r--base/common/src/com/netscape/certsrv/base/IPrettyPrintFormat.java66
-rw-r--r--base/common/src/com/netscape/certsrv/base/ISecurityDomainSessionTable.java48
-rw-r--r--base/common/src/com/netscape/certsrv/base/ISourceConfigStore.java81
-rw-r--r--base/common/src/com/netscape/certsrv/base/ISubsystem.java78
-rw-r--r--base/common/src/com/netscape/certsrv/base/ISubsystemSource.java36
-rw-r--r--base/common/src/com/netscape/certsrv/base/ITimeSource.java41
-rw-r--r--base/common/src/com/netscape/certsrv/base/KeyGenInfo.java229
-rw-r--r--base/common/src/com/netscape/certsrv/base/MessageFormatter.java155
-rw-r--r--base/common/src/com/netscape/certsrv/base/MetaAttributeDef.java198
-rw-r--r--base/common/src/com/netscape/certsrv/base/MetaInfo.java115
-rw-r--r--base/common/src/com/netscape/certsrv/base/Nonces.java123
-rw-r--r--base/common/src/com/netscape/certsrv/base/PasswordResources.java42
-rw-r--r--base/common/src/com/netscape/certsrv/base/Plugin.java59
-rw-r--r--base/common/src/com/netscape/certsrv/base/SessionContext.java166
-rw-r--r--base/common/src/com/netscape/certsrv/ca/CAResources.java42
-rw-r--r--base/common/src/com/netscape/certsrv/ca/ECAException.java91
-rw-r--r--base/common/src/com/netscape/certsrv/ca/EErrorPublishCRL.java42
-rw-r--r--base/common/src/com/netscape/certsrv/ca/ICAService.java90
-rw-r--r--base/common/src/com/netscape/certsrv/ca/ICMSCRLExtension.java72
-rw-r--r--base/common/src/com/netscape/certsrv/ca/ICMSCRLExtensions.java56
-rw-r--r--base/common/src/com/netscape/certsrv/ca/ICRLIssuingPoint.java543
-rw-r--r--base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java503
-rw-r--r--base/common/src/com/netscape/certsrv/cert/ICrossCertPairSubsystem.java62
-rw-r--r--base/common/src/com/netscape/certsrv/client/IDataProcessor.java36
-rw-r--r--base/common/src/com/netscape/certsrv/client/connection/IAuthenticator.java26
-rw-r--r--base/common/src/com/netscape/certsrv/client/connection/IConnection.java50
-rw-r--r--base/common/src/com/netscape/certsrv/client/connection/IConnectionFactory.java43
-rw-r--r--base/common/src/com/netscape/certsrv/common/ConfigConstants.java332
-rw-r--r--base/common/src/com/netscape/certsrv/common/Constants.java731
-rw-r--r--base/common/src/com/netscape/certsrv/common/DestDef.java56
-rw-r--r--base/common/src/com/netscape/certsrv/common/NameValuePairs.java82
-rw-r--r--base/common/src/com/netscape/certsrv/common/OpDef.java38
-rw-r--r--base/common/src/com/netscape/certsrv/common/PrefixDef.java40
-rw-r--r--base/common/src/com/netscape/certsrv/common/ScopeDef.java192
-rw-r--r--base/common/src/com/netscape/certsrv/common/TaskId.java129
-rw-r--r--base/common/src/com/netscape/certsrv/connector/IConnector.java61
-rw-r--r--base/common/src/com/netscape/certsrv/connector/IHttpConnFactory.java51
-rw-r--r--base/common/src/com/netscape/certsrv/connector/IHttpConnection.java41
-rw-r--r--base/common/src/com/netscape/certsrv/connector/IHttpPKIMessage.java58
-rw-r--r--base/common/src/com/netscape/certsrv/connector/IPKIMessage.java71
-rw-r--r--base/common/src/com/netscape/certsrv/connector/IRemoteAuthority.java56
-rw-r--r--base/common/src/com/netscape/certsrv/connector/IRequestEncoder.java49
-rw-r--r--base/common/src/com/netscape/certsrv/connector/IResender.java39
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/DBResources.java38
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/EDBException.java85
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/EDBNotAvailException.java40
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/EDBRecordNotFoundException.java40
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/IDBAttrMapper.java80
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/IDBDynAttrMapper.java22
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/IDBObj.java41
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/IDBRegistry.java171
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/IDBSSession.java213
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/IDBSearchResults.java44
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/IDBSubsystem.java212
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/IDBVirtualList.java144
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/IElementProcessor.java36
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/IFilterConverter.java48
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/Modification.java87
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/ModificationSet.java61
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/certdb/ICertRecord.java176
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/certdb/ICertRecordList.java94
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/certdb/ICertificateRepository.java528
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/certdb/IRevocationInfo.java47
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/crldb/ICRLIssuingPointRecord.java161
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/crldb/ICRLRepository.java181
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRecord.java153
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRecordList.java49
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRepository.java174
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/keydb/KeyId.java122
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/keydb/KeyIdAdapter.java37
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/keydb/KeyState.java106
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/replicadb/IReplicaIDRepository.java30
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/repository/IRepository.java88
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/repository/IRepositoryRecord.java44
-rw-r--r--base/common/src/com/netscape/certsrv/evaluators/IAccessEvaluator.java89
-rw-r--r--base/common/src/com/netscape/certsrv/extensions/EExtensionsException.java58
-rw-r--r--base/common/src/com/netscape/certsrv/extensions/ExtensionsResources.java34
-rw-r--r--base/common/src/com/netscape/certsrv/extensions/ICMSExtension.java74
-rw-r--r--base/common/src/com/netscape/certsrv/jobs/EJobsException.java77
-rw-r--r--base/common/src/com/netscape/certsrv/jobs/IJob.java106
-rw-r--r--base/common/src/com/netscape/certsrv/jobs/IJobCron.java42
-rw-r--r--base/common/src/com/netscape/certsrv/jobs/IJobsScheduler.java162
-rw-r--r--base/common/src/com/netscape/certsrv/jobs/JobPlugin.java72
-rw-r--r--base/common/src/com/netscape/certsrv/jobs/JobsResources.java43
-rw-r--r--base/common/src/com/netscape/certsrv/kra/EKRAException.java94
-rw-r--r--base/common/src/com/netscape/certsrv/kra/IJoinShares.java36
-rw-r--r--base/common/src/com/netscape/certsrv/kra/IKeyRecoveryAuthority.java321
-rw-r--r--base/common/src/com/netscape/certsrv/kra/IKeyService.java179
-rw-r--r--base/common/src/com/netscape/certsrv/kra/IProofOfArchival.java80
-rw-r--r--base/common/src/com/netscape/certsrv/kra/IShare.java33
-rw-r--r--base/common/src/com/netscape/certsrv/kra/KRAResources.java39
-rw-r--r--base/common/src/com/netscape/certsrv/kra/ProofOfArchival.java463
-rw-r--r--base/common/src/com/netscape/certsrv/ldap/ELdapException.java93
-rw-r--r--base/common/src/com/netscape/certsrv/ldap/ELdapServerDownException.java40
-rw-r--r--base/common/src/com/netscape/certsrv/ldap/ILdapAuthInfo.java100
-rw-r--r--base/common/src/com/netscape/certsrv/ldap/ILdapBoundConnFactory.java38
-rw-r--r--base/common/src/com/netscape/certsrv/ldap/ILdapConnFactory.java97
-rw-r--r--base/common/src/com/netscape/certsrv/ldap/ILdapConnInfo.java80
-rw-r--r--base/common/src/com/netscape/certsrv/ldap/ILdapConnModule.java59
-rw-r--r--base/common/src/com/netscape/certsrv/ldap/LdapResources.java42
-rw-r--r--base/common/src/com/netscape/certsrv/listeners/EListenersException.java91
-rw-r--r--base/common/src/com/netscape/certsrv/listeners/IRequestListenerPlugin.java86
-rw-r--r--base/common/src/com/netscape/certsrv/listeners/ListenersResources.java42
-rw-r--r--base/common/src/com/netscape/certsrv/logging/AuditEvent.java347
-rw-r--r--base/common/src/com/netscape/certsrv/logging/AuditFormat.java114
-rw-r--r--base/common/src/com/netscape/certsrv/logging/ConsoleError.java38
-rw-r--r--base/common/src/com/netscape/certsrv/logging/ConsoleLog.java124
-rw-r--r--base/common/src/com/netscape/certsrv/logging/ELogException.java152
-rw-r--r--base/common/src/com/netscape/certsrv/logging/ELogNotFound.java40
-rw-r--r--base/common/src/com/netscape/certsrv/logging/ELogPluginNotFound.java40
-rw-r--r--base/common/src/com/netscape/certsrv/logging/IBundleLogEvent.java37
-rw-r--r--base/common/src/com/netscape/certsrv/logging/ILogEvent.java108
-rw-r--r--base/common/src/com/netscape/certsrv/logging/ILogEventFactory.java52
-rw-r--r--base/common/src/com/netscape/certsrv/logging/ILogEventListener.java135
-rw-r--r--base/common/src/com/netscape/certsrv/logging/ILogQueue.java70
-rw-r--r--base/common/src/com/netscape/certsrv/logging/ILogSubsystem.java108
-rw-r--r--base/common/src/com/netscape/certsrv/logging/ILogger.java492
-rw-r--r--base/common/src/com/netscape/certsrv/logging/LogPlugin.java32
-rw-r--r--base/common/src/com/netscape/certsrv/logging/LogResources.java60
-rw-r--r--base/common/src/com/netscape/certsrv/logging/SignedAuditEvent.java349
-rw-r--r--base/common/src/com/netscape/certsrv/logging/SystemEvent.java348
-rw-r--r--base/common/src/com/netscape/certsrv/notification/ENotificationException.java77
-rw-r--r--base/common/src/com/netscape/certsrv/notification/IEmailFormProcessor.java79
-rw-r--r--base/common/src/com/netscape/certsrv/notification/IEmailResolver.java40
-rw-r--r--base/common/src/com/netscape/certsrv/notification/IEmailResolverKeys.java35
-rw-r--r--base/common/src/com/netscape/certsrv/notification/IEmailTemplate.java48
-rw-r--r--base/common/src/com/netscape/certsrv/notification/IMailNotification.java80
-rw-r--r--base/common/src/com/netscape/certsrv/notification/NotificationResources.java43
-rw-r--r--base/common/src/com/netscape/certsrv/ocsp/IDefStore.java177
-rw-r--r--base/common/src/com/netscape/certsrv/ocsp/IOCSPAuthority.java184
-rw-r--r--base/common/src/com/netscape/certsrv/ocsp/IOCSPService.java77
-rw-r--r--base/common/src/com/netscape/certsrv/ocsp/IOCSPStore.java71
-rw-r--r--base/common/src/com/netscape/certsrv/password/EPasswordCheckException.java91
-rw-r--r--base/common/src/com/netscape/certsrv/password/IConfigPasswordCheck.java43
-rw-r--r--base/common/src/com/netscape/certsrv/password/IPasswordCheck.java43
-rw-r--r--base/common/src/com/netscape/certsrv/pattern/AttrSetCollection.java63
-rw-r--r--base/common/src/com/netscape/certsrv/pattern/Pattern.java162
-rw-r--r--base/common/src/com/netscape/certsrv/policy/EPolicyException.java169
-rw-r--r--base/common/src/com/netscape/certsrv/policy/IEnrollmentPolicy.java35
-rw-r--r--base/common/src/com/netscape/certsrv/policy/IExpression.java61
-rw-r--r--base/common/src/com/netscape/certsrv/policy/IGeneralNameAsConstraintsConfig.java53
-rw-r--r--base/common/src/com/netscape/certsrv/policy/IGeneralNameConfig.java67
-rw-r--r--base/common/src/com/netscape/certsrv/policy/IGeneralNameUtil.java77
-rw-r--r--base/common/src/com/netscape/certsrv/policy/IGeneralNamesAsConstraintsConfig.java53
-rw-r--r--base/common/src/com/netscape/certsrv/policy/IGeneralNamesConfig.java52
-rw-r--r--base/common/src/com/netscape/certsrv/policy/IKeyArchivalPolicy.java33
-rw-r--r--base/common/src/com/netscape/certsrv/policy/IKeyRecoveryPolicy.java33
-rw-r--r--base/common/src/com/netscape/certsrv/policy/IPolicyPredicateParser.java43
-rw-r--r--base/common/src/com/netscape/certsrv/policy/IPolicyProcessor.java196
-rw-r--r--base/common/src/com/netscape/certsrv/policy/IPolicyRule.java128
-rw-r--r--base/common/src/com/netscape/certsrv/policy/IPolicySet.java105
-rw-r--r--base/common/src/com/netscape/certsrv/policy/IRenewalPolicy.java33
-rw-r--r--base/common/src/com/netscape/certsrv/policy/IRevocationPolicy.java33
-rw-r--r--base/common/src/com/netscape/certsrv/policy/ISubjAltNameConfig.java48
-rw-r--r--base/common/src/com/netscape/certsrv/policy/PolicyResources.java45
-rw-r--r--base/common/src/com/netscape/certsrv/profile/CertInfoProfile.java102
-rw-r--r--base/common/src/com/netscape/certsrv/profile/EDeferException.java48
-rw-r--r--base/common/src/com/netscape/certsrv/profile/EProfileException.java47
-rw-r--r--base/common/src/com/netscape/certsrv/profile/ERejectException.java46
-rw-r--r--base/common/src/com/netscape/certsrv/profile/ICertInfoPolicyDefault.java32
-rw-r--r--base/common/src/com/netscape/certsrv/profile/IEnrollProfile.java157
-rw-r--r--base/common/src/com/netscape/certsrv/profile/IPolicyConstraint.java89
-rw-r--r--base/common/src/com/netscape/certsrv/profile/IPolicyDefault.java136
-rw-r--r--base/common/src/com/netscape/certsrv/profile/IProfile.java408
-rw-r--r--base/common/src/com/netscape/certsrv/profile/IProfileAuthenticator.java120
-rw-r--r--base/common/src/com/netscape/certsrv/profile/IProfileContext.java44
-rw-r--r--base/common/src/com/netscape/certsrv/profile/IProfileEx.java36
-rw-r--r--base/common/src/com/netscape/certsrv/profile/IProfileInput.java120
-rw-r--r--base/common/src/com/netscape/certsrv/profile/IProfileOutput.java121
-rw-r--r--base/common/src/com/netscape/certsrv/profile/IProfilePolicy.java49
-rw-r--r--base/common/src/com/netscape/certsrv/profile/IProfileSubsystem.java134
-rw-r--r--base/common/src/com/netscape/certsrv/profile/IProfileUpdater.java77
-rw-r--r--base/common/src/com/netscape/certsrv/property/Descriptor.java93
-rw-r--r--base/common/src/com/netscape/certsrv/property/EPropertyException.java42
-rw-r--r--base/common/src/com/netscape/certsrv/property/IConfigTemplate.java68
-rw-r--r--base/common/src/com/netscape/certsrv/property/IDescriptor.java90
-rw-r--r--base/common/src/com/netscape/certsrv/property/PropertySet.java52
-rw-r--r--base/common/src/com/netscape/certsrv/publish/ECompSyntaxErr.java46
-rw-r--r--base/common/src/com/netscape/certsrv/publish/EMapperNotFound.java42
-rw-r--r--base/common/src/com/netscape/certsrv/publish/EMapperPluginNotFound.java42
-rw-r--r--base/common/src/com/netscape/certsrv/publish/EPublisherNotFound.java42
-rw-r--r--base/common/src/com/netscape/certsrv/publish/EPublisherPluginNotFound.java42
-rw-r--r--base/common/src/com/netscape/certsrv/publish/ERuleNotFound.java42
-rw-r--r--base/common/src/com/netscape/certsrv/publish/ERulePluginNotFound.java42
-rw-r--r--base/common/src/com/netscape/certsrv/publish/ICRLPublisher.java107
-rw-r--r--base/common/src/com/netscape/certsrv/publish/ILdapCertMapper.java70
-rw-r--r--base/common/src/com/netscape/certsrv/publish/ILdapCrlMapper.java60
-rw-r--r--base/common/src/com/netscape/certsrv/publish/ILdapExpression.java69
-rw-r--r--base/common/src/com/netscape/certsrv/publish/ILdapMapper.java80
-rw-r--r--base/common/src/com/netscape/certsrv/publish/ILdapPlugin.java45
-rw-r--r--base/common/src/com/netscape/certsrv/publish/ILdapPluginImpl.java53
-rw-r--r--base/common/src/com/netscape/certsrv/publish/ILdapPublishModule.java43
-rw-r--r--base/common/src/com/netscape/certsrv/publish/ILdapPublisher.java84
-rw-r--r--base/common/src/com/netscape/certsrv/publish/ILdapRule.java77
-rw-r--r--base/common/src/com/netscape/certsrv/publish/IPublishRuleSet.java122
-rw-r--r--base/common/src/com/netscape/certsrv/publish/IPublisherProcessor.java360
-rw-r--r--base/common/src/com/netscape/certsrv/publish/IXcertPublisherProcessor.java38
-rw-r--r--base/common/src/com/netscape/certsrv/publish/LdapCertMapResult.java56
-rw-r--r--base/common/src/com/netscape/certsrv/publish/MapperPlugin.java39
-rw-r--r--base/common/src/com/netscape/certsrv/publish/MapperProxy.java62
-rw-r--r--base/common/src/com/netscape/certsrv/publish/PublisherPlugin.java40
-rw-r--r--base/common/src/com/netscape/certsrv/publish/PublisherProxy.java60
-rw-r--r--base/common/src/com/netscape/certsrv/publish/RulePlugin.java40
-rw-r--r--base/common/src/com/netscape/certsrv/ra/IRAService.java62
-rw-r--r--base/common/src/com/netscape/certsrv/ra/IRegistrationAuthority.java170
-rw-r--r--base/common/src/com/netscape/certsrv/registry/ERegistryException.java42
-rw-r--r--base/common/src/com/netscape/certsrv/registry/IPluginInfo.java61
-rw-r--r--base/common/src/com/netscape/certsrv/registry/IPluginRegistry.java91
-rw-r--r--base/common/src/com/netscape/certsrv/request/ARequestNotifier.java546
-rw-r--r--base/common/src/com/netscape/certsrv/request/AgentApproval.java66
-rw-r--r--base/common/src/com/netscape/certsrv/request/AgentApprovals.java159
-rw-r--r--base/common/src/com/netscape/certsrv/request/IEnrollmentRequest.java30
-rw-r--r--base/common/src/com/netscape/certsrv/request/INotify.java40
-rw-r--r--base/common/src/com/netscape/certsrv/request/IPolicy.java53
-rw-r--r--base/common/src/com/netscape/certsrv/request/IRequest.java764
-rw-r--r--base/common/src/com/netscape/certsrv/request/IRequestList.java56
-rw-r--r--base/common/src/com/netscape/certsrv/request/IRequestListener.java54
-rw-r--r--base/common/src/com/netscape/certsrv/request/IRequestNotifier.java130
-rw-r--r--base/common/src/com/netscape/certsrv/request/IRequestQueue.java403
-rw-r--r--base/common/src/com/netscape/certsrv/request/IRequestRecord.java112
-rw-r--r--base/common/src/com/netscape/certsrv/request/IRequestScheduler.java45
-rw-r--r--base/common/src/com/netscape/certsrv/request/IRequestSubsystem.java105
-rw-r--r--base/common/src/com/netscape/certsrv/request/IRequestVirtualList.java50
-rw-r--r--base/common/src/com/netscape/certsrv/request/IService.java48
-rw-r--r--base/common/src/com/netscape/certsrv/request/PolicyMessage.java46
-rw-r--r--base/common/src/com/netscape/certsrv/request/PolicyResult.java35
-rw-r--r--base/common/src/com/netscape/certsrv/request/RequestId.java121
-rw-r--r--base/common/src/com/netscape/certsrv/request/RequestIdAdapter.java37
-rw-r--r--base/common/src/com/netscape/certsrv/request/RequestStatus.java182
-rw-r--r--base/common/src/com/netscape/certsrv/request/ldap/IRequestMod.java55
-rw-r--r--base/common/src/com/netscape/certsrv/security/Credential.java64
-rw-r--r--base/common/src/com/netscape/certsrv/security/ICryptoSubsystem.java472
-rw-r--r--base/common/src/com/netscape/certsrv/security/IEncryptionUnit.java175
-rw-r--r--base/common/src/com/netscape/certsrv/security/ISigningUnit.java164
-rw-r--r--base/common/src/com/netscape/certsrv/security/IStorageKeyUnit.java99
-rw-r--r--base/common/src/com/netscape/certsrv/security/IToken.java41
-rw-r--r--base/common/src/com/netscape/certsrv/security/ITransportKeyUnit.java111
-rw-r--r--base/common/src/com/netscape/certsrv/security/KeyCertData.java821
-rw-r--r--base/common/src/com/netscape/certsrv/selftests/EDuplicateSelfTestException.java216
-rw-r--r--base/common/src/com/netscape/certsrv/selftests/EInvalidSelfTestException.java216
-rw-r--r--base/common/src/com/netscape/certsrv/selftests/EMissingSelfTestException.java225
-rw-r--r--base/common/src/com/netscape/certsrv/selftests/ESelfTestException.java118
-rw-r--r--base/common/src/com/netscape/certsrv/selftests/ISelfTest.java133
-rw-r--r--base/common/src/com/netscape/certsrv/selftests/ISelfTestSubsystem.java338
-rw-r--r--base/common/src/com/netscape/certsrv/selftests/SelfTestResources.java39
-rw-r--r--base/common/src/com/netscape/certsrv/template/ArgList.java68
-rw-r--r--base/common/src/com/netscape/certsrv/template/ArgSet.java74
-rw-r--r--base/common/src/com/netscape/certsrv/template/ArgString.java45
-rw-r--r--base/common/src/com/netscape/certsrv/template/IArgValue.java28
-rw-r--r--base/common/src/com/netscape/certsrv/tks/ITKSAuthority.java56
-rw-r--r--base/common/src/com/netscape/certsrv/usrgrp/Certificates.java49
-rw-r--r--base/common/src/com/netscape/certsrv/usrgrp/EUsrGrpException.java87
-rw-r--r--base/common/src/com/netscape/certsrv/usrgrp/ICertUserLocator.java49
-rw-r--r--base/common/src/com/netscape/certsrv/usrgrp/IGroup.java74
-rw-r--r--base/common/src/com/netscape/certsrv/usrgrp/IGroupConstants.java46
-rw-r--r--base/common/src/com/netscape/certsrv/usrgrp/IIdEvaluator.java39
-rw-r--r--base/common/src/com/netscape/certsrv/usrgrp/IUGSubsystem.java260
-rw-r--r--base/common/src/com/netscape/certsrv/usrgrp/IUser.java171
-rw-r--r--base/common/src/com/netscape/certsrv/usrgrp/IUserConstants.java66
-rw-r--r--base/common/src/com/netscape/certsrv/usrgrp/IUsrGrp.java117
-rw-r--r--base/common/src/com/netscape/certsrv/usrgrp/UsrGrpResources.java46
-rw-r--r--base/common/src/com/netscape/certsrv/util/HttpInput.java258
-rw-r--r--base/common/src/com/netscape/certsrv/util/IStatsSubsystem.java61
-rw-r--r--base/common/src/com/netscape/certsrv/util/StatsEvent.java175
-rw-r--r--base/common/src/com/netscape/cms/authentication/AVAPattern.java559
-rw-r--r--base/common/src/com/netscape/cms/authentication/AgentCertAuthentication.java332
-rw-r--r--base/common/src/com/netscape/cms/authentication/CMCAuth.java1038
-rw-r--r--base/common/src/com/netscape/cms/authentication/Crypt.java438
-rw-r--r--base/common/src/com/netscape/cms/authentication/DNPattern.java216
-rw-r--r--base/common/src/com/netscape/cms/authentication/DirBasedAuthentication.java676
-rw-r--r--base/common/src/com/netscape/cms/authentication/FlatFileAuth.java686
-rw-r--r--base/common/src/com/netscape/cms/authentication/HashAuthData.java118
-rw-r--r--base/common/src/com/netscape/cms/authentication/HashAuthentication.java288
-rw-r--r--base/common/src/com/netscape/cms/authentication/PortalEnroll.java468
-rw-r--r--base/common/src/com/netscape/cms/authentication/RDNPattern.java232
-rw-r--r--base/common/src/com/netscape/cms/authentication/SSLclientCertAuthentication.java358
-rw-r--r--base/common/src/com/netscape/cms/authentication/SharedSecret.java38
-rw-r--r--base/common/src/com/netscape/cms/authentication/TokenAuthentication.java304
-rw-r--r--base/common/src/com/netscape/cms/authentication/UdnPwdDirAuthentication.java189
-rw-r--r--base/common/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java269
-rw-r--r--base/common/src/com/netscape/cms/authentication/UidPwdPinDirAuthentication.java464
-rw-r--r--base/common/src/com/netscape/cms/authorization/AAclAuthz.java858
-rw-r--r--base/common/src/com/netscape/cms/authorization/BasicAclAuthz.java217
-rw-r--r--base/common/src/com/netscape/cms/authorization/DirAclAuthz.java366
-rw-r--r--base/common/src/com/netscape/cms/crl/CMSAuthInfoAccessExtension.java259
-rw-r--r--base/common/src/com/netscape/cms/crl/CMSAuthorityKeyIdentifierExtension.java165
-rw-r--r--base/common/src/com/netscape/cms/crl/CMSCRLNumberExtension.java107
-rw-r--r--base/common/src/com/netscape/cms/crl/CMSCRLReasonExtension.java96
-rw-r--r--base/common/src/com/netscape/cms/crl/CMSCertificateIssuerExtension.java224
-rw-r--r--base/common/src/com/netscape/cms/crl/CMSDeltaCRLIndicatorExtension.java108
-rw-r--r--base/common/src/com/netscape/cms/crl/CMSFreshestCRLExtension.java232
-rw-r--r--base/common/src/com/netscape/cms/crl/CMSHoldInstructionExtension.java153
-rw-r--r--base/common/src/com/netscape/cms/crl/CMSInvalidityDateExtension.java99
-rw-r--r--base/common/src/com/netscape/cms/crl/CMSIssuerAlternativeNameExtension.java284
-rw-r--r--base/common/src/com/netscape/cms/crl/CMSIssuingDistributionPointExtension.java332
-rw-r--r--base/common/src/com/netscape/cms/evaluators/GroupAccessEvaluator.java183
-rw-r--r--base/common/src/com/netscape/cms/evaluators/IPAddressAccessEvaluator.java128
-rw-r--r--base/common/src/com/netscape/cms/evaluators/UserAccessEvaluator.java153
-rw-r--r--base/common/src/com/netscape/cms/evaluators/UserOrigReqAccessEvaluator.java165
-rw-r--r--base/common/src/com/netscape/cms/jobs/AJobBase.java301
-rw-r--r--base/common/src/com/netscape/cms/jobs/PublishCertsJob.java392
-rw-r--r--base/common/src/com/netscape/cms/jobs/RenewalNotificationJob.java706
-rw-r--r--base/common/src/com/netscape/cms/jobs/RequestInQueueJob.java217
-rw-r--r--base/common/src/com/netscape/cms/jobs/UnpublishExpiredJob.java385
-rw-r--r--base/common/src/com/netscape/cms/listeners/CertificateIssuedListener.java450
-rw-r--r--base/common/src/com/netscape/cms/listeners/CertificateRevokedListener.java368
-rw-r--r--base/common/src/com/netscape/cms/listeners/PinRemovalListener.java175
-rw-r--r--base/common/src/com/netscape/cms/listeners/RequestInQListener.java283
-rw-r--r--base/common/src/com/netscape/cms/logging/LogEntry.java134
-rw-r--r--base/common/src/com/netscape/cms/logging/LogFile.java1534
-rw-r--r--base/common/src/com/netscape/cms/logging/RollingLogFile.java658
-rw-r--r--base/common/src/com/netscape/cms/notification/MailNotification.java197
-rw-r--r--base/common/src/com/netscape/cms/ocsp/DefStore.java953
-rw-r--r--base/common/src/com/netscape/cms/ocsp/LDAPStore.java750
-rw-r--r--base/common/src/com/netscape/cms/password/PasswordChecker.java103
-rw-r--r--base/common/src/com/netscape/cms/policy/APolicyRule.java363
-rw-r--r--base/common/src/com/netscape/cms/policy/constraints/AgentPolicy.java161
-rw-r--r--base/common/src/com/netscape/cms/policy/constraints/AttributePresentConstraints.java406
-rw-r--r--base/common/src/com/netscape/cms/policy/constraints/DSAKeyConstraints.java252
-rw-r--r--base/common/src/com/netscape/cms/policy/constraints/DefaultRevocation.java104
-rw-r--r--base/common/src/com/netscape/cms/policy/constraints/IssuerConstraints.java216
-rw-r--r--base/common/src/com/netscape/cms/policy/constraints/KeyAlgorithmConstraints.java225
-rw-r--r--base/common/src/com/netscape/cms/policy/constraints/ManualAuthentication.java101
-rw-r--r--base/common/src/com/netscape/cms/policy/constraints/RSAKeyConstraints.java280
-rw-r--r--base/common/src/com/netscape/cms/policy/constraints/RenewalConstraints.java242
-rw-r--r--base/common/src/com/netscape/cms/policy/constraints/RenewalValidityConstraints.java351
-rw-r--r--base/common/src/com/netscape/cms/policy/constraints/RevocationConstraints.java215
-rw-r--r--base/common/src/com/netscape/cms/policy/constraints/SigningAlgorithmConstraints.java449
-rw-r--r--base/common/src/com/netscape/cms/policy/constraints/SubCANameConstraints.java195
-rw-r--r--base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectName.java33
-rw-r--r--base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectNameConstraints.java313
-rw-r--r--base/common/src/com/netscape/cms/policy/constraints/ValidityConstraints.java317
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/AuthInfoAccessExt.java394
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/AuthorityKeyIdentifierExt.java425
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/BasicConstraintsExt.java508
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/CRLDistributionPointsExt.java484
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/CertificatePoliciesExt.java534
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/CertificateRenewalWindowExt.java254
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/CertificateScopeOfUseExt.java326
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/ExtendedKeyUsageExt.java285
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/GenericASN1Ext.java509
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/IssuerAltNameExt.java249
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/KeyUsageExt.java362
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/NSCCommentExt.java293
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/NSCertTypeExt.java535
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/NameConstraintsExt.java475
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/OCSPNoCheckExt.java190
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/PolicyConstraintsExt.java287
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/PolicyMappingsExt.java426
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/PresenceExt.java157
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/PrivateKeyUsagePeriodExt.java252
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/RemoveBasicConstraintsExt.java143
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/SubjAltNameExt.java355
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/SubjectAltNameExt.java331
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/SubjectDirectoryAttributesExt.java428
-rw-r--r--base/common/src/com/netscape/cms/policy/extensions/SubjectKeyIdentifierExt.java377
-rw-r--r--base/common/src/com/netscape/cms/profile/common/BasicProfile.java1171
-rw-r--r--base/common/src/com/netscape/cms/profile/common/CACertCAEnrollProfile.java107
-rw-r--r--base/common/src/com/netscape/cms/profile/common/CAEnrollProfile.java242
-rw-r--r--base/common/src/com/netscape/cms/profile/common/EnrollProfile.java1468
-rw-r--r--base/common/src/com/netscape/cms/profile/common/EnrollProfileContext.java31
-rw-r--r--base/common/src/com/netscape/cms/profile/common/ProfileContext.java39
-rw-r--r--base/common/src/com/netscape/cms/profile/common/ProfilePolicy.java53
-rw-r--r--base/common/src/com/netscape/cms/profile/common/RAEnrollProfile.java128
-rw-r--r--base/common/src/com/netscape/cms/profile/common/ServerCertCAEnrollProfile.java100
-rw-r--r--base/common/src/com/netscape/cms/profile/common/UserCertCAEnrollProfile.java100
-rw-r--r--base/common/src/com/netscape/cms/profile/constraint/BasicConstraintsExtConstraint.java224
-rw-r--r--base/common/src/com/netscape/cms/profile/constraint/CAEnrollConstraint.java48
-rw-r--r--base/common/src/com/netscape/cms/profile/constraint/CAValidityConstraint.java139
-rw-r--r--base/common/src/com/netscape/cms/profile/constraint/EnrollConstraint.java214
-rw-r--r--base/common/src/com/netscape/cms/profile/constraint/ExtendedKeyUsageExtConstraint.java156
-rw-r--r--base/common/src/com/netscape/cms/profile/constraint/ExtensionConstraint.java146
-rw-r--r--base/common/src/com/netscape/cms/profile/constraint/KeyConstraint.java644
-rw-r--r--base/common/src/com/netscape/cms/profile/constraint/KeyUsageExtConstraint.java291
-rw-r--r--base/common/src/com/netscape/cms/profile/constraint/NSCertTypeExtConstraint.java243
-rw-r--r--base/common/src/com/netscape/cms/profile/constraint/NoConstraint.java101
-rw-r--r--base/common/src/com/netscape/cms/profile/constraint/RenewGracePeriodConstraint.java165
-rw-r--r--base/common/src/com/netscape/cms/profile/constraint/SigningAlgConstraint.java160
-rw-r--r--base/common/src/com/netscape/cms/profile/constraint/SubjectNameConstraint.java136
-rw-r--r--base/common/src/com/netscape/cms/profile/constraint/UniqueKeyConstraint.java295
-rw-r--r--base/common/src/com/netscape/cms/profile/constraint/UniqueSubjectNameConstraint.java251
-rw-r--r--base/common/src/com/netscape/cms/profile/constraint/ValidityConstraint.java218
-rw-r--r--base/common/src/com/netscape/cms/profile/def/AuthInfoAccessExtDefault.java454
-rw-r--r--base/common/src/com/netscape/cms/profile/def/AuthTokenSubjectNameDefault.java152
-rw-r--r--base/common/src/com/netscape/cms/profile/def/AuthorityKeyIdentifierExtDefault.java190
-rw-r--r--base/common/src/com/netscape/cms/profile/def/AutoAssignDefault.java96
-rw-r--r--base/common/src/com/netscape/cms/profile/def/BasicConstraintsExtDefault.java297
-rw-r--r--base/common/src/com/netscape/cms/profile/def/CAEnrollDefault.java106
-rw-r--r--base/common/src/com/netscape/cms/profile/def/CAValidityDefault.java348
-rw-r--r--base/common/src/com/netscape/cms/profile/def/CRLDistributionPointsExtDefault.java696
-rw-r--r--base/common/src/com/netscape/cms/profile/def/CertificatePoliciesExtDefault.java796
-rw-r--r--base/common/src/com/netscape/cms/profile/def/CertificateVersionDefault.java193
-rw-r--r--base/common/src/com/netscape/cms/profile/def/EnrollDefault.java815
-rw-r--r--base/common/src/com/netscape/cms/profile/def/EnrollExtDefault.java28
-rw-r--r--base/common/src/com/netscape/cms/profile/def/ExtendedKeyUsageExtDefault.java250
-rw-r--r--base/common/src/com/netscape/cms/profile/def/FreshestCRLExtDefault.java584
-rw-r--r--base/common/src/com/netscape/cms/profile/def/GenericExtDefault.java260
-rw-r--r--base/common/src/com/netscape/cms/profile/def/ImageDefault.java105
-rw-r--r--base/common/src/com/netscape/cms/profile/def/InhibitAnyPolicyExtDefault.java271
-rw-r--r--base/common/src/com/netscape/cms/profile/def/IssuerAltNameExtDefault.java317
-rw-r--r--base/common/src/com/netscape/cms/profile/def/KeyUsageExtDefault.java511
-rw-r--r--base/common/src/com/netscape/cms/profile/def/NSCCommentExtDefault.java246
-rw-r--r--base/common/src/com/netscape/cms/profile/def/NSCertTypeExtDefault.java419
-rw-r--r--base/common/src/com/netscape/cms/profile/def/NameConstraintsExtDefault.java670
-rw-r--r--base/common/src/com/netscape/cms/profile/def/NoDefault.java111
-rw-r--r--base/common/src/com/netscape/cms/profile/def/OCSPNoCheckExtDefault.java185
-rw-r--r--base/common/src/com/netscape/cms/profile/def/PolicyConstraintsExtDefault.java287
-rw-r--r--base/common/src/com/netscape/cms/profile/def/PolicyMappingsExtDefault.java420
-rw-r--r--base/common/src/com/netscape/cms/profile/def/PrivateKeyUsagePeriodExtDefault.java316
-rw-r--r--base/common/src/com/netscape/cms/profile/def/SigningAlgDefault.java183
-rw-r--r--base/common/src/com/netscape/cms/profile/def/SubjectAltNameExtDefault.java542
-rw-r--r--base/common/src/com/netscape/cms/profile/def/SubjectDirAttributesExtDefault.java527
-rw-r--r--base/common/src/com/netscape/cms/profile/def/SubjectInfoAccessExtDefault.java448
-rw-r--r--base/common/src/com/netscape/cms/profile/def/SubjectKeyIdentifierExtDefault.java217
-rw-r--r--base/common/src/com/netscape/cms/profile/def/SubjectNameDefault.java184
-rw-r--r--base/common/src/com/netscape/cms/profile/def/UserExtensionDefault.java136
-rw-r--r--base/common/src/com/netscape/cms/profile/def/UserKeyDefault.java233
-rw-r--r--base/common/src/com/netscape/cms/profile/def/UserSigningAlgDefault.java126
-rw-r--r--base/common/src/com/netscape/cms/profile/def/UserSubjectNameDefault.java143
-rw-r--r--base/common/src/com/netscape/cms/profile/def/UserValidityDefault.java149
-rw-r--r--base/common/src/com/netscape/cms/profile/def/ValidityDefault.java263
-rw-r--r--base/common/src/com/netscape/cms/profile/def/nsHKeySubjectNameDefault.java215
-rw-r--r--base/common/src/com/netscape/cms/profile/def/nsNKeySubjectNameDefault.java423
-rw-r--r--base/common/src/com/netscape/cms/profile/def/nsTokenDeviceKeySubjectNameDefault.java215
-rw-r--r--base/common/src/com/netscape/cms/profile/def/nsTokenUserKeySubjectNameDefault.java456
-rw-r--r--base/common/src/com/netscape/cms/profile/input/CMCCertReqInput.java122
-rw-r--r--base/common/src/com/netscape/cms/profile/input/CertReqInput.java185
-rw-r--r--base/common/src/com/netscape/cms/profile/input/DualKeyGenInput.java163
-rw-r--r--base/common/src/com/netscape/cms/profile/input/EncryptionKeyGenInput.java184
-rw-r--r--base/common/src/com/netscape/cms/profile/input/EnrollInput.java303
-rw-r--r--base/common/src/com/netscape/cms/profile/input/FileSigningInput.java143
-rw-r--r--base/common/src/com/netscape/cms/profile/input/GenericInput.java160
-rw-r--r--base/common/src/com/netscape/cms/profile/input/ImageInput.java89
-rw-r--r--base/common/src/com/netscape/cms/profile/input/KeyGenInput.java184
-rw-r--r--base/common/src/com/netscape/cms/profile/input/SerialNumRenewInput.java89
-rw-r--r--base/common/src/com/netscape/cms/profile/input/SigningKeyGenInput.java184
-rw-r--r--base/common/src/com/netscape/cms/profile/input/SubjectDNInput.java142
-rw-r--r--base/common/src/com/netscape/cms/profile/input/SubjectNameInput.java382
-rw-r--r--base/common/src/com/netscape/cms/profile/input/SubmitterInfoInput.java102
-rw-r--r--base/common/src/com/netscape/cms/profile/input/nsHKeyCertReqInput.java160
-rw-r--r--base/common/src/com/netscape/cms/profile/input/nsNKeyCertReqInput.java129
-rw-r--r--base/common/src/com/netscape/cms/profile/output/CMMFOutput.java161
-rw-r--r--base/common/src/com/netscape/cms/profile/output/CertOutput.java120
-rw-r--r--base/common/src/com/netscape/cms/profile/output/EnrollOutput.java134
-rw-r--r--base/common/src/com/netscape/cms/profile/output/PKCS7Output.java158
-rw-r--r--base/common/src/com/netscape/cms/profile/output/nsNKeyOutput.java110
-rw-r--r--base/common/src/com/netscape/cms/profile/updater/SubsystemGroupUpdater.java321
-rw-r--r--base/common/src/com/netscape/cms/publish/mappers/AVAPattern.java594
-rw-r--r--base/common/src/com/netscape/cms/publish/mappers/LdapCaSimpleMap.java372
-rw-r--r--base/common/src/com/netscape/cms/publish/mappers/LdapCertCompsMap.java178
-rw-r--r--base/common/src/com/netscape/cms/publish/mappers/LdapCertExactMap.java199
-rw-r--r--base/common/src/com/netscape/cms/publish/mappers/LdapCertSubjMap.java343
-rw-r--r--base/common/src/com/netscape/cms/publish/mappers/LdapCrlIssuerCompsMap.java156
-rw-r--r--base/common/src/com/netscape/cms/publish/mappers/LdapDNCompsMap.java457
-rw-r--r--base/common/src/com/netscape/cms/publish/mappers/LdapEnhancedMap.java640
-rw-r--r--base/common/src/com/netscape/cms/publish/mappers/LdapSimpleMap.java332
-rw-r--r--base/common/src/com/netscape/cms/publish/mappers/MapAVAPattern.java652
-rw-r--r--base/common/src/com/netscape/cms/publish/mappers/MapDNPattern.java201
-rw-r--r--base/common/src/com/netscape/cms/publish/mappers/MapRDNPattern.java217
-rw-r--r--base/common/src/com/netscape/cms/publish/mappers/NoMap.java104
-rw-r--r--base/common/src/com/netscape/cms/publish/publishers/FileBasedPublisher.java443
-rw-r--r--base/common/src/com/netscape/cms/publish/publishers/LdapCaCertPublisher.java421
-rw-r--r--base/common/src/com/netscape/cms/publish/publishers/LdapCertSubjPublisher.java345
-rw-r--r--base/common/src/com/netscape/cms/publish/publishers/LdapCertificatePairPublisher.java318
-rw-r--r--base/common/src/com/netscape/cms/publish/publishers/LdapCrlPublisher.java379
-rw-r--r--base/common/src/com/netscape/cms/publish/publishers/LdapEncryptCertPublisher.java359
-rw-r--r--base/common/src/com/netscape/cms/publish/publishers/LdapUserCertPublisher.java333
-rw-r--r--base/common/src/com/netscape/cms/publish/publishers/OCSPPublisher.java355
-rw-r--r--base/common/src/com/netscape/cms/publish/publishers/PublisherUtils.java136
-rw-r--r--base/common/src/com/netscape/cms/request/RequestScheduler.java71
-rw-r--r--base/common/src/com/netscape/cms/selftests/ASelfTest.java193
-rw-r--r--base/common/src/com/netscape/cms/selftests/ca/CAPresence.java262
-rw-r--r--base/common/src/com/netscape/cms/selftests/ca/CAValidity.java262
-rw-r--r--base/common/src/com/netscape/cms/selftests/common/SystemCertsVerification.java213
-rw-r--r--base/common/src/com/netscape/cms/selftests/kra/KRAPresence.java251
-rw-r--r--base/common/src/com/netscape/cms/selftests/ocsp/OCSPPresence.java280
-rw-r--r--base/common/src/com/netscape/cms/selftests/ocsp/OCSPValidity.java280
-rw-r--r--base/common/src/com/netscape/cms/selftests/ra/RAPresence.java261
-rw-r--r--base/common/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java302
-rw-r--r--base/common/src/com/netscape/cms/servlet/admin/ACLAdminServlet.java905
-rw-r--r--base/common/src/com/netscape/cms/servlet/admin/AdminResources.java42
-rw-r--r--base/common/src/com/netscape/cms/servlet/admin/AdminServlet.java1296
-rw-r--r--base/common/src/com/netscape/cms/servlet/admin/AuthAdminServlet.java1721
-rw-r--r--base/common/src/com/netscape/cms/servlet/admin/AuthCredentials.java109
-rw-r--r--base/common/src/com/netscape/cms/servlet/admin/CAAdminServlet.java1582
-rw-r--r--base/common/src/com/netscape/cms/servlet/admin/CMSAdminServlet.java3449
-rw-r--r--base/common/src/com/netscape/cms/servlet/admin/JobsAdminServlet.java1007
-rw-r--r--base/common/src/com/netscape/cms/servlet/admin/KRAAdminServlet.java234
-rw-r--r--base/common/src/com/netscape/cms/servlet/admin/LogAdminServlet.java2361
-rw-r--r--base/common/src/com/netscape/cms/servlet/admin/OCSPAdminServlet.java543
-rw-r--r--base/common/src/com/netscape/cms/servlet/admin/PolicyAdminServlet.java1258
-rw-r--r--base/common/src/com/netscape/cms/servlet/admin/ProfileAdminServlet.java2682
-rw-r--r--base/common/src/com/netscape/cms/servlet/admin/PublisherAdminServlet.java3127
-rw-r--r--base/common/src/com/netscape/cms/servlet/admin/RAAdminServlet.java584
-rw-r--r--base/common/src/com/netscape/cms/servlet/admin/RegistryAdminServlet.java373
-rw-r--r--base/common/src/com/netscape/cms/servlet/admin/SystemCertificateResource.java25
-rw-r--r--base/common/src/com/netscape/cms/servlet/admin/SystemCertificateResourceService.java80
-rw-r--r--base/common/src/com/netscape/cms/servlet/admin/UsrGrpAdminServlet.java2313
-rw-r--r--base/common/src/com/netscape/cms/servlet/base/CMSResourceService.java69
-rw-r--r--base/common/src/com/netscape/cms/servlet/base/CMSServlet.java2294
-rw-r--r--base/common/src/com/netscape/cms/servlet/base/CMSStartServlet.java117
-rw-r--r--base/common/src/com/netscape/cms/servlet/base/DisplayHtmlServlet.java97
-rw-r--r--base/common/src/com/netscape/cms/servlet/base/DynamicVariablesServlet.java333
-rw-r--r--base/common/src/com/netscape/cms/servlet/base/GetStats.java184
-rw-r--r--base/common/src/com/netscape/cms/servlet/base/IndexServlet.java118
-rw-r--r--base/common/src/com/netscape/cms/servlet/base/PortsServlet.java90
-rw-r--r--base/common/src/com/netscape/cms/servlet/base/ProxyServlet.java248
-rw-r--r--base/common/src/com/netscape/cms/servlet/base/SystemInfoServlet.java287
-rw-r--r--base/common/src/com/netscape/cms/servlet/base/UserInfo.java90
-rw-r--r--base/common/src/com/netscape/cms/servlet/base/model/Link.java88
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/CMCRevReqServlet.java1056
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/ChallengeRevocationServlet1.java716
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/CloneRedirect.java142
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/DirAuthServlet.java241
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/DisableEnrollResult.java173
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/DisplayBySerial.java488
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/DisplayCRL.java481
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/DisplayHashUserEnroll.java227
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java1221
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/DoRevokeTPS.java940
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/DoUnrevoke.java671
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/DoUnrevokeTPS.java618
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/EnableEnrollResult.java184
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/EnrollServlet.java1768
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/GetBySerial.java296
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/GetCAChain.java407
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/GetCRL.java467
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/GetCertFromRequest.java350
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/GetEnableStatus.java173
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/GetInfo.java377
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/HashEnrollServlet.java1241
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/ImportCertsTemplateFiller.java381
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/ListCerts.java672
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/Monitor.java407
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/ReasonToRevoke.java287
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/RemoteAuthConfig.java624
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/RenewalServlet.java523
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/RevocationServlet.java392
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/RevocationSuccessTemplateFiller.java97
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/SrchCerts.java762
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/UpdateCRL.java530
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/UpdateDir.java747
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/model/CertificateData.java53
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/scep/CRSEnrollment.java2135
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/scep/ChallengePassword.java141
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/scep/ExtensionsRequested.java176
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/AuthCredentials.java109
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java1112
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/CMSFile.java102
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/CMSFileLoader.java160
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/CMSGWResources.java44
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/CMSGateway.java372
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/CMSLoadTemplate.java60
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/CMSRequest.java300
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/CMSTemplate.java609
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/CMSTemplateParams.java70
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/ECMSGWException.java74
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/GenErrorTemplateFiller.java102
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/GenPendingTemplateFiller.java287
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/GenRejectedTemplateFiller.java92
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/GenSuccessTemplateFiller.java63
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/GenSvcPendingTemplateFiller.java79
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/GenUnauthorizedTemplateFiller.java67
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/GenUnexpectedErrorTemplateFiller.java76
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/ICMSTemplateFiller.java49
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/IRawJS.java26
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/IndexTemplateFiller.java114
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/RawJS.java35
-rw-r--r--base/common/src/com/netscape/cms/servlet/common/ServletUtils.java106
-rw-r--r--base/common/src/com/netscape/cms/servlet/connector/CloneServlet.java579
-rw-r--r--base/common/src/com/netscape/cms/servlet/connector/ConnectorServlet.java1116
-rw-r--r--base/common/src/com/netscape/cms/servlet/connector/GenerateKeyPairServlet.java292
-rw-r--r--base/common/src/com/netscape/cms/servlet/connector/TokenKeyRecoveryServlet.java326
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/AdminAuthenticatePanel.java330
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/AdminPanel.java690
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/AgentAuthenticatePanel.java229
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/AuthenticatePanel.java192
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/BackupKeyCertPanel.java450
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/BaseServlet.java121
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/CAInfoPanel.java327
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/Cert.java179
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/CertPrettyPrintPanel.java210
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/CertRequestPanel.java757
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/CertUtil.java667
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/CheckIdentity.java117
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/ConfigBaseServlet.java121
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/ConfigCertApprovalCallback.java33
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/ConfigCertReqServlet.java50
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/ConfigCloneServlet.java50
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/ConfigDatabaseServlet.java196
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/ConfigHSMLoginPanel.java296
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/ConfigHSMServlet.java297
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/ConfigImportCertServlet.java50
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/ConfigJoinServlet.java182
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/ConfigRootCAServlet.java145
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/CreateSubsystemPanel.java299
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/DatabasePanel.java1591
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/DatabaseServlet.java49
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/DisplayCertChainPanel.java236
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/DisplayServlet.java49
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/DonePanel.java897
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/DownloadPKCS12.java136
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/GetCertChain.java158
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/GetConfigEntries.java228
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/GetCookie.java315
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/GetDomainXML.java239
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/GetStatus.java109
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/GetSubsystemCert.java129
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/GetTokenInfo.java151
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/GetTransportCert.java180
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/HierarchyPanel.java194
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/ImportAdminCertPanel.java341
-rwxr-xr-xbase/common/src/com/netscape/cms/servlet/csadmin/ImportCAChainPanel.java145
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/ImportTransportCert.java179
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/LDAPSecurityDomainSessionTable.java295
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/LoginServlet.java72
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/MainPageServlet.java158
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/ModulePanel.java338
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/ModuleServlet.java90
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/NamePanel.java993
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/RegisterUser.java331
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/RestoreKeyCertPanel.java718
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/SavePKCS12Panel.java144
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainLogin.java87
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainPanel.java500
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainSessionTable.java105
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/SessionTimer.java68
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/SizePanel.java669
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/TokenAuthenticate.java146
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/UpdateConnector.java203
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/UpdateDomainXML.java568
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/UpdateNumberRange.java290
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/UpdateOCSPConfig.java182
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/WelcomePanel.java128
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/WelcomeServlet.java49
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/WizardPanelBase.java1630
-rw-r--r--base/common/src/com/netscape/cms/servlet/filter/AdminRequestFilter.java134
-rw-r--r--base/common/src/com/netscape/cms/servlet/filter/AgentRequestFilter.java134
-rw-r--r--base/common/src/com/netscape/cms/servlet/filter/EEClientAuthRequestFilter.java133
-rw-r--r--base/common/src/com/netscape/cms/servlet/filter/EERequestFilter.java186
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/ConfirmRecoverBySerial.java187
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/DisplayBySerial.java194
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/DisplayBySerialForRecovery.java213
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/DisplayTransport.java125
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/ExamineRecovery.java249
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/GetApprovalStatus.java235
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/GetAsyncPk12.java266
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/GetPk12.java260
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/GrantAsyncRecovery.java280
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/GrantRecovery.java308
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/KeyRecordParser.java87
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/KeyResource.java33
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/KeyResourceService.java129
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/KeysResource.java23
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/KeysResourceService.java91
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/RecoverBySerial.java529
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/SrchKey.java297
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/SrchKeyForRecovery.java318
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/model/KeyDAO.java202
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/model/KeyData.java76
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/model/KeyDataInfo.java85
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/model/KeyDataInfos.java87
-rw-r--r--base/common/src/com/netscape/cms/servlet/ocsp/AddCAServlet.java310
-rw-r--r--base/common/src/com/netscape/cms/servlet/ocsp/AddCRLServlet.java591
-rw-r--r--base/common/src/com/netscape/cms/servlet/ocsp/CheckCertServlet.java216
-rw-r--r--base/common/src/com/netscape/cms/servlet/ocsp/GetOCSPInfo.java164
-rw-r--r--base/common/src/com/netscape/cms/servlet/ocsp/ListCAServlet.java198
-rw-r--r--base/common/src/com/netscape/cms/servlet/ocsp/OCSPServlet.java276
-rw-r--r--base/common/src/com/netscape/cms/servlet/ocsp/RemoveCAServlet.java214
-rw-r--r--base/common/src/com/netscape/cms/servlet/processors/CMCProcessor.java433
-rw-r--r--base/common/src/com/netscape/cms/servlet/processors/CRMFProcessor.java372
-rw-r--r--base/common/src/com/netscape/cms/servlet/processors/IPKIProcessor.java33
-rw-r--r--base/common/src/com/netscape/cms/servlet/processors/KeyGenProcessor.java120
-rw-r--r--base/common/src/com/netscape/cms/servlet/processors/PKCS10Processor.java287
-rw-r--r--base/common/src/com/netscape/cms/servlet/processors/PKIProcessor.java356
-rw-r--r--base/common/src/com/netscape/cms/servlet/profile/ProfileApproveServlet.java532
-rw-r--r--base/common/src/com/netscape/cms/servlet/profile/ProfileListServlet.java176
-rw-r--r--base/common/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java960
-rw-r--r--base/common/src/com/netscape/cms/servlet/profile/ProfileReviewServlet.java455
-rw-r--r--base/common/src/com/netscape/cms/servlet/profile/ProfileSelectServlet.java411
-rw-r--r--base/common/src/com/netscape/cms/servlet/profile/ProfileServlet.java511
-rw-r--r--base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java904
-rw-r--r--base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitServlet.java1631
-rw-r--r--base/common/src/com/netscape/cms/servlet/profile/SSLClientCertProvider.java39
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/CertReqParser.java925
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/CheckRequest.java621
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/IReqParser.java42
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/KeyReqParser.java81
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/KeyRequestResource.java69
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/KeyRequestResourceService.java165
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/KeyRequestsResource.java34
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/KeyRequestsResourceService.java101
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/ProcessCertReq.java1933
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/ProcessReq.java334
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/QueryReq.java558
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/ReqParser.java79
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/SearchReqs.java336
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/model/ArchivalRequestData.java123
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/model/KeyRequestDAO.java326
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/model/KeyRequestInfo.java120
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/model/KeyRequestInfos.java89
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/model/RecoveryRequestData.java155
-rw-r--r--base/common/src/com/netscape/cms/servlet/tks/TokenServlet.java1340
-rw-r--r--base/common/src/com/netscape/cms/servlet/wizard/IWizardPanel.java111
-rw-r--r--base/common/src/com/netscape/cms/servlet/wizard/WizardServlet.java489
-rw-r--r--base/common/src/com/netscape/cms/shares/OldJoinShares.java86
-rw-r--r--base/common/src/com/netscape/cms/shares/OldShare.java62
-rw-r--r--base/common/src/com/netscape/cmscore/apps/CMSEngine.java2003
-rw-r--r--base/common/src/com/netscape/cmscore/apps/CommandQueue.java99
-rw-r--r--base/common/src/com/netscape/cmscore/apps/PKIServerEvent.java42
-rw-r--r--base/common/src/com/netscape/cmscore/apps/PKIServerListener.java35
-rw-r--r--base/common/src/com/netscape/cmscore/apps/Setup.java348
-rw-r--r--base/common/src/com/netscape/cmscore/apps/Upgrade.java329
-rw-r--r--base/common/src/com/netscape/cmscore/authentication/AuthSubsystem.java515
-rw-r--r--base/common/src/com/netscape/cmscore/authentication/CertUserDBAuthentication.java260
-rw-r--r--base/common/src/com/netscape/cmscore/authentication/ChallengePhraseAuthentication.java411
-rw-r--r--base/common/src/com/netscape/cmscore/authentication/NullAuthentication.java161
-rw-r--r--base/common/src/com/netscape/cmscore/authentication/PasswdUserDBAuthentication.java274
-rw-r--r--base/common/src/com/netscape/cmscore/authentication/SSLClientCertAuthentication.java291
-rw-r--r--base/common/src/com/netscape/cmscore/authentication/VerifiedCert.java90
-rw-r--r--base/common/src/com/netscape/cmscore/authentication/VerifiedCerts.java158
-rw-r--r--base/common/src/com/netscape/cmscore/authorization/AuthzSubsystem.java474
-rw-r--r--base/common/src/com/netscape/cmscore/base/ArgBlock.java717
-rw-r--r--base/common/src/com/netscape/cmscore/base/FileConfigStore.java222
-rw-r--r--base/common/src/com/netscape/cmscore/base/JDialogPasswordCallback.java270
-rw-r--r--base/common/src/com/netscape/cmscore/base/PropConfigStore.java792
-rw-r--r--base/common/src/com/netscape/cmscore/base/SimpleProperties.java463
-rw-r--r--base/common/src/com/netscape/cmscore/base/SourceConfigStore.java59
-rw-r--r--base/common/src/com/netscape/cmscore/base/SubsystemLoader.java75
-rw-r--r--base/common/src/com/netscape/cmscore/base/SubsystemRegistry.java43
-rw-r--r--base/common/src/com/netscape/cmscore/cert/CertDateCompare.java52
-rw-r--r--base/common/src/com/netscape/cmscore/cert/CertPrettyPrint.java36
-rw-r--r--base/common/src/com/netscape/cmscore/cert/CertUtils.java1103
-rw-r--r--base/common/src/com/netscape/cmscore/cert/CertificatePair.java281
-rw-r--r--base/common/src/com/netscape/cmscore/cert/CrlCachePrettyPrint.java262
-rw-r--r--base/common/src/com/netscape/cmscore/cert/CrlPrettyPrint.java36
-rw-r--r--base/common/src/com/netscape/cmscore/cert/CrossCertPairSubsystem.java505
-rw-r--r--base/common/src/com/netscape/cmscore/cert/ExtPrettyPrint.java36
-rw-r--r--base/common/src/com/netscape/cmscore/cert/OidLoaderSubsystem.java189
-rw-r--r--base/common/src/com/netscape/cmscore/cert/PrettyPrintFormat.java165
-rw-r--r--base/common/src/com/netscape/cmscore/cert/PrettyPrintResources.java293
-rw-r--r--base/common/src/com/netscape/cmscore/cert/PubKeyPrettyPrint.java35
-rw-r--r--base/common/src/com/netscape/cmscore/cert/X500NameSubsystem.java285
-rw-r--r--base/common/src/com/netscape/cmscore/connector/HttpConnFactory.java308
-rw-r--r--base/common/src/com/netscape/cmscore/connector/HttpConnection.java244
-rw-r--r--base/common/src/com/netscape/cmscore/connector/HttpConnector.java207
-rw-r--r--base/common/src/com/netscape/cmscore/connector/HttpPKIMessage.java231
-rw-r--r--base/common/src/com/netscape/cmscore/connector/HttpRequestEncoder.java76
-rw-r--r--base/common/src/com/netscape/cmscore/connector/LocalConnector.java211
-rw-r--r--base/common/src/com/netscape/cmscore/connector/RemoteAuthority.java69
-rw-r--r--base/common/src/com/netscape/cmscore/connector/RequestTransfer.java122
-rw-r--r--base/common/src/com/netscape/cmscore/connector/Resender.java252
-rw-r--r--base/common/src/com/netscape/cmscore/crmf/CRMFParser.java122
-rw-r--r--base/common/src/com/netscape/cmscore/crmf/PKIArchiveOptionsContainer.java31
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/BigIntegerMapper.java121
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/ByteArrayMapper.java96
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/CRLDBSchema.java47
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/CRLIssuingPointRecord.java334
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/CRLRepository.java370
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/CertDBSchema.java54
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/CertRecord.java284
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/CertRecordList.java113
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/CertRecordMapper.java99
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/CertificateRepository.java2030
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/DBRegistry.java564
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/DBSSession.java485
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/DBSUtil.java49
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/DBSearchResults.java93
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/DBSubsystem.java948
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/DBVirtualList.java782
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/DateArrayMapper.java109
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/DateMapper.java113
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/IntegerMapper.java89
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/KeyDBSchema.java51
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/KeyRecord.java386
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/KeyRecordList.java89
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/KeyRecordMapper.java112
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/KeyRepository.java586
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/KeyStateMapper.java82
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/LdapFilterConverter.java62
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/LongMapper.java119
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/MetaInfoMapper.java124
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/ObjectStreamMapper.java136
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/PublicKeyMapper.java136
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/ReplicaIDRepository.java83
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/Repository.java497
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/RepositoryRecord.java111
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/RepositorySchema.java34
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/RevocationInfo.java78
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/RevocationInfoMapper.java171
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/StringMapper.java95
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/StringVectorMapper.java111
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/X500NameMapper.java111
-rw-r--r--base/common/src/com/netscape/cmscore/dbs/X509CertImplMapper.java369
-rw-r--r--base/common/src/com/netscape/cmscore/extensions/CMSExtensionsMap.java160
-rw-r--r--base/common/src/com/netscape/cmscore/extensions/KeyUsage.java230
-rw-r--r--base/common/src/com/netscape/cmscore/jobs/CronItem.java168
-rw-r--r--base/common/src/com/netscape/cmscore/jobs/CronRange.java84
-rw-r--r--base/common/src/com/netscape/cmscore/jobs/JobCron.java355
-rw-r--r--base/common/src/com/netscape/cmscore/jobs/JobsScheduler.java509
-rw-r--r--base/common/src/com/netscape/cmscore/ldap/LdapAndExpression.java74
-rw-r--r--base/common/src/com/netscape/cmscore/ldap/LdapConnModule.java132
-rw-r--r--base/common/src/com/netscape/cmscore/ldap/LdapOrExpression.java80
-rw-r--r--base/common/src/com/netscape/cmscore/ldap/LdapPredicateParser.java340
-rw-r--r--base/common/src/com/netscape/cmscore/ldap/LdapPublishModule.java782
-rw-r--r--base/common/src/com/netscape/cmscore/ldap/LdapRequestListener.java530
-rw-r--r--base/common/src/com/netscape/cmscore/ldap/LdapRule.java301
-rw-r--r--base/common/src/com/netscape/cmscore/ldap/LdapSimpleExpression.java473
-rw-r--r--base/common/src/com/netscape/cmscore/ldap/PublishObject.java84
-rw-r--r--base/common/src/com/netscape/cmscore/ldap/PublisherProcessor.java1498
-rw-r--r--base/common/src/com/netscape/cmscore/ldapconn/LdapAnonConnFactory.java467
-rw-r--r--base/common/src/com/netscape/cmscore/ldapconn/LdapAnonConnection.java92
-rw-r--r--base/common/src/com/netscape/cmscore/ldapconn/LdapAuthInfo.java298
-rw-r--r--base/common/src/com/netscape/cmscore/ldapconn/LdapBoundConnFactory.java529
-rw-r--r--base/common/src/com/netscape/cmscore/ldapconn/LdapBoundConnection.java220
-rw-r--r--base/common/src/com/netscape/cmscore/ldapconn/LdapConnInfo.java119
-rw-r--r--base/common/src/com/netscape/cmscore/ldapconn/LdapJssSSLSocketFactory.java109
-rw-r--r--base/common/src/com/netscape/cmscore/listeners/ListenerPlugin.java52
-rw-r--r--base/common/src/com/netscape/cmscore/logging/AuditEventFactory.java99
-rw-r--r--base/common/src/com/netscape/cmscore/logging/AuditFormat.java111
-rw-r--r--base/common/src/com/netscape/cmscore/logging/LogQueue.java123
-rw-r--r--base/common/src/com/netscape/cmscore/logging/LogSubsystem.java270
-rw-r--r--base/common/src/com/netscape/cmscore/logging/Logger.java374
-rw-r--r--base/common/src/com/netscape/cmscore/logging/SignedAuditEventFactory.java125
-rw-r--r--base/common/src/com/netscape/cmscore/logging/SignedAuditLogger.java39
-rw-r--r--base/common/src/com/netscape/cmscore/logging/SystemEventFactory.java99
-rw-r--r--base/common/src/com/netscape/cmscore/notification/EmailFormProcessor.java250
-rw-r--r--base/common/src/com/netscape/cmscore/notification/EmailResolverKeys.java93
-rw-r--r--base/common/src/com/netscape/cmscore/notification/EmailTemplate.java174
-rw-r--r--base/common/src/com/netscape/cmscore/notification/ReqCertEmailResolver.java155
-rw-r--r--base/common/src/com/netscape/cmscore/notification/ReqCertSANameEmailResolver.java276
-rw-r--r--base/common/src/com/netscape/cmscore/policy/AndExpression.java60
-rw-r--r--base/common/src/com/netscape/cmscore/policy/GeneralNameUtil.java694
-rw-r--r--base/common/src/com/netscape/cmscore/policy/GenericPolicyProcessor.java1548
-rw-r--r--base/common/src/com/netscape/cmscore/policy/JavaScriptRequestProxy.java48
-rw-r--r--base/common/src/com/netscape/cmscore/policy/OrExpression.java67
-rw-r--r--base/common/src/com/netscape/cmscore/policy/PolicyPredicateParser.java341
-rw-r--r--base/common/src/com/netscape/cmscore/policy/PolicySet.java299
-rw-r--r--base/common/src/com/netscape/cmscore/policy/SimpleExpression.java434
-rw-r--r--base/common/src/com/netscape/cmscore/profile/ProfileSubsystem.java325
-rw-r--r--base/common/src/com/netscape/cmscore/realm/ACL.java193
-rw-r--r--base/common/src/com/netscape/cmscore/realm/ACLEntry.java243
-rw-r--r--base/common/src/com/netscape/cmscore/realm/PKIJNDIRealm.java943
-rw-r--r--base/common/src/com/netscape/cmscore/registry/PluginInfo.java52
-rw-r--r--base/common/src/com/netscape/cmscore/registry/PluginRegistry.java294
-rw-r--r--base/common/src/com/netscape/cmscore/request/ARequestQueue.java1578
-rw-r--r--base/common/src/com/netscape/cmscore/request/ARequestRecord.java42
-rw-r--r--base/common/src/com/netscape/cmscore/request/CertRequestConstants.java73
-rw-r--r--base/common/src/com/netscape/cmscore/request/ExtDataHashtable.java78
-rw-r--r--base/common/src/com/netscape/cmscore/request/RequestAttr.java61
-rw-r--r--base/common/src/com/netscape/cmscore/request/RequestQueue.java709
-rw-r--r--base/common/src/com/netscape/cmscore/request/RequestRecord.java883
-rw-r--r--base/common/src/com/netscape/cmscore/request/RequestRepository.java217
-rw-r--r--base/common/src/com/netscape/cmscore/request/RequestSubsystem.java187
-rw-r--r--base/common/src/com/netscape/cmscore/request/Schema.java50
-rw-r--r--base/common/src/com/netscape/cmscore/security/CASigningCert.java162
-rw-r--r--base/common/src/com/netscape/cmscore/security/CertificateInfo.java277
-rw-r--r--base/common/src/com/netscape/cmscore/security/JssSubsystem.java2203
-rw-r--r--base/common/src/com/netscape/cmscore/security/KRATransportCert.java107
-rw-r--r--base/common/src/com/netscape/cmscore/security/KeyCertUtil.java1139
-rw-r--r--base/common/src/com/netscape/cmscore/security/OCSPSigningCert.java140
-rw-r--r--base/common/src/com/netscape/cmscore/security/PWCBsdr.java266
-rw-r--r--base/common/src/com/netscape/cmscore/security/PWUtil.java73
-rw-r--r--base/common/src/com/netscape/cmscore/security/PWsdrCache.java639
-rw-r--r--base/common/src/com/netscape/cmscore/security/Provider.java57
-rw-r--r--base/common/src/com/netscape/cmscore/security/RASigningCert.java113
-rw-r--r--base/common/src/com/netscape/cmscore/security/SSLCert.java125
-rw-r--r--base/common/src/com/netscape/cmscore/security/SSLSelfSignedCert.java119
-rw-r--r--base/common/src/com/netscape/cmscore/security/SubsystemCert.java81
-rw-r--r--base/common/src/com/netscape/cmscore/selftests/SelfTestOrderedInstance.java136
-rw-r--r--base/common/src/com/netscape/cmscore/selftests/SelfTestSubsystem.java1900
-rw-r--r--base/common/src/com/netscape/cmscore/time/SimpleTimeSource.java29
-rw-r--r--base/common/src/com/netscape/cmscore/usrgrp/CertDNCertUserLocator.java77
-rw-r--r--base/common/src/com/netscape/cmscore/usrgrp/ExactMatchCertUserLocator.java83
-rw-r--r--base/common/src/com/netscape/cmscore/usrgrp/Group.java125
-rw-r--r--base/common/src/com/netscape/cmscore/usrgrp/UGSubsystem.java1685
-rw-r--r--base/common/src/com/netscape/cmscore/usrgrp/User.java218
-rw-r--r--base/common/src/com/netscape/cmscore/util/Assert.java48
-rw-r--r--base/common/src/com/netscape/cmscore/util/AssertionException.java36
-rw-r--r--base/common/src/com/netscape/cmscore/util/Debug.java385
-rw-r--r--base/common/src/com/netscape/cmscore/util/ExceptionFormatter.java94
-rw-r--r--base/common/src/com/netscape/cmscore/util/FileAsString.java115
-rw-r--r--base/common/src/com/netscape/cmscore/util/FileDialogFilter.java143
-rw-r--r--base/common/src/com/netscape/cmscore/util/PFXUtils.java167
-rw-r--r--base/common/src/com/netscape/cmscore/util/ProfileSubsystem.java312
-rw-r--r--base/common/src/com/netscape/cmscore/util/StatsSubsystem.java195
-rw-r--r--base/common/src/com/netscape/cmscore/util/UtilMessage.java181
-rw-r--r--base/common/src/com/netscape/cmscore/util/UtilResources.java74
-rw-r--r--base/common/test/CMakeLists.txt103
-rw-r--r--base/common/test/com/netscape/certsrv/app/CMSEngineDefaultStub.java632
-rw-r--r--base/common/test/com/netscape/certsrv/authentication/AuthTokenTest.java271
-rw-r--r--base/common/test/com/netscape/certsrv/logging/LoggerDefaultStub.java71
-rw-r--r--base/common/test/com/netscape/certsrv/request/AgentApprovalsTest.java82
-rw-r--r--base/common/test/com/netscape/cmscore/dbs/CertRecordListTest.java87
-rw-r--r--base/common/test/com/netscape/cmscore/dbs/DBRegistryDefaultStub.java79
-rw-r--r--base/common/test/com/netscape/cmscore/dbs/DBRegistryTest.java175
-rw-r--r--base/common/test/com/netscape/cmscore/dbs/DBSSessionDefaultStub.java79
-rw-r--r--base/common/test/com/netscape/cmscore/dbs/DBSubsystemDefaultStub.java172
-rw-r--r--base/common/test/com/netscape/cmscore/dbs/DBVirtualListDefaultStub.java87
-rw-r--r--base/common/test/com/netscape/cmscore/dbs/RequestRecordDefaultStub.java44
-rw-r--r--base/common/test/com/netscape/cmscore/request/DBDynAttrMapperDefaultStub.java33
-rw-r--r--base/common/test/com/netscape/cmscore/request/ExtAttrDynMapperTest.java278
-rw-r--r--base/common/test/com/netscape/cmscore/request/ExtDataHashtableTest.java81
-rw-r--r--base/common/test/com/netscape/cmscore/request/RequestDefaultStub.java269
-rw-r--r--base/common/test/com/netscape/cmscore/request/RequestModDefaultStub.java21
-rw-r--r--base/common/test/com/netscape/cmscore/request/RequestQueueTest.java60
-rw-r--r--base/common/test/com/netscape/cmscore/request/RequestRecordTest.java168
-rw-r--r--base/common/test/com/netscape/cmscore/request/RequestTest.java649
-rw-r--r--base/common/test/com/netscape/cmscore/test/CMSBaseTestCase.java99
-rw-r--r--base/common/test/com/netscape/cmscore/test/TestHelper.java30
-rw-r--r--base/console/CMakeLists.txt4
-rw-r--r--base/console/LICENSE291
-rw-r--r--base/console/src/CMakeLists.txt661
-rw-r--r--base/console/src/com/netscape/admin/certsrv/AttrCellRenderer.java60
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSAdmin.java969
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSAdminResources.java197
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSAdminUtil.java1298
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSBaseMenuInfo.java178
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSBasePanel.java460
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSBaseResourceModel.java263
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSCAUILoader.java373
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSCCMUILoader.java107
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSContentTableModel.java100
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSEAUILoader.java136
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSKernelUILoader.java319
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSMessageBox.java124
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSOCSPUILoader.java100
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSPageFeeder.java150
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSPassword.java301
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSRAUILoader.java266
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSRemoteClassLoader.java109
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSResourceObject.java126
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSResourcePage.java154
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSServerInfo.java172
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSTableModel.java256
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSTaskModel.java288
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSTaskObject.java71
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CMSUIFramework.java242
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CellEditorData.java32
-rw-r--r--base/console/src/com/netscape/admin/certsrv/Console.java1861
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CustomComboBox.java78
-rw-r--r--base/console/src/com/netscape/admin/certsrv/CustomComboBoxModel.java169
-rw-r--r--base/console/src/com/netscape/admin/certsrv/DefaultTableCellEditor.java238
-rw-r--r--base/console/src/com/netscape/admin/certsrv/EAdminException.java142
-rw-r--r--base/console/src/com/netscape/admin/certsrv/GenericCellEditor.java223
-rw-r--r--base/console/src/com/netscape/admin/certsrv/GenericCellRenderer.java153
-rw-r--r--base/console/src/com/netscape/admin/certsrv/HourGlass.java52
-rw-r--r--base/console/src/com/netscape/admin/certsrv/IAttributeContent.java30
-rw-r--r--base/console/src/com/netscape/admin/certsrv/IConnectionListener.java29
-rw-r--r--base/console/src/com/netscape/admin/certsrv/IDataProcessor.java36
-rw-r--r--base/console/src/com/netscape/admin/certsrv/IDisplayPanel.java43
-rw-r--r--base/console/src/com/netscape/admin/certsrv/IEditorPanel.java60
-rw-r--r--base/console/src/com/netscape/admin/certsrv/IFilterPanel.java67
-rw-r--r--base/console/src/com/netscape/admin/certsrv/IMenuAction.java40
-rw-r--r--base/console/src/com/netscape/admin/certsrv/IRefreshTab.java41
-rw-r--r--base/console/src/com/netscape/admin/certsrv/IRefreshTabPanel.java38
-rw-r--r--base/console/src/com/netscape/admin/certsrv/IResourceSelectionListener.java39
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ISubSystemUILoader.java33
-rw-r--r--base/console/src/com/netscape/admin/certsrv/IUIMapper.java89
-rw-r--r--base/console/src/com/netscape/admin/certsrv/LabelCellRenderer.java116
-rw-r--r--base/console/src/com/netscape/admin/certsrv/MultilineLabelUI.java534
-rw-r--r--base/console/src/com/netscape/admin/certsrv/PasswordCellRenderer.java71
-rw-r--r--base/console/src/com/netscape/admin/certsrv/StatusItemContinuousProgress.java97
-rw-r--r--base/console/src/com/netscape/admin/certsrv/UIMapperRegistry.java121
-rw-r--r--base/console/src/com/netscape/admin/certsrv/certsrv-help.properties534
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ACIDialog.java517
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ACLDataModel.java47
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ACLEditDialog.java557
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ACLImplDataModel.java47
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ACLImplTab.java227
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ACLPanel.java231
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/AutoRecoveryModel.java57
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CACertsTab.java392
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSAccessLogPanel.java210
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSAuditLogPanel.java210
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSAutoRecovery.java267
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSBaseConfigDialog.java1078
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSBaseConfigPanel.java180
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSBaseLDAPPanel.java692
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSBaseLogPanel.java366
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSBaseTab.java95
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSBlankPanel.java82
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSCACertSettingPanel.java171
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSCAConnectorPanel.java237
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSCAGeneralPanel.java424
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSCALDAPPanel.java44
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSCRLCachePanel.java371
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSCRLFormatPanel.java448
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSCRLIPPanel.java327
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSCRLSettingPanel.java698
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSCertSettingPanel.java150
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSCipherPreferenceDialog.java201
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSCipherPreferencePane.java112
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSEAGeneralPanel.java169
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSEncryptionPanel.java835
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSErrorLogPanel.java180
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSKRAAutoPanel.java220
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSKRAPasswdPanel.java267
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSKRASchemePanel.java198
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSLDAPSettingPanel.java362
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSNetworkPanel.java465
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSOCSPGeneralPanel.java219
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSPasswordDialog.java310
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSPluginInstanceTab.java442
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSRACLMPanel.java313
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSRAConnectorPanel.java251
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSRAGeneralPanel.java185
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSRALDAPPanel.java44
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSRuleDataModel.java82
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSSMTPPanel.java170
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSSNMPPanel.java296
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSSSL2CipherPreference.java36
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSSSL2CipherSet.java74
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSSSL3CipherPreference.java37
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSSSL3CipherSet.java91
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSSelfTestsPanel.java219
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSTabPanel.java350
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMSUserCertSettingPanel.java155
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CMStoAdminEncryptionPane.java67
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CRLExtensionsConfigDialog.java76
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CRLExtensionsInstanceTab.java114
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CRLExtensionsPluginSelectionDialog.java67
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CRLExtensionsRuleDataModel.java69
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/CRLIPEditor.java330
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ConfigTableModel.java42
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ConnectorEditor.java634
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/EvaluatorRegisterDialog.java41
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/GeneralLogPanel.java250
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/JobsConfigDialog.java62
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/JobsImplDataModel.java68
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/JobsImplTab.java323
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/JobsInstanceTab.java104
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/JobsPluginSelectionDialog.java66
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/JobsRegisterDialog.java40
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/JobsRuleDataModel.java71
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/JobsSettingPanel.java240
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/KeyCreateDialog.java299
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ListCertsModel.java56
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ListKeysModel.java56
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/LogConfigDialog.java62
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/LogImplDataModel.java68
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/LogImplTab.java315
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/LogInstanceTab.java95
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/LogPluginSelectionDialog.java69
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/LogRegisterDialog.java40
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/LogRuleDataModel.java62
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/MNSchemeWizard.java64
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/MNSchemeWizardInfo.java107
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/MapperConfigDialog.java64
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/MapperImplDataModel.java68
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/MapperImplTab.java320
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/MapperInstanceTab.java95
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/MapperPluginSelectionDialog.java74
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/MapperRegisterDialog.java40
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/MapperRuleDataModel.java62
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/OCSPStoresConfigDialog.java60
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/OCSPStoresInstanceTab.java132
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/OCSPStoresPluginSelectionDialog.java67
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/OCSPStoresRuleDataModel.java69
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/PanelMapperConfigDialog.java409
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/PluginSelectionDialog.java375
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/PolicyConfigDialog.java64
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/PolicyImplDataModel.java68
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/PolicyImplTab.java322
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/PolicyInstanceTab.java139
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/PolicyPluginSelectionDialog.java73
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/PolicyRegisterDialog.java40
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/PolicyRuleDataModel.java71
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/PolicyRuleOrderDialog.java331
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ProfileComponentCellEditor.java109
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ProfileConfigDataModel.java83
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ProfileConfigDialog.java396
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ProfileDataTable.java68
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ProfileEditDataModel.java88
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ProfileEditDialog.java931
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ProfileImplDataModel.java70
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ProfileImplTab.java382
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ProfileInstanceTab.java161
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ProfileListDataModel.java60
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ProfileNonPolicyNewDialog.java429
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ProfileNonPolicySelDialog.java386
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ProfilePluginSelectionDialog.java187
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ProfilePolicyEditDataModel.java85
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ProfilePolicyEditDialog.java698
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ProfilePolicyNewDialog.java714
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ProfilePolicySelectionDialog.java515
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ProfileRegisterDialog.java303
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ProfileRuleDataModel.java69
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/PublisherConfigDialog.java64
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/PublisherImplDataModel.java68
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/PublisherImplTab.java321
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/PublisherInstanceTab.java95
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/PublisherPluginSelectionDialog.java74
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/PublisherRegisterDialog.java40
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/PublisherRuleDataModel.java62
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/RegisterDialog.java286
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/RuleConfigDialog.java64
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/RuleImplDataModel.java68
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/RuleImplTab.java320
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/RuleInstanceTab.java97
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/RulePluginSelectionDialog.java74
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/RuleRegisterDialog.java40
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/RuleRuleDataModel.java70
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/TKSKeysTab.java366
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/UserCertsTab.java342
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ViewDialog.java189
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ViewSelfTestsDialog.java172
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/ViewTableModel.java40
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/WBaseCertExtensionPage.java445
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/WBaseCertRequestPage.java261
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/WBaseDNPage.java493
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/WBaseDNValidityPage.java207
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/WBaseKeyPage.java248
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/WBaseManualCertRequestPage.java508
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/WBaseValidityPage.java258
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/WMNNewAgent.java293
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/WMNOldAgent.java214
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/WMNResultPage.java102
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/WMNSelection.java226
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/WMessageDigestPage.java240
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/WarningDialog.java171
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/ComponentCellRenderer.java32
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/InstallWizard.java202
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/InstallWizardInfo.java1724
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIAdminPage.java266
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIAllCertsInstalledPage.java269
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICACert1CustomPage.java72
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICACert1Page.java218
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICACert2Page.java72
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICACertDNPage.java97
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICACertExtensionPage.java80
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICACertPage.java172
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICACertSubmitPage.java79
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICACertValidityPage.java75
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICAKeyPage.java115
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICAMessageDigestPage.java80
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICAOCSPServicePage.java172
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICARequestResultPage.java59
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICASerialNumberPage.java381
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICATokenLogonPage.java76
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICertDNPage.java153
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICertExtensionPage.java168
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICertRequestPage.java73
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICertSetupStatusPage.java144
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICertSubmitPage.java144
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICertValidityPage.java141
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICloneCAKeyCertPage.java292
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICloneKRAKeyCertPage.java292
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICloneMasterPage.java409
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICloneOCSPKeyCertPage.java237
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIClonePage.java142
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICloneRAKeyCertPage.java242
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICloneTKSKeyCertPage.java182
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIConfigWebServerPage.java182
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WICreateInternalDBPage.java581
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIDBEnrollPage.java211
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIDisplayCACertPage.java75
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIDisplayCertPage.java205
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIDisplayKRACertPage.java77
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIDisplayOCSPCertPage.java71
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIDisplayRACertPage.java73
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIDisplaySSLCertPage.java70
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIExistingDBPage.java282
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIGenCAKeyCertPage.java68
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIGenCAKeyCertReqPage.java80
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIGenKRAKeyCertPage.java70
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIGenKRAKeyCertReqPage.java82
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIGenKeyCertPage.java143
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIGenKeyCertReqPage.java291
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIGenOCSPKeyCertPage.java62
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIGenOCSPKeyCertReqPage.java77
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIGenRAKeyCertPage.java67
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIGenRAKeyCertReqPage.java79
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIGenSSLKeyCertReqPage.java76
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIGenServerKeyCertPage.java62
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIInstallCACertStatusPage.java70
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIInstallCAIntroPage.java62
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIInstallCert1Page.java157
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIInstallCert2Page.java140
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIInstallCertStatusPage.java248
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIInstallIntroPage.java133
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIInstallKRACertStatusPage.java72
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIInstallKRAIntroPage.java65
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIInstallOCSPCertStatusPage.java67
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIInstallOCSPIntroPage.java60
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIInstallRACertStatusPage.java69
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIInstallRAIntroPage.java61
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIInstallSSLCertStatusPage.java65
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIInstallSSLIntroPage.java58
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIInternalDBInfoPage.java173
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIInternalDBPage.java313
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIInternalTokenLogonPage.java67
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIIntroMigrationPage.java162
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIIntroPage.java217
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIIntroSingleSignonPage.java162
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIKRACertDNPage.java105
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIKRACertExtensionPage.java75
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIKRACertSubmitPage.java80
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIKRACertValidityPage.java77
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIKRAKeyPage.java100
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIKRAMessageDigestPage.java79
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIKRANumberPage.java378
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIKRARequestResultPage.java58
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIKRAScheme1Page.java188
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIKRAScheme2Page.java309
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIKRAStorageKeyPage.java356
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIKRATokenLogonPage.java74
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIKeyPage.java641
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WILDAPPublishingPage.java279
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WILoggingPage.java202
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WILogonAllTokensPage.java264
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIManualCACertRequestPage.java86
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIManualCertRequestPage.java178
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIManualKRACertRequestPage.java77
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIManualOCSPCertRequestPage.java72
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIManualRACertRequestPage.java74
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIManualSSLCertRequestPage.java69
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIMasterOrClone.java172
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIMigrationPage.java715
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WINetworkPage.java499
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPCertDNPage.java83
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPCertSubmitPage.java76
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPKeyPage.java90
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPMessageDigestPage.java80
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPRequestResultPage.java63
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPTokenLogonPage.java73
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIPasteCACertPage.java67
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIPasteCertPage.java500
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIPasteKRACertPage.java68
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIPasteOCSPCertPage.java63
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIPasteRACertPage.java64
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIPasteSSLCertPage.java60
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIRACertDNPage.java86
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIRACertExtensionPage.java75
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIRACertSubmitPage.java76
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIRACertValidityPage.java74
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIRAKeyPage.java94
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIRAMessageDigestPage.java79
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIRARequestResultPage.java58
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIRATokenLogonPage.java75
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIRecreateDBPage.java139
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIRemoteCASubsystem.java291
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIRemoteKRASubsystem.java371
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIReplAgreementPage.java417
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIRequestResultPage.java148
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WISMTPPage.java129
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WISSLMessageDigestPage.java79
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WISSLRequestResultPage.java58
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WISSLTokenLogonPage.java72
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIServerCertDNPage.java116
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIServerCertExtensionPage.java71
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIServerCertSubmitPage.java89
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIServerCertValidityPage.java69
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIServerKeyPage.java93
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WIServicesPage.java425
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WISingleSignonPage.java532
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WITokenLogonPage.java255
-rw-r--r--base/console/src/com/netscape/admin/certsrv/config/install/WITrustDBPage.java138
-rw-r--r--base/console/src/com/netscape/admin/certsrv/connection/AdminConnection.java818
-rw-r--r--base/console/src/com/netscape/admin/certsrv/connection/BasicAuthenticator.java54
-rw-r--r--base/console/src/com/netscape/admin/certsrv/connection/IAuthenticator.java30
-rw-r--r--base/console/src/com/netscape/admin/certsrv/connection/IConnection.java55
-rw-r--r--base/console/src/com/netscape/admin/certsrv/connection/IConnectionFactory.java40
-rw-r--r--base/console/src/com/netscape/admin/certsrv/connection/JSSConnection.java761
-rw-r--r--base/console/src/com/netscape/admin/certsrv/connection/PromptForTrustDialog.java316
-rw-r--r--base/console/src/com/netscape/admin/certsrv/connection/Request.java70
-rw-r--r--base/console/src/com/netscape/admin/certsrv/connection/Response.java133
-rw-r--r--base/console/src/com/netscape/admin/certsrv/connection/SSLConnectionFactory.java81
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/CertificateServer.gifbin0 -> 363 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/CertificateServerL.gifbin0 -> 501 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/LOGobjs.gifbin0 -> 174 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/UGobjs.gifbin0 -> 176 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/acl.gifbin0 -> 123 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/aclobj.gifbin0 -> 178 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/aclplugin.gifbin0 -> 173 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/alertl.gifbin0 -> 372 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/allfolder16n.gifbin0 -> 878 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/allgroup16n.gifbin0 -> 128 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/alllogdoc16n.gifbin0 -> 154 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/alllogfolder16n.gifbin0 -> 132 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/alluser16n.gifbin0 -> 85 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/alluserwithcert16n.gifbin0 -> 144 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/auth.gifbin0 -> 112 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/authobj.gifbin0 -> 179 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/authplugin.gifbin0 -> 167 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/cert24.gifbin0 -> 501 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/cert41.gifbin0 -> 2153 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/cert42.gifbin0 -> 2291 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/cms-branding.gifbin0 -> 2145 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/error.gifbin0 -> 368 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/genobject.gifbin0 -> 159 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/jobobj.gifbin0 -> 178 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/jobplugin.gifbin0 -> 173 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/jobs.gifbin0 -> 123 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/ldapub.gifbin0 -> 172 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/messagel.gifbin0 -> 693 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/notsecure.gifbin0 -> 157 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/plug.gifbin0 -> 175 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/plugin.gifbin0 -> 143 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/pluginfolder.gifbin0 -> 176 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/red-ball-small.gifbin0 -> 255 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/rule-16.gifbin0 -> 145 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/ruleDisable-16.gifbin0 -> 131 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/ruleplugin-16.gifbin0 -> 172 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/rulesobj.gifbin0 -> 188 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/secure.gifbin0 -> 173 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/servlet-16.gifbin0 -> 104 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/servlet-plugin-16.gifbin0 -> 164 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/images/servletobj.gifbin0 -> 172 bytes
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/CertSetupWizard.java82
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/CertSetupWizardInfo.java412
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WCACertRequest1Page.java237
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WCAKeyPage.java102
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WCertDNPage.java196
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WCertDNValidityPage.java100
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WCertExtensionPage.java273
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WCertMessageDigestPage.java113
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WCertRequestPage.java81
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WCertTypePage.java500
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WCertValidityPage.java139
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WDisplayCertPage.java258
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WExecute1Page.java158
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WExecutePage.java158
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WGenerateReqPage.java92
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WInstallCertChainPage.java141
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WInstallOpPage.java221
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WInstallStatusPage.java105
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WIntroInstallCertPage.java93
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WIntroPage.java120
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WIssueImportStatusPage.java105
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WKeyPage.java809
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WManualCertRequestPage.java199
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WOperationSelectionPage.java134
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WOtherCertRequest1Page.java176
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WPasteCertPage.java261
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WRAKeyPage.java72
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WRequestStatusPage.java142
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WSSLKeyPage.java72
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WTokenLogonPage.java178
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WTokenSelectionPage.java158
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WWarningExecute1Page.java161
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WWarningExecutePage.java154
-rw-r--r--base/console/src/com/netscape/admin/certsrv/keycert/WWarningPage.java143
-rw-r--r--base/console/src/com/netscape/admin/certsrv/managecert/CertificateInfoDialog.java351
-rw-r--r--base/console/src/com/netscape/admin/certsrv/managecert/ManageCertDialog.java362
-rw-r--r--base/console/src/com/netscape/admin/certsrv/managecert/ManageCertModel.java55
-rw-r--r--base/console/src/com/netscape/admin/certsrv/menu/CertManagementAction.java47
-rw-r--r--base/console/src/com/netscape/admin/certsrv/menu/KeyCertAction.java48
-rw-r--r--base/console/src/com/netscape/admin/certsrv/menu/PKCS11ManagementAction.java47
-rw-r--r--base/console/src/com/netscape/admin/certsrv/menu/RefreshTabPane.java101
-rw-r--r--base/console/src/com/netscape/admin/certsrv/misc/MessageFormatter.java138
-rw-r--r--base/console/src/com/netscape/admin/certsrv/notification/RequestCompletePanel.java280
-rw-r--r--base/console/src/com/netscape/admin/certsrv/notification/RequestInQPanel.java302
-rw-r--r--base/console/src/com/netscape/admin/certsrv/notification/RequestRevokedPanel.java283
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/AbstractCipher.java82
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/AbstractCipherPreference.java279
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CRLAddCertDialog.java226
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CRLCertInfoPane.java112
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CRLDeleteCertDialog.java201
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CRLManagementDialog.java309
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CRLTable.java235
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CRLTableModel.java94
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CertBasicInfo.java83
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CertDetailInfoDialog.java111
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CertInfo.java87
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CertInfoDialog.java528
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CertInstallCertInfoPane.java391
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CertInstallCertPane.java236
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CertInstallTypePane.java296
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CertListTable.java316
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CertListTableModel.java91
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CertManagementDialog.java220
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CertRequestCertPane.java197
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CertRequestEnterPasswordPane.java217
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CertRequestInfoPane.java403
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CertRequestSelectTokenPane.java302
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CertRequestTypePane.java390
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/ChangeKeyPasswordDialog.java175
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CipherEntry.java190
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CipherPreferenceDialog.java332
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CipherResourceSet.java26
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/Comm.java158
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/CreateTrustPane.java231
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/EncryptionPane.java639
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/GuideCertInstallPane.java82
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/GuideCertRequestPane.java81
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/GuideCreateTrustPane.java79
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/GuideIntroPane.java119
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/IAbstractCipherSet.java44
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/ICipherConstants.java76
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/IEncryptionPaneListener.java52
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/IKeyCertPage.java26
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/KeyCertTaskInfo.java116
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/KeyCertUtility.java113
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/KeyCertWizard.java328
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/Message.java241
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/MessageDialog.java66
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/PKCS11AddModuleDialog.java165
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/PKCS11ManagementDialog.java242
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/Response.java407
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/SSL2CipherPreference.java56
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/SSL2CipherSet.java85
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/SSL3CipherPreference.java64
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/SSL3CipherSet.java119
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/StatusPane.java153
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/ToggleCipherPreferencePane.java181
-rw-r--r--base/console/src/com/netscape/admin/certsrv/security/WizardObservable.java48
-rw-r--r--base/console/src/com/netscape/admin/certsrv/status/AccessLogDataModel.java43
-rw-r--r--base/console/src/com/netscape/admin/certsrv/status/AuditLogDataModel.java43
-rw-r--r--base/console/src/com/netscape/admin/certsrv/status/CMSLogPanel.java360
-rw-r--r--base/console/src/com/netscape/admin/certsrv/status/DefaultLogParser.java118
-rw-r--r--base/console/src/com/netscape/admin/certsrv/status/ErrorLogDataModel.java43
-rw-r--r--base/console/src/com/netscape/admin/certsrv/status/ILogParser.java38
-rw-r--r--base/console/src/com/netscape/admin/certsrv/status/LogDataModel.java107
-rw-r--r--base/console/src/com/netscape/admin/certsrv/status/LogEntryViewDialog.java202
-rw-r--r--base/console/src/com/netscape/admin/certsrv/status/LogInstancePanel.java157
-rw-r--r--base/console/src/com/netscape/admin/certsrv/status/StatusPanel.java246
-rw-r--r--base/console/src/com/netscape/admin/certsrv/task/AuthDialog.java244
-rw-r--r--base/console/src/com/netscape/admin/certsrv/task/CGITask.java400
-rw-r--r--base/console/src/com/netscape/admin/certsrv/task/CMSCertRequest.java418
-rw-r--r--base/console/src/com/netscape/admin/certsrv/task/CMSConfigCert.java207
-rw-r--r--base/console/src/com/netscape/admin/certsrv/task/CMSImportCert.java429
-rw-r--r--base/console/src/com/netscape/admin/certsrv/task/CMSMigrateCreate.java340
-rw-r--r--base/console/src/com/netscape/admin/certsrv/task/CMSRemove.java166
-rw-r--r--base/console/src/com/netscape/admin/certsrv/task/CMSRequestCert.java421
-rw-r--r--base/console/src/com/netscape/admin/certsrv/task/CMSRestart.java186
-rw-r--r--base/console/src/com/netscape/admin/certsrv/task/CMSStart.java179
-rw-r--r--base/console/src/com/netscape/admin/certsrv/task/CMSStartDaemon.java284
-rw-r--r--base/console/src/com/netscape/admin/certsrv/task/CMSStatus.java207
-rw-r--r--base/console/src/com/netscape/admin/certsrv/task/CMSStop.java161
-rw-r--r--base/console/src/com/netscape/admin/certsrv/task/CreateInstanceDialog.java246
-rw-r--r--base/console/src/com/netscape/admin/certsrv/task/KeyCert.java62
-rw-r--r--base/console/src/com/netscape/admin/certsrv/task/StatusDialog.java186
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/AuthBaseDialog.java355
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/AuthConfigDialog.java91
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/AuthImplDataModel.java72
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/AuthImplTab.java353
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/AuthInstanceTab.java141
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/AuthPluginSelectionDialog.java95
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/AuthRegisterDialog.java40
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/AuthRuleDataModel.java64
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/AuthViewDialog.java65
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/CMSBaseUGTab.java153
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/CMSUGTabPanel.java136
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/CertDataModel.java85
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/CertImportDialog.java256
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/CertManagementDialog.java441
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/CertViewDialog.java201
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/GroupDataModel.java61
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/GroupEditor.java596
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/GroupListDataModel.java67
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/GroupListDialog.java284
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/GroupTab.java369
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/MemberDataModel.java140
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/UserDataModel.java68
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/UserEditor.java627
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/UserListDataModel.java70
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/UserListDialog.java369
-rw-r--r--base/console/src/com/netscape/admin/certsrv/ug/UserTab.java374
-rw-r--r--base/console/src/com/netscape/admin/certsrv/wizard/ConfigServlet.java24
-rw-r--r--base/console/src/com/netscape/admin/certsrv/wizard/IWizardDone.java28
-rw-r--r--base/console/src/com/netscape/admin/certsrv/wizard/IWizardPanel.java98
-rw-r--r--base/console/src/com/netscape/admin/certsrv/wizard/WizardBasePanel.java290
-rw-r--r--base/console/src/com/netscape/admin/certsrv/wizard/WizardInfo.java88
-rw-r--r--base/console/src/com/netscape/admin/certsrv/wizard/WizardWidget.java428
-rw-r--r--base/console/src/com/netscape/certsrv/common/ConfigConstants.java333
-rw-r--r--base/console/src/com/netscape/certsrv/common/Constants.java749
-rw-r--r--base/console/src/com/netscape/certsrv/common/DestDef.java57
-rw-r--r--base/console/src/com/netscape/certsrv/common/NameValuePairs.java80
-rw-r--r--base/console/src/com/netscape/certsrv/common/OpDef.java39
-rw-r--r--base/console/src/com/netscape/certsrv/common/PrefixDef.java41
-rw-r--r--base/console/src/com/netscape/certsrv/common/ScopeDef.java193
-rw-r--r--base/console/src/com/netscape/certsrv/common/TaskId.java129
-rw-r--r--base/console/templates/CMakeLists.txt12
-rwxr-xr-xbase/console/templates/pki_console_wrapper167
-rw-r--r--base/deploy/CMakeLists.txt137
-rw-r--r--base/deploy/LICENSE291
-rw-r--r--base/deploy/config/pkideployment.cfg28
-rwxr-xr-xbase/deploy/src/pkidestroy151
-rwxr-xr-xbase/deploy/src/pkispawn174
-rw-r--r--base/deploy/src/scriptlets/instance.py105
-rw-r--r--base/deploy/src/scriptlets/pkiconfig.py96
-rw-r--r--base/deploy/src/scriptlets/pkihelper.py222
-rw-r--r--base/deploy/src/scriptlets/pkilogging.py46
-rw-r--r--base/deploy/src/scriptlets/pkimessages.py86
-rw-r--r--base/deploy/src/scriptlets/pkiscriptlet.py47
-rw-r--r--base/deploy/src/scriptlets/security_databases.py78
-rw-r--r--base/java-tools/CMakeLists.txt4
-rw-r--r--base/java-tools/LICENSE291
-rw-r--r--base/java-tools/doc/README161
-rw-r--r--base/java-tools/src/CMakeLists.txt87
-rw-r--r--base/java-tools/src/com/netscape/cmstools/AtoB.java146
-rw-r--r--base/java-tools/src/com/netscape/cmstools/AuditVerify.java334
-rw-r--r--base/java-tools/src/com/netscape/cmstools/BtoA.java119
-rw-r--r--base/java-tools/src/com/netscape/cmstools/CMCEnroll.java467
-rw-r--r--base/java-tools/src/com/netscape/cmstools/CMCRequest.java1129
-rw-r--r--base/java-tools/src/com/netscape/cmstools/CMCResponse.java234
-rw-r--r--base/java-tools/src/com/netscape/cmstools/CMCRevoke.java426
-rw-r--r--base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java620
-rw-r--r--base/java-tools/src/com/netscape/cmstools/DRMTool.cfg160
-rw-r--r--base/java-tools/src/com/netscape/cmstools/DRMTool.java5120
-rw-r--r--base/java-tools/src/com/netscape/cmstools/ExtJoiner.java104
-rw-r--r--base/java-tools/src/com/netscape/cmstools/GenExtKeyUsage.java100
-rw-r--r--base/java-tools/src/com/netscape/cmstools/GenIssuerAltNameExt.java141
-rw-r--r--base/java-tools/src/com/netscape/cmstools/GenSubjectAltNameExt.java141
-rw-r--r--base/java-tools/src/com/netscape/cmstools/HttpClient.java403
-rw-r--r--base/java-tools/src/com/netscape/cmstools/OCSPClient.java276
-rw-r--r--base/java-tools/src/com/netscape/cmstools/PKCS10Client.java249
-rw-r--r--base/java-tools/src/com/netscape/cmstools/PKCS12Export.java301
-rw-r--r--base/java-tools/src/com/netscape/cmstools/PasswordCache.java870
-rw-r--r--base/java-tools/src/com/netscape/cmstools/PrettyPrintCert.java248
-rw-r--r--base/java-tools/src/com/netscape/cmstools/PrettyPrintCrl.java212
-rw-r--r--base/java-tools/src/com/netscape/cmstools/TestCRLSigning.java115
-rw-r--r--base/java-tools/src/com/netscape/cmstools/TokenInfo.java75
-rw-r--r--base/java-tools/templates/CMakeLists.txt67
-rw-r--r--base/java-tools/templates/pki_java_command_wrapper.in150
-rw-r--r--base/java-tools/templates/pretty_print_cert_command_wrapper.in178
-rw-r--r--base/java-tools/templates/pretty_print_crl_command_wrapper.in164
-rw-r--r--base/kra/CMakeLists.txt66
-rw-r--r--base/kra/LICENSE291
-rw-r--r--base/kra/functional/drmclient.py1014
-rw-r--r--base/kra/functional/drmclient.readme.txt50
-rw-r--r--base/kra/functional/src/com/netscape/cms/servlet/test/DRMRestClient.java266
-rw-r--r--base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java503
-rw-r--r--base/kra/functional/src/com/netscape/cms/servlet/test/GeneratePKIArchiveOptions.java222
-rw-r--r--base/kra/setup/CMakeLists.txt8
-rw-r--r--base/kra/setup/registry_instance63
-rw-r--r--base/kra/shared/conf/CMakeLists.txt12
-rw-r--r--base/kra/shared/conf/CS.cfg.in383
-rw-r--r--base/kra/shared/conf/acl.ldif42
-rw-r--r--base/kra/shared/conf/catalina.policy184
-rw-r--r--base/kra/shared/conf/catalina.properties87
-rw-r--r--base/kra/shared/conf/context.xml40
-rw-r--r--base/kra/shared/conf/database.ldif4
-rw-r--r--base/kra/shared/conf/db.ldif107
-rw-r--r--base/kra/shared/conf/index.ldif198
-rw-r--r--base/kra/shared/conf/jk2.manifest2
-rw-r--r--base/kra/shared/conf/jk2.properties26
-rw-r--r--base/kra/shared/conf/jkconf.ant.xml51
-rw-r--r--base/kra/shared/conf/jkconfig.manifest2
-rw-r--r--base/kra/shared/conf/logging.properties70
-rw-r--r--base/kra/shared/conf/manager.ldif48
-rw-r--r--base/kra/shared/conf/schema.ldif489
-rw-r--r--base/kra/shared/conf/server-minimal.xml25
-rw-r--r--base/kra/shared/conf/server.xml308
-rw-r--r--base/kra/shared/conf/serverCert.profile37
-rw-r--r--base/kra/shared/conf/serverCertNick.conf1
-rw-r--r--base/kra/shared/conf/shm.manifest2
-rw-r--r--base/kra/shared/conf/storageCert.profile37
-rw-r--r--base/kra/shared/conf/subsystemCert.profile37
-rw-r--r--base/kra/shared/conf/tomcat-jk2.manifest7
-rw-r--r--base/kra/shared/conf/tomcat-users.xml45
-rw-r--r--base/kra/shared/conf/tomcat6.conf58
-rw-r--r--base/kra/shared/conf/transportCert.profile37
-rw-r--r--base/kra/shared/conf/uriworkermap.properties13
-rw-r--r--base/kra/shared/conf/vlv.ldif207
-rw-r--r--base/kra/shared/conf/vlvtasks.ldif19
-rw-r--r--base/kra/shared/conf/web.xml989
-rw-r--r--base/kra/shared/conf/workers.properties206
-rw-r--r--base/kra/shared/conf/workers.properties.minimal17
-rw-r--r--base/kra/shared/conf/workers2.properties132
-rw-r--r--base/kra/shared/conf/workers2.properties.minimal55
-rwxr-xr-xbase/kra/shared/etc/init.d/pki-krad87
-rw-r--r--base/kra/shared/lib/systemd/system/pki-krad.target8
-rw-r--r--base/kra/shared/lib/systemd/system/pki-krad@.service13
-rw-r--r--base/kra/shared/webapps/ROOT/WEB-INF/web.xml29
-rw-r--r--base/kra/shared/webapps/ROOT/index.jsp98
-rw-r--r--base/kra/shared/webapps/kra/WEB-INF/auth.properties16
-rw-r--r--base/kra/shared/webapps/kra/WEB-INF/velocity.properties8
-rw-r--r--base/kra/shared/webapps/kra/WEB-INF/web.xml1115
-rw-r--r--base/kra/src/CMakeLists.txt109
-rw-r--r--base/kra/src/com/netscape/kra/ArchiveOptions.java154
-rw-r--r--base/kra/src/com/netscape/kra/EncryptionUnit.java741
-rw-r--r--base/kra/src/com/netscape/kra/EnrollmentService.java872
-rw-r--r--base/kra/src/com/netscape/kra/KRANotify.java50
-rw-r--r--base/kra/src/com/netscape/kra/KRAPolicy.java78
-rw-r--r--base/kra/src/com/netscape/kra/KRAService.java101
-rw-r--r--base/kra/src/com/netscape/kra/KeyRecoveryAuthority.java1785
-rw-r--r--base/kra/src/com/netscape/kra/NetkeyKeygenService.java608
-rw-r--r--base/kra/src/com/netscape/kra/RecoveryService.java710
-rw-r--r--base/kra/src/com/netscape/kra/SecurityDataRecoveryService.java388
-rw-r--r--base/kra/src/com/netscape/kra/SecurityDataService.java171
-rw-r--r--base/kra/src/com/netscape/kra/StorageKeyUnit.java978
-rw-r--r--base/kra/src/com/netscape/kra/TokenKeyRecoveryService.java627
-rw-r--r--base/kra/src/com/netscape/kra/TransportKeyUnit.java195
-rw-r--r--base/migrate/41ToTxt/classes/CMS41LdifParser.classbin0 -> 9562 bytes
-rw-r--r--base/migrate/41ToTxt/classes/Main.classbin0 -> 1615 bytes
-rwxr-xr-xbase/migrate/41ToTxt/run.bat192
-rwxr-xr-xbase/migrate/41ToTxt/run.sh191
-rw-r--r--base/migrate/41ToTxt/src/Main.java464
-rwxr-xr-xbase/migrate/41ToTxt/src/compile.bat150
-rwxr-xr-xbase/migrate/41ToTxt/src/compile.sh150
-rw-r--r--base/migrate/42SP2ToTxt/classes/CMS42SP2LdifParser.classbin0 -> 9028 bytes
-rw-r--r--base/migrate/42SP2ToTxt/classes/Main.classbin0 -> 1552 bytes
-rwxr-xr-xbase/migrate/42SP2ToTxt/run.bat192
-rwxr-xr-xbase/migrate/42SP2ToTxt/run.sh205
-rw-r--r--base/migrate/42SP2ToTxt/src/Main.java467
-rwxr-xr-xbase/migrate/42SP2ToTxt/src/compile.bat152
-rwxr-xr-xbase/migrate/42SP2ToTxt/src/compile.sh174
-rw-r--r--base/migrate/42ToTxt/classes/CMS42LdifParser.classbin0 -> 9562 bytes
-rw-r--r--base/migrate/42ToTxt/classes/Main.classbin0 -> 1615 bytes
-rwxr-xr-xbase/migrate/42ToTxt/run.bat192
-rwxr-xr-xbase/migrate/42ToTxt/run.sh205
-rw-r--r--base/migrate/42ToTxt/src/Main.java467
-rwxr-xr-xbase/migrate/42ToTxt/src/compile.bat150
-rwxr-xr-xbase/migrate/42ToTxt/src/compile.sh168
-rw-r--r--base/migrate/45ToTxt/classes/CMS45LdifParser.classbin0 -> 9025 bytes
-rw-r--r--base/migrate/45ToTxt/classes/Main.classbin0 -> 1518 bytes
-rwxr-xr-xbase/migrate/45ToTxt/run.bat192
-rwxr-xr-xbase/migrate/45ToTxt/run.sh196
-rw-r--r--base/migrate/45ToTxt/src/Main.java469
-rwxr-xr-xbase/migrate/45ToTxt/src/compile.bat152
-rwxr-xr-xbase/migrate/45ToTxt/src/compile.sh159
-rw-r--r--base/migrate/47ToTxt/classes/CMS47LdifParser.classbin0 -> 10672 bytes
-rw-r--r--base/migrate/47ToTxt/classes/Main.classbin0 -> 1517 bytes
-rwxr-xr-xbase/migrate/47ToTxt/run.bat192
-rwxr-xr-xbase/migrate/47ToTxt/run.sh205
-rw-r--r--base/migrate/47ToTxt/src/Main.java578
-rwxr-xr-xbase/migrate/47ToTxt/src/compile.bat152
-rwxr-xr-xbase/migrate/47ToTxt/src/compile.sh174
-rw-r--r--base/migrate/60ToTxt/classes/CMS60LdifParser.classbin0 -> 9019 bytes
-rw-r--r--base/migrate/60ToTxt/classes/Main.classbin0 -> 1518 bytes
-rwxr-xr-xbase/migrate/60ToTxt/run.bat192
-rwxr-xr-xbase/migrate/60ToTxt/run.sh199
-rw-r--r--base/migrate/60ToTxt/src/Main.java475
-rwxr-xr-xbase/migrate/60ToTxt/src/compile.bat152
-rwxr-xr-xbase/migrate/60ToTxt/src/compile.sh164
-rw-r--r--base/migrate/61ToTxt/classes/CMS61LdifParser.classbin0 -> 9117 bytes
-rw-r--r--base/migrate/61ToTxt/classes/Main.classbin0 -> 1497 bytes
-rwxr-xr-xbase/migrate/61ToTxt/run.bat192
-rwxr-xr-xbase/migrate/61ToTxt/run.sh202
-rw-r--r--base/migrate/61ToTxt/src/Main.java483
-rwxr-xr-xbase/migrate/61ToTxt/src/compile.bat150
-rwxr-xr-xbase/migrate/61ToTxt/src/compile.sh160
-rw-r--r--base/migrate/62ToTxt/classes/CMS62LdifParser.classbin0 -> 9117 bytes
-rw-r--r--base/migrate/62ToTxt/classes/Main.classbin0 -> 1497 bytes
-rwxr-xr-xbase/migrate/62ToTxt/run.bat192
-rwxr-xr-xbase/migrate/62ToTxt/run.sh202
-rw-r--r--base/migrate/62ToTxt/src/Main.java483
-rwxr-xr-xbase/migrate/62ToTxt/src/compile.bat150
-rwxr-xr-xbase/migrate/62ToTxt/src/compile.sh160
-rw-r--r--base/migrate/63ToTxt/classes/CMS63LdifParser.classbin0 -> 8978 bytes
-rw-r--r--base/migrate/63ToTxt/classes/Main.classbin0 -> 1501 bytes
-rwxr-xr-xbase/migrate/63ToTxt/run.bat192
-rwxr-xr-xbase/migrate/63ToTxt/run.sh202
-rw-r--r--base/migrate/63ToTxt/src/Main.java483
-rwxr-xr-xbase/migrate/63ToTxt/src/compile.bat150
-rwxr-xr-xbase/migrate/63ToTxt/src/compile.sh160
-rw-r--r--base/migrate/70ToTxt/classes/CMS70LdifParser.classbin0 -> 8978 bytes
-rw-r--r--base/migrate/70ToTxt/classes/Main.classbin0 -> 1501 bytes
-rwxr-xr-xbase/migrate/70ToTxt/run.bat192
-rwxr-xr-xbase/migrate/70ToTxt/run.sh202
-rw-r--r--base/migrate/70ToTxt/src/Main.java483
-rwxr-xr-xbase/migrate/70ToTxt/src/compile.bat152
-rwxr-xr-xbase/migrate/70ToTxt/src/compile.sh160
-rw-r--r--base/migrate/71ToTxt/classes/CMS71LdifParser.classbin0 -> 8978 bytes
-rw-r--r--base/migrate/71ToTxt/classes/Main.classbin0 -> 1501 bytes
-rwxr-xr-xbase/migrate/71ToTxt/run.bat192
-rwxr-xr-xbase/migrate/71ToTxt/run.sh202
-rw-r--r--base/migrate/71ToTxt/src/Main.java483
-rwxr-xr-xbase/migrate/71ToTxt/src/compile.bat150
-rwxr-xr-xbase/migrate/71ToTxt/src/compile.sh160
-rw-r--r--base/migrate/72ToTxt/classes/CMS72LdifParser.classbin0 -> 9200 bytes
-rw-r--r--base/migrate/72ToTxt/classes/Main.classbin0 -> 1513 bytes
-rwxr-xr-xbase/migrate/72ToTxt/run.bat192
-rwxr-xr-xbase/migrate/72ToTxt/run.sh158
-rw-r--r--base/migrate/72ToTxt/src/Main.java485
-rwxr-xr-xbase/migrate/72ToTxt/src/compile.bat150
-rwxr-xr-xbase/migrate/72ToTxt/src/compile.sh139
-rw-r--r--base/migrate/73ToTxt/classes/CMS73LdifParser.classbin0 -> 9188 bytes
-rw-r--r--base/migrate/73ToTxt/classes/Main.classbin0 -> 1505 bytes
-rwxr-xr-xbase/migrate/73ToTxt/run.bat192
-rwxr-xr-xbase/migrate/73ToTxt/run.sh157
-rw-r--r--base/migrate/73ToTxt/src/Main.java485
-rwxr-xr-xbase/migrate/73ToTxt/src/compile.bat150
-rwxr-xr-xbase/migrate/73ToTxt/src/compile.sh138
-rw-r--r--base/migrate/80/MigrateSecurityDomain.classbin0 -> 6951 bytes
-rw-r--r--base/migrate/80/MigrateSecurityDomain.java235
-rw-r--r--base/migrate/80/readme29
-rw-r--r--base/migrate/80/schema-add.ldif50
-rw-r--r--base/migrate/CMakeLists.txt36
-rw-r--r--base/migrate/LICENSE291
-rw-r--r--base/migrate/TpsTo80/Makefile36
-rwxr-xr-xbase/migrate/TpsTo80/linux/migrateTPSData.i386bin0 -> 10408 bytes
-rwxr-xr-xbase/migrate/TpsTo80/linux/migrateTPSData.x86_64bin0 -> 12616 bytes
-rw-r--r--base/migrate/TpsTo80/migrateTPSData.c501
-rw-r--r--base/migrate/TpsTo80/readme44
-rwxr-xr-xbase/migrate/TpsTo80/solaris/migrateTPSData.sol9sparcbin0 -> 15712 bytes
-rw-r--r--base/migrate/TxtTo60/classes/CMS60LdifParser.classbin0 -> 12047 bytes
-rw-r--r--base/migrate/TxtTo60/classes/DummyAuthManager.classbin0 -> 1187 bytes
-rw-r--r--base/migrate/TxtTo60/classes/Main.classbin0 -> 1518 bytes
-rwxr-xr-xbase/migrate/TxtTo60/run.bat186
-rwxr-xr-xbase/migrate/TxtTo60/run.sh193
-rw-r--r--base/migrate/TxtTo60/src/Main.java630
-rwxr-xr-xbase/migrate/TxtTo60/src/compile.bat154
-rwxr-xr-xbase/migrate/TxtTo60/src/compile.sh166
-rw-r--r--base/migrate/TxtTo61/classes/CMS61LdifParser.classbin0 -> 12150 bytes
-rw-r--r--base/migrate/TxtTo61/classes/DummyAuthManager.classbin0 -> 1187 bytes
-rw-r--r--base/migrate/TxtTo61/classes/Main.classbin0 -> 1497 bytes
-rwxr-xr-xbase/migrate/TxtTo61/run.bat186
-rwxr-xr-xbase/migrate/TxtTo61/run.sh196
-rw-r--r--base/migrate/TxtTo61/src/Main.java644
-rwxr-xr-xbase/migrate/TxtTo61/src/compile.bat152
-rwxr-xr-xbase/migrate/TxtTo61/src/compile.sh162
-rw-r--r--base/migrate/TxtTo62/classes/CMS62LdifParser.classbin0 -> 12355 bytes
-rw-r--r--base/migrate/TxtTo62/classes/DummyAuthManager.classbin0 -> 1187 bytes
-rw-r--r--base/migrate/TxtTo62/classes/Main.classbin0 -> 1497 bytes
-rwxr-xr-xbase/migrate/TxtTo62/run.bat186
-rwxr-xr-xbase/migrate/TxtTo62/run.sh196
-rw-r--r--base/migrate/TxtTo62/src/Main.java655
-rwxr-xr-xbase/migrate/TxtTo62/src/compile.bat152
-rwxr-xr-xbase/migrate/TxtTo62/src/compile.sh162
-rw-r--r--base/migrate/TxtTo70/classes/CMS70LdifParser.classbin0 -> 12270 bytes
-rw-r--r--base/migrate/TxtTo70/classes/DummyAuthManager.classbin0 -> 1187 bytes
-rw-r--r--base/migrate/TxtTo70/classes/Main.classbin0 -> 1501 bytes
-rwxr-xr-xbase/migrate/TxtTo70/run.bat186
-rwxr-xr-xbase/migrate/TxtTo70/run.sh196
-rw-r--r--base/migrate/TxtTo70/src/Main.java655
-rwxr-xr-xbase/migrate/TxtTo70/src/compile.bat154
-rwxr-xr-xbase/migrate/TxtTo70/src/compile.sh162
-rw-r--r--base/migrate/TxtTo71/classes/CMS71LdifParser.classbin0 -> 12270 bytes
-rw-r--r--base/migrate/TxtTo71/classes/DummyAuthManager.classbin0 -> 1187 bytes
-rw-r--r--base/migrate/TxtTo71/classes/Main.classbin0 -> 1501 bytes
-rwxr-xr-xbase/migrate/TxtTo71/run.bat186
-rwxr-xr-xbase/migrate/TxtTo71/run.sh196
-rw-r--r--base/migrate/TxtTo71/src/Main.java655
-rwxr-xr-xbase/migrate/TxtTo71/src/compile.bat152
-rwxr-xr-xbase/migrate/TxtTo71/src/compile.sh162
-rw-r--r--base/migrate/TxtTo72/classes/CMS72LdifParser.classbin0 -> 12186 bytes
-rw-r--r--base/migrate/TxtTo72/classes/DummyAuthManager.classbin0 -> 1187 bytes
-rw-r--r--base/migrate/TxtTo72/classes/Main.classbin0 -> 1513 bytes
-rwxr-xr-xbase/migrate/TxtTo72/run.bat186
-rwxr-xr-xbase/migrate/TxtTo72/run.sh152
-rw-r--r--base/migrate/TxtTo72/src/Main.java659
-rwxr-xr-xbase/migrate/TxtTo72/src/compile.bat152
-rwxr-xr-xbase/migrate/TxtTo72/src/compile.sh141
-rw-r--r--base/migrate/TxtTo73/classes/CMS73LdifParser.classbin0 -> 12166 bytes
-rw-r--r--base/migrate/TxtTo73/classes/DummyAuthManager.classbin0 -> 1187 bytes
-rw-r--r--base/migrate/TxtTo73/classes/Main.classbin0 -> 1505 bytes
-rwxr-xr-xbase/migrate/TxtTo73/run.bat186
-rwxr-xr-xbase/migrate/TxtTo73/run.sh152
-rw-r--r--base/migrate/TxtTo73/src/Main.java659
-rwxr-xr-xbase/migrate/TxtTo73/src/compile.bat152
-rwxr-xr-xbase/migrate/TxtTo73/src/compile.sh141
-rw-r--r--base/migrate/TxtTo80/classes/CS80LdifParser.classbin0 -> 8542 bytes
-rw-r--r--base/migrate/TxtTo80/classes/Main.classbin0 -> 1626 bytes
-rwxr-xr-xbase/migrate/TxtTo80/run.sh394
-rw-r--r--base/migrate/TxtTo80/src/Main.java593
-rwxr-xr-xbase/migrate/TxtTo80/src/compile.sh345
-rwxr-xr-xbase/migrate/kra/RecoverKey.classbin0 -> 3566 bytes
-rwxr-xr-xbase/migrate/kra/RecoverKey.java101
-rwxr-xr-xbase/migrate/kra/RecoverPin.classbin0 -> 5029 bytes
-rwxr-xr-xbase/migrate/kra/RecoverPin.java149
-rwxr-xr-xbase/migrate/kra/readme.txt130
-rw-r--r--base/native-tools/CMakeLists.txt3
-rw-r--r--base/native-tools/LICENSE291
-rw-r--r--base/native-tools/doc/README55
-rw-r--r--base/native-tools/src/CMakeLists.txt5
-rw-r--r--base/native-tools/src/bulkissuance/CMakeLists.txt37
-rw-r--r--base/native-tools/src/bulkissuance/bulkissuance.c807
-rw-r--r--base/native-tools/src/bulkissuance/bulkissuance.data1
-rw-r--r--base/native-tools/src/bulkissuance/getopt.c126
-rw-r--r--base/native-tools/src/p7tool/CMakeLists.txt33
-rw-r--r--base/native-tools/src/p7tool/NSPRerrs.h161
-rw-r--r--base/native-tools/src/p7tool/SECerrs.h523
-rw-r--r--base/native-tools/src/p7tool/SSLerrs.h393
-rw-r--r--base/native-tools/src/p7tool/p7tool.c375
-rw-r--r--base/native-tools/src/p7tool/pppolicy.c309
-rw-r--r--base/native-tools/src/p7tool/secerror.c119
-rw-r--r--base/native-tools/src/p7tool/secerror.h44
-rw-r--r--base/native-tools/src/p7tool/secpwd.c213
-rw-r--r--base/native-tools/src/p7tool/secutil.c3665
-rw-r--r--base/native-tools/src/p7tool/secutil.h430
-rw-r--r--base/native-tools/src/revoker/CMakeLists.txt30
-rw-r--r--base/native-tools/src/revoker/getopt.c126
-rw-r--r--base/native-tools/src/revoker/revoker.c882
-rw-r--r--base/native-tools/src/setpin/CMakeLists.txt43
-rw-r--r--base/native-tools/src/setpin/b64.c102
-rw-r--r--base/native-tools/src/setpin/options.c184
-rw-r--r--base/native-tools/src/setpin/options.h83
-rw-r--r--base/native-tools/src/setpin/setpin.c1237
-rw-r--r--base/native-tools/src/setpin/setpin.conf83
-rw-r--r--base/native-tools/src/setpin/setpin_options.c290
-rw-r--r--base/native-tools/src/setpin/setpin_options.h56
-rw-r--r--base/native-tools/src/sslget/CMakeLists.txt30
-rw-r--r--base/native-tools/src/sslget/getopt.c126
-rw-r--r--base/native-tools/src/sslget/sslget.c836
-rw-r--r--base/native-tools/src/tkstool/CMakeLists.txt45
-rw-r--r--base/native-tools/src/tkstool/NSPRerrs.h161
-rw-r--r--base/native-tools/src/tkstool/SECerrs.h523
-rw-r--r--base/native-tools/src/tkstool/SSLerrs.h393
-rw-r--r--base/native-tools/src/tkstool/delete.c111
-rw-r--r--base/native-tools/src/tkstool/file.c518
-rw-r--r--base/native-tools/src/tkstool/find.c81
-rw-r--r--base/native-tools/src/tkstool/help.c499
-rw-r--r--base/native-tools/src/tkstool/key.c1350
-rw-r--r--base/native-tools/src/tkstool/list.c181
-rw-r--r--base/native-tools/src/tkstool/modules.c63
-rw-r--r--base/native-tools/src/tkstool/pppolicy.c306
-rw-r--r--base/native-tools/src/tkstool/random.c173
-rw-r--r--base/native-tools/src/tkstool/retrieve.c114
-rw-r--r--base/native-tools/src/tkstool/secerror.c118
-rw-r--r--base/native-tools/src/tkstool/secpwd.c213
-rw-r--r--base/native-tools/src/tkstool/secutil.c3662
-rw-r--r--base/native-tools/src/tkstool/secutil.h430
-rw-r--r--base/native-tools/src/tkstool/tkstool.c2660
-rw-r--r--base/native-tools/src/tkstool/tkstool.h321
-rw-r--r--base/native-tools/src/tkstool/util.c640
-rw-r--r--base/native-tools/src/tkstool/version.c49
-rw-r--r--base/ocsp/CMakeLists.txt65
-rw-r--r--base/ocsp/LICENSE291
-rw-r--r--base/ocsp/setup/CMakeLists.txt8
-rw-r--r--base/ocsp/setup/registry_instance63
-rw-r--r--base/ocsp/shared/conf/CMakeLists.txt12
-rw-r--r--base/ocsp/shared/conf/CS.cfg.in333
-rw-r--r--base/ocsp/shared/conf/acl.ldif29
-rw-r--r--base/ocsp/shared/conf/catalina.policy184
-rw-r--r--base/ocsp/shared/conf/catalina.properties87
-rw-r--r--base/ocsp/shared/conf/context.xml40
-rw-r--r--base/ocsp/shared/conf/database.ldif9
-rw-r--r--base/ocsp/shared/conf/db.ldif67
-rw-r--r--base/ocsp/shared/conf/index.ldif203
-rw-r--r--base/ocsp/shared/conf/jk2.manifest2
-rw-r--r--base/ocsp/shared/conf/jk2.properties31
-rw-r--r--base/ocsp/shared/conf/jkconf.ant.xml55
-rw-r--r--base/ocsp/shared/conf/jkconfig.manifest2
-rw-r--r--base/ocsp/shared/conf/logging.properties70
-rw-r--r--base/ocsp/shared/conf/manager.ldif48
-rw-r--r--base/ocsp/shared/conf/schema.ldif489
-rw-r--r--base/ocsp/shared/conf/server-minimal.xml29
-rw-r--r--base/ocsp/shared/conf/server.xml258
-rw-r--r--base/ocsp/shared/conf/serverCertNick.conf6
-rw-r--r--base/ocsp/shared/conf/shm.manifest2
-rw-r--r--base/ocsp/shared/conf/tomcat-jk2.manifest7
-rw-r--r--base/ocsp/shared/conf/tomcat-users.xml45
-rw-r--r--base/ocsp/shared/conf/tomcat6.conf58
-rw-r--r--base/ocsp/shared/conf/uriworkermap.properties18
-rw-r--r--base/ocsp/shared/conf/web.xml993
-rw-r--r--base/ocsp/shared/conf/workers.properties211
-rw-r--r--base/ocsp/shared/conf/workers.properties.minimal22
-rw-r--r--base/ocsp/shared/conf/workers2.properties137
-rw-r--r--base/ocsp/shared/conf/workers2.properties.minimal60
-rwxr-xr-xbase/ocsp/shared/etc/init.d/pki-ocspd87
-rw-r--r--base/ocsp/shared/lib/systemd/system/pki-ocspd.target8
-rw-r--r--base/ocsp/shared/lib/systemd/system/pki-ocspd@.service13
-rw-r--r--base/ocsp/shared/webapps/ROOT/WEB-INF/web.xml29
-rw-r--r--base/ocsp/shared/webapps/ROOT/index.jsp98
-rw-r--r--base/ocsp/shared/webapps/ocsp/WEB-INF/velocity.properties13
-rw-r--r--base/ocsp/shared/webapps/ocsp/WEB-INF/web.xml647
-rw-r--r--base/ocsp/src/CMakeLists.txt99
-rw-r--r--base/ocsp/src/com/netscape/ocsp/EOCSPException.java74
-rw-r--r--base/ocsp/src/com/netscape/ocsp/OCSPAuthority.java643
-rw-r--r--base/ocsp/src/com/netscape/ocsp/OCSPResources.java42
-rw-r--r--base/ocsp/src/com/netscape/ocsp/SigningUnit.java370
-rw-r--r--base/ra/CMakeLists.txt76
-rw-r--r--base/ra/LICENSE291
-rw-r--r--base/ra/apache/conf/httpd.conf1074
-rw-r--r--base/ra/apache/conf/magic382
-rw-r--r--base/ra/apache/conf/mime.types592
-rw-r--r--base/ra/apache/conf/nss.conf267
-rw-r--r--base/ra/apache/conf/perl.conf102
-rw-r--r--base/ra/doc/CMakeLists.txt10
-rw-r--r--base/ra/doc/CS.cfg.in242
-rw-r--r--base/ra/emails/mail_approve_request.vm11
-rw-r--r--base/ra/emails/mail_create_request.vm8
-rwxr-xr-xbase/ra/etc/init.d/pki-rad87
-rwxr-xr-xbase/ra/forms/admin/group/add.cgi86
-rwxr-xr-xbase/ra/forms/admin/group/add_member.cgi80
-rwxr-xr-xbase/ra/forms/admin/group/add_new.cgi86
-rwxr-xr-xbase/ra/forms/admin/group/delete.cgi79
-rwxr-xr-xbase/ra/forms/admin/group/delete_member.cgi79
-rwxr-xr-xbase/ra/forms/admin/group/index.cgi115
-rwxr-xr-xbase/ra/forms/admin/group/read.cgi125
-rwxr-xr-xbase/ra/forms/admin/index.cgi80
-rwxr-xr-xbase/ra/forms/admin/user/add.cgi99
-rwxr-xr-xbase/ra/forms/admin/user/add_new.cgi87
-rwxr-xr-xbase/ra/forms/admin/user/delete.cgi79
-rwxr-xr-xbase/ra/forms/admin/user/index.cgi118
-rwxr-xr-xbase/ra/forms/admin/user/read.cgi97
-rwxr-xr-xbase/ra/forms/agent/cert/index.cgi119
-rwxr-xr-xbase/ra/forms/agent/cert/read.cgi104
-rwxr-xr-xbase/ra/forms/agent/cert/revoke.cgi89
-rwxr-xr-xbase/ra/forms/agent/cert/submit.cgi104
-rwxr-xr-xbase/ra/forms/agent/error.cgi81
-rwxr-xr-xbase/ra/forms/agent/index.cgi83
-rwxr-xr-xbase/ra/forms/agent/request/add_note.cgi93
-rwxr-xr-xbase/ra/forms/agent/request/index.cgi146
-rwxr-xr-xbase/ra/forms/agent/request/op.cgi153
-rwxr-xr-xbase/ra/forms/agent/request/read.cgi119
-rwxr-xr-xbase/ra/forms/ee/agent/enroll.cgi127
-rwxr-xr-xbase/ra/forms/ee/agent/index.cgi68
-rwxr-xr-xbase/ra/forms/ee/agent/new.cgi68
-rwxr-xr-xbase/ra/forms/ee/agent/start.cgi69
-rwxr-xr-xbase/ra/forms/ee/agent/submit.cgi88
-rwxr-xr-xbase/ra/forms/ee/error.cgi81
-rwxr-xr-xbase/ra/forms/ee/index.cgi68
-rwxr-xr-xbase/ra/forms/ee/request/getcert.cgi93
-rwxr-xr-xbase/ra/forms/ee/request/importcert.cgi82
-rwxr-xr-xbase/ra/forms/ee/request/index.cgi68
-rwxr-xr-xbase/ra/forms/ee/request/status.cgi94
-rwxr-xr-xbase/ra/forms/ee/scep/enroll.cgi112
-rwxr-xr-xbase/ra/forms/ee/scep/index.cgi68
-rwxr-xr-xbase/ra/forms/ee/scep/installer.cgi74
-rwxr-xr-xbase/ra/forms/ee/scep/manager.cgi68
-rwxr-xr-xbase/ra/forms/ee/scep/pkiclient.cgi113
-rwxr-xr-xbase/ra/forms/ee/scep/submit.cgi91
-rwxr-xr-xbase/ra/forms/ee/server/admin.cgi68
-rwxr-xr-xbase/ra/forms/ee/server/index.cgi68
-rwxr-xr-xbase/ra/forms/ee/server/submit.cgi93
-rwxr-xr-xbase/ra/forms/ee/user/index.cgi68
-rwxr-xr-xbase/ra/forms/ee/user/renew.cgi165
-rwxr-xr-xbase/ra/forms/ee/user/renewal.cgi74
-rwxr-xr-xbase/ra/forms/ee/user/submit.cgi112
-rwxr-xr-xbase/ra/forms/ee/user/user.cgi68
-rwxr-xr-xbase/ra/forms/index.cgi76
-rw-r--r--base/ra/lib/perl/PKI/Base/CertStore.pm151
-rwxr-xr-xbase/ra/lib/perl/PKI/Base/Conf.pm130
-rw-r--r--base/ra/lib/perl/PKI/Base/PinStore.pm180
-rw-r--r--base/ra/lib/perl/PKI/Base/Registry.pm55
-rwxr-xr-xbase/ra/lib/perl/PKI/Base/TimeTool.pm54
-rw-r--r--base/ra/lib/perl/PKI/Base/UserStore.pm343
-rwxr-xr-xbase/ra/lib/perl/PKI/Base/Util.pm155
-rw-r--r--base/ra/lib/perl/PKI/Conn/CA.pm390
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/AdminAuthPanel.pm86
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/AdminPanel.pm227
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/AgentAuthPanel.pm86
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/BasePanel.pm40
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/CAInfoPanel.pm289
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/CertInfo.pm133
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/CertPrettyPrintPanel.pm85
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/CertRequestPanel.pm301
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/Common.pm50
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/Config.pm170
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/ConfigHSMLoginPanel.pm104
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/ConfigHSMPanel.pm72
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/DRMInfoPanel.pm140
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/DatabasePanel.pm109
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/DisplayCertChain2Panel.pm179
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/DisplayCertChainPanel.pm348
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/DonePanel.pm399
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/GlobalVar.pm42
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/ImportAdminCertPanel.pm142
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/Login.pm466
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/LoginPanel.pm91
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/ModulePanel.pm273
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/Modutil.pm262
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/NamePanel.pm570
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/ReqCertInfo.pm235
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/SecurityDomainPanel.pm199
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/SizePanel.pm245
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/SubsystemTypePanel.pm142
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/TKSInfoPanel.pm134
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/WelcomePanel.pm90
-rwxr-xr-xbase/ra/lib/perl/PKI/RA/wizard.pm502
-rw-r--r--base/ra/lib/perl/PKI/Request/Plugin/AutoAssign.pm52
-rw-r--r--base/ra/lib/perl/PKI/Request/Plugin/CreatePin.pm75
-rw-r--r--base/ra/lib/perl/PKI/Request/Plugin/EmailNotification.pm100
-rw-r--r--base/ra/lib/perl/PKI/Request/Plugin/RequestToCA.pm89
-rw-r--r--base/ra/lib/perl/PKI/Request/Queue.pm387
-rw-r--r--base/ra/lib/perl/PKI/Service/Op.pm290
-rwxr-xr-xbase/ra/lib/perl/Template/Velocity.pm1099
-rwxr-xr-xbase/ra/scripts/nss_pcache66
-rw-r--r--base/ra/scripts/schema.sql33
-rw-r--r--base/ra/setup/CMakeLists.txt8
-rw-r--r--base/ra/setup/registry_instance116
-rwxr-xr-xbase/scripts/enable_cvs_keywords_in_svn97
-rwxr-xr-xbase/scripts/pkicheck13
-rwxr-xr-xbase/scripts/pkimanifest100
-rw-r--r--base/selinux/CMakeLists.txt11
-rw-r--r--base/selinux/LICENSE291
-rw-r--r--base/selinux/src/CMakeLists.txt28
-rw-r--r--base/selinux/src/Makefile18
-rw-r--r--base/selinux/src/pki.fc91
-rw-r--r--base/selinux/src/pki.if745
-rwxr-xr-xbase/selinux/src/pki.sh41
-rw-r--r--base/selinux/src/pki.te332
-rw-r--r--base/setup/CMakeLists.txt43
-rw-r--r--base/setup/LICENSE291
-rw-r--r--base/setup/jars/resteasy-jettison-provider-2.3-RC1.jarbin0 -> 32378 bytes
-rwxr-xr-xbase/setup/pki-setup-proxy499
-rwxr-xr-xbase/setup/pkicommon.pm3580
-rwxr-xr-xbase/setup/pkicreate3479
-rwxr-xr-xbase/setup/pkiremove680
-rw-r--r--base/setup/scripts/functions1121
-rwxr-xr-xbase/setup/scripts/pki_apache_initscript246
-rwxr-xr-xbase/setup/scripts/pkicontrol73
-rw-r--r--base/silent/CMakeLists.txt17
-rw-r--r--base/silent/LICENSE291
-rw-r--r--base/silent/scripts/CMakeLists.txt10
-rwxr-xr-xbase/silent/scripts/pkisilent117
-rw-r--r--base/silent/src/CMakeLists.txt82
-rw-r--r--base/silent/src/com/netscape/pkisilent/ConfigureCA.java1698
-rw-r--r--base/silent/src/com/netscape/pkisilent/ConfigureDRM.java1374
-rw-r--r--base/silent/src/com/netscape/pkisilent/ConfigureOCSP.java1181
-rw-r--r--base/silent/src/com/netscape/pkisilent/ConfigureRA.java881
-rw-r--r--base/silent/src/com/netscape/pkisilent/ConfigureSubCA.java1249
-rw-r--r--base/silent/src/com/netscape/pkisilent/ConfigureTKS.java1121
-rw-r--r--base/silent/src/com/netscape/pkisilent/ConfigureTPS.java1088
-rw-r--r--base/silent/src/com/netscape/pkisilent/PKISilent.java59
-rw-r--r--base/silent/src/com/netscape/pkisilent/argparser/ArgParseException.java54
-rwxr-xr-xbase/silent/src/com/netscape/pkisilent/argparser/ArgParser.java2085
-rw-r--r--base/silent/src/com/netscape/pkisilent/argparser/ArgParserTest.java1514
-rw-r--r--base/silent/src/com/netscape/pkisilent/argparser/BooleanHolder.java54
-rw-r--r--base/silent/src/com/netscape/pkisilent/argparser/CharHolder.java54
-rw-r--r--base/silent/src/com/netscape/pkisilent/argparser/DoubleHolder.java54
-rw-r--r--base/silent/src/com/netscape/pkisilent/argparser/FloatHolder.java54
-rw-r--r--base/silent/src/com/netscape/pkisilent/argparser/IntHolder.java54
-rw-r--r--base/silent/src/com/netscape/pkisilent/argparser/LongHolder.java54
-rw-r--r--base/silent/src/com/netscape/pkisilent/argparser/ObjectHolder.java54
-rw-r--r--base/silent/src/com/netscape/pkisilent/argparser/SimpleExample.java53
-rw-r--r--base/silent/src/com/netscape/pkisilent/argparser/StringHolder.java54
-rw-r--r--base/silent/src/com/netscape/pkisilent/argparser/StringScanException.java56
-rw-r--r--base/silent/src/com/netscape/pkisilent/argparser/StringScanner.java567
-rw-r--r--base/silent/src/com/netscape/pkisilent/common/BaseState.java118
-rw-r--r--base/silent/src/com/netscape/pkisilent/common/CMSConfig.java569
-rw-r--r--base/silent/src/com/netscape/pkisilent/common/CMSLDAP.java609
-rw-r--r--base/silent/src/com/netscape/pkisilent/common/CMSProperties.java679
-rw-r--r--base/silent/src/com/netscape/pkisilent/common/CMSTask.java190
-rw-r--r--base/silent/src/com/netscape/pkisilent/common/CertificateRecord.java44
-rw-r--r--base/silent/src/com/netscape/pkisilent/common/ComCrypto.java767
-rw-r--r--base/silent/src/com/netscape/pkisilent/common/Con2Agent.java318
-rw-r--r--base/silent/src/com/netscape/pkisilent/common/DirEnroll.java470
-rw-r--r--base/silent/src/com/netscape/pkisilent/common/ParseXML.java170
-rw-r--r--base/silent/src/com/netscape/pkisilent/common/PostQuery.java141
-rw-r--r--base/silent/src/com/netscape/pkisilent/common/Request.java1138
-rw-r--r--base/silent/src/com/netscape/pkisilent/common/ServerInfo.java355
-rw-r--r--base/silent/src/com/netscape/pkisilent/common/TestClient.java941
-rw-r--r--base/silent/src/com/netscape/pkisilent/common/UserEnroll.java536
-rw-r--r--base/silent/src/com/netscape/pkisilent/common/Utilities.java347
-rw-r--r--base/silent/src/com/netscape/pkisilent/common/checkRequest.java617
-rw-r--r--base/silent/src/com/netscape/pkisilent/http/CertSelection.java45
-rw-r--r--base/silent/src/com/netscape/pkisilent/http/HTMLDocument.java595
-rw-r--r--base/silent/src/com/netscape/pkisilent/http/HTTPClient.java1231
-rw-r--r--base/silent/src/com/netscape/pkisilent/http/HTTPResponse.java314
-rwxr-xr-xbase/silent/templates/pki_silent.template1732
-rwxr-xr-xbase/silent/templates/subca_silent.template513
-rw-r--r--base/symkey/CMakeLists.txt4
-rw-r--r--base/symkey/LICENSE291
-rw-r--r--base/symkey/src/CMakeLists.txt24
-rw-r--r--base/symkey/src/com/netscape/symkey/Base.h44
-rw-r--r--base/symkey/src/com/netscape/symkey/Buffer.cpp183
-rw-r--r--base/symkey/src/com/netscape/symkey/Buffer.h173
-rw-r--r--base/symkey/src/com/netscape/symkey/CMakeLists.txt63
-rw-r--r--base/symkey/src/com/netscape/symkey/EncryptData.cpp250
-rw-r--r--base/symkey/src/com/netscape/symkey/SessionKey.cpp2005
-rw-r--r--base/symkey/src/com/netscape/symkey/SessionKey.java167
-rw-r--r--base/symkey/src/com/netscape/symkey/SymKey.cpp1407
-rw-r--r--base/symkey/src/com/netscape/symkey/SymKey.h55
-rw-r--r--base/test/CMakeLists.txt3
-rw-r--r--base/test/src/CMakeLists.txt20
-rw-r--r--base/test/src/com/netscape/test/TestListener.java249
-rw-r--r--base/test/src/com/netscape/test/TestRunner.java23
-rw-r--r--base/tks/CMakeLists.txt65
-rw-r--r--base/tks/LICENSE291
-rw-r--r--base/tks/setup/CMakeLists.txt8
-rw-r--r--base/tks/setup/registry_instance63
-rw-r--r--base/tks/shared/conf/CMakeLists.txt12
-rw-r--r--base/tks/shared/conf/CS.cfg.in350
-rw-r--r--base/tks/shared/conf/acl.ldif30
-rw-r--r--base/tks/shared/conf/catalina.policy184
-rw-r--r--base/tks/shared/conf/catalina.properties87
-rw-r--r--base/tks/shared/conf/context.xml40
-rw-r--r--base/tks/shared/conf/database.ldif9
-rw-r--r--base/tks/shared/conf/db.ldif66
-rw-r--r--base/tks/shared/conf/index.ldif203
-rw-r--r--base/tks/shared/conf/jk2.manifest2
-rw-r--r--base/tks/shared/conf/jk2.properties31
-rw-r--r--base/tks/shared/conf/jkconf.ant.xml55
-rw-r--r--base/tks/shared/conf/jkconfig.manifest2
-rw-r--r--base/tks/shared/conf/logging.properties70
-rw-r--r--base/tks/shared/conf/manager.ldif48
-rw-r--r--base/tks/shared/conf/schema.ldif489
-rw-r--r--base/tks/shared/conf/server-minimal.xml29
-rw-r--r--base/tks/shared/conf/server.xml258
-rw-r--r--base/tks/shared/conf/serverCertNick.conf6
-rw-r--r--base/tks/shared/conf/shm.manifest2
-rw-r--r--base/tks/shared/conf/tomcat-jk2.manifest7
-rw-r--r--base/tks/shared/conf/tomcat-users.xml45
-rw-r--r--base/tks/shared/conf/tomcat6.conf58
-rw-r--r--base/tks/shared/conf/uriworkermap.properties18
-rw-r--r--base/tks/shared/conf/web.xml993
-rw-r--r--base/tks/shared/conf/workers.properties211
-rw-r--r--base/tks/shared/conf/workers.properties.minimal22
-rw-r--r--base/tks/shared/conf/workers2.properties137
-rw-r--r--base/tks/shared/conf/workers2.properties.minimal60
-rwxr-xr-xbase/tks/shared/etc/init.d/pki-tksd87
-rw-r--r--base/tks/shared/lib/systemd/system/pki-tksd.target8
-rw-r--r--base/tks/shared/lib/systemd/system/pki-tksd@.service13
-rw-r--r--base/tks/shared/webapps/ROOT/WEB-INF/web.xml28
-rw-r--r--base/tks/shared/webapps/ROOT/index.jsp98
-rw-r--r--base/tks/shared/webapps/tks/WEB-INF/velocity.properties13
-rw-r--r--base/tks/shared/webapps/tks/WEB-INF/web.xml476
-rw-r--r--base/tks/src/CMakeLists.txt96
-rw-r--r--base/tks/src/com/netscape/tks/TKSAuthority.java160
-rw-r--r--base/tps/CMakeLists.txt208
-rw-r--r--base/tps/LICENSE469
-rw-r--r--base/tps/apache/LICENSE-2.0678
-rw-r--r--base/tps/apache/conf/httpd.conf1085
-rw-r--r--base/tps/apache/conf/magic382
-rw-r--r--base/tps/apache/conf/mime.types592
-rw-r--r--base/tps/apache/conf/nss.conf280
-rw-r--r--base/tps/apache/conf/perl.conf70
-rw-r--r--base/tps/apache/pki_instance_command_wrapper192
-rw-r--r--base/tps/apache/pki_subsystem_command_wrapper182
-rw-r--r--base/tps/apache/readme.html1222
-rw-r--r--base/tps/applets/1.2.4122DFB4.ijcbin0 -> 11944 bytes
-rwxr-xr-xbase/tps/applets/1.2.416DA155.ijcbin0 -> 11945 bytes
-rwxr-xr-xbase/tps/applets/1.3.42260AFA.ijcbin0 -> 13117 bytes
-rw-r--r--base/tps/applets/1.3.4255CC01.ijcbin0 -> 14909 bytes
-rwxr-xr-xbase/tps/applets/1.3.42659461.ijcbin0 -> 14879 bytes
-rw-r--r--base/tps/applets/1.3.427BDDB8.ijcbin0 -> 14527 bytes
-rwxr-xr-xbase/tps/applets/1.3.44724DDE.ijcbin0 -> 14529 bytes
-rwxr-xr-xbase/tps/applets/1.3.45787308.ijcbin0 -> 14893 bytes
-rw-r--r--base/tps/applets/1.4.499dc06c.ijcbin0 -> 14912 bytes
-rw-r--r--base/tps/applets/1.4.4d40a449.ijcbin0 -> 14874 bytes
-rw-r--r--base/tps/applets/3FD00877.ijcbin0 -> 13662 bytes
-rw-r--r--base/tps/applets/4003196C.ijcbin0 -> 13683 bytes
-rw-r--r--base/tps/applets/402428AD.ijcbin0 -> 13699 bytes
-rw-r--r--base/tps/applets/404E4697.ijcbin0 -> 11995 bytes
-rw-r--r--base/tps/applets/4122DFB4.ijcbin0 -> 11944 bytes
-rwxr-xr-xbase/tps/applets/listappletdates42
-rw-r--r--base/tps/applets/readme.txt52
-rw-r--r--base/tps/doc/CMakeLists.txt10
-rw-r--r--base/tps/doc/CS.cfg.in1589
-rwxr-xr-xbase/tps/etc/init.d/pki-tpsd87
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/demo/enroll.cgi183
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/demo/index.cgi47
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/home/cachain.cgi52
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/home/enroll.cgi183
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/home/index.cgi51
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/so/enroll.cgi193
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/so/index.cgi48
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/sow/ajax-list.cgi79
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/sow/cfg.pl174
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/sow/enroll.cgi246
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/sow/enroll_temp.cgi246
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/sow/format.cgi207
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/sow/formatso.cgi207
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/sow/index.cgi42
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/sow/is_agent.cgi69
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/sow/is_user.cgi71
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/sow/main.cgi70
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/sow/noaccess.cgi56
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/sow/read.cgi128
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/sow/read_temp.cgi125
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/sow/search.cgi70
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/sow/search_temp.cgi70
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/sow/seturl.cgi207
-rwxr-xr-xbase/tps/forms/esc/cgi-bin/sow/welcome.cgi57
-rwxr-xr-xbase/tps/forms/esc/esc.cgi1239
-rwxr-xr-xbase/tps/forms/esc/home.cgi40
-rwxr-xr-xbase/tps/forms/index.cgi76
-rw-r--r--base/tps/forms/index.html22
-rwxr-xr-xbase/tps/lib/perl/PKI/Base/Conf.pm130
-rwxr-xr-xbase/tps/lib/perl/PKI/Base/Registry.pm55
-rwxr-xr-xbase/tps/lib/perl/PKI/Service/Op.pm127
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/AdminAuthPanel.pm93
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/AdminPanel.pm234
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/AgentAuthPanel.pm91
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/AuthDBPanel.pm172
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/BasePanel.pm39
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/CAInfoPanel.pm315
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/CertInfo.pm132
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/CertPrettyPrintPanel.pm91
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/CertRequestPanel.pm306
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/Common.pm148
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/Config.pm169
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/ConfigHSMLoginPanel.pm112
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/ConfigHSMPanel.pm78
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/DRMInfoPanel.pm180
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/DatabasePanel.pm277
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/DisplayCertChain2Panel.pm186
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/DisplayCertChainPanel.pm355
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/DonePanel.pm437
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/GlobalVar.pm41
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/ImportAdminCertPanel.pm163
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/Login.pm466
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/LoginPanel.pm98
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/ModulePanel.pm278
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/Modutil.pm263
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/NamePanel.pm611
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/ReqCertInfo.pm234
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/SecurityDomainPanel.pm204
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/SizePanel.pm249
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/SubsystemTypePanel.pm147
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/TKSInfoPanel.pm159
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/WelcomePanel.pm96
-rwxr-xr-xbase/tps/lib/perl/PKI/TPS/wizard.pm509
-rwxr-xr-xbase/tps/lib/perl/Template/Velocity.pm1052
-rw-r--r--base/tps/scripts/addAgents.ldif60
-rw-r--r--base/tps/scripts/addIndexes.ldif76
-rw-r--r--base/tps/scripts/addTokens.ldif44
-rw-r--r--base/tps/scripts/addVLVIndexes.ldif51
-rw-r--r--base/tps/scripts/database.ldif39
-rwxr-xr-xbase/tps/scripts/nss_pcache66
-rw-r--r--base/tps/scripts/schemaMods.ldif58
-rw-r--r--base/tps/scripts/vlvtasks.ldif28
-rw-r--r--base/tps/setup/CMakeLists.txt8
-rwxr-xr-xbase/tps/setup/create.pl973
-rw-r--r--base/tps/setup/registry_instance116
-rw-r--r--base/tps/src/CMakeLists.txt148
-rw-r--r--base/tps/src/apdu/APDU.cpp331
-rw-r--r--base/tps/src/apdu/APDU_Response.cpp111
-rw-r--r--base/tps/src/apdu/Create_Object_APDU.cpp121
-rw-r--r--base/tps/src/apdu/Create_Pin_APDU.cpp73
-rw-r--r--base/tps/src/apdu/Delete_File_APDU.cpp59
-rw-r--r--base/tps/src/apdu/External_Authenticate_APDU.cpp76
-rw-r--r--base/tps/src/apdu/Format_Muscle_Applet_APDU.cpp107
-rw-r--r--base/tps/src/apdu/Generate_Key_APDU.cpp68
-rw-r--r--base/tps/src/apdu/Get_Data_APDU.cpp59
-rw-r--r--base/tps/src/apdu/Get_IssuerInfo_APDU.cpp80
-rw-r--r--base/tps/src/apdu/Get_Status_APDU.cpp59
-rw-r--r--base/tps/src/apdu/Get_Version_APDU.cpp59
-rw-r--r--base/tps/src/apdu/Import_Key_APDU.cpp79
-rw-r--r--base/tps/src/apdu/Import_Key_Enc_APDU.cpp70
-rw-r--r--base/tps/src/apdu/Initialize_Update_APDU.cpp66
-rw-r--r--base/tps/src/apdu/Install_Applet_APDU.cpp112
-rw-r--r--base/tps/src/apdu/Install_Load_APDU.cpp91
-rw-r--r--base/tps/src/apdu/Lifecycle_APDU.cpp50
-rw-r--r--base/tps/src/apdu/List_Objects_APDU.cpp61
-rw-r--r--base/tps/src/apdu/List_Pins_APDU.cpp63
-rw-r--r--base/tps/src/apdu/Load_File_APDU.cpp52
-rw-r--r--base/tps/src/apdu/Put_Key_APDU.cpp53
-rw-r--r--base/tps/src/apdu/Read_Buffer_APDU.cpp63
-rw-r--r--base/tps/src/apdu/Read_Object_APDU.cpp88
-rw-r--r--base/tps/src/apdu/Select_APDU.cpp49
-rw-r--r--base/tps/src/apdu/Set_IssuerInfo_APDU.cpp76
-rw-r--r--base/tps/src/apdu/Set_Pin_APDU.cpp76
-rw-r--r--base/tps/src/apdu/Unblock_Pin_APDU.cpp50
-rw-r--r--base/tps/src/apdu/Write_Object_APDU.cpp103
-rw-r--r--base/tps/src/authentication/CMakeLists.txt52
-rw-r--r--base/tps/src/authentication/LDAP_Authentication.cpp424
-rw-r--r--base/tps/src/channel/Channel.cpp69
-rw-r--r--base/tps/src/channel/Secure_Channel.cpp2550
-rw-r--r--base/tps/src/cms/CertEnroll.cpp725
-rw-r--r--base/tps/src/cms/ConnectionInfo.cpp78
-rw-r--r--base/tps/src/cms/HttpConnection.cpp245
-rw-r--r--base/tps/src/engine/RA.cpp3624
-rw-r--r--base/tps/src/httpClient/Cache.cpp496
-rw-r--r--base/tps/src/httpClient/engine.cpp775
-rw-r--r--base/tps/src/httpClient/http.cpp307
-rw-r--r--base/tps/src/httpClient/httpClient.cpp130
-rw-r--r--base/tps/src/httpClient/nscperror.cpp358
-rw-r--r--base/tps/src/httpClient/request.cpp431
-rw-r--r--base/tps/src/httpClient/response.cpp1115
-rw-r--r--base/tps/src/include/apdu/APDU.h116
-rw-r--r--base/tps/src/include/apdu/APDU_Response.h66
-rw-r--r--base/tps/src/include/apdu/Create_Object_APDU.h57
-rw-r--r--base/tps/src/include/apdu/Create_Pin_APDU.h57
-rw-r--r--base/tps/src/include/apdu/Delete_File_APDU.h57
-rw-r--r--base/tps/src/include/apdu/External_Authenticate_APDU.h62
-rw-r--r--base/tps/src/include/apdu/Format_Muscle_Applet_APDU.h65
-rw-r--r--base/tps/src/include/apdu/Generate_Key_APDU.h60
-rw-r--r--base/tps/src/include/apdu/Get_Data_APDU.h58
-rw-r--r--base/tps/src/include/apdu/Get_IssuerInfo_APDU.h58
-rw-r--r--base/tps/src/include/apdu/Get_Status_APDU.h58
-rw-r--r--base/tps/src/include/apdu/Get_Version_APDU.h58
-rw-r--r--base/tps/src/include/apdu/Import_Key_APDU.h58
-rw-r--r--base/tps/src/include/apdu/Import_Key_Enc_APDU.h58
-rw-r--r--base/tps/src/include/apdu/Initialize_Update_APDU.h60
-rw-r--r--base/tps/src/include/apdu/Install_Applet_APDU.h59
-rw-r--r--base/tps/src/include/apdu/Install_Load_APDU.h58
-rw-r--r--base/tps/src/include/apdu/Lifecycle_APDU.h57
-rw-r--r--base/tps/src/include/apdu/List_Objects_APDU.h59
-rw-r--r--base/tps/src/include/apdu/List_Pins_APDU.h60
-rw-r--r--base/tps/src/include/apdu/Load_File_APDU.h57
-rw-r--r--base/tps/src/include/apdu/Put_Key_APDU.h58
-rw-r--r--base/tps/src/include/apdu/Read_Buffer_APDU.h61
-rw-r--r--base/tps/src/include/apdu/Read_Object_APDU.h57
-rw-r--r--base/tps/src/include/apdu/Select_APDU.h58
-rw-r--r--base/tps/src/include/apdu/Set_IssuerInfo_APDU.h59
-rw-r--r--base/tps/src/include/apdu/Set_Pin_APDU.h59
-rw-r--r--base/tps/src/include/apdu/Unblock_Pin_APDU.h54
-rw-r--r--base/tps/src/include/apdu/Write_Object_APDU.h57
-rw-r--r--base/tps/src/include/authentication/AuthParams.h64
-rw-r--r--base/tps/src/include/authentication/Authentication.h80
-rw-r--r--base/tps/src/include/authentication/LDAP_Authentication.h85
-rw-r--r--base/tps/src/include/channel/Channel.h55
-rw-r--r--base/tps/src/include/channel/Secure_Channel.h158
-rw-r--r--base/tps/src/include/cms/CertEnroll.h75
-rw-r--r--base/tps/src/include/cms/ConnectionInfo.h66
-rw-r--r--base/tps/src/include/cms/HttpConnection.h88
-rw-r--r--base/tps/src/include/engine/RA.h374
-rw-r--r--base/tps/src/include/engine/audit.h90
-rw-r--r--base/tps/src/include/httpClient/httpc/AccessLogger.h105
-rw-r--r--base/tps/src/include/httpClient/httpc/Auth.h155
-rw-r--r--base/tps/src/include/httpClient/httpc/ByteBuffer.h194
-rw-r--r--base/tps/src/include/httpClient/httpc/CERTUtil.h65
-rw-r--r--base/tps/src/include/httpClient/httpc/Cache.h226
-rw-r--r--base/tps/src/include/httpClient/httpc/Connection.h117
-rw-r--r--base/tps/src/include/httpClient/httpc/ConnectionListener.h58
-rw-r--r--base/tps/src/include/httpClient/httpc/DebugLogger.h185
-rw-r--r--base/tps/src/include/httpClient/httpc/Defines.h219
-rw-r--r--base/tps/src/include/httpClient/httpc/ErrorLogger.h93
-rw-r--r--base/tps/src/include/httpClient/httpc/Iterator.h62
-rw-r--r--base/tps/src/include/httpClient/httpc/LogRotationTask.h132
-rw-r--r--base/tps/src/include/httpClient/httpc/Logger.h117
-rw-r--r--base/tps/src/include/httpClient/httpc/NSPRerrs.h160
-rw-r--r--base/tps/src/include/httpClient/httpc/PSBuddy.h89
-rw-r--r--base/tps/src/include/httpClient/httpc/PSBuddyCache.h123
-rw-r--r--base/tps/src/include/httpClient/httpc/PSBuddyList.h373
-rw-r--r--base/tps/src/include/httpClient/httpc/PSBuddyListener.h78
-rw-r--r--base/tps/src/include/httpClient/httpc/PSBuddyService.h121
-rw-r--r--base/tps/src/include/httpClient/httpc/PSCertExtension.h153
-rw-r--r--base/tps/src/include/httpClient/httpc/PSCommonLib.h52
-rw-r--r--base/tps/src/include/httpClient/httpc/PSConfig.h67
-rw-r--r--base/tps/src/include/httpClient/httpc/PSConfigManager.h66
-rw-r--r--base/tps/src/include/httpClient/httpc/PSConfigReader.h71
-rw-r--r--base/tps/src/include/httpClient/httpc/PSCrypt.h79
-rw-r--r--base/tps/src/include/httpClient/httpc/PSDataSourceListener.h106
-rw-r--r--base/tps/src/include/httpClient/httpc/PSDataSourceManager.h152
-rw-r--r--base/tps/src/include/httpClient/httpc/PSGroup.h97
-rw-r--r--base/tps/src/include/httpClient/httpc/PSGroupCache.h74
-rw-r--r--base/tps/src/include/httpClient/httpc/PSHelper.h70
-rw-r--r--base/tps/src/include/httpClient/httpc/PSListener.h55
-rw-r--r--base/tps/src/include/httpClient/httpc/PSPRUtil.h92
-rw-r--r--base/tps/src/include/httpClient/httpc/PSPlugin.h81
-rw-r--r--base/tps/src/include/httpClient/httpc/PSPluginManager.h102
-rw-r--r--base/tps/src/include/httpClient/httpc/PSServer.h95
-rw-r--r--base/tps/src/include/httpClient/httpc/PSServerLib.h62
-rw-r--r--base/tps/src/include/httpClient/httpc/PSServerListener.h85
-rw-r--r--base/tps/src/include/httpClient/httpc/PSServerManager.h145
-rw-r--r--base/tps/src/include/httpClient/httpc/PSServiceListener.h87
-rw-r--r--base/tps/src/include/httpClient/httpc/PSServiceManager.h145
-rw-r--r--base/tps/src/include/httpClient/httpc/PSUser.h164
-rw-r--r--base/tps/src/include/httpClient/httpc/PSWaspLib.h55
-rw-r--r--base/tps/src/include/httpClient/httpc/Pool.h149
-rw-r--r--base/tps/src/include/httpClient/httpc/PresenceManager.h93
-rw-r--r--base/tps/src/include/httpClient/httpc/PresenceServer.h60
-rw-r--r--base/tps/src/include/httpClient/httpc/PresenceServerImpl.h111
-rw-r--r--base/tps/src/include/httpClient/httpc/SECerrs.h522
-rw-r--r--base/tps/src/include/httpClient/httpc/SSLServerSocket.h93
-rw-r--r--base/tps/src/include/httpClient/httpc/SSLSocket.h132
-rw-r--r--base/tps/src/include/httpClient/httpc/SSLerrs.h392
-rw-r--r--base/tps/src/include/httpClient/httpc/ScheduledTask.h86
-rw-r--r--base/tps/src/include/httpClient/httpc/Scheduler.h103
-rw-r--r--base/tps/src/include/httpClient/httpc/SecurityHeaders.h48
-rw-r--r--base/tps/src/include/httpClient/httpc/ServerConnection.h179
-rw-r--r--base/tps/src/include/httpClient/httpc/ServerHeaderProcessor.h72
-rw-r--r--base/tps/src/include/httpClient/httpc/ServerSocket.h113
-rw-r--r--base/tps/src/include/httpClient/httpc/Socket.h157
-rw-r--r--base/tps/src/include/httpClient/httpc/SocketINC.h163
-rw-r--r--base/tps/src/include/httpClient/httpc/SocketLib.h62
-rw-r--r--base/tps/src/include/httpClient/httpc/StringList.h151
-rw-r--r--base/tps/src/include/httpClient/httpc/StringUtil.h74
-rw-r--r--base/tps/src/include/httpClient/httpc/TaskList.h114
-rw-r--r--base/tps/src/include/httpClient/httpc/ThreadPool.h159
-rw-r--r--base/tps/src/include/httpClient/httpc/URLUtil.h92
-rw-r--r--base/tps/src/include/httpClient/httpc/engine.h77
-rw-r--r--base/tps/src/include/httpClient/httpc/http.h120
-rw-r--r--base/tps/src/include/httpClient/httpc/request.h115
-rw-r--r--base/tps/src/include/httpClient/httpc/response.h148
-rw-r--r--base/tps/src/include/main/AttributeSpec.h68
-rw-r--r--base/tps/src/include/main/AuthenticationEntry.h64
-rw-r--r--base/tps/src/include/main/Base.h63
-rw-r--r--base/tps/src/include/main/Buffer.h196
-rw-r--r--base/tps/src/include/main/ConfigStore.h126
-rw-r--r--base/tps/src/include/main/LogFile.h89
-rw-r--r--base/tps/src/include/main/Login.h55
-rw-r--r--base/tps/src/include/main/Memory.h130
-rw-r--r--base/tps/src/include/main/MemoryMgr.h46
-rw-r--r--base/tps/src/include/main/NameValueSet.h72
-rw-r--r--base/tps/src/include/main/ObjectSpec.h79
-rw-r--r--base/tps/src/include/main/PKCS11Obj.h80
-rw-r--r--base/tps/src/include/main/PublishEntry.h57
-rw-r--r--base/tps/src/include/main/RA_Context.h57
-rw-r--r--base/tps/src/include/main/RA_Msg.h79
-rw-r--r--base/tps/src/include/main/RA_Session.h61
-rw-r--r--base/tps/src/include/main/RA_pblock.h74
-rw-r--r--base/tps/src/include/main/RollingLogFile.h93
-rw-r--r--base/tps/src/include/main/SecureId.h55
-rw-r--r--base/tps/src/include/main/Util.h99
-rw-r--r--base/tps/src/include/modules/tps/AP_Context.h57
-rw-r--r--base/tps/src/include/modules/tps/AP_Session.h56
-rw-r--r--base/tps/src/include/msg/RA_ASQ_Request_Msg.h62
-rw-r--r--base/tps/src/include/msg/RA_ASQ_Response_Msg.h62
-rw-r--r--base/tps/src/include/msg/RA_Begin_Op_Msg.h64
-rw-r--r--base/tps/src/include/msg/RA_End_Op_Msg.h84
-rw-r--r--base/tps/src/include/msg/RA_Extended_Login_Request_Msg.h73
-rw-r--r--base/tps/src/include/msg/RA_Extended_Login_Response_Msg.h63
-rw-r--r--base/tps/src/include/msg/RA_Login_Request_Msg.h63
-rw-r--r--base/tps/src/include/msg/RA_Login_Response_Msg.h64
-rw-r--r--base/tps/src/include/msg/RA_New_Pin_Request_Msg.h63
-rw-r--r--base/tps/src/include/msg/RA_New_Pin_Response_Msg.h62
-rw-r--r--base/tps/src/include/msg/RA_SecureId_Request_Msg.h63
-rw-r--r--base/tps/src/include/msg/RA_SecureId_Response_Msg.h64
-rw-r--r--base/tps/src/include/msg/RA_Status_Update_Request_Msg.h65
-rw-r--r--base/tps/src/include/msg/RA_Status_Update_Response_Msg.h63
-rw-r--r--base/tps/src/include/msg/RA_Token_PDU_Request_Msg.h63
-rw-r--r--base/tps/src/include/msg/RA_Token_PDU_Response_Msg.h62
-rw-r--r--base/tps/src/include/processor/RA_Enroll_Processor.h300
-rw-r--r--base/tps/src/include/processor/RA_Format_Processor.h57
-rw-r--r--base/tps/src/include/processor/RA_Pin_Reset_Processor.h57
-rw-r--r--base/tps/src/include/processor/RA_Processor.h214
-rw-r--r--base/tps/src/include/processor/RA_Renew_Processor.h57
-rw-r--r--base/tps/src/include/processor/RA_Unblock_Processor.h57
-rw-r--r--base/tps/src/include/publisher/IConnector.h58
-rw-r--r--base/tps/src/include/publisher/IPublish_Data.h56
-rw-r--r--base/tps/src/include/publisher/IPublisher.h74
-rw-r--r--base/tps/src/include/publisher/NetkeyPublisher.h74
-rw-r--r--base/tps/src/include/selftests/SelfTest.h74
-rw-r--r--base/tps/src/include/selftests/TPSPresence.h78
-rw-r--r--base/tps/src/include/selftests/TPSSystemCertsVerification.h76
-rw-r--r--base/tps/src/include/selftests/TPSValidity.h79
-rw-r--r--base/tps/src/include/service/NK_Context.h57
-rw-r--r--base/tps/src/include/service/NK_Session.h58
-rw-r--r--base/tps/src/include/tus/tus_db.h273
-rw-r--r--base/tps/src/main/AttributeSpec.cpp115
-rw-r--r--base/tps/src/main/AuthParams.cpp72
-rw-r--r--base/tps/src/main/Authentication.cpp105
-rw-r--r--base/tps/src/main/AuthenticationEntry.cpp91
-rw-r--r--base/tps/src/main/Buffer.cpp243
-rw-r--r--base/tps/src/main/ConfigStore.cpp893
-rw-r--r--base/tps/src/main/LogFile.cpp298
-rw-r--r--base/tps/src/main/Login.cpp72
-rw-r--r--base/tps/src/main/Memory.cpp268
-rw-r--r--base/tps/src/main/NameValueSet.cpp322
-rw-r--r--base/tps/src/main/ObjectSpec.cpp515
-rw-r--r--base/tps/src/main/PKCS11Obj.cpp491
-rw-r--r--base/tps/src/main/RA_Context.cpp56
-rw-r--r--base/tps/src/main/RA_Msg.cpp45
-rw-r--r--base/tps/src/main/RA_Session.cpp75
-rw-r--r--base/tps/src/main/RA_pblock.cpp176
-rw-r--r--base/tps/src/main/RollingLogFile.cpp493
-rw-r--r--base/tps/src/main/SecureId.cpp71
-rw-r--r--base/tps/src/main/Util.cpp1168
-rw-r--r--base/tps/src/modules/CMakeLists.txt2
-rw-r--r--base/tps/src/modules/tokendb/CMakeLists.txt48
-rw-r--r--base/tps/src/modules/tokendb/mod_tokendb.cpp7756
-rw-r--r--base/tps/src/modules/tps/AP_Context.cpp83
-rw-r--r--base/tps/src/modules/tps/AP_Session.cpp1169
-rw-r--r--base/tps/src/modules/tps/CMakeLists.txt52
-rw-r--r--base/tps/src/modules/tps/mod_tps.cpp732
-rw-r--r--base/tps/src/msg/RA_ASQ_Request_Msg.cpp70
-rw-r--r--base/tps/src/msg/RA_ASQ_Response_Msg.cpp68
-rw-r--r--base/tps/src/msg/RA_Begin_Op_Msg.cpp72
-rw-r--r--base/tps/src/msg/RA_End_Op_Msg.cpp73
-rw-r--r--base/tps/src/msg/RA_Extended_Login_Request_Msg.cpp114
-rw-r--r--base/tps/src/msg/RA_Extended_Login_Response_Msg.cpp65
-rw-r--r--base/tps/src/msg/RA_Login_Request_Msg.cpp71
-rw-r--r--base/tps/src/msg/RA_Login_Response_Msg.cpp85
-rw-r--r--base/tps/src/msg/RA_New_Pin_Request_Msg.cpp70
-rw-r--r--base/tps/src/msg/RA_New_Pin_Response_Msg.cpp68
-rw-r--r--base/tps/src/msg/RA_SecureId_Request_Msg.cpp69
-rw-r--r--base/tps/src/msg/RA_SecureId_Response_Msg.cpp83
-rw-r--r--base/tps/src/msg/RA_Status_Update_Request_Msg.cpp66
-rw-r--r--base/tps/src/msg/RA_Status_Update_Response_Msg.cpp56
-rw-r--r--base/tps/src/msg/RA_Token_PDU_Request_Msg.cpp63
-rw-r--r--base/tps/src/msg/RA_Token_PDU_Response_Msg.cpp68
-rw-r--r--base/tps/src/processor/RA_Enroll_Processor.cpp5194
-rw-r--r--base/tps/src/processor/RA_Format_Processor.cpp70
-rw-r--r--base/tps/src/processor/RA_Pin_Reset_Processor.cpp1013
-rw-r--r--base/tps/src/processor/RA_Processor.cpp3506
-rw-r--r--base/tps/src/processor/RA_Renew_Processor.cpp57
-rw-r--r--base/tps/src/processor/RA_Unblock_Processor.cpp58
-rw-r--r--base/tps/src/selftests/SelfTest.cpp220
-rw-r--r--base/tps/src/selftests/TPSPresence.cpp204
-rw-r--r--base/tps/src/selftests/TPSSystemCertsVerification.cpp149
-rw-r--r--base/tps/src/selftests/TPSValidity.cpp215
-rw-r--r--base/tps/src/test/Test_ConfigStore.cfg28
-rw-r--r--base/tps/src/test/Test_ConfigStore.cpp79
-rw-r--r--base/tps/src/tus/CMakeLists.txt50
-rw-r--r--base/tps/src/tus/tus_db.c4515
-rw-r--r--base/tps/stubs/modules/nss/mod_nss_stub.c51
-rw-r--r--base/tps/tools/CMakeLists.txt1
-rw-r--r--base/tps/tools/raclient/CMakeLists.txt47
-rw-r--r--base/tps/tools/raclient/RA_Client.cpp1645
-rw-r--r--base/tps/tools/raclient/RA_Client.h78
-rw-r--r--base/tps/tools/raclient/RA_Conn.cpp1037
-rw-r--r--base/tps/tools/raclient/RA_Conn.h71
-rw-r--r--base/tps/tools/raclient/RA_Token.cpp2008
-rw-r--r--base/tps/tools/raclient/RA_Token.h225
-rw-r--r--base/tps/tools/raclient/enroll.tps42
-rw-r--r--base/tps/tools/raclient/enroll1.test43
-rw-r--r--base/tps/tools/raclient/format.tps45
-rw-r--r--base/tps/tools/raclient/nt_enroll.test212
-rw-r--r--base/tps/tools/raclient/readme.txt247
-rw-r--r--base/tps/tools/raclient/reset_pin.tps42
-rw-r--r--base/tps/tools/raclient/reset_pin1.test40
-rw-r--r--base/tps/tools/raclient/reset_pin2.test39
-rw-r--r--base/tps/tools/tus/add.c117
-rw-r--r--base/tps/tools/tus/test.c117
-rwxr-xr-xbase/tps/ui/perl/Velocity.pm1047
-rwxr-xr-xbase/tps/wrappers/tpsclient.in78
-rw-r--r--base/util/CMakeLists.txt4
-rw-r--r--base/util/LICENSE291
-rw-r--r--base/util/src/CMakeLists.txt369
-rw-r--r--base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java1292
-rw-r--r--base/util/src/com/netscape/cmsutil/crypto/Module.java75
-rw-r--r--base/util/src/com/netscape/cmsutil/crypto/Token.java57
-rw-r--r--base/util/src/com/netscape/cmsutil/http/ConnectAsync.java46
-rw-r--r--base/util/src/com/netscape/cmsutil/http/Http.java31
-rw-r--r--base/util/src/com/netscape/cmsutil/http/HttpClient.java217
-rw-r--r--base/util/src/com/netscape/cmsutil/http/HttpEofException.java35
-rw-r--r--base/util/src/com/netscape/cmsutil/http/HttpMessage.java163
-rw-r--r--base/util/src/com/netscape/cmsutil/http/HttpProtocolException.java35
-rw-r--r--base/util/src/com/netscape/cmsutil/http/HttpRequest.java137
-rw-r--r--base/util/src/com/netscape/cmsutil/http/HttpResponse.java139
-rw-r--r--base/util/src/com/netscape/cmsutil/http/JssSSLSocketFactory.java182
-rw-r--r--base/util/src/com/netscape/cmsutil/ldap/LDAPUtil.java101
-rw-r--r--base/util/src/com/netscape/cmsutil/net/ISocketFactory.java38
-rw-r--r--base/util/src/com/netscape/cmsutil/ocsp/BasicOCSPResponse.java195
-rw-r--r--base/util/src/com/netscape/cmsutil/ocsp/CertID.java155
-rw-r--r--base/util/src/com/netscape/cmsutil/ocsp/CertStatus.java35
-rw-r--r--base/util/src/com/netscape/cmsutil/ocsp/GoodInfo.java98
-rw-r--r--base/util/src/com/netscape/cmsutil/ocsp/KeyHashID.java105
-rw-r--r--base/util/src/com/netscape/cmsutil/ocsp/NameID.java106
-rw-r--r--base/util/src/com/netscape/cmsutil/ocsp/OCSPRequest.java140
-rw-r--r--base/util/src/com/netscape/cmsutil/ocsp/OCSPResponse.java135
-rw-r--r--base/util/src/com/netscape/cmsutil/ocsp/OCSPResponseStatus.java120
-rw-r--r--base/util/src/com/netscape/cmsutil/ocsp/Request.java147
-rw-r--r--base/util/src/com/netscape/cmsutil/ocsp/ResponderID.java34
-rw-r--r--base/util/src/com/netscape/cmsutil/ocsp/Response.java34
-rw-r--r--base/util/src/com/netscape/cmsutil/ocsp/ResponseBytes.java130
-rw-r--r--base/util/src/com/netscape/cmsutil/ocsp/ResponseData.java222
-rw-r--r--base/util/src/com/netscape/cmsutil/ocsp/RevokedInfo.java113
-rw-r--r--base/util/src/com/netscape/cmsutil/ocsp/Signature.java159
-rw-r--r--base/util/src/com/netscape/cmsutil/ocsp/SingleResponse.java182
-rw-r--r--base/util/src/com/netscape/cmsutil/ocsp/TBSRequest.java210
-rw-r--r--base/util/src/com/netscape/cmsutil/ocsp/UnknownInfo.java95
-rw-r--r--base/util/src/com/netscape/cmsutil/password/IPasswordReader.java29
-rw-r--r--base/util/src/com/netscape/cmsutil/password/IPasswordStore.java34
-rw-r--r--base/util/src/com/netscape/cmsutil/password/IPasswordWriter.java30
-rw-r--r--base/util/src/com/netscape/cmsutil/password/PlainPasswordFile.java70
-rw-r--r--base/util/src/com/netscape/cmsutil/password/PlainPasswordReader.java58
-rw-r--r--base/util/src/com/netscape/cmsutil/password/PlainPasswordWriter.java56
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/AccessAccept.java27
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/AccessChallenge.java27
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/AccessReject.java27
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/AccessRequest.java25
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/Attribute.java97
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/AttributeFactory.java154
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/AttributeSet.java56
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/Authenticator.java24
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/CHAPChallengeAttribute.java38
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/CHAPPasswordAttribute.java55
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/CallbackIdAttribute.java40
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/CallbackNumberAttribute.java40
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/CallerStationIdAttribute.java40
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/CallingStationIdAttribute.java40
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/ChallengeException.java43
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/FilterIdAttribute.java40
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/FramedAppleTalkLinkAttribute.java51
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/FramedAppleTalkNetworkAttribute.java49
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/FramedAppleTalkZoneAttribute.java40
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/FramedCompressionAttribute.java54
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/FramedIPAddressAttribute.java39
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/FramedIPNetmaskAttribute.java39
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/FramedIPXNetworkAttribute.java39
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/FramedMTUAttribute.java49
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/FramedProtocolAttribute.java56
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/FramedRouteAttribute.java40
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/FramedRoutingAttribute.java54
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/GenericAttribute.java35
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/IdleTimeoutAttribute.java52
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/LoginIPHostAttribute.java52
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/LoginLATGroupAttribute.java40
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/LoginLATNodeAttribute.java40
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/LoginLATPortAttribute.java40
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/LoginLATServiceAttribute.java40
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/LoginServiceAttribute.java58
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/LoginTCPPortAttribute.java52
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/NASClassAttribute.java40
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/NASIPAddressAttribute.java41
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/NASIdentifierAttribute.java40
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/NASPacket.java52
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/NASPortAttribute.java48
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/NASPortTypeAttribute.java53
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/Packet.java70
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/PacketFactory.java39
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/PortLimitAttribute.java51
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/ProxyStateAttribute.java40
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/RadiusConn.java230
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/RejectException.java39
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/ReplyMessageAttribute.java40
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/RequestAuthenticator.java44
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/ResponseAuthenticator.java32
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/ServerPacket.java47
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/ServiceTypeAttribute.java61
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/SessionTimeoutAttribute.java48
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/StateAttribute.java45
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/TerminationActionAttribute.java55
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/UserNameAttribute.java39
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/UserPasswordAttribute.java73
-rw-r--r--base/util/src/com/netscape/cmsutil/radius/VendorSpecificAttribute.java52
-rw-r--r--base/util/src/com/netscape/cmsutil/scep/CRSPKIMessage.java905
-rw-r--r--base/util/src/com/netscape/cmsutil/util/Cert.java186
-rw-r--r--base/util/src/com/netscape/cmsutil/util/Fmt.java605
-rw-r--r--base/util/src/com/netscape/cmsutil/util/HMACDigest.java198
-rw-r--r--base/util/src/com/netscape/cmsutil/util/Utils.java276
-rw-r--r--base/util/src/com/netscape/cmsutil/xml/XMLObject.java187
-rw-r--r--base/util/src/netscape/net/NetworkClient.java87
-rw-r--r--base/util/src/netscape/net/TransferProtocolClient.java127
-rw-r--r--base/util/src/netscape/net/smtp/SmtpClient.java235
-rw-r--r--base/util/src/netscape/net/smtp/SmtpProtocolException.java35
-rw-r--r--base/util/src/netscape/security/acl/AclEntryImpl.java182
-rw-r--r--base/util/src/netscape/security/acl/AclImpl.java391
-rw-r--r--base/util/src/netscape/security/acl/AllPermissionsImpl.java43
-rw-r--r--base/util/src/netscape/security/acl/GroupImpl.java173
-rw-r--r--base/util/src/netscape/security/acl/OwnerImpl.java105
-rw-r--r--base/util/src/netscape/security/acl/PermissionImpl.java65
-rw-r--r--base/util/src/netscape/security/acl/PrincipalImpl.java77
-rw-r--r--base/util/src/netscape/security/acl/WorldGroupImpl.java42
-rw-r--r--base/util/src/netscape/security/extensions/AccessDescription.java76
-rw-r--r--base/util/src/netscape/security/extensions/AuthInfoAccessExtension.java272
-rw-r--r--base/util/src/netscape/security/extensions/CertInfo.java120
-rw-r--r--base/util/src/netscape/security/extensions/CertificateRenewalWindowExtension.java190
-rw-r--r--base/util/src/netscape/security/extensions/CertificateScopeEntry.java103
-rw-r--r--base/util/src/netscape/security/extensions/CertificateScopeOfUseExtension.java199
-rw-r--r--base/util/src/netscape/security/extensions/ExtendedKeyUsageExtension.java226
-rw-r--r--base/util/src/netscape/security/extensions/GenericASN1Extension.java448
-rw-r--r--base/util/src/netscape/security/extensions/InhibitAnyPolicyExtension.java179
-rw-r--r--base/util/src/netscape/security/extensions/KerberosName.java135
-rw-r--r--base/util/src/netscape/security/extensions/NSCertTypeExtension.java377
-rw-r--r--base/util/src/netscape/security/extensions/OCSPNoCheckExtension.java153
-rw-r--r--base/util/src/netscape/security/extensions/PresenceServerExtension.java321
-rw-r--r--base/util/src/netscape/security/extensions/SubjectInfoAccessExtension.java254
-rw-r--r--base/util/src/netscape/security/pkcs/ContentInfo.java155
-rw-r--r--base/util/src/netscape/security/pkcs/EncodingException.java33
-rw-r--r--base/util/src/netscape/security/pkcs/PKCS10.java343
-rw-r--r--base/util/src/netscape/security/pkcs/PKCS10Attribute.java238
-rw-r--r--base/util/src/netscape/security/pkcs/PKCS10Attributes.java147
-rw-r--r--base/util/src/netscape/security/pkcs/PKCS7.java446
-rw-r--r--base/util/src/netscape/security/pkcs/PKCS8Key.java435
-rw-r--r--base/util/src/netscape/security/pkcs/PKCS9Attribute.java1123
-rw-r--r--base/util/src/netscape/security/pkcs/PKCS9Attributes.java312
-rw-r--r--base/util/src/netscape/security/pkcs/ParsingException.java35
-rw-r--r--base/util/src/netscape/security/pkcs/SignerInfo.java347
-rw-r--r--base/util/src/netscape/security/provider/CMS.java52
-rw-r--r--base/util/src/netscape/security/provider/DSA.java660
-rwxr-xr-xbase/util/src/netscape/security/provider/DSAKeyFactory.java232
-rw-r--r--base/util/src/netscape/security/provider/DSAKeyPairGenerator.java398
-rwxr-xr-xbase/util/src/netscape/security/provider/DSAParameterGenerator.java299
-rwxr-xr-xbase/util/src/netscape/security/provider/DSAParameters.java130
-rw-r--r--base/util/src/netscape/security/provider/DSAPrivateKey.java147
-rw-r--r--base/util/src/netscape/security/provider/DSAPublicKey.java133
-rw-r--r--base/util/src/netscape/security/provider/MD5.java378
-rw-r--r--base/util/src/netscape/security/provider/RSAPublicKey.java152
-rw-r--r--base/util/src/netscape/security/provider/SHA.java349
-rw-r--r--base/util/src/netscape/security/provider/Sun.java135
-rw-r--r--base/util/src/netscape/security/provider/X509CertificateFactory.java61
-rw-r--r--base/util/src/netscape/security/util/ASN1CharStrConvMap.java168
-rw-r--r--base/util/src/netscape/security/util/ASN1CharsetProvider.java30
-rw-r--r--base/util/src/netscape/security/util/BigInt.java210
-rw-r--r--base/util/src/netscape/security/util/BitArray.java257
-rw-r--r--base/util/src/netscape/security/util/ByteArrayLexOrder.java58
-rw-r--r--base/util/src/netscape/security/util/ByteArrayTagOrder.java44
-rw-r--r--base/util/src/netscape/security/util/CertPrettyPrint.java345
-rw-r--r--base/util/src/netscape/security/util/CrlPrettyPrint.java271
-rw-r--r--base/util/src/netscape/security/util/DerEncoder.java40
-rw-r--r--base/util/src/netscape/security/util/DerInputBuffer.java186
-rw-r--r--base/util/src/netscape/security/util/DerInputStream.java662
-rw-r--r--base/util/src/netscape/security/util/DerOutputStream.java729
-rw-r--r--base/util/src/netscape/security/util/DerValue.java715
-rw-r--r--base/util/src/netscape/security/util/ExtPrettyPrint.java1653
-rw-r--r--base/util/src/netscape/security/util/IA5Charset.java24
-rw-r--r--base/util/src/netscape/security/util/IA5CharsetDecoder.java62
-rw-r--r--base/util/src/netscape/security/util/IA5CharsetEncoder.java69
-rw-r--r--base/util/src/netscape/security/util/ObjectIdentifier.java426
-rw-r--r--base/util/src/netscape/security/util/PrettyPrintFormat.java160
-rw-r--r--base/util/src/netscape/security/util/PrettyPrintResources.java301
-rw-r--r--base/util/src/netscape/security/util/PrintableCharset.java46
-rw-r--r--base/util/src/netscape/security/util/PrintableCharsetDecoder.java69
-rw-r--r--base/util/src/netscape/security/util/PrintableCharsetEncoder.java71
-rw-r--r--base/util/src/netscape/security/util/PubKeyPrettyPrint.java121
-rw-r--r--base/util/src/netscape/security/util/UniversalCharset.java24
-rw-r--r--base/util/src/netscape/security/util/UniversalCharsetDecoder.java98
-rw-r--r--base/util/src/netscape/security/util/UniversalCharsetEncoder.java68
-rwxr-xr-xbase/util/src/netscape/security/x509/ACertAttrSet.java141
-rw-r--r--base/util/src/netscape/security/x509/AVA.java301
-rw-r--r--base/util/src/netscape/security/x509/AVAValueConverter.java86
-rw-r--r--base/util/src/netscape/security/x509/AlgIdDSA.java185
-rw-r--r--base/util/src/netscape/security/x509/AlgorithmId.java767
-rw-r--r--base/util/src/netscape/security/x509/Attribute.java325
-rw-r--r--base/util/src/netscape/security/x509/AuthorityKeyIdentifierExtension.java340
-rw-r--r--base/util/src/netscape/security/x509/BasicConstraintsExtension.java295
-rw-r--r--base/util/src/netscape/security/x509/CPSuri.java66
-rw-r--r--base/util/src/netscape/security/x509/CRLDistributionPoint.java467
-rw-r--r--base/util/src/netscape/security/x509/CRLDistributionPointsExtension.java391
-rwxr-xr-xbase/util/src/netscape/security/x509/CRLExtensions.java229
-rwxr-xr-xbase/util/src/netscape/security/x509/CRLNumberExtension.java226
-rw-r--r--base/util/src/netscape/security/x509/CRLReasonExtension.java234
-rw-r--r--base/util/src/netscape/security/x509/CertAndKeyGen.java290
-rwxr-xr-xbase/util/src/netscape/security/x509/CertAttrSet.java120
-rw-r--r--base/util/src/netscape/security/x509/CertException.java165
-rw-r--r--base/util/src/netscape/security/x509/CertParseError.java40
-rw-r--r--base/util/src/netscape/security/x509/CertificateAlgorithmId.java189
-rw-r--r--base/util/src/netscape/security/x509/CertificateChain.java137
-rw-r--r--base/util/src/netscape/security/x509/CertificateExtensions.java276
-rw-r--r--base/util/src/netscape/security/x509/CertificateIssuerExtension.java242
-rw-r--r--base/util/src/netscape/security/x509/CertificateIssuerName.java172
-rw-r--r--base/util/src/netscape/security/x509/CertificateIssuerUniqueIdentity.java185
-rw-r--r--base/util/src/netscape/security/x509/CertificatePoliciesExtension.java338
-rw-r--r--base/util/src/netscape/security/x509/CertificatePolicyId.java85
-rw-r--r--base/util/src/netscape/security/x509/CertificatePolicyInfo.java110
-rw-r--r--base/util/src/netscape/security/x509/CertificatePolicyMap.java100
-rw-r--r--base/util/src/netscape/security/x509/CertificatePolicySet.java86
-rw-r--r--base/util/src/netscape/security/x509/CertificateSerialNumber.java191
-rw-r--r--base/util/src/netscape/security/x509/CertificateSubjectName.java203
-rw-r--r--base/util/src/netscape/security/x509/CertificateSubjectUniqueIdentity.java185
-rw-r--r--base/util/src/netscape/security/x509/CertificateValidity.java306
-rw-r--r--base/util/src/netscape/security/x509/CertificateVersion.java247
-rw-r--r--base/util/src/netscape/security/x509/CertificateX509Key.java190
-rw-r--r--base/util/src/netscape/security/x509/DNSName.java82
-rwxr-xr-xbase/util/src/netscape/security/x509/DeltaCRLIndicatorExtension.java239
-rw-r--r--base/util/src/netscape/security/x509/DirStrConverter.java171
-rw-r--r--base/util/src/netscape/security/x509/DisplayText.java82
-rw-r--r--base/util/src/netscape/security/x509/EDIPartyName.java154
-rw-r--r--base/util/src/netscape/security/x509/Extension.java199
-rw-r--r--base/util/src/netscape/security/x509/Extensions.java226
-rw-r--r--base/util/src/netscape/security/x509/FreshestCRLExtension.java396
-rw-r--r--base/util/src/netscape/security/x509/GeneralName.java199
-rw-r--r--base/util/src/netscape/security/x509/GeneralNameInterface.java60
-rw-r--r--base/util/src/netscape/security/x509/GeneralNames.java150
-rw-r--r--base/util/src/netscape/security/x509/GeneralNamesException.java50
-rw-r--r--base/util/src/netscape/security/x509/GeneralSubtree.java159
-rw-r--r--base/util/src/netscape/security/x509/GeneralSubtrees.java106
-rw-r--r--base/util/src/netscape/security/x509/GenericValueConverter.java143
-rw-r--r--base/util/src/netscape/security/x509/HoldInstructionExtension.java354
-rw-r--r--base/util/src/netscape/security/x509/IA5StringConverter.java123
-rw-r--r--base/util/src/netscape/security/x509/IPAddressName.java277
-rw-r--r--base/util/src/netscape/security/x509/InvalidIPAddressException.java33
-rwxr-xr-xbase/util/src/netscape/security/x509/InvalidityDateExtension.java241
-rw-r--r--base/util/src/netscape/security/x509/IssuerAlternativeNameExtension.java240
-rw-r--r--base/util/src/netscape/security/x509/IssuingDistributionPoint.java315
-rw-r--r--base/util/src/netscape/security/x509/IssuingDistributionPointExtension.java416
-rw-r--r--base/util/src/netscape/security/x509/KeyIdentifier.java87
-rw-r--r--base/util/src/netscape/security/x509/KeyUsageExtension.java414
-rw-r--r--base/util/src/netscape/security/x509/LdapDNStrConverter.java144
-rw-r--r--base/util/src/netscape/security/x509/LdapV3DNStrConverter.java824
-rw-r--r--base/util/src/netscape/security/x509/NSCCommentExtension.java230
-rw-r--r--base/util/src/netscape/security/x509/NameConstraintsExtension.java315
-rw-r--r--base/util/src/netscape/security/x509/NoticeReference.java94
-rw-r--r--base/util/src/netscape/security/x509/OIDMap.java303
-rw-r--r--base/util/src/netscape/security/x509/OIDName.java90
-rw-r--r--base/util/src/netscape/security/x509/OtherName.java208
-rw-r--r--base/util/src/netscape/security/x509/PKIXExtensions.java185
-rw-r--r--base/util/src/netscape/security/x509/PolicyConstraint.java136
-rw-r--r--base/util/src/netscape/security/x509/PolicyConstraintsExtension.java306
-rw-r--r--base/util/src/netscape/security/x509/PolicyMappingsExtension.java258
-rw-r--r--base/util/src/netscape/security/x509/PolicyQualifierInfo.java118
-rw-r--r--base/util/src/netscape/security/x509/PolicyQualifiers.java107
-rw-r--r--base/util/src/netscape/security/x509/PrintableConverter.java114
-rw-r--r--base/util/src/netscape/security/x509/PrivateKeyUsageExtension.java339
-rw-r--r--base/util/src/netscape/security/x509/Qualifier.java63
-rw-r--r--base/util/src/netscape/security/x509/RDN.java303
-rw-r--r--base/util/src/netscape/security/x509/RFC1779StrConverter.java102
-rw-r--r--base/util/src/netscape/security/x509/RFC822Name.java85
-rwxr-xr-xbase/util/src/netscape/security/x509/ReasonFlags.java283
-rw-r--r--base/util/src/netscape/security/x509/RevocationReason.java119
-rwxr-xr-xbase/util/src/netscape/security/x509/RevokedCertImpl.java454
-rw-r--r--base/util/src/netscape/security/x509/RevokedCertificate.java95
-rw-r--r--base/util/src/netscape/security/x509/SerialNumber.java124
-rw-r--r--base/util/src/netscape/security/x509/SubjectAlternativeNameExtension.java242
-rw-r--r--base/util/src/netscape/security/x509/SubjectDirAttributesExtension.java286
-rw-r--r--base/util/src/netscape/security/x509/SubjectKeyIdentifierExtension.java222
-rw-r--r--base/util/src/netscape/security/x509/URIName.java85
-rw-r--r--base/util/src/netscape/security/x509/UniqueIdentity.java112
-rw-r--r--base/util/src/netscape/security/x509/UserNotice.java96
-rw-r--r--base/util/src/netscape/security/x509/X500Name.java699
-rw-r--r--base/util/src/netscape/security/x509/X500NameAttrMap.java376
-rw-r--r--base/util/src/netscape/security/x509/X500Signer.java116
-rw-r--r--base/util/src/netscape/security/x509/X509AttributeName.java64
-rwxr-xr-xbase/util/src/netscape/security/x509/X509CRLImpl.java1071
-rw-r--r--base/util/src/netscape/security/x509/X509Cert.java849
-rwxr-xr-xbase/util/src/netscape/security/x509/X509CertImpl.java1226
-rw-r--r--base/util/src/netscape/security/x509/X509CertInfo.java964
-rw-r--r--base/util/src/netscape/security/x509/X509ExtensionException.java54
-rw-r--r--base/util/src/netscape/security/x509/X509Key.java508
-rw-r--r--base/util/test/CMakeLists.txt60
-rw-r--r--base/util/test/com/netscape/security/extensions/GenericASN1ExtensionTest.java72
-rw-r--r--base/util/test/com/netscape/security/util/BMPStringTest.java274
-rw-r--r--base/util/test/com/netscape/security/util/IA5StringTest.java273
-rw-r--r--base/util/test/com/netscape/security/util/JSSUtil.java73
-rw-r--r--base/util/test/com/netscape/security/util/PrintableStringTest.java290
-rw-r--r--base/util/test/com/netscape/security/util/StringTestUtil.java79
-rw-r--r--base/util/test/com/netscape/security/util/TeletexStringTest.java273
-rw-r--r--base/util/test/com/netscape/security/util/UTF8StringTest.java262
-rw-r--r--base/util/test/com/netscape/security/util/UniversalStringTest.java262
-rw-r--r--base/util/test/com/netscape/security/x509/ConverterTestUtil.java22
-rw-r--r--base/util/test/com/netscape/security/x509/DirStrConverterTest.java122
-rw-r--r--base/util/test/com/netscape/security/x509/GenericValueConverterTest.java125
-rw-r--r--base/util/test/com/netscape/security/x509/IA5StringConverterTest.java93
-rw-r--r--base/util/test/com/netscape/security/x509/PrintableConverterTest.java103
2987 files changed, 688935 insertions, 0 deletions
diff --git a/base/CMakeLists.txt b/base/CMakeLists.txt
new file mode 100644
index 000000000..1c6e909ad
--- /dev/null
+++ b/base/CMakeLists.txt
@@ -0,0 +1,33 @@
+project(base)
+
+# The order is important!
+if (APPLICATION_FLAVOR_PKI_CORE)
+ add_subdirectory(test)
+ add_subdirectory(deploy)
+ add_subdirectory(setup)
+ add_subdirectory(symkey)
+ add_subdirectory(native-tools)
+ add_subdirectory(util)
+ add_subdirectory(java-tools)
+ add_subdirectory(common)
+ add_subdirectory(selinux)
+ add_subdirectory(ca)
+ add_subdirectory(kra)
+ add_subdirectory(ocsp)
+ add_subdirectory(tks)
+ add_subdirectory(silent)
+endif (APPLICATION_FLAVOR_PKI_CORE)
+if (APPLICATION_FLAVOR_PKI_RA)
+ add_subdirectory(ra)
+endif (APPLICATION_FLAVOR_PKI_RA)
+if (APPLICATION_FLAVOR_PKI_TPS)
+ add_subdirectory(tps)
+endif (APPLICATION_FLAVOR_PKI_TPS)
+if (APPLICATION_FLAVOR_PKI_CONSOLE)
+ add_subdirectory(test)
+ add_subdirectory(console)
+endif (APPLICATION_FLAVOR_PKI_CONSOLE)
+if (APPLICATION_FLAVOR_PKI_MIGRATE)
+ add_subdirectory(test)
+ add_subdirectory(migrate)
+endif (APPLICATION_FLAVOR_PKI_MIGRATE)
diff --git a/base/ca/CMakeLists.txt b/base/ca/CMakeLists.txt
new file mode 100644
index 000000000..153208c2d
--- /dev/null
+++ b/base/ca/CMakeLists.txt
@@ -0,0 +1,64 @@
+project(ca Java)
+
+add_subdirectory(src)
+add_subdirectory(setup)
+add_subdirectory(shared/conf)
+
+# install systemd scripts
+install(
+ FILES
+ shared/lib/systemd/system/pki-cad.target
+ shared/lib/systemd/system/pki-cad@.service
+ DESTINATION
+ ${SYSTEMD_LIB_INSTALL_DIR}
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+# install init script
+install(
+ FILES
+ shared/etc/init.d/pki-cad
+ DESTINATION
+ ${SYSCONF_INSTALL_DIR}/rc.d/init.d
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+)
+
+# install directories
+install(
+ DIRECTORY
+ shared/
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}
+ PATTERN
+ "CMakeLists.txt" EXCLUDE
+ PATTERN
+ "etc/*" EXCLUDE
+ PATTERN
+ "conf/CS.cfg.in" EXCLUDE
+ PATTERN
+ "lib/*" EXCLUDE
+)
+
+# install empty directories
+install(
+ DIRECTORY
+ DESTINATION
+ ${VAR_INSTALL_DIR}/lock/pki/ca
+)
+
+install(
+ DIRECTORY
+ DESTINATION
+ ${VAR_INSTALL_DIR}/run/pki/ca
+)
+
+install(
+ DIRECTORY
+ DESTINATION
+ ${SYSTEMD_ETC_INSTALL_DIR}/pki-cad.target.wants
+)
diff --git a/base/ca/LICENSE b/base/ca/LICENSE
new file mode 100644
index 000000000..e281f4362
--- /dev/null
+++ b/base/ca/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/base/ca/setup/CMakeLists.txt b/base/ca/setup/CMakeLists.txt
new file mode 100644
index 000000000..f5f069cdb
--- /dev/null
+++ b/base/ca/setup/CMakeLists.txt
@@ -0,0 +1,8 @@
+set(VERSION ${APPLICATION_VERSION})
+
+install(
+ FILES
+ registry_instance
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/setup
+)
diff --git a/base/ca/setup/registry_instance b/base/ca/setup/registry_instance
new file mode 100644
index 000000000..3210b9131
--- /dev/null
+++ b/base/ca/setup/registry_instance
@@ -0,0 +1,63 @@
+# Establish PKI Variable "Slot" Substitutions
+
+PKI_FLAVOR=[PKI_FLAVOR]
+export PKI_FLAVOR
+
+PKI_SUBSYSTEM_TYPE=[PKI_SUBSYSTEM_TYPE]
+export PKI_SUBSYSTEM_TYPE
+
+PKI_USER=[PKI_USER]
+export PKI_USER
+
+PKI_GROUP=[PKI_GROUP]
+export PKI_GROUP
+
+PKI_INSTANCE_ID=[PKI_INSTANCE_ID]
+export PKI_INSTANCE_ID
+
+PKI_INSTANCE_PATH=[PKI_INSTANCE_PATH]
+export PKI_INSTANCE_PATH
+
+PKI_INSTANCE_INITSCRIPT=[PKI_INSTANCE_INITSCRIPT]
+export PKI_INSTANCE_INITSCRIPT
+
+PKI_SERVER_XML_CONF=[PKI_SERVER_XML_CONF]
+export PKI_SERVER_XML_CONF
+
+# Use CATALINA_BASE
+
+CATALINA_BASE=$PKI_INSTANCE_PATH
+export CATALINA_BASE
+
+TOMCAT_PROG=$PKI_INSTANCE_ID
+export TOMCAT_PROG
+
+TOMCAT_USER=$PKI_USER
+export TOMCAT_USER
+
+TOMCAT_GROUP=$PKI_GROUP
+export TOMCAT_GROUP
+
+PKI_LOCKDIR="/var/lock/${PKI_FLAVOR}/${PKI_SUBSYSTEM_TYPE}"
+export PKI_LOCKDIR
+
+PKI_LOCKFILE="${PKI_LOCKDIR}/${PKI_INSTANCE_ID}"
+export PKI_LOCKFILE
+
+PKI_PIDDIR="/var/run/${PKI_FLAVOR}/${PKI_SUBSYSTEM_TYPE}"
+export PKI_PIDDIR
+
+PKI_PIDFILE="${PKI_PIDDIR}/${PKI_INSTANCE_ID}.pid"
+export PKI_PIDFILE
+
+TOMCAT_LOCKFILE=/var/lock/subsys/${PKI_INSTANCE_ID}
+export TOMCAT_LOCKFILE
+
+TOMCAT_PIDFILE=[TOMCAT_PIDFILE]
+export TOMCAT_PIDFILE
+
+pki_instance_configuration_file=${PKI_INSTANCE_PATH}/conf/CS.cfg
+export pki_instance_configuration_file
+
+RESTART_SERVER=${PKI_INSTANCE_PATH}/conf/restart_server_after_configuration
+export RESTART_SERVER
diff --git a/base/ca/shared/conf/CMakeLists.txt b/base/ca/shared/conf/CMakeLists.txt
new file mode 100644
index 000000000..e3cef5915
--- /dev/null
+++ b/base/ca/shared/conf/CMakeLists.txt
@@ -0,0 +1,12 @@
+set(VERSION ${APPLICATION_VERSION})
+set(MAJOR_VERSION ${APPLICATION_VERSION_MAJOR})
+set(MINOR_VERSION ${APPLICATION_VERSION_MINOR})
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CS.cfg.in ${CMAKE_CURRENT_BINARY_DIR}/CS.cfg @ONLY)
+
+install(
+ FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/CS.cfg
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/conf
+)
diff --git a/base/ca/shared/conf/CS.cfg.in b/base/ca/shared/conf/CS.cfg.in
new file mode 100644
index 000000000..980ed5854
--- /dev/null
+++ b/base/ca/shared/conf/CS.cfg.in
@@ -0,0 +1,1108 @@
+_000=##
+_001=## Certificate Authority (CA) Configuration File
+_002=##
+pkicreate.pki_instance_root=[PKI_INSTANCE_ROOT]
+pkicreate.pki_instance_name=[PKI_INSTANCE_ID]
+pkicreate.subsystem_type=[PKI_SUBSYSTEM_TYPE]
+pkicreate.agent_secure_port=[PKI_AGENT_SECURE_PORT]
+pkicreate.ee_secure_port=[PKI_EE_SECURE_PORT]
+pkicreate.ee_secure_client_auth_port=[PKI_EE_SECURE_CLIENT_AUTH_PORT]
+pkicreate.admin_secure_port=[PKI_ADMIN_SECURE_PORT]
+pkicreate.secure_port=[PKI_SECURE_PORT]
+pkicreate.unsecure_port=[PKI_UNSECURE_PORT]
+pkicreate.tomcat_server_port=[TOMCAT_SERVER_PORT]
+pkicreate.user=[PKI_USER]
+pkicreate.arg11.group=[PKI_GROUP]
+pkicreate.systemd.servicename=[PKI_SYSTEMD_SERVICENAME]
+pkiremove.cert.subsystem.nickname=subsystemCert cert-[PKI_INSTANCE_ID]
+installDate=[INSTALL_TIME]
+preop.wizard.name=CA Setup Wizard
+preop.product.name=CS
+preop.product.version=@VERSION@
+preop.system.name=CA
+preop.system.fullname=Certificate Authority
+proxy.securePort=[PKI_PROXY_SECURE_PORT]
+proxy.unsecurePort=[PKI_PROXY_UNSECURE_PORT]
+cs.state._000=##
+cs.state._001=## cs.state=0 (pre-operational)
+cs.state._002=## cs.state=1 (running)
+cs.state._003=##
+cs.state=0
+cs.type=CA
+authType=pwd
+admin.interface.uri=ca/admin/console/config/wizard
+ee.interface.uri=ca/ee/ca
+agent.interface.uri=ca/agent/ca
+preop.securitydomain.admin_url=https://[PKI_MACHINE_NAME]:9445
+securitydomain.flushinterval=86400000
+securitydomain.source=ldap
+securitydomain.checkinterval=300000
+instanceRoot=[PKI_INSTANCE_PATH]
+machineName=[PKI_MACHINE_NAME]
+instanceId=[PKI_INSTANCE_ID]
+pidDir=[PKI_PIDDIR]
+service.machineName=[PKI_MACHINE_NAME]
+service.instanceDir=[PKI_INSTANCE_ROOT]
+service.securePort=[PKI_AGENT_SECURE_PORT]
+service.non_clientauth_securePort=[PKI_EE_SECURE_PORT]
+service.clientauth_securePort=[PKI_EE_SECURE_CLIENT_AUTH_PORT]
+service.unsecurePort=[PKI_UNSECURE_PORT]
+service.instanceID=[PKI_INSTANCE_ID]
+preop.admin.name=Certificate System Administrator
+preop.admin.group=Certificate Manager Agents
+preop.admincert.profile=caAdminCert
+preop.pin=[PKI_RANDOM_NUMBER]
+ca.cert.list=signing,ocsp_signing,sslserver,subsystem,audit_signing
+ca.cert.signing.certusage=SSLCA
+ca.cert.ocsp_signing.certusage=StatusResponder
+ca.cert.sslserver.certusage=SSLServer
+ca.cert.subsystem.certusage=SSLClient
+ca.cert.audit_signing.certusage=ObjectSigner
+preop.cert.list=signing,ocsp_signing,sslserver,subsystem,audit_signing
+preop.cert.rsalist=audit_signing
+preop.cert.signing.enable=true
+preop.cert.ocsp_signing.enable=true
+preop.cert.sslserver.enable=true
+preop.cert.subsystem.enable=true
+preop.cert.audit_signing.enable=true
+preop.cert.signing.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.signing.dn=CN=Certificate Authority
+preop.cert.signing.cncomponent.override=true
+preop.cert.signing.keysize.size=2048
+preop.cert.signing.keysize.custom_size=2048
+preop.cert.signing.nickname=caSigningCert cert-[PKI_INSTANCE_ID]
+preop.cert.signing.profile=caCert.profile
+preop.cert.signing.signing.required=true
+preop.cert.signing.subsystem=ca
+preop.cert.signing.type=selfsign
+preop.cert.signing.userfriendlyname=CA Signing Certificate
+preop.cert.audit_signing.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.audit_signing.dn=CN=CA Audit Signing Certificate
+preop.cert.audit_signing.keysize.custom_size=2048
+preop.cert.audit_signing.keysize.size=2048
+preop.cert.audit_signing.nickname=auditSigningCert cert-[PKI_INSTANCE_ID]
+preop.cert.audit_signing.profile=caAuditSigningCert.profile
+preop.cert.audit_signing.signing.required=false
+preop.cert.audit_signing.subsystem=ca
+preop.cert.audit_signing.type=local
+preop.cert.audit_signing.userfriendlyname=CA Audit Signing Certificate
+preop.cert.audit_signing.cncomponent.override=true
+preop.cert.ocsp_signing.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.ocsp_signing.dn=CN=OCSP Signing Certificate
+preop.cert.ocsp_signing.keysize.custom_size=2048
+preop.cert.ocsp_signing.keysize.size=2048
+preop.cert.ocsp_signing.nickname=ocspSigningCert cert-[PKI_INSTANCE_ID]
+preop.cert.ocsp_signing.profile=caOCSPCert.profile
+preop.cert.ocsp_signing.signing.required=true
+preop.cert.ocsp_signing.subsystem=ca
+preop.cert.ocsp_signing.type=local
+preop.cert.ocsp_signing.userfriendlyname=OCSP Signing Certificate
+preop.cert.ocsp_signing.cncomponent.override=true
+preop.cert.sslserver.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.sslserver.dn=CN=[PKI_MACHINE_NAME]
+preop.cert.sslserver.keysize.custom_size=2048
+preop.cert.sslserver.keysize.size=2048
+preop.cert.sslserver.nickname=Server-Cert cert-[PKI_INSTANCE_ID]
+preop.cert.sslserver.profile=serverCert.profile
+preop.cert.sslserver.signing.required=false
+preop.cert.sslserver.subsystem=ca
+preop.cert.sslserver.type=local
+preop.cert.sslserver.userfriendlyname=SSL Server Certificate
+preop.cert.sslserver.cncomponent.override=false
+preop.cert.subsystem.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.subsystem.dn=CN=CA Subsystem Certificate
+preop.cert.subsystem.keysize.custom_size=2048
+preop.cert.subsystem.keysize.size=2048
+preop.cert.subsystem.nickname=subsystemCert cert-[PKI_INSTANCE_ID]
+preop.cert.subsystem.profile=subsystemCert.profile
+preop.cert.subsystem.signing.required=false
+preop.cert.subsystem.subsystem=ca
+preop.cert.subsystem.type=local
+preop.cert.subsystem.userfriendlyname=Subsystem Certificate
+preop.cert.subsystem.cncomponent.override=true
+preop.cert.admin.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.admin.dn=uid=admin,cn=admin
+preop.cert.admin.keysize.custom_size=2048
+preop.cert.admin.keysize.size=2048
+preop.cert.admin.profile=adminCert.profile
+preop.hierarchy.profile=caCert.profile
+preop.configModules.module0.userFriendlyName=NSS Internal PKCS #11 Module
+preop.configModules.module0.commonName=NSS Internal PKCS #11 Module
+preop.configModules.module0.imagePath=../img/clearpixel.gif
+preop.configModules.module1.userFriendlyName=nCipher's nFast Token Hardware Module
+preop.configModules.module1.commonName=nfast
+preop.configModules.module1.imagePath=../img/clearpixel.gif
+preop.configModules.module2.userFriendlyName=SafeNet's LunaSA Token Hardware Module
+preop.configModules.module2.commonName=lunasa
+preop.configModules.module2.imagePath=../img/clearpixel.gif
+preop.configModules.count=3
+preop.module.token=Internal Key Storage Token
+preop.name.caDN=CN=Certificate Authority
+preop.name.sslDN=CN=[PKI_MACHINE_NAME]
+preop.name.ocspDN=CN=OCSP Signing Certificate
+preop.name.subsystemDN=CN=CA Subsystem Certificate
+preop.name.canickname=caSigningCert cert-[PKI_INSTANCE_ID]
+preop.name.ocspnickname=ocspSigningCert cert-[PKI_INSTANCE_ID]
+preop.name.subsystemnickname=subsystemCert cert-[PKI_INSTANCE_ID]
+preop.name.sslnickname=Server-Cert cert-[PKI_INSTANCE_ID]
+preop.subsystem.count=0
+subsystem.count=0
+passwordFile=[PKI_INSTANCE_PATH]/conf/password.conf
+passwordClass=com.netscape.cmsutil.password.PlainPasswordFile
+CrossCertPair._000=##
+CrossCertPair._001=## CrossCertPair Import
+CrossCertPair._002=##
+CrossCertPair.ldap=internaldb
+accessEvaluator.impl.group.class=com.netscape.cms.evaluators.GroupAccessEvaluator
+accessEvaluator.impl.ipaddress.class=com.netscape.cms.evaluators.IPAddressAccessEvaluator
+accessEvaluator.impl.user.class=com.netscape.cms.evaluators.UserAccessEvaluator
+accessEvaluator.impl.user_origreq.class=com.netscape.cms.evaluators.UserOrigReqAccessEvaluator
+auths._000=##
+auths._001=## new authentication
+auths._002=##
+auths.impl._000=##
+auths.impl._001=## authentication manager implementations
+auths.impl._002=##
+auths.impl.AgentCertAuth.class=com.netscape.cms.authentication.AgentCertAuthentication
+auths.impl.CMCAuth.class=com.netscape.cms.authentication.CMCAuth
+auths.impl.NISAuth.class=com.netscape.cms.authentication.NISAuth
+auths.impl.PortalEnroll.class=com.netscape.cms.authentication.PortalEnroll
+auths.impl.SSLclientCertAuth.class=com.netscape.cms.authentication.SSLclientCertAuthentication
+auths.impl.UdnPwdDirAuth.class=com.netscape.cms.authentication.UdnPwdDirAuthentication
+auths.impl.UidPwdDirAuth.class=com.netscape.cms.authentication.UidPwdDirAuthentication
+auths.impl.UidPwdPinDirAuth.class=com.netscape.cms.authentication.UidPwdPinDirAuthentication
+auths.impl.UidPwdGroupDirAuth.class=com.netscape.cms.authentication.UidPwdGroupDirAuthentication
+auths.impl.TokenAuth.class=com.netscape.cms.authentication.TokenAuthentication
+auths.impl.FlatFileAuth.class=com.netscape.cms.authentication.FlatFileAuth
+auths.instance.TokenAuth.pluginName=TokenAuth
+auths.instance.AgentCertAuth.agentGroup=Certificate Manager Agents
+auths.instance.AgentCertAuth.pluginName=AgentCertAuth
+auths.instance.raCertAuth.agentGroup=Registration Manager Agents
+auths.instance.raCertAuth.pluginName=AgentCertAuth
+auths.instance.flatFileAuth.pluginName=FlatFileAuth
+auths.instance.flatFileAuth.fileName=[PKI_INSTANCE_PATH]/conf/flatfile.txt
+auths.instance.SSLclientCertAuth.pluginName=SSLclientCertAuth
+auths.revocationChecking.bufferSize=50
+auths.revocationChecking.ca=ca
+auths.revocationChecking.enabled=true
+auths.revocationChecking.unknownStateInterval=0
+auths.revocationChecking.validityInterval=120
+authz._000=##
+authz._001=## new authorizatioin
+authz._002=##
+authz.evaluateOrder=deny,allow
+authz.sourceType=ldap
+authz.impl._000=##
+authz.impl._001=## authorization manager implementations
+authz.impl._002=##
+authz.impl.BasicAclAuthz.class=com.netscape.cms.authorization.BasicAclAuthz
+authz.impl.DirAclAuthz.class=com.netscape.cms.authorization.DirAclAuthz
+authz.instance.BasicAclAuthz.pluginName=BasicAclAuthz
+authz.instance.DirAclAuthz.ldap=internaldb
+authz.instance.DirAclAuthz.pluginName=DirAclAuthz
+authz.instance.DirAclAuthz.ldap._000=##
+authz.instance.DirAclAuthz.ldap._001=## Internal Database
+authz.instance.DirAclAuthz.ldap._002=##
+ca.ocsp=true
+ca.certdbInc=20
+ca.crldbInc=20
+ca.id=ca
+ca.local=true
+ca.ocspUseCache=false
+ca.enableNonces=true
+ca.maxNumberOfNonces=100
+ca.reqdbInc=20
+ca.transitMaxRecords=1000000
+ca.transitRecordPageSize=200
+ca.maxSearchReturns._000=##
+ca.maxSearchReturns._001=## limits number of search results
+ca.maxSearchReturns._002=## returned by SearchReqs and SrchCerts
+ca.maxSearchReturns._003=##
+ca.maxSearchReturns=1000
+ca.scep._000=##
+ca.scep._001=## Enable the following parameters to enable SCEP requests
+ca.scep._002=## to be signed by a separate key pair:
+ca.scep._003=##
+ca.scep._004=## ca.scep.nickname=
+ca.scep._005=## ca.scep.tokenname=
+ca.scep._006=##
+ca.scep.enable=false
+ca.scep.hashAlgorithm=SHA1
+ca.scep.allowedHashAlgorithms=SHA1,SHA256,SHA512
+ca.scep.encryptionAlgorithm=DES3
+ca.scep.allowedEncryptionAlgorithms=DES3
+ca.scep.nonceSizeLimit=16
+ca.Policy._000=##
+ca.Policy._001=## Certificate Policy Framework (deprecated)
+ca.Policy._002=##
+ca.Policy._003=## Set 'ca.Policy.enable=true' to allow the following:
+ca.Policy._004=##
+ca.Policy._005=## SERVLET-NAME URL-PATTERN
+ca.Policy._006=## ====================================================
+ca.Policy._007=## caadminEnroll ca/admin/ca/adminEnroll.html
+ca.Policy._008=## cabulkissuance ca/agent/ca/bulkissuance.html
+ca.Policy._009=## cacertbasedenrollment ca/certbasedenrollment.html
+ca.Policy._010=## caenrollment ca/enrollment.html
+ca.Policy._011=## capolicy ca/capolicy
+ca.Policy._012=##
+ca.Policy.enable=false
+ca.Policy.order=KeyAlgRule, RSAKeyRule, DefaultValidityRule, RenewalConstraintsRule, DefaultRenewalValidityRule, RevocationConstraintsRule, NSCertTypeExt, CMCertKeyUsageExt, RMCertKeyUsageExt, ClientCertKeyUsageExt, ServerCertKeyUsageExt, ObjSignCertKeyUsageExt, CRLSignCertKeyUsageExt, SubjectKeyIdentifierExt, CertificatePoliciesExt, NSCCommentExt, OCSPNoCheckExt, OCSPSigningExt, CODESigningExt, GenericASN1Ext, CRLDistributionPointsExt, SubjectAltNameExt, SigningAlgRule, AuthorityKeyIdentifierExt, AuthInfoAccessExt, BasicConstraintsExt, UniqueSubjectNameConstraints, NameConstraintsExt, PolicyConstraintsExt, SubCANameConstraints, PolicyMappingsExt, IssuerRule
+ca.Policy.processor=classic
+ca.Policy.impl._000=##
+ca.Policy.impl._001=## Policy Implementations
+ca.Policy.impl._002=##
+ca.Policy.impl.AttributePresentConstraints.class=com.netscape.cms.policy.constraints.AttributePresentConstraints
+ca.Policy.impl.AuthInfoAccessExt.class=com.netscape.cms.policy.extensions.AuthInfoAccessExt
+ca.Policy.impl.AuthorityKeyIdentifierExt.class=com.netscape.cms.policy.extensions.AuthorityKeyIdentifierExt
+ca.Policy.impl.BasicConstraintsExt.class=com.netscape.cms.policy.extensions.BasicConstraintsExt
+ca.Policy.impl.CRLDistributionPointsExt.class=com.netscape.cms.policy.extensions.CRLDistributionPointsExt
+ca.Policy.impl.CertificatePoliciesExt.class=com.netscape.cms.policy.extensions.CertificatePoliciesExt
+ca.Policy.impl.CertificateRenewalWindowExt.class=com.netscape.cms.policy.extensions.CertificateRenewalWindowExt
+ca.Policy.impl.CertificateScopeOfUseExt.class=com.netscape.cms.policy.extensions.CertificateScopeOfUseExt
+ca.Policy.impl.DSAKeyConstraints.class=com.netscape.cms.policy.constraints.DSAKeyConstraints
+ca.Policy.impl.ExtendedKeyUsageExt.class=com.netscape.cms.policy.extensions.ExtendedKeyUsageExt
+ca.Policy.impl.GenericASN1Ext.class=com.netscape.cms.policy.extensions.GenericASN1Ext
+ca.Policy.impl.IssuerAltNameExt.class=com.netscape.cms.policy.extensions.IssuerAltNameExt
+ca.Policy.impl.IssuerConstraints.class=com.netscape.cms.policy.constraints.IssuerConstraints
+ca.Policy.impl.KeyAlgorithmConstraints.class=com.netscape.cms.policy.constraints.KeyAlgorithmConstraints
+ca.Policy.impl.KeyUsageExt.class=com.netscape.cms.policy.extensions.KeyUsageExt
+ca.Policy.impl.NSCCommentExt.class=com.netscape.cms.policy.extensions.NSCCommentExt
+ca.Policy.impl.NSCertTypeExt.class=com.netscape.cms.policy.extensions.NSCertTypeExt
+ca.Policy.impl.NameConstraintsExt.class=com.netscape.cms.policy.extensions.NameConstraintsExt
+ca.Policy.impl.OCSPNoCheckExt.class=com.netscape.cms.policy.extensions.OCSPNoCheckExt
+ca.Policy.impl.PolicyConstraintsExt.class=com.netscape.cms.policy.extensions.PolicyConstraintsExt
+ca.Policy.impl.PolicyMappingsExt.class=com.netscape.cms.policy.extensions.PolicyMappingsExt
+ca.Policy.impl.PrivateKeyUsagePeriodExt.class=com.netscape.cms.policy.extensions.PrivateKeyUsagePeriodExt
+ca.Policy.impl.RSAKeyConstraints.class=com.netscape.cms.policy.constraints.RSAKeyConstraints
+ca.Policy.impl.RemoveBasicConstraintsExt.class=com.netscape.cms.policy.extensions.RemoveBasicConstraintsExt
+ca.Policy.impl.RenewalConstraints.class=com.netscape.cms.policy.constraints.RenewalConstraints
+ca.Policy.impl.RenewalValidityConstraints.class=com.netscape.cms.policy.constraints.RenewalValidityConstraints
+ca.Policy.impl.RevocationConstraints.class=com.netscape.cms.policy.constraints.RevocationConstraints
+ca.Policy.impl.SigningAlgorithmConstraints.class=com.netscape.cms.policy.constraints.SigningAlgorithmConstraints
+ca.Policy.impl.SubCANameConstraints.class=com.netscape.cms.policy.constraints.SubCANameConstraints
+ca.Policy.impl.SubjectAltNameExt.class=com.netscape.cms.policy.extensions.SubjectAltNameExt
+ca.Policy.impl.SubjectDirectoryAttributesExt.class=com.netscape.cms.policy.extensions.SubjectDirectoryAttributesExt
+ca.Policy.impl.SubjectKeyIdentifierExt.class=com.netscape.cms.policy.extensions.SubjectKeyIdentifierExt
+ca.Policy.impl.UniqueSubjectNameConstraints.class=com.netscape.cms.policy.constraints.UniqueSubjectNameConstraints
+ca.Policy.impl.ValidityConstraints.class=com.netscape.cms.policy.constraints.ValidityConstraints
+ca.Policy.rule.AuthInfoAccessExt.ad0_location=http://[PKI_MACHINE_NAME]:8080/ocsp
+ca.Policy.rule.AuthInfoAccessExt.ad0_location_type=URL
+ca.Policy.rule.AuthInfoAccessExt.ad0_method=ocsp
+ca.Policy.rule.AuthInfoAccessExt.enable=false
+ca.Policy.rule.AuthInfoAccessExt.implName=AuthInfoAccessExt
+ca.Policy.rule.AuthInfoAccessExt.numADs=1
+ca.Policy.rule.AuthInfoAccessExt.predicate=HTTP_PARAMS.certType==client
+ca.Policy.rule.AuthorityKeyIdentifierExt.enable=true
+ca.Policy.rule.AuthorityKeyIdentifierExt.implName=AuthorityKeyIdentifierExt
+ca.Policy.rule.AuthorityKeyIdentifierExt.predicate=
+ca.Policy.rule.BasicConstraintsExt.critical=true
+ca.Policy.rule.BasicConstraintsExt.enable=true
+ca.Policy.rule.BasicConstraintsExt.implName=BasicConstraintsExt
+ca.Policy.rule.BasicConstraintsExt.maxPathLen=
+ca.Policy.rule.BasicConstraintsExt.predicate=HTTP_PARAMS.certType == ca
+ca.Policy.rule.BasicConstraintsExt.removeBasicExt=true
+ca.Policy.rule.CMCertKeyUsageExt.crlSign=true
+ca.Policy.rule.CMCertKeyUsageExt.dataEncipherment=false
+ca.Policy.rule.CMCertKeyUsageExt.decipherOnly=false
+ca.Policy.rule.CMCertKeyUsageExt.digitalSignature=true
+ca.Policy.rule.CMCertKeyUsageExt.enable=true
+ca.Policy.rule.CMCertKeyUsageExt.encipherOnly=false
+ca.Policy.rule.CMCertKeyUsageExt.implName=KeyUsageExt
+ca.Policy.rule.CMCertKeyUsageExt.keyAgreement=false
+ca.Policy.rule.CMCertKeyUsageExt.keyCertsign=true
+ca.Policy.rule.CMCertKeyUsageExt.keyEncipherment=false
+ca.Policy.rule.CMCertKeyUsageExt.nonRepudiation=true
+ca.Policy.rule.CMCertKeyUsageExt.predicate=HTTP_PARAMS.certType==ca
+ca.Policy.rule.CODESigningExt.critical=false
+ca.Policy.rule.CODESigningExt.enable=true
+ca.Policy.rule.CODESigningExt.id0=1.3.6.1.5.5.7.3.3
+ca.Policy.rule.CODESigningExt.implName=ExtendedKeyUsageExt
+ca.Policy.rule.CODESigningExt.predicate=HTTP_PARAMS.certType==codeSignClient
+ca.Policy.rule.CRLDistributionPointsExt.enable=false
+ca.Policy.rule.CRLDistributionPointsExt.implName=CRLDistributionPointsExt
+ca.Policy.rule.CRLDistributionPointsExt.issuerName0=
+ca.Policy.rule.CRLDistributionPointsExt.issuerName1=
+ca.Policy.rule.CRLDistributionPointsExt.issuerName2=
+ca.Policy.rule.CRLDistributionPointsExt.issuerType0=
+ca.Policy.rule.CRLDistributionPointsExt.issuerType1=
+ca.Policy.rule.CRLDistributionPointsExt.issuerType2=
+ca.Policy.rule.CRLDistributionPointsExt.numPoints=0
+ca.Policy.rule.CRLDistributionPointsExt.pointName0=
+ca.Policy.rule.CRLDistributionPointsExt.pointName1=
+ca.Policy.rule.CRLDistributionPointsExt.pointName2=
+ca.Policy.rule.CRLDistributionPointsExt.pointType0=
+ca.Policy.rule.CRLDistributionPointsExt.pointType1=
+ca.Policy.rule.CRLDistributionPointsExt.pointType2=
+ca.Policy.rule.CRLDistributionPointsExt.predicate=
+ca.Policy.rule.CRLDistributionPointsExt.reasons0=
+ca.Policy.rule.CRLDistributionPointsExt.reasons1=
+ca.Policy.rule.CRLDistributionPointsExt.reasons2=
+ca.Policy.rule.CRLSignCertKeyUsageExt.crlSign=true
+ca.Policy.rule.CRLSignCertKeyUsageExt.dataEncipherment=false
+ca.Policy.rule.CRLSignCertKeyUsageExt.decipherOnly=false
+ca.Policy.rule.CRLSignCertKeyUsageExt.digitalSignature=false
+ca.Policy.rule.CRLSignCertKeyUsageExt.enable=true
+ca.Policy.rule.CRLSignCertKeyUsageExt.encipherOnly=false
+ca.Policy.rule.CRLSignCertKeyUsageExt.implName=KeyUsageExt
+ca.Policy.rule.CRLSignCertKeyUsageExt.keyAgreement=false
+ca.Policy.rule.CRLSignCertKeyUsageExt.keyCertsign=false
+ca.Policy.rule.CRLSignCertKeyUsageExt.keyEncipherment=false
+ca.Policy.rule.CRLSignCertKeyUsageExt.nonRepudiation=false
+ca.Policy.rule.CRLSignCertKeyUsageExt.predicate=HTTP_PARAMS.certType==caCrlSigning
+ca.Policy.rule.CertificatePoliciesExt.critical=false
+ca.Policy.rule.CertificatePoliciesExt.enable=false
+ca.Policy.rule.CertificatePoliciesExt.implName=CertificatePoliciesExt
+ca.Policy.rule.CertificatePoliciesExt.numCertPolicies=1
+ca.Policy.rule.CertificatePoliciesExt.predicate=
+ca.Policy.rule.CertificatePoliciesExt.certPolicy0.cpsURI=
+ca.Policy.rule.CertificatePoliciesExt.certPolicy0.noticeRefNumbers=
+ca.Policy.rule.CertificatePoliciesExt.certPolicy0.noticeRefOrganization=
+ca.Policy.rule.CertificatePoliciesExt.certPolicy0.policyId=
+ca.Policy.rule.CertificatePoliciesExt.certPolicy0.userNoticeExplicitText=
+ca.Policy.rule.ClientCertKeyUsageExt.crlSign=false
+ca.Policy.rule.ClientCertKeyUsageExt.dataEncipherment=false
+ca.Policy.rule.ClientCertKeyUsageExt.decipherOnly=false
+ca.Policy.rule.ClientCertKeyUsageExt.digitalSignature=true
+ca.Policy.rule.ClientCertKeyUsageExt.enable=true
+ca.Policy.rule.ClientCertKeyUsageExt.encipherOnly=false
+ca.Policy.rule.ClientCertKeyUsageExt.implName=KeyUsageExt
+ca.Policy.rule.ClientCertKeyUsageExt.keyAgreement=false
+ca.Policy.rule.ClientCertKeyUsageExt.keyCertsign=false
+ca.Policy.rule.ClientCertKeyUsageExt.keyEncipherment=true
+ca.Policy.rule.ClientCertKeyUsageExt.nonRepudiation=true
+ca.Policy.rule.ClientCertKeyUsageExt.predicate=HTTP_PARAMS.certType==client
+ca.Policy.rule.DSAKeyRule.enable=true
+ca.Policy.rule.DSAKeyRule.implName=DSAKeyConstraints
+ca.Policy.rule.DSAKeyRule.maxSize=1024
+ca.Policy.rule.DSAKeyRule.minSize=512
+ca.Policy.rule.DSAKeyRule.predicate=
+ca.Policy.rule.DefaultRenewalValidityRule.enable=true
+ca.Policy.rule.DefaultRenewalValidityRule.implName=RenewalValidityConstraints
+ca.Policy.rule.DefaultRenewalValidityRule.maxValidity=365
+ca.Policy.rule.DefaultRenewalValidityRule.minValidity=30
+ca.Policy.rule.DefaultRenewalValidityRule.predicate=
+ca.Policy.rule.DefaultRenewalValidityRule.renewalInterval=15
+ca.Policy.rule.DefaultValidityRule.enable=true
+ca.Policy.rule.DefaultValidityRule.implName=ValidityConstraints
+ca.Policy.rule.DefaultValidityRule.maxValidity=365
+ca.Policy.rule.DefaultValidityRule.minValidity=1
+ca.Policy.rule.DefaultValidityRule.predicate=
+ca.Policy.rule.GenericASN1Ext.critical=false
+ca.Policy.rule.GenericASN1Ext.enable=false
+ca.Policy.rule.GenericASN1Ext.implName=GenericASN1Ext
+ca.Policy.rule.GenericASN1Ext.name=
+ca.Policy.rule.GenericASN1Ext.oid=
+ca.Policy.rule.GenericASN1Ext.pattern=
+ca.Policy.rule.GenericASN1Ext.predicate=
+ca.Policy.rule.GenericASN1Ext.attribute.0.source=
+ca.Policy.rule.GenericASN1Ext.attribute.0.type=
+ca.Policy.rule.GenericASN1Ext.attribute.0.value=
+ca.Policy.rule.GenericASN1Ext.attribute.1.source=
+ca.Policy.rule.GenericASN1Ext.attribute.1.type=
+ca.Policy.rule.GenericASN1Ext.attribute.1.value=
+ca.Policy.rule.GenericASN1Ext.attribute.2.source=
+ca.Policy.rule.GenericASN1Ext.attribute.2.type=
+ca.Policy.rule.GenericASN1Ext.attribute.2.value=
+ca.Policy.rule.GenericASN1Ext.attribute.3.source=
+ca.Policy.rule.GenericASN1Ext.attribute.3.type=
+ca.Policy.rule.GenericASN1Ext.attribute.3.value=
+ca.Policy.rule.GenericASN1Ext.attribute.4.source=
+ca.Policy.rule.GenericASN1Ext.attribute.4.type=
+ca.Policy.rule.GenericASN1Ext.attribute.4.value=
+ca.Policy.rule.GenericASN1Ext.attribute.5.source=
+ca.Policy.rule.GenericASN1Ext.attribute.5.type=
+ca.Policy.rule.GenericASN1Ext.attribute.5.value=
+ca.Policy.rule.GenericASN1Ext.attribute.6.source=
+ca.Policy.rule.GenericASN1Ext.attribute.6.type=
+ca.Policy.rule.GenericASN1Ext.attribute.6.value=
+ca.Policy.rule.GenericASN1Ext.attribute.7.source=
+ca.Policy.rule.GenericASN1Ext.attribute.7.type=
+ca.Policy.rule.GenericASN1Ext.attribute.7.value=
+ca.Policy.rule.GenericASN1Ext.attribute.8.source=
+ca.Policy.rule.GenericASN1Ext.attribute.8.type=
+ca.Policy.rule.GenericASN1Ext.attribute.8.value=
+ca.Policy.rule.GenericASN1Ext.attribute.9.source=
+ca.Policy.rule.GenericASN1Ext.attribute.9.type=
+ca.Policy.rule.GenericASN1Ext.attribute.9.value=
+ca.Policy.rule.IssuerRule.enable=false
+ca.Policy.rule.IssuerRule.implName=IssuerConstraints
+ca.Policy.rule.IssuerRule.issuerDN=
+ca.Policy.rule.IssuerRule.predicate=HTTP_PARAMS.certType==client AND certauthEnroll==on
+ca.Policy.rule.KeyAlgRule.algorithms=RSA,DSA
+ca.Policy.rule.KeyAlgRule.enable=true
+ca.Policy.rule.KeyAlgRule.implName=KeyAlgorithmConstraints
+ca.Policy.rule.KeyAlgRule.predicate=
+ca.Policy.rule.NSCCommentExt.commentFile=
+ca.Policy.rule.NSCCommentExt.enable=false
+ca.Policy.rule.NSCCommentExt.implName=NSCCommentExt
+ca.Policy.rule.NSCCommentExt.inputType=Text
+ca.Policy.rule.NSCCommentExt.predicate=
+ca.Policy.rule.NSCertTypeExt.enable=true
+ca.Policy.rule.NSCertTypeExt.implName=NSCertTypeExt
+ca.Policy.rule.NSCertTypeExt.predicate=HTTP_PARAMS.certType!=CEP-Request
+ca.Policy.rule.NameConstraintsExt.critical=true
+ca.Policy.rule.NameConstraintsExt.enable=false
+ca.Policy.rule.NameConstraintsExt.implName=NameConstraintsExt
+ca.Policy.rule.NameConstraintsExt.numExcludedSubtrees=3
+ca.Policy.rule.NameConstraintsExt.numPermittedSubtrees=3
+ca.Policy.rule.NameConstraintsExt.predicate=HTTP_PARAMS.certType == ca
+ca.Policy.rule.NameConstraintsExt.excludedSubtrees0.max=-1
+ca.Policy.rule.NameConstraintsExt.excludedSubtrees0.min=0
+ca.Policy.rule.NameConstraintsExt.excludedSubtrees0.base.generalNameChoice=
+ca.Policy.rule.NameConstraintsExt.excludedSubtrees0.base.generalNameValue=
+ca.Policy.rule.NameConstraintsExt.excludedSubtrees1.max=-1
+ca.Policy.rule.NameConstraintsExt.excludedSubtrees1.min=0
+ca.Policy.rule.NameConstraintsExt.excludedSubtrees1.base.generalNameChoice=
+ca.Policy.rule.NameConstraintsExt.excludedSubtrees1.base.generalNameValue=
+ca.Policy.rule.NameConstraintsExt.excludedSubtrees2.max=-1
+ca.Policy.rule.NameConstraintsExt.excludedSubtrees2.min=0
+ca.Policy.rule.NameConstraintsExt.excludedSubtrees2.base.generalNameChoice=
+ca.Policy.rule.NameConstraintsExt.excludedSubtrees2.base.generalNameValue=
+ca.Policy.rule.NameConstraintsExt.permittedSubtrees0.max=-1
+ca.Policy.rule.NameConstraintsExt.permittedSubtrees0.min=0
+ca.Policy.rule.NameConstraintsExt.permittedSubtrees0.base.generalNameChoice=
+ca.Policy.rule.NameConstraintsExt.permittedSubtrees0.base.generalNameValue=
+ca.Policy.rule.NameConstraintsExt.permittedSubtrees1.max=-1
+ca.Policy.rule.NameConstraintsExt.permittedSubtrees1.min=0
+ca.Policy.rule.NameConstraintsExt.permittedSubtrees1.base.generalNameChoice=
+ca.Policy.rule.NameConstraintsExt.permittedSubtrees1.base.generalNameValue=
+ca.Policy.rule.NameConstraintsExt.permittedSubtrees2.max=-1
+ca.Policy.rule.NameConstraintsExt.permittedSubtrees2.min=0
+ca.Policy.rule.NameConstraintsExt.permittedSubtrees2.base.generalNameChoice=
+ca.Policy.rule.NameConstraintsExt.permittedSubtrees2.base.generalNameValue=
+ca.Policy.rule.OCSPNoCheckExt.critical=false
+ca.Policy.rule.OCSPNoCheckExt.enable=true
+ca.Policy.rule.OCSPNoCheckExt.implName=OCSPNoCheckExt
+ca.Policy.rule.OCSPNoCheckExt.predicate=HTTP_PARAMS.certType==ocspResponder
+ca.Policy.rule.OCSPSigningExt.critical=false
+ca.Policy.rule.OCSPSigningExt.enable=true
+ca.Policy.rule.OCSPSigningExt.id0=1.3.6.1.5.5.7.3.9
+ca.Policy.rule.OCSPSigningExt.implName=ExtendedKeyUsageExt
+ca.Policy.rule.OCSPSigningExt.predicate=HTTP_PARAMS.certType==ocspResponder
+ca.Policy.rule.ObjSignCertKeyUsageExt.crlSign=false
+ca.Policy.rule.ObjSignCertKeyUsageExt.dataEncipherment=false
+ca.Policy.rule.ObjSignCertKeyUsageExt.decipherOnly=false
+ca.Policy.rule.ObjSignCertKeyUsageExt.digitalSignature=true
+ca.Policy.rule.ObjSignCertKeyUsageExt.enable=true
+ca.Policy.rule.ObjSignCertKeyUsageExt.encipherOnly=false
+ca.Policy.rule.ObjSignCertKeyUsageExt.implName=KeyUsageExt
+ca.Policy.rule.ObjSignCertKeyUsageExt.keyAgreement=false
+ca.Policy.rule.ObjSignCertKeyUsageExt.keyCertsign=true
+ca.Policy.rule.ObjSignCertKeyUsageExt.keyEncipherment=false
+ca.Policy.rule.ObjSignCertKeyUsageExt.nonRepudiation=false
+ca.Policy.rule.ObjSignCertKeyUsageExt.predicate=HTTP_PARAMS.certType==objSignClient
+ca.Policy.rule.PolicyConstraintsExt.critical=false
+ca.Policy.rule.PolicyConstraintsExt.enable=false
+ca.Policy.rule.PolicyConstraintsExt.implName=PolicyConstraintsExt
+ca.Policy.rule.PolicyConstraintsExt.inhibitPolicyMapping=0
+ca.Policy.rule.PolicyConstraintsExt.predicate=HTTP_PARAMS.certType==ca
+ca.Policy.rule.PolicyConstraintsExt.reqExplicitPolicy=0
+ca.Policy.rule.PolicyMappingsExt.critical=false
+ca.Policy.rule.PolicyMappingsExt.enable=false
+ca.Policy.rule.PolicyMappingsExt.implName=PolicyMappingsExt
+ca.Policy.rule.PolicyMappingsExt.numPolicyMappings=1
+ca.Policy.rule.PolicyMappingsExt.predicate=HTTP_PARAMS.certType==ca
+ca.Policy.rule.PolicyMappingsExt.policyMap0.issuerDomainPolicy=
+ca.Policy.rule.PolicyMappingsExt.policyMap0.subjectDomainPolicy=
+ca.Policy.rule.RMCertKeyUsageExt.crlSign=false
+ca.Policy.rule.RMCertKeyUsageExt.dataEncipherment=false
+ca.Policy.rule.RMCertKeyUsageExt.decipherOnly=false
+ca.Policy.rule.RMCertKeyUsageExt.digitalSignature=true
+ca.Policy.rule.RMCertKeyUsageExt.enable=true
+ca.Policy.rule.RMCertKeyUsageExt.encipherOnly=false
+ca.Policy.rule.RMCertKeyUsageExt.implName=KeyUsageExt
+ca.Policy.rule.RMCertKeyUsageExt.keyAgreement=false
+ca.Policy.rule.RMCertKeyUsageExt.keyCertsign=false
+ca.Policy.rule.RMCertKeyUsageExt.keyEncipherment=false
+ca.Policy.rule.RMCertKeyUsageExt.nonRepudiation=true
+ca.Policy.rule.RMCertKeyUsageExt.predicate=HTTP_PARAMS.certType==ra
+ca.Policy.rule.RSAKeyRule.enable=false
+ca.Policy.rule.RSAKeyRule.exponents=3,7,17,65537
+ca.Policy.rule.RSAKeyRule.implName=RSAKeyConstraints
+ca.Policy.rule.RSAKeyRule.maxSize=2048
+ca.Policy.rule.RSAKeyRule.minSize=512
+ca.Policy.rule.RSAKeyRule.predicate=
+ca.Policy.rule.RenewalConstraintsRule.enable=true
+ca.Policy.rule.RenewalConstraintsRule.implName=RenewalConstraints
+ca.Policy.rule.RenewalConstraintsRule.predicate=
+ca.Policy.rule.RevocationConstraintsRule.enable=true
+ca.Policy.rule.RevocationConstraintsRule.implName=RevocationConstraints
+ca.Policy.rule.RevocationConstraintsRule.predicate=
+ca.Policy.rule.ServerCertKeyUsageExt.crlSign=false
+ca.Policy.rule.ServerCertKeyUsageExt.dataEncipherment=true
+ca.Policy.rule.ServerCertKeyUsageExt.decipherOnly=false
+ca.Policy.rule.ServerCertKeyUsageExt.digitalSignature=true
+ca.Policy.rule.ServerCertKeyUsageExt.enable=true
+ca.Policy.rule.ServerCertKeyUsageExt.encipherOnly=false
+ca.Policy.rule.ServerCertKeyUsageExt.implName=KeyUsageExt
+ca.Policy.rule.ServerCertKeyUsageExt.keyAgreement=false
+ca.Policy.rule.ServerCertKeyUsageExt.keyCertsign=false
+ca.Policy.rule.ServerCertKeyUsageExt.keyEncipherment=true
+ca.Policy.rule.ServerCertKeyUsageExt.nonRepudiation=true
+ca.Policy.rule.ServerCertKeyUsageExt.predicate=HTTP_PARAMS.certType==server
+ca.Policy.rule.SigningAlgRule.algorithms=MD5withRSA,MD2withRSA,SHA1withRSA,SHA256withRSA,SHA512withRSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+ca.Policy.rule.SigningAlgRule.enable=true
+ca.Policy.rule.SigningAlgRule.implName=SigningAlgorithmConstraints
+ca.Policy.rule.SigningAlgRule.predicate=
+ca.Policy.rule.SubCANameConstraints.enable=true
+ca.Policy.rule.SubCANameConstraints.implName=SubCANameConstraints
+ca.Policy.rule.SubCANameConstraints.predicate=HTTP_PARAMS.certType == ca
+ca.Policy.rule.SubjectAltNameExt.enable=true
+ca.Policy.rule.SubjectAltNameExt.implName=SubjectAltNameExt
+ca.Policy.rule.SubjectAltNameExt.numGeneralNames=3
+ca.Policy.rule.SubjectAltNameExt.predicate=HTTP_PARAMS.certType!=CEP-Request
+ca.Policy.rule.SubjectAltNameExt.generalName0.generalNameChoice=rfc822Name
+ca.Policy.rule.SubjectAltNameExt.generalName0.requestAttr=AUTH_TOKEN.mail
+ca.Policy.rule.SubjectAltNameExt.generalName1.generalNameChoice=rfc822Name
+ca.Policy.rule.SubjectAltNameExt.generalName1.requestAttr=AUTH_TOKEN.mailalternateaddress
+ca.Policy.rule.SubjectAltNameExt.generalName2.generalNameChoice=rfc822Name
+ca.Policy.rule.SubjectAltNameExt.generalName2.requestAttr=HTTP_PARAMS.csrRequestorEmail
+ca.Policy.rule.SubjectKeyIdentifierExt.enable=true
+ca.Policy.rule.SubjectKeyIdentifierExt.implName=SubjectKeyIdentifierExt
+ca.Policy.rule.SubjectKeyIdentifierExt.predicate=HTTP_PARAMS.certType==ca
+ca.Policy.rule.UniqueSubjectNameConstraints.enable=false
+ca.Policy.rule.UniqueSubjectNameConstraints.implName=UniqueSubjectNameConstraints
+ca.Policy.rule.UniqueSubjectNameConstraints.predicate=
+ca.crl._000=##
+ca.crl._001=## CA CRL
+ca.crl._002=##
+ca.crl.pageSize=100
+ca.crl.MasterCRL.allowExtensions=true
+ca.crl.MasterCRL.alwaysUpdate=false
+ca.crl.MasterCRL.autoUpdateInterval=240
+ca.crl.MasterCRL.caCertsOnly=false
+ca.crl.MasterCRL.cacheUpdateInterval=15
+ca.crl.MasterCRL.class=com.netscape.ca.CRLIssuingPoint
+ca.crl.MasterCRL.dailyUpdates=1:00
+ca.crl.MasterCRL.description=CA's complete Certificate Revocation List
+ca.crl.MasterCRL.enable=true
+ca.crl.MasterCRL.enableCRLCache=true
+ca.crl.MasterCRL.enableCRLUpdates=true
+ca.crl.MasterCRL.enableCacheTesting=false
+ca.crl.MasterCRL.enableCacheRecovery=true
+ca.crl.MasterCRL.enableDailyUpdates=true
+ca.crl.MasterCRL.enableUpdateInterval=true
+ca.crl.MasterCRL.extendedNextUpdate=true
+ca.crl.MasterCRL.includeExpiredCerts=false
+ca.crl.MasterCRL.minUpdateInterval=0
+ca.crl.MasterCRL.nextUpdateGracePeriod=0
+ca.crl.MasterCRL.publishOnStart=false
+ca.crl.MasterCRL.saveMemory=false
+ca.crl.MasterCRL.signingAlgorithm=SHA256withRSA
+ca.crl.MasterCRL.updateSchema=1
+ca.crl.MasterCRL.extension.AuthorityInformationAccess.accessLocation0=
+ca.crl.MasterCRL.extension.AuthorityInformationAccess.accessLocationType0=URI
+ca.crl.MasterCRL.extension.AuthorityInformationAccess.accessMethod0=caIssuers
+ca.crl.MasterCRL.extension.AuthorityInformationAccess.class=com.netscape.cms.crl.CMSAuthInfoAccessExtension
+ca.crl.MasterCRL.extension.AuthorityInformationAccess.critical=false
+ca.crl.MasterCRL.extension.AuthorityInformationAccess.enable=false
+ca.crl.MasterCRL.extension.AuthorityInformationAccess.numberOfAccessDescriptions=1
+ca.crl.MasterCRL.extension.AuthorityInformationAccess.type=CRLExtension
+ca.crl.MasterCRL.extension.AuthorityKeyIdentifier.class=com.netscape.cms.crl.CMSAuthorityKeyIdentifierExtension
+ca.crl.MasterCRL.extension.AuthorityKeyIdentifier.critical=false
+ca.crl.MasterCRL.extension.AuthorityKeyIdentifier.enable=false
+ca.crl.MasterCRL.extension.AuthorityKeyIdentifier.type=CRLExtension
+ca.crl.MasterCRL.extension.CRLNumber.class=com.netscape.cms.crl.CMSCRLNumberExtension
+ca.crl.MasterCRL.extension.CRLNumber.critical=false
+ca.crl.MasterCRL.extension.CRLNumber.enable=true
+ca.crl.MasterCRL.extension.CRLNumber.type=CRLExtension
+ca.crl.MasterCRL.extension.CRLReason.class=com.netscape.cms.crl.CMSCRLReasonExtension
+ca.crl.MasterCRL.extension.CRLReason.critical=false
+ca.crl.MasterCRL.extension.CRLReason.enable=true
+ca.crl.MasterCRL.extension.CRLReason.type=CRLEntryExtension
+ca.crl.MasterCRL.extension.DeltaCRLIndicator.class=com.netscape.cms.crl.CMSDeltaCRLIndicatorExtension
+ca.crl.MasterCRL.extension.DeltaCRLIndicator.critical=true
+ca.crl.MasterCRL.extension.DeltaCRLIndicator.enable=false
+ca.crl.MasterCRL.extension.DeltaCRLIndicator.type=CRLExtension
+ca.crl.MasterCRL.extension.FreshestCRL.class=com.netscape.cms.crl.CMSFreshestCRLExtension
+ca.crl.MasterCRL.extension.FreshestCRL.critical=false
+ca.crl.MasterCRL.extension.FreshestCRL.enable=false
+ca.crl.MasterCRL.extension.FreshestCRL.numPoints=0
+ca.crl.MasterCRL.extension.FreshestCRL.pointName0=
+ca.crl.MasterCRL.extension.FreshestCRL.pointType0=
+ca.crl.MasterCRL.extension.FreshestCRL.type=CRLExtension
+ca.crl.MasterCRL.extension.InvalidityDate.class=com.netscape.cms.crl.CMSInvalidityDateExtension
+ca.crl.MasterCRL.extension.InvalidityDate.critical=false
+ca.crl.MasterCRL.extension.InvalidityDate.enable=true
+ca.crl.MasterCRL.extension.InvalidityDate.type=CRLEntryExtension
+ca.crl.MasterCRL.extension.IssuerAlternativeName.class=com.netscape.cms.crl.CMSIssuerAlternativeNameExtension
+ca.crl.MasterCRL.extension.IssuerAlternativeName.critical=false
+ca.crl.MasterCRL.extension.IssuerAlternativeName.enable=false
+ca.crl.MasterCRL.extension.IssuerAlternativeName.name0=
+ca.crl.MasterCRL.extension.IssuerAlternativeName.nameType0=
+ca.crl.MasterCRL.extension.IssuerAlternativeName.numNames=0
+ca.crl.MasterCRL.extension.IssuerAlternativeName.type=CRLExtension
+ca.crl.MasterCRL.extension.IssuingDistributionPoint.class=com.netscape.cms.crl.CMSIssuingDistributionPointExtension
+ca.crl.MasterCRL.extension.IssuingDistributionPoint.critical=true
+ca.crl.MasterCRL.extension.IssuingDistributionPoint.enable=false
+ca.crl.MasterCRL.extension.IssuingDistributionPoint.indirectCRL=false
+ca.crl.MasterCRL.extension.IssuingDistributionPoint.onlyContainsCACerts=false
+ca.crl.MasterCRL.extension.IssuingDistributionPoint.onlyContainsUserCerts=false
+ca.crl.MasterCRL.extension.IssuingDistributionPoint.onlySomeReasons=
+ca.crl.MasterCRL.extension.IssuingDistributionPoint.pointName=
+ca.crl.MasterCRL.extension.IssuingDistributionPoint.pointType=
+ca.crl.MasterCRL.extension.IssuingDistributionPoint.type=CRLExtension
+ca.notification.certIssued.emailSubject=Your Certificate Request
+ca.notification.certIssued.emailTemplate=[PKI_INSTANCE_PATH]/emails/certIssued_CA.html
+ca.notification.certIssued.enabled=false
+ca.notification.certIssued.senderEmail=
+ca.notification.certRevoked.emailSubject=Your Certificate Revoked
+ca.notification.certRevoked.emailTemplate=[PKI_INSTANCE_PATH]/emails/certRevoked_CA.html
+ca.notification.certRevoked.enabled=false
+ca.notification.certRevoked.senderEmail=
+ca.notification.requestInQ.emailSubject=Certificate Request in Queue
+ca.notification.requestInQ.emailTemplate=[PKI_INSTANCE_PATH]/emails/reqInQueue_CA.html
+ca.notification.requestInQ.enabled=false
+ca.notification.requestInQ.recipientEmail=
+ca.notification.requestInQ.senderEmail=
+ca.ocsp_signing.cacertnickname=ocspSigningCert cert-[PKI_INSTANCE_ID]
+ca.ocsp_signing.defaultSigningAlgorithm=SHA256withRSA
+ca.ocsp_signing.tokenname=internal
+ca.publish.createOwnDNEntry=false
+ca.publish.queue.enable=true
+ca.publish.queue.maxNumberOfThreads=3
+ca.publish.queue.pageSize=40
+ca.publish.queue.priorityLevel=0
+ca.publish.queue.saveStatus=200
+ca.publish.mapper.impl.LdapCaSimpleMap.class=com.netscape.cms.publish.mappers.LdapCaSimpleMap
+ca.publish.mapper.impl.LdapDNCompsMap.class=com.netscape.cms.publish.mappers.LdapCertCompsMap
+ca.publish.mapper.impl.LdapDNExactMap.class=com.netscape.cms.publish.mappers.LdapCertExactMap
+ca.publish.mapper.impl.LdapEnhancedMap.class=com.netscape.cms.publish.mappers.LdapEnhancedMap
+ca.publish.mapper.impl.LdapSimpleMap.class=com.netscape.cms.publish.mappers.LdapSimpleMap
+ca.publish.mapper.impl.LdapSubjAttrMap.class=com.netscape.cms.publish.mappers.LdapCertSubjMap
+ca.publish.mapper.impl.NoMap.class=com.netscape.cms.publish.mappers.NoMap
+ca.publish.mapper.instance.LdapCaCertMap.createCAEntry=true
+ca.publish.mapper.instance.LdapCaCertMap.dnPattern=UID=$subj.cn,OU=people,O=$subj.o
+ca.publish.mapper.instance.LdapCaCertMap.pluginName=LdapCaSimpleMap
+ca.publish.mapper.instance.LdapCrlMap.createCAEntry=true
+ca.publish.mapper.instance.LdapCrlMap.dnPattern=UID=$subj.cn,OU=people,O=$subj.o
+ca.publish.mapper.instance.LdapCrlMap.pluginName=LdapCaSimpleMap
+ca.publish.mapper.instance.LdapUserCertMap.dnPattern=UID=$subj.UID,OU=people,O=$subj.o
+ca.publish.mapper.instance.LdapUserCertMap.pluginName=LdapSimpleMap
+ca.publish.mapper.instance.NoMap.pluginName=NoMap
+ca.publish.publisher.impl.FileBasedPublisher.class=com.netscape.cms.publish.publishers.FileBasedPublisher
+ca.publish.publisher.impl.LdapCaCertPublisher.class=com.netscape.cms.publish.publishers.LdapCaCertPublisher
+ca.publish.publisher.impl.LdapCertificatePairPublisher.class=com.netscape.cms.publish.publishers.LdapCertificatePairPublisher
+ca.publish.publisher.impl.LdapCrlPublisher.class=com.netscape.cms.publish.publishers.LdapCrlPublisher
+ca.publish.publisher.impl.LdapDeltaCrlPublisher.class=com.netscape.cms.publish.publishers.LdapCrlPublisher
+ca.publish.publisher.impl.LdapUserCertPublisher.class=com.netscape.cms.publish.publishers.LdapUserCertPublisher
+ca.publish.publisher.impl.OCSPPublisher.class=com.netscape.cms.publish.publishers.OCSPPublisher
+ca.publish.publisher.instance.LdapCaCertPublisher.caCertAttr=caCertificate;binary
+ca.publish.publisher.instance.LdapCaCertPublisher.caObjectClass=pkiCA
+ca.publish.publisher.instance.LdapCaCertPublisher.pluginName=LdapCaCertPublisher
+ca.publish.publisher.instance.LdapCrlPublisher.crlAttr=certificateRevocationList;binary
+ca.publish.publisher.instance.LdapCrlPublisher.pluginName=LdapCrlPublisher
+ca.publish.publisher.instance.LdapCrlPublisher.crlObjectClass=pkiCA
+ca.publish.publisher.instance.LdapCrossCertPairPublisher.caObjectClass=pkiCA
+ca.publish.publisher.instance.LdapCrossCertPairPublisher.crossCertPairAttr=crossCertificatePair;binary
+ca.publish.publisher.instance.LdapCrossCertPairPublisher.pluginName=LdapCertificatePairPublisher
+ca.publish.publisher.instance.LdapDeltaCrlPublisher.crlAttr=deltaRevocationList;binary
+ca.publish.publisher.instance.LdapDeltaCrlPublisher.crlObjectClass=pkiCA,deltaCRL
+ca.publish.publisher.instance.LdapDeltaCrlPublisher.pluginName=LdapDeltaCrlPublisher
+ca.publish.publisher.instance.LdapUserCertPublisher.certAttr=userCertificate;binary
+ca.publish.publisher.instance.LdapUserCertPublisher.pluginName=LdapUserCertPublisher
+ca.publish.rule.impl.Rule.class=com.netscape.cmscore.ldap.LdapRule
+ca.publish.rule.instance.LdapCaCertRule.enable=false
+ca.publish.rule.instance.LdapCaCertRule.mapper=LdapCaCertMap
+ca.publish.rule.instance.LdapCaCertRule.pluginName=Rule
+ca.publish.rule.instance.LdapCaCertRule.predicate=
+ca.publish.rule.instance.LdapCaCertRule.publisher=LdapCaCertPublisher
+ca.publish.rule.instance.LdapCaCertRule.type=cacert
+ca.publish.rule.instance.LdapCrlRule.enable=false
+ca.publish.rule.instance.LdapCrlRule.mapper=LdapCrlMap
+ca.publish.rule.instance.LdapCrlRule.pluginName=Rule
+ca.publish.rule.instance.LdapCrlRule.predicate=
+ca.publish.rule.instance.LdapCrlRule.publisher=LdapCrlPublisher
+ca.publish.rule.instance.LdapCrlRule.type=crl
+ca.publish.rule.instance.LdapUserCertRule.enable=false
+ca.publish.rule.instance.LdapUserCertRule.mapper=LdapUserCertMap
+ca.publish.rule.instance.LdapUserCertRule.pluginName=Rule
+ca.publish.rule.instance.LdapUserCertRule.predicate=
+ca.publish.rule.instance.LdapUserCertRule.publisher=LdapUserCertPublisher
+ca.publish.rule.instance.LdapUserCertRule.type=certs
+ca.publish.rule.instance.LdapXCertRule.enable=false
+ca.publish.rule.instance.LdapXCertRule.mapper=LdapCaCertMap
+ca.publish.rule.instance.LdapXCertRule.pluginName=Rule
+ca.publish.rule.instance.LdapXCertRule.predicate=
+ca.publish.rule.instance.LdapXCertRule.publisher=LdapCrossCertPairPublisher
+ca.publish.rule.instance.LdapXCertRule.type=xcert
+cmc.cert.confirmRequired=false
+cmc.lraPopWitness.verify.allow=true
+cmc.revokeCert.verify=true
+cmc.revokeCert.sharedSecret.class=com.netscape.cms.authentication.SharedSecret
+cmc.sharedSecret.class=com.netscape.cms.authentication.SharedSecret
+cms.passwordlist=internaldb,replicationdb
+cms.password.ignore.publishing.failure=true
+cms.version=@MAJOR_VERSION@.@MINOR_VERSION@
+cmsgateway._000=##
+cmsgateway._001=## In the event that all Admin Certificates have been lost
+cmsgateway._002=## for a given instance, perform the following steps to
+cmsgateway._003=## re-enroll for a new Admin Certificate:
+cmsgateway._004=##
+cmsgateway._005=## (1) Become 'root'
+cmsgateway._006=## (2) Type: 'service [PKI_INSTANCE_ID] stop'
+cmsgateway._007=## (3) Edit '[PKI_INSTANCE_ROOT]/[PKI_INSTANCE_ID]/conf/CS.cfg'
+cmsgateway._008=## and set the following name-value pairs (if necessary):
+cmsgateway._009=##
+cmsgateway._010=## ca.Policy.enable=true
+cmsgateway._011=## cmsgateway.enableAdminEnroll=true
+cmsgateway._012=##
+cmsgateway._013=## (4) Type: 'service [PKI_INSTANCE_ID] start'
+cmsgateway._014=## (5) Launch a browser and re-enroll for
+cmsgateway._015=## a new Admin Certificate by typing:
+cmsgateway._016=##
+cmsgateway._017=## https://[PKI_MACHINE_NAME]:[PKI_ADMIN_SECURE_PORT]/ca/admin/ca/adminEnroll.html
+cmsgateway._018=##
+cmsgateway._019=## (6) Verify that the browser contains the new
+cmsgateway._020=## Admin Certificate by successfully navigating to:
+cmsgateway._021=##
+cmsgateway._022=## https://[PKI_MACHINE_NAME]:[PKI_AGENT_SECURE_PORT]/ca/agent/ca/
+cmsgateway._023=##
+cmsgateway._024=## (7) Optionally, disable the Certificate Policies Framework
+cmsgateway._025=## by following steps (1) - (4), but ONLY resetting
+cmsgateway._026=## 'ca.Policy.enable=false', as
+cmsgateway._027=## 'cmsgateway.enableAdminEnroll=false' should have
+cmsgateway._028=## already been reset.
+cmsgateway._029=##
+cmsgateway.enableAdminEnroll=false
+https.port=8443
+http.port=8080
+dbs.enableSerialManagement=false
+dbs.beginRequestNumber=1
+dbs.endRequestNumber=10000000
+dbs.requestIncrement=10000000
+dbs.requestLowWaterMark=2000000
+dbs.requestCloneTransferNumber=10000
+dbs.requestDN=ou=ca, ou=requests
+dbs.requestRangeDN=ou=requests, ou=ranges
+dbs.beginSerialNumber=1
+dbs.endSerialNumber=10000000
+dbs.serialIncrement=10000000
+dbs.serialLowWaterMark=2000000
+dbs.serialCloneTransferNumber=10000
+dbs.serialDN=ou=certificateRepository, ou=ca
+dbs.serialRangeDN=ou=certificateRepository, ou=ranges
+dbs.beginReplicaNumber=1
+dbs.endReplicaNumber=100
+dbs.replicaIncrement=100
+dbs.replicaLowWaterMark=20
+dbs.replicaCloneTransferNumber=5
+dbs.replicaDN=ou=replica
+dbs.replicaRangeDN=ou=replica, ou=ranges
+dbs.ldap=internaldb
+dbs.newSchemaEntryAdded=true
+debug.append=true
+debug.enabled=true
+debug.filename=[PKI_INSTANCE_PATH]/logs/debug
+debug.hashkeytypes=
+debug.level=0
+debug.showcaller=false
+keys.ecc.curve.list=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
+keys.ecc.curve.display.list=nistp256 (secp256r1),nistp384 (secp384r1),nistp521 (secp521r1),nistk163 (sect163k1),sect163r1,nistb163 (sect163r2),sect193r1,sect193r2,nistk233 (sect233k1),nistb233 (sect233r1),sect239k1,nistk283 (sect283k1),nistb283 (sect283r1),nistk409 (sect409k1),nistb409 (sect409r1),nistk571 (sect571k1),nistb571 (sect571r1),secp160k1,secp160r1,secp160r2,secp192k1,nistp192 (secp192r1, prime192v1),secp224k1,nistp224 (secp224r1),secp256k1,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
+keys.ecc.curve.default=nistp256
+keys.rsa.keysize.default=2048
+internaldb._000=##
+internaldb._001=## Internal Database
+internaldb._002=##
+internaldb.basedn=
+internaldb.maxConns=15
+internaldb.minConns=3
+internaldb.ldapauth.authtype=BasicAuth
+internaldb.ldapauth.bindDN=cn=Directory Manager
+internaldb.ldapauth.bindPWPrompt=Internal LDAP Database
+internaldb.ldapauth.clientCertNickname=
+internaldb.ldapconn.host=
+internaldb.ldapconn.port=
+internaldb.ldapconn.secureConn=false
+preop.internaldb.schema.ldif=/usr/share/[PKI_FLAVOR]/ca/conf/schema.ldif
+preop.internaldb.ldif=/usr/share/[PKI_FLAVOR]/ca/conf/database.ldif
+preop.internaldb.data_ldif=/usr/share/[PKI_FLAVOR]/ca/conf/db.ldif,/usr/share/[PKI_FLAVOR]/ca/conf/acl.ldif
+preop.internaldb.index_ldif=
+preop.internaldb.manager_ldif=/usr/share/[PKI_FLAVOR]/ca/conf/manager.ldif
+preop.internaldb.post_ldif=/usr/share/[PKI_FLAVOR]/ca/conf/index.ldif,/usr/share/[PKI_FLAVOR]/ca/conf/vlv.ldif,/usr/share/[PKI_FLAVOR]/ca/conf/vlvtasks.ldif
+preop.internaldb.wait_dn=cn=index1160589769, cn=index, cn=tasks, cn=config
+internaldb.multipleSuffix.enable=false
+jobsScheduler._000=##
+jobsScheduler._001=## jobScheduler
+jobsScheduler._002=##
+jobsScheduler.enabled=false
+jobsScheduler.interval=1
+jobsScheduler.impl.PublishCertsJob.class=com.netscape.cms.jobs.PublishCertsJob
+jobsScheduler.impl.RenewalNotificationJob.class=com.netscape.cms.jobs.RenewalNotificationJob
+jobsScheduler.impl.RequestInQueueJob.class=com.netscape.cms.jobs.RequestInQueueJob
+jobsScheduler.impl.UnpublishExpiredJob.class=com.netscape.cms.jobs.UnpublishExpiredJob
+jobsScheduler.job.certRenewalNotifier.cron=0 3 * * 1-5
+jobsScheduler.job.certRenewalNotifier.emailSubject=Certificate Renewal Notification
+jobsScheduler.job.certRenewalNotifier.emailTemplate=[PKI_INSTANCE_PATH]/emails/rnJob1.txt
+jobsScheduler.job.certRenewalNotifier.enabled=false
+jobsScheduler.job.certRenewalNotifier.notifyEndOffset=30
+jobsScheduler.job.certRenewalNotifier.notifyTriggerOffset=30
+jobsScheduler.job.certRenewalNotifier.pluginName=RenewalNotificationJob
+jobsScheduler.job.certRenewalNotifier.senderEmail=
+jobsScheduler.job.certRenewalNotifier.summary.emailSubject=Certificate Renewal Notification Summary
+jobsScheduler.job.certRenewalNotifier.summary.emailTemplate=[PKI_INSTANCE_PATH]/emails/rnJob1Summary.txt
+jobsScheduler.job.certRenewalNotifier.summary.enabled=true
+jobsScheduler.job.certRenewalNotifier.summary.itemTemplate=[PKI_INSTANCE_PATH]/emails/rnJob1Item.txt
+jobsScheduler.job.certRenewalNotifier.summary.recipientEmail=
+jobsScheduler.job.certRenewalNotifier.summary.senderEmail=
+jobsScheduler.job.publishCerts.cron=0 0 * * 2
+jobsScheduler.job.publishCerts.enabled=false
+jobsScheduler.job.publishCerts.pluginName=PublishCertsJob
+jobsScheduler.job.publishCerts.summary.emailSubject=Certs Publishing Summary
+jobsScheduler.job.publishCerts.summary.emailTemplate=[PKI_INSTANCE_PATH]/emails/publishCerts.html
+jobsScheduler.job.publishCerts.summary.enabled=true
+jobsScheduler.job.publishCerts.summary.itemTemplate=[PKI_INSTANCE_PATH]/emails/publishCertsItem.html
+jobsScheduler.job.publishCerts.summary.recipientEmail=
+jobsScheduler.job.publishCerts.summary.senderEmail=
+jobsScheduler.job.requestInQueueNotifier.cron=0 0 * * 0
+jobsScheduler.job.requestInQueueNotifier.enabled=false
+jobsScheduler.job.requestInQueueNotifier.pluginName=RequestInQueueJob
+jobsScheduler.job.requestInQueueNotifier.subsystemId=ca
+jobsScheduler.job.requestInQueueNotifier.summary.emailSubject=Requests in Queue Summary Report
+jobsScheduler.job.requestInQueueNotifier.summary.emailTemplate=[PKI_INSTANCE_PATH]/emails/riq1Summary.html
+jobsScheduler.job.requestInQueueNotifier.summary.enabled=true
+jobsScheduler.job.requestInQueueNotifier.summary.recipientEmail=
+jobsScheduler.job.requestInQueueNotifier.summary.senderEmail=
+jobsScheduler.job.unpublishExpiredCerts.cron=0 0 * * 6
+jobsScheduler.job.unpublishExpiredCerts.enabled=false
+jobsScheduler.job.unpublishExpiredCerts.pluginName=UnpublishExpiredJob
+jobsScheduler.job.unpublishExpiredCerts.summary.emailSubject=Expired Certs Unpublished Summary
+jobsScheduler.job.unpublishExpiredCerts.summary.emailTemplate=[PKI_INSTANCE_PATH]/emails/euJob1.html
+jobsScheduler.job.unpublishExpiredCerts.summary.enabled=true
+jobsScheduler.job.unpublishExpiredCerts.summary.itemTemplate=[PKI_INSTANCE_PATH]/emails/euJob1Item.html
+jobsScheduler.job.unpublishExpiredCerts.summary.recipientEmail=
+jobsScheduler.job.unpublishExpiredCerts.summary.senderEmail=
+jss._000=##
+jss._001=## JSS
+jss._002=##
+jss.configDir=[PKI_INSTANCE_PATH]/alias/
+jss.enable=true
+jss.secmodName=secmod.db
+jss.ocspcheck.enable=false
+jss.ssl.cipherfortezza=true
+jss.ssl.cipherpref=
+jss.ssl.cipherversion=cipherdomestic
+log._000=##
+log._001=## Logging
+log._002=##
+log.impl.file.class=com.netscape.cms.logging.RollingLogFile
+log.instance.SignedAudit._000=##
+log.instance.SignedAudit._001=## Signed Audit Logging
+log.instance.SignedAudit._002=##
+log.instance.SignedAudit._003=##
+log.instance.SignedAudit._004=## Available Audit events:
+log.instance.SignedAudit._005=## AUDIT_LOG_STARTUP,AUDIT_LOG_SHUTDOWN,ROLE_ASSUME,CONFIG_CERT_POLICY,CONFIG_CERT_PROFILE,CONFIG_CRL_PROFILE,CONFIG_OCSP_PROFILE,CONFIG_AUTH,CONFIG_ROLE,CONFIG_ACL,CONFIG_SIGNED_AUDIT,CONFIG_ENCRYPTION,CONFIG_TRUSTED_PUBLIC_KEY,CONFIG_DRM,SELFTESTS_EXECUTION,AUDIT_LOG_DELETE,LOG_PATH_CHANGE,LOG_EXPIRATION_CHANGE,PRIVATE_KEY_ARCHIVE_REQUEST,PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE,KEY_RECOVERY_REQUEST,KEY_RECOVERY_REQUEST_ASYNC,KEY_RECOVERY_AGENT_LOGIN,KEY_RECOVERY_REQUEST_PROCESSED,KEY_RECOVERY_REQUEST_PROCESSED_ASYNC,KEY_GEN_ASYMMETRIC,NON_PROFILE_CERT_REQUEST,PROFILE_CERT_REQUEST,CERT_REQUEST_PROCESSED,CERT_STATUS_CHANGE_REQUEST,CERT_STATUS_CHANGE_REQUEST_PROCESSED,AUTHZ_SUCCESS,AUTHZ_FAIL,INTER_BOUNDARY,AUTH_FAIL,AUTH_SUCCESS,CERT_PROFILE_APPROVAL,PROOF_OF_POSSESSION,CRL_RETRIEVAL,CRL_VALIDATION,CMC_SIGNED_REQUEST_SIG_VERIFY,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_FAILURE,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_SUCCESS,SERVER_SIDE_KEYGEN_REQUEST,COMPUTE_SESSION_KEY_REQUEST,COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS, COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE,DIVERSIFY_KEY_REQUEST,DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS, DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE,ENCRYPT_DATA_REQUEST,ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS,ENCRYPT_DATA_REQUEST_PROCESSED_FAILURE,OCSP_ADD_CA_REQUEST,OCSP_ADD_CA_REQUEST_PROCESSED,OCSP_REMOVE_CA_REQUEST,OCSP_REMOVE_CA_REQUEST_PROCESSED_SUCCESS,OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE,COMPUTE_RANDOM_DATA_REQUEST,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_SUCCESS,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_FAILURE,CIMC_CERT_VERIFICATION,SECURITY_DOMAIN_UPDATE,CONFIG_SERIAL_NUMBER
+log.instance.SignedAudit._006=##
+log.instance.SignedAudit.bufferSize=512
+log.instance.SignedAudit.enable=true
+log.instance.SignedAudit.events=AUDIT_LOG_STARTUP,AUDIT_LOG_SHUTDOWN,ROLE_ASSUME,CONFIG_CERT_POLICY,CONFIG_CERT_PROFILE,CONFIG_CRL_PROFILE,CONFIG_OCSP_PROFILE,CONFIG_AUTH,CONFIG_ROLE,CONFIG_ACL,CONFIG_SIGNED_AUDIT,CONFIG_ENCRYPTION,CONFIG_TRUSTED_PUBLIC_KEY,CONFIG_DRM,SELFTESTS_EXECUTION,AUDIT_LOG_DELETE,LOG_PATH_CHANGE,PRIVATE_KEY_ARCHIVE_REQUEST,PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE,KEY_RECOVERY_REQUEST,KEY_RECOVERY_REQUEST_ASYNC,KEY_RECOVERY_AGENT_LOGIN,KEY_RECOVERY_REQUEST_PROCESSED,KEY_RECOVERY_REQUEST_PROCESSED_ASYNC,KEY_GEN_ASYMMETRIC,NON_PROFILE_CERT_REQUEST,PROFILE_CERT_REQUEST,CERT_REQUEST_PROCESSED,CERT_STATUS_CHANGE_REQUEST,CERT_STATUS_CHANGE_REQUEST_PROCESSED,AUTHZ_SUCCESS,AUTHZ_FAIL,INTER_BOUNDARY,AUTH_FAIL,AUTH_SUCCESS,CERT_PROFILE_APPROVAL,PROOF_OF_POSSESSION,CRL_RETRIEVAL,CRL_VALIDATION,CMC_SIGNED_REQUEST_SIG_VERIFY,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_FAILURE,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_SUCCESS,SERVER_SIDE_KEYGEN_REQUEST,COMPUTE_SESSION_KEY_REQUEST,COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS, COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE,DIVERSIFY_KEY_REQUEST,DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS, DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE,ENCRYPT_DATA_REQUEST,ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS,ENCRYPT_DATA_REQUEST_PROCESSED_FAILURE,OCSP_ADD_CA_REQUEST,OCSP_ADD_CA_REQUEST_PROCESSED,OCSP_REMOVE_CA_REQUEST,OCSP_REMOVE_CA_REQUEST_PROCESSED_SUCCESS,OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE,COMPUTE_RANDOM_DATA_REQUEST,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_SUCCESS,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_FAILURE,CIMC_CERT_VERIFICATION,SECURITY_DOMAIN_UPDATE,CONFIG_SERIAL_NUMBER
+log.instance.SignedAudit.expirationTime=0
+log.instance.SignedAudit.fileName=[PKI_INSTANCE_PATH]/logs/signedAudit/ca_audit
+log.instance.SignedAudit.flushInterval=5
+log.instance.SignedAudit.level=1
+log.instance.SignedAudit.logSigning=false
+log.instance.SignedAudit.maxFileSize=2000
+log.instance.SignedAudit.pluginName=file
+log.instance.SignedAudit.rolloverInterval=2592000
+log.instance.SignedAudit.signedAudit=_002=##
+log.instance.SignedAudit.signedAuditCertNickname=auditSigningCert cert-[PKI_INSTANCE_ID]
+log.instance.SignedAudit.type=signedAudit
+log.instance.System._000=##
+log.instance.System._001=## System Logging
+log.instance.System._002=##
+log.instance.System.bufferSize=512
+log.instance.System.enable=true
+log.instance.System.expirationTime=0
+log.instance.System.fileName=[PKI_INSTANCE_PATH]/logs/system
+log.instance.System.flushInterval=5
+log.instance.System.level=3
+log.instance.System.maxFileSize=2000
+log.instance.System.pluginName=file
+log.instance.System.rolloverInterval=2592000
+log.instance.System.type=system
+log.instance.Transactions._000=##
+log.instance.Transactions._001=## Transaction Logging
+log.instance.Transactions._002=##
+log.instance.Transactions.bufferSize=512
+log.instance.Transactions.enable=true
+log.instance.Transactions.expirationTime=0
+log.instance.Transactions.fileName=[PKI_INSTANCE_PATH]/logs/transactions
+log.instance.Transactions.flushInterval=5
+log.instance.Transactions.level=1
+log.instance.Transactions.maxFileSize=2000
+log.instance.Transactions.pluginName=file
+log.instance.Transactions.rolloverInterval=2592000
+log.instance.Transactions.type=transaction
+logAudit.fileName=[PKI_INSTANCE_PATH]/logs/access
+logError.fileName=[PKI_INSTANCE_PATH]/logs/error
+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.extended_key_usage.class=netscape.security.extensions.ExtendedKeyUsageExtension
+oidmap.extended_key_usage.oid=2.5.29.37
+oidmap.extensions_requested_pkcs9.class=com.netscape.cms.servlet.cert.scep.ExtensionsRequested
+oidmap.extensions_requested_pkcs9.oid=1.2.840.113549.1.9.14
+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.netscape_comment.class=netscape.security.x509.NSCCommentExtension
+oidmap.netscape_comment.oid=2.16.840.1.113730.1.13
+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.pse.class=netscape.security.extensions.PresenceServerExtension
+oidmap.pse.oid=2.16.840.1.113730.1.18
+oidmap.subject_info_access.class=netscape.security.extensions.SubjectInfoAccessExtension
+oidmap.subject_info_access.oid=1.3.6.1.5.5.7.1.11
+os.userid=nobody
+profile.list=caUserCert,caECUserCert,caUserSMIMEcapCert,caDualCert,caECDualCert,caSignedLogCert,caTPSCert,caRARouterCert,caRouterCert,caServerCert,caOtherCert,caCACert,caInstallCACert,caRACert,caOCSPCert,caTransportCert,caDirUserCert,caAgentServerCert,caAgentFileSigning,caCMCUserCert,caFullCMCUserCert,caSimpleCMCUserCert,caTokenDeviceKeyEnrollment,caTokenUserEncryptionKeyEnrollment,caTokenUserSigningKeyEnrollment,caTempTokenDeviceKeyEnrollment,caTempTokenUserEncryptionKeyEnrollment,caTempTokenUserSigningKeyEnrollment,caAdminCert,caInternalAuthServerCert,caInternalAuthTransportCert,caInternalAuthDRMstorageCert,caInternalAuthSubsystemCert,caInternalAuthOCSPCert,caInternalAuthAuditSigningCert,DomainController,caDualRAuserCert,caRAagentCert,caRAserverCert,caUUIDdeviceCert,caSSLClientSelfRenewal,caDirUserRenewal,caManualRenewal,caTokenMSLoginEnrollment,caTokenUserSigningKeyRenewal,caTokenUserEncryptionKeyRenewal,caJarSigningCert,caIPAserviceCert,caEncUserCert,caEncECUserCert
+profile.caUUIDdeviceCert.class_id=caEnrollImpl
+profile.caUUIDdeviceCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caUUIDdeviceCert.cfg
+profile.caManualRenewal.class_id=caEnrollImpl
+profile.caManualRenewal.config=[PKI_INSTANCE_PATH]/profiles/ca/caManualRenewal.cfg
+profile.caDirUserRenewal.class_id=caEnrollImpl
+profile.caDirUserRenewal.config=[PKI_INSTANCE_PATH]/profiles/ca/caDirUserRenewal.cfg
+profile.caSSLClientSelfRenewal.class_id=caEnrollImpl
+profile.caSSLClientSelfRenewal.config=[PKI_INSTANCE_PATH]/profiles/ca/caSSLClientSelfRenewal.cfg
+profile.DomainController.class_id=caEnrollImpl
+profile.DomainController.config=[PKI_INSTANCE_PATH]/profiles/ca/DomainController.cfg
+profile.caAgentFileSigning.class_id=caEnrollImpl
+profile.caAgentFileSigning.config=[PKI_INSTANCE_PATH]/profiles/ca/caAgentFileSigning.cfg
+profile.caAgentServerCert.class_id=caEnrollImpl
+profile.caAgentServerCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caAgentServerCert.cfg
+profile.caRAserverCert.class_id=caEnrollImpl
+profile.caRAserverCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caRAserverCert.cfg
+profile.caCACert.class_id=caEnrollImpl
+profile.caCACert.config=[PKI_INSTANCE_PATH]/profiles/ca/caCACert.cfg
+profile.caInstallCACert.class_id=caEnrollImpl
+profile.caInstallCACert.config=[PKI_INSTANCE_PATH]/profiles/ca/caInstallCACert.cfg
+profile.caCMCUserCert.class_id=caEnrollImpl
+profile.caCMCUserCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caCMCUserCert.cfg
+profile.caDirUserCert.class_id=caEnrollImpl
+profile.caDirUserCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caDirUserCert.cfg
+profile.caDualCert.class_id=caEnrollImpl
+profile.caDualCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caDualCert.cfg
+profile.caECDualCert.class_id=caEnrollImpl
+profile.caECDualCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caECDualCert.cfg
+profile.caDualRAuserCert.class_id=caEnrollImpl
+profile.caDualRAuserCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caDualRAuserCert.cfg
+profile.caRAagentCert.class_id=caEnrollImpl
+profile.caRAagentCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caRAagentCert.cfg
+profile.caFullCMCUserCert.class_id=caEnrollImpl
+profile.caFullCMCUserCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caFullCMCUserCert.cfg
+profile.caInternalAuthOCSPCert.class_id=caEnrollImpl
+profile.caInternalAuthOCSPCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caInternalAuthOCSPCert.cfg
+profile.caInternalAuthAuditSigningCert.class_id=caEnrollImpl
+profile.caInternalAuthAuditSigningCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caInternalAuthAuditSigningCert.cfg
+profile.caInternalAuthServerCert.class_id=caEnrollImpl
+profile.caInternalAuthServerCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caInternalAuthServerCert.cfg
+profile.caInternalAuthSubsystemCert.class_id=caEnrollImpl
+profile.caInternalAuthSubsystemCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caInternalAuthSubsystemCert.cfg
+profile.caInternalAuthDRMstorageCert.class_id=caEnrollImpl
+profile.caInternalAuthDRMstorageCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caInternalAuthDRMstorageCert.cfg
+profile.caInternalAuthTransportCert.class_id=caEnrollImpl
+profile.caInternalAuthTransportCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caInternalAuthTransportCert.cfg
+profile.caOCSPCert.class_id=caEnrollImpl
+profile.caOCSPCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caOCSPCert.cfg
+profile.caOtherCert.class_id=caEnrollImpl
+profile.caOtherCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caOtherCert.cfg
+profile.caRACert.class_id=caEnrollImpl
+profile.caRACert.config=[PKI_INSTANCE_PATH]/profiles/ca/caRACert.cfg
+profile.caRARouterCert.class_id=caEnrollImpl
+profile.caRARouterCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caRARouterCert.cfg
+profile.caRouterCert.class_id=caEnrollImpl
+profile.caRouterCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caRouterCert.cfg
+profile.caServerCert.class_id=caEnrollImpl
+profile.caServerCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caServerCert.cfg
+profile.caSignedLogCert.class_id=caEnrollImpl
+profile.caSignedLogCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caSignedLogCert.cfg
+profile.caSimpleCMCUserCert.class_id=caEnrollImpl
+profile.caSimpleCMCUserCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caSimpleCMCUserCert.cfg
+profile.caTPSCert.class_id=caEnrollImpl
+profile.caTPSCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caTPSCert.cfg
+profile.caAdminCert.class_id=caEnrollImpl
+profile.caAdminCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caAdminCert.cfg
+profile.caTempTokenDeviceKeyEnrollment.class_id=caUserCertEnrollImpl
+profile.caTempTokenDeviceKeyEnrollment.config=[PKI_INSTANCE_PATH]/profiles/ca/caTempTokenDeviceKeyEnrollment.cfg
+profile.caTempTokenUserEncryptionKeyEnrollment.class_id=caUserCertEnrollImpl
+profile.caTempTokenUserEncryptionKeyEnrollment.config=[PKI_INSTANCE_PATH]/profiles/ca/caTempTokenUserEncryptionKeyEnrollment.cfg
+profile.caTokenUserEncryptionKeyRenewal.class_id=caUserCertEnrollImpl
+profile.caTokenUserEncryptionKeyRenewal.config=[PKI_INSTANCE_PATH]/profiles/ca/caTokenUserEncryptionKeyRenewal.cfg
+profile.caTempTokenUserSigningKeyEnrollment.class_id=caUserCertEnrollImpl
+profile.caTempTokenUserSigningKeyEnrollment.config=[PKI_INSTANCE_PATH]/profiles/ca/caTempTokenUserSigningKeyEnrollment.cfg
+profile.caTokenUserSigningKeyRenewal.class_id=caUserCertEnrollImpl
+profile.caTokenUserSigningKeyRenewal.config=[PKI_INSTANCE_PATH]/profiles/ca/caTokenUserSigningKeyRenewal.cfg
+profile.caTokenDeviceKeyEnrollment.class_id=caUserCertEnrollImpl
+profile.caTokenDeviceKeyEnrollment.config=[PKI_INSTANCE_PATH]/profiles/ca/caTokenDeviceKeyEnrollment.cfg
+profile.caTokenUserEncryptionKeyEnrollment.class_id=caUserCertEnrollImpl
+profile.caTokenUserEncryptionKeyEnrollment.config=[PKI_INSTANCE_PATH]/profiles/ca/caTokenUserEncryptionKeyEnrollment.cfg
+profile.caTokenUserSigningKeyEnrollment.class_id=caUserCertEnrollImpl
+profile.caTokenUserSigningKeyEnrollment.config=[PKI_INSTANCE_PATH]/profiles/ca/caTokenUserSigningKeyEnrollment.cfg
+profile.caTokenMSLoginEnrollment.class_id=caUserCertEnrollImpl
+profile.caTokenMSLoginEnrollment.config=[PKI_INSTANCE_PATH]/profiles/ca/caTokenMSLoginEnrollment.cfg
+profile.caTransportCert.class_id=caEnrollImpl
+profile.caTransportCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caTransportCert.cfg
+profile.caUserCert.class_id=caEnrollImpl
+profile.caUserCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caUserCert.cfg
+profile.caECUserCert.class_id=caEnrollImpl
+profile.caECUserCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caECUserCert.cfg
+profile.caUserSMIMEcapCert.class_id=caEnrollImpl
+profile.caUserSMIMEcapCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caUserSMIMEcapCert.cfg
+profile.caJarSigningCert.class_id=caEnrollImpl
+profile.caJarSigningCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caJarSigningCert.cfg
+profile.caIPAserviceCert.class_id=caEnrollImpl
+profile.caIPAserviceCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caIPAserviceCert.cfg
+profile.caEncUserCert.class_id=caEnrollImpl
+profile.caEncUserCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caEncUserCert.cfg
+profile.caEncECUserCert.class_id=caEnrollImpl
+profile.caEncECUserCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caEncECUserCert.cfg
+registry.file=[PKI_INSTANCE_PATH]/conf/registry.cfg
+request.assignee.enable=true
+selftests._000=##
+selftests._001=## Self Tests
+selftests._002=##
+selftests._003=## The Self-Test plugin SystemCertsVerification uses the
+selftests._004=## following parameters (where certusage is optional):
+selftests._005=## ca.cert.list = <list of cert tag names deliminated by ",">
+selftests._006=## ca.cert.<cert tag name>.nickname
+selftests._007=## ca.cert.<cert tag name>.certusage
+selftests._008=##
+selftests.container.instance.CAPresence=com.netscape.cms.selftests.ca.CAPresence
+selftests.container.instance.CAValidity=com.netscape.cms.selftests.ca.CAValidity
+selftests.container.instance.SystemCertsVerification=com.netscape.cms.selftests.common.SystemCertsVerification
+selftests.container.logger.bufferSize=512
+selftests.container.logger.class=com.netscape.cms.logging.RollingLogFile
+selftests.container.logger.enable=true
+selftests.container.logger.expirationTime=0
+selftests.container.logger.fileName=[PKI_INSTANCE_PATH]/logs/selftests.log
+selftests.container.logger.flushInterval=5
+selftests.container.logger.level=1
+selftests.container.logger.maxFileSize=2000
+selftests.container.logger.register=false
+selftests.container.logger.rolloverInterval=2592000
+selftests.container.logger.type=transaction
+selftests.container.order.onDemand=CAPresence:critical, SystemCertsVerification:critical, CAValidity:critical
+selftests.container.order.startup=CAPresence:critical, SystemCertsVerification:critical
+selftests.plugin.CAPresence.CaSubId=ca
+selftests.plugin.CAValidity.CaSubId=ca
+selftests.plugin.SystemCertsVerification.SubId=ca
+smtp.host=localhost
+smtp.port=25
+subsystem.0.class=com.netscape.ca.CertificateAuthority
+subsystem.0.id=ca
+subsystem.1.class=com.netscape.cmscore.profile.ProfileSubsystem
+subsystem.1.id=profile
+subsystem.2.class=com.netscape.cmscore.selftests.SelfTestSubsystem
+subsystem.2.id=selftests
+subsystem.3.class=com.netscape.cmscore.cert.CrossCertPairSubsystem
+subsystem.3.id=CrossCertPair
+subsystem.4.class=com.netscape.cmscore.util.StatsSubsystem
+subsystem.4.id=stats
+usrgrp._000=##
+usrgrp._001=## User/Group
+usrgrp._002=##
+usrgrp.ldap=internaldb
+multiroles._000=##
+multiroles._001=## multiroles
+multiroles._002=##
+multiroles.enable=true
+multiroles.false.groupEnforceList=Administrators,Auditors,Trusted Managers,Certificate Manager Agents,Registration Manager Agents,Data Recovery Manager Agents,Online Certificate Status Manager Agents,Token Key Service Manager Agents,Enterprise CA Administrators,Enterprise KRA Administrators,Enterprise OCSP Administrators,Enterprise RA Administrators,Enterprise TKS Administrators,Enterprise TPS Administrators,Security Domain Administrators,Subsystem Group,ClonedSubsystems
diff --git a/base/ca/shared/conf/acl.ldif b/base/ca/shared/conf/acl.ldif
new file mode 100644
index 000000000..ceea1f27a
--- /dev/null
+++ b/base/ca/shared/conf/acl.ldif
@@ -0,0 +1,53 @@
+dn: cn=aclResources,{rootSuffix}
+objectClass: top
+objectClass: CertACLS
+cn: aclResources
+resourceACLS: certServer.general.configuration:read,modify,delete:allow (read) group="Administrators" || group="Auditors" || group="Certificate Manager Agents" || group="Registration Manager Agents";allow (modify,delete) group="Administrators":Administrators, auditors, and agents are allowed to read CMS general configuration but only administrators are allowed to modify and delete
+resourceACLS: certServer.policy.configuration:read,modify:allow (read) group="Administrators" || group="Certificate Manager Agents" || group="Registration Manager Agents" || group="Auditors";allow (modify) group="Administrators":Administrators, agents and auditors are allowed to read policy configuration but only administrators allowed to modify
+resourceACLS: certServer.acl.configuration:read,modify:allow (read) group="Administrators" || group="Certificate Manager Agents" || group="Registration Manager Agents" || group="Auditors";allow (modify) group="Administrators":Administrators, agents and auditors are allowed to read ACL configuration but only administrators allowed to modify
+resourceACLS: certServer.log.configuration:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Certificate Manager Agents" || group="Registration Manager Agents";allow (modify) group="Administrators":Administrators, Agents, and auditors are allowed to read the log configuration but only administrators are allowed to modify
+resourceACLS: certServer.securitydomain.domainxml:read,modify:allow (read) user="anybody";allow (modify) group="Subsystem Group":Anybody is allowed to read domain.xml but only Subsystem group is allowed to modify the domain.xml
+resourceACLS: certServer.log.configuration.fileName:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Certificate Manager Agents" || group="Registration Manager Agents" ;deny (modify) user=anybody:Nobody is allowed to modify a fileName parameter
+#resourceACLS: certServer.log.configuration.signedAudit.expirationTime:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Certificate Manager Agents" || group="Registration Manager Agents";deny (modify) user=anybody:Nobody is allowed to modify an expirationTime parameter.
+resourceACLS: certServer.log.content.signedAudit:read:allow (read) group="Auditors":Only auditor is allowed to read the signed audit log
+resourceACLS: certServer.log.content.system:read:allow (read) group="Administrators" || group="Certificate Manager Agents" || group="Registration Manager Agents" || group="Auditors":Administrators, auditors, and agents are allowed to read the log content
+resourceACLS: certServer.log.content.transactions:read:allow (read) group="Administrators" || group="Certificate Manager Agents" || group="Registration Manager Agents" || group="Auditors":Administrators, auditors, and agents are allowed to read the log content
+resourceACLS: certServer.ca.configuration:read,modify:allow (read) group="Administrators" || group="Certificate Manager Agents" || group="Registration Manager Agents" || group="Auditors";allow (modify) group="Administrators":Administrators, auditors, and agents are allowed to read CA configuration but only administrators allowed to modify
+resourceACLS: certServer.auth.configuration:read,modify:allow (read) group="Administrators" || group="Certificate Manager Agents" || group="Registration Manager Agents" || group="Auditors";allow (modify) group="Administrators":Administrators, agents, and auditors are allowed to read authentication configuration but only administrators allowed to modify
+resourceACLS: certServer.ocsp.configuration:read,modify:allow (read) group="Administrators" || group="Certificate Manager Agents" || group="Registration Manager Agents" || group="Auditors";allow (modify) group="Administrators":Administrators, Agents, and auditors are allowed to read ocsp configuration but only administrators allowed to modify
+resourceACLS: certServer.registry.configuration:read,modify:allow (read) group="Administrators" || group="Certificate Manager Agents" || group="Registration Manager Agents" || group="Auditors";allow (modify) group="Administrators":this acl is shared by all admin servlets
+resourceACLS: certServer.profile.configuration:read,modify:allow (read) group="Administrators" || group="Certificate Manager Agents" || group="Registration Manager Agents" || group="Auditors";allow (modify) group="Administrators":Administrators, agents, and auditors are allowed to read profile configuration but only administrators allowed to modify
+resourceACLS: certServer.job.configuration:read,modify:allow (read) group="Administrators" || group="Certificate Manager Agents" || group="Registration Manager Agents" || group="Auditors";allow (modify) group="Administrators":Administrators, agents, and auditors are allowed to read job configuration but only administrators allowed to modify
+resourceACLS: certServer.publisher.configuration:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Certificate Manager Agents" || group="Registration Manager Agents";allow (modify) group="Administrators":Administrators, auditors, and agents are allowed to read publisher configuration but only administrators allowed to modify
+resourceACLS: certServer.kra.configuration:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Certificate Manager Agents" || group="Registration Manager Agents";allow (modify) group="Administrators":Administrators, auditors, and agents are allowed to read DRM configuration but only administrators allowed to modify
+resourceACLS: certServer.ra.configuration:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Certificate Manager Agents" || group="Registration Manager Agents";allow (modify) group="Administrators":Administrators, auditors, and agents are allowed to read RA configuration but only administrators allowed to modify
+resourceACLS: certServer.ca.directory:update:allow (update) group="Certificate Manager Agents":Certificate Manager agents may update directory
+resourceACLS: certServer.ca.certificate:import,unrevoke,revoke,read:allow (import,unrevoke,revoke,read) group="Certificate Manager Agents":Certificate Manager agents may import,unrevoke,revoke,read a certificate
+resourceACLS: certServer.ca.certificates:revoke,list:allow (revoke,list) group="Certificate Manager Agents"|| group="Registration Manager Agents":Only certificate and registration manager agents revoke, list certificates
+resourceACLS: certServer.ca.requests:list:allow (list) group="Certificate Manager Agents"|| group="Registration Manager Agents":Only certificate and registration manager agents list requests
+resourceACLS: certServer.ca.request.enrollment:submit,read,execute,assign,unassign:allow (submit) user="anybody";allow (read,execute,assign,unassign) group="Certificate Manager Agents":Anybody may submit an enrollment request, Certificate Manager Agents may read,execute,assign or unassign request
+resourceACLS: certServer.ca.ocsp:read:allow (read) group="Certificate Manager Agents":Certificate Manager agents may read ocsp information
+resourceACLS: certServer.ee.request.ocsp:submit:allow (submit) ipaddress=".*":Any clients can submit ocsp requests
+resourceACLS: certServer.ca.crl:read,update:allow (read,update) group="Certificate Manager Agents":Certificate Manager agents may read or update crl
+resourceACLS: certServer.ee.certificate:renew,revoke,read,import:allow (renew,revoke,read,import) user="anybody":Anybody may renew,import,revoke,read a certificate
+resourceACLS: certServer.ee.certificates:revoke,list:allow (revoke,list) user="anybody":Anybody may revoke, list certificates
+resourceACLS: certServer.ee.certchain:download,read:allow (download,read) user="anybody":Anybody may download a certificate chain
+resourceACLS: certServer.ee.crl:read,add:allow (read,add) user="anybody":Anybody may add or retrieve CRL
+resourceACLS: certServer.ee.request.enrollment:submit:allow (submit) user="anybody":Anybody may submit an enrollment request
+resourceACLS: certServer.ee.requestStatus:read:allow (read) user="anybody":Anybody may read request status
+resourceACLS: certServer.ee.request.revocation:submit:allow (submit) user="anybody":Anybody may submit a revocation request
+resourceACLS: certServer.admin.certificate:import:allow (import) user="anybody":Any user may import a certificate
+resourceACLS: certServer.admin.request.enrollment:submit,read,execute:allow (submit) user="anybody";allow (read,execute) group="Certificate Manager Agents":Anybody may submit an enrollment request, Certificate Manager Agents may read or execute request
+resourceACLS: certServer.ca.request.profile:approve,read:allow (approve,read) group="Certificate Manager Agents":Certificate Manager agents may approve profile
+resourceACLS: certServer.ca.profiles:list:allow (list) group="Certificate Manager Agents":Certificate Manager agents may list profiles
+resourceACLS: certServer.ca.profile:read,approve:allow (read,approve) group="Certificate Manager Agents":Certificate Manager agents may read profile
+resourceACLS: certServer.ee.profile:submit,read:allow (submit,read) user="anybody":Anybody may submit certificate profiles
+resourceACLS: certServer.ee.profiles:list:allow (list) user="anybody":Anybody may list certificate profiles
+resourceACLS: certServer.ca.connector:submit:allow (submit) group="Trusted Managers":Only Trusted Managers submit requests
+resourceACLS: certServer.ca.clone:submit:allow (submit) group="Certificate Manager Agents":Certificate Manager Agents are allowed to submit request to the master CA
+resourceACLS: certServer.ca.systemstatus:read:allow (read) group="Certificate Manager Agents":Certificate Manager agents may view statistics
+resourceACLS: certServer.ca.group:read,modify:allow (modify,read) group="Administrators":Only administrators are allowed to read and modify users and groups
+resourceACLS: certServer.ca.connectorInfo:read,modify:allow (modify,read) group="Enterprise KRA Administrators":Only Enterprise Administrators are allowed to update the connector information
+resourceACLS: certServer.ca.registerUser:read,modify:allow (modify,read) group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise RA Administrators" || group="Enterprise OCSP Administrators" || group="Enterprise TKS Administrators" || group="Enterprise TPS Administrators":Only Enterprise Administrators are allowed to register a new agent
+resourceACLS: certServer.clone.configuration:read,modify:allow (modify,read) group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise RA Administrators" || group="Enterprise OCSP Administrators" || group="Enterprise TKS Administrators":Only Enterprise Administrators are allowed to clone the configuration.
+resourceACLS: certServer.admin.ocsp:read,modify:allow (modify,read) group="Enterprise OCSP Administrators":Only Enterprise Administrators are allowed to read or update the OCSP configuration.
diff --git a/base/ca/shared/conf/adminCert.profile b/base/ca/shared/conf/adminCert.profile
new file mode 100644
index 000000000..5e84d7492
--- /dev/null
+++ b/base/ca/shared/conf/adminCert.profile
@@ -0,0 +1,39 @@
+#
+# Server Certificate
+#
+id=adminCert.profile
+name=All Purpose admin server cert Profile
+description=This profile creates an administrator's certificate
+profileIDMapping=caAdminCert
+profileSetIDMapping=adminCertSet
+list=2,4,5,6,7
+2.default.class=com.netscape.cms.profile.def.ValidityDefault
+2.default.name=Validity Default
+2.default.params.range=720
+2.default.params.startTime=0
+4.default.class=com.netscape.cms.profile.def.AuthorityKeyIdentifierExtDefault
+4.default.name=Authority Key Identifier Default
+5.default.class=com.netscape.cms.profile.def.AuthInfoAccessExtDefault
+5.default.name=AIA Extension Default
+5.default.params.authInfoAccessADEnable_0=true
+5.default.params.authInfoAccessADLocationType_0=URIName
+5.default.params.authInfoAccessADLocation_0=
+5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+5.default.params.authInfoAccessCritical=false
+5.default.params.authInfoAccessNumADs=1
+6.default.class=com.netscape.cms.profile.def.KeyUsageExtDefault
+6.default.name=Key Usage Default
+6.default.params.keyUsageCritical=true
+6.default.params.keyUsageDigitalSignature=true
+6.default.params.keyUsageNonRepudiation=true
+6.default.params.keyUsageDataEncipherment=true
+6.default.params.keyUsageKeyEncipherment=true
+6.default.params.keyUsageKeyAgreement=false
+6.default.params.keyUsageKeyCertSign=false
+6.default.params.keyUsageCrlSign=false
+6.default.params.keyUsageEncipherOnly=false
+6.default.params.keyUsageDecipherOnly=false
+7.default.class=com.netscape.cms.profile.def.ExtendedKeyUsageExtDefault
+7.default.name=Extended Key Usage Extension Default
+7.default.params.exKeyUsageCritical=false
+7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
diff --git a/base/ca/shared/conf/caAuditSigningCert.profile b/base/ca/shared/conf/caAuditSigningCert.profile
new file mode 100644
index 000000000..5983a186c
--- /dev/null
+++ b/base/ca/shared/conf/caAuditSigningCert.profile
@@ -0,0 +1,35 @@
+#
+# CA Audit Signing Cert Profile
+#
+id=caAuditSigningCert.profile
+name=CA Audit Signing Certificate Profile
+description=This profile creates a CA Audit signing certificate that is valid for audit log signing purpose.
+profileIDMapping=caSignedLogCert
+profileSetIDMapping=caLogSigningSet
+list=2,4,6,8
+2.default.class=com.netscape.cms.profile.def.ValidityDefault
+2.default.name=Validity Default
+2.default.params.range=720
+2.default.params.startTime=0
+4.default.class=com.netscape.cms.profile.def.AuthorityKeyIdentifierExtDefault
+4.default.name=Authority Key Identifier Default
+6.default.class=com.netscape.cms.profile.def.KeyUsageExtDefault
+6.default.name=Key Usage Default
+6.default.params.keyUsageCritical=true
+6.default.params.keyUsageDigitalSignature=true
+6.default.params.keyUsageNonRepudiation=true
+6.default.params.keyUsageDataEncipherment=false
+6.default.params.keyUsageKeyEncipherment=false
+6.default.params.keyUsageKeyAgreement=false
+6.default.params.keyUsageKeyCertSign=false
+6.default.params.keyUsageCrlSign=false
+6.default.params.keyUsageEncipherOnly=false
+6.default.params.keyUsageDecipherOnly=false
+8.default.class=com.netscape.cms.profile.def.AuthInfoAccessExtDefault
+8.default.name=AIA Extension Default
+8.default.params.authInfoAccessADEnable_0=true
+8.default.params.authInfoAccessADLocationType_0=URIName
+8.default.params.authInfoAccessADLocation_0=
+8.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+8.default.params.authInfoAccessCritical=false
+8.default.params.authInfoAccessNumADs=1
diff --git a/base/ca/shared/conf/caCert.profile b/base/ca/shared/conf/caCert.profile
new file mode 100644
index 000000000..3e9c83613
--- /dev/null
+++ b/base/ca/shared/conf/caCert.profile
@@ -0,0 +1,44 @@
+#
+# CA Profile
+#
+id=caCert.profile
+name=All Purpose CA Profile
+description=This profile creates a CA certificate that is valid for all signing purposes.
+profileIDMapping=caCACert
+profileSetIDMapping=caCertSet
+list=2,4,5,6,7,8
+2.default.class=com.netscape.cms.profile.def.CAValidityDefault
+2.default.name=CA Certificate Validity Default
+2.default.params.range=2922
+2.default.params.startTime=0
+4.default.class=com.netscape.cms.profile.def.AuthorityKeyIdentifierExtDefault
+4.default.name=Authority Key Identifier Default
+4.default.params.localKey=true
+5.default.class=com.netscape.cms.profile.def.BasicConstraintsExtDefault
+5.default.name=Basic Constraints Extension Default
+5.default.params.basicConstraintsCritical=true
+5.default.params.basicConstraintsIsCA=true
+5.default.params.basicConstraintsPathLen=-1
+6.default.class=com.netscape.cms.profile.def.KeyUsageExtDefault
+6.default.name=Key Usage Default
+6.default.params.keyUsageCritical=true
+6.default.params.keyUsageDigitalSignature=true
+6.default.params.keyUsageNonRepudiation=true
+6.default.params.keyUsageDataEncipherment=false
+6.default.params.keyUsageKeyEncipherment=false
+6.default.params.keyUsageKeyAgreement=false
+6.default.params.keyUsageKeyCertSign=true
+6.default.params.keyUsageCrlSign=true
+6.default.params.keyUsageEncipherOnly=false
+6.default.params.keyUsageDecipherOnly=false
+7.default.class=com.netscape.cms.profile.def.SubjectKeyIdentifierExtDefault
+7.default.name=Subject Key Identifier Extension Default
+7.default.params.critical=false
+8.default.class=com.netscape.cms.profile.def.AuthInfoAccessExtDefault
+8.default.name=AIA Extension Default
+8.default.params.authInfoAccessADEnable_0=true
+8.default.params.authInfoAccessADLocationType_0=URIName
+8.default.params.authInfoAccessADLocation_0=
+8.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+8.default.params.authInfoAccessCritical=false
+8.default.params.authInfoAccessNumADs=1
diff --git a/base/ca/shared/conf/caOCSPCert.profile b/base/ca/shared/conf/caOCSPCert.profile
new file mode 100644
index 000000000..b3c27c1b0
--- /dev/null
+++ b/base/ca/shared/conf/caOCSPCert.profile
@@ -0,0 +1,42 @@
+#
+# OCSP CA Profile
+#
+id=caOCSPCert.profile
+name=All Purpose CA OCSP Profile
+description=This profile creates a CA OCSP certificate that is valid for all signing purposes.
+profileIDMapping=caOCSPCert
+profileSetIDMapping=ocspCertSet
+list=2,4,6,8,9
+2.default.class=com.netscape.cms.profile.def.ValidityDefault
+2.default.name=Validity Default
+2.default.params.range=720
+2.default.params.startTime=0
+4.default.class=com.netscape.cms.profile.def.AuthorityKeyIdentifierExtDefault
+4.default.name=Authority Key Identifier Default
+6.default.class=com.netscape.cms.profile.def.KeyUsageExtDefault
+6.default.name=Key Usage Default
+6.default.params.keyUsageCritical=true
+6.default.params.keyUsageDigitalSignature=true
+6.default.params.keyUsageNonRepudiation=true
+6.default.params.keyUsageDataEncipherment=false
+6.default.params.keyUsageKeyEncipherment=false
+6.default.params.keyUsageKeyAgreement=false
+6.default.params.keyUsageKeyCertSign=true
+6.default.params.keyUsageCrlSign=true
+6.default.params.keyUsageEncipherOnly=false
+6.default.params.keyUsageDecipherOnly=false
+7.default.class=com.netscape.cms.profile.def.SubjectKeyIdentifierExtDefault
+7.default.name=Subject Key Identifier Extension Default
+7.default.params.critical=false
+8.default.class=com.netscape.cms.profile.def.AuthInfoAccessExtDefault
+8.default.name=AIA Extension Default
+8.default.params.authInfoAccessADEnable_0=true
+8.default.params.authInfoAccessADLocationType_0=URIName
+8.default.params.authInfoAccessADLocation_0=
+8.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+8.default.params.authInfoAccessCritical=false
+8.default.params.authInfoAccessNumADs=1
+9.default.class=com.netscape.cms.profile.def.ExtendedKeyUsageExtDefault
+9.default.name=Extended Key Usage Extension Default
+9.default.params.exKeyUsageCritical=false
+9.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.9
diff --git a/base/ca/shared/conf/catalina.policy b/base/ca/shared/conf/catalina.policy
new file mode 100644
index 000000000..cf8302cd0
--- /dev/null
+++ b/base/ca/shared/conf/catalina.policy
@@ -0,0 +1,184 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// Copyright (C) 2006-2010 Red Hat, Inc.
+// All rights reserved.
+// Modifications: configuration parameters
+// --- END COPYRIGHT BLOCK ---
+
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// ============================================================================
+// catalina.corepolicy - Security Policy Permissions for Tomcat 6
+//
+// This file contains a default set of security policies to be enforced (by the
+// JVM) when Catalina is executed with the "-security" option. In addition
+// to the permissions granted here, the following additional permissions are
+// granted to the codebase specific to each web application:
+//
+// * Read access to the document root directory
+//
+// $Id$
+// ============================================================================
+
+
+// ========== SYSTEM CODE PERMISSIONS =========================================
+
+
+// These permissions apply to javac
+grant codeBase "file:${java.home}/lib/-" {
+ permission java.security.AllPermission;
+};
+
+// These permissions apply to all shared system extensions
+grant codeBase "file:${java.home}/jre/lib/ext/-" {
+ permission java.security.AllPermission;
+};
+
+// These permissions apply to javac when ${java.home] points at $JAVA_HOME/jre
+grant codeBase "file:${java.home}/../lib/-" {
+ permission java.security.AllPermission;
+};
+
+// These permissions apply to all shared system extensions when
+// ${java.home} points at $JAVA_HOME/jre
+grant codeBase "file:${java.home}/lib/ext/-" {
+ permission java.security.AllPermission;
+};
+
+
+// ========== CATALINA CODE PERMISSIONS =======================================
+
+
+// These permissions apply to the daemon code
+grant codeBase "file:${catalina.home}/bin/commons-daemon.jar" {
+ permission java.security.AllPermission;
+};
+
+// These permissions apply to the logging API
+grant codeBase "file:${catalina.home}/bin/tomcat-juli.jar" {
+ permission java.util.PropertyPermission "java.util.logging.config.class", "read";
+ permission java.util.PropertyPermission "java.util.logging.config.file", "read";
+ permission java.io.FilePermission "${java.home}${file.separator}lib${file.separator}logging.properties", "read";
+ permission java.lang.RuntimePermission "shutdownHooks";
+ permission java.io.FilePermission "${catalina.base}${file.separator}conf${file.separator}logging.properties", "read";
+ permission java.util.PropertyPermission "catalina.base", "read";
+ permission java.util.logging.LoggingPermission "control";
+ permission java.io.FilePermission "${catalina.base}${file.separator}logs", "read, write";
+ permission java.io.FilePermission "${catalina.base}${file.separator}logs${file.separator}*", "read, write";
+ permission java.lang.RuntimePermission "getClassLoader";
+ // To enable per context logging configuration, permit read access to the appropriate file.
+ // Be sure that the logging configuration is secure before enabling such access
+ // eg for the examples web application:
+ // permission java.io.FilePermission "${catalina.base}${file.separator}webapps${file.separator}examples${file.separator}WEB-INF${file.separator}classes${file.separator}logging.properties", "read";
+};
+
+// These permissions apply to the server startup code
+grant codeBase "file:${catalina.home}/bin/bootstrap.jar" {
+ permission java.security.AllPermission;
+};
+
+// These permissions apply to the servlet API classes
+// and those that are shared across all class loaders
+// located in the "lib" directory
+grant codeBase "file:${catalina.home}/lib/-" {
+ permission java.security.AllPermission;
+};
+
+
+// ========== WEB APPLICATION PERMISSIONS =====================================
+
+
+// These permissions are granted by default to all web applications
+// In addition, a web application will be given a read FilePermission
+// and JndiPermission for all files and directories in its document root.
+grant {
+ // Required for JNDI lookup of named JDBC DataSource's and
+ // javamail named MimePart DataSource used to send mail
+ permission java.util.PropertyPermission "java.home", "read";
+ permission java.util.PropertyPermission "java.naming.*", "read";
+ permission java.util.PropertyPermission "javax.sql.*", "read";
+
+ // OS Specific properties to allow read access
+ permission java.util.PropertyPermission "os.name", "read";
+ permission java.util.PropertyPermission "os.version", "read";
+ permission java.util.PropertyPermission "os.arch", "read";
+ permission java.util.PropertyPermission "file.separator", "read";
+ permission java.util.PropertyPermission "path.separator", "read";
+ permission java.util.PropertyPermission "line.separator", "read";
+
+ // JVM properties to allow read access
+ permission java.util.PropertyPermission "java.version", "read";
+ permission java.util.PropertyPermission "java.vendor", "read";
+ permission java.util.PropertyPermission "java.vendor.url", "read";
+ permission java.util.PropertyPermission "java.class.version", "read";
+ permission java.util.PropertyPermission "java.specification.version", "read";
+ permission java.util.PropertyPermission "java.specification.vendor", "read";
+ permission java.util.PropertyPermission "java.specification.name", "read";
+
+ permission java.util.PropertyPermission "java.vm.specification.version", "read";
+ permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
+ permission java.util.PropertyPermission "java.vm.specification.name", "read";
+ permission java.util.PropertyPermission "java.vm.version", "read";
+ permission java.util.PropertyPermission "java.vm.vendor", "read";
+ permission java.util.PropertyPermission "java.vm.name", "read";
+
+ // Required for OpenJMX
+ permission java.lang.RuntimePermission "getAttribute";
+
+ // Allow read of JAXP compliant XML parser debug
+ permission java.util.PropertyPermission "jaxp.debug", "read";
+
+ // Precompiled JSPs need access to this package.
+ permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime";
+ permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime.*";
+
+ // Precompiled JSPs need access to this system property.
+ permission java.util.PropertyPermission "org.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER", "read";
+
+};
+
+
+// You can assign additional permissions to particular web applications by
+// adding additional "grant" entries here, based on the code base for that
+// application, /WEB-INF/classes/, or /WEB-INF/lib/ jar files.
+//
+// Different permissions can be granted to JSP pages, classes loaded from
+// the /WEB-INF/classes/ directory, all jar files in the /WEB-INF/lib/
+// directory, or even to individual jar files in the /WEB-INF/lib/ directory.
+//
+// For instance, assume that the standard "examples" application
+// included a JDBC driver that needed to establish a network connection to the
+// corresponding database and used the scrape taglib to get the weather from
+// the NOAA web server. You might create a "grant" entries like this:
+//
+// The permissions granted to the context root directory apply to JSP pages.
+// grant codeBase "file:${catalina.home}/webapps/examples/-" {
+// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
+// permission java.net.SocketPermission "*.noaa.gov:80", "connect";
+// };
+//
+// The permissions granted to the context WEB-INF/classes directory
+// grant codeBase "file:${catalina.home}/webapps/examples/WEB-INF/classes/-" {
+// };
+//
+// The permission granted to your JDBC driver
+// grant codeBase "jar:file:${catalina.home}/webapps/examples/WEB-INF/lib/driver.jar!/-" {
+// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
+// };
+// The permission granted to the scrape taglib
+// grant codeBase "jar:file:${catalina.home}/webapps/examples/WEB-INF/lib/scrape.jar!/-" {
+// permission java.net.SocketPermission "*.noaa.gov:80", "connect";
+// };
+
diff --git a/base/ca/shared/conf/catalina.properties b/base/ca/shared/conf/catalina.properties
new file mode 100644
index 000000000..70cb7c05e
--- /dev/null
+++ b/base/ca/shared/conf/catalina.properties
@@ -0,0 +1,87 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006-2010 Red Hat, Inc.
+# All rights reserved.
+# Modifications: configuration parameters
+# --- END COPYRIGHT BLOCK ---
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# List of comma-separated packages that start with or equal this string
+# will cause a security exception to be thrown when
+# passed to checkPackageAccess unless the
+# corresponding RuntimePermission ("accessClassInPackage."+package) has
+# been granted.
+package.access=sun.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper.,sun.beans.
+#
+# List of comma-separated packages that start with or equal this string
+# will cause a security exception to be thrown when
+# passed to checkPackageDefinition unless the
+# corresponding RuntimePermission ("defineClassInPackage."+package) has
+# been granted.
+#
+# by default, no packages are restricted for definition, and none of
+# the class loaders supplied with the JDK call checkPackageDefinition.
+#
+package.definition=sun.,java.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper.
+
+#
+#
+# List of comma-separated paths defining the contents of the "common"
+# classloader. Prefixes should be used to define what is the repository type.
+# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute.
+# If left as blank,the JVM system loader will be used as Catalina's "common"
+# loader.
+# Examples:
+# "foo": Add this folder as a class repository
+# "foo/*.jar": Add all the JARs of the specified folder as class
+# repositories
+# "foo/bar.jar": Add bar.jar as a class repository
+common.loader=${catalina.home}/lib,${catalina.home}/lib/*.jar,[TOMCAT_INSTANCE_COMMON_LIB]
+
+#
+# List of comma-separated paths defining the contents of the "server"
+# classloader. Prefixes should be used to define what is the repository type.
+# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute.
+# If left as blank, the "common" loader will be used as Catalina's "server"
+# loader.
+# Examples:
+# "foo": Add this folder as a class repository
+# "foo/*.jar": Add all the JARs of the specified folder as class
+# repositories
+# "foo/bar.jar": Add bar.jar as a class repository
+server.loader=
+
+#
+# List of comma-separated paths defining the contents of the "shared"
+# classloader. Prefixes should be used to define what is the repository type.
+# Path may be relative to the CATALINA_BASE path or absolute. If left as blank,
+# the "common" loader will be used as Catalina's "shared" loader.
+# Examples:
+# "foo": Add this folder as a class repository
+# "foo/*.jar": Add all the JARs of the specified folder as class
+# repositories
+# "foo/bar.jar": Add bar.jar as a class repository
+# Please note that for single jars, e.g. bar.jar, you need the URL form
+# starting with file:.
+shared.loader=
+
+#
+# String cache configuration.
+tomcat.util.buf.StringCache.byte.enabled=true
+#tomcat.util.buf.StringCache.char.enabled=true
+#tomcat.util.buf.StringCache.trainThreshold=500000
+#tomcat.util.buf.StringCache.cacheSize=5000
diff --git a/base/ca/shared/conf/context.xml b/base/ca/shared/conf/context.xml
new file mode 100644
index 000000000..8b6fe4905
--- /dev/null
+++ b/base/ca/shared/conf/context.xml
@@ -0,0 +1,40 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2006-2010 Red Hat, Inc.
+ All rights reserved.
+ Modifications: configuration parameters
+ END COPYRIGHT BLOCK -->
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- The contents of this file will be loaded for each web application -->
+<Context crossContext="true" allowLinking="true">
+
+ <!-- Default set of monitored resources -->
+ <WatchedResource>WEB-INF/web.xml</WatchedResource>
+
+ <!-- Uncomment this to disable session persistence across Tomcat restarts -->
+ <!--
+ <Manager pathname="" />
+ -->
+
+ <!-- Uncomment this to enable Comet connection tacking (provides events
+ on session expiration as well as webapp lifecycle) -->
+ <!--
+ <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
+ -->
+
+</Context>
diff --git a/base/ca/shared/conf/database.ldif b/base/ca/shared/conf/database.ldif
new file mode 100644
index 000000000..4dfdcea69
--- /dev/null
+++ b/base/ca/shared/conf/database.ldif
@@ -0,0 +1,4 @@
+dn: cn=config
+changetype: modify
+replace: nsslapd-maxbersize
+nsslapd-maxbersize: 209715200
diff --git a/base/ca/shared/conf/db.ldif b/base/ca/shared/conf/db.ldif
new file mode 100644
index 000000000..00fa919b7
--- /dev/null
+++ b/base/ca/shared/conf/db.ldif
@@ -0,0 +1,163 @@
+dn: ou=people,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: people
+aci: (targetattr!="userPassword")(version 3.0; acl "Enable anonymous access"; allow (read, search, compare)userdn="ldap:///anyone";)
+
+dn: ou=groups,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: groups
+
+dn: cn=Certificate Manager Agents,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Certificate Manager Agents
+description: Agents for Certificate Manager
+
+dn: cn=Registration Manager Agents,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Registration Manager Agents
+description: Agents for Registration Manager
+
+dn: cn=Subsystem Group, ou=groups, {rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Subsystem Group
+description: Subsystem Group
+
+dn: cn=Trusted Managers,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Trusted Managers
+description: Managers trusted by this PKI instance
+
+dn: cn=Administrators,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Administrators
+description: People who manage the Certificate System
+
+dn: cn=Auditors,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Auditors
+description: People who can read the signed audits
+
+dn: cn=ClonedSubsystems,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: ClonedSubsystems
+description: People who can clone the master subsystem
+
+dn: cn=Security Domain Administrators,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Security Domain Administrators
+description: People who are the Security Domain administrators
+
+dn: cn=Enterprise CA Administrators,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Enterprise CA Administrators
+description: People who are the administrators for the security domain for CA
+
+dn: cn=Enterprise KRA Administrators,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Enterprise KRA Administrators
+description: People who are the administrators for the security domain for KRA
+
+dn: cn=Enterprise OCSP Administrators,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Enterprise OCSP Administrators
+description: People who are the administrators for the security domain for OCSP
+
+dn: cn=Enterprise TKS Administrators,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Enterprise TKS Administrators
+description: People who are the administrators for the security domain for TKS
+
+dn: cn=Enterprise RA Administrators,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Enterprise RA Administrators
+description: People who are the administrators for the security domain for RA
+
+dn: cn=Enterprise TPS Administrators,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Enterprise TPS Administrators
+description: People who are the administrators for the security domain for TPS
+
+dn: ou=requests,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: requests
+
+dn: cn=crossCerts,{rootSuffix}
+cn: crossCerts
+sn: crossCerts
+objectClass: top
+objectClass: person
+objectClass: pkiCA
+cACertificate;binary:
+authorityRevocationList;binary:
+certificateRevocationList;binary:
+crossCertificatePair;binary:
+
+dn: ou=ca,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: ca
+
+dn: ou=certificateRepository,ou=ca,{rootSuffix}
+objectClass: top
+objectClass: repository
+ou: certificateRepository
+serialno: 011
+
+dn: ou=crlIssuingPoints,ou=ca,{rootSuffix}
+objectClass: top
+objectClass: repository
+ou: crlIssuingPoints
+serialno: 010
+
+dn: ou=ca, ou=requests,{rootSuffix}
+objectClass: top
+objectClass: repository
+ou: ca
+serialno: 010
+publishingStatus: -2
+
+dn: ou=replica,{rootSuffix}
+objectClass: top
+objectClass: repository
+ou: replica
+serialno: 010
+nextRange: 1000
+
+dn: ou=ranges,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: ranges
+
+dn: ou=replica, ou=ranges,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: replica
+
+dn: ou=requests, ou=ranges,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: requests
+
+dn: ou=certificateRepository, ou=ranges,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: certificateRepository
+
+
diff --git a/base/ca/shared/conf/flatfile.txt b/base/ca/shared/conf/flatfile.txt
new file mode 100644
index 000000000..75defd1da
--- /dev/null
+++ b/base/ca/shared/conf/flatfile.txt
@@ -0,0 +1,2 @@
+#UID:172.16.24.238
+#PWD:1212
diff --git a/base/ca/shared/conf/index.ldif b/base/ca/shared/conf/index.ldif
new file mode 100644
index 000000000..4bc8aebf9
--- /dev/null
+++ b/base/ca/shared/conf/index.ldif
@@ -0,0 +1,198 @@
+dn: cn=revokedby,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: revokedby
+
+dn: cn=issuedby,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: issuedby
+
+dn: cn=publicKeyData,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: publicKeyData
+
+dn: cn=clientId,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: clientId
+
+dn: cn=dataType,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: dataType
+
+dn: cn=status,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: status
+
+dn: cn=description,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: description
+
+dn: cn=serialno,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: serialno
+
+dn: cn=metaInfo,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: metaInfo
+
+dn: cn=certstatus,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: certstatus
+
+dn: cn=requestid,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: requestid
+
+dn: cn=requesttype,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: requesttype
+
+dn: cn=requeststate,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: requeststate
+
+dn: cn=requestowner,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: requestowner
+
+dn: cn=notbefore,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: notbefore
+
+dn: cn=notafter,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: notafter
+
+dn: cn=duration,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: duration
+
+dn: cn=dateOfCreate,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: dateOfCreate
+
+dn: cn=revokedOn,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: revokedOn
+
+dn: cn=archivedBy,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: archivedBy
+
+dn: cn=ownername,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsIndexType: sub
+nsSystemIndex: false
+cn: ownername
+
+dn: cn=subjectname,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsIndexType: sub
+nsSystemIndex: false
+cn: subjectname
+
+dn: cn=requestsourceid,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsIndexType: sub
+nsSystemIndex: false
+cn: requestsourceid
+
+dn: cn=revInfo,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsIndexType: sub
+nsSystemIndex: false
+cn: revInfo
+
+dn: cn=extension,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsIndexType: sub
+nsSystemIndex: false
+cn: extension
diff --git a/base/ca/shared/conf/jk2.manifest b/base/ca/shared/conf/jk2.manifest
new file mode 100644
index 000000000..986d7b874
--- /dev/null
+++ b/base/ca/shared/conf/jk2.manifest
@@ -0,0 +1,2 @@
+Main-Class: org.apache.jk.apr.TomcatStarter
+Class-Path: ../lib/tomcat.jar log4j.jar log4j-core.jar ../lib/common/log4j.jar ../lib/common/log4j-core.jar ../lib/common/classes ../lib/common/commons-logging.jar bootstrap.jar ../server/lib/commons-logging.jar ../server/lib/jmx.jar jmx.jar commons-logging-api.jar
diff --git a/base/ca/shared/conf/jk2.properties b/base/ca/shared/conf/jk2.properties
new file mode 100644
index 000000000..093bae802
--- /dev/null
+++ b/base/ca/shared/conf/jk2.properties
@@ -0,0 +1,26 @@
+## THIS FILE MAY BE OVERRIDEN AT RUNTIME. MAKE SURE TOMCAT IS STOPED
+## WHEN YOU EDIT THE FILE.
+
+## COMMENTS WILL BE _LOST_
+
+## DOCUMENTATION OF THE FORMAT IN JkMain javadoc.
+
+# Set the desired handler list
+# handler.list=apr,request,channelJni
+#
+# Override the default port for the socketChannel
+# channelSocket.port=8019
+# Default:
+# channelUnix.file=${jkHome}/work/jk2.socket
+# Just to check if the the config is working
+# shm.file=${jkHome}/work/jk2.shm
+
+# In order to enable jni use any channelJni directive
+# channelJni.disabled = 0
+# And one of the following directives:
+
+# apr.jniModeSo=/opt/apache2/modules/mod_jk2.so
+
+# If set to inprocess the mod_jk2 will Register natives itself
+# This will enable the starting of the Tomcat from mod_jk2
+# apr.jniModeSo=inprocess
diff --git a/base/ca/shared/conf/jkconf.ant.xml b/base/ca/shared/conf/jkconf.ant.xml
new file mode 100644
index 000000000..245cf98e2
--- /dev/null
+++ b/base/ca/shared/conf/jkconf.ant.xml
@@ -0,0 +1,51 @@
+<project name="jkconf" default="main" basedir=".">
+
+ <target name="init-3x" if="33.detect">
+ <taskdef name="jkconf"
+ classname="org.apache.jk.config.WebXml2Jk" >
+ <classpath>
+ <!-- 3.3 support -->
+ <pathelement location="/ws/jtc/jk/build/classes" />
+ <pathelement location="${tomcat.home}/lib/container/tomcat-jk2.jar" />
+ <pathelement location="${tomcat.home}/lib/container/crimson.jar"/>
+ <pathelement location="${tomcat.home}/lib/common/commons-logging.jar"/>
+ </classpath>
+ </taskdef>
+ </target>
+
+ <target name="init-4x" if="4x.detect" >
+ <path id="main.classpath">
+ <!-- 3.3 support -->
+ <fileset dir="${tomcat.home}/lib" includes="*.jar" />
+ <fileset dir="${tomcat.home}/server/lib" includes="*.jar" />
+ <fileset dir="${tomcat.home}/common/lib" includes="*.jar" />
+ </path>
+
+ <taskdef name="jkconf" classpathref="main.classpath"
+ classname="org.apache.jk.config.WebXml2Jk" />
+ </target>
+
+ <target name="detect" >
+ <property file="build.properties"/>
+ <property file="${user.home}/build.properties"/>
+ <property file="${user.home}/.build.properties"/>
+
+ <!-- default locations, overrident by properties.
+ This file must be installed in conf/ -->
+ <property name="tomcat.home" location=".." />
+
+ <available property="33.detect" file="${tomcat.home}/lib/container" />
+ <available property="4x.detect" file="${tomcat.home}/server/lib" />
+ </target>
+
+ <target name="init" depends="detect,init-3x,init-4x" />
+
+ <!-- ==================== Detection and reports ==================== -->
+
+
+ <target name="main" depends="init">
+ <jkconf docBase="${tomcat.home}/webapps/examples"
+ context="/examples" />
+ </target>
+
+</project>
diff --git a/base/ca/shared/conf/jkconfig.manifest b/base/ca/shared/conf/jkconfig.manifest
new file mode 100644
index 000000000..3ba1f2e3e
--- /dev/null
+++ b/base/ca/shared/conf/jkconfig.manifest
@@ -0,0 +1,2 @@
+Main-Class: org.apache.jk.config.WebXml2Jk
+Class-Path: tomcat-jk2.jar commons-logging.jar crimson.jar xercesImpl.jar xmlApis.jar tomcat-util.jar log4j.jar log4j-core.jar
diff --git a/base/ca/shared/conf/logging.properties b/base/ca/shared/conf/logging.properties
new file mode 100644
index 000000000..796cfc071
--- /dev/null
+++ b/base/ca/shared/conf/logging.properties
@@ -0,0 +1,70 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006-2010 Red Hat, Inc.
+# All rights reserved.
+# Modifications: configuration parameters
+# --- END COPYRIGHT BLOCK ---
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+handlers = 1catalina.org.apache.juli.FileHandler, 2localhost.org.apache.juli.FileHandler, 3manager.org.apache.juli.FileHandler, 4host-manager.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+
+.handlers = 1catalina.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+
+############################################################
+# Handler specific properties.
+# Describes specific configuration info for Handlers.
+############################################################
+
+1catalina.org.apache.juli.FileHandler.level = FINE
+1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+1catalina.org.apache.juli.FileHandler.prefix = catalina.
+
+2localhost.org.apache.juli.FileHandler.level = FINE
+2localhost.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+2localhost.org.apache.juli.FileHandler.prefix = localhost.
+
+3manager.org.apache.juli.FileHandler.level = FINE
+3manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+3manager.org.apache.juli.FileHandler.prefix = manager.
+
+4host-manager.org.apache.juli.FileHandler.level = FINE
+4host-manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+4host-manager.org.apache.juli.FileHandler.prefix = host-manager.
+
+java.util.logging.ConsoleHandler.level = FINE
+java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
+
+
+############################################################
+# Facility specific properties.
+# Provides extra control for each logger.
+############################################################
+
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler
+
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler
+
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler
+
+# For example, set the com.xyz.foo logger to only log SEVERE
+# messages:
+#org.apache.catalina.startup.ContextConfig.level = FINE
+#org.apache.catalina.startup.HostConfig.level = FINE
+#org.apache.catalina.session.ManagerBase.level = FINE
+#org.apache.catalina.core.AprLifecycleListener.level=FINE
diff --git a/base/ca/shared/conf/manager.ldif b/base/ca/shared/conf/manager.ldif
new file mode 100644
index 000000000..52e486987
--- /dev/null
+++ b/base/ca/shared/conf/manager.ldif
@@ -0,0 +1,48 @@
+# acis for cert manager
+
+dn: ou=csusers,cn=config
+objectClass: top
+objectClass: organizationalUnit
+ou: csusers
+
+dn: {rootSuffix}
+changetype: modify
+add: aci
+aci: (targetattr=*)(version 3.0; acl "cert manager access"; allow (all) userdn = "ldap:///{dbuser}";)
+
+dn: cn=ldbm database,cn=plugins,cn=config
+changetype: modify
+add: aci
+aci: (targetattr=*)(version 3.0; acl "Cert Manager access for VLV searches"; allow (read) userdn="ldap:///{dbuser}";)
+
+dn: cn=config
+changetype: modify
+add: aci
+aci: (targetattr != aci)(version 3.0; aci "cert manager read access"; allow (read, search, compare) userdn = "ldap:///{dbuser}";)
+
+dn: ou=csusers,cn=config
+changetype: modify
+add: aci
+aci: (targetattr != aci)(version 3.0; aci "cert manager manage replication users"; allow (all) userdn = "ldap:///{dbuser}";)
+
+dn: cn="{rootSuffix}",cn=mapping tree,cn=config
+changetype: modify
+add: aci
+aci: (targetattr=*)(version 3.0;acl "cert manager: Add Replication Agreements";allow (add) userdn = "ldap:///{dbuser}";)
+
+dn: cn="{rootSuffix}",cn=mapping tree,cn=config
+changetype: modify
+add: aci
+aci: (targetattr=*)(targetfilter="(|(objectclass=nsds5Replica)(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement)(objectClass=nsMappingTree))")(version 3.0; acl "cert manager: Modify Replication Agreements"; allow (read, write, search) userdn = "ldap:///{dbuser}";)
+
+dn: cn="{rootSuffix}",cn=mapping tree,cn=config
+changetype: modify
+add: aci
+aci: (targetattr=*)(targetfilter="(|(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement))")(version 3.0;acl "cert manager: Remove Replication Agreements";allow (delete) userdn = "ldap:///{dbuser}";)
+
+dn: cn=tasks,cn=config
+changetype: modify
+add: aci
+aci: (targetattr=*)(version 3.0; acl "cert manager: Run tasks after replica re-initialization"; allow (add) userdn = "ldap:///{dbuser}";)
+
+
diff --git a/base/ca/shared/conf/proxy.conf b/base/ca/shared/conf/proxy.conf
new file mode 100644
index 000000000..663ba5722
--- /dev/null
+++ b/base/ca/shared/conf/proxy.conf
@@ -0,0 +1,34 @@
+ProxyRequests Off
+
+# matches for ee port
+<LocationMatch "^/ca/ee/*|^/ca/renewal|^/ca/certbasedenrollment|^/ca/ocsp|^/ca/enrollment|^/ca/profileSubmit|^/ca/cgi-bin/pkiclient.exe">
+ NSSOptions +StdEnvVars +ExportCertData +StrictRequire +OptRenegotiate
+ NSSVerifyClient none
+ ProxyPassMatch ajp://[PKI_MACHINE_NAME]:[PKI_AJP_PORT]/
+ ProxyPassReverse ajp://[PKI_MACHINE_NAME]:[PKI_AJP_PORT]/
+</LocationMatch>
+
+# matches for admin port
+<LocationMatch "^/ca/admin/*|^/ca/auths|^/ca/acl|^/ca/server|^/ca/caadmin|^/ca/caprofile|^/ca/jobsScheduler|^/ca/capublisher|^/ca/log|^/ca/ug">
+ NSSOptions +StdEnvVars +ExportCertData +StrictRequire +OptRenegotiate
+ NSSVerifyClient none
+ ProxyPassMatch ajp://[PKI_MACHINE_NAME]:[PKI_AJP_PORT]/
+ ProxyPassReverse ajp://[PKI_MACHINE_NAME]:[PKI_AJP_PORT]/
+</LocationMatch>
+
+# matches for agent port and eeca port
+<LocationMatch "^/ca/agent/*|^/ca/ca/getCertFromRequest|^/ca/ca/GetBySerial|^/ca/ca/connector|/ca/ca/displayCertFromRequest|^/ca/doRevoke|^/ca/eeca/*">
+ NSSOptions +StdEnvVars +ExportCertData +StrictRequire +OptRenegotiate
+ NSSVerifyClient require
+ ProxyPassMatch ajp://[PKI_MACHINE_NAME]:[PKI_AJP_PORT]/
+ ProxyPassReverse ajp://[PKI_MACHINE_NAME]:[PKI_AJP_PORT]/
+</LocationMatch>
+
+# static content
+<LocationMatch "^/graphics/*">
+ NSSOptions +StdEnvVars +ExportCertData +StrictRequire +OptRenegotiate
+ NSSVerifyClient none
+ ProxyPassMatch ajp://[PKI_MACHINE_NAME]:[PKI_AJP_PORT]/
+ ProxyPassReverse ajp://[PKI_MACHINE_NAME]:[PKI_AJP_PORT]/
+</LocationMatch>
+
diff --git a/base/ca/shared/conf/registry.cfg b/base/ca/shared/conf/registry.cfg
new file mode 100644
index 000000000..f424bdb1b
--- /dev/null
+++ b/base/ca/shared/conf/registry.cfg
@@ -0,0 +1,232 @@
+types=profile,defaultPolicy,constraintPolicy,profileInput,profileOutput,profileUpdater
+constraintPolicy.ids=noConstraintImpl,subjectNameConstraintImpl,uniqueSubjectNameConstraintImpl,validityConstraintImpl,keyUsageExtConstraintImpl,nsCertTypeExtConstraintImpl,extendedKeyUsageExtConstraintImpl,keyConstraintImpl,basicConstraintsExtConstraintImpl,extensionConstraintImpl,signingAlgConstraintImpl,uniqueKeyConstraintImpl,renewGracePeriodConstraintImpl
+constraintPolicy.signingAlgConstraintImpl.class=com.netscape.cms.profile.constraint.SigningAlgConstraint
+constraintPolicy.signingAlgConstraintImpl.desc=Signing Algorithm Constraint
+constraintPolicy.signingAlgConstraintImpl.name=Signing Algorithm Constraint
+constraintPolicy.extensionConstraintImpl.class=com.netscape.cms.profile.constraint.ExtensionConstraint
+constraintPolicy.extensionConstraintImpl.desc=Extension Constraint
+constraintPolicy.extensionConstraintImpl.name=Extension Constraint
+constraintPolicy.basicConstraintsExtConstraintImpl.class=com.netscape.cms.profile.constraint.BasicConstraintsExtConstraint
+constraintPolicy.basicConstraintsExtConstraintImpl.desc=Basic Constraints Extension Constraint
+constraintPolicy.basicConstraintsExtConstraintImpl.name=Basic Constraints Extension Constraint
+constraintPolicy.keyConstraintImpl.class=com.netscape.cms.profile.constraint.KeyConstraint
+constraintPolicy.keyConstraintImpl.desc=Key Constraint
+constraintPolicy.keyConstraintImpl.name=Key Constraint
+constraintPolicy.extendedKeyUsageExtConstraintImpl.class=com.netscape.cms.profile.constraint.ExtendedKeyUsageExtConstraint
+constraintPolicy.extendedKeyUsageExtConstraintImpl.desc=Extended Key Usage Extension Constraint
+constraintPolicy.extendedKeyUsageExtConstraintImpl.name=Extended Key Usage Extension Constraint
+constraintPolicy.keyUsageExtConstraintImpl.class=com.netscape.cms.profile.constraint.KeyUsageExtConstraint
+constraintPolicy.keyUsageExtConstraintImpl.desc=Key Usage Extension Constraint
+constraintPolicy.keyUsageExtConstraintImpl.name=Key Usage Extension Constraint
+constraintPolicy.nsCertTypeExtConstraintImpl.class=com.netscape.cms.profile.constraint.NSCertTypeExtConstraint
+constraintPolicy.nsCertTypeExtConstraintImpl.desc=Netscape Certificate Type Extension Constraint
+constraintPolicy.nsCertTypeExtConstraintImpl.name=Netscape Certificate Type Extension Constraint
+constraintPolicy.noConstraintImpl.class=com.netscape.cms.profile.constraint.NoConstraint
+constraintPolicy.noConstraintImpl.desc=No Constraint
+constraintPolicy.noConstraintImpl.name=No Constraint
+constraintPolicy.subjectNameConstraintImpl.class=com.netscape.cms.profile.constraint.SubjectNameConstraint
+constraintPolicy.subjectNameConstraintImpl.desc=Subject Name Constraint
+constraintPolicy.subjectNameConstraintImpl.name=Subject Name Constraint
+constraintPolicy.uniqueSubjectNameConstraintImpl.class=com.netscape.cms.profile.constraint.UniqueSubjectNameConstraint
+constraintPolicy.uniqueSubjectNameConstraintImpl.desc=Unique Subject Name Constraint
+constraintPolicy.uniqueSubjectNameConstraintImpl.name=Unique Subject Name Constraint
+constraintPolicy.validityConstraintImpl.class=com.netscape.cms.profile.constraint.ValidityConstraint
+constraintPolicy.validityConstraintImpl.desc=Validity Constraint
+constraintPolicy.validityConstraintImpl.name=Validity Constraint
+constraintPolicy.renewGracePeriodConstraintImpl.class=com.netscape.cms.profile.constraint.RenewGracePeriodConstraint
+constraintPolicy.renewGracePeriodConstraintImpl.desc=Renewal Grace Period Constraint
+constraintPolicy.renewGracePeriodConstraintImpl.name=Renewal Grace Period Constraint
+constraintPolicy.uniqueKeyConstraintImpl.class=com.netscape.cms.profile.constraint.UniqueKeyConstraint
+constraintPolicy.uniqueKeyConstraintImpl.desc=Unique Public Key Constraint
+constraintPolicy.uniqueKeyConstraintImpl.name=Unique Public Key Constraint
+defaultPolicy.ids=noDefaultImpl,genericExtDefaultImpl,autoAssignDefaultImpl,subjectNameDefaultImpl,validityDefaultImpl,caValidityDefaultImpl,subjectKeyIdentifierExtDefaultImpl,authorityKeyIdentifierExtDefaultImpl,basicConstraintsExtDefaultImpl,keyUsageExtDefaultImpl,nsCertTypeExtDefaultImpl,extendedKeyUsageExtDefaultImpl,ocspNoCheckExtDefaultImpl,issuerAltNameExtDefaultImpl,subjectAltNameExtDefaultImpl,userSubjectNameDefaultImpl,signingAlgDefaultImpl,userKeyDefaultImpl,userValidityDefaultImpl,userExtensionDefaultImpl,userSigningAlgDefaultImpl,authTokenSubjectNameDefaultImpl,subjectInfoAccessExtDefaultImpl,authInfoAccessExtDefaultImpl,nscCommentExtDefaultImpl,freshestCRLExtDefaultImpl,crlDistributionPointsExtDefaultImpl,policyConstraintsExtDefaultImpl,policyMappingsExtDefaultImpl,nameConstraintsExtDefaultImpl,certificateVersionDefaultImpl,certificatePoliciesExtDefaultImpl,subjectDirAttributesExtDefaultImpl,privateKeyPeriodExtDefaultImpl,inhibitAnyPolicyExtDefaultImpl,imageDefaultImpl,nsTokenDeviceKeySubjectNameDefaultImpl,nsTokenUserKeySubjectNameDefaultImpl
+defaultPolicy.autoAssignDefaultImpl.class=com.netscape.cms.profile.def.AutoAssignDefault
+defaultPolicy.autoAssignDefaultImpl.desc=Auto Request Assignment Default
+defaultPolicy.autoAssignDefaultImpl.name=Auto Request Assignment Default
+defaultPolicy.genericExtDefaultImpl.class=com.netscape.cms.profile.def.GenericExtDefault
+defaultPolicy.genericExtDefaultImpl.desc=Generic Extension
+defaultPolicy.genericExtDefaultImpl.name=Generic Extension
+defaultPolicy.imageDefaultImpl.class=com.netscape.cms.profile.def.ImageDefault
+defaultPolicy.imageDefaultImpl.desc=Image Default
+defaultPolicy.imageDefaultImpl.name=Image Default
+defaultPolicy.privateKeyPeriodExtDefaultImpl.class=com.netscape.cms.profile.def.PrivateKeyUsagePeriodExtDefault
+defaultPolicy.privateKeyPeriodExtDefaultImpl.desc=Private Key Period Ext Default
+defaultPolicy.privateKeyPeriodExtDefaultImpl.name=Private Key Period Ext Default
+defaultPolicy.authTokenSubjectNameDefaultImpl.class=com.netscape.cms.profile.def.AuthTokenSubjectNameDefault
+defaultPolicy.authTokenSubjectNameDefaultImpl.desc=Token Supplied Subject Name Default
+defaultPolicy.authTokenSubjectNameDefaultImpl.name=Token Supplied Subject Name Default
+defaultPolicy.userSubjectNameDefaultImpl.class=com.netscape.cms.profile.def.UserSubjectNameDefault
+defaultPolicy.userSubjectNameDefaultImpl.desc=User Supplied Subject Name Default
+defaultPolicy.userSubjectNameDefaultImpl.name=User Supplied Subject Name Default
+defaultPolicy.userKeyDefaultImpl.class=com.netscape.cms.profile.def.UserKeyDefault
+defaultPolicy.userKeyDefaultImpl.desc=User Supplied Key Default
+defaultPolicy.userKeyDefaultImpl.name=User Supplied Key Default
+defaultPolicy.userValidityDefaultImpl.class=com.netscape.cms.profile.def.UserValidityDefault
+defaultPolicy.userValidityDefaultImpl.desc=User Supplied Validity Default
+defaultPolicy.userValidityDefaultImpl.name=User Supplied Validity Default
+defaultPolicy.userExtensionDefaultImpl.class=com.netscape.cms.profile.def.UserExtensionDefault
+defaultPolicy.userExtensionDefaultImpl.desc=User Supplied Extension Default
+defaultPolicy.userExtensionDefaultImpl.name=User Supplied Extension Default
+defaultPolicy.userSigningAlgDefaultImpl.class=com.netscape.cms.profile.def.UserSigningAlgDefault
+defaultPolicy.userSigningAlgDefaultImpl.desc=User Supplied Signing Alg Default
+defaultPolicy.userSigningAlgDefaultImpl.name=User Supplied Signing Alg Default
+defaultPolicy.signingAlgDefaultImpl.class=com.netscape.cms.profile.def.SigningAlgDefault
+defaultPolicy.signingAlgDefaultImpl.desc=Signing Algorithm Default
+defaultPolicy.signingAlgDefaultImpl.name=Signing Algorithm Default
+defaultPolicy.authorityKeyIdentifierExtDefaultImpl.class=com.netscape.cms.profile.def.AuthorityKeyIdentifierExtDefault
+defaultPolicy.authorityKeyIdentifierExtDefaultImpl.desc=Authority Key Identifier Extension Default
+defaultPolicy.authorityKeyIdentifierExtDefaultImpl.name=Authority Key Identifier Extension Default
+defaultPolicy.basicConstraintsExtDefaultImpl.class=com.netscape.cms.profile.def.BasicConstraintsExtDefault
+defaultPolicy.basicConstraintsExtDefaultImpl.desc=Basic Constraints Extension Default
+defaultPolicy.basicConstraintsExtDefaultImpl.name=Basic Constraints Extension Default
+defaultPolicy.extendedKeyUsageExtDefaultImpl.class=com.netscape.cms.profile.def.ExtendedKeyUsageExtDefault
+defaultPolicy.extendedKeyUsageExtDefaultImpl.desc=Extended Key Usage Extension Default
+defaultPolicy.extendedKeyUsageExtDefaultImpl.name=Extended Key Usage Extension Default
+defaultPolicy.keyUsageExtDefaultImpl.class=com.netscape.cms.profile.def.KeyUsageExtDefault
+defaultPolicy.keyUsageExtDefaultImpl.desc=Key Usage Extension Default
+defaultPolicy.keyUsageExtDefaultImpl.name=Key Usage Extension Default
+defaultPolicy.noDefaultImpl.class=com.netscape.cms.profile.def.NoDefault
+defaultPolicy.noDefaultImpl.desc=No Default
+defaultPolicy.noDefaultImpl.name=No Default
+defaultPolicy.nsCertTypeExtDefaultImpl.desc=Netscape Certificate Type Extension Default
+defaultPolicy.nsCertTypeExtDefaultImpl.name=Netscape Certificate Type Extension Default
+defaultPolicy.nsCertTypeExtDefaultImpl.class=com.netscape.cms.profile.def.NSCertTypeExtDefault
+defaultPolicy.nsTokenDeviceKeySubjectNameDefaultImpl.class=com.netscape.cms.profile.def.nsTokenDeviceKeySubjectNameDefault
+defaultPolicy.nsTokenDeviceKeySubjectNameDefaultImpl.desc=nsTokenDeviceKeySubjectNameDefaultImpl
+defaultPolicy.nsTokenDeviceKeySubjectNameDefaultImpl.name=nsTokenDeviceKeySubjectNameDefault
+defaultPolicy.nsTokenUserKeySubjectNameDefaultImpl.class=com.netscape.cms.profile.def.nsTokenUserKeySubjectNameDefault
+defaultPolicy.nsTokenUserKeySubjectNameDefaultImpl.desc=nsTokenUserKeySubjectNameDefaultImpl
+defaultPolicy.nsTokenUserKeySubjectNameDefaultImpl.name=nsTokenUserKeySubjectNameDefault
+defaultPolicy.ocspNoCheckExtDefaultImpl.class=com.netscape.cms.profile.def.OCSPNoCheckExtDefault
+defaultPolicy.ocspNoCheckExtDefaultImpl.desc=OCSP No Check Extension Default
+defaultPolicy.ocspNoCheckExtDefaultImpl.name=OCSP No Check Extension Default
+defaultPolicy.issuerAltNameExtDefaultImpl.class=com.netscape.cms.profile.def.IssuerAltNameExtDefault
+defaultPolicy.issuerAltNameExtDefaultImpl.desc=Issuer Alternative Name Extension Default
+defaultPolicy.issuerAltNameExtDefaultImpl.name=Issuer Alternative Name Extension Default
+defaultPolicy.subjectAltNameExtDefaultImpl.class=com.netscape.cms.profile.def.SubjectAltNameExtDefault
+defaultPolicy.subjectAltNameExtDefaultImpl.desc=Subject Alternative Name Extension Default
+defaultPolicy.subjectAltNameExtDefaultImpl.name=Subject Alternative Name Extension Default
+defaultPolicy.subjectKeyIdentifierExtDefaultImpl.class=com.netscape.cms.profile.def.SubjectKeyIdentifierExtDefault
+defaultPolicy.subjectKeyIdentifierExtDefaultImpl.desc=Subject Key Identifier Default
+defaultPolicy.subjectKeyIdentifierExtDefaultImpl.name=Subject Key Identifier Default
+defaultPolicy.subjectNameDefaultImpl.class=com.netscape.cms.profile.def.SubjectNameDefault
+defaultPolicy.subjectNameDefaultImpl.desc=Subject Name Default
+defaultPolicy.subjectNameDefaultImpl.name=Subject Name Default
+defaultPolicy.validityDefaultImpl.class=com.netscape.cms.profile.def.ValidityDefault
+defaultPolicy.validityDefaultImpl.desc=Validty Default
+defaultPolicy.validityDefaultImpl.name=Validity Default
+defaultPolicy.caValidityDefaultImpl.class=com.netscape.cms.profile.def.CAValidityDefault
+defaultPolicy.caValidityDefaultImpl.desc=CA Certificate Validty Default
+defaultPolicy.caValidityDefaultImpl.name=CA Certificate Validity Default
+defaultPolicy.subjectInfoAccessExtDefaultImpl.class=com.netscape.cms.profile.def.SubjectInfoAccessExtDefault
+defaultPolicy.subjectInfoAccessExtDefaultImpl.desc=Subject Info Access Extension Default
+defaultPolicy.subjectInfoAccessExtDefaultImpl.name=Subject Info Access Extension Default
+defaultPolicy.authInfoAccessExtDefaultImpl.class=com.netscape.cms.profile.def.AuthInfoAccessExtDefault
+defaultPolicy.authInfoAccessExtDefaultImpl.desc=Authority Info Access Extension Default
+defaultPolicy.authInfoAccessExtDefaultImpl.name=Authority Info Access Extension Default
+defaultPolicy.nscCommentExtDefaultImpl.class=com.netscape.cms.profile.def.NSCCommentExtDefault
+defaultPolicy.nscCommentExtDefaultImpl.desc=Netscape Comment Extension Default
+defaultPolicy.nscCommentExtDefaultImpl.name=Netscape Comment Extension Default
+defaultPolicy.freshestCRLExtDefaultImpl.class=com.netscape.cms.profile.def.FreshestCRLExtDefault
+defaultPolicy.freshestCRLExtDefaultImpl.desc=Freshest CRL Extension Default
+defaultPolicy.freshestCRLExtDefaultImpl.name=Freshest CRL Extension Default
+defaultPolicy.crlDistributionPointsExtDefaultImpl.class=com.netscape.cms.profile.def.CRLDistributionPointsExtDefault
+defaultPolicy.crlDistributionPointsExtDefaultImpl.desc=CRL Distribution Points Extension Default
+defaultPolicy.crlDistributionPointsExtDefaultImpl.name=CRL Distribution Points Extension Default
+defaultPolicy.policyConstraintsExtDefaultImpl.class=com.netscape.cms.profile.def.PolicyConstraintsExtDefault
+defaultPolicy.policyConstraintsExtDefaultImpl.desc=Policy Constraints Extension Default
+defaultPolicy.policyConstraintsExtDefaultImpl.name=Policy Constraints Extension Default
+defaultPolicy.policyMappingsExtDefaultImpl.class=com.netscape.cms.profile.def.PolicyMappingsExtDefault
+defaultPolicy.policyMappingsExtDefaultImpl.desc=Policy Mappings Extension Default
+defaultPolicy.policyMappingsExtDefaultImpl.name=Policy Mappings Extension Default
+defaultPolicy.nameConstraintsExtDefaultImpl.class=com.netscape.cms.profile.def.NameConstraintsExtDefault
+defaultPolicy.nameConstraintsExtDefaultImpl.desc=Name Constraints Extension Default
+defaultPolicy.nameConstraintsExtDefaultImpl.name=Name Constraints Extension Default
+defaultPolicy.certificateVersionDefaultImpl.class=com.netscape.cms.profile.def.CertificateVersionDefault
+defaultPolicy.certificateVersionDefaultImpl.desc=Certificate Version Default
+defaultPolicy.certificateVersionDefaultImpl.name=Certificate Version Default
+defaultPolicy.certificatePoliciesExtDefaultImpl.class=com.netscape.cms.profile.def.CertificatePoliciesExtDefault
+defaultPolicy.certificatePoliciesExtDefaultImpl.desc=Certificate Policies Extension Default
+defaultPolicy.certificatePoliciesExtDefaultImpl.name=Certificate Policies Extension Default
+defaultPolicy.subjectDirAttributesExtDefaultImpl.class=com.netscape.cms.profile.def.SubjectDirAttributesExtDefault
+defaultPolicy.subjectDirAttributesExtDefaultImpl.desc=Subject Directory Attributes Extension Default
+defaultPolicy.subjectDirAttributesExtDefaultImpl.name=Subject Directory Attributes Extension Default
+defaultPolicy.inhibitAnyPolicyExtDefaultImpl.class=com.netscape.cms.profile.def.InhibitAnyPolicyExtDefault
+defaultPolicy.inhibitAnyPolicyExtDefaultImpl.desc=Inhibit Any-Policy Extension Default
+defaultPolicy.inhibitAnyPolicyExtDefaultImpl.name=Inhibit Any-Policy Extension Default
+profile.ids=caEnrollImpl,caCACertEnrollImpl,caServerCertEnrollImpl,caUserCertEnrollImpl
+profile.caEnrollImpl.class=com.netscape.cms.profile.common.CAEnrollProfile
+profile.caEnrollImpl.desc=Certificate Authority Generic Certificate Enrollment Profile
+profile.caEnrollImpl.name=Generic Certificate Enrollment Profile
+profile.caCACertEnrollImpl.class=com.netscape.cms.profile.common.CACertCAEnrollProfile
+profile.caCACertEnrollImpl.desc=Certificate Authority CA Certificate Enrollment Profile
+profile.caCACertEnrollImpl.name=CA Certificate Enrollment Profile
+profile.caServerCertEnrollImpl.class=com.netscape.cms.profile.common.ServerCertCAEnrollProfile
+profile.caServerCertEnrollImpl.desc=Certificate Authority Server Certificate Enrollment Profile
+profile.caServerCertEnrollImpl.name=Server Certificate Enrollment Profile
+profile.caUserCertEnrollImpl.class=com.netscape.cms.profile.common.UserCertCAEnrollProfile
+profile.caUserCertEnrollImpl.desc=Certificate Authority User Certificate Enrollment Profile
+profile.caUserCertEnrollImpl.name=User Certificate Enrollment Profile
+profileInput.ids=cmcCertReqInputImpl,certReqInputImpl,keyGenInputImpl,encKeyGenInputImpl,signKeyGenInputImpl,dualKeyGenInputImpl,subjectNameInputImpl,submitterInfoInputImpl,genericInputImpl,fileSigningInputImpl,imageInputImpl,subjectDNInputImpl,nsNKeyCertReqInputImpl,nsHKeyCertReqInputImpl,serialNumRenewInputImpl
+profileInput.fileSigningInputImpl.class=com.netscape.cms.profile.input.FileSigningInput
+profileInput.fileSigningInputImpl.desc=File Signing Input
+profileInput.fileSigningInputImpl.name=File Signing Input
+profileInput.imageInputImpl.class=com.netscape.cms.profile.input.ImageInput
+profileInput.imageInputImpl.desc=Image Input
+profileInput.imageInputImpl.name=Image Input
+profileInput.genericInputImpl.class=com.netscape.cms.profile.input.GenericInput
+profileInput.genericInputImpl.desc=Generic Input
+profileInput.genericInputImpl.name=Generic Input
+profileInput.submitterInfoInputImpl.class=com.netscape.cms.profile.input.SubmitterInfoInput
+profileInput.submitterInfoInputImpl.desc=Submitter Information Input
+profileInput.submitterInfoInputImpl.name=Submitter Information Input
+profileInput.certReqInputImpl.class=com.netscape.cms.profile.input.CertReqInput
+profileInput.certReqInputImpl.desc=Certificate Request Input
+profileInput.certReqInputImpl.name=Certificate Request Input
+profileInput.cmcCertReqInputImpl.class=com.netscape.cms.profile.input.CMCCertReqInput
+profileInput.cmcCertReqInputImpl.desc=CMC Certificate Request Input
+profileInput.cmcCertReqInputImpl.name=CMC Certificate Request Input
+profileInput.dualKeyGenInputImpl.class=com.netscape.cms.profile.input.DualKeyGenInput
+profileInput.dualKeyGenInputImpl.desc=Dual Key Generation Input
+profileInput.dualKeyGenInputImpl.name=Dual Key Generation Input
+profileInput.signKeyGenInputImpl.class=com.netscape.cms.profile.input.SigningKeyGenInput
+profileInput.signKeyGenInputImpl.desc=Encryption Key Generation Input
+profileInput.signKeyGenInputImpl.name=Encryption Key Generation Input
+profileInput.encKeyGenInputImpl.class=com.netscape.cms.profile.input.EncryptionKeyGenInput
+profileInput.encKeyGenInputImpl.desc=Encryption Key Generation Input
+profileInput.encKeyGenInputImpl.name=Encryption Key Generation Input
+profileInput.keyGenInputImpl.class=com.netscape.cms.profile.input.KeyGenInput
+profileInput.keyGenInputImpl.desc=Key Generation Input
+profileInput.keyGenInputImpl.name=Key Generation Input
+profileInput.nsNKeyCertReqInputImpl.class=com.netscape.cms.profile.input.nsNKeyCertReqInput
+profileInput.nsNKeyCertReqInputImpl.desc=nsNKeyCertReqInputImpl
+profileInput.nsNKeyCertReqInputImpl.name=nsNKeyCertReqInputImpl
+profileInput.nsHKeyCertReqInputImpl.class=com.netscape.cms.profile.input.nsHKeyCertReqInput
+profileInput.nsHKeyCertReqInputImpl.desc=nsHKeyCertReqInputImpl
+profileInput.nsHKeyCertReqInputImpl.name=nsHKeyCertReqInputImpl
+profileInput.serialNumRenewInputImpl.class=com.netscape.cms.profile.input.SerialNumRenewInput
+profileInput.serialNumRenewInputImpl.desc=Certificate Renewal Request Serial Number Input
+profileInput.serialNumRenewInputImpl.name=Certificate Renewal Request Serial Number Input
+profileInput.subjectDNInputImpl.class=com.netscape.cms.profile.input.SubjectDNInput
+profileInput.subjectDNInputImpl.desc=Subject DN Input
+profileInput.subjectDNInputImpl.name=Subject DN Input
+profileInput.subjectNameInputImpl.class=com.netscape.cms.profile.input.SubjectNameInput
+profileInput.subjectNameInputImpl.desc=Subject Name Input
+profileInput.subjectNameInputImpl.name=Subject Name Input
+profileOutput.ids=certOutputImpl,cmmfOutputImpl,pkcs7OutputImpl,nsNKeyOutputImpl
+profileOutput.certOutputImpl.class=com.netscape.cms.profile.output.CertOutput
+profileOutput.certOutputImpl.desc=Certificate Output
+profileOutput.certOutputImpl.name=Certificate Output
+profileOutput.cmmfOutputImpl.class=com.netscape.cms.profile.output.CMMFOutput
+profileOutput.cmmfOutputImpl.desc=CMMF Response Output
+profileOutput.cmmfOutputImpl.name=CMMF Response Output
+profileOutput.nsNKeyOutputImpl.class=com.netscape.cms.profile.output.nsNKeyOutput
+profileOutput.nsNKeyOutputImpl.desc=nsNKeyOutputImpl
+profileOutput.nsNKeyOutputImpl.name=nsNKeyOutputImpl
+profileOutput.pkcs7OutputImpl.class=com.netscape.cms.profile.output.PKCS7Output
+profileOutput.pkcs7OutputImpl.desc=PKCS7 Output
+profileOutput.pkcs7OutputImpl.name=PKCS7 Output
+profileUpdater.ids=subsystemGroupUpdaterImpl
+profileUpdater.subsystemGroupUpdaterImpl.class=com.netscape.cms.profile.updater.SubsystemGroupUpdater
+profileUpdater.subsystemGroupUpdaterImpl.desc=Updater for Subsystem Group
+profileUpdater.subsystemGroupUpdaterImpl.name=Updater for Subsystem Group
diff --git a/base/ca/shared/conf/schema.ldif b/base/ca/shared/conf/schema.ldif
new file mode 100644
index 000000000..70578e21c
--- /dev/null
+++ b/base/ca/shared/conf/schema.ldif
@@ -0,0 +1,489 @@
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( usertype-oid NAME 'usertype' DESC 'Distinguish whether the user is administrator, agent or subsystem.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( userstate-oid NAME 'userstate' DESC 'Distinguish whether the user is administrator, agent or subsystem.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( cmsuser-oid NAME 'cmsuser' DESC 'CMS User' SUP top STRUCTURAL MUST usertype MAY userstate X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( archivedBy-oid NAME 'archivedBy' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( adminMessages-oid NAME 'adminMessages' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( algorithm-oid NAME 'algorithm' DESC 'CMS defined attribute'SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( algorithmId-oid NAME 'algorithmId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( signingAlgorithmId-oid NAME 'signingAlgorithmId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( autoRenew-oid NAME 'autoRenew' DESC 'CMS defined attribute'SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( certStatus-oid NAME 'certStatus' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( crlName-oid NAME 'crlName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( crlSize-oid NAME 'crlSize' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( deltaSize-oid NAME 'deltaSize' DESC 'CMS defined attribute'SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( crlNumber-oid NAME 'crlNumber' DESC 'CMS defined attribute'SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( deltaNumber-oid NAME 'deltaNumber' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( firstUnsaved-oid NAME 'firstUnsaved' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( crlCache-oid NAME 'crlCache' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( revokedCerts-oid NAME 'revokedCerts' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( unrevokedCerts-oid NAME 'unrevokedCerts' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( expiredCerts-oid NAME 'expiredCerts' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( crlExtensions-oid NAME 'crlExtensions' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dateOfArchival-oid NAME 'dateOfArchival' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dateOfRecovery-oid NAME 'dateOfRecovery' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dateOfRevocation-oid NAME 'dateOfRevocation' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dateOfCreate-oid NAME 'dateOfCreate' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dateOfModify-oid NAME 'dateOfModify' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( duration-oid NAME 'duration' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( extension-oid NAME 'extension' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( issuedBy-oid NAME 'issuedBy' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( issueInfo-oid NAME 'issueInfo' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( issuerName-oid NAME 'issuerName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( keySize-oid NAME 'keySize' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( clientId-oid NAME 'clientId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dataType-oid NAME 'dataType' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( status-oid NAME 'status' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( keyState-oid NAME 'keyState' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( metaInfo-oid NAME 'metaInfo' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( nextUpdate-oid NAME 'nextUpdate' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( notAfter-oid NAME 'notAfter' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( notBefore-oid NAME 'notBefore' DESC 'CMS defined attribute'SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( ownerName-oid NAME 'ownerName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( password-oid NAME 'password' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( p12Expiration-oid NAME 'p12Expiration' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( proofOfArchival-oid NAME 'proofOfArchival' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( publicKeyData-oid NAME 'publicKeyData' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( publicKeyFormat-oid NAME 'publicKeyFormat' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( privateKeyData-oid NAME 'privateKeyData' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestId-oid NAME 'requestId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestInfo-oid NAME 'requestInfo' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestState-oid NAME 'requestState' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestResult-oid NAME 'requestResult' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestOwner-oid NAME 'requestOwner' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestAgentGroup-oid NAME 'requestAgentGroup' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestSourceId-oid NAME 'requestSourceId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestType-oid NAME 'requestType' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestFlag-oid NAME 'requestFlag' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestError-oid NAME 'requestError' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( resourceACLS-oid NAME 'resourceACLS' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( revInfo-oid NAME 'revInfo' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( revokedBy-oid NAME 'revokedBy' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( revokedOn-oid NAME 'revokedOn' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( serialno-oid NAME 'serialno' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( nextRange-oid NAME 'nextRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( publishingStatus-oid NAME 'publishingStatus' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( beginRange-oid NAME 'beginRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( endRange-oid NAME 'endRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( subjectName-oid NAME 'subjectName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( sessionContext-oid NAME 'sessionContext' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( thisUpdate-oid NAME 'thisUpdate' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( transId-oid NAME 'transId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( transStatus-oid NAME 'transStatus' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( transName-oid NAME 'transName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( transOps-oid NAME 'transOps' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( userDN-oid NAME 'userDN' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( userMessages-oid NAME 'userMessages' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( version-oid NAME 'version' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( Clone-oid NAME 'Clone' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( DomainManager-oid NAME 'DomainManager' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SecurePort-oid NAME 'SecurePort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SecureAgentPort-oid NAME 'SecureAgentPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SecureAdminPort-oid NAME 'SecureAdminPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SecureEEClientAuthPort-oid NAME 'SecureEEClientAuthPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( UnSecurePort-oid NAME 'UnSecurePort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SubsystemName-oid NAME 'SubsystemName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( cmsUserGroup-oid NAME 'cmsUserGroup' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( CertACLS-oid NAME 'CertACLS' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY resourceACLS X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( repository-oid NAME 'repository' DESC 'CMS defined class' SUP top STRUCTURAL MUST ou MAY ( serialno $ description $ nextRange $ publishingStatus ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( request-oid NAME 'request' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( requestId $ dateOfCreate $ dateOfModify $ requestState $ requestResult $ requestOwner $ requestAgentGroup $ requestSourceId $ requestType $ requestFlag $ requestError $ userMessages $ adminMessages ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( transaction-oid NAME 'transaction' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( transId $ description $ transName $ transStatus $ transOps ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( crlIssuingPointRecord-oid NAME 'crlIssuingPointRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( dateOfCreate $ dateOfModify $ crlNumber $ crlSize $ thisUpdate $ nextUpdate $ deltaNumber $ deltaSize $ firstUnsaved $ certificateRevocationList $ deltaRevocationList $ crlCache $ revokedCerts $ unrevokedCerts $ expiredCerts $ cACertificate ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( certificateRecord-oid NAME 'certificateRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( serialno $ dateOfCreate $ dateOfModify $ certStatus $ autoRenew $ issueInfo $ metaInfo $ revInfo $ version $ duration $ notAfter $ notBefore $ algorithmId $ subjectName $ signingAlgorithmId $ userCertificate $ issuedBy $ revokedBy $ revokedOn $ extension $ publicKeyData $ issuerName ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( userDetails-oid NAME 'userDetails' DESC 'CMS defined class' SUP top STRUCTURAL MUST userDN MAY ( dateOfCreate $ dateOfModify $ password $ p12Expiration ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( keyRecord-oid NAME 'keyRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( serialno $ dateOfCreate $ dateOfModify $ keyState $ privateKeyData $ ownerName $ keySize $ metaInfo $ dateOfArchival $ dateOfRecovery $ algorithm $ publicKeyFormat $ publicKeyData $ archivedBy $ clientId $ dataType $ status ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( pkiSecurityDomain-oid NAME 'pkiSecurityDomain' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( ou $ name ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( pkiSecurityGroup-oid NAME 'pkiSecurityGroup' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( pkiSubsystem-oid NAME 'pkiSubsystem' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ Host $ SecurePort $ SubsystemName $ Clone ) MAY ( DomainManager $ SecureAgentPort $ SecureAdminPort $SecureEEClientAuthPort $ UnSecurePort ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( pkiRange-oid NAME 'pkiRange' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ beginRange $ endRange $ Host $ SecurePort ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( securityDomainSessionEntry-oid NAME 'securityDomainSessionEntry' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ host $ uid $ cmsUserGroup $ dateOfCreate ) X-ORIGIN 'user defined' )
diff --git a/base/ca/shared/conf/server-minimal.xml b/base/ca/shared/conf/server-minimal.xml
new file mode 100644
index 000000000..7b542b6cf
--- /dev/null
+++ b/base/ca/shared/conf/server-minimal.xml
@@ -0,0 +1,25 @@
+<Server port="8005" shutdown="SHUTDOWN">
+
+ <GlobalNamingResources>
+ <!-- Used by Manager webapp -->
+ <Resource name="UserDatabase" auth="Container"
+ type="org.apache.catalina.UserDatabase"
+ description="User database that can be updated and saved"
+ factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
+ pathname="conf/tomcat-users.xml" />
+ </GlobalNamingResources>
+
+ <Service name="Catalina">
+ <Connector port="8080" />
+
+ <!-- This is here for compatibility only, not required -->
+ <Connector port="8009" protocol="AJP/1.3" />
+
+ <Engine name="Catalina" defaultHost="localhost">
+ <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+ resourceName="UserDatabase" />
+ <Host name="localhost" appBase="webapps" />
+ </Engine>
+
+ </Service>
+</Server>
diff --git a/base/ca/shared/conf/server.xml b/base/ca/shared/conf/server.xml
new file mode 100644
index 000000000..4056fbbb7
--- /dev/null
+++ b/base/ca/shared/conf/server.xml
@@ -0,0 +1,277 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2006-2010 Red Hat, Inc.
+ All rights reserved.
+ Modifications: configuration parameters
+ END COPYRIGHT BLOCK -->
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- Note: A "Server" is not itself a "Container", so you may not
+ define subcomponents such as "Valves" at this level.
+ Documentation at /docs/config/server.html
+ -->
+
+<!-- DO NOT REMOVE - Begin PKI Status Definitions -->
+<!--
+Unsecure Port = http://[PKI_MACHINE_NAME]:[PKI_UNSECURE_PORT]/[PKI_SUBSYSTEM_TYPE]/ee/[PKI_SUBSYSTEM_TYPE]
+Secure Agent Port = https://[PKI_MACHINE_NAME]:[PKI_AGENT_SECURE_PORT]/[PKI_SUBSYSTEM_TYPE]/agent/[PKI_SUBSYSTEM_TYPE]
+Secure EE Port = https://[PKI_MACHINE_NAME]:[PKI_EE_SECURE_PORT]/[PKI_SUBSYSTEM_TYPE]/ee/[PKI_SUBSYSTEM_TYPE]
+Secure Admin Port = https://[PKI_MACHINE_NAME]:[PKI_ADMIN_SECURE_PORT]/[PKI_SUBSYSTEM_TYPE]/services
+EE Client Auth Port = https://[PKI_MACHINE_NAME]:[PKI_EE_SECURE_CLIENT_AUTH_PORT]/[PKI_SUBSYSTEM_TYPE]/eeca/[PKI_SUBSYSTEM_TYPE]
+PKI Console Port = pkiconsole https://[PKI_MACHINE_NAME]:[PKI_ADMIN_SECURE_PORT]/[PKI_SUBSYSTEM_TYPE]
+Tomcat Port = [TOMCAT_SERVER_PORT] (for shutdown)
+-->
+<!-- DO NOT REMOVE - End PKI Status Definitions -->
+
+<Server port="[TOMCAT_SERVER_PORT]" shutdown="SHUTDOWN">
+
+ <!--APR library loader. Documentation at /docs/apr.html -->
+ <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
+ <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
+ <Listener className="org.apache.catalina.core.JasperListener" />
+ <!-- JMX Support for the Tomcat server. Documentation at /docs/non-existent.html -->
+ <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
+ <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
+
+ <!-- Global JNDI resources
+ Documentation at /docs/jndi-resources-howto.html
+ -->
+ <GlobalNamingResources>
+ <!-- Editable user database that can also be used by
+ UserDatabaseRealm to authenticate users
+ -->
+ <Resource name="UserDatabase" auth="Container"
+ type="org.apache.catalina.UserDatabase"
+ description="User database that can be updated and saved"
+ factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
+ pathname="conf/tomcat-users.xml" />
+ </GlobalNamingResources>
+
+ <!-- A "Service" is a collection of one or more "Connectors" that share
+ a single "Container" Note: A "Service" is not itself a "Container",
+ so you may not define subcomponents such as "Valves" at this level.
+ Documentation at /docs/config/service.html
+ -->
+ <Service name="Catalina">
+
+ <!--The connectors can use a shared executor, you can define one or more named thread pools-->
+ <!--
+ <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
+ maxThreads="150" minSpareThreads="4"/>
+ -->
+
+
+ <!-- A "Connector" represents an endpoint by which requests are received
+ and responses are returned. Documentation at :
+ Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
+ Java AJP Connector: /docs/config/ajp.html
+ APR (HTTP/AJP) Connector: /docs/apr.html
+ Define a non-SSL HTTP/1.1 Connector on port 8080
+ -->
+
+ [PKI_UNSECURE_PORT_SERVER_COMMENT]
+ <Connector name="[PKI_UNSECURE_PORT_CONNECTOR_NAME]" port="[PKI_UNSECURE_PORT]" protocol="HTTP/1.1" redirectPort="8443"
+ maxHttpHeaderSize="8192"
+ acceptCount="100" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+ enableLookups="false" connectionTimeout="20000" disableUploadTimeout="true"
+ />
+
+ <!-- Define a SSL HTTP/1.1 Connector on port 8443 -->
+ [PKI_SECURE_PORT_SERVER_COMMENT]
+ <!-- DO NOT REMOVE - Begin define PKI secure port
+ NOTE: The OCSP settings take effect globally, so it should only be set once.
+
+ In setup where SSL clientAuth="true", OCSP can be turned on by
+ setting enableOCSP to true like the following:
+ enableOCSP="true"
+ along with changes to related settings, especially:
+ ocspResponderURL=<see example in connector definition below>
+ ocspResponderCertNickname=<see example in connector definition below>
+ Here are the definition to all the OCSP-related settings:
+ enableOCSP - turns on/off the ocsp check
+ ocspResponderURL - sets the url where the ocsp requests are sent
+ ocspResponderCertNickname - sets the nickname of the cert that is
+ either CA's signing certificate or the OCSP server's signing
+ certificate.
+ The CA's signing certificate should already be in the db, in
+ case of the same security domain.
+ In case of an ocsp signing certificate, one must import the cert
+ into the subsystem's nss db and set trust. e.g.:
+ certutil -d . -A -n "ocspSigningCert cert-pki-ca" -t "C,," -a -i ocspCert.b64
+ ocspCacheSize - sets max cache entries
+ ocspMinCacheEntryDuration - sets minimum seconds to next fetch attempt
+ ocspMaxCacheEntryDuration - sets maximum seconds to next fetch attempt
+ ocspTimeout -sets OCSP timeout in seconds
+ -->
+ <Connector name="[PKI_SECURE_PORT_CONNECTOR_NAME]" port="[PKI_SECURE_PORT]" protocol="HTTP/1.1" SSLEnabled="true" sslProtocol="SSL" scheme="https" secure="true"
+ maxHttpHeaderSize="8192"
+ acceptCount="100" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+ enableLookups="false" disableUploadTimeout="true"
+ SSLImplementation="org.apache.tomcat.util.net.jss.JSSImplementation"
+ enableOCSP="false"
+ ocspResponderURL="http://[PKI_MACHINE_NAME]:9080/ca/ocsp"
+ ocspResponderCertNickname="ocspSigningCert cert-pki-ca"
+ ocspCacheSize="1000"
+ ocspMinCacheEntryDuration="60"
+ ocspMaxCacheEntryDuration="120"
+ ocspTimeout="10"
+ strictCiphers="false"
+ clientAuth="[PKI_AGENT_CLIENTAUTH]"
+ sslOptions="[TOMCAT_SSL_OPTIONS]"
+ ssl2Ciphers="[TOMCAT_SSL2_CIPHERS]"
+ ssl3Ciphers="[TOMCAT_SSL3_CIPHERS]"
+ tlsCiphers="[TOMCAT_TLS_CIPHERS]"
+ serverCertNickFile="[PKI_INSTANCE_PATH]/conf/serverCertNick.conf"
+ passwordFile="[PKI_INSTANCE_PATH]/conf/password.conf"
+ passwordClass="org.apache.tomcat.util.net.jss.PlainPasswordFile"
+ certdbDir="[PKI_INSTANCE_PATH]/alias"
+ />
+ <!-- DO NOT REMOVE - End define PKI secure port -->
+
+ [PKI_OPEN_SEPARATE_PORTS_SERVER_COMMENT][PKI_ADMIN_SECURE_PORT_SERVER_COMMENT]
+ <Connector name="[PKI_ADMIN_SECURE_PORT_CONNECTOR_NAME]" port="[PKI_ADMIN_SECURE_PORT]" SSLEnabled="true" sslProtocol="SSL" scheme="https" secure="true"
+ maxHttpHeaderSize="8192"
+ acceptCount="100" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+ enableLookups="false" disableUploadTimeout="true"
+ SSLImplementation="org.apache.tomcat.util.net.jss.JSSImplementation"
+ strictCiphers="false"
+ clientAuth="false"
+ sslOptions="[TOMCAT_SSL_OPTIONS]"
+ ssl2Ciphers="[TOMCAT_SSL2_CIPHERS]"
+ ssl3Ciphers="[TOMCAT_SSL3_CIPHERS]"
+ tlsCiphers="[TOMCAT_TLS_CIPHERS]"
+ serverCertNickFile="[PKI_INSTANCE_PATH]/conf/serverCertNick.conf"
+ passwordFile="[PKI_INSTANCE_PATH]/conf/password.conf"
+ passwordClass="org.apache.tomcat.util.net.jss.PlainPasswordFile"
+ certdbDir="[PKI_INSTANCE_PATH]/alias"/>
+ [PKI_CLOSE_SEPARATE_PORTS_SERVER_COMMENT]
+
+ [PKI_OPEN_SEPARATE_PORTS_SERVER_COMMENT][PKI_EE_SECURE_PORT_SERVER_COMMENT]
+ <Connector name="[PKI_EE_SECURE_PORT_CONNECTOR_NAME]" port="[PKI_EE_SECURE_PORT]" SSLEnabled="true" sslProtocol="SSL" scheme="https" secure="true"
+ maxHttpHeaderSize="8192"
+ acceptCount="100" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+ enableLookups="false" disableUploadTimeout="true"
+ SSLImplementation="org.apache.tomcat.util.net.jss.JSSImplementation"
+ strictCiphers="false"
+ clientAuth="false"
+ sslOptions="[TOMCAT_SSL_OPTIONS]"
+ ssl2Ciphers="[TOMCAT_SSL2_CIPHERS]"
+ ssl3Ciphers="[TOMCAT_SSL3_CIPHERS]"
+ tlsCiphers="[TOMCAT_TLS_CIPHERS]"
+ serverCertNickFile="[PKI_INSTANCE_PATH]/conf/serverCertNick.conf"
+ passwordFile="[PKI_INSTANCE_PATH]/conf/password.conf"
+ passwordClass="org.apache.tomcat.util.net.jss.PlainPasswordFile"
+ certdbDir="[PKI_INSTANCE_PATH]/alias"/>
+ [PKI_CLOSE_SEPARATE_PORTS_SERVER_COMMENT]
+
+ [PKI_OPEN_SEPARATE_PORTS_SERVER_COMMENT][PKI_EE_SECURE_CLIENT_AUTH_PORT_SERVER_COMMENT]
+ <Connector name="[PKI_EE_SECURE_CLIENT_AUTH_PORT_CONNECTOR_NAME]" port="[PKI_EE_SECURE_CLIENT_AUTH_PORT]" SSLEnabled="true" sslProtocol="SSL" scheme="https" secure="true"
+ maxHttpHeaderSize="8192"
+ acceptCount="100" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+ enableLookups="false" disableUploadTimeout="true"
+ SSLImplementation="org.apache.tomcat.util.net.jss.JSSImplementation"
+ strictCiphers="false"
+ clientAuth="true"
+ sslOptions="[TOMCAT_SSL_OPTIONS]"
+ ssl2Ciphers="[TOMCAT_SSL2_CIPHERS]"
+ ssl3Ciphers="[TOMCAT_SSL3_CIPHERS]"
+ tlsCiphers="[TOMCAT_TLS_CIPHERS]"
+ serverCertNickFile="[PKI_INSTANCE_PATH]/conf/serverCertNick.conf"
+ passwordFile="[PKI_INSTANCE_PATH]/conf/password.conf"
+ passwordClass="org.apache.tomcat.util.net.jss.PlainPasswordFile"
+ certdbDir="[PKI_INSTANCE_PATH]/alias"/>
+ [PKI_CLOSE_SEPARATE_PORTS_SERVER_COMMENT]
+
+ <!-- A "Connector" using the shared thread pool-->
+ <!--
+ <Connector executor="tomcatThreadPool"
+ port="8080" protocol="HTTP/1.1"
+ connectionTimeout="20000"
+ redirectPort="8443" />
+ -->
+ <!-- Define a SSL HTTP/1.1 Connector on port 8443
+ This connector uses the JSSE configuration, when using APR, the
+ connector should be using the OpenSSL style configuration
+ described in the APR documentation -->
+ <!--
+ <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
+ maxThreads="150" scheme="https" secure="true"
+ clientAuth="false" sslProtocol="TLS" />
+ -->
+
+ <!-- Define an AJP 1.3 Connector on port [PKI_AJP_PORT] -->
+[PKI_OPEN_AJP_PORT_COMMENT]
+ <Connector port="[PKI_AJP_PORT]" protocol="AJP/1.3" redirectPort="[PKI_AJP_REDIRECT_PORT]" />
+[PKI_CLOSE_AJP_PORT_COMMENT]
+
+
+ <!-- An Engine represents the entry point (within Catalina) that processes
+ every request. The Engine implementation for Tomcat stand alone
+ analyzes the HTTP headers included with the request, and passes them
+ on to the appropriate Host (virtual host).
+ Documentation at /docs/config/engine.html -->
+
+ <!-- You should set jvmRoute to support load-balancing via AJP ie :
+ <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
+ -->
+ <Engine name="Catalina" defaultHost="localhost">
+
+ <!--For clustering, please take a look at documentation at:
+ /docs/cluster-howto.html (simple how to)
+ /docs/config/cluster.html (reference documentation) -->
+ <!--
+ <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
+ -->
+
+ <!-- The request dumper valve dumps useful debugging information about
+ the request and response data received and sent by Tomcat.
+ Documentation at: /docs/config/valve.html -->
+ <!--
+ <Valve className="org.apache.catalina.valves.RequestDumperValve"/>
+ -->
+
+ <!-- This Realm uses the UserDatabase configured in the global JNDI
+ resources under the key "UserDatabase". Any edits
+ that are performed against this UserDatabase are immediately
+ available for use by the Realm. -->
+ <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+ resourceName="UserDatabase"/>
+
+ <!-- Define the default virtual host
+ Note: XML Schema validation will not work with Xerces 2.2.
+ -->
+ <Host name="localhost" appBase="webapps"
+ unpackWARs="true" autoDeploy="false"
+ xmlValidation="false" xmlNamespaceAware="false">
+
+ <!-- SingleSignOn valve, share authentication between web applications
+ Documentation at: /docs/config/valve.html -->
+ <!--
+ <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
+ -->
+
+ <!-- Access log processes all example.
+ Documentation at: /docs/config/valve.html -->
+ <!--
+ <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
+ prefix="localhost_access_log." suffix=".txt" pattern="common" resolveHosts="false"/>
+ -->
+
+ </Host>
+ </Engine>
+ </Service>
+</Server>
diff --git a/base/ca/shared/conf/serverCert.profile b/base/ca/shared/conf/serverCert.profile
new file mode 100644
index 000000000..8b436b247
--- /dev/null
+++ b/base/ca/shared/conf/serverCert.profile
@@ -0,0 +1,39 @@
+#
+# Server Certificate
+#
+id=serverCert.profile
+name=All Purpose SSL server cert Profile
+description=This profile creates an SSL server certificate that is valid for SSL servers
+profileIDMapping=caServerCert
+profileSetIDMapping=serverCertSet
+list=2,4,5,6,7
+2.default.class=com.netscape.cms.profile.def.ValidityDefault
+2.default.name=Validity Default
+2.default.params.range=720
+2.default.params.startTime=0
+4.default.class=com.netscape.cms.profile.def.AuthorityKeyIdentifierExtDefault
+4.default.name=Authority Key Identifier Default
+5.default.class=com.netscape.cms.profile.def.AuthInfoAccessExtDefault
+5.default.name=AIA Extension Default
+5.default.params.authInfoAccessADEnable_0=true
+5.default.params.authInfoAccessADLocationType_0=URIName
+5.default.params.authInfoAccessADLocation_0=
+5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+5.default.params.authInfoAccessCritical=false
+5.default.params.authInfoAccessNumADs=1
+6.default.class=com.netscape.cms.profile.def.KeyUsageExtDefault
+6.default.name=Key Usage Default
+6.default.params.keyUsageCritical=true
+6.default.params.keyUsageDigitalSignature=true
+6.default.params.keyUsageNonRepudiation=true
+6.default.params.keyUsageDataEncipherment=true
+6.default.params.keyUsageKeyEncipherment=true
+6.default.params.keyUsageKeyAgreement=false
+6.default.params.keyUsageKeyCertSign=false
+6.default.params.keyUsageCrlSign=false
+6.default.params.keyUsageEncipherOnly=false
+6.default.params.keyUsageDecipherOnly=false
+7.default.class=com.netscape.cms.profile.def.ExtendedKeyUsageExtDefault
+7.default.name=Extended Key Usage Extension Default
+7.default.params.exKeyUsageCritical=false
+7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.1
diff --git a/base/ca/shared/conf/serverCertNick.conf b/base/ca/shared/conf/serverCertNick.conf
new file mode 100644
index 000000000..1b1f4fcad
--- /dev/null
+++ b/base/ca/shared/conf/serverCertNick.conf
@@ -0,0 +1 @@
+Server-Cert cert-[PKI_INSTANCE_ID]
diff --git a/base/ca/shared/conf/shm.manifest b/base/ca/shared/conf/shm.manifest
new file mode 100644
index 000000000..0505c085b
--- /dev/null
+++ b/base/ca/shared/conf/shm.manifest
@@ -0,0 +1,2 @@
+Main-Class: org.apache.jk.common.Shm
+Class-Path: tomcat-jk2.jar commons-logging.jar tomcat-util.jar log4j.jar log4j-core.jar
diff --git a/base/ca/shared/conf/subsystemCert.profile b/base/ca/shared/conf/subsystemCert.profile
new file mode 100644
index 000000000..658e69511
--- /dev/null
+++ b/base/ca/shared/conf/subsystemCert.profile
@@ -0,0 +1,39 @@
+#
+# Server Certificate
+#
+id=serverCert.profile
+name=All Purpose SSL server cert Profile
+description=This profile creates an SSL server certificate that is valid for SSL servers
+profileIDMapping=caServerCert
+profileSetIDMapping=serverCertSet
+list=2,4,5,6,7
+2.default.class=com.netscape.cms.profile.def.ValidityDefault
+2.default.name=Validity Default
+2.default.params.range=720
+2.default.params.startTime=0
+4.default.class=com.netscape.cms.profile.def.AuthorityKeyIdentifierExtDefault
+4.default.name=Authority Key Identifier Default
+5.default.class=com.netscape.cms.profile.def.AuthInfoAccessExtDefault
+5.default.name=AIA Extension Default
+5.default.params.authInfoAccessADEnable_0=true
+5.default.params.authInfoAccessADLocationType_0=URIName
+5.default.params.authInfoAccessADLocation_0=
+5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+5.default.params.authInfoAccessCritical=false
+5.default.params.authInfoAccessNumADs=1
+6.default.class=com.netscape.cms.profile.def.KeyUsageExtDefault
+6.default.name=Key Usage Default
+6.default.params.keyUsageCritical=true
+6.default.params.keyUsageDigitalSignature=true
+6.default.params.keyUsageNonRepudiation=true
+6.default.params.keyUsageDataEncipherment=true
+6.default.params.keyUsageKeyEncipherment=true
+6.default.params.keyUsageKeyAgreement=false
+6.default.params.keyUsageKeyCertSign=false
+6.default.params.keyUsageCrlSign=false
+6.default.params.keyUsageEncipherOnly=false
+6.default.params.keyUsageDecipherOnly=false
+7.default.class=com.netscape.cms.profile.def.ExtendedKeyUsageExtDefault
+7.default.name=Extended Key Usage Extension Default
+7.default.params.exKeyUsageCritical=false
+7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2
diff --git a/base/ca/shared/conf/tomcat-jk2.manifest b/base/ca/shared/conf/tomcat-jk2.manifest
new file mode 100644
index 000000000..acfef4a90
--- /dev/null
+++ b/base/ca/shared/conf/tomcat-jk2.manifest
@@ -0,0 +1,7 @@
+Manifest-version: 1.0
+Extension-Name: org.apache.jk
+Specification-Vendor: Apache Software Foundation
+Specification-Version: 2.0
+Implementation-Vendor-Id: org.apache
+Implementation-Vendor: Apache Software Foundation
+Implementation-Version: 2.1
diff --git a/base/ca/shared/conf/tomcat-users.xml b/base/ca/shared/conf/tomcat-users.xml
new file mode 100644
index 000000000..daa9260cc
--- /dev/null
+++ b/base/ca/shared/conf/tomcat-users.xml
@@ -0,0 +1,45 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2006-2010 Red Hat, Inc.
+ All rights reserved.
+ Modifications: configuration parameters
+ END COPYRIGHT BLOCK -->
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+ <role rolename="tomcat"/>
+ <role rolename="role1"/>
+ <user username="tomcat" password="tomcat" roles="tomcat"/>
+ <user username="both" password="tomcat" roles="tomcat,role1"/>
+ <user username="role1" password="tomcat" roles="role1"/>
+-->
+
+<!-- The host manager webapp is restricted to users with role "admin" -->
+<!--<user name="tomcat" password="password" roles="admin" />-->
+<!-- The manager webapp is restricted to users with role "manager" -->
+<!--<user name="tomcat" password="password" roles="manager" />-->
+<tomcat-users>
+ <role rolename="pkiuser"/>
+ <role rolename="tomcat"/>
+ <role rolename="manager"/>
+ <role rolename="admin"/>
+
+ <user username="pkiuser" password="pkiuser" roles="pkiuser"/>
+ <user username="tomcat" password="tomcat" roles="tomcat"/>
+ <user username="admin" password="netscape" roles="admin,manager"/>
+</tomcat-users>
diff --git a/base/ca/shared/conf/tomcat6.conf b/base/ca/shared/conf/tomcat6.conf
new file mode 100644
index 000000000..2d7def5ec
--- /dev/null
+++ b/base/ca/shared/conf/tomcat6.conf
@@ -0,0 +1,58 @@
+# Service-specific configuration file for tomcat6. This will be sourced by
+# the SysV init script after the global configuration file
+# /etc/tomcat6/tomcat6.conf, thus allowing values to be overridden in
+# a per-service manner.
+#
+# NEVER change the init script itself. To change values for all services make
+# your changes in /etc/tomcat6/tomcat6.conf
+#
+# To change values for a specific service make your edits here.
+# To create a new service create a link from /etc/init.d/<your new service> to
+# /etc/init.d/tomcat6 (do not copy the init script) and make a copy of the
+# /etc/sysconfig/tomcat6 file to /etc/sysconfig/<your new service> and change
+# the property values so the two services won't conflict. Register the new
+# service in the system as usual (see chkconfig and similars).
+#
+
+# Where your java installation lives
+#JAVA_HOME="/usr/lib/jvm/java"
+
+# Where your tomcat installation lives
+CATALINA_BASE="[PKI_INSTANCE_PATH]"
+#CATALINA_HOME="/usr/share/tomcat6"
+#JASPER_HOME="/usr/share/tomcat6"
+#CATALINA_TMPDIR="/var/cache/tomcat6/temp"
+
+# You can pass some parameters to java here if you wish to
+#JAVA_OPTS="-Xminf0.1 -Xmaxf0.3"
+
+# Use JAVA_OPTS to set java.library.path for libtcnative.so
+#JAVA_OPTS="-Djava.library.path=/usr/lib64"
+
+# What user should run tomcat
+TOMCAT_USER="[PKI_USER]"
+
+# You can change your tomcat locale here
+#LANG="en_US"
+
+# Run tomcat under the Java Security Manager
+#SECURITY_MANAGER="false"
+
+# Time to wait in seconds, before killing process
+#SHUTDOWN_WAIT="30"
+
+# Whether to annoy the user with "attempting to shut down" messages or not
+#SHUTDOWN_VERBOSE="false"
+
+# Set the TOMCAT_PID location
+CATALINA_PID="[TOMCAT_PIDFILE]"
+
+# Set the tomcat log file
+TOMCAT_LOG="[TOMCAT_LOG_DIR]/tomcat-initd.log"
+
+# Connector port is 8080 for this tomcat6 instance
+#CONNECTOR_PORT="8080"
+
+# If you wish to further customize your tomcat environment,
+# put your own definitions here
+# (i.e. LD_LIBRARY_PATH for some jdbc drivers)
diff --git a/base/ca/shared/conf/uriworkermap.properties b/base/ca/shared/conf/uriworkermap.properties
new file mode 100644
index 000000000..c65445b10
--- /dev/null
+++ b/base/ca/shared/conf/uriworkermap.properties
@@ -0,0 +1,13 @@
+# uriworkermap.properties - IIS
+#
+# This file provides sample mappings for example ajp13w
+# worker defined in workermap.properties.minimal
+# The general sytax for this file is:
+# [URL]=[Worker name]
+
+/servlet-examples/*=ajp13w
+
+# Optionally filter out all .jpeg files inside that context
+# For no mapping the url has to start with exclamation (!)
+
+!/servlet-examples/*.jpeg=ajp13w
diff --git a/base/ca/shared/conf/vlv.ldif b/base/ca/shared/conf/vlv.ldif
new file mode 100644
index 000000000..a3b574608
--- /dev/null
+++ b/base/ca/shared/conf/vlv.ldif
@@ -0,0 +1,544 @@
+dn: cn=allCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: allCerts-{instanceId}
+vlvBase: ou=certificateRepository,ou=ca,{rootSuffix}
+vlvScope: 1
+vlvFilter: (certstatus=*)
+
+dn: cn=allExpiredCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: allExpiredCerts-{instanceId}
+vlvBase: ou=certificateRepository,ou=ca,{rootSuffix}
+vlvScope: 1
+vlvFilter: (certstatus=EXPIRED)
+
+dn: cn=allInvalidCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: allInvalidCerts-{instanceId}
+vlvBase: ou=certificateRepository,ou=ca,{rootSuffix}
+vlvScope: 1
+vlvFilter: (certstatus=INVALID)
+
+dn: cn=allInValidCertsNotBefore-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: allInValidCertsNotBefore-{instanceId}
+vlvBase: ou=certificateRepository,ou=ca,{rootSuffix}
+vlvScope: 1
+vlvFilter: (certstatus=INVALID)
+
+dn: cn=allNonRevokedCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: allNonRevokedCerts-{instanceId}
+vlvBase: ou=certificateRepository,ou=ca,{rootSuffix}
+vlvScope: 1
+vlvFilter: (|(certstatus=VALID)(certstatus=INVALID)(certstatus=EXPIRED))
+
+dn: cn=allRevokedCaCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: allRevokedCaCerts-{instanceId}
+vlvBase: ou=certificateRepository,ou=ca,{rootSuffix}
+vlvScope: 1
+vlvFilter: (&(certStatus=REVOKED)(extension=2.5.29.19;*isCA=true*))
+
+dn: cn=allRevokedCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: allRevokedCerts-{instanceId}
+vlvBase: ou=certificateRepository,ou=ca,{rootSuffix}
+vlvScope: 1
+vlvFilter: (certstatus=REVOKED)
+
+dn: cn=allRevokedCertsNotAfter-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: allRevokedCertsNotAfter-{instanceId}
+vlvBase: ou=certificateRepository,ou=ca,{rootSuffix}
+vlvScope: 1
+vlvFilter: (certstatus=REVOKED)
+
+dn: cn=allRevokedExpiredCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: allRevokedExpiredCerts-{instanceId}
+vlvBase: ou=certificateRepository,ou=ca,{rootSuffix}
+vlvScope: 1
+vlvFilter: (certstatus=REVOKED_EXPIRED)
+
+dn: cn=allRevokedOrRevokedExpiredCaCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: allRevokedOrRevokedExpiredCaCerts-{instanceId}
+vlvBase: ou=certificateRepository,ou=ca,{rootSuffix}
+vlvScope: 1
+vlvFilter: (&(|(certStatus=REVOKED)(certStatus=REVOKED_EXPIRED))(extension=2.5.29.19;*isCA=true*))
+
+dn: cn=allRevokedOrRevokedExpiredCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: allRevokedOrRevokedExpiredCerts-{instanceId}
+vlvBase: ou=certificateRepository,ou=ca,{rootSuffix}
+vlvScope: 1
+vlvFilter: (|(certstatus=REVOKED)(certstatus=REVOKED_EXPIRED))
+
+dn: cn=allValidCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: allValidCerts-{instanceId}
+vlvBase: ou=certificateRepository,ou=ca,{rootSuffix}
+vlvScope: 1
+vlvFilter: (certstatus=VALID)
+
+dn: cn=allValidCertsNotAfter-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: allValidCertsNotAfter-{instanceId}
+vlvBase: ou=certificateRepository,ou=ca,{rootSuffix}
+vlvScope: 1
+vlvFilter: (certstatus=VALID)
+
+dn: cn=allValidOrRevokedCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: allValidOrRevokedCerts-{instanceId}
+vlvBase: ou=certificateRepository,ou=ca,{rootSuffix}
+vlvScope: 1
+vlvFilter: (|(certstatus=VALID)(certstatus=REVOKED))
+
+dn: cn=caAll-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: caAll-{instanceId}
+vlvBase: ou=ca,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (requeststate=*)
+
+dn: cn=caCanceled-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: caCanceled-{instanceId}
+vlvBase: ou=ca,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (requeststate=canceled)
+
+dn: cn=caCanceledEnrollment-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: caCanceledEnrollment-{instanceId}
+vlvBase: ou=ca,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (&(requeststate=canceled)(requesttype=enrollment))
+
+dn: cn=caCanceledRenewal-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: caCanceledRenewal-{instanceId}
+vlvBase: ou=ca,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (&(requeststate=canceled)(requesttype=renewal))
+
+dn: cn=caCanceledRevocation-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: caCanceledRevocation-{instanceId}
+vlvBase: ou=ca,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (&(requeststate=canceled)(requesttype=revocation))
+
+dn: cn=caComplete-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: caComplete-{instanceId}
+vlvBase: ou=ca,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (requeststate=complete)
+
+dn: cn=caCompleteEnrollment-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: caCompleteEnrollment-{instanceId}
+vlvBase: ou=ca,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (&(requeststate=complete)(requesttype=enrollment))
+
+dn: cn=caCompleteRenewal-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: caCompleteRenewal-{instanceId}
+vlvBase: ou=ca,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (&(requeststate=complete)(requesttype=renewal))
+
+dn: cn=caCompleteRevocation-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: caCompleteRevocation-{instanceId}
+vlvBase: ou=ca,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (&(requeststate=complete)(requesttype=revocation))
+
+dn: cn=caEnrollment-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: caEnrollment-{instanceId}
+vlvBase: ou=ca,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (requesttype=enrollment)
+
+dn: cn=caPending-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: caPending-{instanceId}
+vlvBase: ou=ca,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (requeststate=pending)
+
+dn: cn=caPendingEnrollment-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: caPendingEnrollment-{instanceId}
+vlvBase: ou=ca,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (&(requeststate=pending)(requesttype=enrollment))
+
+dn: cn=caPendingRenewal-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: caPendingRenewal-{instanceId}
+vlvBase: ou=ca,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (&(requeststate=pending)(requesttype=renewal))
+
+dn: cn=caPendingRevocation-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: caPendingRevocation-{instanceId}
+vlvBase: ou=ca,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (&(requeststate=pending)(requesttype=revocation))
+
+dn: cn=caRejected-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: caRejected-{instanceId}
+vlvBase: ou=ca,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (requeststate=rejected)
+
+dn: cn=caRejectedEnrollment-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: caRejectedEnrollment-{instanceId}
+vlvBase: ou=ca,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (&(requeststate=rejected)(requesttype=enrollment))
+
+dn: cn=caRejectedRenewal-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: caRejectedRenewal-{instanceId}
+vlvBase: ou=ca,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (&(requeststate=rejected)(requesttype=renewal))
+
+dn: cn=caRejectedRevocation-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: caRejectedRevocation-{instanceId}
+vlvBase: ou=ca,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (&(requeststate=rejected)(requesttype=revocation))
+
+dn: cn=caRenewal-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: caRenewal-{instanceId}
+vlvBase: ou=ca,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (requesttype=renewal)
+
+dn: cn=caRevocation-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: caRevocation-{instanceId}
+vlvBase: ou=ca,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (requesttype=revocation)
+
+dn: cn=allCerts-{instanceId}Index, cn=allCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: allCerts-{instanceId}Index
+vlvSort: serialno
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=allExpiredCerts-{instanceId}Index, cn=allExpiredCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: allExpiredCerts-{instanceId}Index
+vlvSort: serialno
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=allInvalidCerts-{instanceId}Index, cn=allInvalidCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: allInvalidCerts-{instanceId}Index
+vlvSort: serialno
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=allInValidCertsNotBefore-{instanceId}Index, cn=allInValidCertsNotBefore-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: allInValidCertsNotBefore-{instanceId}Index
+vlvSort: notBefore
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=allNonRevokedCerts-{instanceId}Index, cn=allNonRevokedCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: allNonRevokedCerts-{instanceId}Index
+vlvSort: serialno
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=allRevokedCaCerts-{instanceId}Index, cn=allRevokedCaCerts-{instanceId}, cn={database}, cn=ldb
+ m database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: allRevokedCaCerts-{instanceId}Index
+vlvSort: serialno
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=allRevokedCerts-{instanceId}Index, cn=allRevokedCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: allRevokedCerts-{instanceId}Index
+vlvSort: serialno
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=allRevokedCertsNotAfter-{instanceId}Index, cn=allRevokedCertsNotAfter-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: allRevokedCertsNotAfter-{instanceId}Index
+vlvSort: notAfter
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=allRevokedExpiredCerts-{instanceId}Index, cn=allRevokedExpiredCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: allRevokedExpiredCerts-{instanceId}Index
+vlvSort: serialno
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=allRevokedOrRevokedExpiredCaCerts-{instanceId}Index, cn=allRevokedOrRevokedExpiredCaCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: allRevokedOrRevokedExpiredCaCerts-{instanceId}Index
+vlvSort: serialno
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=allRevokedOrRevokedExpiredCerts-{instanceId}Index, cn=allRevokedOrRevokedExpiredCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: allRevokedOrRevokedExpiredCerts-{instanceId}Index
+vlvSort: serialno
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=allValidCerts-{instanceId}Index, cn=allValidCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: allValidCerts-{instanceId}Index
+vlvSort: serialno
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=allValidCertsNotAfter-{instanceId}Index, cn=allValidCertsNotAfter-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: allValidCertsNotAfter-{instanceId}Index
+vlvSort: notAfter
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=allValidOrRevokedCerts-{instanceId}Index, cn=allValidOrRevokedCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: allValidOrRevokedCerts-{instanceId}Index
+vlvSort: serialno
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=caAll-{instanceId}Index, cn=caAll-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: caAll-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=caCanceled-{instanceId}Index, cn=caCanceled-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: caCanceled-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=caCanceledEnrollment-{instanceId}Index, cn=caCanceledEnrollment-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: caCanceledEnrollment-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=caCanceledRenewal-{instanceId}Index, cn=caCanceledRenewal-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: caCanceledRenewal-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=caCanceledRevocation-{instanceId}Index, cn=caCanceledRevocation-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: caCanceledRevocation-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=caComplete-{instanceId}Index, cn=caComplete-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: caComplete-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=caCompleteEnrollment-{instanceId}Index, cn=caCompleteEnrollment-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: caCompleteEnrollment-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=caCompleteRenewal-{instanceId}Index, cn=caCompleteRenewal-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: caCompleteRenewal-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=caCompleteRevocation-{instanceId}Index, cn=caCompleteRevocation-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: caCompleteRevocation-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=caEnrollment-{instanceId}Index, cn=caEnrollment-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: caEnrollment-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=caPending-{instanceId}Index, cn=caPending-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: caPending-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=caPendingEnrollment-{instanceId}Index, cn=caPendingEnrollment-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: caPendingEnrollment-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=caPendingRenewal-{instanceId}Index, cn=caPendingRenewal-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: caPendingRenewal-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=caPendingRevocation-{instanceId}Index, cn=caPendingRevocation-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: caPendingRevocation-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=caRejected-{instanceId}Index, cn=caRejected-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: caRejected-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=caRejectedEnrollment-{instanceId}Index, cn=caRejectedEnrollment-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: caRejectedEnrollment-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=caRejectedRenewal-{instanceId}Index, cn=caRejectedRenewal-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: caRejectedRenewal-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=caRejectedRevocation-{instanceId}Index, cn=caRejectedRevocation-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: caRejectedRevocation-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=caRenewal-{instanceId}Index, cn=caRenewal-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: caRenewal-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=caRevocation-{instanceId}Index, cn=caRevocation-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: caRevocation-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
diff --git a/base/ca/shared/conf/vlvtasks.ldif b/base/ca/shared/conf/vlvtasks.ldif
new file mode 100644
index 000000000..5458e8a28
--- /dev/null
+++ b/base/ca/shared/conf/vlvtasks.ldif
@@ -0,0 +1,40 @@
+dn: cn=index1160589769, cn=index, cn=tasks, cn=config
+objectclass: top
+objectclass: extensibleObject
+cn: index1160589769
+ttl: 10
+nsInstance: {database}
+nsIndexVLVAttribute: allCerts-{instanceId}Index
+nsIndexVLVAttribute: allExpiredCerts-{instanceId}Index
+nsIndexVLVAttribute: allInvalidCerts-{instanceId}Index
+nsIndexVLVAttribute: allInValidCertsNotBefore-{instanceId}Index
+nsIndexVLVAttribute: allNonRevokedCerts-{instanceId}Index
+nsIndexVLVAttribute: allRevokedCaCerts-{instanceId}Index
+nsIndexVLVAttribute: allRevokedCerts-{instanceId}Index
+nsIndexVLVAttribute: allRevokedCertsNotAfter-{instanceId}Index
+nsIndexVLVAttribute: allRevokedExpiredCerts-{instanceId}Index
+nsIndexVLVAttribute: allRevokedOrRevokedExpiredCaCerts-{instanceId}Index
+nsIndexVLVAttribute: allRevokedOrRevokedExpiredCerts-{instanceId}Index
+nsIndexVLVAttribute: allValidCerts-{instanceId}Index
+nsIndexVLVAttribute: allValidCertsNotAfter-{instanceId}Index
+nsIndexVLVAttribute: allValidOrRevokedCerts-{instanceId}Index
+nsIndexVLVAttribute: caAll-{instanceId}Index
+nsIndexVLVAttribute: caCanceled-{instanceId}Index
+nsIndexVLVAttribute: caCanceledEnrollment-{instanceId}Index
+nsIndexVLVAttribute: caCanceledRenewal-{instanceId}Index
+nsIndexVLVAttribute: caCanceledRevocation-{instanceId}Index
+nsIndexVLVAttribute: caComplete-{instanceId}Index
+nsIndexVLVAttribute: caCompleteEnrollment-{instanceId}Index
+nsIndexVLVAttribute: caCompleteRenewal-{instanceId}Index
+nsIndexVLVAttribute: caCompleteRevocation-{instanceId}Index
+nsIndexVLVAttribute: caEnrollment-{instanceId}Index
+nsIndexVLVAttribute: caPending-{instanceId}Index
+nsIndexVLVAttribute: caPendingEnrollment-{instanceId}Index
+nsIndexVLVAttribute: caPendingRenewal-{instanceId}Index
+nsIndexVLVAttribute: caPendingRevocation-{instanceId}Index
+nsIndexVLVAttribute: caRejected-{instanceId}Index
+nsIndexVLVAttribute: caRejectedEnrollment-{instanceId}Index
+nsIndexVLVAttribute: caRejectedRenewal-{instanceId}Index
+nsIndexVLVAttribute: caRejectedRevocation-{instanceId}Index
+nsIndexVLVAttribute: caRenewal-{instanceId}Index
+nsIndexVLVAttribute: caRevocation-{instanceId}Index
diff --git a/base/ca/shared/conf/web.xml b/base/ca/shared/conf/web.xml
new file mode 100644
index 000000000..fb22468ee
--- /dev/null
+++ b/base/ca/shared/conf/web.xml
@@ -0,0 +1,989 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+ version="2.4">
+
+ <!-- ======================== Introduction ============================== -->
+ <!-- This document defines default values for *all* web applications -->
+ <!-- loaded into this instance of Tomcat. As each application is -->
+ <!-- deployed, this file is processed, followed by the -->
+ <!-- "/WEB-INF/web.xml" deployment descriptor from your own -->
+ <!-- applications. -->
+ <!-- -->
+ <!-- WARNING: Do not configure application-specific resources here! -->
+ <!-- They should go in the "/WEB-INF/web.xml" file in your application. -->
+
+
+ <!-- ================== Built In Servlet Definitions ==================== -->
+
+
+ <!-- The default servlet for all web applications, that serves static -->
+ <!-- resources. It processes all requests that are not mapped to other -->
+ <!-- servlets with servlet mappings (defined either here or in your own -->
+ <!-- web.xml file. This servlet supports the following initialization -->
+ <!-- parameters (default values are in square brackets): -->
+ <!-- -->
+ <!-- debug Debugging detail level for messages logged -->
+ <!-- by this servlet. [0] -->
+ <!-- -->
+ <!-- fileEncoding Encoding to be used to read static resources -->
+ <!-- [platform default] -->
+ <!-- -->
+ <!-- input Input buffer size (in bytes) when reading -->
+ <!-- resources to be served. [2048] -->
+ <!-- -->
+ <!-- listings Should directory listings be produced if there -->
+ <!-- is no welcome file in this directory? [true] -->
+ <!-- -->
+ <!-- output Output buffer size (in bytes) when writing -->
+ <!-- resources to be served. [2048] -->
+ <!-- -->
+ <!-- readonly Is this context "read only", so HTTP -->
+ <!-- commands like PUT and DELETE are -->
+ <!-- rejected? [true] -->
+ <!-- -->
+ <!-- readmeFile File name to display with the directory -->
+ <!-- contents. [null] -->
+ <!-- -->
+ <!-- For directory listing customization. Checks localXsltFile, then -->
+ <!-- globalXsltFile, then defaults to original behavior. -->
+ <!-- -->
+ <!-- localXsltFile Make directory listings an XML doc and -->
+ <!-- pass the result to this style sheet residing -->
+ <!-- in that directory. This overrides -->
+ <!-- globalXsltFile[null] -->
+ <!-- -->
+ <!-- globalXsltFile Site wide configuration version of -->
+ <!-- localXsltFile This argument is expected -->
+ <!-- to be a physical file. [null] -->
+ <!-- -->
+ <!-- -->
+
+ <servlet>
+ <servlet-name>default</servlet-name>
+ <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
+ <init-param>
+ <param-name>debug</param-name>
+ <param-value>0</param-value>
+ </init-param>
+ <init-param>
+ <param-name>listings</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+
+ <!-- The "invoker" servlet, which executes anonymous servlet classes -->
+ <!-- that have not been defined in a web.xml file. Traditionally, this -->
+ <!-- servlet is mapped to the URL pattern "/servlet/*", but you can map -->
+ <!-- it to other patterns as well. The extra path info portion of such a -->
+ <!-- request must be the fully qualified class name of a Java class that -->
+ <!-- implements Servlet (or extends HttpServlet), or the servlet name -->
+ <!-- of an existing servlet definition. This servlet supports the -->
+ <!-- following initialization parameters (default values are in square -->
+ <!-- brackets): -->
+ <!-- -->
+ <!-- debug Debugging detail level for messages logged -->
+ <!-- by this servlet. [0] -->
+
+<!--
+ <servlet>
+ <servlet-name>invoker</servlet-name>
+ <servlet-class>
+ org.apache.catalina.servlets.InvokerServlet
+ </servlet-class>
+ <init-param>
+ <param-name>debug</param-name>
+ <param-value>0</param-value>
+ </init-param>
+ <load-on-startup>2</load-on-startup>
+ </servlet>
+-->
+
+
+ <!-- The JSP page compiler and execution servlet, which is the mechanism -->
+ <!-- used by Tomcat to support JSP pages. Traditionally, this servlet -->
+ <!-- is mapped to the URL pattern "*.jsp". This servlet supports the -->
+ <!-- following initialization parameters (default values are in square -->
+ <!-- brackets): -->
+ <!-- -->
+ <!-- checkInterval If development is false and checkInterval is -->
+ <!-- greater than zero, background compilations are -->
+ <!-- enabled. checkInterval is the time in seconds -->
+ <!-- between checks to see if a JSP page needs to -->
+ <!-- be recompiled. [0] -->
+ <!-- -->
+ <!-- modificationTestInterval -->
+ <!-- Causes a JSP (and its dependent files) to not -->
+ <!-- be checked for modification during the -->
+ <!-- specified time interval (in seconds) from the -->
+ <!-- last time the JSP was checked for -->
+ <!-- modification. A value of 0 will cause the JSP -->
+ <!-- to be checked on every access. -->
+ <!-- Used in development mode only. [4] -->
+ <!-- -->
+ <!-- compiler Which compiler Ant should use to compile JSP -->
+ <!-- pages. See the Ant documentation for more -->
+ <!-- information. [javac] -->
+ <!-- -->
+ <!-- classdebuginfo Should the class file be compiled with -->
+ <!-- debugging information? [true] -->
+ <!-- -->
+ <!-- classpath What class path should I use while compiling -->
+ <!-- generated servlets? [Created dynamically -->
+ <!-- based on the current web application] -->
+ <!-- -->
+ <!-- development Is Jasper used in development mode? If true, -->
+ <!-- the frequency at which JSPs are checked for -->
+ <!-- modification may be specified via the -->
+ <!-- modificationTestInterval parameter. [true] -->
+ <!-- -->
+ <!-- enablePooling Determines whether tag handler pooling is -->
+ <!-- enabled [true] -->
+ <!-- -->
+ <!-- fork Tell Ant to fork compiles of JSP pages so that -->
+ <!-- a separate JVM is used for JSP page compiles -->
+ <!-- from the one Tomcat is running in. [true] -->
+ <!-- -->
+ <!-- ieClassId The class-id value to be sent to Internet -->
+ <!-- Explorer when using <jsp:plugin> tags. -->
+ <!-- [clsid:8AD9C840-044E-11D1-B3E9-00805F499D93] -->
+ <!-- -->
+ <!-- javaEncoding Java file encoding to use for generating java -->
+ <!-- source files. [UTF8] -->
+ <!-- -->
+ <!-- keepgenerated Should we keep the generated Java source code -->
+ <!-- for each page instead of deleting it? [true] -->
+ <!-- -->
+ <!-- mappedfile Should we generate static content with one -->
+ <!-- print statement per input line, to ease -->
+ <!-- debugging? [true] -->
+ <!-- -->
+ <!-- trimSpaces Should white spaces in template text between -->
+ <!-- actions or directives be trimmed? [false] -->
+ <!-- -->
+ <!-- suppressSmap Should the generation of SMAP info for JSR45 -->
+ <!-- debugging be suppressed? [false] -->
+ <!-- -->
+ <!-- dumpSmap Should the SMAP info for JSR45 debugging be -->
+ <!-- dumped to a file? [false] -->
+ <!-- False if suppressSmap is true -->
+ <!-- -->
+ <!-- genStrAsCharArray Should text strings be generated as char -->
+ <!-- arrays, to improve performance in some cases? -->
+ <!-- [false] -->
+ <!-- -->
+ <!-- errorOnUseBeanInvalidClassAttribute -->
+ <!-- Should Jasper issue an error when the value of -->
+ <!-- the class attribute in an useBean action is -->
+ <!-- not a valid bean class? [true] -->
+ <!-- -->
+ <!-- scratchdir What scratch directory should we use when -->
+ <!-- compiling JSP pages? [default work directory -->
+ <!-- for the current web application] -->
+ <!-- -->
+ <!-- xpoweredBy Determines whether X-Powered-By response -->
+ <!-- header is added by generated servlet [false] -->
+ <!-- -->
+ <!-- If you wish to use Jikes to compile JSP pages: -->
+ <!-- Please see the "Using Jikes" section of the Jasper-HowTo -->
+ <!-- page in the Tomcat documentation. -->
+
+ <servlet>
+ <servlet-name>jsp</servlet-name>
+ <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
+ <init-param>
+ <param-name>fork</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ <init-param>
+ <param-name>xpoweredBy</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ <load-on-startup>3</load-on-startup>
+ </servlet>
+
+
+ <!-- Server Side Includes processing servlet, which processes SSI -->
+ <!-- directives in HTML pages consistent with similar support in web -->
+ <!-- servers like Apache. Traditionally, this servlet is mapped to the -->
+ <!-- URL pattern "*.shtml". This servlet supports the following -->
+ <!-- initialization parameters (default values are in square brackets): -->
+ <!-- -->
+ <!-- buffered Should output from this servlet be buffered? -->
+ <!-- (0=false, 1=true) [0] -->
+ <!-- -->
+ <!-- debug Debugging detail level for messages logged -->
+ <!-- by this servlet. [0] -->
+ <!-- -->
+ <!-- expires The number of seconds before a page with SSI -->
+ <!-- directives will expire. [No default] -->
+ <!-- -->
+ <!-- isVirtualWebappRelative -->
+ <!-- Should "virtual" paths be interpreted as -->
+ <!-- relative to the context root, instead of -->
+ <!-- the server root? (0=false, 1=true) [0] -->
+ <!-- -->
+ <!-- -->
+ <!-- IMPORTANT: To use the SSI servlet, you also need to rename the -->
+ <!-- $CATALINA_HOME/server/lib/servlets-ssi.renametojar file -->
+ <!-- to $CATALINA_HOME/server/lib/servlets-ssi.jar -->
+
+<!--
+ <servlet>
+ <servlet-name>ssi</servlet-name>
+ <servlet-class>
+ org.apache.catalina.ssi.SSIServlet
+ </servlet-class>
+ <init-param>
+ <param-name>buffered</param-name>
+ <param-value>1</param-value>
+ </init-param>
+ <init-param>
+ <param-name>debug</param-name>
+ <param-value>0</param-value>
+ </init-param>
+ <init-param>
+ <param-name>expires</param-name>
+ <param-value>666</param-value>
+ </init-param>
+ <init-param>
+ <param-name>isVirtualWebappRelative</param-name>
+ <param-value>0</param-value>
+ </init-param>
+ <load-on-startup>4</load-on-startup>
+ </servlet>
+-->
+
+
+ <!-- Common Gateway Includes (CGI) processing servlet, which supports -->
+ <!-- execution of external applications that conform to the CGI spec -->
+ <!-- requirements. Typically, this servlet is mapped to the URL pattern -->
+ <!-- "/cgi-bin/*", which means that any CGI applications that are -->
+ <!-- executed must be present within the web application. This servlet -->
+ <!-- supports the following initialization parameters (default values -->
+ <!-- are in square brackets): -->
+ <!-- -->
+ <!-- cgiPathPrefix The CGI search path will start at -->
+ <!-- webAppRootDir + File.separator + this prefix. -->
+ <!-- [WEB-INF/cgi] -->
+ <!-- -->
+ <!-- debug Debugging detail level for messages logged -->
+ <!-- by this servlet. [0] -->
+ <!-- -->
+ <!-- executable Name of the exectuable used to run the -->
+ <!-- script. [perl] -->
+ <!-- -->
+ <!-- parameterEncoding Name of parameter encoding to be used with -->
+ <!-- CGI servlet. -->
+ <!-- [System.getProperty("file.encoding","UTF-8")] -->
+ <!-- -->
+ <!-- passShellEnvironment Should the shell environment variables (if -->
+ <!-- any) be passed to the CGI script? [false] -->
+ <!-- -->
+ <!-- IMPORTANT: To use the CGI servlet, you also need to rename the -->
+ <!-- $CATALINA_HOME/server/lib/servlets-cgi.renametojar file -->
+ <!-- to $CATALINA_HOME/server/lib/servlets-cgi.jar -->
+
+<!--
+ <servlet>
+ <servlet-name>cgi</servlet-name>
+ <servlet-class>org.apache.catalina.servlets.CGIServlet</servlet-class>
+ <init-param>
+ <param-name>debug</param-name>
+ <param-value>6</param-value>
+ </init-param>
+ <init-param>
+ <param-name>cgiPathPrefix</param-name>
+ <param-value>WEB-INF/cgi</param-value>
+ </init-param>
+ <load-on-startup>5</load-on-startup>
+ </servlet>
+-->
+
+
+ <!-- ================ Built In Servlet Mappings ========================= -->
+
+
+ <!-- The servlet mappings for the built in servlets defined above. Note -->
+ <!-- that, by default, the CGI and SSI servlets are *not* mapped. You -->
+ <!-- must uncomment these mappings (or add them to your application's own -->
+ <!-- web.xml deployment descriptor) to enable these services -->
+
+ <!-- The mapping for the default servlet -->
+ <servlet-mapping>
+ <servlet-name>default</servlet-name>
+ <url-pattern>/</url-pattern>
+ </servlet-mapping>
+
+ <!-- The mapping for the invoker servlet -->
+<!--
+ <servlet-mapping>
+ <servlet-name>invoker</servlet-name>
+ <url-pattern>/servlet/*</url-pattern>
+ </servlet-mapping>
+-->
+
+ <!-- The mapping for the JSP servlet -->
+ <servlet-mapping>
+ <servlet-name>jsp</servlet-name>
+ <url-pattern>*.jsp</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>jsp</servlet-name>
+ <url-pattern>*.jspx</url-pattern>
+ </servlet-mapping>
+
+ <!-- The mapping for the SSI servlet -->
+<!--
+ <servlet-mapping>
+ <servlet-name>ssi</servlet-name>
+ <url-pattern>*.shtml</url-pattern>
+ </servlet-mapping>
+-->
+
+ <!-- The mapping for the CGI Gateway servlet -->
+
+<!--
+ <servlet-mapping>
+ <servlet-name>cgi</servlet-name>
+ <url-pattern>/cgi-bin/*</url-pattern>
+ </servlet-mapping>
+-->
+
+
+ <!-- ==================== Default Session Configuration ================= -->
+ <!-- You can set the default session timeout (in minutes) for all newly -->
+ <!-- created sessions by modifying the value below. -->
+
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+
+
+ <!-- ===================== Default MIME Type Mappings =================== -->
+ <!-- When serving static resources, Tomcat will automatically generate -->
+ <!-- a "Content-Type" header based on the resource's filename extension, -->
+ <!-- based on these mappings. Additional mappings can be added here (to -->
+ <!-- apply to all web applications), or in your own application's web.xml -->
+ <!-- deployment descriptor. -->
+
+ <mime-mapping>
+ <extension>abs</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ai</extension>
+ <mime-type>application/postscript</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>aif</extension>
+ <mime-type>audio/x-aiff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>aifc</extension>
+ <mime-type>audio/x-aiff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>aiff</extension>
+ <mime-type>audio/x-aiff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>aim</extension>
+ <mime-type>application/x-aim</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>art</extension>
+ <mime-type>image/x-jg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>asf</extension>
+ <mime-type>video/x-ms-asf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>asx</extension>
+ <mime-type>video/x-ms-asf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>au</extension>
+ <mime-type>audio/basic</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>avi</extension>
+ <mime-type>video/x-msvideo</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>avx</extension>
+ <mime-type>video/x-rad-screenplay</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>bcpio</extension>
+ <mime-type>application/x-bcpio</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>bin</extension>
+ <mime-type>application/octet-stream</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>bmp</extension>
+ <mime-type>image/bmp</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>body</extension>
+ <mime-type>text/html</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>cdf</extension>
+ <mime-type>application/x-cdf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>cer</extension>
+ <mime-type>application/x-x509-ca-cert</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>class</extension>
+ <mime-type>application/java</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>cpio</extension>
+ <mime-type>application/x-cpio</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>csh</extension>
+ <mime-type>application/x-csh</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>css</extension>
+ <mime-type>text/css</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>dib</extension>
+ <mime-type>image/bmp</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>doc</extension>
+ <mime-type>application/msword</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>dtd</extension>
+ <mime-type>application/xml-dtd</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>dv</extension>
+ <mime-type>video/x-dv</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>dvi</extension>
+ <mime-type>application/x-dvi</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>eps</extension>
+ <mime-type>application/postscript</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>etx</extension>
+ <mime-type>text/x-setext</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>exe</extension>
+ <mime-type>application/octet-stream</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>gif</extension>
+ <mime-type>image/gif</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>gtar</extension>
+ <mime-type>application/x-gtar</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>gz</extension>
+ <mime-type>application/x-gzip</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>hdf</extension>
+ <mime-type>application/x-hdf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>hqx</extension>
+ <mime-type>application/mac-binhex40</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>htc</extension>
+ <mime-type>text/x-component</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>htm</extension>
+ <mime-type>text/html</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>html</extension>
+ <mime-type>text/html</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>hqx</extension>
+ <mime-type>application/mac-binhex40</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ief</extension>
+ <mime-type>image/ief</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jad</extension>
+ <mime-type>text/vnd.sun.j2me.app-descriptor</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jar</extension>
+ <mime-type>application/java-archive</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>java</extension>
+ <mime-type>text/plain</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jnlp</extension>
+ <mime-type>application/x-java-jnlp-file</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jpe</extension>
+ <mime-type>image/jpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jpeg</extension>
+ <mime-type>image/jpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jpg</extension>
+ <mime-type>image/jpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>js</extension>
+ <mime-type>text/javascript</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jsf</extension>
+ <mime-type>text/plain</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jspf</extension>
+ <mime-type>text/plain</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>kar</extension>
+ <mime-type>audio/x-midi</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>latex</extension>
+ <mime-type>application/x-latex</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>m3u</extension>
+ <mime-type>audio/x-mpegurl</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mac</extension>
+ <mime-type>image/x-macpaint</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>man</extension>
+ <mime-type>application/x-troff-man</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mathml</extension>
+ <mime-type>application/mathml+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>me</extension>
+ <mime-type>application/x-troff-me</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mid</extension>
+ <mime-type>audio/x-midi</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>midi</extension>
+ <mime-type>audio/x-midi</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mif</extension>
+ <mime-type>application/x-mif</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mov</extension>
+ <mime-type>video/quicktime</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>movie</extension>
+ <mime-type>video/x-sgi-movie</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mp1</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mp2</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mp3</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpa</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpe</extension>
+ <mime-type>video/mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpeg</extension>
+ <mime-type>video/mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpega</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpg</extension>
+ <mime-type>video/mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpv2</extension>
+ <mime-type>video/mpeg2</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ms</extension>
+ <mime-type>application/x-wais-source</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>nc</extension>
+ <mime-type>application/x-netcdf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>oda</extension>
+ <mime-type>application/oda</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ogg</extension>
+ <mime-type>application/ogg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pbm</extension>
+ <mime-type>image/x-portable-bitmap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pct</extension>
+ <mime-type>image/pict</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pdf</extension>
+ <mime-type>application/pdf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pgm</extension>
+ <mime-type>image/x-portable-graymap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pic</extension>
+ <mime-type>image/pict</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pict</extension>
+ <mime-type>image/pict</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pls</extension>
+ <mime-type>audio/x-scpls</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>png</extension>
+ <mime-type>image/png</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pnm</extension>
+ <mime-type>image/x-portable-anymap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pnt</extension>
+ <mime-type>image/x-macpaint</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ppm</extension>
+ <mime-type>image/x-portable-pixmap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ppt</extension>
+ <mime-type>application/powerpoint</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ps</extension>
+ <mime-type>application/postscript</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>psd</extension>
+ <mime-type>image/x-photoshop</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>qt</extension>
+ <mime-type>video/quicktime</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>qti</extension>
+ <mime-type>image/x-quicktime</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>qtif</extension>
+ <mime-type>image/x-quicktime</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ras</extension>
+ <mime-type>image/x-cmu-raster</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>rdf</extension>
+ <mime-type>application/rdf+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>rgb</extension>
+ <mime-type>image/x-rgb</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>rm</extension>
+ <mime-type>application/vnd.rn-realmedia</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>roff</extension>
+ <mime-type>application/x-troff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>rtf</extension>
+ <mime-type>application/rtf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>rtx</extension>
+ <mime-type>text/richtext</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>sh</extension>
+ <mime-type>application/x-sh</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>shar</extension>
+ <mime-type>application/x-shar</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>smf</extension>
+ <mime-type>audio/x-midi</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>sit</extension>
+ <mime-type>application/x-stuffit</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>snd</extension>
+ <mime-type>audio/basic</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>src</extension>
+ <mime-type>application/x-wais-source</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>sv4cpio</extension>
+ <mime-type>application/x-sv4cpio</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>sv4crc</extension>
+ <mime-type>application/x-sv4crc</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>svg</extension>
+ <mime-type>image/svg+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>swf</extension>
+ <mime-type>application/x-shockwave-flash</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>t</extension>
+ <mime-type>application/x-troff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tar</extension>
+ <mime-type>application/x-tar</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tcl</extension>
+ <mime-type>application/x-tcl</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tex</extension>
+ <mime-type>application/x-tex</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>texi</extension>
+ <mime-type>application/x-texinfo</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>texinfo</extension>
+ <mime-type>application/x-texinfo</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tif</extension>
+ <mime-type>image/tiff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tiff</extension>
+ <mime-type>image/tiff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tr</extension>
+ <mime-type>application/x-troff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tsv</extension>
+ <mime-type>text/tab-separated-values</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>txt</extension>
+ <mime-type>text/plain</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ulw</extension>
+ <mime-type>audio/basic</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ustar</extension>
+ <mime-type>application/x-ustar</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>vxml</extension>
+ <mime-type>application/voicexml+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xbm</extension>
+ <mime-type>image/x-xbitmap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xht</extension>
+ <mime-type>application/xhtml+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xhtml</extension>
+ <mime-type>application/xhtml+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xml</extension>
+ <mime-type>application/xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xpm</extension>
+ <mime-type>image/x-xpixmap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xsl</extension>
+ <mime-type>application/xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xslt</extension>
+ <mime-type>application/xslt+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xul</extension>
+ <mime-type>application/vnd.mozilla.xul+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xwd</extension>
+ <mime-type>image/x-xwindowdump</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>wav</extension>
+ <mime-type>audio/x-wav</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>svg</extension>
+ <mime-type>image/svg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>svgz</extension>
+ <mime-type>image/svg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>vsd</extension>
+ <mime-type>application/x-visio</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <!-- Wireless Bitmap -->
+ <extension>wbmp</extension>
+ <mime-type>image/vnd.wap.wbmp</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <!-- WML Source -->
+ <extension>wml</extension>
+ <mime-type>text/vnd.wap.wml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <!-- Compiled WML -->
+ <extension>wmlc</extension>
+ <mime-type>application/vnd.wap.wmlc</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <!-- WML Script Source -->
+ <extension>wmls</extension>
+ <mime-type>text/vnd.wap.wmlscript</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <!-- Compiled WML Script -->
+ <extension>wmlscriptc</extension>
+ <mime-type>application/vnd.wap.wmlscriptc</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>wrl</extension>
+ <mime-type>x-world/x-vrml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>Z</extension>
+ <mime-type>application/x-compress</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>z</extension>
+ <mime-type>application/x-compress</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>zip</extension>
+ <mime-type>application/zip</mime-type>
+ </mime-mapping>
+
+
+ <!-- ==================== Default Welcome File List ===================== -->
+ <!-- When a request URI refers to a directory, the default servlet looks -->
+ <!-- for a "welcome file" within that directory and, if present, -->
+ <!-- to the corresponding resource URI for display. If no welcome file -->
+ <!-- is present, the default servlet either serves a directory listing, -->
+ <!-- or returns a 404 status, depending on how it is configured. -->
+ <!-- -->
+ <!-- If you define welcome files in your own application's web.xml -->
+ <!-- deployment descriptor, that list *replaces* the list configured -->
+ <!-- here, so be sure that you include any of the default values that -->
+ <!-- you wish to include. -->
+
+ <welcome-file-list>
+ <welcome-file>index.html</welcome-file>
+ <welcome-file>index.htm</welcome-file>
+ <welcome-file>index.jsp</welcome-file>
+ </welcome-file-list>
+
+ <error-page>
+ <error-code>404</error-code>
+ <location>/404.html</location>
+ </error-page>
+
+ <error-page>
+ <error-code>500</error-code>
+ <location>/500.html</location>
+ </error-page>
+
+</web-app>
diff --git a/base/ca/shared/conf/workers.properties b/base/ca/shared/conf/workers.properties
new file mode 100644
index 000000000..50d88557f
--- /dev/null
+++ b/base/ca/shared/conf/workers.properties
@@ -0,0 +1,206 @@
+# workers.properties -
+#
+# This file provides jk derived plugins with the needed information to
+# connect to the different tomcat workers. Note that the distributed
+# version of this file requires modification before it is usable by a
+# plugin.
+#
+# As a general note, the characters $( and ) are used internally to define
+# macros. Do not use them in your own configuration!!!
+#
+# Whenever you see a set of lines such as:
+# x=value
+# y=$(x)\something
+#
+# the final value for y will be value\something
+#
+# Normaly all you will need to do is un-comment and modify the first three
+# properties, i.e. workers.tomcat_home, workers.java_home and ps.
+# Most of the configuration is derived from these.
+#
+# When you are done updating workers.tomcat_home, workers.java_home and ps
+# you should have 3 workers configured:
+#
+# - An ajp12 worker that connects to localhost:8007
+# - An ajp13 worker that connects to localhost:8009
+# - A jni inprocess worker.
+# - A load balancer worker
+#
+# However by default the plugins will only use the ajp12 worker. To have
+# the plugins use other workers you should modify the worker.list property.
+#
+#
+
+# OPTIONS ( very important for jni mode )
+
+#
+# workers.tomcat_home should point to the location where you
+# installed tomcat. This is where you have your conf, webapps and lib
+# directories.
+#
+workers.tomcat_home=/var/tomcat3
+
+#
+# workers.java_home should point to your Java installation. Normally
+# you should have a bin and lib directories beneath it.
+#
+workers.java_home=/opt/IBMJava2-13
+
+#
+# You should configure your environment slash... ps=\ on NT and / on UNIX
+# and maybe something different elsewhere.
+#
+ps=/
+
+#
+#------ ADVANCED MODE ------------------------------------------------
+#---------------------------------------------------------------------
+#
+
+#
+#------ DEFAULT worket list ------------------------------------------
+#---------------------------------------------------------------------
+#
+#
+# The workers that your plugins should create and work with
+#
+# Add 'inprocess' if you want JNI connector
+worker.list=ajp12, ajp13
+# , inprocess
+
+
+#
+#------ DEFAULT ajp12 WORKER DEFINITION ------------------------------
+#---------------------------------------------------------------------
+#
+
+#
+# Defining a worker named ajp12 and of type ajp12
+# Note that the name and the type do not have to match.
+#
+worker.ajp12.port=8007
+worker.ajp12.host=localhost
+worker.ajp12.type=ajp12
+#
+# Specifies the load balance factor when used with
+# a load balancing worker.
+# Note:
+# ----> lbfactor must be > 0
+# ----> Low lbfactor means less work done by the worker.
+worker.ajp12.lbfactor=1
+
+#
+#------ DEFAULT ajp13 WORKER DEFINITION ------------------------------
+#---------------------------------------------------------------------
+#
+
+#
+# Defining a worker named ajp13 and of type ajp13
+# Note that the name and the type do not have to match.
+#
+worker.ajp13.port=8009
+worker.ajp13.host=localhost
+worker.ajp13.type=ajp13
+#
+# Specifies the load balance factor when used with
+# a load balancing worker.
+# Note:
+# ----> lbfactor must be > 0
+# ----> Low lbfactor means less work done by the worker.
+worker.ajp13.lbfactor=1
+
+#
+# Specify the size of the open connection cache.
+#worker.ajp13.cachesize
+
+#
+#------ DEFAULT LOAD BALANCER WORKER DEFINITION ----------------------
+#---------------------------------------------------------------------
+#
+
+#
+# The loadbalancer (type lb) workers perform wighted round-robin
+# load balancing with sticky sessions.
+# Note:
+# ----> If a worker dies, the load balancer will check its state
+# once in a while. Until then all work is redirected to peer
+# workers.
+worker.loadbalancer.type=lb
+worker.loadbalancer.balanced_workers=ajp12, ajp13
+
+
+#
+#------ DEFAULT JNI WORKER DEFINITION---------------------------------
+#---------------------------------------------------------------------
+#
+
+#
+# Defining a worker named inprocess and of type jni
+# Note that the name and the type do not have to match.
+#
+worker.inprocess.type=jni
+
+#
+#------ CLASSPATH DEFINITION -----------------------------------------
+#---------------------------------------------------------------------
+#
+
+#
+# Additional class path components.
+#
+worker.inprocess.class_path=$(workers.tomcat_home)$(ps)lib$(ps)tomcat.jar
+
+#
+# Setting the command line for tomcat.
+# Note: The cmd_line string may not contain spaces.
+#
+worker.inprocess.cmd_line=start
+
+# Not needed, but can be customized.
+#worker.inprocess.cmd_line=-config
+#worker.inprocess.cmd_line=$(workers.tomcat_home)$(ps)conf$(ps)server.xml
+#worker.inprocess.cmd_line=-home
+#worker.inprocess.cmd_line=$(workers.tomcat_home)
+
+#
+# The JVM that we are about to use
+#
+# This is for Java2
+#
+# Windows
+worker.inprocess.jvm_lib=$(workers.java_home)$(ps)jre$(ps)bin$(ps)classic$(ps)jvm.dll
+# IBM JDK1.3
+#worker.inprocess.jvm_lib=$(workers.java_home)$(ps)jre$(ps)bin$(ps)classic$(ps)libjvm.so
+# Unix - Sun VM or blackdown
+#worker.inprocess.jvm_lib=$(workers.java_home)$(ps)jre$(ps)lib$(ps)i386$(ps)classic$(ps)libjvm.so
+
+#
+# And this is for jdk1.1.X
+#
+#worker.inprocess.jvm_lib=$(workers.java_home)$(ps)bin$(ps)javai.dll
+
+
+#
+# Setting the place for the stdout and stderr of tomcat
+#
+worker.inprocess.stdout=$(workers.tomcat_home)$(ps)logs$(ps)inprocess.stdout
+worker.inprocess.stderr=$(workers.tomcat_home)$(ps)logs$(ps)inprocess.stderr
+
+#
+# Setting the tomcat.home Java property
+#
+#worker.inprocess.sysprops=tomcat.home=$(workers.tomcat_home)
+
+#
+# Java system properties
+#
+# worker.inprocess.sysprops=java.compiler=NONE
+# worker.inprocess.sysprops=myprop=mypropvalue
+
+#
+# Additional path components.
+#
+# worker.inprocess.ld_path=d:$(ps)SQLLIB$(ps)bin
+#
+
+
diff --git a/base/ca/shared/conf/workers.properties.minimal b/base/ca/shared/conf/workers.properties.minimal
new file mode 100644
index 000000000..e3b5942c2
--- /dev/null
+++ b/base/ca/shared/conf/workers.properties.minimal
@@ -0,0 +1,17 @@
+# workers.properties.minimal -
+#
+# This file provides minimal jk configuration properties needed to
+# connect to Tomcat.
+#
+# The workers that jk should create and work with
+#
+worker.list=ajp13w
+
+
+#
+# Defining a worker named ajp13w and of type ajp13
+# Note that the name and the type do not have to match.
+#
+worker.ajp13w.type=ajp13
+worker.ajp13w.host=localhost
+worker.ajp13w.port=8009
diff --git a/base/ca/shared/conf/workers2.properties b/base/ca/shared/conf/workers2.properties
new file mode 100644
index 000000000..778118ff2
--- /dev/null
+++ b/base/ca/shared/conf/workers2.properties
@@ -0,0 +1,132 @@
+[logger]
+level=DEBUG
+
+[config:]
+file=${serverRoot}/conf/workers2.properties
+debug=0
+debugEnv=0
+
+[uriMap:]
+info=Maps the requests. Options: debug
+debug=0
+
+# Alternate file logger
+#[logger.file:0]
+#level=DEBUG
+#file=${serverRoot}/logs/jk2.log
+
+[shm:]
+info=Scoreboard. Required for reconfiguration and status with multiprocess servers
+file=${serverRoot}/logs/jk2.shm
+size=1000000
+debug=0
+disabled=0
+
+[workerEnv:]
+info=Global server options
+timing=1
+debug=0
+# Default Native Logger (apache2 or win32 )
+# can be overriden to a file logger, useful
+# when tracing win32 related issues
+#logger=logger.file:0
+
+[lb:lb]
+info=Default load balancer.
+debug=0
+
+[lb:lb_1]
+info=A second load balancer.
+debug=0
+
+[channel.socket:localhost:8009]
+info=Ajp13 forwarding over socket
+debug=0
+tomcatId=localhost:8009
+
+[channel.socket:localhost:8019]
+info=A second tomcat instance.
+debug=0
+tomcatId=localhost:8019
+lb_factor=1
+#group=lb
+group:lb:lb
+#group=lb_1
+group:lb:lb_1
+disabled=0
+
+[channel.un:/opt/33/work/jk2.socket]
+info=A second channel connecting to localhost:8019 via unix socket
+tomcatId=localhost:8019
+lb_factor=1
+debug=0
+
+[channel.jni:jni]
+info=The jni channel, used if tomcat is started inprocess
+
+[status:]
+info=Status worker, displays runtime informations
+
+[vm:]
+info=Parameters used to load a JVM in the server process
+#JVM=C:\jdk\jre\bin\hotspot\jvm.dll
+classpath=${TOMCAT_HOME}/bin/tomcat-jni.jar
+classpath=${TOMCAT_HOME}/server/lib/commons-logging.jar
+OPT=-Dtomcat.home=${TOMCAT_HOME}
+OPT=-Dcatalina.home=${TOMCAT_HOME}
+OPT=-Xmx128M
+#OPT=-Djava.compiler=NONE
+disabled=1
+
+[worker.jni:onStartup]
+info=Command to be executed by the VM on startup. This one will start tomcat.
+class=org/apache/jk/apr/TomcatStarter
+ARG=start
+# For Tomcat 5 use the 'stard' for startup argument
+# ARG=stard
+disabled=1
+stdout=${serverRoot}/logs/stdout.log
+stderr=${serverRoot}/logs/stderr.log
+
+[worker.jni:onShutdown]
+info=Command to be executed by the VM on shutdown. This one will stop tomcat.
+class=org/apache/jk/apr/TomcatStarter
+ARG=stop
+disabled=1
+
+[uri:/jkstatus/*]
+info=Display status information and checks the config file for changes.
+group=status:
+
+[uri:127.0.0.1:8003]
+info=Example virtual host. Make sure myVirtualHost is in /etc/hosts to test it
+alias=myVirtualHost:8003
+
+[uri:127.0.0.1:8003/ex]
+info=Example webapp in the virtual host. It'll go to lb_1 ( i.e. localhost:8019 )
+context=/ex
+group=lb_1
+
+[uri:/examples]
+info=Example webapp in the default context.
+context=/examples
+debug=0
+
+[uri:/examples1/*]
+info=A second webapp, this time going to the second tomcat only.
+group=lb_1
+debug=0
+
+[uri:/examples/servlet/*]
+info=Prefix mapping
+
+[uri:/examples/*.jsp]
+info=Extension mapping
+
+[uri:/examples/*]
+info=Map the whole webapp
+
+[uri:/examples/servlet/HelloW]
+info=Example with debug enabled.
+debug=10
+
diff --git a/base/ca/shared/conf/workers2.properties.minimal b/base/ca/shared/conf/workers2.properties.minimal
new file mode 100644
index 000000000..41a0ba6c1
--- /dev/null
+++ b/base/ca/shared/conf/workers2.properties.minimal
@@ -0,0 +1,55 @@
+#
+# This is the minimal JK2 connector configuration file.
+#
+
+[logger]
+info=Native logger
+level=ERROR
+
+[config:]
+file=${serverRoot}/conf/workers2.properties
+debug=0
+debugEnv=0
+
+[uriMap:]
+info=Maps the requests.
+debug=0
+
+[shm:]
+info=Scoreboard. Required for reconfiguration and status with multiprocess servers
+file=anonymous
+debug=0
+
+[workerEnv:]
+info=Global server options
+timing=0
+debug=0
+
+[lb:lb]
+info=Default load balancer.
+debug=0
+
+[channel.socket:localhost:8009]
+info=Ajp13 forwarding over socket
+debug=0
+tomcatId=localhost:8009
+
+[uri:/admin]
+info=Tomcat HTML based administration web application.
+debug=0
+
+[uri:/manager]
+info=A scriptable management web application for the Tomcat Web Server.
+debug=0
+
+[uri:/jsp-examples]
+info=JSP 2.0 Examples.
+debug=0
+
+[uri:/servlets-examples]
+info=Servlet 2.4 Examples.
+debug=0
+
+[uri:/*.jsp]
+info=JSP Extension mapping.
+debug=0
diff --git a/base/ca/shared/emails/ExpiredUnpublishJob b/base/ca/shared/emails/ExpiredUnpublishJob
new file mode 100644
index 000000000..902125ee6
--- /dev/null
+++ b/base/ca/shared/emails/ExpiredUnpublishJob
@@ -0,0 +1,6 @@
+ExpiredUnpublishJob $InstanceID summary:
+$SummaryItemList
+Executed at: $ExecutionTime.
+$SummaryTotalSuccess succeeded
+$SummaryTotalFailure failed
+End of summary.
diff --git a/base/ca/shared/emails/ExpiredUnpublishJobItem b/base/ca/shared/emails/ExpiredUnpublishJobItem
new file mode 100644
index 000000000..cb60a2b7d
--- /dev/null
+++ b/base/ca/shared/emails/ExpiredUnpublishJobItem
@@ -0,0 +1,2 @@
+$SubjectDN == status: $TOKEN_STATUS
+
diff --git a/base/ca/shared/emails/certIssued_CA b/base/ca/shared/emails/certIssued_CA
new file mode 100644
index 000000000..af2d2de9c
--- /dev/null
+++ b/base/ca/shared/emails/certIssued_CA
@@ -0,0 +1,12 @@
+Your certificate request has been processed successfully.
+SubjectDN= $SubjectDN
+IssuerDN= $IssuerDN
+notAfter= $NotAfter
+notBefore= $NotBefore
+Serial Number= 0x$HexSerialNumber
+
+To get your certificate, please follow this URL:
+https://$HttpHost:$HttpPort/ca/ee/ca/displayBySerial?serialNumber=$SerialNumber
+
+Please contact your admin if there is any problem.
+And, of course, this is just a \$SAMPLE\$ email notification form.
diff --git a/base/ca/shared/emails/certIssued_CA.html b/base/ca/shared/emails/certIssued_CA.html
new file mode 100644
index 000000000..b380346ac
--- /dev/null
+++ b/base/ca/shared/emails/certIssued_CA.html
@@ -0,0 +1,17 @@
+<html>
+<body>
+<h2>An automatically generated notification from <i>$InstanceID</i></h2>
+Your certificate request has been processed successfully.
+<p>
+SubjectDN= <b>$SubjectDN</b><br>
+IssuerDN= <b>$IssuerDN</b><br>
+notAfter= <b>$NotAfter</b><br>
+notBefore= <b>$NotBefore</b><br>
+Serial Number= <b>0x$HexSerialNumber</b><p>
+<p>
+To get your certificate, please follow this
+<A HREF="https://$HttpHost:$HttpPort/ca/ee/ca/displayBySerial?serialNumber=$SerialNumber">URL</A>
+
+Please contact your admin if there is any problem.
+</body>
+</html>
diff --git a/base/ca/shared/emails/certIssued_RA b/base/ca/shared/emails/certIssued_RA
new file mode 100644
index 000000000..7bde6875b
--- /dev/null
+++ b/base/ca/shared/emails/certIssued_RA
@@ -0,0 +1,12 @@
+Your certificate request has been processed successfully.
+SubjectDN= $SubjectDN
+IssuerDN= $IssuerDN
+notAfter= $NotAfter
+notBefore= $NotBefore
+Serial Number= 0x$HexSerialNumber
+
+To get your certificate, please follow this URL:
+https://$HttpHost:$HttpPort/displayCertFromRequest?requestId=$RequestId
+
+Please contact your admin if there is any problem.
+And, of course, this is just a \$SAMPLE\$ email notification form.
diff --git a/base/ca/shared/emails/certIssued_RA.html b/base/ca/shared/emails/certIssued_RA.html
new file mode 100644
index 000000000..2d7d2e36e
--- /dev/null
+++ b/base/ca/shared/emails/certIssued_RA.html
@@ -0,0 +1,17 @@
+<html>
+<body>
+<h2>An automatically generated notification from <i>$InstanceID</i></h2>
+Your certificate request has been processed successfully.
+<p>
+SubjectDN= <b>$SubjectDN</b><br>
+IssuerDN= <b>$IssuerDN</b><br>
+notAfter= <b>$NotAfter</b><br>
+notBefore= <b>$NotBefore</b><br>
+Serial Number= <b>0x$HexSerialNumber</b><p>
+<p>
+To get your certificate, please follow this
+<A HREF="https://$HttpHost:$HttpPort/displayCertFromRequest?requestId=$RequestId">URL</A>
+
+Please contact your admin if there is any problem.
+</body>
+</html>
diff --git a/base/ca/shared/emails/certRequestRejected.html b/base/ca/shared/emails/certRequestRejected.html
new file mode 100644
index 000000000..9cfa92d79
--- /dev/null
+++ b/base/ca/shared/emails/certRequestRejected.html
@@ -0,0 +1,10 @@
+<html>
+<body>
+<h2>An automatically generated notification from <i>$InstanceID</i></h2>
+Your certificate request has been <b>rejected</b>.
+<p>
+Request ID = <b>$RequestId</b><br>
+<p>
+Please contact your admin for assistance.
+</body>
+</html>
diff --git a/base/ca/shared/emails/certRevoked_CA b/base/ca/shared/emails/certRevoked_CA
new file mode 100644
index 000000000..3539ceaf3
--- /dev/null
+++ b/base/ca/shared/emails/certRevoked_CA
@@ -0,0 +1,12 @@
+Your certificate request has been processed successfully.
+SubjectDN= $SubjectDN
+IssuerDN= $IssuerDN
+notAfter= $NotAfter
+notBefore= $NotBefore
+Serial Number= 0x$HexSerialNumber
+
+To get your certificate, please follow this URL:
+https://$HttpHost:$HttpPort/displayBySerial?op=displayBySerial&serialNumber=$SerialNumber
+
+Please contact your admin if there is any problem.
+And, of course, this is just a \$SAMPLE\$ email notification form.
diff --git a/base/ca/shared/emails/certRevoked_CA.html b/base/ca/shared/emails/certRevoked_CA.html
new file mode 100644
index 000000000..025a0c94e
--- /dev/null
+++ b/base/ca/shared/emails/certRevoked_CA.html
@@ -0,0 +1,13 @@
+<html>
+<body>
+<h2>An automatically generated notification from <i>$InstanceID</i></h2>
+Your certificate revocation request has been processed successfully.
+<p>
+SubjectDN= <b>$SubjectDN</b><br>
+IssuerDN= <b>$IssuerDN</b><br>
+RevocationDate= <b>$RevocationDate</b><br>
+Serial Number= <b>0x$HexSerialNumber</b><p>
+<p>
+Please contact your admin if there is any problem.
+</body>
+</html>
diff --git a/base/ca/shared/emails/certRevoked_RA b/base/ca/shared/emails/certRevoked_RA
new file mode 100644
index 000000000..3539ceaf3
--- /dev/null
+++ b/base/ca/shared/emails/certRevoked_RA
@@ -0,0 +1,12 @@
+Your certificate request has been processed successfully.
+SubjectDN= $SubjectDN
+IssuerDN= $IssuerDN
+notAfter= $NotAfter
+notBefore= $NotBefore
+Serial Number= 0x$HexSerialNumber
+
+To get your certificate, please follow this URL:
+https://$HttpHost:$HttpPort/displayBySerial?op=displayBySerial&serialNumber=$SerialNumber
+
+Please contact your admin if there is any problem.
+And, of course, this is just a \$SAMPLE\$ email notification form.
diff --git a/base/ca/shared/emails/certRevoked_RA.html b/base/ca/shared/emails/certRevoked_RA.html
new file mode 100644
index 000000000..025a0c94e
--- /dev/null
+++ b/base/ca/shared/emails/certRevoked_RA.html
@@ -0,0 +1,13 @@
+<html>
+<body>
+<h2>An automatically generated notification from <i>$InstanceID</i></h2>
+Your certificate revocation request has been processed successfully.
+<p>
+SubjectDN= <b>$SubjectDN</b><br>
+IssuerDN= <b>$IssuerDN</b><br>
+RevocationDate= <b>$RevocationDate</b><br>
+Serial Number= <b>0x$HexSerialNumber</b><p>
+<p>
+Please contact your admin if there is any problem.
+</body>
+</html>
diff --git a/base/ca/shared/emails/euJob1.html b/base/ca/shared/emails/euJob1.html
new file mode 100644
index 000000000..86bae4a52
--- /dev/null
+++ b/base/ca/shared/emails/euJob1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+ <head>
+ <title>Summary for Unpublished Expired Certificates ($InstanceID)</title>
+ </head>
+
+ <body>
+ <h1>Summary for Unpublished Expired Certificates</h1>
+<TABLE BORDER COLS=4 widths="80%" >
+<TR>
+<TD><B>Serial Number</B></TD>
+
+<TD><B>Subject DN</B></TD>
+
+<TD><B>Issuer DN</B></TD>
+
+<TD><B>Expiration date/time</B></TD>
+
+<TD><B>Status</B></TD>
+</TR>
+$SummaryItemList
+</TABLE>
+Executed at: <b>$ExecutionTime</b><p>
+<b>$SummaryTotalSuccess</b> succeeded<p>
+<b>$SummaryTotalFailure</b> failed<p>
+End of summary.
+ <hr>
+ </body>
+</html>
diff --git a/base/ca/shared/emails/euJob1Item.html b/base/ca/shared/emails/euJob1Item.html
new file mode 100644
index 000000000..94732e4c3
--- /dev/null
+++ b/base/ca/shared/emails/euJob1Item.html
@@ -0,0 +1,11 @@
+<TR>
+<TD><B>0x$HexSerialNumber</B></TD>
+
+<TD><B>$SubjectDN</B></TD>
+
+<TD><B>$IssuerDN</B></TD>
+
+<TD><B>$NotAfter</B></TD>
+
+<TD><B>$Status</B></TD>
+</TR>
diff --git a/base/ca/shared/emails/publishCerts.html b/base/ca/shared/emails/publishCerts.html
new file mode 100644
index 000000000..c53f01fb6
--- /dev/null
+++ b/base/ca/shared/emails/publishCerts.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+ <head>
+ <title>Summary for Published Certificates ($InstanceID)</title>
+ </head>
+
+ <body>
+ <h1>Summary for Published Certificates</h1>
+<TABLE BORDER COLS=4 widths="80%" >
+<TR>
+<TD><B>Serial Number</B></TD>
+
+<TD><B>Subject DN</B></TD>
+
+<TD><B>Issuer DN</B></TD>
+
+<TD><B>Expiration date/time</B></TD>
+
+<TD><B>Status</B></TD>
+</TR>
+$SummaryItemList
+</TABLE>
+Executed at: <b>$ExecutionTime</b><p>
+<b>$SummaryTotalSuccess</b> succeeded<p>
+<b>$SummaryTotalFailure</b> failed<p>
+End of summary.
+ <hr>
+ </body>
+</html>
diff --git a/base/ca/shared/emails/publishCertsItem.html b/base/ca/shared/emails/publishCertsItem.html
new file mode 100644
index 000000000..94732e4c3
--- /dev/null
+++ b/base/ca/shared/emails/publishCertsItem.html
@@ -0,0 +1,11 @@
+<TR>
+<TD><B>0x$HexSerialNumber</B></TD>
+
+<TD><B>$SubjectDN</B></TD>
+
+<TD><B>$IssuerDN</B></TD>
+
+<TD><B>$NotAfter</B></TD>
+
+<TD><B>$Status</B></TD>
+</TR>
diff --git a/base/ca/shared/emails/reqInQueue_CA b/base/ca/shared/emails/reqInQueue_CA
new file mode 100644
index 000000000..7916ba5b4
--- /dev/null
+++ b/base/ca/shared/emails/reqInQueue_CA
@@ -0,0 +1,5 @@
+Request $RequestId is in queue.
+requestor email is $RequestorEmail.
+cert type is $CertType.
+request type is $RequestType.
+request process url: https://$HttpHost:$HttpPort/ca/agent/ca/profileReview?requestId=$RequestId
diff --git a/base/ca/shared/emails/reqInQueue_CA.html b/base/ca/shared/emails/reqInQueue_CA.html
new file mode 100644
index 000000000..3ccaac1fe
--- /dev/null
+++ b/base/ca/shared/emails/reqInQueue_CA.html
@@ -0,0 +1,12 @@
+<html>
+<body>
+Request $RequestId is in queue.
+<p>
+requestor email is <b>$RequestorEmail</b>.<p>
+cert type is <b>$CertType</b>.<p>
+request type is <b>$RequestType</b>.<p>
+Click
+<a href="https://$HttpHost:$HttpPort/ca/agent/ca/profileReview?requestId=$RequestId">
+this URL</a> to process request
+</body>
+</html>
diff --git a/base/ca/shared/emails/reqInQueue_RA b/base/ca/shared/emails/reqInQueue_RA
new file mode 100644
index 000000000..41fa62b8a
--- /dev/null
+++ b/base/ca/shared/emails/reqInQueue_RA
@@ -0,0 +1,5 @@
+Request $RequestId is in queue.
+requestor email is $RequestorEmail.
+cert type is $CertType.
+request type is $RequestType.
+request process url: https://$HttpHost:$HttpPort/ra/processReq?seqNum=$RequestId
diff --git a/base/ca/shared/emails/reqInQueue_RA.html b/base/ca/shared/emails/reqInQueue_RA.html
new file mode 100644
index 000000000..1b5bcfaf6
--- /dev/null
+++ b/base/ca/shared/emails/reqInQueue_RA.html
@@ -0,0 +1,12 @@
+<html>
+<body>
+Request $RequestId is in queue.
+<p>
+requestor email is <b>$RequestorEmail</b>.<p>
+cert type is <b>$CertType</b>.<p>
+request type is <b>$RequestType</b>.<p>
+Click
+<a href="https://$HttpHost:$HttpPort/ra/processReq?seqNum=$RequestId">
+this URL</a> to process request
+</body>
+</html>
diff --git a/base/ca/shared/emails/riq1Item.html b/base/ca/shared/emails/riq1Item.html
new file mode 100644
index 000000000..0550ddeaf
--- /dev/null
+++ b/base/ca/shared/emails/riq1Item.html
@@ -0,0 +1,5 @@
+<TR>
+<TD><B>$RequestorEmail</B></TD>
+<TD><B>$CertType</B></TD>
+<TD><B>$RequestType</B></TD>
+</TR>
diff --git a/base/ca/shared/emails/riq1Summary.html b/base/ca/shared/emails/riq1Summary.html
new file mode 100644
index 000000000..cf68bc7df
--- /dev/null
+++ b/base/ca/shared/emails/riq1Summary.html
@@ -0,0 +1,12 @@
+<html>
+ <head>
+ <title>Request in Queue Summary Report from $InstanceID</title>
+ </head>
+
+ <body>
+ <h1>Request in Queue Summary Report from $InstanceID</h1>
+Executed at: <b>$ExecutionTime</b><p>
+Total number of requests in Queue: <b>$SummaryTotalNum</b><p>
+ <hr>
+ </body>
+</html>
diff --git a/base/ca/shared/emails/rnJob1.txt b/base/ca/shared/emails/rnJob1.txt
new file mode 100644
index 000000000..f07250814
--- /dev/null
+++ b/base/ca/shared/emails/rnJob1.txt
@@ -0,0 +1,8 @@
+The following certificate is going to expire (or has expired) on
+ $NotAfter
+Serial number = 0x$HexSerialNumber
+SubjectDN = $SubjectDN
+You can renew this certificate by clicking the "Renewal" button
+at the following URL:
+
+https://$HttpHost:$HttpPort
diff --git a/base/ca/shared/emails/rnJob1Item.txt b/base/ca/shared/emails/rnJob1Item.txt
new file mode 100644
index 000000000..8080c0bde
--- /dev/null
+++ b/base/ca/shared/emails/rnJob1Item.txt
@@ -0,0 +1,8 @@
+Serial number = 0x$HexSerialNumber
+SubjectDN = $SubjectDN
+Validity period = $NotBefore - $NotAfter
+Suggested Renewal http host name = $HttpHost
+Suggested Renewal http port number = $HttpPort
+Renewal notification status = $Status
+-------
+
diff --git a/base/ca/shared/emails/rnJob1Summary.txt b/base/ca/shared/emails/rnJob1Summary.txt
new file mode 100644
index 000000000..65bf98583
--- /dev/null
+++ b/base/ca/shared/emails/rnJob1Summary.txt
@@ -0,0 +1,7 @@
+Automatically generated summary report from $InstanceID
+executed at $ExecutionTime
+========================================================
+
+$SummaryItemList
+$SummaryTotalSuccess succeeded
+$SummaryTotalFailure failed
diff --git a/base/ca/shared/etc/init.d/pki-cad b/base/ca/shared/etc/init.d/pki-cad
new file mode 100755
index 000000000..772523287
--- /dev/null
+++ b/base/ca/shared/etc/init.d/pki-cad
@@ -0,0 +1,87 @@
+#!/bin/bash
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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-2010 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+# pki-cad Startup script for pki-ca with tomcat6
+#
+# chkconfig: - 81 19
+# description: Certificate Authority (Tomcat 6.0)
+# processname: pki-cad
+# piddir: /var/run/pki/ca
+#
+
+PROG_NAME=`basename $0`
+SERVICE_NAME="pki-cad"
+SERVICE_PROG="/sbin/service"
+PKI_PATH="/usr/share/pki/ca"
+PKI_REGISTRY="/etc/sysconfig/pki/ca"
+PKI_TYPE="pki-ca"
+PKI_TOTAL_PORTS=7
+
+# Avoid using 'systemctl' for now
+SYSTEMCTL_SKIP_REDIRECT=1
+export SYSTEMCTL_SKIP_REDIRECT
+
+# Disallow 'others' the ability to 'write' to new files
+umask 00002
+
+command="$1"
+pki_instance="$2"
+
+# Source function library.
+. /etc/init.d/functions
+
+# Source the PKI function library
+. /usr/share/pki/scripts/functions
+
+# See how we were called.
+case $command in
+ status)
+ registry_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 ${default_error}
+ ;;
+ *)
+ echo "unknown action ($command)"
+ usage
+ echo "where valid instance names include:"
+ list_instances
+ exit ${default_error}
+ ;;
+esac
+
diff --git a/base/ca/shared/lib/systemd/system/pki-cad.target b/base/ca/shared/lib/systemd/system/pki-cad.target
new file mode 100644
index 000000000..dab661403
--- /dev/null
+++ b/base/ca/shared/lib/systemd/system/pki-cad.target
@@ -0,0 +1,8 @@
+[Unit]
+Description=PKI Certificate Authority Server
+After=syslog.target network.target
+
+[Install]
+WantedBy=multi-user.target
+
+
diff --git a/base/ca/shared/lib/systemd/system/pki-cad@.service b/base/ca/shared/lib/systemd/system/pki-cad@.service
new file mode 100644
index 000000000..e205d72fb
--- /dev/null
+++ b/base/ca/shared/lib/systemd/system/pki-cad@.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=PKI Certificate Authority Server %i
+After=pki-cad.target
+BindTo=pki-cad.target
+
+[Service]
+Type=forking
+ExecStart=/usr/bin/pkicontrol start ca %i
+ExecStop=/usr/bin/pkicontrol stop ca %i
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/base/ca/shared/profiles/ca/DomainController.cfg b/base/ca/shared/profiles/ca/DomainController.cfg
new file mode 100644
index 000000000..81cba3214
--- /dev/null
+++ b/base/ca/shared/profiles/ca/DomainController.cfg
@@ -0,0 +1,130 @@
+desc=This profile is for enrolling Domain Controller Certificate
+enable=true
+enableBy=admin
+name=Domain Controller
+visible=true
+auth.instance_id=AgentCertAuth
+input.list=i1,i2,i3
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+input.i3.class_id=genericInputImpl
+input.i3.params.gi_display_name0=ccm
+input.i3.params.gi_param_enable0=true
+input.i3.params.gi_param_name0=ccm
+input.i3.params.gi_display_name1=GUID
+input.i3.params.gi_param_enable1=true
+input.i3.params.gi_param_name1=GUID
+input.i3.params.gi_num=2
+output.list=o1,o2
+output.o1.class_id=certOutputImpl
+output.o2.class_id=pkcs7OutputImpl
+policyset.list=set1
+policyset.set1.list=p2,p4,p5,subj,p6,p8,p9,p12,eku,gen,crldp
+policyset.set1.subj.constraint.class_id=noConstraintImpl
+policyset.set1.subj.constraint.name=No Constraint
+policyset.set1.subj.default.class_id=nsTokenUserKeySubjectNameDefaultImpl
+policyset.set1.subj.default.name=nsTokenUserKeySubjectNameDefault
+#policyset.set1.p1.default.params.dnpattern=UID=$request.uid$, E=$request.mail$, O=Token Key User
+#policyset.set1.subj.default.params.dnpattern=CN=GEMSTAR,OU=Domain Controllers,DC=test,dc=local
+policyset.set1.subj.default.params.dnpattern=CN=$request.ccm$
+policyset.set1.subj.default.params.ldap.enable=false
+policyset.set1.subj.default.params.ldap.searchName=uid
+policyset.set1.subj.default.params.ldapStringAttributes=uid,mail
+policyset.set1.subj.default.params.ldap.basedn=
+policyset.set1.subj.default.params.ldap.maxConns=4
+policyset.set1.subj.default.params.ldap.minConns=1
+policyset.set1.subj.default.params.ldap.ldapconn.Version=2
+policyset.set1.subj.default.params.ldap.ldapconn.host=
+policyset.set1.subj.default.params.ldap.ldapconn.port=
+policyset.set1.subj.default.params.ldap.ldapconn.secureConn=false
+policyset.set1.p2.constraint.class_id=noConstraintImpl
+policyset.set1.p2.constraint.name=No Constraint
+policyset.set1.p2.default.class_id=validityDefaultImpl
+policyset.set1.p2.default.name=Validity Default
+policyset.set1.p2.default.params.range=1825
+policyset.set1.p2.default.params.startTime=0
+policyset.set1.p4.constraint.class_id=noConstraintImpl
+policyset.set1.p4.constraint.name=No Constraint
+policyset.set1.p4.default.class_id=signingAlgDefaultImpl
+policyset.set1.p4.default.name=Signing Algorithm Default
+policyset.set1.p4.default.params.signingAlg=-
+policyset.set1.p5.constraint.class_id=noConstraintImpl
+policyset.set1.p5.constraint.name=No Constraint
+policyset.set1.p5.default.class_id=keyUsageExtDefaultImpl
+policyset.set1.p5.default.name=Key Usage Extension Default
+policyset.set1.p5.default.params.keyUsageCritical=true
+policyset.set1.p5.default.params.keyUsageCrlSign=false
+policyset.set1.p5.default.params.keyUsageDataEncipherment=false
+policyset.set1.p5.default.params.keyUsageDecipherOnly=false
+policyset.set1.p5.default.params.keyUsageDigitalSignature=true
+policyset.set1.p5.default.params.keyUsageEncipherOnly=false
+policyset.set1.p5.default.params.keyUsageKeyAgreement=false
+policyset.set1.p5.default.params.keyUsageKeyCertSign=false
+policyset.set1.p5.default.params.keyUsageKeyEncipherment=true
+policyset.set1.p5.default.params.keyUsageNonRepudiation=false
+policyset.set1.p6.constraint.class_id=noConstraintImpl
+policyset.set1.p6.constraint.name=No Constraint
+policyset.set1.p6.default.class_id=subjectAltNameExtDefaultImpl
+policyset.set1.p6.default.name=Subject Alternative Name Extension Default
+policyset.set1.p6.default.params.subjAltExtGNEnable_0=true
+policyset.set1.p6.default.params.subjAltExtGNEnable_1=true
+policyset.set1.p6.default.params.subjAltExtPattern_0=$request.ccm$
+policyset.set1.p6.default.params.subjAltExtType_0=DNSName
+policyset.set1.p6.default.params.subjAltExtPattern_1=(Any)1.3.6.1.4.1.311.25.1,0410$request.GUID$
+policyset.set1.p6.default.params.subjAltExtType_1=OtherName
+policyset.set1.p6.default.params.subjAltNameExtCritical=false
+policyset.set1.p6.default.params.subjAltNameNumGNs=2
+policyset.set1.5.constraint.class_id=noConstraintImpl
+policyset.set1.5.constraint.name=No Constraint
+policyset.set1.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.set1.5.default.name=AIA Extension Default
+policyset.set1.5.default.params.authInfoAccessADEnable_0=true
+policyset.set1.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.set1.5.default.params.authInfoAccessADLocation_0=http://localhost.localdomain:9180/ca/ee/ca/getCRL?crlIssuingPoint=MasterCRL&op=getCRL&crlDisplayType=cachedCRL&submit=Submit
+policyset.set1.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.2
+policyset.set1.5.default.params.authInfoAccessCritical=false
+policyset.set1.5.default.params.authInfoAccessNumADs=1
+policyset.set1.eku.constraint.class_id=noConstraintImpl
+policyset.set1.eku.constraint.name=No Constraint
+policyset.set1.eku.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.set1.eku.default.name=Extended Key Usage Extension Default
+policyset.set1.eku.default.params.exKeyUsageCritical=false
+policyset.set1.eku.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2
+policyset.set1.p8.constraint.class_id=noConstraintImpl
+policyset.set1.p8.constraint.name=No Constraint
+policyset.set1.p8.default.class_id=subjectKeyIdentifierExtDefaultImpl
+policyset.set1.p8.default.name=Subject Key Identifier Default
+policyset.set1.p9.constraint.class_id=noConstraintImpl
+policyset.set1.p9.constraint.name=No Constraint
+policyset.set1.p9.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.set1.p9.default.name=Authority Key Identifier Extension Default
+policyset.set1.p12.constraint.class_id=basicConstraintsExtConstraintImpl
+policyset.set1.p12.constraint.name=Basic Constraints Extension Constraint
+policyset.set1.p12.constraint.params.basicConstraintsCritical=-
+policyset.set1.p12.constraint.params.basicConstraintsIsCA=-
+policyset.set1.p12.constraint.params.basicConstraintsMaxPathLen=-1
+policyset.set1.p12.constraint.params.basicConstraintsMinPathLen=-1
+policyset.set1.p12.default.class_id=basicConstraintsExtDefaultImpl
+policyset.set1.p12.default.name=Basic Constraints Extension Default
+policyset.set1.p12.default.params.basicConstraintsCritical=false
+policyset.set1.p12.default.params.basicConstraintsIsCA=false
+policyset.set1.p12.default.params.basicConstraintsPathLen=-1
+policyset.set1.crldp.constraint.class_id=noConstraintImpl
+policyset.set1.crldp.constraint.name=No Constraint
+policyset.set1.crldp.default.class_id=crlDistributionPointsExtDefaultImpl
+policyset.set1.crldp.default.name=crlDistributionPointsExtDefaultImpl
+policyset.set1.crldp.default.params.crlDistPointsCritical=false
+policyset.set1.crldp.default.params.crlDistPointsNum=1
+policyset.set1.crldp.default.params.crlDistPointsEnable_0=true
+policyset.set1.crldp.default.params.crlDistPointsIssuerName_0=
+policyset.set1.crldp.default.params.crlDistPointsIssuerType_0=
+policyset.set1.crldp.default.params.crlDistPointsPointName_0=http://localhost.localdomain:9180/ca/ee/ca/getCRL?crlIssuingPoint=MasterCRL&op=getCRL&crlDisplayType=cachedCRL&submit=Submit
+policyset.set1.crldp.default.params.crlDistPointsPointType_0=URIName
+policyset.set1.crldp.default.params.crlDistPointsReasons_0=
+policyset.set1.gen.constraint.class_id=noConstraintImpl
+policyset.set1.gen.constraint.name=No Constraint
+policyset.set1.gen.default.class_id=genericExtDefaultImpl
+policyset.set1.gen.default.name=Generic Extension
+#This is the Microsoft 'Certificate Template Name' Extensions. The Value is 'DomainController'
+policyset.set1.gen.default.params.genericExtOID=1.3.6.1.4.1.311.20.2
+policyset.set1.gen.default.params.genericExtData=1e200044006f006d00610069006e0043006f006e00740072006f006c006c00650072
diff --git a/base/ca/shared/profiles/ca/caAdminCert.cfg b/base/ca/shared/profiles/ca/caAdminCert.cfg
new file mode 100644
index 000000000..c44079a1e
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caAdminCert.cfg
@@ -0,0 +1,87 @@
+desc=This certificate profile is for enrolling Security Domain administrator's certificates with LDAP authentication against the internal LDAP database.
+visible=false
+enable=true
+enableBy=admin
+auth.instance_id=TokenAuth
+authz.acl=group="Enterprise OCSP Administrators" || group="Enterprise RA Administrators" || group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise TKS Administrators" || group="Enterprise TPS Administrators"
+name=Security Domain Administrator Certificate Enrollment
+input.list=i1,i2,i3
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+input.i3.class_id=subjectDNInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=adminCertSet
+policyset.adminCertSet.list=1,2,3,4,5,6,7,8
+policyset.adminCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.adminCertSet.1.constraint.name=Subject Name Constraint
+policyset.adminCertSet.1.constraint.params.pattern=.*
+policyset.adminCertSet.1.constraint.params.accept=true
+policyset.adminCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.adminCertSet.1.default.name=Subject Name Default
+policyset.adminCertSet.1.default.params.name=
+policyset.adminCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.adminCertSet.2.constraint.name=Validity Constraint
+policyset.adminCertSet.2.constraint.params.range=365
+policyset.adminCertSet.2.constraint.params.notBeforeCheck=false
+policyset.adminCertSet.2.constraint.params.notAfterCheck=false
+policyset.adminCertSet.2.default.class_id=validityDefaultImpl
+policyset.adminCertSet.2.default.name=Validity Default
+policyset.adminCertSet.2.default.params.range=365
+policyset.adminCertSet.2.default.params.startTime=0
+policyset.adminCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.adminCertSet.3.constraint.name=Key Constraint
+policyset.adminCertSet.3.constraint.params.keyType=RSA
+policyset.adminCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.adminCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.adminCertSet.3.default.name=Key Default
+policyset.adminCertSet.4.constraint.class_id=noConstraintImpl
+policyset.adminCertSet.4.constraint.name=No Constraint
+policyset.adminCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.adminCertSet.4.default.name=Authority Key Identifier Default
+policyset.adminCertSet.5.constraint.class_id=noConstraintImpl
+policyset.adminCertSet.5.constraint.name=No Constraint
+policyset.adminCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.adminCertSet.5.default.name=AIA Extension Default
+policyset.adminCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.adminCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.adminCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.adminCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.adminCertSet.5.default.params.authInfoAccessCritical=false
+policyset.adminCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.adminCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.adminCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.adminCertSet.6.constraint.params.keyUsageCritical=true
+policyset.adminCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.adminCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.adminCertSet.6.constraint.params.keyUsageDataEncipherment=true
+policyset.adminCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.adminCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.adminCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.adminCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.adminCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.adminCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.adminCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.adminCertSet.6.default.name=Key Usage Default
+policyset.adminCertSet.6.default.params.keyUsageCritical=true
+policyset.adminCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.adminCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.adminCertSet.6.default.params.keyUsageDataEncipherment=true
+policyset.adminCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.adminCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.adminCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.adminCertSet.6.default.params.keyUsageCrlSign=false
+policyset.adminCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.adminCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.adminCertSet.7.constraint.class_id=noConstraintImpl
+policyset.adminCertSet.7.constraint.name=No Constraint
+policyset.adminCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.adminCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.adminCertSet.7.default.params.exKeyUsageCritical=false
+policyset.adminCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.adminCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.adminCertSet.8.constraint.name=No Constraint
+policyset.adminCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.adminCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.adminCertSet.8.default.name=Signing Alg
+policyset.adminCertSet.8.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caAgentFileSigning.cfg b/base/ca/shared/profiles/ca/caAgentFileSigning.cfg
new file mode 100644
index 000000000..26eb171b0
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caAgentFileSigning.cfg
@@ -0,0 +1,86 @@
+desc=This certificate profile is for getting file signing certificate with agent authentication.
+visible=true
+enable=true
+enableBy=admin
+auth.instance_id=AgentCertAuth
+name=Agent-Authenticated File Signing
+input.list=i1,i2,i3
+input.i1.class_id=keyGenInputImpl
+input.i2.class_id=fileSigningInputImpl
+input.i3.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=pkcs7OutputImpl
+policyset.list=serverCertSet
+policyset.serverCertSet.list=1,2,3,4,5,6,7,8
+policyset.serverCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.serverCertSet.1.constraint.name=Subject Name Constraint
+policyset.serverCertSet.1.constraint.params.pattern=CN=.*
+policyset.serverCertSet.1.constraint.params.accept=true
+policyset.serverCertSet.1.default.class_id=subjectNameDefaultImpl
+policyset.serverCertSet.1.default.name=Subject Name Default
+policyset.serverCertSet.1.default.params.name=CN=(Name)$request.requestor_name$(Text)$request.file_signing_text$(Size)$request.file_signing_size$(DigestType)$request.file_signing_digest_type$(Digest)$request.file_signing_digest$
+policyset.serverCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.serverCertSet.2.constraint.name=Validity Constraint
+policyset.serverCertSet.2.constraint.params.range=365
+policyset.serverCertSet.2.constraint.params.notBeforeCheck=false
+policyset.serverCertSet.2.constraint.params.notAfterCheck=false
+policyset.serverCertSet.2.default.class_id=validityDefaultImpl
+policyset.serverCertSet.2.default.name=Validity Default
+policyset.serverCertSet.2.default.params.range=180
+policyset.serverCertSet.2.default.params.startTime=0
+policyset.serverCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.serverCertSet.3.constraint.name=Key Constraint
+policyset.serverCertSet.3.constraint.params.keyType=RSA
+policyset.serverCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.serverCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.serverCertSet.3.default.name=Key Default
+policyset.serverCertSet.4.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.4.constraint.name=No Constraint
+policyset.serverCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.serverCertSet.4.default.name=Authority Key Identifier Default
+policyset.serverCertSet.5.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.5.constraint.name=No Constraint
+policyset.serverCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.serverCertSet.5.default.name=AIA Extension Default
+policyset.serverCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.serverCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.serverCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.serverCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.serverCertSet.5.default.params.authInfoAccessCritical=false
+policyset.serverCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.serverCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.serverCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.serverCertSet.6.constraint.params.keyUsageCritical=true
+policyset.serverCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.constraint.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.serverCertSet.6.default.name=Key Usage Default
+policyset.serverCertSet.6.default.params.keyUsageCritical=true
+policyset.serverCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.default.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.default.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.7.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.7.constraint.name=No Constraint
+policyset.serverCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.serverCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.serverCertSet.7.default.params.exKeyUsageCritical=false
+policyset.serverCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.3
+policyset.serverCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.serverCertSet.8.constraint.name=No Constraint
+policyset.serverCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.serverCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.serverCertSet.8.default.name=Signing Alg
+policyset.serverCertSet.8.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caAgentServerCert.cfg b/base/ca/shared/profiles/ca/caAgentServerCert.cfg
new file mode 100644
index 000000000..d0aac7a8f
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caAgentServerCert.cfg
@@ -0,0 +1,85 @@
+desc=This certificate profile is for enrolling server certificates with agent authentication.
+visible=true
+enable=true
+enableBy=admin
+auth.instance_id=AgentCertAuth
+name=Agent-Authenticated Server Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=serverCertSet
+policyset.serverCertSet.list=1,2,3,4,5,6,7,8
+policyset.serverCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.serverCertSet.1.constraint.name=Subject Name Constraint
+policyset.serverCertSet.1.constraint.params.pattern=CN=.*
+policyset.serverCertSet.1.constraint.params.accept=true
+policyset.serverCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.serverCertSet.1.default.name=Subject Name Default
+policyset.serverCertSet.1.default.params.name=
+policyset.serverCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.serverCertSet.2.constraint.name=Validity Constraint
+policyset.serverCertSet.2.constraint.params.range=365
+policyset.serverCertSet.2.constraint.params.notBeforeCheck=false
+policyset.serverCertSet.2.constraint.params.notAfterCheck=false
+policyset.serverCertSet.2.default.class_id=validityDefaultImpl
+policyset.serverCertSet.2.default.name=Validity Default
+policyset.serverCertSet.2.default.params.range=180
+policyset.serverCertSet.2.default.params.startTime=0
+policyset.serverCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.serverCertSet.3.constraint.name=Key Constraint
+policyset.serverCertSet.3.constraint.params.keyType=RSA
+policyset.serverCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.serverCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.serverCertSet.3.default.name=Key Default
+policyset.serverCertSet.4.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.4.constraint.name=No Constraint
+policyset.serverCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.serverCertSet.4.default.name=Authority Key Identifier Default
+policyset.serverCertSet.5.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.5.constraint.name=No Constraint
+policyset.serverCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.serverCertSet.5.default.name=AIA Extension Default
+policyset.serverCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.serverCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.serverCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.serverCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.serverCertSet.5.default.params.authInfoAccessCritical=false
+policyset.serverCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.serverCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.serverCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.serverCertSet.6.constraint.params.keyUsageCritical=true
+policyset.serverCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.constraint.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.serverCertSet.6.default.name=Key Usage Default
+policyset.serverCertSet.6.default.params.keyUsageCritical=true
+policyset.serverCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.default.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.default.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.7.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.7.constraint.name=No Constraint
+policyset.serverCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.serverCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.serverCertSet.7.default.params.exKeyUsageCritical=false
+policyset.serverCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.1
+policyset.serverCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.serverCertSet.8.constraint.name=No Constraint
+policyset.serverCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.serverCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.serverCertSet.8.default.name=Signing Alg
+policyset.serverCertSet.8.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caCACert.cfg b/base/ca/shared/profiles/ca/caCACert.cfg
new file mode 100644
index 000000000..a88abdf1f
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caCACert.cfg
@@ -0,0 +1,95 @@
+desc=This certificate profile is for enrolling Certificate Authority certificates.
+visible=true
+enable=true
+enableBy=admin
+auth.class_id=
+name=Manual Certificate Manager Signing Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=caCertSet
+policyset.caCertSet.list=1,2,3,4,5,6,8,9,10
+policyset.caCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.caCertSet.1.constraint.name=Subject Name Constraint
+policyset.caCertSet.1.constraint.params.pattern=CN=.*
+policyset.caCertSet.1.constraint.params.accept=true
+policyset.caCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.caCertSet.1.default.name=Subject Name Default
+policyset.caCertSet.1.default.params.name=
+policyset.caCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.caCertSet.2.constraint.name=Validity Constraint
+policyset.caCertSet.2.constraint.params.range=2922
+policyset.caCertSet.2.constraint.params.notBeforeCheck=false
+policyset.caCertSet.2.constraint.params.notAfterCheck=false
+policyset.caCertSet.2.default.class_id=caValidityDefaultImpl
+policyset.caCertSet.2.default.name=CA Certificate Validity Default
+policyset.caCertSet.2.default.params.range=2922
+policyset.caCertSet.2.default.params.startTime=0
+policyset.caCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.caCertSet.3.constraint.name=Key Constraint
+policyset.caCertSet.3.constraint.params.keyType=RSA
+policyset.caCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.caCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.caCertSet.3.default.name=Key Default
+policyset.caCertSet.4.constraint.class_id=noConstraintImpl
+policyset.caCertSet.4.constraint.name=No Constraint
+policyset.caCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.caCertSet.4.default.name=Authority Key Identifier Default
+policyset.caCertSet.5.constraint.class_id=basicConstraintsExtConstraintImpl
+policyset.caCertSet.5.constraint.name=Basic Constraint Extension Constraint
+policyset.caCertSet.5.constraint.params.basicConstraintsCritical=true
+policyset.caCertSet.5.constraint.params.basicConstraintsIsCA=true
+policyset.caCertSet.5.constraint.params.basicConstraintsMinPathLen=-1
+policyset.caCertSet.5.constraint.params.basicConstraintsMaxPathLen=-1
+policyset.caCertSet.5.default.class_id=basicConstraintsExtDefaultImpl
+policyset.caCertSet.5.default.name=Basic Constraints Extension Default
+policyset.caCertSet.5.default.params.basicConstraintsCritical=true
+policyset.caCertSet.5.default.params.basicConstraintsIsCA=true
+policyset.caCertSet.5.default.params.basicConstraintsPathLen=-1
+policyset.caCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.caCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.caCertSet.6.constraint.params.keyUsageCritical=true
+policyset.caCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.caCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.caCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.caCertSet.6.constraint.params.keyUsageKeyEncipherment=false
+policyset.caCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.caCertSet.6.constraint.params.keyUsageKeyCertSign=true
+policyset.caCertSet.6.constraint.params.keyUsageCrlSign=true
+policyset.caCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.caCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.caCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.caCertSet.6.default.name=Key Usage Default
+policyset.caCertSet.6.default.params.keyUsageCritical=true
+policyset.caCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.caCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.caCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.caCertSet.6.default.params.keyUsageKeyEncipherment=false
+policyset.caCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.caCertSet.6.default.params.keyUsageKeyCertSign=true
+policyset.caCertSet.6.default.params.keyUsageCrlSign=true
+policyset.caCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.caCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.caCertSet.8.constraint.class_id=noConstraintImpl
+policyset.caCertSet.8.constraint.name=No Constraint
+policyset.caCertSet.8.default.class_id=subjectKeyIdentifierExtDefaultImpl
+policyset.caCertSet.8.default.name=Subject Key Identifier Extension Default
+policyset.caCertSet.8.default.params.critical=false
+policyset.caCertSet.9.constraint.class_id=signingAlgConstraintImpl
+policyset.caCertSet.9.constraint.name=No Constraint
+policyset.caCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.caCertSet.9.default.class_id=signingAlgDefaultImpl
+policyset.caCertSet.9.default.name=Signing Alg
+policyset.caCertSet.9.default.params.signingAlg=-
+policyset.caCertSet.10.constraint.class_id=noConstraintImpl
+policyset.caCertSet.10.constraint.name=No Constraint
+policyset.caCertSet.10.default.class_id=authInfoAccessExtDefaultImpl
+policyset.caCertSet.10.default.name=AIA Extension Default
+policyset.caCertSet.10.default.params.authInfoAccessADEnable_0=true
+policyset.caCertSet.10.default.params.authInfoAccessADLocationType_0=URIName
+policyset.caCertSet.10.default.params.authInfoAccessADLocation_0=
+policyset.caCertSet.10.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.caCertSet.10.default.params.authInfoAccessCritical=false
+policyset.caCertSet.10.default.params.authInfoAccessNumADs=1
diff --git a/base/ca/shared/profiles/ca/caCMCUserCert.cfg b/base/ca/shared/profiles/ca/caCMCUserCert.cfg
new file mode 100644
index 000000000..8d402f771
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caCMCUserCert.cfg
@@ -0,0 +1,86 @@
+desc=This certificate profile is for enrolling user certificates by using the CMC certificate request with CMC Signature authentication.
+visible=true
+enable=true
+enableBy=admin
+auth.instance_id=CMCAuth
+authz.acl=group="Certificate Manager Agents"
+name=Signed CMC-Authenticated User Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=cmcCertReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=cmcUserCertSet
+policyset.cmcUserCertSet.list=1,2,3,4,5,6,7,8
+policyset.cmcUserCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.cmcUserCertSet.1.constraint.name=Subject Name Constraint
+policyset.cmcUserCertSet.1.constraint.params.pattern=.*
+policyset.cmcUserCertSet.1.constraint.params.accept=true
+policyset.cmcUserCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.cmcUserCertSet.1.default.name=Subject Name Default
+policyset.cmcUserCertSet.1.default.params.name=
+policyset.cmcUserCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.cmcUserCertSet.2.constraint.name=Validity Constraint
+policyset.cmcUserCertSet.2.constraint.params.range=365
+policyset.cmcUserCertSet.2.constraint.params.notBeforeCheck=false
+policyset.cmcUserCertSet.2.constraint.params.notAfterCheck=false
+policyset.cmcUserCertSet.2.default.class_id=validityDefaultImpl
+policyset.cmcUserCertSet.2.default.name=Validity Default
+policyset.cmcUserCertSet.2.default.params.range=180
+policyset.cmcUserCertSet.2.default.params.startTime=0
+policyset.cmcUserCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.cmcUserCertSet.3.constraint.name=Key Constraint
+policyset.cmcUserCertSet.3.constraint.params.keyType=-
+policyset.cmcUserCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.cmcUserCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.cmcUserCertSet.3.default.name=Key Default
+policyset.cmcUserCertSet.4.constraint.class_id=noConstraintImpl
+policyset.cmcUserCertSet.4.constraint.name=No Constraint
+policyset.cmcUserCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.cmcUserCertSet.4.default.name=Authority Key Identifier Default
+policyset.cmcUserCertSet.5.constraint.class_id=noConstraintImpl
+policyset.cmcUserCertSet.5.constraint.name=No Constraint
+policyset.cmcUserCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.cmcUserCertSet.5.default.name=AIA Extension Default
+policyset.cmcUserCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.cmcUserCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.cmcUserCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.cmcUserCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.cmcUserCertSet.5.default.params.authInfoAccessCritical=false
+policyset.cmcUserCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.cmcUserCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.cmcUserCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.cmcUserCertSet.6.constraint.params.keyUsageCritical=true
+policyset.cmcUserCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.cmcUserCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.cmcUserCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.cmcUserCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.cmcUserCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.cmcUserCertSet.6.default.name=Key Usage Default
+policyset.cmcUserCertSet.6.default.params.keyUsageCritical=true
+policyset.cmcUserCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.cmcUserCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.cmcUserCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.cmcUserCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.cmcUserCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.cmcUserCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.cmcUserCertSet.6.default.params.keyUsageCrlSign=false
+policyset.cmcUserCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.cmcUserCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.cmcUserCertSet.7.constraint.class_id=noConstraintImpl
+policyset.cmcUserCertSet.7.constraint.name=No Constraint
+policyset.cmcUserCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.cmcUserCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.cmcUserCertSet.7.default.params.exKeyUsageCritical=false
+policyset.cmcUserCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.cmcUserCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.cmcUserCertSet.8.constraint.name=No Constraint
+policyset.cmcUserCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.cmcUserCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.cmcUserCertSet.8.default.name=Signing Alg
+policyset.cmcUserCertSet.8.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caDirUserCert.cfg b/base/ca/shared/profiles/ca/caDirUserCert.cfg
new file mode 100644
index 000000000..ce42445cc
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caDirUserCert.cfg
@@ -0,0 +1,99 @@
+desc=This certificate profile is for enrolling user certificates with directory-based authentication.
+visible=true
+enable=true
+enableBy=admin
+name=Directory-Authenticated User Dual-Use Certificate Enrollment
+auth.instance_id=UserDirEnrollment
+input.list=i1
+input.i1.class_id=keyGenInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=userCertSet
+policyset.userCertSet.list=1,10,2,3,4,5,6,7,8,9
+policyset.userCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.userCertSet.1.constraint.name=Subject Name Constraint
+policyset.userCertSet.1.constraint.params.pattern=UID=.*
+policyset.userCertSet.1.constraint.params.accept=true
+policyset.userCertSet.1.default.class_id=authTokenSubjectNameDefaultImpl
+policyset.userCertSet.1.default.name=Subject Name Default
+policyset.userCertSet.1.default.params.name=
+policyset.userCertSet.10.constraint.class_id=renewGracePeriodConstraintImpl
+policyset.userCertSet.10.constraint.name=Renewal Grace Period Constraint
+policyset.userCertSet.10.constraint.params.renewal.graceBefore=30
+policyset.userCertSet.10.constraint.params.renewal.graceAfter=30
+policyset.userCertSet.10.default.class_id=noDefaultImpl
+policyset.userCertSet.10.default.name=No Default
+policyset.userCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.userCertSet.2.constraint.name=Validity Constraint
+policyset.userCertSet.2.constraint.params.range=365
+policyset.userCertSet.2.constraint.params.notBeforeCheck=false
+policyset.userCertSet.2.constraint.params.notAfterCheck=false
+policyset.userCertSet.2.default.class_id=validityDefaultImpl
+policyset.userCertSet.2.default.name=Validity Default
+policyset.userCertSet.2.default.params.range=180
+policyset.userCertSet.2.default.params.startTime=0
+policyset.userCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.userCertSet.3.constraint.name=Key Constraint
+policyset.userCertSet.3.constraint.params.keyType=RSA
+policyset.userCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.userCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.userCertSet.3.default.name=Key Default
+policyset.userCertSet.4.constraint.class_id=noConstraintImpl
+policyset.userCertSet.4.constraint.name=No Constraint
+policyset.userCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.userCertSet.4.default.name=Authority Key Identifier Default
+policyset.userCertSet.5.constraint.class_id=noConstraintImpl
+policyset.userCertSet.5.constraint.name=No Constraint
+policyset.userCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.userCertSet.5.default.name=AIA Extension Default
+policyset.userCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.userCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.userCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.userCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.userCertSet.5.default.params.authInfoAccessCritical=false
+policyset.userCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.userCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.userCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.userCertSet.6.constraint.params.keyUsageCritical=true
+policyset.userCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.userCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.userCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.userCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.userCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.userCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.userCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.userCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.userCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.userCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.userCertSet.6.default.name=Key Usage Default
+policyset.userCertSet.6.default.params.keyUsageCritical=true
+policyset.userCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.userCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.userCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.userCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.userCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.userCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.userCertSet.6.default.params.keyUsageCrlSign=false
+policyset.userCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.userCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.userCertSet.7.constraint.class_id=noConstraintImpl
+policyset.userCertSet.7.constraint.name=No Constraint
+policyset.userCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.userCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.userCertSet.7.default.params.exKeyUsageCritical=false
+policyset.userCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.userCertSet.8.constraint.class_id=noConstraintImpl
+policyset.userCertSet.8.constraint.name=No Constraint
+policyset.userCertSet.8.default.class_id=subjectAltNameExtDefaultImpl
+policyset.userCertSet.8.default.name=Subject Alt Name Constraint
+policyset.userCertSet.8.default.params.subjAltNameExtCritical=false
+policyset.userCertSet.8.default.params.subjAltExtType_0=RFC822Name
+policyset.userCertSet.8.default.params.subjAltExtPattern_0=$request.requestor_email$
+policyset.userCertSet.8.default.params.subjAltExtGNEnable_0=true
+policyset.userCertSet.8.default.params.subjAltNameNumGNs=1
+policyset.userCertSet.9.constraint.class_id=signingAlgConstraintImpl
+policyset.userCertSet.9.constraint.name=No Constraint
+policyset.userCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.userCertSet.9.default.class_id=signingAlgDefaultImpl
+policyset.userCertSet.9.default.name=Signing Alg
+policyset.userCertSet.9.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caDirUserRenewal.cfg b/base/ca/shared/profiles/ca/caDirUserRenewal.cfg
new file mode 100755
index 000000000..c643b9df4
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caDirUserRenewal.cfg
@@ -0,0 +1,12 @@
+desc=This certificate profile is for renewing a certificate by serial number by using directory based authentication.
+visible=true
+enable=true
+enableBy=admin
+renewal=true
+auth.instance_id=UserDirEnrollment
+authz.acl=user_origreq="auth_token.uid"
+name=Renewal: Directory-Authenticated User Certificate Self-Renew profile
+input.list=i1
+input.i1.class_id=serialNumRenewInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
diff --git a/base/ca/shared/profiles/ca/caDualCert.cfg b/base/ca/shared/profiles/ca/caDualCert.cfg
new file mode 100644
index 000000000..e85cbe002
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caDualCert.cfg
@@ -0,0 +1,168 @@
+desc=This certificate profile is for enrolling dual user certificates. It works only with Netscape 7.0 or later.
+visible=true
+enable=true
+enableBy=admin
+name=Manual User Signing & Encryption Certificates Enrollment
+auth.class_id=
+input.list=i1,i2,i3
+input.i1.class_id=dualKeyGenInputImpl
+input.i2.class_id=subjectNameInputImpl
+input.i3.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=encryptionCertSet,signingCertSet
+policyset.encryptionCertSet.list=1,2,3,4,5,6,7,8,9
+policyset.encryptionCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.encryptionCertSet.1.constraint.name=Subject Name Constraint
+policyset.encryptionCertSet.1.constraint.params.pattern=UID=.*
+policyset.encryptionCertSet.1.constraint.params.accept=true
+policyset.encryptionCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.encryptionCertSet.1.default.name=Subject Name Default
+policyset.encryptionCertSet.1.default.params.name=
+policyset.encryptionCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.encryptionCertSet.2.constraint.name=Validity Constraint
+policyset.encryptionCertSet.2.constraint.params.range=365
+policyset.encryptionCertSet.2.constraint.params.notBeforeCheck=false
+policyset.encryptionCertSet.2.constraint.params.notAfterCheck=false
+policyset.encryptionCertSet.2.default.class_id=validityDefaultImpl
+policyset.encryptionCertSet.2.default.name=Validity Default
+policyset.encryptionCertSet.2.default.params.range=180
+policyset.encryptionCertSet.2.default.params.startTime=0
+policyset.encryptionCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.encryptionCertSet.3.constraint.name=Key Constraint
+policyset.encryptionCertSet.3.constraint.params.keyType=RSA
+policyset.encryptionCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.encryptionCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.encryptionCertSet.3.default.name=Key Default
+policyset.encryptionCertSet.4.constraint.class_id=noConstraintImpl
+policyset.encryptionCertSet.4.constraint.name=No Constraint
+policyset.encryptionCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.encryptionCertSet.4.default.name=Authority Key Identifier Default
+policyset.encryptionCertSet.5.constraint.class_id=noConstraintImpl
+policyset.encryptionCertSet.5.constraint.name=No Constraint
+policyset.encryptionCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.encryptionCertSet.5.default.name=AIA Extension Default
+policyset.encryptionCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.encryptionCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.encryptionCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.encryptionCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.encryptionCertSet.5.default.params.authInfoAccessCritical=false
+policyset.encryptionCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.encryptionCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.encryptionCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.encryptionCertSet.6.constraint.params.keyUsageCritical=true
+policyset.encryptionCertSet.6.constraint.params.keyUsageDigitalSignature=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageNonRepudiation=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.encryptionCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.encryptionCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.encryptionCertSet.6.default.name=Key Usage Default
+policyset.encryptionCertSet.6.default.params.keyUsageCritical=true
+policyset.encryptionCertSet.6.default.params.keyUsageDigitalSignature=false
+policyset.encryptionCertSet.6.default.params.keyUsageNonRepudiation=false
+policyset.encryptionCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.encryptionCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.encryptionCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.encryptionCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.encryptionCertSet.6.default.params.keyUsageCrlSign=false
+policyset.encryptionCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.encryptionCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.encryptionCertSet.7.constraint.class_id=noConstraintImpl
+policyset.encryptionCertSet.7.constraint.name=No Constraint
+policyset.encryptionCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.encryptionCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.encryptionCertSet.7.default.params.exKeyUsageCritical=false
+policyset.encryptionCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.encryptionCertSet.8.constraint.class_id=noConstraintImpl
+policyset.encryptionCertSet.8.constraint.name=No Constraint
+policyset.encryptionCertSet.8.default.class_id=subjectAltNameExtDefaultImpl
+policyset.encryptionCertSet.8.default.name=Subject Alt Name Constraint
+policyset.encryptionCertSet.8.default.params.subjAltNameExtCritical=false
+policyset.encryptionCertSet.8.default.params.subjAltExtType_0=RFC822Name
+policyset.encryptionCertSet.8.default.params.subjAltExtPattern_0=$request.requestor_email$
+policyset.encryptionCertSet.8.default.params.subjAltExtGNEnable_0=true
+policyset.encryptionCertSet.8.default.params.subjAltNameNumGNs=1
+policyset.encryptionCertSet.9.constraint.class_id=signingAlgConstraintImpl
+policyset.encryptionCertSet.9.constraint.name=No Constraint
+policyset.encryptionCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.encryptionCertSet.9.default.class_id=signingAlgDefaultImpl
+policyset.encryptionCertSet.9.default.name=Signing Alg
+policyset.encryptionCertSet.9.default.params.signingAlg=-
+policyset.signingCertSet.list=1,2,3,4,6,7,8,9
+policyset.signingCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.signingCertSet.1.constraint.name=Subject Name Constraint
+policyset.signingCertSet.1.constraint.params.pattern=UID=.*
+policyset.signingCertSet.1.constraint.params.accept=true
+policyset.signingCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.signingCertSet.1.default.name=Subject Name Default
+policyset.signingCertSet.1.default.params.name=
+policyset.signingCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.signingCertSet.2.constraint.name=Validity Constraint
+policyset.signingCertSet.2.constraint.params.range=365
+policyset.signingCertSet.2.constraint.params.notBeforeCheck=false
+policyset.signingCertSet.2.constraint.params.notAfterCheck=false
+policyset.signingCertSet.2.default.class_id=validityDefaultImpl
+policyset.signingCertSet.2.default.name=Validity Default
+policyset.signingCertSet.2.default.params.range=180
+policyset.signingCertSet.2.default.params.startTime=60
+policyset.signingCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.signingCertSet.3.constraint.name=Key Constraint
+policyset.signingCertSet.3.constraint.params.keyType=RSA
+policyset.signingCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.signingCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.signingCertSet.3.default.name=Key Default
+policyset.signingCertSet.4.constraint.class_id=noConstraintImpl
+policyset.signingCertSet.4.constraint.name=No Constraint
+policyset.signingCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.signingCertSet.4.default.name=Authority Key Identifier Default
+policyset.signingCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.signingCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.signingCertSet.6.constraint.params.keyUsageCritical=true
+policyset.signingCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.signingCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.signingCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.signingCertSet.6.constraint.params.keyUsageKeyEncipherment=false
+policyset.signingCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.signingCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.signingCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.signingCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.signingCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.signingCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.signingCertSet.6.default.name=Key Usage Default
+policyset.signingCertSet.6.default.params.keyUsageCritical=true
+policyset.signingCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.signingCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.signingCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.signingCertSet.6.default.params.keyUsageKeyEncipherment=false
+policyset.signingCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.signingCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.signingCertSet.6.default.params.keyUsageCrlSign=false
+policyset.signingCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.signingCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.signingCertSet.7.constraint.class_id=noConstraintImpl
+policyset.signingCertSet.7.constraint.name=No Constraint
+policyset.signingCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.signingCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.signingCertSet.7.default.params.exKeyUsageCritical=false
+policyset.signingCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.signingCertSet.8.constraint.class_id=noConstraintImpl
+policyset.signingCertSet.8.constraint.name=No Constraint
+policyset.signingCertSet.8.default.class_id=subjectAltNameExtDefaultImpl
+policyset.signingCertSet.8.default.name=Subject Alt Name Constraint
+policyset.signingCertSet.8.default.params.subjAltNameExtCritical=false
+policyset.signingCertSet.8.default.params.subjAltExtType_0=RFC822Name
+policyset.signingCertSet.8.default.params.subjAltExtPattern_0=$request.requestor_email$
+policyset.signingCertSet.8.default.params.subjAltExtGNEnable_0=true
+policyset.signingCertSet.8.default.params.subjAltNameNumGNs=1
+policyset.signingCertSet.9.constraint.class_id=signingAlgConstraintImpl
+policyset.signingCertSet.9.constraint.name=No Constraint
+policyset.signingCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.signingCertSet.9.default.class_id=signingAlgDefaultImpl
+policyset.signingCertSet.9.default.name=Signing Alg
+policyset.signingCertSet.9.default.params.signingAlg=-
+policyset.signingCertSet.9.default.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
diff --git a/base/ca/shared/profiles/ca/caDualRAuserCert.cfg b/base/ca/shared/profiles/ca/caDualRAuserCert.cfg
new file mode 100644
index 000000000..741e26a3f
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caDualRAuserCert.cfg
@@ -0,0 +1,94 @@
+desc=This certificate profile is for enrolling user certificates with RA agent authentication.
+visible=false
+enable=true
+enableBy=admin
+auth.instance_id=raCertAuth
+name=RA Agent-Authenticated User Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=userCertSet
+policyset.userCertSet.list=1,2,3,4,5,6,7,8,9
+policyset.userCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.userCertSet.1.constraint.name=Subject Name Constraint
+policyset.userCertSet.1.constraint.params.pattern=.*UID=.*
+policyset.userCertSet.1.constraint.params.accept=true
+policyset.userCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.userCertSet.1.default.name=Subject Name Default
+policyset.userCertSet.1.default.params.name=
+policyset.userCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.userCertSet.2.constraint.name=Validity Constraint
+policyset.userCertSet.2.constraint.params.range=365
+policyset.userCertSet.2.constraint.params.notBeforeCheck=false
+policyset.userCertSet.2.constraint.params.notAfterCheck=false
+policyset.userCertSet.2.default.class_id=validityDefaultImpl
+policyset.userCertSet.2.default.name=Validity Default
+policyset.userCertSet.2.default.params.range=180
+policyset.userCertSet.2.default.params.startTime=0
+policyset.userCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.userCertSet.3.constraint.name=Key Constraint
+policyset.userCertSet.3.constraint.params.keyType=RSA
+policyset.userCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.userCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.userCertSet.3.default.name=Key Default
+policyset.userCertSet.4.constraint.class_id=noConstraintImpl
+policyset.userCertSet.4.constraint.name=No Constraint
+policyset.userCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.userCertSet.4.default.name=Authority Key Identifier Default
+policyset.userCertSet.5.constraint.class_id=noConstraintImpl
+policyset.userCertSet.5.constraint.name=No Constraint
+policyset.userCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.userCertSet.5.default.name=AIA Extension Default
+policyset.userCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.userCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.userCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.userCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.userCertSet.5.default.params.authInfoAccessCritical=false
+policyset.userCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.userCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.userCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.userCertSet.6.constraint.params.keyUsageCritical=true
+policyset.userCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.userCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.userCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.userCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.userCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.userCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.userCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.userCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.userCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.userCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.userCertSet.6.default.name=Key Usage Default
+policyset.userCertSet.6.default.params.keyUsageCritical=true
+policyset.userCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.userCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.userCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.userCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.userCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.userCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.userCertSet.6.default.params.keyUsageCrlSign=false
+policyset.userCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.userCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.userCertSet.7.constraint.class_id=noConstraintImpl
+policyset.userCertSet.7.constraint.name=No Constraint
+policyset.userCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.userCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.userCertSet.7.default.params.exKeyUsageCritical=false
+policyset.userCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.userCertSet.8.constraint.class_id=noConstraintImpl
+policyset.userCertSet.8.constraint.name=No Constraint
+policyset.userCertSet.8.default.class_id=subjectAltNameExtDefaultImpl
+policyset.userCertSet.8.default.name=Subject Alt Name Constraint
+policyset.userCertSet.8.default.params.subjAltNameExtCritical=false
+policyset.userCertSet.8.default.params.subjAltExtType_0=RFC822Name
+policyset.userCertSet.8.default.params.subjAltExtPattern_0=$request.requestor_email$
+policyset.userCertSet.8.default.params.subjAltExtGNEnable_0=true
+policyset.userCertSet.8.default.params.subjAltNameNumGNs=1
+policyset.userCertSet.9.constraint.class_id=signingAlgConstraintImpl
+policyset.userCertSet.9.constraint.name=No Constraint
+policyset.userCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.userCertSet.9.default.class_id=signingAlgDefaultImpl
+policyset.userCertSet.9.default.name=Signing Alg
+policyset.userCertSet.9.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caECDualCert.cfg b/base/ca/shared/profiles/ca/caECDualCert.cfg
new file mode 100644
index 000000000..8bf081088
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caECDualCert.cfg
@@ -0,0 +1,168 @@
+desc=This certificate profile is for enrolling dual user ECC certificates. It works only with Netscape 7.0 or later.
+visible=false
+enable=true
+enableBy=admin
+name=Manual User Signing & Encryption ECC Certificates Enrollment
+auth.class_id=
+input.list=i1,i2,i3
+input.i1.class_id=dualKeyGenInputImpl
+input.i2.class_id=subjectNameInputImpl
+input.i3.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=encryptionCertSet,signingCertSet
+policyset.encryptionCertSet.list=1,2,3,4,5,6,7,8,9
+policyset.encryptionCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.encryptionCertSet.1.constraint.name=Subject Name Constraint
+policyset.encryptionCertSet.1.constraint.params.pattern=UID=.*
+policyset.encryptionCertSet.1.constraint.params.accept=true
+policyset.encryptionCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.encryptionCertSet.1.default.name=Subject Name Default
+policyset.encryptionCertSet.1.default.params.name=
+policyset.encryptionCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.encryptionCertSet.2.constraint.name=Validity Constraint
+policyset.encryptionCertSet.2.constraint.params.range=365
+policyset.encryptionCertSet.2.constraint.params.notBeforeCheck=false
+policyset.encryptionCertSet.2.constraint.params.notAfterCheck=false
+policyset.encryptionCertSet.2.default.class_id=validityDefaultImpl
+policyset.encryptionCertSet.2.default.name=Validity Default
+policyset.encryptionCertSet.2.default.params.range=180
+policyset.encryptionCertSet.2.default.params.startTime=0
+policyset.encryptionCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.encryptionCertSet.3.constraint.name=Key Constraint
+policyset.encryptionCertSet.3.constraint.params.keyType=EC
+policyset.encryptionCertSet.3.constraint.params.keyParameters=nistp256,nistp384,nistp521
+policyset.encryptionCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.encryptionCertSet.3.default.name=Key Default
+policyset.encryptionCertSet.4.constraint.class_id=noConstraintImpl
+policyset.encryptionCertSet.4.constraint.name=No Constraint
+policyset.encryptionCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.encryptionCertSet.4.default.name=Authority Key Identifier Default
+policyset.encryptionCertSet.5.constraint.class_id=noConstraintImpl
+policyset.encryptionCertSet.5.constraint.name=No Constraint
+policyset.encryptionCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.encryptionCertSet.5.default.name=AIA Extension Default
+policyset.encryptionCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.encryptionCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.encryptionCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.encryptionCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.encryptionCertSet.5.default.params.authInfoAccessCritical=false
+policyset.encryptionCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.encryptionCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.encryptionCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.encryptionCertSet.6.constraint.params.keyUsageCritical=true
+policyset.encryptionCertSet.6.constraint.params.keyUsageDigitalSignature=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageNonRepudiation=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.encryptionCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.encryptionCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.encryptionCertSet.6.default.name=Key Usage Default
+policyset.encryptionCertSet.6.default.params.keyUsageCritical=true
+policyset.encryptionCertSet.6.default.params.keyUsageDigitalSignature=false
+policyset.encryptionCertSet.6.default.params.keyUsageNonRepudiation=false
+policyset.encryptionCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.encryptionCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.encryptionCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.encryptionCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.encryptionCertSet.6.default.params.keyUsageCrlSign=false
+policyset.encryptionCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.encryptionCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.encryptionCertSet.7.constraint.class_id=noConstraintImpl
+policyset.encryptionCertSet.7.constraint.name=No Constraint
+policyset.encryptionCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.encryptionCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.encryptionCertSet.7.default.params.exKeyUsageCritical=false
+policyset.encryptionCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.encryptionCertSet.8.constraint.class_id=noConstraintImpl
+policyset.encryptionCertSet.8.constraint.name=No Constraint
+policyset.encryptionCertSet.8.default.class_id=subjectAltNameExtDefaultImpl
+policyset.encryptionCertSet.8.default.name=Subject Alt Name Constraint
+policyset.encryptionCertSet.8.default.params.subjAltNameExtCritical=false
+policyset.encryptionCertSet.8.default.params.subjAltExtType_0=RFC822Name
+policyset.encryptionCertSet.8.default.params.subjAltExtPattern_0=$request.requestor_email$
+policyset.encryptionCertSet.8.default.params.subjAltExtGNEnable_0=true
+policyset.encryptionCertSet.8.default.params.subjAltNameNumGNs=1
+policyset.encryptionCertSet.9.constraint.class_id=signingAlgConstraintImpl
+policyset.encryptionCertSet.9.constraint.name=No Constraint
+policyset.encryptionCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.encryptionCertSet.9.default.class_id=signingAlgDefaultImpl
+policyset.encryptionCertSet.9.default.name=Signing Alg
+policyset.encryptionCertSet.9.default.params.signingAlg=-
+policyset.signingCertSet.list=1,2,3,4,6,7,8,9
+policyset.signingCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.signingCertSet.1.constraint.name=Subject Name Constraint
+policyset.signingCertSet.1.constraint.params.pattern=UID=.*
+policyset.signingCertSet.1.constraint.params.accept=true
+policyset.signingCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.signingCertSet.1.default.name=Subject Name Default
+policyset.signingCertSet.1.default.params.name=
+policyset.signingCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.signingCertSet.2.constraint.name=Validity Constraint
+policyset.signingCertSet.2.constraint.params.range=365
+policyset.signingCertSet.2.constraint.params.notBeforeCheck=false
+policyset.signingCertSet.2.constraint.params.notAfterCheck=false
+policyset.signingCertSet.2.default.class_id=validityDefaultImpl
+policyset.signingCertSet.2.default.name=Validity Default
+policyset.signingCertSet.2.default.params.range=180
+policyset.signingCertSet.2.default.params.startTime=60
+policyset.signingCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.signingCertSet.3.constraint.name=Key Constraint
+policyset.signingCertSet.3.constraint.params.keyType=EC
+policyset.signingCertSet.3.constraint.params.keyParameters=nistp256,nistp384,nistp521
+policyset.signingCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.signingCertSet.3.default.name=Key Default
+policyset.signingCertSet.4.constraint.class_id=noConstraintImpl
+policyset.signingCertSet.4.constraint.name=No Constraint
+policyset.signingCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.signingCertSet.4.default.name=Authority Key Identifier Default
+policyset.signingCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.signingCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.signingCertSet.6.constraint.params.keyUsageCritical=true
+policyset.signingCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.signingCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.signingCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.signingCertSet.6.constraint.params.keyUsageKeyEncipherment=false
+policyset.signingCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.signingCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.signingCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.signingCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.signingCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.signingCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.signingCertSet.6.default.name=Key Usage Default
+policyset.signingCertSet.6.default.params.keyUsageCritical=true
+policyset.signingCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.signingCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.signingCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.signingCertSet.6.default.params.keyUsageKeyEncipherment=false
+policyset.signingCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.signingCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.signingCertSet.6.default.params.keyUsageCrlSign=false
+policyset.signingCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.signingCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.signingCertSet.7.constraint.class_id=noConstraintImpl
+policyset.signingCertSet.7.constraint.name=No Constraint
+policyset.signingCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.signingCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.signingCertSet.7.default.params.exKeyUsageCritical=false
+policyset.signingCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.signingCertSet.8.constraint.class_id=noConstraintImpl
+policyset.signingCertSet.8.constraint.name=No Constraint
+policyset.signingCertSet.8.default.class_id=subjectAltNameExtDefaultImpl
+policyset.signingCertSet.8.default.name=Subject Alt Name Constraint
+policyset.signingCertSet.8.default.params.subjAltNameExtCritical=false
+policyset.signingCertSet.8.default.params.subjAltExtType_0=RFC822Name
+policyset.signingCertSet.8.default.params.subjAltExtPattern_0=$request.requestor_email$
+policyset.signingCertSet.8.default.params.subjAltExtGNEnable_0=true
+policyset.signingCertSet.8.default.params.subjAltNameNumGNs=1
+policyset.signingCertSet.9.constraint.class_id=signingAlgConstraintImpl
+policyset.signingCertSet.9.constraint.name=No Constraint
+policyset.signingCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.signingCertSet.9.default.class_id=signingAlgDefaultImpl
+policyset.signingCertSet.9.default.name=Signing Alg
+policyset.signingCertSet.9.default.params.signingAlg=-
+policyset.signingCertSet.9.default.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
diff --git a/base/ca/shared/profiles/ca/caECUserCert.cfg b/base/ca/shared/profiles/ca/caECUserCert.cfg
new file mode 100644
index 000000000..a641e5800
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caECUserCert.cfg
@@ -0,0 +1,101 @@
+desc=This certificate profile is for enrolling user ECC certificates.
+visible=false
+enable=true
+enableBy=admin
+name=Manual User Dual-Use ECC Certificate Enrollment
+auth.class_id=
+input.list=i1,i2,i3
+input.i1.class_id=keyGenInputImpl
+input.i2.class_id=subjectNameInputImpl
+input.i3.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=userCertSet
+policyset.userCertSet.list=1,10,2,3,4,5,6,7,8,9
+policyset.userCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.userCertSet.1.constraint.name=Subject Name Constraint
+policyset.userCertSet.1.constraint.params.pattern=UID=.*
+policyset.userCertSet.1.constraint.params.accept=true
+policyset.userCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.userCertSet.1.default.name=Subject Name Default
+policyset.userCertSet.1.default.params.name=
+policyset.userCertSet.10.constraint.class_id=renewGracePeriodConstraintImpl
+policyset.userCertSet.10.constraint.name=Renewal Grace Period Constraint
+policyset.userCertSet.10.constraint.params.renewal.graceBefore=30
+policyset.userCertSet.10.constraint.params.renewal.graceAfter=30
+policyset.userCertSet.10.default.class_id=noDefaultImpl
+policyset.userCertSet.10.default.name=No Default
+policyset.userCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.userCertSet.2.constraint.name=Validity Constraint
+policyset.userCertSet.2.constraint.params.range=365
+policyset.userCertSet.2.constraint.params.notBeforeCheck=false
+policyset.userCertSet.2.constraint.params.notAfterCheck=false
+policyset.userCertSet.2.default.class_id=validityDefaultImpl
+policyset.userCertSet.2.default.name=Validity Default
+policyset.userCertSet.2.default.params.range=180
+policyset.userCertSet.2.default.params.startTime=0
+policyset.userCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.userCertSet.3.constraint.name=Key Constraint
+policyset.userCertSet.3.constraint.params.keyType=EC
+policyset.userCertSet.3.constraint.params.keyParameters=nistp256,nistp384,nistp521
+policyset.userCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.userCertSet.3.default.name=Key Default
+policyset.userCertSet.4.constraint.class_id=noConstraintImpl
+policyset.userCertSet.4.constraint.name=No Constraint
+policyset.userCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.userCertSet.4.default.name=Authority Key Identifier Default
+policyset.userCertSet.5.constraint.class_id=noConstraintImpl
+policyset.userCertSet.5.constraint.name=No Constraint
+policyset.userCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.userCertSet.5.default.name=AIA Extension Default
+policyset.userCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.userCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.userCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.userCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.userCertSet.5.default.params.authInfoAccessCritical=false
+policyset.userCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.userCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.userCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.userCertSet.6.constraint.params.keyUsageCritical=true
+policyset.userCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.userCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.userCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.userCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.userCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.userCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.userCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.userCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.userCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.userCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.userCertSet.6.default.name=Key Usage Default
+policyset.userCertSet.6.default.params.keyUsageCritical=true
+policyset.userCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.userCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.userCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.userCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.userCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.userCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.userCertSet.6.default.params.keyUsageCrlSign=false
+policyset.userCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.userCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.userCertSet.7.constraint.class_id=noConstraintImpl
+policyset.userCertSet.7.constraint.name=No Constraint
+policyset.userCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.userCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.userCertSet.7.default.params.exKeyUsageCritical=false
+policyset.userCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.userCertSet.8.constraint.class_id=noConstraintImpl
+policyset.userCertSet.8.constraint.name=No Constraint
+policyset.userCertSet.8.default.class_id=subjectAltNameExtDefaultImpl
+policyset.userCertSet.8.default.name=Subject Alt Name Constraint
+policyset.userCertSet.8.default.params.subjAltNameExtCritical=false
+policyset.userCertSet.8.default.params.subjAltExtType_0=RFC822Name
+policyset.userCertSet.8.default.params.subjAltExtPattern_0=$request.requestor_email$
+policyset.userCertSet.8.default.params.subjAltExtGNEnable_0=true
+policyset.userCertSet.8.default.params.subjAltNameNumGNs=1
+policyset.userCertSet.9.constraint.class_id=signingAlgConstraintImpl
+policyset.userCertSet.9.constraint.name=No Constraint
+policyset.userCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.userCertSet.9.default.class_id=signingAlgDefaultImpl
+policyset.userCertSet.9.default.name=Signing Alg
+policyset.userCertSet.9.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caEncECUserCert.cfg b/base/ca/shared/profiles/ca/caEncECUserCert.cfg
new file mode 100644
index 000000000..66baa4bf8
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caEncECUserCert.cfg
@@ -0,0 +1,93 @@
+desc=This certificate profile is for enrolling user ECC encryption certificates. It works only with latest Firefox.
+visible=false
+enable=true
+enableBy=admin
+name=Manual User Encryption ECC Certificates Enrollment
+auth.class_id=
+input.list=i1
+input.i1.class_id=encKeyGenInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=encryptionCertSet
+policyset.encryptionCertSet.list=1,2,3,4,5,6,7,8,9
+policyset.encryptionCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.encryptionCertSet.1.constraint.name=Subject Name Constraint
+policyset.encryptionCertSet.1.constraint.params.pattern=CN=.*
+policyset.encryptionCertSet.1.constraint.params.accept=true
+policyset.encryptionCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.encryptionCertSet.1.default.name=Subject Name Default
+policyset.encryptionCertSet.1.default.params.name=
+policyset.encryptionCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.encryptionCertSet.2.constraint.name=Validity Constraint
+policyset.encryptionCertSet.2.constraint.params.range=365
+policyset.encryptionCertSet.2.constraint.params.notBeforeCheck=false
+policyset.encryptionCertSet.2.constraint.params.notAfterCheck=false
+policyset.encryptionCertSet.2.default.class_id=validityDefaultImpl
+policyset.encryptionCertSet.2.default.name=Validity Default
+policyset.encryptionCertSet.2.default.params.range=180
+policyset.encryptionCertSet.2.default.params.startTime=0
+policyset.encryptionCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.encryptionCertSet.3.constraint.name=Key Constraint
+policyset.encryptionCertSet.3.constraint.params.keyType=EC
+policyset.encryptionCertSet.3.constraint.params.keyParameters=nistp256,nistp521
+policyset.encryptionCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.encryptionCertSet.3.default.name=Key Default
+policyset.encryptionCertSet.4.constraint.class_id=noConstraintImpl
+policyset.encryptionCertSet.4.constraint.name=No Constraint
+policyset.encryptionCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.encryptionCertSet.4.default.name=Authority Key Identifier Default
+policyset.encryptionCertSet.5.constraint.class_id=noConstraintImpl
+policyset.encryptionCertSet.5.constraint.name=No Constraint
+policyset.encryptionCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.encryptionCertSet.5.default.name=AIA Extension Default
+policyset.encryptionCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.encryptionCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.encryptionCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.encryptionCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.encryptionCertSet.5.default.params.authInfoAccessCritical=false
+policyset.encryptionCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.encryptionCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.encryptionCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.encryptionCertSet.6.constraint.params.keyUsageCritical=true
+policyset.encryptionCertSet.6.constraint.params.keyUsageDigitalSignature=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageNonRepudiation=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.encryptionCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.encryptionCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.encryptionCertSet.6.default.name=Key Usage Default
+policyset.encryptionCertSet.6.default.params.keyUsageCritical=true
+policyset.encryptionCertSet.6.default.params.keyUsageDigitalSignature=false
+policyset.encryptionCertSet.6.default.params.keyUsageNonRepudiation=false
+policyset.encryptionCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.encryptionCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.encryptionCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.encryptionCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.encryptionCertSet.6.default.params.keyUsageCrlSign=false
+policyset.encryptionCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.encryptionCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.encryptionCertSet.7.constraint.class_id=noConstraintImpl
+policyset.encryptionCertSet.7.constraint.name=No Constraint
+policyset.encryptionCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.encryptionCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.encryptionCertSet.7.default.params.exKeyUsageCritical=false
+policyset.encryptionCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.encryptionCertSet.8.constraint.class_id=noConstraintImpl
+policyset.encryptionCertSet.8.constraint.name=No Constraint
+policyset.encryptionCertSet.8.default.class_id=subjectAltNameExtDefaultImpl
+policyset.encryptionCertSet.8.default.name=Subject Alt Name Constraint
+policyset.encryptionCertSet.8.default.params.subjAltNameExtCritical=false
+policyset.encryptionCertSet.8.default.params.subjAltExtType_0=RFC822Name
+policyset.encryptionCertSet.8.default.params.subjAltExtPattern_0=$request.requestor_email$
+policyset.encryptionCertSet.8.default.params.subjAltExtGNEnable_0=true
+policyset.encryptionCertSet.8.default.params.subjAltNameNumGNs=1
+policyset.encryptionCertSet.9.constraint.class_id=signingAlgConstraintImpl
+policyset.encryptionCertSet.9.constraint.name=No Constraint
+policyset.encryptionCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.encryptionCertSet.9.default.class_id=signingAlgDefaultImpl
+policyset.encryptionCertSet.9.default.name=Signing Alg
+policyset.encryptionCertSet.9.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caEncUserCert.cfg b/base/ca/shared/profiles/ca/caEncUserCert.cfg
new file mode 100644
index 000000000..e49faf24e
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caEncUserCert.cfg
@@ -0,0 +1,96 @@
+desc=This certificate profile is for enrolling user encryption certificates with option to archive keys.
+visible=false
+enable=true
+enableBy=admin
+name=Manual User Encryption Certificates Enrollment
+auth.class_id=
+input.list=i1,i2,i3
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=subjectNameInputImpl
+input.i3.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=encryptionCertSet
+policyset.encryptionCertSet.list=1,2,3,4,5,6,7,8,9
+policyset.encryptionCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.encryptionCertSet.1.constraint.name=Subject Name Constraint
+policyset.encryptionCertSet.1.constraint.params.pattern=CN=.*
+policyset.encryptionCertSet.1.constraint.params.accept=true
+policyset.encryptionCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.encryptionCertSet.1.default.name=Subject Name Default
+policyset.encryptionCertSet.1.default.params.name=
+policyset.encryptionCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.encryptionCertSet.2.constraint.name=Validity Constraint
+policyset.encryptionCertSet.2.constraint.params.range=365
+policyset.encryptionCertSet.2.constraint.params.notBeforeCheck=false
+policyset.encryptionCertSet.2.constraint.params.notAfterCheck=false
+policyset.encryptionCertSet.2.default.class_id=validityDefaultImpl
+policyset.encryptionCertSet.2.default.name=Validity Default
+policyset.encryptionCertSet.2.default.params.range=180
+policyset.encryptionCertSet.2.default.params.startTime=0
+policyset.encryptionCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.encryptionCertSet.3.constraint.name=Key Constraint
+policyset.encryptionCertSet.3.constraint.params.keyType=RSA
+policyset.encryptionCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.encryptionCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.encryptionCertSet.3.default.name=Key Default
+policyset.encryptionCertSet.4.constraint.class_id=noConstraintImpl
+policyset.encryptionCertSet.4.constraint.name=No Constraint
+policyset.encryptionCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.encryptionCertSet.4.default.name=Authority Key Identifier Default
+policyset.encryptionCertSet.5.constraint.class_id=noConstraintImpl
+policyset.encryptionCertSet.5.constraint.name=No Constraint
+policyset.encryptionCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.encryptionCertSet.5.default.name=AIA Extension Default
+policyset.encryptionCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.encryptionCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.encryptionCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.encryptionCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.encryptionCertSet.5.default.params.authInfoAccessCritical=false
+policyset.encryptionCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.encryptionCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.encryptionCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.encryptionCertSet.6.constraint.params.keyUsageCritical=true
+policyset.encryptionCertSet.6.constraint.params.keyUsageDigitalSignature=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageNonRepudiation=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.encryptionCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.encryptionCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.encryptionCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.encryptionCertSet.6.default.name=Key Usage Default
+policyset.encryptionCertSet.6.default.params.keyUsageCritical=true
+policyset.encryptionCertSet.6.default.params.keyUsageDigitalSignature=false
+policyset.encryptionCertSet.6.default.params.keyUsageNonRepudiation=false
+policyset.encryptionCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.encryptionCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.encryptionCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.encryptionCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.encryptionCertSet.6.default.params.keyUsageCrlSign=false
+policyset.encryptionCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.encryptionCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.encryptionCertSet.7.constraint.class_id=noConstraintImpl
+policyset.encryptionCertSet.7.constraint.name=No Constraint
+policyset.encryptionCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.encryptionCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.encryptionCertSet.7.default.params.exKeyUsageCritical=false
+policyset.encryptionCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.encryptionCertSet.8.constraint.class_id=noConstraintImpl
+policyset.encryptionCertSet.8.constraint.name=No Constraint
+policyset.encryptionCertSet.8.default.class_id=subjectAltNameExtDefaultImpl
+policyset.encryptionCertSet.8.default.name=Subject Alt Name Constraint
+policyset.encryptionCertSet.8.default.params.subjAltNameExtCritical=false
+policyset.encryptionCertSet.8.default.params.subjAltExtType_0=RFC822Name
+policyset.encryptionCertSet.8.default.params.subjAltExtPattern_0=$request.requestor_email$
+policyset.encryptionCertSet.8.default.params.subjAltExtGNEnable_0=true
+policyset.encryptionCertSet.8.default.params.subjAltNameNumGNs=1
+policyset.encryptionCertSet.9.constraint.class_id=signingAlgConstraintImpl
+policyset.encryptionCertSet.9.constraint.name=No Constraint
+policyset.encryptionCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.encryptionCertSet.9.default.class_id=signingAlgDefaultImpl
+policyset.encryptionCertSet.9.default.name=Signing Alg
+policyset.encryptionCertSet.9.default.params.signingAlg=-
+
diff --git a/base/ca/shared/profiles/ca/caFullCMCUserCert.cfg b/base/ca/shared/profiles/ca/caFullCMCUserCert.cfg
new file mode 100644
index 000000000..c9507b56f
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caFullCMCUserCert.cfg
@@ -0,0 +1,85 @@
+desc=This certificate profile is for enrolling user certificates by using the CMC certificate request with CMC Signature authentication.
+enable=true
+enableBy=admin
+name=Signed CMC-Authenticated User Certificate Enrollment
+visible=false
+auth.instance_id=CMCAuth
+input.list=i1,i2
+input.i1.class_id=cmcCertReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=cmcUserCertSet
+policyset.cmcUserCertSet.list=1,2,3,4,5,6,7,8
+policyset.cmcUserCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.cmcUserCertSet.1.constraint.name=Subject Name Constraint
+policyset.cmcUserCertSet.1.constraint.params.accept=true
+policyset.cmcUserCertSet.1.constraint.params.pattern=.*
+policyset.cmcUserCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.cmcUserCertSet.1.default.name=Subject Name Default
+policyset.cmcUserCertSet.1.default.params.name=
+policyset.cmcUserCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.cmcUserCertSet.2.constraint.name=Validity Constraint
+policyset.cmcUserCertSet.2.constraint.params.notAfterCheck=false
+policyset.cmcUserCertSet.2.constraint.params.notBeforeCheck=false
+policyset.cmcUserCertSet.2.constraint.params.range=365
+policyset.cmcUserCertSet.2.default.class_id=validityDefaultImpl
+policyset.cmcUserCertSet.2.default.name=Validity Default
+policyset.cmcUserCertSet.2.default.params.range=180
+policyset.cmcUserCertSet.2.default.params.startTime=0
+policyset.cmcUserCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.cmcUserCertSet.3.constraint.name=Key Constraint
+policyset.cmcUserCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.cmcUserCertSet.3.constraint.params.keyType=-
+policyset.cmcUserCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.cmcUserCertSet.3.default.name=Key Default
+policyset.cmcUserCertSet.4.constraint.class_id=noConstraintImpl
+policyset.cmcUserCertSet.4.constraint.name=No Constraint
+policyset.cmcUserCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.cmcUserCertSet.4.default.name=Authority Key Identifier Default
+policyset.cmcUserCertSet.5.constraint.class_id=noConstraintImpl
+policyset.cmcUserCertSet.5.constraint.name=No Constraint
+policyset.cmcUserCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.cmcUserCertSet.5.default.name=AIA Extension Default
+policyset.cmcUserCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.cmcUserCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.cmcUserCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.cmcUserCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.cmcUserCertSet.5.default.params.authInfoAccessCritical=false
+policyset.cmcUserCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.cmcUserCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.cmcUserCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.cmcUserCertSet.6.constraint.params.keyUsageCritical=true
+policyset.cmcUserCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.cmcUserCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.cmcUserCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.cmcUserCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.cmcUserCertSet.6.default.name=Key Usage Default
+policyset.cmcUserCertSet.6.default.params.keyUsageCritical=true
+policyset.cmcUserCertSet.6.default.params.keyUsageCrlSign=false
+policyset.cmcUserCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.cmcUserCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.cmcUserCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.cmcUserCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.cmcUserCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.cmcUserCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.cmcUserCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.cmcUserCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.cmcUserCertSet.7.constraint.class_id=noConstraintImpl
+policyset.cmcUserCertSet.7.constraint.name=No Constraint
+policyset.cmcUserCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.cmcUserCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.cmcUserCertSet.7.default.params.exKeyUsageCritical=false
+policyset.cmcUserCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.cmcUserCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.cmcUserCertSet.8.constraint.name=No Constraint
+policyset.cmcUserCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.cmcUserCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.cmcUserCertSet.8.default.name=Signing Alg
+policyset.cmcUserCertSet.8.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caIPAserviceCert.cfg b/base/ca/shared/profiles/ca/caIPAserviceCert.cfg
new file mode 100644
index 000000000..782df9061
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caIPAserviceCert.cfg
@@ -0,0 +1,97 @@
+desc=This certificate profile is for enrolling server certificates with IPA-RA agent authentication.
+visible=false
+enable=true
+enableBy=admin
+auth.instance_id=raCertAuth
+name=IPA-RA Agent-Authenticated Server Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=serverCertSet
+policyset.serverCertSet.list=1,2,3,4,5,6,7,8
+policyset.serverCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.serverCertSet.1.constraint.name=Subject Name Constraint
+policyset.serverCertSet.1.constraint.params.pattern=CN=[^,]+,.+
+policyset.serverCertSet.1.constraint.params.accept=true
+policyset.serverCertSet.1.default.class_id=subjectNameDefaultImpl
+policyset.serverCertSet.1.default.name=Subject Name Default
+policyset.serverCertSet.1.default.params.name=CN=$request.req_subject_name.cn$, OU=pki-ipa, O=IPA
+policyset.serverCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.serverCertSet.2.constraint.name=Validity Constraint
+policyset.serverCertSet.2.constraint.params.range=740
+policyset.serverCertSet.2.constraint.params.notBeforeCheck=false
+policyset.serverCertSet.2.constraint.params.notAfterCheck=false
+policyset.serverCertSet.2.default.class_id=validityDefaultImpl
+policyset.serverCertSet.2.default.name=Validity Default
+policyset.serverCertSet.2.default.params.range=731
+policyset.serverCertSet.2.default.params.startTime=0
+policyset.serverCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.serverCertSet.3.constraint.name=Key Constraint
+policyset.serverCertSet.3.constraint.params.keyType=RSA
+policyset.serverCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.serverCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.serverCertSet.3.default.name=Key Default
+policyset.serverCertSet.4.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.4.constraint.name=No Constraint
+policyset.serverCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.serverCertSet.4.default.name=Authority Key Identifier Default
+policyset.serverCertSet.5.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.5.constraint.name=No Constraint
+policyset.serverCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.serverCertSet.5.default.name=AIA Extension Default
+policyset.serverCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.serverCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.serverCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.serverCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.serverCertSet.5.default.params.authInfoAccessCritical=false
+policyset.serverCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.serverCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.serverCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.serverCertSet.6.constraint.params.keyUsageCritical=true
+policyset.serverCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.constraint.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.serverCertSet.6.default.name=Key Usage Default
+policyset.serverCertSet.6.default.params.keyUsageCritical=true
+policyset.serverCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.default.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.default.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.7.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.7.constraint.name=No Constraint
+policyset.serverCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.serverCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.serverCertSet.7.default.params.exKeyUsageCritical=false
+policyset.serverCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2
+policyset.serverCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.serverCertSet.8.constraint.name=No Constraint
+policyset.serverCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.serverCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.serverCertSet.8.default.name=Signing Alg
+policyset.serverCertSet.8.default.params.signingAlg=-
+policyset.serverCertSet.9.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.9.constraint.name=No Constraint
+policyset.serverCertSet.9.default.class_id=crlDistributionPointsExtDefaultImpl
+policyset.serverCertSet.9.default.name=CRL Distribution Points Extension Default
+policyset.serverCertSet.9.default.params.crlDistPointsCritical=false
+policyset.serverCertSet.9.default.params.crlDistPointsNum=1
+policyset.serverCertSet.9.default.params.crlDistPointsEnable_0=true
+policyset.serverCertSet.9.default.params.crlDistPointsIssuerName_0=
+policyset.serverCertSet.9.default.params.crlDistPointsIssuerType_0=
+policyset.serverCertSet.9.default.params.crlDistPointsPointName_0=https://ipa.example.com/ipa/crl/MasterCRL.bin
+policyset.serverCertSet.9.default.params.crlDistPointsPointType_0=URIName
+policyset.serverCertSet.9.default.params.crlDistPointsReasons_0=
diff --git a/base/ca/shared/profiles/ca/caInstallCACert.cfg b/base/ca/shared/profiles/ca/caInstallCACert.cfg
new file mode 100644
index 000000000..43588fe30
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caInstallCACert.cfg
@@ -0,0 +1,96 @@
+desc=This certificate profile is for enrolling Security Domain Certificate Authority certificates.
+visible=true
+enable=true
+enableBy=admin
+auth.instance_id=TokenAuth
+authz.acl=group="Enterprise OCSP Administrators" || group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise TKS Administrators" || group="Enterprise TPS Administrators"
+name=Manual Security Domain Certificate Authority Signing Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=caCertSet
+policyset.caCertSet.list=1,2,3,4,5,6,8,9,10
+policyset.caCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.caCertSet.1.constraint.name=Subject Name Constraint
+policyset.caCertSet.1.constraint.params.pattern=CN=.*
+policyset.caCertSet.1.constraint.params.accept=true
+policyset.caCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.caCertSet.1.default.name=Subject Name Default
+policyset.caCertSet.1.default.params.name=
+policyset.caCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.caCertSet.2.constraint.name=Validity Constraint
+policyset.caCertSet.2.constraint.params.range=720
+policyset.caCertSet.2.constraint.params.notBeforeCheck=false
+policyset.caCertSet.2.constraint.params.notAfterCheck=false
+policyset.caCertSet.2.default.class_id=validityDefaultImpl
+policyset.caCertSet.2.default.name=Validity Default
+policyset.caCertSet.2.default.params.range=720
+policyset.caCertSet.2.default.params.startTime=0
+policyset.caCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.caCertSet.3.constraint.name=Key Constraint
+policyset.caCertSet.3.constraint.params.keyType=-
+policyset.caCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.caCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.caCertSet.3.default.name=Key Default
+policyset.caCertSet.4.constraint.class_id=noConstraintImpl
+policyset.caCertSet.4.constraint.name=No Constraint
+policyset.caCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.caCertSet.4.default.name=Authority Key Identifier Default
+policyset.caCertSet.5.constraint.class_id=basicConstraintsExtConstraintImpl
+policyset.caCertSet.5.constraint.name=Basic Constraint Extension Constraint
+policyset.caCertSet.5.constraint.params.basicConstraintsCritical=true
+policyset.caCertSet.5.constraint.params.basicConstraintsIsCA=true
+policyset.caCertSet.5.constraint.params.basicConstraintsMinPathLen=-1
+policyset.caCertSet.5.constraint.params.basicConstraintsMaxPathLen=-1
+policyset.caCertSet.5.default.class_id=basicConstraintsExtDefaultImpl
+policyset.caCertSet.5.default.name=Basic Constraints Extension Default
+policyset.caCertSet.5.default.params.basicConstraintsCritical=true
+policyset.caCertSet.5.default.params.basicConstraintsIsCA=true
+policyset.caCertSet.5.default.params.basicConstraintsPathLen=-1
+policyset.caCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.caCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.caCertSet.6.constraint.params.keyUsageCritical=true
+policyset.caCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.caCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.caCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.caCertSet.6.constraint.params.keyUsageKeyEncipherment=false
+policyset.caCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.caCertSet.6.constraint.params.keyUsageKeyCertSign=true
+policyset.caCertSet.6.constraint.params.keyUsageCrlSign=true
+policyset.caCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.caCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.caCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.caCertSet.6.default.name=Key Usage Default
+policyset.caCertSet.6.default.params.keyUsageCritical=true
+policyset.caCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.caCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.caCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.caCertSet.6.default.params.keyUsageKeyEncipherment=false
+policyset.caCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.caCertSet.6.default.params.keyUsageKeyCertSign=true
+policyset.caCertSet.6.default.params.keyUsageCrlSign=true
+policyset.caCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.caCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.caCertSet.8.constraint.class_id=noConstraintImpl
+policyset.caCertSet.8.constraint.name=No Constraint
+policyset.caCertSet.8.default.class_id=subjectKeyIdentifierExtDefaultImpl
+policyset.caCertSet.8.default.name=Subject Key Identifier Extension Default
+policyset.caCertSet.8.default.params.critical=false
+policyset.caCertSet.9.constraint.class_id=signingAlgConstraintImpl
+policyset.caCertSet.9.constraint.name=No Constraint
+policyset.caCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.caCertSet.9.default.class_id=signingAlgDefaultImpl
+policyset.caCertSet.9.default.name=Signing Alg
+policyset.caCertSet.9.default.params.signingAlg=-
+policyset.caCertSet.10.constraint.class_id=noConstraintImpl
+policyset.caCertSet.10.constraint.name=No Constraint
+policyset.caCertSet.10.default.class_id=authInfoAccessExtDefaultImpl
+policyset.caCertSet.10.default.name=AIA Extension Default
+policyset.caCertSet.10.default.params.authInfoAccessADEnable_0=true
+policyset.caCertSet.10.default.params.authInfoAccessADLocationType_0=URIName
+policyset.caCertSet.10.default.params.authInfoAccessADLocation_0=
+policyset.caCertSet.10.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.caCertSet.10.default.params.authInfoAccessCritical=false
+policyset.caCertSet.10.default.params.authInfoAccessNumADs=1
diff --git a/base/ca/shared/profiles/ca/caInternalAuthAuditSigningCert.cfg b/base/ca/shared/profiles/ca/caInternalAuthAuditSigningCert.cfg
new file mode 100644
index 000000000..e0eb13d35
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caInternalAuthAuditSigningCert.cfg
@@ -0,0 +1,80 @@
+desc=This certificate profile is for enrolling audit signing certificates.
+visible=false
+enable=true
+enableBy=admin
+auth.instance_id=TokenAuth
+authz.acl=group="Enterprise OCSP Administrators" || group="Enterprise RA Administrators" || group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise TKS Administrators" || group="Enterprise TPS Administrators"
+name=Audit Signing Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=auditSigningCertSet
+policyset.auditSigningCertSet.list=1,2,3,4,5,6,9
+policyset.auditSigningCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.auditSigningCertSet.1.constraint.name=Subject Name Constraint
+policyset.auditSigningCertSet.1.constraint.params.pattern=CN=.*
+policyset.auditSigningCertSet.1.constraint.params.accept=true
+policyset.auditSigningCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.auditSigningCertSet.1.default.name=Subject Name Default
+policyset.auditSigningCertSet.1.default.params.name=
+policyset.auditSigningCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.auditSigningCertSet.2.constraint.name=Validity Constraint
+policyset.auditSigningCertSet.2.constraint.params.range=720
+policyset.auditSigningCertSet.2.constraint.params.notBeforeCheck=false
+policyset.auditSigningCertSet.2.constraint.params.notAfterCheck=false
+policyset.auditSigningCertSet.2.default.class_id=validityDefaultImpl
+policyset.auditSigningCertSet.2.default.name=Validity Default
+policyset.auditSigningCertSet.2.default.params.range=720
+policyset.auditSigningCertSet.2.default.params.startTime=0
+policyset.auditSigningCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.auditSigningCertSet.3.constraint.name=Key Constraint
+policyset.auditSigningCertSet.3.constraint.params.keyType=-
+policyset.auditSigningCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.auditSigningCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.auditSigningCertSet.3.default.name=Key Default
+policyset.auditSigningCertSet.4.constraint.class_id=noConstraintImpl
+policyset.auditSigningCertSet.4.constraint.name=No Constraint
+policyset.auditSigningCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.auditSigningCertSet.4.default.name=Authority Key Identifier Default
+policyset.auditSigningCertSet.5.constraint.class_id=noConstraintImpl
+policyset.auditSigningCertSet.5.constraint.name=No Constraint
+policyset.auditSigningCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.auditSigningCertSet.5.default.name=AIA Extension Default
+policyset.auditSigningCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.auditSigningCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.auditSigningCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.auditSigningCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.auditSigningCertSet.5.default.params.authInfoAccessCritical=false
+policyset.auditSigningCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.auditSigningCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.auditSigningCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.auditSigningCertSet.6.constraint.params.keyUsageCritical=true
+policyset.auditSigningCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.auditSigningCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.auditSigningCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.auditSigningCertSet.6.constraint.params.keyUsageKeyEncipherment=false
+policyset.auditSigningCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.auditSigningCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.auditSigningCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.auditSigningCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.auditSigningCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.auditSigningCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.auditSigningCertSet.6.default.name=Key Usage Default
+policyset.auditSigningCertSet.6.default.params.keyUsageCritical=true
+policyset.auditSigningCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.auditSigningCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.auditSigningCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.auditSigningCertSet.6.default.params.keyUsageKeyEncipherment=false
+policyset.auditSigningCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.auditSigningCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.auditSigningCertSet.6.default.params.keyUsageCrlSign=false
+policyset.auditSigningCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.auditSigningCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.auditSigningCertSet.9.constraint.class_id=signingAlgConstraintImpl
+policyset.auditSigningCertSet.9.constraint.name=No Constraint
+policyset.auditSigningCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.auditSigningCertSet.9.default.class_id=signingAlgDefaultImpl
+policyset.auditSigningCertSet.9.default.name=Signing Alg
+policyset.auditSigningCertSet.9.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caInternalAuthDRMstorageCert.cfg b/base/ca/shared/profiles/ca/caInternalAuthDRMstorageCert.cfg
new file mode 100644
index 000000000..d5da9f599
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caInternalAuthDRMstorageCert.cfg
@@ -0,0 +1,86 @@
+desc=This certificate profile is for enrolling Security Domain DRM storage certificates
+visible=false
+enable=true
+enableBy=admin
+auth.instance_id=TokenAuth
+authz.acl=group="Enterprise OCSP Administrators" || group="Enterprise RA Administrators" || group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise TKS Administrators" || group="Enterprise TPS Administrators"
+name=Security Domain DRM storage Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=drmStorageCertSet
+policyset.drmStorageCertSet.list=1,2,3,4,5,6,7,9
+policyset.drmStorageCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.drmStorageCertSet.1.constraint.name=Subject Name Constraint
+policyset.drmStorageCertSet.1.constraint.params.pattern=CN=.*
+policyset.drmStorageCertSet.1.constraint.params.accept=true
+policyset.drmStorageCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.drmStorageCertSet.1.default.name=Subject Name Default
+policyset.drmStorageCertSet.1.default.params.name=
+policyset.drmStorageCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.drmStorageCertSet.2.constraint.name=Validity Constraint
+policyset.drmStorageCertSet.2.constraint.params.range=720
+policyset.drmStorageCertSet.2.constraint.params.notBeforeCheck=false
+policyset.drmStorageCertSet.2.constraint.params.notAfterCheck=false
+policyset.drmStorageCertSet.2.default.class_id=validityDefaultImpl
+policyset.drmStorageCertSet.2.default.name=Validity Default
+policyset.drmStorageCertSet.2.default.params.range=720
+policyset.drmStorageCertSet.2.default.params.startTime=0
+policyset.drmStorageCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.drmStorageCertSet.3.constraint.name=Key Constraint
+policyset.drmStorageCertSet.3.constraint.params.keyType=-
+policyset.drmStorageCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.drmStorageCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.drmStorageCertSet.3.default.name=Key Default
+policyset.drmStorageCertSet.4.constraint.class_id=noConstraintImpl
+policyset.drmStorageCertSet.4.constraint.name=No Constraint
+policyset.drmStorageCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.drmStorageCertSet.4.default.name=Authority Key Identifier Default
+policyset.drmStorageCertSet.5.constraint.class_id=noConstraintImpl
+policyset.drmStorageCertSet.5.constraint.name=No Constraint
+policyset.drmStorageCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.drmStorageCertSet.5.default.name=AIA Extension Default
+policyset.drmStorageCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.drmStorageCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.drmStorageCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.drmStorageCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.drmStorageCertSet.5.default.params.authInfoAccessCritical=false
+policyset.drmStorageCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.drmStorageCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.drmStorageCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.drmStorageCertSet.6.constraint.params.keyUsageCritical=true
+policyset.drmStorageCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.drmStorageCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.drmStorageCertSet.6.constraint.params.keyUsageDataEncipherment=true
+policyset.drmStorageCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.drmStorageCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.drmStorageCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.drmStorageCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.drmStorageCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.drmStorageCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.drmStorageCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.drmStorageCertSet.6.default.name=Key Usage Default
+policyset.drmStorageCertSet.6.default.params.keyUsageCritical=true
+policyset.drmStorageCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.drmStorageCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.drmStorageCertSet.6.default.params.keyUsageDataEncipherment=true
+policyset.drmStorageCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.drmStorageCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.drmStorageCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.drmStorageCertSet.6.default.params.keyUsageCrlSign=false
+policyset.drmStorageCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.drmStorageCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.drmStorageCertSet.7.constraint.class_id=noConstraintImpl
+policyset.drmStorageCertSet.7.constraint.name=No Constraint
+policyset.drmStorageCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.drmStorageCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.drmStorageCertSet.7.default.params.exKeyUsageCritical=false
+policyset.drmStorageCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2
+policyset.drmStorageCertSet.9.constraint.class_id=signingAlgConstraintImpl
+policyset.drmStorageCertSet.9.constraint.name=No Constraint
+policyset.drmStorageCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.drmStorageCertSet.9.default.class_id=signingAlgDefaultImpl
+policyset.drmStorageCertSet.9.default.name=Signing Alg
+policyset.drmStorageCertSet.9.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caInternalAuthOCSPCert.cfg b/base/ca/shared/profiles/ca/caInternalAuthOCSPCert.cfg
new file mode 100644
index 000000000..de07df565
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caInternalAuthOCSPCert.cfg
@@ -0,0 +1,71 @@
+desc=This certificate profile is for enrolling Security Domain OCSP Manager certificates.
+visible=false
+enable=true
+enableBy=admin
+auth.instance_id=TokenAuth
+authz.acl=group="Enterprise OCSP Administrators" || group="Enterprise RA Administrators" || group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise TKS Administrators" || group="Enterprise TPS Administrators"
+name=Security Domain OCSP Manager Signing Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=ocspCertSet
+policyset.ocspCertSet.list=1,2,3,4,5,6,8,9
+policyset.ocspCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.ocspCertSet.1.constraint.name=Subject Name Constraint
+policyset.ocspCertSet.1.constraint.params.pattern=CN=.*
+policyset.ocspCertSet.1.constraint.params.accept=true
+policyset.ocspCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.ocspCertSet.1.default.name=Subject Name Default
+policyset.ocspCertSet.1.default.params.name=
+policyset.ocspCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.ocspCertSet.2.constraint.name=Validity Constraint
+policyset.ocspCertSet.2.constraint.params.range=720
+policyset.ocspCertSet.2.constraint.params.notBeforeCheck=false
+policyset.ocspCertSet.2.constraint.params.notAfterCheck=false
+policyset.ocspCertSet.2.default.class_id=validityDefaultImpl
+policyset.ocspCertSet.2.default.name=Validity Default
+policyset.ocspCertSet.2.default.params.range=720
+policyset.ocspCertSet.2.default.params.startTime=0
+policyset.ocspCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.ocspCertSet.3.constraint.name=Key Constraint
+policyset.ocspCertSet.3.constraint.params.keyType=-
+policyset.ocspCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.ocspCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.ocspCertSet.3.default.name=Key Default
+policyset.ocspCertSet.4.constraint.class_id=noConstraintImpl
+policyset.ocspCertSet.4.constraint.name=No Constraint
+policyset.ocspCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.ocspCertSet.4.default.name=Authority Key Identifier Default
+policyset.ocspCertSet.5.constraint.class_id=noConstraintImpl
+policyset.ocspCertSet.5.constraint.name=No Constraint
+policyset.ocspCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.ocspCertSet.5.default.name=AIA Extension Default
+policyset.ocspCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.ocspCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.ocspCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.ocspCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.ocspCertSet.5.default.params.authInfoAccessCritical=false
+policyset.ocspCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.ocspCertSet.6.constraint.class_id=extendedKeyUsageExtConstraintImpl
+policyset.ocspCertSet.6.constraint.name=Extended Key Usage Extension
+policyset.ocspCertSet.6.constraint.params.exKeyUsageCritical=false
+policyset.ocspCertSet.6.constraint.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.9
+policyset.ocspCertSet.6.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.ocspCertSet.6.default.name=Extended Key Usage Default
+policyset.ocspCertSet.6.default.params.exKeyUsageCritical=false
+policyset.ocspCertSet.6.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.9
+policyset.ocspCertSet.8.constraint.class_id=extensionConstraintImpl
+policyset.ocspCertSet.8.constraint.name=No Constraint
+policyset.ocspCertSet.8.constraint.params.extCritical=false
+policyset.ocspCertSet.8.constraint.params.extOID=1.3.6.1.5.5.7.48.1.5
+policyset.ocspCertSet.8.default.class_id=ocspNoCheckExtDefaultImpl
+policyset.ocspCertSet.8.default.name=OCSP No Check Extension
+policyset.ocspCertSet.8.default.params.ocspNoCheckCritical=false
+policyset.ocspCertSet.9.constraint.class_id=signingAlgConstraintImpl
+policyset.ocspCertSet.9.constraint.name=No Constraint
+policyset.ocspCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.ocspCertSet.9.default.class_id=signingAlgDefaultImpl
+policyset.ocspCertSet.9.default.name=Signing Alg
+policyset.ocspCertSet.9.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caInternalAuthServerCert.cfg b/base/ca/shared/profiles/ca/caInternalAuthServerCert.cfg
new file mode 100644
index 000000000..f639d243b
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caInternalAuthServerCert.cfg
@@ -0,0 +1,86 @@
+desc=This certificate profile is for enrolling Security Domain server certificates.
+visible=false
+enable=true
+enableBy=admin
+auth.instance_id=TokenAuth
+authz.acl=group="Enterprise OCSP Administrators" || group="Enterprise RA Administrators" || group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise TKS Administrators" || group="Enterprise TPS Administrators"
+name=Security Domain Server Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=serverCertSet
+policyset.serverCertSet.list=1,2,3,4,5,6,7,8
+policyset.serverCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.serverCertSet.1.constraint.name=Subject Name Constraint
+policyset.serverCertSet.1.constraint.params.pattern=CN=.*
+policyset.serverCertSet.1.constraint.params.accept=true
+policyset.serverCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.serverCertSet.1.default.name=Subject Name Default
+policyset.serverCertSet.1.default.params.name=
+policyset.serverCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.serverCertSet.2.constraint.name=Validity Constraint
+policyset.serverCertSet.2.constraint.params.range=720
+policyset.serverCertSet.2.constraint.params.notBeforeCheck=false
+policyset.serverCertSet.2.constraint.params.notAfterCheck=false
+policyset.serverCertSet.2.default.class_id=validityDefaultImpl
+policyset.serverCertSet.2.default.name=Validity Default
+policyset.serverCertSet.2.default.params.range=720
+policyset.serverCertSet.2.default.params.startTime=0
+policyset.serverCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.serverCertSet.3.constraint.name=Key Constraint
+policyset.serverCertSet.3.constraint.params.keyType=-
+policyset.serverCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.serverCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.serverCertSet.3.default.name=Key Default
+policyset.serverCertSet.4.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.4.constraint.name=No Constraint
+policyset.serverCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.serverCertSet.4.default.name=Authority Key Identifier Default
+policyset.serverCertSet.5.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.5.constraint.name=No Constraint
+policyset.serverCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.serverCertSet.5.default.name=AIA Extension Default
+policyset.serverCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.serverCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.serverCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.serverCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.serverCertSet.5.default.params.authInfoAccessCritical=false
+policyset.serverCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.serverCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.serverCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.serverCertSet.6.constraint.params.keyUsageCritical=true
+policyset.serverCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.constraint.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.serverCertSet.6.default.name=Key Usage Default
+policyset.serverCertSet.6.default.params.keyUsageCritical=true
+policyset.serverCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.default.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.default.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.7.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.7.constraint.name=No Constraint
+policyset.serverCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.serverCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.serverCertSet.7.default.params.exKeyUsageCritical=false
+policyset.serverCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.serverCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.serverCertSet.8.constraint.name=No Constraint
+policyset.serverCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.serverCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.serverCertSet.8.default.name=Signing Alg
+policyset.serverCertSet.8.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caInternalAuthSubsystemCert.cfg b/base/ca/shared/profiles/ca/caInternalAuthSubsystemCert.cfg
new file mode 100644
index 000000000..ed18a547e
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caInternalAuthSubsystemCert.cfg
@@ -0,0 +1,88 @@
+desc=This certificate profile is for enrolling Security Domain subsystem certificates.
+visible=false
+enable=true
+enableBy=admin
+auth.instance_id=TokenAuth
+authz.acl=group="Enterprise OCSP Administrators" || group="Enterprise RA Administrators" || group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise TKS Administrators" || group="Enterprise TPS Administrators"
+name=Security Domain Subsystem Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+updater.list=u1
+updater.u1.class_id=subsystemGroupUpdaterImpl
+policyset.list=serverCertSet
+policyset.serverCertSet.list=1,2,3,4,5,6,7,8
+policyset.serverCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.serverCertSet.1.constraint.name=Subject Name Constraint
+policyset.serverCertSet.1.constraint.params.pattern=CN=.*
+policyset.serverCertSet.1.constraint.params.accept=true
+policyset.serverCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.serverCertSet.1.default.name=Subject Name Default
+policyset.serverCertSet.1.default.params.name=
+policyset.serverCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.serverCertSet.2.constraint.name=Validity Constraint
+policyset.serverCertSet.2.constraint.params.range=720
+policyset.serverCertSet.2.constraint.params.notBeforeCheck=false
+policyset.serverCertSet.2.constraint.params.notAfterCheck=false
+policyset.serverCertSet.2.default.class_id=validityDefaultImpl
+policyset.serverCertSet.2.default.name=Validity Default
+policyset.serverCertSet.2.default.params.range=720
+policyset.serverCertSet.2.default.params.startTime=0
+policyset.serverCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.serverCertSet.3.constraint.name=Key Constraint
+policyset.serverCertSet.3.constraint.params.keyType=-
+policyset.serverCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.serverCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.serverCertSet.3.default.name=Key Default
+policyset.serverCertSet.4.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.4.constraint.name=No Constraint
+policyset.serverCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.serverCertSet.4.default.name=Authority Key Identifier Default
+policyset.serverCertSet.5.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.5.constraint.name=No Constraint
+policyset.serverCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.serverCertSet.5.default.name=AIA Extension Default
+policyset.serverCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.serverCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.serverCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.serverCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.serverCertSet.5.default.params.authInfoAccessCritical=false
+policyset.serverCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.serverCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.serverCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.serverCertSet.6.constraint.params.keyUsageCritical=true
+policyset.serverCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.constraint.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.serverCertSet.6.default.name=Key Usage Default
+policyset.serverCertSet.6.default.params.keyUsageCritical=true
+policyset.serverCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.default.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.default.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.7.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.7.constraint.name=No Constraint
+policyset.serverCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.serverCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.serverCertSet.7.default.params.exKeyUsageCritical=false
+policyset.serverCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2
+policyset.serverCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.serverCertSet.8.constraint.name=No Constraint
+policyset.serverCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.serverCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.serverCertSet.8.default.name=Signing Alg
+policyset.serverCertSet.8.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caInternalAuthTransportCert.cfg b/base/ca/shared/profiles/ca/caInternalAuthTransportCert.cfg
new file mode 100644
index 000000000..538c76071
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caInternalAuthTransportCert.cfg
@@ -0,0 +1,86 @@
+desc=This certificate profile is for enrolling Security Domain Data Recovery Manager transport certificates.
+visible=false
+enable=true
+enableBy=admin
+auth.instance_id=TokenAuth
+authz.acl=group="Enterprise OCSP Administrators" || group="Enterprise RA Administrators" || group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise TKS Administrators" || group="Enterprise TPS Administrators"
+name=Security Domain Data Recovery Manager Transport Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=transportCertSet
+policyset.transportCertSet.list=1,2,3,4,5,6,7,8
+policyset.transportCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.transportCertSet.1.constraint.name=Subject Name Constraint
+policyset.transportCertSet.1.constraint.params.pattern=CN=.*
+policyset.transportCertSet.1.constraint.params.accept=true
+policyset.transportCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.transportCertSet.1.default.name=Subject Name Default
+policyset.transportCertSet.1.default.params.name=
+policyset.transportCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.transportCertSet.2.constraint.name=Validity Constraint
+policyset.transportCertSet.2.constraint.params.range=720
+policyset.transportCertSet.2.constraint.params.notBeforeCheck=false
+policyset.transportCertSet.2.constraint.params.notAfterCheck=false
+policyset.transportCertSet.2.default.class_id=validityDefaultImpl
+policyset.transportCertSet.2.default.name=Validity Default
+policyset.transportCertSet.2.default.params.range=720
+policyset.transportCertSet.2.default.params.startTime=0
+policyset.transportCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.transportCertSet.3.constraint.name=Key Constraint
+policyset.transportCertSet.3.constraint.params.keyType=-
+policyset.transportCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.transportCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.transportCertSet.3.default.name=Key Default
+policyset.transportCertSet.4.constraint.class_id=noConstraintImpl
+policyset.transportCertSet.4.constraint.name=No Constraint
+policyset.transportCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.transportCertSet.4.default.name=Authority Key Identifier Default
+policyset.transportCertSet.5.constraint.class_id=noConstraintImpl
+policyset.transportCertSet.5.constraint.name=No Constraint
+policyset.transportCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.transportCertSet.5.default.name=AIA Extension Default
+policyset.transportCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.transportCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.transportCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.transportCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.transportCertSet.5.default.params.authInfoAccessCritical=false
+policyset.transportCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.transportCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.transportCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.transportCertSet.6.constraint.params.keyUsageCritical=true
+policyset.transportCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.transportCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.transportCertSet.6.constraint.params.keyUsageDataEncipherment=true
+policyset.transportCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.transportCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.transportCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.transportCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.transportCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.transportCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.transportCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.transportCertSet.6.default.name=Key Usage Default
+policyset.transportCertSet.6.default.params.keyUsageCritical=true
+policyset.transportCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.transportCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.transportCertSet.6.default.params.keyUsageDataEncipherment=true
+policyset.transportCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.transportCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.transportCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.transportCertSet.6.default.params.keyUsageCrlSign=false
+policyset.transportCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.transportCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.transportCertSet.7.constraint.class_id=noConstraintImpl
+policyset.transportCertSet.7.constraint.name=No Constraint
+policyset.transportCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.transportCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.transportCertSet.7.default.params.exKeyUsageCritical=false
+policyset.transportCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2
+policyset.transportCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.transportCertSet.8.constraint.name=No Constraint
+policyset.transportCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.transportCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.transportCertSet.8.default.name=Signing Alg
+policyset.transportCertSet.8.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caJarSigningCert.cfg b/base/ca/shared/profiles/ca/caJarSigningCert.cfg
new file mode 100644
index 000000000..5ddf00776
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caJarSigningCert.cfg
@@ -0,0 +1,86 @@
+desc=This is an IPA profile for enrolling Jar Signing certificates.
+enable=true
+enableBy=admin
+name=Manual Jar Signing Certificate Enrollment
+visible=false
+auth.class_id=
+auth.instance_id=raCertAuth
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=caJarSigningSet
+policyset.caJarSigningSet.list=1,2,3,4,5,6
+policyset.caJarSigningSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.caJarSigningSet.1.constraint.name=Subject Name Constraint
+policyset.caJarSigningSet.1.constraint.params.accept=true
+policyset.caJarSigningSet.1.constraint.params.pattern=.*
+policyset.caJarSigningSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.caJarSigningSet.1.default.name=Subject Name Default
+policyset.caJarSigningSet.1.default.params.name=
+policyset.caJarSigningSet.2.constraint.class_id=validityConstraintImpl
+policyset.caJarSigningSet.2.constraint.name=Validity Constraint
+policyset.caJarSigningSet.2.constraint.params.notAfterCheck=false
+policyset.caJarSigningSet.2.constraint.params.notBeforeCheck=false
+policyset.caJarSigningSet.2.constraint.params.range=2922
+policyset.caJarSigningSet.2.default.class_id=validityDefaultImpl
+policyset.caJarSigningSet.2.default.name=Validity Default
+policyset.caJarSigningSet.2.default.params.range=1461
+policyset.caJarSigningSet.2.default.params.startTime=60
+policyset.caJarSigningSet.3.constraint.class_id=keyConstraintImpl
+policyset.caJarSigningSet.3.constraint.name=Key Constraint
+policyset.caJarSigningSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.caJarSigningSet.3.constraint.params.keyType=RSA
+policyset.caJarSigningSet.3.default.class_id=userKeyDefaultImpl
+policyset.caJarSigningSet.3.default.name=Key Default
+policyset.caJarSigningSet.4.constraint.class_id=keyUsageExtConstraintImpl
+policyset.caJarSigningSet.4.constraint.name=Key Usage Extension Constraint
+policyset.caJarSigningSet.4.constraint.params.keyUsageCritical=-
+policyset.caJarSigningSet.4.constraint.params.keyUsageCrlSign=-
+policyset.caJarSigningSet.4.constraint.params.keyUsageDataEncipherment=-
+policyset.caJarSigningSet.4.constraint.params.keyUsageDecipherOnly=-
+policyset.caJarSigningSet.4.constraint.params.keyUsageDigitalSignature=-
+policyset.caJarSigningSet.4.constraint.params.keyUsageEncipherOnly=-
+policyset.caJarSigningSet.4.constraint.params.keyUsageKeyAgreement=-
+policyset.caJarSigningSet.4.constraint.params.keyUsageKeyCertSign=-
+policyset.caJarSigningSet.4.constraint.params.keyUsageKeyEncipherment=-
+policyset.caJarSigningSet.4.constraint.params.keyUsageNonRepudiation=-
+policyset.caJarSigningSet.4.default.class_id=keyUsageExtDefaultImpl
+policyset.caJarSigningSet.4.default.name=Key Usage Default
+policyset.caJarSigningSet.4.default.params.keyUsageCritical=true
+policyset.caJarSigningSet.4.default.params.keyUsageCrlSign=false
+policyset.caJarSigningSet.4.default.params.keyUsageDataEncipherment=false
+policyset.caJarSigningSet.4.default.params.keyUsageDecipherOnly=false
+policyset.caJarSigningSet.4.default.params.keyUsageDigitalSignature=true
+policyset.caJarSigningSet.4.default.params.keyUsageEncipherOnly=false
+policyset.caJarSigningSet.4.default.params.keyUsageKeyAgreement=false
+policyset.caJarSigningSet.4.default.params.keyUsageKeyCertSign=true
+policyset.caJarSigningSet.4.default.params.keyUsageKeyEncipherment=false
+policyset.caJarSigningSet.4.default.params.keyUsageNonRepudiation=false
+policyset.caJarSigningSet.5.constraint.class_id=nsCertTypeExtConstraintImpl
+policyset.caJarSigningSet.5.constraint.name=Netscape Certificate Type Extension Constraint
+policyset.caJarSigningSet.5.constraint.params.nsCertCritical=-
+policyset.caJarSigningSet.5.constraint.params.nsCertEmail=-
+policyset.caJarSigningSet.5.constraint.params.nsCertEmailCA=-
+policyset.caJarSigningSet.5.constraint.params.nsCertObjectSigning=-
+policyset.caJarSigningSet.5.constraint.params.nsCertObjectSigningCA=-
+policyset.caJarSigningSet.5.constraint.params.nsCertSSLCA=-
+policyset.caJarSigningSet.5.constraint.params.nsCertSSLClient=-
+policyset.caJarSigningSet.5.constraint.params.nsCertSSLServer=-
+policyset.caJarSigningSet.5.default.class_id=nsCertTypeExtDefaultImpl
+policyset.caJarSigningSet.5.default.name=Netscape Certificate Type Extension Default
+policyset.caJarSigningSet.5.default.params.nsCertCritical=false
+policyset.caJarSigningSet.5.default.params.nsCertEmail=false
+policyset.caJarSigningSet.5.default.params.nsCertEmailCA=false
+policyset.caJarSigningSet.5.default.params.nsCertObjectSigning=true
+policyset.caJarSigningSet.5.default.params.nsCertObjectSigningCA=false
+policyset.caJarSigningSet.5.default.params.nsCertSSLCA=false
+policyset.caJarSigningSet.5.default.params.nsCertSSLClient=false
+policyset.caJarSigningSet.5.default.params.nsCertSSLServer=false
+policyset.caJarSigningSet.6.constraint.class_id=signingAlgConstraintImpl
+policyset.caJarSigningSet.6.constraint.name=No Constraint
+policyset.caJarSigningSet.6.constraint.params.signingAlgsAllowed=MD5withRSA,MD2withRSA,SHA1withRSA,SHA256withRSA,SHA512withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.caJarSigningSet.6.default.class_id=signingAlgDefaultImpl
+policyset.caJarSigningSet.6.default.name=Signing Alg
+policyset.caJarSigningSet.6.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caManualRenewal.cfg b/base/ca/shared/profiles/ca/caManualRenewal.cfg
new file mode 100755
index 000000000..e470f2a28
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caManualRenewal.cfg
@@ -0,0 +1,11 @@
+desc=This certificate profile is for renewing certificates to be approved manually by agents.
+visible=true
+enable=true
+enableBy=admin
+renewal=true
+auth.instance_id=
+name=Renewal: Renew certificate to be manually approved by agents
+input.list=i1
+input.i1.class_id=serialNumRenewInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
diff --git a/base/ca/shared/profiles/ca/caOCSPCert.cfg b/base/ca/shared/profiles/ca/caOCSPCert.cfg
new file mode 100644
index 000000000..bda3ee752
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caOCSPCert.cfg
@@ -0,0 +1,70 @@
+desc=This certificate profile is for enrolling OCSP Manager certificates.
+visible=true
+enable=true
+enableBy=admin
+auth.class_id=
+name=Manual OCSP Manager Signing Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=ocspCertSet
+policyset.ocspCertSet.list=1,2,3,4,5,6,8,9
+policyset.ocspCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.ocspCertSet.1.constraint.name=Subject Name Constraint
+policyset.ocspCertSet.1.constraint.params.pattern=CN=.*
+policyset.ocspCertSet.1.constraint.params.accept=true
+policyset.ocspCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.ocspCertSet.1.default.name=Subject Name Default
+policyset.ocspCertSet.1.default.params.name=
+policyset.ocspCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.ocspCertSet.2.constraint.name=Validity Constraint
+policyset.ocspCertSet.2.constraint.params.range=720
+policyset.ocspCertSet.2.constraint.params.notBeforeCheck=false
+policyset.ocspCertSet.2.constraint.params.notAfterCheck=false
+policyset.ocspCertSet.2.default.class_id=validityDefaultImpl
+policyset.ocspCertSet.2.default.name=Validity Default
+policyset.ocspCertSet.2.default.params.range=720
+policyset.ocspCertSet.2.default.params.startTime=0
+policyset.ocspCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.ocspCertSet.3.constraint.name=Key Constraint
+policyset.ocspCertSet.3.constraint.params.keyType=RSA
+policyset.ocspCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.ocspCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.ocspCertSet.3.default.name=Key Default
+policyset.ocspCertSet.4.constraint.class_id=noConstraintImpl
+policyset.ocspCertSet.4.constraint.name=No Constraint
+policyset.ocspCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.ocspCertSet.4.default.name=Authority Key Identifier Default
+policyset.ocspCertSet.5.constraint.class_id=noConstraintImpl
+policyset.ocspCertSet.5.constraint.name=No Constraint
+policyset.ocspCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.ocspCertSet.5.default.name=AIA Extension Default
+policyset.ocspCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.ocspCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.ocspCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.ocspCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.ocspCertSet.5.default.params.authInfoAccessCritical=false
+policyset.ocspCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.ocspCertSet.6.constraint.class_id=extendedKeyUsageExtConstraintImpl
+policyset.ocspCertSet.6.constraint.name=Extended Key Usage Extension
+policyset.ocspCertSet.6.constraint.params.exKeyUsageCritical=false
+policyset.ocspCertSet.6.constraint.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.9
+policyset.ocspCertSet.6.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.ocspCertSet.6.default.name=Extended Key Usage Default
+policyset.ocspCertSet.6.default.params.exKeyUsageCritical=false
+policyset.ocspCertSet.6.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.9
+policyset.ocspCertSet.8.constraint.class_id=extensionConstraintImpl
+policyset.ocspCertSet.8.constraint.name=No Constraint
+policyset.ocspCertSet.8.constraint.params.extCritical=false
+policyset.ocspCertSet.8.constraint.params.extOID=1.3.6.1.5.5.7.48.1.5
+policyset.ocspCertSet.8.default.class_id=ocspNoCheckExtDefaultImpl
+policyset.ocspCertSet.8.default.name=OCSP No Check Extension
+policyset.ocspCertSet.8.default.params.ocspNoCheckCritical=false
+policyset.ocspCertSet.9.constraint.class_id=signingAlgConstraintImpl
+policyset.ocspCertSet.9.constraint.name=No Constraint
+policyset.ocspCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.ocspCertSet.9.default.class_id=signingAlgDefaultImpl
+policyset.ocspCertSet.9.default.name=Signing Alg
+policyset.ocspCertSet.9.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caOtherCert.cfg b/base/ca/shared/profiles/ca/caOtherCert.cfg
new file mode 100644
index 000000000..305a37b92
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caOtherCert.cfg
@@ -0,0 +1,85 @@
+desc=This certificate profile is for enrolling other certificates.
+visible=true
+enable=true
+enableBy=admin
+auth.class_id=
+name=Other Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=otherCertSet
+policyset.otherCertSet.list=1,2,3,4,5,6,7,8
+policyset.otherCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.otherCertSet.1.constraint.name=Subject Name Constraint
+policyset.otherCertSet.1.constraint.params.pattern=CN=.*
+policyset.otherCertSet.1.constraint.params.accept=true
+policyset.otherCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.otherCertSet.1.default.name=Subject Name Default
+policyset.otherCertSet.1.default.params.name=
+policyset.otherCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.otherCertSet.2.constraint.name=Validity Constraint
+policyset.otherCertSet.2.constraint.params.range=720
+policyset.otherCertSet.2.constraint.params.notBeforeCheck=false
+policyset.otherCertSet.2.constraint.params.notAfterCheck=false
+policyset.otherCertSet.2.default.class_id=validityDefaultImpl
+policyset.otherCertSet.2.default.name=Validity Default
+policyset.otherCertSet.2.default.params.range=720
+policyset.otherCertSet.2.default.params.startTime=0
+policyset.otherCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.otherCertSet.3.constraint.name=Key Constraint
+policyset.otherCertSet.3.constraint.params.keyType=RSA
+policyset.otherCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.otherCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.otherCertSet.3.default.name=Key Default
+policyset.otherCertSet.4.constraint.class_id=noConstraintImpl
+policyset.otherCertSet.4.constraint.name=No Constraint
+policyset.otherCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.otherCertSet.4.default.name=Authority Key Identifier Default
+policyset.otherCertSet.5.constraint.class_id=noConstraintImpl
+policyset.otherCertSet.5.constraint.name=No Constraint
+policyset.otherCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.otherCertSet.5.default.name=AIA Extension Default
+policyset.otherCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.otherCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.otherCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.otherCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.otherCertSet.5.default.params.authInfoAccessCritical=false
+policyset.otherCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.otherCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.otherCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.otherCertSet.6.constraint.params.keyUsageCritical=true
+policyset.otherCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.otherCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.otherCertSet.6.constraint.params.keyUsageDataEncipherment=true
+policyset.otherCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.otherCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.otherCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.otherCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.otherCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.otherCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.otherCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.otherCertSet.6.default.name=Key Usage Default
+policyset.otherCertSet.6.default.params.keyUsageCritical=true
+policyset.otherCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.otherCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.otherCertSet.6.default.params.keyUsageDataEncipherment=true
+policyset.otherCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.otherCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.otherCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.otherCertSet.6.default.params.keyUsageCrlSign=false
+policyset.otherCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.otherCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.otherCertSet.7.constraint.class_id=noConstraintImpl
+policyset.otherCertSet.7.constraint.name=No Constraint
+policyset.otherCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.otherCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.otherCertSet.7.default.params.exKeyUsageCritical=false
+policyset.otherCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.1
+policyset.otherCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.otherCertSet.8.constraint.name=No Constraint
+policyset.otherCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.otherCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.otherCertSet.8.default.name=Signing Alg
+policyset.otherCertSet.8.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caRACert.cfg b/base/ca/shared/profiles/ca/caRACert.cfg
new file mode 100644
index 000000000..a3d8dc45f
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caRACert.cfg
@@ -0,0 +1,85 @@
+desc=This certificate profile is for enrolling Registration Manager certificates.
+visible=true
+enable=true
+enableBy=admin
+auth.class_id=
+name=Manual Registration Manager Signing Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=raCertSet
+policyset.raCertSet.list=1,2,3,4,5,6,7,8
+policyset.raCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.raCertSet.1.constraint.name=Subject Name Constraint
+policyset.raCertSet.1.constraint.params.pattern=CN=.*
+policyset.raCertSet.1.constraint.params.accept=true
+policyset.raCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.raCertSet.1.default.name=Subject Name Default
+policyset.raCertSet.1.default.params.name=
+policyset.raCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.raCertSet.2.constraint.name=Validity Constraint
+policyset.raCertSet.2.constraint.params.range=720
+policyset.raCertSet.2.constraint.params.notBeforeCheck=false
+policyset.raCertSet.2.constraint.params.notAfterCheck=false
+policyset.raCertSet.2.default.class_id=validityDefaultImpl
+policyset.raCertSet.2.default.name=Validity Default
+policyset.raCertSet.2.default.params.range=720
+policyset.raCertSet.2.default.params.startTime=0
+policyset.raCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.raCertSet.3.constraint.name=Key Constraint
+policyset.raCertSet.3.constraint.params.keyType=RSA
+policyset.raCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.raCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.raCertSet.3.default.name=Key Default
+policyset.raCertSet.4.constraint.class_id=noConstraintImpl
+policyset.raCertSet.4.constraint.name=No Constraint
+policyset.raCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.raCertSet.4.default.name=Authority Key Identifier Default
+policyset.raCertSet.5.constraint.class_id=noConstraintImpl
+policyset.raCertSet.5.constraint.name=No Constraint
+policyset.raCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.raCertSet.5.default.name=AIA Extension Default
+policyset.raCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.raCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.raCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.raCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.raCertSet.5.default.params.authInfoAccessCritical=false
+policyset.raCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.raCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.raCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.raCertSet.6.constraint.params.keyUsageCritical=true
+policyset.raCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.raCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.raCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.raCertSet.6.constraint.params.keyUsageKeyEncipherment=false
+policyset.raCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.raCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.raCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.raCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.raCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.raCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.raCertSet.6.default.name=Key Usage Default
+policyset.raCertSet.6.default.params.keyUsageCritical=true
+policyset.raCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.raCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.raCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.raCertSet.6.default.params.keyUsageKeyEncipherment=false
+policyset.raCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.raCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.raCertSet.6.default.params.keyUsageCrlSign=false
+policyset.raCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.raCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.raCertSet.7.constraint.class_id=noConstraintImpl
+policyset.raCertSet.7.constraint.name=No Constraint
+policyset.raCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.raCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.raCertSet.7.default.params.exKeyUsageCritical=false
+policyset.raCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2
+policyset.raCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.raCertSet.8.constraint.name=No Constraint
+policyset.raCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.raCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.raCertSet.8.default.name=Signing Alg
+policyset.raCertSet.8.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caRARouterCert.cfg b/base/ca/shared/profiles/ca/caRARouterCert.cfg
new file mode 100644
index 000000000..284076686
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caRARouterCert.cfg
@@ -0,0 +1,85 @@
+desc=This certificate profile is for enrolling router certificates.
+visible=false
+enable=true
+enableBy=admin
+auth.instance_id=raCertAuth
+name=RA Agent-Authenticated Router Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=serverCertSet
+policyset.serverCertSet.list=1,2,3,4,5,6,7,8
+policyset.serverCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.serverCertSet.1.constraint.name=Subject Name Constraint
+policyset.serverCertSet.1.constraint.params.pattern=.*
+policyset.serverCertSet.1.constraint.params.accept=true
+policyset.serverCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.serverCertSet.1.default.name=Subject Name Default
+policyset.serverCertSet.1.default.params.name=
+policyset.serverCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.serverCertSet.2.constraint.name=Validity Constraint
+policyset.serverCertSet.2.constraint.params.range=720
+policyset.serverCertSet.2.constraint.params.notBeforeCheck=false
+policyset.serverCertSet.2.constraint.params.notAfterCheck=false
+policyset.serverCertSet.2.default.class_id=validityDefaultImpl
+policyset.serverCertSet.2.default.name=Validity Default
+policyset.serverCertSet.2.default.params.range=720
+policyset.serverCertSet.2.default.params.startTime=0
+policyset.serverCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.serverCertSet.3.constraint.name=Key Constraint
+policyset.serverCertSet.3.constraint.params.keyType=RSA
+policyset.serverCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.serverCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.serverCertSet.3.default.name=Key Default
+policyset.serverCertSet.4.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.4.constraint.name=No Constraint
+policyset.serverCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.serverCertSet.4.default.name=Authority Key Identifier Default
+policyset.serverCertSet.5.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.5.constraint.name=No Constraint
+policyset.serverCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.serverCertSet.5.default.name=AIA Extension Default
+policyset.serverCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.serverCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.serverCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.serverCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.serverCertSet.5.default.params.authInfoAccessCritical=false
+policyset.serverCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.serverCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.serverCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.serverCertSet.6.constraint.params.keyUsageCritical=true
+policyset.serverCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.serverCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.serverCertSet.6.default.name=Key Usage Default
+policyset.serverCertSet.6.default.params.keyUsageCritical=true
+policyset.serverCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.serverCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.default.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.7.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.7.constraint.name=No Constraint
+policyset.serverCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.serverCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.serverCertSet.7.default.params.exKeyUsageCritical=false
+policyset.serverCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.serverCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.serverCertSet.8.constraint.name=No Constraint
+policyset.serverCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.serverCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.serverCertSet.8.default.name=Signing Alg
+policyset.serverCertSet.8.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caRAagentCert.cfg b/base/ca/shared/profiles/ca/caRAagentCert.cfg
new file mode 100644
index 000000000..d330e6f01
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caRAagentCert.cfg
@@ -0,0 +1,95 @@
+desc=This certificate profile is for enrolling RA agent user certificates with RA agent authentication.
+visible=false
+enable=true
+enableBy=admin
+auth.instance_id=raCertAuth
+name=RA Agent-Authenticated Agent User Certificate Enrollment
+input.list=i1,i2,i3
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+input.i3.class_id=subjectDNInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=userCertSet
+policyset.userCertSet.list=1,2,3,4,5,6,7,8,9
+policyset.userCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.userCertSet.1.constraint.name=Subject Name Constraint
+policyset.userCertSet.1.constraint.params.pattern=UID=.*
+policyset.userCertSet.1.constraint.params.accept=true
+policyset.userCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.userCertSet.1.default.name=Subject Name Default
+policyset.userCertSet.1.default.params.name=
+policyset.userCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.userCertSet.2.constraint.name=Validity Constraint
+policyset.userCertSet.2.constraint.params.range=365
+policyset.userCertSet.2.constraint.params.notBeforeCheck=false
+policyset.userCertSet.2.constraint.params.notAfterCheck=false
+policyset.userCertSet.2.default.class_id=validityDefaultImpl
+policyset.userCertSet.2.default.name=Validity Default
+policyset.userCertSet.2.default.params.range=180
+policyset.userCertSet.2.default.params.startTime=0
+policyset.userCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.userCertSet.3.constraint.name=Key Constraint
+policyset.userCertSet.3.constraint.params.keyType=RSA
+policyset.userCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.userCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.userCertSet.3.default.name=Key Default
+policyset.userCertSet.4.constraint.class_id=noConstraintImpl
+policyset.userCertSet.4.constraint.name=No Constraint
+policyset.userCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.userCertSet.4.default.name=Authority Key Identifier Default
+policyset.userCertSet.5.constraint.class_id=noConstraintImpl
+policyset.userCertSet.5.constraint.name=No Constraint
+policyset.userCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.userCertSet.5.default.name=AIA Extension Default
+policyset.userCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.userCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.userCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.userCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.userCertSet.5.default.params.authInfoAccessCritical=false
+policyset.userCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.userCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.userCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.userCertSet.6.constraint.params.keyUsageCritical=true
+policyset.userCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.userCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.userCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.userCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.userCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.userCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.userCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.userCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.userCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.userCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.userCertSet.6.default.name=Key Usage Default
+policyset.userCertSet.6.default.params.keyUsageCritical=true
+policyset.userCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.userCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.userCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.userCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.userCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.userCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.userCertSet.6.default.params.keyUsageCrlSign=false
+policyset.userCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.userCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.userCertSet.7.constraint.class_id=noConstraintImpl
+policyset.userCertSet.7.constraint.name=No Constraint
+policyset.userCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.userCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.userCertSet.7.default.params.exKeyUsageCritical=false
+policyset.userCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.userCertSet.8.constraint.class_id=noConstraintImpl
+policyset.userCertSet.8.constraint.name=No Constraint
+policyset.userCertSet.8.default.class_id=subjectAltNameExtDefaultImpl
+policyset.userCertSet.8.default.name=Subject Alt Name Constraint
+policyset.userCertSet.8.default.params.subjAltNameExtCritical=false
+policyset.userCertSet.8.default.params.subjAltExtType_0=RFC822Name
+policyset.userCertSet.8.default.params.subjAltExtPattern_0=$request.requestor_email$
+policyset.userCertSet.8.default.params.subjAltExtGNEnable_0=true
+policyset.userCertSet.8.default.params.subjAltNameNumGNs=1
+policyset.userCertSet.9.constraint.class_id=signingAlgConstraintImpl
+policyset.userCertSet.9.constraint.name=No Constraint
+policyset.userCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.userCertSet.9.default.class_id=signingAlgDefaultImpl
+policyset.userCertSet.9.default.name=Signing Alg
+policyset.userCertSet.9.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caRAserverCert.cfg b/base/ca/shared/profiles/ca/caRAserverCert.cfg
new file mode 100644
index 000000000..297c001e3
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caRAserverCert.cfg
@@ -0,0 +1,85 @@
+desc=This certificate profile is for enrolling server certificates with RA agent authentication.
+visible=false
+enable=true
+enableBy=admin
+auth.instance_id=raCertAuth
+name=RA Agent-Authenticated Server Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=serverCertSet
+policyset.serverCertSet.list=1,2,3,4,5,6,7,8
+policyset.serverCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.serverCertSet.1.constraint.name=Subject Name Constraint
+policyset.serverCertSet.1.constraint.params.pattern=CN=.*
+policyset.serverCertSet.1.constraint.params.accept=true
+policyset.serverCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.serverCertSet.1.default.name=Subject Name Default
+policyset.serverCertSet.1.default.params.name=
+policyset.serverCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.serverCertSet.2.constraint.name=Validity Constraint
+policyset.serverCertSet.2.constraint.params.range=365
+policyset.serverCertSet.2.constraint.params.notBeforeCheck=false
+policyset.serverCertSet.2.constraint.params.notAfterCheck=false
+policyset.serverCertSet.2.default.class_id=validityDefaultImpl
+policyset.serverCertSet.2.default.name=Validity Default
+policyset.serverCertSet.2.default.params.range=180
+policyset.serverCertSet.2.default.params.startTime=0
+policyset.serverCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.serverCertSet.3.constraint.name=Key Constraint
+policyset.serverCertSet.3.constraint.params.keyType=RSA
+policyset.serverCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.serverCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.serverCertSet.3.default.name=Key Default
+policyset.serverCertSet.4.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.4.constraint.name=No Constraint
+policyset.serverCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.serverCertSet.4.default.name=Authority Key Identifier Default
+policyset.serverCertSet.5.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.5.constraint.name=No Constraint
+policyset.serverCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.serverCertSet.5.default.name=AIA Extension Default
+policyset.serverCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.serverCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.serverCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.serverCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.serverCertSet.5.default.params.authInfoAccessCritical=false
+policyset.serverCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.serverCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.serverCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.serverCertSet.6.constraint.params.keyUsageCritical=true
+policyset.serverCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.constraint.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.serverCertSet.6.default.name=Key Usage Default
+policyset.serverCertSet.6.default.params.keyUsageCritical=true
+policyset.serverCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.default.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.default.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.7.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.7.constraint.name=No Constraint
+policyset.serverCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.serverCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.serverCertSet.7.default.params.exKeyUsageCritical=false
+policyset.serverCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.1
+policyset.serverCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.serverCertSet.8.constraint.name=No Constraint
+policyset.serverCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.serverCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.serverCertSet.8.default.name=Signing Alg
+policyset.serverCertSet.8.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caRouterCert.cfg b/base/ca/shared/profiles/ca/caRouterCert.cfg
new file mode 100644
index 000000000..2400c69b8
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caRouterCert.cfg
@@ -0,0 +1,85 @@
+desc=This certificate profile is for enrolling router certificates.
+visible=false
+enable=true
+enableBy=admin
+auth.instance_id=flatFileAuth
+name=One Time Pin Router Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=serverCertSet
+policyset.serverCertSet.list=1,2,3,4,5,6,7,8
+policyset.serverCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.serverCertSet.1.constraint.name=Subject Name Constraint
+policyset.serverCertSet.1.constraint.params.pattern=.*
+policyset.serverCertSet.1.constraint.params.accept=true
+policyset.serverCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.serverCertSet.1.default.name=Subject Name Default
+policyset.serverCertSet.1.default.params.name=
+policyset.serverCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.serverCertSet.2.constraint.name=Validity Constraint
+policyset.serverCertSet.2.constraint.params.range=720
+policyset.serverCertSet.2.constraint.params.notBeforeCheck=false
+policyset.serverCertSet.2.constraint.params.notAfterCheck=false
+policyset.serverCertSet.2.default.class_id=validityDefaultImpl
+policyset.serverCertSet.2.default.name=Validity Default
+policyset.serverCertSet.2.default.params.range=720
+policyset.serverCertSet.2.default.params.startTime=0
+policyset.serverCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.serverCertSet.3.constraint.name=Key Constraint
+policyset.serverCertSet.3.constraint.params.keyType=RSA
+policyset.serverCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.serverCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.serverCertSet.3.default.name=Key Default
+policyset.serverCertSet.4.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.4.constraint.name=No Constraint
+policyset.serverCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.serverCertSet.4.default.name=Authority Key Identifier Default
+policyset.serverCertSet.5.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.5.constraint.name=No Constraint
+policyset.serverCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.serverCertSet.5.default.name=AIA Extension Default
+policyset.serverCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.serverCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.serverCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.serverCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.serverCertSet.5.default.params.authInfoAccessCritical=false
+policyset.serverCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.serverCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.serverCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.serverCertSet.6.constraint.params.keyUsageCritical=true
+policyset.serverCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.serverCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.serverCertSet.6.default.name=Key Usage Default
+policyset.serverCertSet.6.default.params.keyUsageCritical=true
+policyset.serverCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.serverCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.default.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.7.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.7.constraint.name=No Constraint
+policyset.serverCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.serverCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.serverCertSet.7.default.params.exKeyUsageCritical=false
+policyset.serverCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.serverCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.serverCertSet.8.constraint.name=No Constraint
+policyset.serverCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.serverCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.serverCertSet.8.default.name=Signing Alg
+policyset.serverCertSet.8.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caSSLClientSelfRenewal.cfg b/base/ca/shared/profiles/ca/caSSLClientSelfRenewal.cfg
new file mode 100755
index 000000000..d502e84d4
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caSSLClientSelfRenewal.cfg
@@ -0,0 +1,9 @@
+desc=This certificate profile is for renewing SSL client certificates.
+visible=true
+enable=true
+enableBy=admin
+renewal=true
+auth.instance_id=SSLclientCertAuth
+name=Renewal: Self-renew user SSL client certificates
+output.list=o1
+output.o1.class_id=certOutputImpl
diff --git a/base/ca/shared/profiles/ca/caServerCert.cfg b/base/ca/shared/profiles/ca/caServerCert.cfg
new file mode 100644
index 000000000..060194d8a
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caServerCert.cfg
@@ -0,0 +1,85 @@
+desc=This certificate profile is for enrolling server certificates.
+visible=true
+enable=true
+enableBy=admin
+auth.class_id=
+name=Manual Server Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=serverCertSet
+policyset.serverCertSet.list=1,2,3,4,5,6,7,8
+policyset.serverCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.serverCertSet.1.constraint.name=Subject Name Constraint
+policyset.serverCertSet.1.constraint.params.pattern=.*CN=.*
+policyset.serverCertSet.1.constraint.params.accept=true
+policyset.serverCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.serverCertSet.1.default.name=Subject Name Default
+policyset.serverCertSet.1.default.params.name=
+policyset.serverCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.serverCertSet.2.constraint.name=Validity Constraint
+policyset.serverCertSet.2.constraint.params.range=720
+policyset.serverCertSet.2.constraint.params.notBeforeCheck=false
+policyset.serverCertSet.2.constraint.params.notAfterCheck=false
+policyset.serverCertSet.2.default.class_id=validityDefaultImpl
+policyset.serverCertSet.2.default.name=Validity Default
+policyset.serverCertSet.2.default.params.range=720
+policyset.serverCertSet.2.default.params.startTime=0
+policyset.serverCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.serverCertSet.3.constraint.name=Key Constraint
+policyset.serverCertSet.3.constraint.params.keyType=RSA
+policyset.serverCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.serverCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.serverCertSet.3.default.name=Key Default
+policyset.serverCertSet.4.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.4.constraint.name=No Constraint
+policyset.serverCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.serverCertSet.4.default.name=Authority Key Identifier Default
+policyset.serverCertSet.5.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.5.constraint.name=No Constraint
+policyset.serverCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.serverCertSet.5.default.name=AIA Extension Default
+policyset.serverCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.serverCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.serverCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.serverCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.serverCertSet.5.default.params.authInfoAccessCritical=false
+policyset.serverCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.serverCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.serverCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.serverCertSet.6.constraint.params.keyUsageCritical=true
+policyset.serverCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.constraint.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.serverCertSet.6.default.name=Key Usage Default
+policyset.serverCertSet.6.default.params.keyUsageCritical=true
+policyset.serverCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.default.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.default.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.7.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.7.constraint.name=No Constraint
+policyset.serverCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.serverCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.serverCertSet.7.default.params.exKeyUsageCritical=false
+policyset.serverCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2
+policyset.serverCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.serverCertSet.8.constraint.name=No Constraint
+policyset.serverCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.serverCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.serverCertSet.8.default.name=Signing Alg
+policyset.serverCertSet.8.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caSignedLogCert.cfg b/base/ca/shared/profiles/ca/caSignedLogCert.cfg
new file mode 100644
index 000000000..ad5a09667
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caSignedLogCert.cfg
@@ -0,0 +1,74 @@
+desc=This profile is for enrolling audit log signing certificates
+visible=true
+enable=true
+enableBy=admin
+auth.class_id=
+name=Manual Log Signing Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=caLogSigningSet
+policyset.caLogSigningSet.list=1,2,3,4,6,8,9
+policyset.caLogSigningSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.caLogSigningSet.1.constraint.name=Subject Name Constraint
+policyset.caLogSigningSet.1.constraint.params.pattern=CN=.*
+policyset.caLogSigningSet.1.constraint.params.accept=true
+policyset.caLogSigningSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.caLogSigningSet.1.default.name=Subject Name Default
+policyset.caLogSigningSet.1.default.params.name=
+policyset.caLogSigningSet.2.constraint.class_id=validityConstraintImpl
+policyset.caLogSigningSet.2.constraint.name=Validity Constraint
+policyset.caLogSigningSet.2.constraint.params.range=365
+policyset.caLogSigningSet.2.constraint.params.notBeforeCheck=false
+policyset.caLogSigningSet.2.constraint.params.notAfterCheck=false
+policyset.caLogSigningSet.2.default.class_id=validityDefaultImpl
+policyset.caLogSigningSet.2.default.name=Validity Default
+policyset.caLogSigningSet.2.default.params.range=180
+policyset.caLogSigningSet.2.default.params.startTime=60
+policyset.caLogSigningSet.3.constraint.class_id=keyConstraintImpl
+policyset.caLogSigningSet.3.constraint.name=Key Constraint
+policyset.caLogSigningSet.3.constraint.params.keyType=RSA
+policyset.caLogSigningSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.caLogSigningSet.3.default.class_id=userKeyDefaultImpl
+policyset.caLogSigningSet.3.default.name=Key Default
+policyset.caLogSigningSet.4.constraint.class_id=noConstraintImpl
+policyset.caLogSigningSet.4.constraint.name=No Constraint
+policyset.caLogSigningSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.caLogSigningSet.4.default.name=Authority Key Identifier Default
+policyset.caLogSigningSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.caLogSigningSet.6.constraint.name=Key Usage Extension Constraint
+policyset.caLogSigningSet.6.constraint.params.keyUsageCritical=true
+policyset.caLogSigningSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.caLogSigningSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.caLogSigningSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.caLogSigningSet.6.constraint.params.keyUsageKeyEncipherment=false
+policyset.caLogSigningSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.caLogSigningSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.caLogSigningSet.6.constraint.params.keyUsageCrlSign=false
+policyset.caLogSigningSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.caLogSigningSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.caLogSigningSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.caLogSigningSet.6.default.name=Key Usage Default
+policyset.caLogSigningSet.6.default.params.keyUsageCritical=true
+policyset.caLogSigningSet.6.default.params.keyUsageDigitalSignature=true
+policyset.caLogSigningSet.6.default.params.keyUsageNonRepudiation=true
+policyset.caLogSigningSet.6.default.params.keyUsageDataEncipherment=false
+policyset.caLogSigningSet.6.default.params.keyUsageKeyEncipherment=false
+policyset.caLogSigningSet.6.default.params.keyUsageKeyAgreement=false
+policyset.caLogSigningSet.6.default.params.keyUsageKeyCertSign=false
+policyset.caLogSigningSet.6.default.params.keyUsageCrlSign=false
+policyset.caLogSigningSet.6.default.params.keyUsageEncipherOnly=false
+policyset.caLogSigningSet.6.default.params.keyUsageDecipherOnly=false
+policyset.caLogSigningSet.8.constraint.class_id=noConstraintImpl
+policyset.caLogSigningSet.8.constraint.name=No Constraint
+policyset.caLogSigningSet.8.default.class_id=subjectKeyIdentifierExtDefaultImpl
+policyset.caLogSigningSet.8.default.name=Subject Key Identifier Extension Default
+policyset.caLogSigningSet.8.default.params.critical=false
+policyset.caLogSigningSet.9.constraint.class_id=signingAlgConstraintImpl
+policyset.caLogSigningSet.9.constraint.name=No Constraint
+policyset.caLogSigningSet.9.constraint.params.signingAlgsAllowed=MD5withRSA,MD2withRSA,SHA1withRSA,SHA256withRSA,SHA512withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.caLogSigningSet.9.default.class_id=signingAlgDefaultImpl
+policyset.caLogSigningSet.9.default.name=Signing Alg
+policyset.caLogSigningSet.9.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caSimpleCMCUserCert.cfg b/base/ca/shared/profiles/ca/caSimpleCMCUserCert.cfg
new file mode 100644
index 000000000..a823bab10
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caSimpleCMCUserCert.cfg
@@ -0,0 +1,84 @@
+desc=This certificate profile is for enrolling user certificates by using the CMC certificate request with CMC Signature authentication.
+enable=true
+enableBy=admin
+name=Simple CMC Enrollment Request for User Certificate
+visible=false
+auth.instance_id=
+input.list=i1
+input.i1.class_id=certReqInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=cmcUserCertSet
+policyset.cmcUserCertSet.list=1,2,3,4,5,6,7,8
+policyset.cmcUserCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.cmcUserCertSet.1.constraint.name=Subject Name Constraint
+policyset.cmcUserCertSet.1.constraint.params.accept=true
+policyset.cmcUserCertSet.1.constraint.params.pattern=.*
+policyset.cmcUserCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.cmcUserCertSet.1.default.name=Subject Name Default
+policyset.cmcUserCertSet.1.default.params.name=
+policyset.cmcUserCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.cmcUserCertSet.2.constraint.name=Validity Constraint
+policyset.cmcUserCertSet.2.constraint.params.notAfterCheck=false
+policyset.cmcUserCertSet.2.constraint.params.notBeforeCheck=false
+policyset.cmcUserCertSet.2.constraint.params.range=365
+policyset.cmcUserCertSet.2.default.class_id=validityDefaultImpl
+policyset.cmcUserCertSet.2.default.name=Validity Default
+policyset.cmcUserCertSet.2.default.params.range=180
+policyset.cmcUserCertSet.2.default.params.startTime=0
+policyset.cmcUserCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.cmcUserCertSet.3.constraint.name=Key Constraint
+policyset.cmcUserCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.cmcUserCertSet.3.constraint.params.keyType=-
+policyset.cmcUserCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.cmcUserCertSet.3.default.name=Key Default
+policyset.cmcUserCertSet.4.constraint.class_id=noConstraintImpl
+policyset.cmcUserCertSet.4.constraint.name=No Constraint
+policyset.cmcUserCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.cmcUserCertSet.4.default.name=Authority Key Identifier Default
+policyset.cmcUserCertSet.5.constraint.class_id=noConstraintImpl
+policyset.cmcUserCertSet.5.constraint.name=No Constraint
+policyset.cmcUserCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.cmcUserCertSet.5.default.name=AIA Extension Default
+policyset.cmcUserCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.cmcUserCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.cmcUserCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.cmcUserCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.cmcUserCertSet.5.default.params.authInfoAccessCritical=false
+policyset.cmcUserCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.cmcUserCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.cmcUserCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.cmcUserCertSet.6.constraint.params.keyUsageCritical=true
+policyset.cmcUserCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.cmcUserCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.cmcUserCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.cmcUserCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.cmcUserCertSet.6.default.name=Key Usage Default
+policyset.cmcUserCertSet.6.default.params.keyUsageCritical=true
+policyset.cmcUserCertSet.6.default.params.keyUsageCrlSign=false
+policyset.cmcUserCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.cmcUserCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.cmcUserCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.cmcUserCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.cmcUserCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.cmcUserCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.cmcUserCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.cmcUserCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.cmcUserCertSet.7.constraint.class_id=noConstraintImpl
+policyset.cmcUserCertSet.7.constraint.name=No Constraint
+policyset.cmcUserCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.cmcUserCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.cmcUserCertSet.7.default.params.exKeyUsageCritical=false
+policyset.cmcUserCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.cmcUserCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.cmcUserCertSet.8.constraint.name=No Constraint
+policyset.cmcUserCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.cmcUserCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.cmcUserCertSet.8.default.name=Signing Alg
+policyset.cmcUserCertSet.8.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caTPSCert.cfg b/base/ca/shared/profiles/ca/caTPSCert.cfg
new file mode 100644
index 000000000..5553d4f41
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caTPSCert.cfg
@@ -0,0 +1,85 @@
+desc=This certificate profile is for enrolling TPS server certificates.
+visible=true
+enable=true
+enableBy=admin
+auth.class_id=
+name=Manual TPS Server Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=serverCertSet
+policyset.serverCertSet.list=1,2,3,4,5,6,7,8
+policyset.serverCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.serverCertSet.1.constraint.name=Subject Name Constraint
+policyset.serverCertSet.1.constraint.params.pattern=CN=.*
+policyset.serverCertSet.1.constraint.params.accept=true
+policyset.serverCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.serverCertSet.1.default.name=Subject Name Default
+policyset.serverCertSet.1.default.params.name=
+policyset.serverCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.serverCertSet.2.constraint.name=Validity Constraint
+policyset.serverCertSet.2.constraint.params.range=720
+policyset.serverCertSet.2.constraint.params.notBeforeCheck=false
+policyset.serverCertSet.2.constraint.params.notAfterCheck=false
+policyset.serverCertSet.2.default.class_id=validityDefaultImpl
+policyset.serverCertSet.2.default.name=Validity Default
+policyset.serverCertSet.2.default.params.range=720
+policyset.serverCertSet.2.default.params.startTime=0
+policyset.serverCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.serverCertSet.3.constraint.name=Key Constraint
+policyset.serverCertSet.3.constraint.params.keyType=RSA
+policyset.serverCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.serverCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.serverCertSet.3.default.name=Key Default
+policyset.serverCertSet.4.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.4.constraint.name=No Constraint
+policyset.serverCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.serverCertSet.4.default.name=Authority Key Identifier Default
+policyset.serverCertSet.5.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.5.constraint.name=No Constraint
+policyset.serverCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.serverCertSet.5.default.name=AIA Extension Default
+policyset.serverCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.serverCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.serverCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.serverCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.serverCertSet.5.default.params.authInfoAccessCritical=false
+policyset.serverCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.serverCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.serverCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.serverCertSet.6.constraint.params.keyUsageCritical=true
+policyset.serverCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.constraint.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.serverCertSet.6.default.name=Key Usage Default
+policyset.serverCertSet.6.default.params.keyUsageCritical=true
+policyset.serverCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.default.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.default.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.7.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.7.constraint.name=No Constraint
+policyset.serverCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.serverCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.serverCertSet.7.default.params.exKeyUsageCritical=false
+policyset.serverCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.serverCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.serverCertSet.8.constraint.name=No Constraint
+policyset.serverCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.serverCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.serverCertSet.8.default.name=Signing Alg
+policyset.serverCertSet.8.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caTempTokenDeviceKeyEnrollment.cfg b/base/ca/shared/profiles/ca/caTempTokenDeviceKeyEnrollment.cfg
new file mode 100644
index 000000000..530b3395a
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caTempTokenDeviceKeyEnrollment.cfg
@@ -0,0 +1,144 @@
+desc=This profile is for enrolling token device keys
+enable=true
+enableBy=admin
+lastModified=1068835451090
+name=Temporary Device Certificate Enrollment
+visible=false
+auth.instance_id=AgentCertAuth
+input.list=i1
+input.i1.class_id=nsHKeyCertReqInputImpl
+input.i1.name=nsHKeyCertReqInputImpl
+output.list=o1
+output.o1.class_id=nsNKeyOutputImpl
+output.o2.name=nsNKeyOutputImpl
+policyset.list=set1
+#policyset.set1.list=p2,p3,p4,p5,p1,p7,p8,p9,p12,p6
+policyset.set1.list=p2,p4,p5,p1,p8,p9,p12
+policyset.set1.p1.constraint.class_id=noConstraintImpl
+policyset.set1.p1.constraint.name=No Constraint
+policyset.set1.p1.default.class_id=nsTokenDeviceKeySubjectNameDefaultImpl
+policyset.set1.p1.default.name=nsTokenDeviceKeySubjectNameDefault
+policyset.set1.p1.default.params.dnpattern=UID=Token Key Device - $request.tokencuid$
+policyset.set1.p12.constraint.class_id=basicConstraintsExtConstraintImpl
+policyset.set1.p12.constraint.name=Basic Constraints Extension Constraint
+policyset.set1.p12.constraint.params.basicConstraintsCritical=-
+policyset.set1.p12.constraint.params.basicConstraintsIsCA=-
+policyset.set1.p12.constraint.params.basicConstraintsMaxPathLen=-1
+policyset.set1.p12.constraint.params.basicConstraintsMinPathLen=-1
+policyset.set1.p12.default.class_id=basicConstraintsExtDefaultImpl
+policyset.set1.p12.default.name=Basic Constraints Extension Default
+policyset.set1.p12.default.params.basicConstraintsCritical=false
+policyset.set1.p12.default.params.basicConstraintsIsCA=false
+policyset.set1.p12.default.params.basicConstraintsPathLen=-1
+policyset.set1.p2.constraint.class_id=noConstraintImpl
+policyset.set1.p2.constraint.name=No Constraint
+policyset.set1.p2.default.class_id=validityDefaultImpl
+policyset.set1.p2.default.name=Validity Default
+policyset.set1.p2.default.params.range=7
+policyset.set1.p2.default.params.startTime=0
+policyset.set1.p3.constraint.class_id=noConstraintImpl
+policyset.set1.p3.constraint.name=No Constraint
+policyset.set1.p3.default.class_id=crlDistributionPointsExtDefaultImpl
+policyset.set1.p3.default.name=crlDistributionPointsExtDefaultImpl
+policyset.set1.p3.default.params.crlDistPointsCritical=false
+policyset.set1.p3.default.params.crlDistPointsNum=1
+policyset.set1.p3.default.params.crlDistPointsEnable_0=false
+policyset.set1.p3.default.params.crlDistPointsIssuerName_0=
+policyset.set1.p3.default.params.crlDistPointsIssuerType_0=
+policyset.set1.p3.default.params.crlDistPointsPointName_0=
+policyset.set1.p3.default.params.crlDistPointsPointType_0=URIName
+policyset.set1.p3.default.params.crlDistPointsReasons_0=
+policyset.set1.p4.constraint.class_id=noConstraintImpl
+policyset.set1.p4.constraint.name=No Constraint
+policyset.set1.p4.default.class_id=signingAlgDefaultImpl
+policyset.set1.p4.default.name=Signing Algorithm Default
+policyset.set1.p4.default.params.signingAlg=-
+policyset.set1.p5.constraint.class_id=noConstraintImpl
+policyset.set1.p5.constraint.name=No Constraint
+policyset.set1.p5.default.class_id=keyUsageExtDefaultImpl
+policyset.set1.p5.default.name=Key Usage Extension Default
+policyset.set1.p5.default.params.keyUsageCritical=true
+policyset.set1.p5.default.params.keyUsageCrlSign=false
+policyset.set1.p5.default.params.keyUsageDataEncipherment=false
+policyset.set1.p5.default.params.keyUsageDecipherOnly=false
+policyset.set1.p5.default.params.keyUsageDigitalSignature=true
+policyset.set1.p5.default.params.keyUsageEncipherOnly=false
+policyset.set1.p5.default.params.keyUsageKeyAgreement=false
+policyset.set1.p5.default.params.keyUsageKeyCertSign=false
+policyset.set1.p5.default.params.keyUsageKeyEncipherment=false
+policyset.set1.p5.default.params.keyUsageNonRepudiation=false
+policyset.set1.p7.constraint.class_id=noConstraintImpl
+policyset.set1.p7.constraint.name=No Constraint
+policyset.set1.p7.default.class_id=certificatePoliciesExtDefaultImpl
+policyset.set1.p7.default.name=Certificate Policies Extension Default
+policyset.set1.p7.default.params.Critical=false
+policyset.set1.p7.default.params.PoliciesExt.num=5
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p8.constraint.class_id=noConstraintImpl
+policyset.set1.p8.constraint.name=No Constraint
+policyset.set1.p8.default.class_id=subjectKeyIdentifierExtDefaultImpl
+policyset.set1.p8.default.name=Subject Key Identifier Default
+policyset.set1.p9.constraint.class_id=noConstraintImpl
+policyset.set1.p9.constraint.name=No Constraint
+policyset.set1.p9.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.set1.p9.default.name=Authority Key Identifier Extension Default
+policyset.set1.p6.constraint.class_id=noConstraintImpl
+policyset.set1.p6.constraint.name=No Constraint
+policyset.set1.p6.default.class_id=subjectAltNameExtDefaultImpl
+policyset.set1.p6.default.name=Subject Alternative Name Extension Default
+policyset.set1.p6.default.params.subjAltExtGNEnable_0=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_1=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_2=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_3=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_4=false
+policyset.set1.p6.default.params.subjAltExtPattern_0=
+policyset.set1.p6.default.params.subjAltExtPattern_1=
+policyset.set1.p6.default.params.subjAltExtPattern_2=
+policyset.set1.p6.default.params.subjAltExtPattern_3=
+policyset.set1.p6.default.params.subjAltExtPattern_4=
+policyset.set1.p6.default.params.subjAltExtType_0=OtherName
+policyset.set1.p6.default.params.subjAltExtType_1=RFC822Name
+policyset.set1.p6.default.params.subjAltExtType_2=RFC822Name
+policyset.set1.p6.default.params.subjAltExtType_3=RFC822Name
+policyset.set1.p6.default.params.subjAltExtType_4=RFC822Name
+policyset.set1.p6.default.params.subjAltNameExtCritical=false
+policyset.set1.p6.default.params.subjAltNameNumGNs=1
diff --git a/base/ca/shared/profiles/ca/caTempTokenUserEncryptionKeyEnrollment.cfg b/base/ca/shared/profiles/ca/caTempTokenUserEncryptionKeyEnrollment.cfg
new file mode 100644
index 000000000..5f4c85f18
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caTempTokenUserEncryptionKeyEnrollment.cfg
@@ -0,0 +1,166 @@
+desc=This profile is for enrolling Token Encryption key
+enable=true
+enableBy=admin
+name=Temporary Token User Encryption Certificate Enrollment
+visible=false
+auth.instance_id=AgentCertAuth
+input.list=i1
+input.i1.class_id=nsNKeyCertReqInputImpl
+input.i1.name=nsNKeyCertReqInputImpl
+output.list=o1
+output.o1.class_id=nsNKeyOutputImpl
+output.o2.name=nsNKeyOutputImpl
+policyset.list=set1
+#policyset.set1.list=p2,p4,p5,p1,p6,p7,p8,p9,p12,p13,p14
+policyset.set1.list=p2,p4,p5,p1,p6,p8,p9,p12
+policyset.set1.p1.constraint.class_id=noConstraintImpl
+policyset.set1.p1.constraint.name=No Constraint
+policyset.set1.p1.default.class_id=nsTokenUserKeySubjectNameDefaultImpl
+policyset.set1.p1.default.name=nsTokenUserKeySubjectNameDefault
+#uncomment below to support SMIME
+#policyset.set1.p1.default.params.dnpattern=UID=$request.uid$, E=$request.mail$, O=Token Key User
+policyset.set1.p1.default.params.dnpattern=UID=$request.uid$, O=Token Key User
+#changed ldap.enable to true to support SMIME
+policyset.set1.p1.default.params.ldap.enable=false
+policyset.set1.p1.default.params.ldap.searchName=uid
+policyset.set1.p1.default.params.ldapStringAttributes=uid,mail
+policyset.set1.p1.default.params.ldap.basedn=
+policyset.set1.p1.default.params.ldap.maxConns=4
+policyset.set1.p1.default.params.ldap.minConns=1
+policyset.set1.p1.default.params.ldap.ldapconn.Version=2
+policyset.set1.p1.default.params.ldap.ldapconn.host=
+policyset.set1.p1.default.params.ldap.ldapconn.port=
+policyset.set1.p1.default.params.ldap.ldapconn.secureConn=false
+policyset.set1.p2.constraint.class_id=noConstraintImpl
+policyset.set1.p2.constraint.name=No Constraint
+policyset.set1.p2.default.class_id=validityDefaultImpl
+policyset.set1.p2.default.name=Validity Default
+policyset.set1.p2.default.params.range=7
+policyset.set1.p2.default.params.startTime=0
+policyset.set1.p4.constraint.class_id=noConstraintImpl
+policyset.set1.p4.constraint.name=No Constraint
+policyset.set1.p4.default.class_id=signingAlgDefaultImpl
+policyset.set1.p4.default.name=Signing Algorithm Default
+policyset.set1.p4.default.params.signingAlg=-
+policyset.set1.p5.constraint.class_id=noConstraintImpl
+policyset.set1.p5.constraint.name=No Constraint
+policyset.set1.p5.default.class_id=keyUsageExtDefaultImpl
+policyset.set1.p5.default.name=Key Usage Extension Default
+policyset.set1.p5.default.params.keyUsageCritical=true
+policyset.set1.p5.default.params.keyUsageCrlSign=false
+policyset.set1.p5.default.params.keyUsageDataEncipherment=false
+policyset.set1.p5.default.params.keyUsageDecipherOnly=false
+policyset.set1.p5.default.params.keyUsageDigitalSignature=false
+policyset.set1.p5.default.params.keyUsageEncipherOnly=false
+policyset.set1.p5.default.params.keyUsageKeyAgreement=false
+policyset.set1.p5.default.params.keyUsageKeyCertSign=false
+policyset.set1.p5.default.params.keyUsageKeyEncipherment=true
+policyset.set1.p5.default.params.keyUsageNonRepudiation=false
+policyset.set1.p6.constraint.class_id=noConstraintImpl
+policyset.set1.p6.constraint.name=No Constraint
+policyset.set1.p6.default.class_id=subjectAltNameExtDefaultImpl
+policyset.set1.p6.default.name=Subject Alternative Name Extension Default
+policyset.set1.p6.default.params.subjAltExtGNEnable_0=true
+policyset.set1.p6.default.params.subjAltExtGNEnable_1=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_2=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_3=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_4=false
+policyset.set1.p6.default.params.subjAltExtPattern_0=$request.mail$
+policyset.set1.p6.default.params.subjAltExtPattern_1=
+policyset.set1.p6.default.params.subjAltExtPattern_2=
+policyset.set1.p6.default.params.subjAltExtPattern_3=
+policyset.set1.p6.default.params.subjAltExtPattern_4=
+policyset.set1.p6.default.params.subjAltExtType_0=RFC822Name
+policyset.set1.p6.default.params.subjAltExtType_1=OtherName
+policyset.set1.p6.default.params.subjAltExtType_2=RFC822Name
+policyset.set1.p6.default.params.subjAltExtType_3=RFC822Name
+policyset.set1.p6.default.params.subjAltExtType_4=RFC822Name
+policyset.set1.p6.default.params.subjAltNameExtCritical=false
+policyset.set1.p6.default.params.subjAltNameNumGNs=1
+policyset.set1.p7.constraint.class_id=noConstraintImpl
+policyset.set1.p7.constraint.name=No Constraint
+policyset.set1.p7.default.class_id=certificatePoliciesExtDefaultImpl
+policyset.set1.p7.default.name=Certificate Policies Extension Default
+policyset.set1.p7.default.params.Critical=false
+policyset.set1.p7.default.params.PoliciesExt.num=5
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.CPSURI.enable=true
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p8.constraint.class_id=noConstraintImpl
+policyset.set1.p8.constraint.name=No Constraint
+policyset.set1.p8.default.class_id=subjectKeyIdentifierExtDefaultImpl
+policyset.set1.p8.default.name=Subject Key Identifier Default
+policyset.set1.p9.constraint.class_id=noConstraintImpl
+policyset.set1.p9.constraint.name=No Constraint
+policyset.set1.p9.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.set1.p9.default.name=Authority Key Identifier Extension Default
+policyset.set1.p12.constraint.class_id=basicConstraintsExtConstraintImpl
+policyset.set1.p12.constraint.name=Basic Constraints Extension Constraint
+policyset.set1.p12.constraint.params.basicConstraintsCritical=-
+policyset.set1.p12.constraint.params.basicConstraintsIsCA=-
+policyset.set1.p12.constraint.params.basicConstraintsMaxPathLen=-1
+policyset.set1.p12.constraint.params.basicConstraintsMinPathLen=-1
+policyset.set1.p12.default.class_id=basicConstraintsExtDefaultImpl
+policyset.set1.p12.default.name=Basic Constraints Extension Default
+policyset.set1.p12.default.params.basicConstraintsCritical=false
+policyset.set1.p12.default.params.basicConstraintsIsCA=false
+policyset.set1.p12.default.params.basicConstraintsPathLen=-1
+policyset.set1.p13.constraint.class_id=noConstraintImpl
+policyset.set1.p13.constraint.name=No Constraint
+policyset.set1.p13.default.class_id=crlDistributionPointsExtDefaultImpl
+policyset.set1.p13.default.name=crlDistributionPointsExtDefaultImpl
+policyset.set1.p13.default.params.crlDistPointsCritical=false
+policyset.set1.p13.default.params.crlDistPointsNum=1
+policyset.set1.p13.default.params.crlDistPointsEnable_0=false
+policyset.set1.p13.default.params.crlDistPointsIssuerName_0=
+policyset.set1.p13.default.params.crlDistPointsIssuerType_0=
+policyset.set1.p13.default.params.crlDistPointsPointName_0=
+policyset.set1.p13.default.params.crlDistPointsPointType_0=URIName
+policyset.set1.p13.default.params.crlDistPointsReasons_0=
+policyset.set1.p14.constraint.class_id=noConstraintImpl
+policyset.set1.p14.constraint.name=No Constraint
+policyset.set1.p14.default.class_id=authInfoAccessExtDefaultImpl
+policyset.set1.p14.default.name=AIA Extension Default
+policyset.set1.p14.default.params.authInfoAccessADEnable_0=false
+policyset.set1.p14.default.params.authInfoAccessADLocationType_0=URIName
+policyset.set1.p14.default.params.authInfoAccessADLocation_0=
+policyset.set1.p14.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.set1.p14.default.params.authInfoAccessCritical=false
+policyset.set1.p14.default.params.authInfoAccessNumADs=1
diff --git a/base/ca/shared/profiles/ca/caTempTokenUserSigningKeyEnrollment.cfg b/base/ca/shared/profiles/ca/caTempTokenUserSigningKeyEnrollment.cfg
new file mode 100644
index 000000000..8500b9d06
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caTempTokenUserSigningKeyEnrollment.cfg
@@ -0,0 +1,166 @@
+desc=This profile is for enrolling Token Signing key
+enable=true
+enableBy=admin
+name=Temporary Token User Signing Certificate Enrollment
+visible=false
+auth.instance_id=AgentCertAuth
+input.list=i1
+input.i1.class_id=nsNKeyCertReqInputImpl
+input.i1.name=nsNKeyCertReqInputImpl
+output.list=o1
+output.o1.class_id=nsNKeyOutputImpl
+output.o2.name=nsNKeyOutputImpl
+policyset.list=set1
+#policyset.set1.list=p2,p4,p5,p1,p6,p7,p8,p9,p12,p13,p14
+policyset.set1.list=p2,p4,p5,p1,p6,p8,p9,p12
+policyset.set1.p1.constraint.class_id=noConstraintImpl
+policyset.set1.p1.constraint.name=No Constraint
+policyset.set1.p1.default.class_id=nsTokenUserKeySubjectNameDefaultImpl
+policyset.set1.p1.default.name=nsTokenUserKeySubjectNameDefault
+#uncomment below to support SMIME
+#policyset.set1.p1.default.params.dnpattern=UID=$request.uid$, E=$request.mail$, O=Token Key User
+policyset.set1.p1.default.params.dnpattern=UID=$request.uid$, O=Token Key User
+#changed ldap.enable to true to support SMIME
+policyset.set1.p1.default.params.ldap.enable=false
+policyset.set1.p1.default.params.ldap.searchName=uid
+policyset.set1.p1.default.params.ldapStringAttributes=uid,mail
+policyset.set1.p1.default.params.ldap.basedn=
+policyset.set1.p1.default.params.ldap.maxConns=4
+policyset.set1.p1.default.params.ldap.minConns=1
+policyset.set1.p1.default.params.ldap.ldapconn.Version=2
+policyset.set1.p1.default.params.ldap.ldapconn.host=
+policyset.set1.p1.default.params.ldap.ldapconn.port=
+policyset.set1.p1.default.params.ldap.ldapconn.secureConn=false
+policyset.set1.p2.constraint.class_id=noConstraintImpl
+policyset.set1.p2.constraint.name=No Constraint
+policyset.set1.p2.default.class_id=validityDefaultImpl
+policyset.set1.p2.default.name=Validity Default
+policyset.set1.p2.default.params.range=7
+policyset.set1.p2.default.params.startTime=0
+policyset.set1.p4.constraint.class_id=noConstraintImpl
+policyset.set1.p4.constraint.name=No Constraint
+policyset.set1.p4.default.class_id=signingAlgDefaultImpl
+policyset.set1.p4.default.name=Signing Algorithm Default
+policyset.set1.p4.default.params.signingAlg=-
+policyset.set1.p5.constraint.class_id=noConstraintImpl
+policyset.set1.p5.constraint.name=No Constraint
+policyset.set1.p5.default.class_id=keyUsageExtDefaultImpl
+policyset.set1.p5.default.name=Key Usage Extension Default
+policyset.set1.p5.default.params.keyUsageCritical=true
+policyset.set1.p5.default.params.keyUsageCrlSign=false
+policyset.set1.p5.default.params.keyUsageDataEncipherment=false
+policyset.set1.p5.default.params.keyUsageDecipherOnly=false
+policyset.set1.p5.default.params.keyUsageDigitalSignature=true
+policyset.set1.p5.default.params.keyUsageEncipherOnly=false
+policyset.set1.p5.default.params.keyUsageKeyAgreement=false
+policyset.set1.p5.default.params.keyUsageKeyCertSign=false
+policyset.set1.p5.default.params.keyUsageKeyEncipherment=false
+policyset.set1.p5.default.params.keyUsageNonRepudiation=true
+policyset.set1.p6.constraint.class_id=noConstraintImpl
+policyset.set1.p6.constraint.name=No Constraint
+policyset.set1.p6.default.class_id=subjectAltNameExtDefaultImpl
+policyset.set1.p6.default.name=Subject Alternative Name Extension Default
+policyset.set1.p6.default.params.subjAltExtGNEnable_0=true
+policyset.set1.p6.default.params.subjAltExtGNEnable_1=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_2=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_3=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_4=false
+policyset.set1.p6.default.params.subjAltExtPattern_0=$request.mail$
+policyset.set1.p6.default.params.subjAltExtPattern_1=
+policyset.set1.p6.default.params.subjAltExtPattern_2=
+policyset.set1.p6.default.params.subjAltExtPattern_3=
+policyset.set1.p6.default.params.subjAltExtPattern_4=
+policyset.set1.p6.default.params.subjAltExtType_0=RFC822Name
+policyset.set1.p6.default.params.subjAltExtType_1=OtherName
+policyset.set1.p6.default.params.subjAltExtType_2=RFC822Name
+policyset.set1.p6.default.params.subjAltExtType_3=RFC822Name
+policyset.set1.p6.default.params.subjAltExtType_4=RFC822Name
+policyset.set1.p6.default.params.subjAltNameExtCritical=false
+policyset.set1.p6.default.params.subjAltNameNumGNs=1
+policyset.set1.p7.constraint.class_id=noConstraintImpl
+policyset.set1.p7.constraint.name=No Constraint
+policyset.set1.p7.default.class_id=certificatePoliciesExtDefaultImpl
+policyset.set1.p7.default.name=Certificate Policies Extension Default
+policyset.set1.p7.default.params.Critical=false
+policyset.set1.p7.default.params.PoliciesExt.num=5
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.CPSURI.enable=true
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p8.constraint.class_id=noConstraintImpl
+policyset.set1.p8.constraint.name=No Constraint
+policyset.set1.p8.default.class_id=subjectKeyIdentifierExtDefaultImpl
+policyset.set1.p8.default.name=Subject Key Identifier Default
+policyset.set1.p9.constraint.class_id=noConstraintImpl
+policyset.set1.p9.constraint.name=No Constraint
+policyset.set1.p9.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.set1.p9.default.name=Authority Key Identifier Extension Default
+policyset.set1.p12.constraint.class_id=basicConstraintsExtConstraintImpl
+policyset.set1.p12.constraint.name=Basic Constraints Extension Constraint
+policyset.set1.p12.constraint.params.basicConstraintsCritical=-
+policyset.set1.p12.constraint.params.basicConstraintsIsCA=-
+policyset.set1.p12.constraint.params.basicConstraintsMaxPathLen=-1
+policyset.set1.p12.constraint.params.basicConstraintsMinPathLen=-1
+policyset.set1.p12.default.class_id=basicConstraintsExtDefaultImpl
+policyset.set1.p12.default.name=Basic Constraints Extension Default
+policyset.set1.p12.default.params.basicConstraintsCritical=false
+policyset.set1.p12.default.params.basicConstraintsIsCA=false
+policyset.set1.p12.default.params.basicConstraintsPathLen=-1
+policyset.set1.p13.constraint.class_id=noConstraintImpl
+policyset.set1.p13.constraint.name=No Constraint
+policyset.set1.p13.default.class_id=crlDistributionPointsExtDefaultImpl
+policyset.set1.p13.default.name=crlDistributionPointsExtDefaultImpl
+policyset.set1.p13.default.params.crlDistPointsCritical=false
+policyset.set1.p13.default.params.crlDistPointsNum=1
+policyset.set1.p13.default.params.crlDistPointsEnable_0=false
+policyset.set1.p13.default.params.crlDistPointsIssuerName_0=
+policyset.set1.p13.default.params.crlDistPointsIssuerType_0=
+policyset.set1.p13.default.params.crlDistPointsPointName_0=
+policyset.set1.p13.default.params.crlDistPointsPointType_0=URIName
+policyset.set1.p13.default.params.crlDistPointsReasons_0=
+policyset.set1.p14.constraint.class_id=noConstraintImpl
+policyset.set1.p14.constraint.name=No Constraint
+policyset.set1.p14.default.class_id=authInfoAccessExtDefaultImpl
+policyset.set1.p14.default.name=AIA Extension Default
+policyset.set1.p14.default.params.authInfoAccessADEnable_0=false
+policyset.set1.p14.default.params.authInfoAccessADLocationType_0=URIName
+policyset.set1.p14.default.params.authInfoAccessADLocation_0=
+policyset.set1.p14.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.set1.p14.default.params.authInfoAccessCritical=false
+policyset.set1.p14.default.params.authInfoAccessNumADs=1
diff --git a/base/ca/shared/profiles/ca/caTokenDeviceKeyEnrollment.cfg b/base/ca/shared/profiles/ca/caTokenDeviceKeyEnrollment.cfg
new file mode 100644
index 000000000..ba0520963
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caTokenDeviceKeyEnrollment.cfg
@@ -0,0 +1,143 @@
+desc=This profile is for enrolling token device keys
+enable=true
+enableBy=admin
+lastModified=1068835451090
+name=Token Device Key Enrollment
+visible=false
+auth.instance_id=AgentCertAuth
+input.list=i1
+input.i1.class_id=nsHKeyCertReqInputImpl
+input.i1.name=nsHKeyCertReqInputImpl
+output.list=o1
+output.o1.class_id=nsNKeyOutputImpl
+output.o2.name=nsNKeyOutputImpl
+policyset.list=set1
+#policyset.set1.list=p2,p3,p4,p5,p1,p7,p8,p9,p12,p6
+policyset.set1.list=p2,p4,p5,p1,p8,p9,p12
+policyset.set1.p1.constraint.class_id=noConstraintImpl
+policyset.set1.p1.constraint.name=No Constraint
+policyset.set1.p1.default.class_id=nsTokenDeviceKeySubjectNameDefaultImpl
+policyset.set1.p1.default.name=nsTokenDeviceKeySubjectNameDefault
+policyset.set1.p1.default.params.dnpattern=UID=Token Key Device - $request.tokencuid$
+policyset.set1.p12.constraint.class_id=basicConstraintsExtConstraintImpl
+policyset.set1.p12.constraint.name=Basic Constraints Extension Constraint
+policyset.set1.p12.constraint.params.basicConstraintsCritical=-
+policyset.set1.p12.constraint.params.basicConstraintsIsCA=-
+policyset.set1.p12.constraint.params.basicConstraintsMaxPathLen=-1
+policyset.set1.p12.constraint.params.basicConstraintsMinPathLen=-1
+policyset.set1.p12.default.class_id=basicConstraintsExtDefaultImpl
+policyset.set1.p12.default.name=Basic Constraints Extension Default
+policyset.set1.p12.default.params.basicConstraintsCritical=false
+policyset.set1.p12.default.params.basicConstraintsIsCA=false
+policyset.set1.p12.default.params.basicConstraintsPathLen=-1
+policyset.set1.p2.constraint.class_id=noConstraintImpl
+policyset.set1.p2.constraint.name=No Constraint
+policyset.set1.p2.default.class_id=validityDefaultImpl
+policyset.set1.p2.default.name=Validity Default
+policyset.set1.p2.default.params.range=1825
+policyset.set1.p2.default.params.startTime=0
+policyset.set1.p3.constraint.class_id=noConstraintImpl
+policyset.set1.p3.constraint.name=No Constraint
+policyset.set1.p3.default.class_id=crlDistributionPointsExtDefaultImpl
+policyset.set1.p3.default.name=crlDistributionPointsExtDefaultImpl
+policyset.set1.p3.default.params.crlDistPointsCritical=false
+policyset.set1.p3.default.params.crlDistPointsNum=1
+policyset.set1.p3.default.params.crlDistPointsEnable_0=false
+policyset.set1.p3.default.params.crlDistPointsIssuerName_0=
+policyset.set1.p3.default.params.crlDistPointsIssuerType_0=
+policyset.set1.p3.default.params.crlDistPointsPointName_0=
+policyset.set1.p3.default.params.crlDistPointsPointType_0=URIName
+policyset.set1.p3.default.params.crlDistPointsReasons_0=
+policyset.set1.p4.constraint.class_id=noConstraintImpl
+policyset.set1.p4.constraint.name=No Constraint
+policyset.set1.p4.default.class_id=signingAlgDefaultImpl
+policyset.set1.p4.default.name=Signing Algorithm Default
+policyset.set1.p4.default.params.signingAlg=-
+policyset.set1.p5.constraint.class_id=noConstraintImpl
+policyset.set1.p5.constraint.name=No Constraint
+policyset.set1.p5.default.class_id=keyUsageExtDefaultImpl
+policyset.set1.p5.default.name=Key Usage Extension Default
+policyset.set1.p5.default.params.keyUsageCritical=true
+policyset.set1.p5.default.params.keyUsageCrlSign=false
+policyset.set1.p5.default.params.keyUsageDataEncipherment=false
+policyset.set1.p5.default.params.keyUsageDecipherOnly=false
+policyset.set1.p5.default.params.keyUsageDigitalSignature=true
+policyset.set1.p5.default.params.keyUsageEncipherOnly=false
+policyset.set1.p5.default.params.keyUsageKeyAgreement=false
+policyset.set1.p5.default.params.keyUsageKeyCertSign=false
+policyset.set1.p5.default.params.keyUsageKeyEncipherment=false
+policyset.set1.p5.default.params.keyUsageNonRepudiation=false
+policyset.set1.p7.constraint.class_id=noConstraintImpl
+policyset.set1.p7.constraint.name=No Constraint
+policyset.set1.p7.default.class_id=certificatePoliciesExtDefaultImpl
+policyset.set1.p7.default.name=Certificate Policies Extension Default
+policyset.set1.p7.default.params.Critical=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p8.constraint.class_id=noConstraintImpl
+policyset.set1.p8.constraint.name=No Constraint
+policyset.set1.p8.default.class_id=subjectKeyIdentifierExtDefaultImpl
+policyset.set1.p8.default.name=Subject Key Identifier Default
+policyset.set1.p9.constraint.class_id=noConstraintImpl
+policyset.set1.p9.constraint.name=No Constraint
+policyset.set1.p9.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.set1.p9.default.name=Authority Key Identifier Extension Default
+policyset.set1.p6.constraint.class_id=noConstraintImpl
+policyset.set1.p6.constraint.name=No Constraint
+policyset.set1.p6.default.class_id=subjectAltNameExtDefaultImpl
+policyset.set1.p6.default.name=Subject Alternative Name Extension Default
+policyset.set1.p6.default.params.subjAltExtGNEnable_0=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_1=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_2=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_3=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_4=false
+policyset.set1.p6.default.params.subjAltExtPattern_0=
+policyset.set1.p6.default.params.subjAltExtPattern_1=
+policyset.set1.p6.default.params.subjAltExtPattern_2=
+policyset.set1.p6.default.params.subjAltExtPattern_3=
+policyset.set1.p6.default.params.subjAltExtPattern_4=
+policyset.set1.p6.default.params.subjAltExtType_0=OtherName
+policyset.set1.p6.default.params.subjAltExtType_1=RFC822Name
+policyset.set1.p6.default.params.subjAltExtType_2=RFC822Name
+policyset.set1.p6.default.params.subjAltExtType_3=RFC822Name
+policyset.set1.p6.default.params.subjAltExtType_4=RFC822Name
+policyset.set1.p6.default.params.subjAltNameExtCritical=false
+policyset.set1.p6.default.params.subjAltNameNumGNs=1
diff --git a/base/ca/shared/profiles/ca/caTokenMSLoginEnrollment.cfg b/base/ca/shared/profiles/ca/caTokenMSLoginEnrollment.cfg
new file mode 100644
index 000000000..37c9af5e0
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caTokenMSLoginEnrollment.cfg
@@ -0,0 +1,171 @@
+desc=This profile is for enrolling MS Login Certificate
+enable=true
+enableBy=admin
+name=Token User MS Login Certificate Enrollment
+visible=false
+auth.instance_id=AgentCertAuth
+input.list=i1
+input.i1.class_id=nsNKeyCertReqInputImpl
+input.i1.name=nsNKeyCertReqInputImpl
+output.list=o1
+output.o1.class_id=nsNKeyOutputImpl
+output.o2.name=nsNKeyOutputImpl
+policyset.list=set1
+#policyset.set1.list=p2,p4,p5,p1,p6,p7,p8,p9,p12,p13,p14
+policyset.set1.list=p2,p4,p5,p1,p6,p8,p9,p12,p13,p14,p15
+policyset.set1.p1.constraint.class_id=noConstraintImpl
+policyset.set1.p1.constraint.name=No Constraint
+policyset.set1.p1.default.class_id=nsTokenUserKeySubjectNameDefaultImpl
+policyset.set1.p1.default.name=nsTokenUserKeySubjectNameDefault
+policyset.set1.p1.default.params.dnpattern=CN=uid=$request.uid$,E=$request.mail$, ou=$request.upn$, o=example
+#changed ldap.enable to true to support SMIME
+policyset.set1.p1.default.params.ldap.enable=true
+policyset.set1.p1.default.params.ldap.searchName=uid
+policyset.set1.p1.default.params.ldapStringAttributes=uid,mail,givenName,sn,upn
+policyset.set1.p1.default.params.ldap.basedn=ou=People,dc=example,dc=com
+policyset.set1.p1.default.params.ldap.maxConns=4
+policyset.set1.p1.default.params.ldap.minConns=1
+policyset.set1.p1.default.params.ldap.ldapconn.Version=2
+policyset.set1.p1.default.params.ldap.ldapconn.host=localhost.localdomain
+policyset.set1.p1.default.params.ldap.ldapconn.port=389
+policyset.set1.p1.default.params.ldap.ldapconn.secureConn=false
+policyset.set1.p2.constraint.class_id=noConstraintImpl
+policyset.set1.p2.constraint.name=No Constraint
+policyset.set1.p2.default.class_id=validityDefaultImpl
+policyset.set1.p2.default.name=Validity Default
+policyset.set1.p2.default.params.range=1825
+policyset.set1.p2.default.params.startTime=0
+policyset.set1.p4.constraint.class_id=noConstraintImpl
+policyset.set1.p4.constraint.name=No Constraint
+policyset.set1.p4.default.class_id=signingAlgDefaultImpl
+policyset.set1.p4.default.name=Signing Algorithm Default
+policyset.set1.p4.default.params.signingAlg=-
+policyset.set1.p5.constraint.class_id=noConstraintImpl
+policyset.set1.p5.constraint.name=No Constraint
+policyset.set1.p5.default.class_id=keyUsageExtDefaultImpl
+policyset.set1.p5.default.name=Key Usage Extension Default
+policyset.set1.p5.default.params.keyUsageCritical=true
+policyset.set1.p5.default.params.keyUsageCrlSign=false
+policyset.set1.p5.default.params.keyUsageDataEncipherment=false
+policyset.set1.p5.default.params.keyUsageDecipherOnly=false
+policyset.set1.p5.default.params.keyUsageDigitalSignature=true
+policyset.set1.p5.default.params.keyUsageEncipherOnly=false
+policyset.set1.p5.default.params.keyUsageKeyAgreement=false
+policyset.set1.p5.default.params.keyUsageKeyCertSign=false
+policyset.set1.p5.default.params.keyUsageKeyEncipherment=false
+policyset.set1.p5.default.params.keyUsageNonRepudiation=true
+policyset.set1.p6.constraint.class_id=noConstraintImpl
+policyset.set1.p6.constraint.name=No Constraint
+policyset.set1.p6.default.class_id=subjectAltNameExtDefaultImpl
+policyset.set1.p6.default.name=Subject Alternative Name Extension Default
+policyset.set1.p6.default.params.subjAltExtGNEnable_0=true
+policyset.set1.p6.default.params.subjAltExtGNEnable_1=true
+policyset.set1.p6.default.params.subjAltExtGNEnable_2=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_3=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_4=false
+policyset.set1.p6.default.params.subjAltExtPattern_0=$request.mail$
+policyset.set1.p6.default.params.subjAltExtPattern_1=(UTF8String)1.3.6.1.4.1.311.20.2.3,$request.upn$
+policyset.set1.p6.default.params.subjAltExtPattern_2=
+policyset.set1.p6.default.params.subjAltExtPattern_3=
+policyset.set1.p6.default.params.subjAltExtPattern_4=
+policyset.set1.p6.default.params.subjAltExtType_0=RFC822Name
+policyset.set1.p6.default.params.subjAltExtType_1=OtherName
+policyset.set1.p6.default.params.subjAltExtType_2=RFC822Name
+policyset.set1.p6.default.params.subjAltExtType_3=RFC822Name
+policyset.set1.p6.default.params.subjAltExtType_4=RFC822Name
+policyset.set1.p6.default.params.subjAltNameExtCritical=false
+policyset.set1.p6.default.params.subjAltNameNumGNs=2
+policyset.set1.p7.constraint.class_id=noConstraintImpl
+policyset.set1.p7.constraint.name=No Constraint
+policyset.set1.p7.default.class_id=certificatePoliciesExtDefaultImpl
+policyset.set1.p7.default.name=Certificate Policies Extension Default
+policyset.set1.p7.default.params.Critical=false
+policyset.set1.p7.default.params.PoliciesExt.num=5
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.CPSURI.enable=true
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.explicitText.value=
+ policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+ policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.enable=false
+ policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.explicitText.value=
+ policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+ policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+ policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p8.constraint.class_id=noConstraintImpl
+policyset.set1.p8.constraint.name=No Constraint
+policyset.set1.p8.default.class_id=subjectKeyIdentifierExtDefaultImpl
+policyset.set1.p8.default.name=Subject Key Identifier Default
+policyset.set1.p9.constraint.class_id=noConstraintImpl
+policyset.set1.p9.constraint.name=No Constraint
+policyset.set1.p9.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.set1.p9.default.name=Authority Key Identifier Extension Default
+policyset.set1.p12.constraint.class_id=basicConstraintsExtConstraintImpl
+policyset.set1.p12.constraint.name=Basic Constraints Extension Constraint
+policyset.set1.p12.constraint.params.basicConstraintsCritical=-
+policyset.set1.p12.constraint.params.basicConstraintsIsCA=-
+policyset.set1.p12.constraint.params.basicConstraintsMaxPathLen=-1
+policyset.set1.p12.constraint.params.basicConstraintsMinPathLen=-1
+policyset.set1.p12.default.class_id=basicConstraintsExtDefaultImpl
+policyset.set1.p12.default.name=Basic Constraints Extension Default
+policyset.set1.p12.default.params.basicConstraintsCritical=false
+policyset.set1.p12.default.params.basicConstraintsIsCA=false
+policyset.set1.p12.default.params.basicConstraintsPathLen=-1
+policyset.set1.p13.constraint.class_id=noConstraintImpl
+policyset.set1.p13.constraint.name=No Constraint
+policyset.set1.p13.default.class_id=crlDistributionPointsExtDefaultImpl
+policyset.set1.p13.default.name=crlDistributionPointsExtDefaultImpl
+policyset.set1.p13.default.params.crlDistPointsCritical=false
+policyset.set1.p13.default.params.crlDistPointsNum=1
+policyset.set1.p13.default.params.crlDistPointsEnable_0=true
+policyset.set1.p13.default.params.crlDistPointsIssuerName_0=
+policyset.set1.p13.default.params.crlDistPointsIssuerType_0=
+policyset.set1.p13.default.params.crlDistPointsPointName_0=http://localhost.localdomain:9443/ca/ee/ca/getCRL?crlIssuingPoint=MasterCRL&op=getCRL
+policyset.set1.p13.default.params.crlDistPointsPointType_0=URIName
+policyset.set1.p13.default.params.crlDistPointsReasons_0=
+policyset.set1.p14.constraint.class_id=noConstraintImpl
+policyset.set1.p14.constraint.name=No Constraint
+policyset.set1.p14.default.class_id=authInfoAccessExtDefaultImpl
+policyset.set1.p14.default.name=AIA Extension Default
+policyset.set1.p14.default.params.authInfoAccessADEnable_0=true
+policyset.set1.p14.default.params.authInfoAccessADLocationType_0=URIName
+policyset.set1.p14.default.params.authInfoAccessADLocation_0=http://localhost.localdomain:9443/ca/ocsp
+policyset.set1.p14.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.set1.p14.default.params.authInfoAccessCritical=false
+policyset.set1.p14.default.params.authInfoAccessNumADs=1
+policyset.set1.p15.constraint.class_id=noConstraintImpl
+policyset.set1.p15.constraint.name=No Constraint
+policyset.set1.p15.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.set1.p15.default.name=Extended Key Usage Extension Default
+policyset.set1.p15.default.params.exKeyUsageCritical=false
+policyset.set1.p15.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.4.1.311.20.2.2
+
diff --git a/base/ca/shared/profiles/ca/caTokenUserEncryptionKeyEnrollment.cfg b/base/ca/shared/profiles/ca/caTokenUserEncryptionKeyEnrollment.cfg
new file mode 100644
index 000000000..5b3ecd40c
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caTokenUserEncryptionKeyEnrollment.cfg
@@ -0,0 +1,170 @@
+desc=This profile is for enrolling Token Encryption key
+enable=true
+enableBy=admin
+name=Token User Encryption Certificate Enrollment
+visible=false
+auth.instance_id=AgentCertAuth
+input.list=i1
+input.i1.class_id=nsNKeyCertReqInputImpl
+input.i1.name=nsNKeyCertReqInputImpl
+output.list=o1
+output.o1.class_id=nsNKeyOutputImpl
+output.o2.name=nsNKeyOutputImpl
+policyset.list=set1
+#policyset.set1.list=p2,p4,p5,p1,p6,p7,p8,p9,p12,p13,p14
+policyset.set1.list=p2,p4,p5,p1,p6,p8,p9,p12
+policyset.set1.p1.constraint.class_id=noConstraintImpl
+policyset.set1.p1.constraint.name=No Constraint
+policyset.set1.p1.default.class_id=nsTokenUserKeySubjectNameDefaultImpl
+policyset.set1.p1.default.name=nsTokenUserKeySubjectNameDefault
+policyset.set1.p1.default.params.dnpattern=UID=$request.uid$, O=Token Key User
+#changed ldap.enable to true to support SMIME
+policyset.set1.p1.default.params.ldap.enable=false
+policyset.set1.p1.default.params.ldap.searchName=uid
+policyset.set1.p1.default.params.ldapStringAttributes=uid,mail
+policyset.set1.p1.default.params.ldap.basedn=
+policyset.set1.p1.default.params.ldap.maxConns=4
+policyset.set1.p1.default.params.ldap.minConns=1
+policyset.set1.p1.default.params.ldap.ldapconn.Version=2
+policyset.set1.p1.default.params.ldap.ldapconn.host=
+policyset.set1.p1.default.params.ldap.ldapconn.port=
+policyset.set1.p1.default.params.ldap.ldapconn.secureConn=false
+policyset.set1.p2.constraint.class_id=noConstraintImpl
+policyset.set1.p2.constraint.name=No Constraint
+policyset.set1.p2.default.class_id=validityDefaultImpl
+policyset.set1.p2.default.name=Validity Default
+policyset.set1.p2.default.params.range=1825
+policyset.set1.p2.default.params.startTime=0
+policyset.set1.p4.constraint.class_id=noConstraintImpl
+policyset.set1.p4.constraint.name=No Constraint
+policyset.set1.p4.default.class_id=signingAlgDefaultImpl
+policyset.set1.p4.default.name=Signing Algorithm Default
+policyset.set1.p4.default.params.signingAlg=-
+policyset.set1.p5.constraint.class_id=noConstraintImpl
+policyset.set1.p5.constraint.name=No Constraint
+policyset.set1.p5.default.class_id=keyUsageExtDefaultImpl
+policyset.set1.p5.default.name=Key Usage Extension Default
+policyset.set1.p5.default.params.keyUsageCritical=true
+policyset.set1.p5.default.params.keyUsageCrlSign=false
+policyset.set1.p5.default.params.keyUsageDataEncipherment=false
+policyset.set1.p5.default.params.keyUsageDecipherOnly=false
+policyset.set1.p5.default.params.keyUsageDigitalSignature=false
+policyset.set1.p5.default.params.keyUsageEncipherOnly=false
+policyset.set1.p5.default.params.keyUsageKeyAgreement=false
+policyset.set1.p5.default.params.keyUsageKeyCertSign=false
+policyset.set1.p5.default.params.keyUsageKeyEncipherment=true
+policyset.set1.p5.default.params.keyUsageNonRepudiation=false
+policyset.set1.p6.constraint.class_id=noConstraintImpl
+policyset.set1.p6.constraint.name=No Constraint
+policyset.set1.p6.default.class_id=subjectAltNameExtDefaultImpl
+policyset.set1.p6.default.name=Subject Alternative Name Extension Default
+policyset.set1.p6.default.params.subjAltExtGNEnable_0=true
+policyset.set1.p6.default.params.subjAltExtGNEnable_1=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_2=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_3=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_4=false
+policyset.set1.p6.default.params.subjAltExtPattern_0=$request.mail$
+policyset.set1.p6.default.params.subjAltExtPattern_1=
+policyset.set1.p6.default.params.subjAltExtPattern_2=
+policyset.set1.p6.default.params.subjAltExtPattern_3=
+policyset.set1.p6.default.params.subjAltExtPattern_4=
+policyset.set1.p6.default.params.subjAltExtType_0=RFC822Name
+policyset.set1.p6.default.params.subjAltExtType_1=OtherName
+policyset.set1.p6.default.params.subjAltExtType_2=RFC822Name
+policyset.set1.p6.default.params.subjAltExtType_3=RFC822Name
+policyset.set1.p6.default.params.subjAltExtType_4=RFC822Name
+policyset.set1.p6.default.params.subjAltNameExtCritical=false
+policyset.set1.p6.default.params.subjAltNameNumGNs=1
+policyset.set1.p7.constraint.class_id=noConstraintImpl
+policyset.set1.p7.constraint.name=No Constraint
+policyset.set1.p7.default.class_id=certificatePoliciesExtDefaultImpl
+policyset.set1.p7.default.name=Certificate Policies Extension Default
+policyset.set1.p7.default.params.Critical=false
+policyset.set1.p7.default.params.PoliciesExt.num=5
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.CPSURI.enable=true
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p8.constraint.class_id=noConstraintImpl
+policyset.set1.p8.constraint.name=No Constraint
+policyset.set1.p8.default.class_id=subjectKeyIdentifierExtDefaultImpl
+policyset.set1.p8.default.name=Subject Key Identifier Default
+policyset.set1.p9.constraint.class_id=noConstraintImpl
+policyset.set1.p9.constraint.name=No Constraint
+policyset.set1.p9.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.set1.p9.default.name=Authority Key Identifier Extension Default
+policyset.set1.10.constraint.class_id=renewGracePeriodConstraintImpl
+policyset.set1.10.constraint.name=Renewal Grace Period Constraint
+policyset.set1.10.constraint.params.renewal.graceBefore=30
+policyset.set1.10.constraint.params.renewal.graceAfter=30
+policyset.set1.10.default.class_id=noDefaultImpl
+policyset.set1.10.default.name=No Default
+policyset.set1.p12.constraint.class_id=basicConstraintsExtConstraintImpl
+policyset.set1.p12.constraint.name=Basic Constraints Extension Constraint
+policyset.set1.p12.constraint.params.basicConstraintsCritical=-
+policyset.set1.p12.constraint.params.basicConstraintsIsCA=-
+policyset.set1.p12.constraint.params.basicConstraintsMaxPathLen=-1
+policyset.set1.p12.constraint.params.basicConstraintsMinPathLen=-1
+policyset.set1.p12.default.class_id=basicConstraintsExtDefaultImpl
+policyset.set1.p12.default.name=Basic Constraints Extension Default
+policyset.set1.p12.default.params.basicConstraintsCritical=false
+policyset.set1.p12.default.params.basicConstraintsIsCA=false
+policyset.set1.p12.default.params.basicConstraintsPathLen=-1
+policyset.set1.p13.constraint.class_id=noConstraintImpl
+policyset.set1.p13.constraint.name=No Constraint
+policyset.set1.p13.default.class_id=crlDistributionPointsExtDefaultImpl
+policyset.set1.p13.default.name=crlDistributionPointsExtDefaultImpl
+policyset.set1.p13.default.params.crlDistPointsCritical=false
+policyset.set1.p13.default.params.crlDistPointsNum=1
+policyset.set1.p13.default.params.crlDistPointsEnable_0=false
+policyset.set1.p13.default.params.crlDistPointsIssuerName_0=
+policyset.set1.p13.default.params.crlDistPointsIssuerType_0=
+policyset.set1.p13.default.params.crlDistPointsPointName_0=
+policyset.set1.p13.default.params.crlDistPointsPointType_0=URIName
+policyset.set1.p13.default.params.crlDistPointsReasons_0=
+policyset.set1.p14.constraint.class_id=noConstraintImpl
+policyset.set1.p14.constraint.name=No Constraint
+policyset.set1.p14.default.class_id=authInfoAccessExtDefaultImpl
+policyset.set1.p14.default.name=AIA Extension Default
+policyset.set1.p14.default.params.authInfoAccessADEnable_0=false
+policyset.set1.p14.default.params.authInfoAccessADLocationType_0=URIName
+policyset.set1.p14.default.params.authInfoAccessADLocation_0=
+policyset.set1.p14.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.set1.p14.default.params.authInfoAccessCritical=false
+policyset.set1.p14.default.params.authInfoAccessNumADs=1
diff --git a/base/ca/shared/profiles/ca/caTokenUserEncryptionKeyRenewal.cfg b/base/ca/shared/profiles/ca/caTokenUserEncryptionKeyRenewal.cfg
new file mode 100644
index 000000000..281e2a43e
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caTokenUserEncryptionKeyRenewal.cfg
@@ -0,0 +1,11 @@
+desc=This certificate profile is for renewing a token encryption certificate
+visible=false
+enable=true
+enableBy=admin
+renewal=true
+auth.instance_id=AgentCertAuth
+name=smart card token signing cert renewal profile
+input.list=i1
+input.i1.class_id=serialNumRenewInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
diff --git a/base/ca/shared/profiles/ca/caTokenUserSigningKeyEnrollment.cfg b/base/ca/shared/profiles/ca/caTokenUserSigningKeyEnrollment.cfg
new file mode 100644
index 000000000..ebc231808
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caTokenUserSigningKeyEnrollment.cfg
@@ -0,0 +1,170 @@
+desc=This profile is for enrolling Token Signing key
+enable=true
+enableBy=admin
+name=Token User Signing Certificate Enrollment
+visible=false
+auth.instance_id=AgentCertAuth
+input.list=i1
+input.i1.class_id=nsNKeyCertReqInputImpl
+input.i1.name=nsNKeyCertReqInputImpl
+output.list=o1
+output.o1.class_id=nsNKeyOutputImpl
+output.o2.name=nsNKeyOutputImpl
+policyset.list=set1
+#policyset.set1.list=p2,p4,p5,p1,p6,p7,p8,p9,p12,p13,p14
+policyset.set1.list=p2,p4,p5,p1,p6,p8,p9,p12
+policyset.set1.p1.constraint.class_id=noConstraintImpl
+policyset.set1.p1.constraint.name=No Constraint
+policyset.set1.p1.default.class_id=nsTokenUserKeySubjectNameDefaultImpl
+policyset.set1.p1.default.name=nsTokenUserKeySubjectNameDefault
+policyset.set1.p1.default.params.dnpattern=UID=$request.uid$, O=Token Key User
+#changed ldap.enable to true to support SMIME
+policyset.set1.p1.default.params.ldap.enable=false
+policyset.set1.p1.default.params.ldap.searchName=uid
+policyset.set1.p1.default.params.ldapStringAttributes=uid,mail
+policyset.set1.p1.default.params.ldap.basedn=
+policyset.set1.p1.default.params.ldap.maxConns=4
+policyset.set1.p1.default.params.ldap.minConns=1
+policyset.set1.p1.default.params.ldap.ldapconn.Version=2
+policyset.set1.p1.default.params.ldap.ldapconn.host=
+policyset.set1.p1.default.params.ldap.ldapconn.port=
+policyset.set1.p1.default.params.ldap.ldapconn.secureConn=false
+policyset.set1.p2.constraint.class_id=noConstraintImpl
+policyset.set1.p2.constraint.name=No Constraint
+policyset.set1.p2.default.class_id=validityDefaultImpl
+policyset.set1.p2.default.name=Validity Default
+policyset.set1.p2.default.params.range=1825
+policyset.set1.p2.default.params.startTime=0
+policyset.set1.p4.constraint.class_id=noConstraintImpl
+policyset.set1.p4.constraint.name=No Constraint
+policyset.set1.p4.default.class_id=signingAlgDefaultImpl
+policyset.set1.p4.default.name=Signing Algorithm Default
+policyset.set1.p4.default.params.signingAlg=-
+policyset.set1.p5.constraint.class_id=noConstraintImpl
+policyset.set1.p5.constraint.name=No Constraint
+policyset.set1.p5.default.class_id=keyUsageExtDefaultImpl
+policyset.set1.p5.default.name=Key Usage Extension Default
+policyset.set1.p5.default.params.keyUsageCritical=true
+policyset.set1.p5.default.params.keyUsageCrlSign=false
+policyset.set1.p5.default.params.keyUsageDataEncipherment=false
+policyset.set1.p5.default.params.keyUsageDecipherOnly=false
+policyset.set1.p5.default.params.keyUsageDigitalSignature=true
+policyset.set1.p5.default.params.keyUsageEncipherOnly=false
+policyset.set1.p5.default.params.keyUsageKeyAgreement=false
+policyset.set1.p5.default.params.keyUsageKeyCertSign=false
+policyset.set1.p5.default.params.keyUsageKeyEncipherment=false
+policyset.set1.p5.default.params.keyUsageNonRepudiation=true
+policyset.set1.p6.constraint.class_id=noConstraintImpl
+policyset.set1.p6.constraint.name=No Constraint
+policyset.set1.p6.default.class_id=subjectAltNameExtDefaultImpl
+policyset.set1.p6.default.name=Subject Alternative Name Extension Default
+policyset.set1.p6.default.params.subjAltExtGNEnable_0=true
+policyset.set1.p6.default.params.subjAltExtGNEnable_1=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_2=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_3=false
+policyset.set1.p6.default.params.subjAltExtGNEnable_4=false
+policyset.set1.p6.default.params.subjAltExtPattern_0=$request.mail$
+policyset.set1.p6.default.params.subjAltExtPattern_1=
+policyset.set1.p6.default.params.subjAltExtPattern_2=
+policyset.set1.p6.default.params.subjAltExtPattern_3=
+policyset.set1.p6.default.params.subjAltExtPattern_4=
+policyset.set1.p6.default.params.subjAltExtType_0=RFC822Name
+policyset.set1.p6.default.params.subjAltExtType_1=OtherName
+policyset.set1.p6.default.params.subjAltExtType_2=RFC822Name
+policyset.set1.p6.default.params.subjAltExtType_3=RFC822Name
+policyset.set1.p6.default.params.subjAltExtType_4=RFC822Name
+policyset.set1.p6.default.params.subjAltNameExtCritical=false
+policyset.set1.p6.default.params.subjAltNameNumGNs=1
+policyset.set1.p7.constraint.class_id=noConstraintImpl
+policyset.set1.p7.constraint.name=No Constraint
+policyset.set1.p7.default.class_id=certificatePoliciesExtDefaultImpl
+policyset.set1.p7.default.name=Certificate Policies Extension Default
+policyset.set1.p7.default.params.Critical=false
+policyset.set1.p7.default.params.PoliciesExt.num=5
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.CPSURI.enable=true
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy1.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy2.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy3.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.policyId=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.CPSURI.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.CPSURI.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.enable=false
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.explicitText.value=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.noticeReference.noticeNumbers=
+policyset.set1.p7.default.params.PoliciesExt.certPolicy4.PolicyQualifiers0.usernotice.noticeReference.organization=
+policyset.set1.p8.constraint.class_id=noConstraintImpl
+policyset.set1.p8.constraint.name=No Constraint
+policyset.set1.p8.default.class_id=subjectKeyIdentifierExtDefaultImpl
+policyset.set1.p8.default.name=Subject Key Identifier Default
+policyset.set1.p9.constraint.class_id=noConstraintImpl
+policyset.set1.p9.constraint.name=No Constraint
+policyset.set1.p9.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.set1.p9.default.name=Authority Key Identifier Extension Default
+policyset.set1.10.constraint.class_id=renewGracePeriodConstraintImpl
+policyset.set1.10.constraint.name=Renewal Grace Period Constraint
+policyset.set1.10.constraint.params.renewal.graceBefore=30
+policyset.set1.10.constraint.params.renewal.graceAfter=30
+policyset.set1.10.default.class_id=noDefaultImpl
+policyset.set1.10.default.name=No Default
+policyset.set1.p12.constraint.class_id=basicConstraintsExtConstraintImpl
+policyset.set1.p12.constraint.name=Basic Constraints Extension Constraint
+policyset.set1.p12.constraint.params.basicConstraintsCritical=-
+policyset.set1.p12.constraint.params.basicConstraintsIsCA=-
+policyset.set1.p12.constraint.params.basicConstraintsMaxPathLen=-1
+policyset.set1.p12.constraint.params.basicConstraintsMinPathLen=-1
+policyset.set1.p12.default.class_id=basicConstraintsExtDefaultImpl
+policyset.set1.p12.default.name=Basic Constraints Extension Default
+policyset.set1.p12.default.params.basicConstraintsCritical=false
+policyset.set1.p12.default.params.basicConstraintsIsCA=false
+policyset.set1.p12.default.params.basicConstraintsPathLen=-1
+policyset.set1.p13.constraint.class_id=noConstraintImpl
+policyset.set1.p13.constraint.name=No Constraint
+policyset.set1.p13.default.class_id=crlDistributionPointsExtDefaultImpl
+policyset.set1.p13.default.name=crlDistributionPointsExtDefaultImpl
+policyset.set1.p13.default.params.crlDistPointsCritical=false
+policyset.set1.p13.default.params.crlDistPointsNum=1
+policyset.set1.p13.default.params.crlDistPointsEnable_0=false
+policyset.set1.p13.default.params.crlDistPointsIssuerName_0=
+policyset.set1.p13.default.params.crlDistPointsIssuerType_0=
+policyset.set1.p13.default.params.crlDistPointsPointName_0=
+policyset.set1.p13.default.params.crlDistPointsPointType_0=URIName
+policyset.set1.p13.default.params.crlDistPointsReasons_0=
+policyset.set1.p14.constraint.class_id=noConstraintImpl
+policyset.set1.p14.constraint.name=No Constraint
+policyset.set1.p14.default.class_id=authInfoAccessExtDefaultImpl
+policyset.set1.p14.default.name=AIA Extension Default
+policyset.set1.p14.default.params.authInfoAccessADEnable_0=false
+policyset.set1.p14.default.params.authInfoAccessADLocationType_0=URIName
+policyset.set1.p14.default.params.authInfoAccessADLocation_0=
+policyset.set1.p14.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.set1.p14.default.params.authInfoAccessCritical=false
+policyset.set1.p14.default.params.authInfoAccessNumADs=1
diff --git a/base/ca/shared/profiles/ca/caTokenUserSigningKeyRenewal.cfg b/base/ca/shared/profiles/ca/caTokenUserSigningKeyRenewal.cfg
new file mode 100644
index 000000000..e89e32382
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caTokenUserSigningKeyRenewal.cfg
@@ -0,0 +1,11 @@
+desc=This certificate profile is for renewing a token certificate
+visible=false
+enable=true
+enableBy=admin
+renewal=true
+auth.instance_id=AgentCertAuth
+name=smart card token signing cert renewal profile
+input.list=i1
+input.i1.class_id=serialNumRenewInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
diff --git a/base/ca/shared/profiles/ca/caTransportCert.cfg b/base/ca/shared/profiles/ca/caTransportCert.cfg
new file mode 100644
index 000000000..466e2b313
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caTransportCert.cfg
@@ -0,0 +1,85 @@
+desc=This certificate profile is for enrolling Data Recovery Manager transport certificates.
+visible=true
+enable=true
+enableBy=admin
+auth.class_id=
+name=Manual Data Recovery Manager Transport Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=transportCertSet
+policyset.transportCertSet.list=1,2,3,4,5,6,7,8
+policyset.transportCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.transportCertSet.1.constraint.name=Subject Name Constraint
+policyset.transportCertSet.1.constraint.params.pattern=CN=.*
+policyset.transportCertSet.1.constraint.params.accept=true
+policyset.transportCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.transportCertSet.1.default.name=Subject Name Default
+policyset.transportCertSet.1.default.params.name=
+policyset.transportCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.transportCertSet.2.constraint.name=Validity Constraint
+policyset.transportCertSet.2.constraint.params.range=720
+policyset.transportCertSet.2.constraint.params.notBeforeCheck=false
+policyset.transportCertSet.2.constraint.params.notAfterCheck=false
+policyset.transportCertSet.2.default.class_id=validityDefaultImpl
+policyset.transportCertSet.2.default.name=Validity Default
+policyset.transportCertSet.2.default.params.range=720
+policyset.transportCertSet.2.default.params.startTime=0
+policyset.transportCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.transportCertSet.3.constraint.name=Key Constraint
+policyset.transportCertSet.3.constraint.params.keyType=RSA
+policyset.transportCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.transportCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.transportCertSet.3.default.name=Key Default
+policyset.transportCertSet.4.constraint.class_id=noConstraintImpl
+policyset.transportCertSet.4.constraint.name=No Constraint
+policyset.transportCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.transportCertSet.4.default.name=Authority Key Identifier Default
+policyset.transportCertSet.5.constraint.class_id=noConstraintImpl
+policyset.transportCertSet.5.constraint.name=No Constraint
+policyset.transportCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.transportCertSet.5.default.name=AIA Extension Default
+policyset.transportCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.transportCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.transportCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.transportCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.transportCertSet.5.default.params.authInfoAccessCritical=false
+policyset.transportCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.transportCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.transportCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.transportCertSet.6.constraint.params.keyUsageCritical=true
+policyset.transportCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.transportCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.transportCertSet.6.constraint.params.keyUsageDataEncipherment=true
+policyset.transportCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.transportCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.transportCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.transportCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.transportCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.transportCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.transportCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.transportCertSet.6.default.name=Key Usage Default
+policyset.transportCertSet.6.default.params.keyUsageCritical=true
+policyset.transportCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.transportCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.transportCertSet.6.default.params.keyUsageDataEncipherment=true
+policyset.transportCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.transportCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.transportCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.transportCertSet.6.default.params.keyUsageCrlSign=false
+policyset.transportCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.transportCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.transportCertSet.7.constraint.class_id=noConstraintImpl
+policyset.transportCertSet.7.constraint.name=No Constraint
+policyset.transportCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.transportCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.transportCertSet.7.default.params.exKeyUsageCritical=false
+policyset.transportCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2
+policyset.transportCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.transportCertSet.8.constraint.name=No Constraint
+policyset.transportCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.transportCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.transportCertSet.8.default.name=Signing Alg
+policyset.transportCertSet.8.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caUUIDdeviceCert.cfg b/base/ca/shared/profiles/ca/caUUIDdeviceCert.cfg
new file mode 100644
index 000000000..f1701081c
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caUUIDdeviceCert.cfg
@@ -0,0 +1,99 @@
+desc=This certificate profile is for enrolling device certificates to contain UUID in the Subject Alternative Name extension
+visible=true
+enable=false
+enableBy=admin
+name=Manual device Dual-Use Certificate Enrollment to contain UUID in SAN
+auth.class_id=
+input.list=i1,i2,i3
+input.i1.class_id=keyGenInputImpl
+input.i2.class_id=subjectNameInputImpl
+input.i3.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=userCertSet
+policyset.userCertSet.list=1,2,3,4,5,6,7,8,9
+policyset.userCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.userCertSet.1.constraint.name=Subject Name Constraint
+policyset.userCertSet.1.constraint.params.pattern=UID=.*
+policyset.userCertSet.1.constraint.params.accept=true
+policyset.userCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.userCertSet.1.default.name=Subject Name Default
+policyset.userCertSet.1.default.params.name=
+policyset.userCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.userCertSet.2.constraint.name=Validity Constraint
+policyset.userCertSet.2.constraint.params.range=365
+policyset.userCertSet.2.constraint.params.notBeforeCheck=false
+policyset.userCertSet.2.constraint.params.notAfterCheck=false
+policyset.userCertSet.2.default.class_id=validityDefaultImpl
+policyset.userCertSet.2.default.name=Validity Default
+policyset.userCertSet.2.default.params.range=180
+policyset.userCertSet.2.default.params.startTime=0
+policyset.userCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.userCertSet.3.constraint.name=Key Constraint
+policyset.userCertSet.3.constraint.params.keyType=RSA
+policyset.userCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.userCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.userCertSet.3.default.name=Key Default
+policyset.userCertSet.4.constraint.class_id=noConstraintImpl
+policyset.userCertSet.4.constraint.name=No Constraint
+policyset.userCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.userCertSet.4.default.name=Authority Key Identifier Default
+policyset.userCertSet.5.constraint.class_id=noConstraintImpl
+policyset.userCertSet.5.constraint.name=No Constraint
+policyset.userCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.userCertSet.5.default.name=AIA Extension Default
+policyset.userCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.userCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.userCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.userCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.userCertSet.5.default.params.authInfoAccessCritical=false
+policyset.userCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.userCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.userCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.userCertSet.6.constraint.params.keyUsageCritical=true
+policyset.userCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.userCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.userCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.userCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.userCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.userCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.userCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.userCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.userCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.userCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.userCertSet.6.default.name=Key Usage Default
+policyset.userCertSet.6.default.params.keyUsageCritical=true
+policyset.userCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.userCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.userCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.userCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.userCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.userCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.userCertSet.6.default.params.keyUsageCrlSign=false
+policyset.userCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.userCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.userCertSet.7.constraint.class_id=noConstraintImpl
+policyset.userCertSet.7.constraint.name=No Constraint
+policyset.userCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.userCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.userCertSet.7.default.params.exKeyUsageCritical=false
+policyset.userCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.userCertSet.8.constraint.class_id=noConstraintImpl
+policyset.userCertSet.8.constraint.name=No Constraint
+policyset.userCertSet.8.default.class_id=subjectAltNameExtDefaultImpl
+policyset.userCertSet.8.default.name=Subject Alt Name Constraint
+policyset.userCertSet.8.default.params.subjAltNameExtCritical=false
+policyset.userCertSet.8.default.params.subjAltExtType_0=RFC822Name
+policyset.userCertSet.8.default.params.subjAltExtPattern_0=$request.requestor_email$
+policyset.userCertSet.8.default.params.subjAltExtGNEnable_0=true
+policyset.userCertSet.8.default.params.subjAltExtType_1=OtherName
+policyset.userCertSet.8.default.params.subjAltExtPattern_1=(IA5String)1.2.3.4,$server.source$
+policyset.userCertSet.8.default.params.subjAltExtGNEnable_1=true
+policyset.userCertSet.8.default.params.subjAltExtSource_1=UUID4
+policyset.userCertSet.8.default.params.subjAltNameNumGNs=2
+policyset.userCertSet.9.constraint.class_id=signingAlgConstraintImpl
+policyset.userCertSet.9.constraint.name=No Constraint
+policyset.userCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.userCertSet.9.default.class_id=signingAlgDefaultImpl
+policyset.userCertSet.9.default.name=Signing Alg
+policyset.userCertSet.9.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caUserCert.cfg b/base/ca/shared/profiles/ca/caUserCert.cfg
new file mode 100644
index 000000000..9a5d83c9b
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caUserCert.cfg
@@ -0,0 +1,101 @@
+desc=This certificate profile is for enrolling user certificates.
+visible=true
+enable=true
+enableBy=admin
+name=Manual User Dual-Use Certificate Enrollment
+auth.class_id=
+input.list=i1,i2,i3
+input.i1.class_id=keyGenInputImpl
+input.i2.class_id=subjectNameInputImpl
+input.i3.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=userCertSet
+policyset.userCertSet.list=1,10,2,3,4,5,6,7,8,9
+policyset.userCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.userCertSet.1.constraint.name=Subject Name Constraint
+policyset.userCertSet.1.constraint.params.pattern=UID=.*
+policyset.userCertSet.1.constraint.params.accept=true
+policyset.userCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.userCertSet.1.default.name=Subject Name Default
+policyset.userCertSet.1.default.params.name=
+policyset.userCertSet.10.constraint.class_id=renewGracePeriodConstraintImpl
+policyset.userCertSet.10.constraint.name=Renewal Grace Period Constraint
+policyset.userCertSet.10.constraint.params.renewal.graceBefore=30
+policyset.userCertSet.10.constraint.params.renewal.graceAfter=30
+policyset.userCertSet.10.default.class_id=noDefaultImpl
+policyset.userCertSet.10.default.name=No Default
+policyset.userCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.userCertSet.2.constraint.name=Validity Constraint
+policyset.userCertSet.2.constraint.params.range=365
+policyset.userCertSet.2.constraint.params.notBeforeCheck=false
+policyset.userCertSet.2.constraint.params.notAfterCheck=false
+policyset.userCertSet.2.default.class_id=validityDefaultImpl
+policyset.userCertSet.2.default.name=Validity Default
+policyset.userCertSet.2.default.params.range=180
+policyset.userCertSet.2.default.params.startTime=0
+policyset.userCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.userCertSet.3.constraint.name=Key Constraint
+policyset.userCertSet.3.constraint.params.keyType=RSA
+policyset.userCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.userCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.userCertSet.3.default.name=Key Default
+policyset.userCertSet.4.constraint.class_id=noConstraintImpl
+policyset.userCertSet.4.constraint.name=No Constraint
+policyset.userCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.userCertSet.4.default.name=Authority Key Identifier Default
+policyset.userCertSet.5.constraint.class_id=noConstraintImpl
+policyset.userCertSet.5.constraint.name=No Constraint
+policyset.userCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.userCertSet.5.default.name=AIA Extension Default
+policyset.userCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.userCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.userCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.userCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.userCertSet.5.default.params.authInfoAccessCritical=false
+policyset.userCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.userCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.userCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.userCertSet.6.constraint.params.keyUsageCritical=true
+policyset.userCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.userCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.userCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.userCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.userCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.userCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.userCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.userCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.userCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.userCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.userCertSet.6.default.name=Key Usage Default
+policyset.userCertSet.6.default.params.keyUsageCritical=true
+policyset.userCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.userCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.userCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.userCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.userCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.userCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.userCertSet.6.default.params.keyUsageCrlSign=false
+policyset.userCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.userCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.userCertSet.7.constraint.class_id=noConstraintImpl
+policyset.userCertSet.7.constraint.name=No Constraint
+policyset.userCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.userCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.userCertSet.7.default.params.exKeyUsageCritical=false
+policyset.userCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.userCertSet.8.constraint.class_id=noConstraintImpl
+policyset.userCertSet.8.constraint.name=No Constraint
+policyset.userCertSet.8.default.class_id=subjectAltNameExtDefaultImpl
+policyset.userCertSet.8.default.name=Subject Alt Name Constraint
+policyset.userCertSet.8.default.params.subjAltNameExtCritical=false
+policyset.userCertSet.8.default.params.subjAltExtType_0=RFC822Name
+policyset.userCertSet.8.default.params.subjAltExtPattern_0=$request.requestor_email$
+policyset.userCertSet.8.default.params.subjAltExtGNEnable_0=true
+policyset.userCertSet.8.default.params.subjAltNameNumGNs=1
+policyset.userCertSet.9.constraint.class_id=signingAlgConstraintImpl
+policyset.userCertSet.9.constraint.name=No Constraint
+policyset.userCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.userCertSet.9.default.class_id=signingAlgDefaultImpl
+policyset.userCertSet.9.default.name=Signing Alg
+policyset.userCertSet.9.default.params.signingAlg=-
diff --git a/base/ca/shared/profiles/ca/caUserSMIMEcapCert.cfg b/base/ca/shared/profiles/ca/caUserSMIMEcapCert.cfg
new file mode 100644
index 000000000..c273e26f0
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caUserSMIMEcapCert.cfg
@@ -0,0 +1,107 @@
+desc=This certificate profile is for enrolling user certificates with S/MIME capabilities extension - OID: 1.2.840.113549.1.9.15
+visible=true
+enable=true
+enableBy=admin
+name=Manual User Dual-Use S/MIME capabilities Certificate Enrollment
+auth.class_id=
+input.list=i1,i2,i3
+input.i1.class_id=keyGenInputImpl
+input.i2.class_id=subjectNameInputImpl
+input.i3.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=userCertSet
+policyset.userCertSet.list=1,10,2,3,4,5,6,7,8,9,11
+policyset.userCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.userCertSet.1.constraint.name=Subject Name Constraint
+policyset.userCertSet.1.constraint.params.pattern=UID=.*
+policyset.userCertSet.1.constraint.params.accept=true
+policyset.userCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.userCertSet.1.default.name=Subject Name Default
+policyset.userCertSet.1.default.params.name=
+policyset.userCertSet.10.constraint.class_id=renewGracePeriodConstraintImpl
+policyset.userCertSet.10.constraint.name=Renewal Grace Period Constraint
+policyset.userCertSet.10.constraint.params.renewal.graceBefore=30
+policyset.userCertSet.10.constraint.params.renewal.graceAfter=30
+policyset.userCertSet.10.default.class_id=noDefaultImpl
+policyset.userCertSet.10.default.name=No Default
+policyset.userCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.userCertSet.2.constraint.name=Validity Constraint
+policyset.userCertSet.2.constraint.params.range=365
+policyset.userCertSet.2.constraint.params.notBeforeCheck=false
+policyset.userCertSet.2.constraint.params.notAfterCheck=false
+policyset.userCertSet.2.default.class_id=validityDefaultImpl
+policyset.userCertSet.2.default.name=Validity Default
+policyset.userCertSet.2.default.params.range=180
+policyset.userCertSet.2.default.params.startTime=0
+policyset.userCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.userCertSet.3.constraint.name=Key Constraint
+policyset.userCertSet.3.constraint.params.keyType=RSA
+policyset.userCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.userCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.userCertSet.3.default.name=Key Default
+policyset.userCertSet.4.constraint.class_id=noConstraintImpl
+policyset.userCertSet.4.constraint.name=No Constraint
+policyset.userCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.userCertSet.4.default.name=Authority Key Identifier Default
+policyset.userCertSet.5.constraint.class_id=noConstraintImpl
+policyset.userCertSet.5.constraint.name=No Constraint
+policyset.userCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.userCertSet.5.default.name=AIA Extension Default
+policyset.userCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.userCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.userCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.userCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.userCertSet.5.default.params.authInfoAccessCritical=false
+policyset.userCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.userCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.userCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.userCertSet.6.constraint.params.keyUsageCritical=true
+policyset.userCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.userCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.userCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.userCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.userCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.userCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.userCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.userCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.userCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.userCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.userCertSet.6.default.name=Key Usage Default
+policyset.userCertSet.6.default.params.keyUsageCritical=true
+policyset.userCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.userCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.userCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.userCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.userCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.userCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.userCertSet.6.default.params.keyUsageCrlSign=false
+policyset.userCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.userCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.userCertSet.7.constraint.class_id=noConstraintImpl
+policyset.userCertSet.7.constraint.name=No Constraint
+policyset.userCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.userCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.userCertSet.7.default.params.exKeyUsageCritical=false
+policyset.userCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.userCertSet.8.constraint.class_id=noConstraintImpl
+policyset.userCertSet.8.constraint.name=No Constraint
+policyset.userCertSet.8.default.class_id=subjectAltNameExtDefaultImpl
+policyset.userCertSet.8.default.name=Subject Alt Name Constraint
+policyset.userCertSet.8.default.params.subjAltNameExtCritical=false
+policyset.userCertSet.8.default.params.subjAltExtType_0=RFC822Name
+policyset.userCertSet.8.default.params.subjAltExtPattern_0=$request.requestor_email$
+policyset.userCertSet.8.default.params.subjAltExtGNEnable_0=true
+policyset.userCertSet.8.default.params.subjAltNameNumGNs=1
+policyset.userCertSet.9.constraint.class_id=signingAlgConstraintImpl
+policyset.userCertSet.9.constraint.name=No Constraint
+policyset.userCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.userCertSet.9.default.class_id=signingAlgDefaultImpl
+policyset.userCertSet.9.default.name=Signing Alg
+policyset.userCertSet.9.default.params.signingAlg=-
+policyset.userCertSet.11.constraint.class_id=noConstraintImpl
+policyset.userCertSet.11.constraint.name=No Constraint
+policyset.userCertSet.11.default.class_id=genericExtDefaultImpl
+policyset.userCertSet.11.default.name=Generic Extension
+policyset.userCertSet.11.default.params.genericExtOID=1.2.840.113549.1.9.15
+policyset.userCertSet.11.default.params.genericExtData=3067300B06092A864886F70D010105300B06092A864886F70D01010B300B06092A864886F70D01010C300B06092A864886F70D01010D300A06082A864886F70D0307300B0609608648016503040102300B060960864801650304012A300B06092A864886F70D010101
diff --git a/base/ca/shared/webapps/ROOT/WEB-INF/web.xml b/base/ca/shared/webapps/ROOT/WEB-INF/web.xml
new file mode 100644
index 000000000..59245836e
--- /dev/null
+++ b/base/ca/shared/webapps/ROOT/WEB-INF/web.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ Copyright 2004 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+ version="2.4">
+
+ <display-name>Welcome to Tomcat</display-name>
+ <description>
+ Welcome to Tomcat
+ </description>
+
+</web-app>
+
diff --git a/base/ca/shared/webapps/ROOT/index.jsp b/base/ca/shared/webapps/ROOT/index.jsp
new file mode 100644
index 000000000..85a4654c3
--- /dev/null
+++ b/base/ca/shared/webapps/ROOT/index.jsp
@@ -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.
+
+ Copyright (C) 2010 Red Hat, Inc.
+ All rights reserved.
+ --- END COPYRIGHT BLOCK --- -->
+<%
+ // establish acceptable schemes
+ final String HTTP_SCHEME = "http";
+ final String HTTPS_SCHEME = "https";
+
+ // establish known ports
+ final int EE_HTTP_PORT = [PKI_UNSECURE_PORT];
+ final int AGENT_HTTPS_PORT = [PKI_AGENT_SECURE_PORT];
+ final int EE_HTTPS_PORT = [PKI_EE_SECURE_PORT];
+ final int ADMIN_HTTPS_PORT = [PKI_ADMIN_SECURE_PORT];
+
+ // establish known paths
+ final String ADMIN_PATH = "/[PKI_SUBSYSTEM_TYPE]/services";
+ final String AGENT_PATH = "/[PKI_SUBSYSTEM_TYPE]/agent/[PKI_SUBSYSTEM_TYPE]";
+ final String EE_PATH = "/[PKI_SUBSYSTEM_TYPE]/ee/[PKI_SUBSYSTEM_TYPE]";
+ final String ERROR_PATH = "/[PKI_SUBSYSTEM_TYPE]/404.html";
+
+ // retrieve scheme from request
+ String scheme = request.getScheme();
+
+ // retrieve client hostname on which the request was sent
+ String client_hostname = request.getServerName();
+
+ // retrieve client port number on which the request was sent
+ int client_port = request.getServerPort();
+
+ // retrieve server hostname on which the request was received
+ String server_hostname = request.getLocalName();
+
+ // retrieve server port number on which the request was received
+ int server_port = request.getLocalPort();
+
+ // uncomment the following lines to write to 'catalina.out'
+ //System.out.println( "scheme = '" + scheme + "'" );
+ //System.out.println( "client hostname = '" + client_hostname + "'" );
+ //System.out.println( "client port = '" + client_port + "'" );
+ //System.out.println( "server hostname = '" + server_hostname + "'" );
+ //System.out.println( "server port = '" + server_port + "'" );
+
+ // compose the appropriate URL
+ String URL = "";
+
+ if( scheme.equals( HTTP_SCHEME ) ) {
+ if( server_port == EE_HTTP_PORT ) {
+ URL = scheme + "://" + client_hostname + ":" + client_port + EE_PATH;
+ } else {
+ // unknown HTTP server port: should never get here
+ URL = scheme + "://" + client_hostname + ":" + client_port + ERROR_PATH;
+
+ // uncomment the following line to write to 'catalina.out'
+ //System.out.println( "Unknown HTTP server port: '" + server_port + "'" );
+ }
+ } else if( scheme.equals( HTTPS_SCHEME ) ) {
+ if( server_port == AGENT_HTTPS_PORT ) {
+ URL = scheme + "://" + client_hostname + ":" + client_port + AGENT_PATH;
+ } else if( server_port == EE_HTTPS_PORT ) {
+ URL = scheme + "://" + client_hostname + ":" + client_port + EE_PATH;
+ } else if( server_port == ADMIN_HTTPS_PORT ) {
+ URL = scheme + "://" + client_hostname + ":" + client_port + ADMIN_PATH;
+ } else {
+ // unknown HTTPS server port: should never get here
+ URL = scheme + "://" + client_hostname + ":" + client_port + ERROR_PATH;
+
+ // uncomment the following line to write to 'catalina.out'
+ //System.out.println( "Unknown HTTPS server port: '" + server_port + "'" );
+ }
+ } else {
+ // unacceptable scheme: should never get here
+ URL = scheme + "://" + client_hostname + ":" + client_port + ERROR_PATH;
+
+ // uncomment the following line to write to 'catalina.out'
+ //System.out.println( "Unacceptable scheme: '" + scheme + "'" );
+ }
+
+ // respond (back to browser) with the appropriate redirected URL
+ response.sendRedirect( URL );
+%>
diff --git a/base/ca/shared/webapps/ca/WEB-INF/velocity.properties b/base/ca/shared/webapps/ca/WEB-INF/velocity.properties
new file mode 100644
index 000000000..2dfae4bca
--- /dev/null
+++ b/base/ca/shared/webapps/ca/WEB-INF/velocity.properties
@@ -0,0 +1,8 @@
+resource.loader = file
+file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
+file.resource.loader.path = [PKI_INSTANCE_PATH]/[PKI_WEBAPPS_NAME]/[PKI_SUBSYSTEM_TYPE]
+file.resource.loader.cache = true
+file.resource.loader.modificationCheckInterval = 2
+input.encoding=UTF-8
+output.encoding=UTF-8
+runtime.log.logsystem.class=org.apache.velocity.runtime.log.NullLogSystem
diff --git a/base/ca/shared/webapps/ca/WEB-INF/web.xml b/base/ca/shared/webapps/ca/WEB-INF/web.xml
new file mode 100644
index 000000000..5e91977aa
--- /dev/null
+++ b/base/ca/shared/webapps/ca/WEB-INF/web.xml
@@ -0,0 +1,2480 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE web-app
+ PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "file:///usr/share/pki/setup/web-app_2_3.dtd">
+<web-app>
+
+ <filter>
+ <filter-name>AgentRequestFilter</filter-name>
+ <filter-class>com.netscape.cms.servlet.filter.AgentRequestFilter</filter-class>
+ <init-param>
+ <param-name>https_port</param-name>
+ <param-value>[PKI_AGENT_SECURE_PORT]</param-value>
+ </init-param>
+[PKI_OPEN_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>proxy_port</param-name>
+ <param-value>[PKI_PROXY_SECURE_PORT]</param-value>
+ </init-param>
+[PKI_CLOSE_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>active</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ </filter>
+
+ <filter>
+ <filter-name>AdminRequestFilter</filter-name>
+ <filter-class>com.netscape.cms.servlet.filter.AdminRequestFilter</filter-class>
+ <init-param>
+ <param-name>https_port</param-name>
+ <param-value>[PKI_ADMIN_SECURE_PORT]</param-value>
+ </init-param>
+[PKI_OPEN_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>proxy_port</param-name>
+ <param-value>[PKI_PROXY_SECURE_PORT]</param-value>
+ </init-param>
+[PKI_CLOSE_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>active</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ </filter>
+
+ <filter>
+ <filter-name>EERequestFilter</filter-name>
+ <filter-class>com.netscape.cms.servlet.filter.EERequestFilter</filter-class>
+ <init-param>
+ <param-name>http_port</param-name>
+ <param-value>[PKI_UNSECURE_PORT]</param-value>
+ </init-param>
+ <init-param>
+ <param-name>https_port</param-name>
+ <param-value>[PKI_EE_SECURE_PORT]</param-value>
+ </init-param>
+[PKI_OPEN_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>proxy_port</param-name>
+ <param-value>[PKI_PROXY_SECURE_PORT]</param-value>
+ </init-param>
+ <init-param>
+ <param-name>proxy_http_port</param-name>
+ <param-value>[PKI_PROXY_UNSECURE_PORT]</param-value>
+ </init-param>
+[PKI_CLOSE_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>active</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ </filter>
+
+ <filter>
+ <filter-name>EEClientAuthRequestFilter</filter-name>
+ <filter-class>com.netscape.cms.servlet.filter.EEClientAuthRequestFilter</filter-class>
+ <init-param>
+ <param-name>https_port</param-name>
+ <param-value>[PKI_EE_SECURE_CLIENT_AUTH_PORT]</param-value>
+ </init-param>
+[PKI_OPEN_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>proxy_port</param-name>
+ <param-value>[PKI_PROXY_SECURE_PORT]</param-value>
+ </init-param>
+[PKI_CLOSE_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>active</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ </filter>
+
+ <servlet>
+ <servlet-name>csadmin-wizard</servlet-name>
+ <servlet-class>com.netscape.cms.servlet.wizard.WizardServlet</servlet-class>
+ <init-param>
+ <param-name>properties</param-name>
+ <param-value>/WEB-INF/velocity.properties</param-value>
+ </init-param>
+ <init-param>
+ <param-name>name</param-name>
+ <param-value>CA Setup Wizard</param-value>
+ </init-param>
+ <init-param>
+ <param-name>panels</param-name>
+ <param-value>welcome=com.netscape.cms.servlet.csadmin.WelcomePanel,module=com.netscape.cms.servlet.csadmin.ModulePanel,confighsmlogin=com.netscape.cms.servlet.csadmin.ConfigHSMLoginPanel,securitydomain=com.netscape.cms.servlet.csadmin.SecurityDomainPanel,securitydomain=com.netscape.cms.servlet.csadmin.DisplayCertChainPanel,subsystem=com.netscape.cms.servlet.csadmin.CreateSubsystemPanel,clone=com.netscape.cms.servlet.csadmin.DisplayCertChainPanel,restorekeys=com.netscape.cms.servlet.csadmin.RestoreKeyCertPanel,cahierarchy=com.netscape.cms.servlet.csadmin.HierarchyPanel,database=com.netscape.cms.servlet.csadmin.DatabasePanel,size=com.netscape.cms.servlet.csadmin.SizePanel,subjectname=com.netscape.cms.servlet.csadmin.NamePanel,certrequest=com.netscape.cms.servlet.csadmin.CertRequestPanel,backupkeys=com.netscape.cms.servlet.csadmin.BackupKeyCertPanel,savepk12=com.netscape.cms.servlet.csadmin.SavePKCS12Panel,importcachain=com.netscape.cms.servlet.csadmin.ImportCAChainPanel,admin=com.netscape.cms.servlet.csadmin.AdminPanel,importadmincert=com.netscape.cms.servlet.csadmin.ImportAdminCertPanel,done=com.netscape.cms.servlet.csadmin.DonePanel</param-value>
+ </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name>csadmin-login</servlet-name>
+ <servlet-class>com.netscape.cms.servlet.csadmin.LoginServlet</servlet-class>
+ <init-param>
+ <param-name>properties</param-name>
+ <param-value>/WEB-INF/velocity.properties</param-value>
+ </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> services </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.MainPageServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authorityId </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> services </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /services.template </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caacl </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.ACLAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> caacl </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caug </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.UsrGrpAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> caug </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caserver </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.CMSAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> caserver </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> capolicy </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.PolicyAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> capolicy </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> calog </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.LogAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> calog </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caGetAdminCertBySerial </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.GetBySerial </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caGetAdminCertBySerial </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.admin.certificate </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caUpdateConnector </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.UpdateConnector </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caUpdateConnector </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> TokenAuth </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.connectorInfo </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caRegisterUser </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.RegisterUser </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caRegisterUser </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> TokenAuth </param-value> </init-param>
+ <init-param><param-name> GroupName </param-name>
+ <param-value> Certificate Manager Agents </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.registerUser </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caRegisterRaUser </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.RegisterUser </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caRegisterRaUser </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> TokenAuth </param-value> </init-param>
+ <init-param><param-name> GroupName </param-name>
+ <param-value> Registration Manager Agents </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.registerUser </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caGetDomainXML </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.GetDomainXML </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caGetDomainXML </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caUpdateDomainXML </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.UpdateDomainXML </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caUpdateDomainXML </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.securitydomain.domainxml </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caUpdateNumberRange </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.UpdateNumberRange </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caUpdateNumberRange </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> TokenAuth </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.clone.configuration.UpdateNumberRange </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caUpdateOCSPConfig </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.UpdateOCSPConfig </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caUpdateOCSPConfig </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> TokenAuth </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.admin.ocsp </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caDownloadPKCS12 </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.DownloadPKCS12 </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caDownloadPKCS12 </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> TokenAuth </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.clone.configuration </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caGetCertChain </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.GetCertChain </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caGetCertChain </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caGetCertChainAdmin </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.GetCertChain </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caGetCertChainAdmin </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caGetStatus </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.GetStatus </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caGetStatus </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caGetConfigEntries </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.GetConfigEntries </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caGetConfigEntries </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> TokenAuth </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.clone.configuration.GetConfigEntries </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caca </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.CAAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> caca </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caregistry </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.RegistryAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> caregistry </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caauths </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.AuthAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> caauths </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> castart </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.CMSStartServlet </servlet-class>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> cfgPath </param-name>
+ <param-value> [PKI_INSTANCE_PATH]/conf/CS.cfg </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> castart </param-value> </init-param>
+ <load-on-startup> 1 </load-on-startup>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caprofile </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.ProfileAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> caprofile </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> cajobsScheduler </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.JobsAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> cajobsScheduler </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caadminEnroll </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.EnrollServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> successTemplate </param-name>
+ <param-value> /admin/ca/EnrollSuccess.template </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> admin </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caadminEnroll </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.admin.request.enrollment </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> passwdUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> capublisher </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.PublisherAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> capublisher </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caGetOCSPInfo </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.ocsp.GetOCSPInfo </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ca/getOCSPInfo.template </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caGetOCSPInfo </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.ocsp </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caUpdateDir </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.UpdateDir </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ca/updateDir.template </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caUpdateDir </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.directory </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caGetCertFromRequest-agent </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.GetCertFromRequest </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caGetCertFromRequest </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.certificate </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> importCert </param-name>
+ <param-value> true </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caGetBySerial-agent </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.GetBySerial </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> successTemplate </param-name>
+ <param-value> /ca/ImportCert.template </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caGetBySerial </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.certificate </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caProfileSelect-agent </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.profile.ProfileSelectServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authorityId </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caProfileSelect </param-value> </init-param>
+ <init-param><param-name> unauthorizedTemplate </param-name>
+ <param-value> /GenUnauthorized.template </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ca/ProfileSelect.template </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.profile </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caindex </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.IndexServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> caindex </param-value> </init-param>
+ <init-param><param-name> template </param-name>
+ <param-value> index.template </param-value> </init-param>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caStats </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.GetStats </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ca/getStats.template </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> stats </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.systemstatus </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caMonitor </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.Monitor </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ca/monitor.template </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caMonitor </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.systemstatus </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caReasonToRevoke </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.ReasonToRevoke </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ca/reasonToRevoke.template </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caReasonToRevoke </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.certificates </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caListRequests </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.DisplayHtmlServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> htmlPath </param-name>
+ <param-value> /agent/ca/ListRequests.html </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caListRequests </param-value> </init-param>
+ <init-param><param-name> unauthorizedTemplate </param-name>
+ <param-value> /agent/ca/GenUnauthorized.template </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> casearchReqs </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.request.SearchReqs </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> parser </param-name>
+ <param-value> CertReqParser.NODETAIL_PARSER </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ca/queryReq.template </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> casearchReqs </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.requests </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> timeLimits </param-name>
+ <param-value> 10 </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caProfileApprove </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.profile.ProfileApproveServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authorityId </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caProfileApprove </param-value> </init-param>
+ <init-param><param-name> unauthorizedTemplate </param-name>
+ <param-value> /agent/GenUnauthorized.template </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ca/ProfileApprove.template </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.profile </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caUpdateDirectory </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.DisplayHtmlServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> htmlPath </param-name>
+ <param-value> /agent/ca/UpdateDir.html </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caUpdateDirectory </param-value> </init-param>
+ <init-param><param-name> unauthorizedTemplate </param-name>
+ <param-value> /agent/GenUnauthorized.template </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caProfileReview </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.profile.ProfileReviewServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authorityId </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caProfileReview </param-value> </init-param>
+ <init-param><param-name> unauthorizedTemplate </param-name>
+ <param-value> /agent/GenUnauthorized.template </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ca/ProfileReview.template </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.request.profile </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caConnector </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.connector.ConnectorServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caConnector </param-value> </init-param>
+ <init-param><param-name> RequestEncoder </param-name>
+ <param-value> com.netscape.cmscore.connector.HttpRequestEncoder </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.connector </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caSrchCerts-agent </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.SrchCerts </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ca/srchCert.template </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caSrchCerts </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.certificates </param-value> </init-param>
+ <init-param><param-name> timeLimits </param-name>
+ <param-value> 15 </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caheader </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.IndexServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> caheader </param-value> </init-param>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> template </param-name>
+ <param-value> /agent/header.template </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ </servlet>
+
+
+ <servlet>
+ <servlet-name> caDisplayCertFromRequest-agent </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.GetCertFromRequest </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caDisplayCertFromRequest </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.certificate </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> importCert </param-name>
+ <param-value> false </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caListCerts-agent </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.ListCerts </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ca/queryCert.template </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caListCerts </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.certificates </param-value> </init-param>
+ <init-param><param-name> maxResults </param-name>
+ <param-value> 1000 </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caqueryReq </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.request.QueryReq </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> parser </param-name>
+ <param-value> CertReqParser.NODETAIL_PARSER </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ca/queryReq.template </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caqueryReq </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.requests </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> maxResults </param-name>
+ <param-value> 1000 </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caProcessReq </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.request.ProcessReq </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> parser </param-name>
+ <param-value> CertReqParser.DETAIL_PARSER </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caProcessReq </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ca/processReq.template </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.request.enrollment </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caports </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.PortsServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> caports </param-value> </init-param>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caSrchCert </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.DisplayHtmlServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> htmlPath </param-name>
+ <param-value> /agent/ca/SrchCert.html </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caSrchCert </param-value> </init-param>
+ <init-param><param-name> unauthorizedTemplate </param-name>
+ <param-value> /agent/GenUnauthorized.template </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caProfileList-agent </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.profile.ProfileListServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authorityId </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caProfileList </param-value> </init-param>
+ <init-param><param-name> unauthorizedTemplate </param-name>
+ <param-value> /agent/GenUnauthorized.template </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ca/ProfileList.template </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.profiles </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caDisplayBySerial-agent </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.DisplayBySerial </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ca/displayBySerial.template </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caDisplayBySerial </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.certificate </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caSrchRevokeCert </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.DisplayHtmlServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> htmlPath </param-name>
+ <param-value> /agent/ca/SrchRevokeCert.html </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caSrchRevokeCert </param-value> </init-param>
+ <init-param><param-name> unauthorizedTemplate </param-name>
+ <param-value> /agent/GenUnauthorized.template </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caDoUnrevoke </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.DoUnrevoke </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ca/unrevocationResult.template </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caDoUnrevoke </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.certificate </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caDoRevoke-agent </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.DoRevoke </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ca/revocationResult.template </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caDoRevoke </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.certificates </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caProfileProcess </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.profile.ProfileProcessServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authorityId </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caProfileProcess </param-value> </init-param>
+ <init-param><param-name> unauthorizedTemplate </param-name>
+ <param-value> /GenUnauthorized.template </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ca/ProfileProcess.template </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.request.profile </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caProcessCertReq </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.request.ProcessCertReq </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caProcessCertReq </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.request.enrollment </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> cabulkissuance </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.EnrollServlet </servlet-class>
+ <init-param><param-name> unauthorizedTemplate </param-name>
+ <param-value> /agent/ca/bulkissuance.template </param-value> </init-param>
+ <init-param><param-name> rejectedTemplate </param-name>
+ <param-value> /agent/ca/bulkissuance.template </param-value> </init-param>
+ <init-param><param-name> svcpendingTemplate </param-name>
+ <param-value> /agent/ca/bulkissuance.template </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.request.enrollment </param-value> </init-param>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> cabulkissuance </param-value> </init-param>
+ <init-param><param-name> errorTemplate </param-name>
+ <param-value> /agent/ca/bulkissuance.template </param-value> </init-param>
+ <init-param><param-name> unexpectedErrorTemplate </param-name>
+ <param-value> /agent/ca/bulkissuance.template </param-value> </init-param>
+ <init-param><param-name> pendingTemplate </param-name>
+ <param-value> /agent/ca/bulkissuance.template </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> successTemplate </param-name>
+ <param-value> /agent/ca/bulkissuance.template </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caQueryBySerial </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.DisplayHtmlServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> htmlPath </param-name>
+ <param-value> /agent/ca/queryBySerial.html </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caQueryBySerial </param-value> </init-param>
+ <init-param><param-name> unauthorizedTemplate </param-name>
+ <param-value> /agent/GenUnauthorized.template </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> camasterCAUpdateCRL </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.UpdateCRL </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ca/updateCRL.template </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> camasterCAUpdateCRL </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.crl </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> camasterCADisplayCRL </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.DisplayCRL </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ca/displayCRL.template </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> camasterCADisplayCRL </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.crl </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> camasterCAGetInfo </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.GetInfo </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> camasterCAGetInfo </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.crl </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caProfileSubmit </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.profile.ProfileSubmitServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authorityId </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caProfileSubmit </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /ee/ca/ProfileSubmit.template </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.profile </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caRenewal </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.RenewalServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> successTemplate </param-name>
+ <param-value> /ca/RenewalSuccess.template </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caRenewal </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.certificate </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> sslClientCertAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caGetCertFromRequest </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.GetCertFromRequest </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> successTemplate </param-name>
+ <param-value> /ee/ca/ImportCert.template </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caGetCertFromRequest </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.certificate </param-value> </init-param>
+ <init-param><param-name> importCert </param-name>
+ <param-value> true </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caGetCRL </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.GetCRL </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /ee/ca/displayCRL.template </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caGetCRL </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.crl </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caGetBySerial </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.GetBySerial </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> successTemplate </param-name>
+ <param-value> /ee/ca/ImportCert.template </param-value> </init-param>
+ <init-param><param-name> importCertTemplate </param-name>
+ <param-value> /ee/ca/ImportAdminCert.template </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caGetBySerial </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.certificate </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caGetAdminBySerial </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.GetBySerial </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> successTemplate </param-name>
+ <param-value> /admin/ca/ImportCert.template </param-value> </init-param>
+ <init-param><param-name> importCertTemplate </param-name>
+ <param-value> /admin/ca/ImportAdminCert.template </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> admin </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caGetAdminBySerial </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.admin.certificate </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> admin </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> cacertbasedenrollment </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.EnrollServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> successTemplate </param-name>
+ <param-value> /ca/EnrollSuccess.template </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> cacertbasedenrollment </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.request.enrollment </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caProfileSelect </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.profile.ProfileSelectServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authorityId </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caProfileSelect </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /ee/ca/ProfileSelect.template </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.profile </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caenrollment </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.EnrollServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> successTemplate </param-name>
+ <param-value> /ca/EnrollSuccess.template </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caenrollment </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.request.enrollment </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caCheckRequest </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.request.CheckRequest </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /ee/ca/requestStatus.template </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caCheckRequest </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.requestStatus </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caOCSP </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.ocsp.OCSPServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caOCSP </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.request.ocsp </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caDoRevoke1 </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.DoRevokeTPS </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /ee/ca/revocationResult.template</param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caDoRevoke1 </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.certificates </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caSrchCerts </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.SrchCerts </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /ee/ca/srchCert.template </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caSrchCerts </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.certificates </param-value> </init-param>
+ <init-param><param-name> timeLimits </param-name>
+ <param-value> 10 </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caDynamicVariables </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.DynamicVariablesServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> caDynamicVariables </param-value> </init-param>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> dynamicVariables </param-name>
+ <param-value> serverdate=serverdate(),subsystemname=subsystemname(),http=http(),authmgrs=authmgrs(),clacrlurl=clacrlurl() </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caDynamicVariables-agent </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.DynamicVariablesServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> caDynamicVariables </param-value> </init-param>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> dynamicVariables </param-name>
+ <param-value> serverdate=serverdate(),subsystemname=subsystemname(),http=http(),authmgrs=authmgrs(),clacrlurl=clacrlurl() </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caDynamicVariables-admin </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.DynamicVariablesServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> caDynamicVariables </param-value> </init-param>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> dynamicVariables </param-name>
+ <param-value> serverdate=serverdate(),subsystemname=subsystemname(),http=http(),authmgrs=authmgrs(),clacrlurl=clacrlurl() </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> admin </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caProfileSubmitCMCSimple </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.profile.ProfileSubmitCMCServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> cert_request_type </param-name>
+ <param-value> pkcs10 </param-value> </init-param>
+ <init-param><param-name> profileId </param-name>
+ <param-value> caSimpleCMCUserCert </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> outputFormat </param-name>
+ <param-value> cmc </param-value> </init-param>
+ <init-param><param-name> authorityId </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caProfileSubmitCMCSimple </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /ee/ca/ProfileSubmit.template </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.profile </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caDisplayCertFromRequest </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.GetCertFromRequest </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> successTemplate </param-name>
+ <param-value> /ee/ca/displayCertFromRequest.template </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caDisplayCertFromRequest </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.certificate </param-value> </init-param>
+ <init-param><param-name> importCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caListCerts </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.ListCerts </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /ee/ca/queryCert.template </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caListCerts </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.certificates </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ <init-param><param-name> maxResults </param-name>
+ <param-value> 1000 </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caProfileSubmitSSLClient </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.profile.ProfileSubmitServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authorityId </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caProfileSubmitSSLClient </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /ee/ca/ProfileSubmit.template </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.profile </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caGetCAChain </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.GetCAChain </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /ee/ca/displayCaCert.template </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caGetCAChain </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.certchain </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caProfileSubmitCMCFull </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.profile.ProfileSubmitCMCServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> cert_request_type </param-name>
+ <param-value> cmc </param-value> </init-param>
+ <init-param><param-name> profileId </param-name>
+ <param-value> caFullCMCUserCert </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authorityId </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caProfileSubmitCMCFull </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /ee/ca/ProfileSubmit.template </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.profile </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caProfileList </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.profile.ProfileListServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authorityId </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caProfileList </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /ee/ca/ProfileList.template </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.profiles </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caCMCRevReq </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.CMCRevReqServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /ee/ca/revocationResult.template </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caCMCRevReq </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> CMCAuth </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.certificates </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caDoUnrevoke1 </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.DoUnrevokeTPS </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caDoUnrevoke1 </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ca.certificate </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caDisplayBySerial </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.DisplayBySerial </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /ee/ca/displayBySerial.template </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caDisplayBySerial </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.certificate </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caRevocation </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.RevocationServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> successTemplate </param-name>
+ <param-value> /ee/ca/reasonToRevoke.template </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caRevocation </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.request.revocation </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> sslClientCertAuthMgr </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caGetInfo </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.GetInfo </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caGetInfo </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.crl </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caGetSubsystemCert </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.GetSubsystemCert </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caGetSubsystemCert </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.certificate </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caDoRevoke </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.DoRevoke </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /ee/ca/revocationResult.template </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caDoRevoke </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.certificates </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caSecurityDomainLogin </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.SecurityDomainLogin </servlet-class>
+ <init-param> <param-name>properties</param-name>
+ <param-value>/WEB-INF/velocity.properties</param-value> </init-param>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caSecurityDomainLogin </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.certificates </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caGetCookie </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.GetCookie </servlet-class>
+ <init-param> <param-name>properties</param-name>
+ <param-value>/WEB-INF/velocity.properties</param-value> </init-param>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caGetCookie </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> passwdUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /admin/ca/sendCookie.template </param-value> </init-param>
+ <init-param><param-name> errorTemplatePath </param-name>
+ <param-value> /admin/ca/securitydomainlogin.template </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caTokenAuthenticate </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.TokenAuthenticate </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caTokenAuthenticate </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caGetTokenInfo </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.GetTokenInfo </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> caGetTokenInfo </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caProxyProfileSubmit </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.ProxyServlet </servlet-class>
+ <init-param><param-name> destServlet </param-name>
+ <param-value> /ee/ca/profileSubmit </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caProxyBulkIssuance </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.ProxyServlet </servlet-class>
+ <init-param><param-name> destServlet </param-name>
+ <param-value> /agent/ca/bulkissuance </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caSCEP </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.scep.CRSEnrollment </servlet-class>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> profileId </param-name>
+ <param-value> caRouterCert </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caRASCEP </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.cert.scep.CRSEnrollment </servlet-class>
+ <init-param><param-name> authority </param-name>
+ <param-value> ca </param-value> </init-param>
+ <init-param><param-name> profileId </param-name>
+ <param-value> caRARouterCert </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> caProxyDoRevoke </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.ProxyServlet </servlet-class>
+ <init-param><param-name> destServlet </param-name>
+ <param-value> /agent/ca/doRevoke </param-value> </init-param>
+ </servlet>
+
+[PKI_OPEN_SEPARATE_PORTS_WEB_COMMENT]
+ <filter-mapping>
+ <filter-name> AgentRequestFilter </filter-name>
+ <url-pattern> /agent/* </url-pattern>
+ <url-pattern> /ca/getCertFromRequest </url-pattern>
+ <url-pattern> /ca/getBySerial </url-pattern>
+ <url-pattern> /ca/connector </url-pattern>
+ <url-pattern> /ca/displayCertFromRequest </url-pattern>
+ <url-pattern> /doRevoke </url-pattern>
+ </filter-mapping>
+
+ <filter-mapping>
+ <filter-name> AdminRequestFilter </filter-name>
+ <url-pattern> /admin/* </url-pattern>
+ <url-pattern> /auths </url-pattern>
+ <url-pattern> /acl </url-pattern>
+ <url-pattern> /server </url-pattern>
+ <url-pattern> /caadmin </url-pattern>
+ <url-pattern> /caprofile </url-pattern>
+ <url-pattern> /jobsScheduler </url-pattern>
+ <url-pattern> /capublisher </url-pattern>
+ <url-pattern> /log </url-pattern>
+ <url-pattern> /ug </url-pattern>
+ </filter-mapping>
+
+ <filter-mapping>
+ <filter-name> EEClientAuthRequestFilter </filter-name>
+ <url-pattern> /eeca/* </url-pattern>
+ </filter-mapping>
+
+ <filter-mapping>
+ <filter-name> EERequestFilter </filter-name>
+ <url-pattern> /ee/* </url-pattern>
+ <url-pattern> /renewal </url-pattern>
+ <url-pattern> /certbasedenrollment </url-pattern>
+ <url-pattern> /ocsp </url-pattern>
+ <url-pattern> /enrollment </url-pattern>
+ <url-pattern> /profileSubmit </url-pattern>
+ <url-pattern> /cgi-bin/pkiclient.exe </url-pattern>
+ </filter-mapping>
+[PKI_CLOSE_SEPARATE_PORTS_WEB_COMMENT]
+
+ <servlet-mapping>
+ <servlet-name> caacl </servlet-name>
+ <url-pattern> /acl </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caug </servlet-name>
+ <url-pattern> /ug </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caserver </servlet-name>
+ <url-pattern> /server </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> capolicy </servlet-name>
+ <url-pattern> /capolicy </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> calog </servlet-name>
+ <url-pattern> /log </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caGetAdminCertBySerial </servlet-name>
+ <url-pattern> /ca/getAdminCertBySerial </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caGetConfigEntries </servlet-name>
+ <url-pattern> /admin/ca/getConfigEntries </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caGetDomainXML </servlet-name>
+ <url-pattern> /admin/ca/getDomainXML </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caUpdateDomainXML </servlet-name>
+ <url-pattern> /agent/ca/updateDomainXML </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caUpdateNumberRange </servlet-name>
+ <url-pattern> /ee/ca/updateNumberRange </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caDownloadPKCS12 </servlet-name>
+ <url-pattern> /admin/console/config/savepkcs12 </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caGetCertChain </servlet-name>
+ <url-pattern> /ee/ca/getCertChain </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caGetCertChainAdmin </servlet-name>
+ <url-pattern> /admin/ca/getCertChain </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caGetStatus </servlet-name>
+ <url-pattern> /admin/ca/getStatus </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caca </servlet-name>
+ <url-pattern> /caadmin </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caregistry </servlet-name>
+ <url-pattern> /registry </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caauths </servlet-name>
+ <url-pattern> /auths </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> castart </servlet-name>
+ <url-pattern> /start </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caprofile </servlet-name>
+ <url-pattern> /caprofile </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caDynamicVariables </servlet-name>
+ <url-pattern> /ee/dynamicVars.js </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caDynamicVariables-agent </servlet-name>
+ <url-pattern> /agent/dynamicVars.js </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caDynamicVariables-admin </servlet-name>
+ <url-pattern> /admin/dynamicVars.js </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> cajobsScheduler </servlet-name>
+ <url-pattern> /jobsScheduler </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caadminEnroll </servlet-name>
+ <url-pattern> /admin/ca/adminEnroll </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> capublisher </servlet-name>
+ <url-pattern> /capublisher </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caGetOCSPInfo </servlet-name>
+ <url-pattern> /agent/ca/getOCSPInfo </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caUpdateDir </servlet-name>
+ <url-pattern> /agent/ca/updateDir </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caGetCertFromRequest-agent </servlet-name>
+ <url-pattern> /ca/getCertFromRequest </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caGetBySerial-agent </servlet-name>
+ <url-pattern> /ca/getBySerial </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caProfileSelect-agent </servlet-name>
+ <url-pattern> /agent/ca/profileSelect </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caindex </servlet-name>
+ <url-pattern> /index </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caMonitor </servlet-name>
+ <url-pattern> /agent/ca/monitor </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caReasonToRevoke </servlet-name>
+ <url-pattern> /agent/ca/reasonToRevoke </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caListRequests </servlet-name>
+ <url-pattern> /agent/ca/listRequests.html </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> casearchReqs </servlet-name>
+ <url-pattern> /agent/ca/searchReqs </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caProfileApprove </servlet-name>
+ <url-pattern> /agent/ca/profileApprove </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caUpdateDirectory </servlet-name>
+ <url-pattern> /agent/ca/updateDir.html </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caProfileReview </servlet-name>
+ <url-pattern> /agent/ca/profileReview </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caConnector </servlet-name>
+ <url-pattern> /ca/connector </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caSrchCerts-agent </servlet-name>
+ <url-pattern> /agent/ca/srchCerts </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caheader </servlet-name>
+ <url-pattern> /agent/header </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caDisplayCertFromRequest-agent </servlet-name>
+ <url-pattern> /ca/displayCertFromRequest </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caListCerts-agent </servlet-name>
+ <url-pattern> /agent/ca/listCerts </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caqueryReq </servlet-name>
+ <url-pattern> /agent/ca/queryReq </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caProcessReq </servlet-name>
+ <url-pattern> /agent/ca/processReq </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caports </servlet-name>
+ <url-pattern> /ee/ca/ports </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caSrchCert </servlet-name>
+ <url-pattern> /agent/ca/srchCert.html </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caProfileList-agent </servlet-name>
+ <url-pattern> /agent/ca/profileList </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caDisplayBySerial-agent </servlet-name>
+ <url-pattern> /agent/ca/displayBySerial </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caSrchRevokeCert </servlet-name>
+ <url-pattern> /agent/ca/srchRevokeCert.html </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caDoUnrevoke </servlet-name>
+ <url-pattern> /agent/ca/doUnrevoke </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caDoRevoke-agent </servlet-name>
+ <url-pattern> /agent/ca/doRevoke </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caProfileProcess </servlet-name>
+ <url-pattern> /agent/ca/profileProcess </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caProcessCertReq </servlet-name>
+ <url-pattern> /agent/ca/processCertReq </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> cabulkissuance </servlet-name>
+ <url-pattern> /agent/ca/bulkissuance </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caQueryBySerial </servlet-name>
+ <url-pattern> /agent/ca/queryBySerial.html </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> camasterCAUpdateCRL </servlet-name>
+ <url-pattern> /agent/ca/updateCRL </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> camasterCADisplayCRL </servlet-name>
+ <url-pattern> /agent/ca/displayCRL </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> camasterCAGetInfo </servlet-name>
+ <url-pattern> /agent/ca/getInfo </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caProfileSubmit </servlet-name>
+ <url-pattern> /ee/ca/profileSubmit </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caRenewal </servlet-name>
+ <url-pattern> /renewal </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caGetCertFromRequest </servlet-name>
+ <url-pattern> /ee/ca/getCertFromRequest </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caGetCRL </servlet-name>
+ <url-pattern> /ee/ca/getCRL </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caGetBySerial </servlet-name>
+ <url-pattern> /ee/ca/getBySerial </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caGetAdminBySerial </servlet-name>
+ <url-pattern> /admin/ca/getBySerial </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> cacertbasedenrollment </servlet-name>
+ <url-pattern> /certbasedenrollment </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caProfileSelect </servlet-name>
+ <url-pattern> /ee/ca/profileSelect </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caenrollment </servlet-name>
+ <url-pattern> /enrollment </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caCheckRequest </servlet-name>
+ <url-pattern> /ee/ca/checkRequest </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caOCSP </servlet-name>
+ <url-pattern> /ocsp </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caDoRevoke1 </servlet-name>
+ <url-pattern> /ee/subsystem/ca/doRevoke </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caStats </servlet-name>
+ <url-pattern> /agent/ca/getStats </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caSrchCerts </servlet-name>
+ <url-pattern> /ee/ca/srchCerts </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caProfileSubmitCMCSimple </servlet-name>
+ <url-pattern> /ee/ca/profileSubmitCMCSimple </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caDisplayCertFromRequest </servlet-name>
+ <url-pattern> /ee/ca/displayCertFromRequest </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caListCerts </servlet-name>
+ <url-pattern> /ee/ca/listCerts </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caProfileSubmitSSLClient </servlet-name>
+ <url-pattern> /eeca/ca/profileSubmitSSLClient </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caGetCertFromRequest </servlet-name>
+ <url-pattern> /eeca/ca/getCertFromRequest </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caProfileSubmitSSLClient </servlet-name>
+ <url-pattern> /ee/ca/profileSubmitSSLClient </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caGetCAChain </servlet-name>
+ <url-pattern> /ee/ca/getCAChain </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caProfileSubmitCMCFull </servlet-name>
+ <url-pattern> /ee/ca/profileSubmitCMCFull </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caProfileList </servlet-name>
+ <url-pattern> /ee/ca/profileList </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caCMCRevReq </servlet-name>
+ <url-pattern> /ee/ca/CMCRevReq </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caDoUnrevoke1 </servlet-name>
+ <url-pattern> /ee/subsystem/ca/doUnrevoke </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caDisplayBySerial </servlet-name>
+ <url-pattern> /ee/ca/displayBySerial </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caRevocation </servlet-name>
+ <url-pattern> /ee/ca/revocation </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caGetInfo </servlet-name>
+ <url-pattern> /ee/ca/getInfo </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caDoRevoke </servlet-name>
+ <url-pattern> /ee/ca/doRevoke </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>csadmin-login</servlet-name>
+ <url-pattern>/admin/console/config/login</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>csadmin-wizard</servlet-name>
+ <url-pattern>/admin/console/config/wizard</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caUpdateConnector </servlet-name>
+ <url-pattern> /admin/ca/updateConnector </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caRegisterUser </servlet-name>
+ <url-pattern> /admin/ca/registerUser </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caRegisterRaUser </servlet-name>
+ <url-pattern> /admin/ca/registerRaUser </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> services </servlet-name>
+ <url-pattern> /services </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caGetSubsystemCert </servlet-name>
+ <url-pattern> /admin/ca/getSubsystemCert </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caSecurityDomainLogin </servlet-name>
+ <url-pattern> /admin/ca/securityDomainLogin </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caGetCookie </servlet-name>
+ <url-pattern> /admin/ca/getCookie </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caTokenAuthenticate </servlet-name>
+ <url-pattern> /ee/ca/tokenAuthenticate </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caGetTokenInfo </servlet-name>
+ <url-pattern> /ee/ca/getTokenInfo </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caUpdateOCSPConfig </servlet-name>
+ <url-pattern> /ee/ca/updateOCSPConfig </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caProxyProfileSubmit </servlet-name>
+ <url-pattern> /profileSubmit </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caProxyBulkIssuance </servlet-name>
+ <url-pattern> /agent/bulkissuance </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caProxyDoRevoke </servlet-name>
+ <url-pattern> /doRevoke </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caSCEP </servlet-name>
+ <url-pattern> /cgi-bin/pkiclient.exe </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> caRASCEP </servlet-name>
+ <url-pattern> /ee/ca/pkiclient </url-pattern>
+ </servlet-mapping>
+
+ <!-- ==================== Default Session Configuration =============== -->
+ <!-- You can set the default session timeout (in minutes) for all newly -->
+ <!-- created sessions by modifying the value below. -->
+ <!-- -->
+ <!-- To disable session timeouts for this instance, set a value of -1. -->
+
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+</web-app>
+
diff --git a/base/ca/src/CMakeLists.txt b/base/ca/src/CMakeLists.txt
new file mode 100644
index 000000000..12436f301
--- /dev/null
+++ b/base/ca/src/CMakeLists.txt
@@ -0,0 +1,57 @@
+project(pki-ca_java Java)
+
+# '/usr/share/java' jars
+find_file(LDAPJDK_JAR
+ NAMES
+ ldapjdk.jar
+ PATHS
+ /usr/share/java
+)
+
+
+# '${JAVA_LIB_INSTALL_DIR}' jars
+find_file(JSS_JAR
+ NAMES
+ jss4.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+)
+
+find_file(COMMONS_CODEC_JAR
+ NAMES
+ commons-codec.jar
+ PATHS
+ /usr/share/java
+)
+
+
+# identify java sources
+set(pki-ca_java_SRCS
+ com/netscape/ca/CMSCRLExtensions.java
+ com/netscape/ca/CAService.java
+ com/netscape/ca/SigningUnit.java
+ com/netscape/ca/CRLWithExpiredCerts.java
+ com/netscape/ca/CRLIssuingPoint.java
+ com/netscape/ca/CAPolicy.java
+ com/netscape/ca/CertificateAuthority.java
+)
+
+
+# set classpath
+set(CMAKE_JAVA_INCLUDE_PATH
+ ${PKI_CERTSRV_JAR} ${PKI_CMS_JAR} ${PKI_CMSCORE_JAR}
+ ${PKI_CMSUTIL_JAR} ${PKI_NSUTIL_JAR}
+ ${LDAPJDK_JAR}
+ ${JSS_JAR} ${COMMONS_CODEC_JAR} ${SYMKEY_JAR})
+
+
+# set version
+set(CMAKE_JAVA_TARGET_VERSION ${APPLICATION_VERSION})
+
+
+# build pki-ca.jar
+add_jar(pki-ca ${pki-ca_java_SRCS})
+add_dependencies(pki-ca symkey pki-nsutil pki-cmsutil pki-certsrv pki-cms pki-cmscore)
+install_jar(pki-ca ${JAVA_JAR_INSTALL_DIR}/pki)
+set(PKI_CA_JAR ${pki-ca_JAR_FILE} CACHE INTERNAL "pki-ca jar file")
+
diff --git a/base/ca/src/com/netscape/ca/CAPolicy.java b/base/ca/src/com/netscape/ca/CAPolicy.java
new file mode 100644
index 000000000..4df28d344
--- /dev/null
+++ b/base/ca/src/com/netscape/ca/CAPolicy.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.ca;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.policy.IPolicyProcessor;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileSubsystem;
+import com.netscape.certsrv.request.IPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.cmscore.policy.GenericPolicyProcessor;
+import com.netscape.cmscore.util.Debug;
+
+/**
+ * XXX Just inherit 'GenericPolicyProcessor' (from RA) for now.
+ * This really bad. need to make a special case just for connector.
+ * would like a much better way of doing this to handle both EE and
+ * connectors.
+ * XXX2 moved to just implement IPolicy since GenericPolicyProcessor is
+ * unuseable for CA.
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class CAPolicy implements IPolicy {
+ IConfigStore mConfig = null;
+ ICertificateAuthority mCA = null;
+
+ public static String PROP_PROCESSOR =
+ "processor";
+ // These are the different types of policy that are
+ // allowed for the "processor" property
+ public static String PR_TYPE_CLASSIC = "classic";
+
+ // XXX this way for now since generic just works for EE.
+ public GenericPolicyProcessor mPolicies = null;
+
+ public CAPolicy() {
+ }
+
+ public IPolicyProcessor getPolicyProcessor() {
+ return mPolicies;
+ }
+
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mCA = (ICertificateAuthority) owner;
+ mConfig = config;
+
+ String processorType = // XXX - need to upgrade 4.2
+ config.getString(PROP_PROCESSOR, PR_TYPE_CLASSIC);
+
+ Debug.trace("selected policy processor = " + processorType);
+ if (processorType.equals(PR_TYPE_CLASSIC)) {
+ mPolicies = new GenericPolicyProcessor();
+ } else {
+ throw new EBaseException("Unknown policy processor type (" +
+ processorType + ")");
+ }
+
+ mPolicies.init(mCA, mConfig);
+ }
+
+ public boolean isProfileRequest(IRequest request) {
+ String profileId = request.getExtDataInString("profileId");
+
+ if (profileId == null || profileId.equals(""))
+ return false;
+ else
+ return true;
+ }
+
+ /**
+ */
+ public PolicyResult apply(IRequest r) {
+ if (r == null) {
+ Debug.trace("in CAPolicy.apply(request=null)");
+ return PolicyResult.REJECTED;
+ }
+
+ Debug.trace("in CAPolicy.apply(requestType=" +
+ r.getRequestType() + ",requestId=" +
+ r.getRequestId().toString() + ",requestStatus=" +
+ r.getRequestStatus().toString() + ")");
+
+ if (isProfileRequest(r)) {
+ Debug.trace("CAPolicy: Profile-base Request " +
+ r.getRequestId().toString());
+
+ CMS.debug("CAPolicy: requestId=" +
+ r.getRequestId().toString());
+
+ String profileId = r.getExtDataInString("profileId");
+
+ if (profileId == null || profileId.equals("")) {
+ return PolicyResult.REJECTED;
+ }
+
+ IProfileSubsystem ps = (IProfileSubsystem)
+ CMS.getSubsystem("profile");
+
+ try {
+ IProfile profile = ps.getProfile(profileId);
+
+ r.setExtData("dbStatus", "NOT_UPDATED");
+ profile.populate(r);
+ profile.validate(r);
+ return PolicyResult.ACCEPTED;
+ } catch (EBaseException e) {
+ CMS.debug("CAPolicy: " + e.toString());
+ return PolicyResult.REJECTED;
+ }
+ }
+ Debug.trace("mPolicies = " + mPolicies.getClass());
+ return mPolicies.apply(r);
+ }
+
+}
diff --git a/base/ca/src/com/netscape/ca/CAService.java b/base/ca/src/com/netscape/ca/CAService.java
new file mode 100644
index 000000000..62bae3b5f
--- /dev/null
+++ b/base/ca/src/com/netscape/ca/CAService.java
@@ -0,0 +1,2122 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.ca;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.Principal;
+import java.security.cert.CRLException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import netscape.security.extensions.CertInfo;
+import netscape.security.util.BigInt;
+import netscape.security.util.DerValue;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.BasicConstraintsExtension;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.CertificateAlgorithmId;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateIssuerName;
+import netscape.security.x509.CertificateSerialNumber;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.Extension;
+import netscape.security.x509.LdapV3DNStrConverter;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.RevocationReason;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.SerialNumber;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X500NameAttrMap;
+import netscape.security.x509.X509CRLImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509ExtensionException;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.MetaInfo;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.ca.ECAException;
+import com.netscape.certsrv.ca.ICAService;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.connector.IConnector;
+import com.netscape.certsrv.dbs.Modification;
+import com.netscape.certsrv.dbs.ModificationSet;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertRecordList;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileSubsystem;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IService;
+import com.netscape.cmscore.base.SubsystemRegistry;
+import com.netscape.cmscore.connector.HttpConnector;
+import com.netscape.cmscore.connector.LocalConnector;
+import com.netscape.cmscore.connector.RemoteAuthority;
+import com.netscape.cmscore.crmf.CRMFParser;
+import com.netscape.cmscore.crmf.PKIArchiveOptionsContainer;
+import com.netscape.cmscore.dbs.CertRecord;
+import com.netscape.cmscore.dbs.CertificateRepository;
+import com.netscape.cmscore.dbs.RevocationInfo;
+import com.netscape.cmscore.util.Debug;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * Request Service for CertificateAuthority.
+ */
+public class CAService implements ICAService, IService {
+
+ public static final String CRMF_REQUEST = "CRMFRequest";
+ public static final String CHALLENGE_PHRASE = "challengePhrase";
+ public static final String SERIALNO_ARRAY = "serialNoArray";
+
+ // CCA->CLA connector
+ protected static IConnector mCLAConnector = null;
+
+ private ICertificateAuthority mCA = null;
+ private Hashtable<String, IServant> mServants = new Hashtable<String, IServant>();
+ private IConnector mKRAConnector = null;
+ private IConfigStore mConfig = null;
+ private boolean mArchivalRequired = true;
+ private Hashtable<String, ICRLIssuingPoint> mCRLIssuingPoints = new Hashtable<String, ICRLIssuingPoint>();
+
+ private ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+ private final static String LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST =
+ "LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST_4";
+
+ public CAService(ICertificateAuthority ca) {
+ mCA = ca;
+
+ // init services.
+ mServants.put(
+ IRequest.ENROLLMENT_REQUEST,
+ new serviceIssue(this));
+ mServants.put(
+ IRequest.RENEWAL_REQUEST,
+ new serviceRenewal(this));
+ mServants.put(
+ IRequest.REVOCATION_REQUEST,
+ new serviceRevoke(this));
+ mServants.put(
+ IRequest.CMCREVOKE_REQUEST,
+ new serviceRevoke(this));
+ mServants.put(
+ IRequest.REVOCATION_CHECK_CHALLENGE_REQUEST,
+ new serviceCheckChallenge(this));
+ mServants.put(
+ IRequest.GETCERTS_FOR_CHALLENGE_REQUEST,
+ new getCertsForChallenge(this));
+ mServants.put(
+ IRequest.UNREVOCATION_REQUEST,
+ new serviceUnrevoke(this));
+ mServants.put(
+ IRequest.GETCACHAIN_REQUEST,
+ new serviceGetCAChain(this));
+ mServants.put(
+ IRequest.GETCRL_REQUEST,
+ new serviceGetCRL(this));
+ mServants.put(
+ IRequest.GETREVOCATIONINFO_REQUEST,
+ new serviceGetRevocationInfo(this));
+ mServants.put(
+ IRequest.GETCERTS_REQUEST,
+ new serviceGetCertificates(this));
+ mServants.put(
+ IRequest.CLA_CERT4CRL_REQUEST,
+ new serviceCert4Crl(this));
+ mServants.put(
+ IRequest.CLA_UNCERT4CRL_REQUEST,
+ new serviceUnCert4Crl(this));
+ mServants.put(
+ IRequest.GETCERT_STATUS_REQUEST,
+ new getCertStatus(this));
+ }
+
+ public void init(IConfigStore config) throws EBaseException {
+ mConfig = config;
+
+ try {
+ // MOVED TO com.netscape.certsrv.apps.CMS
+ // java.security.Security.addProvider(new netscape.security.provider.CMS());
+ // java.security.Provider pr = java.security.Security.getProvider("CMS");
+ // if (pr != null) {
+ // ;
+ // }
+ // else
+ // Debug.trace("Something is wrong in CMS install !");
+ java.security.cert.CertificateFactory cf = java.security.cert.CertificateFactory.getInstance("X.509");
+
+ Debug.trace("CertificateFactory Type : " + cf.getType());
+ Debug.trace("CertificateFactory Provider : " + cf.getProvider().getInfo());
+ } catch (java.security.cert.CertificateException e) {
+ Debug.trace("Something is happen in install CMS provider !" + e.toString());
+ }
+ }
+
+ public void startup() throws EBaseException {
+ IConfigStore kraConfig = mConfig.getSubStore("KRA");
+
+ if (kraConfig != null) {
+ mArchivalRequired = kraConfig.getBoolean(
+ "archivalRequired", true);
+ mKRAConnector = getConnector(kraConfig);
+ if (mKRAConnector != null) {
+ if (Debug.ON) {
+ Debug.trace("Started KRA Connector");
+ }
+ mKRAConnector.start();
+ }
+ }
+
+ // clone ca to CLA (clone master) connector
+ IConfigStore claConfig = mConfig.getSubStore("CLA");
+
+ if (claConfig != null) {
+ mCLAConnector = getConnector(claConfig);
+ if (mCLAConnector != null) {
+ CMS.debug(CMS.getLogMessage("CMSCORE_CA_START_CONNECTOR"));
+ if (Debug.ON) {
+ Debug.trace("Started CLA Connector in CCA");
+ }
+ mCLAConnector.start();
+ }
+ }
+ }
+
+ protected ICertificateAuthority getCA() {
+ return mCA;
+ }
+
+ public IConnector getKRAConnector() {
+ return mKRAConnector;
+ }
+
+ public void setKRAConnector(IConnector c) {
+ mKRAConnector = c;
+ }
+
+ public IConnector getConnector(IConfigStore config)
+ throws EBaseException {
+ IConnector connector = null;
+
+ if (config == null || config.size() <= 0) {
+ return null;
+ }
+ boolean enable = config.getBoolean("enable", true);
+ // provide a way to register a 3rd connector into RA
+ String extConnector = config.getString("class", null);
+
+ if (extConnector != null) {
+ try {
+ connector = (IConnector)
+ Class.forName(extConnector).newInstance();
+ // connector.start() will be called later on
+ return connector;
+ } catch (Exception e) {
+ // ignore external class if error
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_LOAD_CONNECTOR", extConnector, e.toString()));
+ }
+ }
+
+ if (!enable)
+ return null;
+ boolean local = config.getBoolean("local");
+ IAuthority authority = null;
+
+ if (local) {
+ String id = config.getString("id");
+
+ authority = (IAuthority) SubsystemRegistry.getInstance().get(id);
+ if (authority == null) {
+ String msg = "local authority " + id + " not found.";
+
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_AUTHORITY_NOT_FOUND", id));
+ throw new EBaseException(msg);
+ }
+ connector = new LocalConnector((ICertAuthority) mCA, authority);
+ // log(ILogger.LL_INFO, "local Connector to "+id+" inited");
+ } else {
+ String host = config.getString("host");
+ int port = config.getInteger("port");
+ String uri = config.getString("uri");
+ String nickname = config.getString("nickName", null);
+ int resendInterval = config.getInteger("resendInterval", -1);
+ // Inserted by beomsuk
+ int timeout = config.getInteger("timeout", 0);
+ // Insert end
+ // Changed by beomsuk
+ //RemoteAuthority remauthority =
+ // new RemoteAuthority(host, port, uri);
+ RemoteAuthority remauthority =
+ new RemoteAuthority(host, port, uri, timeout);
+
+ // Change end
+ if (nickname == null)
+ nickname = mCA.getNickname();
+ // Changed by beomsuk
+ //connector =
+ // new HttpConnector(mCA, nickname, remauthority, resendInterval);
+ if (timeout == 0)
+ connector = new HttpConnector((IAuthority) mCA, nickname, remauthority, resendInterval, config);
+ else
+ connector =
+ new HttpConnector((IAuthority) mCA, nickname, remauthority, resendInterval, config, timeout);
+ // Change end
+
+ // log(ILogger.LL_INFO, "remote authority "+
+ // host+":"+port+" "+uri+" inited");
+ }
+ return connector;
+ }
+
+ public boolean isProfileRequest(IRequest request) {
+ String profileId = request.getExtDataInString("profileId");
+
+ if (profileId == null || profileId.equals(""))
+ return false;
+ else
+ return true;
+ }
+
+ /**
+ * After population of defaults, and constraint validation,
+ * the profile request is processed here.
+ */
+ public void serviceProfileRequest(IRequest request)
+ throws EBaseException {
+ CMS.debug("CAService: serviceProfileRequest requestId=" +
+ request.getRequestId().toString());
+
+ String profileId = request.getExtDataInString("profileId");
+
+ if (profileId == null || profileId.equals("")) {
+ throw new EBaseException("profileId not found");
+ }
+
+ IProfileSubsystem ps = (IProfileSubsystem)
+ CMS.getSubsystem("profile");
+ IProfile profile = null;
+
+ try {
+ profile = ps.getProfile(profileId);
+ } catch (EProfileException e) {
+ }
+ if (profile == null) {
+ throw new EProfileException("Profile not found " + profileId);
+ }
+
+ // assumed rejected
+ request.setExtData("dbStatus", "NOT_UPDATED");
+
+ // profile.populate(request);
+ profile.validate(request);
+ profile.execute(request);
+
+ // This function is called only from ConnectorServlet
+
+ // serialize to request queue
+ }
+
+ /**
+ * method interface for IService
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST used whenever a user private key archive
+ * request is made. This is an option in a cert enrollment request detected by an RA or a CA, so, if selected, it
+ * should be logged immediately following the certificate request.
+ * </ul>
+ *
+ * @param request a certificate enrollment request from an RA or CA
+ * @return true or false
+ */
+ public boolean serviceRequest(IRequest request) {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = auditRequesterID();
+ String auditArchiveID = ILogger.SIGNED_AUDIT_NON_APPLICABLE;
+
+ boolean completed = false;
+
+ // short cut profile-based request
+ if (isProfileRequest(request)) {
+ try {
+ CMS.debug("CAServic: x0 requestStatus="
+ + request.getRequestStatus().toString() + " instance=" + request);
+ serviceProfileRequest(request);
+ request.setExtData(IRequest.RESULT, IRequest.RES_SUCCESS);
+ CMS.debug("CAServic: x1 requestStatus=" + request.getRequestStatus().toString());
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+
+ return true;
+ } catch (EBaseException e) {
+ CMS.debug("CAServic: x2 requestStatus=" + request.getRequestStatus().toString());
+ // need to put error into the request
+ CMS.debug("CAService: serviceRequest " + e.toString());
+ request.setExtData(IRequest.RESULT, IRequest.RES_ERROR);
+ request.setExtData(IRequest.ERROR, e.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+
+ return false;
+ }
+ }
+
+ String type = request.getRequestType();
+ IServant servant = mServants.get(type);
+
+ if (servant == null) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_INVALID_REQUEST_TYPE", type));
+ request.setExtData(IRequest.RESULT, IRequest.RES_ERROR);
+ request.setExtData(IRequest.ERROR,
+ new ECAException(CMS.getUserMessage("CMS_CA_UNRECOGNIZED_REQUEST_TYPE", type)));
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+
+ return true;
+ }
+
+ try {
+ // send request to KRA first
+ if (type.equals(IRequest.ENROLLMENT_REQUEST) &&
+ isPKIArchiveOptionPresent(request) && mKRAConnector != null) {
+ if (Debug.ON) {
+ Debug.trace("*** Sending enrollment request to KRA");
+ }
+ boolean sendStatus = mKRAConnector.send(request);
+
+ if (mArchivalRequired == true) {
+ if (sendStatus == false) {
+ request.setExtData(IRequest.RESULT,
+ IRequest.RES_ERROR);
+ request.setExtData(IRequest.ERROR,
+ new ECAException(CMS.getUserMessage("CMS_CA_SEND_KRA_REQUEST")));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+
+ return true;
+ } else {
+ if (request.getExtDataInString(IRequest.ERROR) != null) {
+ request.setExtData(IRequest.RESULT, IRequest.RES_SUCCESS);
+ request.deleteExtData(IRequest.ERROR);
+ }
+ }
+ if (request.getExtDataInString(IRequest.ERROR) != null) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+
+ return true;
+ }
+ }
+ } else {
+ if (Debug.ON) {
+ Debug.trace("*** NOT Send to KRA type=" + type + " ENROLLMENT=" + IRequest.ENROLLMENT_REQUEST);
+ }
+ }
+
+ completed = servant.service(request);
+ request.setExtData(IRequest.RESULT, IRequest.RES_SUCCESS);
+ } catch (EBaseException e) {
+ request.setExtData(IRequest.RESULT, IRequest.RES_ERROR);
+ request.setExtData(IRequest.ERROR, e);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+
+ return true;
+ }
+
+ // XXX in case of key archival this may not always be the case.
+ if (Debug.ON)
+ Debug.trace("serviceRequest completed = " + completed);
+
+ if (!(type.equals(IRequest.REVOCATION_REQUEST) ||
+ type.equals(IRequest.UNREVOCATION_REQUEST) || type.equals(IRequest.CMCREVOKE_REQUEST))) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+ }
+
+ return completed;
+ }
+
+ /**
+ * register CRL Issuing Point
+ */
+ public void addCRLIssuingPoint(String id, ICRLIssuingPoint crlIssuingPoint) {
+ mCRLIssuingPoints.put(id, crlIssuingPoint);
+ }
+
+ /**
+ * get CRL Issuing Point
+ */
+ public Hashtable<String, ICRLIssuingPoint> getCRLIssuingPoints() {
+ return mCRLIssuingPoints;
+ }
+
+ /**
+ * Checks if PKIArchiveOption present in the request.
+ */
+ private boolean isPKIArchiveOptionPresent(IRequest request) {
+ String crmfBlob = request.getExtDataInString(
+ IRequest.HTTP_PARAMS, CRMF_REQUEST);
+
+ if (crmfBlob == null) {
+ if (Debug.ON) {
+ Debug.trace("CRMF not found");
+ }
+ } else {
+ try {
+ PKIArchiveOptionsContainer opts[] = CRMFParser.getPKIArchiveOptions(crmfBlob);
+
+ if (opts != null) {
+ return true;
+ }
+ } catch (IOException e) {
+ }
+ return false;
+ }
+ return false;
+ }
+
+ ///
+ /// CA related routines.
+ ///
+
+ public X509CertImpl issueX509Cert(X509CertInfo certi)
+ throws EBaseException {
+ return issueX509Cert(certi, null, null);
+ }
+
+ /**
+ * issue cert for enrollment.
+ */
+ public X509CertImpl issueX509Cert(X509CertInfo certi, String profileId, String rid)
+ throws EBaseException {
+ CMS.debug("issueX509Cert");
+ X509CertImpl certImpl = issueX509Cert("", certi, false, null);
+
+ CMS.debug("storeX509Cert " + certImpl.getSerialNumber());
+ storeX509Cert(profileId, rid, certImpl);
+ CMS.debug("done storeX509Cert");
+ return certImpl;
+ }
+
+ X509CertImpl issueX509Cert(String rid, X509CertInfo certi)
+ throws EBaseException {
+ return issueX509Cert(rid, certi, false, null);
+ }
+
+ /**
+ * issue cert for enrollment.
+ */
+ void storeX509Cert(String profileId, String rid, X509CertImpl cert)
+ throws EBaseException {
+ storeX509Cert(rid, cert, false, null, null, null, profileId);
+ }
+
+ /**
+ * issue cert for enrollment.
+ */
+ void storeX509Cert(String rid, X509CertImpl cert, String crmfReqId)
+ throws EBaseException {
+ storeX509Cert(rid, cert, false, null, crmfReqId, null, null);
+ }
+
+ void storeX509Cert(String rid, X509CertImpl cert, String crmfReqId,
+ String challengePassword) throws EBaseException {
+ storeX509Cert(rid, cert, false, null, crmfReqId, challengePassword, null);
+ }
+
+ /**
+ * issue cert for enrollment and renewal.
+ * renewal is expected to have original cert serial no. in cert info
+ * field.
+ */
+ X509CertImpl issueX509Cert(String rid, X509CertInfo certi,
+ boolean renewal, BigInteger oldSerialNo)
+ throws EBaseException {
+ String algname = null;
+ X509CertImpl cert = null;
+
+ // NOTE: In this implementation, the "oldSerialNo"
+ // parameter is NOT used!
+
+ boolean doUTF8 = mConfig.getBoolean("dnUTF8Encoding", false);
+
+ CMS.debug("dnUTF8Encoding " + doUTF8);
+
+ try {
+ // check required fields in certinfo.
+ if (certi.get(X509CertInfo.SUBJECT) == null ||
+ certi.get(X509CertInfo.KEY) == null) {
+
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_MISSING_ATTR"));
+ // XXX how do you reject a request in the service object ?
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_MISSING_REQD_FIELDS_IN_CERTISSUE"));
+ }
+
+ // set default cert version. If policies added a extensions
+ // the version would already be set to version 3.
+ if (certi.get(X509CertInfo.VERSION) == null) {
+ certi.set(X509CertInfo.VERSION, mCA.getDefaultCertVersion());
+ }
+
+ // set default validity if not set.
+ // validity would normally be set by policies or by
+ // agent or by authentication module.
+ CertificateValidity validity = (CertificateValidity)
+ certi.get(X509CertInfo.VALIDITY);
+ Date begin = null, end = null;
+
+ if (validity != null) {
+ begin = (Date)
+ validity.get(CertificateValidity.NOT_BEFORE);
+ end = (Date)
+ validity.get(CertificateValidity.NOT_AFTER);
+ }
+ if (validity == null ||
+ (begin.getTime() == 0 && end.getTime() == 0)) {
+ if (Debug.ON) {
+ Debug.trace("setting default validity");
+ }
+
+ begin = CMS.getCurrentDate();
+ end = new Date(begin.getTime() + mCA.getDefaultValidity());
+ certi.set(CertificateValidity.NAME,
+ new CertificateValidity(begin, end));
+ }
+
+ /*
+ * For non-CA certs, check if validity exceeds CA time.
+ * If so, set to CA's not after if default validity
+ * exceeds ca's not after.
+ */
+
+ // First find out if it is a CA cert
+ boolean is_ca = false;
+ CertificateExtensions exts = null;
+ BasicConstraintsExtension bc_ext = null;
+
+ try {
+ exts = (CertificateExtensions)
+ certi.get(X509CertInfo.EXTENSIONS);
+ if (exts != null) {
+ Enumeration<Extension> e = exts.getAttributes();
+
+ while (e.hasMoreElements()) {
+ netscape.security.x509.Extension ext = (netscape.security.x509.Extension) e.nextElement();
+
+ if (ext.getExtensionId().toString().equals(PKIXExtensions.BasicConstraints_Id.toString())) {
+ bc_ext = (BasicConstraintsExtension) ext;
+ }
+ }
+
+ if (bc_ext != null) {
+ Boolean isCA = (Boolean) bc_ext.get(BasicConstraintsExtension.IS_CA);
+ is_ca = isCA.booleanValue();
+ }
+ } // exts != null
+ } catch (Exception e) {
+ CMS.debug("EnrollDefault: getExtension " + e.toString());
+ }
+
+ Date caNotAfter =
+ mCA.getSigningUnit().getCertImpl().getNotAfter();
+
+ if (begin.after(caNotAfter)) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_PAST_VALIDITY"));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_CERT_BEGIN_AFTER_CA_VALIDITY"));
+ }
+
+ if (end.after(caNotAfter)) {
+ if (!is_ca) {
+ if (!mCA.isEnablePastCATime()) {
+ end = caNotAfter;
+ certi.set(CertificateValidity.NAME,
+ new CertificateValidity(begin, caNotAfter));
+ CMS.debug("CAService: issueX509Cert: cert past CA's NOT_AFTER...ca.enablePastCATime != true...resetting");
+ } else {
+ CMS.debug("CAService: issueX509Cert: cert past CA's NOT_AFTER...ca.enablePastCATime = true...not resetting");
+ }
+ } else {
+ CMS.debug("CAService: issueX509Cert: CA cert issuance past CA's NOT_AFTER.");
+ } //!is_ca
+ mCA.log(ILogger.LL_INFO, CMS.getLogMessage("CMSCORE_CA_PAST_NOT_AFTER"));
+ }
+
+ // check algorithm in certinfo.
+ AlgorithmId algid = null;
+ CertificateAlgorithmId algor = (CertificateAlgorithmId)
+ certi.get(X509CertInfo.ALGORITHM_ID);
+
+ if (algor == null || algor.toString().equals(CertInfo.SERIALIZE_ALGOR.toString())) {
+ algname = mCA.getSigningUnit().getDefaultAlgorithm();
+ algid = AlgorithmId.get(algname);
+ certi.set(X509CertInfo.ALGORITHM_ID,
+ new CertificateAlgorithmId(algid));
+ } else {
+ algid = (AlgorithmId)
+ algor.get(CertificateAlgorithmId.ALGORITHM);
+ algname = algid.getName();
+ }
+ } catch (CertificateException e) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_BAD_FIELD", e.toString()));
+ if (Debug.ON) {
+ e.printStackTrace();
+ }
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_ERROR_GETTING_FIELDS_IN_ISSUE"));
+ } catch (IOException e) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_BAD_FIELD", e.toString()));
+ if (Debug.ON) {
+ e.printStackTrace();
+ }
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_ERROR_GETTING_FIELDS_IN_ISSUE"));
+ } catch (NoSuchAlgorithmException e) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_SIGNING_ALG_NOT_SUPPORTED", algname));
+ if (Debug.ON) {
+ e.printStackTrace();
+ }
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_SIGNING_ALGOR_NOT_SUPPORTED", algname));
+ }
+
+ // get old cert serial number if renewal
+ if (renewal) {
+ try {
+ CertificateSerialNumber serialno = (CertificateSerialNumber)
+ certi.get(X509CertInfo.SERIAL_NUMBER);
+
+ if (serialno == null) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_NULL_SERIAL_NUMBER"));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_MISSING_INFO_IN_RENEWREQ"));
+ }
+ SerialNumber serialnum = (SerialNumber)
+ serialno.get(CertificateSerialNumber.NUMBER);
+
+ if (serialnum == null) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_NULL_SERIAL_NUMBER"));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_MISSING_INFO_IN_RENEWREQ"));
+ }
+ } catch (CertificateException e) {
+ // not possible
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_NO_ORG_SERIAL", e.getMessage()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_MISSING_INFO_IN_RENEWREQ"));
+ } catch (IOException e) {
+ // not possible.
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_NO_ORG_SERIAL", e.getMessage()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_MISSING_INFO_IN_RENEWREQ"));
+ }
+ }
+
+ // set issuer, serial number
+ try {
+ BigInteger serialNo =
+ mCA.getCertificateRepository().getNextSerialNumber();
+
+ certi.set(X509CertInfo.SERIAL_NUMBER,
+ new CertificateSerialNumber(serialNo));
+ mCA.log(ILogger.LL_INFO, CMS.getLogMessage("CMSCORE_CA_SIGN_SERIAL", serialNo.toString(16)));
+ } catch (EBaseException e) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_NO_NEXT_SERIAL", e.toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_NOSERIALNO", rid));
+ } catch (CertificateException e) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_SET_SERIAL", e.toString()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_SET_SERIALNO_FAILED", rid));
+ } catch (IOException e) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_SET_SERIAL", e.toString()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_SET_SERIALNO_FAILED", rid));
+ }
+
+ try {
+ certi.set(X509CertInfo.ISSUER,
+ new CertificateIssuerName(mCA.getX500Name()));
+ } catch (CertificateException e) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_SET_ISSUER", e.toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_SET_ISSUER_FAILED", rid));
+ } catch (IOException e) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_SET_ISSUER", e.toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_SET_ISSUER_FAILED", rid));
+ }
+
+ byte[] utf8_encodingOrder = { DerValue.tag_UTF8String };
+
+ if (doUTF8 == true) {
+ try {
+
+ CMS.debug("doUTF8 true, updating subject.");
+
+ String subject = certi.get(X509CertInfo.SUBJECT).toString();
+
+ certi.set(X509CertInfo.SUBJECT, new CertificateSubjectName(
+ new X500Name(subject,
+ new LdapV3DNStrConverter(X500NameAttrMap.getDirDefault(), true), utf8_encodingOrder)));
+
+ } catch (CertificateException e) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_SET_SUBJECT", e.toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_SET_ISSUER_FAILED", rid));
+ } catch (IOException e) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_SET_SUBJECT", e.toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_SET_ISSUER_FAILED", rid));
+ }
+ }
+
+ CMS.debug("About to mCA.sign cert.");
+ cert = mCA.sign(certi, algname);
+ return cert;
+ }
+
+ void storeX509Cert(String rid, X509CertImpl cert,
+ boolean renewal, BigInteger oldSerialNo)
+ throws EBaseException {
+ storeX509Cert(rid, cert, renewal, oldSerialNo, null, null, null);
+ }
+
+ void storeX509Cert(String rid, X509CertImpl cert,
+ boolean renewal, BigInteger oldSerialNo, String crmfReqId,
+ String challengePassword, String profileId) throws EBaseException {
+ // now store in repository.
+ // if renewal, set the old serial number in the new cert,
+ // set the new serial number in the old cert.
+
+ CMS.debug("In storeX509Cert");
+ try {
+ BigInteger newSerialNo = cert.getSerialNumber();
+ MetaInfo metaInfo = new MetaInfo();
+
+ if (profileId != null)
+ metaInfo.set("profileId", profileId);
+ if (rid != null)
+ metaInfo.set(CertRecord.META_REQUEST_ID, rid);
+ if (challengePassword != null && !challengePassword.equals(""))
+ metaInfo.set("challengePhrase", challengePassword);
+ if (crmfReqId != null) {
+ //System.out.println("Adding crmf reqid "+crmfReqId);
+ metaInfo.set(CertRecord.META_CRMF_REQID, crmfReqId);
+ }
+ if (renewal)
+ metaInfo.set(CertRecord.META_OLD_CERT, oldSerialNo.toString());
+ mCA.getCertificateRepository().addCertificateRecord(
+ new CertRecord(newSerialNo, cert, metaInfo));
+
+ mCA.log(ILogger.LL_INFO, CMS.getLogMessage("CMSCORE_CA_STORE_SERIAL", cert.getSerialNumber().toString(16)));
+ if (renewal) {
+
+ /*
+ mCA.getCertificateRepository().markCertificateAsRenewed(
+ BigIntegerMapper.BigIntegerToDB(oldSerialNo));
+ mCA.mCertRepot.markCertificateAsRenewed(oldSerialNo);
+ */
+ MetaInfo oldMeta = null;
+ CertRecord oldCertRec = (CertRecord)
+ mCA.getCertificateRepository().readCertificateRecord(oldSerialNo);
+
+ if (oldCertRec == null) {
+ Exception e =
+ new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Cannot read cert record for " + oldSerialNo));
+
+ e.printStackTrace();
+ }
+ if (oldCertRec != null)
+ oldMeta = oldCertRec.getMetaInfo();
+ if (oldMeta == null) {
+ if (Debug.ON) {
+ Debug.trace("No meta info! for " + oldSerialNo);
+ }
+ oldMeta = new MetaInfo();
+ } else {
+ if (Debug.ON) {
+ System.out.println("Old meta info");
+ Enumeration<String> n = oldMeta.getElements();
+
+ while (n.hasMoreElements()) {
+ String name = n.nextElement();
+
+ System.out.println("name " + name + " value " +
+ oldMeta.get(name));
+ }
+ }
+ }
+ oldMeta.set(CertRecord.META_RENEWED_CERT,
+ newSerialNo.toString());
+ ModificationSet modSet = new ModificationSet();
+
+ modSet.add(CertRecord.ATTR_AUTO_RENEW,
+ Modification.MOD_REPLACE,
+ CertRecord.AUTO_RENEWAL_DONE);
+ modSet.add(ICertRecord.ATTR_META_INFO,
+ Modification.MOD_REPLACE, oldMeta);
+ mCA.getCertificateRepository().modifyCertificateRecord(oldSerialNo, modSet);
+ mCA.log(ILogger.LL_INFO,
+ CMS.getLogMessage("CMSCORE_CA_MARK_SERIAL", oldSerialNo.toString(16), newSerialNo.toString(16)));
+ if (Debug.ON) {
+ CertRecord check = (CertRecord)
+ mCA.getCertificateRepository().readCertificateRecord(oldSerialNo);
+ MetaInfo meta = check.getMetaInfo();
+
+ Enumeration<String> n = oldMeta.getElements();
+
+ while (n.hasMoreElements()) {
+ String name = n.nextElement();
+
+ }
+ }
+ }
+ } catch (EBaseException e) {
+ mCA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_NO_STORE_SERIAL", cert.getSerialNumber().toString(16)));
+ if (Debug.ON)
+ e.printStackTrace();
+ throw e;
+ }
+ }
+
+ /**
+ * revoke cert, check fields in crlentry, etc.
+ */
+ public void revokeCert(RevokedCertImpl crlentry)
+ throws EBaseException {
+ revokeCert(crlentry, null);
+ }
+
+ public void revokeCert(RevokedCertImpl crlentry, String requestId)
+ throws EBaseException {
+ BigInteger serialno = crlentry.getSerialNumber();
+ Date revdate = crlentry.getRevocationDate();
+ CRLExtensions crlentryexts = crlentry.getExtensions();
+
+ CertRecord certRec = (CertRecord) mCA.getCertificateRepository().readCertificateRecord(serialno);
+
+ if (certRec == null) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CERT_NOT_FOUND", serialno.toString(16)));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_CANT_FIND_CERT_SERIAL",
+ "0x" + serialno.toString(16)));
+ }
+
+ // allow revoking certs that are on hold.
+ String certStatus = certRec.getStatus();
+
+ if (certStatus.equals(ICertRecord.STATUS_REVOKED) ||
+ certStatus.equals(ICertRecord.STATUS_REVOKED_EXPIRED)) {
+ throw new ECAException(CMS.getUserMessage("CMS_CA_CERT_ALREADY_REVOKED",
+ "0x" + Long.toHexString(serialno.longValue())));
+ }
+ try {
+ mCA.getCertificateRepository().markAsRevoked(serialno,
+ new RevocationInfo(revdate, crlentryexts));
+ mCA.log(ILogger.LL_INFO, CMS.getLogMessage("CMSCORE_CA_CERT_REVOKED",
+ serialno.toString(16)));
+ // inform all CRLIssuingPoints about revoked certificate
+ Enumeration<ICRLIssuingPoint> eIPs = mCRLIssuingPoints.elements();
+
+ while (eIPs.hasMoreElements()) {
+ ICRLIssuingPoint ip = (ICRLIssuingPoint) eIPs.nextElement();
+
+ if (ip != null) {
+ boolean b = true;
+
+ if (ip.isCACertsOnly()) {
+ X509CertImpl cert = certRec.getCertificate();
+
+ if (cert != null)
+ b = cert.getBasicConstraintsIsCA();
+ }
+ if (ip.isProfileCertsOnly()) {
+ MetaInfo metaInfo = certRec.getMetaInfo();
+ if (metaInfo != null) {
+ String profileId = (String) metaInfo.get("profileId");
+ if (profileId != null) {
+ b = ip.checkCurrentProfile(profileId);
+ }
+ }
+ }
+ if (b)
+ ip.addRevokedCert(serialno, crlentry, requestId);
+ }
+ }
+ } catch (EBaseException e) {
+ mCA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_ERROR_REVOCATION", serialno.toString(), e.toString()));
+ //e.printStackTrace();
+ throw e;
+ }
+ return;
+ }
+
+ /**
+ * unrevoke cert, check serial number, etc.
+ */
+ void unrevokeCert(BigInteger serialNo)
+ throws EBaseException {
+ unrevokeCert(serialNo, null);
+ }
+
+ void unrevokeCert(BigInteger serialNo, String requestId)
+ throws EBaseException {
+ CertRecord certRec = (CertRecord) mCA.getCertificateRepository().readCertificateRecord(serialNo);
+
+ if (certRec == null) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CERT_NOT_FOUND", serialNo.toString(16)));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_CANT_FIND_CERT_SERIAL",
+ "0x" + serialNo.toString(16)));
+ }
+ RevocationInfo revInfo = (RevocationInfo) certRec.getRevocationInfo();
+ CRLExtensions exts = null;
+ CRLReasonExtension reasonext = null;
+
+ if (revInfo == null) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CERT_ON_HOLD", serialNo.toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_IS_NOT_ON_HOLD",
+ serialNo.toString()));
+ }
+ exts = revInfo.getCRLEntryExtensions();
+ if (exts != null) {
+ try {
+ reasonext = (CRLReasonExtension)
+ exts.get(CRLReasonExtension.NAME);
+ } catch (X509ExtensionException e) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CERT_ON_HOLD", serialNo.toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_IS_NOT_ON_HOLD",
+ serialNo.toString()));
+ }
+ } else {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CERT_ON_HOLD", serialNo.toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_IS_NOT_ON_HOLD",
+ serialNo.toString()));
+ }
+ // allow unrevoking certs that are on hold.
+ if ((certRec.getStatus().equals(ICertRecord.STATUS_REVOKED) ||
+ certRec.getStatus().equals(ICertRecord.STATUS_REVOKED_EXPIRED)) &&
+ reasonext != null &&
+ reasonext.getReason() == RevocationReason.CERTIFICATE_HOLD) {
+ try {
+ mCA.getCertificateRepository().unmarkRevoked(serialNo, revInfo,
+ certRec.getRevokedOn(), certRec.getRevokedBy());
+ mCA.log(ILogger.LL_INFO, CMS.getLogMessage("CMSCORE_CA_CERT_UNREVOKED", serialNo.toString(16)));
+ // inform all CRLIssuingPoints about unrevoked certificate
+ Enumeration<ICRLIssuingPoint> eIPs = mCRLIssuingPoints.elements();
+
+ while (eIPs.hasMoreElements()) {
+ ICRLIssuingPoint ip = eIPs.nextElement();
+
+ if (ip != null) {
+ boolean b = true;
+
+ if (ip.isCACertsOnly()) {
+ X509CertImpl cert = certRec.getCertificate();
+
+ if (cert != null)
+ b = cert.getBasicConstraintsIsCA();
+ }
+ if (ip.isProfileCertsOnly()) {
+ MetaInfo metaInfo = certRec.getMetaInfo();
+ if (metaInfo != null) {
+ String profileId = (String) metaInfo.get("profileId");
+ if (profileId != null) {
+ b = ip.checkCurrentProfile(profileId);
+ }
+ }
+ }
+ if (b)
+ ip.addUnrevokedCert(serialNo, requestId);
+ }
+ }
+ } catch (EBaseException e) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CERT_ERROR_UNREVOKE", serialNo.toString(16)));
+ throw e;
+ }
+ } else {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CERT_ON_HOLD", serialNo.toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_IS_NOT_ON_HOLD",
+ "0x" + serialNo.toString(16)));
+ }
+
+ return;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Signed Audit Log Requester ID
+ *
+ * This method is called to obtain the "RequesterID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditRequesterID() {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requesterID = null;
+
+ // Initialize requesterID
+ SessionContext auditContext = SessionContext.getExistingContext();
+
+ if (auditContext != null) {
+ requesterID = (String)
+ auditContext.get(SessionContext.REQUESTER_ID);
+
+ if (requesterID != null) {
+ requesterID = requesterID.trim();
+ } else {
+ requesterID = ILogger.UNIDENTIFIED;
+ }
+ } else {
+ requesterID = ILogger.UNIDENTIFIED;
+ }
+
+ return requesterID;
+ }
+}
+
+///
+/// servant classes
+///
+
+interface IServant {
+ public boolean service(IRequest request) throws EBaseException;
+}
+
+class serviceIssue implements IServant {
+ private ICertificateAuthority mCA;
+ private CAService mService;
+
+ public serviceIssue(CAService service) {
+ mService = service;
+ mCA = mService.getCA();
+ }
+
+ public boolean service(IRequest request)
+ throws EBaseException {
+ // XXX This is ugly. should associate attributes with
+ // request types, not policy.
+ // XXX how do we know what to look for in request ?
+
+ if (request.getExtDataInCertInfoArray(IRequest.CERT_INFO) != null)
+ return serviceX509(request);
+ else
+ return false; // Don't know what it is ?????
+ }
+
+ public boolean serviceX509(IRequest request)
+ throws EBaseException {
+ // XXX This is ugly. should associate attributes with
+ // request types, not policy.
+ // XXX how do we know what to look for in request ?
+ X509CertInfo certinfos[] =
+ request.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (certinfos == null || certinfos[0] == null) {
+ mCA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CERT_REQUEST_NOT_FOUND", request.getRequestId().toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_MISSING_INFO_IN_ISSUEREQ"));
+ }
+ String challengePassword =
+ request.getExtDataInString(CAService.CHALLENGE_PHRASE);
+
+ X509CertImpl[] certs = new X509CertImpl[certinfos.length];
+ String rid = request.getRequestId().toString();
+ int i;
+
+ for (i = 0; i < certinfos.length; i++) {
+ try {
+ certs[i] = mService.issueX509Cert(rid, certinfos[i]);
+ } catch (EBaseException e) {
+ mCA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_ISSUE_ERROR", Integer.toString(i), rid, e.toString()));
+ throw e;
+ }
+ }
+ String crmfReqId = request.getExtDataInString(IRequest.CRMF_REQID);
+ EBaseException ex = null;
+
+ for (i = 0; i < certs.length; i++) {
+ try {
+ mService.storeX509Cert(rid, certs[i], crmfReqId, challengePassword);
+ } catch (EBaseException e) {
+ e.printStackTrace();
+ mCA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_STORE_ERROR", Integer.toString(i), rid, e.toString()));
+ ex = e; // save to throw later.
+ break;
+ }
+ }
+ if (ex != null) {
+ for (int j = 0; j < i; j++) {
+ // delete the stored cert records from the database.
+ // we issue all or nothing.
+ BigInteger serialNo =
+ ((X509Certificate) certs[i]).getSerialNumber();
+
+ try {
+ mCA.getCertificateRepository().deleteCertificateRecord(serialNo);
+ } catch (EBaseException e) {
+ mCA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_DELETE_CERT_ERROR", serialNo.toString(), e.toString()));
+ }
+ }
+ throw ex;
+ }
+
+ request.setExtData(IRequest.ISSUED_CERTS, certs);
+
+ return true;
+ }
+}
+
+class serviceRenewal implements IServant {
+ private ICertificateAuthority mCA;
+ private CAService mService;
+
+ public serviceRenewal(CAService service) {
+ mService = service;
+ mCA = mService.getCA();
+ }
+
+ public boolean service(IRequest request)
+ throws EBaseException {
+ // XXX if one fails should all fail ? - can't backtrack.
+ X509CertInfo certinfos[] =
+ request.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (certinfos == null || certinfos[0] == null) {
+ mCA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CERT_REQUEST_NOT_FOUND", request.getRequestId().toString()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_MISSING_INFO_IN_RENEWREQ"));
+ }
+ X509CertImpl issuedCerts[] = new X509CertImpl[certinfos.length];
+
+ for (int j = 0; j < issuedCerts.length; j++)
+ issuedCerts[j] = null;
+ String svcerrors[] = new String[certinfos.length];
+
+ for (int k = 0; k < svcerrors.length; k++)
+ svcerrors[k] = null;
+ String rid = request.getRequestId().toString();
+
+ for (int i = 0; i < certinfos.length; i++) {
+ try {
+ // get old serial number.
+ SerialNumber serialnum = null;
+
+ try {
+ CertificateSerialNumber serialno = (CertificateSerialNumber)
+ certinfos[i].get(X509CertInfo.SERIAL_NUMBER);
+
+ if (serialno == null) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_NULL_SERIAL_NUMBER"));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_MISSING_INFO_IN_RENEWREQ"));
+ }
+ serialnum = (SerialNumber)
+ serialno.get(CertificateSerialNumber.NUMBER);
+ } catch (IOException e) {
+ if (Debug.ON)
+ e.printStackTrace();
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ERROR_GET_CERT", e.toString()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_MISSING_INFO_IN_RENEWREQ"));
+ } catch (CertificateException e) {
+ if (Debug.ON)
+ e.printStackTrace();
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ERROR_GET_CERT", e.toString()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_MISSING_INFO_IN_RENEWREQ"));
+ }
+ if (serialnum == null) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ERROR_GET_CERT", ""));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_MISSING_INFO_IN_RENEWREQ"));
+ }
+ BigInt serialnumBigInt = serialnum.getNumber();
+ BigInteger oldSerialNo = serialnumBigInt.toBigInteger();
+
+ // get cert record
+ CertRecord certRecord = (CertRecord)
+ mCA.getCertificateRepository().readCertificateRecord(oldSerialNo);
+
+ if (certRecord == null) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_NOT_FROM_CA", oldSerialNo.toString()));
+ svcerrors[i] = new ECAException(
+ CMS.getUserMessage("CMS_CA_CANT_FIND_CERT_SERIAL",
+ oldSerialNo.toString())).toString();
+ continue;
+ }
+
+ // check if cert has been revoked.
+ String certStatus = certRecord.getStatus();
+
+ if (certStatus.equals(ICertRecord.STATUS_REVOKED) ||
+ certStatus.equals(ICertRecord.STATUS_REVOKED_EXPIRED)) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_RENEW_REVOKED", oldSerialNo.toString()));
+ svcerrors[i] = new ECAException(
+ CMS.getUserMessage("CMS_CA_CANNOT_RENEW_REVOKED_CERT",
+ "0x" + oldSerialNo.toString(16))).toString();
+ continue;
+ }
+
+ // check if cert has already been renewed.
+ MetaInfo metaInfo = certRecord.getMetaInfo();
+
+ if (metaInfo != null) {
+ String renewed = (String)
+ metaInfo.get(ICertRecord.META_RENEWED_CERT);
+
+ if (renewed != null) {
+ BigInteger serial = new BigInteger(renewed);
+ X509CertImpl cert =
+ mCA.getCertificateRepository().getX509Certificate(serial);
+
+ if (cert == null) {
+ // something wrong
+ mCA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_MISSING_RENEWED", serial.toString()));
+ svcerrors[i] = new ECAException(
+ CMS.getUserMessage("CMS_CA_ERROR_GETTING_RENEWED_CERT",
+ oldSerialNo.toString(), serial.toString())).toString();
+ continue;
+ }
+ // get cert record
+ CertRecord cRecord = (CertRecord)
+ mCA.getCertificateRepository().readCertificateRecord(serial);
+
+ if (cRecord == null) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_NOT_FROM_CA", serial.toString()));
+ svcerrors[i] = new ECAException(
+ CMS.getUserMessage("CMS_CA_CANT_FIND_CERT_SERIAL",
+ serial.toString())).toString();
+ continue;
+ }
+ // Check renewed certificate already REVOKED or EXPIRED
+ String status = cRecord.getStatus();
+
+ if (status.equals(ICertRecord.STATUS_REVOKED) ||
+ status.equals(ICertRecord.STATUS_REVOKED_EXPIRED)) {
+ Debug.trace("It is already revoked or Expired !!!");
+ } // it is still new ... So just return this certificate to user
+ else {
+ Debug.trace("It is still new !!!");
+ issuedCerts[i] = cert;
+ continue;
+ }
+ }
+ }
+
+ // issue the cert.
+ issuedCerts[i] =
+ mService.issueX509Cert(rid, certinfos[i], true, oldSerialNo);
+ mService.storeX509Cert(rid, issuedCerts[i], true, oldSerialNo);
+ } catch (ECAException e) {
+ svcerrors[i] = e.toString();
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CANNOT_RENEW", Integer.toString(i), request
+ .getRequestId().toString()));
+ }
+ }
+
+ // always set issued certs regardless of error.
+ request.setExtData(IRequest.ISSUED_CERTS, issuedCerts);
+
+ // set and throw error if any.
+ int l;
+
+ for (l = svcerrors.length - 1; l >= 0 && svcerrors[l] == null; l--)
+ ;
+ if (l >= 0) {
+ request.setExtData(IRequest.SVCERRORS, svcerrors);
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_NO_RENEW", request.getRequestId().toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_RENEW_FAILED"));
+ }
+ return true;
+ }
+}
+
+class getCertsForChallenge implements IServant {
+ private ICertificateAuthority mCA;
+ private CAService mService;
+
+ public getCertsForChallenge(CAService service) {
+ mService = service;
+ mCA = mService.getCA();
+ }
+
+ public boolean service(IRequest request)
+ throws EBaseException {
+ BigInteger[] serialNoArray =
+ request.getExtDataInBigIntegerArray(CAService.SERIALNO_ARRAY);
+ X509CertImpl[] certs = new X509CertImpl[serialNoArray.length];
+
+ for (int i = 0; i < serialNoArray.length; i++) {
+ certs[i] = mCA.getCertificateRepository().getX509Certificate(serialNoArray[i]);
+ }
+ request.setExtData(IRequest.OLD_CERTS, certs);
+ return true;
+ }
+}
+
+class getCertStatus implements IServant {
+ private ICertificateAuthority mCA;
+ private CAService mService;
+
+ public getCertStatus(CAService service) {
+ mService = service;
+ mCA = mService.getCA();
+ }
+
+ public boolean service(IRequest request) throws EBaseException {
+ BigInteger serialno = request.getExtDataInBigInteger("serialNumber");
+ String issuerDN = request.getExtDataInString("issuerDN");
+ CertificateRepository certDB = (CertificateRepository)
+ mCA.getCertificateRepository();
+
+ String status = null;
+
+ if (serialno != null) {
+ CertRecord record = null;
+
+ try {
+ record = (CertRecord) certDB.readCertificateRecord(serialno);
+ } catch (EBaseException ee) {
+ Debug.trace(ee.toString());
+ }
+
+ if (record != null) {
+ status = record.getStatus();
+ if (status.equals("VALID")) {
+ X509CertImpl cacert = mCA.getCACert();
+ Principal p = cacert.getSubjectDN();
+
+ if (!p.toString().equals(issuerDN)) {
+ status = "INVALIDCERTROOT";
+ }
+ }
+ }
+ }
+
+ request.setExtData(IRequest.CERT_STATUS, status);
+ return true;
+ }
+}
+
+class serviceCheckChallenge implements IServant {
+ private ICertificateAuthority mCA;
+ private CAService mService;
+ private MessageDigest mSHADigest = null;
+
+ public serviceCheckChallenge(CAService service) {
+ mService = service;
+ mCA = mService.getCA();
+ try {
+ mSHADigest = MessageDigest.getInstance("SHA1");
+ } catch (NoSuchAlgorithmException e) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ }
+ }
+
+ public boolean service(IRequest request)
+ throws EBaseException {
+ // note: some request attributes used below are set in
+ // authentication/ChallengePhraseAuthentication.java :(
+ BigInteger serialno = request.getExtDataInBigInteger("serialNumber");
+ String pwd = request.getExtDataInString(
+ CAService.CHALLENGE_PHRASE);
+ CertificateRepository certDB = (CertificateRepository) mCA.getCertificateRepository();
+ BigInteger[] bigIntArray = null;
+
+ if (serialno != null) {
+ CertRecord record = null;
+
+ try {
+ record = (CertRecord) certDB.readCertificateRecord(serialno);
+ } catch (EBaseException ee) {
+ Debug.trace(ee.toString());
+ }
+ if (record != null) {
+ String status = record.getStatus();
+
+ if (status.equals("VALID")) {
+ boolean samepwd = compareChallengePassword(record, pwd);
+
+ if (samepwd) {
+ bigIntArray = new BigInteger[1];
+ bigIntArray[0] = record.getSerialNumber();
+ }
+ } else {
+ bigIntArray = new BigInteger[0];
+ }
+ } else
+ bigIntArray = new BigInteger[0];
+ } else {
+ String subjectName = request.getExtDataInString("subjectName");
+
+ if (subjectName != null) {
+ String filter = "(&(x509cert.subject=" + subjectName + ")(certStatus=VALID))";
+ ICertRecordList list = certDB.findCertRecordsInList(filter, null, 10);
+ int size = list.getSize();
+ Enumeration<ICertRecord> en = list.getCertRecords(0, size - 1);
+
+ if (!en.hasMoreElements()) {
+ bigIntArray = new BigInteger[0];
+ } else {
+ Vector<BigInteger> idv = new Vector<BigInteger>();
+
+ while (en.hasMoreElements()) {
+ ICertRecord record = en.nextElement();
+ boolean samepwd = compareChallengePassword(record, pwd);
+
+ if (samepwd) {
+ BigInteger id = record.getSerialNumber();
+
+ idv.addElement(id);
+ }
+ }
+ bigIntArray = new BigInteger[idv.size()];
+ idv.copyInto(bigIntArray);
+ }
+ }
+ }
+
+ if (bigIntArray == null)
+ bigIntArray = new BigInteger[0];
+
+ request.setExtData(CAService.SERIALNO_ARRAY, bigIntArray);
+ return true;
+ }
+
+ private boolean compareChallengePassword(ICertRecord 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"));
+ }
+
+ String hashpwd = hashPassword(pwd);
+
+ // got metaInfo
+ String challengeString =
+ (String) metaInfo.get(CertRecord.META_CHALLENGE_PHRASE);
+
+ if (!challengeString.equals(hashpwd)) {
+ return false;
+ } else
+ return true;
+ }
+
+ private String hashPassword(String pwd) {
+ String salt = "lala123";
+ byte[] pwdDigest = mSHADigest.digest((salt + pwd).getBytes());
+ String b64E = Utils.base64encode(pwdDigest);
+
+ return "{SHA}" + b64E;
+ }
+}
+
+class serviceRevoke implements IServant {
+ private ICertificateAuthority mCA;
+ private CAService mService;
+
+ public serviceRevoke(CAService service) {
+ mService = service;
+ mCA = mService.getCA();
+ }
+
+ public boolean service(IRequest request)
+ throws EBaseException {
+ boolean sendStatus = true;
+ // XXX Need to think passing as array.
+ // XXX every implemented according to servlet.
+ RevokedCertImpl crlentries[] =
+ request.getExtDataInRevokedCertArray(IRequest.CERT_INFO);
+
+ if (crlentries == null ||
+ crlentries.length == 0 ||
+ crlentries[0] == null) {
+ // XXX should this be an error ?
+ mCA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CRL_NOT_FOUND", request.getRequestId().toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_MISSING_INFO_IN_REVREQ"));
+ }
+
+ RevokedCertImpl revokedCerts[] =
+ new RevokedCertImpl[crlentries.length];
+ String svcerrors[] = null;
+
+ for (int i = 0; i < crlentries.length; i++) {
+ try {
+ mService.revokeCert(crlentries[i], request.getRequestId().toString());
+ revokedCerts[i] = crlentries[i];
+ } catch (ECAException e) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CANNOT_REVOKE", Integer.toString(i), request
+ .getRequestId().toString(), e.toString()));
+ revokedCerts[i] = null;
+ if (svcerrors == null) {
+ svcerrors = new String[revokedCerts.length];
+ }
+ svcerrors[i] = e.toString();
+ }
+ }
+
+ // #605941 - request.get(IRequest.CERT_INFO) store exact same thing
+ // request.set(IRequest.REVOKED_CERTS, revokedCerts);
+
+ // if clone ca, send revoked cert records to CLA
+ if (CAService.mCLAConnector != null) {
+ CMS.debug(CMS.getLogMessage("CMSCORE_CA_CLONE_READ_REVOKED"));
+ BigInteger revokedCertIds[] =
+ new BigInteger[revokedCerts.length];
+
+ for (int i = 0; i < revokedCerts.length; i++) {
+ revokedCertIds[i] = revokedCerts[i].getSerialNumber();
+ }
+ request.deleteExtData(IRequest.CERT_INFO);
+ request.deleteExtData(IRequest.OLD_CERTS);
+ request.setExtData(IRequest.REVOKED_CERT_RECORDS, revokedCertIds);
+
+ CMS.debug(CMS.getLogMessage("CMSCORE_CA_CLONE_READ_REVOKED_CONNECTOR"));
+
+ request.setRequestType(IRequest.CLA_CERT4CRL_REQUEST);
+ sendStatus = CAService.mCLAConnector.send(request);
+ if (sendStatus == false) {
+ request.setExtData(IRequest.RESULT,
+ IRequest.RES_ERROR);
+ request.setExtData(IRequest.ERROR,
+ new ECAException(CMS.getUserMessage("CMS_CA_SEND_CLA_REQUEST")));
+ return sendStatus;
+ } else {
+ if (request.getExtDataInString(IRequest.ERROR) != null) {
+ request.setExtData(IRequest.RESULT, IRequest.RES_SUCCESS);
+ request.deleteExtData(IRequest.ERROR);
+ }
+ }
+ if (request.getExtDataInString(IRequest.ERROR) != null) {
+ return sendStatus;
+ }
+ }
+
+ if (svcerrors != null) {
+ request.setExtData(IRequest.SVCERRORS, svcerrors);
+ throw new ECAException(CMS.getUserMessage("CMS_CA_REVOKE_FAILED"));
+ }
+
+ if (Debug.ON) {
+ Debug.trace("serviceRevoke sendStatus=" + sendStatus);
+ }
+
+ return sendStatus;
+ }
+}
+
+class serviceUnrevoke implements IServant {
+ private ICertificateAuthority mCA;
+ private CAService mService;
+
+ public serviceUnrevoke(CAService service) {
+ mService = service;
+ mCA = mService.getCA();
+ }
+
+ public boolean service(IRequest request)
+ throws EBaseException {
+ boolean sendStatus = true;
+ BigInteger oldSerialNo[] =
+ request.getExtDataInBigIntegerArray(IRequest.OLD_SERIALS);
+
+ if (oldSerialNo == null || oldSerialNo.length < 1) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_UNREVOKE_MISSING_SERIAL"));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_MISSING_SERIAL_NUMBER"));
+ }
+
+ String svcerrors[] = null;
+ boolean needOldCerts = false;
+ X509CertImpl oldCerts[] = request.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ if (oldCerts == null || oldCerts.length < 1) {
+ needOldCerts = true;
+ oldCerts = new X509CertImpl[oldSerialNo.length];
+ }
+
+ for (int i = 0; i < oldSerialNo.length; i++) {
+ try {
+ if (oldSerialNo[i].compareTo(new BigInteger("0")) < 0) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_UNREVOKE_MISSING_SERIAL"));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_MISSING_SERIAL_NUMBER"));
+ }
+ if (needOldCerts) {
+ CertRecord certRec = (CertRecord)
+ mCA.getCertificateRepository().readCertificateRecord(oldSerialNo[i]);
+
+ oldCerts[i] = certRec.getCertificate();
+ }
+ mService.unrevokeCert(oldSerialNo[i], request.getRequestId().toString());
+ } catch (ECAException e) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_UNREVOKE_FAILED", oldSerialNo[i].toString(),
+ request.getRequestId().toString()));
+ if (svcerrors == null) {
+ svcerrors = new String[oldSerialNo.length];
+ }
+ svcerrors[i] = e.toString();
+ }
+ }
+
+ // if clone ca, send unrevoked cert serials to CLA
+ if (CAService.mCLAConnector != null) {
+ request.setRequestType(IRequest.CLA_UNCERT4CRL_REQUEST);
+ sendStatus = CAService.mCLAConnector.send(request);
+ if (sendStatus == false) {
+ request.setExtData(IRequest.RESULT,
+ IRequest.RES_ERROR);
+ request.setExtData(IRequest.ERROR,
+ new ECAException(CMS.getUserMessage("CMS_CA_SEND_CLA_REQUEST")));
+ return sendStatus;
+ } else {
+ if (request.getExtDataInString(IRequest.ERROR) != null) {
+ request.setExtData(IRequest.RESULT, IRequest.RES_SUCCESS);
+ request.deleteExtData(IRequest.ERROR);
+ }
+ }
+
+ }
+
+ if (needOldCerts) {
+ request.setExtData(IRequest.OLD_CERTS, oldCerts);
+ }
+
+ if (svcerrors != null) {
+ request.setExtData(IRequest.SVCERRORS, svcerrors);
+ throw new ECAException(CMS.getUserMessage("CMS_CA_UNREVOKE_FAILED"));
+ }
+
+ return sendStatus;
+ }
+}
+
+class serviceGetCAChain implements IServant {
+ private ICertificateAuthority mCA;
+ private CAService mService;
+
+ public serviceGetCAChain(CAService service) {
+ mService = service;
+ mCA = mService.getCA();
+ }
+
+ public boolean service(IRequest request) throws EBaseException {
+ CertificateChain certChain = mCA.getCACertChain();
+ ByteArrayOutputStream certChainOut = new ByteArrayOutputStream();
+ try {
+ certChain.encode(certChainOut);
+ } catch (IOException e) {
+ mCA.log(ILogger.LL_FAILURE, e.toString());
+ throw new EBaseException(e.toString());
+ }
+ request.setExtData(IRequest.CACERTCHAIN, certChainOut.toByteArray());
+ return true;
+ }
+}
+
+class serviceGetCRL implements IServant {
+ private ICertificateAuthority mCA;
+ private CAService mService;
+
+ public serviceGetCRL(CAService service) {
+ mService = service;
+ mCA = mService.getCA();
+ }
+
+ public boolean service(IRequest request)
+ throws EBaseException {
+ try {
+ ICRLIssuingPointRecord crlRec =
+ mCA.getCRLRepository().readCRLIssuingPointRecord(
+ ICertificateAuthority.PROP_MASTER_CRL);
+ X509CRLImpl crl = new X509CRLImpl(crlRec.getCRL());
+
+ request.setExtData(IRequest.CRL, crl.getEncoded());
+ } catch (EBaseException e) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_GETCRL_FIND_CRL"));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_CRL_ISSUEPT_NOT_FOUND", e.toString()));
+ } catch (CRLException e) {
+ mCA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_GETCRL_INST_CRL", ICertificateAuthority.PROP_MASTER_CRL));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_CRL_ISSUEPT_NOGOOD", ICertificateAuthority.PROP_MASTER_CRL));
+ } catch (X509ExtensionException e) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_GETCRL_NO_ISSUING_REC"));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_CRL_ISSUEPT_EXT_NOGOOD",
+ ICertificateAuthority.PROP_MASTER_CRL));
+ }
+ return true;
+ }
+}
+
+class serviceGetRevocationInfo implements IServant {
+ private ICertificateAuthority mCA;
+ private CAService mService;
+
+ public serviceGetRevocationInfo(CAService service) {
+ mService = service;
+ mCA = mService.getCA();
+ }
+
+ public boolean service(IRequest request)
+ throws EBaseException {
+ Enumeration<String> enum1 = request.getExtDataKeys();
+
+ while (enum1.hasMoreElements()) {
+ String name = enum1.nextElement();
+
+ if (name.equals(IRequest.ISSUED_CERTS)) {
+ X509CertImpl certsToCheck[] =
+ request.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ CertificateRepository certDB = (CertificateRepository) mCA.getCertificateRepository();
+ RevocationInfo info =
+ certDB.isCertificateRevoked(certsToCheck[0]);
+
+ if (info != null) {
+ RevokedCertImpl revokedCerts[] = new RevokedCertImpl[1];
+ RevokedCertImpl revokedCert = new RevokedCertImpl(
+ certsToCheck[0].getSerialNumber(),
+ info.getRevocationDate(),
+ info.getCRLEntryExtensions());
+
+ revokedCerts[0] = revokedCert;
+ request.setExtData(IRequest.REVOKED_CERTS, revokedCerts);
+ }
+ }
+ }
+ return true;
+ }
+}
+
+class serviceGetCertificates implements IServant {
+ private ICertificateAuthority mCA;
+ private CAService mService;
+
+ public serviceGetCertificates(CAService service) {
+ mService = service;
+ mCA = mService.getCA();
+ }
+
+ public boolean service(IRequest request)
+ throws EBaseException {
+ Enumeration<String> enum1 = request.getExtDataKeys();
+
+ while (enum1.hasMoreElements()) {
+ String name = enum1.nextElement();
+
+ if (name.equals(IRequest.CERT_FILTER)) {
+ String filter = request.getExtDataInString(IRequest.CERT_FILTER);
+
+ CertificateRepository certDB = (CertificateRepository) mCA.getCertificateRepository();
+ X509CertImpl[] certs = certDB.getX509Certificates(filter);
+
+ if (certs != null) {
+ request.setExtData(IRequest.OLD_CERTS, certs);
+ }
+ }
+ }
+ return true;
+ }
+}
+
+class serviceCert4Crl implements IServant {
+ private ICertificateAuthority mCA;
+ private CAService mService;
+
+ public serviceCert4Crl(CAService service) {
+ mService = service;
+ mCA = mService.getCA();
+ }
+
+ public boolean service(IRequest request)
+ throws EBaseException {
+ // XXX Need to think passing as array.
+ // XXX every implemented according to servlet.
+ BigInteger revokedCertIds[] = request.getExtDataInBigIntegerArray(
+ IRequest.REVOKED_CERT_RECORDS);
+ if (revokedCertIds == null ||
+ revokedCertIds.length == 0) {
+ mCA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CERT4CRL_NO_ENTRY", request.getRequestId().toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_MISSING_INFO_IN_CLAREQ"));
+ }
+
+ CertRecord revokedCertRecs[] = new CertRecord[revokedCertIds.length];
+ for (int i = 0; i < revokedCertIds.length; i++) {
+ revokedCertRecs[i] = (CertRecord)
+ mCA.getCertificateRepository().readCertificateRecord(
+ revokedCertIds[i]);
+ }
+
+ if (revokedCertRecs == null ||
+ revokedCertRecs.length == 0 ||
+ revokedCertRecs[0] == null) {
+ // XXX should this be an error ?
+ mCA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CERT4CRL_NO_ENTRY", request.getRequestId().toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_MISSING_INFO_IN_CLAREQ"));
+ }
+
+ CertRecord recordedCerts[] =
+ new CertRecord[revokedCertRecs.length];
+ String svcerrors[] = null;
+
+ for (int i = 0; i < revokedCertRecs.length; i++) {
+ try {
+ // for CLA, record it into cert repost
+ ((CertificateRepository) mCA.getCertificateRepository()).addRevokedCertRecord(revokedCertRecs[i]);
+ // mService.revokeCert(crlentries[i]);
+ recordedCerts[i] = revokedCertRecs[i];
+ // inform all CRLIssuingPoints about revoked certificate
+ Hashtable<String, ICRLIssuingPoint> hips = mService.getCRLIssuingPoints();
+ Enumeration<ICRLIssuingPoint> eIPs = hips.elements();
+
+ while (eIPs.hasMoreElements()) {
+ ICRLIssuingPoint ip = eIPs.nextElement();
+ // form RevokedCertImpl
+ RevokedCertImpl rci =
+ new RevokedCertImpl(revokedCertRecs[i].getSerialNumber(),
+ revokedCertRecs[i].getRevokedOn());
+
+ if (ip != null) {
+ ip.addRevokedCert(revokedCertRecs[i].getSerialNumber(), rci);
+ }
+ }
+
+ } catch (ECAException e) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CERT4CRL_NO_REC", Integer.toString(i),
+ request.getRequestId().toString(), e.toString()));
+ recordedCerts[i] = null;
+ if (svcerrors == null) {
+ svcerrors = new String[recordedCerts.length];
+ }
+ svcerrors[i] = e.toString();
+ }
+ }
+ //need to record which gets recorded and which failed...cfu
+ // request.set(IRequest.REVOKED_CERTS, revokedCerts);
+ if (svcerrors != null) {
+ request.setExtData(IRequest.SVCERRORS, svcerrors);
+ throw new ECAException(CMS.getUserMessage("CMS_CA_CERT4CRL_FAILED"));
+ }
+
+ return true;
+ }
+}
+
+class serviceUnCert4Crl implements IServant {
+ private ICertificateAuthority mCA;
+ private CAService mService;
+
+ public serviceUnCert4Crl(CAService service) {
+ mService = service;
+ mCA = mService.getCA();
+ }
+
+ public boolean service(IRequest request)
+ throws EBaseException {
+ BigInteger oldSerialNo[] =
+ request.getExtDataInBigIntegerArray(IRequest.OLD_SERIALS);
+
+ if (oldSerialNo == null || oldSerialNo.length < 1) {
+ mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_UNREVOKE_MISSING_SERIAL"));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_MISSING_SERIAL_NUMBER"));
+ }
+
+ String svcerrors[] = null;
+
+ for (int i = 0; i < oldSerialNo.length; i++) {
+ try {
+ mCA.getCertificateRepository().deleteCertificateRecord(oldSerialNo[i]);
+ // inform all CRLIssuingPoints about unrevoked certificate
+ Hashtable<String, ICRLIssuingPoint> hips = mService.getCRLIssuingPoints();
+ Enumeration<ICRLIssuingPoint> eIPs = hips.elements();
+
+ while (eIPs.hasMoreElements()) {
+ ICRLIssuingPoint ip = eIPs.nextElement();
+
+ if (ip != null) {
+ ip.addUnrevokedCert(oldSerialNo[i]);
+ }
+ }
+ } catch (EBaseException e) {
+ mCA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_DELETE_CERT_ERROR", oldSerialNo[i].toString(), e.toString()));
+ if (svcerrors == null) {
+ svcerrors = new String[oldSerialNo.length];
+ }
+ svcerrors[i] = e.toString();
+ }
+
+ }
+
+ if (svcerrors != null) {
+ request.setExtData(IRequest.SVCERRORS, svcerrors);
+ throw new ECAException(CMS.getUserMessage("CMS_CA_UNCERT4CRL_FAILED"));
+ }
+
+ return true;
+ }
+}
diff --git a/base/ca/src/com/netscape/ca/CMSCRLExtensions.java b/base/ca/src/com/netscape/ca/CMSCRLExtensions.java
new file mode 100644
index 000000000..94693d69a
--- /dev/null
+++ b/base/ca/src/com/netscape/ca/CMSCRLExtensions.java
@@ -0,0 +1,711 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.ca;
+
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.security.extensions.AuthInfoAccessExtension;
+import netscape.security.x509.AuthorityKeyIdentifierExtension;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLNumberExtension;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.DeltaCRLIndicatorExtension;
+import netscape.security.x509.Extension;
+import netscape.security.x509.FreshestCRLExtension;
+import netscape.security.x509.HoldInstructionExtension;
+import netscape.security.x509.InvalidityDateExtension;
+import netscape.security.x509.IssuerAlternativeNameExtension;
+import netscape.security.x509.IssuingDistributionPointExtension;
+import netscape.security.x509.OIDMap;
+import netscape.security.x509.PKIXExtensions;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotDefined;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ca.ICMSCRLExtension;
+import com.netscape.certsrv.ca.ICMSCRLExtensions;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.crl.CMSIssuingDistributionPointExtension;
+import com.netscape.cmscore.base.SubsystemRegistry;
+
+public class CMSCRLExtensions implements ICMSCRLExtensions {
+ public static final String PROP_ENABLE = "enable";
+ public static final String PROP_EXTENSION = "extension";
+ public static final String PROP_CLASS = "class";
+ public static final String PROP_TYPE = "type";
+ public static final String PROP_CRITICAL = "critical";
+ public static final String PROP_CRL_EXT = "CRLExtension";
+ public static final String PROP_CRL_ENTRY_EXT = "CRLEntryExtension";
+
+ private ICRLIssuingPoint mCRLIssuingPoint = null;
+
+ private IConfigStore mConfig = null;
+ private IConfigStore mCRLExtConfig = null;
+
+ private Vector<String> mCRLExtensionNames = new Vector<String>();
+ private Vector<String> mCRLEntryExtensionNames = new Vector<String>();
+ private Vector<String> mEnabledCRLExtensions = new Vector<String>();
+ private Vector<String> mCriticalCRLExtensions = new Vector<String>();
+ private Hashtable<String, String> mCRLExtensionClassNames = new Hashtable<String, String>();
+ private Hashtable<String, String> mCRLExtensionIDs = new Hashtable<String, String>();
+
+ private static final Vector<String> mDefaultCRLExtensionNames = new Vector<String>();
+ private static final Vector<String> mDefaultCRLEntryExtensionNames = new Vector<String>();
+ private static final Vector<String> mDefaultEnabledCRLExtensions = new Vector<String>();
+ private static final Vector<String> mDefaultCriticalCRLExtensions = new Vector<String>();
+ private static final Hashtable<String, String> mDefaultCRLExtensionClassNames = new Hashtable<String, String>();
+ private static final Hashtable<String, String> mDefaultCRLExtensionIDs = new Hashtable<String, String>();
+
+ private ILogger mLogger = CMS.getLogger();
+
+ static {
+
+ /* Default CRL Extensions */
+ mDefaultCRLExtensionNames.addElement(AuthorityKeyIdentifierExtension.NAME);
+ mDefaultCRLExtensionNames.addElement(IssuerAlternativeNameExtension.NAME);
+ mDefaultCRLExtensionNames.addElement(CRLNumberExtension.NAME);
+ mDefaultCRLExtensionNames.addElement(DeltaCRLIndicatorExtension.NAME);
+ mDefaultCRLExtensionNames.addElement(IssuingDistributionPointExtension.NAME);
+ mDefaultCRLExtensionNames.addElement(FreshestCRLExtension.NAME);
+ mDefaultCRLExtensionNames.addElement(AuthInfoAccessExtension.NAME2);
+
+ /* Default CRL Entry Extensions */
+ mDefaultCRLEntryExtensionNames.addElement(CRLReasonExtension.NAME);
+ //mDefaultCRLEntryExtensionNames.addElement(HoldInstructionExtension.NAME);
+ mDefaultCRLEntryExtensionNames.addElement(InvalidityDateExtension.NAME);
+ //mDefaultCRLEntryExtensionNames.addElement(CertificateIssuerExtension.NAME);
+
+ /* Default Enabled CRL Extensions */
+ mDefaultEnabledCRLExtensions.addElement(CRLNumberExtension.NAME);
+ //mDefaultEnabledCRLExtensions.addElement(DeltaCRLIndicatorExtension.NAME);
+ mDefaultEnabledCRLExtensions.addElement(CRLReasonExtension.NAME);
+ mDefaultEnabledCRLExtensions.addElement(InvalidityDateExtension.NAME);
+
+ /* Default Critical CRL Extensions */
+ mDefaultCriticalCRLExtensions.addElement(DeltaCRLIndicatorExtension.NAME);
+ mDefaultCriticalCRLExtensions.addElement(IssuingDistributionPointExtension.NAME);
+ //mDefaultCriticalCRLExtensions.addElement(CertificateIssuerExtension.NAME);
+
+ /* CRL extension IDs */
+ mDefaultCRLExtensionIDs.put(PKIXExtensions.AuthorityKey_Id.toString(),
+ AuthorityKeyIdentifierExtension.NAME);
+ mDefaultCRLExtensionIDs.put(PKIXExtensions.IssuerAlternativeName_Id.toString(),
+ IssuerAlternativeNameExtension.NAME);
+ mDefaultCRLExtensionIDs.put(PKIXExtensions.CRLNumber_Id.toString(),
+ CRLNumberExtension.NAME);
+ mDefaultCRLExtensionIDs.put(PKIXExtensions.DeltaCRLIndicator_Id.toString(),
+ DeltaCRLIndicatorExtension.NAME);
+ mDefaultCRLExtensionIDs.put(PKIXExtensions.IssuingDistributionPoint_Id.toString(),
+ IssuingDistributionPointExtension.NAME);
+ mDefaultCRLExtensionIDs.put(PKIXExtensions.ReasonCode_Id.toString(),
+ CRLReasonExtension.NAME);
+ mDefaultCRLExtensionIDs.put(PKIXExtensions.HoldInstructionCode_Id.toString(),
+ HoldInstructionExtension.NAME);
+ mDefaultCRLExtensionIDs.put(PKIXExtensions.InvalidityDate_Id.toString(),
+ InvalidityDateExtension.NAME);
+ //mDefaultCRLExtensionIDs.put(PKIXExtensions.CertificateIssuer_Id.toString(),
+ // CertificateIssuerExtension.NAME);
+ mDefaultCRLExtensionIDs.put(PKIXExtensions.FreshestCRL_Id.toString(),
+ FreshestCRLExtension.NAME);
+ mDefaultCRLExtensionIDs.put(AuthInfoAccessExtension.ID.toString(),
+ AuthInfoAccessExtension.NAME2);
+
+ /* Class names */
+ mDefaultCRLExtensionClassNames.put(AuthorityKeyIdentifierExtension.NAME,
+ "com.netscape.cms.crl.CMSAuthorityKeyIdentifierExtension");
+ mDefaultCRLExtensionClassNames.put(IssuerAlternativeNameExtension.NAME,
+ "com.netscape.cms.crl.CMSIssuerAlternativeNameExtension");
+ mDefaultCRLExtensionClassNames.put(CRLNumberExtension.NAME,
+ "com.netscape.cms.crl.CMSCRLNumberExtension");
+ mDefaultCRLExtensionClassNames.put(DeltaCRLIndicatorExtension.NAME,
+ "com.netscape.cms.crl.CMSDeltaCRLIndicatorExtension");
+ mDefaultCRLExtensionClassNames.put(IssuingDistributionPointExtension.NAME,
+ "com.netscape.cms.crl.CMSIssuingDistributionPointExtension");
+ mDefaultCRLExtensionClassNames.put(CRLReasonExtension.NAME,
+ "com.netscape.cms.crl.CMSCRLReasonExtension");
+ mDefaultCRLExtensionClassNames.put(HoldInstructionExtension.NAME,
+ "com.netscape.cms.crl.CMSHoldInstructionExtension");
+ mDefaultCRLExtensionClassNames.put(InvalidityDateExtension.NAME,
+ "com.netscape.cms.crl.CMSInvalidityDateExtension");
+ //mDefaultCRLExtensionClassNames.put(CertificateIssuerExtension.NAME,
+ // "com.netscape.cms.crl.CMSCertificateIssuerExtension");
+ mDefaultCRLExtensionClassNames.put(FreshestCRLExtension.NAME,
+ "com.netscape.cms.crl.CMSFreshestCRLExtension");
+ mDefaultCRLExtensionClassNames.put(AuthInfoAccessExtension.NAME2,
+ "com.netscape.cms.crl.CMSAuthInfoAccessExtension");
+
+ try {
+ OIDMap.addAttribute(DeltaCRLIndicatorExtension.class.getName(),
+ DeltaCRLIndicatorExtension.OID,
+ DeltaCRLIndicatorExtension.NAME);
+ } catch (CertificateException e) {
+ }
+ try {
+ OIDMap.addAttribute(HoldInstructionExtension.class.getName(),
+ HoldInstructionExtension.OID,
+ HoldInstructionExtension.NAME);
+ } catch (CertificateException e) {
+ }
+ try {
+ OIDMap.addAttribute(InvalidityDateExtension.class.getName(),
+ InvalidityDateExtension.OID,
+ InvalidityDateExtension.NAME);
+ } catch (CertificateException e) {
+ }
+ try {
+ OIDMap.addAttribute(FreshestCRLExtension.class.getName(),
+ FreshestCRLExtension.OID,
+ FreshestCRLExtension.NAME);
+ } catch (CertificateException e) {
+ }
+ }
+
+ /**
+ * Constructs a CRL extensions for CRL issuing point.
+ */
+ public CMSCRLExtensions(ICRLIssuingPoint crlIssuingPoint, IConfigStore config) {
+ boolean modifiedConfig = false;
+
+ mConfig = config;
+ mCRLExtConfig = config.getSubStore(PROP_EXTENSION);
+ mCRLIssuingPoint = crlIssuingPoint;
+
+ IConfigStore mFileConfig =
+ SubsystemRegistry.getInstance().get("MAIN").getConfigStore();
+
+ IConfigStore crlExtConfig = mFileConfig;
+ StringTokenizer st = new StringTokenizer(mCRLExtConfig.getName(), ".");
+
+ while (st.hasMoreTokens()) {
+ String subStoreName = st.nextToken();
+ IConfigStore newConfig = crlExtConfig.getSubStore(subStoreName);
+
+ if (newConfig != null) {
+ crlExtConfig = newConfig;
+ }
+ }
+
+ if (crlExtConfig != null) {
+ Enumeration<String> enumExts = crlExtConfig.getSubStoreNames();
+
+ while (enumExts.hasMoreElements()) {
+ String extName = enumExts.nextElement();
+ IConfigStore extConfig = crlExtConfig.getSubStore(extName);
+
+ if (extConfig != null) {
+ modifiedConfig |= getEnableProperty(extName, extConfig);
+ modifiedConfig |= getCriticalProperty(extName, extConfig);
+ modifiedConfig |= getTypeProperty(extName, extConfig);
+ modifiedConfig |= getClassProperty(extName, extConfig);
+ }
+ }
+
+ if (modifiedConfig) {
+ try {
+ mFileConfig.commit(true);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CRLEXTS_SAVE_CONF", e.toString()));
+ }
+ }
+ }
+ }
+
+ private boolean getEnableProperty(String extName, IConfigStore extConfig) {
+ boolean modifiedConfig = false;
+
+ try {
+ if (extConfig.getBoolean(PROP_ENABLE)) {
+ mEnabledCRLExtensions.addElement(extName);
+ }
+ } catch (EPropertyNotFound e) {
+ extConfig.putBoolean(PROP_ENABLE, mDefaultEnabledCRLExtensions.contains(extName));
+ modifiedConfig = true;
+ if (mDefaultEnabledCRLExtensions.contains(extName)) {
+ mEnabledCRLExtensions.addElement(extName);
+ }
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CRLEXTS_NO_ENABLE", extName,
+ mDefaultEnabledCRLExtensions.contains(extName) ? "true" : "false"));
+ } catch (EPropertyNotDefined e) {
+ extConfig.putBoolean(PROP_ENABLE, mDefaultEnabledCRLExtensions.contains(extName));
+ modifiedConfig = true;
+ if (mDefaultEnabledCRLExtensions.contains(extName)) {
+ mEnabledCRLExtensions.addElement(extName);
+ }
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CRLEXTS_UNDEFINE_ENABLE", extName,
+ mDefaultEnabledCRLExtensions.contains(extName) ? "true" : "false"));
+ } catch (EBaseException e) {
+ extConfig.putBoolean(PROP_ENABLE, mDefaultEnabledCRLExtensions.contains(extName));
+ modifiedConfig = true;
+ if (mDefaultEnabledCRLExtensions.contains(extName)) {
+ mEnabledCRLExtensions.addElement(extName);
+ }
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CRLEXTS_INVALID_ENABLE", extName,
+ mDefaultEnabledCRLExtensions.contains(extName) ? "true" : "false"));
+ }
+ return modifiedConfig;
+ }
+
+ private boolean getCriticalProperty(String extName, IConfigStore extConfig) {
+ boolean modifiedConfig = false;
+
+ try {
+ if (extConfig.getBoolean(PROP_CRITICAL)) {
+ mCriticalCRLExtensions.addElement(extName);
+ }
+ } catch (EPropertyNotFound e) {
+ extConfig.putBoolean(PROP_CRITICAL, mDefaultCriticalCRLExtensions.contains(extName));
+ modifiedConfig = true;
+ if (mDefaultCriticalCRLExtensions.contains(extName)) {
+ mCriticalCRLExtensions.addElement(extName);
+ }
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CRLEXTS_NO_CRITICAL", extName,
+ mDefaultEnabledCRLExtensions.contains(extName) ? "true" : "false"));
+ } catch (EPropertyNotDefined e) {
+ extConfig.putBoolean(PROP_CRITICAL, mDefaultCriticalCRLExtensions.contains(extName));
+ modifiedConfig = true;
+ if (mDefaultCriticalCRLExtensions.contains(extName)) {
+ mCriticalCRLExtensions.addElement(extName);
+ }
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CRLEXTS_UNDEFINE_CRITICAL", extName,
+ mDefaultEnabledCRLExtensions.contains(extName) ? "true" : "false"));
+ } catch (EBaseException e) {
+ extConfig.putBoolean(PROP_CRITICAL, mDefaultCriticalCRLExtensions.contains(extName));
+ modifiedConfig = true;
+ if (mDefaultCriticalCRLExtensions.contains(extName)) {
+ mCriticalCRLExtensions.addElement(extName);
+ }
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CRLEXTS_INVALID_CRITICAL", extName,
+ mDefaultEnabledCRLExtensions.contains(extName) ? "true" : "false"));
+ }
+ return modifiedConfig;
+ }
+
+ private boolean getTypeProperty(String extName, IConfigStore extConfig) {
+ boolean modifiedConfig = false;
+ String extType = null;
+
+ try {
+ extType = extConfig.getString(PROP_TYPE);
+ if (extType.length() > 0) {
+ if (extType.equals(PROP_CRL_ENTRY_EXT)) {
+ mCRLEntryExtensionNames.addElement(extName);
+ } else if (extType.equals(PROP_CRL_EXT)) {
+ mCRLExtensionNames.addElement(extName);
+ } else {
+ if (mDefaultCRLEntryExtensionNames.contains(extName)) {
+ extConfig.putString(PROP_TYPE, PROP_CRL_ENTRY_EXT);
+ modifiedConfig = true;
+ mCRLEntryExtensionNames.addElement(extName);
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CRLEXTS_INVALID_EXT", extName, PROP_CRL_ENTRY_EXT));
+ } else if (mDefaultCRLExtensionNames.contains(extName)) {
+ extConfig.putString(PROP_TYPE, PROP_CRL_EXT);
+ modifiedConfig = true;
+ mCRLExtensionNames.addElement(extName);
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CRLEXTS_INVALID_EXT", extName, PROP_CRL_EXT));
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CRLEXTS_INVALID_EXT", extName, ""));
+ }
+ }
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CRLEXTS_UNDEFINE_EXT", extName));
+ }
+ } catch (EPropertyNotFound e) {
+ if (mDefaultCRLEntryExtensionNames.contains(extName)) {
+ extConfig.putString(PROP_TYPE, PROP_CRL_ENTRY_EXT);
+ modifiedConfig = true;
+ } else if (mDefaultCRLExtensionNames.contains(extName)) {
+ extConfig.putString(PROP_TYPE, PROP_CRL_EXT);
+ modifiedConfig = true;
+ }
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CRLEXTS_MISSING_EXT", extName));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CRLEXTS_INVALID_EXT", extName, ""));
+ }
+ return modifiedConfig;
+ }
+
+ private boolean getClassProperty(String extName, IConfigStore extConfig) {
+ boolean modifiedConfig = false;
+ String extClass = null;
+
+ try {
+ extClass = extConfig.getString(PROP_CLASS);
+ if (extClass.length() > 0) {
+ mCRLExtensionClassNames.put(extName, extClass);
+
+ try {
+ @SuppressWarnings("unchecked")
+ Class<ICMSCRLExtension> crlExtClass = (Class<ICMSCRLExtension>) Class.forName(extClass);
+
+ if (crlExtClass != null) {
+ ICMSCRLExtension cmsCRLExt = crlExtClass.newInstance();
+
+ if (cmsCRLExt != null) {
+ String id = cmsCRLExt.getCRLExtOID();
+
+ if (id != null) {
+ mCRLExtensionIDs.put(id, extName);
+ }
+ }
+ }
+ } catch (ClassCastException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CRLEXTS_INCORRECT_CLASS", extClass, e.toString()));
+ } catch (ClassNotFoundException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CRLEXTS_CLASS_NOT_FOUND", extClass, e.toString()));
+ } catch (InstantiationException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CRLEXTS_CLASS_NOT_INST", extClass, e.toString()));
+ } catch (IllegalAccessException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CRLEXTS_CLASS_NOT_ACCESS", extClass, e.toString()));
+ }
+
+ } else {
+ if (mDefaultCRLExtensionClassNames.containsKey(extName)) {
+ extClass = mCRLExtensionClassNames.get(extName);
+ extConfig.putString(PROP_CLASS, extClass);
+ modifiedConfig = true;
+ }
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CRLEXTS_CLASS_NOT_DEFINED", extName));
+ }
+ } catch (EPropertyNotFound e) {
+ if (mDefaultCRLExtensionClassNames.containsKey(extName)) {
+ extClass = mDefaultCRLExtensionClassNames.get(extName);
+ extConfig.putString(PROP_CLASS, extClass);
+ modifiedConfig = true;
+ }
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CRLEXTS_CLASS_MISSING", extName));
+ } catch (EBaseException e) {
+ if (mDefaultCRLExtensionClassNames.containsKey(extName)) {
+ extClass = mDefaultCRLExtensionClassNames.get(extName);
+ extConfig.putString(PROP_CLASS, extClass);
+ modifiedConfig = true;
+ }
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CRLEXTS_CLASS_INVALID", extName));
+ }
+ return modifiedConfig;
+ }
+
+ public boolean isCRLExtension(String extName) {
+ return mCRLExtensionNames.contains(extName);
+ }
+
+ public boolean isCRLEntryExtension(String extName) {
+ return mCRLEntryExtensionNames.contains(extName);
+ }
+
+ public boolean isCRLExtensionEnabled(String extName) {
+ return ((mCRLExtensionNames.contains(extName) || mCRLEntryExtensionNames.contains(extName)) &&
+ mEnabledCRLExtensions.contains(extName));
+ }
+
+ public boolean isCRLExtensionCritical(String extName) {
+ return mCriticalCRLExtensions.contains(extName);
+ }
+
+ public String getCRLExtensionName(String id) {
+ String name = null;
+
+ if (mCRLExtensionIDs.containsKey(id)) {
+ name = mCRLExtensionIDs.get(id);
+ }
+ return name;
+ }
+
+ public Vector<String> getCRLExtensionNames() {
+ return new Vector<String>(mCRLExtensionNames);
+ }
+
+ public Vector<String> getCRLEntryExtensionNames() {
+ return new Vector<String>(mCRLEntryExtensionNames);
+ }
+
+ public void addToCRLExtensions(CRLExtensions crlExts, String extName, Extension ext) {
+ if (mCRLExtensionClassNames.containsKey(extName)) {
+ String name = mCRLExtensionClassNames.get(extName);
+
+ try {
+ @SuppressWarnings("unchecked")
+ Class<ICMSCRLExtension> extClass = (Class<ICMSCRLExtension>) Class.forName(name);
+
+ if (extClass != null) {
+ ICMSCRLExtension cmsCRLExt = extClass.newInstance();
+
+ if (cmsCRLExt != null) {
+ if (ext != null) {
+ if (isCRLExtensionCritical(extName) ^ ext.isCritical()) {
+ ext = cmsCRLExt.setCRLExtensionCriticality(
+ ext, isCRLExtensionCritical(extName));
+ }
+ } else {
+ ext = cmsCRLExt.getCRLExtension(mCRLExtConfig.getSubStore(extName),
+ mCRLIssuingPoint,
+ isCRLExtensionCritical(extName));
+ }
+
+ if (crlExts != null && ext != null) {
+ crlExts.set(extName, ext);
+ }
+ }
+ }
+ } catch (ClassCastException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CRLEXTS_INCORRECT_CLASS", name, e.toString()));
+ } catch (ClassNotFoundException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CRLEXTS_CLASS_NOT_FOUND", name, e.toString()));
+ } catch (InstantiationException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CRLEXTS_CLASS_NOT_INST", name, e.toString()));
+ } catch (IllegalAccessException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CRLEXTS_CLASS_NOT_ACCESS", name, e.toString()));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CRLEXTS_CLASS_ADD", name, e.toString()));
+ }
+ }
+ }
+
+ public NameValuePairs getConfigParams(String id) {
+ NameValuePairs nvp = null;
+
+ if (mCRLEntryExtensionNames.contains(id) ||
+ mCRLExtensionNames.contains(id)) {
+ nvp = new NameValuePairs();
+
+ /*
+ if (mCRLEntryExtensionNames.contains(id)) {
+ nvp.add(Constants.PR_CRLEXT_IMPL_NAME, "CRLEntryExtension");
+ } else {
+ nvp.add(Constants.PR_CRLEXT_IMPL_NAME, "CRLExtension");
+ }
+
+ if (mCRLEntryExtensionNames.contains(id)) {
+ nvp.add(PROP_TYPE, "CRLEntryExtension");
+ } else {
+ nvp.add(PROP_TYPE, "CRLExtension");
+ }
+ */
+
+ if (mEnabledCRLExtensions.contains(id)) {
+ nvp.put(PROP_ENABLE, Constants.TRUE);
+ } else {
+ nvp.put(PROP_ENABLE, Constants.FALSE);
+ }
+ if (mCriticalCRLExtensions.contains(id)) {
+ nvp.put(PROP_CRITICAL, Constants.TRUE);
+ } else {
+ nvp.put(PROP_CRITICAL, Constants.FALSE);
+ }
+
+ if (mCRLExtensionClassNames.containsKey(id)) {
+ String name = mCRLExtensionClassNames.get(id);
+
+ if (name != null) {
+
+ try {
+ Class<?> extClass = Class.forName(name);
+
+ if (extClass != null) {
+ ICMSCRLExtension cmsCRLExt = (ICMSCRLExtension) extClass.newInstance();
+
+ if (cmsCRLExt != null) {
+ cmsCRLExt.getConfigParams(mCRLExtConfig.getSubStore(id), nvp);
+ }
+ }
+ } catch (ClassNotFoundException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CRLEXTS_CLASS_NOT_FOUND", name, e.toString()));
+ } catch (InstantiationException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CRLEXTS_CLASS_NOT_INST", name, e.toString()));
+ } catch (IllegalAccessException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CRLEXTS_CLASS_NOT_ACCESS", name, e.toString()));
+ }
+
+ int i = name.lastIndexOf('.');
+
+ if ((i > -1) && (i + 1 < name.length())) {
+ String idName = name.substring(i + 1);
+
+ if (idName != null) {
+ nvp.put(Constants.PR_CRLEXT_IMPL_NAME, idName);
+ }
+ }
+ }
+ }
+ }
+ return nvp;
+ }
+
+ public void setConfigParams(String id, NameValuePairs nvp, IConfigStore config) {
+ ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ String ipId = nvp.get("id");
+
+ ICRLIssuingPoint ip = null;
+ if (ipId != null && ca != null) {
+ ip = ca.getCRLIssuingPoint(ipId);
+ }
+
+ for (String name : nvp.keySet()) {
+ String value = nvp.get(name);
+
+ if (name.equals(PROP_ENABLE)) {
+ if (!(value.equals(Constants.TRUE) || value.equals(Constants.FALSE))) {
+ continue;
+ }
+ if (value.equals(Constants.TRUE)) {
+ if (!(mEnabledCRLExtensions.contains(id))) {
+ mEnabledCRLExtensions.addElement(id);
+ }
+ }
+ if (value.equals(Constants.FALSE)) {
+ mEnabledCRLExtensions.remove(id);
+ }
+ }
+
+ if (name.equals(PROP_CRITICAL)) {
+ if (!(value.equals(Constants.TRUE) || value.equals(Constants.FALSE))) {
+ continue;
+ }
+ if (value.equals(Constants.TRUE)) {
+ if (!(mCriticalCRLExtensions.contains(id))) {
+ mCriticalCRLExtensions.addElement(id);
+ }
+ }
+ if (value.equals(Constants.FALSE)) {
+ mCriticalCRLExtensions.remove(id);
+ }
+ }
+ //Sync the onlyContainsCACerts with similar property in CRLIssuingPoint
+ //called caCertsOnly.
+ if (name.equals(CMSIssuingDistributionPointExtension.PROP_CACERTS)) {
+ NameValuePairs crlIssuingPointPairs = null;
+ boolean crlCACertsOnly = false;
+
+ boolean issuingDistPointExtEnabled = false;
+
+ CMSCRLExtensions cmsCRLExtensions = (CMSCRLExtensions) ip.getCRLExtensions();
+ if (cmsCRLExtensions != null) {
+ issuingDistPointExtEnabled =
+ cmsCRLExtensions.isCRLExtensionEnabled(IssuingDistributionPointExtension.NAME);
+ }
+
+ CMS.debug("issuingDistPointExtEnabled = " + issuingDistPointExtEnabled);
+
+ if (!(value.equals(Constants.TRUE) || value.equals(Constants.FALSE))) {
+ continue;
+ }
+
+ //Get value of caCertsOnly from CRLIssuingPoint
+ if ((ip != null) && (issuingDistPointExtEnabled == true)) {
+ crlCACertsOnly = ip.isCACertsOnly();
+ CMS.debug("CRLCACertsOnly is: " + crlCACertsOnly);
+ crlIssuingPointPairs = new NameValuePairs();
+
+ }
+
+ String newValue = "";
+ boolean modifiedCRLConfig = false;
+ //If the CRLCACertsOnly prop is false change it to true to sync.
+ if (value.equals(Constants.TRUE) && (issuingDistPointExtEnabled == true)) {
+ if (crlCACertsOnly == false) {
+ CMS.debug(" value = true and CRLCACertsOnly is already false.");
+ crlIssuingPointPairs.put(Constants.PR_CA_CERTS_ONLY, Constants.TRUE);
+ newValue = Constants.TRUE;
+ ip.updateConfig(crlIssuingPointPairs);
+ modifiedCRLConfig = true;
+ }
+ }
+
+ //If the CRLCACertsOnly prop is true change it to false to sync.
+ if (value.equals(Constants.FALSE) && (issuingDistPointExtEnabled == true)) {
+ crlIssuingPointPairs.put(Constants.PR_CA_CERTS_ONLY, Constants.FALSE);
+ if (ip != null) {
+ ip.updateConfig(crlIssuingPointPairs);
+ newValue = Constants.FALSE;
+ modifiedCRLConfig = true;
+ }
+ }
+
+ if (modifiedCRLConfig == true) {
+ //Commit to this CRL IssuingPoint's config store
+ ICertificateAuthority CA = (ICertificateAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ IConfigStore crlsSubStore = CA.getConfigStore();
+ crlsSubStore = crlsSubStore.getSubStore(ICertificateAuthority.PROP_CRL_SUBSTORE);
+ crlsSubStore = crlsSubStore.getSubStore(ipId);
+ try {
+ crlsSubStore.putString(Constants.PR_CA_CERTS_ONLY, newValue);
+ crlsSubStore.commit(true);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CRLEXTS_SAVE_CONF", e.toString()));
+ }
+ }
+ }
+
+ config.putString(name, value);
+ }
+ }
+
+ public String getClassPath(String name) {
+ Enumeration<String> enum1 = mCRLExtensionClassNames.elements();
+
+ while (enum1.hasMoreElements()) {
+ String extClassName = enum1.nextElement();
+
+ if (extClassName != null) {
+ int i = extClassName.lastIndexOf('.');
+
+ if ((i > -1) && (i + 1 < extClassName.length())) {
+ String idName = extClassName.substring(i + 1);
+
+ if (idName != null) {
+ if (name.equals(idName)) {
+ return extClassName;
+ }
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_CA, level,
+ "CMSCRLExtension - " + msg);
+ }
+}
diff --git a/base/ca/src/com/netscape/ca/CRLIssuingPoint.java b/base/ca/src/com/netscape/ca/CRLIssuingPoint.java
new file mode 100644
index 000000000..d4b747b32
--- /dev/null
+++ b/base/ca/src/com/netscape/ca/CRLIssuingPoint.java
@@ -0,0 +1,3140 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.ca;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CRLException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.TimeZone;
+import java.util.Vector;
+
+import netscape.security.util.BitArray;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLNumberExtension;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.DeltaCRLIndicatorExtension;
+import netscape.security.x509.Extension;
+import netscape.security.x509.FreshestCRLExtension;
+import netscape.security.x509.IssuingDistributionPoint;
+import netscape.security.x509.IssuingDistributionPointExtension;
+import netscape.security.x509.RevocationReason;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.RevokedCertificate;
+import netscape.security.x509.X509CRLImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509ExtensionException;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.ca.ECAException;
+import com.netscape.certsrv.ca.EErrorPublishCRL;
+import com.netscape.certsrv.ca.ICMSCRLExtensions;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.dbs.EDBNotAvailException;
+import com.netscape.certsrv.dbs.IElementProcessor;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.dbs.certdb.IRevocationInfo;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.dbs.crldb.ICRLRepository;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.ILdapRule;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestListener;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.IRequestVirtualList;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.util.IStatsSubsystem;
+import com.netscape.cmscore.dbs.CRLIssuingPointRecord;
+import com.netscape.cmscore.dbs.CertRecord;
+import com.netscape.cmscore.dbs.CertificateRepository;
+import com.netscape.cmscore.util.Debug;
+
+/**
+ * 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
+ * <P>
+ *
+ * @author awnuk
+ * @author lhsiao
+ * @author galperin
+ * @version $Revision$, $Date$
+ */
+
+public class CRLIssuingPoint implements ICRLIssuingPoint, Runnable {
+
+ /* Foreign config param for IssuingDistributionPointExtension. */
+ public static final String PROP_CACERTS = "onlyContainsCACerts";
+
+ public static final long SECOND = 1000L;
+ public static final long MINUTE = (SECOND * 60L);
+
+ private static final int CRL_PAGE_SIZE = 10000;
+
+ /* configuration file property names */
+
+ public IPublisherProcessor mPublisherProcessor = null;
+
+ private ILogger mLogger = CMS.getLogger();
+
+ private IConfigStore mConfigStore;
+
+ private int mCountMod = 0;
+ private int mCount = 0;
+ private int mPageSize = CRL_PAGE_SIZE;
+
+ private CMSCRLExtensions mCMSCRLExtensions = null;
+
+ /**
+ * Internal unique id of this CRL issuing point.
+ */
+ protected String mId = null;
+
+ /**
+ * Reference to the CertificateAuthority instance which owns this
+ * issuing point.
+ */
+ protected ICertificateAuthority mCA = null;
+
+ /**
+ * Reference to the CRL repository maintained in CA.
+ */
+ protected ICRLRepository mCRLRepository = null;
+
+ /**
+ * Reference to the cert repository maintained in CA.
+ */
+ private ICertificateRepository mCertRepository = null;
+
+ /**
+ * Enable CRL issuing point.
+ */
+ private boolean mEnable = true;
+
+ /**
+ * Description of the issuing point
+ */
+ private String mDescription = null;
+
+ /**
+ * CRL cache
+ */
+ private Hashtable<BigInteger, RevokedCertificate> mCRLCerts = new Hashtable<BigInteger, RevokedCertificate>();
+ private Hashtable<BigInteger, RevokedCertificate> mRevokedCerts = new Hashtable<BigInteger, RevokedCertificate>();
+ private Hashtable<BigInteger, RevokedCertificate> mUnrevokedCerts = new Hashtable<BigInteger, RevokedCertificate>();
+ private Hashtable<BigInteger, RevokedCertificate> mExpiredCerts = new Hashtable<BigInteger, RevokedCertificate>();
+ private boolean mIncludeExpiredCerts = false;
+ private boolean mIncludeExpiredCertsOneExtraTime = false;
+ private boolean mCACertsOnly = false;
+
+ private boolean mProfileCertsOnly = false;
+ private Vector<String> mProfileList = null;
+
+ /**
+ * Enable CRL cache.
+ */
+ private boolean mEnableCRLCache = true;
+ private boolean mCRLCacheIsCleared = true;
+ private boolean mEnableCacheRecovery = false;
+ private String mFirstUnsaved = null;
+ private boolean mEnableCacheTesting = false;
+
+ /**
+ * Last CRL cache update
+ */
+ private long mLastCacheUpdate = 0;
+
+ /**
+ * Time interval in milliseconds between consequential CRL cache
+ * updates performed automatically.
+ */
+ private long mCacheUpdateInterval;
+
+ /**
+ * Enable CRL updates.
+ */
+ private boolean mEnableCRLUpdates = true;
+
+ /**
+ * CRL update schema.
+ */
+ private int mUpdateSchema = 1;
+ private int mSchemaCounter = 0;
+
+ /**
+ * Enable CRL daily updates at listed times.
+ */
+ private boolean mEnableDailyUpdates = false;
+ private Vector<Vector<Integer>> mDailyUpdates = null;
+ private int mCurrentDay = 0;
+ private int mLastDay = 0;
+ private int mTimeListSize = 0;
+ private boolean mExtendedTimeList = false;
+
+ /**
+ * Enable CRL auto update with interval
+ */
+ private boolean mEnableUpdateFreq = false;
+
+ /**
+ * Time interval in milliseconds between consequential CRL Enable CRL daily update at updates
+ * performed automatically.
+ */
+ private long mAutoUpdateInterval;
+
+ /**
+ * Minimum time interval in milliseconds between consequential
+ * CRL updates (manual or automatic).
+ */
+ private long mMinUpdateInterval;
+
+ /**
+ * Update CRL even if auto interval > 0
+ */
+ private boolean mAlwaysUpdate = false;
+
+ /**
+ * next update grace period
+ */
+ private long mNextUpdateGracePeriod;
+
+ /**
+ * Boolean flag controlling whether CRLv2 extensions are to be
+ * used in CRL.
+ */
+ private boolean mAllowExtensions = false;
+
+ /**
+ * DN of the directory entry where CRLs from this issuing point
+ * are published.
+ */
+ private String mPublishDN = null;
+
+ /**
+ * signing algorithm
+ */
+ private String mSigningAlgorithm = null;
+ private String mLastSigningAlgorithm = null;
+
+ /**
+ * Cached value of the CRL extensions to be placed in CRL
+ */
+ //protected CRLExtensions mCrlExtensions;
+
+ /**
+ * CRL number
+ */
+ private BigInteger mCRLNumber;
+ private BigInteger mNextCRLNumber;
+ private BigInteger mLastCRLNumber;
+
+ /**
+ * Delta CRL number
+ */
+ private BigInteger mDeltaCRLNumber;
+ private BigInteger mNextDeltaCRLNumber;
+
+ /**
+ * Last CRL update date
+ */
+ private Date mLastUpdate;
+ private Date mLastFullUpdate;
+ private long mLastScheduledUpdate = 0;
+
+ /**
+ * Next scheduled CRL update date
+ */
+ private Date mNextUpdate;
+ private Date mNextDeltaUpdate;
+ private boolean mExtendedNextUpdate;
+
+ /**
+ * Worker thread doing auto-update
+ */
+ private Thread mUpdateThread = null;
+
+ /**
+ * for going one more round when auto-interval is set to 0 (turned off)
+ */
+ private boolean mDoLastAutoUpdate = false;
+
+ /**
+ * whether issuing point has been initialized.
+ */
+ private int mInitialized = CRL_IP_NOT_INITIALIZED;
+
+ /**
+ * number of entries in the CRL
+ */
+ private long mCRLSize = -1;
+ private long mDeltaCRLSize = -1;
+
+ /**
+ * update status, publishing status Strings to store in requests to
+ * display result.
+ */
+ private String mCrlUpdateStatus;
+ private String mCrlUpdateError;
+ private String mCrlPublishStatus;
+ private String mCrlPublishError;
+
+ /**
+ * begin, end serial number range of revoked certs if any.
+ */
+ protected BigInteger mBeginSerial = null;
+ protected BigInteger mEndSerial = null;
+
+ private int mUpdatingCRL = CRL_UPDATE_DONE;
+
+ private boolean mDoManualUpdate = false;
+ private String mSignatureAlgorithmForManualUpdate = null;
+
+ private boolean mPublishOnStart = false;
+ private long[] mSplits = new long[10];
+
+ private boolean mSaveMemory = false;
+
+ /**
+ * Constructs a CRL issuing point from instantiating from class name.
+ * CRL Issuing point must be followed by method call init(CA, id, config);
+ */
+ public CRLIssuingPoint() {
+ }
+
+ public boolean isCRLIssuingPointEnabled() {
+ return mEnable;
+ }
+
+ public void enableCRLIssuingPoint(boolean enable) {
+ if ((!enable) && (mEnable ^ enable)) {
+ clearCRLCache();
+ updateCRLCacheRepository();
+ }
+ mEnable = enable;
+ setAutoUpdates();
+ }
+
+ public boolean isCRLGenerationEnabled() {
+ return mEnableCRLUpdates;
+ }
+
+ public String getCrlUpdateStatusStr() {
+ return mCrlUpdateStatus;
+ }
+
+ public String getCrlUpdateErrorStr() {
+ return mCrlUpdateError;
+ }
+
+ public String getCrlPublishStatusStr() {
+ return mCrlPublishStatus;
+ }
+
+ public String getCrlPublishErrorStr() {
+ return mCrlPublishError;
+ }
+
+ public ICMSCRLExtensions getCRLExtensions() {
+ return mCMSCRLExtensions;
+ }
+
+ public int isCRLIssuingPointInitialized() {
+ return mInitialized;
+ }
+
+ public boolean isManualUpdateSet() {
+ return mDoManualUpdate;
+ }
+
+ public boolean areExpiredCertsIncluded() {
+ return mIncludeExpiredCerts;
+ }
+
+ public boolean isCACertsOnly() {
+ return mCACertsOnly;
+ }
+
+ public boolean isProfileCertsOnly() {
+ return (mProfileCertsOnly && mProfileList != null && mProfileList.size() > 0);
+ }
+
+ public boolean checkCurrentProfile(String id) {
+ boolean b = false;
+
+ if (mProfileCertsOnly && mProfileList != null && mProfileList.size() > 0) {
+ for (int k = 0; k < mProfileList.size(); k++) {
+ String profileId = mProfileList.elementAt(k);
+ if (id != null && profileId != null && profileId.equalsIgnoreCase(id)) {
+ b = true;
+ break;
+ }
+ }
+ }
+
+ return b;
+ }
+
+ /**
+ * Initializes a CRL issuing point config.
+ * <P>
+ *
+ * @param ca reference to CertificateAuthority instance which
+ * owns this issuing point.
+ * @param id string id of this CRL issuing point.
+ * @param config configuration of this CRL issuing point.
+ * @exception EBaseException if initialization failed
+ * @exception IOException
+ */
+ public void init(ISubsystem ca, String id, IConfigStore config)
+ throws EBaseException {
+ mCA = (ICertificateAuthority) ca;
+ mId = id;
+
+ if (mId.equals(ICertificateAuthority.PROP_MASTER_CRL)) {
+ mCrlUpdateStatus = IRequest.CRL_UPDATE_STATUS;
+ mCrlUpdateError = IRequest.CRL_UPDATE_ERROR;
+ mCrlPublishStatus = IRequest.CRL_PUBLISH_STATUS;
+ mCrlPublishError = IRequest.CRL_PUBLISH_ERROR;
+ } else {
+ mCrlUpdateStatus = IRequest.CRL_UPDATE_STATUS + "_" + mId;
+ mCrlUpdateError = IRequest.CRL_UPDATE_ERROR + "_" + mId;
+ mCrlPublishStatus = IRequest.CRL_PUBLISH_STATUS + "_" + mId;
+ mCrlPublishError = IRequest.CRL_PUBLISH_ERROR + "_" + mId;
+ }
+
+ mConfigStore = config;
+
+ IConfigStore crlSubStore = mCA.getConfigStore().getSubStore(ICertificateAuthority.PROP_CRL_SUBSTORE);
+ mPageSize = crlSubStore.getInteger(ICertificateAuthority.PROP_CRL_PAGE_SIZE, CRL_PAGE_SIZE);
+ CMS.debug("CRL Page Size: " + mPageSize);
+
+ mCountMod = config.getInteger("countMod", 0);
+ mCRLRepository = mCA.getCRLRepository();
+ mCertRepository = mCA.getCertificateRepository();
+ ((CertificateRepository) mCertRepository).addCRLIssuingPoint(mId, this);
+ mPublisherProcessor = mCA.getPublisherProcessor();
+
+ //mCRLPublisher = mCA.getCRLPublisher();
+ ((CAService) mCA.getCAService()).addCRLIssuingPoint(mId, this);
+
+ // read in config parameters.
+ initConfig(config);
+
+ // create request listener.
+ String lname = RevocationRequestListener.class.getName();
+ String crlListName = lname + "_" + mId;
+
+ if (mCA.getRequestListener(crlListName) == null) {
+ mCA.registerRequestListener(
+ crlListName, new RevocationRequestListener());
+ }
+
+ for (int i = 0; i < mSplits.length; i++) {
+ mSplits[i] = 0;
+ }
+
+ // this will start a thread if necessary for automatic updates.
+ setAutoUpdates();
+ }
+
+ private int checkTime(String time) {
+ String digits = "0123456789";
+
+ int len = time.length();
+ if (len < 3 || len > 5)
+ return -1;
+
+ int s = time.indexOf(':');
+ if (s < 0 || s > 2 || (len - s) != 3)
+ return -1;
+
+ int h = 0;
+ for (int i = 0; i < s; i++) {
+ h *= 10;
+ int k = digits.indexOf(time.charAt(i));
+ if (k < 0)
+ return -1;
+ h += k;
+ }
+ if (h > 23)
+ return -1;
+
+ int m = 0;
+ for (int i = s + 1; i < len; i++) {
+ m *= 10;
+ int k = digits.indexOf(time.charAt(i));
+ if (k < 0)
+ return -1;
+ m += k;
+ }
+ if (m > 59)
+ return -1;
+
+ return ((h * 60) + m);
+ }
+
+ private boolean areTimeListsIdentical(Vector<Vector<Integer>> list1, Vector<Vector<Integer>> list2) {
+ boolean identical = true;
+ if (list1 == null || list2 == null)
+ identical = false;
+ if (identical && list1.size() != list2.size())
+ identical = false;
+ for (int i = 0; identical && i < list1.size(); i++) {
+ Vector<Integer> times1 = list1.elementAt(i);
+ Vector<Integer> times2 = list2.elementAt(i);
+ if (times1.size() != times2.size())
+ identical = false;
+ for (int j = 0; identical && j < times1.size(); j++) {
+ if ((((times1.elementAt(j))).intValue()) != (((times2.elementAt(j))).intValue())) {
+ identical = false;
+ }
+ }
+ }
+ CMS.debug("areTimeListsIdentical: identical: " + identical);
+ return identical;
+ }
+
+ private int getTimeListSize(Vector<Vector<Integer>> listedDays) {
+ int listSize = 0;
+ for (int i = 0; listedDays != null && i < listedDays.size(); i++) {
+ Vector<Integer> listedTimes = listedDays.elementAt(i);
+ listSize += ((listedTimes != null) ? listedTimes.size() : 0);
+ }
+ CMS.debug("getTimeListSize: ListSize=" + listSize);
+ return listSize;
+ }
+
+ private boolean isTimeListExtended(String list) {
+ boolean extendedTimeList = true;
+ if (list == null || list.indexOf('*') == -1)
+ extendedTimeList = false;
+ return extendedTimeList;
+ }
+
+ private Vector<Vector<Integer>> getTimeList(String list) {
+ boolean timeListPresent = false;
+ if (list == null || list.length() == 0)
+ return null;
+ if (list.charAt(0) == ',' || list.charAt(list.length() - 1) == ',')
+ return null;
+
+ Vector<Vector<Integer>> listedDays = new Vector<Vector<Integer>>();
+
+ StringTokenizer days = new StringTokenizer(list, ";", true);
+ Vector<Integer> listedTimes = null;
+ while (days.hasMoreTokens()) {
+ String dayList = days.nextToken().trim();
+ if (dayList == null)
+ continue;
+
+ if (dayList.equals(";")) {
+ if (timeListPresent) {
+ timeListPresent = false;
+ } else {
+ listedTimes = new Vector<Integer>();
+ listedDays.addElement(listedTimes);
+ }
+ continue;
+ } else {
+ listedTimes = new Vector<Integer>();
+ listedDays.addElement(listedTimes);
+ timeListPresent = true;
+ }
+ int t0 = -1;
+ StringTokenizer times = new StringTokenizer(dayList, ",");
+ while (times.hasMoreTokens()) {
+ String time = times.nextToken();
+ int k = 1;
+ if (time.charAt(0) == '*') {
+ time = time.substring(1);
+ k = -1;
+ }
+ int t = checkTime(time);
+ if (t < 0) {
+ return null;
+ } else {
+ if (t > t0) {
+ listedTimes.addElement(new Integer(k * t));
+ t0 = t;
+ } else {
+ return null;
+ }
+ }
+ }
+ }
+ if (!timeListPresent) {
+ listedTimes = new Vector<Integer>();
+ listedDays.addElement(listedTimes);
+ }
+
+ return listedDays;
+ }
+
+ private String checkProfile(String id, Enumeration<String> e) {
+ if (e != null) {
+ while (e.hasMoreElements()) {
+ String profileId = e.nextElement();
+ if (profileId != null && profileId.equalsIgnoreCase(id))
+ return id;
+ }
+ }
+ return null;
+ }
+
+ private Vector<String> getProfileList(String list) {
+ Enumeration<String> e = null;
+ IConfigStore pc = CMS.getConfigStore().getSubStore("profile");
+ if (pc != null)
+ e = pc.getSubStoreNames();
+ if (list == null)
+ return null;
+ if (list.length() > 0 && list.charAt(list.length() - 1) == ',')
+ return null;
+
+ Vector<String> listedProfiles = new Vector<String>();
+
+ StringTokenizer elements = new StringTokenizer(list, ",", true);
+ int n = 0;
+ while (elements.hasMoreTokens()) {
+ String element = elements.nextToken().trim();
+ if (element == null || element.length() == 0)
+ return null;
+ if (element.equals(",") && n % 2 == 0)
+ return null;
+ if (n % 2 == 0) {
+ String id = checkProfile(element, e);
+ if (id != null) {
+ listedProfiles.addElement(id);
+ }
+ }
+ n++;
+ }
+ if (n % 2 == 0)
+ return null;
+
+ return listedProfiles;
+ }
+
+ /**
+ * get CRL config store info
+ */
+ protected void initConfig(IConfigStore config)
+ throws EBaseException {
+
+ mEnable = config.getBoolean(Constants.PR_ENABLE, true);
+ mDescription = config.getString(Constants.PR_DESCRIPTION);
+
+ // Get CRL cache config.
+ mEnableCRLCache = config.getBoolean(Constants.PR_ENABLE_CACHE, true);
+ mCacheUpdateInterval = MINUTE * config.getInteger(Constants.PR_CACHE_FREQ, 0);
+ mEnableCacheRecovery = config.getBoolean(Constants.PR_CACHE_RECOVERY, false);
+ mEnableCacheTesting = config.getBoolean(Constants.PR_CACHE_TESTING, false);
+
+ // check if CRL generation is enabled
+ mEnableCRLUpdates = config.getBoolean(Constants.PR_ENABLE_CRL, true);
+
+ // get update schema
+ mUpdateSchema = config.getInteger(Constants.PR_UPDATE_SCHEMA, 1);
+ mSchemaCounter = 0;
+
+ // Get always update even if updated perdically.
+ mAlwaysUpdate = config.getBoolean(Constants.PR_UPDATE_ALWAYS, false);
+
+ // Get list of daily updates.
+ mEnableDailyUpdates = config.getBoolean(Constants.PR_ENABLE_DAILY, false);
+ String daily = config.getString(Constants.PR_DAILY_UPDATES, null);
+ mDailyUpdates = getTimeList(daily);
+ mExtendedTimeList = isTimeListExtended(daily);
+ mTimeListSize = getTimeListSize(mDailyUpdates);
+ if (mDailyUpdates == null || mDailyUpdates.isEmpty() || mTimeListSize == 0) {
+ mEnableDailyUpdates = false;
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_INVALID_TIME_LIST"));
+ }
+
+ // Get auto update interval in minutes.
+ mEnableUpdateFreq = config.getBoolean(Constants.PR_ENABLE_FREQ, true);
+ mAutoUpdateInterval = MINUTE * config.getInteger(Constants.PR_UPDATE_FREQ, 0);
+ mMinUpdateInterval = MINUTE * config.getInteger(PROP_MIN_UPDATE_INTERVAL, 0);
+ if (mEnableUpdateFreq && mAutoUpdateInterval > 0 &&
+ mAutoUpdateInterval < mMinUpdateInterval)
+ mAutoUpdateInterval = mMinUpdateInterval;
+
+ // get next update grace period
+ mNextUpdateGracePeriod = MINUTE * config.getInteger(Constants.PR_GRACE_PERIOD, 0);
+
+ // Get V2 or V1 CRL
+ mAllowExtensions = config.getBoolean(Constants.PR_EXTENSIONS, false);
+
+ mIncludeExpiredCerts = config.getBoolean(Constants.PR_INCLUDE_EXPIREDCERTS, false);
+ mIncludeExpiredCertsOneExtraTime = config.getBoolean(Constants.PR_INCLUDE_EXPIREDCERTS_ONEEXTRATIME, false);
+ mCACertsOnly = config.getBoolean(Constants.PR_CA_CERTS_ONLY, false);
+ mProfileCertsOnly = config.getBoolean(Constants.PR_PROFILE_CERTS_ONLY, false);
+ if (mProfileCertsOnly) {
+ String profiles = config.getString(Constants.PR_PROFILE_LIST, null);
+ mProfileList = getProfileList(profiles);
+ }
+
+ // Get default signing algorithm.
+ // check if algorithm is supported.
+ mSigningAlgorithm = mCA.getCRLSigningUnit().getDefaultAlgorithm();
+ String algorithm = config.getString(Constants.PR_SIGNING_ALGORITHM, null);
+
+ if (algorithm != null) {
+ // make sure this algorithm is acceptable to CA.
+ mCA.getCRLSigningUnit().checkSigningAlgorithmFromName(algorithm);
+ mSigningAlgorithm = algorithm;
+ }
+
+ mPublishOnStart = config.getBoolean(PROP_PUBLISH_ON_START, false);
+ // if publish dn is null then certificate will be published to
+ // CA's entry in the directory.
+ mPublishDN = config.getString(PROP_PUBLISH_DN, null);
+
+ mSaveMemory = config.getBoolean("saveMemory", false);
+
+ mCMSCRLExtensions = new CMSCRLExtensions(this, config);
+
+ mExtendedNextUpdate =
+ ((mUpdateSchema > 1 || (mEnableDailyUpdates && mExtendedTimeList)) && isDeltaCRLEnabled()) ?
+ config.getBoolean(Constants.PR_EXTENDED_NEXT_UPDATE, true) :
+ false;
+
+ // Get serial number ranges if any.
+ mBeginSerial = config.getBigInteger(PROP_BEGIN_SERIAL, null);
+ if (mBeginSerial != null && mBeginSerial.compareTo(BigInteger.ZERO) < 0) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_PROPERTY_1",
+ PROP_BEGIN_SERIAL, "BigInteger", "positive number"));
+ }
+ mEndSerial = config.getBigInteger(PROP_END_SERIAL, null);
+ if (mEndSerial != null && mEndSerial.compareTo(BigInteger.ZERO) < 0) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_PROPERTY_1",
+ PROP_END_SERIAL, "BigInteger", "positive number"));
+ }
+ }
+
+ /**
+ * Reads CRL issuing point, if missing, it creates one.
+ * Initializes CRL cache and republishes CRL if requested
+ * Called from auto update thread (run()).
+ * Do not call it from init(), because it will block CMS on start.
+ */
+ private void initCRL() {
+ ICRLIssuingPointRecord crlRecord = null;
+
+ mLastCacheUpdate = System.currentTimeMillis() + mCacheUpdateInterval;
+
+ try {
+ crlRecord = mCRLRepository.readCRLIssuingPointRecord(mId);
+ } catch (EDBNotAvailException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_INST_CRL", e.toString()));
+ mInitialized = CRL_IP_INITIALIZATION_FAILED;
+ return;
+ } catch (EBaseException e) {
+ // CRL was never set.
+ // fall to the following..
+ }
+
+ if (crlRecord != null) {
+ mCRLNumber = crlRecord.getCRLNumber();
+ if (crlRecord.getCRLSize() != null) {
+ mCRLSize = crlRecord.getCRLSize().longValue();
+ }
+ mNextCRLNumber = mCRLNumber.add(BigInteger.ONE);
+
+ if (crlRecord.getDeltaCRLSize() != null) {
+ mDeltaCRLSize = crlRecord.getDeltaCRLSize().longValue();
+ }
+
+ mDeltaCRLNumber = crlRecord.getDeltaCRLNumber();
+ if (mDeltaCRLNumber == null) {
+ mDeltaCRLNumber = mCRLNumber; // better recovery later
+ } else {
+ if (mDeltaCRLNumber.compareTo(mCRLNumber) < 0) {
+ mDeltaCRLNumber = mCRLNumber;
+ clearCRLCache();
+ mDeltaCRLSize = -1L;
+ }
+ }
+ mNextDeltaCRLNumber = mDeltaCRLNumber.add(BigInteger.ONE);
+
+ if (mNextDeltaCRLNumber.compareTo(mNextCRLNumber) > 0) {
+ mNextCRLNumber = mNextDeltaCRLNumber;
+ }
+
+ mLastCRLNumber = BigInteger.ZERO;
+
+ mLastUpdate = crlRecord.getThisUpdate();
+ if (mLastUpdate == null) {
+ mLastUpdate = new Date(0L);
+ }
+ mLastFullUpdate = null;
+
+ mNextUpdate = crlRecord.getNextUpdate();
+ if (isDeltaCRLEnabled()) {
+ mNextDeltaUpdate = (mNextUpdate != null) ? new Date(mNextUpdate.getTime()) : null;
+ }
+
+ mFirstUnsaved = crlRecord.getFirstUnsaved();
+ if (Debug.on()) {
+ Debug.trace("initCRL CRLNumber=" + mCRLNumber.toString() + " CRLSize=" + mCRLSize +
+ " FirstUnsaved=" + mFirstUnsaved);
+ }
+ if (mFirstUnsaved == null ||
+ (mFirstUnsaved != null && mFirstUnsaved.equals(ICRLIssuingPointRecord.NEW_CACHE))) {
+ clearCRLCache();
+ updateCRLCacheRepository();
+ } else {
+ byte[] crl = crlRecord.getCRL();
+
+ if (crl != null) {
+ X509CRLImpl x509crl = null;
+
+ if (mEnableCRLCache || mPublishOnStart) {
+ try {
+ x509crl = new X509CRLImpl(crl);
+ } catch (Exception e) {
+ clearCRLCache();
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_DECODE_CRL", e.toString()));
+ } catch (OutOfMemoryError e) {
+ clearCRLCache();
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_DECODE_CRL", e.toString()));
+ mInitialized = CRL_IP_INITIALIZATION_FAILED;
+ return;
+ }
+ }
+ if (x509crl != null) {
+ mLastFullUpdate = x509crl.getThisUpdate();
+ if (mEnableCRLCache) {
+ if (mCRLCacheIsCleared && mUpdatingCRL == CRL_UPDATE_DONE) {
+ mRevokedCerts = crlRecord.getRevokedCerts();
+ if (mRevokedCerts == null) {
+ mRevokedCerts = new Hashtable<BigInteger, RevokedCertificate>();
+ }
+ mUnrevokedCerts = crlRecord.getUnrevokedCerts();
+ if (mUnrevokedCerts == null) {
+ mUnrevokedCerts = new Hashtable<BigInteger, RevokedCertificate>();
+ }
+ mExpiredCerts = crlRecord.getExpiredCerts();
+ if (mExpiredCerts == null) {
+ mExpiredCerts = new Hashtable<BigInteger, RevokedCertificate>();
+ }
+ if (isDeltaCRLEnabled()) {
+ mNextUpdate = x509crl.getNextUpdate();
+ }
+ mCRLCerts = x509crl.getListOfRevokedCertificates();
+ }
+ if (mFirstUnsaved != null && !mFirstUnsaved.equals(ICRLIssuingPointRecord.CLEAN_CACHE)) {
+ recoverCRLCache();
+ } else {
+ mCRLCacheIsCleared = false;
+ }
+ mInitialized = CRL_IP_INITIALIZED;
+ }
+ if (mPublishOnStart) {
+ try {
+ publishCRL(x509crl);
+ x509crl = null;
+ } catch (EBaseException e) {
+ x509crl = null;
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_ISSUING_PUBLISH_CRL", mCRLNumber.toString(),
+ e.toString()));
+ } catch (OutOfMemoryError e) {
+ x509crl = null;
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_ISSUING_PUBLISH_CRL", mCRLNumber.toString(),
+ e.toString()));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (crlRecord == null) {
+ // no crl was ever created, or crl in db is corrupted.
+ // create new one.
+ try {
+ crlRecord = new CRLIssuingPointRecord(mId, BigInteger.ZERO, Long.valueOf(-1),
+ null, null, BigInteger.ZERO, Long.valueOf(-1),
+ mRevokedCerts, mUnrevokedCerts, mExpiredCerts);
+ mCRLRepository.addCRLIssuingPointRecord(crlRecord);
+ mCRLNumber = BigInteger.ZERO; //BIG_ZERO;
+ mNextCRLNumber = BigInteger.ONE; //BIG_ONE;
+ mLastCRLNumber = mCRLNumber;
+ mDeltaCRLNumber = mCRLNumber;
+ mNextDeltaCRLNumber = mNextCRLNumber;
+ mLastUpdate = new Date(0L);
+ if (crlRecord != null) {
+ // This will trigger updateCRLNow, which will also publish CRL.
+ if ((mDoManualUpdate == false) &&
+ (mEnableCRLCache || mAlwaysUpdate ||
+ (mEnableUpdateFreq && mAutoUpdateInterval > 0))) {
+ mInitialized = CRL_IP_INITIALIZED;
+ setManualUpdate(null);
+ }
+ }
+ } catch (EBaseException ex) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_CREATE_CRL", ex.toString()));
+ mInitialized = CRL_IP_INITIALIZATION_FAILED;
+ return;
+ }
+ }
+ mInitialized = CRL_IP_INITIALIZED;
+ }
+
+ private Object configMonitor = new Object();
+
+ public boolean updateConfig(NameValuePairs params) {
+ synchronized (configMonitor) {
+ boolean noRestart = true;
+ boolean modifiedSchedule = false;
+
+ for (String name : params.keySet()) {
+ String value = params.get(name);
+
+ // -- Update Schema --
+ if (name.equals(Constants.PR_ENABLE_CRL)) {
+ if (value.equals(Constants.FALSE) && mEnableCRLUpdates) {
+ mEnableCRLUpdates = false;
+ modifiedSchedule = true;
+ } else if (value.equals(Constants.TRUE) && (!mEnableCRLUpdates)) {
+ mEnableCRLUpdates = true;
+ modifiedSchedule = true;
+ }
+ }
+
+ if (name.equals(Constants.PR_UPDATE_SCHEMA)) {
+ try {
+ if (value != null && value.length() > 0) {
+ int schema = Integer.parseInt(value.trim());
+ if (mUpdateSchema != schema) {
+ mUpdateSchema = schema;
+ mSchemaCounter = 0;
+ modifiedSchedule = true;
+ }
+ }
+ } catch (NumberFormatException e) {
+ noRestart = false;
+ }
+ }
+
+ if (name.equals(Constants.PR_EXTENDED_NEXT_UPDATE)) {
+ if (value.equals(Constants.FALSE) && mExtendedNextUpdate) {
+ mExtendedNextUpdate = false;
+ } else if (value.equals(Constants.TRUE) && (!mExtendedNextUpdate)) {
+ mExtendedNextUpdate = true;
+ }
+ }
+
+ // -- Update Frequency --
+ if (name.equals(Constants.PR_UPDATE_ALWAYS)) {
+ if (value.equals(Constants.FALSE) && mAlwaysUpdate) {
+ mAlwaysUpdate = false;
+ } else if (value.equals(Constants.TRUE) && (!mAlwaysUpdate)) {
+ mAlwaysUpdate = true;
+ }
+ }
+
+ if (name.equals(Constants.PR_ENABLE_DAILY)) {
+ if (value.equals(Constants.FALSE) && mEnableDailyUpdates) {
+ mEnableDailyUpdates = false;
+ modifiedSchedule = true;
+ } else if (value.equals(Constants.TRUE) && (!mEnableDailyUpdates)) {
+ mEnableDailyUpdates = true;
+ modifiedSchedule = true;
+ }
+ }
+
+ if (name.equals(Constants.PR_DAILY_UPDATES)) {
+ boolean extendedTimeList = isTimeListExtended(value);
+ Vector<Vector<Integer>> dailyUpdates = getTimeList(value);
+ if (mExtendedTimeList != extendedTimeList) {
+ mExtendedTimeList = extendedTimeList;
+ modifiedSchedule = true;
+ }
+ if (!areTimeListsIdentical(mDailyUpdates, dailyUpdates)) {
+ mCurrentDay = 0;
+ mLastDay = 0;
+ mDailyUpdates = dailyUpdates;
+ mTimeListSize = getTimeListSize(mDailyUpdates);
+ modifiedSchedule = true;
+ }
+ if (mDailyUpdates == null || mDailyUpdates.isEmpty() || mTimeListSize == 0) {
+ mEnableDailyUpdates = false;
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_INVALID_TIME_LIST"));
+ }
+ }
+
+ if (name.equals(Constants.PR_ENABLE_FREQ)) {
+ if (value.equals(Constants.FALSE) && mEnableUpdateFreq) {
+ mEnableUpdateFreq = false;
+ modifiedSchedule = true;
+ } else if (value.equals(Constants.TRUE) && (!mEnableUpdateFreq)) {
+ mEnableUpdateFreq = true;
+ modifiedSchedule = true;
+ }
+ }
+
+ if (name.equals(Constants.PR_UPDATE_FREQ)) {
+ try {
+ if (value != null && value.length() > 0) {
+ long t = MINUTE * Long.parseLong(value.trim());
+ if (mAutoUpdateInterval != t) {
+ mAutoUpdateInterval = t;
+ modifiedSchedule = true;
+ }
+ } else {
+ if (mAutoUpdateInterval != 0) {
+ mAutoUpdateInterval = 0;
+ modifiedSchedule = true;
+ }
+ }
+ } catch (NumberFormatException e) {
+ noRestart = false;
+ }
+ }
+
+ if (name.equals(Constants.PR_GRACE_PERIOD)) {
+ try {
+ if (value != null && value.length() > 0) {
+ mNextUpdateGracePeriod = MINUTE * Long.parseLong(value.trim());
+ }
+ } catch (NumberFormatException e) {
+ noRestart = false;
+ }
+ }
+
+ // -- CRL Cache --
+ if (name.equals(Constants.PR_ENABLE_CACHE)) {
+ if (value.equals(Constants.FALSE) && mEnableCRLCache) {
+ clearCRLCache();
+ updateCRLCacheRepository();
+ mEnableCRLCache = false;
+ modifiedSchedule = true;
+ } else if (value.equals(Constants.TRUE) && (!mEnableCRLCache)) {
+ clearCRLCache();
+ updateCRLCacheRepository();
+ mEnableCRLCache = true;
+ modifiedSchedule = true;
+ }
+ }
+
+ if (name.equals(Constants.PR_CACHE_FREQ)) {
+ try {
+ if (value != null && value.length() > 0) {
+ long t = MINUTE * Long.parseLong(value.trim());
+ if (mCacheUpdateInterval != t) {
+ mCacheUpdateInterval = t;
+ modifiedSchedule = true;
+ }
+ }
+ } catch (NumberFormatException e) {
+ noRestart = false;
+ }
+ }
+
+ if (name.equals(Constants.PR_CACHE_RECOVERY)) {
+ if (value.equals(Constants.FALSE) && mEnableCacheRecovery) {
+ mEnableCacheRecovery = false;
+ } else if (value.equals(Constants.TRUE) && (!mEnableCacheRecovery)) {
+ mEnableCacheRecovery = true;
+ }
+ }
+
+ if (name.equals(Constants.PR_CACHE_TESTING)) {
+ if (value.equals(Constants.FALSE) && mEnableCacheTesting) {
+ clearCRLCache();
+ updateCRLCacheRepository();
+ mEnableCacheTesting = false;
+ setManualUpdate(null);
+ } else if (value.equals(Constants.TRUE) && (!mEnableCacheTesting)) {
+ mEnableCacheTesting = true;
+ }
+ }
+
+ // -- CRL Format --
+ if (name.equals(Constants.PR_SIGNING_ALGORITHM)) {
+ if (value != null)
+ value = value.trim();
+ if (!mSigningAlgorithm.equals(value)) {
+ mSigningAlgorithm = value;
+ }
+ }
+
+ if (name.equals(Constants.PR_EXTENSIONS)) {
+ if (value.equals(Constants.FALSE) && mAllowExtensions) {
+ clearCRLCache();
+ updateCRLCacheRepository();
+ mAllowExtensions = false;
+ } else if (value.equals(Constants.TRUE) && (!mAllowExtensions)) {
+ clearCRLCache();
+ updateCRLCacheRepository();
+ mAllowExtensions = true;
+ }
+ }
+
+ if (name.equals(Constants.PR_INCLUDE_EXPIREDCERTS)) {
+ if (value.equals(Constants.FALSE) && mIncludeExpiredCerts) {
+ clearCRLCache();
+ updateCRLCacheRepository();
+ mIncludeExpiredCerts = false;
+ } else if (value.equals(Constants.TRUE) && (!mIncludeExpiredCerts)) {
+ clearCRLCache();
+ updateCRLCacheRepository();
+ mIncludeExpiredCerts = true;
+ }
+ }
+
+ if (name.equals(Constants.PR_INCLUDE_EXPIREDCERTS_ONEEXTRATIME)) {
+ if (value.equals(Constants.FALSE) && mIncludeExpiredCertsOneExtraTime) {
+ mIncludeExpiredCertsOneExtraTime = false;
+ } else if (value.equals(Constants.TRUE) && (!mIncludeExpiredCertsOneExtraTime)) {
+ mIncludeExpiredCertsOneExtraTime = true;
+ }
+ }
+
+ if (name.equals(Constants.PR_CA_CERTS_ONLY)) {
+ Extension distExt = getCRLExtension(IssuingDistributionPointExtension.NAME);
+ IssuingDistributionPointExtension iExt = (IssuingDistributionPointExtension) distExt;
+ IssuingDistributionPoint issuingDistributionPoint = null;
+ if (iExt != null)
+ issuingDistributionPoint = iExt.getIssuingDistributionPoint();
+ if (value.equals(Constants.FALSE) && mCACertsOnly) {
+ clearCRLCache();
+ updateCRLCacheRepository();
+ mCACertsOnly = false;
+ } else if (value.equals(Constants.TRUE) && (!mCACertsOnly)) {
+ clearCRLCache();
+ updateCRLCacheRepository();
+ mCACertsOnly = true;
+ }
+ //attempt to sync the IssuingDistributionPoint Extension value of
+ //onlyContainsCACerts
+ if (issuingDistributionPoint != null && params.size() > 1) {
+ boolean onlyContainsCACerts = issuingDistributionPoint.getOnlyContainsCACerts();
+ if (onlyContainsCACerts != mCACertsOnly) {
+ IConfigStore config = mCA.getConfigStore();
+ IConfigStore crlsSubStore =
+ config.getSubStore(ICertificateAuthority.PROP_CRL_SUBSTORE);
+ IConfigStore crlSubStore = crlsSubStore.getSubStore(mId);
+ IConfigStore crlExtsSubStore =
+ crlSubStore.getSubStore(ICertificateAuthority.PROP_CRLEXT_SUBSTORE);
+ crlExtsSubStore =
+ crlExtsSubStore
+ .getSubStore(IssuingDistributionPointExtension.NAME);
+
+ if (crlExtsSubStore != null) {
+ String val = "";
+ if (mCACertsOnly == true) {
+ val = Constants.TRUE;
+ } else {
+ val = Constants.FALSE;
+ }
+ crlExtsSubStore.putString(PROP_CACERTS, val);
+ try {
+ crlExtsSubStore.commit(true);
+ } catch (Exception e) {
+ }
+ }
+ }
+ }
+ }
+
+ if (name.equals(Constants.PR_PROFILE_CERTS_ONLY)) {
+ if (value.equals(Constants.FALSE) && mProfileCertsOnly) {
+ clearCRLCache();
+ updateCRLCacheRepository();
+ mProfileCertsOnly = false;
+ } else if (value.equals(Constants.TRUE) && (!mProfileCertsOnly)) {
+ clearCRLCache();
+ updateCRLCacheRepository();
+ mProfileCertsOnly = true;
+ }
+ }
+
+ if (name.equals(Constants.PR_PROFILE_LIST)) {
+ Vector<String> profileList = getProfileList(value);
+ if (((profileList != null) ^ (mProfileList != null)) ||
+ (profileList != null && mProfileList != null &&
+ (!mProfileList.equals(profileList)))) {
+ if (profileList != null) {
+ @SuppressWarnings("unchecked")
+ Vector<String> newProfileList = (Vector<String>) profileList.clone();
+ mProfileList = newProfileList;
+ } else {
+ mProfileList = null;
+ }
+ clearCRLCache();
+ updateCRLCacheRepository();
+ }
+ if (mProfileList == null || mProfileList.isEmpty()) {
+ mProfileCertsOnly = false;
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_INVALID_PROFILE_LIST"));
+ }
+ }
+ }
+
+ if (modifiedSchedule)
+ setAutoUpdates();
+
+ return noRestart;
+ }
+ }
+
+ /**
+ * This method is called during shutdown.
+ * <P>
+ */
+ public synchronized void shutdown() {
+ // this should stop a thread if necessary
+ if (mEnableCRLCache && mCacheUpdateInterval > 0) {
+ updateCRLCacheRepository();
+ }
+ mEnable = false;
+
+ setAutoUpdates();
+ /*
+ if (mUpdateThread != null) {
+ try {
+ mUpdateThread.interrupt();
+ }
+ catch (Exception e) {
+ }
+ }
+ */
+ }
+
+ /**
+ * Returns internal id of this CRL issuing point.
+ * <P>
+ *
+ * @return internal id of this CRL issuing point
+ */
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * Returns internal description of this CRL issuing point.
+ * <P>
+ *
+ * @return internal description of this CRL issuing point
+ */
+ public String getDescription() {
+ return mDescription;
+ }
+
+ /**
+ * Sets internal description of this CRL issuing point.
+ *
+ * @param description description for this CRL issuing point.
+ */
+ public void setDescription(String description) {
+ mDescription = description;
+ }
+
+ /**
+ * Returns DN of the directory entry where CRLs.from this issuing point
+ * are published.
+ * <P>
+ *
+ * @return DN of the directory entry where CRLs are published.
+ */
+ public String getPublishDN() {
+ return mPublishDN;
+ }
+
+ /**
+ * Returns signing algorithm.
+ * <P>
+ *
+ * @return SigningAlgorithm.
+ */
+ public String getSigningAlgorithm() {
+ return mSigningAlgorithm;
+ }
+
+ public String getLastSigningAlgorithm() {
+ return mLastSigningAlgorithm;
+ }
+
+ /**
+ * Returns current CRL generation schema for this CRL issuing point.
+ * <P>
+ *
+ * @return current CRL generation schema for this CRL issuing point
+ */
+ public int getCRLSchema() {
+ return mUpdateSchema;
+ }
+
+ /**
+ * Returns current CRL number of this CRL issuing point.
+ * <P>
+ *
+ * @return current CRL number of this CRL issuing point
+ */
+ public BigInteger getCRLNumber() {
+ return mCRLNumber;
+ }
+
+ /**
+ * Returns current delta CRL number of this CRL issuing point.
+ * <P>
+ *
+ * @return current delta CRL number of this CRL issuing point
+ */
+ public BigInteger getDeltaCRLNumber() {
+ return (isDeltaCRLEnabled() && mDeltaCRLSize > -1) ? mDeltaCRLNumber : BigInteger.ZERO;
+ }
+
+ /**
+ * Returns next CRL number of this CRL issuing point.
+ * <P>
+ *
+ * @return next CRL number of this CRL issuing point
+ */
+ public BigInteger getNextCRLNumber() {
+ return mNextDeltaCRLNumber;
+ }
+
+ /**
+ * Returns number of entries in the CRL
+ * <P>
+ *
+ * @return number of entries in the CRL
+ */
+ public long getCRLSize() {
+ return (mCRLCerts.size() > 0 && mCRLSize == 0) ? mCRLCerts.size() : mCRLSize;
+ }
+
+ /**
+ * Returns number of entries in delta CRL
+ * <P>
+ *
+ * @return number of entries in delta CRL
+ */
+ public long getDeltaCRLSize() {
+ return mDeltaCRLSize;
+ }
+
+ /**
+ * Returns last update time
+ * <P>
+ *
+ * @return last CRL update time
+ */
+ public Date getLastUpdate() {
+ return mLastUpdate;
+ }
+
+ /**
+ * Returns next update time
+ * <P>
+ *
+ * @return next CRL update time
+ */
+ public Date getNextUpdate() {
+ return mNextUpdate;
+ }
+
+ /**
+ * Returns next update time
+ * <P>
+ *
+ * @return next CRL update time
+ */
+ public Date getNextDeltaUpdate() {
+ return mNextDeltaUpdate;
+ }
+
+ /**
+ * Returns all the revoked certificates from the CRL cache.
+ * <P>
+ *
+ * @return set of all the revoked certificates or null if there are none.
+ */
+ public Set<RevokedCertificate> getRevokedCertificates(int start, int end) {
+ if (mCRLCacheIsCleared || mCRLCerts == null || mCRLCerts.isEmpty()) {
+ return null;
+ } else {
+ Set<RevokedCertificate> certSet = new LinkedHashSet<RevokedCertificate>(mCRLCerts.values());
+ return certSet;
+ }
+ }
+
+ /**
+ * Returns certificate authority.
+ * <P>
+ *
+ * @return certificate authority
+ */
+ public ISubsystem getCertificateAuthority() {
+ return mCA;
+ }
+
+ /**
+ * Sets CRL auto updates
+ */
+
+ private synchronized void setAutoUpdates() {
+ if ((mEnable && mUpdateThread == null) &&
+ ((mEnableCRLCache && mCacheUpdateInterval > 0) ||
+ (mEnableCRLUpdates &&
+ ((mEnableDailyUpdates && mDailyUpdates != null &&
+ mTimeListSize > 0) ||
+ (mEnableUpdateFreq && mAutoUpdateInterval > 0) ||
+ (mInitialized == CRL_IP_NOT_INITIALIZED) ||
+ mDoLastAutoUpdate || mDoManualUpdate)))) {
+ mUpdateThread = new Thread(this, "CRLIssuingPoint-" + mId);
+ log(ILogger.LL_INFO, CMS.getLogMessage("CMSCORE_CA_ISSUING_START_CRL", mId));
+ mUpdateThread.setDaemon(true);
+ mUpdateThread.start();
+ }
+
+ if ((mInitialized == CRL_IP_INITIALIZED) && (((mNextUpdate != null) ^
+ ((mEnableDailyUpdates && mDailyUpdates != null && mTimeListSize > 0) ||
+ (mEnableUpdateFreq && mAutoUpdateInterval > 0))) ||
+ (!mEnableCRLUpdates && mNextUpdate != null))) {
+ mDoLastAutoUpdate = true;
+ }
+
+ if (mEnableUpdateFreq && mAutoUpdateInterval > 0 &&
+ mAutoUpdateInterval < mMinUpdateInterval) {
+ mAutoUpdateInterval = mMinUpdateInterval;
+ }
+
+ notifyAll();
+ }
+
+ /**
+ * Sets CRL manual-update
+ * Starts or stops worker thread as necessary.
+ */
+ public synchronized void setManualUpdate(String signatureAlgorithm) {
+ if (!mDoManualUpdate) {
+ mDoManualUpdate = true;
+ mSignatureAlgorithmForManualUpdate = signatureAlgorithm;
+ if (mEnableUpdateFreq && mAutoUpdateInterval > 0 && mUpdateThread != null) {
+ notifyAll();
+ } else {
+ setAutoUpdates();
+ }
+ }
+ }
+
+ /**
+ * @return auto update interval in milliseconds.
+ */
+ public long getAutoUpdateInterval() {
+ return (mEnableUpdateFreq) ? mAutoUpdateInterval : 0;
+ }
+
+ /**
+ * @return always update the CRL
+ */
+ public boolean getAlwaysUpdate() {
+ return mAlwaysUpdate;
+ }
+
+ /**
+ * @return next update grace period in minutes.
+ */
+
+ public long getNextUpdateGracePeriod() {
+ return mNextUpdateGracePeriod;
+ }
+
+ /**
+ * Finds next update time expressed as delay or time of the next update.
+ *
+ * @param fromLastUpdate if true, function returns delay to the next update time
+ * otherwise returns the next update time.
+ * @param delta if true, function returns the next update time for delta CRL,
+ * otherwise returns the next update time for CRL.
+ * @return delay to the next update time or the next update time itself
+ */
+ private long findNextUpdate(boolean fromLastUpdate, boolean delta) {
+ long now = System.currentTimeMillis();
+ TimeZone tz = TimeZone.getDefault();
+ int offset = tz.getOffset(now);
+ long oneDay = 1440L * MINUTE;
+ long nowToday = (now + (long) offset) % oneDay;
+ long startOfToday = now - nowToday;
+
+ long lastUpdated = (mLastUpdate != null) ? mLastUpdate.getTime() : now;
+ long lastUpdateDay = lastUpdated - ((lastUpdated + (long) offset) % oneDay);
+
+ long lastUpdate = (mLastUpdate != null && fromLastUpdate) ? mLastUpdate.getTime() : now;
+ long last = (lastUpdate + (long) offset) % oneDay;
+ long lastDay = lastUpdate - last;
+
+ boolean isDeltaEnabled = isDeltaCRLEnabled();
+ long next = 0L;
+ long nextUpdate = 0L;
+
+ CMS.debug("findNextUpdate: fromLastUpdate: " + fromLastUpdate + " delta: " + delta);
+
+ int numberOfDays = (int) ((startOfToday - lastUpdateDay) / oneDay);
+ if (numberOfDays > 0 && mDailyUpdates.size() > 1 &&
+ ((mCurrentDay == mLastDay) ||
+ (mCurrentDay != ((mLastDay + numberOfDays) % mDailyUpdates.size())))) {
+ mCurrentDay = (mLastDay + numberOfDays) % mDailyUpdates.size();
+ }
+
+ if ((delta || fromLastUpdate) && isDeltaEnabled &&
+ (mUpdateSchema > 1 || (mEnableDailyUpdates && mExtendedTimeList)) &&
+ mNextDeltaUpdate != null) {
+ nextUpdate = mNextDeltaUpdate.getTime();
+ } else if (mNextUpdate != null) {
+ nextUpdate = mNextUpdate.getTime();
+ }
+
+ if (mEnableDailyUpdates &&
+ mDailyUpdates != null && mDailyUpdates.size() > 0) {
+ int n = 0;
+ if (mDailyUpdates.size() == 1 && mDailyUpdates.elementAt(0).size() == 1 &&
+ mEnableUpdateFreq && mAutoUpdateInterval > 0) {
+ // Interval updates with starting time
+ long firstTime = MINUTE * ((Integer) mDailyUpdates.elementAt(0).elementAt(0)).longValue();
+ long t = firstTime;
+ long interval = mAutoUpdateInterval;
+ if (mExtendedNextUpdate && (!fromLastUpdate) && (!delta) &&
+ isDeltaEnabled && mUpdateSchema > 1) {
+ interval *= mUpdateSchema;
+ }
+ while (t < oneDay) {
+ if (t - mMinUpdateInterval > last)
+ break;
+ t += interval;
+ n++;
+ }
+
+ if (t <= oneDay) {
+ next = lastDay + t;
+ if (fromLastUpdate) {
+ n = n % mUpdateSchema;
+ if (t == firstTime) {
+ mSchemaCounter = 0;
+ } else if (n != mSchemaCounter) {
+ if (mSchemaCounter != 0 && (mSchemaCounter < n || n == 0)) {
+ mSchemaCounter = n;
+ }
+ }
+ }
+ } else {
+ next = lastDay + oneDay + firstTime;
+ if (fromLastUpdate) {
+ mSchemaCounter = 0;
+ }
+ }
+ } else {
+ // Daily updates following the list
+ if (last > nowToday) {
+ last = nowToday - 100; // 100ms - precision
+ }
+ int i, m;
+ for (i = 0, m = 0; i < mCurrentDay; i++) {
+ m += mDailyUpdates.elementAt(i).size();
+ }
+ // search the current day
+ for (i = 0; i < mDailyUpdates.elementAt(mCurrentDay).size(); i++) {
+ long t = MINUTE * ((Integer) mDailyUpdates.elementAt(mCurrentDay).elementAt(i)).longValue();
+ if (mEnableDailyUpdates && mExtendedTimeList) {
+ if (mExtendedNextUpdate && (!fromLastUpdate) && (!delta) && isDeltaEnabled) {
+ if (t < 0) {
+ t *= -1;
+ } else {
+ t = 0;
+ }
+ } else {
+ if (t < 0) {
+ t *= -1;
+ }
+ }
+ }
+ if (t - mMinUpdateInterval > last) {
+ if (mExtendedNextUpdate
+ && (!fromLastUpdate) && (!(mEnableDailyUpdates && mExtendedTimeList)) && (!delta) &&
+ isDeltaEnabled && mUpdateSchema > 1) {
+ i += mUpdateSchema - ((i + m) % mUpdateSchema);
+ }
+ break;
+ }
+ n++;
+ }
+
+ if (i < mDailyUpdates.elementAt(mCurrentDay).size()) {
+ // found inside the current day
+ next = (MINUTE * ((Integer) mDailyUpdates.elementAt(mCurrentDay).elementAt(i)).longValue());
+ if (mEnableDailyUpdates && mExtendedTimeList && next < 0) {
+ next *= -1;
+ if (fromLastUpdate) {
+ mSchemaCounter = 0;
+ }
+ }
+ next += ((lastDay < lastUpdateDay) ? lastDay : lastUpdateDay) + (oneDay * (mCurrentDay - mLastDay));
+
+ if (fromLastUpdate && (!(mEnableDailyUpdates && mExtendedTimeList))) {
+ n = n % mUpdateSchema;
+ if (i == 0 && mCurrentDay == 0) {
+ mSchemaCounter = 0;
+ } else if (n != mSchemaCounter) {
+ if (mSchemaCounter != 0 && ((n == 0 && mCurrentDay == 0) || mSchemaCounter < n)) {
+ mSchemaCounter = n;
+ }
+ }
+ }
+ } else {
+ // done with today
+ int j = i - mDailyUpdates.elementAt(mCurrentDay).size();
+ int nDays = 1;
+ long t = 0;
+ if (mDailyUpdates.size() > 1) {
+ while (nDays <= mDailyUpdates.size()) {
+ int nextDay = (mCurrentDay + nDays) % mDailyUpdates.size();
+ if (j < mDailyUpdates.elementAt(nextDay).size()) {
+ if (nextDay == 0 && (!(mEnableDailyUpdates && mExtendedTimeList)))
+ j = 0;
+ t = MINUTE * ((Integer) mDailyUpdates.elementAt(nextDay).elementAt(j)).longValue();
+ if (mEnableDailyUpdates && mExtendedTimeList) {
+ if (mExtendedNextUpdate && (!fromLastUpdate) && (!delta) && isDeltaEnabled) {
+ if (t < 0) {
+ t *= -1;
+ } else {
+ j++;
+ continue;
+ }
+ } else {
+ if (t < 0) {
+ t *= -1;
+ if (fromLastUpdate) {
+ mSchemaCounter = 0;
+ }
+ }
+ }
+ }
+ break;
+ } else {
+ j -= mDailyUpdates.elementAt(nextDay).size();
+ }
+ nDays++;
+ }
+ }
+ next = ((lastDay < lastUpdateDay) ? lastDay : lastUpdateDay) + (oneDay * nDays) + t;
+
+ if (fromLastUpdate && mDailyUpdates.size() < 2) {
+ mSchemaCounter = 0;
+ }
+ }
+ }
+ } else if (mEnableUpdateFreq && mAutoUpdateInterval > 0) {
+ // Interval updates without starting time
+ if (mExtendedNextUpdate && (!fromLastUpdate) && (!delta) && isDeltaEnabled && mUpdateSchema > 1) {
+ next = lastUpdate + (mUpdateSchema * mAutoUpdateInterval);
+ } else {
+ next = lastUpdate + mAutoUpdateInterval;
+ }
+ }
+
+ if (fromLastUpdate && nextUpdate > 0 && (nextUpdate < next || nextUpdate >= now)) {
+ next = nextUpdate;
+ }
+
+ CMS.debug("findNextUpdate: "
+ + ((new Date(next)).toString()) + ((fromLastUpdate) ? " delay: " + (next - now) : ""));
+
+ return (fromLastUpdate) ? next - now : next;
+ }
+
+ /**
+ * Implements Runnable interface. Defines auto-update
+ * logic used by worker thread.
+ * <P>
+ */
+ public void run() {
+ while (mEnable && ((mEnableCRLCache && mCacheUpdateInterval > 0) ||
+ (mInitialized == CRL_IP_NOT_INITIALIZED) ||
+ mDoLastAutoUpdate || (mEnableCRLUpdates &&
+ ((mEnableDailyUpdates && mDailyUpdates != null &&
+ mTimeListSize > 0) ||
+ (mEnableUpdateFreq && mAutoUpdateInterval > 0) ||
+ mDoManualUpdate)))) {
+
+ synchronized (this) {
+ long delay = 0;
+ long delay2 = 0;
+ boolean doCacheUpdate = false;
+ boolean scheduledUpdates = mEnableCRLUpdates &&
+ ((mEnableDailyUpdates && mDailyUpdates != null &&
+ mTimeListSize > 0) ||
+ (mEnableUpdateFreq && mAutoUpdateInterval > 0));
+
+ if (mInitialized == CRL_IP_NOT_INITIALIZED)
+ initCRL();
+ if (mInitialized == CRL_IP_INITIALIZED && (!mEnable))
+ break;
+
+ if ((mEnableCRLUpdates && mDoManualUpdate) || mDoLastAutoUpdate) {
+ delay = 0;
+ } else if (scheduledUpdates) {
+ delay = findNextUpdate(true, false);
+ }
+
+ if (mEnableCRLCache && mCacheUpdateInterval > 0) {
+ delay2 = mLastCacheUpdate + mCacheUpdateInterval -
+ System.currentTimeMillis();
+ if (delay2 < delay ||
+ (!(scheduledUpdates || mDoLastAutoUpdate ||
+ (mEnableCRLUpdates && mDoManualUpdate)))) {
+ delay = delay2;
+ if (delay <= 0) {
+ doCacheUpdate = true;
+ mLastCacheUpdate = System.currentTimeMillis();
+ }
+ }
+ }
+
+ if (delay > 0) {
+ try {
+ wait(delay);
+ } catch (InterruptedException e) {
+ }
+ } else {
+ try {
+ if (doCacheUpdate) {
+ updateCRLCacheRepository();
+ } else if (mAutoUpdateInterval > 0 || mDoLastAutoUpdate || mDoManualUpdate) {
+ updateCRL();
+ }
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_CRL",
+ (doCacheUpdate) ? "update CRL cache" : "update CRL", e.toString()));
+ if (Debug.on()) {
+ Debug.trace((doCacheUpdate) ? "update CRL cache" : "update CRL" + " error " + e);
+ Debug.printStackTrace(e);
+ }
+ }
+ // put this here to prevent continuous loop if internal
+ // db is down.
+ if (mDoLastAutoUpdate)
+ mDoLastAutoUpdate = false;
+ if (mDoManualUpdate) {
+ mDoManualUpdate = false;
+ mSignatureAlgorithmForManualUpdate = null;
+ }
+ }
+ }
+ }
+ mUpdateThread = null;
+ }
+
+ /**
+ * Updates CRL and publishes it.
+ * If time elapsed since last CRL update is less than
+ * minUpdateInterval silently returns.
+ * Otherwise determines nextUpdate by adding autoUpdateInterval or
+ * minUpdateInterval to the current time. If neither of the
+ * intervals are defined nextUpdate will be null.
+ * Then using specified configuration parameters it formulates new
+ * CRL, signs it, updates CRLIssuingPointRecord in the database
+ * and publishes CRL in the directory.
+ * <P>
+ */
+ private void updateCRL() throws EBaseException {
+ /*
+ if (mEnableUpdateFreq && mAutoUpdateInterval > 0 &&
+ (System.currentTimeMillis() - mLastUpdate.getTime() <
+ mMinUpdateInterval)) {
+ // log or alternatively throw an Exception
+ return;
+ }
+ */
+ if (mDoManualUpdate && mSignatureAlgorithmForManualUpdate != null) {
+ updateCRLNow(mSignatureAlgorithmForManualUpdate);
+ } else {
+ updateCRLNow();
+ }
+ }
+
+ /**
+ * This method may be overrided by CRLWithExpiredCerts.java
+ */
+ public String getFilter() {
+ // PLEASE DONT CHANGE THE FILTER. It is indexed.
+ // Changing it will degrade performance. See
+ // also com.netscape.certsetup.LDAPUtil.java
+ String filter = "";
+
+ if (mIncludeExpiredCerts)
+ filter += "(|";
+ filter += "(" + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_REVOKED + ")";
+ if (mIncludeExpiredCerts)
+ filter += "(" + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_REVOKED_EXPIRED + "))";
+
+ if (mCACertsOnly) {
+ filter += "(x509cert.BasicConstraints.isCA=on)";
+ }
+
+ if (mProfileCertsOnly && mProfileList != null && mProfileList.size() > 0) {
+ if (mProfileList.size() > 1) {
+ filter += "(|";
+ }
+ for (int k = 0; k < mProfileList.size(); k++) {
+ String id = mProfileList.elementAt(k);
+ filter += "(" + CertRecord.ATTR_META_INFO + "=profileId:" + id + ")";
+ }
+ if (mProfileList.size() > 1) {
+ filter += ")";
+ }
+ }
+
+ // check if any ranges specified.
+ if (mBeginSerial != null) {
+ filter += "(" + CertRecord.ATTR_ID + ">=" + mBeginSerial.toString() + ")";
+ }
+ if (mEndSerial != null) {
+ filter += "(" + CertRecord.ATTR_ID + "<=" + mEndSerial.toString() + ")";
+ }
+
+ // get all revoked non-expired certs.
+ if (mEndSerial != null || mBeginSerial != null || mCACertsOnly ||
+ (mProfileCertsOnly && mProfileList != null && mProfileList.size() > 0)) {
+ filter = "(&" + filter + ")";
+ }
+
+ return filter;
+ }
+
+ /**
+ * Gets a enumeration of revoked certs to put into CRL.
+ * This does not include expired certs.
+ * <i>Override this method to make a CRL other than the
+ * full/complete CRL.</i>
+ *
+ * @return Enumeration of CertRecords to put into CRL.
+ * @exception EBaseException if an error occured in the database.
+ */
+ public void processRevokedCerts(IElementProcessor p)
+ throws EBaseException {
+ mCertRepository.processRevokedCerts(p, getFilter(), mPageSize);
+ }
+
+ /**
+ * clears CRL cache
+ */
+ public void clearCRLCache() {
+ mCRLCacheIsCleared = true;
+ mCRLCerts.clear();
+ mRevokedCerts.clear();
+ mUnrevokedCerts.clear();
+ mExpiredCerts.clear();
+ mSchemaCounter = 0;
+ }
+
+ /**
+ * clears Delta-CRL cache
+ */
+ public void clearDeltaCRLCache() {
+ mRevokedCerts.clear();
+ mUnrevokedCerts.clear();
+ mExpiredCerts.clear();
+ mSchemaCounter = 0;
+ }
+
+ /**
+ * recovers CRL cache
+ */
+ private void recoverCRLCache() {
+ if (mEnableCacheRecovery) {
+ // 553815 - original filter was not aligned with any VLV index
+ // String filter = "(&(requeststate=complete)"+
+ // "(|(requestType=" + IRequest.REVOCATION_REQUEST + ")"+
+ // "(requestType=" + IRequest.UNREVOCATION_REQUEST + ")))";
+ String filter = "(requeststate=complete)";
+ if (Debug.on()) {
+ Debug.trace("recoverCRLCache mFirstUnsaved=" + mFirstUnsaved + " filter=" + filter);
+ }
+ IRequestQueue mQueue = mCA.getRequestQueue();
+
+ IRequestVirtualList list = mQueue.getPagedRequestsByFilter(
+ new RequestId(mFirstUnsaved), filter, 500, "requestId");
+ if (Debug.on()) {
+ Debug.trace("recoverCRLCache size=" + list.getSize() + " index=" + list.getCurrentIndex());
+ }
+
+ CertRecProcessor cp = new CertRecProcessor(mCRLCerts, this, mLogger, mAllowExtensions);
+ boolean includeCert = true;
+
+ int s = list.getSize() - list.getCurrentIndex();
+ for (int i = 0; i < s; i++) {
+ IRequest request = null;
+ try {
+ request = list.getElementAt(i);
+ } catch (Exception e) {
+ // handled below
+ }
+ if (request == null) {
+ continue;
+ }
+ if (Debug.on()) {
+ Debug.trace("recoverCRLCache request=" + request.getRequestId().toString() +
+ " type=" + request.getRequestType());
+ }
+ if (IRequest.REVOCATION_REQUEST.equals(request.getRequestType())) {
+ RevokedCertImpl revokedCert[] =
+ request.getExtDataInRevokedCertArray(IRequest.CERT_INFO);
+ for (int j = 0; j < revokedCert.length; j++) {
+ if (Debug.on()) {
+ Debug.trace("recoverCRLCache R j=" + j + " length=" + revokedCert.length +
+ " SerialNumber=0x" + revokedCert[j].getSerialNumber().toString(16));
+ }
+ if (cp != null)
+ includeCert = cp.checkRevokedCertExtensions(revokedCert[j].getExtensions());
+ if (includeCert) {
+ updateRevokedCert(REVOKED_CERT, revokedCert[j].getSerialNumber(), revokedCert[j]);
+ }
+ }
+ } else if (IRequest.UNREVOCATION_REQUEST.equals(request.getRequestType())) {
+ BigInteger serialNo[] = request.getExtDataInBigIntegerArray(IRequest.OLD_SERIALS);
+ for (int j = 0; j < serialNo.length; j++) {
+ if (Debug.on()) {
+ Debug.trace("recoverCRLCache U j=" + j + " length=" + serialNo.length +
+ " SerialNumber=0x" + serialNo[j].toString(16));
+ }
+ updateRevokedCert(UNREVOKED_CERT, serialNo[j], null);
+ }
+ }
+ }
+
+ try {
+ mCRLRepository.updateRevokedCerts(mId, mRevokedCerts, mUnrevokedCerts);
+ mFirstUnsaved = ICRLIssuingPointRecord.CLEAN_CACHE;
+ mCRLCacheIsCleared = false;
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_STORE_CRL_CACHE", e.toString()));
+ }
+ } else {
+ clearCRLCache();
+ updateCRLCacheRepository();
+ }
+ }
+
+ public int getNumberOfRecentlyRevokedCerts() {
+ return mRevokedCerts.size();
+ }
+
+ public int getNumberOfRecentlyUnrevokedCerts() {
+ return mUnrevokedCerts.size();
+ }
+
+ public int getNumberOfRecentlyExpiredCerts() {
+ return mExpiredCerts.size();
+ }
+
+ private Extension getCRLExtension(String extName) {
+ if (mAllowExtensions == false) {
+ return null;
+ }
+ if (mCMSCRLExtensions.isCRLExtensionEnabled(extName) == false) {
+ return null;
+ }
+
+ CMSCRLExtensions exts = (CMSCRLExtensions) this.getCRLExtensions();
+ CRLExtensions ext = new CRLExtensions();
+
+ Vector<String> extNames = exts.getCRLExtensionNames();
+ for (int i = 0; i < extNames.size(); i++) {
+ String curName = extNames.elementAt(i);
+ if (curName.equals(extName)) {
+ exts.addToCRLExtensions(ext, extName, null);
+ }
+ }
+ Extension theExt = null;
+ try {
+ theExt = ext.get(extName);
+ } catch (Exception e) {
+ }
+
+ CMS.debug("CRLIssuingPoint.getCRLExtension extension: " + theExt);
+ return theExt;
+ }
+
+ /**
+ * get required crl entry extensions
+ */
+ public CRLExtensions getRequiredEntryExtensions(CRLExtensions exts) {
+ CRLExtensions entryExt = null;
+
+ if (mAllowExtensions && exts != null && exts.size() > 0) {
+ entryExt = new CRLExtensions();
+ Vector<String> extNames = mCMSCRLExtensions.getCRLEntryExtensionNames();
+
+ for (int i = 0; i < extNames.size(); i++) {
+ String extName = extNames.elementAt(i);
+
+ if (mCMSCRLExtensions.isCRLExtensionEnabled(extName)) {
+ int k;
+
+ for (k = 0; k < exts.size(); k++) {
+ Extension ext = (Extension) exts.elementAt(k);
+ String name = mCMSCRLExtensions.getCRLExtensionName(
+ ext.getExtensionId().toString());
+
+ if (extName.equals(name)) {
+ if (!(ext instanceof CRLReasonExtension) ||
+ (((CRLReasonExtension) ext).getReason().toInt() >
+ RevocationReason.UNSPECIFIED.toInt())) {
+ mCMSCRLExtensions.addToCRLExtensions(entryExt, extName, ext);
+ }
+ break;
+ }
+ }
+ if (k == exts.size()) {
+ mCMSCRLExtensions.addToCRLExtensions(entryExt, extName, null);
+ }
+ }
+ }
+ }
+
+ return entryExt;
+ }
+
+ private static final int REVOKED_CERT = 1;
+ private static final int UNREVOKED_CERT = 2;
+ private Object cacheMonitor = new Object();
+
+ /**
+ * update CRL cache with new revoked-unrevoked certificate info
+ */
+ private void updateRevokedCert(int certType,
+ BigInteger serialNumber,
+ RevokedCertImpl revokedCert) {
+ updateRevokedCert(certType, serialNumber, revokedCert, null);
+ }
+
+ private void updateRevokedCert(int certType,
+ BigInteger serialNumber,
+ RevokedCertImpl revokedCert,
+ String requestId) {
+ synchronized (cacheMonitor) {
+ if (requestId != null && mFirstUnsaved != null &&
+ mFirstUnsaved.equals(ICRLIssuingPointRecord.CLEAN_CACHE)) {
+ mFirstUnsaved = requestId;
+ try {
+ mCRLRepository.updateFirstUnsaved(mId, mFirstUnsaved);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_STORE_CRL_CACHE", e.toString()));
+ }
+ }
+ if (certType == REVOKED_CERT) {
+ if (mUnrevokedCerts.containsKey(serialNumber)) {
+ mUnrevokedCerts.remove(serialNumber);
+ if (mCRLCerts.containsKey(serialNumber)) {
+ Date revocationDate = revokedCert.getRevocationDate();
+ CRLExtensions entryExt = getRequiredEntryExtensions(revokedCert.getExtensions());
+ RevokedCertImpl newRevokedCert =
+ new RevokedCertImpl(serialNumber, revocationDate, entryExt);
+
+ mCRLCerts.put(serialNumber, newRevokedCert);
+ }
+ } else {
+ Date revocationDate = revokedCert.getRevocationDate();
+ CRLExtensions entryExt = getRequiredEntryExtensions(revokedCert.getExtensions());
+ RevokedCertImpl newRevokedCert =
+ new RevokedCertImpl(serialNumber, revocationDate, entryExt);
+
+ mRevokedCerts.put(serialNumber, (RevokedCertificate) newRevokedCert);
+ }
+ } else if (certType == UNREVOKED_CERT) {
+ if (mRevokedCerts.containsKey(serialNumber)) {
+ mRevokedCerts.remove(serialNumber);
+ } else {
+ CRLExtensions entryExt = new CRLExtensions();
+
+ try {
+ entryExt.set(CRLReasonExtension.REMOVE_FROM_CRL.getName(),
+ CRLReasonExtension.REMOVE_FROM_CRL);
+ } catch (IOException e) {
+ }
+ RevokedCertImpl newRevokedCert = new RevokedCertImpl(serialNumber,
+ CMS.getCurrentDate(), entryExt);
+
+ mUnrevokedCerts.put(serialNumber, (RevokedCertificate) newRevokedCert);
+ }
+ }
+ }
+ }
+
+ /**
+ * registers revoked certificates
+ */
+ public void addRevokedCert(BigInteger serialNumber, RevokedCertImpl revokedCert) {
+ addRevokedCert(serialNumber, revokedCert, null);
+ }
+
+ public void addRevokedCert(BigInteger serialNumber, RevokedCertImpl revokedCert,
+ String requestId) {
+
+ CertRecProcessor cp = new CertRecProcessor(mCRLCerts, this, mLogger, mAllowExtensions);
+ boolean includeCert = true;
+ if (cp != null)
+ includeCert = cp.checkRevokedCertExtensions(revokedCert.getExtensions());
+
+ if (mEnable && mEnableCRLCache && includeCert == true) {
+ updateRevokedCert(REVOKED_CERT, serialNumber, revokedCert, requestId);
+
+ if (mCacheUpdateInterval == 0) {
+ try {
+ mCRLRepository.updateRevokedCerts(mId, mRevokedCerts, mUnrevokedCerts);
+ mFirstUnsaved = ICRLIssuingPointRecord.CLEAN_CACHE;
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_ISSUING_STORE_REVOKED_CERT", mId, e.toString()));
+ }
+ }
+ }
+ }
+
+ /**
+ * registers unrevoked certificates
+ */
+ public void addUnrevokedCert(BigInteger serialNumber) {
+ addUnrevokedCert(serialNumber, null);
+ }
+
+ public void addUnrevokedCert(BigInteger serialNumber, String requestId) {
+ if (mEnable && mEnableCRLCache) {
+ updateRevokedCert(UNREVOKED_CERT, serialNumber, null, requestId);
+
+ if (mCacheUpdateInterval == 0) {
+ try {
+ mCRLRepository.updateRevokedCerts(mId, mRevokedCerts, mUnrevokedCerts);
+ mFirstUnsaved = ICRLIssuingPointRecord.CLEAN_CACHE;
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_ISSUING_STORE_UNREVOKED_CERT", mId, e.toString()));
+ }
+ }
+ }
+ }
+
+ /**
+ * registers expired certificates
+ */
+ public void addExpiredCert(BigInteger serialNumber) {
+
+ if (mEnable && mEnableCRLCache && (!mIncludeExpiredCerts)) {
+ if (!(mExpiredCerts.containsKey(serialNumber))) {
+ CRLExtensions entryExt = new CRLExtensions();
+
+ try {
+ entryExt.set(CRLReasonExtension.REMOVE_FROM_CRL.getName(),
+ CRLReasonExtension.REMOVE_FROM_CRL);
+ } catch (IOException e) {
+ }
+ RevokedCertImpl newRevokedCert = new RevokedCertImpl(serialNumber,
+ CMS.getCurrentDate(), entryExt);
+
+ mExpiredCerts.put(serialNumber, (RevokedCertificate) newRevokedCert);
+ }
+
+ if (mCacheUpdateInterval == 0) {
+ try {
+ mCRLRepository.updateExpiredCerts(mId, mExpiredCerts);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_ISSUING_STORE_EXPIRED_CERT", mId, e.toString()));
+ }
+ }
+ }
+ }
+
+ private Object repositoryMonitor = new Object();
+
+ public void updateCRLCacheRepository() {
+ synchronized (repositoryMonitor) {
+ try {
+ mCRLRepository.updateCRLCache(mId, Long.valueOf(mCRLSize),
+ mRevokedCerts, mUnrevokedCerts, mExpiredCerts);
+ mFirstUnsaved = ICRLIssuingPointRecord.CLEAN_CACHE;
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_STORE_CRL_CACHE", e.toString()));
+ }
+ }
+ }
+
+ public boolean isDeltaCRLEnabled() {
+ return (mAllowExtensions && mEnableCRLCache &&
+ mCMSCRLExtensions.isCRLExtensionEnabled(DeltaCRLIndicatorExtension.NAME) &&
+ mCMSCRLExtensions.isCRLExtensionEnabled(CRLNumberExtension.NAME) &&
+ mCMSCRLExtensions.isCRLExtensionEnabled(CRLReasonExtension.NAME));
+ }
+
+ public boolean isThisCurrentDeltaCRL(X509CRLImpl deltaCRL) {
+ boolean result = false;
+
+ if (isDeltaCRLEnabled() && mDeltaCRLSize > -1) {
+ if (deltaCRL != null) {
+ CRLExtensions crlExtensions = deltaCRL.getExtensions();
+
+ if (crlExtensions != null) {
+ for (int k = 0; k < crlExtensions.size(); k++) {
+ Extension ext = (Extension) crlExtensions.elementAt(k);
+
+ if (DeltaCRLIndicatorExtension.OID.equals(ext.getExtensionId().toString())) {
+ DeltaCRLIndicatorExtension dExt = (DeltaCRLIndicatorExtension) ext;
+ BigInteger crlNumber = null;
+
+ try {
+ crlNumber = (BigInteger) dExt.get(DeltaCRLIndicatorExtension.NUMBER);
+ } catch (IOException e) {
+ }
+ if (crlNumber != null && (crlNumber.equals(mLastCRLNumber) ||
+ mLastCRLNumber.equals(BigInteger.ZERO))) {
+ result = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ return (result);
+ }
+
+ public boolean isCRLCacheEnabled() {
+ return mEnableCRLCache;
+ }
+
+ public boolean isCRLCacheEmpty() {
+ return ((mCRLCerts != null) ? mCRLCerts.isEmpty() : true);
+ }
+
+ public boolean isCRLCacheTestingEnabled() {
+ return mEnableCacheTesting;
+ }
+
+ public Date getRevocationDateFromCache(BigInteger serialNumber,
+ boolean checkDeltaCache,
+ boolean includeExpiredCerts) {
+ Date revocationDate = null;
+
+ if (mCRLCerts.containsKey(serialNumber)) {
+ revocationDate = mCRLCerts.get(serialNumber).getRevocationDate();
+ }
+
+ if (checkDeltaCache && isDeltaCRLEnabled()) {
+ if (mUnrevokedCerts.containsKey(serialNumber)) {
+ revocationDate = null;
+ }
+ if (mRevokedCerts.containsKey(serialNumber)) {
+ revocationDate = mRevokedCerts.get(serialNumber).getRevocationDate();
+ }
+ if (!includeExpiredCerts && mExpiredCerts.containsKey(serialNumber)) {
+ revocationDate = null;
+ }
+ }
+
+ return revocationDate;
+ }
+
+ public Vector<Long> getSplitTimes() {
+ Vector<Long> splits = new Vector<Long>();
+
+ for (int i = 0; i < mSplits.length; i++) {
+ splits.addElement(Long.valueOf(mSplits[i]));
+ }
+ return splits;
+ }
+
+ public int isCRLUpdateInProgress() {
+ return mUpdatingCRL;
+ }
+
+ /**
+ * updates CRL and publishes it now
+ */
+ public void updateCRLNow()
+ throws EBaseException {
+
+ updateCRLNow(null);
+ }
+
+ public synchronized void updateCRLNow(String signingAlgorithm)
+ throws EBaseException {
+
+ if ((!mEnable) || (!mEnableCRLUpdates && !mDoLastAutoUpdate))
+ return;
+ CMS.debug("Updating CRL");
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER, AuditFormat.LEVEL,
+ CMS.getLogMessage("CMSCORE_CA_CA_CRL_UPDATE_STARTED"),
+ new Object[] {
+ getId(),
+ getNextCRLNumber(),
+ Boolean.toString(isDeltaCRLEnabled()),
+ Boolean.toString(isCRLCacheEnabled()),
+ Boolean.toString(mEnableCacheRecovery),
+ Boolean.toString(mCRLCacheIsCleared),
+ mCRLCerts.size() + "," + mRevokedCerts.size() + "," + mUnrevokedCerts.size()
+ + "," + mExpiredCerts.size() + ""
+ }
+ );
+ mUpdatingCRL = CRL_UPDATE_STARTED;
+ if (signingAlgorithm == null || signingAlgorithm.length() == 0)
+ signingAlgorithm = mSigningAlgorithm;
+ mLastSigningAlgorithm = signingAlgorithm;
+ Date thisUpdate = CMS.getCurrentDate();
+ Date nextUpdate = null;
+ Date nextDeltaUpdate = null;
+
+ if (mEnableCRLUpdates && ((mEnableDailyUpdates &&
+ mDailyUpdates != null && mTimeListSize > 0) ||
+ (mEnableUpdateFreq && mAutoUpdateInterval > 0))) {
+
+ if ((!isDeltaCRLEnabled()) || mSchemaCounter == 0 || mUpdateSchema == 1) {
+ nextUpdate = new Date(findNextUpdate(false, false));
+ mNextUpdate = new Date(nextUpdate.getTime());
+ }
+ if (isDeltaCRLEnabled()) {
+ if (mUpdateSchema > 1 || (mEnableDailyUpdates && mExtendedTimeList && mTimeListSize > 1)) {
+ nextDeltaUpdate = new Date(findNextUpdate(false, true));
+ if (mExtendedNextUpdate && mSchemaCounter > 0 &&
+ mNextUpdate != null && mNextUpdate.equals(nextDeltaUpdate)) {
+ if (mEnableDailyUpdates && mExtendedTimeList && mTimeListSize > 1) {
+ mSchemaCounter = mTimeListSize - 1;
+ } else {
+ mSchemaCounter = mUpdateSchema - 1;
+ }
+ }
+ } else {
+ nextDeltaUpdate = new Date(nextUpdate.getTime());
+ if (mUpdateSchema == 1) {
+ mSchemaCounter = 0;
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < mSplits.length; i++) {
+ mSplits[i] = 0;
+ }
+
+ mLastUpdate = thisUpdate;
+ // mNextUpdate = nextUpdate;
+ mNextDeltaUpdate = (nextDeltaUpdate != null) ? new Date(nextDeltaUpdate.getTime()) : null;
+ if (nextUpdate != null) {
+ nextUpdate.setTime((nextUpdate.getTime()) + mNextUpdateGracePeriod);
+ }
+ if (nextDeltaUpdate != null) {
+ nextDeltaUpdate.setTime((nextDeltaUpdate.getTime()) + mNextUpdateGracePeriod);
+ }
+
+ mSplits[0] -= System.currentTimeMillis();
+ @SuppressWarnings("unchecked")
+ Hashtable<BigInteger, RevokedCertificate> clonedRevokedCerts =
+ (Hashtable<BigInteger, RevokedCertificate>) mRevokedCerts.clone();
+ @SuppressWarnings("unchecked")
+ Hashtable<BigInteger, RevokedCertificate> clonedUnrevokedCerts =
+ (Hashtable<BigInteger, RevokedCertificate>) mUnrevokedCerts.clone();
+ @SuppressWarnings("unchecked")
+ Hashtable<BigInteger, RevokedCertificate> clonedExpiredCerts =
+ (Hashtable<BigInteger, RevokedCertificate>) mExpiredCerts.clone();
+
+ mSplits[0] += System.currentTimeMillis();
+
+ // starting from the beginning
+
+ if ((!mEnableCRLCache) ||
+ ((mCRLCacheIsCleared && mCRLCerts.isEmpty() && clonedRevokedCerts.isEmpty() &&
+ clonedUnrevokedCerts.isEmpty() && clonedExpiredCerts.isEmpty()) ||
+ (mCRLCerts.isEmpty() && (!clonedUnrevokedCerts.isEmpty())) ||
+ (mCRLCerts.size() < clonedUnrevokedCerts.size()) ||
+ (mCRLCerts.isEmpty() && (mCRLSize > 0)) ||
+ (mCRLCerts.size() > 0 && mCRLSize == 0))) {
+
+ mSplits[5] -= System.currentTimeMillis();
+ mDeltaCRLSize = -1;
+ clearCRLCache();
+ clonedRevokedCerts.clear();
+ clonedUnrevokedCerts.clear();
+ clonedExpiredCerts.clear();
+ mSchemaCounter = 0;
+
+ IStatsSubsystem statsSub = (IStatsSubsystem) CMS.getSubsystem("stats");
+ if (statsSub != null) {
+ statsSub.startTiming("generation");
+ }
+ CertRecProcessor cp = new CertRecProcessor(mCRLCerts, this, mLogger, mAllowExtensions);
+ processRevokedCerts(cp);
+
+ if (statsSub != null) {
+ statsSub.endTiming("generation");
+ }
+
+ mCRLCacheIsCleared = false;
+ mSplits[5] += System.currentTimeMillis();
+ } else {
+ if (isDeltaCRLEnabled()) {
+ mSplits[1] -= System.currentTimeMillis();
+ @SuppressWarnings("unchecked")
+ Hashtable<BigInteger, RevokedCertificate> deltaCRLCerts =
+ (Hashtable<BigInteger, RevokedCertificate>) clonedRevokedCerts.clone();
+
+ deltaCRLCerts.putAll(clonedUnrevokedCerts);
+ if (mIncludeExpiredCertsOneExtraTime) {
+ if (!clonedExpiredCerts.isEmpty()) {
+ for (Enumeration<BigInteger> e = clonedExpiredCerts.keys(); e.hasMoreElements();) {
+ BigInteger serialNumber = e.nextElement();
+ if ((mLastFullUpdate != null &&
+ mLastFullUpdate.after((mExpiredCerts.get(serialNumber)).getRevocationDate())) ||
+ mLastFullUpdate == null) {
+ deltaCRLCerts.put(serialNumber, clonedExpiredCerts.get(serialNumber));
+ }
+ }
+ }
+ } else {
+ deltaCRLCerts.putAll(clonedExpiredCerts);
+ }
+
+ mLastCRLNumber = mCRLNumber;
+
+ CRLExtensions ext = new CRLExtensions();
+ Vector<String> extNames = mCMSCRLExtensions.getCRLExtensionNames();
+
+ for (int i = 0; i < extNames.size(); i++) {
+ String extName = extNames.elementAt(i);
+
+ if (mCMSCRLExtensions.isCRLExtensionEnabled(extName) &&
+ (!extName.equals(FreshestCRLExtension.NAME))) {
+ mCMSCRLExtensions.addToCRLExtensions(ext, extName, null);
+ }
+ }
+ mSplits[1] += System.currentTimeMillis();
+
+ X509CRLImpl newX509DeltaCRL = null;
+
+ try {
+ mSplits[2] -= System.currentTimeMillis();
+ byte[] newDeltaCRL;
+
+ // #56123 - dont generate CRL if no revoked certificates
+ if (mConfigStore.getBoolean("noCRLIfNoRevokedCert", false)) {
+ if (deltaCRLCerts.size() == 0) {
+ CMS.debug("CRLIssuingPoint: No Revoked Certificates Found And noCRLIfNoRevokedCert is set to true - No Delta CRL Generated");
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "No Revoked Certificates"));
+ }
+ }
+ X509CRLImpl crl = new X509CRLImpl(mCA.getCRLX500Name(),
+ AlgorithmId.get(signingAlgorithm),
+ thisUpdate, nextDeltaUpdate, deltaCRLCerts, ext);
+
+ newX509DeltaCRL = mCA.sign(crl, signingAlgorithm);
+ newDeltaCRL = newX509DeltaCRL.getEncoded();
+ mSplits[2] += System.currentTimeMillis();
+
+ mSplits[3] -= System.currentTimeMillis();
+ mCRLRepository.updateDeltaCRL(mId, mNextDeltaCRLNumber,
+ Long.valueOf(deltaCRLCerts.size()), mNextDeltaUpdate, newDeltaCRL);
+ mSplits[3] += System.currentTimeMillis();
+
+ mDeltaCRLSize = deltaCRLCerts.size();
+
+ long totalTime = 0;
+ String splitTimes = " (";
+ for (int i = 1; i < mSplits.length && i < 5; i++) {
+ totalTime += mSplits[i];
+ if (i > 1)
+ splitTimes += ",";
+ splitTimes += Long.toString(mSplits[i]);
+ }
+ splitTimes += ")";
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ CMS.getLogMessage("CMSCORE_CA_CA_DELTA_CRL_UPDATED"),
+ new Object[] {
+ getId(),
+ getNextCRLNumber(),
+ getCRLNumber(),
+ getLastUpdate(),
+ getNextDeltaUpdate(),
+ Long.toString(mDeltaCRLSize),
+ Long.toString(totalTime) + splitTimes
+ }
+ );
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_SIGN_OR_STORE_DELTA", e.toString()));
+ mDeltaCRLSize = -1;
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_SIGN_DELTA", e.toString()));
+ mDeltaCRLSize = -1;
+ } catch (CRLException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_SIGN_DELTA", e.toString()));
+ mDeltaCRLSize = -1;
+ } catch (X509ExtensionException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_SIGN_DELTA", e.toString()));
+ mDeltaCRLSize = -1;
+ } catch (OutOfMemoryError e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_SIGN_DELTA", e.toString()));
+ mDeltaCRLSize = -1;
+ }
+
+ try {
+ mSplits[4] -= System.currentTimeMillis();
+ publishCRL(newX509DeltaCRL, true);
+ mSplits[4] += System.currentTimeMillis();
+ } catch (EBaseException e) {
+ newX509DeltaCRL = null;
+ if (Debug.on())
+ Debug.printStackTrace(e);
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_ISSUING_PUBLISH_DELTA", mCRLNumber.toString(), e.toString()));
+ } catch (OutOfMemoryError e) {
+ newX509DeltaCRL = null;
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_ISSUING_PUBLISH_DELTA", mCRLNumber.toString(), e.toString()));
+ }
+ } else {
+ mDeltaCRLSize = -1;
+ }
+
+ mSplits[5] -= System.currentTimeMillis();
+
+ if (mSchemaCounter == 0) {
+ if (((!mCRLCerts.isEmpty()) && ((!clonedRevokedCerts.isEmpty()) ||
+ (!clonedUnrevokedCerts.isEmpty()) || (!clonedExpiredCerts.isEmpty()))) ||
+ (mCRLCerts.isEmpty() && (mCRLSize == 0) && (!clonedRevokedCerts.isEmpty()))) {
+
+ if (!clonedUnrevokedCerts.isEmpty()) {
+ for (Enumeration<BigInteger> e = clonedUnrevokedCerts.keys(); e.hasMoreElements();) {
+ BigInteger serialNumber = e.nextElement();
+
+ if (mCRLCerts.containsKey(serialNumber)) {
+ mCRLCerts.remove(serialNumber);
+ }
+ mUnrevokedCerts.remove(serialNumber);
+ }
+ }
+
+ if (!clonedRevokedCerts.isEmpty()) {
+ for (Enumeration<BigInteger> e = clonedRevokedCerts.keys(); e.hasMoreElements();) {
+ BigInteger serialNumber = e.nextElement();
+
+ mCRLCerts.put(serialNumber, mRevokedCerts.get(serialNumber));
+ mRevokedCerts.remove(serialNumber);
+ }
+ }
+
+ if (!clonedExpiredCerts.isEmpty()) {
+ for (Enumeration<BigInteger> e = clonedExpiredCerts.keys(); e.hasMoreElements();) {
+ BigInteger serialNumber = e.nextElement();
+
+ if ((!mIncludeExpiredCertsOneExtraTime) ||
+ (mLastFullUpdate != null &&
+ mLastFullUpdate.after((mExpiredCerts.get(serialNumber)).getRevocationDate())) ||
+ mLastFullUpdate == null) {
+ if (mCRLCerts.containsKey(serialNumber)) {
+ mCRLCerts.remove(serialNumber);
+ }
+ mExpiredCerts.remove(serialNumber);
+ }
+ }
+ }
+ }
+ mLastFullUpdate = mLastUpdate;
+ }
+ mSplits[5] += System.currentTimeMillis();
+ }
+
+ clonedRevokedCerts.clear();
+ clonedUnrevokedCerts.clear();
+ clonedExpiredCerts.clear();
+ clonedRevokedCerts = null;
+ clonedUnrevokedCerts = null;
+ clonedExpiredCerts = null;
+
+ if ((!isDeltaCRLEnabled()) || mSchemaCounter == 0) {
+ mSplits[6] -= System.currentTimeMillis();
+ if (mNextDeltaCRLNumber.compareTo(mNextCRLNumber) > 0) {
+ mNextCRLNumber = mNextDeltaCRLNumber;
+ }
+
+ CRLExtensions ext = null;
+
+ if (mAllowExtensions) {
+ ext = new CRLExtensions();
+ Vector<String> extNames = mCMSCRLExtensions.getCRLExtensionNames();
+
+ for (int i = 0; i < extNames.size(); i++) {
+ String extName = extNames.elementAt(i);
+
+ if (mCMSCRLExtensions.isCRLExtensionEnabled(extName) &&
+ (!extName.equals(DeltaCRLIndicatorExtension.NAME))) {
+ mCMSCRLExtensions.addToCRLExtensions(ext, extName, null);
+ }
+ }
+ }
+ mSplits[6] += System.currentTimeMillis();
+ // for audit log
+
+ X509CRLImpl newX509CRL;
+
+ try {
+ byte[] newCRL;
+
+ CMS.debug("Making CRL with algorithm " +
+ signingAlgorithm + " " + AlgorithmId.get(signingAlgorithm));
+
+ mSplits[7] -= System.currentTimeMillis();
+
+ // #56123 - dont generate CRL if no revoked certificates
+ if (mConfigStore.getBoolean("noCRLIfNoRevokedCert", false)) {
+ if (mCRLCerts.size() == 0) {
+ CMS.debug("CRLIssuingPoint: No Revoked Certificates Found And noCRLIfNoRevokedCert is set to true - No CRL Generated");
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "No Revoked Certificates"));
+ }
+ }
+ CMS.debug("before new X509CRLImpl");
+ X509CRLImpl crl = new X509CRLImpl(mCA.getCRLX500Name(),
+ AlgorithmId.get(signingAlgorithm),
+ thisUpdate, nextUpdate, mCRLCerts, ext);
+
+ CMS.debug("before sign");
+ newX509CRL = mCA.sign(crl, signingAlgorithm);
+
+ CMS.debug("before getEncoded()");
+ newCRL = newX509CRL.getEncoded();
+ CMS.debug("after getEncoded()");
+ mSplits[7] += System.currentTimeMillis();
+
+ mSplits[8] -= System.currentTimeMillis();
+
+ Date nextUpdateDate = mNextUpdate;
+ if (isDeltaCRLEnabled() && (mUpdateSchema > 1 ||
+ (mEnableDailyUpdates && mExtendedTimeList)) && mNextDeltaUpdate != null) {
+ nextUpdateDate = mNextDeltaUpdate;
+ }
+ if (mSaveMemory) {
+ mCRLRepository.updateCRLIssuingPointRecord(
+ mId, newCRL, thisUpdate, nextUpdateDate,
+ mNextCRLNumber, Long.valueOf(mCRLCerts.size()));
+ updateCRLCacheRepository();
+ } else {
+ mCRLRepository.updateCRLIssuingPointRecord(
+ mId, newCRL, thisUpdate, nextUpdateDate,
+ mNextCRLNumber, Long.valueOf(mCRLCerts.size()),
+ mRevokedCerts, mUnrevokedCerts, mExpiredCerts);
+ mFirstUnsaved = ICRLIssuingPointRecord.CLEAN_CACHE;
+ }
+
+ mSplits[8] += System.currentTimeMillis();
+
+ mCRLSize = mCRLCerts.size();
+ mCRLNumber = mNextCRLNumber;
+ mDeltaCRLNumber = mCRLNumber;
+ mNextCRLNumber = mCRLNumber.add(BigInteger.ONE);
+ mNextDeltaCRLNumber = mNextCRLNumber;
+
+ CMS.debug("Logging CRL Update to transaction log");
+ long totalTime = 0;
+ long crlTime = 0;
+ long deltaTime = 0;
+ String splitTimes = " (";
+ for (int i = 0; i < mSplits.length; i++) {
+ totalTime += mSplits[i];
+ if (i > 0 && i < 5) {
+ deltaTime += mSplits[i];
+ } else {
+ crlTime += mSplits[i];
+ }
+ if (i > 0)
+ splitTimes += ",";
+ splitTimes += Long.toString(mSplits[i]);
+ }
+ splitTimes +=
+ ","
+ + Long.toString(deltaTime) + "," + Long.toString(crlTime) + ","
+ + Long.toString(totalTime) + ")";
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ CMS.getLogMessage("CMSCORE_CA_CA_CRL_UPDATED"),
+ new Object[] {
+ getId(),
+ getCRLNumber(),
+ getLastUpdate(),
+ getNextUpdate(),
+ Long.toString(mCRLSize),
+ Long.toString(totalTime),
+ Long.toString(crlTime),
+ Long.toString(deltaTime) + splitTimes
+ }
+ );
+ CMS.debug("Finished Logging CRL Update to transaction log");
+
+ } catch (EBaseException e) {
+ newX509CRL = null;
+ mUpdatingCRL = CRL_UPDATE_DONE;
+ if (Debug.on())
+ Debug.printStackTrace(e);
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_SIGN_OR_STORE_CRL", e.toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_FAILED_CONSTRUCTING_CRL", e.toString()));
+ } catch (NoSuchAlgorithmException e) {
+ newX509CRL = null;
+ mUpdatingCRL = CRL_UPDATE_DONE;
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_SIGN_CRL", e.toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_FAILED_CONSTRUCTING_CRL", e.toString()));
+ } catch (CRLException e) {
+ newX509CRL = null;
+ mUpdatingCRL = CRL_UPDATE_DONE;
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_SIGN_CRL", e.toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_FAILED_CONSTRUCTING_CRL", e.toString()));
+ } catch (X509ExtensionException e) {
+ newX509CRL = null;
+ mUpdatingCRL = CRL_UPDATE_DONE;
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_SIGN_CRL", e.toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_FAILED_CONSTRUCTING_CRL", e.toString()));
+ } catch (OutOfMemoryError e) {
+ newX509CRL = null;
+ mUpdatingCRL = CRL_UPDATE_DONE;
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_SIGN_CRL", e.toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_FAILED_CONSTRUCTING_CRL", e.toString()));
+ }
+
+ try {
+ mSplits[9] -= System.currentTimeMillis();
+ mUpdatingCRL = CRL_PUBLISHING_STARTED;
+ publishCRL(newX509CRL);
+ newX509CRL = null;
+ mSplits[9] += System.currentTimeMillis();
+ } catch (EBaseException e) {
+ newX509CRL = null;
+ mUpdatingCRL = CRL_UPDATE_DONE;
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_ISSUING_PUBLISH_CRL", mCRLNumber.toString(), e.toString()));
+ } catch (OutOfMemoryError e) {
+ newX509CRL = null;
+ mUpdatingCRL = CRL_UPDATE_DONE;
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_ISSUING_PUBLISH_CRL", mCRLNumber.toString(), e.toString()));
+ }
+ }
+
+ if (isDeltaCRLEnabled() && mDeltaCRLSize > -1 && mSchemaCounter > 0) {
+ mDeltaCRLNumber = mNextDeltaCRLNumber;
+ mNextDeltaCRLNumber = mDeltaCRLNumber.add(BigInteger.ONE);
+ }
+
+ if ((!(mEnableDailyUpdates && mExtendedTimeList)) || mSchemaCounter == 0)
+ mSchemaCounter++;
+ if ((mEnableDailyUpdates && mExtendedTimeList && mSchemaCounter >= mTimeListSize) ||
+ (mUpdateSchema > 1 && mSchemaCounter >= mUpdateSchema))
+ mSchemaCounter = 0;
+ mLastDay = mCurrentDay;
+
+ mUpdatingCRL = CRL_UPDATE_DONE;
+ notifyAll();
+ }
+
+ /**
+ * publish CRL. called from updateCRLNow() and init().
+ */
+
+ public void publishCRL()
+ throws EBaseException {
+ publishCRL(null);
+ }
+
+ protected void publishCRL(X509CRLImpl x509crl)
+ throws EBaseException {
+ publishCRL(x509crl, false);
+ }
+
+ /*
+ * The Session Context is a Hashtable, but without type information.
+ * Suppress the warnings generated by adding to the session context
+ *
+ */
+ protected void publishCRL(X509CRLImpl x509crl, boolean isDeltaCRL)
+ throws EBaseException {
+ SessionContext sc = SessionContext.getContext();
+
+ IStatsSubsystem statsSub = (IStatsSubsystem) CMS.getSubsystem("stats");
+ if (statsSub != null) {
+ statsSub.startTiming("crl_publishing");
+ }
+
+ if (mCountMod == 0) {
+ sc.put(SC_CRL_COUNT, Integer.toString(mCount));
+ } else {
+ sc.put(SC_CRL_COUNT, Integer.toString(mCount % mCountMod));
+ }
+ mCount++;
+ sc.put(SC_ISSUING_POINT_ID, mId);
+ if (isDeltaCRL) {
+ sc.put(SC_IS_DELTA_CRL, "true");
+ } else {
+ sc.put(SC_IS_DELTA_CRL, "false");
+ }
+
+ ICRLIssuingPointRecord crlRecord = null;
+
+ CMS.debug("Publish CRL");
+ try {
+ if (x509crl == null) {
+ crlRecord = mCRLRepository.readCRLIssuingPointRecord(mId);
+ if (crlRecord != null) {
+ byte[] crl = (isDeltaCRL) ? crlRecord.getDeltaCRL() : crlRecord.getCRL();
+
+ if (crl != null) {
+ x509crl = new X509CRLImpl(crl);
+ }
+ }
+ }
+ if (x509crl != null &&
+ mPublisherProcessor != null && mPublisherProcessor.enabled()) {
+ Enumeration<ILdapRule> rules = mPublisherProcessor.getRules(IPublisherProcessor.PROP_LOCAL_CRL);
+ if (rules == null || !rules.hasMoreElements()) {
+ CMS.debug("CRL publishing is not enabled.");
+ } else {
+ if (mPublishDN != null) {
+ mPublisherProcessor.publishCRL(mPublishDN, x509crl);
+ CMS.debug("CRL published to " + mPublishDN);
+ } else {
+ mPublisherProcessor.publishCRL(x509crl, getId());
+ CMS.debug("CRL published.");
+ }
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug("Could not publish CRL. Error " + e);
+ CMS.debug("Could not publish CRL. ID " + mId);
+ throw new EErrorPublishCRL(
+ CMS.getUserMessage("CMS_CA_ERROR_PUBLISH_CRL", mId, e.toString()));
+ } finally {
+ if (statsSub != null) {
+ statsSub.endTiming("crl_publishing");
+ }
+ }
+ }
+
+ protected void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_CA, level,
+ "CRLIssuingPoint " + mId + " - " + msg);
+ }
+
+ void setConfigParam(String name, String value) {
+ mConfigStore.putString(name, value);
+ }
+
+ class RevocationRequestListener implements IRequestListener {
+
+ public void init(ISubsystem sys, IConfigStore config)
+ throws EBaseException {
+ }
+
+ public void set(String name, String val) {
+ }
+
+ public void accept(IRequest r) {
+ String requestType = r.getRequestType();
+
+ if (requestType.equals(IRequest.REVOCATION_REQUEST) ||
+ requestType.equals(IRequest.UNREVOCATION_REQUEST) ||
+ requestType.equals(IRequest.CLA_CERT4CRL_REQUEST) ||
+ requestType.equals(IRequest.CLA_UNCERT4CRL_REQUEST)) {
+ CMS.debug("Revocation listener called.");
+ // check if serial number is in begin/end range if set.
+ if (mBeginSerial != null || mEndSerial != null) {
+ CMS.debug(
+ "Checking if serial number is between " +
+ mBeginSerial + " and " + mEndSerial);
+ BigInteger[] serialNos =
+ r.getExtDataInBigIntegerArray(IRequest.OLD_SERIALS);
+
+ if (serialNos == null || serialNos.length == 0) {
+ X509CertImpl oldCerts[] =
+ r.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ if (oldCerts == null || oldCerts.length == 0)
+ return;
+ serialNos = new BigInteger[oldCerts.length];
+ for (int i = 0; i < oldCerts.length; i++) {
+ serialNos[i] = oldCerts[i].getSerialNumber();
+ }
+ }
+
+ boolean inRange = false;
+
+ for (int i = 0; i < serialNos.length; i++) {
+ if ((mBeginSerial == null ||
+ serialNos[i].compareTo(mBeginSerial) >= 0) &&
+ (mEndSerial == null ||
+ serialNos[i].compareTo(mEndSerial) <= 0)) {
+ inRange = true;
+ }
+ }
+ if (!inRange) {
+ return;
+ }
+ }
+
+ if (mAlwaysUpdate) {
+ try {
+ updateCRLNow();
+ r.setExtData(mCrlUpdateStatus, IRequest.RES_SUCCESS);
+ if (mPublisherProcessor != null) {
+ r.setExtData(mCrlPublishStatus, IRequest.RES_SUCCESS);
+ }
+ } catch (EErrorPublishCRL e) {
+ // error already logged in updateCRLNow();
+ r.setExtData(mCrlUpdateStatus, IRequest.RES_SUCCESS);
+ if (mPublisherProcessor != null) {
+ r.setExtData(mCrlPublishStatus, IRequest.RES_ERROR);
+ r.setExtData(mCrlPublishError, e);
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_UPDATE_CRL", e.toString()));
+ r.setExtData(mCrlUpdateStatus, IRequest.RES_ERROR);
+ r.setExtData(mCrlUpdateError, e);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_UPDATE_CRL", e.toString()));
+ if (Debug.on())
+ Debug.printStackTrace(e);
+ r.setExtData(mCrlUpdateStatus, IRequest.RES_ERROR);
+ r.setExtData(mCrlUpdateError,
+ new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString())));
+ }
+ }
+ }
+ }
+ }
+}
+
+class CertRecProcessor implements IElementProcessor {
+ private Hashtable<BigInteger, RevokedCertificate> mCRLCerts = null;
+ private boolean mAllowExtensions = false;
+ private ILogger mLogger;
+ private CRLIssuingPoint mIP = null;
+
+ private boolean mIssuingDistPointAttempted = false;
+ private boolean mIssuingDistPointEnabled = false;
+ private BitArray mOnlySomeReasons = null;
+
+ public CertRecProcessor(Hashtable<BigInteger, RevokedCertificate> crlCerts, CRLIssuingPoint ip, ILogger logger,
+ boolean allowExtensions) {
+ mCRLCerts = crlCerts;
+ mLogger = logger;
+ mIP = ip;
+ mAllowExtensions = allowExtensions;
+ mIssuingDistPointAttempted = false;
+ mIssuingDistPointEnabled = false;
+ mOnlySomeReasons = null;
+ }
+
+ private boolean initCRLIssuingDistPointExtension() {
+ boolean result = false;
+ CMSCRLExtensions exts = null;
+
+ if (mIssuingDistPointAttempted == true) {
+ if ((mIssuingDistPointEnabled == true) && (mOnlySomeReasons != null)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ mIssuingDistPointAttempted = true;
+ exts = (CMSCRLExtensions) mIP.getCRLExtensions();
+ if (exts == null) {
+ return result;
+ }
+ boolean isIssuingDistPointExtEnabled = false;
+ isIssuingDistPointExtEnabled =
+ exts.isCRLExtensionEnabled(IssuingDistributionPointExtension.NAME);
+ if (isIssuingDistPointExtEnabled == false) {
+ mIssuingDistPointEnabled = false;
+ return false;
+ }
+
+ mIssuingDistPointEnabled = true;
+
+ //Get info out of the IssuingDistPointExtension
+ CRLExtensions ext = new CRLExtensions();
+ Vector<String> extNames = exts.getCRLExtensionNames();
+ for (int i = 0; i < extNames.size(); i++) {
+ String extName = extNames.elementAt(i);
+ if (extName.equals(IssuingDistributionPointExtension.NAME)) {
+ exts.addToCRLExtensions(ext, extName, null);
+ }
+ }
+ Extension issuingDistExt = null;
+ try {
+ issuingDistExt = ext.get(IssuingDistributionPointExtension.NAME);
+ } catch (Exception e) {
+ }
+
+ IssuingDistributionPointExtension iExt = null;
+ if (issuingDistExt != null)
+ iExt = (IssuingDistributionPointExtension) issuingDistExt;
+ IssuingDistributionPoint issuingDistributionPoint = null;
+ if (iExt != null)
+ issuingDistributionPoint = iExt.getIssuingDistributionPoint();
+
+ BitArray onlySomeReasons = null;
+
+ if (issuingDistributionPoint != null)
+ onlySomeReasons = issuingDistributionPoint.getOnlySomeReasons();
+
+ boolean applyReasonMatch = false;
+
+ if (onlySomeReasons != null) {
+ applyReasonMatch = !onlySomeReasons.toString().equals("0000000");
+ CMS.debug("applyReasonMatch " + applyReasonMatch);
+ if (applyReasonMatch == true) {
+ mOnlySomeReasons = onlySomeReasons;
+ result = true;
+ }
+ }
+ return result;
+ }
+
+ private boolean checkOnlySomeReasonsExtension(CRLExtensions entryExts) {
+ boolean includeCert = true;
+ //This is exactly how the Pretty Print code obtains the reason code
+ //through the extensions
+ if (entryExts == null) {
+ return includeCert;
+ }
+
+ Extension crlReasonExt = null;
+ try {
+ crlReasonExt = entryExts.get(CRLReasonExtension.NAME);
+ } catch (Exception e) {
+ return includeCert;
+ }
+
+ RevocationReason reason = null;
+ int reasonIndex = 0;
+ if (crlReasonExt != null) {
+ try {
+ CRLReasonExtension theReason = (CRLReasonExtension) crlReasonExt;
+ reason = (RevocationReason) theReason.get("value");
+ reasonIndex = reason.toInt();
+ CMS.debug("revoked reason " + reason);
+ } catch (Exception e) {
+ return includeCert;
+ }
+ } else {
+ return includeCert;
+ }
+ boolean reasonMatch = false;
+ if (reason != null) {
+ if (mOnlySomeReasons != null) {
+ reasonMatch = mOnlySomeReasons.get(reasonIndex);
+ if (reasonMatch != true) {
+ includeCert = false;
+ } else {
+ CMS.debug("onlySomeReasons match! reason: " + reason);
+ }
+ }
+ }
+
+ return includeCert;
+ }
+
+ public boolean checkRevokedCertExtensions(CRLExtensions crlExtensions) {
+ //For now just check the onlySomeReason CRL IssuingDistributionPoint extension
+
+ boolean includeCert = true;
+ if ((crlExtensions == null) || (mAllowExtensions == false)) {
+ return includeCert;
+ }
+ boolean inited = initCRLIssuingDistPointExtension();
+
+ //If the CRLIssuingDistPointExtension is not available or
+ // if onlySomeReasons does not apply, bail.
+ if (inited == false) {
+ return includeCert;
+ }
+
+ //Check the onlySomeReasonsExtension
+ includeCert = checkOnlySomeReasonsExtension(crlExtensions);
+
+ return includeCert;
+ }
+
+ public void process(Object o) throws EBaseException {
+ try {
+ CertRecord certRecord = (CertRecord) o;
+
+ CRLExtensions entryExt = null, crlExts = null;
+ BigInteger serialNumber = certRecord.getSerialNumber();
+ Date revocationDate = certRecord.getRevocationDate();
+ IRevocationInfo revInfo = certRecord.getRevocationInfo();
+
+ if (revInfo != null) {
+ crlExts = revInfo.getCRLEntryExtensions();
+ entryExt = mIP.getRequiredEntryExtensions(crlExts);
+ }
+ RevokedCertificate newRevokedCert =
+ new RevokedCertImpl(serialNumber, revocationDate, entryExt);
+
+ boolean includeCert = checkRevokedCertExtensions(crlExts);
+
+ if (includeCert == true) {
+ mCRLCerts.put(serialNumber, newRevokedCert);
+ if (serialNumber != null) {
+ CMS.debug("Putting certificate serial: 0x" + serialNumber.toString(16) + " into CRL hashtable");
+ }
+ }
+ } catch (EBaseException e) {
+ CMS.debug(
+ "CA failed constructing CRL entry: " +
+ (mCRLCerts.size() + 1) + " " + e);
+ throw new ECAException(CMS.getUserMessage("CMS_CA_FAILED_CONSTRUCTING_CRL", e.toString()));
+ }
+ }
+}
diff --git a/base/ca/src/com/netscape/ca/CRLWithExpiredCerts.java b/base/ca/src/com/netscape/ca/CRLWithExpiredCerts.java
new file mode 100644
index 000000000..9ad619ff8
--- /dev/null
+++ b/base/ca/src/com/netscape/ca/CRLWithExpiredCerts.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.ca;
+
+import java.math.BigInteger;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.cmscore.dbs.CertRecord;
+
+/**
+ * A CRL Issuing point that contains revoked certs, include onces that
+ * have expired.
+ */
+public class CRLWithExpiredCerts extends CRLIssuingPoint {
+
+ /**
+ * overrides getRevokedCerts in CRLIssuingPoint to include
+ * all revoked certs, including once that have expired.
+ *
+ * @param thisUpdate parameter is ignored.
+ *
+ * @exception EBaseException if an exception occured getting revoked
+ * certificates from the database.
+ */
+ public String getFilter() {
+ // PLEASE DONT CHANGE THE FILTER. It is indexed.
+ // Changing it will degrade performance. See
+ // also com.netscape.certsetup.LDAPUtil.java
+ String filter =
+ "(|(" + CertRecord.ATTR_CERT_STATUS + "=" +
+ CertRecord.STATUS_REVOKED + ")" +
+ "(" + CertRecord.ATTR_CERT_STATUS + "=" +
+ CertRecord.STATUS_REVOKED_EXPIRED + "))";
+
+ // check if any ranges specified.
+ if (mBeginSerial != null)
+ filter += "(" + CertRecord.ATTR_ID + ">=" + mBeginSerial.toString() + ")";
+ if (mEndSerial != null)
+ filter += "(" + CertRecord.ATTR_ID + "<=" + mEndSerial.toString() + ")";
+ // get all revoked non-expired certs.
+ if (mEndSerial != null || mBeginSerial != null) {
+ filter = "(&" + filter + ")";
+ }
+ return filter;
+ }
+
+ /**
+ * registers expired certificates
+ */
+ public void addExpiredCert(BigInteger serialNumber) {
+ // don't do anything
+ }
+}
diff --git a/base/ca/src/com/netscape/ca/CertificateAuthority.java b/base/ca/src/com/netscape/ca/CertificateAuthority.java
new file mode 100644
index 000000000..c8783f566
--- /dev/null
+++ b/base/ca/src/com/netscape/ca/CertificateAuthority.java
@@ -0,0 +1,2024 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.ca;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.cert.CRLException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateParsingException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CRLImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509ExtensionException;
+import netscape.security.x509.X509Key;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.GeneralizedTime;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.pkix.cert.Extension;
+import org.mozilla.jss.pkix.primitive.Name;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.base.Nonces;
+import com.netscape.certsrv.ca.ECAException;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.IDBSubsystem;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.dbs.crldb.ICRLRepository;
+import com.netscape.certsrv.dbs.replicadb.IReplicaIDRepository;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ocsp.IOCSPService;
+import com.netscape.certsrv.policy.IPolicyProcessor;
+import com.netscape.certsrv.publish.ICRLPublisher;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.request.ARequestNotifier;
+import com.netscape.certsrv.request.IPolicy;
+import com.netscape.certsrv.request.IRequestListener;
+import com.netscape.certsrv.request.IRequestNotifier;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.IRequestScheduler;
+import com.netscape.certsrv.request.IService;
+import com.netscape.certsrv.security.ISigningUnit;
+import com.netscape.certsrv.util.IStatsSubsystem;
+import com.netscape.cmscore.dbs.CRLRepository;
+import com.netscape.cmscore.dbs.CertRecord;
+import com.netscape.cmscore.dbs.CertificateRepository;
+import com.netscape.cmscore.dbs.DBSubsystem;
+import com.netscape.cmscore.dbs.ReplicaIDRepository;
+import com.netscape.cmscore.ldap.PublisherProcessor;
+import com.netscape.cmscore.listeners.ListenerPlugin;
+import com.netscape.cmscore.request.RequestSubsystem;
+import com.netscape.cmscore.security.KeyCertUtil;
+import com.netscape.cmscore.util.Debug;
+import com.netscape.cmsutil.ocsp.BasicOCSPResponse;
+import com.netscape.cmsutil.ocsp.CertID;
+import com.netscape.cmsutil.ocsp.CertStatus;
+import com.netscape.cmsutil.ocsp.GoodInfo;
+import com.netscape.cmsutil.ocsp.KeyHashID;
+import com.netscape.cmsutil.ocsp.NameID;
+import com.netscape.cmsutil.ocsp.OCSPRequest;
+import com.netscape.cmsutil.ocsp.OCSPResponse;
+import com.netscape.cmsutil.ocsp.OCSPResponseStatus;
+import com.netscape.cmsutil.ocsp.ResponderID;
+import com.netscape.cmsutil.ocsp.ResponseBytes;
+import com.netscape.cmsutil.ocsp.ResponseData;
+import com.netscape.cmsutil.ocsp.RevokedInfo;
+import com.netscape.cmsutil.ocsp.SingleResponse;
+import com.netscape.cmsutil.ocsp.TBSRequest;
+import com.netscape.cmsutil.ocsp.UnknownInfo;
+
+/**
+ * A class represents a Certificate Authority that is
+ * responsible for certificate specific operations.
+ * <P>
+ *
+ * @author lhsiao
+ * @version $Revision$, $Date$
+ */
+public class CertificateAuthority implements ICertificateAuthority, ICertAuthority, IOCSPService {
+ public static final String OFFICIAL_NAME = "Certificate Manager";
+
+ public final static OBJECT_IDENTIFIER OCSP_NONCE = new OBJECT_IDENTIFIER("1.3.6.1.5.5.7.48.1.2");
+
+ protected ISubsystem mOwner = null;
+ protected IConfigStore mConfig = null;
+ protected ILogger mLogger = CMS.getLogger();
+ protected Hashtable<String, ICRLIssuingPoint> mCRLIssuePoints = new Hashtable<String, ICRLIssuingPoint>();
+ protected CRLIssuingPoint mMasterCRLIssuePoint = null; // the complete crl.
+ protected SigningUnit mSigningUnit;
+ protected SigningUnit mOCSPSigningUnit;
+ protected SigningUnit mCRLSigningUnit;
+
+ protected X500Name mName = null;
+ protected X500Name mCRLName = null;
+ protected X500Name mOCSPName = null;
+ protected String mNickname = null; // nickname of CA signing cert.
+ protected String mOCSPNickname = null; // nickname of OCSP signing cert.
+ protected long mCertSerialNumberCounter = System.currentTimeMillis();
+ protected long mRequestID = System.currentTimeMillis();
+
+ protected String[] mAllowedSignAlgors = null;
+
+ protected CertificateRepository mCertRepot = null;
+ protected CRLRepository mCRLRepot = null;
+ protected ReplicaIDRepository mReplicaRepot = null;
+
+ protected CertificateChain mCACertChain = null;
+ protected CertificateChain mOCSPCertChain = null;
+ protected X509CertImpl mCRLCert = null;
+ protected org.mozilla.jss.crypto.X509Certificate mCRLX509Cert = null;
+ protected X509CertImpl mCaCert = null;
+ protected org.mozilla.jss.crypto.X509Certificate mCaX509Cert = null;
+ protected X509CertImpl mOCSPCert = null;
+ protected org.mozilla.jss.crypto.X509Certificate mOCSPX509Cert = null;
+ protected String[] mCASigningAlgorithms = null;
+
+ protected PublisherProcessor mPublisherProcessor = null;
+ protected IRequestQueue mRequestQueue = null;
+ protected CAPolicy mPolicy = null;
+ protected CAService mService = null;
+ protected IRequestNotifier mNotify = null;
+ protected IRequestNotifier mPNotify = null;
+ protected long mNumOCSPRequest = 0;
+ protected long mTotalTime = 0;
+ protected long mTotalData = 0;
+ protected long mSignTime = 0;
+ protected long mLookupTime = 0;
+
+ protected static final int FASTSIGNING_DISABLED = 0;
+ protected static final int FASTSIGNING_ENABLED = 1;
+
+ protected CertificateVersion mDefaultCertVersion;
+ protected long mDefaultValidity;
+ protected boolean mEnablePastCATime;
+ protected boolean mEnableOCSP;
+ protected int mFastSigning = FASTSIGNING_DISABLED;
+
+ protected static final long SECOND = 1000; // 1000 milliseconds
+ protected static final long MINUTE = 60 * SECOND;
+ protected static final long HOUR = 60 * MINUTE;
+ protected static final long DAY = 24 * HOUR;
+ protected static final long YEAR = DAY * 365;
+
+ protected static final String PROP_CERT_REPOS_DN = "CertificateRepositoryDN";
+ protected static final String PROP_REPOS_DN = "RepositoryDN";
+ protected static final String PROP_REPLICAID_DN = "dbs.replicadn";
+
+ // for the notification listeners
+
+ /**
+ * Package constants
+ */
+
+ public IRequestListener mCertIssuedListener = null;
+ public IRequestListener mCertRevokedListener = null;
+ public IRequestListener mReqInQListener = null;
+
+ /* cache responder ID for performance */
+ private ResponderID mResponderIDByName = null;
+ private ResponderID mResponderIDByHash = null;
+
+ protected Hashtable<String, ListenerPlugin> mListenerPlugins = null;
+
+ /**
+ * Internal constants
+ */
+
+ protected ICRLPublisher mCRLPublisher = null;
+ private String mId = null;
+
+ private boolean mByName = true;
+
+ private boolean mUseNonces = true;
+ private int mMaxNonces = 100;
+ private Nonces mNonces = null;
+
+ /**
+ * Constructs a CA subsystem.
+ */
+ public CertificateAuthority() {
+ }
+
+ /**
+ * Retrieves subsystem identifier.
+ */
+ public String getId() {
+ return mId;
+ }
+
+ public CertificateVersion getDefaultCertVersion() {
+ return mDefaultCertVersion;
+ }
+
+ public boolean isEnablePastCATime() {
+ return mEnablePastCATime;
+ }
+
+ /**
+ * Sets subsystem identifier.
+ */
+ public void setId(String id) throws EBaseException {
+ mId = id;
+ }
+
+ /**
+ * updates the Master CRL now
+ */
+ public void updateCRLNow() throws EBaseException {
+ if (mMasterCRLIssuePoint != null) {
+ mMasterCRLIssuePoint.updateCRLNow();
+ }
+ }
+
+ public void publishCRLNow() throws EBaseException {
+ if (mMasterCRLIssuePoint != null) {
+ mMasterCRLIssuePoint.publishCRL();
+ }
+ }
+
+ public ICRLPublisher getCRLPublisher() {
+ return mCRLPublisher;
+ }
+
+ /**
+ * @deprecated
+ */
+ public IPolicyProcessor getPolicyProcessor() {
+ return mPolicy.getPolicyProcessor();
+ }
+
+ public boolean noncesEnabled() {
+ return mUseNonces;
+ }
+
+ public Nonces getNonces() {
+ return mNonces;
+ }
+
+ /**
+ * Initializes this CA subsystem.
+ * <P>
+ *
+ * @param owner owner of this subsystem
+ * @param config configuration of this subsystem
+ * @exception EBaseException failed to initialize this CA
+ */
+ public void init(ISubsystem owner, IConfigStore config) throws
+ EBaseException {
+
+ try {
+ CMS.debug("CertificateAuthority init ");
+ mOwner = owner;
+ mConfig = config;
+
+ // init cert & crl database.
+ initCaDatabases();
+
+ // init signing unit & CA cert.
+ try {
+ initSigUnit();
+ // init default CA attributes like cert version, validity.
+ initDefCaAttrs();
+ } catch (EBaseException e) {
+ if (CMS.isPreOpMode())
+ ;
+ else
+ throw e;
+ }
+
+ // init web gateway.
+ initWebGateway();
+
+ mUseNonces = mConfig.getBoolean("enableNonces", true);
+ mMaxNonces = mConfig.getInteger("maxNumberOfNonces", 100);
+ if (mUseNonces) {
+ mNonces = new Nonces(mMaxNonces);
+ CMS.debug("CertificateAuthority init: Nonces enabled. (" + mNonces.size() + ")");
+ }
+
+ // init request queue and related modules.
+ CMS.debug("CertificateAuthority init: initRequestQueue");
+ initRequestQueue();
+ if (CMS.isPreOpMode())
+ return;
+
+ // set certificate status to 10 minutes
+ mCertRepot.setCertStatusUpdateInterval(
+ mRequestQueue.getRequestRepository(),
+ mConfig.getInteger("certStatusUpdateInterval", 10 * 60),
+ mConfig.getBoolean("listenToCloneModifications", false));
+ mCertRepot.setConsistencyCheck(
+ mConfig.getBoolean("ConsistencyCheck", false));
+ mCertRepot.setSkipIfInConsistent(
+ mConfig.getBoolean("SkipIfInConsistent", false));
+
+ mService.init(config.getSubStore("connector"));
+
+ initMiscellaneousListeners();
+
+ // instantiate CRL publisher
+ IConfigStore cpStore = null;
+
+ mByName = config.getBoolean("byName", true);
+
+ cpStore = config.getSubStore("crlPublisher");
+ if (cpStore != null && cpStore.size() > 0) {
+ String publisherClass = cpStore.getString("class");
+
+ if (publisherClass != null) {
+ try {
+ @SuppressWarnings("unchecked")
+ Class<ICRLPublisher> pc = (Class<ICRLPublisher>) Class.forName(publisherClass);
+
+ mCRLPublisher = pc.newInstance();
+ mCRLPublisher.init(this, cpStore);
+ } catch (ClassNotFoundException ee) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_NO_PUBLISHER", ee.toString()));
+ } catch (IllegalAccessException ee) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_NO_PUBLISHER", ee.toString()));
+ } catch (InstantiationException ee) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_NO_PUBLISHER", ee.toString()));
+ }
+ }
+ }
+
+ // initialize publisher processor (publish remote admin
+ // rely on this subsystem, so it has to be initialized)
+ initPublish();
+
+ // Initialize CRL issuing points.
+ // note CRL framework depends on DBS, CRYPTO and PUBLISHING
+ // being functional.
+ initCRL();
+
+ } catch (EBaseException e) {
+ if (CMS.isPreOpMode())
+ return;
+ else
+ throw e;
+ }
+ }
+
+ /**
+ * return CA's request queue processor
+ */
+ public IRequestQueue getRequestQueue() {
+ return mRequestQueue;
+ }
+
+ /**
+ * registers listener
+ */
+ public void registerRequestListener(IRequestListener listener) {
+ mNotify.registerListener(listener);
+ }
+
+ /**
+ * registers listener with a name.
+ */
+ public void registerRequestListener(String name, IRequestListener listener) {
+ mNotify.registerListener(name, listener);
+ }
+
+ /**
+ * removes listener
+ */
+ public void removeRequestListener(IRequestListener listener) {
+ mNotify.removeListener(listener);
+ }
+
+ /**
+ * removes listener with a name.
+ */
+ public void removeRequestListener(String name) {
+ mNotify.removeListener(name);
+ }
+
+ /**
+ * register listener for pending requests
+ */
+ public void registerPendingListener(IRequestListener listener) {
+ mPNotify.registerListener(listener);
+ }
+
+ /**
+ * register listener for pending requests with a name.
+ */
+ public void registerPendingListener(String name, IRequestListener listener) {
+ mPNotify.registerListener(name, listener);
+ }
+
+ /**
+ * get listener from listener list
+ */
+ public IRequestListener getRequestListener(String name) {
+ return mNotify.getListener(name);
+ }
+
+ /**
+ * get notifiers registered by CA
+ */
+ public IRequestNotifier getRequestNotifier() {
+ return mNotify;
+ }
+
+ /**
+ * get listener from listener list
+ */
+ public IRequestListener getPendingListener(String name) {
+ return mPNotify.getListener(name);
+ }
+
+ public Enumeration<String> getRequestListenerNames() {
+ return mNotify.getListenerNames();
+ }
+
+ public IRequestListener getRequestInQListener() {
+ return mReqInQListener;
+ }
+
+ public IRequestListener getCertIssuedListener() {
+ return mCertIssuedListener;
+ }
+
+ public IRequestListener getCertRevokedListener() {
+ return mCertRevokedListener;
+ }
+
+ /**
+ * return CA's policy processor.
+ */
+ public IPolicy getCAPolicy() {
+ return mPolicy;
+ }
+
+ /**
+ * return CA's request queue service object.
+ */
+ public IService getCAService() {
+ return mService;
+ }
+
+ /**
+ * check if the ca is a clone.
+ */
+ public boolean isClone() {
+ if (CAService.mCLAConnector != null)
+ return true;
+ else
+ return false;
+ }
+
+ /**
+ * Starts up this subsystem.
+ */
+ public void startup() throws EBaseException {
+ if (CMS.isPreOpMode()) {
+ return;
+ }
+ mService.startup();
+ mRequestQueue.recover();
+
+ // Note that this could be null.
+
+ // setup Admin operations
+
+ initNotificationListeners();
+
+ startPublish();
+ // startCRL();
+ }
+
+ /**
+ * Shutdowns this subsystem.
+ * <P>
+ */
+ public void shutdown() {
+ Enumeration<ICRLIssuingPoint> enums = mCRLIssuePoints.elements();
+ while (enums.hasMoreElements()) {
+ CRLIssuingPoint point = (CRLIssuingPoint) enums.nextElement();
+ point.shutdown();
+ }
+
+ if (mMasterCRLIssuePoint != null) {
+ mMasterCRLIssuePoint.shutdown();
+ }
+
+ mSigningUnit = null;
+ mOCSPSigningUnit = null;
+ mCRLSigningUnit = null;
+ if (mCertRepot != null) {
+ mCertRepot.shutdown();
+ mCertRepot = null;
+ }
+ mCRLRepot = null;
+ mPublisherProcessor.shutdown();
+ }
+
+ /**
+ * Retrieves the configuration store of this subsystem.
+ * <P>
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Retrieves logger.
+ */
+ public ILogger getLogger() {
+ return CMS.getLogger();
+ }
+
+ /**
+ * Retrieves database services.
+ */
+ public IDBSubsystem getDBSubsystem() {
+ return DBSubsystem.getInstance();
+ }
+
+ public void setValidity(String enableCAPast) throws EBaseException {
+ if (enableCAPast.equals("true"))
+ mEnablePastCATime = true;
+ else
+ mEnablePastCATime = false;
+ mConfig.putString(PROP_ENABLE_PAST_CATIME, enableCAPast);
+ }
+
+ public long getDefaultValidity() {
+ return mDefaultValidity;
+ }
+
+ public SignatureAlgorithm getDefaultSignatureAlgorithm() {
+ return mSigningUnit.getDefaultSignatureAlgorithm();
+ }
+
+ public String getDefaultAlgorithm() {
+ return mSigningUnit.getDefaultAlgorithm();
+ }
+
+ public void setDefaultAlgorithm(String algorithm) throws EBaseException {
+ mSigningUnit.setDefaultAlgorithm(algorithm);
+ }
+
+ public String getStartSerial() {
+ try {
+ BigInteger serial =
+ mCertRepot.getTheSerialNumber();
+
+ if (serial == null)
+ return "";
+ else
+ return serial.toString(16);
+ } catch (EBaseException e) {
+ // shouldn't get here.
+ return "";
+ }
+ }
+
+ public void setStartSerial(String serial) throws EBaseException {
+ mCertRepot.setTheSerialNumber(new BigInteger(serial));
+ }
+
+ public String getMaxSerial() {
+ String serial = mCertRepot.getMaxSerial();
+
+ if (serial != null)
+ return serial;
+ else
+ return "";
+ }
+
+ public void setMaxSerial(String serial) throws EBaseException {
+ mCertRepot.setMaxSerial(serial);
+ }
+
+ /**
+ * Retrieves certificate repository.
+ * <P>
+ *
+ * @return certificate repository
+ */
+ public ICertificateRepository getCertificateRepository() {
+ return mCertRepot;
+ }
+
+ /**
+ * Retrieves replica repository.
+ * <P>
+ *
+ * @return replica repository
+ */
+ public IReplicaIDRepository getReplicaRepository() {
+ return mReplicaRepot;
+ }
+
+ /**
+ * Retrieves CRL repository.
+ */
+ public ICRLRepository getCRLRepository() {
+ return mCRLRepot;
+ }
+
+ public IPublisherProcessor getPublisherProcessor() {
+ return mPublisherProcessor;
+ }
+
+ /**
+ * Retrieves the CRL issuing point by id.
+ * <P>
+ *
+ * @param id string id of the CRL issuing point
+ * @return CRL issuing point
+ */
+ public ICRLIssuingPoint getCRLIssuingPoint(String id) {
+ return mCRLIssuePoints.get(id);
+ }
+
+ /**
+ * Enumerates CRL issuing points
+ * <P>
+ *
+ * @return security service
+ */
+ public Enumeration<ICRLIssuingPoint> getCRLIssuingPoints() {
+ return mCRLIssuePoints.elements();
+ }
+
+ public int getCRLIssuingPointsSize() {
+ return mCRLIssuePoints.size();
+ }
+
+ /**
+ * Adds CRL issuing point with the given identifier and description.
+ */
+ @SuppressWarnings("unchecked")
+ public boolean addCRLIssuingPoint(IConfigStore crlSubStore, String id,
+ boolean enable, String description) {
+ crlSubStore.makeSubStore(id);
+ IConfigStore c = crlSubStore.getSubStore(id);
+
+ if (c != null) {
+ c.putString("allowExtensions", "true");
+ c.putString("alwaysUpdate", "false");
+ c.putString("autoUpdateInterval", "240");
+ c.putString("caCertsOnly", "false");
+ c.putString("cacheUpdateInterval", "15");
+ c.putString("class", "com.netscape.ca.CRLIssuingPoint");
+ c.putString("dailyUpdates", "3:45");
+ c.putString("description", description);
+ c.putBoolean("enable", enable);
+ c.putString("enableCRLCache", "true");
+ c.putString("enableCRLUpdates", "true");
+ c.putString("enableCacheTesting", "false");
+ c.putString("enableCacheRecovery", "true");
+ c.putString("enableDailyUpdates", "false");
+ c.putString("enableUpdateInterval", "true");
+ c.putString("extendedNextUpdate", "true");
+ c.putString("includeExpiredCerts", "false");
+ c.putString("minUpdateInterval", "0");
+ c.putString("nextUpdateGracePeriod", "0");
+ c.putString("publishOnStart", "false");
+ c.putString("saveMemory", "false");
+ c.putString("signingAlgorithm", "SHA256withRSA");
+ c.putString("updateSchema", "1");
+
+ // crl extensions
+ // AuthorityInformationAccess
+ c.putString("extension.AuthorityInformationAccess.enable", "false");
+ c.putString("extension.AuthorityInformationAccess.critical", "false");
+ c.putString("extension.AuthorityInformationAccess.type", "CRLExtension");
+ c.putString("extension.AuthorityInformationAccess.class",
+ "com.netscape.cms.crl.CMSAuthInfoAccessExtension");
+ c.putString("extension.AuthorityInformationAccess.numberOfAccessDescriptions", "1");
+ c.putString("extension.AuthorityInformationAccess.accessMethod0", "caIssuers");
+ c.putString("extension.AuthorityInformationAccess.accessLocationType0", "URI");
+ c.putString("extension.AuthorityInformationAccess.accessLocation0", "");
+ // AuthorityKeyIdentifier
+ c.putString("extension.AuthorityKeyIdentifier.enable", "false");
+ c.putString("extension.AuthorityKeyIdentifier.critical", "false");
+ c.putString("extension.AuthorityKeyIdentifier.type", "CRLExtension");
+ c.putString("extension.AuthorityKeyIdentifier.class",
+ "com.netscape.cms.crl.CMSAuthorityKeyIdentifierExtension");
+ // IssuerAlternativeName
+ c.putString("extension.IssuerAlternativeName.enable", "false");
+ c.putString("extension.IssuerAlternativeName.critical", "false");
+ c.putString("extension.IssuerAlternativeName.type", "CRLExtension");
+ c.putString("extension.IssuerAlternativeName.class",
+ "com.netscape.cms.crl.CMSIssuerAlternativeNameExtension");
+ c.putString("extension.IssuerAlternativeName.numNames", "0");
+ c.putString("extension.IssuerAlternativeName.nameType0", "");
+ c.putString("extension.IssuerAlternativeName.name0", "");
+ // CRLNumber
+ c.putString("extension.CRLNumber.enable", "true");
+ c.putString("extension.CRLNumber.critical", "false");
+ c.putString("extension.CRLNumber.type", "CRLExtension");
+ c.putString("extension.CRLNumber.class",
+ "com.netscape.cms.crl.CMSCRLNumberExtension");
+ // DeltaCRLIndicator
+ c.putString("extension.DeltaCRLIndicator.enable", "false");
+ c.putString("extension.DeltaCRLIndicator.critical", "true");
+ c.putString("extension.DeltaCRLIndicator.type", "CRLExtension");
+ c.putString("extension.DeltaCRLIndicator.class",
+ "com.netscape.cms.crl.CMSDeltaCRLIndicatorExtension");
+ // IssuingDistributionPoint
+ c.putString("extension.IssuingDistributionPoint.enable", "false");
+ c.putString("extension.IssuingDistributionPoint.critical", "true");
+ c.putString("extension.IssuingDistributionPoint.type", "CRLExtension");
+ c.putString("extension.IssuingDistributionPoint.class",
+ "com.netscape.cms.crl.CMSIssuingDistributionPointExtension");
+ c.putString("extension.IssuingDistributionPoint.pointType", "");
+ c.putString("extension.IssuingDistributionPoint.pointName", "");
+ c.putString("extension.IssuingDistributionPoint.onlyContainsUserCerts", "false");
+ c.putString("extension.IssuingDistributionPoint.onlyContainsCACerts", "false");
+ c.putString("extension.IssuingDistributionPoint.onlySomeReasons", "");
+ //"keyCompromise,cACompromise,affiliationChanged,superseded,cessationOfOperation,certificateHold");
+ c.putString("extension.IssuingDistributionPoint.indirectCRL", "false");
+ // CRLReason
+ c.putString("extension.CRLReason.enable", "true");
+ c.putString("extension.CRLReason.critical", "false");
+ c.putString("extension.CRLReason.type", "CRLEntryExtension");
+ c.putString("extension.CRLReason.class",
+ "com.netscape.cms.crl.CMSCRLReasonExtension");
+ // HoldInstruction - removed by RFC 5280
+ // c.putString("extension.HoldInstruction.enable", "false");
+ // c.putString("extension.HoldInstruction.critical", "false");
+ // c.putString("extension.HoldInstruction.type", "CRLEntryExtension");
+ // c.putString("extension.HoldInstruction.class",
+ // "com.netscape.cms.crl.CMSHoldInstructionExtension");
+ // c.putString("extension.HoldInstruction.instruction", "none");
+ // InvalidityDate
+ c.putString("extension.InvalidityDate.enable", "true");
+ c.putString("extension.InvalidityDate.critical", "false");
+ c.putString("extension.InvalidityDate.type", "CRLEntryExtension");
+ c.putString("extension.InvalidityDate.class",
+ "com.netscape.cms.crl.CMSInvalidityDateExtension");
+ // CertificateIssuer
+ /*
+ c.putString("extension.CertificateIssuer.enable", "false");
+ c.putString("extension.CertificateIssuer.critical", "true");
+ c.putString("extension.CertificateIssuer.type", "CRLEntryExtension");
+ c.putString("extension.CertificateIssuer.class",
+ "com.netscape.cms.crl.CMSCertificateIssuerExtension");
+ c.putString("extension.CertificateIssuer.numNames", "0");
+ c.putString("extension.CertificateIssuer.nameType0", "");
+ c.putString("extension.CertificateIssuer.name0", "");
+ */
+ // FreshestCRL
+ c.putString("extension.FreshestCRL.enable", "false");
+ c.putString("extension.FreshestCRL.critical", "false");
+ c.putString("extension.FreshestCRL.type", "CRLExtension");
+ c.putString("extension.FreshestCRL.class",
+ "com.netscape.cms.crl.CMSFreshestCRLExtension");
+ c.putString("extension.FreshestCRL.numPoints", "0");
+ c.putString("extension.FreshestCRL.pointType0", "");
+ c.putString("extension.FreshestCRL.pointName0", "");
+
+ String issuingPointClassName = null;
+ Class<CRLIssuingPoint> issuingPointClass = null;
+ CRLIssuingPoint issuingPoint = null;
+
+ try {
+ issuingPointClassName = c.getString(PROP_CLASS);
+ issuingPointClass = (Class<CRLIssuingPoint>) Class.forName(issuingPointClassName);
+ issuingPoint = (CRLIssuingPoint) issuingPointClass.newInstance();
+ issuingPoint.init(this, id, c);
+ mCRLIssuePoints.put(id, issuingPoint);
+ } catch (EPropertyNotFound e) {
+ crlSubStore.removeSubStore(id);
+ return false;
+ } catch (EBaseException e) {
+ crlSubStore.removeSubStore(id);
+ return false;
+ } catch (ClassNotFoundException e) {
+ crlSubStore.removeSubStore(id);
+ return false;
+ } catch (InstantiationException e) {
+ crlSubStore.removeSubStore(id);
+ return false;
+ } catch (IllegalAccessException e) {
+ crlSubStore.removeSubStore(id);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Deletes CRL issuing point with the given identifier.
+ */
+ public void deleteCRLIssuingPoint(IConfigStore crlSubStore, String id) {
+ CRLIssuingPoint ip = (CRLIssuingPoint) mCRLIssuePoints.get(id);
+
+ if (ip != null) {
+ ip.shutdown();
+ mCRLIssuePoints.remove(id);
+ ip = null;
+ crlSubStore.removeSubStore(id);
+ try {
+ mCRLRepot.deleteCRLIssuingPointRecord(id);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("FAILED_REMOVING_CRL_IP_2", id, e.toString()));
+ }
+ }
+ }
+
+ /**
+ * Returns X500 name of the Certificate Authority
+ * <P>
+ *
+ * @return CA name
+ */
+ public X500Name getX500Name() {
+ return mName;
+ }
+
+ public X500Name getCRLX500Name() {
+ return mCRLName;
+ }
+
+ public X500Name getOCSPX500Name() {
+ return mOCSPName;
+ }
+
+ /**
+ * Returns nickname of CA's signing cert.
+ * <p>
+ *
+ * @return CA signing cert nickname.
+ */
+ public String getNickname() {
+ return mNickname;
+ }
+
+ /**
+ * Returns nickname of OCSP's signing cert.
+ * <p>
+ *
+ * @return OCSP signing cert nickname.
+ */
+ public String getOCSPNickname() {
+ return mOCSPNickname;
+ }
+
+ /**
+ * Returns default signing unit used by this CA
+ * <P>
+ *
+ * @return request identifier
+ */
+ public ISigningUnit getSigningUnit() {
+ return mSigningUnit;
+ }
+
+ public ISigningUnit getCRLSigningUnit() {
+ return mCRLSigningUnit;
+ }
+
+ public ISigningUnit getOCSPSigningUnit() {
+ return mOCSPSigningUnit;
+ }
+
+ public void setBasicConstraintMaxLen(int num) {
+ mConfig.putString("Policy.rule.BasicConstraintsExt.maxPathLen", "" + num);
+ }
+
+ /**
+ * Signs CRL using the specified signature algorithm.
+ * If no algorithm is specified the CA's default signing algorithm
+ * is used.
+ * <P>
+ *
+ * @param crl the CRL to be signed.
+ * @param algname the algorithm name to use. This is a JCA name such
+ * as MD5withRSA, etc. If set to null the default signing algorithm
+ * is used.
+ *
+ * @return the signed CRL
+ */
+ public X509CRLImpl sign(X509CRLImpl crl, String algname)
+ throws EBaseException {
+ X509CRLImpl signedcrl = null;
+
+ IStatsSubsystem statsSub = (IStatsSubsystem) CMS.getSubsystem("stats");
+ if (statsSub != null) {
+ statsSub.startTiming("signing");
+ }
+
+ try {
+ DerOutputStream out = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+
+ if (algname == null) {
+ algname = mSigningUnit.getDefaultAlgorithm();
+ }
+
+ crl.encodeInfo(tmp);
+ AlgorithmId.get(algname).encode(tmp);
+
+ byte[] tbsCertList = crl.getTBSCertList();
+
+ byte[] signature = mCRLSigningUnit.sign(tbsCertList, algname);
+
+ if (crl.setSignature(signature)) {
+ tmp.putBitString(signature);
+ out.write(DerValue.tag_Sequence, tmp);
+
+ if (crl.setSignedCRL(out.toByteArray())) {
+ signedcrl = crl;
+ // signedcrl = new X509CRLImpl(out.toByteArray());
+ } else {
+ CMS.debug("Failed to add signed-CRL to CRL object.");
+ }
+ } else {
+ CMS.debug("Failed to add signature to CRL object.");
+ }
+ } catch (CRLException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_SIGN_CRL", e.toString(), e.getMessage()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_SIGNING_CRL_FAILED", e.getMessage()));
+ } catch (X509ExtensionException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_SIGN_CRL", e.toString(), e.getMessage()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_SIGNING_CRL_FAILED", e.getMessage()));
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_SIGN_CRL", e.toString(), e.getMessage()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_SIGNING_CRL_FAILED", e.getMessage()));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_SIGN_CRL", e.toString(), e.getMessage()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_SIGNING_CRL_FAILED", e.getMessage()));
+ } finally {
+ if (statsSub != null) {
+ statsSub.endTiming("signing");
+ }
+ }
+
+ return signedcrl;
+ }
+
+ /**
+ * Signs the given certificate info using specified signing algorithm
+ * If no algorithm is specified the CA's default algorithm is used.
+ * <P>
+ *
+ * @param certInfo the certificate info to be signed.
+ * @param algname the signing algorithm to use. These are names defined
+ * in JCA, such as MD5withRSA, etc. If null the CA's default
+ * signing algorithm will be used.
+ * @return signed certificate
+ */
+ public X509CertImpl sign(X509CertInfo certInfo, String algname)
+ throws EBaseException {
+
+ X509CertImpl signedcert = null;
+
+ IStatsSubsystem statsSub = (IStatsSubsystem) CMS.getSubsystem("stats");
+ if (statsSub != null) {
+ statsSub.startTiming("signing");
+ }
+
+ try {
+ DerOutputStream out = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+
+ if (certInfo == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_NO_CERTINFO"));
+ return null;
+ }
+
+ if (algname == null) {
+ algname = mSigningUnit.getDefaultAlgorithm();
+ }
+
+ CMS.debug("sign cert get algorithm");
+ AlgorithmId alg = AlgorithmId.get(algname);
+
+ // encode certificate info
+ CMS.debug("sign cert encoding cert");
+ certInfo.encode(tmp);
+ byte[] rawCert = tmp.toByteArray();
+
+ // encode algorithm identifier
+ CMS.debug("sign cert encoding algorithm");
+ alg.encode(tmp);
+
+ CMS.debug("CA cert signing: signing cert");
+ byte[] signature = mSigningUnit.sign(rawCert, algname);
+
+ tmp.putBitString(signature);
+
+ // Wrap the signed data in a SEQUENCE { data, algorithm, sig }
+ out.write(DerValue.tag_Sequence, tmp);
+ //log(ILogger.LL_INFO, "CertificateAuthority: done signing");
+
+ switch (mFastSigning) {
+ case FASTSIGNING_DISABLED:
+ signedcert = new X509CertImpl(out.toByteArray());
+ break;
+
+ case FASTSIGNING_ENABLED:
+ signedcert = new X509CertImpl(out.toByteArray(), certInfo);
+ break;
+
+ default:
+ break;
+ }
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_SIGN_CERT", e.toString(), e.getMessage()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_SIGNING_CERT_FAILED", e.getMessage()));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_SIGN_CERT", e.toString(), e.getMessage()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_SIGNING_CERT_FAILED", e.getMessage()));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_SIGN_CERT", e.toString(), e.getMessage()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_SIGNING_CERT_FAILED", e.getMessage()));
+ } finally {
+ if (statsSub != null) {
+ statsSub.endTiming("signing");
+ }
+ }
+ return signedcert;
+ }
+
+ /**
+ * Sign a byte array using the specified algorithm.
+ * If algorithm is null the CA's default algorithm is used.
+ * <p>
+ *
+ * @param data the data to be signed in a byte array.
+ * @param algname the algorithm to use.
+ * @return the signature in a byte array.
+ */
+ public byte[] sign(byte[] data, String algname)
+ throws EBaseException {
+ return mSigningUnit.sign(data, algname);
+ }
+
+ /**
+ * logs a message in the CA area.
+ *
+ * @param level the debug level.
+ * @param msg the message to debug.
+ */
+ public void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_CA,
+ level, msg);
+ }
+
+ /**
+ * Retrieves certificate chains of this CA.
+ *
+ * @return this CA's cert chain.
+ */
+ public CertificateChain getCACertChain() {
+ return mCACertChain;
+ }
+
+ public X509CertImpl getCACert() {
+ if (mCaCert != null) {
+ return mCaCert;
+ }
+ // during configuration
+ try {
+ String cert = mConfig.getString("signing.cert", null);
+ if (cert != null) {
+ return new X509CertImpl(CMS.AtoB(cert));
+ }
+ } catch (EBaseException e) {
+ CMS.debug(e);
+ } catch (CertificateException e) {
+ CMS.debug(e);
+ }
+ return null;
+ }
+
+ public org.mozilla.jss.crypto.X509Certificate getCaX509Cert() {
+ return mCaX509Cert;
+ }
+
+ public String[] getCASigningAlgorithms() {
+ if (mCASigningAlgorithms != null)
+ return mCASigningAlgorithms;
+
+ if (mCaCert == null)
+ return null; // CA not inited yet.
+ X509Key caPubKey = null;
+
+ try {
+ caPubKey = (X509Key) mCaCert.get(X509CertImpl.PUBLIC_KEY);
+ } catch (CertificateParsingException e) {
+ }
+ if (caPubKey == null)
+ return null; // something seriously wrong.
+ AlgorithmId alg = caPubKey.getAlgorithmId();
+
+ if (alg == null)
+ return null; // something seriously wrong.
+ mCASigningAlgorithms = AlgorithmId.getSigningAlgorithms(alg);
+ if (mCASigningAlgorithms == null) {
+ CMS.debug(
+ "CA - no signing algorithms for " + alg.getName());
+ } else {
+ CMS.debug(
+ "CA First signing algorithm is " + mCASigningAlgorithms[0]);
+ }
+
+ return mCASigningAlgorithms;
+ }
+
+ //////////
+ // Initialization routines.
+ //
+
+ /**
+ * init CA signing unit & cert chain.
+ */
+ private void initSigUnit()
+ throws EBaseException {
+ try {
+ // init signing unit
+ mSigningUnit = new SigningUnit();
+ IConfigStore caSigningCfg =
+ mConfig.getSubStore(PROP_SIGNING_SUBSTORE);
+
+ mSigningUnit.init(this, caSigningCfg);
+ CMS.debug("CA signing unit inited");
+
+ // for identrus
+ IConfigStore CrlStore = mConfig.getSubStore(PROP_CRL_SIGNING_SUBSTORE);
+
+ if (CrlStore != null && CrlStore.size() > 0) {
+ mCRLSigningUnit = new SigningUnit();
+ mCRLSigningUnit.init(this, mConfig.getSubStore(PROP_CRL_SIGNING_SUBSTORE));
+ } else {
+ mCRLSigningUnit = mSigningUnit;
+ }
+
+ // init cert chain
+ CryptoManager manager = CryptoManager.getInstance();
+
+ int caChainNum =
+ caSigningCfg.getInteger(PROP_CA_CHAIN_NUM, 0);
+
+ CMS.debug("cachainNum= " + caChainNum);
+ if (caChainNum > 0) {
+ // custom build chain (for cross cert chain)
+ // audit here ***
+ IConfigStore chainStore =
+ caSigningCfg.getSubStore(PROP_CA_CHAIN);
+
+ if (chainStore == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CA_OCSP_CHAIN",
+ "ca cert chain config error"));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_BUILD_CA_CHAIN_FAILED",
+ "ca cert chain config error"));
+ }
+
+ java.security.cert.X509Certificate[] implchain =
+ new java.security.cert.X509Certificate[caChainNum];
+
+ for (int i = 0; i < caChainNum; i++) {
+ String subtreeName = PROP_CA_CERT + i;
+ // cert file name must be full path
+ String certFileName =
+ chainStore.getString(subtreeName, null);
+
+ if ((certFileName == null) || certFileName.equals("")) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_OCSP_CHAIN", "cert file config error"));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_BUILD_CA_CHAIN_FAILED",
+ "cert file config error"));
+ }
+ byte[] b64Bytes = getCertFromFile(certFileName);
+ String b64String = new String(b64Bytes);
+ byte[] certBytes = KeyCertUtil.convertB64EToByteArray(b64String);
+
+ implchain[i] = new X509CertImpl(certBytes);
+ } // for
+
+ mCACertChain = new CertificateChain(implchain);
+ CMS.debug("in init - custom built CA cert chain.");
+ } else {
+ // build ca chain the traditional way
+ org.mozilla.jss.crypto.X509Certificate[] chain =
+ manager.buildCertificateChain(mSigningUnit.getCert());
+ // do this in case other subsyss expect a X509CertImpl
+ java.security.cert.X509Certificate[] implchain =
+ new java.security.cert.X509Certificate[chain.length];
+
+ for (int i = 0; i < chain.length; i++) {
+ implchain[i] = new X509CertImpl(chain[i].getEncoded());
+ }
+ mCACertChain = new CertificateChain(implchain);
+ CMS.debug("in init - got CA chain from JSS.");
+ }
+
+ IConfigStore OCSPStore = mConfig.getSubStore(PROP_OCSP_SIGNING_SUBSTORE);
+
+ if (OCSPStore != null && OCSPStore.size() > 0) {
+ mOCSPSigningUnit = new SigningUnit();
+ mOCSPSigningUnit.init(this, mConfig.getSubStore(PROP_OCSP_SIGNING_SUBSTORE));
+ CMS.debug("Separate OCSP signing unit inited");
+ } else {
+ mOCSPSigningUnit = mSigningUnit;
+ CMS.debug("Shared OCSP signing unit inited");
+ }
+
+ org.mozilla.jss.crypto.X509Certificate[] ocspChain =
+ manager.buildCertificateChain(mOCSPSigningUnit.getCert());
+ // do this in case other subsyss expect a X509CertImpl
+ java.security.cert.X509Certificate[] ocspImplchain =
+ new java.security.cert.X509Certificate[ocspChain.length];
+
+ for (int i = 0; i < ocspChain.length; i++) {
+ ocspImplchain[i] = new X509CertImpl(ocspChain[i].getEncoded());
+ }
+ mOCSPCertChain = new CertificateChain(ocspImplchain);
+ CMS.debug("in init - got OCSP chain from JSS.");
+ // init issuer name - take name from the cert.
+
+ mCaX509Cert = mSigningUnit.getCert();
+ mCaCert = new X509CertImpl(mCaX509Cert.getEncoded());
+ getCASigningAlgorithms();
+ mName = (X500Name) mCaCert.getSubjectDN();
+
+ mCRLX509Cert = mCRLSigningUnit.getCert();
+ mCRLCert = new X509CertImpl(mCRLX509Cert.getEncoded());
+ mCRLName = (X500Name) mCRLCert.getSubjectDN();
+
+ mOCSPX509Cert = mOCSPSigningUnit.getCert();
+ mOCSPNickname = mOCSPSigningUnit.getNickname();
+ mOCSPCert = new X509CertImpl(mOCSPX509Cert.getEncoded());
+ mOCSPName = (X500Name) mOCSPCert.getSubjectDN();
+ mNickname = mSigningUnit.getNickname();
+ CMS.debug("in init - got CA name " + mName);
+
+ } catch (CryptoManager.NotInitializedException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_OCSP_SIGNING", e.toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_CRYPTO_NOT_INITIALIZED"));
+ } catch (CertificateException e) {
+ if (Debug.ON)
+ e.printStackTrace();
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_OCSP_CHAIN", e.toString()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_BUILD_CA_CHAIN_FAILED", e.toString()));
+ } catch (FileNotFoundException e) {
+ if (Debug.ON)
+ e.printStackTrace();
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_OCSP_CHAIN", e.toString()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_BUILD_CA_CHAIN_FAILED", e.toString()));
+ } catch (IOException e) {
+ if (Debug.ON)
+ e.printStackTrace();
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_OCSP_CHAIN", e.toString()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_BUILD_CA_CHAIN_FAILED", e.toString()));
+ } catch (TokenException e) {
+ if (Debug.ON)
+ e.printStackTrace();
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_OCSP_CHAIN", e.toString()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_BUILD_CA_CHAIN_FAILED", e.toString()));
+ }
+ }
+
+ /**
+ * read ca cert from path, converts and bytes
+ */
+ byte[] getCertFromFile(String path)
+ throws FileNotFoundException, IOException {
+
+ File file = new File(path);
+ Long l = Long.valueOf(file.length());
+ byte[] b = new byte[l.intValue()];
+ FileInputStream in = new FileInputStream(path);
+ in.read(b);
+ in.close();
+
+ return b;
+ }
+
+ /**
+ * init default cert attributes.
+ */
+ private void initDefCaAttrs()
+ throws EBaseException {
+ int version = mConfig.getInteger(PROP_X509CERT_VERSION,
+ CertificateVersion.V3);
+
+ if (version != CertificateVersion.V1 &&
+ version != CertificateVersion.V3) {
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_X509CERT_VERSION_NOT_SUPPORTED"));
+ }
+ try {
+ mDefaultCertVersion = new CertificateVersion(version - 1);
+ } catch (IOException e) {
+ // should never occur.
+ }
+
+ int validity_in_days = mConfig.getInteger(PROP_DEF_VALIDITY, 2 * 365);
+
+ mDefaultValidity = validity_in_days * DAY; // days in config file.
+
+ mEnablePastCATime =
+ mConfig.getBoolean(PROP_ENABLE_PAST_CATIME, false);
+ mEnableOCSP =
+ mConfig.getBoolean(PROP_ENABLE_OCSP, true);
+
+ String fs = mConfig.getString(PROP_FAST_SIGNING, "");
+
+ if (fs.equals("enabled") || fs.equals("enable")) {
+ mFastSigning = FASTSIGNING_ENABLED;
+ } else {
+ mFastSigning = FASTSIGNING_DISABLED;
+ }
+
+ }
+
+ /**
+ * init cert & crl database
+ */
+ private void initCaDatabases()
+ throws EBaseException {
+ int certdb_inc = mConfig.getInteger(PROP_CERTDB_INC, 5);
+
+ String certReposDN = mConfig.getString(PROP_CERT_REPOS_DN, null);
+
+ if (certReposDN == null) {
+ certReposDN = "ou=certificateRepository, ou=" + getId() +
+ ", " + getDBSubsystem().getBaseDN();
+ }
+ String reposDN = mConfig.getString(PROP_REPOS_DN, null);
+
+ if (reposDN == null) {
+ reposDN = "ou=certificateRepository, ou=" + getId() +
+ ", " + getDBSubsystem().getBaseDN();
+ }
+
+ int transitMaxRecords = mConfig.getInteger(PROP_CERTDB_TRANS_MAXRECORDS, 1000000);
+ int transitRecordPageSize = mConfig.getInteger(PROP_CERTDB_TRANS_PAGESIZE, 200);
+
+ mCertRepot = new CertificateRepository(
+ DBSubsystem.getInstance(),
+ certReposDN, certdb_inc, reposDN);
+
+ mCertRepot.setTransitMaxRecords(transitMaxRecords);
+ mCertRepot.setTransitRecordPageSize(transitRecordPageSize);
+
+ CMS.debug("Cert Repot inited");
+
+ // init crl repot.
+
+ int crldb_inc = mConfig.getInteger(PROP_CRLDB_INC, 5);
+
+ mCRLRepot = new CRLRepository(
+ DBSubsystem.getInstance(),
+ crldb_inc,
+ "ou=crlIssuingPoints, ou=" + getId() + ", " +
+ getDBSubsystem().getBaseDN());
+ CMS.debug("CRL Repot inited");
+
+ String replicaReposDN = mConfig.getString(PROP_REPLICAID_DN, null);
+ if (replicaReposDN == null) {
+ replicaReposDN = "ou=Replica," + getDBSubsystem().getBaseDN();
+ }
+ mReplicaRepot = new ReplicaIDRepository(
+ DBSubsystem.getInstance(), 1, replicaReposDN);
+ CMS.debug("Replica Repot inited");
+
+ }
+
+ /**
+ * init web gateway - just gets the ee gateway for this CA.
+ */
+ private void initWebGateway()
+ throws EBaseException {
+ }
+
+ private void startPublish()
+ throws EBaseException {
+ //xxx Note that CMS411 only support ca cert publishing to ldap
+ // if ldap publishing is not enabled while publishing isenabled
+ // there will be a lot of problem.
+ try {
+ if (mPublisherProcessor.enabled()) {
+ mPublisherProcessor.publishCACert(mCaCert);
+ CMS.debug("published ca cert");
+ }
+ } catch (ELdapException e) {
+ // exception not thrown - not seen as a fatal error.
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_PUBLISH", e.toString()));
+ }
+ }
+
+ /**
+ * init publishing
+ */
+ private void initPublish()
+ throws EBaseException {
+ IConfigStore c = null;
+
+ try {
+ c = mConfig.getSubStore(PROP_PUBLISH_SUBSTORE);
+ if (c != null && c.size() > 0) {
+ mPublisherProcessor = new PublisherProcessor(
+ getId() + "pp");
+ mPublisherProcessor.init(this, c);
+ CMS.debug("Publishing inited");
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_NO_PUBLISH"));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_INIT_PUBLISH_MODULE_FAILED"));
+ }
+
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_ERROR_PUBLISH_MODULE", e.toString()));
+ //throw new ECAException(
+ // CAResources.INIT_PUBLISH_MODULE_FAILED, e);
+ }
+ }
+
+ private void initMiscellaneousListeners() {
+ IConfigStore lc = null;
+ IConfigStore implc = null;
+ IConfigStore instc = null;
+
+ mListenerPlugins = new Hashtable<String, ListenerPlugin>();
+ try {
+ // Get list of listener implementations
+ lc = mConfig.getSubStore(PROP_LISTENER_SUBSTORE);
+ if (lc != null) {
+
+ implc = lc.getSubStore(PROP_IMPL);
+ Enumeration<String> names = implc.getSubStoreNames();
+
+ while (names.hasMoreElements()) {
+ String id = names.nextElement();
+
+ if (Debug.ON)
+ Debug.trace("registering listener impl: " + id);
+ String cl = implc.getString(id + "." + PROP_CLASS);
+
+ ListenerPlugin plugin = new ListenerPlugin(id, cl);
+
+ mListenerPlugins.put(id, plugin);
+ }
+
+ instc = lc.getSubStore(PROP_INSTANCE);
+ Enumeration<String> instances = instc.getSubStoreNames();
+
+ while (instances.hasMoreElements()) {
+ String id = (String) instances.nextElement();
+
+ if (Debug.ON)
+ Debug.trace("registering listener instance: " + id);
+ IConfigStore iConfig = instc.getSubStore(id);
+ String implName = instc.getString(id + "." + PROP_PLUGIN);
+ ListenerPlugin plugin = (ListenerPlugin) mListenerPlugins.get(implName);
+
+ if (plugin == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_ERROR_LISTENER", implName));
+ throw new Exception("Cannot initialize");
+ }
+ String className = plugin.getClassPath();
+
+ try {
+ IRequestListener listener = null;
+
+ listener = (IRequestListener)
+ Class.forName(className).newInstance();
+
+ //listener.init(id, implName, iConfig);
+ listener.init(this, iConfig);
+ // registerRequestListener(id, (IRequestListener) listener);
+ //log(ILogger.LL_INFO,
+ // "Listener instance " + id + " added");
+
+ } catch (Exception e) {
+ if (Debug.ON) {
+ e.printStackTrace();
+ }
+ Debug.trace("failed to add listener instance");
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_INIT_LISTENER", id, e.toString()));
+ throw e;
+ }
+ }
+
+ }
+
+ } catch (Exception e) {
+ log(ILogger.LL_INFO, CMS.getLogMessage("CMSCORE_CA_CA_FAILED_LISTENER", e.toString()));
+ }
+
+ }
+
+ /**
+ * init notification related listeners
+ */
+ private void initNotificationListeners() {
+ IConfigStore nc = null;
+
+ try {
+ nc = mConfig.getSubStore(PROP_NOTIFY_SUBSTORE);
+ if (nc != null && nc.size() > 0) {
+ // Initialize Certificate Issued notification listener
+
+ String certificateIssuedListenerClassName =
+ nc.getString("certificateIssuedListenerClassName",
+ "com.netscape.cms.listeners.CertificateIssuedListener");
+
+ try {
+ mCertIssuedListener =
+ (IRequestListener) Class.forName(certificateIssuedListenerClassName).newInstance();
+ mCertIssuedListener.init(this, nc);
+ } catch (Exception e1) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CA_REGISTER_LISTENER", certificateIssuedListenerClassName));
+ }
+
+ // Initialize Revoke Request notification listener
+
+ String certificateRevokedListenerClassName =
+ nc.getString("certificateIssuedListenerClassName",
+ "com.netscape.cms.listeners.CertificateRevokedListener");
+
+ try {
+ mCertRevokedListener =
+ (IRequestListener) Class.forName(certificateRevokedListenerClassName).newInstance();
+ mCertRevokedListener.init(this, nc);
+ } catch (Exception e1) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CA_REGISTER_LISTENER", certificateRevokedListenerClassName));
+ }
+
+ // Initialize Request In Queue notification listener
+ String requestInQListenerClassName =
+ nc.getString("certificateIssuedListenerClassName",
+ "com.netscape.cms.listeners.RequestInQListener");
+
+ try {
+ mReqInQListener = (IRequestListener) Class.forName(requestInQListenerClassName).newInstance();
+ mReqInQListener.init(this, nc);
+ } catch (Exception e1) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_CA_CA_REGISTER_REQ_LISTENER", requestInQListenerClassName));
+ }
+
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_NOTIFY_NONE"));
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_NOTIFY_FAILED"));
+ // throw e;
+ }
+ }
+
+ /**
+ * initialize request queue components
+ */
+ private void initRequestQueue()
+ throws EBaseException {
+ mPolicy = new CAPolicy();
+ ((CAPolicy) mPolicy).init(this, mConfig.getSubStore(PROP_POLICY));
+ CMS.debug("CA policy inited");
+ mService = new CAService(this);
+ CMS.debug("CA service inited");
+
+ mNotify = new ARequestNotifier(this);
+ CMS.debug("CA notifier inited");
+ mPNotify = new ARequestNotifier();
+ CMS.debug("CA pending notifier inited");
+
+ // instantiate CA request queue.
+ try {
+ int reqdb_inc = mConfig.getInteger("reqdbInc", 5);
+
+ mRequestQueue =
+ RequestSubsystem.getInstance().getRequestQueue(
+ getId(), reqdb_inc, mPolicy, mService, mNotify, mPNotify);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_QUEUE_FAILED", e.toString()));
+ throw e;
+ }
+
+ // init request scheduler if configured
+ String schedulerClass =
+ mConfig.getString("requestSchedulerClass", null);
+
+ if (schedulerClass != null) {
+ try {
+ IRequestScheduler scheduler = (IRequestScheduler)
+ Class.forName(schedulerClass).newInstance();
+
+ mRequestQueue.setRequestScheduler(scheduler);
+ } catch (Exception e) {
+ // do nothing here
+ }
+ }
+ }
+
+ /*
+ private void startCRL()
+ throws EBaseException
+ {
+ Enumeration e = mCRLIssuePoints.keys();
+ while (e.hasMoreElements()) {
+ CRLIssuingPoint cp = (CRLIssuingPoint)
+ mCRLIssuePoints.get(e.nextElement());
+ cp.startup();
+ }
+ }
+ */
+
+ /**
+ * initialize CRL
+ */
+ @SuppressWarnings("unchecked")
+ private void initCRL()
+ throws EBaseException {
+ IConfigStore crlConfig = mConfig.getSubStore(PROP_CRL_SUBSTORE);
+
+ if ((crlConfig == null) || (crlConfig.size() <= 0)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_NO_MASTER_CRL"));
+ //throw new ECAException(CAResources.NO_CONFIG_FOR_MASTER_CRL);
+ return;
+ }
+ Enumeration<String> issuePointIdEnum = crlConfig.getSubStoreNames();
+
+ if (issuePointIdEnum == null || !issuePointIdEnum.hasMoreElements()) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_NO_MASTER_CRL_SUBSTORE"));
+ //throw new ECAException(CAResources.NO_CONFIG_FOR_MASTER_CRL);
+ return;
+ }
+
+ // a Master/full crl must exist.
+
+ while (issuePointIdEnum.hasMoreElements()) {
+ String issuePointId = issuePointIdEnum.nextElement();
+
+ CMS.debug(
+ "initializing crl issue point " + issuePointId);
+ IConfigStore issuePointConfig = null;
+ String issuePointClassName = null;
+ Class<CRLIssuingPoint> issuePointClass = null;
+ CRLIssuingPoint issuePoint = null;
+
+ try {
+ issuePointConfig = crlConfig.getSubStore(issuePointId);
+ issuePointClassName = issuePointConfig.getString(PROP_CLASS);
+ issuePointClass = (Class<CRLIssuingPoint>) Class.forName(issuePointClassName);
+ issuePoint = issuePointClass.newInstance();
+ issuePoint.init(this, issuePointId, issuePointConfig);
+ mCRLIssuePoints.put(issuePointId, issuePoint);
+ if (mMasterCRLIssuePoint == null &&
+ issuePointId.equals(PROP_MASTER_CRL))
+ mMasterCRLIssuePoint = issuePoint;
+ } catch (ClassNotFoundException e) {
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_CRL_ISSUING_POINT_INIT_FAILED",
+ issuePointId, e.toString()));
+ } catch (InstantiationException e) {
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_CRL_ISSUING_POINT_INIT_FAILED",
+ issuePointId, e.toString()));
+ } catch (IllegalAccessException e) {
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_CRL_ISSUING_POINT_INIT_FAILED",
+ issuePointId, e.toString()));
+ }
+ }
+
+ /*
+ if (mMasterCRLIssuePoint == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_NO_FULL_CRL", PROP_MASTER_CRL));
+ throw new ECAException(CAResources.NO_CONFIG_FOR_MASTER_CRL);
+ }
+ */
+ log(ILogger.LL_INFO, "CRL Issuing Points inited");
+ }
+
+ public String getOfficialName() {
+ return OFFICIAL_NAME;
+ }
+
+ public long getNumOCSPRequest() {
+ return mNumOCSPRequest;
+ }
+
+ public long getOCSPRequestTotalTime() {
+ return mTotalTime;
+ }
+
+ public long getOCSPTotalData() {
+ return mTotalData;
+ }
+
+ public long getOCSPTotalSignTime() {
+ return mSignTime;
+ }
+
+ public long getOCSPTotalLookupTime() {
+ return mLookupTime;
+ }
+
+ public ResponderID getResponderIDByName() {
+ try {
+ X500Name name = getOCSPX500Name();
+ Name.Template nameTemplate = new Name.Template();
+
+ return new NameID((Name) nameTemplate.decode(
+ new ByteArrayInputStream(name.getEncoded())));
+ } catch (IOException e) {
+ return null;
+ } catch (InvalidBERException e) {
+ return null;
+ }
+ }
+
+ public ResponderID getResponderIDByHash() {
+
+ /*
+ KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key
+ --(excluding the tag and length fields)
+ */
+ PublicKey publicKey = getOCSPSigningUnit().getPublicKey();
+ MessageDigest md = null;
+
+ try {
+ md = MessageDigest.getInstance("SHA1");
+ } catch (NoSuchAlgorithmException e) {
+ return null;
+ }
+ md.update(publicKey.getEncoded());
+ byte digested[] = md.digest();
+
+ return new KeyHashID(new OCTET_STRING(digested));
+ }
+
+ /**
+ * Process OCSPRequest.
+ */
+ public OCSPResponse validate(OCSPRequest request)
+ throws EBaseException {
+
+ if (!mEnableOCSP) {
+ CMS.debug("Local ocsp service is disable.");
+ return null;
+ }
+
+ mNumOCSPRequest++;
+ IStatsSubsystem statsSub = (IStatsSubsystem) CMS.getSubsystem("stats");
+ long startTime = CMS.getCurrentDate().getTime();
+ try {
+ //log(ILogger.LL_INFO, "start OCSP request");
+ TBSRequest tbsReq = request.getTBSRequest();
+
+ // (3) look into database to check the
+ // certificate's status
+ Vector<SingleResponse> singleResponses = new Vector<SingleResponse>();
+ 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");
+ }
+ mLookupTime += lookupEndTime - lookupStartTime;
+
+ if (statsSub != null) {
+ statsSub.startTiming("build_response");
+ }
+ SingleResponse res[] = new SingleResponse[singleResponses.size()];
+
+ singleResponses.copyInto(res);
+
+ ResponderID rid = null;
+ if (mByName) {
+ if (mResponderIDByName == null) {
+ mResponderIDByName = getResponderIDByName();
+ }
+ rid = mResponderIDByName;
+ } else {
+ if (mResponderIDByHash == null) {
+ mResponderIDByHash = getResponderIDByHash();
+ }
+ rid = mResponderIDByHash;
+ }
+
+ Extension nonce[] = null;
+
+ for (int j = 0; j < tbsReq.getExtensionsCount(); j++) {
+ Extension thisExt = tbsReq.getRequestExtensionAt(j);
+
+ if (thisExt.getExtnId().equals(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 = sign(rd);
+ long signEndTime = CMS.getCurrentDate().getTime();
+ mSignTime += 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();
+ mTotalTime += endTime - startTime;
+ return response;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_OCSP_REQUEST", e.toString()));
+ return null;
+ }
+ }
+
+ private BasicOCSPResponse sign(ResponseData rd) throws EBaseException {
+ try {
+ DerOutputStream out = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+
+ String algname = mOCSPSigningUnit.getDefaultAlgorithm();
+
+ byte rd_data[] = ASN1Util.encode(rd);
+ if (rd_data != null) {
+ mTotalData += rd_data.length;
+ }
+ rd.encode(tmp);
+ AlgorithmId.get(algname).encode(tmp);
+ CMS.debug("adding signature");
+ byte[] signature = mOCSPSigningUnit.sign(rd_data, algname);
+
+ tmp.putBitString(signature);
+ // optional, put the certificate chains in also
+
+ DerOutputStream tmpChain = new DerOutputStream();
+ DerOutputStream tmp1 = new DerOutputStream();
+ java.security.cert.X509Certificate chains[] =
+ mOCSPCertChain.getChain();
+
+ for (int i = 0; i < chains.length; i++) {
+ tmpChain.putDerValue(new DerValue(chains[i].getEncoded()));
+ }
+ tmp1.write(DerValue.tag_Sequence, tmpChain);
+ tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0),
+ tmp1);
+
+ out.write(DerValue.tag_Sequence, tmp);
+
+ BasicOCSPResponse response = new BasicOCSPResponse(out.toByteArray());
+
+ return response;
+ } catch (Exception e) {
+ e.printStackTrace();
+ // error e
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_CA_OCSP_SIGN", e.toString()));
+ return null;
+ }
+ }
+
+ private SingleResponse processRequest(CertID cid) {
+ INTEGER serialNo = cid.getSerialNumber();
+
+ CMS.debug("process request " + serialNo);
+ CertStatus certStatus = null;
+ GeneralizedTime thisUpdate = new GeneralizedTime(CMS.getCurrentDate());
+ GeneralizedTime nextUpdate = null;
+
+ boolean ocspUseCache = true;
+
+ try {
+ /* enable OCSP cache by default */
+ ocspUseCache = mConfig.getBoolean("ocspUseCache", false);
+ } catch (EBaseException e) {
+ }
+
+ if (ocspUseCache) {
+ String issuingPointId = PROP_MASTER_CRL;
+
+ try {
+ issuingPointId = mConfig.getString(
+ "ocspUseCacheIssuingPointId", PROP_MASTER_CRL);
+
+ } catch (EBaseException e) {
+ }
+ CRLIssuingPoint point = (CRLIssuingPoint)
+ getCRLIssuingPoint(issuingPointId);
+
+ if (point.isCRLCacheEnabled()) {
+ // only do this if cache is enabled
+ BigInteger sno = new BigInteger(serialNo.toString());
+ boolean checkDeltaCache = false;
+ boolean includeExpiredCerts = false;
+
+ try {
+ checkDeltaCache = mConfig.getBoolean("ocspUseCacheCheckDeltaCache", false);
+ } catch (EBaseException e) {
+ }
+ try {
+ includeExpiredCerts = mConfig.getBoolean("ocspUseCacheIncludeExpiredCerts", false);
+ } catch (EBaseException e) {
+ }
+ Date revokedOn = point.getRevocationDateFromCache(
+ sno, checkDeltaCache, includeExpiredCerts);
+
+ if (revokedOn == null) {
+ certStatus = new GoodInfo();
+ } else {
+ certStatus = new RevokedInfo(new GeneralizedTime(revokedOn));
+ }
+ return new SingleResponse(cid, certStatus, thisUpdate, nextUpdate);
+ }
+ }
+
+ try {
+ ICertRecord rec = mCertRepot.readCertificateRecord(serialNo);
+ String status = rec.getStatus();
+
+ if (status == null) {
+ certStatus = new UnknownInfo();
+ } else if (status.equals(CertRecord.STATUS_VALID)) {
+ certStatus = new GoodInfo();
+ } else if (status.equals(CertRecord.STATUS_INVALID)) {
+ // not yet valid
+ certStatus = new UnknownInfo();
+ } else if (status.equals(CertRecord.STATUS_REVOKED)) {
+ certStatus = new RevokedInfo(new GeneralizedTime(rec.getRevokedOn()));
+ } else if (status.equals(CertRecord.STATUS_EXPIRED)) {
+ certStatus = new UnknownInfo();
+ } else if (status.equals(CertRecord.STATUS_REVOKED_EXPIRED)) {
+ certStatus = new RevokedInfo(new GeneralizedTime(rec.getRevokedOn()));
+ } else {
+ certStatus = new UnknownInfo();
+ }
+ } catch (Exception e) {
+ // not found
+ certStatus = new UnknownInfo(); // not issued not all
+ }
+
+ return new SingleResponse(cid, certStatus, thisUpdate, nextUpdate);
+ }
+}
diff --git a/base/ca/src/com/netscape/ca/SigningUnit.java b/base/ca/src/com/netscape/ca/SigningUnit.java
new file mode 100644
index 000000000..85e3621d7
--- /dev/null
+++ b/base/ca/src/com/netscape/ca/SigningUnit.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.ca;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.SignatureException;
+
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509Key;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.NoSuchTokenException;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.ObjectNotFoundException;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.crypto.Signature;
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.util.IncorrectPasswordException;
+import org.mozilla.jss.util.PasswordCallback;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ca.ECAException;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.security.ISigningUnit;
+import com.netscape.cmscore.security.JssSubsystem;
+import com.netscape.cmsutil.util.Cert;
+
+/**
+ * CA signing unit based on JSS.
+ *
+ * $Revision$ $Date$
+ */
+
+public final class SigningUnit implements 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";
+
+ private CryptoManager mManager = null;
+ private CryptoToken mToken = null;
+ private PublicKey mPubk = null;
+ private PrivateKey mPrivk = null;
+
+ protected X509Certificate mCert = null;
+ protected X509CertImpl mCertImpl = null;
+ protected String mNickname = null;
+
+ private boolean mInited = false;
+ private ILogger mLogger = CMS.getLogger();
+ private IConfigStore mConfig;
+
+ private ISubsystem mOwner = null;
+
+ private String mDefSigningAlgname = null;
+ private SignatureAlgorithm mDefSigningAlgorithm = null;
+
+ public SigningUnit() {
+ }
+
+ public X509Certificate getCert() {
+ return mCert;
+ }
+
+ public X509CertImpl getCertImpl() {
+ return mCertImpl;
+ }
+
+ public String getNickname() {
+ return mNickname;
+ }
+
+ public String getNewNickName() throws EBaseException {
+ return mConfig.getString(PROP_NEW_NICKNAME, "");
+ }
+
+ public void setNewNickName(String name) {
+ mConfig.putString(PROP_NEW_NICKNAME, name);
+ }
+
+ public PublicKey getPublicKey() {
+ return mPubk;
+ }
+
+ public PrivateKey getPrivateKey() {
+ return mPrivk;
+ }
+
+ public void updateConfig(String nickname, String tokenname) {
+ mConfig.putString(PROP_CERT_NICKNAME, nickname);
+ mConfig.putString(PROP_TOKEN_NAME, tokenname);
+ }
+
+ public String getTokenName() throws EBaseException {
+ return mConfig.getString(PROP_TOKEN_NAME);
+ }
+
+ public String getNickName() throws EBaseException {
+ try {
+ return mConfig.getString(PROP_RENAMED_CERT_NICKNAME);
+ } catch (EBaseException e) {
+ return mConfig.getString(PROP_CERT_NICKNAME);
+ }
+ }
+
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mOwner = owner;
+ mConfig = config;
+
+ String tokenname = null;
+ try {
+ mManager = CryptoManager.getInstance();
+
+ mNickname = getNickName();
+
+ tokenname = config.getString(PROP_TOKEN_NAME);
+ if (tokenname.equalsIgnoreCase(Constants.PR_INTERNAL_TOKEN) ||
+ tokenname.equalsIgnoreCase("Internal Key Storage Token")) {
+ mToken = mManager.getInternalKeyStorageToken();
+ setNewNickName(mNickname);
+ } else {
+ mToken = mManager.getTokenByName(tokenname);
+ mNickname = tokenname + ":" + mNickname;
+ setNewNickName(mNickname);
+ }
+ CMS.debug(config.getName() + " Signing Unit nickname " + mNickname);
+ CMS.debug("Got token " + tokenname + " by name");
+
+ PasswordCallback cb = JssSubsystem.getInstance().getPWCB();
+
+ mToken.login(cb); // ONE_TIME by default.
+
+ mCert = mManager.findCertByNickname(mNickname);
+ CMS.debug("Found cert by nickname: '" + mNickname + "' with serial number: " + mCert.getSerialNumber());
+
+ mCertImpl = new X509CertImpl(mCert.getEncoded());
+ CMS.debug("converted to x509CertImpl");
+
+ mPrivk = mManager.findPrivKeyByCert(mCert);
+ CMS.debug("Got private key from cert");
+
+ mPubk = mCert.getPublicKey();
+ CMS.debug("Got public key from cert");
+
+ // get def alg and check if def sign alg is valid for token.
+ mDefSigningAlgname = config.getString(PROP_DEFAULT_SIGNALG);
+ mDefSigningAlgorithm =
+ checkSigningAlgorithmFromName(mDefSigningAlgname);
+ CMS.debug(
+ "got signing algorithm " + mDefSigningAlgorithm);
+ mInited = true;
+ } catch (java.security.cert.CertificateException e) {
+ CMS.debug("SigningUnit init: debug " + e.toString());
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_SIGNING_CA_CERT", e.getMessage()));
+ throw new ECAException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (CryptoManager.NotInitializedException e) {
+ CMS.debug("SigningUnit init: debug " + e.toString());
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_SIGNING_TOKEN_INIT", e.toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_CRYPTO_NOT_INITIALIZED"));
+ } catch (IncorrectPasswordException e) {
+ CMS.debug("SigningUnit init: debug " + e.toString());
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_SIGNING_WRONG_PWD", e.toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_INVALID_PASSWORD"));
+ } catch (NoSuchTokenException e) {
+ CMS.debug("SigningUnit init: debug " + e.toString());
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_SIGNING_TOKEN_NOT_FOUND", tokenname, e.toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_TOKEN_NOT_FOUND", tokenname));
+ } catch (ObjectNotFoundException e) {
+ CMS.debug("SigningUnit init: debug " + e.toString());
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_SIGNING_CERT_NOT_FOUND", e.toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_CERT_OBJECT_NOT_FOUND"));
+ } catch (TokenException e) {
+ CMS.debug("SigningUnit init: debug " + e.toString());
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ throw new ECAException(CMS.getUserMessage("CMS_CA_TOKEN_ERROR"));
+ } catch (Exception e) {
+ CMS.debug("SigningUnit init: debug " + e.toString());
+ }
+ }
+
+ /**
+ * Check if the signing algorithm name is supported and valid for this
+ * signing unit's token and key.
+ *
+ * @param algname a signing algorithm name from JCA.
+ * @return the mapped JSS signature algorithm object.
+ *
+ * @exception EBaseException if signing algorithm is not supported.
+ */
+ public SignatureAlgorithm checkSigningAlgorithmFromName(String algname)
+ throws EBaseException {
+ try {
+ SignatureAlgorithm sigalg = null;
+
+ sigalg = mapAlgorithmToJss(algname);
+ if (sigalg == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_SIGNING_ALG_NOT_SUPPORTED", algname, ""));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_SIGNING_ALGOR_NOT_SUPPORTED", algname));
+ }
+ Signature signer = mToken.getSignatureContext(sigalg);
+
+ signer.initSign(mPrivk);
+ return sigalg;
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_SIGNING_ALG_NOT_SUPPORTED", algname, e.toString()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_SIGNING_ALGOR_NOT_SUPPORTED", algname));
+ } catch (TokenException e) {
+ // from get signature context or from initSign
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_SIGNING_ALG_NOT_SUPPORTED", algname, e.toString()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_SIGNING_ALGOR_NOT_SUPPORTED", algname));
+ } catch (InvalidKeyException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_SIGNING_ALG_NOT_SUPPORTED", algname, e.toString()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_SIGNING_ALGOR_NOT_SUPPORTED_FOR_KEY", algname));
+ }
+ }
+
+ /**
+ * @param algname is expected to be one of JCA's algorithm names.
+ */
+ public byte[] sign(byte[] data, String algname)
+ throws EBaseException {
+ if (!mInited) {
+ throw new EBaseException("CASigningUnit not initialized!");
+ }
+ try {
+ // XXX for now do this mapping until James changes the names
+ // to match JCA names and provide a getAlgorithm method.
+ SignatureAlgorithm signAlg = mDefSigningAlgorithm;
+
+ if (algname != null) {
+ signAlg = checkSigningAlgorithmFromName(algname);
+ }
+
+ // XXX use a pool of signers based on alg ?
+ // XXX Map algor. name to id. hack: use hardcoded define for now.
+ CMS.debug(
+ "Getting algorithm context for " + algname + " " + signAlg);
+ Signature signer = mToken.getSignatureContext(signAlg);
+
+ signer.initSign(mPrivk);
+ signer.update(data);
+ // XXX add something more descriptive.
+ CMS.debug("Signing Certificate");
+ return signer.sign();
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_SIGNING_ALGOR_NOT_SUPPORTED", algname));
+ } catch (TokenException e) {
+ // from get signature context or from initSign
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ // XXX fix this exception later.
+ throw new EBaseException(e.toString());
+ } catch (InvalidKeyException e) {
+ // XXX fix this exception later.
+ throw new EBaseException(e.toString());
+ } catch (SignatureException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ // XXX fix this exception later.
+ throw new EBaseException(e.toString());
+ }
+ }
+
+ public boolean verify(byte[] data, byte[] signature, String algname)
+ throws EBaseException {
+ if (!mInited) {
+ throw new EBaseException("CASigningUnit not initialized!");
+ }
+ try {
+ SignatureAlgorithm signAlg = mapAlgorithmToJss(algname);
+
+ if (signAlg == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_SIGNING_ALG_NOT_SUPPORTED", algname, ""));
+ throw new ECAException(
+ CMS.getUserMessage("CMS_CA_SIGNING_ALGOR_NOT_SUPPORTED", algname));
+ }
+ // XXX make this configurable. hack: use hardcoded for now.
+ Signature signer = mToken.getSignatureContext(signAlg);
+
+ signer.initVerify(mPubk);
+ signer.update(data);
+ return signer.verify(signature);
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ // XXX fix this exception later.
+ throw new EBaseException(e.toString());
+ } catch (TokenException e) {
+ // from get signature context or from initSign
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ // XXX fix this exception later.
+ throw new EBaseException(e.toString());
+ } catch (InvalidKeyException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ // XXX fix this exception later.
+ throw new EBaseException(e.toString());
+ } catch (SignatureException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ // XXX fix this exception later.
+ throw new EBaseException(e.toString());
+ }
+ }
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_CA,
+ level, "CASigningUnit: " + msg);
+ }
+
+ /**
+ * returns default signature algorithm
+ */
+ public SignatureAlgorithm getDefaultSignatureAlgorithm() {
+ return mDefSigningAlgorithm;
+ }
+
+ /**
+ * returns default signing algorithm name.
+ */
+ public String getDefaultAlgorithm() {
+ return mDefSigningAlgname;
+ }
+
+ public void setDefaultAlgorithm(String algorithm) throws EBaseException {
+ mConfig.putString(PROP_DEFAULT_SIGNALG, algorithm);
+ mDefSigningAlgname = algorithm;
+ log(ILogger.LL_INFO,
+ "Default signing algorithm is set to " + algorithm);
+ }
+
+ /**
+ * get all possible algorithms for the CA signing key type.
+ */
+ public String[] getAllAlgorithms() throws EBaseException {
+ byte[] keybytes = mPubk.getEncoded();
+ X509Key key = new X509Key();
+
+ try {
+ key.decode(keybytes);
+ } catch (java.security.InvalidKeyException e) {
+ String msg = "Invalid encoding in CA signing key.";
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", msg));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", msg));
+ }
+
+ if (key.getAlgorithmId().getOID().equals(AlgorithmId.DSA_oid)) {
+ return AlgorithmId.DSA_SIGNING_ALGORITHMS;
+ } else {
+ return AlgorithmId.ALL_SIGNING_ALGORITHMS;
+ }
+ }
+
+ public static SignatureAlgorithm mapAlgorithmToJss(String algname) {
+ return Cert.mapAlgorithmToJss(algname);
+ }
+}
diff --git a/base/common/CMakeLists.txt b/base/common/CMakeLists.txt
new file mode 100644
index 000000000..10a7cc0bb
--- /dev/null
+++ b/base/common/CMakeLists.txt
@@ -0,0 +1,16 @@
+project(common Java)
+
+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)
+add_subdirectory(test)
diff --git a/base/common/LICENSE b/base/common/LICENSE
new file mode 100644
index 000000000..e281f4362
--- /dev/null
+++ b/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/base/common/setup/CertServer.directory b/base/common/setup/CertServer.directory
new file mode 100644
index 000000000..6d21bacb9
--- /dev/null
+++ b/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/base/common/setup/menu.xml b/base/common/setup/menu.xml
new file mode 100644
index 000000000..562ea0261
--- /dev/null
+++ b/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/base/common/setup/web-app_2_3.dtd b/base/common/setup/web-app_2_3.dtd
new file mode 100644
index 000000000..5e3ab01c0
--- /dev/null
+++ b/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/base/common/src/CMakeLists.txt b/base/common/src/CMakeLists.txt
new file mode 100644
index 000000000..a9d4a765c
--- /dev/null
+++ b/base/common/src/CMakeLists.txt
@@ -0,0 +1,1095 @@
+project(pki-certsrv_java Java)
+
+find_file(JSS_JAR
+ NAMES
+ jss4.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(LDAPJDK_JAR
+ NAMES
+ ldapjdk.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(COMMONS_CODEC_JAR
+ NAMES
+ commons-codec.jar
+ PATHS
+ /usr/share/java
+)
+
+find_file(TOMCAT_CATALINA_JAR
+ NAMES
+ catalina.jar
+ PATHS
+ /usr/share/java/tomcat6
+)
+
+find_file(SERVLET_JAR
+ NAMES
+ servlet.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(VELOCITY_JAR
+ NAMES
+ velocity.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(XALAN_JAR
+ NAMES
+ xalan-j2.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(XERCES_JAR
+ NAMES
+ xerces-j2.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(JAXRS_API_JAR
+ NAMES
+ jaxrs-api-2.2.1.GA.jar
+ PATHS
+ /usr/share/candlepin/lib
+)
+
+find_file(RESTEASY_JAXRS_JAR
+ NAMES
+ resteasy-jaxrs-2.2.1.GA.jar
+ PATHS
+ /usr/share/candlepin/lib
+)
+
+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/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/KeyId.java
+ com/netscape/certsrv/dbs/keydb/KeyIdAdapter.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/RequestIdAdapter.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/PublisherUtils.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/ServletUtils.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/cert/model/CertificateData.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/admin/SystemCertificateResource.java
+ com/netscape/cms/servlet/admin/SystemCertificateResourceService.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/key/KeyResource.java
+ com/netscape/cms/servlet/key/KeyResourceService.java
+ com/netscape/cms/servlet/key/KeysResource.java
+ com/netscape/cms/servlet/key/KeysResourceService.java
+ com/netscape/cms/servlet/key/model/KeyDAO.java
+ com/netscape/cms/servlet/key/model/KeyDataInfo.java
+ com/netscape/cms/servlet/key/model/KeyDataInfos.java
+ com/netscape/cms/servlet/key/model/KeyData.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/CMSResourceService.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/base/model/Link.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/request/KeyRequestResource.java
+ com/netscape/cms/servlet/request/KeyRequestResourceService.java
+ com/netscape/cms/servlet/request/KeyRequestsResource.java
+ com/netscape/cms/servlet/request/KeyRequestsResourceService.java
+ com/netscape/cms/servlet/request/model/ArchivalRequestData.java
+ com/netscape/cms/servlet/request/model/KeyRequestDAO.java
+ com/netscape/cms/servlet/request/model/KeyRequestInfo.java
+ com/netscape/cms/servlet/request/model/KeyRequestInfos.java
+ com/netscape/cms/servlet/request/model/RecoveryRequestData.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/SigningKeyGenInput.java
+ com/netscape/cms/profile/input/EncryptionKeyGenInput.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/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-jndi-realm_SRCS
+ com/netscape/cmscore/realm/PKIJNDIRealm.java
+ com/netscape/cmscore/realm/ACLEntry.java
+ com/netscape/cmscore/realm/ACL.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} ${COMMONS_CODEC_JAR} ${TOMCAT_CATALINA_JAR} ${SYMKEY_JAR} ${JAXRS_API_JAR} ${RESTEASY_JAXRS_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 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 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 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 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")
+
+# build pki jndi realm
+set(CMAKE_JAR_CLASSES_PREFIX com/netscape/cmscore/realm)
+add_jar(pki-jndi-realm ${pki-jndi-realm_SRCS})
+install_jar(pki-jndi-realm ${JAVA_JAR_INSTALL_DIR}/pki)
+set(PKI_JNDI_REALM_JAR ${pki-jndi-realm_JAR_FILE} CACHE INTERNAL "pki-jndi-realm jar file")
+
diff --git a/base/common/src/LogMessages.properties b/base/common/src/LogMessages.properties
new file mode 100644
index 000000000..bd108bf80
--- /dev/null
+++ b/base/common/src/LogMessages.properties
@@ -0,0 +1,2475 @@
+#
+# 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 {0}
+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
+#
+#
+#
+# LOGGING_SIGNED_AUDIT_SECURITY_DOMAIN_UPDATE
+# - used when updating contents of security domain
+# (add/remove a subsystem)
+# 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_SECURITY_DOMAIN_UPDATE_1=<type=SECURITY_DOMAIN_UPDATE>:[AuditEvent=SECURITY_DOMAIN_UPDATE][SubjectID={0}][Outcome={1}][ParamNameValPairs={2}] security domain update
+#
+#
+#
+# LOGGING_SIGNED_AUDIT_CONFIG_SERIAL_NUMBER
+# - used when configuring serial number ranges
+# (when requesting a serial number range when cloning, for example)
+# 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_SERIAL_NUMBER_1=<type=CONFIG_SERIAL_NUMBER>:[AuditEvent=CONFIG_SERIAL_NUMBER][SubjectID={0}][Outcome={1}][ParamNameValPairs={2}] serial number range update
+
+
+###########################
+#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/base/common/src/UserMessages.properties b/base/common/src/UserMessages.properties
new file mode 100644
index 000000000..1c78c98ce
--- /dev/null
+++ b/base/common/src/UserMessages.properties
@@ -0,0 +1,1133 @@
+#
+# 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
+CMS_ADMIN_SRVLT_CERT_VALIDATE_FAILED=Imported cert has not been verified to be valid. Please review the usual validity properties of this certificate before using it as part of the system.
+#######################################################
+# 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: 1024,2048,4096,8192 or: nistp256,nistp384,nistp521,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_ENC_KEY_GEN_NAME=Encryption Key Generation
+CMS_PROFILE_INPUT_ENC_KEY_GEN_TEXT=Encryption Key Generation
+CMS_PROFILE_INPUT_SIGN_KEY_GEN_NAME=Signing Key Generation
+CMS_PROFILE_INPUT_SIGN_KEY_GEN_TEXT=Signing 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/base/common/src/com/netscape/certsrv/acls/ACL.java b/base/common/src/com/netscape/certsrv/acls/ACL.java
new file mode 100644
index 000000000..508793ddf
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/acls/ACL.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.acls;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1867465948611161868L;
+
+ protected Vector<ACLEntry> mEntries = new Vector<ACLEntry>(); // ACL entries
+ protected Vector<String> 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<String> rights, String resourceACLs) {
+ setName(name);
+ if (rights != null) {
+ mRights = rights;
+ } else {
+ mRights = new Vector<String>();
+ }
+ 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<ACLEntry> 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<ACLEntry> 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<String> rights() {
+ return mRights.elements();
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/acls/ACLEntry.java b/base/common/src/com/netscape/certsrv/acls/ACLEntry.java
new file mode 100644
index 000000000..2c1b7c3ea
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/acls/ACLEntry.java
@@ -0,0 +1,245 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Enumeration;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+
+/**
+ * A class represents an ACI entry of an access control list.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class ACLEntry implements IACLEntry, java.io.Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 422656406529200393L;
+
+ protected Hashtable<String, String> mPerms = new Hashtable<String, String>();
+ 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<String> 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<String> e = permissions();
+
+ for (; e.hasMoreElements();) {
+ String p = e.nextElement();
+
+ entry += p;
+ if (e.hasMoreElements())
+ entry += ",";
+ }
+ entry += ") " + getAttributeExpressions();
+ return entry;
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/acls/ACLsResources.java b/base/common/src/com/netscape/certsrv/acls/ACLsResources.java
new file mode 100644
index 000000000..bf3ea4a28
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/acls/ACLsResources.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.acls;
+
+import java.util.ListResourceBundle;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/acls/EACLsException.java b/base/common/src/com/netscape/certsrv/acls/EACLsException.java
new file mode 100644
index 000000000..8d204091e
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/acls/EACLsException.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.acls;
+
+import java.util.Locale;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.MessageFormatter;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5471535135648315104L;
+ /**
+ * 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(&quot;failed to load {0}&quot;, 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/base/common/src/com/netscape/certsrv/acls/IACL.java b/base/common/src/com/netscape/certsrv/acls/IACL.java
new file mode 100644
index 000000000..aad733722
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/acls/IACL.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.acls;
+
+import java.util.Enumeration;
+
+/**
+ * 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<String> rights();
+
+ /**
+ * Returns a list of entries of the current ACL.
+ *
+ * @return a list of entries
+ */
+ public Enumeration<ACLEntry> 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/base/common/src/com/netscape/certsrv/acls/IACLEntry.java b/base/common/src/com/netscape/certsrv/acls/IACLEntry.java
new file mode 100644
index 000000000..ff806f155
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/acls/IACLEntry.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.acls;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/apps/CMS.java b/base/common/src/com/netscape/certsrv/apps/CMS.java
new file mode 100644
index 000000000..3a36c71bc
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/apps/CMS.java
@@ -0,0 +1,1649 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.math.BigInteger;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSSLSocketFactoryExt;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.Extension;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.X509CertInfo;
+
+import org.mozilla.jss.CryptoManager.CertificateUsage;
+import org.mozilla.jss.util.PasswordCallback;
+
+import com.netscape.certsrv.acls.EACLsException;
+import com.netscape.certsrv.acls.IACL;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.authorization.IAuthzSubsystem;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.ICRLPrettyPrint;
+import com.netscape.certsrv.base.ICertPrettyPrint;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtPrettyPrint;
+import com.netscape.certsrv.base.IPrettyPrintFormat;
+import com.netscape.certsrv.base.ISecurityDomainSessionTable;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.connector.IHttpConnection;
+import com.netscape.certsrv.connector.IPKIMessage;
+import com.netscape.certsrv.connector.IRemoteAuthority;
+import com.netscape.certsrv.connector.IRequestEncoder;
+import com.netscape.certsrv.connector.IResender;
+import com.netscape.certsrv.dbs.IDBSubsystem;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.dbs.repository.IRepositoryRecord;
+import com.netscape.certsrv.jobs.IJobsScheduler;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ILdapAuthInfo;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.ldap.ILdapConnInfo;
+import com.netscape.certsrv.logging.ILogSubsystem;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.notification.IEmailFormProcessor;
+import com.netscape.certsrv.notification.IEmailResolver;
+import com.netscape.certsrv.notification.IEmailResolverKeys;
+import com.netscape.certsrv.notification.IEmailTemplate;
+import com.netscape.certsrv.notification.IMailNotification;
+import com.netscape.certsrv.ocsp.IOCSPAuthority;
+import com.netscape.certsrv.password.IPasswordCheck;
+import com.netscape.certsrv.policy.IGeneralNameAsConstraintsConfig;
+import com.netscape.certsrv.policy.IGeneralNamesAsConstraintsConfig;
+import com.netscape.certsrv.policy.IGeneralNamesConfig;
+import com.netscape.certsrv.policy.ISubjAltNameConfig;
+import com.netscape.certsrv.profile.IProfileSubsystem;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.certsrv.registry.IPluginRegistry;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.security.ICryptoSubsystem;
+import com.netscape.certsrv.selftests.ISelfTestSubsystem;
+import com.netscape.certsrv.tks.ITKSAuthority;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.cmsutil.net.ISocketFactory;
+import com.netscape.cmsutil.password.IPasswordStore;
+
+/**
+ * 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<String> 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<ISubsystem> 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<String> 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<String> 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<String> 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<String> 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<String> 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<String> 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";
+
+ try {
+ ICMSEngine engine = (ICMSEngine)
+ Class.forName(classname).newInstance();
+
+ CMS.setCMSEngine(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<String, String> httpReq) {
+ return _engine.createArgBlock(realm, httpReq);
+ }
+
+ public static IArgBlock createArgBlock(Hashtable<String, String> 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/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java b/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java
new file mode 100644
index 000000000..ba9731867
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java
@@ -0,0 +1,1126 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.BigInteger;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSSLSocketFactoryExt;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.Extension;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.X509CertInfo;
+
+import org.mozilla.jss.CryptoManager.CertificateUsage;
+import org.mozilla.jss.util.PasswordCallback;
+
+import com.netscape.certsrv.acls.EACLsException;
+import com.netscape.certsrv.acls.IACL;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.ICRLPrettyPrint;
+import com.netscape.certsrv.base.ICertPrettyPrint;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtPrettyPrint;
+import com.netscape.certsrv.base.IPrettyPrintFormat;
+import com.netscape.certsrv.base.ISecurityDomainSessionTable;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.connector.IHttpConnection;
+import com.netscape.certsrv.connector.IPKIMessage;
+import com.netscape.certsrv.connector.IRemoteAuthority;
+import com.netscape.certsrv.connector.IRequestEncoder;
+import com.netscape.certsrv.connector.IResender;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.dbs.repository.IRepositoryRecord;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ILdapAuthInfo;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.ldap.ILdapConnInfo;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.notification.IEmailFormProcessor;
+import com.netscape.certsrv.notification.IEmailResolver;
+import com.netscape.certsrv.notification.IEmailResolverKeys;
+import com.netscape.certsrv.notification.IEmailTemplate;
+import com.netscape.certsrv.notification.IMailNotification;
+import com.netscape.certsrv.password.IPasswordCheck;
+import com.netscape.certsrv.policy.IGeneralNameAsConstraintsConfig;
+import com.netscape.certsrv.policy.IGeneralNamesAsConstraintsConfig;
+import com.netscape.certsrv.policy.IGeneralNamesConfig;
+import com.netscape.certsrv.policy.ISubjAltNameConfig;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cmsutil.net.ISocketFactory;
+import com.netscape.cmsutil.password.IPasswordStore;
+
+/**
+ * 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<String> getSubsystemNames();
+
+ /**
+ * Returns all the registered subsystems.
+ *
+ * @return a list of ISubsystem-based subsystems
+ */
+ public Enumeration<ISubsystem> 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<String> 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<String> 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<String> 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<String> 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<String> params);
+
+ /**
+ * Get extended plugin info for subject alt name configuration.
+ *
+ * @param name configuration name
+ * @param params configuration parameters
+ */
+ public void getSubjAltNameConfigExtendedPluginInfo(String name, Vector<String> 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<String, String> httpReq);
+
+ /**
+ * Creates argument block.
+ */
+ public IArgBlock createArgBlock(Hashtable<String, String> 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/base/common/src/com/netscape/certsrv/apps/ICommandQueue.java b/base/common/src/com/netscape/certsrv/apps/ICommandQueue.java
new file mode 100644
index 000000000..a165ab461
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/apps/ICommandQueue.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.apps;
+
+import javax.servlet.Servlet;
+
+import com.netscape.cms.servlet.common.CMSRequest;
+
+/**
+ * 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(CMSRequest currentRequest, Servlet 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/base/common/src/com/netscape/certsrv/authentication/AuthCredentials.java b/base/common/src/com/netscape/certsrv/authentication/AuthCredentials.java
new file mode 100644
index 000000000..5a0cdd3b8
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authentication/AuthCredentials.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.authentication;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import com.netscape.certsrv.base.IArgBlock;
+
+/**
+ * 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 static final long serialVersionUID = 5862936214648594328L;
+ private Hashtable<String, Object> authCreds = null;
+ private IArgBlock argblk = null;
+
+ /**
+ * Constructor
+ */
+ public AuthCredentials() {
+ authCreds = new Hashtable<String, Object>();
+ }
+
+ /**
+ * 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 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 credential names in this credential
+ * set. Use the Enumeration methods on the returned object to
+ * fetch the elements sequentially.
+ *
+ * @return an enumeration of the names in this credential set
+ */
+ public Enumeration<String> getElements() {
+ return authCreds.keys();
+ }
+
+ /**
+ * 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/base/common/src/com/netscape/certsrv/authentication/AuthManagerProxy.java b/base/common/src/com/netscape/certsrv/authentication/AuthManagerProxy.java
new file mode 100644
index 000000000..76161e803
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authentication/AuthManagerProxy.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.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/base/common/src/com/netscape/certsrv/authentication/AuthMgrPlugin.java b/base/common/src/com/netscape/certsrv/authentication/AuthMgrPlugin.java
new file mode 100644
index 000000000..4226fd83c
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authentication/AuthMgrPlugin.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.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 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/base/common/src/com/netscape/certsrv/authentication/AuthResources.java b/base/common/src/com/netscape/certsrv/authentication/AuthResources.java
new file mode 100644
index 000000000..35e810112
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authentication/AuthResources.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.authentication;
+
+import java.util.ListResourceBundle;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/authentication/AuthToken.java b/base/common/src/com/netscape/certsrv/authentication/AuthToken.java
new file mode 100644
index 000000000..0a2b1f0a2
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authentication/AuthToken.java
@@ -0,0 +1,451 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.usrgrp.Certificates;
+
+/**
+ * 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<String, Object> 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<String, Object>();
+ 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<String> 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<Object> 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/base/common/src/com/netscape/certsrv/authentication/EAuthException.java b/base/common/src/com/netscape/certsrv/authentication/EAuthException.java
new file mode 100644
index 000000000..c79c3e9a7
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authentication/EAuthException.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.authentication;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * This class represents authentication exceptions.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class EAuthException extends EBaseException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2763649418082002427L;
+ /**
+ * 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/base/common/src/com/netscape/certsrv/authentication/EAuthInternalError.java b/base/common/src/com/netscape/certsrv/authentication/EAuthInternalError.java
new file mode 100644
index 000000000..52688f922
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authentication/EAuthInternalError.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.authentication;
+
+/**
+ * An exception for authentication internal error.
+ */
+public class EAuthInternalError extends EAuthException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4020816090107820450L;
+
+ /**
+ * Constructs an authentication internal error exception
+ * with a detailed message.
+ *
+ * @param errorString Detailed error message.
+ */
+ public EAuthInternalError(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/authentication/EAuthMgrNotFound.java b/base/common/src/com/netscape/certsrv/authentication/EAuthMgrNotFound.java
new file mode 100644
index 000000000..925aaabf0
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authentication/EAuthMgrNotFound.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.authentication;
+
+/**
+ * Exception for authentication manager not found.
+ */
+public class EAuthMgrNotFound extends EAuthException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3102946146034004983L;
+
+ /**
+ * 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/base/common/src/com/netscape/certsrv/authentication/EAuthMgrPluginNotFound.java b/base/common/src/com/netscape/certsrv/authentication/EAuthMgrPluginNotFound.java
new file mode 100644
index 000000000..2ca90e3c8
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authentication/EAuthMgrPluginNotFound.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.authentication;
+
+/**
+ * Exception for authentication manager not found.
+ */
+public class EAuthMgrPluginNotFound extends EAuthException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7422356574227925974L;
+
+ /**
+ * 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/base/common/src/com/netscape/certsrv/authentication/EAuthUserError.java b/base/common/src/com/netscape/certsrv/authentication/EAuthUserError.java
new file mode 100644
index 000000000..f816c35e8
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authentication/EAuthUserError.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.authentication;
+
+/**
+ * Exception for invalid attribute value
+ */
+public class EAuthUserError extends EAuthException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 287839079094761375L;
+
+ /**
+ * Constructs a exception for a Invalid attribute value
+ *
+ * @param errorString Detailed error message.
+ */
+ public EAuthUserError(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/authentication/ECompSyntaxErr.java b/base/common/src/com/netscape/certsrv/authentication/ECompSyntaxErr.java
new file mode 100644
index 000000000..84725bb96
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authentication/ECompSyntaxErr.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.authentication;
+
+/**
+ * An exception for DN component syntax error.
+ */
+public class ECompSyntaxErr extends EAuthException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5434000917203952218L;
+
+ /**
+ * Constructs an component syntax error
+ *
+ * @param errorString Detailed error message.
+ */
+ public ECompSyntaxErr(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/authentication/EFormSubjectDN.java b/base/common/src/com/netscape/certsrv/authentication/EFormSubjectDN.java
new file mode 100644
index 000000000..952824481
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authentication/EFormSubjectDN.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.authentication;
+
+/**
+ * An exception for Error formulating the subject name (X500Name)
+ */
+public class EFormSubjectDN extends EAuthException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4052335779095200482L;
+
+ /**
+ * Constructs an Error on formulating the subject dn.
+ *
+ * @param errorString Detailed error message.
+ */
+ public EFormSubjectDN(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/authentication/EInvalidCredentials.java b/base/common/src/com/netscape/certsrv/authentication/EInvalidCredentials.java
new file mode 100644
index 000000000..3e4daaf0d
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authentication/EInvalidCredentials.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.authentication;
+
+/**
+ * An exception for invalid credentials.
+ */
+public class EInvalidCredentials extends EAuthException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5695804026210904331L;
+
+ /**
+ * Constructs an Invalid Credentials exception.
+ *
+ * @param errorString Detailed error message.
+ */
+ public EInvalidCredentials(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/authentication/EMissingCredential.java b/base/common/src/com/netscape/certsrv/authentication/EMissingCredential.java
new file mode 100644
index 000000000..5de73aa0d
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authentication/EMissingCredential.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.authentication;
+
+/**
+ * Exception for missing a required authentication credential.
+ */
+public class EMissingCredential extends EAuthException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1252384491944341767L;
+
+ /**
+ * Constructs a exception for a missing required authentication credential
+ *
+ * @param errorString Detailed error message.
+ */
+ public EMissingCredential(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/authentication/IAuthCredentials.java b/base/common/src/com/netscape/certsrv/authentication/IAuthCredentials.java
new file mode 100644
index 000000000..cd8434433
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authentication/IAuthCredentials.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.authentication;
+
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.IAttrSet;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/authentication/IAuthManager.java b/base/common/src/com/netscape/certsrv/authentication/IAuthManager.java
new file mode 100644
index 000000000..1ff46af7d
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authentication/IAuthManager.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.authentication;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/authentication/IAuthSubsystem.java b/base/common/src/com/netscape/certsrv/authentication/IAuthSubsystem.java
new file mode 100644
index 000000000..329b6802e
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authentication/IAuthSubsystem.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.certsrv.authentication;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.ISubsystem;
+
+/**
+ * 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<IAuthManager> getAuthManagers();
+
+ /**
+ * Gets an enumeration of authentication manager plugins.
+ *
+ * @return a list of authentication plugins
+ */
+ public Enumeration<AuthMgrPlugin> 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<String, AuthMgrPlugin> 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/base/common/src/com/netscape/certsrv/authentication/IAuthToken.java b/base/common/src/com/netscape/certsrv/authentication/IAuthToken.java
new file mode 100644
index 000000000..f46ee3ca1
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authentication/IAuthToken.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.authentication;
+
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Enumeration;
+
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.usrgrp.Certificates;
+
+/**
+ * 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<String> 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/base/common/src/com/netscape/certsrv/authentication/ISSLClientCertProvider.java b/base/common/src/com/netscape/certsrv/authentication/ISSLClientCertProvider.java
new file mode 100644
index 000000000..6932decc0
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authentication/ISSLClientCertProvider.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.authentication;
+
+import java.security.cert.X509Certificate;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/authentication/ISharedToken.java b/base/common/src/com/netscape/certsrv/authentication/ISharedToken.java
new file mode 100644
index 000000000..830c8866e
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authentication/ISharedToken.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;
+
+import java.math.BigInteger;
+
+import org.mozilla.jss.pkix.cmc.PKIData;
+
+/**
+ * Shared Token interface.
+ */
+public interface ISharedToken {
+
+ public String getSharedToken(PKIData cmcData);
+
+ public String getSharedToken(BigInteger serialnum);
+}
diff --git a/base/common/src/com/netscape/certsrv/authority/IAuthority.java b/base/common/src/com/netscape/certsrv/authority/IAuthority.java
new file mode 100644
index 000000000..2875e4dd1
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authority/IAuthority.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.authority;
+
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.request.IRequestListener;
+import com.netscape.certsrv.request.IRequestQueue;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/authority/ICertAuthority.java b/base/common/src/com/netscape/certsrv/authority/ICertAuthority.java
new file mode 100644
index 000000000..c2f2c91ec
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authority/ICertAuthority.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.authority;
+
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.request.IRequestListener;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/authorization/AuthzManagerProxy.java b/base/common/src/com/netscape/certsrv/authorization/AuthzManagerProxy.java
new file mode 100644
index 000000000..58a5264ba
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authorization/AuthzManagerProxy.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.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/base/common/src/com/netscape/certsrv/authorization/AuthzMgrPlugin.java b/base/common/src/com/netscape/certsrv/authorization/AuthzMgrPlugin.java
new file mode 100644
index 000000000..e47e58171
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authorization/AuthzMgrPlugin.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.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 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/base/common/src/com/netscape/certsrv/authorization/AuthzResources.java b/base/common/src/com/netscape/certsrv/authorization/AuthzResources.java
new file mode 100644
index 000000000..13d33c212
--- /dev/null
+++ b/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.ListResourceBundle;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/authorization/AuthzToken.java b/base/common/src/com/netscape/certsrv/authorization/AuthzToken.java
new file mode 100644
index 000000000..262902e62
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authorization/AuthzToken.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.certsrv.authorization;
+
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import com.netscape.certsrv.base.IAttrSet;
+
+/**
+ * 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 static final long serialVersionUID = 4716145610877112054L;
+ private Hashtable<String, Object> 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<String, Object>();
+ 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<String> getElements() {
+ return mAttrs.keys();
+ }
+
+ /**
+ * Enumerate all attribute values in the AuthzToken.
+ *
+ * @return Enumeration of all attribute names in this AuthzToken.
+ */
+ public Enumeration<Object> 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/base/common/src/com/netscape/certsrv/authorization/EAuthzAccessDenied.java b/base/common/src/com/netscape/certsrv/authorization/EAuthzAccessDenied.java
new file mode 100644
index 000000000..9fc7777c7
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authorization/EAuthzAccessDenied.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.authorization;
+
+/**
+ * Exception for authorization failure
+ */
+public class EAuthzAccessDenied extends EAuthzException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 603324526695263260L;
+
+ /**
+ * Constructs a exception for access denied by Authz manager
+ *
+ * @param errorString Detailed error message.
+ */
+ public EAuthzAccessDenied(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/authorization/EAuthzException.java b/base/common/src/com/netscape/certsrv/authorization/EAuthzException.java
new file mode 100644
index 000000000..65d95a571
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authorization/EAuthzException.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.authorization;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * This class represents authorization exceptions.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class EAuthzException extends EBaseException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6265731237976616272L;
+ /**
+ * 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/base/common/src/com/netscape/certsrv/authorization/EAuthzInternalError.java b/base/common/src/com/netscape/certsrv/authorization/EAuthzInternalError.java
new file mode 100644
index 000000000..2afe2c747
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authorization/EAuthzInternalError.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.authorization;
+
+/**
+ * An exception for internal error for authorization.
+ */
+public class EAuthzInternalError extends EAuthzException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2954801841027751903L;
+
+ /**
+ * Constructs an authorization internal error exception
+ *
+ * @param errorString error with a detailed message.
+ */
+ public EAuthzInternalError(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/authorization/EAuthzMgrNotFound.java b/base/common/src/com/netscape/certsrv/authorization/EAuthzMgrNotFound.java
new file mode 100644
index 000000000..a920d37ac
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authorization/EAuthzMgrNotFound.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.authorization;
+
+/**
+ * Exception for authorization manager not found.
+ */
+public class EAuthzMgrNotFound extends EAuthzException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 858647841945772328L;
+
+ /**
+ * Constructs a exception for a missing required authorization manager
+ *
+ * @param errorString Detailed error message.
+ */
+ public EAuthzMgrNotFound(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/authorization/EAuthzMgrPluginNotFound.java b/base/common/src/com/netscape/certsrv/authorization/EAuthzMgrPluginNotFound.java
new file mode 100644
index 000000000..43ae6edcd
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authorization/EAuthzMgrPluginNotFound.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.authorization;
+
+/**
+ * Exception for authorization manager plugin not found.
+ */
+public class EAuthzMgrPluginNotFound extends EAuthzException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2647973726997526429L;
+
+ /**
+ * Constructs a exception for a missing authorization plugin
+ *
+ * @param errorString Detailed error message.
+ */
+ public EAuthzMgrPluginNotFound(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/authorization/EAuthzUnknownOperation.java b/base/common/src/com/netscape/certsrv/authorization/EAuthzUnknownOperation.java
new file mode 100644
index 000000000..ce061ddd2
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authorization/EAuthzUnknownOperation.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.authorization;
+
+/**
+ * Exception for operation unknown to the authorization manager
+ */
+public class EAuthzUnknownOperation extends EAuthzException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4344508835702220953L;
+
+ /**
+ * 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/base/common/src/com/netscape/certsrv/authorization/EAuthzUnknownProtectedRes.java b/base/common/src/com/netscape/certsrv/authorization/EAuthzUnknownProtectedRes.java
new file mode 100644
index 000000000..5cb2d7276
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authorization/EAuthzUnknownProtectedRes.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.authorization;
+
+/**
+ * Exception for protected resource unknown to the authorization manager
+ */
+public class EAuthzUnknownProtectedRes extends EAuthzException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 444663701711532889L;
+
+ /**
+ * 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/base/common/src/com/netscape/certsrv/authorization/IAuthzManager.java b/base/common/src/com/netscape/certsrv/authorization/IAuthzManager.java
new file mode 100644
index 000000000..8b52b3928
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authorization/IAuthzManager.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.certsrv.authorization;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import com.netscape.certsrv.acls.ACL;
+import com.netscape.certsrv.acls.EACLsException;
+import com.netscape.certsrv.acls.IACL;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.evaluators.IAccessEvaluator;
+
+/**
+ * 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<ACL> 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<IAccessEvaluator> 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<String, IAccessEvaluator> getAccessEvaluators();
+}
diff --git a/base/common/src/com/netscape/certsrv/authorization/IAuthzSubsystem.java b/base/common/src/com/netscape/certsrv/authorization/IAuthzSubsystem.java
new file mode 100644
index 000000000..d8ccc8a83
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authorization/IAuthzSubsystem.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.certsrv.authorization;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.ISubsystem;
+
+/**
+ * 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<IAuthzManager> 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<AuthzMgrPlugin> 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<String, AuthzMgrPlugin> getPlugins();
+
+ /**
+ * Get a hashtable containing all authentication instances.
+ *
+ * @return all authentication instances.
+ */
+ public Hashtable<String, AuthzManagerProxy> 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/base/common/src/com/netscape/certsrv/base/ASubsystem.java b/base/common/src/com/netscape/certsrv/base/ASubsystem.java
new file mode 100644
index 000000000..2b4c6d15a
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/ASubsystem.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;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/base/AttributeNameHelper.java b/base/common/src/com/netscape/certsrv/base/AttributeNameHelper.java
new file mode 100644
index 000000000..5b6db131e
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/AttributeNameHelper.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.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/base/common/src/com/netscape/certsrv/base/BaseResources.java b/base/common/src/com/netscape/certsrv/base/BaseResources.java
new file mode 100644
index 000000000..41159481f
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/BaseResources.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.ListResourceBundle;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/base/EBaseException.java b/base/common/src/com/netscape/certsrv/base/EBaseException.java
new file mode 100644
index 000000000..26def60f5
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/EBaseException.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.certsrv.base;
+
+import java.util.Locale;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8213021692117483973L;
+
+ /**
+ * 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(&quot;An plain error message&quot;);
+ * <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/base/common/src/com/netscape/certsrv/base/EPropertyNotDefined.java b/base/common/src/com/netscape/certsrv/base/EPropertyNotDefined.java
new file mode 100644
index 000000000..466306582
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/EPropertyNotDefined.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.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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7986464387187170352L;
+
+ /**
+ * 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/base/common/src/com/netscape/certsrv/base/EPropertyNotFound.java b/base/common/src/com/netscape/certsrv/base/EPropertyNotFound.java
new file mode 100644
index 000000000..5a8a9550f
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/EPropertyNotFound.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.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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2701966082697733003L;
+
+ /**
+ * 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/base/common/src/com/netscape/certsrv/base/ExtendedPluginInfo.java b/base/common/src/com/netscape/certsrv/base/ExtendedPluginInfo.java
new file mode 100644
index 000000000..86f5999d9
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/ExtendedPluginInfo.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.base;
+
+import java.util.Locale;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/base/IArgBlock.java b/base/common/src/com/netscape/certsrv/base/IArgBlock.java
new file mode 100644
index 000000000..adddccba6
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/IArgBlock.java
@@ -0,0 +1,283 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.math.BigInteger;
+import java.util.Enumeration;
+
+import netscape.security.pkcs.PKCS10;
+
+/**
+ * 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<String> 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<String> getElements();
+}
diff --git a/base/common/src/com/netscape/certsrv/base/IAttrSet.java b/base/common/src/com/netscape/certsrv/base/IAttrSet.java
new file mode 100644
index 000000000..e396b072a
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/IAttrSet.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;
+
+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<String> getElements();
+}
diff --git a/base/common/src/com/netscape/certsrv/base/IAuthInfo.java b/base/common/src/com/netscape/certsrv/base/IAuthInfo.java
new file mode 100644
index 000000000..4806a94c0
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/IAuthInfo.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.base;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/base/ICRLPrettyPrint.java b/base/common/src/com/netscape/certsrv/base/ICRLPrettyPrint.java
new file mode 100644
index 000000000..d111063a7
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/ICRLPrettyPrint.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.base;
+
+import java.util.Locale;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/base/ICertPrettyPrint.java b/base/common/src/com/netscape/certsrv/base/ICertPrettyPrint.java
new file mode 100644
index 000000000..e991d5a11
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/ICertPrettyPrint.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.base;
+
+import java.util.Locale;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/base/IConfigStore.java b/base/common/src/com/netscape/certsrv/base/IConfigStore.java
new file mode 100644
index 000000000..d12265e83
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/IConfigStore.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.certsrv.base;
+
+import java.math.BigInteger;
+import java.util.Enumeration;
+
+/**
+ * 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(&quot;param1&quot;);
+ * // valx is &quot;value1&quot; &lt;p&gt;
+ *
+ * IConfigStore substore1 = config.getSubstore(&quot;configStore1&quot;);
+ * String valy = substore1.getString(&quot;param11&quot;);
+ * // valy is &quot;value11&quot; &lt;p&gt;
+ *
+ * IConfigStore substore2 = config.getSubstore(&quot;configStore2&quot;);
+ * String valz = substore2.getString(&quot;param21&quot;);
+ * // valz is &quot;value21&quot; &lt;p&gt;
+ * }
+ * </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<String> 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<String> 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/base/common/src/com/netscape/certsrv/base/IConfigStoreEventListener.java b/base/common/src/com/netscape/certsrv/base/IConfigStoreEventListener.java
new file mode 100644
index 000000000..06e7d522a
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/IConfigStoreEventListener.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.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<String, String> 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<String, String> params) throws EBaseException;
+}
diff --git a/base/common/src/com/netscape/certsrv/base/IExtPrettyPrint.java b/base/common/src/com/netscape/certsrv/base/IExtPrettyPrint.java
new file mode 100644
index 000000000..8d95a40ca
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/IExtPrettyPrint.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.base;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/base/IExtendedPluginInfo.java b/base/common/src/com/netscape/certsrv/base/IExtendedPluginInfo.java
new file mode 100644
index 000000000..aff3daf4d
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/IExtendedPluginInfo.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.certsrv.base;
+
+import java.util.Locale;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/base/IPluginImpl.java b/base/common/src/com/netscape/certsrv/base/IPluginImpl.java
new file mode 100644
index 000000000..a7a0560b5
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/IPluginImpl.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.base;
+
+import java.util.Vector;
+
+/**
+ * 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<String> 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<String> getDefaultParams();
+
+}
diff --git a/base/common/src/com/netscape/certsrv/base/IPrettyPrintFormat.java b/base/common/src/com/netscape/certsrv/base/IPrettyPrintFormat.java
new file mode 100644
index 000000000..67c1b01d1
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/IPrettyPrintFormat.java
@@ -0,0 +1,66 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 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/base/common/src/com/netscape/certsrv/base/ISecurityDomainSessionTable.java b/base/common/src/com/netscape/certsrv/base/ISecurityDomainSessionTable.java
new file mode 100644
index 000000000..24c55d086
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/ISecurityDomainSessionTable.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.base;
+
+import java.util.Enumeration;
+
+/**
+ * This interface defines the abstraction for the cookie table.
+ **/
+public interface ISecurityDomainSessionTable {
+ public static final int SUCCESS = 0;
+ public static final int FAILURE = 1;
+
+ public int addEntry(String cookieId, String ip, String uid, String group);
+
+ public int 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<String> getSessionIds();
+}
diff --git a/base/common/src/com/netscape/certsrv/base/ISourceConfigStore.java b/base/common/src/com/netscape/certsrv/base/ISourceConfigStore.java
new file mode 100644
index 000000000..eb848c54e
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/ISourceConfigStore.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.base;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+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 String get(String name);
+
+ /**
+ * Retrieves a property.
+ * <P>
+ *
+ * @param name The property name
+ * @param value The property value
+ */
+ public String put(String name, String 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<String> 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/base/common/src/com/netscape/certsrv/base/ISubsystem.java b/base/common/src/com/netscape/certsrv/base/ISubsystem.java
new file mode 100644
index 000000000..7b2a37d7d
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/ISubsystem.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.base;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/base/ISubsystemSource.java b/base/common/src/com/netscape/certsrv/base/ISubsystemSource.java
new file mode 100644
index 000000000..f6bb6378b
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/ISubsystemSource.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;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/base/ITimeSource.java b/base/common/src/com/netscape/certsrv/base/ITimeSource.java
new file mode 100644
index 000000000..1e7dd0fb0
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/ITimeSource.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;
+
+import java.util.Date;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/base/KeyGenInfo.java b/base/common/src/com/netscape/certsrv/base/KeyGenInfo.java
new file mode 100644
index 000000000..8c13fca56
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/KeyGenInfo.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.certsrv.base;
+
+import java.io.IOException;
+
+import com.netscape.cmsutil.util.Utils;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerValue;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.X509Key;
+
+/**
+ *
+ * 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 Utils.base64decode(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/base/common/src/com/netscape/certsrv/base/MessageFormatter.java b/base/common/src/com/netscape/certsrv/base/MessageFormatter.java
new file mode 100644
index 000000000..903b534e0
--- /dev/null
+++ b/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.lang.reflect.Method;
+import java.text.MessageFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/base/MetaAttributeDef.java b/base/common/src/com/netscape/certsrv/base/MetaAttributeDef.java
new file mode 100644
index 000000000..3a7bac977
--- /dev/null
+++ b/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<String, MetaAttributeDef> mNameToAttrDef = new Hashtable<String, MetaAttributeDef>();
+ private static Hashtable<ObjectIdentifier, MetaAttributeDef> mOidToAttrDef =
+ new Hashtable<ObjectIdentifier, MetaAttributeDef>();
+
+ 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<String> getAttributeNames() {
+ return mNameToAttrDef.keys();
+ }
+
+ /**
+ * Returns enumeration of the registered attribute object identifiers
+ * <P>
+ *
+ * @return returns enumeration of the attribute object identifiers
+ */
+ public static Enumeration<ObjectIdentifier> getAttributeNameOids() {
+ return mOidToAttrDef.keys();
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/base/MetaInfo.java b/base/common/src/com/netscape/certsrv/base/MetaInfo.java
new file mode 100644
index 000000000..8aed6b840
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/MetaInfo.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.certsrv.base;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7722068404789828101L;
+ public static final String REQUEST_ID = "requestId";
+ public static final String IN_LDAP_PUBLISH_DIR = "inLdapPublishDir";
+
+ private Hashtable<String, Object> content = new Hashtable<String, Object>();
+
+ /**
+ * 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<String> 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<String> getElements() {
+ return content.keys();
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/base/Nonces.java b/base/common/src/com/netscape/certsrv/base/Nonces.java
new file mode 100644
index 000000000..cc0231ac3
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/Nonces.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.certsrv.base;
+
+import java.security.cert.X509Certificate;
+import java.util.Hashtable;
+import java.util.Vector;
+
+/**
+ * This class manages nonces sometimes used to control request state flow.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class Nonces {
+
+ private Hashtable<Long, X509Certificate> mNonces = new Hashtable<Long, X509Certificate>();
+ private Vector<Long> mNonceList = new Vector<Long>();
+ private int mNonceLimit;
+
+ /**
+ * Constructs nonces.
+ */
+ public Nonces() {
+ this(100);
+ }
+
+ public Nonces(int limit) {
+ mNonceLimit = limit;
+ }
+
+ 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/base/common/src/com/netscape/certsrv/base/PasswordResources.java b/base/common/src/com/netscape/certsrv/base/PasswordResources.java
new file mode 100644
index 000000000..c3309c5fa
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/PasswordResources.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.base;
+
+import java.util.ListResourceBundle;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/base/Plugin.java b/base/common/src/com/netscape/certsrv/base/Plugin.java
new file mode 100644
index 000000000..79fae88ac
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/Plugin.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.base;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/base/SessionContext.java b/base/common/src/com/netscape/certsrv/base/SessionContext.java
new file mode 100644
index 000000000..b4ecd1241
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/SessionContext.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.certsrv.base;
+
+import java.util.Hashtable;
+
+/**
+ * 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<Object, Object> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3376355842991589505L;
+
+ /**
+ * 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<Thread, SessionContext> mContexts = new Hashtable<Thread, SessionContext>();
+
+ /**
+ * 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/base/common/src/com/netscape/certsrv/ca/CAResources.java b/base/common/src/com/netscape/certsrv/ca/CAResources.java
new file mode 100644
index 000000000..dfb72d57d
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ca/CAResources.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.ca;
+
+import java.util.ListResourceBundle;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/ca/ECAException.java b/base/common/src/com/netscape/certsrv/ca/ECAException.java
new file mode 100644
index 000000000..a530b08a5
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ca/ECAException.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.ca;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * A class represents a CA exception.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class ECAException extends EBaseException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2963412888833532478L;
+ /**
+ * 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/base/common/src/com/netscape/certsrv/ca/EErrorPublishCRL.java b/base/common/src/com/netscape/certsrv/ca/EErrorPublishCRL.java
new file mode 100644
index 000000000..b4c10a0c5
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ca/EErrorPublishCRL.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.ca;
+
+/**
+ * A class represents a CA exception associated with publishing error.
+ * <P>
+ *
+ * @version $Revision$ $Date$
+ */
+public class EErrorPublishCRL extends ECAException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5773392283237284399L;
+
+ /**
+ * Constructs a CA exception caused by publishing error.
+ * <P>
+ *
+ * @param errorString Detailed error message.
+ */
+ public EErrorPublishCRL(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/ca/ICAService.java b/base/common/src/com/netscape/certsrv/ca/ICAService.java
new file mode 100644
index 000000000..1edebcc8b
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ca/ICAService.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.ca;
+
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.connector.IConnector;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/ca/ICMSCRLExtension.java b/base/common/src/com/netscape/certsrv/ca/ICMSCRLExtension.java
new file mode 100644
index 000000000..b3e94d02e
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ca/ICMSCRLExtension.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.ca;
+
+import netscape.security.x509.Extension;
+
+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/base/common/src/com/netscape/certsrv/ca/ICMSCRLExtensions.java b/base/common/src/com/netscape/certsrv/ca/ICMSCRLExtensions.java
new file mode 100644
index 000000000..6fa520fbf
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ca/ICMSCRLExtensions.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.ca;
+
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.common.NameValuePairs;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/ca/ICRLIssuingPoint.java b/base/common/src/com/netscape/certsrv/ca/ICRLIssuingPoint.java
new file mode 100644
index 000000000..f317db9b1
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ca/ICRLIssuingPoint.java
@@ -0,0 +1,543 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.math.BigInteger;
+import java.util.Date;
+import java.util.Set;
+import java.util.Vector;
+
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.RevokedCertificate;
+import netscape.security.x509.X509CRLImpl;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.dbs.IElementProcessor;
+
+/**
+ * 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<RevokedCertificate> 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<Long> 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/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java b/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java
new file mode 100644
index 000000000..25bc9cabe
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java
@@ -0,0 +1,503 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Enumeration;
+
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CRLImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.base.Nonces;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.dbs.crldb.ICRLRepository;
+import com.netscape.certsrv.dbs.replicadb.IReplicaIDRepository;
+import com.netscape.certsrv.policy.IPolicyProcessor;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.request.IRequestListener;
+import com.netscape.certsrv.request.IRequestNotifier;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.IService;
+import com.netscape.certsrv.security.ISigningUnit;
+
+/**
+ * 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.
+ * @deprecated
+ * @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<ICRLIssuingPoint> 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<String> 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/base/common/src/com/netscape/certsrv/cert/ICrossCertPairSubsystem.java b/base/common/src/com/netscape/certsrv/cert/ICrossCertPairSubsystem.java
new file mode 100644
index 000000000..c79479dc7
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/cert/ICrossCertPairSubsystem.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.cert;
+
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.ISubsystem;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/client/IDataProcessor.java b/base/common/src/com/netscape/certsrv/client/IDataProcessor.java
new file mode 100644
index 000000000..b6784b6d2
--- /dev/null
+++ b/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/base/common/src/com/netscape/certsrv/client/connection/IAuthenticator.java b/base/common/src/com/netscape/certsrv/client/connection/IAuthenticator.java
new file mode 100644
index 000000000..0a96ee698
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/client/connection/IAuthenticator.java
@@ -0,0 +1,26 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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;
+
+/**
+ * An interface represents authentiator.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IAuthenticator {
+}
diff --git a/base/common/src/com/netscape/certsrv/client/connection/IConnection.java b/base/common/src/com/netscape/certsrv/client/connection/IConnection.java
new file mode 100644
index 000000000..4a8166b02
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/client/connection/IConnection.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.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/base/common/src/com/netscape/certsrv/client/connection/IConnectionFactory.java b/base/common/src/com/netscape/certsrv/client/connection/IConnectionFactory.java
new file mode 100644
index 000000000..4506abbfa
--- /dev/null
+++ b/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.io.IOException;
+import java.net.UnknownHostException;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/common/ConfigConstants.java b/base/common/src/com/netscape/certsrv/common/ConfigConstants.java
new file mode 100644
index 000000000..2ea7b7469
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/common/ConfigConstants.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.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/base/common/src/com/netscape/certsrv/common/Constants.java b/base/common/src/com/netscape/certsrv/common/Constants.java
new file mode 100644
index 000000000..be9d33b4c
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/common/Constants.java
@@ -0,0 +1,731 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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/base/common/src/com/netscape/certsrv/common/DestDef.java b/base/common/src/com/netscape/certsrv/common/DestDef.java
new file mode 100644
index 000000000..273e6af05
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/common/DestDef.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.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/base/common/src/com/netscape/certsrv/common/NameValuePairs.java b/base/common/src/com/netscape/certsrv/common/NameValuePairs.java
new file mode 100644
index 000000000..0999db7bc
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/common/NameValuePairs.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.common;
+
+import java.util.LinkedHashMap;
+import java.util.StringTokenizer;
+
+/**
+ * A class represents an ordered list of name
+ * value pairs.
+ *
+ * @version $Revision$, $Date$
+ */
+public class NameValuePairs extends LinkedHashMap<String, String> {
+
+ private static final long serialVersionUID = 1494507857048437440L;
+
+ /**
+ * Constructs name value pairs.
+ */
+ public NameValuePairs() {
+ }
+
+ /**
+ * Show the content of this name value container as
+ * string representation.
+ *
+ * @return string representation
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+
+ for (String name : keySet()) {
+ String value = get(name);
+
+ buf.append(name + "=" + value);
+ 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.put(n, v);
+ }
+ return true;
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/common/OpDef.java b/base/common/src/com/netscape/certsrv/common/OpDef.java
new file mode 100644
index 000000000..22a974e12
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/common/OpDef.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.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/base/common/src/com/netscape/certsrv/common/PrefixDef.java b/base/common/src/com/netscape/certsrv/common/PrefixDef.java
new file mode 100644
index 000000000..833847d05
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/common/PrefixDef.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.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/base/common/src/com/netscape/certsrv/common/ScopeDef.java b/base/common/src/com/netscape/certsrv/common/ScopeDef.java
new file mode 100644
index 000000000..f29067f51
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/common/ScopeDef.java
@@ -0,0 +1,192 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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/base/common/src/com/netscape/certsrv/common/TaskId.java b/base/common/src/com/netscape/certsrv/common/TaskId.java
new file mode 100644
index 000000000..01a97b2a1
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/common/TaskId.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.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/base/common/src/com/netscape/certsrv/connector/IConnector.java b/base/common/src/com/netscape/certsrv/connector/IConnector.java
new file mode 100644
index 000000000..202fb0794
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/connector/IConnector.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.connector;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/connector/IHttpConnFactory.java b/base/common/src/com/netscape/certsrv/connector/IHttpConnFactory.java
new file mode 100644
index 000000000..27a94a57f
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/connector/IHttpConnFactory.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.EBaseException;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/connector/IHttpConnection.java b/base/common/src/com/netscape/certsrv/connector/IHttpConnection.java
new file mode 100644
index 000000000..d1652dc90
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/connector/IHttpConnection.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.connector;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/connector/IHttpPKIMessage.java b/base/common/src/com/netscape/certsrv/connector/IHttpPKIMessage.java
new file mode 100644
index 000000000..efa49126e
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/connector/IHttpPKIMessage.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.connector;
+
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/connector/IPKIMessage.java b/base/common/src/com/netscape/certsrv/connector/IPKIMessage.java
new file mode 100644
index 000000000..787dd8385
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/connector/IPKIMessage.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.connector;
+
+import java.io.Serializable;
+
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/connector/IRemoteAuthority.java b/base/common/src/com/netscape/certsrv/connector/IRemoteAuthority.java
new file mode 100644
index 000000000..50a3aea5f
--- /dev/null
+++ b/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;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/connector/IRequestEncoder.java b/base/common/src/com/netscape/certsrv/connector/IRequestEncoder.java
new file mode 100644
index 000000000..478af4174
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/connector/IRequestEncoder.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.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/base/common/src/com/netscape/certsrv/connector/IResender.java b/base/common/src/com/netscape/certsrv/connector/IResender.java
new file mode 100644
index 000000000..85d3e364c
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/connector/IResender.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.connector;
+
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/dbs/DBResources.java b/base/common/src/com/netscape/certsrv/dbs/DBResources.java
new file mode 100644
index 000000000..a2201b8e6
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/DBResources.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 java.util.ListResourceBundle;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/dbs/EDBException.java b/base/common/src/com/netscape/certsrv/dbs/EDBException.java
new file mode 100644
index 000000000..77508dca4
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/EDBException.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.dbs;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * A class represents a database exception.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class EDBException extends EBaseException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -895521374187351529L;
+ /**
+ * 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/base/common/src/com/netscape/certsrv/dbs/EDBNotAvailException.java b/base/common/src/com/netscape/certsrv/dbs/EDBNotAvailException.java
new file mode 100644
index 000000000..6afb2dcc3
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/EDBNotAvailException.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.dbs;
+
+/**
+ * Indicates internal db is down.
+ *
+ * @version $Revision$, $Date$
+ */
+public class EDBNotAvailException extends EDBException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8516095366048215233L;
+
+ /**
+ * Constructs a ldap server down exception with host & port info.
+ *
+ * @param errorString Detailed error message.
+ */
+ public EDBNotAvailException(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/dbs/EDBRecordNotFoundException.java b/base/common/src/com/netscape/certsrv/dbs/EDBRecordNotFoundException.java
new file mode 100644
index 000000000..dd3880c12
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/EDBRecordNotFoundException.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.dbs;
+
+/**
+ * Indicates internal db is down.
+ *
+ * @version $Revision$, $Date$
+ */
+public class EDBRecordNotFoundException extends EDBException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3797213848651705426L;
+
+ /**
+ * Constructs a ldap server down exception with host & port info.
+ *
+ * @param errorString Detailed error message.
+ */
+ public EDBRecordNotFoundException(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/dbs/IDBAttrMapper.java b/base/common/src/com/netscape/certsrv/dbs/IDBAttrMapper.java
new file mode 100644
index 000000000..27e15bd7d
--- /dev/null
+++ b/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.Enumeration;
+
+import netscape.ldap.LDAPAttributeSet;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * 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<String> 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/base/common/src/com/netscape/certsrv/dbs/IDBDynAttrMapper.java b/base/common/src/com/netscape/certsrv/dbs/IDBDynAttrMapper.java
new file mode 100644
index 000000000..5684dd4d7
--- /dev/null
+++ b/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/base/common/src/com/netscape/certsrv/dbs/IDBObj.java b/base/common/src/com/netscape/certsrv/dbs/IDBObj.java
new file mode 100644
index 000000000..5c634beeb
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/IDBObj.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.Enumeration;
+
+import com.netscape.certsrv.base.IAttrSet;
+
+/**
+ * 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<String> getSerializableAttrNames();
+}
diff --git a/base/common/src/com/netscape/certsrv/dbs/IDBRegistry.java b/base/common/src/com/netscape/certsrv/dbs/IDBRegistry.java
new file mode 100644
index 000000000..241f3af9f
--- /dev/null
+++ b/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 netscape.ldap.LDAPAttributeSet;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.ISubsystem;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/dbs/IDBSSession.java b/base/common/src/com/netscape/certsrv/dbs/IDBSSession.java
new file mode 100644
index 000000000..c186d1145
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/IDBSSession.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 netscape.ldap.LDAPSearchResults;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.ISubsystem;
+
+/**
+ * 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(&quot;cn=123459,o=certificate repository,o=airius.com&quot;,
+ * 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 <T> IDBVirtualList<T> 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;
+
+ public void abandon(LDAPSearchResults results) 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 <T> IDBVirtualList<T> 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 <T> IDBVirtualList<T> createVirtualList(String base, String filter,
+ String attrs[], String startFrom,
+ String sortKey, int pageSize)
+ throws EBaseException;
+}
diff --git a/base/common/src/com/netscape/certsrv/dbs/IDBSearchResults.java b/base/common/src/com/netscape/certsrv/dbs/IDBSearchResults.java
new file mode 100644
index 000000000..04736cf32
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/IDBSearchResults.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.dbs;
+
+import java.util.Enumeration;
+
+/**
+ * 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<Object> {
+
+ /**
+ * 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/base/common/src/com/netscape/certsrv/dbs/IDBSubsystem.java b/base/common/src/com/netscape/certsrv/dbs/IDBSubsystem.java
new file mode 100644
index 000000000..fec6e6afa
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/IDBSubsystem.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.certsrv.dbs;
+
+import java.math.BigInteger;
+
+import netscape.ldap.LDAPConnection;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.ISubsystem;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/dbs/IDBVirtualList.java b/base/common/src/com/netscape/certsrv/dbs/IDBVirtualList.java
new file mode 100644
index 000000000..919a82efb
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/IDBVirtualList.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.dbs;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * 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<E> {
+
+ /**
+ * 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 E getElementAt(int index);
+
+ /**
+ * Retrieves and jumps to element in the given position.
+ *
+ * @param i position
+ * @return object
+ */
+ public E 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/base/common/src/com/netscape/certsrv/dbs/IElementProcessor.java b/base/common/src/com/netscape/certsrv/dbs/IElementProcessor.java
new file mode 100644
index 000000000..648a13aef
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/IElementProcessor.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;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/dbs/IFilterConverter.java b/base/common/src/com/netscape/certsrv/dbs/IFilterConverter.java
new file mode 100644
index 000000000..2c0ccb89f
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/IFilterConverter.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.dbs;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/dbs/Modification.java b/base/common/src/com/netscape/certsrv/dbs/Modification.java
new file mode 100644
index 000000000..6c61bdb1f
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/Modification.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.dbs;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/dbs/ModificationSet.java b/base/common/src/com/netscape/certsrv/dbs/ModificationSet.java
new file mode 100644
index 000000000..70e9b377d
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/ModificationSet.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.dbs;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+/**
+ * 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<Modification> mods = new Vector<Modification>();
+
+ /**
+ * 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<Modification> getModifications() {
+ return mods.elements();
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/dbs/certdb/ICertRecord.java b/base/common/src/com/netscape/certsrv/dbs/certdb/ICertRecord.java
new file mode 100644
index 000000000..d05c9ed5f
--- /dev/null
+++ b/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.math.BigInteger;
+import java.util.Date;
+
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.base.MetaInfo;
+import com.netscape.certsrv.dbs.IDBObj;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/dbs/certdb/ICertRecordList.java b/base/common/src/com/netscape/certsrv/dbs/certdb/ICertRecordList.java
new file mode 100644
index 000000000..59a826ee2
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/certdb/ICertRecordList.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.dbs.certdb;
+
+import java.util.Enumeration;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IElementProcessor;
+
+/**
+ * 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<ICertRecord> 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 ICertRecord getCertRecord(int index)
+ throws EBaseException;
+}
diff --git a/base/common/src/com/netscape/certsrv/dbs/certdb/ICertificateRepository.java b/base/common/src/com/netscape/certsrv/dbs/certdb/ICertificateRepository.java
new file mode 100644
index 000000000..a8505c2a2
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/certdb/ICertificateRepository.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.certsrv.dbs.certdb;
+
+import java.math.BigInteger;
+import java.security.cert.Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import netscape.ldap.LDAPEntry;
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.MetaInfo;
+import com.netscape.certsrv.dbs.IElementProcessor;
+import com.netscape.certsrv.dbs.ModificationSet;
+import com.netscape.certsrv.dbs.repository.IRepository;
+import com.netscape.cmscore.dbs.CertificateRepository.RenewableCertificateCollection;
+
+/**
+ * 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<Object> 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<ICertRecord> 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<ICertRecord> 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<ICertRecord> getAllRevokedCertificates()
+ throws EBaseException;
+
+ /**
+ * Retrieves all revoked but not expired certificates.
+ *
+ * @return a list of revoked certificates
+ * @exception EBaseException failed to search
+ */
+ public Enumeration<ICertRecord> 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<X509CertImpl> 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<ICertRecord> 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<Object> findCertRecs(String filter)
+ throws EBaseException;
+
+ /**
+ * Retrieves renewable certificates.
+ *
+ * @param renewalTime renewal time
+ * @return certificates
+ * @exception EBaseException failed to retrieve
+ */
+ public Hashtable<String, RenewableCertificateCollection> 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<ICertRecord> 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<ICertRecord> 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<ICertRecord> 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<ICertRecord> 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<ICertRecord> 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<ICertRecord> 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;
+
+ /**
+ * 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, String filter, int pageSize) throws EBaseException;
+
+ public void shutdown();
+}
diff --git a/base/common/src/com/netscape/certsrv/dbs/certdb/IRevocationInfo.java b/base/common/src/com/netscape/certsrv/dbs/certdb/IRevocationInfo.java
new file mode 100644
index 000000000..fb773576c
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/certdb/IRevocationInfo.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.dbs.certdb;
+
+import java.util.Date;
+
+import netscape.security.x509.CRLExtensions;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/dbs/crldb/ICRLIssuingPointRecord.java b/base/common/src/com/netscape/certsrv/dbs/crldb/ICRLIssuingPointRecord.java
new file mode 100644
index 000000000..b990bbf57
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/crldb/ICRLIssuingPointRecord.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.certsrv.dbs.crldb;
+
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Hashtable;
+
+import netscape.security.x509.RevokedCertificate;
+
+import com.netscape.certsrv.dbs.IDBObj;
+
+/**
+ * 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<BigInteger, RevokedCertificate> getCRLCacheNoClone();
+
+ public Hashtable<BigInteger, RevokedCertificate> getCRLCache();
+
+ /**
+ * Retrieves cache information about revoked certificates.
+ *
+ * @return list of recently revoked certificates
+ */
+ public Hashtable<BigInteger, RevokedCertificate> getRevokedCerts();
+
+ /**
+ * Retrieves cache information about certificates released from hold.
+ *
+ * @return list of certificates recently released from hold
+ */
+ public Hashtable<BigInteger, RevokedCertificate> getUnrevokedCerts();
+
+ /**
+ * Retrieves cache information about expired certificates.
+ *
+ * @return list of recently expired certificates
+ */
+ public Hashtable<BigInteger, RevokedCertificate> getExpiredCerts();
+}
diff --git a/base/common/src/com/netscape/certsrv/dbs/crldb/ICRLRepository.java b/base/common/src/com/netscape/certsrv/dbs/crldb/ICRLRepository.java
new file mode 100644
index 000000000..806a2cb19
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/crldb/ICRLRepository.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.dbs.crldb;
+
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import netscape.security.x509.RevokedCertificate;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.ModificationSet;
+
+/**
+ * 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<String> 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<BigInteger, RevokedCertificate> revokedCerts,
+ Hashtable<BigInteger, RevokedCertificate> unrevokedCerts,
+ Hashtable<BigInteger, RevokedCertificate> 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<BigInteger, RevokedCertificate> revokedCerts, Hashtable<BigInteger, RevokedCertificate> 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<BigInteger, RevokedCertificate> 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<BigInteger, RevokedCertificate> revokedCerts,
+ Hashtable<BigInteger, RevokedCertificate> unrevokedCerts,
+ Hashtable<BigInteger, RevokedCertificate> 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/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRecord.java b/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRecord.java
new file mode 100644
index 000000000..7da212469
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRecord.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.certsrv.dbs.keydb;
+
+import java.math.BigInteger;
+import java.util.Date;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * 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";
+ public static final String ATTR_CLIENT_ID = "clientId";
+ public static final String ATTR_DATA_TYPE = "dataType";
+ public static final String ATTR_STATUS = "status";
+
+
+ // 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 client ID.
+ *
+ * @return client id
+ * @exception EBaseException failed to retrieve client id
+ */
+ public String getClientId() throws EBaseException;
+
+ /**
+ * Retrieves key data type.
+ *
+ * @return data type
+ * @exception EBaseException failed to retrieve data type
+ */
+ public String getDataType() throws EBaseException;
+
+ /**
+ * Retrieves key status.
+ *
+ * @return key status
+ * @exception EBaseException failed to retrieve key status
+ */
+ public String getKeyStatus() 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/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRecordList.java b/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRecordList.java
new file mode 100644
index 000000000..75f833892
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRecordList.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.keydb;
+
+import java.util.Enumeration;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * 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<IKeyRecord> getKeyRecords(int startidx, int endidx)
+ throws EBaseException;
+}
diff --git a/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRepository.java b/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRepository.java
new file mode 100644
index 000000000..627844286
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRepository.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.certsrv.dbs.keydb;
+
+import java.math.BigInteger;
+import java.security.PublicKey;
+import java.util.Enumeration;
+
+import netscape.security.x509.X500Name;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.ModificationSet;
+import com.netscape.certsrv.dbs.repository.IRepository;
+
+/**
+ * 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<IKeyRecord> 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<IKeyRecord> 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/base/common/src/com/netscape/certsrv/dbs/keydb/KeyId.java b/base/common/src/com/netscape/certsrv/dbs/keydb/KeyId.java
new file mode 100644
index 000000000..f998bf97a
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/keydb/KeyId.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.dbs.keydb;
+
+import java.math.BigInteger;
+
+/**
+ * The KeyId class represents the identifier for a particular
+ * key record. This identifier may be used to retrieve the key record
+ * from the database.
+ * <p>
+ *
+ * @author Endi S. Dewata
+ * @version $Revision$ $Date$
+ */
+public class KeyId {
+
+ protected BigInteger value;
+
+ /**
+ * Creates a new KeyId from its string representation.
+ * <p>
+ *
+ * @param id
+ * a string containing the decimal or hex value for the identifier.
+ */
+ public KeyId(String id) {
+ if (id != null) {
+ id = id.trim();
+ if (id.startsWith("0x")) { // hex
+ value = new BigInteger(id.substring(2), 16);
+ } else { // decimal
+ value = new BigInteger(id);
+ }
+ }
+ }
+
+ /**
+ * Creates a new KeyId from its BigInteger representation.
+ * <p>
+ *
+ * @param id
+ * a BigInteger containing the identifier.
+ */
+ public KeyId(BigInteger id) {
+ value = id;
+ }
+
+ /**
+ * Creates a new KeyId from its integer representation.
+ * <p>
+ *
+ * @param id
+ * an integer containing the identifier.
+ */
+ public KeyId(int id) {
+ value = BigInteger.valueOf(id);
+ }
+
+ /**
+ * Converts the KeyId into its BigInteger representation.
+ * <p>
+ *
+ * @return
+ * a BigInteger containing the identifier.
+ */
+ public BigInteger toBigInteger() {
+ return value;
+ }
+
+ /**
+ * Converts the KeyId 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 value.toString();
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((value == null) ? 0 : value.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ KeyId other = (KeyId) obj;
+ if (value == null) {
+ if (other.value != null)
+ return false;
+ } else if (!value.equals(other.value))
+ return false;
+ return true;
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/dbs/keydb/KeyIdAdapter.java b/base/common/src/com/netscape/certsrv/dbs/keydb/KeyIdAdapter.java
new file mode 100644
index 000000000..3232999fd
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/keydb/KeyIdAdapter.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.dbs.keydb;
+
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+
+/**
+ * The KeyIdAdapter class provides custom marshaling for KeyId.
+ *
+ * @author Endi S. Dewata
+ * @version $Revision$ $Date$
+ */
+public class KeyIdAdapter extends XmlAdapter<String, KeyId> {
+
+ public KeyId unmarshal(String value) throws Exception {
+ return new KeyId(value);
+ }
+
+ public String marshal(KeyId value) throws Exception {
+ return value.toString();
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/dbs/keydb/KeyState.java b/base/common/src/com/netscape/certsrv/dbs/keydb/KeyState.java
new file mode 100644
index 000000000..fa8a0d768
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/keydb/KeyState.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.dbs.keydb;
+
+import java.io.Serializable;
+
+/**
+ * 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 static final long serialVersionUID = 5452723730414730579L;
+ 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/base/common/src/com/netscape/certsrv/dbs/replicadb/IReplicaIDRepository.java b/base/common/src/com/netscape/certsrv/dbs/replicadb/IReplicaIDRepository.java
new file mode 100644
index 000000000..574adfae9
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/replicadb/IReplicaIDRepository.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.certsrv.dbs.replicadb;
+
+import com.netscape.certsrv.dbs.repository.IRepository;
+
+/**
+ * An interface represents a ReplicaID Repository.
+ * It provides unique managed replica IDs.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IReplicaIDRepository extends IRepository {
+}
diff --git a/base/common/src/com/netscape/certsrv/dbs/repository/IRepository.java b/base/common/src/com/netscape/certsrv/dbs/repository/IRepository.java
new file mode 100644
index 000000000..943d4a686
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/repository/IRepository.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.dbs.repository;
+
+import java.math.BigInteger;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/dbs/repository/IRepositoryRecord.java b/base/common/src/com/netscape/certsrv/dbs/repository/IRepositoryRecord.java
new file mode 100644
index 000000000..c46e8419c
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/dbs/repository/IRepositoryRecord.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.dbs.repository;
+
+import java.math.BigInteger;
+
+import com.netscape.certsrv.dbs.IDBObj;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/evaluators/IAccessEvaluator.java b/base/common/src/com/netscape/certsrv/evaluators/IAccessEvaluator.java
new file mode 100644
index 000000000..31f8b8c2f
--- /dev/null
+++ b/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 com.netscape.certsrv.authentication.IAuthToken;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/extensions/EExtensionsException.java b/base/common/src/com/netscape/certsrv/extensions/EExtensionsException.java
new file mode 100644
index 000000000..40fe80f99
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/extensions/EExtensionsException.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.extensions;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * This represents the extensions exception.
+ *
+ * @version $Revision$, $Date$
+ */
+public class EExtensionsException extends EBaseException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6442466262945583489L;
+ /**
+ * 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/base/common/src/com/netscape/certsrv/extensions/ExtensionsResources.java b/base/common/src/com/netscape/certsrv/extensions/ExtensionsResources.java
new file mode 100644
index 000000000..ca1e4545a
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/extensions/ExtensionsResources.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.extensions;
+
+import java.util.ListResourceBundle;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/extensions/ICMSExtension.java b/base/common/src/com/netscape/certsrv/extensions/ICMSExtension.java
new file mode 100644
index 000000000..04086adcf
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/extensions/ICMSExtension.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.extensions;
+
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.Extension;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/jobs/EJobsException.java b/base/common/src/com/netscape/certsrv/jobs/EJobsException.java
new file mode 100644
index 000000000..cc0923ae7
--- /dev/null
+++ b/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 com.netscape.certsrv.base.EBaseException;
+
+/**
+ * A class represents a jobs exception.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class EJobsException extends EBaseException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4542243534794168088L;
+ /**
+ * 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/base/common/src/com/netscape/certsrv/jobs/IJob.java b/base/common/src/com/netscape/certsrv/jobs/IJob.java
new file mode 100644
index 000000000..5584d68ff
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/jobs/IJob.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.jobs;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+
+/**
+ * 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();
+
+ /**
+ * Request the job to stop gracefully. The job may not stop immediately.
+ */
+ public void stop();
+
+ /**
+ * Check whether the job has been asked to stop. Long running jobs should call
+ * this method occasionally inside the run() method and exit gracefully if it
+ * returns true.
+ */
+ public boolean isStopped();
+}
diff --git a/base/common/src/com/netscape/certsrv/jobs/IJobCron.java b/base/common/src/com/netscape/certsrv/jobs/IJobCron.java
new file mode 100644
index 000000000..f161b5e8d
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/jobs/IJobCron.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.jobs;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/jobs/IJobsScheduler.java b/base/common/src/com/netscape/certsrv/jobs/IJobsScheduler.java
new file mode 100644
index 000000000..f4184853d
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/jobs/IJobsScheduler.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.certsrv.jobs;
+
+import java.util.Hashtable;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.ISubsystem;
+
+/**
+ * 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<String, JobPlugin> getPlugins();
+
+ /**
+ * Retrieves all the job instances.
+ *
+ * @return a Hashtable of job instances
+ */
+ public Hashtable<String, IJob> 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/base/common/src/com/netscape/certsrv/jobs/JobPlugin.java b/base/common/src/com/netscape/certsrv/jobs/JobPlugin.java
new file mode 100644
index 000000000..46a1b6d7e
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/jobs/JobPlugin.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.jobs;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/jobs/JobsResources.java b/base/common/src/com/netscape/certsrv/jobs/JobsResources.java
new file mode 100644
index 000000000..ec33137cf
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/jobs/JobsResources.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.jobs;
+
+import java.util.ListResourceBundle;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/kra/EKRAException.java b/base/common/src/com/netscape/certsrv/kra/EKRAException.java
new file mode 100644
index 000000000..3f23bfe78
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/kra/EKRAException.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.kra;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6803576959258754821L;
+ /**
+ * 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/base/common/src/com/netscape/certsrv/kra/IJoinShares.java b/base/common/src/com/netscape/certsrv/kra/IJoinShares.java
new file mode 100644
index 000000000..e9a5ecae5
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/kra/IJoinShares.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.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/base/common/src/com/netscape/certsrv/kra/IKeyRecoveryAuthority.java b/base/common/src/com/netscape/certsrv/kra/IKeyRecoveryAuthority.java
new file mode 100644
index 000000000..a7cc40507
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/kra/IKeyRecoveryAuthority.java
@@ -0,0 +1,321 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import netscape.security.x509.X500Name;
+
+import org.mozilla.jss.crypto.CryptoToken;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.dbs.replicadb.IReplicaIDRepository;
+import com.netscape.certsrv.policy.IPolicyProcessor;
+import com.netscape.certsrv.request.IRequestListener;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.security.Credential;
+import com.netscape.certsrv.security.IStorageKeyUnit;
+import com.netscape.certsrv.security.ITransportKeyUnit;
+
+/**
+ * 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<String> 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.
+ * @deprecated
+ * @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<String, Object> createVolatileRequest(RequestId id);
+
+ /**
+ * Retrieves the request object.
+ *
+ * @param id request id
+ * @return volatile requests
+ */
+ public Hashtable<String, Object> getVolatileRequest(RequestId id);
+
+ /**
+ * Destroys the request object.
+ *
+ * @param id request id
+ */
+ public void destroyVolatileRequest(RequestId id);
+
+ public Vector<Credential> 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/base/common/src/com/netscape/certsrv/kra/IKeyService.java b/base/common/src/com/netscape/certsrv/kra/IKeyService.java
new file mode 100644
index 000000000..13748f2d1
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/kra/IKeyService.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.certsrv.kra;
+
+import java.math.BigInteger;
+import java.util.Hashtable;
+
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.security.Credential;
+
+/**
+ * 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<String, Object> 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<String, Object> 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/base/common/src/com/netscape/certsrv/kra/IProofOfArchival.java b/base/common/src/com/netscape/certsrv/kra/IProofOfArchival.java
new file mode 100644
index 000000000..20ac336e5
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/kra/IProofOfArchival.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.kra;
+
+import java.math.BigInteger;
+import java.util.Date;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/kra/IShare.java b/base/common/src/com/netscape/certsrv/kra/IShare.java
new file mode 100644
index 000000000..19e7d7ce2
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/kra/IShare.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 IShare {
+
+ public void initialize(byte[] secret, int threshold) throws Exception;
+
+ public byte[] createShare(int sharenumber);
+
+}
diff --git a/base/common/src/com/netscape/certsrv/kra/KRAResources.java b/base/common/src/com/netscape/certsrv/kra/KRAResources.java
new file mode 100644
index 000000000..14b686e63
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/kra/KRAResources.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.kra;
+
+import java.util.ListResourceBundle;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/kra/ProofOfArchival.java b/base/common/src/com/netscape/certsrv/kra/ProofOfArchival.java
new file mode 100644
index 000000000..df05c882f
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/kra/ProofOfArchival.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.certsrv.kra;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.X500Name;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBObj;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2533562170977678799L;
+
+ /**
+ * 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<String> mNames = new Vector<String>();
+ 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<String> getElements() {
+ return mNames.elements();
+ }
+
+ /**
+ * Retrieves serializable attribute names.
+ *
+ * @return a list of serializable attribute names
+ */
+ public Enumeration<String> 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
+ seq.putInteger(new BigInt(mSerialNo));
+
+ // subject name
+ new X500Name(mSubject).encode(seq);
+
+ // issuer name
+ 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"));
+ }
+
+ @SuppressWarnings("unused")
+ AlgorithmId algid = AlgorithmId.parse(seq[1]); // consume algid
+
+ @SuppressWarnings("unused")
+ byte signature[] = seq[2].getBitString(); // consume signature
+
+ 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/base/common/src/com/netscape/certsrv/ldap/ELdapException.java b/base/common/src/com/netscape/certsrv/ldap/ELdapException.java
new file mode 100644
index 000000000..8c1d2d4a5
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ldap/ELdapException.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.certsrv.ldap;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4345538974758823452L;
+ /**
+ * 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/base/common/src/com/netscape/certsrv/ldap/ELdapServerDownException.java b/base/common/src/com/netscape/certsrv/ldap/ELdapServerDownException.java
new file mode 100644
index 000000000..f347b1714
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ldap/ELdapServerDownException.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.ldap;
+
+/**
+ * This represents exception which indicates Ldap server is down.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ELdapServerDownException extends ELdapException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -21440748379854829L;
+
+ /**
+ * Constructs a ldap server down exception with host & port info.
+ *
+ * @param errorString Detailed error message.
+ */
+ public ELdapServerDownException(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/ldap/ILdapAuthInfo.java b/base/common/src/com/netscape/certsrv/ldap/ILdapAuthInfo.java
new file mode 100644
index 000000000..4325f077c
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ldap/ILdapAuthInfo.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.ldap;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/ldap/ILdapBoundConnFactory.java b/base/common/src/com/netscape/certsrv/ldap/ILdapBoundConnFactory.java
new file mode 100644
index 000000000..846f51749
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ldap/ILdapBoundConnFactory.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.ldap;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/ldap/ILdapConnFactory.java b/base/common/src/com/netscape/certsrv/ldap/ILdapConnFactory.java
new file mode 100644
index 000000000..738f5832d
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ldap/ILdapConnFactory.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.ldap;
+
+import netscape.ldap.LDAPConnection;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/ldap/ILdapConnInfo.java b/base/common/src/com/netscape/certsrv/ldap/ILdapConnInfo.java
new file mode 100644
index 000000000..aa5b388a3
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ldap/ILdapConnInfo.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.ldap;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/ldap/ILdapConnModule.java b/base/common/src/com/netscape/certsrv/ldap/ILdapConnModule.java
new file mode 100644
index 000000000..efa1c271e
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ldap/ILdapConnModule.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.ldap;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/ldap/LdapResources.java b/base/common/src/com/netscape/certsrv/ldap/LdapResources.java
new file mode 100644
index 000000000..332fcaddf
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ldap/LdapResources.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.ldap;
+
+import java.util.ListResourceBundle;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/listeners/EListenersException.java b/base/common/src/com/netscape/certsrv/listeners/EListenersException.java
new file mode 100644
index 000000000..6aee21ff4
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/listeners/EListenersException.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.listeners;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * A class represents a listener exception.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class EListenersException extends EBaseException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8895858413292894796L;
+ /**
+ * 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/base/common/src/com/netscape/certsrv/listeners/IRequestListenerPlugin.java b/base/common/src/com/netscape/certsrv/listeners/IRequestListenerPlugin.java
new file mode 100644
index 000000000..c615586db
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/listeners/IRequestListenerPlugin.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.listeners;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/listeners/ListenersResources.java b/base/common/src/com/netscape/certsrv/listeners/ListenersResources.java
new file mode 100644
index 000000000..9eaf41371
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/listeners/ListenersResources.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.listeners;
+
+import java.util.ListResourceBundle;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/logging/AuditEvent.java b/base/common/src/com/netscape/certsrv/logging/AuditEvent.java
new file mode 100644
index 000000000..aa0077b06
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/AuditEvent.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.certsrv.logging;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.MessageFormatter;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -844306657733902324L;
+
+ 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(&quot;failed to load {0}&quot;, 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/base/common/src/com/netscape/certsrv/logging/AuditFormat.java b/base/common/src/com/netscape/certsrv/logging/AuditFormat.java
new file mode 100644
index 000000000..e5f8726f7
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/AuditFormat.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.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}";
+ public static final String ADDCERTSUBJECTDNFORMAT =
+ "Admin UID: {0} added cert subject DN for User UID: {1}. cert DN: {2}";
+
+ // LDAP publishing
+ public static final String LDAP_PUBLISHED_FORMAT =
+ "{0} successfully published serial number: 0x{1} with DN: {2}";
+
+}
diff --git a/base/common/src/com/netscape/certsrv/logging/ConsoleError.java b/base/common/src/com/netscape/certsrv/logging/ConsoleError.java
new file mode 100644
index 000000000..13e0f3d45
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/ConsoleError.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;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/logging/ConsoleLog.java b/base/common/src/com/netscape/certsrv/logging/ConsoleLog.java
new file mode 100644
index 000000000..2e87fc92c
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/ConsoleLog.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.certsrv.logging;
+
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.servlet.ServletException;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.common.NameValuePairs;
+
+/**
+ * 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<String, String> req) throws ServletException,
+ IOException, EBaseException {
+ return null;
+ }
+
+ /**
+ * Retrieve log file list. <br>
+ * unimplemented
+ */
+ public synchronized NameValuePairs retrieveLogList(Hashtable<String, String> req) throws ServletException,
+ IOException, EBaseException {
+ return null;
+ }
+
+ public String getImplName() {
+ return "ConsoleLog";
+ }
+
+ public String getDescription() {
+ return "ConsoleLog";
+ }
+
+ public Vector<String> getDefaultParams() {
+ Vector<String> v = new Vector<String>();
+
+ return v;
+ }
+
+ public Vector<String> getInstanceParams() {
+ Vector<String> v = new Vector<String>();
+
+ return v;
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/logging/ELogException.java b/base/common/src/com/netscape/certsrv/logging/ELogException.java
new file mode 100644
index 000000000..717dbdfe2
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/ELogException.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.certsrv.logging;
+
+import java.util.Locale;
+
+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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8903703675126348145L;
+ /**
+ * 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(&quot;failed to load {0}&quot;, 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/base/common/src/com/netscape/certsrv/logging/ELogNotFound.java b/base/common/src/com/netscape/certsrv/logging/ELogNotFound.java
new file mode 100644
index 000000000..7de84733c
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/ELogNotFound.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.logging;
+
+/**
+ * Exception for log not found.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ELogNotFound extends ELogException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7970168133875460127L;
+
+ /**
+ * Constructs a exception for a missing required log.
+ *
+ * @param errorString Detailed error message.
+ */
+ public ELogNotFound(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/logging/ELogPluginNotFound.java b/base/common/src/com/netscape/certsrv/logging/ELogPluginNotFound.java
new file mode 100644
index 000000000..6c434aff9
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/ELogPluginNotFound.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.logging;
+
+/**
+ * Exception for log plugin not found.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ELogPluginNotFound extends ELogException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 256873523074609116L;
+
+ /**
+ * Constructs a exception for a missing log plugin.
+ *
+ * @param errorString Detailed error message.
+ */
+ public ELogPluginNotFound(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/logging/IBundleLogEvent.java b/base/common/src/com/netscape/certsrv/logging/IBundleLogEvent.java
new file mode 100644
index 000000000..9dd8595cf
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/IBundleLogEvent.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.logging;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/logging/ILogEvent.java b/base/common/src/com/netscape/certsrv/logging/ILogEvent.java
new file mode 100644
index 000000000..423918983
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/ILogEvent.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.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/base/common/src/com/netscape/certsrv/logging/ILogEventFactory.java b/base/common/src/com/netscape/certsrv/logging/ILogEventFactory.java
new file mode 100644
index 000000000..bfd5be930
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/ILogEventFactory.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.certsrv.logging;
+
+import java.util.Properties;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/logging/ILogEventListener.java b/base/common/src/com/netscape/certsrv/logging/ILogEventListener.java
new file mode 100644
index 000000000..15ff08ad5
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/ILogEventListener.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.certsrv.logging;
+
+import java.io.IOException;
+import java.util.EventListener;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.servlet.ServletException;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.common.NameValuePairs;
+
+/**
+ * An interface represents 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 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<String, String> req) throws ServletException,
+ IOException, EBaseException;
+
+ /**
+ * Retrieve list of log files.
+ *
+ */
+ public NameValuePairs retrieveLogList(Hashtable<String, String> 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<String> getDefaultParams();
+
+ /**
+ * Return list of instance config parameters for this log event listener.
+ *
+ * @return Vector of instance parameters.
+ */
+ public Vector<String> getInstanceParams();
+}
diff --git a/base/common/src/com/netscape/certsrv/logging/ILogQueue.java b/base/common/src/com/netscape/certsrv/logging/ILogQueue.java
new file mode 100644
index 000000000..bca7a93df
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/ILogQueue.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.logging;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/logging/ILogSubsystem.java b/base/common/src/com/netscape/certsrv/logging/ILogSubsystem.java
new file mode 100644
index 000000000..ce317a5b8
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/ILogSubsystem.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.certsrv.logging;
+
+import java.util.Hashtable;
+import java.util.Vector;
+
+import com.netscape.certsrv.base.ISubsystem;
+
+/**
+ * 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<String, LogPlugin> 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<String, ILogEventListener> 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<String> 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<String> getLogInstanceParams(String insName)
+ throws ELogException;
+}
diff --git a/base/common/src/com/netscape/certsrv/logging/ILogger.java b/base/common/src/com/netscape/certsrv/logging/ILogger.java
new file mode 100644
index 000000000..4cdb4b80f
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/ILogger.java
@@ -0,0 +1,492 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Properties;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/logging/LogPlugin.java b/base/common/src/com/netscape/certsrv/logging/LogPlugin.java
new file mode 100644
index 000000000..9d7a5cc45
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/LogPlugin.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.logging;
+
+import com.netscape.certsrv.base.Plugin;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/logging/LogResources.java b/base/common/src/com/netscape/certsrv/logging/LogResources.java
new file mode 100644
index 000000000..899bf1893
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/LogResources.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.logging;
+
+import java.util.ListResourceBundle;
+import java.util.ResourceBundle;
+
+import com.netscape.certsrv.base.BaseResources;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/logging/SignedAuditEvent.java b/base/common/src/com/netscape/certsrv/logging/SignedAuditEvent.java
new file mode 100644
index 000000000..8541eda34
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/SignedAuditEvent.java
@@ -0,0 +1,349 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.text.MessageFormat;
+import java.util.Locale;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.MessageFormatter;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4287822756516673931L;
+
+ 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(&quot;failed to load {0}&quot;, 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/base/common/src/com/netscape/certsrv/logging/SystemEvent.java b/base/common/src/com/netscape/certsrv/logging/SystemEvent.java
new file mode 100644
index 000000000..9f625cdfd
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/SystemEvent.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.certsrv.logging;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.MessageFormatter;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7160410535724580752L;
+
+ 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(&quot;failed to load {0}&quot;, 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/base/common/src/com/netscape/certsrv/notification/ENotificationException.java b/base/common/src/com/netscape/certsrv/notification/ENotificationException.java
new file mode 100644
index 000000000..fffc8edeb
--- /dev/null
+++ b/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 com.netscape.certsrv.base.EBaseException;
+
+/**
+ * A class represents a notification exception.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class ENotificationException extends EBaseException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2101529206306996303L;
+ /**
+ * 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/base/common/src/com/netscape/certsrv/notification/IEmailFormProcessor.java b/base/common/src/com/netscape/certsrv/notification/IEmailFormProcessor.java
new file mode 100644
index 000000000..40114bd1e
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/notification/IEmailFormProcessor.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.certsrv.notification;
+
+import java.util.Hashtable;
+import java.util.Vector;
+
+/**
+ * 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<String, Object> tok2vals);
+
+ /**
+ * takes a vector of strings and concatenate them
+ */
+ public String formContent(Vector<String> vec);
+
+ /**
+ * logs an entry in the log file.
+ */
+ public void log(int level, String msg);
+}
diff --git a/base/common/src/com/netscape/certsrv/notification/IEmailResolver.java b/base/common/src/com/netscape/certsrv/notification/IEmailResolver.java
new file mode 100644
index 000000000..39e5bed37
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/notification/IEmailResolver.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.notification;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/notification/IEmailResolverKeys.java b/base/common/src/com/netscape/certsrv/notification/IEmailResolverKeys.java
new file mode 100644
index 000000000..1363a9e09
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/notification/IEmailResolverKeys.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.notification;
+
+import com.netscape.certsrv.base.IAttrSet;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/notification/IEmailTemplate.java b/base/common/src/com/netscape/certsrv/notification/IEmailTemplate.java
new file mode 100644
index 000000000..cbdea8436
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/notification/IEmailTemplate.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.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/base/common/src/com/netscape/certsrv/notification/IMailNotification.java b/base/common/src/com/netscape/certsrv/notification/IMailNotification.java
new file mode 100644
index 000000000..356a6bba3
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/notification/IMailNotification.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.notification;
+
+import java.io.IOException;
+import java.util.Vector;
+
+/**
+ * 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<String> addresses);
+
+ /**
+ * sets the recipient's email address
+ *
+ * @param to address of the recipient email address
+ */
+ public void setTo(String to);
+
+}
diff --git a/base/common/src/com/netscape/certsrv/notification/NotificationResources.java b/base/common/src/com/netscape/certsrv/notification/NotificationResources.java
new file mode 100644
index 000000000..b81443999
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/notification/NotificationResources.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.notification;
+
+import java.util.ListResourceBundle;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/ocsp/IDefStore.java b/base/common/src/com/netscape/certsrv/ocsp/IDefStore.java
new file mode 100644
index 000000000..ee4c76a08
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ocsp/IDefStore.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.ocsp;
+
+import java.math.BigInteger;
+import java.security.cert.X509CRL;
+import java.util.Date;
+import java.util.Enumeration;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.dbs.repository.IRepositoryRecord;
+
+/**
+ * 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<ICRLIssuingPointRecord> 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<ICRLIssuingPointRecord> 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/base/common/src/com/netscape/certsrv/ocsp/IOCSPAuthority.java b/base/common/src/com/netscape/certsrv/ocsp/IOCSPAuthority.java
new file mode 100644
index 000000000..0219d357d
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ocsp/IOCSPAuthority.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.ocsp;
+
+import netscape.security.x509.X500Name;
+
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.security.ISigningUnit;
+import com.netscape.cmsutil.ocsp.BasicOCSPResponse;
+import com.netscape.cmsutil.ocsp.ResponderID;
+import com.netscape.cmsutil.ocsp.ResponseData;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/ocsp/IOCSPService.java b/base/common/src/com/netscape/certsrv/ocsp/IOCSPService.java
new file mode 100644
index 000000000..574289c29
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ocsp/IOCSPService.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.ocsp;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.cmsutil.ocsp.OCSPRequest;
+import com.netscape.cmsutil.ocsp.OCSPResponse;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/ocsp/IOCSPStore.java b/base/common/src/com/netscape/certsrv/ocsp/IOCSPStore.java
new file mode 100644
index 000000000..676122105
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ocsp/IOCSPStore.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.ocsp;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.cmsutil.ocsp.OCSPRequest;
+import com.netscape.cmsutil.ocsp.OCSPResponse;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/password/EPasswordCheckException.java b/base/common/src/com/netscape/certsrv/password/EPasswordCheckException.java
new file mode 100644
index 000000000..3dc028ffb
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/password/EPasswordCheckException.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.password;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.PasswordResources;
+
+/**
+ * A class represents a password checker exception.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class EPasswordCheckException extends EBaseException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6274695122717026554L;
+ /**
+ * 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/base/common/src/com/netscape/certsrv/password/IConfigPasswordCheck.java b/base/common/src/com/netscape/certsrv/password/IConfigPasswordCheck.java
new file mode 100644
index 000000000..8b23fa513
--- /dev/null
+++ b/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/base/common/src/com/netscape/certsrv/password/IPasswordCheck.java b/base/common/src/com/netscape/certsrv/password/IPasswordCheck.java
new file mode 100644
index 000000000..d885d3fce
--- /dev/null
+++ b/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/base/common/src/com/netscape/certsrv/pattern/AttrSetCollection.java b/base/common/src/com/netscape/certsrv/pattern/AttrSetCollection.java
new file mode 100644
index 000000000..5f73fc257
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/pattern/AttrSetCollection.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.pattern;
+
+import java.util.Hashtable;
+
+import com.netscape.certsrv.base.IAttrSet;
+
+/**
+ * This class represents a collection of attribute
+ * sets.
+ *
+ * @version $Revision$, $Date$
+ */
+public class AttrSetCollection extends Hashtable<String, IAttrSet> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8499028375092730021L;
+
+ /**
+ * 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/base/common/src/com/netscape/certsrv/pattern/Pattern.java b/base/common/src/com/netscape/certsrv/pattern/Pattern.java
new file mode 100644
index 000000000..bce3a426b
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/pattern/Pattern.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.certsrv.pattern;
+
+import java.util.Enumeration;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IAttrSet;
+
+/**
+ * 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<String> 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/base/common/src/com/netscape/certsrv/policy/EPolicyException.java b/base/common/src/com/netscape/certsrv/policy/EPolicyException.java
new file mode 100644
index 000000000..f32f4f64f
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/policy/EPolicyException.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.policy;
+
+import java.util.Locale;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.MessageFormatter;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1969940775036388085L;
+ /**
+ * 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(&quot;failed to load {0}&quot;, 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/base/common/src/com/netscape/certsrv/policy/IEnrollmentPolicy.java b/base/common/src/com/netscape/certsrv/policy/IEnrollmentPolicy.java
new file mode 100644
index 000000000..7c789932a
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/policy/IEnrollmentPolicy.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.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/base/common/src/com/netscape/certsrv/policy/IExpression.java b/base/common/src/com/netscape/certsrv/policy/IExpression.java
new file mode 100644
index 000000000..4075e8683
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/policy/IExpression.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.policy;
+
+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/base/common/src/com/netscape/certsrv/policy/IGeneralNameAsConstraintsConfig.java b/base/common/src/com/netscape/certsrv/policy/IGeneralNameAsConstraintsConfig.java
new file mode 100644
index 000000000..78ec31198
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/policy/IGeneralNameAsConstraintsConfig.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.Vector;
+
+import netscape.security.x509.GeneralName;
+
+/**
+ * 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<String> params);
+
+ /**
+ * Retrieves the general name.
+ *
+ * @return general name
+ */
+ public GeneralName getGeneralName();
+
+}
diff --git a/base/common/src/com/netscape/certsrv/policy/IGeneralNameConfig.java b/base/common/src/com/netscape/certsrv/policy/IGeneralNameConfig.java
new file mode 100644
index 000000000..193269bbd
--- /dev/null
+++ b/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.Vector;
+
+import netscape.security.x509.GeneralName;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * 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<GeneralName> formGeneralNames(Object value)
+ throws EBaseException;
+
+ /**
+ * Retrieves the instance parameters.
+ *
+ * @param params parameters
+ */
+ public void getInstanceParams(Vector<String> params);
+}
diff --git a/base/common/src/com/netscape/certsrv/policy/IGeneralNameUtil.java b/base/common/src/com/netscape/certsrv/policy/IGeneralNameUtil.java
new file mode 100644
index 000000000..102b25ccd
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/policy/IGeneralNameUtil.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.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/base/common/src/com/netscape/certsrv/policy/IGeneralNamesAsConstraintsConfig.java b/base/common/src/com/netscape/certsrv/policy/IGeneralNamesAsConstraintsConfig.java
new file mode 100644
index 000000000..aeb7867e3
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/policy/IGeneralNamesAsConstraintsConfig.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.Vector;
+
+import netscape.security.x509.GeneralNames;
+
+/**
+ * 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<String> params);
+
+}
diff --git a/base/common/src/com/netscape/certsrv/policy/IGeneralNamesConfig.java b/base/common/src/com/netscape/certsrv/policy/IGeneralNamesConfig.java
new file mode 100644
index 000000000..2074b9d19
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/policy/IGeneralNamesConfig.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.certsrv.policy;
+
+import java.util.Vector;
+
+import netscape.security.x509.GeneralNames;
+
+/**
+ * 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<String> params);
+}
diff --git a/base/common/src/com/netscape/certsrv/policy/IKeyArchivalPolicy.java b/base/common/src/com/netscape/certsrv/policy/IKeyArchivalPolicy.java
new file mode 100644
index 000000000..14a29256f
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/policy/IKeyArchivalPolicy.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.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/base/common/src/com/netscape/certsrv/policy/IKeyRecoveryPolicy.java b/base/common/src/com/netscape/certsrv/policy/IKeyRecoveryPolicy.java
new file mode 100644
index 000000000..6de615673
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/policy/IKeyRecoveryPolicy.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.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/base/common/src/com/netscape/certsrv/policy/IPolicyPredicateParser.java b/base/common/src/com/netscape/certsrv/policy/IPolicyPredicateParser.java
new file mode 100644
index 000000000..0992beaeb
--- /dev/null
+++ b/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/base/common/src/com/netscape/certsrv/policy/IPolicyProcessor.java b/base/common/src/com/netscape/certsrv/policy/IPolicyProcessor.java
new file mode 100644
index 000000000..11927a03f
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/policy/IPolicyProcessor.java
@@ -0,0 +1,196 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.ISubsystem;
+
+/**
+ * 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<String> getPolicyImplsInfo();
+
+ /**
+ * Returns the rule implementations registered with this processor.
+ *
+ * @return An Enumeration of uninitialized IPolicyRule
+ * objects.
+ */
+ Enumeration<IPolicyRule> 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<String> 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<String> getPolicyInstancesInfo();
+
+ /**
+ * Returns policy instances registered with this processor.
+ *
+ * @return An Enumeration of policy instances.
+ */
+ Enumeration<IPolicyRule> 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<String> 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<String, String> 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<String, String> ht)
+ throws EBaseException;
+
+ /**
+ * Modifies policy ordering.
+ *
+ * @param policyOrderStr The comma separated list of instance ids.
+ *
+ */
+ void changePolicyInstanceOrdering(String policyOrderStr)
+ throws EBaseException;
+}
diff --git a/base/common/src/com/netscape/certsrv/policy/IPolicyRule.java b/base/common/src/com/netscape/certsrv/policy/IPolicyRule.java
new file mode 100644
index 000000000..7f7f888f6
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/policy/IPolicyRule.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.policy;
+
+import java.util.Vector;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+
+/**
+ * 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<String> 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<String> 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/base/common/src/com/netscape/certsrv/policy/IPolicySet.java b/base/common/src/com/netscape/certsrv/policy/IPolicySet.java
new file mode 100644
index 000000000..a9fb6a2d2
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/policy/IPolicySet.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.policy;
+
+import java.util.Enumeration;
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+
+/**
+ * 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<IPolicyRule> 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/base/common/src/com/netscape/certsrv/policy/IRenewalPolicy.java b/base/common/src/com/netscape/certsrv/policy/IRenewalPolicy.java
new file mode 100644
index 000000000..28f56fe73
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/policy/IRenewalPolicy.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.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/base/common/src/com/netscape/certsrv/policy/IRevocationPolicy.java b/base/common/src/com/netscape/certsrv/policy/IRevocationPolicy.java
new file mode 100644
index 000000000..7e6084c76
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/policy/IRevocationPolicy.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.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/base/common/src/com/netscape/certsrv/policy/ISubjAltNameConfig.java b/base/common/src/com/netscape/certsrv/policy/ISubjAltNameConfig.java
new file mode 100644
index 000000000..0fee01be2
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/policy/ISubjAltNameConfig.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.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 ISubjAltNameConfig extends IGeneralNameConfig {
+
+ /**
+ * Retrieves configuration prefix.
+ *
+ * @return prefix
+ */
+ public String getPfx();
+
+ /**
+ * Retrieves configuration attribute.
+ *
+ * @return attribute
+ */
+ public String getAttr();
+}
diff --git a/base/common/src/com/netscape/certsrv/policy/PolicyResources.java b/base/common/src/com/netscape/certsrv/policy/PolicyResources.java
new file mode 100644
index 000000000..d330b719f
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/policy/PolicyResources.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.policy;
+
+import java.util.ListResourceBundle;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/profile/CertInfoProfile.java b/base/common/src/com/netscape/certsrv/profile/CertInfoProfile.java
new file mode 100644
index 000000000..5c192e9cd
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/profile/CertInfoProfile.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.profile;
+
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+
+public class CertInfoProfile {
+ private Vector<ICertInfoPolicyDefault> mDefaults = new Vector<ICertInfoPolicyDefault>();
+ 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<ICertInfoPolicyDefault> 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/base/common/src/com/netscape/certsrv/profile/EDeferException.java b/base/common/src/com/netscape/certsrv/profile/EDeferException.java
new file mode 100644
index 000000000..c92630b97
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/profile/EDeferException.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;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8267140233153746034L;
+
+ /**
+ * 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/base/common/src/com/netscape/certsrv/profile/EProfileException.java b/base/common/src/com/netscape/certsrv/profile/EProfileException.java
new file mode 100644
index 000000000..37f968a67
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/profile/EProfileException.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.EBaseException;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4259647804183018757L;
+
+ /**
+ * 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/base/common/src/com/netscape/certsrv/profile/ERejectException.java b/base/common/src/com/netscape/certsrv/profile/ERejectException.java
new file mode 100644
index 000000000..59b35bcdb
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/profile/ERejectException.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.profile;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -542393641391361342L;
+
+ /**
+ * 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/base/common/src/com/netscape/certsrv/profile/ICertInfoPolicyDefault.java b/base/common/src/com/netscape/certsrv/profile/ICertInfoPolicyDefault.java
new file mode 100644
index 000000000..698791296
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/profile/ICertInfoPolicyDefault.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.profile;
+
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.request.IRequest;
+
+public interface ICertInfoPolicyDefault extends IPolicyDefault {
+
+ /**
+ * Populates certificate info directly.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EBaseException;
+}
diff --git a/base/common/src/com/netscape/certsrv/profile/IEnrollProfile.java b/base/common/src/com/netscape/certsrv/profile/IEnrollProfile.java
new file mode 100644
index 000000000..189530f7a
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/profile/IEnrollProfile.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.certsrv.profile;
+
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/profile/IPolicyConstraint.java b/base/common/src/com/netscape/certsrv/profile/IPolicyConstraint.java
new file mode 100644
index 000000000..bf2374652
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/profile/IPolicyConstraint.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.profile;
+
+import java.util.Locale;
+
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.property.IConfigTemplate;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/profile/IPolicyDefault.java b/base/common/src/com/netscape/certsrv/profile/IPolicyDefault.java
new file mode 100644
index 000000000..469d6dded
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/profile/IPolicyDefault.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.Enumeration;
+import java.util.Locale;
+
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IConfigTemplate;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> 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/base/common/src/com/netscape/certsrv/profile/IProfile.java b/base/common/src/com/netscape/certsrv/profile/IProfile.java
new file mode 100644
index 000000000..0cd39c091
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/profile/IProfile.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.certsrv.profile;
+
+import java.util.Enumeration;
+import java.util.Locale;
+
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.cms.profile.common.ProfilePolicy;
+
+/**
+ * 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<String> 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<String> 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<String> 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<String> 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<ProfilePolicy> 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/base/common/src/com/netscape/certsrv/profile/IProfileAuthenticator.java b/base/common/src/com/netscape/certsrv/profile/IProfileAuthenticator.java
new file mode 100644
index 000000000..98546c601
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/profile/IProfileAuthenticator.java
@@ -0,0 +1,120 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Enumeration;
+import java.util.Locale;
+
+import com.netscape.certsrv.authentication.IAuthManager;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> 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/base/common/src/com/netscape/certsrv/profile/IProfileContext.java b/base/common/src/com/netscape/certsrv/profile/IProfileContext.java
new file mode 100644
index 000000000..b3c27d040
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/profile/IProfileContext.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.profile;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/profile/IProfileEx.java b/base/common/src/com/netscape/certsrv/profile/IProfileEx.java
new file mode 100644
index 000000000..79e4f4175
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/profile/IProfileEx.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 com.netscape.certsrv.base.EBaseException;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/profile/IProfileInput.java b/base/common/src/com/netscape/certsrv/profile/IProfileInput.java
new file mode 100644
index 000000000..4ef598698
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/profile/IProfileInput.java
@@ -0,0 +1,120 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Enumeration;
+import java.util.Locale;
+
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IConfigTemplate;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> 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/base/common/src/com/netscape/certsrv/profile/IProfileOutput.java b/base/common/src/com/netscape/certsrv/profile/IProfileOutput.java
new file mode 100644
index 000000000..b60e4475b
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/profile/IProfileOutput.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.profile;
+
+import java.util.Enumeration;
+import java.util.Locale;
+
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IConfigTemplate;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> 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/base/common/src/com/netscape/certsrv/profile/IProfilePolicy.java b/base/common/src/com/netscape/certsrv/profile/IProfilePolicy.java
new file mode 100644
index 000000000..d231f8d55
--- /dev/null
+++ b/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/base/common/src/com/netscape/certsrv/profile/IProfileSubsystem.java b/base/common/src/com/netscape/certsrv/profile/IProfileSubsystem.java
new file mode 100644
index 000000000..b7a68445b
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/profile/IProfileSubsystem.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.certsrv.profile;
+
+import java.util.Enumeration;
+
+import com.netscape.certsrv.base.ISubsystem;
+
+/**
+ * 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<String> getProfileIds();
+
+ /**
+ * Checks if owner id should be enforced during profile approval.
+ *
+ * @return true if approval should be checked
+ */
+ public boolean checkOwner();
+
+}
diff --git a/base/common/src/com/netscape/certsrv/profile/IProfileUpdater.java b/base/common/src/com/netscape/certsrv/profile/IProfileUpdater.java
new file mode 100644
index 000000000..3749cd1d2
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/profile/IProfileUpdater.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.profile;
+
+import java.util.Locale;
+
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.property.IConfigTemplate;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/property/Descriptor.java b/base/common/src/com/netscape/certsrv/property/Descriptor.java
new file mode 100644
index 000000000..bd2b56340
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/property/Descriptor.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.certsrv.property;
+
+import java.util.Locale;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/property/EPropertyException.java b/base/common/src/com/netscape/certsrv/property/EPropertyException.java
new file mode 100644
index 000000000..23f59a25f
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/property/EPropertyException.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.property;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * This is the base exception for property handling.
+ *
+ * @version $Revision$, $Date$
+ */
+public class EPropertyException extends EBaseException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6100285768016343010L;
+
+ /**
+ * Constructs property exception
+ *
+ * @param msg exception message
+ */
+ public EPropertyException(String msg) {
+ super(msg);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/property/IConfigTemplate.java b/base/common/src/com/netscape/certsrv/property/IConfigTemplate.java
new file mode 100644
index 000000000..431c90de9
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/property/IConfigTemplate.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.property;
+
+import java.util.Enumeration;
+import java.util.Locale;
+
+/**
+ * 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<String> 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/base/common/src/com/netscape/certsrv/property/IDescriptor.java b/base/common/src/com/netscape/certsrv/property/IDescriptor.java
new file mode 100644
index 000000000..727c1130d
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/property/IDescriptor.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.property;
+
+import java.util.Locale;
+
+/**
+ * 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 ENC_KEYGEN_REQUEST = "enc_keygen_request";
+ public static String ENC_KEYGEN_REQUEST_TYPE = "enc_keygen_request_type";
+ public static String SIGN_KEYGEN_REQUEST = "sign_keygen_request";
+ public static String SIGN_KEYGEN_REQUEST_TYPE = "sign_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/base/common/src/com/netscape/certsrv/property/PropertySet.java b/base/common/src/com/netscape/certsrv/property/PropertySet.java
new file mode 100644
index 000000000..dc839deb1
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/property/PropertySet.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.certsrv.property;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ * A set of properties.
+ */
+public class PropertySet {
+
+ private Hashtable<String, IDescriptor> mProperties = new Hashtable<String, IDescriptor>();
+
+ public PropertySet() {
+ }
+
+ public void add(String name, IDescriptor desc) {
+ mProperties.put(name, desc);
+ }
+
+ public Enumeration<String> 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/base/common/src/com/netscape/certsrv/publish/ECompSyntaxErr.java b/base/common/src/com/netscape/certsrv/publish/ECompSyntaxErr.java
new file mode 100644
index 000000000..a3a109900
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/ECompSyntaxErr.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 com.netscape.certsrv.ldap.ELdapException;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2224290038321971845L;
+
+ /**
+ * Construct a ECompSyntaxErr
+ *
+ * @param errorString The descriptive error condition.
+ */
+
+ public ECompSyntaxErr(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/publish/EMapperNotFound.java b/base/common/src/com/netscape/certsrv/publish/EMapperNotFound.java
new file mode 100644
index 000000000..fdf4a1b9f
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/EMapperNotFound.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.ELdapException;
+
+/**
+ * Exception for Publish Mapper not found.
+ *
+ * @version $Revision$ $Date$
+ */
+public class EMapperNotFound extends ELdapException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2222814261042222152L;
+
+ /**
+ * Constructs a exception for a missing required mapper
+ *
+ * @param errorString Detailed error message.
+ */
+ public EMapperNotFound(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/publish/EMapperPluginNotFound.java b/base/common/src/com/netscape/certsrv/publish/EMapperPluginNotFound.java
new file mode 100644
index 000000000..f8f18c5ff
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/EMapperPluginNotFound.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.ELdapException;
+
+/**
+ * Exception for Mapper Plugin not found.
+ *
+ * @version $Revision$ $Date$
+ */
+public class EMapperPluginNotFound extends ELdapException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3564854656103487939L;
+
+ /**
+ * Constructs a exception for a missing mapper plugin
+ *
+ * @param errorString Detailed error message.
+ */
+ public EMapperPluginNotFound(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/publish/EPublisherNotFound.java b/base/common/src/com/netscape/certsrv/publish/EPublisherNotFound.java
new file mode 100644
index 000000000..176001e99
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/EPublisherNotFound.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.ELdapException;
+
+/**
+ * Exception for Publisher not found. Required for successful publishing.
+ *
+ * @version $Revision$ $Date$
+ */
+public class EPublisherNotFound extends ELdapException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6159885167931517580L;
+
+ /**
+ * Constructs a exception for a missing required publisher.
+ *
+ * @param errorString Detailed error message.
+ */
+ public EPublisherNotFound(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/publish/EPublisherPluginNotFound.java b/base/common/src/com/netscape/certsrv/publish/EPublisherPluginNotFound.java
new file mode 100644
index 000000000..56076863a
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/EPublisherPluginNotFound.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.ELdapException;
+
+/**
+ * Exception for Publisher Plugin not found. Plugin implementation is required to actually publish.
+ *
+ * @version $Revision$ $Date$
+ */
+public class EPublisherPluginNotFound extends ELdapException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8626436244270286308L;
+
+ /**
+ * Constructs a exception for a missing publisher plugin.
+ *
+ * @param errorString Detailed error message.
+ */
+ public EPublisherPluginNotFound(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/publish/ERuleNotFound.java b/base/common/src/com/netscape/certsrv/publish/ERuleNotFound.java
new file mode 100644
index 000000000..01c9897eb
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/ERuleNotFound.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.ELdapException;
+
+/**
+ * Exception for Ldap Publishing Rule not found.
+ *
+ * @version $Revision$ $Date$
+ */
+public class ERuleNotFound extends ELdapException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8442034769483263745L;
+
+ /**
+ * 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/base/common/src/com/netscape/certsrv/publish/ERulePluginNotFound.java b/base/common/src/com/netscape/certsrv/publish/ERulePluginNotFound.java
new file mode 100644
index 000000000..f619e7f4a
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/ERulePluginNotFound.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.ELdapException;
+
+/**
+ * Exception for Publisher Rule plugin not found. Plugin required to implement Ldap Rule.
+ *
+ * @version $Revision$ $Date$
+ */
+public class ERulePluginNotFound extends ELdapException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4056965992924762809L;
+
+ /**
+ * Constructs a exception for a missing rule plugin.
+ *
+ * @param errorString Detailed error message.
+ */
+ public ERulePluginNotFound(String errorString) {
+ super(errorString);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/publish/ICRLPublisher.java b/base/common/src/com/netscape/certsrv/publish/ICRLPublisher.java
new file mode 100644
index 000000000..cd5763cdb
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/ICRLPublisher.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.publish;
+
+import netscape.security.x509.X509CRLImpl;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/publish/ILdapCertMapper.java b/base/common/src/com/netscape/certsrv/publish/ILdapCertMapper.java
new file mode 100644
index 000000000..3acaeb580
--- /dev/null
+++ b/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 java.security.cert.X509Certificate;
+import java.util.Vector;
+
+import netscape.ldap.LDAPConnection;
+
+import com.netscape.certsrv.ldap.ELdapException;
+
+/**
+ * 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<String> getDefaultParams();
+
+ /**
+ * Returns the instance parameters.
+ */
+ public Vector<String> 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/base/common/src/com/netscape/certsrv/publish/ILdapCrlMapper.java b/base/common/src/com/netscape/certsrv/publish/ILdapCrlMapper.java
new file mode 100644
index 000000000..252a09ec3
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/ILdapCrlMapper.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.publish;
+
+import netscape.ldap.LDAPConnection;
+import netscape.security.x509.X509CRLImpl;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ldap.ELdapException;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/publish/ILdapExpression.java b/base/common/src/com/netscape/certsrv/publish/ILdapExpression.java
new file mode 100644
index 000000000..4537636c1
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/ILdapExpression.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.publish;
+
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/publish/ILdapMapper.java b/base/common/src/com/netscape/certsrv/publish/ILdapMapper.java
new file mode 100644
index 000000000..09238421f
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/ILdapMapper.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.publish;
+
+import java.util.Vector;
+
+import netscape.ldap.LDAPConnection;
+
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> getDefaultParams();
+
+ /**
+ * Returns the current instance parameters.
+ */
+ public Vector<String> 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/base/common/src/com/netscape/certsrv/publish/ILdapPlugin.java b/base/common/src/com/netscape/certsrv/publish/ILdapPlugin.java
new file mode 100644
index 000000000..b0a9fe73b
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/ILdapPlugin.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.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ldap.ELdapException;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/publish/ILdapPluginImpl.java b/base/common/src/com/netscape/certsrv/publish/ILdapPluginImpl.java
new file mode 100644
index 000000000..db52a9106
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/ILdapPluginImpl.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.publish;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IPluginImpl;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ldap.ELdapException;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/publish/ILdapPublishModule.java b/base/common/src/com/netscape/certsrv/publish/ILdapPublishModule.java
new file mode 100644
index 000000000..81e5be952
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/ILdapPublishModule.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.publish;
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestListener;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/publish/ILdapPublisher.java b/base/common/src/com/netscape/certsrv/publish/ILdapPublisher.java
new file mode 100644
index 000000000..398d86453
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/ILdapPublisher.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.publish;
+
+import java.util.Vector;
+
+import netscape.ldap.LDAPConnection;
+
+import com.netscape.certsrv.ldap.ELdapException;
+
+/**
+ * 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<String> getInstanceParams();
+
+ /**
+ * Returns the initial default parameters.
+ */
+ public Vector<String> 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/base/common/src/com/netscape/certsrv/publish/ILdapRule.java b/base/common/src/com/netscape/certsrv/publish/ILdapRule.java
new file mode 100644
index 000000000..7bf19b070
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/ILdapRule.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.publish;
+
+import java.util.Vector;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+
+/**
+ * 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<String> getInstanceParams();
+
+ /**
+ * Returns the initial default parameters.
+ */
+ public Vector<String> getDefaultParams();
+
+ /**
+ * Returns true if the rule is enabled, false if it's disabled.
+ */
+ public boolean enabled();
+}
diff --git a/base/common/src/com/netscape/certsrv/publish/IPublishRuleSet.java b/base/common/src/com/netscape/certsrv/publish/IPublishRuleSet.java
new file mode 100644
index 000000000..911d4e132
--- /dev/null
+++ b/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.Enumeration;
+
+import netscape.ldap.LDAPConnection;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<ILdapRule> 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/base/common/src/com/netscape/certsrv/publish/IPublisherProcessor.java b/base/common/src/com/netscape/certsrv/publish/IPublisherProcessor.java
new file mode 100644
index 000000000..3ed985403
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/IPublisherProcessor.java
@@ -0,0 +1,360 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.math.BigInteger;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import netscape.security.x509.X509CRLImpl;
+
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ILdapConnModule;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String, RulePlugin> getRulePlugins();
+
+ /**
+ *
+ * Returns Hashtable of rule instances.
+ */
+
+ public Hashtable<String, ILdapRule> getRuleInsts();
+
+ /**
+ *
+ * Returns Hashtable of mapper plugins.
+ */
+
+ public Hashtable<String, MapperPlugin> getMapperPlugins();
+
+ /**
+ *
+ * Returns Hashtable of publisher plugins.
+ */
+ public Hashtable<String, PublisherPlugin> getPublisherPlugins();
+
+ /**
+ *
+ * Returns Hashtable of rule mapper instances.
+ */
+ public Hashtable<String, MapperProxy> getMapperInsts();
+
+ /**
+ *
+ * Returns Hashtable of rule publisher instances.
+ */
+ public Hashtable<String, PublisherProxy> getPublisherInsts();
+
+ /**
+ *
+ * Returns list of rules based on publishing type.
+ *
+ * @param publishingType Type for which to retrieve rule list.
+ */
+
+ public Enumeration<ILdapRule> 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<ILdapRule> getRules(String publishingType, IRequest req);
+
+ /**
+ *
+ * Returns mapper initial default parameters.
+ *
+ * @param implName name of MapperPlugin.
+ */
+
+ public Vector<String> getMapperDefaultParams(String implName) throws
+ ELdapException;
+
+ /**
+ *
+ * Returns mapper current instance parameters.
+ *
+ * @param insName name of MapperProxy.
+ * @exception ELdapException failed due to Ldap error.
+ */
+
+ public Vector<String> getMapperInstanceParams(String insName) throws
+ ELdapException;
+
+ /**
+ *
+ * Returns publisher initial default parameters.
+ *
+ * @param implName name of PublisherPlugin.
+ * @exception ELdapException failed due to Ldap error.
+ */
+ public Vector<String> 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<String> 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<String> 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<String> 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/base/common/src/com/netscape/certsrv/publish/IXcertPublisherProcessor.java b/base/common/src/com/netscape/certsrv/publish/IXcertPublisherProcessor.java
new file mode 100644
index 000000000..b70a0626d
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/IXcertPublisherProcessor.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.ELdapException;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/publish/LdapCertMapResult.java b/base/common/src/com/netscape/certsrv/publish/LdapCertMapResult.java
new file mode 100644
index 000000000..84a866095
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/LdapCertMapResult.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.publish;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/publish/MapperPlugin.java b/base/common/src/com/netscape/certsrv/publish/MapperPlugin.java
new file mode 100644
index 000000000..b193e1b5f
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/MapperPlugin.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.base.Plugin;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/publish/MapperProxy.java b/base/common/src/com/netscape/certsrv/publish/MapperProxy.java
new file mode 100644
index 000000000..95dc98d9c
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/MapperProxy.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.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/base/common/src/com/netscape/certsrv/publish/PublisherPlugin.java b/base/common/src/com/netscape/certsrv/publish/PublisherPlugin.java
new file mode 100644
index 000000000..5a163b80c
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/PublisherPlugin.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.publish;
+
+import com.netscape.certsrv.base.Plugin;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/publish/PublisherProxy.java b/base/common/src/com/netscape/certsrv/publish/PublisherProxy.java
new file mode 100644
index 000000000..eb71f3e56
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/PublisherProxy.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.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/base/common/src/com/netscape/certsrv/publish/RulePlugin.java b/base/common/src/com/netscape/certsrv/publish/RulePlugin.java
new file mode 100644
index 000000000..b37a24d51
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/publish/RulePlugin.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.publish;
+
+import com.netscape.certsrv.base.Plugin;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/ra/IRAService.java b/base/common/src/com/netscape/certsrv/ra/IRAService.java
new file mode 100644
index 000000000..4bab4745c
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ra/IRAService.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.ra;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.connector.IConnector;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IService;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/ra/IRegistrationAuthority.java b/base/common/src/com/netscape/certsrv/ra/IRegistrationAuthority.java
new file mode 100644
index 000000000..8302e2d23
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ra/IRegistrationAuthority.java
@@ -0,0 +1,170 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.util.Enumeration;
+
+import netscape.security.x509.X500Name;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.policy.IPolicyProcessor;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.request.IRequestListener;
+import com.netscape.certsrv.request.IRequestQueue;
+
+/**
+ * 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.
+ * @deprecated
+ * @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<String> getRequestListenerNames();
+}
diff --git a/base/common/src/com/netscape/certsrv/registry/ERegistryException.java b/base/common/src/com/netscape/certsrv/registry/ERegistryException.java
new file mode 100644
index 000000000..5d2e2c91c
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/registry/ERegistryException.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.registry;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * This represents a registry exception.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ERegistryException extends EBaseException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8977050444820190765L;
+
+ /**
+ * Constructs a registry exception.
+ *
+ * @param msg message carried along with the exception
+ */
+ public ERegistryException(String msg) {
+ super(msg);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/registry/IPluginInfo.java b/base/common/src/com/netscape/certsrv/registry/IPluginInfo.java
new file mode 100644
index 000000000..8e6a87365
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/registry/IPluginInfo.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.registry;
+
+import java.util.Locale;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/registry/IPluginRegistry.java b/base/common/src/com/netscape/certsrv/registry/IPluginRegistry.java
new file mode 100644
index 000000000..1c85aeba9
--- /dev/null
+++ b/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.Enumeration;
+
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+
+/**
+ * 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<String> getTypeNames();
+
+ /**
+ * Returns a list of plugin identifiers of the given type.
+ *
+ * @param type plugin type
+ * @return a list of plugin IDs
+ */
+ public Enumeration<String> 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/base/common/src/com/netscape/certsrv/request/ARequestNotifier.java b/base/common/src/com/netscape/certsrv/request/ARequestNotifier.java
new file mode 100644
index 000000000..a50996f2b
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/request/ARequestNotifier.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.request;
+
+import java.math.BigInteger;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.ldap.ILdapConnModule;
+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<String, IRequestListener> mListeners = new Hashtable<String, IRequestListener>();
+ private Vector<Thread> mNotifierThreads = new Vector<Thread>();
+ private Vector<String> mRequests = new Vector<String>();
+ 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<String> 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<IRequestListener> 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<IRequestListener> 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<IRequestListener> mListeners = null;
+ IRequestNotifier mRequestNotifier = null;
+
+ /**
+ * RunListeners class constructor.
+ *
+ * @param r request
+ * @param listeners list of listeners
+ */
+ public RunListeners(IRequest r, Enumeration<IRequestListener> 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/base/common/src/com/netscape/certsrv/request/AgentApproval.java b/base/common/src/com/netscape/certsrv/request/AgentApproval.java
new file mode 100644
index 000000000..eb3ca06a8
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/request/AgentApproval.java
@@ -0,0 +1,66 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3444654917454805225L;
+
+ /**
+ * 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/base/common/src/com/netscape/certsrv/request/AgentApprovals.java b/base/common/src/com/netscape/certsrv/request/AgentApprovals.java
new file mode 100644
index 000000000..d6fa41b8f
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/request/AgentApprovals.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.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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3827259076159153561L;
+
+ /**
+ * 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 = 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<AgentApproval> 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<String> toStringVector() {
+ Vector<String> retval = new Vector<String>(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<String> stringVector) {
+ if (stringVector == null) {
+ return null;
+ }
+ AgentApprovals approvals = new AgentApprovals();
+ for (int i = 0; i < stringVector.size(); i++) {
+ try {
+ String approvalString = 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<AgentApproval> mVector = new Vector<AgentApproval>();
+}
diff --git a/base/common/src/com/netscape/certsrv/request/IEnrollmentRequest.java b/base/common/src/com/netscape/certsrv/request/IEnrollmentRequest.java
new file mode 100644
index 000000000..32c3f53a9
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/request/IEnrollmentRequest.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.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/base/common/src/com/netscape/certsrv/request/INotify.java b/base/common/src/com/netscape/certsrv/request/INotify.java
new file mode 100644
index 000000000..938cd855b
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/request/INotify.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.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/base/common/src/com/netscape/certsrv/request/IPolicy.java b/base/common/src/com/netscape/certsrv/request/IPolicy.java
new file mode 100644
index 000000000..9998abee7
--- /dev/null
+++ b/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/base/common/src/com/netscape/certsrv/request/IRequest.java b/base/common/src/com/netscape/certsrv/request/IRequest.java
new file mode 100644
index 000000000..e43856e2d
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/request/IRequest.java
@@ -0,0 +1,764 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.math.BigInteger;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.IAttrSet;
+
+/**
+ * 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";
+
+ //Security Data request attributes
+ public static final String SECURITY_DATA_ENROLLMENT_REQUEST = "securityDataEnrollment";
+ public static final String SECURITY_DATA_RECOVERY_REQUEST = "securityDataRecovery";
+ public static final String SECURITY_DATA_CLIENT_ID = "clientID";
+ public static final String SECURITY_DATA_TYPE = "dataType";
+ public static final String SECURITY_DATA_STATUS = "status";
+ public static final String SECURITY_DATA_TRANS_SESS_KEY = "transWrappedSessionKey";
+ public static final String SECURITY_DATA_SESS_PASS_PHRASE = "sessionWrappedPassphrase";
+ public static final String SECURITY_DATA_IV_STRING_IN = "iv_in";
+ public static final String SECURITY_DATA_IV_STRING_OUT = "iv_out";
+ public static final String SECURITY_DATA_SESS_WRAPPED_DATA = "sessWrappedSecData";
+ public static final String SECURITY_DATA_PASS_WRAPPED_DATA = "passPhraseWrappedData";
+
+
+ // 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<String, String> 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<String, String> getExtDataInHashtable(String key);
+
+ /**
+ * Returns all the keys stored in ExtData
+ *
+ * @return Enumeration of all the keys.
+ */
+ public Enumeration<String> 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<String> 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/base/common/src/com/netscape/certsrv/request/IRequestList.java b/base/common/src/com/netscape/certsrv/request/IRequestList.java
new file mode 100644
index 000000000..5f265941a
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/request/IRequestList.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;
+
+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<RequestId> {
+
+ /**
+ * 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/base/common/src/com/netscape/certsrv/request/IRequestListener.java b/base/common/src/com/netscape/certsrv/request/IRequestListener.java
new file mode 100644
index 000000000..8dc8a42a9
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/request/IRequestListener.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.request;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/request/IRequestNotifier.java b/base/common/src/com/netscape/certsrv/request/IRequestNotifier.java
new file mode 100644
index 000000000..66bd35432
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/request/IRequestNotifier.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.request;
+
+import java.util.Enumeration;
+
+/**
+ * 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<String> 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<IRequestListener> 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/base/common/src/com/netscape/certsrv/request/IRequestQueue.java b/base/common/src/com/netscape/certsrv/request/IRequestQueue.java
new file mode 100644
index 000000000..a8f5f7332
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/request/IRequestQueue.java
@@ -0,0 +1,403 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.BigInteger;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.repository.IRepository;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/request/IRequestRecord.java b/base/common/src/com/netscape/certsrv/request/IRequestRecord.java
new file mode 100644
index 000000000..53531b133
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/request/IRequestRecord.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.request;
+
+import java.util.Enumeration;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBObj;
+
+/**
+ * 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<String> 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<String> getElements();
+
+ // IDBObj.getSerializableAttrNames
+ //public Enumeration getSerializableAttrNames();
+
+}
diff --git a/base/common/src/com/netscape/certsrv/request/IRequestScheduler.java b/base/common/src/com/netscape/certsrv/request/IRequestScheduler.java
new file mode 100644
index 000000000..5012f5b0c
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/request/IRequestScheduler.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.request;
+
+//import java.io.Serializable;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/request/IRequestSubsystem.java b/base/common/src/com/netscape/certsrv/request/IRequestSubsystem.java
new file mode 100644
index 000000000..164e84a37
--- /dev/null
+++ b/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/base/common/src/com/netscape/certsrv/request/IRequestVirtualList.java b/base/common/src/com/netscape/certsrv/request/IRequestVirtualList.java
new file mode 100644
index 000000000..540ec679c
--- /dev/null
+++ b/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/base/common/src/com/netscape/certsrv/request/IService.java b/base/common/src/com/netscape/certsrv/request/IService.java
new file mode 100644
index 000000000..adf2c5095
--- /dev/null
+++ b/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/base/common/src/com/netscape/certsrv/request/PolicyMessage.java b/base/common/src/com/netscape/certsrv/request/PolicyMessage.java
new file mode 100644
index 000000000..c21b8ca4d
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/request/PolicyMessage.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.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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8129371562473386912L;
+
+ /**
+ * Class constructor that registers policy message.
+ * <p>
+ *
+ * @param message message string
+ */
+ public PolicyMessage(String message) {
+ super(message);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/request/PolicyResult.java b/base/common/src/com/netscape/certsrv/request/PolicyResult.java
new file mode 100644
index 000000000..c7cad94f2
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/request/PolicyResult.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.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/base/common/src/com/netscape/certsrv/request/RequestId.java b/base/common/src/com/netscape/certsrv/request/RequestId.java
new file mode 100644
index 000000000..da61f2bc0
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/request/RequestId.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.request;
+
+import java.math.BigInteger;
+
+/**
+ * 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 class RequestId {
+
+ protected BigInteger value;
+
+ /**
+ * Creates a new RequestId from its string representation.
+ * <p>
+ *
+ * @param id
+ * a string containing the decimal or hex value for the identifier.
+ */
+ public RequestId(String id) {
+ if (id != null) {
+ id = id.trim();
+ if (id.startsWith("0x")) { // hex
+ value = new BigInteger(id.substring(2), 16);
+ } else { // decimal
+ value = new BigInteger(id);
+ }
+ }
+ }
+
+ /**
+ * Creates a new RequestId from its BigInteger representation.
+ * <p>
+ *
+ * @param id
+ * a BigInteger containing the identifier.
+ */
+ public RequestId(BigInteger id) {
+ value = id;
+ }
+
+ /**
+ * Creates a new RequestId from its integer representation.
+ * <p>
+ *
+ * @param id
+ * an integer containing the identifier.
+ */
+ public RequestId(int id) {
+ value = BigInteger.valueOf(id);
+ }
+
+ /**
+ * Converts the RequestId into its BigInteger representation.
+ * <p>
+ *
+ * @return
+ * a BigInteger containing the identifier.
+ */
+ public BigInteger toBigInteger() {
+ return value;
+ }
+
+ /**
+ * 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 value.toString();
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((value == null) ? 0 : value.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ RequestId other = (RequestId) obj;
+ if (value == null) {
+ if (other.value != null)
+ return false;
+ } else if (!value.equals(other.value))
+ return false;
+ return true;
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/request/RequestIdAdapter.java b/base/common/src/com/netscape/certsrv/request/RequestIdAdapter.java
new file mode 100644
index 000000000..1780bc337
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/request/RequestIdAdapter.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.request;
+
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+
+/**
+ * The RequestIdAdapter class provides custom marshaling for RequestId.
+ *
+ * @author Endi S. Dewata
+ * @version $Revision$ $Date$
+ */
+public class RequestIdAdapter extends XmlAdapter<String, RequestId> {
+
+ public RequestId unmarshal(String value) throws Exception {
+ return new RequestId(value);
+ }
+
+ public String marshal(RequestId value) throws Exception {
+ return value.toString();
+ }
+} \ No newline at end of file
diff --git a/base/common/src/com/netscape/certsrv/request/RequestStatus.java b/base/common/src/com/netscape/certsrv/request/RequestStatus.java
new file mode 100644
index 000000000..f58a568d8
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/request/RequestStatus.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.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/base/common/src/com/netscape/certsrv/request/ldap/IRequestMod.java b/base/common/src/com/netscape/certsrv/request/ldap/IRequestMod.java
new file mode 100644
index 000000000..c1e153a81
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/request/ldap/IRequestMod.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.ldap;
+
+import java.util.Date;
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/security/Credential.java b/base/common/src/com/netscape/certsrv/security/Credential.java
new file mode 100644
index 000000000..48038a40b
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/security/Credential.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.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 static final long serialVersionUID = -7810193228062824943L;
+ 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/base/common/src/com/netscape/certsrv/security/ICryptoSubsystem.java b/base/common/src/com/netscape/certsrv/security/ICryptoSubsystem.java
new file mode 100644
index 000000000..3d26d6f3a
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/security/ICryptoSubsystem.java
@@ -0,0 +1,472 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.io.IOException;
+import java.security.KeyPair;
+import java.security.cert.CertificateException;
+import java.util.Locale;
+
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.X509CertImpl;
+
+import org.mozilla.jss.CryptoManager.NotInitializedException;
+import org.mozilla.jss.crypto.ObjectNotFoundException;
+import org.mozilla.jss.crypto.PQGParams;
+import org.mozilla.jss.crypto.TokenException;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.common.NameValuePairs;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/security/IEncryptionUnit.java b/base/common/src/com/netscape/certsrv/security/IEncryptionUnit.java
new file mode 100644
index 000000000..0a526e582
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/security/IEncryptionUnit.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.security;
+
+import java.security.PublicKey;
+
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.crypto.SymmetricKey;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * 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;
+
+ /**
+ * Wraps data. The given key will be wrapped by the
+ * private key in this unit.
+ *
+ * @param symKey symmetric key to be wrapped
+ * @return wrapped data
+ * @exception EBaseException failed to wrap
+ */
+ public byte[] wrap(SymmetricKey symKey) 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 symmetric key data. This method rebuilds the symmetric key by
+ * unwrapping the private data blob.
+ *
+ * @param wrappedKeyData symmetric key data wrapped up with session key
+ * @return Symmetric key object
+ * @exception EBaseException failed to unwrap
+ */
+
+ public SymmetricKey unwrap(byte wrappedKeyData[])
+ throws EBaseException;
+
+ /**
+ * Unwraps symmetric key . This method
+ * unwraps the symmetric key.
+ *
+ * @param sessionKey session key that unwrap the symmetric key
+ * @param symmAlgOID symmetric algorithm
+ * @param symmAlgParams symmetric algorithm parameters
+ * @param symmetricKey symmetric key data
+ * @return Symmetric key object
+ * @exception EBaseException failed to unwrap
+ */
+
+ public SymmetricKey unwrap_symmetric(byte sessionKey[], String symmAlgOID,
+ byte symmAlgParams[], byte symmetricKey[])
+ throws EBaseException;
+
+ /**
+ * Unwraps symmetric key . This method
+ * unwraps the symmetric key.
+ *
+ * @param encSymmKey wrapped symmetric key to be unwrapped
+ * @return Symmetric key object
+ * @exception EBaseException failed to unwrap
+ */
+
+ public SymmetricKey unwrap_sym(byte encSymmKey[],
+ SymmetricKey.Usage usage);
+
+ /**
+ * 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/base/common/src/com/netscape/certsrv/security/ISigningUnit.java b/base/common/src/com/netscape/certsrv/security/ISigningUnit.java
new file mode 100644
index 000000000..7fbed0b6c
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/security/ISigningUnit.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.security;
+
+import java.security.PublicKey;
+
+import netscape.security.x509.X509CertImpl;
+
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+import org.mozilla.jss.crypto.X509Certificate;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/security/IStorageKeyUnit.java b/base/common/src/com/netscape/certsrv/security/IStorageKeyUnit.java
new file mode 100644
index 000000000..5f3b0ec48
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/security/IStorageKeyUnit.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.certsrv.security;
+
+import java.util.Enumeration;
+
+import org.mozilla.jss.crypto.CryptoToken;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * 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<String> 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/base/common/src/com/netscape/certsrv/security/IToken.java b/base/common/src/com/netscape/certsrv/security/IToken.java
new file mode 100644
index 000000000..05aff64f9
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/security/IToken.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.security;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/security/ITransportKeyUnit.java b/base/common/src/com/netscape/certsrv/security/ITransportKeyUnit.java
new file mode 100644
index 000000000..6e1c7ab4a
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/security/ITransportKeyUnit.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.certsrv.security;
+
+import java.security.PublicKey;
+
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.crypto.SymmetricKey;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * 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();
+
+ /**
+ * Unwraps symmetric key . This method
+ * unwraps the symmetric key.
+ *
+ * @param encSymmKey wrapped symmetric key to be unwrapped
+ * @param usage Key usage for unwrapped key.
+ * @return Symmetric key object
+ * @exception EBaseException failed to unwrap
+ */
+
+ public SymmetricKey unwrap_sym(byte encSymmKey[], SymmetricKey.Usage usage);
+
+ /**
+ * Unwraps symmetric key . This method
+ * unwraps the symmetric key.
+ *
+ * @param encSymmKey wrapped symmetric key to be unwrapped
+ * @return Symmetric key object
+ * @exception EBaseException failed to unwrap
+ */
+
+ public SymmetricKey unwrap_sym(byte encSymmKey[]);
+
+ /**
+ * Unwraps symmetric key for encrypton . This method
+ * unwraps the symmetric key.
+ *
+ * @param encSymmKey wrapped symmetric key to be unwrapped
+ * @return Symmetric key object
+ * @exception EBaseException failed to unwrap
+ */
+
+ public SymmetricKey unwrap_encrypt_sym(byte encSymmKey[]);
+
+ /**
+ * Unwraps temporary private key . This method
+ * unwraps the temporary private key.
+ *
+ * @param wrappedKeyData wrapped private key to be unwrapped
+ * @param pubKey public key
+ * @return Private key object
+ * @exception EBaseException failed to unwrap
+ */
+
+ public PrivateKey unwrap_temp(byte wrappedKeyData[], PublicKey
+ pubKey) throws EBaseException;
+ /**
+ * Returns this Unit's crypto token object.
+ * @return CryptoToken object.
+ */
+
+ public CryptoToken getToken();
+
+ /**
+ * Returns this Unit's signing algorithm in String format.
+ * @return String of signing algorithm
+ * @throws EBaseException
+ */
+
+ public String getSigningAlgorithm() throws EBaseException;
+
+ /**
+ * Sets this Unit's signing algorithm.
+ * @param str String of signing algorithm to set.
+ * @throws EBaseException
+ */
+ public void setSigningAlgorithm(String str) throws EBaseException;
+}
diff --git a/base/common/src/com/netscape/certsrv/security/KeyCertData.java b/base/common/src/com/netscape/certsrv/security/KeyCertData.java
new file mode 100644
index 000000000..dbcc0118f
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/security/KeyCertData.java
@@ -0,0 +1,821 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.math.BigInteger;
+import java.security.KeyPair;
+import java.util.Properties;
+
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateExtensions;
+
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.common.ConfigConstants;
+import com.netscape.certsrv.common.Constants;
+
+/**
+ * This class represents a container for storaging
+ * data in the security package.
+ *
+ * @version $Revision$, $Date$
+ */
+public class KeyCertData extends Properties {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -9084106429445432037L;
+
+ /**
+ * 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/base/common/src/com/netscape/certsrv/selftests/EDuplicateSelfTestException.java b/base/common/src/com/netscape/certsrv/selftests/EDuplicateSelfTestException.java
new file mode 100644
index 000000000..958919e1e
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/selftests/EDuplicateSelfTestException.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 statement //
+///////////////////////
+
+package com.netscape.certsrv.selftests;
+
+///////////////////////
+// import statements //
+///////////////////////
+
+//////////////////////
+// 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 static final long serialVersionUID = -7484729117186395701L;
+ 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/base/common/src/com/netscape/certsrv/selftests/EInvalidSelfTestException.java b/base/common/src/com/netscape/certsrv/selftests/EInvalidSelfTestException.java
new file mode 100644
index 000000000..58592b89b
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/selftests/EInvalidSelfTestException.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 statement //
+///////////////////////
+
+package com.netscape.certsrv.selftests;
+
+///////////////////////
+// import statements //
+///////////////////////
+
+//////////////////////
+// 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 static final long serialVersionUID = 942550656371185199L;
+ 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/base/common/src/com/netscape/certsrv/selftests/EMissingSelfTestException.java b/base/common/src/com/netscape/certsrv/selftests/EMissingSelfTestException.java
new file mode 100644
index 000000000..c15852f4f
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/selftests/EMissingSelfTestException.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 //
+///////////////////////
+
+//////////////////////
+// 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 static final long serialVersionUID = -2969459432517671352L;
+ 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/base/common/src/com/netscape/certsrv/selftests/ESelfTestException.java b/base/common/src/com/netscape/certsrv/selftests/ESelfTestException.java
new file mode 100644
index 000000000..6c4f6bf2f
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/selftests/ESelfTestException.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 statement //
+///////////////////////
+
+package com.netscape.certsrv.selftests;
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import com.netscape.certsrv.base.EBaseException;
+
+//////////////////////
+// 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 long serialVersionUID = -8001373369705595891L;
+ 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/base/common/src/com/netscape/certsrv/selftests/ISelfTest.java b/base/common/src/com/netscape/certsrv/selftests/ISelfTest.java
new file mode 100644
index 000000000..04285a9dc
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/selftests/ISelfTest.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 statement //
+///////////////////////
+
+package com.netscape.certsrv.selftests;
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import java.util.Locale;
+
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.logging.ILogEventListener;
+
+//////////////////////
+// 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/base/common/src/com/netscape/certsrv/selftests/ISelfTestSubsystem.java b/base/common/src/com/netscape/certsrv/selftests/ISelfTestSubsystem.java
new file mode 100644
index 000000000..d16627ab5
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/selftests/ISelfTestSubsystem.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 statement //
+///////////////////////
+
+package com.netscape.certsrv.selftests;
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.logging.ILogEventListener;
+
+//////////////////////
+// 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/base/common/src/com/netscape/certsrv/selftests/SelfTestResources.java b/base/common/src/com/netscape/certsrv/selftests/SelfTestResources.java
new file mode 100644
index 000000000..c7c4d372d
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/selftests/SelfTestResources.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.selftests;
+
+import java.util.ListResourceBundle;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/template/ArgList.java b/base/common/src/com/netscape/certsrv/template/ArgList.java
new file mode 100644
index 000000000..586bf7663
--- /dev/null
+++ b/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.Vector;
+
+/**
+ * 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<IArgValue> mList = new Vector<IArgValue>();
+
+ /**
+ * 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/base/common/src/com/netscape/certsrv/template/ArgSet.java b/base/common/src/com/netscape/certsrv/template/ArgSet.java
new file mode 100644
index 000000000..333a51e50
--- /dev/null
+++ b/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.Enumeration;
+import java.util.Hashtable;
+
+/**
+ * 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<String, IArgValue> mArgs = new Hashtable<String, IArgValue>();
+
+ /**
+ * Returns a list of argument names.
+ *
+ * @return list of argument names
+ */
+ public Enumeration<String> 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/base/common/src/com/netscape/certsrv/template/ArgString.java b/base/common/src/com/netscape/certsrv/template/ArgString.java
new file mode 100644
index 000000000..4fb982eb6
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/template/ArgString.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.template;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/template/IArgValue.java b/base/common/src/com/netscape/certsrv/template/IArgValue.java
new file mode 100644
index 000000000..e820ce69f
--- /dev/null
+++ b/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/base/common/src/com/netscape/certsrv/tks/ITKSAuthority.java b/base/common/src/com/netscape/certsrv/tks/ITKSAuthority.java
new file mode 100644
index 000000000..0a045a6fb
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/tks/ITKSAuthority.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.tks;
+
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.request.IRequestQueue;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/usrgrp/Certificates.java b/base/common/src/com/netscape/certsrv/usrgrp/Certificates.java
new file mode 100644
index 000000000..fdfa3cd38
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/usrgrp/Certificates.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 java.security.cert.X509Certificate;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/usrgrp/EUsrGrpException.java b/base/common/src/com/netscape/certsrv/usrgrp/EUsrGrpException.java
new file mode 100644
index 000000000..a25a1a6b3
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/usrgrp/EUsrGrpException.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.usrgrp;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * A class represents a Identity exception.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class EUsrGrpException extends EBaseException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5549165292376270875L;
+ /**
+ * 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/base/common/src/com/netscape/certsrv/usrgrp/ICertUserLocator.java b/base/common/src/com/netscape/certsrv/usrgrp/ICertUserLocator.java
new file mode 100644
index 000000000..dbbd068c4
--- /dev/null
+++ b/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.LDAPException;
+
+import com.netscape.certsrv.ldap.ELdapException;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/usrgrp/IGroup.java b/base/common/src/com/netscape/certsrv/usrgrp/IGroup.java
new file mode 100644
index 000000000..522d0fc89
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/usrgrp/IGroup.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.usrgrp;
+
+import java.util.Enumeration;
+
+import com.netscape.certsrv.base.IAttrSet;
+
+/**
+ * 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<String> getMemberNames();
+}
diff --git a/base/common/src/com/netscape/certsrv/usrgrp/IGroupConstants.java b/base/common/src/com/netscape/certsrv/usrgrp/IGroupConstants.java
new file mode 100644
index 000000000..22d89455c
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/usrgrp/IGroupConstants.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.usrgrp;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/usrgrp/IIdEvaluator.java b/base/common/src/com/netscape/certsrv/usrgrp/IIdEvaluator.java
new file mode 100644
index 000000000..41209b4b9
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/usrgrp/IIdEvaluator.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.usrgrp;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/usrgrp/IUGSubsystem.java b/base/common/src/com/netscape/certsrv/usrgrp/IUGSubsystem.java
new file mode 100644
index 000000000..282d672f1
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/usrgrp/IUGSubsystem.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.certsrv.usrgrp;
+
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+
+import netscape.ldap.LDAPException;
+
+import com.netscape.certsrv.base.ISubsystem;
+
+/**
+ * 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<IUser> 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;
+
+ /**
+ * Add a certSubjectDN field to the user
+ * @param identity
+ * @throws EUsrGrpException
+ * @throws LDAPException
+ */
+ public void addCertSubjectDN(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<IGroup> 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<IGroup> 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/base/common/src/com/netscape/certsrv/usrgrp/IUser.java b/base/common/src/com/netscape/certsrv/usrgrp/IUser.java
new file mode 100644
index 000000000..9370a6718
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/usrgrp/IUser.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.usrgrp;
+
+import java.security.cert.X509Certificate;
+
+import com.netscape.certsrv.base.IAttrSet;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/usrgrp/IUserConstants.java b/base/common/src/com/netscape/certsrv/usrgrp/IUserConstants.java
new file mode 100644
index 000000000..f66f01c73
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/usrgrp/IUserConstants.java
@@ -0,0 +1,66 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/usrgrp/IUsrGrp.java b/base/common/src/com/netscape/certsrv/usrgrp/IUsrGrp.java
new file mode 100644
index 000000000..f6cef0d46
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/usrgrp/IUsrGrp.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.usrgrp;
+
+import netscape.ldap.LDAPException;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/usrgrp/UsrGrpResources.java b/base/common/src/com/netscape/certsrv/usrgrp/UsrGrpResources.java
new file mode 100644
index 000000000..11a3da23b
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/usrgrp/UsrGrpResources.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.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/base/common/src/com/netscape/certsrv/util/HttpInput.java b/base/common/src/com/netscape/certsrv/util/HttpInput.java
new file mode 100644
index 000000000..7e7fe7c4a
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/util/HttpInput.java
@@ -0,0 +1,258 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.io.IOException;
+import java.net.URL;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.servlet.http.HttpServletRequest;
+
+import netscape.ldap.LDAPDN;
+
+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) {
+ 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) {
+ return getString(request, name);
+ }
+
+ public static String getURL(HttpServletRequest request, String name)
+ throws IOException {
+ String v = getString(request, name);
+ try {
+ new URL(v); // throw exception on error
+ } catch (Exception e) {
+ throw new IOException("Invalid URL " + v);
+ }
+ return v;
+ }
+
+ public static String getUID(HttpServletRequest request, String name) {
+ return getString(request, name);
+ }
+
+ public static String getPassword(HttpServletRequest request, String name) {
+ 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) {
+ return getString(request, name);
+ }
+
+ public static String getName(HttpServletRequest request, String name) {
+ return getString(request, name);
+ }
+
+ public static String getCertRequest(HttpServletRequest request, String name) {
+ return getString(request, name);
+ }
+
+ public static String getCertChain(HttpServletRequest request, String name) {
+ return getString(request, name);
+ }
+
+ public static String getCert(HttpServletRequest request, String name) {
+ return getString(request, name);
+ }
+
+ public static String getNickname(HttpServletRequest request, String name) {
+ return getString(request, name);
+ }
+
+ public static String getHostname(HttpServletRequest request, String name) {
+ return getString(request, name);
+ }
+
+ public static String getTokenName(HttpServletRequest request, String name) {
+ return getString(request, name);
+ }
+
+ public static String getReplicationAgreementName(HttpServletRequest request, String name) {
+ 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) {
+ 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/base/common/src/com/netscape/certsrv/util/IStatsSubsystem.java b/base/common/src/com/netscape/certsrv/util/IStatsSubsystem.java
new file mode 100644
index 000000000..989d7a4a1
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/util/IStatsSubsystem.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.util;
+
+import java.util.Date;
+
+import com.netscape.certsrv.base.ISubsystem;
+
+/**
+ * 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/base/common/src/com/netscape/certsrv/util/StatsEvent.java b/base/common/src/com/netscape/certsrv/util/StatsEvent.java
new file mode 100644
index 000000000..eafd90d05
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/util/StatsEvent.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.util;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+/**
+ * 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<StatsEvent> mSubEvents = new Vector<StatsEvent>();
+ 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<String> getSubEventNames() {
+ Vector<String> names = new Vector<String>();
+ Enumeration<StatsEvent> e = mSubEvents.elements();
+ while (e.hasMoreElements()) {
+ StatsEvent st = e.nextElement();
+ names.addElement(st.getName());
+ }
+ return names.elements();
+ }
+
+ /**
+ * Retrieves a sub transaction.
+ */
+ public StatsEvent getSubEvent(String name) {
+ Enumeration<StatsEvent> e = mSubEvents.elements();
+ while (e.hasMoreElements()) {
+ StatsEvent st = 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<String> e = getSubEventNames();
+ while (e.hasMoreElements()) {
+ String n = 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/base/common/src/com/netscape/cms/authentication/AVAPattern.java b/base/common/src/com/netscape/cms/authentication/AVAPattern.java
new file mode 100644
index 000000000..6a8bbcbf2
--- /dev/null
+++ b/base/common/src/com/netscape/cms/authentication/AVAPattern.java
@@ -0,0 +1,559 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.io.PushbackReader;
+import java.io.StringReader;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPDN;
+import netscape.ldap.LDAPEntry;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.AVA;
+import netscape.security.x509.LdapV3DNStrConverter;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.EAuthException;
+import com.netscape.certsrv.authentication.ECompSyntaxErr;
+
+/**
+ * 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;
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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<String> avas = new Vector<String>();
+ 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/base/common/src/com/netscape/cms/authentication/AgentCertAuthentication.java b/base/common/src/com/netscape/cms/authentication/AgentCertAuthentication.java
new file mode 100644
index 000000000..65ef434a9
--- /dev/null
+++ b/base/common/src/com/netscape/cms/authentication/AgentCertAuthentication.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.authentication;
+
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+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.authentication.ISSLClientCertProvider;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileAuthenticator;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.usrgrp.Certificates;
+import com.netscape.certsrv.usrgrp.EUsrGrpException;
+import com.netscape.certsrv.usrgrp.ICertUserLocator;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.certsrv.usrgrp.IUser;
+
+/**
+ * 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<String> 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/base/common/src/com/netscape/cms/authentication/CMCAuth.java b/base/common/src/com/netscape/cms/authentication/CMCAuth.java
new file mode 100644
index 000000000..06d4eaa0f
--- /dev/null
+++ b/base/common/src/com/netscape/cms/authentication/CMCAuth.java
@@ -0,0 +1,1038 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software 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 java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.PublicKey;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.pkcs.PKCS10;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.crypto.DigestAlgorithm;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.pkcs10.CertificationRequest;
+import org.mozilla.jss.pkcs11.PK11PubKey;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.pkix.cert.CertificateInfo;
+import org.mozilla.jss.pkix.cmc.PKIData;
+import org.mozilla.jss.pkix.cmc.TaggedAttribute;
+import org.mozilla.jss.pkix.cmc.TaggedCertificationRequest;
+import org.mozilla.jss.pkix.cmc.TaggedRequest;
+import org.mozilla.jss.pkix.cms.EncapsulatedContentInfo;
+import org.mozilla.jss.pkix.cms.IssuerAndSerialNumber;
+import org.mozilla.jss.pkix.cms.SignedData;
+import org.mozilla.jss.pkix.cms.SignerIdentifier;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.crmf.CertTemplate;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.pkix.primitive.Name;
+
+import com.netscape.certsrv.apps.CMS;
+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.IAuthSubsystem;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileAuthenticator;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cmsutil.util.Utils;
+
+//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<String> 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<String>();
+
+ 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();
+
+ 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<String, byte[]> digs = new Hashtable<String, byte[]>();
+
+ //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
+
+ // find from certDB
+ si.verify(digest, id);
+
+ } //
+ }
+ } 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<String> getValueNames() {
+ Vector<String> v = new Vector<String>();
+ 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/base/common/src/com/netscape/cms/authentication/Crypt.java b/base/common/src/com/netscape/cms/authentication/Crypt.java
new file mode 100644
index 000000000..e6dd7087d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/authentication/Crypt.java
@@ -0,0 +1,438 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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/base/common/src/com/netscape/cms/authentication/DNPattern.java b/base/common/src/com/netscape/cms/authentication/DNPattern.java
new file mode 100644
index 000000000..480b5b909
--- /dev/null
+++ b/base/common/src/com/netscape/cms/authentication/DNPattern.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.authentication;
+
+import java.io.IOException;
+import java.io.PushbackReader;
+import java.io.StringReader;
+import java.util.Vector;
+
+import netscape.ldap.LDAPEntry;
+
+import com.netscape.certsrv.authentication.EAuthException;
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * 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<RDNPattern> rdnPatterns = new Vector<RDNPattern>();
+ 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<String> ldapAttrs = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/authentication/DirBasedAuthentication.java b/base/common/src/com/netscape/cms/authentication/DirBasedAuthentication.java
new file mode 100644
index 000000000..da8d5bd51
--- /dev/null
+++ b/base/common/src/com/netscape/cms/authentication/DirBasedAuthentication.java
@@ -0,0 +1,676 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.security.cert.CertificateException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.EAuthException;
+import com.netscape.certsrv.authentication.EFormSubjectDN;
+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.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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<String> mExtendedPluginInfo = null;
+
+ static {
+ mExtendedPluginInfo = new Vector<String>();
+ 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<String> v = new Vector<String>();
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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<byte[]> v = new Vector<byte[]>();
+ @SuppressWarnings("unchecked")
+ Enumeration<byte[]> 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/base/common/src/com/netscape/cms/authentication/FlatFileAuth.java b/base/common/src/com/netscape/cms/authentication/FlatFileAuth.java
new file mode 100644
index 000000000..f60110b0b
--- /dev/null
+++ b/base/common/src/com/netscape/cms/authentication/FlatFileAuth.java
@@ -0,0 +1,686 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import com.netscape.certsrv.apps.CMS;
+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.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;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileAuthenticator;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String, Hashtable<String, String>> 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<String, String> ht = new Hashtable<String, String>();
+
+ 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<String> e = ht.keys();
+
+ for (int i = 0; e.hasMoreElements(); i++) {
+ s[i] = 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<String, Hashtable<String, String>> 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<String, Hashtable<String, String>> allusers = new Hashtable<String, Hashtable<String, String>>();
+ Hashtable<String, String> 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<String, String>();
+ }
+
+ 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<String, Hashtable<String, String>> allUsers,
+ Hashtable<String, String> entry,
+ String[] keys) {
+ if (entry == null) {
+ return;
+ }
+ String key = "";
+
+ print("keys.length = " + keys.length);
+ for (int i = 0; i < keys.length; i++) {
+ String s = 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<String> e = entries.keys();
+
+ while (e.hasMoreElements()) {
+ String key = e.nextElement();
+
+ print("* " + key + " *");
+ Hashtable<String, String> ht = entries.get(key);
+ Enumeration<String> f = ht.keys();
+
+ while (f.hasMoreElements()) {
+ String fkey = f.nextElement();
+
+ print(" " + fkey + " -> " + ht.get(fkey));
+ }
+ }
+ }
+
+ /**
+ * Compare attributes provided by the user with those in
+ * in flat file.
+ *
+ */
+
+ private IAuthToken doAuthentication(Hashtable<String, String> 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<String, String> user = 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<String> 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/base/common/src/com/netscape/cms/authentication/HashAuthData.java b/base/common/src/com/netscape/cms/authentication/HashAuthData.java
new file mode 100644
index 000000000..3a447d282
--- /dev/null
+++ b/base/common/src/com/netscape/cms/authentication/HashAuthData.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.authentication;
+
+// java sdk imports.
+import java.util.Hashtable;
+import java.util.Vector;
+
+/**
+ * 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<String, Vector<Object>> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -988354133432275910L;
+ public static final long TIMEOUT = 600000;
+ public static final long LASTLOGIN = 0;
+
+ public HashAuthData() {
+ }
+
+ public String getAgentName(String hostname) {
+ Vector<Object> val = get(hostname);
+
+ if (val != null)
+ return (String) val.elementAt(0);
+ return null;
+ }
+
+ public void setAgentName(String hostname, String agentName) {
+ Vector<Object> val = get(hostname);
+
+ if (val == null) {
+ val = new Vector<Object>();
+ put(hostname, val);
+ }
+ val.setElementAt(agentName, 0);
+ }
+
+ public long getTimeout(String hostname) {
+ Vector<Object> val = get(hostname);
+
+ if (val != null) {
+ return ((Long) val.elementAt(1)).longValue();
+ }
+ return TIMEOUT;
+ }
+
+ public void setTimeout(String hostname, long timeout) {
+ Vector<Object> val = get(hostname);
+
+ if (val == null) {
+ val = new Vector<Object>();
+ put(hostname, val);
+ }
+ val.setElementAt(Long.valueOf(timeout), 1);
+ }
+
+ public String getSecret(String hostname) {
+ Vector<Object> val = get(hostname);
+
+ if (val != null) {
+ return (String) val.elementAt(2);
+ }
+ return null;
+ }
+
+ public void setSecret(String hostname, String secret) {
+ Vector<Object> val = get(hostname);
+
+ if (val == null) {
+ val = new Vector<Object>();
+ put(hostname, val);
+ }
+ val.setElementAt(secret, 2);
+ }
+
+ public long getLastLogin(String hostname) {
+ Vector<Object> val = get(hostname);
+
+ if (val != null) {
+ return ((Long) val.elementAt(3)).longValue();
+ }
+ return LASTLOGIN;
+ }
+
+ public void setLastLogin(String hostname, long lastLogin) {
+ Vector<Object> val = get(hostname);
+
+ if (val == null) {
+ val = new Vector<Object>();
+ put(hostname, val);
+ }
+ val.setElementAt(Long.valueOf(lastLogin), 3);
+ }
+}
diff --git a/base/common/src/com/netscape/cms/authentication/HashAuthentication.java b/base/common/src/com/netscape/cms/authentication/HashAuthentication.java
new file mode 100644
index 000000000..2537efa10
--- /dev/null
+++ b/base/common/src/com/netscape/cms/authentication/HashAuthentication.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.authentication;
+
+// ldap java sdk
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.EAuthException;
+import com.netscape.certsrv.authentication.EInvalidCredentials;
+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.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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<String, IAuthToken> mData = null;
+ private IConfigStore mConfig;
+ private String mName = null;
+ private String mImplName = null;
+ private ILogger mLogger = CMS.getLogger();
+ private static Vector<String> mExtendedPluginInfo = null;
+ private HashAuthData mHosts = null;
+
+ static String[] mConfigParams =
+ new String[] {};
+
+ static {
+ mExtendedPluginInfo = new Vector<String>();
+ 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<String, IAuthToken>();
+ 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 mData.remove(key);
+ }
+
+ public void addAuthToken(String pageID, IAuthToken token) {
+ mData.put(pageID, token);
+ }
+
+ public void deleteToken(String pageID) {
+ mData.remove(pageID);
+ }
+
+ public HashAuthData getData() {
+ return mHosts;
+ }
+
+ public void createEntry(String host, String dn, long timeout,
+ String secret, long lastLogin) {
+ Vector<Object> v = new Vector<Object>();
+
+ 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<String> 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 = Utils.base64encode(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/base/common/src/com/netscape/cms/authentication/PortalEnroll.java b/base/common/src/com/netscape/cms/authentication/PortalEnroll.java
new file mode 100644
index 000000000..38a3e6fcf
--- /dev/null
+++ b/base/common/src/com/netscape/cms/authentication/PortalEnroll.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.authentication;
+
+// ldap java sdk
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPObjectClassSchema;
+import netscape.ldap.LDAPSchema;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.EAuthInternalError;
+import com.netscape.certsrv.authentication.EAuthUserError;
+import com.netscape.certsrv.authentication.EInvalidCredentials;
+import com.netscape.certsrv.authentication.EMissingCredential;
+import com.netscape.certsrv.authentication.IAuthCredentials;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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<Enumeration<String>> mRequiredAttrs = null;
+
+ // contains all nested superiors' optional attrs in the form of a
+ // vector of "optional" attributes in Enumeration
+ Vector<Enumeration<String>> mOptionalAttrs = null;
+
+ // contains all the objclasses, including superiors and itself
+ Vector<String> 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()) {
+ res.nextElement(); // consume the entry
+
+ 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<String> objectclass_values = null;
+
+ LDAPAttributeSet attrs = new LDAPAttributeSet();
+ LDAPAttribute attr = new LDAPAttribute("objectclass");
+
+ // initialized to new
+ mRequiredAttrs = new Vector<Enumeration<String>>();
+ mOptionalAttrs = new Vector<Enumeration<String>>();
+ mObjClasses = new Vector<String>();
+
+ 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<Enumeration<String>> objClasses = mRequiredAttrs.elements();
+ Enumeration<String> attrnames = null;
+
+ while (objClasses.hasMoreElements()) {
+ attrnames = objClasses.nextElement();
+ CMS.debug("PortalEnroll: Required attrs:");
+ while (attrnames.hasMoreElements()) {
+ String attrname = 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 = objClasses.nextElement();
+ CMS.debug("PortalEnroll: Optional attrs:");
+ while (attrnames.hasMoreElements()) {
+ String attrname = 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
+ */
+ @SuppressWarnings("unchecked")
+ 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/base/common/src/com/netscape/cms/authentication/RDNPattern.java b/base/common/src/com/netscape/cms/authentication/RDNPattern.java
new file mode 100644
index 000000000..722aefbc3
--- /dev/null
+++ b/base/common/src/com/netscape/cms/authentication/RDNPattern.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.cms.authentication;
+
+import java.io.IOException;
+import java.io.PushbackReader;
+import java.io.StringReader;
+import java.util.Vector;
+
+import netscape.ldap.LDAPEntry;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.EAuthException;
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * 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<AVAPattern> avaPatterns = new Vector<AVAPattern>();
+ 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<String> ldapAttrs = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/authentication/SSLclientCertAuthentication.java b/base/common/src/com/netscape/cms/authentication/SSLclientCertAuthentication.java
new file mode 100644
index 000000000..35c23bd0f
--- /dev/null
+++ b/base/common/src/com/netscape/cms/authentication/SSLclientCertAuthentication.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) 2008 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.authentication;
+
+import java.security.Principal;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import netscape.security.x509.BasicConstraintsExtension;
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+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.authentication.ISSLClientCertProvider;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileAuthenticator;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.usrgrp.Certificates;
+
+/**
+ * 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<String> 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/base/common/src/com/netscape/cms/authentication/SharedSecret.java b/base/common/src/com/netscape/cms/authentication/SharedSecret.java
new file mode 100644
index 000000000..7a0784c53
--- /dev/null
+++ b/base/common/src/com/netscape/cms/authentication/SharedSecret.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.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/base/common/src/com/netscape/cms/authentication/TokenAuthentication.java b/base/common/src/com/netscape/cms/authentication/TokenAuthentication.java
new file mode 100644
index 000000000..f8e0669e9
--- /dev/null
+++ b/base/common/src/com/netscape/cms/authentication/TokenAuthentication.java
@@ -0,0 +1,304 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.ByteArrayInputStream;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+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.IConfigStore;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileAuthenticator;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.cmsutil.http.HttpClient;
+import com.netscape.cmsutil.http.HttpRequest;
+import com.netscape.cmsutil.http.HttpResponse;
+import com.netscape.cmsutil.http.JssSSLSocketFactory;
+import com.netscape.cmsutil.xml.XMLObject;
+
+/**
+ * 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<String> getValueNames() {
+ Vector<String> v = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/authentication/UdnPwdDirAuthentication.java b/base/common/src/com/netscape/cms/authentication/UdnPwdDirAuthentication.java
new file mode 100644
index 000000000..c9fbbf9ac
--- /dev/null
+++ b/base/common/src/com/netscape/cms/authentication/UdnPwdDirAuthentication.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.authentication;
+
+// ldap java sdk
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPException;
+
+import com.netscape.certsrv.apps.CMS;
+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.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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/base/common/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java b/base/common/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java
new file mode 100644
index 000000000..d4a9de108
--- /dev/null
+++ b/base/common/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java
@@ -0,0 +1,269 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+
+import com.netscape.certsrv.apps.CMS;
+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.IAuthToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileAuthenticator;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> getValueNames() {
+ Vector<String> v = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/authentication/UidPwdPinDirAuthentication.java b/base/common/src/com/netscape/cms/authentication/UidPwdPinDirAuthentication.java
new file mode 100644
index 000000000..880b7c767
--- /dev/null
+++ b/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 java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPModification;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.EAuthException;
+import com.netscape.certsrv.authentication.EInvalidCredentials;
+import com.netscape.certsrv.authentication.EMissingCredential;
+import com.netscape.certsrv.authentication.IAuthCredentials;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileAuthenticator;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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"));
+ }
+
+ @SuppressWarnings("unchecked")
+ Enumeration<byte[]> 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 = 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<String> getValueNames() {
+ Vector<String> v = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/authorization/AAclAuthz.java b/base/common/src/com/netscape/cms/authorization/AAclAuthz.java
new file mode 100644
index 000000000..570fe3a88
--- /dev/null
+++ b/base/common/src/com/netscape/cms/authorization/AAclAuthz.java
@@ -0,0 +1,858 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import com.netscape.certsrv.acls.ACL;
+import com.netscape.certsrv.acls.ACLEntry;
+import com.netscape.certsrv.acls.EACLsException;
+import com.netscape.certsrv.acls.IACL;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.evaluators.IAccessEvaluator;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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<String, ACL> mACLs = new Hashtable<String, ACL>();
+ private Hashtable<String, IAccessEvaluator> mEvaluators = new Hashtable<String, IAccessEvaluator>();
+ private ILogger mLogger = null;
+
+ /* Vector of extendedPluginInfo strings */
+ protected static Vector<String> mExtendedPluginInfo = null;
+
+ protected static String[] mConfigParams = null;
+
+ static {
+ mExtendedPluginInfo = new Vector<String>();
+ }
+
+ /**
+ * 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<String> 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) {
+ throw new EACLsException(CMS.getUserMessage("CMS_ACL_CLASS_LOAD_FAIL",
+ evalClassPath));
+ }
+
+ if (evaluator != null) {
+ evaluator.init();
+ // store evaluator
+ registerEvaluator(type, evaluator);
+ } else {
+ 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<String> getTargetNames() {
+ return mACLs.keys();
+ }
+
+ public Enumeration<ACL> 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;
+
+ 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<ACLEntry> 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<Object> v = new Vector<Object>();
+
+ 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) {
+ 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<String> nodev = getNodes(name);
+ Enumeration<String> nodes = nodev.elements();
+ String order = getOrder();
+ Enumeration<ACLEntry> 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;
+
+ 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<ACLEntry> getAllowEntries(Enumeration<String> nodes, String operation) {
+ String name = "";
+ ACL acl = null;
+ Enumeration<ACLEntry> e = null;
+ Vector<ACLEntry> v = new Vector<ACLEntry>();
+
+ 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<ACLEntry> getDenyEntries(Enumeration<String> nodes, String operation) {
+ String name = "";
+ ACL acl = null;
+ Enumeration<ACLEntry> e = null;
+ Vector<ACLEntry> v = new Vector<ACLEntry>();
+
+ while (nodes.hasMoreElements()) {
+ name = (String) nodes.nextElement();
+ acl = (ACL) mACLs.get(name);
+ if (acl == null)
+ continue;
+ e = acl.entries();
+ while (e.hasMoreElements()) {
+ ACLEntry entry = 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<Object> v = new Vector<Object>();
+
+ 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<String> getNodes(String resourceID) {
+ Vector<String> v = new Vector<String>();
+
+ 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) {
+ 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 {
+ 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<ACL> aclResElements() {
+ return (mACLs.elements());
+ }
+
+ /**
+ * gets an enumeration of access evaluators
+ *
+ * @return an enumeraton of access evaluators
+ */
+ public Enumeration<IAccessEvaluator> aclEvaluatorElements() {
+ return (mEvaluators.elements());
+ }
+
+ /**
+ * gets the access evaluators
+ *
+ * @return handle to the access evaluators table
+ */
+ public Hashtable<String, IAccessEvaluator> 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/base/common/src/com/netscape/cms/authorization/BasicAclAuthz.java b/base/common/src/com/netscape/cms/authorization/BasicAclAuthz.java
new file mode 100644
index 000000000..f6b1b6713
--- /dev/null
+++ b/base/common/src/com/netscape/cms/authorization/BasicAclAuthz.java
@@ -0,0 +1,217 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.EACLsException;
+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.authorization.EAuthzInternalError;
+import com.netscape.certsrv.authorization.IAuthzManager;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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(&quot;DirACLBasedAuthz&quot;, authToken, RES_GROUP, &quot;read&quot;);
+ * } catch (EBaseException e) {
+ * log(ILogger.LL_FAILURE, &quot;authorize call: &quot; + 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;
+
+ 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/base/common/src/com/netscape/cms/authorization/DirAclAuthz.java b/base/common/src/com/netscape/cms/authorization/DirAclAuthz.java
new file mode 100644
index 000000000..acc3ffbb7
--- /dev/null
+++ b/base/common/src/com/netscape/cms/authorization/DirAclAuthz.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.authorization;
+
+import java.util.Enumeration;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPModification;
+import netscape.ldap.LDAPModificationSet;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+
+import com.netscape.certsrv.acls.ACL;
+import com.netscape.certsrv.acls.EACLsException;
+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.authorization.EAuthzInternalError;
+import com.netscape.certsrv.authorization.IAuthzManager;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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 {
+ @SuppressWarnings("unused")
+ String hostname = ldapConfig.getString("ldapconn.host"); // check for errors
+ } 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");
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> en = (Enumeration<String>) aclRes.getStringValues();
+
+ for (; en != null && en.hasMoreElements();) {
+ addACLs(en.nextElement());
+ }
+ } else {
+ log(ILogger.LL_INFO, "ldap search found no cn=aclResources");
+ }
+ } catch (LDAPException e) {
+ 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(&quot;DirAclAuthz&quot;, authToken, RES_GROUP, &quot;read&quot;);
+ * } catch (EBaseException e) {
+ * log(ILogger.LL_FAILURE, &quot;authorize call: &quot; + 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;
+
+ 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<ACL> 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/base/common/src/com/netscape/cms/crl/CMSAuthInfoAccessExtension.java b/base/common/src/com/netscape/cms/crl/CMSAuthInfoAccessExtension.java
new file mode 100644
index 000000000..d4cef0148
--- /dev/null
+++ b/base/common/src/com/netscape/cms/crl/CMSAuthInfoAccessExtension.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.crl;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import netscape.security.extensions.AuthInfoAccessExtension;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.Extension;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.URIName;
+import netscape.security.x509.X500Name;
+
+import com.netscape.certsrv.apps.CMS;
+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.ca.ICMSCRLExtension;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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) {
+ 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.put(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.put(PROP_ACCESS_METHOD + i, accessMethod);
+ } else {
+ nvp.put(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.put(PROP_ACCESS_LOCATION_TYPE + i, accessLocationType);
+ } else {
+ nvp.put(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.put(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.put(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/base/common/src/com/netscape/cms/crl/CMSAuthorityKeyIdentifierExtension.java b/base/common/src/com/netscape/cms/crl/CMSAuthorityKeyIdentifierExtension.java
new file mode 100644
index 000000000..26c8c1d0e
--- /dev/null
+++ b/base/common/src/com/netscape/cms/crl/CMSAuthorityKeyIdentifierExtension.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.crl;
+
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateParsingException;
+import java.util.Locale;
+
+import netscape.security.x509.AuthorityKeyIdentifierExtension;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.KeyIdentifier;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.SerialNumber;
+import netscape.security.x509.SubjectKeyIdentifierExtension;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ca.ICMSCRLExtension;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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/base/common/src/com/netscape/cms/crl/CMSCRLNumberExtension.java b/base/common/src/com/netscape/cms/crl/CMSCRLNumberExtension.java
new file mode 100644
index 000000000..e7f4e7b3f
--- /dev/null
+++ b/base/common/src/com/netscape/cms/crl/CMSCRLNumberExtension.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.crl;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Locale;
+
+import netscape.security.x509.CRLNumberExtension;
+import netscape.security.x509.Extension;
+import netscape.security.x509.PKIXExtensions;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ca.ICMSCRLExtension;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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/base/common/src/com/netscape/cms/crl/CMSCRLReasonExtension.java b/base/common/src/com/netscape/cms/crl/CMSCRLReasonExtension.java
new file mode 100644
index 000000000..6ed993d54
--- /dev/null
+++ b/base/common/src/com/netscape/cms/crl/CMSCRLReasonExtension.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.crl;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.Extension;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.RevocationReason;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ca.ICMSCRLExtension;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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/base/common/src/com/netscape/cms/crl/CMSCertificateIssuerExtension.java b/base/common/src/com/netscape/cms/crl/CMSCertificateIssuerExtension.java
new file mode 100644
index 000000000..b0bf20856
--- /dev/null
+++ b/base/common/src/com/netscape/cms/crl/CMSCertificateIssuerExtension.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.crl;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import netscape.security.x509.CertificateIssuerExtension;
+import netscape.security.x509.Extension;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.URIName;
+import netscape.security.x509.X500Name;
+
+import com.netscape.certsrv.apps.CMS;
+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.ca.ICMSCRLExtension;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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;
+
+ 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.put("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.put("nameType" + i, nameType);
+ } else {
+ nvp.put("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.put("name" + i, name);
+ } else {
+ nvp.put("name" + i, "");
+ }
+ }
+
+ if (numNames < 3) {
+ for (int i = numNames; i < 3; i++) {
+ nvp.put("nameType" + i, "");
+ nvp.put("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/base/common/src/com/netscape/cms/crl/CMSDeltaCRLIndicatorExtension.java b/base/common/src/com/netscape/cms/crl/CMSDeltaCRLIndicatorExtension.java
new file mode 100644
index 000000000..8672502ab
--- /dev/null
+++ b/base/common/src/com/netscape/cms/crl/CMSDeltaCRLIndicatorExtension.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.IOException;
+import java.math.BigInteger;
+import java.util.Locale;
+
+import netscape.security.x509.DeltaCRLIndicatorExtension;
+import netscape.security.x509.Extension;
+import netscape.security.x509.PKIXExtensions;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ca.ICMSCRLExtension;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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/base/common/src/com/netscape/cms/crl/CMSFreshestCRLExtension.java b/base/common/src/com/netscape/cms/crl/CMSFreshestCRLExtension.java
new file mode 100644
index 000000000..72dbe5502
--- /dev/null
+++ b/base/common/src/com/netscape/cms/crl/CMSFreshestCRLExtension.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.cms.crl;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import netscape.security.x509.CRLDistributionPoint;
+import netscape.security.x509.Extension;
+import netscape.security.x509.FreshestCRLExtension;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.GeneralNamesException;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.URIName;
+import netscape.security.x509.X500Name;
+
+import com.netscape.certsrv.apps.CMS;
+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.ca.ICMSCRLExtension;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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) {
+ 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.put(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.put(PROP_POINTTYPE + i, pointType);
+ } else {
+ nvp.put(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.put(PROP_POINTNAME + i, pointName);
+ } else {
+ nvp.put(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/base/common/src/com/netscape/cms/crl/CMSHoldInstructionExtension.java b/base/common/src/com/netscape/cms/crl/CMSHoldInstructionExtension.java
new file mode 100644
index 000000000..4023e3b2f
--- /dev/null
+++ b/base/common/src/com/netscape/cms/crl/CMSHoldInstructionExtension.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.crl;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.Extension;
+import netscape.security.x509.HoldInstructionExtension;
+import netscape.security.x509.PKIXExtensions;
+
+import com.netscape.certsrv.apps.CMS;
+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.ca.ICMSCRLExtension;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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;
+
+ 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.put(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/base/common/src/com/netscape/cms/crl/CMSInvalidityDateExtension.java b/base/common/src/com/netscape/cms/crl/CMSInvalidityDateExtension.java
new file mode 100644
index 000000000..083873c31
--- /dev/null
+++ b/base/common/src/com/netscape/cms/crl/CMSInvalidityDateExtension.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.IOException;
+import java.util.Date;
+import java.util.Locale;
+
+import netscape.security.x509.Extension;
+import netscape.security.x509.InvalidityDateExtension;
+import netscape.security.x509.PKIXExtensions;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ca.ICMSCRLExtension;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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/base/common/src/com/netscape/cms/crl/CMSIssuerAlternativeNameExtension.java b/base/common/src/com/netscape/cms/crl/CMSIssuerAlternativeNameExtension.java
new file mode 100644
index 000000000..64252a0b9
--- /dev/null
+++ b/base/common/src/com/netscape/cms/crl/CMSIssuerAlternativeNameExtension.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.crl;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.Locale;
+
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.DNSName;
+import netscape.security.x509.EDIPartyName;
+import netscape.security.x509.Extension;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.IPAddressName;
+import netscape.security.x509.IssuerAlternativeNameExtension;
+import netscape.security.x509.OIDName;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.RFC822Name;
+import netscape.security.x509.URIName;
+import netscape.security.x509.X500Name;
+
+import com.netscape.certsrv.apps.CMS;
+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.ca.ICMSCRLExtension;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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) {
+ 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 = Utils.base64decode(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.put("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.put("nameType" + i, nameType);
+ } else {
+ nvp.put("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.put("name" + i, name);
+ } else {
+ nvp.put("name" + i, "");
+ }
+ }
+
+ if (numNames < 3) {
+ for (int i = numNames; i < 3; i++) {
+ nvp.put("nameType" + i, "");
+ nvp.put("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/base/common/src/com/netscape/cms/crl/CMSIssuingDistributionPointExtension.java b/base/common/src/com/netscape/cms/crl/CMSIssuingDistributionPointExtension.java
new file mode 100644
index 000000000..4253584ce
--- /dev/null
+++ b/base/common/src/com/netscape/cms/crl/CMSIssuingDistributionPointExtension.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.crl;
+
+import java.io.IOException;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import netscape.security.util.BitArray;
+import netscape.security.x509.Extension;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.GeneralNamesException;
+import netscape.security.x509.IssuingDistributionPoint;
+import netscape.security.x509.IssuingDistributionPointExtension;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.RDN;
+import netscape.security.x509.URIName;
+import netscape.security.x509.X500Name;
+
+import com.netscape.certsrv.apps.CMS;
+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.ca.ICMSCRLExtension;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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.");
+ 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.put("pointType", pointType);
+ } else {
+ nvp.put("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.put("pointName", pointName);
+ } else {
+ nvp.put("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.put(PROP_REASONS, reasons);
+ } else {
+ nvp.put(PROP_REASONS, "");
+ }
+
+ try {
+ boolean caCertsOnly = config.getBoolean(PROP_CACERTS, false);
+
+ nvp.put(PROP_CACERTS, String.valueOf(caCertsOnly));
+ } catch (EBaseException e) {
+ nvp.put(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/base/common/src/com/netscape/cms/evaluators/GroupAccessEvaluator.java b/base/common/src/com/netscape/cms/evaluators/GroupAccessEvaluator.java
new file mode 100644
index 000000000..530ca9447
--- /dev/null
+++ b/base/common/src/com/netscape/cms/evaluators/GroupAccessEvaluator.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.evaluators;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.evaluators.IAccessEvaluator;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.certsrv.usrgrp.IUser;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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/base/common/src/com/netscape/cms/evaluators/IPAddressAccessEvaluator.java b/base/common/src/com/netscape/cms/evaluators/IPAddressAccessEvaluator.java
new file mode 100644
index 000000000..17d383688
--- /dev/null
+++ b/base/common/src/com/netscape/cms/evaluators/IPAddressAccessEvaluator.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.cms.evaluators;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.evaluators.IAccessEvaluator;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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/base/common/src/com/netscape/cms/evaluators/UserAccessEvaluator.java b/base/common/src/com/netscape/cms/evaluators/UserAccessEvaluator.java
new file mode 100644
index 000000000..bf7727c92
--- /dev/null
+++ b/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.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.evaluators.IAccessEvaluator;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.usrgrp.IUser;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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/base/common/src/com/netscape/cms/evaluators/UserOrigReqAccessEvaluator.java b/base/common/src/com/netscape/cms/evaluators/UserOrigReqAccessEvaluator.java
new file mode 100644
index 000000000..442828e75
--- /dev/null
+++ b/base/common/src/com/netscape/cms/evaluators/UserOrigReqAccessEvaluator.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) 2008 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.evaluators;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.evaluators.IAccessEvaluator;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.usrgrp.IUser;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/jobs/AJobBase.java b/base/common/src/com/netscape/cms/jobs/AJobBase.java
new file mode 100644
index 000000000..0da5d2028
--- /dev/null
+++ b/base/common/src/com/netscape/cms/jobs/AJobBase.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.jobs;
+
+import java.io.IOException;
+import java.util.Hashtable;
+
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.jobs.IJob;
+import com.netscape.certsrv.jobs.IJobCron;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.notification.ENotificationException;
+import com.netscape.certsrv.notification.IEmailFormProcessor;
+import com.netscape.certsrv.notification.IEmailTemplate;
+import com.netscape.certsrv.notification.IMailNotification;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String, Object> mContentParams = new Hashtable<String, Object>();
+ protected Hashtable<String, Object> mItemParams = new Hashtable<String, Object>();
+
+ boolean stopped;
+
+ 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,
+ cert.getSerialNumber().toString());
+ mItemParams.put(IEmailFormProcessor.TOKEN_HEX_SERIAL_NUM,
+ cert.getSerialNumber().toString(16));
+ mItemParams.put(IEmailFormProcessor.TOKEN_ISSUER_DN,
+ cert.getIssuerDN().toString());
+ mItemParams.put(IEmailFormProcessor.TOKEN_SUBJECT_DN,
+ cert.getSubjectDN().toString());
+ mItemParams.put(IEmailFormProcessor.TOKEN_NOT_AFTER,
+ cert.getNotAfter().toString());
+ mItemParams.put(IEmailFormProcessor.TOKEN_NOT_BEFORE,
+ 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);
+ }
+
+ public void stop() {
+ stopped = true;
+ }
+
+ public boolean isStopped() {
+ return stopped;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/jobs/PublishCertsJob.java b/base/common/src/com/netscape/cms/jobs/PublishCertsJob.java
new file mode 100644
index 000000000..28268dfab
--- /dev/null
+++ b/base/common/src/com/netscape/cms/jobs/PublishCertsJob.java
@@ -0,0 +1,392 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.text.DateFormat;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+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.base.MetaInfo;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.jobs.IJob;
+import com.netscape.certsrv.jobs.IJobCron;
+import com.netscape.certsrv.jobs.IJobsScheduler;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.notification.IEmailFormProcessor;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+
+/**
+ * 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"
+ };
+
+ 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 = 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();
+ DateFormat dateFormat = DateFormat.getDateTimeInstance();
+ String nowString = dateFormat.format(date);
+
+ // form filter
+ String filter = // might need to use "metaInfo"
+ "(!(certMetainfo=" + ICertRecord.META_LDAPPUBLISH +
+ ":true))";
+
+ Enumeration<Object> 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 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(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(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/base/common/src/com/netscape/cms/jobs/RenewalNotificationJob.java b/base/common/src/com/netscape/cms/jobs/RenewalNotificationJob.java
new file mode 100644
index 000000000..5ca581445
--- /dev/null
+++ b/base/common/src/com/netscape/cms/jobs/RenewalNotificationJob.java
@@ -0,0 +1,706 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.io.IOException;
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import com.netscape.certsrv.apps.CMS;
+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.base.MetaInfo;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.IElementProcessor;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.jobs.IJob;
+import com.netscape.certsrv.jobs.IJobCron;
+import com.netscape.certsrv.jobs.IJobsScheduler;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.notification.ENotificationException;
+import com.netscape.certsrv.notification.IEmailFormProcessor;
+import com.netscape.certsrv.notification.IEmailResolver;
+import com.netscape.certsrv.notification.IEmailResolverKeys;
+import com.netscape.certsrv.notification.IMailNotification;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestId;
+
+/**
+ * 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;
+
+ /**
+ * 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 = 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<Object> en = mCertDB.findCertRecs(filter);
+
+ while (en.hasMoreElements()) {
+ Object element = 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()));
+ }
+ }
+
+ /**
+ * 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");
+
+ 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,
+ AJobBase.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,
+ AJobBase.STATUS_SUCCESS);
+
+ mIC.mNumSuccessful++;
+
+ } catch (Exception e) {
+ CMS.debug("RenewalNotificationJob Exception: " + e.toString());
+ mJob.buildItemParams(IEmailFormProcessor.TOKEN_STATUS, AJobBase.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/base/common/src/com/netscape/cms/jobs/RequestInQueueJob.java b/base/common/src/com/netscape/cms/jobs/RequestInQueueJob.java
new file mode 100644
index 000000000..b04461941
--- /dev/null
+++ b/base/common/src/com/netscape/cms/jobs/RequestInQueueJob.java
@@ -0,0 +1,217 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.text.DateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+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.jobs.IJob;
+import com.netscape.certsrv.jobs.IJobCron;
+import com.netscape.certsrv.jobs.IJobsScheduler;
+import com.netscape.certsrv.notification.IEmailFormProcessor;
+import com.netscape.certsrv.request.IRequestList;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestStatus;
+
+/**
+ * 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();
+ DateFormat dateFormat = DateFormat.getDateTimeInstance();
+ String nowString = dateFormat.format(date);
+
+ int count = 0;
+ IRequestList list =
+ mReqQ.listRequestsByStatus(RequestStatus.PENDING);
+
+ while (list != null && list.hasMoreElements()) {
+ 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/base/common/src/com/netscape/cms/jobs/UnpublishExpiredJob.java b/base/common/src/com/netscape/cms/jobs/UnpublishExpiredJob.java
new file mode 100644
index 000000000..2f4a6ad75
--- /dev/null
+++ b/base/common/src/com/netscape/cms/jobs/UnpublishExpiredJob.java
@@ -0,0 +1,385 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.security.cert.X509Certificate;
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+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.base.MetaInfo;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.jobs.IJob;
+import com.netscape.certsrv.jobs.IJobCron;
+import com.netscape.certsrv.jobs.IJobsScheduler;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.notification.IEmailFormProcessor;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+
+/**
+ * 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"
+ };
+
+ 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 = 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<Object> 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/base/common/src/com/netscape/cms/listeners/CertificateIssuedListener.java b/base/common/src/com/netscape/cms/listeners/CertificateIssuedListener.java
new file mode 100644
index 000000000..91526d583
--- /dev/null
+++ b/base/common/src/com/netscape/cms/listeners/CertificateIssuedListener.java
@@ -0,0 +1,450 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.Hashtable;
+
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.listeners.EListenersException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.notification.ENotificationException;
+import com.netscape.certsrv.notification.IEmailFormProcessor;
+import com.netscape.certsrv.notification.IEmailResolver;
+import com.netscape.certsrv.notification.IEmailResolverKeys;
+import com.netscape.certsrv.notification.IEmailTemplate;
+import com.netscape.certsrv.notification.IMailNotification;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestListener;
+import com.netscape.certsrv.request.RequestId;
+
+/**
+ * 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<String, Object> mContentParams = new Hashtable<String, Object>();
+
+ 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,
+ issuedCert[0].getSerialNumber().toString());
+ mContentParams.put(IEmailFormProcessor.TOKEN_HEX_SERIAL_NUM,
+ Long.toHexString(issuedCert[0].getSerialNumber().longValue()));
+ mContentParams.put(IEmailFormProcessor.TOKEN_REQUEST_ID,
+ mReqId.toString());
+ mContentParams.put(IEmailFormProcessor.TOKEN_HTTP_HOST,
+ mHttpHost);
+ mContentParams.put(IEmailFormProcessor.TOKEN_HTTP_PORT,
+ mHttpPort);
+ mContentParams.put(IEmailFormProcessor.TOKEN_ISSUER_DN,
+ issuedCert[0].getIssuerDN().toString());
+ mContentParams.put(IEmailFormProcessor.TOKEN_SUBJECT_DN,
+ 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,
+ mSenderEmail);
+ mContentParams.put(IEmailFormProcessor.TOKEN_RECIPIENT_EMAIL,
+ 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/base/common/src/com/netscape/cms/listeners/CertificateRevokedListener.java b/base/common/src/com/netscape/cms/listeners/CertificateRevokedListener.java
new file mode 100644
index 000000000..da041b85d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/listeners/CertificateRevokedListener.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.listeners;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.cert.X509Certificate;
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.Hashtable;
+
+import netscape.security.x509.RevokedCertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.listeners.EListenersException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.notification.ENotificationException;
+import com.netscape.certsrv.notification.IEmailFormProcessor;
+import com.netscape.certsrv.notification.IEmailResolver;
+import com.netscape.certsrv.notification.IEmailResolverKeys;
+import com.netscape.certsrv.notification.IEmailTemplate;
+import com.netscape.certsrv.notification.IMailNotification;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestListener;
+import com.netscape.certsrv.request.RequestId;
+
+/**
+ * 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<String, Object> mContentParams = new Hashtable<String, Object>();
+
+ 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 buildContentParams(RevokedCertImpl crlentries[], String mEmail) {
+ mContentParams.put(IEmailFormProcessor.TOKEN_ID,
+ mConfig.getName());
+ mContentParams.put(IEmailFormProcessor.TOKEN_SERIAL_NUM,
+ crlentries[0].getSerialNumber().toString());
+ mContentParams.put(IEmailFormProcessor.TOKEN_HEX_SERIAL_NUM,
+ Long.toHexString(crlentries[0].getSerialNumber().longValue()));
+ mContentParams.put(IEmailFormProcessor.TOKEN_REQUEST_ID,
+ mReqId.toString());
+ mContentParams.put(IEmailFormProcessor.TOKEN_HTTP_HOST,
+ mHttpHost);
+ mContentParams.put(IEmailFormProcessor.TOKEN_HTTP_PORT,
+ 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,
+ cert.getIssuerDN().toString());
+ mContentParams.put(IEmailFormProcessor.TOKEN_SUBJECT_DN,
+ 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,
+ mSenderEmail);
+ mContentParams.put(IEmailFormProcessor.TOKEN_RECIPIENT_EMAIL,
+ 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/base/common/src/com/netscape/cms/listeners/PinRemovalListener.java b/base/common/src/com/netscape/cms/listeners/PinRemovalListener.java
new file mode 100644
index 000000000..662e762b0
--- /dev/null
+++ b/base/common/src/com/netscape/cms/listeners/PinRemovalListener.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.cms.listeners;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPModification;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestListener;
+import com.netscape.certsrv.request.RequestId;
+
+/**
+ * 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 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 {
+
+ 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/base/common/src/com/netscape/cms/listeners/RequestInQListener.java b/base/common/src/com/netscape/cms/listeners/RequestInQListener.java
new file mode 100644
index 000000000..7ff13db54
--- /dev/null
+++ b/base/common/src/com/netscape/cms/listeners/RequestInQListener.java
@@ -0,0 +1,283 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Hashtable;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.listeners.EListenersException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.notification.ENotificationException;
+import com.netscape.certsrv.notification.IEmailFormProcessor;
+import com.netscape.certsrv.notification.IEmailTemplate;
+import com.netscape.certsrv.notification.IMailNotification;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestListener;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.cms.profile.input.SubjectNameInput;
+import com.netscape.cms.profile.input.SubmitterInfoInput;
+
+/**
+ * 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<String, Object> mContentParams = new Hashtable<String, Object>();
+ 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/base/common/src/com/netscape/cms/logging/LogEntry.java b/base/common/src/com/netscape/cms/logging/LogEntry.java
new file mode 100644
index 000000000..d91bd7406
--- /dev/null
+++ b/base/common/src/com/netscape/cms/logging/LogEntry.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.logging;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Vector;
+
+/**
+ * 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<String> 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<String> 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<String> row = new Vector<String>();
+
+ 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<String> getRow() {
+ return mRow;
+ }
+
+ public String getEntry() {
+ return mEntry;
+ }
+
+ public void appendDetail(String msg) {
+ mDetail = mDetail + "\n" + msg;
+ mEntry = mEntry + "\n" + msg;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/logging/LogFile.java b/base/common/src/com/netscape/cms/logging/LogFile.java
new file mode 100644
index 000000000..5144bf16d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/logging/LogFile.java
@@ -0,0 +1,1534 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.CharArrayReader;
+import java.io.CharArrayWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.RandomAccessFile;
+import java.io.UnsupportedEncodingException;
+import java.security.GeneralSecurityException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.interfaces.DSAPrivateKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.ServletException;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.ObjectNotFoundException;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.util.Base64OutputStream;
+
+import com.netscape.certsrv.apps.CMS;
+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.common.Constants;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.logging.AuditEvent;
+import com.netscape.certsrv.logging.ConsoleError;
+import com.netscape.certsrv.logging.ELogException;
+import com.netscape.certsrv.logging.ILogEvent;
+import com.netscape.certsrv.logging.ILogEventListener;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.SignedAuditEvent;
+import com.netscape.certsrv.logging.SystemEvent;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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 selected log event types
+ */
+ protected String mSelectedEventsList = null;
+ protected Vector<String> 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<String> string2Vector(String theString) {
+ Vector<String> theVector = new Vector<String>();
+ 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<String> 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() {
+ return String.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())));
+ if (mLogSigning) {
+ //error in writing to signed audit log, shut down CMS
+ e.printStackTrace();
+ shutdownCMS();
+ }
+ } 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())));
+ if (mLogSigning) {
+ // Failed to write to audit log, shut down CMS
+ e.printStackTrace();
+ shutdownCMS();
+ }
+ } 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 = CMS.getPID() + "." + Thread.currentThread().getName() + " - ["
+ + mLogDateFormat.format(mDate) + "] [" +
+ Integer.toString(ev.getSource()) + "] [" + Integer.toString(ev.getLevel())
+ + "] " + prepareMultiline(ev.toString());
+ } else {
+ entry = CMS.getPID() + "." + 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<LogEntry> readEntry(int maxLine, int lowLevel, int source, String fName) {
+ Vector<LogEntry> mEntries = new Vector<LogEntry>();
+ 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<String, String> req) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ String tmp, fName = null;
+ int maxLine = -1, level = -1, source = -1;
+ Vector<LogEntry> 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.put(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<String, String> req) throws ServletException,
+ IOException, EBaseException {
+ return null;
+ }
+
+ public String getImplName() {
+ return "LogFile";
+ }
+
+ public String getDescription() {
+ return "LogFile";
+ }
+
+ public Vector<String> getDefaultParams() {
+ Vector<String> v = new Vector<String>();
+
+ 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<String> getInstanceParams() {
+ Vector<String> v = new Vector<String>();
+
+ try {
+
+ if (mType == null) {
+ v.addElement(PROP_TYPE + "=");
+ } else {
+ v.addElement(PROP_TYPE + "=" +
+ mConfig.getString(PROP_TYPE));
+ }
+ v.addElement(PROP_ON + "=" + String.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)) {
+ v.addElement(PROP_SIGNED_AUDIT_LOG_SIGNING + "="
+ + String.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/base/common/src/com/netscape/cms/logging/RollingLogFile.java b/base/common/src/com/netscape/cms/logging/RollingLogFile.java
new file mode 100644
index 000000000..93455e9fe
--- /dev/null
+++ b/base/common/src/com/netscape/cms/logging/RollingLogFile.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.logging;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.servlet.ServletException;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.logging.ConsoleError;
+import com.netscape.certsrv.logging.ELogException;
+import com.netscape.certsrv.logging.ILogEvent;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.SystemEvent;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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);
+ 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<String, String> req
+ ) throws ServletException,
+ IOException, EBaseException {
+ NameValuePairs params = new NameValuePairs();
+ String[] files = null;
+
+ files = fileList();
+ for (int i = 0; i < files.length; i++) {
+ params.put(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<String> getDefaultParams() {
+ Vector<String> v = super.getDefaultParams();
+
+ v.addElement(PROP_MAX_FILE_SIZE + "=");
+ v.addElement(PROP_ROLLOVER_INTERVAL + "=");
+ //v.addElement(PROP_EXPIRATION_TIME + "=");
+ return v;
+ }
+
+ public Vector<String> getInstanceParams() {
+ Vector<String> 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<String> info = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/notification/MailNotification.java b/base/common/src/com/netscape/cms/notification/MailNotification.java
new file mode 100644
index 000000000..ef09d8f71
--- /dev/null
+++ b/base/common/src/com/netscape/cms/notification/MailNotification.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.cms.notification;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Vector;
+
+import netscape.net.smtp.SmtpClient;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.notification.ENotificationException;
+import com.netscape.certsrv.notification.IMailNotification;
+
+/**
+ * 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<String> 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/base/common/src/com/netscape/cms/ocsp/DefStore.java b/base/common/src/com/netscape/cms/ocsp/DefStore.java
new file mode 100644
index 000000000..21f7023d8
--- /dev/null
+++ b/base/common/src/com/netscape/cms/ocsp/DefStore.java
@@ -0,0 +1,953 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.BigInteger;
+import java.security.MessageDigest;
+import java.security.cert.X509CRL;
+import java.security.cert.X509CRLEntry;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.RevokedCertificate;
+import netscape.security.x509.X509CRLImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509Key;
+
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.GeneralizedTime;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.pkix.cert.Extension;
+
+import com.netscape.certsrv.apps.CMS;
+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.common.Constants;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.dbs.IDBSSession;
+import com.netscape.certsrv.dbs.IDBSearchResults;
+import com.netscape.certsrv.dbs.IDBSubsystem;
+import com.netscape.certsrv.dbs.Modification;
+import com.netscape.certsrv.dbs.ModificationSet;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.dbs.repository.IRepositoryRecord;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ocsp.IDefStore;
+import com.netscape.certsrv.ocsp.IOCSPAuthority;
+import com.netscape.certsrv.util.IStatsSubsystem;
+import com.netscape.cmsutil.ocsp.BasicOCSPResponse;
+import com.netscape.cmsutil.ocsp.CertID;
+import com.netscape.cmsutil.ocsp.CertStatus;
+import com.netscape.cmsutil.ocsp.GoodInfo;
+import com.netscape.cmsutil.ocsp.OCSPRequest;
+import com.netscape.cmsutil.ocsp.OCSPResponse;
+import com.netscape.cmsutil.ocsp.OCSPResponseStatus;
+import com.netscape.cmsutil.ocsp.ResponderID;
+import com.netscape.cmsutil.ocsp.ResponseBytes;
+import com.netscape.cmsutil.ocsp.ResponseData;
+import com.netscape.cmsutil.ocsp.RevokedInfo;
+import com.netscape.cmsutil.ocsp.SingleResponse;
+import com.netscape.cmsutil.ocsp.TBSRequest;
+import com.netscape.cmsutil.ocsp.UnknownInfo;
+
+/**
+ * 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<String, Long> mReqCounts = new Hashtable<String, Long>();
+ protected boolean mNotFoundGood = true;
+ protected boolean mUseCache = true;
+ protected boolean mByName = true;
+ protected boolean mIncludeNextUpdate = false;
+ protected Hashtable<String, CRLIPContainer> mCacheCRLIssuingPoints = new Hashtable<String, CRLIPContainer>();
+ private IOCSPAuthority mOCSPAuthority = null;
+ private IConfigStore mConfig = null;
+ private String mId = null;
+ private IDBSubsystem mDBService = null;
+ private int mStateCount = 0;
+
+ /**
+ * Constructs the default store.
+ */
+ public DefStore() {
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ Vector<String> v = new Vector<String>();
+
+ 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);
+
+ // 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<ICRLIssuingPointRecord> recs = searchCRLIssuingPointRecord(
+ "objectclass=" +
+ CMS.getCRLIssuingPointRecordName(),
+ 100);
+ while (recs.hasMoreElements()) {
+ ICRLIssuingPointRecord rec = 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<IRepositoryRecord> e = searchRepository(
+ caName,
+ "(!" + IRepositoryRecord.ATTR_SERIALNO + "=" +
+ thisUpdate + ")");
+
+ while (e != null && e.hasMoreElements()) {
+ IRepositoryRecord r = e.nextElement();
+ Enumeration<ICertRecord> 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<SingleResponse> singleResponses = new Vector<SingleResponse>();
+ 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<ICRLIssuingPointRecord> recs = searchCRLIssuingPointRecord(
+ "objectclass=" +
+ CMS.getCRLIssuingPointRecordName(),
+ 100);
+
+ while (recs.hasMoreElements()) {
+ ICRLIssuingPointRecord rec = 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<BigInteger, RevokedCertificate> 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<ICRLIssuingPointRecord> searchAllCRLIssuingPointRecord(int maxSize)
+ throws EBaseException {
+ return searchCRLIssuingPointRecord(
+ "objectclass=" +
+ CMS.getCRLIssuingPointRecordName(),
+ maxSize);
+ }
+
+ public Enumeration<ICRLIssuingPointRecord> searchCRLIssuingPointRecord(String filter,
+ int maxSize)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Vector<ICRLIssuingPointRecord> v = new Vector<ICRLIssuingPointRecord>();
+
+ try {
+ IDBSearchResults sr = s.search(getBaseDN(), filter, maxSize);
+ while (sr.hasMoreElements()) {
+ v.add((ICRLIssuingPointRecord) sr.nextElement());
+ }
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return v.elements();
+ }
+
+ 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<IRepositoryRecord> searchRepository(String name, String filter)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Vector<IRepositoryRecord> v = new Vector<IRepositoryRecord>();
+
+ try {
+ IDBSearchResults sr = s.search("cn=" + transformDN(name) + "," + getBaseDN(),
+ filter);
+ while (sr.hasMoreElements()) {
+ v.add((IRepositoryRecord) sr.nextElement());
+ }
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return v.elements();
+ }
+
+ /**
+ * 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<ICertRecord> searchCertRecord(String name, String thisUpdate,
+ String filter) throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Vector<ICertRecord> v = new Vector<ICertRecord>();
+
+ try {
+ IDBSearchResults sr = s.search("ou=" + thisUpdate + ",cn=" +
+ transformDN(name) + "," + getBaseDN(),
+ filter);
+ while (sr.hasMoreElements()) {
+ v.add((ICertRecord) sr.nextElement());
+ }
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return v.elements();
+ }
+
+ 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.put(Constants.PR_OCSPSTORE_IMPL_NAME,
+ mConfig.getString("class"));
+ params.put(PROP_NOT_FOUND_GOOD,
+ mConfig.getString(PROP_NOT_FOUND_GOOD, "true"));
+ params.put(PROP_BY_NAME,
+ mConfig.getString(PROP_BY_NAME, "true"));
+ params.put(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 {
+
+ for (String key : pairs.keySet()) {
+ mConfig.put(key, pairs.get(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<String, CRLIPContainer> mCache = null;
+ private int mSec = 0;
+
+ public DefStoreCRLUpdater(Hashtable<String, CRLIPContainer> 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/base/common/src/com/netscape/cms/ocsp/LDAPStore.java b/base/common/src/com/netscape/cms/ocsp/LDAPStore.java
new file mode 100644
index 000000000..bca02f4a6
--- /dev/null
+++ b/base/common/src/com/netscape/cms/ocsp/LDAPStore.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.cms.ocsp;
+
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.cert.X509CRL;
+import java.security.cert.X509CRLEntry;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+import netscape.security.x509.RevokedCertificate;
+import netscape.security.x509.X509CRLImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509Key;
+
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.GeneralizedTime;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.pkix.cert.Extension;
+
+import com.netscape.certsrv.apps.CMS;
+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.common.Constants;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.dbs.repository.IRepositoryRecord;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ocsp.IDefStore;
+import com.netscape.certsrv.ocsp.IOCSPAuthority;
+import com.netscape.certsrv.util.IStatsSubsystem;
+import com.netscape.cmsutil.ocsp.BasicOCSPResponse;
+import com.netscape.cmsutil.ocsp.CertID;
+import com.netscape.cmsutil.ocsp.CertStatus;
+import com.netscape.cmsutil.ocsp.GoodInfo;
+import com.netscape.cmsutil.ocsp.OCSPRequest;
+import com.netscape.cmsutil.ocsp.OCSPResponse;
+import com.netscape.cmsutil.ocsp.OCSPResponseStatus;
+import com.netscape.cmsutil.ocsp.ResponderID;
+import com.netscape.cmsutil.ocsp.ResponseBytes;
+import com.netscape.cmsutil.ocsp.ResponseData;
+import com.netscape.cmsutil.ocsp.RevokedInfo;
+import com.netscape.cmsutil.ocsp.SingleResponse;
+import com.netscape.cmsutil.ocsp.TBSRequest;
+import com.netscape.cmsutil.ocsp.UnknownInfo;
+
+/**
+ * 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<String, Long> mReqCounts = new Hashtable<String, Long>();
+ private Hashtable<X509CertImpl, X509CRLImpl> mCRLs = new Hashtable<X509CertImpl, X509CRLImpl>();
+
+ /**
+ * Constructs the default store.
+ */
+ public LDAPStore() {
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ Vector<String> v = new Vector<String>();
+
+ 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);
+ @SuppressWarnings("unchecked")
+ Enumeration<byte[]> vals = crls.getByteValues();
+
+ if (!vals.hasMoreElements()) {
+ throw new EBaseException("error - no values");
+ }
+ byte caCertData[] = 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);
+ @SuppressWarnings("unchecked")
+ Enumeration<byte[]> vals = crls.getByteValues();
+
+ if (!vals.hasMoreElements()) {
+ throw new EBaseException("error - no values");
+ }
+ byte crlData[] = 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 = 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<SingleResponse> singleResponses = new Vector<SingleResponse>();
+
+ 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 = 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<ICRLIssuingPointRecord> searchAllCRLIssuingPointRecord(int maxSize)
+ throws EBaseException {
+ Vector<ICRLIssuingPointRecord> recs = new Vector<ICRLIssuingPointRecord>();
+ Enumeration<X509CertImpl> keys = mCRLs.keys();
+
+ while (keys.hasMoreElements()) {
+ X509CertImpl caCert = keys.nextElement();
+ X509CRLImpl crl = mCRLs.get(caCert);
+
+ recs.addElement(new TempCRLIssuingPointRecord(caCert, crl));
+ }
+ return recs.elements();
+ }
+
+ public Enumeration<ICRLIssuingPointRecord> 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<X509CertImpl> caCerts = mCRLs.keys();
+
+ while (caCerts.hasMoreElements()) {
+ X509CertImpl caCert = 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 = 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.put(Constants.PR_OCSPSTORE_IMPL_NAME,
+ mConfig.getString("class"));
+ int num = mConfig.getInteger(PROP_NUM_CONNS, 0);
+
+ params.put(PROP_NUM_CONNS, Integer.toString(num));
+ for (int i = 0; i < num; i++) {
+ params.put(PROP_HOST + Integer.toString(i),
+ mConfig.getString(PROP_HOST +
+ Integer.toString(i), ""));
+ params.put(PROP_PORT + Integer.toString(i),
+ mConfig.getString(PROP_PORT +
+ Integer.toString(i), "389"));
+ params.put(PROP_BASE_DN + Integer.toString(i),
+ mConfig.getString(PROP_BASE_DN +
+ Integer.toString(i), ""));
+ params.put(PROP_REFRESH_IN_SEC + Integer.toString(i),
+ mConfig.getString(PROP_REFRESH_IN_SEC +
+ Integer.toString(i), Integer.toString(DEF_REFRESH_IN_SEC)));
+ }
+ params.put(PROP_BY_NAME,
+ mConfig.getString(PROP_BY_NAME, "true"));
+ params.put(PROP_CA_CERT_ATTR,
+ mConfig.getString(PROP_CA_CERT_ATTR, DEF_CA_CERT_ATTR));
+ params.put(PROP_CRL_ATTR,
+ mConfig.getString(PROP_CRL_ATTR, DEF_CRL_ATTR));
+ params.put(PROP_NOT_FOUND_GOOD,
+ mConfig.getString(PROP_NOT_FOUND_GOOD, "true"));
+ params.put(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 {
+
+ for (String key : pairs.keySet()) {
+ mConfig.put(key, pairs.get(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 static final long serialVersionUID = 5299660983298765746L;
+ 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<BigInteger, RevokedCertificate> getCRLCacheNoClone() {
+ return null;
+ }
+
+ public Hashtable<BigInteger, RevokedCertificate> 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 int isCRLIssuingPointInitialized() {
+ return 1;
+ }
+
+ public byte[] getCACert() {
+ try {
+ return mCACert.getEncoded();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Retrieves cache info of revoked certificates.
+ */
+ public Hashtable<BigInteger, RevokedCertificate> getRevokedCerts() {
+ return mCRL.getListOfRevokedCertificates();
+ }
+
+ /**
+ * Retrieves cache info of unrevoked certificates.
+ */
+ public Hashtable<BigInteger, RevokedCertificate> getUnrevokedCerts() {
+ return null;
+ }
+
+ /**
+ * Retrieves cache info of expired certificates.
+ */
+ public Hashtable<BigInteger, RevokedCertificate> getExpiredCerts() {
+ return null;
+ }
+
+ public Enumeration<String> 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<String> getElements() {
+ return null;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/password/PasswordChecker.java b/base/common/src/com/netscape/cms/password/PasswordChecker.java
new file mode 100644
index 000000000..847f3a2c1
--- /dev/null
+++ b/base/common/src/com/netscape/cms/password/PasswordChecker.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.password;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.password.EPasswordCheckException;
+import com.netscape.certsrv.password.IConfigPasswordCheck;
+import com.netscape.certsrv.password.IPasswordCheck;
+
+/**
+ * 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) {
+ return false;
+ } else if (mPassword.length() < 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) {
+ return false;
+ } else if (mPassword.length() < 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/base/common/src/com/netscape/cms/policy/APolicyRule.java b/base/common/src/com/netscape/cms/policy/APolicyRule.java
new file mode 100644
index 000000000..0faf7591d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/APolicyRule.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.cms.policy;
+
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.KeyIdentifier;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import com.netscape.certsrv.apps.CMS;
+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.policy.EPolicyException;
+import com.netscape.certsrv.policy.IExpression;
+import com.netscape.certsrv.policy.IPolicyRule;
+import com.netscape.certsrv.request.AgentApprovals;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+
+/**
+ * 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<String> getInstanceParams();
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public abstract Vector<String> 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<String> ev = req.getExtDataInStringVector(IRequest.ERRORS);
+ if (ev == null) {
+ ev = new Vector<String>();
+ }
+ 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<String> ev = req.getExtDataInStringVector(IRequest.ERRORS);
+ if (ev == null) {
+ ev = new Vector<String>();
+ }
+ 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/base/common/src/com/netscape/cms/policy/constraints/AgentPolicy.java b/base/common/src/com/netscape/cms/policy/constraints/AgentPolicy.java
new file mode 100644
index 000000000..b7a24bd65
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/constraints/AgentPolicy.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.policy.constraints;
+
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.policy.EPolicyException;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.request.AgentApprovals;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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 {
+ @SuppressWarnings("unchecked")
+ Class<APolicyRule> c = (Class<APolicyRule>) 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<String> getInstanceParams() {
+ return null;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector<String> getDefaultParams() {
+ return null;
+ }
+
+ APolicyRule mPolicy = null;
+}
diff --git a/base/common/src/com/netscape/cms/policy/constraints/AttributePresentConstraints.java b/base/common/src/com/netscape/cms/policy/constraints/AttributePresentConstraints.java
new file mode 100644
index 000000000..93327445e
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/constraints/AttributePresentConstraints.java
@@ -0,0 +1,406 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+
+import com.netscape.certsrv.apps.CMS;
+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.ldap.ILdapConnFactory;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.request.RequestId;
+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 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<String> mParamNames;
+ protected static Hashtable<String, Object> mParamDefault;
+ protected Hashtable<String, Object> mParamValue = null;
+
+ static {
+ mParamNames = new Vector<String>();
+ mParamDefault = new Hashtable<String, Object>();
+ 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<String, Object>();
+
+ 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<String> getInstanceParams() {
+ Vector<String> params = new Vector<String>();
+
+ Enumeration<String> 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<String> getDefaultParams() {
+ Vector<String> params = new Vector<String>();
+
+ Enumeration<String> 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/base/common/src/com/netscape/cms/policy/constraints/DSAKeyConstraints.java b/base/common/src/com/netscape/cms/policy/constraints/DSAKeyConstraints.java
new file mode 100644
index 000000000..387b702bf
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/constraints/DSAKeyConstraints.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.constraints;
+
+import java.math.BigInteger;
+import java.security.interfaces.DSAParams;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.provider.DSAPublicKey;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import com.netscape.certsrv.apps.CMS;
+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.logging.ILogger;
+import com.netscape.certsrv.policy.EPolicyException;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<String> defConfParams = new Vector<String>();
+
+ 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.
+ 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<String> getInstanceParams() {
+ Vector<String> confParams = new Vector<String>();
+
+ 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<String> getDefaultParams() {
+ return defConfParams;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/policy/constraints/DefaultRevocation.java b/base/common/src/com/netscape/cms/policy/constraints/DefaultRevocation.java
new file mode 100644
index 000000000..2af145475
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/constraints/DefaultRevocation.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.policy.constraints;
+
+import java.util.Locale;
+import java.util.Vector;
+
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.policy.EPolicyException;
+import com.netscape.certsrv.policy.IRevocationPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<String> getInstanceParams() {
+ return null;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector<String> getDefaultParams() {
+ return null;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ IExtendedPluginInfo.HELP_TOKEN + ";configuration-policyrules-defaultrevocation"
+ };
+
+ return params;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/policy/constraints/IssuerConstraints.java b/base/common/src/com/netscape/cms/policy/constraints/IssuerConstraints.java
new file mode 100644
index 000000000..a08bde78c
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/constraints/IssuerConstraints.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.policy.constraints;
+
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.policy.EPolicyException;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<String> getInstanceParams() {
+ Vector<String> confParams = new Vector<String>();
+
+ 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<String> getDefaultParams() {
+ Vector<String> defParams = new Vector<String>();
+
+ defParams.addElement(PROP_ISSUER_DN + "=");
+ return defParams;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/policy/constraints/KeyAlgorithmConstraints.java b/base/common/src/com/netscape/cms/policy/constraints/KeyAlgorithmConstraints.java
new file mode 100644
index 000000000..3779b16e3
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/constraints/KeyAlgorithmConstraints.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.policy.constraints;
+
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.policy.EPolicyException;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<String> 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<String> defConfParams = new Vector<String>();
+
+ 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<String>();
+
+ 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<String> e = mAlgorithms.elements(); e.hasMoreElements();) {
+ int i;
+ String configuredAlg = 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<String> getInstanceParams() {
+ Vector<String> v = new Vector<String>();
+ StringBuffer sb = new StringBuffer();
+
+ for (Enumeration<String> e = mAlgorithms.elements(); e.hasMoreElements();) {
+ sb.append(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<String> getDefaultParams() {
+ return defConfParams;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/policy/constraints/ManualAuthentication.java b/base/common/src/com/netscape/cms/policy/constraints/ManualAuthentication.java
new file mode 100644
index 000000000..3af9e636f
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/constraints/ManualAuthentication.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.policy.constraints;
+
+import java.util.Vector;
+
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.policy.EPolicyException;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<String> getInstanceParams() {
+ return null;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector<String> getDefaultParams() {
+ return null;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/policy/constraints/RSAKeyConstraints.java b/base/common/src/com/netscape/cms/policy/constraints/RSAKeyConstraints.java
new file mode 100644
index 000000000..7c53808c5
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/constraints/RSAKeyConstraints.java
@@ -0,0 +1,280 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.security.provider.RSAPublicKey;
+import netscape.security.util.BigInt;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import com.netscape.certsrv.apps.CMS;
+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.policy.EPolicyException;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<BigInt> 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<String> defConfParams = new Vector<String>();
+
+ 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<BigInt>();
+
+ // 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<BigInt> 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<String> getInstanceParams() {
+ Vector<String> confParams = new Vector<String>();
+
+ confParams.addElement(PROP_MIN_SIZE + "=" + mMinSize);
+ confParams.addElement(PROP_MAX_SIZE + "=" + mMaxSize);
+ StringBuffer sb = new StringBuffer();
+
+ for (Enumeration<BigInt> e = mExponents.elements(); e.hasMoreElements();) {
+ sb.append(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<String> getDefaultParams() {
+ return defConfParams;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/policy/constraints/RenewalConstraints.java b/base/common/src/com/netscape/cms/policy/constraints/RenewalConstraints.java
new file mode 100644
index 000000000..f3e5efc9b
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/constraints/RenewalConstraints.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.policy.constraints;
+
+import java.util.Date;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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.policy.EPolicyException;
+import com.netscape.certsrv.policy.IRenewalPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<String> defConfParams = new Vector<String>();
+ 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<String> getInstanceParams() {
+ Vector<String> confParams = new Vector<String>();
+
+ 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<String> getDefaultParams() {
+ return defConfParams;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/policy/constraints/RenewalValidityConstraints.java b/base/common/src/com/netscape/cms/policy/constraints/RenewalValidityConstraints.java
new file mode 100644
index 000000000..0265ff855
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/constraints/RenewalValidityConstraints.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.constraints;
+
+import java.util.Date;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.policy.EPolicyException;
+import com.netscape.certsrv.policy.IRenewalPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.cms.policy.APolicyRule;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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<String> defConfParams = new Vector<String>();
+
+ 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<String> getInstanceParams() {
+ Vector<String> confParams = new Vector<String>();
+
+ 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<String> 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 = Utils.base64encode(ba);
+
+ sb.append(CERT_HEADER + encodedCert + CERT_TRAILER);
+ } catch (Exception e) {
+ //throw new AssertionException(e.toString());
+ }
+ }
+ return sb.toString();
+ }
+}
diff --git a/base/common/src/com/netscape/cms/policy/constraints/RevocationConstraints.java b/base/common/src/com/netscape/cms/policy/constraints/RevocationConstraints.java
new file mode 100644
index 000000000..513e199c4
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/constraints/RevocationConstraints.java
@@ -0,0 +1,215 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Date;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.RevocationReason;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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.policy.EPolicyException;
+import com.netscape.certsrv.policy.IRevocationPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<String> defConfParams = new Vector<String>();
+ 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<String> getInstanceParams() {
+ Vector<String> confParams = new Vector<String>();
+
+ 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<String> getDefaultParams() {
+ return defConfParams;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/policy/constraints/SigningAlgorithmConstraints.java b/base/common/src/com/netscape/cms/policy/constraints/SigningAlgorithmConstraints.java
new file mode 100644
index 000000000..8b504eb50
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/constraints/SigningAlgorithmConstraints.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.policy.constraints;
+
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateAlgorithmId;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+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.logging.ILogger;
+import com.netscape.certsrv.policy.EPolicyException;
+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;
+
+/**
+ * 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<String> defConfParams = new Vector<String>();
+
+ 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<String> algs = new Vector<String>();
+
+ 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<String> goodAlgs = new Vector<String>();
+
+ 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<String> getInstanceParams() {
+ Vector<String> confParams = new Vector<String>();
+ 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<String> 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/base/common/src/com/netscape/cms/policy/constraints/SubCANameConstraints.java b/base/common/src/com/netscape/cms/policy/constraints/SubCANameConstraints.java
new file mode 100644
index 000000000..da63f6f24
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/constraints/SubCANameConstraints.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.policy.constraints;
+
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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.certsrv.security.ISigningUnit;
+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<String> getInstanceParams() {
+ Vector<String> v = new Vector<String>();
+
+ return v;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector<String> getDefaultParams() {
+ Vector<String> v = new Vector<String>();
+
+ return v;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectName.java b/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectName.java
new file mode 100644
index 000000000..9afbf7650
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectName.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.cms.policy.constraints;
+
+/**
+ * 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/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectNameConstraints.java b/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectNameConstraints.java
new file mode 100644
index 000000000..8c106800a
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectNameConstraints.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.policy.constraints;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.KeyUsageExtension;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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.dbs.certdb.ICertRecord;
+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;
+
+/**
+ * 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<ICertRecord> matched =
+ mCA.getCertificateRepository().findCertRecords(filter);
+
+ while (matched.hasMoreElements()) {
+ ICertRecord rec = 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<String> getInstanceParams() {
+ Vector<String> confParams = new Vector<String>();
+
+ 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<String> getDefaultParams() {
+ Vector<String> defParams = new Vector<String>();
+
+ defParams.addElement(PROP_PRE_AGENT_APPROVAL_CHECKING + "=");
+ defParams.addElement(PROP_KEY_USAGE_EXTENSION_CHECKING + "=");
+ return defParams;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/policy/constraints/ValidityConstraints.java b/base/common/src/com/netscape/cms/policy/constraints/ValidityConstraints.java
new file mode 100644
index 000000000..0409f3c33
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/constraints/ValidityConstraints.java
@@ -0,0 +1,317 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Date;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.policy.EPolicyException;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<String> defConfParams = new Vector<String>();
+
+ 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<String> getInstanceParams() {
+ Vector<String> confParams = new Vector<String>();
+
+ 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<String> 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/base/common/src/com/netscape/cms/policy/extensions/AuthInfoAccessExt.java b/base/common/src/com/netscape/cms/policy/extensions/AuthInfoAccessExt.java
new file mode 100644
index 000000000..fea126567
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/AuthInfoAccessExt.java
@@ -0,0 +1,394 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.io.Serializable;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.extensions.AuthInfoAccessExtension;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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.logging.ILogger;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.policy.IGeneralNameUtil;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<String> v = new Vector<String>();
+
+ 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<Vector<Serializable>> getAccessDescriptions() throws EBaseException {
+ Vector<Vector<Serializable>> ads = new Vector<Vector<Serializable>>();
+
+ //
+ // 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<Serializable> e = new Vector<Serializable>();
+
+ 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<Vector<Serializable>> 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<Serializable> ad = 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<String> getInstanceParams() {
+ Vector<String> params = new Vector<String>();
+
+ 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<String> getDefaultParams() {
+ Vector<String> defParams = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/policy/extensions/AuthorityKeyIdentifierExt.java b/base/common/src/com/netscape/cms/policy/extensions/AuthorityKeyIdentifierExt.java
new file mode 100644
index 000000000..971379a46
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/AuthorityKeyIdentifierExt.java
@@ -0,0 +1,425 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.AuthorityKeyIdentifierExtension;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.KeyIdentifier;
+import netscape.security.x509.SubjectKeyIdentifierExtension;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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;
+
+/**
+ * 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<String> mInstanceParams = new Vector<String>();
+
+ // default params for console.
+ protected static Vector<String> mDefaultParams = new Vector<String>();
+ 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<String> getInstanceParams() {
+ return mInstanceParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector<String> 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/base/common/src/com/netscape/cms/policy/extensions/BasicConstraintsExt.java b/base/common/src/com/netscape/cms/policy/extensions/BasicConstraintsExt.java
new file mode 100644
index 000000000..f830b7e3d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/BasicConstraintsExt.java
@@ -0,0 +1,508 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.x509.BasicConstraintsExtension;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotDefined;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.policy.EPolicyException;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.policy.IPolicyProcessor;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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) {
+
+ // 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<String> getInstanceParams() {
+ Vector<String> params = new Vector<String>();
+
+ // 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<String> getDefaultParams() {
+ Vector<String> defParams = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/policy/extensions/CRLDistributionPointsExt.java b/base/common/src/com/netscape/cms/policy/extensions/CRLDistributionPointsExt.java
new file mode 100644
index 000000000..1ede3d5d0
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/CRLDistributionPointsExt.java
@@ -0,0 +1,484 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.util.Hashtable;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.security.util.BitArray;
+import netscape.security.x509.CRLDistributionPoint;
+import netscape.security.x509.CRLDistributionPointsExtension;
+import netscape.security.x509.CRLDistributionPointsExtension.Reason;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.GeneralNamesException;
+import netscape.security.x509.RDN;
+import netscape.security.x509.URIName;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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.logging.ILogger;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<String, NameType> map = new Hashtable<String, NameType>();
+
+ /**
+ * Looks up a NameType from its string representation. Returns null
+ * if no matching NameType was found.
+ */
+ public static NameType fromString(String s) {
+ return 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<String> defaultParams = new Vector<String>();
+
+ private Vector<String> mParams = new Vector<String>();
+ 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<String> v = new Vector<String>();
+
+ // 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<String> 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<String> getInstanceParams() {
+ return mParams;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/policy/extensions/CertificatePoliciesExt.java b/base/common/src/com/netscape/cms/policy/extensions/CertificatePoliciesExt.java
new file mode 100644
index 000000000..597357318
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/CertificatePoliciesExt.java
@@ -0,0 +1,534 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CPSuri;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificatePoliciesExtension;
+import netscape.security.x509.CertificatePolicyId;
+import netscape.security.x509.CertificatePolicyInfo;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.DisplayText;
+import netscape.security.x509.NoticeReference;
+import netscape.security.x509.PolicyQualifierInfo;
+import netscape.security.x509.PolicyQualifiers;
+import netscape.security.x509.UserNotice;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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.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;
+
+/**
+ * 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<String> mInstanceParams = new Vector<String>();
+ 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<CertificatePolicyInfo> CertPolicies = new Vector<CertificatePolicyInfo>();
+
+ 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<String> 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<String> mDefParams = new Vector<String>();
+ 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<String> getDefaultParams() {
+ return mDefParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ Vector<String> theparams = new Vector<String>();
+
+ 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.
+
+ if (mPolicyId != null)
+ 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<String> numsVector = new Vector<String>();
+ 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(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<String> 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/base/common/src/com/netscape/cms/policy/extensions/CertificateRenewalWindowExt.java b/base/common/src/com/netscape/cms/policy/extensions/CertificateRenewalWindowExt.java
new file mode 100644
index 000000000..28366ade8
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/CertificateRenewalWindowExt.java
@@ -0,0 +1,254 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.util.Date;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.extensions.CertificateRenewalWindowExtension;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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.logging.ILogger;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<String> getInstanceParams() {
+ Vector<String> params = new Vector<String>();
+
+ 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<String> getDefaultParams() {
+ Vector<String> defParams = new Vector<String>();
+
+ defParams.addElement(PROP_CRITICAL + "=false");
+ defParams.addElement(PROP_BEGIN_TIME + "=");
+ defParams.addElement(PROP_END_TIME + "=");
+ return defParams;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/policy/extensions/CertificateScopeOfUseExt.java b/base/common/src/com/netscape/cms/policy/extensions/CertificateScopeOfUseExt.java
new file mode 100644
index 000000000..b385923af
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/CertificateScopeOfUseExt.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.policy.extensions;
+
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.extensions.CertificateScopeEntry;
+import netscape.security.extensions.CertificateScopeOfUseExtension;
+import netscape.security.util.BigInt;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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.logging.ILogger;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.policy.IGeneralNameUtil;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<String> v = new Vector<String>();
+
+ 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<CertificateScopeEntry> getScopeEntries() throws EBaseException {
+ Vector<CertificateScopeEntry> entries = new Vector<CertificateScopeEntry>();
+
+ //
+ // 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<CertificateScopeEntry> 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<String> getInstanceParams() {
+ Vector<String> params = new Vector<String>();
+
+ 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<String> getDefaultParams() {
+ Vector<String> defParams = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/policy/extensions/ExtendedKeyUsageExt.java b/base/common/src/com/netscape/cms/policy/extensions/ExtendedKeyUsageExt.java
new file mode 100644
index 000000000..65ef6b937
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/ExtendedKeyUsageExt.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.cms.policy.extensions;
+
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.extensions.ExtendedKeyUsageExtension;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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.logging.ILogger;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<ObjectIdentifier> 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<String> getInstanceParams() {
+ Vector<String> params = new Vector<String>();
+
+ 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<String> v = new Vector<String>();
+ 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<String> getDefaultParams() {
+ Vector<String> defParams = new Vector<String>();
+
+ 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<ObjectIdentifier>();
+ }
+
+ 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/base/common/src/com/netscape/cms/policy/extensions/GenericASN1Ext.java b/base/common/src/com/netscape/cms/policy/extensions/GenericASN1Ext.java
new file mode 100644
index 000000000..0202ee784
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/GenericASN1Ext.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.policy.extensions;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.text.ParseException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.extensions.GenericASN1Extension;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.OIDMap;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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.logging.ILogger;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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(priExt.getName(), 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<String, String> h = new Hashtable<String, String>();
+ // This only show one level, not substores!
+ Enumeration<String> 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<String> getInstanceParams() {
+ int idx = 0;
+ Vector<String> params = new Vector<String>();
+
+ 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<String> getDefaultParams() {
+ int idx = 0;
+
+ Vector<String> defParams = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/policy/extensions/IssuerAltNameExt.java b/base/common/src/com/netscape/cms/policy/extensions/IssuerAltNameExt.java
new file mode 100644
index 000000000..bb9abd9cf
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/IssuerAltNameExt.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.extensions;
+
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.IssuerAlternativeNameExtension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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.logging.ILogger;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.policy.IGeneralNamesConfig;
+import com.netscape.certsrv.policy.IPolicyProcessor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<String> defaultParams = new Vector<String>();
+ private static String[] mInfo = null;
+
+ static {
+ defaultParams.addElement(PROP_CRITICAL + "=" + DEFAULT_CRITICALITY);
+ CMS.getGeneralNamesConfigDefaultParams(null, true, defaultParams);
+
+ Vector<String> info = new Vector<String>();
+
+ 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<String> mParams = new Vector<String>();
+ 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);
+
+ 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 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<String> getInstanceParams() {
+ return mParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return Empty Vector since this policy implementation has no
+ * configuration parameters.
+ */
+ public Vector<String> getDefaultParams() {
+ return defaultParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ return mInfo;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/policy/extensions/KeyUsageExt.java b/base/common/src/com/netscape/cms/policy/extensions/KeyUsageExt.java
new file mode 100644
index 000000000..6594cc4a2
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/KeyUsageExt.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.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.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.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;
+
+/**
+ * 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) {
+
+ 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<String> getInstanceParams() {
+ Vector<String> params = new Vector<String>();
+
+ 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<String> mDefParams = new Vector<String>();
+ 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<String> 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/base/common/src/com/netscape/cms/policy/extensions/NSCCommentExt.java b/base/common/src/com/netscape/cms/policy/extensions/NSCCommentExt.java
new file mode 100644
index 000000000..ecc084d29
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/NSCCommentExt.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.policy.extensions;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.NSCCommentExtension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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.logging.ILogger;
+import com.netscape.certsrv.policy.EPolicyException;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<String> mParams = new Vector<String>();
+
+ 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;
+
+ 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<String> getInstanceParams() {
+ return mParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector<String> getDefaultParams() {
+ Vector<String> defParams = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/policy/extensions/NSCertTypeExt.java b/base/common/src/com/netscape/cms/policy/extensions/NSCertTypeExt.java
new file mode 100644
index 000000000..2fb09b2b7
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/NSCertTypeExt.java
@@ -0,0 +1,535 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.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()");
+
+ 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 {
+ 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<String> getInstanceParams() {
+ Vector<String> params = new Vector<String>();
+
+ params.addElement(PROP_CRITICAL + "=" + mCritical);
+ params.addElement(PROP_SET_DEFAULT_BITS + "=" + mSetDefaultBits);
+ //new Boolean(mSetDefaultBits).toString());
+ return params;
+ }
+
+ private static Vector<String> mDefParams = new Vector<String>();
+ 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<String> getDefaultParams() {
+ return mDefParams;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/policy/extensions/NameConstraintsExt.java b/base/common/src/com/netscape/cms/policy/extensions/NameConstraintsExt.java
new file mode 100644
index 000000000..f010bf3f1
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/NameConstraintsExt.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.cms.policy.extensions;
+
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.GeneralSubtree;
+import netscape.security.x509.GeneralSubtrees;
+import netscape.security.x509.NameConstraintsExtension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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.logging.ILogger;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.policy.IGeneralNameAsConstraintsConfig;
+import com.netscape.certsrv.policy.IPolicyProcessor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<String> mInstanceParams = new Vector<String>();
+
+ 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<GeneralSubtree> permittedSubtrees = new Vector<GeneralSubtree>();
+
+ for (int i = 0; i < mNumPermittedSubtrees; i++) {
+ permittedSubtrees.addElement(
+ mPermittedSubtrees[i].mGeneralSubtree);
+ }
+ Vector<GeneralSubtree> excludedSubtrees = new Vector<GeneralSubtree>();
+
+ 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<String> 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<String> mDefParams = new Vector<String>();
+ 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<String> getDefaultParams() {
+ return mDefParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ Vector<String> theparams = new Vector<String>();
+
+ 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<String> instanceParams) {
+ mBase.getInstanceParams(instanceParams);
+ instanceParams.addElement(mNameDotMin + "=" + mMin);
+ instanceParams.addElement(mNameDotMax + "=" + mMax);
+ }
+
+ static void getDefaultParams(String name, Vector<String> 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<String> 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/base/common/src/com/netscape/cms/policy/extensions/OCSPNoCheckExt.java b/base/common/src/com/netscape/cms/policy/extensions/OCSPNoCheckExt.java
new file mode 100644
index 000000000..33f2f85e0
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/OCSPNoCheckExt.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.policy.extensions;
+
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.extensions.OCSPNoCheckExtension;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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.logging.ILogger;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<String> getInstanceParams() {
+ Vector<String> params = new Vector<String>();
+
+ params.addElement(PROP_CRITICAL + "=" + mCritical);
+ return params;
+
+ }
+
+ /**
+ * Returns default parameters.
+ */
+ public Vector<String> getDefaultParams() {
+ Vector<String> defParams = new Vector<String>();
+
+ defParams.addElement(PROP_CRITICAL + "=false");
+ return defParams;
+
+ }
+}
diff --git a/base/common/src/com/netscape/cms/policy/extensions/PolicyConstraintsExt.java b/base/common/src/com/netscape/cms/policy/extensions/PolicyConstraintsExt.java
new file mode 100644
index 000000000..861107b8e
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/PolicyConstraintsExt.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.policy.extensions;
+
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.PolicyConstraintsExtension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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.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;
+
+/**
+ * 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<String> mInstanceParams = new Vector<String>();
+
+ protected static Vector<String> mDefaultParams = new Vector<String>();
+ 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<String> getInstanceParams() {
+ return mInstanceParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector<String> 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/base/common/src/com/netscape/cms/policy/extensions/PolicyMappingsExt.java b/base/common/src/com/netscape/cms/policy/extensions/PolicyMappingsExt.java
new file mode 100644
index 000000000..7623f455f
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/PolicyMappingsExt.java
@@ -0,0 +1,426 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.util.Locale;
+import java.util.Vector;
+
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificatePolicyId;
+import netscape.security.x509.CertificatePolicyMap;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.PolicyMappingsExtension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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.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;
+
+/**
+ * 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<String> mInstanceParams = new Vector<String>();
+
+ 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<CertificatePolicyMap> certPolicyMaps = new Vector<CertificatePolicyMap>();
+
+ 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<String> 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<String> mDefParams = new Vector<String>();
+ 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<String> getDefaultParams() {
+ return mDefParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ Vector<String> theparams = new Vector<String>();
+
+ 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<String> instanceParams) {
+ instanceParams.addElement(
+ mNameDot + PROP_ISSUER_DOMAIN_POLICY + "=" + (mIssuerDomainPolicy == null ? "" :
+ mIssuerDomainPolicy));
+ instanceParams.addElement(
+ mNameDot + PROP_SUBJECT_DOMAIN_POLICY + "=" + (mSubjectDomainPolicy == null ? "" :
+ mSubjectDomainPolicy));
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/policy/extensions/PresenceExt.java b/base/common/src/com/netscape/cms/policy/extensions/PresenceExt.java
new file mode 100644
index 000000000..e13a7a84c
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/PresenceExt.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.policy.extensions;
+
+import java.util.Locale;
+import java.util.Vector;
+
+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.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<String> mDefParams = new Vector<String>();
+ 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<String> getInstanceParams() {
+ Vector<String> params = new Vector<String>();
+
+ 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<String> getDefaultParams() {
+ return mDefParams;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/policy/extensions/PrivateKeyUsagePeriodExt.java b/base/common/src/com/netscape/cms/policy/extensions/PrivateKeyUsagePeriodExt.java
new file mode 100644
index 000000000..3b80246a9
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/PrivateKeyUsagePeriodExt.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.io.IOException;
+import java.security.cert.CertificateException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.PrivateKeyUsageExtension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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.logging.ILogger;
+import com.netscape.certsrv.policy.EPolicyException;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<String> defaultParams;
+
+ static {
+
+ formatter.setLenient(false);
+
+ defaultParams = new Vector<String>();
+ 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 for errors
+ formatter.format(formatter.parse(mNotBefore.trim()));
+ 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) {
+
+ // 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<String> getInstanceParams() {
+ Vector<String> params = new Vector<String>();
+
+ 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<String> getDefaultParams() {
+ Vector<String> defParams = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/policy/extensions/RemoveBasicConstraintsExt.java b/base/common/src/com/netscape/cms/policy/extensions/RemoveBasicConstraintsExt.java
new file mode 100644
index 000000000..2a5af4240
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/RemoveBasicConstraintsExt.java
@@ -0,0 +1,143 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.BasicConstraintsExtension;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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) {
+
+ // 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<String> getInstanceParams() {
+ Vector<String> params = new Vector<String>();
+
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector<String> getDefaultParams() {
+ Vector<String> defParams = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/policy/extensions/SubjAltNameExt.java b/base/common/src/com/netscape/cms/policy/extensions/SubjAltNameExt.java
new file mode 100644
index 000000000..63bd8804c
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/SubjAltNameExt.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.cms.policy.extensions;
+
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.RFC822Name;
+import netscape.security.x509.SubjectAlternativeNameExtension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+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.logging.ILogger;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<String> 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 */<String>
+ getEmailList(IAuthToken tok) {
+
+ Vector<String> v = new Vector<String>();
+
+ 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<String> 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<String> emails)
+ throws IOException {
+ SubjectAlternativeNameExtension sa;
+ GeneralNames gns = new GeneralNames();
+
+ for (int i = 0; i < emails.size(); i++) {
+ String email = 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<String> getInstanceParams() {
+ Vector<String> params = new Vector<String>();
+
+ //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<String> getDefaultParams() {
+ Vector<String> defParams = new Vector<String>();
+
+ //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/base/common/src/com/netscape/cms/policy/extensions/SubjectAltNameExt.java b/base/common/src/com/netscape/cms/policy/extensions/SubjectAltNameExt.java
new file mode 100644
index 000000000..62f0b21da
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/SubjectAltNameExt.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.cms.policy.extensions;
+
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.SubjectAlternativeNameExtension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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.logging.ILogger;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.policy.IGeneralNameUtil;
+import com.netscape.certsrv.policy.IPolicyProcessor;
+import com.netscape.certsrv.policy.ISubjAltNameConfig;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<String> mInstanceParams = new Vector<String>();
+
+ // init default params and extended plugin info.
+ private static Vector<String> mDefParams = new Vector<String>();
+ 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<GeneralName> gn = mGNs[i].formGeneralNames(value);
+
+ if (gn.size() == 0)
+ continue;
+ for (Enumeration<GeneralName> n = gn.elements(); n.hasMoreElements();) {
+ gns.addElement(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<String> getInstanceParams() {
+ return mInstanceParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector<String> getDefaultParams() {
+ return mDefParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+
+ // extended plugin info.
+ Vector<String> info = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/policy/extensions/SubjectDirectoryAttributesExt.java b/base/common/src/com/netscape/cms/policy/extensions/SubjectDirectoryAttributesExt.java
new file mode 100644
index 000000000..6b4e7ead9
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/SubjectDirectoryAttributesExt.java
@@ -0,0 +1,428 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.AVAValueConverter;
+import netscape.security.x509.Attribute;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.SubjectDirAttributesExtension;
+import netscape.security.x509.X500NameAttrMap;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+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.logging.ILogger;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+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<String> mParams = new Vector<String>();
+ private String[] mEPI = null; // extended plugin info
+ protected static Vector<String> mDefParams = new Vector<String>();
+
+ 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) {
+ 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;
+
+ 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;
+ }
+ }
+
+ public Vector<String> getInstanceParams() {
+ return mParams; // inited in init()
+ }
+
+ public Vector<String> 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<String> v = new Vector<String>();
+
+ 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<Attribute> attrs = new Vector<Attribute>();
+
+ // 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<String> 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<String> 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<String> 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<String> n = X500NameAttrMap.getDefault().getAllNames();
+ StringBuffer sb = new StringBuffer();
+ sb.append(n.nextElement());
+
+ while (n.hasMoreElements()) {
+ sb.append(",");
+ sb.append(n.nextElement());
+ }
+ return sb.toString();
+ }
+
+ private static void checkValue(ObjectIdentifier oid, String val)
+ throws IOException {
+ AVAValueConverter c = X500NameAttrMap.getDefault().getValueConverter(oid);
+
+ @SuppressWarnings("unused")
+ DerValue derval = c.getValue(val); // check for errors
+ return;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/policy/extensions/SubjectKeyIdentifierExt.java b/base/common/src/com/netscape/cms/policy/extensions/SubjectKeyIdentifierExt.java
new file mode 100644
index 000000000..32d254c40
--- /dev/null
+++ b/base/common/src/com/netscape/cms/policy/extensions/SubjectKeyIdentifierExt.java
@@ -0,0 +1,377 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.KeyIdentifier;
+import netscape.security.x509.SubjectKeyIdentifierExtension;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import com.netscape.certsrv.apps.CMS;
+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.logging.ILogger;
+import com.netscape.certsrv.policy.EPolicyException;
+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;
+
+/**
+ * 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<String> mInstanceParams = new Vector<String>();
+
+ protected static Vector<String> mDefaultParams = new Vector<String>();
+ 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<String> getInstanceParams() {
+ return mInstanceParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector<String> 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/base/common/src/com/netscape/cms/profile/common/BasicProfile.java b/base/common/src/com/netscape/cms/profile/common/BasicProfile.java
new file mode 100644
index 000000000..696d0cd13
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/common/BasicProfile.java
@@ -0,0 +1,1171 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IPolicyConstraint;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileAuthenticator;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.profile.IProfileOutput;
+import com.netscape.certsrv.profile.IProfilePolicy;
+import com.netscape.certsrv.profile.IProfileSubsystem;
+import com.netscape.certsrv.profile.IProfileUpdater;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.registry.IPluginInfo;
+import com.netscape.certsrv.registry.IPluginRegistry;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+
+/**
+ * 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<String> mInputNames = new Vector<String>();
+ protected Hashtable<String, IProfileInput> mInputs = new Hashtable<String, IProfileInput>();
+ protected Vector<String> mInputIds = new Vector<String>();
+ protected Hashtable<String, IProfileOutput> mOutputs = new Hashtable<String, IProfileOutput>();
+ protected Vector<String> mOutputIds = new Vector<String>();
+ protected Hashtable<String, IProfileUpdater> mUpdaters = new Hashtable<String, IProfileUpdater>();
+ protected Vector<String> mUpdaterIds = new Vector<String>();
+ protected IProfileAuthenticator mAuthenticator = null;
+ protected String mAuthInstanceId = null;
+ protected String mId = null;
+ protected String mAuthzAcl = "";
+
+ protected Hashtable<String, Vector<ProfilePolicy>> mPolicySet = new Hashtable<String, Vector<ProfilePolicy>>();
+
+ 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 = 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 = 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 = 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 = st.nextToken();
+
+ IConfigStore policyStore = policySetStore.getSubStore(setId);
+ String list = policyStore.getString(PROP_POLICY_LIST, "");
+ StringTokenizer st1 = new StringTokenizer(list, ",");
+
+ while (st1.hasMoreTokens()) {
+ String id = 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<String> getInputNames() {
+ return mInputNames.elements();
+ }
+
+ public Enumeration<String> getProfileUpdaterIds() {
+ return mUpdaterIds.elements(); // ordered list
+ }
+
+ public IProfileUpdater getProfileUpdater(String name) {
+ return mUpdaters.get(name);
+ }
+
+ public Enumeration<String> getProfileOutputIds() {
+ return mOutputIds.elements(); // ordered list
+ }
+
+ public IProfileOutput getProfileOutput(String name) {
+ return mOutputs.get(name);
+ }
+
+ public Enumeration<String> getProfileInputIds() {
+ return mInputIds.elements(); // ordered list
+ }
+
+ public IProfileInput getProfileInput(String name) {
+ return 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<String> getProfilePolicySetIds() {
+ return mPolicySet.keys();
+ }
+
+ public void deleteProfilePolicy(String setId, String policyId)
+ throws EProfileException {
+ Vector<ProfilePolicy> policies = 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();
+
+ for (int i = 0; i < size; i++) {
+ ProfilePolicy policy = 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();
+
+ for (int i = 0; i < size; i++) {
+ String id = 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();
+
+ for (int i = 0; i < size; i++) {
+ String id = 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");
+
+ 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);
+
+ for (String name : nvps.keySet()) {
+
+ outputStore.putString(prefix + "params." + name, nvps.get(name));
+ try {
+ if (output != null) {
+ output.setConfig(name, nvps.get(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");
+
+ 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);
+
+ for (String name : nvps.keySet()) {
+
+ inputStore.putString(prefix + "params." + name, nvps.get(name));
+ try {
+ if (input != null) {
+ input.setConfig(name, nvps.get(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<ProfilePolicy> policies = mPolicySet.get(setId);
+
+ IConfigStore policyStore = mConfig.getSubStore("policyset." + setId);
+ if (policies == null) {
+ policies = new Vector<ProfilePolicy>();
+ mPolicySet.put(setId, policies);
+ if (createConfig) {
+ // re-create policyset.list
+ StringBuffer setlist = new StringBuffer();
+ Enumeration<String> keys = mPolicySet.keys();
+
+ while (keys.hasMoreElements()) {
+ String k = 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 = 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 = 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!");
+ }
+
+ //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<ProfilePolicy> policies = mPolicySet.get(setId);
+
+ if (policies == null)
+ return null;
+
+ for (int i = 0; i < policies.size(); i++) {
+ ProfilePolicy policy = 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<String> ids = getProfileInputIds();
+
+ while (ids.hasMoreElements()) {
+ String id = ids.nextElement();
+ IProfileInput input = getProfileInput(id);
+
+ input.populate(ctx, request);
+ }
+ }
+
+ public Vector<ProfilePolicy> getPolicies(String setId) {
+ Vector<ProfilePolicy> policies = 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<ProfilePolicy> policies = getPolicies(setId);
+ CMS.debug("BasicProfile: populate() policy setid =" + setId);
+
+ for (int i = 0; i < policies.size(); i++) {
+ ProfilePolicy policy = 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<ProfilePolicy> policies = getPolicies(setId);
+
+ for (int i = 0; i < policies.size(); i++) {
+ ProfilePolicy policy = 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<ProfilePolicy> getProfilePolicies(String setId) {
+ Vector<ProfilePolicy> policies = mPolicySet.get(setId);
+
+ if (policies == null)
+ return null;
+ return policies.elements();
+ }
+
+ public Enumeration<String> getProfilePolicyIds(String setId) {
+ Vector<ProfilePolicy> policies = mPolicySet.get(setId);
+
+ if (policies == null)
+ return null;
+
+ Vector<String> v = new Vector<String>();
+
+ for (int i = 0; i < policies.size(); i++) {
+ ProfilePolicy policy = 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/base/common/src/com/netscape/cms/profile/common/CACertCAEnrollProfile.java b/base/common/src/com/netscape/cms/profile/common/CACertCAEnrollProfile.java
new file mode 100644
index 000000000..b95b22339
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/common/CACertCAEnrollProfile.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.common;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfileEx;
+import com.netscape.certsrv.profile.IProfilePolicy;
+
+/**
+ * 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();
+ createProfileInput("i1", "certReqInputImpl", inputParams1);
+ NameValuePairs inputParams2 = new NameValuePairs();
+ createProfileInput("i2", "submitterInfoInputImpl", inputParams2);
+
+ // create outputs
+ NameValuePairs outputParams1 = new NameValuePairs();
+ createProfileOutput("o1", "certOutputImpl", outputParams1);
+
+ // create policies
+ createProfilePolicy("set1", "p1",
+ "userSubjectNameDefaultImpl", "noConstraintImpl");
+
+ 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");
+
+ 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");
+
+ 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");
+
+ // 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");
+
+ 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");
+ }
+}
diff --git a/base/common/src/com/netscape/cms/profile/common/CAEnrollProfile.java b/base/common/src/com/netscape/cms/profile/common/CAEnrollProfile.java
new file mode 100644
index 000000000..c03f90a4b
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/common/CAEnrollProfile.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.profile.common;
+
+import java.util.Enumeration;
+
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import org.mozilla.jss.pkix.crmf.PKIArchiveOptions;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.ca.ICAService;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.connector.IConnector;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IProfileUpdater;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+
+/**
+ * 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<String> updaterIds = getProfileUpdaterIds();
+ while (updaterIds.hasMoreElements()) {
+ String updaterId = 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/base/common/src/com/netscape/cms/profile/common/EnrollProfile.java b/base/common/src/com/netscape/cms/profile/common/EnrollProfile.java
new file mode 100644
index 000000000..d574f0f94
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/common/EnrollProfile.java
@@ -0,0 +1,1468 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import netscape.security.pkcs.PKCS10;
+import netscape.security.pkcs.PKCS10Attribute;
+import netscape.security.pkcs.PKCS10Attributes;
+import netscape.security.pkcs.PKCS9Attribute;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateAlgorithmId;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateIssuerName;
+import netscape.security.x509.CertificateSerialNumber;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.Extension;
+import netscape.security.x509.Extensions;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.pkcs10.CertificationRequest;
+import org.mozilla.jss.pkcs10.CertificationRequestInfo;
+import org.mozilla.jss.pkix.cmc.LraPopWitness;
+import org.mozilla.jss.pkix.cmc.OtherMsg;
+import org.mozilla.jss.pkix.cmc.PKIData;
+import org.mozilla.jss.pkix.cmc.TaggedAttribute;
+import org.mozilla.jss.pkix.cmc.TaggedCertificationRequest;
+import org.mozilla.jss.pkix.cmc.TaggedRequest;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.crmf.CertTemplate;
+import org.mozilla.jss.pkix.crmf.PKIArchiveOptions;
+import org.mozilla.jss.pkix.crmf.ProofOfPossession;
+import org.mozilla.jss.pkix.primitive.AVA;
+import org.mozilla.jss.pkix.primitive.Attribute;
+import org.mozilla.jss.pkix.primitive.Name;
+import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authentication.ISharedToken;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EDeferException;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.cmsutil.util.HMACDigest;
+
+/**
+ * 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<String> 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);
+
+ 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();
+ 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");
+ savedToken = cm.getThreadToken();
+ CryptoToken signToken = null;
+ if (tokenName.equals("internal")) {
+ CMS.debug("EnrollProfile: parsePKCS10: use internal token");
+ signToken = cm.getInternalCryptoToken();
+ } else {
+ CMS.debug("EnrollProfile: parsePKCS10: tokenName=" + tokenName);
+ 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);
+ @SuppressWarnings("unused")
+ AlgorithmId mAlgId = AlgorithmId.parse(derSPKACContent[1]);
+ @SuppressWarnings("unused")
+ byte mSignature[] = derSPKACContent[2].getBitString();
+
+ /* get PKAC SPKI & Challenge */
+ byte mPKAC[] = derSPKACContent[0].toByteArray();
+
+ derIn = new DerInputStream(mPKAC);
+ DerValue derPKACContent[] = derIn.getSequence(2);
+
+ @SuppressWarnings("unused")
+ DerValue mDerSPKI = derPKACContent[0];
+ X509Key mSPKI = X509Key.parse(derPKACContent[0]);
+
+ @SuppressWarnings("unused")
+ 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();
+ CryptoToken verifyToken = null;
+ String tokenName = CMS.getConfigStore().getString("ca.requestVerify.token", "internal");
+ if (tokenName.equals("internal")) {
+ CMS.debug("POP verification using internal token");
+ certReqMsg.verify();
+ } else {
+ CMS.debug("POP verification using token:" + tokenName);
+ verifyToken = cm.getTokenByName(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/base/common/src/com/netscape/cms/profile/common/EnrollProfileContext.java b/base/common/src/com/netscape/cms/profile/common/EnrollProfileContext.java
new file mode 100644
index 000000000..3610520fd
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/common/EnrollProfileContext.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.cms.profile.common;
+
+import com.netscape.certsrv.profile.IProfileContext;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/common/ProfileContext.java b/base/common/src/com/netscape/cms/profile/common/ProfileContext.java
new file mode 100644
index 000000000..7d0686378
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/common/ProfileContext.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.cms.profile.common;
+
+import java.util.Hashtable;
+
+import com.netscape.certsrv.profile.IProfileContext;
+
+/**
+ * This class implements the profile context.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ProfileContext implements IProfileContext {
+ private Hashtable<String, String> m_Attrs = new Hashtable<String, String>();
+
+ public void set(String name, String value) {
+ m_Attrs.put(name, value);
+ }
+
+ public String get(String name) {
+ return m_Attrs.get(name);
+ }
+}
diff --git a/base/common/src/com/netscape/cms/profile/common/ProfilePolicy.java b/base/common/src/com/netscape/cms/profile/common/ProfilePolicy.java
new file mode 100644
index 000000000..a8a90aef9
--- /dev/null
+++ b/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.IPolicyConstraint;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfilePolicy;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/common/RAEnrollProfile.java b/base/common/src/com/netscape/cms/profile/common/RAEnrollProfile.java
new file mode 100644
index 000000000..36bac1fa7
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/common/RAEnrollProfile.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.cms.profile.common;
+
+import java.util.Enumeration;
+
+import netscape.security.x509.X500Name;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.connector.IConnector;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.ra.IRAService;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestListener;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestStatus;
+
+/**
+ * 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<String> names = ra.getRequestListenerNames();
+
+ if (names != null) {
+ while (names.hasMoreElements()) {
+ String name = names.nextElement();
+
+ CMS.debug("CAEnrollProfile: listener " + name);
+ IRequestListener listener = ra.getRequestListener(name);
+
+ if (listener != null) {
+ listener.accept(request);
+ }
+ }
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cms/profile/common/ServerCertCAEnrollProfile.java b/base/common/src/com/netscape/cms/profile/common/ServerCertCAEnrollProfile.java
new file mode 100644
index 000000000..9be1e43c4
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/common/ServerCertCAEnrollProfile.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.profile.common;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfileEx;
+import com.netscape.certsrv.profile.IProfilePolicy;
+
+/**
+ * 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();
+ createProfileInput("i1", "certReqInputImpl", inputParams1);
+ NameValuePairs inputParams2 = new NameValuePairs();
+ createProfileInput("i2", "submitterInfoInputImpl", inputParams2);
+
+ // create outputs
+ NameValuePairs outputParams1 = new NameValuePairs();
+ createProfileOutput("o1", "certOutputImpl", outputParams1);
+
+ createProfilePolicy("set1", "p1",
+ "userSubjectNameDefaultImpl", "noConstraintImpl");
+
+ 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");
+
+ 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");
+
+ 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");
+
+ 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");
+
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/profile/common/UserCertCAEnrollProfile.java b/base/common/src/com/netscape/cms/profile/common/UserCertCAEnrollProfile.java
new file mode 100644
index 000000000..3f1cdfb21
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/common/UserCertCAEnrollProfile.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.profile.common;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfileEx;
+import com.netscape.certsrv.profile.IProfilePolicy;
+
+/**
+ * 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();
+ createProfileInput("i1", "keyGenInputImpl", inputParams1);
+ NameValuePairs inputParams2 = new NameValuePairs();
+ createProfileInput("i2", "subjectNameInputImpl", inputParams2);
+ createProfileInput("i3", "submitterInfoInputImpl", inputParams2);
+
+ // create outputs
+ NameValuePairs outputParams1 = new NameValuePairs();
+ createProfileOutput("o1", "certOutputImpl", outputParams1);
+
+ // create policies
+ createProfilePolicy("set1", "p1",
+ "userSubjectNameDefaultImpl", "noConstraintImpl");
+
+ 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");
+
+ 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");
+
+ 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");
+
+ 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");
+ }
+}
diff --git a/base/common/src/com/netscape/cms/profile/constraint/BasicConstraintsExtConstraint.java b/base/common/src/com/netscape/cms/profile/constraint/BasicConstraintsExtConstraint.java
new file mode 100644
index 000000000..f924c587f
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/constraint/BasicConstraintsExtConstraint.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.profile.constraint;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import netscape.security.x509.BasicConstraintsExtension;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.def.BasicConstraintsExtDefault;
+import com.netscape.cms.profile.def.NoDefault;
+import com.netscape.cms.profile.def.UserExtensionDefault;
+
+/**
+ * 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 {
+
+ 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/base/common/src/com/netscape/cms/profile/constraint/CAEnrollConstraint.java b/base/common/src/com/netscape/cms/profile/constraint/CAEnrollConstraint.java
new file mode 100644
index 000000000..c0a9758da
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/constraint/CAEnrollConstraint.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.cms.profile.constraint;
+
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/constraint/CAValidityConstraint.java b/base/common/src/com/netscape/cms/profile/constraint/CAValidityConstraint.java
new file mode 100644
index 000000000..e118fa215
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/constraint/CAValidityConstraint.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.constraint;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.Locale;
+
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.def.CAValidityDefault;
+import com.netscape.cms.profile.def.NoDefault;
+import com.netscape.cms.profile.def.UserValidityDefault;
+import com.netscape.cms.profile.def.ValidityDefault;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/constraint/EnrollConstraint.java b/base/common/src/com/netscape/cms/profile/constraint/EnrollConstraint.java
new file mode 100644
index 000000000..40c2153a8
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/constraint/EnrollConstraint.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.cms.profile.constraint;
+
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IPolicyConstraint;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.common.EnrollProfile;
+
+/**
+ * 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<String> mConfigNames = new Vector<String>();
+
+ public EnrollConstraint() {
+ }
+
+ public Enumeration<String> 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<Extension> e = exts.getAttributes();
+
+ while (e.hasMoreElements()) {
+ Extension ext = 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/base/common/src/com/netscape/cms/profile/constraint/ExtendedKeyUsageExtConstraint.java b/base/common/src/com/netscape/cms/profile/constraint/ExtendedKeyUsageExtConstraint.java
new file mode 100644
index 000000000..3c737e8a5
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/constraint/ExtendedKeyUsageExtConstraint.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.cms.profile.constraint;
+
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.security.extensions.ExtendedKeyUsageExtension;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.def.ExtendedKeyUsageExtDefault;
+import com.netscape.cms.profile.def.NoDefault;
+import com.netscape.cms.profile.def.UserExtensionDefault;
+
+/**
+ * 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<String> mCache = new Vector<String>();
+ StringTokenizer st = new StringTokenizer(getConfig(CONFIG_OIDS), ",");
+
+ while (st.hasMoreTokens()) {
+ String oid = st.nextToken();
+
+ mCache.addElement(oid);
+ }
+
+ // check OIDs
+ Enumeration<ObjectIdentifier> e = ext.getOIDs();
+
+ while (e.hasMoreElements()) {
+ ObjectIdentifier oid = 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/base/common/src/com/netscape/cms/profile/constraint/ExtensionConstraint.java b/base/common/src/com/netscape/cms/profile/constraint/ExtensionConstraint.java
new file mode 100644
index 000000000..1562fddb8
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/constraint/ExtensionConstraint.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.profile.constraint;
+
+import java.util.Locale;
+
+import netscape.security.x509.Extension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.def.EnrollExtDefault;
+import com.netscape.cms.profile.def.NoDefault;
+import com.netscape.cms.profile.def.UserExtensionDefault;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/constraint/KeyConstraint.java b/base/common/src/com/netscape/cms/profile/constraint/KeyConstraint.java
new file mode 100644
index 000000000..e6f5019a0
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/constraint/KeyConstraint.java
@@ -0,0 +1,644 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.math.BigInteger;
+import java.security.interfaces.DSAParams;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.provider.DSAPublicKey;
+import netscape.security.provider.RSAPublicKey;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.def.NoDefault;
+import com.netscape.cms.profile.def.UserKeyDefault;
+
+/**
+ * This constraint is to check the key type and
+ * key length.
+ *
+ * @version $Revision$, $Date$
+ */
+@SuppressWarnings("serial")
+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 final static HashMap<String, Vector<String>> ecOIDs = new HashMap<String, Vector<String>>();
+ static {
+ ecOIDs.put("1.2.840.10045.3.1.7", new Vector<String>() {
+ {
+ add("nistp256");
+ add("secp256r1");
+ }
+ });
+ ecOIDs.put("1.3.132.0.34", new Vector<String>() {
+ {
+ add("nistp384");
+ add("secp384r1");
+ }
+ });
+ ecOIDs.put("1.3.132.0.35", new Vector<String>() {
+ {
+ add("nistp521");
+ add("secp521r1");
+ }
+ });
+ ecOIDs.put("1.3.132.0.1", new Vector<String>() {
+ {
+ add("sect163k1");
+ add("nistk163");
+ }
+ });
+ ecOIDs.put("1.3.132.0.2", new Vector<String>() {
+ {
+ add("sect163r1");
+ }
+ });
+ ecOIDs.put("1.3.132.0.15", new Vector<String>() {
+ {
+ add("sect163r2");
+ add("nistb163");
+ }
+ });
+ ecOIDs.put("1.3.132.0.24", new Vector<String>() {
+ {
+ add("sect193r1");
+ }
+ });
+ ecOIDs.put("1.3.132.0.25", new Vector<String>() {
+ {
+ add("sect193r2");
+ }
+ });
+ ecOIDs.put("1.3.132.0.26", new Vector<String>() {
+ {
+ add("sect233k1");
+ add("nistk233");
+ }
+ });
+ ecOIDs.put("1.3.132.0.27", new Vector<String>() {
+ {
+ add("sect233r1");
+ add("nistb233");
+ }
+ });
+ ecOIDs.put("1.3.132.0.3", new Vector<String>() {
+ {
+ add("sect239k1");
+ }
+ });
+ ecOIDs.put("1.3.132.0.16", new Vector<String>() {
+ {
+ add("sect283k1");
+ add("nistk283");
+ }
+ });
+ ecOIDs.put("1.3.132.0.17", new Vector<String>() {
+ {
+ add("sect283r1");
+ add("nistb283");
+ }
+ });
+ ecOIDs.put("1.3.132.0.36", new Vector<String>() {
+ {
+ add("sect409k1");
+ add("nistk409");
+ }
+ });
+ ecOIDs.put("1.3.132.0.37", new Vector<String>() {
+ {
+ add("sect409r1");
+ add("nistb409");
+ }
+ });
+ ecOIDs.put("1.3.132.0.38", new Vector<String>() {
+ {
+ add("sect571k1");
+ add("nistk571");
+ }
+ });
+ ecOIDs.put("1.3.132.0.39", new Vector<String>() {
+ {
+ add("sect571r1");
+ add("nistb571");
+ }
+ });
+ ecOIDs.put("1.3.132.0.9", new Vector<String>() {
+ {
+ add("secp160k1");
+ }
+ });
+ ecOIDs.put("1.3.132.0.8", new Vector<String>() {
+ {
+ add("secp160r1");
+ }
+ });
+ ecOIDs.put("1.3.132.0.30", new Vector<String>() {
+ {
+ add("secp160r2");
+ }
+ });
+ ecOIDs.put("1.3.132.0.31", new Vector<String>() {
+ {
+ add("secp192k1");
+ }
+ });
+ ecOIDs.put("1.2.840.10045.3.1.1", new Vector<String>() {
+ {
+ add("secp192r1");
+ add("nistp192");
+ add("prime192v1");
+ }
+ });
+ ecOIDs.put("1.3.132.0.32", new Vector<String>() {
+ {
+ add("secp224k1");
+ }
+ });
+ ecOIDs.put("1.3.132.0.33", new Vector<String>() {
+ {
+ add("secp224r1");
+ add("nistp224");
+ }
+ });
+ ecOIDs.put("1.3.132.0.10", new Vector<String>() {
+ {
+ add("secp256k1");
+ }
+ });
+ ecOIDs.put("1.2.840.10045.3.1.2", new Vector<String>() {
+ {
+ add("prime192v2");
+ }
+ });
+ ecOIDs.put("1.2.840.10045.3.1.3", new Vector<String>() {
+ {
+ add("prime192v3");
+ }
+ });
+ ecOIDs.put("1.2.840.10045.3.1.4", new Vector<String>() {
+ {
+ add("prime239v1");
+ }
+ });
+ ecOIDs.put("1.2.840.10045.3.1.5", new Vector<String>() {
+ {
+ add("prime239v2");
+ }
+ });
+ ecOIDs.put("1.2.840.10045.3.1.6", new Vector<String>() {
+ {
+ add("prime239v3");
+ }
+ });
+ ecOIDs.put("1.2.840.10045.3.0.1", new Vector<String>() {
+ {
+ add("c2pnb163v1");
+ }
+ });
+ ecOIDs.put("1.2.840.10045.3.0.2", new Vector<String>() {
+ {
+ add("c2pnb163v2");
+ }
+ });
+ ecOIDs.put("1.2.840.10045.3.0.3", new Vector<String>() {
+ {
+ add("c2pnb163v3");
+ }
+ });
+ ecOIDs.put("1.2.840.10045.3.0.4", new Vector<String>() {
+ {
+ add("c2pnb176v1");
+ }
+ });
+ ecOIDs.put("1.2.840.10045.3.0.5", new Vector<String>() {
+ {
+ add("c2tnb191v1");
+ }
+ });
+ ecOIDs.put("1.2.840.10045.3.0.6", new Vector<String>() {
+ {
+ add("c2tnb191v2");
+ }
+ });
+ ecOIDs.put("1.2.840.10045.3.0.7", new Vector<String>() {
+ {
+ add("c2tnb191v3");
+ }
+ });
+ ecOIDs.put("1.2.840.10045.3.0.10", new Vector<String>() {
+ {
+ add("c2pnb208w1");
+ }
+ });
+ ecOIDs.put("1.2.840.10045.3.0.11", new Vector<String>() {
+ {
+ add("c2tnb239v1");
+ }
+ });
+ ecOIDs.put("1.2.840.10045.3.0.12", new Vector<String>() {
+ {
+ add("c2tnb239v2");
+ }
+ });
+ ecOIDs.put("1.2.840.10045.3.0.13", new Vector<String>() {
+ {
+ add("c2tnb239v3");
+ }
+ });
+ ecOIDs.put("1.2.840.10045.3.0.16", new Vector<String>() {
+ {
+ add("c2pnb272w1");
+ }
+ });
+ ecOIDs.put("1.2.840.10045.3.0.17", new Vector<String>() {
+ {
+ add("c2pnb304w1");
+ }
+ });
+ ecOIDs.put("1.2.840.10045.3.0.19", new Vector<String>() {
+ {
+ add("c2pnb368w1");
+ }
+ });
+ ecOIDs.put("1.2.840.10045.3.0.20", new Vector<String>() {
+ {
+ add("c2tnb431r1");
+ }
+ });
+ ecOIDs.put("1.3.132.0.6", new Vector<String>() {
+ {
+ add("secp112r1");
+ }
+ });
+ ecOIDs.put("1.3.132.0.7", new Vector<String>() {
+ {
+ add("secp112r2");
+ }
+ });
+ ecOIDs.put("1.3.132.0.28", new Vector<String>() {
+ {
+ add("secp128r1");
+ }
+ });
+ ecOIDs.put("1.3.132.0.29", new Vector<String>() {
+ {
+ add("secp128r2");
+ }
+ });
+ ecOIDs.put("1.3.132.0.4", new Vector<String>() {
+ {
+ add("sect113r1");
+ }
+ });
+ ecOIDs.put("1.3.132.0.5", new Vector<String>() {
+ {
+ add("sect113r2");
+ }
+ });
+ ecOIDs.put("1.3.132.0.22", new Vector<String>() {
+ {
+ add("sect131r1");
+ }
+ });
+ ecOIDs.put("1.3.132.0.23", new Vector<String>() {
+ {
+ add("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;
+
+ 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")) {
+ if (!alg.equals(keyType) && !isOptional(keyType)) {
+ throw new ERejectException(
+ CMS.getUserMessage(
+ getLocale(request),
+ "CMS_PROFILE_KEY_PARAMS_NOT_MATCHED",
+ value));
+ }
+
+ AlgorithmId algid = key.getAlgorithmId();
+
+ CMS.debug("algId: " + algid);
+
+ //Get raw string representation of alg parameters, will give
+ //us the curve OID.
+
+ String params = null;
+ if (algid != null) {
+ params = algid.getParametersString();
+ }
+
+ if (params.startsWith("OID.")) {
+ params = params.substring(4);
+ }
+
+ CMS.debug("EC key OID: " + params);
+ Vector<String> vect = ecOIDs.get(params);
+
+ boolean curveFound = false;
+
+ if (vect != null) {
+ CMS.debug("vect: " + vect.toString());
+
+ if (!isOptional(keyType)) {
+ //Check the curve parameters only if explicit ECC or not optional
+ for (int i = 0; i < keyParams.length; i++) {
+ String ecParam = keyParams[i];
+ CMS.debug("keyParams[i]: " + i + " param: " + ecParam);
+ if (vect.contains(ecParam)) {
+ curveFound = true;
+ CMS.debug("KeyConstraint.validate: EC key constrainst passed.");
+ break;
+ }
+ }
+ } else {
+ curveFound = true;
+ }
+ }
+
+ if (!curveFound) {
+ CMS.debug("KeyConstraint.validate: EC key constrainst failed.");
+ throw new ERejectException(
+ CMS.getUserMessage(
+ getLocale(request),
+ "CMS_PROFILE_KEY_PARAMS_NOT_MATCHED",
+ value));
+ }
+
+ } 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/base/common/src/com/netscape/cms/profile/constraint/KeyUsageExtConstraint.java b/base/common/src/com/netscape/cms/profile/constraint/KeyUsageExtConstraint.java
new file mode 100644
index 000000000..927c64ec2
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/constraint/KeyUsageExtConstraint.java
@@ -0,0 +1,291 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Locale;
+
+import netscape.security.x509.KeyUsageExtension;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.def.KeyUsageExtDefault;
+import com.netscape.cms.profile.def.NoDefault;
+import com.netscape.cms.profile.def.UserExtensionDefault;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/constraint/NSCertTypeExtConstraint.java b/base/common/src/com/netscape/cms/profile/constraint/NSCertTypeExtConstraint.java
new file mode 100644
index 000000000..843360542
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/constraint/NSCertTypeExtConstraint.java
@@ -0,0 +1,243 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Locale;
+
+import netscape.security.extensions.NSCertTypeExtension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.def.NSCertTypeExtDefault;
+import com.netscape.cms.profile.def.NoDefault;
+import com.netscape.cms.profile.def.UserExtensionDefault;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/constraint/NoConstraint.java b/base/common/src/com/netscape/cms/profile/constraint/NoConstraint.java
new file mode 100644
index 000000000..459e9f219
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/constraint/NoConstraint.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.profile.constraint;
+
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IPolicyConstraint;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> mNames = new Vector<String>();
+
+ public Enumeration<String> 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/base/common/src/com/netscape/cms/profile/constraint/RenewGracePeriodConstraint.java b/base/common/src/com/netscape/cms/profile/constraint/RenewGracePeriodConstraint.java
new file mode 100644
index 000000000..fb01d7d14
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/constraint/RenewGracePeriodConstraint.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.profile.constraint;
+
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Locale;
+
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.def.NoDefault;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/constraint/SigningAlgConstraint.java b/base/common/src/com/netscape/cms/profile/constraint/SigningAlgConstraint.java
new file mode 100644
index 000000000..4dbe329b3
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/constraint/SigningAlgConstraint.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.constraint;
+
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateAlgorithmId;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.def.NoDefault;
+import com.netscape.cms.profile.def.SigningAlgDefault;
+import com.netscape.cms.profile.def.UserSigningAlgDefault;
+
+/**
+ * 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<String> mCache = new Vector<String>();
+ 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/base/common/src/com/netscape/cms/profile/constraint/SubjectNameConstraint.java b/base/common/src/com/netscape/cms/profile/constraint/SubjectNameConstraint.java
new file mode 100644
index 000000000..477e99b98
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/constraint/SubjectNameConstraint.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.profile.constraint;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.def.NoDefault;
+import com.netscape.cms.profile.def.SubjectNameDefault;
+import com.netscape.cms.profile.def.UserSubjectNameDefault;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/constraint/UniqueKeyConstraint.java b/base/common/src/com/netscape/cms/profile/constraint/UniqueKeyConstraint.java
new file mode 100644
index 000000000..f10130aa6
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/constraint/UniqueKeyConstraint.java
@@ -0,0 +1,295 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Enumeration;
+import java.util.Locale;
+
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertRecordList;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.def.NoDefault;
+
+/**
+ * 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<ICertRecord> e = list.getCertRecords(0, size - 1);
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = 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/base/common/src/com/netscape/cms/profile/constraint/UniqueSubjectNameConstraint.java b/base/common/src/com/netscape/cms/profile/constraint/UniqueSubjectNameConstraint.java
new file mode 100644
index 000000000..7a985b631
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/constraint/UniqueSubjectNameConstraint.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.profile.constraint;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.Extension;
+import netscape.security.x509.KeyUsageExtension;
+import netscape.security.x509.RevocationReason;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.dbs.certdb.IRevocationInfo;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.def.NoDefault;
+import com.netscape.cms.profile.def.SubjectNameDefault;
+import com.netscape.cms.profile.def.UserSubjectNameDefault;
+
+/**
+ * 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<ICertRecord> sameSubjRecords = null;
+ try {
+ sameSubjRecords = certdb.findCertRecords(filter);
+ } catch (EBaseException e) {
+ CMS.debug("UniqueSubjectNameConstraint exception: " + e.toString());
+ }
+ while (sameSubjRecords != null && sameSubjRecords.hasMoreElements()) {
+ ICertRecord rec = sameSubjRecords.nextElement();
+ String status = rec.getStatus();
+
+ IRevocationInfo revocationInfo = rec.getRevocationInfo();
+ RevocationReason reason = null;
+
+ if (revocationInfo != null) {
+ CRLExtensions crlExts = revocationInfo.getCRLEntryExtensions();
+
+ if (crlExts != null) {
+ Enumeration<Extension> enumx = crlExts.getElements();
+
+ while (enumx.hasMoreElements()) {
+ Extension ext = 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/base/common/src/com/netscape/cms/profile/constraint/ValidityConstraint.java b/base/common/src/com/netscape/cms/profile/constraint/ValidityConstraint.java
new file mode 100644
index 000000000..98a7b4f96
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/constraint/ValidityConstraint.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.profile.constraint;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.Locale;
+
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.def.CAValidityDefault;
+import com.netscape.cms.profile.def.NoDefault;
+import com.netscape.cms.profile.def.UserValidityDefault;
+import com.netscape.cms.profile.def.ValidityDefault;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/AuthInfoAccessExtDefault.java b/base/common/src/com/netscape/cms/profile/def/AuthInfoAccessExtDefault.java
new file mode 100644
index 000000000..4e4f951f7
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/AuthInfoAccessExtDefault.java
@@ -0,0 +1,454 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.extensions.AccessDescription;
+import netscape.security.extensions.AuthInfoAccessExtension;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.GeneralNameInterface;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> 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<NameValuePairs> 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 = v.elementAt(i);
+
+ for (String name1 : nvps.keySet()) {
+
+ if (name1.equals(AD_METHOD)) {
+ method = nvps.get(name1);
+ } else if (name1.equals(AD_LOCATION_TYPE)) {
+ locationType = nvps.get(name1);
+ } else if (name1.equals(AD_LOCATION)) {
+ location = nvps.get(name1);
+ } else if (name1.equals(AD_ENABLE)) {
+ enable = nvps.get(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<NameValuePairs> recs = new Vector<NameValuePairs>();
+
+ 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.put(AD_METHOD, "");
+ np.put(AD_LOCATION_TYPE, "");
+ np.put(AD_LOCATION, "");
+ np.put(AD_ENABLE, "false");
+ } else {
+ ObjectIdentifier methodOid = des.getMethod();
+ GeneralName gn = des.getLocation();
+
+ np.put(AD_METHOD, methodOid.toString());
+ np.put(AD_LOCATION_TYPE, getGeneralNameType(gn));
+ np.put(AD_LOCATION, getGeneralNameValue(gn));
+ np.put(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();
+ 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/base/common/src/com/netscape/cms/profile/def/AuthTokenSubjectNameDefault.java b/base/common/src/com/netscape/cms/profile/def/AuthTokenSubjectNameDefault.java
new file mode 100644
index 000000000..6c0f6e9fc
--- /dev/null
+++ b/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.IOException;
+import java.util.Locale;
+
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileAuthenticator;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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);
+ CMS.debug("AuthTokenSubjectNameDefault: setValue x500name=" + x500name.toString());
+ } 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/base/common/src/com/netscape/cms/profile/def/AuthorityKeyIdentifierExtDefault.java b/base/common/src/com/netscape/cms/profile/def/AuthorityKeyIdentifierExtDefault.java
new file mode 100644
index 000000000..6ec75990c
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/AuthorityKeyIdentifierExtDefault.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.profile.def;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import netscape.security.x509.AuthorityKeyIdentifierExtension;
+import netscape.security.x509.KeyIdentifier;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/AutoAssignDefault.java b/base/common/src/com/netscape/cms/profile/def/AutoAssignDefault.java
new file mode 100644
index 000000000..043cf029b
--- /dev/null
+++ b/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.util.Locale;
+
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/BasicConstraintsExtDefault.java b/base/common/src/com/netscape/cms/profile/def/BasicConstraintsExtDefault.java
new file mode 100644
index 000000000..c442bf576
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/BasicConstraintsExtDefault.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.def;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import netscape.security.x509.BasicConstraintsExtension;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/CAEnrollDefault.java b/base/common/src/com/netscape/cms/profile/def/CAEnrollDefault.java
new file mode 100644
index 000000000..872e32960
--- /dev/null
+++ b/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.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.KeyIdentifier;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.SubjectKeyIdentifierExtension;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/CAValidityDefault.java b/base/common/src/com/netscape/cms/profile/def/CAValidityDefault.java
new file mode 100644
index 000000000..e3b834ce5
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/CAValidityDefault.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.cms.profile.def;
+
+import java.io.IOException;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+import netscape.security.x509.BasicConstraintsExtension;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/CRLDistributionPointsExtDefault.java b/base/common/src/com/netscape/cms/profile/def/CRLDistributionPointsExtDefault.java
new file mode 100644
index 000000000..d1def3d5d
--- /dev/null
+++ b/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.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.security.util.BitArray;
+import netscape.security.x509.CRLDistributionPoint;
+import netscape.security.x509.CRLDistributionPointsExtension;
+import netscape.security.x509.CRLDistributionPointsExtension.Reason;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.GeneralNamesException;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.RDN;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> 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<NameValuePairs> v = parseRecords(value);
+ int size = v.size();
+
+ boolean critical = ext.isCritical();
+ int i = 0;
+
+ for (; i < size; i++) {
+ NameValuePairs nvps = v.elementAt(i);
+ String pointType = null;
+ String pointValue = null;
+ String issuerType = null;
+ String issuerValue = null;
+ String enable = null;
+ CRLDistributionPoint cdp = new CRLDistributionPoint();
+
+ for (String name1 : nvps.keySet()) {
+
+ if (name1.equals(REASONS)) {
+ addReasons(locale, cdp, REASONS, nvps.get(name1));
+ } else if (name1.equals(POINT_TYPE)) {
+ pointType = nvps.get(name1);
+ } else if (name1.equals(POINT_NAME)) {
+ pointValue = nvps.get(name1);
+ } else if (name1.equals(ISSUER_TYPE)) {
+ issuerType = nvps.get(name1);
+ } else if (name1.equals(ISSUER_NAME)) {
+ issuerValue = nvps.get(name1);
+ } else if (name1.equals(ENABLE)) {
+ enable = nvps.get(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 "";
+
+ Vector<NameValuePairs> recs = new Vector<NameValuePairs>();
+ 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.put(POINT_TYPE, "");
+ pairs.put(POINT_NAME, "");
+ pairs.put(REASONS, "");
+ pairs.put(ISSUER_TYPE, "");
+ pairs.put(ISSUER_NAME, "");
+ pairs.put(ENABLE, "false");
+ return pairs;
+ }
+
+ protected NameValuePairs buildGeneralNames(GeneralNames gns, CRLDistributionPoint p)
+ throws EPropertyException {
+
+ NameValuePairs pairs = new NameValuePairs();
+
+ RDN rdn = null;
+ boolean hasFullName = false;
+
+ pairs.put(ENABLE, "true");
+ if (gns == null) {
+ rdn = p.getRelativeName();
+ if (rdn != null) {
+ hasFullName = true;
+ pairs.put(POINT_TYPE, RELATIVETOISSUER);
+ pairs.put(POINT_NAME, rdn.toString());
+ } else {
+ pairs.put(POINT_TYPE, "");
+ pairs.put(POINT_NAME, "");
+ }
+ } else {
+ GeneralName gn = (GeneralName) gns.elementAt(0);
+
+ if (gn != null) {
+ hasFullName = true;
+
+ pairs.put(POINT_TYPE, getGeneralNameType(gn));
+ pairs.put(POINT_NAME, getGeneralNameValue(gn));
+ }
+ }
+
+ if (!hasFullName) {
+ pairs.put(POINT_TYPE, GN_DIRECTORY_NAME);
+ pairs.put(POINT_NAME, "");
+ }
+
+ BitArray reasons = p.getReasons();
+ String s = convertBitArrayToReasonNames(reasons);
+
+ if (s.length() > 0) {
+ pairs.put(REASONS, s);
+ } else {
+ pairs.put(REASONS, "");
+ }
+
+ gns = p.getCRLIssuer();
+
+ if (gns == null) {
+ pairs.put(ISSUER_TYPE, GN_DIRECTORY_NAME);
+ pairs.put(ISSUER_NAME, "");
+ } else {
+ GeneralName gn = (GeneralName) gns.elementAt(0);
+
+ if (gn != null) {
+ hasFullName = true;
+
+ pairs.put(ISSUER_TYPE, getGeneralNameType(gn));
+ pairs.put(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/base/common/src/com/netscape/cms/profile/def/CertificatePoliciesExtDefault.java b/base/common/src/com/netscape/cms/profile/def/CertificatePoliciesExtDefault.java
new file mode 100644
index 000000000..8d4ae2288
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/CertificatePoliciesExtDefault.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.cms.profile.def;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CPSuri;
+import netscape.security.x509.CertificatePoliciesExtension;
+import netscape.security.x509.CertificatePolicyId;
+import netscape.security.x509.CertificatePolicyInfo;
+import netscape.security.x509.DisplayText;
+import netscape.security.x509.NoticeReference;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.PolicyQualifiers;
+import netscape.security.x509.Qualifier;
+import netscape.security.x509.UserNotice;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> 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<String, String> buildRecords(String value) throws EPropertyException {
+ StringTokenizer st = new StringTokenizer(value, "\r\n");
+ Hashtable<String, String> table = new Hashtable<String, String>();
+ 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<String, String> h = buildRecords(value);
+
+ String numStr = (String) h.get(CONFIG_POLICY_NUM);
+ int size = Integer.parseInt(numStr);
+
+ Vector<CertificatePolicyInfo> certificatePolicies = new Vector<CertificatePolicyInfo>();
+ 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));
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ 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();
+ sb.append(CONFIG_POLICY_NUM);
+ sb.append(":");
+ sb.append(num_policies);
+ sb.append("\n");
+ Vector<CertificatePolicyInfo> infos;
+
+ try {
+ infos = (Vector<CertificatePolicyInfo>) ext.get(CertificatePoliciesExtension.INFOS);
+ } catch (IOException ee) {
+ infos = null;
+ }
+
+ 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 =
+ 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();
+ 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<CertificatePolicyInfo> certificatePolicies = new Vector<CertificatePolicyInfo>();
+ 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<String> numsVector = new Vector<String>();
+ 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/base/common/src/com/netscape/cms/profile/def/CertificateVersionDefault.java b/base/common/src/com/netscape/cms/profile/def/CertificateVersionDefault.java
new file mode 100644
index 000000000..d30f971dd
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/CertificateVersionDefault.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.profile.def;
+
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.util.Locale;
+
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java b/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java
new file mode 100644
index 000000000..67ebadbe4
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java
@@ -0,0 +1,815 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.security.extensions.KerberosName;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.DNSName;
+import netscape.security.x509.EDIPartyName;
+import netscape.security.x509.Extension;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.GeneralNameInterface;
+import netscape.security.x509.IPAddressName;
+import netscape.security.x509.OIDName;
+import netscape.security.x509.OtherName;
+import netscape.security.x509.RFC822Name;
+import netscape.security.x509.URIName;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IAttrSet;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IPrettyPrintFormat;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.pattern.Pattern;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ICertInfoPolicyDefault;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.common.EnrollProfile;
+
+/**
+ * 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<String> mConfigNames = new Vector<String>();
+ protected Vector<String> mValueNames = new Vector<String>();
+
+ public EnrollDefault() {
+ }
+
+ public Enumeration<String> 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<String> 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<String> e = exts.getNames();
+
+ while (e.hasMoreElements()) {
+ String n = 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<Extension> e = exts.getAttributes();
+
+ while (e.hasMoreElements()) {
+ Extension ext = 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 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
+ 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<String> strings = new Vector<String>();
+ 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<NameValuePairs> recs) throws EPropertyException {
+ StringBuffer sb = new StringBuffer();
+
+ for (int i = 0; i < recs.size(); i++) {
+ NameValuePairs pairs = recs.elementAt(i);
+
+ sb.append("Record #");
+ sb.append(i);
+ sb.append("\r\n");
+
+ for (String key : pairs.keySet()) {
+ String val = pairs.get(key);
+
+ sb.append(key);
+ sb.append(":");
+ sb.append(val);
+ sb.append("\r\n");
+ }
+ sb.append("\r\n");
+
+ }
+ return sb.toString();
+ }
+
+ protected Vector<NameValuePairs> parseRecords(String value) throws EPropertyException {
+ StringTokenizer st = new StringTokenizer(value, "\r\n");
+ int num = 0;
+ Vector<NameValuePairs> v = new Vector<NameValuePairs>();
+ NameValuePairs nvps = null;
+
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+
+ if (token.equals("Record #" + num)) {
+ CMS.debug("parseRecords: Record" + num);
+ nvps = new NameValuePairs();
+ v.addElement(nvps);
+ try {
+ token = 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.put(token.substring(0, pos), "");
+ } else {
+ nvps.put(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(GeneralNameInterface 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 == '"') {
+ if ((c == 0x5c) && ((i + 1) < v.length())) {
+ int nextC = v.charAt(i + 1);
+ if ((c == 0x5c) && (nextC == ',' || nextC == '=' || nextC == '+' ||
+ nextC == '<' || nextC == '>' || nextC == '#' ||
+ nextC == ';' || nextC == '\r' || nextC == '\n' ||
+ nextC == '\\' || nextC == '"')) {
+ if (doubleEscape)
+ result.append('\\');
+ } else {
+ result.append('\\');
+ if (doubleEscape)
+ result.append('\\');
+ }
+ } else {
+ 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/base/common/src/com/netscape/cms/profile/def/EnrollExtDefault.java b/base/common/src/com/netscape/cms/profile/def/EnrollExtDefault.java
new file mode 100644
index 000000000..24f79cdec
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/EnrollExtDefault.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.cms.profile.def;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/ExtendedKeyUsageExtDefault.java b/base/common/src/com/netscape/cms/profile/def/ExtendedKeyUsageExtDefault.java
new file mode 100644
index 000000000..f1d63a348
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/ExtendedKeyUsageExtDefault.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.profile.def;
+
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import netscape.security.extensions.ExtendedKeyUsageExtension;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<ObjectIdentifier> e = ext.getOIDs();
+
+ while (e.hasMoreElements()) {
+ ObjectIdentifier oid = 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/base/common/src/com/netscape/cms/profile/def/FreshestCRLExtDefault.java b/base/common/src/com/netscape/cms/profile/def/FreshestCRLExtDefault.java
new file mode 100644
index 000000000..acbbd1089
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/FreshestCRLExtDefault.java
@@ -0,0 +1,584 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.CRLDistributionPoint;
+import netscape.security.x509.FreshestCRLExtension;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.GeneralNamesException;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> 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<NameValuePairs> v = parseRecords(value);
+ int size = v.size();
+
+ boolean critical = ext.isCritical();
+ int i = 0;
+
+ for (; i < size; i++) {
+ NameValuePairs nvps = v.elementAt(i);
+ String pointType = null;
+ String pointValue = null;
+ String issuerType = null;
+ String issuerValue = null;
+ String enable = null;
+ CRLDistributionPoint cdp = new CRLDistributionPoint();
+
+ for (String name1 : nvps.keySet()) {
+
+ if (name1.equals(POINT_TYPE)) {
+ pointType = nvps.get(name1);
+ } else if (name1.equals(POINT_NAME)) {
+ pointValue = nvps.get(name1);
+ } else if (name1.equals(ISSUER_TYPE)) {
+ issuerType = nvps.get(name1);
+ } else if (name1.equals(ISSUER_NAME)) {
+ issuerValue = nvps.get(name1);
+ } else if (name1.equals(ENABLE)) {
+ enable = nvps.get(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 "";
+
+ Vector<NameValuePairs> recs = new Vector<NameValuePairs>();
+ 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.put(POINT_TYPE, "");
+ pairs.put(POINT_NAME, "");
+ pairs.put(ISSUER_TYPE, "");
+ pairs.put(ISSUER_NAME, "");
+ pairs.put(ENABLE, "false");
+ return pairs;
+ }
+
+ protected NameValuePairs buildGeneralNames(GeneralNames gns, CRLDistributionPoint p)
+ throws EPropertyException {
+
+ NameValuePairs pairs = new NameValuePairs();
+
+ boolean hasFullName = false;
+
+ pairs.put(ENABLE, "true");
+ if (gns == null) {
+ pairs.put(POINT_TYPE, "");
+ pairs.put(POINT_NAME, "");
+ } else {
+ GeneralName gn = (GeneralName) gns.elementAt(0);
+
+ if (gn != null) {
+ hasFullName = true;
+
+ pairs.put(POINT_TYPE, getGeneralNameType(gn));
+ pairs.put(POINT_NAME, getGeneralNameValue(gn));
+ }
+ }
+
+ if (!hasFullName) {
+ pairs.put(POINT_TYPE, GN_DIRECTORY_NAME);
+ pairs.put(POINT_NAME, "");
+ }
+
+ gns = p.getCRLIssuer();
+
+ if (gns == null) {
+ pairs.put(ISSUER_TYPE, GN_DIRECTORY_NAME);
+ pairs.put(ISSUER_NAME, "");
+ } else {
+ GeneralName gn = (GeneralName) gns.elementAt(0);
+
+ if (gn != null) {
+ hasFullName = true;
+
+ pairs.put(ISSUER_TYPE, getGeneralNameType(gn));
+ pairs.put(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/base/common/src/com/netscape/cms/profile/def/GenericExtDefault.java b/base/common/src/com/netscape/cms/profile/def/GenericExtDefault.java
new file mode 100644
index 000000000..1797091b7
--- /dev/null
+++ b/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.util.Locale;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.Extension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/ImageDefault.java b/base/common/src/com/netscape/cms/profile/def/ImageDefault.java
new file mode 100644
index 000000000..16a7ac402
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/ImageDefault.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.profile.def;
+
+import java.util.Locale;
+
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/InhibitAnyPolicyExtDefault.java b/base/common/src/com/netscape/cms/profile/def/InhibitAnyPolicyExtDefault.java
new file mode 100644
index 000000000..97cfb3ff4
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/InhibitAnyPolicyExtDefault.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.profile.def;
+
+import java.math.BigInteger;
+import java.util.Locale;
+
+import netscape.security.extensions.InhibitAnyPolicyExtension;
+import netscape.security.util.BigInt;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/IssuerAltNameExtDefault.java b/base/common/src/com/netscape/cms/profile/def/IssuerAltNameExtDefault.java
new file mode 100644
index 000000000..251d8a3e7
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/IssuerAltNameExtDefault.java
@@ -0,0 +1,317 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.GeneralNameInterface;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.IssuerAlternativeNameExtension;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<GeneralNameInterface> 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/base/common/src/com/netscape/cms/profile/def/KeyUsageExtDefault.java b/base/common/src/com/netscape/cms/profile/def/KeyUsageExtDefault.java
new file mode 100644
index 000000000..1bfda9ad9
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/KeyUsageExtDefault.java
@@ -0,0 +1,511 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Locale;
+
+import netscape.security.x509.KeyUsageExtension;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/NSCCommentExtDefault.java b/base/common/src/com/netscape/cms/profile/def/NSCCommentExtDefault.java
new file mode 100644
index 000000000..cc96f3e90
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/NSCCommentExtDefault.java
@@ -0,0 +1,246 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Locale;
+
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.NSCCommentExtension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/NSCertTypeExtDefault.java b/base/common/src/com/netscape/cms/profile/def/NSCertTypeExtDefault.java
new file mode 100644
index 000000000..0677ef69f
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/NSCertTypeExtDefault.java
@@ -0,0 +1,419 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.security.cert.CertificateException;
+import java.util.Locale;
+
+import netscape.security.extensions.NSCertTypeExtension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/NameConstraintsExtDefault.java b/base/common/src/com/netscape/cms/profile/def/NameConstraintsExtDefault.java
new file mode 100644
index 000000000..e57d04067
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/NameConstraintsExtDefault.java
@@ -0,0 +1,670 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.GeneralNameInterface;
+import netscape.security.x509.GeneralSubtree;
+import netscape.security.x509.GeneralSubtrees;
+import netscape.security.x509.NameConstraintsExtension;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> 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;
+ }
+ if ((value == null) || (value.equals("null")) || (value.equals(""))) {
+ CMS.debug("NameConstraintsExtDefault:setValue : " +
+ "blank value for permitted subtrees ... returning");
+ return;
+ }
+
+ Vector<NameValuePairs> v = parseRecords(value);
+
+ Vector<GeneralSubtree> 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;
+ }
+ if ((value == null) || (value.equals("null")) || (value.equals(""))) {
+ CMS.debug("NameConstraintsExtDefault:setValue : " +
+ "blank value for excluded subtrees ... returning");
+ return;
+ }
+ Vector<NameValuePairs> v = parseRecords(value);
+
+ Vector<GeneralSubtree> 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<GeneralSubtree> createSubtrees(Locale locale, Vector<NameValuePairs> v) throws EPropertyException {
+ int size = v.size();
+ String choice = null;
+ String val = "";
+ String minS = null;
+ String maxS = null;
+
+ Vector<GeneralSubtree> subtrees = new Vector<GeneralSubtree>();
+
+ for (int i = 0; i < size; i++) {
+ NameValuePairs nvps = v.elementAt(i);
+
+ for (String name1 : nvps.keySet()) {
+
+ if (name1.equals(GENERAL_NAME_CHOICE)) {
+ choice = nvps.get(name1);
+ } else if (name1.equals(GENERAL_NAME_VALUE)) {
+ val = nvps.get(name1);
+ } else if (name1.equals(MIN_VALUE)) {
+ minS = nvps.get(name1);
+ } else if (name1.equals(MAX_VALUE)) {
+ maxS = nvps.get(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<GeneralSubtree> trees = subtrees.getSubtrees();
+ int size = trees.size();
+
+ Vector<NameValuePairs> recs = new Vector<NameValuePairs>();
+
+ 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.put(GENERAL_NAME_CHOICE, type);
+ pairs.put(GENERAL_NAME_VALUE, getGeneralNameValue(gn));
+ pairs.put(MIN_VALUE, Integer.toString(min));
+ pairs.put(MAX_VALUE, Integer.toString(max));
+ pairs.put(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<GeneralSubtree> v = new Vector<GeneralSubtree>();
+
+ 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<GeneralSubtree> v1 = new Vector<GeneralSubtree>();
+
+ 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/base/common/src/com/netscape/cms/profile/def/NoDefault.java b/base/common/src/com/netscape/cms/profile/def/NoDefault.java
new file mode 100644
index 000000000..4678f4487
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/NoDefault.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.profile.def;
+
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * This class implements no default policy.
+ *
+ * @version $Revision$, $Date$
+ */
+public class NoDefault implements IPolicyDefault {
+
+ public static final String PROP_NAME = "name";
+
+ protected Vector<String> mValues = new Vector<String>();
+ protected Vector<String> mNames = new Vector<String>();
+ protected IConfigStore mConfig = null;
+
+ public Enumeration<String> 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<String> 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/base/common/src/com/netscape/cms/profile/def/OCSPNoCheckExtDefault.java b/base/common/src/com/netscape/cms/profile/def/OCSPNoCheckExtDefault.java
new file mode 100644
index 000000000..382f3cec3
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/OCSPNoCheckExtDefault.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.profile.def;
+
+import java.util.Locale;
+
+import netscape.security.extensions.OCSPNoCheckExtension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/PolicyConstraintsExtDefault.java b/base/common/src/com/netscape/cms/profile/def/PolicyConstraintsExtDefault.java
new file mode 100644
index 000000000..db9b95a04
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/PolicyConstraintsExtDefault.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.profile.def;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.PolicyConstraintsExtension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/PolicyMappingsExtDefault.java b/base/common/src/com/netscape/cms/profile/def/PolicyMappingsExtDefault.java
new file mode 100644
index 000000000..712641c0d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/PolicyMappingsExtDefault.java
@@ -0,0 +1,420 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CertificatePolicyId;
+import netscape.security.x509.CertificatePolicyMap;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.PolicyMappingsExtension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> 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<NameValuePairs> v = parseRecords(value);
+ int size = v.size();
+
+ String issuerPolicyId = null;
+ String subjectPolicyId = null;
+ String enable = null;
+ Vector<CertificatePolicyMap> policyMaps = new Vector<CertificatePolicyMap>();
+
+ for (int i = 0; i < size; i++) {
+ NameValuePairs nvps = v.elementAt(i);
+
+ for (String name1 : nvps.keySet()) {
+
+ if (name1.equals(ISSUER_POLICY_ID)) {
+ issuerPolicyId = nvps.get(name1);
+ } else if (name1.equals(SUBJECT_POLICY_ID)) {
+ subjectPolicyId = nvps.get(name1);
+ } else if (name1.equals(POLICY_ID_ENABLE)) {
+ enable = nvps.get(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<CertificatePolicyMap> maps = ext.getMappings();
+
+ Vector<NameValuePairs> recs = new Vector<NameValuePairs>();
+
+ 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.put(ISSUER_POLICY_ID, i1.getIdentifier().toString());
+ pairs.put(SUBJECT_POLICY_ID, s1.getIdentifier().toString());
+ pairs.put(POLICY_ID_ENABLE, "true");
+ } else {
+ pairs.put(ISSUER_POLICY_ID, "");
+ pairs.put(SUBJECT_POLICY_ID, "");
+ pairs.put(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();
+ 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<CertificatePolicyMap> policyMaps = new Vector<CertificatePolicyMap>();
+ 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/base/common/src/com/netscape/cms/profile/def/PrivateKeyUsagePeriodExtDefault.java b/base/common/src/com/netscape/cms/profile/def/PrivateKeyUsagePeriodExtDefault.java
new file mode 100644
index 000000000..20285567e
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/PrivateKeyUsagePeriodExtDefault.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.profile.def;
+
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.PrivateKeyUsageExtension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/SigningAlgDefault.java b/base/common/src/com/netscape/cms/profile/def/SigningAlgDefault.java
new file mode 100644
index 000000000..11da93fc8
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/SigningAlgDefault.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.profile.def;
+
+import java.util.Locale;
+
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateAlgorithmId;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/SubjectAltNameExtDefault.java b/base/common/src/com/netscape/cms/profile/def/SubjectAltNameExtDefault.java
new file mode 100644
index 000000000..d3838577e
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/SubjectAltNameExtDefault.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.profile.def;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.UUID;
+
+import netscape.security.x509.GeneralNameInterface;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.SubjectAlternativeNameExtension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IAttrSet;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.pattern.Pattern;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> 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<GeneralNameInterface> e = names.elements();
+
+ while (e.hasMoreElements()) {
+ GeneralNameInterface gn = e.nextElement();
+
+ 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();
+ 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/base/common/src/com/netscape/cms/profile/def/SubjectDirAttributesExtDefault.java b/base/common/src/com/netscape/cms/profile/def/SubjectDirAttributesExtDefault.java
new file mode 100644
index 000000000..cca5ab234
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/SubjectDirAttributesExtDefault.java
@@ -0,0 +1,527 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.AVAValueConverter;
+import netscape.security.x509.Attribute;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.SubjectDirAttributesExtension;
+import netscape.security.x509.X500NameAttrMap;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> 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<NameValuePairs> v = parseRecords(value);
+ int size = v.size();
+
+ boolean critical = ext.isCritical();
+
+ Vector<Attribute> attrV = new Vector<Attribute>();
+ for (int i = 0; i < size; i++) {
+ NameValuePairs nvps = v.elementAt(i);
+ String attrName = null;
+ String attrValue = null;
+ String enable = "false";
+
+ for (String name1 : nvps.keySet()) {
+
+ if (name1.equals(ATTR_NAME)) {
+ attrName = nvps.get(name1);
+ } else if (name1.equals(ATTR_VALUE)) {
+ attrValue = nvps.get(name1);
+ } else if (name1.equals(ENABLE)) {
+ enable = nvps.get(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<NameValuePairs> recs = new Vector<NameValuePairs>();
+ int num = getNumAttrs();
+ Enumeration<Attribute> e = ext.getAttributesList();
+ CMS.debug("SubjectDirAttributesExtDefault: getValue: attributesList=" + e);
+ int i = 0;
+
+ while (e.hasMoreElements()) {
+ NameValuePairs pairs = new NameValuePairs();
+ pairs.put(ENABLE, "true");
+ Attribute attr = 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.put(ATTR_NAME, vv);
+ else
+ pairs.put(ATTR_NAME, oid.toString());
+ Enumeration<String> 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.put(ATTR_VALUE, ss.toString());
+ recs.addElement(pairs);
+ i++;
+ }
+
+ for (; i < num; i++) {
+ NameValuePairs pairs = new NameValuePairs();
+ pairs.put(ENABLE, "false");
+ pairs.put(ATTR_NAME, "GENERATIONQUALIFIER");
+ pairs.put(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<Attribute> attrs = new Vector<Attribute>();
+ 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);
+
+ @SuppressWarnings("unused")
+ DerValue derval = c.getValue(val); // check for errors
+ return;
+ }
+
+ private Vector<String> str2MultiValues(String attrValue) {
+ StringTokenizer tokenizer = new StringTokenizer(attrValue, ",");
+ Vector<String> v = new Vector<String>();
+ while (tokenizer.hasMoreTokens()) {
+ v.addElement(tokenizer.nextToken());
+ }
+
+ return v;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/profile/def/SubjectInfoAccessExtDefault.java b/base/common/src/com/netscape/cms/profile/def/SubjectInfoAccessExtDefault.java
new file mode 100644
index 000000000..8ea7533cc
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/SubjectInfoAccessExtDefault.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;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.extensions.AccessDescription;
+import netscape.security.extensions.SubjectInfoAccessExtension;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.GeneralNameInterface;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> 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<NameValuePairs> 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 = v.elementAt(i);
+
+ for (String name1 : nvps.keySet()) {
+
+ if (name1.equals(AD_METHOD)) {
+ method = nvps.get(name1);
+ } else if (name1.equals(AD_LOCATION_TYPE)) {
+ locationType = nvps.get(name1);
+ } else if (name1.equals(AD_LOCATION)) {
+ location = nvps.get(name1);
+ } else if (name1.equals(AD_ENABLE)) {
+ enable = nvps.get(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<NameValuePairs> recs = new Vector<NameValuePairs>();
+
+ 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.put(AD_METHOD, "");
+ np.put(AD_LOCATION_TYPE, "");
+ np.put(AD_LOCATION, "");
+ np.put(AD_ENABLE, "false");
+ } else {
+ ObjectIdentifier methodOid = des.getMethod();
+ GeneralName gn = des.getLocation();
+
+ np.put(AD_METHOD, methodOid.toString());
+ np.put(AD_LOCATION_TYPE, getGeneralNameType(gn));
+ np.put(AD_LOCATION, getGeneralNameValue(gn));
+ np.put(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();
+ 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/base/common/src/com/netscape/cms/profile/def/SubjectKeyIdentifierExtDefault.java b/base/common/src/com/netscape/cms/profile/def/SubjectKeyIdentifierExtDefault.java
new file mode 100644
index 000000000..9476e45f6
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/SubjectKeyIdentifierExtDefault.java
@@ -0,0 +1,217 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Locale;
+
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.KeyIdentifier;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.SubjectKeyIdentifierExtension;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/SubjectNameDefault.java b/base/common/src/com/netscape/cms/profile/def/SubjectNameDefault.java
new file mode 100644
index 000000000..479219b84
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/SubjectNameDefault.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.IOException;
+import java.util.Locale;
+
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/UserExtensionDefault.java b/base/common/src/com/netscape/cms/profile/def/UserExtensionDefault.java
new file mode 100644
index 000000000..46a78c731
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/UserExtensionDefault.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.profile.def;
+
+import java.util.Locale;
+
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/UserKeyDefault.java b/base/common/src/com/netscape/cms/profile/def/UserKeyDefault.java
new file mode 100644
index 000000000..b1dc9d116
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/UserKeyDefault.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.def;
+
+import java.io.ByteArrayInputStream;
+import java.math.BigInteger;
+import java.security.interfaces.DSAParams;
+import java.util.Locale;
+
+import netscape.security.provider.DSAPublicKey;
+import netscape.security.provider.RSAPublicKey;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/UserSigningAlgDefault.java b/base/common/src/com/netscape/cms/profile/def/UserSigningAlgDefault.java
new file mode 100644
index 000000000..4aeed6ba3
--- /dev/null
+++ b/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.ByteArrayInputStream;
+import java.util.Locale;
+
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateAlgorithmId;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/UserSubjectNameDefault.java b/base/common/src/com/netscape/cms/profile/def/UserSubjectNameDefault.java
new file mode 100644
index 000000000..65456e256
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/UserSubjectNameDefault.java
@@ -0,0 +1,143 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Locale;
+
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/UserValidityDefault.java b/base/common/src/com/netscape/cms/profile/def/UserValidityDefault.java
new file mode 100644
index 000000000..3fadb81fd
--- /dev/null
+++ b/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.ByteArrayInputStream;
+import java.util.Date;
+import java.util.Locale;
+
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/ValidityDefault.java b/base/common/src/com/netscape/cms/profile/def/ValidityDefault.java
new file mode 100644
index 000000000..ad06400f3
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/ValidityDefault.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.profile.def;
+
+import java.io.IOException;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/nsHKeySubjectNameDefault.java b/base/common/src/com/netscape/cms/profile/def/nsHKeySubjectNameDefault.java
new file mode 100644
index 000000000..6b5ab6bc0
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/nsHKeySubjectNameDefault.java
@@ -0,0 +1,215 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Locale;
+
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/nsNKeySubjectNameDefault.java b/base/common/src/com/netscape/cms/profile/def/nsNKeySubjectNameDefault.java
new file mode 100644
index 000000000..cc1a8de81
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/nsNKeySubjectNameDefault.java
@@ -0,0 +1,423 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/nsTokenDeviceKeySubjectNameDefault.java b/base/common/src/com/netscape/cms/profile/def/nsTokenDeviceKeySubjectNameDefault.java
new file mode 100644
index 000000000..77fa417f6
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/nsTokenDeviceKeySubjectNameDefault.java
@@ -0,0 +1,215 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Locale;
+
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/def/nsTokenUserKeySubjectNameDefault.java b/base/common/src/com/netscape/cms/profile/def/nsTokenUserKeySubjectNameDefault.java
new file mode 100644
index 000000000..65adabfad
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/def/nsTokenUserKeySubjectNameDefault.java
@@ -0,0 +1,456 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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());
+ }
+ }
+ CMS.debug("pattern = " + pattern);
+ sbjname = mapPattern(request, pattern);
+ CMS.debug("nsTokenUserKeySubjectNameDefault: getSubjectName(): subject name mapping done");
+ 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/base/common/src/com/netscape/cms/profile/input/CMCCertReqInput.java b/base/common/src/com/netscape/cms/profile/input/CMCCertReqInput.java
new file mode 100644
index 000000000..77d4b1ce0
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/input/CMCCertReqInput.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.cms.profile.input;
+
+import java.util.Locale;
+
+import netscape.security.x509.X509CertInfo;
+
+import org.mozilla.jss.pkix.cmc.TaggedRequest;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.common.EnrollProfile;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/input/CertReqInput.java b/base/common/src/com/netscape/cms/profile/input/CertReqInput.java
new file mode 100644
index 000000000..0b7e9f071
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/input/CertReqInput.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.profile.input;
+
+import java.util.Locale;
+
+import netscape.security.pkcs.PKCS10;
+import netscape.security.util.DerInputStream;
+import netscape.security.x509.X509CertInfo;
+
+import org.mozilla.jss.pkix.cmc.TaggedRequest;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.common.EnrollProfile;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/input/DualKeyGenInput.java b/base/common/src/com/netscape/cms/profile/input/DualKeyGenInput.java
new file mode 100644
index 000000000..18b9ecf52
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/input/DualKeyGenInput.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.profile.input;
+
+import java.util.Locale;
+
+import netscape.security.pkcs.PKCS10;
+import netscape.security.util.DerInputStream;
+import netscape.security.x509.X509CertInfo;
+
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.common.EnrollProfile;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/input/EncryptionKeyGenInput.java b/base/common/src/com/netscape/cms/profile/input/EncryptionKeyGenInput.java
new file mode 100644
index 000000000..d59629f78
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/input/EncryptionKeyGenInput.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.input;
+
+import java.util.Locale;
+
+import netscape.security.pkcs.PKCS10;
+import netscape.security.util.DerInputStream;
+import netscape.security.x509.X509CertInfo;
+
+import org.mozilla.jss.pkix.cmc.TaggedRequest;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.common.EnrollProfile;
+
+/**
+ * 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 EncryptionKeyGenInput 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 EncryptionKeyGenInput() {
+ 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_ENC_KEY_GEN_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_ENC_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("EncryptionKeyGenInput: 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("EncryptionKeyGenInput: 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.ENC_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.ENC_KEYGEN_REQUEST, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_KEYGEN_REQ"));
+ }
+ return null;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/profile/input/EnrollInput.java b/base/common/src/com/netscape/cms/profile/input/EnrollInput.java
new file mode 100644
index 000000000..c4269ba7d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/input/EnrollInput.java
@@ -0,0 +1,303 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.ProofOfPossession;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.common.EnrollProfile;
+
+/**
+ * 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<String> mValueNames = new Vector<String>();
+ protected Vector<String> mConfigNames = new Vector<String>();
+ 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<String> getValueNames() {
+ return mValueNames.elements();
+ }
+
+ public void addConfigName(String name) {
+ mConfigNames.addElement(name);
+ }
+
+ public Enumeration<String> 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();
+
+ CryptoToken verifyToken = null;
+ String tokenName = CMS.getConfigStore().getString("ca.requestVerify.token", "internal");
+ if (tokenName.equals("internal")) {
+ CMS.debug("POP verification using internal token");
+ certReqMsg.verify();
+ } else {
+ CMS.debug("POP verification using token:" + tokenName);
+ verifyToken = cm.getTokenByName(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/base/common/src/com/netscape/cms/profile/input/FileSigningInput.java b/base/common/src/com/netscape/cms/profile/input/FileSigningInput.java
new file mode 100644
index 000000000..357488186
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/input/FileSigningInput.java
@@ -0,0 +1,143 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.BufferedInputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.MessageDigest;
+import java.util.Locale;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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 < 16) {
+ 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/base/common/src/com/netscape/cms/profile/input/GenericInput.java b/base/common/src/com/netscape/cms/profile/input/GenericInput.java
new file mode 100644
index 000000000..e8edfaa6d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/input/GenericInput.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.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> getValueNames() {
+ Vector<String> v = new Vector<String>();
+ 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/base/common/src/com/netscape/cms/profile/input/ImageInput.java b/base/common/src/com/netscape/cms/profile/input/ImageInput.java
new file mode 100644
index 000000000..30570b56c
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/input/ImageInput.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.cms.profile.input;
+
+import java.util.Locale;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/input/KeyGenInput.java b/base/common/src/com/netscape/cms/profile/input/KeyGenInput.java
new file mode 100644
index 000000000..c2b3cf0d5
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/input/KeyGenInput.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.input;
+
+import java.util.Locale;
+
+import netscape.security.pkcs.PKCS10;
+import netscape.security.util.DerInputStream;
+import netscape.security.x509.X509CertInfo;
+
+import org.mozilla.jss.pkix.cmc.TaggedRequest;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.common.EnrollProfile;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/input/SerialNumRenewInput.java b/base/common/src/com/netscape/cms/profile/input/SerialNumRenewInput.java
new file mode 100644
index 000000000..542a2c940
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/input/SerialNumRenewInput.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.cms.profile.input;
+
+import java.util.Locale;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/input/SigningKeyGenInput.java b/base/common/src/com/netscape/cms/profile/input/SigningKeyGenInput.java
new file mode 100644
index 000000000..aa471d4f6
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/input/SigningKeyGenInput.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.input;
+
+import java.util.Locale;
+
+import netscape.security.pkcs.PKCS10;
+import netscape.security.util.DerInputStream;
+import netscape.security.x509.X509CertInfo;
+
+import org.mozilla.jss.pkix.cmc.TaggedRequest;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.common.EnrollProfile;
+
+/**
+ * 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 SigningKeyGenInput 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 SigningKeyGenInput() {
+ 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_SIGN_KEY_GEN_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_SIGN_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("SigningKeyGenInput: 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("SigningKeyGenInput: 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.SIGN_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.SIGN_KEYGEN_REQUEST, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_KEYGEN_REQ"));
+ }
+ return null;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/profile/input/SubjectDNInput.java b/base/common/src/com/netscape/cms/profile/input/SubjectDNInput.java
new file mode 100644
index 000000000..a12351f8a
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/input/SubjectDNInput.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.profile.input;
+
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.common.EnrollProfile;
+
+/**
+ * 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<String> getValueNames() {
+ Vector<String> v = new Vector<String>();
+ 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/base/common/src/com/netscape/cms/profile/input/SubjectNameInput.java b/base/common/src/com/netscape/cms/profile/input/SubjectNameInput.java
new file mode 100644
index 000000000..db70da666
--- /dev/null
+++ b/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.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.common.EnrollProfile;
+
+/**
+ * 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<String> getValueNames() {
+ Vector<String> v = new Vector<String>();
+ 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/base/common/src/com/netscape/cms/profile/input/SubmitterInfoInput.java b/base/common/src/com/netscape/cms/profile/input/SubmitterInfoInput.java
new file mode 100644
index 000000000..984706f42
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/input/SubmitterInfoInput.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.profile.input;
+
+import java.util.Locale;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/input/nsHKeyCertReqInput.java b/base/common/src/com/netscape/cms/profile/input/nsHKeyCertReqInput.java
new file mode 100644
index 000000000..3c6067891
--- /dev/null
+++ b/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.Locale;
+
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.common.EnrollProfile;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/input/nsNKeyCertReqInput.java b/base/common/src/com/netscape/cms/profile/input/nsNKeyCertReqInput.java
new file mode 100644
index 000000000..196798683
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/input/nsNKeyCertReqInput.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.util.Locale;
+
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.common.EnrollProfile;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/output/CMMFOutput.java b/base/common/src/com/netscape/cms/profile/output/CMMFOutput.java
new file mode 100644
index 000000000..2253460b1
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/output/CMMFOutput.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.profile.output;
+
+import java.io.ByteArrayOutputStream;
+import java.security.cert.X509Certificate;
+import java.util.Locale;
+
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.X509CertImpl;
+
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.pkix.cmmf.CertOrEncCert;
+import org.mozilla.jss.pkix.cmmf.CertRepContent;
+import org.mozilla.jss.pkix.cmmf.CertResponse;
+import org.mozilla.jss.pkix.cmmf.CertifiedKeyPair;
+import org.mozilla.jss.pkix.cmmf.PKIStatusInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.ICertPrettyPrint;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileOutput;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.common.EnrollProfile;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/output/CertOutput.java b/base/common/src/com/netscape/cms/profile/output/CertOutput.java
new file mode 100644
index 000000000..1293c055c
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/output/CertOutput.java
@@ -0,0 +1,120 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Locale;
+
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.ICertPrettyPrint;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileOutput;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.common.EnrollProfile;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/output/EnrollOutput.java b/base/common/src/com/netscape/cms/profile/output/EnrollOutput.java
new file mode 100644
index 000000000..25a4b4908
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/output/EnrollOutput.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.output;
+
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileOutput;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * This class implements the basic enrollment output.
+ *
+ * @version $Revision$, $Date$
+ */
+public abstract class EnrollOutput implements IProfileOutput {
+ private IConfigStore mConfig = null;
+ private Vector<String> mValueNames = new Vector<String>();
+ protected Vector<String> mConfigNames = new Vector<String>();
+
+ /**
+ * 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<String> 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<String> 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/base/common/src/com/netscape/cms/profile/output/PKCS7Output.java b/base/common/src/com/netscape/cms/profile/output/PKCS7Output.java
new file mode 100644
index 000000000..0e01e15dd
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/output/PKCS7Output.java
@@ -0,0 +1,158 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.profile.output;
+
+import java.io.ByteArrayOutputStream;
+import java.security.cert.X509Certificate;
+import java.util.Locale;
+
+import netscape.security.pkcs.ContentInfo;
+import netscape.security.pkcs.PKCS7;
+import netscape.security.pkcs.SignerInfo;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.ICertPrettyPrint;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileOutput;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.common.EnrollProfile;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/output/nsNKeyOutput.java b/base/common/src/com/netscape/cms/profile/output/nsNKeyOutput.java
new file mode 100644
index 000000000..6bf03f436
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/output/nsNKeyOutput.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.profile.output;
+
+import java.util.Locale;
+
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileOutput;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.common.EnrollProfile;
+
+/**
+ * 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/base/common/src/com/netscape/cms/profile/updater/SubsystemGroupUpdater.java b/base/common/src/com/netscape/cms/profile/updater/SubsystemGroupUpdater.java
new file mode 100644
index 000000000..52c87113d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/profile/updater/SubsystemGroupUpdater.java
@@ -0,0 +1,321 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.ldap.LDAPException;
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileUpdater;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.usrgrp.IGroup;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.certsrv.usrgrp.IUser;
+import com.netscape.cms.profile.common.EnrollProfile;
+
+/**
+ * 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 {
+
+ private IProfile mProfile = null;
+ private EnrollProfile mEnrollProfile = null;
+ private IConfigStore mConfig = null;
+ private ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+ private Vector<String> mConfigNames = new Vector<String>();
+ private Vector<String> mValueNames = new Vector<String>();
+
+ private final static String LOGGING_SIGNED_AUDIT_CONFIG_ROLE =
+ "LOGGING_SIGNED_AUDIT_CONFIG_ROLE_3";
+ private final static String SIGNED_AUDIT_PASSWORD_VALUE = "********";
+ private final static String SIGNED_AUDIT_EMPTY_NAME_VALUE_PAIR = "Unknown";
+ private final static String SIGNED_AUDIT_NAME_VALUE_DELIMITER = ";;";
+ private final static String SIGNED_AUDIT_NAME_VALUE_PAIRS_DELIMITER = "+";
+
+ public SubsystemGroupUpdater() {
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ mConfig = config;
+ mProfile = profile;
+ mEnrollProfile = (EnrollProfile) profile;
+ }
+
+ public Enumeration<String> 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 {
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ 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) {
+ }
+ String auditParams = "Scope;;users+Operation;;OP_ADD+source;;SubsystemGroupUpdater" +
+ "+Resource;;" + id +
+ "+fullname;;" + id +
+ "+state;;1" +
+ "+userType;;agentType+email;;<null>+password;;<null>+phone;;<null>";
+
+ 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");
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams);
+ audit(auditMessage);
+
+ String b64 = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ try {
+ byte[] certEncoded = cert.getEncoded();
+ b64 = CMS.BtoA(certEncoded).trim();
+
+ // extract all line separators
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < b64.length(); i++) {
+ if (!Character.isWhitespace(b64.charAt(i))) {
+ sb.append(b64.charAt(i));
+ }
+ }
+ b64 = sb.toString();
+ } catch (Exception ence) {
+ CMS.debug("SubsystemGroupUpdater update: user cert encoding failed: " + ence);
+ }
+
+ auditParams = "Scope;;certs+Operation;;OP_ADD+source;;SubsystemGroupUpdater" +
+ "+Resource;;" + id +
+ "+cert;;" + b64;
+
+ system.addUserCert(user);
+ CMS.debug("SubsystemGroupUpdater update: successfully add the user certificate");
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams);
+ audit(auditMessage);
+ } catch (LDAPException e) {
+ CMS.debug("UpdateSubsystemGroup: update " + e.toString());
+ if (e.getLDAPResultCode() != LDAPException.ENTRY_ALREADY_EXISTS) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams);
+ audit(auditMessage);
+ throw new EProfileException(e.toString());
+ }
+ } catch (Exception e) {
+ CMS.debug("UpdateSubsystemGroup: update addUser " + e.toString());
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams);
+ audit(auditMessage);
+ throw new EProfileException(e.toString());
+ }
+
+ IGroup group = null;
+ String groupName = "Subsystem Group";
+ auditParams = "Scope;;groups+Operation;;OP_MODIFY+source;;SubsystemGroupUpdater" +
+ "+Resource;;" + groupName;
+
+ try {
+ group = system.getGroupFromName(groupName);
+
+ auditParams += "+user;;";
+ Enumeration<String> members = group.getMemberNames();
+ while (members.hasMoreElements()) {
+ auditParams += members.nextElement();
+ if (members.hasMoreElements()) {
+ auditParams += ",";
+ }
+ }
+
+ if (!group.isMember(id)) {
+ auditParams += "," + id;
+ group.addMemberName(id);
+ system.modifyGroup(group);
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams);
+ audit(auditMessage);
+
+ CMS.debug("UpdateSubsystemGroup: update: successfully added the user to the group.");
+ } else {
+ CMS.debug("UpdateSubsystemGroup: update: user already a member of the group");
+ }
+ } catch (Exception e) {
+ CMS.debug("UpdateSubsystemGroup update: modifyGroup " + e.toString());
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams);
+ audit(auditMessage);
+ }
+ }
+
+ 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");
+ }
+
+ private void audit(String msg) {
+ if (mSignedAuditLogger == null) {
+ return;
+ }
+
+ mSignedAuditLogger.log(ILogger.EV_SIGNED_AUDIT,
+ null,
+ ILogger.S_SIGNED_AUDIT,
+ ILogger.LL_SECURITY,
+ msg);
+ }
+
+ private String auditSubjectID() {
+ 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/base/common/src/com/netscape/cms/publish/mappers/AVAPattern.java b/base/common/src/com/netscape/cms/publish/mappers/AVAPattern.java
new file mode 100644
index 000000000..7f70722d0
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/mappers/AVAPattern.java
@@ -0,0 +1,594 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software 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 java.io.IOException;
+import java.io.PushbackReader;
+import java.io.StringReader;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.ldap.LDAPDN;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.GeneralNameInterface;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.LdapV3DNStrConverter;
+import netscape.security.x509.OIDMap;
+import netscape.security.x509.SubjectAlternativeNameExtension;
+import netscape.security.x509.X500Name;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.publish.ECompSyntaxErr;
+import com.netscape.certsrv.request.IRequest;
+
+//////////////////////
+// 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<GeneralNameInterface> 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<String> avas = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/publish/mappers/LdapCaSimpleMap.java b/base/common/src/com/netscape/cms/publish/mappers/LdapCaSimpleMap.java
new file mode 100644
index 000000000..bbf641540
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/mappers/LdapCaSimpleMap.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.publish.mappers;
+
+import java.io.IOException;
+import java.security.cert.X509Certificate;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+import netscape.ldap.LDAPv3;
+import netscape.ldap.util.DN;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CRLImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ELdapServerDownException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.ILdapMapper;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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);
+ } 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" };
+
+ 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<String> getDefaultParams() {
+ Vector<String> v = new Vector<String>();
+
+ v.addElement(PROP_DNPATTERN + "=");
+ v.addElement(PROP_CREATECA + "=true");
+ return v;
+ }
+
+ public Vector<String> getInstanceParams() {
+ Vector<String> v = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/publish/mappers/LdapCertCompsMap.java b/base/common/src/com/netscape/cms/publish/mappers/LdapCertCompsMap.java
new file mode 100644
index 000000000..2373e3c66
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/mappers/LdapCertCompsMap.java
@@ -0,0 +1,178 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.security.cert.CRLException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.Vector;
+
+import netscape.ldap.LDAPConnection;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CRLImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.ILdapMapper;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> getDefaultParams() {
+ Vector<String> v = super.getDefaultParams();
+
+ return v;
+ }
+
+ public Vector<String> getInstanceParams() {
+ Vector<String> 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/base/common/src/com/netscape/cms/publish/mappers/LdapCertExactMap.java b/base/common/src/com/netscape/cms/publish/mappers/LdapCertExactMap.java
new file mode 100644
index 000000000..11b53a797
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/mappers/LdapCertExactMap.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.publish.mappers;
+
+import java.security.cert.X509Certificate;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+import netscape.ldap.LDAPv3;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CRLImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ELdapServerDownException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.ILdapMapper;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> getDefaultParams() {
+ Vector<String> v = new Vector<String>();
+
+ return v;
+ }
+
+ public Vector<String> getInstanceParams() {
+ Vector<String> v = new Vector<String>();
+
+ 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 {
+ 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/base/common/src/com/netscape/cms/publish/mappers/LdapCertSubjMap.java b/base/common/src/com/netscape/cms/publish/mappers/LdapCertSubjMap.java
new file mode 100644
index 000000000..4d5ff38c8
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/mappers/LdapCertSubjMap.java
@@ -0,0 +1,343 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.security.cert.X509Certificate;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+import netscape.ldap.LDAPv3;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CRLImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ELdapServerDownException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.ILdapMapper;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> getDefaultParams() {
+ Vector<String> v = new Vector<String>();
+
+ 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<String> getInstanceParams() {
+ Vector<String> v = new Vector<String>();
+
+ 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 {
+ 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<String> mapAll(LDAPConnection conn, Object obj)
+ throws ELdapException {
+ Vector<String> v = new Vector<String>();
+
+ 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 {
+ 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<String> 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/base/common/src/com/netscape/cms/publish/mappers/LdapCrlIssuerCompsMap.java b/base/common/src/com/netscape/cms/publish/mappers/LdapCrlIssuerCompsMap.java
new file mode 100644
index 000000000..654de5d30
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/mappers/LdapCrlIssuerCompsMap.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.cms.publish.mappers;
+
+import java.security.cert.CRLException;
+import java.util.Vector;
+
+import netscape.ldap.LDAPConnection;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CRLImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.ILdapMapper;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> getDefaultParams() {
+ Vector<String> v = super.getDefaultParams();
+
+ //v.addElement("crlAttr=" + LdapCrlPublisher.LDAP_CRL_ATTR);
+ return v;
+ }
+
+ public Vector<String> getInstanceParams() {
+ Vector<String> 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/base/common/src/com/netscape/cms/publish/mappers/LdapDNCompsMap.java b/base/common/src/com/netscape/cms/publish/mappers/LdapDNCompsMap.java
new file mode 100644
index 000000000..73549f1b5
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/mappers/LdapDNCompsMap.java
@@ -0,0 +1,457 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+import netscape.ldap.LDAPv3;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.AVA;
+import netscape.security.x509.RDN;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X500NameAttrMap;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ELdapServerDownException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.ILdapPlugin;
+
+/**
+ * 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<String> getDefaultParams() {
+ Vector<String> v = new Vector<String>();
+
+ v.addElement("baseDN=");
+ v.addElement("dnComps=");
+ v.addElement("filterComps=");
+ return v;
+ }
+
+ public Vector<String> getInstanceParams() {
+ Vector<String> v = new Vector<String>();
+
+ 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<RDN> dnRdns = new Vector<RDN>();
+ 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<RDN> 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<Object> {
+ private static final long serialVersionUID = 4210302171279891828L;
+
+ 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/base/common/src/com/netscape/cms/publish/mappers/LdapEnhancedMap.java b/base/common/src/com/netscape/cms/publish/mappers/LdapEnhancedMap.java
new file mode 100644
index 000000000..c9a7f867c
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/mappers/LdapEnhancedMap.java
@@ -0,0 +1,640 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software 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 java.io.IOException;
+import java.security.cert.X509Certificate;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+import netscape.ldap.LDAPv3;
+import netscape.ldap.util.DN;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CRLImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ELdapServerDownException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.ILdapMapper;
+import com.netscape.certsrv.request.IRequest;
+
+//////////////////////
+// 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<String> defaultParams = new Vector<String>();
+
+ 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);
+ } 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<String> getDefaultParams() {
+ return defaultParams;
+ }
+
+ public Vector<String> getInstanceParams() {
+ Vector<String> v = new Vector<String>();
+
+ 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<String> v = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/publish/mappers/LdapSimpleMap.java b/base/common/src/com/netscape/cms/publish/mappers/LdapSimpleMap.java
new file mode 100644
index 000000000..642729673
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/mappers/LdapSimpleMap.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.mappers;
+
+import java.io.IOException;
+import java.security.cert.X509Certificate;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+import netscape.ldap.LDAPv3;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CRLImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ELdapServerDownException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.ILdapMapper;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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);
+ } 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<String> getDefaultParams() {
+ Vector<String> v = new Vector<String>();
+
+ v.addElement(PROP_DNPATTERN + "=");
+ return v;
+ }
+
+ public Vector<String> getInstanceParams() {
+ Vector<String> v = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/publish/mappers/MapAVAPattern.java b/base/common/src/com/netscape/cms/publish/mappers/MapAVAPattern.java
new file mode 100644
index 000000000..7aeb672d0
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/mappers/MapAVAPattern.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.publish.mappers;
+
+import java.io.IOException;
+import java.io.PushbackReader;
+import java.io.StringReader;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.ldap.LDAPDN;
+import netscape.security.x509.AVA;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.GeneralNameInterface;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.LdapV3DNStrConverter;
+import netscape.security.x509.OIDMap;
+import netscape.security.x509.SubjectAlternativeNameExtension;
+import netscape.security.x509.X500Name;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.publish.ECompSyntaxErr;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<GeneralNameInterface> 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<String> avas = new Vector<String>();
+ 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/base/common/src/com/netscape/cms/publish/mappers/MapDNPattern.java b/base/common/src/com/netscape/cms/publish/mappers/MapDNPattern.java
new file mode 100644
index 000000000..7a9025b1d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/mappers/MapDNPattern.java
@@ -0,0 +1,201 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.io.PushbackReader;
+import java.io.StringReader;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.X500Name;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<MapRDNPattern> rdnPatterns = new Vector<MapRDNPattern>();
+ 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<String> reqAttrs = new Vector<String>();
+
+ 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<String> certAttrs = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/publish/mappers/MapRDNPattern.java b/base/common/src/com/netscape/cms/publish/mappers/MapRDNPattern.java
new file mode 100644
index 000000000..c1688345b
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/mappers/MapRDNPattern.java
@@ -0,0 +1,217 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.io.PushbackReader;
+import java.io.StringReader;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.X500Name;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<MapAVAPattern> avaPatterns = new Vector<MapAVAPattern>();
+ 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<String> reqAttrs = new Vector<String>();
+
+ 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<String> certAttrs = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/publish/mappers/NoMap.java b/base/common/src/com/netscape/cms/publish/mappers/NoMap.java
new file mode 100644
index 000000000..155c54ce0
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/mappers/NoMap.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.publish.mappers;
+
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.ldap.LDAPConnection;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.publish.ILdapMapper;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<String> getDefaultParams() {
+ Vector<String> v = new Vector<String>();
+ return v;
+ }
+
+ public Vector<String> getInstanceParams() {
+ Vector<String> v = new Vector<String>();
+ return v;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/publish/publishers/FileBasedPublisher.java b/base/common/src/com/netscape/cms/publish/publishers/FileBasedPublisher.java
new file mode 100644
index 000000000..cb13b2452
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/publishers/FileBasedPublisher.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.cms.publish.publishers;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.math.BigInteger;
+import java.security.cert.CRLException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.util.Locale;
+import java.util.TimeZone;
+import java.util.Vector;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import netscape.ldap.LDAPConnection;
+
+import org.mozilla.jss.util.Base64OutputStream;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.ILdapPublisher;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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<String> getInstanceParams() {
+ Vector<String> v = new Vector<String>();
+ 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<String> getDefaultParams() {
+ Vector<String> v = new Vector<String>();
+
+ 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;
+
+ 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();
+
+ fos = new FileOutputStream(tempFile);
+ fos.write(Utils.base64encode(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/base/common/src/com/netscape/cms/publish/publishers/LdapCaCertPublisher.java b/base/common/src/com/netscape/cms/publish/publishers/LdapCaCertPublisher.java
new file mode 100644
index 000000000..e47318b76
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/publishers/LdapCaCertPublisher.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.publish.publishers;
+
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPModification;
+import netscape.ldap.LDAPModificationSet;
+import netscape.ldap.LDAPSSLSocketFactoryExt;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ELdapServerDownException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.ILdapPublisher;
+
+/**
+ * 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<String> getInstanceParams() {
+ Vector<String> v = new Vector<String>();
+
+ v.addElement("caCertAttr=" + mCaCertAttr);
+ v.addElement("caObjectClass=" + mCaObjectclass);
+ return v;
+ }
+
+ public Vector<String> getDefaultParams() {
+ Vector<String> v = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/publish/publishers/LdapCertSubjPublisher.java b/base/common/src/com/netscape/cms/publish/publishers/LdapCertSubjPublisher.java
new file mode 100644
index 000000000..9000f6834
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/publishers/LdapCertSubjPublisher.java
@@ -0,0 +1,345 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPModification;
+import netscape.ldap.LDAPModificationSet;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ELdapServerDownException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.ILdapPublisher;
+
+/**
+ * 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<String> getInstanceParams() {
+ Vector<String> v = new Vector<String>();
+
+ v.addElement("certAttr=" + mCertAttr);
+ v.addElement("subjectNameAttr=" + mSubjNameAttr);
+ return v;
+ }
+
+ public Vector<String> getDefaultParams() {
+ Vector<String> v = new Vector<String>();
+
+ 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
+ @SuppressWarnings("unchecked")
+ Enumeration<byte[]> vals = certs.getByteValues();
+ byte[] val = null;
+
+ while (vals.hasMoreElements()) {
+ val = vals.nextElement();
+ if (PublisherUtils.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 (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/base/common/src/com/netscape/cms/publish/publishers/LdapCertificatePairPublisher.java b/base/common/src/com/netscape/cms/publish/publishers/LdapCertificatePairPublisher.java
new file mode 100644
index 000000000..c65ff79d5
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/publishers/LdapCertificatePairPublisher.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.publish.publishers;
+
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPModification;
+import netscape.ldap.LDAPModificationSet;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ELdapServerDownException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.ILdapPublisher;
+
+/**
+ * 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<String> getInstanceParams() {
+ Vector<String> v = new Vector<String>();
+
+ v.addElement("crossCertPairAttr=" + mCrossCertPairAttr);
+ v.addElement("caObjectClass=" + mCaObjectclass);
+ return v;
+ }
+
+ public Vector<String> getInstanceParamsWithExtras() {
+ return getInstanceParams();
+ }
+
+ public Vector<String> getDefaultParams() {
+ Vector<String> v = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/publish/publishers/LdapCrlPublisher.java b/base/common/src/com/netscape/cms/publish/publishers/LdapCrlPublisher.java
new file mode 100644
index 000000000..6826cc801
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/publishers/LdapCrlPublisher.java
@@ -0,0 +1,379 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.security.cert.CRLException;
+import java.security.cert.X509CRL;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPModification;
+import netscape.ldap.LDAPModificationSet;
+import netscape.ldap.LDAPSSLSocketFactoryExt;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ELdapServerDownException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.ILdapPublisher;
+
+/**
+ * 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<String> getInstanceParams() {
+ Vector<String> v = new Vector<String>();
+
+ v.addElement("crlAttr=" + mCrlAttr);
+ v.addElement("crlObjectClass=" + mCrlObjectClass);
+ return v;
+ }
+
+ public Vector<String> getDefaultParams() {
+ Vector<String> v = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/publish/publishers/LdapEncryptCertPublisher.java b/base/common/src/com/netscape/cms/publish/publishers/LdapEncryptCertPublisher.java
new file mode 100644
index 000000000..d2c488620
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/publishers/LdapEncryptCertPublisher.java
@@ -0,0 +1,359 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.math.BigInteger;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPModification;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.RevocationReason;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ca.ICAService;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ELdapServerDownException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.ILdapPublisher;
+
+/**
+ * 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<String> getInstanceParams() {
+ Vector<String> v = new Vector<String>();
+
+ v.addElement("certAttr=" + mCertAttr);
+ return v;
+ }
+
+ public Vector<String> getDefaultParams() {
+ Vector<String> v = new Vector<String>();
+
+ 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);
+ // 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;
+ }
+
+ @SuppressWarnings("unchecked")
+ Enumeration<byte[]> vals = attr.getByteValues();
+ byte[] val = null;
+
+ while (vals.hasMoreElements()) {
+ val = 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;
+ }
+ @SuppressWarnings("unchecked")
+ Enumeration<byte[]> vals = attr.getByteValues();
+ byte[] val = null;
+
+ while (vals.hasMoreElements()) {
+ val = (byte[]) vals.nextElement();
+ if (PublisherUtils.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;
+ }
+ @SuppressWarnings("unchecked")
+ Enumeration<String> vals = attr.getStringValues();
+ String val = null;
+
+ while (vals.hasMoreElements()) {
+ val = vals.nextElement();
+ if (val.equalsIgnoreCase(sval)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/publish/publishers/LdapUserCertPublisher.java b/base/common/src/com/netscape/cms/publish/publishers/LdapUserCertPublisher.java
new file mode 100644
index 000000000..e31ce674c
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/publishers/LdapUserCertPublisher.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) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.publish.publishers;
+
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPModification;
+import netscape.ldap.LDAPSSLSocketFactoryExt;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ELdapServerDownException;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.ILdapPublisher;
+
+/**
+ * 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<String> getInstanceParams() {
+ Vector<String> v = new Vector<String>();
+
+ v.addElement("certAttr=" + mCertAttr);
+ return v;
+ }
+
+ public Vector<String> getDefaultParams() {
+ Vector<String> v = new Vector<String>();
+
+ 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;
+ }
+ @SuppressWarnings("unchecked")
+ Enumeration<byte[]> vals = attr.getByteValues();
+ byte[] val = null;
+
+ while (vals.hasMoreElements()) {
+ val = vals.nextElement();
+ if (val.length == 0)
+ continue;
+ if (PublisherUtils.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;
+ }
+ @SuppressWarnings("unchecked")
+ Enumeration<String> vals = attr.getStringValues();
+ String val = null;
+
+ while (vals.hasMoreElements()) {
+ val = vals.nextElement();
+ if (val.equalsIgnoreCase(sval)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/publish/publishers/OCSPPublisher.java b/base/common/src/com/netscape/cms/publish/publishers/OCSPPublisher.java
new file mode 100644
index 000000000..600bbd110
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/publishers/OCSPPublisher.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.cms.publish.publishers;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.Socket;
+import java.net.URLEncoder;
+import java.security.cert.CRLException;
+import java.security.cert.X509CRL;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.ldap.LDAPConnection;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.ILdapPublisher;
+import com.netscape.cmsutil.http.HttpRequest;
+import com.netscape.cmsutil.http.JssSSLSocketFactory;
+
+/**
+ * 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<String> getInstanceParams() {
+ Vector<String> v = new Vector<String>();
+ 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<String> getDefaultParams() {
+ Vector<String> v = new Vector<String>();
+
+ 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", "UTF-8"));
+ query.append(URLEncoder.encode(CMS.BtoA(crl.getEncoded()), "UTF-8"));
+ query.append(URLEncoder.encode("\n-----END CERTIFICATE REVOCATION LIST-----", "UTF-8"));
+ 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 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/base/common/src/com/netscape/cms/publish/publishers/PublisherUtils.java b/base/common/src/com/netscape/cms/publish/publishers/PublisherUtils.java
new file mode 100644
index 000000000..af8d283dd
--- /dev/null
+++ b/base/common/src/com/netscape/cms/publish/publishers/PublisherUtils.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.publish.publishers;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Vector;
+
+/**
+ * Publisher utility class.
+ *
+ * @version $Revision$, $Date$
+ */
+public class PublisherUtils {
+ public static void checkHost(String hostname) throws UnknownHostException {
+ 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<String> v) {
+ String s[] = new String[v.size()];
+
+ v.copyInto(s);
+ return s;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/request/RequestScheduler.java b/base/common/src/com/netscape/cms/request/RequestScheduler.java
new file mode 100644
index 000000000..e0ebaefc4
--- /dev/null
+++ b/base/common/src/com/netscape/cms/request/RequestScheduler.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.cms.request;
+
+import java.util.Vector;
+
+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<Thread> mRequestThreads = new Vector<Thread>();
+
+ /**
+ * 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/base/common/src/com/netscape/cms/selftests/ASelfTest.java b/base/common/src/com/netscape/cms/selftests/ASelfTest.java
new file mode 100644
index 000000000..cdd86ccaf
--- /dev/null
+++ b/base/common/src/com/netscape/cms/selftests/ASelfTest.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 statement //
+///////////////////////
+
+package com.netscape.cms.selftests;
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import java.util.Locale;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.logging.ILogEventListener;
+import com.netscape.certsrv.selftests.EDuplicateSelfTestException;
+import com.netscape.certsrv.selftests.EInvalidSelfTestException;
+import com.netscape.certsrv.selftests.EMissingSelfTestException;
+import com.netscape.certsrv.selftests.ESelfTestException;
+import com.netscape.certsrv.selftests.ISelfTest;
+import com.netscape.certsrv.selftests.ISelfTestSubsystem;
+
+//////////////////////
+// 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/base/common/src/com/netscape/cms/selftests/ca/CAPresence.java b/base/common/src/com/netscape/cms/selftests/ca/CAPresence.java
new file mode 100644
index 000000000..c9c12bb42
--- /dev/null
+++ b/base/common/src/com/netscape/cms/selftests/ca/CAPresence.java
@@ -0,0 +1,262 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software 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 java.security.cert.CertificateParsingException;
+import java.util.Locale;
+
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509Key;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.logging.ILogEventListener;
+import com.netscape.certsrv.selftests.EDuplicateSelfTestException;
+import com.netscape.certsrv.selftests.EInvalidSelfTestException;
+import com.netscape.certsrv.selftests.EMissingSelfTestException;
+import com.netscape.certsrv.selftests.ESelfTestException;
+import com.netscape.certsrv.selftests.ISelfTestSubsystem;
+import com.netscape.cms.selftests.ASelfTest;
+
+//////////////////////
+// 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/base/common/src/com/netscape/cms/selftests/ca/CAValidity.java b/base/common/src/com/netscape/cms/selftests/ca/CAValidity.java
new file mode 100644
index 000000000..9325208f9
--- /dev/null
+++ b/base/common/src/com/netscape/cms/selftests/ca/CAValidity.java
@@ -0,0 +1,262 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software 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 java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.util.Locale;
+
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.logging.ILogEventListener;
+import com.netscape.certsrv.selftests.EDuplicateSelfTestException;
+import com.netscape.certsrv.selftests.EInvalidSelfTestException;
+import com.netscape.certsrv.selftests.EMissingSelfTestException;
+import com.netscape.certsrv.selftests.ESelfTestException;
+import com.netscape.certsrv.selftests.ISelfTestSubsystem;
+import com.netscape.cms.selftests.ASelfTest;
+
+//////////////////////
+// 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/base/common/src/com/netscape/cms/selftests/common/SystemCertsVerification.java b/base/common/src/com/netscape/cms/selftests/common/SystemCertsVerification.java
new file mode 100644
index 000000000..57afffdf2
--- /dev/null
+++ b/base/common/src/com/netscape/cms/selftests/common/SystemCertsVerification.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) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+// package statement //
+///////////////////////
+
+package com.netscape.cms.selftests.common;
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import java.util.Locale;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.logging.ILogEventListener;
+import com.netscape.certsrv.selftests.EDuplicateSelfTestException;
+import com.netscape.certsrv.selftests.EInvalidSelfTestException;
+import com.netscape.certsrv.selftests.EMissingSelfTestException;
+import com.netscape.certsrv.selftests.ESelfTestException;
+import com.netscape.certsrv.selftests.ISelfTestSubsystem;
+import com.netscape.cms.selftests.ASelfTest;
+
+//////////////////////
+// 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/base/common/src/com/netscape/cms/selftests/kra/KRAPresence.java b/base/common/src/com/netscape/cms/selftests/kra/KRAPresence.java
new file mode 100644
index 000000000..01f5609bf
--- /dev/null
+++ b/base/common/src/com/netscape/cms/selftests/kra/KRAPresence.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 statement //
+///////////////////////
+
+package com.netscape.cms.selftests.kra;
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import java.security.PublicKey;
+import java.util.Locale;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogEventListener;
+import com.netscape.certsrv.selftests.EDuplicateSelfTestException;
+import com.netscape.certsrv.selftests.EInvalidSelfTestException;
+import com.netscape.certsrv.selftests.EMissingSelfTestException;
+import com.netscape.certsrv.selftests.ESelfTestException;
+import com.netscape.certsrv.selftests.ISelfTestSubsystem;
+import com.netscape.cms.selftests.ASelfTest;
+
+//////////////////////
+// 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/base/common/src/com/netscape/cms/selftests/ocsp/OCSPPresence.java b/base/common/src/com/netscape/cms/selftests/ocsp/OCSPPresence.java
new file mode 100644
index 000000000..c862362a2
--- /dev/null
+++ b/base/common/src/com/netscape/cms/selftests/ocsp/OCSPPresence.java
@@ -0,0 +1,280 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software 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 java.security.cert.CertificateParsingException;
+import java.util.Locale;
+
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509Key;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.logging.ILogEventListener;
+import com.netscape.certsrv.ocsp.IOCSPAuthority;
+import com.netscape.certsrv.security.ISigningUnit;
+import com.netscape.certsrv.selftests.EDuplicateSelfTestException;
+import com.netscape.certsrv.selftests.EInvalidSelfTestException;
+import com.netscape.certsrv.selftests.EMissingSelfTestException;
+import com.netscape.certsrv.selftests.ESelfTestException;
+import com.netscape.certsrv.selftests.ISelfTestSubsystem;
+import com.netscape.cms.selftests.ASelfTest;
+
+//////////////////////
+// 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/base/common/src/com/netscape/cms/selftests/ocsp/OCSPValidity.java b/base/common/src/com/netscape/cms/selftests/ocsp/OCSPValidity.java
new file mode 100644
index 000000000..478746827
--- /dev/null
+++ b/base/common/src/com/netscape/cms/selftests/ocsp/OCSPValidity.java
@@ -0,0 +1,280 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software 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 java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.util.Locale;
+
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.logging.ILogEventListener;
+import com.netscape.certsrv.ocsp.IOCSPAuthority;
+import com.netscape.certsrv.security.ISigningUnit;
+import com.netscape.certsrv.selftests.EDuplicateSelfTestException;
+import com.netscape.certsrv.selftests.EInvalidSelfTestException;
+import com.netscape.certsrv.selftests.EMissingSelfTestException;
+import com.netscape.certsrv.selftests.ESelfTestException;
+import com.netscape.certsrv.selftests.ISelfTestSubsystem;
+import com.netscape.cms.selftests.ASelfTest;
+
+//////////////////////
+// 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/base/common/src/com/netscape/cms/selftests/ra/RAPresence.java b/base/common/src/com/netscape/cms/selftests/ra/RAPresence.java
new file mode 100644
index 000000000..9790bf619
--- /dev/null
+++ b/base/common/src/com/netscape/cms/selftests/ra/RAPresence.java
@@ -0,0 +1,261 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software 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 java.security.PublicKey;
+import java.util.Locale;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.logging.ILogEventListener;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.certsrv.selftests.EDuplicateSelfTestException;
+import com.netscape.certsrv.selftests.EInvalidSelfTestException;
+import com.netscape.certsrv.selftests.EMissingSelfTestException;
+import com.netscape.certsrv.selftests.ESelfTestException;
+import com.netscape.certsrv.selftests.ISelfTestSubsystem;
+import com.netscape.cms.selftests.ASelfTest;
+
+//////////////////////
+// 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/base/common/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java b/base/common/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java
new file mode 100644
index 000000000..69edeb24f
--- /dev/null
+++ b/base/common/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.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 statement //
+///////////////////////
+
+package com.netscape.cms.selftests.tks;
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import java.util.Arrays;
+import java.util.Locale;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.logging.ILogEventListener;
+import com.netscape.certsrv.selftests.EDuplicateSelfTestException;
+import com.netscape.certsrv.selftests.EInvalidSelfTestException;
+import com.netscape.certsrv.selftests.EMissingSelfTestException;
+import com.netscape.certsrv.selftests.ESelfTestException;
+import com.netscape.certsrv.selftests.ISelfTestSubsystem;
+import com.netscape.cms.selftests.ASelfTest;
+import com.netscape.symkey.SessionKey;
+
+//////////////////////
+// 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;
+
+ 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, null, null);
+ 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;
+ String keySet = "defKeySet";
+
+ byte[] sessionKey = SessionKey.ComputeSessionKey(mToken, mKeyName,
+ mCardChallenge, mHostChallenge,
+ mKeyInfo, mCUID, mMacKey, mUseSoftToken, keySet, null);
+
+ // Now we just see if we can successfully generate a session key.
+ // For FIPS compliance, the routine now returns a wrapped key, which can't be extracted and compared.
+ 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 {
+ logMessage = CMS.getLogMessage("SELFTESTS_TKS_SUCCEEDED", getSelfTestName(), getSelfTestName());
+ mSelfTestSubsystem.log(logger, logMessage);
+ CMS.debug("TKSKnownSessionKey self test SUCCEEDED");
+ }
+
+ return;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/admin/ACLAdminServlet.java b/base/common/src/com/netscape/cms/servlet/admin/ACLAdminServlet.java
new file mode 100644
index 000000000..12575675c
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/admin/ACLAdminServlet.java
@@ -0,0 +1,905 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.acls.ACL;
+import com.netscape.certsrv.acls.ACLEntry;
+import com.netscape.certsrv.acls.IACL;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authorization.IAuthzManager;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.common.OpDef;
+import com.netscape.certsrv.common.ScopeDef;
+import com.netscape.certsrv.evaluators.IAccessEvaluator;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+
+/**
+ * Manage Access Control List configuration
+ *
+ * @version $Revision$, $Date$
+ */
+public class ACLAdminServlet extends AdminServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -322237202045924779L;
+ 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;
+ }
+
+ 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;
+ }
+
+ 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<ACL> res = mAuthzMgr.getACLs();
+
+ while (res.hasMoreElements()) {
+ ACL acl = (ACL) res.nextElement();
+ String desc = acl.getDescription();
+
+ if (desc == null)
+ params.put(acl.getName(), "");
+ else
+ params.put(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<String> rightsEnum = acl.rights();
+
+ StringBuffer rights = new StringBuffer();
+
+ if (rightsEnum.hasMoreElements()) {
+ while (rightsEnum.hasMoreElements()) {
+ if (rights.length() != 0) {
+ rights.append(",");
+ }
+ String right = rightsEnum.nextElement();
+
+ rights.append(right);
+ }
+ }
+
+ params.put(Constants.PR_ACL_OPS, rights.toString());
+
+ Enumeration<ACLEntry> aclEntryEnum;
+ aclEntryEnum = acl.entries();
+ String acis = "";
+
+ if (aclEntryEnum.hasMoreElements()) {
+ while (aclEntryEnum.hasMoreElements()) {
+ if (acis != "") {
+ acis += ";";
+ }
+ ACLEntry aclEntry = (ACLEntry) aclEntryEnum.nextElement();
+ String aci = aclEntry.getACLEntryString();
+
+ acis += aci;
+ }
+ }
+
+ params.put(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<IAccessEvaluator> res = mAuthzMgr.aclEvaluatorElements();
+
+ while (res.hasMoreElements()) {
+ IAccessEvaluator evaluator = res.nextElement();
+
+ // params.add(evaluator.getType(), evaluator.getDescription());
+ params.put(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<IAccessEvaluator> res = mAuthzMgr.aclEvaluatorElements();
+
+ while (res.hasMoreElements()) {
+ IAccessEvaluator evaluator = 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.put(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<String, IAccessEvaluator> 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/base/common/src/com/netscape/cms/servlet/admin/AdminResources.java b/base/common/src/com/netscape/cms/servlet/admin/AdminResources.java
new file mode 100644
index 000000000..a36c859d9
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/admin/AdminResources.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.servlet.admin;
+
+import java.util.ListResourceBundle;
+
+/**
+ * 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/base/common/src/com/netscape/cms/servlet/admin/AdminServlet.java b/base/common/src/com/netscape/cms/servlet/admin/AdminServlet.java
new file mode 100644
index 000000000..ce4c966ad
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/admin/AdminServlet.java
@@ -0,0 +1,1296 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.IAuthCredentials;
+import com.netscape.certsrv.authentication.IAuthManager;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
+import com.netscape.certsrv.authorization.IAuthzSubsystem;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.usrgrp.EUsrGrpException;
+import com.netscape.certsrv.usrgrp.IGroup;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.certsrv.usrgrp.IUser;
+import com.netscape.cms.servlet.base.UserInfo;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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 static final long serialVersionUID = 7740464244137421542L;
+ 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());
+ @SuppressWarnings("unchecked")
+ Enumeration<String> paramNames = httpReq.getParameterNames();
+ while (paramNames.hasMoreElements()) {
+ String pn = 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 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;
+
+ 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(Utils.base64decode(b64s));
+ String userid = authCode.substring(0,
+ authCode.indexOf(':'));
+ String password = authCode.substring(
+ authCode.indexOf(':') + 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");
+ }
+
+ // 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) {
+ Collection<String> names = params.keySet();
+
+ if (!names.isEmpty()) {
+ for (Iterator<String> i = names.iterator(); i.hasNext(); ) {
+ String name = i.next();
+ String value = java.net.URLEncoder.encode(
+ params.get(name), "UTF-8");
+
+ buf.append(java.net.URLEncoder.encode(name, "UTF-8") +
+ "=" + value);
+ if (i.hasNext())
+ 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();
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = 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.put(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();
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = 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<String> e = config.getPropertyNames();
+ NameValuePairs params = new NameValuePairs();
+
+ while (e.hasMoreElements()) {
+ String s = e.nextElement();
+
+ params.put(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
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = 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<IGroup> groups = null;
+
+ try {
+ groups = mUG.findGroups("*");
+ } catch (Exception e) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ StringBuffer membersString = new StringBuffer();
+
+ while (groups.hasMoreElements()) {
+ IGroup group = 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.put(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/base/common/src/com/netscape/cms/servlet/admin/AuthAdminServlet.java b/base/common/src/com/netscape/cms/servlet/admin/AuthAdminServlet.java
new file mode 100644
index 000000000..cacd0b5d0
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/admin/AuthAdminServlet.java
@@ -0,0 +1,1721 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthManagerProxy;
+import com.netscape.certsrv.authentication.AuthMgrPlugin;
+import com.netscape.certsrv.authentication.EAuthException;
+import com.netscape.certsrv.authentication.EAuthMgrNotFound;
+import com.netscape.certsrv.authentication.EAuthMgrPluginNotFound;
+import com.netscape.certsrv.authentication.IAuthManager;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.common.DestDef;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.common.OpDef;
+import com.netscape.certsrv.common.ScopeDef;
+import com.netscape.certsrv.ldap.ILdapAuthInfo;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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 static final long serialVersionUID = -6258411211380144425L;
+ 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.put(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.put("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<IAuthManager> newImpl = null;
+
+ try {
+ @SuppressWarnings("unchecked")
+ Class<IAuthManager> tmpImpl = (Class<IAuthManager>) Class.forName(classPath);
+ newImpl = tmpImpl;
+ } 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.put(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<String> e = mAuths.getPlugins().keys();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+ AuthMgrPlugin value = (AuthMgrPlugin)
+ mAuths.getPlugins().get(name);
+
+ if (value.isVisible()) {
+ params.put(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.put(name, value.getImplName() + ";invisible;" + enableStr);
+ } else {
+ params.put(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.
+ mAuths.getInstances().remove(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.put(Constants.PR_AUTH_IMPL_NAME, "");
+ if (configParams != null) {
+ for (int i = 0; i < configParams.length; i++) {
+ params.put(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.put(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.put(key, val);
+ } else {
+ params.put(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.put(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.put(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);
+
+ for (String key : saveParams.keySet()) {
+ String value = saveParams.get(key);
+
+ if (value != null)
+ rstore.put(key, value);
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/admin/AuthCredentials.java b/base/common/src/com/netscape/cms/servlet/admin/AuthCredentials.java
new file mode 100644
index 000000000..69cfd9aaf
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/admin/AuthCredentials.java
@@ -0,0 +1,109 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Enumeration;
+import java.util.Hashtable;
+
+import com.netscape.certsrv.authentication.IAuthCredentials;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+
+/**
+ * Authentication Credentials as input to the authMgr
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class AuthCredentials implements IAuthCredentials {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6938644716486895814L;
+ private Hashtable<String, Object> authCreds = null;
+ // Inserted by bskim
+ private IArgBlock argblk = null;
+
+ // Insert end
+
+ public AuthCredentials() {
+ authCreds = new Hashtable<String, Object>();
+ }
+
+ /**
+ * 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 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 credential names in this credential
+ * set. Use the Enumeration methods on the returned object to
+ * fetch the elements sequentially.
+ *
+ * @return an enumeration of the names in this credential set
+ * @see java.util.Enumeration
+ */
+ public Enumeration<String> getElements() {
+ return authCreds.keys();
+ }
+
+ // Inserted by bskim
+ public void setArgBlock(IArgBlock blk) {
+ argblk = blk;
+ return;
+ }
+
+ // Insert end
+
+ public IArgBlock getArgBlock() {
+ return argblk;
+ }
+ // Insert end
+}
diff --git a/base/common/src/com/netscape/cms/servlet/admin/CAAdminServlet.java b/base/common/src/com/netscape/cms/servlet/admin/CAAdminServlet.java
new file mode 100644
index 000000000..e7b32e844
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/admin/CAAdminServlet.java
@@ -0,0 +1,1582 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.File;
+import java.io.IOException;
+import java.net.UnknownHostException;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ca.ICMSCRLExtensions;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.common.OpDef;
+import com.netscape.certsrv.common.ScopeDef;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequestListener;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6200983242040946840L;
+
+ 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();
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = 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.put(name, rc.getString(name, ""));
+ }
+
+ params.put(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(ICertificateAuthority.PROP_NOTIFY_SUBSTORE);
+ IConfigStore rc = nc.getSubStore(ICertificateAuthority.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(ICertificateAuthority.PROP_NOTIFY_SUBSTORE);
+ IConfigStore rc = nc.getSubStore(ICertificateAuthority.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(ICertificateAuthority.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore riq = nc.getSubStore(ICertificateAuthority.PROP_REQ_IN_Q_SUBSTORE);
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = 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.put(name, riq.getString(name, ""));
+ }
+
+ params.put(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(ICertificateAuthority.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore riq = nc.getSubStore(ICertificateAuthority.PROP_REQ_IN_Q_SUBSTORE);
+
+ //set rest of the parameters
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = 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())) {
+ 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
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = 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())) {
+ 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(ICertificateAuthority.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore rc = nc.getSubStore(ICertificateAuthority.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(ICertificateAuthority.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore rc = nc.getSubStore(ICertificateAuthority.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<ICRLIssuingPoint> ips = mCA.getCRLIssuingPoints();
+
+ while (ips.hasMoreElements()) {
+ ICRLIssuingPoint ip = ips.nextElement();
+
+ if (ip != null) {
+ String ipId = ip.getId();
+
+ if (ipId != null && ipId.length() > 0)
+ params.put(ipId, ip.getDescription());
+ params.put(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) {
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = req.getParameterNames();
+ String value = "";
+
+ while (e.hasMoreElements()) {
+ String name = 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.put(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.put(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.put(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.put(Constants.PR_ENABLED, Constants.FALSE);
+ } else {
+ params.put(Constants.PR_ENABLED, Constants.TRUE);
+ }
+
+ IConfigStore crlSubStore =
+ mCA.getConfigStore().getSubStore(ICertificateAuthority.PROP_CRL_SUBSTORE);
+ Enumeration<String> crlNames = crlSubStore.getSubStoreNames();
+
+ while (crlNames.hasMoreElements()) {
+ String name = 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.put(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.put(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.put(Constants.PR_ENABLED, Constants.FALSE);
+ } else {
+ params.put(Constants.PR_ENABLED, Constants.TRUE);
+ }
+
+ IConfigStore crlSubStore =
+ mCA.getConfigStore().getSubStore(ICertificateAuthority.PROP_CRL_SUBSTORE);
+ boolean done = false;
+ Enumeration<String> crlNames = crlSubStore.getSubStoreNames();
+
+ while (crlNames.hasMoreElements()) {
+ String name = 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(ICertificateAuthority.PROP_CRL_SUBSTORE);
+ boolean done = false;
+ Enumeration<String> crlNames = crlSubStore.getSubStoreNames();
+
+ while (crlNames.hasMoreElements()) {
+ String name = 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;
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = 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(ICertificateAuthority.PROP_CRL_SUBSTORE);
+ IConfigStore crlSubStore = crlsSubStore.getSubStore(ipId);
+ IConfigStore crlExtsSubStore =
+ crlSubStore.getSubStore(ICertificateAuthority.PROP_CRLEXT_SUBSTORE);
+
+ String id = req.getParameter(Constants.RS_ID);
+
+ if (id != null) {
+ IConfigStore crlExtSubStore = crlExtsSubStore.getSubStore(id);
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = 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.put(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 = ICertificateAuthority.PROP_MASTER_CRL;
+ }
+
+ IConfigStore config = mCA.getConfigStore();
+ IConfigStore crlsSubStore = config.getSubStore(ICertificateAuthority.PROP_CRL_SUBSTORE);
+ IConfigStore crlSubStore = crlsSubStore.getSubStore(id);
+ IConfigStore crlExtsSubStore = crlSubStore.getSubStore(ICertificateAuthority.PROP_CRLEXT_SUBSTORE);
+
+ if (crlExtsSubStore != null) {
+ Enumeration<String> enumExts = crlExtsSubStore.getSubStoreNames();
+
+ while (enumExts.hasMoreElements()) {
+ String extName = enumExts.nextElement();
+ boolean crlExtEnabled = false;
+ IConfigStore crlExtSubStore = crlExtsSubStore.getSubStore(extName);
+ Enumeration<String> properties = crlExtSubStore.getPropertyNames();
+
+ while (properties.hasMoreElements()) {
+ String name = properties.nextElement();
+
+ if (name.equals(Constants.PR_ENABLE)) {
+ crlExtEnabled = crlExtSubStore.getBoolean(name, false);
+ }
+ }
+ params.put(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<ICRLIssuingPoint> ips = mCA.getCRLIssuingPoints();
+ if (ips.hasMoreElements()) {
+ ICRLIssuingPoint ip = 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 = ICertificateAuthority.PROP_MASTER_CRL;
+ }
+ ICRLIssuingPoint ip = mCA.getCRLIssuingPoint(id);
+
+ //Save New Settings to the config file
+ IConfigStore config = mCA.getConfigStore();
+ IConfigStore crlsSubStore = config.getSubStore(ICertificateAuthority.PROP_CRL_SUBSTORE);
+ IConfigStore crlSubStore = crlsSubStore.getSubStore(id);
+
+ //set reset of the parameters
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = 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.put(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 = ICertificateAuthority.PROP_MASTER_CRL;
+ }
+ IConfigStore crlsSubStore =
+ mCA.getConfigStore().getSubStore(ICertificateAuthority.PROP_CRL_SUBSTORE);
+ IConfigStore crlSubStore = crlsSubStore.getSubStore(id);
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = 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.put(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");
+ }
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> enum1 = req.getParameterNames();
+ NameValuePairs params = new NameValuePairs();
+
+ if (caConnectorConfig != null) {
+ while (enum1.hasMoreElements()) {
+ String name = enum1.nextElement();
+
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+
+ params.put(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");
+ }
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> enum1 = req.getParameterNames();
+
+ if (caConnectorConfig != null) {
+ while (enum1.hasMoreElements()) {
+ String name = 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) {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> enum1 = req.getParameterNames();
+
+ while (enum1.hasMoreElements()) {
+ String key = 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) {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> enum1 = req.getParameterNames();
+
+ while (enum1.hasMoreElements()) {
+ String key = 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(ICertificateAuthority.PROP_ENABLE_PAST_CATIME, "false");
+ params.put(Constants.PR_VALIDITY, value);
+
+ getSigningAlgConfig(params);
+ getSerialConfig(params);
+ getMaxSerialConfig(params);
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void getSigningAlgConfig(NameValuePairs params) {
+ params.put(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.put(Constants.PR_ALL_ALGORITHMS, algorStr.toString());
+ }
+
+ private void getSerialConfig(NameValuePairs params) {
+ params.put(Constants.PR_SERIAL,
+ mCA.getStartSerial());
+ }
+
+ private void getMaxSerialConfig(NameValuePairs params) {
+ params.put(Constants.PR_MAXSERIAL,
+ mCA.getMaxSerial());
+ }
+
+ private void setGeneralConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ /*
+ ISubsystem eeGateway =
+ SubsystemRegistry.getInstance().get("eeGateway");
+ */
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> enum1 = req.getParameterNames();
+ boolean restart = false;
+
+ //mCA.setMaxSerial("");
+ while (enum1.hasMoreElements()) {
+ String key = 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);
+ }
+
+ 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/base/common/src/com/netscape/cms/servlet/admin/CMSAdminServlet.java b/base/common/src/com/netscape/cms/servlet/admin/CMSAdminServlet.java
new file mode 100644
index 000000000..3a2ae0a11
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/admin/CMSAdminServlet.java
@@ -0,0 +1,3449 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.math.BigInteger;
+import java.security.KeyPair;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.BasicConstraintsExtension;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.PQGParams;
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.util.ConsolePasswordCallback;
+import org.mozilla.jss.util.PasswordCallback;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.cert.ICrossCertPairSubsystem;
+import com.netscape.certsrv.common.ConfigConstants;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.common.OpDef;
+import com.netscape.certsrv.common.ScopeDef;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ocsp.IOCSPAuthority;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.certsrv.security.ICryptoSubsystem;
+import com.netscape.certsrv.security.ISigningUnit;
+import com.netscape.certsrv.security.KeyCertData;
+import com.netscape.certsrv.selftests.EMissingSelfTestException;
+import com.netscape.certsrv.selftests.ESelfTestException;
+import com.netscape.certsrv.selftests.ISelfTest;
+import com.netscape.certsrv.selftests.ISelfTestSubsystem;
+import com.netscape.certsrv.tks.ITKSAuthority;
+import com.netscape.cmsutil.util.Cert;
+import com.netscape.cmsutil.util.Utils;
+import com.netscape.symkey.SessionKey;
+
+/**
+ * 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 static final long serialVersionUID = 714370238027440050L;
+ 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 (scope.equals(ScopeDef.SC_CERT_PRETTY_PRINT))
+ getCertPrettyPrint(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.put(Constants.PR_NT, Constants.TRUE);
+ else
+ params.put(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.put(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.put(Constants.PR_ALL_NICKNAMES, jssSubSystem.getAllCerts());
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private boolean isSubsystemInstalled(String subsystem) {
+ Enumeration<ISubsystem> e = CMS.getSubsystems();
+
+ while (e.hasMoreElements()) {
+ 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<ISubsystem> e = CMS.getSubsystems();
+ boolean isCAInstalled = false;
+ boolean isRAInstalled = false;
+ boolean isKRAInstalled = false;
+
+ while (e.hasMoreElements()) {
+ 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;
+
+ }
+
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ String caTokenName = "";
+
+ NameValuePairs params = new NameValuePairs();
+
+ params.put(Constants.PR_CIPHER_VERSION,
+ jssSubSystem.getCipherVersion());
+ params.put(Constants.PR_CIPHER_FORTEZZA, jssSubSystem.isCipherFortezza());
+ params.put(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.put(Constants.PR_TOKEN_PREFIX + tokenName, certs);
+ }
+
+ params.put(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.put(Constants.PR_CERT_CA, getCertNickname(caNickName));
+ }
+
+ if (isRAInstalled) {
+ IRegistrationAuthority ra = (IRegistrationAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_RA);
+ String raNickname = ra.getNickname();
+
+ params.put(Constants.PR_CERT_RA, getCertNickname(raNickname));
+ }
+
+ if (isKRAInstalled) {
+ IKeyRecoveryAuthority kra = (IKeyRecoveryAuthority)
+ CMS.getSubsystem(CMS.SUBSYSTEM_KRA);
+ String kraNickname = kra.getNickname();
+
+ params.put(Constants.PR_CERT_TRANS, getCertNickname(kraNickname));
+ }
+
+ String nickName = CMS.getServerCertNickname();
+
+ params.put(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 {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> enum1 = req.getParameterNames();
+ NameValuePairs params = new NameValuePairs();
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+
+ jssSubSystem.getInternalTokenName();
+ Enumeration<ISubsystem> e = CMS.getSubsystems();
+ boolean isCAInstalled = false;
+ boolean isRAInstalled = false;
+ boolean isKRAInstalled = false;
+
+ while (e.hasMoreElements()) {
+ 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;
+ }
+
+ ICertificateAuthority ca = null;
+ IRegistrationAuthority ra = null;
+ IKeyRecoveryAuthority kra = 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);
+
+ 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<ISubsystem> e = CMS.getSubsystems();
+
+ 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.put(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.put(Constants.PR_STAT_INSTALLDATE, installdate);
+ } catch (Exception e) {
+ }
+
+ try {
+ String version = cs.getString(Constants.PR_STAT_VERSION, "");
+ params.put(Constants.PR_STAT_VERSION, version);
+ } catch (Exception e) {
+ }
+
+ try {
+ String instanceId = cs.getString(Constants.PR_STAT_INSTANCEID, "");
+ params.put(Constants.PR_STAT_INSTANCEID, instanceId);
+ } catch (Exception e) {
+ }
+
+ params.put(Constants.PR_STAT_STARTUP,
+ (new Date(CMS.getStartupTime())).toString());
+ params.put(Constants.PR_STAT_TIME,
+ (new Date(System.currentTimeMillis())).toString());
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ /**
+ * Modifies database information.
+ */
+ private void setDBConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ IConfigStore dbConfig = mConfig.getSubStore(PROP_INTERNAL_DB);
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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();
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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) {
+ SessionKey.GenMasterKey(selectedToken, newKeyName); // check for errors
+ CMS.getConfigStore().putString("tks.defaultSlot", selectedToken);
+ String masterKeyPrefix = CMS.getConfigStore().getString("tks.master_key_prefix", null);
+
+ SessionKey.SetDefaultPrefix(masterKeyPrefix);
+ params.put(Constants.PR_KEY_LIST, newKeyName);
+ params.put(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();
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (name.equals(Constants.PR_TOKEN_LIST)) {
+ String selectedToken = req.getParameter(name);
+
+ 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.put(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();
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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.put(name, ldapConfig.getString(name, "Constants.FALSE"));
+ else
+ params.put(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.put(Constants.PR_SERVER_NAME,
+ dbConfig.getString("host"));
+ params.put(Constants.PR_PORT,
+ dbConfig.getString("port"));
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void loggedInToken(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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 {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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.put(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();
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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 otherNickname = "";
+ 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_NICKNAME)) {
+ otherNickname = 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.put(Constants.PR_CSR, certReq);
+ params.put(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 {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> enum1 = req.getParameterNames();
+ String tokenName = Constants.PR_INTERNAL_TOKEN_NAME;
+ String keyType = "RSA";
+ KeyCertData properties = new KeyCertData();
+
+ String newtokenname = null;
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (!key.equals("pathname")) {
+ 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);
+ 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();
+
+ if (keyType.equals("DSA")) {
+ @SuppressWarnings("unused")
+ PQGParams pqgParams =
+ jssSubSystem.getCAPQG(Integer.parseInt(keyLen), mConfig); // check for errors
+ //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 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 = "";
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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).
+ //
+
+ CMS.debug("CMSAdminServlet.installCert(): About to try jssSubSystem.importCert: "
+ + nicknameWithoutTokenName);
+ try {
+ jssSubSystem.importCert(pkcs, nicknameWithoutTokenName,
+ certType);
+ } catch (EBaseException e) {
+
+ boolean certFound = false;
+
+ String eString = e.toString();
+ if (eString.contains("Failed to find certificate that was just imported")) {
+ CMS.debug("CMSAdminServlet.installCert(): nickname="
+ + nicknameWithoutTokenName + " TokenException: " + eString);
+
+ X509Certificate cert = null;
+ try {
+ cert = CryptoManager.getInstance().findCertByNickname(nickname);
+ if (cert != null) {
+ certFound = true;
+ }
+ CMS.debug("CMSAdminServlet.installCert() Found cert just imported: " + nickname);
+ } catch (Exception ex) {
+ CMS.debug("CMSAdminServlet.installCert() Can't find cert just imported: " + ex.toString());
+ }
+ }
+
+ if (!certFound) {
+ // 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(): After second install attempt following initial error: 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);
+ if (verified == true) {
+ sendResponse(SUCCESS, null, null, resp);
+ } else {
+ sendResponse(ERROR, CMS.getUserMessage(getLocale(req), "CMS_ADMIN_SRVLT_CERT_VALIDATE_FAILED"),
+ 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 pathname = "";
+ String serverRoot = "";
+ String serverID = "";
+ String certpath = "";
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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("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 = Utils.base64decode(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.put(Constants.PR_NICKNAME, "FBCA cross-signed cert");
+ results.put(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 {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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.put(Constants.PR_NICKNAME, nickname);
+ results.put(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 {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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.put(nickname, print);
+
+ sendResponse(SUCCESS, null, pairs, resp);
+ }
+
+ private void getRootCertTrustBit(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> enum1 = req.getParameterNames();
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ String nickname = "";
+ String serialno = "";
+ String issuername = "";
+ 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.put(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 {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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 {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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 {
+
+ sendResponse(SUCCESS, null, null, resp);
+ }
+
+ private void validateCurveName(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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 {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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();
+ @SuppressWarnings("unchecked")
+ Enumeration<String> enum1 = req.getParameterNames();
+
+ String nickname = "";
+
+ while (enum1.hasMoreElements()) {
+ String key = (String) enum1.nextElement();
+ String value = req.getParameter(key);
+
+ if (key.equals(Constants.RS_ID)) {
+ nickname = getNickname(value);
+ break;
+ }
+ }
+
+ ICryptoSubsystem jssSubSystem = (ICryptoSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_CRYPTO);
+ String subjectName = jssSubSystem.getSubjectDN(nickname);
+
+ params.put(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();
+ @SuppressWarnings("unchecked")
+ Enumeration<String> enum1 = req.getParameterNames();
+
+ String nickname = "";
+
+ 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.put(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 {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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 . . .");
+ }
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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.put(Constants.PR_RUN_SELFTESTS_ON_DEMAND_CLASS,
+ CMSAdminServlet.class.getName());
+ results.put(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 = Utils.base64encode(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/base/common/src/com/netscape/cms/servlet/admin/JobsAdminServlet.java b/base/common/src/com/netscape/cms/servlet/admin/JobsAdminServlet.java
new file mode 100644
index 000000000..42ff32ebe
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/admin/JobsAdminServlet.java
@@ -0,0 +1,1007 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.common.DestDef;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.common.OpDef;
+import com.netscape.certsrv.common.ScopeDef;
+import com.netscape.certsrv.jobs.EJobsException;
+import com.netscape.certsrv.jobs.IJob;
+import com.netscape.certsrv.jobs.IJobsScheduler;
+import com.netscape.certsrv.jobs.JobPlugin;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * A class representing an administration servlet for the
+ * Jobs Scheduler and it's scheduled jobs.
+ *
+ * @version $Revision$, $Date$
+ */
+public class JobsAdminServlet extends AdminServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 561767449283982015L;
+ // ... 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.put(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<String> e = mJobsSched.getPlugins().keys();
+
+ while (e.hasMoreElements()) {
+ String name = e.nextElement();
+ JobPlugin value = mJobsSched.getPlugins().get(name);
+
+ params.put(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<String> e = mJobsSched.getInstances().keys(); e.hasMoreElements();) {
+ String name = e.nextElement();
+ IJob value = mJobsSched.getInstances().get((Object) name);
+
+ // params.add(name, value.getImplName());
+ params.put(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<IJob> e = mJobsSched.getInstances().elements(); e.hasMoreElements();) {
+ IJob jobs = 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.
+ mJobsSched.getInstances().remove(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.put(Constants.PR_JOBS_IMPL_NAME, "");
+ if (configParams != null) {
+ for (int i = 0; i < configParams.length; i++) {
+ params.put(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.put(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.put(key, val);
+ } else {
+ params.put(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.put(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.put(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.put(Constants.PR_ENABLE,
+ config.getString(IJobsScheduler.PROP_ENABLED,
+ Constants.FALSE));
+ // default 1 minute
+ params.put(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);
+
+ for (String key : saveParams.keySet()) {
+ String value = saveParams.get(key);
+
+ if (!value.equals(""))
+ rstore.put(key, value);
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/admin/KRAAdminServlet.java b/base/common/src/com/netscape/cms/servlet/admin/KRAAdminServlet.java
new file mode 100644
index 000000000..eaa5a95c4
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/admin/KRAAdminServlet.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 com.netscape.cms.servlet.admin;
+
+import java.io.IOException;
+import java.util.Enumeration;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.common.OpDef;
+import com.netscape.certsrv.common.ScopeDef;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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 {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5794220348195666729L;
+
+ 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.put(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 {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> enum1 = req.getParameterNames();
+ boolean restart = false;
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ while (enum1.hasMoreElements()) {
+ String key = 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);
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/admin/LogAdminServlet.java b/base/common/src/com/netscape/cms/servlet/admin/LogAdminServlet.java
new file mode 100644
index 000000000..1b32018bc
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/admin/LogAdminServlet.java
@@ -0,0 +1,2361 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.common.OpDef;
+import com.netscape.certsrv.common.ScopeDef;
+import com.netscape.certsrv.logging.ELogException;
+import com.netscape.certsrv.logging.ELogNotFound;
+import com.netscape.certsrv.logging.ELogPluginNotFound;
+import com.netscape.certsrv.logging.ILogEventListener;
+import com.netscape.certsrv.logging.ILogSubsystem;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.LogPlugin;
+
+/**
+ * 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 static final long serialVersionUID = -99699953656847603L;
+
+ 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<String, String> toHashtable(HttpServletRequest req) {
+ Hashtable<String, String> httpReqHash = new Hashtable<String, String>();
+ 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() + "<<<");
+ e.printStackTrace();
+ 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();
+ Enumeration<String> 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.put(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
+ */
+ @SuppressWarnings("unchecked")
+ 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<ILogEventListener> newImpl = null;
+
+ try {
+ newImpl = (Class<ILogEventListener>) 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<String> 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.put(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<String> 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.put(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.
+ mSys.getLogInsts().remove(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<String> 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;
+ }
+ }
+
+ /**
+ * 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);
+
+ // 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<String> oldConfigParms = oldinst.getInstanceParams();
+ NameValuePairs saveParams = new NameValuePairs();
+
+ // implName is always required so always include it it.
+ saveParams.put("pluginName", implname);
+ if (oldConfigParms != null) {
+ for (int i = 0; i < oldConfigParms.size(); i++) {
+ String kv = (String) oldConfigParms.elementAt(i);
+ int index = kv.indexOf('=');
+
+ saveParams.put(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<String> 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 (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();
+ @SuppressWarnings("unused")
+ 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
+
+ // 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<String> configParams = mSys.getLogDefaultParams(implname);
+ NameValuePairs params = new NameValuePairs();
+
+ // implName is always required so always send it.
+ params.put(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.put(kv, "");
+ } else {
+ params.put(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<String> configParams = logInst.getInstanceParams();
+ NameValuePairs params = new NameValuePairs();
+
+ params.put(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.put(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);
+
+ for (String key : saveParams.keySet()) {
+ String value = saveParams.get(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;
+ }
+
+ 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.put(Constants.PR_DEBUG_LOG_ENABLE, value);
+
+ value = mConfig.getString(Constants.PR_DEBUG_LOG_LEVEL, "0");
+ params.put(Constants.PR_DEBUG_LOG_LEVEL, value);
+
+ sendResponse(SUCCESS, null, params, resp);
+ }
+
+ private void setGeneralConfig(HttpServletRequest req,
+ HttpServletResponse resp) throws ServletException,
+ IOException, EBaseException {
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> enum1 = req.getParameterNames();
+ boolean restart = false;
+
+ while (enum1.hasMoreElements()) {
+ String key = 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 {
+ Integer.parseInt(value); // check for errors
+ 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/base/common/src/com/netscape/cms/servlet/admin/OCSPAdminServlet.java b/base/common/src/com/netscape/cms/servlet/admin/OCSPAdminServlet.java
new file mode 100644
index 000000000..0e6784413
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/admin/OCSPAdminServlet.java
@@ -0,0 +1,543 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.common.OpDef;
+import com.netscape.certsrv.common.ScopeDef;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ocsp.IOCSPAuthority;
+import com.netscape.certsrv.ocsp.IOCSPStore;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3349635369730415767L;
+
+ 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);
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = 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.put(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(IOCSPAuthority.PROP_DEF_STORE_ID);
+ IConfigStore SubStore = config.getSubStore(IOCSPAuthority.PROP_STORE);
+ Enumeration<String> enumStores = SubStore.getSubStoreNames();
+
+ while (enumStores.hasMoreElements()) {
+ String storeName = enumStores.nextElement();
+ boolean storeEnabled = false;
+
+ if (storeName.equals(defStore)) {
+ storeEnabled = true;
+ }
+ params.put(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.put(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.put(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 {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> enum1 = req.getParameterNames();
+
+ 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;
+
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/admin/PolicyAdminServlet.java b/base/common/src/com/netscape/cms/servlet/admin/PolicyAdminServlet.java
new file mode 100644
index 000000000..0bcb962ea
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/admin/PolicyAdminServlet.java
@@ -0,0 +1,1258 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.common.OpDef;
+import com.netscape.certsrv.common.ScopeDef;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.policy.IPolicyProcessor;
+import com.netscape.certsrv.policy.IPolicyRule;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+
+/**
+ * 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.
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class PolicyAdminServlet extends AdminServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8850646362111106656L;
+
+ 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.get(IPolicyRule.PROP_ENABLE) == null) {
+ nvps.put(IPolicyRule.PROP_ENABLE, "boolean;Enable this policy rule");
+ }
+ if (nvps.get(PROP_PREDICATE) == null) {
+ nvps.put(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<String> policyImplNames = mProcessor.getPolicyImplsInfo();
+ Enumeration<IPolicyRule> 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 = policyImplNames.nextElement();
+ IPolicyRule impl = policyImpls.nextElement();
+ String className =
+ impl.getClass().getName();
+ String desc = impl.getDescription();
+
+ nvp.put(id, className + "," + desc);
+ }
+ sendResponse(SUCCESS, null, nvp, resp);
+ }
+
+ public void listPolicyInstances(HttpServletRequest req,
+ HttpServletResponse resp)
+ throws ServletException, IOException {
+ Enumeration<String> instancesInfo = mProcessor.getPolicyInstancesInfo();
+
+ if (instancesInfo == null) {
+ sendResponse(ERROR, INVALID_POLICY_INSTANCE_CONFIG, null, resp);
+ return;
+ }
+
+ // Assemble name value pairs
+ NameValuePairs nvp = new NameValuePairs();
+
+ while (instancesInfo.hasMoreElements()) {
+ String info = instancesInfo.nextElement();
+ int i = info.indexOf(";");
+
+ nvp.put(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<String> v = mProcessor.getPolicyImplConfig(id);
+
+ if (v == null) {
+ sendResponse(ERROR, INVALID_POLICY_IMPL_ID, null, resp);
+ return;
+ }
+ NameValuePairs nvp = new NameValuePairs();
+
+ for (Enumeration<String> e = v.elements(); e.hasMoreElements();) {
+ String nv = e.nextElement();
+ int index = nv.indexOf("=");
+
+ nvp.put(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<String> v = mProcessor.getPolicyInstanceConfig(id);
+
+ if (v == null) {
+ sendResponse(ERROR, INVALID_POLICY_INST_ID, null, resp);
+ return;
+ }
+ NameValuePairs nvp = new NameValuePairs();
+
+ for (Enumeration<String> e = v.elements(); e.hasMoreElements();) {
+ String nv = e.nextElement();
+ int index = nv.indexOf("=");
+ String name = nv.substring(0, index);
+ String value = nv.substring(index + 1);
+
+ if (value == null) {
+ value = "";
+ }
+
+ nvp.put(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<String, String> ht = new Hashtable<String, String>();
+ 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<String> 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<String> e = v.elements(); e.hasMoreElements();) {
+ String nv = 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<String, String> ht = new Hashtable<String, String>();
+ 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<String> 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 (@SuppressWarnings("unchecked")
+ Enumeration<String> n = req.getParameterNames(); n.hasMoreElements();) {
+ String p = n.nextElement();
+ String l = 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/base/common/src/com/netscape/cms/servlet/admin/ProfileAdminServlet.java b/base/common/src/com/netscape/cms/servlet/admin/ProfileAdminServlet.java
new file mode 100644
index 000000000..94235f532
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/admin/ProfileAdminServlet.java
@@ -0,0 +1,2682 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.common.OpDef;
+import com.netscape.certsrv.common.ScopeDef;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IPolicyConstraint;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileEx;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.profile.IProfileOutput;
+import com.netscape.certsrv.profile.IProfilePolicy;
+import com.netscape.certsrv.profile.IProfileSubsystem;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.registry.IPluginInfo;
+import com.netscape.certsrv.registry.IPluginRegistry;
+import com.netscape.cms.profile.common.ProfilePolicy;
+
+/**
+ * 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 {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4828203666899891742L;
+
+ 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;
+ }
+
+ /**
+ * 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);
+
+ 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);
+
+ 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<String> impls = mRegistry.getIds("profile");
+ NameValuePairs nvp = new NameValuePairs();
+
+ while (impls.hasMoreElements()) {
+ String id = (String) impls.nextElement();
+ IPluginInfo info = mRegistry.getPluginInfo("profile", id);
+
+ nvp.put(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();
+
+ 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;
+ }
+ 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;
+ }
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> names = req.getParameterNames();
+ NameValuePairs nvps = new NameValuePairs();
+
+ while (names.hasMoreElements()) {
+ String name = names.nextElement();
+
+ if (name.equals("OP_SCOPE"))
+ continue;
+ if (name.equals("OP_TYPE"))
+ continue;
+ if (name.equals("RS_ID"))
+ continue;
+ nvps.put(name, req.getParameter(name));
+ }
+
+ try {
+ 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;
+ }
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> names = req.getParameterNames();
+ NameValuePairs nvps = new NameValuePairs();
+
+ while (names.hasMoreElements()) {
+ String name = names.nextElement();
+
+ if (name.equals("OP_SCOPE"))
+ continue;
+ if (name.equals("OP_TYPE"))
+ continue;
+ if (name.equals("RS_ID"))
+ continue;
+ nvps.put(name, req.getParameter(name));
+ }
+
+ try {
+ 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 = "";
+ @SuppressWarnings("unchecked")
+ Enumeration<String> names = req.getParameterNames();
+
+ while (names.hasMoreElements()) {
+ String name = 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 = "";
+ @SuppressWarnings("unchecked")
+ Enumeration<String> names = req.getParameterNames();
+
+ while (names.hasMoreElements()) {
+ String name = 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 = "";
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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();
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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();
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> names = req.getParameterNames();
+
+ while (names.hasMoreElements()) {
+ String name = 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();
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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();
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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();
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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();
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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<String> names = rule.getConfigNames();
+
+ while (names.hasMoreElements()) {
+ String name = names.nextElement();
+ IDescriptor desc = rule.getConfigDescriptor(getLocale(req), name);
+
+ if (desc == null) {
+ nvp.put(name, ";" + ";" + rule.getConfig(name));
+ } else {
+ nvp.put(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<String> names = rule.getConfigNames();
+
+ while (names.hasMoreElements()) {
+ String name = names.nextElement();
+ IDescriptor desc = rule.getConfigDescriptor(getLocale(req), name);
+
+ if (desc == null) {
+ nvp.put(name, ";" + rule.getConfig(name));
+ } else {
+ nvp.put(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<String> 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<ProfilePolicy> policies = profile.getProfilePolicies(setId);
+
+ while (policies.hasMoreElements()) {
+ IProfilePolicy policy = (IProfilePolicy) policies.nextElement();
+ IPolicyDefault def = policy.getDefault();
+ IPolicyConstraint con = policy.getConstraint();
+
+ nvp.put(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<String> outputs = profile.getProfileOutputIds();
+
+ while (outputs.hasMoreElements()) {
+ String outputId = (String) outputs.nextElement();
+ IProfileOutput output = profile.getProfileOutput(outputId);
+
+ nvp.put(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<String> inputs = profile.getProfileInputIds();
+
+ while (inputs.hasMoreElements()) {
+ String inputId = (String) inputs.nextElement();
+ IProfileInput input = profile.getProfileInput(inputId);
+
+ nvp.put(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<String> names = profileInput.getConfigNames();
+
+ while (names.hasMoreElements()) {
+ String name = names.nextElement();
+ IDescriptor desc = profileInput.getConfigDescriptor(
+ getLocale(req), name);
+ if (desc == null) {
+ nvp.put(name, ";" + ";" + profileInput.getConfig(name));
+ } else {
+ nvp.put(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<String> names = profileOutput.getConfigNames();
+
+ while (names.hasMoreElements()) {
+ String name = names.nextElement();
+ IDescriptor desc = profileOutput.getConfigDescriptor(
+ getLocale(req), name);
+ if (desc == null) {
+ nvp.put(name, ";" + ";" + profileOutput.getConfig(name));
+ } else {
+ nvp.put(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<String> e = mProfileSub.getProfileIds();
+
+ while (e.hasMoreElements()) {
+ String profileId = e.nextElement();
+
+ String status = null;
+
+ if (mProfileSub.isProfileEnable(profileId)) {
+ status = "enabled";
+ } else {
+ status = "disabled";
+ }
+
+ // mInstanceId + ";visible;" + enabled
+ nvp.put(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.put("name", profile.getName(getLocale(req)));
+ nvp.put("desc", profile.getDescription(getLocale(req)));
+ nvp.put("visible", Boolean.toString(profile.isVisible()));
+ nvp.put("enable", Boolean.toString(
+ mProfileSub.isProfileEnable(id)));
+
+ String authid = profile.getAuthenticatorId();
+
+ if (authid == null) {
+ nvp.put("auth", "");
+ } else {
+ nvp.put("auth", authid);
+ }
+ CMS.debug("ProfileAdminServlet: authid=" + authid);
+ nvp.put("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 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/base/common/src/com/netscape/cms/servlet/admin/PublisherAdminServlet.java b/base/common/src/com/netscape/cms/servlet/admin/PublisherAdminServlet.java
new file mode 100644
index 000000000..483ac42ef
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/admin/PublisherAdminServlet.java
@@ -0,0 +1,3127 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPException;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.ExtendedPluginInfo;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.Plugin;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.common.ConfigConstants;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.common.OpDef;
+import com.netscape.certsrv.common.ScopeDef;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ILdapAuthInfo;
+import com.netscape.certsrv.ldap.ILdapBoundConnFactory;
+import com.netscape.certsrv.ldap.ILdapConnInfo;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.EMapperNotFound;
+import com.netscape.certsrv.publish.EMapperPluginNotFound;
+import com.netscape.certsrv.publish.EPublisherNotFound;
+import com.netscape.certsrv.publish.EPublisherPluginNotFound;
+import com.netscape.certsrv.publish.ERuleNotFound;
+import com.netscape.certsrv.publish.ERulePluginNotFound;
+import com.netscape.certsrv.publish.ILdapMapper;
+import com.netscape.certsrv.publish.ILdapPublisher;
+import com.netscape.certsrv.publish.ILdapRule;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.publish.MapperPlugin;
+import com.netscape.certsrv.publish.MapperProxy;
+import com.netscape.certsrv.publish.PublisherPlugin;
+import com.netscape.certsrv.publish.PublisherProxy;
+import com.netscape.certsrv.publish.RulePlugin;
+import com.netscape.certsrv.security.ICryptoSubsystem;
+import com.netscape.cmsutil.password.IPasswordStore;
+
+/**
+ * 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 {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7055088618787207262L;
+
+ 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<String> mappers = p.getMapperInsts().keys();
+ Enumeration<String> publishers = p.getPublisherInsts().keys();
+
+ StringBuffer map = new StringBuffer();
+
+ for (; mappers.hasMoreElements();) {
+ String name = 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;
+
+ // 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);
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = 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.put(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.put(name, value);
+ }
+ }
+ params.put(Constants.PR_PUBLISHING_ENABLE,
+ publishcfg.getString(IPublisherProcessor.PROP_ENABLE, Constants.FALSE));
+ params.put(Constants.PR_PUBLISHING_QUEUE_ENABLE,
+ publishcfg.getString(Constants.PR_PUBLISHING_QUEUE_ENABLE, Constants.TRUE));
+ params.put(Constants.PR_PUBLISHING_QUEUE_THREADS,
+ publishcfg.getString(Constants.PR_PUBLISHING_QUEUE_THREADS, "3"));
+ params.put(Constants.PR_PUBLISHING_QUEUE_PAGE_SIZE,
+ publishcfg.getString(Constants.PR_PUBLISHING_QUEUE_PAGE_SIZE, "40"));
+ params.put(Constants.PR_PUBLISHING_QUEUE_PRIORITY,
+ publishcfg.getString(Constants.PR_PUBLISHING_QUEUE_PRIORITY, "0"));
+ params.put(Constants.PR_PUBLISHING_QUEUE_STATUS,
+ publishcfg.getString(Constants.PR_PUBLISHING_QUEUE_STATUS, "200"));
+ params.put(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 {
+
+ //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
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = req.getParameterNames();
+ String pwd = null;
+
+ while (e.hasMoreElements()) {
+ String name = 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
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = req.getParameterNames();
+ String pwd = null;
+
+ while (e.hasMoreElements()) {
+ String name = 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.put("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.put(Constants.PR_CONN_INITED,
+ "Create ssl LDAPConnection with certificate: " +
+ certNickName + dashes(70 - 44 - certNickName.length()) + " Success");
+ } catch (Exception ex) {
+ params.put(Constants.PR_CONN_INIT_FAIL,
+ "Create ssl LDAPConnection with certificate: "
+ +
+ certNickName + dashes(70 - 44 - certNickName.length()) + " failure\n"
+ + " exception: " + ex);
+ params.put(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.put(Constants.PR_CONN_OK,
+ "Connect to directory server "
+ +
+ host + " at port " + port +
+ dashes(70 - 37 - host.length() - (Integer.valueOf(port)).toString().length())
+ + " Success");
+ params.put(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.put(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.put(Constants.PR_CONN_FAIL,
+ "Connect to directory server " +
+ host + " at port " + port +
+ dashes(70 - 37 - host.length() - (Integer.valueOf(port)).toString().length()) +
+ " Failure");
+ }
+ params.put(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.put(Constants.PR_CONN_INITED,
+ "Create ssl LDAPConnection" +
+ dashes(70 - 25) + " Success");
+ } else {
+ conn = new LDAPConnection();
+ params.put(Constants.PR_CONN_INITED,
+ "Create LDAPConnection" +
+ dashes(70 - 21) + " Success");
+ }
+ } catch (Exception ex) {
+ params.put(Constants.PR_CONN_INIT_FAIL,
+ "Create LDAPConnection" +
+ dashes(70 - 21) + " Failure\n" +
+ "exception: " + ex);
+ params.put(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.put(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.put(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.put(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.put(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.put(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.put(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.put(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.put(Constants.PR_AUTH_FAIL,
+ "Authentication: Basic authentication" +
+ dashes(70 - 36) + " Failure" +
+ "\nBind to the directory as: " + bindAs +
+ dashes(70 - 26 - bindAs.length()) +
+ " Failure");
+ }
+ params.put(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.put("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.put("publishCA",
+ "Failed to publish CA certificate.");
+ int index = ex.toString().indexOf("Failed to create CA");
+
+ if (index > -1) {
+ params.put("createError",
+ ex.toString().substring(index));
+ }
+ mProcessor.shutdown();
+ // Do you want to enable LDAP publishing anyway
+ params.put(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.put("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.put("publishCRL",
+ "Failed to publish CRL.");
+ mProcessor.shutdown();
+ // Do you want to enable LDAP publishing anyway
+ params.put(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.put(Constants.PR_SAVE_OK,
+ "\n \nConfiguration changes are now committed.");
+ params.put("restarted", "Publishing is restarted.");
+ } else {
+ commit(true);
+ params.put(Constants.PR_SAVE_OK,
+ "\n \nConfiguration changes are now committed.");
+ params.put("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<String> 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.put(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<String> e = mProcessor.getMapperPlugins().keys();
+
+ while (e.hasMoreElements()) {
+ String name = 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.put(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<String> e = mProcessor.getMapperInsts().keys();
+
+ for (; e.hasMoreElements();) {
+ String name = e.nextElement();
+ ILdapMapper value = mProcessor.getMapperInstance(name);
+
+ params.put(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.
+ mProcessor.getMapperInsts().remove(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<String> 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<String> configParams = mProcessor.getMapperDefaultParams(implname);
+ NameValuePairs params = new NameValuePairs();
+
+ // implName is always required so always send it.
+ params.put(Constants.PR_MAPPER_IMPL_NAME, "");
+ if (configParams != null) {
+ for (int i = 0; i < configParams.size(); i++) {
+ String kv = configParams.elementAt(i);
+ int index = kv.indexOf('=');
+
+ params.put(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<String> configParams = mapperInst.getInstanceParams();
+ NameValuePairs params = new NameValuePairs();
+
+ params.put(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 = configParams.elementAt(i);
+ int index = kv.indexOf('=');
+
+ params.put(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<String> oldConfigParms = oldinst.getInstanceParams();
+ NameValuePairs saveParams = new NameValuePairs();
+
+ // implName is always required so always include it it.
+ saveParams.put("pluginName", implname);
+ if (oldConfigParms != null) {
+ for (int i = 0; i < oldConfigParms.size(); i++) {
+ String kv = oldConfigParms.elementAt(i);
+ int index = kv.indexOf('=');
+
+ saveParams.put(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<String> 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 = 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<String> 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 = 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.put(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<String> e = mProcessor.getRulePlugins().keys();
+
+ while (e.hasMoreElements()) {
+ String name = 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.put(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();
+ Enumeration<String> e = mProcessor.getRuleInsts().keys();
+
+ for (; e.hasMoreElements();) {
+ String name = e.nextElement();
+ ILdapRule value = (ILdapRule)
+ mProcessor.getRuleInsts().get((Object) name);
+ String enabled = value.enabled() ? "enabled" : "disabled";
+
+ params.put(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<ILdapRule> e = mProcessor.getRuleInsts().elements(); e.hasMoreElements();) {
+ ILdapRule rule = 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.
+ mProcessor.getRuleInsts().remove(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<String> configParams = mProcessor.getRuleDefaultParams(implname);
+ NameValuePairs params = new NameValuePairs();
+
+ // implName is always required so always send it.
+ params.put(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.put(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<String> configParams = ruleInst.getInstanceParams();
+ NameValuePairs params = new NameValuePairs();
+
+ params.put(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.put(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<String> oldConfigParms = oldinst.getInstanceParams();
+ NameValuePairs saveParams = new NameValuePairs();
+
+ // implName is always required so always include it it.
+ saveParams.put("pluginName", implname);
+ if (oldConfigParms != null) {
+ for (int i = 0; i < oldConfigParms.size(); i++) {
+ String kv = oldConfigParms.elementAt(i);
+ int index = kv.indexOf('=');
+
+ saveParams.put(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<String> 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 = 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<String> 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 = 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.put(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<String> e = mProcessor.getPublisherPlugins().keys();
+
+ while (e.hasMoreElements()) {
+ String name = 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.put(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();
+ Enumeration<String> e = mProcessor.getPublisherInsts().keys();
+
+ for (; e.hasMoreElements();) {
+ String name = e.nextElement();
+ ILdapPublisher value = mProcessor.getPublisherInstance(name);
+
+ if (value == null)
+ continue;
+ params.put(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<String> e = mProcessor.getPublisherInsts().keys(); e.hasMoreElements();) {
+ String name = 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.
+ mProcessor.getPublisherInsts().remove(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<String> configParams = mProcessor.getPublisherDefaultParams(implname);
+ NameValuePairs params = new NameValuePairs();
+
+ // implName is always required so always send it.
+ params.put(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.put(kv, "");
+ } else {
+ params.put(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<String> configParams = publisherInst.getInstanceParams();
+ NameValuePairs params = new NameValuePairs();
+
+ params.put(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.put(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<String> oldConfigParms = oldinst.getInstanceParams();
+ NameValuePairs saveParams = new NameValuePairs();
+ String pubType = "";
+
+ // implName is always required so always include it it.
+ saveParams.put("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.put(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.put("caObjectClassAdded", instancesConfig.getString(id + ".caObjectClassAdded", ""));
+ saveParams.put("caObjectClassDeleted", instancesConfig.getString(id + ".caObjectClassDeleted", ""));
+ } else if (pubType.equals("crl")) {
+ saveParams.put("crlObjectClassAdded", instancesConfig.getString(id + ".crlObjectClassAdded", ""));
+ saveParams.put("crlObjectClassDeleted", instancesConfig.getString(id + ".crlObjectClassDeleted", ""));
+ }
+
+ // create new substore.
+
+ Vector<String> 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.get(objName);
+ oldAdded = saveParams.get(objName + "Added");
+ oldDeleted = saveParams.get(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);
+
+ for (String key : saveParams.keySet()) {
+ String value = saveParams.get(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/base/common/src/com/netscape/cms/servlet/admin/RAAdminServlet.java b/base/common/src/com/netscape/cms/servlet/admin/RAAdminServlet.java
new file mode 100644
index 000000000..5bdb14177
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/admin/RAAdminServlet.java
@@ -0,0 +1,584 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Enumeration;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.common.OpDef;
+import com.netscape.certsrv.common.ScopeDef;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+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 {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8417319111438832435L;
+
+ 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();
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = 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.put(name, rc.getString(name, ""));
+ }
+
+ params.put(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(IRegistrationAuthority.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore rc = nc.getSubStore(IRegistrationAuthority.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(IRegistrationAuthority.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore rc = nc.getSubStore(IRegistrationAuthority.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(IRegistrationAuthority.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore riq = nc.getSubStore(IRegistrationAuthority.PROP_REQ_IN_Q_SUBSTORE);
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = 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.put(name, riq.getString(name, ""));
+ }
+
+ params.put(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(IRegistrationAuthority.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore riq = nc.getSubStore(IRegistrationAuthority.PROP_REQ_IN_Q_SUBSTORE);
+
+ //set rest of the parameters
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = 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
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = req.getParameterNames();
+
+ while (e.hasMoreElements()) {
+ String name = 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(IRegistrationAuthority.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore rc = nc.getSubStore(IRegistrationAuthority.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(IRegistrationAuthority.PROP_NOTIFY_SUBSTORE);
+
+ IConfigStore rc = nc.getSubStore(IRegistrationAuthority.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"))
+ }
+ }
+ */
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> enum1 = req.getParameterNames();
+ NameValuePairs params = new NameValuePairs();
+
+ if (caConnectorConfig != null) {
+ while (enum1.hasMoreElements()) {
+ String name = enum1.nextElement();
+
+ if (name.equals(Constants.RS_ID))
+ continue;
+ if (name.equals(Constants.OP_SCOPE))
+ continue;
+ if (name.equals(Constants.OP_TYPE))
+ continue;
+
+ params.put(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");
+ }
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> enum1 = req.getParameterNames();
+
+ if (caConnectorConfig != null) {
+ while (enum1.hasMoreElements()) {
+ String name = 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) {
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> enum1 = req.getParameterNames();
+
+ while (enum1.hasMoreElements()) {
+ String key = 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) {
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> enum1 = req.getParameterNames();
+
+ while (enum1.hasMoreElements()) {
+ String key = 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) {
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> enum1 = req.getParameterNames();
+
+ while (enum1.hasMoreElements()) {
+ String key = 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/base/common/src/com/netscape/cms/servlet/admin/RegistryAdminServlet.java b/base/common/src/com/netscape/cms/servlet/admin/RegistryAdminServlet.java
new file mode 100644
index 000000000..4bebe85d3
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/admin/RegistryAdminServlet.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.cms.servlet.admin;
+
+import java.io.IOException;
+import java.util.Enumeration;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.common.OpDef;
+import com.netscape.certsrv.common.ScopeDef;
+import com.netscape.certsrv.profile.IPolicyConstraint;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.property.IConfigTemplate;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.registry.IPluginInfo;
+import com.netscape.certsrv.registry.IPluginRegistry;
+
+/**
+ * This implements the administration servlet for registry subsystem.
+ *
+ * @version $Revision$, $Date$
+ */
+public class RegistryAdminServlet extends AdminServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2104924641665675578L;
+
+ 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);
+
+ 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<String> impls = mRegistry.getIds(scope);
+ NameValuePairs nvp = new NameValuePairs();
+
+ while (impls.hasMoreElements()) {
+ String id = impls.nextElement();
+ IPluginInfo info = mRegistry.getPluginInfo(scope, id);
+
+ nvp.put(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<String> 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.put(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<String> names = template.getConfigNames();
+
+ if (names != null) {
+ while (names.hasMoreElements()) {
+ String name = 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.put(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/base/common/src/com/netscape/cms/servlet/admin/SystemCertificateResource.java b/base/common/src/com/netscape/cms/servlet/admin/SystemCertificateResource.java
new file mode 100644
index 000000000..d4cfcd296
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/admin/SystemCertificateResource.java
@@ -0,0 +1,25 @@
+package com.netscape.cms.servlet.admin;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.jboss.resteasy.annotations.ClientResponseType;
+
+import com.netscape.cms.servlet.cert.model.CertificateData;
+
+@Path("/config/cert")
+public interface SystemCertificateResource {
+
+ /**
+ * Used to retrieve the transport certificate
+ */
+ @GET
+ @Path("/transport")
+ @ClientResponseType(entityType=CertificateData.class)
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
+ public Response getTransportCert();
+
+} \ No newline at end of file
diff --git a/base/common/src/com/netscape/cms/servlet/admin/SystemCertificateResourceService.java b/base/common/src/com/netscape/cms/servlet/admin/SystemCertificateResourceService.java
new file mode 100644
index 000000000..48f410c73
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/admin/SystemCertificateResourceService.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) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.cms.servlet.admin;
+
+import java.security.cert.CertificateEncodingException;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.Response;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.security.ITransportKeyUnit;
+import com.netscape.cms.servlet.base.CMSResourceService;
+import com.netscape.cms.servlet.cert.model.CertificateData;
+
+/**
+ * This is the class used to list, retrieve and modify system certificates for all Java subsystems.
+ *
+ * @author alee
+ *
+ */
+public class SystemCertificateResourceService extends CMSResourceService implements SystemCertificateResource {
+
+ @Context
+ Request request;
+
+ /**
+ * Used to retrieve the transport certificate
+ */
+ public Response getTransportCert() {
+ CertificateData cert = null;
+ IKeyRecoveryAuthority kra = null;
+
+ // auth and authz
+
+ kra = (IKeyRecoveryAuthority) CMS.getSubsystem("kra");
+ if (kra == null) {
+ // no KRA
+ throw new WebApplicationException(Response.Status.NOT_FOUND);
+ }
+
+ ITransportKeyUnit tu = kra.getTransportKeyUnit();
+ if (tu == null) {
+ CMS.debug("getTransportCert: transport key unit is null");
+ throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+ }
+ org.mozilla.jss.crypto.X509Certificate transportCert = tu.getCertificate();
+ if (transportCert == null) {
+ CMS.debug("getTransportCert: transport cert is null");
+ throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+ }
+ try {
+ cert = createCertificateData(transportCert);
+ } catch (CertificateEncodingException e) {
+ CMS.debug("getTransportCert: certificate encoding exception with transport cert");
+ e.printStackTrace();
+ throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+ }
+ return sendConditionalGetResponse(DEFAULT_LONG_CACHE_LIFETIME, cert, request);
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/admin/UsrGrpAdminServlet.java b/base/common/src/com/netscape/cms/servlet/admin/UsrGrpAdminServlet.java
new file mode 100644
index 000000000..e5a6dd3c4
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/admin/UsrGrpAdminServlet.java
@@ -0,0 +1,2313 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.ldap.LDAPException;
+import netscape.security.pkcs.PKCS7;
+import netscape.security.x509.X509CertImpl;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.InternalCertificate;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authorization.IAuthzSubsystem;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.ICertPrettyPrint;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.common.OpDef;
+import com.netscape.certsrv.common.ScopeDef;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.password.IPasswordCheck;
+import com.netscape.certsrv.usrgrp.EUsrGrpException;
+import com.netscape.certsrv.usrgrp.IGroup;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.certsrv.usrgrp.IUser;
+import com.netscape.cmsutil.util.Cert;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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 static final long serialVersionUID = -4341817607402387714L;
+ 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 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.put(Constants.PR_USER_TYPE, val);
+ sendResponse(SUCCESS, null, params, 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<IUser> 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 = 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.put("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.put(Constants.PR_USER_FULLNAME, user.getFullName());
+ params.put(Constants.PR_USER_EMAIL, user.getEmail());
+ params.put(Constants.PR_USER_PHONE, user.getPhone());
+ params.put(Constants.PR_USER_STATE, user.getState());
+
+ // get list of groups, and get a list of those that this
+ // uid belongs to
+ Enumeration<IGroup> 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 = e.nextElement();
+
+ if (group.isMember(id) == true) {
+ if (grpString.length() != 0) {
+ grpString.append(",");
+ }
+ grpString.append(group.getGroupID());
+ }
+ }
+
+ params.put(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.put(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<IGroup> 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 = e.nextElement();
+ String desc = group.getDescription();
+
+ if (desc != null) {
+ params.put(group.getGroupID(), desc);
+ } else {
+ params.put(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<IGroup> 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 = e.nextElement();
+
+ params.put(Constants.PR_GROUP_GROUP, group.getGroupID());
+ params.put(Constants.PR_GROUP_DESC,
+ group.getDescription());
+
+ Enumeration<String> members = group.getMemberNames();
+ StringBuffer membersString = new StringBuffer();
+
+ if (members != null) {
+ while (members.hasMoreElements()) {
+ if (membersString.length() != 0) {
+ membersString.append(", ");
+ }
+
+ String mn = members.nextElement();
+
+ membersString.append(mn);
+ }
+ }
+
+ params.put(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<IGroup> 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 = 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) {
+ 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[] = Utils.base64decode(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[] = Utils.base64decode(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<IGroup> 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<IGroup> 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 = groups.nextElement();
+ String name = group.getName();
+ Enumeration<IGroup> g = mMgr.findGroups(name);
+ IGroup g1 = g.nextElement();
+ if (!name.equals(groupName)) {
+ if (isGroupInMultiRoleEnforceList(name)) {
+ Enumeration<String> members = g1.getMemberNames();
+ while (members.hasMoreElements()) {
+ String m1 = 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/base/common/src/com/netscape/cms/servlet/base/CMSResourceService.java b/base/common/src/com/netscape/cms/servlet/base/CMSResourceService.java
new file mode 100644
index 000000000..acddba559
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/base/CMSResourceService.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) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.base;
+
+import java.security.cert.CertificateEncodingException;
+
+import javax.ws.rs.core.CacheControl;
+import javax.ws.rs.core.EntityTag;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.cms.servlet.cert.model.CertificateData;
+
+/**
+ * Base class for CMS RESTful resources
+ *
+ * @author alee
+ *
+ */
+public class CMSResourceService {
+ public static final String HEADER = "-----BEGIN NEW CERTIFICATE REQUEST-----";
+ public static final String TRAILER = "-----END NEW CERTIFICATE REQUEST-----";
+
+ // caching parameters
+ protected static final int DEFAULT_LONG_CACHE_LIFETIME = 1000;
+
+ protected Response sendConditionalGetResponse(int ctime, Object object, Request request) {
+ CacheControl cc = new CacheControl();
+ cc.setMaxAge(ctime);
+ EntityTag tag = new EntityTag(Integer.toString(object.hashCode()));
+
+ ResponseBuilder builder = request.evaluatePreconditions(tag);
+ if (builder != null) {
+ builder.cacheControl(cc);
+ return builder.build();
+ }
+
+ builder = Response.ok(object);
+ builder.cacheControl(cc);
+ builder.tag(tag);
+ return builder.build();
+ }
+
+ public CertificateData createCertificateData(org.mozilla.jss.crypto.X509Certificate cert)
+ throws CertificateEncodingException {
+ CertificateData data = new CertificateData();
+ String b64 = HEADER + CMS.BtoA(cert.getEncoded()) + TRAILER;
+ data.setB64(b64);
+ return data;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java b/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java
new file mode 100644
index 000000000..c0931ee2f
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java
@@ -0,0 +1,2294 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Random;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.pkcs.ContentInfo;
+import netscape.security.pkcs.PKCS7;
+import netscape.security.pkcs.SignerInfo;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.RevocationReason;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X509CertImpl;
+
+import org.w3c.dom.Node;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.apps.ICommandQueue;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.IAuthManager;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.IAuthzSubsystem;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.usrgrp.IGroup;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.cms.servlet.common.AuthCredentials;
+import com.netscape.cms.servlet.common.CMSFileLoader;
+import com.netscape.cms.servlet.common.CMSGateway;
+import com.netscape.cms.servlet.common.CMSLoadTemplate;
+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.cms.servlet.common.GenErrorTemplateFiller;
+import com.netscape.cms.servlet.common.GenPendingTemplateFiller;
+import com.netscape.cms.servlet.common.GenRejectedTemplateFiller;
+import com.netscape.cms.servlet.common.GenSuccessTemplateFiller;
+import com.netscape.cms.servlet.common.GenSvcPendingTemplateFiller;
+import com.netscape.cms.servlet.common.GenUnexpectedErrorTemplateFiller;
+import com.netscape.cms.servlet.common.ICMSTemplateFiller;
+import com.netscape.cms.servlet.common.ServletUtils;
+import com.netscape.cmsutil.util.Utils;
+import com.netscape.cmsutil.xml.XMLObject;
+
+/**
+ * This is the base class of all CS servlet.
+ *
+ * @version $Revision$, $Date$
+ */
+public abstract class CMSServlet extends HttpServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3886300199374147160L;
+ // 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<Integer, CMSLoadTemplate> mTemplates = new Hashtable<Integer, CMSLoadTemplate>();
+
+ protected ServletConfig mServletConfig = null;
+ protected ServletContext mServletContext = null;
+ private CMSFileLoader mFileLoader = null;
+
+ protected Vector<String> mDontSaveHttpParams = new Vector<String>();
+ protected Vector<String> mSaveHttpHeaders = new Vector<String>();
+
+ 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<String, String> toHashtable(HttpServletRequest req) {
+ Hashtable<String, String> httpReqHash = new Hashtable<String, String>();
+ 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 = ServletUtils.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<CMSLoadTemplate> 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.startsWith("p12Password") ||
+ 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.");
+
+ // 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(cmsRequest, 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<String> 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<IArgBlock> 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) {
+
+ /*
+ 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<String, String> headers = new Hashtable<String, String>();
+ Enumeration<String> hdrs = mSaveHttpHeaders.elements();
+
+ while (hdrs.hasMoreElements()) {
+ String hdr = 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<String, String> saveParams = new Hashtable<String, String>();
+
+ Enumeration<String> names = httpParams.elements();
+
+ while (names.hasMoreElements()) {
+ String name = names.nextElement();
+ Enumeration<String> params = mDontSaveHttpParams.elements();
+ boolean dosave = true;
+
+ while (params.hasMoreElements()) {
+ String param = 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, (String) 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 =
+ ((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 =
+ ((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<String> e = token.getElements();
+ while (e.hasMoreElements()) {
+ String n = 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 = Utils.base64encode(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, String resource, IAuthToken authToken,
+ String exp) throws EBaseException {
+ AuthzToken authzToken = null;
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditGroupID = auditGroupID();
+ String auditACLResource = resource;
+ String auditOperation = "enroll";
+
+ try {
+ authzToken = mAuthz.authorize(authzMgrName, authToken, exp);
+ if (authzToken != null) {
+ 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,
+ auditGroupID);
+
+ audit(auditMessage);
+ } else {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTHZ_FAIL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditACLResource,
+ auditOperation);
+
+ audit(auditMessage);
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_ROLE_ASSUME,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditGroupID);
+
+ audit(auditMessage);
+ }
+ return authzToken;
+ } catch (Exception e) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTHZ_FAIL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditACLResource,
+ auditOperation);
+
+ audit(auditMessage);
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_ROLE_ASSUME,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditGroupID);
+
+ audit(auditMessage);
+ throw new EBaseException(e.toString());
+ }
+ }
+
+ /**
+ * 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 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<IGroup> groups = null;
+
+ try {
+ groups = mUG.findGroups("*");
+ } catch (Exception e) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ StringBuffer membersString = new StringBuffer();
+
+ while (groups.hasMoreElements()) {
+ IGroup group = 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 == '"') {
+ if ((c == 0x5c) && ((i + 1) < v.length())) {
+ int nextC = v.charAt(i + 1);
+ if ((c == 0x5c) && (nextC == ',' || nextC == '=' || nextC == '+' ||
+ nextC == '<' || nextC == '>' || nextC == '#' ||
+ nextC == ';' || nextC == '\r' || nextC == '\n' ||
+ nextC == '\\' || nextC == '"')) {
+ if (doubleEscape)
+ result.append('\\');
+ } else {
+ result.append('\\');
+ if (doubleEscape)
+ result.append('\\');
+ }
+ } else {
+ 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/base/common/src/com/netscape/cms/servlet/base/CMSStartServlet.java b/base/common/src/com/netscape/cms/servlet/base/CMSStartServlet.java
new file mode 100644
index 000000000..4bfc74607
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/base/CMSStartServlet.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.base;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+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 {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 515623839479425172L;
+ 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/base/common/src/com/netscape/cms/servlet/base/DisplayHtmlServlet.java b/base/common/src/com/netscape/cms/servlet/base/DisplayHtmlServlet.java
new file mode 100644
index 000000000..54e453f30
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/base/DisplayHtmlServlet.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.cms.servlet.base;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ECMSGWException;
+
+/**
+ * This is the servlet that displays the html page for the corresponding input id.
+ *
+ * @version $Revision$, $Date$
+ */
+public class DisplayHtmlServlet extends CMSServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4343458180370708327L;
+ 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 ");
+
+ 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/base/common/src/com/netscape/cms/servlet/base/DynamicVariablesServlet.java b/base/common/src/com/netscape/cms/servlet/base/DynamicVariablesServlet.java
new file mode 100644
index 000000000..0bf726879
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/base/DynamicVariablesServlet.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) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.base;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthMgrPlugin;
+import com.netscape.certsrv.authentication.IAuthManager;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+
+/**
+ * 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 {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7246774978153039460L;
+ 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<Integer, String> 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<Integer, String>();
+
+ 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, 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 {
+ 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<Integer> k = dynvars.keys();
+
+ while (k.hasMoreElements()) {
+ String toBeWritten;
+ Integer varcode = 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<IAuthManager> 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 = 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/base/common/src/com/netscape/cms/servlet/base/GetStats.java b/base/common/src/com/netscape/cms/servlet/base/GetStats.java
new file mode 100644
index 000000000..c21b56835
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/base/GetStats.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.base;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+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.logging.ILogger;
+import com.netscape.certsrv.util.IStatsSubsystem;
+import com.netscape.certsrv.util.StatsEvent;
+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;
+
+/**
+ * Retrieve information.
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetStats extends CMSServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3336253558044271816L;
+ 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;
+
+ 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, 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<String> names = st.getSubEventNames();
+ while (names.hasMoreElements()) {
+ String name = 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/base/common/src/com/netscape/cms/servlet/base/IndexServlet.java b/base/common/src/com/netscape/cms/servlet/base/IndexServlet.java
new file mode 100644
index 000000000..95dbf2abf
--- /dev/null
+++ b/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 java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.common.CMSGateway;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ECMSGWException;
+import com.netscape.cms.servlet.common.IndexTemplateFiller;
+
+/**
+ * This is the servlet that builds the index page in
+ * various ports.
+ *
+ * @version $Revision$, $Date$
+ */
+public class IndexServlet extends CMSServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8632685610380549L;
+
+ 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/base/common/src/com/netscape/cms/servlet/base/PortsServlet.java b/base/common/src/com/netscape/cms/servlet/base/PortsServlet.java
new file mode 100644
index 000000000..fced583a2
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/base/PortsServlet.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.servlet.base;
+
+import java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.w3c.dom.Node;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cmsutil.xml.XMLObject;
+
+/**
+ * This servlet returns port information.
+ *
+ * @version $Revision$, $Date$
+ */
+public class PortsServlet extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3750153734073658934L;
+ 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/base/common/src/com/netscape/cms/servlet/base/ProxyServlet.java b/base/common/src/com/netscape/cms/servlet/base/ProxyServlet.java
new file mode 100644
index 000000000..41666ab31
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/base/ProxyServlet.java
@@ -0,0 +1,248 @@
+/* CMS_SDK_LICENSE_TEXT */
+
+package com.netscape.cms.servlet.base;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+
+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 static final long serialVersionUID = -2535349161521094539L;
+ private String mDest = null;
+ private String mDestContext = null;
+ private String mSrcContext = null;
+ private String mAppendPathInfo = null;
+ private Vector<String> mMatchStrings = new Vector<String>();
+ private String mDestServletOnNoMatch = null;
+ private String mAppendPathInfoOnNoMatch = null;
+ private Map<String, String> mParamMap = new HashMap<String, String>();
+ private Map<String, String[]> mParamValue = new HashMap<String, String[]>();
+
+ 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 = 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<String, String> mMap = null;
+ private Map<String, String[]> mValueMap = null;
+
+ public ProxyWrapper(HttpServletRequest req) {
+ super(req);
+ }
+
+ public void setParameterMapAndValue(Map<String, String> m, Map<String, String[]> v) {
+ if (m != null)
+ mMap = m;
+ if (v != null)
+ mValueMap = v;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Map<String, String[]> 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<String, String[]> n = new HashMap<String, String[]>();
+ // get the HTTP parameters the user supplied.
+ Map<String, String[]> m = super.getParameterMap();
+ Set<Map.Entry<String, String[]>> s = m.entrySet();
+ Iterator<Map.Entry<String, String[]>> i = s.iterator();
+ while (i.hasNext()) {
+ Map.Entry<String, String[]> me = i.next();
+ String name = me.getKey();
+ String[] values = 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<Map.Entry<String, String[]>> s2 = mValueMap.entrySet();
+ Iterator<Map.Entry<String, String[]>> i2 = s2.iterator();
+ // Cycle through all the static values
+ while (i2.hasNext()) {
+ Map.Entry<String, String[]> me2 = i2.next();
+ String name2 = me2.getKey();
+ if (n.get(name2) == null) {
+ String[] values2 = 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/base/common/src/com/netscape/cms/servlet/base/SystemInfoServlet.java b/base/common/src/com/netscape/cms/servlet/base/SystemInfoServlet.java
new file mode 100644
index 000000000..f883fd373
--- /dev/null
+++ b/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 java.io.IOException;
+import java.util.Date;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -438134935001530607L;
+
+ 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 {
+ 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/base/common/src/com/netscape/cms/servlet/base/UserInfo.java b/base/common/src/com/netscape/cms/servlet/base/UserInfo.java
new file mode 100644
index 000000000..dd8f69613
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/base/UserInfo.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.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/base/common/src/com/netscape/cms/servlet/base/model/Link.java b/base/common/src/com/netscape/cms/servlet/base/model/Link.java
new file mode 100644
index 000000000..7fd850a22
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/base/model/Link.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) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---/**
+package com.netscape.cms.servlet.base.model;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * @author alee
+ *
+ */
+@XmlRootElement(name = "Link")
+public class Link {
+ protected String relationship;
+ protected String href;
+ protected String type;
+
+ public Link() {
+ // required for jaxb
+ }
+
+ public Link(String relationship, String href, String type) {
+ this.relationship = relationship;
+ this.href = href;
+ this.type = type;
+ }
+
+ /**
+ * @return the relationship
+ */
+ @XmlAttribute(name = "rel")
+ public String getRelationship() {
+ return relationship;
+ }
+
+ /**
+ * @param relationship the relationship to set
+ */
+ public void setRelationship(String relationship) {
+ this.relationship = relationship;
+ }
+
+ /**
+ * @return the href
+ */
+ @XmlAttribute
+ public String getHref() {
+ return href;
+ }
+
+ /**
+ * @param href the href to set
+ */
+ public void setHref(String href) {
+ this.href = href;
+ }
+
+ /**
+ * @return the type
+ */
+ @XmlAttribute
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * @param type the type to set
+ */
+ public void setType(String type) {
+ this.type = type;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/cert/CMCRevReqServlet.java b/base/common/src/com/netscape/cms/servlet/cert/CMCRevReqServlet.java
new file mode 100644
index 000000000..5af09ad0d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/CMCRevReqServlet.java
@@ -0,0 +1,1056 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.CertificateException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.InvalidityDateExtension;
+import netscape.security.x509.RevocationReason;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.EMissingCredential;
+import com.netscape.certsrv.authentication.IAuthManager;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertRecordList;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+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.Utils;
+
+/**
+ * Revoke a certificate with a CMC-formatted revocation request
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMCRevReqServlet extends CMSServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4731070386698127770L;
+ 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"));
+ }
+
+ 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);
+ }
+
+ 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 {
+ 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) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+ }
+
+ /**
+ * 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<X509CertImpl> oldCertsV = new Vector<X509CertImpl>();
+ Vector<RevokedCertImpl> revCertImplsV = new Vector<RevokedCertImpl>();
+
+ // 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<ICertRecord> e = list.getCertRecords(0, totalRecordCount - 1);
+
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = 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<String> serialNumbers = new Vector<String>();
+
+ 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 = Utils.base64decode(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<ICRLIssuingPoint> 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<String> 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/base/common/src/com/netscape/cms/servlet/cert/ChallengeRevocationServlet1.java b/base/common/src/com/netscape/cms/servlet/cert/ChallengeRevocationServlet1.java
new file mode 100644
index 000000000..f056047cc
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/ChallengeRevocationServlet1.java
@@ -0,0 +1,716 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.CertificateException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.InvalidityDateExtension;
+import netscape.security.x509.RevocationReason;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertRecordList;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+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.Utils;
+
+/**
+ * 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 {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1253319999546210407L;
+ 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"));
+ }
+
+ 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);
+
+ 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 {
+ 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) {
+ 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<X509CertImpl> oldCertsV = new Vector<X509CertImpl>();
+ Vector<RevokedCertImpl> revCertImplsV = new Vector<RevokedCertImpl>();
+
+ // 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<ICertRecord> e = list.getCertRecords(0, totalRecordCount - 1);
+
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = 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<String> serialNumbers = new Vector<String>();
+
+ 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 = Utils.base64decode(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<ICRLIssuingPoint> 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<String> 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/base/common/src/com/netscape/cms/servlet/cert/CloneRedirect.java b/base/common/src/com/netscape/cms/servlet/cert/CloneRedirect.java
new file mode 100644
index 000000000..d17fd959b
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/CloneRedirect.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;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.logging.ILogger;
+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;
+
+/**
+ * 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 static final long serialVersionUID = 3217967115281965166L;
+ 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();
+
+ 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();
+
+ 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) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/cert/DirAuthServlet.java b/base/common/src/com/netscape/cms/servlet/cert/DirAuthServlet.java
new file mode 100644
index 000000000..ced92ba85
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/DirAuthServlet.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.cert;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthManager;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.cms.authentication.HashAuthentication;
+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;
+
+/**
+ * 'Face-to-face' certificate enrollment.
+ *
+ * @version $Revision$, $Date$
+ */
+public class DirAuthServlet extends CMSServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3906057586972768401L;
+ 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 {
+ 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/base/common/src/com/netscape/cms/servlet/cert/DisableEnrollResult.java b/base/common/src/com/netscape/cms/servlet/cert/DisableEnrollResult.java
new file mode 100644
index 000000000..a5cdc98e8
--- /dev/null
+++ b/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 java.io.IOException;
+import java.security.cert.X509Certificate;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthManager;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.cms.authentication.HashAuthentication;
+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;
+
+/**
+ * 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 static final long serialVersionUID = 4307655310299723974L;
+ 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/base/common/src/com/netscape/cms/servlet/cert/DisplayBySerial.java b/base/common/src/com/netscape/cms/servlet/cert/DisplayBySerial.java
new file mode 100644
index 000000000..5a1e4ed65
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/DisplayBySerial.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.cms.servlet.cert;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.extensions.NSCertTypeExtension;
+import netscape.security.pkcs.ContentInfo;
+import netscape.security.pkcs.PKCS7;
+import netscape.security.pkcs.SignerInfo;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.KeyUsageExtension;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.ICertPrettyPrint;
+import com.netscape.certsrv.base.MetaInfo;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.EDBRecordNotFoundException;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.dbs.certdb.IRevocationInfo;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestId;
+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.Utils;
+
+/**
+ * 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 static final long serialVersionUID = -4143700762995036597L;
+ 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);
+ getCertRecord(serialNumber, certType); //throw exception on error
+
+ 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 {
+ getCertRecord(seq, certType); // throw exception on error
+
+ 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<Extension> 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", Utils.base64encode(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 = Utils.base64encode(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/base/common/src/com/netscape/cms/servlet/cert/DisplayCRL.java b/base/common/src/com/netscape/cms/servlet/cert/DisplayCRL.java
new file mode 100644
index 000000000..ad503272a
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/DisplayCRL.java
@@ -0,0 +1,481 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.CRLException;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X509CRLImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.ICRLPrettyPrint;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.dbs.crldb.ICRLRepository;
+import com.netscape.certsrv.logging.ILogger;
+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.Utils;
+
+/**
+ * Decode the CRL and display it to the requester.
+ *
+ * @version $Revision$, $Date$
+ */
+public class DisplayCRL extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1152016798229054027L;
+ 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.
+
+ String crlIssuingPointId = req.getParameter("crlIssuingPoint");
+
+ process(argSet, header, req, resp, crlIssuingPointId,
+ locale[0]);
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ 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) {
+ 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) {
+ ICRLIssuingPoint crlIP = null;
+ X509CRLImpl crl = null;
+ boolean clonedCA = false;
+ boolean isCRLCacheEnabled = false;
+ String masterHost = null;
+ String masterPort = null;
+ Vector<String> 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 = ipNames.elementAt(i);
+ if (crlIssuingPointId.equals(ipName)) {
+ break;
+ }
+ }
+ if (i >= ipNames.size())
+ crlIssuingPointId = null;
+ } else {
+ crlIssuingPointId = null;
+ }
+ }
+ } else {
+ if (crlIssuingPointId != null) {
+ Enumeration<ICRLIssuingPoint> ips = mCA.getCRLIssuingPoints();
+
+ while (ips.hasMoreElements()) {
+ ICRLIssuingPoint ip = 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 = Utils.base64encode(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 = Utils.base64encode(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/base/common/src/com/netscape/cms/servlet/cert/DisplayHashUserEnroll.java b/base/common/src/com/netscape/cms/servlet/cert/DisplayHashUserEnroll.java
new file mode 100644
index 000000000..99082d4c5
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/DisplayHashUserEnroll.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.servlet.cert;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthManager;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.cms.authentication.HashAuthentication;
+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;
+
+/**
+ * Servlet to report the status, ie, the agent-initiated user
+ * enrollment is enabled or disabled.
+ *
+ * @version $Revision$, $Date$
+ */
+public class DisplayHashUserEnroll extends CMSServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7063912475278810362L;
+ 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();
+
+ 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 {
+ 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/base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java b/base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java
new file mode 100644
index 000000000..1594c5323
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java
@@ -0,0 +1,1221 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+import java.math.BigInteger;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.InvalidityDateExtension;
+import netscape.security.x509.RevocationReason;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.ICertAuthority;
+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.Nonces;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.usrgrp.Certificates;
+import com.netscape.certsrv.usrgrp.ICertUserLocator;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.certsrv.usrgrp.IUser;
+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;
+
+/**
+ * Revoke a Certificate
+ *
+ * @version $Revision$, $Date$
+ */
+public class DoRevoke extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1693115906265904238L;
+ 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) {
+
+ String serialNumber = req.getParameter("serialNumber");
+ getSSLClientCertificate(req); // throw exception on error
+
+ if (serialNumber != null) {
+ eeSerialNumber = serialNumber;
+ }
+
+ 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);
+
+ CMS.debug("DoRevoke: eeSerialNumber: " + eeSerialNumber + " auditSerialNumber: " + auditSerialNumber);
+ long startTime = CMS.getCurrentDate().getTime();
+
+ try {
+ int count = 0;
+ Vector<X509CertImpl> oldCertsV = new Vector<X509CertImpl>();
+ Vector<RevokedCertImpl> revCertImplsV = new Vector<RevokedCertImpl>();
+
+ // 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<ICertRecord> e = mCertDB.searchCertificates(revokeAll,
+ totalRecordCount, mTimeLimits);
+
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = 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<String> serialNumbers = new Vector<String>();
+
+ 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<ICRLIssuingPoint> 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<String> 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();
+
+ // find out if the value is hex or decimal
+
+ BigInteger value = BigInteger.ONE.negate();
+
+ //try int
+ try {
+ value = new BigInteger(serialNumber, 10);
+ } catch (NumberFormatException e) {
+ }
+
+ //try hex
+ if (value.compareTo(BigInteger.ONE.negate()) == 0) {
+ try {
+ value = new BigInteger(serialNumber, 16);
+ } catch (NumberFormatException e) {
+ }
+ }
+ // give up if it isn't hex or dec
+ if (value.compareTo(BigInteger.ONE.negate()) == 0) {
+ throw new NumberFormatException();
+ }
+
+ // convert it to hexadecimal
+ serialNumber = "0x" + value.toString(16);
+ } 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/base/common/src/com/netscape/cms/servlet/cert/DoRevokeTPS.java b/base/common/src/com/netscape/cms/servlet/cert/DoRevokeTPS.java
new file mode 100644
index 000000000..c4603dd51
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/DoRevokeTPS.java
@@ -0,0 +1,940 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+import java.math.BigInteger;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.InvalidityDateExtension;
+import netscape.security.x509.RevocationReason;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.ICertAuthority;
+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.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestStatus;
+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;
+
+/**
+ * Revoke a Certificate
+ *
+ * @version $Revision$, $Date$
+ */
+public class DoRevokeTPS extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2980600514636454836L;
+ 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;
+ Locale[] locale = new Locale[1];
+
+ CMS.debug("DoRevokeTPS before getTemplate");
+ try {
+ @SuppressWarnings("unused")
+ CMSTemplate form = getTemplate(mFormPath, req, locale); // check for errors
+ } 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 {
+ 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);
+
+ if (revokeAll != null) {
+ CMS.debug("DoRevokeTPS.process revokeAll" + revokeAll);
+
+ String serial = "";
+ String[] tokens;
+ tokens = revokeAll.split("=");
+
+ if (tokens.length == 2) {
+ serial = tokens[1];
+ //remove the trailing paren
+ if (serial.endsWith(")")) {
+ serial = serial.substring(0, serial.length() - 1);
+ }
+ auditSerialNumber = serial;
+ }
+ }
+
+ long startTime = CMS.getCurrentDate().getTime();
+
+ try {
+ int count = 0;
+ Vector<X509CertImpl> oldCertsV = new Vector<X509CertImpl>();
+ Vector<RevokedCertImpl> revCertImplsV = new Vector<RevokedCertImpl>();
+
+ // 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<ICertRecord> 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<ICRLIssuingPoint> 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");
+
+ // 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<String> 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" + (new BigInteger(serialNumber)).toString(16);
+ } 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/base/common/src/com/netscape/cms/servlet/cert/DoUnrevoke.java b/base/common/src/com/netscape/cms/servlet/cert/DoUnrevoke.java
new file mode 100644
index 000000000..c6b6065b4
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/DoUnrevoke.java
@@ -0,0 +1,671 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.math.BigInteger;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X509CertImpl;
+
+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.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestStatus;
+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;
+
+/**
+ * 'Unrevoke' a certificate. (For certificates that are on-hold only,
+ * take them off-hold)
+ *
+ * @version $Revision$, $Date$
+ */
+public class DoUnrevoke extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7978703730006036625L;
+ 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<ICRLIssuingPoint> otherCRLs =
+ ((ICertificateAuthority) mAuthority).getCRLIssuingPoints();
+
+ while (otherCRLs.hasMoreElements()) {
+ ICRLIssuingPoint crl = 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<BigInteger> biList = new Vector<BigInteger>();
+ 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" + (new BigInteger(serialNumber)).toString(16);
+ } else {
+ serialNumber = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ return serialNumber;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/cert/DoUnrevokeTPS.java b/base/common/src/com/netscape/cms/servlet/cert/DoUnrevokeTPS.java
new file mode 100644
index 000000000..5d096aff3
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/DoUnrevokeTPS.java
@@ -0,0 +1,618 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X509CertImpl;
+
+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.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ECMSGWException;
+
+/**
+ * 'Unrevoke' a certificate. (For certificates that are on-hold only,
+ * take them off-hold)
+ *
+ * @version $Revision$, $Date$
+ */
+public class DoUnrevokeTPS extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6245049221697655642L;
+ 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;
+
+ 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 {
+ 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<ICRLIssuingPoint> otherCRLs =
+ ((ICertificateAuthority) mAuthority).getCRLIssuingPoints();
+
+ while (otherCRLs.hasMoreElements()) {
+ ICRLIssuingPoint crl = 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<BigInteger> biList = new Vector<BigInteger>();
+ 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" + (new BigInteger(serialNumber)).toString(16);
+ } else {
+ serialNumber = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ return serialNumber;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/cert/EnableEnrollResult.java b/base/common/src/com/netscape/cms/servlet/cert/EnableEnrollResult.java
new file mode 100644
index 000000000..2a143b668
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/EnableEnrollResult.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.cert;
+
+import java.io.IOException;
+import java.security.cert.X509Certificate;
+import java.util.Locale;
+import java.util.Random;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthManager;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.cms.authentication.HashAuthentication;
+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;
+
+/**
+ * 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 static final long serialVersionUID = -2646998784859783012L;
+ 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/base/common/src/com/netscape/cms/servlet/cert/EnrollServlet.java b/base/common/src/com/netscape/cms/servlet/cert/EnrollServlet.java
new file mode 100644
index 000000000..a73a8146c
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/EnrollServlet.java
@@ -0,0 +1,1768 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.pkcs.PKCS10;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateAlgorithmId;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+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.IConfigStore;
+import com.netscape.certsrv.base.KeyGenInfo;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertRecordList;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.policy.IPolicyProcessor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.usrgrp.IGroup;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.certsrv.usrgrp.IUser;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSGateway;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ECMSGWException;
+import com.netscape.cms.servlet.common.ICMSTemplateFiller;
+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.cms.servlet.processors.PKIProcessor;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * Submit a Certificate Enrollment request
+ *
+ * @version $Revision$, $Date$
+ */
+public class EnrollServlet extends CMSServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6983729702665630013L;
+
+ 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<ICertRecord> en = list.getCertRecords(0, size - 1);
+
+ 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 = 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<String> messages = req.getExtDataInStringVector(IRequest.ERRORS);
+
+ if (messages != null) {
+ Enumeration<String> 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 };
+
+ 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;
+
+ // support Enterprise 3.5.1 server where CERT_TYPE=csrCertType
+ // instead of certType
+ String 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);
+ }
+
+ /**
+ * 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 = Utils.base64encode(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/base/common/src/com/netscape/cms/servlet/cert/GetBySerial.java b/base/common/src/com/netscape/cms/servlet/cert/GetBySerial.java
new file mode 100644
index 000000000..663397f54
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/GetBySerial.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.cms.servlet.cert;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.X509Certificate;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.pkcs.ContentInfo;
+import netscape.security.pkcs.PKCS7;
+import netscape.security.pkcs.SignerInfo;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.X509CertImpl;
+
+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.MetaInfo;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+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.cms.servlet.common.ICMSTemplateFiller;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+
+/**
+ * Retrieve certificate by serial number.
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetBySerial extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2276677839178370838L;
+
+ 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 {
+
+ 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();
+
+ 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/base/common/src/com/netscape/cms/servlet/cert/GetCAChain.java b/base/common/src/com/netscape/cms/servlet/cert/GetCAChain.java
new file mode 100644
index 000000000..fe55f335b
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/GetCAChain.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.cms.servlet.cert;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.ICertAuthority;
+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.ICertPrettyPrint;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.base.UserInfo;
+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;
+
+/**
+ * Retrieve the Certificates comprising the CA Chain for this CA.
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetCAChain extends CMSServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8189048155415074581L;
+ 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 {
+
+ 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;
+ }
+
+ /**
+ * 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/base/common/src/com/netscape/cms/servlet/cert/GetCRL.java b/base/common/src/com/netscape/cms/servlet/cert/GetCRL.java
new file mode 100644
index 000000000..4c8661359
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/GetCRL.java
@@ -0,0 +1,467 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.CRLException;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X509CRLImpl;
+
+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.ICRLPrettyPrint;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.logging.ILogger;
+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.Utils;
+
+/**
+ * Retrieve CRL for a Certificate Authority
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetCRL extends CMSServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7132206924070383013L;
+ 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 ((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 = Utils.base64encode(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 = Utils.base64encode(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/base/common/src/com/netscape/cms/servlet/cert/GetCertFromRequest.java b/base/common/src/com/netscape/cms/servlet/cert/GetCertFromRequest.java
new file mode 100644
index 000000000..71b0004cd
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/GetCertFromRequest.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.servlet.cert;
+
+import java.io.IOException;
+import java.util.Locale;
+import java.math.BigInteger;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+import netscape.security.extensions.NSCertTypeExtension;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.KeyUsageExtension;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.IAuthority;
+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.logging.ILogger;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.CMSTemplateParams;
+import com.netscape.cms.servlet.common.ECMSGWException;
+import com.netscape.cms.servlet.common.ICMSTemplateFiller;
+
+/**
+ * Gets a issued certificate from a request id.
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetCertFromRequest extends CMSServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5310646832256611066L;
+ 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 {
+ new BigInteger(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/base/common/src/com/netscape/cms/servlet/cert/GetEnableStatus.java b/base/common/src/com/netscape/cms/servlet/cert/GetEnableStatus.java
new file mode 100644
index 000000000..d0dfb8f9a
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/GetEnableStatus.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 java.io.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthManager;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.cms.authentication.HashAuthentication;
+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;
+
+/**
+ * Servlet to get the enrollment status, enable or disable.
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetEnableStatus extends CMSServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3879769989681379834L;
+ 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();
+
+ 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 = HashAuthentication.DEFAULT_TIMEOUT / 1000;
+
+ header.addStringValue("timeout", "" + timeout);
+ header.addStringValue("reqHost", reqHost);
+
+ for (Enumeration<String> hosts = mgr.getHosts(); hosts.hasMoreElements();) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addStringValue("hosts", 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/base/common/src/com/netscape/cms/servlet/cert/GetInfo.java b/base/common/src/com/netscape/cms/servlet/cert/GetInfo.java
new file mode 100644
index 000000000..6af5c0c39
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/GetInfo.java
@@ -0,0 +1,377 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.math.BigInteger;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.AlgorithmId;
+
+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.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.dbs.crldb.ICRLRepository;
+import com.netscape.certsrv.logging.ILogger;
+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;
+
+/**
+ * Get detailed information about CA CRL processing
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetInfo extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1909881831730252799L;
+
+ 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<String> ipNames = crlRepository.getIssuingPointsNames();
+ for (int i = 0; i < ipNames.size(); i++) {
+ String ipName = 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<ICRLIssuingPoint> ips = mCA.getCRLIssuingPoints();
+
+ while (ips.hasMoreElements()) {
+ ICRLIssuingPoint ip = 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() == ICRLIssuingPoint.CRL_PUBLISHING_STARTED) {
+ recentChanges += "Publishing CRL #" + ip.getCRLNumber();
+ } else if (ip.isCRLUpdateInProgress() == ICRLIssuingPoint.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<Long> 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", ICertificateAuthority.PROP_MASTER_CRL);
+ ICRLIssuingPoint ip0 = mCA.getCRLIssuingPoint(ICertificateAuthority.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/base/common/src/com/netscape/cms/servlet/cert/HashEnrollServlet.java b/base/common/src/com/netscape/cms/servlet/cert/HashEnrollServlet.java
new file mode 100644
index 000000000..5e6207e1a
--- /dev/null
+++ b/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 java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.Extension;
+import netscape.security.x509.KeyUsageExtension;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.crmf.CertTemplate;
+import org.mozilla.jss.pkix.primitive.Name;
+import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.IAuthManager;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertRecordList;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cms.authentication.HashAuthentication;
+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.cms.servlet.common.ICMSTemplateFiller;
+
+/**
+ * performs face-to-face enrollment.
+ *
+ * @version $Revision$, $Date$
+ */
+public class HashEnrollServlet extends CMSServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5532936020515258333L;
+
+ 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();
+ 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 {
+ 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);
+
+ 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);
+
+ 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);
+ // }
+ }
+
+ // support Enterprise 3.5.1 server where CERT_TYPE=csrCertType
+ // instead of certType
+ String 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<ICertRecord> 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 = 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<String> messages = req.getExtDataInStringVector(IRequest.ERRORS);
+
+ if (messages != null) {
+ Enumeration<String> 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/base/common/src/com/netscape/cms/servlet/cert/ImportCertsTemplateFiller.java b/base/common/src/com/netscape/cms/servlet/cert/ImportCertsTemplateFiller.java
new file mode 100644
index 000000000..2f551d3f5
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/ImportCertsTemplateFiller.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.servlet.cert;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.math.BigInteger;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.Locale;
+
+import javax.servlet.http.HttpServletRequest;
+
+import netscape.security.pkcs.ContentInfo;
+import netscape.security.pkcs.PKCS7;
+import netscape.security.pkcs.SignerInfo;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.X509CertImpl;
+
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.pkix.cmmf.CertOrEncCert;
+import org.mozilla.jss.pkix.cmmf.CertRepContent;
+import org.mozilla.jss.pkix.cmmf.CertResponse;
+import org.mozilla.jss.pkix.cmmf.CertifiedKeyPair;
+import org.mozilla.jss.pkix.cmmf.PKIStatusInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.ICertPrettyPrint;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.CMSTemplateParams;
+import com.netscape.cms.servlet.common.ECMSGWException;
+import com.netscape.cms.servlet.common.ICMSTemplateFiller;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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 = Utils.base64encode(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/base/common/src/com/netscape/cms/servlet/cert/ListCerts.java b/base/common/src/com/netscape/cms/servlet/cert/ListCerts.java
new file mode 100644
index 000000000..b93a82fb8
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/ListCerts.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.cms.servlet.cert;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.PublicKey;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.provider.RSAPublicKey;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.Extension;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509Key;
+
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertRecordList;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.dbs.certdb.IRevocationInfo;
+import com.netscape.certsrv.logging.ILogger;
+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;
+
+/**
+ * Retrieve a paged list of certs matching the specified query
+ *
+ * @version $Revision$, $Date$
+ */
+public class ListCerts extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3568155814023099576L;
+ private final static String TPL_FILE = "queryCert.template";
+ private final static BigInteger MINUS_ONE = new BigInteger("-1");
+
+ 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<String> mAllowedClientFilters = new Vector<String>();
+ 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<String> 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<ICertRecord> 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<ICertRecord> en = tolist.getCertRecords(0, 0);
+
+ if (en == null || (!en.hasMoreElements())) {
+ toCurIndex = list.getSize() - 1;
+ } else {
+ toCurIndex = tolist.getCurrentIndex();
+ ICertRecord rx = 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());
+
+ }
+
+ /**
+ * 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<Extension> 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/base/common/src/com/netscape/cms/servlet/cert/Monitor.java b/base/common/src/com/netscape/cms/servlet/cert/Monitor.java
new file mode 100644
index 000000000..ac531caca
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/Monitor.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.cms.servlet.cert;
+
+import java.io.IOException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X500Name;
+
+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.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequestList;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.IRequestRecord;
+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;
+
+/**
+ * Provide statistical queries of request and certificate records.
+ *
+ * @version $Revision$, $Date$
+ */
+public class Monitor extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8492837942132357692L;
+ 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<Object> 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));
+ 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));
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(year, month, date, hour, minute, second);
+ d = calendar.getTime();
+ } 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) {
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(d);
+
+ String time = "" + (calendar.get(Calendar.YEAR));
+ int i = calendar.get(Calendar.MONTH) + 1;
+
+ if (i < 10)
+ time += "0";
+ time += i;
+ i = calendar.get(Calendar.DAY_OF_MONTH);
+ if (i < 10)
+ time += "0";
+ time += i;
+ i = calendar.get(Calendar.HOUR_OF_DAY);
+ if (i < 10)
+ time += "0";
+ time += i;
+ i = calendar.get(Calendar.MINUTE);
+ if (i < 10)
+ time += "0";
+ time += i;
+ i = calendar.get(Calendar.SECOND);
+ 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/base/common/src/com/netscape/cms/servlet/cert/ReasonToRevoke.java b/base/common/src/com/netscape/cms/servlet/cert/ReasonToRevoke.java
new file mode 100644
index 000000000..0f21e1921
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/ReasonToRevoke.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.cert;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Random;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X509CertImpl;
+
+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.Nonces;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.logging.ILogger;
+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;
+
+/**
+ * Specify the RevocationReason when revoking a certificate
+ *
+ * @version $Revision$, $Date$
+ */
+public class ReasonToRevoke extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8447580860330758660L;
+ 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<ICertRecord> e = mCertDB.searchCertificates(revokeAll,
+ totalRecordCount, mTimeLimits);
+
+ int count = 0;
+
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = 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/base/common/src/com/netscape/cms/servlet/cert/RemoteAuthConfig.java b/base/common/src/com/netscape/cms/servlet/cert/RemoteAuthConfig.java
new file mode 100644
index 000000000..478df161d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/RemoteAuthConfig.java
@@ -0,0 +1,624 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.util.Calendar;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthMgrPlugin;
+import com.netscape.certsrv.authentication.IAuthManager;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.logging.ILogger;
+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;
+
+/**
+ * Allow agent to turn on/off authentication managers
+ *
+ * @version $Revision$, $Date$
+ */
+public class RemoteAuthConfig extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5803015919915253940L;
+ 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<String> mRemotelySetInstances = new Vector<String>();
+ 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();
+
+ 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) {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> eVals = attr.getStringValues();
+
+ while (eVals.hasMoreElements()) {
+ String nextValue = eVals.nextElement();
+
+ if (nextValue.indexOf("Administrator") > -1) {
+ LDAPEntry groupEntry = c.read(nextValue);
+
+ if (groupEntry != null) {
+ LDAPAttribute gAttr = groupEntry.getAttribute(UNIQUE_MEMBER);
+
+ if (gAttr != null) {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> eValues = gAttr.getStringValues();
+
+ while (eValues.hasMoreElements()) {
+ String value = 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;
+ @SuppressWarnings("unchecked")
+ Enumeration<String> eVals = attr.getStringValues();
+
+ while (eVals.hasMoreElements()) {
+ String nextValue = eVals.nextElement();
+
+ if (nextValue.indexOf("Administrator") > -1) {
+ LDAPEntry groupEntry = c.read(nextValue);
+
+ if (groupEntry != null) {
+ LDAPAttribute gAttr = groupEntry.getAttribute(UNIQUE_MEMBER);
+
+ if (gAttr != null) {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> eValues = gAttr.getStringValues();
+
+ while (eValues.hasMoreElements()) {
+ String value = 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(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(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<AuthMgrPlugin> e = mAuthSubsystem.getAuthManagerPlugins();
+
+ while (e.hasMoreElements()) {
+ AuthMgrPlugin plugin = 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<IAuthManager> e = mAuthSubsystem.getAuthManagers();
+
+ while (e.hasMoreElements()) {
+ IAuthManager authManager = e.nextElement();
+
+ if (instanceName.equals(authManager.getName())) {
+ isListed = true;
+ break;
+ }
+ }
+ }
+
+ return isListed;
+ }
+
+ private String makeInstanceName() {
+ Calendar now = Calendar.getInstance();
+ int y = now.get(Calendar.YEAR);
+ String name = "R" + y;
+
+ if (now.get(Calendar.MONTH) < 10)
+ name += "0";
+ name += now.get(Calendar.MONTH);
+ if (now.get(Calendar.DAY_OF_MONTH) < 10)
+ name += "0";
+ name += now.get(Calendar.DAY_OF_MONTH);
+ if (now.get(Calendar.HOUR_OF_DAY) < 10)
+ name += "0";
+ name += now.get(Calendar.HOUR_OF_DAY);
+ if (now.get(Calendar.MINUTE) < 10)
+ name += "0";
+ name += now.get(Calendar.MINUTE);
+ if (now.get(Calendar.SECOND) < 10)
+ name += "0";
+ name += now.get(Calendar.SECOND);
+ return name;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/cert/RenewalServlet.java b/base/common/src/com/netscape/cms/servlet/cert/RenewalServlet.java
new file mode 100644
index 000000000..223121577
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/RenewalServlet.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.servlet.cert;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+import netscape.security.extensions.CertInfo;
+import netscape.security.x509.CertificateSerialNumber;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+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.MetaInfo;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ECMSGWException;
+import com.netscape.cms.servlet.common.ICMSTemplateFiller;
+
+/**
+ * Certificate Renewal
+ *
+ * @version $Revision$, $Date$
+ */
+public class RenewalServlet extends CMSServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3094124661102395244L;
+
+ // 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) {
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(beginYear, beginMonth, beginDate);
+ notBefore = calendar.getTime();
+ calendar.set(endYear, endMonth, endDate);
+ notAfter = calendar.getTime();
+ }
+ } // 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<String> messages = req.getExtDataInStringVector(IRequest.ERRORS);
+
+ if (messages != null) {
+ Enumeration<String> 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();
+
+ 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/base/common/src/com/netscape/cms/servlet/cert/RevocationServlet.java b/base/common/src/com/netscape/cms/servlet/cert/RevocationServlet.java
new file mode 100644
index 000000000..22aa29eda
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/RevocationServlet.java
@@ -0,0 +1,392 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Random;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+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.Nonces;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+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.Utils;
+
+/**
+ * Perform the first step in revoking a certificate
+ *
+ * @version $Revision$, $Date$
+ */
+public class RevocationServlet extends CMSServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -9086730404084717413L;
+ 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;
+
+ 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<String> enum1 = req.getExtDataKeys();
+
+ while (enum1.hasMoreElements()) {
+ String name = 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", Utils.base64encode(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/base/common/src/com/netscape/cms/servlet/cert/RevocationSuccessTemplateFiller.java b/base/common/src/com/netscape/cms/servlet/cert/RevocationSuccessTemplateFiller.java
new file mode 100644
index 000000000..cfc562d71
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/RevocationSuccessTemplateFiller.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.cms.servlet.cert;
+
+import java.util.Locale;
+
+import javax.servlet.http.HttpServletRequest;
+
+import netscape.security.x509.RevokedCertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.CMSTemplateParams;
+import com.netscape.cms.servlet.common.ICMSTemplateFiller;
+
+/**
+ * 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/base/common/src/com/netscape/cms/servlet/cert/SrchCerts.java b/base/common/src/com/netscape/cms/servlet/cert/SrchCerts.java
new file mode 100644
index 000000000..3602515c9
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/SrchCerts.java
@@ -0,0 +1,762 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.math.BigInteger;
+import java.security.PublicKey;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.provider.RSAPublicKey;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.Extension;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509Key;
+
+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.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.dbs.certdb.IRevocationInfo;
+import com.netscape.certsrv.logging.ILogger;
+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;
+
+/**
+ * Search for certificates matching complex query filter
+ *
+ * @version $Revision$, $Date$
+ */
+public class SrchCerts extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5876805830088921643L;
+ 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) {
+ 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<ICertRecord> e = mCertDB.searchCertificates(filter, maxResults, timeLimit);
+
+ int count = 0;
+
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = 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<Extension> enum1 = crlExts.getElements();
+ int reason = 0;
+
+ while (enum1.hasMoreElements()) {
+ Extension ext = enum1.nextElement();
+
+ if (ext instanceof CRLReasonExtension) {
+ reason = ((CRLReasonExtension) ext).getReason().toInt();
+ break;
+ }
+ }
+ rarg.addIntegerValue("revocationReason", reason);
+ }
+ }
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/cert/UpdateCRL.java b/base/common/src/com/netscape/cms/servlet/cert/UpdateCRL.java
new file mode 100644
index 000000000..c0298d1e7
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/UpdateCRL.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.cms.servlet.cert;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.InvalidityDateExtension;
+import netscape.security.x509.RevocationReason;
+import netscape.security.x509.RevokedCertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+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.ca.EErrorPublishCRL;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.ILdapRule;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.util.IStatsSubsystem;
+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;
+
+/**
+ * Force the CRL to be updated now.
+ *
+ * @version $Revision$, $Date$
+ */
+public class UpdateCRL extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1182106454856991246L;
+ private final static String INFO = "UpdateCRL";
+ private final static String TPL_FILE = "updateCRL.template";
+
+ private static Vector<String> mTesting = new Vector<String>();
+
+ 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 */);
+ }
+
+ 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<Long> 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<ICRLIssuingPoint> ips = mCA.getCRLIssuingPoints();
+
+ while (ips.hasMoreElements()) {
+ ICRLIssuingPoint ip = ips.nextElement();
+
+ if (crlIssuingPointId.equals(ip.getId())) {
+ break;
+ }
+ if (!ips.hasMoreElements())
+ crlIssuingPointId = null;
+ }
+ }
+ if (crlIssuingPointId == null) {
+ crlIssuingPointId = ICertificateAuthority.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<ILdapRule> 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/base/common/src/com/netscape/cms/servlet/cert/UpdateDir.java b/base/common/src/com/netscape/cms/servlet/cert/UpdateDir.java
new file mode 100644
index 000000000..707e7ff5f
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/UpdateDir.java
@@ -0,0 +1,747 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.math.BigInteger;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X509CRLImpl;
+import netscape.security.x509.X509CertImpl;
+
+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.MetaInfo;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.dbs.crldb.ICRLRepository;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestId;
+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;
+
+/**
+ * Update the configured LDAP server with specified objects
+ *
+ * @version $Revision$, $Date$
+ */
+public class UpdateDir extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3063889978908136789L;
+ 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<ICRLIssuingPoint> ips = mCA.getCRLIssuingPoints();
+
+ while (ips.hasMoreElements()) {
+ ICRLIssuingPoint ip = 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<String> ipNames = mCRLRepository.getIssuingPointsNames();
+ if (ipNames != null && ipNames.size() > 0) {
+ for (int i = 0; i < ipNames.size(); i++) {
+ String ipName = ipNames.elementAt(i);
+
+ updateCRLIssuingPoint(header, ipName, null, locale);
+ }
+ }
+ } else {
+ Enumeration<ICRLIssuingPoint> oips = mCA.getCRLIssuingPoints();
+
+ while (oips.hasMoreElements()) {
+ ICRLIssuingPoint oip = oips.nextElement();
+
+ updateCRLIssuingPoint(header, oip.getId(), oip, locale);
+ }
+ }
+ } else {
+ ICRLIssuingPoint crlIssuingPoint =
+ mCA.getCRLIssuingPoint(crlIssuingPointId);
+
+ 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<ICertRecord> 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 =
+ 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<ICertRecord> 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 = 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<ICertRecord> 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 = 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/base/common/src/com/netscape/cms/servlet/cert/model/CertificateData.java b/base/common/src/com/netscape/cms/servlet/cert/model/CertificateData.java
new file mode 100644
index 000000000..14c537098
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/model/CertificateData.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) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.cert.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * @author alee
+ *
+ */
+@XmlRootElement(name = "CertificateData")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class CertificateData {
+ @XmlElement
+ private String b64;
+
+ public CertificateData() {
+ // required for jaxb
+ }
+
+ /**
+ * @return the b64
+ */
+ public String getB64() {
+ return b64;
+ }
+
+ /**
+ * @param b64 the b64 to set
+ */
+ public void setB64(String b64) {
+ this.b64 = b64;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/cert/scep/CRSEnrollment.java b/base/common/src/com/netscape/cms/servlet/cert/scep/CRSEnrollment.java
new file mode 100644
index 000000000..90a48cb4e
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/scep/CRSEnrollment.java
@@ -0,0 +1,2135 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.ByteArrayInputStream;
+import java.io.FileOutputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Random;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.security.pkcs.PKCS10;
+import netscape.security.pkcs.PKCS10Attribute;
+import netscape.security.pkcs.PKCS10Attributes;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.AVA;
+import netscape.security.x509.CertAttrSet;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.DNSName;
+import netscape.security.x509.Extension;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.GeneralNameInterface;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.IPAddressName;
+import netscape.security.x509.KeyUsageExtension;
+import netscape.security.x509.OIDMap;
+import netscape.security.x509.RDN;
+import netscape.security.x509.SubjectAlternativeNameExtension;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X500NameAttrMap;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.NoSuchTokenException;
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.BIT_STRING;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.crypto.Cipher;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.EncryptionAlgorithm;
+import org.mozilla.jss.crypto.IVParameterSpec;
+import org.mozilla.jss.crypto.KeyGenAlgorithm;
+import org.mozilla.jss.crypto.KeyGenerator;
+import org.mozilla.jss.crypto.KeyWrapAlgorithm;
+import org.mozilla.jss.crypto.KeyWrapper;
+import org.mozilla.jss.crypto.ObjectNotFoundException;
+import org.mozilla.jss.crypto.SymmetricKey;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.pkcs7.IssuerAndSerialNumber;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.util.IncorrectPasswordException;
+import org.mozilla.jss.util.PasswordCallback;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthCredentials;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.EInvalidCredentials;
+import com.netscape.certsrv.authentication.EMissingCredential;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileAuthenticator;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileSubsystem;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cms.servlet.profile.SSLClientCertProvider;
+import com.netscape.cmsutil.scep.CRSPKIMessage;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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 {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8483002540957382369L;
+ 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<String, String> toHashtable(HttpServletRequest req) {
+ Hashtable<String, String> httpReqHash = new Hashtable<String, String>();
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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;
+ }
+ if (!(mTokenName.equalsIgnoreCase(Constants.PR_INTERNAL_TOKEN) ||
+ mTokenName.equalsIgnoreCase("Internal Key Storage Token") || mTokenName.length() == 0)) {
+ int i = mNickname.indexOf(':');
+ if (!((i > -1) && (mTokenName.length() == i) && (mNickname.startsWith(mTokenName)))) {
+ mNickname = mTokenName + ":" + mNickname;
+ }
+ }
+ }
+ } 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<String> 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<PKCS10Attribute> 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 = Utils.base64decode(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 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<PKCS10Attribute> 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<Extension> exts = ((ExtensionsRequested) attr).getExtensions().elements();
+ while (exts.hasMoreElements()) {
+ Extension ext = exts.nextElement();
+
+ if (ext.getExtensionId().equals(
+ OIDMap.getOID(SubjectAlternativeNameExtension.IDENT))) {
+ SubjectAlternativeNameExtension sane = new SubjectAlternativeNameExtension(
+ Boolean.valueOf(false), // noncritical
+ ext.getExtensionValue());
+
+ @SuppressWarnings("unchecked")
+ Vector<GeneralNameInterface> v =
+ (Vector<GeneralNameInterface>) sane
+ .get(SubjectAlternativeNameExtension.SUBJECT_NAME);
+
+ Enumeration<GeneralNameInterface> gne = v.elements();
+
+ StringBuffer subjAltNameStr = new StringBuffer();
+ while (gne.hasMoreElements()) {
+ GeneralNameInterface gni = 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 = Utils.base64decode(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(CRSPKIMessage.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(CRSPKIMessage.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(CRSPKIMessage.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(CRSPKIMessage.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<RequestId> rids = rq.findRequestsBySourceId(txid);
+ if (rids == null) {
+ return null;
+ }
+
+ while (rids.hasMoreElements()) {
+ RequestId rid = 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(CRSPKIMessage.mFailInfo_badCertId);
+ resp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE);
+ return null;
+ }
+
+ return makeResponseFromRequest(req, resp, foundRequest);
+ }
+
+ public void verifyRequest(CRSPKIMessage req, CryptoContext cx)
+ throws CRSInvalidSignatureException {
+
+ // Get Signed Data
+
+ @SuppressWarnings("unused")
+ byte[] reqAAbytes = req.getAA(); // check for errors
+
+ @SuppressWarnings("unused")
+ byte[] reqAAsig = req.getAADigest(); // check for errors
+
+ }
+
+ /**
+ * 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;
+
+ // 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 {
+
+ SubjectAlternativeNameExtension sane = null;
+
+ try {
+ PKCS10 p10 = req.getP10();
+
+ if (p10 == null) {
+ crsResp.setFailInfo(CRSPKIMessage.mFailInfo_badMessageCheck);
+ crsResp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE);
+ throw new CRSFailureException("Failed to decode pkcs10 from CEP request");
+ }
+
+ AuthCredentials authCreds = new AuthCredentials();
+
+ // 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<RDN> rdne = p10subject.getRDNs();
+ Vector<RDN> rdnv = new Vector<RDN>();
+
+ Hashtable<String, String> sanehash = new Hashtable<String, String>();
+
+ 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<PKCS10Attribute> 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<Extension> exts = ((ExtensionsRequested) attr).getExtensions().elements();
+ while (exts.hasMoreElements()) {
+ Extension ext = 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))) {
+ sane = new SubjectAlternativeNameExtension(
+ new Boolean(false), // noncritical
+ ext.getExtensionValue());
+
+ @SuppressWarnings("unchecked")
+ Vector<GeneralNameInterface> v =
+ (Vector<GeneralNameInterface>) sane
+ .get(SubjectAlternativeNameExtension.SUBJECT_NAME);
+
+ Enumeration<GeneralNameInterface> 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("")) {
+
+ new X500Name(subject.toString()); // check for errors
+
+ 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(CRSPKIMessage.mFailInfo_badMessageCheck);
+ crsResp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE);
+ return;
+ } // NEED TO FIX
+ }
+
+ private SubjectAlternativeNameExtension makeDefaultSubjectAltName(Hashtable<String, String> 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<String> 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<String, byte[]> fingerprints) {
+
+ Hashtable<String, String> old_fprints = req.getExtDataInHashtable(IRequest.FINGERPRINTS);
+ if (old_fprints == null) {
+ return false;
+ }
+
+ byte[] old_md5 = CMS.AtoB(old_fprints.get("MD5"));
+ byte[] new_md5 = 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<String, byte[]> 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(CRSPKIMessage.mFailInfo_badRequest);
+ crsResp.setPKIStatus(CRSPKIMessage.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(CRSPKIMessage.mFailInfo_badIdentity);
+ crsResp.setPKIStatus(CRSPKIMessage.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(CRSPKIMessage.mFailInfo_badMessageCheck);
+ crsResp.setPKIStatus(CRSPKIMessage.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(CRSPKIMessage.mFailInfo_internalCAError);
+ crsResp.setPKIStatus(CRSPKIMessage.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 = 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<String, String> encodedPrints = new Hashtable<String, String>(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(CRSPKIMessage.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<String, byte[]> makeFingerPrints(CRSPKIMessage req) {
+ Hashtable<String, byte[]> fingerprints = new Hashtable<String, byte[]>();
+
+ 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(CRSPKIMessage.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(CRSPKIMessage.mStatus_SUCCESS);
+
+ } else { // status is not 'success' - there must've been a problem
+
+ crsResp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE);
+ crsResp.setFailInfo(CRSPKIMessage.mFailInfo_badAlg);
+ }
+ } else if (status.equals(RequestStatus.REJECTED_STRING) ||
+ status.equals(RequestStatus.CANCELED_STRING)) {
+ crsResp.setPKIStatus(CRSPKIMessage.mStatus_FAILURE);
+ crsResp.setFailInfo(CRSPKIMessage.mFailInfo_badRequest);
+ } else { // not complete
+ crsResp.setPKIStatus(CRSPKIMessage.mStatus_PENDING);
+ }
+
+ return issuedCert;
+ }
+
+ protected String hashPassword(String pwd) {
+ String salt = "lala123";
+ byte[] pwdDigest = mSHADigest.digest((salt + pwd).getBytes());
+ String b64E = Utils.base64encode(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 {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1124116326126256475L;
+
+ 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;
+ }
+ 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 {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1962741611501549051L;
+
+ public CRSFailureException() {
+ super();
+ }
+
+ public CRSFailureException(String s) {
+ super(s);
+ }
+ }
+
+ class CRSInvalidSignatureException extends Exception {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 9096408193567657944L;
+
+ public CRSInvalidSignatureException() {
+ super();
+ }
+
+ public CRSInvalidSignatureException(String s) {
+ super(s);
+ }
+ }
+
+ class CRSPolicyException extends Exception {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5846593800658787396L;
+
+ public CRSPolicyException() {
+ super();
+ }
+
+ public CRSPolicyException(String s) {
+ super(s);
+ }
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/cert/scep/ChallengePassword.java b/base/common/src/com/netscape/cms/servlet/cert/scep/ChallengePassword.java
new file mode 100644
index 000000000..ff55dc9ce
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/scep/ChallengePassword.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.servlet.cert.scep;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerValue;
+import netscape.security.x509.CertAttrSet;
+
+/**
+ * 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<String> getAttributeNames() {
+ return (new Vector<String>()).elements();
+ }
+
+ /**
+ * @return the String "ChallengePassword"
+ */
+ public String getName() {
+ return NAME;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/cert/scep/ExtensionsRequested.java b/base/common/src/com/netscape/cms/servlet/cert/scep/ExtensionsRequested.java
new file mode 100644
index 000000000..85f3938b8
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/scep/ExtensionsRequested.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.cms.servlet.cert.scep;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerValue;
+import netscape.security.x509.CertAttrSet;
+import netscape.security.x509.Extension;
+
+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<Extension> exts = new Vector<Extension>();
+
+ 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<String> getAttributeNames() {
+ return (new Vector<String>()).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;
+
+ try { // try decoding as sequence first
+
+ stream = dv.toDerInputStream();
+
+ stream.getDerValue(); // consume stream
+ stream.reset();
+
+ stream.getSequence(2); // consume stream
+ } 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();
+ stream.getSequence(2); // consume stream
+ }
+
+ // 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<Extension> getExtensions() {
+ return exts;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/common/AuthCredentials.java b/base/common/src/com/netscape/cms/servlet/common/AuthCredentials.java
new file mode 100644
index 000000000..88369ace3
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/common/AuthCredentials.java
@@ -0,0 +1,109 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Hashtable;
+
+import com.netscape.certsrv.authentication.IAuthCredentials;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+
+/**
+ * Authentication Credentials as input to the authMgr
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class AuthCredentials implements IAuthCredentials {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5995164231849154265L;
+ private Hashtable<String, Object> authCreds = null;
+ // Inserted by bskim
+ private IArgBlock argblk = null;
+
+ // Insert end
+
+ public AuthCredentials() {
+ authCreds = new Hashtable<String, Object>();
+ }
+
+ /**
+ * 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 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 credential names in this credential
+ * set. Use the Enumeration methods on the returned object to
+ * fetch the elements sequentially.
+ *
+ * @return an enumeration of the names in this credential set
+ * @see java.util.Enumeration
+ */
+ public Enumeration<String> getElements() {
+ return authCreds.keys();
+ }
+
+ // Inserted by bskim
+ public void setArgBlock(IArgBlock blk) {
+ argblk = blk;
+ return;
+ }
+
+ // Insert end
+
+ public IArgBlock getArgBlock() {
+ return argblk;
+ }
+ // Insert end
+}
diff --git a/base/common/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java b/base/common/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java
new file mode 100644
index 000000000..38fcf24f9
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java
@@ -0,0 +1,1112 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.util.Date;
+import java.util.Hashtable;
+
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.InvalidityDateExtension;
+import netscape.security.x509.RevocationReason;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509Key;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.ENUMERATED;
+import org.mozilla.jss.asn1.GeneralizedTime;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.asn1.UTF8String;
+import org.mozilla.jss.crypto.DigestAlgorithm;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+import org.mozilla.jss.pkcs11.PK11PubKey;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.pkix.cmc.CMCCertId;
+import org.mozilla.jss.pkix.cmc.CMCStatusInfo;
+import org.mozilla.jss.pkix.cmc.GetCert;
+import org.mozilla.jss.pkix.cmc.OtherInfo;
+import org.mozilla.jss.pkix.cmc.OtherMsg;
+import org.mozilla.jss.pkix.cmc.PendInfo;
+import org.mozilla.jss.pkix.cmc.ResponseBody;
+import org.mozilla.jss.pkix.cmc.TaggedAttribute;
+import org.mozilla.jss.pkix.cmmf.RevRequest;
+import org.mozilla.jss.pkix.cms.ContentInfo;
+import org.mozilla.jss.pkix.cms.EncapsulatedContentInfo;
+import org.mozilla.jss.pkix.cms.IssuerAndSerialNumber;
+import org.mozilla.jss.pkix.cms.SignedData;
+import org.mozilla.jss.pkix.cms.SignerIdentifier;
+import org.mozilla.jss.pkix.cms.SignerInfo;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.pkix.primitive.Name;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.ISharedToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+
+/**
+ * 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();
+ try {
+ repository.getX509Certificate(serialno);
+ } catch (EBaseException ee) {
+ CMS.debug("CMCOutputTemplate: Certificate in the confirm acceptance control was not found");
+ }
+ }
+ 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) {
+ 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;
+ }
+
+ 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<String, byte[]> digs = new Hashtable<String, byte[]>();
+ 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 = 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/base/common/src/com/netscape/cms/servlet/common/CMSFile.java b/base/common/src/com/netscape/cms/servlet/common/CMSFile.java
new file mode 100644
index 000000000..4d7c4cdd6
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/common/CMSFile.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.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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/base/common/src/com/netscape/cms/servlet/common/CMSFileLoader.java b/base/common/src/com/netscape/cms/servlet/common/CMSFileLoader.java
new file mode 100644
index 000000000..808bdda78
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/common/CMSFileLoader.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.common;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+
+/**
+ * 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<String, CMSFile> mLoadedFiles = new Hashtable<String, CMSFile>();
+
+ // 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<CMSFile> 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 = elements.nextElement();
+
+ if (cmsFile.getLastAccess() < lru) {
+ lruFile = cmsFile;
+ }
+ mLoadedFiles.remove(lruFile.getAbsPath());
+ }
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/common/CMSGWResources.java b/base/common/src/com/netscape/cms/servlet/common/CMSGWResources.java
new file mode 100644
index 000000000..7ae242ae7
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/common/CMSGWResources.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.common;
+
+import java.util.ListResourceBundle;
+
+/**
+ * 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/base/common/src/com/netscape/cms/servlet/common/CMSGateway.java b/base/common/src/com/netscape/cms/servlet/common/CMSGateway.java
new file mode 100644
index 000000000..20743022a
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/common/CMSGateway.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.common;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.IAuthCredentials;
+import com.netscape.certsrv.authentication.IAuthManager;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.IConfigStore;
+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<String, String> toHashtable(HttpServletRequest req) {
+ Hashtable<String, String> httpReqHash = new Hashtable<String, String>();
+ @SuppressWarnings("unchecked")
+ Enumeration<String> names = req.getParameterNames();
+
+ while (names.hasMoreElements()) {
+ String name = 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/base/common/src/com/netscape/cms/servlet/common/CMSLoadTemplate.java b/base/common/src/com/netscape/cms/servlet/common/CMSLoadTemplate.java
new file mode 100644
index 000000000..62276df14
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/common/CMSLoadTemplate.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.cms.servlet.common;
+
+/**
+ * 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/base/common/src/com/netscape/cms/servlet/common/CMSRequest.java b/base/common/src/com/netscape/cms/servlet/common/CMSRequest.java
new file mode 100644
index 000000000..256c01010
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/common/CMSRequest.java
@@ -0,0 +1,300 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Hashtable;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+
+/**
+ * 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<String> mErrorDescr = null;
+
+ // any request resulting data;
+ Object mResult = null;
+ Hashtable<String, Object> mResults = new Hashtable<String, Object>();
+
+ /**
+ * 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<String>();
+ 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<String> 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<String> 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/base/common/src/com/netscape/cms/servlet/common/CMSTemplate.java b/base/common/src/com/netscape/cms/servlet/common/CMSTemplate.java
new file mode 100644
index 000000000..317bddbcd
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/common/CMSTemplate.java
@@ -0,0 +1,609 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Enumeration;
+
+import javax.servlet.ServletOutputStream;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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 {
+ /* 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<String> e = null;
+ Enumeration<IArgBlock> q = null;
+ IArgBlock r = null;
+ 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()) {
+ String n = 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()) {
+ String n = 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()) {
+ 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 = q.nextElement();
+ e = r.elements();
+ while (e.hasMoreElements()) {
+ String n = 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] == 'r' || in[i + 1] == 'f' || in[i + 1] == 't' ||
+ in[i + 1] == '<' || in[i + 1] == '>' ||
+ in[i + 1] == '\"' || in[i + 1] == '\'' || in[i + 1] == '\\')) {
+ if (in[i + 1] == 'x' && ((i + 3) < l) && in[i + 2] == '3' &&
+ (in[i + 3] == 'c' || in[i + 3] == 'e')) {
+ out[j++] = '\\';
+ out[j++] = in[i + 1];
+ out[j++] = in[i + 2];
+ out[j++] = in[i + 3];
+ i += 3;
+ } else {
+ 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 > 0x5C) {
+ out[j++] = c;
+ continue;
+ }
+
+ if ((c == 0x5c) && ((i + 1) < l) && (in[i + 1] == 'n' ||
+ in[i + 1] == 'r' || in[i + 1] == 'f' || in[i + 1] == 't' ||
+ in[i + 1] == '<' || in[i + 1] == '>' ||
+ in[i + 1] == '\"' || in[i + 1] == '\'' || in[i + 1] == '\\')) {
+ if (in[i + 1] == 'x' && ((i + 3) < l) && in[i + 2] == '3' &&
+ (in[i + 3] == 'c' || in[i + 3] == 'e')) {
+ out[j++] = '\\';
+ out[j++] = in[i + 1];
+ out[j++] = in[i + 2];
+ out[j++] = in[i + 3];
+ i += 3;
+ } else {
+ 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;
+ }
+ }
+
+ private class templateLine {
+ private StringBuffer s = new StringBuffer();
+
+ 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/base/common/src/com/netscape/cms/servlet/common/CMSTemplateParams.java b/base/common/src/com/netscape/cms/servlet/common/CMSTemplateParams.java
new file mode 100644
index 000000000..ce2c26c3c
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/common/CMSTemplateParams.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.common;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+import com.netscape.certsrv.base.IArgBlock;
+
+/**
+ * Holds template parameters
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMSTemplateParams {
+ private IArgBlock mHeader = null;
+ private IArgBlock mFixed = null;
+ private Vector<IArgBlock> mRepeat = new Vector<IArgBlock>();
+
+ 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<IArgBlock>();
+ }
+
+ public Enumeration<IArgBlock> queryRecords() {
+ return mRepeat.elements();
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/common/ECMSGWException.java b/base/common/src/com/netscape/cms/servlet/common/ECMSGWException.java
new file mode 100644
index 000000000..e8b848f7d
--- /dev/null
+++ b/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 com.netscape.certsrv.base.EBaseException;
+
+/**
+ * A class represents a CMS gateway exception.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class ECMSGWException extends EBaseException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7546430025179838019L;
+ /**
+ * 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/base/common/src/com/netscape/cms/servlet/common/GenErrorTemplateFiller.java b/base/common/src/com/netscape/cms/servlet/common/GenErrorTemplateFiller.java
new file mode 100644
index 000000000..40edb3bda
--- /dev/null
+++ b/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.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+
+/**
+ * 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<String> descr = cmsReq.getErrorDescr();
+
+ if (descr != null) {
+ Enumeration<String> num = descr.elements();
+
+ while (num.hasMoreElements()) {
+ String elem = 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/base/common/src/com/netscape/cms/servlet/common/GenPendingTemplateFiller.java b/base/common/src/com/netscape/cms/servlet/common/GenPendingTemplateFiller.java
new file mode 100644
index 000000000..1d479fef3
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/common/GenPendingTemplateFiller.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.common;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Date;
+import java.util.Locale;
+
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.crypto.DigestAlgorithm;
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+import org.mozilla.jss.pkix.cmc.CMCStatusInfo;
+import org.mozilla.jss.pkix.cmc.OtherInfo;
+import org.mozilla.jss.pkix.cmc.PendInfo;
+import org.mozilla.jss.pkix.cmc.ResponseBody;
+import org.mozilla.jss.pkix.cmc.TaggedAttribute;
+import org.mozilla.jss.pkix.cms.ContentInfo;
+import org.mozilla.jss.pkix.cms.EncapsulatedContentInfo;
+import org.mozilla.jss.pkix.cms.IssuerAndSerialNumber;
+import org.mozilla.jss.pkix.cms.SignedData;
+import org.mozilla.jss.pkix.cms.SignerIdentifier;
+import org.mozilla.jss.pkix.cms.SignerInfo;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.pkix.primitive.Name;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestId;
+
+/**
+ * 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/base/common/src/com/netscape/cms/servlet/common/GenRejectedTemplateFiller.java b/base/common/src/com/netscape/cms/servlet/common/GenRejectedTemplateFiller.java
new file mode 100644
index 000000000..9e75cc799
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/common/GenRejectedTemplateFiller.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.common;
+
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.IArgBlock;
+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<String> messages = req.getExtDataInStringVector(IRequest.ERRORS);
+
+ if (messages != null) {
+ Enumeration<String> msgs = messages.elements();
+
+ while (msgs.hasMoreElements()) {
+ String ex = 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/base/common/src/com/netscape/cms/servlet/common/GenSuccessTemplateFiller.java b/base/common/src/com/netscape/cms/servlet/common/GenSuccessTemplateFiller.java
new file mode 100644
index 000000000..f6de38412
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/common/GenSuccessTemplateFiller.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.cms.servlet.common;
+
+import java.util.Locale;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.IArgBlock;
+
+/**
+ * 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/base/common/src/com/netscape/cms/servlet/common/GenSvcPendingTemplateFiller.java b/base/common/src/com/netscape/cms/servlet/common/GenSvcPendingTemplateFiller.java
new file mode 100644
index 000000000..ec1b97779
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/common/GenSvcPendingTemplateFiller.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.cms.servlet.common;
+
+import java.util.Locale;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cms/servlet/common/GenUnauthorizedTemplateFiller.java b/base/common/src/com/netscape/cms/servlet/common/GenUnauthorizedTemplateFiller.java
new file mode 100644
index 000000000..cab1b36e6
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/common/GenUnauthorizedTemplateFiller.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.cms.servlet.common;
+
+import java.util.Locale;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.IArgBlock;
+
+/**
+ * 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/base/common/src/com/netscape/cms/servlet/common/GenUnexpectedErrorTemplateFiller.java b/base/common/src/com/netscape/cms/servlet/common/GenUnexpectedErrorTemplateFiller.java
new file mode 100644
index 000000000..8b560d7bc
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/common/GenUnexpectedErrorTemplateFiller.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.cms.servlet.common;
+
+import java.util.Locale;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+
+/**
+ * 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/base/common/src/com/netscape/cms/servlet/common/ICMSTemplateFiller.java b/base/common/src/com/netscape/cms/servlet/common/ICMSTemplateFiller.java
new file mode 100644
index 000000000..2d046f0ee
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/common/ICMSTemplateFiller.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.cms.servlet.common;
+
+import java.util.Locale;
+
+import com.netscape.certsrv.authority.IAuthority;
+
+/**
+ * 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/base/common/src/com/netscape/cms/servlet/common/IRawJS.java b/base/common/src/com/netscape/cms/servlet/common/IRawJS.java
new file mode 100644
index 000000000..827f24f1d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/common/IRawJS.java
@@ -0,0 +1,26 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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/base/common/src/com/netscape/cms/servlet/common/IndexTemplateFiller.java b/base/common/src/com/netscape/cms/servlet/common/IndexTemplateFiller.java
new file mode 100644
index 000000000..59c4a0fe4
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/common/IndexTemplateFiller.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.common;
+
+import java.util.Locale;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.ISubsystem;
+
+/**
+ * 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/base/common/src/com/netscape/cms/servlet/common/RawJS.java b/base/common/src/com/netscape/cms/servlet/common/RawJS.java
new file mode 100644
index 000000000..f936e0757
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/common/RawJS.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.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/base/common/src/com/netscape/cms/servlet/common/ServletUtils.java b/base/common/src/com/netscape/cms/servlet/common/ServletUtils.java
new file mode 100644
index 000000000..5c16b8195
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/common/ServletUtils.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.StringTokenizer;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authorization.IAuthzSubsystem;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+
+/**
+ * Utility class
+ *
+ * @version $Revision$, $Date$
+ */
+public class ServletUtils {
+
+ 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/base/common/src/com/netscape/cms/servlet/connector/CloneServlet.java b/base/common/src/com/netscape/cms/servlet/connector/CloneServlet.java
new file mode 100644
index 000000000..f9085a5bc
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/connector/CloneServlet.java
@@ -0,0 +1,579 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthCredentials;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.EInvalidCredentials;
+import com.netscape.certsrv.authentication.IAuthManager;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.connector.IPKIMessage;
+import com.netscape.certsrv.connector.IRequestEncoder;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+
+/**
+ * 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 {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3474557834182380981L;
+ 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.");
+
+ 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;
+
+ // 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;
+ 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/base/common/src/com/netscape/cms/servlet/connector/ConnectorServlet.java b/base/common/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
new file mode 100644
index 000000000..e8d4f898f
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
@@ -0,0 +1,1116 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.CertificateAlgorithmId;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.Extension;
+import netscape.security.x509.RevocationReason;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.EInvalidCredentials;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.connector.IPKIMessage;
+import com.netscape.certsrv.connector.IRequestEncoder;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.profile.IProfileSubsystem;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * Connector servlet
+ * process requests from remote authority -
+ * service request or return status.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ConnectorServlet extends CMSServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1221916495803185863L;
+ 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;
+
+ 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;
+
+ // 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 {
+ 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<Extension> enum1 = crlExts.getElements();
+
+ while (enum1.hasMoreElements()) {
+ Extension ext = 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 = Utils.base64encode(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/base/common/src/com/netscape/cms/servlet/connector/GenerateKeyPairServlet.java b/base/common/src/com/netscape/cms/servlet/connector/GenerateKeyPairServlet.java
new file mode 100644
index 000000000..bb787c7ad
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/connector/GenerateKeyPairServlet.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.connector;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IPrettyPrintFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+
+/**
+ * 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 static final long serialVersionUID = 4308385291961910458L;
+ 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;
+
+ 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";
+ }
+
+ 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 {
+ super.service(req, resp);
+
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/connector/TokenKeyRecoveryServlet.java b/base/common/src/com/netscape/cms/servlet/connector/TokenKeyRecoveryServlet.java
new file mode 100644
index 000000000..337b24259
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/connector/TokenKeyRecoveryServlet.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.connector;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IPrettyPrintFormat;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+
+/**
+ * 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 static final long serialVersionUID = -2322410659376501336L;
+ 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;
+ }
+
+ 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 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
+
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/AdminAuthenticatePanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/AdminAuthenticatePanel.java
new file mode 100644
index 000000000..585d444d4
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/AdminAuthenticatePanel.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 java.io.IOException;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.context.Context;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.X509Certificate;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.certsrv.util.HttpInput;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+
+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 {
+ @SuppressWarnings("unused")
+ boolean done = cs.getBoolean("preop.AdminAuthenticate.done"); // check for errors
+ 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");
+ }
+ s1.append(",internaldb,internaldb.ldapauth,internaldb.ldapconn");
+ String content =
+ "uid=" + uid
+ + "&pwd=" + pwd
+ + "&op=get&names=cloning.module.token,instanceId,"
+ + "internaldb.ldapauth.password,internaldb.replication.password"
+ + 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", "");
+ cm.getTokenByName(tokenname); // throw exception on error
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/AdminPanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/AdminPanel.java
new file mode 100644
index 000000000..1f5a3327c
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/AdminPanel.java
@@ -0,0 +1,690 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.net.URLEncoder;
+import java.security.cert.X509Certificate;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.ldap.LDAPException;
+import netscape.security.pkcs.ContentInfo;
+import netscape.security.pkcs.PKCS10;
+import netscape.security.pkcs.PKCS7;
+import netscape.security.pkcs.SignerInfo;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509Key;
+
+import org.apache.velocity.context.Context;
+import org.mozilla.jss.asn1.SEQUENCE;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.certsrv.usrgrp.IGroup;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.certsrv.usrgrp.IUser;
+import com.netscape.certsrv.util.HttpInput;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+import com.netscape.cmsutil.http.HttpClient;
+import com.netscape.cmsutil.http.HttpRequest;
+import com.netscape.cmsutil.http.HttpResponse;
+import com.netscape.cmsutil.http.JssSSLSocketFactory;
+import com.netscape.cmsutil.xml.XMLObject;
+
+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");
+
+ try {
+ type = cs.getString("preop.ca.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 selected_hierarchy = "";
+ try {
+ type = config.getString(PRE_CA_TYPE, "");
+ subsystemtype = config.getString("cs.type", "");
+ 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);
+
+ 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 groupName = null;
+
+ try {
+ 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 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/base/common/src/com/netscape/cms/servlet/csadmin/AgentAuthenticatePanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/AgentAuthenticatePanel.java
new file mode 100644
index 000000000..c1e6bffd1
--- /dev/null
+++ b/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 java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.certsrv.util.HttpInput;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+
+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/base/common/src/com/netscape/cms/servlet/csadmin/AuthenticatePanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/AuthenticatePanel.java
new file mode 100644
index 000000000..6700b9312
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/AuthenticatePanel.java
@@ -0,0 +1,192 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.certsrv.util.HttpInput;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+
+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/base/common/src/com/netscape/cms/servlet/csadmin/BackupKeyCertPanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/BackupKeyCertPanel.java
new file mode 100644
index 000000000..d216a9212
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/BackupKeyCertPanel.java
@@ -0,0 +1,450 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.ByteArrayOutputStream;
+import java.io.CharConversionException;
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.cert.CertificateEncodingException;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.context.Context;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.BMPString;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.crypto.Cipher;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.EncryptionAlgorithm;
+import org.mozilla.jss.crypto.IVParameterSpec;
+import org.mozilla.jss.crypto.KeyGenAlgorithm;
+import org.mozilla.jss.crypto.KeyGenerator;
+import org.mozilla.jss.crypto.KeyWrapAlgorithm;
+import org.mozilla.jss.crypto.KeyWrapper;
+import org.mozilla.jss.crypto.PBEAlgorithm;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.crypto.SymmetricKey;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.pkcs12.AuthenticatedSafes;
+import org.mozilla.jss.pkcs12.CertBag;
+import org.mozilla.jss.pkcs12.PFX;
+import org.mozilla.jss.pkcs12.PasswordConverter;
+import org.mozilla.jss.pkcs12.SafeBag;
+import org.mozilla.jss.pkix.primitive.EncryptedPrivateKeyInfo;
+import org.mozilla.jss.pkix.primitive.PrivateKeyInfo;
+import org.mozilla.jss.util.Password;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.certsrv.util.HttpInput;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+
+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 {
+ @SuppressWarnings("unused")
+ boolean done = cs.getBoolean("preop.backupkeycert.done"); // check for errors
+ 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 {
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/BaseServlet.java b/base/common/src/com/netscape/cms/servlet/csadmin/BaseServlet.java
new file mode 100644
index 000000000..9e800b9cc
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/BaseServlet.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.csadmin;
+
+import java.io.IOException;
+import java.util.Enumeration;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.context.Context;
+import org.apache.velocity.servlet.VelocityServlet;
+
+import com.netscape.certsrv.apps.CMS;
+
+public class BaseServlet extends VelocityServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3169697149104780149L;
+
+ /**
+ * 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());
+ @SuppressWarnings("unchecked")
+ Enumeration<String> paramNames = httpReq.getParameterNames();
+
+ while (paramNames.hasMoreElements()) {
+ String pn = 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/base/common/src/com/netscape/cms/servlet/csadmin/CAInfoPanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/CAInfoPanel.java
new file mode 100644
index 000000000..827f0ce92
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/CAInfoPanel.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.csadmin;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+
+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<String> 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 {
+ }
+
+ /**
+ * 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/base/common/src/com/netscape/cms/servlet/csadmin/Cert.java b/base/common/src/com/netscape/cms/servlet/csadmin/Cert.java
new file mode 100644
index 000000000..0aedded83
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/Cert.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.servlet.csadmin;
+
+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/base/common/src/com/netscape/cms/servlet/csadmin/CertPrettyPrintPanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/CertPrettyPrintPanel.java
new file mode 100644
index 000000000..9c4315c05
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/CertPrettyPrintPanel.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.cms.servlet.csadmin;
+
+import java.io.IOException;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.util.CertPrettyPrint;
+
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+
+public class CertPrettyPrintPanel extends WizardPanelBase {
+ private Vector<Cert> 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<Cert>();
+
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/CertRequestPanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/CertRequestPanel.java
new file mode 100644
index 000000000..20ddf9f2d
--- /dev/null
+++ b/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 java.io.IOException;
+import java.math.BigInteger;
+import java.security.Principal;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.pkcs.PKCS10;
+import netscape.security.util.CertPrettyPrint;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509Key;
+
+import org.apache.velocity.context.Context;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.InternalCertificate;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.crypto.X509Certificate;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.certsrv.util.HttpInput;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+
+public class CertRequestPanel extends WizardPanelBase {
+ private Vector<Cert> 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 {
+ @SuppressWarnings("unused")
+ boolean done = cs.getBoolean("preop.CertRequestPanel.done"); // check for errors
+ 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 list = "";
+ String tokenname = "";
+ try {
+ 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 {
+ @SuppressWarnings("unused")
+ boolean done = cs.getBoolean("preop.CertRequestPanel.done"); // check for errors
+ 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<Cert>();
+
+ 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();
+
+ if (isPanelDone()) {
+ context.put("updateStatus", "success");
+ return;
+ }
+
+ try {
+ Enumeration<Cert> 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 && b64chain.length() != 0)) {
+ CMS.debug("CertRequestPanel: cert might not have contained chain...calling importCertificateChain: "
+ + b64chain);
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/CertUtil.java b/base/common/src/com/netscape/cms/servlet/csadmin/CertUtil.java
new file mode 100644
index 000000000..e956edebe
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/CertUtil.java
@@ -0,0 +1,667 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.math.BigInteger;
+import java.util.Date;
+
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.ldap.LDAPException;
+import netscape.security.pkcs.PKCS10;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import org.apache.velocity.context.Context;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.crypto.X509Certificate;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.MetaInfo;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.profile.CertInfoProfile;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.usrgrp.IGroup;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.certsrv.usrgrp.IUser;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+import com.netscape.cmsutil.http.HttpClient;
+import com.netscape.cmsutil.http.HttpRequest;
+import com.netscape.cmsutil.http.HttpResponse;
+import com.netscape.cmsutil.http.JssSSLSocketFactory;
+import com.netscape.cmsutil.xml.XMLObject;
+
+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);
+ new X500Name(subjectName); // check for errors
+ }
+ }
+ 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");
+
+ 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;
+
+ if (!tokenname.equals("internal") && !tokenname.equals("Internal Key Storage Token")) {
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/CheckIdentity.java b/base/common/src/com/netscape/cms/servlet/csadmin/CheckIdentity.java
new file mode 100644
index 000000000..52a98d540
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/CheckIdentity.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 java.io.IOException;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.w3c.dom.Node;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.base.UserInfo;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cmsutil.xml.XMLObject;
+
+public class CheckIdentity extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1647682040815275807L;
+ 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 {
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ try {
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/ConfigBaseServlet.java b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigBaseServlet.java
new file mode 100644
index 000000000..dbda788f6
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigBaseServlet.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.csadmin;
+
+import java.util.Enumeration;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.apps.CMS;
+
+public abstract class ConfigBaseServlet extends BaseServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7692352201878710530L;
+
+ 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());
+ @SuppressWarnings("unchecked")
+ Enumeration<String> paramNames = httpReq.getParameterNames();
+
+ while (paramNames.hasMoreElements()) {
+ String pn = 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/base/common/src/com/netscape/cms/servlet/csadmin/ConfigCertApprovalCallback.java b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigCertApprovalCallback.java
new file mode 100644
index 000000000..956c285b5
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigCertApprovalCallback.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.cms.servlet.csadmin;
+
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.ssl.SSLCertificateApprovalCallback;
+
+public class ConfigCertApprovalCallback
+ implements SSLCertificateApprovalCallback {
+
+ public ConfigCertApprovalCallback() {
+ }
+
+ public boolean approve(X509Certificate cert,
+ SSLCertificateApprovalCallback.ValidityStatus status) {
+ return true;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/ConfigCertReqServlet.java b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigCertReqServlet.java
new file mode 100644
index 000000000..b04de4144
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigCertReqServlet.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.csadmin;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+
+public class ConfigCertReqServlet extends BaseServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4489288758636916446L;
+
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/ConfigCloneServlet.java b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigCloneServlet.java
new file mode 100644
index 000000000..ed1d9cc07
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigCloneServlet.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.csadmin;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+
+public class ConfigCloneServlet extends BaseServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -9065299591659111350L;
+
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/ConfigDatabaseServlet.java b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigDatabaseServlet.java
new file mode 100644
index 000000000..2b4a82a08
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigDatabaseServlet.java
@@ -0,0 +1,196 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+
+public class ConfigDatabaseServlet extends ConfigBaseServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2625626176089893989L;
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/ConfigHSMLoginPanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigHSMLoginPanel.java
new file mode 100644
index 000000000..03233042c
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigHSMLoginPanel.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.cms.servlet.csadmin;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.context.Context;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.util.IncorrectPasswordException;
+import org.mozilla.jss.util.Password;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.certsrv.util.HttpInput;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+import com.netscape.cmsutil.password.PlainPasswordReader;
+import com.netscape.cmsutil.password.PlainPasswordWriter;
+
+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;
+ tokName = HttpInput.getTokenName(request, "SecToken");
+
+ 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());
+
+ 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;
+ }
+ 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) {
+
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/ConfigHSMServlet.java b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigHSMServlet.java
new file mode 100644
index 000000000..9eb146294
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigHSMServlet.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.servlet.csadmin;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.pkcs11.PK11Module;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.cmsutil.crypto.Module;
+
+public class ConfigHSMServlet extends ConfigBaseServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -330521231753992202L;
+ private CryptoManager mCryptoManager = null;
+ private Vector<Module> mSupportedModules = null;
+ private Vector<Module> mOtherModules = null;
+ private String mDefaultTok = null;
+ private Hashtable<String, PK11Module> mCurrModTable = new Hashtable<String, PK11Module>();
+
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ }
+
+ public void loadCurrModTable() {
+ try {
+ // getting existing modules
+ mCryptoManager = CryptoManager.getInstance();
+ @SuppressWarnings("unchecked")
+ Enumeration<PK11Module> modules = mCryptoManager.getModules();
+
+ while (modules.hasMoreElements()) {
+ PK11Module mod = 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<PK11Module> m = mCurrModTable.elements();
+
+ mOtherModules = new Vector<Module>();
+ while (m.hasMoreElements()) {
+ PK11Module mod = m.nextElement();
+ Enumeration<Module> s = mSupportedModules.elements();
+ boolean found = false;
+
+ while (s.hasMoreElements()) {
+ Module sm = 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(module);
+ break;
+ }
+ }// while
+ }
+
+ /*
+ * find all tokens belonging to a module and load the Module
+ */
+ public void loadModTokens(Module module, PK11Module mod) {
+ @SuppressWarnings("unchecked")
+ Enumeration<CryptoToken> tokens = mod.getTokens();
+
+ while (tokens.hasMoreElements()) {
+ try {
+ CryptoToken token = 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<Module>();
+ // 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 = mCurrModTable.get(cn);
+
+ loadModTokens(module, m);
+ }
+
+ CMS.debug("ConfigHSMServlet: adding module " + cn);
+ // add module to set
+ if (!mSupportedModules.contains(module)) {
+ mSupportedModules.addElement(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/base/common/src/com/netscape/cms/servlet/csadmin/ConfigImportCertServlet.java b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigImportCertServlet.java
new file mode 100644
index 000000000..c65e559df
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigImportCertServlet.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.csadmin;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+
+public class ConfigImportCertServlet extends BaseServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1907102921734394118L;
+
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/ConfigJoinServlet.java b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigJoinServlet.java
new file mode 100644
index 000000000..5d50193cb
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigJoinServlet.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.servlet.csadmin;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+
+public class ConfigJoinServlet extends ConfigBaseServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5848083581083497909L;
+
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/ConfigRootCAServlet.java b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigRootCAServlet.java
new file mode 100644
index 000000000..c9618db19
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigRootCAServlet.java
@@ -0,0 +1,145 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.Vector;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.CertInfoProfile;
+
+public class ConfigRootCAServlet extends ConfigBaseServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1128630821163059659L;
+
+ 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<CertInfoProfile> getProfiles() {
+ IConfigStore config = CMS.getConfigStore();
+ String instancePath = "";
+
+ try {
+ instancePath = config.getString("instanceRoot");
+ } catch (EBaseException e) {
+ }
+ String p[] = { "caCert.profile" };
+ Vector<CertInfoProfile> profiles = new Vector<CertInfoProfile>();
+
+ 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<CertInfoProfile> 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<CertInfoProfile> 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/base/common/src/com/netscape/cms/servlet/csadmin/CreateSubsystemPanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/CreateSubsystemPanel.java
new file mode 100644
index 000000000..9e430e2fd
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/CreateSubsystemPanel.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.servlet.csadmin;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.certsrv.util.HttpInput;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+
+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 = "";
+
+ 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<String> 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/base/common/src/com/netscape/cms/servlet/csadmin/DatabasePanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/DatabasePanel.java
new file mode 100644
index 000000000..82c45d1cd
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/DatabasePanel.java
@@ -0,0 +1,1591 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Random;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPDN;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPModification;
+import netscape.ldap.LDAPSearchConstraints;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv3;
+
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.authorization.IAuthzSubsystem;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.IDBSubsystem;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.certsrv.util.HttpInput;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+import com.netscape.cmsutil.ldap.LDAPUtil;
+
+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 BINDDN = "cn=Directory Manager";
+
+ 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 masterReplicationPort = "";
+ String cloneReplicationPort = "";
+ String replicationSecurity = "";
+
+ try {
+ @SuppressWarnings("unused")
+ String s = cs.getString("preop.database.removeData"); // check whether it's first time
+ } 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", "");
+ replicationSecurity = cs.getString("internaldb.ldapconn.replicationSecurity", "None");
+ masterReplicationPort = cs.getString("internaldb.ldapconn.masterReplicationPort", "");
+ cloneReplicationPort = cs.getString("internaldb.ldapconn.cloneReplicationPort", "");
+ 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("masterReplicationPort", masterReplicationPort);
+ context.put("cloneReplicationPort", cloneReplicationPort);
+ context.put("replicationSecurity", replicationSecurity);
+ 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") != null) ? request.getParameter("host") : "");
+ context.put("portStr", (request.getParameter("port") != null) ? request.getParameter("port") : "");
+ context.put("basedn", (request.getParameter("basedn") != null) ? request.getParameter("basedn") : "");
+ context.put("binddn", (request.getParameter("binddn") != null) ? request.getParameter("binddn") : "");
+ context.put("bindpwd", (request.getParameter("__bindpwd") != null) ?
+ request.getParameter("__bindpwd"): "");
+ context.put("database", (request.getParameter("database") != null) ?
+ request.getParameter("database") : "");
+ context.put("masterReplicationPort", (request.getParameter("masterReplicationPort") != null) ?
+ request.getParameter("masterReplicationPort"): "");
+ context.put("cloneReplicationPort", (request.getParameter("cloneReplicationPort") != null) ?
+ request.getParameter("cloneReplicationPort"): "");
+ context.put("replicationSecurity", (request.getParameter("replicationSecurity") != null) ?
+ request.getParameter("replicationSecurity"): "None");
+ }
+
+ /**
+ * Parses and validates the parameters in the request.
+ */
+ public void parseParameters(HttpServletRequest request,
+ HttpServletResponse response, Context context) throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+
+ String select = "";
+ try {
+ select = cs.getString("preop.subsystem.select", "");
+ } catch (Exception e) {
+ }
+
+ String hostname = HttpInput.getHostname(request, "host");
+ if (hostname == null || hostname.length() == 0) {
+ throw new IOException("hostname is empty string");
+ }
+ context.put("hostname", hostname);
+
+ // this validates that port is an integer
+ String portStr = HttpInput.getPortNumber(request, "port");
+ context.put("portStr", portStr);
+
+ String basedn = HttpInput.getDN(request, "basedn");
+ if (basedn == null || basedn.length() == 0) {
+ throw new IOException("basedn is empty string");
+ }
+ context.put("basedn", basedn);
+
+ String binddn = HttpInput.getDN(request, "binddn");
+ if (binddn == null || binddn.length() == 0) {
+ throw new IOException("binddn is empty string");
+ }
+ context.put("binddn", binddn);
+
+ String database = HttpInput.getLdapDatabase(request, "database");
+ if (database == null || database.length() == 0) {
+ throw new IOException("Database is empty string");
+ }
+ context.put("database", database);
+
+ String bindpwd = HttpInput.getPassword(request, "__bindpwd");
+ if (bindpwd == null || bindpwd.length() == 0) {
+ throw new IOException("Bind password is empty string");
+ }
+ context.put("bindpwd", bindpwd);
+
+ String secure = HttpInput.getCheckbox(request, "secureConn");
+ context.put("secureConn", secure);
+
+ String masterReplicationPort = HttpInput.getString(request, "masterReplicationPort");
+ if (masterReplicationPort != null && masterReplicationPort.length() > 0) {
+ try {
+ Integer.parseInt(masterReplicationPort); // check for errors
+ } catch (NumberFormatException e) {
+ throw new IOException("Master replication port is invalid");
+ }
+ }
+ context.put("masterReplicationPort", masterReplicationPort);
+
+ String cloneReplicationPort = HttpInput.getString(request, "cloneReplicationPort");
+ if (cloneReplicationPort != null && cloneReplicationPort.length() > 0) {
+ try {
+ Integer.parseInt(cloneReplicationPort); // check for errors
+ } catch (Exception e) {
+ throw new IOException("Clone replication port is invalid");
+ }
+ }
+ context.put("cloneReplicationPort", cloneReplicationPort);
+
+ String replicationSecurity = HttpInput.getString(request, "replicationSecurity");
+ context.put("replicationSecurity", replicationSecurity);
+
+ if (select.equals("clone")) {
+ String masterhost = "";
+ String masterport = "";
+ String masterbasedn = "";
+ String realhostname = "";
+ try {
+ masterhost = cs.getString("preop.internaldb.master.ldapconn.host", "");
+ masterport = cs.getString("preop.internaldb.master.ldapconn.port", "");
+ masterbasedn = cs.getString("preop.internaldb.master.basedn", "");
+ realhostname = cs.getString("machineName", "");
+ } catch (Exception e) {
+ }
+
+ if (masterhost.equals(realhostname) && masterport.equals(portStr)) {
+ throw new IOException("Master and clone must not share the same internal database");
+ }
+
+ if (!masterbasedn.equals(basedn)) {
+ throw new IOException("Master and clone should have the same base DN");
+ }
+ }
+
+ context.put("errorString", "");
+ cs.putString("preop.database.errorString", "");
+ }
+
+ /**
+ * 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 {
+ @SuppressWarnings("unused")
+ String s = cs.getString("preop.database.removeData"); // check whether it's first time
+ } catch (Exception e) {
+ context.put("firsttime", "true");
+ }
+
+ try {
+ parseParameters(request, response, context);
+ } catch (IOException e) {
+ context.put("errorString", e.getMessage());
+ cs.putString("preop.database.errorString", e.getMessage());
+ context.put("updateStatus", "validate-failure");
+ throw e;
+ }
+
+ 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);
+ importLDIFS("preop.internaldb.manager_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);
+ importLDIFS("preop.internaldb.manager_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 dbuser = null;
+ try {
+ dbuser = "uid=" + cs.getString("cs.type") + "-" + cs.getString("machineName") + "-"
+ + cs.getString("service.securePort") + ",ou=people," + baseDN;
+ } catch (EBaseException e) {
+ CMS.debug("Unable to construct dbuser" + e.toString());
+ e.printStackTrace();
+ throw new IOException("unable to construct dbuser");
+ }
+
+ 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);
+ } else if (tok.equals("dbuser")) {
+ ps.print(dbuser);
+ }
+ 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);
+ }
+ ArrayList<String> errors = new ArrayList<String>();
+ LDAPUtil.importLDIF(conn, filename, errors);
+ if (! errors.isEmpty()) {
+ CMS.debug("DatabasePanel: importLDIFS: LDAP Errors in importing " + filename);
+ for (String error: errors) {
+ CMS.debug(error);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Commit parameter changes
+ */
+ public void update(HttpServletRequest request,
+ HttpServletResponse response,
+ Context context) throws IOException {
+ IConfigStore cs = CMS.getConfigStore();
+ boolean hasErr = false;
+
+ context.put("firsttime", "false");
+ try {
+ @SuppressWarnings("unused")
+ String s = cs.getString("preop.database.removeData"); // check whether it's first time
+ } catch (Exception e) {
+ context.put("firsttime", "true");
+ }
+
+ String hostname1 = "";
+ String portStr1 = "";
+ String database1 = "";
+ String masterPortStr = "";
+
+ try {
+ hostname1 = cs.getString("internaldb.ldapconn.host", "");
+ portStr1 = cs.getString("internaldb.ldapconn.port", "");
+ database1 = cs.getString("internaldb.database", "");
+ masterPortStr = cs.getString("preop.internaldb.master.ldapconn.port", "0");
+ } catch (Exception e) {
+ }
+
+ try {
+ parseParameters(request, response, context);
+ } catch (IOException e) {
+ context.put("errorString", e.getMessage());
+ cs.putString("preop.database.errorString", e.getMessage());
+ context.put("updateStatus", "validate-failure");
+ throw e;
+ }
+
+ String hostname2 = (String) context.get("hostname");
+ String portStr2 = (String) context.get("portStr");
+ String database2 = (String) context.get("database");
+ String basedn2 = (String) context.get("basedn");
+ String binddn = (String) context.get("binddn");
+ String secure = (String) context.get("secureConn");
+ String masterReplicationPortStr = (String) context.get("masterReplicationPort");
+ String cloneReplicationPortStr = (String) context.get("cloneReplicationPort");
+
+ cs.putString("internaldb.ldapconn.host", hostname2);
+ cs.putString("internaldb.ldapconn.port", portStr2);
+ cs.putString("internaldb.database", database2);
+ cs.putString("internaldb.basedn", basedn2);
+ cs.putString("internaldb.ldapauth.bindDN", binddn);
+ cs.putString("internaldb.ldapconn.secureConn", (secure.equals("on") ? "true" : "false"));
+
+ int masterReplicationPort = 0;
+ if ((masterReplicationPortStr == null) || (masterReplicationPortStr.length() == 0)) {
+ masterReplicationPortStr = masterPortStr;
+ }
+ masterReplicationPort = Integer.parseInt(masterReplicationPortStr);
+ cs.putString("internaldb.ldapconn.masterReplicationPort", masterReplicationPortStr);
+
+ int cloneReplicationPort = 0;
+ int port = Integer.parseInt(portStr2);
+ if ((cloneReplicationPortStr == null) || (cloneReplicationPortStr.length() == 0)) {
+ cloneReplicationPortStr = portStr2;
+ }
+ cloneReplicationPort = Integer.parseInt(cloneReplicationPortStr);
+ cs.putString("internaldb.ldapconn.cloneReplicationPort", cloneReplicationPortStr);
+
+ String replicationSecurity = HttpInput.getString(request, "replicationSecurity");
+ if ((cloneReplicationPort == port) && (secure.equals("true"))) {
+ replicationSecurity = "SSL";
+ } else if (replicationSecurity == null) {
+ replicationSecurity = "None";
+ }
+ cs.putString("internaldb.ldapconn.replicationSecurity", replicationSecurity);
+
+ 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"),
+ replicationSecurity, masterReplicationPort, cloneReplicationPort);
+ 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 replicationSecurity,
+ int masterReplicationPort, int cloneReplicationPort)
+ throws IOException {
+ 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) {
+ }
+
+ // get connection to master
+ LDAPConnection masterConn = null;
+ ILdapConnFactory masterFactory = null;
+ try {
+ IConfigStore masterCfg = cs.getSubStore("preop.internaldb.master");
+ masterFactory = CMS.getLdapBoundConnFactory();
+ masterFactory.init(masterCfg);
+ masterConn = masterFactory.getConn();
+ } catch (Exception e) {
+ CMS.debug("Failed to set up connection to master:" + e.toString());
+ e.printStackTrace();
+ throw new IOException("Failed to set up replication: No connection to master");
+ }
+
+ // get connection to replica
+ LDAPConnection replicaConn = null;
+ ILdapConnFactory replicaFactory = null;
+ try {
+ IConfigStore replicaCfg = cs.getSubStore("internaldb");
+ replicaFactory = CMS.getLdapBoundConnFactory();
+ replicaFactory.init(replicaCfg);
+ replicaConn = replicaFactory.getConn();
+ } catch (Exception e) {
+ CMS.debug("Failed to set up connection to replica:" + e.toString());
+ e.printStackTrace();
+ throw new IOException("Failed to set up replication: No connection to replica");
+ }
+
+ String master_hostname = "";
+ String master_replicationpwd = "";
+ String replica_hostname = "";
+ String replica_replicationpwd = "";
+
+ try {
+ master_hostname = cs.getString("preop.internaldb.master.ldapconn.host", "");
+ master_replicationpwd = cs.getString("preop.internaldb.master.replication.password", "");
+ replica_hostname = cs.getString("internaldb.ldapconn.host", "");
+ replica_replicationpwd = cs.getString("preop.internaldb.replicationpwd", "");
+ } catch (Exception e) {
+ }
+
+ String basedn = "";
+ try {
+ basedn = cs.getString("internaldb.basedn");
+ } catch (Exception e) {
+ }
+
+ try {
+ 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(masterConn, masterBindUser, master_replicationpwd);
+ createReplicationManager(replicaConn, cloneBindUser, replica_replicationpwd);
+
+ String dir1 = getInstanceDir(masterConn);
+ createChangeLog(masterConn, dir1 + "/changelogs");
+
+ String dir2 = getInstanceDir(replicaConn);
+ createChangeLog(replicaConn, dir2 + "/changelogs");
+
+ int replicaId = cs.getInteger("dbs.beginReplicaNumber", 1);
+
+ replicaId = enableReplication(replicadn, masterConn, masterBindUser, basedn, replicaId);
+ replicaId = enableReplication(replicadn, replicaConn, cloneBindUser, basedn, replicaId);
+ cs.putString("dbs.beginReplicaNumber", Integer.toString(replicaId));
+
+ CMS.debug("DatabasePanel setupReplication: Finished enabling replication");
+
+ createReplicationAgreement(replicadn, masterConn, masterAgreementName,
+ replica_hostname, cloneReplicationPort, replica_replicationpwd, basedn,
+ cloneBindUser, secure, replicationSecurity);
+
+ createReplicationAgreement(replicadn, replicaConn, cloneAgreementName,
+ master_hostname, masterReplicationPort, master_replicationpwd, basedn,
+ masterBindUser, secure, replicationSecurity);
+
+ // initialize consumer
+ initializeConsumer(replicadn, masterConn, masterAgreementName);
+
+ while (!replicationDone(replicadn, masterConn, masterAgreementName)) {
+ CMS.debug("DatabasePanel setupReplication: Waiting for replication to complete");
+ Thread.sleep(1000);
+ }
+
+ String status = replicationStatus(replicadn, masterConn, masterAgreementName);
+ if (!status.startsWith("0 ")) {
+ CMS.debug("DatabasePanel setupReplication: consumer initialization failed. " +
+ status);
+ throw new IOException("consumer initialization failed. " + status);
+ }
+
+ // remove master ldap password from password.conf (if present)
+ String passwordFile = cs.getString("passwordFile");
+ IConfigStore psStore = CMS.createFileConfigStore(passwordFile);
+ psStore.remove("master_internaldb");
+ psStore.commit(false);
+
+ } 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 void createReplicationManager(LDAPConnection conn, String bindUser, String pwd)
+ throws LDAPException {
+ LDAPAttributeSet attrs = null;
+ LDAPEntry entry = null;
+ String dn = "cn=" + bindUser + ",ou=csusers,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(dn, 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 + ",ou=csusers,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 + ",ou=csusers,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 replicationSecurity)
+ 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 + ",ou=csusers,cn=config"));
+ attrs.add(new LDAPAttribute("nsDS5ReplicaBindMethod", "Simple"));
+ attrs.add(new LDAPAttribute("nsds5replicacredentials", replicapwd));
+
+ if (replicationSecurity.equals("SSL")) {
+ attrs.add(new LDAPAttribute("nsDS5ReplicaTransportInfo", "SSL"));
+ } else if (replicationSecurity.equals("TLS")) {
+ 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" };
+
+ 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) {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> valsInAttr = attr.getStringValues();
+ if (valsInAttr.hasMoreElements()) {
+ return 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();
+ @SuppressWarnings("unchecked")
+ Enumeration<LDAPAttribute> attrsInSet = entryAttrs.getAttributes();
+ while (attrsInSet.hasMoreElements()) {
+ LDAPAttribute nextAttr = attrsInSet.nextElement();
+ String attrName = nextAttr.getName();
+ CMS.debug("DatabasePanel getInstanceDir: attribute name: " + attrName);
+ @SuppressWarnings("unchecked")
+ Enumeration<String> valsInAttr = nextAttr.getStringValues();
+ while (valsInAttr.hasMoreElements()) {
+ String nextValue = 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/base/common/src/com/netscape/cms/servlet/csadmin/DatabaseServlet.java b/base/common/src/com/netscape/cms/servlet/csadmin/DatabaseServlet.java
new file mode 100644
index 000000000..c44f61130
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/DatabaseServlet.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.cms.servlet.csadmin;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+
+public class DatabaseServlet extends BaseServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6474664942834474385L;
+
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/DisplayCertChainPanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/DisplayCertChainPanel.java
new file mode 100644
index 000000000..c6db8a8b7
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/DisplayCertChainPanel.java
@@ -0,0 +1,236 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.net.URLEncoder;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.util.CertPrettyPrint;
+import netscape.security.x509.X509CertImpl;
+
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+
+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<String> v = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/DisplayServlet.java b/base/common/src/com/netscape/cms/servlet/csadmin/DisplayServlet.java
new file mode 100644
index 000000000..3bb8c73c8
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/DisplayServlet.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.cms.servlet.csadmin;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+
+public class DisplayServlet extends BaseServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8753831516572779596L;
+
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/DonePanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/DonePanel.java
new file mode 100644
index 000000000..6d0e92618
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/DonePanel.java
@@ -0,0 +1,897 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.math.BigInteger;
+import java.net.URLEncoder;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPModification;
+import netscape.security.x509.X509CertImpl;
+
+import org.apache.velocity.context.Context;
+import org.mozilla.jss.CryptoManager;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.ocsp.IDefStore;
+import com.netscape.certsrv.ocsp.IOCSPAuthority;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.certsrv.usrgrp.EUsrGrpException;
+import com.netscape.certsrv.usrgrp.IGroup;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.certsrv.usrgrp.IUser;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+import com.netscape.cmsutil.password.IPasswordStore;
+import com.netscape.cmsutil.util.Cert;
+import com.netscape.cmsutil.util.Utils;
+
+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 = "";
+ String systemdService = "";
+ try {
+ type = cs.getString("cs.type", "");
+ instanceId = cs.getString("instanceId");
+ instanceRoot = cs.getString("instanceRoot");
+ select = cs.getString("preop.subsystem.select", "");
+ systemdService = cs.getString("pkicreate.systemd.servicename", "");
+ } 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")) {
+ if (!systemdService.equals("")) {
+ context.put("initCommand", "/bin/systemctl");
+ context.put("instanceId", systemdService);
+ } else {
+ 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 subsystemName = "";
+ try {
+ sdtype = cs.getString("securitydomain.select", "");
+ 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 . . .");
+ @SuppressWarnings("unused")
+ 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 . . .");
+ @SuppressWarnings("unused")
+ 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 endRequestNumStr = "";
+ String endSerialNumStr = "";
+
+ 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");
+ }
+ }
+
+ String dbuser = null;
+ try {
+ dbuser = cs.getString("cs.type") + "-" + cs.getString("machineName") + "-" + cs.getString("service.securePort");
+ if (! sdtype.equals("new")) {
+ setupDBUser(dbuser);
+ }
+ IUGSubsystem system = (IUGSubsystem) (CMS.getSubsystem(IUGSubsystem.ID));
+ IUser user = system.getUser(dbuser);
+ system.addCertSubjectDN(user);
+ } catch (Exception e) {
+ e.printStackTrace();
+ CMS.debug("Unable to create or update dbuser" + e);
+ }
+
+ 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 setupDBUser(String dbuser) throws CertificateException, EUsrGrpException, LDAPException {
+ IUGSubsystem system =
+ (IUGSubsystem) (CMS.getSubsystem(IUGSubsystem.ID));
+
+ String b64 = getSubsystemCert();
+ if (b64 == null) {
+ CMS.debug("DonePanel setupDBUser: failed to fetch subsystem cert");
+ return;
+ }
+
+ IUser user = system.createUser(dbuser);
+ user.setFullName(dbuser);
+ 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 setupDBUser: successfully add the user");
+ system.addUserCert(user);
+ CMS.debug("DonePanel setupDBUser: successfully add the user certificate");
+ }
+
+ private String getSubsystemCert() {
+ IConfigStore cs = CMS.getConfigStore();
+ String nickname = "";
+ try {
+ nickname = cs.getString("preop.cert.subsystem.nickname", "");
+ String tokenname = cs.getString("preop.module.token", "");
+ if (!tokenname.equals("internal") && !tokenname.equals("Internal Key Storage Token")
+ && !tokenname.equals(""))
+ nickname = tokenname + ":" + nickname;
+ } catch (Exception e) {
+ }
+
+ CMS.debug("DonePanel getSubsystemCert: nickname=" + nickname);
+ String s = null;
+ try {
+ CryptoManager cm = CryptoManager.getInstance();
+ org.mozilla.jss.crypto.X509Certificate cert = cm.findCertByNickname(nickname);
+
+ if (cert == null) {
+ CMS.debug("DonePanel getSubsystemCert: subsystem cert is null");
+ return null;
+ }
+
+ byte[] bytes = cert.getEncoded();
+ s = CryptoUtil.normalizeCertStr(CryptoUtil.base64Encode(bytes));
+ } catch (Exception e) {
+ CMS.debug("DonePanel getSubsystemCert: exception: " + e.toString());
+ }
+ return s;
+ }
+
+ private void updateOCSPConfig(HttpServletResponse response)
+ throws IOException {
+ IConfigStore config = CMS.getConfigStore();
+ String cahost = "";
+ int caport = -1;
+
+ try {
+ cahost = config.getString("preop.ca.hostname", "");
+ caport = config.getInteger("preop.ca.httpsport", -1);
+ } catch (Exception e) {
+ }
+
+ String ocsphost = CMS.getAgentHost();
+ int ocspport = 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, "UTF-8")
+ + "&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/base/common/src/com/netscape/cms/servlet/csadmin/DownloadPKCS12.java b/base/common/src/com/netscape/cms/servlet/csadmin/DownloadPKCS12.java
new file mode 100644
index 000000000..094aa7166
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/DownloadPKCS12.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.servlet.csadmin;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.base.UserInfo;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ICMSTemplateFiller;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+
+public class DownloadPKCS12 extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7770226137155537526L;
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/GetCertChain.java b/base/common/src/com/netscape/cms/servlet/csadmin/GetCertChain.java
new file mode 100644
index 000000000..02fbd7643
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/GetCertChain.java
@@ -0,0 +1,158 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.csadmin;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.CertificateChain;
+
+import org.w3c.dom.Node;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.base.UserInfo;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cmsutil.xml.XMLObject;
+
+public class GetCertChain extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -356806997334418285L;
+ 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 {
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/GetConfigEntries.java b/base/common/src/com/netscape/cms/servlet/csadmin/GetConfigEntries.java
new file mode 100644
index 000000000..33d82e9b8
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/GetConfigEntries.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.cms.servlet.csadmin;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.w3c.dom.Node;
+
+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.IConfigStore;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.base.UserInfo;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cmsutil.password.IPasswordStore;
+import com.netscape.cmsutil.xml.XMLObject;
+
+public class GetConfigEntries extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7418561215631752315L;
+ private final static String SUCCESS = "0";
+ 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 {
+ 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<String> enum1 = cs.getPropertyNames();
+
+ while (enum1.hasMoreElements()) {
+ String name = name1 + "." + enum1.nextElement();
+ try {
+ String value = config.getString(name);
+ if (value.equals("localhost")) {
+ value = config.getString("machineName", InetAddress.getLocalHost().getHostName());
+ }
+ 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", InetAddress.getLocalHost().getHostName());
+ } 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/base/common/src/com/netscape/cms/servlet/csadmin/GetCookie.java b/base/common/src/com/netscape/cms/servlet/csadmin/GetCookie.java
new file mode 100644
index 000000000..e6810ff42
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/GetCookie.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.csadmin;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.Locale;
+import java.util.Random;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISecurityDomainSessionTable;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.base.UserInfo;
+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;
+
+public class GetCookie extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2466968231929541707L;
+ private static Random mRandom = null;
+ private final static int SESSION_MAX_AGE = 3600;
+ private String mErrorFormPath = null;
+ private String mFormPath = null;
+
+ private final static String LOGGING_SIGNED_AUDIT_SECURITY_DOMAIN_UPDATE =
+ "LOGGING_SIGNED_AUDIT_SECURITY_DOMAIN_UPDATE_1";
+ private final static String LOGGING_SIGNED_AUDIT_ROLE_ASSUME =
+ "LOGGING_SIGNED_AUDIT_ROLE_ASSUME_3";
+
+ 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;
+ IConfigStore cs = CMS.getConfigStore();
+
+ 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 = "";
+ String auditMessage = "";
+
+ if (authToken != null) {
+ String uid = authToken.getInString("uid");
+ String groupname = getGroupName(uid, subsystem);
+
+ if (groupname != null) {
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_ROLE_ASSUME,
+ uid,
+ ILogger.SUCCESS,
+ groupname);
+ audit(auditMessage);
+
+ // 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) {
+ }
+
+ String auditParams = "operation;;issue_token+token;;" + cookie + "+ip;;" + ip +
+ "+uid;;" + uid + "+groupname;;" + groupname;
+
+ int status = ctable.addEntry(cookie, ip, uid, groupname);
+ if (status == ISecurityDomainSessionTable.SUCCESS) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SECURITY_DOMAIN_UPDATE,
+ uid,
+ ILogger.SUCCESS,
+ auditParams);
+ audit(auditMessage);
+ } else {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SECURITY_DOMAIN_UPDATE,
+ uid,
+ ILogger.FAILURE,
+ auditParams);
+ audit(auditMessage);
+ }
+
+ try {
+ 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);
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } 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) {
+ }
+ } else {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_ROLE_ASSUME,
+ uid,
+ ILogger.FAILURE,
+ "Enterprise " + subsystem + " Administrators");
+ audit(auditMessage);
+ }
+ }
+ }
+
+ private String getGroupName(String uid, String subsystemname) {
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/GetDomainXML.java b/base/common/src/com/netscape/cms/servlet/csadmin/GetDomainXML.java
new file mode 100644
index 000000000..999f13815
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/GetDomainXML.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.cms.servlet.csadmin;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPSearchConstraints;
+import netscape.ldap.LDAPSearchResults;
+
+import org.w3c.dom.Node;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.base.UserInfo;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ICMSTemplateFiller;
+import com.netscape.cmsutil.xml.XMLObject;
+
+public class GetDomainXML extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3079546345000720649L;
+ 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...");
+
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ 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 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();
+ @SuppressWarnings("unchecked")
+ Enumeration<LDAPAttribute> attrsInSet = entryAttrs.getAttributes();
+ while (attrsInSet.hasMoreElements()) {
+ LDAPAttribute nextAttr = 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/base/common/src/com/netscape/cms/servlet/csadmin/GetStatus.java b/base/common/src/com/netscape/cms/servlet/csadmin/GetStatus.java
new file mode 100644
index 000000000..4dc6f0ff6
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/GetStatus.java
@@ -0,0 +1,109 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.w3c.dom.Node;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.base.UserInfo;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cmsutil.xml.XMLObject;
+
+public class GetStatus extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2852842030221659847L;
+ 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 {
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+ IConfigStore config = CMS.getConfigStore();
+
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/GetSubsystemCert.java b/base/common/src/com/netscape/cms/servlet/csadmin/GetSubsystemCert.java
new file mode 100644
index 000000000..288cfad60
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/GetSubsystemCert.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.servlet.csadmin;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.w3c.dom.Node;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.base.UserInfo;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+import com.netscape.cmsutil.xml.XMLObject;
+
+public class GetSubsystemCert extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5720342238234153488L;
+ 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 {
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ 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;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/GetTokenInfo.java b/base/common/src/com/netscape/cms/servlet/csadmin/GetTokenInfo.java
new file mode 100644
index 000000000..f97d3e5e1
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/GetTokenInfo.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.cms.servlet.csadmin;
+
+import java.io.IOException;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.w3c.dom.Node;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.base.UserInfo;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cmsutil.xml.XMLObject;
+
+public class GetTokenInfo extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8416582986909026263L;
+ 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 {
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/GetTransportCert.java b/base/common/src/com/netscape/cms/servlet/csadmin/GetTransportCert.java
new file mode 100644
index 000000000..87a1788d6
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/GetTransportCert.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 java.io.IOException;
+import java.security.cert.CertificateEncodingException;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.w3c.dom.Node;
+
+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.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.security.ITransportKeyUnit;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.base.UserInfo;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ICMSTemplateFiller;
+import com.netscape.cmsutil.xml.XMLObject;
+
+/**
+ * This servlet retrieves the transport certificate from DRM.
+ */
+public class GetTransportCert extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2495152202191979339L;
+ 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...");
+
+ 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;
+ }
+
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/HierarchyPanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/HierarchyPanel.java
new file mode 100644
index 000000000..9044dec04
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/HierarchyPanel.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.csadmin;
+
+import java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.certsrv.util.HttpInput;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+
+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/base/common/src/com/netscape/cms/servlet/csadmin/ImportAdminCertPanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/ImportAdminCertPanel.java
new file mode 100644
index 000000000..93c26cdf3
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ImportAdminCertPanel.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.csadmin;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.math.BigInteger;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.ldap.LDAPException;
+import netscape.security.x509.X509CertImpl;
+
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.certsrv.usrgrp.IUser;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+
+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 = "";
+
+ try {
+ type = cs.getString("preop.ca.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 selected_hierarchy = "";
+
+ try {
+ type = cs.getString("preop.ca.type", "");
+ subsystemtype = cs.getString("cs.type", "");
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/ImportCAChainPanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/ImportCAChainPanel.java
new file mode 100755
index 000000000..d0ccb58e9
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ImportCAChainPanel.java
@@ -0,0 +1,145 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+
+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 {
+
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/ImportTransportCert.java b/base/common/src/com/netscape/cms/servlet/csadmin/ImportTransportCert.java
new file mode 100644
index 000000000..66ca8a8bf
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ImportTransportCert.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.servlet.csadmin;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.mozilla.jss.CryptoManager;
+import org.w3c.dom.Node;
+
+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.IConfigStore;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.base.UserInfo;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ICMSTemplateFiller;
+import com.netscape.cmsutil.xml.XMLObject;
+
+/**
+ * This servlet imports DRM's transport certificate into TKS.
+ */
+public class ImportTransportCert extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7490067757951541235L;
+ 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 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/base/common/src/com/netscape/cms/servlet/csadmin/LDAPSecurityDomainSessionTable.java b/base/common/src/com/netscape/cms/servlet/csadmin/LDAPSecurityDomainSessionTable.java
new file mode 100644
index 000000000..b9932722e
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/LDAPSecurityDomainSessionTable.java
@@ -0,0 +1,295 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License 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.Date;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISecurityDomainSessionTable;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+
+/**
+ * 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;
+ private ILdapConnFactory mLdapConnFactory = null;
+
+ public LDAPSecurityDomainSessionTable(long timeToLive) throws ELdapException, EBaseException {
+ m_timeToLive = timeToLive;
+ IConfigStore cs = CMS.getConfigStore();
+ IConfigStore internaldb = cs.getSubStore("internaldb");
+ mLdapConnFactory = CMS.getLdapBoundConnFactory();
+ mLdapConnFactory.init(internaldb);
+ }
+
+ public int addEntry(String sessionId, String ip,
+ String uid, String group) {
+ IConfigStore cs = CMS.getConfigStore();
+ LDAPConnection conn = null;
+ boolean sessions_exists = true;
+ int status = FAILURE;
+
+ 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 status;
+ }
+
+ try {
+ // create session entry (if it does not exist)
+ conn = mLdapConnFactory.getConn();
+
+ 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);
+ status = SUCCESS;
+ }
+ } catch (Exception e) {
+ CMS.debug("SecurityDomainSessionTable: unable to create session entry" + sessionId + ": " + e);
+ }
+
+ try {
+ mLdapConnFactory.returnConn(conn);
+ } catch (Exception e) {
+ CMS.debug("SecurityDomainSessionTable:addEntry: Error in disconnecting from database: " + e);
+ }
+ return status;
+ }
+
+ public int removeEntry(String sessionId) {
+ IConfigStore cs = CMS.getConfigStore();
+ LDAPConnection conn = null;
+ int status = FAILURE;
+ try {
+ String basedn = cs.getString("internaldb.basedn");
+ String dn = "cn=" + sessionId + ",ou=sessions,ou=Security Domain," + basedn;
+ conn = mLdapConnFactory.getConn();
+ conn.delete(dn);
+ status = SUCCESS;
+ } 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 {
+ mLdapConnFactory.returnConn(conn);
+ } catch (Exception e) {
+ CMS.debug("SecurityDomainSessionTable: removeEntry: Error in disconnecting from database: " + e);
+ }
+ return status;
+ }
+
+ 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 = mLdapConnFactory.getConn();
+ 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 {
+ mLdapConnFactory.returnConn(conn);
+ } catch (Exception e) {
+ CMS.debug("SecurityDomainSessionTable: isSessionIdExist: Error in disconnecting from database: " + e);
+ }
+ return ret;
+ }
+
+ public Enumeration<String> getSessionIds() {
+ IConfigStore cs = CMS.getConfigStore();
+ LDAPConnection conn = null;
+ Vector<String> ret = new Vector<String>();
+
+ try {
+ String basedn = cs.getString("internaldb.basedn");
+ String sessionsdn = "ou=sessions,ou=Security Domain," + basedn;
+ String filter = "(objectclass=securityDomainSessionEntry)";
+ String[] attrs = { "cn" };
+
+ conn = mLdapConnFactory.getConn();
+ 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 {
+ mLdapConnFactory.returnConn(conn);
+ } 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 = mLdapConnFactory.getConn();
+ 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 {
+ mLdapConnFactory.returnConn(conn);
+ } 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 = mLdapConnFactory.getConn();
+ 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 {
+ mLdapConnFactory.returnConn(conn);
+ } catch (Exception e) {
+ CMS.debug("SecurityDomainSessionTable: getSessionIds: Error in disconnecting from database: " + e);
+ }
+
+ return ret;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/LoginServlet.java b/base/common/src/com/netscape/cms/servlet/csadmin/LoginServlet.java
new file mode 100644
index 000000000..713cb170a
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/LoginServlet.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.cms.servlet.csadmin;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.apps.CMS;
+
+public class LoginServlet extends BaseServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4766622132710080340L;
+
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/MainPageServlet.java b/base/common/src/com/netscape/cms/servlet/csadmin/MainPageServlet.java
new file mode 100644
index 000000000..1d833ca9b
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/MainPageServlet.java
@@ -0,0 +1,158 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.csadmin;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.logging.ILogger;
+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;
+
+public class MainPageServlet extends CMSServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2425301522251239666L;
+ 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);
+
+ try {
+ ServletOutputStream out = response.getOutputStream();
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ response.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } 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/base/common/src/com/netscape/cms/servlet/csadmin/ModulePanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/ModulePanel.java
new file mode 100644
index 000000000..00474615f
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ModulePanel.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.csadmin;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.context.Context;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.pkcs11.PK11Module;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.certsrv.util.HttpInput;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+import com.netscape.cmsutil.crypto.Module;
+
+public class ModulePanel extends WizardPanelBase {
+ private CryptoManager mCryptoManager = null;
+ private Vector<Module> mSupportedModules = null;
+ private Vector<Module> mOtherModules = null;
+ private Hashtable<String, PK11Module> mCurrModTable = new Hashtable<String, PK11Module>();
+ 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();
+ @SuppressWarnings("unchecked")
+ Enumeration<PK11Module> modules = mCryptoManager.getModules();
+
+ while (modules.hasMoreElements()) {
+ PK11Module mod = 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<PK11Module> m = mCurrModTable.elements();
+
+ mOtherModules = new Vector<Module>();
+ while (m.hasMoreElements()) {
+ PK11Module mod = m.nextElement();
+ Enumeration<Module> s = mSupportedModules.elements();
+ boolean found = false;
+
+ while (s.hasMoreElements()) {
+ Module sm = 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(module);
+ break;
+ }
+ }// while
+ }
+
+ /*
+ * find all tokens belonging to a module and load the Module
+ */
+ public void loadModTokens(Module module, PK11Module mod) {
+ @SuppressWarnings("unchecked")
+ Enumeration<CryptoToken> tokens = mod.getTokens();
+
+ while (tokens.hasMoreElements()) {
+ try {
+ CryptoToken token = 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<Module>();
+ // 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 = mCurrModTable.get(cn);
+
+ loadModTokens(module, m);
+ }
+
+ CMS.debug("ModulePanel: adding module " + cn);
+ // add module to set
+ if (!mSupportedModules.contains(module)) {
+ mSupportedModules.addElement(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/base/common/src/com/netscape/cms/servlet/csadmin/ModuleServlet.java b/base/common/src/com/netscape/cms/servlet/csadmin/ModuleServlet.java
new file mode 100644
index 000000000..1c67654b4
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ModuleServlet.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.servlet.csadmin;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.apps.CMS;
+
+public class ModuleServlet extends BaseServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6518965840466227888L;
+
+ /**
+ * 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/base/common/src/com/netscape/cms/servlet/csadmin/NamePanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/NamePanel.java
new file mode 100644
index 000000000..916ab199b
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/NamePanel.java
@@ -0,0 +1,993 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509Key;
+
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.certsrv.util.HttpInput;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+
+public class NamePanel extends WizardPanelBase {
+ private Vector<Cert> 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 {
+ @SuppressWarnings("unused")
+ boolean done = cs.getBoolean("preop.NamePanel.done"); // check for errors
+ 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<Cert>();
+
+ 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 {
+ @SuppressWarnings("unused")
+ boolean done = config.getBoolean("preop.NamePanel.done"); // check for errors
+ 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<String> 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<Cert> c = mCerts.elements();
+
+ while (c.hasMoreElements()) {
+ 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;
+ }
+ 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<Cert> c = mCerts.elements();
+ IConfigStore config = CMS.getConfigStore();
+
+ while (c.hasMoreElements()) {
+ 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<Cert> c = mCerts.elements();
+
+ while (c.hasMoreElements()) {
+ 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 url = getURL(request, config);
+
+ URL urlx = null;
+
+ if (url.equals("External CA")) {
+ CMS.debug("NamePanel: external CA selected");
+ 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");
+ // 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<Cert> c = mCerts.elements();
+
+ while (c.hasMoreElements()) {
+ Cert cert = c.nextElement();
+ String ct = cert.getCertTag();
+ 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");
+
+ try {
+ Integer.parseInt(httpsPortStr); // check for errors
+ } 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/base/common/src/com/netscape/cms/servlet/csadmin/RegisterUser.java b/base/common/src/com/netscape/cms/servlet/csadmin/RegisterUser.java
new file mode 100644
index 000000000..0042cdb5a
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/RegisterUser.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.cms.servlet.csadmin;
+
+import java.io.IOException;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X509CertImpl;
+
+import org.w3c.dom.Node;
+
+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.usrgrp.ICertUserLocator;
+import com.netscape.certsrv.usrgrp.IGroup;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.certsrv.usrgrp.IUser;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.base.UserInfo;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ICMSTemplateFiller;
+import com.netscape.cmsutil.util.Utils;
+import com.netscape.cmsutil.xml.XMLObject;
+
+/**
+ * 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 static final long serialVersionUID = -699307373400031138L;
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+ private final static String AUTH_FAILURE = "2";
+ private String mGroupName = null;
+ private final static String LOGGING_SIGNED_AUDIT_CONFIG_ROLE =
+ "LOGGING_SIGNED_AUDIT_CONFIG_ROLE_3";
+
+ 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;
+ }
+
+ // 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);
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditParams = "Scope;;users+Operation;;OP_ADD+source;;RegisterUser" +
+ "+Resource;;" + uid +
+ "+fullname;;" + name +
+ "+state;;1" +
+ "+userType;;<null>+email;;<null>+password;;<null>+phone;;<null>";
+
+ 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 = Utils.base64decode(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);
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams);
+ audit(auditMessage);
+ }
+
+ // extract all line separators
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < certsString.length(); i++) {
+ if (!Character.isWhitespace(certsString.charAt(i))) {
+ sb.append(certsString.charAt(i));
+ }
+ }
+ certsString = sb.toString();
+
+ auditParams = "Scope;;certs+Operation;;OP_ADD+source;;RegisterUser" +
+ "+Resource;;" + uid +
+ "+cert;;" + certsString;
+
+ user.setX509Certificates(certs);
+ if (!foundByCert) {
+ ugsys.addUserCert(user);
+ CMS.debug("RegisterUser added user certificate");
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams);
+ audit(auditMessage);
+ } else
+ CMS.debug("RegisterUser no need to add user certificate");
+ } catch (Exception eee) {
+ CMS.debug("RegisterUser error " + eee.toString());
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams);
+
+ audit(auditMessage);
+ outputError(httpResp, "Error: Certificate malformed");
+ return;
+ }
+
+ // add user to the group
+ auditParams = "Scope;;groups+Operation;;OP_MODIFY+source;;RegisterUser" +
+ "+Resource;;" + mGroupName;
+ try {
+ Enumeration<IGroup> groups = ugsys.findGroups(mGroupName);
+ IGroup group = groups.nextElement();
+
+ auditParams += "+user;;";
+ Enumeration<String> members = group.getMemberNames();
+ while (members.hasMoreElements()) {
+ auditParams += members.nextElement();
+ if (members.hasMoreElements()) {
+ auditParams += ",";
+ }
+ }
+
+ if (!group.isMember(user.getUserID())) {
+ auditParams += "," + user.getUserID();
+ group.addMemberName(user.getUserID());
+ ugsys.modifyGroup(group);
+ CMS.debug("RegisterUser modified group");
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams);
+
+ audit(auditMessage);
+ }
+ } catch (Exception e) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams);
+
+ audit(auditMessage);
+ }
+
+ // 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/base/common/src/com/netscape/cms/servlet/csadmin/RestoreKeyCertPanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/RestoreKeyCertPanel.java
new file mode 100644
index 000000000..54a5ed3f6
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/RestoreKeyCertPanel.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.servlet.csadmin;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.Principal;
+import java.security.PublicKey;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.ldap.LDAPDN;
+import netscape.security.x509.X509CertImpl;
+
+import org.apache.velocity.context.Context;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.asn1.BMPString;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.crypto.Cipher;
+import org.mozilla.jss.crypto.CryptoStore;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.EncryptionAlgorithm;
+import org.mozilla.jss.crypto.IVParameterSpec;
+import org.mozilla.jss.crypto.InternalCertificate;
+import org.mozilla.jss.crypto.KeyGenAlgorithm;
+import org.mozilla.jss.crypto.KeyGenerator;
+import org.mozilla.jss.crypto.KeyWrapAlgorithm;
+import org.mozilla.jss.crypto.KeyWrapper;
+import org.mozilla.jss.crypto.SymmetricKey;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.pkcs11.PK11Store;
+import org.mozilla.jss.pkcs12.AuthenticatedSafes;
+import org.mozilla.jss.pkcs12.CertBag;
+import org.mozilla.jss.pkcs12.PFX;
+import org.mozilla.jss.pkcs12.PasswordConverter;
+import org.mozilla.jss.pkcs12.SafeBag;
+import org.mozilla.jss.pkix.primitive.Attribute;
+import org.mozilla.jss.pkix.primitive.EncryptedPrivateKeyInfo;
+import org.mozilla.jss.pkix.primitive.PrivateKeyInfo;
+import org.mozilla.jss.util.Password;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.certsrv.util.HttpInput;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+
+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 {
+ @SuppressWarnings("unused")
+ boolean done = cs.getBoolean("preop.restorekeycert.done"); // check for errors
+ 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", "");
+ 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<Vector<Object>> pkeyinfo_collection = new Vector<Vector<Object>>();
+ Vector<Vector<Object>> cert_collection = new Vector<Vector<Object>>();
+ 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();
+ PrivateKeyInfo pkeyinfo = privkeyinfo.decrypt(password, new PasswordConverter());
+ Vector<Object> pkeyinfo_v = new Vector<Object>();
+ 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<Object> cert_v = new Vector<Object>();
+ 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 master_hostname = "";
+ int master_port = -1;
+ int master_ee_port = -1;
+ try {
+ 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");
+ }
+
+ s1.append(",internaldb,internaldb.ldapauth,internaldb.ldapconn");
+
+ content =
+ "op=get&names=cloning.token,instanceId,internaldb.basedn,internaldb.ldapauth.password,"
+ + "internaldb.replication.password" + 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<Vector<Object>> pkeyinfo_collection,
+ Vector<Vector<Object>> 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<Object> pkeyinfo_v = 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);
+ 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<Object> cert_v = 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<Vector<Object>> cert_collection)
+ throws IOException {
+ for (int i = 0; i < cert_collection.size(); i++) {
+ Vector<Object> v = 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", "");
+ cm.getTokenByName(tokenname); // throw exception if token doesn't exist
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/SavePKCS12Panel.java b/base/common/src/com/netscape/cms/servlet/csadmin/SavePKCS12Panel.java
new file mode 100644
index 000000000..0c066268d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/SavePKCS12Panel.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.servlet.csadmin;
+
+import java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+
+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/base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainLogin.java b/base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainLogin.java
new file mode 100644
index 000000000..42165b08f
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainLogin.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.cms.servlet.csadmin;
+
+import java.net.URL;
+import java.net.URLDecoder;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+
+public class SecurityDomainLogin extends BaseServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1616344299101179396L;
+
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainPanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainPanel.java
new file mode 100644
index 000000000..f3a4169e8
--- /dev/null
+++ b/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 java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.certsrv.util.HttpInput;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+
+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 systemdService = "";
+
+ try {
+ default_admin_url = config.getString("preop.securitydomain.admin_url", "");
+ name = config.getString("preop.securitydomain.name", "");
+ systemdService = config.getString("pkicreate.systemd.servicename", "");
+ } 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")) {
+ if (!systemdService.equals("")) {
+ context.put("initCommand", "/usr/bin/pkicontrol");
+ context.put("instanceId", "ca " + systemdService);
+ } else {
+ 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) {
+ }
+
+ } 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/base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainSessionTable.java b/base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainSessionTable.java
new file mode 100644
index 000000000..d15ca5ad3
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/SecurityDomainSessionTable.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.csadmin;
+
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import com.netscape.certsrv.base.ISecurityDomainSessionTable;
+
+/**
+ * This object stores the values for IP, uid and group based on the cookie id.
+ */
+public class SecurityDomainSessionTable
+ implements ISecurityDomainSessionTable {
+
+ private Hashtable<String, Vector<Comparable<?>>> m_sessions;
+ private long m_timeToLive;
+
+ public SecurityDomainSessionTable(long timeToLive) {
+ m_sessions = new Hashtable<String, Vector<Comparable<?>>>();
+ m_timeToLive = timeToLive;
+ }
+
+ public int addEntry(String sessionId, String ip,
+ String uid, String group) {
+ Vector<Comparable<?>> v = new Vector<Comparable<?>>();
+ 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);
+ return SUCCESS;
+ }
+
+ public int removeEntry(String sessionId) {
+ m_sessions.remove(sessionId);
+ return SUCCESS;
+ }
+
+ public boolean isSessionIdExist(String sessionId) {
+ return m_sessions.containsKey(sessionId);
+ }
+
+ public Enumeration<String> getSessionIds() {
+ return m_sessions.keys();
+ }
+
+ public String getIP(String sessionId) {
+ Vector<Comparable<?>> v = m_sessions.get(sessionId);
+ if (v != null)
+ return (String) v.elementAt(0);
+ return null;
+ }
+
+ public String getUID(String sessionId) {
+ Vector<Comparable<?>> v = m_sessions.get(sessionId);
+ if (v != null)
+ return (String) v.elementAt(1);
+ return null;
+ }
+
+ public String getGroup(String sessionId) {
+ Vector<Comparable<?>> v = m_sessions.get(sessionId);
+ if (v != null)
+ return (String) v.elementAt(2);
+ return null;
+ }
+
+ public long getBeginTime(String sessionId) {
+ Vector<Comparable<?>> v = 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/base/common/src/com/netscape/cms/servlet/csadmin/SessionTimer.java b/base/common/src/com/netscape/cms/servlet/csadmin/SessionTimer.java
new file mode 100644
index 000000000..2d8a188af
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/SessionTimer.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.servlet.csadmin;
+
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.TimerTask;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.ISecurityDomainSessionTable;
+import com.netscape.certsrv.logging.ILogger;
+
+public class SessionTimer extends TimerTask {
+ private ISecurityDomainSessionTable m_sessiontable = null;
+ private ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+ private final static String LOGGING_SIGNED_AUDIT_SECURITY_DOMAIN_UPDATE =
+ "LOGGING_SIGNED_AUDIT_SECURITY_DOMAIN_UPDATE_1";
+
+ public SessionTimer(ISecurityDomainSessionTable table) {
+ super();
+ m_sessiontable = table;
+ }
+
+ public void run() {
+ Enumeration<String> keys = m_sessiontable.getSessionIds();
+ while (keys.hasMoreElements()) {
+ String sessionId = 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.");
+
+ // audit message
+ String auditParams = "operation;;expire_token+token;;" + sessionId;
+ String auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SECURITY_DOMAIN_UPDATE,
+ "system",
+ ILogger.SUCCESS,
+ auditParams);
+
+ mSignedAuditLogger.log(ILogger.EV_SIGNED_AUDIT,
+ null,
+ ILogger.S_SIGNED_AUDIT,
+ ILogger.LL_SECURITY,
+ auditMessage);
+
+ }
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/SizePanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/SizePanel.java
new file mode 100644
index 000000000..678145a92
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/SizePanel.java
@@ -0,0 +1,669 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.IOException;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.context.Context;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.NoSuchTokenException;
+import org.mozilla.jss.crypto.TokenException;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.certsrv.util.HttpInput;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+
+public class SizePanel extends WizardPanelBase {
+ private Vector<Cert> 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 {
+ @SuppressWarnings("unused")
+ boolean done = cs.getBoolean("preop.SizePanel.done"); // check for errors
+ 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<Cert>();
+
+ IConfigStore config = CMS.getConfigStore();
+ try {
+ @SuppressWarnings("unused")
+ boolean done = config.getBoolean("preop.SizePanel.done"); // check whether it's first time
+ } catch (Exception e) {
+ context.put("firsttime", "true");
+ }
+
+ try {
+ default_ecc_curve_name = config.getString("keys.ecc.curve.default", "nistp256");
+ } 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");
+ String rsaCertTags = config.getString("preop.cert.rsalist", "");
+ context.put("rsaTags", rsaCertTags);
+ 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");
+ try {
+ @SuppressWarnings("unused")
+ boolean done = config.getBoolean("preop.SizePanel.done"); // check whether it's first time
+ } 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<Cert> c = mCerts.elements();
+
+ while (c.hasMoreElements()) {
+ 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<Cert> c = mCerts.elements();
+
+ while (c.hasMoreElements()) {
+ 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");
+
+ 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", "nistp256");
+ context.put("curvelist", s);
+
+ s = config.getString("keys.ecc.curve.display.list", "nistp256");
+ context.put("displaycurvelist", 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/base/common/src/com/netscape/cms/servlet/csadmin/TokenAuthenticate.java b/base/common/src/com/netscape/cms/servlet/csadmin/TokenAuthenticate.java
new file mode 100644
index 000000000..2372b3094
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/TokenAuthenticate.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 java.io.IOException;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.w3c.dom.Node;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISecurityDomainSessionTable;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.base.UserInfo;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cmsutil.xml.XMLObject;
+
+public class TokenAuthenticate extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -9098593390260940853L;
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/UpdateConnector.java b/base/common/src/com/netscape/cms/servlet/csadmin/UpdateConnector.java
new file mode 100644
index 000000000..f3df51bd1
--- /dev/null
+++ b/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 java.io.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.w3c.dom.Node;
+
+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.IConfigStore;
+import com.netscape.certsrv.ca.ICAService;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.connector.IConnector;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.base.UserInfo;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ICMSTemplateFiller;
+import com.netscape.cmsutil.xml.XMLObject;
+
+public class UpdateConnector extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 972871860008509849L;
+ 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();
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> list = httpReq.getParameterNames();
+ while (list.hasMoreElements()) {
+ String name = 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/base/common/src/com/netscape/cms/servlet/csadmin/UpdateDomainXML.java b/base/common/src/com/netscape/cms/servlet/csadmin/UpdateDomainXML.java
new file mode 100644
index 000000000..a2b6ebc72
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/UpdateDomainXML.java
@@ -0,0 +1,568 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPModification;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+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.IConfigStore;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.base.UserInfo;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ICMSTemplateFiller;
+import com.netscape.cmsutil.xml.XMLObject;
+
+public class UpdateDomainXML extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4059169588555717548L;
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+ private final static String LOGGING_SIGNED_AUDIT_SECURITY_DOMAIN_UPDATE =
+ "LOGGING_SIGNED_AUDIT_SECURITY_DOMAIN_UPDATE_1";
+ private final static String LOGGING_SIGNED_AUDIT_CONFIG_ROLE =
+ "LOGGING_SIGNED_AUDIT_CONFIG_ROLE_3";
+
+ 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;
+ String status2 = 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 ((type == null) || type.equals("")) {
+ missing += " type ";
+ }
+ 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 auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditParams = "host;;" + host + "+name;;" + name + "+sport;;" + sport +
+ "+clone;;" + clone + "+type;;" + type;
+ if (operation != null) {
+ auditParams += "+operation;;" + operation;
+ } else {
+ auditParams += "+operation;;add";
+ }
+
+ 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;
+ 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;
+ if ((agentsport != null) && (!agentsport.equals(""))) {
+ adminUserDN = "uid=" + type + "-" + host + "-" + agentsport + ",ou=People," + basedn;
+ } else {
+ adminUserDN = "uid=" + type + "-" + host + "-" + sport + ",ou=People," + basedn;
+ }
+ String userAuditParams = "Scope;;users+Operation;;OP_DELETE+source;;UpdateDomainXML" +
+ "+resource;;" + adminUserDN;
+ if (status.equals(SUCCESS)) {
+ // remove the user for this subsystem's admin
+ status2 = remove_from_ldap(adminUserDN);
+ if (status2.equals(SUCCESS)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ userAuditParams);
+ audit(auditMessage);
+
+ // remove this user from the subsystem group
+ userAuditParams = "Scope;;groups+Operation;;OP_DELETE_USER" +
+ "+source;;UpdateDomainXML" +
+ "+resource;;Subsystem Group+user;;" + adminUserDN;
+ dn = "cn=Subsystem Group, ou=groups," + basedn;
+ LDAPModification mod = new LDAPModification(LDAPModification.DELETE,
+ new LDAPAttribute("uniqueMember", adminUserDN));
+ status2 = modify_ldap(dn, mod);
+ if (status2.equals(SUCCESS)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ userAuditParams);
+ } else {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ userAuditParams);
+ }
+ audit(auditMessage);
+ } else { // error deleting user
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_ROLE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ userAuditParams);
+ audit(auditMessage);
+ }
+ }
+ } 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<String> v_name = parser.getValuesFromContainer(nn, "SubsystemName");
+ Vector<String> v_host = parser.getValuesFromContainer(nn, "Host");
+ Vector<String> 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();
+ 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) {
+ }
+
+ 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;
+ }
+
+ }
+
+ if (status.equals(SUCCESS)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SECURITY_DOMAIN_UPDATE,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams);
+ } else {
+ // what if already exists or already deleted
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SECURITY_DOMAIN_UPDATE,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams);
+ }
+ audit(auditMessage);
+
+ if (status.equals(SUCCESS) && status2.equals(SUCCESS)) {
+ status = SUCCESS;
+ } else {
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/UpdateNumberRange.java b/base/common/src/com/netscape/cms/servlet/csadmin/UpdateNumberRange.java
new file mode 100644
index 000000000..894afa5ff
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/UpdateNumberRange.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.servlet.csadmin;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.w3c.dom.Node;
+
+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.IConfigStore;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.repository.IRepository;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.base.UserInfo;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ICMSTemplateFiller;
+import com.netscape.cmsutil.xml.XMLObject;
+
+public class UpdateNumberRange extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1584171713024263331L;
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+ private final static String AUTH_FAILURE = "2";
+ private final static String LOGGING_SIGNED_AUDIT_CONFIG_SERIAL_NUMBER =
+ "LOGGING_SIGNED_AUDIT_CONFIG_SERIAL_NUMBER_1";
+
+ 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;
+ }
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditParams = "source;;updateNumberRange";
+
+ try {
+ String type = httpReq.getParameter("type");
+ IConfigStore cs = CMS.getConfigStore();
+ String cstype = cs.getString("cs.type", "");
+
+ auditParams += "+type;;" + 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);
+ String decrementStr = cs.getString(cloneNumConfig, "");
+ BigInteger decrement = new BigInteger(decrementStr, radix);
+ beginNum = endNum.subtract(decrement).add(oneNum);
+
+ if (beginNum.compareTo(repo.getTheSerialNumber()) < 0) {
+ String nextEndNumStr = cs.getString(nextEndConfig, "");
+ BigInteger endNum2 = new BigInteger(nextEndNumStr, radix);
+ 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!");
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SERIAL_NUMBER,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams);
+ audit(auditMessage);
+ 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);
+
+ auditParams += "+beginNumber;;" + beginNum.toString(radix) +
+ "+endNumber;;" + endNum.toString(radix);
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SERIAL_NUMBER,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditParams);
+ audit(auditMessage);
+
+ } catch (Exception e) {
+ CMS.debug("UpdateNumberRange: Failed to update number range. Exception: " + e.toString());
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CONFIG_SERIAL_NUMBER,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditParams);
+ audit(auditMessage);
+
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/UpdateOCSPConfig.java b/base/common/src/com/netscape/cms/servlet/csadmin/UpdateOCSPConfig.java
new file mode 100644
index 000000000..2d3e33f9a
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/UpdateOCSPConfig.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.servlet.csadmin;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.w3c.dom.Node;
+
+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.IConfigStore;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.base.UserInfo;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ICMSTemplateFiller;
+import com.netscape.cmsutil.xml.XMLObject;
+
+public class UpdateOCSPConfig extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 42812270761684404L;
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/WelcomePanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/WelcomePanel.java
new file mode 100644
index 000000000..4224c4ebf
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/WelcomePanel.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.cms.servlet.csadmin;
+
+import java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+
+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/base/common/src/com/netscape/cms/servlet/csadmin/WelcomeServlet.java b/base/common/src/com/netscape/cms/servlet/csadmin/WelcomeServlet.java
new file mode 100644
index 000000000..f5a96bc8a
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/WelcomeServlet.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.cms.servlet.csadmin;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+
+public class WelcomeServlet extends BaseServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1179761802633506502L;
+
+ 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/base/common/src/com/netscape/cms/servlet/csadmin/WizardPanelBase.java b/base/common/src/com/netscape/cms/servlet/csadmin/WizardPanelBase.java
new file mode 100644
index 000000000..55f7171ef
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/WizardPanelBase.java
@@ -0,0 +1,1630 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.ByteArrayInputStream;
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.URLEncoder;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPDN;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPSearchConstraints;
+import netscape.ldap.LDAPSearchResults;
+
+import org.apache.velocity.context.Context;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.CryptoStore;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.pkcs11.PK11Store;
+import org.mozilla.jss.ssl.SSLCertificateApprovalCallback;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.property.PropertySet;
+import com.netscape.cms.servlet.base.UserInfo;
+import com.netscape.cms.servlet.wizard.IWizardPanel;
+import com.netscape.cms.servlet.wizard.WizardServlet;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+import com.netscape.cmsutil.http.HttpClient;
+import com.netscape.cmsutil.http.HttpRequest;
+import com.netscape.cmsutil.http.HttpResponse;
+import com.netscape.cmsutil.http.JssSSLSocketFactory;
+import com.netscape.cmsutil.xml.XMLObject;
+
+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.basedn")) {
+ config.putString(name, v);
+ config.putString("preop.internaldb.master.basedn", v);
+ } else if (name.startsWith("internaldb")) {
+ config.putString(name.replaceFirst("internaldb", "preop.internaldb.master"), 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);
+ }
+ }
+
+ // set master ldap password (if it exists) temporarily in password store
+ // in case it is needed for replication. Not stored in password.conf.
+ try {
+ String master_pwd = config.getString("preop.internaldb.master.ldapauth.password", "");
+ if (!master_pwd.equals("")) {
+ config.putString("preop.internaldb.master.ldapauth.bindPWPrompt", "master_internaldb");
+ String passwordFile = config.getString("passwordFile");
+ IConfigStore psStore = CMS.createFileConfigStore(passwordFile);
+ psStore.putString("master_internaldb", master_pwd);
+ psStore.commit(false);
+ }
+ } catch (Exception e) {
+ CMS.debug("updateConfigEntries: Failed to temporarily store master bindpwd: " + e.toString());
+ e.printStackTrace();
+ throw new IOException(e.toString());
+ }
+
+ 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 {
+ 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<String> v_hostname =
+ parser.getValuesFromContainer(nodeList.item(i),
+ "Host");
+
+ Vector<String> v_https_admin_port =
+ parser.getValuesFromContainer(nodeList.item(i),
+ "SecureAdminPort");
+
+ Vector<String> 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<String> getMasterUrlListFromSecurityDomain(IConfigStore config,
+ String type,
+ String portType) {
+ Vector<String> v = new Vector<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("Type " + type);
+
+ 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<String> v_clone = parser.getValuesFromContainer(nodeList.item(i),
+ "Clone");
+ String clone = (String) v_clone.elementAt(0);
+ if (clone.equalsIgnoreCase("true"))
+ continue;
+ Vector<String> v_name = parser.getValuesFromContainer(nodeList.item(i),
+ "SubsystemName");
+ Vector<String> v_host = parser.getValuesFromContainer(nodeList.item(i),
+ "Host");
+ Vector<String> 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<String> getUrlListFromSecurityDomain(IConfigStore config,
+ String type,
+ String portType) {
+ Vector<String> v = new Vector<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 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<String> v_name = parser.getValuesFromContainer(nodeList.item(i),
+ "SubsystemName");
+ Vector<String> v_host = parser.getValuesFromContainer(nodeList.item(i),
+ "Host");
+ Vector<String> v_port = parser.getValuesFromContainer(nodeList.item(i),
+ portType);
+ Vector<String> 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<String> v_hostname =
+ parser.getValuesFromContainer(nodeList.item(i),
+ "Host");
+
+ Vector<String> v_https_ee_port =
+ parser.getValuesFromContainer(nodeList.item(i),
+ "SecurePort");
+
+ Vector<String> 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<String> v_admin_port =
+ parser.getValuesFromContainer(nodeList.item(i),
+ "SecureAdminPort");
+
+ Vector<String> 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);
+ }
+ }
+
+ // reset nicknames for system cert verification
+ String token = config.getString("preop.module.token",
+ "Internal Key Storage Token");
+ if (!token.equals("Internal Key Storage Token")) {
+ String certlist = config.getString("preop.cert.list");
+
+ StringTokenizer t1 = new StringTokenizer(certlist, ",");
+ while (t1.hasMoreTokens()) {
+ String tag = t1.nextToken();
+ if (tag.equals("sslserver"))
+ continue;
+ config.putString(type + ".cert." + tag + ".nickname",
+ token + ":" +
+ config.getString(type + ".cert." + tag + ".nickname", ""));
+ }
+ }
+ } 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/base/common/src/com/netscape/cms/servlet/filter/AdminRequestFilter.java b/base/common/src/com/netscape/cms/servlet/filter/AdminRequestFilter.java
new file mode 100644
index 000000000..c7532c7aa
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/filter/AdminRequestFilter.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) 2009 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.filter;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+
+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/base/common/src/com/netscape/cms/servlet/filter/AgentRequestFilter.java b/base/common/src/com/netscape/cms/servlet/filter/AgentRequestFilter.java
new file mode 100644
index 000000000..4225aed77
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/filter/AgentRequestFilter.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) 2009 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.filter;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+
+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/base/common/src/com/netscape/cms/servlet/filter/EEClientAuthRequestFilter.java b/base/common/src/com/netscape/cms/servlet/filter/EEClientAuthRequestFilter.java
new file mode 100644
index 000000000..8c62cd311
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/filter/EEClientAuthRequestFilter.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) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.filter;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+
+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/base/common/src/com/netscape/cms/servlet/filter/EERequestFilter.java b/base/common/src/com/netscape/cms/servlet/filter/EERequestFilter.java
new file mode 100644
index 000000000..8a8bea01c
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/filter/EERequestFilter.java
@@ -0,0 +1,186 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License 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.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+
+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/base/common/src/com/netscape/cms/servlet/key/ConfirmRecoverBySerial.java b/base/common/src/com/netscape/cms/servlet/key/ConfirmRecoverBySerial.java
new file mode 100644
index 000000000..59b01f26a
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/ConfirmRecoverBySerial.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.key;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.kra.IKeyService;
+import com.netscape.certsrv.logging.ILogger;
+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;
+
+/**
+ * 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 static final long serialVersionUID = 2221819191344494389L;
+ 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();
+
+ 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);
+
+ BigInteger seqNum = BigInteger.ZERO;
+
+ try {
+ if (req.getParameter(IN_SERIALNO) != null) {
+ seqNum = new BigInteger(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, BigInteger seq,
+ HttpServletRequest req, HttpServletResponse resp,
+ Locale locale) {
+ try {
+ header.addBigIntegerValue(OUT_SERIALNO, seq, 10);
+ 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(seq);
+
+ KeyRecordParser.fillRecordIntoArg(rec, header);
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale));
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/DisplayBySerial.java b/base/common/src/com/netscape/cms/servlet/key/DisplayBySerial.java
new file mode 100644
index 000000000..8876d9350
--- /dev/null
+++ b/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 java.io.IOException;
+import java.math.BigInteger;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+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.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+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;
+
+/**
+ * Display a specific Key Archival Request
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class DisplayBySerial extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -537957487396615246L;
+ 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);
+ BigInteger seqNum = BigInteger.ZERO;
+
+ try {
+ if (req.getParameter(IN_SERIALNO) != null) {
+ seqNum = new BigInteger(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, BigInteger 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(seq);
+
+ KeyRecordParser.fillRecordIntoArg(rec, header);
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale));
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/DisplayBySerialForRecovery.java b/base/common/src/com/netscape/cms/servlet/key/DisplayBySerialForRecovery.java
new file mode 100644
index 000000000..29cc2b3b3
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/DisplayBySerialForRecovery.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.servlet.key;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+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.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.kra.IKeyService;
+import com.netscape.certsrv.logging.ILogger;
+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;
+
+/**
+ * Display a Specific Key Archival Request, and initiate
+ * key recovery process
+ *
+ * @version $Revision$, $Date$
+ */
+public class DisplayBySerialForRecovery extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6876016034084761827L;
+ 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);
+
+ BigInteger seqNum = BigInteger.ZERO;
+
+ try {
+ if (req.getParameter(IN_SERIALNO) != null) {
+ seqNum = new BigInteger(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, BigInteger 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(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/base/common/src/com/netscape/cms/servlet/key/DisplayTransport.java b/base/common/src/com/netscape/cms/servlet/key/DisplayTransport.java
new file mode 100644
index 000000000..dd224cc8a
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/DisplayTransport.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.cms.servlet.key;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.security.ITransportKeyUnit;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ECMSGWException;
+
+/**
+ * Retrieve Transport Certificate used to
+ * wrap Private key Archival requests
+ *
+ * @version $Revision$, $Date$
+ */
+public class DisplayTransport extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6509083753395783705L;
+ 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 {
+
+ 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/base/common/src/com/netscape/cms/servlet/key/ExamineRecovery.java b/base/common/src/com/netscape/cms/servlet/key/ExamineRecovery.java
new file mode 100644
index 000000000..cd440da08
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/ExamineRecovery.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.servlet.key;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Hashtable;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+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.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.kra.IKeyService;
+import com.netscape.certsrv.logging.ILogger;
+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;
+
+/**
+ * View the Key Recovery Request
+ *
+ * @version $Revision$, $Date$
+ */
+public class ExamineRecovery extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -953282265332774966L;
+ 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);
+
+ 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<String, Object> 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/base/common/src/com/netscape/cms/servlet/key/GetApprovalStatus.java b/base/common/src/com/netscape/cms/servlet/key/GetApprovalStatus.java
new file mode 100644
index 000000000..55d79b1ab
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/GetApprovalStatus.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 java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+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;
+
+/**
+ * Check to see if a Key Recovery Request has been approved
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetApprovalStatus extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8257339915430654983L;
+ 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 rComplete = 0;
+
+ // get status and populate argSet
+ try {
+ String recoveryID = req.getParameter("recoveryID");
+
+ header.addStringValue("recoveryID", recoveryID);
+
+ Hashtable<String, Object> 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<Credential> dc = ((IKeyRecoveryAuthority) mService).getAppAgents(recoveryID);
+ Enumeration<Credential> agents = dc.elements();
+
+ while (agents.hasMoreElements()) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addStringValue("agentName", 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/base/common/src/com/netscape/cms/servlet/key/GetAsyncPk12.java b/base/common/src/com/netscape/cms/servlet/key/GetAsyncPk12.java
new file mode 100644
index 000000000..9d67cab8d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/GetAsyncPk12.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.cms.servlet.key;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+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.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;
+
+/**
+ * Get the recovered key in PKCS#12 format
+ * - for asynchronous key recovery only
+ *
+ */
+public class GetAsyncPk12 extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6933634840339605800L;
+
+ 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 final static String LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS =
+ "LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS_4";
+
+ private final static String LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE =
+ "LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE_4";
+
+ 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();
+ String auditMessage = null;
+ String agent = null;
+ String reqID = null;
+
+ 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);
+
+ // get status and populate argSet
+ try {
+ reqID = req.getParameter("reqID");
+ header.addStringValue("reqID", reqID);
+
+ // only the init DRM agent can get the pkcs12
+ SessionContext sContext = SessionContext.getContext();
+
+ 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;
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS,
+ agent,
+ ILogger.SUCCESS,
+ reqID,
+ "");
+
+ audit(auditMessage);
+
+ 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]));
+ }
+
+ if ((agent != null) && (reqID != null)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE,
+ agent,
+ ILogger.FAILURE,
+ reqID,
+ "");
+
+ audit(auditMessage);
+ }
+
+ 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/base/common/src/com/netscape/cms/servlet/key/GetPk12.java b/base/common/src/com/netscape/cms/servlet/key/GetPk12.java
new file mode 100644
index 000000000..96fe7c85d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/GetPk12.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.servlet.key;
+
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+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.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;
+
+/**
+ * Get the recovered key in PKCS#12 format
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetPk12 extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8974964964333880697L;
+
+ 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 final static String LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS =
+ "LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS_4";
+
+ private final static String LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE =
+ "LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE_4";
+
+ 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();
+ String auditMessage = null;
+ String recoveryID = null;
+ String agent = null;
+
+ 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);
+
+ // get status and populate argSet
+ try {
+ recoveryID = req.getParameter("recoveryID");
+
+ header.addStringValue("recoveryID", recoveryID);
+
+ Hashtable<String, Object> 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();
+ 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;
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS,
+ agent,
+ ILogger.SUCCESS,
+ recoveryID,
+ "");
+
+ audit(auditMessage);
+
+ 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]));
+ }
+
+ if ((agent != null) && (recoveryID != null)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE,
+ agent,
+ ILogger.FAILURE,
+ recoveryID,
+ "");
+
+ audit(auditMessage);
+ }
+
+ 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/base/common/src/com/netscape/cms/servlet/key/GrantAsyncRecovery.java b/base/common/src/com/netscape/cms/servlet/key/GrantAsyncRecovery.java
new file mode 100644
index 000000000..7c0c0cb1c
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/GrantAsyncRecovery.java
@@ -0,0 +1,280 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License 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 java.io.IOException;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+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.kra.IKeyService;
+import com.netscape.certsrv.logging.ILogger;
+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;
+
+/**
+ * Approve an asynchronous key recovery request
+ *
+ */
+public class GrantAsyncRecovery extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4200111795169532676L;
+ 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);
+
+ 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/base/common/src/com/netscape/cms/servlet/key/GrantRecovery.java b/base/common/src/com/netscape/cms/servlet/key/GrantRecovery.java
new file mode 100644
index 000000000..02aacc31c
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/GrantRecovery.java
@@ -0,0 +1,308 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.util.Hashtable;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+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.kra.IKeyService;
+import com.netscape.certsrv.logging.ILogger;
+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;
+
+/**
+ * Approve a key recovery request
+ *
+ * @version $Revision$, $Date$
+ */
+public class GrantRecovery extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 991970686415492L;
+ 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);
+
+ 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<String, Object> 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/base/common/src/com/netscape/cms/servlet/key/KeyRecordParser.java b/base/common/src/com/netscape/cms/servlet/key/KeyRecordParser.java
new file mode 100644
index 000000000..aeee624c0
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/KeyRecordParser.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.cms.servlet.key;
+
+import java.util.Date;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.IPrettyPrintFormat;
+import com.netscape.certsrv.dbs.keydb.IKeyRecord;
+
+/**
+ * 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.addBigIntegerValue(OUT_SERIALNO,
+ rec.getSerialNumber(), 10);
+ 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/base/common/src/com/netscape/cms/servlet/key/KeyResource.java b/base/common/src/com/netscape/cms/servlet/key/KeyResource.java
new file mode 100644
index 000000000..a47c46d86
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/KeyResource.java
@@ -0,0 +1,33 @@
+package com.netscape.cms.servlet.key;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+
+import com.netscape.cms.servlet.key.model.KeyData;
+import com.netscape.cms.servlet.request.model.RecoveryRequestData;
+
+@Path("/key")
+public interface KeyResource {
+
+ /**
+ * Used to retrieve a key
+ * @param data
+ * @return
+ */
+ @POST
+ @Path("retrieve")
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
+ @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ public KeyData retrieveKey(RecoveryRequestData data);
+
+ // retrieval - used to test integration with a browser
+ @POST
+ @Path("retrieve")
+ @Produces(MediaType.TEXT_XML)
+ @Consumes({ MediaType.APPLICATION_FORM_URLENCODED})
+ public KeyData retrieveKey(MultivaluedMap<String, String> form);
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/KeyResourceService.java b/base/common/src/com/netscape/cms/servlet/key/KeyResourceService.java
new file mode 100644
index 000000000..79e6ccfdb
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/KeyResourceService.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) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.cms.servlet.key;
+
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import com.netscape.cms.servlet.base.CMSResourceService;
+import com.netscape.cms.servlet.key.model.KeyDAO;
+import com.netscape.cms.servlet.key.model.KeyData;
+import com.netscape.cms.servlet.request.model.KeyRequestDAO;
+import com.netscape.cms.servlet.request.model.KeyRequestInfo;
+import com.netscape.cms.servlet.request.model.RecoveryRequestData;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.keydb.KeyId;
+
+/**
+ * @author alee
+ *
+ */
+public class KeyResourceService extends CMSResourceService implements KeyResource{
+
+ @Context
+ UriInfo uriInfo;
+
+ /**
+ * Used to retrieve a key
+ * @param data
+ * @return
+ */
+ public KeyData retrieveKey(RecoveryRequestData data) {
+ // auth and authz
+ KeyId keyId = validateRequest(data);
+ KeyDAO dao = new KeyDAO();
+ KeyData keyData;
+ try {
+ keyData = dao.getKey(keyId, data);
+ } catch (EBaseException e) {
+ // log error
+ e.printStackTrace();
+ throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+ }
+ if (keyData == null) {
+ // no key record
+ throw new WebApplicationException(Response.Status.GONE);
+ }
+ return keyData;
+ }
+
+ // retrieval - used to test integration with a browser
+ public KeyData retrieveKey(MultivaluedMap<String, String> form) {
+ RecoveryRequestData data = new RecoveryRequestData(form);
+ return retrieveKey(data);
+ }
+
+ private KeyId validateRequest(RecoveryRequestData data) {
+
+ // confirm request exists
+ RequestId reqId = data.getRequestId();
+ if (reqId == null) {
+ // log error
+ throw new WebApplicationException(Response.Status.BAD_REQUEST);
+ }
+
+ // confirm that at least one wrapping method exists
+ // There must be at least the wrapped session key method.
+ if ((data.getTransWrappedSessionKey() == null)) {
+ // log error
+ throw new WebApplicationException(Response.Status.BAD_REQUEST);
+ }
+
+ KeyRequestDAO reqDAO = new KeyRequestDAO();
+ KeyRequestInfo reqInfo;
+ try {
+ reqInfo = reqDAO.getRequest(reqId, uriInfo);
+ } catch (EBaseException e1) {
+ // failed to get request
+ e1.printStackTrace();
+ throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+ }
+ if (reqInfo == null) {
+ // request not found
+ throw new WebApplicationException(Response.Status.GONE);
+ }
+
+ //confirm request is of the right type
+ String type = reqInfo.getRequestType();
+ if (!type.equals(IRequest.SECURITY_DATA_RECOVERY_REQUEST)) {
+ // log error
+ throw new WebApplicationException(Response.Status.BAD_REQUEST);
+ }
+
+ //confirm that agent is originator of request, else throw 401
+ // TO-DO
+
+ // confirm request is in approved state
+ String status = reqInfo.getRequestStatus();
+ if (!status.equals(RequestStatus.APPROVED.toString())) {
+ // log error
+ throw new WebApplicationException(Response.Status.UNAUTHORIZED);
+ }
+
+ return reqInfo.getKeyId();
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/KeysResource.java b/base/common/src/com/netscape/cms/servlet/key/KeysResource.java
new file mode 100644
index 000000000..c93ffa4c9
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/KeysResource.java
@@ -0,0 +1,23 @@
+package com.netscape.cms.servlet.key;
+
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import com.netscape.cms.servlet.key.model.KeyDataInfos;
+
+@Path("/keys")
+public interface KeysResource {
+ public static final int DEFAULT_MAXTIME = 10;
+ public static final int DEFAULT_MAXRESULTS = 100;
+
+ @GET
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
+ public KeyDataInfos listKeys(@QueryParam("clientID") String clientID,
+ @QueryParam("status") String status,
+ @DefaultValue(""+DEFAULT_MAXRESULTS) @QueryParam("maxResults") int maxResults,
+ @DefaultValue(""+DEFAULT_MAXTIME) @QueryParam("maxTime") int maxTime);
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/KeysResourceService.java b/base/common/src/com/netscape/cms/servlet/key/KeysResourceService.java
new file mode 100644
index 000000000..a7876a6c6
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/KeysResourceService.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) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+/**
+ *
+ */
+package com.netscape.cms.servlet.key;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.cms.servlet.base.CMSResourceService;
+import com.netscape.cms.servlet.key.model.KeyDAO;
+import com.netscape.cms.servlet.key.model.KeyDataInfos;
+import com.netscape.cmsutil.ldap.LDAPUtil;
+
+/**
+ * @author alee
+ *
+ */
+public class KeysResourceService extends CMSResourceService implements KeysResource {
+
+ @Context
+ UriInfo uriInfo;
+
+ /**
+ * Used to generate list of key infos based on the search parameters
+ */
+ public KeyDataInfos listKeys(String clientID, String status, int maxResults, int maxTime) {
+ // auth and authz
+
+ // get ldap filter
+ String filter = createSearchFilter(status, clientID);
+ CMS.debug("listKeys: filter is " + filter);
+
+ KeyDAO dao = new KeyDAO();
+ KeyDataInfos infos;
+ try {
+ infos = dao.listKeys(filter, maxResults, maxTime, uriInfo);
+ } catch (EBaseException e) {
+ e.printStackTrace();
+ throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+ }
+ return infos;
+ }
+
+ private String createSearchFilter(String status, String clientID) {
+ String filter = "";
+ int matches = 0;
+
+ if ((status == null) && (clientID == null)) {
+ filter = "(serialno=*)";
+ return filter;
+ }
+
+ if (status != null) {
+ filter += "(status=" + LDAPUtil.escape(status) + ")";
+ matches ++;
+ }
+
+ if (clientID != null) {
+ filter += "(clientID=" + LDAPUtil.escape(clientID) + ")";
+ matches ++;
+ }
+
+ if (matches > 1) {
+ filter = "(&" + filter + ")";
+ }
+
+ return filter;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/RecoverBySerial.java b/base/common/src/com/netscape/cms/servlet/key/RecoverBySerial.java
new file mode 100644
index 000000000..28ff30803
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/RecoverBySerial.java
@@ -0,0 +1,529 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.math.BigInteger;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X509CertImpl;
+
+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;
+
+/**
+ * A class representing a recoverBySerial servlet.
+ *
+ * @version $Revision$, $Date$
+ */
+public class RecoverBySerial extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4544485601409309840L;
+ 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);
+
+ SessionContext ctx = null;
+
+ try {
+ 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 {
+ SessionContext.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 || cert.trim().length() == 0) {
+ 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 || cert.trim().length() == 0) {
+ // 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<String, Object> 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<Credential> v = new Vector<Credential>();
+
+ 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.addBigIntegerValue(OUT_SERIALNO,
+ new BigInteger(seq), 10);
+ 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<String, Object> 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/base/common/src/com/netscape/cms/servlet/key/SrchKey.java b/base/common/src/com/netscape/cms/servlet/key/SrchKey.java
new file mode 100644
index 000000000..bff14e9f2
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/SrchKey.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.servlet.key;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X500Name;
+
+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.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+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;
+
+/**
+ * Retrieve archived keys matching search criteria
+ *
+ * @version $Revision$, $Date$
+ */
+public class SrchKey extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6404955402865756665L;
+ 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<IKeyRecord> e = mKeyDB.searchKeys(filter,
+ maxResults, timeLimit);
+ int count = 0;
+
+ if (e == null) {
+ header.addStringValue(OUT_SENTINEL,
+ null);
+ } else {
+ while (e.hasMoreElements()) {
+ IKeyRecord rec = 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/base/common/src/com/netscape/cms/servlet/key/SrchKeyForRecovery.java b/base/common/src/com/netscape/cms/servlet/key/SrchKeyForRecovery.java
new file mode 100644
index 000000000..95c777701
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/SrchKeyForRecovery.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.key;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X500Name;
+
+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.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+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;
+
+/**
+ * Retrieve archived keys matching given public key material
+ *
+ *
+ * @version $Revision$, $Date$
+ */
+public class SrchKeyForRecovery extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5426987963811540460L;
+ 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<IKeyRecord> e = mKeyDB.searchKeys(filter, maxResults, timeLimit);
+ int count = 0;
+
+ if (e == null) {
+ header.addStringValue(OUT_SENTINEL,
+ null);
+ } else {
+ while (e.hasMoreElements()) {
+ IKeyRecord rec = 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/base/common/src/com/netscape/cms/servlet/key/model/KeyDAO.java b/base/common/src/com/netscape/cms/servlet/key/model/KeyDAO.java
new file mode 100644
index 000000000..f479c6f0d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/model/KeyDAO.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) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.key.model;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+
+import javax.ws.rs.Path;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.dbs.keydb.KeyId;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cms.servlet.key.KeyResource;
+import com.netscape.cms.servlet.request.model.RecoveryRequestData;
+
+/**
+ * @author alee
+ *
+ */
+public class KeyDAO {
+
+ private IKeyRepository repo;
+ private IKeyRecoveryAuthority kra;
+ private IRequestQueue queue;
+
+ public KeyDAO() {
+ kra = ( IKeyRecoveryAuthority ) CMS.getSubsystem( "kra" );
+ repo = kra.getKeyRepository();
+ queue = kra.getRequestQueue();
+ }
+ /**
+ * Returns list of keys meeting specified search filter.
+ * Currently, vlv searches are not used for keys.
+ *
+ * @param filter
+ * @param maxResults
+ * @param maxTime
+ * @param uriInfo
+ * @return
+ * @throws EBaseException
+ */
+ public KeyDataInfos listKeys(String filter, int maxResults, int maxTime, UriInfo uriInfo)
+ throws EBaseException {
+ List <KeyDataInfo> list = new ArrayList<KeyDataInfo>();
+ Enumeration<IKeyRecord> e = null;
+
+ e = repo.searchKeys(filter, maxResults, maxTime);
+ if (e == null) {
+ throw new EBaseException("search results are null");
+ }
+
+ while (e.hasMoreElements()) {
+ IKeyRecord rec = e.nextElement();
+ if (rec != null) {
+ list.add(createKeyDataInfo(rec, uriInfo));
+ }
+ }
+
+ KeyDataInfos ret = new KeyDataInfos();
+ ret.setKeyInfos(list);
+
+ return ret;
+ }
+
+ public KeyData getKey(KeyId keyId, RecoveryRequestData data) throws EBaseException {
+ KeyData keyData;
+
+ RequestId rId = data.getRequestId();
+
+ String transWrappedSessionKey;
+ String sessionWrappedPassphrase;
+
+ IRequest request = queue.findRequest(rId);
+
+ if (request == null) {
+ return null;
+ }
+
+ // get wrapped key
+ IKeyRecord rec = repo.readKeyRecord(keyId.toBigInteger());
+ if (rec == null) {
+ return null;
+ }
+
+ Hashtable<String, Object> requestParams = kra.getVolatileRequest(
+ request.getRequestId());
+
+ if(requestParams == null) {
+ throw new EBaseException("Can't obtain Volatile requestParams in KeyDAO.getKey!");
+ }
+
+ String sessWrappedKeyData = (String) requestParams.get(IRequest.SECURITY_DATA_SESS_WRAPPED_DATA);
+ String passWrappedKeyData = (String) requestParams.get(IRequest.SECURITY_DATA_PASS_WRAPPED_DATA);
+ String nonceData = (String) requestParams.get(IRequest.SECURITY_DATA_IV_STRING_OUT);
+
+ if (sessWrappedKeyData != null || passWrappedKeyData != null) {
+ //The recovery process has already placed a valid recovery
+ //package, either session key wrapped or pass wrapped, into the request.
+ //Request already has been processed.
+ keyData = new KeyData();
+
+ } else {
+ // The request has not yet been processed, let's see if the RecoveryRequestData contains
+ // the info now needed to process the recovery request.
+
+ transWrappedSessionKey = data.getTransWrappedSessionKey();
+ sessionWrappedPassphrase = data.getSessionWrappedPassphrase();
+ nonceData = data.getNonceData();
+
+ if (transWrappedSessionKey == null) {
+ //There must be at least a transWrappedSessionKey input provided.
+ //The command AND the request have provided insufficient data, end of the line.
+ throw new EBaseException("Can't retrieve key, insufficient input data!");
+ }
+
+ if (sessionWrappedPassphrase != null) {
+ requestParams.put(IRequest.SECURITY_DATA_SESS_PASS_PHRASE, sessionWrappedPassphrase);
+ }
+
+ if (transWrappedSessionKey != null) {
+ requestParams.put(IRequest.SECURITY_DATA_TRANS_SESS_KEY, transWrappedSessionKey);
+ }
+
+ if (nonceData != null) {
+ requestParams.put(IRequest.SECURITY_DATA_IV_STRING_IN, nonceData);
+ }
+
+ try {
+ // Has to be in this state or it won't go anywhere.
+ request.setRequestStatus(RequestStatus.BEGIN);
+ queue.processRequest(request);
+ } catch (EBaseException e) {
+ kra.destroyVolatileRequest(request.getRequestId());
+ throw new EBaseException(e.toString());
+ }
+
+ nonceData = null;
+ keyData = new KeyData();
+
+ sessWrappedKeyData = (String) requestParams.get(IRequest.SECURITY_DATA_SESS_WRAPPED_DATA);
+ passWrappedKeyData = (String) requestParams.get(IRequest.SECURITY_DATA_PASS_WRAPPED_DATA);
+ nonceData = (String) requestParams.get(IRequest.SECURITY_DATA_IV_STRING_OUT);
+
+ }
+
+ if (sessWrappedKeyData != null) {
+ keyData.setWrappedPrivateData(sessWrappedKeyData);
+ }
+ if (passWrappedKeyData != null) {
+ keyData.setWrappedPrivateData(passWrappedKeyData);
+ }
+ if (nonceData != null) {
+ keyData.setNonceData(nonceData);
+ }
+
+ kra.destroyVolatileRequest(request.getRequestId());
+
+ queue.markAsServiced(request);
+
+ return keyData;
+ }
+
+ public KeyDataInfo createKeyDataInfo(IKeyRecord rec, UriInfo uriInfo) throws EBaseException {
+ KeyDataInfo ret = new KeyDataInfo();
+
+ Path keyPath = KeyResource.class.getAnnotation(Path.class);
+ BigInteger serial = rec.getSerialNumber();
+
+ UriBuilder keyBuilder = uriInfo.getBaseUriBuilder();
+ keyBuilder.path(keyPath.value() + "/" + serial);
+ ret.setKeyURL(keyBuilder.build().toString());
+
+ return ret;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/model/KeyData.java b/base/common/src/com/netscape/cms/servlet/key/model/KeyData.java
new file mode 100644
index 000000000..4f303e27d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/model/KeyData.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) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ *
+ */
+package com.netscape.cms.servlet.key.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * @author alee
+ *
+ */
+@XmlRootElement(name="SecurityData")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class KeyData {
+ @XmlElement
+ String wrappedPrivateData;
+
+ @XmlElement
+ String nonceData;
+
+ public KeyData() {
+ // required for JAXB (defaults)
+ }
+
+ /**
+ * @return the wrappedPrivateData
+ */
+ public String getWrappedPrivateData() {
+ return wrappedPrivateData;
+ }
+
+ /**
+ * @param wrappedPrivateData the wrappedPrivateData to set
+ */
+ public void setWrappedPrivateData(String wrappedPrivateData) {
+ this.wrappedPrivateData = wrappedPrivateData;
+ }
+
+ /**
+ * @return the nonceData
+ */
+
+ public String getNonceData() {
+ return nonceData;
+ }
+
+ /**
+ * @param nonceData the nonceData to set
+ */
+
+ public void setNonceData(String nonceData) {
+ this.nonceData = nonceData;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/model/KeyDataInfo.java b/base/common/src/com/netscape/cms/servlet/key/model/KeyDataInfo.java
new file mode 100644
index 000000000..88b31b4d1
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/model/KeyDataInfo.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) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+/**
+ *
+ */
+package com.netscape.cms.servlet.key.model;
+
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlAccessorType;
+
+import com.netscape.certsrv.dbs.keydb.KeyId;
+
+/**
+ * @author alee
+ *
+ */
+@XmlRootElement(name="SecurityDataInfo")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class KeyDataInfo {
+
+ @XmlElement
+ protected String keyURL;
+
+ @XmlElement
+ protected String clientID;
+
+ public KeyDataInfo() {
+ // required for JAXB (defaults)
+ }
+
+ /**
+ * @return the keyURL
+ */
+ public String getKeyURL() {
+ return keyURL;
+ }
+
+ /**
+ * @param keyURL the keyURL to set
+ */
+ public void setKeyURL(String keyURL) {
+ this.keyURL = keyURL;
+ }
+
+ /**
+ * @return the key ID in the keyURL
+ */
+ public KeyId getKeyId() {
+ String id = keyURL.substring(keyURL.lastIndexOf("/") + 1);
+ return new KeyId(id);
+ }
+
+ /**
+ * @return the clientID
+ */
+ public String getClientID() {
+ return clientID;
+ }
+
+ /**
+ * @param clientID the clientID to set
+ */
+ public void setClientID(String clientID) {
+ this.clientID = clientID;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/model/KeyDataInfos.java b/base/common/src/com/netscape/cms/servlet/key/model/KeyDataInfos.java
new file mode 100644
index 000000000..b01184708
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/model/KeyDataInfos.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) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.key.model;
+
+import java.util.Collection;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlElementRef;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import com.netscape.cms.servlet.base.model.Link;
+
+@XmlRootElement(name = "SecurityDataInfos")
+public class KeyDataInfos {
+
+ protected Collection<KeyDataInfo> keyInfos;
+ protected List<Link> links;
+
+ /**
+ * @return the keyInfos
+ */
+ @XmlElementRef
+ public Collection<KeyDataInfo> getKeyInfos() {
+ return keyInfos;
+ }
+ /**
+ * @param keyInfos the keyInfos to set
+ */
+ public void setKeyInfos(Collection<KeyDataInfo> keyInfos) {
+ this.keyInfos = keyInfos;
+ }
+ /**
+ * @return the links
+ */
+ @XmlElementRef
+ public List<Link> getLinks() {
+ return links;
+ }
+ /**
+ * @param links the links to set
+ */
+ public void setLinks(List<Link> links) {
+ this.links = links;
+ }
+
+ @XmlTransient
+ public String getNext() {
+ if (links == null) {
+ return null;
+ }
+ for (Link link : links) {
+ if ("next".equals(link.getRelationship())) {
+ return link.getHref();
+ }
+ }
+ return null;
+ }
+
+ @XmlTransient
+ public String getPrevious() {
+ if (links == null) {
+ return null;
+ }
+ for (Link link : links) {
+ if ("previous".equals(link.getRelationship())) {
+ return link.getHref();
+ }
+ }
+ return null;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/ocsp/AddCAServlet.java b/base/common/src/com/netscape/cms/servlet/ocsp/AddCAServlet.java
new file mode 100644
index 000000000..1ef680853
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/ocsp/AddCAServlet.java
@@ -0,0 +1,310 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.X509Certificate;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ocsp.IDefStore;
+import com.netscape.certsrv.ocsp.IOCSPAuthority;
+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;
+
+/**
+ * Configure the CA to respond to OCSP requests for a CA
+ *
+ * @version $Revision$ $Date$
+ */
+public class AddCAServlet extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1065151608542115340L;
+ 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 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) {
+ 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/base/common/src/com/netscape/cms/servlet/ocsp/AddCRLServlet.java b/base/common/src/com/netscape/cms/servlet/ocsp/AddCRLServlet.java
new file mode 100644
index 000000000..2dec0e1f5
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/ocsp/AddCRLServlet.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.ocsp;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.CRLException;
+import java.security.cert.X509CRL;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X509CRLImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509ExtensionException;
+
+import org.mozilla.jss.CryptoManager;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.dbs.repository.IRepositoryRecord;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ocsp.IDefStore;
+import com.netscape.certsrv.ocsp.IOCSPAuthority;
+import com.netscape.certsrv.util.IStatsSubsystem;
+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;
+
+/**
+ * Update the OCSP responder with a new CRL
+ *
+ * @version $Revision$ $Date$
+ */
+public class AddCRLServlet extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1476080474638590902L;
+ 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)) {
+ if (authToken != null) {
+ 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());
+
+ 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/base/common/src/com/netscape/cms/servlet/ocsp/CheckCertServlet.java b/base/common/src/com/netscape/cms/servlet/ocsp/CheckCertServlet.java
new file mode 100644
index 000000000..dfe796366
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/ocsp/CheckCertServlet.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.ocsp;
+
+import java.io.IOException;
+import java.security.cert.X509CRLEntry;
+import java.security.cert.X509Certificate;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X509CRLImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ocsp.IDefStore;
+import com.netscape.certsrv.ocsp.IOCSPAuthority;
+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;
+
+/**
+ * Check the status of a specific certificate
+ *
+ * @version $Revision$ $Date$
+ */
+public class CheckCertServlet extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7782198059640825050L;
+ 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 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) {
+ 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/base/common/src/com/netscape/cms/servlet/ocsp/GetOCSPInfo.java b/base/common/src/com/netscape/cms/servlet/ocsp/GetOCSPInfo.java
new file mode 100644
index 000000000..3dfc1d5f3
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/ocsp/GetOCSPInfo.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.servlet.ocsp;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+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.logging.ILogger;
+import com.netscape.certsrv.ocsp.IOCSPService;
+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;
+
+/**
+ * Retrieve information about the number of OCSP requests the OCSP
+ * has serviced
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetOCSPInfo extends CMSServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3633557968127876119L;
+ 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;
+ }
+
+ 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/base/common/src/com/netscape/cms/servlet/ocsp/ListCAServlet.java b/base/common/src/com/netscape/cms/servlet/ocsp/ListCAServlet.java
new file mode 100644
index 000000000..a93512ccd
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/ocsp/ListCAServlet.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.cms.servlet.ocsp;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ocsp.IDefStore;
+import com.netscape.certsrv.ocsp.IOCSPAuthority;
+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;
+
+/**
+ * Show the list of CA's that the OCSP responder can service
+ *
+ * @version $Revision$ $Date$
+ */
+public class ListCAServlet extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3764395161795483452L;
+ 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<ICRLIssuingPointRecord> recs = defStore.searchAllCRLIssuingPointRecord(100);
+
+ // show the current CRL number if present
+ header.addStringValue("stateCount",
+ Integer.toString(defStore.getStateCount()));
+
+ while (recs.hasMoreElements()) {
+ ICRLIssuingPointRecord rec = 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 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) {
+ 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/base/common/src/com/netscape/cms/servlet/ocsp/OCSPServlet.java b/base/common/src/com/netscape/cms/servlet/ocsp/OCSPServlet.java
new file mode 100644
index 000000000..3ab20141c
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/ocsp/OCSPServlet.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.ocsp;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.mozilla.jss.asn1.ASN1Util;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.ocsp.IOCSPService;
+import com.netscape.certsrv.util.IStatsSubsystem;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cmsutil.ocsp.BasicOCSPResponse;
+import com.netscape.cmsutil.ocsp.OCSPRequest;
+import com.netscape.cmsutil.ocsp.OCSPResponse;
+import com.netscape.cmsutil.ocsp.ResponseBytes;
+import com.netscape.cmsutil.ocsp.ResponseData;
+import com.netscape.cmsutil.ocsp.SingleResponse;
+import com.netscape.cmsutil.ocsp.TBSRequest;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * Process OCSP messages, According to RFC 2560
+ * See http://www.ietf.org/rfc/rfc2560.txt
+ *
+ * @version $Revision$ $Date$
+ */
+public class OCSPServlet extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 120903601883352030L;
+ 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();
+ if (pathInfo != null && pathInfo.indexOf('%') != -1) {
+ try {
+ pathInfo = URLDecoder.decode(pathInfo, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ throw new EBaseException("OCSPServlet: Unsupported encoding" + e);
+ }
+ }
+ 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(
+ Utils.base64decode(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/base/common/src/com/netscape/cms/servlet/ocsp/RemoveCAServlet.java b/base/common/src/com/netscape/cms/servlet/ocsp/RemoveCAServlet.java
new file mode 100644
index 000000000..4262940d0
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/ocsp/RemoveCAServlet.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.cms.servlet.ocsp;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ocsp.IDefStore;
+import com.netscape.certsrv.ocsp.IOCSPAuthority;
+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;
+
+/**
+ * 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 static final long serialVersionUID = -4519898238552366358L;
+ 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();
+
+ 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 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) {
+ 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/base/common/src/com/netscape/cms/servlet/processors/CMCProcessor.java b/base/common/src/com/netscape/cms/servlet/processors/CMCProcessor.java
new file mode 100644
index 000000000..53c13510d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/processors/CMCProcessor.java
@@ -0,0 +1,433 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.PublicKey;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Hashtable;
+
+import netscape.security.pkcs.PKCS10;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.crypto.DigestAlgorithm;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.pkcs10.CertificationRequest;
+import org.mozilla.jss.pkcs11.PK11PubKey;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.pkix.cert.CertificateInfo;
+import org.mozilla.jss.pkix.cmc.PKIData;
+import org.mozilla.jss.pkix.cmc.TaggedAttribute;
+import org.mozilla.jss.pkix.cmc.TaggedCertificationRequest;
+import org.mozilla.jss.pkix.cmc.TaggedRequest;
+import org.mozilla.jss.pkix.cms.EncapsulatedContentInfo;
+import org.mozilla.jss.pkix.cms.IssuerAndSerialNumber;
+import org.mozilla.jss.pkix.cms.SignedData;
+import org.mozilla.jss.pkix.cms.SignerIdentifier;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.pkix.primitive.Name;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ECMSGWException;
+
+/**
+ * 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<String, byte[]> digs = new Hashtable<String, byte[]>();
+
+ 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/base/common/src/com/netscape/cms/servlet/processors/CRMFProcessor.java b/base/common/src/com/netscape/cms/servlet/processors/CRMFProcessor.java
new file mode 100644
index 000000000..2d2f1430e
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/processors/CRMFProcessor.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.processors;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.cert.CertificateException;
+
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.Extension;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.crmf.CertTemplate;
+import org.mozilla.jss.pkix.crmf.ProofOfPossession;
+import org.mozilla.jss.pkix.primitive.Name;
+import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ECMSGWException;
+
+/**
+ * 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();
+
+ 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/base/common/src/com/netscape/cms/servlet/processors/IPKIProcessor.java b/base/common/src/com/netscape/cms/servlet/processors/IPKIProcessor.java
new file mode 100644
index 000000000..9139f888c
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/processors/IPKIProcessor.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.cms.servlet.processors;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.cms.servlet.common.CMSRequest;
+
+/**
+ * This represents the request parser.
+ *
+ * @version $Revision$, $Date$
+ */
+public interface IPKIProcessor {
+
+ public void process(CMSRequest cmsReq)
+ throws EBaseException;
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/processors/KeyGenProcessor.java b/base/common/src/com/netscape/cms/servlet/processors/KeyGenProcessor.java
new file mode 100644
index 000000000..cfe9754a8
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/processors/KeyGenProcessor.java
@@ -0,0 +1,120 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.io.IOException;
+import java.security.cert.CertificateException;
+
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.KeyGenInfo;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ECMSGWException;
+
+/**
+ * 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/base/common/src/com/netscape/cms/servlet/processors/PKCS10Processor.java b/base/common/src/com/netscape/cms/servlet/processors/PKCS10Processor.java
new file mode 100644
index 000000000..dad4b64ab
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/processors/PKCS10Processor.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.processors;
+
+import java.io.IOException;
+import java.security.cert.CertificateException;
+
+import netscape.security.pkcs.PKCS10;
+import netscape.security.pkcs.PKCS10Attribute;
+import netscape.security.pkcs.PKCS10Attributes;
+import netscape.security.pkcs.PKCS9Attribute;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.Extensions;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.IAuthSubsystem;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ECMSGWException;
+
+/**
+ * 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/base/common/src/com/netscape/cms/servlet/processors/PKIProcessor.java b/base/common/src/com/netscape/cms/servlet/processors/PKIProcessor.java
new file mode 100644
index 000000000..5b78bb42a
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/processors/PKIProcessor.java
@@ -0,0 +1,356 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.io.IOException;
+import java.security.cert.CertificateException;
+import java.util.Date;
+
+import javax.servlet.http.HttpServletRequest;
+
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.X500Name;
+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.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ECMSGWException;
+
+/**
+ * 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();
+
+ }
+
+ 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/base/common/src/com/netscape/cms/servlet/profile/ProfileApproveServlet.java b/base/common/src/com/netscape/cms/servlet/profile/ProfileApproveServlet.java
new file mode 100644
index 000000000..48848695f
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/profile/ProfileApproveServlet.java
@@ -0,0 +1,532 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.IAuthority;
+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.EProfileException;
+import com.netscape.certsrv.profile.IPolicyConstraint;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfilePolicy;
+import com.netscape.certsrv.profile.IProfileSubsystem;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.template.ArgList;
+import com.netscape.certsrv.template.ArgSet;
+import com.netscape.cms.servlet.common.CMSRequest;
+
+/**
+ * Toggle the approval state of a profile
+ *
+ * @version $Revision$, $Date$
+ */
+public class ProfileApproveServlet extends ProfileServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3956879326742839550L;
+ 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);
+ auditSubjectID = auditSubjectID();
+ CMS.debug("uid=" + authToken.getInString("userid"));
+ userid = authToken.getInString("userid");
+ } catch (Exception e) {
+ auditSubjectID = auditSubjectID();
+ 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<String> policySetIds = profile.getProfilePolicySetIds();
+
+ ArgList setlist = new ArgList();
+
+ while (policySetIds.hasMoreElements()) {
+ String setId = policySetIds.nextElement();
+
+ Enumeration<String> policyIds = profile.getProfilePolicyIds(setId);
+ ArgList list = new ArgList();
+
+ while (policyIds.hasMoreElements()) {
+ String id = policyIds.nextElement();
+ IProfilePolicy policy = 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<String> defNames = def.getValueNames();
+
+ if (defNames != null) {
+ while (defNames.hasMoreElements()) {
+ ArgSet defset = new ArgSet();
+ String defName = 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/base/common/src/com/netscape/cms/servlet/profile/ProfileListServlet.java b/base/common/src/com/netscape/cms/servlet/profile/ProfileListServlet.java
new file mode 100644
index 000000000..2ca5f0a5c
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/profile/ProfileListServlet.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.cms.servlet.profile;
+
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+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 long serialVersionUID = -5118812083812548395L;
+
+ 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<String> 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/base/common/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java b/base/common/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java
new file mode 100644
index 000000000..e482b67da
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java
@@ -0,0 +1,960 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.Nonces;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EDeferException;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.profile.IPolicyConstraint;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileOutput;
+import com.netscape.certsrv.profile.IProfilePolicy;
+import com.netscape.certsrv.profile.IProfileSubsystem;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.template.ArgList;
+import com.netscape.certsrv.template.ArgSet;
+import com.netscape.certsrv.util.IStatsSubsystem;
+import com.netscape.cms.profile.common.ProfilePolicy;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * This servlet approves profile-based request.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ProfileProcessServlet extends ProfileServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5244627530516577838L;
+ 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<String> outputIds = profile.getProfileOutputIds();
+
+ if (outputIds != null) {
+ while (outputIds.hasMoreElements()) {
+ String outputId = outputIds.nextElement();
+ IProfileOutput profileOutput = profile.getProfileOutput(
+ outputId);
+
+ Enumeration<String> outputNames = profileOutput.getValueNames();
+
+ if (outputNames != null) {
+ while (outputNames.hasMoreElements()) {
+ ArgSet outputset = new ArgSet();
+ String outputName =
+ 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<ProfilePolicy> policies = profile.getProfilePolicies(profileSetId);
+ int count = 0;
+
+ while (policies.hasMoreElements()) {
+ ProfilePolicy policy = policies.nextElement();
+
+ setValue(locale, count, policy, req, request);
+ count++;
+ }
+
+ policies = profile.getProfilePolicies(profileSetId);
+ count = 0;
+ while (policies.hasMoreElements()) {
+ ProfilePolicy policy = 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<String> defNames = def.getValueNames();
+
+ while (defNames.hasMoreElements()) {
+ String defName = 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 = Utils.base64encode(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/base/common/src/com/netscape/cms/servlet/profile/ProfileReviewServlet.java b/base/common/src/com/netscape/cms/servlet/profile/ProfileReviewServlet.java
new file mode 100644
index 000000000..dd0ee7be7
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/profile/ProfileReviewServlet.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.servlet.profile;
+
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Random;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.Nonces;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IPolicyConstraint;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.profile.IProfileOutput;
+import com.netscape.certsrv.profile.IProfilePolicy;
+import com.netscape.certsrv.profile.IProfileSubsystem;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.template.ArgList;
+import com.netscape.certsrv.template.ArgSet;
+import com.netscape.cms.servlet.common.CMSRequest;
+
+/**
+ * This servlet allows reviewing of profile-based request.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ProfileReviewServlet extends ProfileServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6559751428547928511L;
+
+ 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<String> policyIds = (profileSetId != null && profileSetId.length() > 0) ?
+ profile.getProfilePolicyIds(profileSetId) : null;
+ ArgList list = new ArgList();
+
+ if (policyIds != null) {
+ while (policyIds.hasMoreElements()) {
+ String id = policyIds.nextElement();
+ IProfilePolicy policy =
+ 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);
+ }
+ }
+
+ 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<String> inputIds = profile.getProfileInputIds();
+
+ if (inputIds != null) {
+ while (inputIds.hasMoreElements()) {
+ String inputId = inputIds.nextElement();
+ IProfileInput profileInput = profile.getProfileInput(inputId);
+
+ Enumeration<String> inputNames = profileInput.getValueNames();
+
+ if (inputNames != null) {
+ while (inputNames.hasMoreElements()) {
+ ArgSet inputset = new ArgSet();
+ String inputName = 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<String> outputIds = profile.getProfileOutputIds();
+
+ if (outputIds != null) {
+ while (outputIds.hasMoreElements()) {
+ String outputId = outputIds.nextElement();
+ IProfileOutput profileOutput = profile.getProfileOutput(outputId
+ );
+
+ Enumeration<String> outputNames = profileOutput.getValueNames();
+
+ if (outputNames != null) {
+ while (outputNames.hasMoreElements()) {
+ ArgSet outputset = new ArgSet();
+ String outputName = 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<String> defNames = def.getValueNames();
+
+ if (defNames != null) {
+ while (defNames.hasMoreElements()) {
+ ArgSet defset = new ArgSet();
+ String defName = 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/base/common/src/com/netscape/cms/servlet/profile/ProfileSelectServlet.java b/base/common/src/com/netscape/cms/servlet/profile/ProfileSelectServlet.java
new file mode 100644
index 000000000..5b07951f8
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/profile/ProfileSelectServlet.java
@@ -0,0 +1,411 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.IAuthority;
+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.EProfileException;
+import com.netscape.certsrv.profile.IPolicyConstraint;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileAuthenticator;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.profile.IProfilePolicy;
+import com.netscape.certsrv.profile.IProfileSubsystem;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.template.ArgList;
+import com.netscape.certsrv.template.ArgSet;
+import com.netscape.cms.servlet.common.CMSRequest;
+
+/**
+ * Retrieve detailed information of a particular profile.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ProfileSelectServlet extends ProfileServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3765390650830903602L;
+ 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<String> policySetIds = profile.getProfilePolicySetIds();
+
+ if (policySetIds != null) {
+ while (policySetIds.hasMoreElements()) {
+ String setId = policySetIds.nextElement();
+
+ ArgList list = new ArgList();
+ Enumeration<String> policyIds = profile.getProfilePolicyIds(setId);
+
+ if (policyIds != null) {
+ while (policyIds.hasMoreElements()) {
+ String id = 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<String> authNames = authenticator.getValueNames();
+
+ if (authNames != null) {
+ while (authNames.hasMoreElements()) {
+ ArgSet authset = new ArgSet();
+ String authName = 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<String> inputIds = profile.getProfileInputIds();
+
+ if (inputIds != null) {
+ while (inputIds.hasMoreElements()) {
+ String inputId = 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<String> inputNames = profileInput.getValueNames();
+
+ if (inputNames != null) {
+ while (inputNames.hasMoreElements()) {
+ ArgSet inputset = new ArgSet();
+ String inputName = 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<String> defNames = def.getValueNames();
+
+ if (defNames != null) {
+ while (defNames.hasMoreElements()) {
+ ArgSet defset = new ArgSet();
+ String defName = 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<String> conNames = con.getConfigNames();
+ if (conNames != null) {
+ while (conNames.hasMoreElements()) {
+ ArgSet conset = new ArgSet();
+ String conName = 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/base/common/src/com/netscape/cms/servlet/profile/ProfileServlet.java b/base/common/src/com/netscape/cms/servlet/profile/ProfileServlet.java
new file mode 100644
index 000000000..457b8422b
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/profile/ProfileServlet.java
@@ -0,0 +1,511 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authorization.IAuthzSubsystem;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.template.ArgList;
+import com.netscape.certsrv.template.ArgSet;
+import com.netscape.certsrv.template.ArgString;
+import com.netscape.certsrv.template.IArgValue;
+import com.netscape.certsrv.util.IStatsSubsystem;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.base.UserInfo;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ServletUtils;
+
+/**
+ * This servlet is the base class of all profile servlets.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ProfileServlet extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7011378748671762375L;
+ 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 = ServletUtils.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<String> names = set.getNames();
+ while (names.hasMoreElements()) {
+ String n = 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) && (c != 0x3c) && (c != 0x3e)) {
+ 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] == 'r' || in[i + 1] == 'f' || in[i + 1] == 't' ||
+ in[i + 1] == '<' || in[i + 1] == '>' ||
+ in[i + 1] == '\"' || in[i + 1] == '\'' || in[i + 1] == '\\')) {
+ if (in[i + 1] == 'x' && ((i + 3) < l) && in[i + 2] == '3' &&
+ (in[i + 3] == 'c' || in[i + 3] == 'e')) {
+ out[j++] = '\\';
+ out[j++] = in[i + 1];
+ out[j++] = in[i + 2];
+ out[j++] = in[i + 3];
+ i += 3;
+ } else {
+ 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<String> e = set.getNames();
+
+ while (e.hasMoreElements()) {
+ String n = 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<String> e = set.getNames();
+
+ while (e.hasMoreElements()) {
+ String n = 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/base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java b/base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java
new file mode 100644
index 000000000..16451f6dd
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java
@@ -0,0 +1,904 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.InputStream;
+import java.io.OutputStream;
+import java.security.cert.CertificateEncodingException;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X509CertImpl;
+
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.asn1.UTF8String;
+import org.mozilla.jss.pkix.cmc.LraPopWitness;
+import org.mozilla.jss.pkix.cmc.OtherInfo;
+import org.mozilla.jss.pkix.cmc.TaggedAttribute;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EDeferException;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileAuthenticator;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.profile.IProfileSubsystem;
+import com.netscape.certsrv.request.INotify;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cms.servlet.common.AuthCredentials;
+import com.netscape.cms.servlet.common.CMCOutputTemplate;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * This servlet submits end-user request into the profile framework.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ProfileSubmitCMCServlet extends ProfileServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8017841111435988197L;
+ 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<String> inputIds = profile.getProfileInputIds();
+
+ if (inputIds != null) {
+ while (inputIds.hasMoreElements()) {
+ String inputId = inputIds.nextElement();
+ IProfileInput profileInput = profile.getProfileInput(inputId);
+ Enumeration<String> inputNames = profileInput.getValueNames();
+
+ while (inputNames.hasMoreElements()) {
+ String inputName = inputNames.nextElement();
+
+ if (request.getParameter(inputName) != null) {
+ ctx.set(inputName, request.getParameter(inputName));
+ }
+ }
+ }
+ }
+
+ }
+
+ private void setCredentialsIntoContext(HttpServletRequest request, IProfileAuthenticator authenticator,
+ IProfileContext ctx) {
+ Enumeration<String> authIds = authenticator.getValueNames();
+
+ if (authIds != null) {
+ while (authIds.hasMoreElements()) {
+ String authName = 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<String> authNames = authenticator.getValueNames();
+
+ if (authNames != null) {
+ while (authNames.hasMoreElements()) {
+ String authName = 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<String> inputIds = profile.getProfileInputIds();
+
+ if (inputIds != null) {
+ while (inputIds.hasMoreElements()) {
+ String inputId = inputIds.nextElement();
+ IProfileInput profileInput = profile.getProfileInput(inputId);
+ Enumeration<String> inputNames = profileInput.getValueNames();
+
+ if (inputNames != null) {
+ while (inputNames.hasMoreElements()) {
+ String inputName = 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);
+ 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 = Utils.base64encode(reqbuf);
+
+ if (CMS.debugOn()) {
+ CMS.debug("Start of ProfileSubmitCMCServlet Input Parameters");
+ @SuppressWarnings("unchecked")
+ Enumeration<String> paramNames = request.getParameterNames();
+
+ while (paramNames.hasMoreElements()) {
+ String paramName = 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<String> tokenNames = authToken.getElements();
+ while (tokenNames.hasMoreElements()) {
+ String tokenName = 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;
+
+ 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<String> reqKeys = reqs[k].getExtDataKeys();
+ while (reqKeys.hasMoreElements()) {
+ String reqKey = 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 {
+ SessionContext.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 = Utils.base64encode(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/base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitServlet.java b/base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitServlet.java
new file mode 100644
index 000000000..eb3b93eb8
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitServlet.java
@@ -0,0 +1,1631 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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.math.BigInteger;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.BasicConstraintsExtension;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import org.w3c.dom.Node;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.MetaInfo;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EDeferException;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileAuthenticator;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.profile.IProfileOutput;
+import com.netscape.certsrv.profile.IProfileSubsystem;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.INotify;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.template.ArgList;
+import com.netscape.certsrv.template.ArgSet;
+import com.netscape.certsrv.util.IStatsSubsystem;
+import com.netscape.cms.servlet.common.AuthCredentials;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cmsutil.util.Cert;
+import com.netscape.cmsutil.util.Utils;
+import com.netscape.cmsutil.xml.XMLObject;
+
+/**
+ * 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 long serialVersionUID = 7557922703180866442L;
+ 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";
+
+ 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";
+
+ 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<String> inputIds = profile.getProfileInputIds();
+
+ if (inputIds != null) {
+ while (inputIds.hasMoreElements()) {
+ String inputId = (String) inputIds.nextElement();
+ IProfileInput profileInput = profile.getProfileInput(inputId);
+ Enumeration<String> 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<String> inputIds = profile.getProfileInputIds();
+
+ if (inputIds != null) {
+ while (inputIds.hasMoreElements()) {
+ String inputId = (String) inputIds.nextElement();
+ IProfileInput profileInput = profile.getProfileInput(inputId);
+ Enumeration<String> 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<String> 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<String> 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<String> inputIds = profile.getProfileInputIds();
+
+ if (inputIds != null) {
+ while (inputIds.hasMoreElements()) {
+ String inputId = (String) inputIds.nextElement();
+ IProfileInput profileInput = profile.getProfileInput(inputId);
+ Enumeration<String> 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<String> inputIds = profile.getProfileInputIds();
+
+ if (inputIds != null) {
+ while (inputIds.hasMoreElements()) {
+ String inputId = (String) inputIds.nextElement();
+ IProfileInput profileInput = profile.getProfileInput(inputId);
+ Enumeration<String> 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<String> outputIds = profile.getProfileOutputIds();
+
+ if (outputIds != null) {
+ while (outputIds.hasMoreElements()) {
+ String outputId = (String) outputIds.nextElement();
+ IProfileOutput profileOutput = profile.getProfileOutput(outputId);
+
+ Enumeration<String> 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 */);
+ }
+
+ Locale locale = getLocale(request);
+ ArgSet args = new ArgSet();
+
+ if (CMS.debugOn()) {
+ CMS.debug("Start of ProfileSubmitServlet Input Parameters");
+ @SuppressWarnings("unchecked")
+ Enumeration<String> paramNames = request.getParameterNames();
+
+ while (paramNames.hasMoreElements()) {
+ String paramName = 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<String> 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) {
+
+ CMS.debug("ProfileSubmitServlet: authentication required.");
+ String uid_cred = "Unidentified";
+ String uid_attempted_cred = "Unidentified";
+ Enumeration<String> authIds = authenticator.getValueNames();
+ //Attempt to possibly fetch attemped uid, may not always be available.
+ if (authIds != null) {
+ while (authIds.hasMoreElements()) {
+ String authName = authIds.nextElement();
+ String value = request.getParameter(authName);
+ if (value != null) {
+ if (authName.equals("uid")) {
+ uid_attempted_cred = value;
+ }
+ }
+ }
+ }
+
+ String authSubjectID = auditSubjectID();
+
+ String authMgrID = authenticator.getName();
+ String auditMessage = 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");
+ }
+
+ //audit log our authentication failure
+
+ authSubjectID += " : " + uid_cred;
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_FAIL,
+ authSubjectID,
+ ILogger.FAILURE,
+ authMgrID,
+ uid_attempted_cred);
+ audit(auditMessage);
+
+ return;
+ }
+
+ //Log successful authentication
+
+ //Attempt to get uid from authToken, most tokens respond to the "uid" cred.
+ uid_cred = authToken.getInString("uid");
+
+ if (uid_cred == null || uid_cred.length() == 0) {
+ uid_cred = "Unidentified";
+ }
+
+ authSubjectID = authSubjectID + " : " + uid_cred;
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_SUCCESS,
+ authSubjectID,
+ ILogger.SUCCESS,
+ authMgrID);
+
+ audit(auditMessage);
+
+ }
+ 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 {
+ String resource = profileId + ".authz.acl";
+ authorize(mAclMethod, resource, 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<String> tokenNames = authToken.getElements();
+ while (tokenNames.hasMoreElements()) {
+ String tokenName = 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<String> reqKeys = reqs[k].getExtDataKeys();
+ while (reqKeys.hasMoreElements()) {
+ String reqKey = 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 {
+ SessionContext.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<String> outputIds = profile.getProfileOutputIds();
+ if (outputIds != null) {
+ while (outputIds.hasMoreElements()) {
+ String outputId = outputIds.nextElement();
+ IProfileOutput profileOutput = profile.getProfileOutput(outputId);
+ Enumeration<String> outputNames = profileOutput.getValueNames();
+ if (outputNames != null) {
+ while (outputNames.hasMoreElements()) {
+ String outputName = 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 = Utils.base64encode(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/base/common/src/com/netscape/cms/servlet/profile/SSLClientCertProvider.java b/base/common/src/com/netscape/cms/servlet/profile/SSLClientCertProvider.java
new file mode 100644
index 000000000..0114f6323
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/profile/SSLClientCertProvider.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.cms.servlet.profile;
+
+import java.security.cert.X509Certificate;
+
+import javax.servlet.http.HttpServletRequest;
+
+import com.netscape.certsrv.authentication.ISSLClientCertProvider;
+
+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/base/common/src/com/netscape/cms/servlet/request/CertReqParser.java b/base/common/src/com/netscape/cms/servlet/request/CertReqParser.java
new file mode 100644
index 000000000..d8fc68a69
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/request/CertReqParser.java
@@ -0,0 +1,925 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.lang.reflect.Array;
+import java.math.BigInteger;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.extensions.NSCertTypeExtension;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.BasicConstraintsExtension;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.CertificateAlgorithmId;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.Extension;
+import netscape.security.x509.RevocationReason;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.IPrettyPrintFormat;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cms.servlet.common.CMSTemplate;
+import com.netscape.cms.servlet.common.CMSTemplateParams;
+import com.netscape.cms.servlet.common.RawJS;
+
+/**
+ * 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<String> enum1 = req.getExtDataKeys();
+
+ // gross hack
+ String prefix = "record.";
+
+ if (argSet.getHeader() == arg)
+ prefix = "header.";
+
+ while (enum1.hasMoreElements()) {
+ String name = enum1.nextElement();
+
+ if (mDetails) {
+ // show all http parameters stored in request.
+ if (name.equalsIgnoreCase(IRequest.HTTP_PARAMS)) {
+ Hashtable<String, String> http_params = req.getExtDataInHashtable(name);
+ // show certType specially
+ String certType = 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<String> elms = http_params.keys();
+
+ while (elms.hasMoreElements()) {
+ String parami =
+ IRequest.HTTP_PARAMS + LB + String.valueOf(counter++) + RB;
+ // hack
+ String n = 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.equalsIgnoreCase(IRequest.HTTP_HEADERS)) {
+ Hashtable<String, String> http_hdrs = req.getExtDataInHashtable(name);
+ Enumeration<String> elms = http_hdrs.keys();
+ int counter = 0;
+
+ while (elms.hasMoreElements()) {
+ String parami =
+ IRequest.HTTP_HEADERS + LB + String.valueOf(counter++) + RB;
+ // hack
+ String n = 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.equalsIgnoreCase(IRequest.AUTH_TOKEN)) {
+ IAuthToken auth_token = req.getExtDataInAuthToken(name);
+ Enumeration<String> elms = auth_token.getElements();
+ int counter = 0;
+
+ while (elms.hasMoreElements()) {
+ String parami =
+ IRequest.AUTH_TOKEN + LB + String.valueOf(counter++) + RB;
+ // hack
+ String n = 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;
+
+ if (name.equalsIgnoreCase(IRequest.ISSUED_CERTS) && mDetails &&
+ (req.getRequestStatus().toString().equals(RequestStatus.COMPLETE_STRING) ||
+ req.getRequestType().equals(IRequest.GETREVOCATIONINFO_REQUEST))) {
+ X509CertImpl issuedCert[] =
+ req.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+ if (issuedCert != null && issuedCert[0] != null) {
+ val = "<pre>" + CMS.getCertPrettyPrint(issuedCert[0]).toString(l) + "</pre>";
+ }
+ } else if (name.equalsIgnoreCase(IRequest.CERT_INFO) && mDetails) {
+ X509CertInfo[] certInfo =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+ if (certInfo != null && certInfo[0] != null) {
+ val = "<pre>" + certInfo[0].toString() + "</pre>";
+ }
+ }
+
+ 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.equalsIgnoreCase(IRequest.REQUESTOR_PHONE)
+ || name.equalsIgnoreCase(IRequest.REQUESTOR_EMAIL)
+ || name.equalsIgnoreCase(IRequest.REQUESTOR_COMMENTS)
+ || name.equalsIgnoreCase(IRequest.RESULT)
+ || name.equalsIgnoreCase(IRequest.REQUEST_TRUSTEDMGR_PRIVILEGE)) {
+ arg.addStringValue(name, req.getExtDataInString(name));
+ }
+
+ if (name.equalsIgnoreCase(IRequest.REQUESTOR_NAME)) {
+ String requestorName = req.getExtDataInString(name);
+
+ requestorName = requestorName.trim();
+ if (requestorName.length() > 0) {
+ arg.addStringValue(name, requestorName);
+ }
+ }
+
+ if (name.equalsIgnoreCase(IRequest.ERRORS)) {
+ Vector<String> 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.equalsIgnoreCase(IRequest.ERROR)) {
+ arg.addStringValue(IRequest.ERRORS, req.getExtDataInString(name));
+ }
+
+ if (name.equalsIgnoreCase(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<Extension> exts = extensions.getAttributes();
+
+ while (exts.hasMoreElements()) {
+ Extension ext = 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.equalsIgnoreCase(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.equalsIgnoreCase(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.equalsIgnoreCase(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.equalsIgnoreCase(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.equalsIgnoreCase(IRequest.FINGERPRINTS) && mDetails) {
+ Hashtable<String, String> fingerprints =
+ req.getExtDataInHashtable(IRequest.FINGERPRINTS);
+
+ if (fingerprints != null) {
+ String namesAndHashes = null;
+ Enumeration<String> enumFingerprints = fingerprints.keys();
+
+ while (enumFingerprints.hasMoreElements()) {
+ String hashname = enumFingerprints.nextElement();
+ String hashvalue = 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 (@SuppressWarnings("unchecked")
+ Enumeration<String> n = ((Vector<String>) 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<String> 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.equalsIgnoreCase(IRequest.HTTP_PARAMS)) {
+ Hashtable<String, String> http_params = req.getExtDataInHashtable(name);
+ // show certType specially
+ String certType = 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<String> 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.equalsIgnoreCase(IRequest.HTTP_HEADERS)) {
+ Hashtable<String, String> http_hdrs = req.getExtDataInHashtable(name);
+ Enumeration<String> elms = http_hdrs.keys();
+ int counter = 0;
+
+ while (elms.hasMoreElements()) {
+ String parami =
+ IRequest.HTTP_HEADERS + LB + String.valueOf(counter++) + RB;
+ // hack
+ String n = 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.equalsIgnoreCase(IRequest.AUTH_TOKEN)) {
+ IAuthToken auth_token = req.getExtDataInAuthToken(name);
+ Enumeration<String> 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.equalsIgnoreCase(IRequest.REQUESTOR_PHONE)
+ || name.equalsIgnoreCase(IRequest.REQUESTOR_EMAIL)
+ || name.equalsIgnoreCase(IRequest.REQUESTOR_COMMENTS)
+ || name.equalsIgnoreCase(IRequest.RESULT)
+ || name.equalsIgnoreCase(IRequest.REQUEST_TRUSTEDMGR_PRIVILEGE)) {
+ arg.addStringValue(name, req.getExtDataInString(name));
+ }
+
+ if (name.equalsIgnoreCase(IRequest.REQUESTOR_NAME)) {
+ String requestorName = req.getExtDataInString(name);
+
+ requestorName = requestorName.trim();
+ if (requestorName.length() > 0) {
+ arg.addStringValue(name, requestorName);
+ }
+ }
+
+ if (name.equalsIgnoreCase(IRequest.ERRORS)) {
+ Vector<String> 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.equalsIgnoreCase(IRequest.ERROR)) {
+ arg.addStringValue(IRequest.ERRORS, req.getExtDataInString(name));
+ }
+
+ if (name.equalsIgnoreCase(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.equalsIgnoreCase(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.equalsIgnoreCase(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.equalsIgnoreCase(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/base/common/src/com/netscape/cms/servlet/request/CheckRequest.java b/base/common/src/com/netscape/cms/servlet/request/CheckRequest.java
new file mode 100644
index 000000000..b65c90fca
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/request/CheckRequest.java
@@ -0,0 +1,621 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.math.BigInteger;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.pkcs.PKCS7;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.crypto.DigestAlgorithm;
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+import org.mozilla.jss.pkix.cmc.CMCStatusInfo;
+import org.mozilla.jss.pkix.cmc.PKIData;
+import org.mozilla.jss.pkix.cmc.ResponseBody;
+import org.mozilla.jss.pkix.cmc.TaggedAttribute;
+import org.mozilla.jss.pkix.cms.EncapsulatedContentInfo;
+import org.mozilla.jss.pkix.cms.IssuerAndSerialNumber;
+import org.mozilla.jss.pkix.cms.SignedData;
+import org.mozilla.jss.pkix.cms.SignerIdentifier;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.pkix.primitive.Name;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+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;
+
+/**
+ * Check the status of a certificate request
+ *
+ * @version $Revision$, $Date$
+ */
+public class CheckRequest extends CMSServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2791195859767119636L;
+ // 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, 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)) {
+ // recipient nonce
+ } 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 {
+ new BigInteger(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/base/common/src/com/netscape/cms/servlet/request/IReqParser.java b/base/common/src/com/netscape/cms/servlet/request/IReqParser.java
new file mode 100644
index 000000000..f90e97b70
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/request/IReqParser.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.servlet.request;
+
+import java.util.Locale;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.servlet.common.CMSTemplateParams;
+
+/**
+ * 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/base/common/src/com/netscape/cms/servlet/request/KeyReqParser.java b/base/common/src/com/netscape/cms/servlet/request/KeyReqParser.java
new file mode 100644
index 000000000..b7ddc16d4
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/request/KeyReqParser.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.request;
+
+import java.math.BigInteger;
+import java.util.Locale;
+
+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;
+
+/**
+ * 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/base/common/src/com/netscape/cms/servlet/request/KeyRequestResource.java b/base/common/src/com/netscape/cms/servlet/request/KeyRequestResource.java
new file mode 100644
index 000000000..cd08f46bb
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/request/KeyRequestResource.java
@@ -0,0 +1,69 @@
+package com.netscape.cms.servlet.request;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.cms.servlet.request.model.ArchivalRequestData;
+import com.netscape.cms.servlet.request.model.KeyRequestInfo;
+import com.netscape.cms.servlet.request.model.RecoveryRequestData;
+
+@Path("/keyrequest")
+public interface KeyRequestResource {
+ public final String SYMMETRIC_KEY_TYPE = "symmetricKey";
+ public final String PASS_PHRASE_TYPE = "passPhrase";
+ public final String ASYMMETRIC_KEY_TYPE = "asymmetricKey";
+
+ /**
+ * Used to retrieve key request info for a specific request
+ */
+ @GET
+ @Path("{id}")
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
+ public KeyRequestInfo getRequestInfo(@PathParam("id") RequestId id);
+
+ // Archiving - used to test integration with a browser
+ @POST
+ @Path("archive")
+ @Produces({ MediaType.TEXT_XML })
+ @Consumes({ MediaType.APPLICATION_FORM_URLENCODED})
+ public KeyRequestInfo archiveKey(MultivaluedMap<String, String> form);
+
+ @POST
+ @Path("archive")
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
+ @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ public KeyRequestInfo archiveKey(ArchivalRequestData data);
+
+ //Recovery - used to test integration with a browser
+ @POST
+ @Path("recover")
+ @Produces({ MediaType.TEXT_XML })
+ @Consumes({ MediaType.APPLICATION_FORM_URLENCODED})
+ public KeyRequestInfo recoverKey(MultivaluedMap<String, String> form);
+
+ @POST
+ @Path("recover")
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
+ @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ public KeyRequestInfo recoverKey(RecoveryRequestData data);
+
+ @POST
+ @Path("approve/{id}")
+ public void approveRequest(@PathParam("id") RequestId id);
+
+ @POST
+ @Path("reject/{id}")
+ public void rejectRequest(@PathParam("id") RequestId id);
+
+ @POST
+ @Path("cancel/{id}")
+ public void cancelRequest(@PathParam("id") RequestId id);
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/request/KeyRequestResourceService.java b/base/common/src/com/netscape/cms/servlet/request/KeyRequestResourceService.java
new file mode 100644
index 000000000..43e58bbdc
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/request/KeyRequestResourceService.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) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.cms.servlet.request;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.cms.servlet.base.CMSResourceService;
+import com.netscape.cms.servlet.request.model.ArchivalRequestData;
+import com.netscape.cms.servlet.request.model.KeyRequestDAO;
+import com.netscape.cms.servlet.request.model.KeyRequestInfo;
+import com.netscape.cms.servlet.request.model.RecoveryRequestData;
+
+/**
+ * @author alee
+ *
+ */
+public class KeyRequestResourceService extends CMSResourceService implements KeyRequestResource {
+
+ @Context
+ UriInfo uriInfo;
+
+ /**
+ * Used to retrieve key request info for a specific request
+ */
+ public KeyRequestInfo getRequestInfo(RequestId id) {
+ // auth and authz
+ KeyRequestDAO dao = new KeyRequestDAO();
+ KeyRequestInfo info;
+ try {
+ info = dao.getRequest(id, uriInfo);
+ } catch (EBaseException e) {
+ // log error
+ e.printStackTrace();
+ throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+ }
+ if (info == null) {
+ // request does not exist
+ throw new WebApplicationException(Response.Status.NOT_FOUND);
+ }
+ return info;
+ }
+
+ // Archiving - used to test integration with a browser
+ public KeyRequestInfo archiveKey(MultivaluedMap<String, String> form) {
+ ArchivalRequestData data = new ArchivalRequestData(form);
+ return archiveKey(data);
+ }
+
+ public KeyRequestInfo archiveKey(ArchivalRequestData data) {
+ // auth and authz
+ // Catch this before internal server processing has to deal with it
+
+ if (data == null || data.getClientId() == null
+ || data.getWrappedPrivateData() == null
+ || data.getDataType() == null) {
+ throw new WebApplicationException(Response.Status.BAD_REQUEST);
+ }
+
+ KeyRequestDAO dao = new KeyRequestDAO();
+ KeyRequestInfo info;
+ try {
+ info = dao.submitRequest(data, uriInfo);
+ } catch (EBaseException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+ }
+ return info;
+ }
+
+ //Recovery - used to test integration with a browser
+ public KeyRequestInfo recoverKey(MultivaluedMap<String, String> form) {
+ RecoveryRequestData data = new RecoveryRequestData(form);
+ return recoverKey(data);
+ }
+
+ public KeyRequestInfo recoverKey(RecoveryRequestData data) {
+ // auth and authz
+
+ //Check for entirely illegal data combination here
+ //Catch this before the internal server processing has to deal with it
+ //If data has been provided, we need at least the wrapped session key,
+ //or the command is invalid.
+ if (data == null || (data.getTransWrappedSessionKey() == null
+ && data.getSessionWrappedPassphrase() != null)) {
+ throw new WebApplicationException(Response.Status.BAD_REQUEST);
+ }
+ KeyRequestDAO dao = new KeyRequestDAO();
+ KeyRequestInfo info;
+ try {
+ info = dao.submitRequest(data, uriInfo);
+ } catch (EBaseException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+ }
+ return info;
+ }
+
+ public void approveRequest(RequestId id) {
+ if (id == null) {
+ throw new WebApplicationException(Response.Status.BAD_REQUEST);
+ }
+ // auth and authz
+ KeyRequestDAO dao = new KeyRequestDAO();
+ try {
+ dao.approveRequest(id);
+ } catch (EBaseException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+ }
+ }
+
+ public void rejectRequest(RequestId id) {
+ if (id == null) {
+ throw new WebApplicationException(Response.Status.BAD_REQUEST);
+ }
+ // auth and authz
+ KeyRequestDAO dao = new KeyRequestDAO();
+ try {
+ dao.rejectRequest(id);
+ } catch (EBaseException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+ }
+ }
+
+ public void cancelRequest(RequestId id) {
+ if (id == null) {
+ throw new WebApplicationException(Response.Status.BAD_REQUEST);
+ }
+ // auth and authz
+ KeyRequestDAO dao = new KeyRequestDAO();
+ try {
+ dao.cancelRequest(id);
+ } catch (EBaseException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/request/KeyRequestsResource.java b/base/common/src/com/netscape/cms/servlet/request/KeyRequestsResource.java
new file mode 100644
index 000000000..fd6bc4c27
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/request/KeyRequestsResource.java
@@ -0,0 +1,34 @@
+package com.netscape.cms.servlet.request;
+
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.cms.servlet.request.model.KeyRequestInfos;
+
+@Path("/keyrequests")
+public interface KeyRequestsResource {
+
+ public static final int DEFAULT_START = 0;
+ public static final int DEFAULT_PAGESIZE = 20;
+ public static final int DEFAULT_MAXRESULTS = 100;
+ public static final int DEFAULT_MAXTIME = 10;
+
+ /**
+ * Used to generate list of key requests based on the search parameters
+ */
+ @GET
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
+ public KeyRequestInfos listRequests(@QueryParam("requestState") String requestState,
+ @QueryParam("requestType") String requestType,
+ @QueryParam("clientID") String clientID,
+ @DefaultValue(""+DEFAULT_START) @QueryParam("start") RequestId start,
+ @DefaultValue(""+DEFAULT_PAGESIZE) @QueryParam("pageSize") int pageSize,
+ @DefaultValue(""+DEFAULT_MAXRESULTS) @QueryParam("maxResults") int maxResults,
+ @DefaultValue(""+DEFAULT_MAXTIME) @QueryParam("maxTime") int maxTime);
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/request/KeyRequestsResourceService.java b/base/common/src/com/netscape/cms/servlet/request/KeyRequestsResourceService.java
new file mode 100644
index 000000000..11898ef7a
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/request/KeyRequestsResourceService.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) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.cms.servlet.request;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.cms.servlet.base.CMSResourceService;
+import com.netscape.cms.servlet.request.model.KeyRequestDAO;
+import com.netscape.cms.servlet.request.model.KeyRequestInfos;
+import com.netscape.cmsutil.ldap.LDAPUtil;
+
+/**
+ * @author alee
+ *
+ */
+public class KeyRequestsResourceService extends CMSResourceService implements KeyRequestsResource{
+
+ @Context
+ UriInfo uriInfo;
+
+ /**
+ * Used to generate list of key requests based on the search parameters
+ */
+ public KeyRequestInfos listRequests(String requestState, String requestType, String clientID,
+ RequestId start, int pageSize, int maxResults, int maxTime) {
+ // auth and authz
+
+ // get ldap filter
+ String filter = createSearchFilter(requestState, requestType, clientID);
+ CMS.debug("listRequests: filter is " + filter);
+
+ // get start marker
+ if (start == null) {
+ start = new RequestId(KeyRequestsResource.DEFAULT_START);
+ }
+
+ KeyRequestDAO reqDAO = new KeyRequestDAO();
+ KeyRequestInfos requests;
+ try {
+ requests = reqDAO.listRequests(filter, start, pageSize, maxResults, maxTime, uriInfo);
+ } catch (EBaseException e) {
+ CMS.debug("listRequests: error in obtaining request results" + e);
+ e.printStackTrace();
+ throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+ }
+ return requests;
+ }
+
+ private String createSearchFilter(String requestState, String requestType, String clientID) {
+ String filter = "";
+ int matches = 0;
+
+ if ((requestState == null) && (requestType == null) && (clientID == null)) {
+ filter = "(requeststate=*)";
+ return filter;
+ }
+
+ if (requestState != null) {
+ filter += "(requeststate=" + LDAPUtil.escape(requestState) + ")";
+ matches ++;
+ }
+
+ if (requestType != null) {
+ filter += "(requesttype=" + LDAPUtil.escape(requestType) + ")";
+ matches ++;
+ }
+
+ if (clientID != null) {
+ filter += "(clientID=" + LDAPUtil.escape(clientID) + ")";
+ matches ++;
+ }
+
+ if (matches > 1) {
+ filter = "(&" + filter + ")";
+ }
+
+ return filter;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/request/ProcessCertReq.java b/base/common/src/com/netscape/cms/servlet/request/ProcessCertReq.java
new file mode 100644
index 000000000..820e9a654
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/request/ProcessCertReq.java
@@ -0,0 +1,1933 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.math.BigInteger;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.extensions.NSCertTypeExtension;
+import netscape.security.extensions.PresenceServerExtension;
+import netscape.security.util.DerValue;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.BasicConstraintsExtension;
+import netscape.security.x509.CertificateAlgorithmId;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.Extension;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+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.IAuthority;
+import com.netscape.certsrv.authority.ICertAuthority;
+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.common.Constants;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.usrgrp.IGroup;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.certsrv.usrgrp.IUser;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.cert.ImportCertsTemplateFiller;
+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.cms.servlet.common.ICMSTemplateFiller;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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 static final long serialVersionUID = 812464895240811318L;
+ 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;
+ BigInteger seqNum = BigInteger.ONE.negate();
+ 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;
+ 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 = new BigInteger(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.compareTo(BigInteger.ONE.negate()) > 0) {
+ r = mQueue.findRequest(new RequestId(seqNum));
+ }
+
+ if (seqNum.compareTo(BigInteger.ONE.negate()) > 0 && 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", seqNum.toString()));
+ error = new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_REQUEST_ID",
+ seqNum.toString()));
+ }
+ } 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 {
+ 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,
+ BigInteger 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(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<Extension> extsToBeAdded = new Vector<Extension>();
+
+ byte[] b = Utils.base64decode(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) {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> extraparams = req.getParameterNames();
+ int l = IRequest.AGENT_PARAMS.length() + 1;
+ int ap_counter = 0;
+ Hashtable<String, String> agentparamsargblock = new Hashtable<String, String>();
+
+ if (extraparams != null) {
+ while (extraparams.hasMoreElements()) {
+ String s = 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
+ try {
+ int res = grant_privileges(
+ cmsReq, r, issuedCerts, header);
+
+ if (res != 0) {
+ header.addStringValue(GRANT_ERROR, "SUCCESS");
+ }
+ } catch (EBaseException e) {
+ header.addStringValue(GRANT_ERROR, e.toString());
+ }
+
+ // 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.addBigIntegerValue("seqNum", seqNum, 10);
+ 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 = Utils.base64encode(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/base/common/src/com/netscape/cms/servlet/request/ProcessReq.java b/base/common/src/com/netscape/cms/servlet/request/ProcessReq.java
new file mode 100644
index 000000000..9c173d832
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/request/ProcessReq.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.cms.servlet.request;
+
+import java.io.IOException;
+import java.util.Locale;
+import java.math.BigInteger;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.ICertAuthority;
+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.ca.ICertificateAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+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;
+
+/**
+ * Display Generic Request detail to the user.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ProcessReq extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6941843162486565610L;
+ 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 {
+ BigInteger seqNum = BigInteger.ONE.negate();
+
+ 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;
+ 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 = new BigInteger(req.getParameter(SEQNUM));
+ }
+ doAssign = req.getParameter(DO_ASSIGN);
+
+ if (seqNum.compareTo(BigInteger.ONE.negate()) > 0) {
+ // 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 {
+ 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,
+ BigInteger seqNum, HttpServletRequest req,
+ HttpServletResponse resp,
+ String doAssign, Locale locale)
+ throws EBaseException {
+
+ header.addBigIntegerValue("seqNum", seqNum, 10);
+
+ IRequest r = mQueue.findRequest(new RequestId(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.toString());
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_REQUEST_ID",
+ seqNum.toString()));
+ }
+
+ return;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/request/QueryReq.java b/base/common/src/com/netscape/cms/servlet/request/QueryReq.java
new file mode 100644
index 000000000..f6ae634f4
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/request/QueryReq.java
@@ -0,0 +1,558 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+import java.math.BigInteger;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+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.logging.ILogger;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.IRequestVirtualList;
+import com.netscape.certsrv.request.RequestId;
+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;
+
+/**
+ * Show paged list of requests matching search criteria
+ *
+ * @version $Revision$, $Date$
+ */
+public class QueryReq extends CMSServlet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8729364426329835378L;
+ // 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();
+ }
+
+ BigInteger top = BigInteger.ZERO;
+ BigInteger bottom = BigInteger.ZERO;
+
+ 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";
+
+ if (top_s.trim().startsWith("0x")) {
+ top = new BigInteger(top_s.trim().substring(2), 16);
+ } else {
+ top = new BigInteger(top_s.trim());
+ }
+ if (bottom_s.trim().startsWith("0x")) {
+ bottom = new BigInteger(bottom_s.trim().substring(2), 16);
+ } else {
+ bottom = new BigInteger(bottom_s.trim());
+ }
+
+ } 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;
+ }
+
+ /**
+ * 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, BigInteger top, BigInteger bottom) {
+ CMSTemplateParams ctp = null;
+ if (direction.equals("previous")) {
+ ctp = doSearch(l, filter, -count, top);
+ } else if (direction.equals("next")) {
+ bottom = bottom.add(BigInteger.ONE);
+ ctp = doSearch(l, filter, count, bottom);
+ } else if (direction.equals("begin")) {
+ ctp = doSearch(l, filter, count, BigInteger.ZERO);
+ } else if (direction.equals("first")) {
+ ctp = doSearch(l, filter, count, bottom);
+ } else { // if 'direction is 'end', default here
+ ctp = doSearch(l, filter, -count, BigInteger.ONE.negate());
+ }
+ 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,
+ BigInteger 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.toString().equals("-1")) {
+ marker = BigInteger.ZERO; // I think this is inconsequential
+ jumptoend = true; // override to '99' during search
+ }
+
+ RequestId id = new RequestId(marker);
+ IRequestVirtualList list = mQueue.getPagedRequestsByFilter(
+ id,
+ jumptoend,
+ filter,
+ ((count < 0) ? count - 1 : count + 1),
+ "requestId");
+
+ int maxCount = 0;
+ if (count < 0 && jumptoend) {
+ maxCount = -count;
+ } else if (count < 0) {
+ maxCount = -count + 1;
+ } else {
+ maxCount = count;
+ }
+ int totalCount = (jumptoend) ? maxCount :
+ (list.getSize() - list.getCurrentIndex());
+ header.addIntegerValue(OUT_TOTALCOUNT, totalCount);
+ header.addIntegerValue(OUT_CURRENTCOUNT, list.getSize());
+
+ Vector<IRequest> v = fetchRecords(list, maxCount);
+ v = normalizeOrder(v);
+ trim(v, id);
+
+ int currentCount = 0;
+ BigInteger curNum = BigInteger.ZERO;
+ BigInteger firstNum = BigInteger.ONE.negate();
+ Enumeration<IRequest> requests = v.elements();
+
+ while (requests.hasMoreElements()) {
+ IRequest request = null;
+ try {
+ request = 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 = new BigInteger(request.getRequestId().toString());
+
+ if (firstNum.equals(BigInteger.ONE.negate())) {
+ 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.addBigIntegerValue(OUT_FIRST_ENTRY_ON_PAGE, firstNum, 10);
+ header.addBigIntegerValue(OUT_LAST_ENTRY_ON_PAGE, curNum, 10);
+
+ } 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<IRequest> v, RequestId marker) {
+ int i = v.size() - 1;
+ if (v.elementAt(i).getRequestId().toString().equals(
+ marker.toString())) {
+ 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<IRequest> fetchRecords(IRequestVirtualList list, int maxCount) {
+
+ Vector<IRequest> v = new Vector<IRequest>();
+ 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<IRequest> normalizeOrder(Vector<IRequest> list) {
+
+ BigInteger firstrequestnum = new BigInteger(list.elementAt(0)
+ .getRequestId().toString());
+ BigInteger lastrequestnum = new BigInteger(list.elementAt(list
+ .size() - 1).getRequestId().toString());
+ boolean reverse = false;
+ if (firstrequestnum.compareTo(lastrequestnum) > 0) {
+ reverse = true; // if the order is backwards, place items at the beginning
+ }
+ Vector<IRequest> v = new Vector<IRequest>();
+ int count = list.size();
+ for (int i = 0; i < count; i++) {
+ IRequest request = list.elementAt(i);
+ if (request != null) {
+ if (reverse)
+ v.add(0, request);
+ else
+ v.add(request);
+ }
+ }
+
+ return v;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/request/ReqParser.java b/base/common/src/com/netscape/cms/servlet/request/ReqParser.java
new file mode 100644
index 000000000..230ddb433
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/request/ReqParser.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.cms.servlet.request;
+
+import java.util.Locale;
+import java.math.BigInteger;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.servlet.common.CMSTemplateParams;
+
+/**
+ * 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.addBigIntegerValue("seqNum",
+ new BigInteger(req.getRequestId().toString()), 10);
+ 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/base/common/src/com/netscape/cms/servlet/request/SearchReqs.java b/base/common/src/com/netscape/cms/servlet/request/SearchReqs.java
new file mode 100644
index 000000000..08d5805b6
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/request/SearchReqs.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.servlet.request;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+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.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestList;
+import com.netscape.certsrv.request.IRequestQueue;
+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;
+
+/**
+ * Search for certificates matching complex query filter
+ *
+ * @version $Revision$, $Date$
+ */
+public class SearchReqs extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2449481964851735051L;
+ 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;
+ }
+
+ 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/base/common/src/com/netscape/cms/servlet/request/model/ArchivalRequestData.java b/base/common/src/com/netscape/cms/servlet/request/model/ArchivalRequestData.java
new file mode 100644
index 000000000..8a25c6684
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/request/model/ArchivalRequestData.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) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ *
+ */
+package com.netscape.cms.servlet.request.model;
+
+import javax.ws.rs.core.MultivaluedMap;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * @author alee
+ *
+ */
+@XmlRootElement(name="SecurityDataArchivalRequest")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ArchivalRequestData {
+
+ private static final String CLIENT_ID = "clientID";
+ private static final String TRANS_WRAPPED_SESSION_KEY = "transWrappedSessionKey";
+ private static final String DATA_TYPE = "dataType";
+ private static final String WRAPPED_PRIVATE_DATA = "wrappedPrivateData";
+
+ @XmlElement
+ protected String clientId;
+
+ @XmlElement
+ protected String transWrappedSessionKey;
+
+ @XmlElement
+ protected String dataType;
+
+ @XmlElement
+ protected String wrappedPrivateData;
+
+ public ArchivalRequestData() {
+ // required for JAXB (defaults)
+ }
+
+ public ArchivalRequestData(MultivaluedMap<String, String> form) {
+ clientId = form.getFirst(CLIENT_ID);
+ transWrappedSessionKey = form.getFirst(TRANS_WRAPPED_SESSION_KEY);
+ dataType = form.getFirst(DATA_TYPE);
+ wrappedPrivateData = form.getFirst(WRAPPED_PRIVATE_DATA);
+ }
+
+ /**
+ * @return the clientId
+ */
+ public String getClientId() {
+ return clientId;
+ }
+
+ /**
+ * @param clientId the clientId to set
+ */
+ public void setClientId(String clientId) {
+ this.clientId = clientId;
+ }
+
+ /**
+ * @return the transWrappedSessionKey
+ */
+ public String getTransWrappedSessionKey() {
+ return transWrappedSessionKey;
+ }
+
+ /**
+ * @param transWrappedSessionKey the transWrappedSessionKey to set
+ */
+ public void setTransWrappedSessionKey(String transWrappedSessionKey) {
+ this.transWrappedSessionKey = transWrappedSessionKey;
+ }
+
+ /**
+ * @return the dataType
+ */
+ public String getDataType() {
+ return dataType;
+ }
+
+ /**
+ * @param dataType the dataType to set
+ */
+ public void setDataType(String dataType) {
+ this.dataType = dataType;
+ }
+
+ /**
+ * @return the wrappedPrivateData
+ */
+ public String getWrappedPrivateData() {
+ return wrappedPrivateData;
+ }
+
+ /**
+ * @param wrappedPrivateData the wrappedPrivateData to set
+ */
+ public void setWrappedPrivateData(String wrappedPrivateData) {
+ this.wrappedPrivateData = wrappedPrivateData;
+ }
+
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestDAO.java b/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestDAO.java
new file mode 100644
index 000000000..d1f1a27bd
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestDAO.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) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.request.model;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+
+import javax.ws.rs.Path;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.keydb.KeyId;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestList;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.IRequestVirtualList;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cms.servlet.base.model.Link;
+import com.netscape.cms.servlet.key.KeyResource;
+import com.netscape.cms.servlet.key.model.KeyDAO;
+import com.netscape.cms.servlet.key.model.KeyDataInfos;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.cms.servlet.request.KeyRequestResource;
+
+/**
+ * @author alee
+ *
+ */
+public class KeyRequestDAO {
+ private IRequestQueue queue;
+ private IKeyRecoveryAuthority kra;
+
+ private static String REQUEST_ARCHIVE_OPTIONS = IEnrollProfile.REQUEST_ARCHIVE_OPTIONS;
+
+ private String[] vlvFilters = {
+ "(requeststate=*)", "(requesttype=enrollment)",
+ "(requesttype=recovery)", "(requeststate=canceled)",
+ "(&(requeststate=canceled)(requesttype=enrollment))",
+ "(&(requeststate=canceled)(requesttype=recovery))",
+ "(requeststate=rejected)",
+ "(&(requeststate=rejected)(requesttype=enrollment))",
+ "(&(requeststate=rejected)(requesttype=recovery))",
+ "(requeststate=complete)",
+ "(&(requeststate=complete)(requesttype=enrollment))",
+ "(&(requeststate=complete)(requesttype=recovery))"
+ };
+
+ public static final String ATTR_SERIALNO = "serialNumber";
+
+ public KeyRequestDAO() {
+ kra = ( IKeyRecoveryAuthority ) CMS.getSubsystem( "kra" );
+ queue = kra.getRequestQueue();
+ }
+
+ /**
+ * Finds list of requests matching the specified search filter.
+ *
+ * If the filter corresponds to a VLV search, then that search is executed and the pageSize
+ * and start parameters are used. Otherwise, the maxResults and maxTime parameters are
+ * used in the regularly indexed search.
+ *
+ * @param filter - ldap search filter
+ * @param start - start position for VLV search
+ * @param pageSize - page size for VLV search
+ * @param maxResults - max results to be returned in normal search
+ * @param maxTime - max time for normal search
+ * @param uriInfo - uri context of request
+ * @return collection of key request info
+ * @throws EBaseException
+ */
+ public KeyRequestInfos listRequests(String filter, RequestId start, int pageSize, int maxResults, int maxTime,
+ UriInfo uriInfo) throws EBaseException {
+ List <KeyRequestInfo> list = new ArrayList<KeyRequestInfo>();
+ List <Link> links = new ArrayList<Link>();
+ int totalSize = 0;
+ int current = 0;
+
+ if (isVLVSearch(filter)) {
+ IRequestVirtualList vlvlist = queue.getPagedRequestsByFilter(start, false, filter,
+ pageSize +1 , "requestId");
+ totalSize = vlvlist.getSize();
+ current = vlvlist.getCurrentIndex();
+
+ int numRecords = (totalSize > (current + pageSize)) ? pageSize :
+ totalSize - current;
+
+ for (int i=0; i < numRecords; i++) {
+ IRequest request = vlvlist.getElementAt(i);
+ list.add(createKeyRequestInfo(request, uriInfo));
+ }
+ } else {
+ // The non-vlv requests are indexed, but are not paginated.
+ // We should think about whether they should be, or if we need to
+ // limit the number of results returned.
+ IRequestList requests = queue.listRequestsByFilter(filter, maxResults, maxTime);
+
+ if (requests == null) {
+ return null;
+ }
+ while (requests.hasMoreElements()) {
+ RequestId rid = requests.nextElement();
+ IRequest request = queue.findRequest(rid);
+ if (request != null) {
+ list.add(createKeyRequestInfo(request, uriInfo));
+ }
+ }
+ }
+
+ // builder for vlv links
+ MultivaluedMap<String, String> params = uriInfo.getQueryParameters();
+ UriBuilder builder = uriInfo.getAbsolutePathBuilder();
+ if (params.containsKey("requestState")) {
+ builder.queryParam("requestState", params.getFirst("requestState"));
+ }
+ if (params.containsKey("requestType")) {
+ builder.queryParam("requestType", params.getFirst("requestType"));
+ }
+ builder.queryParam("start", "{start}");
+ builder.queryParam("pageSize", "{pageSize}");
+
+ // next link
+ if (totalSize > current + pageSize) {
+ int next = current + pageSize + 1;
+ URI nextUri = builder.clone().build(next,pageSize);
+ Link nextLink = new Link("next", nextUri.toString(), "application/xml");
+ links.add(nextLink);
+ }
+
+ // previous link
+ if (current >0) {
+ int previous = current - pageSize;
+ URI previousUri = builder.clone().build(previous,pageSize);
+ Link previousLink = new Link("previous", previousUri.toString(), "application/xml");
+ links.add(previousLink);
+ }
+
+ KeyRequestInfos ret = new KeyRequestInfos();
+ ret.setRequests(list);
+ ret.setLinks(links);
+ return ret;
+ }
+
+ /**
+ * Gets info for a specific request
+ * @param id
+ * @return info for specific request
+ * @throws EBaseException
+ */
+ public KeyRequestInfo getRequest(RequestId id, UriInfo uriInfo) throws EBaseException {
+ IRequest request = queue.findRequest(id);
+ if (request == null) {
+ return null;
+ }
+ KeyRequestInfo info = createKeyRequestInfo(request, uriInfo);
+ return info;
+ }
+ /**
+ * Submits an archival request and processes it.
+ * @param data
+ * @return info for the request submitted.
+ * @throws EBaseException
+ */
+ public KeyRequestInfo submitRequest(ArchivalRequestData data, UriInfo uriInfo) throws EBaseException {
+ String clientId = data.getClientId();
+ String wrappedSecurityData = data.getWrappedPrivateData();
+ String dataType = data.getDataType();
+
+ boolean keyExists = doesKeyExist(clientId, "active", uriInfo);
+
+ if (keyExists == true) {
+ throw new EBaseException("Can not archive already active existing key!");
+ }
+
+ IRequest request = queue.newRequest(IRequest.SECURITY_DATA_ENROLLMENT_REQUEST);
+
+ request.setExtData(REQUEST_ARCHIVE_OPTIONS, wrappedSecurityData);
+ request.setExtData(IRequest.SECURITY_DATA_CLIENT_ID, clientId);
+ request.setExtData(IRequest.SECURITY_DATA_TYPE, dataType);
+
+ queue.processRequest(request);
+
+ queue.markAsServiced(request);
+
+ return createKeyRequestInfo(request, uriInfo);
+ }
+ /**
+ * Submits a key recovery request.
+ * @param data
+ * @return info on the recovery request created
+ * @throws EBaseException
+ */
+ public KeyRequestInfo submitRequest(RecoveryRequestData data, UriInfo uriInfo) throws EBaseException {
+
+ // set data using request.setExtData(field, data)
+
+ String wrappedSessionKeyStr = data.getTransWrappedSessionKey();
+ String wrappedPassPhraseStr = data.getSessionWrappedPassphrase();
+ String nonceDataStr = data.getNonceData();
+
+ IRequest request = queue.newRequest(IRequest.SECURITY_DATA_RECOVERY_REQUEST);
+
+ KeyId keyId = data.getKeyId();
+
+ Hashtable<String, Object> requestParams;
+ requestParams = kra.createVolatileRequest(request.getRequestId());
+
+ if(requestParams == null) {
+ throw new EBaseException("Can not create Volatile params in submitRequest!");
+ }
+
+ CMS.debug("Create volatile params for recovery request. " + requestParams);
+
+ if (wrappedPassPhraseStr != null) {
+ requestParams.put(IRequest.SECURITY_DATA_SESS_PASS_PHRASE, wrappedPassPhraseStr);
+ }
+
+ if (wrappedSessionKeyStr != null) {
+ requestParams.put(IRequest.SECURITY_DATA_TRANS_SESS_KEY, wrappedSessionKeyStr);
+ }
+
+ if (nonceDataStr != null) {
+ requestParams.put(IRequest.SECURITY_DATA_IV_STRING_IN, nonceDataStr);
+ }
+
+ request.setExtData(ATTR_SERIALNO, keyId.toString());
+
+ queue.processRequest(request);
+
+ return createKeyRequestInfo(request, uriInfo);
+ }
+
+ public void approveRequest(RequestId id) throws EBaseException {
+ IRequest request = queue.findRequest(id);
+ request.setRequestStatus(RequestStatus.APPROVED);
+ queue.updateRequest(request);
+ }
+
+ public void rejectRequest(RequestId id) throws EBaseException {
+ IRequest request = queue.findRequest(id);
+ request.setRequestStatus(RequestStatus.CANCELED);
+ queue.updateRequest(request);
+ }
+
+ public void cancelRequest(RequestId id) throws EBaseException {
+ IRequest request = queue.findRequest(id);
+ request.setRequestStatus(RequestStatus.REJECTED);
+ queue.updateRequest(request);
+ }
+
+ public KeyRequestInfo createKeyRequestInfo(IRequest request, UriInfo uriInfo) {
+ KeyRequestInfo ret = new KeyRequestInfo();
+
+ ret.setRequestType(request.getRequestType());
+ ret.setRequestStatus(request.getRequestStatus().toString());
+
+ Path keyRequestPath = KeyRequestResource.class.getAnnotation(Path.class);
+ RequestId rid = request.getRequestId();
+
+ UriBuilder reqBuilder = uriInfo.getBaseUriBuilder();
+ reqBuilder.path(keyRequestPath.value() + "/" + rid);
+ ret.setRequestURL(reqBuilder.build().toString());
+
+ Path keyPath = KeyResource.class.getAnnotation(Path.class);
+ String kid = request.getExtDataInString("keyrecord");
+
+ UriBuilder keyBuilder = uriInfo.getBaseUriBuilder();
+ keyBuilder.path(keyPath.value() + "/" + kid);
+ ret.setKeyURL(keyBuilder.build().toString());
+
+ return ret;
+ }
+
+ private boolean isVLVSearch(String filter) {
+ for (int i=0; i < vlvFilters.length; i++) {
+ if (vlvFilters[i].equalsIgnoreCase(filter)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ //We only care if the key exists or not
+ private boolean doesKeyExist(String clientId, String keyStatus, UriInfo uriInfo) {
+ boolean ret = false;
+ String state = "active";
+
+ KeyDAO keys = new KeyDAO();
+
+ KeyDataInfos existingKeys;
+ String filter = "(&(" + IRequest.SECURITY_DATA_CLIENT_ID + "=" + clientId + ")"
+ + "(" + IRequest.SECURITY_DATA_STATUS + "=" + state + "))";
+ try {
+ existingKeys = keys.listKeys(filter, 1, 10, uriInfo);
+
+ if(existingKeys != null && existingKeys.getKeyInfos().size() > 0) {
+ ret = true;
+ }
+ } catch (EBaseException e) {
+ ret= false;
+ }
+
+ return ret;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestInfo.java b/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestInfo.java
new file mode 100644
index 000000000..f07c302dd
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestInfo.java
@@ -0,0 +1,120 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.cms.servlet.request.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+
+import com.netscape.certsrv.dbs.keydb.KeyId;
+import com.netscape.certsrv.request.RequestId;
+
+@XmlRootElement(name="SecurityDataRequestInfo")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class KeyRequestInfo {
+
+ @XmlElement
+ protected String requestType;
+
+ @XmlElement
+ protected String requestStatus;
+
+ @XmlElement
+ protected String requestURL;
+
+ @XmlElement
+ protected String keyURL;
+
+ public KeyRequestInfo(){
+ // required to be here for JAXB (defaults)
+ }
+
+ /**
+ * @return the requestType
+ */
+ public String getRequestType() {
+ return requestType;
+ }
+
+ /**
+ * @param requestType the requestType to set
+ */
+ public void setRequestType(String requestType) {
+ this.requestType = requestType;
+ }
+
+ /**
+ * @return the requestStatus
+ */
+ public String getRequestStatus() {
+ return requestStatus;
+ }
+
+ /**
+ * @param requestStatus the requestStatus to set
+ */
+ public void setRequestStatus(String requestStatus) {
+ this.requestStatus = requestStatus;
+ }
+
+ /**
+ * @return the requestURL
+ */
+ public String getRequestURL() {
+ return requestURL;
+ }
+
+ /**
+ * @return the request ID in the requestURL
+ */
+ public RequestId getRequestId() {
+ String id = requestURL.substring(requestURL.lastIndexOf("/") + 1);
+ return new RequestId(id);
+ }
+
+ /**
+ * @param requestURL the requestURL to set
+ */
+ public void setRequestURL(String requestURL) {
+ this.requestURL = requestURL;
+ }
+
+ /**
+ * @return the keyURL
+ */
+ public String getKeyURL() {
+ return keyURL;
+ }
+
+ /**
+ * @return the key ID in the keyURL
+ */
+ public KeyId getKeyId() {
+ String id = keyURL.substring(keyURL.lastIndexOf("/") + 1);
+ return new KeyId(id);
+ }
+
+ /**
+ * @param keyURL the keyURL to set
+ */
+ public void setKeyURL(String keyURL) {
+ this.keyURL = keyURL;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestInfos.java b/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestInfos.java
new file mode 100644
index 000000000..dc1b6a5e4
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestInfos.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) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.request.model;
+
+import java.util.Collection;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlElementRef;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import com.netscape.cms.servlet.base.model.Link;
+
+@XmlRootElement(name = "SecurityDataRequestInfos")
+public class KeyRequestInfos {
+ protected Collection<KeyRequestInfo> requests;
+ protected List<Link> links;
+
+ /**
+ * @return the requests
+ */
+ @XmlElementRef
+ public Collection<KeyRequestInfo> getRequests() {
+ return requests;
+ }
+
+ /**
+ * @param requests the requests to set
+ */
+ public void setRequests(Collection<KeyRequestInfo> requests) {
+ this.requests = requests;
+ }
+
+ /**
+ * @return the links
+ */
+ @XmlElementRef
+ public List<Link> getLinks() {
+ return links;
+ }
+
+ /**
+ * @param links the links to set
+ */
+ public void setLinks(List<Link> links) {
+ this.links = links;
+ }
+
+ @XmlTransient
+ public String getNext() {
+ if (links == null) {
+ return null;
+ }
+ for (Link link : links) {
+ if ("next".equals(link.getRelationship())) {
+ return link.getHref();
+ }
+ }
+ return null;
+ }
+
+ @XmlTransient
+ public String getPrevious() {
+ if (links == null) {
+ return null;
+ }
+ for (Link link : links) {
+ if ("previous".equals(link.getRelationship())) {
+ return link.getHref();
+ }
+ }
+ return null;
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/request/model/RecoveryRequestData.java b/base/common/src/com/netscape/cms/servlet/request/model/RecoveryRequestData.java
new file mode 100644
index 000000000..80ec6d127
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/request/model/RecoveryRequestData.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) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ *
+ */
+package com.netscape.cms.servlet.request.model;
+
+import javax.ws.rs.core.MultivaluedMap;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
+import com.netscape.certsrv.dbs.keydb.KeyId;
+import com.netscape.certsrv.dbs.keydb.KeyIdAdapter;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestIdAdapter;
+
+/**
+ * @author alee
+ *
+ */
+@XmlRootElement(name="SecurityDataRecoveryRequest")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class RecoveryRequestData {
+
+ private static final String KEY_ID = "keyId";
+ private static final String REQUEST_ID = "requestId";
+ private static final String TRANS_WRAPPED_SESSION_KEY = "transWrappedSessionKey";
+ private static final String SESSION_WRAPPED_PASSPHRASE = "sessionWrappedPassphrase";
+ private static final String NONCE_DATA = "nonceData";
+
+ @XmlElement
+ @XmlJavaTypeAdapter(KeyIdAdapter.class)
+ protected KeyId keyId;
+
+ @XmlElement
+ @XmlJavaTypeAdapter(RequestIdAdapter.class)
+ protected RequestId requestId;
+
+ @XmlElement
+ protected String transWrappedSessionKey;
+
+ @XmlElement
+ protected String sessionWrappedPassphrase;
+
+ @XmlElement
+ protected String nonceData;
+
+ public RecoveryRequestData() {
+ // required for JAXB (defaults)
+ }
+
+ public RecoveryRequestData(MultivaluedMap<String, String> form) {
+ if (form.containsKey(KEY_ID)) {
+ keyId = new KeyId(form.getFirst(KEY_ID));
+ }
+ if (form.containsKey(REQUEST_ID)) {
+ requestId = new RequestId(form.getFirst(REQUEST_ID));
+ }
+ transWrappedSessionKey = form.getFirst(TRANS_WRAPPED_SESSION_KEY);
+ sessionWrappedPassphrase = form.getFirst(SESSION_WRAPPED_PASSPHRASE);
+ nonceData = form.getFirst(NONCE_DATA);
+ }
+
+ /**
+ * @return the keyId
+ */
+ public KeyId getKeyId() {
+ return keyId;
+ }
+
+ /**
+ * @param keyId the keyId to set
+ */
+ public void setKeyId(KeyId keyId) {
+ this.keyId = keyId;
+ }
+
+ /**
+ * @return the requestId
+ */
+ public RequestId getRequestId() {
+ return requestId;
+ }
+
+ /**
+ * @param requestId the requestId to set
+ */
+ public void setRequestId(RequestId requestId) {
+ this.requestId = requestId;
+ }
+
+ /**
+ * @return the transWrappedSessionKey
+ */
+ public String getTransWrappedSessionKey() {
+ return transWrappedSessionKey;
+ }
+
+ /**
+ * @param transWrappedSessionKey the transWrappedSessionKey to set
+ */
+ public void setTransWrappedSessionKey(String transWrappedSessionKey) {
+ this.transWrappedSessionKey = transWrappedSessionKey;
+ }
+
+ /**
+ * @return the sessionWrappedPassphrase
+ */
+ public String getSessionWrappedPassphrase() {
+ return sessionWrappedPassphrase;
+ }
+
+ /**
+ * @param sessionWrappedPassphrase the sessionWrappedPassphrase to set
+ */
+ public void setSessionWrappedPassphrase(String sessionWrappedPassphrase) {
+ this.sessionWrappedPassphrase = sessionWrappedPassphrase;
+ }
+
+ /**
+ * @return nonceData
+ */
+
+ public String getNonceData() {
+ return nonceData;
+ }
+
+ /**
+ * @param nonceData the nonceData to set
+ */
+
+ public void setNonceData(String nonceData) {
+ this.nonceData = nonceData;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/tks/TokenServlet.java b/base/common/src/com/netscape/cms/servlet/tks/TokenServlet.java
new file mode 100644
index 000000000..c96a30a85
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/tks/TokenServlet.java
@@ -0,0 +1,1340 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.KeyWrapAlgorithm;
+import org.mozilla.jss.crypto.KeyWrapper;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.pkcs11.PK11SymKey;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IPrettyPrintFormat;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.tks.ITKSAuthority;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.symkey.SessionKey;
+
+/**
+ * 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 {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8687436109695172791L;
+ protected static final String PROP_ENABLED = "enabled";
+ protected static final String TRANSPORT_KEY_NAME = "sharedSecret";
+ 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 transportKeyName = "";
+
+ 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;
+ PK11SymKey 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) {
+ }
+
+ try {
+ transportKeyName = sconfig.getString("tks.tksSharedSymKeyName", TRANSPORT_KEY_NAME);
+ } catch (EBaseException e) {
+ }
+
+ CMS.debug("TokenServlet: ComputeSessionKey(): tksSharedSymKeyName: " + transportKeyName);
+
+ 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, keySet, transportKeyName);
+
+ 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, keySet);
+
+ 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, keySet);
+
+ 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);
+ /*
+ 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);
+ /*
+ 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(selectedToken);
+ token = CryptoManager.getInstance().getInternalCryptoToken();
+ } 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);
+ }
+ CMS.debug("desKey token " + desKey.getOwningToken().getName() + " token: " + token.getName());
+ 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, keySet);
+
+ 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, keySet);
+
+ 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, 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;
+ 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, keySet);
+
+ 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");
+ } // ! 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, keySet);
+
+ 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) {
+ // 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 {
+ super.service(req, resp);
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/wizard/IWizardPanel.java b/base/common/src/com/netscape/cms/servlet/wizard/IWizardPanel.java
new file mode 100644
index 000000000..d9d3ddec7
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/wizard/IWizardPanel.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.wizard;
+
+import java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.context.Context;
+
+import com.netscape.certsrv.property.PropertySet;
+
+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/base/common/src/com/netscape/cms/servlet/wizard/WizardServlet.java b/base/common/src/com/netscape/cms/servlet/wizard/WizardServlet.java
new file mode 100644
index 000000000..42fa88cd9
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/wizard/WizardServlet.java
@@ -0,0 +1,489 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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 java.io.IOException;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+import org.apache.velocity.servlet.VelocityServlet;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.cms.servlet.csadmin.Cert;
+import com.netscape.cmsutil.crypto.Module;
+
+/**
+ * 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 static final long serialVersionUID = -4513510177445656799L;
+ private String name = null;
+ private Vector<IWizardPanel> mPanels = new Vector<IWizardPanel>();
+
+ 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<IWizardPanel> e = mPanels.elements();
+ Vector<IWizardPanel> panels = new Vector<IWizardPanel>();
+ 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 = 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 = 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 = mPanels.elementAt(p);
+ return wp.getId();
+ }
+
+ public IWizardPanel getPreviousPanel(int p) {
+ CMS.debug("getPreviousPanel input p=" + p);
+ IWizardPanel backpanel = mPanels.elementAt(p - 1);
+ if (backpanel.isSubPanel()) {
+ backpanel = mPanels.elementAt(p - 1 - 1);
+ }
+ while (backpanel.shouldSkip()) {
+ backpanel = 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 = 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 = 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());
+ @SuppressWarnings("unchecked")
+ Enumeration<String> paramNames = httpReq.getParameterNames();
+ while (paramNames.hasMoreElements()) {
+ String pn = 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/base/common/src/com/netscape/cms/shares/OldJoinShares.java b/base/common/src/com/netscape/cms/shares/OldJoinShares.java
new file mode 100644
index 000000000..f01e1e1c3
--- /dev/null
+++ b/base/common/src/com/netscape/cms/shares/OldJoinShares.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.shares;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+import com.netscape.certsrv.kra.IJoinShares;
+
+/**
+ * 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/base/common/src/com/netscape/cms/shares/OldShare.java b/base/common/src/com/netscape/cms/shares/OldShare.java
new file mode 100644
index 000000000..4020e759e
--- /dev/null
+++ b/base/common/src/com/netscape/cms/shares/OldShare.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.cms.shares;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+import com.netscape.certsrv.kra.IShare;
+
+/**
+ * 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<?> 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/base/common/src/com/netscape/cmscore/apps/CMSEngine.java b/base/common/src/com/netscape/cmscore/apps/CMSEngine.java
new file mode 100644
index 000000000..e1981132d
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/apps/CMSEngine.java
@@ -0,0 +1,2003 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.text.MessageFormat;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.StringTokenizer;
+import java.util.Timer;
+import java.util.Vector;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSSLSocketFactoryExt;
+import netscape.security.extensions.CertInfo;
+import netscape.security.pkcs.ContentInfo;
+import netscape.security.pkcs.PKCS7;
+import netscape.security.pkcs.SignerInfo;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.Extension;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.X509CRLImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import org.apache.xerces.parsers.DOMParser;
+import org.mozilla.jss.CryptoManager.CertificateUsage;
+import org.mozilla.jss.util.PasswordCallback;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import com.netscape.certsrv.acls.ACL;
+import com.netscape.certsrv.acls.ACLEntry;
+import com.netscape.certsrv.acls.EACLsException;
+import com.netscape.certsrv.acls.IACL;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.apps.ICMSEngine;
+import com.netscape.certsrv.apps.ICommandQueue;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.ICRLPrettyPrint;
+import com.netscape.certsrv.base.ICertPrettyPrint;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtPrettyPrint;
+import com.netscape.certsrv.base.IPrettyPrintFormat;
+import com.netscape.certsrv.base.ISecurityDomainSessionTable;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.base.ITimeSource;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.connector.IHttpConnection;
+import com.netscape.certsrv.connector.IPKIMessage;
+import com.netscape.certsrv.connector.IRemoteAuthority;
+import com.netscape.certsrv.connector.IRequestEncoder;
+import com.netscape.certsrv.connector.IResender;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.dbs.repository.IRepositoryRecord;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ILdapAuthInfo;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.ldap.ILdapConnInfo;
+import com.netscape.certsrv.logging.ELogException;
+import com.netscape.certsrv.logging.ILogEvent;
+import com.netscape.certsrv.logging.ILogEventListener;
+import com.netscape.certsrv.logging.ILogQueue;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.notification.IEmailFormProcessor;
+import com.netscape.certsrv.notification.IEmailResolver;
+import com.netscape.certsrv.notification.IEmailResolverKeys;
+import com.netscape.certsrv.notification.IEmailTemplate;
+import com.netscape.certsrv.notification.IMailNotification;
+import com.netscape.certsrv.password.IPasswordCheck;
+import com.netscape.certsrv.policy.IGeneralNameAsConstraintsConfig;
+import com.netscape.certsrv.policy.IGeneralNamesAsConstraintsConfig;
+import com.netscape.certsrv.policy.IGeneralNamesConfig;
+import com.netscape.certsrv.policy.ISubjAltNameConfig;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.csadmin.LDAPSecurityDomainSessionTable;
+import com.netscape.cms.servlet.csadmin.SecurityDomainSessionTable;
+import com.netscape.cms.servlet.csadmin.SessionTimer;
+import com.netscape.cmscore.authentication.AuthSubsystem;
+import com.netscape.cmscore.authentication.VerifiedCert;
+import com.netscape.cmscore.authentication.VerifiedCerts;
+import com.netscape.cmscore.authorization.AuthzSubsystem;
+import com.netscape.cmscore.base.ArgBlock;
+import com.netscape.cmscore.base.FileConfigStore;
+import com.netscape.cmscore.base.SubsystemRegistry;
+import com.netscape.cmscore.cert.CertPrettyPrint;
+import com.netscape.cmscore.cert.CertUtils;
+import com.netscape.cmscore.cert.CrlCachePrettyPrint;
+import com.netscape.cmscore.cert.CrlPrettyPrint;
+import com.netscape.cmscore.cert.ExtPrettyPrint;
+import com.netscape.cmscore.cert.OidLoaderSubsystem;
+import com.netscape.cmscore.cert.X500NameSubsystem;
+import com.netscape.cmscore.connector.HttpConnection;
+import com.netscape.cmscore.connector.HttpPKIMessage;
+import com.netscape.cmscore.connector.HttpRequestEncoder;
+import com.netscape.cmscore.connector.Resender;
+import com.netscape.cmscore.dbs.CRLIssuingPointRecord;
+import com.netscape.cmscore.dbs.CertificateRepository;
+import com.netscape.cmscore.dbs.DBSubsystem;
+import com.netscape.cmscore.dbs.RepositoryRecord;
+import com.netscape.cmscore.jobs.JobsScheduler;
+import com.netscape.cmscore.ldapconn.LdapAnonConnFactory;
+import com.netscape.cmscore.ldapconn.LdapAuthInfo;
+import com.netscape.cmscore.ldapconn.LdapBoundConnFactory;
+import com.netscape.cmscore.ldapconn.LdapBoundConnection;
+import com.netscape.cmscore.ldapconn.LdapConnInfo;
+import com.netscape.cmscore.ldapconn.LdapJssSSLSocketFactory;
+import com.netscape.cmscore.logging.LogSubsystem;
+import com.netscape.cmscore.logging.Logger;
+import com.netscape.cmscore.logging.SignedAuditLogger;
+import com.netscape.cmscore.notification.EmailFormProcessor;
+import com.netscape.cmscore.notification.EmailResolverKeys;
+import com.netscape.cmscore.notification.EmailTemplate;
+import com.netscape.cmscore.notification.ReqCertSANameEmailResolver;
+import com.netscape.cmscore.policy.GeneralNameUtil;
+import com.netscape.cmscore.registry.PluginRegistry;
+import com.netscape.cmscore.request.CertRequestConstants;
+import com.netscape.cmscore.request.RequestSubsystem;
+import com.netscape.cmscore.security.JssSubsystem;
+import com.netscape.cmscore.security.PWCBsdr;
+import com.netscape.cmscore.security.PWsdrCache;
+import com.netscape.cmscore.time.SimpleTimeSource;
+import com.netscape.cmscore.usrgrp.UGSubsystem;
+import com.netscape.cmscore.util.Debug;
+import com.netscape.cmsutil.net.ISocketFactory;
+import com.netscape.cmsutil.password.IPasswordStore;
+import com.netscape.cmsutil.util.Utils;
+
+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 String instanceDir; /* path to instance <server-root>/cert-<instance-name> */
+ private String instanceId;
+ private int pid;
+
+ 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(
+ 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() {
+
+ // Shutdown on SIGINT, SIGTERM, or SIGHUP.
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ public void run() {
+ /*LogDoc
+ *
+ * @phase watchdog check
+ */
+ getLogger().log(ILogger.EV_SYSTEM,
+ ILogger.S_OTHER,
+ ILogger.LL_INFO,
+ "OS: Received shutdown signal");
+
+ shutdown();
+ };
+ });
+ }
+
+ /**
+ * 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 ((state == 1) && (!sd.equals("existing"))) {
+ // check session domain table only if this is a
+ // configured security domain host
+
+ 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);
+
+ 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");
+ instanceId = config.getString("instanceId");
+
+ 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<String> 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<String>();
+ 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, ";");
+
+ 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<String, String> httpReq) {
+ return new ArgBlock(httpReq);
+ }
+
+ public IArgBlock createArgBlock(String realm, Hashtable<String, String> 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<String> getSubsystemNames() {
+ return mSSReg.keys();
+ }
+
+ public Enumeration<ISubsystem> 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<String> 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 {
+ 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;
+ }
+
+ 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<String> params) {
+ GeneralNameUtil.SubjAltNameGN.getDefaultParams(name, params);
+ }
+
+ public void getSubjAltNameConfigExtendedPluginInfo(String name,
+ Vector<String> 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<String> params) {
+ GeneralNameUtil.GeneralNameConfig.getDefaultParams(name, isValueConfigured, params);
+ }
+
+ public void getGeneralNamesConfigDefaultParams(String name,
+ boolean isValueConfigured, Vector<String> params) {
+ GeneralNameUtil.GeneralNamesConfig.getDefaultParams(name, isValueConfigured, params);
+ }
+
+ public void getGeneralNameConfigExtendedPluginInfo(String name,
+ boolean isValueConfigured, Vector<String> info) {
+ GeneralNameUtil.GeneralNameConfig.getExtendedPluginInfo(name, isValueConfigured, info);
+ }
+
+ public void getGeneralNamesConfigExtendedPluginInfo(String name,
+ boolean isValueConfigured, Vector<String> 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 Utils.base64encode(data);
+ }
+
+ public byte[] AtoB(String data) {
+ return Utils.base64decode(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() {
+ Enumeration<CMSRequest> 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 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();
+
+ } 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);
+ }
+
+ /**
+ * 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.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() {
+ if (pid != 0) return pid;
+
+ BufferedReader bf = null;
+ try {
+ // PID file is be created by wrapper script (e.g. /usr/sbin/tomcat6)
+ String dir = mConfig.getString("pidDir");
+ String name = dir+File.separator+instanceId+".pid";
+
+ if (dir == null) return pid;
+ File file = new File(name);
+ if (!file.exists()) return pid;
+
+ bf = new BufferedReader(new FileReader(file));
+ String value = bf.readLine();
+ pid = Integer.parseInt(value);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+
+ } finally {
+ if (bf != null) try { bf.close(); } catch (Exception e) { e.printStackTrace(); }
+ }
+
+ return pid;
+ }
+
+ 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<String> enum1 = checkRevReq.getExtDataKeys();
+
+ while (enum1.hasMoreElements()) {
+ String name = 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<String, String> req) throws ServletException,
+ IOException, EBaseException {
+ return null;
+ }
+
+ /**
+ * Retrieve log file list.
+ */
+ public synchronized NameValuePairs retrieveLogList(Hashtable<String, String> req) throws ServletException,
+ IOException, EBaseException {
+ return null;
+ }
+
+ public String getImplName() {
+ return "ConsoleLog";
+ }
+
+ public String getDescription() {
+ return "ConsoleLog";
+ }
+
+ public Vector<String> getDefaultParams() {
+ Vector<String> v = new Vector<String>();
+
+ return v;
+ }
+
+ public Vector<String> getInstanceParams() {
+ Vector<String> v = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cmscore/apps/CommandQueue.java b/base/common/src/com/netscape/cmscore/apps/CommandQueue.java
new file mode 100644
index 000000000..6604fea5b
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/apps/CommandQueue.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.cmscore.apps;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import javax.servlet.Servlet;
+
+import com.netscape.certsrv.apps.ICommandQueue;
+import com.netscape.cms.servlet.common.CMSRequest;
+
+/*---------------------------------------------------------------
+ ** CommandQueue - Class
+ */
+
+/**
+ * register and unregister proccess for clean shutdown
+ */
+public class CommandQueue implements Runnable, ICommandQueue {
+
+ public static Hashtable<CMSRequest, Servlet> mCommandQueue = new Hashtable<CMSRequest, Servlet>();
+ 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.sleep(5 * 1000);
+ //gcProcess();
+ } catch (Exception e) {
+
+ }
+ }
+ } // run
+
+ public boolean registerProcess(CMSRequest currentRequest, Servlet 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) {
+ Enumeration<CMSRequest> 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/base/common/src/com/netscape/cmscore/apps/PKIServerEvent.java b/base/common/src/com/netscape/cmscore/apps/PKIServerEvent.java
new file mode 100644
index 000000000..e815a9940
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/apps/PKIServerEvent.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.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/base/common/src/com/netscape/cmscore/apps/PKIServerListener.java b/base/common/src/com/netscape/cmscore/apps/PKIServerListener.java
new file mode 100644
index 000000000..bef70ce86
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/apps/PKIServerListener.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.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/base/common/src/com/netscape/cmscore/apps/Setup.java b/base/common/src/com/netscape/cmscore/apps/Setup.java
new file mode 100644
index 000000000..3486ec40e
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/apps/Setup.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.apps;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/apps/Upgrade.java b/base/common/src/com/netscape/cmscore/apps/Upgrade.java
new file mode 100644
index 000000000..cd5b2991f
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/apps/Upgrade.java
@@ -0,0 +1,329 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.cmsutil.util.Utils;
+
+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 (Utils.isNT()) {
+ 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;
+
+ // 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;
+ }
+
+ 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/base/common/src/com/netscape/cmscore/authentication/AuthSubsystem.java b/base/common/src/com/netscape/cmscore/authentication/AuthSubsystem.java
new file mode 100644
index 000000000..64a09173f
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/authentication/AuthSubsystem.java
@@ -0,0 +1,515 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthManagerProxy;
+import com.netscape.certsrv.authentication.AuthMgrPlugin;
+import com.netscape.certsrv.authentication.EAuthException;
+import com.netscape.certsrv.authentication.EAuthMgrNotFound;
+import com.netscape.certsrv.authentication.EAuthMgrPluginNotFound;
+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.IAuthSubsystem;
+import com.netscape.certsrv.authentication.IAuthToken;
+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.cmscore.util.Debug;
+
+/**
+ * Default authentication subsystem
+ * <P>
+ *
+ * @author cfu
+ * @author lhsiao
+ * @version $Revision$, $Date$
+ */
+public class AuthSubsystem implements IAuthSubsystem {
+ public static final String ID = "auths";
+
+ public Hashtable<String, AuthMgrPlugin> mAuthMgrPlugins = new Hashtable<String, AuthMgrPlugin>();
+ public Hashtable<String, AuthManagerProxy> mAuthMgrInsts = new Hashtable<String, AuthManagerProxy>();
+ 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<String> 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<String> 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<IAuthManager> getAuthManagers() {
+ Vector<IAuthManager> inst = new Vector<IAuthManager>();
+ Enumeration<String> e = mAuthMgrInsts.keys();
+
+ while (e.hasMoreElements()) {
+ IAuthManager p = get(e.nextElement());
+
+ if (p != null) {
+ inst.addElement(p);
+ }
+ }
+ return (inst.elements());
+ }
+
+ /**
+ * Enumerate all registered authentication manager plugins.
+ */
+ public Enumeration<AuthMgrPlugin> 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<String> 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<String, AuthMgrPlugin> getPlugins() {
+ return mAuthMgrPlugins;
+ }
+
+ public Hashtable<String, AuthManagerProxy> 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/base/common/src/com/netscape/cmscore/authentication/CertUserDBAuthentication.java b/base/common/src/com/netscape/cmscore/authentication/CertUserDBAuthentication.java
new file mode 100644
index 000000000..84807430f
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/authentication/CertUserDBAuthentication.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.cmscore.authentication;
+
+import java.security.cert.X509Certificate;
+
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+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.IConfigStore;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.usrgrp.Certificates;
+import com.netscape.certsrv.usrgrp.EUsrGrpException;
+import com.netscape.certsrv.usrgrp.ICertUserLocator;
+import com.netscape.cmscore.usrgrp.ExactMatchCertUserLocator;
+import com.netscape.cmscore.usrgrp.User;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/authentication/ChallengePhraseAuthentication.java b/base/common/src/com/netscape/cmscore/authentication/ChallengePhraseAuthentication.java
new file mode 100644
index 000000000..a7d5329c0
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/authentication/ChallengePhraseAuthentication.java
@@ -0,0 +1,411 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.EAuthException;
+import com.netscape.certsrv.authentication.EAuthUserError;
+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.IConfigStore;
+import com.netscape.certsrv.base.MetaInfo;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.usrgrp.ICertUserLocator;
+import com.netscape.cmscore.base.SubsystemRegistry;
+import com.netscape.cmscore.dbs.CertRecord;
+import com.netscape.cmscore.dbs.CertificateRepository;
+import com.netscape.cmscore.util.Debug;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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 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();
+ }
+ */
+
+ 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 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 = Utils.base64encode(pwdDigest);
+
+ return "{SHA}" + b64E;
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/authentication/NullAuthentication.java b/base/common/src/com/netscape/cmscore/authentication/NullAuthentication.java
new file mode 100644
index 000000000..e124f1407
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/authentication/NullAuthentication.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 com.netscape.certsrv.apps.CMS;
+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.IConfigStore;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/authentication/PasswdUserDBAuthentication.java b/base/common/src/com/netscape/cmscore/authentication/PasswdUserDBAuthentication.java
new file mode 100644
index 000000000..f20bd5f07
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/authentication/PasswdUserDBAuthentication.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.cmscore.authentication;
+
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+
+import com.netscape.certsrv.apps.CMS;
+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.IConfigStore;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.usrgrp.IUser;
+import com.netscape.cmscore.dbs.DBSubsystem;
+import com.netscape.cmscore.ldapconn.LdapAnonConnFactory;
+import com.netscape.cmscore.ldapconn.LdapBoundConnFactory;
+import com.netscape.cmscore.ldapconn.LdapConnInfo;
+import com.netscape.cmscore.usrgrp.UGSubsystem;
+import com.netscape.cmscore.util.Debug;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/authentication/SSLClientCertAuthentication.java b/base/common/src/com/netscape/cmscore/authentication/SSLClientCertAuthentication.java
new file mode 100644
index 000000000..3f0d7a87b
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/authentication/SSLClientCertAuthentication.java
@@ -0,0 +1,291 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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 java.math.BigInteger;
+import java.security.Principal;
+import java.security.cert.X509Certificate;
+
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.EAuthUserError;
+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.IConfigStore;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ra.IRegistrationAuthority;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cmscore.util.Debug;
+
+/**
+ * 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();
+
+ 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/base/common/src/com/netscape/cmscore/authentication/VerifiedCert.java b/base/common/src/com/netscape/cmscore/authentication/VerifiedCert.java
new file mode 100644
index 000000000..173d69f89
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/authentication/VerifiedCert.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.cmscore.authentication;
+
+import java.math.BigInteger;
+import java.util.Date;
+
+import com.netscape.certsrv.apps.CMS;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/authentication/VerifiedCerts.java b/base/common/src/com/netscape/cmscore/authentication/VerifiedCerts.java
new file mode 100644
index 000000000..52ce91fdf
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/authentication/VerifiedCerts.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.cmscore.authentication;
+
+import java.math.BigInteger;
+
+import netscape.security.x509.X509CertImpl;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/authorization/AuthzSubsystem.java b/base/common/src/com/netscape/cmscore/authorization/AuthzSubsystem.java
new file mode 100644
index 000000000..16bc40e29
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/authorization/AuthzSubsystem.java
@@ -0,0 +1,474 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzManagerProxy;
+import com.netscape.certsrv.authorization.AuthzMgrPlugin;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzException;
+import com.netscape.certsrv.authorization.EAuthzMgrNotFound;
+import com.netscape.certsrv.authorization.EAuthzMgrPluginNotFound;
+import com.netscape.certsrv.authorization.IAuthzManager;
+import com.netscape.certsrv.authorization.IAuthzSubsystem;
+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.cmscore.util.Debug;
+
+/**
+ * Default authorization subsystem
+ * <P>
+ *
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class AuthzSubsystem implements IAuthzSubsystem {
+ public static final String ID = "authz";
+
+ public Hashtable<String, AuthzMgrPlugin> mAuthzMgrPlugins = new Hashtable<String, AuthzMgrPlugin>();
+ public Hashtable<String, AuthzManagerProxy> mAuthzMgrInsts = new Hashtable<String, AuthzManagerProxy>();
+ 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<String> 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<String> 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<IAuthzManager> getAuthzManagers() {
+ Vector<IAuthzManager> inst = new Vector<IAuthzManager>();
+ Enumeration<String> 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<AuthzMgrPlugin> 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<String> 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<String, AuthzMgrPlugin> getPlugins() {
+ return mAuthzMgrPlugins;
+ }
+
+ public Hashtable<String, AuthzManagerProxy> 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/base/common/src/com/netscape/cmscore/base/ArgBlock.java b/base/common/src/com/netscape/cmscore/base/ArgBlock.java
new file mode 100644
index 000000000..62b5971a4
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/base/ArgBlock.java
@@ -0,0 +1,717 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.IOException;
+import java.math.BigInteger;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.SignatureException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+
+import netscape.security.pkcs.PKCS10;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.KeyGenInfo;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6054531129316353282L;
+ /*==========================================================
+ * 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<String, Object> mArgs = new Hashtable<String, Object>();
+
+ 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<String, String> httpReq) {
+ mType = realm;
+ populate(httpReq);
+ }
+
+ /**
+ * Constructs an argument block with the given hashtable values.
+ *
+ * @param httpReq hashtable keys and values
+ */
+ public ArgBlock(Hashtable<String, String> httpReq) {
+ populate(httpReq);
+ }
+
+ private void populate(Hashtable<String, String> httpReq) {
+ // Add all parameters from the request
+ Enumeration<String> e = httpReq.keys();
+
+ if (e != null) {
+ while (e.hasMoreElements()) {
+ String name = e.nextElement();
+ String value = 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<String> getElements() {
+ return mArgs.keys();
+ }
+
+ /**
+ * Retrieves a list of argument keys.
+ *
+ * @return a list of string-based keys
+ */
+ public Enumeration<String> 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 = Utils.base64decode(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/base/common/src/com/netscape/cmscore/base/FileConfigStore.java b/base/common/src/com/netscape/cmscore/base/FileConfigStore.java
new file mode 100644
index 000000000..f0c52866e
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/base/FileConfigStore.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.cmscore.base;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+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 static final long serialVersionUID = 2642124526598175633L;
+ 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<String> e0 = store.getPropertyNames();
+ Vector<String> v = new Vector<String>();
+
+ 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<String> 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/base/common/src/com/netscape/cmscore/base/JDialogPasswordCallback.java b/base/common/src/com/netscape/cmscore/base/JDialogPasswordCallback.java
new file mode 100644
index 000000000..7a7709466
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/base/JDialogPasswordCallback.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.cmscore.base;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.util.Password;
+import org.mozilla.jss.util.PasswordCallback;
+import org.mozilla.jss.util.PasswordCallbackInfo;
+
+/**
+ * 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 = GridBagConstraints.RELATIVE;
+ gbc.gridy = GridBagConstraints.RELATIVE;
+ gbc.gridwidth = 1;
+ gbc.gridheight = 1;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ gbc.anchor = GridBagConstraints.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 = GridBagConstraints.NORTHWEST;
+ c.gridwidth = GridBagConstraints.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 = GridBagConstraints.NORTHWEST;
+ c.gridwidth = GridBagConstraints.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 = GridBagConstraints.CENTER;
+ c.fill = GridBagConstraints.NONE;
+ c.insets = new Insets(16, 0, 0, 0);
+ c.gridwidth = GridBagConstraints.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 = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.CENTER;
+ c.gridheight = GridBagConstraints.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 = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.CENTER;
+ c.insets = new Insets(10, 4, 0, 0);
+ c.gridheight = GridBagConstraints.REMAINDER;
+ c.gridwidth = GridBagConstraints.REMAINDER;
+ buttonPanel.add(cancel, c);
+
+ resetGBC(c);
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.CENTER;
+ c.gridwidth = GridBagConstraints.REMAINDER;
+ c.gridheight = GridBagConstraints.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/base/common/src/com/netscape/cmscore/base/PropConfigStore.java b/base/common/src/com/netscape/cmscore/base/PropConfigStore.java
new file mode 100644
index 000000000..1e46d3ef3
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/base/PropConfigStore.java
@@ -0,0 +1,792 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.ByteArrayOutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.math.BigInteger;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.mozilla.jss.util.Base64OutputStream;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotDefined;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISourceConfigStore;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4714108964096659077L;
+
+ 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 String 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 String put(String name, String value) {
+ return 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<String> keys() {
+ Hashtable<String, Object> h = new Hashtable<String, Object>();
+
+ enumerate(h);
+ return h.keys();
+ }
+
+ /**
+ * Retrieves the hashtable where all the properties are kept.
+ *
+ * @return hashtable
+ */
+ public Hashtable<String, Object> hashtable() {
+ Hashtable<String, Object> h = new Hashtable<String, Object>();
+
+ enumerate(h);
+ return h;
+ }
+
+ /**
+ * Return the number of items in this substore
+ */
+ public int size() {
+ Hashtable<String, Object> h = new Hashtable<String, Object>();
+
+ 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<String, Object> h) {
+ Enumeration<String> 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 = 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 = 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);
+
+ if (str == null || str.length() == 0) {
+ CMS.traceHashKey(mDebugType, getFullName(name),
+ "<notpresent>", "<bytearray>");
+ return defval;
+ } else {
+ CMS.traceHashKey(mDebugType, getFullName(name),
+ "<bytearray>", "<bytearray>");
+ return Utils.base64decode(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
+ */
+ @SuppressWarnings("unchecked")
+ public void removeSubStore(String name) {
+ // this operation is expensive!!!
+
+ Enumeration<String> 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);
+
+ while (e.hasMoreElements()) {
+ String key = e.nextElement();
+
+ if (key.startsWith(fullName + ".")) {
+ ((Hashtable<String, String>) 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 = 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<String> getPropertyNames() {
+ // XXX - this operation is expensive!!!
+ Hashtable<String, Object> h = new Hashtable<String, Object>();
+
+ enumerate(h);
+ Enumeration<String> e = h.keys();
+ Vector<String> v = new Vector<String>();
+
+ while (e.hasMoreElements()) {
+ String pname = 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<String> getSubStoreNames() {
+ // XXX - this operation is expensive!!!
+ Hashtable<String, Object> h = new Hashtable<String, Object>();
+
+ enumerate(h);
+ Enumeration<String> e = h.keys();
+ Vector<String> v = new Vector<String>();
+
+ while (e.hasMoreElements()) {
+ String pname = 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<String> keys = mSource.keys();
+
+ while (keys.hasMoreElements()) {
+ String key = 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<String> subs = getSubStoreNames();
+
+ while (subs.hasMoreElements()) {
+ String name = subs.nextElement();
+
+ IConfigStore sub = getSubStore(name);
+ IConfigStore newSub = that.makeSubStore(sub.getName());
+
+ Enumeration<String> props = sub.getPropertyNames();
+
+ while (props.hasMoreElements()) {
+ String n = 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/base/common/src/com/netscape/cmscore/base/SimpleProperties.java b/base/common/src/com/netscape/cmscore/base/SimpleProperties.java
new file mode 100644
index 000000000..7b1c6bae4
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/base/SimpleProperties.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.cmscore.base;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.Date;
+import java.util.Enumeration;
+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<String, String> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6129810287662322712L;
+
+ /**
+ * 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>
+ * &quot;apple, banana, pear, cantaloupe, watermelon,kiwi, mango&quot;
+ * </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);
+ }
+
+ /**
+ * 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<String> e = keys(); e.hasMoreElements();) {
+ String key = e.nextElement();
+ String val = 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) {
+ String oval = super.get(key);
+ String sval = (oval instanceof 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<String> propertyNames() {
+ Hashtable<String, String> h = new Hashtable<String, String>();
+
+ 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<String, String> h = new Hashtable<String, String>();
+
+ enumerate(h);
+ for (Enumeration<String> e = h.keys(); e.hasMoreElements();) {
+ String key = e.nextElement();
+ String val = 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<String, String> h = new Hashtable<String, String>();
+
+ enumerate(h);
+ for (Enumeration<String> e = h.keys(); e.hasMoreElements();) {
+ String key = e.nextElement();
+ String val = 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<String, String> h) {
+ if (defaults != null) {
+ defaults.enumerate(h);
+ }
+ for (Enumeration<String> e = keys(); e.hasMoreElements();) {
+ String key = e.nextElement();
+
+ h.put(key, get(key));
+ }
+ }
+
+ /** 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/base/common/src/com/netscape/cmscore/base/SourceConfigStore.java b/base/common/src/com/netscape/cmscore/base/SourceConfigStore.java
new file mode 100644
index 000000000..3c4ec6992
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/base/SourceConfigStore.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.base;
+
+import com.netscape.certsrv.base.ISourceConfigStore;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1703553593020810628L;
+
+ /**
+ * Retrieves a property from the config store
+ * <P>
+ *
+ * @param name property name
+ * @return property value
+ */
+ public String 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
+ * @return
+ */
+ public String put(String name, String value) {
+ return super.put(name, value); // from Properties->Hashtable
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/base/SubsystemLoader.java b/base/common/src/com/netscape/cmscore/base/SubsystemLoader.java
new file mode 100644
index 000000000..a9307e858
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/base/SubsystemLoader.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.base;
+
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+
+/**
+ * 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<ISubsystem> load(IConfigStore config) throws EBaseException {
+ Vector<ISubsystem> v = new Vector<ISubsystem>();
+
+ // 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/base/common/src/com/netscape/cmscore/base/SubsystemRegistry.java b/base/common/src/com/netscape/cmscore/base/SubsystemRegistry.java
new file mode 100644
index 000000000..adae60496
--- /dev/null
+++ b/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.ISubsystem;
+
+public class SubsystemRegistry extends Hashtable<String, ISubsystem> {
+ private static final long serialVersionUID = 7801949114531559118L;
+ 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 super.get(key);
+ }
+
+}
diff --git a/base/common/src/com/netscape/cmscore/cert/CertDateCompare.java b/base/common/src/com/netscape/cmscore/cert/CertDateCompare.java
new file mode 100644
index 000000000..7078c3440
--- /dev/null
+++ b/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.Comparator;
+import java.util.Date;
+
+import netscape.security.x509.X509CertImpl;
+
+/**
+ * Compares validity dates for use in sorting.
+ *
+ * @author kanda
+ * @version $Revision$, $Date$
+ */
+public class CertDateCompare implements Comparator<X509CertImpl> {
+ public CertDateCompare() {
+ }
+
+ public int compare(X509CertImpl cert1, X509CertImpl cert2) {
+ Date d1 = null;
+ Date d2 = null;
+
+ try {
+ d1 = cert1.getNotAfter();
+ d2 = cert2.getNotAfter();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ if (d1 == d2)
+ return 0;
+ if (d1.after(d2))
+ return 1;
+ else
+ return -1;
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/cert/CertPrettyPrint.java b/base/common/src/com/netscape/cmscore/cert/CertPrettyPrint.java
new file mode 100644
index 000000000..726fa5e14
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/cert/CertPrettyPrint.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.cert;
+
+import java.security.cert.Certificate;
+
+import com.netscape.certsrv.base.ICertPrettyPrint;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/cert/CertUtils.java b/base/common/src/com/netscape/cmscore/cert/CertUtils.java
new file mode 100644
index 000000000..9710d63f5
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/cert/CertUtils.java
@@ -0,0 +1,1103 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.StringTokenizer;
+
+import netscape.security.extensions.NSCertTypeExtension;
+import netscape.security.pkcs.PKCS10;
+import netscape.security.pkcs.PKCS7;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateAlgorithmId;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateIssuerName;
+import netscape.security.x509.CertificateSerialNumber;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CRLImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.CryptoManager.CertificateUsage;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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 = Utils.base64decode(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" +
+ Utils.base64encode(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[] = Utils.base64decode(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[] = Utils.base64decode(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[] = Utils.base64decode(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[] = Utils.base64decode(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();
+ boolean verifyResult = true;
+ boolean r = true; /* the final return value */
+ 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);
+ return 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);
+ return false;
+ }
+ 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);
+ return false;
+ }
+ StringTokenizer tokenizer = new StringTokenizer(certlist, ",");
+ while (tokenizer.hasMoreTokens()) {
+ String tag = tokenizer.nextToken();
+ tag = tag.trim();
+ CMS.debug("CertUtils: verifySystemCerts() cert tag=" + tag);
+ verifyResult = verifySystemCertByTag(tag);
+ if (verifyResult == false)
+ r = false; //r captures the value for final return
+ }
+ } 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/base/common/src/com/netscape/cmscore/cert/CertificatePair.java b/base/common/src/com/netscape/cmscore/cert/CertificatePair.java
new file mode 100644
index 000000000..b8f958be5
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/cert/CertificatePair.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.cmscore.cert;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.Tag;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+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/base/common/src/com/netscape/cmscore/cert/CrlCachePrettyPrint.java b/base/common/src/com/netscape/cmscore/cert/CrlCachePrettyPrint.java
new file mode 100644
index 000000000..6d838b70d
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/cert/CrlCachePrettyPrint.java
@@ -0,0 +1,262 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.text.DateFormat;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.TimeZone;
+
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.RevokedCertificate;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.ICRLPrettyPrint;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+
+/**
+ * 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<RevokedCertificate> revokedCerts =
+ mIP.getRevokedCertificates((int) (pageStart - 1), (int) upperLimit);
+
+ if (revokedCerts != null) {
+ Iterator<RevokedCertificate> i = revokedCerts.iterator();
+ long l = 1;
+
+ while ((i.hasNext()) && ((crlSize == 0) || (upperLimit - pageStart + 1 >= l))) {
+ RevokedCertificate revokedCert = 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/base/common/src/com/netscape/cmscore/cert/CrlPrettyPrint.java b/base/common/src/com/netscape/cmscore/cert/CrlPrettyPrint.java
new file mode 100644
index 000000000..1d6048c8d
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/cert/CrlPrettyPrint.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.cert;
+
+import netscape.security.x509.X509CRLImpl;
+
+import com.netscape.certsrv.base.ICRLPrettyPrint;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/cert/CrossCertPairSubsystem.java b/base/common/src/com/netscape/cmscore/cert/CrossCertPairSubsystem.java
new file mode 100644
index 000000000..8d8a337c5
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/cert/CrossCertPairSubsystem.java
@@ -0,0 +1,505 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPModification;
+import netscape.ldap.LDAPModificationSet;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.cert.ICrossCertPairSubsystem;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.publish.IXcertPublisherProcessor;
+import com.netscape.cmscore.ldapconn.LdapBoundConnFactory;
+
+/**
+ * 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;
+ }
+
+ @SuppressWarnings("unchecked")
+ Enumeration<byte[]> 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 = 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;
+ }
+ @SuppressWarnings("unchecked")
+ Enumeration<byte[]> vals = attr.getByteValues();
+ byte[] val = null;
+
+ while (vals.hasMoreElements()) {
+ val = 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;
+ }
+
+ @SuppressWarnings("unchecked")
+ Enumeration<byte[]> 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 = 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/base/common/src/com/netscape/cmscore/cert/ExtPrettyPrint.java b/base/common/src/com/netscape/cmscore/cert/ExtPrettyPrint.java
new file mode 100644
index 000000000..5f5c66a48
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/cert/ExtPrettyPrint.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.cert;
+
+import netscape.security.x509.Extension;
+
+import com.netscape.certsrv.base.IExtPrettyPrint;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/cert/OidLoaderSubsystem.java b/base/common/src/com/netscape/cmscore/cert/OidLoaderSubsystem.java
new file mode 100644
index 000000000..dfd7dbab8
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/cert/OidLoaderSubsystem.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.cmscore.cert;
+
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+
+import netscape.security.extensions.CertificateRenewalWindowExtension;
+import netscape.security.extensions.CertificateScopeOfUseExtension;
+import netscape.security.extensions.NSCertTypeExtension;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.DeltaCRLIndicatorExtension;
+import netscape.security.x509.FreshestCRLExtension;
+import netscape.security.x509.HoldInstructionExtension;
+import netscape.security.x509.InvalidityDateExtension;
+import netscape.security.x509.IssuingDistributionPointExtension;
+import netscape.security.x509.OIDMap;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.cmscore.util.Debug;
+
+/**
+ *
+ * @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<String> 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/base/common/src/com/netscape/cmscore/cert/PrettyPrintFormat.java b/base/common/src/com/netscape/cmscore/cert/PrettyPrintFormat.java
new file mode 100644
index 000000000..669200575
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/cert/PrettyPrintFormat.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.cmscore.cert;
+
+import com.netscape.certsrv.base.IPrettyPrintFormat;
+
+/**
+ * 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) {
+
+ if (in == null) return "";
+
+ 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/base/common/src/com/netscape/cmscore/cert/PrettyPrintResources.java b/base/common/src/com/netscape/cmscore/cert/PrettyPrintResources.java
new file mode 100644
index 000000000..361f50b47
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/cert/PrettyPrintResources.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.cmscore.cert;
+
+import java.util.ListResourceBundle;
+
+import netscape.security.extensions.NSCertTypeExtension;
+import netscape.security.x509.KeyUsageExtension;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/cert/PubKeyPrettyPrint.java b/base/common/src/com/netscape/cmscore/cert/PubKeyPrettyPrint.java
new file mode 100644
index 000000000..9ea581812
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/cert/PubKeyPrettyPrint.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.cmscore.cert;
+
+import java.security.PublicKey;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/cert/X500NameSubsystem.java b/base/common/src/com/netscape/cmscore/cert/X500NameSubsystem.java
new file mode 100644
index 000000000..de5e233c9
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/cert/X500NameSubsystem.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.cmscore.cert;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.AVAValueConverter;
+import netscape.security.x509.DirStrConverter;
+import netscape.security.x509.X500NameAttrMap;
+
+import com.netscape.certsrv.apps.CMS;
+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.cmscore.util.Debug;
+
+/**
+ * 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<String> 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<String, Byte> mDerStr2TagHash = new Hashtable<String, Byte>();
+
+ 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 = 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/base/common/src/com/netscape/cmscore/connector/HttpConnFactory.java b/base/common/src/com/netscape/cmscore/connector/HttpConnFactory.java
new file mode 100644
index 000000000..01bb0f879
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/connector/HttpConnFactory.java
@@ -0,0 +1,308 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.connector.IHttpConnection;
+import com.netscape.certsrv.connector.IRemoteAuthority;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cmsutil.http.JssSSLSocketFactory;
+import com.netscape.cmsutil.net.ISocketFactory;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/connector/HttpConnection.java b/base/common/src/com/netscape/cmscore/connector/HttpConnection.java
new file mode 100644
index 000000000..95cdbc779
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/connector/HttpConnection.java
@@ -0,0 +1,244 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.io.IOException;
+import java.util.StringTokenizer;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.connector.IHttpConnection;
+import com.netscape.certsrv.connector.IPKIMessage;
+import com.netscape.certsrv.connector.IRemoteAuthority;
+import com.netscape.certsrv.connector.IRequestEncoder;
+import com.netscape.cmscore.util.Debug;
+import com.netscape.cmsutil.http.HttpClient;
+import com.netscape.cmsutil.http.HttpRequest;
+import com.netscape.cmsutil.http.HttpResponse;
+import com.netscape.cmsutil.net.ISocketFactory;
+
+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/base/common/src/com/netscape/cmscore/connector/HttpConnector.java b/base/common/src/com/netscape/cmscore/connector/HttpConnector.java
new file mode 100644
index 000000000..cdb315795
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/connector/HttpConnector.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.cmscore.connector;
+
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.connector.IConnector;
+import com.netscape.certsrv.connector.IHttpConnection;
+import com.netscape.certsrv.connector.IHttpPKIMessage;
+import com.netscape.certsrv.connector.IRemoteAuthority;
+import com.netscape.certsrv.connector.IResender;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cmsutil.http.JssSSLSocketFactory;
+import com.netscape.cmsutil.net.ISocketFactory;
+
+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<String> 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/base/common/src/com/netscape/cmscore/connector/HttpPKIMessage.java b/base/common/src/com/netscape/cmscore/connector/HttpPKIMessage.java
new file mode 100644
index 000000000..ea235391d
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/connector/HttpPKIMessage.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.cmscore.connector;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.OptionalDataException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.NoSuchElementException;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.connector.IHttpPKIMessage;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cmscore.util.Debug;
+
+/**
+ * simple name/value pair message.
+ */
+public class HttpPKIMessage implements IHttpPKIMessage {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3378261119472034953L;
+ // initialized to "" because nulls don't serialize well.
+ public String reqType = "";
+ public String reqId = "";
+ protected String reqStatus = "";
+ protected Vector<Object> mNameVals = new Vector<Object>(); // 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.
+ */
+ @SuppressWarnings("unchecked")
+ 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);
+
+ String key;
+ Object value;
+ Enumeration<Object> 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<String, String>) 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<Object> 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>();
+ 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/base/common/src/com/netscape/cmscore/connector/HttpRequestEncoder.java b/base/common/src/com/netscape/cmscore/connector/HttpRequestEncoder.java
new file mode 100644
index 000000000..76d39b3ed
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/connector/HttpRequestEncoder.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.connector;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OptionalDataException;
+
+import com.netscape.certsrv.connector.IRequestEncoder;
+import com.netscape.cmscore.util.Debug;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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 = Utils.base64encode(serial);
+ return s;
+ }
+
+ public Object decode(String s)
+ throws IOException {
+ Object result = null;
+ byte[] serial = null;
+
+ try {
+
+ serial = Utils.base64decode(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/base/common/src/com/netscape/cmscore/connector/LocalConnector.java b/base/common/src/com/netscape/cmscore/connector/LocalConnector.java
new file mode 100644
index 000000000..42c6636ce
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/connector/LocalConnector.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.cmscore.connector;
+
+import java.util.Hashtable;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.connector.IConnector;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestListener;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cmscore.util.Debug;
+
+public class LocalConnector implements IConnector {
+ ILogger mLogger = CMS.getLogger();
+ ICertAuthority mSource = null;
+ IAuthority mDest = null;
+ Hashtable<String, IRequest> mSourceReqs = new Hashtable<String, IRequest>();
+
+ 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 = 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/base/common/src/com/netscape/cmscore/connector/RemoteAuthority.java b/base/common/src/com/netscape/cmscore/connector/RemoteAuthority.java
new file mode 100644
index 000000000..71d01579f
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/connector/RemoteAuthority.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.cmscore.connector;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.connector.IRemoteAuthority;
+
+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/base/common/src/com/netscape/cmscore/connector/RequestTransfer.java b/base/common/src/com/netscape/cmscore/connector/RequestTransfer.java
new file mode 100644
index 000000000..33a2d7d71
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/connector/RequestTransfer.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.connector;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.request.IRequest;
+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<String> e = r.getExtDataKeys();
+ Vector<String> v = new Vector<String>();
+
+ while (e.hasMoreElements()) {
+ String k = 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/base/common/src/com/netscape/cmscore/connector/Resender.java b/base/common/src/com/netscape/cmscore/connector/Resender.java
new file mode 100644
index 000000000..783caa671
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/connector/Resender.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.cmscore.connector;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.connector.IRemoteAuthority;
+import com.netscape.certsrv.connector.IResender;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestList;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cmscore.util.Debug;
+import com.netscape.cmsutil.http.JssSSLSocketFactory;
+
+/**
+ * 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<String> mRequestIds = new Vector<String>();
+
+ 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
+ @SuppressWarnings("unchecked")
+ Vector<String> rids = (Vector<String>) mRequestIds.clone();
+ Vector<RequestId> completedRids = new Vector<RequestId>();
+
+ // resend each request to CA to ping for status.
+ Enumeration<String> enum1 = rids.elements();
+
+ while (enum1.hasMoreElements()) {
+ // request ids are added as strings.
+ String ridString = 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<RequestId> en = completedRids.elements();
+
+ synchronized (mRequestIds) {
+ while (en.hasMoreElements()) {
+ RequestId id = 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 {
+
+ 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/base/common/src/com/netscape/cmscore/crmf/CRMFParser.java b/base/common/src/com/netscape/cmscore/crmf/CRMFParser.java
new file mode 100644
index 000000000..b42bc00f9
--- /dev/null
+++ b/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 java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.Vector;
+
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.crmf.PKIArchiveOptions;
+import org.mozilla.jss.pkix.primitive.AVA;
+
+import com.netscape.certsrv.apps.CMS;
+
+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<PKIArchiveOptionsContainer> options = new Vector<PKIArchiveOptionsContainer>();
+
+ 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/base/common/src/com/netscape/cmscore/crmf/PKIArchiveOptionsContainer.java b/base/common/src/com/netscape/cmscore/crmf/PKIArchiveOptionsContainer.java
new file mode 100644
index 000000000..4c5478daf
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/crmf/PKIArchiveOptionsContainer.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.cmscore.crmf;
+
+import org.mozilla.jss.pkix.crmf.PKIArchiveOptions;
+
+public class PKIArchiveOptionsContainer {
+
+ public PKIArchiveOptions mAO = null;
+ public int mReqPos;
+
+ public PKIArchiveOptionsContainer(PKIArchiveOptions ao, int reqpos) {
+ mAO = ao;
+ mReqPos = reqpos;
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/dbs/BigIntegerMapper.java b/base/common/src/com/netscape/cmscore/dbs/BigIntegerMapper.java
new file mode 100644
index 000000000..3fa613198
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/BigIntegerMapper.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.cmscore.dbs;
+
+import java.math.BigInteger;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBAttrMapper;
+import com.netscape.certsrv.dbs.IDBObj;
+
+/**
+ * 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<String> v = new Vector<String>();
+
+ /**
+ * Constructs BigInteger mapper.
+ */
+ public BigIntegerMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Returns a list of supported ldap attribute names.
+ */
+ public Enumeration<String> 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/base/common/src/com/netscape/cmscore/dbs/ByteArrayMapper.java b/base/common/src/com/netscape/cmscore/dbs/ByteArrayMapper.java
new file mode 100644
index 000000000..38362f341
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/ByteArrayMapper.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.cmscore.dbs;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBAttrMapper;
+import com.netscape.certsrv.dbs.IDBObj;
+
+/**
+ * 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<String> v = new Vector<String>();
+
+ /**
+ * Constructs a byte array mapper.
+ */
+ public ByteArrayMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Lists a list of supported ldap attribute names.
+ */
+ public Enumeration<String> 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/base/common/src/com/netscape/cmscore/dbs/CRLDBSchema.java b/base/common/src/com/netscape/cmscore/dbs/CRLDBSchema.java
new file mode 100644
index 000000000..253bd81e0
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/CRLDBSchema.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.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/base/common/src/com/netscape/cmscore/dbs/CRLIssuingPointRecord.java b/base/common/src/com/netscape/cmscore/dbs/CRLIssuingPointRecord.java
new file mode 100644
index 000000000..0a3a46f14
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/CRLIssuingPointRecord.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.cmscore.dbs;
+
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import netscape.security.x509.RevokedCertificate;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBObj;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+
+/**
+ * A class represents a CRL issuing point record.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class CRLIssuingPointRecord implements ICRLIssuingPointRecord, IDBObj {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 400565044343905267L;
+ 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<BigInteger, RevokedCertificate> mCRLCache = null;
+ protected Hashtable<BigInteger, RevokedCertificate> mRevokedCerts = null;
+ protected Hashtable<BigInteger, RevokedCertificate> mUnrevokedCerts = null;
+ protected Hashtable<BigInteger, RevokedCertificate> mExpiredCerts = null;
+ protected byte mDeltaCRL[] = null;
+ protected static Vector<String> mNames = new Vector<String>();
+ 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<BigInteger, RevokedCertificate> revokedCerts,
+ Hashtable<BigInteger, RevokedCertificate> unrevokedCerts,
+ Hashtable<BigInteger, RevokedCertificate> 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;
+ }
+
+ @SuppressWarnings({ "unchecked" })
+ 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<BigInteger, RevokedCertificate>) obj;
+ } else if (name.equalsIgnoreCase(ATTR_REVOKED_CERTS)) {
+ mRevokedCerts = (Hashtable<BigInteger, RevokedCertificate>) obj;
+ } else if (name.equalsIgnoreCase(ATTR_UNREVOKED_CERTS)) {
+ mUnrevokedCerts = (Hashtable<BigInteger, RevokedCertificate>) obj;
+ } else if (name.equalsIgnoreCase(ATTR_EXPIRED_CERTS)) {
+ mExpiredCerts = (Hashtable<BigInteger, RevokedCertificate>) 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<String> getElements() {
+ return mNames.elements();
+ }
+
+ public Enumeration<String> 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<BigInteger, RevokedCertificate> getCRLCacheNoClone() {
+ if (mCRLCache == null)
+ return null;
+ else
+ return mCRLCache;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Hashtable<BigInteger, RevokedCertificate> getCRLCache() {
+ if (mCRLCache == null)
+ return null;
+ else
+ return (Hashtable<BigInteger, RevokedCertificate>) mCRLCache.clone();
+ }
+
+ /**
+ * Retrieves cache info of revoked certificates.
+ */
+ @SuppressWarnings("unchecked")
+ public Hashtable<BigInteger, RevokedCertificate> getRevokedCerts() {
+ if (mRevokedCerts == null)
+ return null;
+ else
+ return (Hashtable<BigInteger, RevokedCertificate>) mRevokedCerts.clone();
+ }
+
+ /**
+ * Retrieves cache info of unrevoked certificates.
+ */
+ @SuppressWarnings("unchecked")
+ public Hashtable<BigInteger, RevokedCertificate> getUnrevokedCerts() {
+ if (mUnrevokedCerts == null)
+ return null;
+ else
+ return (Hashtable<BigInteger, RevokedCertificate>) mUnrevokedCerts.clone();
+ }
+
+ /**
+ * Retrieves cache info of expired certificates.
+ */
+ @SuppressWarnings("unchecked")
+ public Hashtable<BigInteger, RevokedCertificate> getExpiredCerts() {
+ if (mExpiredCerts == null)
+ return null;
+ else
+ return (Hashtable<BigInteger, RevokedCertificate>) mExpiredCerts.clone();
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/dbs/CRLRepository.java b/base/common/src/com/netscape/cmscore/dbs/CRLRepository.java
new file mode 100644
index 000000000..7eb470d55
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/CRLRepository.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.cmscore.dbs;
+
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import netscape.security.x509.RevokedCertificate;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.EDBException;
+import com.netscape.certsrv.dbs.IDBSSession;
+import com.netscape.certsrv.dbs.IDBSearchResults;
+import com.netscape.certsrv.dbs.IDBSubsystem;
+import com.netscape.certsrv.dbs.Modification;
+import com.netscape.certsrv.dbs.ModificationSet;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.dbs.crldb.ICRLRepository;
+
+/**
+ * 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;
+
+ /*
+ DBRegistry 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<String> 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<String> v = new Vector<String>();
+ 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<BigInteger, RevokedCertificate> revokedCerts,
+ Hashtable<BigInteger, RevokedCertificate> unrevokedCerts,
+ Hashtable<BigInteger, RevokedCertificate> 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<BigInteger, RevokedCertificate> revokedCerts,
+ Hashtable<BigInteger, RevokedCertificate> 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<BigInteger, RevokedCertificate> 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<BigInteger, RevokedCertificate> revokedCerts,
+ Hashtable<BigInteger, RevokedCertificate> unrevokedCerts,
+ Hashtable<BigInteger, RevokedCertificate> 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/base/common/src/com/netscape/cmscore/dbs/CertDBSchema.java b/base/common/src/com/netscape/cmscore/dbs/CertDBSchema.java
new file mode 100644
index 000000000..67b662713
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/CertDBSchema.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.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/base/common/src/com/netscape/cmscore/dbs/CertRecord.java b/base/common/src/com/netscape/cmscore/dbs/CertRecord.java
new file mode 100644
index 000000000..1981757cb
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/CertRecord.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.cmscore.dbs;
+
+import java.math.BigInteger;
+import java.security.cert.Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.MetaInfo;
+import com.netscape.certsrv.dbs.EDBException;
+import com.netscape.certsrv.dbs.IDBObj;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.IRevocationInfo;
+
+/**
+ * A class represents a serializable certificate record.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class CertRecord implements IDBObj, ICertRecord {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6231895305929417777L;
+ 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<String> mNames = new Vector<String>();
+ 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<String> getElements() {
+ return mNames.elements();
+ }
+
+ public Enumeration<String> 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/base/common/src/com/netscape/cmscore/dbs/CertRecordList.java b/base/common/src/com/netscape/cmscore/dbs/CertRecordList.java
new file mode 100644
index 000000000..29792880d
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/CertRecordList.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.cmscore.dbs;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBVirtualList;
+import com.netscape.certsrv.dbs.IElementProcessor;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertRecordList;
+
+/**
+ * A class represents a list of certificate records.
+ * <P>
+ *
+ * @author thomask mzhao
+ * @version $Revision$, $Date$
+ */
+public class CertRecordList implements ICertRecordList {
+
+ private IDBVirtualList<ICertRecord> mVlist = null;
+
+ /**
+ * Constructs a request list.
+ */
+ public CertRecordList(IDBVirtualList<ICertRecord> 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<ICertRecord> getCertRecords(int startidx, int endidx)
+ throws EBaseException {
+ Vector<ICertRecord> entries = new Vector<ICertRecord>();
+
+ for (int i = startidx; i <= endidx; i++) {
+ ICertRecord element = mVlist.getElementAt(i);
+
+ // CMS.debug("gerCertRecords[" + i + "] element: " + element);
+ if (element != null) {
+ entries.addElement(element);
+ }
+ }
+ return entries.elements();
+ }
+
+ public ICertRecord getCertRecord(int index)
+ throws EBaseException {
+
+ return mVlist.getElementAt(index);
+
+ }
+
+}
diff --git a/base/common/src/com/netscape/cmscore/dbs/CertRecordMapper.java b/base/common/src/com/netscape/cmscore/dbs/CertRecordMapper.java
new file mode 100644
index 000000000..f4074c213
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/CertRecordMapper.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.cmscore.dbs;
+
+import java.math.BigInteger;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+
+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.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.cmscore.util.Debug;
+
+/**
+ * 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<String> getSupportedLDAPAttributeNames() {
+ Vector<String> v = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cmscore/dbs/CertificateRepository.java b/base/common/src/com/netscape/cmscore/dbs/CertificateRepository.java
new file mode 100644
index 000000000..0df563cad
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/CertificateRepository.java
@@ -0,0 +1,2030 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.Serializable;
+import java.math.BigInteger;
+import java.security.cert.Certificate;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPSearchResults;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.MetaInfo;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.dbs.EDBException;
+import com.netscape.certsrv.dbs.IDBSSession;
+import com.netscape.certsrv.dbs.IDBSearchResults;
+import com.netscape.certsrv.dbs.IDBSubsystem;
+import com.netscape.certsrv.dbs.IDBVirtualList;
+import com.netscape.certsrv.dbs.IElementProcessor;
+import com.netscape.certsrv.dbs.Modification;
+import com.netscape.certsrv.dbs.ModificationSet;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertRecordList;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.dbs.certdb.IRevocationInfo;
+import com.netscape.certsrv.dbs.repository.IRepository;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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<String, ICRLIssuingPoint> mCRLIssuingPoints = new Hashtable<String, ICRLIssuingPoint>();
+
+ private int mTransitMaxRecords = 1000000;
+ private int mTransitRecordPageSize = 200;
+
+ CertStatusUpdateTask certStatusUpdateTask;
+ RetrieveModificationsTask retrieveModificationsTask;
+
+ IRepository requestRepository;
+
+ /**
+ * Constructs a certificate repository.
+ */
+ public CertificateRepository(IDBSubsystem dbService, String certRepoBaseDN, int increment, String baseDN)
+ throws EDBException {
+ super(dbService, increment, baseDN);
+ mBaseDN = certRepoBaseDN;
+ mDBService = dbService;
+ }
+
+ 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();
+
+ 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<ICertRecord> 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 void setCertStatusUpdateInterval(IRepository requestRepository, int interval, boolean listenToCloneModifications) {
+
+ CMS.debug("In setCertStatusUpdateInterval " + interval);
+
+ this.requestRepository = requestRepository;
+
+ if (interval == 0) {
+ CMS.debug("In setCertStatusUpdateInterval interval = 0");
+ if (certStatusUpdateTask != null) {
+ certStatusUpdateTask.stop();
+ }
+ if (retrieveModificationsTask != null) {
+ retrieveModificationsTask.stop();
+ }
+ return;
+ }
+
+ CMS.debug("In setCertStatusUpdateInterval listenToCloneModifications=" + listenToCloneModifications);
+
+ if (listenToCloneModifications) {
+ CMS.debug("In setCertStatusUpdateInterval listening to modifications");
+ try {
+ retrieveModificationsTask = new RetrieveModificationsTask(this);
+ retrieveModificationsTask.start();
+ } catch (EBaseException e) {
+ retrieveModificationsTask = null;
+ e.printStackTrace();
+ }
+ }
+
+ CMS.debug("In setCertStatusUpdateInterval scheduling cert status update every " + interval + " seconds.");
+ certStatusUpdateTask = new CertStatusUpdateTask(this, interval);
+ certStatusUpdateTask.start();
+ }
+
+ /**
+ * This method blocks when another thread (such as the CRL Update) is running
+ */
+ public synchronized void updateCertStatus() {
+
+ CMS.debug("In updateCertStatus()");
+
+ try {
+ 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"));
+
+ CMS.debug("Starting cert checkRanges");
+ checkRanges();
+ CMS.debug("cert checkRanges done");
+
+ CMS.debug("Starting request checkRanges");
+ requestRepository.checkRanges();
+ CMS.debug("request checkRanges done");
+
+ } catch (Exception e) {
+ CMS.debug("updateCertStatus done: " + e.toString());
+ }
+ }
+
+ public synchronized void processRevokedCerts(IElementProcessor p, String filter, int pageSize)
+ throws EBaseException {
+
+ CMS.debug("Starting processRevokedCerts (entered lock)");
+ ICertRecordList list = findCertRecordsInList(filter,
+ new String[] { ICertRecord.ATTR_ID, ICertRecord.ATTR_REVO_INFO, "objectclass" },
+ "serialno",
+ pageSize);
+
+ int totalSize = list.getSize();
+
+ list.processCertRecords(0, totalSize - 1, p);
+ CMS.debug("processRevokedCerts done");
+ }
+
+ /**
+ * 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<Serializable> cList = new Vector<Serializable>(ltSize);
+
+ CMS.debug("transidValidCertificates: list size: " + size);
+ CMS.debug("transitValidCertificates: ltSize " + ltSize);
+
+ CertRecord curRec = null;
+
+ int i;
+ ICertRecord 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");
+ }
+ }
+
+ 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<Serializable> cList = new Vector<Serializable>(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<Serializable> cList = new Vector<Serializable>(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<Serializable> 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<ICRLIssuingPoint> eIPs = mCRLIssuingPoints.elements();
+
+ while (eIPs.hasMoreElements()) {
+ ICRLIssuingPoint ip = 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 {
+ 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<Object> searchCertificates(String filter, int maxSize)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration<Object> 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<ICertRecord> searchCertificates(String filter, int maxSize, int timeLimit)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Vector<ICertRecord> v = new Vector<ICertRecord>();
+
+ CMS.debug("searchCertificateswith time limit filter " + filter);
+ try {
+ IDBSearchResults sr = s.search(getDN(), filter, maxSize, timeLimit);
+ while (sr.hasMoreElements()) {
+ v.add((ICertRecord) sr.nextElement());
+ }
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return v.elements();
+ }
+
+ /**
+ * Returns a list of X509CertImp that satisfies the filter.
+ *
+ * @deprecated replaced by <code>findCertificatesInList</code>
+ */
+ public Enumeration<Object> findCertRecs(String filter)
+ throws EBaseException {
+ CMS.debug("findCertRecs " + filter);
+ IDBSSession s = mDBService.createSession();
+ Enumeration<Object> e = null;
+ try {
+ e = s.search(getDN(), filter);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ public Enumeration<Object> findCertRecs(String filter, String[] attrs)
+ throws EBaseException {
+
+ CMS.debug("findCertRecs " + filter
+ + "attrs " + Arrays.toString(attrs));
+ IDBSSession s = mDBService.createSession();
+ Enumeration<Object> e = null;
+ try {
+ e = s.search(getDN(), filter, attrs);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+
+ }
+
+ public Enumeration<X509CertImpl> findCertificates(String filter)
+ throws EBaseException {
+ Enumeration<ICertRecord> e = findCertRecords(filter);
+ Vector<X509CertImpl> v = new Vector<X509CertImpl>();
+
+ while (e.hasMoreElements()) {
+ ICertRecord rec = 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<ICertRecord> findCertRecords(String filter)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration<ICertRecord> 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 {
+ IDBVirtualList<ICertRecord> vlist = s.<ICertRecord>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;
+ }
+ }
+
+ IDBVirtualList<ICertRecord> vlist = 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 {
+
+ IDBVirtualList<ICertRecord> vlist = 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<Object> mToRenew = null;
+ Vector<Object> mToNotify = null;
+
+ public RenewableCertificateCollection() {
+ }
+
+ public Vector<Object> getRenewable() {
+ return mToRenew;
+ }
+
+ public Vector<Object> getNotifiable() {
+ return mToNotify;
+ }
+
+ public void addCertificate(String renewalFlag, Object o) {
+ if (renewalFlag.equals(CertRecord.AUTO_RENEWAL_ENABLED)) {
+ if (mToRenew == null)
+ mToRenew = new Vector<Object>();
+ mToRenew.addElement(o);
+ }
+ if (renewalFlag.equals(CertRecord.AUTO_RENEWAL_DISABLED)) {
+ if (mToNotify == null)
+ mToNotify = new Vector<Object>();
+ mToNotify.addElement(o);
+ }
+ }
+ }
+
+ public Hashtable<String, RenewableCertificateCollection> getRenewableCertificates(String renewalTime)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ Hashtable<String, RenewableCertificateCollection> 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<ICertRecord> e = list.getCertRecords(0, size - 1);
+
+ tab = new Hashtable<String, RenewableCertificateCollection>();
+ 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<ICertRecord> e = list.getCertRecords(0, size - 1);
+
+ Vector<X509CertImpl> v = new Vector<X509CertImpl>();
+
+ 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<ICertRecord> 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<X509CertImpl> v = new Vector<X509CertImpl>();
+
+ 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<ICertRecord> getValidCertificates(String from, String to)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Vector<ICertRecord> v = new Vector<ICertRecord>();
+
+ try {
+
+ // 'from' determines 'jumpto' value
+ // 'to' determines where to stop looking
+
+ String ldapfilter = "(certstatus=VALID)";
+
+ String fromVal = "0";
+ try {
+ if (from != null) {
+ 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<ICertRecord> getAllValidCertificates()
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration<ICertRecord> 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<ICertRecord> getValidNotPublishedCertificates(String from, String to)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration<ICertRecord> 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<ICertRecord> getAllValidNotPublishedCertificates()
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration<ICertRecord> 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<ICertRecord> getExpiredCertificates(String from, String to)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration<ICertRecord> 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<ICertRecord> getAllExpiredCertificates()
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration<ICertRecord> 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<ICertRecord> getExpiredPublishedCertificates(String from, String to)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration<ICertRecord> 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<ICertRecord> getAllExpiredPublishedCertificates()
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration<ICertRecord> 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 {
+
+ 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 {
+
+ 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<ICertRecord> getRevokedCertificates(String from, String to)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration<ICertRecord> 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<ICertRecord> getAllRevokedCertificates()
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration<ICertRecord> e = null;
+ // index is setup for this filter
+ String ldapfilter = "(|(" + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_REVOKED + ")("
+ + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_REVOKED_EXPIRED + "))";
+
+ 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<ICertRecord> getRevokedPublishedCertificates(String from, String to)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration<ICertRecord> 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<ICertRecord> getAllRevokedPublishedCertificates()
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration<ICertRecord> e = null;
+ // index is setup for this filter
+ String ldapfilter = "(&(|(" + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_REVOKED + ")("
+ + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_REVOKED_EXPIRED + "))";
+
+ 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<ICertRecord> getRevokedCertificates(Date asOfDate)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration<ICertRecord> 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<ICertRecord> getAllRevokedNonExpiredCertificates()
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration<ICertRecord> 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;
+ }
+
+ LDAPSearchResults searchForModifiedCertificateRecords(IDBSSession session) {
+ CMS.debug("searchForModifiedCertificateRecords");
+ LDAPSearchResults results = null;
+
+ String filter = "(" + CertRecord.ATTR_CERT_STATUS + "=*)";
+ try {
+ results = session.persistentSearch(getDN(), filter, null);
+
+ } catch (Exception e) {
+ CMS.debug("startSearchForModifiedCertificateRecords persistentSearch Exception=" + e);
+ }
+
+ return results;
+ }
+
+ 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<ICRLIssuingPoint> eIPs = mCRLIssuingPoints.elements();
+
+ while (eIPs.hasMoreElements()) {
+ ICRLIssuingPoint ip = 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 (certStatusUpdateTask != null) {
+ certStatusUpdateTask.stop();
+ }
+
+ if (retrieveModificationsTask != null) {
+ retrieveModificationsTask.stop();
+ }
+ }
+}
+
+class CertStatusUpdateTask implements Runnable {
+
+ CertificateRepository repository;
+ int interval;
+
+ ScheduledExecutorService executorService;
+
+ public CertStatusUpdateTask(CertificateRepository repository, int interval) {
+ this.repository = repository;
+ this.interval = interval;
+ }
+
+ public void start() {
+ // schedule task to run immediately and repeat after specified interval
+ executorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
+ public Thread newThread(Runnable r) {
+ return new Thread(r, "CertStatusUpdateTask");
+ }
+ });
+ executorService.scheduleWithFixedDelay(this, 0, interval, TimeUnit.SECONDS);
+ }
+
+ public void run() {
+ repository.updateCertStatus();
+ }
+
+ public void stop() {
+ // shutdown executorService without interrupting running task
+ if (executorService != null) executorService.shutdown();
+ }
+}
+
+class RetrieveModificationsTask implements Runnable {
+
+ CertificateRepository repository;
+
+ IDBSSession session;
+ LDAPSearchResults results;
+
+ ScheduledExecutorService executorService;
+
+ public RetrieveModificationsTask(CertificateRepository repository) {
+ this.repository = repository;
+ }
+
+ public void start() throws EBaseException {
+ // start persistent search
+ try {
+ session = repository.getDBSubsystem().createSession();
+ results = repository.searchForModifiedCertificateRecords(session);
+ } catch (EBaseException e) {
+ stop(); // avoid leaks
+ throw e;
+ }
+
+ // schedule task to run immediately and repeat without delay
+ executorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
+ public Thread newThread(Runnable r) {
+ return new Thread(r, "RetrieveModificationsTask");
+ }
+ });
+ executorService.scheduleWithFixedDelay(this, 0, 1, TimeUnit.MICROSECONDS);
+ }
+
+ public void run() {
+ CMS.debug("Inside run method of RetrieveModificationsThread");
+
+ try {
+ // results.hasMoreElements() will block until next element becomes available
+ // or return false if the search is abandoned or connection is closed
+ if (results.hasMoreElements()) {
+ LDAPEntry entry = results.next();
+ repository.getModifications(entry);
+ }
+ } catch (Exception e) {
+ CMS.debug("Exception: " + e.toString());
+ }
+ CMS.debug("Done with run method of RetrieveModificationsThread");
+ }
+
+ public void stop() {
+ if (executorService != null) executorService.shutdown();
+
+ if (session != null) {
+ // closing the session doesn't actually close the connection,
+ // so the search needs to be abandoned explicitly
+ if (results != null) try { session.abandon(results); } catch (Exception e) { e.printStackTrace(); }
+
+ // close session
+ try { session.close(); } catch (Exception e) { e.printStackTrace(); }
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/dbs/DBRegistry.java b/base/common/src/com/netscape/cmscore/dbs/DBRegistry.java
new file mode 100644
index 000000000..20e40a8e3
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/DBRegistry.java
@@ -0,0 +1,564 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+
+import com.netscape.certsrv.apps.CMS;
+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.IDBAttrMapper;
+import com.netscape.certsrv.dbs.IDBDynAttrMapper;
+import com.netscape.certsrv.dbs.IDBObj;
+import com.netscape.certsrv.dbs.IDBRegistry;
+import com.netscape.certsrv.dbs.IFilterConverter;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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<String, String[]> mOCclassNames = new Hashtable<String, String[]>();
+ private Hashtable<String, NameAndObject> mOCldapNames = new Hashtable<String, NameAndObject>();
+ private Hashtable<String, IDBAttrMapper> mAttrufNames = new Hashtable<String, IDBAttrMapper>();
+ private IFilterConverter mConverter = null;
+ private Vector<IDBDynAttrMapper> mDynAttrMappers = new Vector<IDBDynAttrMapper>();
+
+ 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<String> v = new Vector<String>();
+
+ 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<String> v = new Vector<String>();
+
+ 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<String> 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<IDBDynAttrMapper> 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<String> 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
+ @SuppressWarnings("unchecked")
+ Enumeration<String> vals = attr.getStringValues();
+ Vector<String> v = new Vector<String>();
+
+ 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<String> 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<String> v = new Vector<String>();
+
+ // 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/base/common/src/com/netscape/cmscore/dbs/DBSSession.java b/base/common/src/com/netscape/cmscore/dbs/DBSSession.java
new file mode 100644
index 000000000..ddc9f1874
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/DBSSession.java
@@ -0,0 +1,485 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.Enumeration;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPModification;
+import netscape.ldap.LDAPModificationSet;
+import netscape.ldap.LDAPSearchConstraints;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+import netscape.ldap.controls.LDAPPersistSearchControl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.dbs.EDBException;
+import com.netscape.certsrv.dbs.EDBNotAvailException;
+import com.netscape.certsrv.dbs.EDBRecordNotFoundException;
+import com.netscape.certsrv.dbs.IDBObj;
+import com.netscape.certsrv.dbs.IDBSSession;
+import com.netscape.certsrv.dbs.IDBSearchResults;
+import com.netscape.certsrv.dbs.IDBSubsystem;
+import com.netscape.certsrv.dbs.IDBVirtualList;
+import com.netscape.certsrv.dbs.Modification;
+import com.netscape.certsrv.dbs.ModificationSet;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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(&quot;cn=123459,o=certificate repository,o=airius.com&quot;,
+ * 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);
+ }
+
+ @SuppressWarnings("unchecked")
+ 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()));
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ 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.
+ */
+ @SuppressWarnings("unchecked")
+ 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()));
+ }
+ }
+
+ public void abandon(LDAPSearchResults results) throws EBaseException {
+ try {
+ mConn.abandon(results);
+
+ } 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 <T> IDBVirtualList<T> createVirtualList(String base, String filter,
+ String attrs[]) throws EBaseException {
+ return new DBVirtualList<T>(mDBSystem.getRegistry(), mConn, base,
+ filter, attrs);
+ }
+
+ /**
+ * Retrieves a list of objects.
+ */
+ public <T> IDBVirtualList<T> createVirtualList(String base, String filter,
+ String attrs[], String sortKey[]) throws EBaseException {
+ return new DBVirtualList<T>(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<Object>(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<Object>(mDBSystem.getRegistry(), mConn, base,
+ filter, attrs, sortKey, pageSize);
+ }
+
+ /**
+ * Retrieves a list of objects.
+ */
+ public IDBVirtualList<Object> createVirtualList(String base, String filter,
+ String attrs[], String sortKey, int pageSize) throws EBaseException {
+ return new DBVirtualList<Object>(mDBSystem.getRegistry(), mConn, base,
+ filter, attrs, sortKey, pageSize);
+ }
+
+ public IDBVirtualList<Object> createVirtualList(String base, String filter,
+ String attrs[], String startFrom, String sortKey, int pageSize) throws EBaseException {
+ return new DBVirtualList<Object>(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/base/common/src/com/netscape/cmscore/dbs/DBSUtil.java b/base/common/src/com/netscape/cmscore/dbs/DBSUtil.java
new file mode 100644
index 000000000..7c551b141
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/DBSUtil.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.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 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/base/common/src/com/netscape/cmscore/dbs/DBSearchResults.java b/base/common/src/com/netscape/cmscore/dbs/DBSearchResults.java
new file mode 100644
index 000000000..0621701b0
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/DBSearchResults.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.Enumeration;
+
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.dbs.IDBRegistry;
+import com.netscape.certsrv.dbs.IDBSearchResults;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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<Object> mRes = null;
+ private ILogger mLogger = CMS.getLogger();
+
+ /**
+ * Constructs search results.
+ */
+ public DBSearchResults(IDBRegistry registry, Enumeration<Object> 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/base/common/src/com/netscape/cmscore/dbs/DBSubsystem.java b/base/common/src/com/netscape/cmscore/dbs/DBSubsystem.java
new file mode 100644
index 000000000..4bc5b6471
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/DBSubsystem.java
@@ -0,0 +1,948 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.Hashtable;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSchema;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPModification;
+import netscape.ldap.LDAPObjectClassSchema;
+import netscape.ldap.LDAPSchema;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv3;
+import netscape.security.x509.CertificateValidity;
+
+import com.netscape.certsrv.apps.CMS;
+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.EDBNotAvailException;
+import com.netscape.certsrv.dbs.IDBRegistry;
+import com.netscape.certsrv.dbs.IDBSSession;
+import com.netscape.certsrv.dbs.IDBSubsystem;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.dbs.repository.IRepositoryRecord;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ELdapServerDownException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cmscore.base.PropConfigStore;
+import com.netscape.cmscore.ldapconn.LdapAuthInfo;
+import com.netscape.cmscore.ldapconn.LdapBoundConnFactory;
+import com.netscape.cmscore.ldapconn.LdapConnInfo;
+
+/**
+ * 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<String, String>[] 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 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 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 = 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 = 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 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 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<String, String> 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<String, String> 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<String, String> 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) {
+ 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<String, String> 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) {
+ 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<String, String> 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);
+ BigInteger incrementNo = new BigInteger((String) h.get(PROP_INCREMENT));
+ // 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<String, String> 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.
+ */
+ @SuppressWarnings("unchecked")
+ 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<String, String> certs = new Hashtable<String, String>();
+ 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<String, String> requests = new Hashtable<String, String>();
+ 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<String, String> replicaID = new Hashtable<String, String>();
+ 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/base/common/src/com/netscape/cmscore/dbs/DBVirtualList.java b/base/common/src/com/netscape/cmscore/dbs/DBVirtualList.java
new file mode 100644
index 000000000..574ab41c0
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/DBVirtualList.java
@@ -0,0 +1,782 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.Arrays;
+import java.util.Vector;
+
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPControl;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPSearchConstraints;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPSortKey;
+import netscape.ldap.controls.LDAPSortControl;
+import netscape.ldap.controls.LDAPVirtualListControl;
+import netscape.ldap.controls.LDAPVirtualListResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBRegistry;
+import com.netscape.certsrv.dbs.IDBVirtualList;
+import com.netscape.certsrv.dbs.IElementProcessor;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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<E> implements IDBVirtualList<E> {
+
+ 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<E> mEntries = new Vector<E>();
+ // 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
+ @SuppressWarnings("unchecked")
+ E o = (E) 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 E 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
+ */
+ 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 null; //("No entry at " + index);
+ else
+ return mEntries.elementAt(offset);
+ }
+
+ public E 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/base/common/src/com/netscape/cmscore/dbs/DateArrayMapper.java b/base/common/src/com/netscape/cmscore/dbs/DateArrayMapper.java
new file mode 100644
index 000000000..20562404b
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/DateArrayMapper.java
@@ -0,0 +1,109 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.Date;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBAttrMapper;
+import com.netscape.certsrv.dbs.IDBObj;
+
+/**
+ * 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<String> v = new Vector<String>();
+
+ /**
+ * Constructs a date array mapper.
+ */
+ public DateArrayMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Retrieves a list of support ldap attributes.
+ */
+ public Enumeration<String> 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;
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = attr.getStringValues();
+ Vector<Date> v = new Vector<Date>();
+
+ while (e.hasMoreElements()) {
+ v.addElement(DateMapper.dateFromDB(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/base/common/src/com/netscape/cmscore/dbs/DateMapper.java b/base/common/src/com/netscape/cmscore/dbs/DateMapper.java
new file mode 100644
index 000000000..a767758f6
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/DateMapper.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.cmscore.dbs;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBAttrMapper;
+import com.netscape.certsrv.dbs.IDBObj;
+
+/**
+ * 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<String> v = new Vector<String>();
+ 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<String> 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/base/common/src/com/netscape/cmscore/dbs/IntegerMapper.java b/base/common/src/com/netscape/cmscore/dbs/IntegerMapper.java
new file mode 100644
index 000000000..8dc07e4d9
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/IntegerMapper.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.cmscore.dbs;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBAttrMapper;
+import com.netscape.certsrv.dbs.IDBObj;
+
+/**
+ * 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<String> v = new Vector<String>();
+
+ /**
+ * Constructs mapper to deal with Integer.
+ */
+ public IntegerMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Retrieves a list of supported ldap attributes.
+ */
+ public Enumeration<String> 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/base/common/src/com/netscape/cmscore/dbs/KeyDBSchema.java b/base/common/src/com/netscape/cmscore/dbs/KeyDBSchema.java
new file mode 100644
index 000000000..50b3badc3
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/KeyDBSchema.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.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";
+ public static final String LDAP_ATTR_CLIENT_ID = "clientId";
+ public static final String LDAP_ATTR_STATUS = "status";
+ public static final String LDAP_ATTR_DATA_TYPE = "dataType";
+}
diff --git a/base/common/src/com/netscape/cmscore/dbs/KeyRecord.java b/base/common/src/com/netscape/cmscore/dbs/KeyRecord.java
new file mode 100644
index 000000000..f7773e3fa
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/KeyRecord.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.cmscore.dbs;
+
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.MetaInfo;
+import com.netscape.certsrv.dbs.IDBObj;
+import com.netscape.certsrv.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.KeyState;
+
+/**
+ * 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 static final long serialVersionUID = -3765000841161998984L;
+ 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;
+ private String mClientId = null;
+ private String mStatus = null;
+ private String mDataType = null;
+
+
+ protected static Vector<String> mNames = new Vector<String>();
+ 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);
+ mNames.addElement(ATTR_CLIENT_ID);
+ mNames.addElement(ATTR_STATUS);
+ mNames.addElement(ATTR_DATA_TYPE);
+ }
+
+ /**
+ * 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 if (name.equalsIgnoreCase(ATTR_CLIENT_ID)) {
+ mClientId = (String) object;
+ } else if (name.equalsIgnoreCase(ATTR_DATA_TYPE)) {
+ mDataType = (String) object;
+ } else if (name.equalsIgnoreCase(ATTR_STATUS)) {
+ mStatus = (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 if (name.equalsIgnoreCase(ATTR_CLIENT_ID)) {
+ return mClientId;
+ } else if (name.equalsIgnoreCase(ATTR_DATA_TYPE)) {
+ return mDataType;
+ } else if (name.equalsIgnoreCase(ATTR_STATUS)) {
+ return mStatus;
+ } 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<String> getElements() {
+ return mNames.elements();
+ }
+
+ /**
+ * Retrieves serializable attribute names.
+ */
+ public Enumeration<String> 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;
+ }
+
+ /**
+ * Retrieves the client ID of this record.
+ */
+ public String getClientId() throws EBaseException {
+ return mClientId ;
+ }
+
+ /**
+ * Retrieves the key status of this record.
+ */
+ public String getKeyStatus() throws EBaseException {
+ return mStatus;
+
+ }
+
+ /**
+ * Retrieves the key data type of this record.
+ */
+ public String getDataType() throws EBaseException {
+ return mDataType;
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/dbs/KeyRecordList.java b/base/common/src/com/netscape/cmscore/dbs/KeyRecordList.java
new file mode 100644
index 000000000..941b0552d
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/KeyRecordList.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.cmscore.dbs;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBVirtualList;
+import com.netscape.certsrv.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRecordList;
+
+/**
+ * A class represents a list of key records.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class KeyRecordList implements IKeyRecordList {
+
+ private IDBVirtualList<IKeyRecord> mVlist = null;
+
+ /**
+ * Constructs a key list.
+ */
+ public KeyRecordList(IDBVirtualList<IKeyRecord> 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) {
+ IKeyRecord record = mVlist.getElementAt(i);
+
+ if (record == null)
+ return null;
+
+ return record;
+ }
+
+ /**
+ * Retrieves requests.
+ */
+ public Enumeration<IKeyRecord> getKeyRecords(int startidx, int endidx)
+ throws EBaseException {
+ Vector<IKeyRecord> entries = new Vector<IKeyRecord>();
+
+ for (int i = startidx; i <= endidx; i++) {
+ IKeyRecord element = mVlist.getElementAt(i);
+
+ if (element != null) {
+ entries.addElement(element);
+ }
+ }
+ return entries.elements();
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/dbs/KeyRecordMapper.java b/base/common/src/com/netscape/cmscore/dbs/KeyRecordMapper.java
new file mode 100644
index 000000000..1a6103492
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/KeyRecordMapper.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.math.BigInteger;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+
+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.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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<String> getSupportedLDAPAttributeNames() {
+ Vector<String> v = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cmscore/dbs/KeyRepository.java b/base/common/src/com/netscape/cmscore/dbs/KeyRepository.java
new file mode 100644
index 000000000..3b2186b23
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/KeyRepository.java
@@ -0,0 +1,586 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.security.PublicKey;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.x509.X500Name;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.EDBException;
+import com.netscape.certsrv.dbs.IDBRegistry;
+import com.netscape.certsrv.dbs.IDBSSession;
+import com.netscape.certsrv.dbs.IDBSearchResults;
+import com.netscape.certsrv.dbs.IDBSubsystem;
+import com.netscape.certsrv.dbs.Modification;
+import com.netscape.certsrv.dbs.ModificationSet;
+import com.netscape.certsrv.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRecordList;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.dbs.repository.IRepository;
+
+/**
+ * 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));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_CLIENT_ID)) {
+ reg.registerAttribute(KeyRecord.ATTR_CLIENT_ID, new
+ StringMapper(KeyDBSchema.LDAP_ATTR_CLIENT_ID));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_STATUS)) {
+ reg.registerAttribute(KeyRecord.ATTR_STATUS, new
+ StringMapper(KeyDBSchema.LDAP_ATTR_STATUS));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_DATA_TYPE)) {
+ reg.registerAttribute(KeyRecord.ATTR_DATA_TYPE, new
+ StringMapper(KeyDBSchema.LDAP_ATTR_DATA_TYPE));
+ }
+
+ }
+
+ 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<IKeyRecord> e = list.getKeyRecords(0, size - 1);
+ while (e.hasMoreElements()) {
+ IKeyRecord rec = 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<IKeyRecord> searchKeys(String filter, int maxSize)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Vector<IKeyRecord> v = new Vector<IKeyRecord>();
+
+ try {
+ IDBSearchResults sr = s.search(getDN(), filter, maxSize);
+ while (sr.hasMoreElements()) {
+ v.add((IKeyRecord) sr.nextElement());
+ }
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return v.elements();
+ }
+
+ public Enumeration<IKeyRecord> searchKeys(String filter, int maxSize, int timeLimit)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Vector<IKeyRecord> v = new Vector<IKeyRecord>();
+
+ try {
+ IDBSearchResults sr = s.search(getDN(), filter, maxSize, timeLimit);
+ while (sr.hasMoreElements()) {
+ v.add((IKeyRecord) sr.nextElement());
+ }
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return v.elements();
+ }
+
+ /**
+ * 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.<IKeyRecord>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.<IKeyRecord>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();
+
+ 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/base/common/src/com/netscape/cmscore/dbs/KeyStateMapper.java b/base/common/src/com/netscape/cmscore/dbs/KeyStateMapper.java
new file mode 100644
index 000000000..2622cdbc6
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/KeyStateMapper.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.util.Enumeration;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBAttrMapper;
+import com.netscape.certsrv.dbs.IDBObj;
+import com.netscape.certsrv.dbs.keydb.KeyState;
+
+/**
+ * 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<String> getSupportedLDAPAttributeNames() {
+ Vector<String> v = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cmscore/dbs/LdapFilterConverter.java b/base/common/src/com/netscape/cmscore/dbs/LdapFilterConverter.java
new file mode 100644
index 000000000..ff867bf52
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/LdapFilterConverter.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.cmscore.dbs;
+
+import java.util.Hashtable;
+
+import com.netscape.certsrv.base.AttributeNameHelper;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBAttrMapper;
+import com.netscape.certsrv.dbs.IFilterConverter;
+
+/**
+ * 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<String, IDBAttrMapper> mReg = null;
+
+ /**
+ * Constructs filter convertor.
+ */
+ public LdapFilterConverter(Hashtable<String, IDBAttrMapper> 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/base/common/src/com/netscape/cmscore/dbs/LongMapper.java b/base/common/src/com/netscape/cmscore/dbs/LongMapper.java
new file mode 100644
index 000000000..b4d6c75d6
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/LongMapper.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.Enumeration;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBAttrMapper;
+import com.netscape.certsrv.dbs.IDBObj;
+
+/**
+ * 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<String> v = new Vector<String>();
+
+ /**
+ * Constructs Long mapper.
+ */
+ public LongMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Returns a list of supported ldap attribute names.
+ */
+ public Enumeration<String> 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/base/common/src/com/netscape/cmscore/dbs/MetaInfoMapper.java b/base/common/src/com/netscape/cmscore/dbs/MetaInfoMapper.java
new file mode 100644
index 000000000..9b224508c
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/MetaInfoMapper.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.dbs;
+
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.MetaInfo;
+import com.netscape.certsrv.dbs.IDBAttrMapper;
+import com.netscape.certsrv.dbs.IDBObj;
+
+/**
+ * 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<String> v = new Vector<String>();
+
+ /**
+ * Constructs a metainfo object.
+ */
+ public MetaInfoMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Returns a list of supported ldap attribute names.
+ */
+ public Enumeration<String> 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<String> e = info.getElements();
+
+ if (!e.hasMoreElements())
+ return; // dont add anything
+ LDAPAttribute attr = new LDAPAttribute(mLdapName);
+
+ while (e.hasMoreElements()) {
+ String s = null;
+ String attrName = 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;
+ @SuppressWarnings("unchecked")
+ Enumeration<String> values = attr.getStringValues();
+ MetaInfo info = new MetaInfo();
+
+ while (values.hasMoreElements()) {
+ String s = 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/base/common/src/com/netscape/cmscore/dbs/ObjectStreamMapper.java b/base/common/src/com/netscape/cmscore/dbs/ObjectStreamMapper.java
new file mode 100644
index 000000000..f77a36ed4
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/ObjectStreamMapper.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.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.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+
+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<String> v = new Vector<String>();
+ 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<String> 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/base/common/src/com/netscape/cmscore/dbs/PublicKeyMapper.java b/base/common/src/com/netscape/cmscore/dbs/PublicKeyMapper.java
new file mode 100644
index 000000000..8b66d02ca
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/PublicKeyMapper.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.cmscore.dbs;
+
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBAttrMapper;
+import com.netscape.certsrv.dbs.IDBObj;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cmscore.cert.CertUtils;
+
+/**
+ * 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<String> v = new Vector<String>();
+
+ 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<String> 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;
+ }
+
+ 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/base/common/src/com/netscape/cmscore/dbs/ReplicaIDRepository.java b/base/common/src/com/netscape/cmscore/dbs/ReplicaIDRepository.java
new file mode 100644
index 000000000..46ab07385
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/ReplicaIDRepository.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.dbs;
+
+import java.math.BigInteger;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.EDBException;
+import com.netscape.certsrv.dbs.IDBSubsystem;
+import com.netscape.certsrv.dbs.replicadb.IReplicaIDRepository;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/dbs/Repository.java b/base/common/src/com/netscape/cmscore/dbs/Repository.java
new file mode 100644
index 000000000..aadfb888a
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/Repository.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.cmscore.dbs;
+
+import java.math.BigInteger;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.EDBException;
+import com.netscape.certsrv.dbs.IDBObj;
+import com.netscape.certsrv.dbs.IDBSSession;
+import com.netscape.certsrv.dbs.IDBSubsystem;
+import com.netscape.certsrv.dbs.Modification;
+import com.netscape.certsrv.dbs.ModificationSet;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.dbs.replicadb.IReplicaIDRepository;
+import com.netscape.certsrv.dbs.repository.IRepository;
+import com.netscape.certsrv.dbs.repository.IRepositoryRecord;
+
+/**
+ * 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();
+ 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/base/common/src/com/netscape/cmscore/dbs/RepositoryRecord.java b/base/common/src/com/netscape/cmscore/dbs/RepositoryRecord.java
new file mode 100644
index 000000000..8f90723cd
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/RepositoryRecord.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.BigInteger;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.repository.IRepositoryRecord;
+
+/**
+ * A class represents a repository record.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class RepositoryRecord implements IRepositoryRecord {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1648450747848783853L;
+ private BigInteger mSerialNo = null;
+ private String mPublishingStatus = null;
+
+ protected static Vector<String> mNames = new Vector<String>();
+ 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<String> getElements() {
+ return mNames.elements();
+ }
+
+ public Enumeration<String> getSerializableAttrNames() {
+ return mNames.elements();
+ }
+
+ /**
+ * Retrieves serial number.
+ */
+ public BigInteger getSerialNumber() {
+ return mSerialNo;
+ }
+
+ public String getPublishingStatus() {
+ return mPublishingStatus;
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/dbs/RepositorySchema.java b/base/common/src/com/netscape/cmscore/dbs/RepositorySchema.java
new file mode 100644
index 000000000..4a0cf4155
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/RepositorySchema.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.cmscore.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/base/common/src/com/netscape/cmscore/dbs/RevocationInfo.java b/base/common/src/com/netscape/cmscore/dbs/RevocationInfo.java
new file mode 100644
index 000000000..00ca0034b
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/RevocationInfo.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.cmscore.dbs;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLReasonExtension;
+
+import com.netscape.certsrv.dbs.certdb.IRevocationInfo;
+
+/**
+ * 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 static final long serialVersionUID = -157323417902547417L;
+ 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/base/common/src/com/netscape/cmscore/dbs/RevocationInfoMapper.java b/base/common/src/com/netscape/cmscore/dbs/RevocationInfoMapper.java
new file mode 100644
index 000000000..7cf39dcef
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/RevocationInfoMapper.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.cmscore.dbs;
+
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.Extension;
+import netscape.security.x509.InvalidityDateExtension;
+import netscape.security.x509.RevocationReason;
+
+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.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<String> mNames = new Vector<String>();
+ static {
+ mNames.addElement(CertDBSchema.LDAP_ATTR_REVO_INFO);
+ }
+
+ /**
+ * Constructs revocation information mapper.
+ */
+ public RevocationInfoMapper() {
+ }
+
+ public Enumeration<String> 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<Extension> e = exts.getElements();
+
+ while (e.hasMoreElements()) {
+ Extension ext = 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/base/common/src/com/netscape/cmscore/dbs/StringMapper.java b/base/common/src/com/netscape/cmscore/dbs/StringMapper.java
new file mode 100644
index 000000000..710a17875
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/StringMapper.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.cmscore.dbs;
+
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBAttrMapper;
+import com.netscape.certsrv.dbs.IDBObj;
+
+/**
+ * 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<String> v = new Vector<String>();
+
+ /**
+ * Constructs string mapper.
+ */
+ public StringMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Retrieves a list of supported ldap attributes.
+ */
+ public Enumeration<String> 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/base/common/src/com/netscape/cmscore/dbs/StringVectorMapper.java b/base/common/src/com/netscape/cmscore/dbs/StringVectorMapper.java
new file mode 100644
index 000000000..7a465231b
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/StringVectorMapper.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.util.Enumeration;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBAttrMapper;
+import com.netscape.certsrv.dbs.IDBObj;
+
+/**
+ * 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<String> v = new Vector<String>();
+
+ /**
+ * Constructs string vector mapper.
+ */
+ public StringVectorMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Retrieves a list of supported ldap attributes.
+ */
+ public Enumeration<String> getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps attribute value to ldap attributes.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ @SuppressWarnings("unchecked")
+ Vector<String> v = (Vector<String>) obj;
+ int s = v.size();
+
+ if (s == 0) {
+ return;
+ }
+ String m[] = new String[s];
+
+ for (int i = 0; i < s; i++) {
+ m[i] = 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;
+ @SuppressWarnings("unchecked")
+ Enumeration<String> e = attr.getStringValues();
+ Vector<String> v = new Vector<String>();
+
+ while (e.hasMoreElements()) {
+ v.addElement(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/base/common/src/com/netscape/cmscore/dbs/X500NameMapper.java b/base/common/src/com/netscape/cmscore/dbs/X500NameMapper.java
new file mode 100644
index 000000000..0bf3bf7da
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/X500NameMapper.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.io.IOException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.security.x509.X500Name;
+
+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 X500Name object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class X500NameMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector<String> v = new Vector<String>();
+
+ 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<String> 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/base/common/src/com/netscape/cmscore/dbs/X509CertImplMapper.java b/base/common/src/com/netscape/cmscore/dbs/X509CertImplMapper.java
new file mode 100644
index 000000000..18f0c8e3d
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/dbs/X509CertImplMapper.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.cmscore.dbs;
+
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.security.extensions.NSCertTypeExtension;
+import netscape.security.x509.BasicConstraintsExtension;
+import netscape.security.x509.Extension;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509Key;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.AttributeNameHelper;
+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.dbs.certdb.ICertRecord;
+
+/**
+ * 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<String> getSupportedLDAPAttributeNames() {
+ Vector<String> v = new Vector<String>();
+
+ 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<String> nonCritSet = cert.getNonCriticalExtensionOIDs();
+
+ if (nonCritSet != null) {
+ for (Iterator<String> i = nonCritSet.iterator(); i.hasNext();) {
+ String oid = 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<String> critSet = cert.getCriticalExtensionOIDs();
+
+ if (critSet != null) {
+ for (Iterator<String> i = critSet.iterator(); i.hasNext();) {
+ String oid = 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);
+
+ 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/base/common/src/com/netscape/cmscore/extensions/CMSExtensionsMap.java b/base/common/src/com/netscape/cmscore/extensions/CMSExtensionsMap.java
new file mode 100644
index 000000000..213772882
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/extensions/CMSExtensionsMap.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.cmscore.extensions;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import netscape.security.util.ObjectIdentifier;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.extensions.EExtensionsException;
+import com.netscape.certsrv.extensions.ICMSExtension;
+
+/**
+ * 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<String, ICMSExtension> mName2Ext = new Hashtable<String, ICMSExtension>();
+ private Hashtable<String, ICMSExtension> mOID2Ext = new Hashtable<String, ICMSExtension>();
+ 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<String> 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/base/common/src/com/netscape/cmscore/extensions/KeyUsage.java b/base/common/src/com/netscape/cmscore/extensions/KeyUsage.java
new file mode 100644
index 000000000..dc4423357
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/extensions/KeyUsage.java
@@ -0,0 +1,230 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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 netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.Extension;
+import netscape.security.x509.KeyUsageExtension;
+import netscape.security.x509.PKIXExtensions;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.extensions.EExtensionsException;
+import com.netscape.certsrv.extensions.ICMSExtension;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cmscore.util.Debug;
+
+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 {
+ 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;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cmscore/jobs/CronItem.java b/base/common/src/com/netscape/cmscore/jobs/CronItem.java
new file mode 100644
index 000000000..91574c6cc
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/jobs/CronItem.java
@@ -0,0 +1,168 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.StringTokenizer;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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<CronRange> mElements = new Vector<CronRange>();
+
+ 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<CronRange> 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/base/common/src/com/netscape/cmscore/jobs/CronRange.java b/base/common/src/com/netscape/cmscore/jobs/CronRange.java
new file mode 100644
index 000000000..af5ae2a51
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/jobs/CronRange.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.cmscore.jobs;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/jobs/JobCron.java b/base/common/src/com/netscape/cmscore/jobs/JobCron.java
new file mode 100644
index 000000000..164c1250e
--- /dev/null
+++ b/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 java.util.Calendar;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.jobs.IJobCron;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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<CronRange> item) {
+ // loop through all of the elements of an item
+ for (Enumeration<CronRange> e = item.elements(); e.hasMoreElements();) {
+ CronRange cElement = 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/base/common/src/com/netscape/cmscore/jobs/JobsScheduler.java b/base/common/src/com/netscape/cmscore/jobs/JobsScheduler.java
new file mode 100644
index 000000000..b35f8c340
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/jobs/JobsScheduler.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.cmscore.jobs;
+
+import java.util.Calendar;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.jobs.EJobsException;
+import com.netscape.certsrv.jobs.IJob;
+import com.netscape.certsrv.jobs.IJobCron;
+import com.netscape.certsrv.jobs.IJobsScheduler;
+import com.netscape.certsrv.jobs.JobPlugin;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cmscore.util.Debug;
+
+/**
+ * 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<String, JobPlugin> mJobPlugins = new Hashtable<String, JobPlugin>();
+ public Hashtable<String, IJob> mJobs = new Hashtable<String, IJob>();
+ private Hashtable<String, Thread> mJobThreads = new Hashtable<String, Thread>();
+
+ 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<String> mImpls = c.getSubStoreNames();
+
+ // register all job plugins
+ while (mImpls.hasMoreElements()) {
+ String id = 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<String> jobs = c.getSubStoreNames();
+
+ while (jobs.hasMoreElements()) {
+ String jobName = jobs.nextElement();
+ String implName = c.getString(jobName + "." + PROP_PLUGIN);
+ JobPlugin plugin = 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
+ try {
+ IJob 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) {
+ 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) {
+ 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) {
+ 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<String, JobPlugin> getPlugins() {
+ return mJobPlugins;
+ }
+
+ public Hashtable<String, IJob> 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;
+ 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);
+ }
+ }
+
+ // 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();
+
+ for (Enumeration<IJob> e = mJobs.elements(); e.hasMoreElements(); ) {
+ IJob job = 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 = 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<CronRange> moy =
+ jcron.getItem(JobCron.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<CronRange> dow = jcron.getItem(JobCron.CRON_DAY_OF_WEEK).getElements();
+ Vector<CronRange> dom = jcron.getItem(JobCron.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<CronRange> hour = jcron.getItem(JobCron.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<CronRange> minute = jcron.getItem(JobCron.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() {
+ for (IJob job : mJobs.values()) {
+ job.stop();
+ }
+ }
+
+ /**
+ * 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 = 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
+ String className = plugin.getClassPath();
+
+ if (Debug.ON)
+ Debug.trace("className = " + className);
+ try {
+ IJob 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);
+ 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);
+ 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);
+ 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<String, JobPlugin> getJobPlugins() {
+ return mJobPlugins;
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/ldap/LdapAndExpression.java b/base/common/src/com/netscape/cmscore/ldap/LdapAndExpression.java
new file mode 100644
index 000000000..3d7e7f31d
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/ldap/LdapAndExpression.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.ldap;
+
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.publish.ILdapExpression;
+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 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/base/common/src/com/netscape/cmscore/ldap/LdapConnModule.java b/base/common/src/com/netscape/cmscore/ldap/LdapConnModule.java
new file mode 100644
index 000000000..7dd282140
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/ldap/LdapConnModule.java
@@ -0,0 +1,132 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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 netscape.ldap.LDAPConnection;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ILdapBoundConnFactory;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.ldap.ILdapConnInfo;
+import com.netscape.certsrv.ldap.ILdapConnModule;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cmscore.ldapconn.LdapAuthInfo;
+import com.netscape.cmscore.ldapconn.LdapBoundConnFactory;
+import com.netscape.cmscore.ldapconn.LdapConnInfo;
+
+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/base/common/src/com/netscape/cmscore/ldap/LdapOrExpression.java b/base/common/src/com/netscape/cmscore/ldap/LdapOrExpression.java
new file mode 100644
index 000000000..011e3e690
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/ldap/LdapOrExpression.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.ldap;
+
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.publish.ILdapExpression;
+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 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/base/common/src/com/netscape/cmscore/ldap/LdapPredicateParser.java b/base/common/src/com/netscape/cmscore/ldap/LdapPredicateParser.java
new file mode 100644
index 000000000..469ba62a0
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/ldap/LdapPredicateParser.java
@@ -0,0 +1,340 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.publish.ILdapExpression;
+import com.netscape.cmscore.util.Debug;
+
+/**
+ * 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();
+
+ 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<ILdapExpression> expSet = new Vector<ILdapExpression>();
+ 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<LdapSimpleExpression> expVector = new Vector<LdapSimpleExpression>();
+
+ 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;
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/ldap/LdapPublishModule.java b/base/common/src/com/netscape/cmscore/ldap/LdapPublishModule.java
new file mode 100644
index 000000000..bbe86e8a5
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/ldap/LdapPublishModule.java
@@ -0,0 +1,782 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.IOException;
+import java.math.BigInteger;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import netscape.ldap.LDAPConnection;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CRLImpl;
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.base.MetaInfo;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.Modification;
+import com.netscape.certsrv.dbs.ModificationSet;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.ILdapMapper;
+import com.netscape.certsrv.publish.ILdapPlugin;
+import com.netscape.certsrv.publish.ILdapPublishModule;
+import com.netscape.certsrv.publish.ILdapPublisher;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestListener;
+import com.netscape.cmscore.dbs.CertRecord;
+import com.netscape.cmscore.ldapconn.LdapBoundConnFactory;
+import com.netscape.cmscore.util.Debug;
+
+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<String, LdapMappers> mMappers = new Hashtable<String, LdapMappers>();
+
+ /**
+ * handlers for request types (events)
+ * values implement IRequestListener
+ */
+ protected Hashtable<String, IRequestListener> mEventHandlers = new Hashtable<String, IRequestListener>();
+
+ /**
+ * 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<String> substores = types.getSubStoreNames();
+
+ while (substores.hasMoreElements()) {
+ String certType = 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();
+
+ IRequestListener handler = 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 {
+
+ 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];
+
+ 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()));
+ }
+ }
+ 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()));
+ }
+ }
+ r.setExtData("ldapPublishStatus", results);
+ r.setExtData("ldapPublishOverAllStatus",
+ (error == true ? IRequest.RES_ERROR : IRequest.RES_SUCCESS));
+ }
+
+}
diff --git a/base/common/src/com/netscape/cmscore/ldap/LdapRequestListener.java b/base/common/src/com/netscape/cmscore/ldap/LdapRequestListener.java
new file mode 100644
index 000000000..cbeeed2df
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/ldap/LdapRequestListener.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.ldap;
+
+import java.math.BigInteger;
+import java.security.cert.Certificate;
+import java.util.Hashtable;
+
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.base.MetaInfo;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestListener;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.cmscore.dbs.CertRecord;
+
+public class LdapRequestListener implements IRequestListener {
+ private boolean mInited = false;
+
+ /**
+ * handlers for request types (events)
+ * each handler implement IRequestListener
+ */
+ private Hashtable<String, IRequestListener> mRequestListeners = new Hashtable<String, IRequestListener>();
+
+ 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 = 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/base/common/src/com/netscape/cmscore/ldap/LdapRule.java b/base/common/src/com/netscape/cmscore/ldap/LdapRule.java
new file mode 100644
index 000000000..0f0c3a3b9
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/ldap/LdapRule.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.ldap;
+
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.publish.ILdapExpression;
+import com.netscape.certsrv.publish.ILdapRule;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.cmscore.util.Debug;
+
+/**
+ * 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<String> mappers = mProcessor.getMapperInsts().keys();
+ Enumeration<String> publishers = mProcessor.getPublisherInsts().keys();
+
+ String map = NOMAPPER;
+
+ for (; mappers.hasMoreElements();) {
+ String name = mappers.nextElement();
+
+ map = map + "," + name;
+ }
+ String publish = "";
+
+ for (; publishers.hasMoreElements();) {
+ String name = 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<String> getInstanceParams() {
+ //if (mProcessor == null) System.out.println("xxxxnull");
+ //dont know why the processor was null in getExtendedPluginInfo()
+ Enumeration<String> mappers = mProcessor.getMapperInsts().keys();
+ Enumeration<String> 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<String> v = new Vector<String>();
+
+ 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<String> getDefaultParams() {
+ Vector<String> v = new Vector<String>();
+
+ 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/base/common/src/com/netscape/cmscore/ldap/LdapSimpleExpression.java b/base/common/src/com/netscape/cmscore/ldap/LdapSimpleExpression.java
new file mode 100644
index 000000000..0a1dde49f
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/ldap/LdapSimpleExpression.java
@@ -0,0 +1,473 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.Enumeration;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.publish.ILdapExpression;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cmscore.util.AssertionException;
+
+/**
+ * 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<Object> value)
+ throws ELdapException {
+ boolean result = false;
+ Enumeration<Object> e = (Enumeration<Object>) 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(value[i]);
+ if (result)
+ break;
+ }
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ 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<Object>) 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/base/common/src/com/netscape/cmscore/ldap/PublishObject.java b/base/common/src/com/netscape/cmscore/ldap/PublishObject.java
new file mode 100644
index 000000000..940330d6d
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/ldap/PublishObject.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.cmscore.ldap;
+
+import netscape.security.x509.X509CRLImpl;
+import netscape.security.x509.X509CertImpl;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/ldap/PublisherProcessor.java b/base/common/src/com/netscape/cmscore/ldap/PublisherProcessor.java
new file mode 100644
index 000000000..453703443
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/ldap/PublisherProcessor.java
@@ -0,0 +1,1498 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.math.BigInteger;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import netscape.ldap.LDAPConnection;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CRLImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.base.MetaInfo;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.Modification;
+import com.netscape.certsrv.dbs.ModificationSet;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ILdapConnModule;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.publish.ILdapExpression;
+import com.netscape.certsrv.publish.ILdapMapper;
+import com.netscape.certsrv.publish.ILdapPublisher;
+import com.netscape.certsrv.publish.ILdapRule;
+import com.netscape.certsrv.publish.IPublisherProcessor;
+import com.netscape.certsrv.publish.IXcertPublisherProcessor;
+import com.netscape.certsrv.publish.MapperPlugin;
+import com.netscape.certsrv.publish.MapperProxy;
+import com.netscape.certsrv.publish.PublisherPlugin;
+import com.netscape.certsrv.publish.PublisherProxy;
+import com.netscape.certsrv.publish.RulePlugin;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestNotifier;
+import com.netscape.cmscore.dbs.CertRecord;
+import com.netscape.cmscore.util.Debug;
+
+public class PublisherProcessor implements
+ IPublisherProcessor, IXcertPublisherProcessor {
+
+ public Hashtable<String, PublisherPlugin> mPublisherPlugins = new Hashtable<String, PublisherPlugin>();
+ public Hashtable<String, PublisherProxy> mPublisherInsts = new Hashtable<String, PublisherProxy>();
+ public Hashtable<String, MapperPlugin> mMapperPlugins = new Hashtable<String, MapperPlugin>();
+ public Hashtable<String, MapperProxy> mMapperInsts = new Hashtable<String, MapperProxy>();
+ public Hashtable<String, RulePlugin> mRulePlugins = new Hashtable<String, RulePlugin>();
+ public Hashtable<String, ILdapRule> mRuleInsts = new Hashtable<String, ILdapRule>();
+
+ /**
+ * 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<String> 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<String> 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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<String, RulePlugin> getRulePlugins() {
+ return mRulePlugins;
+ }
+
+ public Hashtable<String, ILdapRule> getRuleInsts() {
+ return mRuleInsts;
+ }
+
+ public Hashtable<String, MapperPlugin> getMapperPlugins() {
+ return mMapperPlugins;
+ }
+
+ public Hashtable<String, PublisherPlugin> getPublisherPlugins() {
+ return mPublisherPlugins;
+ }
+
+ public Hashtable<String, MapperProxy> getMapperInsts() {
+ return mMapperInsts;
+ }
+
+ public Hashtable<String, PublisherProxy> getPublisherInsts() {
+ return mPublisherInsts;
+ }
+
+ //certType can be client,server,ca,crl,smime
+ //XXXshould make it static to make it faster
+ public Enumeration<ILdapRule> getRules(String publishingType) {
+ Vector<ILdapRule> rules = new Vector<ILdapRule>();
+ Enumeration<String> 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<ILdapRule> getRules(String publishingType, IRequest req) {
+ if (req == null) {
+ return getRules(publishingType);
+ }
+
+ Vector<ILdapRule> rules = new Vector<ILdapRule>();
+ Enumeration<String> 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<String> getMapperDefaultParams(String implName) throws
+ ELdapException {
+ // is this a registered implname?
+ MapperPlugin plugin = 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<String> 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<String> getMapperInstanceParams(String insName) throws
+ ELdapException {
+ ILdapMapper mapperInst = null;
+ MapperProxy proxy = mMapperInsts.get(insName);
+
+ if (proxy == null) {
+ return null;
+ }
+ mapperInst = proxy.getMapper();
+ if (mapperInst == null) {
+ return null;
+ }
+ Vector<String> v = mapperInst.getInstanceParams();
+
+ return v;
+ }
+
+ public Vector<String> getPublisherDefaultParams(String implName) throws
+ ELdapException {
+ // is this a registered implname?
+ PublisherPlugin plugin = 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<String> 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<String> getPublisherInstanceParams(String insName) throws
+ ELdapException {
+ ILdapPublisher publisherInst = getPublisherInstance(insName);
+
+ if (publisherInst == null) {
+ return null;
+ }
+ Vector<String> v = publisherInst.getInstanceParams();
+
+ return v;
+ }
+
+ public Vector<String> getRuleDefaultParams(String implName) throws
+ ELdapException {
+ // is this a registered implname?
+ RulePlugin plugin = 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<String> 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<String> getRuleInstanceParams(String implName) throws
+ ELdapException {
+ // is this a registered implname?
+ RulePlugin plugin = 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<String> v = ruleInst.getInstanceParams();
+
+ 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
+ + " 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<ILdapRule> 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);
+ error = true;
+ errorRule = errorRule + " " + rule.getInstanceName() +
+ " error:" + e;
+ }
+ }
+ // 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<ILdapRule> 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 {
+ String errorRule = "";
+
+ if (!enabled())
+ return;
+ CMS.debug("PublisherProcessor: in publishXCertPair()");
+
+ // get mapper and publisher for cert type.
+ Enumeration<ILdapRule> 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());
+ errorRule = errorRule + " " + rule.getInstanceName() +
+ " error:" + e;
+
+ CMS.debug("PublisherProcessor::publishXCertPair: error: " + e);
+ }
+ }
+ }
+
+ /**
+ * 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<ILdapRule> 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,exiting routine.");
+
+ error = true;
+ errorRule = "No rules enabled";
+ }
+
+ while (rules != null && 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<ILdapRule> 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<ILdapRule> 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);
+ }
+ }
+ } 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<ILdapRule> 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);
+ error = true;
+ errorRule = errorRule + " " + rule.getInstanceName();
+ CMS.debug("PublisherProcessor::publishCRL: error: " + e);
+ }
+ }
+ } catch (ELdapException e) {
+ 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));
+ }
+
+ 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) {
+ 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) {
+ @SuppressWarnings("unchecked")
+ Vector<String> dirdnVector = (Vector<String>) dirdn;
+ int n = dirdnVector.size();
+ for (int i = 0; i < n; i++) {
+ publisher.publish(conn, dirdnVector.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) {
+ 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) {
+ 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/base/common/src/com/netscape/cmscore/ldapconn/LdapAnonConnFactory.java b/base/common/src/com/netscape/cmscore/ldapconn/LdapAnonConnFactory.java
new file mode 100644
index 000000000..dc4c86547
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/ldapconn/LdapAnonConnFactory.java
@@ -0,0 +1,467 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.LDAPConnection;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSocketFactory;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ELdapServerDownException;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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.");
+ }
+ // 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.");
+ }
+ }
+
+ // 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 {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4813780131074412404L;
+
+ 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/base/common/src/com/netscape/cmscore/ldapconn/LdapAnonConnection.java b/base/common/src/com/netscape/cmscore/ldapconn/LdapAnonConnection.java
new file mode 100644
index 000000000..1dc9723a8
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/ldapconn/LdapAnonConnection.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.ldapconn;
+
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSocketFactory;
+import netscape.ldap.LDAPv2;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6671180208419384682L;
+
+ /**
+ * 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/base/common/src/com/netscape/cmscore/ldapconn/LdapAuthInfo.java b/base/common/src/com/netscape/cmscore/ldapconn/LdapAuthInfo.java
new file mode 100644
index 000000000..b1af367b9
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/ldapconn/LdapAuthInfo.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.cmscore.ldapconn;
+
+import java.util.Hashtable;
+
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPException;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ldap.ILdapAuthInfo;
+import com.netscape.cmsutil.password.IPasswordStore;
+
+/**
+ * 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<String, String> passwords = new Hashtable<String, String>();
+
+ /**
+ * 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] = 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/base/common/src/com/netscape/cmscore/ldapconn/LdapBoundConnFactory.java b/base/common/src/com/netscape/cmscore/ldapconn/LdapBoundConnFactory.java
new file mode 100644
index 000000000..b4839f7d5
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/ldapconn/LdapBoundConnFactory.java
@@ -0,0 +1,529 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.LDAPConnection;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSocketFactory;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ELdapServerDownException;
+import com.netscape.certsrv.ldap.ILdapBoundConnFactory;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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.");
+ }
+ for (int i = 0; i < mNumConns; i++) {
+ if (mConns[i] == conn) {
+ CMS.debug(
+ "returnConn: previously returned connection.");
+ }
+ }
+ 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 {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1353616391879078337L;
+
+ 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/base/common/src/com/netscape/cmscore/ldapconn/LdapBoundConnection.java b/base/common/src/com/netscape/cmscore/ldapconn/LdapBoundConnection.java
new file mode 100644
index 000000000..fc97ab48c
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/ldapconn/LdapBoundConnection.java
@@ -0,0 +1,220 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.Properties;
+
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPRebind;
+import netscape.ldap.LDAPRebindAuth;
+import netscape.ldap.LDAPSocketFactory;
+import netscape.ldap.LDAPv2;
+
+import com.netscape.certsrv.apps.CMS;
+
+/**
+ * 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 {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2242077674357271559L;
+ // 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/base/common/src/com/netscape/cmscore/ldapconn/LdapConnInfo.java b/base/common/src/com/netscape/cmscore/ldapconn/LdapConnInfo.java
new file mode 100644
index 000000000..4ef7d804c
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/ldapconn/LdapConnInfo.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.ldapconn;
+
+import netscape.ldap.LDAPv2;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ILdapConnInfo;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/ldapconn/LdapJssSSLSocketFactory.java b/base/common/src/com/netscape/cmscore/ldapconn/LdapJssSSLSocketFactory.java
new file mode 100644
index 000000000..4df2fe357
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/ldapconn/LdapJssSSLSocketFactory.java
@@ -0,0 +1,109 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.io.IOException;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSSLSocketFactoryExt;
+
+import org.mozilla.jss.ssl.SSLHandshakeCompletedEvent;
+import org.mozilla.jss.ssl.SSLHandshakeCompletedListener;
+import org.mozilla.jss.ssl.SSLSocket;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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);
+ //TODO Do we really want to set the default each time?
+ SSLSocket.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/base/common/src/com/netscape/cmscore/listeners/ListenerPlugin.java b/base/common/src/com/netscape/cmscore/listeners/ListenerPlugin.java
new file mode 100644
index 000000000..baedb98de
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/listeners/ListenerPlugin.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.listeners;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/logging/AuditEventFactory.java b/base/common/src/com/netscape/cmscore/logging/AuditEventFactory.java
new file mode 100644
index 000000000..438b3abb9
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/logging/AuditEventFactory.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.cmscore.logging;
+
+import java.util.Properties;
+
+import com.netscape.certsrv.logging.AuditEvent;
+import com.netscape.certsrv.logging.IBundleLogEvent;
+import com.netscape.certsrv.logging.ILogEvent;
+import com.netscape.certsrv.logging.ILogEventFactory;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/logging/AuditFormat.java b/base/common/src/com/netscape/cmscore/logging/AuditFormat.java
new file mode 100644
index 000000000..a5ce83251
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/logging/AuditFormat.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.logging;
+
+import com.netscape.certsrv.logging.ILogger;
+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/base/common/src/com/netscape/cmscore/logging/LogQueue.java b/base/common/src/com/netscape/cmscore/logging/LogQueue.java
new file mode 100644
index 000000000..90ca05d81
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/logging/LogQueue.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.logging;
+
+import java.util.Vector;
+
+import com.netscape.certsrv.logging.ELogException;
+import com.netscape.certsrv.logging.ILogEvent;
+import com.netscape.certsrv.logging.ILogEventListener;
+import com.netscape.certsrv.logging.ILogQueue;
+
+/**
+ * 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<ILogEventListener> 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<ILogEventListener>();
+
+ }
+
+ /**
+ * 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/base/common/src/com/netscape/cmscore/logging/LogSubsystem.java b/base/common/src/com/netscape/cmscore/logging/LogSubsystem.java
new file mode 100644
index 000000000..1cfce4e65
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/logging/LogSubsystem.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.cmscore.logging;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.logging.ELogException;
+import com.netscape.certsrv.logging.ILogEventListener;
+import com.netscape.certsrv.logging.ILogQueue;
+import com.netscape.certsrv.logging.ILogSubsystem;
+import com.netscape.certsrv.logging.LogPlugin;
+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<String, LogPlugin> mLogPlugins = new Hashtable<String, LogPlugin>();
+ public Hashtable<String, ILogEventListener> mLogInsts = new Hashtable<String, ILogEventListener>();
+
+ /**
+ * 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<String> 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<String> 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) {
+ throw new EBaseException(insName + ":Failed to instantiate class " + className);
+
+ } catch (IllegalAccessException e) {
+ throw new EBaseException(insName + ":Failed to instantiate class " + className);
+
+ } catch (InstantiationException e) {
+ 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 (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<String> 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<String, LogPlugin> getLogPlugins() {
+ return mLogPlugins;
+ }
+
+ public Hashtable<String, ILogEventListener> getLogInsts() {
+ return mLogInsts;
+ }
+
+ public Vector<String> 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<String> 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<String> getLogInstanceParams(String insName) throws
+ ELogException {
+ ILogEventListener logInst = getLogInstance(insName);
+
+ if (logInst == null) {
+ return null;
+ }
+ Vector<String> v = logInst.getInstanceParams();
+
+ return v;
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/logging/Logger.java b/base/common/src/com/netscape/cmscore/logging/Logger.java
new file mode 100644
index 000000000..79895e263
--- /dev/null
+++ b/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.util.Hashtable;
+import java.util.Properties;
+
+import com.netscape.certsrv.logging.ILogEvent;
+import com.netscape.certsrv.logging.ILogEventFactory;
+import com.netscape.certsrv.logging.ILogQueue;
+import com.netscape.certsrv.logging.ILogger;
+
+/**
+ * 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<Integer, ILogEventFactory> mFactories = new Hashtable<Integer, ILogEventFactory>();
+
+ /**
+ * 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(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 = mFactories.get(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/base/common/src/com/netscape/cmscore/logging/SignedAuditEventFactory.java b/base/common/src/com/netscape/cmscore/logging/SignedAuditEventFactory.java
new file mode 100644
index 000000000..48570cada
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/logging/SignedAuditEventFactory.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.logging;
+
+import java.util.Properties;
+
+import com.netscape.certsrv.logging.IBundleLogEvent;
+import com.netscape.certsrv.logging.ILogEvent;
+import com.netscape.certsrv.logging.ILogEventFactory;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.SignedAuditEvent;
+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/base/common/src/com/netscape/cmscore/logging/SignedAuditLogger.java b/base/common/src/com/netscape/cmscore/logging/SignedAuditLogger.java
new file mode 100644
index 000000000..acc2b866f
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/logging/SignedAuditLogger.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.cmscore.logging;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/logging/SystemEventFactory.java b/base/common/src/com/netscape/cmscore/logging/SystemEventFactory.java
new file mode 100644
index 000000000..dfe25f03f
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/logging/SystemEventFactory.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.cmscore.logging;
+
+import java.util.Properties;
+
+import com.netscape.certsrv.logging.IBundleLogEvent;
+import com.netscape.certsrv.logging.ILogEvent;
+import com.netscape.certsrv.logging.ILogEventFactory;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.SystemEvent;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/notification/EmailFormProcessor.java b/base/common/src/com/netscape/cmscore/notification/EmailFormProcessor.java
new file mode 100644
index 000000000..a057484cf
--- /dev/null
+++ b/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 java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.notification.IEmailFormProcessor;
+
+/**
+ * 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<String> mContent = new Vector<String>();
+ Hashtable<String, Object> 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<String, Object> 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<String> 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(s);
+ } 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);
+
+ 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<String> vec) {
+ String content = null;
+
+ Enumeration<String> e = vec.elements();
+
+ // initialize content with first element
+ if (e.hasMoreElements()) {
+ content = e.nextElement();
+ }
+
+ while (e.hasMoreElements()) {
+ String v = 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/base/common/src/com/netscape/cmscore/notification/EmailResolverKeys.java b/base/common/src/com/netscape/cmscore/notification/EmailResolverKeys.java
new file mode 100644
index 000000000..cd63841eb
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/notification/EmailResolverKeys.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.notification;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.notification.IEmailResolverKeys;
+
+/**
+ * Email resolver keys as input to email resolvers
+ * <P>
+ *
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class EmailResolverKeys implements IEmailResolverKeys {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8823197350102151516L;
+ private Hashtable<String, Object> mKeys = null;
+
+ public EmailResolverKeys() {
+ mKeys = new Hashtable<String, Object>();
+ }
+
+ /**
+ * 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 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 key names 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<String> getElements() {
+ return mKeys.keys();
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/notification/EmailTemplate.java b/base/common/src/com/netscape/cmscore/notification/EmailTemplate.java
new file mode 100644
index 000000000..bdc16a24e
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/notification/EmailTemplate.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.cmscore.notification;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.notification.IEmailTemplate;
+
+/**
+ * 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())) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_NOTIFY_TEMPLATE_NOT_EXIST", mTemplateFile));
+ return false;
+ }
+
+ /* create input stream */
+ FileReader input;
+
+ try {
+ input = new FileReader(template);
+ } catch (FileNotFoundException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_NOTIFY_TEMPLATE_NOT_FOUND", mTemplateFile));
+
+ return false;
+ }
+
+ /* load template */
+ mFileContents = loadFile(input);
+ if (mFileContents == null) {
+ 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) {
+ 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/base/common/src/com/netscape/cmscore/notification/ReqCertEmailResolver.java b/base/common/src/com/netscape/cmscore/notification/ReqCertEmailResolver.java
new file mode 100644
index 000000000..330621e7a
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/notification/ReqCertEmailResolver.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.cmscore.notification;
+
+import java.io.IOException;
+import java.security.cert.X509Certificate;
+
+import netscape.security.x509.X500Name;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.notification.ENotificationException;
+import com.netscape.certsrv.notification.IEmailResolver;
+import com.netscape.certsrv.notification.IEmailResolverKeys;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/notification/ReqCertSANameEmailResolver.java b/base/common/src/com/netscape/cmscore/notification/ReqCertSANameEmailResolver.java
new file mode 100644
index 000000000..68556dfc0
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/notification/ReqCertSANameEmailResolver.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.notification;
+
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.GeneralNameInterface;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.SubjectAlternativeNameExtension;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.notification.ENotificationException;
+import com.netscape.certsrv.notification.IEmailResolver;
+import com.netscape.certsrv.notification.IEmailResolverKeys;
+import com.netscape.certsrv.request.IRequest;
+
+/**
+ * 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<GeneralNameInterface> e = gn.elements();
+
+ while (e.hasMoreElements()) {
+ GeneralNameInterface gni = e.nextElement();
+
+ if (gni.getType() == GeneralNameInterface.NAME_RFC822) {
+ CMS.debug("got an subjectalternatename email");
+
+ String nameString = gni.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/base/common/src/com/netscape/cmscore/policy/AndExpression.java b/base/common/src/com/netscape/cmscore/policy/AndExpression.java
new file mode 100644
index 000000000..459660f1e
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/policy/AndExpression.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.cmscore.policy;
+
+import com.netscape.certsrv.policy.EPolicyException;
+import com.netscape.certsrv.policy.IExpression;
+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.
+ *
+ * @deprecated
+ * @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/base/common/src/com/netscape/cmscore/policy/GeneralNameUtil.java b/base/common/src/com/netscape/cmscore/policy/GeneralNameUtil.java
new file mode 100644
index 000000000..7c7162d0c
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/policy/GeneralNameUtil.java
@@ -0,0 +1,694 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.DNSName;
+import netscape.security.x509.EDIPartyName;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.GeneralNameInterface;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.IPAddressName;
+import netscape.security.x509.InvalidIPAddressException;
+import netscape.security.x509.OIDName;
+import netscape.security.x509.RFC822Name;
+import netscape.security.x509.URIName;
+import netscape.security.x509.X500Name;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.policy.IGeneralNameAsConstraintsConfig;
+import com.netscape.certsrv.policy.IGeneralNameConfig;
+import com.netscape.certsrv.policy.IGeneralNameUtil;
+import com.netscape.certsrv.policy.IGeneralNamesAsConstraintsConfig;
+import com.netscape.certsrv.policy.IGeneralNamesConfig;
+import com.netscape.certsrv.policy.ISubjAltNameConfig;
+import com.netscape.cmscore.util.Debug;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * Class that can be used to form general names from configuration file.
+ * Used by policies and extension commands.
+ * @deprecated
+ */
+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 = Utils.base64decode(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<String> 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<String> 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<String> 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<GeneralName> formGeneralNames(Object value)
+ throws EBaseException {
+ Vector<GeneralName> gns = new Vector<GeneralName>();
+ 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<String> 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<String> 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<String> 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<String> params) {
+ params.addElement(mNameDot + PROP_REQUEST_ATTR + "=" + mRequestAttr);
+ super.getInstanceParams(params);
+ }
+
+ public static void getDefaultParams(String name, Vector<String> 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<String> 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/base/common/src/com/netscape/cmscore/policy/GenericPolicyProcessor.java b/base/common/src/com/netscape/cmscore/policy/GenericPolicyProcessor.java
new file mode 100644
index 000000000..05f8e111a
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/policy/GenericPolicyProcessor.java
@@ -0,0 +1,1548 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.Hashtable;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.policy.EPolicyException;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.policy.IExpression;
+import com.netscape.certsrv.policy.IKeyArchivalPolicy;
+import com.netscape.certsrv.policy.IKeyRecoveryPolicy;
+import com.netscape.certsrv.policy.IPolicyProcessor;
+import com.netscape.certsrv.policy.IPolicyRule;
+import com.netscape.certsrv.policy.IPolicySet;
+import com.netscape.certsrv.policy.IRenewalPolicy;
+import com.netscape.certsrv.policy.IRevocationPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.cmscore.base.PropConfigStore;
+import com.netscape.cmscore.base.SubsystemRegistry;
+import com.netscape.cmscore.request.ARequestQueue;
+import com.netscape.cmscore.util.AssertionException;
+import com.netscape.cmscore.util.Debug;
+
+/**
+ * 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.
+ *
+ * @deprecated
+ * @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<String, IExpression> DEF_UNDELETABLE_POLICIES =
+ new Hashtable<String, IExpression>();
+
+ private String mId = "Policy";
+ private Vector<String> mPolicyOrder = new Vector<String>();
+ private Hashtable<String, RegisteredPolicy> mImplTable = new Hashtable<String, RegisteredPolicy>();
+ private Hashtable<String, PolicyInstance> mInstanceTable = new Hashtable<String, PolicyInstance>();
+ 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<String, IExpression> 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<String> 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";
+ }
+
+ public Enumeration<IPolicyRule> getPolicyImpls() {
+ Vector<IPolicyRule> impls = new Vector<IPolicyRule>();
+ Enumeration<RegisteredPolicy> enum1 = mImplTable.elements();
+ Enumeration<IPolicyRule> 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<String> getPolicyImplsInfo() {
+ Vector<String> impls = new Vector<String>();
+ Enumeration<RegisteredPolicy> enum1 = mImplTable.elements();
+ Enumeration<String> 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<String> getPolicyImplConfig(String id) {
+ IPolicyRule rp = getPolicyImpl(id);
+
+ if (rp == null)
+ return null;
+ Vector<String> v = rp.getDefaultParams();
+
+ if (v == null)
+ v = new Vector<String>();
+ 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<PolicyInstance> 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<IPolicyRule> getPolicyInstances() {
+ Vector<IPolicyRule> rules = new Vector<IPolicyRule>();
+ Enumeration<String> enum1 = mPolicyOrder.elements();
+ Enumeration<IPolicyRule> 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<String> getPolicyInstancesInfo() {
+ Vector<String> rules = new Vector<String>();
+ Enumeration<String> enum1 = mPolicyOrder.elements();
+ Enumeration<String> ret = null;
+
+ try {
+ while (enum1.hasMoreElements()) {
+ String ruleName = enum1.nextElement();
+ PolicyInstance instance = 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<String> getPolicyInstanceConfig(String id) {
+ PolicyInstance policyInstance = (PolicyInstance)
+ mInstanceTable.get(id);
+
+ if (policyInstance == null)
+ return null;
+ Vector<String> v = policyInstance.getRule().getInstanceParams();
+
+ if (v == null)
+ v = new Vector<String>();
+ 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<String, String> 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<String> keys = ht.keys(); keys.hasMoreElements();) {
+ String key = keys.nextElement();
+ String val = 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<String, String> 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<String> 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<String> 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<String> 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<String> policyOrder = new Vector<String>();
+ 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<String> 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<String> v1, Vector<String> 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<String> rules) {
+ StringBuffer sb = new StringBuffer();
+
+ for (Enumeration<String> 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<String> 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<String> rules = new Vector<String>();
+ 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<String> rules = new Vector<String>();
+ 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<String, IExpression>();
+ for (Enumeration<String> 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<String> 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;
+ }
+}
+
+/**
+ * @deprecated
+ */
+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/base/common/src/com/netscape/cmscore/policy/JavaScriptRequestProxy.java b/base/common/src/com/netscape/cmscore/policy/JavaScriptRequestProxy.java
new file mode 100644
index 000000000..1fbcf2738
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/policy/JavaScriptRequestProxy.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.cmscore.policy;
+
+import com.netscape.certsrv.policy.IPolicyRule;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+
+/**
+ *
+ * @deprecated
+ *
+ */
+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/base/common/src/com/netscape/cmscore/policy/OrExpression.java b/base/common/src/com/netscape/cmscore/policy/OrExpression.java
new file mode 100644
index 000000000..3b220c100
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/policy/OrExpression.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.cmscore.policy;
+
+import com.netscape.certsrv.policy.EPolicyException;
+import com.netscape.certsrv.policy.IExpression;
+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.
+ *
+ * @deprecated
+ * @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/base/common/src/com/netscape/cmscore/policy/PolicyPredicateParser.java b/base/common/src/com/netscape/cmscore/policy/PolicyPredicateParser.java
new file mode 100644
index 000000000..568a38e6d
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/policy/PolicyPredicateParser.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.cmscore.policy;
+
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.policy.EPolicyException;
+import com.netscape.certsrv.policy.IExpression;
+import com.netscape.cmscore.util.Debug;
+
+/**
+ * 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.
+ *
+ * @deprecated
+ * @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();
+
+ 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<IExpression> expSet = new Vector<IExpression>();
+ 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<SimpleExpression> expVector = new Vector<SimpleExpression>();
+
+ 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;
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/policy/PolicySet.java b/base/common/src/com/netscape/cmscore/policy/PolicySet.java
new file mode 100644
index 000000000..9e7ecdc64
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/policy/PolicySet.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.policy;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+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.
+ *
+ * @deprecated
+ * @author kanda
+ * @version $Revision$, $Date$
+ */
+public class PolicySet implements IPolicySet {
+ private String mName;
+ private Vector<String> mRuleNames = new Vector<String>();
+ private Vector<IPolicyRule> mRules = new Vector<IPolicyRule>();
+ 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<IPolicyRule> 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.
+
+ if (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/base/common/src/com/netscape/cmscore/policy/SimpleExpression.java b/base/common/src/com/netscape/cmscore/policy/SimpleExpression.java
new file mode 100644
index 000000000..892fd6451
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/policy/SimpleExpression.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.cmscore.policy;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.policy.EPolicyException;
+import com.netscape.certsrv.policy.IExpression;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cmscore.util.AssertionException;
+import com.netscape.cmscore.util.Debug;
+
+/**
+ * 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.
+ *
+ * @deprecated
+ * @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/base/common/src/com/netscape/cmscore/profile/ProfileSubsystem.java b/base/common/src/com/netscape/cmscore/profile/ProfileSubsystem.java
new file mode 100644
index 000000000..585af5600
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/profile/ProfileSubsystem.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.profile;
+
+import java.io.File;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileSubsystem;
+import com.netscape.certsrv.registry.IPluginInfo;
+import com.netscape.certsrv.registry.IPluginRegistry;
+
+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<String> mProfileIds = new Vector<String>();
+ private Hashtable<String, IProfile> mProfiles = new Hashtable<String, IProfile>();
+ private Hashtable<String, String> mProfileClassIds = new Hashtable<String, String>();
+
+ /**
+ * 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());
+ createProfile(id, classid, info.getClassName(),
+ configPath);
+
+ CMS.debug("Done Profile Creation - " + id);
+ }
+
+ Enumeration<String> 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 = 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 mProfiles.get(id);
+ }
+
+ public String getProfileClassId(String id) {
+ return mProfileClassIds.get(id);
+ }
+
+ /**
+ * Retrieves a list of profile ids. The return
+ * list is of type String.
+ */
+ public Enumeration<String> 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/base/common/src/com/netscape/cmscore/realm/ACL.java b/base/common/src/com/netscape/cmscore/realm/ACL.java
new file mode 100644
index 000000000..4d7303f9d
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/realm/ACL.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.cmscore.realm;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+/**
+ * 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 {
+
+ /**
+ *
+ */
+
+ protected Vector<ACLEntry> entries = new Vector<ACLEntry>(); // ACL entries
+ protected Vector<String> rights = null; // possible rights entries
+ protected String resourceACLs = null; // exact resourceACLs string on ldap server
+ protected String name = null; // resource name
+ protected String description = 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<String> rights, String resourceACLs) {
+ setName(name);
+ if (rights != null) {
+ this.rights = rights;
+ } else {
+ this.rights = new Vector<String>();
+ }
+ this.resourceACLs = resourceACLs;
+
+ }
+
+ /**
+ * Sets the name of the resource governed by this
+ * access control.
+ *
+ * @param name name of the resource
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Retrieves the name of the resource governed by
+ * this access control.
+ *
+ * @return name of the resource
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Retrieves the exact string of the resourceACLs
+ *
+ * @return resource's acl
+ */
+ public String getResourceACLs() {
+ return resourceACLs;
+ }
+
+ /**
+ * Sets the description of the resource governed by this
+ * access control.
+ *
+ * @param description Description of the protected resource
+ */
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ /**
+ * Retrieves the description of the resource governed by
+ * this access control.
+ *
+ * @return Description of the protected resource
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Adds an ACL entry to this list.
+ *
+ * @param entry the <code>ACLEntry</code> to be added to this resource
+ */
+ public void addEntry(ACLEntry entry) {
+ entries.addElement(entry);
+ }
+
+ /**
+ * Returns ACL entries.
+ *
+ * @return enumeration for the <code>ACLEntry</code> vector
+ */
+ public Enumeration<ACLEntry> entries() {
+ return entries.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<ACLEntry> 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) {
+ rights.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 (rights.contains((Object) permission));
+ }
+
+ /**
+ * Returns rights entries.
+ *
+ * @return enumeration of rights defined for this ACL
+ */
+ public Enumeration<String> rights() {
+ return rights.elements();
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/realm/ACLEntry.java b/base/common/src/com/netscape/cmscore/realm/ACLEntry.java
new file mode 100644
index 000000000..8e502b02c
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/realm/ACLEntry.java
@@ -0,0 +1,243 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.realm;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+
+/**
+ * A class represents an ACI entry of an access control list.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class ACLEntry {
+ /**
+ *
+ */
+ protected Hashtable<String, String> mPerms = new Hashtable<String, String>();
+ protected String expressions = null;
+ protected boolean negative = false;
+ protected String ACLEntryString = 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 negative;
+ }
+
+ /**
+ * Sets this ACL entry negative. This ACL entry expression is for "deny".
+ */
+ public void setNegative() {
+ negative = 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) {
+ ACLEntryString = 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 ACLEntryString;
+ }
+
+ /**
+ * 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(ACL 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<String> 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) {
+ this.expressions = expressions;
+ }
+
+ /**
+ * Retrieves the expression associated with this entry.
+ *
+ * @return the evaluator expressions. For example,
+ * group="Administrators"
+ */
+ public String getAttributeExpressions() {
+ return expressions;
+ }
+
+ /**
+ * 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(ACL 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<String> e = permissions();
+
+ for (; e.hasMoreElements();) {
+ String p = e.nextElement();
+
+ entry += p;
+ if (e.hasMoreElements())
+ entry += ",";
+ }
+ entry += ") " + getAttributeExpressions();
+ return entry;
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/realm/PKIJNDIRealm.java b/base/common/src/com/netscape/cmscore/realm/PKIJNDIRealm.java
new file mode 100644
index 000000000..720d9f52e
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/realm/PKIJNDIRealm.java
@@ -0,0 +1,943 @@
+package com.netscape.cmscore.realm;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.Principal;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.deploy.SecurityConstraint;
+import org.apache.catalina.realm.JNDIRealm;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.PartialResultException;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.servlet.http.HttpServletResponse;
+
+/*
+ * Self contained PKI JNDI Real that overrides the standard JNDI Realm
+ *
+ * The purpose is to move authentication and authorization code out of the core server.
+ * This realm can be used standalone with only the dependency of having tomcatjss and jss installed
+ * and having tomcatjss connectors configured in the tomcat instance.
+ *
+ * This realm allows for configurable SSL client authentication checking as well
+ * as checking against the standard PKI ACLs we have configured in our ldap database.
+ * Those not using a CS instance could either not configure the ACL checking or
+ * override this class to read in and evaluate their own ACL's.
+ *
+ * This code makes use and simplifies some existing ACL and authorization code
+ * from the main server for now.
+ *
+ */
+
+public class PKIJNDIRealm extends JNDIRealm {
+
+ private static final String DEF_CERT_ATTR = "userCert";
+ private static final String DEF_ACL_ATTR = "resource";
+
+ private static final String PROP_USER = "user";
+ private static final String PROP_GROUP = "group";
+ private static final String PROP_USER_ANYBODY = "anybody";
+ private static final String PROP_USER_EVERYBODY = "everybody";
+ private static final String CERT_VERSION = "2";
+ private static final String PROP_AUTH_FILE_PATH = "/WEB-INF/auth.properties";
+ private static final int EXPRESSION_SIZE = 2;
+
+ private Hashtable<String, ACL> acls = new Hashtable<String, ACL>();
+
+ private Properties authzProperties = null;
+
+ /* Look up the principal user based on the incoming client auth
+ * certificate.
+ * @param usercert Incoming client auth certificate presented by user
+ * @return Principal Object representing the authenticated user.
+ */
+ @Override
+ protected synchronized Principal getPrincipal(X509Certificate usercert) {
+
+ logDebug("Entering PKIJNDIRealm.getPrincipal");
+
+ if (usercert == null)
+ return null;
+
+ String uid = null;
+ String certUIDLabel = getCertUIDLabel();
+
+ if (certUIDLabel == null) {
+ // We have no uid label, attempt to construct a description
+
+ uid = CERT_VERSION + ";" + usercert.getSerialNumber() + ";"
+ + usercert.getIssuerDN() + ";" + usercert.getSubjectDN();
+
+ //The description field is devoid of spaces and the email label is E
+ //instead of EMAIL
+ uid = uid.replaceAll(", ", ",");
+ uid = uid.replaceAll("EMAILADDRESS", "E");
+
+ logDebug(uid);
+
+ } else {
+
+ String certUIDSrchStr = certUIDLabel + "=";
+
+ StringTokenizer dnTokens =
+ new StringTokenizer(usercert.getSubjectDN().getName(), ",");
+
+ while (dnTokens.hasMoreTokens()) {
+ String token = dnTokens.nextToken();
+ int index = token.indexOf(certUIDSrchStr);
+
+ if (index != -1) {
+ // Found the entry with the cert's UID
+
+ try {
+ uid = token.substring(index + certUIDSrchStr.length());
+ } catch (IndexOutOfBoundsException e) {
+ logErr("Out of Bounds Exception when attempting to extract UID from incomgin certificate.");
+ return null;
+ }
+
+ if (uid != null) {
+ break;
+ }
+ }
+ }
+ }
+
+ //Call the getPrincipal method of the base JNDIRealm class
+ //based on the just calculated uid. During the next call
+ // one of our methods to extract and store the user's ldap stored
+ //client cert will be invoked
+
+ Principal user = getPrincipal(uid);
+
+ //ToDo: Possibly perform some more cert verficiation
+ // such as OCSP, even though the tomcat jss connector
+ // can already be configured for OCSP
+
+ if (user != null) {
+ X509Certificate storedCert = getStoredUserCert();
+ setStoredUserCert(null);
+ //Compare the stored ldap cert with the incoming cert
+ if (usercert.equals(storedCert)) {
+ //Success, the incoming certificate matches the
+ //certificate stored in LDAP for this user.
+ return user;
+ }
+ }
+
+ setStoredUserCert(null);
+
+ return null;
+ }
+
+ /**
+ * Return a User object containing information about the user
+ * with the specified username, if found in the directory;
+ * otherwise return <code>null</code>.
+ * Override here to extract the client auth certificate from the
+ * ldap db.
+ *
+ * @param context The directory context
+ * @param username Username to be looked up
+ *
+ * @exception NamingException if a directory server error occurs
+ *
+ * @see #getUser(DirContext, String, String, int)
+ */
+ @Override
+ protected User getUser(DirContext context, String username)
+ throws NamingException {
+
+ //ToDo: Right now we support the Realm attribute
+ // userBase which only allows a single pattern from
+ // which to search for users in ldap.
+ // We need to use the "userPattern" attribute
+ // which supports multiple search patterns.
+ // This has not been done because the out of the box
+ // Support for SSL client auth does not appear to support
+ // the userPattern attribute. Certainly another method here
+ // could be overridden to get this working.
+
+ User certUser = super.getUser(context, username);
+
+ if (certUser != null) {
+ extractAndSaveStoredX509UserCert(context, certUser);
+ }
+
+ return certUser;
+ }
+
+ /**
+ * Perform access control based on the specified authorization constraint.
+ * Return <code>true</code> if this constraint is satisfied and processing
+ * should continue, or <code>false</code> otherwise.
+ * override to check for custom PKI ACL's authz permissions.
+ *
+ * @param request Request we are processing
+ * @param response Response we are creating
+ * @param constraints Security constraint we are enforcing
+ * @param context The Context to which client of this class is attached.
+ *
+ * @exception IOException if an input/output error occurs
+ */
+ @Override
+ public boolean hasResourcePermission(Request request,
+ Response response,
+ SecurityConstraint[] constraints,
+ Context context)
+ throws IOException {
+
+ boolean allowed = super.hasResourcePermission(request, response, constraints, context);
+
+ if (allowed == true && hasResourceACLS()) {
+
+ loadAuthzProperties(context);
+
+ if (hasAuthzProperties()) {
+ //Let's check against our encoded acls.
+
+ String requestURI = request.getDecodedRequestURI();
+ Principal principal = request.getPrincipal();
+
+ String match = getACLEntryDataForURL(requestURI);
+
+ if (match != null) {
+ //first part is the resourceID, second part is the operation
+ String[] authzParams = match.split("\\,");
+
+ String resourceID = null;
+ String operation = null;
+
+ if (authzParams.length >= EXPRESSION_SIZE) {
+ resourceID = authzParams[0];
+ operation = authzParams[1];
+
+ if (resourceID != null) {
+ resourceID = resourceID.trim();
+ }
+
+ if (operation != null) {
+ operation = operation.trim();
+ }
+ }
+
+ allowed = checkACLPermission(principal, resourceID, operation);
+ logDebug("resourceID: " + resourceID + " operation: " + operation + " allowed: " + allowed);
+ }
+ }
+ }
+
+ // Return a "Forbidden" message denying access to this resource
+ if (!allowed) {
+ response.sendError
+ (HttpServletResponse.SC_FORBIDDEN,
+ sm.getString("realmBase.forbidden"));
+ }
+
+ return allowed;
+ }
+
+ /**
+ * Return a List of roles associated with the given User. Any
+ * roles present in the user's directory entry are supplemented by
+ * a directory search. If no roles are associated with this user,
+ * a zero-length List is returned.
+ * Override here to get the PKI Resource ACLs if so configured
+ *
+ * @param context The directory context we are searching
+ * @param user The User to be checked
+ *
+ * @exception NamingException if a directory server error occurs
+ */
+
+ @Override
+ protected List<String> getRoles(DirContext context, User user)
+ throws NamingException {
+
+ try {
+ getResourceACLS(context);
+ } catch (NamingException e) {
+ logDebug("No aclResources found.");
+ }
+
+ return super.getRoles(context, user);
+ }
+
+ /* Custom variables, see <Realm> element */
+
+ /* Attribute to find encoded Cert in ldap
+ * "userCertificate" is most common value.
+ */
+ private String certAttrName;
+
+ public String getCertAttrName() {
+ return (certAttrName != null) ? certAttrName : DEF_CERT_ATTR;
+ }
+
+ public void setCertAttrName(String certAttrName) {
+ this.certAttrName = certAttrName;
+ }
+
+ /* Attribute to find encoded acl resources in ldap
+ * "aclResources" is most common value.
+ */
+ private String aclAttrName;
+
+ public String getAclAttrName() {
+ return (aclAttrName != null) ? aclAttrName : DEF_ACL_ATTR;
+ }
+
+ public void setAclAttrName(String aclAttrName) {
+ this.aclAttrName = aclAttrName;
+ }
+
+ /* Attribute for base dn of acl resources in ldap
+ */
+
+ private String aclBase;
+
+ public String getAclBase() {
+ return aclBase;
+ }
+
+ public void setAclBase(String aclBase) {
+ this.aclBase = aclBase;
+ }
+
+ /* Substring label to search for user id in presented client auth cert.
+ * "UID" is most common value.
+ */
+
+ private String certUIDLabel;
+
+ public String getCertUIDLabel() {
+ return certUIDLabel;
+ }
+
+ public void setCertUIDStr(String certUIDLabel) {
+ this.certUIDLabel = certUIDLabel;
+ }
+
+ /* Saved user certificate object obtained during authentication
+ * from the user's LDAP record.
+ * Will be accessed later to compare with incoming client auth certificate.
+ */
+ private X509Certificate storedUserCert;
+
+ protected void setStoredUserCert(X509Certificate cert) {
+ this.storedUserCert = cert;
+ }
+
+ protected X509Certificate getStoredUserCert() {
+ return storedUserCert;
+ }
+
+ // Check a PKI ACL resourceID and operation for permissions
+ // If the check fails the user (principal) is not authorized to access the resource
+ private boolean checkACLPermission(Principal principal, String resourceId, String operation) {
+
+ boolean allowed = true;
+
+ if (!hasAuthzProperties() || !hasResourceACLS()) {
+ //We arent' configured for this sort of authz
+ return allowed;
+ }
+
+ if (principal == null || resourceId == null || operation == null) {
+ return allowed;
+ }
+
+ ACL acl = acls.get(resourceId);
+
+ if (acl == null) {
+ //No such acl, assume true
+ return allowed;
+ }
+
+ Enumeration<ACLEntry> aclEntries = acl.entries();
+ while (aclEntries != null && aclEntries.hasMoreElements()) {
+ ACLEntry entry = aclEntries.nextElement();
+ boolean isEntryNegative = entry.isNegative();
+
+ String expressions = entry.getAttributeExpressions();
+
+ allowed = evaluateExpressions(principal, expressions);
+
+ if (isEntryNegative) {
+ allowed = !allowed;
+ }
+
+ //ToDo:
+ // Handle the more than one entry case.
+ // What to do if one of them fails.
+ }
+
+ return allowed;
+ }
+
+ // Evaluate an expression as part of a PKI ACL
+ // Ex: user=anybody , group=Data Recovery Manager Agents
+ private boolean evaluateExpression(Principal principal, String expression) {
+
+ boolean allowed = true;
+ if (principal == null || expression == null) {
+ return allowed;
+ }
+
+ String operation = getExpressionOperation(expression);
+
+ if (operation == null) {
+ return allowed;
+ }
+
+ String[] expBlock = expression.split(operation);
+
+ if (expBlock.length != 2) {
+ return allowed;
+ }
+
+ String left = expBlock[0];
+ String right = expBlock[1];
+
+ if (left != null) {
+ left.trim();
+ } else {
+ return allowed;
+ }
+ //Massage the right hand side of this expression to be a legal string value.
+ if (right != null) {
+ right.trim();
+ right = right.replace("\"", "");
+ right = right.trim();
+ } else {
+ return allowed;
+ }
+
+ boolean negate = false;
+
+ //Otherwise assume "="
+ if (operation.equals("!=")) {
+ negate = true;
+ }
+
+ allowed = false;
+ if (left.equals(PROP_GROUP)) {
+ // Check JNDI to see if the user has this role/group
+ if (hasRole(principal, right)) {
+ allowed = true;
+ }
+ } else if (left.equals(PROP_USER)) {
+ if (right.equals(PROP_USER_ANYBODY) || right.equals(PROP_USER_EVERYBODY)) {
+ allowed = true;
+ }
+ } else {
+ logDebug("Unknown expression.");
+ }
+
+ if (negate) {
+ allowed = !allowed;
+ }
+
+ return allowed;
+ }
+
+ // Convenience method to find the operation in an ACL expression
+ private String getExpressionOperation(String exp) {
+ //Support only = and !=
+
+ int i = exp.indexOf("!=");
+
+ if (i == -1) {
+ i = exp.indexOf("=");
+ if (i == -1) {
+ return null;
+ } else {
+ return "=";
+ }
+ } else {
+ return "!=";
+ }
+ }
+
+ // Take a set of expressions in an ACL and evaluate it
+ private boolean evaluateExpressions(Principal principal, String s) {
+
+ Vector<Object> v = new Vector<Object>();
+
+ 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(principal, 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(principal, 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(principal, s1.trim());
+
+ 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();
+
+ if (op.equals("||")) {
+ if (left == false && right == false)
+ left = false;
+ left = true;
+ } else if (op.equals("&&")) {
+ if (left == true && right == true)
+ left = true;
+ left = false;
+ }
+ }
+
+ return left;
+
+ }
+
+ /* Attempt to get the stored user certificate object and save it for
+ * future reference. This all takes place within one command invocation from
+ * the getPrincipal method defined here.
+ */
+ private void extractAndSaveStoredX509UserCert(DirContext context, User certUser)
+ throws NamingException {
+
+ setStoredUserCert(null);
+
+ if (certUser != null && context != null) {
+
+ String certAttrStr = this.getCertAttrName();
+
+ // certAttrStr has a default value, can not be null
+ String[] attrs = new String[] { certAttrStr };
+
+ Attributes attributes = context.getAttributes(certUser.getDN(), attrs);
+
+ if (attributes == null) {
+ logErr("Can not get certificate attributes in extractAndSaveStoredX590UserCert.");
+ return;
+ }
+
+ Attribute certAttr = null;
+
+ certAttr = attributes.get(certAttrStr);
+
+ if (certAttr == null) {
+ logErr("Can not get certificate attribut in extractAndSaveStoredX509UserCert.");
+ return;
+ }
+
+ Object oAttr = null;
+
+ oAttr = certAttr.get();
+
+ if (oAttr == null) {
+ logErr("Can not get certificate attribute object in extractAndSaveStoredX509UserCert.");
+ return;
+ }
+
+ byte[] certData = null;
+
+ if (oAttr instanceof byte[]) {
+ certData = (byte[]) oAttr;
+ } else {
+ logErr("Can not get certificate data in extractAndSaveStoredX509UserCert.");
+ return;
+ }
+
+ ByteArrayInputStream inStream = null;
+ try {
+ X509Certificate x509Cert = null;
+ if (certData != null) {
+ inStream = new ByteArrayInputStream(certData);
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+
+ if (cf != null) {
+ x509Cert = (X509Certificate) cf.generateCertificate(inStream);
+ }
+
+ setStoredUserCert(x509Cert);
+ }
+ } catch (Exception e) {
+ logErr("Certificate encoding error in extractAndSaveStoredX509UserCert: " + e);
+ } finally {
+ if (inStream != null) {
+ try {
+ inStream.close();
+ } catch (IOException e) {
+ logErr("Can't close ByteArrayStream in extractAndSaveStoredX509UserCert: " + e);
+ }
+ }
+ }
+ }
+ }
+
+ // Search for the proper auth.properties entry corresponding
+ // to a particular incoming URL
+ // ToDo: In the admin interface, often the operation is sent
+ // as one of the parameters to the message.
+ // There may be a way to extract this information at this level.
+ // The parameter name to scan for could be configured with the Realm.
+
+ private String getACLEntryDataForURL(String requestURI) {
+ String aclEntryData;
+
+ if (!hasAuthzProperties()) {
+ return null;
+ }
+
+ aclEntryData = authzProperties.getProperty(requestURI);
+
+ if (aclEntryData == null) {
+ //Check for a partial match such as
+ // ex: /kra/pki/keyrequest/2
+ // ToDo: Check into more sophisticated
+ // methods of doing this mapping.
+ // Perhaps Rest gives us this more
+ // sophisticated mapping ability.
+
+ Properties props = authzProperties;
+ Enumeration<?> e = props.propertyNames();
+
+ while (e.hasMoreElements()) {
+ String key = (String) e.nextElement();
+ if (requestURI.startsWith(key)) {
+ aclEntryData = props.getProperty(key);
+ break;
+ }
+ }
+ }
+
+ return aclEntryData;
+
+ }
+
+ //Go to the directory server, if configured, and go get the Resource ACLs
+ private synchronized void getResourceACLS(DirContext context) throws NamingException {
+
+ //for now lets support this on startup
+ if (hasResourceACLS()) {
+ return;
+ }
+
+ String filter = "(" + aclAttrName + "=*)";
+
+ SearchControls constraints = new SearchControls();
+
+ constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
+
+ constraints.setReturningAttributes(null);
+
+ NamingEnumeration<SearchResult> results =
+ context.search(aclBase, filter, constraints);
+
+ try {
+ if (results == null || !results.hasMore()) {
+ return;
+ }
+ } catch (PartialResultException ex) {
+ throw ex;
+ }
+
+ SearchResult result = null;
+ try {
+ result = results.next();
+ if (result != null) {
+
+ Attributes attrs = result.getAttributes();
+ if (attrs == null)
+ return;
+
+ Vector<String> aclVec = getAttributeValues(aclAttrName, attrs);
+
+ if (aclVec != null) {
+
+ Enumeration<String> vEnum = aclVec.elements();
+
+ while (vEnum.hasMoreElements())
+ {
+ String curAcl = vEnum.nextElement();
+ ACL acl = parseACL(curAcl);
+ if (acl != null) {
+ acls.put(acl.getName(), acl);
+ }
+ }
+ }
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ return;
+ }
+
+ }
+
+ // Check to see if we have obtained the PKI ACLs from the ldap server
+ private boolean hasResourceACLS() {
+
+ if (acls != null && acls.size() > 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ // Check to see if we have read in the auth properties file
+ private boolean hasAuthzProperties() {
+
+ if (this.authzProperties != null) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Parse ACL resource attributes
+ *
+ * @param res same format as the resource attribute:
+ *
+ * <PRE>
+ * <resource name>:<permission1,permission2,...permissionn>:
+ * <allow|deny> (<subset of the permission set>) <evaluator expression>
+ * </PRE>
+ * @exception EException ACL related parsing errors for res
+ * @return an ACL instance built from the parsed res
+ */
+ private ACL parseACL(String res) throws Exception {
+ if (res == null) {
+ throw new Exception("Bad input to parseACL.");
+ }
+
+ ACL acl = null;
+ Vector<String> rights = null;
+ int idx1 = res.indexOf(":");
+
+ if (idx1 <= 0) {
+ acl = new ACL(res, rights, res);
+ } else {
+ // getting resource id
+ String resource = res.substring(0, idx1);
+
+ if (resource == null) {
+ String infoMsg = "resource not specified in resource attribute:" +
+ res;
+
+ String[] params = new String[2];
+
+ params[0] = res;
+ params[1] = infoMsg;
+ throw new Exception(infoMsg);
+ }
+
+ // getting list of applicable rights
+ String st = res.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 resource attribute:" + res;
+ String[] params = new String[2];
+
+ params[0] = res;
+ params[1] = infoMsg;
+ throw new Exception(infoMsg);
+ }
+
+ if (rightsString != null) {
+ rights = new Vector<String>();
+ StringTokenizer rtok = new StringTokenizer(rightsString, ",");
+
+ while (rtok.hasMoreTokens()) {
+ rights.addElement(rtok.nextToken());
+ }
+ }
+
+ acl = new ACL(resource, rights, res);
+
+ String stx = st.substring(idx2 + 1);
+ int idx3 = stx.indexOf(":");
+ String tr = stx.substring(0, idx3);
+
+ // getting list of acl entries
+ if (tr != null) {
+ StringTokenizer atok = new StringTokenizer(tr, ";");
+
+ 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 Exception(infoMsg);
+ }
+
+ entry.setACLEntryString(acs);
+ acl.addEntry(entry);
+ }
+ } else {
+ // fine
+ String infoMsg = " not specified in resource attribute:" +
+
+ res;
+
+ String[] params = new String[2];
+
+ params[0] = res;
+ params[1] = infoMsg;
+ throw new Exception(infoMsg);
+ }
+
+ // getting description
+ String desc = stx.substring(idx3 + 1);
+
+ acl.setDescription(desc);
+ }
+
+ return (acl);
+ }
+
+ //Load the custom mapping file auth.properties, which maps urls to acl resourceID and operation value
+ //example entry: /kra/pki/config/cert/transport = certServer.kra.pki.config.cert.transport,read
+ // ToDo: Look into a more sophisticated method than this simple properties file if appropriate.
+ private synchronized void loadAuthzProperties(Context context) {
+
+ if (authzProperties == null && context != null) {
+ ClassLoader loader = this.getClass().getClassLoader();
+ if (loader == null)
+ loader = ClassLoader.getSystemClassLoader();
+
+ InputStream inputStream = context.getServletContext().getResourceAsStream(PROP_AUTH_FILE_PATH);
+
+ if (inputStream == null)
+ return;
+
+ Properties properties = new Properties();
+
+ try {
+ properties.load(inputStream);
+ } catch (IOException e) {
+ properties = null;
+ } finally {
+
+ if (properties != null) {
+ authzProperties = properties;
+ }
+ try {
+ inputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ return;
+ }
+ }
+
+ /**
+ * Return a String representing the value of the specified attribute.
+ * Create our own since the super class has it as private
+ *
+ * @param attrId Attribute name
+ * @param attrs Attributes containing the required value
+ *
+ * @exception NamingException if a directory server error occurs
+ */
+ private Vector<String> getAttributeValues(String attrId, Attributes attrs)
+ throws NamingException {
+
+ if (attrId == null || attrs == null)
+ return null;
+
+ Vector<String> values = new Vector<String>();
+ Attribute attr = attrs.get(attrId);
+ if (attr == null)
+ return (null);
+ NamingEnumeration<?> value = attr.getAll();
+ if (value == null)
+ return (null);
+
+ while (value.hasMore()) {
+ Object obj = value.next();
+ String valueString = null;
+ if (obj instanceof byte[])
+ valueString = new String((byte[]) obj);
+ else
+ valueString = obj.toString();
+ values.add(valueString);
+ }
+ return values;
+ }
+
+ /*
+ * ToDo: Figure out how to do real logging
+ */
+ private void logErr(String msg) {
+ System.err.println(msg);
+ }
+
+ private void logDebug(String msg) {
+ System.out.println(msg);
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/registry/PluginInfo.java b/base/common/src/com/netscape/cmscore/registry/PluginInfo.java
new file mode 100644
index 000000000..681861901
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/registry/PluginInfo.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.registry;
+
+import java.util.Locale;
+
+import com.netscape.certsrv.registry.IPluginInfo;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/registry/PluginRegistry.java b/base/common/src/com/netscape/cmscore/registry/PluginRegistry.java
new file mode 100644
index 000000000..42bb3e68e
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/registry/PluginRegistry.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.registry;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.registry.ERegistryException;
+import com.netscape.certsrv.registry.IPluginInfo;
+import com.netscape.certsrv.registry.IPluginRegistry;
+
+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<String, Hashtable<String, IPluginInfo>> mTypes =
+ new Hashtable<String, Hashtable<String, IPluginInfo>>();
+
+ 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<String, IPluginInfo> plugins = 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<String, IPluginInfo> plugins = mTypes.get(type);
+
+ if (plugins == null) {
+ plugins = new Hashtable<String, IPluginInfo>();
+ 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<String> types = mTypes.keys();
+ StringBuffer typesBuf = new StringBuffer();
+
+ while (types.hasMoreElements()) {
+ String type = (String) types.nextElement();
+
+ typesBuf.append(type);
+ if (types.hasMoreElements()) {
+ typesBuf.append(",");
+ }
+ Hashtable<String, IPluginInfo> mPlugins = mTypes.get(type);
+ StringBuffer idsBuf = new StringBuffer();
+ Enumeration<String> 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<String> getTypeNames() {
+ return mTypes.keys();
+ }
+
+ /**
+ * Returns a list of identifiers of the given type.
+ */
+ public Enumeration<String> getIds(String type) {
+ Hashtable<String, IPluginInfo> plugins = mTypes.get(type);
+
+ if (plugins == null)
+ return null;
+ return plugins.keys();
+ }
+
+ /**
+ * Retrieves the plugin information.
+ */
+ public IPluginInfo getPluginInfo(String type, String id) {
+ Hashtable<String, IPluginInfo> plugins = mTypes.get(type);
+
+ if (plugins == null)
+ return null;
+ return plugins.get(id);
+ }
+
+}
diff --git a/base/common/src/com/netscape/cmscore/request/ARequestQueue.java b/base/common/src/com/netscape/cmscore/request/ARequestQueue.java
new file mode 100644
index 000000000..16db3985c
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/request/ARequestQueue.java
@@ -0,0 +1,1578 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.CRLException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Set;
+import java.util.Vector;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509ExtensionException;
+
+import com.netscape.certsrv.apps.CMS;
+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 com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.AgentApprovals;
+import com.netscape.certsrv.request.IEnrollmentRequest;
+import com.netscape.certsrv.request.INotify;
+import com.netscape.certsrv.request.IPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestList;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.IRequestScheduler;
+import com.netscape.certsrv.request.IService;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+
+/**
+ * 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<RequestId> 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(), (Vector<?>) 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<String> 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<String, String> hash) {
+ if (hash == null) {
+ return false;
+ }
+ Enumeration<String> keys = hash.keys();
+ while (keys.hasMoreElements()) {
+ Object key = keys.nextElement();
+ if (!((key instanceof String) && isValidExtDataKey((String) key))) {
+ return false;
+ }
+ /*
+ * TODO should the Value type be String?
+ */
+ 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<String, String> value) {
+ if (!(isValidExtDataKey(key) && isValidExtDataHashtableValue(value))) {
+ return false;
+ }
+
+ mExtData.put(key, new ExtDataHashtable<String>(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;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Hashtable<String, String> getExtDataInHashtable(String key) {
+ Object value = mExtData.get(key);
+ if (value == null) {
+ return null;
+ }
+ if (!(value instanceof Hashtable)) {
+ return null;
+ }
+ return new ExtDataHashtable<String>((Hashtable<String, String>) value);
+ }
+
+ public Enumeration<String> 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;
+ }
+
+ @SuppressWarnings("unchecked")
+ Hashtable<String, String> existingValue = (Hashtable<String, String>) mExtData.get(key);
+ if (existingValue == null) {
+ existingValue = new ExtDataHashtable<String>();
+ mExtData.put(key, existingValue);
+ }
+ existingValue.put(subkey, value);
+ return true;
+ }
+
+ public String getExtDataInString(String key, String subkey) {
+ Hashtable<String, String> value = getExtDataInHashtable(key);
+ if (value == null) {
+ return null;
+ }
+ return 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<String> getExtDataInStringVector(String key) {
+ String[] stringArray = getExtDataInStringArray(key);
+ if (stringArray == null) {
+ return null;
+ }
+ return new Vector<String>(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<String, String> hash = new Hashtable<String, String>();
+ Enumeration<String> keys = data.getElements();
+ while (keys.hasMoreElements()) {
+ try {
+ String authKey = keys.nextElement();
+ hash.put(authKey, data.getInString(authKey));
+ } catch (ClassCastException e) {
+ return false;
+ }
+ }
+ return setExtData(key, hash);
+ }
+
+ public IAuthToken getExtDataInAuthToken(String key) {
+ Hashtable<String, String> hash = getExtDataInHashtable(key);
+ if (hash == null) {
+ return null;
+ }
+ AuthToken authToken = new AuthToken(null);
+ Enumeration<String> 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<String, String> hashValue = new Hashtable<String, String>();
+ 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<String, String> hashValue = getExtDataInHashtable(key);
+ if (hashValue == null) {
+ String s = getExtDataInString(key);
+ if (s == null) {
+ return null;
+ } else {
+ String[] sa = { s };
+ return sa;
+ }
+ }
+ Set<String> arrayKeys = hashValue.keySet();
+ Vector<Object> listValue = new Vector<Object>(arrayKeys.size());
+ for (Iterator<String> iter = arrayKeys.iterator(); iter.hasNext();) {
+ String arrayKey = 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 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<Object> mExtData = new ExtDataHashtable<Object>();
+
+ Date mCreationTime = CMS.getCurrentDate();
+ Date mModificationTime = CMS.getCurrentDate();
+}
+
+class RequestIAttrSetWrapper implements IAttrSet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8231914824991772682L;
+ 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<String> 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 RequestId nextElement() {
+ RequestId next = mNext;
+
+ update();
+
+ return next;
+ }
+
+ public RequestId nextRequestId() {
+ RequestId next = mNext;
+
+ update();
+
+ return next;
+ }
+
+ public RequestListByStatus(Enumeration<RequestId> 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 = 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<RequestId> mEnumeration;
+ protected RequestId mNext;
+}
+
+class RequestList
+ implements IRequestList {
+ public boolean hasMoreElements() {
+ return mEnumeration.hasMoreElements();
+ }
+
+ public RequestId nextElement() {
+ return mEnumeration.nextElement();
+ }
+
+ public RequestId nextRequestId() {
+ return (RequestId) mEnumeration.nextElement();
+ }
+
+ public Object nextRequest() {
+ return null;
+ }
+
+ public IRequest nextRequestObject() {
+ return null;
+ }
+
+ public RequestList(Enumeration<RequestId> e) {
+ mEnumeration = e;
+ }
+
+ protected Enumeration<RequestId> 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/base/common/src/com/netscape/cmscore/request/ARequestRecord.java b/base/common/src/com/netscape/cmscore/request/ARequestRecord.java
new file mode 100644
index 000000000..e23d4007c
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/request/ARequestRecord.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.cmscore.request;
+
+import java.util.Date;
+import java.util.Hashtable;
+
+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<String, Object> mExtData;
+};
diff --git a/base/common/src/com/netscape/cmscore/request/CertRequestConstants.java b/base/common/src/com/netscape/cmscore/request/CertRequestConstants.java
new file mode 100644
index 000000000..eab41fcd5
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/request/CertRequestConstants.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.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/base/common/src/com/netscape/cmscore/request/ExtDataHashtable.java b/base/common/src/com/netscape/cmscore/request/ExtDataHashtable.java
new file mode 100644
index 000000000..86e6c0530
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/request/ExtDataHashtable.java
@@ -0,0 +1,78 @@
+package com.netscape.cmscore.request;
+
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 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<V> extends Hashtable<String, V> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8401134619951331450L;
+
+ public ExtDataHashtable() {
+ super();
+ }
+
+ public ExtDataHashtable(int i) {
+ super(i);
+ }
+
+ public ExtDataHashtable(int i, float v) {
+ super(i, v);
+ }
+
+ public ExtDataHashtable(Map<? extends String, ? extends V> 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 V get(Object o) {
+ if (o instanceof String) {
+ String key = (String) o;
+ return super.get(key.toLowerCase());
+ }
+ return super.get(o);
+ }
+
+ public V put(String oKey, V val) {
+ if (oKey instanceof String) {
+ String key = (String) oKey;
+ return super.put(key.toLowerCase(), val);
+ }
+ return super.put(oKey, val);
+ }
+
+ public void putAll(Map<? extends String, ? extends V> map) {
+ Set<? extends String> keys = map.keySet();
+ for (Iterator<? extends String> i = keys.iterator(); i.hasNext();) {
+ Object key = i.next();
+ put((String) key, map.get(key));
+ }
+ }
+
+ public V remove(Object o) {
+ if (o instanceof String) {
+ String key = (String) o;
+ return super.remove(key.toLowerCase());
+ }
+ return super.remove(o);
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/request/RequestAttr.java b/base/common/src/com/netscape/cmscore/request/RequestAttr.java
new file mode 100644
index 000000000..25734c91e
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/request/RequestAttr.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.request;
+
+import com.netscape.certsrv.dbs.IDBAttrMapper;
+import com.netscape.certsrv.dbs.Modification;
+import com.netscape.certsrv.dbs.ModificationSet;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.ldap.IRequestMod;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/request/RequestQueue.java b/base/common/src/com/netscape/cmscore/request/RequestQueue.java
new file mode 100644
index 000000000..ef13d3c29
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/request/RequestQueue.java
@@ -0,0 +1,709 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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 java.util.Hashtable;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBSSession;
+import com.netscape.certsrv.dbs.IDBSearchResults;
+import com.netscape.certsrv.dbs.IDBSubsystem;
+import com.netscape.certsrv.dbs.IDBVirtualList;
+import com.netscape.certsrv.dbs.ModificationSet;
+import com.netscape.certsrv.dbs.repository.IRepository;
+import com.netscape.certsrv.request.INotify;
+import com.netscape.certsrv.request.IPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestList;
+import com.netscape.certsrv.request.IRequestRecord;
+import com.netscape.certsrv.request.IRequestVirtualList;
+import com.netscape.certsrv.request.IService;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.request.ldap.IRequestMod;
+import com.netscape.cmscore.dbs.DBSubsystem;
+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);
+
+ 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);
+
+ 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 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<RequestId> getRawList() {
+ IDBSearchResults results = null;
+ IDBSSession dbs = null;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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<Object> 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, Hashtable<String, Object> h) {
+ System.err.println(s);
+ Enumeration<String> e = h.keys();
+
+ while (e.hasMoreElements()) {
+ String name = 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 RequestId 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<Object> list) {
+ mQueue = queue;
+ mList = list;
+ }
+
+ protected RequestQueue mQueue;
+ protected IDBVirtualList<Object> mList;
+}
diff --git a/base/common/src/com/netscape/cmscore/request/RequestRecord.java b/base/common/src/com/netscape/cmscore/request/RequestRecord.java
new file mode 100644
index 000000000..1d066f0ad
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/request/RequestRecord.java
@@ -0,0 +1,883 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.EDBException;
+import com.netscape.certsrv.dbs.IDBAttrMapper;
+import com.netscape.certsrv.dbs.IDBDynAttrMapper;
+import com.netscape.certsrv.dbs.IDBObj;
+import com.netscape.certsrv.dbs.IDBRegistry;
+import com.netscape.certsrv.dbs.IDBSubsystem;
+import com.netscape.certsrv.dbs.Modification;
+import com.netscape.certsrv.dbs.ModificationSet;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestRecord;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.request.ldap.IRequestMod;
+import com.netscape.cmscore.dbs.BigIntegerMapper;
+import com.netscape.cmscore.dbs.DateMapper;
+import com.netscape.cmscore.dbs.StringMapper;
+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 {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8044665107558872084L;
+
+ public RequestId getRequestId() {
+ return mRequestId;
+ }
+
+ public Enumeration<String> 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 = mAttrTable.get(name);
+
+ if (ra != null)
+ return ra.get(this);
+ }
+
+ return null;
+ }
+
+ // IDBObj.set
+ @SuppressWarnings("unchecked")
+ 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<String, Object>) o;
+ else {
+ RequestAttr ra = 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<String> getElements() {
+ return mAttrs.elements();
+ }
+
+ // IDBObj.getSerializableAttrNames
+ public Enumeration<String> 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<String, Object> loadExtDataFromRequest(IRequest r) throws EBaseException {
+ Hashtable<String, Object> h = new Hashtable<String, Object>();
+
+ Enumeration<String> e = r.getExtDataKeys();
+ while (e.hasMoreElements()) {
+ String key = e.nextElement();
+ if (r.isSimpleExtDataValue(key)) {
+ h.put(key, r.getExtDataInString(key));
+ } else {
+ h.put(key, r.getExtDataInHashtable(key));
+ }
+ }
+
+ return h;
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void storeExtDataIntoRequest(IRequest r) throws EBaseException {
+ Enumeration<String> e = mExtData.keys();
+ while (e.hasMoreElements()) {
+ String key = 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<String, String>) value);
+ } else {
+ throw new EDBException("Illegal data value in RequestRecord: " +
+ r.toString());
+ }
+ }
+ }
+
+ protected static Vector<String> mAttrs = new Vector<String>();
+
+ static Hashtable<String, RequestAttr> mAttrTable = new Hashtable<String, RequestAttr>();
+
+ /*
+ * 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<String> 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<String> mAttrs = new Vector<String>();
+
+ 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<String> 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<String> mAttrs = new Vector<String>();
+
+ 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<String> getSupportedLDAPAttributeNames() {
+ return mAttrs.elements();
+ }
+
+ //
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs) {
+ @SuppressWarnings("unchecked")
+ Hashtable<String, Object> ht = (Hashtable<String, Object>) obj;
+ Enumeration<String> e = ht.keys();
+
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(bos);
+
+ String key = null;
+ Object value = null;
+
+ while (e.hasMoreElements()) {
+ key = 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<String, Object> decodeHashtable(byte[] data)
+ throws ObjectStreamException, IOException, ClassNotFoundException {
+ Hashtable<String, Object> ht = new Hashtable<String, Object>();
+ 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<String, Object> 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) {
+ @SuppressWarnings("unchecked")
+ Enumeration<byte[]> 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<String> mAttrs = new Vector<String>();
+
+ 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<String> 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 {
+ @SuppressWarnings("unchecked")
+ Hashtable<String, Object> ht = (Hashtable<String, Object>) obj;
+ Enumeration<String> e = ht.keys();
+
+ try {
+ while (e.hasMoreElements()) {
+ String key = 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) {
+ @SuppressWarnings("unchecked")
+ Hashtable<String, String> innerHash = (Hashtable<String, String>) value;
+ Enumeration<String> innerHashEnum = innerHash.keys();
+ while (innerHashEnum.hasMoreElements()) {
+ String innerKey = innerHashEnum.nextElement();
+ String innerValue = 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);
+ //}
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs, String name,
+ IDBObj parent)
+ throws EBaseException {
+ Hashtable<String, Object> ht = new Hashtable<String, Object>();
+ Hashtable<String, String> valueHashtable;
+
+ Enumeration<LDAPAttribute> attrEnum = attrs.getAttributes();
+ while (attrEnum.hasMoreElements()) {
+ LDAPAttribute attr = 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<String, String>) value;
+ if (valueHashtable == null) {
+ valueHashtable = new Hashtable<String, String>();
+ 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<String> mAttrs = new Vector<String>();
+
+ static {
+ mAttrs.add(Schema.LDAP_ATTR_EXT_ATTR);
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/request/RequestRepository.java b/base/common/src/com/netscape/cmscore/request/RequestRepository.java
new file mode 100644
index 000000000..0a4a4ebf9
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/request/RequestRepository.java
@@ -0,0 +1,217 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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 com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.EDBException;
+import com.netscape.certsrv.dbs.IDBSSession;
+import com.netscape.certsrv.dbs.IDBSearchResults;
+import com.netscape.certsrv.dbs.IDBSubsystem;
+import com.netscape.certsrv.dbs.Modification;
+import com.netscape.certsrv.dbs.ModificationSet;
+import com.netscape.certsrv.dbs.repository.IRepositoryRecord;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.cmscore.dbs.Repository;
+import com.netscape.cmscore.dbs.RepositoryRecord;
+
+/**
+ * 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 {
+ IDBSearchResults sr = s.search(getBaseDN(),
+ "(" + RequestRecord.ATTR_REQUEST_ID + "=*)");
+ while (sr.hasMoreElements()) {
+ RequestRecord r = (RequestRecord) sr.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/base/common/src/com/netscape/cmscore/request/RequestSubsystem.java b/base/common/src/com/netscape/cmscore/request/RequestSubsystem.java
new file mode 100644
index 000000000..862ddaa68
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/request/RequestSubsystem.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.cmscore.request;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.dbs.IDBSSession;
+import com.netscape.certsrv.dbs.IDBSubsystem;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.INotify;
+import com.netscape.certsrv.request.IPolicy;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.IRequestSubsystem;
+import com.netscape.certsrv.request.IService;
+import com.netscape.cmscore.dbs.DBSubsystem;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/request/Schema.java b/base/common/src/com/netscape/cmscore/request/Schema.java
new file mode 100644
index 000000000..89a7b74b9
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/request/Schema.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.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/base/common/src/com/netscape/cmscore/security/CASigningCert.java b/base/common/src/com/netscape/cmscore/security/CASigningCert.java
new file mode 100644
index 000000000..bba12561f
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/security/CASigningCert.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.security;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.KeyPair;
+
+import netscape.security.x509.KeyUsageExtension;
+
+import org.mozilla.jss.crypto.PQGParamGenException;
+import org.mozilla.jss.crypto.PQGParams;
+
+import com.netscape.certsrv.apps.CMS;
+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;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/security/CertificateInfo.java b/base/common/src/com/netscape/cmscore/security/CertificateInfo.java
new file mode 100644
index 000000000..fc7fb9087
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/security/CertificateInfo.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.security;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateParsingException;
+import java.util.Calendar;
+import java.util.Date;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.AuthorityKeyIdentifierExtension;
+import netscape.security.x509.CertificateAlgorithmId;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateIssuerName;
+import netscape.security.x509.CertificateSerialNumber;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.KeyIdentifier;
+import netscape.security.x509.KeyUsageExtension;
+import netscape.security.x509.SubjectKeyIdentifierExtension;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.crypto.PQGParamGenException;
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+
+import com.netscape.certsrv.apps.CMS;
+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;
+
+/**
+ * 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());
+
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(beginYear, beginMonth, beginDate,
+ beginHour, beginMin, beginSec);
+ notBeforeDate = calendar.getTime();
+ calendar.set(afterYear, afterMonth, afterDate,
+ afterHour, afterMin, afterSec);
+ notAfterDate = calendar.getTime();
+ }
+ 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);
+ 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/base/common/src/com/netscape/cmscore/security/JssSubsystem.java b/base/common/src/com/netscape/cmscore/security/JssSubsystem.java
new file mode 100644
index 000000000..42768060c
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/security/JssSubsystem.java
@@ -0,0 +1,2203 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.math.BigInteger;
+import java.net.SocketException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.ldap.util.DN;
+import netscape.security.x509.AlgIdDSA;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.BasicConstraintsExtension;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.CryptoManager.NicknameConflictException;
+import org.mozilla.jss.CryptoManager.NotInitializedException;
+import org.mozilla.jss.CryptoManager.UserCertConflictException;
+import org.mozilla.jss.NoSuchTokenException;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.crypto.AlreadyInitializedException;
+import org.mozilla.jss.crypto.CryptoStore;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.InternalCertificate;
+import org.mozilla.jss.crypto.KeyPairAlgorithm;
+import org.mozilla.jss.crypto.NoSuchItemOnTokenException;
+import org.mozilla.jss.crypto.ObjectNotFoundException;
+import org.mozilla.jss.crypto.PQGParamGenException;
+import org.mozilla.jss.crypto.PQGParams;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+import org.mozilla.jss.crypto.TokenCertificate;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.pkcs11.PK11SecureRandom;
+import org.mozilla.jss.pkcs7.ContentInfo;
+import org.mozilla.jss.pkcs7.SignedData;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.ssl.SSLServerSocket;
+import org.mozilla.jss.ssl.SSLSocket;
+import org.mozilla.jss.util.IncorrectPasswordException;
+import org.mozilla.jss.util.Password;
+import org.mozilla.jss.util.PasswordCallback;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.common.NameValuePairs;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.security.ICryptoSubsystem;
+import com.netscape.certsrv.security.KeyCertData;
+import com.netscape.cmscore.cert.CertPrettyPrint;
+import com.netscape.cmscore.cert.CertUtils;
+import com.netscape.cmscore.util.Debug;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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<String, X509Certificate[]> mNicknameMapCertsTable = new Hashtable<String, X509Certificate[]>();
+ private Hashtable<String, X509Certificate[]> mNicknameMapUserCertsTable =
+ new Hashtable<String, X509Certificate[]>();
+
+ 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<String, Integer> mCipherNames = new Hashtable<String, Integer>();
+
+ /* default sslv2 and sslv3 cipher suites(all), set if no prefs in config.*/
+ private static final String DEFAULT_CIPHERPREF =
+ "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA," +
+ "TLS_RSA_WITH_AES_128_CBC_SHA," +
+ "TLS_RSA_WITH_AES_256_CBC_SHA," +
+ "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA," +
+ "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA," +
+ // "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA," +
+ // "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA," +
+ // "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA," +
+ "TLS_DHE_DSS_WITH_AES_128_CBC_SHA," +
+ "TLS_DHE_DSS_WITH_AES_256_CBC_SHA," +
+ "TLS_DHE_RSA_WITH_AES_128_CBC_SHA," +
+ "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
+
+ /* 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 = "";
+ @SuppressWarnings("unchecked")
+ Enumeration<CryptoToken> tokens = mCryptoManager.getExternalTokens();
+ int num = 0;
+
+ try {
+ while (tokens.hasMoreElements()) {
+ CryptoToken c = 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 {
+ @SuppressWarnings("unchecked")
+ Enumeration<CryptoToken> enums = mCryptoManager.getAllTokens();
+
+ while (enums.hasMoreElements()) {
+ CryptoToken token = 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 {
+ new X500Name(dn); // check for errors
+ } 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) {
+ String eString = e.toString();
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_SECURITY_IMPORT_CERT", e.toString()));
+ if (eString.contains("Failed to find certificate that was just imported")) {
+ throw new EBaseException(eString);
+ } else {
+ 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 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.put(Constants.PR_CERT_SUBJECT_NAME, impl.getSubjectDN().getName());
+ results.put(Constants.PR_ISSUER_NAME, impl.getIssuerDN().getName());
+ results.put(Constants.PR_SERIAL_NUMBER, impl.getSerialNumber().toString());
+ results.put(Constants.PR_BEFORE_VALIDDATE, impl.getNotBefore().toString());
+ results.put(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;
+
+ 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;
+
+ 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 {
+ @SuppressWarnings("unchecked")
+ Enumeration<CryptoToken> enums = mCryptoManager.getAllTokens();
+ if (mNicknameMapCertsTable != null)
+ mNicknameMapCertsTable.clear();
+
+ // a temp hashtable with vectors
+ Hashtable<String, Vector<X509Certificate>> vecTable = new Hashtable<String, Vector<X509Certificate>>();
+
+ 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 {
+ @SuppressWarnings("unused")
+ PrivateKey key =
+ CryptoManager.getInstance().findPrivKeyByCert(list[i]); // check for errors
+ 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<X509Certificate> v;
+ if (vecTable.containsKey((Object) nickname) == true) {
+ v = vecTable.get(nickname);
+ } else {
+ v = new Vector<X509Certificate>();
+ }
+ 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.put(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<String> elms = vecTable.keys();
+
+ while (elms.hasMoreElements()) {
+ String key = (String) elms.nextElement();
+ Vector<X509Certificate> v = 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 {
+ @SuppressWarnings("unchecked")
+ Enumeration<CryptoToken> 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 {
+ @SuppressWarnings("unused")
+ PrivateKey key =
+ CryptoManager.getInstance().findPrivKeyByCert(list[i]); // check for errors
+ 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.put(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 {
+ @SuppressWarnings("unchecked")
+ Enumeration<CryptoToken> 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();
+ 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);
+ String vvalue = pairs.get(nickname);
+
+ /* always user cert here*/
+ String certValue = dateStr + "," + "u";
+
+ if (vvalue == null)
+ pairs.put(nickname, certValue);
+ else {
+ if (vvalue.endsWith(",u")) {
+ pairs.put(nickname, 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<String, Vector<X509Certificate>> vecTable = new Hashtable<String, Vector<X509Certificate>>();
+
+ for (int i = 0; i < certs.length; i++) {
+ String nickname = certs[i].getNickname();
+
+ /* build a table of our own */
+ Vector<X509Certificate> v;
+
+ if (vecTable.containsKey((Object) nickname) == true) {
+ v = vecTable.get(nickname);
+ } else {
+ v = new Vector<X509Certificate>();
+ }
+ v.addElement(certs[i]);
+ vecTable.put(nickname, v);
+ }
+
+ // convert hashtable of vectors to hashtable of arrays
+ Enumeration<String> elms = vecTable.keys();
+
+ while (elms.hasMoreElements()) {
+ String key = (String) elms.nextElement();
+ Vector<X509Certificate> v = vecTable.get((Object) key);
+ X509Certificate[] a = new X509Certificate[v.size()];
+
+ v.copyInto((Object[]) a);
+ mNicknameMapCertsTable.put(key, a);
+ }
+
+ Enumeration<String> 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);
+ String vvalue = pairs.get(nickname);
+ String certValue = dateStr + "," + trust;
+
+ if (vvalue == null)
+ pairs.put(nickname, certValue);
+ else {
+ pairs.put(nickname, 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;
+
+ 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;
+
+ 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);
+ Principal principal = cert.getSubjectDN();
+ DN dn = new DN(principal.getName());
+ BigInteger serialno = cert.getSerialNumber();
+ String suffix = "." + System.currentTimeMillis();
+ String b64E = Utils.base64encode(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;
+
+ 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());
+ 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()));
+ }
+ }
+
+ 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[] = Utils.base64decode(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/base/common/src/com/netscape/cmscore/security/KRATransportCert.java b/base/common/src/com/netscape/cmscore/security/KRATransportCert.java
new file mode 100644
index 000000000..79988e7d6
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/security/KRATransportCert.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.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/base/common/src/com/netscape/cmscore/security/KeyCertUtil.java b/base/common/src/com/netscape/cmscore/security/KeyCertUtil.java
new file mode 100644
index 000000000..2a9afb868
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/security/KeyCertUtil.java
@@ -0,0 +1,1139 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.KeyPair;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.interfaces.DSAParams;
+import java.security.interfaces.DSAPublicKey;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPModification;
+import netscape.security.extensions.AuthInfoAccessExtension;
+import netscape.security.extensions.ExtendedKeyUsageExtension;
+import netscape.security.extensions.NSCertTypeExtension;
+import netscape.security.extensions.OCSPNoCheckExtension;
+import netscape.security.pkcs.PKCS10;
+import netscape.security.pkcs.PKCS10Attribute;
+import netscape.security.pkcs.PKCS10Attributes;
+import netscape.security.pkcs.PKCS9Attribute;
+import netscape.security.util.BigInt;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.AlgIdDSA;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.AuthorityKeyIdentifierExtension;
+import netscape.security.x509.BasicConstraintsExtension;
+import netscape.security.x509.CertAttrSet;
+import netscape.security.x509.CertificateAlgorithmId;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.Extensions;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.KeyIdentifier;
+import netscape.security.x509.KeyUsageExtension;
+import netscape.security.x509.SubjectKeyIdentifierExtension;
+import netscape.security.x509.URIName;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X500Signer;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.CryptoManager.NicknameConflictException;
+import org.mozilla.jss.CryptoManager.NotInitializedException;
+import org.mozilla.jss.CryptoManager.UserCertConflictException;
+import org.mozilla.jss.NoSuchTokenException;
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.asn1.ASN1Header;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.BIT_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.InternalCertificate;
+import org.mozilla.jss.crypto.KeyPairAlgorithm;
+import org.mozilla.jss.crypto.KeyPairGenerator;
+import org.mozilla.jss.crypto.NoSuchItemOnTokenException;
+import org.mozilla.jss.crypto.ObjectNotFoundException;
+import org.mozilla.jss.crypto.PQGParamGenException;
+import org.mozilla.jss.crypto.PQGParams;
+import org.mozilla.jss.crypto.Signature;
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.pkcs11.PK11ECPublicKey;
+import org.mozilla.jss.util.Base64OutputStream;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.security.KeyCertData;
+import com.netscape.cmscore.cert.CertUtils;
+import com.netscape.cmscore.dbs.BigIntegerMapper;
+import com.netscape.cmscore.dbs.DateMapper;
+import com.netscape.cmscore.dbs.X509CertImplMapper;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * 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 = Utils.base64decode(ext);
+ // this b can be "Extension" Or "SEQUENCE OF Extension"
+ DerValue b_der = new DerValue(b);
+
+ while (b_der.data.available() != 0) {
+ new Extension(b_der.data.getDerValue()); // check for errors
+ }
+ } catch (IOException e) {
+ try {
+ new Extension(new DerValue(b)); // check for errors
+ } catch (IOException ex) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_CERT_EXTENSION"));
+ }
+ }
+ }
+ }
+
+ public static String getTokenNames(CryptoManager manager)
+ throws TokenException {
+ String tokenList = "";
+ @SuppressWarnings("unchecked")
+ Enumeration<CryptoToken> 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);
+ 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[] = Utils.base64decode(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 = Utils.base64decode(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
+ 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<ObjectIdentifier> oidSet = new Vector<ObjectIdentifier>();
+ 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/base/common/src/com/netscape/cmscore/security/OCSPSigningCert.java b/base/common/src/com/netscape/cmscore/security/OCSPSigningCert.java
new file mode 100644
index 000000000..762db5e90
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/security/OCSPSigningCert.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 com.netscape.cmscore.security;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.KeyPair;
+
+import netscape.security.x509.KeyUsageExtension;
+
+import org.mozilla.jss.crypto.PQGParamGenException;
+import org.mozilla.jss.crypto.PQGParams;
+
+import com.netscape.certsrv.apps.CMS;
+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;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/security/PWCBsdr.java b/base/common/src/com/netscape/cmscore/security/PWCBsdr.java
new file mode 100644
index 000000000..32a0e90ed
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/security/PWCBsdr.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.security;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.mozilla.jss.util.Password;
+import org.mozilla.jss.util.PasswordCallback;
+import org.mozilla.jss.util.PasswordCallbackInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cmscore.base.JDialogPasswordCallback;
+
+/*
+ * 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");
+ 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/base/common/src/com/netscape/cmscore/security/PWUtil.java b/base/common/src/com/netscape/cmscore/security/PWUtil.java
new file mode 100644
index 000000000..3938bf5d2
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/security/PWUtil.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.security;
+
+import org.mozilla.jss.util.Password;
+import org.mozilla.jss.util.PasswordCallback;
+
+public class PWUtil {
+ public static Password
+ readPasswordFromStream()
+ throws PasswordCallback.GiveUpException {
+
+ 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/base/common/src/com/netscape/cmscore/security/PWsdrCache.java b/base/common/src/com/netscape/cmscore/security/PWsdrCache.java
new file mode 100644
index 000000000..6c834d0e0
--- /dev/null
+++ b/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 java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.CryptoManager.NotInitializedException;
+import org.mozilla.jss.SecretDecoderRing.Decryptor;
+import org.mozilla.jss.SecretDecoderRing.Encryptor;
+import org.mozilla.jss.SecretDecoderRing.KeyManager;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.util.Base64OutputStream;
+import org.mozilla.jss.util.Password;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+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 = Utils.base64decode(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<String, String>) null);
+ }
+
+ /*
+ * Store passwd in pwcache.
+ */
+ public void addEntry(Hashtable<String, String> ht) throws EBaseException {
+ addEntry((String) null, (String) null, ht);
+ }
+
+ /*
+ * add passwd in pwcache.
+ */
+ public void addEntry(String tag, String pwd, Hashtable<String, String> tagPwds) throws EBaseException {
+
+ String stringToAdd = null;
+ String bufs = null;
+
+ if (tagPwds == null) {
+ stringToAdd = tag + ":" + pwd + "\n";
+ } else {
+ Enumeration<String> enum1 = tagPwds.keys();
+
+ while (enum1.hasMoreElements()) {
+ tag = enum1.nextElement();
+ pwd = 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<String, String> 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<String, String> 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<String, String> ht) {
+ Enumeration<String> enum1 = ht.keys();
+ String returnString = null;
+
+ while (enum1.hasMoreElements()) {
+ String tag = enum1.nextElement();
+ String pwd = ht.get(tag);
+
+ if (returnString == null) {
+ returnString = tag + ":" + pwd + "\n";
+ } else {
+ returnString += tag + ":" + pwd + "\n";
+ }
+ }
+ return returnString;
+ }
+
+ public Hashtable<String, String> string2Hashtable(String cache) {
+ Hashtable<String, String> ht = new Hashtable<String, String>();
+
+ // 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<String, String> 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();
+
+ 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 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/base/common/src/com/netscape/cmscore/security/Provider.java b/base/common/src/com/netscape/cmscore/security/Provider.java
new file mode 100644
index 000000000..540fe2201
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/security/Provider.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.security;
+
+public class Provider extends java.security.Provider {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8050884788034389693L;
+
+ 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/base/common/src/com/netscape/cmscore/security/RASigningCert.java b/base/common/src/com/netscape/cmscore/security/RASigningCert.java
new file mode 100644
index 000000000..581fc8866
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/security/RASigningCert.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.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;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/security/SSLCert.java b/base/common/src/com/netscape/cmscore/security/SSLCert.java
new file mode 100644
index 000000000..b54f24dc7
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/security/SSLCert.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 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;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/security/SSLSelfSignedCert.java b/base/common/src/com/netscape/cmscore/security/SSLSelfSignedCert.java
new file mode 100644
index 000000000..1d70e7a1d
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/security/SSLSelfSignedCert.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.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;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/security/SubsystemCert.java b/base/common/src/com/netscape/cmscore/security/SubsystemCert.java
new file mode 100644
index 000000000..aede5e4d9
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/security/SubsystemCert.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.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;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/selftests/SelfTestOrderedInstance.java b/base/common/src/com/netscape/cmscore/selftests/SelfTestOrderedInstance.java
new file mode 100644
index 000000000..2146b290d
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/selftests/SelfTestOrderedInstance.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 statement //
+///////////////////////
+
+package com.netscape.cmscore.selftests;
+
+///////////////////////
+// import statements //
+///////////////////////
+
+import java.util.StringTokenizer;
+
+//////////////////////
+// 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/base/common/src/com/netscape/cmscore/selftests/SelfTestSubsystem.java b/base/common/src/com/netscape/cmscore/selftests/SelfTestSubsystem.java
new file mode 100644
index 000000000..6fac3d9d7
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/selftests/SelfTestSubsystem.java
@@ -0,0 +1,1900 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software 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.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.ListIterator;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.logging.AuditEvent;
+import com.netscape.certsrv.logging.ELogException;
+import com.netscape.certsrv.logging.ILogEventListener;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.selftests.EDuplicateSelfTestException;
+import com.netscape.certsrv.selftests.EInvalidSelfTestException;
+import com.netscape.certsrv.selftests.EMissingSelfTestException;
+import com.netscape.certsrv.selftests.ESelfTestException;
+import com.netscape.certsrv.selftests.ISelfTest;
+import com.netscape.certsrv.selftests.ISelfTestSubsystem;
+
+//////////////////////
+// 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<String, ISelfTest> mSelfTestInstances = new Hashtable<String, ISelfTest>();
+ public Vector<SelfTestOrderedInstance> mOnDemandOrder = new Vector<SelfTestOrderedInstance>();
+ public Vector<SelfTestOrderedInstance> mStartupOrder = new Vector<SelfTestOrderedInstance>();
+
+ ///////////////////////////
+ // 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<SelfTestOrderedInstance> 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<SelfTestOrderedInstance> 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<SelfTestOrderedInstance> 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<SelfTestOrderedInstance> 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<SelfTestOrderedInstance> 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<SelfTestOrderedInstance> 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<SelfTestOrderedInstance> 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<SelfTestOrderedInstance> 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<SelfTestOrderedInstance> 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<SelfTestOrderedInstance> 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<SelfTestOrderedInstance> 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<SelfTestOrderedInstance> 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;
+ }
+ }
+
+ 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<ISelfTest> 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<String> 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<String> 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<ISelfTest> 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<SelfTestOrderedInstance> 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<ISelfTest> collection = mSelfTestInstances.values();
+ Vector<ISelfTest> list = new Vector<ISelfTest>(collection);
+
+ Collections.reverse(list);
+
+ // loop through all self test plugin instances
+ ListIterator<ISelfTest> 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/base/common/src/com/netscape/cmscore/time/SimpleTimeSource.java b/base/common/src/com/netscape/cmscore/time/SimpleTimeSource.java
new file mode 100644
index 000000000..ab832b7cc
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/time/SimpleTimeSource.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.cmscore.time;
+
+import java.util.Date;
+
+import com.netscape.certsrv.base.ITimeSource;
+
+public class SimpleTimeSource implements ITimeSource {
+
+ public Date getCurrentDate() {
+ return new Date();
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/usrgrp/CertDNCertUserLocator.java b/base/common/src/com/netscape/cmscore/usrgrp/CertDNCertUserLocator.java
new file mode 100644
index 000000000..8f4cd8841
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/usrgrp/CertDNCertUserLocator.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.cmscore.usrgrp;
+
+import java.security.cert.X509Certificate;
+
+import netscape.ldap.LDAPException;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.usrgrp.Certificates;
+import com.netscape.certsrv.usrgrp.EUsrGrpException;
+import com.netscape.certsrv.usrgrp.ICertUserLocator;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.certsrv.usrgrp.IUser;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/usrgrp/ExactMatchCertUserLocator.java b/base/common/src/com/netscape/cmscore/usrgrp/ExactMatchCertUserLocator.java
new file mode 100644
index 000000000..871a38435
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/usrgrp/ExactMatchCertUserLocator.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.usrgrp;
+
+import java.security.cert.X509Certificate;
+
+import netscape.ldap.LDAPException;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.usrgrp.Certificates;
+import com.netscape.certsrv.usrgrp.EUsrGrpException;
+import com.netscape.certsrv.usrgrp.ICertUserLocator;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.certsrv.usrgrp.IUser;
+
+/**
+ * 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/base/common/src/com/netscape/cmscore/usrgrp/Group.java b/base/common/src/com/netscape/cmscore/usrgrp/Group.java
new file mode 100644
index 000000000..eee2afb43
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/usrgrp/Group.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.usrgrp;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.usrgrp.IGroup;
+import com.netscape.certsrv.usrgrp.IUsrGrp;
+
+/**
+ * A class represents a group.
+ *
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class Group implements IGroup {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1264387079578766750L;
+ private IUsrGrp mBase = null;
+ private String mName = null;
+ private Vector<String> mMembers = new Vector<String>();
+ private String mDescription = null;
+
+ private static final Vector<String> mNames = new Vector<String>();
+ 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<String> 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;
+ }
+
+ @SuppressWarnings("unchecked")
+ 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<String>) 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<String> getElements() {
+ return mNames.elements();
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/usrgrp/UGSubsystem.java b/base/common/src/com/netscape/cmscore/usrgrp/UGSubsystem.java
new file mode 100644
index 000000000..a4c4d6854
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/usrgrp/UGSubsystem.java
@@ -0,0 +1,1685 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPDN;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPModification;
+import netscape.ldap.LDAPModificationSet;
+import netscape.ldap.LDAPSearchConstraints;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.usrgrp.EUsrGrpException;
+import com.netscape.certsrv.usrgrp.ICertUserLocator;
+import com.netscape.certsrv.usrgrp.IGroup;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.certsrv.usrgrp.IUser;
+import com.netscape.certsrv.usrgrp.IUsrGrp;
+import com.netscape.cmscore.ldapconn.LdapBoundConnFactory;
+import com.netscape.cmscore.util.Debug;
+
+/**
+ * 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);
+ } 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<IUser> 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<IUser> 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<IUser> e = buildUsers(res);
+
+ return (User) e.nextElement();
+ } catch (LDAPException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_FIND_USER", e.toString()));
+ } catch (ELdapException 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<IUser> e = buildUsers(res);
+
+ return e.nextElement();
+ } catch (LDAPException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_FIND_USER_BY_CERT", e.toString()));
+ } catch (ELdapException 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<IUser> 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<IUser> e = buildUsers(res);
+
+ return e;
+ } catch (LDAPException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_FIND_USERS", e.toString()));
+ } catch (ELdapException 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<IUser> 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<IUser> e = lbuildUsers(res);
+
+ return e;
+ } catch (LDAPException e) {
+ 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<IUser> lbuildUsers(LDAPSearchResults res) throws
+ EUsrGrpException {
+ Vector<IUser> v = new Vector<IUser>();
+
+ while (res.hasMoreElements()) {
+ LDAPEntry entry = (LDAPEntry) res.nextElement();
+ IUser user = lbuildUser(entry);
+
+ v.addElement(user);
+ }
+ return v.elements();
+ }
+
+ protected Enumeration<IUser> buildUsers(LDAPSearchResults res) throws
+ EUsrGrpException {
+ Vector<IUser> v = new Vector<IUser>();
+
+ 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<X509Certificate> certVector = new Vector<X509Certificate>();
+ @SuppressWarnings("unchecked")
+ Enumeration<byte[]> e = certAttr.getByteValues();
+
+ try {
+ for (; e != null && e.hasMoreElements();) {
+ X509Certificate cert = new X509CertImpl(
+ 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<X509Certificate> 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
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_BUILD_USER", userdn));
+
+ 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) {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> en = mailAttr.getStringValues();
+
+ if (en != null && en.hasMoreElements()) {
+ String mail = 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) {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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 {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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 {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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<X509Certificate> certVector = new Vector<X509Certificate>();
+ @SuppressWarnings("unchecked")
+ Enumeration<byte[]> 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<X509Certificate> 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) {
+ 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 attrCertBin = new LDAPAttribute(LDAP_ATTR_USER_CERT);
+
+ try {
+ attrCertBin.addValue(cert[0].getEncoded());
+ attrCertStr.addValue(getCertificateString(cert[0]));
+ } 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, 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();
+ }
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_ADD_USER", e.toString()));
+ throw e;
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_ADD_USER", e.toString()));
+ } finally {
+ if (ldapconn != null)
+ returnConn(ldapconn);
+ }
+ }
+
+ return;
+ }
+
+ public void addCertSubjectDN(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 attrCertDNStr = new LDAPAttribute(LDAP_ATTR_CERTDN);
+ attrCertDNStr.addValue(cert[0].getSubjectDN().toString());
+ addCert.add(LDAPModification.ADD, attrCertDNStr);
+
+ 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.ADDCERTSUBJECTDNFORMAT,
+ new Object[] { adminId, user.getUserID(),
+ cert[0].getSubjectDN().toString()}
+ );
+
+ } catch (LDAPException e) {
+ if (Debug.ON) {
+ e.printStackTrace();
+ }
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_ADD_USER", e.toString()));
+ throw e;
+ } catch (ELdapException 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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<IGroup> buildGroups(LDAPSearchResults res) {
+ Vector<IGroup> v = new Vector<IGroup>();
+
+ while (res.hasMoreElements()) {
+ LDAPEntry entry = (LDAPEntry) res.nextElement();
+
+ v.addElement(buildGroup(entry));
+ }
+ return v.elements();
+ }
+
+ /**
+ * Finds groups.
+ */
+ public Enumeration<IGroup> 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) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_FIND_GROUPS", e.toString()));
+ return null;
+ } catch (ELdapException 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<IGroup> groups = findGroups(filter);
+
+ if (groups == null || !groups.hasMoreElements())
+ return null;
+ return groups.nextElement();
+ }
+
+ /**
+ * List groups. more efficient than find Groups. only retrieves
+ * group names and description.
+ */
+ public Enumeration<IGroup> 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) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_LIST_GROUPS", e.toString()));
+ } catch (ELdapException 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) {
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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;
+ }
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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<IGroup> 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;
+ }
+ @SuppressWarnings("unchecked")
+ Enumeration<String> 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()) {
+ res.nextElement(); // consume the entry
+ 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<String> 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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 desc = grp.getDescription();
+
+ if (desc != null) {
+ mod.add(LDAPModification.REPLACE,
+ new LDAPAttribute("description", desc));
+ }
+
+ Enumeration<String> 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) {
+ 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) {
+ 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/base/common/src/com/netscape/cmscore/usrgrp/User.java b/base/common/src/com/netscape/cmscore/usrgrp/User.java
new file mode 100644
index 000000000..89ea3e589
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/usrgrp/User.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.cmscore.usrgrp;
+
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.usrgrp.IUser;
+import com.netscape.certsrv.usrgrp.IUsrGrp;
+
+/**
+ * A class represents a user.
+ *
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class User implements IUser {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7407288327775546979L;
+ 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<String> mNames = new Vector<String>();
+ 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<String> getElements() {
+ return mNames.elements();
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/util/Assert.java b/base/common/src/com/netscape/cmscore/util/Assert.java
new file mode 100644
index 000000000..246599290
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/util/Assert.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.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/base/common/src/com/netscape/cmscore/util/AssertionException.java b/base/common/src/com/netscape/cmscore/util/AssertionException.java
new file mode 100644
index 000000000..46b3f32da
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/util/AssertionException.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.util;
+
+/**
+ * Assertion exceptions are thrown when assertion code is invoked
+ * and fails to operate properly.
+ */
+public class AssertionException extends Error {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5647721098177211353L;
+
+ public AssertionException() {
+ }
+
+ public AssertionException(String msg) {
+ super(msg);
+ }
+}
diff --git a/base/common/src/com/netscape/cmscore/util/Debug.java b/base/common/src/com/netscape/cmscore/util/Debug.java
new file mode 100644
index 000000000..8c41d5bb5
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/util/Debug.java
@@ -0,0 +1,385 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.FileOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.cmsutil.util.Utils;
+
+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<SimpleDateFormat> mFormatObject = new ThreadLocal<SimpleDateFormat>() {
+ protected synchronized SimpleDateFormat initialValue() {
+ return new SimpleDateFormat(DATE_PATTERN);
+ }
+ };
+
+ /* the dateformatter should be accessed with this function */
+ private static SimpleDateFormat getDateFormatter() {
+ return 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<String, String> 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(&quot;obj is: &quot; + 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<String, String>();
+ 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/base/common/src/com/netscape/cmscore/util/ExceptionFormatter.java b/base/common/src/com/netscape/cmscore/util/ExceptionFormatter.java
new file mode 100644
index 000000000..88dd32a05
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/util/ExceptionFormatter.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.cmscore.util;
+
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.PrintWriter;
+
+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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5737463439434110385L;
+
+ public TestException() {
+ }
+
+ public TestException(String s) {
+ super(s);
+ }
+
+}
diff --git a/base/common/src/com/netscape/cmscore/util/FileAsString.java b/base/common/src/com/netscape/cmscore/util/FileAsString.java
new file mode 100644
index 000000000..7853346f5
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/util/FileAsString.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.cmscore.util;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+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);
+ }
+ } 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) {
+ 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/base/common/src/com/netscape/cmscore/util/FileDialogFilter.java b/base/common/src/com/netscape/cmscore/util/FileDialogFilter.java
new file mode 100644
index 000000000..eb1d1097a
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/util/FileDialogFilter.java
@@ -0,0 +1,143 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.File;
+import java.io.FilenameFilter;
+
+/**
+ * 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 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/base/common/src/com/netscape/cmscore/util/PFXUtils.java b/base/common/src/com/netscape/cmscore/util/PFXUtils.java
new file mode 100644
index 000000000..ed0e6d641
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/util/PFXUtils.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.util;
+
+import java.io.ByteArrayOutputStream;
+import java.security.MessageDigest;
+import java.security.cert.X509Certificate;
+
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.BMPString;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.crypto.PBEAlgorithm;
+import org.mozilla.jss.pkcs12.AuthenticatedSafes;
+import org.mozilla.jss.pkcs12.CertBag;
+import org.mozilla.jss.pkcs12.PFX;
+import org.mozilla.jss.pkcs12.PasswordConverter;
+import org.mozilla.jss.pkcs12.SafeBag;
+import org.mozilla.jss.pkix.primitive.EncryptedPrivateKeyInfo;
+import org.mozilla.jss.pkix.primitive.PrivateKeyInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+
+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/base/common/src/com/netscape/cmscore/util/ProfileSubsystem.java b/base/common/src/com/netscape/cmscore/util/ProfileSubsystem.java
new file mode 100644
index 000000000..caf05c6df
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/util/ProfileSubsystem.java
@@ -0,0 +1,312 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 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.Frame;
+import java.awt.TextArea;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.Vector;
+
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTable;
+import javax.swing.JTextArea;
+import javax.swing.table.AbstractTableModel;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+
+/**
+ * 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 static final long serialVersionUID = -7411549542009497317L;
+ 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<Vector<String>> data = new Vector<Vector<String>>();
+ Thread threads[] = new Thread[100];
+ int numThreads = Thread.enumerate(threads);
+
+ for (int i = 0; i < numThreads; i++) {
+ Vector<String> row = new Vector<String>();
+
+ 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<String> colNames = new Vector<String>();
+
+ 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
+ Thread.sleep(1000);
+ } catch (Exception e) {
+ }
+ }
+ }
+}
+
+class ThreadTableModel extends AbstractTableModel {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6977965542104110870L;
+ Vector<Vector<String>> rowData;
+ Vector<String> columnNames;
+
+ public ThreadTableModel() {
+ }
+
+ public void setInfo(Vector<Vector<String>> _rowData, Vector<String> _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 String getValueAt(int row, int column) {
+ return rowData.elementAt(row).elementAt(column);
+ }
+
+ public boolean isCellEditable(int row, int column) {
+ return false;
+ }
+
+ public void setValueAt(String value, int row, int column) {
+ 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));
+ //TODO remove. This was being called on the array object
+ //But you can only dump stack on the current thread
+ Thread.dumpStack();
+
+ 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/base/common/src/com/netscape/cmscore/util/StatsSubsystem.java b/base/common/src/com/netscape/cmscore/util/StatsSubsystem.java
new file mode 100644
index 000000000..222964261
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/util/StatsSubsystem.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.cmscore.util;
+
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.util.IStatsSubsystem;
+import com.netscape.certsrv.util.StatsEvent;
+
+/**
+ * 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<String, Vector<StatsMilestone>> mHashtable = new Hashtable<String, Vector<StatsMilestone>>();
+
+ /**
+ * 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<StatsMilestone> milestones = null;
+ if (mHashtable.containsKey(t.toString())) {
+ milestones = mHashtable.get(t.toString());
+ } else {
+ milestones = new Vector<StatsMilestone>();
+ 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<StatsMilestone> milestones = mHashtable.get(t.toString());
+ if (milestones.size() == 0) {
+ return; /* error */
+ }
+ StatsMilestone last = 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/base/common/src/com/netscape/cmscore/util/UtilMessage.java b/base/common/src/com/netscape/cmscore/util/UtilMessage.java
new file mode 100644
index 000000000..8002cfe1f
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/util/UtilMessage.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.cmscore.util;
+
+import java.util.Locale;
+
+import com.netscape.certsrv.base.MessageFormatter;
+
+/**
+ * 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(&quot;failed to load {0}&quot;, 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/base/common/src/com/netscape/cmscore/util/UtilResources.java b/base/common/src/com/netscape/cmscore/util/UtilResources.java
new file mode 100644
index 000000000..6955dda50
--- /dev/null
+++ b/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.ListResourceBundle;
+
+/**
+ * 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/base/common/test/CMakeLists.txt b/base/common/test/CMakeLists.txt
new file mode 100644
index 000000000..2f7b4fa4e
--- /dev/null
+++ b/base/common/test/CMakeLists.txt
@@ -0,0 +1,103 @@
+project(pki-common-test Java)
+
+find_file(PKI_CERTSRV_JAR
+ NAMES
+ pki-certsrv.jar
+ PATHS
+ ${JAVA_JAR_INSTALL_DIR}/pki
+)
+
+find_file(PKI_CMS_JAR
+ NAMES
+ pki-cms
+ PATHS
+ ${JAVA_JAR_INSTALL_DIR}/pki
+)
+
+find_file(PKI_CMSCORE_JAR
+ NAMES
+ pki-cmscore
+ PATHS
+ ${JAVA_JAR_INSTALL_DIR}/pki
+)
+
+find_file(PKI_CMSBUNDLE_JAR
+ NAMES
+ pki-cmsbundle
+ PATHS
+ ${JAVA_JAR_INSTALL_DIR}/pki
+)
+
+# TODO: create CMake function to find all Java files
+set(pki-common-test_SRCS
+ com/netscape/certsrv/app/CMSEngineDefaultStub.java
+ com/netscape/certsrv/authentication/AuthTokenTest.java
+ com/netscape/certsrv/logging/LoggerDefaultStub.java
+ com/netscape/certsrv/request/AgentApprovalsTest.java
+ com/netscape/cmscore/dbs/CertRecordListTest.java
+ com/netscape/cmscore/dbs/DBRegistryDefaultStub.java
+ com/netscape/cmscore/dbs/DBRegistryTest.java
+ com/netscape/cmscore/dbs/DBSSessionDefaultStub.java
+ com/netscape/cmscore/dbs/DBSubsystemDefaultStub.java
+ com/netscape/cmscore/dbs/DBVirtualListDefaultStub.java
+ com/netscape/cmscore/dbs/RequestRecordDefaultStub.java
+ com/netscape/cmscore/request/DBDynAttrMapperDefaultStub.java
+ com/netscape/cmscore/request/ExtAttrDynMapperTest.java
+ com/netscape/cmscore/request/ExtDataHashtableTest.java
+ com/netscape/cmscore/request/RequestDefaultStub.java
+ com/netscape/cmscore/request/RequestModDefaultStub.java
+ com/netscape/cmscore/request/RequestQueueTest.java
+ com/netscape/cmscore/request/RequestRecordTest.java
+ com/netscape/cmscore/request/RequestTest.java
+ com/netscape/cmscore/test/CMSBaseTestCase.java
+ com/netscape/cmscore/test/TestHelper.java
+)
+
+set(CMAKE_JAVA_INCLUDE_PATH
+ ${PKI_NSUTIL_JAR} ${PKI_CMSUTIL_JAR}
+ ${PKI_CERTSRV_JAR} ${PKI_CMS_JAR} ${PKI_CMSCORE_JAR} ${PKI_CMSBUNDLE_JAR}
+ ${LDAPJDK_JAR} ${SERVLET_JAR} ${VELOCITY_JAR} ${XALAN_JAR} ${XERCES_JAR}
+ ${JSS_JAR} ${COMMONS_CODEC_JAR} ${SYMKEY_JAR}
+ ${PKI_TEST_JAR} ${JUNIT_JAR}
+)
+
+set(CMAKE_JAVA_TARGET_VERSION ${APPLICATION_VERSION})
+
+# build test jar file
+# TODO: create CMake function to compile without building jar file
+# TODO: build test only when the test is invoked
+set(CMAKE_JAR_CLASSES_PREFIX com/netscape)
+add_jar(pki-common-test ${pki-common-test_SRCS})
+add_dependencies(pki-common-test
+ pki-nsutil pki-cmsutil
+ pki-certsrv pki-cms pki-cmscore pki-cmsbundle
+ pki-test
+)
+
+# create test target
+# do not include xalan and xerces in class path
+# TODO: create CMake function to find all JUnit test classes
+add_junit_test(test-pki-common
+ CLASSPATH
+ ${pki-common-test_JAR_FILE}
+ ${PKI_NSUTIL_JAR} ${PKI_CMSUTIL_JAR}
+ ${PKI_CERTSRV_JAR} ${PKI_CMS_JAR} ${PKI_CMSCORE_JAR} ${PKI_CMSBUNDLE_JAR}
+ ${LDAPJDK_JAR} ${SERVLET_JAR} ${VELOCITY_JAR}
+ ${JSS_JAR} ${COMMONS_CODEC_JAR} ${SYMKEY_JAR}
+ ${PKI_TEST_JAR} ${JUNIT_JAR}
+ TESTS
+ com.netscape.certsrv.authentication.AuthTokenTest
+ com.netscape.certsrv.request.AgentApprovalsTest
+ com.netscape.cmscore.dbs.CertRecordListTest
+ com.netscape.cmscore.dbs.DBRegistryTest
+ com.netscape.cmscore.request.ExtAttrDynMapperTest
+ com.netscape.cmscore.request.ExtDataHashtableTest
+ com.netscape.cmscore.request.RequestQueueTest
+ com.netscape.cmscore.request.RequestRecordTest
+ com.netscape.cmscore.request.RequestTest
+ REPORTS_DIR
+ reports
+)
+
+# include test into the main test
+add_dependencies(test test-pki-common)
diff --git a/base/common/test/com/netscape/certsrv/app/CMSEngineDefaultStub.java b/base/common/test/com/netscape/certsrv/app/CMSEngineDefaultStub.java
new file mode 100644
index 000000000..cddd1205a
--- /dev/null
+++ b/base/common/test/com/netscape/certsrv/app/CMSEngineDefaultStub.java
@@ -0,0 +1,632 @@
+package com.netscape.certsrv.app;
+
+import java.math.BigInteger;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSSLSocketFactoryExt;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.Extension;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.X509CertInfo;
+
+import org.mozilla.jss.CryptoManager.CertificateUsage;
+import org.mozilla.jss.util.PasswordCallback;
+
+import com.netscape.certsrv.acls.EACLsException;
+import com.netscape.certsrv.acls.IACL;
+import com.netscape.certsrv.apps.ICMSEngine;
+import com.netscape.certsrv.apps.ICommandQueue;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.ICRLPrettyPrint;
+import com.netscape.certsrv.base.ICertPrettyPrint;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtPrettyPrint;
+import com.netscape.certsrv.base.IPrettyPrintFormat;
+import com.netscape.certsrv.base.ISecurityDomainSessionTable;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ca.ICRLIssuingPoint;
+import com.netscape.certsrv.connector.IHttpConnection;
+import com.netscape.certsrv.connector.IPKIMessage;
+import com.netscape.certsrv.connector.IRemoteAuthority;
+import com.netscape.certsrv.connector.IRequestEncoder;
+import com.netscape.certsrv.connector.IResender;
+import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.dbs.repository.IRepositoryRecord;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ILdapAuthInfo;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.ldap.ILdapConnInfo;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.notification.IEmailFormProcessor;
+import com.netscape.certsrv.notification.IEmailResolver;
+import com.netscape.certsrv.notification.IEmailResolverKeys;
+import com.netscape.certsrv.notification.IEmailTemplate;
+import com.netscape.certsrv.notification.IMailNotification;
+import com.netscape.certsrv.password.IPasswordCheck;
+import com.netscape.certsrv.policy.IGeneralNameAsConstraintsConfig;
+import com.netscape.certsrv.policy.IGeneralNamesAsConstraintsConfig;
+import com.netscape.certsrv.policy.IGeneralNamesConfig;
+import com.netscape.certsrv.policy.ISubjAltNameConfig;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cmsutil.net.ISocketFactory;
+import com.netscape.cmsutil.password.IPasswordStore;
+
+/**
+ * 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<String> getSubsystemNames() {
+ return null;
+ }
+
+ public Enumeration<ISubsystem> 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 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 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 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;
+ }
+
+ @Override
+ public String getEEClientAuthSSLPort() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public boolean verifySystemCerts() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean verifySystemCertByTag(String tag) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean verifySystemCertByNickname(String nickname,
+ String certificateUsage) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public CertificateUsage getCertificateUsage(String certusage) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void getGeneralNameConfigDefaultParams(String name,
+ boolean isValueConfigured, Vector<String> params) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void getGeneralNamesConfigDefaultParams(String name,
+ boolean isValueConfigured, Vector<String> params) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void getGeneralNameConfigExtendedPluginInfo(String name,
+ boolean isValueConfigured, Vector<String> info) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void getGeneralNamesConfigExtendedPluginInfo(String name,
+ boolean isValueConfigured, Vector<String> info) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void getSubjAltNameConfigDefaultParams(String name,
+ Vector<String> params) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void getSubjAltNameConfigExtendedPluginInfo(String name,
+ Vector<String> params) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public IArgBlock createArgBlock(String realm,
+ Hashtable<String, String> httpReq) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public IArgBlock createArgBlock(Hashtable<String, String> httpReq) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+}
diff --git a/base/common/test/com/netscape/certsrv/authentication/AuthTokenTest.java b/base/common/test/com/netscape/certsrv/authentication/AuthTokenTest.java
new file mode 100644
index 000000000..c60e93d99
--- /dev/null
+++ b/base/common/test/com/netscape/certsrv/authentication/AuthTokenTest.java
@@ -0,0 +1,271 @@
+package com.netscape.certsrv.authentication;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import netscape.security.util.DerOutputStream;
+import netscape.security.x509.BasicConstraintsExtension;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.app.CMSEngineDefaultStub;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.usrgrp.Certificates;
+import com.netscape.cmscore.test.CMSBaseTestCase;
+
+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/base/common/test/com/netscape/certsrv/logging/LoggerDefaultStub.java b/base/common/test/com/netscape/certsrv/logging/LoggerDefaultStub.java
new file mode 100644
index 000000000..c136c7feb
--- /dev/null
+++ b/base/common/test/com/netscape/certsrv/logging/LoggerDefaultStub.java
@@ -0,0 +1,71 @@
+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/base/common/test/com/netscape/certsrv/request/AgentApprovalsTest.java b/base/common/test/com/netscape/certsrv/request/AgentApprovalsTest.java
new file mode 100644
index 000000000..e7606951d
--- /dev/null
+++ b/base/common/test/com/netscape/certsrv/request/AgentApprovalsTest.java
@@ -0,0 +1,82 @@
+package com.netscape.certsrv.request;
+
+import java.util.Vector;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import com.netscape.cmscore.test.CMSBaseTestCase;
+
+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<String> 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<String>();
+ stringVector.add("foo");
+ assertNull(AgentApprovals.fromStringVector(stringVector));
+
+ stringVector = new Vector<String>();
+ stringVector.add(";foo");
+ assertNull(AgentApprovals.fromStringVector(stringVector));
+
+ stringVector = new Vector<String>();
+ stringVector.add("bar;foo");
+ assertNull(AgentApprovals.fromStringVector(stringVector));
+
+ stringVector = new Vector<String>();
+ stringVector.add("00123b;foo");
+ assertNull(AgentApprovals.fromStringVector(stringVector));
+
+ assertNull(AgentApprovals.fromStringVector(null));
+ }
+}
diff --git a/base/common/test/com/netscape/cmscore/dbs/CertRecordListTest.java b/base/common/test/com/netscape/cmscore/dbs/CertRecordListTest.java
new file mode 100644
index 000000000..d3177f62c
--- /dev/null
+++ b/base/common/test/com/netscape/cmscore/dbs/CertRecordListTest.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 junit.framework.Test;
+import junit.framework.TestSuite;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IElementProcessor;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+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<ICertRecord> dbList = new DBVirtualListStub<ICertRecord>();
+ 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<T> extends DBVirtualListDefaultStub<T> {
+ public int size = 0;
+ public int getElementAtCallCount = 0;
+ public int lastIndexGetElementAtCalledWith = 0;
+
+ public T 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/base/common/test/com/netscape/cmscore/dbs/DBRegistryDefaultStub.java b/base/common/test/com/netscape/cmscore/dbs/DBRegistryDefaultStub.java
new file mode 100644
index 000000000..9635129f4
--- /dev/null
+++ b/base/common/test/com/netscape/cmscore/dbs/DBRegistryDefaultStub.java
@@ -0,0 +1,79 @@
+package com.netscape.cmscore.dbs;
+
+import netscape.ldap.LDAPAttributeSet;
+
+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.IDBAttrMapper;
+import com.netscape.certsrv.dbs.IDBDynAttrMapper;
+import com.netscape.certsrv.dbs.IDBObj;
+import com.netscape.certsrv.dbs.IDBRegistry;
+import com.netscape.certsrv.dbs.IFilterConverter;
+
+/**
+ * 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/base/common/test/com/netscape/cmscore/dbs/DBRegistryTest.java b/base/common/test/com/netscape/cmscore/dbs/DBRegistryTest.java
new file mode 100644
index 000000000..c74f66ba1
--- /dev/null
+++ b/base/common/test/com/netscape/cmscore/dbs/DBRegistryTest.java
@@ -0,0 +1,175 @@
+package com.netscape.cmscore.dbs;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+
+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.test.CMSBaseTestCase;
+import com.netscape.cmscore.test.TestHelper;
+
+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 {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2155124580267335995L;
+
+ 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<String> getSerializableAttrNames() {
+ getSerializedAttrNamesCalled = true;
+ return Collections.enumeration(Arrays.asList(attrs));
+ }
+}
diff --git a/base/common/test/com/netscape/cmscore/dbs/DBSSessionDefaultStub.java b/base/common/test/com/netscape/cmscore/dbs/DBSSessionDefaultStub.java
new file mode 100644
index 000000000..09a2e1498
--- /dev/null
+++ b/base/common/test/com/netscape/cmscore/dbs/DBSSessionDefaultStub.java
@@ -0,0 +1,79 @@
+package com.netscape.cmscore.dbs;
+
+import netscape.ldap.LDAPSearchResults;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.dbs.EDBException;
+import com.netscape.certsrv.dbs.IDBObj;
+import com.netscape.certsrv.dbs.IDBSSession;
+import com.netscape.certsrv.dbs.IDBSearchResults;
+import com.netscape.certsrv.dbs.IDBVirtualList;
+import com.netscape.certsrv.dbs.ModificationSet;
+
+/**
+ * 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 <T> IDBVirtualList<T> 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 void abandon(LDAPSearchResults results) throws EBaseException {
+ }
+
+ public <T> IDBVirtualList<T> createVirtualList(String base, String filter, String attrs[], String sortKey, int pageSize)
+ throws EBaseException {
+ return null;
+ }
+
+ public <T> IDBVirtualList<T> createVirtualList(String base, String filter, String attrs[], String startFrom,
+ String sortKey, int pageSize) throws EBaseException {
+ return null;
+ }
+}
diff --git a/base/common/test/com/netscape/cmscore/dbs/DBSubsystemDefaultStub.java b/base/common/test/com/netscape/cmscore/dbs/DBSubsystemDefaultStub.java
new file mode 100644
index 000000000..fe19159d5
--- /dev/null
+++ b/base/common/test/com/netscape/cmscore/dbs/DBSubsystemDefaultStub.java
@@ -0,0 +1,172 @@
+package com.netscape.cmscore.dbs;
+
+import java.math.BigInteger;
+
+import netscape.ldap.LDAPConnection;
+
+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;
+
+/**
+ * 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;
+ }
+
+ @Override
+ public void setMaxSerialConfig(int repo, String serial)
+ throws EBaseException {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void setMinSerialConfig(int repo, String serial)
+ throws EBaseException {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void setNextMaxSerialConfig(int repo, String serial)
+ throws EBaseException {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void setNextMinSerialConfig(int repo, String serial)
+ throws EBaseException {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public String getMinSerialConfig(int repo) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getMaxSerialConfig(int repo) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getNextMaxSerialConfig(int repo) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getNextMinSerialConfig(int repo) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getLowWaterMarkConfig(int repo) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getIncrementConfig(int repo) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getNextRange(int repo) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public boolean hasRangeConflict(int repo) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean getEnableSerialMgmt() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public void setEnableSerialMgmt(boolean value) throws EBaseException {
+ // TODO Auto-generated method stub
+
+ }
+}
diff --git a/base/common/test/com/netscape/cmscore/dbs/DBVirtualListDefaultStub.java b/base/common/test/com/netscape/cmscore/dbs/DBVirtualListDefaultStub.java
new file mode 100644
index 000000000..d674bd6a6
--- /dev/null
+++ b/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<T> implements IDBVirtualList<T> {
+
+ 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 T getElementAt(int index) {
+ return null;
+ }
+
+ public T 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/base/common/test/com/netscape/cmscore/dbs/RequestRecordDefaultStub.java b/base/common/test/com/netscape/cmscore/dbs/RequestRecordDefaultStub.java
new file mode 100644
index 000000000..1814c90d6
--- /dev/null
+++ b/base/common/test/com/netscape/cmscore/dbs/RequestRecordDefaultStub.java
@@ -0,0 +1,44 @@
+package com.netscape.cmscore.dbs;
+
+import java.util.Enumeration;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBObj;
+import com.netscape.certsrv.request.IRequestRecord;
+import com.netscape.certsrv.request.RequestId;
+
+/**
+ * Default stub for RequestRecord tests.
+ */
+public class RequestRecordDefaultStub implements IRequestRecord, IDBObj {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3486144284074519531L;
+
+ public RequestId getRequestId() {
+ return null;
+ }
+
+ public Enumeration<String> 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<String> getElements() {
+ return null;
+ }
+
+ public Enumeration<String> getSerializableAttrNames() {
+ return null;
+ }
+}
diff --git a/base/common/test/com/netscape/cmscore/request/DBDynAttrMapperDefaultStub.java b/base/common/test/com/netscape/cmscore/request/DBDynAttrMapperDefaultStub.java
new file mode 100644
index 000000000..cccbe600f
--- /dev/null
+++ b/base/common/test/com/netscape/cmscore/request/DBDynAttrMapperDefaultStub.java
@@ -0,0 +1,33 @@
+package com.netscape.cmscore.request;
+
+import java.util.Enumeration;
+
+import netscape.ldap.LDAPAttributeSet;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.IDBDynAttrMapper;
+import com.netscape.certsrv.dbs.IDBObj;
+
+/**
+ * Default testing stub for the IRequest interface.
+ */
+public class DBDynAttrMapperDefaultStub implements IDBDynAttrMapper {
+ public boolean supportsLDAPAttributeName(String attrName) {
+ return false;
+ }
+
+ public Enumeration<String> 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/base/common/test/com/netscape/cmscore/request/ExtAttrDynMapperTest.java b/base/common/test/com/netscape/cmscore/request/ExtAttrDynMapperTest.java
new file mode 100644
index 000000000..a0ad0a8a3
--- /dev/null
+++ b/base/common/test/com/netscape/cmscore/request/ExtAttrDynMapperTest.java
@@ -0,0 +1,278 @@
+package com.netscape.cmscore.request;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+
+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<String> attrs = mapper.getSupportedLDAPAttributeNames();
+ ArrayList<String> attrsList = new ArrayList<String>();
+ 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<String, Serializable> extAttrsHash = new Hashtable<String, Serializable>();
+ 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<String, String> extAttrsValueHash = new Hashtable<String, String>();
+ 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 {
+ private static final long serialVersionUID = 4106967075497999274L;
+ Hashtable<String, Object> extAttrData = new Hashtable<String, Object>();
+ 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/base/common/test/com/netscape/cmscore/request/ExtDataHashtableTest.java b/base/common/test/com/netscape/cmscore/request/ExtDataHashtableTest.java
new file mode 100644
index 000000000..c349b73d0
--- /dev/null
+++ b/base/common/test/com/netscape/cmscore/request/ExtDataHashtableTest.java
@@ -0,0 +1,81 @@
+package com.netscape.cmscore.request;
+
+import java.util.Hashtable;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import com.netscape.cmscore.test.CMSBaseTestCase;
+
+public class ExtDataHashtableTest extends CMSBaseTestCase {
+
+ ExtDataHashtable<String> hash;
+
+ public ExtDataHashtableTest(String name) {
+ super(name);
+ }
+
+ public void cmsTestSetUp() {
+ hash = new ExtDataHashtable<String>();
+ }
+
+ 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<String, String> hash2 = new Hashtable<String, String>();
+ 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<String, String> hash2 = new Hashtable<String, String>();
+ hash2.put("KEY1", "VAL1");
+ hash2.put("KEY2", "val2");
+
+ hash = new ExtDataHashtable<String>(hash2);
+
+ assertTrue(hash.containsKey("key1"));
+ assertEquals("VAL1", hash.get("key1"));
+ assertEquals("val2", hash.get("Key2"));
+ }
+
+}
diff --git a/base/common/test/com/netscape/cmscore/request/RequestDefaultStub.java b/base/common/test/com/netscape/cmscore/request/RequestDefaultStub.java
new file mode 100644
index 000000000..fd53c2ea9
--- /dev/null
+++ b/base/common/test/com/netscape/cmscore/request/RequestDefaultStub.java
@@ -0,0 +1,269 @@
+package com.netscape.cmscore.request;
+
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.IAttrSet;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+
+/**
+ * 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<String> 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<String, String> value) {
+ return false;
+ }
+
+ public boolean isSimpleExtDataValue(String key) {
+ return false;
+ }
+
+ public String getExtDataInString(String key) {
+ return null;
+ }
+
+ public Hashtable<String, String> getExtDataInHashtable(String key) {
+ return null;
+ }
+
+ public Enumeration<String> 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<String> 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/base/common/test/com/netscape/cmscore/request/RequestModDefaultStub.java b/base/common/test/com/netscape/cmscore/request/RequestModDefaultStub.java
new file mode 100644
index 000000000..730928bdb
--- /dev/null
+++ b/base/common/test/com/netscape/cmscore/request/RequestModDefaultStub.java
@@ -0,0 +1,21 @@
+package com.netscape.cmscore.request;
+
+import java.util.Date;
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.request.ldap.IRequestMod;
+
+/**
+ * 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/base/common/test/com/netscape/cmscore/request/RequestQueueTest.java b/base/common/test/com/netscape/cmscore/request/RequestQueueTest.java
new file mode 100644
index 000000000..a66326d03
--- /dev/null
+++ b/base/common/test/com/netscape/cmscore/request/RequestQueueTest.java
@@ -0,0 +1,60 @@
+package com.netscape.cmscore.request;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.cmscore.test.CMSBaseTestCase;
+
+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<String> 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/base/common/test/com/netscape/cmscore/request/RequestRecordTest.java b/base/common/test/com/netscape/cmscore/request/RequestRecordTest.java
new file mode 100644
index 000000000..0ebf3beab
--- /dev/null
+++ b/base/common/test/com/netscape/cmscore/request/RequestRecordTest.java
@@ -0,0 +1,168 @@
+package com.netscape.cmscore.request;
+
+import java.util.Hashtable;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.EDBException;
+import com.netscape.certsrv.dbs.IDBAttrMapper;
+import com.netscape.certsrv.dbs.IDBDynAttrMapper;
+import com.netscape.certsrv.dbs.IDBRegistry;
+import com.netscape.certsrv.dbs.ModificationSet;
+import com.netscape.certsrv.request.IRequestRecord;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.cmscore.dbs.DBRegistryDefaultStub;
+import com.netscape.cmscore.dbs.DBSubsystemDefaultStub;
+import com.netscape.cmscore.test.CMSBaseTestCase;
+import com.netscape.cmscore.test.TestHelper;
+
+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("0xabcdef"));
+ }
+
+ public void cmsTestTearDown() {
+ }
+
+ public static Test suite() {
+ return new TestSuite(RequestRecordTest.class);
+ }
+
+ public void testGetExtData() {
+ Hashtable<String, Object> hash = new Hashtable<String, Object>();
+
+ assertNotSame(hash, requestRecord.get(IRequestRecord.ATTR_EXT_DATA));
+ requestRecord.mExtData = hash;
+ assertSame(hash, requestRecord.get(IRequestRecord.ATTR_EXT_DATA));
+ }
+
+ public void testSetExtData() {
+ Hashtable<String, Object> hash = new Hashtable<String, Object>();
+
+ 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<String, String> requestHashValue = new Hashtable<String, String>();
+ 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<String, Object> extData = new Hashtable<String, Object>();
+ extData.put("foo", "bar");
+ Hashtable<String, String> extDataHashValue = new Hashtable<String, String>();
+ 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/base/common/test/com/netscape/cmscore/request/RequestTest.java b/base/common/test/com/netscape/cmscore/request/RequestTest.java
new file mode 100644
index 000000000..5832f6af5
--- /dev/null
+++ b/base/common/test/com/netscape/cmscore/request/RequestTest.java
@@ -0,0 +1,649 @@
+package com.netscape.cmscore.request;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.CRLException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import netscape.security.x509.BasicConstraintsExtension;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.app.CMSEngineDefaultStub;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.cmscore.test.CMSBaseTestCase;
+import com.netscape.cmscore.test.TestHelper;
+
+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("0xabcdef"));
+ }
+
+ 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<String, Object>());
+
+ 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<String, String> valueHash = new Hashtable<String, String>();
+
+ valueHash.put("key1", "val1");
+ valueHash.put("key;2", "val2");
+ assertTrue(request.isValidExtDataHashtableValue(valueHash));
+
+ valueHash.clear();
+ valueHash.put("", "bar");
+ assertFalse(request.isValidExtDataHashtableValue(valueHash));
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public void testSetExtHashtableData() {
+ Hashtable<String, String> valueHash = new Hashtable<String, String>();
+
+ valueHash.put("key1", "val1");
+ valueHash.put("KEY2", "val2");
+
+ request.setExtData("TOPKEY", valueHash);
+
+ Hashtable<String, String> 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<String, String> hashValue = new Hashtable<String, String>();
+ 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<String, String> hashValue = new Hashtable<String, String>();
+ hashValue.put("uh", "oh");
+ request.mExtData.put("hashkey", hashValue);
+
+ Hashtable<String, String> 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<String, String>());
+
+ 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<String, String> 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<String, String>();
+ 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<String, String> value = new Hashtable<String, String>();
+ 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<String, String> hashValue = new Hashtable<String, String>();
+ 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<String, String> hashValue = new Hashtable<String, String>();
+ 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"));
+ @SuppressWarnings("unchecked")
+ Hashtable<String, String> hashValue = (Hashtable<String, String>) 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<String, String>();
+ 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<String, String>();
+ 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<String> stringVector = new Vector<String>();
+ stringVector.add("blue");
+ stringVector.add("green");
+ stringVector.add("red");
+ stringVector.add("orange");
+
+ assertTrue(request.setExtData("key", stringVector));
+
+ assertTrue(request.mExtData.containsKey("key"));
+ @SuppressWarnings("unchecked")
+ Hashtable<String, String> hashValue = (Hashtable<String, String>) 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<String> 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<String, String>();
+ 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<String, String> hashValue = new Hashtable<String, String>();
+ 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 {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -821992386369710423L;
+ boolean getEncodedCalled = false;
+
+ public X509CertInfoStub() {
+ }
+
+ public byte[] getEncodedInfo(boolean ignoreCache) throws CertificateEncodingException {
+ getEncodedCalled = true;
+ return new byte[] {};
+ }
+ }
+
+ class RevokedCertImplStub extends RevokedCertImpl {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -9088436260566619005L;
+ boolean getEncodedCalled = false;
+
+ public byte[] getEncoded() throws CRLException {
+ getEncodedCalled = true;
+ return new byte[] {};
+ }
+ }
+
+}
diff --git a/base/common/test/com/netscape/cmscore/test/CMSBaseTestCase.java b/base/common/test/com/netscape/cmscore/test/CMSBaseTestCase.java
new file mode 100644
index 000000000..d3971afd4
--- /dev/null
+++ b/base/common/test/com/netscape/cmscore/test/CMSBaseTestCase.java
@@ -0,0 +1,99 @@
+package com.netscape.cmscore.test;
+
+import java.security.cert.CertificateException;
+
+import junit.framework.TestCase;
+import netscape.security.x509.X509CertImpl;
+
+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;
+
+/**
+ * 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/base/common/test/com/netscape/cmscore/test/TestHelper.java b/base/common/test/com/netscape/cmscore/test/TestHelper.java
new file mode 100644
index 000000000..55d2ac7f7
--- /dev/null
+++ b/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;
+ }
+
+}
diff --git a/base/console/CMakeLists.txt b/base/console/CMakeLists.txt
new file mode 100644
index 000000000..24adfac49
--- /dev/null
+++ b/base/console/CMakeLists.txt
@@ -0,0 +1,4 @@
+project(console Java)
+
+add_subdirectory(src)
+add_subdirectory(templates)
diff --git a/base/console/LICENSE b/base/console/LICENSE
new file mode 100644
index 000000000..e281f4362
--- /dev/null
+++ b/base/console/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/base/console/src/CMakeLists.txt b/base/console/src/CMakeLists.txt
new file mode 100644
index 000000000..175a4a1a7
--- /dev/null
+++ b/base/console/src/CMakeLists.txt
@@ -0,0 +1,661 @@
+project(pki-console_java Java)
+
+# '/usr/share/java/pki' jars
+find_file(PKI_NSUTIL_JAR
+ NAMES
+ pki-nsutil.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java/pki
+)
+
+
+# '/usr/share/java' jars
+find_file(BASE_JAR
+ NAMES
+ idm-console-base.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(LDAPJDK_JAR
+ NAMES
+ ldapjdk.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(MMC_JAR
+ NAMES
+ idm-console-mcc.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(MMC_EN_JAR
+ NAMES
+ idm-console-mcc_en.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(NMCLF_JAR
+ NAMES
+ idm-console-nmclf.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(NMCLF_EN_JAR
+ NAMES
+ idm-console-nmclf_en.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+
+# '${JAVA_LIB_INSTALL_DIR}' jars
+find_file(JSS_JAR
+ NAMES
+ jss4.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(COMMONS_CODEC_JAR
+ NAMES
+ commons-codec.jar
+ PATHS
+ /usr/share/java
+)
+
+
+# identify java sources
+set(pki-console_java_SRCS
+ 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/OpDef.java
+ com/netscape/certsrv/common/Constants.java
+ com/netscape/admin/certsrv/CMSCCMUILoader.java
+ com/netscape/admin/certsrv/IFilterPanel.java
+ com/netscape/admin/certsrv/CMSPageFeeder.java
+ com/netscape/admin/certsrv/CMSResourceObject.java
+ com/netscape/admin/certsrv/CMSOCSPUILoader.java
+ com/netscape/admin/certsrv/Console.java
+ com/netscape/admin/certsrv/connection/AdminConnection.java
+ com/netscape/admin/certsrv/connection/Response.java
+ com/netscape/admin/certsrv/connection/BasicAuthenticator.java
+ com/netscape/admin/certsrv/connection/JSSConnection.java
+ com/netscape/admin/certsrv/connection/IAuthenticator.java
+ com/netscape/admin/certsrv/connection/IConnectionFactory.java
+ com/netscape/admin/certsrv/connection/PromptForTrustDialog.java
+ com/netscape/admin/certsrv/connection/SSLConnectionFactory.java
+ com/netscape/admin/certsrv/connection/IConnection.java
+ com/netscape/admin/certsrv/connection/Request.java
+ com/netscape/admin/certsrv/CMSTaskModel.java
+ com/netscape/admin/certsrv/IEditorPanel.java
+ com/netscape/admin/certsrv/IAttributeContent.java
+ com/netscape/admin/certsrv/CMSAdmin.java
+ com/netscape/admin/certsrv/CMSBaseMenuInfo.java
+ com/netscape/admin/certsrv/CMSTaskObject.java
+ com/netscape/admin/certsrv/IResourceSelectionListener.java
+ com/netscape/admin/certsrv/PasswordCellRenderer.java
+ com/netscape/admin/certsrv/GenericCellEditor.java
+ com/netscape/admin/certsrv/CMSRAUILoader.java
+ com/netscape/admin/certsrv/CMSResourcePage.java
+ com/netscape/admin/certsrv/CustomComboBox.java
+ com/netscape/admin/certsrv/AttrCellRenderer.java
+ com/netscape/admin/certsrv/CMSAdminUtil.java
+ com/netscape/admin/certsrv/CMSCAUILoader.java
+ com/netscape/admin/certsrv/misc/MessageFormatter.java
+ com/netscape/admin/certsrv/CMSBasePanel.java
+ com/netscape/admin/certsrv/CMSAdminResources.java
+ com/netscape/admin/certsrv/managecert/ManageCertModel.java
+ com/netscape/admin/certsrv/managecert/ManageCertDialog.java
+ com/netscape/admin/certsrv/managecert/CertificateInfoDialog.java
+ com/netscape/admin/certsrv/EAdminException.java
+ com/netscape/admin/certsrv/CMSTableModel.java
+ com/netscape/admin/certsrv/IDisplayPanel.java
+ com/netscape/admin/certsrv/CustomComboBoxModel.java
+ com/netscape/admin/certsrv/CMSUIFramework.java
+ com/netscape/admin/certsrv/ISubSystemUILoader.java
+ com/netscape/admin/certsrv/CMSRemoteClassLoader.java
+ com/netscape/admin/certsrv/config/PolicyRuleDataModel.java
+ com/netscape/admin/certsrv/config/CMSBaseLDAPPanel.java
+ com/netscape/admin/certsrv/config/CMSSelfTestsPanel.java
+ com/netscape/admin/certsrv/config/RuleImplTab.java
+ com/netscape/admin/certsrv/config/ProfileEditDataModel.java
+ com/netscape/admin/certsrv/config/ProfileInstanceTab.java
+ com/netscape/admin/certsrv/config/ACLDataModel.java
+ com/netscape/admin/certsrv/config/PublisherRuleDataModel.java
+ com/netscape/admin/certsrv/config/MapperImplDataModel.java
+ com/netscape/admin/certsrv/config/ProfileComponentCellEditor.java
+ com/netscape/admin/certsrv/config/LogPluginSelectionDialog.java
+ com/netscape/admin/certsrv/config/RuleRegisterDialog.java
+ com/netscape/admin/certsrv/config/CMSBaseConfigPanel.java
+ com/netscape/admin/certsrv/config/CMSCRLFormatPanel.java
+ com/netscape/admin/certsrv/config/CRLIPEditor.java
+ com/netscape/admin/certsrv/config/CMSAccessLogPanel.java
+ com/netscape/admin/certsrv/config/WarningDialog.java
+ com/netscape/admin/certsrv/config/PolicyPluginSelectionDialog.java
+ com/netscape/admin/certsrv/config/ListCertsModel.java
+ com/netscape/admin/certsrv/config/CMSAutoRecovery.java
+ com/netscape/admin/certsrv/config/CRLExtensionsPluginSelectionDialog.java
+ com/netscape/admin/certsrv/config/CMSSNMPPanel.java
+ com/netscape/admin/certsrv/config/MapperImplTab.java
+ com/netscape/admin/certsrv/config/CRLExtensionsInstanceTab.java
+ com/netscape/admin/certsrv/config/ProfileRegisterDialog.java
+ com/netscape/admin/certsrv/config/CMSCipherPreferenceDialog.java
+ com/netscape/admin/certsrv/config/RegisterDialog.java
+ com/netscape/admin/certsrv/config/CMSCipherPreferencePane.java
+ com/netscape/admin/certsrv/config/ACIDialog.java
+ com/netscape/admin/certsrv/config/PolicyRuleOrderDialog.java
+ com/netscape/admin/certsrv/config/MapperPluginSelectionDialog.java
+ com/netscape/admin/certsrv/config/PolicyImplTab.java
+ com/netscape/admin/certsrv/config/ViewDialog.java
+ com/netscape/admin/certsrv/config/MapperRegisterDialog.java
+ com/netscape/admin/certsrv/config/JobsRuleDataModel.java
+ com/netscape/admin/certsrv/config/GeneralLogPanel.java
+ com/netscape/admin/certsrv/config/WMNSelection.java
+ com/netscape/admin/certsrv/config/OCSPStoresConfigDialog.java
+ com/netscape/admin/certsrv/config/PublisherPluginSelectionDialog.java
+ com/netscape/admin/certsrv/config/JobsImplDataModel.java
+ com/netscape/admin/certsrv/config/WBaseKeyPage.java
+ com/netscape/admin/certsrv/config/CMSRACLMPanel.java
+ com/netscape/admin/certsrv/config/WMNResultPage.java
+ com/netscape/admin/certsrv/config/WMNOldAgent.java
+ com/netscape/admin/certsrv/config/PolicyInstanceTab.java
+ com/netscape/admin/certsrv/config/ProfileImplTab.java
+ com/netscape/admin/certsrv/config/PluginSelectionDialog.java
+ com/netscape/admin/certsrv/config/CMSCRLSettingPanel.java
+ com/netscape/admin/certsrv/config/CMSCRLIPPanel.java
+ com/netscape/admin/certsrv/config/CMSLDAPSettingPanel.java
+ com/netscape/admin/certsrv/config/PublisherImplTab.java
+ com/netscape/admin/certsrv/config/RuleImplDataModel.java
+ com/netscape/admin/certsrv/config/ProfilePolicyEditDataModel.java
+ com/netscape/admin/certsrv/config/LogInstanceTab.java
+ com/netscape/admin/certsrv/config/CMSPasswordDialog.java
+ com/netscape/admin/certsrv/config/UserCertsTab.java
+ com/netscape/admin/certsrv/config/CMSSSL3CipherPreference.java
+ com/netscape/admin/certsrv/config/WBaseManualCertRequestPage.java
+ com/netscape/admin/certsrv/config/WBaseCertRequestPage.java
+ com/netscape/admin/certsrv/config/ProfileImplDataModel.java
+ com/netscape/admin/certsrv/config/JobsSettingPanel.java
+ com/netscape/admin/certsrv/config/CMSBaseConfigDialog.java
+ com/netscape/admin/certsrv/config/ViewTableModel.java
+ com/netscape/admin/certsrv/config/OCSPStoresPluginSelectionDialog.java
+ com/netscape/admin/certsrv/config/CMSCAConnectorPanel.java
+ com/netscape/admin/certsrv/config/CMSKRASchemePanel.java
+ com/netscape/admin/certsrv/config/RuleInstanceTab.java
+ com/netscape/admin/certsrv/config/PolicyConfigDialog.java
+ com/netscape/admin/certsrv/config/ConnectorEditor.java
+ com/netscape/admin/certsrv/config/ProfilePolicyNewDialog.java
+ com/netscape/admin/certsrv/config/CMSErrorLogPanel.java
+ com/netscape/admin/certsrv/config/RulePluginSelectionDialog.java
+ com/netscape/admin/certsrv/config/AutoRecoveryModel.java
+ com/netscape/admin/certsrv/config/PublisherInstanceTab.java
+ com/netscape/admin/certsrv/config/WBaseDNValidityPage.java
+ com/netscape/admin/certsrv/config/install/WITrustDBPage.java
+ com/netscape/admin/certsrv/config/install/WIRequestResultPage.java
+ com/netscape/admin/certsrv/config/install/WIPasteOCSPCertPage.java
+ com/netscape/admin/certsrv/config/install/WIRACertExtensionPage.java
+ com/netscape/admin/certsrv/config/install/WIKRANumberPage.java
+ com/netscape/admin/certsrv/config/install/WIKRARequestResultPage.java
+ com/netscape/admin/certsrv/config/install/WIGenCAKeyCertPage.java
+ com/netscape/admin/certsrv/config/install/WICACertValidityPage.java
+ com/netscape/admin/certsrv/config/install/WIRAMessageDigestPage.java
+ com/netscape/admin/certsrv/config/install/WICloneTKSKeyCertPage.java
+ com/netscape/admin/certsrv/config/install/WIInstallCACertStatusPage.java
+ com/netscape/admin/certsrv/config/install/WIGenOCSPKeyCertPage.java
+ com/netscape/admin/certsrv/config/install/WIKeyPage.java
+ com/netscape/admin/certsrv/config/install/WIPasteSSLCertPage.java
+ com/netscape/admin/certsrv/config/install/WIKRAScheme1Page.java
+ com/netscape/admin/certsrv/config/install/WIDBEnrollPage.java
+ com/netscape/admin/certsrv/config/install/WIKRACertDNPage.java
+ com/netscape/admin/certsrv/config/install/WICertDNPage.java
+ com/netscape/admin/certsrv/config/install/WIManualKRACertRequestPage.java
+ com/netscape/admin/certsrv/config/install/WIConfigWebServerPage.java
+ com/netscape/admin/certsrv/config/install/WIGenKeyCertReqPage.java
+ com/netscape/admin/certsrv/config/install/WIKRAStorageKeyPage.java
+ com/netscape/admin/certsrv/config/install/WIClonePage.java
+ com/netscape/admin/certsrv/config/install/WILogonAllTokensPage.java
+ com/netscape/admin/certsrv/config/install/WICloneCAKeyCertPage.java
+ com/netscape/admin/certsrv/config/install/WIMigrationPage.java
+ com/netscape/admin/certsrv/config/install/WICACertPage.java
+ com/netscape/admin/certsrv/config/install/WIRACertSubmitPage.java
+ com/netscape/admin/certsrv/config/install/WICertExtensionPage.java
+ com/netscape/admin/certsrv/config/install/WIInternalTokenLogonPage.java
+ com/netscape/admin/certsrv/config/install/WIRACertDNPage.java
+ com/netscape/admin/certsrv/config/install/WIServerCertExtensionPage.java
+ com/netscape/admin/certsrv/config/install/WIInstallCert2Page.java
+ com/netscape/admin/certsrv/config/install/WIGenRAKeyCertReqPage.java
+ com/netscape/admin/certsrv/config/install/WIKRAMessageDigestPage.java
+ com/netscape/admin/certsrv/config/install/WILoggingPage.java
+ com/netscape/admin/certsrv/config/install/WIKRATokenLogonPage.java
+ com/netscape/admin/certsrv/config/install/WIRARequestResultPage.java
+ com/netscape/admin/certsrv/config/install/WIOCSPRequestResultPage.java
+ com/netscape/admin/certsrv/config/install/WIDisplayRACertPage.java
+ com/netscape/admin/certsrv/config/install/WICACertSubmitPage.java
+ com/netscape/admin/certsrv/config/install/WIInstallCAIntroPage.java
+ com/netscape/admin/certsrv/config/install/WICloneMasterPage.java
+ com/netscape/admin/certsrv/config/install/WICertSubmitPage.java
+ com/netscape/admin/certsrv/config/install/WIRATokenLogonPage.java
+ com/netscape/admin/certsrv/config/install/WICloneRAKeyCertPage.java
+ com/netscape/admin/certsrv/config/install/WIGenKRAKeyCertPage.java
+ com/netscape/admin/certsrv/config/install/WICAKeyPage.java
+ com/netscape/admin/certsrv/config/install/WIInstallIntroPage.java
+ com/netscape/admin/certsrv/config/install/WIDisplayOCSPCertPage.java
+ com/netscape/admin/certsrv/config/install/WIIntroSingleSignonPage.java
+ com/netscape/admin/certsrv/config/install/WIInstallRACertStatusPage.java
+ com/netscape/admin/certsrv/config/install/WINetworkPage.java
+ com/netscape/admin/certsrv/config/install/WIOCSPKeyPage.java
+ com/netscape/admin/certsrv/config/install/WIManualSSLCertRequestPage.java
+ com/netscape/admin/certsrv/config/install/WIGenCAKeyCertReqPage.java
+ com/netscape/admin/certsrv/config/install/WIDisplayCACertPage.java
+ com/netscape/admin/certsrv/config/install/WICAMessageDigestPage.java
+ com/netscape/admin/certsrv/config/install/WIServerCertValidityPage.java
+ com/netscape/admin/certsrv/config/install/WIKRACertValidityPage.java
+ com/netscape/admin/certsrv/config/install/WIInstallSSLIntroPage.java
+ com/netscape/admin/certsrv/config/install/WIServerKeyPage.java
+ com/netscape/admin/certsrv/config/install/WISSLRequestResultPage.java
+ com/netscape/admin/certsrv/config/install/WIServerCertDNPage.java
+ com/netscape/admin/certsrv/config/install/WIOCSPMessageDigestPage.java
+ com/netscape/admin/certsrv/config/install/WIOCSPTokenLogonPage.java
+ com/netscape/admin/certsrv/config/install/WIPasteRACertPage.java
+ com/netscape/admin/certsrv/config/install/WISSLTokenLogonPage.java
+ com/netscape/admin/certsrv/config/install/ComponentCellRenderer.java
+ com/netscape/admin/certsrv/config/install/WIInstallCertStatusPage.java
+ com/netscape/admin/certsrv/config/install/WIInstallCert1Page.java
+ com/netscape/admin/certsrv/config/install/WIGenKeyCertPage.java
+ com/netscape/admin/certsrv/config/install/WIInstallRAIntroPage.java
+ com/netscape/admin/certsrv/config/install/WIOCSPCertSubmitPage.java
+ com/netscape/admin/certsrv/config/install/WIInternalDBInfoPage.java
+ com/netscape/admin/certsrv/config/install/WICloneKRAKeyCertPage.java
+ com/netscape/admin/certsrv/config/install/WISSLMessageDigestPage.java
+ com/netscape/admin/certsrv/config/install/WIManualOCSPCertRequestPage.java
+ com/netscape/admin/certsrv/config/install/WICATokenLogonPage.java
+ com/netscape/admin/certsrv/config/install/WICACert2Page.java
+ com/netscape/admin/certsrv/config/install/WIInstallKRAIntroPage.java
+ com/netscape/admin/certsrv/config/install/WIManualRACertRequestPage.java
+ com/netscape/admin/certsrv/config/install/WITokenLogonPage.java
+ com/netscape/admin/certsrv/config/install/WIRACertValidityPage.java
+ com/netscape/admin/certsrv/config/install/WICARequestResultPage.java
+ com/netscape/admin/certsrv/config/install/WIIntroMigrationPage.java
+ com/netscape/admin/certsrv/config/install/WIRAKeyPage.java
+ com/netscape/admin/certsrv/config/install/WIGenServerKeyCertPage.java
+ com/netscape/admin/certsrv/config/install/WIKRAScheme2Page.java
+ com/netscape/admin/certsrv/config/install/WICAOCSPServicePage.java
+ com/netscape/admin/certsrv/config/install/WILDAPPublishingPage.java
+ com/netscape/admin/certsrv/config/install/WICACertDNPage.java
+ com/netscape/admin/certsrv/config/install/WIRemoteCASubsystem.java
+ com/netscape/admin/certsrv/config/install/WIRecreateDBPage.java
+ com/netscape/admin/certsrv/config/install/WIServerCertSubmitPage.java
+ com/netscape/admin/certsrv/config/install/WIAllCertsInstalledPage.java
+ com/netscape/admin/certsrv/config/install/InstallWizardInfo.java
+ com/netscape/admin/certsrv/config/install/WIManualCertRequestPage.java
+ com/netscape/admin/certsrv/config/install/WIManualCACertRequestPage.java
+ com/netscape/admin/certsrv/config/install/WIIntroPage.java
+ com/netscape/admin/certsrv/config/install/WIAdminPage.java
+ com/netscape/admin/certsrv/config/install/WIPasteKRACertPage.java
+ com/netscape/admin/certsrv/config/install/WICACertExtensionPage.java
+ com/netscape/admin/certsrv/config/install/WIGenOCSPKeyCertReqPage.java
+ com/netscape/admin/certsrv/config/install/WIInstallOCSPIntroPage.java
+ com/netscape/admin/certsrv/config/install/WICertSetupStatusPage.java
+ com/netscape/admin/certsrv/config/install/WIPasteCACertPage.java
+ com/netscape/admin/certsrv/config/install/WIKRACertExtensionPage.java
+ com/netscape/admin/certsrv/config/install/WIGenRAKeyCertPage.java
+ com/netscape/admin/certsrv/config/install/WISMTPPage.java
+ com/netscape/admin/certsrv/config/install/WIReplAgreementPage.java
+ com/netscape/admin/certsrv/config/install/WISingleSignonPage.java
+ com/netscape/admin/certsrv/config/install/WIOCSPCertDNPage.java
+ com/netscape/admin/certsrv/config/install/WIKRAKeyPage.java
+ com/netscape/admin/certsrv/config/install/WIInstallKRACertStatusPage.java
+ com/netscape/admin/certsrv/config/install/WICertValidityPage.java
+ com/netscape/admin/certsrv/config/install/WICreateInternalDBPage.java
+ com/netscape/admin/certsrv/config/install/WIRemoteKRASubsystem.java
+ com/netscape/admin/certsrv/config/install/WIDisplayCertPage.java
+ com/netscape/admin/certsrv/config/install/WIInstallOCSPCertStatusPage.java
+ com/netscape/admin/certsrv/config/install/WIInternalDBPage.java
+ com/netscape/admin/certsrv/config/install/WICACert1Page.java
+ com/netscape/admin/certsrv/config/install/WIDisplaySSLCertPage.java
+ com/netscape/admin/certsrv/config/install/WIInstallSSLCertStatusPage.java
+ com/netscape/admin/certsrv/config/install/WIExistingDBPage.java
+ com/netscape/admin/certsrv/config/install/InstallWizard.java
+ com/netscape/admin/certsrv/config/install/WIGenKRAKeyCertReqPage.java
+ com/netscape/admin/certsrv/config/install/WIMasterOrClone.java
+ com/netscape/admin/certsrv/config/install/WIServicesPage.java
+ com/netscape/admin/certsrv/config/install/WIKRACertSubmitPage.java
+ com/netscape/admin/certsrv/config/install/WICertRequestPage.java
+ com/netscape/admin/certsrv/config/install/WICloneOCSPKeyCertPage.java
+ com/netscape/admin/certsrv/config/install/WICASerialNumberPage.java
+ com/netscape/admin/certsrv/config/install/WIGenSSLKeyCertReqPage.java
+ com/netscape/admin/certsrv/config/install/WIPasteCertPage.java
+ com/netscape/admin/certsrv/config/install/WIDisplayKRACertPage.java
+ com/netscape/admin/certsrv/config/install/WICACert1CustomPage.java
+ com/netscape/admin/certsrv/config/ProfileDataTable.java
+ com/netscape/admin/certsrv/config/CMSSSL2CipherSet.java
+ com/netscape/admin/certsrv/config/CMSCACertSettingPanel.java
+ com/netscape/admin/certsrv/config/PublisherConfigDialog.java
+ com/netscape/admin/certsrv/config/CMSAuditLogPanel.java
+ com/netscape/admin/certsrv/config/ACLImplDataModel.java
+ com/netscape/admin/certsrv/config/CMSCertSettingPanel.java
+ com/netscape/admin/certsrv/config/CMSKRAAutoPanel.java
+ com/netscape/admin/certsrv/config/CMSCAGeneralPanel.java
+ com/netscape/admin/certsrv/config/CMSEncryptionPanel.java
+ com/netscape/admin/certsrv/config/CMSOCSPGeneralPanel.java
+ com/netscape/admin/certsrv/config/PublisherRegisterDialog.java
+ com/netscape/admin/certsrv/config/ProfileNonPolicySelDialog.java
+ com/netscape/admin/certsrv/config/LogImplDataModel.java
+ com/netscape/admin/certsrv/config/LogImplTab.java
+ com/netscape/admin/certsrv/config/ProfilePolicyEditDialog.java
+ com/netscape/admin/certsrv/config/CRLExtensionsRuleDataModel.java
+ com/netscape/admin/certsrv/config/CMSCALDAPPanel.java
+ com/netscape/admin/certsrv/config/CMSBlankPanel.java
+ com/netscape/admin/certsrv/config/CMSTabPanel.java
+ com/netscape/admin/certsrv/config/CACertsTab.java
+ com/netscape/admin/certsrv/config/CMSRAGeneralPanel.java
+ com/netscape/admin/certsrv/config/ViewSelfTestsDialog.java
+ com/netscape/admin/certsrv/config/CMSBaseLogPanel.java
+ com/netscape/admin/certsrv/config/CMSPluginInstanceTab.java
+ com/netscape/admin/certsrv/config/MapperConfigDialog.java
+ com/netscape/admin/certsrv/config/TKSKeysTab.java
+ com/netscape/admin/certsrv/config/ConfigTableModel.java
+ com/netscape/admin/certsrv/config/OCSPStoresInstanceTab.java
+ com/netscape/admin/certsrv/config/ProfileEditDialog.java
+ com/netscape/admin/certsrv/config/EvaluatorRegisterDialog.java
+ com/netscape/admin/certsrv/config/ACLPanel.java
+ com/netscape/admin/certsrv/config/LogRegisterDialog.java
+ com/netscape/admin/certsrv/config/OCSPStoresRuleDataModel.java
+ com/netscape/admin/certsrv/config/PanelMapperConfigDialog.java
+ com/netscape/admin/certsrv/config/LogConfigDialog.java
+ com/netscape/admin/certsrv/config/CMSKRAPasswdPanel.java
+ com/netscape/admin/certsrv/config/CMSRALDAPPanel.java
+ com/netscape/admin/certsrv/config/CMSRuleDataModel.java
+ com/netscape/admin/certsrv/config/ProfileConfigDataModel.java
+ com/netscape/admin/certsrv/config/MapperInstanceTab.java
+ com/netscape/admin/certsrv/config/JobsConfigDialog.java
+ com/netscape/admin/certsrv/config/MNSchemeWizard.java
+ com/netscape/admin/certsrv/config/RuleConfigDialog.java
+ com/netscape/admin/certsrv/config/ProfilePluginSelectionDialog.java
+ com/netscape/admin/certsrv/config/JobsInstanceTab.java
+ com/netscape/admin/certsrv/config/JobsRegisterDialog.java
+ com/netscape/admin/certsrv/config/JobsImplTab.java
+ com/netscape/admin/certsrv/config/WBaseCertExtensionPage.java
+ com/netscape/admin/certsrv/config/CMSBaseTab.java
+ com/netscape/admin/certsrv/config/ACLImplTab.java
+ com/netscape/admin/certsrv/config/KeyCreateDialog.java
+ com/netscape/admin/certsrv/config/CMSNetworkPanel.java
+ com/netscape/admin/certsrv/config/ProfileConfigDialog.java
+ com/netscape/admin/certsrv/config/MapperRuleDataModel.java
+ com/netscape/admin/certsrv/config/WBaseValidityPage.java
+ com/netscape/admin/certsrv/config/CMSSSL3CipherSet.java
+ com/netscape/admin/certsrv/config/CMSEAGeneralPanel.java
+ com/netscape/admin/certsrv/config/WBaseDNPage.java
+ com/netscape/admin/certsrv/config/CMStoAdminEncryptionPane.java
+ com/netscape/admin/certsrv/config/ListKeysModel.java
+ com/netscape/admin/certsrv/config/CMSSSL2CipherPreference.java
+ com/netscape/admin/certsrv/config/ACLEditDialog.java
+ com/netscape/admin/certsrv/config/CRLExtensionsConfigDialog.java
+ com/netscape/admin/certsrv/config/ProfilePolicySelectionDialog.java
+ com/netscape/admin/certsrv/config/WMessageDigestPage.java
+ com/netscape/admin/certsrv/config/CMSUserCertSettingPanel.java
+ com/netscape/admin/certsrv/config/MNSchemeWizardInfo.java
+ com/netscape/admin/certsrv/config/PublisherImplDataModel.java
+ com/netscape/admin/certsrv/config/CMSSMTPPanel.java
+ com/netscape/admin/certsrv/config/JobsPluginSelectionDialog.java
+ com/netscape/admin/certsrv/config/LogRuleDataModel.java
+ com/netscape/admin/certsrv/config/CMSCRLCachePanel.java
+ com/netscape/admin/certsrv/config/ProfileNonPolicyNewDialog.java
+ com/netscape/admin/certsrv/config/RuleRuleDataModel.java
+ com/netscape/admin/certsrv/config/ProfileRuleDataModel.java
+ com/netscape/admin/certsrv/config/WMNNewAgent.java
+ com/netscape/admin/certsrv/config/CMSRAConnectorPanel.java
+ com/netscape/admin/certsrv/config/PolicyRegisterDialog.java
+ com/netscape/admin/certsrv/config/PolicyImplDataModel.java
+ com/netscape/admin/certsrv/config/ProfileListDataModel.java
+ com/netscape/admin/certsrv/IDataProcessor.java
+ com/netscape/admin/certsrv/MultilineLabelUI.java
+ com/netscape/admin/certsrv/LabelCellRenderer.java
+ com/netscape/admin/certsrv/GenericCellRenderer.java
+ com/netscape/admin/certsrv/task/AuthDialog.java
+ com/netscape/admin/certsrv/task/CreateInstanceDialog.java
+ com/netscape/admin/certsrv/task/CMSStart.java
+ com/netscape/admin/certsrv/task/StatusDialog.java
+ com/netscape/admin/certsrv/task/CGITask.java
+ com/netscape/admin/certsrv/task/CMSConfigCert.java
+ com/netscape/admin/certsrv/task/CMSMigrateCreate.java
+ com/netscape/admin/certsrv/task/KeyCert.java
+ com/netscape/admin/certsrv/task/CMSStartDaemon.java
+ com/netscape/admin/certsrv/task/CMSRestart.java
+ com/netscape/admin/certsrv/task/CMSStop.java
+ com/netscape/admin/certsrv/task/CMSStatus.java
+ com/netscape/admin/certsrv/task/CMSRemove.java
+ com/netscape/admin/certsrv/task/CMSImportCert.java
+ com/netscape/admin/certsrv/task/CMSRequestCert.java
+ com/netscape/admin/certsrv/task/CMSCertRequest.java
+ com/netscape/admin/certsrv/IMenuAction.java
+ com/netscape/admin/certsrv/CMSEAUILoader.java
+ com/netscape/admin/certsrv/wizard/WizardWidget.java
+ com/netscape/admin/certsrv/wizard/IWizardDone.java
+ com/netscape/admin/certsrv/wizard/WizardInfo.java
+ com/netscape/admin/certsrv/wizard/ConfigServlet.java
+ com/netscape/admin/certsrv/wizard/IWizardPanel.java
+ com/netscape/admin/certsrv/wizard/WizardBasePanel.java
+ com/netscape/admin/certsrv/CellEditorData.java
+ com/netscape/admin/certsrv/CMSContentTableModel.java
+ com/netscape/admin/certsrv/keycert/WCAKeyPage.java
+ com/netscape/admin/certsrv/keycert/WSSLKeyPage.java
+ com/netscape/admin/certsrv/keycert/WKeyPage.java
+ com/netscape/admin/certsrv/keycert/WWarningExecute1Page.java
+ com/netscape/admin/certsrv/keycert/WTokenLogonPage.java
+ com/netscape/admin/certsrv/keycert/CertSetupWizard.java
+ com/netscape/admin/certsrv/keycert/WCertMessageDigestPage.java
+ com/netscape/admin/certsrv/keycert/WCertRequestPage.java
+ com/netscape/admin/certsrv/keycert/WWarningExecutePage.java
+ com/netscape/admin/certsrv/keycert/WPasteCertPage.java
+ com/netscape/admin/certsrv/keycert/WCertValidityPage.java
+ com/netscape/admin/certsrv/keycert/WCertExtensionPage.java
+ com/netscape/admin/certsrv/keycert/WInstallOpPage.java
+ com/netscape/admin/certsrv/keycert/WDisplayCertPage.java
+ com/netscape/admin/certsrv/keycert/WWarningPage.java
+ com/netscape/admin/certsrv/keycert/WRequestStatusPage.java
+ com/netscape/admin/certsrv/keycert/WCertTypePage.java
+ com/netscape/admin/certsrv/keycert/WIntroInstallCertPage.java
+ com/netscape/admin/certsrv/keycert/CertSetupWizardInfo.java
+ com/netscape/admin/certsrv/keycert/WInstallStatusPage.java
+ com/netscape/admin/certsrv/keycert/WExecutePage.java
+ com/netscape/admin/certsrv/keycert/WOperationSelectionPage.java
+ com/netscape/admin/certsrv/keycert/WTokenSelectionPage.java
+ com/netscape/admin/certsrv/keycert/WGenerateReqPage.java
+ com/netscape/admin/certsrv/keycert/WManualCertRequestPage.java
+ com/netscape/admin/certsrv/keycert/WInstallCertChainPage.java
+ com/netscape/admin/certsrv/keycert/WOtherCertRequest1Page.java
+ com/netscape/admin/certsrv/keycert/WExecute1Page.java
+ com/netscape/admin/certsrv/keycert/WIntroPage.java
+ com/netscape/admin/certsrv/keycert/WCertDNValidityPage.java
+ com/netscape/admin/certsrv/keycert/WCertDNPage.java
+ com/netscape/admin/certsrv/keycert/WIssueImportStatusPage.java
+ com/netscape/admin/certsrv/keycert/WCACertRequest1Page.java
+ com/netscape/admin/certsrv/keycert/WRAKeyPage.java
+ com/netscape/admin/certsrv/IRefreshTabPanel.java
+ com/netscape/admin/certsrv/status/LogDataModel.java
+ com/netscape/admin/certsrv/status/AccessLogDataModel.java
+ com/netscape/admin/certsrv/status/LogInstancePanel.java
+ com/netscape/admin/certsrv/status/DefaultLogParser.java
+ com/netscape/admin/certsrv/status/ErrorLogDataModel.java
+ com/netscape/admin/certsrv/status/CMSLogPanel.java
+ com/netscape/admin/certsrv/status/StatusPanel.java
+ com/netscape/admin/certsrv/status/LogEntryViewDialog.java
+ com/netscape/admin/certsrv/status/ILogParser.java
+ com/netscape/admin/certsrv/status/AuditLogDataModel.java
+ com/netscape/admin/certsrv/StatusItemContinuousProgress.java
+ com/netscape/admin/certsrv/CMSPassword.java
+ com/netscape/admin/certsrv/ug/AuthRuleDataModel.java
+ com/netscape/admin/certsrv/ug/AuthConfigDialog.java
+ com/netscape/admin/certsrv/ug/AuthPluginSelectionDialog.java
+ com/netscape/admin/certsrv/ug/UserDataModel.java
+ com/netscape/admin/certsrv/ug/GroupDataModel.java
+ com/netscape/admin/certsrv/ug/GroupListDialog.java
+ com/netscape/admin/certsrv/ug/UserListDataModel.java
+ com/netscape/admin/certsrv/ug/GroupListDataModel.java
+ com/netscape/admin/certsrv/ug/CMSBaseUGTab.java
+ com/netscape/admin/certsrv/ug/CMSUGTabPanel.java
+ com/netscape/admin/certsrv/ug/CertDataModel.java
+ com/netscape/admin/certsrv/ug/MemberDataModel.java
+ com/netscape/admin/certsrv/ug/UserEditor.java
+ com/netscape/admin/certsrv/ug/GroupTab.java
+ com/netscape/admin/certsrv/ug/AuthRegisterDialog.java
+ com/netscape/admin/certsrv/ug/CertImportDialog.java
+ com/netscape/admin/certsrv/ug/AuthInstanceTab.java
+ com/netscape/admin/certsrv/ug/CertViewDialog.java
+ com/netscape/admin/certsrv/ug/CertManagementDialog.java
+ com/netscape/admin/certsrv/ug/AuthImplDataModel.java
+ com/netscape/admin/certsrv/ug/UserTab.java
+ com/netscape/admin/certsrv/ug/AuthViewDialog.java
+ com/netscape/admin/certsrv/ug/AuthImplTab.java
+ com/netscape/admin/certsrv/ug/GroupEditor.java
+ com/netscape/admin/certsrv/ug/UserListDialog.java
+ com/netscape/admin/certsrv/ug/AuthBaseDialog.java
+ com/netscape/admin/certsrv/IConnectionListener.java
+ com/netscape/admin/certsrv/UIMapperRegistry.java
+ com/netscape/admin/certsrv/HourGlass.java
+ com/netscape/admin/certsrv/CMSBaseResourceModel.java
+ com/netscape/admin/certsrv/menu/CertManagementAction.java
+ com/netscape/admin/certsrv/menu/PKCS11ManagementAction.java
+ com/netscape/admin/certsrv/menu/RefreshTabPane.java
+ com/netscape/admin/certsrv/menu/KeyCertAction.java
+ com/netscape/admin/certsrv/IRefreshTab.java
+ com/netscape/admin/certsrv/CMSKernelUILoader.java
+ com/netscape/admin/certsrv/CMSMessageBox.java
+ com/netscape/admin/certsrv/DefaultTableCellEditor.java
+ com/netscape/admin/certsrv/security/GuideCreateTrustPane.java
+ com/netscape/admin/certsrv/security/SSL2CipherSet.java
+ com/netscape/admin/certsrv/security/Comm.java
+ com/netscape/admin/certsrv/security/CertBasicInfo.java
+ com/netscape/admin/certsrv/security/CRLAddCertDialog.java
+ com/netscape/admin/certsrv/security/AbstractCipherPreference.java
+ com/netscape/admin/certsrv/security/WizardObservable.java
+ com/netscape/admin/certsrv/security/CertDetailInfoDialog.java
+ com/netscape/admin/certsrv/security/IAbstractCipherSet.java
+ com/netscape/admin/certsrv/security/StatusPane.java
+ com/netscape/admin/certsrv/security/Response.java
+ com/netscape/admin/certsrv/security/ICipherConstants.java
+ com/netscape/admin/certsrv/security/MessageDialog.java
+ com/netscape/admin/certsrv/security/SSL2CipherPreference.java
+ com/netscape/admin/certsrv/security/KeyCertTaskInfo.java
+ com/netscape/admin/certsrv/security/AbstractCipher.java
+ com/netscape/admin/certsrv/security/CertInstallTypePane.java
+ com/netscape/admin/certsrv/security/CertInstallCertPane.java
+ com/netscape/admin/certsrv/security/ChangeKeyPasswordDialog.java
+ com/netscape/admin/certsrv/security/CertRequestEnterPasswordPane.java
+ com/netscape/admin/certsrv/security/CertListTableModel.java
+ com/netscape/admin/certsrv/security/KeyCertUtility.java
+ com/netscape/admin/certsrv/security/CreateTrustPane.java
+ com/netscape/admin/certsrv/security/CipherPreferenceDialog.java
+ com/netscape/admin/certsrv/security/CRLTableModel.java
+ com/netscape/admin/certsrv/security/CRLTable.java
+ com/netscape/admin/certsrv/security/EncryptionPane.java
+ com/netscape/admin/certsrv/security/PKCS11ManagementDialog.java
+ com/netscape/admin/certsrv/security/CertInfo.java
+ com/netscape/admin/certsrv/security/CRLCertInfoPane.java
+ com/netscape/admin/certsrv/security/CertRequestSelectTokenPane.java
+ com/netscape/admin/certsrv/security/GuideCertRequestPane.java
+ com/netscape/admin/certsrv/security/IKeyCertPage.java
+ com/netscape/admin/certsrv/security/SSL3CipherSet.java
+ com/netscape/admin/certsrv/security/Message.java
+ com/netscape/admin/certsrv/security/CertInstallCertInfoPane.java
+ com/netscape/admin/certsrv/security/CertListTable.java
+ com/netscape/admin/certsrv/security/CRLManagementDialog.java
+ com/netscape/admin/certsrv/security/GuideIntroPane.java
+ com/netscape/admin/certsrv/security/CertRequestTypePane.java
+ com/netscape/admin/certsrv/security/ToggleCipherPreferencePane.java
+ com/netscape/admin/certsrv/security/CertInfoDialog.java
+ com/netscape/admin/certsrv/security/CipherResourceSet.java
+ com/netscape/admin/certsrv/security/CertManagementDialog.java
+ com/netscape/admin/certsrv/security/KeyCertWizard.java
+ com/netscape/admin/certsrv/security/GuideCertInstallPane.java
+ com/netscape/admin/certsrv/security/CertRequestInfoPane.java
+ com/netscape/admin/certsrv/security/PKCS11AddModuleDialog.java
+ com/netscape/admin/certsrv/security/SSL3CipherPreference.java
+ com/netscape/admin/certsrv/security/CRLDeleteCertDialog.java
+ com/netscape/admin/certsrv/security/IEncryptionPaneListener.java
+ com/netscape/admin/certsrv/security/CipherEntry.java
+ com/netscape/admin/certsrv/security/CertRequestCertPane.java
+ com/netscape/admin/certsrv/CMSServerInfo.java
+ com/netscape/admin/certsrv/notification/RequestInQPanel.java
+ com/netscape/admin/certsrv/notification/RequestCompletePanel.java
+ com/netscape/admin/certsrv/notification/RequestRevokedPanel.java
+ com/netscape/admin/certsrv/IUIMapper.java
+ com/netscape/admin/certsrv/images/alertl.gif
+ com/netscape/admin/certsrv/images/rulesobj.gif
+ com/netscape/admin/certsrv/images/secure.gif
+ com/netscape/admin/certsrv/images/red-ball-small.gif
+ com/netscape/admin/certsrv/images/error.gif
+ com/netscape/admin/certsrv/images/UGobjs.gif
+ com/netscape/admin/certsrv/images/allfolder16n.gif
+ com/netscape/admin/certsrv/images/aclobj.gif
+ com/netscape/admin/certsrv/images/alllogfolder16n.gif
+ com/netscape/admin/certsrv/images/alluser16n.gif
+ com/netscape/admin/certsrv/images/authobj.gif
+ com/netscape/admin/certsrv/images/plugin.gif
+ com/netscape/admin/certsrv/images/LOGobjs.gif
+ com/netscape/admin/certsrv/images/acl.gif
+ com/netscape/admin/certsrv/images/messagel.gif
+ com/netscape/admin/certsrv/images/genobject.gif
+ com/netscape/admin/certsrv/images/auth.gif
+ com/netscape/admin/certsrv/images/cms-branding.gif
+ com/netscape/admin/certsrv/images/plug.gif
+ com/netscape/admin/certsrv/images/servlet-16.gif
+ com/netscape/admin/certsrv/images/CertificateServer.gif
+ com/netscape/admin/certsrv/images/ruleplugin-16.gif
+ com/netscape/admin/certsrv/images/aclplugin.gif
+ com/netscape/admin/certsrv/images/ruleDisable-16.gif
+ com/netscape/admin/certsrv/images/servletobj.gif
+ com/netscape/admin/certsrv/images/authplugin.gif
+ com/netscape/admin/certsrv/images/CertificateServerL.gif
+ com/netscape/admin/certsrv/images/alllogdoc16n.gif
+ com/netscape/admin/certsrv/images/jobplugin.gif
+ com/netscape/admin/certsrv/images/pluginfolder.gif
+ com/netscape/admin/certsrv/images/rule-16.gif
+ com/netscape/admin/certsrv/images/jobs.gif
+ com/netscape/admin/certsrv/images/cert41.gif
+ com/netscape/admin/certsrv/images/cert42.gif
+ com/netscape/admin/certsrv/images/cert24.gif
+ com/netscape/admin/certsrv/images/servlet-plugin-16.gif
+ com/netscape/admin/certsrv/images/jobobj.gif
+ com/netscape/admin/certsrv/images/alluserwithcert16n.gif
+ com/netscape/admin/certsrv/images/notsecure.gif
+ com/netscape/admin/certsrv/images/ldapub.gif
+ com/netscape/admin/certsrv/images/allgroup16n.gif
+)
+
+# set classpath
+set(CMAKE_JAVA_INCLUDE_PATH
+ ${BASE_JAR} ${LDAPJDK_JAR} ${MMC_JAR}
+ ${MMC_EN_JAR} ${NMCLF_JAR} ${NMCLF_EN_JAR}
+ ${PKI_NSUTIL_JAR}
+ ${JSS_JAR}
+ ${COMMONS_CODEC_JAR})
+
+
+# set version
+set(CMAKE_JAVA_TARGET_VERSION ${APPLICATION_VERSION})
+
+
+# build pki-console.jar
+add_jar(pki-console ${pki-console_java_SRCS})
+add_dependencies(pki-console pki-nsutil)
+install_jar(pki-console ${JAVA_JAR_INSTALL_DIR}/pki)
+set(PKI_CONSOLE_JAR ${pki-console_JAR_FILE} CACHE INTERNAL "pki-console jar file")
+
diff --git a/base/console/src/com/netscape/admin/certsrv/AttrCellRenderer.java b/base/console/src/com/netscape/admin/certsrv/AttrCellRenderer.java
new file mode 100644
index 000000000..863e42197
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/AttrCellRenderer.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.admin.certsrv;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.border.*;
+
+/**
+ * class used to crate the label to be displayed in the attr list
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class AttrCellRenderer extends JLabel implements ListCellRenderer {
+ static Color HIGHLIGHTCOLOR = new Color(0, 0, 128);
+ static Color WHITECOLOR = Color.white;
+ static Color BLACKCOLOR = Color.black;
+
+ public AttrCellRenderer() {
+ setOpaque(true);
+ setBorder(new EmptyBorder(1,CMSAdminUtil.COMPONENT_SPACE, 1, 2));
+ JTextField temp = new JTextField();
+ setFont(temp.getFont());
+ }
+
+ public Component getListCellRendererComponent(JList list,
+ Object value, int index, boolean isSelected, boolean cellHasFocus) {
+
+ if (value instanceof JLabel) {
+ setText(((JLabel)value).getText());
+ setIcon(((JLabel)value).getIcon());
+ setHorizontalAlignment(((JLabel)value).getHorizontalAlignment());
+ } else {
+ if (value instanceof String) {
+ setText((String) value);
+ } else {
+ setText(value.toString());
+ }
+ }
+ setBackground(isSelected ? HIGHLIGHTCOLOR : WHITECOLOR);
+ setForeground(isSelected ? WHITECOLOR : BLACKCOLOR);
+ return this;
+ }
+} \ No newline at end of file
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSAdmin.java b/base/console/src/com/netscape/admin/certsrv/CMSAdmin.java
new file mode 100644
index 000000000..6e88cc276
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSAdmin.java
@@ -0,0 +1,969 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv;
+
+import java.util.*;
+import java.net.*;
+import java.awt.*;
+import javax.swing.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.topology.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.config.install.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.admin.certsrv.wizard.*;
+import netscape.ldap.*;
+
+/**
+ * Netscape Certificate Server 4.0 configuration entry point. The
+ * directory server needs to contain the name of this class in order
+ * for the topology view to load this class.
+ *
+ * @author Jack Pan-Chen
+ * @author Thomas Kwan
+ * @version $Revision$, $Date$
+ * @date 01/12/97
+ */
+public class CMSAdmin extends AbstractServerObject
+ implements IWizardDone, IRemovableServerObject, IMenuInfo
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "CMSADMIN";
+ private static final String START = "start";
+ private static final String STOP = "stop";
+ private static final String CONFIGURE = "configure";
+// private static final String START_DAEMON_CGI = "Tasks/Operation/StartDaemon";
+
+ private ConsoleInfo mConsoleInfo; // global information
+ private CMSServerInfo mServerInfo; // server-specific information
+ private ConsoleInfo mServerInstanceInfo;
+ private CMSServerInfo mStatusInfo; // server-specific information
+ private CMSUIFramework mFramework; // parent frame
+ private CMSPageFeeder mPagefeeder; // what generates tab views
+ //private CMSInfoPanel mInfoPanel; // information panel
+ private RemoteImage mIconImage = null; // server icon
+ private String mServerID, mServerVersion, mInstallationDate, mServerRoot;
+ private String mHost = null; // server name
+ private int mPort = 0; // server port
+ private String mAdminURL = null; // admin server url
+ private int mServerStatus = STATUS_UNKNOWN;
+ private StatusItemText mAuthid;
+ private JFrame mActiveFrame;
+
+ protected ResourceBundle mResource; //resource boundle
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSAdmin()
+ {
+ //Debug.setTrace(true);
+ if (mActiveFrame == null)
+ mActiveFrame = UtilConsoleGlobals.getActivatedFrame();
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ // STATUS_UPDATE_INTERVAL = 1500000;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ public int getServerLastKnownStatus() {
+ return mServerStatus;
+ }
+
+ /**
+ * Initialize the page with global information.
+ *
+ * @param info global information.
+ */
+ public void initialize(ConsoleInfo info) {
+ mConsoleInfo = info;
+ mIconImage = CMSAdminUtil.getImage(CMSAdminResources.IMAGE_CERTICON_SMALL);
+ getInfo( info.getCurrentDN());
+ //getServerStatus();
+ if (info.getCurrentDN() == null) {
+ Debug.println( "initialized CMSAdmin (Standalone mode)");
+ } else {
+ super.initialize( info );
+ }
+ Debug.println( "initialized CMSAdmin for " + mConsoleInfo.getCurrentDN() );
+ }
+
+
+ /**
+ * overwrite the base class to add admin port number
+ * Not sure we want to do this.
+ *
+ protected Vector initializeNodeDataVector(String dataKeys[]) {
+ Vector v = super.initializeNodeDataVector(dataKeys);
+ if ( mServerInfo != null ) {
+ int port = mServerInfo.getPort();
+ if ( port > 0 ) {
+ String label = mResource.getString(PREFIX+"_ADMINPORT_LABEL");
+ v.addElement(new NodeData("nsServerPort",
+ label,
+ Integer.toString(port)));
+ }
+ }
+ return v;
+ }
+ */
+
+ /**
+ * return the server instance name instead for now
+ *
+ * @return return the server name
+ *
+ */
+ public String getName() {
+ return ("Certificate Server ("+ mServerID +")");
+ }
+
+
+ /**
+ * Return the information panel. - Admin take over this already
+ *
+ * @return information panel
+ *
+ public Component getCustomPanel() {
+ if(mInfoPanel == null)
+ mInfoPanel = new CMSInfoPanel( (IServerObject)this,
+ mHost,
+ mPort,
+ mServerVersion,
+ mInstallationDate,
+ mAdminURL);
+ return mInfoPanel;
+ }
+ */
+
+ /**
+ * Return connection info for a server instance.
+ * @return Connection info for a server instance.
+ */
+ public CMSServerInfo getServerInfo() {
+ return mServerInfo;
+ }
+
+ public ConsoleInfo getServerInstanceInfo() {
+ mServerInstanceInfo = (ConsoleInfo)mConsoleInfo.clone();
+ return mServerInstanceInfo;
+ }
+
+ /**
+ * Returns the global console info.
+ *
+ * @return Global console info reference.
+ **/
+ public ConsoleInfo getConsoleInfo() {
+ return mConsoleInfo;
+ }
+
+ /**
+ * This function is called when the certificate server is deselected
+ * on the topology view.
+ */
+ public void unselect(IPage viewInstance) {
+// Debug.println( "DSAdmin unselect" );
+ super.unselect(viewInstance);
+ fireRemoveMenuItems( viewInstance, this );
+ }
+
+ /**
+ * This function is called when the directory server is selected
+ * on the topology view.
+ */
+ public void select(IPage viewInstance) {
+/*
+ if (_removed)
+ return;
+*/
+
+ HourGlass hglass = new HourGlass(mActiveFrame);
+ super.select(viewInstance); // sets _viewInstance used
+ // by getViewInstance()
+ Debug.println( "CMSAdmin.select(): viewInstance =" +
+ getViewInstance() );
+ fireAddMenuItems( viewInstance, this );
+ if (mPort == 0) {
+ fireDisableMenuItem(viewInstance, START);
+ fireDisableMenuItem(viewInstance, STOP);
+ fireEnableMenuItem(viewInstance, CONFIGURE);
+ } else if ( getServerStatus() == STATUS_STARTED ) {
+ fireDisableMenuItem( viewInstance, START );
+ fireEnableMenuItem(viewInstance, STOP);
+ fireDisableMenuItem(viewInstance, CONFIGURE);
+ } else {
+ fireEnableMenuItem( viewInstance, START );
+ fireDisableMenuItem( viewInstance, STOP );
+ fireDisableMenuItem(viewInstance, CONFIGURE);
+ }
+ if (hglass != null) {
+ hglass.setNonWaitCursor();
+ hglass = null;
+ }
+ }
+
+ /**
+ * Returns supported menu categories
+ */
+ public String[] getMenuCategoryIDs() {
+ return new String[]
+ {
+ ResourcePage.MENU_CONTEXT,
+ ResourcePage.MENU_OBJECT
+ };
+ }
+
+ /**
+ * Add menu items for this page.
+ *
+ * @param category Which menu
+ */
+ public IMenuItem[] getMenuItems(String category) {
+ /* Same for both CONTEXT and OBJECT menus */
+ return new IMenuItem[] {
+ new MenuItemText( CONFIGURE,
+ CMSAdminResources.MENU_CONFIGURE_SERVER,
+ CMSAdminResources.MENU_CONFIGURE_SERVER_DESC),
+ new MenuItemText( START,
+ CMSAdminResources.MENU_START_SERVER,
+ CMSAdminResources.MENU_START_SERVER_DESC),
+
+ new MenuItemText( STOP,
+ CMSAdminResources.MENU_STOP_SERVER,
+ CMSAdminResources.MENU_STOP_SERVER_DESC),
+ new MenuItemSeparator() };
+ }
+
+ /**
+ * Notification that a menu item has been selected.
+ */
+ public void actionMenuSelected(IPage viewInstance, IMenuItem item) {
+ if (item.getID().equals(START)) {
+ ConsoleInfo info = getServerInstanceInfo();
+ /* Fire off the Start task */
+ CMSStart task = new CMSStart();
+ mConsoleInfo.put(CMSStart.START_TASK_CGI, mServerID);
+ mConsoleInfo.put("serverRoot",mServerRoot);
+ mConsoleInfo.put("servid", mServerID);
+ task.initialize(mConsoleInfo);
+ //task.setConsoleInfo( info );
+ boolean status = task.run( null );
+ if( status ) {
+ getServerStatus();
+ enableStartStop(viewInstance);
+ }
+ } else if(item.getID().equals(STOP)) {
+ CMSStop task = new CMSStop();
+ ConsoleInfo info = getServerInstanceInfo();
+ mConsoleInfo.put(CMSStop.STOP_TASK_CGI, mServerID);
+ mConsoleInfo.put("servid", mServerID);
+ mConsoleInfo.put("serverRoot",mServerRoot);
+ task.initialize(mConsoleInfo);
+ boolean status = task.run( null );
+ if ( status ) {
+ getServerStatus();
+ enableStartStop(viewInstance);
+ }
+ } else if (item.getID().equals(CONFIGURE)) {
+ startupInstallationWizard(viewInstance);
+ }
+ }
+
+ public void updateMenu(IPage viewInstance) {
+ getInfo(getConsoleInfo().getCurrentDN());
+ if (mPort != 0) {
+ fireDisableMenuItem(viewInstance, CONFIGURE);
+ getServerStatus();
+ enableStartStop(viewInstance);
+ }
+ }
+
+ /**
+ * Enable/Disable start/stop action menu.
+ */
+ private void enableStartStop(IPage viewInstance) {
+ if (mServerStatus == STATUS_STOPPED) {
+ fireEnableMenuItem( viewInstance, START );
+ fireDisableMenuItem( viewInstance, STOP );
+ } else if (mServerStatus == STATUS_STARTED) {
+ fireEnableMenuItem( viewInstance, STOP );
+ fireDisableMenuItem( viewInstance, START );
+ }
+ }
+
+ /**
+ * Set the title bar in the following format:<p><pre>
+ * [server information] - [server type] - [nickname]</pre>
+ * Administrator id is shown at lower status bar
+ */
+ public void updateTitle () {
+ /*
+ mAuthid.setState(mResource.getString("CMSADMIN_USER_LABEL")+
+ " = "+mServerInfo.getUserId()+" ");
+ mFramework.getFramework().changeStatusItemState(mAuthid);
+ */
+ String id = mServerID;
+ int i = id.indexOf( '-' );
+ if ( (i > 0) && (i < (id.length()-1)) )
+ id = id.substring( i + 1 );
+ mFramework.getFramework().setTitle( mServerInfo.getHost()+" - "
+ + mResource.getString(CMSAdminResources.CERT_SERVER_NAME)+
+ " - "+ id );
+ }
+
+ private Hashtable createWizardInfo() {
+ Hashtable data = new Hashtable();
+ /* This does nothing
+ data.put(ConfigConstants.TASKID,TaskId.TASK_LIST_PREVIOUS_STAGES);
+ data.put(ConfigConstants.OPTYPE, OpDef.OP_READ);
+ data.put(ConfigConstants.PR_CERT_INSTANCE_NAME, mServerID);
+ data.put(ConfigConstants.PR_SERVER_ROOT, mServerRoot);
+ */
+
+ // moved from WIIntroPage.java
+ data.put(ConfigConstants.TASKID,TaskId.TASK_GET_DEFAULT_INFO);
+ data.put(ConfigConstants.OPTYPE, OpDef.OP_READ);
+ data.put(ConfigConstants.PR_CERT_INSTANCE_NAME,
+ mConsoleInfo.get(ConfigConstants.PR_CERT_INSTANCE_NAME));
+ // #344791 - help server to make up the hostname
+ data.put(ConfigConstants.PR_HOST,
+ mConsoleInfo.get(ConfigConstants.PR_HOST));
+ data.put(ConfigConstants.PR_SERVER_ROOT,
+ mConsoleInfo.get(ConfigConstants.PR_SERVER_ROOT));
+ return data;
+ }
+
+ /**
+ * This is called when the installwizard is done.
+ */
+ public void notify(WizardWidget w) {
+ Debug.println("Configuration Completed");
+ for (int i = 0; i < 10; i++) { // try to detect 10 times
+ Debug.println("Check Status #" + i);
+ if ( getServerStatus() == STATUS_STARTED ) {
+ return;
+ }
+ try {
+ Thread.currentThread().sleep(2000); // 2 seconds
+ } catch (Exception e) {
+ }
+ }
+ }
+
+ /**
+ * Start up the installation wizard
+ */
+ public void startupInstallationWizard(IPage viewInstance) {
+ Hashtable data = new Hashtable();
+ CMSStartDaemon daemon = new CMSStartDaemon();
+ mConsoleInfo.put("servid", mServerID);
+ mConsoleInfo.put(CMSStartDaemon.START_DAEMON_CGI, mServerID);
+ mConsoleInfo.put(CMSConfigCert.CONFIG_CERT_CGI, mServerID);
+ daemon.initialize(mConsoleInfo);
+ data.put(ConfigConstants.PR_CERT_INSTANCE_NAME, mServerID);
+ Debug.println("about to run Daemon");
+ boolean success = daemon.runDaemon(data);
+ Debug.println("run daemon success = "+success);
+ data.clear();
+ data = null;
+ boolean isInfoReady = false;
+
+ if (success) {
+ InstallWizardInfo wizardInfo =
+ new InstallWizardInfo(mConsoleInfo);
+ wizardInfo.setAdminFrame(mActiveFrame);
+ Debug.println("CMSAdmin: creating new configCertCgi");
+ CMSConfigCert configCertCgi = new CMSConfigCert();
+ configCertCgi.initialize(wizardInfo);
+ Debug.println("CMSAdmin: back from creating new configCertCgi");
+ data = createWizardInfo();
+ isInfoReady = configCertCgi.configCert(data);
+ Debug.println("CMSAdmin: isInfoReady = "+isInfoReady);
+
+ if (isInfoReady) {
+ JFrame frame = new JFrame();
+ Cursor cursor = new Cursor(Cursor.HAND_CURSOR);
+ frame.setCursor(cursor);
+ frame.invalidate();
+ frame.validate();
+ frame.repaint(1);
+ // XXX - checking status is too slow, dont do it now.
+ // InstallWizard wizard = new InstallWizard(
+ // mConsoleInfo.getFrame(), wizardInfo, this);
+ InstallWizard wizard = new InstallWizard(mActiveFrame,
+ wizardInfo, null);
+ wizardInfo.setAdminFrame(mActiveFrame);
+ wizardInfo.put("viewInstance", viewInstance);
+ wizardInfo.put("CMSAdmin", this);
+ new Thread(wizard).start();
+ }
+ }
+ data.clear();
+ data = null;
+ mServerStatus = STATUS_UNKNOWN;
+ }
+
+ /**
+ * This function is called when the server is double clicked on
+ * the topology view. Auth dialog is displayed to get user dn and pwd.
+ */
+ public boolean run(IPage viewInstance) {
+
+ Debug.println("The user double click the icon "+getConsoleInfo().getCurrentDN());
+ Debug.println("View instance in the run method -> "+viewInstance);
+
+ if (getConsoleInfo().getCurrentDN() == null) {
+ mServerID = (String)mConsoleInfo.get("cmsServerInstance");
+ }
+
+ mConsoleInfo.put(CMSRestart.RESTART_TASK_CGI, mServerID);
+ mConsoleInfo.put(CMSStart.START_TASK_CGI, mServerID);
+ mConsoleInfo.put(CMSStop.STOP_TASK_CGI, mServerID);
+ mConsoleInfo.put("CMSAdmin", this);
+ if (mPort == 0) {
+ getInfo(getConsoleInfo().getCurrentDN());
+ if (mPort == 0) {
+ startupInstallationWizard(viewInstance);
+ return false;
+ }
+ }
+
+ if (getConsoleInfo().getCurrentDN() == null) {
+ mHost = (String)mConsoleInfo.get("cmsHost");
+ mPort = Integer.parseInt((String)mConsoleInfo.get("cmsPort"));
+ } else {
+ try {
+ LDAPConnection ldc = mConsoleInfo.getLDAPConnection();
+ if ( ldc == null ) {
+ Debug.println( "No connection ready in ConsoelInfo" );
+ ldc = new LDAPConnection();
+ ldc.connect( mConsoleInfo.getHost(), mConsoleInfo.getPort(),
+ mConsoleInfo.getAuthenticationDN(),
+ mConsoleInfo.getAuthenticationPassword());
+ }
+ //Debug.println( "Fetching " + sBase + " from " +
+ // mConsoleInfo.getHost() + ":" + mConsoleInfo.getPort() );
+ LDAPEntry entry = ldc.read( mConsoleInfo.getCurrentDN() );
+ //Debug.println( "Got " + entry );
+
+ try {
+ String port = getAttrVal(entry, "nsserverport");
+
+ if (port == null)
+ return false;
+ else {
+ int portnum = Integer.parseInt(port);
+ if (portnum != mPort)
+ mPort = portnum;
+ }
+ } catch (Exception e) {
+ return false;
+ }
+ } catch (LDAPException ex) {
+ CMSAdminUtil.showErrorDialog(mConsoleInfo.getFrame(), mResource,
+ ex.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ }
+ }
+
+ try {
+ // server off
+ if (getServerStatus() != STATUS_STARTED) {
+ CMSAdminUtil.showMessageDialog(mConsoleInfo.getFrame(), mResource, PREFIX,
+ "SERVEROFF", CMSAdminUtil.ERROR_MESSAGE);
+ return false;
+ }
+
+/*
+ mServerInfo = new CMSServerInfo(mHost, mPort, d.getUsername(),
+ d.getPassword(),
+ mServerID, mInstallationDate, mServerVersion, mServerRoot);
+*/
+ String path = (String)mConsoleInfo.get("cmsPath");
+ mServerInfo = new CMSServerInfo(mHost, mPort, "","",
+ mServerID, mInstallationDate, mServerVersion, mServerRoot, path);
+
+
+ String authType = mServerInfo.getAuthType();
+
+ // server is alive, do authenticate if the server asks for
+ // password-based authentication
+ if (authType.equals("pwd")) {
+ CMSPassword d = new CMSPassword(mActiveFrame);
+ d.show();
+ if (d.isCancel())
+ return false;
+ mServerInfo = new CMSServerInfo(mHost, mPort, d.getUsername(),
+ d.getPassword(),
+ mServerID, mInstallationDate, mServerVersion, mServerRoot, path);
+ mServerInfo.authenticate();
+ }
+ mConsoleInfo.put("serverInfo", mServerInfo);
+ } catch (EAdminException ex) {
+ System.exit(0); // exit if authentication fails
+ CMSAdminUtil.showErrorDialog(mConsoleInfo.getFrame(), mResource,
+ ex.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ return false;
+ }
+
+
+ //LOAD UI FRAMEWORK
+ try {
+ mFramework = new CMSUIFramework(mConsoleInfo, mServerInfo);
+ } catch (EAdminException e) {
+ CMSAdminUtil.showErrorDialog(mConsoleInfo.getFrame(), mResource,
+ e.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ return false;
+ }
+
+ //show secure status
+ StatusItemSecureMode statusSecureMode = new StatusItemSecureMode(Framework.STATUS_SECURE_MODE);
+ statusSecureMode.setSecureMode(true);
+ mFramework.getFramework().addStatusItem(statusSecureMode, IStatusItem.LEFTFIRST);
+ statusSecureMode.setToolTipText(mServerInfo.getHost()+":"+mServerInfo.getPort());
+
+ //show login status
+ updateTitle ();
+ return true;
+ }
+
+ /**
+ * Run the object
+ * @param viewInstance CMSPageFeeder object
+ * @param selectionList List of selected objects
+ */
+ public boolean run(IPage viewInstance, IResourceObject selectionList[]) {
+ return run( viewInstance );
+ }
+
+ /**
+ * perform the specified action. The command string is specified either
+ * from the content menu or the menu bar.
+ *
+ * @param command Command String
+ */
+ public void performAction(String command) {
+
+ }
+
+ /**
+ * Return the server icon.
+ *
+ * @return The Directory Server icon.
+ */
+ public Icon getIcon() {
+ return mIconImage;
+ }
+
+ public int getStatus() {
+ return mServerStatus;
+ }
+
+ /**
+ * Return the current status of the server (running or not).
+ *
+ * @return The Certificate Server status.
+ */
+ public int getServerStatus() {
+ Debug.println("Check server status");
+ if (getConsoleInfo().getCurrentDN() == null) {
+ return STATUS_STARTED;
+ } else {
+ if ( mPort == 0) {
+ mServerStatus = STATUS_UNKNOWN;
+ return STATUS_UNKNOWN;
+ }
+ try {
+ ConsoleInfo info = getServerInstanceInfo();
+ CMSStatus task = new CMSStatus();
+ mConsoleInfo.put(CMSStatus.STATUS_TASK_CGI, mServerID);
+ mConsoleInfo.put("serverRoot",mServerRoot);
+ mConsoleInfo.put("servid", mServerID);
+ task.initialize(mConsoleInfo);
+ //task.setConsoleInfo( info );
+ boolean status = task.run( null );
+ if( status) {
+ mServerStatus = STATUS_STARTED;
+ return STATUS_STARTED;
+ }
+ else{
+ mServerStatus = STATUS_STOPPED;
+ return STATUS_STOPPED;
+ }
+ }
+ catch (Exception e) {
+ String bob = e.toString();
+ Debug.println(bob);
+ if (Debug.isEnabled())
+ e.printStackTrace();
+ return STATUS_UNKNOWN;
+ }
+ }
+ }
+
+
+ /**
+ * Return the current status of the server (running or not)
+ * by pinging the agent HTTPS port.
+ *
+ * @return The Certificate Server status.
+ */
+ public boolean getStatusFromAgentPort() {
+
+ if (mPort == 0) {
+ getInfo(getConsoleInfo().getCurrentDN());
+ if (mPort == 0) {
+ //Debug.println("CMSAdmin: getServerStatus --> "+mServerStatus);
+ return false;
+ }
+ }
+
+ //check if ssl port is functional
+ try {
+ if ((mServerInfo == null) || (mServerInfo.getPort() == 0)) {
+ String path = (String)mConsoleInfo.get("cmsPath");
+ mServerInfo = new CMSServerInfo(mHost, mPort, "", "",
+ mServerID, mInstallationDate, mServerVersion, mServerRoot, path);
+ }
+
+ mServerInfo.ping();
+
+ } catch (EAdminException e) {
+ Debug.println("CMSAdmin: getServerStatus() -"+e.toString());
+ if (e.getMessageString().equals(CMSAdminResources.SERVER_NORESPONSE) ||
+ e.getMessageString().equals(CMSAdminResources.SERVER_UNREACHABLE) ||
+ e.getMessageString().equals(CMSAdminResources.IOEXCEPTION) ||
+ e.getMessageString().equals(CMSAdminResources.UNKNOWNEXCEPTION) ||
+ e.getMessageString().equals(CMSAdminResources.UNKNOWNHOST) ) {
+ // mServerStatus = STATUS_STOPPED;
+ return false;
+ }
+ Debug.println("CMSAdmin: getServerStatus() -UNKNOWN");
+ // mServerStatus = STATUS_UNKNOWN;
+ return false;
+ }
+
+ Debug.println("CMSAdmin: getServerStatus() -OK");
+ // mServerStatus = STATUS_STARTED;
+ return true;
+ }
+
+ /**
+ * The concrete class implementing this method will clone its
+ * configuration from the reference server. This supports using the
+ * GET method for cloning the server.
+ *
+ * @param referenceDN - DN of server to clone from.
+ */
+ public void cloneFrom(String referenceDN) {
+ //XXX TBD
+ }
+
+ /**
+ * Implements the IRemovableServerObject interface.
+ * @return true if the server was successfully removed, false otherwise
+ */
+
+ public boolean removeServer() {
+ Debug.println("-------------- removeServer() ==== --------------------");
+
+ Debug.println("getting console obj");
+ ConsoleInfo info = getServerInstanceInfo();
+ Debug.println("constuctor for remove");
+ /* Fire off the Remove task */
+ CMSRemove task = new CMSRemove();
+ mConsoleInfo.put(CMSRemove.REMOVE_TASK_CGI, mServerID);
+ mConsoleInfo.put("serverRoot",mServerRoot);
+ mConsoleInfo.put("servid", mServerID);
+ Debug.println("initalizing remove");
+ task.initialize(mConsoleInfo);
+ //task.setConsoleInfo( info );
+ Debug.println("about to run remove rask");
+ boolean status = task.run( null );
+ Debug.println("remove run");
+ Debug.println("Remove server status: "+ status);
+ String instance = (String) mConsoleInfo.get("ServerInstance");
+ if (null == instance) {
+ instance = "";
+ }
+
+ if (true == status) { /* successfully called remove cgi */
+ Debug.println("removing topology for the server");
+ LDAPConnection ldc = mConsoleInfo.getLDAPConnection();
+ Debug.println("got the ldap connection");
+ String[] attrs = { "*", "numsubordinates" };
+ String sieDN = mConsoleInfo.getCurrentDN();
+ Debug.println("removeServer:sieDN:" + sieDN);
+
+ LDAPEntry sieEntry = null;
+ try {
+ sieEntry = ldc.read( sieDN, attrs );
+ Debug.println("read a ldap entry");
+ } catch (Exception ex ) {
+ Debug.println( "removeServer <" + sieDN + "> " + ex);
+
+ /*
+ args[1] = ex.toString();
+ DSUtil.showErrorDialog(_info.getFrame(), "removeinstance",
+ args);
+ _removed = false; // remove failed
+ */
+ return false;
+ }
+ if (sieEntry != null ) {
+ try {
+ Debug.println("Calling delete_sieTree");
+ status = delete_sieTree(sieEntry );
+ } catch (Exception ex ) {
+ Debug.println( "removeServer:Unable to delete the " +
+ "tree");
+ /*
+ args[1] = ex.toString();
+ DSUtil.showErrorDialog(_info.getFrame(), "removesie",
+ args);
+ _removed = false; // remove failed
+ */
+ return false;
+ }
+ // Now we need to remove the reference of this server
+ Debug.println("calling remove_serverinstance");
+ status = remove_serverInstance(sieDN);
+ }
+ /*
+ if ( status == false) {
+ args[1] = "";
+ DSUtil.showErrorDialog(_info.getFrame(), "removesie",
+ args);
+ } else {
+ DSUtil.showInformationDialog(_info.getFrame(), "121",
+ (String)null) ;
+ }
+
+ */
+ }
+ // CMSAdminUtil.showMessageDialog(mConsoleInfo.getFrame(), mResource, PREFIX,
+ // "NOTIMPLEMENTED", CMSAdminUtil.ERROR_MESSAGE);
+ return status;
+ }
+
+
+
+ private boolean delete_sieTree (LDAPEntry entry )
+ throws LDAPException {
+
+ LDAPConnection ldc = mConsoleInfo.getLDAPConnection();
+ boolean ret = false;
+
+ String dn = entry.getDN();
+ if ( entryHasChildren( entry ) ) {
+ LDAPSearchResults search_results = null;
+ String[] attrs = { "numsubordinates" };
+ search_results = ldc.search( dn,
+ LDAPConnection.SCOPE_ONE,
+ "(objectClass=*)", attrs, false );
+
+ while ( search_results.hasMoreElements() ) {
+ /* Get the next child */
+ LDAPEntry child_entry =
+ (LDAPEntry)search_results.nextElement();
+ ret = delete_sieTree( child_entry );
+
+ }
+ }
+ ldc.delete(dn);
+ return true;
+ }
+
+ static boolean entryHasChildren( LDAPEntry entry ) {
+ boolean hasChildren = false;
+ LDAPAttribute attr = entry.getAttribute(
+ "numsubordinates" );
+ if ( attr != null ) {
+ Enumeration e = attr.getStringValues();
+ if ( e.hasMoreElements() ) {
+ String s = (String)e.nextElement();
+ int count = Integer.parseInt( s );
+ if ( count > 0 ) {
+ hasChildren = true;
+ }
+ }
+ }
+ return hasChildren;
+ }
+
+
+ private boolean remove_serverInstance (String sieDN ) {
+
+ LDAPSearchResults search_results = null;
+ String baseDN =(String) mConsoleInfo.get("BaseDN");
+ LDAPConnection ldc = mConsoleInfo.getLDAPConnection();
+ String[] attrs = { "*", "uniquemember" };
+ String filter = "(&(objectclass=groupOfUniquenames)(uniquemember=" +
+ sieDN+"))";
+
+ try {
+ search_results = ldc.search( baseDN, ldc.SCOPE_SUB,
+ filter, attrs, false);
+ } catch (LDAPException e) {
+ Debug.println( "Failed to search - " + e.toString() );
+ return false;
+ }
+ LDAPEntry entry = null;
+ while ( search_results.hasMoreElements() ) {
+ // need to remove the reference to the sieDN from
+ // this entry.
+
+ entry = (LDAPEntry)search_results.nextElement();
+ String eDN = (String) entry.getDN();
+ // Now we need to modify the entry to delete the
+ // reference to the serevr.
+ remove_intstanceFromEntry(ldc, eDN, sieDN);
+ }
+ return true;
+ }
+
+ private boolean remove_intstanceFromEntry ( LDAPConnection ldc,
+ String eDN, String sieDN ) {
+
+ LDAPModificationSet mods = new LDAPModificationSet();
+ LDAPAttribute attUmember = new LDAPAttribute("uniquemember", sieDN);
+ Debug.println("DSAdmin:remove_intstanceFromEntry: Modifying entry:" +
+ eDN);
+ mods.add( LDAPModification.DELETE, attUmember );
+ try {
+ ldc.modify(eDN, mods );
+ } catch ( LDAPException e ) {
+ Debug.println ( "Modifying " + eDN + ", " + e);
+ return false;
+ }
+ return true;
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ /**
+ * Extract a single string
+ *
+ * @param entry A Directory entry
+ * @param name Name of attribute to fetch
+ * @return A concatenated string
+ */
+ private String getAttrVal( LDAPEntry entry, String name ) {
+ LDAPAttribute findAttr =
+ entry.getAttribute( name, LDAPUtil.getLDAPAttributeLocale() );
+ if ( findAttr != null ) {
+ return LDAPUtil.flatting(findAttr);
+ }
+/*
+ Debug.println( "Attribute " + name + " not found in " +
+ entry.getDN() );
+*/
+ return null;
+ }
+
+ /**
+ * get the attribute information to display in the information panel
+ *
+ * @param sDN DN for the entry.
+ */
+ private void getInfo(String sDN) {
+ //String sBase = "cn=configuration, " + sDN;
+ if (sDN == null) {
+ mHost = (String)mConsoleInfo.get("cmsHost");
+ mPort = Integer.parseInt((String)mConsoleInfo.get("cmsPort"));
+ } else {
+ String sBase = sDN;
+ try {
+ LDAPConnection ldc = mConsoleInfo.getLDAPConnection();
+ if ( ldc == null ) {
+ Debug.println( "No connection ready in ConsoelInfo" );
+ ldc = new LDAPConnection();
+ ldc.connect( mConsoleInfo.getHost(), mConsoleInfo.getPort(),
+ mConsoleInfo.getAuthenticationDN(),
+ mConsoleInfo.getAuthenticationPassword());
+ }
+ //Debug.println( "Fetching " + sBase + " from " +
+ // mConsoleInfo.getHost() + ":" + mConsoleInfo.getPort() );
+ LDAPEntry entry = ldc.read( sBase );
+ //Debug.println( "Got " + entry );
+
+ mHost = getAttrVal( entry, "serverHostName" );
+ try {
+ String port = getAttrVal(entry, "nsserverport");
+ if (port == null)
+ mPort = 0;
+ else
+ mPort = Integer.parseInt(port);
+ } catch (Exception e) {
+ mPort = 0;
+ }
+
+ // get the attribute information for display purposes
+ mServerVersion = getAttrVal( entry, "serverVersionNumber" );
+ mInstallationDate = getAttrVal( entry, "installationTimeStamp" );
+ mServerID = getAttrVal( entry, "nsserverid" );
+ mServerRoot = getAttrVal( entry, "serverroot" );
+ Debug.println("CMSAdmin::PR_HOST = " + mHost);
+ mConsoleInfo.put(ConfigConstants.PR_HOST, mHost);
+ mConsoleInfo.put(ConfigConstants.PR_SERVER_ROOT, mServerRoot);
+ mConsoleInfo.put(ConfigConstants.PR_CERT_INSTANCE_NAME, mServerID);
+ } catch( Exception e) {
+ Debug.println( "Fetching " + sBase + " from " +
+ mConsoleInfo.getHost() + ":" + mConsoleInfo.getPort() +
+ ", " + e );
+ }
+
+ mAdminURL = mConsoleInfo.getAdminURL();
+
+ /* Extract the username part of the admin authentication DN */
+ String[] rdns = LDAPDN.explodeDN( mConsoleInfo.getAuthenticationDN(),
+ true );
+ String s = rdns[0].trim();
+ mConsoleInfo.put( "AdminUsername", s );
+ //getServerStatus();
+ }
+ }
+
+ /**
+ * Note: it would be better if this method were declared in the superclass,
+ * but having it here is better than nothing, since I need access to it
+ * for getServerStatus() . . .
+ */
+ private IPage getViewInstance() {
+ return _viewInstance;
+ }
+
+ public boolean isCloningEnabled() {
+ return false;
+ }
+
+ public boolean isMigrationEnabled() {
+ return false;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSAdminResources.java b/base/console/src/com/netscape/admin/certsrv/CMSAdminResources.java
new file mode 100644
index 000000000..af2ba4c91
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSAdminResources.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.admin.certsrv;
+
+import com.netscape.management.client.util.*;
+import java.io.*;
+import java.util.*;
+import com.netscape.certsrv.common.Constants;
+
+/**
+ * Resource Boundle for the Certificate Server Admin Console
+ *
+ * <pre>
+ * COMPONENT NAMING CONTEXT:
+ *
+ * CONTEXT = PANELNAME + <COMPONENT> + IDENTIFIER + <SUFFIX>
+ *
+ * PANELNAME = UPPERCASE STRING IDENTIFIER
+ * <COMPONENT> = {"BORDER","BUTTON","TEXT","RADIOBUTTON","CHECKBOX","LIST","COMBOBOX","LABEL"}
+ * IDENTIFIER = UPPERCASE STRING COMPONENT IDENTIFIER
+ * <SUFFIX> = {"LABEL","TTIP", <VALUE>}
+ * <VALUE> = "VALUE" + {"0","1",...}
+ * + = "_"
+ * </pre>
+ *
+ *
+ * @author Jack Pan-Chen
+ * @author Thomas Kwan
+ * @author Christina Fu
+ * @version $Revision$, $Date$
+ */
+
+public class CMSAdminResources extends ResourceBundle {
+
+ //directory
+ static final String DEFAULT_IMAGE_DIRECTORY = "com/netscape/admin/certsrv/images";
+ static final String DEFAULT_THEME_IMAGE_DIRECTORY = "com/netscape/admin/certsrv/theme";
+
+ //image files
+ public static final String IMAGE_CERTICON_LARGE = "CertificateServerL.gif";
+ public static final String IMAGE_CERTICON_SMALL = "CertificateServer.gif";
+ public static final String IMAGE_CERTICON_MEDIUM = "cert24.gif";
+ public static final String IMAGE_LOGFOLDER = "alllogfolder16n.gif";
+ public static final String IMAGE_LOGOBJ = "LOGobjs.gif";
+ public static final String IMAGE_LOGOBJECT = "alllogdoc16n.gif";
+ public static final String IMAGE_FOLDER = "allfolder16n.gif";
+ public static final String IMAGE_USERGROUP = "allgroup16n.gif";
+ public static final String IMAGE_USER = "alluser16n.gif";
+ public static final String IMAGE_USER_WITH_CERT = "alluserwithcert16n.gif";
+ public static final String IMAGE_UGOBJECT = "UGobjs.gif";
+ public static final String IMAGE_DIRTY_TAB = "red-ball-small.gif";
+ public static final String IMAGE_BRANDING = "certmgmt.gif";
+ public static final String IMAGE_GENERICOBJ = "genobject.gif";
+ public static final String IMAGE_PLUGIN = "plug.gif";
+ public static final String IMAGE_PLUGINOBJECT = "plugin.gif";
+ public static final String IMAGE_PLUGINFOLDER = "pluginfolder.gif";
+ public static final String IMAGE_RULEOBJECT = "rulesobj.gif";
+ public static final String IMAGE_RULE = "rule-16.gif";
+ public static final String IMAGE_RULE_PLUGIN = "ruleplugin-16.gif";
+ public static final String IMAGE_RULE_DISABLE = "ruleDisable-16.gif";
+ public static final String IMAGE_SERVLETOBJECT = "servletobj.gif";
+ public static final String IMAGE_SERVLET = "servlet-16.gif";
+ public static final String IMAGE_SERVLET_PLUGIN = "servlet-plugin-16.gif";
+ public static final String IMAGE_AUTH = "auth.gif";
+ public static final String IMAGE_AUTH_PLUGIN = "authplugin.gif";
+ public static final String IMAGE_AUTHOBJECT = "authobj.gif";
+ public static final String IMAGE_JOBS = "jobs.gif";
+ public static final String IMAGE_JOBS_PLUGIN = "jobplugin.gif";
+ public static final String IMAGE_JOBSOBJECT = "jobobj.gif";
+ public static final String IMAGE_LDAPPUB = "ldapub.gif";
+ public static final String IMAGE_ACLOBJECT = "aclobj.gif";
+ public static final String IMAGE_ACL = "acl.gif";
+ public static final String IMAGE_ACLPLUGIN = "aclplugin.gif";
+
+ //dialog icons
+ public static final String IMAGE_INFO_ICON = "messagel.gif";
+ public static final String IMAGE_ERROR_ICON = "error.gif";
+ public static final String IMAGE_WARN_ICON = "alertl.gif";
+
+
+ /**
+ * Exception resources
+ */
+ public final static String IOEXCEPTION = "IOEXCEPTION";
+ public final static String UNKNOWNHOST = "UNKNOWNHOST";
+ public final static String UNKNOWNEXCEPTION = "UNKNOWNEXCEPTION";
+ public final static String AUTHENNOTSUPPORTED = "AUTHENNOTSUPPORTED";
+ public final static String AUTHENTICATION_FAILED = "AUTHENTICATION_FAILED";
+ public final static String PING_FAILED = "PING_FAILED";
+ public final static String SERVER_UNREACHABLE = "SERVER_UNREACHABLE";
+ public final static String SERVER_NORESPONSE ="SERVER_NORESPONSE";
+ public final static String SERVERCONNECTION_SERVER_CERT_IMPORTED_FAILED="SERVERCONNECTION_SERVER_CERT_IMPORTED_FAILED";
+ public final static String SERVERCONNECTION_NO_CLIENT_CERT="SERVERCONNECTION_NO_CLIENT_CERT";
+ public final static String SERVERCONNECTION_SERVER_CERT_DENIED="SERVERCONNECTION_SERVER_CERT_DENIED";
+ public final static String SERVERCONNECTION_DIFFERENT_PWD = "SERVERCONNECTION_DIFFERENT_PWD";
+ public final static String SERVERCONNECTION_TOKEN_INIT_FAILED = "SERVERCONNECTION_TOKEN_INIT_FAILED";
+ public final static String PROTOCOL_ERROR = "PROTOCOL_ERROR";
+
+ //server info panel
+ public final static String CERT_SERVER_NAME = "CMSINFOPANEL_LABEL_SERVERNAME_LABEL";
+ public final static String SERVER_STATUS = "CMSINFOPANEL_LABEL_STATUS_LABEL";
+ public final static String SERVER_STATUS_ON = "CMSINFOPANEL_LABEL_STATUSON_LABEL";
+ public final static String SERVER_STATUS_OFF = "CMSINFOPANEL_LABEL_STATUSOFF_LABEL";
+ public final static String SERVER_INFO = "CMSINFOPANEL_LABEL_SERVERINFO_LABEL";
+
+ //general items
+ public final static String GENERAL_OK = "GENERAL_OK";
+ public final static String GENERAL_BACK = "GENERAL_BACK";
+ public final static String GENERAL_DONE = "GENERAL_DONE";
+ public final static String GENERAL_NEXT = "GENERAL_NEXT";
+ public final static String GENERAL_HELP = "GENERAL_HELP";
+ public final static String GENERAL_CANCEL = "GENERAL_CANCEL";
+ public final static String GENERAL_ERROR = "GENERAL_ERROR";
+ public final static String GENERAL_QUESTION = "GENERAL_QUESTION";
+
+ //menu items
+ public final static String MENU_KEYCERT = "KEYCERT";
+ public final static String MENU_REFRESH = "REFRESH";
+ public final static String MENU_KEYCERT_MANAGEMENT = "CERTMANAGEMENT";
+ public final static String MENU_PKCS11 = "PKCS11MANAGEMENT";
+ public final static String MENU_NEWCERT = "NEWCERT";
+ public final static String MENU_NEW_EXTENSION = "NEW_EXTENSION";
+ public final static String MENU_NEW_POLICY = "NEW_POLICY";
+ public final static String MENU_PERMISSION = "PERMISSION";
+ public final static String MENU_CONFIGURE_SERVER = "Configure Server";
+ public final static String MENU_CONFIGURE_SERVER_DESC = "Configure the Server";
+ public final static String MENU_START_SERVER = "Start Server";
+ public final static String MENU_START_SERVER_DESC = "Start the Server";
+ public final static String MENU_REMOVE_SERVER = "Remove Server";
+ public final static String MENU_REMOVE_SERVER_DESC = "Remove the Server";
+ public final static String MENU_STOP_SERVER = "Stop Server";
+ public final static String MENU_STOP_SERVER_DESC = "Stop the Server";
+ public final static String MENU_RESTART_SERVER = "Restart Server";
+ public final static String MENU_RESTART_SERVER_DESC = "Restart the Server";
+
+
+ public final static String PROP_FILE =
+ "CMSAdminRS";
+
+ public CMSAdminResources()
+ {
+ mResourceSet = new ThisResourceSet(PROP_FILE);
+ mResourceBundle = mResourceSet.getThisBundle(PROP_FILE,
+ Locale.getDefault());
+ }
+
+ /**
+ * Override of ResourceBundle, same semantics
+ */
+ public Object handleGetObject(String key) {
+ Object o = mResourceBundle.handleGetObject(key);
+ if (o == null) {
+ Debug.println("**** UNDEFINED PROPERTY=" + key);
+ }
+ return o;
+ }
+
+ /**
+ * Implementation of ResourceBundle.getKeys.
+ */
+ public Enumeration getKeys() {
+ return mResourceBundle.getKeys();
+ }
+
+ // ==================privates====================
+
+ private PropertyResourceBundle mResourceBundle = null;
+ private ThisResourceSet mResourceSet = null;
+}
+
+class ThisResourceSet extends ResourceSet
+{
+ public ThisResourceSet(String s)
+ {
+ super(s);
+ }
+
+ public PropertyResourceBundle getThisBundle(String n, Locale l)
+ {
+ return super.getBundle(n, l);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSAdminUtil.java b/base/console/src/com/netscape/admin/certsrv/CMSAdminUtil.java
new file mode 100644
index 000000000..107de427b
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSAdminUtil.java
@@ -0,0 +1,1298 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv;
+
+import java.util.*;
+import java.text.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.border.*;
+import javax.swing.table.*;
+import javax.swing.text.*;
+import java.awt.*;
+import java.awt.event.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.misc.MessageFormatter;
+import java.text.BreakIterator;
+import java.text.Collator;
+import com.netscape.management.nmclf.*;
+
+/**
+ * Utility class for the CMSAdmin package
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @date 01/12/97
+ */
+public class CMSAdminUtil {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final int DEFAULT_TEXTFIELD_WIDTH = 30;
+ public static final int COMPONENT_SPACE = SuiLookAndFeel.COMPONENT_SPACE;
+ public static final int SEPARATED_COMPONENT_SPACE =
+ SuiLookAndFeel.SEPARATED_COMPONENT_SPACE;
+ public static final int DIFFERENT_COMPONENT_SPACE =
+ SuiLookAndFeel.DIFFERENT_COMPONENT_SPACE;
+ public static final int HELP_BUTTON_OFFSET = 9;
+
+ public static final int DEFAULT_BUTTON_SIZE = 72;
+
+ final public static Dimension DEFAULT_PANEL_SIZE = new Dimension(350,440);
+ final public static int DEFAULT_PADDING = SuiLookAndFeel.COMPONENT_SPACE;
+ private static final int DEFAULT_WIDTH = 40;
+ final public static Insets DEFAULT_EMPTY_INSETS = new Insets(0,0,0,0);
+ public static final Insets DEAFULT_END_INSETS = new Insets(COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE,COMPONENT_SPACE);
+
+ public static final int WARNING_MESSAGE = JOptionPane.WARNING_MESSAGE;
+ public static final int ERROR_MESSAGE = JOptionPane.ERROR_MESSAGE;
+ public static final int INFORMATION_MESSAGE = JOptionPane.INFORMATION_MESSAGE;
+ public static final int OK_OPTION = JOptionPane.OK_OPTION;
+ public static final int NO_OPTION = JOptionPane.NO_OPTION;
+ public static final int CANCEL_OPTION = JOptionPane.CANCEL_OPTION;
+
+ private static Hashtable mPackageImages = new Hashtable(); //image container
+ private static final ResourceSet mHelpResource =
+ new ResourceSet("com.netscape.admin.certsrv.certsrv-help");
+ public static final ResourceSet mResource =
+ new ResourceSet("com.netscape.admin.certsrv.certsrv");
+ public static Collator collator = Collator.getInstance();
+
+
+
+ /*==========================================================
+ * Utilities methods
+ *==========================================================*/
+
+ /**
+ * Utility function to retrieve images from the package image
+ * class path.
+ *
+ * @param name Image name to be returned
+ * @return Image
+ */
+ public static RemoteImage getImage( String name ) {
+ String imageDir = CMSAdminResources.DEFAULT_IMAGE_DIRECTORY;
+ RemoteImage i = (RemoteImage) mPackageImages.get( name );
+ if ( i != null )
+ return i;
+ i = getSystemImage( imageDir + "/" + name );
+ if ( i != null )
+ mPackageImages.put( name, i );
+ return i;
+ }
+
+ public static RemoteImage getThemeImage( String name ) {
+ String imageDir = CMSAdminResources.DEFAULT_THEME_IMAGE_DIRECTORY;
+ RemoteImage i = (RemoteImage) mPackageImages.get( name );
+ if ( i != null )
+ return i;
+ i = getSystemImage( imageDir + "/" + name );
+ if ( i != null )
+ mPackageImages.put( name, i );
+ return i;
+ }
+
+ /**
+ * Utility function to reset the GridBagConstraints to default
+ *
+ * parameters specified below.
+ * @param GridBagConstraints to be reseted
+ */
+ public static 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;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ 0,COMPONENT_SPACE);
+ }
+
+ public static void repaintComp(JComponent component) {
+ component.invalidate();
+ component.validate();
+ component.repaint(1);
+ }
+
+ public static void enableJTextField(JTextComponent component,
+ boolean enable, Color color) {
+ component.setEnabled(enable);
+ component.setEditable(enable);
+ component.setBackground(color);
+ component.invalidate();
+ component.validate();
+ component.repaint(1);
+ }
+
+ public static void addComponents(JPanel panel, JComponent comp1,
+ JComponent comp2, GridBagConstraints gbc) {
+ double weighty = gbc.weighty;
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.weighty = weighty;
+ panel.add(comp1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.weighty = weighty;
+ gbc.gridwidth = gbc.REMAINDER;
+ panel.add(comp2, gbc);
+ }
+
+ public static void addComponents(JPanel panel, JComponent comp1,
+ JComponent comp2, JComponent comp3, GridBagConstraints gbc) {
+ double weighty = gbc.weighty;
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.weighty = weighty;
+ panel.add(comp1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.weighty = weighty;
+ panel.add(comp2, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.weighty = weighty;
+ gbc.gridwidth = gbc.REMAINDER;
+ panel.add(comp3, gbc);
+ }
+
+ public static void addComponents(JPanel panel, JComponent comp1,
+ JComponent comp2, JComponent comp3, JComponent comp4,
+ GridBagConstraints gbc) {
+ double weighty = gbc.weighty;
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.weighty = weighty;
+ panel.add(comp1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.weighty = weighty;
+ panel.add(comp2, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.weighty = weighty;
+ panel.add(comp3, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.weighty = weighty;
+ gbc.gridwidth = gbc.REMAINDER;
+ panel.add(comp4, gbc);
+ }
+
+ /**
+ * Add a label and a textfield to a panel, assumed to be using
+ * GridBagLayout.
+ */
+ public static void addEntryField(JPanel panel, JComponent label,
+ JComponent field, GridBagConstraints gbc) {
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.gridx = 0;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ panel.add( label, gbc );
+
+ gbc.gridx++;
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ 0,DIFFERENT_COMPONENT_SPACE);
+ panel.add( field, gbc );
+ }
+
+ /**
+ * Add 3 components in the same row to a panel, assumed to be using
+ * GridBagLayout.
+ */
+ public static void addEntryField(JPanel panel, JComponent field1,
+ JComponent field2, JComponent field3, GridBagConstraints gbc) {
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.gridx = 0;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ panel.add( field1, gbc );
+
+ gbc.gridx++;
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,0);
+ panel.add(field2, gbc);
+
+ gbc.gridx++;
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ 0,DIFFERENT_COMPONENT_SPACE);
+ panel.add( field3, gbc );
+ }
+
+ /**
+ * Add 4 components in the same row to a panel, assumed to be using
+ * GridBagLayout.
+ */
+ public static void addEntryField(JPanel panel, JComponent field1,
+ JComponent field2, JComponent field3, JComponent field4, GridBagConstraints gbc) {
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.gridx = 0;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ panel.add( field1, gbc );
+
+ gbc.gridx++;
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 0.5;
+ gbc.gridwidth = 1;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,0);
+ panel.add(field2, gbc);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.gridx++;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ panel.add( field3, gbc );
+
+ gbc.gridx++;
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 0.5;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ 0,DIFFERENT_COMPONENT_SPACE);
+ panel.add( field4, gbc );
+ }
+
+ /**
+ * Add 5 components in the same row to a panel, assumed to be using
+ * GridBagLayout.
+ */
+ public static void addEntryField(JPanel panel, JComponent field1,
+ JComponent field2, JComponent field3, JComponent field4,
+ JComponent field5, GridBagConstraints gbc) {
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.gridx = 0;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ panel.add( field1, gbc );
+
+ gbc.gridx++;
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.HORIZONTAL;
+ //gbc.weightx = 0.5;
+ gbc.gridwidth = 1;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,0);
+ panel.add(field2, gbc);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.gridx++;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ panel.add( field3, gbc );
+
+ gbc.gridx++;
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ //gbc.weightx = 0.5;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ 0,DIFFERENT_COMPONENT_SPACE);
+ panel.add( field4, gbc );
+
+ gbc.gridx++;
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ 0,DIFFERENT_COMPONENT_SPACE);
+ panel.add( field5, gbc );
+ }
+
+ /**
+ * Add 6 components in the same row to a panel, assumed to be using
+ * GridBagLayout.
+ */
+ public static void addEntryField(JPanel panel, JComponent field1,
+ JComponent field2, JComponent field3, JComponent field4,
+ JComponent field5, JComponent field6, GridBagConstraints gbc) {
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.gridx = 0;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ panel.add( field1, gbc );
+
+ gbc.gridx++;
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.HORIZONTAL;
+ //gbc.weightx = 0.5;
+ gbc.gridwidth = 1;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,0);
+ panel.add(field2, gbc);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.gridx++;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ panel.add( field3, gbc );
+
+ gbc.gridx++;
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ //gbc.weightx = 0.5;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ 0,DIFFERENT_COMPONENT_SPACE);
+ panel.add(field4, gbc);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.gridx++;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ panel.add( field5, gbc );
+
+ gbc.gridx++;
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ 0,DIFFERENT_COMPONENT_SPACE);
+ panel.add( field6, gbc );
+ }
+
+ /**
+ * Utility function to wrap text at given width. Used mostly
+ * for displaying text in the dialog box.
+ *
+ * @param s message string
+ * @param width width per line
+ * @return string with line feeds
+ */
+ public static String wrapText(String str, int width)
+ {
+ if (str == null || str.length() < width) {
+ return str;
+ }
+ String ret = "";
+
+ StringTokenizer tokenizer = new StringTokenizer(str, "\n");
+ while (tokenizer.hasMoreTokens()) {
+ BreakIterator boundary = BreakIterator.getLineInstance();
+ String s = (String)tokenizer.nextToken();
+ boundary.setText(s);
+ int end;
+ int start = 0;
+ while ((end = boundary.next()) != BreakIterator.DONE) {
+ if (end - start > width) {
+ end = boundary.previous();
+ if (start == end) {
+ // Was too long for even one iteration
+ end = boundary.next();
+ }
+ ret += s.substring(start, end);
+ ret += "\n";
+ start = end;
+ }
+ }
+ end = boundary.last();
+ ret = ret+s.substring(start, end)+"\n";
+ }
+ return ret;
+ }
+
+ public static String certRequestWrapText(String s, int width) {
+ String ret = "";
+ StringTokenizer tokenizer = new StringTokenizer(s, "\n");
+ int numTokens = tokenizer.countTokens();
+ int index = 1;
+ String beginCert = "";
+ String endCert = "";
+ String content = "";
+ while(tokenizer.hasMoreTokens()) {
+ String sToken = (String)tokenizer.nextToken();
+ if (index == 1) {
+ beginCert = sToken;
+ } else if (index == numTokens) {
+ endCert = sToken;
+ } else {
+ content += sToken;
+ }
+
+ index++;
+ }
+
+ ret = beginCert+"\n"+wrapText(content, width, true)+"\n"+endCert;
+ return ret;
+ }
+
+ public static String wrapText(String s, int width, boolean noIterator) {
+ if (noIterator) {
+ if (s == null || s.length() <= width) {
+ return s;
+ }
+
+ String ret = "";
+ int start = 0;
+ int end = width;
+ int len = s.length();
+ while (len > width) {
+ ret += s.substring(start, end);
+ ret += "\n";
+ len -= width;
+ start += width;
+ end += width;
+ }
+ ret += s.substring(start);
+ return ret;
+ } else {
+ return wrapText(s, width);
+ }
+ }
+
+ /**
+ * Utility function to wrap text at default width. Used mostly
+ * for displaying text in the dialog box.
+ *
+ * @param s message string
+ * @return string with line feeds
+ */
+ public static String wrapText(String s) {
+ return(wrapText(s, DEFAULT_WIDTH));
+ }
+
+ /**
+ * Find out the table width to be used
+ *
+ * @table JTable object
+ */
+ public static int getTotalColumnWidth( JTable table ) {
+ Enumeration en = table.getColumnModel().getColumns();
+ int width = 0;
+ while( en.hasMoreElements() ) {
+ TableColumn col = (TableColumn)en.nextElement();
+ width += col.getWidth();
+ }
+ return width - 200;
+ }
+
+
+ /*==========================================================
+ * Component Factory
+ *==========================================================*/
+
+ //==== BORDER CREATION ====================================
+ public static Border makeEtchedBorder() {
+ Border margin = new EmptyBorder(0,0,
+ SuiLookAndFeel.VERT_WINDOW_INSET,0);
+ return new CompoundBorder(BorderFactory.createEtchedBorder(), margin);
+ }
+
+ public static Border makeTitledBorder(ResourceBundle resource,
+ String panelName,
+ String keyword) {
+ String title;
+ try {
+ title = resource.getString(panelName+"_BORDER_"+keyword+"_LABEL");
+ } catch (MissingResourceException e) {
+ title = "Missing Title";
+ }
+ return new TitledBorder(title);
+ }
+
+ //==== DIALOG CREATION ====================================
+
+ public static void showMessageDialog(ResourceBundle resource,
+ String panelName,
+ String keyword,
+ int messageType ) {
+ showMessageDialog(UtilConsoleGlobals.getActivatedFrame(), resource, panelName, keyword, messageType);
+ }
+
+ public static void showMessageDialog(JFrame frame,
+ String title,
+ String msg,
+ int messageType ) {
+ Icon icon;
+ if (messageType != ERROR_MESSAGE)
+ icon = getImage(CMSAdminResources.IMAGE_INFO_ICON);
+ else
+ icon = getImage(CMSAdminResources.IMAGE_ERROR_ICON);
+
+ JOptionPane.showMessageDialog(
+ frame,
+ CMSAdminUtil.wrapText(msg),
+ title,
+ messageType,
+ icon);
+ }
+
+ /**
+ * Creating message dialog box for display
+ */
+ public static void showMessageDialog(JFrame frame,
+ ResourceBundle resource,
+ String panelName,
+ String keyword,
+ int messageType ) {
+ String msg, title;
+ try {
+ msg = resource.getString(panelName+"_DIALOG_"+keyword+ "_MESSAGE");
+ } catch (MissingResourceException e) {
+ msg = "Missing Label";
+ }
+ try {
+ title = resource.getString(panelName+"_DIALOG_"+keyword+ "_TITLE");
+ } catch (MissingResourceException e) {
+ title = "Missing Title";
+ }
+
+ Icon icon;
+ if (messageType != ERROR_MESSAGE)
+ icon = getImage(CMSAdminResources.IMAGE_INFO_ICON);
+ else
+ icon = getImage(CMSAdminResources.IMAGE_ERROR_ICON);
+
+ JOptionPane.showMessageDialog(
+ frame,
+ CMSAdminUtil.wrapText(msg),
+ title,
+ messageType,
+ icon);
+ }
+
+ public static void showErrorDialog(ResourceBundle resource,
+ String message,
+ int messageType) {
+ showErrorDialog(new JFrame(), resource, message, messageType);
+ }
+
+ /**
+ * Creating error dialog box for display
+ */
+ public static void showErrorDialog(JFrame frame,
+ ResourceBundle resource,
+ String message,
+ int messageType) {
+ String title;
+ try {
+ title = resource.getString(CMSAdminResources.GENERAL_ERROR);
+ } catch (MissingResourceException e) {
+ title = "Missing Title";
+ }
+ JOptionPane.showMessageDialog(
+ frame,
+ CMSAdminUtil.wrapText(message),
+ title,
+ messageType,
+ getImage(CMSAdminResources.IMAGE_ERROR_ICON));
+ }
+
+ public static int showConfirmDialog( ResourceBundle resource,
+ String panelName,
+ String keyword,
+ int messageType )
+ {
+ return showConfirmDialog(new JFrame(), resource, panelName, keyword, messageType);
+ }
+
+ public static int showConfirmDialog( ResourceBundle resource,
+ String panelName,
+ String keyword, String[] params,
+ int messageType )
+ {
+ return showConfirmDialog(new JFrame(), resource, panelName, keyword,
+ params, messageType);
+ }
+
+ /**
+ * Creating confirm dialog box for display
+ */
+ public static int showConfirmDialog( JFrame frame,
+ ResourceBundle resource,
+ String panelName,
+ String keyword,
+ int messageType )
+ {
+ String msg, title;
+ try {
+ msg = resource.getString(panelName+"_DIALOG_"+keyword+ "_MESSAGE");
+ } catch (MissingResourceException e) {
+ msg = "Missing Label";
+ }
+ try {
+ title = resource.getString(panelName+"_DIALOG_"+keyword+ "_TITLE");
+ } catch (MissingResourceException e) {
+ title = "Missing Title";
+ }
+
+ return JOptionPane.showConfirmDialog(
+ frame,
+ CMSAdminUtil.wrapText(msg), title,
+ JOptionPane.YES_NO_OPTION,
+ messageType,
+ getImage(CMSAdminResources.IMAGE_WARN_ICON));
+ }
+
+ public static int showConfirmDialog(JFrame frame, ResourceBundle resource,
+ String panelName, String keyword, String[] params, int messageType )
+ {
+ String msg, title;
+ try {
+ msg = resource.getString(panelName+"_DIALOG_"+keyword+ "_MESSAGE");
+ } catch (MissingResourceException e) {
+ msg = "Missing Label";
+ }
+ try {
+ title = resource.getString(panelName+"_DIALOG_"+keyword+ "_TITLE");
+ } catch (MissingResourceException e) {
+ title = "Missing Title";
+ }
+
+ String finalmsg = msg;
+ if (params != null && params.length > 0) {
+ MessageFormat mf = new MessageFormat(msg);
+ finalmsg = mf.format(params);
+ }
+
+ return JOptionPane.showConfirmDialog(
+ frame,
+ CMSAdminUtil.wrapText(finalmsg), title,
+ JOptionPane.YES_NO_OPTION,
+ messageType,
+ getImage(CMSAdminResources.IMAGE_WARN_ICON));
+ }
+
+ //==== LABEL CREATION ================================
+
+ /**
+ * Factory Method to create LABEL using specified params
+ */
+ public static JLabel makeJLabel(ResourceBundle resource,
+ String panelName,
+ String keyword,
+ Icon icon)
+ {
+ return makeJLabel(resource, panelName, keyword, icon, -1);
+ }
+
+
+ /**
+ * Factory Method to create LABEL using specified params
+ */
+ public static JLabel makeJLabel(ResourceBundle resource,
+ String panelName,
+ String keyword,
+ Icon icon,
+ int alignment)
+ {
+ String title;
+ try {
+ title = resource.getString(panelName+"_LABEL_"+keyword+ "_LABEL");
+ } catch (MissingResourceException e) {
+ title = "Missing Label";
+ Debug.println("CMSAdminUtil - makeJLabel() - missing resource: "+panelName+"_LABEL_"+keyword+ "_LABEL");
+ }
+ JLabel label = new JLabel();
+ if (icon != null)
+ label.setIcon(icon);
+ if (title != null)
+ label.setText(title);
+ if (alignment != -1)
+ label.setHorizontalAlignment(alignment);
+ //setToolTip(resource, panelName, "LABEL_"+keyword, label);
+
+ return label;
+ }
+
+
+ //==== TEXTFIELD CREATION ================================
+
+ /**
+ * Factory Method to create TextFiled using specified params
+ */
+ public static JTextField makeJTextField(Document d,
+ String s,
+ int len,
+ Object listener) {
+
+ JTextField pf = new JTextField(DEFAULT_TEXTFIELD_WIDTH){
+ public void setEnabled( boolean enabled ) {
+ super.setEnabled( enabled );
+ //super.setEditable(enabled);
+ super.setBackground( enabled ? Color.white: SystemColor.window);
+ }
+ };
+ pf.setEnabled( true );
+
+ if (d != null)
+ pf.setDocument(d);
+ if (s != null)
+ pf.setText(s);
+ if (len != -1)
+ pf.setColumns(len);
+
+ pf.addActionListener((ActionListener)listener);
+ //detect text changes
+ pf.getDocument().addDocumentListener((DocumentListener)listener);
+ return pf;
+ }
+
+ //==== PASSWORD FIELD CREATION ================================
+
+ /**
+ * Factory Method to create Password Filed using specified params
+ */
+ public static JPasswordField makeJPasswordField(Document d,
+ String s,
+ int len,
+ Object listener) {
+ JPasswordField pf = new JPasswordField(DEFAULT_TEXTFIELD_WIDTH) {
+ public void setEnabled( boolean enabled ) {
+ super.setEnabled( enabled );
+ super.setEditable(enabled);
+ setBackground( enabled ? Color.white: SystemColor.window);
+ this.repaint();
+ }
+ };
+ pf.setEnabled( true );
+ if (d != null)
+ pf.setDocument(d);
+ if (s != null)
+ pf.setText(s);
+ if (len != -1)
+ pf.setColumns(len);
+
+ pf.addActionListener((ActionListener)listener);
+ //detect text changes
+ pf.getDocument().addDocumentListener((DocumentListener)listener);
+ return pf;
+ }
+
+
+ //==== LIST CREATION ================================
+
+ /**
+ * Factory Method to create a list box mode specified with specific
+ * visible row count. Special cell renderer is used to display each cell.
+ */
+ public static JList makeJList(DefaultListModel listModel, int visibleCount) {
+ JList listbox = new JList(listModel);
+ listbox.setCellRenderer(new AttrCellRenderer());
+ listbox.setSelectionModel(new DefaultListSelectionModel());
+ listbox.setVisibleRowCount(visibleCount);
+ if(listModel.size()!=0)
+ listbox.setSelectedIndex(0);
+ return listbox;
+ }
+
+ //===== CHECKBOX CREATION =======================
+
+ /**
+ * Factory Method to create CheckBox using specified params
+ */
+ public static JCheckBox makeJCheckBox(ResourceBundle resource,
+ String panelName,
+ String keyword,
+ Icon icon,
+ boolean select,
+ ActionListener listener)
+ {
+ String label;
+ try {
+ label = resource.getString(panelName+"_CHECKBOX_"+keyword+ "_LABEL");
+ } catch (MissingResourceException e) {
+ label = "Missing Label";
+ }
+
+ JCheckBox button = new JCheckBox();
+ if (label != null)
+ button.setText(label);
+ if (icon != null)
+ button.setIcon(icon);
+ button.setSelected(select);
+ button.addActionListener(listener);
+ //setToolTip(resource, panelName, "CHECKBOX_"+keyword, button);
+
+ return button;
+ }
+
+ //===== RADIO BUTTON CREATION =======================
+
+ /**
+ * Factory Method to create Radio Button using specified params
+ */
+ public static JRadioButton makeJRadioButton(ResourceBundle resource,
+ String panelName,
+ String keyword,
+ Icon icon,
+ boolean select,
+ ActionListener listener)
+ {
+ String label;
+ try {
+ label = resource.getString(panelName+"_RADIOBUTTON_"+keyword+ "_LABEL");
+ } catch (MissingResourceException e) {
+ label = "Missing Label";
+ }
+
+ JRadioButton button = new JRadioButton();
+ if (label != null)
+ button.setText(label);
+ if (icon != null)
+ button.setIcon(icon);
+ button.setSelected(select);
+ button.addActionListener(listener);
+ //setToolTip(resource, panelName, "RADIOBUTTON_"+keyword, button);
+
+ return button;
+ }
+
+ //===== BUTTON CREATION =======================
+
+ /**
+ * Factory Method to create Button using specified params
+ */
+ public static JButton makeJButton(ResourceBundle resource,
+ String panelName,
+ String keyword,
+ Icon icon,
+ ActionListener listener)
+ {
+ String label;
+ try {
+ label = resource.getString(panelName+"_BUTTON_"+keyword+ "_LABEL");
+ } catch (MissingResourceException e) {
+ label = "Missing Label";
+ }
+
+ JButton button = new JButton();
+ if (label != null)
+ button.setText(label);
+ if (icon != null)
+ button.setIcon(icon);
+ button.addActionListener(listener);
+ //setToolTip(resource, panelName, "BUTTON_"+keyword, button);
+
+ return button;
+ }
+
+ /**
+ * Create a panel with horizontally arranged, equally sized buttons
+ * The buttons are aligned to the right in the panel (if it is
+ * stretched beyond the length of the buttons)
+ *
+ * @param buttons An array of buttons for the panel
+ * @param isHelp Help button is the last one so pat extra space
+ * @param isConfig don't pat button
+ * @return A panel containing the buttons
+ */
+
+ public static JPanel makeJButtonPanel( JButton[] buttons) {
+ return makeJButtonPanel(buttons, false, false);
+ }
+
+ public static JPanel makeJButtonPanel( JButton[] buttons, boolean isHelp) {
+ return makeJButtonPanel(buttons, isHelp, false);
+ }
+
+ public static JPanel makeJButtonPanel( JButton[] buttons, boolean isHelp, boolean isConfig) {
+ JButtonFactory.resize( buttons );
+ JPanel buttonPanel = new JPanel();
+ GridBagConstraints gbc = new GridBagConstraints();
+ buttonPanel.setLayout(new GridBagLayout());
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.gridwidth = 1;
+ buttonPanel.add( Box.createGlue(), gbc );
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0;
+ for( int i = 0; i < buttons.length; i++ ) {
+ if ( i == buttons.length-1 ) {
+ gbc.gridwidth = gbc.REMAINDER;
+ if (isHelp)
+ buttonPanel.add( Box.createHorizontalStrut(HELP_BUTTON_OFFSET));
+ else
+ buttonPanel.add( Box.createHorizontalStrut(SuiLookAndFeel.COMPONENT_SPACE) );
+ }
+ buttonPanel.add( buttons[i], gbc );
+ if ( i < buttons.length-2 )
+ buttonPanel.add( Box.createHorizontalStrut(SuiLookAndFeel.COMPONENT_SPACE) );
+ }
+
+ JPanel p = new JPanel();
+ p.setLayout( new BorderLayout() );
+ p.add( "Center", buttonPanel );
+
+ if(!isConfig) {
+ p.add( "South",
+ Box.createVerticalStrut(DIFFERENT_COMPONENT_SPACE) );
+ p.add( "East",
+ Box.createHorizontalStrut(DIFFERENT_COMPONENT_SPACE) );
+ } else {
+ p.add( "South",
+ Box.createVerticalStrut(DIFFERENT_COMPONENT_SPACE-COMPONENT_SPACE) );
+ }
+ p.add( "North",
+ Box.createVerticalStrut(DIFFERENT_COMPONENT_SPACE) );
+
+ return p;
+ }
+
+ /**
+ * Create a panel with vertically arranged, equally sized buttons
+ * The buttons are aligned to the top in the panel (if it is
+ * stretched beyond the length of the buttons)
+ *
+ * @param buttons An array of buttons for the panel
+ * @return A panel containing the buttons
+ */
+ public static JPanel makeJButtonVPanel( JButton[] buttons ) {
+ //JButtonFactory.resize( buttons );
+ JPanel buttonPanel = new JPanel();
+ GridBagConstraints gbc = new GridBagConstraints();
+ buttonPanel.setLayout(new GridBagLayout());
+ resetGBC(gbc);
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, DIFFERENT_COMPONENT_SPACE, 0,0);
+
+ for( int i = 0; i < buttons.length; i++ ) {
+ if ( i == buttons.length-1 )
+ gbc.gridheight = gbc.REMAINDER;
+ buttonPanel.add( buttons[i], gbc );
+ gbc.insets = new Insets(COMPONENT_SPACE, DIFFERENT_COMPONENT_SPACE,
+ 0, 0);
+ }
+
+ JPanel p = new JPanel();
+ p.setLayout( new BorderLayout() );
+ p.add( "Center", buttonPanel );
+ return p;
+ }
+
+ //===== COMBOBOX CREATION =======================
+
+ public static JComboBox makeJComboBox(ResourceBundle resource,
+ String panelName,
+ String keyword)
+ {
+ String value = null;
+ try {
+ value = resource.getString(panelName+"_COMBOBOX_"+keyword+"_DEFAULT");
+ } catch (MissingResourceException e) {
+ }
+ JComboBox jcb = new JComboBox();
+ String val = null;
+ int ii = 0;
+ do {
+ try {
+ val = resource.getString(panelName+"_COMBOBOX_"+keyword+"_VALUE_"+ii);
+ if (val != null) {
+ jcb.addItem(val);
+ }
+ ++ii;
+ } catch (MissingResourceException e) {
+ val = null;
+ }
+ } while (val != null);
+
+ if (value != null)
+ jcb.setSelectedItem(value);
+ return jcb;
+ }
+
+
+ //===== TOOL TIP CREATION =======================
+
+ /**
+ * Set tool tip on compoenent using resources passed in
+ */
+ public static void setToolTip(ResourceBundle resource,
+ String panelName,
+ String compKeyword,
+ JComponent w)
+ {
+ try {
+ String ttip = resource.getString(panelName+"_"+compKeyword+"_TTIP");
+ w.setToolTipText(ttip);
+ } catch (MissingResourceException e) {
+ //DON'T HAVE TOOT TIP
+ }
+ }
+
+ public static String[] randomize(String [] t) {
+ String[] s = new String[t.length];
+ System.arraycopy(t,0,s,0,t.length);
+ String[] result = new String[s.length];
+
+ int j=0;
+ java.util.Random r = new java.util.Random();
+
+ for (int i=0; i<s.length; i++) {
+ int x = r.nextInt();
+ if (x <0) x = -x;
+ int n = x % (s.length-i);
+ result[j] = s[n];
+ s[n] = s[s.length-i-1];
+ j++;
+ }
+ return result;
+ }
+
+ /**
+ * Sorts the array of strings using bubble sort.
+ * @param str The array of string being sorted. The str parameter contains
+ * the sorted result.
+ */
+ public static void bubbleSort(String[] str) {
+ for (int i = 0; i < str.length-1; i++) {
+ for (int j = i+1; j < str.length; j++) {
+ if( collator.compare(str[i], str[j]) > 0 ) {
+ String t = str[i];
+ str[i] = str[j];
+ str[j] = t;
+ }
+ }
+ }
+ }
+
+ public static void bubbleSort(String[] str, String[] data) {
+ for (int i = 0; i < str.length-1; i++) {
+ for (int j = i+1; j < str.length; j++) {
+ if( collator.compare(str[i], str[j]) > 0 ) {
+ String t = str[i];
+ str[i] = str[j];
+ str[j] = t;
+ String d = data[i];
+ data[i] = data[j];
+ data[j] = d;
+ }
+ }
+ }
+ }
+
+ public static void quickSort(String[] str, int low, int high) {
+ if (low >= high)
+ return;
+
+ String pivot = str[low];
+ int slow = low-1, shigh = high+1;
+
+ while (true) {
+ do
+ shigh--;
+ while (collator.compare(str[shigh], pivot) > 0);
+ do
+ slow++;
+ while (collator.compare(pivot, str[slow]) > 0);
+ if (slow >= shigh)
+ break;
+
+ String temp = str[slow];
+ str[slow] = str[shigh];
+ str[shigh] = temp;
+ }
+
+ quickSort (str, low, shigh);
+ quickSort (str, shigh+1, high);
+ }
+
+ public static void help(String token) {
+ Debug.println( "CMSAdminUtil.help: "+token);
+ new Help(mHelpResource).help(token);
+ }
+
+ //get localized string using the format
+ public static String getLocalizedString(ResourceBundle resource,
+ String keyword,
+ Object param) {
+ return MessageFormatter.getLocalizedString(resource.getClass().getName(),
+ keyword, param);
+ }
+
+ //get localized string using the format
+ public static String getLocalizedString(ResourceBundle resource,
+ String keyword,
+ Object [] params) {
+ return MessageFormatter.getLocalizedString(resource.getClass().getName(),
+ keyword, params);
+ }
+
+ public static String getPureString(String data) {
+ StringBuffer input = new StringBuffer(data);
+ StringBuffer buff = new StringBuffer();
+ for (int i=0; i< input.length(); i++) {
+ char c = input.charAt(i);
+ if ((c != '\n') && (c != '\r'))
+ buff.append(c);
+ }
+ return buff.toString();
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ /**
+ * This is not necessary any more, now that RemoteImage implements
+ * the code we used to have inside this method.
+ */
+ static RemoteImage getSystemImage( String imagePath ) {
+ return new RemoteImage( imagePath );
+ }
+
+ public static JTextArea createTextArea(String str, Color color) {
+ JTextArea desc = new JTextArea(str);
+ desc.setBackground(color);
+ desc.setEditable(false);
+ desc.setCaretColor(color);
+ desc.setLineWrap(true);
+ desc.setWrapStyleWord(true);
+
+ return desc;
+ }
+
+ public static long hexToLong(String s)
+ throws NumberFormatException {
+ int len = s.length();
+ double y = 0;
+ double base = 16;
+ long num = 0;
+
+ StringBuffer buffer = new StringBuffer(s);
+
+ for (int i=0; i<len; i++) {
+ char x = buffer.charAt(i);
+ if (x >= '0' && x <= '9') {
+ y = x-48;
+ } else if (x == 'a') {
+ y = 10;
+ } else if (x == 'b') {
+ y = 11;
+ } else if (x == 'c') {
+ y = 12;
+ } else if (x == 'd') {
+ y = 13;
+ } else if (x == 'e') {
+ y = 14;
+ } else if (x == 'f') {
+ y = 15;
+ } else {
+ num = -1;
+ break;
+ }
+ num = num+(long)(y*Math.pow(base, len-1-i));
+ }
+
+ return num;
+ }
+
+ public static Object createTableCell(String syntax, String syntaxVal, String v) {
+ if (syntax.equalsIgnoreCase("string") ||
+ syntax.equalsIgnoreCase("integer")) {
+ if (v == null) {
+ return new JTextField("");
+ } else {
+ return new JTextField(v);
+ }
+ } else if (syntax.equalsIgnoreCase("choice")) {
+ if (syntaxVal != null && syntaxVal.length() > 0) {
+ StringTokenizer st = new StringTokenizer(syntaxVal, ",");
+ int num = st.countTokens();
+ String[] item = new String[num];
+ int i=0;
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ // Fixes Bugscape Bug #56335: remove extraneous ';'
+ if( token.charAt(0) == ';' ) {
+ token = token.substring(1);
+ }
+ item[i++] = token;
+ }
+
+ CMSAdminUtil.bubbleSort(item);
+ JComboBox b = new JComboBox(item);
+
+ if (v != null && v.length() > 0)
+ b.setSelectedItem(v);
+ else
+ b.setSelectedIndex(0);
+ return b;
+ }
+ } else if (syntax.equalsIgnoreCase("boolean")) {
+ String[] item = {"true", "false"};
+ JComboBox b = new JComboBox(item);
+ if (v != null && v.equalsIgnoreCase("true")) {
+ b.setSelectedIndex(0);
+ } else {
+ b.setSelectedIndex(1);
+ }
+ return b;
+ }
+
+ return null;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSBaseMenuInfo.java b/base/console/src/com/netscape/admin/certsrv/CMSBaseMenuInfo.java
new file mode 100644
index 000000000..cb1909f22
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSBaseMenuInfo.java
@@ -0,0 +1,178 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv;
+
+import javax.swing.*;
+import javax.swing.tree.*;
+import javax.swing.event.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import java.util.*;
+
+/**
+ * This class represents the menu item selection and associated
+ * call back function.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv
+ */
+public class CMSBaseMenuInfo implements IMenuInfo {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ //framework level menu catagory ids
+ public static String MENU_FILE = Framework.MENU_FILE;
+ public static String MENU_VIEW = Framework.MENU_VIEW;
+ public static String MENU_OBJECT = ResourcePage.MENU_OBJECT;
+
+ //menu bar menu items
+ public static String MENU_KEYCERT = CMSAdminResources.MENU_KEYCERT;
+ public static String MENU_REFRESH = CMSAdminResources.MENU_REFRESH;
+ public static String MENU_KEYCERT_MANAGEMENT = CMSAdminResources.MENU_KEYCERT_MANAGEMENT;
+ public static String MENU_PKCS11 = CMSAdminResources.MENU_PKCS11;
+ public static String MENU_NEWCERT = CMSAdminResources.MENU_NEWCERT;
+
+ //context menu items
+
+
+ protected Vector mMenuCategoryIDs; //stores the ids
+ protected Vector mCategoryIDMenuItems; //stores the menu items associated
+ //with the specified id
+ protected Vector mMenuItemsIDs; //stores the item ids
+ protected Vector mActionListeners; //stores the action listeners
+
+ protected ResourceBundle mResource;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSBaseMenuInfo() {
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mMenuCategoryIDs = new Vector();
+ mCategoryIDMenuItems = new Vector();
+ mMenuItemsIDs = new Vector();
+ mActionListeners = new Vector();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Register menu items and associated action obejct
+ * @param id menu catagory ID
+ * @param item menu item
+ * @param action IMenuAction object
+ */
+ public void registerMenuItem(String id, String keyword, IMenuAction action) {
+ IMenuItem item = getMenuItemText(keyword);
+
+ //register menu item and action pair
+ int i = mMenuItemsIDs.indexOf(item.getID());
+ if (i == -1) {
+ mMenuItemsIDs.addElement(item.getID());
+ mActionListeners.addElement(action);
+ } else {
+ mActionListeners.setElementAt(action,i);
+ }
+
+ //register catgory id and associated menu items
+ i = mMenuCategoryIDs.indexOf(id);
+ if (i == -1) {
+ mMenuCategoryIDs.addElement(id);
+ mCategoryIDMenuItems.addElement(new Vector());
+ }
+ i = mMenuCategoryIDs.indexOf(id);
+ Vector items = (Vector) mCategoryIDMenuItems.elementAt(i);
+ items.addElement(item); //XXX check exist already ??
+ }
+
+ /**
+ * Add menu item separator
+ */
+ public void addMenuItemSeparator(String id) {
+ int i = mMenuCategoryIDs.indexOf(id);
+ if (i < 0 ) {
+ mMenuCategoryIDs.addElement(id);
+ Vector items = new Vector();
+ items.addElement(new MenuItemSeparator());
+ mCategoryIDMenuItems.addElement(items);
+ } else {
+ Vector items = (Vector) mCategoryIDMenuItems.elementAt(i);
+ items.addElement(new MenuItemSeparator());
+ }
+ }
+
+ /**
+ * Returns supported menu categories.
+ */
+ public String[] getMenuCategoryIDs() {
+ if (mMenuCategoryIDs.size() == 0) {
+ return null;
+ }
+ String[] id = new String[mMenuCategoryIDs.size()];
+ mMenuCategoryIDs.copyInto(id);
+ //for(int i=0; i< id.length; i++)
+ // System.out.println("ID: "+id[i]);
+ return id;
+ }
+
+ /**
+ * Returns menu items for a particular menu category.
+ */
+ public IMenuItem[] getMenuItems(String category) {
+ int i = mMenuCategoryIDs.indexOf(category);
+ if (i != -1) {
+ Vector v = (Vector) mCategoryIDMenuItems.elementAt(i);
+ IMenuItem[] items = new IMenuItem[v.size()];
+ v.copyInto(items);
+ //for(int j=0; j< items.length; j++)
+ // System.out.println("ITEM: "+items[j].getID());
+ return items;
+ }
+ return null;
+ }
+
+ /**
+ * Notification that a menu item has been selected.
+ */
+ public void actionMenuSelected(IPage viewInstance, IMenuItem item) {
+ int i = mMenuItemsIDs.indexOf(item.getID());
+ if (i == -1)
+ return;
+ IMenuAction act = (IMenuAction) mActionListeners.elementAt(i);
+ act.perform(viewInstance);
+ }
+
+ /*==========================================================
+ * priotected methods
+ *==========================================================*/
+
+ protected MenuItemText getMenuItemText(String keyword) {
+ String name = mResource.getString("GENERAL_MENU_"+keyword+"_LABEL");
+ if (name == null)
+ name = "Missing Label";
+ String desc = mResource.getString("GENERAL_MENU_"+keyword+"_DESC");
+ if (desc == null)
+ desc = " ";
+ return new MenuItemText( keyword, name, desc);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSBasePanel.java b/base/console/src/com/netscape/admin/certsrv/CMSBasePanel.java
new file mode 100644
index 000000000..3430a74d9
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSBasePanel.java
@@ -0,0 +1,460 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv;
+
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.border.*;
+import javax.swing.text.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+import java.util.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * Netscape Certificate Server 4.0 Default Base Panel
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class CMSBasePanel extends JPanel
+ implements ActionListener, DocumentListener,
+ ItemListener, ListSelectionListener
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static Insets DEFAULT_CENTER_INSETS = new Insets(0,0,0,0);
+ public static Insets EMPTY_INSETS = new Insets(0,0,0,0);
+ public static final int COMPONENT_SPACE = SuiLookAndFeel.COMPONENT_SPACE;
+ public static final int SEPARATED_COMPONENT_SPACE =
+ SuiLookAndFeel.SEPARATED_COMPONENT_SPACE;
+ public static final int DIFFERENT_COMPONENT_SPACE =
+ SuiLookAndFeel.DIFFERENT_COMPONENT_SPACE;
+
+ protected static final int WARNING_MESSAGE = JOptionPane.WARNING_MESSAGE;
+ protected static final int ERROR_MESSAGE = JOptionPane.ERROR_MESSAGE;
+ protected static final int INFORMATION_MESSAGE = JOptionPane.INFORMATION_MESSAGE;
+
+ protected String mPanelName; // panel name (UPPERCASE IDENTIFIER)
+ protected ResourceBundle mResource; // resource boundle
+ public static int mNonWaitCursor = -1;
+ public static Cursor mCursor = null;
+ protected JDialog mParent;
+ protected JFrame mAdminFrame;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSBasePanel(String panelName) {
+ this(panelName, ResourceBundle.getBundle(CMSAdminResources.class.getName()));
+ }
+
+ public CMSBasePanel(String panelName, ResourceBundle rb) {
+ super();
+ mPanelName = panelName;
+ mResource = rb;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Set Panel name
+ * @param name panel name
+ */
+ public void setPanelName(String name) {
+ mPanelName = name;
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ }
+
+ //== DocumentListener ==
+ public void insertUpdate(DocumentEvent e) {
+ }
+
+ public void removeUpdate(DocumentEvent e){
+ }
+
+ public void changedUpdate(DocumentEvent e){
+ }
+
+ //== ItemListener ==
+ public void itemStateChanged(ItemEvent e){
+ }
+
+ //== ListSelectionListener ==
+ public void valueChanged(ListSelectionEvent e){
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+
+ //create string using formated resource string
+ //the string format
+ protected String getLocalizedString(String keyword, Object param) {
+ return CMSAdminUtil.getLocalizedString(mResource, keyword, param);
+ }
+
+ protected String getLocalizedString(String keyword, Object [] params) {
+ return CMSAdminUtil.getLocalizedString(mResource, keyword, params);
+ }
+
+
+ //=== DIALOG MESSAGE =====================
+
+ protected void showMessageDialog(String keyword, int messageType ) {
+ CMSAdminUtil.showMessageDialog(mResource, mPanelName, keyword, messageType);
+ }
+
+ protected void showMessageDialog(String keyword) {
+ showMessageDialog(keyword, ERROR_MESSAGE);
+ }
+
+ protected int showConfirmDialog(String keyword, int messageType ) {
+ return CMSAdminUtil.showConfirmDialog(mResource, mPanelName, keyword, messageType);
+ }
+
+ protected int showConfirmDialog(String keyword, String[] params, int messageType ) {
+ return CMSAdminUtil.showConfirmDialog(mResource, mPanelName, keyword, params, messageType);
+ }
+
+ protected int showConfirmDialog(String keyword) {
+ return showConfirmDialog(keyword, WARNING_MESSAGE);
+ }
+
+ protected int showConfirmDialog(String keyword, String[] params) {
+ return showConfirmDialog(keyword, params, WARNING_MESSAGE);
+ }
+
+ /**
+ * Display Error Message dialog
+ *
+ * @param message - message to be displayed
+ */
+ protected void showErrorDialog(String message) {
+ CMSAdminUtil.showErrorDialog(mResource, message, ERROR_MESSAGE);
+ }
+
+ //=== TITLED BORDER ======================
+ protected Border makeTitledBorder(String keyword) {
+ String label;
+ try {
+ label = mResource.getString(mPanelName+"_BORDER_"+keyword+"_LABEL");
+ } catch (MissingResourceException e) {
+ label = "Missing Label";
+ }
+ TitledBorder border = BorderFactory.createTitledBorder(label);
+ Border margin = new EmptyBorder(-3,
+ 0,
+ DIFFERENT_COMPONENT_SPACE,
+ 0);
+ /*
+ Border margin = new EmptyBorder(0,
+ DIFFERENT_COMPONENT_SPACE-COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE-COMPONENT_SPACE);
+ */
+ return new CompoundBorder(border, margin);
+ }
+
+ //=== LABEL CREATION ====================
+ protected JLabel makeJLabel(Icon i, String s, int a) {
+ JLabel label = new JLabel();
+ if (i != null)
+ label.setIcon(i);
+ if (s != null)
+ label.setText(s);
+ if (a != -1)
+ label.setHorizontalAlignment(a);
+ return label;
+ }
+
+ protected JLabel makeJLabel() {
+ return makeJLabel((Icon)null, null, -1);
+ }
+
+ protected JLabel makeJLabel(String keyword) {
+ return makeJLabel(keyword, (Icon) null, -1);
+ }
+
+ protected JLabel makeJLabel(String keyword, Icon i, int a) {
+ return CMSAdminUtil.makeJLabel(mResource, mPanelName, keyword, i, a);
+ }
+
+ //===== TEXT FIELD CREATION ================
+ protected JTextField makeJTextField(Document d, String s, int len) {
+ return CMSAdminUtil.makeJTextField(d, s,len, this);
+ }
+
+ protected JTextField makeJTextField() {
+ return makeJTextField(null, null, -1);
+ }
+
+ protected JTextField makeJTextField(int len) {
+ return makeJTextField(null, null, len);
+ }
+
+ protected JTextField makeJTextField(String s) {
+ return makeJTextField(null, s, -1);
+ }
+
+ protected JTextField makeJTextField(String s, int len) {
+ return makeJTextField(null, s, len);
+ }
+
+ //==== PASSWORD FIELD CREATION ======================
+ protected JPasswordField makeJPasswordField() {
+ return makeJPasswordField(null, null, -1);
+ }
+
+ protected JPasswordField makeJPasswordField(Document d, String s, int len) {
+ return CMSAdminUtil.makeJPasswordField(d, s,len, this);
+ }
+
+ protected JPasswordField makeJPasswordField(int len) {
+ return makeJPasswordField(null, null, len);
+ }
+
+ protected JPasswordField makeJPasswordField(String s) {
+ return makeJPasswordField(null, s, -1);
+ }
+
+ protected JPasswordField makeJPasswordField(String s, int len) {
+ return makeJPasswordField(null, s, len);
+ }
+
+ //====== BUTTON CREATION ===========================
+ protected JButton makeJButton(Icon i, String s) {
+ JButton button = new JButton();
+ if (s != null)
+ button.setText(s);
+ if (i != null)
+ button.setIcon(i);
+
+ button.addActionListener(this);
+ return button;
+ }
+
+ protected JButton makeJButton() {
+ return makeJButton((Icon)null, null);
+ }
+
+ protected JButton makeJButton(Icon i) {
+ return makeJButton(i, null);
+ }
+
+ protected JButton makeJButton(String keyword) {
+ return makeJButton(keyword, (Icon)null);
+ }
+
+ protected JButton makeJButton(String keyword, ActionListener listener) {
+ return makeJButton(keyword, (Icon)null, listener);
+ }
+
+ protected JButton makeJButton(String keyword, Icon i) {
+ return makeJButton(keyword, i, this);
+ }
+
+ protected JButton makeJButton(String keyword, Icon i, ActionListener listener) {
+ return CMSAdminUtil.makeJButton(mResource, mPanelName, keyword, i, listener);
+ }
+
+ //===== CHECKBOX CREATION ========================
+ protected JCheckBox makeJCheckBox(Icon i, String s, boolean b) {
+ JCheckBox cb = new JCheckBox();
+ if (s != null)
+ cb.setText(s);
+ if (i != null)
+ cb.setIcon(i);
+ cb.setSelected(b);
+ cb.addActionListener(this);
+
+ return cb;
+ }
+
+ protected JCheckBox makeJCheckBox() {
+ return makeJCheckBox((Icon)null, null, false);
+ }
+
+ protected JCheckBox makeJCheckBox(Icon i) {
+ return makeJCheckBox(i, null, false);
+ }
+
+ protected JCheckBox makeJCheckBox(Icon i, boolean b) {
+ return makeJCheckBox(i, null, b);
+ }
+
+ protected JCheckBox makeJCheckBox(String keyword) {
+ return makeJCheckBox(keyword, (Icon)null, false);
+ }
+
+ protected JCheckBox makeJCheckBox(String keyword, boolean b) {
+ return makeJCheckBox(keyword, (Icon)null, b);
+ }
+
+ protected JCheckBox makeJCheckBox(String keyword, Icon i) {
+ return makeJCheckBox(keyword, i, false);
+ }
+
+ protected JCheckBox makeJCheckBox(String keyword, Icon i, boolean val) {
+ return CMSAdminUtil.makeJCheckBox(mResource, mPanelName, keyword, i, val, this);
+ }
+
+ //====== COMBOBOX CREATION ==========================
+ protected JComboBox makeJComboBox(ComboBoxModel cbm) {
+ JComboBox cb = new JComboBox();
+ if (cbm != null)
+ cb.setModel(cbm);
+ cb.addItemListener(this);
+ return cb;
+ }
+
+ protected JComboBox makeJComboBox() {
+ return makeJComboBox((ComboBoxModel)null);
+ }
+
+ protected JComboBox makeJComboBox(String keyword) {
+ String value = null;
+ try {
+ value = mResource.getString(mPanelName+"_COMBOBOX_"+keyword+"_DEFAULT");
+ } catch (MissingResourceException e) {
+ }
+ JComboBox jcb = makeJComboBox((ComboBoxModel)null);
+ String val = null;
+ int ii = 0;
+ do {
+ try {
+ val = mResource.getString(mPanelName+"_COMBOBOX_"+keyword+"_VALUE_"+ii);
+ if (val != null) {
+ jcb.addItem(val);
+ }
+ ++ii;
+ } catch (MissingResourceException e) {
+ val = null;
+ }
+ } while (val != null);
+
+ if (value != null)
+ jcb.setSelectedItem(value);
+ return jcb;
+ }
+
+
+ //==== LIST CREATION ============================
+
+ protected JList makeJList(DefaultListModel listModel, int visibleCount) {
+ return CMSAdminUtil.makeJList(listModel, visibleCount);
+ }
+
+ //===== RADIO BUTTON CREATION =======================
+ protected JRadioButton makeJRadioButton(Icon i, String s, boolean b) {
+ JRadioButton rb = new JRadioButton();
+ if (s != null)
+ rb.setText(s);
+ if (i != null)
+ rb.setIcon(i);
+ rb.setSelected(b);
+ rb.addActionListener(this);
+
+ return rb;
+ }
+
+ protected JRadioButton makeJRadioButton() {
+ return makeJRadioButton((Icon)null, null, false);
+ }
+
+ protected JRadioButton makeJRadioButton(Icon i) {
+ return makeJRadioButton(i, null, false);
+ }
+
+ protected JRadioButton makeJRadioButton(Icon i, boolean b) {
+ return makeJRadioButton(i, null, b);
+ }
+
+ protected JRadioButton makeJRadioButton(String keyword) {
+ return makeJRadioButton(keyword, (Icon)null, false);
+ }
+
+ protected JRadioButton makeJRadioButton(String keyword, boolean b) {
+ return makeJRadioButton(keyword, (Icon)null, b);
+ }
+
+ protected JRadioButton makeJRadioButton(String keyword, Icon i, boolean b) {
+ return CMSAdminUtil.makeJRadioButton(mResource, mPanelName, keyword, i, b, this);
+ }
+
+ /**
+ * Create a panel with horizontally arranged, equally sized buttons
+ * The buttons are aligned to the right in the panel (if it is
+ * stretched beyond the length of the buttons)
+ *
+ * @param buttons An array of buttons for the panel
+ *
+ * @return A panel containing the buttons
+ */
+ public static JPanel makeJButtonPanel( JButton[] buttons ) {
+ return CMSAdminUtil.makeJButtonPanel(buttons);
+ }
+
+ public static JPanel makeJButtonPanel( JButton[] buttons, boolean isHelp) {
+ return CMSAdminUtil.makeJButtonPanel(buttons, isHelp);
+ }
+
+ public static JPanel makeJButtonPanel( JButton[] buttons, boolean isHelp, boolean isConfig) {
+ return CMSAdminUtil.makeJButtonPanel(buttons, isHelp, isConfig);
+ }
+
+ protected void startProgressStatus() {
+ if (mNonWaitCursor == -1) {
+ mCursor = mParent.getCursor();
+ mNonWaitCursor = mCursor.getType();
+ }
+ mCursor = new Cursor(Cursor.WAIT_CURSOR);
+ mParent.setCursor(mCursor);
+ if (mAdminFrame != null)
+ mAdminFrame.setCursor(mCursor);
+ //UtilConsoleGlobals.getActivatedFrame().setCursor(mCursor);
+ }
+
+ protected void endProgressStatus() {
+ if (mNonWaitCursor == -1)
+ mNonWaitCursor = 0;
+ mCursor = new Cursor(mNonWaitCursor);
+ mParent.setCursor(mCursor);
+ if (mAdminFrame != null)
+ mAdminFrame.setCursor(mCursor);
+ //UtilConsoleGlobals.getActivatedFrame().setCursor(mCursor);
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+ private void setToolTip(String compKeyword, JComponent w) {
+ CMSAdminUtil.setToolTip(mResource, mPanelName, compKeyword, w);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSBaseResourceModel.java b/base/console/src/com/netscape/admin/certsrv/CMSBaseResourceModel.java
new file mode 100644
index 000000000..b7ec04e3a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSBaseResourceModel.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.admin.certsrv;
+
+import java.util.*;
+import java.io.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.client.console.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.menu.*;
+
+/**
+ * Netscape Certificate Server 4.0 BASE resource model.<br>
+ *
+ * This class represtents the tree node objects displayed
+ * in the right tree-view.<p>
+ *
+ * Menu Event are now handled by extenal IMenuInfo object.
+ *
+ * @author Jack Pan-Chen
+ * @author Thomas Kwan
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv
+ */
+public class CMSBaseResourceModel extends ResourceModel {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+
+ private CMSResourcePage mPage; // physical page representation
+ protected ConsoleInfo mConsoleInfo; // console info
+ protected CMSServerInfo mServerInfo; // server info
+ protected IResourceObject[] mSelection; // selected objects
+ protected Vector mSelectionListeners; // listener list
+ protected ResourceBundle mResource; // resource boundle
+ protected Hashtable mNickNameRegistry; // storing the obejct nickname pair
+ protected RefreshTabPane mRefreshPane;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ /**
+ * Constructor - create all panels.
+ *
+ * @param info Global console connection information
+ * @param serverInfo Server instance connection information
+ */
+ public CMSBaseResourceModel( ConsoleInfo info, CMSServerInfo serverInfo ) {
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mConsoleInfo = info;
+ mServerInfo = serverInfo;
+ mNickNameRegistry = new Hashtable();
+ mSelectionListeners = new Vector();
+ init();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Set the physical page associated with this model
+ * @param page CMSResourcePage instance
+ */
+ public void setResourcePage(CMSResourcePage page) {
+ mPage = page;
+ }
+
+ public CMSResourcePage getResourcePage() {
+ return mPage;
+ }
+
+ /**
+ * Return the global console information reference.
+ *
+ * @return The global console information reference.
+ **/
+ public ConsoleInfo getConsoleInfo() {
+ return mConsoleInfo;
+ }
+
+ /**
+ * Return the Server information reference.
+ *
+ * @return The server information reference.
+ **/
+ public CMSServerInfo getServerInfo() {
+ return mServerInfo;
+ }
+
+
+ /**
+ * Get Parent Frame
+ * @return frame to be usd in dialogs
+ */
+ public JFrame getFrame() {
+ return UtilConsoleGlobals.getActivatedFrame();
+ }
+
+ /**
+ * Tree Nodes selected call back
+ */
+ public void actionObjectSelected( IPage viewInstance,
+ IResourceObject[] selection,
+ IResourceObject[] previousSelection) {
+
+ //Debug.println("CMSResourceModel: actionObjectSelected()");
+ mSelection = selection;
+ if ( mSelection == null )
+ mSelection = new IResourceObject[0];
+ Vector selected = new Vector();
+ Vector toNotify = new Vector();
+ /* Signal all selected objects, keep track of which ones */
+ for( int i = 0; i < mSelection.length; i++ ) {
+ IResourceObject sel = mSelection[i];
+ Component c = sel.getCustomPanel();
+ if (mRefreshPane != null) {
+ mRefreshPane.select(c);
+ }
+ if ( (c != null) && (mSelectionListeners.indexOf( c ) >= 0) ) {
+ toNotify.addElement( sel );
+ }
+ selected.addElement( c );
+ }
+
+ /* All other listeners must be unselected */
+ boolean canMove = true;
+ if ( previousSelection != null ) {
+ for( int i = 0; i < previousSelection.length; i++ ) {
+ IResourceObject sel = previousSelection[i];
+ Component c = sel.getCustomPanel();
+ if ( (mSelectionListeners.indexOf( c ) >= 0) &&
+ (selected.indexOf( c ) < 0) ) {
+ try {
+ IResourceSelectionListener l =
+ (IResourceSelectionListener)c;
+ if (!l.unselect( sel, viewInstance ))
+ canMove = false;
+ } catch ( Exception e ) {
+ //System.err.println( e );
+ Debug.println( e.toString() );
+ }
+ }
+ }
+ }
+
+ if (!canMove)
+ return;
+
+ for( int i = 0; i < toNotify.size(); i++ ) {
+ IResourceObject sel =
+ (IResourceObject)toNotify.elementAt( i );
+ Component c = sel.getCustomPanel();
+ IResourceSelectionListener l =
+ (IResourceSelectionListener)c;
+ l.select( sel, viewInstance );
+ }
+
+ //change menu
+ super.actionObjectSelected(viewInstance, selection, previousSelection);
+ }
+
+ public void setRefreshCallback(RefreshTabPane pane) {
+ mRefreshPane = pane;
+ }
+
+ /**
+ * Adds a listener that is interested in receiving selection events.
+ * Called by panels
+ */
+ public void addIResourceSelectionListener(IResourceSelectionListener l) {
+ mSelectionListeners.addElement(l);
+ }
+
+ /**
+ * Removes previously added IDSResourceSelectionListener.
+ * Called by panels
+ */
+ public void removeIResourceSelectionListener(IResourceSelectionListener l) {
+ mSelectionListeners.removeElement(l);
+ }
+
+ /**
+ * Returns list of listeners for this model.
+ */
+ public Enumeration getSelectionListeners() {
+ return mSelectionListeners.elements();
+ }
+
+ /**
+ * The SubSystemUILoader should use this function to add
+ * subsystem node into the root node. SubSystemLoader is responsible
+ * for setting up the subtrees.
+ */
+ public void addSubSystemNode(CMSResourceObject node) {
+ ((CMSResourceObject)getRoot()).add(node);
+ }
+
+ /**
+ * Register the nick name of the resource object, so other sub system
+ * can look up and retrieve the corresponding resource object.
+ */
+ public void registerNickName(String nickName, CMSResourceObject node) {
+ mNickNameRegistry.put(nickName, node);
+ }
+
+ /**
+ * Retrieve the resource obejct associated with this nickname
+ */
+ public CMSResourceObject getByNickName(String nickName) {
+ return (CMSResourceObject) mNickNameRegistry.get(nickName);
+ }
+
+ /**
+ * Start the zipping status bar
+ */
+ public void progressStart() {
+ mPage.progressStart();
+ }
+
+ /**
+ * Stop the zipping status bar
+ */
+ public void progressStop() {
+ mPage.progressStop();
+ }
+
+ /*==========================================================
+ * priotected methods
+ *==========================================================*/
+
+ protected void init() {
+ CMSResourceObject root = new CMSResourceObject();
+ root.setName(mResource.getString(CMSAdminResources.CERT_SERVER_NAME)+":" + mServerInfo.getPort());
+ root.setCustomPanel( new CMSBlankPanel(this));
+ root.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_CERTICON_SMALL));
+ root.setAllowsChildren(true);
+ super.setRoot( root );
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSCAUILoader.java b/base/console/src/com/netscape/admin/certsrv/CMSCAUILoader.java
new file mode 100644
index 000000000..f967d28e0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSCAUILoader.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.admin.certsrv;
+
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.ug.*;
+import com.netscape.admin.certsrv.menu.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.notification.*;
+import java.util.*;
+
+/**
+ * Netscape Certificate Server 4.0 Certificate Authority UI Loader.
+ *
+ * This class is responsible for the loading of UI components associated with
+ * the ca functionality.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @date 03/30/97
+ */
+public class CMSCAUILoader implements ISubSystemUILoader {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private CMSUIFramework mUIFramework; //parent framework
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSCAUILoader(CMSUIFramework framework) {
+ mUIFramework = framework;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void register() {
+ //register subsystem UI
+ try {
+
+ //task tab
+ IPage task = mUIFramework.getPage(CMSPageFeeder.TASK_TAB_TYPE,"");
+
+ //config tab
+ CMSResourcePage page = (CMSResourcePage) mUIFramework.getPage(CMSPageFeeder.RESOURCE_TAB_TYPE,"CONFIGURATION");
+ CMSBaseResourceModel model = (CMSBaseResourceModel) page.getModel();
+ model.setResourcePage(page);
+ populateConfigContent(model);
+
+ /*repos tab
+ page = (CMSResourcePage) mUIFramework.getPage(CMSPageFeeder.RESOURCE_TAB_TYPE,"CONTENT");
+ model = (CMSBaseResourceModel) page.getModel();
+ populateRepositoryContent(model);
+ populateRepositoryMenu(page);
+ */
+
+ /*acl tab
+ page = (CMSResourcePage) mUIFramework.getPage(CMSPageFeeder.RESOURCE_TAB_TYPE,"ACCESSCONTROLLIST");
+ model = (CMSBaseResourceModel) page.getModel();
+ populateACLContent(model);
+ */
+
+ }catch(Exception e) {
+ Debug.println("CMSCAUILoader: register() config - "+e.toString());
+ }
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+ protected void populateConfigContent(CMSBaseResourceModel model) {
+ CMSResourceObject list, node;
+ CMSTabPanel tabPane;
+
+ CMSResourceObject authnode = new CMSResourceObject("AUTH");
+ CMSUGTabPanel tabPane1 = new CMSUGTabPanel(model, authnode);
+ tabPane1.addTab(new AuthInstanceTab(model));
+ tabPane1.addTab(new AuthImplTab(model));
+ authnode.setCustomPanel(tabPane1);
+ authnode.setIcon( CMSAdminUtil.getImage(
+ CMSAdminResources.IMAGE_AUTHOBJECT));
+ authnode.setAllowsChildren(false);
+ model.addSubSystemNode(authnode);
+
+ // jobs scheduler node
+ CMSResourceObject jobsnode = new CMSResourceObject("JOBSCHED");
+ tabPane = new CMSTabPanel(model, jobsnode);
+ tabPane.addTab(new JobsSettingPanel("JOBSGENERAL", tabPane));
+
+ jobsnode.setCustomPanel(tabPane);
+ jobsnode.setIcon( CMSAdminUtil.getImage(
+ CMSAdminResources.IMAGE_JOBSOBJECT));
+
+ jobsnode.setAllowsChildren(true);
+ CMSResourceObject cnode = new CMSResourceObject("JOBS");
+
+ tabPane1 = new CMSUGTabPanel(model, cnode);
+ tabPane1.addTab(new JobsInstanceTab(model));
+ tabPane1.addTab(new JobsImplTab(model));
+ cnode.setCustomPanel(tabPane1);
+ cnode.setIcon( CMSAdminUtil.getImage(
+ CMSAdminResources.IMAGE_JOBSOBJECT));
+ jobsnode.add(cnode);
+ cnode.setAllowsChildren(false);
+ model.addSubSystemNode(jobsnode);
+
+ //ca node
+ list = new CMSResourceObject("CACONFIG");
+ tabPane = new CMSTabPanel(model, list);
+ tabPane.addTab(new CMSCAGeneralPanel(tabPane));
+ //tabPane.addTab(new CMSCRLSettingPanel(tabPane));
+ tabPane.addTab(new CMSCAConnectorPanel(model,tabPane));
+ //tabPane.addTab(new CMSCACLMPanel(tabPane));
+ list.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_FOLDER));
+ list.setAllowsChildren(true);
+ list.setCustomPanel(tabPane);
+
+ //policies sub node
+ //CMSResourceObject node2;
+ node = new CMSResourceObject("POLICIES");
+ CMSUGTabPanel tabPane2 = new CMSUGTabPanel(model, node);
+ tabPane2.addTab(new PolicyInstanceTab(model, DestDef.DEST_CA_POLICY_ADMIN));
+ tabPane2.addTab(new PolicyImplTab(model, DestDef.DEST_CA_POLICY_ADMIN));
+ node.setCustomPanel(tabPane2);
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULEOBJECT));
+ node.setAllowsChildren(false);
+ //list.add(node);
+
+ // profiles
+ node = new CMSResourceObject("PROFILES");
+ CMSUGTabPanel tabPane3 = new CMSUGTabPanel(model, node);
+ tabPane3.addTab(new ProfileInstanceTab(model, DestDef.DEST_CA_PROFILE_ADMIN));
+ tabPane3.addTab(new ProfileImplTab(model, DestDef.DEST_REGISTRY_ADMIN));
+ node.setCustomPanel(tabPane3);
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULEOBJECT));
+ node.setAllowsChildren(false);
+ list.add(node);
+
+
+ // notification
+ CMSResourceObject notificationNode = new CMSResourceObject("NOTIFICATION");
+ tabPane = new CMSTabPanel(model, notificationNode);
+ tabPane.addTab(new RequestCompletePanel("NOTIFYREQCOMPLETE",
+ tabPane,
+ DestDef.DEST_CA_ADMIN));
+ tabPane.addTab(new RequestRevokedPanel("NOTIFYREVCOMPLETE",
+ tabPane,
+ DestDef.DEST_CA_ADMIN));
+ tabPane.addTab(new RequestInQPanel("NOTIFYREQINQ", tabPane,
+ DestDef.DEST_CA_ADMIN));
+
+ notificationNode.setCustomPanel(tabPane);
+ notificationNode.setIcon( CMSAdminUtil.getImage(
+ CMSAdminResources.IMAGE_JOBSOBJECT));
+
+ notificationNode.setAllowsChildren(false);
+ list.add(notificationNode);
+
+
+ /* servlet sub node - XXX NOT FOR B1
+ Servlet Instance Tab code is under config/servlet. It has
+ been 'cvs removed'. It needs porting to new UI.
+ CMSResourceObject node3;
+ node3 = new CMSResourceObject("SERVLET");
+ CMSUGTabPanel tabPane3 = new CMSUGTabPanel(model, node3);
+ tabPane3.addTab(new ServletInstanceTab(model,
+ DestDef.DEST_CA_SERVLET_ADMIN));
+ tabPane3.addTab(new ServletImplTab(model,
+ DestDef.DEST_CA_SERVLET_ADMIN));
+ node3.setCustomPanel(tabPane3);
+ node3.setIcon(CMSAdminUtil.getImage(CMSAdminResources.IMAGE_SERVLETOBJECT));
+ node3.setAllowsChildren(false);
+ list.add(node3);
+ */
+
+ /*extensions sub node
+ node = new CMSResourceObject("EXTENSIONS");
+ tabPane = new CMSTabPanel(model, node);
+ tabPane.addTab(new CMSBlankPanel(model,tabPane,"Configuration"));
+ tabPane.addTab(new CMSBlankPanel(model,tabPane,"Registration"));
+ node.setCustomPanel(tabPane);
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_PLUGIN));
+ node.setAllowsChildren(false);
+ list.add(node);
+ */
+
+ /* crl extensions sub node
+ node = new CMSResourceObject("CRLEXTENSIONS");
+ CMSUGTabPanel crlExtTabPane = new CMSUGTabPanel(model, node);
+ crlExtTabPane.addTab(new CRLExtensionsInstanceTab(model, DestDef.DEST_CA_ADMIN));
+ node.setCustomPanel(crlExtTabPane);
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULEOBJECT));
+ node.setAllowsChildren(false);
+ list.add(node);
+ */
+
+ // crl issuing points
+ node = new CMSResourceObject("CRLIPS");
+ CMSTabPanel crlIPsTabPane = new CMSTabPanel(model, node);
+ crlIPsTabPane.addTab(new CMSCRLIPPanel(model, crlIPsTabPane));
+ node.setCustomPanel(crlIPsTabPane);
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULEOBJECT));
+ node.setAllowsChildren(true);
+ list.add(node);
+
+ CMSResourceObject crlsNode = node;
+ AdminConnection ac = model.getServerInfo().getAdmin();
+ NameValuePairs nvps = null;
+ try {
+ nvps = ac.search(DestDef.DEST_CA_ADMIN, ScopeDef.SC_CRLIPS,
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ }
+
+ if (nvps != null && nvps.size() > 0) {
+ for (String name : nvps.keySet()) {
+ if (name.indexOf('.') == -1) {
+ node = new CMSResourceObject();
+ node.setName(name);
+ CMSTabPanel crlIPTabPane = new CMSTabPanel(model, node);
+ crlIPTabPane.addTab(new CMSCRLSettingPanel(crlIPTabPane, name));
+ crlIPTabPane.addTab(new CMSCRLCachePanel(crlIPTabPane, name));
+ crlIPTabPane.addTab(new CMSCRLFormatPanel(crlIPTabPane, name));
+ node.setCustomPanel(crlIPTabPane);
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULEOBJECT));
+ node.setAllowsChildren(true);
+ crlsNode.add(node);
+
+ CMSResourceObject crlNode = node;
+
+ node = new CMSResourceObject("CRLEXTENSIONS");
+ CMSUGTabPanel crlExtTabPane1 = new CMSUGTabPanel(model, node);
+ crlExtTabPane1.addTab(new CRLExtensionsInstanceTab(model, DestDef.DEST_CA_ADMIN, name));
+ node.setCustomPanel(crlExtTabPane1);
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULEOBJECT));
+ node.setAllowsChildren(false);
+ crlNode.add(node);
+ }
+ }
+ }
+
+ /*backup restore sub node
+ node = new CMSResourceObject("BACKUP");
+ tabPane = new CMSTabPanel(model, node);
+ tabPane.addTab(new CMSBlankPanel(model,tabPane,"Backup"));
+ tabPane.addTab(new CMSBlankPanel(model,tabPane,"Restore"));
+ node.setCustomPanel(tabPane);
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_BACKUPFOLDER));
+ node.setAllowsChildren(false);
+ list.add(node);
+ */
+
+ //ldap publishing
+ node = new CMSResourceObject("PUBLISHING");
+ tabPane = new CMSTabPanel(model, node);
+ tabPane.addTab(new CMSCALDAPPanel(tabPane));
+ // tabPane.addTab(new CMSCACertSettingPanel(tabPane));
+ // tabPane.addTab(new CMSUserCertSettingPanel("CAUSERCERTSETTING", tabPane));
+ node.setCustomPanel(tabPane);
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_LDAPPUB));
+ node.setAllowsChildren(true);
+ list.add(node);
+
+ CMSResourceObject publishingNode = node;
+
+ // allow mappers
+ node = new CMSResourceObject("MAPPERS");
+ CMSUGTabPanel ugtabPane = new CMSUGTabPanel(model, node);
+ ugtabPane.addTab(new MapperInstanceTab(model,
+ DestDef.DEST_CA_PUBLISHER_ADMIN));
+ ugtabPane.addTab(new MapperImplTab(model,
+ DestDef.DEST_CA_PUBLISHER_ADMIN));
+ node.setCustomPanel(ugtabPane);
+ node.setIcon(CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULEOBJECT));
+ node.setAllowsChildren(false);
+ publishingNode.add(node);
+
+ // allow LDAP publisher and mapper plugins
+ node = new CMSResourceObject("PUBLISHERS");
+ ugtabPane = new CMSUGTabPanel(model, node);
+ ugtabPane.addTab(new PublisherInstanceTab(model,
+ DestDef.DEST_CA_PUBLISHER_ADMIN));
+ ugtabPane.addTab(new PublisherImplTab(model,
+ DestDef.DEST_CA_PUBLISHER_ADMIN));
+ node.setCustomPanel(ugtabPane);
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULEOBJECT));
+ node.setAllowsChildren(false);
+ publishingNode.add(node);
+
+ // allow rules
+ node = new CMSResourceObject("RULES");
+ ugtabPane = new CMSUGTabPanel(model, node);
+ ugtabPane.addTab(new RuleInstanceTab(model,
+ DestDef.DEST_CA_PUBLISHER_ADMIN));
+ // XXX just support one publishing rule type
+ // ugtabPane.addTab(new RuleImplTab(model,
+ // DestDef.DEST_CA_PUBLISHER_ADMIN));
+ node.setCustomPanel(ugtabPane);
+ node.setIcon(CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULEOBJECT));
+ node.setAllowsChildren(false);
+ publishingNode.add(node);
+
+
+ model.addSubSystemNode(list);
+ }
+
+ /*
+ protected void populateRepositoryContent(CMSBaseResourceModel model) {
+ CMSResourceObject list, node;
+
+ //ca repositories node
+ list = new CMSResourceObject("CAREPOSITORIES");
+ list.setCustomPanel(new CMSBlankPanel(model));
+ list.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_DBCONATINER));
+ list.setAllowsChildren(true);
+ node = new CMSResourceObject("CAREQUESTS");
+ node.setCustomPanel(new CertificateRequestPanel(model, node));
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_DBOBJECT));
+ node.setAllowsChildren(false);
+ list.add(node);
+ node = new CMSResourceObject("CACERTIFICATE");
+ node.setCustomPanel(new CertificateRepositoryPanel(model,node));
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_DBOBJECT));
+ node.setAllowsChildren(false);
+ list.add(node);
+ model.addSubSystemNode(list);
+ }
+
+ protected void populateRepositoryMenu(CMSResourcePage page) {
+ CMSBaseResourceModel model = (CMSBaseResourceModel) page.getModel();
+ CMSBaseMenuInfo menuInfo = (CMSBaseMenuInfo)page.getMenuInfo();
+ try {
+ menuInfo.registerMenuItem(CMSBaseMenuInfo.MENU_FILE,
+ CMSBaseMenuInfo.MENU_NEWCERT,
+ new CertRequestAction(model.getConsoleInfo(),model.getServerInfo()));
+ } catch(Exception e) {
+ Debug.println("menuinfo register()"+e.toString());
+ }
+ }
+ */
+ protected void populateACLContent(CMSBaseResourceModel model) {
+ /*
+ CMSResourceObject list, node;
+ list = model.getByNickName("ACL");
+ node = new CMSResourceObject("CAACL");
+ node.setCustomPanel(new CMSBlankPanel(model));
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_DOCUMENT));
+ node.setAllowsChildren(false);
+ list.add(node);
+ */
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSCCMUILoader.java b/base/console/src/com/netscape/admin/certsrv/CMSCCMUILoader.java
new file mode 100644
index 000000000..785514ac2
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSCCMUILoader.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.admin.certsrv;
+
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.ug.*;
+
+
+/**
+ * Netscape Certificate Server 4.0 CCM UI Loader.
+ *
+ * This class is responsible for the loading of UI components associated with
+ * the ccm functionality.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @date 03/30/97
+ */
+public class CMSCCMUILoader implements ISubSystemUILoader {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private CMSUIFramework mUIFramework; //parent framework
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSCCMUILoader(CMSUIFramework framework) {
+ mUIFramework = framework;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void register() {
+ //register subsystem UI
+ try {
+
+ //task tab
+ IPage task = mUIFramework.getPage(CMSPageFeeder.TASK_TAB_TYPE,"");
+
+ //config tab
+ CMSResourcePage page = (CMSResourcePage) mUIFramework.getPage(CMSPageFeeder.RESOURCE_TAB_TYPE,"CONFIGURATION");
+ CMSBaseResourceModel model = (CMSBaseResourceModel) page.getModel();
+ populateConfigContent(model);
+
+ /*acl tab
+ page = (CMSResourcePage) mUIFramework.getPage(CMSPageFeeder.RESOURCE_TAB_TYPE,"ACCESSCONTROLLIST");
+ model = (CMSBaseResourceModel) page.getModel();
+ populateACLContent(model);
+ */
+
+ }catch(Exception e) {
+ Debug.println("CMSCCMUILoader: register() config - "+e.toString());
+ }
+
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+ protected void populateConfigContent(CMSBaseResourceModel model) {
+ CMSResourceObject node;
+ CMSTabPanel tabPane;
+
+ //ccm node
+ node = new CMSResourceObject("CCMCONFIG");
+ tabPane = new CMSTabPanel(model, node);
+ tabPane.addTab(new CMSBlankPanel(model,tabPane,"Service Ports"));
+ tabPane.addTab(new CMSBlankPanel(model,tabPane,"Password Distribution"));
+ node.setCustomPanel(tabPane);
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_FOLDER));
+ node.setAllowsChildren(true);
+
+ model.addSubSystemNode(node);
+ }
+
+ /*
+ protected void populateACLContent(CMSBaseResourceModel model) {
+ CMSResourceObject list, node;
+ list = model.getByNickName("ACL");
+ node = new CMSResourceObject("CCMACL");
+ node.setCustomPanel(new CMSBlankPanel(model));
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_DOCUMENT));
+ node.setAllowsChildren(false);
+ list.add(node);
+ }
+ */
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSContentTableModel.java b/base/console/src/com/netscape/admin/certsrv/CMSContentTableModel.java
new file mode 100644
index 000000000..15bc29665
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSContentTableModel.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.admin.certsrv;
+
+import java.util.*;
+import javax.swing.table.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.client.logging.*;
+
+/**
+ * Generic base class for the JTable data container that will
+ * CACHE the data object retrieved.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv
+ * @see javax.swing.table.AbstractTableModel
+ */
+public class CMSContentTableModel extends CMSTableModel {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ protected Vector mObjectContainer = new Vector(); // object container
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSContentTableModel() {
+ super();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Returns the number of rows in the table
+ * @return number of rows
+ */
+ public int getRowCount() {
+ return mObjectContainer.size();
+ }
+
+ /**
+ * Add data row and data object associated with this row
+ * @param values row values for the table
+ * @param obj data object
+ */
+ public void addRow(Vector values, Object obj) {
+ super.addRow(values);
+ mObjectContainer.addElement(obj);
+ }
+
+ /**
+ * Remove row at the specified index position
+ * @param index row index to be removed
+ */
+ public void removeRow(int index)
+ throws ArrayIndexOutOfBoundsException
+ {
+ Debug.println("CMSContentDataModel: removeRow() - start");
+ mObjectContainer.removeElementAt(index);
+ super.removeRow(index);
+ Debug.println("CMSContentDataModel: removeRow() - end");
+ }
+
+ /**
+ * clean up the table including the datat objects
+ */
+ public void removeAllRows() {
+ super.removeAllRows();
+ mObjectContainer.removeAllElements();
+ }
+
+ /**
+ * retrieve data object associated with specified row
+ * @param row table row number
+ * @return data object
+ */
+ public Object getObjectValueAt(int row) {
+ return mObjectContainer.elementAt(row);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSEAUILoader.java b/base/console/src/com/netscape/admin/certsrv/CMSEAUILoader.java
new file mode 100644
index 000000000..9c3ae6e01
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSEAUILoader.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.admin.certsrv;
+
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.ug.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.notification.*;
+
+/**
+ * Netscape Certificate Server 4.0 Escrow Authority UI Loader.
+ *
+ * This class is responsible for the loading of UI components associated with
+ * the ea functionality.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @date 03/30/97
+ */
+public class CMSEAUILoader implements ISubSystemUILoader {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private CMSUIFramework mUIFramework; //parent framework
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSEAUILoader(CMSUIFramework framework) {
+ mUIFramework = framework;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void register() {
+ //register subsystem UI
+ try {
+
+ //task tab
+ IPage task = mUIFramework.getPage(CMSPageFeeder.TASK_TAB_TYPE,"");
+
+ //config tab
+ CMSResourcePage page = (CMSResourcePage) mUIFramework.getPage(CMSPageFeeder.RESOURCE_TAB_TYPE,"CONFIGURATION");
+ CMSBaseResourceModel model = (CMSBaseResourceModel) page.getModel();
+ populateConfigContent(model);
+
+ /*repos tab
+ page = (CMSResourcePage) mUIFramework.getPage(CMSPageFeeder.RESOURCE_TAB_TYPE,"CONTENT");
+ model = (CMSBaseResourceModel) page.getModel();
+ populateRepositoryContent(model);
+ */
+
+ /*acl tab
+ page = (CMSResourcePage) mUIFramework.getPage(CMSPageFeeder.RESOURCE_TAB_TYPE,"ACCESSCONTROLLIST");
+ model = (CMSBaseResourceModel) page.getModel();
+ populateACLContent(model);
+ */
+
+ }catch(Exception e) {
+ Debug.println("CMSEAUILoader: register() config - "+e.toString());
+ }
+
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+ protected void populateConfigContent(CMSBaseResourceModel model) {
+ CMSResourceObject list, node;
+ CMSTabPanel tabPane;
+
+ //ca node
+ list = new CMSResourceObject("EACONFIG");
+ tabPane = new CMSTabPanel(model, list);
+ tabPane.addTab(new CMSEAGeneralPanel(tabPane));
+ list.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_FOLDER));
+ list.setAllowsChildren(false);
+ list.setCustomPanel(tabPane);
+
+ model.addSubSystemNode(list);
+ }
+
+ /*
+ protected void populateRepositoryContent(CMSBaseResourceModel model) {
+ CMSResourceObject list, node;
+
+ //ca repositories node
+ list = new CMSResourceObject("EAREPOSITORIES");
+ list.setCustomPanel(new CMSBlankPanel(model));
+ list.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_DBCONATINER));
+ list.setAllowsChildren(true);
+ node = new CMSResourceObject("EAREQUESTS");
+ node.setCustomPanel(new KeyRequestPanel(model, node));
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_DBOBJECT));
+ node.setAllowsChildren(false);
+ list.add(node);
+ node = new CMSResourceObject("EAKEY");
+ node.setCustomPanel(new KeyRepositoryPanel(model, node));
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_DBOBJECT));
+ node.setAllowsChildren(false);
+ list.add(node);
+ model.addSubSystemNode(list);
+ }
+ */
+ /*
+ protected void populateACLContent(CMSBaseResourceModel model) {
+ CMSResourceObject list, node;
+ list = model.getByNickName("ACL");
+ node = new CMSResourceObject("EAACL");
+ node.setCustomPanel(new CMSBlankPanel(model));
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_DOCUMENT));
+ node.setAllowsChildren(false);
+ list.add(node);
+ }
+ */
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSKernelUILoader.java b/base/console/src/com/netscape/admin/certsrv/CMSKernelUILoader.java
new file mode 100644
index 000000000..cb232c527
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSKernelUILoader.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.admin.certsrv;
+
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.client.console.*;
+import com.netscape.admin.certsrv.security.*;
+import com.netscape.admin.certsrv.menu.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.ug.*;
+import com.netscape.admin.certsrv.status.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.CMSUIFramework;
+import java.util.*;
+import javax.swing.*;
+
+/**
+ * Netscape Certificate Server Kernel UI Loader.
+ *
+ * This class registers tabs (tasks,configuraiton,status)
+ * into the UI framework.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @date 03/30/97
+ */
+public class CMSKernelUILoader implements ISubSystemUILoader {
+
+ protected static final int ERROR_MESSAGE = JOptionPane.ERROR_MESSAGE;
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private CMSUIFramework mUIFramework; //parent framework
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSKernelUILoader(CMSUIFramework framework) {
+ mUIFramework = framework;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void register() {
+
+ //register subsystem UI
+ try {
+ //task tab - this holds icons such as start server, stop server, etc
+ IPage task = mUIFramework.getPage(CMSPageFeeder.TASK_TAB_TYPE,"");
+ }catch(Exception e) {
+ Debug.println("CMSKernelUILoader: register() config tab - "+e.toString());
+ }
+ CMSResourcePage page;
+ CMSBaseResourceModel model;
+
+ try {
+ //configuration tab - (holds main UI tree)
+ page = (CMSResourcePage) mUIFramework.getPage(CMSPageFeeder.RESOURCE_TAB_TYPE,"CONFIGURATION");
+ model = (CMSBaseResourceModel) page.getModel();
+ populateConfigContent(model);
+ populateConfigMenu(page);
+
+ } catch(Exception e) {
+ Debug.println("CMSKernelUILoader: register() config tab - "+e.toString());
+ }
+
+ try {
+ //status tab - allows user to view CMS log files
+ page = (CMSResourcePage) mUIFramework.getPage(CMSPageFeeder.RESOURCE_TAB_TYPE,"STATUS");
+ populateStatusContent(page);
+ populateStatusMenu(page);
+ } catch(Exception e) {
+ Debug.println("CMSKernelUILoader: register() status - "+e.toString());
+ }
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+
+ /**
+ * This method creates the configuration tree
+ */
+
+ protected void populateConfigContent(CMSBaseResourceModel model) {
+
+ CMSResourceObject root = (CMSResourceObject) model.getRoot();
+ CMSTabPanel tabPane = new CMSTabPanel(model, root);
+ tabPane.addTab(new CMSLDAPSettingPanel(tabPane));
+ tabPane.addTab(new CMSSMTPPanel(tabPane));
+ tabPane.addTab(new CMSSelfTestsPanel(tabPane));
+
+ // The log panel would only really be useful if we were able to
+ // enable or disable debug without restarting. If we can do this,
+ // then we can enable this tab.
+ //
+ // tabPane.addTab(new GeneralLogPanel(tabPane));
+
+ root.setCustomPanel(tabPane);
+
+
+ CMSResourceObject usernode = new CMSResourceObject("USERGROUPS");
+ CMSUGTabPanel tabPane1 = new CMSUGTabPanel(model, usernode);
+ tabPane1.addTab(new UserTab(model));
+ tabPane1.addTab(new GroupTab(model));
+ usernode.setCustomPanel(tabPane1);
+ usernode.setAllowsChildren(false);
+ usernode.setIcon(CMSAdminUtil.getImage(CMSAdminResources.IMAGE_UGOBJECT));
+ model.addSubSystemNode(usernode);
+
+// This ACL configuration may be revived in a future version
+ CMSResourceObject aclnode = new CMSResourceObject("ACL");
+ CMSUGTabPanel aclTabPane = new CMSUGTabPanel(model, aclnode);
+ aclTabPane.addTab(new ACLPanel(aclTabPane));
+ aclTabPane.addTab(new ACLImplTab(aclTabPane));
+ aclnode.setCustomPanel(aclTabPane);
+ aclnode.setIcon(CMSAdminUtil.getImage(
+ CMSAdminResources.IMAGE_ACLOBJECT));
+ aclnode.setAllowsChildren(false);
+ model.addSubSystemNode(aclnode);
+
+ // Authentication subsystem
+/*
+ CMSResourceObject authnode = new CMSResourceObject("AUTH");
+ tabPane1 = new CMSUGTabPanel(model, authnode);
+ tabPane1.addTab(new AuthInstanceTab(model));
+ tabPane1.addTab(new AuthImplTab(model));
+ authnode.setCustomPanel(tabPane1);
+ authnode.setIcon( CMSAdminUtil.getImage(
+ CMSAdminResources.IMAGE_AUTHOBJECT));
+ authnode.setAllowsChildren(false);
+ model.addSubSystemNode(authnode);
+
+ // jobs scheduler node
+ CMSResourceObject jobsnode = new CMSResourceObject("JOBSCHED");
+ tabPane = new CMSTabPanel(model, jobsnode);
+ tabPane.addTab(new JobsSettingPanel("JOBSGENERAL", tabPane));
+
+ jobsnode.setCustomPanel(tabPane);
+ jobsnode.setIcon( CMSAdminUtil.getImage(
+ CMSAdminResources.IMAGE_JOBSOBJECT));
+
+ jobsnode.setAllowsChildren(true);
+ CMSResourceObject cnode = new CMSResourceObject("JOBS");
+
+ tabPane1 = new CMSUGTabPanel(model, cnode);
+ tabPane1.addTab(new JobsInstanceTab(model));
+ tabPane1.addTab(new JobsImplTab(model));
+ cnode.setCustomPanel(tabPane1);
+ cnode.setIcon( CMSAdminUtil.getImage(
+ CMSAdminResources.IMAGE_JOBSOBJECT));
+ jobsnode.add(cnode);
+ cnode.setAllowsChildren(false);
+ model.addSubSystemNode(jobsnode);
+*/
+
+ // log config node
+ CMSResourceObject node = new CMSResourceObject("LOG");
+
+ CMSUGTabPanel tabPane2 = new CMSUGTabPanel(model, node);
+ tabPane2.addTab(new LogInstanceTab(model, DestDef.DEST_LOG_ADMIN));
+ tabPane2.addTab(new LogImplTab(model, DestDef.DEST_LOG_ADMIN));
+ node.setCustomPanel(tabPane2);
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_LOGOBJ));
+ node.setAllowsChildren(false);
+ model.addSubSystemNode(node);
+
+ // encryption config node
+ CMSResourceObject encryptionnode = new CMSResourceObject("ENCRYPTION");
+ CMSUGTabPanel tabPane3 = new CMSUGTabPanel(model, encryptionnode);
+ tabPane3.addTab(new CACertsTab(model, DestDef.DEST_SERVER_ADMIN));
+ tabPane3.addTab(new UserCertsTab(model, DestDef.DEST_SERVER_ADMIN));
+ NameValuePairs response;
+/*
+ try
+ {
+ AdminConnection connection = model.getServerInfo().getAdmin();
+
+ response = connection.search(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_SUBSYSTEM, new NameValuePairs());
+ Debug.println(response.toString());
+ String tempString = response.toString();
+ if(tempString.length()==0) // tempString should equals tks=tks in CMSAdminServlet::readSubsystem
+ tabPane3.addTab(new TKSKeysTab(model, DestDef.DEST_SERVER_ADMIN));
+ }catch (Exception e) {
+ Debug.println("bad admin servlet connection ");
+ }
+*/
+
+ encryptionnode.setCustomPanel(tabPane3);
+ encryptionnode.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_AUTHOBJECT));
+ encryptionnode.setAllowsChildren(false);
+ model.addSubSystemNode(encryptionnode);
+ }
+
+
+ /**
+ * Modifies the window menu (File, Edit, View, etc) to add some
+ * things which are specific to CMS configuration
+ */
+ protected void populateConfigMenu(CMSResourcePage page) {
+ CMSBaseResourceModel model = (CMSBaseResourceModel) page.getModel();
+ CMSBaseMenuInfo menuInfo = (CMSBaseMenuInfo)page.getMenuInfo();
+ try {
+ //menuInfo.registerMenuItem(CMSBaseMenuInfo.MENU_FILE,
+ // CMSBaseMenuInfo.MENU_PKCS11,
+ // new PKCS11ManagementAction(model.getConsoleInfo()));
+ // reference Bug 613851 Manage PKCS#11 shows a blank window.
+ menuInfo.addMenuItemSeparator(CMSBaseMenuInfo.MENU_FILE);
+ menuInfo.addMenuItemSeparator(CMSBaseMenuInfo.MENU_VIEW);
+ menuInfo.registerMenuItem(CMSBaseMenuInfo.MENU_VIEW,
+ CMSBaseMenuInfo.MENU_REFRESH,
+ new RefreshTabPane(model));
+ } catch(Exception e) {
+ Debug.println("menuinfo register()"+e.toString());
+ }
+ }
+
+
+ /**
+ * creates the tree view seen in the left panel when the user selects
+ * the status tab. This typically looks like this:
+ * 1 Netscape Certificate Management System
+ * 2 + Log
+ * 3 System
+ * 4 Transactions
+ * [ this method creates 1,2. The updateLogInstance() method creates 3,4 ]
+ */
+
+ protected void populateStatusContent(CMSResourcePage page) {
+ CMSBaseResourceModel model = (CMSBaseResourceModel) page.getModel();
+ CMSResourceObject root = (CMSResourceObject) model.getRoot();
+
+ //set general stat panel
+ root.setCustomPanel(new StatusPanel(model));
+
+ CMSResourceObject list, node;
+ CMSTabPanel tabPane;
+
+ //log content
+ list = new CMSResourceObject("LOG");
+ list.setCustomPanel(new CMSBlankPanel(model));
+ list.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_LOGFOLDER));
+ list.setAllowsChildren(true);
+
+ // get the log instance name list
+ updateLogInstance(page, list);
+
+ model.addSubSystemNode(list);
+ }
+
+ protected void populateStatusMenu(CMSResourcePage page) {
+ CMSBaseResourceModel model = (CMSBaseResourceModel) page.getModel();
+ CMSBaseMenuInfo menuInfo = (CMSBaseMenuInfo)page.getMenuInfo();
+ try {
+ menuInfo.addMenuItemSeparator(CMSBaseMenuInfo.MENU_VIEW);
+ menuInfo.registerMenuItem(CMSBaseMenuInfo.MENU_VIEW,
+ CMSBaseMenuInfo.MENU_REFRESH,
+ new RefreshTabPane(model));
+ } catch(Exception e) {
+ Debug.println("menuinfo register()"+e.toString());
+ }
+ }
+
+ /**
+ * retrieve log instance listing from the server
+ * side and populate the index
+ */
+ protected void updateLogInstance(CMSResourcePage page, CMSResourceObject list) {
+ CMSBaseResourceModel model = (CMSBaseResourceModel) page.getModel();
+ AdminConnection connection = model.getServerInfo().getAdmin();
+
+ //get the list of log instances from the server
+ NameValuePairs response;
+ model.progressStart();
+ try {
+ response = connection.search(DestDef.DEST_LOG_ADMIN,
+ ScopeDef.SC_LOG_INSTANCES,
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ CMSAdminUtil.showErrorDialog(model.getFrame(),
+ ResourceBundle.getBundle(
+ CMSAdminResources.class.getName()
+ ), e.getMessage(), ERROR_MESSAGE);
+ model.progressStop();
+ return;
+ }
+
+ //update the index
+ for (String entry : response.keySet()) {
+ CMSResourceObject node = new CMSResourceObject(entry);
+ node.setCustomPanel(new LogInstancePanel(entry, model));
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_LOGOBJECT));
+ node.setAllowsChildren(false);
+ list.add(node);
+ }
+ model.progressStop();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSMessageBox.java b/base/console/src/com/netscape/admin/certsrv/CMSMessageBox.java
new file mode 100644
index 000000000..2eef61cb2
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSMessageBox.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.admin.certsrv;
+
+import java.util.*;
+import java.awt.*;
+import javax.swing.*;
+
+/*
+ A basic implementation of the JDialog class.
+*/
+
+public class CMSMessageBox extends JDialog
+{
+ private Label message;
+ protected ResourceBundle mResource;
+
+ public CMSMessageBox(JFrame parent, String title, String messageString, int width) {
+ super(parent, title, false);
+ setSize( width, 100 );
+ setResizable( false );
+ setLocationRelativeTo(parent);
+
+ message = new Label( messageString, Label.CENTER );
+ getContentPane().add( message, BorderLayout.CENTER );
+ setVisible(true);
+ }
+
+ public CMSMessageBox(JFrame parent, String panelName, String keyword) {
+ super(parent, "Status", false);
+ int width = 300;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ String messageString = mResource.getString(panelName+"_DIALOG_PROGRESS_"+keyword);
+
+ setSize( width, 100 );
+ setResizable( false );
+ setLocationRelativeTo(parent);
+
+ message = new Label( messageString, Label.CENTER );
+ getContentPane().add( message, BorderLayout.CENTER );
+ setVisible(true);
+ }
+
+ public CMSMessageBox(Frame parent)
+ {
+ super(parent);
+
+ // This code is automatically generated by Visual Cafe when you add
+ // components to the visual environment. It instantiates and initializes
+ // the components. To modify the code, only use code syntax that matches
+ // what Visual Cafe can generate, or Visual Cafe may be unable to back
+ // parse your Java file into its visual environment.
+ //{{INIT_CONTROLS
+ getContentPane().setLayout(null);
+ setSize(405,305);
+ setVisible(false);
+ label1.setText("text");
+ getContentPane().add(label1);
+ label1.setBounds(96,96,206,52);
+ //}}
+ }
+
+ public CMSMessageBox()
+ {
+ this((Frame)null);
+ }
+
+ public CMSMessageBox(String sTitle)
+ {
+ this();
+ setTitle(sTitle);
+ }
+
+ public void setVisible(boolean b)
+ {
+ super.setVisible(b);
+ }
+
+ static public void main(String args[])
+ {
+ (new CMSMessageBox()).setVisible(true);
+ }
+
+ public void addNotify()
+ {
+ // Record the size of the window prior to calling parents addNotify.
+ Dimension size = getSize();
+
+ super.addNotify();
+
+ if (frameSizeAdjusted)
+ return;
+ frameSizeAdjusted = true;
+
+ // Adjust size of frame according to the insets
+ Insets insets = getInsets();
+ setSize(insets.left + insets.right + size.width, insets.top + insets.bottom + size.height);
+ }
+
+ // Used by addNotify
+ boolean frameSizeAdjusted = false;
+
+ //{{DECLARE_CONTROLS
+ java.awt.Label label1 = new java.awt.Label();
+ //}}
+
+}
+
+
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSOCSPUILoader.java b/base/console/src/com/netscape/admin/certsrv/CMSOCSPUILoader.java
new file mode 100644
index 000000000..3c8d5dba0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSOCSPUILoader.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.admin.certsrv;
+
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.ug.*;
+import com.netscape.admin.certsrv.menu.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.notification.*;
+
+/**
+ * Netscape Certificate Server 4.0 Certificate Authority UI Loader.
+ *
+ * This class is responsible for the loading of UI components associated with
+ * the ca functionality.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @date 03/30/97
+ */
+public class CMSOCSPUILoader implements ISubSystemUILoader {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private CMSUIFramework mUIFramework; //parent framework
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSOCSPUILoader(CMSUIFramework framework) {
+ mUIFramework = framework;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void register() {
+ //register subsystem UI
+ try {
+
+ //task tab
+ IPage task = mUIFramework.getPage(CMSPageFeeder.TASK_TAB_TYPE,"");
+
+ //config tab
+ CMSResourcePage page = (CMSResourcePage) mUIFramework.getPage(CMSPageFeeder.RESOURCE_TAB_TYPE,"CONFIGURATION");
+ CMSBaseResourceModel model = (CMSBaseResourceModel) page.getModel();
+ populateConfigContent(model);
+
+ }catch(Exception e) {
+ Debug.println("CMSCAUILoader: register() config - "+e.toString());
+ }
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+ protected void populateConfigContent(CMSBaseResourceModel model) {
+ CMSResourceObject list, node;
+ CMSTabPanel tabPane;
+
+ //ca node
+ list = new CMSResourceObject("OCSPCONFIG");
+ tabPane = new CMSTabPanel(model, list);
+ tabPane.addTab(new CMSOCSPGeneralPanel(tabPane));
+ list.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_FOLDER));
+ list.setAllowsChildren(true);
+ list.setCustomPanel(tabPane);
+
+ // crl extensions sub node
+ node = new CMSResourceObject("OCSPSTORES");
+ CMSUGTabPanel storeTabPane = new CMSUGTabPanel(model, node);
+ storeTabPane.addTab(new OCSPStoresInstanceTab(model, DestDef.DEST_OCSP_ADMIN));
+ node.setCustomPanel(storeTabPane);
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULEOBJECT))
+;
+ node.setAllowsChildren(false);
+ list.add(node);
+
+ model.addSubSystemNode(list);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSPageFeeder.java b/base/console/src/com/netscape/admin/certsrv/CMSPageFeeder.java
new file mode 100644
index 000000000..0abd28f29
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSPageFeeder.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.admin.certsrv;
+
+import java.util.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.topology.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.config.*;
+import netscape.ldap.*;
+
+/**
+ * Netscape Certificate Server 4.0 page model.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class CMSPageFeeder extends FrameworkInitializer {
+//public class CMSPageFeeder extends PageFeeder {
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static String RESOURCE_TAB_TYPE = "RESOURCE_TAB_TYPE";
+ public static String TASK_TAB_TYPE = "TASK_TAB_TYPE";
+
+ private static String PREFIX = "CMSPAGEFEEDER_";
+
+ private ConsoleInfo mConsoleInfo; // global information
+ private CMSServerInfo mServerInfo; // instance information
+
+ //private TaskPage mTaskPage; // task page
+ private Hashtable mPages; // resource pages
+ //private ResourcePage mResourcePage; // resource page
+ //private ResourcePage mContentPage; // content page
+ //private ResourcePage mUGPage; // identity and roles page
+
+ private ResourceBundle mResource; // resource boundle
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ /**
+ * Constructor.
+ *
+ * @param admin The server instance.
+ * @param info Global console connection information
+ * @param serverInfo Server instance connection information
+ */
+ public CMSPageFeeder( ConsoleInfo info, CMSServerInfo serverInfo ) {
+ mConsoleInfo = info;
+ mServerInfo = serverInfo;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mPages = new Hashtable();
+
+ setFrameTitle(mResource.getString(PREFIX+"SERVERNAME"));
+ setMinimizedImage(CMSAdminUtil.getImage(CMSAdminResources.IMAGE_CERTICON_MEDIUM).getImage());
+ setBannerImage(CMSAdminUtil.getThemeImage(CMSAdminResources.IMAGE_BRANDING).getImage());
+ setBannerText("");
+ //setFrameImage(CMSAdminUtil.getImage(CMSAdminResources.IMAGE_CERTICON_SMALL).getImage());
+ }
+
+ /**
+ * Retrieve the tab page as needed. If the tab page type not found
+ * throws exceptions. If the tab page with the specified name already
+ * exist, simply return that page.
+ */
+ public IPage getPage(String type, String name) throws EAdminException {
+ //Debug.println("CMSPageFeeder: getPage() -"+type+"-"+name);
+ if (type.trim().equals(TASK_TAB_TYPE)) {
+ return null;
+/*
+ //XXX Support multiple task tab ???
+ if (mPages.containsKey("TASK"))
+ return (IPage) mPages.get("TASK");
+ TaskPage task = createTaskPage();
+
+ // TAKE THIS ONE OUT FOR BETA-1
+ mPages.put("TASK", task);
+ addPage(task);
+ return task;
+*/
+ }
+
+ if (!type.trim().equals(RESOURCE_TAB_TYPE)) {
+ throw new EAdminException(mResource.getString(PREFIX+"RESOURCE_TAB_NOT_FOUND"), true);
+ }
+
+ if (mPages.containsKey(name.trim())) {
+ return (IPage) mPages.get(name.trim());
+ } else {
+ CMSResourcePage page = new CMSResourcePage(new CMSBaseResourceModel(mConsoleInfo,mServerInfo));
+ String title;
+ try {
+ title = mResource.getString(PREFIX+name.trim());
+ } catch (MissingResourceException e) {
+ title = "Missing Title";
+ }
+ page.setPageTitle(title);
+ mPages.put(name.trim(), page);
+ addPage(page);
+ return page;
+ }
+ }
+
+
+ /**
+ * Expend resource trees insde each individual pages
+ */
+ public void expendPages() {
+ for (Enumeration e = mPages.keys() ; e.hasMoreElements() ;) {
+ String name = (String)e.nextElement();
+ IPage page = (IPage)mPages.get(name);
+ if (page instanceof CMSResourcePage)
+ ((CMSResourcePage)page).getTree().expandRow(0);
+ }
+ }
+
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ /**
+ * Create the directory server task tab page by finding all task
+ * entries in the directory for this instance.
+ */
+ private TaskPage createTaskPage() {
+ TaskModel model = new CMSTaskModel(mConsoleInfo, mServerInfo);
+ return new TaskPage( model );
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSPassword.java b/base/console/src/com/netscape/admin/certsrv/CMSPassword.java
new file mode 100644
index 000000000..4fbca9011
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSPassword.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.admin.certsrv;
+
+import java.awt.*;
+import java.util.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.border.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+
+/**
+ * Display this dialog to get a password.
+ *
+ * @author chrisho
+ * @version $Revision$, $Date$
+ * @date 07/21/98
+ */
+
+public class CMSPassword extends JDialog
+ implements ActionListener, DocumentListener, MouseListener
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final int WIDTH = 300;
+ private static final int HEIGHT = 150;
+ private static final String HELPINDEX =
+ "authentication-certsrv-auth-dialog-help";
+
+ private JTextField mUsernameField; // username textfield
+ private JPasswordField mPasswordField; // password field
+ private boolean mCanceled = true; // exit state of the dialog
+ private String mUsername; // username
+ private String mPassword; // password
+ private static final String PREFIX = "CMSPASSWORD";
+ private JFrame mParentFrame;
+ private ResourceBundle mResource;
+ private JButton mOK, mCancel, mHelp;
+ private KeyListener mTextFieldKeyListener;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ /**
+ * @param parent parent frame
+ */
+ public CMSPassword(JFrame parent) {
+ super(parent, true);
+ mParentFrame = parent;
+ mResource =
+ ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mTextFieldKeyListener = new TextFieldKeyListener();
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+
+ JPanel center = new JPanel();
+ getContentPane().setLayout(new BorderLayout());
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ JPanel contentPanel = new JPanel();
+ GridBagLayout gb1 = new GridBagLayout();
+ contentPanel.setLayout(gb1);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(contentPanel, gbc);
+ center.add(contentPanel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel lUsername =
+ new JLabel(mResource.getString(PREFIX+"_LABEL_UID_LABEL"));
+ lUsername.setToolTipText(
+ mResource.getString(PREFIX+"_LABEL_UID_TTIP"));
+
+ mUsernameField = new JTextField();
+ mUsernameField.addKeyListener(mTextFieldKeyListener);
+ mUsernameField.getDocument().addDocumentListener(this);
+ mUsernameField.addMouseListener(this);
+
+ CMSAdminUtil.addEntryField(contentPanel, lUsername, mUsernameField,
+ gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel lPassword=
+ new JLabel(mResource.getString(PREFIX+"_LABEL_PWD_LABEL"));
+ lPassword.setToolTipText(
+ mResource.getString(PREFIX+"_LABEL_PWD_TTIP"));
+ mPasswordField = new JPasswordField();
+ mPasswordField.addKeyListener(mTextFieldKeyListener);
+ mPasswordField.getDocument().addDocumentListener(this);
+ mPasswordField.addMouseListener(this);
+ CMSAdminUtil.addEntryField(contentPanel, lPassword, mPasswordField,
+ gbc);
+
+ JPanel actionPanel = makeActionPane();
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(actionPanel, gbc);
+ center.add(actionPanel);
+
+ getContentPane().add("Center",center);
+
+ mCanceled=false;
+ mUsername="";
+ mPassword="";
+
+ setSize( WIDTH, HEIGHT );
+
+ addWindowListener(
+ new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ //setVisible(false);
+ dispose();
+ mCanceled = true;
+ }
+ }
+ );
+
+ addWindowListener(
+ new WindowAdapter() {
+ public void windowOpened(WindowEvent e) {
+ mUsernameField.requestFocus();
+ }
+ }
+ );
+
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * return the exit status of the dialog
+ *
+ * @return true if the user hits the cancel button.
+ */
+ public boolean isCancel() {
+ return mCanceled;
+ }
+
+ /**
+ * Returns the username typed in by the user, on OK.
+ *
+ * @return The selected username, if the user hits the OK button.
+ */
+ public String getUsername() {
+ return mUsername;
+ }
+
+ /**
+ * Return the password typed in by the user, on OK.
+ *
+ * @return The selected password, if the user hits the OK button.
+ */
+ public String getPassword() {
+ return mPassword;
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+ public void actionPerformed(ActionEvent evt) {
+ if (evt.getSource().equals(mOK)) {
+ mUsername = mUsernameField.getText().trim();
+ mPassword = mPasswordField.getText().trim();
+
+ /* USE PROACTIVE VERIFICATION
+ if (userid.equals("") || newpassword.equals("")) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, mResource,
+ PREFIX, "EMPTYFIELD", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ */
+
+ mCanceled = false;
+ //setVisible(false);
+ this.dispose();
+ return;
+
+ }
+ if (evt.getSource().equals(mCancel)) {
+ //setVisible(false);
+ mCanceled = true;
+ this.dispose();
+ return;
+ }
+ if (evt.getSource().equals(mHelp)) {
+ CMSAdminUtil.help(HELPINDEX);
+ return;
+ }
+ }
+
+ //== DocumentListener ==
+ public void insertUpdate(DocumentEvent e) {
+ setButtons();
+ }
+
+ public void removeUpdate(DocumentEvent e){
+ setButtons();
+ }
+
+ public void changedUpdate(DocumentEvent e){
+ setButtons();
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {}
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null,
+ this);
+ mOK.setEnabled(false);
+ mCancel = CMSAdminUtil.makeJButton(mResource, PREFIX, "CANCEL",
+ null, this);
+ mHelp = CMSAdminUtil.makeJButton(mResource, PREFIX, "HELP",
+ null, this);
+
+ //JButton[] buttons = { mOK, mCancel, mHelp};
+ JButton[] buttons = { mOK, mCancel};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonPanel(buttons, true);
+ }
+
+ //set buttons
+ private void setButtons() {
+ if ( (mUsernameField.getText().trim().equals("")) ||
+ (mPasswordField.getText().trim().equals("")) ) {
+ mOK.setEnabled(false);
+ } else {
+ mOK.setEnabled(true);
+ getRootPane().setDefaultButton(mOK);
+ }
+ }
+
+ /**
+ * Inner class which handles key events for JTextField components.
+ */
+ class TextFieldKeyListener implements KeyListener
+ {
+ public void keyTyped(KeyEvent e) {
+ }
+
+ public void keyPressed(KeyEvent e) {
+ }
+
+ public void keyReleased(KeyEvent e) {
+ if(e.getKeyCode() == KeyEvent.VK_ENTER) {
+ if ( (!mUsernameField.getText().trim().equals("")) &&
+ (!mPasswordField.getText().trim().equals("")) ) {
+ mOK.doClick();
+ }
+ }
+ }
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSRAUILoader.java b/base/console/src/com/netscape/admin/certsrv/CMSRAUILoader.java
new file mode 100644
index 000000000..b2103a34e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSRAUILoader.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.admin.certsrv;
+
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.ug.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.notification.*;
+
+/**
+ * Netscape Certificate Server 4.0 Kernel UI Loader.
+ *
+ * This class is responsible for the loading of UI components associated with
+ * the kernel functionality.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @date 03/30/97
+ */
+public class CMSRAUILoader implements ISubSystemUILoader {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private CMSUIFramework mUIFramework; //parent framework
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSRAUILoader(CMSUIFramework framework) {
+ mUIFramework = framework;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void register() {
+ //register subsystem UI
+ try {
+
+ //task tab
+ IPage task = mUIFramework.getPage(CMSPageFeeder.TASK_TAB_TYPE,"");
+
+ //config tab
+ CMSResourcePage page = (CMSResourcePage) mUIFramework.getPage(CMSPageFeeder.RESOURCE_TAB_TYPE,"CONFIGURATION");
+ CMSBaseResourceModel model = (CMSBaseResourceModel) page.getModel();
+ populateConfigContent(model);
+
+ /*repos tab
+ page = (CMSResourcePage) mUIFramework.getPage(CMSPageFeeder.RESOURCE_TAB_TYPE,"CONTENT");
+ model = (CMSBaseResourceModel) page.getModel();
+ populateRepositoryContent(model);
+ */
+
+ /*acl tab
+ page = (CMSResourcePage) mUIFramework.getPage(CMSPageFeeder.RESOURCE_TAB_TYPE,"ACCESSCONTROLLIST");
+ model = (CMSBaseResourceModel) page.getModel();
+ populateACLContent(model);
+ */
+
+ }catch(Exception e) {
+ Debug.println("CMSRAUILoader: register() config - "+e.toString());
+ }
+
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+ protected void populateConfigContent(CMSBaseResourceModel model) {
+ CMSResourceObject list, node;
+ CMSTabPanel tabPane;
+
+ CMSResourceObject authnode = new CMSResourceObject("AUTH");
+ CMSUGTabPanel tabPane1 = new CMSUGTabPanel(model, authnode);
+ tabPane1.addTab(new AuthInstanceTab(model));
+ tabPane1.addTab(new AuthImplTab(model));
+ authnode.setCustomPanel(tabPane1);
+ authnode.setIcon( CMSAdminUtil.getImage(
+ CMSAdminResources.IMAGE_AUTHOBJECT));
+ authnode.setAllowsChildren(false);
+ model.addSubSystemNode(authnode);
+
+ // jobs scheduler node
+ CMSResourceObject jobsnode = new CMSResourceObject("JOBSCHED");
+ tabPane = new CMSTabPanel(model, jobsnode);
+ tabPane.addTab(new JobsSettingPanel("JOBSGENERAL", tabPane));
+
+ jobsnode.setCustomPanel(tabPane);
+ jobsnode.setIcon( CMSAdminUtil.getImage(
+ CMSAdminResources.IMAGE_JOBSOBJECT));
+
+ jobsnode.setAllowsChildren(true);
+ CMSResourceObject cnode = new CMSResourceObject("JOBS");
+
+ tabPane1 = new CMSUGTabPanel(model, cnode);
+ tabPane1.addTab(new JobsInstanceTab(model));
+ tabPane1.addTab(new JobsImplTab(model));
+ cnode.setCustomPanel(tabPane1);
+ cnode.setIcon( CMSAdminUtil.getImage(
+ CMSAdminResources.IMAGE_JOBSOBJECT));
+ jobsnode.add(cnode);
+ cnode.setAllowsChildren(false);
+ model.addSubSystemNode(jobsnode);
+
+ //ra node
+ list = new CMSResourceObject("RACONFIG");
+ tabPane = new CMSTabPanel(model, list);
+// tabPane.addTab(new CMSRAGeneralPanel(tabPane));
+ tabPane.addTab(new CMSRAConnectorPanel(model,tabPane));
+ list.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_FOLDER));
+ list.setAllowsChildren(true);
+ list.setCustomPanel(tabPane);
+
+ //policies sub node
+ CMSResourceObject node2;
+ node = new CMSResourceObject("POLICIES");
+ CMSUGTabPanel tabPane2 = new CMSUGTabPanel(model, node);
+ tabPane2.addTab(new PolicyInstanceTab(model, DestDef.DEST_RA_POLICY_ADMIN));
+ tabPane2.addTab(new PolicyImplTab(model, DestDef.DEST_RA_POLICY_ADMIN));
+ node.setCustomPanel(tabPane2);
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULEOBJECT));
+ node.setAllowsChildren(false);
+ list.add(node);
+
+ // profiles
+ node = new CMSResourceObject("PROFILES");
+ CMSUGTabPanel tabPane3 = new CMSUGTabPanel(model, node);
+ tabPane3.addTab(new ProfileInstanceTab(model, DestDef.DEST_RA_PROFILE_ADMIN));
+ tabPane3.addTab(new ProfileImplTab(model, DestDef.DEST_REGISTRY_ADMIN));
+ node.setCustomPanel(tabPane3);
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULEOBJECT))
+;
+ node.setAllowsChildren(false);
+ list.add(node);
+
+ // notification
+ CMSResourceObject notificationNode = new CMSResourceObject("NOTIFICATION");
+ tabPane = new CMSTabPanel(model, notificationNode);
+ tabPane.addTab(new RequestCompletePanel("NOTIFYREQCOMPLETE",
+ tabPane,
+ DestDef.DEST_RA_ADMIN));
+ tabPane.addTab(new RequestInQPanel("NOTIFYREQINQ", tabPane,
+ DestDef.DEST_RA_ADMIN));
+
+ notificationNode.setCustomPanel(tabPane);
+ notificationNode.setIcon( CMSAdminUtil.getImage(
+ CMSAdminResources.IMAGE_JOBSOBJECT));
+
+ notificationNode.setAllowsChildren(false);
+ list.add(notificationNode);
+
+
+ /* servlet sub node - XXX NOT FOR B1
+ CMSResourceObject node3;
+ node3 = new CMSResourceObject("SERVLET");
+ CMSUGTabPanel tabPane3 = new CMSUGTabPanel(model, node3);
+ tabPane3.addTab(new ServletInstanceTab(model,
+ DestDef.DEST_RA_SERVLET_ADMIN));
+ tabPane3.addTab(new ServletImplTab(model,
+ DestDef.DEST_RA_SERVLET_ADMIN));
+ node3.setCustomPanel(tabPane3);
+ node3.setIcon(CMSAdminUtil.getImage(CMSAdminResources.IMAGE_SERVLETOBJECT));
+ node3.setAllowsChildren(false);
+ list.add(node3);
+ */
+
+ /*extensions sub node
+ node = new CMSResourceObject("EXTENSIONS");
+ tabPane = new CMSTabPanel(model, node);
+ tabPane.addTab(new CMSBlankPanel(model,tabPane,"Configuration"));
+ tabPane.addTab(new CMSBlankPanel(model,tabPane,"Registartion"));
+ node.setCustomPanel(tabPane);
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_PLUGIN));
+ node.setAllowsChildren(false);
+ list.add(node);
+ */
+
+ /*backup restore sub node
+ node = new CMSResourceObject("BACKUP");
+ tabPane = new CMSTabPanel(model, node);
+ tabPane.addTab(new CMSBlankPanel(model,tabPane,"Backup"));
+ tabPane.addTab(new CMSBlankPanel(model,tabPane,"Restore"));
+ node.setCustomPanel(tabPane);
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_GENERICOBJ));
+ node.setAllowsChildren(false);
+ list.add(node);
+ */
+
+ //ldap publishing
+ //node = new CMSResourceObject("PUBLISHING");
+ //tabPane = new CMSTabPanel(model, node);
+ //tabPane.addTab(new CMSRALDAPPanel(tabPane));
+ //tabPane.addTab(new CMSUserCertSettingPanel("RAUSERCERTSETTING",tabPane));
+ //node.setCustomPanel(tabPane);
+ //node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_LDAPPUB));
+ //node.setAllowsChildren(false);
+ //list.add(node);
+
+ /*webgateway
+ node = new CMSResourceObject("GATEWAY");
+ tabPane = new CMSTabPanel(model, node);
+ tabPane.addTab(new CMSBlankPanel(model,tabPane,"VGI Setting"));
+ tabPane.addTab(new CMSBlankPanel(model,tabPane,"Error Responses"));
+ node.setCustomPanel(tabPane);
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_FOLDER));
+ node.setAllowsChildren(false);
+ list.add(node);
+ */
+
+ model.addSubSystemNode(list);
+ }
+
+ /*
+ protected void populateRepositoryContent(CMSBaseResourceModel model) {
+ CMSResourceObject list, node;
+
+ //ra repositories node
+ list = new CMSResourceObject("RAREPOSITORIES");
+ list.setCustomPanel(new CMSBlankPanel(model));
+ list.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_DBCONATINER));
+ list.setAllowsChildren(true);
+ node = new CMSResourceObject("RAREQUESTS");
+ node.setCustomPanel(new CMSBlankPanel(model));
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_DBOBJECT));
+ node.setAllowsChildren(false);
+ list.add(node);
+ node = new CMSResourceObject("RACERTIFICATE");
+ node.setCustomPanel(new CMSBlankPanel(model));
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_DBOBJECT));
+ node.setAllowsChildren(false);
+ list.add(node);
+ model.addSubSystemNode(list);
+ }
+ */
+
+ /*
+ protected void populateACLContent(CMSBaseResourceModel model) {
+ CMSResourceObject list, node;
+ list = model.getByNickName("ACL");
+ node = new CMSResourceObject("RAACL");
+ node.setCustomPanel(new CMSBlankPanel(model));
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_DOCUMENT));
+ node.setAllowsChildren(false);
+ list.add(node);
+ }
+ */
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSRemoteClassLoader.java b/base/console/src/com/netscape/admin/certsrv/CMSRemoteClassLoader.java
new file mode 100644
index 000000000..f389aedda
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSRemoteClassLoader.java
@@ -0,0 +1,109 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv;
+
+import java.util.Hashtable;
+import java.io.IOException;
+import com.netscape.admin.certsrv.connection.AdminConnection;
+
+/**
+ * The CMSRemoteClassLoader is designed to load classes from remote
+ * Certificate Servers. Classes are acquired via the admin channel
+ * used by the Certificate Server console.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @date 02/13/97
+ * @see ClassLoader
+ */
+class CMSRemoteClassLoader extends ClassLoader {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private Hashtable mCache = new Hashtable(); // stores classes
+ private AdminConnection mAdmin; // srever entry point
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSRemoteClassLoader(CMSServerInfo info) {
+ //mAdmin = info.getAdmin();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Attempts to load the named class.
+ *
+ * @param name the fully-qualified class name, in '.' form.
+ * @return the Class object of the named class.
+ * @throws ClassNotFoundException if the class cannot be found.
+ */
+ public synchronized Class loadClass(String name, boolean resolve)
+ throws ClassNotFoundException
+ {
+ Class c = (Class) mCache.get(name);
+
+ if (c == null) {
+ String path = name.replace('.', '/') + ".class";
+ try {
+ byte data[] = loadClassData(path);
+ c = defineClass(name,data, 0, data.length);
+ mCache.put(name, c);
+ } catch (Exception e) {
+ }
+ }
+ if (resolve)
+ resolveClass(c);
+ return c;
+
+ }
+
+ /**
+ * Attempts to load the named class.
+ *
+ * @param name the fully-qualified class name, in '.' form.
+ * @return the Class object of the named class.
+ * @throws ClassNotFoundException if the class cannot be found.
+ */
+ public Class loadClass(String name) throws ClassNotFoundException {
+ return this.loadClass(name, true);
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ /**
+ * Retrieves the class specified by path from the server side.
+ *
+ * @param class name
+ * @return an InputStream for the resource.
+ * @throws Exception on any error while loading the resource.
+ */
+ private byte[] loadClassData(String path)
+ throws EAdminException
+ {
+ //load the class here from server side
+ return null;
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSResourceObject.java b/base/console/src/com/netscape/admin/certsrv/CMSResourceObject.java
new file mode 100644
index 000000000..f0f5d38b0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSResourceObject.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.admin.certsrv;
+
+import java.util.*;
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.tree.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.client.*;
+
+/**
+ * Netscape Certificate Server 4.0 Node Object.<br>
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv
+ */
+public class CMSResourceObject extends ResourceObject {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private final String PREFIX = "CMSRESOURCEOBJECT_";
+ private JPanel mRightPane;
+ private String mNickName;
+ protected ResourceBundle mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ /**
+ * Creates empty resource object.
+ */
+ public CMSResourceObject() {
+ super();
+ mNickName = "";
+ }
+
+ /**
+ * Creates resource object with specified keyword/nickname.
+ */
+ public CMSResourceObject(String keyword) {
+ this();
+ mNickName = keyword;
+ String sDisplayName;
+ try {
+ sDisplayName = mResource.getString(PREFIX+keyword+"_TITLE");
+ } catch(MissingResourceException e) {
+ sDisplayName = keyword;
+ }
+ setName(sDisplayName);
+ }
+
+ /**
+ * Creates resource object with specified keyword/nickname and icons.
+ */
+ public CMSResourceObject(String keyword, Icon icon, Icon largeIcon) {
+ this();
+ mNickName = keyword;
+ String sDisplayName;
+ try {
+ sDisplayName = mResource.getString(PREFIX+keyword+"_TITLE");
+ } catch(MissingResourceException e) {
+ sDisplayName = "MissingTitle";
+ }
+ setName(sDisplayName);
+ setIcon(icon);
+ setLargeIcon(largeIcon);
+ }
+
+ /**
+ * Returns the internal nickname for this resource object
+ */
+ public String getNickName() {
+ return mNickName;
+ }
+
+ /**
+ * Returns the AWT Component that is displayed in the right hand pane
+ * of the resource page.
+ * @return a new instantiation of the component for each view.
+ * Called by: ResourceModel
+ */
+ public Component getCustomPanel()
+ {
+ return mRightPane;
+ }
+
+ /**
+ * Set the right hand panel to be shown
+ * @param panel right hand panel
+ */
+ public void setCustomPanel(JPanel panel) {
+ mRightPane = panel;
+ }
+
+ protected MenuItemText getMenuItemText(String keyword) {
+ ResourceBundle mResource = ResourceBundle.getBundle(
+ CMSAdminResources.class.getName());
+ String name = mResource.getString("GENERAL_MENU_"+keyword+"_LABEL");
+ if (name == null)
+ name = "Missing Label";
+ String desc = mResource.getString("GENERAL_MENU_"+keyword+"_DESC");
+ if (desc == null)
+ desc = " ";
+ return new MenuItemText( keyword, name, desc);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSResourcePage.java b/base/console/src/com/netscape/admin/certsrv/CMSResourcePage.java
new file mode 100644
index 000000000..9ad03515d
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSResourcePage.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.admin.certsrv;
+
+import javax.swing.*;
+import javax.swing.tree.*;
+import javax.swing.event.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * This page creates the resource view
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv
+ */
+public class CMSResourcePage extends ResourcePage implements Cloneable {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ protected IMenuInfo mMenuInfo; // menu information delegation
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ /**
+ * Return ResourcePage using the data model specified.
+ */
+ public CMSResourcePage(CMSBaseResourceModel resourceModel) {
+ super(resourceModel);
+ resourceModel.setResourcePage(this);
+ //we will only support single selection model
+ TreeSelectionModel selectionModel = _tree.getSelectionModel();
+ selectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION );
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Need to overwrite this one to clone
+ * DSResourcePage instead of ResourcePage
+ * @return copy of resource page
+ */
+ public Object clone() {
+ CMSResourcePage rp = new CMSResourcePage((CMSBaseResourceModel)_model);
+ rp.setCellRenderer( _treeRenderer );
+ rp.setPageTitle(getPageTitle());
+ rp.setMenuInfo(mMenuInfo);
+ return rp;
+ }
+
+ /**
+ * Retrieve JTree Obejct
+ * @return JTree obejct in the resource page
+ */
+ public JTree getTree() {
+ return (JTree)_tree;
+ }
+
+ /**
+ * Implements TreeSelectionListener. Called when an object is selected
+ * in the resource tree. Informs IResourceModelListeners of this event.
+ */
+ public void valueChanged(TreeSelectionEvent ev)
+ {
+ IResourceObject[] selection = getSelection();
+ if(selection != null) {
+ if(selection.length == 1) // single selection {
+ setCustomPanel(_model.getCustomPanel(this, selection[0]));
+ }
+ _model.actionObjectSelected(this, selection, getPreviousSelection());
+
+ //the selected node not necessary the original selection
+ //in case of not allow to change
+ _previousSelection = getSelection();
+ }
+
+ /**
+ * Called internally when page is unselected
+ */
+ public void pageUnselected(IFramework framework) {
+ super.pageUnselected(framework);
+ //check if the data is not saved
+ }
+
+ /**
+ * Initializes page. Called after construction or after clonePage().
+ * The reference to IFramework allows this page to set menu items, status
+ * bars, and add event notification listeners. COVERWRITES the method in
+ * the ResourcePage class to provide the menu contain separartion.
+ */
+ public void initialize(IFramework framework) {
+ //Debug.println("CMSResourcePage - initialize() "+mMenuInfo);
+ super.initialize(framework);
+ if (mMenuInfo != null)
+ addMenuItems(mMenuInfo , _menuInfoAction);
+ }
+
+ /**
+ * Set and replace the existing menuInfo delegation object
+ */
+ public void setMenuInfo(IMenuInfo menuInfo) {
+ //Debug.println("CMSResourcePage - setMenuInfo() "+menuInfo);
+ mMenuInfo = menuInfo;
+ }
+
+ /**
+ * Retrieve IMenuInfo object
+ */
+ public IMenuInfo getMenuInfo() {
+ if (mMenuInfo == null) {
+ mMenuInfo = new CMSBaseMenuInfo();
+ }
+ return mMenuInfo;
+ }
+
+ /**
+ * Start the zipping status bar
+ */
+ public void progressStart() {
+ //XXX COMEBACK AFTER UPGRADE
+ _statusItemProgress.start();
+ }
+
+ /**
+ * Stop the zipping status bar
+ */
+ public void progressStop() {
+ //XXX COMEBACK AFTER UPGRADE
+ _statusItemProgress.stop();
+ }
+
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSServerInfo.java b/base/console/src/com/netscape/admin/certsrv/CMSServerInfo.java
new file mode 100644
index 000000000..d2d64b3fc
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSServerInfo.java
@@ -0,0 +1,172 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv;
+
+import java.util.*;
+import javax.swing.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+
+/**
+ * Certificate server information. Store all relevant
+ * information that allows this client to connect to
+ * the certificate server.
+ *
+ * @author Jack Pan-Chen
+ * @author Thomas Kwan
+ * @version $Revision$, $Date$
+ */
+public class CMSServerInfo implements IConnectionListener {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "SERVER";
+ private AdminConnection mAdmin = null; // srever entry point
+ private String mHost = null; // server host
+ private int mPort; // server port
+ private String mServerId = null; // server id
+ private String mServerRoot = null;
+ private String mServerVersion = null; // server version
+ private String mUserid = null; // user id
+ private String mInstallDate = null; // server install date
+ private String mPassword = null; // user password
+ private String mPath = null;
+ private Vector mSubsystem = new Vector();
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSServerInfo(String host, int port, String userid, String password,
+ String serverid, String installDate, String version,
+ String serverRoot, String path)
+ throws EAdminException
+ {
+
+ mHost = host;
+ mPort = port;
+ mUserid = userid;
+ mPassword = password;
+ mServerId = serverid;
+ mServerVersion = version;
+ mInstallDate = installDate;
+ mServerRoot = serverRoot;
+ mPath = path;
+
+ Debug.println("CMSServerInfo: host "+mHost+" port "+mPort+
+ " userid "+mUserid+" serverRoot "+mServerRoot+" serverid "+mServerId);
+ mAdmin = new AdminConnection(
+ new BasicAuthenticator(mUserid, mPassword),
+ new SSLConnectionFactory(SSLConnectionFactory.JSS_CONNECTION),
+ true /* KeepAlive */, mHost, mPort, mPath);
+ mAdmin.setConnectionListener(this);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ public void restartCallback() {
+ JFrame frame = UtilConsoleGlobals.getActivatedFrame();
+ if (frame != null) {
+ ResourceBundle bundle =
+ ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ CMSAdminUtil.showMessageDialog(frame, bundle, PREFIX, "RESTART",
+ CMSAdminUtil.WARNING_MESSAGE);
+ }
+ }
+
+ public void ping() throws EAdminException {
+
+ // Need to do authentication here
+ NameValuePairs config = new NameValuePairs();
+ config.put(Constants.PR_PING, "");
+
+ NameValuePairs response;
+
+ response = mAdmin.read(DestDef.DEST_AUTH_ADMIN,
+ ScopeDef.SC_AUTH,
+ Constants.RS_ID_CONFIG,
+ config);
+
+ if (!response.get(Constants.PR_PING).equalsIgnoreCase(Constants.TRUE)) {
+ Debug.println("Ping failed -> Server off");
+ throw new EAdminException("PING_FAILED",false);
+ }
+ }
+
+ public void authenticate() throws EAdminException {
+ mAdmin.auth(DestDef.DEST_AUTH_ADMIN, ScopeDef.SC_AUTH);
+ }
+
+ public String getAuthType() throws EAdminException {
+ return mAdmin.authType(DestDef.DEST_AUTH_ADMIN, ScopeDef.SC_AUTHTYPE);
+ }
+
+ public AdminConnection getAdmin() {
+ return mAdmin;
+ }
+
+ public String getHost() {
+ return mHost;
+ }
+
+ public int getPort() {
+ return mPort;
+ }
+
+ public String getUserId() {
+ return mUserid;
+ }
+
+ public String getServerId() {
+ return mServerId;
+ }
+
+ public String getServerRoot() {
+ return mServerRoot;
+ }
+
+ public String getServerVersion() {
+ return mServerVersion;
+ }
+
+ public String getInstallDate() {
+ return mInstallDate;
+ }
+
+ public Object clone() {
+ try {
+ return new CMSServerInfo(mHost, mPort, mUserid, mPassword,
+ mServerId, mServerVersion, mInstallDate, mServerRoot, mPath);
+ } catch (EAdminException e) {
+ return null;
+ }
+ }
+
+ public Vector getInstalledSubsystems() {
+ return mSubsystem;
+ }
+
+ public void setInstalledSubsystems(Vector subsystem) {
+ mSubsystem = subsystem;
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSTableModel.java b/base/console/src/com/netscape/admin/certsrv/CMSTableModel.java
new file mode 100644
index 000000000..0afd3d0a5
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSTableModel.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.admin.certsrv;
+
+
+import java.util.*;
+import javax.swing.table.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Generic base class for the JTable data container
+ * It provides <B>FORWARD</B> listing of the data.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv
+ * @see javax.swing.table.AbstractTableModel
+ */
+public class CMSTableModel extends AbstractTableModel {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+
+ //log
+ protected static String DATE = "DATE";
+ protected static String TIME = "TIME";
+ protected static String DETAILS = "DETAILS";
+ protected static String SEVERITY = "SEVERITY";
+ protected static String SOURCE = "SOURCE";
+
+ //property table
+ protected static String ATTRIBUTE = "ATTRIBUTE";
+ protected static String VALUE = "VALUE";
+
+ //repository
+ protected static String REQUESTNO = "REQUESTNO";
+ protected static String REQUESTSTATUS = "REQUESTSTATUS";
+ protected static String REQUESTTYPE = "REQUESTTYPE";
+ protected static String RECORDNUMBER = "RECORDNUMBER";
+ protected static String STATUS = "STATUS";
+ protected static String SERIALNO = "SERIALNO";
+ protected static String VERSION = "VERSION";
+ protected static String SUBJECT = "SUBJECT";
+ protected static String SIGNALG = "SIGNALG";
+ protected static String NOTBEFORE = "NOTBEFORE";
+ protected static String NOTAFTER = "NOTAFTER";
+ protected static String NAME = "NAME";
+ protected static String DEPARTMENT = "DEPARTMENT";
+ protected static String EMAIL = "EMAIL";
+ protected static String PHONE = "PHONE";
+ protected static String OID = "OID";
+ protected static String CLASSNAME = "CLASSNAME";
+ protected static String DESC = "DESC";
+ protected static String UIMAPPER = "UIMAPPER";
+ protected static String USERID = "USERID";
+ protected static String FULLNAME = "FULLNAME";
+ protected static String CERTIFICATE = "CERTIFICATE";
+ protected static String POLICY_IMPL = "POLICY_IMPL";
+ protected static String POLICY_TYPE = "POLICY_TYPE";
+ protected static String POLICY_RULE = "POLICY_RULE";
+ protected static String PROFILE_IMPL = "PROFILE_IMPL";
+ protected static String PROFILE_RULE = "PROFILE_RULE";
+ protected static String JOBS_IMPL = "JOBS_IMPL";
+ protected static String JOBS_RULE = "JOBS_RULE";
+ protected static String PUBLISHER_IMPL = "PUBLISHER_IMPL";
+ protected static String PUBLISHER_RULE = "PUBLISHER_RULE";
+ protected static String MAPPER_IMPL = "MAPPER_IMPL";
+ protected static String MAPPER_RULE = "MAPPER_RULE";
+ protected static String RULE_IMPL = "RULE_IMPL";
+ protected static String RULE_RULE = "RULE_RULE";
+ protected static String CRLEXTS_RULE = "CRLEXTS_RULE";
+ protected static String OCSPSTORES_RULE = "OCSPSTORES_RULE";
+ protected static String LOG_IMPL = "LOG_IMPL";
+ protected static String LOG_RULE = "LOG_RULE";
+ protected static String PLUGIN = "PLUGIN";
+ protected static String RULE = "RULE";
+ protected static String CONFIG = "CONFIG";
+ protected static String SERVLETNAME = "SERVLETNAME";
+
+ //user and group
+ protected static String DEFAULTGROUP = "DEFAULTGROUP";
+ protected static String GROUPNAME = "GROUPNAME";
+ protected static String GROUPDESC = "GROUPDESC";
+ protected static String MEMBER = "MEMBER";
+
+ protected Vector _columnNames = new Vector(); // name container
+ protected Vector _tableColumns = new Vector(); // column container
+ protected ResourceBundle mResource; // resource boundle
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSTableModel() {
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ }
+
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ public int getColumnCount() {
+ return _columnNames.size();
+ }
+
+ public int getRowCount() {
+ if (getColumnCount() > 0 ) {
+ Vector v = (Vector)_tableColumns.elementAt(0);
+ return v.size();
+ }
+ return 0;
+ }
+
+ public String getColumnName(int column) {
+ if (column >= _columnNames.size())
+ return "";
+ return (String)_columnNames.elementAt(column);
+ }
+
+ public boolean isCellEditable(int row, int col) {
+ return false;
+ }
+
+ public synchronized void setValueAt(Object aValue, int row, int column) {
+ Vector col = (Vector)_tableColumns.elementAt(column);
+ col.setElementAt(aValue, row);
+ }
+
+ public synchronized Object getValueAt(int row, int col) {
+ if ( getColumnCount() > 0 ) {
+ Vector v = (Vector)_tableColumns.elementAt(col);
+ return v.elementAt(row);
+ }
+ return null;
+ }
+
+ public synchronized void removeAllRows() {
+ for (int i=0; i<_tableColumns.size(); i++) {
+ Vector v = (Vector)_tableColumns.elementAt(i);
+ v.removeAllElements();
+ }
+ fireTableDataChanged();
+ }
+
+ /**
+ * add specified data to the end of the table
+ */
+ public synchronized void addRow(Vector values) {
+ for (int i=0; i < values.size(); i++) {
+ Vector v = (Vector)_tableColumns.elementAt(i);
+ v.addElement(values.elementAt(i));
+ }
+ fireTableDataChanged();
+ }
+
+ /**
+ * remove specified row at index position
+ */
+ public void removeRow(int index)
+ throws ArrayIndexOutOfBoundsException
+ {
+ for (int i=0; i < _tableColumns.size(); i++) {
+ Vector v = (Vector)_tableColumns.elementAt(i);
+ v.removeElementAt(index);
+ }
+ fireTableDataChanged();
+ }
+
+ public synchronized void addColumn(String name) {
+ _columnNames.addElement(name);
+ _tableColumns.addElement(new Vector());
+ }
+
+ public Class getColumnClass(int c) {
+ return getValueAt(0, c).getClass();
+ }
+
+ /**
+ * Returns detail information for a given cell. If the Object
+ * is a Component, it is set in the detail pane, otherwise the
+ * toString() value of object is displayed as text.
+ * Called by LogViewer
+ */
+ public Object getDetailInfo(int column, int row) {
+ return null;
+ }
+
+ /**
+ * Returns a boolean value indicating whether any log data
+ * has detail information.
+ * Called by LogViewer
+ */
+ public boolean hasDetailInfo() {
+ return false;
+ }
+
+ /**
+ * Returns a component that displays a log filter.
+ * Called by LogViewer
+ *
+ public IFilterComponent getFilterComponent(Object viewInstance) {
+ return (IFilterComponent)null;
+ }
+ */
+
+ /**
+ * Sets an object representing a log filter. This object
+ * is obtained from the IFilterComponent.
+ * Called by LogViewer
+ */
+ public void setFilter(Object viewInstance, Object filter) {
+ }
+
+ /**
+ * Notification that the log should be updated.
+ * Called by LogViewer
+ */
+ public void updateNow(Object viewInstance) {
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+
+ /**
+ * Initialize the column headings
+ */
+ protected void init(String[] column ) {
+ for( int i = 0; i < column.length; i++ ) {
+ String name;
+ try {
+ name = mResource.getString("LOG_COLUMN_"+column[i]+"_LABEL");
+ } catch (MissingResourceException e) {
+ name = "Missing Label";
+ }
+ //Debug.println("LogDataModel: init() - add Column: "+name);
+ addColumn( name );
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSTaskModel.java b/base/console/src/com/netscape/admin/certsrv/CMSTaskModel.java
new file mode 100644
index 000000000..c3451609d
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSTaskModel.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.admin.certsrv;
+
+import java.util.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.tree.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.security.KeyCertWizard;
+import com.netscape.admin.certsrv.security.CertManagementDialog;
+import com.netscape.admin.certsrv.security.PKCS11ManagementDialog;
+import com.netscape.management.client.preferences.*;
+import netscape.ldap.*;
+
+/**
+ * Certificate Server 4.0 Task Model
+ *
+ * @author Jack Pan-Chen
+ * @author Thomas Kwan
+ * @version $Revision$, $Date$
+ * @date 02/04/97
+ */
+public class CMSTaskModel extends TaskModel implements IMenuInfo {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static String PREFIX = "CMSTASKMODEL_NODE_";
+
+ private static final String PREFERENCES_TASK_TAB = "TaskTab";
+ private static final String PREFERENCES_TASK_LIST = "TaskList";
+
+ static public String MENU_KEYCERT = CMSAdminResources.MENU_KEYCERT;
+ static public String MENU_KEYCERT_MANAGEMENT =
+ CMSAdminResources.MENU_KEYCERT_MANAGEMENT;
+ static public String MENU_PKCS11 = CMSAdminResources.MENU_PKCS11;
+ static public String REF_TASKMODEL = "CMSTASKMODEL";
+
+ protected ITaskObject mSelection;
+ private ConsoleInfo mConsoleInfo;
+ private ResourceBundle mResource;
+ private CMSServerInfo mServerInfo = null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ public CMSTaskModel(ConsoleInfo ci, CMSServerInfo serverInfo) {
+ mServerInfo = serverInfo;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mConsoleInfo = ci;
+ init();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * getServerInfo()
+ */
+ public CMSServerInfo getServerInfo() {
+ return mServerInfo;
+ }
+
+ /**
+ * Returns supported menu categories
+ */
+ public String[] getMenuCategoryIDs() {
+ return new String[] {
+ Framework.MENU_FILE
+ };
+ }
+
+ /**
+ * add menu items for this page.
+ */
+ public IMenuItem[] getMenuItems(String categoryID) {
+ if(categoryID.equals(Framework.MENU_FILE)) {
+ return new IMenuItem[] {
+ //getMenuItemText(MENU_KEYCERT),
+ //getMenuItemText(MENU_KEYCERT_MANAGEMENT),
+ // getMenuItemText(MENU_PKCS11),
+ new MenuItemSeparator()
+ };
+ }
+ return null;
+ }
+
+ public void actionObjectSelected(IPage viewInstance,
+ ITaskObject selection,
+ ITaskObject previousSelection) {
+ super.actionObjectSelected(viewInstance, selection, previousSelection);
+ mSelection = selection;
+ }
+
+ /**
+ * Notification that a menu item has been selected.
+ */
+ public void actionMenuSelected(IPage viewInstance, IMenuItem item) {
+
+ if(item.getID().equals(MENU_KEYCERT)) {
+ KeyCertWizard wizard = new KeyCertWizard(mConsoleInfo);
+ } else if(item.getID().equals(MENU_KEYCERT_MANAGEMENT)) {
+ (new CertManagementDialog( mConsoleInfo )).showModal();
+ } else if(item.getID().equals(MENU_PKCS11)){
+ (new PKCS11ManagementDialog( mConsoleInfo )).showModal();
+ }
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ private MenuItemText getMenuItemText(String keyword) {
+ String name = mResource.getString("GENERAL_MENU_"+keyword+"_LABEL");
+ if (name == null)
+ name = "Missing Label";
+ String desc = mResource.getString("GENERAL_MENU_"+keyword+"_DESC");
+ if (desc == null)
+ desc = " ";
+ return new MenuItemText( keyword, name, desc);
+ }
+
+ private void init() {
+ TaskObject root = new TaskObject( "root", mConsoleInfo );
+ root.setAllowsChildren(true);
+ String serverDN = mConsoleInfo.getCurrentDN();
+ if ( serverDN != null ) {
+ /* Check if there is a list of tasks */
+ String order = findTaskOrder( serverDN );
+
+ /* Accumulate tasks in a hash table */
+ Hashtable list = new Hashtable();
+ Debug.println( "CMSTaskModel.init: Searching for tasks under " +
+ serverDN );
+ findTasks(root, serverDN, list );
+ /* Need to go up one from the instance entry, to get non-instance-
+ specific task entries. */
+ serverDN = "cn=Tasks," +
+ new netscape.ldap.util.DN(
+ mConsoleInfo.getCurrentDN() ).getParent().toString();
+ Debug.println( "CMSTaskModel.init: Searching for tasks under " +
+ serverDN );
+ findTasks(root, serverDN, list );
+
+ /* Now sort them by preferred order, or just list them as found */
+ if ( order != null ) {
+ StringTokenizer st = new StringTokenizer( order, " " );
+ while( st.hasMoreTokens() ) {
+ TaskObject task = (TaskObject)list.get( st.nextToken() );
+ if ( task != null ) {
+ root.add(task);
+ }
+ }
+ } else {
+ Enumeration en = list.elements();
+ while( en.hasMoreElements() ) {
+ root.add( (TaskObject)en.nextElement() );
+ }
+ }
+ } else {
+ Debug.println( "CMSTaskModel.init: no currentDN" );
+ }
+ setRoot(root);
+ }
+
+ private void findTasks(TaskObject root, String base, Hashtable list ) {
+ // connect to the DS and search for task information
+ LDAPConnection ldc = mConsoleInfo.getLDAPConnection();
+ if ( ldc == null)
+ return;
+ try {
+ String[] attrs = {"nsclassname", "nsexecref"};
+ LDAPSearchResults result =
+ ldc.search( base, ldc.SCOPE_SUB,
+ "(objectclass=nstask)",
+ attrs, false );
+
+ while ( result.hasMoreElements() ) {
+ String sJavaClassName = null;
+ LDAPEntry findEntry = (LDAPEntry)result.nextElement();
+ Debug.println( "Found task " + findEntry.getDN() );
+ LDAPAttribute anAttr =
+ findEntry.getAttribute( attrs[0] );
+ if ( anAttr != null )
+ sJavaClassName =
+ LDAPUtil.flatting( anAttr.getStringValues() );
+ if ( sJavaClassName != null ) {
+ // load the associated task class file
+ try {
+ Class c =
+ ClassLoaderUtil.getClass(mConsoleInfo,
+ sJavaClassName);
+ TaskObject task = (TaskObject)c.newInstance();
+ ConsoleInfo taskConsoleInfo =
+ (ConsoleInfo)mConsoleInfo.clone();
+ taskConsoleInfo.setCurrentDN(findEntry.getDN());
+ /* Add a listener interface for
+ authentication changes */
+ Vector v = new Vector(1);
+ anAttr = findEntry.getAttribute( attrs[1] );
+ if ( anAttr != null ) {
+ String s = LDAPUtil.flatting(
+ anAttr.getStringValues() );
+ taskConsoleInfo.put( "execref", s );
+ }
+ taskConsoleInfo.put(REF_TASKMODEL, this );
+ task.setConsoleInfo(taskConsoleInfo);
+ Debug.println( "CMSSTaskModel.init: Found task " +
+ task );
+ String[] rdns =
+ LDAPDN.explodeDN( findEntry.getDN(), true );
+ list.put( rdns[0], task );
+ } catch (Exception e) {
+ Debug.println("CMSTaskModel.findTasks: could not " +
+ "load class: " + sJavaClassName + ", " +
+ e);
+ // This implicitly means that this task should
+ // not show up in
+ // in the Task list.
+ }
+ }
+ }
+ } catch ( LDAPException e ) {
+ Debug.println( "CMSTaskModel.findTasks: " + e.toString() );
+ }
+ }
+
+ //get task orders
+ private String findTaskOrder( String base ) {
+ String order = null;
+ /* See if there is a personal preference set */
+ PreferenceManager pm =
+ PreferenceManager.getPreferenceManager(Framework.IDENTIFIER,
+ Framework.VERSION);
+ Preferences p = pm.getPreferences(PREFERENCES_TASK_TAB);
+ if ( p != null ) {
+ order = p.getString( PREFERENCES_TASK_LIST );
+ if ( (order != null) && (order.trim().length() > 0) ) {
+ return order;
+ } else {
+ order = null;
+ }
+ }
+
+ LDAPConnection ldc = mConsoleInfo.getLDAPConnection();
+ if ( ldc == null ) {
+ return null;
+ }
+ /* Check if there is a list */
+ try {
+ String dn = "cn=task summary, cn=Operation, cn=Tasks," + base;
+ String[] attrs = {"description"};
+ LDAPEntry entry = ldc.read( dn, attrs );
+ if ( entry != null ) {
+ LDAPAttribute attr = entry.getAttribute( attrs[0] );
+ if ( attr != null ) {
+ order = (String)attr.getStringValues().nextElement();
+ }
+ }
+ } catch ( LDAPException ex ) {
+ Debug.println( "CMSTaskModel.findTaskOrder: no list of tasks, " +
+ ex );
+ }
+ return order;
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSTaskObject.java b/base/console/src/com/netscape/admin/certsrv/CMSTaskObject.java
new file mode 100644
index 000000000..5999ab833
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSTaskObject.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.admin.certsrv;
+
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+/**
+ * Represents the task entry on the task Tab.
+ *
+ * @author Thomas Kwan
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.management.client.TaskObject
+ */
+public class CMSTaskObject extends TaskObject
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private CMSServerInfo mServerInfo = null; // server info
+ protected ResourceBundle mResource;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSTaskObject() {
+ super();
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ }
+
+ public CMSTaskObject(CMSServerInfo serverInfo, String name,
+ ConsoleInfo info) {
+ super(name, info);
+ mServerInfo = serverInfo;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void setServerInfo(CMSServerInfo i) {
+ mServerInfo = i;
+ }
+
+ public CMSServerInfo getServerInfo() {
+ return mServerInfo;
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CMSUIFramework.java b/base/console/src/com/netscape/admin/certsrv/CMSUIFramework.java
new file mode 100644
index 000000000..13028b003
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CMSUIFramework.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.admin.certsrv;
+
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.client.console.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+
+/**
+ * Netscape Certificate Server 4.0 UI Framework
+ *
+ * This class is responsible for the loading of UI components associated with
+ * the certificate server.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @date 03/30/97
+ */
+public class CMSUIFramework {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private ConsoleInfo mConsoleInfo; // global information
+ private CMSServerInfo mServerInfo; // server-specific information
+ private CMSPageFeeder mPageFeeder; // KP PageFeeder
+ private Framework mFramework; // KP Framework
+ private ISubSystemLocator mSubSystemLocator = null; // subsystem locator
+ private UILoaderRegistry mUILoaders;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSUIFramework(ConsoleInfo info, CMSServerInfo serverInfo)
+ throws EAdminException
+ {
+ mConsoleInfo = info;
+ mServerInfo = serverInfo;
+ mPageFeeder = new CMSPageFeeder(info, serverInfo);
+ setSubSystemLocator( new HTTPSSubSystemLocator(serverInfo.getAdmin()));
+ init();
+ //framework must be created as the last components
+ //we are not able to change the components of the
+ //pages after creating the framework.
+ mFramework = new Framework(mPageFeeder);
+ mPageFeeder.expendPages();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void setSubSystemLocator(ISubSystemLocator locator) {
+ mSubSystemLocator = locator;
+ }
+
+ public IPage getPage(String type, String name) throws EAdminException {
+ return mPageFeeder.getPage(type, name);
+ }
+
+ public Framework getFramework() {
+ return mFramework;
+ }
+
+ public boolean isNTEnv() throws EAdminException {
+ Debug.println("CMSUIFramework - isNTEnv()");
+ NameValuePairs response;
+ AdminConnection conn = mServerInfo.getAdmin();
+ response = conn.search(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_PLATFORM, new NameValuePairs());
+ if (response == null)
+ throw new EAdminException("PROTOCOL_ERROR",false);
+ if (response.get(Constants.PR_NT).equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+ private void init() throws EAdminException {
+ //initialize the kernel UI
+ CMSKernelUILoader kernelUI = new CMSKernelUILoader(this);
+ kernelUI.register();
+
+ //load subsystem information. if no locator specified use default
+ if (mSubSystemLocator == null)
+ mSubSystemLocator = new DefaultSubSystemLocator();
+ SubSystemInfo[] subsystems = mSubSystemLocator.getInstalledSubSystem();
+
+ //delegate UI loading to each subsystem loader
+ UILoaderRegistry registry = new UILoaderRegistry(this);
+ Vector subsystemList = new Vector();
+ for (int i=0; i< subsystems.length; i++) {
+ try {
+ subsystemList.addElement(subsystems[i].mType);
+ ISubSystemUILoader loader = registry.getUILoader(subsystems[i].mType);
+ loader.register();
+ } catch (Exception e) {
+ Debug.println("Error loading subsystem UI - "+e.toString());
+ }
+ }
+
+ //set subsystem setting
+ mServerInfo.setInstalledSubsystems(subsystemList);
+ }
+
+}
+
+//=====================================================================
+
+/**
+ * Registry for the Subsystem UI loader.
+ * Only single instance of the UI loader should be created.
+ */
+class UILoaderRegistry {
+ private final String PREFIX = "UILOADERREGISTRY_";
+ private Hashtable mContent = new Hashtable();
+ private ResourceBundle mResource; // resource boundle
+
+ public UILoaderRegistry(CMSUIFramework uiFramework) {
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mContent.put(Constants.PR_CA_INSTANCE,new CMSCAUILoader(uiFramework));
+ mContent.put(Constants.PR_KRA_INSTANCE,new CMSEAUILoader(uiFramework));
+ mContent.put(Constants.PR_RA_INSTANCE,new CMSRAUILoader(uiFramework));
+ mContent.put(Constants.PR_OCSP_INSTANCE,new CMSOCSPUILoader(uiFramework));
+ //mContent.put("ccm",new CMSCCMUILoader(uiFramework));
+ }
+
+ public ISubSystemUILoader getUILoader(String type) throws EAdminException {
+ if (!mContent.containsKey(type)) {
+ Debug.println("Error Loading Subsystem UI Loader");
+ return null;
+ }
+ return (ISubSystemUILoader) mContent.get(type);
+ }
+}
+
+//============================================================================
+
+/**
+ * Info container for the sub system
+ */
+class SubSystemInfo {
+ String mType;
+ String mNickName;
+}
+
+/**
+ * Interface for the sub system UI loader
+ */
+interface ISubSystemLocator {
+ public SubSystemInfo[] getInstalledSubSystem() throws EAdminException;
+}
+
+//XXX DUMMY that just returned with all components
+//XXX installed on the srever side
+class DefaultSubSystemLocator implements ISubSystemLocator {
+
+ public SubSystemInfo[] getInstalledSubSystem() throws EAdminException {
+ SubSystemInfo[] subsystems = new SubSystemInfo[4];
+ for (int i=0; i< subsystems.length; i++)
+ subsystems[i] = new SubSystemInfo();
+ subsystems[0].mType=Constants.PR_CA_INSTANCE;
+ subsystems[1].mType=Constants.PR_RA_INSTANCE;
+ subsystems[2].mType=Constants.PR_KRA_INSTANCE;
+ subsystems[3].mType=Constants.PR_OCSP_INSTANCE;
+ //subsystems[3].mType="ccm";
+ if (true)
+ return subsystems;
+ //this should never be called
+ throw new EAdminException("DefaultSubSystemLocator - error loading",true);
+ }
+}
+
+/**
+ * This is the one actually used to communicate with the
+ * server side and retreive the subsystem actually loaded
+ */
+class HTTPSSubSystemLocator implements ISubSystemLocator {
+ private AdminConnection mConnection;
+
+ public HTTPSSubSystemLocator(AdminConnection conn) {
+ mConnection = conn;
+ }
+
+ public SubSystemInfo[] getInstalledSubSystem() throws EAdminException {
+ NameValuePairs input = getSubSystem();
+ Debug.println("getInstalledSubSystem() - "+input.toString());
+ SubSystemInfo[] subsystems = new SubSystemInfo[input.size()];
+ int i =0;
+ for (String entry : input.keySet()) {
+ entry = entry.trim();
+ String value = input.get(entry);
+ subsystems[i] = new SubSystemInfo();
+ subsystems[i].mType = value;
+ subsystems[i].mNickName = entry;
+ i++;
+ }
+ return subsystems;
+ }
+
+ private NameValuePairs getSubSystem() throws EAdminException {
+ Debug.println("CMSUIFramework - getSubSystem() - started");
+ NameValuePairs response;
+ response = mConnection.search(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_SUBSYSTEM,
+ new NameValuePairs());
+ if (response == null) {
+ throw new EAdminException("PROTOCOL_ERROR",false);
+ }
+ Debug.println("CMSUIFramework - getSubSystem() - completed");
+ return response;
+ }
+
+}
+
+/*
+//XXX TBD Read the SubSystem installation information
+//XXX from the SIE entry.
+class SIESubSystemLocator implements ISubSystemLocator {
+ public SubSystemInfo[] getInstalledSubSystem() {
+ }
+}
+*/
diff --git a/base/console/src/com/netscape/admin/certsrv/CellEditorData.java b/base/console/src/com/netscape/admin/certsrv/CellEditorData.java
new file mode 100644
index 000000000..4aeb9219a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CellEditorData.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.admin.certsrv;
+
+/**
+ * Table Cell Editor Data Structure. Since we need to display different
+ * editor depending on serverside input. We will use this editor
+ * data to specify data and UI type
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv
+ */
+public class CellEditorData {
+ public Object mData;
+ public String mType;
+} \ No newline at end of file
diff --git a/base/console/src/com/netscape/admin/certsrv/Console.java b/base/console/src/com/netscape/admin/certsrv/Console.java
new file mode 100644
index 000000000..c9684583a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/Console.java
@@ -0,0 +1,1861 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.io.*;
+import java.text.MessageFormat;
+import java.net.URL;
+import java.net.MalformedURLException;
+
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.border.*;
+
+import com.netscape.management.client.console.*;
+import com.netscape.management.nmclf.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.preferences.*;
+import com.netscape.management.client.components.*;
+import com.netscape.management.client.topology.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.client.cmd.*;
+import com.netscape.management.client.ug.*;
+import com.netscape.management.client.comm.*;
+
+import netscape.ldap.*;
+import netscape.ldap.util.DN;
+
+/**
+ * To start standard CS console, issue the following command
+ *
+ * /export/nkwan/s71/bin/base/jre/bin/java -ms8m -mx64m -cp .:./ldapjdk.jar:./base.jar:./jss3.jar:./mcc70_en.jar:./mcc70.jar:./nmclf70_en.jar:./nmclf70.jar:./jars/cms71.jar:./jars/cms71_en.jar -Djava.library.path=/export/nkwan/s71/lib/jss -Djava.util.prefs.systemRoot=/export/nkwan/s71/java/.java -Djava.util.prefs.userRoot=/export/nkwan/s71/java com.netscape.admin.certsrv.Console -D -s instanceID -a http://water:8200
+ *
+ */
+public class Console implements CommClient {
+ // Capture the time before any class is loaded so that we can measure JVM load time
+ static long _t0 = System.currentTimeMillis();
+
+ //
+ // preference information
+ //
+ public static final String IDENTIFIER = "Console";
+ public static final String VERSION = "4.0";
+ public static final String PREFERENCES_LOGIN =
+ IDENTIFIER + "." + VERSION + ".Login.preferences";
+
+ public static final String PREFERENCE_UID = "UserID";
+ public static final String PREFERENCE_REMEMBER_UID =
+ "Remember" + PREFERENCE_UID;
+ public static final String PREFERENCE_URL = "HostURL";
+ public static final String PREFERENCE_LOCAL = "StorePrefsToDisk";
+ public static final String PREFERENCE_X = "X";
+ public static final String PREFERENCE_Y = "Y";
+
+ public static final String OPTION_NOWINPOS = "nowinpos";
+ public static final String OPTION_NOLOGO = "nologo";
+ public static final String OPTION_JAVALAF = "javalaf";
+
+ public static final int MAX_RECENT_URLS = 5;
+
+ protected static final double MIN_CONTEXT_HELP_VERSION = 4.5;
+
+ //
+ // global values
+ //
+ public static Preferences _preferences;
+ public static ConsoleInfo _info;
+ public static String _consoleAdminURL;
+ public static ResourceSet _resource = new ResourceSet("com.netscape.management.client.console.console");
+
+ //
+ // private values
+ //
+ private String _adminServerSIE;
+ private JFrame _frame = null;
+ private com.netscape.management.client.console.SplashScreen _splashScreen = null;
+ private static boolean _showSplashScreen = true;
+ private static boolean _useJavaLookAndFeel = false;
+
+ // return valued from LDAPinitialization() method
+ private static final int LDAP_INIT_OK = 0;
+ private static final int LDAP_INIT_FAILED = 1;
+ private static final int LDAP_INIT_DS_RESTART = 2;
+ //user password expired, or removed on DS, but admin
+ //server still cached the user (user login before the
+ //passowrd expired, or invalid).
+ private static final int LDAP_INIT_BIND_FAIL = 3;
+
+ // A flag used by LDAPinitialization() to know whether to try to restart DS
+ // if ConsoleInfo.setLDAPConnection() has failed
+ private boolean _dsHasBeenRestarted = false;
+
+ // Track the version of the admin server
+ private String _adminVersion = null;
+
+ //
+ // check whether the preference file exist or not
+ //
+ static {
+ if (_preferences == null)
+ _preferences = new FilePreferences(PREFERENCES_LOGIN);
+ }
+
+ private static final boolean _isWindows =
+ System.getProperty("os.name").startsWith("Windows");
+
+ public static void loadFontPreferences() {
+ return;
+ }
+
+ /**
+ * common initialization routine.
+ *
+ * @param language language string. For example, "en" for english
+ */
+ protected static void common_init(String language) {
+ Locale.setDefault(
+ new Locale(language, Locale.getDefault().getCountry()));
+
+ try {
+
+ // bug 115085: init calls needs to be inside the try block as, on Unix, during
+ // initialization any call to java.awt.* will cause an exception to be thrown
+ // if Xserver is not accessable. The jvm prints correctly the error message about
+ // unaccessable Xserver but exception stack trace makes it less readable
+
+ if (_info == null)
+ _info = new ConsoleInfo();
+
+ PreferenceManager.setLocalStorageFlag(
+ _preferences.getBoolean(PREFERENCE_LOCAL, false));
+
+ if (!_useJavaLookAndFeel) {
+ SuiLookAndFeel nmclf = new SuiLookAndFeel();
+ UIManager.setLookAndFeel(nmclf);
+
+ // With JDK1.4 on Unix, the first instance of JFileChooser
+ // has an incorrect layout for some of the buttons. Create
+ // and discard an instance.
+ if (!_isWindows) {
+ Object o = new JFileChooser();
+ o = null;
+ }
+ }
+ FontFactory.initializeLFFonts(); // load default customized fonts for login/splash
+
+ } catch (InternalError ie) {
+ System.err.println("Console: " + ie.getMessage());
+ System.exit(1);
+ }
+ catch (Exception e) {
+ Debug.println("Console.common_init: Cannot init " + e);
+ }
+ }
+
+ /**
+ * return the console info object
+ *
+ * @return return the global console info object
+ */
+ public static ConsoleInfo getConsoleInfo() {
+ return _info;
+ }
+
+ /**
+ * set the global console info object.
+ *
+ * @param info consoleInfo object to be set as global console info
+ */
+ public static void setConsoleInfo(ConsoleInfo info) {
+ _info = info;
+ }
+
+ /**
+ * return whether the preferences is set or not
+ *
+ * @return true is the preference is set. false otherwise.
+ */
+ public static boolean canSetLocalPreferencesFlag() {
+ return (_preferences != null);
+ }
+
+ /**
+ * set the local preference flag
+ *
+ * @param b preference flag
+ */
+ public static void setLocalPreferencesFlag(boolean b) {
+ if (_preferences != null) {
+ _preferences.set(PREFERENCE_LOCAL, b);
+ _preferences.save();
+ }
+ }
+
+ /**
+ * return the local preference flag
+ *
+ * @return local preference flag
+ */
+ public static boolean getLocalPreferencesFlag() {
+ if (_preferences != null)
+ return _preferences.getBoolean(PREFERENCE_LOCAL);
+ return true;
+ }
+
+ /**
+ * by given the ldap connection and the server DN, it will find out the admin server for that server.
+ *
+ * @param ldc ldap connection
+ * @param serverDN dn of the server
+ * @return full URL of the admin server. It will return null if it cannot find uidthe admin server.
+ */
+ protected String getInstanceAdminURL(LDAPConnection ldc,
+ String serverDN) {
+ ServiceLocator sl = new ServiceLocator(_info);
+ String dn=null;
+ try {
+ String productDN =
+ serverDN.substring(serverDN.indexOf(',') + 1);
+ String ss40DN = productDN.substring(productDN.indexOf(',') + 1);
+ String adminServerDN = sl.getAdminServer(ss40DN);
+ if (adminServerDN == null) {
+ Debug.println(
+ "ERROR ConsoleInfo.getInstanceAdminURL: could not get admin server entry = " +
+ ss40DN);
+ return null;
+ }
+
+ String configDN = "cn=configuration," + adminServerDN;
+ LDAPEntry configEntry = ldc.read(dn=configDN);
+ if (configEntry == null) {
+ Debug.println(
+ "ERROR ConsoleInfo.getInstanceAdminURL: could not get admin server config entry = " +
+ configDN);
+ return null;
+ }
+
+ String host = LDAPUtil.flatting(
+ configEntry.getAttribute("nsserveraddress"));
+ String port = LDAPUtil.flatting(
+ configEntry.getAttribute("nsServerport"));
+ boolean securityOn = (LDAPUtil.flatting(
+ configEntry.getAttribute("nsServersecurity"))).
+ equalsIgnoreCase("on");
+
+ /*
+ * nsserveraddress might not be defined, which means that the
+ * admin server should listen on all interfaces rather than on
+ * a specific one. Read serverhostname from the SIE entry.
+ */
+ if (host == null || host.trim().length() == 0) {
+ LDAPEntry sieEntry = ldc.read(dn=adminServerDN, new String[] {"serverhostname"});
+ if (sieEntry == null) {
+ Debug.println("ERROR Console.getInstanceAdminURL: " +
+ "could not get serverhostname from " + adminServerDN);
+ return null;
+ }
+ host = LDAPUtil.flatting(sieEntry.getAttribute("serverhostname"));
+ }
+
+ String url = "http";
+ if (securityOn) {
+ url = url + "s";
+ }
+ url = url + "://" + host + ":" + port + "/";
+ return url;
+ } catch (LDAPException e) {
+ Debug.println("ERROR Console.getInstanceAdminURL: " +
+ "LDAP error " + e + " dn=" + dn);
+ }
+ return null;
+ }
+
+ /**
+ * get the OS type of the admin server.
+ *
+ * @param ldc ldap connection
+ * @param serverDN DN of the admin server
+ * @return os type of the admin server
+ */
+ protected String getInstanceAdminOS(LDAPConnection ldc,
+ String serverDN) {
+ try {
+ String productDN =
+ serverDN.substring(serverDN.indexOf(',') + 1);
+ String ss40DN = productDN.substring(productDN.indexOf(',') + 1);
+ String hostDN = ss40DN.substring(ss40DN.indexOf(',') + 1);
+
+ LDAPEntry hostEntry = ldc.read(hostDN);
+ if (hostEntry == null) {
+ Debug.println(
+ "ERROR ConsoleInfo.getInstanceAdminOS: could not get host entry = " +
+ hostDN);
+ return null;
+ }
+
+ String osVersion = LDAPUtil.flatting(
+ hostEntry.getAttribute("nsosversion",
+ LDAPUtil.getLDAPAttributeLocale()));
+ return osVersion;
+ } catch (LDAPException e) {
+ Debug.println(
+ "ERROR ConsoleInfo.getInstanceAdminOS: LDAP error " + e);
+ }
+ return null;
+ }
+
+ /**
+ * A helper method to find an SIE DN from its ID. See -s Console option.
+ * Called by createPerInstanceUI().
+ */
+ private String serverIDtoDN(String id) {
+
+ LDAPConnection ldc = _info.getLDAPConnection();
+ Vector instances = new Vector();
+
+ try {
+ LDAPSearchResults res = ldc.search(
+ "o=netscapeRoot",
+ LDAPConnection.SCOPE_SUB,
+ "(nsServerID=" + id + ")",
+ new String[]{"dn"}, false);
+
+ while (res.hasMoreElements()) {
+ LDAPEntry hostEntry = res.next();
+ instances.addElement(hostEntry.getDN());
+ }
+
+ if (instances.size() == 0) {
+ System.err.println("Server instance " + id + " does not exist.");
+ System.exit(0);
+ }
+ else if (instances.size() == 1) {
+ id = (String) instances.elementAt(0);
+ }
+ else {
+
+ if (_splashScreen != null) {
+ _splashScreen.setVisible(false);
+ }
+
+ int idx = -1;
+ while (idx == -1) {
+ System.out.println("\nThere are multiple instances of server \"" + id + "\":\n");
+ for (int i=0; i < instances.size(); i++) {
+ System.out.println( (i+1) + ") " + instances.elementAt(i));
+ }
+ System.out.print("\nPlease select an instance form the above list [1]: ");
+ try {
+ String rsp = new BufferedReader(new InputStreamReader(System.in)).readLine();
+ if (rsp.length() == 0) {
+ idx = 1;
+ }
+ else {
+ try {
+ idx = Integer.parseInt(rsp);
+ }
+ catch (Exception ignore) {}
+ }
+
+ if (idx >=1 && idx <= instances.size()) {
+ idx = idx - 1;
+ }
+ else {
+ idx = -1;
+ }
+ }
+ catch (Exception e) {
+ break;
+ }
+ }
+ id = (String) instances.elementAt(idx);
+ }
+ }
+ catch (Exception e) {
+ if (Debug.isEnabled()) {
+ e.printStackTrace();
+ }
+ }
+ return id;
+ }
+
+ protected void createPerInstanceUI(String host) {
+
+ if (!DN.isDN(host)) {
+ host = serverIDtoDN(host);
+ }
+
+ LDAPConnection ldc = _info.getLDAPConnection();
+ String configDN = "cn=configuration," + host;
+ try {
+ LDAPEntry configEntry = ldc.read(configDN);
+ String className = LDAPUtil.flatting(
+ configEntry.getAttribute("nsclassname",
+ LDAPUtil.getLDAPAttributeLocale()));
+ if (className == null) {
+ Debug.println(
+ "ERROR Console: no 'nsclassname' attribute in " +
+ configDN);
+ System.exit(0);
+ }
+
+ String adminURL = getInstanceAdminURL(ldc, host);
+ if (adminURL == null) {
+ Debug.println(
+ "ERROR Console: could not set the adminURL for " +
+ host);
+ } else {
+ _info.setAdminURL(adminURL);
+ }
+
+ String adminOS = getInstanceAdminOS(ldc, host);
+ if (adminOS == null) {
+ Debug.println(
+ "ERROR Console.constructor: could not set the adminOS for " +
+ host);
+ } else {
+ _info.setAdminOS(adminOS);
+ }
+ _info.setCurrentDN(host);
+
+ Class c = ClassLoaderUtil.getClass(_info, className);
+ if (c == null) {
+ Debug.println(
+ "ERROR Console.constructor: could not get class " +
+ className);
+ System.exit(0);
+ }
+
+ try {
+ Hashtable topologyplugin =
+ TopologyInitializer.getTopologyPluginFromDS( _info);
+ Enumeration ePlugins = topologyplugin.elements();
+ while (ePlugins.hasMoreElements()) {
+ ITopologyPlugin plugin =
+ (ITopologyPlugin) ePlugins.nextElement();
+ ResourceObject resObj =
+ plugin.getResourceObjectByID(host);
+ if (resObj != null) {
+ if (resObj instanceof ServerNode) {
+
+ ServerNode srvNode = ((ServerNode) resObj);
+ IServerObject srvObj = null;
+
+ // ServerNode is loaded asynchronously
+ srvNode.reload();
+ while ((srvObj=srvNode.getServerObject()) == null) {
+ try { Thread.sleep(200); } catch (Exception e) {}
+ }
+ IResourceObject sel[] = new IResourceObject[1];
+ sel[0] = srvObj;
+ srvObj.run((IPage) null, sel);
+ return;
+ } else if (resObj instanceof ServerNode) {
+ }
+ }
+ }
+ Debug.println("ERROR Console.constructor: cannot find associated plugin for "+
+ host);
+ } catch (Exception e) {
+ if (Debug.isEnabled()) {
+ e.printStackTrace();
+ }
+ Debug.println(
+ "ERROR Console.constructor: could not create " +
+ className);
+ Debug.println(" Exception: " + e);
+ }
+ } catch (LDAPException e) {
+ if (Debug.isEnabled()) {
+ e.printStackTrace();
+ }
+ Debug.println("ERROR Console.constructor: createServerInstance failed");
+ Debug.println(" LDAPException: " + e);
+ }
+ System.exit(0);
+ }
+
+ public Console(String adminURL, String localAdminURL, String language, String host, String uid, String passwd) {
+ Vector recentURLs = new Vector();
+ String lastUsedURL;
+ common_init(language);
+ String userid = uid;
+ String password = passwd;
+
+ if (userid == null) {
+ userid = _preferences.getString(PREFERENCE_UID);
+ }
+
+ lastUsedURL = _preferences.getString(PREFERENCE_URL);
+ if(lastUsedURL != null) {
+ recentURLs.addElement(lastUsedURL);
+ if(adminURL == null) {
+ adminURL = lastUsedURL;
+ }
+ }
+
+ if(adminURL == null) {
+ adminURL = localAdminURL;
+ }
+
+ for(int count = 1; count < MAX_RECENT_URLS; count++) {
+ String temp;
+ temp = _preferences.getString(PREFERENCE_URL+Integer.toString(count));
+ if(temp != null && temp.length() > 0)
+ recentURLs.addElement(temp);
+ }
+
+ _frame = new JFrame();
+ // Set the icon image so that login dialog will inherit it
+ _frame.setIconImage( new RemoteImage("com/netscape/management/client/images/logo16.gif").getImage());
+
+ ModalDialogUtil.setWindowLocation(_frame);
+
+ //enable server auth
+ UtilConsoleGlobals.setServerAuthEnabled(true);
+
+ _splashScreen = new com.netscape.management.client.console.SplashScreen(_frame);
+ _splashScreen.addWindowListener (new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ System.exit(0);
+ }
+ }
+ );
+ if (_showSplashScreen)
+ _splashScreen.showWindow();
+
+ boolean fSecondTry = false;
+
+ while (true) {
+ LoginDialog dialog = null;
+
+ _splashScreen.setStatusText(_resource.getString("splash","PleaseLogin"));
+ _splashScreen.setCursor(
+ Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+ if ((adminURL == null) || (userid == null) ||
+ (password == null) || (fSecondTry)) {
+ dialog = new LoginDialog(_frame, userid, adminURL, recentURLs);
+ Dimension paneSize = dialog.getSize();
+ Dimension screenSize = dialog.getToolkit().getScreenSize();
+ int centerX = (screenSize.width - paneSize.width) / 2;
+ int centerY = (screenSize.height - paneSize.height) / 2;
+ int x = _preferences.getInt(PREFERENCE_X, centerX);
+ int y = _preferences.getInt(PREFERENCE_Y, centerY);
+ UtilConsoleGlobals.setAdminURL(adminURL);
+ UtilConsoleGlobals.setAdminHelpURL(adminURL);
+ dialog.setInitialLocation(x, y);
+ _splashScreen.setCursor(
+ Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ dialog.showModal();
+ if (dialog.isCancel())
+ System.exit(0);
+ _splashScreen.setCursor(
+ Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+
+ userid = dialog.getUsername();
+ adminURL = dialog.getURL();
+ if(!adminURL.startsWith("http://") && !adminURL.startsWith("https://"))
+ adminURL = "http://" + adminURL;
+ password = dialog.getPassword();
+ }
+ fSecondTry = true;
+ UtilConsoleGlobals.setAdminURL(adminURL);
+ UtilConsoleGlobals.setAdminHelpURL(adminURL);
+ _consoleAdminURL = adminURL;
+
+ _splashScreen.setStatusText( MessageFormat.format(_resource.getString("splash", "authenticate"), new Object[]{ userid}));
+
+ if (authenticate_user(adminURL, _info, userid, password)) {
+ _splashScreen.setStatusText(
+ _resource.getString("splash","initializing"));
+
+ /**
+ * Initialize ldap. In the case config DS is down, the user can restart
+ * the DS from the Console. The Console will need to re-authenticate
+ * the user if that's the case.
+ */
+ int ldapInitResult = LDAPinitialization(_info);
+ if (ldapInitResult == LDAP_INIT_FAILED) {
+ Debug.println("Console: LDAPinitialization() failed.");
+ System.exit(1);
+ } else if (ldapInitResult == LDAP_INIT_DS_RESTART) {
+ Debug.println("Console: LDAPinitialization() DS restarted.");
+
+ // Need to re-authenticate the user
+ _splashScreen.setStatusText( MessageFormat.format(_resource.getString("splash", "authenticate"), new Object[]{ userid}));
+ if (authenticate_user(adminURL, _info, userid,
+ password)) {
+ _splashScreen.setStatusText(
+ _resource.getString("splash","initializing"));
+ if (LDAPinitialization(_info) == LDAP_INIT_FAILED) {
+ Debug.println("Console: LDAPinitialization() failed.");
+ System.exit(1);
+ }
+ } else {
+ continue; // Autentication faled, try again
+ }
+ } else if (ldapInitResult == LDAP_INIT_BIND_FAIL) {
+ continue;
+ }
+
+ boolean rememberUserid = _preferences.getBoolean(
+ PREFERENCE_REMEMBER_UID, true);
+ if (rememberUserid) {
+ _preferences.set(PREFERENCE_UID, userid);
+ _preferences.set(PREFERENCE_URL, adminURL);
+
+ String recentlyUsedURL;
+ int count = 1;
+ Enumeration urlEnum = recentURLs.elements();
+ while (urlEnum.hasMoreElements()) {
+ recentlyUsedURL = (String)urlEnum.nextElement();
+ if(!recentlyUsedURL.equals(adminURL))
+ _preferences.set(PREFERENCE_URL+Integer.toString(count++), recentlyUsedURL);
+ }
+
+ for(; count < MAX_RECENT_URLS; count++) {
+ _preferences.remove(PREFERENCE_URL+Integer.toString(count));
+ }
+
+ if (dialog != null) {
+ Point p = dialog.getLocation();
+ _preferences.set(PREFERENCE_X, p.x);
+ _preferences.set(PREFERENCE_Y, p.y);
+ dialog.dispose();
+ dialog = null;
+ }
+ _preferences.save();
+ }
+
+ initialize(_info);
+ if (host == null) {
+ Framework framework = createTopologyFrame();
+ UtilConsoleGlobals.setRootFrame(framework.getJFrame());
+ } else {
+ // popup the per server configuration UI
+ // first get the java class name
+ createPerInstanceUI(host);
+ }
+
+ _frame.dispose();
+ _splashScreen.dispose();
+ com.netscape.management.client.console.SplashScreen.removeInstance();
+ _splashScreen = null;
+
+ break;
+ }
+ }
+ }
+
+ static public Framework createTopologyFrame() {
+ if (_info != null) {
+ TopologyInitializer initializer = new TopologyInitializer(_info);
+ Framework f = new Framework(initializer);
+ UtilConsoleGlobals.setRootTopologyFrame(f.getJFrame());
+ return f;
+ }
+ return null;
+ }
+
+ public void setDomainSuffix(String adminServerSIE) {
+ String location = "";
+ if (adminServerSIE != null) {
+ String temp = adminServerSIE;
+ int index = 0;
+ for (int i = 0; i < 4; i++) {
+ index = temp.indexOf(',',index);
+ index++;
+ }
+ location = temp.substring(index);
+ LDAPUtil.setInstalledSoftwareDN(location);
+ }
+ }
+
+ /**
+ * get the user and group information.
+ *
+ * @param info console info
+ */
+ public void initialize(ConsoleInfo info) {
+ setDomainSuffix(_adminServerSIE);
+
+ LDAPConnection ldc = _info.getLDAPConnection();
+
+ if (ldc != null) {
+ String sName;
+ String sValue;
+ int iFirstQuote;
+ int iSecondQuote;
+ int iThirdQuote;
+ int iFourthQuote;
+ LDAPAttribute attribute;
+ Enumeration eAttributes;
+ String ldapLocation = "";
+ LDAPEntry entry;
+ LDAPSearchResults result;
+ LDAPSearchConstraints cons;
+
+ // get default object classes container
+ try {
+ ldapLocation = "cn=user, cn=DefaultObjectClassesContainer,"+
+ LDAPUtil.getAdminGlobalParameterEntry();
+ entry = ldc.read(ldapLocation);
+ if (entry != null) {
+ // get the new user / group class information
+ attribute = entry.getAttribute("nsDefaultObjectClass",
+ LDAPUtil.getLDAPAttributeLocale());
+
+ if (attribute != null) {
+ Vector vUserObjectClasses = new Vector();
+ eAttributes = attribute.getStringValues();
+ while (eAttributes.hasMoreElements()) {
+ String sUserObjectClass =
+ (String) eAttributes.nextElement();
+ vUserObjectClasses.addElement(
+ sUserObjectClass);
+ }
+
+ ResourceEditor.getNewObjectClasses().put(
+ ResourceEditor.KEY_NEW_USER_OBJECTCLASSES,
+ vUserObjectClasses);
+ }
+ }
+ } catch (LDAPException e) {
+ Debug.println("Console: Cannot open: "+ldapLocation);
+ }
+ if (ResourceEditor.getNewObjectClasses().get(
+ ResourceEditor.KEY_NEW_USER_OBJECTCLASSES) == null) {
+ Vector vObject = new Vector();
+ vObject.addElement("top");
+ vObject.addElement("person");
+ vObject.addElement("organizationalPerson");
+ vObject.addElement("inetorgperson");
+ ResourceEditor.getNewObjectClasses().put(
+ ResourceEditor.KEY_NEW_USER_OBJECTCLASSES, vObject);
+ }
+
+ try {
+ ldapLocation =
+ "cn=group, cn=DefaultObjectClassesContainer,"+
+ LDAPUtil.getAdminGlobalParameterEntry();
+ entry = ldc.read(ldapLocation);
+ if (entry != null) {
+ attribute = entry.getAttribute("nsDefaultObjectClass",
+ LDAPUtil.getLDAPAttributeLocale());
+
+ if (attribute != null) {
+ Vector vGroupObjectClasses = new Vector();
+ eAttributes = attribute.getStringValues();
+ while (eAttributes.hasMoreElements()) {
+ String sGroupObjectClass =
+ (String) eAttributes.nextElement();
+ vGroupObjectClasses.addElement(
+ sGroupObjectClass);
+ }
+
+ ResourceEditor.getNewObjectClasses().put(
+ ResourceEditor.KEY_NEW_GROUP_OBJECTCLASSES,
+ vGroupObjectClasses);
+ }
+ }
+ } catch (LDAPException e) {
+ Debug.println("Console: Cannot open "+ldapLocation);
+ }
+ if (ResourceEditor.getNewObjectClasses().get(
+ ResourceEditor.KEY_NEW_GROUP_OBJECTCLASSES) == null) {
+ Vector vObject = new Vector();
+ vObject.addElement("top");
+ vObject.addElement("groupofuniquenames");
+ ResourceEditor.getNewObjectClasses().put(
+ ResourceEditor.KEY_NEW_GROUP_OBJECTCLASSES,
+ vObject);
+ }
+
+ try {
+ ldapLocation = "cn=OU, cn=DefaultObjectClassesContainer,"+
+ LDAPUtil.getAdminGlobalParameterEntry();
+ entry = ldc.read(ldapLocation);
+ if (entry != null) {
+ attribute = entry.getAttribute("nsDefaultObjectClass",
+ LDAPUtil.getLDAPAttributeLocale());
+
+ if (attribute != null) {
+ Vector vOUObjectClasses = new Vector();
+ eAttributes = attribute.getStringValues();
+ while (eAttributes.hasMoreElements()) {
+ String sOUObjectClass =
+ (String) eAttributes.nextElement();
+ vOUObjectClasses.addElement(sOUObjectClass);
+ }
+
+ ResourceEditor.getNewObjectClasses().put(
+ ResourceEditor.KEY_NEW_OU_OBJECTCLASSES,
+ vOUObjectClasses);
+ }
+ }
+ } catch (LDAPException e) {
+ Debug.println("Console: Cannot open "+ldapLocation);
+ }
+ if (ResourceEditor.getNewObjectClasses().get(
+ ResourceEditor.KEY_NEW_OU_OBJECTCLASSES) == null) {
+ Vector vObject = new Vector();
+ vObject.addElement("top");
+ vObject.addElement("organizationalunit");
+ ResourceEditor.getNewObjectClasses().put(
+ ResourceEditor.KEY_NEW_OU_OBJECTCLASSES, vObject);
+ }
+
+ try {
+ cons = ldc.getSearchConstraints();
+ cons.setBatchSize(1);
+ // then get the resource editor extension
+ ldapLocation = "cn=ResourceEditorExtension,"+
+ LDAPUtil.getAdminGlobalParameterEntry();
+ result = ldc.search(ldapLocation,
+ LDAPConnection.SCOPE_ONE, "(Objectclass=nsAdminResourceEditorExtension)",
+ null, false, cons);
+ Hashtable hResourceEditorExtension = new Hashtable();
+ Hashtable deleteResourceEditorExtension = new Hashtable();
+
+ if (result != null) {
+ while (result.hasMoreElements()) {
+ LDAPEntry ExtensionEntry;
+ try {
+ ExtensionEntry = (LDAPEntry) result.next();
+ } catch (Exception e) {
+ // ldap exception
+ continue;
+ }
+
+ attribute = ExtensionEntry.getAttribute("cn",
+ LDAPUtil.getLDAPAttributeLocale());
+ Enumeration eValues = attribute.getStringValues();
+ String sCN = "";
+ while (eValues.hasMoreElements()) {
+ sCN = (String) eValues.nextElement(); // Take the first CN
+ break;
+ }
+
+ attribute =
+ ExtensionEntry.getAttribute("nsClassname",
+ LDAPUtil.getLDAPAttributeLocale());
+ if (attribute != null) {
+ eValues = attribute.getStringValues();
+ Vector vClass = new Vector();
+ while (eValues.hasMoreElements()) {
+ String sJarClassName =
+ (String) eValues.nextElement();
+ Class c = ClassLoaderUtil.getClass(
+ _info, sJarClassName);
+
+ if (c != null) {
+ vClass.addElement(c);
+ }
+ }
+ hResourceEditorExtension.put(
+ sCN.toLowerCase(), vClass);
+ }
+
+ attribute =
+ ExtensionEntry.getAttribute("nsDeleteClassname",
+ LDAPUtil.getLDAPAttributeLocale());
+ if (attribute != null) {
+ Enumeration deleteClasses =
+ attribute.getStringValues();
+ Vector deleteClassesVector = new Vector();
+ while (deleteClasses.hasMoreElements()) {
+ String jarClassname = (String)
+ deleteClasses.nextElement();
+ Class c = ClassLoaderUtil.getClass(
+ _info, jarClassname);
+ if (c != null) {
+ deleteClassesVector.addElement(c);
+ }
+ }
+ deleteResourceEditorExtension.put(
+ sCN.toLowerCase(), deleteClassesVector);
+ }
+ }
+ ResourceEditor.setResourceEditorExtension(
+ hResourceEditorExtension);
+ ResourceEditor.setDeleteResourceEditorExtension(
+ deleteResourceEditorExtension);
+ }
+
+ // set up resource editor attribute
+ ResourceEditor.setUniqueAttribute(
+ LDAPUtil.getUniqueAttribute(
+ _info.getLDAPConnection(),
+ LDAPUtil.getCommonGlobalParameterEntry()));
+
+ String sLocation = LDAPUtil.getCommonGlobalParameterEntry();
+ entry = ldc.read(sLocation);
+
+ if (entry != null) {
+ attribute = entry.getAttribute("nsUserRDNComponent");
+ String sAttribute = LDAPUtil.flatting(attribute);
+ ResourceEditor.setUserRDNComponent(sAttribute);
+ attribute = entry.getAttribute("nsUserIDFormat");
+ sAttribute = LDAPUtil.flatting(attribute);
+ ResourceEditor.setUserIDFormat(sAttribute);
+ attribute = entry.getAttribute("nsGroupRDNComponent");
+ sAttribute = LDAPUtil.flatting(attribute);
+ ResourceEditor.setGroupRDNComponent(sAttribute);
+ }
+
+ ResourceEditor.setAccountPlugin(
+ buildAccountPluginHashtable());
+
+
+ }
+ catch (LDAPException e) {
+ Debug.println("Console: Cannot open "+ldapLocation);
+ }
+
+ // this *should* already be created at install time, but just in case
+ // note: if this entry is created here, then ACIs (for non-admins) will break
+ String userPreferenceDN = LDAPUtil.createEntry(ldc,
+ LDAPUtil.getUserPreferenceOU(),
+ LDAPUtil.getInstalledSoftwareDN());
+ userPreferenceDN = LDAPUtil.createEntry(ldc,
+ "\""+_info.getAuthenticationDN() + "\"",
+ userPreferenceDN, true);
+ _info.setUserPreferenceDN(userPreferenceDN);
+ }
+ checkHelpSystem();
+ }
+
+ /**
+ * Check if the Admin Server version supports context-sensitive
+ * Help. That is the case if the version is greater than 4.2.
+ */
+ protected void checkHelpSystem() {
+ boolean hasContextHelp = false;
+ if ( _adminVersion != null ) {
+ hasContextHelp = ( Double.parseDouble( _adminVersion ) >=
+ MIN_CONTEXT_HELP_VERSION );
+ Debug.println( "Console.checkHelpSystem: contextHelp=" +
+ hasContextHelp );
+ } else {
+ Debug.println( "Console.checkHelpSystem: cannot determine " +
+ "Admin Version" );
+ }
+ UtilConsoleGlobals.setContextHelpEnabled( hasContextHelp );
+ }
+
+ /**
+ * build up the resource editor extension plugin.
+ *
+ * @return hashtable which contain all the resource editor plugin.
+ */
+ private Hashtable buildAccountPluginHashtable() {
+ Hashtable HTAccountPlugin = new Hashtable();
+ try {
+ LDAPConnection ldc = _info.getLDAPConnection();
+ String sExtension = "cn=ResourceEditorExtension, "+
+ LDAPUtil.getAdminGlobalParameterEntry();
+ String reqAttrs[] = {"cn","nsadminaccountInfo"};
+ LDAPSearchResults results =
+ ldc.search(sExtension, LDAPConnection.SCOPE_ONE, "(nsadminaccountInfo=*)",
+ reqAttrs, false);
+ if (results != null) {
+ while (results.hasMoreElements()) {
+ LDAPEntry entry;
+ try {
+ entry = (LDAPEntry) results.next();
+ } catch (Exception e) {
+ // ldap exception
+ continue;
+ }
+ LDAPAttributeSet entryAttrs = entry.getAttributeSet();
+ Enumeration attrsInSet = entryAttrs.getAttributes();
+ String sName = "";
+ Vector vJavaClass = new Vector();
+ while (attrsInSet.hasMoreElements()) {
+ LDAPAttribute nextAttr =
+ (LDAPAttribute) attrsInSet.nextElement();
+ if (nextAttr.getName().equalsIgnoreCase("cn")) {
+ sName = LDAPUtil.flatting(
+ nextAttr.getStringValues());
+ } else if (
+ nextAttr.getName().equalsIgnoreCase("nsadminaccountInfo")) {
+ String sJavaClass = LDAPUtil.flatting(
+ nextAttr.getStringValues());
+ // parse it
+ // assume it is in [xxx][xxx].. format
+ boolean fFinish = false;
+ do {
+ int iOpenBucket = sJavaClass.indexOf('[');
+ if (iOpenBucket < 0) {
+ fFinish = true;
+ } else {
+ int iCloseBucket =
+ sJavaClass.indexOf(']',
+ iOpenBucket + 1);
+ String sClassString =
+ sJavaClass.substring(
+ iOpenBucket + 1, iCloseBucket);
+ vJavaClass.addElement(sClassString);
+ sJavaClass = sJavaClass.substring(
+ iCloseBucket + 1);
+ }
+ } while (!fFinish)
+ ;
+ }
+ }
+ if (sName != null) {
+ HTAccountPlugin.put(sName.toLowerCase(),
+ vJavaClass);
+ }
+ }
+ }
+ } catch (LDAPException e) {
+ Debug.println("Console.buildAccountPluginHashtable: ResEditorAccountPage LDAP Exception: "+e);
+ }
+ return HTAccountPlugin;
+ }
+
+
+ /**
+ * New authentication method, via CGI. Authenticate the user through the admin server CGI.
+ *
+ * @param adminServerURL url of the admin server
+ * @param info console info
+ * @param user user dn
+ * @param pw user password
+ * @return true if successful. false otherwise.
+ */
+ private synchronized final boolean authenticate_user(
+ String adminServerURL, ConsoleInfo info, String user,
+ String pw) {
+ URL url;
+
+ try {
+ // DT 5/14/98 This method of URL construction provides some limited
+ // validation of the URL, and eliminates any preexisting uri component.
+ url = new URL(new URL(adminServerURL), "/admin-serv/authenticate");
+ } catch (MalformedURLException mue) {
+ Debug.println("Console:authenticate_user():Unable to create authentication URL");
+ return false;
+ }
+
+ Hashtable ht = new Hashtable();
+
+ boolean successfulAuth = invoke_task(url, user, pw, ht);
+
+ String param;
+
+ // DT 6/29/98 Check Password Expiration data
+ if ((param = (String)(ht.get("NW_PASSWD_EXPIRING"))) != null) {
+ int secondsToExpiration = Integer.parseInt(param);
+
+ if (secondsToExpiration == 0) {
+ // Password expired. For now, show error and exit.
+ // Later, this should jump to a UI.
+ String msg = _resource.getString("error","pwExpired");
+ System.err.println(msg);
+ JOptionPane.showMessageDialog(
+ com.netscape.management.client.console.SplashScreen.getInstance(), msg,
+ _resource.getString("error","pwTitle"),
+ JOptionPane.ERROR_MESSAGE);
+ ModalDialogUtil.sleep();
+ System.exit(1);
+ } else {
+ double days = (secondsToExpiration / (1.0 * 3600 * 24));
+ String msg = MessageFormat.format(
+ _resource.getString("warning","pwExpireSoon"),
+ new Object[]{ new Double(days)});
+ Debug.println("Console: " + msg);
+ JOptionPane.showMessageDialog(
+ com.netscape.management.client.console.SplashScreen.getInstance(), msg,
+ _resource.getString("warning","title"),
+ JOptionPane.ERROR_MESSAGE);
+ ModalDialogUtil.sleep();
+ }
+ }
+
+ if (!successfulAuth)
+ return false;
+
+ if ((param = (String)(ht.get("UserDN"))) != null)
+ info.setAuthenticationDN(param);
+ else {
+ Debug.println("Console:authenticate_user():UserDN not found");
+ info.setAuthenticationDN(user);
+ }
+
+ info.setAuthenticationPassword(pw);
+ info.setAuthenticationValues(ht);
+
+ return true;
+ }
+
+ /**
+ * return the directory server
+ *
+ * @param user username
+ * @param pw password
+ * @param baseURL url of the admin server
+ * @return true if successful. false otherwise.
+ */
+ protected boolean restartDirectoryServer(String user, String pw,
+ String baseURL) {
+ URL url;
+
+ try {
+ // DT 5/14/98 This method of URL construction provides some limited
+ // validation of the URL, and eliminates any preexisting uri component.
+ url = new URL(new URL(baseURL), "/admin-serv/tasks/operation/StartConfigDS");
+ } catch (MalformedURLException mue) {
+ Debug.println("Console:restartDirectoryServer():Unable to create start task URL");
+ return false;
+ }
+
+ return invoke_task(url, user, pw, new Hashtable());
+ }
+
+ /**
+ * invoking a task
+ *
+ * @param url URL of the task
+ * @param user username
+ * @param pw password
+ * @param ht hashtable which contain the returned result
+ * @return true if successful. false otherwise.
+ */
+
+ private synchronized final boolean invoke_task(URL url,
+ String user, String pw, Hashtable ht) {
+ HttpManager h = new HttpManager();
+
+ InputStream is;
+ Response r;
+ Exception e = null;
+
+ try {
+ h.get(url, this, r = new Response(user, pw),
+ h.FORCE_BASIC_AUTH);
+ } catch (Exception ioe) {
+ String _url;
+ try {
+ _url = (new URL(url, "/")).toString();
+ } catch (MalformedURLException mue) {
+ _url = url.toString();
+ }
+
+ String msg = MessageFormat.format(
+ _resource.getString("error","connectAS"),
+ new Object[]{ _url});
+ JOptionPane.showMessageDialog(com.netscape.management.client.console.SplashScreen.getInstance(),
+ msg, _resource.getString("error","title"),
+ JOptionPane.ERROR_MESSAGE);
+ ModalDialogUtil.sleep();
+
+ return false;
+ }
+
+ try {
+ while (((is = r.getInputStream()) == null) &&
+ ((e = r.getError()) == null))
+ wait();
+ } catch (InterruptedException ie) {
+ Debug.println("Console:invoke_task():task response interrupted");
+ return false;
+ }
+
+ if (e != null) {
+ String msg = MessageFormat.format(
+ _resource.getString("error","task"),
+ new Object[]{ e.toString()});
+ JOptionPane.showMessageDialog(com.netscape.management.client.console.SplashScreen.getInstance(),
+ msg, _resource.getString("error","title"),
+ JOptionPane.ERROR_MESSAGE);
+ ModalDialogUtil.sleep();
+
+ if (!(e instanceof HttpException))
+ Debug.println("Console:invoke_task():error:" + e);
+ return false;
+ }
+
+ // parse response
+ BufferedReader br;
+ try {
+ br = new BufferedReader(new InputStreamReader(is, "UTF8"));
+ } catch (Exception ioe) {
+ br = new BufferedReader(new InputStreamReader(is));
+ Debug.println("Console:BufferedReader(UTF8) Error");
+ }
+
+ try {
+ String line;
+
+ while ((line = br.readLine()) != null) {
+ int i = line.indexOf(':');
+
+ if (i == -1)
+ continue;
+
+ // each line is of the form "name: value" (note spacing)
+ ht.put(line.substring(0, i), line.substring(i + 2));
+ }
+ } catch (Exception e2) {
+ }
+
+ String status = (String)(ht.get("NMC_Status"));
+
+ if ((status == null) || (Integer.parseInt(status) != 0)) {
+ Debug.println("Console:invoke_task():invocation failed");
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * initialize the ldap connection according to all the information. If the directory server is
+ * not running, try to start the directory server.
+ *
+ * @param info ConsoleInfo which store the global information.
+ * @return true if successfull. false otherwise.
+ */
+ private final int LDAPinitialization(ConsoleInfo info) {
+ // Set DS information;
+
+ Hashtable ht = _info.getAuthenticationValues();
+
+ String param;
+
+ // set up configuration data base information
+
+ if ((param = (String)(ht.get("SIE"))) != null)
+ _adminServerSIE = param;
+ else
+ Debug.println("Console:authenticate_user():SIE not found");
+
+ if ((param = (String)(ht.get("ldapHost"))) != null)
+ info.setHost(param);
+ else
+ Debug.println("Console:authenticate_user():ldapHost not found");
+
+ if ((param = (String)(ht.get("ldapPort"))) != null)
+ info.setPort(Integer.parseInt(param));
+ else
+ Debug.println("Console:authenticate_user():ldapPort not found");
+
+ if ((param = (String)(ht.get("ldapBaseDN"))) != null)
+ info.setBaseDN(param);
+ else
+ Debug.println("Console:authenticate_user():ldapBaseDN not found");
+
+ param = (String)(ht.get("ldapSecurity"));
+ boolean fLdapSecurity = false;
+ if ((param != null) && (param.equals("on"))) {
+ info.put("ldapSecurity","on");
+ fLdapSecurity = true;
+ } else {
+ info.put("ldapSecurity","off");
+ }
+
+ // Need to open an LDAPConnection for the ConsoleInfo object.
+
+ try {
+ LDAPConnection ldapConnection = createLDAPConnection(info);
+ if (ldapConnection == null) {
+ return LDAP_INIT_BIND_FAIL;
+ }
+ info.setLDAPConnection(ldapConnection);
+
+ } catch (LDAPException le) {
+
+ // DT 5/19/98 Prompt user to restart the registry DS if ldc.connect() failed
+ String dsURL = (fLdapSecurity ? "ldaps" : "ldap") + "://" +
+ info.getHost() + ":" + info.getPort();
+ String msg = MessageFormat.format(
+ _resource.getString("error","connectDS"),
+ new Object[]{dsURL, le.getMessage()});
+ Debug.println("Console:authenticate_user():" + msg);
+
+
+ if (_dsHasBeenRestarted) {
+ // DS has already been restarted, return an error
+ JOptionPane.showMessageDialog(
+ com.netscape.management.client.console.SplashScreen.getInstance(), msg,
+ _resource.getString("error","title"),
+ JOptionPane.ERROR_MESSAGE);
+ ModalDialogUtil.sleep();
+ return LDAP_INIT_FAILED;
+ }
+
+ Object[] choices = { _resource.getString("error", "restartDSButton"),
+ _resource.getString("error", "cancelButton")};
+ Object[] msgs = { msg, " ",
+ _resource.getString("error", "restartDSMessage"), " "};
+
+ int selection = JOptionPane.showOptionDialog(
+ com.netscape.management.client.console.SplashScreen.getInstance(), msgs,
+ _resource.getString("error","inittitle"),
+ JOptionPane.DEFAULT_OPTION,
+ JOptionPane.QUESTION_MESSAGE, null, choices,
+ choices[0]);
+
+ if (selection == 1)
+ System.exit(1); // cancel
+
+ // Pop a new login dialog, but this is for the Registry DS AS
+
+/*
+ RestartDialog rd = new RestartDialog(_frame);
+ rd.setDialogLocation(_frame);
+ rd.showModal();
+ if (rd.isCancel())
+ System.exit(0);
+ _splashScreen.toFront();
+
+ if (!restartDirectoryServer(rd.getUsername(),
+ rd.getPassword(), rd.getURL())) {
+ return LDAP_INIT_FAILED;
+ } else {
+ msg = _resource.getString("info","restartDS");
+ JOptionPane.showMessageDialog(
+ com.netscape.management.client.console.SplashScreen.getInstance(), msg,
+ _resource.getString("info","restartDSTitle"),
+ JOptionPane.INFORMATION_MESSAGE);
+ _dsHasBeenRestarted = true;
+ return LDAP_INIT_DS_RESTART;
+ }
+*/
+ }
+
+ // set up user data base information
+ // If config DS is unaccessable when authenticate CGI is called, the CGI returns ? for UserDirectory
+ if ((param = (String)(ht.get("UserDirectory"))) != null &&
+ !param.equals("?")) {
+ // this caused I18n problem - param=param.toLowerCase();
+ LDAPConnection ldc = null;
+ boolean fSSL = false;
+ String sHost = info.getHost();
+ int iPort = info.getPort();
+ String sBaseDN = info.getBaseDN();
+ int iStartSearch = 7;
+ if (param.startsWith("ldaps://")) {
+ fSSL = true;
+ iStartSearch = 8;
+ }
+
+ int iNextSlash = param.indexOf('/',8);
+ int iNextColon = param.indexOf(':',8);
+ int iNextSpace = param.indexOf(' ',8); //for failover list
+
+ // if failover list, use the first host and port in the list
+
+ if ((iNextSlash > iNextColon) && (iNextColon != (-1))) {
+ // has a port number
+ if ((iNextSpace != (-1))&&(iNextSpace<iNextSlash)) {
+ // failover list
+ iPort = Integer.parseInt(
+ param.substring(iNextColon + 1, iNextSpace));
+ } else {
+ iPort = Integer.parseInt(
+ param.substring(iNextColon + 1, iNextSlash));
+ }
+ sHost = param.substring(iStartSearch, iNextColon);
+ } else {
+ sHost = param.substring(iStartSearch, iNextSlash);
+ }
+
+ sBaseDN = param.substring(iNextSlash + 1);
+ info.setUserHost(sHost);
+ info.setUserPort(iPort);
+ info.setUserBaseDN(sBaseDN);
+
+ if (fSSL) {
+ ldc = new KingpinLDAPConnection(
+ UtilConsoleGlobals.getLDAPSSLSocketFactory(),
+ info.getAuthenticationDN(),
+ info.getAuthenticationPassword());
+ } else {
+ ldc = new KingpinLDAPConnection( info.getAuthenticationDN(),
+ info.getAuthenticationPassword());
+ }
+
+ try {
+ ldc.connect(info.getUserHost(), info.getUserPort());
+ ldc.authenticate(LDAPUtil.LDAP_VERSION,
+ info.getAuthenticationDN(),
+ info.getAuthenticationPassword());
+ } catch (Exception e) {
+ // catch no user exception
+ Debug.println("Console: cannot connect to the user database");
+ }
+ info.setUserLDAPConnection(ldc);
+ } else
+ Debug.println("Console.authenticate_user():UserDirectory value not found");
+
+
+ return LDAP_INIT_OK;
+ }
+
+ /**
+ * create an ldap connection.
+ *
+ * @param info ConsoleInfo object.
+ * @exception LDAPException Throws LDAPException if it cannot create a LDAP connection.
+ */
+
+ protected LDAPConnection createLDAPConnection(ConsoleInfo info)
+ throws LDAPException {
+ LDAPConnection ldc = null;
+
+ if (info.get("ldapSecurity").equals("on")) {
+ ldc = new KingpinLDAPConnection(
+ UtilConsoleGlobals.getLDAPSSLSocketFactory(),
+ info.getAuthenticationDN(),
+ info.getAuthenticationPassword());
+ } else {
+ ldc = new KingpinLDAPConnection(info.getAuthenticationDN(),
+ info.getAuthenticationPassword());
+ }
+
+ ldc.connect(info.getHost(), info.getPort());
+ try {
+ ldc.authenticate(LDAPUtil.LDAP_VERSION,
+ info.getAuthenticationDN(),
+ info.getAuthenticationPassword());
+ } catch (Exception e) {
+ // unable to auth the user, either password expired or account didn't exist.
+ // perhpas directory server is down.
+ JOptionPane.showMessageDialog(null, /*_info.getFrame(),*/
+
+ _resource.getString("error","cannotconnect") + e,
+ _resource.getString("error","title"),
+ JOptionPane.ERROR_MESSAGE);
+ ldc = null;
+ }
+
+ return ldc;
+ }
+
+ /**
+ * The CommClient interface for authentication.
+ */
+
+ /**
+ * reply the response
+ *
+ * @param is input stream for the response
+ * @param cr communication record
+ */
+ public synchronized void replyHandler(InputStream is, CommRecord cr) {
+ HttpChannel channel = (HttpChannel)cr.getChannel();
+ if (channel != null) {
+ _adminVersion = channel.getAdminVersion();
+ Debug.println("Console.replyHandler: adminVersion = " +
+ _adminVersion );
+ } else {
+ Debug.println("Console.replyHandler: no channel");
+ }
+ ((Response)(cr.getArg())).setInputStream(is);
+ notifyAll();
+ }
+
+ /**
+ * error exception handler
+ *
+ * @param e exception
+ * @param cr communication record
+ */
+ public synchronized void errorHandler(Exception e, CommRecord cr) {
+ ((Response)(cr.getArg())).setError(e);
+ notifyAll();
+ }
+
+ /**
+ * return the responsed username
+ *
+ * @param realm authenicate object
+ * @param cr communication record
+ * @return username
+ */
+ public String username(Object realm, CommRecord cr) {
+ return ((Response)(cr.getArg())).getUsername();
+ }
+
+ /**
+ * return the responsed password
+ *
+ * @param realm authenicate object
+ * @param cr communication record
+ * @return password
+ */
+ public String password(Object realm, CommRecord cr) {
+ return ((Response)(cr.getArg())).getPassword();
+ }
+
+ static Console _console;
+
+ private static void waitForKeyPress() {
+ // On Windows, startconsole window disappears immediately on exit, so
+ // we wait for keyboard input to allow the user to read the message
+ if (System.getProperty("os.name").startsWith("Win")) {
+ System.out.print("\nPress Enter key to continue ...");
+ try {
+ System.in.read();
+ } catch (Exception e) {}
+ }
+ }
+
+ /**
+ * main routine. It will pass the command line parameters then call the Console constructor
+ * to create a console instance.
+ *
+ * @param parameters list
+ */
+
+ static public void main(String argv[]) {
+ GetOpt opt = new GetOpt("h:a:A:f:l:u:w:s:D:x:", argv);
+
+ if (opt.hasOption('f')) {
+ String outFile = opt.getOptionParam('f');
+ try {
+ TeeStream.tee(outFile);
+ }
+ catch (Exception e) {
+ System.err.println("Missing or invalid output file specification for the -f option: " + e);
+ System.exit(1);
+ }
+ }
+
+ if (opt.hasOption('D')) {
+ Debug.setApplicationStartTime(_t0);
+ String extraParam = opt.getOptionParam('D');
+ if (extraParam != null) {
+ if (extraParam.equals("?") ||
+ !Debug.setTraceMode(extraParam)) {
+ System.out.println(Debug.getUsage());
+ waitForKeyPress(); // allow the user to read the msg on Win NT
+ System.exit(0);
+ }
+ } else {
+ Debug.setTraceMode(null);
+ }
+
+ // Show all system proprties if debug level is 9
+ if (Debug.getTraceLevel() == 9) {
+ try {
+ Properties props = System.getProperties();
+ for (Enumeration e = props.keys();
+ e.hasMoreElements();) {
+ String key = (String) e.nextElement();
+ String val = (String) props.get(key);
+ Debug.println(9, key + "="+val);
+ }
+ } catch (Exception e) {}
+ }
+ }
+
+ Debug.println(0,
+ "Management-Console/" +
+ _resource.getString("console","displayVersion") +
+ " B" + VersionInfo.getBuildNumber());
+
+ if (opt.hasOption('x')) {
+ String extraParam = opt.getOptionParam('x');
+ boolean supportedOption = false;
+
+ if (extraParam == null)
+ extraParam = "";
+
+ if (extraParam.indexOf(OPTION_NOLOGO) != -1) {
+ _showSplashScreen = false;
+ supportedOption = true;
+ }
+ if (extraParam.indexOf(OPTION_NOWINPOS) != -1) {
+ Framework.setEnableWinPositioning(false);
+ supportedOption = true;
+ }
+ if (extraParam.indexOf(OPTION_JAVALAF) != -1) {
+ _useJavaLookAndFeel= true;
+ supportedOption = true;
+ }
+
+ if (supportedOption == false) {
+ opt = new GetOpt("h:", new String[]{ "-h"});
+ }
+ }
+
+ if (opt.hasOption('h'))// help
+ {
+ System.err.println("Syntax: Console [-a <URL>] [-l <Language Code>] [-s <SIE DN>] [-x <options>]");
+ System.err.println(" -a admin server base URL");
+ System.err.println(" -l language code (en fr gr)");
+ System.err.println(" -f <file> capture stderr and stdout to <file> (like Unix tee command)");
+ System.err.println(" -s server DN (cn=...) or instance ID (e.g. slapd-host)");
+ System.err.println(" -x extra options (javalaf,nowinpos,nologo)");
+ System.err.println("\nExample: Console -a https://hostname:10021 -l en");
+ waitForKeyPress(); // allow the user to read the msg on Win NT
+ System.exit(0);
+ }
+
+ // bug 353403: -a option intended for end-user to
+ // specify default admin url. This option overrides
+ // -A option.
+ String sAdminURL = null;
+ if (opt.hasOption('a')) {
+ sAdminURL = opt.getOptionParam('a');
+ }
+
+ // bug 353403, -A option intended for startconsole to
+ // specify local admin server url, if one exists.
+ String localAdminURL = null;
+ if (opt.hasOption('A')) {
+ localAdminURL = opt.getOptionParam('A');
+ }
+
+ String instanceID = null;
+ if (opt.hasOption('s')) {
+ instanceID = opt.getOptionParam('s');
+ }
+
+ String sLang = "en";
+ if (opt.hasOption('l')) {
+ sLang = opt.getOptionParam('l');
+ }
+
+ String host = null;
+ if (opt.hasOption('s')) {
+ host = opt.getOptionParam('s');
+ }
+
+ String uid = null;
+ if (opt.hasOption('u')) {
+ uid = opt.getOptionParam('u');
+ }
+
+ String password = null;
+ if (opt.hasOption('w')) {
+ password = opt.getOptionParam('w');
+ }
+
+
+ ConsoleInfo cinfo = new ConsoleInfo();
+ CMSAdmin admin = new CMSAdmin();
+ URL url = null;
+ try {
+ url = new URL(sAdminURL);
+ } catch (Exception e) {
+ String es = e.toString();
+ String ep = "java.net.MalformedURLException:";
+ if (es != null && es.startsWith(ep)) {
+ es = es.substring(ep.length());
+ }
+ System.err.println("\nURL error: "+es+"\n");
+ waitForKeyPress(); // allow the user to read the msg on Win NT
+ System.exit(1);
+ }
+ if (url == null) {
+ System.err.println("\nIncorrect URL: "+sAdminURL+"\n");
+ waitForKeyPress(); // allow the user to read the msg on Win NT
+ System.exit(1);
+ }
+ cinfo.put("cmsServerInstance", instanceID);
+
+ String protocol = url.getProtocol();
+ String hostName = url.getHost();
+ String path = url.getPath();
+ /* Protocol part of URL is required only by URL class. Console assumes URL protocol. */
+ if (protocol == null || protocol.length() == 0 ||
+ ((!protocol.equalsIgnoreCase("https")) && (!protocol.equalsIgnoreCase("http"))) ) {
+ System.err.println("\nIncorrect protocol"+
+ ((protocol != null && protocol.length() > 0)?": "+protocol:".")+
+ "\nDefault supported protocol is 'https'.\n");
+ waitForKeyPress(); // allow the user to read the msg on Win NT
+ System.exit(1);
+ }
+
+ if (hostName == null || hostName.length() == 0) {
+ System.err.println("\nMissing hostName: "+sAdminURL+"\n");
+ waitForKeyPress(); // allow the user to read the msg on Win NT
+ System.exit(1);
+ }
+ if (path == null || path.length() < 2 ) {
+ System.err.println("\nMissing URL path: "+sAdminURL+
+ "\nDefault supported URL paths are 'ca', 'kra', 'ocsp', and 'tks'.\n");
+ waitForKeyPress(); // allow the user to read the msg on Win NT
+ System.exit(1);
+ }
+ path = path.substring(1);
+ if ((!path.equals("ca")) && (!path.equals("kra")) &&
+ (!path.equals("ocsp")) && (!path.equals("tks"))) {
+ System.err.println("\nWarning: Potentially incorrect URL path: "+path+
+ "\n Default supported URL paths are 'ca', 'kra', 'ocsp', and 'tks'.\n");
+ }
+ int portNumber = url.getPort();
+ if (portNumber < 0) {
+ System.err.println("\nWarning: Unspecified port number: "+sAdminURL+"\n");
+ /* Add warning about using non default port numbers after port separation is done.
+ "\n Default port number is 9443.\n");
+ } else if (portNumber != 9443) {
+ System.err.println("\nWarning: Attempt to connect to non default port number: "+sAdminURL+
+ "\n Default port number is 9443.\n");
+ */
+ }
+ cinfo.put("cmsHost", url.getHost());
+ cinfo.put("cmsPort", Integer.toString(portNumber));
+ cinfo.put("cmsPath", path);
+ admin.initialize(cinfo);
+ admin.run(null, null);
+/*
+ _console = new Console(sAdminURL, localAdminURL, sLang, host, uid, password);
+*/
+ return;
+ }
+}
+
+
+/**
+ * A class that makes a PrintStream act like a Unix tee command
+ */
+class TeeStream extends PrintStream {
+ static OutputStream logfile;
+
+ private TeeStream(PrintStream ps) {
+ super(ps);
+ }
+
+ // Redirects stdout and stderr to the logfile
+ public static void tee(String f) throws IOException {
+
+ // Create/Open logfile.
+ logfile = new PrintStream(
+ new BufferedOutputStream(
+ new FileOutputStream(f)),
+ /*autoFlush=*/true);
+
+ // Start redirecting the output.
+ System.setOut(new TeeStream(System.out));
+ System.setErr(new TeeStream(System.err));
+ }
+
+
+ // PrintStream override.
+ public void write(int b) {
+ try {
+ logfile.write(b);
+ } catch (Exception e) {
+ e.printStackTrace();
+ setError();
+ }
+ super.write(b);
+ }
+
+ // PrintStream override.
+ public void write(
+ byte buf[], int off, int len) {
+ try {
+ logfile.write(buf, off, len);
+ } catch (Exception e) {
+ e.printStackTrace();
+ setError();
+ }
+ super.write(buf, off, len);
+ }
+}
+
+/**
+ * An internal class used to wrap the parameters of an
+ * authentication request.
+ *
+ * @author David Tompkins, 12/13/97
+ */
+class Response {
+ private InputStream is;
+ private Exception ex;
+ private String user;
+ private String pw;
+
+ /**
+ * constructor for the response object.
+ *
+ * @param _user username
+ * @param _pw password
+ */
+ public Response(String _user, String _pw) {
+ user = _user;
+ pw = _pw;
+ is = null;
+ ex = null;
+ }
+
+ /**
+ * set the input stream
+ *
+ * @param _is input stream to be set
+ */
+ protected void setInputStream(InputStream _is) {
+ is = _is;
+ }
+
+ /**
+ * set the response error
+ *
+ * @param e error of the exception
+ */
+ protected void setError(Exception e) {
+ ex = e;
+ }
+
+ /**
+ * return the response input stream
+ *
+ * @return return the response input stream.
+ */
+ protected InputStream getInputStream() {
+ return is;
+ }
+
+ /**
+ * return the error exception
+ *
+ * @return error exception
+ */
+ protected Exception getError() {
+ return ex;
+ }
+
+ /**
+ * return the username
+ *
+ * @return username
+ */
+ protected String getUsername() {
+ return user;
+ }
+
+ /**
+ * return the password
+ *
+ * @return password
+ */
+ protected String getPassword() {
+ return pw;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/CustomComboBox.java b/base/console/src/com/netscape/admin/certsrv/CustomComboBox.java
new file mode 100644
index 000000000..c76c36006
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CustomComboBox.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.admin.certsrv;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+
+/**
+ * General Purpose Custom Combo Box
+ *
+ * @author jpanchen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv
+ * @see CustomComboBoxModel
+ */
+public class CustomComboBox extends JComboBox {
+
+ public CustomComboBox(ComboBoxModel m) {
+ super(m);
+ super.setRenderer( new CustomCellRenderer(this));
+ }
+}
+
+class CustomCellRenderer extends JLabel implements ListCellRenderer {
+
+ final static Color selectedCellBackground = new Color(0,0,128);
+ final static Color selectedCellForeground = Color.white;
+ final static Color defaultCellBackground = Color.white;
+ final static Color defaultCellForeground = Color.black;
+ final static String SELECTION_TITLE = CustomComboBoxModel.SELECTION_TITLE;
+ final static String SELECTION_ICON = CustomComboBoxModel.SELECTION_ICON;
+
+ CustomComboBox combobox;
+
+ public CustomCellRenderer(CustomComboBox x) {
+ combobox = x;
+ setOpaque(true);
+ }
+
+ public Component getListCellRendererComponent(
+ JList listbox, Object value, int index,
+ boolean isSelected, boolean cellHasFocus)
+ {
+ Hashtable h = (Hashtable) value;
+ if(value == null) {
+ setText("");
+ setIcon(null);
+ setBackground(selectedCellBackground);
+ setForeground(selectedCellForeground);
+ } else {
+ setIcon((ImageIcon)h.get(SELECTION_ICON));
+ setText((String)h.get(SELECTION_TITLE));
+ setBackground(defaultCellBackground);
+ setForeground(defaultCellForeground);
+ }
+
+ return this;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/CustomComboBoxModel.java b/base/console/src/com/netscape/admin/certsrv/CustomComboBoxModel.java
new file mode 100644
index 000000000..c97beeb5b
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/CustomComboBoxModel.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.admin.certsrv;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+
+/**
+ * Custom Combo Box Model
+ * Let you specify an icon and title to be displayed.
+ *
+ * @author jpanchen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv
+ * @see CustomComboBox
+ */
+class CustomComboBoxModel extends AbstractListModel implements ComboBoxModel {
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CustomComboBoxModel() {
+ _cache = new Vector();
+ _index = new Vector();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * set selected item
+ * DO NOT USE!!!
+ * use JComboBox.setSelectedIndex()
+ */
+ public void setSelectedItem(Object anObject) {
+ _currentValue = anObject;
+ fireContentsChanged(this,-1,-1);
+ }
+
+ /**
+ * Get selected Item.
+ * DO NOT USE !!!
+ * use JComboBox.getItemAt(JComboBox.getSelectedIndex())
+ */
+ public Object getSelectedItem() {
+ return _currentValue;
+ }
+
+ /**
+ * Return size
+ * @return size
+ */
+ public int getSize() {
+ return _cache.size();
+ }
+
+ /**
+ * Retrieve element at index position
+ * @param index location
+ * @Object Hashtable obejct with "icon" and "title" field
+ */
+ public Object getElementAt(int index) {
+ try {
+ return _cache.elementAt(index);
+ } catch(ArrayIndexOutOfBoundsException e) {
+ return null;
+ }
+ }
+
+ /**
+ * set default icon
+ * @param icon new icon to be used
+ */
+ public void setIcon(ImageIcon icon) {
+ _icon = icon;
+ }
+
+ /**
+ * Add new list entry into model
+ * @param icon new icon associated
+ * @param title text associated
+ */
+ public void addItem(ImageIcon icon, String title, Object data) {
+ Hashtable newItem = new Hashtable();
+ newItem.put(SELECTION_ICON,icon);
+ newItem.put(SELECTION_TITLE, title);
+ newItem.put(SELECTION_DATA, data);
+ _cache.addElement(newItem);
+ _index.addElement(title.toUpperCase());
+ }
+
+ /**
+ * Add new list entry into model
+ * @param icon new icon associated
+ * @param title text associated
+ */
+ public void addItem(ImageIcon icon, String title) {
+ Hashtable newItem = new Hashtable();
+ newItem.put(SELECTION_ICON,icon);
+ newItem.put(SELECTION_TITLE, title);
+ _cache.addElement(newItem);
+ _index.addElement(title.toUpperCase());
+ }
+
+ /**
+ * Add new list entry into model.
+ * Default icon used
+ * @param title text associated
+ */
+ public void addItem(String title) {
+ Hashtable newItem = new Hashtable();
+ newItem.put(SELECTION_ICON,_icon);
+ newItem.put(SELECTION_TITLE, title);
+ _cache.addElement(newItem);
+ _index.addElement(title.toUpperCase());
+ }
+
+ /**
+ * Remove all entries from the model
+ */
+ public void removeAll() {
+ _cache.removeAllElements();
+ }
+
+ /**
+ * Remove specific entry from the model
+ * @param key key string associated with the entry
+ */
+ public void removeEntry(String key) {
+ int x = _index.indexOf(key.toUpperCase());
+ if ((x != -1) && (x < _cache.size()) ) {
+ _cache.removeElementAt(x);
+ _index.removeElementAt(x);
+ }
+ }
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+
+ public static final String SELECTION_TITLE = "title";
+ public static final String SELECTION_ICON = "icon";
+ public static final String SELECTION_DATA = "data";
+
+ private Object _currentValue;
+ private Vector _cache;
+ private Vector _index;
+ private ImageIcon _icon;
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/DefaultTableCellEditor.java b/base/console/src/com/netscape/admin/certsrv/DefaultTableCellEditor.java
new file mode 100644
index 000000000..638494326
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/DefaultTableCellEditor.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.admin.certsrv;
+
+import com.netscape.certsrv.common.*;
+import java.awt.Component;
+import java.awt.event.*;
+import java.awt.AWTEvent;
+import java.lang.Boolean;
+import javax.swing.table.*;
+import javax.swing.event.*;
+import java.util.EventObject;
+import javax.swing.*;
+import javax.swing.tree.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Default Table Cell Editor. Since we need to display different
+ * editor depending on serverside input. We will use this editor
+ * that takes specific data object.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv
+ */
+public class DefaultTableCellEditor
+ implements TableCellEditor, ActionListener
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+
+ /** Event listeners */
+ protected EventListenerList listenerList = new EventListenerList();
+ transient protected ChangeEvent changeEvent = null;
+ protected CellEditorData mValue;
+
+ protected JTextField mTextField = new JTextField();
+ protected JPasswordField mPasswordField = new JPasswordField();
+ protected JTextField mEditorComponent;
+ protected int clickCountToStart = 2;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public DefaultTableCellEditor() {
+ mTextField = new JTextField();
+ mTextField.addActionListener(this);
+ mPasswordField = new JPasswordField();
+ mPasswordField.addActionListener(this);
+ mValue = new CellEditorData();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ public Component getComponent() {
+ return mEditorComponent;
+ }
+
+ /**
+ * clickCountToStart controls the number of clicks required to start
+ * editing if the event passed to isCellEditable() or startCellEditing() is
+ * a MouseEvent. For example, by default the clickCountToStart for
+ * a JTextField is set to 2, so in a JTable the user will need to
+ * double click to begin editing a cell.
+ */
+ public void setClickCountToStart(int count) {
+ clickCountToStart = count;
+ }
+
+ /**
+ * clickCountToStart controls the number of clicks required to start
+ * editing if the event passed to isCellEditable() or startCellEditing() is
+ * a MouseEvent. For example, by default the clickCountToStart for
+ * a JTextField is set to 2, so in a JTable the user will need to
+ * double click to begin editing a cell.
+ */
+ public int getClickCountToStart() {
+ return clickCountToStart;
+ }
+
+ //Interface javax.swing.CellEditor
+ public Object getCellEditorValue() {
+ mValue.mData = mEditorComponent.getText();
+ return mValue;
+ }
+
+ public boolean isCellEditable(EventObject anEvent) {
+ if (anEvent instanceof MouseEvent) {
+ if (((MouseEvent)anEvent).getClickCount() < clickCountToStart)
+ return false;
+ }
+ return true;
+ }
+
+ public boolean shouldSelectCell(EventObject anEvent) {
+ boolean retValue = true;
+
+ if (this.isCellEditable(anEvent)) {
+ if (anEvent == null || ((MouseEvent)anEvent).getClickCount() >=
+ clickCountToStart)
+ retValue = startCellEditing(anEvent);
+ }
+
+ // By default we want the cell the be selected so
+ // we return true
+ return retValue;
+
+ }
+
+ public boolean startCellEditing(EventObject anEvent) {
+ if(anEvent == null)
+ mEditorComponent.requestFocus();
+ return true;
+ }
+
+ public boolean stopCellEditing() {
+ fireEditingStopped();
+ return true;
+ }
+
+ public void cancelCellEditing() {
+ fireEditingCanceled();
+ }
+
+ // Handle the event listener bookkeeping
+ public void addCellEditorListener(CellEditorListener l) {
+ listenerList.add(CellEditorListener.class, l);
+ }
+
+ public void removeCellEditorListener(CellEditorListener l) {
+ listenerList.remove(CellEditorListener.class, l);
+ }
+
+ // Implementing ActionListener interface
+ public void actionPerformed(ActionEvent e) {
+ fireEditingStopped();
+ }
+
+ public Component getTableCellEditorComponent(JTable table,
+ Object value,
+ boolean isSelected,
+ int row, int column) {
+
+ Debug.println("DefaultTableCellEditor: getTableCellEditorComponent() -");
+ if(value != null) {
+ Debug.println(" data: "+(String)((CellEditorData)value).mData);
+ Debug.println(" type: "+((CellEditorData)value).mType);
+ }
+ Debug.println(" isSelected: "+isSelected);
+ Debug.println(" row:"+row +" col:"+column);
+
+ mEditorComponent = mTextField;
+ if(value != null) {
+ mValue = (CellEditorData)value;
+
+ if (mValue.mType.equals(Constants.TYPE_PASSWORD))
+ mEditorComponent = mPasswordField;
+ mEditorComponent.setText((String)mValue.mData);
+ } else {
+ mEditorComponent.setText("");
+ }
+ return mEditorComponent;
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+
+ /*
+ * Notify all listeners that have registered interest for
+ * notification on this event type. The event instance
+ * is lazily created using the parameters passed into
+ * the fire method.
+ * @see EventListenerList
+ */
+ protected void fireEditingStopped() {
+ // Guaranteed to return a non-null array
+ Object[] listeners = listenerList.getListenerList();
+ // Process the listeners last to first, notifying
+ // those that are interested in this event
+ for (int i = listeners.length-2; i>=0; i-=2) {
+ if (listeners[i]==CellEditorListener.class) {
+ // Lazily create the event:
+ if (changeEvent == null)
+ changeEvent = new ChangeEvent(this);
+ ((CellEditorListener)listeners[i+1]).editingStopped(changeEvent);
+ }
+ }
+ }
+
+
+ /*
+ * Notify all listeners that have registered interest for
+ * notification on this event type. The event instance
+ * is lazily created using the parameters passed into
+ * the fire method.
+ * @see EventListenerList
+ */
+ protected void fireEditingCanceled() {
+ // Guaranteed to return a non-null array
+ Object[] listeners = listenerList.getListenerList();
+ // Process the listeners last to first, notifying
+ // those that are interested in this event
+ for (int i = listeners.length-2; i>=0; i-=2) {
+ if (listeners[i]==CellEditorListener.class) {
+ // Lazily create the event:
+ if (changeEvent == null)
+ changeEvent = new ChangeEvent(this);
+ ((CellEditorListener)listeners[i+1]).editingCanceled(changeEvent);
+ }
+ }
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/EAdminException.java b/base/console/src/com/netscape/admin/certsrv/EAdminException.java
new file mode 100644
index 000000000..acb5ab6ce
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/EAdminException.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.admin.certsrv;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * A class represents an administartive exception. By
+ * using this exception, the locale conversion can be
+ * delayed until it is necessary. THIS CLASS DOES NOT
+ * SUPPORT MESSAGE FORMAT.
+ * <P>
+ *
+ * @author jpanchen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv
+ */
+public class EAdminException extends Exception {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String RESOURCES = CMSAdminResources.class.getName();
+ private boolean mIsLocalized = false;
+ private ResourceBundle mResource;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ /**
+ * Constructs an exception.
+ * <P>
+ *
+ * @param msgFormat exception details
+ * @param isLocalized true if the string is localized already
+ */
+ public EAdminException(String msgFormat, boolean isLocalized) {
+ super(msgFormat);
+ mResource = ResourceBundle.getBundle(RESOURCES);
+ mIsLocalized = isLocalized;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Check if the original message is localized already
+ *
+ * @return true if the message is localized
+ */
+ public boolean isLocalized() {
+ return mIsLocalized;
+ }
+
+ /**
+ * Returns localized exception string. This method should
+ * only be called if a localized string is necessary.
+ * <P>
+ *
+ * @return details message
+ */
+ public String toString() {
+ return getMessage();
+ }
+
+ /**
+ * Returns the string based on the given locale.
+ * This is costly since resource boundle is created each time. Use
+ * this only when it is necessary.
+ *
+ * @param locale locale
+ * @return details message
+ */
+ public String toString(Locale locale) {
+ ResourceBundle resource = ResourceBundle.getBundle(RESOURCES, locale);
+ try {
+ return resource.getString(super.getMessage());
+ } catch (MissingResourceException e) {
+ return super.getMessage()+"-"+e.toString();
+ } catch (Exception ex) {
+ return super.getMessage();
+ }
+ }
+
+ /**
+ * Returns the message based on the given locale.If the original message
+ * is mark localized, the orginal message will be returned without
+ * converstion. This is costly since resource boundle is created each time.Use
+ * this only when it is necessary.<P>
+ *
+ * @param locale user specify local
+ * @return string representation in specified local
+ */
+ public String getMessage(Locale locale){
+ return toString(locale);
+ }
+
+ /**
+ * Returns the message in default locale. If the original message
+ * is mark localized, the orginal message will be returned without
+ * converstion.<P>
+ *
+ * @return localized detial exception string
+ */
+ public String getMessage(){
+ if (mIsLocalized)
+ return super.getMessage();
+ try {
+ return mResource.getString(super.getMessage());
+ } catch (MissingResourceException e) {
+ return super.getMessage()+"-"+e.toString();
+ } catch (Exception ex) {
+ return super.getMessage();
+ }
+ }
+
+ /**
+ * Returns the message or message tag unconvrted
+ */
+ public String getMessageString() {
+ return super.getMessage();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/GenericCellEditor.java b/base/console/src/com/netscape/admin/certsrv/GenericCellEditor.java
new file mode 100644
index 000000000..b26b9f9f9
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/GenericCellEditor.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.admin.certsrv;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.lang.*;
+import java.util.*;
+import javax.swing.table.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.io.Serializable;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+
+/**
+ * Class that will edit components correctly in table
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv
+ */
+public class GenericCellEditor implements TableCellEditor, Serializable {
+
+ protected EventListenerList listenerList = new EventListenerList();
+ transient protected ChangeEvent changeEvent = null;
+ protected JComponent editorComponent;
+ protected JTextField mTextField = new JTextField();
+ protected JPasswordField mPasswordField = new JPasswordField();
+
+ protected EditorDelegate delegate = new EditorDelegate();
+ protected int clickCounts = 2;
+
+ public GenericCellEditor() {
+ mTextField.addActionListener(delegate);
+ mPasswordField.addActionListener(delegate);
+ }
+
+ public Component getTableCellEditorComponent(JTable table, Object value,
+ boolean isSelected, int row, int column) {
+
+ TableModel model = table.getModel();
+
+ Vector v = (Vector)(((CMSContentTableModel)model).getObjectValueAt(row));
+ delegate.setValue(value, v);
+
+ return editorComponent;
+ }
+
+ public Component getComponent() {
+ return editorComponent;
+ }
+
+ public Object getCellEditorValue() {
+ return delegate.getCellEditorValue();
+ }
+
+ public boolean isCellEditable(EventObject anEvent) {
+ if (anEvent instanceof MouseEvent) {
+ if (((MouseEvent)anEvent).getClickCount() < clickCounts)
+ return false;
+ }
+ return delegate.isCellEditable(anEvent);
+ }
+
+ public boolean shouldSelectCell(EventObject anEvent) {
+ boolean retValue = true;
+
+ if (this.isCellEditable(anEvent)) {
+ if (anEvent == null || ((MouseEvent)anEvent).getClickCount() >=
+ clickCounts)
+ retValue = delegate.startCellEditing(anEvent);
+ }
+ // By default we want the cell the be selected so
+ // we return true
+ return retValue;
+ }
+
+ public boolean stopCellEditing() {
+ boolean stopped = delegate.stopCellEditing();
+
+ if (stopped) {
+ fireEditingStopped();
+ }
+
+ return stopped;
+ }
+
+ public void cancelCellEditing() {
+ delegate.cancelCellEditing();
+ fireEditingCanceled();
+ }
+
+ public void addCellEditorListener(CellEditorListener l) {
+ listenerList.add(CellEditorListener.class, l);
+ }
+
+ public void removeCellEditorListener(CellEditorListener l) {
+ listenerList.remove(CellEditorListener.class, l);
+ }
+
+ /*
+ * Notify all listeners that have registered interest for
+ * notification on this event type. The event instance
+ * is lazily created using the parameters passed into
+ * the fire method.
+ * @see EventListenerList
+ */
+ protected void fireEditingStopped() {
+ // Guaranteed to return a non-null array
+ Object[] listeners = listenerList.getListenerList();
+ // Process the listeners last to first, notifying
+ // those that are interested in this event
+ for (int i = listeners.length-2; i>=0; i-=2) {
+ if (listeners[i]==CellEditorListener.class) {
+ // Lazily create the event:
+ if (changeEvent == null)
+ changeEvent = new ChangeEvent(this);
+ ((CellEditorListener)listeners[i+1]).editingStopped(changeEvent);
+ }
+ }
+ }
+
+ /*
+ * Notify all listeners that have registered interest for
+ * notification on this event type. The event instance
+ * is lazily created using the parameters passed into
+ * the fire method.
+ * @see EventListenerList
+ */
+ protected void fireEditingCanceled() {
+ // Guaranteed to return a non-null array
+ Object[] listeners = listenerList.getListenerList();
+ // Process the listeners last to first, notifying
+ // those that are interested in this event
+ for (int i = listeners.length-2; i>=0; i-=2) {
+ if (listeners[i]==CellEditorListener.class) {
+ // Lazily create the event:
+ if (changeEvent == null)
+ changeEvent = new ChangeEvent(this);
+ ((CellEditorListener)listeners[i+1]).editingCanceled(changeEvent);
+ }
+ }
+ }
+
+ protected class EditorDelegate implements ActionListener, ItemListener,
+ Serializable {
+ protected Object value;
+
+ public Object getCellEditorValue() {
+ if (editorComponent instanceof JPasswordField)
+ return mPasswordField.getText();
+ else if (editorComponent instanceof JTextField)
+ return mTextField.getText();
+
+ return null;
+ }
+
+ public void setValue(Object x, Vector v) {
+ String type = (String)v.elementAt(0);
+ this.value = x;
+
+ if (type.equals(Constants.TEXTTYPE)) {
+ if (mTextField == null)
+ mTextField = new JTextField();
+ editorComponent = mTextField;
+ if (x != null)
+ mTextField.setText(x.toString());
+ else
+ mTextField.setText("");
+ } else if (type.equals(Constants.PASSWORDTYPE)) {
+ if (mPasswordField == null)
+ mPasswordField = new JPasswordField();
+ editorComponent = mPasswordField;
+ if (x != null)
+ mPasswordField.setText(x.toString());
+ else
+ mPasswordField.setText("");
+ //((JPasswordField)editorComponent).setCaretPosition(0);
+ }
+ }
+
+ public boolean isCellEditable(EventObject anEvent) {
+ return true;
+ }
+
+ public boolean startCellEditing(EventObject anEvent) {
+ if (anEvent == null)
+ editorComponent.requestFocus();
+ return true;
+ }
+
+ public boolean stopCellEditing() {
+ return true;
+ }
+
+ public void cancelCellEditing() {
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ fireEditingStopped();
+ }
+
+ public void itemStateChanged(ItemEvent e) {
+ fireEditingStopped();
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/GenericCellRenderer.java b/base/console/src/com/netscape/admin/certsrv/GenericCellRenderer.java
new file mode 100644
index 000000000..34d69e37e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/GenericCellRenderer.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.admin.certsrv;
+
+import java.awt.*;
+import java.lang.*;
+import java.util.*;
+import javax.swing.table.*;
+import javax.swing.*;
+import java.io.Serializable;
+import com.netscape.certsrv.common.*;
+import javax.swing.border.*;
+import com.netscape.admin.certsrv.connection.*;
+
+/**
+ * Class that will render components correctly in table
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv
+ */
+public class GenericCellRenderer
+ implements TableCellRenderer, Serializable
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ protected JComponent component;
+ private JPasswordField mPasswordField;
+ private JLabel mLabel;
+ private JCheckBox mCheckBox;
+ private JComboBox mComboBox;
+ protected ValueProperty value;
+ static Color HIGHLIGHTCOLOR = new Color(0, 0, 128);
+ static Color WHITECOLOR = Color.white;
+ static Color BLACKCOLOR = Color.black;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ public GenericCellRenderer() {
+ value = new ValueProperty();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ public void setToolTipText(String text) {
+ if (component instanceof JComponent)
+ ((JComponent)component).setToolTipText(text);
+ }
+
+ public Component getComponent() {
+ return component;
+ }
+
+ //==== Implementing TableCellRenderer =========
+ public Component getTableCellRendererComponent(JTable table, Object value,
+ boolean isSelected,
+ boolean hasFocus,
+ int row, int column) {
+ TableModel model = table.getModel();
+ if(value == null) {
+
+ value = model.getValueAt(row, column);
+ }
+ Vector v = (Vector)(((CMSContentTableModel)model).getObjectValueAt(row));
+ this.value.setValue(value, v);
+ component.setBackground(isSelected ? HIGHLIGHTCOLOR : WHITECOLOR);
+ component.setForeground(isSelected ? WHITECOLOR : BLACKCOLOR);
+ return component;
+ }
+
+
+ protected class ValueProperty implements Serializable {
+
+ public void setValue(Object x, Vector v) {
+ String type = (String)v.elementAt(0);
+ if (type.equals(Constants.PASSWORDTYPE)) {
+ if (mLabel == null) {
+ mLabel = new JLabel();
+ mLabel.setOpaque(true);
+ mLabel.setBorder(new EmptyBorder(1,CMSAdminUtil.COMPONENT_SPACE, 1, 2));
+ JPasswordField temp = new JPasswordField();
+ mLabel.setFont(temp.getFont());
+ }
+ component = mLabel;
+
+ StringBuffer buf = new StringBuffer();
+ for(int i=0; i< ((String)x).length(); i++)
+ buf.append("*");
+ ((JLabel)component).setText(buf.toString());
+ } else if (type.equals(Constants.TEXTTYPE)) {
+ if (mLabel == null) {
+ mLabel = new JLabel();
+ mLabel.setOpaque(true);
+ mLabel.setBorder(new EmptyBorder(1,CMSAdminUtil.COMPONENT_SPACE, 1, 2));
+ JTextField temp = new JTextField();
+ mLabel.setFont(temp.getFont());
+ }
+ component = mLabel;
+ ((JLabel)component).setText((String)x);
+ } else if (type.equals(Constants.CHECKBOXTYPE)) {
+ if (mCheckBox == null)
+ mCheckBox = new JCheckBox();
+ component = mCheckBox;
+ if (x instanceof Boolean) {
+ Boolean bool = (Boolean)x;
+ mCheckBox.setHorizontalAlignment(JCheckBox.CENTER);
+ mCheckBox.setSelected(bool.booleanValue());
+ }
+ } else if (type.equals(Constants.COMBOTYPE)) {
+ String[] items = (String[])v.elementAt(1);
+
+ if (mComboBox == null)
+ mComboBox = new JComboBox(items);
+ else {
+ mComboBox.removeAllItems();
+ for (int i=0; i<items.length; i++) {
+ mComboBox.insertItemAt(items[i], i);
+ }
+ }
+ component = mComboBox;
+ String str = (String)x;
+
+ if (str.equals(""))
+ mComboBox.setSelectedIndex(0);
+ else
+ mComboBox.setSelectedItem(str);
+ }
+ }
+
+ }
+}
+
+
diff --git a/base/console/src/com/netscape/admin/certsrv/HourGlass.java b/base/console/src/com/netscape/admin/certsrv/HourGlass.java
new file mode 100644
index 000000000..a0c582761
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/HourGlass.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.admin.certsrv;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * This class changes the cursor to the busy mode.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @date 03/19/99
+ */
+public class HourGlass extends Thread {
+
+ private JFrame mActiveFrame;
+ private int mNonWaitType;
+
+ public HourGlass(JFrame frame) {
+ mActiveFrame = frame;
+ mNonWaitType = frame.getCursor().getType();
+ start();
+ }
+
+ public void run() {
+ Cursor cursor = new Cursor(Cursor.WAIT_CURSOR);
+ mActiveFrame.setCursor(cursor);
+ }
+
+ public void setNonWaitCursor() {
+ Cursor cursor = new Cursor(mNonWaitType);
+ mActiveFrame.setCursor(cursor);
+ this.stop();
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/IAttributeContent.java b/base/console/src/com/netscape/admin/certsrv/IAttributeContent.java
new file mode 100644
index 000000000..f467b38a1
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/IAttributeContent.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.admin.certsrv;
+
+/**
+ * Interface for the attribute content
+ *
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv
+ */
+public interface IAttributeContent {
+
+} \ No newline at end of file
diff --git a/base/console/src/com/netscape/admin/certsrv/IConnectionListener.java b/base/console/src/com/netscape/admin/certsrv/IConnectionListener.java
new file mode 100644
index 000000000..c6275b403
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/IConnectionListener.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.admin.certsrv;
+
+/**
+ * Listener interface
+ *
+ * @author chrisho
+ * @version $Revision$, $Date$
+ */
+public interface IConnectionListener {
+ public void restartCallback();
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/IDataProcessor.java b/base/console/src/com/netscape/admin/certsrv/IDataProcessor.java
new file mode 100644
index 000000000..1aa4b9049
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/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.admin.certsrv;
+
+/**
+ * this class represents the callback interface between
+ * the client package and the data storage object (data model)
+ *
+ * @author Jack Pan-Chen
+ * @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/base/console/src/com/netscape/admin/certsrv/IDisplayPanel.java b/base/console/src/com/netscape/admin/certsrv/IDisplayPanel.java
new file mode 100644
index 000000000..1a855ef22
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/IDisplayPanel.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.admin.certsrv;
+
+/**
+ * Display Panel Interface
+ *
+ * The Display Panel is plugable UI intended for the displaying of the
+ * certificate attributes. It will contain displaying components only.
+ * No editing should be allowed.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv
+ */
+public interface IDisplayPanel {
+
+ /**
+ * Set the data associated with this ui
+ */
+ public boolean setDisplayPanelContent(IAttributeContent content);
+
+ /**
+ * Retrieve the error message to be displayed to the user
+ */
+ public String getErrorMessage();
+
+} \ No newline at end of file
diff --git a/base/console/src/com/netscape/admin/certsrv/IEditorPanel.java b/base/console/src/com/netscape/admin/certsrv/IEditorPanel.java
new file mode 100644
index 000000000..c04f66549
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/IEditorPanel.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.admin.certsrv;
+
+/**
+ * Editor Panel Interface
+ *
+ * The Editor Panel is plugable UI intended for the editing of the
+ * certificate attributes. It will contain editing components only.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv
+ */
+public interface IEditorPanel {
+
+ /**
+ * Set the data associated with this ui
+ */
+ public void setEditorPanelContent(IAttributeContent content);
+
+ /**
+ * validate the content contained in this panel. Called when
+ * the user pressed ok button.
+ *
+ * this method should return false if the selections
+ * made by the user is not acceptable. ie. no selection made.
+ *
+ * getErrorMessage() will be called to retrieve the message
+ * and displayed to the user.
+ */
+ public boolean validateEditorPanelContent();
+
+ /**
+ * retrieve the attribute content from the editing panel.
+ * this method will be called after the validation has been
+ * performed.
+ */
+ public IAttributeContent getEditorPanelContent();
+
+ /**
+ * Retrieve the error message to be displayed to the user
+ */
+ public String getErrorMessage();
+} \ No newline at end of file
diff --git a/base/console/src/com/netscape/admin/certsrv/IFilterPanel.java b/base/console/src/com/netscape/admin/certsrv/IFilterPanel.java
new file mode 100644
index 000000000..2758e7152
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/IFilterPanel.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.admin.certsrv;
+
+/**
+ * Filter Panel Interface
+ *
+ * The Filter Panel is plugable UI intended for constructing search filter for
+ * the certificate attributes. It will contain the Filter type, operation type,
+ * and construct the filter string to be used by the database mapper.
+ *
+ * <XXX DOCUMENT PANEL SIZE>
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv
+ */
+public interface IFilterPanel {
+
+ /**
+ * validate the content contained in this panel. Called when
+ * the user pressed ok button.
+ *
+ * this method should return false if the selections
+ * made by the user is not acceptable. ie. no selection made.
+ *
+ * getErrorMessage() will be called to retrieve the message
+ * and displayed to the user.
+ */
+ public boolean validateFilterPanelContent();
+
+ /**
+ * name of this filter type. should be the same as attribute name.
+ */
+ public String getFilterIdentifier();
+
+ /**
+ * string representation of operation type
+ */
+ public String getFilterOperation();
+
+ /**
+ * Actual filter string to be passed on to the server side.
+ * ie. (KeyUsage==1000111)
+ */
+ public String getFilterString();
+
+ /**
+ * Retrieve the error message to be displayed to the user
+ */
+ public String getErrorMessage();
+} \ No newline at end of file
diff --git a/base/console/src/com/netscape/admin/certsrv/IMenuAction.java b/base/console/src/com/netscape/admin/certsrv/IMenuAction.java
new file mode 100644
index 000000000..59ff0562a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/IMenuAction.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.admin.certsrv;
+
+import com.netscape.management.client.*;
+
+/**
+ * This class represents the interface for the menu action listener
+ * that will be called based on the menu selection.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv
+ */
+public interface IMenuAction {
+
+ /**
+ * Perform the action for the menu item
+ */
+ public void perform(IPage viewInstance);
+
+}
+
+
+
diff --git a/base/console/src/com/netscape/admin/certsrv/IRefreshTab.java b/base/console/src/com/netscape/admin/certsrv/IRefreshTab.java
new file mode 100644
index 000000000..c69bedc4c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/IRefreshTab.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.admin.certsrv;
+
+/**
+ * The interface for refreshing the tab.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ *
+ * @see com.netscape.admin.certsrv.IRefreshTabPanel
+ * @see com.netscape.admin.certsrv.menu.RefreshTabPane
+ * @see com.netscape.admin.certsrv.CMSBaseResourceModel
+ */
+public interface IRefreshTab {
+
+ /**
+ * fresh the panel. The panel should IGNOR all
+ * modification made, retrieve the old value
+ * from the server side, and populate the UI
+ * components on this panel.
+ */
+ public void refresh();
+
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/IRefreshTabPanel.java b/base/console/src/com/netscape/admin/certsrv/IRefreshTabPanel.java
new file mode 100644
index 000000000..bc657b0db
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/IRefreshTabPanel.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.admin.certsrv;
+
+/**
+ * The interface to get selected tab from the tab panel.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.IRefreshTab
+ * @see com.netscape.admin.certsrv.menu.RefreshTabPane
+ * @see com.netscape.admin.certsrv.CMSBaseResourceModel
+ */
+public interface IRefreshTabPanel {
+
+ /**
+ * Get Selected Tab from Tab panel
+ */
+ public CMSBasePanel getSelectedTab();
+
+
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/IResourceSelectionListener.java b/base/console/src/com/netscape/admin/certsrv/IResourceSelectionListener.java
new file mode 100644
index 000000000..1f1c3deee
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/IResourceSelectionListener.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.admin.certsrv;
+
+import com.netscape.management.client.*;
+
+/**
+ * Resource Selection Notification
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public interface IResourceSelectionListener
+{
+ /**
+ * Called when the object is selected.
+ */
+ public abstract void select( IResourceObject parent, Object viewInstance);
+
+ /**
+ * Called when the object is unselected.
+ */
+ public abstract boolean unselect( IResourceObject parent, Object viewInstance);
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ISubSystemUILoader.java b/base/console/src/com/netscape/admin/certsrv/ISubSystemUILoader.java
new file mode 100644
index 000000000..1bf05dfd6
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ISubSystemUILoader.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.admin.certsrv;
+
+/**
+ * Netscape Certificate Server 4.0 SubSystem UI Loader interface
+ *
+ * This class represents the interface for the loading of UI components
+ * associated with each subsystem.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @date 03/30/97
+ */
+public interface ISubSystemUILoader {
+ public void register();
+
+} \ No newline at end of file
diff --git a/base/console/src/com/netscape/admin/certsrv/IUIMapper.java b/base/console/src/com/netscape/admin/certsrv/IUIMapper.java
new file mode 100644
index 000000000..e24e38664
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/IUIMapper.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.admin.certsrv;
+
+/**
+ * UI Mapper Interface
+ *
+ * The UIMapper is intended for the editing and
+ * the display of the certificate attributes. This
+ * includes most the certificate attributes and extensions
+ * defined in PKCS and PKIX.
+ *
+ * Each Individual UI Mapper should provide the methods
+ * defined in this interface. It must extends the
+ * JFC JPanel object. The UI Mapper should not exceeds
+ * the size of 400(Width)x450(Height). Use of LayoutManager
+ * is recommended.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv
+ */
+public interface IUIMapper {
+
+ /**
+ * Retrieve the attr name.
+ * The name will be presented to the user (i.e. Key Usage, Basic Constraints)
+ *
+ * @return attribute name
+ */
+ public String getName();
+
+ /**
+ * Retrieve the attr description.
+ * The description will be use as tool tip on the extension selection
+ * screen.
+ *
+ * @return description or null if none
+ */
+ public String getDesc();
+
+ /**
+ * Is this UI provide edit panel
+ */
+ public boolean isEditable();
+
+ /**
+ * Is this UI Provide display panel
+ */
+ public boolean isDisplayable();
+
+ /**
+ * Is this UI provide search filter panel
+ */
+ public boolean isFilterable();
+
+ /**
+ * retrieve Editor Panel
+ * isEditable() will be called before this operation is
+ * used.
+ */
+ public IEditorPanel getEditorPanel();
+
+ /**
+ * retrieve Display Panel
+ */
+ public IDisplayPanel getDisplayPanel();
+
+ /**
+ * Retrieve Filter Panel
+ */
+ public IFilterPanel getFilterPanel();
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/LabelCellRenderer.java b/base/console/src/com/netscape/admin/certsrv/LabelCellRenderer.java
new file mode 100644
index 000000000..ea41f6b45
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/LabelCellRenderer.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.admin.certsrv;
+
+import java.awt.*;
+import java.lang.*;
+import javax.swing.table.*;
+import javax.swing.border.*;
+import javax.swing.*;
+import java.io.Serializable;
+
+/**
+ * Class that will render label correctly in table
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv
+ */
+public class LabelCellRenderer
+ implements TableCellRenderer, Serializable
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ protected JComponent component;
+ protected ValueProperty value;
+ public final static Color HIGHLIGHTCOLOR = new Color(0, 0, 128);
+ public final static Color WHITECOLOR = Color.white;
+ public final static Color BLACKCOLOR = Color.black;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ public LabelCellRenderer(JLabel x) {
+ component = x;
+ x.setOpaque(true);
+ x.setBorder(new EmptyBorder(1,CMSAdminUtil.COMPONENT_SPACE, 1, 2));
+ JTextField temp = new JTextField();
+ x.setFont(temp.getFont());
+ value = new ValueProperty();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ public void setToolTipText(String text) {
+ if (component instanceof JComponent)
+ ((JComponent)component).setToolTipText(text);
+ }
+
+ public Component getComponent() {
+ return component;
+ }
+
+ //==== Implementing TableCellRenderer =========
+
+ public Component getTableCellRendererComponent(JTable table, Object value,
+ boolean isSelected,
+ boolean hasFocus,
+ int row, int column) {
+
+ if(value == null) {
+ value = table.getModel().getValueAt(row, column);
+ }
+ this.value.setValue(value);
+ component.setBackground(isSelected ? HIGHLIGHTCOLOR : WHITECOLOR);
+ component.setForeground(isSelected ? WHITECOLOR : BLACKCOLOR);
+ return component;
+ }
+
+
+ public class ValueProperty implements Serializable {
+ public Object value;
+
+ public void setValue(Object x) {
+ if (x == null) {
+ value = "";
+ //System.out.println("SetValue: x is null");
+ } else {
+ value = x;
+ }
+ if (x instanceof Icon)
+ ((JLabel)component).setIcon((Icon)x);
+ if (x instanceof String)
+ ((JLabel)component).setText(x.toString());
+ if (x instanceof JLabel) {
+ //System.out.println("SetValue: TTIP="+((JLabel)x).getToolTipText());
+ ((JLabel)component).setIcon(((JLabel)x).getIcon());
+ ((JLabel)component).setText(((JLabel)x).getText());
+ ((JLabel)component).setHorizontalAlignment(((JLabel)x).getHorizontalAlignment());
+ ((JLabel)component).setToolTipText(((JLabel)x).getToolTipText());
+ }
+ }
+
+ }
+
+}
+
+
diff --git a/base/console/src/com/netscape/admin/certsrv/MultilineLabelUI.java b/base/console/src/com/netscape/admin/certsrv/MultilineLabelUI.java
new file mode 100644
index 000000000..931732675
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/MultilineLabelUI.java
@@ -0,0 +1,534 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv;
+
+import java.util.*;
+import javax.swing.*;
+import javax.swing.plaf.basic.*; //<JFC1.0>
+//<JFC0.7>import javax.swing.basic.*;
+import javax.swing.plaf.*;
+import java.awt.event.ActionEvent;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.awt.Insets;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.io.Serializable;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import javax.swing.AbstractAction;
+
+/**
+ * Specific UI to handle to the line wrap for the multi-line log entries.
+ *
+ * This UI component extends the BasicLabelUI to handle multi-line label.
+ * NOTE:
+ * [1] This class does not break up the lines automatically. It relies on
+ * '\n' in input text.
+ * [2] This UI implementation can NOT be shared between components. Each
+ * JLabel instance needs to install its own instance of MultilineLabelUI.
+ * TODO:
+ * [1] clipping, append "..."
+ * [2] auto wrapping
+ *
+ * @version $Revision$, $Date$
+ */
+public class MultilineLabelUI extends BasicLabelUI {
+
+ /**
+ * Replaced with our own layout routine.
+ *
+ * @see SwingUtilities#layoutCompoundLabel
+ */
+ protected String layoutCL(
+ JLabel label,
+ FontMetrics fontMetrics,
+ String text,
+ Icon icon,
+ Rectangle viewR,
+ Rectangle iconR,
+ Rectangle textR)
+ {
+ return layoutCompoundLabel(
+ fontMetrics,
+ text,
+ icon,
+ label.getVerticalAlignment(),
+ label.getHorizontalAlignment(),
+ label.getVerticalTextPosition(),
+ label.getHorizontalTextPosition(),
+ viewR,
+ iconR,
+ textR,
+ label.getIconTextGap());
+ }
+
+ /**
+ * Paint the label text in the foreground color, if the label
+ * is opaque then paint the entire background with the background
+ * color. The Label text is drawn by paintEnabledText() or
+ * paintDisabledText(). The locations of the label parts are computed
+ * by layoutCL.
+ *
+ * @see #paintEnabledText
+ * @see #paintDisabledText
+ * @see #layoutCL
+ */
+ public void paint(Graphics g, JComponent c) {
+ JLabel label = (JLabel)c;
+ String text = label.getText();
+ Icon icon = (label.isEnabled()) ? label.getIcon() : label.getDisabledIcon();
+ int i;
+
+ if ((icon == null) && (text == null)) {
+ return;
+ }
+
+ //g.setFont(label.getFont());
+ FontMetrics fm = g.getFontMetrics();
+ Rectangle iconR = new Rectangle();
+ Rectangle textR = new Rectangle();
+ Rectangle viewR = new Rectangle(c.getSize());
+ Insets viewInsets = c.getInsets();
+
+ viewR.x = viewInsets.left;
+ viewR.y = viewInsets.top;
+ viewR.width -= (viewInsets.left + viewInsets.right);
+ viewR.height -= (viewInsets.top + viewInsets.bottom);
+
+ //Debug.println("---> Calling layoutCL from paint");
+ layoutCL(label, fm, text, icon, viewR, iconR, textR);
+
+ if (icon != null) {
+ icon.paintIcon(null, g, iconR.x, iconR.y);
+ }
+
+ int horizontalAlignment = ((JLabel)c).getHorizontalAlignment();
+
+ if (text != null) {
+ int textX = textR.x;
+ int textY = textR.y + fm.getAscent();
+ char accChar = (char)label.getDisplayedMnemonic(); //<JFC1.0>
+ //<JFC0.7>char accChar = (char)label.getDisplayedKeyAccelerator();
+ char tmpChar;
+ int h = fm.getHeight();
+
+ int firstAccCharLine = findAccChar(textVector, accChar);
+
+ /* NOTE: draws each string in the textVector */
+ if (label.isEnabled()) {
+ g.setColor(label.getForeground());
+ for (i = 0; i < textVector.size(); i++) {
+ if (i == firstAccCharLine) {
+ tmpChar = accChar;
+ }
+ else {
+ tmpChar = '\0';
+ }
+ BasicGraphicsUtils.drawString(g,
+ (String)textVector.elementAt(i), tmpChar,
+ offsetArray[0], textY+h*i);
+ //offsetArray[i], textY+h*i);
+ }
+ }
+ else {
+ g.setColor(Color.gray);
+ for (i = 0; i < textVector.size(); i++) {
+ if (i == firstAccCharLine) {
+ tmpChar = accChar;
+ }
+ else {
+ tmpChar = '\0';
+ }
+ BasicGraphicsUtils.drawString(g,
+ (String)textVector.elementAt(i), tmpChar,
+ offsetArray[i], textY+h*i);
+ }
+ g.setColor(Color.white);
+ for (i = 0; i < textVector.size(); i++) {
+ if (i == firstAccCharLine) {
+ tmpChar = accChar;
+ }
+ else {
+ tmpChar = '\0';
+ }
+ BasicGraphicsUtils.drawString(g,
+ (String)textVector.elementAt(i), tmpChar,
+ offsetArray[i] + 1, textY + 1 + h*i);
+ }
+ }
+ }
+ }
+
+ public Dimension getPreferredSize(JComponent c) {
+ Dimension realSize = super.getPreferredSize(c);
+ //Debug.println("MultilineLabelUI: realSize " + realSize);
+ int width, height;
+
+ /* if preferred width is set, always use the preferred width
+ */
+ if (preferredSize != null) {
+ width = preferredSize.width;
+ }
+ else {
+ width = realSize.width;
+ }
+ /* compare computed height with the preferred height,
+ * return whichever is larger
+ */
+ height = realSize.height;
+ if (preferredSize != null) {
+ height = preferredSize.height > height ?
+ preferredSize.height : height;
+ }
+ Dimension result = new Dimension(width, height);
+ //Debug.println("MultilineLabelUI: preferredSize " + result);
+ return result;
+ }
+
+ private final int computeStringVWidth(FontMetrics fm, Vector strV, int[] widthA) {
+ int w = 0, width = 0;
+ //Debug.println("computeStringWidth: vsize " + strV.size());
+ for (int i = 0; i < strV.size(); i++) {
+ w = SwingUtilities.computeStringWidth(fm, (String)strV.elementAt(i));
+ //Debug.println("computeStringWidth: w for " + (String)strV.elementAt(i) + " is " + w);
+ widthA[i] = w;
+ if (w > width) width = w;
+ }
+ //Debug.println("computeStringWidth: width " + width);
+ return width;
+ }
+
+ public static ComponentUI createUI(JComponent c) {
+ return new MultilineLabelUI();
+ }
+
+ /* NOTE: " " has to be the first entry */
+ static final String[] SEPARATORS = {" ", ".", ",", "?", "-", ":", ";", "!", "/", "\\"};
+ Vector textVector;
+ int[] widthArray;
+ int[] offsetArray;
+
+ protected Dimension preferredSize;
+
+ boolean _parsed = false;
+
+ public void parse() {
+ _parsed = false;
+ }
+
+ /**
+ * Only the preferred width is observed. MultilineLabelUI will break
+ * the input text into multiple lines by calling wrapString. Derived
+ * class should overrid wrapString to provide different parsing behavior.
+ * The result of wrapString will determine the preferred height of this
+ * component.
+ */
+ public void setWrap(int width) {
+ if (preferredSize == null) {
+ preferredSize = new Dimension();
+ }
+ preferredSize.width = width;
+ }
+
+ /**
+ * This method break the input text into a vector of strings.
+ * The default implementation is based on '\n' in the text.
+ * Override this method to provide different parsing behavior.
+ * wrapString expects the input string to be the last element
+ * in the vector.
+ */
+ protected void wrapString(Vector v, FontMetrics fm, int w, String[] separators) {
+ String s = (String)v.lastElement();
+ //Debug.println("----> calling wrapString with " + s);
+ if ((null == s) || ("".equals(s))) {
+ return;
+ }
+ if (fm.stringWidth(s) > w) {
+ String s1 = s, s2 = "";
+ int i = -1;
+ int j;
+ int k;
+ while (fm.stringWidth(s1) > w) {
+ for (j = 0; j < separators.length; j++) {
+ i = s1.lastIndexOf(separators[j]);
+ if (i != -1 && i != (s1.length()-1)) {
+ break;
+ }
+ }
+ if (i == -1) {
+ for (k = s1.length()-1; k > 1; k--) {
+ String test = s1.substring(0, k-1);
+ if (fm.stringWidth(test) < w) {
+ s1 = test;
+ s2 = s.substring(s1.length());
+ break;
+ }
+ }
+ }
+ else {
+ s1 = (s1.substring(0, i+1)).trim();
+ s2 = s.substring(i+1);
+ }
+ }
+ v.removeElementAt(v.size() - 1);
+ v.addElement(s1);
+ v.addElement(s2.trim());
+ wrapString(v, fm, w, separators);
+ }
+ else {
+ return;
+ }
+ }
+
+ protected void parseTextV(String text, Vector textV) {
+ if (text == null || "".equals(text)) {
+ textV.addElement("");
+ return;
+ }
+
+ char[] textContent = text.toCharArray();
+ int begin = 0, end = 0;
+ for (end = 0; end < textContent.length; end++) {
+ if (textContent[end] == '\n') {
+ textV.addElement(new String(textContent, begin, end - begin));
+ begin = end + 1;
+ }
+ }
+ if (begin != textContent.length) {
+ textV.addElement(new String(textContent, begin, end - begin));
+ }
+ }
+
+ public String layoutCompoundLabel(
+ FontMetrics fm,
+ String text,
+ Icon icon,
+ int verticalAlignment,
+ int horizontalAlignment,
+ int verticalTextPosition,
+ int horizontalTextPosition,
+ Rectangle viewR,
+ Rectangle iconR,
+ Rectangle textR,
+ int textIconGap)
+ {
+ /* Initialize the icon bounds rectangle iconR.
+ */
+
+ if (icon != null) {
+ iconR.width = icon.getIconWidth();
+ iconR.height = icon.getIconHeight();
+ }
+ else {
+ iconR.width = iconR.height = 0;
+ }
+
+ /* Initialize the text bounds rectangle textR. If a null
+ * or and empty String was specified we substitute "" here
+ * and use 0,0,0,0 for textR.
+ */
+
+ boolean textIsEmpty = (text == null) || text.equals("");
+
+ /* Unless both text and icon are non-null, we effectively ignore
+ * the value of textIconGap. The code that follows uses the
+ * value of gap instead of textIconGap.
+ */
+
+ int gap = (textIsEmpty || (icon == null)) ? 0 : textIconGap;
+
+ /* NOTE: break up the text into multiple lines */
+ /* TODO: clean up parseTextV and wrapString */
+ if (!_parsed) {
+ textVector = new Vector();
+ if (preferredSize != null) {
+ /* remove newline before calling wrapString
+ if (!textIsEmpty) {
+ text = text.replace('\n', ' ');
+ }
+ textVector.addElement(text);
+ */
+
+ int iconW;
+ iconW = (icon == null) ? 0 : icon.getIconWidth();
+
+ Vector tmp = new Vector();
+ //Debug.println("calling parseTextV with " + text);
+ parseTextV(text, tmp);
+ for (Enumeration e = tmp.elements(); e.hasMoreElements(); ) {
+ String subs = (String)e.nextElement();
+ //Debug.println("parseTextV returns " + subs);
+ textVector.addElement(subs);
+ wrapString(textVector, fm, preferredSize.width - gap - iconW, SEPARATORS);
+ }
+ }
+ else {
+ parseTextV(text, textVector);
+ }
+ _parsed = true;
+ }
+ widthArray = new int[textVector.size()];
+ offsetArray = new int[widthArray.length];
+
+ if (textIsEmpty) {
+ textR.width = textR.height = 0;
+ text = "";
+ }
+ else {
+ textR.width = computeStringVWidth(fm,textVector,widthArray);
+ textR.height = fm.getHeight() * textVector.size();
+ }
+
+ /* NOTE: we need to handle clipped case
+ if (!textIsEmpty) {
+
+ int availTextWidth;
+
+ if (horizontalTextPosition == CENTER) {
+ availTextWidth = viewR.width;
+ }
+ else {
+ availTextWidth = viewR.width - (iconR.width + gap);
+ }
+
+
+ if (textR.width > availTextWidth) {
+ String clipString = "...";
+ int totalWidth = computeStringWidth(fm,clipString);
+ int nChars;
+ for(nChars = 0; nChars < text.length(); nChars++) {
+ totalWidth += fm.charWidth(text.charAt(nChars));
+ if (totalWidth > availTextWidth) {
+ break;
+ }
+ }
+ text = text.substring(0, nChars) + clipString;
+ textR.width = computeStringWidth(fm,text);
+ }
+ }
+ */
+
+
+ /* Compute textR.x,y given the verticalTextPosition and
+ * horizontalTextPosition properties
+ */
+
+ if (verticalTextPosition == SwingUtilities.TOP) {
+ if (horizontalTextPosition != SwingUtilities.CENTER) {
+ textR.y = 0;
+ }
+ else {
+ textR.y = -(textR.height + gap);
+ }
+ }
+ else if (verticalTextPosition == SwingUtilities.CENTER) {
+ textR.y = (iconR.height / 2) - (textR.height / 2);
+ }
+ else { // (verticalTextPosition == SwingUtilities.BOTTOM)
+ if (horizontalTextPosition != SwingUtilities.CENTER) {
+ textR.y = iconR.height - textR.height;
+ }
+ else {
+ textR.y = (iconR.height + gap);
+ }
+ }
+
+ if (horizontalTextPosition == SwingUtilities.LEFT) {
+ textR.x = -(textR.width + gap);
+ }
+ else if (horizontalTextPosition == SwingUtilities.CENTER) {
+ textR.x = (iconR.width / 2) - (textR.width / 2);
+ }
+ else { // (verticalTextPosition == SwingUtilities.RIGHT)
+ textR.x = (iconR.width + gap);
+ }
+
+ /* labelR is the rectangle that contains iconR and textR.
+ * Move it to its proper position given the labelAlignment
+ * properties.
+ */
+
+ Rectangle labelR = iconR.union(textR);
+ int dx, dy;
+
+ if (verticalAlignment == SwingUtilities.TOP) {
+ dy = viewR.y - labelR.y;
+ }
+ else if (verticalAlignment == SwingUtilities.CENTER) {
+ dy = (viewR.y + (viewR.height / 2)) - (labelR.y + (labelR.height / 2));
+ }
+ else { // (verticalAlignment == SwingUtilities.BOTTOM)
+ dy = (viewR.y + viewR.height) - (labelR.y + labelR.height);
+ }
+
+ if (horizontalAlignment == SwingUtilities.LEFT) {
+ dx = viewR.x - labelR.x;
+ }
+ else if (horizontalAlignment == SwingUtilities.CENTER) {
+ dx = (viewR.x + (viewR.width / 2)) - (labelR.x + (labelR.width / 2));
+ }
+ else { // (horizontalAlignment == SwingUtilities.RIGHT)
+ dx = (viewR.x + viewR.width) - (labelR.x + labelR.width);
+ }
+
+ /* Translate textR and glypyR by dx,dy.
+ */
+ textR.x += dx;
+ textR.y += dy;
+
+ iconR.x += dx;
+ iconR.y += dy;
+
+ /* NOTE: calculate string offsets based on the string width and
+ * horizontal alignment
+ */
+ computeOffset(textR, horizontalAlignment, widthArray, offsetArray);
+
+ //Debug.println("layoutCompound: " + text + " " + textR);
+ return text;
+ }
+
+ final void computeOffset(Rectangle textR, int horizontalAlignment, int[] widthA, int[] offsetA) {
+ for (int i = 0; i < widthA.length; i++) {
+ if (SwingConstants.LEFT == horizontalAlignment) {
+ offsetA[i] = textR.x;
+ }
+ else if (SwingConstants.RIGHT == horizontalAlignment) {
+ offsetA[i] = textR.x + textR.width - widthA[i];
+ }
+ else if (SwingConstants.CENTER == horizontalAlignment) {
+ offsetA[i] = textR.x + (int)((textR.width - widthA[i]) * 0.5);
+ }
+ }
+ }
+
+ final int findAccChar(Vector strV, char c) {
+ for (int i = 0; i < strV.size(); i++) {
+ String s = (String)strV.elementAt(i);
+ if (s.indexOf(c) != -1) {
+ return i;
+ }
+ }
+ return 0;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/PasswordCellRenderer.java b/base/console/src/com/netscape/admin/certsrv/PasswordCellRenderer.java
new file mode 100644
index 000000000..172f0499e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/PasswordCellRenderer.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.admin.certsrv;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.table.*;
+
+/**
+ * class used to creat the password label
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class PasswordCellRenderer extends JLabel
+ implements ListCellRenderer, TableCellRenderer
+{
+ static Color HIGHLIGHTCOLOR = new Color(0, 0, 128);
+ static Color WHITECOLOR = Color.white;
+ static Color BLACKCOLOR = Color.black;
+
+ public PasswordCellRenderer() {
+ super();
+ setOpaque(true);
+ setBorder(new EmptyBorder(1,CMSAdminUtil.COMPONENT_SPACE, 1, 2));
+ JPasswordField temp = new JPasswordField();
+ setFont(temp.getFont());
+ }
+
+ public Component getListCellRendererComponent(JList list,
+ Object value, int index, boolean isSelected, boolean cellHasFocus) {
+ StringBuffer buf = new StringBuffer();
+ for(int i=0; i< ((String)value).length(); i++)
+ buf.append("*");
+ setText(buf.toString());
+ setBackground(isSelected ? HIGHLIGHTCOLOR : WHITECOLOR);
+ setForeground(isSelected ? WHITECOLOR : BLACKCOLOR);
+ return this;
+ }
+
+ public Component getTableCellRendererComponent(JTable table, Object value,
+ boolean isSelected, boolean hasFocus, int row, int column) {
+ if (value!=null) {
+ StringBuffer buf = new StringBuffer();
+ for(int i=0; i< ((String)value).length(); i++)
+ buf.append("*");
+ setText(buf.toString());
+ setBackground(isSelected ? HIGHLIGHTCOLOR : WHITECOLOR);
+ setForeground(isSelected ? WHITECOLOR : BLACKCOLOR);
+ }
+ return this;
+
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/StatusItemContinuousProgress.java b/base/console/src/com/netscape/admin/certsrv/StatusItemContinuousProgress.java
new file mode 100644
index 000000000..6945456f1
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/StatusItemContinuousProgress.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.admin.certsrv;
+
+import java.lang.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Status bar item for continuous progress feedback
+ * [This one is borrowed from directory server]
+ *
+ * @author kirwin
+ * @version %I%, %G%
+ * @date 4/8/98
+ * @see com.netscape.admin.certsrv
+ */
+public class StatusItemContinuousProgress extends StatusItemProgress
+{
+ private int _val = 0;
+ private static int VALUE_INCREMENT = 9;
+ private static int UPDATE_INTERVAL = 50;
+ private static int INITIAL_DELAY = 0;
+ private ProgressTracker _thread;
+ private boolean _running = false;
+
+ public StatusItemContinuousProgress(String id) {
+ super(id, 0);
+ _thread = new ProgressTracker();
+ _thread.start();
+ }
+
+ public void start() {
+ if (!_running) {
+ _running = true;
+ _val = 0;
+ setValue(0);
+ _thread.resume();
+ }
+ }
+
+ public void stop() {
+ if (_running) {
+ _running = false;
+ _val = 0;
+ setValue(0);
+ }
+ }
+
+ private void increment() {
+ Graphics g = getGraphics();
+ if ((_val += VALUE_INCREMENT) > 99) {
+ _val = 0;
+ if (g != null) {
+ Rectangle r = getBounds();
+ g.clearRect(0, 0, r.width, r.height);
+ }
+ }
+ setValue(_val);
+ update(g);
+ }
+
+ private class ProgressTracker extends Thread {
+
+ public void run() {
+ while (true) {
+ while (_running) {
+ increment();
+ try {
+ sleep(UPDATE_INTERVAL);
+ } catch (InterruptedException e) {
+ Debug.println("sleep exception");
+ }
+ }
+ suspend();
+ }
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/UIMapperRegistry.java b/base/console/src/com/netscape/admin/certsrv/UIMapperRegistry.java
new file mode 100644
index 000000000..531a0b5fc
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/UIMapperRegistry.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.admin.certsrv;
+
+import com.netscape.management.client.util.*;
+import java.security.cert.CertificateException;
+import netscape.security.x509.*;
+import java.util.*;
+
+/**
+ * UIMapper Registry
+ *
+ * This Registry keeps track of the mappings between the certificate
+ * attribute class and the UI Mapper.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.IUIMapper
+ */
+public class UIMapperRegistry {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static UIMapperRegistry mSelf = null;
+ private static Hashtable mAttrContent = new Hashtable();
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * register new certificate attribute.
+ *
+ * @param className fully qualified class name implementing CertAttrSet
+ * @param oid the string representation of the object identifier
+ * @param extentionName the name of the attribute.
+ * @param mapperClassName fully qualified class name implementing UI
+ */
+ /* XXX WE DON'T NEED THIS
+ public static void registerCertAttrUI(String className, String oid,
+ String attrName, String mapperClassName)
+ throws ClassNotFoundException, CertificateException
+ {
+ Class extClass, mapClass;
+ extClass = Class.forName(className);
+ mapClass = Class.forName(mapperClassName);
+ OIDMap.addAttribute(className,oid,attrName);
+ registerCertAttrUI(attrName,mapperClassName);
+ }
+ */
+
+ /**
+ * internal register new cert attr
+ *
+ * @param className fully qualified class name implementing CertAttrSet
+ * @param extentionName the name of the attribute.
+ * @param mapperClassName fully qualified class name implementing UI
+ */
+ public static void registerCertAttrUI(String attrName, String mapperClassName) {
+ mAttrContent.put(attrName, mapperClassName);
+ }
+
+ /**
+ * Retrieve all certificate attribute name
+ */
+ public static Enumeration getCertAttrNames() {
+ return mAttrContent.keys();
+ }
+
+ /**
+ * Retrieve all extension UI Mappers
+ */
+ public static Enumeration getCertAttrUIs() {
+ return mAttrContent.elements();
+ }
+
+ /**
+ * Get instance of UI Mapper by certificate attribute name
+ *
+ * @param certAttrClassName certificate attribute name
+ */
+ public static IUIMapper getCertAttrUI(String certAttrClassName)
+ throws InstantiationException, IllegalAccessException, ClassNotFoundException
+ {
+ String mapperClassName = (String) mAttrContent.get(certAttrClassName);
+ Class mapClass = Class.forName(mapperClassName);
+ IUIMapper instance = (IUIMapper) mapClass.newInstance();
+ return instance;
+ }
+
+ //load the static stuff here
+ static {
+ loadUIMappings();
+ }
+
+ //loads the standard UI components
+ private static void loadUIMappings() {
+ /*
+ UIMapperRegistry registry = UIMapperRegistry.getUIMapperRegistry();
+ registry.addExtensionMapping
+ */
+ }
+
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/certsrv-help.properties b/base/console/src/com/netscape/admin/certsrv/certsrv-help.properties
new file mode 100644
index 000000000..1faf8ef68
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/certsrv-help.properties
@@ -0,0 +1,534 @@
+;Last update: Aug 19, 1998
+
+; CA General Setting
+configuration-ca-general-help = cert
+configuration-ca-connector-help = cert
+configuration-ca-connector-editor-help = cert
+
+; Notification
+notification-ra-reqinq-help = cert
+notification-ra-certissued-help = cert
+notification-ca-reqinq-help = cert
+notification-ca-certissued-help = cert
+
+; Job scheduling
+jobsscheduler-certsrv-setting-jobrule-help = cert
+jobsscheduler-certsrv-jobrules-help = cert
+jobsscheduler-certsrv-add-jobrule-dbox-help = cert
+jobsscheduler-certsrv-edit-jobrule-dbox-help = cert
+jobsscheduler-certsrv-jobplugin-help = cert
+jobsscheduler-certsrv-register-jobplugin-dbox-help = cert
+;OOTB job plugins
+configuration-jobrules-renewalnotification = cert
+configuration-jobrules-requestinqueuejob = cert
+configuration-jobrules-unpublishexpiredjobs = cert
+
+;Certificate server configuration settings
+;
+;Network configuration
+configuration-system-network-help = cert
+;Database configuration
+configuration-database-settings-help = cert
+;Encryption configuration
+configuration-system-encryption-help = cert
+;SNMP configuration
+configuration-system-snmp-help = cert
+;SMTP configuration
+configuration-system-smtp-help = cert
+;System log configuration
+configuration-logs-system-help = cert
+;Error log configuration
+configuration-logs-error-help = cert
+;Transactions log configuration
+configuration-logs-audit-help = cert
+;log instance configuration
+configuration-loginstances-help = cert
+;log plugin configuration
+configuration-log-plugin-help = cert
+;add log plugin configuration
+configuration-add-logrule-dbox-help = cert
+configuration-logrules-logfile = cert
+configuration-logrules-rollinglogfile = cert
+configuration-logrules-nteventlog = cert
+
+;RA configuration settings
+;
+;General settings
+configuration-ra-general-help = cert
+;RA connector
+configuration-ra-connector-help = cert
+;RA connector editor
+configuration-ra-connector-editor-help = cert
+;Certificate life cycle management configuration
+configuration-ra-clm-help = cert
+;Policy rules management
+configuration-ra-policyrules-help = cert
+;Add policy rules management
+configuration-ra-add-policyrule-dbox-help = cert
+;Edit policy rules management
+configuration-ra-edit-policyrule-dbox-help = cert
+;Reorder policy rules management
+configuration-ra-reorder-policyrule-dbox-help = cert
+;Policy plugin registration
+configuration-ra-policyplugin-help = cert
+;Register policy plugin registration
+configuration-ra-register-policyplugin-dbox-help = cert
+;Servlet management
+configuration-ra-servletmgt-help = cert
+;Add servlet plugin implementation
+configuration-ra-add-servletplugin-dbox-help = cert
+;Edit servlet instance
+configuration-ra-edit-servlet-dbox-help = cert
+;Servlet plugin registration
+configuration-ra-servletplugin-help = cert
+;Register plugin registration
+configuration-ra-register-servletplugin-dbox-help = cert
+
+;CRL Extensions configuration settings
+configuration-ca-crlextensioninstances-help = cert
+configuration-ca-edit-crlextensionrule-dbox-help = cert
+configuration-ca-add-crlextensionrule-dbox-help = cert
+;CRL Extensions
+configuration-ca-edit-crlextension-authoritykeyidentifier = cert
+configuration-ca-edit-crlextension-issueralternativename = cert
+configuration-ca-edit-crlextension-crlnumber = cert
+configuration-ca-edit-crlextension-issuingdistributionpoint = cert
+;CRL Entry Extensions
+configuration-ca-edit-crlextension-crlreason = cert
+configuration-ca-edit-crlextension-holdinstruction = cert
+configuration-ca-edit-crlextension-invaliditydate = cert
+configuration-ca-edit-crlextension-certificateissuer = cert
+;CRL Extensions Management
+configuration-ca-crlinstances-help = cert
+
+;Destination for LDAP publishing
+configuration-ra-ldappublish-destination-help = cert
+;User certificate for LDAP publishing
+configuration-ra-ldappublish-usercert-help = cert
+;Mapper configuration for CA LDAP publishing
+configuration-ldappublish-camapper-dbox-help = cert
+;Mapper configuration for RA LDAP publishing
+configuration-ldappublish-ramapper-dbox-help = cert
+
+;LDAP publishing mappers 12/29/99
+configuration-ca-edit-mapperrule-dbox-help = cert
+configuration-ca-mapperinstances-help = cert
+configuration-ca-mapperplugin-help = cert
+configuration-ca-add-mapperrule-dbox-help = cert
+configuration-ldappublish-mapper-simplemapper = cert
+configuration-ldappublish-mapper-casimplemapper = cert
+configuration-ldappublish-mapper-certexactmapper = cert
+configuration-ldappublish-mapper-certsubjmapper = cert
+configuration-ldappublish-mapper-dncompsmapper = cert
+
+;LDAP publishers 12/29/99
+configuration-ca-edit-publisherrule-dbox-help = cert
+configuration-ca-publisherinstances-help = cert
+configuration-ca-publisherplugin-help = cert
+configuration-ca-add-publisherrule-dbox-help = cert
+configuration-ldappublish-publisher-filepublisher = cert
+configuration-ldappublish-publisher-cacertpublisher = cert
+configuration-ldappublish-publisher-certsubjpublisher = cert
+configuration-ldappublish-publisher-crlpublisher = cert
+configuration-ldappublish-publisher-usercertpublisher = cert
+configuration-ldappublish-publisher-ocsppublisher = cert
+
+;LDAP publish rule 01/25/00
+configuration-ca-ruleinstances-help = cert
+configuration-ca-edit-rulerule-dbox-help = cert
+configuration-ca-add-rulerule-dbox-help = cert
+
+
+;Policies 12/29/99
+configuration-policyrules-authkeyid = cert
+configuration-policyrules-basicconstraints = cert
+configuration-policyrules-crldistributionpoints = cert
+configuration-policyrules-certificatepolicies = cert
+configuration-policyrules-certificatescopeofuse = cert
+configuration-policyrules-dsakeyconstraints = cert
+configuration-policyrules-extendedkeyusage = cert
+configuration-policyrules-genericasn1ext = cert
+configuration-policyrules-issueraltname = cert
+configuration-policyrules-issuerconstraints = cert
+configuration-policyrules-keyalgorithmconstraints = cert
+configuration-policyrules-keyusage = cert
+configuration-policyrules-nameconstraints = cert
+configuration-policyrules-nsccomment = cert
+configuration-policyrules-nscerttype = cert
+configuration-policyrules-ocspnocheck = cert
+configuration-policyrules-pinpresent = cert
+configuration-policyrules-privatekeyusageperiod = cert
+configuration-policyrules-renewalconstraints = cert
+configuration-policyrules-renewalvalidityconstraints = cert
+configuration-policyrules-revocationconstraints = cert
+configuration-policyrules-rsakeyconstraints = cert
+configuration-policyrules-subcanamecheck = cert
+configuration-policyrules-subjaltname = cert
+configuration-policyrules-subjectdirectoryattributes = cert
+configuration-policyrules-subjectkeyidentifier = cert
+configuration-policyrules-uniquesubjectname = cert
+configuration-policyrules-validityconstraints = cert
+configuration-policyrules-defaultrevocation = cert
+configuration-policyrules-policyconstraints = cert
+configuration-policyrules-signingalgconstraints = cert
+configuration-policyrules-policymappings = cert
+configuration-policyrules-authinfoaccess = cert
+configuration-policyrules-certificaterenewalwindow = cert
+
+;CA configuration settings
+;
+;Policy rules management
+configuration-ca-policyrules-help = cert
+;Add policy rules management
+configuration-ca-add-policyrule-dbox-help = cert
+;Edit policy rules management
+configuration-ca-edit-policyrule-dbox-help = cert
+;Reorder policy rules management
+configuration-ca-reorder-policyrule-dbox-help = cert
+;Policy plugin registration
+configuration-ca-policyplugin-help = cert
+;Register policy plugin registration
+configuration-ca-register-policyplugin-dbox-help = cert
+;Servlet management
+configuration-ca-servletmgt-help = cert
+;Add servlet plugin implementation
+configuration-ca-add-servletplugin-dbox-help = cert
+;Edit servlet instance
+configuration-ca-edit-servlet-dbox-help = cert
+;Servlet plugin registration
+configuration-ca-servletplugin-help = cert
+;Register plugin registration
+configuration-ca-register-servletplugin-dbox-help = cert
+;Destination for LDAP publishing
+configuration-ca-ldappublish-destination-help = cert
+;CRL setting for LDAP publishing
+configuration-ca-ldappublish-crl-help = cert
+;CA certificate for LDAP publishing
+configuration-ca-ldappublish-cacert-help = cert
+;User certificate for LDAP publishing
+configuration-ca-ldappublish-usercert-help = cert
+
+;OCSP configuration
+;
+;Online Certificate Status Manager
+configuration-ocsp-general-help = cert
+;Revocation Info Stores
+configuration-ocsp-storeinstances-help = cert
+
+;KRA configuration settings
+;
+;Auto recovery
+configuration-kra-autorecovery-help = cert
+;User ids and passwords for auto recovery
+configuration-kra-autorecovery-agents-dbox-help = cert
+;Scheme management
+configuration-kra-schememgt-help = cert
+;Change recovery key scheme
+configuration-kra-wizard-change-keyscheme-help = cert
+;Enter existing recovery agent password
+configuration-kra-wizard-agentpwd-keyscheme-help = cert
+;Enter new recovery agent password
+configuration-kra-wizard-newagentpwd-keyscheme-help = cert
+;Recovery agent password
+configuration-kra-agentpwd-help = cert
+;Change agent password
+configuration-kra-change-agentpwd-dbox-help = cert
+;Policy rules management
+configuration-kra-policyrules-help = cert
+;Add policy rules management
+configuration-kra-add-policyrule-dbox-help = cert
+;Edit policy rules management
+configuration-kra-edit-policyrule-dbox-help = cert
+;Reorder policy rules management
+configuration-kra-reorder-policyrule-dbox-help = cert
+;Policy plugin registration
+configuration-kra-policyplugin-help = cert
+;Register policy plugin registration
+configuration-kra-register-policyplugin-dbox-help = cert
+
+;ACL configuration settings
+;
+;ACL
+configuration-acl-resourceobjects-help = cert
+configuration-acl-evaluators-help = cert
+configuration-acl-edit-help = cert
+configuration-acl-aci-edit-help = cert
+
+;Keys and certificates settings
+;
+;Keys and certs
+configuration-keycert-wizard-introduction-help = cert
+configuration-keycert-wizard-operationselection-help = cert
+configuration-keycert-wizard-certtype-help = cert
+configuration-keycert-wizard-key-help = cert
+configuration-keycert-wizard-subjectdn-help = cert
+configuration-keycert-wizard-validityperiod-help = cert
+configuration-keycert-wizard-certrequest-help = cert
+configuration-keycert-wizard-extension-help = cert
+configuration-keycert-wizard-selfsignedcert-help = cert
+configuration-keycert-wizard-selfsignedstatus-help = cert
+configuration-keycert-wizard-displaycertrequest-help = cert
+configuration-keycert-wizard-certrequeststatus-help = cert
+configuration-keycert-wizard-installcerttype-help = cert
+configuration-keycert-wizard-pastecert-help = cert
+configuration-keycert-wizard-displaycert-help = cert
+configuration-keycert-wizard-installcertstatus-help = cert
+configuration-keycert-wizard-tokenlogon-help = cert
+configuration-keycert-wizard-messagedigest-help = cert
+
+;Manage certificate
+;
+configuration-managecert-wizard-certlists-help = cert
+configuration-managecert-wizard-trustcert-help = cert
+
+;Certificate server authentication
+;
+;Users
+usersgroups-certsrv-users-help = cert
+;Add user
+usersgroups-certsrv-add-user-dbox-help = cert
+;Edit user information
+usersgroups-certsrv-edit-user-dbox-help = cert
+usersgroups-certsrv-select-user-dbox-help = cert
+;Manage user certificates
+usersgroups-certsrv-manage-usercert-dbox-help = cert
+;Groups
+usersgroups-certsrv-groups-help = cert
+;Add group
+usersgroups-certsrv-add-group-dbox-help = cert
+;Edit group
+usersgroups-certsrv-edit-group-dbox-help = cert
+
+;Authentication
+;Authenticaton rules management
+authentication-certsrv-authrules-help = cert
+;Add auth rules
+authentication-certsrv-add-authrule-dbox-help = cert
+;Edit auth rules
+authentication-certsrv-edit-authrule-dbox-help = cert
+authentication-certsrv-view-authrule-dbox-help = cert
+;Authentication plugin registration
+authentication-certsrv-authplugin-help = cert
+;Register auth plugin
+authentication-certsrv-register-authplugin-dbox-help = cert
+;Auth dialog
+authentication-certsrv-auth-dialog-help = cert
+;OOTB Auth plugins
+configuration-authrules-kerberosauth = cert
+configuration-authrules-nisauth = cert
+configuration-authrules-portalauth = cert
+configuration-authrules-uidpwddirauth = cert
+configuration-authrules-uidpwdpindirauth = cert
+
+;authentication implementations 1/1/2000
+authentication-certsrv-impl-ldap = cert
+authentication-certsrv-impl-ldappin = cert
+authentication-certsrv-impl-nis = cert
+authentication-certsrv-impl-portal= cert
+
+;Certificate server status
+;
+;Display status
+status-certsrv-help = cert
+status-logs-help = cert
+;System log content
+status-logs-system-help = cert
+;Error log content
+status-logs-error-help = cert
+;Transactions log content
+status-logs-audit-help = cert
+
+
+Last update: Jan 26, 1999
+
+;Installation Wizard
+;
+
+install-general-intro-wizard-help = cert
+install-internaldb-createdbagain-help = cert
+install-internaldb-configuration-wizard-help = cert
+install-network-configuration-wizard-help = cert
+install-administrator-configuration-wizard-help = cert
+install-internaldb-logon-wizard-help = cert
+install-services-configuration-wizard-help = cert
+install-ca-migration-enable-wizard-help = cert
+install-cakra-migration-enable-wizard-help = cert
+install-ca-migration-configuration-wizard-help = cert
+install-cakra-migration-configuration-wizard-help = cert
+install-catype-wizard-help = cert
+install-cakeylocal-configuration-wizard-help = cert
+install-cakeysub-configuration-wizard-help = cert
+install-cakrakeylocal-configuration-wizard-help = cert
+install-cakra-krakeylocal-configuration-wizard-help = cert
+install-cakrakeysub-configuration-wizard-help = cert
+install-cakra-krakeysub-configuration-wizard-help = cert
+install-cacert-subjectdn-wizard-help = cert
+install-cacertlocal-subjectdn-wizard-help = cert
+install-cacert-validity-wizard-help = cert
+install-cacert-extension-wizard-help = cert
+install-cacert-creation-wizard-help = cert
+install-cacert-request-wizard-help = cert
+install-cacertrequest-manual-wizard-help = cert
+install-cacert-installintro-wizard-help = cert
+install-cacert-paste-wizard-help = cert
+install-cacert-display-wizard-help = cert
+install-cacert-status-wizard-help = cert
+install-ratype-wizard-help = cert
+install-rakey-configuration-wizard-help = cert
+install-racert-subjectdn-wizard-help = cert
+install-racert-validity-wizard-help = cert
+install-racert-extension-wizard-help = cert
+install-racert-creation-wizard-help = cert
+install-racert-request-wizard-help = cert
+install-racertrequest-manual-wizard-help = cert
+install-racert-installintro-wizard-help = cert
+install-racert-paste-wizard-help = cert
+install-racert-display-wizard-help = cert
+install-racert-status-wizard-help = cert
+install-kratype-wizard-help = cert
+install-krakeysub-configuration-wizard-help = cert
+install-kracertsub-subjectdn-wizard-help = cert
+install-kracert-validity-wizard-help = cert
+install-kracert-extension-wizard-help = cert
+install-kracert-creation-wizard-help = cert
+install-kracert-request-wizard-help = cert
+install-kracertrequest-manual-wizard-help = cert
+install-kracert-installintro-wizard-help = cert
+install-kracert-paste-wizard-help = cert
+install-kracert-display-wizard-help = cert
+install-kracert-status-wizard-help = cert
+install-cassltypelocal-wizard-help = cert
+install-cassltypesub-wizard-help = cert
+install-cakrassltypelocal-wizard-help = cert
+install-cakrassltypesub-wizard-help = cert
+install-serverkeylocal-configuration-wizard-help = cert
+install-serverkeysub-configuration-wizard-help = cert
+install-sslcertlocal-subjectdn-wizard-help = cert
+install-sslcertsub-subjectdn-wizard-help = cert
+install-sslcert-validity-wizard-help = cert
+install-sslcert-extension-wizard-help = cert
+install-sslcert-creation-wizard-help = cert
+install-sslcert-request-wizard-help = cert
+install-sslcertrequest-manual-wizard-help = cert
+install-sslcert-installintro-wizard-help = cert
+install-sslcert-paste-wizard-help = cert
+install-sslcert-display-wizard-help = cert
+install-sslcert-status-wizard-help = cert
+install-cakratype-wizard-help = cert
+install-cakrakeylocal-configuration-wizard-help = cert
+install-cakrakeysub-configuration-wizard-help = cert
+install-cakracertlocal-subjectdn-wizard-help = cert
+install-cakra-kracertlocal-subjectdn-wizard-help = cert
+install-cakracertsub-subjectdn-wizard-help = cert
+install-cakra-kracertsub-subjectdn-wizard-help = cert
+install-cakracert-validity-wizard-help = cert
+install-cakra-kracert-validity-wizard-help = cert
+install-cakracert-extension-wizard-help = cert
+install-cakra-kracert-extension-wizard-help = cert
+install-cakracert-creation-wizard-help = cert
+install-cakra-kracert-creation-wizard-help = cert
+install-cakracert-request-wizard-help = cert
+install-cakra-kracert-request-wizard-help = cert
+install-cakracertrequest-manual-wizard-help = cert
+install-cakra-kracertrequest-manual-wizard-help = cert
+install-cakracert-installintro-wizard-help = cert
+install-cakra-kracert-installintro-wizard-help = cert
+install-cakracert-paste-wizard-help = cert
+install-cakra-kracert-paste-wizard-help = cert
+install-cakracert-display-wizard-help = cert
+install-cakra-kracert-display-wizard-help = cert
+install-cakracert-status-wizard-help = cert
+install-cakra-kracert-status-wizard-help = cert
+install-rakratype-wizard-help = cert
+install-rakrakey-configuration-wizard-help = cert
+install-rakra-krakeysub-configuration-wizard-help = cert
+install-rakracert-subjectdn-wizard-help = cert
+install-rakra-kracertsub-subjectdn-wizard-help = cert
+install-rakracert-validity-wizard-help = cert
+install-rakracert-extension-wizard-help = cert
+install-rakracert-creation-wizard-help = cert
+install-rakracert-request-wizard-help = cert
+install-rakra-kracert-request-wizard-help = cert
+install-rakracertrequest-manual-wizard-help = cert
+install-rakra-kracertrequest-manual-wizard-help = cert
+install-rakracert-installintro-wizard-help = cert
+install-rakra-kracert-installintro-wizard-help = cert
+install-rakracert-paste-wizard-help = cert
+install-rakra-kracert-paste-wizard-help = cert
+install-rakracert-display-wizard-help = cert
+install-rakra-kracert-display-wizard-help = cert
+install-rakracert-status-wizard-help = cert
+install-rakra-kracert-status-wizard-help = cert
+install-single-signon-enable-wizard-help = cert
+install-single-signon-wizard-help = cert
+install-certsetup-status-wizard-help = cert
+install-kra-storagekey-wizard-help = cert
+install-cakra-storagekey-wizard-help = cert
+install-rakra-storagekey-wizard-help = cert
+install-kra-mnscheme-wizard-help = cert
+install-cakra-mnscheme-wizard-help = cert
+install-rakra-mnscheme-wizard-help = cert
+install-kra-scheme-usrpwds-wizard-help = cert
+install-cakra-scheme-usrpwds-wizard-help = cert
+install-rakra-scheme-usrpwds-wizard-help = cert
+install-ca-remote-kra-wizard-help = cert
+install-ra-remote-kra-wizard-help = cert
+install-remote-ca-wizard-help = cert
+install-rakra-remote-ca-wizard-help = cert
+install-allcerts-getinstalled-wizard-help = cert
+install-catoken-logon-wizard-help = cert
+install-ratoken-logon-wizard-help = cert
+install-kratoken-logon-wizard-help = cert
+install-ssltoken-logon-wizard-help = cert
+install-internaltoken-logon-wizard-help = cert
+install-cacertclone-wizard-help = cert
+install-cakracertclone-wizard-help = cert
+install-racertclone-wizard-help = cert
+install-rakracertclone-wizard-help = cert
+install-kracertclone-wizard-help = cert
+install-rakracertclone-wizard-help = cert
+install-sslcertclone-wizard-help = cert
+install-ca-serialnumber-wizard-help = cert
+install-request-result-wizard-help = cert
+install-cert-mda-wizard-help = cert
+install-ca-clone-master-wizard-help = cert
+install-ca-ocspservice-wizard-help = cert
+install-ocsptype-wizard-help = cert
+install-ocspcert-subjectdn-wizard-help = cert
+install-ocspkey-configuration-wizard-help = cert
+install-ocspcert-request-wizard-help = cert
+install-ocspcertrequest-manual-wizard-help = cert
+install-ocspcert-installintro-wizard-help = cert
+install-ocsptoken-logon-wizard-help = cert
+install-ocspcert-paste-wizard-help = cert
+install-ocspcert-display-wizard-help = cert
+install-ocspcert-status-wizard-help = cert
+
+; additional tokens for admin guide
+configuration-overview = cert
+configuration-installation = cert
+configuration-certificatemanager = cert
+configuration-registrationmanager = cert
+configuration-ocsp = cert
+configuration-datarecoverymanager = cert
+configuration-adminbasics = cert
+configuration-authorization = cert
+configuration-authentication = cert
+configuration-certificateprofiles = cert
+configuration-policies = cert
+configuration-notifications = cert
+configuration-jobs = cert
+configuration-revocation = cert
+configuration-publishing = cert
+configuration-appendixA = cert
+configuration-appendixB = cert
+configuration-appendixC = cert
+
+; additional tokens for agent guide
+agent-overallservices = cert
+agent-certificateprofiles = cert
+agent-certificaterequests = cert
+agent-revokecertificates = cert
+agent-publishing = cert
+agent-recoverencrypteddata = cert
+agent-ocsp = cert
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ACIDialog.java b/base/console/src/com/netscape/admin/certsrv/config/ACIDialog.java
new file mode 100644
index 000000000..e6085f820
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ACIDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * ACL Editor
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ACIDialog extends JDialog
+ implements ActionListener, MouseListener
+{
+ private final static String PREFIX = "ACIDIALOG";
+ private static final String HELPINDEX =
+ "configuration-authorization";
+ private JFrame mParentFrame;
+ private JButton mOK, mCancel, mHelp;
+ private ResourceBundle mResource;
+ private boolean mDone = false;
+ private JTextArea mACIText, mHelpArea;
+ private String mOperations;
+ private JList mList;
+ private JScrollPane mScrollPane;
+ private DefaultListModel mDataModel;
+ private JRadioButton mAllowBtn, mDenyBtn;
+ private String mHelpToken;
+ private AdminConnection mConnection;
+
+ public ACIDialog(JFrame parent, String ops, AdminConnection adminConn) {
+ super(parent,true);
+ mParentFrame = parent;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mDataModel = new DefaultListModel();
+ mConnection = adminConn;
+ mOperations = ops;
+ mHelpToken = HELPINDEX;
+ setSize(360, 350);
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ setDisplay();
+ }
+
+ public void actionPerformed(ActionEvent evt) {
+ if (evt.getSource().equals(mCancel)) {
+ mDone = false;
+ this.hide();
+ } else if (evt.getSource().equals(mOK)) {
+ String acl = mACIText.getText().trim();
+ Vector v = parseExpressions(acl);
+
+ NameValuePairs response;
+ try {
+ response = mConnection.search(DestDef.DEST_ACL_ADMIN,
+ ScopeDef.SC_EVALUATOR_TYPES,
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+
+ Enumeration enum1 = v.elements();
+ boolean allCorrect = true;
+ while (enum1.hasMoreElements()) {
+ String element = (String)enum1.nextElement();
+ boolean correctSyntax = validateSyntax(element, response);
+ if (correctSyntax) {
+ continue;
+ } else {
+ allCorrect = false;
+ break;
+ }
+ }
+
+ if (allCorrect) {
+ mDone = true;
+ this.hide();
+ } else {
+ String msg = mResource.getString(
+ PREFIX+"_DIALOG_INCORRECTSYNTAX_MESSAGE");
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ msg ,CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ } else if (evt.getSource().equals(mHelp)) {
+ CMSAdminUtil.help(mHelpToken);
+ }
+ }
+
+ private Vector parseExpressions(String s) {
+ String str = s;
+ Vector v = new Vector();
+
+ while (str.length() > 0) {
+ int orIndex = str.indexOf("||");
+ int andIndex = str.indexOf("&&");
+
+ if (orIndex == -1 && andIndex == -1) {
+ if (str.length() > 0)
+ v.addElement(str.trim());
+ return v;
+
+ // || first
+ } else if (andIndex == -1 || (orIndex != -1 && orIndex < andIndex)) {
+ v.addElement(str.substring(0, orIndex).trim());
+
+ str = str.substring(orIndex+2);
+ // && first
+ } else {
+ v.addElement(str.substring(0, andIndex).trim());
+ str = str.substring(andIndex+2);
+ }
+ }
+
+ return v;
+ }
+
+ public void showDialog(String aci, boolean newACI) {
+ if (newACI) {
+ mList.clearSelection();
+ mList.invalidate();
+ mList.validate();
+ mList.repaint(1);
+ mAllowBtn.setSelected(true);
+ mAllowBtn.invalidate();
+ mAllowBtn.validate();
+ mAllowBtn.repaint(1);
+ mDenyBtn.setSelected(false);
+ mDenyBtn.invalidate();
+ mDenyBtn.validate();
+ mDenyBtn.repaint(1);
+ mACIText.setText("");
+ if (mList.getSelectedIndex() < 0)
+ mOK.setEnabled(false);
+ else
+ mOK.setEnabled(true);
+ } else {
+ if (aci.startsWith("allow")) {
+ mAllowBtn.setSelected(true);
+ } else if (aci.startsWith("deny")) {
+ mDenyBtn.setSelected(true);
+ }
+ int startIndex = aci.indexOf("(");
+ int endIndex = aci.indexOf(")");
+ if ((startIndex > 0) && (endIndex > 0)) {
+ String str = aci.substring(startIndex+1, endIndex);
+ StringTokenizer tokenizer = new StringTokenizer(str,",");
+ int[] indices = new int[tokenizer.countTokens()];
+ int i = 0;
+ while (tokenizer.hasMoreElements()) {
+ indices[i++] = mDataModel.indexOf(tokenizer.nextElement());
+ }
+ mList.setSelectedIndices(indices);
+ }
+ String text = aci.substring(endIndex+1).trim();
+ mACIText.setText(text);
+ }
+
+ this.show();
+ }
+
+ public boolean getOK() {
+ return mDone;
+ }
+
+ public String getValue() {
+ Object[] values = mList.getSelectedValues();
+ String result = "";
+ if (!mAllowBtn.isSelected() && !mDenyBtn.isSelected())
+ return "";
+ if (mAllowBtn.isSelected())
+ result = result+"allow"+" (";
+ else if (mDenyBtn.isSelected())
+ result = result+"deny"+" (";
+ if ((values == null) || (values.length == 0))
+ return "";
+
+ for (int i=0; i<values.length; i++) {
+ if (i > 0)
+ result = result+","+(String)values[i];
+ else if (i == 0)
+ result = result+(String)values[i];
+ if (i == values.length-1)
+ result = result+") ";
+ }
+ result = result+mACIText.getText();
+ return result;
+ }
+
+ public void mouseClicked(MouseEvent e) {
+ if (e.getSource() == mList) {
+ if (mList.getSelectedIndex() < 0)
+ mOK.setEnabled(false);
+ else
+ mOK.setEnabled(true);
+ return;
+ }
+
+ Component comp = (Component)e.getSource();
+ String str = comp.getName();
+ String text = "";
+ if (str.equals("access")) {
+ text = mResource.getString(PREFIX+"_ACCESS_HELP");
+ } else if (str.equals("rights")) {
+ text = mResource.getString(PREFIX+"_RIGHTS_HELP");
+ } else if (str.equals("syntax")) {
+ text = mResource.getString(PREFIX+"_SYNTAX_HELP");
+ }
+ mHelpArea.setText(text);
+ }
+
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {
+ }
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {
+ }
+
+ private boolean validateSyntax(String str, NameValuePairs nvps) {
+ for (String name : nvps.keySet()) {
+ if (str.startsWith(name)) {
+ int len = name.length();
+ String leftover = str.substring(len).trim();
+ String operators = nvps.get(name);
+ StringTokenizer st = new StringTokenizer(operators, ",");
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ if (leftover.startsWith(token))
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ // Help Panel
+ JPanel helpPanel = makeHelpPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gbc.insets = new Insets(CMSAdminUtil.DIFFERENT_COMPONENT_SPACE,
+ CMSAdminUtil.DIFFERENT_COMPONENT_SPACE,
+ 0,CMSAdminUtil.DIFFERENT_COMPONENT_SPACE);
+ gb.setConstraints(helpPanel, gbc);
+ center.add(helpPanel);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ //create botton action panel
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null, this);
+ mCancel = CMSAdminUtil.makeJButton(mResource, PREFIX, "CANCEL", null, this);
+ mHelp = CMSAdminUtil.makeJButton(mResource, PREFIX, "HELP", null, this);
+ //JButton[] buttons = { mOK, mCancel, mHelp};
+ JButton[] buttons = { mOK, mCancel};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonPanel( buttons, true);
+ }
+
+ private JPanel makeHelpPanel() {
+ JPanel helpPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ helpPanel.setBorder(CMSAdminUtil.makeEtchedBorder());
+ helpPanel.setLayout(gb);
+
+ mHelpArea = new JTextArea();
+ mHelpArea.setRows(20);
+ mHelpArea.setLineWrap(true);
+ mHelpArea.setWrapStyleWord(true);
+ mHelpArea.setBackground(helpPanel.getBackground());
+ mHelpArea.setEditable(false);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.fill=gbc.BOTH;
+ gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+/*
+ gbc.insets = new Insets(0,
+ CMSAdminUtil.DIFFERENT_COMPONENT_SPACE,
+ 0,CMSAdminUtil.DIFFERENT_COMPONENT_SPACE);
+*/
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ // gbc.gridx = 1;
+ // gbc.gridy = 1;
+ gb.setConstraints(mHelpArea, gbc);
+ helpPanel.add(mHelpArea);
+ mHelpArea.setText(mResource.getString(PREFIX+"_INTRO_HELP"));
+ return helpPanel;
+ }
+
+ private JPanel makeListPane() {
+ JPanel listPanel = new JPanel();
+
+ GridBagConstraints gbc = new GridBagConstraints();
+ GridBagLayout gb = new GridBagLayout();
+ listPanel.setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel opsLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "RIGHTS", null);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gb.setConstraints(opsLabel, gbc);
+ listPanel.add(opsLabel);
+
+ mList = CMSAdminUtil.makeJList(mDataModel, 3);
+ mScrollPane = new JScrollPane(mList,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mList.addMouseListener(this);
+ mScrollPane.setBackground(Color.white);
+ mScrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
+
+ if (!mOperations.equals("")) {
+ StringTokenizer tokenizer = new StringTokenizer(mOperations, ",");
+ while (tokenizer.hasMoreElements()) {
+ mDataModel.addElement(tokenizer.nextElement());
+ }
+ }
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gb.setConstraints(mScrollPane, gbc);
+ listPanel.add(mScrollPane);
+
+ return listPanel;
+ }
+
+ private JPanel makeContentPanel() {
+ JPanel mainPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mainPanel.setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel accessLbl = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "ACCESS", null);
+ gbc.anchor = gbc.NORTHWEST;
+ gb.setConstraints(accessLbl, gbc);
+ mainPanel.add(accessLbl);
+ accessLbl.addMouseListener(this);
+ accessLbl.setName("access");
+ ButtonGroup group = new ButtonGroup();
+
+ CMSAdminUtil.resetGBC(gbc);
+ //mAllowBtn = new JRadioButton("allow");
+ mAllowBtn = CMSAdminUtil.makeJRadioButton(mResource, PREFIX,
+ "ALLOW", null, true, this);
+ group.add(mAllowBtn);
+ gbc.anchor = gbc.NORTHWEST;
+ gb.setConstraints(mAllowBtn, gbc);
+ mainPanel.add(mAllowBtn);
+
+ CMSAdminUtil.resetGBC(gbc);
+ //mDenyBtn = new JRadioButton("deny");
+ mDenyBtn = CMSAdminUtil.makeJRadioButton(mResource, PREFIX,
+ "DENY", null, false, this);
+ group.add(mDenyBtn);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gb.setConstraints(mDenyBtn, gbc);
+ mainPanel.add(mDenyBtn);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel opsLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "RIGHTS", null);
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.gridwidth = gbc.REMAINDER;
+ gb.setConstraints(opsLabel, gbc);
+ mainPanel.add(opsLabel);
+ opsLabel.addMouseListener(this);
+ opsLabel.setName("rights");
+
+ mList = CMSAdminUtil.makeJList(mDataModel, 3);
+ mScrollPane = new JScrollPane(mList,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mList.addMouseListener(this);
+ mScrollPane.setBackground(Color.white);
+ mScrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
+
+ if (!mOperations.equals("")) {
+ StringTokenizer tokenizer = new StringTokenizer(mOperations, ",");
+ while (tokenizer.hasMoreElements()) {
+ mDataModel.addElement(tokenizer.nextElement());
+ }
+ }
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gb.setConstraints(mScrollPane, gbc);
+ mainPanel.add(mScrollPane);
+/*
+ JPanel listPane = makeListPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gb.setConstraints(listPane, gbc);
+ mainPanel.add(listPane);
+*/
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel attrLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "SYNTAX", null);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gb.setConstraints(attrLabel, gbc);
+ mainPanel.add(attrLabel);
+ attrLabel.addMouseListener(this);
+ attrLabel.setName("syntax");
+
+ CMSAdminUtil.resetGBC(gbc);
+ mACIText = new JTextArea();
+ mACIText.setRows(20);
+ mACIText.setLineWrap(true);
+ mACIText.setWrapStyleWord(true);
+ JScrollPane scrollPane = createScrollPane(mACIText);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.fill=gbc.BOTH;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ // gbc.gridx = 1;
+ // gbc.gridy = 1;
+ gb.setConstraints(scrollPane, gbc);
+ mainPanel.add(scrollPane);
+
+ return mainPanel;
+ }
+
+ private JScrollPane createScrollPane(JComponent component) {
+
+ JScrollPane scrollPane = new JScrollPane(component,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ scrollPane.setBackground(getBackground());
+ scrollPane.setAlignmentX(LEFT_ALIGNMENT);
+ scrollPane.setAlignmentY(TOP_ALIGNMENT);
+ scrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
+ return scrollPane;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ACLDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/ACLDataModel.java
new file mode 100644
index 000000000..4adf6c4d3
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ACLDataModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * ACL data model - represents the access control information
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class ACLDataModel extends CMSTableModel {
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String COL1 = "ACLNAME";
+ public static final String COL2 = "ACLDESC";
+
+ private static String[] mColumns = {COL1, COL2};
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public ACLDataModel() {
+ super();
+ init(mColumns);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ACLEditDialog.java b/base/console/src/com/netscape/admin/certsrv/config/ACLEditDialog.java
new file mode 100644
index 000000000..b3bcb72e1
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ACLEditDialog.java
@@ -0,0 +1,557 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * ACL Editor
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ACLEditDialog extends JDialog
+ implements ActionListener, MouseListener
+{
+ private final static String PREFIX = "ACLEDITDIALOG";
+ private final static String HELPINDEX =
+ "configuration-authorization";
+ private JScrollPane mScrollPane;
+ private JList mList;
+ private JFrame mParentFrame;
+ private JButton mOK, mCancel, mHelp;
+ private JButton mAdd, mEdit, mDelete;
+ private ResourceBundle mResource;
+ private String mResourceName, mDesc;
+ private DefaultListModel mDataModel;
+ private String mOperations;
+ private AdminConnection mAdmin;
+ private ACIDialog mDialog;
+ private String mHelpToken;
+ private JTextArea mDescArea, mHelpArea;
+ private JTextField mResourceText, mRightsText;
+ private boolean mIsNew = false;
+ private Color mActiveColor;
+
+ public ACLEditDialog(AdminConnection admin, JFrame parent) {
+ this(admin, parent, null, null);
+ }
+
+ public ACLEditDialog(AdminConnection admin, JFrame parent,
+ String name, String desc) {
+ super(parent,true);
+ mParentFrame = parent;
+ mResource = ResourceBundle.getBundle(
+ CMSAdminResources.class.getName());
+ mDesc = desc;
+ mResourceName = name;
+ if (mResourceName == null)
+ mIsNew = true;
+ mAdmin = admin;
+ mHelpToken = HELPINDEX;
+ mDataModel = new DefaultListModel();
+ setSize(460, 420);
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ setDisplay();
+ }
+
+ public void actionPerformed(ActionEvent evt) {
+ if (evt.getSource().equals(mCancel)) {
+ if (mDialog != null) {
+ mDialog.dispose();
+ mDialog = null;
+ }
+ this.dispose();
+ } else if (evt.getSource().equals(mDelete)) {
+ int index = mList.getSelectedIndex();
+ if (index >= 0) {
+ int i = CMSAdminUtil.showConfirmDialog(mParentFrame,
+ mResource, PREFIX, "DELETE", CMSAdminUtil.WARNING_MESSAGE);
+ if (i == JOptionPane.YES_OPTION) {
+ mDataModel.removeElementAt(index);
+ Debug.println("Deleted");
+ if (mDataModel.size() > 0)
+ mList.setSelectedIndex(0);
+ }
+ }
+ } else if (evt.getSource().equals(mOK)) {
+ if (mIsNew) {
+ mResourceName = mResourceText.getText().trim();
+ if (mResourceName.equals("")) {
+ String msg = mResource.getString(
+ PREFIX+"_DIALOG_EMPTYRESOURCEID_MESSAGE");
+ CMSAdminUtil.showErrorDialog(mParentFrame,
+ mResource, msg, CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ }
+
+ String rights = mRightsText.getText().trim();
+
+ NameValuePairs pairs = new NameValuePairs();
+ if (!rights.equals("")) {
+ String str = "";
+ int size=mDataModel.getSize();
+ if (size == 0) {
+ String msg = mResource.getString(
+ PREFIX+"_DIALOG_EMPTYACIS_MESSAGE");
+ CMSAdminUtil.showErrorDialog(mParentFrame,
+ mResource, msg, CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+
+ String desc = mDescArea.getText().trim();
+ if (desc.equals("")) {
+ String msg = mResource.getString(
+ PREFIX+"_DIALOG_EMPTYDESC_MESSAGE");
+ CMSAdminUtil.showErrorDialog(mParentFrame,
+ mResource, msg, CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+
+ for (int i=0; i<size; i++) {
+ if (i > 0)
+ str = str+";"+(String)mDataModel.elementAt(i);
+ else
+ str = str+(String)mDataModel.elementAt(i);
+ }
+ pairs.put(Constants.PR_ACI, str);
+ pairs.put(Constants.PR_ACL_DESC, desc);
+ pairs.put(Constants.PR_ACL_RIGHTS, rights);
+ }
+
+ try {
+ mAdmin.modify(DestDef.DEST_ACL_ADMIN, ScopeDef.SC_ACL,
+ mResourceName, pairs);
+ if (mDialog != null) {
+ mDialog.dispose();
+ mDialog = null;
+ }
+ this.dispose();
+ } catch (EAdminException e) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource, e.getMessage(),
+ CMSAdminUtil.ERROR_MESSAGE);
+ }
+ } else if (evt.getSource().equals(mAdd)) {
+ String rights = mRightsText.getText().trim();
+ if (rights.equals("")) {
+ String msg = mResource.getString(
+ PREFIX+"_DIALOG_EMPTYRIGHTS_MESSAGE");
+ CMSAdminUtil.showErrorDialog(mParentFrame,
+ mResource, msg, CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ mOperations = rights;
+ mDialog = new ACIDialog(mParentFrame, mOperations, mAdmin);
+ mDialog.showDialog("", true);
+ if (mDialog.getOK()) {
+ mDataModel.addElement(mDialog.getValue());
+ mList.setSelectedIndex(mDataModel.size()-1);
+ mDelete.setEnabled(true);
+ mEdit.setEnabled(true);
+ }
+ mDialog = null;
+ } else if (evt.getSource().equals(mEdit)) {
+ mDialog = new ACIDialog(mParentFrame, mOperations, mAdmin);
+ int index = mList.getSelectedIndex();
+ if (index >= 0) {
+ String aci = (String)mDataModel.elementAt(index);
+ mDialog.showDialog(aci, false);
+
+ if (mDialog.getOK())
+ mDataModel.setElementAt(mDialog.getValue(), index);
+ }
+ mDialog = null;
+ } else if (evt.getSource().equals(mHelp)) {
+ CMSAdminUtil.help(mHelpToken);
+ }
+ }
+
+ public void showDialog() {
+ mEdit.setEnabled(false);
+ mDelete.setEnabled(false);
+ this.show();
+ }
+
+ public void showDialog(NameValuePairs data) {
+ String aci = data.get(Constants.PR_ACI);
+ mOperations = data.get(Constants.PR_ACL_OPS);
+
+ if ((aci != null) && (!aci.trim().equals(""))) {
+ StringTokenizer tokenizer = new StringTokenizer(aci, ";");
+ while (tokenizer.hasMoreElements())
+ mDataModel.addElement(tokenizer.nextElement());
+ }
+ if (mList.getSelectedIndex() < 0) {
+ mEdit.setEnabled(false);
+ mDelete.setEnabled(false);
+ } else {
+ mEdit.setEnabled(true);
+ mDelete.setEnabled(true);
+ }
+
+ if (!mIsNew)
+ mRightsText.setText(mOperations);
+
+ this.show();
+ }
+
+ private void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ // Help Panel
+ JPanel helpPanel = makeHelpPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gbc.insets = new Insets(CMSAdminUtil.DIFFERENT_COMPONENT_SPACE,
+ CMSAdminUtil.DIFFERENT_COMPONENT_SPACE,
+ 0,CMSAdminUtil.DIFFERENT_COMPONENT_SPACE);
+ gb.setConstraints(helpPanel, gbc);
+ center.add(helpPanel);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ public void mouseClicked(MouseEvent e) {
+ if (e.getSource() == mList) {
+ if (mList.getSelectedIndex() < 0) {
+ mDelete.setEnabled(false);
+ mEdit.setEnabled(false);
+ } else {
+ mDelete.setEnabled(true);
+ mEdit.setEnabled(true);
+ }
+
+ return;
+ }
+
+ Component comp = (Component)e.getSource();
+ String str = comp.getName();
+ String text = "";
+ if (str.equals("resourceID")) {
+ text = mResource.getString(PREFIX+"_RESOURCEID_HELP");
+ } else if (str.equals("rights")) {
+ text = mResource.getString(PREFIX+"_RIGHTS_HELP");
+ } else if (str.equals("aci")) {
+ text = mResource.getString(PREFIX+"_ACI_HELP");
+ } else if (str.equals("description")) {
+ text = mResource.getString(PREFIX+"_DESC_HELP");
+ }
+ mHelpArea.setText(text);
+ }
+
+ public void mousePressed(MouseEvent e) {
+ }
+ public void mouseReleased(MouseEvent e) {
+ }
+ public void mouseEntered(MouseEvent e) {
+ }
+ public void mouseExited(MouseEvent e) {
+ }
+
+ /**
+ * create the bottom action button panel
+ */
+ private JPanel createUDButtonPanel() {
+ //up, down buttons required
+ //actionlister to this object
+ mAdd = CMSAdminUtil.makeJButton(mResource, PREFIX, "ADD", null, this);
+ mDelete = CMSAdminUtil.makeJButton(mResource, PREFIX, "DELETE",
+ null, this);
+ mEdit = CMSAdminUtil.makeJButton(mResource, PREFIX, "EDIT", null, this);
+ JButton[] buttons = {mAdd, mDelete, mEdit};
+ JButtonFactory.resize(buttons);
+ return CMSAdminUtil.makeJButtonVPanel(buttons);
+ }
+
+ //create botton action panel
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null, this);
+ mCancel = CMSAdminUtil.makeJButton(mResource, PREFIX, "CANCEL", null, this);
+ mHelp = CMSAdminUtil.makeJButton(mResource, PREFIX, "HELP", null, this);
+ //JButton[] buttons = { mOK, mCancel, mHelp};
+ JButton[] buttons = { mOK, mCancel};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonPanel( buttons, true);
+ }
+
+ private JPanel makeHelpPanel() {
+ JPanel helpPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ helpPanel.setBorder(CMSAdminUtil.makeEtchedBorder());
+ helpPanel.setLayout(gb);
+
+ mHelpArea = new JTextArea();
+ mHelpArea.setRows(20);
+ mHelpArea.setLineWrap(true);
+ mHelpArea.setWrapStyleWord(true);
+ mHelpArea.setBackground(helpPanel.getBackground());
+ mHelpArea.setEditable(false);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.fill=gbc.BOTH;
+ gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+/*
+ gbc.insets = new Insets(0,
+ CMSAdminUtil.DIFFERENT_COMPONENT_SPACE,
+ 0,CMSAdminUtil.DIFFERENT_COMPONENT_SPACE);
+*/
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ // gbc.gridx = 1;
+ // gbc.gridy = 1;
+ gb.setConstraints(mHelpArea, gbc);
+ helpPanel.add(mHelpArea);
+ mHelpArea.setText(mResource.getString(PREFIX+"_INTRO_HELP"));
+ return helpPanel;
+ }
+
+ private JPanel makeContentPanel() {
+ JPanel mainPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mainPanel.setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label1 = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "RESOURCEOBJECT", null);
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.DIFFERENT_COMPONENT_SPACE,
+ 0, CMSAdminUtil.COMPONENT_SPACE);
+ gb.setConstraints(label1, gbc);
+ mainPanel.add(label1);
+ label1.setName("resourceID");
+ label1.addMouseListener(this);
+
+ CMSAdminUtil.resetGBC(gbc);
+ if (mIsNew) {
+ mResourceText = new JTextField(30);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gb.setConstraints(mResourceText, gbc);
+ mainPanel.add(mResourceText);
+ } else {
+ JLabel label2 = new JLabel(mResourceName);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gb.setConstraints(label2, gbc);
+ mainPanel.add(label2);
+ }
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel rightsLbl = CMSAdminUtil.makeJLabel(
+ mResource, PREFIX, "RIGHTS", null);
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.DIFFERENT_COMPONENT_SPACE,
+ 0, CMSAdminUtil.COMPONENT_SPACE);
+ gb.setConstraints(rightsLbl, gbc);
+ mainPanel.add(rightsLbl);
+ rightsLbl.setName("rights");
+ rightsLbl.addMouseListener(this);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRightsText = new JTextField(30);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gb.setConstraints(mRightsText, gbc);
+ mainPanel.add(mRightsText);
+
+ JLabel aciLbl = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "ACI", null);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.DIFFERENT_COMPONENT_SPACE,
+ 0,CMSAdminUtil.DIFFERENT_COMPONENT_SPACE);
+ gb.setConstraints(aciLbl, gbc);
+ mainPanel.add(aciLbl);
+ aciLbl.setName("aci");
+ aciLbl.addMouseListener(this);
+
+ JPanel listPanel = makeListPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill=gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(0,
+ CMSAdminUtil.DIFFERENT_COMPONENT_SPACE,
+ 0,CMSAdminUtil.DIFFERENT_COMPONENT_SPACE);
+ gb.setConstraints(listPanel, gbc);
+ mainPanel.add(listPanel);
+
+ JLabel descLbl = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "DESC", null);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.DIFFERENT_COMPONENT_SPACE,
+ 0,CMSAdminUtil.DIFFERENT_COMPONENT_SPACE);
+ gb.setConstraints(descLbl, gbc);
+ mainPanel.add(descLbl);
+ descLbl.setName("description");
+ descLbl.addMouseListener(this);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mDescArea = new JTextArea();
+ mDescArea.setRows(20);
+ mDescArea.setLineWrap(true);
+ mDescArea.setWrapStyleWord(true);
+ if (mDesc != null)
+ mDescArea.setText(mDesc);
+ JScrollPane scrollPane = createScrollPane(mDescArea);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.fill=gbc.BOTH;
+ gbc.insets = new Insets(0,
+ CMSAdminUtil.DIFFERENT_COMPONENT_SPACE,
+ 0,CMSAdminUtil.DIFFERENT_COMPONENT_SPACE);
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ // gbc.gridx = 1;
+ // gbc.gridy = 1;
+ gb.setConstraints(scrollPane, gbc);
+ mainPanel.add(scrollPane);
+
+/*
+ mActiveColor = mDescArea.getBackground();
+
+ if (mIsNew)
+ enableTextField(mResourceText, true, mActiveColor);
+ else
+ enableTextField(mResourceText, false, getBackground());
+*/
+ return mainPanel;
+ }
+
+ private void enableTextField(JTextField textFld, boolean enabled,
+ Color color) {
+ textFld.setEnabled(enabled);
+ textFld.setEditable(enabled);
+ textFld.setBackground(color);
+ CMSAdminUtil.repaintComp(textFld);
+ }
+
+ private JScrollPane createScrollPane(JComponent component) {
+
+ JScrollPane scrollPane = new JScrollPane(component,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ scrollPane.setBackground(getBackground());
+ scrollPane.setAlignmentX(LEFT_ALIGNMENT);
+ scrollPane.setAlignmentY(TOP_ALIGNMENT);
+ scrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
+ return scrollPane;
+ }
+
+ private JPanel makeListPanel() {
+ JPanel listPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ listPanel.setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mList = CMSAdminUtil.makeJList(mDataModel,9);
+ mScrollPane = new JScrollPane(mList,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ mScrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
+ mList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION );
+ mList.addMouseListener(this);
+ mScrollPane.setBackground(Color.white);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ //gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ listPanel.add(mScrollPane);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JPanel VBtnPanel = createUDButtonPanel();
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+ gb.setConstraints(VBtnPanel, gbc);
+ listPanel.add(VBtnPanel);
+
+ return listPanel;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ACLImplDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/ACLImplDataModel.java
new file mode 100644
index 000000000..79033030d
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ACLImplDataModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * ACL data model - represents the evaluator table information
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class ACLImplDataModel extends CMSTableModel {
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String COL1 = "EVALNAME";
+ public static final String COL2 = "CLASSNAME";
+
+ private static String[] mColumns = {COL1, COL2};
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public ACLImplDataModel() {
+ super();
+ init(mColumns);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ACLImplTab.java b/base/console/src/com/netscape/admin/certsrv/config/ACLImplTab.java
new file mode 100644
index 000000000..4693224b1
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ACLImplTab.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import java.awt.*;
+import java.util.*;
+import java.awt.event.*;
+
+/**
+ * ACL Implementation Tab
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class ACLImplTab extends CMSBaseUGTab {
+ private static String PANEL_NAME = "ACLIMPL";
+ private CMSBaseResourceModel mModel;
+ private AdminConnection mConnection;
+ private JTable mTable;
+ private JScrollPane mScrollPane;
+ protected ACLImplDataModel mDataModel;
+ protected EvaluatorRegisterDialog mEditor=null;
+ protected JButton mRefresh, mAdd, mDelete, mHelp;
+ private static final String HELPINDEX =
+ "configuration-authorization";
+
+ public ACLImplTab(CMSUGTabPanel parent) {
+ super(PANEL_NAME, parent.getResourceModel());
+ mModel = parent.getResourceModel();
+ mDataModel = new ACLImplDataModel();
+ mConnection = mModel.getServerInfo().getAdmin();
+ mHelpToken = HELPINDEX;
+ }
+
+ protected JPanel createListPanel() {
+ JPanel mainPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mainPanel.setLayout(gb);
+
+ //center table
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ mScrollPane.setHorizontalScrollBarPolicy(
+ mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(
+ mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(
+ ListSelectionModel.SINGLE_SELECTION);
+ mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ mTable.addMouseListener(this);
+ setLabelCellRenderer(mTable,0);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = 1;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mainPanel.add(mScrollPane);
+
+ JPanel buttonPanel = createButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ mainPanel.add(buttonPanel);
+
+ refresh();
+
+ return mainPanel;
+ }
+
+ /**
+ * create the user action button panel
+ */
+ protected JPanel createButtonPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mAdd = makeJButton("ADD");
+ mDelete = makeJButton("DELETE");
+ JButton[] buttons = {mAdd, mDelete};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ protected JPanel createActionPanel() {
+ mRefresh = makeJButton("REFRESH");
+ mHelp = makeJButton("HELP");
+ //JButton[] buttons = { mRefresh, mHelp };
+ JButton[] buttons = { mRefresh };
+ return makeJButtonPanel(buttons, true);
+ }
+
+ public void refresh() {
+ mModel.progressStart();
+ mDataModel.removeAllRows();
+ update();
+ mTable.invalidate();
+ mTable.validate();
+ mScrollPane.invalidate();
+ mScrollPane.validate();
+ mScrollPane.repaint(1);
+ mModel.progressStop();
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mRefresh)) {
+ refresh();
+ } else if (e.getSource().equals(mAdd)) {
+ if (mEditor==null)
+ mEditor = new EvaluatorRegisterDialog(mModel.getFrame(),
+ mConnection);
+ mEditor.showDialog(DestDef.DEST_ACL_ADMIN, ScopeDef.SC_ACL_IMPLS);
+ refresh();
+ } else if (e.getSource().equals(mDelete)) {
+ Debug.println("Delete");
+ if(mTable.getSelectedRow()< 0)
+ return;
+ int i = showConfirmDialog("DELETE");
+ if (i == JOptionPane.YES_OPTION) {
+ delete();
+ Debug.println("Deleted");
+ }
+ } else if (e.getSource().equals(mHelp)) {
+ helpCallback();
+ }
+ }
+
+ public void mouseClicked(MouseEvent e) {
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(
+ new LabelCellRenderer(new JLabel()));
+ }
+
+ private void delete() {
+ //get entry name
+ int row = mTable.getSelectedRow();
+
+ //send comment to server for the removal of user
+ try {
+ mConnection.delete(DestDef.DEST_ACL_ADMIN,
+ ScopeDef.SC_ACL_IMPLS,
+ ((JLabel)(mDataModel.getValueAt(row, 0))).getText());
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ return;
+ }
+
+ //send comment to server and refetch the content
+ refresh();
+ }
+
+ private void update() {
+ //send request and parse data
+ NameValuePairs response;
+ try {
+ response = mConnection.search(DestDef.DEST_ACL_ADMIN,
+ ScopeDef.SC_ACL_IMPLS,
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ return;
+ }
+
+ Debug.println(response.toString());
+
+ //parse the data
+ int i=0;
+ String[] vals = new String[response.size()];
+
+ for (String entry : response.keySet()) {
+ vals[i++] = entry.trim();
+ }
+
+ CMSAdminUtil.bubbleSort(vals);
+
+ for (i=0; i<vals.length; i++) {
+ String name = vals[i];
+ Vector v = new Vector();
+ v.addElement(new JLabel(name,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_ACLPLUGIN),
+ JLabel.LEFT));
+ v.addElement(response.get(name));
+ mDataModel.addRow(v);
+ }
+
+ if (mDataModel.getRowCount() >0)
+ mTable.setRowSelectionInterval(0,0);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ACLPanel.java b/base/console/src/com/netscape/admin/certsrv/config/ACLPanel.java
new file mode 100644
index 000000000..2593e0c0b
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ACLPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import java.awt.*;
+import java.util.*;
+import java.awt.event.*;
+
+/**
+ * ACL Management Tab
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class ACLPanel extends CMSBaseUGTab {
+ private static String PANEL_NAME = "ACLMGMT";
+ private CMSBaseResourceModel mModel;
+ private AdminConnection mAdmin;
+ private JButton mRefresh;
+ private JButton mHelp;
+ private JButton mEdit, mAdd;
+ private JTable mTable;
+ private ACLDataModel mDataModel;
+ private JScrollPane mScrollPane;
+ private ACLEditDialog mEditor;
+ private static final String HELPINDEX =
+ "configuration-authorization";
+
+ public ACLPanel(CMSUGTabPanel parent) {
+ super(PANEL_NAME, parent.getResourceModel());
+ mModel = parent.getResourceModel();
+ mAdmin = mModel.getServerInfo().getAdmin();
+ mDataModel = new ACLDataModel();
+ mHelpToken = HELPINDEX;
+ }
+
+ protected JPanel createListPanel() {
+ JPanel mainPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mainPanel.setLayout(gb);
+
+ //center table
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ mScrollPane.setHorizontalScrollBarPolicy(
+ mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(
+ mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(
+ ListSelectionModel.SINGLE_SELECTION);
+ mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ mTable.addMouseListener(this);
+ setLabelCellRenderer(mTable,0);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = 1;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mainPanel.add(mScrollPane);
+
+ JPanel buttonPanel = createButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ mainPanel.add(buttonPanel);
+
+ refresh();
+
+ return mainPanel;
+ }
+
+ /**
+ * create the user action button panel
+ */
+ protected JPanel createButtonPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mAdd = makeJButton("ADD");
+ mEdit = makeJButton("EDIT");
+ JButton[] buttons = {mAdd,mEdit};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ private JScrollPane createScrollPane(JList listbox) {
+
+ JScrollPane scrollPane = new JScrollPane(listbox,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ scrollPane.setBackground(getBackground());
+ scrollPane.setAlignmentX(LEFT_ALIGNMENT);
+ scrollPane.setAlignmentY(TOP_ALIGNMENT);
+ scrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
+ return scrollPane;
+ }
+
+ protected JPanel createActionPanel() {
+ mRefresh = makeJButton("REFRESH");
+ mHelp = makeJButton("HELP");
+ //JButton[] buttons = { mRefresh, mHelp };
+ JButton[] buttons = { mRefresh };
+ return makeJButtonPanel(buttons, true);
+ }
+
+ public void refresh() {
+ mModel.progressStart();
+ mDataModel.removeAllRows();
+ update();
+ mTable.invalidate();
+ mTable.validate();
+ mScrollPane.invalidate();
+ mScrollPane.validate();
+ mScrollPane.repaint(1);
+ mModel.progressStop();
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mEdit)) {
+ int row = -1;
+ if ((row = mTable.getSelectedRow()) < 0)
+ return;
+ String name = ((JLabel)(mDataModel.getValueAt(row, 0))).getText();
+ String desc = (String)(mDataModel.getValueAt(row, 1));
+ NameValuePairs response;
+ try {
+ response = mAdmin.read(DestDef.DEST_ACL_ADMIN,
+ ScopeDef.SC_ACL, name, new NameValuePairs());
+ } catch (EAdminException ee) {
+ //display error dialog
+ showErrorDialog(ee.getMessage());
+ return;
+ }
+
+ Debug.println(response.toString());
+ mEditor = new ACLEditDialog(mAdmin, mModel.getFrame(), name, desc);
+ mEditor.showDialog(response);
+ refresh();
+ } else if (e.getSource().equals(mAdd)) {
+ mEditor = new ACLEditDialog(mAdmin, mModel.getFrame());
+ mEditor.showDialog();
+ refresh();
+ } else if (e.getSource().equals(mRefresh)) {
+ refresh();
+ } else if (e.getSource().equals(mHelp)) {
+ helpCallback();
+ }
+ }
+
+ public void mouseClicked(MouseEvent e) {
+ }
+
+ private void update() {
+ //send request and parse data
+ NameValuePairs response;
+ try {
+ response = mAdmin.search(DestDef.DEST_ACL_ADMIN,
+ ScopeDef.SC_ACL,
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ return;
+ }
+
+ Debug.println(response.toString());
+
+ //parse the data
+ int i=0;
+ String[] vals = new String[response.size()];
+
+ for (String entry : response.keySet()) {
+ vals[i++] = entry.trim();
+ }
+
+ CMSAdminUtil.bubbleSort(vals);
+
+ for (i=0; i<vals.length; i++) {
+ String name = vals[i];
+ Vector v = new Vector();
+ v.addElement(new JLabel(name,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_ACL),
+ JLabel.LEFT));
+ v.addElement(response.get(name));
+ mDataModel.addRow(v);
+ }
+
+ if (mDataModel.getRowCount() >0)
+ mTable.setRowSelectionInterval(0,0);
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(
+ new LabelCellRenderer(new JLabel()));
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/AutoRecoveryModel.java b/base/console/src/com/netscape/admin/certsrv/config/AutoRecoveryModel.java
new file mode 100644
index 000000000..90b617cbd
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/AutoRecoveryModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Auto recovery data model - represents the instance
+ * table information
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class AutoRecoveryModel extends CMSTableModel
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String COL1 = "NUMBER";
+ public static final String COL2 = "UID";
+ public static final String COL3 = "PASSWORD";
+
+ private static String[] mColumns = {COL1, COL2, COL3};
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public AutoRecoveryModel() {
+ super();
+ init(mColumns);
+ }
+
+ public boolean isCellEditable(int row, int col) {
+ if(col >= 1)
+ return true;
+ return false;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CACertsTab.java b/base/console/src/com/netscape/admin/certsrv/config/CACertsTab.java
new file mode 100644
index 000000000..18590747a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CACertsTab.java
@@ -0,0 +1,392 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.management.client.console.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.keycert.*;
+
+/**
+ * CA certs Tab
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class CACertsTab extends CMSBaseUGTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PANEL_NAME = "CACERTS";
+ private CMSBaseResourceModel mModel;
+ private AdminConnection mConnection;
+ private String mDestination;
+ private ConsoleInfo mConsoleInfo;
+
+ protected JScrollPane mScrollPane;
+ protected JTable mTable; //table
+ protected ListCertsModel mDataModel; //table model
+ protected CertViewDialog mEditor=null; //keep single copy
+
+ protected JButton mRefresh, mAdd, mDelete, mView, mEdit, mHelp;
+ private final static String HELPINDEX = "configuration-log-plugin-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CACertsTab(CMSBaseResourceModel model, String destination) {
+ super(PANEL_NAME, model);
+ mConnection = model.getServerInfo().getAdmin();
+ mModel = model;
+ mConsoleInfo = mModel.getConsoleInfo();
+ mDataModel = new ListCertsModel();
+ mDestination = destination;
+ mHelpToken = HELPINDEX;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mRefresh)) {
+ refresh();
+ }
+ if (e.getSource().equals(mHelp)) {
+ helpCallback();
+ }
+ if (e.getSource().equals(mAdd)) {
+
+ CertSetupWizardInfo info = new CertSetupWizardInfo(mConnection, mConsoleInfo);
+
+ // if it is "0", then it means it is root cert mode.
+ // if it is "1", then it means it is user cert mode.
+ info.setMode("0");
+ CertSetupWizard wizard = new CertSetupWizard(
+ mModel, info);
+ refresh();
+ return;
+ }
+
+ int row = mTable.getSelectedRow();
+ if(row < 0)
+ return;
+
+ if (e.getSource().equals(mDelete)) {
+ Debug.println("Delete");
+ if(mTable.getSelectedRow()< 0)
+ return;
+ int i = showConfirmDialog("DELETE");
+ if (i == JOptionPane.YES_OPTION) {
+ delete();
+ Debug.println("Deleted");
+ }
+ }
+ if (e.getSource().equals(mView)) {
+ Debug.println("View");
+ String nickname = (String)(mTable.getValueAt(row, 3)) + ":" +
+ (String)(mTable.getValueAt(row, 0));
+ String serialno = (String)(mTable.getValueAt(row, 1));
+ String issuername = (String)(mTable.getValueAt(row, 2));
+
+ try {
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_NICK_NAME, nickname);
+ nvps.put(Constants.PR_SERIAL_NUMBER, serialno);
+ nvps.put(Constants.PR_ISSUER_NAME, issuername);
+ NameValuePairs results = mConnection.process(
+ DestDef.DEST_SERVER_ADMIN, ScopeDef.SC_CERT_PRETTY_PRINT,
+ Constants.RS_ID_CONFIG, nvps);
+ if (nvps.size() <= 0)
+ return;
+ String name = results.keySet().iterator().next(); // first element
+ String print = results.get(name);
+ CertViewDialog certdialog = new CertViewDialog(mModel.getFrame());
+ certdialog.showDialog(nickname, print);
+ } catch (EAdminException ex) {
+ CMSAdminUtil.showErrorDialog(mModel.getFrame(), mResource, ex.toString(),
+ CMSAdminUtil.ERROR_MESSAGE);
+ }
+ }
+ if (e.getSource().equals(mEdit)) {
+ Debug.println("Edit");
+ String nickname = (String)(mTable.getValueAt(row, 3)) + ":" +
+ (String)(mTable.getValueAt(row, 0));
+ String serialno = (String)(mTable.getValueAt(row, 1));
+ String issuername = (String)(mTable.getValueAt(row, 2));
+
+ try {
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_NICK_NAME, nickname);
+ nvps.put(Constants.PR_SERIAL_NUMBER, serialno);
+ nvps.put(Constants.PR_ISSUER_NAME, issuername);
+ NameValuePairs results = mConnection.process(
+ DestDef.DEST_SERVER_ADMIN, ScopeDef.SC_ROOTCERT_TRUSTBIT,
+ Constants.RS_ID_CONFIG, nvps);
+ if (nvps.size() <= 0)
+ return;
+ String name = results.keySet().iterator().next(); // first element
+ String trust = results.get(name);
+ int i;
+ String[] params = new String[2];
+ if (trust.equals("U")) {
+ params[0] = "untrusted";
+ params[1] = "trust";
+ i = showConfirmDialog("TRUST", params);
+ } else {
+ params[0] = "trusted";
+ params[1] = "untrust";
+ i = showConfirmDialog("TRUST", params);
+ }
+
+ if (i == JOptionPane.YES_OPTION) {
+ nvps.put("trustbit", params[1]);
+ mConnection.modify(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_ROOTCERT_TRUSTBIT,
+ Constants.RS_ID_CONFIG, nvps);
+ }
+ } catch (EAdminException ex) {
+ CMSAdminUtil.showErrorDialog(mModel.getFrame(), mResource, ex.toString(),
+ CMSAdminUtil.ERROR_MESSAGE);
+ }
+ }
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+ public void refresh() {
+
+ mDataModel.removeAllRows();
+ update();
+
+ setButtons();
+ mTable.invalidate();
+ mTable.validate();
+ mTable.repaint(1);
+ }
+
+ /**
+ * create the user action button panel
+ */
+ protected JPanel createButtonPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mAdd = makeJButton("ADD");
+ mDelete = makeJButton("DELETE");
+ mView = makeJButton("VIEW");
+ mEdit = makeJButton("EDIT");
+ JButton[] buttons = {mAdd, mDelete, mView, mEdit};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ protected JPanel createActionPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mRefresh = makeJButton("REFRESH");
+ mHelp = makeJButton("HELP");
+ //JButton[] buttons = { mRefresh, mHelp };
+ JButton[] buttons = { mRefresh };
+ return makeJButtonPanel(buttons, true);
+ }
+
+ protected JPanel createListPanel() {
+ mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ //center table
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ //mScrollPane.setBorder(CMSAdminUtil.makeTitledBorder(mResource,PANEL_NAME,"USERS"));
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ mTable.addMouseListener(this);
+ setLabelCellRenderer(mTable,0);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = 1;
+ gbc.weightx = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ JPanel buttonPanel = createButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ mListPanel.add(buttonPanel);
+
+ refresh();
+
+ return mListPanel;
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(new LabelCellRenderer(new JLabel()));
+ }
+
+
+ //set buttons
+ private void setButtons() {
+
+ //enable and diable buttons accordingly
+ //Debug.println("setButtons() - "+mTable.getSelectedRow());
+ //Debug.println("setButtons() - "+mTable.getSelectionModel().isSelectionEmpty());
+ if (mTable.getSelectionModel().isSelectionEmpty()) {
+ mDelete.setEnabled(false);
+ mView.setEnabled(false);
+ return;
+ }
+
+ if(mDataModel.getRowCount()<=0) {
+ mDelete.setEnabled(false);
+ mView.setEnabled(false);
+ return;
+ }
+
+ mDelete.setEnabled(true);
+ mView.setEnabled(true);
+
+ }
+
+ //=============================================
+ // SEND REQUESTS TO THE SERVER SIDE
+ //=============================================
+ private void update() {
+ //send request and parse data
+
+ mModel.progressStart();
+ NameValuePairs response;
+ try {
+ response = mConnection.search(mDestination, ScopeDef.SC_ROOTCERTSLIST,
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+
+ Debug.println(response.toString());
+
+ //parse the data
+ mDataModel.removeAllRows();
+ if (response != null) {
+ String[] vals = new String[response.size()];
+ int i=0;
+ for (String entry : response.keySet()) {
+ vals[i++] = entry.trim();
+ }
+
+ int sindex = 0;
+ String snickname = "";
+ CMSAdminUtil.quickSort(vals, 0, response.size()-1);
+ for (i=0; i<vals.length; i++) {
+ Vector v = new Vector();
+ String entry = vals[i];
+ String value = response.get(entry);
+
+ // look for the comma separator
+ int lastindex = entry.lastIndexOf(",");
+ if (lastindex != -1) {
+ String nickname = entry.substring(0, lastindex);
+ int colonindex = nickname.indexOf(":");
+ if (colonindex != -1)
+ v.addElement(nickname.substring(colonindex+1));
+ else
+ v.addElement(nickname);
+ v.addElement(entry.substring(lastindex+1));
+ v.addElement(value);
+ if (colonindex != -1)
+ v.addElement(nickname.substring(0, colonindex));
+ else
+ v.addElement("internal");
+ mDataModel.addRow(v);
+ }
+ }
+ if (vals.length > 0)
+ mTable.setRowSelectionInterval(0,0);
+ }
+
+ mModel.progressStop();
+ }
+
+ private void delete() {
+ mModel.progressStart();
+ int row = mTable.getSelectedRow();
+ String nickname = (String)(mDataModel.getValueAt(row, 3))+":"+
+ (String)(mDataModel.getValueAt(row, 0));
+ String id = nickname+":SERIAL#<"+mDataModel.getValueAt(row, 1)+">"
+ +mDataModel.getValueAt(row, 2);
+
+ //send comment to server for the removal of user
+ try {
+ mConnection.delete(mDestination, ScopeDef.SC_ROOTCERTSLIST, id);
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+ mModel.progressStop();
+ //send comment to server and refetch the content
+ refresh();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSAccessLogPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSAccessLogPanel.java
new file mode 100644
index 000000000..8f1fc1f20
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSAccessLogPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+
+import java.awt.event.*;
+
+/**
+ * Access Log Setting Tab to be displayed at the right hand side
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class CMSAccessLogPanel extends CMSBaseLogPanel {
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static String PANEL_NAME = "ACCESSLOG";
+ private CMSTabPanel mParent;
+ private static final String HELPINDEX = "configuration-logs-system-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSAccessLogPanel(CMSTabPanel parent, boolean isNT) {
+ super(PANEL_NAME, parent);
+ mParent = parent;
+ mHelpToken = HELPINDEX;
+ mIsNT = isNT;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Actual Instantiation of the UI components
+ */
+ public void init() {
+ Debug.println("AccessLogPanel: init()");
+ super.init();
+ refresh();
+ }
+
+ public void refresh() {
+ mModel.progressStart();
+ NameValuePairs nvp = new NameValuePairs();
+ nvp.put(Constants.PR_LOG_ENABLED, "");
+ nvp.put(Constants.PR_LOG_LEVEL, "");
+ nvp.put(Constants.PR_LOG_BUFFERSIZE, "");
+ //nvp.add(Constants.PR_LOG_EXPIRED_TIME, "");
+ //nvp.add(Constants.PR_LOG_FILENAME, "");
+ //nvp.add(Constants.PR_LOG_FLUSHINTERVAL, "");
+ nvp.put(Constants.PR_LOG_MAXFILESIZE, "");
+ nvp.put(Constants.PR_LOG_ROLLEROVER_INTERVAL, "");
+
+ try {
+ NameValuePairs val = mAdmin.read(DestDef.DEST_LOG_ADMIN,
+ ScopeDef.SC_SYSTEMLOG, Constants.RS_ID_CONFIG, nvp);
+ parseVals(val);
+ if (mIsNT) {
+ nvp.clear();
+ nvp.put(Constants.PR_NT_EVENT_SOURCE, "");
+ nvp.put(Constants.PR_NT_LOG_LEVEL, "");
+ nvp.put(Constants.PR_NT_LOG_ENABLED, "");
+ val = mAdmin.read(DestDef.DEST_LOG_ADMIN,
+ ScopeDef.SC_NTSYSTEMLOG, Constants.RS_ID_CONFIG, nvp);
+ parseNTVals(val);
+ }
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ }
+ setValues();
+ mModel.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+ }
+
+ private void parseVals(NameValuePairs nvp) {
+ if (nvp.get(Constants.PR_LOG_ENABLED).equalsIgnoreCase(
+ Constants.TRUE))
+ activateLog.setSelected(true);
+ else
+ activateLog.setSelected(false);
+ mLevel = Integer.parseInt(nvp.get(Constants.PR_LOG_LEVEL));
+ mlogBufSizTextData = nvp.get(Constants.PR_LOG_BUFFERSIZE);
+ mlogMaxSizTextData = nvp.get(Constants.PR_LOG_MAXFILESIZE);
+ int val =
+ Integer.parseInt(nvp.get(Constants.PR_LOG_ROLLEROVER_INTERVAL));
+ mFrequency = getRollOverIndex(val);
+ }
+
+ private void parseNTVals(NameValuePairs nvp) {
+ mNTLevel = Integer.parseInt(nvp.get(Constants.PR_NT_LOG_LEVEL));
+ mSource = nvp.get(Constants.PR_NT_EVENT_SOURCE);
+ if (nvp.get(Constants.PR_NT_LOG_ENABLED).equalsIgnoreCase(
+ Constants.TRUE))
+ mActivateNTLog.setSelected(true);
+ else
+ mActivateNTLog.setSelected(false);
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ // check blank fields
+ if ((mlogMaxSizText.getText().trim().equals("")) ||
+ (mlogBufSizText.getText().trim().equals("")) ) {
+ showMessageDialog("BLANKFIELD");
+ return false;
+ }
+
+ String bufSize = mlogBufSizText.getText().trim();
+ String maxSize = mlogMaxSizText.getText().trim();
+
+ try {
+ int val1 = Integer.parseInt(bufSize);
+ int val2 = Integer.parseInt(maxSize);
+ if (val1 <= 0 || val2 <= 0) {
+ showMessageDialog("OUTOFRANGE");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ showMessageDialog("NUMBERFORMAT");
+ return false;
+ }
+
+ NameValuePairs nvp = new NameValuePairs();
+ mModel.progressStart();
+ if (activateLog.isSelected())
+ nvp.put(Constants.PR_LOG_ENABLED, Constants.TRUE);
+ else
+ nvp.put(Constants.PR_LOG_ENABLED, Constants.FALSE);
+ String str = "" + mLogLevel.getSelectedIndex();
+ nvp.put(Constants.PR_LOG_LEVEL, str);
+ nvp.put(Constants.PR_LOG_BUFFERSIZE, mlogBufSizText.getText().trim());
+ //nvp.add(Constants.PR_LOG_EXPIRED_TIME, "");
+ //nvp.add(Constants.PR_LOG_FILENAME, "");
+ //nvp.add(Constants.PR_LOG_FLUSHINTERVAL, "");
+ nvp.put(Constants.PR_LOG_MAXFILESIZE, mlogMaxSizText.getText().trim());
+
+ str = "" + getRollOverTime(mlogFQC.getSelectedIndex());
+ nvp.put(Constants.PR_LOG_ROLLEROVER_INTERVAL, str);
+
+ try {
+ mAdmin.modify(DestDef.DEST_LOG_ADMIN,
+ ScopeDef.SC_SYSTEMLOG, Constants.RS_ID_CONFIG, nvp);
+ if (mIsNT) {
+ nvp.clear();
+ nvp.put(Constants.PR_NT_LOG_LEVEL,
+ "" + mNTLogLevel.getSelectedIndex());
+ nvp.put(Constants.PR_NT_EVENT_SOURCE,
+ mEventSourceText.getText().trim());
+ if (mActivateNTLog.isSelected())
+ nvp.put(Constants.PR_NT_LOG_ENABLED, Constants.TRUE);
+ else
+ nvp.put(Constants.PR_NT_LOG_ENABLED, Constants.FALSE);
+ mAdmin.modify(DestDef.DEST_LOG_ADMIN,
+ ScopeDef.SC_NTSYSTEMLOG, Constants.RS_ID_CONFIG, nvp);
+ }
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ return false;
+ }
+
+ clearDirtyFlag();
+ mModel.progressStop();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+
+ /*==========================================================
+ * EVENT HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ super.actionPerformed(e);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSAuditLogPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSAuditLogPanel.java
new file mode 100644
index 000000000..067b954e8
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSAuditLogPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+
+import java.awt.event.*;
+
+/**
+ * Audit Log Setting Tab to be displayed at the right hand side
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class CMSAuditLogPanel extends CMSBaseLogPanel {
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static String PANEL_NAME = "AUDITLOG";
+ private CMSTabPanel mParent;
+ private static final String HELPINDEX = "configuration-logs-audit-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSAuditLogPanel(CMSTabPanel parent, boolean isNT) {
+ super(PANEL_NAME, parent);
+ mParent = parent;
+ mHelpToken = HELPINDEX;
+ mIsNT = isNT;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Actual Instantiation of the UI components
+ */
+ public void init() {
+ Debug.println("AuditLogPanel: init()");
+ super.init();
+ refresh();
+ }
+
+ public void refresh() {
+ mModel.progressStart();
+ NameValuePairs nvp = new NameValuePairs();
+ nvp.put(Constants.PR_LOG_ENABLED, "");
+ nvp.put(Constants.PR_LOG_LEVEL, "");
+ nvp.put(Constants.PR_LOG_BUFFERSIZE, "");
+ //nvp.add(Constants.PR_LOG_EXPIRED_TIME, "");
+ //nvp.add(Constants.PR_LOG_FILENAME, "");
+ //nvp.add(Constants.PR_LOG_FLUSHINTERVAL, "");
+ nvp.put(Constants.PR_LOG_MAXFILESIZE, "");
+ nvp.put(Constants.PR_LOG_ROLLEROVER_INTERVAL, "");
+
+ try {
+ NameValuePairs val = mAdmin.read(DestDef.DEST_LOG_ADMIN,
+ ScopeDef.SC_AUDITLOG, Constants.RS_ID_CONFIG, nvp);
+ parseVals(val);
+ if (mIsNT) {
+ nvp.clear();
+ nvp.put(Constants.PR_NT_EVENT_SOURCE, "");
+ nvp.put(Constants.PR_NT_LOG_LEVEL, "");
+ nvp.put(Constants.PR_NT_LOG_ENABLED, "");
+ val = mAdmin.read(DestDef.DEST_LOG_ADMIN,
+ ScopeDef.SC_NTAUDITLOG, Constants.RS_ID_CONFIG, nvp);
+ parseNTVals(val);
+ }
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ }
+ setValues();
+ mModel.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+ }
+
+ private void parseVals(NameValuePairs nvp) {
+ if (nvp.get(Constants.PR_LOG_ENABLED).equalsIgnoreCase(
+ Constants.TRUE))
+ activateLog.setSelected(true);
+ else
+ activateLog.setSelected(false);
+ mLevel = Integer.parseInt(nvp.get(Constants.PR_LOG_LEVEL));
+ mlogBufSizTextData = nvp.get(Constants.PR_LOG_BUFFERSIZE);
+ mlogMaxSizTextData = nvp.get(Constants.PR_LOG_MAXFILESIZE);
+ int val =
+ Integer.parseInt(nvp.get(Constants.PR_LOG_ROLLEROVER_INTERVAL));
+ mFrequency = getRollOverIndex(val);
+ }
+
+ private void parseNTVals(NameValuePairs nvp) {
+ mNTLevel = Integer.parseInt(nvp.get(Constants.PR_NT_LOG_LEVEL));
+ mSource = nvp.get(Constants.PR_NT_EVENT_SOURCE);
+ if (nvp.get(Constants.PR_NT_LOG_ENABLED).equalsIgnoreCase(
+ Constants.TRUE))
+ mActivateNTLog.setSelected(true);
+ else
+ mActivateNTLog.setSelected(false);
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ // check blank fields
+ if ((mlogMaxSizText.getText().trim().equals("")) ||
+ (mlogBufSizText.getText().trim().equals("")) ) {
+ showMessageDialog("BLANKFIELD");
+ return false;
+ }
+
+ String bufSize = mlogBufSizText.getText().trim();
+ String maxSize = mlogMaxSizText.getText().trim();
+
+ try {
+ int val1 = Integer.parseInt(bufSize);
+ int val2 = Integer.parseInt(maxSize);
+ if (val1 <= 0 || val2 <= 0) {
+ showMessageDialog("OUTOFRANGE");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ showMessageDialog("NUMBERFORMAT");
+ return false;
+ }
+
+ NameValuePairs nvp = new NameValuePairs();
+ mModel.progressStart();
+ if (activateLog.isSelected())
+ nvp.put(Constants.PR_LOG_ENABLED, Constants.TRUE);
+ else
+ nvp.put(Constants.PR_LOG_ENABLED, Constants.FALSE);
+ String str = "" + mLogLevel.getSelectedIndex();
+ nvp.put(Constants.PR_LOG_LEVEL, str);
+ nvp.put(Constants.PR_LOG_BUFFERSIZE, mlogBufSizText.getText().trim());
+ //nvp.add(Constants.PR_LOG_EXPIRED_TIME, "");
+ //nvp.add(Constants.PR_LOG_FILENAME, "");
+ //nvp.add(Constants.PR_LOG_FLUSHINTERVAL, "");
+ nvp.put(Constants.PR_LOG_MAXFILESIZE, mlogMaxSizText.getText().trim());
+
+ str = "" + getRollOverTime(mlogFQC.getSelectedIndex());
+ nvp.put(Constants.PR_LOG_ROLLEROVER_INTERVAL, str);
+
+ try {
+ mAdmin.modify(DestDef.DEST_LOG_ADMIN,
+ ScopeDef.SC_AUDITLOG, Constants.RS_ID_CONFIG, nvp);
+ if (mIsNT) {
+ nvp.clear();
+ nvp.put(Constants.PR_NT_LOG_LEVEL,
+ "" + mNTLogLevel.getSelectedIndex());
+ nvp.put(Constants.PR_NT_EVENT_SOURCE,
+ mEventSourceText.getText().trim());
+ if (mActivateNTLog.isSelected())
+ nvp.put(Constants.PR_NT_LOG_ENABLED, Constants.TRUE);
+ else
+ nvp.put(Constants.PR_NT_LOG_ENABLED, Constants.FALSE);
+ mAdmin.modify(DestDef.DEST_LOG_ADMIN,
+ ScopeDef.SC_NTAUDITLOG, Constants.RS_ID_CONFIG, nvp);
+ }
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ return false;
+ }
+
+ mModel.progressStop();
+ clearDirtyFlag();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+
+ /*==========================================================
+ * EVENT HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ super.actionPerformed(e);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSAutoRecovery.java b/base/console/src/com/netscape/admin/certsrv/config/CMSAutoRecovery.java
new file mode 100644
index 000000000..ef55470c6
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSAutoRecovery.java
@@ -0,0 +1,267 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import java.awt.*;
+import java.util.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.table.*;
+import javax.swing.text.*;
+import javax.swing.event.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.*;
+
+/**
+ * Display the auto recovery dialog box.
+ * @author chrisho
+ * @version $Revision$, $Date$
+ */
+public class CMSAutoRecovery extends JDialog implements ActionListener,
+ ListSelectionListener, MouseListener {
+
+ private final static String PREFIX = "AUTORECOVERYDIALOG";
+ private AdminConnection mAdmin;
+ private JFrame mParentFrame;
+ private ResourceBundle mResource;
+ private JButton mOK;
+ private JButton mCancel;
+ private JButton mEnable;
+ private String mDisableLabel;
+ private String mDisableTip;
+ private JTable mTable;
+ private AutoRecoveryModel mDataModel;
+ protected JScrollPane mScrollPane;
+
+ public CMSAutoRecovery(JFrame parent, AdminConnection conn, JButton button) {
+ super(parent, true);
+ mParentFrame = parent;
+ mAdmin = conn;
+ mEnable = button;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mDisableLabel = mResource.getString(PREFIX + "_BUTTON_"+"DISABLEAUTO_LABEL");
+ mDisableTip = mResource.getString(PREFIX + "_BUTTON_"+"DISABLEAUTO_TTIP");
+ setSize(360, 216);
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ setDisplay();
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getActionCommand().equals("ok")) {
+
+ Component component = mTable.getEditorComponent();
+ if(component!= null) {
+ int col = mTable.getEditingColumn();
+ int row = mTable.getEditingRow();
+ if ((col>-1)&&(row>-1)) {
+ String str = ((JTextComponent)component).getText();
+ mTable.setValueAt(str, row, col);
+ }
+ }
+
+ String val = getUIDPassword();
+
+ // check empty user id and password
+ if (val.equals("")) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, mResource,
+ PREFIX, "EMPTYFIELD", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ } else {
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_RECOVERY_AGENT, val);
+ nvps.put(Constants.PR_AUTO_RECOVERY_ON, Constants.TRUE);
+
+ try {
+ mAdmin.modify(DestDef.DEST_KRA_ADMIN,
+ ScopeDef.SC_AUTO_RECOVERY, Constants.RS_ID_CONFIG, nvps);
+ } catch (EAdminException ex) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ ex.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ }
+ }
+ mEnable.setText(mDisableLabel);
+ mEnable.setToolTipText(mDisableTip);
+ mEnable.repaint();
+ cleanup();
+ this.dispose();
+ } else if (e.getActionCommand().equals("cancel")) {
+ cleanup();
+ this.dispose();
+ }
+
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(
+ new DefaultTableCellRenderer());
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellEditor(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(
+ new PasswordCellRenderer());
+ table.getColumnModel().getColumn(index).setCellEditor(
+ new DefaultCellEditor(new JPasswordField()));
+ }
+
+ private String getUIDPassword() {
+ String result = "";
+ for (int i=0; i<mDataModel.getRowCount(); i++) {
+ for (int j=1; j<mDataModel.getColumnCount(); j++) {
+ String val = (String)mDataModel.getValueAt(i, j);
+ if (val.equals(""))
+ return "";
+ else if (j == (mDataModel.getColumnCount()-1))
+ result = result+val;
+ else
+ result = result+val+"=";
+ }
+ if (i < (mDataModel.getRowCount()-1))
+ result = result+",";
+ }
+ return result;
+ }
+
+ private void cleanup() {
+ mDataModel.removeAllRows();
+ }
+
+ private void setDisplay() {
+ GridBagLayout gbm = new GridBagLayout();
+ getContentPane().setLayout(gbm);
+ GridBagConstraints gbc = new GridBagConstraints();
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel heading = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "HEADING", null);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbm.setConstraints(heading, gbc);
+ getContentPane().add(heading);
+
+ createTable();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gbm.setConstraints(mScrollPane, gbc);
+ getContentPane().add(mScrollPane);
+
+ JPanel action = makeActionPane();
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.SOUTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbm.setConstraints(action, gbc);
+ getContentPane().add(action);
+
+ this.show();
+ }
+
+ private JPanel makeLabelPane() {
+ JPanel labelPane = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ labelPane.setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel heading = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "HEADING", null);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(heading, gbc);
+ labelPane.add(heading);
+ return labelPane;
+ }
+
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null, this);
+ mOK.setActionCommand("ok");
+ mCancel = CMSAdminUtil.makeJButton(mResource, PREFIX, "CANCEL", null, this);
+ mCancel.setActionCommand("cancel");
+ JButton[] buttons = {mOK, mCancel};
+ JButtonFactory.resize(buttons);
+ return CMSAdminUtil.makeJButtonPanel(buttons);
+ }
+
+ private void createTable() {
+
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_RECOVERY_M, "");
+
+ int numUsers = 0;
+ try {
+ NameValuePairs val = mAdmin.read(DestDef.DEST_KRA_ADMIN,
+ ScopeDef.SC_RECOVERY, Constants.RS_ID_CONFIG, nvps);
+ String str = val.get(Constants.PR_RECOVERY_M);
+ numUsers = Integer.parseInt(str);
+ } catch (EAdminException e) {
+ //showErrorDialog(e.toString());
+ }
+
+ mDataModel = new AutoRecoveryModel();
+ Vector[] data = new Vector[numUsers];
+ for (int i=0; i<data.length; i++) {
+ data[i] = new Vector();
+ Integer num = new Integer(i+1);
+ data[i].addElement(num.toString());
+ data[i].addElement("");
+ data[i].addElement("");
+ mDataModel.addRow(data[i]);
+ }
+
+ mTable = new JTable(mDataModel);
+ mTable.setShowGrid(true);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.setPreferredScrollableViewportSize(new Dimension(200, 100));
+ //mTable.setMaximumSize(new Dimension(200, 100));
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
+ mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ mTable.addMouseListener((MouseListener)this);
+ setLabelCellRenderer(mTable, 1);
+ setLabelCellEditor(mTable, 2);
+ }
+
+ public void mouseClicked(MouseEvent e) {}
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {}
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {}
+ public void valueChanged(ListSelectionEvent e){
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSBaseConfigDialog.java b/base/console/src/com/netscape/admin/certsrv/config/CMSBaseConfigDialog.java
new file mode 100644
index 000000000..87562829b
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSBaseConfigDialog.java
@@ -0,0 +1,1078 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Plugin Parameter Configuration Dialog
+ *
+ * @author Steve Parkinson
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class CMSBaseConfigDialog extends JDialog
+ implements ActionListener, MouseListener, FocusListener
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ protected JFrame mParentFrame;
+ protected ResourceBundle mResource;
+
+ protected String PREFIX = null;
+
+ protected boolean mIsOK = false;
+ protected NameValuePairs mData=null;
+
+ protected JScrollPane mScrollPane=null;
+ protected JTable mTable=null;
+ protected String mRuleName=null;//instance name
+ protected JPanel mParamPanel=null;
+ protected JPanel mHelpPanel=null;
+ protected JTextArea mHelpLabel=null;
+
+ protected JButton mOK=null, mCancel=null, mHelp=null;
+ protected JTextField mPluginName=null;
+ protected JLabel mImplnameCaption=null,mRulenameCaption=null;
+ protected JLabel mImplName=null, mPluginLabel=null;
+ protected String RAHELPINDEX=null;
+ protected String KRAHELPINDEX=null;
+ protected String CAHELPINDEX=null;
+ protected String mHelpToken=null;
+
+ protected AdminConnection mAdminConnection = null;
+
+ protected String mImplName_token=null;//nvp index for plubinName
+ protected String mImplType=null;//plugin type:policy,auth etc
+ protected String mDest;
+ protected String mInstanceScope=null;
+ protected String mId = null; // used as a ip id for crl exts
+
+ /* true if creating a new instance
+ * false if editing an old one
+ */
+ protected boolean mNewInstance=false; //
+
+ private ExtendedPluginInfoSet mEPIs = null;
+ protected CMSBaseResourceModel mModel = null;
+
+ private String mServletName;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSBaseConfigDialog(JFrame frame,
+ String dest) {
+ super(frame,true);
+ mServletName = dest;
+ }
+
+ protected void init(NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest)
+ {
+ mParentFrame = parent;
+ mDest = dest;
+ mAdminConnection = conn;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ setSize(360, 415);
+
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(mParentFrame);
+ getRootPane().setDoubleBuffered(true);
+ setDisplay();
+ }
+
+ protected void init(NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ String id)
+ {
+ mId = id;
+ init(nvp, parent, conn, dest);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * the model needs to be set if we need to start/stop the progress
+ * bar.
+ */
+
+ public void setModel(CMSBaseResourceModel model)
+ {
+ mModel = model;
+ }
+
+ public void setInstanceScope(String s)
+ {
+ mInstanceScope = s;
+ }
+
+ /**
+ * retrieve the extended plugin information for this plugin
+ * from the server. The servlet must implement the scope
+ * 'extendedPluginInfo' and the plugin must implement the
+ * IExtendedPluginInfo interface, or else the display
+ * will revert back to simple name-value pairs.
+ */
+
+ ExtendedPluginInfoSet getExtendedPluginInfo(String implname,
+ NameValuePairs oldstyle) {
+
+ NameValuePairs data = new NameValuePairs();
+ String query = mImplType+":"+implname;//implName:pluginName
+ NameValuePairs response=null;
+
+ if (mImplType.equals("policy") &&
+ (mRuleName != null) && !mRuleName.trim().equals("")) {
+ query = query + ":" + mRuleName;
+ }
+
+ /* make the request to the server */
+ try {
+ response = mAdminConnection.read(mServletName,
+ ScopeDef.SC_EXTENDED_PLUGIN_INFO,
+ query,
+ data);
+ }
+ catch (EAdminException e) {
+ }
+
+ ExtendedPluginInfoSet epis = new ExtendedPluginInfoSet();
+
+ if (response == null) response = new NameValuePairs();
+
+ /* if the servlet or rule wasn't capable of handling the new style
+ * of interface, just return the names from the name/value pairs that
+ * were passed in
+ * otherwise, for each parameter name, fetch the associated
+ * parameter type from the extendedPluginInfo that the server
+ * returned
+ */
+ for (String name : oldstyle.keySet()) {
+ String value = response.get(name);
+ if (value != null) {
+ epis.add(name, value,false);
+ }
+ else {
+ epis.add(name, "",true);
+ }
+ }
+
+
+ String ht = response.get("HELP_TOKEN");
+ if (ht != null) epis.setHelpToken(ht);
+
+ String hs = response.get("HELP_TEXT");
+ if (hs != null) epis.setHelpSummary(hs);
+
+ return epis;
+ }
+
+
+
+ /**
+ * show the list of configuration parameters
+ */
+ public void showDialog(NameValuePairs data, String name) {
+ mIsOK = false;
+
+ mData = data;
+
+ Debug.println("in CMSBaseConfigDialog.showDialog()");
+
+ JPanel p = mParamPanel;
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ p.setLayout(gb);
+
+ mRuleName = data.get(mImplName_token);
+ mEPIs = getExtendedPluginInfo(mRuleName,data);
+
+ for (String entry : data.keySet()) {
+ entry = entry.trim();
+ Debug.println("in CMSBaseConfigDialog.showDialog() entry=" + entry);
+ if (!entry.equals(mImplName_token)) {
+ String labelname = entry;
+
+ /* comp is the component which represents the value
+ * of the parameter. It can be a checkbox, choice, or
+ * text field
+ */
+
+ JComponent comp = null;
+ String stringvalue = data.get(entry);
+ ExtendedPluginInfo epi = mEPIs.get(entry);
+ if (epi == null) {
+ Debug.println("no ExtendedPluginInfo for "+entry);
+ }
+
+ if (epi.getType() == ExtendedPluginInfo.TYPE_PASSWORD) {
+ labelname = "password";
+ }
+
+ if (epi.isRequired()) {
+ labelname = "* "+labelname;
+ }
+
+ /* this label is the name of the parameter. We need
+ * to add a mouselistener so that we can update the
+ * help text if someone clicks on the label
+ */
+ JLabel l = new JLabel(labelname);
+ l.addMouseListener(this);
+
+ CMSAdminUtil.resetGBC(gbc);
+
+ gbc.gridwidth = 1;
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.2;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(
+ CMSAdminUtil.COMPONENT_SPACE, // top
+ 0, // left
+ 0, // bottom
+ 5); // right
+ p.add(l,gbc);
+
+
+ /* if there was no text extendedplugininfo for this parameter
+ * just make it a text box
+ */
+ if (epi == null) {
+ comp = new JTextField(stringvalue);
+ }
+ else {
+ epi.setValue(stringvalue);
+ comp = epi.makeComponent(this);
+ }
+
+ /* this lets us get an event when this component
+ * is clicked on, so we can update the help text
+ */
+ comp.addFocusListener(this);
+
+ gbc.weightx = 0.7;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.gridwidth = gbc.RELATIVE;
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(
+ CMSAdminUtil.COMPONENT_SPACE, //top
+ 0, //left
+ 0, //bottom
+ 0); // right
+ p.add(comp ,gbc);
+
+ /* add a dummy component to the end of each row to
+ * keep it from hiting the edge of the panel
+ */
+ JLabel j = new JLabel("");
+ gbc.weightx = 0.1;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(
+ CMSAdminUtil.COMPONENT_SPACE, //top
+ 0, //left
+ 0, //bottom
+ CMSAdminUtil.COMPONENT_SPACE); // right
+ p.add(j,gbc);
+
+ }
+ }
+
+ mImplName.setText(mRuleName);
+
+ if ((name==null)||name.equals("")) {
+ mNewInstance = true;
+ /* we're dealing with a new instance - so the rule name is
+ * a text box - it's editable
+ */
+ mPluginName.setVisible(true);
+ mPluginName.setText(getDefaultInstanceName(mRuleName));
+ mPluginLabel.setVisible(false);
+ } else {
+ mNewInstance = false;
+ /* we're editing an old instance - so the rule name is just
+ * a label - you can't edit it
+ */
+ mPluginName.setVisible(false);
+ mPluginLabel.setVisible(true);
+ mPluginLabel.setText(name);
+ }
+
+ mHelpLabel.setText(mEPIs.getHelpSummary());
+ mHelpLabel.repaint();
+
+ mImplName.addMouseListener(this);
+ mPluginName.addMouseListener(this);
+ mPluginLabel.addMouseListener(this);
+
+ this.show();
+ }
+
+ public String getDefaultInstanceName(String implName)
+ {
+ Debug.println("in CMSBaseConfigDialog::getDefaultInstanceName("+implName+") - returning ''");
+ return "";
+ }
+
+ public boolean isOK() {
+ return mIsOK;
+ }
+
+
+ public String getRuleName() {
+ return mRuleName;
+ }
+
+ /*==========================================================
+ * EVENT HANDLER METHODS
+ *==========================================================*/
+
+ /**
+ * From focuslistener interface. This lets us know when a component
+ * has received focus, so we can update the help text.
+ */
+ public void focusGained(FocusEvent f) {
+ Component comp = f.getComponent();
+ mPluginName.addFocusListener(this);
+ mPluginLabel.addMouseListener(this);
+ String text = "";
+
+ if (comp instanceof ExtendedPluginInfoComponent) {
+ ExtendedPluginInfoComponent epic = (ExtendedPluginInfoComponent)comp;
+ ExtendedPluginInfo epi = epic.getExtendedPluginInfo();
+ text = epi.getHelpText()+" ";
+ }
+ else if (doHelpSummary(comp)) {
+ text = mEPIs.getHelpSummary();
+ }
+ else {
+ }
+
+ mHelpLabel.setText(text);
+ mHelpLabel.repaint();
+
+ }
+
+ /** need to supply this method for focuslistener, but we
+ * really don't care about it
+ */
+ public void focusLost(FocusEvent f) {
+ }
+
+
+ /*
+ * mouselistener events - for JLabel
+ */
+
+ /**
+ * This lets us know when someone clicked a label, so we can
+ * update the help text
+ */
+ public void mouseClicked(MouseEvent e) {
+ Component c = e.getComponent();
+ String helpText = "";
+ if (c instanceof JLabel) {
+ String paramName = ((JLabel)c).getText();
+ ExtendedPluginInfo epi = mEPIs.get(paramName);
+
+ if (epi != null) helpText = epi.getHelpText();
+ else if (doHelpSummary(c)) {
+ helpText = mEPIs.getHelpSummary();
+ }
+ }
+ mHelpLabel.setText(helpText);
+ mHelpLabel.repaint();
+ }
+
+ public void mouseEntered(MouseEvent e) {
+ }
+ public void mouseExited(MouseEvent e) {
+ }
+ public void mousePressed(MouseEvent e) {
+ }
+ public void mouseReleased(MouseEvent e) {
+ }
+
+
+ public boolean doHelpSummary(Component c) {
+
+ if (c.equals(mPluginName) ||
+ c.equals(mPluginLabel) ||
+ c.equals(mRulenameCaption) ||
+ c.equals(mImplnameCaption) ||
+ c.equals(mImplName) ) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ //=== ACTIONLISTENER =====================
+
+ /**
+ * this gets called when a someone made some kind of event happen.
+ * We really only check for the OK, Cancel, or Help buttons here
+ */
+ public void actionPerformed(ActionEvent evt) {
+
+ if (evt.getSource().equals(mOK)) {
+
+ /* if this is a new instance of a rule, (as opposed to editing an old one) */
+ if (mNewInstance) {
+ mRuleName = mPluginName.getText();
+ /* make sure they set the name of the rule, otherwise, show an error message */
+ if (mRuleName.trim().equals("")) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ mResource.getString("INSTANCECONFIGDIALOG_DIALOG_NOINSTANCENAME_MESSAGE"),
+ CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ }
+ else {
+ mRuleName = mPluginLabel.getText();
+ }
+
+ Debug.println(4,"User pressed okay on instance config dialog");
+ Enumeration e = mEPIs.keys();
+ NameValuePairs nvp = new NameValuePairs();
+ while (e.hasMoreElements()) {
+ String paramName = (String)e.nextElement();
+ ExtendedPluginInfo epi = mEPIs.get(paramName);
+ String value = epi.getComponentStateAsString();
+ if (epi.getType() == ExtendedPluginInfo.TYPE_PASSWORD) {
+ String password = value;
+ value = "Rule "+mRuleName;
+ if (password != null && password.length() >0) {
+ nvp.put("PASSWORD_CACHE_ADD", value + ";" + password);
+ }
+ }
+
+ nvp.put(paramName, value);
+ }
+ nvp.put(PolicyRuleDataModel.RULE_NAME, mRuleName);
+ nvp.put(mImplName_token, mImplName.getText());
+
+ mData = nvp;
+ try {
+ if (mModel != null) { mModel.progressStart(); }
+ if (mNewInstance == true) {
+ mAdminConnection.add(mDest, mInstanceScope, mRuleName, nvp);
+ }
+ else {
+ if (mId != null && mId.length() > 0) {
+ nvp.put(Constants.PR_ID, mId);
+ }
+ mAdminConnection.modify(mDest, mInstanceScope, mRuleName, nvp);
+ }
+ mIsOK = true;
+ if (mModel != null) { mModel.progressStop(); }
+ this.dispose();
+ }
+ catch (EAdminException ex) {
+ mModel.progressStop();
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ ex.toString(),CMSAdminUtil.ERROR_MESSAGE);
+ }
+ }
+
+ if (evt.getSource().equals(mCancel)) {
+ this.dispose();
+ }
+ if (evt.getSource().equals(mHelp)) {
+ String ht = mEPIs.getHelpToken();
+ if (ht == null || ht.equals("")) {
+ CMSAdminUtil.help(mHelpToken);
+ }
+ else {
+ CMSAdminUtil.help(ht);
+ }
+ }
+ }
+
+
+ public NameValuePairs getData() {
+ return mData;
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+ private void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+
+ /* Content panel. This is where we put the name/value pairs,
+ * and the help text */
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+
+ /* Action panel. This is where we put the OK, Cancel, Help buttons */
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ //create botton action panel
+ private JPanel makeActionPane() {
+
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null, this);
+ mCancel = CMSAdminUtil.makeJButton(mResource, PREFIX, "CANCEL", null, this);
+ mHelp = CMSAdminUtil.makeJButton(mResource, PREFIX, "HELP", null, this);
+
+ //JButton[] buttons = { mOK, mCancel, mHelp};
+ JButton[] buttons = { mOK, mCancel};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonPanel( buttons, true);
+ }
+
+ protected void setDestination(String dest) {
+ mDest = dest;
+ }
+
+ protected JPanel makeContentPane() {
+ JPanel mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ /* mPluginName and mPluginLabel occupy the same space in the UI, but
+ * only one of them is visible at a time. showDialog() determines which
+ * is visible. If this is a new component, mPluginName is visible, and is a
+ * a text field, so the user can enter the name of the new instance.
+ * Otherwise, it's just a label, showing the existing name.
+ */
+ // 'Policy Rule ID' here
+ CMSAdminUtil.resetGBC(gbc);
+ mRulenameCaption = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "RULENAME", null);
+ mRulenameCaption.addMouseListener(this);
+ mPluginLabel = new JLabel();
+ mPluginLabel.setVisible(false);
+ mPluginName = new JTextField();
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add(mRulenameCaption, gbc);
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ 0,CMSAdminUtil.COMPONENT_SPACE);
+ mListPanel.add( mPluginName, gbc );
+ mListPanel.add( mPluginLabel, gbc );
+
+ // 'Policy Plugin ID' here
+ CMSAdminUtil.resetGBC(gbc);
+ mImplnameCaption = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "IMPLNAME", null);
+ mImplnameCaption.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add( mImplnameCaption, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mImplName = new JLabel();
+ mListPanel.add( mImplName, gbc );
+
+ /* Panel for list of plugin's parameters */
+ mParamPanel = new JPanel();
+
+ mScrollPane = new JScrollPane(mParamPanel);
+ mScrollPane.setBorder(CMSAdminUtil.makeEtchedBorder());
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.BOTH;
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ /* Panel in which to put plugin's help text */
+ mHelpPanel = new JPanel();
+ mHelpPanel.setBorder(CMSAdminUtil.makeEtchedBorder());
+ mHelpLabel = new JTextArea(3,0);
+ mHelpLabel.setLineWrap(true);
+ mHelpLabel.setWrapStyleWord(true);
+ mHelpLabel.setBackground(mHelpPanel.getBackground());
+ mHelpLabel.setEditable(false);
+ GridBagLayout gb2 = new GridBagLayout();
+ GridBagConstraints gbc2 = new GridBagConstraints();
+
+ CMSAdminUtil.resetGBC(gbc2);
+ gbc2.fill = gbc.BOTH;
+ gbc2.anchor = gbc.WEST;
+ gbc2.gridwidth = gbc.REMAINDER;
+ gbc2.weightx = 1.0;
+ gbc2.weighty = 1.0;
+ gb2.setConstraints(mHelpLabel, gbc2);
+ mHelpPanel.setLayout(gb2);
+ mHelpPanel.add(mHelpLabel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.SOUTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gb.setConstraints(mHelpPanel, gbc);
+ mListPanel.add(mHelpPanel);
+
+ return mListPanel;
+ }
+
+}
+
+
+class ExtendedPluginInfoSet extends Hashtable {
+
+ /**
+ * Add a value for this config parameter.
+ * the format of 'syntax' is specified in
+ * @see com.netscape.certsrv.base.IExtendedPluginInfo
+ */
+ public void add(String param, String syntax, boolean oldstyle) {
+
+ try {
+ String type;
+ ExtendedPluginInfo epi;
+ boolean required=false;
+
+ if (!oldstyle) {
+ String rest, helptext;
+ int semicolon = syntax.indexOf(';');
+
+ type = syntax.substring(0,semicolon);
+ rest = syntax.substring(semicolon+1);
+
+ for (int i=0;i<1;i++) {
+ int length = type.length();
+ if (type.endsWith(",required")) {
+ type=type.substring(0,length-0);
+ required=true;
+ }
+ }
+ helptext = rest; // ADDED to fix bug #383969
+/*
+ semicolon = rest.indexOf(';');
+ if (semicolon == -1) { // no more semicolons
+ helptext = rest;
+ }
+ else {
+ helptext = rest.substring(0,semicolon);
+ rest = rest.substring(semicolon+1);
+ }
+*/
+ epi = new ExtendedPluginInfo(type,helptext);
+ epi.setRequired(required);
+ }
+ else {
+ epi = new ExtendedPluginInfo("string","");
+ }
+
+ put(param,epi);
+ } catch (Exception e) {
+ Debug.println("Badly formatted ExtendedpluginInfo for string: '"+
+ syntax+"'");
+ }
+ }
+
+ private String mHelpSummary = "";
+ private String mHelpToken = "";
+
+ public String getHelpSummary() {
+ return mHelpSummary;
+ }
+
+ public void setHelpSummary(String summary) {
+ mHelpSummary = summary;
+ }
+
+ public String getHelpToken() {
+ return mHelpToken;
+ }
+
+ public void setHelpToken(String token) {
+ mHelpToken = token;
+ }
+
+ public ExtendedPluginInfo get(String param) {
+ return (ExtendedPluginInfo)super.get(param);
+ }
+
+}
+
+
+
+interface ExtendedPluginInfoComponent
+{
+ public abstract ExtendedPluginInfo getExtendedPluginInfo();
+
+ public abstract String getValueAsString();
+}
+
+
+class ExtendedPluginInfoCheckBox extends JCheckBox
+implements ExtendedPluginInfoComponent
+{
+ private ExtendedPluginInfo mEpi;
+
+ public ExtendedPluginInfoCheckBox(ExtendedPluginInfo epi, boolean b)
+ {
+ super("",b);
+ mEpi = epi;
+ }
+
+ public ExtendedPluginInfo getExtendedPluginInfo() {
+ return mEpi;
+ }
+
+ public String getValueAsString() {
+ if (isSelected()) {
+ return "true";
+ }
+ else {
+ return "false";
+ }
+ }
+
+}
+
+class ExtendedPluginInfoComboBox extends JComboBox
+implements ExtendedPluginInfoComponent
+{
+ private ExtendedPluginInfo mEpi;
+
+ public ExtendedPluginInfoComboBox(ExtendedPluginInfo epi, Vector v)
+ {
+ super(v);
+ mEpi = epi;
+ }
+
+ public ExtendedPluginInfo getExtendedPluginInfo() {
+ return mEpi;
+ }
+
+ public String getValueAsString() {
+ return (String)getSelectedItem();
+ }
+}
+
+class ExtendedPluginInfoTextField extends JTextField
+implements ExtendedPluginInfoComponent
+{
+ private ExtendedPluginInfo mEpi;
+
+ public ExtendedPluginInfoTextField(ExtendedPluginInfo epi, String s)
+ {
+ super(s);
+ mEpi = epi;
+ }
+
+ public ExtendedPluginInfo getExtendedPluginInfo() {
+ return mEpi;
+ }
+
+ public String getValueAsString() {
+ return getText();
+ }
+}
+
+class ExtendedPluginInfoPasswordField extends JPasswordField
+implements ExtendedPluginInfoComponent
+{
+ private ExtendedPluginInfo mEpi;
+
+ public ExtendedPluginInfoPasswordField(ExtendedPluginInfo epi, String s)
+ {
+ super(s);
+ mEpi = epi;
+ }
+
+ public ExtendedPluginInfo getExtendedPluginInfo() {
+ return mEpi;
+ }
+
+ public String getValueAsString() {
+ return getText();
+ }
+}
+
+class ExtendedPluginInfoNumberField extends JTextField
+implements ExtendedPluginInfoComponent
+{
+ private ExtendedPluginInfo mEpi;
+
+ public ExtendedPluginInfoNumberField(ExtendedPluginInfo epi, String s)
+ {
+ super(s);
+ mEpi = epi;
+ }
+
+ public ExtendedPluginInfo getExtendedPluginInfo() {
+ return mEpi;
+ }
+
+ public String getValueAsString() {
+ return getText();
+ }
+
+ protected Document createDefaultModel() {
+ return new NumberDocument();
+ }
+
+ static class NumberDocument extends PlainDocument {
+
+ public void insertString(int offs, String str, AttributeSet a)
+ throws BadLocationException {
+
+ if (str == null) {
+ return;
+ }
+
+ char[] chars = str.toCharArray();
+ int j=0;
+
+ for (int i = 0; i < chars.length; i++) {
+ if ( (chars[i]<'0' || chars[i]>'9')
+ && (chars[i] != '.')
+ && (chars[i] != '-') ) {
+ }
+ else {
+ chars[j++] = chars[i];
+ }
+ }
+ char newchars[] = new char[j];
+ if (j != 0) {
+ System.arraycopy(chars,0,newchars,0,j);
+ }
+ super.insertString(offs, new String(newchars), a);
+ }
+ }
+}
+
+
+
+/**
+ * This class records information about the type of a parameter
+ * and what possible value it can take
+ */
+
+class ExtendedPluginInfo {
+
+ public static final int TYPE_STRING = 0;
+ public static final int TYPE_BOOLEAN = 1;
+ public static final int TYPE_NUMBER = 2;
+ public static final int TYPE_CHOICE = 3;
+ public static final int TYPE_PASSWORD = 4;
+
+ private int mType;
+ private boolean mRequired;
+
+ private String mValue = null;
+
+ private Vector mChoices = null;
+
+ private String mHelpText = null;
+
+
+ ExtendedPluginInfo(String type, String helptext)
+ {
+ mHelpText = helptext;
+
+ if (type.equals("string")) {
+ mType = TYPE_STRING;
+ }
+ else if (type.equals("boolean")) {
+ mType = TYPE_BOOLEAN;
+ }
+ else if (type.equals("number")) {
+ mType = TYPE_NUMBER;
+ }
+ else if (type.equals("integer")) {
+ mType = TYPE_NUMBER;
+ }
+ else if (type.equals("password")) {
+ mType = TYPE_PASSWORD;
+ }
+ else if (type.startsWith("choice")) {
+ mType = TYPE_CHOICE;
+ String choices = type.substring(
+ type.indexOf('(')+1,
+ type.indexOf(')')
+ );
+ StringTokenizer tokenizer = new StringTokenizer(choices,",",false);
+ mChoices = new Vector();
+ String prefix = null;
+ while (tokenizer.hasMoreElements()) {
+ String c = (String)tokenizer.nextElement();
+ int i = c.indexOf("\\");
+ if ( i != -1 ) {
+ if (prefix == null)
+ prefix = c.substring(0,i);
+ else
+ prefix = prefix + "," + c.substring(0,i);
+ } else {
+ if (prefix != null) {
+ c = prefix + "," + c;
+ prefix = null;
+ }
+ mChoices.addElement(c);
+ }
+ }
+ }
+ else {
+ mType = TYPE_STRING; // unknown type - default to string type
+ }
+ }
+
+ public Vector getChoices() {
+ return mChoices;
+ }
+
+ public String getHelpText() {
+ return mHelpText;
+ }
+
+ public String getValue() {
+ return mValue;
+ }
+
+ public void setValue(String val) {
+ mValue = val;
+ }
+
+ public int getType() {
+ return mType;
+ }
+
+ public void setRequired(boolean b) {
+ mRequired = b;
+ }
+
+ public boolean isRequired() {
+ return mRequired;
+ }
+
+ private JComponent component = null;
+
+ public JComponent getComponent() {
+ return component;
+ }
+
+ public String getComponentStateAsString() {
+ if (component == null)
+ return null;
+ return ((ExtendedPluginInfoComponent)component).getValueAsString();
+ }
+
+ public JComponent makeComponent(ActionListener al)
+ {
+ switch (getType()) {
+ case ExtendedPluginInfo.TYPE_BOOLEAN:
+ boolean b;
+ if (getValue().equals("true")) { b=true; }
+ else { b = false; }
+ component = new ExtendedPluginInfoCheckBox(this,b);
+ ((ExtendedPluginInfoCheckBox)component).addActionListener(al);
+ break;
+
+ case ExtendedPluginInfo.TYPE_STRING:
+ component = new ExtendedPluginInfoTextField(this,getValue());
+ ((ExtendedPluginInfoTextField)component).addActionListener(al);
+ break;
+
+ case ExtendedPluginInfo.TYPE_NUMBER:
+ component = new ExtendedPluginInfoNumberField(this,getValue());
+ ((ExtendedPluginInfoNumberField)component).addActionListener(al);
+ break;
+
+ case ExtendedPluginInfo.TYPE_PASSWORD:
+ component = new ExtendedPluginInfoPasswordField(this,"");
+ ((ExtendedPluginInfoPasswordField)component).addActionListener(al);
+ break;
+
+ case ExtendedPluginInfo.TYPE_CHOICE:
+ JComboBox cb = new ExtendedPluginInfoComboBox(this,getChoices());
+ cb.setSelectedItem(getValue());
+ ((ExtendedPluginInfoComboBox)cb).addActionListener(al);
+ component = cb;
+ break;
+
+ default:
+ return null;
+ }
+ return component;
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSBaseConfigPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSBaseConfigPanel.java
new file mode 100644
index 000000000..89dce60c7
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSBaseConfigPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.border.*;
+import javax.swing.text.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+import java.util.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * Netscape Certificate Server 4.0 Default Base Panel
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public abstract class CMSBaseConfigPanel extends CMSBasePanel {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+
+ private String mTitle; // panel title actually shows
+ protected boolean mDirty = false; // panel dirty flag
+ protected boolean mInit = false; // true if this panel is initialized
+ protected JPanel mCenterPanel; // display panel
+ protected String mHelpToken;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSBaseConfigPanel(String panelName) {
+ super(panelName);
+ //mPanelName = panelName;
+ setLayout(new BorderLayout());
+ mCenterPanel = new JPanel();
+ try {
+ String title = mResource.getString(mPanelName+"_TITLE");
+ mTitle = title;
+ } catch (MissingResourceException e) {
+ mTitle = "Missing Title";
+ }
+ }
+
+ public CMSBaseConfigPanel() {
+ super("");
+ mTitle = "Missing Title";
+ }
+
+ /*==========================================================
+ * abstract methods
+ *==========================================================*/
+
+ //Actual Instanciation of the panels
+ public abstract void init();
+
+ //Implementation for saving panel information
+ public abstract boolean applyCallback();
+
+ //Implementation for reset values
+ public abstract boolean resetCallback();
+
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ //Implementation for calling help
+ public void helpCallback() {
+ CMSAdminUtil.help(mHelpToken);
+ }
+
+ /**
+ * Returns the title of the tab
+ * @return string representation of the title
+ */
+ public String getTitle() {
+ return mTitle;
+ }
+
+ /**
+ * set the title of the tab
+ */
+ public void setTitle(String title) {
+ mTitle = title;
+ }
+
+ /**
+ * see if the contents of the panel have been changed but not applied
+ * @return true if dirty; otherwise,false.
+ */
+ public boolean isDirty() {
+ return mDirty;
+ }
+
+ /**
+ * Called by the Tab parent to initialize the panel
+ */
+ public void initialize() {
+ if (!mInit) {
+ //Debug.println("CMSBasePanel: initialize()"+mPanelName);
+ mCenterPanel.setBorder(new EmptyBorder(DEFAULT_CENTER_INSETS));
+ init();
+ mInit = true;
+ }
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ if (mInit)
+ this.setDirtyFlag();
+ }
+
+ //== DocumentListener ==
+ public void insertUpdate(DocumentEvent e) {
+ if (mInit)
+ this.setDirtyFlag();
+ }
+ public void removeUpdate(DocumentEvent e){
+ if (mInit)
+ this.setDirtyFlag();
+ }
+ public void changedUpdate(DocumentEvent e){
+ if (mInit)
+ this.setDirtyFlag();
+ }
+
+ //== ItemListener ==
+ public void itemStateChanged(ItemEvent e){
+ if (mInit)
+ this.setDirtyFlag();
+ }
+
+ //== ListSelectionListener ==
+ public void valueChanged(ListSelectionEvent e){
+ if (mInit)
+ this.setDirtyFlag();
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+
+ //=== Dirty Flag =========================
+
+ //set dirty flag
+ protected void setDirtyFlag() {
+ mDirty = true;
+ }
+
+ //clear dirty flag
+ protected void clearDirtyFlag() {
+ mDirty = false;
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSBaseLDAPPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSBaseLDAPPanel.java
new file mode 100644
index 000000000..dbba4a763
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSBaseLDAPPanel.java
@@ -0,0 +1,692 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.*;
+import java.util.*;
+import java.awt.event.*;
+
+/**
+ * LDAP server setting tab
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public abstract class CMSBaseLDAPPanel extends CMSBaseTab implements ItemListener {
+ private static final String SERVER_CERT_NICKNAME = "Server-Cert";
+ private JTextField mHostNameText;
+ private JTextField mPortText;
+ //private JTextField mBaseDNText;
+ private JTextField mBindAsText;
+ private JPasswordField mPasswordText;
+ private JCheckBox mSecurePort;
+ private JCheckBox mEnable;
+ private JCheckBox mEnablePublishing;
+ private JCheckBox mEnableQueue;
+ private Color mActiveColor;
+ private JLabel mHostLabel, mPortLabel, mBindAsLabel, mVersionLabel;
+ protected JLabel mPasswordLabel;
+ protected AdminConnection mAdmin;
+ protected CMSBaseResourceModel mModel;
+ private String mServletName;
+ private CMSTabPanel mParent;
+ private boolean mPublishing = true;
+ private boolean mLDAPPublishing = true;
+ private boolean mPublishingQueue = true;
+ private String mPublishingQueuePriorityLevel = "0";
+ private String mMaxNumberOfPublishingThreads = "3";
+ private String mPublishingQueuePageSize = "40";
+ private String mPublishingQueueStatus = "200";
+ private JLabel mAuthLabel, mCertLabel;
+ private JComboBox mAuthBox, mCertBox;
+ private String mPanelName;
+ private JComboBox mVersionBox;
+ private final static String[] AUTHTYPE = {Constants.PR_BASIC_AUTH,
+ Constants.PR_SSL_AUTH};
+
+ private static final String DELIMITER = ",";
+
+ public CMSBaseLDAPPanel(String panelName, CMSTabPanel parent) {
+ this(panelName, parent, true);
+ mPanelName = panelName;
+ }
+
+ public CMSBaseLDAPPanel(String panelName, CMSTabPanel parent, boolean flag) {
+ super(panelName, parent);
+ mServletName = getServletName(panelName);
+ mModel = parent.getResourceModel();
+ mParent = parent;
+ mPublishing = flag;
+ mPublishingQueue = flag;
+ mLDAPPublishing = flag;
+ }
+
+ public void init() {
+ mAdmin = mModel.getServerInfo().getAdmin();
+ JPanel serverInfo = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mCenterPanel.setLayout(gb);
+
+ mEnablePublishing = makeJCheckBox("ENABLEPUBLISHING");
+ mEnablePublishing.setSelected(true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(DIFFERENT_COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE,
+ 0,
+ DIFFERENT_COMPONENT_SPACE);
+ gb.setConstraints(mEnablePublishing, gbc);
+ mEnablePublishing.addItemListener(this);
+ mCenterPanel.add(mEnablePublishing);
+
+ //add the enable queue
+ mEnableQueue = makeJCheckBox("ENABLEQUEUE");
+ mEnableQueue.setSelected(true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(DIFFERENT_COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE,
+ 0,
+ DIFFERENT_COMPONENT_SPACE);
+ gb.setConstraints(mEnableQueue, gbc);
+ mEnableQueue.addItemListener(this);
+ mCenterPanel.add(mEnableQueue);
+
+ //add the enable checkbox
+ mEnable = makeJCheckBox("ENABLE");
+ mEnable.setSelected(true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(DIFFERENT_COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE,
+ 0,
+ DIFFERENT_COMPONENT_SPACE);
+ gb.setConstraints(mEnable, gbc);
+ mEnable.addItemListener(this);
+ if (mLDAPPublishing)
+ mCenterPanel.add(mEnable);
+
+ //add the destination panel
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(serverInfo, gbc);
+ mCenterPanel.add(serverInfo);
+
+ GridBagLayout gb1 = new GridBagLayout();
+ serverInfo.setLayout(gb1);
+ if (mLDAPPublishing)
+ serverInfo.setBorder(makeTitledBorder("DESTINATION"));
+
+ // add host name label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ mHostLabel = makeJLabel("HOST");
+ mHostNameText = makeJTextField(30);
+ mActiveColor = mHostNameText.getBackground();
+ CMSAdminUtil.addEntryField(serverInfo, mHostLabel, mHostNameText, gbc);
+
+ // add port number label
+ CMSAdminUtil.resetGBC(gbc);
+ mPortLabel = makeJLabel("PORT");
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,0);
+ gb1.setConstraints(mPortLabel, gbc);
+ serverInfo.add(mPortLabel);
+
+ // add port number text field
+ CMSAdminUtil.resetGBC(gbc);
+ mPortText = makeJTextField(10);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 0.0;
+ gb1.setConstraints(mPortText, gbc);
+ serverInfo.add(mPortText);
+
+ // add check box
+ CMSAdminUtil.resetGBC(gbc);
+ mSecurePort = makeJCheckBox("SECUREPORT");
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE - COMPONENT_SPACE,0,COMPONENT_SPACE);
+ gb1.setConstraints(mSecurePort, gbc);
+ serverInfo.add(mSecurePort);
+
+ /* add base DN label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel baseDNLabel = makeJLabel("BASEDN");
+ mBaseDNText = makeJTextField(30);
+ CMSAdminUtil.addEntryField(serverInfo, baseDNLabel, mBaseDNText, gbc);
+ */
+
+ // add bind as label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ mBindAsLabel = makeJLabel("BINDAS");
+ mBindAsText = makeJTextField(30);
+ CMSAdminUtil.addEntryField(serverInfo, mBindAsLabel, mBindAsText, gbc);
+
+ // add password label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ mPasswordLabel = makeJLabel("PWD");
+ mPasswordText = makeJPasswordField(20);
+ CMSAdminUtil.addEntryField(serverInfo, mPasswordLabel, mPasswordText, gbc);
+
+ // add LDAP version
+ CMSAdminUtil.resetGBC(gbc);
+ mVersionLabel = makeJLabel("VERSION");
+ mVersionBox = makeJComboBox("VERSION");
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.addEntryField(serverInfo, mVersionLabel, mVersionBox,
+ dummy, gbc);
+
+ // add cert nickname
+ CMSAdminUtil.resetGBC(gbc);
+ mCertLabel = makeJLabel("CERTLIST");
+ mCertBox = makeJComboBox("CERTLIST");
+ JLabel dummy3 = new JLabel(" ");
+ CMSAdminUtil.addEntryField(serverInfo, mCertLabel, mCertBox, dummy3, gbc);
+
+ // add combo box for authentication type
+ CMSAdminUtil.resetGBC(gbc);
+ mAuthLabel = makeJLabel("AUTHTYPE");
+ mAuthBox = makeJComboBox("AUTHTYPE");
+ mAuthBox.addItemListener(this);
+ JLabel dummy4 = new JLabel(" ");
+ CMSAdminUtil.addEntryField(serverInfo, mAuthLabel, mAuthBox, dummy4, gbc);
+ }
+
+ public void refresh() {
+ mModel.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ if (mPublishing)
+ nvps.put(Constants.PR_PUBLISHING_ENABLE, "");
+ if (mLDAPPublishing)
+ nvps.put(Constants.PR_ENABLE, "");
+ nvps.put(Constants.PR_HOST_NAME, "");
+ nvps.put(Constants.PR_LDAP_PORT, "");
+ nvps.put(Constants.PR_SECURE_PORT_ENABLED, "");
+ //nvps.add(Constants.PR_BASE_DN, "");
+ nvps.put(Constants.PR_BIND_DN, "");
+ nvps.put(Constants.PR_LDAP_VERSION, "");
+ nvps.put(Constants.PR_AUTH_TYPE, "");
+ nvps.put(Constants.PR_CERT_NAMES, "");
+ nvps.put(Constants.PR_LDAP_CLIENT_CERT, "");
+
+ nvps.put(Constants.PR_PUBLISHING_QUEUE_ENABLE, "");
+ nvps.put(Constants.PR_PUBLISHING_QUEUE_THREADS, "");
+ nvps.put(Constants.PR_PUBLISHING_QUEUE_PAGE_SIZE, "");
+ nvps.put(Constants.PR_PUBLISHING_QUEUE_PRIORITY, "");
+ nvps.put(Constants.PR_PUBLISHING_QUEUE_STATUS, "");
+
+ try {
+ NameValuePairs val = mAdmin.read(mServletName,
+ ScopeDef.SC_LDAP, Constants.RS_ID_CONFIG, nvps);
+
+ populate(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+ }
+
+ protected String getServletName(String panelName) {
+ if (panelName.equals("LDAPSETTING"))
+ return DestDef.DEST_SERVER_ADMIN;
+ else if (panelName.equals("CALDAPSETTING"))
+ return DestDef.DEST_CA_PUBLISHER_ADMIN;
+ return DestDef.DEST_RA_PUBLISHER_ADMIN;
+ }
+
+ protected void populate(NameValuePairs nvps) {
+ String clientCert = "";
+ int serverCertIndex = -1;
+
+ String version = "";
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name);
+ if (name.equals(Constants.PR_HOST_NAME)) {
+ mHostNameText.setText(value);
+ } else if (name.equals(Constants.PR_LDAP_PORT)) {
+ mPortText.setText(value);
+ } else if (name.equals(Constants.PR_SECURE_PORT_ENABLED)) {
+ if (value.equals(Constants.TRUE))
+ mSecurePort.setSelected(true);
+ else
+ mSecurePort.setSelected(false);
+ } else if (name.equals(Constants.PR_BIND_DN)) {
+ mBindAsText.setText(value);
+ } else if (name.equals(Constants.PR_PUBLISHING_ENABLE)) {
+ if (value.equals(Constants.TRUE))
+ mEnablePublishing.setSelected(true);
+ else
+ mEnablePublishing.setSelected(false);
+ } else if (name.equals(Constants.PR_PUBLISHING_QUEUE_ENABLE)) {
+ if (value.equals(Constants.TRUE)) {
+ mEnableQueue.setSelected(true);
+ mPublishingQueue = true;
+ } else {
+ mEnableQueue.setSelected(false);
+ mPublishingQueue = false;
+ }
+ } else if (name.equals(Constants.PR_PUBLISHING_QUEUE_THREADS)) {
+ mMaxNumberOfPublishingThreads = value;
+ } else if (name.equals(Constants.PR_PUBLISHING_QUEUE_PAGE_SIZE)) {
+ mPublishingQueuePageSize = value;
+ } else if (name.equals(Constants.PR_PUBLISHING_QUEUE_PRIORITY)) {
+ mPublishingQueuePriorityLevel = value;
+ } else if (name.equals(Constants.PR_PUBLISHING_QUEUE_STATUS)) {
+ mPublishingQueueStatus = value;
+ } else if (name.equals(Constants.PR_ENABLE)) {
+ if (value.equals(Constants.TRUE))
+ mEnable.setSelected(true);
+ else
+ mEnable.setSelected(false);
+ } else if (name.equals(Constants.PR_AUTH_TYPE)) {
+ int index = getIndex(value, AUTHTYPE);
+ if (index >= 0)
+ mAuthBox.setSelectedIndex(index);
+ } else if (name.equals(Constants.PR_CERT_NAMES)) {
+ mCertBox.removeAllItems();
+ String certNames = value;
+ StringTokenizer tokenizer = new StringTokenizer(certNames,
+ DELIMITER);
+ for (int index=0; tokenizer.hasMoreTokens(); index++) {
+ String str = (String)tokenizer.nextToken();
+ if (str.startsWith(SERVER_CERT_NICKNAME))
+ serverCertIndex = index;
+ mCertBox.addItem(str);
+ }
+ } else if (name.equals(Constants.PR_LDAP_CLIENT_CERT)) {
+ clientCert = value;
+ } else if (name.equals(Constants.PR_LDAP_VERSION)) {
+ version = value;
+ }
+ }
+
+ if (version.equals(""))
+ mVersionBox.setSelectedIndex(1);
+ else
+ mVersionBox.setSelectedItem(version);
+
+ if (clientCert.equals("")) {
+ if (serverCertIndex == -1)
+ mCertBox.setSelectedIndex(0);
+ else
+ mCertBox.setSelectedIndex(serverCertIndex);
+ } else
+ mCertBox.setSelectedItem(clientCert.trim());
+
+ if (mEnablePublishing.isSelected())
+ {
+ enableFieldsAndLDAP(true, mActiveColor);
+ }
+ else
+ {
+ enableFieldsAndLDAP(false, getBackground());
+ }
+
+ if (mEnable.isSelected())
+ enableFields(true, mActiveColor);
+ else
+ enableFields(false, getBackground());
+
+ mPasswordText.setText("");
+ }
+
+ private int getIndex(String val, String[] array) {
+ for (int i=0; i<array.length; i++) {
+ if (val.equals(array[i]))
+ return i;
+ }
+ return -1;
+ }
+
+ private void enableFieldsAndLDAP(boolean enable, Color color) {
+ mEnable.setEnabled(enable);
+ mEnableQueue.setEnabled(enable);
+ if (!enable) {
+ mEnable.setSelected(false);
+ mEnableQueue.setSelected(false);
+ mPublishingQueue = false;
+ }
+ enableFields(enable, color);
+ }
+
+ private void enableFields(boolean enable, Color color) {
+ mHostNameText.setEnabled(enable);
+ mHostNameText.setEditable(enable);
+ mHostNameText.setBackground(color);
+ mPortText.setEnabled(enable);
+ mPortText.setEditable(enable);
+ mPortText.setBackground(color);
+ mPasswordText.setEnabled(enable);
+ mPasswordText.setEditable(enable);
+ mPasswordText.setBackground(color);
+ mSecurePort.setEnabled(enable);
+ mHostLabel.setEnabled(enable);
+ mPortLabel.setEnabled(enable);
+ mAuthBox.setEnabled(enable);
+ mAuthLabel.setEnabled(enable);
+ mVersionLabel.setEnabled(enable);
+ mVersionBox.setEnabled(enable);
+ mPasswordLabel.setEnabled(enable);
+ enableAuthFields(enable, color);
+ }
+
+ private void enableAuthFields(boolean enable, Color color) {
+ if (enable) {
+ if (mAuthBox.getSelectedIndex() == 0) {
+ mCertLabel.setEnabled(!enable);
+ mCertBox.setEnabled(!enable);
+ mBindAsText.setEnabled(enable);
+ mBindAsText.setEditable(enable);
+ mBindAsText.setBackground(color);
+ mBindAsLabel.setEnabled(enable);
+ mPasswordText.setEnabled(enable);
+ mPasswordText.setEditable(enable);
+ mPasswordText.setBackground(color);
+ mPasswordLabel.setEnabled(enable);
+ } else {
+ mCertLabel.setEnabled(enable);
+ mCertBox.setEnabled(enable);
+ mBindAsText.setEnabled(!enable);
+ mBindAsText.setEditable(!enable);
+ mBindAsText.setBackground(getBackground());
+ mBindAsLabel.setEnabled(!enable);
+ mPasswordText.setEnabled(!enable);
+ mPasswordText.setEditable(!enable);
+ mPasswordText.setBackground(getBackground());
+ mPasswordLabel.setEnabled(!enable);
+ }
+ } else {
+ mCertLabel.setEnabled(enable);
+ mCertBox.setEnabled(enable);
+ mBindAsText.setEnabled(enable);
+ mBindAsText.setEditable(enable);
+ mBindAsText.setBackground(color);
+ mBindAsLabel.setEnabled(enable);
+ mPasswordText.setEnabled(enable);
+ mPasswordText.setEditable(enable);
+ mPasswordText.setBackground(color);
+ mPasswordLabel.setEnabled(enable);
+ }
+ repaintComp(mHostLabel);
+ repaintComp(mPortLabel);
+ repaintComp(mSecurePort);
+ repaintComp(mBindAsLabel);
+ repaintComp(mCertLabel);
+ repaintComp(mAuthLabel);
+ repaintComp(mVersionLabel);
+ repaintComp(mPasswordText);
+ repaintComp(mPasswordLabel);
+ }
+
+ private void repaintComp(JComponent component) {
+ component.invalidate();
+ component.validate();
+ component.repaint(1);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ super.actionPerformed(e);
+ if (mEnablePublishing.isSelected()) {
+ mEnable.setEnabled(true);
+ mEnableQueue.setEnabled(true);
+ enableFieldsAndLDAP(true, mActiveColor);
+ } else {
+ mEnable.setEnabled(false);
+ mEnableQueue.setEnabled(false);
+ enableFieldsAndLDAP(false, getBackground());
+ }
+ if (mLDAPPublishing) {
+ if (mEnable.isSelected()) {
+ enableFields(true, mActiveColor);
+ } else {
+ enableFields(false, getBackground());
+ }
+ }
+ }
+
+ public void itemStateChanged(ItemEvent e) {
+ super.itemStateChanged(e);
+ if (e.getSource().equals(mAuthBox)) {
+ int index = mAuthBox.getSelectedIndex();
+ if (index == 1) {
+ mSecurePort.setSelected(true);
+ }
+ enableFields(true, mActiveColor);
+ } else if (e.getSource().equals(mEnable)) {
+ if (mEnable.isSelected()) {
+ mEnableQueue.setSelected(true);
+ }
+ enableFields(true, mActiveColor);
+ }
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ // check blank fields
+ NameValuePairs nvps = new NameValuePairs();
+
+ if (mPublishing) {
+ if (mEnablePublishing.isSelected())
+ nvps.put(Constants.PR_PUBLISHING_ENABLE, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_PUBLISHING_ENABLE, Constants.FALSE);
+ }
+
+ if (mLDAPPublishing) {
+ if (mEnable.isSelected())
+ nvps.put(Constants.PR_ENABLE, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_ENABLE, Constants.FALSE);
+ }
+
+ if (mEnableQueue.isSelected())
+ nvps.put(Constants.PR_PUBLISHING_QUEUE_ENABLE, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_PUBLISHING_QUEUE_ENABLE, Constants.FALSE);
+ nvps.put(Constants.PR_PUBLISHING_QUEUE_THREADS, mMaxNumberOfPublishingThreads);
+ nvps.put(Constants.PR_PUBLISHING_QUEUE_PAGE_SIZE, mPublishingQueuePageSize);
+ nvps.put(Constants.PR_PUBLISHING_QUEUE_PRIORITY, mPublishingQueuePriorityLevel);
+ nvps.put(Constants.PR_PUBLISHING_QUEUE_STATUS, mPublishingQueueStatus);
+
+ if (mEnable.isSelected()) {
+ String host = mHostNameText.getText().trim();
+ String port = mPortText.getText().trim();
+ String bindAs = mBindAsText.getText().trim();
+ String passwd = null;
+
+ if (host.equals("") || port.equals("")) {
+ showMessageDialog("BLANKFIELD");
+ return false;
+ }
+
+ try {
+ int num = Integer.parseInt(port);
+ } catch (NumberFormatException e) {
+ showMessageDialog("NUMBERFORMAT");
+ return false;
+ }
+ nvps.put(Constants.PR_HOST_NAME, host);
+ nvps.put(Constants.PR_LDAP_PORT, port);
+
+ if (mSecurePort.isSelected())
+ nvps.put(Constants.PR_SECURE_PORT_ENABLED, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_SECURE_PORT_ENABLED, Constants.FALSE);
+
+ if (mAuthBox.getSelectedIndex() == 0) {
+ if (mPanelName.equals("CALDAPSETTING")) {
+ nvps.put(Constants.PR_BINDPWD_PROMPT, "CA LDAP Publishing");
+ } else {
+ nvps.put(Constants.PR_BINDPWD_PROMPT, "RA LDAP Publishing");
+ }
+ nvps.put(Constants.PR_BIND_DN, bindAs);
+ passwd = mPasswordText.getText();
+
+ if (passwd.equals("")) {
+ showMessageDialog("EMPTYPASSWD");
+ return false;
+ }
+
+ nvps.put(Constants.PR_DIRECTORY_MANAGER_PWD, passwd);
+ } else {
+ nvps.put(Constants.PR_LDAP_CLIENT_CERT,
+ (String) (mCertBox.getSelectedItem()));
+ }
+
+ int index = mAuthBox.getSelectedIndex();
+ if (index == 1) {
+ if (!mSecurePort.isSelected()) {
+ showMessageDialog("SSLERROR");
+ return false;
+ }
+ }
+ nvps.put(Constants.PR_AUTH_TYPE, AUTHTYPE[index]);
+ nvps.put(Constants.PR_LDAP_VERSION,
+ (String) mVersionBox.getSelectedItem());
+
+ // test the connection before save
+ /*
+ LDAPConnection conn = null;
+ if (mAuthBox.getSelectedIndex() == 1) {
+ try {
+ conn = new LDAPConnection(new LdapJssSSLSocketFactory(
+ (String)(mCertBox.getSelectedItem())));
+ showMessageDialog("SSLOK");
+ } catch (LDAPException e ) {
+ showMessageDialog("SSLERROR");
+ }
+ try {
+ conn.connect((String)mVersionBox.getSelectedItem(),
+ host, port, null, null);
+ } catch (LDAPException e ) {
+ showMessageDialog("SSLERROR");
+ }
+ } else {
+ try {
+ if (mSecurePort.isSelected()) {
+ conn = new LDAPConnection(new
+ LdapJssSSLSocketFactory());
+ } else {
+ conn = new LDAPConnection();
+ }
+ showMessageDialog("SSLOK");
+ } catch (LDAPException e ) {
+ showMessageDialog("SSLERROR");
+ }
+ try {
+ conn.connect(host, port);
+ showMessageDialog("SSLOK");
+ } catch (LDAPException e ) {
+ showMessageDialog("SSLERROR");
+ }
+ try {
+ conn.authenticate((String)mVersionBox.getSelectedItem(),
+ bindAs, passwd);
+ showMessageDialog("SSLOK");
+ } catch (LDAPException e ) {
+ showMessageDialog("SSLERROR");
+ }
+ }
+ */
+
+ }
+
+ mModel.progressStart();
+ try {
+ NameValuePairs nvps1 = mAdmin.process(mServletName, ScopeDef.SC_LDAP,
+ Constants.RS_ID_CONFIG, nvps, false);
+ // show test report
+ String report = "";
+ for (String value : nvps1.values()) {
+ report = report + value + "\n";
+ }
+ if (report.indexOf("Fail") == -1) {
+ JOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(),
+ CMSAdminUtil.wrapText(report,80),
+ "Configuration Successful",
+ JOptionPane.INFORMATION_MESSAGE,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_INFO_ICON));
+ clearDirtyFlag();
+ } else {
+ int i = JOptionPane.showConfirmDialog(
+ UtilConsoleGlobals.getActivatedFrame(),
+ CMSAdminUtil.wrapText(report,80),
+ "Configuration Error", JOptionPane.YES_NO_OPTION,
+ JOptionPane.ERROR_MESSAGE,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_ERROR_ICON));
+ if (i == JOptionPane.YES_OPTION) {
+ mAdmin.modify(mServletName, ScopeDef.SC_LDAP,
+ Constants.RS_ID_CONFIG, nvps, false);
+ clearDirtyFlag();
+ } else {
+ nvps.put(Constants.PR_ENABLE, "false");
+ mAdmin.modify(mServletName, ScopeDef.SC_LDAP,
+ Constants.RS_ID_CONFIG, nvps, false);
+ }
+ }
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ return false;
+ }
+
+ mModel.progressStop();
+ //clearDirtyFlag();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSBaseLogPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSBaseLogPanel.java
new file mode 100644
index 000000000..c0437cbc4
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSBaseLogPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.connection.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+
+/**
+ * Base Log Panel
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public abstract class CMSBaseLogPanel extends CMSBaseTab {
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ protected JCheckBox activateLog;
+
+ protected JComboBox mlogFQC, mLogLevel, mNTLogLevel;
+ protected JTextField mlogMaxSizText, mlogBufSizText, mEventSourceText;
+ protected Color mActiveColor;
+
+ protected Object mselectedItem;
+ protected String mlogMaxSizTextData, mlogBufSizTextData;
+ protected CMSBaseResourceModel mModel;
+ protected AdminConnection mAdmin;
+ protected int mLevel, mNTLevel;
+ protected int mFrequency;
+ protected String mSource;
+
+ protected JLabel mMaxLabel, mNTLogLevelLbl;
+ protected JLabel mBufferLabel, mEventSourceLbl;
+ protected JCheckBox mActivateNTLog;
+ protected boolean mIsNT;
+
+ protected final static int YEAR = 31536000;
+ protected final static int MONTH = 2592000;
+ protected final static int WEEK = 604800;
+ protected final static int DAY = 86400;
+ protected final static int HOUR = 3600;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSBaseLogPanel(String panelName, CMSTabPanel parent) {
+ super(panelName, parent);
+ mModel = parent.getResourceModel();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Actual Instantiation of the UI components
+ */
+ public void init() {
+ mAdmin = mModel.getServerInfo().getAdmin();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ CMSAdminUtil.resetGBC(gbc);
+ mCenterPanel.setLayout(gb);
+
+ //=== Activate Radio Button ===
+ activateLog = makeJCheckBox("ACTIVATE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0, COMPONENT_SPACE);
+ gb.setConstraints(activateLog, gbc);
+ mCenterPanel.add(activateLog);
+
+ // use a lined border later...titled for now
+ JPanel logInfo = new JPanel();
+ GridBagLayout gb1 = new GridBagLayout();
+ logInfo.setLayout(gb1);
+ logInfo.setBorder(makeTitledBorder("LOGATTRIBUTE"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ if (!mIsNT)
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(logInfo, gbc);
+ mCenterPanel.add(logInfo);
+
+ // Log Rotation Frequency
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel logFQC = makeJLabel("LOGFQC");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 0.0;
+ gbc.weighty = 0.0;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0, COMPONENT_SPACE);
+ logInfo.add(logFQC, gbc);
+
+ mlogFQC = makeJComboBox("LOGFQC");
+ gbc.anchor = gbc.WEST;
+ logInfo.add(mlogFQC, gbc);
+
+ JLabel dummyFQC = new JLabel();
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ logInfo.add(dummyFQC, gbc);
+
+ // Log File Maximum Size
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel logMaxSiz = makeJLabel("LOGMAXSIZ");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.weightx = 0.0;
+ gbc.weighty = 0.0;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0, COMPONENT_SPACE);
+ logInfo.add(logMaxSiz, gbc);
+
+ mlogMaxSizText = makeJTextField(10);
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 0.007;
+ gbc.fill = gbc.HORIZONTAL;
+ logInfo.add(mlogMaxSizText, gbc);
+ mActiveColor = mlogMaxSizText.getBackground();
+
+ mMaxLabel = makeJLabel("SIZEUNIT");
+ gbc.weightx = 0.0;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0, COMPONENT_SPACE);
+ logInfo.add(mMaxLabel, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.fill = gbc.HORIZONTAL;
+ logInfo.add(dummy, gbc);
+
+ // Log File Buffer Size
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel logBufSiz = makeJLabel("LOGBUFSIZ");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.weightx = 0.0;
+ gbc.weighty = 0.0;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0, COMPONENT_SPACE);
+ logInfo.add(logBufSiz, gbc);
+
+ mlogBufSizText = makeJTextField(10);
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 0.007;
+ gbc.fill = gbc.HORIZONTAL;
+ logInfo.add(mlogBufSizText, gbc);
+
+ mBufferLabel = makeJLabel("SIZEUNIT");
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0, COMPONENT_SPACE);
+ gbc.weightx = 0.0;
+ gbc.fill = gbc.NONE;
+ logInfo.add(mBufferLabel, gbc);
+
+ JLabel dummy1 = new JLabel(" ");
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.fill = gbc.HORIZONTAL;
+ logInfo.add(dummy1, gbc);
+
+ // Log Level
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel logLevel = makeJLabel("LOGLEVEL");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.weightx = 0.0;
+ gbc.weighty = 0.0;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0, COMPONENT_SPACE);
+ logInfo.add(logLevel, gbc);
+
+ mLogLevel = makeJComboBox("LOGLEVEL");
+ gbc.anchor = gbc.WEST;
+ logInfo.add(mLogLevel, gbc);
+
+ JLabel dummy2 = new JLabel(" ");
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.fill = gbc.HORIZONTAL;
+ logInfo.add(dummy2, gbc);
+
+ if (mIsNT)
+ addNTEventLog();
+ }
+
+ private void addNTEventLog() {
+ GridBagConstraints gbc = new GridBagConstraints();
+ CMSAdminUtil.resetGBC(gbc);
+ mActivateNTLog = makeJCheckBox("ACTIVATENTLOG");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, 0, COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ mCenterPanel.add(mActivateNTLog, gbc);
+
+ JPanel NTLogInfo = new JPanel();
+ GridBagLayout gb1 = new GridBagLayout();
+ NTLogInfo.setLayout(gb1);
+ NTLogInfo.setBorder(makeTitledBorder("NTLOGATTRIBUTE"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ mCenterPanel.add(NTLogInfo, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEventSourceLbl = makeJLabel("EVENTSOURCE");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.weightx = 0.0;
+ gbc.weighty = 0.0;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0, COMPONENT_SPACE);
+ NTLogInfo.add(mEventSourceLbl, gbc);
+
+ mEventSourceText = makeJTextField(10);
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 0.007;
+ gbc.fill = gbc.HORIZONTAL;
+ NTLogInfo.add(mEventSourceText, gbc);
+
+ JLabel dummy1 = new JLabel(" ");
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.fill = gbc.HORIZONTAL;
+ NTLogInfo.add(dummy1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mNTLogLevelLbl = makeJLabel("LOGLEVEL");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.weightx = 0.0;
+ gbc.weighty = 0.0;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0, COMPONENT_SPACE);
+ NTLogInfo.add(mNTLogLevelLbl, gbc);
+
+ mNTLogLevel = makeJComboBox("LOGLEVEL");
+ gbc.anchor = gbc.WEST;
+ NTLogInfo.add(mNTLogLevel, gbc);
+
+ JLabel dummy2 = new JLabel(" ");
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.fill = gbc.HORIZONTAL;
+ NTLogInfo.add(dummy2, gbc);
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ //enable/disable section
+ protected void setSection(boolean flag) {
+ mlogFQC.setEnabled(flag);
+ mLogLevel.setEnabled(flag);
+ mlogMaxSizText.setEditable(flag);
+ mlogBufSizText.setEditable(flag);
+ if (flag) {
+ mlogFQC.setBackground(mActiveColor);
+ mLogLevel.setBackground(mActiveColor);
+ mlogMaxSizText.setBackground(mActiveColor);
+ mlogBufSizText.setBackground(mActiveColor);
+ } else {
+ mLogLevel.setBackground(getBackground());
+ mlogFQC.setBackground(getBackground());
+ mlogMaxSizText.setBackground(getBackground());
+ mlogBufSizText.setBackground(getBackground());
+ }
+ mlogFQC.repaint();
+ mlogMaxSizText.repaint();
+ mlogBufSizText.repaint();
+ }
+
+ protected void setNTSection(boolean flag, Color color) {
+ mNTLogLevel.setEnabled(flag);
+ mEventSourceText.setEnabled(flag);
+ mEventSourceText.setEditable(flag);
+ mEventSourceText.setBackground(color);
+ CMSAdminUtil.repaintComp(mNTLogLevel);
+ CMSAdminUtil.repaintComp(mEventSourceText);
+ }
+
+ //update component data
+ protected void setValues() {
+ if (activateLog.isSelected()) {
+ setSection(true);
+ } else {
+ setSection(false);
+ }
+ mlogFQC.setSelectedIndex(mFrequency);
+ mlogMaxSizText.setText(mlogMaxSizTextData);
+ mlogBufSizText.setText(mlogBufSizTextData);
+ mLogLevel.setSelectedIndex(mLevel);
+
+ if (mIsNT) {
+ if (mActivateNTLog.isSelected()) {
+ setNTSection(true, mActiveColor);
+ } else {
+ setNTSection(false, getBackground());
+ }
+ mEventSourceText.setText(mSource);
+ mNTLogLevel.setSelectedIndex(mNTLevel);
+ }
+ }
+
+ protected int getRollOverTime(int index) {
+ if (index == 0)
+ return HOUR;
+ else if (index == 1)
+ return DAY;
+ else if (index == 2)
+ return WEEK;
+ else if (index == 3)
+ return MONTH;
+ return YEAR;
+ }
+
+ protected int getRollOverIndex(int val) {
+ if (val >= YEAR)
+ return 4;
+ else if (val >= MONTH)
+ return 3;
+ else if (val >= WEEK)
+ return 2;
+ else if (val >= DAY)
+ return 1;
+ return 0;
+ }
+
+ /*==========================================================
+ * EVENT HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ super.actionPerformed(e);
+ if (e.getSource().equals(activateLog) ||
+ e.getSource().equals(mActivateNTLog)) {
+ setValues();
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSBaseTab.java b/base/console/src/com/netscape/admin/certsrv/config/CMSBaseTab.java
new file mode 100644
index 000000000..c3c707f68
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSBaseTab.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.border.*;
+import javax.swing.text.*;
+import java.util.*;
+import java.awt.*;
+import java.awt.event.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Netscape Certificate Server 4.0 Deafult Base TAB
+ * This class is the base class for all the TAB panels.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public abstract class CMSBaseTab extends CMSBaseConfigPanel
+ implements IRefreshTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ protected CMSTabPanel mParent;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSBaseTab(String panelName, CMSTabPanel parent) {
+ super(panelName);
+ mParent = parent;
+ add("Center", mCenterPanel);
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+
+ //set dirty flag
+ protected void setDirtyFlag() {
+ super.setDirtyFlag();
+ mParent.setDirtyTab(this);
+ }
+
+ //clear dirty flag
+ protected void clearDirtyFlag() {
+ super.clearDirtyFlag();
+ mParent.clearDirtyTab(this);
+ }
+
+ //=== OVERWRITE DIALOG MESSAGE =====================
+
+ protected void showMessageDialog(String keyword, int messageType ) {
+ CMSAdminUtil.showMessageDialog(mParent.mModel.getFrame(), mResource, mPanelName, keyword, messageType);
+ }
+
+ protected void showMessageDialog(String keyword) {
+ showMessageDialog(keyword, ERROR_MESSAGE);
+ }
+
+ protected int showConfirmDialog(String keyword, int messageType ) {
+ return CMSAdminUtil.showConfirmDialog(mParent.mModel.getFrame(), mResource, mPanelName, keyword, messageType);
+ }
+
+ protected int showConfirmDialog(String keyword) {
+ return showConfirmDialog(keyword, WARNING_MESSAGE);
+ }
+
+ protected void showErrorDialog(String message) {
+ CMSAdminUtil.showErrorDialog(mParent.mModel.getFrame(), mResource, message, ERROR_MESSAGE);
+ }
+
+ public void refresh() {
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSBlankPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSBlankPanel.java
new file mode 100644
index 000000000..b3f357564
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSBlankPanel.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.admin.certsrv.config;
+
+import com.netscape.management.client.*;
+import com.netscape.admin.certsrv.*;
+
+/**
+ * Blank Panel to be displayed at the right hand side
+ * we should place some ads here... =-)
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class CMSBlankPanel extends CMSBaseTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static String PANEL_NAME = "CMSBLANKPANEL";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSBlankPanel(ResourceModel model) {
+ super(PANEL_NAME, null);
+ }
+
+ public CMSBlankPanel(ResourceModel model, CMSTabPanel parent, String name) {
+ super(PANEL_NAME, parent);
+ setTitle(name);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Actual Instanciation of the UI components
+ */
+ public void init() {
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ return true;
+ }
+
+ /**
+ * Implementation for calling help
+ */
+ public void helpCallback() {
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSCACertSettingPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSCACertSettingPanel.java
new file mode 100644
index 000000000..76aa59511
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSCACertSettingPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+
+import java.awt.event.*;
+
+/**
+ * CA Certificate Setting
+ *
+ * @author Christine Ho
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class CMSCACertSettingPanel extends CMSCertSettingPanel {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static String PANEL_NAME = "CACERTSETTING";
+ private PanelMapperConfigDialog mDialog = null;
+ private CMSTabPanel mParent;
+ private static final String HELPINDEX =
+ "configuration-ca-ldappublish-cacert-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSCACertSettingPanel(CMSTabPanel parent) {
+ super(PANEL_NAME, parent);
+ mParent = parent;
+ mHelpToken = HELPINDEX;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Actual UI construction
+ */
+ public void init() {
+ super.init();
+
+ //XXX B1 - disable the publisher configuration
+ mPublisher.setEnabled(false);
+ //XXX B1 - disable the publisher configuration
+
+ refresh();
+ }
+
+ public void refresh() {
+ _model.progressStart();
+ NameValuePairs nvp = new NameValuePairs();
+ nvp.put(Constants.PR_MAPPER, "");
+ nvp.put(Constants.PR_PUBLISHER, "");
+
+ try {
+ NameValuePairs val = _admin.read(DestDef.DEST_CA_ADMIN,
+ ScopeDef.SC_CACERT, Constants.RS_ID_CONFIG, nvp);
+
+ populate(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ _model.progressStop();
+ }
+ _model.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+ }
+
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ clearDirtyFlag();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mMapper)) {
+ Debug.println("Edit Mapper Config");
+ mDialog = new PanelMapperConfigDialog(_model.getFrame(), _admin);
+ mDialog.showDialog(_mapper.getText(),
+ DestDef.DEST_CA_ADMIN, ScopeDef.SC_CACERT);
+ if (!mDialog.isOK())
+ return;
+ refresh();
+ } else if (e.getSource().equals(mPublisher)) {
+ //Debug.println("Edit Publisher Config");
+ }
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ /* get config parameters associated with each mapper
+ private NameValueParis getConfig() throws EAdminException {
+
+ NameValuePairs response = _admin.read(DestDef.DEST_CA_ADMIN,
+ ScopeDef.SC_CAMAPPER, _mapper.getText()],
+ new NameValuePairs());
+ return response;
+ }
+ */
+
+ /*send configuration to server
+ private void sendConfig(NameValuePairs response) {
+
+ response.add(Constants.PR_MAPPER, MAPPER[_mapper.getSelectedIndex()]);
+ _model.progressStart();
+ try {
+ _admin.modify(DestDef.DEST_CA_ADMIN,
+ ScopeDef.SC_CACERT, Constants.RS_ID_CONFIG, response);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ _model.progressStop();
+ return false;
+ }
+ _model.progressStop();
+
+ }
+ */
+
+ private void populate(NameValuePairs nvps) {
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name);
+ if (name.equals(Constants.PR_MAPPER)) {
+ _mapper.setText(value);
+ } else if (name.equals(Constants.PR_PUBLISHER)) {
+ _publisher.setText(value);
+ }
+ }
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSCAConnectorPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSCAConnectorPanel.java
new file mode 100644
index 000000000..1af02a881
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSCAConnectorPanel.java
@@ -0,0 +1,237 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * CA Connector Panel
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class CMSCAConnectorPanel extends CMSBaseTab
+ implements MouseListener
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+
+ private final static String PANEL_NAME = "CACONNECTOR";
+ private final static String HELPINDEX = "configuration-ca-connector-help";
+
+ private AdminConnection mAdmin;
+ private CMSBaseResourceModel mModel;
+ private CMSTabPanel mParent;
+ private JList mList;
+ private DefaultListModel mDataModel;
+ private JScrollPane mScrollPane;
+ private JButton mEdit;
+ protected boolean mInit = false;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSCAConnectorPanel(CMSBaseResourceModel model, CMSTabPanel parent) {
+ super(PANEL_NAME, parent);
+ mModel = model;
+ mParent = parent;
+ mDataModel = new DefaultListModel();
+ mHelpToken = HELPINDEX;
+
+ // hardcoded just for beta 1
+ mDataModel.addElement("Data Recovery Manager Connector");
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * initialize the UI components
+ */
+ public void init() {
+// setLayout(new BorderLayout());
+
+ // JPanel mainPanel = new JPanel();
+ JPanel mainPanel = mCenterPanel;
+
+
+ Debug.println("ConnectorPanel: init()");
+ mAdmin = mModel.getServerInfo().getAdmin();
+
+ GridBagLayout gb1 = new GridBagLayout();
+ mainPanel.setLayout(gb1);
+
+ GridBagConstraints gbc = new GridBagConstraints();
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel listLabel = makeJLabel("CONNLIST");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(DIFFERENT_COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,
+ 0,DIFFERENT_COMPONENT_SPACE);
+ gb1.setConstraints(listLabel, gbc);
+ mainPanel.add(listLabel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mList = makeJList(mDataModel, 3);
+ mScrollPane = new JScrollPane(mList,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mList.addMouseListener(this);
+ mScrollPane.setBackground(Color.white);
+ mScrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 0.5;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,
+ 0,DIFFERENT_COMPONENT_SPACE);
+ gb1.setConstraints(mScrollPane, gbc);
+ mainPanel.add(mScrollPane);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEdit = makeJButton("EDIT");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ gbc.weightx = 0.5;
+ gbc.insets = new Insets(COMPONENT_SPACE,0,
+ 0,DIFFERENT_COMPONENT_SPACE);
+ gb1.setConstraints(mEdit, gbc);
+ mainPanel.add(mEdit);
+
+ // add("Center",mainPanel);
+ refresh();
+ }
+
+ /**
+ * refresh the panel data
+ */
+ public void refresh() {
+ repaint(1);
+ }
+
+ /*==========================================================
+ * Event Handler
+ *==========================================================*/
+
+ //======= ActionLister ============================
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mEdit)) {
+ JFrame frame = mModel.getFrame();
+ String name = (String)mList.getSelectedValue();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_ID, "");
+ nvps.put(Constants.PR_HOST, "");
+ nvps.put(Constants.PR_PORT, "");
+ // Inserted by beomsuk
+ nvps.put(Constants.PR_TIMEOUT, "");
+ // Insert end
+ nvps.put(Constants.PR_URI, "");
+ nvps.put(Constants.PR_LOCAL, "");
+ nvps.put(Constants.PR_ENABLE, "");
+
+ try {
+ NameValuePairs values = mAdmin.read(DestDef.DEST_CA_ADMIN,
+ ScopeDef.SC_CONNECTOR, name, nvps);
+ NameValuePairs subsystems = mAdmin.search(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_SUBSYSTEM, new NameValuePairs());
+
+ boolean colocated = false;
+ if (name.equals("Data Recovery Manager Connector")) {
+ String val = values.get("id");
+ if (val != null && val.equals("kra"))
+ colocated = true;
+ }
+
+ ConnectorEditor editor = new ConnectorEditor(mAdmin,
+ mModel.getFrame(), name, DestDef.DEST_CA_ADMIN,
+ mModel.getServerInfo().getServerId(), colocated);
+ editor.showDialog(values);
+ } catch (EAdminException ex) {
+ showErrorDialog(ex.toString());
+ }
+/*
+ NameValuePairs values = new NameValuePairs();
+ ConnectorEditor editor = new ConnectorEditor(mAdmin,
+ mModel.getFrame(), name);
+ editor.showDialog(values);
+*/
+ }
+ }
+
+ //=== MOUSELISTENER ========================
+ public void mouseClicked(MouseEvent e) {
+ if (e.getSource() == mList) {
+ if (mList.getSelectedIndex() < 0)
+ mEdit.setEnabled(false);
+ else
+ mEdit.setEnabled(true);
+ }
+ }
+
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {}
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {}
+
+ //======== CMSBaseConfigPanel ==============
+ public boolean applyCallback() {
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ //update the UI component using the data retrieved
+ private void populate(NameValuePairs nvps) {
+/*
+ Enumeration names = nvps.getNames();
+ mDataModel.removeAllElements();
+ while (names.hasMoreElements())
+ mDataModel.addElement(names.nextElement());
+
+ if (mDataModel.size() > 0) {
+ mList.setSelectedIndex(0);
+ mEdit.setEnabled(true);
+ } else
+ mEdit.setEnabled(false);
+*/
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSCAGeneralPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSCAGeneralPanel.java
new file mode 100644
index 000000000..6f809316a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSCAGeneralPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.math.*;
+
+/**
+ * RA General Setting
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class CMSCAGeneralPanel extends CMSBaseTab implements ItemListener {
+
+ private static String PANEL_NAME = "CAGENERAL";
+ private static CMSBaseResourceModel mModel;
+ protected AdminConnection mAdmin;
+ private JCheckBox mRAEnable;
+ private JCheckBox mEEEnable;
+ private JCheckBox mOCSPEnable;
+ private CMSTabPanel mParent;
+ private JComboBox mGroups;
+ private JComboBox mAlgorithms;
+ private JTextField mSerialNumber;
+ private JTextField mMaxSerialNumber;
+ private JCheckBox mValidity;
+ private Vector mGroupData;
+ private static final String HELPINDEX =
+ "configuration-ca-general-help";
+
+ public CMSCAGeneralPanel(CMSTabPanel parent) {
+ super(PANEL_NAME, parent);
+ mModel = parent.getResourceModel();
+ mParent = parent;
+ mHelpToken = HELPINDEX;
+ }
+
+ public void init() {
+ Debug.println("CMSCAGeneral: init()");
+ mAdmin = mModel.getServerInfo().getAdmin();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ CMSAdminUtil.resetGBC(gbc);
+ mCenterPanel.setLayout(gb);
+
+ JPanel adminPanel = new JPanel();
+ GridBagLayout gb1 = new GridBagLayout();
+ adminPanel.setLayout(gb1);
+ adminPanel.setBorder(makeTitledBorder("INTERACTION"));
+
+ JPanel signingPanel = new JPanel();
+ GridBagLayout gb2 = new GridBagLayout();
+ signingPanel.setLayout(gb2);
+ signingPanel.setBorder(makeTitledBorder("SIGNING"));
+
+ JPanel serialPanel = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ serialPanel.setLayout(gb3);
+ serialPanel.setBorder(makeTitledBorder("SERIAL"));
+
+ JPanel validityPanel = new JPanel();
+ GridBagLayout gb4 = new GridBagLayout();
+ validityPanel.setLayout(gb4);
+ validityPanel.setBorder(makeTitledBorder("VALIDITY"));
+
+ CMSAdminUtil.resetGBC(gbc);
+ mCenterPanel.setLayout(gb);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ //gbc.weighty = 1.0;
+ gb.setConstraints(adminPanel, gbc);
+ // mCenterPanel.add(adminPanel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(validityPanel, gbc);
+ mCenterPanel.add(validityPanel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(serialPanel, gbc);
+ mCenterPanel.add(serialPanel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(signingPanel, gbc);
+ mCenterPanel.add(signingPanel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEEEnable = makeJCheckBox("EE");
+ gbc.anchor = gbc.NORTHWEST;
+ // gbc.gridwidth = gbc.REMAINDER;
+ // gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb1.setConstraints(mEEEnable, gbc);
+ adminPanel.add(mEEEnable);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mOCSPEnable = makeJCheckBox("OCSP");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb1.setConstraints(mOCSPEnable, gbc);
+ adminPanel.add(mOCSPEnable);
+
+ // add validity block
+ CMSAdminUtil.resetGBC(gbc);
+ mValidity = makeJCheckBox("VALIDITY");
+ gbc.anchor = gbc.CENTER;
+ //gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ //gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb4.setConstraints(mValidity, gbc);
+ validityPanel.add(mValidity);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel dummy4 = new JLabel(" ");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb4.setConstraints(dummy4, gbc);
+ validityPanel.add(dummy4);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel signingLabel = makeJLabel("ALGORITHM");
+ gbc.anchor = gbc.CENTER;
+ gb2.setConstraints(signingLabel, gbc);
+ gbc.weighty = 1.0;
+ signingPanel.add(signingLabel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mAlgorithms = new JComboBox();
+ mAlgorithms.addItemListener(this);
+ //mAlgorithms = makeJComboBox("ALGORITHM");
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ //gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb2.setConstraints(mAlgorithms, gbc);
+ signingPanel.add(mAlgorithms);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel dummy1 = new JLabel(" ");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb2.setConstraints(dummy1, gbc);
+ signingPanel.add(dummy1);
+
+ // add serial number block
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel serialLabel = makeJLabel("SERIAL");
+ gbc.anchor = gbc.CENTER;
+ gb3.setConstraints(serialLabel, gbc);
+ gbc.weighty = 1.0;
+ //gbc.insets = new Insets(COMPONENT_SPACE,0,COMPONENT_SPACE,0);
+ serialPanel.add(serialLabel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mSerialNumber = makeJTextField(17);
+ mSerialNumber.setEnabled(false);
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ //gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb3.setConstraints(mSerialNumber, gbc);
+ serialPanel.add(mSerialNumber);
+
+ // add end serial number block
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel maxSerialLabel = makeJLabel("MAXSERIAL");
+ gbc.anchor = gbc.EAST;
+ //gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.gridx = 0;
+ gb3.setConstraints(maxSerialLabel, gbc);
+ //gbc.weighty = 1.0;
+ serialPanel.add(maxSerialLabel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mMaxSerialNumber = makeJTextField(17);
+ mMaxSerialNumber.setEnabled(false);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridy = 1;
+ //gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ //gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb3.setConstraints(mMaxSerialNumber, gbc);
+ serialPanel.add(mMaxSerialNumber);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel dummy2 = new JLabel(" ");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb3.setConstraints(dummy2, gbc);
+ serialPanel.add(dummy2);
+
+ refresh();
+ }
+
+ public void refresh() {
+ mModel.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_EE_ENABLED, "");
+ //nvps.add(Constants.PR_RA_ENABLED, "");
+ nvps.put(Constants.PR_DEFAULT_ALGORITHM, "");
+ nvps.put(Constants.PR_ALL_ALGORITHMS, "");
+ nvps.put(Constants.PR_SERIAL, "");
+ nvps.put(Constants.PR_MAXSERIAL, "");
+ nvps.put(Constants.PR_VALIDITY, "");
+
+ try {
+ NameValuePairs val = mAdmin.read(DestDef.DEST_CA_ADMIN,
+ ScopeDef.SC_GENERAL, Constants.RS_ID_CONFIG, nvps);
+
+ populate(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ }
+
+ protected void populate(NameValuePairs nvps) {
+ String defaultAlgorithm = "";
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name);
+ if (name.equals(Constants.PR_EE_ENABLED)) {
+ mEEEnable.setSelected(getBoolean(value));
+ } else if (name.equals(Constants.PR_OCSP_ENABLED)) {
+ mOCSPEnable.setSelected(getBoolean(value));
+/*
+ } else if (name.equals(Constants.PR_RA_ENABLED)) {
+ mRAEnable.setSelected(getBoolean(nvp.getValue()));
+*/
+ } else if (name.equals(Constants.PR_VALIDITY)) {
+ mValidity.setSelected(getBoolean(value));
+ } else if (name.equals(Constants.PR_DEFAULT_ALGORITHM)) {
+ defaultAlgorithm = value;
+ } else if (name.equals(Constants.PR_ALL_ALGORITHMS)) {
+ initAlgorithmBox(value);
+ } else if (name.equals(Constants.PR_SERIAL)) {
+ String serial = value;
+ if (!serial.equals(""))
+ mSerialNumber.setText(serial);
+ else
+ mSerialNumber.setText("All serial numbers are used");
+ } else if (name.equals(Constants.PR_MAXSERIAL)) {
+ String serial = value;
+ if (!serial.equals(""))
+ mMaxSerialNumber.setText(serial);
+ }
+ }
+
+ mAlgorithms.setSelectedItem(defaultAlgorithm);
+ }
+
+ private void initAlgorithmBox(String val) {
+ if (mAlgorithms.getItemCount() >= 0) {
+ mAlgorithms.removeAllItems();
+ }
+ StringTokenizer tokenizer = new StringTokenizer(val, ":");
+ while (tokenizer.hasMoreTokens()) {
+ mAlgorithms.addItem(tokenizer.nextToken());
+ }
+ }
+
+ private boolean getBoolean(String str) {
+ if (str.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ super.actionPerformed(e);
+ }
+
+ private String hexToDecimal(String hex)
+ {
+ //String newHex = hex.substring(2);
+ BigInteger bi = new BigInteger(hex, 16);
+ return bi.toString();
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ NameValuePairs nvps = new NameValuePairs();
+
+ if (mEEEnable.isSelected())
+ nvps.put(Constants.PR_EE_ENABLED, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_EE_ENABLED, Constants.FALSE);
+
+ if (mOCSPEnable.isSelected())
+ nvps.put(Constants.PR_OCSP_ENABLED, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_OCSP_ENABLED, Constants.FALSE);
+
+/*
+ if (mRAEnable.isSelected())
+ nvps.add(Constants.PR_RA_ENABLED, Constants.TRUE);
+ else
+ nvps.add(Constants.PR_RA_ENABLED, Constants.FALSE);
+*/
+
+ if (mValidity.isSelected())
+ nvps.put(Constants.PR_VALIDITY, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_VALIDITY, Constants.FALSE);
+
+ nvps.put(Constants.PR_DEFAULT_ALGORITHM,
+ (String) mAlgorithms.getSelectedItem());
+
+ String serial = (String)mSerialNumber.getText().trim();
+ try {
+ //if (serial.startsWith("0x")) {
+ serial = hexToDecimal(serial);
+ //}
+ BigInteger num = new BigInteger(serial);
+ if (num.compareTo(new BigInteger("0")) < 0) {
+ showMessageDialog("OUTOFRANGE");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ showMessageDialog("NUMBERFORMAT");
+ return false;
+ }
+// nvps.add(Constants.PR_SERIAL, serial);
+
+ String maxserial =
+ (String)mMaxSerialNumber.getText().trim();
+ if (maxserial != null && !maxserial.equals("")) {
+ try {
+ //if (serial.startsWith("0x")) {
+ String maxserialdec = hexToDecimal(maxserial);
+ //}
+ BigInteger num = new BigInteger(maxserialdec);
+ if (num.compareTo(new BigInteger("0")) < 0) {
+ showMessageDialog("OUTOFRANGE");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ showMessageDialog("NUMBERFORMAT");
+ return false;
+ }
+// nvps.add(Constants.PR_MAXSERIAL, maxserial);
+ }
+
+ mModel.progressStart();
+ try {
+ mAdmin.modify(DestDef.DEST_CA_ADMIN,
+ ScopeDef.SC_GENERAL, Constants.RS_ID_CONFIG, nvps);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ return false;
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSCALDAPPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSCALDAPPanel.java
new file mode 100644
index 000000000..735818834
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSCALDAPPanel.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.admin.certsrv.config;
+
+import com.netscape.management.client.util.*;
+
+/**
+ * LDAP server setting tab
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class CMSCALDAPPanel extends CMSBaseLDAPPanel {
+
+ private static String PANEL_NAME = "CALDAPSETTING";
+ private static final String HELPINDEX =
+ "configuration-ca-ldappublish-destination-help";
+
+ public CMSCALDAPPanel(CMSTabPanel parent) {
+ super(PANEL_NAME, parent);
+ mHelpToken = HELPINDEX;
+ }
+
+ public void init() {
+ super.init();
+ refresh();
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSCRLCachePanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSCRLCachePanel.java
new file mode 100644
index 000000000..51da9c58c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSCRLCachePanel.java
@@ -0,0 +1,371 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * Panel Setting CRL Cache
+ *
+ * @author Andrew Wnuk
+ * @version $Revision$, $Date$
+ */
+public class CMSCRLCachePanel extends CMSBaseTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static String PANEL_NAME = "CRLCACHE";
+
+ private JCheckBox mEnableCache;
+
+ private JLabel mCacheFreqLabel;
+ private JTextField mCacheFreq;
+ private JLabel mCacheFreqMinLabel;
+
+ private JLabel mEnableCacheRecoveryLabel;
+ private JCheckBox mEnableCacheRecovery;
+
+ private JLabel mEnableCacheTestingLabel;
+ private JCheckBox mEnableCacheTesting;
+
+ private Color mActiveColor;
+ private AdminConnection _admin;
+ private CMSBaseResourceModel _model;
+ private CMSTabPanel mParent;
+ private String mId = null;
+ private static final String HELPINDEX =
+ "configuration-ca-ldappublish-crl-help";
+ private CMSCRLFormatPanel mCRLFormatPanel = null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSCRLCachePanel(CMSTabPanel parent) {
+ super(PANEL_NAME, parent);
+ _model = parent.getResourceModel();
+ mParent = parent;
+ mHelpToken = HELPINDEX;
+ }
+
+ public CMSCRLCachePanel(CMSTabPanel parent, String id) {
+ super(PANEL_NAME, parent);
+ _model = parent.getResourceModel();
+ mParent = parent;
+ mHelpToken = HELPINDEX;
+ mId = id;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void init() {
+ Debug.println("CRLCachePanel: init()");
+ _admin = _model.getServerInfo().getAdmin();
+
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mCenterPanel.setLayout(gb);
+
+
+ //cache panel
+ JPanel cachePanel = new JPanel();
+ cachePanel.setBorder(makeTitledBorder("CACHE"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(cachePanel, gbc);
+ mCenterPanel.add(cachePanel);
+
+ GridBagLayout gb3 = new GridBagLayout();
+ cachePanel.setLayout(gb3);
+
+
+ // enable cache
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel enableCacheLabel = makeJLabel("CACHE");
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.gridx = 0;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ cachePanel.add(enableCacheLabel, gbc);
+
+ mEnableCache = makeJCheckBox();
+ gbc.anchor = gbc.WEST;
+ gbc.gridx++;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,COMPONENT_SPACE);
+ cachePanel.add(mEnableCache, gbc);
+
+
+ // how often to save cache
+ CMSAdminUtil.resetGBC(gbc);
+ mCacheFreqLabel = makeJLabel("INTERVAL");
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.gridx = 0;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ cachePanel.add(mCacheFreqLabel, gbc);
+
+ mCacheFreq = makeJTextField(5);
+ gbc.anchor = gbc.WEST;
+ gbc.gridx++;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,0);
+ cachePanel.add(mCacheFreq, gbc);
+ mActiveColor = mCacheFreq.getBackground();
+
+ mCacheFreqMinLabel = makeJLabel("MINUTES");
+ gbc.anchor = gbc.WEST;
+ gbc.gridx++;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,COMPONENT_SPACE);
+ cachePanel.add(mCacheFreqMinLabel, gbc);
+
+
+ // enable cache recovery
+ CMSAdminUtil.resetGBC(gbc);
+ mEnableCacheRecoveryLabel = makeJLabel("RECOVERY");
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.gridx = 0;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ cachePanel.add(mEnableCacheRecoveryLabel, gbc );
+
+ mEnableCacheRecovery = makeJCheckBox();
+ gbc.anchor = gbc.WEST;
+ gbc.gridx++;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,COMPONENT_SPACE);
+ cachePanel.add(mEnableCacheRecovery, gbc);
+
+ // enable cache testing
+ CMSAdminUtil.resetGBC(gbc);
+ mEnableCacheTestingLabel = makeJLabel("TEST");
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.gridx = 0;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ cachePanel.add(mEnableCacheTestingLabel, gbc );
+
+ mEnableCacheTesting = makeJCheckBox();
+ gbc.anchor = gbc.WEST;
+ gbc.gridx++;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,COMPONENT_SPACE);
+ cachePanel.add(mEnableCacheTesting, gbc);
+
+ int nTabs = mParent.mTabbedPane.getTabCount();
+ for (int i = 0; i < nTabs; i++) {
+ Object p = mParent.mTabbedPane.getComponentAt(i);
+ if (p instanceof CMSCRLFormatPanel) {
+ mCRLFormatPanel = (CMSCRLFormatPanel)p;
+ }
+ }
+
+ refresh();
+ }
+
+ public void refresh() {
+ _model.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_ENABLE_CACHE, "");
+ nvps.put(Constants.PR_CACHE_FREQ, "");
+ nvps.put(Constants.PR_CACHE_RECOVERY, "");
+ nvps.put(Constants.PR_CACHE_TESTING, "");
+
+ try {
+ NameValuePairs val = null;
+ if (mId != null && mId.length() > 0) {
+ val = _admin.read(DestDef.DEST_CA_ADMIN, ScopeDef.SC_CRL,
+ mId, nvps);
+ } else {
+ val = _admin.read(DestDef.DEST_CA_ADMIN, ScopeDef.SC_CRL,
+ Constants.RS_ID_CONFIG, nvps);
+ }
+
+ populate(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ _model.progressStop();
+ }
+ _model.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+ enableFields();
+ }
+
+ public void populate(NameValuePairs nvps) {
+ String signingAlg = "";
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name).trim();
+ if (name.equals(Constants.PR_ENABLE_CACHE)) {
+ mEnableCache.setSelected(getBoolean(value, true));
+ } else if (name.equals(Constants.PR_CACHE_FREQ)) {
+ mCacheFreq.setText(value);
+ } else if (name.equals(Constants.PR_CACHE_RECOVERY)) {
+ mEnableCacheRecovery.setSelected(getBoolean(value));
+ } else if (name.equals(Constants.PR_CACHE_TESTING)) {
+ mEnableCacheTesting.setSelected(getBoolean(value));
+ }
+ }
+ }
+
+ public boolean getBoolean(String val) {
+ if (val.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean getBoolean(String val, boolean defaultValue) {
+ if (val.equals(Constants.TRUE))
+ return true;
+ else if (val.equals(Constants.FALSE))
+ return false;
+ else
+ return defaultValue;
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ String cacheFreq = "";
+ int iCacheFreq = 0;
+
+ NameValuePairs nvps = new NameValuePairs();
+
+
+ if (mEnableCache.isSelected())
+ nvps.put(Constants.PR_ENABLE_CACHE, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_ENABLE_CACHE, Constants.FALSE);
+
+ cacheFreq = mCacheFreq.getText().trim();
+ if (cacheFreq.equals("")) {
+ showMessageDialog("BLANKFIELD");
+ return false;
+ }
+ try {
+ iCacheFreq = Integer.parseInt(cacheFreq);
+ } catch (NumberFormatException e) {
+ showMessageDialog("NUMBERFORMAT");
+ return false;
+ }
+ if (iCacheFreq < 0) {
+ showMessageDialog("NUMBERFORMAT");
+ return false;
+ }
+ nvps.put(Constants.PR_CACHE_FREQ, cacheFreq);
+
+
+ if (mEnableCacheRecovery.isSelected())
+ nvps.put(Constants.PR_CACHE_RECOVERY, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_CACHE_RECOVERY, Constants.FALSE);
+
+ if (mEnableCacheTesting.isSelected())
+ nvps.put(Constants.PR_CACHE_TESTING, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_CACHE_TESTING, Constants.FALSE);
+
+ _model.progressStart();
+
+ try {
+ if (mId != null && mId.length() > 0) {
+ _admin.modify(DestDef.DEST_CA_ADMIN, ScopeDef.SC_CRL,
+ mId, nvps);
+ } else {
+ _admin.modify(DestDef.DEST_CA_ADMIN, ScopeDef.SC_CRL,
+ Constants.RS_ID_CONFIG, nvps);
+ }
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ _model.progressStop();
+ return false;
+ }
+
+ _model.progressStop();
+ clearDirtyFlag();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mEnableCache)) {
+ enableFields();
+ }
+ super.actionPerformed(e);
+ }
+
+ private void enableFields() {
+ boolean enable = mEnableCache.isSelected();
+ Color color = (enable)? mActiveColor: getBackground();
+ mCRLFormatPanel.setCacheEnabled(enable);
+
+ mCacheFreqLabel.setEnabled(enable);
+ CMSAdminUtil.repaintComp(mCacheFreqLabel);
+
+ CMSAdminUtil.enableJTextField(mCacheFreq, enable, color);
+
+ mCacheFreqMinLabel.setEnabled(enable);
+ CMSAdminUtil.repaintComp(mCacheFreqMinLabel);
+
+ mEnableCacheRecoveryLabel.setEnabled(enable);
+ CMSAdminUtil.repaintComp(mEnableCacheRecoveryLabel);
+
+ mEnableCacheRecovery.setEnabled(enable);
+ CMSAdminUtil.repaintComp(mEnableCacheRecovery);
+
+ mEnableCacheTestingLabel.setEnabled(enable);
+ CMSAdminUtil.repaintComp(mEnableCacheTestingLabel);
+
+ mEnableCacheTesting.setEnabled(enable);
+ CMSAdminUtil.repaintComp(mEnableCacheTesting);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSCRLFormatPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSCRLFormatPanel.java
new file mode 100644
index 000000000..3257b90a0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSCRLFormatPanel.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.admin.certsrv.config;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.StringTokenizer;
+
+/**
+ * Panel Setting CRL Format
+ *
+ * @author Andrew Wnuk
+ * @version $Revision$, $Date$
+ */
+public class CMSCRLFormatPanel extends CMSBaseTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static String PANEL_NAME = "CRLFORMAT";
+ private JCheckBox mEnableExtensions;
+ private JCheckBox mEnableExpired;
+ private JCheckBox mEnableOneExtraTime;
+ private JCheckBox mCACertsOnly;
+ private JCheckBox mProfileCertsOnly;
+ private JTextField mProfiles;
+ private AdminConnection _admin;
+ private CMSBaseResourceModel _model;
+ private JComboBox mAlgorithms;
+ private Color mActiveColor;
+ private CMSTabPanel mParent;
+ private String mId = null;
+ private static final String HELPINDEX =
+ "configuration-ca-ldappublish-crl-help";
+ private boolean mCacheEnabled;
+ private boolean mInitialized = false;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSCRLFormatPanel(CMSTabPanel parent) {
+ super(PANEL_NAME, parent);
+ _model = parent.getResourceModel();
+ mParent = parent;
+ mHelpToken = HELPINDEX;
+ }
+
+ public CMSCRLFormatPanel(CMSTabPanel parent, String id) {
+ super(PANEL_NAME, parent);
+ _model = parent.getResourceModel();
+ mParent = parent;
+ mHelpToken = HELPINDEX;
+ mId = id;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void init() {
+ Debug.println("CRLFormatPanel: init()");
+ _admin = _model.getServerInfo().getAdmin();
+
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mCenterPanel.setLayout(gb);
+
+
+ //format panel
+ JPanel formatPanel = new JPanel();
+ formatPanel.setBorder(makeTitledBorder("FORMAT"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gb.setConstraints(formatPanel, gbc);
+ mCenterPanel.add(formatPanel);
+
+ GridBagLayout gb1 = new GridBagLayout();
+ formatPanel.setLayout(gb1);
+
+
+ // algorithm selection
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel digestLabel = makeJLabel("MESSAGEDIGEST");
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.gridx = 0;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ formatPanel.add(digestLabel, gbc );
+
+ mAlgorithms = makeJComboBox();
+ mAlgorithms.addItemListener(this);
+ gbc.anchor = gbc.WEST;
+ gbc.gridx++;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,COMPONENT_SPACE);
+ formatPanel.add(mAlgorithms, gbc);
+
+
+ // allow extensions
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel allowExtensionsLabel = makeJLabel("EXT");
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.gridx = 0;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ formatPanel.add(allowExtensionsLabel, gbc );
+
+ mEnableExtensions = makeJCheckBox();
+ gbc.anchor = gbc.WEST;
+ gbc.gridx++;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,COMPONENT_SPACE);
+ formatPanel.add(mEnableExtensions, gbc);
+
+
+ //contents panel
+ JPanel contentsPanel = new JPanel();
+ contentsPanel.setBorder(makeTitledBorder("CONTENTS"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(contentsPanel, gbc);
+ mCenterPanel.add(contentsPanel);
+
+ GridBagLayout gb2 = new GridBagLayout();
+ contentsPanel.setLayout(gb2);
+
+
+ // include expired certs
+ CMSAdminUtil.resetGBC(gbc);
+ mEnableExpired = makeJCheckBox("EXPIRED");
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridx = 0;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ contentsPanel.add(mEnableExpired, gbc);
+
+
+ // include expired certs one extra time
+ CMSAdminUtil.resetGBC(gbc);
+ mEnableOneExtraTime = makeJCheckBox("ONEEXTRATIME");
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridx = 0;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ contentsPanel.add(mEnableOneExtraTime, gbc);
+
+
+ // CA certs only
+ CMSAdminUtil.resetGBC(gbc);
+ mCACertsOnly = makeJCheckBox("CACERTSONLY");
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridx = 0;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ contentsPanel.add(mCACertsOnly, gbc);
+
+
+ // profile certs only
+ CMSAdminUtil.resetGBC(gbc);
+ mProfileCertsOnly = makeJCheckBox("PROFILECERTSONLY");
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridx = 0;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ contentsPanel.add(mProfileCertsOnly, gbc);
+
+ mProfiles = makeJTextField(20);
+ gbc.anchor = gbc.WEST;
+ gbc.gridx++;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,0,0,COMPONENT_SPACE);
+ contentsPanel.add(mProfiles, gbc);
+ mActiveColor = mProfiles.getBackground();
+
+
+ refresh();
+ mInitialized = true;
+ }
+
+ public void refresh() {
+ _model.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_EXTENSIONS, "");
+ nvps.put(Constants.PR_SIGNING_ALGORITHM, "");
+ nvps.put(Constants.PR_INCLUDE_EXPIREDCERTS, "");
+ nvps.put(Constants.PR_INCLUDE_EXPIREDCERTS_ONEEXTRATIME, "");
+ nvps.put(Constants.PR_CA_CERTS_ONLY, "");
+ nvps.put(Constants.PR_PROFILE_CERTS_ONLY, "");
+ nvps.put(Constants.PR_PROFILE_LIST, "");
+ nvps.put(Constants.PR_ENABLE_CACHE, "");
+
+ try {
+ NameValuePairs val = null;
+ if (mId != null && mId.length() > 0) {
+ val = _admin.read(DestDef.DEST_CA_ADMIN, ScopeDef.SC_CRL,
+ mId, nvps);
+ } else {
+ val = _admin.read(DestDef.DEST_CA_ADMIN, ScopeDef.SC_CRL,
+ Constants.RS_ID_CONFIG, nvps);
+ }
+
+ populate(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ _model.progressStop();
+ }
+ _model.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+
+ if (mProfileCertsOnly.isSelected()) {
+ CMSAdminUtil.enableJTextField(mProfiles, true, mActiveColor);
+ } else {
+ CMSAdminUtil.enableJTextField(mProfiles, false, getBackground());
+ }
+ mEnableOneExtraTime.setEnabled(mCacheEnabled && (!mEnableExpired.isSelected()));
+ CMSAdminUtil.repaintComp(mEnableOneExtraTime);
+ }
+
+ public void populate(NameValuePairs nvps) {
+ String signingAlg = "";
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name).trim();
+ if (name.equals(Constants.PR_EXTENSIONS)) {
+ mEnableExtensions.setSelected(getBoolean(value));
+ } else if (name.equals(Constants.PR_SIGNING_ALGORITHM)) {
+ signingAlg = value;
+ } else if (name.equals(Constants.PR_ALL_ALGORITHMS)) {
+ initAlgorithmBox(value);
+ } else if (name.equals(Constants.PR_INCLUDE_EXPIREDCERTS)) {
+ mEnableExpired.setSelected(getBoolean(value));
+ } else if (name.equals(Constants.PR_INCLUDE_EXPIREDCERTS_ONEEXTRATIME)) {
+ mEnableOneExtraTime.setSelected(getBoolean(value));
+ } else if (name.equals(Constants.PR_CA_CERTS_ONLY)) {
+ mCACertsOnly.setSelected(getBoolean(value));
+ } else if (name.equals(Constants.PR_PROFILE_CERTS_ONLY)) {
+ mProfileCertsOnly.setSelected(getBoolean(value));
+ } else if (name.equals(Constants.PR_PROFILE_LIST)) {
+ mProfiles.setText(value);
+ } else if (name.equals(Constants.PR_ENABLE_CACHE)) {
+ mCacheEnabled = (value.equals(Constants.TRUE))? true: false;
+ }
+ }
+
+ mAlgorithms.setSelectedItem(signingAlg);
+ }
+
+ private void initAlgorithmBox(String val) {
+ if (mAlgorithms.getItemCount() >= 0) {
+ mAlgorithms.removeAllItems();
+ }
+ StringTokenizer tokenizer = new StringTokenizer(val, ":");
+ while (tokenizer.hasMoreTokens()) {
+ mAlgorithms.addItem(tokenizer.nextToken());
+ }
+ }
+
+ public boolean getBoolean(String val) {
+ if (val.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ private String trimList(String list) {
+ String trimmed = "";
+
+ StringTokenizer elements = new StringTokenizer(list, ",", true);
+ int n = 0;
+ while (elements.hasMoreTokens()) {
+ String element = elements.nextToken().trim();
+ if (element == null || element.length() == 0) return null;
+ if (element.equals(",") && n % 2 == 0) return null;
+ trimmed += element;
+ n++;
+ }
+ if (n % 2 == 0) return null;
+
+ return trimmed;
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ NameValuePairs nvps = new NameValuePairs();
+
+ if (mEnableExtensions.isSelected())
+ nvps.put(Constants.PR_EXTENSIONS, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_EXTENSIONS, Constants.FALSE);
+
+ if (mEnableExpired.isSelected())
+ nvps.put(Constants.PR_INCLUDE_EXPIREDCERTS, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_INCLUDE_EXPIREDCERTS, Constants.FALSE);
+
+ if (mEnableOneExtraTime.isSelected())
+ nvps.put(Constants.PR_INCLUDE_EXPIREDCERTS_ONEEXTRATIME, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_INCLUDE_EXPIREDCERTS_ONEEXTRATIME, Constants.FALSE);
+
+ if (mCACertsOnly.isSelected())
+ nvps.put(Constants.PR_CA_CERTS_ONLY, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_CA_CERTS_ONLY, Constants.FALSE);
+
+ if (mProfileCertsOnly.isSelected())
+ nvps.put(Constants.PR_PROFILE_CERTS_ONLY, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_PROFILE_CERTS_ONLY, Constants.FALSE);
+
+ String profileList = null;
+ if (mProfileCertsOnly.isSelected()) {
+ if (mProfiles.getText().trim().equals("")) {
+ showMessageDialog("BLANKPROFILELIST");
+ return false;
+ }
+ profileList = trimList(mProfiles.getText());
+ if (profileList == null) {
+ showMessageDialog("PROFILELISTFORMAT");
+ return false;
+ }
+ }
+ if (profileList != null)
+ nvps.put(Constants.PR_PROFILE_LIST, profileList);
+ else
+ nvps.put(Constants.PR_PROFILE_LIST, mProfiles.getText().trim());
+
+
+ int index = mAlgorithms.getSelectedIndex();
+
+ nvps.put(Constants.PR_SIGNING_ALGORITHM,
+ (String) mAlgorithms.getSelectedItem());
+
+ _model.progressStart();
+
+ try {
+ if (mId != null && mId.length() > 0) {
+ _admin.modify(DestDef.DEST_CA_ADMIN, ScopeDef.SC_CRL,
+ mId, nvps);
+ } else {
+ _admin.modify(DestDef.DEST_CA_ADMIN, ScopeDef.SC_CRL,
+ Constants.RS_ID_CONFIG, nvps);
+ }
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ _model.progressStop();
+ return false;
+ }
+
+ _model.progressStop();
+ clearDirtyFlag();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mProfileCertsOnly)) {
+ if (mProfileCertsOnly.isSelected()) {
+ CMSAdminUtil.enableJTextField(mProfiles, true, mActiveColor);
+ } else {
+ CMSAdminUtil.enableJTextField(mProfiles, false, getBackground());
+ }
+ } else if (e.getSource().equals(mEnableExpired)) {
+ mEnableOneExtraTime.setEnabled(mCacheEnabled && (!mEnableExpired.isSelected()));
+ CMSAdminUtil.repaintComp(mEnableOneExtraTime);
+ }
+
+ super.actionPerformed(e);
+ }
+
+ public void setCacheEnabled (boolean cacheEnabled) {
+ if (mCacheEnabled != cacheEnabled) {
+ mCacheEnabled = cacheEnabled;
+ if (mInitialized) {
+ mEnableOneExtraTime.setEnabled(mCacheEnabled && (!mEnableExpired.isSelected()));
+ CMSAdminUtil.repaintComp(mEnableOneExtraTime);
+ }
+ }
+ }
+
+ /**
+ * Override the initialize method only for this panel.
+ * We need to refresh in case the CRLDistributionPointExtension
+ * has modified the caCertsOnly property for us.
+ **/
+ public void initialize() {
+ Debug.println("CMSCRLFormatPanel: intialize()");
+ if (!mInit) {
+ init();
+ mInit = true;
+ } else {
+ if(!isDirty()) {
+ refresh();
+ }
+ }
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSCRLIPPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSCRLIPPanel.java
new file mode 100644
index 000000000..553211eb8
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSCRLIPPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.ug.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+
+/**
+ * CRL IP Panel
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMSCRLIPPanel extends CMSBaseTab
+ implements MouseListener
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+
+ private final static String PANEL_NAME = "CRLIPS";
+ private final static String HELPINDEX = "configuration-revocation";
+
+ private AdminConnection mAdmin;
+ private CMSBaseResourceModel mModel;
+ private CMSTabPanel mParent;
+ private JList mList;
+ private DefaultListModel mDataModel;
+ private JScrollPane mScrollPane;
+ private JButton mAdd;
+ private JButton mEdit;
+ private JButton mDelete;
+ private Vector mNames;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSCRLIPPanel(CMSBaseResourceModel model, CMSTabPanel parent) {
+ super(PANEL_NAME, parent);
+ mModel = model;
+ mParent = parent;
+ mDataModel = new DefaultListModel();
+ mHelpToken = HELPINDEX;
+ mNames = new Vector();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * initialize the UI components
+ */
+ public void init() {
+ JPanel mainPanel = mCenterPanel;
+
+ Debug.println("CRLIPPanel: init()");
+ mAdmin = mModel.getServerInfo().getAdmin();
+
+ GridBagLayout gb1 = new GridBagLayout();
+ mainPanel.setLayout(gb1);
+
+ GridBagConstraints gbc = new GridBagConstraints();
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel listLabel = makeJLabel("CRLIPLIST");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(DIFFERENT_COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE,
+ 0,DIFFERENT_COMPONENT_SPACE);
+ gb1.setConstraints(listLabel, gbc);
+ mainPanel.add(listLabel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mList = makeJList(mDataModel, 7);
+ mScrollPane = new JScrollPane(mList,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mList.addMouseListener(this);
+ mScrollPane.setBackground(Color.white);
+ mScrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 0.5;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE,
+ 0,DIFFERENT_COMPONENT_SPACE);
+ gb1.setConstraints(mScrollPane, gbc);
+ mainPanel.add(mScrollPane);
+
+ JPanel buttonPanel = createUserButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,0,
+ 0,DIFFERENT_COMPONENT_SPACE);
+ gb1.setConstraints(buttonPanel, gbc);
+ mainPanel.add(buttonPanel);
+
+ refresh();
+ }
+
+
+ /**
+ * create the user action button panel
+ */
+ protected JPanel createUserButtonPanel() {
+ //add, edit, delete, help buttons required
+ //actionlister to this object
+ mAdd = makeJButton("ADD");
+ mEdit = makeJButton("EDIT");
+ mDelete = makeJButton("DELETE");
+ JButton[] buttons = {mAdd, mEdit, mDelete};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ /**
+ * refresh the panel data
+ */
+ public void refresh() {
+ try {
+ NameValuePairs nvps = mAdmin.search(DestDef.DEST_CA_ADMIN,
+ ScopeDef.SC_CRLIPS,
+ new NameValuePairs());
+ populate(nvps);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ }
+
+ repaint(1);
+ }
+
+
+ /*==========================================================
+ * Event Handler
+ *==========================================================*/
+
+ //======= ActionLister ============================
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mEdit)) {
+ JFrame frame = mModel.getFrame();
+ String name = ((JLabel)mList.getSelectedValue()).getText();
+ //(String)mList.getSelectedValue();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_ENABLED, "");
+ nvps.put(Constants.PR_ID, "");
+ nvps.put(Constants.PR_DESCRIPTION, "");
+ nvps.put(Constants.PR_CLASS, "");
+ try {
+ NameValuePairs values = mAdmin.read(DestDef.DEST_CA_ADMIN,
+ ScopeDef.SC_CRLIPS,
+ name, nvps);
+
+ CRLIPEditor editor = new CRLIPEditor(mAdmin, mModel.getFrame(),
+ name, DestDef.DEST_CA_ADMIN,
+ mModel.getServerInfo().getServerId(),
+ mNames);
+ editor.showDialog(values);
+ } catch (EAdminException ex) {
+ showErrorDialog(ex.toString());
+ }
+ refresh();
+ } else if (e.getSource().equals(mAdd)) {
+ CRLIPEditor editor = new CRLIPEditor(mAdmin, mModel.getFrame(),
+ null, DestDef.DEST_CA_ADMIN,
+ mModel.getServerInfo().getServerId(),
+ mNames);
+ editor.showDialog(new NameValuePairs());
+ String name = editor.getCRLName();
+ CMSResourceObject node = (CMSResourceObject)(mParent.getResourceObject());
+ CMSResourceObject crlsNode = node;
+ node = new CMSResourceObject();
+ node.setName(name);
+ CMSTabPanel crlIPTabPane = new CMSTabPanel(mModel, node);
+ crlIPTabPane.addTab(new CMSCRLSettingPanel(crlIPTabPane, name));
+ crlIPTabPane.addTab(new CMSCRLCachePanel(crlIPTabPane, name));
+ crlIPTabPane.addTab(new CMSCRLFormatPanel(crlIPTabPane, name));
+ node.setCustomPanel(crlIPTabPane);
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULEOBJECT));
+ node.setAllowsChildren(true);
+ crlsNode.insert(node, crlsNode.getChildCount());
+
+ CMSResourceObject crlNode = node;
+
+ node = new CMSResourceObject("CRLEXTENSIONS");
+ CMSUGTabPanel crlExtTabPane1 = new CMSUGTabPanel(mModel, node);
+ crlExtTabPane1.addTab(new CRLExtensionsInstanceTab(mModel, DestDef.DEST_CA_ADMIN, name));
+ node.setCustomPanel(crlExtTabPane1);
+ node.setIcon( CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULEOBJECT));
+ node.setAllowsChildren(false);
+ crlNode.add(node);
+ mModel.fireTreeStructureChanged((ResourceObject)crlsNode);
+
+ refresh();
+ } else if (e.getSource().equals(mDelete)) {
+ int index = mList.getSelectedIndex();
+ if (index >= 0) {
+ String name = ((JLabel)mList.getSelectedValue()).getText();
+ //(String)mList.getSelectedValue();
+
+ int i = showConfirmDialog("DELETE");
+ if (i == JOptionPane.YES_OPTION) {
+ try {
+ mAdmin.delete(DestDef.DEST_CA_ADMIN,
+ ScopeDef.SC_CRLIPS, name);
+ } catch (EAdminException ex) {
+ showErrorDialog(ex.toString());
+ }
+ if (mNames.contains(name))
+ mNames.remove(name);
+ mDataModel.removeElementAt(index);
+ if (mDataModel.size() > 0)
+ mList.setSelectedIndex(0);
+ }
+ CMSResourceObject node =
+ (CMSResourceObject)(mParent.getResourceObject());
+ Enumeration allchildren = node.children();
+ while (allchildren.hasMoreElements()) {
+ CMSResourceObject child = (CMSResourceObject)(allchildren.nextElement());
+ String name1 = child.getName();
+ if (name1.equals(name)) {
+ node.remove(child);
+ mModel.fireTreeStructureChanged((ResourceObject)node);
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ //=== MOUSELISTENER ========================
+ public void mouseClicked(MouseEvent e) {
+ if (e.getSource() == mList) {
+ if (mList.getSelectedIndex() < 0)
+ mEdit.setEnabled(false);
+ else
+ mEdit.setEnabled(true);
+ }
+ }
+
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {}
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {}
+
+ //======== CMSBaseConfigPanel ==============
+ public boolean applyCallback() {
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ //update the UI component using the data retrieved
+ private void populate(NameValuePairs nvps) {
+
+ mDataModel.removeAllElements();
+ mNames.removeAllElements();
+ for (String name : nvps.keySet()) {
+ if (name.indexOf('.') == -1) {
+ mNames.addElement(name);
+
+ String enable = nvps.get(name + "." + Constants.PR_ENABLED);
+ if (enable != null && enable.equalsIgnoreCase(Constants.TRUE)) {
+ mDataModel.addElement(new JLabel(name,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE),
+ JLabel.LEFT));
+ } else {
+ mDataModel.addElement(new JLabel(name,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE_DISABLE),
+ JLabel.LEFT));
+ }
+ /*
+ mDataModel.addElement(name);
+ */
+ }
+ }
+
+ if (mDataModel.size() > 0) {
+ mList.setSelectedIndex(0);
+ mEdit.setEnabled(true);
+ mDelete.setEnabled(true);
+ } else {
+ mEdit.setEnabled(false);
+ mDelete.setEnabled(false);
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSCRLSettingPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSCRLSettingPanel.java
new file mode 100644
index 000000000..d420686e3
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSCRLSettingPanel.java
@@ -0,0 +1,698 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+/**
+ * CRL Publishing Setting Panel
+ *
+ * @author Andrew Wnuk
+ * @author Christine Ho
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class CMSCRLSettingPanel extends CMSBaseTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static String PANEL_NAME = "CRLSETTING";
+
+ private JCheckBox mEnableCRL;
+ private JLabel mCRLGenLabel;
+ private JTextField mCRLGen;
+ private JLabel mDeltaGenLabel;
+
+ private JLabel mExtendNextUpdateLabel;
+ private JCheckBox mExtendNextUpdate;
+
+ private JCheckBox mAlways;
+ private JCheckBox mDaily;
+ private JTextField mDailyAt;
+ private JCheckBox mEnableFreq;
+ private JTextField mFrequency;
+ private JLabel mMinLabel;
+ private JLabel mGracePeriodLabel;
+ private JTextField mGracePeriod;
+ private JLabel mGracePeriodMinLabel;
+
+ private Color mActiveColor;
+ private AdminConnection _admin;
+ private CMSBaseResourceModel _model;
+ private CMSTabPanel mParent;
+ private String mId = null;
+ private static final String HELPINDEX =
+ "configuration-ca-ldappublish-crl-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSCRLSettingPanel(CMSTabPanel parent) {
+ super(PANEL_NAME, parent);
+ _model = parent.getResourceModel();
+ mParent = parent;
+ mHelpToken = HELPINDEX;
+ }
+
+ public CMSCRLSettingPanel(CMSTabPanel parent, String id) {
+ super(PANEL_NAME, parent);
+ _model = parent.getResourceModel();
+ mParent = parent;
+ mHelpToken = HELPINDEX;
+ mId = id;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void init() {
+ Debug.println("CRLSettingPanel: init()");
+ _admin = _model.getServerInfo().getAdmin();
+
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mCenterPanel.setLayout(gb);
+
+
+ //schema panel
+ JPanel schemaPanel = new JPanel();
+ schemaPanel.setBorder(makeTitledBorder("SCHEMA"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gb.setConstraints(schemaPanel, gbc);
+ mCenterPanel.add(schemaPanel);
+
+ GridBagLayout gb4 = new GridBagLayout();
+ schemaPanel.setLayout(gb4);
+
+
+ // enable CRL generation
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel enableCRLLabel = makeJLabel("CRL");
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.gridx = 0;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ schemaPanel.add(enableCRLLabel, gbc );
+
+ mEnableCRL = makeJCheckBox();
+ gbc.anchor = gbc.WEST;
+ gbc.gridx++;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,COMPONENT_SPACE);
+ schemaPanel.add(mEnableCRL, gbc);
+
+
+ // generate full CRL every X deltas
+ CMSAdminUtil.resetGBC(gbc);
+ mCRLGenLabel = makeJLabel("GENERATION");
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.gridx = 0;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ schemaPanel.add(mCRLGenLabel, gbc );
+
+ mCRLGen = makeJTextField(5);
+ gbc.anchor = gbc.WEST;
+ gbc.gridx++;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,0);
+ schemaPanel.add(mCRLGen, gbc);
+ mActiveColor = mCRLGen.getBackground();
+
+ mDeltaGenLabel = makeJLabel("DELTAS");
+ gbc.anchor = gbc.WEST;
+ gbc.gridx++;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,COMPONENT_SPACE);
+ schemaPanel.add(mDeltaGenLabel, gbc);
+
+
+ // Extend next update time
+ CMSAdminUtil.resetGBC(gbc);
+ mExtendNextUpdateLabel = makeJLabel("NEXTTIME");
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.gridx = 0;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ schemaPanel.add(mExtendNextUpdateLabel, gbc );
+
+ mExtendNextUpdate = makeJCheckBox();
+ gbc.anchor = gbc.WEST;
+ gbc.gridx++;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,COMPONENT_SPACE);
+ schemaPanel.add(mExtendNextUpdate, gbc);
+
+
+ //frequency panel
+ JPanel freqPanel = new JPanel();
+ freqPanel.setBorder(makeTitledBorder("FREQ"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(freqPanel, gbc);
+ mCenterPanel.add(freqPanel);
+
+ //add components
+ GridBagLayout gb2 = new GridBagLayout();
+ freqPanel.setLayout(gb2);
+
+
+ // update every time
+ CMSAdminUtil.resetGBC(gbc);
+ mAlways = makeJCheckBox("ALWAYS");
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridx = 0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,COMPONENT_SPACE);
+ freqPanel.add(mAlways, gbc);
+
+
+ // update at specified time
+ CMSAdminUtil.resetGBC(gbc);
+ mDaily = makeJCheckBox("DAILY");
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridx = 0;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ freqPanel.add(mDaily, gbc);
+
+ mDailyAt = makeJTextField(30);
+ gbc.anchor = gbc.WEST;
+ gbc.gridx++;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,COMPONENT_SPACE);
+ freqPanel.add(mDailyAt, gbc);
+
+
+ // update by time interval
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridx = 0;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ mEnableFreq = makeJCheckBox("FREQ");
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ freqPanel.add(mEnableFreq, gbc);
+
+ mFrequency = makeJTextField(5);
+ gbc.anchor = gbc.WEST;
+ gbc.gridx++;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,0);
+ freqPanel.add(mFrequency, gbc);
+
+ mMinLabel = makeJLabel("MINUTES");
+ gbc.anchor = gbc.WEST;
+ gbc.gridx++;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,COMPONENT_SPACE);
+ freqPanel.add(mMinLabel, gbc);
+
+
+ // next update grace period
+ CMSAdminUtil.resetGBC(gbc);
+ mGracePeriodLabel = makeJLabel("GRACEPERIOD");
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridx = 0;
+ // gbc.gridx = 2;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ freqPanel.add(mGracePeriodLabel, gbc);
+
+ mGracePeriod = makeJTextField(5);
+ gbc.anchor = gbc.WEST;
+ gbc.gridx++;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,0);
+ freqPanel.add(mGracePeriod, gbc);
+
+ mGracePeriodMinLabel = makeJLabel("MINUTES");
+ gbc.anchor = gbc.WEST;
+ gbc.gridx++;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,COMPONENT_SPACE);
+ freqPanel.add(mGracePeriodMinLabel, gbc);
+
+
+ refresh();
+ }
+
+ public void refresh() {
+ _model.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_ENABLE_CRL, "");
+ nvps.put(Constants.PR_UPDATE_SCHEMA, "");
+ nvps.put(Constants.PR_EXTENDED_NEXT_UPDATE, "");
+ nvps.put(Constants.PR_UPDATE_ALWAYS, "");
+ nvps.put(Constants.PR_ENABLE_DAILY, "");
+ nvps.put(Constants.PR_DAILY_UPDATES, "");
+ nvps.put(Constants.PR_ENABLE_FREQ, "");
+ nvps.put(Constants.PR_UPDATE_FREQ, "");
+ nvps.put(Constants.PR_GRACE_PERIOD, "");
+
+ try {
+ NameValuePairs val = null;
+ if (mId != null && mId.length() > 0) {
+ val = _admin.read(DestDef.DEST_CA_ADMIN, ScopeDef.SC_CRL,
+ mId, nvps);
+ } else {
+ val = _admin.read(DestDef.DEST_CA_ADMIN, ScopeDef.SC_CRL,
+ Constants.RS_ID_CONFIG, nvps);
+ }
+
+ populate(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ _model.progressStop();
+ }
+ _model.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+
+ enableFields();
+ }
+
+ public void populate(NameValuePairs nvps) {
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name).trim();
+ if (name.equals(Constants.PR_ENABLE_CRL)) {
+ mEnableCRL.setSelected(getBoolean(value));
+ } else if (name.equals(Constants.PR_UPDATE_SCHEMA)) {
+ mCRLGen.setText(value);
+ } else if (name.equals(Constants.PR_EXTENDED_NEXT_UPDATE)) {
+ mExtendNextUpdate.setSelected(getBoolean(value));
+ } else if (name.equals(Constants.PR_UPDATE_ALWAYS)) {
+ mAlways.setSelected(getBoolean(value));
+ } else if (name.equals(Constants.PR_ENABLE_DAILY)) {
+ mDaily.setSelected(getBoolean(value));
+ } else if (name.equals(Constants.PR_DAILY_UPDATES)) {
+ mDailyAt.setText(value);
+ } else if (name.equals(Constants.PR_ENABLE_FREQ)) {
+ mEnableFreq.setSelected(getBoolean(value));
+ } else if (name.equals(Constants.PR_UPDATE_FREQ)) {
+ mFrequency.setText(value);
+ } else if (name.equals(Constants.PR_GRACE_PERIOD)) {
+ mGracePeriod.setText(value);
+ }
+ }
+ }
+
+ public boolean getBoolean(String val) {
+ if (val.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean getBoolean(String val, boolean defaultValue) {
+ if (val.equals(Constants.TRUE))
+ return true;
+ else if (val.equals(Constants.FALSE))
+ return false;
+ else
+ return defaultValue;
+ }
+
+ private int checkTime(String time) {
+ String digits = "0123456789";
+ int len = time.length();
+ if (len < 3 || len > 5) return -1;
+ int s = time.indexOf(':');
+ if (s < 0 || s > 2 || (len - s) != 3) return -1;
+
+ int h = 0;
+ for (int i = 0; i < s; i++) {
+ h *= 10;
+ int k = digits.indexOf(time.charAt(i));
+ if (k < 0) return -1;
+ h += k;
+ }
+ if (h > 23) return -1;
+
+ int m = 0;
+ for (int i = s+1; i < len; i++) {
+ m *= 10;
+ int k = digits.indexOf(time.charAt(i));
+ if (k < 0) return -1;
+ m += k;
+ }
+ if (m > 59) return -1;
+
+ return ((h * 60) + m);
+ }
+
+ private String trimList(String list) {
+ String trimmed = "";
+
+ StringTokenizer days = new StringTokenizer(list, ";", true);
+ while (days.hasMoreTokens()) {
+ String dayList = days.nextToken().trim();
+ if (dayList == null || dayList.length() == 0) continue;
+ if (dayList.equals(";")) {
+ trimmed += dayList;
+ continue;
+ }
+ StringTokenizer elements = new StringTokenizer(dayList, ",", true);
+ int n = 0;
+ while (elements.hasMoreTokens()) {
+ String element = elements.nextToken().trim();
+ if (element == null || element.length() == 0) return null;
+ if (element.equals(",") && n % 2 == 0) return null;
+ trimmed += element;
+ n++;
+ }
+ if (n % 2 == 0) return null;
+ }
+ return trimmed;
+ }
+
+ private Vector checkTimeList(String list) {
+ if (list == null || list.length() == 0) return null;
+ if (list.charAt(0) == ',' || list.charAt(list.length()-1) == ',') return null;
+
+ Vector listedTimes = new Vector();
+
+ StringTokenizer days = new StringTokenizer(list, ";");
+ while (days.hasMoreTokens()) {
+ String dayList = days.nextToken().trim();
+ if (dayList == null || dayList.length() == 0) continue;
+ int t0 = -1;
+ StringTokenizer times = new StringTokenizer(dayList, ",");
+ while (times.hasMoreTokens()) {
+ String time = times.nextToken();
+ if (time.charAt(0) == '*') time = time.substring(1);
+ int t = checkTime(time);
+ if (t < 0) {
+ return null;
+ } else {
+ if (t > t0) {
+ listedTimes.addElement(new Integer(t));
+ t0 = t;
+ } else {
+ return null;
+ }
+ }
+ }
+ }
+ return listedTimes;
+ }
+
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ String timeList = trimList(mDailyAt.getText());
+
+ if (mEnableCRL.isSelected()) {
+ if (!mAlways.isSelected() && !mDaily.isSelected() &&
+ !mEnableFreq.isSelected()) {
+ showMessageDialog("UPDATES");
+ return false;
+ }
+
+ if (mCRLGen.getText().trim().equals("")) {
+ showMessageDialog("BLANKSCHEMA");
+ return false;
+ }
+ try {
+ int num = Integer.parseInt(mCRLGen.getText().trim());
+ if (num < 1) {
+ showMessageDialog("SCHEMANUMBER");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ showMessageDialog("SCHEMANUMBER");
+ return false;
+ }
+
+ Vector daily = null;
+ if (mDaily.isSelected()) {
+ if (mDailyAt.getText().trim().equals("")) {
+ showMessageDialog("BLANKDAILY");
+ return false;
+ }
+ daily = checkTimeList(timeList);
+ if (daily == null) {
+ showMessageDialog("DAILYFORMAT");
+ return false;
+ }
+ }
+
+ if (mEnableFreq.isSelected()) {
+ if (mFrequency.getText().trim().equals("")) {
+ showMessageDialog("BLANKFREQ");
+ return false;
+ }
+ int freq = 0;
+ try {
+ freq = Integer.parseInt(mFrequency.getText().trim());
+ if (freq < 1) {
+ showMessageDialog("FREQNUMBER");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ showMessageDialog("FREQNUMBER");
+ return false;
+ }
+ if (mDaily.isSelected() && daily != null && daily.size() > 1) {
+ showMessageDialog("DAILYFORMAT");
+ return false;
+ }
+ if (mDaily.isSelected() && daily != null && daily.size() == 1 &&
+ (freq >= 1440 ||
+ freq + ((Integer)(daily.elementAt(0))).intValue() >= 1440)) {
+ showMessageDialog("INTERVALTOBIG");
+ return false;
+ }
+ }
+
+ if (mGracePeriod.getText().trim().equals("")) {
+ showMessageDialog("BLANKGRACE");
+ return false;
+ }
+ try {
+ int grace = Integer.parseInt(mGracePeriod.getText().trim());
+ if (grace < 0) {
+ showMessageDialog("GRACENUMBER");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ showMessageDialog("GRACENUMBER");
+ return false;
+ }
+ }
+
+ NameValuePairs nvps = new NameValuePairs();
+
+ if (mEnableCRL.isSelected())
+ nvps.put(Constants.PR_ENABLE_CRL, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_ENABLE_CRL, Constants.FALSE);
+
+ nvps.put(Constants.PR_UPDATE_SCHEMA, mCRLGen.getText().trim());
+
+ if (mExtendNextUpdate.isSelected())
+ nvps.put(Constants.PR_EXTENDED_NEXT_UPDATE, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_EXTENDED_NEXT_UPDATE, Constants.FALSE);
+
+ if (mAlways.isSelected())
+ nvps.put(Constants.PR_UPDATE_ALWAYS, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_UPDATE_ALWAYS, Constants.FALSE);
+
+ if (mDaily.isSelected())
+ nvps.put(Constants.PR_ENABLE_DAILY, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_ENABLE_DAILY, Constants.FALSE);
+
+ if (timeList != null)
+ nvps.put(Constants.PR_DAILY_UPDATES, timeList);
+ else
+ nvps.put(Constants.PR_DAILY_UPDATES, mDailyAt.getText().trim());
+
+
+ if (mEnableFreq.isSelected())
+ nvps.put(Constants.PR_ENABLE_FREQ, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_ENABLE_FREQ, Constants.FALSE);
+
+ nvps.put(Constants.PR_UPDATE_FREQ, mFrequency.getText().trim());
+
+ nvps.put(Constants.PR_GRACE_PERIOD, mGracePeriod.getText().trim());
+
+
+ _model.progressStart();
+
+ try {
+ if (mId != null && mId.length() > 0) {
+ _admin.modify(DestDef.DEST_CA_ADMIN, ScopeDef.SC_CRL,
+ mId, nvps);
+ } else {
+ _admin.modify(DestDef.DEST_CA_ADMIN, ScopeDef.SC_CRL,
+ Constants.RS_ID_CONFIG, nvps);
+ }
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ _model.progressStop();
+ return false;
+ }
+
+ _model.progressStop();
+ clearDirtyFlag();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ Debug.println("CRLSettingPanel: resetCallback()");
+ refresh();
+ return true;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ Debug.println("CRLSettingPanel: actionPerformed()");
+ if (e.getSource().equals(mEnableCRL)) {
+ enableFields();
+ }
+
+ if (e.getSource().equals(mDaily)) {
+ if (mDaily.isSelected()) {
+ CMSAdminUtil.enableJTextField(mDailyAt, true, mActiveColor);
+ CMSAdminUtil.enableJTextField(mGracePeriod, true, mActiveColor);
+ mGracePeriodLabel.setEnabled(true);
+ CMSAdminUtil.repaintComp(mGracePeriodLabel);
+ mGracePeriodMinLabel.setEnabled(true);
+ CMSAdminUtil.repaintComp(mGracePeriodMinLabel);
+ } else {
+ CMSAdminUtil.enableJTextField(mDailyAt, false, getBackground());
+ if (!mEnableFreq.isSelected()) {
+ CMSAdminUtil.enableJTextField(mGracePeriod, false, getBackground());
+ mGracePeriodLabel.setEnabled(false);
+ CMSAdminUtil.repaintComp(mGracePeriodLabel);
+ mGracePeriodMinLabel.setEnabled(false);
+ CMSAdminUtil.repaintComp(mGracePeriodMinLabel);
+ }
+ }
+ }
+ if (e.getSource().equals(mEnableFreq)) {
+ if (mEnableFreq.isSelected()) {
+ CMSAdminUtil.enableJTextField(mFrequency, true, mActiveColor);
+ mMinLabel.setEnabled(true);
+ CMSAdminUtil.repaintComp(mMinLabel);
+ CMSAdminUtil.enableJTextField(mGracePeriod, true, mActiveColor);
+ mGracePeriodLabel.setEnabled(true);
+ CMSAdminUtil.repaintComp(mGracePeriodLabel);
+ mGracePeriodMinLabel.setEnabled(true);
+ CMSAdminUtil.repaintComp(mGracePeriodMinLabel);
+ } else {
+ CMSAdminUtil.enableJTextField(mFrequency, false, getBackground());
+ mMinLabel.setEnabled(false);
+ CMSAdminUtil.repaintComp(mMinLabel);
+ if (!mDaily.isSelected()) {
+ CMSAdminUtil.enableJTextField(mGracePeriod, false, getBackground());
+ mGracePeriodLabel.setEnabled(false);
+ CMSAdminUtil.repaintComp(mGracePeriodLabel);
+ mGracePeriodMinLabel.setEnabled(false);
+ CMSAdminUtil.repaintComp(mGracePeriodMinLabel);
+ }
+ }
+ }
+
+ super.actionPerformed(e);
+ }
+
+ private void enableFields() {
+ boolean enable = mEnableCRL.isSelected();
+ Color color = (enable)? mActiveColor: getBackground();
+
+ CMSAdminUtil.enableJTextField(mCRLGen, enable, color);
+ mCRLGenLabel.setEnabled(enable);
+ CMSAdminUtil.repaintComp(mCRLGenLabel);
+ mDeltaGenLabel.setEnabled(enable);
+ CMSAdminUtil.repaintComp(mDeltaGenLabel);
+
+ mExtendNextUpdateLabel.setEnabled(enable);
+ CMSAdminUtil.repaintComp(mExtendNextUpdateLabel);
+ mExtendNextUpdate.setEnabled(enable);
+ CMSAdminUtil.repaintComp(mExtendNextUpdate);
+
+ mAlways.setEnabled(enable);
+ CMSAdminUtil.repaintComp(mAlways);
+
+ mDaily.setEnabled(enable);
+ CMSAdminUtil.repaintComp(mDaily);
+
+ boolean enable1 = enable && mDaily.isSelected();
+ Color color1 = (enable1)? mActiveColor: getBackground();
+ CMSAdminUtil.enableJTextField(mDailyAt, enable1, color1);
+
+ mEnableFreq.setEnabled(enable);
+ CMSAdminUtil.repaintComp(mEnableFreq);
+
+ boolean enable2 = enable && mEnableFreq.isSelected();
+ Color color2 = (enable2)? mActiveColor: getBackground();
+ CMSAdminUtil.enableJTextField(mFrequency, enable2, color2);
+ mMinLabel.setEnabled(enable2);
+ CMSAdminUtil.repaintComp(mMinLabel);
+
+ boolean enable3 = enable1 || enable2;
+ Color color3 = (enable3)? mActiveColor: getBackground();
+ CMSAdminUtil.enableJTextField(mGracePeriod, enable3, color3);
+ mGracePeriodLabel.setEnabled(enable3);
+ CMSAdminUtil.repaintComp(mGracePeriodLabel);
+ mGracePeriodMinLabel.setEnabled(enable3);
+ CMSAdminUtil.repaintComp(mGracePeriodMinLabel);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSCertSettingPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSCertSettingPanel.java
new file mode 100644
index 000000000..975ba97da
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSCertSettingPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * CA Certificate Setting
+ *
+ * @author Christine Ho
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public abstract class CMSCertSettingPanel extends CMSBaseTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ protected JLabel _mapper, _publisher;
+ protected CMSBaseResourceModel _model;
+ protected AdminConnection _admin;
+ protected JButton mMapper, mPublisher;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ public CMSCertSettingPanel(String panelName, CMSTabPanel parent) {
+ super(panelName, parent);
+ _model = parent.getResourceModel();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Actual UI construction
+ */
+ public void init() {
+ _admin = _model.getServerInfo().getAdmin();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ CMSAdminUtil.resetGBC(gbc);
+ mCenterPanel.setLayout(gb);
+
+ JPanel mapPanel = new JPanel();
+ GridBagLayout gb2 = new GridBagLayout();
+ mapPanel.setLayout(gb2);
+ mapPanel.setBorder(makeTitledBorder("MAPPER"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(mapPanel, gbc);
+ mCenterPanel.add(mapPanel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel mapperLabel = makeJLabel("MAPPER");
+ _mapper = new JLabel("");
+ mMapper = makeJButton("MAPPER");
+ addEntryField(mapPanel, mapperLabel, _mapper, mMapper , gbc);
+
+ JPanel certSetting = new JPanel();
+ GridBagLayout gb1 = new GridBagLayout();
+ certSetting.setLayout(gb1);
+ certSetting.setBorder(makeTitledBorder("PUBLISHER"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(certSetting, gbc);
+ mCenterPanel.add(certSetting);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel publisherLabel = makeJLabel("PUBLISHER");
+ _publisher = new JLabel("");
+ mPublisher = makeJButton("PUBLISHER");
+ addEntryField(certSetting, publisherLabel, _publisher, mPublisher, gbc);
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+
+ protected int getIndex(String value, String[] source) {
+ for (int i=0; i<source.length; i++) {
+ if (value.equals(source[i]))
+ return i;
+ }
+ return -1;
+ }
+
+ /**
+ * Add 3 components in the same row to a panel, assumed to be using
+ * GridBagLayout. Customized for the LDAP certificate mappings/publishing
+ * UI.
+ */
+ protected void addEntryField(JPanel panel, JComponent field1,
+ JComponent field2, JComponent field3, GridBagConstraints gbc) {
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.gridx = 0;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ panel.add( field1, gbc );
+
+ gbc.gridx++;
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = 1;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,0);
+ panel.add(field2, gbc);
+
+ gbc.gridx++;
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ 0,DIFFERENT_COMPONENT_SPACE);
+ panel.add( field3, gbc );
+ }
+
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSCipherPreferenceDialog.java b/base/console/src/com/netscape/admin/certsrv/config/CMSCipherPreferenceDialog.java
new file mode 100644
index 000000000..69e208be5
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSCipherPreferenceDialog.java
@@ -0,0 +1,201 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.security.CipherPreferenceDialog;
+import com.netscape.management.client.util.*;
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * Allows user to select the SSL cipher preferences.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class CMSCipherPreferenceDialog extends AbstractDialog {
+
+ CMSSSL2CipherPreference ssl2CipherPref = null;
+ CMSSSL3CipherPreference ssl3CipherPref = null;
+
+ public final static int SSL2 = 1;
+ public final static int SSL3 = 2;
+ private JPanel cipherPreferencePane;
+ boolean modified = true;
+ private static final ResourceSet mHelpResource =
+ new ResourceSet("com.netscape.admin.certsrv.certsrv-help");
+ Help help;
+
+ public CMSCipherPreferenceDialog(JFrame parent, boolean isDomestic) {
+ this(parent, isDomestic, false);
+ }
+
+ public CMSCipherPreferenceDialog(JFrame parent, boolean isDomestic,
+ boolean hasFortezza) {
+ this(parent, isDomestic, hasFortezza, SSL2|SSL3);
+ }
+
+ public CMSCipherPreferenceDialog(JFrame parent, boolean isDomestic,
+ boolean hasFortezza, int SSLVersion) {
+
+ super(parent, "", true, OK | CANCEL | HELP);
+ cipherPreferencePane = new JPanel();
+ cipherPreferencePane.setLayout(new BoxLayout(cipherPreferencePane, BoxLayout.Y_AXIS));
+ if ((SSL2 & SSLVersion) == SSL2) {
+ ssl2CipherPref = new CMSSSL2CipherPreference(isDomestic);
+ cipherPreferencePane.add(ssl2CipherPref);
+ }
+
+ if ((SSL3 & SSLVersion) == SSL3) {
+ ssl3CipherPref = new CMSSSL3CipherPreference(isDomestic, hasFortezza);
+ cipherPreferencePane.add(ssl3CipherPref);
+ }
+
+ cipherPreferencePane.add(Box.createRigidArea(new Dimension(0,4)));
+ getContentPane().add(cipherPreferencePane);
+ pack();
+ }
+
+ public void removeSSLVersion(int sslVersion) {
+ switch (sslVersion) {
+ case SSL2:
+ cipherPreferencePane.remove(ssl2CipherPref);
+ break;
+ case SSL3:
+ cipherPreferencePane.remove(ssl3CipherPref);
+ break;
+ }
+ pack();
+ }
+
+ public boolean isCipherEnabled(String cipher) {
+ return (((ssl2CipherPref == null)?false:ssl2CipherPref.isCipherEnabled(cipher))||
+ ((ssl3CipherPref == null)?false:ssl3CipherPref.isCipherEnabled(cipher)));
+ }
+
+ public void setCipherEnabled(String cipher, boolean enable) {
+ if (ssl2CipherPref != null) {
+ ssl2CipherPref.setCipherEnabled(cipher, enable);
+ }
+ if (ssl3CipherPref != null) {
+ ssl3CipherPref.setCipherEnabled(cipher, enable);
+ }
+ }
+
+ public String[] getSSLPreference(int sslVersion) {
+ String[] cipher = null;
+ switch(sslVersion) {
+ case SSL2:
+ cipher = ssl2CipherPref.getCipherList();
+ break;
+ case SSL3:
+ cipher = ssl3CipherPref.getCipherList();
+ break;
+ default:
+ break;
+ }
+
+ return cipher;
+ }
+
+ public boolean isSSLEnabled(int sslVersion) {
+ boolean enable = false;
+ switch (sslVersion) {
+ case SSL2:
+ enable = ssl2CipherPref.isEnabled();
+ break;
+
+ case SSL3:
+ enable = ssl3CipherPref.isEnabled();
+ break;
+
+ default:
+ break;
+ }
+
+ return enable;
+ }
+
+ public void setSSLEnabled(int sslVersion, boolean enable) {
+ switch (sslVersion) {
+ case SSL2:
+ ssl2CipherPref.setEnabled(enable);
+ break;
+
+ case SSL3:
+ ssl3CipherPref.setEnabled(enable);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ public boolean isModified() {
+ return modified;
+ }
+
+ public void reset() {
+ if (ssl2CipherPref != null)
+ ssl2CipherPref.reset();
+
+ if (ssl3CipherPref != null)
+ ssl3CipherPref.reset();
+ }
+
+ public void setSaved() {
+ if (ssl2CipherPref != null) {
+ ssl2CipherPref.setSaved();
+ }
+
+ if (ssl3CipherPref != null) {
+ ssl3CipherPref.setSaved();
+ }
+ }
+
+ public void setSaved(boolean saved) {
+ if (saved) {
+ if (ssl2CipherPref != null) {
+ ssl2CipherPref.setSaved();
+ }
+ if (ssl3CipherPref != null) {
+ ssl3CipherPref.setSaved();
+ }
+ }
+ }
+
+ protected void cancelInvoked() {
+ reset();
+ modified = false;
+ super.cancelInvoked();
+ }
+
+ protected void okInvoked() {
+ modified = (((ssl2CipherPref==null)?false:ssl2CipherPref.isModified()) ||
+ ((ssl3CipherPref==null)?false:ssl3CipherPref.isModified()));
+ setSaved();
+ super.okInvoked();
+ }
+
+ protected void helpInvoked() {
+ new Help(mHelpResource).help("configuration-overview");
+// help.help("SSL", "Preference");
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSCipherPreferencePane.java b/base/console/src/com/netscape/admin/certsrv/config/CMSCipherPreferencePane.java
new file mode 100644
index 000000000..88faf2a71
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSCipherPreferencePane.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.security.*;
+import java.awt.event.*;
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.plaf.*;
+import com.netscape.management.nmclf.*;
+import com.netscape.admin.certsrv.*;
+
+/**
+ * Constructs a Cipher preference pane.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class CMSCipherPreferencePane extends AbstractCipherPreference implements ICipherConstants {
+ private JCheckBox on;
+ private JPanel top = new JPanel();
+ boolean _ismodified;
+ boolean oldValue;
+
+ public CMSCipherPreferencePane(IAbstractCipherSet cipherSet) {
+ this(cipherSet, true);
+ }
+
+ public CMSCipherPreferencePane(IAbstractCipherSet cipherSet, boolean enabled) {
+ oldValue = enabled;
+ on = new JCheckBox(cipherSet.getTitle(), enabled);
+ on.setActionCommand("ENABLED");
+ on.addActionListener(new actionListener());
+ top.setLayout(new BoxLayout(top, BoxLayout.Y_AXIS));
+ top.add(on);
+ setBorder(new CompoundBorder(new ToggleBorder(top, SwingConstants.TOP),
+ new EmptyBorder(0, SuiConstants.COMPONENT_SPACE, SuiConstants.COMPONENT_SPACE, 0)));
+ add(top);
+ initialize(cipherSet);
+ add(Box.createHorizontalGlue());
+ }
+
+ class actionListener implements ActionListener{
+ public void actionPerformed(ActionEvent e) {
+ if (e.getActionCommand().equals("ENABLED")) {
+ _ismodified = true;
+ setEnableAll(on.isSelected());
+ }
+ }
+ }
+
+ public void setEnabled(boolean enable) {
+ on.setSelected(enable);
+ super.setEnableAll(enable);
+ }
+
+ public boolean isEnabled() {
+ return on.isSelected();
+ }
+
+
+ class ToggleBorder extends EtchedBorder {
+ private JComponent _switchPanel;
+ private int _switchAlign;
+
+ public ToggleBorder(JComponent sp, int align) {
+ _switchPanel = sp;
+ _switchAlign = align;
+ }
+
+ public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
+ Color save = g.getColor();
+ int top = y + (_switchPanel.getHeight() >> 1);
+ int new_height = height - top;
+ BorderUIResource.getEtchedBorderUIResource().paintBorder(c, g, x, top, width, new_height);
+ }
+ }
+
+ public boolean isModified() {
+ return (_ismodified | super.isModified());
+ }
+
+ public void reset() {
+ setEnabled(oldValue);
+ _ismodified = false;
+ super.reset();
+ }
+
+ public void setSaved() {
+ oldValue = isEnabled();
+ _ismodified = false;
+ super.setSaved();
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSEAGeneralPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSEAGeneralPanel.java
new file mode 100644
index 000000000..2d35133df
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSEAGeneralPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * KRA General Setting
+ *
+ * @author Ade Lee
+ * @version $Revision: 1211 $, $Date: 2010-08-18 13:15:37 -0400 (Wed, 18 Aug 2010) $
+ */
+public class CMSEAGeneralPanel extends CMSBaseTab implements ItemListener {
+
+ private static String PANEL_NAME = "EAGENERAL";
+ private static CMSBaseResourceModel mModel;
+ protected AdminConnection mAdmin;
+ private JTextField mNumberOfAgentsText;
+ private CMSTabPanel mParent;
+ private static final String EAHELPINDEX =
+ "configuration-ea-general-help";
+
+ public CMSEAGeneralPanel(CMSTabPanel parent) {
+ super(PANEL_NAME, parent);
+ mModel = parent.getResourceModel();
+ mParent = parent;
+ mHelpToken = EAHELPINDEX;
+ }
+
+ public void init() {
+ Debug.println("CMSEAGeneral: init()");
+ mAdmin = mModel.getServerInfo().getAdmin();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ CMSAdminUtil.resetGBC(gbc);
+ mCenterPanel.setLayout(gb);
+
+ JPanel agentsPanel = new JPanel();
+ GridBagLayout gb2 = new GridBagLayout();
+ agentsPanel.setLayout(gb2);
+ agentsPanel.setBorder(makeTitledBorder("AGENTS"));
+
+ CMSAdminUtil.resetGBC(gbc);
+ mCenterPanel.setLayout(gb);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(agentsPanel, gbc);
+ mCenterPanel.add(agentsPanel);
+
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel numberLabel = makeJLabel("NUMBER");
+ mNumberOfAgentsText = makeJTextField(30);
+ CMSAdminUtil.addEntryField(agentsPanel, numberLabel, mNumberOfAgentsText, gbc);
+
+ refresh();
+ }
+
+ public void refresh() {
+ mModel.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_NO_OF_REQUIRED_RECOVERY_AGENTS, "1");
+
+ try {
+ NameValuePairs val = mAdmin.read(DestDef.DEST_KRA_ADMIN,
+ ScopeDef.SC_GENERAL, Constants.RS_ID_CONFIG, nvps);
+
+ populate(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ }
+
+ protected void populate(NameValuePairs nvps) {
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name);
+ if (name.equals(Constants.PR_NO_OF_REQUIRED_RECOVERY_AGENTS)) {
+ mNumberOfAgentsText.setText(value);
+ }
+ }
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ super.actionPerformed(e);
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ String numberOfAgents = mNumberOfAgentsText.getText().trim();
+
+ if (numberOfAgents.equals("")) {
+ showMessageDialog("BLANKFIELD");
+ return false;
+ }
+
+ try {
+ int num = Integer.parseInt(numberOfAgents);
+ if (num < 1) {
+ showMessageDialog("NUMBERRANGE");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ showMessageDialog("NUMBERFORMAT");
+ return false;
+ }
+
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_NO_OF_REQUIRED_RECOVERY_AGENTS,
+ numberOfAgents);
+
+ mModel.progressStart();
+ try {
+ mAdmin.modify(DestDef.DEST_KRA_ADMIN,
+ ScopeDef.SC_GENERAL, Constants.RS_ID_CONFIG, nvps);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ return false;
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSEncryptionPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSEncryptionPanel.java
new file mode 100644
index 000000000..913974eaf
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSEncryptionPanel.java
@@ -0,0 +1,835 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.management.client.console.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.certsrv.common.*;
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import java.awt.event.*;
+import javax.swing.border.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.keycert.*;
+import com.netscape.admin.certsrv.managecert.*;
+
+/**
+ * Encryption panel used for setup server encryption options.
+ * This is a wrapper class that emulates the CMSBaseTab API
+ * calls.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class CMSEncryptionPanel extends CMSBaseTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static String PANEL_NAME = "ENCRYPTION";
+ private ConsoleInfo mConsoleInfo;
+ private CMSServerInfo mServerInfo;
+ private AdminConnection mConnection;
+ private JPanel mEncryptPane;
+ private JComboBox mSelection, mTokenList, mCertList;
+ private Hashtable mCertMapping; //maps the function list items to tags
+ private String mSelectedItem, mSelectedToken, mSelectedCert;
+ private JButton mWizard, mCipherPref, mSetup;
+ private Hashtable mTokenCertList; //container for tokens and certs (Vector)
+ private boolean mIsDomestic = false;
+ private boolean mHasFortezza = false;
+ private Vector mCipherPrefStore;
+ private CMSCipherPreferenceDialog mCipherDialog;
+ private boolean updateFlag = false;
+ private boolean mSelectionIgnore = false;
+ private boolean mWarningOn = false;
+ private static final String HELPINDEX =
+ "configuration-system-encryption-help";
+
+ /**=========================================================
+ * constructors
+ * @param parent the parent panel
+ * @see com.netscape.admin.certsrv.config.CMSTabPanel
+ *==========================================================*/
+ public CMSEncryptionPanel(CMSTabPanel parent) {
+ super(PANEL_NAME, parent);
+ mConsoleInfo = parent.getResourceModel().getConsoleInfo();
+ mServerInfo = parent.getResourceModel().getServerInfo();
+ mConnection = mServerInfo.getAdmin();
+ mCertMapping = new Hashtable();
+ mTokenCertList = new Hashtable();
+ mCipherPrefStore = new Vector();
+ mHelpToken = HELPINDEX;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Actual Instanciation of the UI components
+ */
+ public void init() {
+ Debug.println("EncryptionPanel: init()");
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ CMSAdminUtil.resetGBC(gbc);
+ mCenterPanel.setLayout(gb);
+
+ //certificate settings
+ JPanel top = new JPanel();
+ GridBagLayout gb2 = new GridBagLayout();
+ top.setLayout(gb2);
+ top.setBorder( new CompoundBorder(
+ BorderFactory.createTitledBorder(
+ mResource.getString("ENCRYPTION_BORDER_CERT_LABEL")),
+ new EmptyBorder(-3,
+ 0,
+ DIFFERENT_COMPONENT_SPACE - 3,
+ 0)));
+
+ //add selection combobox
+ JLabel label1 = makeJLabel("SELECT");
+ mSelection = new JComboBox();
+ updateCertSelection(); //dynamically generate this list
+ addTopEntryField(top, label1, mSelection, gbc);
+ if (mSelection.getItemCount()>0) {
+ mSelection.setSelectedIndex(0);
+ mSelectedItem = (String) mSelection.getSelectedItem();
+ } else {
+ //disable if nothing there
+ mSelection.setEnabled(false);
+ }
+ mSelection.addItemListener(this);
+
+ //add encryption panel
+ mEncryptPane = createCertEntry();
+ //mEncryptPane = new InnerEncryptionPane(mConsoleInfo);
+ //mEncryptPane.addEncryptionPaneListener(this);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ //gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,
+ COMPONENT_SPACE,0,COMPONENT_SPACE);
+ gb2.setConstraints(mEncryptPane, gbc);
+ top.add(mEncryptPane);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(top, gbc);
+ mCenterPanel.add(top);
+
+ mWizard = makeJButton("WIZARD");
+ mCipherPref = makeJButton("CIPHERPREF");
+ mSetup = makeJButton("SETUP");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ //addButtonEntryField(mCenterPanel, mSetup, mWizard, mCipherPref, gbc);
+ addButtonEntryField(mCenterPanel, mSetup, mWizard, gbc);
+ //addButtonEntryField(mCenterPanel, mCipherPref, gbc);
+
+ /* retrieve data from server and
+ * feed data into mEncryptionPane for display ...
+ */
+ refresh();
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ if (mWarningOn) {
+ String errorMsg =
+ mResource.getString(mPanelName+"_LABEL_WARNING_LABEL");
+ JOptionPane.showMessageDialog(new JFrame(), errorMsg, "Warning",
+ JOptionPane.WARNING_MESSAGE,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_WARN_ICON));
+ mWarningOn = false;
+ return false;
+ }
+
+ //save current changes if modified
+ saveChanges((String) mSelection.getSelectedItem());
+
+ //construct NVP parameters
+ NameValuePairs nvp = new NameValuePairs();
+ for (Enumeration e = mCertMapping.keys() ; e.hasMoreElements() ;) {
+ CipherEntryData data =
+ (CipherEntryData)mCertMapping.get(e.nextElement());
+ nvp.put(data.getTagName(), data.getTokenName() + "," + data.getCertName());
+ }
+
+ if (updateCertMap(nvp)) {
+ mWarningOn = false;
+ clearDirtyFlag();
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if reset successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ mWarningOn = false;
+ return true;
+ }
+
+ /**
+ * retrieve data from server and
+ * feed data into mEncryptPane for display ...
+ * refresh the panel and update data
+ */
+ public void refresh() {
+
+ //call server to get the encryption settings
+ NameValuePairs response;
+ try {
+ response = updateSecurityInformation();
+ } catch(EAdminException e) {
+ //display error dialog
+ CMSAdminUtil.showErrorDialog(mParent.getResourceModel().getFrame(), mResource,
+ e.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+
+ //setup the data and UI
+ updateFlag = true;
+ cleanup();
+ setupDataContainer(response);
+ setupComboSelection();
+ updateFlag = false;
+
+ clearDirtyFlag();
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+/*
+ if (e.getSource().equals(mSetup)) {
+ Debug.println("Configure cert");
+ InstallWizardInfo info = new InstallWizardInfo();
+ InstallWizard wizard = new InstallWizard(
+ mParent.getResourceModel().getFrame(), info);
+ return;
+ }
+*/
+ if (e.getSource().equals(mSetup)) {
+ ManageCertDialog manageDialog =
+ new ManageCertDialog(mParent.getResourceModel().getFrame());
+ manageDialog.showDialog(mParent.getResourceModel().getServerInfo().getAdmin());
+ }
+ if (e.getSource().equals(mWizard)) {
+ Debug.println("Wizard");
+
+ //XXX launch OUR OWN wizard
+ CertSetupWizardInfo info = new
+ CertSetupWizardInfo(mConnection, mConsoleInfo);
+ CertSetupWizard wizard = new CertSetupWizard(mParent.getResourceModel(), info);
+ // mParent.getResourceModel().getFrame(), info);
+ //KeyCertWizard wizard = new KeyCertWizard(mConnection);
+
+ //XXX we should update the settings to reflect the changes
+
+
+ return;
+ }
+ if (e.getSource().equals(mCipherPref)) {
+ Debug.println("Wizard");
+
+ if (mCipherDialog == null) {
+ mCipherDialog = new CMSCipherPreferenceDialog(mParent.mModel.getFrame(),
+ mIsDomestic,
+ mHasFortezza,
+ CMSCipherPreferenceDialog.SSL2|CMSCipherPreferenceDialog.SSL3);
+
+ }
+
+ refresh();
+ setupCipherDialog(mCipherDialog);
+
+ mCipherDialog.show();
+
+ if (!mCipherDialog.isModified())
+ return;
+
+ //Save the cipher settings
+ StringBuffer buf = new StringBuffer();
+
+ if (mCipherDialog.isSSLEnabled(mCipherDialog.SSL2)) {
+ String[] v2 = mCipherDialog.getSSLPreference(mCipherDialog.SSL2);
+ for (int i=0; i< v2.length; i++) {
+ if (mCipherDialog.isCipherEnabled(v2[i])) {
+ if (buf.length()>0)
+ buf.append(",");
+ buf.append(v2[i]);
+ }
+ }
+ }
+
+ if (mCipherDialog.isSSLEnabled(mCipherDialog.SSL3)) {
+ String[] v3 = mCipherDialog.getSSLPreference(mCipherDialog.SSL3);
+ for (int i=0; i< v3.length; i++) {
+ if (mCipherDialog.isCipherEnabled(v3[i])) {
+ if (buf.length()>0)
+ buf.append(",");
+ buf.append(v3[i]);
+ }
+ }
+ }
+
+ updateCipherPref(buf.toString());
+
+ //save the new settings
+ mCipherDialog.setSaved(true);
+
+ return;
+ }
+ }
+
+ //== ItemListener ==
+ public void itemStateChanged(ItemEvent e){
+
+ if (e.getSource().equals(mSelection)) {
+ if (e.getStateChange() == e.SELECTED) {
+ if (!mSelectionIgnore) {
+ updateFlag = true;
+ saveChanges(mSelectedItem);
+ mSelectedItem = (String) mSelection.getSelectedItem();
+ setupComboSelection();
+ updateFlag = false;
+ }
+ }
+ } else if (e.getSource().equals(mTokenList)) {
+ if ( (!updateFlag) && (e.getStateChange() == e.SELECTED) ){
+ Debug.println("Token Selected");
+ setDirtyFlag();
+ updateFlag = true;
+ setupCertCombo();
+ updateFlag = false;
+ }
+ } else if (e.getSource().equals(mCertList)) {
+ if ( (!updateFlag) && (e.getStateChange() == e.SELECTED) ){
+ Debug.println("Cert Selected");
+ saveChanges(mSelectedItem);
+ setupComboSelection();
+ setDirtyFlag();
+ }
+ }
+ mWarningOn = true;
+ }
+
+ /*==========================================================
+ * Private Methods
+ *==========================================================*/
+
+ //save the mappings if changes made
+ private void saveChanges(String entry) {
+ if ( (!mSelectedToken.equals((String)mTokenList.getSelectedItem())) ||
+ (!mSelectedCert.equals((String)mCertList.getSelectedItem())) ) {
+
+ CipherEntryData data = (CipherEntryData) mCertMapping.get(entry);
+ data.setData((String)mTokenList.getSelectedItem(),
+ (String)mCertList.getSelectedItem());
+ }
+ }
+
+ //cleanup the
+ private void cleanup() {
+ mTokenCertList.clear();
+ mCipherPrefStore.removeAllElements();
+ mTokenList.removeAllItems();
+ mCertList.removeAllItems();
+ }
+
+ //setup the cipher dialog
+ private void setupCipherDialog(CMSCipherPreferenceDialog dialog) {
+ Debug.println("setupCipherDialog");
+ dialog.setSSLEnabled(dialog.SSL3,true);
+
+ //set selected/unselected ciphers
+ String[] v2 = dialog.getSSLPreference(dialog.SSL2);
+
+ if (v2.length <= 0)
+ dialog.setSSLEnabled(dialog.SSL2,false);
+ else
+ dialog.setSSLEnabled(dialog.SSL2,true);
+
+ for (int i=0; i< v2.length; i++) {
+ if (mCipherPrefStore.contains(v2[i])) {
+ //Debug.println("setEnable: "+v2[i]);
+ dialog.setCipherEnabled(v2[i], true);
+ } else {
+ //Debug.println("setDisable: "+v2[i]);
+ dialog.setCipherEnabled(v2[i], false);
+ }
+ }
+ String[] v3 = dialog.getSSLPreference(dialog.SSL3);
+ if (v3.length <= 0)
+ dialog.setSSLEnabled(dialog.SSL3,false);
+ else
+ dialog.setSSLEnabled(dialog.SSL3,true);
+
+ for (int i=0; i< v3.length; i++) {
+ if (mCipherPrefStore.contains(v3[i])) {
+ //Debug.println("setEnable: "+v3[i]);
+ dialog.setCipherEnabled(v3[i], true);
+ } else {
+ //Debug.println("setDisable: "+v3[i]);
+ dialog.setCipherEnabled(v3[i], false);
+ }
+ }
+
+ mCipherDialog.setSaved(true);
+ }
+
+ //initialize the data containers
+ private void setupDataContainer(NameValuePairs response) {
+
+ //setup security version flag
+ String version = response.get(Constants.PR_CIPHER_VERSION);
+ if ( (version != null) && (version.equals(
+ Constants.PR_CIPHER_VERSION_DOMESTIC)) ) {
+ mIsDomestic = true;
+ }
+
+ //setup fortezza flag
+ String fortezza = response.get(Constants.PR_CIPHER_FORTEZZA);
+ if ( (fortezza != null) && (fortezza.equalsIgnoreCase("TRUE")) ){
+ mHasFortezza = true;
+ }
+
+ //setup cipher preference settings
+ String cipherpref = response.get(Constants.PR_CIPHER_PREF);
+ //Debug.println("cipher preference: "+cipherpref);
+ if ( (cipherpref != null) && (!cipherpref.trim().equals("")) ) {
+ StringTokenizer tokenizer = new StringTokenizer(cipherpref, ",");
+ while (tokenizer.hasMoreTokens()) {
+ String pref = tokenizer.nextToken().trim();
+ //Debug.println("Add cipher: "+pref);
+ mCipherPrefStore.addElement(pref);
+ }
+ } else {
+ Debug.println("ERROR: CMSEncryptionPanel: setupDataContainer()- no cert pref list");
+ }
+
+ //setup the cipher entry data - loop through table and retrieve
+ //the current mappings
+ mSelectionIgnore = true;
+ for (Enumeration e = mCertMapping.keys() ; e.hasMoreElements() ;) {
+ String name = (String) e.nextElement();
+ CipherEntryData data = (CipherEntryData)mCertMapping.get(name);
+ String value = response.get(data.getTagName());
+ if ( (value != null) && (!value.trim().equals("")) ) {
+ StringTokenizer tokenizer = new StringTokenizer(value, ",");
+ try {
+ String token = tokenizer.nextToken().trim();
+ String cert = tokenizer.nextToken().trim();
+ data.setData(token, cert);
+ } catch(Exception ex) {
+ Debug.println("ERROR: CMSEncryptionPanel: setupDataContainer()- no token/cert not complete");
+ }
+ } else {
+ Debug.println("ERROR: CMSEncryptionPanel: setupDataContainer()- no token/cert for:"+data.getTagName());
+ mCertMapping.remove(name);
+ mSelection.removeItem(name);
+ Debug.println("RECOVER: CMSEncryptionPanel: setupDataContainer()- "+name+" removed from selection");
+ }
+ }
+ mSelectionIgnore = false;
+
+ //setup the token-cert list data table
+ String tokenlist = response.get(Constants.PR_TOKEN_LIST);
+ if ( (tokenlist != null) && (!tokenlist.trim().equals("")) ) {
+ StringTokenizer tokenizer = new StringTokenizer(tokenlist, ",");
+ while (tokenizer.hasMoreTokens()) {
+ String token = tokenizer.nextToken().trim();
+ Debug.println("Token: "+token);
+
+ //get the certificate associated with this token
+ String certList = response.get(Constants.PR_TOKEN_PREFIX + token);
+ Vector certVector = new Vector();
+ if ( (certList != null) && (!certList.trim().equals("")) ) {
+ StringTokenizer tokenizer2 = new StringTokenizer(certList, ",");
+ while (tokenizer2.hasMoreTokens()) {
+ certVector.addElement(tokenizer2.nextToken().trim());
+ }
+ } else {
+ Debug.println("WARNING: CMSEncryptionPanel: setupDataContainer()- no certlist for: "+token);
+ }
+
+ //set the token-cert to hashtable
+ mTokenCertList.put(token, certVector);
+ mTokenList.addItem(token);
+ }
+ } else {
+ Debug.println("ERROR: CMSEncryptionPanel: setupDataContainer()- no tokenlist");
+ }
+
+ //setup the initial combobox selection
+ String newToken = (String) mTokenList.getSelectedItem();
+ mSelectedToken = newToken;
+ mCertList.removeAllItems();
+ Vector list = (Vector) mTokenCertList.get(newToken);
+ for (int i=0; i< list.size(); i++)
+ mCertList.addItem(list.elementAt(i));
+ }
+
+ //setup combobox selection
+ private void setupComboSelection() {
+ //get current function selection
+ CipherEntryData data = (CipherEntryData) mCertMapping.get(mSelection.getSelectedItem());
+
+ //select correct token from the token list
+ String oldToken = (String) mTokenList.getSelectedItem();
+ String newToken = data.getTokenName();
+ if (!oldToken.equals(newToken)) {
+ mTokenList.setSelectedItem(newToken);
+ mSelectedToken = newToken;
+ setupCertCombo();
+ }
+ //select correct certiicate from the cert list
+ mCertList.setSelectedItem(data.getCertName());
+ mSelectedCert = data.getCertName();
+ }
+
+ //setup the certlist combo
+ private void setupCertCombo() {
+ String newToken = (String) mTokenList.getSelectedItem();
+ mCertList.removeAllItems();
+ Vector list = (Vector) mTokenCertList.get(newToken);
+ for (int i=0; i< list.size(); i++)
+ mCertList.addItem(list.elementAt(i));
+ }
+
+ //creating the certificate mapping UI components
+ private JPanel createCertEntry() {
+ JPanel panel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ CMSAdminUtil.resetGBC(gbc);
+ panel.setLayout(gb);
+
+ //set border
+ panel.setBorder( new CompoundBorder(
+ BorderFactory.createTitledBorder(mResource.getString("ENCRYPTION_BORDER_MAPTO_LABEL")),
+ new EmptyBorder(-3,
+ 0,
+ CMSAdminUtil.DIFFERENT_COMPONENT_SPACE,
+ 0)));
+
+ //add components
+ mTokenList = new JComboBox();
+ mTokenList.addItemListener(this);
+ mCertList = new JComboBox();
+ mCertList.addItemListener(this);
+ JLabel label1 = makeJLabel("TOKEN");
+ JLabel label2 = makeJLabel("CERTIFICATE");
+ CMSAdminUtil.addEntryField(panel, label1, mTokenList, label2, mCertList, gbc);
+ return panel;
+ }
+
+ /**
+ * The certificates used by each subsystem are stored as cert list
+ * strings in the resource file using the PR_ prefix tags.
+ */
+ private void updateCertSelection() {
+ //get installed subsystem
+ Vector v = mServerInfo.getInstalledSubsystems();
+
+ //add default system certificate list
+ String certs;
+ try {
+ certs = mResource.getString("ENCRYPTION_SERVER_CERTS");
+ } catch (MissingResourceException e) {
+ Debug.println("ERROR: unable retrieving server default cert list");
+ certs = "";
+ }
+ if (!certs.trim().equals("")) {
+ StringTokenizer tokenizer = new StringTokenizer(certs, ",");
+ while (tokenizer.hasMoreTokens()) {
+ String certname = tokenizer.nextToken().trim();
+ loadCertList(certname);
+ }
+ }
+
+ //create additional subsystem certificate list
+ for (int i=0; i< v.size(); i++) {
+ String name = (String)v.elementAt(i);
+ try {
+ String certlist = mResource.getString(PANEL_NAME+"_"+name+"_CERTS");
+ if (!certlist.trim().equals("")) {
+ StringTokenizer tokenizer = new StringTokenizer(certlist, ",");
+ while (tokenizer.hasMoreTokens()) {
+ String certname = tokenizer.nextToken().trim();
+ loadCertList(certname);
+ }
+ }
+ } catch (MissingResourceException e) {
+ Debug.println("ERROR: unable retrieving subsystem certificate list: "+name);
+ }
+ }
+ }
+
+ //register the certificate and mapping entry
+ private void loadCertList(String certTag) {
+ //add to selection list
+ String name;
+ try {
+ name = mResource.getString("ENCRYPTION_COMBOBOX_SELECT_VALUE_"+certTag);
+ } catch (MissingResourceException e) {
+ Debug.println("ERROR: cert resource not found: "+certTag);
+ return;
+ }
+ mSelection.addItem(name);
+ mCertMapping.put(name, new CipherEntryData(certTag));
+ }
+
+ private static void addTopEntryField(JPanel panel, JComponent label,
+ JComponent field, GridBagConstraints gbc) {
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.gridx = 0;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ panel.add( label, gbc );
+
+ gbc.gridx++;
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ 0,DIFFERENT_COMPONENT_SPACE);
+ panel.add( field, gbc );
+ }
+
+ private static void addButtonEntryField(JPanel panel,
+ JComponent field, GridBagConstraints gbc) {
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.gridx = 0;
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,0);
+ //gbc.insets = new Insets(DIFFERENT_COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ panel.add(new JLabel(""));
+
+ gbc.gridx++;
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.insets = new Insets(DIFFERENT_COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,
+ // 0,DIFFERENT_COMPONENT_SPACE);
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ 0,COMPONENT_SPACE);
+ panel.add( field, gbc );
+ }
+
+ private static void addButtonEntryField(JPanel panel, JComponent label,
+ JComponent field, GridBagConstraints gbc) {
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.gridx = 0;
+ gbc.anchor = gbc.NORTHEAST;
+ //gbc.insets = new Insets(DIFFERENT_COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,0);
+ panel.add(new JLabel(""));
+
+ gbc.gridx++;
+ gbc.weightx = 1.0;
+ panel.add( label, gbc );
+
+ gbc.gridx++;
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.insets = new Insets(DIFFERENT_COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,
+ //0,DIFFERENT_COMPONENT_SPACE);
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ 0,COMPONENT_SPACE);
+ panel.add( field, gbc );
+ }
+
+ private static void addButtonEntryField(JPanel panel, JComponent label,
+ JComponent field, JComponent field1, GridBagConstraints gbc) {
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.gridx = 0;
+ gbc.anchor = gbc.NORTHEAST;
+ //gbc.insets = new Insets(DIFFERENT_COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,0);
+ panel.add(new JLabel(""));
+
+ gbc.gridx++;
+ gbc.weightx = 1.0;
+ panel.add( label, gbc );
+
+ gbc.gridx++;
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ //gbc.gridwidth = gbc.REMAINDER;
+ //gbc.insets = new Insets(DIFFERENT_COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,
+ // 0,DIFFERENT_COMPONENT_SPACE);
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ 0,COMPONENT_SPACE);
+ panel.add( field, gbc );
+
+ gbc.gridx++;
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.insets = new Insets(DIFFERENT_COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,
+ // 0,DIFFERENT_COMPONENT_SPACE);
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ 0,COMPONENT_SPACE);
+ panel.add( field1, gbc );
+ }
+
+ /*==========================================================
+ * SEND STUFF TO SERVER
+ *==========================================================*/
+
+ //retrieve security information from the server side
+ private NameValuePairs updateSecurityInformation()
+ throws EAdminException
+ {
+ Debug.println("Get Security Information");
+ NameValuePairs nvp = new NameValuePairs();
+ nvp.put(Constants.PR_CIPHER_PREF, "");
+ nvp.put(Constants.PR_CIPHER_VERSION, "");
+ nvp.put(Constants.PR_CIPHER_FORTEZZA, "");
+ nvp.put(Constants.PR_TOKEN_LIST, "");
+
+ //create installed certificate list data request
+ for (Enumeration e = mCertMapping.elements(); e.hasMoreElements() ;) {
+ CipherEntryData data = (CipherEntryData)e.nextElement();
+ nvp.put(data.getTagName(), "");
+ }
+
+ NameValuePairs response;
+
+ response = mConnection.read(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_ENCRYPTION,
+ Constants.RS_ID_CONFIG,
+ nvp);
+
+ Debug.println("Received: "+response.toString());
+
+ return response;
+ }
+
+ //modify cipher preference
+ private void updateCipherPref(String list) {
+ Debug.println("Set Cipher Preference: "+list);
+
+ NameValuePairs nvp = new NameValuePairs();
+ nvp.put(Constants.PR_CIPHER_PREF, list);
+
+ //send to server
+ try {
+ mConnection.modify(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_ENCRYPTION,
+ Constants.RS_ID_CONFIG,
+ nvp);
+ } catch(EAdminException e) {
+ //display error dialog
+ CMSAdminUtil.showErrorDialog(mParent.getResourceModel().getFrame(), mResource,
+ e.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ }
+
+ //modify certificate mapping
+ private boolean updateCertMap(NameValuePairs config) {
+ Debug.println("Set Certificate Mapping: "+config.toString());
+
+ //send to server
+ try {
+ mConnection.modify(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_ENCRYPTION,
+ Constants.RS_ID_CONFIG,
+ config);
+ } catch(EAdminException e) {
+ //display error dialog
+ CMSAdminUtil.showErrorDialog(mParent.getResourceModel().getFrame(), mResource,
+ e.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ return false;
+ }
+
+ return true;
+ }
+
+}
+
+//internal data structure
+class CipherEntryData {
+
+ String mTag;
+ String mToken;
+ String mCert;
+
+ public CipherEntryData(String tag) {
+ mTag = tag;
+ }
+
+ public void setData(String token, String cert) {
+ mToken = token;
+ mCert = cert;
+ }
+
+ public String getCertName() {
+ return mCert;
+ }
+
+ public String getTokenName() {
+ return mToken;
+ }
+
+ public String getTagName() {
+ return mTag;
+ }
+
+ public String toString() {
+ return mTag+"-"+mToken+":"+mCert;
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSErrorLogPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSErrorLogPanel.java
new file mode 100644
index 000000000..23b4ececa
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSErrorLogPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+
+import java.awt.event.*;
+
+/**
+ * Error Log Setting Tab to be displayed at the right hand side
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class CMSErrorLogPanel extends CMSBaseLogPanel {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static String PANEL_NAME = "ERRORLOG";
+ private CMSTabPanel mParent;
+ private static final String HELPINDEX = "configuration-logs-error-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSErrorLogPanel(CMSTabPanel parent, boolean isNT) {
+ super(PANEL_NAME, parent);
+ mParent = parent;
+ mHelpToken = HELPINDEX;
+ mIsNT = isNT;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Actual Instantiation of the UI components
+ */
+ public void init() {
+ Debug.println("ErrorLogPanel: init()");
+ super.init();
+ refresh();
+ }
+
+ public void refresh() {
+ mModel.progressStart();
+ NameValuePairs nvp = new NameValuePairs();
+ nvp.put(Constants.PR_LOG_ENABLED, "");
+ nvp.put(Constants.PR_LOG_LEVEL, "");
+ nvp.put(Constants.PR_LOG_BUFFERSIZE, "");
+ //nvp.add(Constants.PR_LOG_EXPIRED_TIME, "");
+ //nvp.add(Constants.PR_LOG_FILENAME, "");
+ //nvp.add(Constants.PR_LOG_FLUSHINTERVAL, "");
+ nvp.put(Constants.PR_LOG_MAXFILESIZE, "");
+ nvp.put(Constants.PR_LOG_ROLLEROVER_INTERVAL, "");
+
+ try {
+ NameValuePairs val = mAdmin.read(DestDef.DEST_LOG_ADMIN,
+ ScopeDef.SC_ERRORLOG, Constants.RS_ID_CONFIG, nvp);
+
+ parseVals(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ }
+ setValues();
+ mModel.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+ }
+
+ private void parseVals(NameValuePairs nvp) {
+ if (nvp.get(Constants.PR_LOG_ENABLED).equalsIgnoreCase(
+ Constants.TRUE))
+ activateLog.setSelected(true);
+ else
+ activateLog.setSelected(false);
+ mLevel = Integer.parseInt(nvp.get(Constants.PR_LOG_LEVEL));
+ mlogBufSizTextData = nvp.get(Constants.PR_LOG_BUFFERSIZE);
+ mlogMaxSizTextData = nvp.get(Constants.PR_LOG_MAXFILESIZE);
+ int val =
+ Integer.parseInt(nvp.get(Constants.PR_LOG_ROLLEROVER_INTERVAL));
+ mFrequency = getRollOverIndex(val);
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ // check blank fields
+ if ((mlogMaxSizText.getText().trim().equals("")) ||
+ (mlogBufSizText.getText().trim().equals("")) ) {
+ showMessageDialog("BLANKFIELD");
+ return false;
+ }
+
+ String bufSize = mlogBufSizText.getText().trim();
+ String maxSize = mlogMaxSizText.getText().trim();
+
+ try {
+ int val1 = Integer.parseInt(bufSize);
+ int val2 = Integer.parseInt(maxSize);
+ if (val1 <= 0 || val2 <= 0) {
+ showMessageDialog("OUTOFRANGE");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ showMessageDialog("NUMBERFORMAT");
+ return false;
+ }
+
+ NameValuePairs nvp = new NameValuePairs();
+
+ if (activateLog.isSelected())
+ nvp.put(Constants.PR_LOG_ENABLED, Constants.TRUE);
+ else
+ nvp.put(Constants.PR_LOG_ENABLED, Constants.FALSE);
+ String str = "" + mLogLevel.getSelectedIndex();
+ nvp.put(Constants.PR_LOG_LEVEL, str);
+ nvp.put(Constants.PR_LOG_BUFFERSIZE, mlogBufSizText.getText().trim());
+ //nvp.add(Constants.PR_LOG_EXPIRED_TIME, "");
+ //nvp.add(Constants.PR_LOG_FILENAME, "");
+ //nvp.add(Constants.PR_LOG_FLUSHINTERVAL, "");
+ nvp.put(Constants.PR_LOG_MAXFILESIZE, mlogMaxSizText.getText().trim());
+
+ str = "" + getRollOverTime(mlogFQC.getSelectedIndex());
+ nvp.put(Constants.PR_LOG_ROLLEROVER_INTERVAL, str);
+
+ mModel.progressStart();
+ try {
+ mAdmin.modify(DestDef.DEST_LOG_ADMIN,
+ ScopeDef.SC_ERRORLOG, Constants.RS_ID_CONFIG, nvp);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ return false;
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+
+ /*==========================================================
+ * EVENT HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ super.actionPerformed(e);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSKRAAutoPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSKRAAutoPanel.java
new file mode 100644
index 000000000..f408e7297
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSKRAAutoPanel.java
@@ -0,0 +1,220 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * KRA recovery management tab
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class CMSKRAAutoPanel extends CMSBaseUGTab {
+ private static String PANEL_NAME = "AUTORECOVERYMGMT";
+ private CMSBaseResourceModel mModel;
+ private JButton mEnableAuto;
+ private AdminConnection mAdmin;
+ private String mEnableLabel;
+ private String mEnableTTip;
+ private String mDisableLabel;
+ private String mDisableTTip;
+ private JButton mRefresh, mHelp;
+ private JLabel mStatus;
+ private String mEnableStatus;
+ private String mEnableStatusTTip;
+ private String mDisableStatus;
+ private String mDisableStatusTTip;
+ private static final String HELPINDEX =
+ "configuration-kra-autorecovery-help";
+
+ public CMSKRAAutoPanel(CMSUGTabPanel parent) {
+ super(PANEL_NAME, parent.getResourceModel());
+ mModel = parent.getResourceModel();
+ mAdmin = mModel.getServerInfo().getAdmin();
+ mDisableTTip = mResource.getString(PANEL_NAME + "_BUTTON_"+
+ "DISABLEAUTO_TTIP");
+ mDisableLabel = mResource.getString(PANEL_NAME + "_BUTTON_"+
+ "DISABLEAUTO_LABEL");
+ mEnableTTip = mResource.getString(PANEL_NAME + "_BUTTON_"+
+ "ENABLEAUTO_TTIP");
+ mEnableLabel = mResource.getString(PANEL_NAME + "_BUTTON_"+
+ "ENABLEAUTO_LABEL");
+ mEnableStatus = mResource.getString(PANEL_NAME + "_LABEL_"+
+ "ENABLESTATUS_LABEL");
+ mEnableStatusTTip = mResource.getString(PANEL_NAME + "_LABEL_"+
+ "ENABLESTATUS_TTIP");
+ mDisableStatus = mResource.getString(PANEL_NAME + "_LABEL_"+
+ "DISABLESTATUS_LABEL");
+ mDisableStatusTTip = mResource.getString(PANEL_NAME + "_LABEL_"+
+ "DISABLESTATUS_TTIP");
+ mHelpToken = HELPINDEX;
+ }
+
+ protected JPanel createListPanel() {
+ JPanel mainPanel = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mainPanel.setLayout(gb3);
+
+ JPanel autoPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ autoPanel.setLayout(gb);
+ autoPanel.setBorder(makeTitledBorder("AUTO"));
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.gridwidth = gbc.REMAINDER;
+ gb3.setConstraints(autoPanel, gbc);
+ mainPanel.add(autoPanel);
+
+ // Auto recovery
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel autoLabel = makeJLabel("ENABLEAUTO");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridheight = gbc.REMAINDER;
+ gb.setConstraints(autoLabel, gbc);
+ autoPanel.add(autoLabel);
+
+ // labels
+ CMSAdminUtil.resetGBC(gbc);
+ mStatus = makeJLabel("ENABLESTATUS");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 0.0;
+ gbc.weighty = 0.0;
+ gbc.gridheight = gbc.REMAINDER;
+ gb.setConstraints(mStatus, gbc);
+ autoPanel.add(mStatus);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEnableAuto = makeJButton("DISABLEAUTO");
+ mEnableAuto.setPreferredSize(new Dimension(78, 23));
+ mEnableAuto.setActionCommand("autoButton");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.weighty = 1.0;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gb.setConstraints(mEnableAuto, gbc);
+ autoPanel.add(mEnableAuto);
+
+ refresh();
+ return mainPanel;
+ }
+
+ protected JPanel createActionPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mRefresh = makeJButton("REFRESH");
+ mHelp = makeJButton("HELP");
+ //JButton[] buttons = { mRefresh, mHelp };
+ JButton[] buttons = { mRefresh };
+ return makeJButtonPanel(buttons, true);
+ }
+
+ public void refresh() {
+ mModel.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_AUTO_RECOVERY_ON, "");
+
+ try {
+ NameValuePairs val = mAdmin.read(DestDef.DEST_KRA_ADMIN,
+ ScopeDef.SC_AUTO_RECOVERY, Constants.RS_ID_CONFIG, nvps);
+
+ populate(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ }
+ mModel.progressStop();
+ }
+
+ protected void populate(NameValuePairs nvps) {
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name);
+ if (name.equals(Constants.PR_AUTO_RECOVERY_ON)) {
+ if (value.equals(Constants.TRUE)) {
+ setStatus(true);
+ //mEnableAuto.setText(mDisableLabel);
+ //mEnableAuto.setToolTipText(mDisableTTip);
+ } else {
+ setStatus(false);
+ //mEnableAuto.setText(mEnableLabel);
+ //mEnableAuto.setToolTipText(mEnableTTip);
+ }
+ }
+ }
+ }
+
+ private void setStatus(boolean enabled) {
+ if (enabled) {
+ mEnableAuto.setText(mDisableLabel);
+ mEnableAuto.setToolTipText(mDisableTTip);
+ mStatus.setText(mEnableStatus);
+ mStatus.setToolTipText(mEnableStatusTTip);
+ } else {
+ mEnableAuto.setText(mEnableLabel);
+ mEnableAuto.setToolTipText(mEnableTTip);
+ mStatus.setText(mDisableStatus);
+ mStatus.setToolTipText(mDisableStatusTTip);
+ }
+ }
+
+ public void actionPerformed(ActionEvent e) {
+
+ if (e.getActionCommand().equals("autoButton")) {
+ String text = mEnableAuto.getText();
+ if (text.equals(mEnableLabel)) {
+ JDialog enableDialog = new CMSAutoRecovery(mModel.getFrame(),
+ mAdmin, mEnableAuto);
+ } else {
+ mModel.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_AUTO_RECOVERY_ON, Constants.FALSE);
+ try {
+ mAdmin.modify(DestDef.DEST_KRA_ADMIN,
+ ScopeDef.SC_AUTO_RECOVERY, Constants.RS_ID_CONFIG, nvps);
+ //mEnableAuto.setText(mEnableLabel);
+ //mEnableAuto.setToolTipText(mEnableTTip);
+ } catch (EAdminException ex) {
+ showErrorDialog(ex.toString());
+ }
+ mModel.progressStop();
+ }
+ refresh();
+ } else if (e.getSource().equals(mRefresh)) {
+ refresh();
+ } else if (e.getSource().equals(mHelp)) {
+ helpCallback();
+ }
+ }
+
+ public void mouseClicked(MouseEvent e) {
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSKRAPasswdPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSKRAPasswdPanel.java
new file mode 100644
index 000000000..7c70dca7f
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSKRAPasswdPanel.java
@@ -0,0 +1,267 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.AdminConnection;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import java.awt.*;
+import java.util.*;
+import java.awt.event.*;
+
+/**
+ * KRA password management tab
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class CMSKRAPasswdPanel extends CMSBaseUGTab {
+ private static String PANEL_NAME = "KRAPASSWD";
+ private CMSBaseResourceModel mModel;
+ private JButton mPwdBtn;
+ private AdminConnection mAdmin;
+ private JList mAgentList;
+ private DefaultListModel mAgentModel;
+ private Icon mUserIcon;
+ private JButton mRefresh, mHelp;
+ private static final String HELPINDEX =
+ "configuration-kra-agentpwd-help";
+ private CMSUGTabPanel mParent = null;
+
+ public CMSKRAPasswdPanel(CMSUGTabPanel parent) {
+ super(PANEL_NAME, parent.getResourceModel());
+ mModel = parent.getResourceModel();
+ mAdmin = mModel.getServerInfo().getAdmin();
+ mParent = parent;
+ mHelpToken = HELPINDEX;
+ }
+
+ public void refresh() {
+ mModel.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_RECOVERY_AGENT, "");
+
+ try {
+ NameValuePairs val = mAdmin.read(DestDef.DEST_KRA_ADMIN,
+ ScopeDef.SC_RECOVERY, Constants.RS_ID_CONFIG, nvps);
+
+ populate(val);
+ } catch (EAdminException e) {
+ mParent.removeAll();
+ //showErrorDialog(e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+ }
+
+ protected void populate(NameValuePairs nvps) {
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name);
+ if (name.equals(Constants.PR_RECOVERY_AGENT)) {
+ mAgentModel.removeAllElements();
+ updateModel(value);
+ }
+ }
+ }
+
+ private void updateModel(String value) {
+ String[] uids = getUIDs(value);
+ for (int i=0; i<uids.length; i++) {
+ JLabel label = makeJLabel(mUserIcon, uids[i],
+ SwingConstants.LEFT);
+ mAgentModel.add(i, label);
+ }
+
+ if (mAgentModel.size() > 0)
+ mAgentList.setSelectedIndex(0);
+ setSelectedItem();
+ }
+
+ private String[] getUIDs(String uids) {
+ StringTokenizer tokenizer = new StringTokenizer(uids, ",");
+ String[] vals = new String[tokenizer.countTokens()];
+ int i=0;
+ while (tokenizer.hasMoreElements()) {
+ vals[i++] = (String)tokenizer.nextElement();
+ }
+ CMSAdminUtil.bubbleSort(vals);
+ return vals;
+ }
+
+ protected JPanel createActionPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mRefresh = makeJButton("REFRESH");
+ mHelp = makeJButton("HELP");
+ //JButton[] buttons = { mRefresh, mHelp };
+ JButton[] buttons = { mRefresh };
+ return makeJButtonPanel(buttons, true);
+ }
+
+ protected JPanel createListPanel() {
+ JPanel mainPanel = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mainPanel.setLayout(gb3);
+
+ JPanel listPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ listPanel.setLayout(gb);
+ listPanel.setBorder(makeTitledBorder("RECOVERYLIST"));
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.gridwidth = gbc.REMAINDER;
+ gb3.setConstraints(listPanel, gbc);
+ mainPanel.add(listPanel);
+
+ // label for table
+ JLabel tablelbl = makeJLabel("RECOVERYLIST");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ //gbc.weightx = 1.0;
+ //gbc.weighty = 1.0;
+ gb.setConstraints(tablelbl, gbc);
+ listPanel.add(tablelbl);
+
+ // agent table
+ mAgentModel = new DefaultListModel();
+ mAgentList = makeJList(mAgentModel, 10);
+ mAgentList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ MouseListener mouseListener = new MouseAdapter() {
+ public void mouseClicked(MouseEvent e) {
+ if (e.getClickCount() == 2)
+ displayPasswordDialog();
+ else
+ setSelectedItem();
+ }
+ };
+
+ mAgentList.addMouseListener(mouseListener);
+ mUserIcon = CMSAdminUtil.getImage(CMSAdminResources.IMAGE_USER);
+ JScrollPane scrollPane = createScrollPane(mAgentList);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridx = 0;
+ gbc.gridy = 1;
+ gbc.gridheight = gbc.REMAINDER;
+ gb.setConstraints(scrollPane, gbc);
+ listPanel.add(scrollPane);
+
+ // change password button
+ mPwdBtn = makeJButton("CHANGEPWD");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridx = 1;
+ gbc.gridy = 1;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.gridwidth = gbc.REMAINDER;
+ gb.setConstraints(mPwdBtn, gbc);
+ listPanel.add(mPwdBtn);
+
+ refresh();
+
+ return mainPanel;
+ }
+
+ private JScrollPane createScrollPane(JList listbox) {
+
+ JScrollPane scrollPane = new JScrollPane(listbox,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ scrollPane.setBackground(getBackground());
+ scrollPane.setAlignmentX(LEFT_ALIGNMENT);
+ scrollPane.setAlignmentY(TOP_ALIGNMENT);
+ scrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
+ return scrollPane;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mRefresh)) {
+ refresh();
+ } else if (e.getSource().equals(mHelp)) {
+ helpCallback();
+ } else if (e.getSource().equals(mPwdBtn)) {
+ displayPasswordDialog();
+ }
+ }
+
+ public void displayPasswordDialog() {
+ Object[] values = mAgentList.getSelectedValues();
+ if (values.length == 0) {
+ showMessageDialog("NOSELECTION");
+ } else if (values.length > 1) {
+ showMessageDialog("MULTISELECTIONS");
+ } else {
+ String str = ((JLabel)values[0]).getText();
+
+ // ensure the selected id is valid
+ refresh();
+ int s = mAgentList.getModel().getSize();
+ boolean foundID = false;
+ for (int i = 0; i < s; i++) {
+ JLabel l = (JLabel)mAgentList.getModel().getElementAt(i);
+ if (str.equals(l.getText())) {
+ foundID = true;
+ break;
+ }
+ }
+ if (foundID) {
+ JDialog pwdDialog = new CMSPasswordDialog(mModel.getFrame(),
+ mAdmin, str);
+ } else {
+ showErrorDialog("Invalid ID");
+ }
+ }
+ }
+
+ private void setSelectedItem() {
+ if (mAgentList.getSelectedIndex()< 0) {
+ mPwdBtn.setEnabled(false);
+ return;
+ }
+
+ if (mAgentList.getSelectedIndex() >= 0)
+ mPwdBtn.setEnabled(true);
+ }
+
+ public void mouseClicked(MouseEvent e) {
+/*
+ if (e.getClickCount() == 2)
+ displayPasswordDialog();
+ else
+ setSelectedItem();
+*/
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSKRASchemePanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSKRASchemePanel.java
new file mode 100644
index 000000000..34950b371
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSKRASchemePanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.AdminConnection;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * KRA scheme management tab
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class CMSKRASchemePanel extends CMSBaseUGTab {
+ private static String PANEL_NAME = "SCHEMEMGMT";
+ private CMSBaseResourceModel mModel;
+ private JButton mSchemeBtn;
+ private AdminConnection mAdmin;
+ private JLabel mAvailAgentLbl;
+ private JLabel mReqAgentLbl;
+ private String mAvailAgentStr;
+ private String mReqAgentStr;
+ private JButton mRefresh, mHelp;
+ private static final String HELPINDEX =
+ "configuration-kra-schememgt-help";
+ private CMSUGTabPanel mParent = null;
+
+ public CMSKRASchemePanel(CMSUGTabPanel parent) {
+ super(PANEL_NAME, parent.getResourceModel());
+ mModel = parent.getResourceModel();
+ mAdmin = mModel.getServerInfo().getAdmin();
+ mAvailAgentStr =
+ mResource.getString(PANEL_NAME + "_LABEL_AVAILAGENT_LABEL");
+ mReqAgentStr =
+ mResource.getString(PANEL_NAME + "_LABEL_REQAGENT_LABEL");
+ mParent = parent;
+ mHelpToken = HELPINDEX;
+ }
+
+/*
+ public void init() {
+ GridBagLayout gbm = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ CMSAdminUtil.resetGBC(gbc);
+ mCenterPanel.setLayout(gbm);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ JPanel agentPanel = createAgentPanel();
+ gbm.setConstraints(agentPanel, gbc);
+ mCenterPanel.add(agentPanel);
+
+ refresh();
+ }
+*/
+
+ public void refresh() {
+ mModel.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_RECOVERY_N, "");
+ nvps.put(Constants.PR_RECOVERY_M, "");
+
+ try {
+ NameValuePairs val = mAdmin.read(DestDef.DEST_KRA_ADMIN,
+ ScopeDef.SC_RECOVERY, Constants.RS_ID_CONFIG, nvps);
+
+ populate(val);
+ } catch (EAdminException e) {
+ mParent.removeAll();
+ //showErrorDialog(e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+ }
+
+ protected void populate(NameValuePairs nvps) {
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name);
+ if (name.equals(Constants.PR_RECOVERY_N)) {
+ mAvailAgentLbl.setText(value);
+ } else if (name.equals(Constants.PR_RECOVERY_M)) {
+ mReqAgentLbl.setText(value);
+ }
+ }
+ }
+
+ protected JPanel createActionPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mRefresh = makeJButton("REFRESH");
+ mHelp = makeJButton("HELP");
+ //JButton[] buttons = { mRefresh, mHelp };
+ JButton[] buttons = { mRefresh };
+ return makeJButtonPanel(buttons, true);
+ }
+
+ protected JPanel createListPanel() {
+ JPanel listPanel = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ listPanel.setLayout(gb3);
+
+ JPanel agentPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ agentPanel.setLayout(gb);
+ agentPanel.setBorder(makeTitledBorder("CURRENT"));
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.gridwidth = gbc.REMAINDER;
+ gb3.setConstraints(agentPanel, gbc);
+ listPanel.add(agentPanel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label2 = makeJLabel("REQAGENT");
+ mReqAgentLbl= new JLabel("");
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.EAST;
+ gbc. insets = new Insets(0,COMPONENT_SPACE,0,0);
+ gb.setConstraints(label2, gbc);
+ agentPanel.add(label2);
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc. insets = new Insets(0,COMPONENT_SPACE,
+ 0,COMPONENT_SPACE);
+ gb.setConstraints(mReqAgentLbl, gbc);
+ agentPanel.add(mReqAgentLbl);
+
+ mSchemeBtn = makeJButton("CHANGESCHEME");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gb.setConstraints(mSchemeBtn, gbc);
+ agentPanel.add(mSchemeBtn);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label1 = makeJLabel("AVAILAGENT");
+ mAvailAgentLbl = new JLabel("");
+ gbc.gridheight = gbc.REMAINDER;
+ CMSAdminUtil.addEntryField(agentPanel, label1, mAvailAgentLbl, gbc);
+
+ refresh();
+ return listPanel;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mSchemeBtn)) {
+ try {
+ MNSchemeWizardInfo info = new MNSchemeWizardInfo(mAdmin,
+ Integer.parseInt(mReqAgentLbl.getText()),
+ Integer.parseInt(mAvailAgentLbl.getText()));
+ MNSchemeWizard wizard = new MNSchemeWizard(mModel.getFrame(), info);
+ } catch(NumberFormatException ex) {
+ Debug.println("CMSKRASchemePanel: MN not intereger "+ex.toString());
+ showErrorDialog(mResource.getString("SCHEMEMGMT_DIALOG_MNFORMAT_MESSAGE"));
+ }
+ refresh();
+ } else if (e.getSource().equals(mRefresh)) {
+ refresh();
+ } else if (e.getSource().equals(mHelp)) {
+ helpCallback();
+ }
+ }
+
+ public void mouseClicked(MouseEvent e) {
+ }
+
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSLDAPSettingPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSLDAPSettingPanel.java
new file mode 100644
index 000000000..641a6641e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSLDAPSettingPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * LDAP server setting tab
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class CMSLDAPSettingPanel extends CMSBaseTab {
+
+ private static String PANEL_NAME = "LDAPSETTING";
+ private static final String HELPINDEX =
+ "configuration-database-settings-help";
+ private JTextField mHostNameText;
+ private JTextField mPortText;
+ private JTextField mBindAsText;
+ private JTextField mMaxConnsText;
+ private JTextField mMinConnsText;
+ private JPasswordField mPasswordText;
+ private JPasswordField mPasswordAgainText;
+ private JCheckBox mEnable;
+ private Color mActiveColor;
+ protected AdminConnection mAdmin;
+ protected CMSBaseResourceModel mModel;
+ private String mServletName;
+ private CMSTabPanel mParent;
+ private static final int MAX_PORT = 65535;
+ //private JComboBox mVersionBox;
+
+ public CMSLDAPSettingPanel(CMSTabPanel parent) {
+ super(PANEL_NAME, parent);
+ mHelpToken = HELPINDEX;
+ mServletName = getServletName(PANEL_NAME);
+ mModel = parent.getResourceModel();
+ mParent = parent;
+ }
+
+ public void init() {
+ mAdmin = mModel.getServerInfo().getAdmin();
+ JPanel serverInfo = new JPanel();
+ serverInfo.setBorder(makeTitledBorder("SETTING"));
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mCenterPanel.setLayout(gb);
+
+ //add the destination panel
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(serverInfo, gbc);
+ mCenterPanel.add(serverInfo);
+
+ GridBagLayout gb1 = new GridBagLayout();
+ serverInfo.setLayout(gb1);
+
+ // add host name label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel hostLabel = makeJLabel("HOST");
+ mHostNameText = makeJTextField(30);
+ mActiveColor = mHostNameText.getBackground();
+ CMSAdminUtil.addEntryField(serverInfo, hostLabel, mHostNameText, gbc);
+
+ // add port number label
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel portLabel = makeJLabel("PORT");
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,0);
+ gb1.setConstraints(portLabel, gbc);
+ serverInfo.add(portLabel);
+
+ // add port number text field
+ CMSAdminUtil.resetGBC(gbc);
+ mPortText = makeJTextField(10);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ //gbc.weightx = 0.0;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gb1.setConstraints(mPortText, gbc);
+ serverInfo.add(mPortText);
+
+ // add check box
+/*
+ CMSAdminUtil.resetGBC(gbc);
+ mSecurePort = makeJCheckBox("SECUREPORT");
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE - COMPONENT_SPACE,0,COMPONENT_SPACE);
+ gb1.setConstraints(mSecurePort, gbc);
+ serverInfo.add(mSecurePort);
+*/
+
+ // add base DN label and text field
+/*
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel baseDNLabel = makeJLabel("BASEDN");
+ mBaseDNText = makeJTextField(30);
+ CMSAdminUtil.addEntryField(serverInfo, baseDNLabel, mBaseDNText, gbc);
+*/
+
+ // add bind as label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel bindAsLabel = makeJLabel("BINDAS");
+ mBindAsText = makeJTextField(30);
+ CMSAdminUtil.addEntryField(serverInfo, bindAsLabel, mBindAsText, gbc);
+
+ // add password label and text field
+/*
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel passwordLabel = makeJLabel("PWD");
+ mPasswordText = makeJPasswordField(20);
+ CMSAdminUtil.addEntryField(serverInfo, passwordLabel, mPasswordText, gbc);
+*/
+
+ // add password again label and text field
+/*
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel passwordAgainLabel = makeJLabel("PWDAGAIN");
+ mPasswordAgainText = makeJPasswordField(30);
+ CMSAdminUtil.addEntryField(serverInfo, passwordAgainLabel,
+ mPasswordAgainText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel versionLabel = makeJLabel("VERSION");
+ mVersionBox = makeJComboBox("VERSION");
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.addEntryField(serverInfo, versionLabel, mVersionBox,
+ dummy, gbc);
+*/
+
+ // add maxconns label text field
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel maxConnsLabel = makeJLabel("MAXCONNS");
+ mMaxConnsText = makeJTextField(30);
+ CMSAdminUtil.addEntryField(serverInfo, maxConnsLabel, mMaxConnsText, gbc);
+
+ // add maxconns label text field
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel minConnsLabel = makeJLabel("MINCONNS");
+ mMinConnsText = makeJTextField(30);
+ CMSAdminUtil.addEntryField(serverInfo, minConnsLabel, mMinConnsText, gbc);
+
+ refresh();
+ }
+
+ public void refresh() {
+ mModel.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_HOST_NAME, "");
+ nvps.put(Constants.PR_LDAP_PORT, "");
+ //nvps.add(Constants.PR_SECURE_PORT_ENABLED, "");
+ //nvps.add(Constants.PR_BASE_DN, "");
+ nvps.put(Constants.PR_BIND_DN, "");
+ nvps.put(Constants.PR_LDAP_VERSION, "");
+ nvps.put(Constants.PR_LDAP_MAX_CONNS, "");
+ nvps.put(Constants.PR_LDAP_MIN_CONNS, "");
+
+ try {
+ NameValuePairs val = mAdmin.read(mServletName,
+ ScopeDef.SC_LDAP, Constants.RS_ID_CONFIG, nvps);
+
+ populate(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+ }
+
+ protected String getServletName(String panelName) {
+ if (panelName.equals("LDAPSETTING"))
+ return DestDef.DEST_SERVER_ADMIN;
+ else if (panelName.equals("CALDAPSETTING"))
+ return DestDef.DEST_CA_ADMIN;
+ return DestDef.DEST_RA_ADMIN;
+ }
+
+ protected void populate(NameValuePairs nvps) {
+ String version = "";
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name);
+ if (name.equals(Constants.PR_HOST_NAME)) {
+ mHostNameText.setText(value);
+ } else if (name.equals(Constants.PR_LDAP_PORT)) {
+ mPortText.setText(value);
+ } else if (name.equals(Constants.PR_SECURE_PORT_ENABLED)) {
+/*
+ if (nvp.getValue().equals(Constants.TRUE))
+ mSecurePort.setSelected(true);
+ else
+ mSecurePort.setSelected(false);
+*/
+ } else if (name.equals(Constants.PR_BASE_DN)) {
+ //mBaseDNText.setText(nvp.getValue());
+ } else if (name.equals(Constants.PR_BIND_DN)) {
+ mBindAsText.setText(value);
+ } else if (name.equals(Constants.PR_ENABLE)) {
+ if (value.equals(Constants.TRUE))
+ mEnable.setSelected(true);
+ else
+ mEnable.setSelected(false);
+ } else if (name.equals(Constants.PR_LDAP_VERSION)) {
+ version = value;
+ } else if (name.equals(Constants.PR_LDAP_MIN_CONNS)) {
+ mMinConnsText.setText(value);
+ } else if (name.equals(Constants.PR_LDAP_MAX_CONNS)) {
+ mMaxConnsText.setText(value);
+ }
+
+ }
+
+/*
+ if (version.equals(""))
+ mVersionBox.setSelectedIndex(1);
+ else
+ mVersionBox.setSelectedItem(version);
+*/
+ //mPasswordText.setText("");
+ //mPasswordAgainText.setText("");
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ super.actionPerformed(e);
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ // check blank fields
+ String host = mHostNameText.getText().trim();
+ String port = mPortText.getText().trim();
+ //String baseDN = mBaseDNText.getText().trim();
+ String bindAs = mBindAsText.getText().trim();
+ String maxConns = mMaxConnsText.getText().trim();
+ String minConns = mMinConnsText.getText().trim();
+
+ //if (host.equals("") || port.equals("") || baseDN.equals("") ||
+ // bindAs.equals("")) {
+ if (host.equals("") || port.equals("") || bindAs.equals("") || maxConns.equals("") || minConns.equals("")) {
+ showMessageDialog("BLANKFIELD");
+ return false;
+ }
+
+ try {
+ int num = Integer.parseInt(port);
+ if (num <= 0 || num > MAX_PORT) {
+ showMessageDialog("PORTRANGE");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ showMessageDialog("NUMBERFORMAT");
+ return false;
+ }
+
+ try {
+ int max = Integer.parseInt(maxConns);
+ int min = Integer.parseInt(minConns);
+ if ((max < min) || (max <0) || (min <0)) {
+ showMessageDialog("MAXMINRANGE");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ showMessageDialog("MAXMINNUMBERFORMAT");
+ return false;
+ }
+
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_HOST_NAME, host);
+ nvps.put(Constants.PR_LDAP_PORT, port);
+ //nvps.add(Constants.PR_BASE_DN, baseDN);
+ nvps.put(Constants.PR_BIND_DN, bindAs);
+ nvps.put(Constants.PR_LDAP_MAX_CONNS, maxConns);
+ nvps.put(Constants.PR_LDAP_MIN_CONNS, minConns);
+/*
+ nvps.add(Constants.PR_LDAP_VERSION,
+ (String)mVersionBox.getSelectedItem());
+*/
+
+/*
+ if (mSecurePort.isSelected())
+ nvps.add(Constants.PR_SECURE_PORT_ENABLED, Constants.TRUE);
+ else
+ nvps.add(Constants.PR_SECURE_PORT_ENABLED, Constants.FALSE);
+*/
+
+/*
+ String passwd = mPasswordText.getText();
+ String passwdagain = mPasswordAgainText.getText();
+
+ if (!passwd.equals("") && !passwdagain.equals("")) {
+ if (passwd.equals(passwdagain)) {
+ nvps.add(Constants.PR_BIND_PASSWD, passwd);
+ } else {
+ showMessageDialog("UNMATCHEDPASSWD");
+ return false;
+ }
+ } else if (((!passwd.equals("")) && passwdagain.equals("")) ||
+ ((!passwd.equals("")) && passwdagain.equals(""))) {
+ showMessageDialog("UNMATCHEDPASSWD");
+ return false;
+ }
+*/
+
+ mModel.progressStart();
+ try {
+ mAdmin.modify(mServletName, ScopeDef.SC_LDAP,
+ Constants.RS_ID_CONFIG, nvps, false);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ return false;
+ }
+
+ mModel.progressStop();
+ clearDirtyFlag();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSNetworkPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSNetworkPanel.java
new file mode 100644
index 000000000..03458d2b1
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSNetworkPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.client.console.ConsoleInfo;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import netscape.ldap.*;
+
+/**
+ * Network Connection Setting Tab to be displayed at the right hand side
+ *
+ * @author Christine Ho
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class CMSNetworkPanel extends CMSBaseTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private final static String PANEL_NAME = "NETWORK";
+ private final static String DISABLED = "-1";
+
+ private static final int MAX_PORT = 65535;
+ private static final int MIN_PORT = 1;
+
+ private Color mActiveColor;
+
+ // TextField for port
+ private JTextField mAdminSSLPortText;
+ private JTextField mAgentSSLPortText;
+ private JTextField mGatewayPortText;
+ private JTextField mGatewaySSLPortText;
+
+ // TextField for Backlog
+ private JTextField mAdminSSLBacklogText;
+ private JTextField mAgentSSLBacklogText;
+ private JTextField mGatewayBacklogText;
+ private JTextField mGatewaySSLBacklogText;
+
+ // Label for EE port
+ private JLabel mPortLabel;
+ private JLabel mEnableLabel;
+ private JLabel mBacklogLabel;
+
+ // Label for SSL EE port
+ private JLabel mSSLPortLabel;
+ private JLabel mSSLBacklogLabel;
+
+ private JCheckBox mEnable;
+
+ private CMSBaseResourceModel mModel;
+ protected AdminConnection mAdmin;
+ private boolean mBlankFieldError = false;
+ private boolean mNumberError = false;
+ private CMSTabPanel mParent;
+ private static final String HELPINDEX = "configuration-system-network-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSNetworkPanel(CMSTabPanel parent) {
+ super(PANEL_NAME, parent);
+ mParent = parent;
+ mModel = parent.getResourceModel();
+ mHelpToken = HELPINDEX;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Actual Instanciation of the UI components
+ */
+ public void init() {
+ Debug.println("NetworkPanel: init()");
+ mAdmin = mModel.getServerInfo().getAdmin();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ CMSAdminUtil.resetGBC(gbc);
+ mCenterPanel.setLayout(gb);
+
+ // admin panel
+ JPanel adminPanel = new JPanel();
+ GridBagLayout gb1 = new GridBagLayout();
+ adminPanel.setLayout(gb1);
+ adminPanel.setBorder(makeTitledBorder("ADMIN"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(adminPanel, gbc);
+ mCenterPanel.add(adminPanel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel adminSSLport = makeJLabel("ADMINSSLPORT");
+ mAdminSSLPortText = makeJTextField(10);
+ JLabel adminBacklog = makeJLabel("ADMINBACKLOG");
+ mAdminSSLBacklogText = makeJTextField(10);
+ JLabel dummy1 = new JLabel(" ");
+ CMSAdminUtil.addEntryField(adminPanel, adminSSLport,
+ mAdminSSLPortText, adminBacklog, mAdminSSLBacklogText, dummy1, gbc);
+
+ mActiveColor = mAdminSSLPortText.getBackground();
+
+ // gateway panel
+ JPanel agentPanel = new JPanel();
+ GridBagLayout gb2 = new GridBagLayout();
+ agentPanel.setLayout(gb2);
+ agentPanel.setBorder(makeTitledBorder("AGENT"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(agentPanel, gbc);
+ mCenterPanel.add(agentPanel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel agentPort = makeJLabel("AGENTSSLPORT");
+ mAgentSSLPortText = makeJTextField(10);
+ JLabel agentBacklog = makeJLabel("SECUREAGENTBACKLOG");
+ mAgentSSLBacklogText = makeJTextField(10);
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.addEntryField(agentPanel, agentPort, mAgentSSLPortText,
+ agentBacklog, mAgentSSLBacklogText, dummy, gbc);
+
+ JPanel gatewayPanel = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ gatewayPanel.setLayout(gb3);
+ gatewayPanel.setBorder(makeTitledBorder("EE"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(gatewayPanel, gbc);
+ mCenterPanel.add(gatewayPanel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPortLabel = makeJLabel("GATEWAYPORT");
+ mGatewayPortText = makeJTextField(10);
+ mBacklogLabel = makeJLabel("EEBACKLOG");
+ mGatewayBacklogText = makeJTextField(10);
+ mEnableLabel = makeJLabel("ENABLED");
+ mEnable = makeJCheckBox();
+ CMSAdminUtil.addEntryField(gatewayPanel, mPortLabel, mGatewayPortText,
+ mBacklogLabel, mGatewayBacklogText, mEnableLabel, mEnable, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mSSLPortLabel = makeJLabel("GATEWAYSSLPORT");
+ mGatewaySSLPortText = makeJTextField(10);
+ mSSLBacklogLabel = makeJLabel("SECUREEEBACKLOG");
+ mGatewaySSLBacklogText = makeJTextField(10);
+ JLabel dummy2 = new JLabel(" ");
+ CMSAdminUtil.addEntryField(gatewayPanel, mSSLPortLabel,
+ mGatewaySSLPortText, mSSLBacklogLabel, mGatewaySSLBacklogText,
+ dummy2, gbc);
+
+ refresh();
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ String adminSSLPortStr = mAdminSSLPortText.getText().trim();
+ String gatewayPortStr = mGatewayPortText.getText().trim();
+ String gatewaySSLPortStr = mGatewaySSLPortText.getText().trim();
+ String agentSSLPortStr = mAgentSSLPortText.getText().trim();
+ String adminSSLBacklogStr = mAdminSSLBacklogText.getText().trim();
+ String gatewayBacklogStr = mGatewayBacklogText.getText().trim();
+ String gatewaySSLBacklogStr = mGatewaySSLBacklogText.getText().trim();
+ String agentSSLBacklogStr = mAgentSSLBacklogText.getText().trim();
+ //String docroot = mDocRootText.getText().trim();
+
+ //check blank fields
+ if (adminSSLPortStr.equals("") ||
+ (gatewayPortStr.equals("") && mGatewayPortText.isEnabled()) ||
+ (gatewaySSLPortStr.equals("") && mGatewaySSLPortText.isEnabled()) ||
+ agentSSLPortStr.equals("") ||
+ adminSSLBacklogStr.equals("") ||
+ (gatewayBacklogStr.equals("") && mGatewayBacklogText.isEnabled()) ||
+ (gatewaySSLBacklogStr.equals("") && mGatewaySSLBacklogText.isEnabled()) ||
+ agentSSLBacklogStr.equals("") ) {
+ showMessageDialog("BLANKFIELD");
+ return false;
+ }
+
+ //check format and range number
+ int adminSSLPort;
+ int gatewayPort;
+ int gatewaySSLPort;
+ int agentSSLPort;
+ int adminSSLBacklog;
+ int gatewayBacklog;
+ int gatewaySSLBacklog;
+ int agentSSLBacklog;
+
+ try {
+ adminSSLPort = Integer.parseInt(adminSSLPortStr);
+ gatewayPort = Integer.parseInt(gatewayPortStr);
+ gatewaySSLPort = Integer.parseInt(gatewaySSLPortStr);
+ agentSSLPort = Integer.parseInt(agentSSLPortStr);
+ adminSSLBacklog = Integer.parseInt(adminSSLBacklogStr);
+ gatewayBacklog = Integer.parseInt(gatewayBacklogStr);
+ gatewaySSLBacklog = Integer.parseInt(gatewaySSLBacklogStr);
+ agentSSLBacklog = Integer.parseInt(agentSSLBacklogStr);
+ } catch (NumberFormatException e) {
+ showMessageDialog("NUMBERFORMAT");
+ return false;
+ }
+
+ if (adminSSLBacklog <= 0 || gatewayBacklog <= 0 ||
+ gatewaySSLBacklog <= 0 || agentSSLBacklog <= 0) {
+ showMessageDialog("NEGATIVE");
+ return false;
+ }
+ if ((adminSSLPort < MIN_PORT) || (adminSSLPort > MAX_PORT) ||
+ (gatewayPort < MIN_PORT) || (gatewayPort > MAX_PORT) ||
+ (agentSSLPort < MIN_PORT) || (agentSSLPort > MAX_PORT) ||
+ (gatewaySSLPort < MIN_PORT) || (gatewaySSLPort > MAX_PORT)) {
+ showMessageDialog("PORTRANGE");
+ return false;
+ } else {
+ mModel.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_ADMIN_S_PORT, adminSSLPortStr);
+ nvps.put(Constants.PR_GATEWAY_PORT, gatewayPortStr);
+ nvps.put(Constants.PR_AGENT_S_PORT, agentSSLPortStr);
+
+ if (mGatewaySSLPortText.isEnabled()) {
+ nvps.put(Constants.PR_GATEWAY_S_PORT, gatewaySSLPortStr);
+ }
+
+ if (mGatewaySSLBacklogText.isEnabled()) {
+ nvps.put(Constants.PR_GATEWAY_S_BACKLOG, gatewaySSLBacklogStr);
+ }
+
+ if (mEnable.isSelected()) {
+ nvps.put(Constants.PR_GATEWAY_PORT_ENABLED, Constants.TRUE);
+ nvps.put(Constants.PR_ADMIN_S_BACKLOG, adminSSLBacklogStr);
+ nvps.put(Constants.PR_GATEWAY_BACKLOG, gatewayBacklogStr);
+ nvps.put(Constants.PR_AGENT_S_BACKLOG, agentSSLBacklogStr);
+ } else
+ nvps.put(Constants.PR_GATEWAY_PORT_ENABLED, Constants.FALSE);
+
+ try {
+ mAdmin.modify(DestDef.DEST_SERVER_ADMIN, ScopeDef.SC_NETWORK,
+ Constants.RS_ID_CONFIG, nvps);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ return false;
+ }
+
+ ConsoleInfo consoleInfo = mModel.getConsoleInfo();
+ LDAPConnection conn = consoleInfo.getLDAPConnection();
+ try {
+ LDAPAttribute attr = new LDAPAttribute("nsserverport", adminSSLPortStr);
+ LDAPModification singleChange = new LDAPModification(LDAPModification.REPLACE,
+ attr);
+ conn.modify(consoleInfo.getCurrentDN(), singleChange);
+ } catch (Exception eee) {
+ }
+ mModel.progressStop();
+ }
+
+ clearDirtyFlag();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ //clearDirtyFlag();
+ return true;
+ }
+
+ /**
+ * refresh the panel and update data
+ */
+ public void refresh() {
+ mModel.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_ADMIN_S_PORT, "");
+ nvps.put(Constants.PR_AGENT_S_PORT, "");
+ nvps.put(Constants.PR_GATEWAY_S_PORT, "");
+ nvps.put(Constants.PR_GATEWAY_PORT, "");
+ nvps.put(Constants.PR_GATEWAY_PORT_ENABLED, "");
+
+ try {
+ NameValuePairs val = mAdmin.read(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_NETWORK, Constants.RS_ID_CONFIG, nvps);
+
+ populate(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ super.actionPerformed(e);
+ if (e.getSource().equals(mEnable)) {
+ if (mEnable.isSelected()) {
+ enableFields(true, mActiveColor);
+ } else {
+ enableFields(false, getBackground());
+ }
+ }
+ }
+
+ private void populate(NameValuePairs nvps) {
+ for (String name : nvps.keySet()) {
+ String str = nvps.get(name);
+
+ if (name.equals(Constants.PR_GATEWAY_PORT_ENABLED)) {
+ mEnable.setSelected(getBoolean(str));
+ } else {
+ if (!validate(str))
+ continue;
+
+ if (name.equals(Constants.PR_AGENT_S_PORT)) {
+ mAgentSSLPortText.setText(str);
+ } else if (name.equals(Constants.PR_ADMIN_S_PORT)) {
+ mAdminSSLPortText.setText(str);
+ } else if (name.equals(Constants.PR_GATEWAY_S_PORT)) {
+ if (str.equals(DISABLED)) {
+ mGatewaySSLPortText.setText("");
+ enableFields(mSSLPortLabel, mGatewaySSLPortText, false,
+ getBackground());
+ } else {
+ mGatewaySSLPortText.setText(str);
+ enableFields(mSSLPortLabel, mGatewaySSLPortText, true,
+ mActiveColor);
+ }
+ } else if (name.equals(Constants.PR_GATEWAY_PORT)) {
+ if (str.equals(DISABLED)) {
+ mGatewayPortText.setText("");
+ enableFields(mEnable, false);
+ } else {
+ mGatewayPortText.setText(str);
+ enableFields(mEnable, true);
+ }
+ } else if (name.equals(Constants.PR_ADMIN_S_BACKLOG)) {
+ mAdminSSLBacklogText.setText(str);
+ } else if (name.equals(Constants.PR_AGENT_S_BACKLOG)) {
+ mAgentSSLBacklogText.setText(str);
+ } else if (name.equals(Constants.PR_GATEWAY_S_BACKLOG)) {
+ if (str.equals(DISABLED)) {
+ enableFields(mSSLBacklogLabel, mGatewaySSLBacklogText,
+ false, getBackground());
+ mGatewaySSLBacklogText.setText("");
+ } else {
+ enableFields(mSSLBacklogLabel, mGatewaySSLBacklogText,
+ true, mActiveColor);
+ mGatewaySSLBacklogText.setText(str);
+ }
+ } else if (name.equals(Constants.PR_GATEWAY_BACKLOG)) {
+ if (str.equals(DISABLED)) {
+ enableFields(mEnable, false);
+ mGatewayBacklogText.setText("");
+ } else {
+ enableFields(mEnable, true);
+ mGatewayBacklogText.setText(str);
+ }
+ }
+ }
+ }
+
+ if (mEnable.isSelected())
+ enableFields(true, mActiveColor);
+ else
+ enableFields(false, getBackground());
+ }
+
+ private boolean getBoolean(String val) {
+ if (val.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ private void enableFields(boolean enabled, Color color) {
+ mGatewayPortText.setEnabled(enabled);
+ mGatewayPortText.setEditable(enabled);
+ mGatewayPortText.setBackground(color);
+ mGatewayBacklogText.setEnabled(enabled);
+ mGatewayBacklogText.setEditable(enabled);
+ mGatewayBacklogText.setBackground(color);
+ mPortLabel.setEnabled(enabled);
+ mBacklogLabel.setEnabled(enabled);
+
+ invalidate();
+ validate();
+ repaint(1);
+ }
+
+ private void enableFields(JLabel label, JTextComponent text,
+ boolean enabled, Color color) {
+ label.setEnabled(enabled);
+ text.setEnabled(enabled);
+ text.setEditable(enabled);
+ text.setBackground(color);
+ CMSAdminUtil.repaintComp(label);
+ CMSAdminUtil.repaintComp(text);
+ }
+
+ private void enableFields(JCheckBox comp, boolean enabled) {
+ comp.setEnabled(enabled);
+ CMSAdminUtil.repaintComp(comp);
+ }
+
+ private boolean validate(String str) {
+ if (str.equals("")) {
+ if (!mBlankFieldError) {
+ showMessageDialog("BLANKFIELD");
+ mBlankFieldError = true;
+ }
+ return false;
+ }
+
+ try {
+ int sslPort = Integer.parseInt(str);
+ } catch (NumberFormatException e) {
+ if (!mNumberError) {
+ showMessageDialog("NUMBERFORMAT");
+ mNumberError = true;
+ }
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSOCSPGeneralPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSOCSPGeneralPanel.java
new file mode 100644
index 000000000..37dfbef44
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSOCSPGeneralPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.math.*;
+
+/**
+ * OCSP General Setting
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class CMSOCSPGeneralPanel extends CMSBaseTab implements ItemListener {
+
+ private static String PANEL_NAME = "OCSPGENERAL";
+ private static CMSBaseResourceModel mModel;
+ protected AdminConnection mAdmin;
+ private JCheckBox mRAEnable;
+ private JCheckBox mEEEnable;
+ private CMSTabPanel mParent;
+ private JComboBox mGroups;
+ private JComboBox mAlgorithms;
+ private JTextField mSerialNumber;
+ private JTextField mMaxSerialNumber;
+ private JCheckBox mValidity;
+ private Vector mGroupData;
+ private static final String OCSPHELPINDEX =
+ "configuration-ocsp-general-help";
+
+ public CMSOCSPGeneralPanel(CMSTabPanel parent) {
+ super(PANEL_NAME, parent);
+ mModel = parent.getResourceModel();
+ mParent = parent;
+ mHelpToken = OCSPHELPINDEX;
+ }
+
+ public void init() {
+ Debug.println("CMSCAGeneral: init()");
+ mAdmin = mModel.getServerInfo().getAdmin();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ CMSAdminUtil.resetGBC(gbc);
+ mCenterPanel.setLayout(gb);
+
+ JPanel signingPanel = new JPanel();
+ GridBagLayout gb2 = new GridBagLayout();
+ signingPanel.setLayout(gb2);
+ signingPanel.setBorder(makeTitledBorder("SIGNING"));
+
+ CMSAdminUtil.resetGBC(gbc);
+ mCenterPanel.setLayout(gb);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ //gbc.weighty = 1.0;
+// gb.setConstraints(adminPanel, gbc);
+// mCenterPanel.add(adminPanel);
+
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(signingPanel, gbc);
+ mCenterPanel.add(signingPanel);
+
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel signingLabel = makeJLabel("ALGORITHM");
+ gbc.anchor = gbc.CENTER;
+ gb2.setConstraints(signingLabel, gbc);
+ gbc.weighty = 1.0;
+ signingPanel.add(signingLabel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mAlgorithms = new JComboBox();
+ mAlgorithms.addItemListener(this);
+ //mAlgorithms = makeJComboBox("ALGORITHM");
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ //gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb2.setConstraints(mAlgorithms, gbc);
+ signingPanel.add(mAlgorithms);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel dummy1 = new JLabel(" ");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb2.setConstraints(dummy1, gbc);
+ signingPanel.add(dummy1);
+
+ refresh();
+ }
+
+ public void refresh() {
+ mModel.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_DEFAULT_ALGORITHM, "");
+ nvps.put(Constants.PR_ALL_ALGORITHMS, "");
+
+ try {
+ NameValuePairs val = mAdmin.read(DestDef.DEST_OCSP_ADMIN,
+ ScopeDef.SC_GENERAL, Constants.RS_ID_CONFIG, nvps);
+
+ populate(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ }
+
+ protected void populate(NameValuePairs nvps) {
+ String defaultAlgorithm = "";
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name);
+ if (name.equals(Constants.PR_DEFAULT_ALGORITHM)) {
+ defaultAlgorithm = value;
+ } else if (name.equals(Constants.PR_ALL_ALGORITHMS)) {
+ initAlgorithmBox(value);
+ }
+ }
+
+ mAlgorithms.setSelectedItem(defaultAlgorithm);
+ }
+
+ private void initAlgorithmBox(String val) {
+ if (mAlgorithms.getItemCount() >= 0) {
+ mAlgorithms.removeAllItems();
+ }
+ StringTokenizer tokenizer = new StringTokenizer(val, ":");
+ while (tokenizer.hasMoreTokens()) {
+ mAlgorithms.addItem(tokenizer.nextToken());
+ }
+ }
+
+ private boolean getBoolean(String str) {
+ if (str.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ super.actionPerformed(e);
+ }
+
+ private String hexToDecimal(String hex)
+ {
+ //String newHex = hex.substring(2);
+ BigInteger bi = new BigInteger(hex, 16);
+ return bi.toString();
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ NameValuePairs nvps = new NameValuePairs();
+
+ nvps.put(Constants.PR_DEFAULT_ALGORITHM,
+ (String) mAlgorithms.getSelectedItem());
+
+ mModel.progressStart();
+ try {
+ mAdmin.modify(DestDef.DEST_OCSP_ADMIN,
+ ScopeDef.SC_GENERAL, Constants.RS_ID_CONFIG, nvps);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ return false;
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSPasswordDialog.java b/base/console/src/com/netscape/admin/certsrv/config/CMSPasswordDialog.java
new file mode 100644
index 000000000..47cb6c865
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSPasswordDialog.java
@@ -0,0 +1,310 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import java.awt.*;
+import java.util.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.event.*;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+
+/**
+ * Display this dialog to get a password.
+ *
+ * @author chrisho
+ * @author jpanchen
+ * @version $Revision$, $Date$
+ * @date 07/21/98
+ */
+
+public class CMSPasswordDialog extends JDialog
+ implements ActionListener, DocumentListener, MouseListener
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final int WIDTH = 300;
+ private static final int HEIGHT = 216;
+
+ private JLabel mUsernameField; // username textfield
+ private JPasswordField mPasswordField; // password field
+ private JPasswordField mPasswordFieldAgain; // password field
+ private JPasswordField mOldPasswordField; // old password
+ private boolean mCanceled = true; // exit state of the dialog
+ private String mUsername; // username
+ private String mPassword; // password
+ private static final String PREFIX = "PASSWDDIALOG";
+ private JFrame mParentFrame;
+ private ResourceBundle mResource;
+ private AdminConnection mAdmin;
+ private JButton mOK, mCancel, mHelp;
+
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ /**
+ * @param parent parent frame
+ */
+ public CMSPasswordDialog(JFrame parent, AdminConnection conn, String uid) {
+ super(parent, true);
+ mParentFrame = parent;
+ mAdmin = conn;
+ mResource =
+ ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+
+ JPanel center = new JPanel();
+ getContentPane().setLayout(new BorderLayout());
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ JPanel contentPanel = new JPanel();
+ GridBagLayout gb1 = new GridBagLayout();
+ contentPanel.setLayout(gb1);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(contentPanel, gbc);
+ center.add(contentPanel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel lUsername =
+ new JLabel(mResource.getString(PREFIX+"_LABEL_USERID_LABEL"));
+ lUsername.setToolTipText(
+ mResource.getString(PREFIX+"_LABEL_USERID_TTIP"));
+
+ mUsernameField = new JLabel(uid);
+
+
+ CMSAdminUtil.addEntryField(contentPanel, lUsername, mUsernameField,
+ gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel lOldPassword=
+ new JLabel(mResource.getString(PREFIX+"_LABEL_OLDPASSWORD_LABEL"));
+ lOldPassword.setToolTipText(
+ mResource.getString(PREFIX+"_LABEL_OLDPASSWORD_TTIP"));
+ mOldPasswordField = new JPasswordField();
+ mOldPasswordField.getDocument().addDocumentListener(this);
+ mOldPasswordField.addMouseListener(this);
+ CMSAdminUtil.addEntryField(contentPanel, lOldPassword,
+ mOldPasswordField, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel lPassword=
+ new JLabel(mResource.getString(PREFIX+"_LABEL_PASSWORD_LABEL"));
+ lPassword.setToolTipText(
+ mResource.getString(PREFIX+"_LABEL_PASSWORD_TTIP"));
+ mPasswordField = new JPasswordField();
+ mPasswordField.getDocument().addDocumentListener(this);
+ mPasswordField.addMouseListener(this);
+ CMSAdminUtil.addEntryField(contentPanel, lPassword, mPasswordField,
+ gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel lPasswordAgain=
+ new JLabel(mResource.getString(PREFIX+"_LABEL_PASSWORD_AGAIN_LABEL"));
+ lPassword.setToolTipText(
+ mResource.getString(PREFIX+"_LABEL_PASSWORD_AGAIN_TTIP"));
+ mPasswordFieldAgain = new JPasswordField();
+ mPasswordFieldAgain.getDocument().addDocumentListener(this);
+ mPasswordFieldAgain.addMouseListener(this);
+ CMSAdminUtil.addEntryField(contentPanel, lPasswordAgain,
+ mPasswordFieldAgain, gbc);
+
+ JPanel actionPanel = makeActionPane();
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(actionPanel, gbc);
+ center.add(actionPanel);
+
+ getContentPane().add("Center",center);
+
+ mCanceled=false;
+ mUsername="";
+ mPassword="";
+
+ setSize( WIDTH, HEIGHT );
+ this.show();
+
+ /* Cancel if the window is closed */
+ addWindowListener(
+ new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ dispose();
+ mCanceled = true;
+ }
+ }
+ );
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * return the exit status of the dialog
+ *
+ * @return true if the user hits the cancel button.
+ */
+ public boolean isCancel() {
+ return mCanceled;
+ }
+
+ /**
+ * Returns the username typed in by the user, on OK.
+ *
+ * @return The selected username, if the user hits the OK button.
+ */
+ public String getUsername() {
+ return mUsername;
+ }
+
+ /**
+ * Return the password typed in by the user, on OK.
+ *
+ * @return The selected password, if the user hits the OK button.
+ */
+ public String getPassword() {
+ return mPassword;
+ }
+
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ public void actionPerformed(ActionEvent evt) {
+ if (evt.getSource().equals(mOK)) {
+ String userid = mUsernameField.getText().trim();
+ String oldpassword = mOldPasswordField.getText().trim();
+ String newpassword = mPasswordField.getText().trim();
+ String passwordAgain = mPasswordFieldAgain.getText().trim();
+
+ /* PROACTIVE VERIFICATION
+ if (oldpassword.equals("") || newpassword.equals("") ||
+ passwordAgain.equals("")) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, mResource,
+ PREFIX, "EMPTYFIELD", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ */
+ if (!newpassword.equals(passwordAgain)) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, mResource,
+ PREFIX, "CONFIRMED", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+
+
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_OLD_AGENT_PWD, oldpassword);
+ nvps.put(Constants.PR_AGENT_PWD, newpassword);
+
+ try {
+ mAdmin.modify(DestDef.DEST_KRA_ADMIN,
+ ScopeDef.SC_AGENT_PWD, userid, nvps);
+ } catch (EAdminException ex) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ ex.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ if (!ex.getMessage().equals("Server Error"))
+ return;
+ }
+
+ mCanceled = false;
+ this.dispose();
+ return;
+ }
+ if (evt.getSource().equals(mCancel)) {
+ //setVisible(false);
+ mCanceled = true;
+ this.dispose();
+ return;
+ }
+ }
+
+
+ //== DocumentListener ==
+ public void insertUpdate(DocumentEvent e) {
+ setButtons();
+ }
+
+ public void removeUpdate(DocumentEvent e){
+ setButtons();
+ }
+
+ public void changedUpdate(DocumentEvent e){
+ setButtons();
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {}
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {
+ setButtons();
+ }
+
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null,
+ this);
+ mOK.setEnabled(false);
+ mCancel = CMSAdminUtil.makeJButton(mResource, PREFIX, "CANCEL",
+ null, this);
+ JButton[] buttons = { mOK, mCancel};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonPanel(buttons);
+ }
+
+ //set buttons
+ private void setButtons() {
+ if ( (mPasswordField.getText().trim().equals("")) ||
+ (mPasswordFieldAgain.getText().trim().equals("")) ||
+ (mOldPasswordField.getText().trim().equals("")) ) {
+ mOK.setEnabled(false);
+ } else {
+ mOK.setEnabled(true);
+ }
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSPluginInstanceTab.java b/base/console/src/com/netscape/admin/certsrv/config/CMSPluginInstanceTab.java
new file mode 100644
index 000000000..d4fb62340
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSPluginInstanceTab.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Plugin Instances Management Tab
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public abstract class CMSPluginInstanceTab extends CMSBaseUGTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ protected static String PANEL_NAME = null;
+ protected static String RULE_NAME = null;
+ protected static String RULE_STAT = null;
+ protected static String RULE_IMPL = null;
+ protected static String RULE_TYPE = null;
+
+
+ protected AdminConnection mConnection;
+
+ protected JScrollPane mScrollPane;
+ protected JTable mTable; //table
+ protected CMSRuleDataModel mDataModel; //table model
+ protected String mDestination; //dest flag
+ protected String mScope;
+ protected String mId = null; // used as a ip id for crl exts
+
+ protected JButton mRefresh, mEdit, mAdd, mDelete, mOrder, mHelp;
+ protected static String RAHELPINDEX = null;
+ protected static String CAHELPINDEX = null;
+ protected static String KRAHELPINDEX = null;
+ protected static String OCSPHELPINDEX = null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSPluginInstanceTab(CMSBaseResourceModel model, String dest,
+ String panelName) {
+ super(panelName, model);
+ Debug.println("CMSPluginInstanceTab::CMSPluginInstanceTab(<model>,"+dest+","+panelName+")");
+ mConnection = model.getServerInfo().getAdmin();
+ mDestination = dest;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /*==========================================================
+ * EVENT HANDLER METHODS
+ *==========================================================*/
+
+ public CMSBaseConfigDialog makeEditConfigDialog(
+ NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest
+ )
+ {
+ // make it possible to use a different dialog for
+ // edit operation
+ return makeNewConfigDialog(nvp, parent, conn, dest);
+ }
+
+ public abstract CMSBaseConfigDialog makeNewConfigDialog(
+ NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest
+ );
+
+ public abstract PluginSelectionDialog getPluginSelectionDialog(
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType
+ );
+
+ /**
+ * Can override this to handle more events if needed
+ */
+ public void moreActionPerformed(ActionEvent e)
+ {
+ return;
+ }
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mRefresh)) {
+ Debug.println("Refresh");
+ refresh();
+ }
+ if (e.getSource().equals(mEdit)) {
+ if(mTable.getSelectedRow()< 0)
+ return;
+ NameValuePairs data = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+
+ NameValuePairs response;
+ mModel.progressStart();
+ try{
+ response = getConfig();
+ } catch (EAdminException ex1) {
+ showErrorDialog(ex1.getMessage());
+ mModel.progressStop();
+ return;
+ }
+ mModel.progressStop();
+ Debug.println(response.toString());
+
+ CMSBaseConfigDialog dialog = makeEditConfigDialog(
+ response,
+ mModel.getFrame(),
+ mModel.getServerInfo().getAdmin(),
+ mDestination);
+
+ dialog.setModel(mModel);
+ dialog.setInstanceScope(mScope);
+ dialog.showDialog(response, data.get(RULE_NAME));
+
+ if(!dialog.isOK()) return;
+
+ refresh();
+ }
+
+ if (e.getSource().equals(mAdd)) {
+ Debug.println("Add");
+ PluginSelectionDialog dialog =
+ getPluginSelectionDialog(
+ mModel.getFrame(),
+ mConnection,
+ mDestination,
+ this
+ );
+
+ dialog.setModel(mModel);
+ dialog.showDialog();
+ refresh();
+ }
+
+ if (e.getSource().equals(mDelete)) {
+ Debug.println("Delete");
+ if(mTable.getSelectedRow()< 0)
+ return;
+ int i = showConfirmDialog("DELETE");
+ if (i == JOptionPane.YES_OPTION) {
+ delete();
+ Debug.println("Deleted");
+ }
+ }
+ if (e.getSource().equals(mHelp)) {
+ helpCallback();
+ }
+ moreActionPerformed(e);
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+ public void refresh() {
+
+ mDataModel.removeAllRows();
+ update();
+
+ setButtons();
+ }
+
+ /**
+ * create the user action button panel
+ */
+ protected JPanel createUserButtonPanel() {
+ Debug.println("CMSPluginInstanceTab::createUserButtonPanel()");
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mEdit = makeJButton("EDIT");
+ mAdd = makeJButton("ADD");
+ mDelete = makeJButton("DELETE");
+ JButton[] buttons = {mAdd, mDelete, mEdit};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ protected JPanel createActionPanel() {
+ Debug.println("CMSPluginInstanceTab::createActionPanel()");
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mRefresh = makeJButton("REFRESH");
+ mHelp = makeJButton("HELP");
+ //JButton[] buttons = { mRefresh, mHelp };
+ JButton[] buttons = { mRefresh };
+ return makeJButtonPanel( buttons , true);
+ }
+
+ protected JPanel createListPanel() {
+ Debug.println("CMSPluginInstanceTab::createListPanel()");
+ try {
+ mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ //center table
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ mTable.addMouseListener(this);
+ setLabelCellRenderer(mTable,0);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = 1;
+ gbc.weightx = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ JPanel buttonPanel = createUserButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ mListPanel.add(buttonPanel);
+
+ refresh();
+
+ Debug.println("returning from CMSPluginInstanceTab::createListPanel()");
+
+ } catch (Exception e3) {
+ Debug.println("e3: caught exception:");
+ if (Debug.isEnabled())
+ e3.printStackTrace();
+ }
+ return mListPanel;
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ Debug.println("Table.getColumnModel = "+table.getColumnModel());
+ table.getColumnModel().getColumn(index).setCellRenderer(new LabelCellRenderer(new JLabel()));
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellEditor(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(new PasswordCellRenderer());
+ table.getColumnModel().getColumn(index).setCellEditor(new DefaultCellEditor(new JPasswordField()));
+ }
+
+
+ //set buttons
+ protected void setButtons() {
+
+ //enable and diable buttons accordingly
+ //Debug.println("setButtons() - "+mTable.getSelectedRow());
+
+ if (mTable.getSelectionModel().isSelectionEmpty()) {
+ mDelete.setEnabled(false);
+ mEdit.setEnabled(false);
+ return;
+ }
+
+ if(mDataModel.getRowCount()<=0) {
+ mDelete.setEnabled(false);
+ mEdit.setEnabled(false);
+ return;
+ }
+
+ mDelete.setEnabled(true);
+ mEdit.setEnabled(true);
+ }
+
+ //=============================================
+ // SEND REQUESTS TO THE SERVER SIDE
+ //=============================================
+ private void update() {
+ //send request and parse data
+
+ NameValuePairs response;
+ NameValuePairs request = new NameValuePairs();
+ if (mId != null && mId.length() > 0) {
+ request.put(Constants.PR_ID, mId);
+ }
+
+ try {
+ Debug.println("CMSPluginInstanceTab:update() ---- 1 --- ");
+ Debug.println("mConnection = "+mConnection);
+ response = mConnection.search(mDestination,
+ mScope,
+ request);
+ } catch (EAdminException e) {
+ //display error dialog
+ if (Debug.isEnabled())
+ e.printStackTrace();
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+
+ Debug.println(response.toString());
+
+ /* format of each data element:
+ plugin;visibility;enabled
+ where plugin is the name of the plugin impl
+ visibility is one of {visible,invisible}
+ enabled is one of {enabled,disabled}
+ */
+
+ for (String entry : response.keySet()) {
+ String plugin="";
+ String visibility=null;
+ String enabled=null;
+
+ entry = entry.trim();
+ String value = response.get(entry);
+
+ StringTokenizer st = new StringTokenizer(value,";");
+
+ if (st.hasMoreElements()) {
+ plugin = st.nextToken();
+Debug.println("xxxxxxx plugin " + plugin);
+ if (st.hasMoreElements()) {
+ visibility = st.nextToken();
+ if (st.hasMoreElements()) {
+ enabled = st.nextToken();
+ }
+ }
+ }
+
+ if (visibility != null && visibility.equals("visible")) {
+
+ NameValuePairs data = new NameValuePairs();
+ data.put(RULE_NAME, entry);
+ data.put(RULE_IMPL, plugin);
+ if (enabled != null) {
+ data.put(RULE_STAT, enabled);
+ }
+ mDataModel.processData(data);
+ }
+ }
+
+ if (mDataModel.getRowCount() >0)
+ mTable.setRowSelectionInterval(0,0);
+
+ mTable.invalidate();
+ mTable.validate();
+ mTable.repaint(1);
+ mModel.progressStop();
+ }
+
+ private void delete() {
+
+ mModel.progressStart();
+ //get entry name
+ NameValuePairs data = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+
+ //send comment to server for the removal of user
+ try {
+ mConnection.delete(mDestination,
+ mScope,
+ data.get(RULE_NAME));
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+
+ mModel.progressStop();
+ //send comment to server and refetch the content
+ refresh();
+
+ }
+
+ //this returns the onfiguration
+ private NameValuePairs getConfig() throws EAdminException {
+ NameValuePairs data = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+ NameValuePairs request = new NameValuePairs();
+ if (mId != null && mId.length() > 0) {
+ request.put(mId, "");
+ }
+
+ NameValuePairs response = mConnection.read(mDestination,
+ mScope,
+ data.get(RULE_NAME),
+ request);
+ return response;
+ }
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSRACLMPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSRACLMPanel.java
new file mode 100644
index 000000000..734425b41
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSRACLMPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * RA CLM Setting
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class CMSRACLMPanel extends CMSBaseTab {
+
+ private static String PANEL_NAME = "RACLM";
+ private static CMSBaseResourceModel mModel;
+ protected AdminConnection mAdmin;
+ private JCheckBox mRenewEnable;
+ private JTextField mValidText;
+ private JTextField mEmailText;
+ private JCheckBox mNotifyEnable;
+ private JTextField mNotifiedText;
+ private JTextField mIntervalText;
+ private Color mActiveColor;
+ private CMSTabPanel mParent;
+ private static final String HELPINDEX =
+ "configuration-ra-clm-help";
+
+ public CMSRACLMPanel(CMSTabPanel parent) {
+ super(PANEL_NAME, parent);
+ mModel = parent.getResourceModel();
+ mParent = parent;
+ mHelpToken = HELPINDEX;
+ }
+
+ public void init() {
+ Debug.println("CMSRACLMPanel: init()");
+ mAdmin = mModel.getServerInfo().getAdmin();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ CMSAdminUtil.resetGBC(gbc);
+ mCenterPanel.setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRenewEnable = makeJCheckBox("RENEWENABLED");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gb.setConstraints(mRenewEnable, gbc);
+ mCenterPanel.add(mRenewEnable);
+
+ JPanel adminPanel = new JPanel();
+ GridBagLayout gb1 = new GridBagLayout();
+ adminPanel.setLayout(gb1);
+ adminPanel.setBorder(makeTitledBorder("CLMRENEWAL"));
+
+ CMSAdminUtil.resetGBC(gbc);
+ mCenterPanel.setLayout(gb);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(adminPanel, gbc);
+ mCenterPanel.add(adminPanel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel validLbl = makeJLabel("VALID");
+ mValidText = makeJTextField(4);
+ mActiveColor = mValidText.getBackground();
+ JLabel day1Lbl = makeJLabel("DAYS");
+ CMSAdminUtil.addEntryField(adminPanel, validLbl, mValidText,
+ day1Lbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ //JLabel dummy2 = new JLabel("");
+ mNotifyEnable = makeJCheckBox("NOTIFIED");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gb1.setConstraints(mNotifyEnable, gbc);
+ adminPanel.add(mNotifyEnable);
+
+ //CMSAdminUtil.addEntryField(adminPanel, dummy2, mNotifyEnable, gbc);
+
+ JPanel subPanel = new JPanel();
+ GridBagLayout gb2 = new GridBagLayout();
+ subPanel.setLayout(gb2);
+ subPanel.setBorder(makeTitledBorder("CLMRENEWALNOTIFY"));
+
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb1.setConstraints(subPanel, gbc);
+ adminPanel.add(subPanel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel emailLbl = makeJLabel("EMAIL");
+ mEmailText = makeJTextField(30);
+ CMSAdminUtil.addEntryField(subPanel, emailLbl, mEmailText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel numNotifyLbl = makeJLabel("NUMNOTIFIED");
+ mNotifiedText = makeJTextField(4);
+ CMSAdminUtil.addEntryField(subPanel, numNotifyLbl, mNotifiedText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel intervalLbl = makeJLabel("INTERVAL");
+ mIntervalText = makeJTextField(4);
+ JLabel day2Lbl = makeJLabel("DAYS");
+ CMSAdminUtil.addEntryField(subPanel, intervalLbl, mIntervalText,
+ day2Lbl, gbc);
+
+ refresh();
+ }
+
+ public void refresh() {
+ mModel.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_RENEWAL_ENABLED, "");
+ nvps.put(Constants.PR_RENEWAL_VALIDITY, "");
+ nvps.put(Constants.PR_RENEWAL_EMAIL, "");
+ nvps.put(Constants.PR_RENEWAL_EXPIREDNOTIFIEDENABLED, "");
+ nvps.put(Constants.PR_RENEWAL_NUMNOTIFICATION, "");
+ nvps.put(Constants.PR_RENEWAL_INTERVAL, "");
+
+ try {
+ NameValuePairs val = mAdmin.read(DestDef.DEST_RA_ADMIN,
+ ScopeDef.SC_CLM, Constants.RS_ID_CONFIG, nvps);
+
+ populate(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+ }
+
+ protected void populate(NameValuePairs nvps) {
+ boolean renewalEnabled = false;
+ boolean notificationEnabled = false;
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name);
+ if (name.equals(Constants.PR_RENEWAL_ENABLED)) {
+ renewalEnabled = getBoolean(value);
+ mRenewEnable.setSelected(renewalEnabled);
+ } else if (name.equals(Constants.PR_RENEWAL_EXPIREDNOTIFIEDENABLED)) {
+ notificationEnabled = getBoolean(value);
+ mNotifyEnable.setSelected(notificationEnabled);
+ } else if (name.equals(Constants.PR_RENEWAL_VALIDITY)) {
+ mValidText.setText(value);
+ } else if (name.equals(Constants.PR_RENEWAL_EMAIL)) {
+ mEmailText.setText(value);
+ } else if (name.equals(Constants.PR_RENEWAL_NUMNOTIFICATION)) {
+ mNotifiedText.setText(value);
+ } else if (name.equals(Constants.PR_RENEWAL_INTERVAL)) {
+ mIntervalText.setText(value);
+ }
+ }
+
+ if (renewalEnabled) {
+ enableRenewal(renewalEnabled, mActiveColor);
+ if (notificationEnabled)
+ enableNotification(notificationEnabled, mActiveColor);
+ else
+ enableNotification(notificationEnabled, getBackground());
+ } else {
+ enableRenewal(renewalEnabled, getBackground());
+ enableNotification(renewalEnabled, getBackground());
+ }
+ }
+
+ private boolean getBoolean(String str) {
+ if (str.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ private void enableRenewal(boolean renewalEnabled, boolean notificationEnabled) {
+
+ if (renewalEnabled) {
+ enableRenewal(renewalEnabled, mActiveColor);
+ if (notificationEnabled)
+ enableNotification(notificationEnabled, mActiveColor);
+ else
+ enableNotification(notificationEnabled, getBackground());
+ } else {
+ enableRenewal(renewalEnabled, getBackground());
+ enableNotification(renewalEnabled, getBackground());
+ }
+ }
+
+ private void enableRenewal(boolean enable, Color color) {
+ mValidText.setEnabled(enable);
+ mValidText.setEditable(enable);
+ mValidText.setBackground(color);
+ mNotifyEnable.setEnabled(enable);
+ mNotifyEnable.setBackground(color);
+ //enableNotification(enable, color);
+ }
+
+ private void enableNotification(boolean enable, Color color) {
+ mEmailText.setEnabled(enable);
+ mEmailText.setEditable(enable);
+ mEmailText.setBackground(color);
+ mNotifiedText.setEnabled(enable);
+ mNotifiedText.setEditable(enable);
+ mNotifiedText.setBackground(color);
+ mIntervalText.setEnabled(enable);
+ mIntervalText.setEditable(enable);
+ mIntervalText.setBackground(color);
+ invalidate();
+ validate();
+ repaint(1);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ super.actionPerformed(e);
+ if (e.getSource().equals(mRenewEnable) ||
+ e.getSource().equals(mNotifyEnable)) {
+ enableRenewal(mRenewEnable.isSelected(),
+ mNotifyEnable.isSelected());
+ }
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ NameValuePairs nvps = new NameValuePairs();
+ if (mRenewEnable.isSelected()) {
+ nvps.put(Constants.PR_RENEWAL_ENABLED, Constants.TRUE);
+ String validStr = mValidText.getText();
+ try {
+ int num = Integer.parseInt(validStr);
+ } catch (NumberFormatException e) {
+ showMessageDialog("NUMBERFORMAT");
+ return false;
+ }
+ nvps.put(Constants.PR_RENEWAL_VALIDITY, validStr);
+
+ if (mNotifyEnable.isSelected()) {
+ nvps.put(Constants.PR_RENEWAL_EXPIREDNOTIFIEDENABLED,
+ Constants.TRUE);
+ nvps.put(Constants.PR_RENEWAL_EMAIL, mEmailText.getText());
+ String numStr = mNotifiedText.getText();
+ String intervalStr = mIntervalText.getText();
+
+ try {
+ int num1 = Integer.parseInt(numStr);
+ int num2 = Integer.parseInt(intervalStr);
+ } catch (NumberFormatException ex) {
+ showMessageDialog("NUMBERFORMAT");
+ return false;
+ }
+
+ nvps.put(Constants.PR_RENEWAL_NUMNOTIFICATION, numStr);
+ nvps.put(Constants.PR_RENEWAL_INTERVAL, intervalStr);
+ } else {
+ nvps.put(Constants.PR_RENEWAL_EXPIREDNOTIFIEDENABLED,
+ Constants.FALSE);
+ }
+ } else {
+ nvps.put(Constants.PR_RENEWAL_ENABLED, Constants.FALSE);
+ }
+
+ mModel.progressStart();
+ try {
+ mAdmin.modify(DestDef.DEST_RA_ADMIN,
+ ScopeDef.SC_CLM, Constants.RS_ID_CONFIG, nvps);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ return false;
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSRAConnectorPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSRAConnectorPanel.java
new file mode 100644
index 000000000..7733a43d7
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSRAConnectorPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * RA Connector Panel
+ *
+ * @author Christine Ho
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class CMSRAConnectorPanel extends CMSBaseTab
+ implements MouseListener
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+
+ private final static String PANEL_NAME = "CONNECTOR";
+ private final static String HELPINDEX = "configuration-ra-connector-help";
+
+ private AdminConnection mAdmin;
+ private CMSBaseResourceModel mModel;
+ private CMSTabPanel mParent;
+ private JList mList;
+ private DefaultListModel mDataModel;
+ private JScrollPane mScrollPane;
+ private JButton mEdit;
+ protected boolean mInit = false;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSRAConnectorPanel(CMSBaseResourceModel model, CMSTabPanel parent) {
+ super(PANEL_NAME, parent);
+ mModel = model;
+ mParent = parent;
+ mDataModel = new DefaultListModel();
+ mHelpToken = HELPINDEX;
+
+ // hardcoded just for beta 1
+ mDataModel.addElement("Certificate Manager Connector");
+ mDataModel.addElement("Data Recovery Manager Connector");
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * initialize the UI components
+ */
+ public void init() {
+// setLayout(new BorderLayout());
+
+ // JPanel mainPanel = new JPanel();
+ JPanel mainPanel = mCenterPanel;
+
+
+ Debug.println("ConnectorPanel: init()");
+ mAdmin = mModel.getServerInfo().getAdmin();
+
+ GridBagLayout gb1 = new GridBagLayout();
+ mainPanel.setLayout(gb1);
+
+ GridBagConstraints gbc = new GridBagConstraints();
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel listLabel = makeJLabel("CONNLIST");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(DIFFERENT_COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,
+ 0,DIFFERENT_COMPONENT_SPACE);
+ gb1.setConstraints(listLabel, gbc);
+ mainPanel.add(listLabel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mList = makeJList(mDataModel, 3);
+ mScrollPane = new JScrollPane(mList,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mList.addMouseListener(this);
+ mScrollPane.setBackground(Color.white);
+ mScrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 0.5;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,
+ 0,DIFFERENT_COMPONENT_SPACE);
+ gb1.setConstraints(mScrollPane, gbc);
+ mainPanel.add(mScrollPane);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEdit = makeJButton("EDIT");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ gbc.weightx = 0.5;
+ gbc.insets = new Insets(COMPONENT_SPACE,0,
+ 0,DIFFERENT_COMPONENT_SPACE);
+ gb1.setConstraints(mEdit, gbc);
+ mainPanel.add(mEdit);
+
+ // add("Center",mainPanel);
+ refresh();
+ }
+
+ /**
+ * refresh the panel data
+ */
+ public void refresh() {
+/*
+ NameValuePairs response;
+ mModel.progressStart();
+ try {
+ response = mAdmin.search(DestDef.DEST_RA_ADMIN,
+ ScopeDef.SC_CONNECTOR, new NameValuePairs());
+
+ Debug.println(response.toString());
+ populate(response);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ }
+ mModel.progressStop();
+*/
+ }
+
+ /*==========================================================
+ * Event Handler
+ *==========================================================*/
+
+ //======= ActionLister ============================
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mEdit)) {
+ JFrame frame = mModel.getFrame();
+ String name = (String)mList.getSelectedValue();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_ID, "");
+ nvps.put(Constants.PR_HOST, "");
+ nvps.put(Constants.PR_PORT, "");
+ // Inserted by beomsuk
+ nvps.put(Constants.PR_TIMEOUT, "");
+ // Insert end
+ nvps.put(Constants.PR_URI, "");
+ nvps.put(Constants.PR_LOCAL, "");
+ nvps.put(Constants.PR_ENABLE, "");
+
+ try {
+ NameValuePairs values = mAdmin.read(DestDef.DEST_RA_ADMIN,
+ ScopeDef.SC_CONNECTOR, name, nvps);
+
+ NameValuePairs subsystems = mAdmin.search(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_SUBSYSTEM, new NameValuePairs());
+
+ boolean colocated = false;
+ if (name.equals("Data Recovery Manager Connector")) {
+ String val = values.get("id");
+ if (val != null && val.equals("kra"))
+ colocated = true;
+ }
+ ConnectorEditor editor = new ConnectorEditor(mAdmin,
+ mModel.getFrame(), name, DestDef.DEST_RA_ADMIN,
+ mModel.getServerInfo().getServerId(), colocated);
+ editor.showDialog(values);
+ } catch (EAdminException ex) {
+ showErrorDialog(ex.toString());
+ }
+/*
+ NameValuePairs values = new NameValuePairs();
+ ConnectorEditor editor = new ConnectorEditor(mAdmin,
+ mModel.getFrame(), name);
+ editor.showDialog(values);
+*/
+ }
+ }
+
+ //=== MOUSELISTENER ========================
+ public void mouseClicked(MouseEvent e) {
+ if (e.getSource() == mList) {
+ if (mList.getSelectedIndex() < 0)
+ mEdit.setEnabled(false);
+ else
+ mEdit.setEnabled(true);
+ }
+ }
+
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {}
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {}
+
+ //======== CMSBaseConfigPanel ==============
+ public boolean applyCallback() {
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ //update the UI component using the data retrieved
+ private void populate(NameValuePairs nvps) {
+/*
+ Enumeration names = nvps.getNames();
+ mDataModel.removeAllElements();
+ while (names.hasMoreElements())
+ mDataModel.addElement(names.nextElement());
+
+ if (mDataModel.size() > 0) {
+ mList.setSelectedIndex(0);
+ mEdit.setEnabled(true);
+ } else
+ mEdit.setEnabled(false);
+*/
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSRAGeneralPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSRAGeneralPanel.java
new file mode 100644
index 000000000..6605385b0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSRAGeneralPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * RA General Setting
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class CMSRAGeneralPanel extends CMSBaseTab {
+
+ private static String PANEL_NAME = "RAGENERAL";
+ private static CMSBaseResourceModel mModel;
+ protected AdminConnection mAdmin;
+ private JCheckBox mRAEnable;
+ private JCheckBox mEEEnable;
+ private CMSTabPanel mParent;
+ private static final String HELPINDEX =
+ "configuration-ra-general-help";
+
+ public CMSRAGeneralPanel(CMSTabPanel parent) {
+ super(PANEL_NAME, parent);
+ mModel = parent.getResourceModel();
+ mParent = parent;
+ mHelpToken = HELPINDEX;
+ }
+
+ public void init() {
+ Debug.println("CMSRAGeneral: init()");
+ mAdmin = mModel.getServerInfo().getAdmin();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ CMSAdminUtil.resetGBC(gbc);
+ mCenterPanel.setLayout(gb);
+
+ JPanel adminPanel = new JPanel();
+ GridBagLayout gb1 = new GridBagLayout();
+ adminPanel.setLayout(gb1);
+ adminPanel.setBorder(makeTitledBorder("PARAMETERS"));
+
+ CMSAdminUtil.resetGBC(gbc);
+ mCenterPanel.setLayout(gb);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(adminPanel, gbc);
+ mCenterPanel.add(adminPanel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEEEnable = makeJCheckBox("EE");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb1.setConstraints(mEEEnable, gbc);
+ adminPanel.add(mEEEnable);
+
+/*
+ CMSAdminUtil.resetGBC(gbc);
+ mRAEnable = makeJCheckBox("RA");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb1.setConstraints(mRAEnable, gbc);
+ adminPanel.add(mRAEnable);
+*/
+
+ refresh();
+ }
+
+ public void refresh() {
+ mModel.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_EE_ENABLED, "");
+ //nvps.add(Constants.PR_RA_ENABLED, "");
+
+ try {
+ NameValuePairs val = mAdmin.read(DestDef.DEST_RA_ADMIN,
+ ScopeDef.SC_GENERAL, Constants.RS_ID_CONFIG, nvps);
+
+ populate(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ }
+
+ protected void populate(NameValuePairs nvps) {
+ Debug.println("RA General Received: "+nvps.toString());
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name);
+ if (name.equals(Constants.PR_EE_ENABLED)) {
+ mEEEnable.setSelected(getBoolean(value));
+/*
+ } else if (name.equals(Constants.PR_RA_ENABLED)) {
+ mRAEnable.setSelected(getBoolean(value));
+*/
+ }
+ }
+ }
+
+ private boolean getBoolean(String str) {
+ if (str.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ super.actionPerformed(e);
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ NameValuePairs nvps = new NameValuePairs();
+
+ if (mEEEnable.isSelected())
+ nvps.put(Constants.PR_EE_ENABLED, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_EE_ENABLED, Constants.FALSE);
+
+/*
+ if (mRAEnable.isSelected())
+ nvps.add(Constants.PR_RA_ENABLED, Constants.TRUE);
+ else
+ nvps.add(Constants.PR_RA_ENABLED, Constants.FALSE);
+*/
+
+ mModel.progressStart();
+ try {
+ mAdmin.modify(DestDef.DEST_RA_ADMIN,
+ ScopeDef.SC_GENERAL, Constants.RS_ID_CONFIG, nvps);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ return false;
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSRALDAPPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSRALDAPPanel.java
new file mode 100644
index 000000000..3fbe6a72a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSRALDAPPanel.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.admin.certsrv.config;
+
+import com.netscape.management.client.util.*;
+
+/**
+ * LDAP server setting tab
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class CMSRALDAPPanel extends CMSBaseLDAPPanel {
+
+ private static String PANEL_NAME = "RALDAPSETTING";
+ private static final String HELPINDEX =
+ "configuration-ra-ldappublish-destination-help";
+
+ public CMSRALDAPPanel(CMSTabPanel parent) {
+ super(PANEL_NAME, parent);
+ mHelpToken = HELPINDEX;
+ }
+
+ public void init() {
+ super.init();
+ refresh();
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSRuleDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSRuleDataModel.java
new file mode 100644
index 000000000..2c12183c7
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSRuleDataModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.certsrv.common.*;
+
+
+/**
+ * instance Data model - represents the instance
+ * table information
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public abstract class CMSRuleDataModel extends CMSContentTableModel
+ implements IDataProcessor
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String RULE_NAME = "RULENAME";
+ public static final String RULE_STAT = "STATUS";
+ public static final String RULE_IMPL = "IMPL";
+ public static final String RULE_TYPE = "TYPE";
+
+ protected static String[] mColumns = null;
+ protected Vector mRules;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSRuleDataModel() {
+ super();
+ mColumns = getColumns();
+ init(mColumns);
+ mRules = new Vector();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ protected abstract String[] getColumns();
+
+ /**
+ * clean up the table including the datat objects
+ */
+ public void removeAllRows() {
+ super.removeAllRows();
+ mRules.removeAllElements();
+ }
+
+
+ public Vector getRules() {
+ return (Vector) mRules.clone();
+ }
+
+ public boolean isCellEditable(int row, int col) {
+ return false;
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSSMTPPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSSMTPPanel.java
new file mode 100644
index 000000000..0275e3cb0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSSMTPPanel.java
@@ -0,0 +1,170 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * SMTP setting tab
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class CMSSMTPPanel extends CMSBaseTab {
+ private static String PANEL_NAME = "SMTPSETTING";
+ private JTextField mServerText;
+ private JTextField mPortText;
+ private Color mActiveColor;
+ private AdminConnection mAdmin;
+ private CMSBaseResourceModel mModel;
+ private CMSTabPanel mParent;
+ private static final String HELPINDEX =
+ "configuration-system-smtp-help";
+
+ public CMSSMTPPanel(CMSTabPanel parent) {
+ super(PANEL_NAME, parent);
+ mModel = parent.getResourceModel();
+ mParent = parent;
+ mHelpToken = HELPINDEX;
+ }
+
+ public void init() {
+ Debug.println("SMTPPanel: init()");
+ mAdmin = mModel.getServerInfo().getAdmin();
+ JPanel smtpInfo = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ CMSAdminUtil.resetGBC(gbc);
+ mCenterPanel.setLayout(gb);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(smtpInfo, gbc);
+ mCenterPanel.add(smtpInfo);
+
+ GridBagLayout gb1 = new GridBagLayout();
+ smtpInfo.setLayout(gb1);
+
+ // add server name label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel serverLabel = makeJLabel("SERVER");
+ mServerText = makeJTextField(30);
+ mActiveColor = mServerText.getBackground();
+ CMSAdminUtil.addEntryField(smtpInfo, serverLabel, mServerText, gbc);
+
+ // add port number label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel portLabel = makeJLabel("PORT");
+ mPortText = makeJTextField(30);
+ CMSAdminUtil.addEntryField(smtpInfo, portLabel, mPortText, gbc);
+
+ refresh();
+ }
+
+ public void refresh() {
+ mModel.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_SERVER_NAME, "");
+ nvps.put(Constants.PR_PORT, "");
+ try {
+ NameValuePairs val = mAdmin.read(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_SMTP, Constants.RS_ID_CONFIG, nvps);
+
+ populate(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+ }
+
+ private void populate(NameValuePairs nvps) {
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name);
+ if (name.equals(Constants.PR_SERVER_NAME)) {
+ mServerText.setText(value);
+ } else if (name.equals(Constants.PR_PORT)) {
+ mPortText.setText(value);
+ }
+ }
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ super.actionPerformed(e);
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ // check blank field
+ if (mServerText.getText().trim().equals("")) {
+ showMessageDialog("BLANKFIELD");
+ return false;
+ }
+
+ String port = mPortText.getText().trim();
+ try {
+ int num = Integer.parseInt(port);
+ if (num <= 0) {
+ showMessageDialog("OUTOFRANGE");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ showMessageDialog("NUMBERFORMAT");
+ return false;
+ }
+
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_SERVER_NAME, mServerText.getText().trim());
+ nvps.put(Constants.PR_PORT, port);
+ mModel.progressStart();
+ try {
+ mAdmin.modify(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_SMTP, Constants.RS_ID_CONFIG, nvps);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ return false;
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSSNMPPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSSNMPPanel.java
new file mode 100644
index 000000000..b5b589eb0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSSNMPPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * SNMP setting tab
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class CMSSNMPPanel extends CMSBaseTab {
+ private static String PANEL_NAME = "SNMPSETTING";
+ private Color mActiveColor;
+ private JButton mOnB;
+ private JButton mOffB;
+ private JCheckBox mEnable;
+ private JTextField mHostNameText;
+ private JTextField mPortText;
+ private JTextField mDescText;
+ private JTextField mOrgnText;
+ private JTextField mLocText;
+ private JTextField mContactText;
+ private AdminConnection mAdmin;
+ private CMSBaseResourceModel mModel;
+ private CMSTabPanel mParent;
+ private JLabel mHostLabel;
+ private JLabel mPortLabel;
+ private JLabel mDescLabel;
+ private JLabel mOrgnLabel;
+ private JLabel mLocLabel;
+ private JLabel mContactLabel;
+ private static final String HELPINDEX =
+ "configuration-system-snmp-help";
+
+ public CMSSNMPPanel(CMSTabPanel parent) {
+ super(PANEL_NAME, parent);
+ mModel = parent.getResourceModel();
+ mParent = parent;
+ mHelpToken = HELPINDEX;
+ }
+
+ public void init() {
+ Debug.println("SNMPPanel: init()");
+ mAdmin = mModel.getServerInfo().getAdmin();
+ JPanel snmpInfo = new JPanel();
+ snmpInfo.setBorder(CMSAdminUtil.makeEtchedBorder());
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ CMSAdminUtil.resetGBC(gbc);
+ mCenterPanel.setLayout(gb);
+
+ mEnable = makeJCheckBox("ENABLE");
+ mEnable.setActionCommand("enable");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gb.setConstraints(mEnable, gbc);
+ mCenterPanel.add(mEnable);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(snmpInfo, gbc);
+ mCenterPanel.add(snmpInfo);
+
+ mOnB = makeJButton("ON");
+ mOffB = makeJButton("OFF");
+ JButton[] bArray = {mOnB, mOffB};
+ JPanel buttonPanel = CMSAdminUtil.makeJButtonPanel(bArray);
+
+ GridBagLayout gb1 = new GridBagLayout();
+ snmpInfo.setLayout(gb1);
+
+ // add host name label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ mHostLabel = makeJLabel("HOST");
+ mHostNameText = makeJTextField(30);
+ mActiveColor = mHostNameText.getBackground();
+ CMSAdminUtil.addEntryField(snmpInfo, mHostLabel, mHostNameText, gbc);
+
+ // add port label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ mPortLabel = makeJLabel("PORT");
+ mPortText = makeJTextField(30);
+ CMSAdminUtil.addEntryField(snmpInfo, mPortLabel, mPortText, gbc);
+
+ // add description label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ mDescLabel = makeJLabel("DESC");
+ mDescText = makeJTextField(30);
+ CMSAdminUtil.addEntryField(snmpInfo, mDescLabel, mDescText, gbc);
+
+ // add organization label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ mOrgnLabel = makeJLabel("ORGN");
+ mOrgnText = makeJTextField(30);
+ CMSAdminUtil.addEntryField(snmpInfo, mOrgnLabel, mOrgnText, gbc);
+
+ // add location label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ mLocLabel = makeJLabel("LOC");
+ mLocText = makeJTextField(30);
+ CMSAdminUtil.addEntryField(snmpInfo, mLocLabel, mLocText, gbc);
+
+ // add contact label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ mContactLabel = makeJLabel("CONTACT");
+ mContactText = makeJTextField(30);
+ CMSAdminUtil.addEntryField(snmpInfo, mContactLabel, mContactText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gb1.setConstraints(buttonPanel, gbc);
+ snmpInfo.add(buttonPanel);
+
+ refresh();
+ }
+
+ public void refresh() {
+ mModel.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_SNMP_ENABLED, "");
+ nvps.put(Constants.PR_SNMP_MASTER_HOST, "");
+ nvps.put(Constants.PR_SNMP_MASTER_PORT, "");
+ nvps.put(Constants.PR_SNMP_DESC, "");
+ nvps.put(Constants.PR_SNMP_ORGN, "");
+ nvps.put(Constants.PR_SNMP_LOC, "");
+ nvps.put(Constants.PR_SNMP_CONTACT, "");
+
+ try {
+ NameValuePairs val = mAdmin.read(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_SNMP, Constants.RS_ID_CONFIG, nvps);
+
+ populate(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+ }
+
+ private void populate(NameValuePairs nvps) {
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name);
+ if (name.equals(Constants.PR_SNMP_ENABLED)) {
+ mEnable.setSelected(getBoolean(value));
+ } else if (name.equals(Constants.PR_SNMP_MASTER_HOST)) {
+ mHostNameText.setText(value);
+ } else if (name.equals(Constants.PR_SNMP_MASTER_PORT)) {
+ mPortText.setText(value);
+ } else if (name.equals(Constants.PR_SNMP_DESC)) {
+ mDescText.setText(value);
+ } else if (name.equals(Constants.PR_SNMP_ORGN)) {
+ mOrgnText.setText(value);
+ } else if (name.equals(Constants.PR_SNMP_LOC)) {
+ mLocText.setText(value);
+ } else if (name.equals(Constants.PR_SNMP_CONTACT)) {
+ mContactText.setText(value);
+ }
+ }
+
+ if (mEnable.isSelected())
+ enableTextField(true, mActiveColor);
+ else
+ enableTextField(false, getBackground());
+ }
+
+ public boolean getBoolean(String value) {
+ if (value.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ super.actionPerformed(e);
+ if (e.getActionCommand().equals("enable")) {
+ if (mEnable.isSelected()) {
+ enableTextField(true, mActiveColor);
+ } else {
+ enableTextField(false, getBackground());
+ }
+ }
+ }
+
+ private void enableTextField(boolean enable, Color color) {
+ mHostNameText.setEnabled(enable);
+ mHostNameText.setEditable(enable);
+ mHostNameText.setBackground(color);
+ mHostLabel.setEnabled(enable);
+ mPortText.setEnabled(enable);
+ mPortText.setEditable(enable);
+ mPortText.setBackground(color);
+ mPortLabel.setEnabled(enable);
+ mDescText.setEnabled(enable);
+ mDescText.setEditable(enable);
+ mDescText.setBackground(color);
+ mDescLabel.setEnabled(enable);
+ mOrgnText.setEnabled(enable);
+ mOrgnText.setEditable(enable);
+ mOrgnText.setBackground(color);
+ mOrgnLabel.setEnabled(enable);
+ mLocText.setEnabled(enable);
+ mLocText.setEditable(enable);
+ mLocText.setBackground(color);
+ mLocLabel.setEnabled(enable);
+ mContactText.setEnabled(enable);
+ mContactText.setEditable(enable);
+ mContactText.setBackground(color);
+ mContactLabel.setEnabled(enable);
+ mOnB.setEnabled(enable);
+ mOffB.setEnabled(enable);
+ invalidate();
+ validate();
+ repaint(1);
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ String port = mPortText.getText().trim();
+
+ try {
+ Integer num = new Integer(port);
+ } catch (NumberFormatException e) {
+ showMessageDialog("NUMBERFORMAT");
+ return false;
+ }
+
+ NameValuePairs nvps = new NameValuePairs();
+ if (mEnable.isSelected())
+ nvps.put(Constants.PR_SNMP_ENABLED, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_SNMP_ENABLED, Constants.FALSE);
+
+ nvps.put(Constants.PR_SNMP_MASTER_HOST, mHostNameText.getText().trim());
+ nvps.put(Constants.PR_SNMP_MASTER_PORT, port);
+ nvps.put(Constants.PR_SNMP_DESC, mDescText.getText().trim());
+ nvps.put(Constants.PR_SNMP_ORGN, mOrgnText.getText().trim());
+ nvps.put(Constants.PR_SNMP_LOC, mLocText.getText().trim());
+ nvps.put(Constants.PR_SNMP_CONTACT, mContactText.getText().trim());
+
+ mModel.progressStart();
+ try {
+ mAdmin.modify(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_SNMP, Constants.RS_ID_CONFIG, nvps);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ return false;
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSSSL2CipherPreference.java b/base/console/src/com/netscape/admin/certsrv/config/CMSSSL2CipherPreference.java
new file mode 100644
index 000000000..4e95d25db
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSSSL2CipherPreference.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.security.*;
+/**
+ * Constructs panel containing a SSL2 cipher suites
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+
+public class CMSSSL2CipherPreference extends CMSCipherPreferencePane
+ implements ICipherConstants {
+
+ public CMSSSL2CipherPreference(boolean isDomestic) {
+ super(new CMSSSL2CipherSet(isDomestic), true);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSSSL2CipherSet.java b/base/console/src/com/netscape/admin/certsrv/config/CMSSSL2CipherSet.java
new file mode 100644
index 000000000..fa18107cb
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSSSL2CipherSet.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.security.*;
+import java.util.*;
+
+/**
+ * Constructs a SSL2 cipher suites.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class CMSSSL2CipherSet implements ICipherConstants, IAbstractCipherSet {
+ Vector cipherList = new Vector();
+ String title;
+
+ boolean defaultOn = true;
+
+ /**
+ * Create a SSL2 cipher set
+ * @param isDomestic show all ssl2 ciphers for domestic and export version.
+ */
+ public CMSSSL2CipherSet(boolean isDomestic) {
+ ResourceBundle resource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ cipherList.addElement(
+ new AbstractCipher(resource.getString("SSL2CIPHERPREF_RC440MD5"),
+ RC4EXPORT, defaultOn));
+ cipherList.addElement(
+ new AbstractCipher(resource.getString("SSL2CIPHERPREF_RC240MD5"),
+ RC2EXPORT, defaultOn));
+ cipherList.addElement(
+ new AbstractCipher(resource.getString("SSL2CIPHERPREF_DES56MD5"),
+ DES, defaultOn));
+ if (isDomestic) {
+ cipherList.addElement(
+ new AbstractCipher(resource.getString("SSL2CIPHERPREF_RC4128MD5"),
+ RC4, defaultOn));
+ cipherList.addElement(
+ new AbstractCipher(resource.getString("SSL2CIPHERPREF_RC2128MD5"),
+ RC2, defaultOn));
+ cipherList.addElement(
+ new AbstractCipher(resource.getString("SSL2CIPHERPREF_TRIPLEDES168MD5"),
+ DES3, defaultOn));
+ }
+ title = resource.getString("SSL2CIPHERPREF_TITLE");
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public Vector getCipherList() {
+ return cipherList;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSSSL3CipherPreference.java b/base/console/src/com/netscape/admin/certsrv/config/CMSSSL3CipherPreference.java
new file mode 100644
index 000000000..63444fc75
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSSSL3CipherPreference.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.security.*;
+
+/**
+ * Constructs panel containing a SSL3 cipher suites
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+
+public class CMSSSL3CipherPreference extends CMSCipherPreferencePane
+ implements ICipherConstants {
+
+ public CMSSSL3CipherPreference(boolean isDomestic, boolean hasFortezza) {
+ super(new CMSSSL3CipherSet(isDomestic, hasFortezza), true);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSSSL3CipherSet.java b/base/console/src/com/netscape/admin/certsrv/config/CMSSSL3CipherSet.java
new file mode 100644
index 000000000..0286f3820
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSSSL3CipherSet.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.security.*;
+import java.util.*;
+import com.netscape.admin.certsrv.*;
+
+/**
+ * Constructs a SSL3 cipher suites.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class CMSSSL3CipherSet implements ICipherConstants, IAbstractCipherSet {
+ Vector cipherList = new Vector();
+ String title;
+
+ boolean defaultOn = true;
+
+ /**
+ * Create a SSL3 cipher set
+ * @param isDomestic show all ssl2 ciphers for domestic and export version.
+ */
+ public CMSSSL3CipherSet(boolean isDomestic, boolean hasFortezza) {
+ ResourceBundle resource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ cipherList.addElement(
+ new AbstractCipher(resource.getString("SSL3CIPHERPREF_RC440MD5"),
+ RSA_RC4_40_MD5, defaultOn));
+ cipherList.addElement(
+ new AbstractCipher(resource.getString("SSL3CIPHERPREF_RC240MD5"),
+ RSA_RC2_40_MD5, defaultOn));
+ cipherList.addElement(
+ new AbstractCipher(resource.getString("SSL3CIPHERPREF_DES56SHA"),
+ RSA_DES_SHA, defaultOn));
+ cipherList.addElement(
+ new AbstractCipher(resource.getString("SSL3CIPHERPREF_FIPSDES56SHA"),
+ RSA_FIPS_DES_SHA, defaultOn));
+ if (isDomestic) {
+ cipherList.addElement(
+ new AbstractCipher(resource.getString("SSL3CIPHERPREF_RC4128MD5"),
+ RSA_RC4_128_MD5, defaultOn));
+ cipherList.addElement(
+ new AbstractCipher(resource.getString("SSL3CIPHERPREF_TRIPLEDES168SHA"),
+ RSA_3DES_SHA, defaultOn));
+ cipherList.addElement(
+ new AbstractCipher(resource.getString("SSL3CIPHERPREF_TRIPLEDES168SHA"),
+ RSA_FIPS_3DES_SHA, defaultOn));
+ if (hasFortezza) {
+ cipherList.addElement(
+ new AbstractCipher(resource.getString("SSL3CIPHERPREF_FORT80SHA"),
+ FORTEZZA, !defaultOn));
+ cipherList.addElement(
+ new AbstractCipher(resource.getString("SSL3CIPHERPREF_RC4128FORTSHA"),
+ FORTEZZA_RC4_128_SHA, !defaultOn));
+ cipherList.addElement(
+ new AbstractCipher(resource.getString("SSL3CIPHERPREF_NOENCRYPTIONFORSHA"),
+ FORTEZZA_NULL, !defaultOn));
+ }
+ }
+ cipherList.addElement(
+ new AbstractCipher(resource.getString("SSL3CIPHERPREF_NOENCRYPTION"),
+ RSA_NULL_MD5, !defaultOn));
+ title = resource.getString("SSL3CIPHERPREF_TITLE");
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public Vector getCipherList() {
+ return cipherList;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSSelfTestsPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSSelfTestsPanel.java
new file mode 100644
index 000000000..ab957a69c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSSelfTestsPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.border.*;
+
+/**
+ * Self Tests setting tab
+ *
+ * @author Matt Harmsen
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class CMSSelfTestsPanel extends CMSBaseTab
+{
+ private static final String PROP_TITLE = "On-Demand Self Tests Results";
+ private static String PANEL_NAME = "SELFTESTS";
+ private AdminConnection mAdmin;
+ private JButton mOnDemand;
+ private CMSBaseResourceModel mModel;
+ private CMSTabPanel mParent;
+ private static final String HELPINDEX =
+ "configuration-overview";
+ private ViewSelfTestsDialog mViewer = null;
+
+
+ public CMSSelfTestsPanel( CMSTabPanel parent )
+ {
+ super( PANEL_NAME, parent );
+ mModel = parent.getResourceModel();
+ mParent = parent;
+ mHelpToken = HELPINDEX;
+ }
+
+
+ public void init()
+ {
+ Debug.println( "SelfTestsPanel: init()" );
+ mAdmin = mModel.getServerInfo().getAdmin();
+ JPanel selftestsInfo = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ CMSAdminUtil.resetGBC( gbc );
+ mCenterPanel.setLayout( gb );
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints( selftestsInfo, gbc );
+ mCenterPanel.add( selftestsInfo );
+
+ GridBagLayout gb1 = new GridBagLayout();
+ selftestsInfo.setLayout( gb1 );
+
+ // self tests border
+ selftestsInfo.setBorder( new CompoundBorder(
+ BorderFactory.createTitledBorder(
+ mResource.getString(
+ "SELFTESTS_BORDER_LABEL" ) ),
+ new EmptyBorder( -3,
+ 0,
+ DIFFERENT_COMPONENT_SPACE - 3,
+ 0 ) ) );
+
+ // add on-demand self tests label
+ CMSAdminUtil.resetGBC( gbc );
+ JLabel onDemandLabel = makeJLabel( "ONDEMAND" );
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.gridx = 0;
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets( COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE,
+ 0,
+ 0 );
+ selftestsInfo.add( onDemandLabel, gbc );
+
+
+ // add run button for on-demand self tests
+ mOnDemand = makeJButton( "RUN" );
+ JButton[] buttons = { mOnDemand };
+ JButtonFactory.resize( buttons );
+ CMSAdminUtil.makeJButtonVPanel( buttons );
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = gbc.RELATIVE;
+ gbc.gridx = gbc.RELATIVE;
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets( COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE,
+ 0,
+ DIFFERENT_COMPONENT_SPACE );
+ selftestsInfo.add( mOnDemand, gbc );
+
+ // add space after the run button
+ JLabel dummy = new JLabel(" ");
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridx = gbc.RELATIVE;
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets( COMPONENT_SPACE,
+ 0,
+ COMPONENT_SPACE,
+ 0 );
+ selftestsInfo.add( dummy, gbc );
+
+ refresh();
+ }
+
+
+ public void refresh()
+ {
+ clearDirtyFlag();
+ }
+
+
+ public void actionPerformed( ActionEvent evt )
+ {
+ super.actionPerformed( evt );
+
+ NameValuePairs nvps = new NameValuePairs();
+ NameValuePairs nvps1;
+
+ nvps.put(Constants.PR_RUN_SELFTESTS_ON_DEMAND, Constants.TRUE);
+
+ if( evt.getSource().equals( mOnDemand ) ) {
+ Debug.println( "Run self tests on-demand . . ." );
+
+ mModel.progressStart();
+ try {
+ nvps1 = mAdmin.process( DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_SELFTESTS,
+ Constants.RS_ID_CONFIG,
+ nvps );
+ // show server response
+ String responseClass = "";
+ String response = "";
+ boolean first = true;
+ for (String name : nvps1.keySet()) {
+ String value = nvps1.get(name);
+ if (first) {
+ first = false;
+ responseClass = value;
+ } else {
+ response = response + value + "\n";
+ }
+ }
+
+ Debug.println( ". . . class \""
+ + responseClass
+ + "\" responded with "
+ + "on-demand self tests results." );
+
+ if( mViewer == null ) {
+ mViewer = new ViewSelfTestsDialog( mModel.getFrame(),
+ PROP_TITLE );
+ }
+
+ mViewer.showDialog( response );
+ } catch( EAdminException e ) {
+ showErrorDialog( e.toString() );
+ mModel.progressStop();
+ return;
+ }
+ mModel.progressStop();
+ }
+
+ clearDirtyFlag();
+ return;
+ }
+
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback()
+ {
+ clearDirtyFlag();
+ return true;
+ }
+
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback()
+ {
+ refresh();
+ return true;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSTabPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSTabPanel.java
new file mode 100644
index 000000000..63899892f
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSTabPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.tree.*;
+import java.awt.event.*;
+import java.awt.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Base Class for Tabbed right hand pane
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class CMSTabPanel extends CMSBaseConfigPanel
+ implements IResourceSelectionListener, ChangeListener, IRefreshTabPanel
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static String PANEL_NAME = "CMSTABPANEL";
+
+ protected JTabbedPane mTabbedPane; //tabbed panel
+ protected JButton mbOK, mbReset, mbHelp; //buttons
+ CMSBaseResourceModel mModel; //resource model
+ private ResourceObject mParent; //tree node parent
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSTabPanel(CMSBaseResourceModel model, ResourceObject parent) {
+ this(model, parent, true);
+ }
+
+ public CMSTabPanel(CMSBaseResourceModel model, ResourceObject parent, boolean showButton) {
+ super(PANEL_NAME);
+ mModel = model;
+ mParent = parent;
+
+ setLayout(new BorderLayout());
+ //mTabbedPane = new JTabbedPane();
+
+ // Look and Feel
+ mTabbedPane = new NSTabbedPane();
+ add("Center", mTabbedPane);
+
+ if (showButton)
+ add("South", createButtonPanel());
+ mbOK.setEnabled(false);
+ mbReset.setEnabled(false);
+
+ mModel.addIResourceSelectionListener(this);
+ //mTabbedPane.addChangeListener(this);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void init() {}
+
+ /**
+ * Retrieve Resource Model
+ */
+ public CMSBaseResourceModel getResourceModel() {
+ return mModel;
+ }
+
+ public ResourceObject getResourceObject() {
+ return mParent;
+ }
+
+ /**
+ * Set the Tab associated with this component dirty
+ */
+ public void setDirtyTab(CMSBaseTab component) {
+ int index = mTabbedPane.indexOfComponent(component);
+ if (index == -1) {
+ Debug.println("CMSTabPanel: setDirtyTab() - component not part of this panel");
+ return;
+ }
+ if ((mTabbedPane != null) && (mTabbedPane.getIconAt(index)== null) ) {
+ mTabbedPane.setIconAt(index,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_DIRTY_TAB));
+ mTabbedPane.repaint();
+ }
+ mbOK.setEnabled(true);
+ mbReset.setEnabled(true);
+ }
+
+ /**
+ * Clear the Tab associated with this component
+ */
+ public void clearDirtyTab(CMSBaseTab component) {
+ int index = mTabbedPane.indexOfComponent(component);
+ if (index == -1) {
+ Debug.println("CMSTabPanel: clearDirtyTab() - component not part of this panel");
+ return;
+ }
+ if ((mTabbedPane != null) && (mTabbedPane.getIconAt(index)!= null) ) {
+ mTabbedPane.setIconAt(index, null);
+ mTabbedPane.repaint();
+ }
+ setOKCancel();
+ }
+
+ //=== Callback methods ====
+ public boolean applyCallback(){
+ int currentTab = mTabbedPane.getSelectedIndex();
+ int nTabs = mTabbedPane.getTabCount();
+ boolean failed = false;
+
+ //we will go through each tab and apply
+ for (int i= 0; i < nTabs; ++i) {
+ CMSBaseTab p = (CMSBaseTab)mTabbedPane.getComponentAt(i);
+ if (p.isDirty()) {
+ mTabbedPane.setSelectedIndex(i);
+ if (!p.applyCallback()) {
+ failed = true;
+ }
+ }
+ }
+
+ //one or more panel falied
+ if (failed) {
+ //get first dirty tab
+ for (int i= 0; i < nTabs; ++i) {
+ CMSBaseTab p = (CMSBaseTab)mTabbedPane.getComponentAt(i);
+ if (p.isDirty()) {
+ mTabbedPane.setSelectedIndex(i);
+ break;
+ }
+ }
+ return false;
+ }
+
+ //everything ok
+ if (currentTab >=0 )
+ mTabbedPane.setSelectedIndex(currentTab);
+ mbOK.setEnabled(false);
+ mbReset.setEnabled(false);
+ mbHelp.requestFocusInWindow();
+ return true;
+ }
+
+ public boolean resetCallback() {
+ int nTabs = mTabbedPane.getTabCount();
+ for (int i= 0; i < nTabs; ++i) {
+ CMSBaseTab p = (CMSBaseTab)mTabbedPane.getComponentAt(i);
+ if (p.isDirty()) {
+ p.resetCallback();
+ }
+ }
+ mbOK.setEnabled(false);
+ mbReset.setEnabled(false);
+ return true;
+ }
+
+ public void setOKCancel() {
+ int nTabs = mTabbedPane.getTabCount();
+ for (int i= 0; i < nTabs; ++i) {
+ CMSBaseTab p = (CMSBaseTab)mTabbedPane.getComponentAt(i);
+ if (p.isDirty()) {
+ return;
+ }
+ }
+ mbOK.setEnabled(false);
+ mbReset.setEnabled(false);
+ }
+
+ public void helpCallback() {
+ CMSBaseTab p = (CMSBaseTab)mTabbedPane.getSelectedComponent();
+ if (p != null)
+ p.helpCallback();
+ Debug.println("CMSTabPanel: helpCallback()");
+ }
+
+ public CMSBasePanel getSelectedTab() {
+ return (CMSBasePanel)mTabbedPane.getSelectedComponent();
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+ //== ACTIONLISTENER =====
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mbOK)) {
+ applyCallback();
+ }
+ if (e.getSource().equals(mbReset)) {
+ resetCallback();
+ }
+ if (e.getSource().equals(mbHelp)) {
+ helpCallback();
+ }
+ }
+
+ //== IResourceListener ===
+ public void select(IResourceObject parent, Object viewInstance) {
+ //System.out.println("CMSTabPanel: select() "+ parent);
+ if (parent == mParent) {
+ try {
+ mTabbedPane.addChangeListener(this);
+ mTabbedPane.setSelectedIndex(0);
+ CMSBaseConfigPanel selectedPanel = (CMSBaseConfigPanel) mTabbedPane.getComponentAt(0);
+ if ( selectedPanel != null )
+ selectedPanel.initialize();
+ mTabbedPane.invalidate();
+ mTabbedPane.validate();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //NO TAB SO IGNORE
+ }
+ }
+ }
+
+ public boolean unselect(IResourceObject parent, Object viewInstance) {
+ //System.out.println("CMSTabPanel: unselect() "+ parent);
+
+ // XXX NOT SAVED MODEL IS MOVED TO HIGHER LEVEL
+
+ //check if any tab is dirty
+ boolean dirty = false;
+ int nTabs = mTabbedPane.getTabCount();
+ for (int i= 0; i < nTabs; ++i) {
+ CMSBaseTab p = (CMSBaseTab)mTabbedPane.getComponentAt(i);
+ if (p.isDirty()) {
+ dirty = true;
+ }
+ }
+ if (!dirty)
+ return true;
+
+ //return to previous node
+ TreePath thisPath = new TreePath(((ResourceObject)parent).getPath());
+ TreePath selectedPath =
+ ((CMSResourcePage)viewInstance).getTree().getSelectionPath();
+ if (!thisPath.equals(selectedPath))
+ ((CMSResourcePage)viewInstance).getTree().setSelectionPath(thisPath);
+
+ //popup dialog for user to set changes
+ int result = showConfirmDialog("NOTSAVED");
+ switch (result) {
+ case JOptionPane.YES_OPTION:
+ if (applyCallback()) {
+ ((CMSResourcePage)viewInstance).getTree().setSelectionPath(selectedPath);
+ return true;
+ }
+ break;
+ case JOptionPane.NO_OPTION:
+ resetCallback();
+ ((CMSResourcePage)viewInstance).getTree().setSelectionPath(selectedPath);
+ return true;
+ default:
+ break;
+ }
+
+ //can not be unselected
+ return false;
+ }
+
+ //== ChangeListener ==
+ public void stateChanged(ChangeEvent e) {
+ //Debug.println("CMSTabPanel: stateChanged()");
+ CMSBaseConfigPanel selectedPanel = (CMSBaseConfigPanel)mTabbedPane.getSelectedComponent();
+ if ( selectedPanel != null )
+ selectedPanel.initialize();
+ mTabbedPane.invalidate();
+ mTabbedPane.validate();
+ mTabbedPane.repaint(1);
+ }
+
+ /**
+ * Add Panels to the Tab Panel. ChangeListener is
+ * added automatically.
+ *
+ * @param p CMS Panel to be added
+ */
+ public void addTab(CMSBaseTab p) {
+ mTabbedPane.addTab(p.getTitle(), p);
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+
+ /**
+ * create button panel using the factory method
+ */
+ protected JPanel createButtonPanel() {
+ mbOK = makeJButton("APPLY");
+ mbReset = makeJButton("RESET");
+ mbHelp = makeJButton("HELP");
+
+ //JButton[] buttons = { mbOK, mbReset, mbHelp };
+ JButton[] buttons = { mbOK, mbReset };
+ return makeJButtonPanel(buttons, true, true);
+ }
+
+ class NSTabbedPane extends JTabbedPane {
+/*
+ public String getUIClassID() {
+ return "SecondaryTabbedPaneUI";
+ }
+*/
+ }
+
+ //=== OVERWRITE DIALOG MESSAGE =====================
+
+ protected void showMessageDialog(String keyword, int messageType ) {
+ CMSAdminUtil.showMessageDialog(mModel.getFrame(), mResource, mPanelName, keyword, messageType);
+ }
+
+ protected void showMessageDialog(String keyword) {
+ showMessageDialog(keyword, ERROR_MESSAGE);
+ }
+
+ protected int showConfirmDialog(String keyword, int messageType ) {
+ return CMSAdminUtil.showConfirmDialog(mModel.getFrame(), mResource, mPanelName, keyword, messageType);
+ }
+
+ protected int showConfirmDialog(String keyword) {
+ return showConfirmDialog(keyword, WARNING_MESSAGE);
+ }
+
+ protected void showErrorDialog(String message) {
+ CMSAdminUtil.showErrorDialog(mModel.getFrame(), mResource, message, ERROR_MESSAGE);
+ }
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMSUserCertSettingPanel.java b/base/console/src/com/netscape/admin/certsrv/config/CMSUserCertSettingPanel.java
new file mode 100644
index 000000000..ca424c3a0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMSUserCertSettingPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+
+import java.awt.event.*;
+
+/**
+ * User Certificate Setting
+ *
+ * @author Christine Ho
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class CMSUserCertSettingPanel extends CMSCertSettingPanel {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private String _servletName; //destination name
+ private CMSTabPanel mParent;
+ private PanelMapperConfigDialog mDialog = null;
+ private static final String RAHELPINDEX =
+ "configuration-ra-ldappublish-usercert-help";
+ private static final String CAHELPINDEX =
+ "configuration-ca-ldappublish-usercert-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSUserCertSettingPanel(String panelName, CMSTabPanel parent) {
+ super(panelName, parent);
+ _servletName = getServletName(panelName);
+ mParent = parent;
+ if (panelName.equals("RAUSERCERTSETTING"))
+ mHelpToken = RAHELPINDEX;
+ else
+ mHelpToken = CAHELPINDEX;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Actual UI construction
+ */
+ public void init() {
+ super.init();
+
+ //XXX B1 - disable the publisher configuration
+ mPublisher.setEnabled(false);
+ //XXX B1 - disable the publisher configuration
+
+ refresh();
+ }
+
+ public void refresh() {
+ _model.progressStart();
+ NameValuePairs nvp = new NameValuePairs();
+ nvp.put(Constants.PR_MAPPER, "");
+ nvp.put(Constants.PR_PUBLISHER, "");
+
+ try {
+ NameValuePairs val = _admin.read(_servletName,
+ ScopeDef.SC_USERCERT, Constants.RS_ID_CONFIG, nvp);
+
+ populate(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ _model.progressStop();
+ }
+ _model.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+ }
+
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ clearDirtyFlag();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mMapper)) {
+ Debug.println("Edit Mapper Config");
+ mDialog = new PanelMapperConfigDialog(_model.getFrame(), _admin);
+ mDialog.showDialog(_mapper.getText(),
+ _servletName, ScopeDef.SC_USERCERT);
+ if (!mDialog.isOK())
+ return;
+ refresh();
+ } else if (e.getSource().equals(mPublisher)) {
+ //Debug.println("Edit Publisher Config");
+ }
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+ private String getServletName(String panelName) {
+ if (panelName.equals("CAUSERCERTSETTING"))
+ return DestDef.DEST_CA_ADMIN;
+ return DestDef.DEST_RA_ADMIN;
+ }
+
+ private void populate(NameValuePairs nvps) {
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name);
+ if (name.equals(Constants.PR_MAPPER)) {
+ _mapper.setText(value);
+ } else if (name.equals(Constants.PR_PUBLISHER)) {
+ _publisher.setText(value);
+ }
+ }
+ }
+
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CMStoAdminEncryptionPane.java b/base/console/src/com/netscape/admin/certsrv/config/CMStoAdminEncryptionPane.java
new file mode 100644
index 000000000..ea448b4e0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CMStoAdminEncryptionPane.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.security.EncryptionPane;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.event.*;
+
+/**
+ * Encryption set preference panel glue between CMS and KingPin
+ *
+ * @author Christina Fu (cfu)
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ * @see com.netscape.management.admserv.config
+ */
+
+/* replace "implements ActionListener" with
+ *"implements IPluginConfigPanel" when the
+ * com.netscape.management.admserv.config.* package is available
+
+public class CMStoAdminEncryptionPane extends EncryptionPane implements IPluginConfigPanel{
+*/
+public class CMStoAdminEncryptionPane extends EncryptionPane
+ implements ActionListener
+{
+ protected boolean mEncryptionPaneDirty = false;
+
+ public CMStoAdminEncryptionPane(ConsoleInfo consoleInfo) {
+ super(consoleInfo);
+ }
+
+ /**
+ * overrides the super class action listener
+ */
+ public void actionPerformed(ActionEvent e) {
+ Debug.println("CMStoAdminEncryptionPane: actionPerformed()");
+ mEncryptionPaneDirty = true;
+ }
+
+ public boolean isDirty() {
+ return mEncryptionPaneDirty;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CRLExtensionsConfigDialog.java b/base/console/src/com/netscape/admin/certsrv/config/CRLExtensionsConfigDialog.java
new file mode 100644
index 000000000..9a4f5ae17
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CRLExtensionsConfigDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import javax.swing.text.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * CRL Extensions Parameter Configuration Dialog
+ *
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class CRLExtensionsConfigDialog extends CMSBaseConfigDialog
+ implements ActionListener
+{
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CRLExtensionsConfigDialog(NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest) {
+
+ super(parent, dest);
+ PREFIX = "CRLEXTCONFIGDIALOG";
+ CAHELPINDEX = "configuration-ca-edit-crlextensionrule-dbox-help";
+
+ mImplName_token = Constants.PR_CRLEXT_IMPL_NAME;
+ mImplType = Constants.PR_EXT_PLUGIN_IMPLTYPE_CRLEXTSRULE;
+
+ init(nvp,parent,conn,dest);
+ }
+
+ public CRLExtensionsConfigDialog(NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ String id) {
+
+ super(parent, dest);
+ PREFIX = "CRLEXTCONFIGDIALOG";
+ CAHELPINDEX = "configuration-ca-edit-crlextensionrule-dbox-help";
+
+ mImplName_token = Constants.PR_CRLEXT_IMPL_NAME;
+ mImplType = Constants.PR_EXT_PLUGIN_IMPLTYPE_CRLEXTSRULE;
+
+ init(nvp,parent,conn,dest,id);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CRLExtensionsInstanceTab.java b/base/console/src/com/netscape/admin/certsrv/config/CRLExtensionsInstanceTab.java
new file mode 100644
index 000000000..5c687ea90
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CRLExtensionsInstanceTab.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+
+/**
+ * CRL Extensions - Instances Management Tab
+ *
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+
+public class CRLExtensionsInstanceTab extends CMSPluginInstanceTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PANEL_NAME = "CRLEXTSRULE";
+
+ private final static String CAHELPINDEX = "configuration-ca-crlinstances-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CRLExtensionsInstanceTab(CMSBaseResourceModel model, String dest) {
+ super(model,dest,PANEL_NAME);
+ Debug.println("CRLExtensionsInstanceTab::CRLExtensionsInstanceTab(<model>,"+dest);
+ mConnection = model.getServerInfo().getAdmin();
+ mDataModel = new RuleRuleDataModel();
+ mScope = ScopeDef.SC_CRLEXTS_RULES;
+ RULE_NAME = CRLExtensionsRuleDataModel.RULE_NAME;
+ RULE_STAT = CRLExtensionsRuleDataModel.RULE_STAT;
+ mHelpToken = CAHELPINDEX;
+ }
+
+ public CRLExtensionsInstanceTab(CMSBaseResourceModel model, String dest, String id) {
+ super(model,dest,PANEL_NAME);
+ Debug.println("CRLExtensionsInstanceTab::CRLExtensionsInstanceTab(<model>,"+dest);
+ mConnection = model.getServerInfo().getAdmin();
+ mDataModel = new RuleRuleDataModel();
+ mScope = ScopeDef.SC_CRLEXTS_RULES;
+ RULE_NAME = CRLExtensionsRuleDataModel.RULE_NAME;
+ RULE_STAT = CRLExtensionsRuleDataModel.RULE_STAT;
+ mHelpToken = CAHELPINDEX;
+ mId = id;
+ }
+
+
+ public CMSBaseConfigDialog makeNewConfigDialog(
+ NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest)
+ {
+ if (mId != null && mId.length() > 0)
+ return new CRLExtensionsConfigDialog(nvp, parent, conn, dest, mId);
+ else
+ return new CRLExtensionsConfigDialog(nvp, parent, conn, dest);
+ }
+
+ public PluginSelectionDialog getPluginSelectionDialog(
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType)
+ {
+ return new CRLExtensionsPluginSelectionDialog(parent, conn, dest, pluginType);
+ }
+
+
+ /**
+ * create the user action button panel
+ */
+ protected JPanel createUserButtonPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mAdd = makeJButton("ADD");
+ mDelete = makeJButton("DELETE");
+ mAdd.setEnabled(false);
+ mDelete.setEnabled(false);
+ mEdit = makeJButton("EDIT");
+ JButton[] buttons = {mEdit};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CRLExtensionsPluginSelectionDialog.java b/base/console/src/com/netscape/admin/certsrv/config/CRLExtensionsPluginSelectionDialog.java
new file mode 100644
index 000000000..aa169235d
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CRLExtensionsPluginSelectionDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * CRL Extensions Plugin Selection Dialog
+ *
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class CRLExtensionsPluginSelectionDialog extends PluginSelectionDialog
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "CRLEXTSELECTIONDIALOG";
+ private static final String CAHELPINDEX =
+ "configuration-ca-add-crlextensionrule-dbox-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CRLExtensionsPluginSelectionDialog(
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType)
+ {
+ super(PREFIX, parent,conn, dest, pluginType);
+// mScope = ScopeDef.SC_RULE_IMPLS;
+ mInstanceScope = ScopeDef.SC_CRLEXTS_RULES;
+ mImageName = CMSAdminResources.IMAGE_RULE_PLUGIN;
+ mHelpToken = CAHELPINDEX;
+ setDisplay();
+ }
+
+ /*==========================================================
+ * EVENT HANDLER METHODS
+ *==========================================================*/
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CRLExtensionsRuleDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/CRLExtensionsRuleDataModel.java
new file mode 100644
index 000000000..e5ae9352a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CRLExtensionsRuleDataModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.Debug;
+
+
+/**
+ * CRL Extensions instance Data model - represents the instance
+ * table information
+ *
+ * @version $Revision$, $Date$
+ */
+
+public class CRLExtensionsRuleDataModel extends CMSRuleDataModel
+{
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CRLExtensionsRuleDataModel() {
+ super();
+ }
+
+ protected String[] getColumns() {
+ Debug.println("PolicyRuleDataModel.getColumns()");
+ String x[] = {CRLEXTS_RULE, STATUS};
+ return x;
+ }
+
+ public void processData(Object data) {
+ Vector v = new Vector();
+ NameValuePairs obj = (NameValuePairs) data;
+
+ if (obj.get(RULE_STAT).equalsIgnoreCase("enabled")) {
+ v.addElement(new JLabel(obj.get(RULE_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE),
+ JLabel.LEFT));
+ v.addElement(mResource.getString("CRLEXTSRULE_LABEL_ENABLED_LABEL"));
+ } else {
+ v.addElement(new JLabel(obj.get(RULE_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE_DISABLE),
+ JLabel.LEFT));
+ v.addElement(mResource.getString("CRLEXTSRULE_LABEL_DISABLED_LABEL"));
+ }
+ addRow(v, data);
+ mRules.addElement(obj.get(RULE_NAME));
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/CRLIPEditor.java b/base/console/src/com/netscape/admin/certsrv/config/CRLIPEditor.java
new file mode 100644
index 000000000..040b21b83
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/CRLIPEditor.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * CRL IP Editor
+ *
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class CRLIPEditor extends JDialog implements ActionListener {
+
+ private final static String PREFIX = "CRLIPEDITOR";
+ private final static String HELPINDEX =
+ "configuration-revocation";
+ private JButton mOK, mCancel, mHelp;
+ private String mName;
+ private JTextField mNameText, mDescText;
+ private ResourceBundle mResource;
+ private JFrame mParentFrame;
+ private AdminConnection mAdmin;
+ private JLabel nameLabel, descLabel;
+ private Color mActiveColor;
+ private String mDest;
+ private JCheckBox mEnableBox;
+ private boolean mEnable = true;
+ private String mInstanceName;
+ private Vector mNames;
+
+ public CRLIPEditor(AdminConnection admin, JFrame parent,
+ String name, String dest, String instanceName, Vector names) {
+ super(parent,true);
+ mParentFrame = parent;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mAdmin = admin;
+ mName = name;
+ mNames = names;
+ mInstanceName = instanceName;
+ mDest = dest;
+ setSize(600, 180);
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ setDisplay();
+ }
+
+ private void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ //gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ public void showDialog(NameValuePairs values) {
+
+ for (String name : values.keySet()) {
+ String val = values.get(name);
+ if ((mName == null || mName.length() == 0) &&
+ name.equals(Constants.PR_ID)) {
+ mNameText.setText(val);
+ } else if (name.equals(Constants.PR_DESCRIPTION)) {
+ mDescText.setText(val);
+ } else if (name.equals(Constants.PR_ENABLED)) {
+ if (val.equalsIgnoreCase(Constants.TRUE))
+ mEnable = true;
+ else
+ mEnable = false;
+ }
+ }
+
+ mEnableBox.setSelected(mEnable);
+ enableCRLIP();
+ this.show();
+ }
+
+ public String getCRLName() {
+ return mNameText.getText().trim();
+ }
+
+ private void enableCRLIP() {
+ if (mName == null || mName.length() == 0) {
+ nameLabel.setEnabled(true);
+ mNameText.setBackground(mActiveColor);
+ mNameText.setEnabled(true);
+ mNameText.setEditable(true);
+
+ descLabel.setEnabled(true);
+ mDescText.setBackground(mActiveColor);
+ mDescText.setEnabled(true);
+ mDescText.setEditable(true);
+
+ CMSAdminUtil.repaintComp(nameLabel);
+ CMSAdminUtil.repaintComp(mNameText);
+ } else if (mEnable) {
+ descLabel.setEnabled(true);
+ mDescText.setBackground(mActiveColor);
+ mDescText.setEnabled(true);
+ mDescText.setEditable(true);
+ } else {
+ descLabel.setEnabled(false);
+ mDescText.setBackground(getBackground());
+ mDescText.setEnabled(false);
+ mDescText.setEditable(false);
+ }
+
+ CMSAdminUtil.repaintComp(descLabel);
+ CMSAdminUtil.repaintComp(mDescText);
+ }
+
+ private JPanel makeContentPanel() {
+ JPanel mainPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mainPanel.setLayout(gb);
+
+ if (mName != null && mName.length() > 0) {
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label1 = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "CRLIPNAME", null);
+ gbc.anchor = gbc.WEST;
+ //gbc.weightx = 1.0;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE);
+ gb.setConstraints(label1, gbc);
+ mainPanel.add(label1);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label2 = new JLabel(mName);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE);
+ gb.setConstraints(label2, gbc);
+ mainPanel.add(label2);
+ }
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEnableBox = CMSAdminUtil.makeJCheckBox(mResource, PREFIX,
+ "ENABLE", null, false, this);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE);
+ gb.setConstraints(mEnableBox, gbc);
+ mainPanel.add(mEnableBox);
+
+ if (mName == null || mName.length() == 0) {
+ CMSAdminUtil.resetGBC(gbc);
+ nameLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "CRLIPNAME", null);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.insets = new Insets(0, 0,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE);
+ gb.setConstraints(nameLabel, gbc);
+ mainPanel.add(nameLabel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mNameText = new JTextField(30);
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 0.0;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(0, CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE);
+ gb.setConstraints(mNameText, gbc);
+ mainPanel.add(mNameText);
+ //mActiveColor = mNameText.getBackground();
+ }
+
+ CMSAdminUtil.resetGBC(gbc);
+ descLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "DESCRIPTION", null);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 0,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE);
+ gbc.weightx = 0.0;
+ gb.setConstraints(descLabel, gbc);
+ mainPanel.add(descLabel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mDescText = new JTextField(30);
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 0.0;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ gb.setConstraints(mDescText, gbc);
+ mainPanel.add(mDescText);
+ mActiveColor = mDescText.getBackground();
+
+ return mainPanel;
+ }
+
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null, this);
+ mCancel = CMSAdminUtil.makeJButton(mResource, PREFIX, "CANCEL", null, this);
+ mHelp = CMSAdminUtil.makeJButton(mResource, PREFIX, "HELP", null, this);
+ //JButton[] buttons = { mOK, mCancel, mHelp};
+ JButton[] buttons = { mOK, mCancel};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonPanel( buttons, true);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+
+ if (e.getSource().equals(mEnableBox)) {
+ mEnable = mEnableBox.isSelected();
+ enableCRLIP();
+ } else if (e.getSource().equals(mCancel)) {
+ this.dispose();
+ } else if (e.getSource().equals(mOK)) {
+ NameValuePairs nvps = new NameValuePairs();
+
+ if (mName != null && mName.length() > 0) {
+ nvps.put(Constants.PR_ID, mName);
+ } else {
+ nvps.put(Constants.PR_ID, mNameText.getText().trim());
+ }
+
+ nvps.put(Constants.PR_DESCRIPTION, mDescText.getText().trim());
+
+ if (mEnable) {
+ nvps.put(Constants.PR_ENABLED, Constants.TRUE);
+ } else {
+ nvps.put(Constants.PR_ENABLED, Constants.FALSE);
+ }
+
+ try {
+ if (mName != null && mName.length() > 0) {
+ mAdmin.modify(mDest, ScopeDef.SC_CRLIPS, Constants.OP_SET, nvps);
+ } else {
+ for (int i = 0; i < mNames.size(); i++) {
+ String name = (String)mNames.elementAt(i);
+ if (name.equalsIgnoreCase(mNameText.getText().trim())) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, "Error",
+ mNameText.getText().trim()+" already exists",
+ CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ if (mNameText.getText().trim().indexOf(' ') > -1 ||
+ mNameText.getText().trim().indexOf('.') > -1 ||
+ mNameText.getText().trim().indexOf(',') > -1) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, "Error",
+ "Invalid name: "+mNameText.getText(),
+ CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ }
+
+ mAdmin.add(mDest, ScopeDef.SC_CRLIPS,
+ mNameText.getText().trim(), nvps);
+ mNames.addElement(mNameText.getText());
+ }
+ this.dispose();
+ } catch (EAdminException ex) {
+ CMSAdminUtil.showMessageDialog(mParentFrame,
+ "Error", ex.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ }
+ } else if (e.getSource().equals(mHelp)) {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ConfigTableModel.java b/base/console/src/com/netscape/admin/certsrv/config/ConfigTableModel.java
new file mode 100644
index 000000000..8608e943a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ConfigTableModel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+
+/**
+ * Table Model for configuration parameters
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ConfigTableModel extends CMSTableModel {
+ private static String[] mColumns = {CONFIG, VALUE};
+
+ public ConfigTableModel() {
+ init(mColumns);
+ }
+
+ public boolean isCellEditable(int row, int col) {
+ if(col == 1)
+ return true;
+ return false;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ConnectorEditor.java b/base/console/src/com/netscape/admin/certsrv/config/ConnectorEditor.java
new file mode 100644
index 000000000..6f711eca9
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ConnectorEditor.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.ug.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.table.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Connector Editor
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ConnectorEditor extends JDialog implements ActionListener, MouseListener {
+
+ private final static String PREFIX = "CONNECTOREDITOR";
+ private final static String HELPINDEX =
+ "configuration-ra-connector-editor-help";
+ private final static String HELPINDEX1 =
+ "configuration-overview";
+ private JButton mOK, mCancel, mHelp;
+ private String mName;
+ private ListCertsModel mDataModel;
+ // Changed by beomsuk
+ //private JTextField mLocalText, mURIText, mHostText, mPortText;
+ private JTextField mLocalText, mURIText, mHostText, mPortText, mTimeoutText, mNicknameText;
+ // Change end
+ private ResourceBundle mResource;
+ private JFrame mParentFrame;
+ private AdminConnection mAdmin;
+ // Changed by beomsuk
+ //private JLabel idLabel, uriLabel, hostLabel, portLabel;
+ private JLabel idLabel, uriLabel, hostLabel, portLabel, timeoutLabel, timeunitLabel,
+ nicknameLabel;
+ // Change end
+ private Color mActiveColor;
+ private String mDest;
+ private JCheckBox mEnableBox;
+ private boolean mEnable = false;
+ private String mInstanceName;
+ private boolean mColocated;
+ private JTable mCertTable;
+ private JTextArea mHeading;
+
+ public ConnectorEditor(AdminConnection admin, JFrame parent, String name,
+ String dest, String instanceName, boolean colocated) {
+ super(parent,true);
+ mParentFrame = parent;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mAdmin = admin;
+ mName = name;
+ mInstanceName = instanceName;
+ mDest = dest;
+ mColocated = colocated;
+ setSize(460, 516);
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ setDisplay();
+ }
+
+ private void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ //gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ NameValuePairs response = getCertsList(ScopeDef.SC_USERCERTSLIST);
+ mDataModel.removeAllRows();
+ if (response != null) {
+ String[] vals = new String[response.size()];
+ int i=0;
+ for (String entry : response.keySet()) {
+ vals[i++] = entry.trim();
+ }
+
+ int sindex = 0;
+ String snickname = "";
+ CMSAdminUtil.quickSort(vals, 0, response.size() - 1);
+ for (i=0; i<vals.length; i++) {
+ Vector v = new Vector();
+ String entry = vals[i];
+ String value = response.get(entry);
+
+ // look for the comma separator
+ int lastindex = entry.lastIndexOf(",");
+ if (lastindex != -1) {
+ String fullnickname = entry.substring(0, lastindex);
+ int tindex = fullnickname.indexOf(":");
+ String tokenname = fullnickname.substring(0, tindex);
+ String nickname = fullnickname.substring(tindex+1);
+ if (mName.equals("Data Recovery Manager Connector")) {
+ if (fullnickname.indexOf("subsystemCert") > -1) {
+ sindex = i;
+ snickname = fullnickname;
+ }
+ } else {
+ if (fullnickname.indexOf("raSigningCert") > -1) {
+ sindex = i;
+ snickname = fullnickname;
+ }
+ }
+ v.addElement(nickname);
+ v.addElement(entry.substring(lastindex+1));
+ v.addElement(value);
+ v.addElement(tokenname);
+ mDataModel.addRow(v);
+ }
+ }
+ mCertTable.setRowSelectionInterval(sindex, sindex);
+ mNicknameText.setText(snickname);
+ }
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(
+ new DefaultTableCellRenderer());
+ }
+
+ private void displayCert(int row) {
+ String nickname = (String)(mCertTable.getValueAt(row, 3)) + ":" +
+ (String)(mCertTable.getValueAt(row, 0));
+ String serialno = (String)(mCertTable.getValueAt(row, 1));
+ String issuername = (String)(mCertTable.getValueAt(row, 2));
+
+ try {
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_NICK_NAME, nickname);
+ nvps.put(Constants.PR_SERIAL_NUMBER, serialno);
+ nvps.put(Constants.PR_ISSUER_NAME, issuername);
+ NameValuePairs results = mAdmin.process(
+ DestDef.DEST_SERVER_ADMIN, ScopeDef.SC_CERT_PRETTY_PRINT,
+ Constants.RS_ID_CONFIG, nvps);
+ if (nvps.size() <= 0)
+ return;
+ String name = results.keySet().iterator().next(); // first element
+ String print = results.get(name);
+ CertViewDialog certdialog = new CertViewDialog(mParentFrame);
+ certdialog.showDialog(nickname, print);
+ } catch (EAdminException ex) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource, ex.toString(),
+ CMSAdminUtil.ERROR_MESSAGE);
+ }
+ }
+
+ public void mouseClicked(MouseEvent e) {
+ //setButtons();
+
+ //we track the double click action on the table entry - View op
+ int row = mCertTable.getSelectedRow();
+ if(row >= 0) {
+ mNicknameText.setText((String)(mCertTable.getValueAt(row, 0)));
+ if(e.getClickCount() == 2) {
+ displayCert(row);
+ }
+ }
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ }
+
+ public void mousePressed(MouseEvent e) {
+ }
+
+ public void mouseEntered(MouseEvent e) {
+ }
+
+ public void mouseExited(MouseEvent e) {
+ }
+
+ public void showDialog(NameValuePairs values) {
+
+ for (String name : values.keySet()) {
+ String val = values.get(name);
+ if (name.equals(Constants.PR_HOST)) {
+ mHostText.setText(val);
+ } else if (name.equals(Constants.PR_PORT)) {
+ mPortText.setText(val);
+ // Inserted by beomsuk
+ } else if (name.equals(Constants.PR_TIMEOUT)) {
+ if (val == null || val.equals(""))
+ mTimeoutText.setText("30");
+ else
+ mTimeoutText.setText(val);
+ // Insert end
+ } else if (name.equals(Constants.PR_ENABLED)) {
+ if (val.equals(Constants.TRUE))
+ mEnable = true;
+ else
+ mEnable = false;
+ }
+ }
+
+ mEnableBox.setSelected(mEnable);
+ enableConnector();
+ //update(local);
+ this.show();
+ }
+
+ private void enableConnector() {
+ if (mEnable) {
+ update();
+ } else {
+ hostLabel.setEnabled(false);
+ portLabel.setEnabled(false);
+ nicknameLabel.setEnabled(false);
+ timeoutLabel.setEnabled(false);
+ //timeunitLabel.setEnabled(false);
+ mHostText.setBackground(getBackground());
+ mPortText.setBackground(getBackground());
+ mNicknameText.setBackground(getBackground());
+ mTimeoutText.setBackground(getBackground());
+ mHostText.setEnabled(false);
+ mPortText.setEnabled(false);
+ mNicknameText.setEnabled(false);
+ mTimeoutText.setEnabled(false);
+ mHostText.setEditable(false);
+ mPortText.setEditable(false);
+ mNicknameText.setEditable(false);
+ mTimeoutText.setEditable(false);
+ mHeading.setEnabled(false);
+ mCertTable.setEnabled(false);
+ mCertTable.setBackground(getBackground());
+ CMSAdminUtil.repaintComp(hostLabel);
+ CMSAdminUtil.repaintComp(portLabel);
+ CMSAdminUtil.repaintComp(timeoutLabel);
+ //CMSAdminUtil.repaintComp(timeunitLabel);
+ CMSAdminUtil.repaintComp(mHostText);
+ CMSAdminUtil.repaintComp(mPortText);
+ CMSAdminUtil.repaintComp(mTimeoutText);
+ }
+ }
+
+ private void update() {
+ hostLabel.setEnabled(true);
+ portLabel.setEnabled(true);
+ nicknameLabel.setEnabled(true);
+ timeoutLabel.setEnabled(true);
+ mHostText.setEditable(true);
+ mPortText.setEditable(true);
+ mNicknameText.setEditable(true);
+ mTimeoutText.setEditable(true);
+ mHostText.setBackground(mActiveColor);
+ mPortText.setBackground(mActiveColor);
+ mNicknameText.setBackground(mActiveColor);
+ mTimeoutText.setBackground(mActiveColor);
+ mHostText.setEnabled(true);
+ mPortText.setEnabled(true);
+ mTimeoutText.setEnabled(true);
+ mNicknameText.setEnabled(true);
+ mHeading.setEnabled(true);
+ mCertTable.setEnabled(true);
+ mCertTable.setBackground(mActiveColor);
+
+ CMSAdminUtil.repaintComp(hostLabel);
+ CMSAdminUtil.repaintComp(portLabel);
+ CMSAdminUtil.repaintComp(timeoutLabel);
+ //CMSAdminUtil.repaintComp(timeunitLabel);
+ CMSAdminUtil.repaintComp(mHostText);
+ CMSAdminUtil.repaintComp(mPortText);
+ CMSAdminUtil.repaintComp(mTimeoutText);
+ }
+
+ private JPanel makeContentPanel() {
+ JPanel mainPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mainPanel.setLayout(gb);
+
+/*
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label1 = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "CONNECTORNAME", null);
+ gbc.anchor = gbc.WEST;
+ //gbc.weightx = 1.0;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE);
+ gb.setConstraints(label1, gbc);
+ mainPanel.add(label1);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label2 = new JLabel(mName);
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.DIFFERENT_COMPONENT_SPACE,
+ 0, CMSAdminUtil.COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE);
+ gb.setConstraints(label2, gbc);
+ mainPanel.add(label2);
+*/
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label2 = new JLabel(mName+":");
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.fill = gbc.HORIZONTAL;
+ gb.setConstraints(label2, gbc);
+ mainPanel.add(label2);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEnableBox = CMSAdminUtil.makeJCheckBox(mResource, PREFIX,
+ "ENABLE", null, false, this);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+/*
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE);
+*/
+ gb.setConstraints(mEnableBox, gbc);
+ mainPanel.add(mEnableBox);
+
+ CMSAdminUtil.resetGBC(gbc);
+ hostLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "HOST", null);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.insets = new Insets(0, CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+ gb.setConstraints(hostLabel, gbc);
+ mainPanel.add(hostLabel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mHostText = new JTextField(20);
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 1.0;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+/*
+ gbc.insets = new Insets(0, CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+*/
+ gb.setConstraints(mHostText, gbc);
+ mainPanel.add(mHostText);
+ mActiveColor = mHostText.getBackground();
+
+ CMSAdminUtil.resetGBC(gbc);
+ portLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "PORT", null);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+ gbc.weightx = 0.0;
+ gb.setConstraints(portLabel, gbc);
+ mainPanel.add(portLabel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPortText = new JTextField(20);
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 1.0;
+ gbc.fill = gbc.HORIZONTAL;
+/*
+ gbc.insets = new Insets(0, CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+*/
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ gb.setConstraints(mPortText, gbc);
+ mainPanel.add(mPortText);
+
+ CMSAdminUtil.resetGBC(gbc);
+ timeoutLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "TIMEOUT", null);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 4*CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+ gbc.weightx = 0.0;
+ gb.setConstraints(timeoutLabel, gbc);
+ mainPanel.add(timeoutLabel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mTimeoutText = new JTextField(20);
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 1.0;
+ gbc.fill = gbc.HORIZONTAL;
+/*
+ gbc.insets = new Insets(0, CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+*/
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ gb.setConstraints(mTimeoutText, gbc);
+ mTimeoutText.setText("30");
+ mainPanel.add(mTimeoutText);
+
+ CMSAdminUtil.resetGBC(gbc);
+ nicknameLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "NICKNAME", null);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.insets = new Insets(0, CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+ gb.setConstraints(nicknameLabel, gbc);
+ mainPanel.add(nicknameLabel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mNicknameText = new JTextField(50);
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 1.0;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.gridwidth = gbc.REMAINDER;
+ gb.setConstraints(mNicknameText, gbc);
+ mainPanel.add(mNicknameText);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mHeading = createTextArea(mResource.getString(
+ PREFIX+"_TEXT_CERTHEADING_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 1.0;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.insets = new Insets(2*CMSAdminUtil.COMPONENT_SPACE,
+ 4*CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ gb.setConstraints(mHeading, gbc);
+ mainPanel.add(mHeading);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mDataModel = new ListCertsModel();
+ mCertTable = new JTable(mDataModel);
+ JScrollPane scrollPane = JTable.createScrollPaneForTable(mCertTable);
+ scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mCertTable.setPreferredScrollableViewportSize(new Dimension(200, 350));
+ mCertTable.setAutoscrolls(true);
+ mCertTable.sizeColumnsToFit(true);
+ mCertTable.addMouseListener(this);
+ scrollPane.setBackground(Color.white);
+ setLabelCellRenderer(mCertTable, 0);
+ setLabelCellRenderer(mCertTable, 1);
+ setLabelCellRenderer(mCertTable, 2);
+
+/*
+ Vector v = new Vector();
+ v.addElement("abc1");
+ v.addElement("def1");
+ v.addElement("hij1");
+ mDataModel.addRow(v);
+ Vector v1 = new Vector();
+ v1.addElement("abc1");
+ v1.addElement("def1");
+ v1.addElement("hij1");
+ mDataModel.addRow(v1);
+ Vector v2 = new Vector();
+ v2.addElement("abc1");
+ v2.addElement("def1");
+ v2.addElement("hij1");
+ mDataModel.addRow(v2);
+*/
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ 4*CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+ gb.setConstraints(scrollPane, gbc);
+ mainPanel.add(scrollPane);
+
+
+ return mainPanel;
+ }
+
+ private JTextArea createTextArea(String str) {
+ JTextArea desc = new JTextArea(str);
+ desc.setBackground(getBackground());
+ desc.setEditable(false);
+ desc.setCaretColor(getBackground());
+ desc.setLineWrap(true);
+ desc.setWrapStyleWord(true);
+
+ return desc;
+ }
+
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null, this);
+ mCancel = CMSAdminUtil.makeJButton(mResource, PREFIX, "CANCEL", null, this);
+ mHelp = CMSAdminUtil.makeJButton(mResource, PREFIX, "HELP", null, this);
+ //JButton[] buttons = { mOK, mCancel, mHelp};
+ JButton[] buttons = { mOK, mCancel};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonPanel( buttons, true);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+
+ if (e.getSource().equals(mEnableBox)) {
+ mEnable = mEnableBox.isSelected();
+ enableConnector();
+ } else if (e.getSource().equals(mCancel))
+ this.dispose();
+ else if (e.getSource().equals(mOK)) {
+ NameValuePairs nvps = new NameValuePairs();
+
+ if (mEnable) {
+ nvps.put(Constants.PR_LOCAL, Constants.FALSE);
+ nvps.put(Constants.PR_HOST, mHostText.getText());
+ String portStr = mPortText.getText().trim();
+ try {
+ int port = Integer.parseInt(portStr);
+ if (port <= 0) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, mResource, PREFIX,
+ "OUTOFRANGE", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ } catch (NumberFormatException ex) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, mResource, PREFIX,
+ "NONINTEGER", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ nvps.put(Constants.PR_PORT, portStr);
+
+ String timeoutStr = mTimeoutText.getText().trim();
+ try {
+ int timeout = Integer.parseInt(timeoutStr);
+ if (timeout < 0) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, mResource, PREFIX,
+ "TIMEOUTOUTOFRANGE", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ } catch (NumberFormatException ex) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, mResource, PREFIX,
+ "TIMEOUTNONINTEGER", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ nvps.put(Constants.PR_TIMEOUT, timeoutStr);
+
+ if (mName.equals("Data Recovery Manager Connector")) {
+ nvps.put(Constants.PR_URI, "/kra/agent/kra/connector");
+ } else if (mName.equals("Registration Manager Connector")) {
+ nvps.put(Constants.PR_URI, "/ra/connector");
+ } else if (mName.equals("Certificate Manager Connector")) {
+ nvps.put(Constants.PR_URI, "/ca/connector");
+ }
+ nvps.put(Constants.PR_NICK_NAME, mNicknameText.getText().trim());
+ nvps.put(Constants.PR_ENABLED, Constants.TRUE);
+ } else {
+ nvps.put(Constants.PR_ENABLED, Constants.FALSE);
+ }
+
+ try {
+ mAdmin.modify(mDest, ScopeDef.SC_CONNECTOR,
+ mName, nvps);
+ this.dispose();
+ } catch (EAdminException ex) {
+ CMSAdminUtil.showMessageDialog(mParentFrame,
+ "Error", ex.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ }
+ } else if (e.getSource().equals(mHelp)) {
+ CMSAdminUtil.help(HELPINDEX1);
+ }
+ }
+
+ private NameValuePairs getCertsList(String scope) {
+ try {
+ NameValuePairs nvps =
+ mAdmin.search(DestDef.DEST_SERVER_ADMIN, scope, new NameValuePairs());
+ return nvps;
+ } catch (EAdminException ex) {
+ CMSAdminUtil.showMessageDialog(mParentFrame,
+ "Error", ex.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ return null;
+ }
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/EvaluatorRegisterDialog.java b/base/console/src/com/netscape/admin/certsrv/config/EvaluatorRegisterDialog.java
new file mode 100644
index 000000000..d4dff2e25
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/EvaluatorRegisterDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+
+/**
+ * Evaluator Implementation Registration Editor
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+
+public class EvaluatorRegisterDialog extends RegisterDialog {
+
+ private final static String PREFIX = "EVALUATORREGISTERDIALOG";
+
+ public EvaluatorRegisterDialog(JFrame parent, AdminConnection conn) {
+ super(PREFIX, parent, conn);
+ setDisplay();
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/GeneralLogPanel.java b/base/console/src/com/netscape/admin/certsrv/config/GeneralLogPanel.java
new file mode 100644
index 000000000..66e9b4397
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/GeneralLogPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * LDAP server setting tab
+ *
+ * @author Ade Lee
+ * @version $Revision: 1211 $, $Date: 2010-08-18 13:15:37 -0400 (Wed, 18 Aug 2010) $
+ */
+public class GeneralLogPanel extends CMSBaseTab {
+
+ private static String PANEL_NAME = "GENERALLOG";
+ private static final String HELPINDEX =
+ "configuration-general-logs-settings-help";
+ private JCheckBox mEnable;
+ private Color mActiveColor;
+ private JLabel mLevelLabel;
+ private JTextField mLevelText;
+ private JCheckBox mShowCaller;
+
+ protected AdminConnection mAdmin;
+ protected CMSBaseResourceModel mModel;
+ private String mServletName;
+ private CMSTabPanel mParent;
+
+ public GeneralLogPanel(CMSTabPanel parent) {
+ super(PANEL_NAME, parent);
+ mHelpToken = HELPINDEX;
+ mServletName = DestDef.DEST_LOG_ADMIN;
+ mModel = parent.getResourceModel();
+ mParent = parent;
+ }
+
+ public void init() {
+ mAdmin = mModel.getServerInfo().getAdmin();
+ JPanel serverInfo = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mCenterPanel.setLayout(gb);
+
+ //add the enable checkbox
+ mEnable = makeJCheckBox("ENABLE");
+ mEnable.setSelected(true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(DIFFERENT_COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE,
+ 0,
+ DIFFERENT_COMPONENT_SPACE);
+ gb.setConstraints(mEnable, gbc);
+ mCenterPanel.add(mEnable);
+
+ //add the debug properties panel
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(serverInfo, gbc);
+ mCenterPanel.add(serverInfo);
+
+ GridBagLayout gb1 = new GridBagLayout();
+ serverInfo.setLayout(gb1);
+ serverInfo.setBorder(makeTitledBorder("DEBUG"));
+
+ // add frequency label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ mLevelLabel = makeJLabel("LEVEL");
+ mLevelText = makeJTextField(30);
+ mActiveColor = mLevelText.getBackground();
+ CMSAdminUtil.addEntryField(serverInfo,
+ mLevelLabel, mLevelText, gbc);
+
+ // add show caller checkbox
+ /*
+ CMSAdminUtil.resetGBC(gbc);
+ mShowCaller = makeJCheckBox("SHOWCALLER");
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE - COMPONENT_SPACE,0,COMPONENT_SPACE);
+ gb1.setConstraints(mShowCaller, gbc);
+ serverInfo.add(mShowCaller);
+ */
+ refresh();
+ }
+
+
+ public void refresh() {
+ mModel.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_DEBUG_LOG_ENABLE, "true");
+ nvps.put(Constants.PR_DEBUG_LOG_LEVEL, "0");
+ /*nvps.add(Constants.PR_DEBUG_LOG_SHOWCALLER, ""); */
+
+ try {
+ NameValuePairs val = mAdmin.read(mServletName,
+ ScopeDef.SC_GENERAL, Constants.RS_ID_CONFIG, nvps);
+
+ populate(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+ }
+
+ private void enableFields(boolean enable, Color color) {
+ mLevelText.setEnabled(enable);
+ mLevelText.setEditable(enable);
+ mLevelText.setBackground(color);
+ mLevelLabel.setEnabled(enable);
+ mLevelLabel.setBackground(color);
+
+ mLevelLabel.invalidate();
+ mLevelLabel.validate();
+ mLevelLabel.repaint(1);
+ }
+
+ protected void populate(NameValuePairs nvps) {
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name);
+ if (name.equals(Constants.PR_DEBUG_LOG_ENABLE)) {
+ if (value.equals(Constants.TRUE))
+ mEnable.setSelected(true);
+ else
+ mEnable.setSelected(false);
+ } else if (name.equals(Constants.PR_DEBUG_LOG_LEVEL)) {
+ mLevelText.setText(value);
+ }
+
+ /* else if (name.equals(Constants.PR_DEBUG_LOG_SHOWCALLER)) {
+ if (value.equals(Constants.TRUE))
+ mShowCaller.setSelected(true);
+ else
+ mShowCaller.setSelected(false);
+ } */
+
+ }
+
+ if (mEnable.isSelected())
+ enableFields(true, mActiveColor);
+ else
+ enableFields(false, getBackground());
+
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ super.actionPerformed(e);
+ if (mEnable.isSelected()) {
+ enableFields(true, mActiveColor);
+ } else {
+ enableFields(false, getBackground());
+ }
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ // check blank fields
+ String level = mLevelText.getText().trim();
+
+ if (mEnable.isSelected() && level.equals("")) {
+ showMessageDialog("BLANKFIELD");
+ return false;
+ }
+
+ try {
+ int num = Integer.parseInt(level);
+ if (num < 0) {
+ showMessageDialog("LEVELRANGE");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ showMessageDialog("NUMBERFORMAT");
+ return false;
+ }
+
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_DEBUG_LOG_LEVEL, level);
+
+ /*
+ if (mShowCaller.isSelected())
+ nvps.add(Constants.PR_DEBUG_LOG_SHOWCALLER, Constants.TRUE);
+ else
+ nvps.add(Constants.PR_DEBUG_LOG_SHOWCALLER, Constants.FALSE);
+ */
+
+ if (mEnable.isSelected())
+ nvps.put(Constants.PR_DEBUG_LOG_ENABLE, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_DEBUG_LOG_ENABLE, Constants.FALSE);
+
+ mModel.progressStart();
+ try {
+ mAdmin.modify(mServletName, ScopeDef.SC_GENERAL,
+ Constants.RS_ID_CONFIG, nvps, false);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ return false;
+ }
+
+ mModel.progressStop();
+ clearDirtyFlag();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/JobsConfigDialog.java b/base/console/src/com/netscape/admin/certsrv/config/JobsConfigDialog.java
new file mode 100644
index 000000000..307ddbbc4
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/JobsConfigDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import javax.swing.text.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Jobs Parameter Configuration Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class JobsConfigDialog extends CMSBaseConfigDialog
+ implements ActionListener
+{
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public JobsConfigDialog(NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest) {
+
+ super(parent, dest);
+
+ PREFIX = "JOBSCONFIGDIALOG";
+ mImplName_token = Constants.PR_JOBS_IMPL_NAME;
+ mImplType = Constants.PR_EXT_PLUGIN_IMPLTYPE_JOBS;
+ mHelpToken = "configuration-jobs";
+
+ init(nvp,parent,conn,dest);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/JobsImplDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/JobsImplDataModel.java
new file mode 100644
index 000000000..d3a605433
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/JobsImplDataModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Jobs Implementation Data model - represents the implementation
+ * table information
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class JobsImplDataModel extends CMSContentTableModel
+ implements IDataProcessor
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String IMPL_NAME = "NAME";
+ public static final String IMPL_CLASS = "CLASS";
+ public static final String IMPL_DESC = "DESC";
+
+ private static String[] mColumns = {JOBS_IMPL, CLASSNAME};
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public JobsImplDataModel() {
+ super();
+ init(mColumns);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void processData(Object data) {
+ Vector v = new Vector();
+ NameValuePairs obj = (NameValuePairs) data;
+ v.addElement(new JLabel(obj.get(IMPL_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE_PLUGIN),
+ JLabel.LEFT));
+ v.addElement(obj.get(IMPL_CLASS));
+ //v.addElement(obj.getValue(IMPL_DESC));
+ addRow(v, data);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/JobsImplTab.java b/base/console/src/com/netscape/admin/certsrv/config/JobsImplTab.java
new file mode 100644
index 000000000..57848c649
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/JobsImplTab.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 com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Jobs Instances Management Tab
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class JobsImplTab extends CMSBaseUGTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String IMPL_NAME = JobsImplDataModel.IMPL_NAME;
+ private static final String IMPL_CLASS = JobsImplDataModel.IMPL_CLASS;
+ private static final String IMPL_DESC = JobsImplDataModel.IMPL_DESC;
+
+ private static final String PANEL_NAME = "JOBSIMPL";
+ private static final String DIALOG_PREFIX = "JOBSREGISTERDIALOG";
+
+ private AdminConnection mConnection;
+ private String mDestination;
+
+ protected JScrollPane mScrollPane;
+ protected JTable mTable; //table
+ protected JobsImplDataModel mDataModel; //table model
+ protected JobsRegisterDialog mEditor=null; //keep single copy
+ protected ViewDialog mViewer=null; //keep single copy
+
+ protected JButton mRefresh, mAdd, mDelete, mView, mHelp;
+ private final static String HELPINDEX = "jobsscheduler-certsrv-jobplugin-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public JobsImplTab(CMSBaseResourceModel model) {
+ super(PANEL_NAME, model);
+ mConnection = model.getServerInfo().getAdmin();
+ mDataModel = new JobsImplDataModel();
+ mDestination = DestDef.DEST_JOBS_ADMIN;
+ mHelpToken = HELPINDEX;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mRefresh)) {
+ refresh();
+ }
+ if (e.getSource().equals(mAdd)) {
+ if (mEditor==null)
+ mEditor = new JobsRegisterDialog(mModel.getFrame(),
+ mConnection);
+ mEditor.showDialog(mDestination, ScopeDef.SC_JOBS_IMPLS);
+ refresh();
+ }
+ if (e.getSource().equals(mDelete)) {
+ Debug.println("Delete");
+ if(mTable.getSelectedRow()< 0)
+ return;
+ int i = showConfirmDialog("DELETE");
+ if (i == JOptionPane.YES_OPTION) {
+ delete();
+ Debug.println("Deleted");
+ }
+ }
+ if (e.getSource().equals(mView)) {
+ Debug.println("View");
+ if(mTable.getSelectedRow()< 0)
+ return;
+ NameValuePairs obj = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+ if (mViewer==null)
+ mViewer = new ViewDialog(mModel.getFrame());
+ mViewer.showDialog(obj.get(IMPL_NAME),
+ obj.get(IMPL_CLASS),
+ obj.get(IMPL_DESC));
+ }
+ if (e.getSource().equals(mHelp)) {
+ helpCallback();
+ }
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+ public void refresh() {
+
+ mDataModel.removeAllRows();
+ update();
+
+ setButtons();
+ mTable.invalidate();
+ mTable.validate();
+ mTable.repaint(1);
+ }
+
+ /**
+ * create the user action button panel
+ */
+ protected JPanel createButtonPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mAdd = makeJButton("ADD");
+ mDelete = makeJButton("DELETE");
+ mView = makeJButton("VIEW");
+ JButton[] buttons = {mAdd, mDelete, mView};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ protected JPanel createActionPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mRefresh = makeJButton("REFRESH");
+ mHelp = makeJButton("HELP");
+ //JButton[] buttons = { mRefresh, mHelp };
+ JButton[] buttons = { mRefresh };
+ return makeJButtonPanel(buttons, true);
+ }
+
+ protected JPanel createListPanel() {
+ mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ //center table
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ //mScrollPane.setBorder(CMSAdminUtil.makeTitledBorder(mResource,PANEL_NAME,"USERS"));
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ mTable.addMouseListener(this);
+ setLabelCellRenderer(mTable,0);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = 1;
+ gbc.weightx = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ JPanel buttonPanel = createButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ mListPanel.add(buttonPanel);
+
+ refresh();
+
+ return mListPanel;
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(new LabelCellRenderer(new JLabel()));
+ }
+
+
+ //set buttons
+ private void setButtons() {
+
+ //enable and diable buttons accordingly
+ //Debug.println("setButtons() - "+mTable.getSelectedRow());
+ //Debug.println("setButtons() - "+mTable.getSelectionModel().isSelectionEmpty());
+ if (mTable.getSelectionModel().isSelectionEmpty()) {
+ mDelete.setEnabled(false);
+ mView.setEnabled(false);
+ return;
+ }
+
+ if(mDataModel.getRowCount()<=0) {
+ mDelete.setEnabled(false);
+ mView.setEnabled(false);
+ return;
+ }
+
+ mDelete.setEnabled(true);
+ mView.setEnabled(true);
+
+ }
+
+ //=============================================
+ // SEND REQUESTS TO THE SERVER SIDE
+ //=============================================
+ private void update() {
+ //send request and parse data
+
+ mModel.progressStart();
+ NameValuePairs response;
+ try {
+ response = mConnection.search(mDestination,
+ ScopeDef.SC_JOBS_IMPLS,
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+
+ Debug.println(response.toString());
+
+ //parse the data
+ int i=0;
+ String[] vals = new String[response.size()];
+ Hashtable<String, NameValuePairs> data = new Hashtable<String, NameValuePairs>();
+ for (String entry : response.keySet()) {
+ entry = entry.trim();
+ String value = response.get(entry);
+ Debug.println("entry= "+entry);
+ Debug.println("value= " + value);
+ int x = value.indexOf(",");
+ Debug.println("x = " + x);
+ NameValuePairs obj = new NameValuePairs();
+ obj.put(IMPL_NAME, entry);
+ vals[i++]= entry ;
+ if (x != -1) {
+ obj.put(IMPL_CLASS, value.substring(0, x));
+ obj.put(IMPL_DESC, value.substring(x + 1));
+ }
+ else {
+ obj.put(IMPL_CLASS, value);
+ }
+ data.put(entry,obj);
+ }
+
+ CMSAdminUtil.bubbleSort(vals);
+
+ for (int y=0; y< vals.length ; y++) {
+ mDataModel.processData(data.get(vals[y]));
+ }
+
+ data.clear();
+
+ if (mDataModel.getRowCount() >0)
+ mTable.setRowSelectionInterval(0,0);
+
+ mModel.progressStop();
+ }
+
+ private void delete() {
+ //get entry name
+ mModel.progressStart();
+ NameValuePairs obj = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+
+ //send comment to server for the removal of user
+ try {
+ mConnection.delete(mDestination,
+ ScopeDef.SC_JOBS_IMPLS,
+ obj.get(IMPL_NAME));
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+ mModel.progressStop();
+ //send comment to server and refetch the content
+ refresh();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/JobsInstanceTab.java b/base/console/src/com/netscape/admin/certsrv/config/JobsInstanceTab.java
new file mode 100644
index 000000000..059a741ce
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/JobsInstanceTab.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Jobs Instances Management Tab
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class JobsInstanceTab extends CMSPluginInstanceTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PANEL_NAME = "JOBSRULE";
+
+ private final static String HELPINDEX = "jobsscheduler-certsrv-jobrules-help";
+
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public JobsInstanceTab(CMSBaseResourceModel model) {
+ super(model,DestDef.DEST_JOBS_ADMIN,PANEL_NAME);
+ Debug.println("JobsInstanceTab::JobsInstanceTab(<model>");
+ mConnection = model.getServerInfo().getAdmin();
+ mDataModel = new JobsRuleDataModel();
+ mScope = ScopeDef.SC_JOBS_INSTANCE;
+ RULE_NAME = JobsRuleDataModel.RULE_NAME;
+ RULE_STAT = JobsRuleDataModel.RULE_STAT;
+
+ mHelpToken = HELPINDEX;
+ }
+
+
+ public CMSBaseConfigDialog makeNewConfigDialog(
+ NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest
+ )
+ {
+
+ return new JobsConfigDialog(nvp,
+ parent,
+ conn,
+ dest);
+ }
+
+ public PluginSelectionDialog getPluginSelectionDialog(
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType
+ )
+ {
+ return new JobsPluginSelectionDialog(parent,conn,dest,pluginType);
+ }
+
+
+ /**
+ * create the user action button panel
+ */
+ protected JPanel createUserButtonPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mEdit = makeJButton("EDIT");
+ mAdd = makeJButton("ADD");
+ mDelete = makeJButton("DELETE");
+ JButton[] buttons = {mAdd, mDelete, mEdit};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/JobsPluginSelectionDialog.java b/base/console/src/com/netscape/admin/certsrv/config/JobsPluginSelectionDialog.java
new file mode 100644
index 000000000..d07e5ed32
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/JobsPluginSelectionDialog.java
@@ -0,0 +1,66 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Jobs Plugin Selection Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class JobsPluginSelectionDialog extends PluginSelectionDialog
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "JOBSSELECTIONDIALOG";
+ private static final String HELPINDEX =
+ "jobsscheduler-certsrv-add-jobrule-dbox-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public JobsPluginSelectionDialog(
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType)
+ {
+ super(PREFIX, parent,conn, dest, pluginType);
+ mScope = ScopeDef.SC_JOBS_IMPLS;
+ mInstanceScope = ScopeDef.SC_JOBS_INSTANCE;
+ mImageName = CMSAdminResources.IMAGE_RULE_PLUGIN;
+ if (dest.equals(DestDef.DEST_JOBS_ADMIN))
+ mHelpToken = HELPINDEX;
+
+ setDisplay();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/JobsRegisterDialog.java b/base/console/src/com/netscape/admin/certsrv/config/JobsRegisterDialog.java
new file mode 100644
index 000000000..bdb448eeb
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/JobsRegisterDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+
+/**
+ * Jobs Implementation Registration Editor
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+
+public class JobsRegisterDialog extends RegisterDialog {
+
+ private final static String PREFIX = "JOBSREGISTERDIALOG";
+
+ public JobsRegisterDialog(JFrame parent, AdminConnection conn) {
+ super(PREFIX, parent, conn);
+ setDisplay();
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/JobsRuleDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/JobsRuleDataModel.java
new file mode 100644
index 000000000..76fbd9a38
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/JobsRuleDataModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.Debug;
+
+
+/**
+ * Jobs instance Data model - represents the instance
+ * table information
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class JobsRuleDataModel extends CMSRuleDataModel
+{
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public JobsRuleDataModel() {
+ super();
+ }
+
+ protected String[] getColumns() {
+ Debug.println("JobsRuleDataModel.getColumns()");
+ String x[] = {JOBS_RULE, STATUS};
+ return x;
+ }
+
+ public void processData(Object data) {
+ Vector v = new Vector();
+ NameValuePairs obj = (NameValuePairs) data;
+
+ //XXX NEED TO ADD STUFF
+ if (obj.get(RULE_STAT).equalsIgnoreCase("enabled")) {
+ v.addElement(new JLabel(obj.get(RULE_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE),
+ JLabel.LEFT));
+ v.addElement(mResource.getString("JOBSRULE_LABEL_ENABLED_LABEL"));
+ } else {
+ v.addElement(new JLabel(obj.get(RULE_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE_DISABLE),
+ JLabel.LEFT));
+ v.addElement(mResource.getString("JOBSRULE_LABEL_DISABLED_LABEL"));
+ }
+ addRow(v, data);
+ mRules.addElement(obj.get(RULE_NAME));
+ }
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/JobsSettingPanel.java b/base/console/src/com/netscape/admin/certsrv/config/JobsSettingPanel.java
new file mode 100644
index 000000000..b6a93d191
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/JobsSettingPanel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * Jobs Scheduler setting tab
+ *
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class JobsSettingPanel extends CMSBaseTab implements ItemListener {
+ private static final String HELPINDEX =
+ "jobsscheduler-certsrv-setting-jobrule-help";
+ private JTextField mFrequencyText;
+ private JCheckBox mEnable;
+ private Color mActiveColor;
+ private JLabel mFrequencyLabel;
+ protected AdminConnection mAdmin;
+ protected CMSBaseResourceModel mModel;
+ private String mServletName;
+ private CMSTabPanel mParent;
+ private String mPanelName;
+
+ public JobsSettingPanel(String panelName, CMSTabPanel parent) {
+ this(panelName, parent, true);
+ mPanelName = panelName;
+ }
+
+ public JobsSettingPanel(String panelName, CMSTabPanel parent, boolean flag) {
+ super(panelName, parent);
+ mServletName = DestDef.DEST_JOBS_ADMIN;
+ mHelpToken = HELPINDEX;
+ mModel = parent.getResourceModel();
+ mParent = parent;
+ }
+
+ public void init() {
+ mAdmin = mModel.getServerInfo().getAdmin();
+ JPanel serverInfo = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mCenterPanel.setLayout(gb);
+
+ //add the enable checkbox
+ mEnable = makeJCheckBox("ENABLE");
+ mEnable.setSelected(true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(DIFFERENT_COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE,
+ 0,
+ DIFFERENT_COMPONENT_SPACE);
+ gb.setConstraints(mEnable, gbc);
+ mCenterPanel.add(mEnable);
+
+ //add the frequency panel
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(serverInfo, gbc);
+ mCenterPanel.add(serverInfo);
+
+ GridBagLayout gb1 = new GridBagLayout();
+ serverInfo.setLayout(gb1);
+ serverInfo.setBorder(makeTitledBorder("FREQUENCY"));
+
+ // add frequency label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ mFrequencyLabel = makeJLabel("FREQUENCY");
+ mFrequencyText = makeJTextField(30);
+ mActiveColor = mFrequencyText.getBackground();
+ JLabel dateLabel = makeJLabel("MINUTES");
+ CMSAdminUtil.addEntryField(serverInfo,
+ mFrequencyLabel, mFrequencyText, dateLabel, gbc);
+
+ refresh();
+ }
+
+ public void refresh() {
+ mModel.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_ENABLE, "");
+ nvps.put(Constants.PR_JOBS_FREQUENCY, "");
+
+ try {
+ NameValuePairs val = mAdmin.read(mServletName,
+ ScopeDef.SC_JOBS, Constants.RS_ID_CONFIG, nvps);
+
+ populate(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+ }
+
+ protected void populate(NameValuePairs nvps) {
+ String clientCert = "";
+
+ String version = "";
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name);
+ if (name.equals(Constants.PR_JOBS_FREQUENCY)) {
+ mFrequencyText.setText(value);
+ } else if (name.equals(Constants.PR_ENABLE)) {
+ if (value.equals(Constants.TRUE))
+ mEnable.setSelected(true);
+ else
+ mEnable.setSelected(false);
+ }
+ }
+
+ if (mEnable.isSelected())
+ enableFields(true, mActiveColor);
+ else
+ enableFields(false, getBackground());
+ }
+
+ private int getIndex(String val, String[] array) {
+ for (int i=0; i<array.length; i++) {
+ if (val.equals(array[i]))
+ return i;
+ }
+ return -1;
+ }
+
+ private void enableFields(boolean enable, Color color) {
+ mFrequencyText.setEnabled(enable);
+ mFrequencyText.setEditable(enable);
+ mFrequencyText.setBackground(color);
+ mFrequencyLabel.setEnabled(enable);
+ mFrequencyLabel.setBackground(color);
+
+ mFrequencyLabel.invalidate();
+ mFrequencyLabel.validate();
+ mFrequencyLabel.repaint(1);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ super.actionPerformed(e);
+ if (mEnable.isSelected()) {
+ enableFields(true, mActiveColor);
+ } else {
+ enableFields(false, getBackground());
+ }
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ // check blank fields
+ String freq = mFrequencyText.getText().trim();
+
+ if (freq.equals("")) {
+ showMessageDialog("BLANKFIELD");
+ return false;
+ }
+
+ int ifreq = 0;
+ // make sure it's a positive integer
+ try {
+ ifreq = Integer.parseInt(freq);
+ } catch (NumberFormatException e) {
+ showMessageDialog("NEEDINTEGER");
+ return false;
+ }
+
+ if (ifreq < 0) {
+ showMessageDialog("NEEDINTEGER");
+ return false;
+ }
+
+ NameValuePairs nvps = new NameValuePairs();
+ if (mEnable.isSelected())
+ nvps.put(Constants.PR_ENABLE, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_ENABLE, Constants.FALSE);
+
+ if (mEnable.isSelected()){
+ nvps.put(Constants.PR_JOBS_FREQUENCY, freq);
+ }
+
+ mModel.progressStart();
+ try {
+ mAdmin.modify(mServletName, ScopeDef.SC_JOBS,
+ Constants.RS_ID_CONFIG, nvps);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ return false;
+ }
+
+ mModel.progressStop();
+ clearDirtyFlag();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/KeyCreateDialog.java b/base/console/src/com/netscape/admin/certsrv/config/KeyCreateDialog.java
new file mode 100644
index 000000000..5821127d4
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/KeyCreateDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Log Implementation Registration Editor
+ *
+ * @author Michelle Zhao
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+
+public class KeyCreateDialog extends JDialog
+ implements ActionListener, DocumentListener, MouseListener {
+
+ private final static String PREFIX = "KEYCREATEDIALOG";
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private JFrame mParentFrame;
+ private AdminConnection mConnection;
+ private ResourceBundle mResource;
+
+ private JTextField mNameField; //mClassField,mTypeField
+ private JButton mOK, mCancel;
+
+ protected String mDestination; //DEST_TAG to support RA/KRA/CA dest
+ protected String mScope;
+ protected String mPrefix;
+ protected String selectedToken;
+ private boolean mIsOK = false;
+ protected boolean mType = false;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ public KeyCreateDialog(JFrame parent, AdminConnection conn) {
+ super(parent,true);
+ KeyCreateDialog2(PREFIX, parent, conn);
+ setDisplay();
+ }
+ public void KeyCreateDialog2(String prefix, JFrame parent, AdminConnection conn) {
+
+ mParentFrame = parent;
+ mPrefix = prefix;
+ mConnection = conn;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ setSize(360, 216);
+ setTitle(mResource.getString(mPrefix+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ //setDisplay(); SUBCLASS MUST call setDiaply() in its constructor
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * show the windows
+ */
+ public void showDialog(String destination, String scope) {
+ //initialize and setup
+ mNameField.setText("");
+ //mClassField.setText("");
+ //if (mType) {
+ // mTypeField.setText("");
+ //}
+ mDestination=destination;
+ mScope=scope;
+ this.show();
+ }
+
+ protected void setDestination(String destination) {
+ mDestination = destination;
+ }
+
+ protected void setScope(String scope) {
+ mScope = scope;
+ }
+
+ public boolean isOK() {
+ return mIsOK;
+ }
+ public void setToken(String thisToken)
+ {
+ selectedToken = thisToken;
+ }
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent evt) {
+
+ if (evt.getSource().equals(mCancel)) {
+ mIsOK = false;
+ this.hide();
+ }
+
+ if (evt.getSource().equals(mOK)) {
+
+ /* REPLACED BY PROACTIVE ENFORCEMENT
+ if (mNameField.getText().trim().equals("")) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, mResource, mPrefix,
+ "NONAME", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ if (mClassField.getText().trim().equals("")) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, mResource, mPrefix,
+ "NOCLASS", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ */
+
+ //save value
+ try {
+ addImpl();
+ } catch (EAdminException e) {
+ //display error dialog
+ Debug.println(e.toString());
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ mIsOK = false;
+ return;
+ }
+ mIsOK = true;
+ this.hide();
+ }
+ }
+
+ //== DocumentListener ==
+ public void insertUpdate(DocumentEvent e) {
+ setButtons();
+ }
+
+ public void removeUpdate(DocumentEvent e){
+ setButtons();
+ }
+
+ public void changedUpdate(DocumentEvent e){
+ setButtons();
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {}
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+
+ protected void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ //set arrow buttons
+ private void setButtons() {
+ if ( mNameField.getText().trim().equals("")) {
+ //||
+ //(mClassField.getText().trim().equals("")) ) {
+ mOK.setEnabled(false);
+ } else {
+ mOK.setEnabled(true);
+ }
+ }
+
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, mPrefix, "OK", null, this);
+ mOK.setEnabled(false);
+ mCancel = CMSAdminUtil.makeJButton(mResource, mPrefix, "CANCEL", null, this);
+ JButton[] buttons = { mOK, mCancel};
+ return CMSAdminUtil.makeJButtonPanel( buttons );
+ }
+
+ private JPanel makeContentPane() {
+ JPanel content = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ content.setLayout(gb3);
+ //content.setBorder(CMSAdminUtil.makeEtchedBorder());
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label1 = CMSAdminUtil.makeJLabel(mResource, mPrefix, "NAME", null);
+ mNameField = new JTextField();
+ mNameField.getDocument().addDocumentListener(this);
+ mNameField.addMouseListener(this);
+ CMSAdminUtil.addEntryField(content, label1, mNameField, gbc);
+
+ //CMSAdminUtil.resetGBC(gbc);
+ // gbc.gridheight = gbc.REMAINDER;
+ //JLabel label2 = CMSAdminUtil.makeJLabel(mResource, mPrefix, "CLASS", null);
+ //mClassField = new JTextField();
+ //mClassField.getDocument().addDocumentListener(this);
+ //mClassField.addMouseListener(this);
+ //CMSAdminUtil.addEntryField(content, label2, mClassField, gbc);
+
+ //if (mType) {
+ // CMSAdminUtil.resetGBC(gbc);
+ // gbc.gridheight = gbc.REMAINDER;
+ // JLabel label3 = CMSAdminUtil.makeJLabel(mResource, mPrefix, "TYPE", null);
+ // mTypeField = new JTextField();
+ // mTypeField.getDocument().addDocumentListener(this);
+ // mTypeField.addMouseListener(this);
+ // CMSAdminUtil.addEntryField(content, label3, mTypeField, gbc);
+ //}
+
+ return content;
+ }
+
+ //=================================================
+ // CONNECT TO SERVER SIDE
+ //=================================================
+
+ //add new group information
+ private void addImpl() throws EAdminException {
+
+ //construct NVP
+ NameValuePairs config = new NameValuePairs();
+ config.put(Constants.PR_KEY_LIST, mNameField.getText());
+ config.put(Constants.PR_TOKEN_LIST, selectedToken);
+
+
+
+
+ //send request
+ mConnection.process(mDestination,
+ ScopeDef.SC_TKSKEYSLIST,
+ mNameField.getText().trim(),
+ config);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ListCertsModel.java b/base/console/src/com/netscape/admin/certsrv/config/ListCertsModel.java
new file mode 100644
index 000000000..b239edfb9
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ListCertsModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Manage certificate data model - represents the instance
+ * table information
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class ListCertsModel extends CMSTableModel
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String COL1 = "CERTNICKNAMENAME";
+ public static final String COL2 = "SERIALNUMBER";
+ public static final String COL3 = "ISSUERNAME";
+ public static final String COL4 = "TOKENNAME";
+
+ private static String[] mColumns = {COL1, COL2, COL3, COL4};
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public ListCertsModel() {
+ super();
+ init(mColumns);
+ }
+
+ public boolean isCellEditable(int row, int col) {
+ return false;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ListKeysModel.java b/base/console/src/com/netscape/admin/certsrv/config/ListKeysModel.java
new file mode 100644
index 000000000..78f033be5
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ListKeysModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Manage Keys data model - represents the instance
+ * table information
+ *
+ * @author Khai
+ * @version $Revision$, $Date$
+ */
+public class ListKeysModel extends CMSTableModel
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String COL1 = "KEYNAME";
+ public static final String COL2 = "SERIALNUMBER";
+ public static final String COL3 = "ISSUERNAME";
+ public static final String COL4 = "TOKENNAME";
+
+ private static String[] mColumns = {COL1};
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public ListKeysModel() {
+ super();
+ init(mColumns);
+ }
+
+ public boolean isCellEditable(int row, int col) {
+ return false;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/LogConfigDialog.java b/base/console/src/com/netscape/admin/certsrv/config/LogConfigDialog.java
new file mode 100644
index 000000000..7f3833034
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/LogConfigDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import javax.swing.text.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Log Parameter Configuration Dialog
+ *
+ * @author Michelle Zhao
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class LogConfigDialog extends CMSBaseConfigDialog
+ implements ActionListener
+{
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public LogConfigDialog(NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest) {
+
+ super(parent, dest);
+
+ PREFIX = "LOGCONFIGDIALOG";
+ mHelpToken = "configuration-overview";
+ mImplName_token = Constants.PR_LOG_IMPL_NAME;
+ mImplType = Constants.PR_EXT_PLUGIN_IMPLTYPE_LOG;
+
+ init(nvp,parent,conn,dest);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/LogImplDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/LogImplDataModel.java
new file mode 100644
index 000000000..a5af0b1dc
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/LogImplDataModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Log Implementation Data model - represents the implementation
+ * table information
+ *
+ * @author Michelle Zhao
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class LogImplDataModel extends CMSContentTableModel
+ implements IDataProcessor
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String IMPL_NAME = "NAME";
+ public static final String IMPL_CLASS = "CLASS";
+ public static final String IMPL_DESC = "DESC";
+
+ private static String[] mColumns = {LOG_IMPL, CLASSNAME};
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public LogImplDataModel() {
+ super();
+ init(mColumns);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void processData(Object data) {
+ Vector v = new Vector();
+ NameValuePairs obj = (NameValuePairs) data;
+ v.addElement(new JLabel(obj.get(IMPL_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE_PLUGIN),
+ JLabel.LEFT));
+ v.addElement(obj.get(IMPL_CLASS));
+ //v.addElement(obj.getValue(IMPL_DESC));
+ addRow(v, data);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/LogImplTab.java b/base/console/src/com/netscape/admin/certsrv/config/LogImplTab.java
new file mode 100644
index 000000000..1b654fead
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/LogImplTab.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Log Plugins Management Tab
+ *
+ * @author Michelle Zhao
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class LogImplTab extends CMSBaseUGTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String IMPL_NAME = LogImplDataModel.IMPL_NAME;
+ private static final String IMPL_CLASS = LogImplDataModel.IMPL_CLASS;
+ private static final String IMPL_DESC = LogImplDataModel.IMPL_DESC;
+
+ private static final String PANEL_NAME = "LOGIMPL";
+ private static final String DIALOG_PREFIX = "LOGREGISTERDIALOG";
+
+ private AdminConnection mConnection;
+ private String mDestination;
+
+ protected JScrollPane mScrollPane;
+ protected JTable mTable; //table
+ protected LogImplDataModel mDataModel; //table model
+ protected LogRegisterDialog mEditor=null; //keep single copy
+ protected ViewDialog mViewer=null; //keep single copy
+
+ protected JButton mRefresh, mAdd, mDelete, mView, mHelp;
+ private final static String HELPINDEX = "configuration-log-plugin-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public LogImplTab(CMSBaseResourceModel model, String destination) {
+ super(PANEL_NAME, model);
+ mConnection = model.getServerInfo().getAdmin();
+ mDataModel = new LogImplDataModel();
+ mDestination = destination;
+ mHelpToken = HELPINDEX;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mRefresh)) {
+ refresh();
+ }
+ if (e.getSource().equals(mAdd)) {
+ if (mEditor==null)
+ mEditor = new LogRegisterDialog(mModel.getFrame(),
+ mConnection);
+ mEditor.showDialog(mDestination, ScopeDef.SC_LOG_IMPLS);
+ refresh();
+ }
+ if (e.getSource().equals(mDelete)) {
+ Debug.println("Delete");
+ if(mTable.getSelectedRow()< 0)
+ return;
+ int i = showConfirmDialog("DELETE");
+ if (i == JOptionPane.YES_OPTION) {
+ delete();
+ Debug.println("Deleted");
+ }
+ }
+ if (e.getSource().equals(mView)) {
+ Debug.println("View");
+ if(mTable.getSelectedRow()< 0)
+ return;
+ NameValuePairs obj = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+ if (mViewer==null)
+ mViewer = new ViewDialog(mModel.getFrame());
+ mViewer.showDialog(obj.get(IMPL_NAME),
+ obj.get(IMPL_CLASS),
+ obj.get(IMPL_DESC));
+ }
+ if (e.getSource().equals(mHelp)) {
+ helpCallback();
+ }
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+ public void refresh() {
+
+ mDataModel.removeAllRows();
+ update();
+
+ setButtons();
+ mTable.invalidate();
+ mTable.validate();
+ mTable.repaint(1);
+ }
+
+ /**
+ * create the user action button panel
+ */
+ protected JPanel createButtonPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mAdd = makeJButton("ADD");
+ mDelete = makeJButton("DELETE");
+ mView = makeJButton("VIEW");
+ JButton[] buttons = {mAdd, mDelete, mView};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ protected JPanel createActionPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mRefresh = makeJButton("REFRESH");
+ mHelp = makeJButton("HELP");
+ //JButton[] buttons = { mRefresh, mHelp };
+ JButton[] buttons = { mRefresh };
+ return makeJButtonPanel(buttons, true);
+ }
+
+ protected JPanel createListPanel() {
+ mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ //center table
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ //mScrollPane.setBorder(CMSAdminUtil.makeTitledBorder(mResource,PANEL_NAME,"USERS"));
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ mTable.addMouseListener(this);
+ setLabelCellRenderer(mTable,0);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = 1;
+ gbc.weightx = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ JPanel buttonPanel = createButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ mListPanel.add(buttonPanel);
+
+ refresh();
+
+ return mListPanel;
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(new LabelCellRenderer(new JLabel()));
+ }
+
+
+ //set buttons
+ private void setButtons() {
+
+ //enable and diable buttons accordingly
+ //Debug.println("setButtons() - "+mTable.getSelectedRow());
+ //Debug.println("setButtons() - "+mTable.getSelectionModel().isSelectionEmpty());
+ if (mTable.getSelectionModel().isSelectionEmpty()) {
+ mDelete.setEnabled(false);
+ mView.setEnabled(false);
+ return;
+ }
+
+ if(mDataModel.getRowCount()<=0) {
+ mDelete.setEnabled(false);
+ mView.setEnabled(false);
+ return;
+ }
+
+ mDelete.setEnabled(true);
+ mView.setEnabled(true);
+
+ }
+
+ //=============================================
+ // SEND REQUESTS TO THE SERVER SIDE
+ //=============================================
+ private void update() {
+ //send request and parse data
+
+ mModel.progressStart();
+ NameValuePairs response;
+ try {
+ response = mConnection.search(mDestination,
+ "logImpls",
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+
+ Debug.println(response.toString());
+
+ //parse the data
+ int i=0;
+ String[] vals = new String[response.size()];
+ Hashtable<String, NameValuePairs> data = new Hashtable<String, NameValuePairs>();
+ for (String entry : response.keySet()) {
+ entry = entry.trim();
+ String value = response.get(entry);
+ int x = value.indexOf(",");
+ NameValuePairs obj = new NameValuePairs();
+ obj.put(IMPL_NAME, entry);
+ vals[i++]= entry ;
+ obj.put(IMPL_CLASS, value.substring(0, x));
+ obj.put(IMPL_DESC, value.substring(x + 1));
+ data.put(entry,obj);
+ }
+
+ CMSAdminUtil.bubbleSort(vals);
+
+ for (int y=0; y< vals.length ; y++) {
+ mDataModel.processData(data.get(vals[y]));
+ }
+
+ data.clear();
+
+ if (mDataModel.getRowCount() >0)
+ mTable.setRowSelectionInterval(0,0);
+
+ mModel.progressStop();
+ }
+
+ private void delete() {
+ //get entry name
+ mModel.progressStart();
+ NameValuePairs obj = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+
+ //send comment to server for the removal of user
+ try {
+ mConnection.delete(mDestination,
+ ScopeDef.SC_LOG_IMPLS,
+ obj.get(IMPL_NAME));
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+ mModel.progressStop();
+ //send comment to server and refetch the content
+ refresh();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/LogInstanceTab.java b/base/console/src/com/netscape/admin/certsrv/config/LogInstanceTab.java
new file mode 100644
index 000000000..99b86e5eb
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/LogInstanceTab.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Log Instances Management Tab
+ *
+ * @author Michelle Zhao
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class LogInstanceTab extends CMSPluginInstanceTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PANEL_NAME = "LOGRULE";
+
+ private final static String HELPINDEX = "configuration-loginstances-help";
+
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public LogInstanceTab(CMSBaseResourceModel model, String dest) {
+ super(model,dest,PANEL_NAME);
+ Debug.println("LogInstanceTab::LogInstanceTab(<model>,"+dest);
+ mConnection = model.getServerInfo().getAdmin();
+ mDataModel = new LogRuleDataModel();
+ mScope = ScopeDef.SC_LOG_RULES;
+ RULE_NAME = LogRuleDataModel.RULE_NAME;
+ RULE_IMPL = LogRuleDataModel.RULE_IMPL;
+ RULE_STAT = LogRuleDataModel.RULE_STAT;
+
+ mHelpToken = HELPINDEX;
+ }
+
+
+ public CMSBaseConfigDialog makeNewConfigDialog(
+ NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest
+ )
+ {
+
+ return new LogConfigDialog(nvp,
+ parent,
+ conn,
+ dest);
+ }
+
+ public PluginSelectionDialog getPluginSelectionDialog(
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType
+ )
+ {
+ return new LogPluginSelectionDialog(parent,conn,dest,pluginType);
+ }
+
+
+}
+
+
+
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/LogPluginSelectionDialog.java b/base/console/src/com/netscape/admin/certsrv/config/LogPluginSelectionDialog.java
new file mode 100644
index 000000000..83c8ab2e8
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/LogPluginSelectionDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Log Plugin Selection Dialog
+ *
+ * @author Michelle Zhao
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class LogPluginSelectionDialog extends PluginSelectionDialog
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "LOGSELECTIONDIALOG";
+ private static final String HELPINDEX =
+ "configuration-add-logrule-dbox-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public LogPluginSelectionDialog(
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType)
+ {
+ super(PREFIX, parent,conn, dest, pluginType);
+ mScope = ScopeDef.SC_LOG_IMPLS;
+ mInstanceScope = ScopeDef.SC_LOG_RULES;
+ mImageName = CMSAdminResources.IMAGE_RULE_PLUGIN;
+ mHelpToken = HELPINDEX;
+ setDisplay();
+ }
+
+ /*==========================================================
+ * EVENT HANDLER METHODS
+ *==========================================================*/
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/LogRegisterDialog.java b/base/console/src/com/netscape/admin/certsrv/config/LogRegisterDialog.java
new file mode 100644
index 000000000..2360c860a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/LogRegisterDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+
+/**
+ * Log Implementation Registration Editor
+ *
+ * @author Michelle Zhao
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+
+public class LogRegisterDialog extends RegisterDialog {
+
+ private final static String PREFIX = "LOGREGISTERDIALOG";
+
+ public LogRegisterDialog(JFrame parent, AdminConnection conn) {
+ super(PREFIX, parent, conn);
+ setDisplay();
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/LogRuleDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/LogRuleDataModel.java
new file mode 100644
index 000000000..1a64226f0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/LogRuleDataModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.Debug;
+
+
+/**
+ * Log instance Data model - represents the instance
+ * table information
+ *
+ * @author Michelle Zhao
+ * @version $Revision$, $Date$
+ */
+public class LogRuleDataModel extends CMSRuleDataModel
+{
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public LogRuleDataModel() {
+ super();
+ }
+
+ protected String[] getColumns() {
+ Debug.println("LogRuleDataModel.getColumns()");
+ String x[] = {LOG_RULE, PLUGIN};
+ return x;
+ }
+
+ public void processData(Object data) {
+ Vector v = new Vector();
+ NameValuePairs obj = (NameValuePairs) data;
+
+ v.addElement(new JLabel(obj.get(RULE_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE),
+ JLabel.LEFT));
+ v.addElement(obj.get(RULE_IMPL));
+ addRow(v, data);
+ }
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/MNSchemeWizard.java b/base/console/src/com/netscape/admin/certsrv/config/MNSchemeWizard.java
new file mode 100644
index 000000000..cd10c5575
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/MNSchemeWizard.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.admin.certsrv.config;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Wizard for reconfiguring the Recovery MN Scheme
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class MNSchemeWizard extends WizardWidget {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public MNSchemeWizard(JFrame parent, MNSchemeWizardInfo info) {
+ super(parent);
+ setWizardInfo(info);
+ //add page here
+ addPage(new WMNSelection());
+ addPage(new WMNOldAgent());
+ addPage(new WMNNewAgent());
+ addPage(new WMNResultPage());
+ show();
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+ protected void callHelp() {
+ if (mCurrent instanceof IWizardPanel) {
+ ((IWizardPanel)mCurrent).callHelp();
+ }
+ }
+
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/MNSchemeWizardInfo.java b/base/console/src/com/netscape/admin/certsrv/config/MNSchemeWizardInfo.java
new file mode 100644
index 000000000..8d90914b3
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/MNSchemeWizardInfo.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * WizardInfo for reconfiguring the Recovery MN Scheme
+ * Once complete, we need to zap this object.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class MNSchemeWizardInfo extends WizardInfo {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private AdminConnection mConnection;
+ private int mM, mN;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public MNSchemeWizardInfo(AdminConnection conn, int m, int n) {
+ super();
+ mConnection = conn;
+ mM = m;
+ mN = n;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ //get m
+ public String getM() {
+ return Integer.toString(mM);
+ }
+
+ //get n
+ public String getN() {
+ return Integer.toString(mN);
+ }
+
+ public String getNewM() {
+ if(containsKey(Constants.PR_RECOVERY_M))
+ return (String) get(Constants.PR_RECOVERY_M);
+ return getM();
+ }
+
+ public String getNewN() {
+ if(containsKey(Constants.PR_RECOVERY_N))
+ return (String) get(Constants.PR_RECOVERY_N);
+ return getN();
+ }
+
+
+ //add information into info
+ public void add(String name, String value) {
+ put(name,value);
+ }
+
+ /**
+ * Clean up the data struture stored within this container
+ */
+ public void cleanup() {
+ clear();
+ }
+
+ /**
+ * Perform Operation
+ */
+ public void changeScheme() throws EAdminException {
+
+ NameValuePairs param = new NameValuePairs();
+ param.put(Constants.PR_RECOVERY_M, (String) get(Constants.PR_RECOVERY_M));
+ param.put(Constants.PR_RECOVERY_N, (String) get(Constants.PR_RECOVERY_N));
+ param.put(Constants.PR_RECOVERY_AGENT, (String) get(Constants.PR_RECOVERY_AGENT));
+ param.put(Constants.PR_OLD_RECOVERY_AGENT, (String) get(Constants.PR_OLD_RECOVERY_AGENT));
+
+ mConnection.modify(DestDef.DEST_KRA_ADMIN,
+ ScopeDef.SC_MNSCHEME,
+ Constants.RS_ID_CONFIG,
+ param);
+
+ //param.clear();
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/MapperConfigDialog.java b/base/console/src/com/netscape/admin/certsrv/config/MapperConfigDialog.java
new file mode 100644
index 000000000..119823d58
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/MapperConfigDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import javax.swing.text.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Mapper Parameter Configuration Dialog
+ *
+ * @author Steve Parkinson
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class MapperConfigDialog extends CMSBaseConfigDialog
+ implements ActionListener
+{
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public MapperConfigDialog(NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest) {
+
+ super(parent, dest);
+
+ PREFIX = "MAPPERCONFIGDIALOG";
+ RAHELPINDEX = "configuration-ra-edit-mapperrule-dbox-help";
+ KRAHELPINDEX = "configuration-kra-edit-mapperrule-dbox-help";
+ CAHELPINDEX = "configuration-ca-edit-mapperrule-dbox-help";
+ mImplName_token = Constants.PR_MAPPER_IMPL_NAME;
+ mImplType = Constants.PR_EXT_PLUGIN_IMPLTYPE_MAPPER;
+
+ init(nvp,parent,conn,dest);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/MapperImplDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/MapperImplDataModel.java
new file mode 100644
index 000000000..23d6ee0b4
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/MapperImplDataModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Mapper Implementation Data model - represents the implementation
+ * table information
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class MapperImplDataModel extends CMSContentTableModel
+ implements IDataProcessor
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String IMPL_NAME = "NAME";
+ public static final String IMPL_CLASS = "CLASS";
+ public static final String IMPL_DESC = "DESC";
+
+ private static String[] mColumns = {MAPPER_IMPL, CLASSNAME};
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public MapperImplDataModel() {
+ super();
+ init(mColumns);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void processData(Object data) {
+ Vector v = new Vector();
+ NameValuePairs obj = (NameValuePairs) data;
+ v.addElement(new JLabel(obj.get(IMPL_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE_PLUGIN),
+ JLabel.LEFT));
+ v.addElement(obj.get(IMPL_CLASS));
+ //v.addElement(obj.getValue(IMPL_DESC));
+ addRow(v, data);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/MapperImplTab.java b/base/console/src/com/netscape/admin/certsrv/config/MapperImplTab.java
new file mode 100644
index 000000000..2ad54da60
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/MapperImplTab.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Mapper Instances Management Tab
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class MapperImplTab extends CMSBaseUGTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String IMPL_NAME = MapperImplDataModel.IMPL_NAME;
+ private static final String IMPL_CLASS = MapperImplDataModel.IMPL_CLASS;
+ private static final String IMPL_DESC = MapperImplDataModel.IMPL_DESC;
+
+ private static final String PANEL_NAME = "MAPPERIMPL";
+ private static final String DIALOG_PREFIX = "MAPPERREGISTERDIALOG";
+
+ private AdminConnection mConnection;
+ private String mDestination;
+
+ protected JScrollPane mScrollPane;
+ protected JTable mTable; //table
+ protected MapperImplDataModel mDataModel; //table model
+ protected MapperRegisterDialog mEditor=null; //keep single copy
+ protected ViewDialog mViewer=null; //keep single copy
+
+ protected JButton mRefresh, mAdd, mDelete, mView, mHelp;
+ private final static String RAHELPINDEX = "configuration-ra-mapperplugin-help";
+ private final static String CAHELPINDEX = "configuration-ca-mapperplugin-help";
+ private final static String KRAHELPINDEX = "configuration-kra-mapperplugin-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public MapperImplTab(CMSBaseResourceModel model, String destination) {
+ super(PANEL_NAME, model);
+ mConnection = model.getServerInfo().getAdmin();
+ mDataModel = new MapperImplDataModel();
+ mDestination = destination;
+ if (mDestination.equals(DestDef.DEST_RA_MAPPER_ADMIN))
+ mHelpToken = RAHELPINDEX;
+ else
+ mHelpToken = CAHELPINDEX;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mRefresh)) {
+ refresh();
+ }
+ if (e.getSource().equals(mAdd)) {
+ if (mEditor==null)
+ mEditor = new MapperRegisterDialog(mModel.getFrame(),
+ mConnection);
+ mEditor.showDialog(mDestination, ScopeDef.SC_MAPPER_IMPLS);
+ refresh();
+ }
+ if (e.getSource().equals(mDelete)) {
+ Debug.println("Delete");
+ if(mTable.getSelectedRow()< 0)
+ return;
+ int i = showConfirmDialog("DELETE");
+ if (i == JOptionPane.YES_OPTION) {
+ delete();
+ Debug.println("Deleted");
+ }
+ }
+ if (e.getSource().equals(mView)) {
+ Debug.println("View");
+ if(mTable.getSelectedRow()< 0)
+ return;
+ NameValuePairs obj = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+ if (mViewer==null)
+ mViewer = new ViewDialog(mModel.getFrame());
+ mViewer.showDialog(obj.get(IMPL_NAME),
+ obj.get(IMPL_CLASS),
+ obj.get(IMPL_DESC));
+ }
+ if (e.getSource().equals(mHelp)) {
+ helpCallback();
+ }
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+ public void refresh() {
+
+ mDataModel.removeAllRows();
+ update();
+
+ setButtons();
+ mTable.invalidate();
+ mTable.validate();
+ mTable.repaint(1);
+ }
+
+ /**
+ * create the user action button panel
+ */
+ protected JPanel createButtonPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mAdd = makeJButton("ADD");
+ mDelete = makeJButton("DELETE");
+ mView = makeJButton("VIEW");
+ JButton[] buttons = {mAdd, mDelete, mView};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ protected JPanel createActionPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mRefresh = makeJButton("REFRESH");
+ mHelp = makeJButton("HELP");
+ // JButton[] buttons = { mRefresh, mHelp };
+ JButton[] buttons = { mRefresh };
+ return makeJButtonPanel(buttons, true);
+ }
+
+ protected JPanel createListPanel() {
+ mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ //center table
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ //mScrollPane.setBorder(CMSAdminUtil.makeTitledBorder(mResource,PANEL_NAME,"USERS"));
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ mTable.addMouseListener(this);
+ setLabelCellRenderer(mTable,0);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = 1;
+ gbc.weightx = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ JPanel buttonPanel = createButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ mListPanel.add(buttonPanel);
+
+ refresh();
+
+ return mListPanel;
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(new LabelCellRenderer(new JLabel()));
+ }
+
+
+ //set buttons
+ private void setButtons() {
+
+ //enable and diable buttons accordingly
+ //Debug.println("setButtons() - "+mTable.getSelectedRow());
+ //Debug.println("setButtons() - "+mTable.getSelectionModel().isSelectionEmpty());
+ if (mTable.getSelectionModel().isSelectionEmpty()) {
+ mDelete.setEnabled(false);
+ mView.setEnabled(false);
+ return;
+ }
+
+ if(mDataModel.getRowCount()<=0) {
+ mDelete.setEnabled(false);
+ mView.setEnabled(false);
+ return;
+ }
+
+ mDelete.setEnabled(true);
+ mView.setEnabled(true);
+
+ }
+
+ //=============================================
+ // SEND REQUESTS TO THE SERVER SIDE
+ //=============================================
+ private void update() {
+ //send request and parse data
+
+ mModel.progressStart();
+ NameValuePairs response;
+ try {
+ response = mConnection.search(mDestination,
+ ScopeDef.SC_MAPPER_IMPLS,
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+
+ Debug.println(response.toString());
+
+ //parse the data
+ int i=0;
+ String[] vals = new String[response.size()];
+ Hashtable<String, NameValuePairs> data = new Hashtable<String, NameValuePairs>();
+ for (String entry : response.keySet()) {
+ entry = entry.trim();
+ String value = response.get(entry);
+ int x = value.indexOf(",");
+ NameValuePairs obj = new NameValuePairs();
+ obj.put(IMPL_NAME, entry);
+ vals[i++]= entry ;
+ obj.put(IMPL_CLASS, value.substring(0, x));
+ obj.put(IMPL_DESC, value.substring(x + 1));
+ data.put(entry,obj);
+ }
+
+ CMSAdminUtil.bubbleSort(vals);
+
+ for (int y=0; y< vals.length ; y++) {
+ mDataModel.processData(data.get(vals[y]));
+ }
+
+ data.clear();
+
+ if (mDataModel.getRowCount() >0)
+ mTable.setRowSelectionInterval(0,0);
+
+ mModel.progressStop();
+ }
+
+ private void delete() {
+ //get entry name
+ mModel.progressStart();
+ NameValuePairs obj = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+
+ //send comment to server for the removal of user
+ try {
+ mConnection.delete(mDestination,
+ ScopeDef.SC_MAPPER_IMPLS,
+ obj.get(IMPL_NAME));
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+ mModel.progressStop();
+ //send comment to server and refetch the content
+ refresh();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/MapperInstanceTab.java b/base/console/src/com/netscape/admin/certsrv/config/MapperInstanceTab.java
new file mode 100644
index 000000000..a531ecf30
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/MapperInstanceTab.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Mapper Instances Management Tab
+ *
+ * @author Steve Parkinson
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class MapperInstanceTab extends CMSPluginInstanceTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PANEL_NAME = "MAPPERRULE";
+
+ private final static String RAHELPINDEX = "configuration-ra-mapperinstances-help";
+ private final static String CAHELPINDEX = "configuration-ca-mapperinstances-help";
+ private final static String KRAHELPINDEX = "configuration-kra-mapperinstances-help";
+
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public MapperInstanceTab(CMSBaseResourceModel model, String dest) {
+ super(model,dest,PANEL_NAME);
+ Debug.println("MapperInstanceTab::MapperInstanceTab(<model>,"+dest);
+ mConnection = model.getServerInfo().getAdmin();
+ mDataModel = new MapperRuleDataModel();
+ mScope = ScopeDef.SC_MAPPER_RULES;
+ RULE_NAME = MapperRuleDataModel.RULE_NAME;
+ RULE_STAT = MapperRuleDataModel.RULE_STAT;
+
+ if (mDestination.equals(DestDef.DEST_RA_MAPPER_ADMIN))
+ mHelpToken = RAHELPINDEX;
+ else
+ mHelpToken = CAHELPINDEX;
+ }
+
+
+ public CMSBaseConfigDialog makeNewConfigDialog(
+ NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest
+ )
+ {
+
+ return new MapperConfigDialog(nvp,
+ parent,
+ conn,
+ dest);
+ }
+
+ public PluginSelectionDialog getPluginSelectionDialog(
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType
+ )
+ {
+ return new MapperPluginSelectionDialog(parent,conn,dest,pluginType);
+ }
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/MapperPluginSelectionDialog.java b/base/console/src/com/netscape/admin/certsrv/config/MapperPluginSelectionDialog.java
new file mode 100644
index 000000000..ce0e10e9a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/MapperPluginSelectionDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Mapper Plugin Selection Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class MapperPluginSelectionDialog extends PluginSelectionDialog
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "MAPPERSELECTIONDIALOG";
+ private static final String CAHELPINDEX =
+ "configuration-ca-add-mapperrule-dbox-help";
+ private static final String RAHELPINDEX =
+ "configuration-ra-add-mapperrule-dbox-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public MapperPluginSelectionDialog(
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType)
+ {
+ super(PREFIX, parent,conn, dest, pluginType);
+ mScope = ScopeDef.SC_MAPPER_IMPLS;
+ mInstanceScope = ScopeDef.SC_MAPPER_RULES;
+ mImageName = CMSAdminResources.IMAGE_RULE_PLUGIN;
+ if (dest.equals(DestDef.DEST_RA_MAPPER_ADMIN))
+ mHelpToken = RAHELPINDEX;
+ else
+ mHelpToken = CAHELPINDEX;
+ setDisplay();
+ }
+
+ /*==========================================================
+ * EVENT HANDLER METHODS
+ *==========================================================*/
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/MapperRegisterDialog.java b/base/console/src/com/netscape/admin/certsrv/config/MapperRegisterDialog.java
new file mode 100644
index 000000000..3f6be3234
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/MapperRegisterDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+
+/**
+ * Mapper Implementation Registration Editor
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+
+public class MapperRegisterDialog extends RegisterDialog {
+
+ private final static String PREFIX = "MAPPERREGISTERDIALOG";
+
+ public MapperRegisterDialog(JFrame parent, AdminConnection conn) {
+ super(PREFIX, parent, conn);
+ setDisplay();
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/MapperRuleDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/MapperRuleDataModel.java
new file mode 100644
index 000000000..a72b59f7c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/MapperRuleDataModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.Debug;
+
+
+/**
+ * Mapper instance Data model - represents the instance
+ * table information
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class MapperRuleDataModel extends CMSRuleDataModel
+{
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public MapperRuleDataModel() {
+ super();
+ }
+
+ protected String[] getColumns() {
+ Debug.println("MapperRuleDataModel.getColumns()");
+ String x[] = {MAPPER_RULE, PLUGIN};
+ return x;
+ }
+
+ public void processData(Object data) {
+ Vector v = new Vector();
+ NameValuePairs obj = (NameValuePairs) data;
+
+ v.addElement(new JLabel(obj.get(RULE_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE),
+ JLabel.LEFT));
+ v.addElement(obj.get(RULE_IMPL));
+ addRow(v, data);
+ }
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/OCSPStoresConfigDialog.java b/base/console/src/com/netscape/admin/certsrv/config/OCSPStoresConfigDialog.java
new file mode 100644
index 000000000..87097ddc0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/OCSPStoresConfigDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import javax.swing.text.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * CRL Extensions Parameter Configuration Dialog
+ *
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class OCSPStoresConfigDialog extends CMSBaseConfigDialog
+ implements ActionListener
+{
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public OCSPStoresConfigDialog(NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest) {
+
+ super(parent, dest);
+ PREFIX = "OCSPSTORECONFIGDIALOG";
+ CAHELPINDEX = "configuration-ocsp-edit-crlextensionrule-dbox-help";
+
+ mImplName_token = Constants.PR_OCSPSTORE_IMPL_NAME;
+ mImplType = Constants.PR_EXT_PLUGIN_IMPLTYPE_OCSPSTORESRULE;
+
+ init(nvp,parent,conn,dest);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/OCSPStoresInstanceTab.java b/base/console/src/com/netscape/admin/certsrv/config/OCSPStoresInstanceTab.java
new file mode 100644
index 000000000..ff234c7fd
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/OCSPStoresInstanceTab.java
@@ -0,0 +1,132 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+
+import javax.swing.*;
+import java.awt.event.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+
+/**
+ * CRL Extensions - Instances Management Tab
+ *
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+
+public class OCSPStoresInstanceTab extends CMSPluginInstanceTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PANEL_NAME = "OCSPSTORESRULE";
+
+ private final static String OCSPHELPINDEX = "configuration-ocsp-storeinstances-help";
+
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public OCSPStoresInstanceTab(CMSBaseResourceModel model, String dest) {
+ super(model,dest,PANEL_NAME);
+ Debug.println("OCSPStoresInstanceTab::OCSPStoresInstanceTab(<model>,"+dest);
+ mConnection = model.getServerInfo().getAdmin();
+ mDataModel = new OCSPStoresRuleDataModel();
+ mScope = ScopeDef.SC_OCSPSTORES_RULES;
+ RULE_NAME = OCSPStoresRuleDataModel.RULE_NAME;
+ RULE_IMPL = OCSPStoresRuleDataModel.RULE_IMPL;
+ RULE_STAT = OCSPStoresRuleDataModel.RULE_STAT;
+ mHelpToken = OCSPHELPINDEX;
+ }
+
+
+ public CMSBaseConfigDialog makeNewConfigDialog(
+ NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest)
+ {
+ return new OCSPStoresConfigDialog(nvp, parent, conn, dest);
+ }
+
+ public PluginSelectionDialog getPluginSelectionDialog(
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType)
+ {
+ return new OCSPStoresPluginSelectionDialog(parent, conn, dest, pluginType);
+ }
+
+
+ /**
+ * create the user action button panel
+ */
+ protected JPanel createUserButtonPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mAdd = makeJButton("DEFAULT");
+ mDelete = makeJButton("DELETE");
+ mAdd.setEnabled(true);
+ mDelete.setEnabled(false);
+ mEdit = makeJButton("EDIT");
+ JButton[] buttons = {mAdd, mEdit};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mAdd)) {
+ setDefault();
+ } else {
+ super.actionPerformed(e);
+ }
+ }
+
+ private void setDefault() {
+
+ mModel.progressStart();
+ //get entry name
+ NameValuePairs data = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+ NameValuePairs nvps = new NameValuePairs();
+
+ //send comment to server for the removal of user
+ try {
+ mConnection.modify(DestDef.DEST_OCSP_ADMIN,
+ ScopeDef.SC_OCSPSTORE_DEFAULT,
+ data.get(RULE_NAME), nvps);
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+
+ mModel.progressStop();
+ //send comment to server and refetch the content
+ refresh();
+
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/OCSPStoresPluginSelectionDialog.java b/base/console/src/com/netscape/admin/certsrv/config/OCSPStoresPluginSelectionDialog.java
new file mode 100644
index 000000000..32365c27c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/OCSPStoresPluginSelectionDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * CRL Extensions Plugin Selection Dialog
+ *
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class OCSPStoresPluginSelectionDialog extends PluginSelectionDialog
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "OCSPSTORESELECTIONDIALOG";
+ private static final String OCSPHELPINDEX =
+ "configuration-ocsp-add-crlextensionrule-dbox-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public OCSPStoresPluginSelectionDialog(
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType)
+ {
+ super(PREFIX, parent,conn, dest, pluginType);
+// mScope = ScopeDef.SC_RULE_IMPLS;
+ mInstanceScope = ScopeDef.SC_OCSPSTORES_RULES;
+ mImageName = CMSAdminResources.IMAGE_RULE_PLUGIN;
+ mHelpToken = OCSPHELPINDEX;
+ setDisplay();
+ }
+
+ /*==========================================================
+ * EVENT HANDLER METHODS
+ *==========================================================*/
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/OCSPStoresRuleDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/OCSPStoresRuleDataModel.java
new file mode 100644
index 000000000..5cd67e276
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/OCSPStoresRuleDataModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.Debug;
+
+
+/**
+ * CRL Extensions instance Data model - represents the instance
+ * table information
+ *
+ * @version $Revision$, $Date$
+ */
+
+public class OCSPStoresRuleDataModel extends CMSRuleDataModel
+{
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public OCSPStoresRuleDataModel() {
+ super();
+ }
+
+ protected String[] getColumns() {
+ Debug.println("PolicyRuleDataModel.getColumns()");
+ String x[] = {OCSPSTORES_RULE, STATUS};
+ return x;
+ }
+
+ public void processData(Object data) {
+ Vector v = new Vector();
+ NameValuePairs obj = (NameValuePairs) data;
+
+ if (obj.get(RULE_STAT).equalsIgnoreCase("enabled")) {
+ v.addElement(new JLabel(obj.get(RULE_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE),
+ JLabel.LEFT));
+ v.addElement(mResource.getString("OCSPSTORESRULE_LABEL_ENABLED_LABEL"));
+ } else {
+ v.addElement(new JLabel(obj.get(RULE_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE_DISABLE),
+ JLabel.LEFT));
+ v.addElement(mResource.getString("OCSPSTORESRULE_LABEL_DISABLED_LABEL"));
+ }
+ addRow(v, data);
+ mRules.addElement(obj.get(RULE_NAME));
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/PanelMapperConfigDialog.java b/base/console/src/com/netscape/admin/certsrv/config/PanelMapperConfigDialog.java
new file mode 100644
index 000000000..5de06c7f9
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/PanelMapperConfigDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.table.*;
+import javax.swing.text.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * LDAP Mapper Parameter Configuration Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class PanelMapperConfigDialog extends JDialog
+ implements ActionListener, ItemListener
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private String PREFIX = "MAPPERCONFIGDIALOG";
+
+ private JFrame mParentFrame;
+ private ResourceBundle mResource;
+ protected ConfigTableModel mDataModel;
+ protected boolean mIsOK = false;
+ protected NameValuePairs mData;
+ private JScrollPane mScrollPane;
+ private JTable mTable;
+ private String mRuleName;
+ private String mDest;
+ private String mScope; //SC_USERCERT or SC_CACERT
+ private AdminConnection mConn;
+ private JButton mOK, mCancel, mHelp;
+ private JComboBox mSelection;
+
+ private static final String CAHELPINDEX =
+ "configuration-ldappublish-camapper-dbox-help";
+ private static final String RAHELPINDEX =
+ "configuration-ldappublish-ramapper-dbox-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public PanelMapperConfigDialog(JFrame parent, AdminConnection conn) {
+ super(parent,true);
+ mConn = conn;
+ mParentFrame = parent;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mDataModel = new ConfigTableModel();
+ setSize(360, 216);
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ setDisplay();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * show the windows
+ * @param users list of current groups
+ */
+ public void showDialog(String name, String destination, String scope) {
+ mIsOK = false;
+
+ mDataModel.removeAllRows();
+ mData = new NameValuePairs();
+ mRuleName = name;
+ mDest = destination;
+ mScope = scope;
+ Debug.println("MapperConfigDialog: showDialog() - mapper: "+
+ mRuleName+" dest: "+mDest+" scope: "+mScope);
+
+ if (!refresh(name))
+ return;
+
+ this.show();
+ }
+
+ public boolean isOK() {
+ return mIsOK;
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent evt) {
+
+ if (evt.getSource().equals(mOK)) {
+
+ //save any current edit component
+ Component component = mTable.getEditorComponent();
+ if (component!= null) {
+ int col = mTable.getEditingColumn();
+ int row = mTable.getEditingRow();
+ if ((col>-1)&&(row>-1)) {
+ String str = ((JTextComponent)component).getText();
+ mTable.setValueAt(str, row, col);
+ }
+ }
+
+ try {
+ saveConfiguration();
+ } catch (EAdminException e) {
+ //display error dialog
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+
+ mIsOK = true;
+ this.dispose();
+ }
+
+ if (evt.getSource().equals(mCancel)) {
+ this.dispose();
+ }
+ if (evt.getSource().equals(mHelp)) {
+ if (mDest.equals(DestDef.DEST_CA_ADMIN))
+ CMSAdminUtil.help(CAHELPINDEX);
+ else if (mDest.equals(DestDef.DEST_RA_ADMIN))
+ CMSAdminUtil.help(RAHELPINDEX);
+ }
+ }
+
+ //== ItemListener ==
+ public void itemStateChanged(ItemEvent e){
+ if (e.getSource().equals(mSelection)) {
+ if (e.getStateChange() == e.SELECTED) {
+ //take care of current editing
+ mTable.getColumnModel().getColumn(1).
+ getCellEditor().stopCellEditing();
+ Debug.println("Selected: "+ (String) mSelection.getSelectedItem());
+ setupConfigUI((String) mSelection.getSelectedItem());
+ }
+ }
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ private void saveEdit() {
+
+ //save any current edit component
+ Component component = mTable.getEditorComponent();
+
+ }
+
+ //setup and refresh the UI components
+ private boolean refresh(String mapperName) {
+
+ //get mapper listing
+ if (!getMapperListing(mapperName))
+ return false;
+
+ //setup UI
+ if (! setupConfigUI(mapperName))
+ return false;
+
+ return true;
+ }
+
+ //retrieve the mapper class listing and update
+ //the selection UI
+ private boolean getMapperListing(String mapperName) {
+ NameValuePairs response;
+
+ try {
+ response = getMapperList();
+ }catch (EAdminException e) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ return false;
+ }
+
+ Debug.println("MapperList: "+response.toString());
+ mSelection.removeAllItems();
+
+ for (String name : response.keySet()) {
+ mSelection.addItem(name.trim());
+ }
+
+ mSelection.setSelectedItem(mapperName);
+ return true;
+ }
+
+ //retrieve the config parameters for the mapper
+ //and update the config UI
+ private boolean setupConfigUI(String mapperName) {
+
+ try {
+ mData = getConfiguration(mapperName);
+ }catch (EAdminException e) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ return false;
+ }
+ Debug.println("MapperConfigDialog: showDialog() config: "+mData.toString());
+
+ mDataModel.removeAllRows();
+
+ for (String entry : mData.keySet()) {
+ entry = entry.trim();
+ if (!entry.equals(Constants.PR_MAPPER)) {
+ String value = mData.get(entry);
+ Vector<String> v = new Vector<String>();
+ v.addElement(entry);
+ v.addElement(value);
+ mDataModel.addRow(v);
+ }
+ }
+ mScrollPane.repaint();
+ mTable.repaint();
+ return true;
+ }
+
+ private void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ //create botton action panel
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null, this);
+ mCancel = CMSAdminUtil.makeJButton(mResource, PREFIX, "CANCEL", null, this);
+ mHelp = CMSAdminUtil.makeJButton(mResource, PREFIX, "HELP", null, this);
+ //JButton[] buttons = { mOK, mCancel, mHelp};
+ JButton[] buttons = { mOK, mCancel};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonPanel( buttons, true);
+ }
+
+ private JPanel makeContentPane() {
+ JPanel mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+ //content.setBorder(CMSAdminUtil.makeEtchedBorder());
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label3 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "IMPLNAME", null);
+ mSelection = new JComboBox();
+ mSelection.addItemListener(this);
+ addEntryField(mListPanel, label3, mSelection, gbc);
+
+ //left side certificate table
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ //mScrollPane.setBorder(CMSAdminUtil.makeTitledBorder(mResource,PANEL_NAME,"USERS"));
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
+ //mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ //setLabelCellRenderer(mTable,1);
+ setCellEditor(mTable,1);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(CMSAdminUtil.DIFFERENT_COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ 0,CMSAdminUtil.COMPONENT_SPACE);
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ return mListPanel;
+ }
+
+ //Set the index column's cellrender as label cell
+ private void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(
+ new DefaultTableCellRenderer());
+ }
+
+ //set the index column's cell editor
+ private void setCellEditor(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellEditor(
+ new DefaultCellEditor(new JTextField()));
+ }
+
+ //retrieve the mapper listing from the server side
+ private NameValuePairs getMapperList()
+ throws EAdminException
+ {
+ return mConn.search(mDest, getMapperScope(),
+ new NameValuePairs());
+ }
+
+ //retrieve the configuration parameters for specific
+ //mapper class
+ private NameValuePairs getConfiguration(String mapper)
+ throws EAdminException
+ {
+ return mConn.read(mDest, getMapperScope(),
+ mapper, new NameValuePairs());
+ }
+
+ //get the mapper scope
+ private String getMapperScope() {
+
+ if (mScope.equals(ScopeDef.SC_CACERT))
+ return ScopeDef.SC_CAMAPPER;
+ else
+ return ScopeDef.SC_USERMAPPER;
+ }
+
+ //save the configuration settings for the mapper
+ private void saveConfiguration() throws EAdminException {
+ NameValuePairs nvp = getData();
+ nvp.put(Constants.PR_MAPPER, (String) mSelection.getSelectedItem());
+ mConn.modify(mDest, mScope, Constants.RS_ID_CONFIG, nvp);
+ }
+
+ private NameValuePairs getData() {
+ NameValuePairs response = new NameValuePairs();
+ for (int i=0; i< mDataModel.getRowCount(); i++) {
+ response.put((String) mDataModel.getValueAt(i, 0),
+ (String) mDataModel.getValueAt(i, 1));
+ }
+ return response;
+ }
+
+ /**
+ * Add a label and a textfield to a panel, assumed to be using
+ * GridBagLayout.
+ */
+ private static void addEntryField(JPanel panel, JComponent label,
+ JComponent field, GridBagConstraints gbc) {
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.gridx = 0;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ panel.add( label, gbc );
+
+ gbc.gridx++;
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ 0,CMSAdminUtil.COMPONENT_SPACE);
+ panel.add( field, gbc );
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/PluginSelectionDialog.java b/base/console/src/com/netscape/admin/certsrv/config/PluginSelectionDialog.java
new file mode 100644
index 000000000..437881186
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/PluginSelectionDialog.java
@@ -0,0 +1,375 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Plugin Selection Dialog
+ *
+ * @author Jack Pan-chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class PluginSelectionDialog extends JDialog
+ implements ActionListener, MouseListener
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ protected JFrame mParentFrame;
+ protected AdminConnection mConnection;
+ protected ResourceBundle mResource;
+ protected DefaultListModel mDataModel;
+ protected String mDestination; //dest flag
+ protected String mExtraDestination = null; //dest flag
+
+ private JScrollPane mScrollPane;
+ protected JList mList;
+
+ protected JButton mOK, mCancel, mHelp;
+ protected String mPrefix;
+ protected String mScope;
+ protected String mInstanceScope;
+ protected String mImageName;
+ protected String mHelpToken;
+ protected CMSPluginInstanceTab mPluginInstanceDialog;
+ protected CMSBaseResourceModel mModel=null;
+
+ public PluginSelectionDialog(
+ String prefix,
+ JFrame parent,
+ AdminConnection conn,
+ String dest)
+ {
+ this( prefix,
+ parent,
+ conn,
+ dest,
+ null );
+ }
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public PluginSelectionDialog(
+ String prefix,
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType)
+ {
+ super(parent,true);
+ mParentFrame = parent;
+ mConnection = conn;
+ mDestination = dest;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mDataModel = new DefaultListModel();
+ mPrefix = prefix;
+ mPluginInstanceDialog = pluginType;
+
+ setTitle(mResource.getString(mPrefix+"_TITLE"));
+ setSize(360, 216);
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ }
+
+ public PluginSelectionDialog(
+ String prefix,
+ JFrame parent,
+ AdminConnection conn,
+ String dest, String extraDest,
+ CMSPluginInstanceTab pluginType)
+ {
+ super(parent,true);
+ mParentFrame = parent;
+ mConnection = conn;
+ mDestination = dest;
+ mExtraDestination = extraDest;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mDataModel = new DefaultListModel();
+ mPrefix = prefix;
+ mPluginInstanceDialog = pluginType;
+
+ setTitle(mResource.getString(mPrefix+"_TITLE"));
+ setSize(360, 216);
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ public void setModel(CMSBaseResourceModel model)
+ {
+ mModel = model;
+ }
+
+ /**
+ * show the windows
+ * @param users list of current groups
+ */
+ public void showDialog() {
+
+ mDataModel.clear();
+
+ if(!update())
+ return;
+ refresh();
+ setArrowButtons();
+ this.show();
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent evt) {
+
+ if (evt.getSource().equals(mOK)) {
+ NameValuePairs response;
+ try {
+ response = getDefaultConfig();
+ } catch (EAdminException e) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ Debug.println(response.toString());
+ String id = ((JLabel)mDataModel.elementAt(mList.getSelectedIndex())).getText();
+ response.put(Constants.PR_POLICY_IMPL_NAME, id);
+
+ CMSBaseConfigDialog dialog = null;
+ if (mExtraDestination == null) {
+ dialog = mPluginInstanceDialog.makeNewConfigDialog(
+ response, mParentFrame, mConnection, mDestination);
+ } else {
+ dialog = mPluginInstanceDialog.makeNewConfigDialog(
+ response, mParentFrame, mConnection, mExtraDestination);
+ }
+
+ dialog.setModel(mModel);
+ dialog.setInstanceScope(mInstanceScope);
+
+ dialog.showDialog(response,"");
+
+ if(!dialog.isOK()) {
+ this.dispose();
+ return;
+ }
+
+ response = dialog.getData();
+ String name = dialog.getRuleName();
+
+ Debug.println(response.toString());
+
+ dialog.dispose();
+ this.dispose();
+ }
+
+
+ if (evt.getSource().equals(mCancel)) {
+ this.dispose();
+ }
+ if (evt.getSource().equals(mHelp)) {
+ CMSAdminUtil.help(mHelpToken);
+ }
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setArrowButtons();
+ }
+
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {
+ setArrowButtons();
+ }
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {
+ setArrowButtons();
+ }
+
+ protected void setDisplay() {
+ Debug.println("*** PluginSelectionDialog.setDisplay() - 1");
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ //create botton action panel
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, mPrefix, "OK", null, this);
+ mCancel = CMSAdminUtil.makeJButton(mResource, mPrefix, "CANCEL", null, this);
+ mHelp = CMSAdminUtil.makeJButton(mResource, mPrefix, "HELP", null, this);
+ //JButton[] buttons = { mOK, mCancel, mHelp};
+ JButton[] buttons = { mOK, mCancel};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonPanel( buttons, true);
+ }
+
+ private JPanel makeContentPane() {
+ Debug.println("*** PluginSelectionDialog.makeContentPane() - 0");
+ JPanel mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ Debug.println("*** PluginSelectionDialog.makeContentPane() - 1");
+ mListPanel.setLayout(gb);
+ //content.setBorder(CMSAdminUtil.makeEtchedBorder());
+
+ Debug.println("*** PluginSelectionDialog.makeContentPane() - 2");
+ //left side certificate table
+ mList = CMSAdminUtil.makeJList(mDataModel,9);
+ Debug.println("PluginSelectionDialog.makeContentPane() - making mList("+mList+")");
+ mScrollPane = new JScrollPane(mList,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION );
+ mList.addMouseListener(this);
+ mScrollPane.setBackground(Color.white);
+ mScrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ return mListPanel;
+ }
+
+
+ //set arrow buttons
+ private void setArrowButtons() {
+
+ //enable and diable buttons accordingly
+ //Debug.println("setArrowButtons() - "+mList.getSelectedIndex());
+
+ if (mList.getSelectedIndex()< 0) {
+ mOK.setEnabled(false);
+ return;
+ }
+
+ mOK.setEnabled(true);
+ }
+
+ //refresh the table content
+ private void refresh() {
+ //mScrollPane.invalidate();
+ //mScrollPane.validate();
+ //repaint();
+ }
+
+ //=================================================
+ // RETRIEVE INFO FROM SERVER SIDE
+ //=================================================
+
+ //save order information to the server
+ protected boolean update() {
+
+ NameValuePairs response;
+ try {
+ response = mConnection.search(mDestination, mScope,
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ return false;
+ }
+
+ Debug.println(response.toString());
+
+ //parse the data
+ String[] vals = new String[response.size()];
+ int i=0;
+ for (String name : response.keySet()) {
+ vals[i++] = name.trim();
+ Debug.println("PluginSelectionDialog::update() - adding '" + vals[i - 1] + "'");
+ }
+
+ CMSAdminUtil.bubbleSort(vals);
+
+ for (int y=0; y< vals.length ; y++) {
+ try {
+ mDataModel.addElement(new JLabel(vals[y],
+ CMSAdminUtil.getImage(mImageName), JLabel.LEFT));
+ }
+ catch (Exception ex) {
+ Debug.println("PluginSelectionDialog could not get image for '"+
+ mImageName+"'. Adding without image");
+ mDataModel.addElement(new JLabel(vals[y],
+ JLabel.LEFT));
+ }
+ }
+
+ return true;
+ }
+
+ //this returns the default configuration
+ protected NameValuePairs getDefaultConfig() throws EAdminException {
+ String id = ((JLabel)mDataModel.elementAt(mList.getSelectedIndex())).getText();
+ NameValuePairs response;
+ response = mConnection.read(mDestination, mScope, id,
+ new NameValuePairs());
+
+ Debug.println(response.toString());
+
+ return response;
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/PolicyConfigDialog.java b/base/console/src/com/netscape/admin/certsrv/config/PolicyConfigDialog.java
new file mode 100644
index 000000000..8dec3cabf
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/PolicyConfigDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import javax.swing.text.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Policy Parameter Configuration Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class PolicyConfigDialog extends CMSBaseConfigDialog
+ implements ActionListener
+{
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public PolicyConfigDialog(NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest) {
+
+ super(parent, dest);
+
+ PREFIX = "POLICYCONFIGDIALOG";
+ RAHELPINDEX = "configuration-ra-edit-policyrule-dbox-help";
+ KRAHELPINDEX = "configuration-kra-edit-policyrule-dbox-help";
+ CAHELPINDEX = "configuration-ca-edit-policyrule-dbox-help";
+ mImplName_token = Constants.PR_POLICY_IMPL_NAME;
+ mImplType = Constants.PR_EXT_PLUGIN_IMPLTYPE_POLICY;
+
+ init(nvp,parent,conn,dest);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/PolicyImplDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/PolicyImplDataModel.java
new file mode 100644
index 000000000..59ea36ec8
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/PolicyImplDataModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Policy Implementation Data model - represents the implementation
+ * table information
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class PolicyImplDataModel extends CMSContentTableModel
+ implements IDataProcessor
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String IMPL_NAME = "NAME";
+ public static final String IMPL_CLASS = "CLASS";
+ public static final String IMPL_DESC = "DESC";
+
+ private static String[] mColumns = {POLICY_IMPL, CLASSNAME};
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public PolicyImplDataModel() {
+ super();
+ init(mColumns);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void processData(Object data) {
+ Vector v = new Vector();
+ NameValuePairs obj = (NameValuePairs) data;
+ v.addElement(new JLabel(obj.get(IMPL_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE_PLUGIN),
+ JLabel.LEFT));
+ v.addElement(obj.get(IMPL_CLASS));
+ //v.addElement(obj.getValue(IMPL_DESC));
+ addRow(v, data);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/PolicyImplTab.java b/base/console/src/com/netscape/admin/certsrv/config/PolicyImplTab.java
new file mode 100644
index 000000000..f4fab7260
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/PolicyImplTab.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Policy Instances Management Tab
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class PolicyImplTab extends CMSBaseUGTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String IMPL_NAME = PolicyImplDataModel.IMPL_NAME;
+ private static final String IMPL_CLASS = PolicyImplDataModel.IMPL_CLASS;
+ private static final String IMPL_DESC = PolicyImplDataModel.IMPL_DESC;
+
+ private static final String PANEL_NAME = "POLICYIMPL";
+ private static final String DIALOG_PREFIX = "POLICYREGISTERDIALOG";
+
+ private AdminConnection mConnection;
+ private String mDestination;
+
+ protected JScrollPane mScrollPane;
+ protected JTable mTable; //table
+ protected PolicyImplDataModel mDataModel; //table model
+ protected PolicyRegisterDialog mEditor=null; //keep single copy
+ protected ViewDialog mViewer=null; //keep single copy
+
+ protected JButton mRefresh, mAdd, mDelete, mView, mHelp;
+ private final static String RAHELPINDEX = "configuration-ra-policyplugin-help";
+ private final static String CAHELPINDEX = "configuration-ca-policyplugin-help";
+ private final static String KRAHELPINDEX = "configuration-kra-policyplugin-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public PolicyImplTab(CMSBaseResourceModel model, String destination) {
+ super(PANEL_NAME, model);
+ mConnection = model.getServerInfo().getAdmin();
+ mDataModel = new PolicyImplDataModel();
+ mDestination = destination;
+ if (mDestination.equals(DestDef.DEST_RA_POLICY_ADMIN))
+ mHelpToken = RAHELPINDEX;
+ else if (mDestination.equals(DestDef.DEST_KRA_POLICY_ADMIN))
+ mHelpToken = KRAHELPINDEX;
+ else
+ mHelpToken = CAHELPINDEX;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mRefresh)) {
+ refresh();
+ }
+ if (e.getSource().equals(mAdd)) {
+ if (mEditor==null)
+ mEditor = new PolicyRegisterDialog(mModel.getFrame(),
+ mConnection);
+ mEditor.showDialog(mDestination, ScopeDef.SC_POLICY_IMPLS);
+ refresh();
+ }
+ if (e.getSource().equals(mDelete)) {
+ Debug.println("Delete");
+ if(mTable.getSelectedRow()< 0)
+ return;
+ int i = showConfirmDialog("DELETE");
+ if (i == JOptionPane.YES_OPTION) {
+ delete();
+ Debug.println("Deleted");
+ }
+ }
+ if (e.getSource().equals(mView)) {
+ Debug.println("View");
+ if(mTable.getSelectedRow()< 0)
+ return;
+ NameValuePairs obj = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+ if (mViewer==null)
+ mViewer = new ViewDialog(mModel.getFrame());
+ mViewer.showDialog(obj.get(IMPL_NAME),
+ obj.get(IMPL_CLASS),
+ obj.get(IMPL_DESC));
+ }
+ if (e.getSource().equals(mHelp)) {
+ helpCallback();
+ }
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+ public void refresh() {
+
+ mDataModel.removeAllRows();
+ update();
+
+ setButtons();
+ mTable.invalidate();
+ mTable.validate();
+ mTable.repaint(1);
+ }
+
+ /**
+ * create the user action button panel
+ */
+ protected JPanel createButtonPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mAdd = makeJButton("ADD");
+ mDelete = makeJButton("DELETE");
+ mView = makeJButton("VIEW");
+ JButton[] buttons = {mAdd, mDelete, mView};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ protected JPanel createActionPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mRefresh = makeJButton("REFRESH");
+ mHelp = makeJButton("HELP");
+ //JButton[] buttons = { mRefresh, mHelp };
+ JButton[] buttons = { mRefresh };
+ return makeJButtonPanel(buttons, true);
+ }
+
+ protected JPanel createListPanel() {
+ mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ //center table
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ //mScrollPane.setBorder(CMSAdminUtil.makeTitledBorder(mResource,PANEL_NAME,"USERS"));
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ mTable.addMouseListener(this);
+ setLabelCellRenderer(mTable,0);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = 1;
+ gbc.weightx = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ JPanel buttonPanel = createButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ mListPanel.add(buttonPanel);
+
+ refresh();
+
+ return mListPanel;
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(new LabelCellRenderer(new JLabel()));
+ }
+
+
+ //set buttons
+ private void setButtons() {
+
+ //enable and diable buttons accordingly
+ //Debug.println("setButtons() - "+mTable.getSelectedRow());
+ //Debug.println("setButtons() - "+mTable.getSelectionModel().isSelectionEmpty());
+ if (mTable.getSelectionModel().isSelectionEmpty()) {
+ mDelete.setEnabled(false);
+ mView.setEnabled(false);
+ return;
+ }
+
+ if(mDataModel.getRowCount()<=0) {
+ mDelete.setEnabled(false);
+ mView.setEnabled(false);
+ return;
+ }
+
+ mDelete.setEnabled(true);
+ mView.setEnabled(true);
+
+ }
+
+ //=============================================
+ // SEND REQUESTS TO THE SERVER SIDE
+ //=============================================
+ private void update() {
+ //send request and parse data
+
+ mModel.progressStart();
+ NameValuePairs response;
+ try {
+ response = mConnection.search(mDestination,
+ ScopeDef.SC_POLICY_IMPLS,
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+
+ Debug.println(response.toString());
+
+ //parse the data
+ int i=0;
+ String[] vals = new String[response.size()];
+ Hashtable<String, NameValuePairs> data = new Hashtable<String, NameValuePairs>();
+ for (String entry : response.keySet()) {
+ entry = entry.trim();
+ String value = response.get(entry);
+ int x = value.indexOf(",");
+ NameValuePairs obj = new NameValuePairs();
+ obj.put(IMPL_NAME, entry);
+ vals[i++]= entry ;
+ obj.put(IMPL_CLASS, value.substring(0, x));
+ obj.put(IMPL_DESC, value.substring(x + 1));
+ data.put(entry,obj);
+ }
+
+ CMSAdminUtil.bubbleSort(vals);
+
+ for (int y=0; y< vals.length ; y++) {
+ mDataModel.processData(data.get(vals[y]));
+ }
+
+ data.clear();
+
+ if (mDataModel.getRowCount() >0)
+ mTable.setRowSelectionInterval(0,0);
+
+ mModel.progressStop();
+ }
+
+ private void delete() {
+ //get entry name
+ mModel.progressStart();
+ NameValuePairs obj = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+
+ //send comment to server for the removal of user
+ try {
+ mConnection.delete(mDestination,
+ ScopeDef.SC_POLICY_IMPLS,
+ obj.get(IMPL_NAME));
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+ mModel.progressStop();
+ //send comment to server and refetch the content
+ refresh();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/PolicyInstanceTab.java b/base/console/src/com/netscape/admin/certsrv/config/PolicyInstanceTab.java
new file mode 100644
index 000000000..9bf8fb54b
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/PolicyInstanceTab.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Policy Instances Management Tab
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class PolicyInstanceTab extends CMSPluginInstanceTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PANEL_NAME = "POLICYRULE";
+
+ protected JButton mOrder;
+ private final static String RAHELPINDEX = "configuration-ra-policyrules-help";
+ private final static String CAHELPINDEX = "configuration-ca-policyrules-help";
+ private final static String KRAHELPINDEX = "configuration-kra-policyrules-help";
+
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public PolicyInstanceTab(CMSBaseResourceModel model, String dest) {
+ super(model,dest,PANEL_NAME);
+ Debug.println("PolicyInstanceTab::PolicyInstanceTab(<model>,"+dest);
+ mConnection = model.getServerInfo().getAdmin();
+ mDataModel = new PolicyRuleDataModel();
+ mScope = ScopeDef.SC_POLICY_RULES;
+ RULE_NAME = PolicyRuleDataModel.RULE_NAME;
+ RULE_STAT = PolicyRuleDataModel.RULE_STAT;
+
+ if (mDestination.equals(DestDef.DEST_RA_POLICY_ADMIN))
+ mHelpToken = RAHELPINDEX;
+ else if (mDestination.equals(DestDef.DEST_KRA_POLICY_ADMIN))
+ mHelpToken = KRAHELPINDEX;
+ else
+ mHelpToken = CAHELPINDEX;
+ }
+
+
+ public CMSBaseConfigDialog makeNewConfigDialog(
+ NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest
+ )
+ {
+
+ return new PolicyConfigDialog(nvp,
+ parent,
+ conn,
+ dest);
+ }
+
+ public PluginSelectionDialog getPluginSelectionDialog(
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType
+ )
+ {
+ return new PolicyPluginSelectionDialog(parent,conn,dest,pluginType);
+ }
+
+
+ //=== ACTIONLISTENER =====================
+ public void moreActionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mOrder)) {
+ Debug.println("Order");
+ PolicyRuleOrderDialog dialog =
+ new PolicyRuleOrderDialog(mModel.getFrame(),
+ mConnection, mDestination);
+ dialog.showDialog(mDataModel.getRules());
+ refresh();
+ }
+ }
+
+ /**
+ * create the user action button panel
+ */
+ protected JPanel createUserButtonPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mOrder = makeJButton("ORDER");
+ mEdit = makeJButton("EDIT");
+ mAdd = makeJButton("ADD");
+ mDelete = makeJButton("DELETE");
+ JButton[] buttons = {mAdd, mDelete, mEdit, mOrder};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+
+ //set buttons
+ protected void setButtons() {
+ super.setButtons();
+
+ if (mDataModel.getRowCount()<=0) {
+ mOrder.setEnabled(false);
+ }
+ else {
+ mOrder.setEnabled(true);
+ }
+ }
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/PolicyPluginSelectionDialog.java b/base/console/src/com/netscape/admin/certsrv/config/PolicyPluginSelectionDialog.java
new file mode 100644
index 000000000..6ef26b767
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/PolicyPluginSelectionDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Policy Plugin Selection Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class PolicyPluginSelectionDialog extends PluginSelectionDialog
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "POLICYSELECTIONDIALOG";
+ private static final String CAHELPINDEX =
+ "configuration-ca-add-policyrule-dbox-help";
+ private static final String RAHELPINDEX =
+ "configuration-ra-add-policyrule-dbox-help";
+ private static final String KRAHELPINDEX =
+ "configuration-kra-add-policyrule-dbox-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public PolicyPluginSelectionDialog(
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType)
+ {
+ super(PREFIX, parent,conn, dest, pluginType);
+ mScope = ScopeDef.SC_POLICY_IMPLS;
+ mInstanceScope = ScopeDef.SC_POLICY_RULES;
+ mImageName = CMSAdminResources.IMAGE_RULE_PLUGIN;
+ if (dest.equals(DestDef.DEST_RA_POLICY_ADMIN))
+ mHelpToken = RAHELPINDEX;
+ else if (dest.equals(DestDef.DEST_KRA_POLICY_ADMIN))
+ mHelpToken = KRAHELPINDEX;
+ else
+ mHelpToken = CAHELPINDEX;
+ setDisplay();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/PolicyRegisterDialog.java b/base/console/src/com/netscape/admin/certsrv/config/PolicyRegisterDialog.java
new file mode 100644
index 000000000..cbc961c5b
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/PolicyRegisterDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+
+/**
+ * Policy Implementation Registration Editor
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+
+public class PolicyRegisterDialog extends RegisterDialog {
+
+ private final static String PREFIX = "POLICYREGISTERDIALOG";
+
+ public PolicyRegisterDialog(JFrame parent, AdminConnection conn) {
+ super(PREFIX, parent, conn);
+ setDisplay();
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/PolicyRuleDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/PolicyRuleDataModel.java
new file mode 100644
index 000000000..9bbeda334
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/PolicyRuleDataModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.Debug;
+
+
+/**
+ * Policy instance Data model - represents the instance
+ * table information
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class PolicyRuleDataModel extends CMSRuleDataModel
+{
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public PolicyRuleDataModel() {
+ super();
+ }
+
+ protected String[] getColumns() {
+ Debug.println("PolicyRuleDataModel.getColumns()");
+ String x[] = {POLICY_RULE, STATUS};
+ return x;
+ }
+
+ public void processData(Object data) {
+ Vector v = new Vector();
+ NameValuePairs obj = (NameValuePairs) data;
+
+ //XXX NEED TO ADD STUFF
+ if (obj.get(RULE_STAT).equalsIgnoreCase("enabled")) {
+ v.addElement(new JLabel(obj.get(RULE_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE),
+ JLabel.LEFT));
+ v.addElement(mResource.getString("POLICYRULE_LABEL_ENABLED_LABEL"));
+ } else {
+ v.addElement(new JLabel(obj.get(RULE_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE_DISABLE),
+ JLabel.LEFT));
+ v.addElement(mResource.getString("POLICYRULE_LABEL_DISABLED_LABEL"));
+ }
+ addRow(v, data);
+ mRules.addElement(obj.get(RULE_NAME));
+ }
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/PolicyRuleOrderDialog.java b/base/console/src/com/netscape/admin/certsrv/config/PolicyRuleOrderDialog.java
new file mode 100644
index 000000000..1c99d999f
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/PolicyRuleOrderDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Policy Rule Order Dialog - <p>
+ *
+ * The administrator can use this dialog to reconfig the ordering
+ * of the existing policy rules.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class PolicyRuleOrderDialog extends JDialog
+ implements ActionListener, MouseListener
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private String PREFIX = "POLICYORDERDIALOG";
+
+ private JFrame mParentFrame;
+ private AdminConnection mConnection;
+ private ResourceBundle mResource;
+ protected DefaultListModel mDataModel;
+ protected String mDestination; //dest flag
+
+ private JScrollPane mScrollPane;
+ private JList mList;
+
+ private JButton mOK, mCancel, mUp, mDown, mHelp;
+ private final static String RAHELPINDEX =
+ "configuration-ra-reorder-policyrule-dbox-help";
+ private final static String KRAHELPINDEX =
+ "configuration-kra-reorder-policyrule-dbox-help";
+ private final static String CAHELPINDEX =
+ "configuration-ca-reorder-policyrule-dbox-help";
+ private String mHelpToken;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public PolicyRuleOrderDialog(JFrame parent, AdminConnection conn, String dest) {
+ super(parent,true);
+ mParentFrame = parent;
+ mConnection = conn;
+ mDestination = dest;
+ if (mDestination.equals(DestDef.DEST_RA_POLICY_ADMIN))
+ mHelpToken = RAHELPINDEX;
+ else if (mDestination.equals(DestDef.DEST_KRA_POLICY_ADMIN))
+ mHelpToken = KRAHELPINDEX;
+ else
+ mHelpToken = CAHELPINDEX;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mDataModel = new DefaultListModel();
+ setSize(360, 216);
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ setDisplay();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * show the windows
+ * @param users list of current groups
+ */
+ public void showDialog(Vector rules) {
+
+ mDataModel.clear();
+ for (int i=0; i<rules.size(); i++)
+ mDataModel.addElement(
+ new JLabel((String)rules.elementAt(i),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE),
+ JLabel.LEFT));
+ if (mDataModel.getSize() >0)
+ mList.setSelectedIndex(0);
+
+ refresh();
+ setArrowButtons();
+ this.show();
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent evt) {
+
+ if (evt.getSource().equals(mOK)) {
+ try {
+ saveOrder();
+ } catch (EAdminException e) {
+ //display error dialog
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ this.dispose();
+ }
+ if (evt.getSource().equals(mCancel)) {
+ this.dispose();
+ }
+ if (evt.getSource().equals(mUp)) {
+ int index = mList.getSelectedIndex();
+ Object obj = mDataModel.elementAt(index);
+ mDataModel.removeElementAt(index);
+ mDataModel.insertElementAt(obj,index-1);
+ mList.setSelectedIndex(index-1);
+ setArrowButtons();
+ refresh();
+ }
+ if (evt.getSource().equals(mDown)) {
+ int index = mList.getSelectedIndex();
+ Object obj = mDataModel.elementAt(index);
+ mDataModel.removeElementAt(index);
+ mDataModel.insertElementAt(obj,index+1);
+ mList.setSelectedIndex(index+1);
+ setArrowButtons();
+ refresh();
+ }
+ if (evt.getSource().equals(mHelp)) {
+ CMSAdminUtil.help(mHelpToken);
+ }
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setArrowButtons();
+ }
+
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {
+ setArrowButtons();
+ }
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {
+ setArrowButtons();
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+ private void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ /**
+ * create the bottom action button panel
+ */
+ protected JPanel createUDButtonPanel() {
+ //up, down buttons required
+ //actionlister to this object
+ mUp = CMSAdminUtil.makeJButton(mResource, PREFIX, "UP", null, this);
+ mDown = CMSAdminUtil.makeJButton(mResource, PREFIX, "DOWN", null, this);
+ JButton[] buttons = { mUp, mDown};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ //create botton action panel
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null, this);
+ mCancel = CMSAdminUtil.makeJButton(mResource, PREFIX, "CANCEL", null, this);
+ mHelp = CMSAdminUtil.makeJButton(mResource, PREFIX, "HELP", null, this);
+ //JButton[] buttons = { mOK, mCancel, mHelp};
+ JButton[] buttons = { mOK, mCancel};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonPanel( buttons, true);
+ }
+
+ private JPanel makeContentPane() {
+ JPanel mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+ //content.setBorder(CMSAdminUtil.makeEtchedBorder());
+
+ //left side certificate table
+ mList = CMSAdminUtil.makeJList(mDataModel,10);
+ mScrollPane = new JScrollPane(mList,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION );
+ mList.addMouseListener(this);
+ mScrollPane.setBackground(Color.white);
+ mScrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = 1;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,CMSAdminUtil.COMPONENT_SPACE,0,0);
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ JPanel buttonPanel = createUDButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,0,0,0);
+ gb.setConstraints(buttonPanel, gbc);
+ mListPanel.add(buttonPanel);
+
+ return mListPanel;
+ }
+
+ //=================================================
+ // RETRIEVE INFO FROM SERVER SIDE
+ //=================================================
+
+ //save order information to the server
+ private void saveOrder() throws EAdminException {
+ StringBuffer buf = new StringBuffer();
+
+ int x = 0;
+ for(int i=0; i<mDataModel.size(); i++) {
+ if (x > 0)
+ buf.append(",");
+ x++;
+ buf.append(((JLabel)mDataModel.getElementAt(i)).getText());
+ }
+
+ NameValuePairs nvp = new NameValuePairs();
+ nvp.put(Constants.PR_POLICY_ORDER, buf.toString());
+
+ Debug.println("ORDER: "+buf.toString());
+
+ mConnection.modify(mDestination,
+ ScopeDef.SC_POLICY_RULES,
+ Constants.RS_ID_ORDER,
+ nvp);
+ }
+
+ //set arrow buttons
+ private void setArrowButtons() {
+
+ //enable and diable buttons accordingly
+ Debug.println("setArrowButtons() - "+mList.getSelectedIndex());
+ if (mList.getSelectedIndex()< 0) {
+ mUp.setEnabled(false);
+ mDown.setEnabled(false);
+ mOK.setEnabled(false);
+ return;
+ }
+
+ if (mList.getSelectedIndex()==0)
+ mUp.setEnabled(false);
+ else
+ mUp.setEnabled(true);
+ if (mList.getSelectedIndex()< mDataModel.getSize()-1)
+ mDown.setEnabled(true);
+ else
+ mDown.setEnabled(false);
+ mOK.setEnabled(true);
+ }
+
+ //refresh the table content
+ private void refresh() {
+ //mTable.invalidate();
+ //mTable.validate();
+ //mTable.repaint(1);
+ mScrollPane.invalidate();
+ mScrollPane.validate();
+ //mScrollPane.repaint(1);
+ repaint();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ProfileComponentCellEditor.java b/base/console/src/com/netscape/admin/certsrv/config/ProfileComponentCellEditor.java
new file mode 100644
index 000000000..b1e2769db
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ProfileComponentCellEditor.java
@@ -0,0 +1,109 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import java.awt.Component;
+import java.awt.event.*;
+import java.awt.AWTEvent;
+import java.lang.Boolean;
+import javax.swing.table.*;
+import javax.swing.event.*;
+import java.util.EventObject;
+import javax.swing.tree.*;
+import java.io.Serializable;
+import javax.swing.*;
+
+public class ProfileComponentCellEditor implements TableCellEditor {
+ protected EventListenerList listenerList = new EventListenerList();
+ protected ChangeEvent changeEvent = null;
+
+ protected JComponent editorComponent = null;
+ protected JComponent container = null; // Can be tree or table
+
+ public Component getComponent() {
+ return editorComponent;
+ }
+
+ public Object getCellEditorValue() {
+ return editorComponent;
+ }
+
+ public boolean isCellEditable(EventObject anEvent) {
+ return true;
+ }
+
+ public boolean shouldSelectCell(EventObject anEvent) {
+ return true;
+ }
+
+ public boolean stopCellEditing() {
+ fireEditingStopped();
+ return true;
+ }
+
+ public void cancelCellEditing() {
+ fireEditingCanceled();
+ }
+
+ public void addCellEditorListener(CellEditorListener l) {
+ listenerList.add(CellEditorListener.class, l);
+ }
+
+ public void removeCellEditorListener(CellEditorListener l) {
+ listenerList.remove(CellEditorListener.class, l);
+ }
+
+ protected void fireEditingStopped() {
+ Object[] listeners = listenerList.getListenerList();
+ // Process the listeners last to first, notifying
+ // those that are interested in this event
+ for (int i = listeners.length-2; i>=0; i-=2) {
+ if (listeners[i]==CellEditorListener.class) {
+ // Lazily create the event:
+ if (changeEvent == null)
+ changeEvent = new ChangeEvent(this);
+ ((CellEditorListener)listeners[i+1]).editingStopped(changeEvent);
+ }
+ }
+ }
+
+ protected void fireEditingCanceled() {
+ // Guaranteed to return a non-null array
+ Object[] listeners = listenerList.getListenerList();
+ // Process the listeners last to first, notifying
+ // those that are interested in this event
+ for (int i = listeners.length-2; i>=0; i-=2) {
+ if (listeners[i]==CellEditorListener.class) {
+ // Lazily create the event:
+ if (changeEvent == null)
+ changeEvent = new ChangeEvent(this);
+ ((CellEditorListener)listeners[i+1]).editingCanceled(changeEvent);
+ }
+ }
+ }
+
+ // implements javax.swing.table.TableCellEditor
+ public Component getTableCellEditorComponent(JTable table, Object value,
+ boolean isSelected, int row, int column) {
+
+ editorComponent = (JComponent)value;
+ container = table;
+ return editorComponent;
+ }
+} // End of class JComponentCellEditor
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ProfileConfigDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/ProfileConfigDataModel.java
new file mode 100644
index 000000000..af20b4e99
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ProfileConfigDataModel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import javax.swing.text.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Policy Parameter Configuration Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ProfileConfigDataModel extends AbstractTableModel
+{
+ Vector rowData;
+ Vector columnNames;
+
+ public ProfileConfigDataModel()
+ {
+ }
+
+ 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);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ProfileConfigDialog.java b/base/console/src/com/netscape/admin/certsrv/config/ProfileConfigDialog.java
new file mode 100644
index 000000000..a8d312d2a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ProfileConfigDialog.java
@@ -0,0 +1,396 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Policy Parameter Configuration Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ProfileConfigDialog extends CMSBaseConfigDialog
+ implements ActionListener
+{
+ protected JButton mRefresh, mEdit, mAdd, mDelete, mOrder, mHelp;
+ protected JTextField mAuthField=null,mNameField=null, mDescField=null, mConfigField=null;
+ protected JComboBox mVisibleField = null;
+ protected JLabel mVisibleLabel=null,mAuthLabel=null,mNameLabel=null, mDescLabel = null, mConfigLabel =null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public ProfileConfigDialog(NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest) {
+
+ super(parent, dest);
+
+ PREFIX = "PROFILECONFIGDIALOG";
+ mHelpToken = "configuration-certificateprofiles";
+ mImplName_token = Constants.PR_POLICY_IMPL_NAME;
+ mImplType = Constants.PR_EXT_PLUGIN_IMPLTYPE_POLICY;
+ init(nvp,parent,conn,dest);
+ }
+
+
+ protected JPanel makeContentPane() {
+ JPanel mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ // 'Policy Rule ID' here
+ CMSAdminUtil.resetGBC(gbc);
+ mRulenameCaption = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "RULENAME", null);
+ mRulenameCaption.addMouseListener(this);
+ mPluginLabel = new JLabel();
+ mPluginLabel.setVisible(false);
+ mPluginName = new JTextField();
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add(mRulenameCaption, gbc);
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ 0,CMSAdminUtil.COMPONENT_SPACE);
+ mListPanel.add( mPluginName, gbc );
+ mListPanel.add( mPluginLabel, gbc );
+
+ // name
+ CMSAdminUtil.resetGBC(gbc);
+ mNameLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "NAMENAME", null);
+ mNameLabel.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add( mNameLabel, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mNameField = new JTextField();
+ mListPanel.add( mNameField, gbc );
+
+ // desc
+ CMSAdminUtil.resetGBC(gbc);
+ mDescLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "DESCNAME", null);
+ mDescLabel.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add( mDescLabel, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mDescField = new JTextField();
+ mListPanel.add( mDescField, gbc );
+
+ // visible
+ CMSAdminUtil.resetGBC(gbc);
+ mVisibleLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "VISIBLENAME", null);
+ mVisibleLabel.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add( mVisibleLabel, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ String[] item = {"true", "false"};
+ mVisibleField = new JComboBox(item);
+ mListPanel.add( mVisibleField, gbc );
+
+ // authentication
+ CMSAdminUtil.resetGBC(gbc);
+ mAuthLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "AUTHNAME", null);
+ mAuthLabel.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add( mAuthLabel, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mAuthField = new JTextField();
+ mListPanel.add( mAuthField, gbc );
+
+ // config file
+/*
+ CMSAdminUtil.resetGBC(gbc);
+ mConfigLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "CONFIGNAME", null);
+ mConfigLabel.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add( mConfigLabel, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mConfigField = new JTextField();
+ mListPanel.add( mConfigField, gbc );
+*/
+
+
+ // 'Policy Plugin ID' here
+ CMSAdminUtil.resetGBC(gbc);
+ mImplnameCaption = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "IMPLNAME", null);
+ mImplnameCaption.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add( mImplnameCaption, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mImplName = new JLabel();
+ mListPanel.add( mImplName, gbc );
+
+ /* Tab */
+/*
+ JTabbedPane tabPane = new JTabbedPane();
+ JPanel lpanel = createListPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.BOTH;
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ tabPane.addTab("Policies", lpanel);
+ gb.setConstraints(tabPane, gbc);
+ mListPanel.add(tabPane);
+*/
+
+ /* Panel for list of plugin's parameters */
+ mParamPanel = new JPanel();
+/*
+ mScrollPane = new JScrollPane(mParamPanel);
+ mScrollPane.setBorder(CMSAdminUtil.makeEtchedBorder());
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.BOTH;
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+*/
+
+ /* Panel in which to put plugin's help text */
+ mHelpPanel = new JPanel();
+ mHelpPanel.setBorder(CMSAdminUtil.makeEtchedBorder());
+ mHelpLabel = new JTextArea(3,0);
+ mHelpLabel.setLineWrap(true);
+ mHelpLabel.setWrapStyleWord(true);
+ mHelpLabel.setBackground(mHelpPanel.getBackground());
+ mHelpLabel.setEditable(false);
+ GridBagLayout gb2 = new GridBagLayout();
+ GridBagConstraints gbc2 = new GridBagConstraints();
+
+ CMSAdminUtil.resetGBC(gbc2);
+ gbc2.fill = gbc.BOTH;
+ gbc2.anchor = gbc.WEST;
+ gbc2.gridwidth = gbc.REMAINDER;
+ gbc2.weightx = 1.0;
+ gbc2.weighty = 1.0;
+ gb2.setConstraints(mHelpLabel, gbc2);
+ mHelpPanel.setLayout(gb2);
+ mHelpPanel.add(mHelpLabel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.SOUTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gb.setConstraints(mHelpPanel, gbc);
+ mListPanel.add(mHelpPanel);
+
+ return mListPanel;
+ }
+
+ public JPanel createListPanel()
+ {
+ // GridBagLayout gb = new GridBagLayout();
+ // GridBagConstraints gbc = new GridBagConstraints();
+
+ Vector colNames = new Vector();
+ colNames.addElement("Defaults");
+ colNames.addElement("Constraints");
+ Vector data = new Vector();
+ Vector row = new Vector();
+ row.addElement("NoDefault");
+ row.addElement("NoConstraint");
+ data.addElement(row);
+
+ JPanel mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ //center table
+ ProfileConfigDataModel model = new ProfileConfigDataModel();
+ model.setInfo(data, colNames);
+ JTable mTable = new JTable(model);
+ JScrollPane mScrollPane = JTable.createScrollPaneForTable(mTable);
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ // mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ mTable.addMouseListener(this);
+// setLabelCellRenderer(mTable,0);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = 1;
+ gbc.weightx = 1.0;
+ gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ JPanel buttonPanel = createUserButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ mListPanel.add(buttonPanel);
+
+ return mListPanel;
+ }
+
+ protected JPanel createUserButtonPanel() {
+ Debug.println("CMSPluginInstanceTab::createUserButtonPanel()");
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mEdit = CMSAdminUtil.makeJButton(mResource, PREFIX, "EDIT", null, this);
+ mAdd = CMSAdminUtil.makeJButton(mResource, PREFIX, "ADD", null, this);
+ mDelete = CMSAdminUtil.makeJButton(mResource, PREFIX, "DELETE", null, this);
+ JButton[] buttons = {mAdd, mDelete, mEdit};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ public void actionPerformed(ActionEvent evt) {
+
+ if (evt.getSource().equals(mOK)) {
+
+ NameValuePairs nvp = new NameValuePairs();
+ try {
+ if (mModel != null) { mModel.progressStart(); }
+
+ String instanceName = mPluginName.getText();
+ nvp.put("impl", mImplName.getText());
+ nvp.put("name", mNameField.getText());
+ nvp.put("visible", (String) (mVisibleField.getSelectedItem()));
+ nvp.put("auth", mAuthField.getText());
+ nvp.put("desc", mDescField.getText());
+ // nvp.add("config", mConfigField.getText());
+ // mAdminConnection.add(DestDef.DEST_CA_PROFILE_ADMIN,
+ mAdminConnection.add(mDest,
+ ScopeDef.SC_PROFILE_RULES, instanceName, nvp);
+
+ mIsOK = true;
+ if (mModel != null) { mModel.progressStop(); }
+ this.dispose();
+ }
+ catch (EAdminException ex) {
+ mModel.progressStop();
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ ex.toString(),CMSAdminUtil.ERROR_MESSAGE);
+ }
+ }
+
+ if (evt.getSource().equals(mCancel)) {
+ this.dispose();
+ }
+ if (evt.getSource().equals(mHelp)) {
+ CMSAdminUtil.help(mHelpToken);
+ }
+
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ProfileDataTable.java b/base/console/src/com/netscape/admin/certsrv/config/ProfileDataTable.java
new file mode 100644
index 000000000..94d3b65f2
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ProfileDataTable.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.admin.certsrv.config;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.table.*;
+
+/**
+ * class used to creat the password label
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class ProfileDataTable extends JTable
+{
+
+ public ProfileDataTable(TableModel model) {
+ super(model);
+ }
+
+ public TableCellRenderer getCellRenderer(int row, int column) {
+ TableColumn tableColumn = getColumnModel().getColumn(column);
+ TableCellRenderer renderer = tableColumn.getCellRenderer();
+ if (renderer == null) {
+ Class c = getColumnClass(column);
+ if( c.equals(Object.class) ) {
+ Object o = getValueAt(row,column);
+ if( o != null ) {
+ c = getValueAt(row,column).getClass();
+ }
+ }
+ renderer = getDefaultRenderer(c);
+ }
+ return renderer;
+ }
+
+ public TableCellEditor getCellEditor(int row, int column) {
+ TableColumn tableColumn = getColumnModel().getColumn(column);
+ TableCellEditor editor = tableColumn.getCellEditor();
+ if (editor == null) {
+ Class c = getColumnClass(column);
+ if( c.equals(Object.class) ) {
+ Object o = getValueAt(row,column);
+ if( o != null )
+ c = getValueAt(row,column).getClass();
+ }
+ editor = getDefaultEditor(c);
+ }
+ return editor;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ProfileEditDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/ProfileEditDataModel.java
new file mode 100644
index 000000000..096a4075c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ProfileEditDataModel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import javax.swing.text.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Policy Parameter Configuration Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ProfileEditDataModel extends AbstractTableModel
+{
+ Vector rowData;
+ Vector columnNames;
+
+ public ProfileEditDataModel()
+ {
+ }
+
+ 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);
+ }
+
+ public void removeRow(int row) {
+ rowData.removeElementAt(row);
+ fireTableRowsDeleted(row, rowData.size());
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ProfileEditDialog.java b/base/console/src/com/netscape/admin/certsrv/config/ProfileEditDialog.java
new file mode 100644
index 000000000..d10e19215
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ProfileEditDialog.java
@@ -0,0 +1,931 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Policy Parameter Configuration Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ProfileEditDialog extends CMSBaseConfigDialog
+ implements ActionListener, ChangeListener
+{
+ protected JButton mRefresh, mOrder, mHelp;
+ protected JTextField mAuthField=null,mNameField=null, mDescField=null, mConfigField=null;
+ protected JLabel mVisibleLabel=null,mAuthLabel=null,mNameLabel=null, mDescLabel = null, mConfigLabel =null;
+ protected JComboBox mVisibleField = null;
+ protected JTable mPolicyTable=null, mInputTable=null, mOutputTable=null,
+ mAuthTable=null;
+
+ protected String mDefSetId = null;
+ protected String mName = null;
+ protected JTabbedPane mTabbedPane = null;
+ protected JButton mPolicyEdit, mPolicyAdd, mPolicyDelete;
+ protected JButton mInputEdit, mInputAdd, mInputDelete;
+ protected JButton mOutputEdit, mOutputAdd, mOutputDelete;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public ProfileEditDialog(NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest) {
+
+ super(parent, dest);
+
+ PREFIX = "PROFILEEDITDIALOG";
+ mHelpToken = "configuration-certificateprofiles";
+ mImplName_token = Constants.PR_POLICY_IMPL_NAME;
+ mImplType = Constants.PR_EXT_PLUGIN_IMPLTYPE_POLICY;
+
+ init(nvp,parent,conn,dest);
+ setSize(540, 440);
+ }
+
+
+ protected JPanel makeContentPane() {
+ JPanel mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ // 'Policy Rule ID' here
+ CMSAdminUtil.resetGBC(gbc);
+ mRulenameCaption = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "RULENAME", null);
+ mRulenameCaption.addMouseListener(this);
+ mPluginLabel = new JLabel();
+ mPluginLabel.setVisible(false);
+ mPluginName = new JTextField();
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add(mRulenameCaption, gbc);
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ 0,CMSAdminUtil.COMPONENT_SPACE);
+ mListPanel.add( mPluginName, gbc );
+ mListPanel.add( mPluginLabel, gbc );
+
+ // name
+ CMSAdminUtil.resetGBC(gbc);
+ mNameLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "NAMENAME", null);
+ mNameLabel.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add( mNameLabel, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mNameField = new JTextField();
+ mListPanel.add( mNameField, gbc );
+
+ // desc
+ CMSAdminUtil.resetGBC(gbc);
+ mDescLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "DESCNAME", null);
+ mDescLabel.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add( mDescLabel, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mDescField = new JTextField();
+ mListPanel.add( mDescField, gbc );
+
+ // visible
+ CMSAdminUtil.resetGBC(gbc);
+ mVisibleLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "VISIBLENAME", null);
+ mVisibleLabel.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add( mVisibleLabel, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ String[] item = {"true", "false"};
+ mVisibleField = new JComboBox(item);
+ mListPanel.add( mVisibleField, gbc );
+
+ // auth
+ CMSAdminUtil.resetGBC(gbc);
+ mAuthLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "AUTHNAME", null);
+ mAuthLabel.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add( mAuthLabel, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mAuthField = new JTextField();
+ mListPanel.add( mAuthField, gbc );
+
+ // config file
+/*
+ CMSAdminUtil.resetGBC(gbc);
+ mConfigLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "CONFIGNAME", null);
+ mConfigLabel.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ // mListPanel.add( mConfigLabel, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mConfigField = new JTextField();
+ // mListPanel.add( mConfigField, gbc );
+
+*/
+
+ // 'Policy Plugin ID' here
+ CMSAdminUtil.resetGBC(gbc);
+ mImplnameCaption = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "IMPLNAME", null);
+ mImplnameCaption.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add( mImplnameCaption, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mImplName = new JLabel();
+ mListPanel.add( mImplName, gbc );
+
+ /* Tab */
+ mTabbedPane = new JTabbedPane();
+ Vector policyColNames = new Vector();
+ policyColNames.addElement("Set Id");
+ policyColNames.addElement("Id");
+ policyColNames.addElement("Defaults");
+ policyColNames.addElement("Constraints");
+ Vector policyData = new Vector();
+ Vector policyRow = new Vector();
+ policyRow.addElement("p1");
+ policyRow.addElement("p1");
+ policyRow.addElement("NoDefault");
+ policyRow.addElement("NoConstraint");
+ policyData.addElement(policyRow);
+ ProfileEditDataModel model = new ProfileEditDataModel();
+ model.setInfo(policyData, policyColNames);
+ mPolicyTable = new JTable(model);
+ mPolicyEdit = CMSAdminUtil.makeJButton(mResource, PREFIX, "EDIT", null, this);
+ mPolicyAdd = CMSAdminUtil.makeJButton(mResource, PREFIX, "ADD", null, this);
+ mPolicyDelete = CMSAdminUtil.makeJButton(mResource, PREFIX, "DELETE", null, this);
+ JPanel buttonPanel = createUserButtonPanel(mPolicyAdd,
+ mPolicyDelete, mPolicyEdit);
+ JPanel lpanel = createListPanel(mPolicyTable, buttonPanel,
+ policyColNames, policyData);
+
+ Vector inputColNames = new Vector();
+ inputColNames.addElement("Id");
+ inputColNames.addElement("Inputs");
+ Vector inputData = new Vector();
+ Vector inputRow = new Vector();
+ inputRow.addElement("i1");
+ inputRow.addElement("NoInput");
+ inputData.addElement(inputRow);
+ ProfileEditDataModel model1 = new ProfileEditDataModel();
+ model1.setInfo(inputData, inputColNames);
+ mInputTable = new JTable(model1);
+ mInputEdit = CMSAdminUtil.makeJButton(mResource, PREFIX, "EDIT", null, this);
+ mInputAdd = CMSAdminUtil.makeJButton(mResource, PREFIX, "ADD", null, this);
+ mInputDelete = CMSAdminUtil.makeJButton(mResource, PREFIX, "DELETE", null, this);
+ JPanel buttonPanel1 = createUserButtonPanel(mInputAdd,
+ mInputDelete, mInputEdit);
+ JPanel lpanel1 = createListPanel(mInputTable, buttonPanel1,
+ inputColNames, inputData);
+
+ Vector outputColNames = new Vector();
+ outputColNames.addElement("Id");
+ outputColNames.addElement("Outputs");
+ Vector outputData = new Vector();
+ Vector outputRow = new Vector();
+ outputRow.addElement("i1");
+ outputRow.addElement("NoOutput");
+ outputData.addElement(outputRow);
+ ProfileEditDataModel model2 = new ProfileEditDataModel();
+ model2.setInfo(outputData, outputColNames);
+ mOutputTable = new JTable(model2);
+ mOutputEdit = CMSAdminUtil.makeJButton(mResource, PREFIX, "EDIT", null, this);
+ mOutputAdd = CMSAdminUtil.makeJButton(mResource, PREFIX, "ADD", null, this);
+ mOutputDelete = CMSAdminUtil.makeJButton(mResource, PREFIX, "DELETE",
+ null , this);
+ JPanel buttonPanel2 = createUserButtonPanel(mOutputAdd,
+ mOutputDelete, mOutputEdit);
+ JPanel lpanel2 = createListPanel(mOutputTable, buttonPanel2,
+ outputColNames, outputData);
+
+// JPanel lpanel2 = createOutputPanel();
+// JPanel lpanel3 = createAuthPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.BOTH;
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ mTabbedPane.addTab(mResource.getString(PREFIX+"_POLICIES_TAB"), lpanel);
+ mTabbedPane.addTab(mResource.getString(PREFIX+"_INPUTS_TAB"), lpanel1);
+ mTabbedPane.addTab(mResource.getString(PREFIX+"_OUTPUTS_TAB"), lpanel2);
+
+ //mTabbedPane.addTab(mResource.getString(PREFIX+"_OUTPUTS_TAB"), lpanel2);
+ //mTabbedPane.addTab(mResource.getString(PREFIX+"_AUTHS_TAB"), lpanel3);
+ gb.setConstraints(mTabbedPane, gbc);
+ mListPanel.add(mTabbedPane);
+
+ /* Panel for list of plugin's parameters */
+ mParamPanel = new JPanel();
+/*
+ mScrollPane = new JScrollPane(mParamPanel);
+ mScrollPane.setBorder(CMSAdminUtil.makeEtchedBorder());
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.BOTH;
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+*/
+
+ /* Panel in which to put plugin's help text */
+ mHelpPanel = new JPanel();
+ mHelpPanel.setBorder(CMSAdminUtil.makeEtchedBorder());
+ mHelpLabel = new JTextArea(3,0);
+ mHelpLabel.setLineWrap(true);
+ mHelpLabel.setWrapStyleWord(true);
+ mHelpLabel.setBackground(mHelpPanel.getBackground());
+ mHelpLabel.setEditable(false);
+ GridBagLayout gb2 = new GridBagLayout();
+ GridBagConstraints gbc2 = new GridBagConstraints();
+
+ CMSAdminUtil.resetGBC(gbc2);
+ gbc2.fill = gbc.BOTH;
+ gbc2.anchor = gbc.WEST;
+ gbc2.gridwidth = gbc.REMAINDER;
+ gbc2.weightx = 1.0;
+ gbc2.weighty = 1.0;
+ gb2.setConstraints(mHelpLabel, gbc2);
+ mHelpPanel.setLayout(gb2);
+ mHelpPanel.add(mHelpLabel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.SOUTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gb.setConstraints(mHelpPanel, gbc);
+ mListPanel.add(mHelpPanel);
+ mTabbedPane.addChangeListener(this);
+
+ return mListPanel;
+ }
+
+ private JTable getTable() {
+ int i = mTabbedPane.getSelectedIndex();
+ if (i == 0) {
+ return mPolicyTable;
+ } else if (i == 1) {
+ return mInputTable;
+ } else if (i == 2) {
+ return mOutputTable;
+ }
+ return null;
+ }
+
+ public JPanel createListPanel(JTable table, JPanel buttonPanel,
+ Vector column, Vector datav)
+ {
+ Vector colNames = column;
+ Vector data = datav;
+
+ JPanel listPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ listPanel.setLayout(gb);
+
+ //center table
+ JScrollPane mScrollPane = JTable.createScrollPaneForTable(table);
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ table.setAutoscrolls(true);
+ table.sizeColumnsToFit(true);
+ table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ // table.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ table.addMouseListener(this);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = 1;
+ gbc.weightx = 1.0;
+ gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ listPanel.add(mScrollPane);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ listPanel.add(buttonPanel);
+
+ return listPanel;
+ }
+
+ protected JPanel createUserButtonPanel(JButton add, JButton delete,
+ JButton edit) {
+ Debug.println("CMSPluginInstanceTab::createUserButtonPanel()");
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ JButton[] buttons = {add, delete, edit};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ public void refresh()
+ {
+ showDialog(null, mName);
+ }
+
+ public void stateChanged(ChangeEvent evt) {
+ setProfileOtherInfo(mName);
+ }
+
+ public void actionPerformed(ActionEvent evt) {
+
+ if (evt.getSource().equals(mHelp)) {
+ CMSAdminUtil.help(mHelpToken);
+ }
+
+ if (evt.getSource().equals(mPolicyAdd)) {
+ String profileId = mPluginName.getText();
+ Debug.println("Add Policy");
+ ProfilePolicySelectionDialog dialog =
+ new ProfilePolicySelectionDialog(mDefSetId, profileId,
+ "PROFILEPOLICYSELDIALOG",
+ mModel.getFrame(),
+ mAdminConnection,
+ DestDef.DEST_REGISTRY_ADMIN, mDest);
+
+ dialog.setModel(mModel);
+ dialog.setDisplay();
+ dialog.showDialog();
+ refresh();
+ }
+
+ if (evt.getSource().equals(mInputAdd)) {
+ String profileId = mPluginName.getText();
+ Debug.println("Add Input");
+ ProfileNonPolicySelDialog dialog =
+ new ProfileNonPolicySelDialog(profileId,
+ "PROFILEINPUTSELDIALOG", mModel.getFrame(),
+ mAdminConnection, DestDef.DEST_REGISTRY_ADMIN, mDest,
+ ScopeDef.SC_PROFILE_INPUT);
+ dialog.setModel(mModel);
+ dialog.setDisplay();
+ dialog.showDialog();
+ refresh();
+ }
+
+ if (evt.getSource().equals(mOutputAdd)) {
+ String profileId = mPluginName.getText();
+ Debug.println("Add Output");
+ ProfileNonPolicySelDialog dialog =
+ new ProfileNonPolicySelDialog(profileId,
+ "PROFILEOUTPUTSELDIALOG", mModel.getFrame(),
+ mAdminConnection, DestDef.DEST_REGISTRY_ADMIN, mDest,
+ ScopeDef.SC_PROFILE_OUTPUT);
+ dialog.setModel(mModel);
+ dialog.setDisplay();
+ dialog.showDialog();
+ refresh();
+ }
+
+ if (evt.getSource().equals(mPolicyDelete)) {
+ JTable table = getTable();
+ if (table.getSelectedRowCount() <= 0) {
+ String msg = mResource.getString(
+ PREFIX+"_DIALOG_NOPOLICY_MESSAGE");
+ CMSAdminUtil.showErrorDialog(mModel.getFrame(),
+ mResource, msg, CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ int i = CMSAdminUtil.showConfirmDialog(mParentFrame,
+ mResource, PREFIX, "DELETE", CMSAdminUtil.WARNING_MESSAGE);
+ if (i == JOptionPane.YES_OPTION) {
+ String policyId = (String)
+ table.getValueAt(table.getSelectedRow(), 0) + ":" +
+ table.getValueAt(table.getSelectedRow(), 1);
+ try {
+ deletePolicy(mPluginName.getText().trim(),policyId);
+
+ ProfileEditDataModel model =
+ (ProfileEditDataModel)table.getModel();
+ model.removeRow(table.getSelectedRow());
+ table.invalidate();
+ table.validate();
+ table.repaint(1);
+ } catch (EAdminException e) {
+ CMSAdminUtil.showErrorDialog(mParentFrame,
+ mResource, e.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ Debug.println("Deleted");
+ }
+ }
+
+ if (evt.getSource().equals(mInputDelete)) {
+ JTable table = getTable();
+ if (table.getSelectedRowCount() <= 0) {
+ String msg = mResource.getString(
+ PREFIX+"_DIALOG_NOPOLICY_MESSAGE");
+ CMSAdminUtil.showErrorDialog(mModel.getFrame(),
+ mResource, msg, CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ int i = CMSAdminUtil.showConfirmDialog(mParentFrame,
+ mResource, PREFIX, "DELETE", CMSAdminUtil.WARNING_MESSAGE);
+ if (i == JOptionPane.YES_OPTION) {
+ String inputId = (String)
+ table.getValueAt(table.getSelectedRow(), 0);
+ try {
+ deleteInput(mPluginName.getText().trim(),inputId);
+
+ ProfileEditDataModel model =
+ (ProfileEditDataModel)table.getModel();
+ model.removeRow(table.getSelectedRow());
+ table.invalidate();
+ table.validate();
+ table.repaint(1);
+ } catch (EAdminException e) {
+ CMSAdminUtil.showErrorDialog(mParentFrame,
+ mResource, e.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ Debug.println("Deleted");
+ }
+ }
+
+ if (evt.getSource().equals(mOutputDelete)) {
+ JTable table = getTable();
+ if (table.getSelectedRowCount() <= 0) {
+ String msg = mResource.getString(
+ PREFIX+"_DIALOG_NOPOLICY_MESSAGE");
+ CMSAdminUtil.showErrorDialog(mModel.getFrame(),
+ mResource, msg, CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ int i = CMSAdminUtil.showConfirmDialog(mParentFrame,
+ mResource, PREFIX, "DELETE", CMSAdminUtil.WARNING_MESSAGE);
+ if (i == JOptionPane.YES_OPTION) {
+ String outputId = (String)
+ table.getValueAt(table.getSelectedRow(), 0);
+ try {
+ deleteOutput(mPluginName.getText().trim(),outputId);
+
+ ProfileEditDataModel model =
+ (ProfileEditDataModel)table.getModel();
+ model.removeRow(table.getSelectedRow());
+ table.invalidate();
+ table.validate();
+ table.repaint(1);
+ } catch (EAdminException e) {
+ CMSAdminUtil.showErrorDialog(mParentFrame,
+ mResource, e.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ Debug.println("Deleted");
+ }
+ }
+
+ if (evt.getSource().equals(mPolicyEdit)) {
+ JTable table = getTable();
+ // pick selected entry
+ if (table.getSelectedRowCount() <= 0) {
+ CMSAdminUtil.showErrorDialog(mModel.getFrame(),
+ mResource,
+ "You must select a policy first",
+ CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ String policyId = (String)
+ table.getValueAt(table.getSelectedRow(), 0) + ":" +
+ table.getValueAt(table.getSelectedRow(), 1);
+
+ Debug.println("Edit");
+ NameValuePairs nvp = new NameValuePairs();
+ ProfilePolicyEditDialog dialog =
+ new ProfilePolicyEditDialog(nvp,
+ mModel.getFrame(),
+ mAdminConnection,
+ // DestDef.DEST_CA_PROFILE_ADMIN);
+ mDest);
+ dialog.setModel(mModel);
+
+ String name = mPluginName.getText() + ";" + policyId;
+ Debug.println(" XXXX name=" + name);
+ dialog.showDialog(null, name);
+ }
+
+ if (evt.getSource().equals(mInputEdit)) {
+ JTable table = getTable();
+ // pick selected entry
+ if (table.getSelectedRowCount() <= 0) {
+ CMSAdminUtil.showErrorDialog(mModel.getFrame(),
+ mResource,
+ "You must select an input first",
+ CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ String inputId = (String)
+ table.getValueAt(table.getSelectedRow(), 0);
+
+ Debug.println("Edit input");
+ NameValuePairs nvp = new NameValuePairs();
+ ProfileNonPolicyNewDialog dialog =
+ new ProfileNonPolicyNewDialog(nvp,
+ mModel.getFrame(),
+ mAdminConnection,
+ //DestDef.DEST_CA_PROFILE_ADMIN,
+ mDest,
+ ScopeDef.SC_PROFILE_INPUT_CONFIG, false);
+ dialog.setModel(mModel);
+
+ String name = mPluginName.getText() + ";" + inputId;
+ Debug.println(" XXXX name=" + name);
+ dialog.showDialog(null, mPluginName.getText().trim(), inputId);
+ }
+
+ if (evt.getSource().equals(mOutputEdit)) {
+ JTable table = getTable();
+ // pick selected entry
+ if (table.getSelectedRowCount() <= 0) {
+ CMSAdminUtil.showErrorDialog(mModel.getFrame(),
+ mResource,
+ "You must select an output first",
+ CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ String outputId = (String)
+ table.getValueAt(table.getSelectedRow(), 0);
+
+ Debug.println("Edit output");
+ NameValuePairs nvp = new NameValuePairs();
+ ProfileNonPolicyNewDialog dialog =
+ new ProfileNonPolicyNewDialog(nvp,
+ mModel.getFrame(),
+ mAdminConnection,
+ // DestDef.DEST_CA_PROFILE_ADMIN,
+ mDest,
+ ScopeDef.SC_PROFILE_OUTPUT_CONFIG, false);
+ dialog.setModel(mModel);
+
+ String name = mPluginName.getText() + ";" + outputId;
+ Debug.println(" XXXX name=" + name);
+ dialog.showDialog(null, mPluginName.getText().trim(), outputId);
+ }
+
+ if (evt.getSource().equals(mOK)) {
+
+ NameValuePairs nvp = new NameValuePairs();
+ try {
+ if (mModel != null)
+ mModel.progressStart();
+
+ String instanceName = mPluginName.getText();
+ nvp.put("impl", mImplName.getText());
+ nvp.put("name", mNameField.getText());
+ nvp.put("desc", mDescField.getText());
+ nvp.put("visible", (String) (mVisibleField.getSelectedItem()));
+ nvp.put("auth", mAuthField.getText());
+ // nvp.add("config", mConfigField.getText());
+
+/*
+ // mAdminConnection.add(DestDef.DEST_CA_PROFILE_ADMIN,
+ ScopeDef.SC_PROFILE_RULES, instanceName, nvp);
+*/
+ //DestDef.DEST_CA_PROFILE_ADMIN,
+ mAdminConnection.modify(mDest,
+ ScopeDef.SC_PROFILE_RULES, instanceName, nvp);
+
+ mIsOK = true;
+ if (mModel != null)
+ mModel.progressStop();
+ this.dispose();
+ } catch (EAdminException ex) {
+ mModel.progressStop();
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ ex.toString(),CMSAdminUtil.ERROR_MESSAGE);
+ }
+ }
+
+ if (evt.getSource().equals(mCancel)) {
+ this.dispose();
+ }
+
+ }
+
+ private void deletePolicy(String profileId, String policyId)
+ throws EAdminException{
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put("POLICYID", policyId);
+ //mAdminConnection.delete(DestDef.DEST_CA_PROFILE_ADMIN,
+ mAdminConnection.delete(mDest,
+ ScopeDef.SC_PROFILE_POLICIES, profileId, nvps);
+ }
+
+ private void deleteInput(String profileId, String inputId)
+ throws EAdminException{
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put("INPUTID", inputId);
+ //mAdminConnection.delete(DestDef.DEST_CA_PROFILE_ADMIN,
+ mAdminConnection.delete(mDest,
+ ScopeDef.SC_PROFILE_INPUT, profileId, nvps);
+ }
+
+ private void deleteOutput(String profileId, String outputId)
+ throws EAdminException{
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put("OUTPUTID", outputId);
+ //mAdminConnection.delete(DestDef.DEST_CA_PROFILE_ADMIN,
+ mAdminConnection.delete(mDest,
+ ScopeDef.SC_PROFILE_OUTPUT, profileId, nvps);
+ }
+
+ public void showDialog(NameValuePairs data, String name) {
+
+ mName = name;
+ setProfileInfo(name);
+ setProfileOtherInfo(name);
+
+ this.show();
+ }
+
+ private void setProfileInfo(String name) {
+ mModel.progressStart();
+
+ // retrieve profile information
+ NameValuePairs response = null;
+ NameValuePairs request = new NameValuePairs();
+ try {
+ //response = mAdminConnection.read(DestDef.DEST_CA_PROFILE_ADMIN,
+ response = mAdminConnection.read(mDest,
+ ScopeDef.SC_PROFILE_RULES,
+ name, request);
+ } catch (EAdminException e) {
+// CMSAdminUtil.showErrorDialog(mParentFrame, mResource, e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+
+ String enable = response.get("enable");
+
+ if (response != null) {
+ mPluginName.setEnabled(false);
+ mPluginName.setBackground(getBackground());
+ mPluginName.setText(name);
+ mNameField.setText(response.get("name"));
+ mDescField.setText(response.get("desc"));
+ mAuthField.setText(response.get("auth"));
+ mVisibleField.setSelectedItem(response.get("visible"));
+ mImplName.setText(response.get("plugin"));
+ // mConfigField.setText(response.getValue("config"));
+ }
+ if (enable != null && enable.equals("true")) {
+ // disable everything
+ mNameField.setEnabled(false);
+ mDescField.setEnabled(false);
+ mAuthField.setEnabled(false);
+ mVisibleField.setEnabled(false);
+ mImplName.setEnabled(false);
+
+ mPolicyEdit.setEnabled(false);
+ mPolicyAdd.setEnabled(false);
+ mPolicyDelete.setEnabled(false);
+
+ mInputEdit.setEnabled(false);
+ mInputAdd.setEnabled(false);
+ mInputDelete.setEnabled(false);
+
+ mOutputEdit.setEnabled(false);
+ mOutputAdd.setEnabled(false);
+ mOutputDelete.setEnabled(false);
+ }
+ }
+
+ private void setProfileOtherInfo(String name) {
+ if (mModel != null)
+ mModel.progressStart();
+ JTable table = getTable();
+ NameValuePairs request = new NameValuePairs();
+ NameValuePairs response = null;
+ if (table == mPolicyTable) {
+ try {
+ response = mAdminConnection.read(
+ mDest,
+ ScopeDef.SC_PROFILE_POLICIES, name, request);
+ } catch (EAdminException e) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ if (mModel != null)
+ mModel.progressStop();
+ return;
+ }
+
+ if (mModel != null)
+ mModel.progressStop();
+ if (response != null) {
+ populatePolicies(response, table);
+ }
+ } else if (table == mInputTable) {
+ try {
+ response = mAdminConnection.read(
+ mDest,
+ ScopeDef.SC_PROFILE_INPUT, name, request);
+ } catch (EAdminException e) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ if (mModel != null)
+ mModel.progressStop();
+ return;
+ }
+
+ if (mModel != null)
+ mModel.progressStop();
+ if (response != null) {
+ populateNonPolicy(response, table);
+ }
+ } else if (table == mOutputTable) {
+ try {
+ response = mAdminConnection.read(
+ mDest,
+ ScopeDef.SC_PROFILE_OUTPUT, name, request);
+ } catch (EAdminException e) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ if (mModel != null)
+ mModel.progressStop();
+ return;
+ }
+
+ if (mModel != null)
+ mModel.progressStop();
+ if (response != null) {
+ populateNonPolicy(response, table);
+ }
+ } else {
+ // do nothing
+ }
+ }
+
+ private void populatePolicies(NameValuePairs response, JTable table) {
+ Vector<String> colNames = new Vector<String>();
+ colNames.addElement("Set Id");
+ colNames.addElement("Id");
+ colNames.addElement("Defaults");
+ colNames.addElement("Constraints");
+ Vector<Vector<String>> d = new Vector<Vector<String>>();
+
+ for (String entry : response.keySet()) {
+ entry = entry.trim();
+ String value = response.get(entry);
+ Debug.println("populatePolicies entry= "+entry);
+ Debug.println("populatePolicies value= "+value);
+
+ StringTokenizer st = new StringTokenizer(value, ";");
+ String def = st.nextToken();
+ String con = st.nextToken();
+ Vector<String> row = new Vector<String>();
+
+ StringTokenizer st1 = new StringTokenizer(entry, ":");
+ String setId = st1.nextToken();
+ String id = st1.nextToken();
+
+ if (mDefSetId == null) {
+ mDefSetId = setId;
+ }
+ row.addElement(setId);
+ row.addElement(id);
+ row.addElement(def);
+ row.addElement(con);
+ d.addElement(row);
+ }
+ ProfileEditDataModel model = new ProfileEditDataModel();
+ model.setInfo(d, colNames);
+ table.setModel(model);
+ }
+
+ private void populateNonPolicy(NameValuePairs response, JTable table) {
+ Vector<String> colNames = new Vector<String>();
+ colNames.addElement("Id");
+ if (table == mInputTable)
+ colNames.addElement("Inputs");
+ else if (table == mOutputTable)
+ colNames.addElement("Outputs");
+ Vector<Vector<String>> d = new Vector<Vector<String>>();
+
+ for (String entry : response.keySet()) {
+ entry = entry.trim();
+ String value = response.get(entry);
+ Debug.println("populateNonPolicy entry= " + entry);
+ Debug.println("populateNonPolicy value= " + value);
+
+ Vector<String> row = new Vector<String>();
+ row.addElement(entry);
+ row.addElement(value);
+ d.addElement(row);
+ }
+ ProfileEditDataModel model = new ProfileEditDataModel();
+ model.setInfo(d, colNames);
+ table.setModel(model);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ProfileImplDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/ProfileImplDataModel.java
new file mode 100644
index 000000000..eee2531cf
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ProfileImplDataModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Policy Implementation Data model - represents the implementation
+ * table information
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ProfileImplDataModel extends CMSContentTableModel
+ implements IDataProcessor
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String IMPL_NAME = "NAME";
+ public static final String IMPL_CLASS = "CLASS";
+ public static final String IMPL_TYPE = "TYPE";
+ public static final String IMPL_DESC = "DESC";
+
+ private static String[] mColumns = {POLICY_IMPL, IMPL_TYPE, CLASSNAME};
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public ProfileImplDataModel() {
+ super();
+ init(mColumns);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void processData(Object data) {
+ Vector v = new Vector();
+ NameValuePairs obj = (NameValuePairs) data;
+ v.addElement(new JLabel(obj.get(IMPL_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE_PLUGIN),
+ JLabel.LEFT));
+ v.addElement(obj.get(IMPL_TYPE));
+ v.addElement(obj.get(IMPL_CLASS));
+ //v.addElement(obj.getValue(IMPL_DESC));
+ addRow(v, data);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ProfileImplTab.java b/base/console/src/com/netscape/admin/certsrv/config/ProfileImplTab.java
new file mode 100644
index 000000000..c7d28dd07
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ProfileImplTab.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Policy Instances Management Tab
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ProfileImplTab extends CMSBaseUGTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String IMPL_NAME = ProfileImplDataModel.IMPL_NAME;
+ private static final String IMPL_TYPE = ProfileImplDataModel.IMPL_TYPE;
+ private static final String IMPL_CLASS = ProfileImplDataModel.IMPL_CLASS;
+ private static final String IMPL_DESC = ProfileImplDataModel.IMPL_DESC;
+
+ private static final String PANEL_NAME = "PROFILEIMPL";
+ private static final String DIALOG_PREFIX = "PROFILEREGISTERDIALOG";
+
+ private AdminConnection mConnection;
+ private String mDestination;
+
+ protected JScrollPane mScrollPane;
+ protected JTable mTable; //table
+ protected ProfileImplDataModel mDataModel; //table model
+ protected ProfileRegisterDialog mEditor=null; //keep single copy
+ protected ViewDialog mViewer=null; //keep single copy
+
+ protected JButton mRefresh, mAdd, mDelete, mView, mHelp;
+ private final static String HELPINDEX = "configuration-certificateprofiles";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public ProfileImplTab(CMSBaseResourceModel model, String destination) {
+ super(PANEL_NAME, model);
+ mConnection = model.getServerInfo().getAdmin();
+ mDataModel = new ProfileImplDataModel();
+ mDestination = destination;
+ mHelpToken = HELPINDEX;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mRefresh)) {
+ refresh();
+ }
+ if (e.getSource().equals(mAdd)) {
+ if (mEditor==null)
+ mEditor = new ProfileRegisterDialog(mModel.getFrame(),
+ mConnection);
+ mEditor.showDialog(mDestination, ScopeDef.SC_POLICY_IMPLS);
+ refresh();
+ }
+ if (e.getSource().equals(mDelete)) {
+ Debug.println("Delete");
+ if(mTable.getSelectedRow()< 0)
+ return;
+ int i = showConfirmDialog("DELETE");
+ if (i == JOptionPane.YES_OPTION) {
+ delete();
+ Debug.println("Deleted");
+ }
+ }
+ if (e.getSource().equals(mView)) {
+ Debug.println("View");
+ if(mTable.getSelectedRow()< 0)
+ return;
+ NameValuePairs obj = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+ if (mViewer==null)
+ mViewer = new ViewDialog(mModel.getFrame());
+ mViewer.showDialog(obj.get(IMPL_NAME),
+ obj.get(IMPL_CLASS),
+ obj.get(IMPL_DESC));
+ }
+ if (e.getSource().equals(mHelp)) {
+ helpCallback();
+ }
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+ public void refresh() {
+
+ mDataModel.removeAllRows();
+ update();
+
+ setButtons();
+ mTable.invalidate();
+ mTable.validate();
+ mTable.repaint(1);
+ }
+
+ /**
+ * create the user action button panel
+ */
+ protected JPanel createButtonPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mAdd = makeJButton("ADD");
+ mDelete = makeJButton("DELETE");
+ mView = makeJButton("VIEW");
+ JButton[] buttons = {mAdd, mDelete, mView};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ protected JPanel createActionPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mRefresh = makeJButton("REFRESH");
+ mHelp = makeJButton("HELP");
+ //JButton[] buttons = { mRefresh, mHelp };
+ JButton[] buttons = { mRefresh };
+ return makeJButtonPanel(buttons, true);
+ }
+
+ protected JPanel createListPanel() {
+ mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ //center table
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ //mScrollPane.setBorder(CMSAdminUtil.makeTitledBorder(mResource,PANEL_NAME,"USERS"));
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ mTable.addMouseListener(this);
+ setLabelCellRenderer(mTable,0);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = 1;
+ gbc.weightx = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ JPanel buttonPanel = createButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ mListPanel.add(buttonPanel);
+
+ refresh();
+
+ return mListPanel;
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(new LabelCellRenderer(new JLabel()));
+ }
+
+
+ //set buttons
+ private void setButtons() {
+
+ //enable and diable buttons accordingly
+ //Debug.println("setButtons() - "+mTable.getSelectedRow());
+ //Debug.println("setButtons() - "+mTable.getSelectionModel().isSelectionEmpty());
+ if (mTable.getSelectionModel().isSelectionEmpty()) {
+ mDelete.setEnabled(false);
+ mView.setEnabled(false);
+ return;
+ }
+
+ if(mDataModel.getRowCount()<=0) {
+ mDelete.setEnabled(false);
+ mView.setEnabled(false);
+ return;
+ }
+
+ mDelete.setEnabled(true);
+ mView.setEnabled(true);
+
+ }
+
+ //=============================================
+ // SEND REQUESTS TO THE SERVER SIDE
+ //=============================================
+ private void update() {
+ //send request and parse data
+
+ mModel.progressStart();
+ NameValuePairs response = new NameValuePairs();
+ NameValuePairs response1;
+ NameValuePairs response2;
+ NameValuePairs response3;
+ NameValuePairs response4;
+ NameValuePairs response5;
+ try {
+ response1 = mConnection.search(mDestination,
+ "profile",
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+ for (String entry : response1.keySet()) {
+ entry = entry.trim();
+ response.put(entry + ";profile", response1.get(entry));
+ }
+ try {
+ response2 = mConnection.search(mDestination,
+ "profileInput",
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+ for (String entry : response2.keySet()) {
+ entry = entry.trim();
+ response.put(entry + ";profileInput", response2.get(entry));
+ }
+ try {
+ response3 = mConnection.search(mDestination,
+ "profileOutput",
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+ for (String entry : response3.keySet()) {
+ entry = entry.trim();
+ response.put(entry + ";profileOutput", response3.get(entry));
+ }
+ try {
+ response4 = mConnection.search(mDestination,
+ "defaultPolicy",
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+ for (String entry : response4.keySet()) {
+ entry = entry.trim();
+ response.put(entry + ";defaultPolicy", response4.get(entry));
+ }
+ try {
+ response5 = mConnection.search(mDestination,
+ "constraintPolicy",
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+ for (String entry : response5.keySet()) {
+ entry = entry.trim();
+ response.put(entry + ";constraintPolicy", response5.get(entry));
+ }
+
+ //parse the data
+ int i=0;
+ String[] vals = new String[response.size()];
+ Hashtable data = new Hashtable();
+ for (String entry : response.keySet()) {
+ entry = entry.trim();
+ String value = response.get(entry);
+ int x = value.indexOf(",");
+ int x_end = value.lastIndexOf(",");
+ int y = entry.indexOf(";");
+ NameValuePairs obj = new NameValuePairs();
+ obj.put(IMPL_NAME, entry.substring(0, y));
+ obj.put(IMPL_TYPE, entry.substring(y + 1));
+ vals[i++]= entry ;
+ obj.put(IMPL_CLASS, value.substring(0, x));
+ obj.put(IMPL_DESC, value.substring(x + 1, x_end));
+ data.put(entry,obj);
+ }
+
+ CMSAdminUtil.bubbleSort(vals);
+
+ for (int y=0; y< vals.length ; y++) {
+ mDataModel.processData(data.get(vals[y]));
+ }
+
+ data.clear();
+
+ if (mDataModel.getRowCount() >0)
+ mTable.setRowSelectionInterval(0,0);
+
+ mModel.progressStop();
+ }
+
+ private void delete() {
+ //get entry name
+ mModel.progressStart();
+ NameValuePairs obj = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+
+ //send comment to server for the removal of user
+ try {
+ mConnection.delete(mDestination,
+ obj.get(IMPL_TYPE),
+ obj.get(IMPL_NAME));
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+ mModel.progressStop();
+ //send comment to server and refetch the content
+ refresh();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ProfileInstanceTab.java b/base/console/src/com/netscape/admin/certsrv/config/ProfileInstanceTab.java
new file mode 100644
index 000000000..6dbc1dceb
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ProfileInstanceTab.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Profile Instances Management Tab
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ProfileInstanceTab extends CMSPluginInstanceTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PANEL_NAME = "PROFILERULE";
+
+ protected JButton mOrder;
+ private final static String HELPINDEX = "configuration-certificateprofiles";
+ private ResourceBundle mResource;
+ private String mDest;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public ProfileInstanceTab(CMSBaseResourceModel model, String dest) {
+ super(model,dest,PANEL_NAME);
+ Debug.println("PolicyInstanceTab::PolicyInstanceTab(<model>,"+dest);
+ mConnection = model.getServerInfo().getAdmin();
+ mDataModel = new ProfileRuleDataModel();
+ mScope = ScopeDef.SC_POLICY_RULES;
+ mDest = dest;
+ RULE_NAME = PolicyRuleDataModel.RULE_NAME;
+ RULE_STAT = PolicyRuleDataModel.RULE_STAT;
+ mResource = ResourceBundle.getBundle(
+ CMSAdminResources.class.getName());
+
+ mHelpToken = HELPINDEX;
+ }
+
+ public CMSBaseConfigDialog makeEditConfigDialog(
+ NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest
+ )
+ {
+ return new ProfileEditDialog(nvp,
+ parent,
+ conn,
+ dest);
+ }
+
+ public CMSBaseConfigDialog makeNewConfigDialog(
+ NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest
+ )
+ {
+
+ return new ProfileConfigDialog(nvp,
+ parent,
+ conn,
+ dest);
+ }
+
+ public PluginSelectionDialog getPluginSelectionDialog(
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType
+ )
+ {
+ return new ProfilePluginSelectionDialog(parent,conn,DestDef.DEST_REGISTRY_ADMIN, dest, pluginType);
+ }
+
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mEdit) || e.getSource().equals(mDelete)) {
+ if(mTable.getSelectedRow()< 0)
+ return;
+ NameValuePairs data = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+ // dont check enable and disable here. We want to
+ // view profile even though it is enabled
+ }
+
+ super.actionPerformed(e);
+ }
+
+ public void moreActionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mOrder)) {
+ Debug.println("Order");
+ PolicyRuleOrderDialog dialog =
+ new PolicyRuleOrderDialog(mModel.getFrame(),
+ mConnection, mDestination);
+ dialog.showDialog(mDataModel.getRules());
+ refresh();
+ }
+ }
+
+ /**
+ * create the user action button panel
+ */
+ protected JPanel createUserButtonPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mOrder = makeJButton("ORDER");
+ mEdit = makeJButton("EDIT");
+ mAdd = makeJButton("ADD");
+ mDelete = makeJButton("DELETE");
+ JButton[] buttons = {mAdd, mDelete, mEdit };
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+
+ //set buttons
+ protected void setButtons() {
+ super.setButtons();
+
+ if (mDataModel.getRowCount()<=0) {
+ mOrder.setEnabled(false);
+ }
+ else {
+ mOrder.setEnabled(true);
+ }
+ }
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ProfileListDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/ProfileListDataModel.java
new file mode 100644
index 000000000..2e4633046
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ProfileListDataModel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Profile List Model
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ProfileListDataModel extends DefaultListModel {
+
+ private Vector mObjectContainer = new Vector();
+
+ public Object getObjectValueAt(int row) {
+ return mObjectContainer.elementAt(row);
+ }
+
+ public void removeAllRows() {
+ super.removeAllElements();
+ mObjectContainer.removeAllElements();
+ }
+
+ public void addElement(Object displayData, Object extraData) {
+ super.addElement(displayData);
+ mObjectContainer.addElement(extraData);
+ }
+
+ public void clear() {
+ super.clear();
+ mObjectContainer.clear();
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ProfileNonPolicyNewDialog.java b/base/console/src/com/netscape/admin/certsrv/config/ProfileNonPolicyNewDialog.java
new file mode 100644
index 000000000..e597b242b
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ProfileNonPolicyNewDialog.java
@@ -0,0 +1,429 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Policy Parameter Configuration Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ProfileNonPolicyNewDialog extends CMSBaseConfigDialog
+ implements ActionListener
+{
+ protected JButton mRefresh, mEdit, mAdd, mDelete, mOrder, mHelp;
+ protected JTextField mNameField=null, mDescField=null, mConfigField=null;
+ protected JLabel mNameLabel=null, mDescLabel = null, mConfigLabel =null;
+ protected JTable mTable = null;
+ private String mParamId = null, mInputId = null;
+ private String mScope = null;
+ private boolean mIsNew = true;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public ProfileNonPolicyNewDialog(NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest, String scope, boolean new1) {
+
+ super(parent, dest);
+
+ PREFIX = "PROFILEREGISTRYNEWDIALOG";
+ mHelpToken = "configuration-certificateprofiles";
+ mImplName_token = Constants.PR_POLICY_IMPL_NAME;
+ mImplType = Constants.PR_EXT_PLUGIN_IMPLTYPE_POLICY;
+ mIsNew = new1;
+ mScope = scope;
+
+ init(nvp,parent,conn,dest);
+ setSize(500, 415);
+ }
+
+
+ protected JPanel makeContentPane() {
+ JPanel mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ // 'Policy Rule ID' here
+ CMSAdminUtil.resetGBC(gbc);
+ mRulenameCaption = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "RULENAME", null);
+ mRulenameCaption.addMouseListener(this);
+ mPluginLabel = new JLabel();
+ mPluginLabel.setVisible(false);
+ mPluginName = new JTextField();
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add(mRulenameCaption, gbc);
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ 0,CMSAdminUtil.COMPONENT_SPACE);
+ mListPanel.add( mPluginName, gbc );
+ // mListPanel.add( mPluginLabel, gbc );
+
+ // name
+ CMSAdminUtil.resetGBC(gbc);
+ mNameLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "NAMENAME", null);
+ mNameLabel.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ // mListPanel.add( mNameLabel, gbc );
+ mNameLabel.setBackground(getBackground());
+ mNameLabel.setEnabled(false);
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mNameField = new JTextField();
+ // mListPanel.add( mNameField, gbc );
+
+ // desc
+ CMSAdminUtil.resetGBC(gbc);
+ mDescLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "DESCNAME", null);
+ // mDescLabel.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add( mDescLabel, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mDescField = new JTextField();
+ mListPanel.add( mDescField, gbc );
+
+ // config file
+/*
+ CMSAdminUtil.resetGBC(gbc);
+ mConfigLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "CONFIGNAME", null);
+ mConfigLabel.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ // mListPanel.add( mConfigLabel, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mConfigField = new JTextField();
+ // mListPanel.add( mConfigField, gbc );
+*/
+
+
+ // 'Policy Plugin ID' here
+ CMSAdminUtil.resetGBC(gbc);
+ mImplnameCaption = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "IMPLNAME", null);
+ mImplnameCaption.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ // mListPanel.add( mImplnameCaption, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mImplName = new JLabel();
+// mListPanel.add( mImplName, gbc );
+
+ JPanel lpanel1 = createListPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.BOTH;
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(lpanel1, gbc);
+ mListPanel.add(lpanel1);
+
+ /* Panel in which to put plugin's help text */
+ mHelpPanel = new JPanel();
+ mHelpPanel.setBorder(CMSAdminUtil.makeEtchedBorder());
+ mHelpLabel = new JTextArea(3,0);
+ mHelpLabel.setLineWrap(true);
+ mHelpLabel.setWrapStyleWord(true);
+ mHelpLabel.setBackground(mHelpPanel.getBackground());
+ mHelpLabel.setEditable(false);
+ GridBagLayout gb2 = new GridBagLayout();
+ GridBagConstraints gbc2 = new GridBagConstraints();
+
+ CMSAdminUtil.resetGBC(gbc2);
+ gbc2.fill = gbc.BOTH;
+ gbc2.anchor = gbc.WEST;
+ gbc2.gridwidth = gbc.REMAINDER;
+ gbc2.weightx = 1.0;
+ gbc2.weighty = 1.0;
+ gb2.setConstraints(mHelpLabel, gbc2);
+ mHelpPanel.setLayout(gb2);
+ mHelpPanel.add(mHelpLabel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.SOUTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gb.setConstraints(mHelpPanel, gbc);
+ mListPanel.add(mHelpPanel);
+
+ return mListPanel;
+ }
+
+ public JPanel createListPanel()
+ {
+ Vector colNames = new Vector();
+ colNames.addElement("Parameter");
+ colNames.addElement("Value");
+ Vector data = new Vector();
+ Vector row = new Vector();
+ row.addElement("x");
+ row.addElement("x");
+ data.addElement(row);
+
+ JPanel mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ //center table
+ ProfilePolicyEditDataModel model = new ProfilePolicyEditDataModel();
+ model.setInfo(data, colNames);
+ mTable = new JTable(model);
+ JScrollPane mScrollPane = JTable.createScrollPaneForTable(mTable);
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ // mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ mTable.addMouseListener(this);
+// setLabelCellRenderer(mTable,0);
+setLabelCellEditor(mTable, 1);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ // gbc.gridwidth = 1;
+ // gbc.weightx = 1.0;
+ gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ return mListPanel;
+ }
+
+ public void actionPerformed(ActionEvent evt) {
+
+ if (evt.getSource().equals(mHelp)) {
+ CMSAdminUtil.help(mHelpToken);
+ }
+
+ if (evt.getSource().equals(mOK)) {
+
+ try {
+ if (mModel != null) {
+ mModel.progressStart();
+ }
+
+ NameValuePairs nvp = new NameValuePairs();
+ String instanceName = mPluginName.getText();
+
+ String id = mDescField.getText();
+ if (id == null || id.trim().equals("")) {
+ String msg = mResource.getString(
+ PREFIX+"_DIALOG_BLANKPOLICYID_MESSAGE");
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ msg ,CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+
+ for (int i = 0; i < mTable.getRowCount(); i++) {
+ nvp.put((String) mTable.getValueAt(i, 0),
+ (String) mTable.getValueAt(i, 1));
+ }
+
+ if (mIsNew) {
+ String name = instanceName + ";" + id + ";" + mParamId;
+ // mAdminConnection.add(DestDef.DEST_CA_PROFILE_ADMIN,
+ mAdminConnection.add(mDest,
+ mScope, name, nvp);
+ //ScopeDef.SC_PROFILE_INPUT, name, nvp);
+ } else {
+ String name = instanceName + ";" + id;
+ //mAdminConnection.modify(DestDef.DEST_CA_PROFILE_ADMIN,
+ mAdminConnection.modify(mDest,
+ mScope, name, nvp);
+ //ScopeDef.SC_PROFILE_INPUT_CONFIG, name, nvp);
+ }
+
+ mIsOK = true;
+ if (mModel != null) {
+ mModel.progressStop();
+ }
+
+ this.dispose();
+ }
+ catch (EAdminException ex) {
+ mModel.progressStop();
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ ex.toString(),CMSAdminUtil.ERROR_MESSAGE);
+ }
+ }
+
+ if (evt.getSource().equals(mCancel)) {
+ this.dispose();
+ }
+
+ }
+
+ public void showDialog(NameValuePairs data, String profileId, String paramId) {
+
+ if (mIsNew)
+ mParamId = paramId;
+ else {
+ mInputId = paramId;
+ mDescField.setText(paramId);
+ mDescField.setBackground(getBackground());
+ mDescField.setEnabled(false);
+ }
+
+ mModel.progressStart();
+
+ // retrieve profile information
+ NameValuePairs response = null;
+ NameValuePairs request = new NameValuePairs();
+ try {
+ if (mIsNew)
+ response = mAdminConnection.read(DestDef.DEST_REGISTRY_ADMIN,
+ //ScopeDef.SC_PROFILE_INPUT,
+ mScope, paramId, request);
+ else
+ // response = mAdminConnection.read(DestDef.DEST_CA_PROFILE_ADMIN,
+ response = mAdminConnection.read(mDest,
+ //ScopeDef.SC_PROFILE_INPUT_CONFIG,
+ mScope, profileId+";"+mInputId, request);
+ } catch (EAdminException e) {
+// CMSAdminUtil.showErrorDialog(mParentFrame, mResource, e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+
+ Vector defcolNames = new Vector();
+ defcolNames.addElement("Parameter");
+ defcolNames.addElement("Value");
+ Vector defdata = new Vector();
+
+ for (String entry : response.keySet()) {
+ entry = entry.trim();
+ String value = response.get(entry);
+ Debug.println("entry= " + entry);
+ Debug.println("value= " + value);
+
+ int start_pos = value.indexOf(';');
+ int end_pos = value.lastIndexOf(';');
+ String syntax = null;
+ String syntaxVal = null;
+ String val = null;
+
+ syntax = value.substring(0,start_pos);
+ syntaxVal = value.substring(start_pos+1, end_pos);
+ val = value.substring(end_pos+1);
+
+ Vector row = new Vector();
+ row.addElement(entry);
+ row.addElement(val);
+ defdata.addElement(row);
+ }
+ ProfilePolicyEditDataModel model = new ProfilePolicyEditDataModel();
+ model.setInfo(defdata, defcolNames);
+ mTable.setModel(model);
+
+ if (response != null) {
+ mPluginName.setText(profileId);
+ mPluginName.setBackground(getBackground());
+ mPluginName.setEnabled(false);
+ mNameField.setText(response.get("name"));
+ if (mIsNew)
+ mDescField.setText(response.get("desc"));
+ }
+
+ this.show();
+ }
+
+ protected void setLabelCellEditor(JTable table, int index) {
+/*
+ table.getColumnModel().getColumn(index).setCellRenderer(
+ new PasswordCellRenderer());
+*/
+ table.getColumnModel().getColumn(index).setCellEditor(
+ new DefaultCellEditor(new JTextField()));
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ProfileNonPolicySelDialog.java b/base/console/src/com/netscape/admin/certsrv/config/ProfileNonPolicySelDialog.java
new file mode 100644
index 000000000..8d97ffd13
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ProfileNonPolicySelDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Plugin Selection Dialog
+ *
+ * @author Jack Pan-chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ProfileNonPolicySelDialog extends JDialog
+ implements ActionListener, MouseListener
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ protected JFrame mParentFrame;
+ protected AdminConnection mConnection;
+ protected ResourceBundle mResource;
+ protected DefaultListModel mListModel;
+ protected Hashtable mListData;
+ protected String mDestination; //dest flag
+
+ private JScrollPane mScrollPane;
+ protected JList mList;
+
+ protected JLabel mLabel;
+ protected JButton mOK, mCancel, mHelp;
+ protected String mPrefix;
+ protected String mScope;
+ protected String mInstanceScope;
+ protected String mProfileId;
+ protected String mHelpToken;
+ protected String mExtraDestination;
+ protected CMSPluginInstanceTab mPluginInstanceDialog;
+ protected CMSBaseResourceModel mModel=null;
+
+
+ public ProfileNonPolicySelDialog (
+ String profileId,
+ String prefix,
+ JFrame parent,
+ AdminConnection conn,
+ String dest, String scope)
+ {
+ this(profileId, prefix, parent, conn, dest, null, scope, null);
+ }
+
+ public ProfileNonPolicySelDialog (
+ String profileId,
+ String prefix,
+ JFrame parent,
+ AdminConnection conn,
+ String dest, String extraDest, String scope)
+ {
+ this( profileId, prefix,
+ parent,
+ conn,
+ dest, extraDest, scope,
+ null );
+ }
+
+ public ProfileNonPolicySelDialog(
+ String profileId,
+ String prefix,
+ JFrame parent,
+ AdminConnection conn,
+ String dest, String scope,
+ CMSPluginInstanceTab pluginType)
+ {
+ this(profileId, prefix, parent, conn, dest, null, scope, pluginType);
+ }
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public ProfileNonPolicySelDialog(
+ String profileId,
+ String prefix,
+ JFrame parent,
+ AdminConnection conn,
+ String dest, String extraDest, String scope,
+ CMSPluginInstanceTab pluginType)
+ {
+ super(parent,true);
+ mProfileId = profileId;
+ mParentFrame = parent;
+ mConnection = conn;
+ mDestination = dest;
+ mExtraDestination = extraDest;
+ mScope = scope;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mListModel = new DefaultListModel();
+ mListData = new Hashtable();
+ mPrefix = prefix;
+ mPluginInstanceDialog = pluginType;
+
+ setTitle(mResource.getString(mPrefix+"_TITLE"));
+ setSize(400, 230);
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ public void setModel(CMSBaseResourceModel model)
+ {
+ mModel = model;
+ }
+
+ /**
+ * show the windows
+ * @param users list of current groups
+ */
+ public void showDialog() {
+
+ mListModel.clear();
+
+ if(!update())
+ return;
+ this.show();
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent evt) {
+
+ if (evt.getSource().equals(mOK)) {
+
+ // check selection lists
+ if (mList.getSelectedIndex() < 0) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource, "Must select default", CMSAdminUtil.ERROR_MESSAGE);
+ }
+
+ NameValuePairs response = null;
+
+ String scope = "";
+ if (mPrefix.equals("PROFILEINPUTSELDIALOG")) {
+ scope = ScopeDef.SC_PROFILE_INPUT;
+ } else if (mPrefix.equals("PROFILEOUTPUTSELDIALOG")) {
+ scope = ScopeDef.SC_PROFILE_OUTPUT;
+ }
+
+ ProfileNonPolicyNewDialog dialog =
+ new ProfileNonPolicyNewDialog(
+ response,
+ mParentFrame,
+ mConnection,
+ mExtraDestination, scope, true);
+
+ dialog.setModel(mModel);
+
+ String name = ((JLabel)mListModel.elementAt(mList.getSelectedIndex())).getText();
+
+ dialog.showDialog(response, mProfileId, getID(name));
+
+ if(!dialog.isOK()) {
+ this.dispose();
+ return;
+ }
+
+ //response = dialog.getData();
+ // String name = dialog.getRuleName();
+
+ // Debug.println(response.toString());
+
+ dialog.dispose();
+ this.dispose();
+ }
+
+ if (evt.getSource().equals(mCancel)) {
+ this.dispose();
+ }
+ if (evt.getSource().equals(mHelp)) {
+ CMSAdminUtil.help(mHelpToken);
+ }
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setArrowButtons();
+ }
+
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {
+ setArrowButtons();
+ }
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {
+ setArrowButtons();
+ }
+
+ protected void setDisplay() {
+ Debug.println("*** PluginSelectionDialog.setDisplay() - 1");
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ //create botton action panel
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, mPrefix, "OK", null, this);
+ mCancel = CMSAdminUtil.makeJButton(mResource, mPrefix, "CANCEL", null, this);
+ mHelp = CMSAdminUtil.makeJButton(mResource, mPrefix, "HELP", null, this);
+ //JButton[] buttons = { mOK, mCancel, mHelp};
+ JButton[] buttons = { mOK, mCancel};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonPanel( buttons, true);
+ }
+
+ private JPanel makeContentPane() {
+ Debug.println("*** PluginSelectionDialog.makeContentPane() - 0");
+ JPanel mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ Debug.println("*** PluginSelectionDialog.makeContentPane() - 1");
+ mListPanel.setLayout(gb);
+ //content.setBorder(CMSAdminUtil.makeEtchedBorder());
+
+ JLabel label = CMSAdminUtil.makeJLabel(mResource, mPrefix,
+ "SELECT", null);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.fill = gbc.HORIZONTAL;
+ gb.setConstraints(label, gbc);
+ mListPanel.add(label);
+
+ Debug.println("*** PluginSelectionDialog.makeContentPane() - 2");
+ mList = CMSAdminUtil.makeJList(mListModel,9);
+ mScrollPane = new JScrollPane(mList,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION );
+ mList.addMouseListener(this);
+ mScrollPane.setBackground(Color.white);
+ mScrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ return mListPanel;
+ }
+
+ //set arrow buttons
+ private void setArrowButtons() {
+
+ if (mList.getSelectedIndex()< 0) {
+ mOK.setEnabled(false);
+ return;
+ }
+
+ mOK.setEnabled(true);
+ }
+
+ //refresh the table content
+ private void refresh() {
+ //mScrollPane.invalidate();
+ //mScrollPane.validate();
+ //repaint();
+ }
+
+ //=================================================
+ // RETRIEVE INFO FROM SERVER SIDE
+ //=================================================
+
+ //save order information to the server
+ protected boolean update() {
+
+ NameValuePairs response;
+ NameValuePairs params = new NameValuePairs();
+ try {
+ response = mConnection.search(mDestination, mScope,
+ params);
+ } catch (EAdminException e) {
+ //display error dialog
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ return false;
+ }
+
+ Debug.println(response.toString());
+
+ //parse the data
+ String[] vals = new String[response.size()];
+ int i=0;
+ for (String name : response.keySet()) {
+ name = name.trim();
+ String val = response.get(name);
+ StringTokenizer st = new StringTokenizer(val, ",");
+ String className = st.nextToken();
+ String desc = st.nextToken();
+ String friendlyName = st.nextToken();
+ vals[i++] = friendlyName.trim();
+ mListData.put(name, friendlyName);
+ // vals[i++] = ((String)e.nextElement()).trim();
+ Debug.println("PluginSelectionDialog::update() - adding '"+vals[i-1]+"'");
+ }
+
+ CMSAdminUtil.bubbleSort(vals);
+
+ for (int y=0; y< vals.length ; y++) {
+ try {
+ mListModel.addElement(new JLabel(vals[y], JLabel.LEFT));
+ } catch (Exception ex) {
+ }
+ }
+
+ return true;
+ }
+
+ private String getID(String name) {
+ Enumeration keys = mListData.keys();
+ while (keys.hasMoreElements()) {
+ String key = (String)keys.nextElement();
+ String val = (String)mListData.get(key);
+ if (val.equals(name)) {
+ return key;
+ }
+ }
+ return "";
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ProfilePluginSelectionDialog.java b/base/console/src/com/netscape/admin/certsrv/config/ProfilePluginSelectionDialog.java
new file mode 100644
index 000000000..ec3bb4c7c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ProfilePluginSelectionDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.event.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Policy Plugin Selection Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ProfilePluginSelectionDialog extends PluginSelectionDialog
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "PROFILESELECTIONDIALOG";
+ private static final String HELPINDEX = "configuration-certificateprofiles";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public ProfilePluginSelectionDialog(
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType)
+ {
+ super(PREFIX, parent,conn, dest, pluginType);
+ mScope = ScopeDef.SC_PROFILE_IMPLS;
+ mInstanceScope = ScopeDef.SC_PROFILE_RULES;
+ mImageName = CMSAdminResources.IMAGE_RULE_PLUGIN;
+ mHelpToken = HELPINDEX;
+ mDataModel = new ProfileListDataModel();
+ setDisplay();
+ }
+
+ public ProfilePluginSelectionDialog(
+ JFrame parent,
+ AdminConnection conn,
+ String dest, String extraDest,
+ CMSPluginInstanceTab pluginType)
+ {
+ super(PREFIX, parent,conn, dest, extraDest, pluginType);
+ mScope = ScopeDef.SC_PROFILE_IMPLS;
+ mInstanceScope = ScopeDef.SC_PROFILE_RULES;
+ mImageName = CMSAdminResources.IMAGE_RULE_PLUGIN;
+ mHelpToken = HELPINDEX;
+ mDataModel = new ProfileListDataModel();
+ setDisplay();
+ }
+
+ public void actionPerformed(ActionEvent evt) {
+
+ if (evt.getSource().equals(mOK)) {
+ NameValuePairs response;
+ try {
+ response = getDefaultConfig();
+ } catch (EAdminException e) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ Debug.println(response.toString());
+ String id =(String)(((ProfileListDataModel)mDataModel).getObjectValueAt(mList.getSelectedIndex()));
+ response.put(Constants.PR_POLICY_IMPL_NAME, id);
+
+ CMSBaseConfigDialog dialog = null;
+ if (mExtraDestination == null) {
+ dialog = mPluginInstanceDialog.makeNewConfigDialog(
+ response, mParentFrame, mConnection, mDestination);
+ } else {
+ dialog = mPluginInstanceDialog.makeNewConfigDialog(
+ response, mParentFrame, mConnection, mExtraDestination);
+ }
+
+ dialog.setModel(mModel);
+ dialog.setInstanceScope(mInstanceScope);
+
+ dialog.showDialog(response,"");
+
+ if(!dialog.isOK()) {
+ this.dispose();
+ return;
+ }
+
+ response = dialog.getData();
+ String name = dialog.getRuleName();
+
+ Debug.println(response.toString());
+
+ dialog.dispose();
+ this.dispose();
+ }
+
+
+ if (evt.getSource().equals(mCancel)) {
+ this.dispose();
+ }
+ if (evt.getSource().equals(mHelp)) {
+ CMSAdminUtil.help(mHelpToken);
+ }
+ }
+
+ //this returns the default configuration
+ protected NameValuePairs getDefaultConfig() throws EAdminException {
+ String id = (String)(((ProfileListDataModel)mDataModel).getObjectValueAt(mList.getSelectedIndex()));
+ NameValuePairs response;
+ response = mConnection.read(mDestination, mScope, id,
+ new NameValuePairs());
+
+ Debug.println(response.toString());
+
+ return response;
+ }
+
+ //save order information to the server
+ protected boolean update() {
+
+ NameValuePairs response;
+ try {
+ response = mConnection.search(mDestination, mScope,
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ return false;
+ }
+
+ Debug.println(response.toString());
+
+ //parse the data
+ String[] classnames = new String[response.size()];
+ String[] ids = new String[response.size()];
+ int i=0;
+ for (String id : response.keySet()) {
+ String value = response.get(id);
+ int pos = value.lastIndexOf(",");
+ String className = value.substring(pos+1);
+
+ classnames[i] = className;
+ ids[i++] = id;
+ Debug.println("PluginSelectionDialog::update() - adding '"+classnames[i-1]+"'");
+ }
+
+ CMSAdminUtil.bubbleSort(classnames, ids);
+
+ for (int y=0; y< classnames.length ; y++) {
+ try {
+ ((ProfileListDataModel)mDataModel).addElement(new JLabel(classnames[y],
+ CMSAdminUtil.getImage(mImageName), JLabel.LEFT), ids[y]);
+ }
+ catch (Exception ex) {
+ Debug.println("PluginSelectionDialog could not get image for '"+
+ mImageName+"'. Adding without image");
+ ((ProfileListDataModel)mDataModel).addElement(new JLabel(classnames[y],
+ JLabel.LEFT), ids[y]);
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ProfilePolicyEditDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/ProfilePolicyEditDataModel.java
new file mode 100644
index 000000000..7b306d1da
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ProfilePolicyEditDataModel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import javax.swing.text.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Policy Parameter Configuration Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ProfilePolicyEditDataModel extends AbstractTableModel
+{
+ Vector rowData;
+ Vector columnNames;
+
+ public ProfilePolicyEditDataModel()
+ {
+ }
+
+ 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)
+ {
+ if (column == 1)
+ return true;
+ return false;
+ }
+
+ public void setValueAt(Object value, int row, int column)
+ {
+ ((Vector)rowData.elementAt(row)).setElementAt(value, column);
+ fireTableCellUpdated(row, column);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ProfilePolicyEditDialog.java b/base/console/src/com/netscape/admin/certsrv/config/ProfilePolicyEditDialog.java
new file mode 100644
index 000000000..34b95c0f1
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ProfilePolicyEditDialog.java
@@ -0,0 +1,698 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.table.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Policy Parameter Configuration Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ProfilePolicyEditDialog extends CMSBaseConfigDialog
+ implements ActionListener, FocusListener
+{
+ protected JButton mRefresh, mEdit, mAdd, mDelete, mOrder, mHelp;
+ protected JTextField mNameField=null, mIdField=null, mDescField=null, mConfigField=null;
+ protected JLabel mNameLabel=null, mIdLabel=null, mDescLabel = null, mConfigLabel =null;
+ protected JTable mConstraintTable = null;
+ protected ProfileDataTable mDefaultTable = null;
+ protected Hashtable mHelpDesc = new Hashtable();
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public ProfilePolicyEditDialog(NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest) {
+
+ super(parent, dest);
+
+ PREFIX = "PROFILEEDITDIALOG";
+ mHelpToken = "configuration-certificateprofiles";
+ mImplName_token = Constants.PR_POLICY_IMPL_NAME;
+ mImplType = Constants.PR_EXT_PLUGIN_IMPLTYPE_POLICY;
+ init(nvp,parent,conn,dest);
+ setSize(500, 415);
+ }
+
+
+ protected JPanel makeContentPane() {
+ JPanel mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ // 'Policy Rule ID' here
+ CMSAdminUtil.resetGBC(gbc);
+ mRulenameCaption = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "RULENAME", null);
+ mRulenameCaption.addMouseListener(this);
+ mPluginLabel = new JLabel();
+ mPluginLabel.setVisible(false);
+ mPluginName = new JTextField();
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add(mRulenameCaption, gbc);
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ 0,CMSAdminUtil.COMPONENT_SPACE);
+ mListPanel.add( mPluginName, gbc );
+ // mListPanel.add( mPluginLabel, gbc );
+
+ // name
+ CMSAdminUtil.resetGBC(gbc);
+ mNameLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "NAMENAME", null);
+ mNameLabel.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ // mListPanel.add( mNameLabel, gbc );
+ mNameLabel.setBackground(getBackground());
+ mNameLabel.setEnabled(false);
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mNameField = new JTextField();
+ // mListPanel.add( mNameField, gbc );
+
+ // desc
+ CMSAdminUtil.resetGBC(gbc);
+ mDescLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "DESCNAME", null);
+ // mDescLabel.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add( mDescLabel, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mDescField = new JTextField();
+ mListPanel.add( mDescField, gbc );
+
+ CMSAdminUtil.resetGBC(gbc);
+ mIdLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "IDNAME", null);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add( mIdLabel, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mIdField = new JTextField();
+ mListPanel.add( mIdField, gbc );
+
+ // config file
+/*
+ CMSAdminUtil.resetGBC(gbc);
+ mConfigLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "CONFIGNAME", null);
+ mConfigLabel.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ // mListPanel.add( mConfigLabel, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mConfigField = new JTextField();
+ // mListPanel.add( mConfigField, gbc );
+*/
+
+
+ // 'Policy Plugin ID' here
+ CMSAdminUtil.resetGBC(gbc);
+ mImplnameCaption = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "IMPLNAME", null);
+ mImplnameCaption.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ // mListPanel.add( mImplnameCaption, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mImplName = new JLabel();
+// mListPanel.add( mImplName, gbc );
+
+ /* Tab */
+ JTabbedPane tabPane = new JTabbedPane();
+ JPanel lpanel1 = createDefaultListPanel();
+ JPanel lpanel2 = createConstraintListPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.BOTH;
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(tabPane, gbc);
+ tabPane.addTab("Default", lpanel1);
+ tabPane.addTab("Constraint", lpanel2);
+ mListPanel.add(tabPane);
+
+ /* Panel for list of plugin's parameters */
+ mParamPanel = new JPanel();
+/*
+ mScrollPane = new JScrollPane(mParamPanel);
+ mScrollPane.setBorder(CMSAdminUtil.makeEtchedBorder());
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.BOTH;
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+*/
+
+ /* Panel in which to put plugin's help text */
+ mHelpPanel = new JPanel();
+ mHelpPanel.setBorder(CMSAdminUtil.makeEtchedBorder());
+ mHelpLabel = new JTextArea(3,0);
+ mHelpLabel.setLineWrap(true);
+ mHelpLabel.setWrapStyleWord(true);
+ mHelpLabel.setBackground(mHelpPanel.getBackground());
+ mHelpLabel.setEditable(false);
+ GridBagLayout gb2 = new GridBagLayout();
+ GridBagConstraints gbc2 = new GridBagConstraints();
+
+ CMSAdminUtil.resetGBC(gbc2);
+ gbc2.fill = gbc.BOTH;
+ gbc2.anchor = gbc.WEST;
+ gbc2.gridwidth = gbc.REMAINDER;
+ gbc2.weightx = 1.0;
+ gbc2.weighty = 1.0;
+ gb2.setConstraints(mHelpLabel, gbc2);
+ mHelpPanel.setLayout(gb2);
+ mHelpPanel.add(mHelpLabel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.SOUTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gb.setConstraints(mHelpPanel, gbc);
+ mListPanel.add(mHelpPanel);
+
+ return mListPanel;
+ }
+
+ public JPanel createDefaultListPanel()
+ {
+ Vector colNames = new Vector();
+ colNames.addElement("Parameter");
+ colNames.addElement("Value");
+ Vector data = new Vector();
+ Vector row = new Vector();
+ row.addElement("x");
+ row.addElement("x");
+ data.addElement(row);
+
+ JPanel mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ //center table
+ ProfilePolicyEditDataModel model = new ProfilePolicyEditDataModel();
+ model.setInfo(data, colNames);
+ mDefaultTable = new ProfileDataTable(model);
+ JScrollPane mScrollPane = JTable.createScrollPaneForTable(mDefaultTable);
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mDefaultTable.setAutoscrolls(true);
+ mDefaultTable.sizeColumnsToFit(true);
+ mDefaultTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ // mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ mDefaultTable.addMouseListener(this);
+// setLabelCellRenderer(mDefaultTable,1);
+//setLabelCellEditor(mDefaultTable, 1);
+ mDefaultTable.setDefaultRenderer(JComponent.class, new JComponentCellRenderer());
+ mDefaultTable.setDefaultEditor(JComponent.class,
+ new ProfileComponentCellEditor());
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ // gbc.gridwidth = 1;
+ // gbc.weightx = 1.0;
+ gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+/*
+ JPanel buttonPanel = createUserButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ mListPanel.add(buttonPanel);
+*/
+
+ return mListPanel;
+ }
+
+ public JPanel createConstraintListPanel()
+ {
+ Vector colNames = new Vector();
+ colNames.addElement("Parameter");
+ colNames.addElement("Value");
+ Vector data = new Vector();
+ Vector row = new Vector();
+ row.addElement("x");
+ row.addElement("x");
+ data.addElement(row);
+
+ JPanel mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ //center table
+ ProfilePolicyEditDataModel model = new ProfilePolicyEditDataModel();
+ model.setInfo(data, colNames);
+ mConstraintTable = new ProfileDataTable(model);
+ JScrollPane mScrollPane = JTable.createScrollPaneForTable(mConstraintTable);
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mConstraintTable.setAutoscrolls(true);
+ mConstraintTable.sizeColumnsToFit(true);
+ mConstraintTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ // mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ mConstraintTable.addMouseListener(this);
+// setLabelCellRenderer(mConstraintTable,0);
+ mConstraintTable.setDefaultRenderer(JComponent.class, new JComponentCellRenderer());
+ mConstraintTable.setDefaultEditor(JComponent.class,
+ new ProfileComponentCellEditor());
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ // gbc.gridwidth = 1;
+ // gbc.weightx = 1.0;
+ gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+/*
+ JPanel buttonPanel = createUserButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ mListPanel.add(buttonPanel);
+*/
+
+ return mListPanel;
+ }
+
+ protected JPanel createUserButtonPanel() {
+ Debug.println("CMSPluginInstanceTab::createUserButtonPanel()");
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mEdit = CMSAdminUtil.makeJButton(mResource, PREFIX, "EDIT", null, this);
+ mAdd = CMSAdminUtil.makeJButton(mResource, PREFIX, "ADD", null, this);
+ mDelete = CMSAdminUtil.makeJButton(mResource, PREFIX, "DELETE", null, this);
+ JButton[] buttons = {mAdd, mDelete, mEdit};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ public void actionPerformed(ActionEvent evt) {
+ if (evt.getSource().equals(mHelp)) {
+ CMSAdminUtil.help(mHelpToken);
+ }
+
+ if (evt.getSource().equals(mAdd)) {
+/*
+ Debug.println("Add");
+ PluginSelectionDialog dialog =
+ getPluginSelectionDialog(
+ mModel.getFrame(),
+ mConnection,
+ mDestination,
+ this
+ );
+
+ dialog.setModel(mModel);
+ dialog.showDialog();
+ refresh();
+*/
+ }
+ if (evt.getSource().equals(mDelete)) {
+ }
+ if (evt.getSource().equals(mEdit)) {
+ }
+
+ if (evt.getSource().equals(mOK)) {
+
+ try {
+ if (mModel != null) { mModel.progressStart(); }
+
+ NameValuePairs nvp = new NameValuePairs();
+ String instanceName = mPluginName.getText();
+
+ String policyId = mDescField.getText() + ":" + mIdField.getText();
+ String name = instanceName + ";" + policyId;
+
+/*
+ nvp.add("impl", mImplName.getText());
+ nvp.add("name", mNameField.getText());
+ nvp.add("desc", mDescField.getText());
+ nvp.add("config", mConfigField.getText());
+*/
+
+ for (int i = 0; i < mDefaultTable.getRowCount(); i++) {
+ JComponent comp = (JComponent)mDefaultTable.getValueAt(i,1);
+ String val = null;
+ if (comp instanceof JTextField) {
+ val = ((JTextField)comp).getText().trim();
+ } else if (comp instanceof JComboBox) {
+ val = (String)(((JComboBox)comp).getSelectedItem());
+ }
+ String name1 = ((JLabel)(mDefaultTable.getValueAt(i,0))).getText();
+ nvp.put(name1, val);
+ }
+
+
+ //mAdminConnection.modify(DestDef.DEST_CA_PROFILE_ADMIN,
+ mAdminConnection.modify(mDest,
+ ScopeDef.SC_PROFILE_DEFAULT_POLICY, name, nvp);
+
+ mIsOK = true;
+ if (mModel != null) { mModel.progressStop(); }
+
+ nvp = new NameValuePairs();
+ for (int i = 0; i < mConstraintTable.getRowCount(); i++) {
+
+ JComponent comp = (JComponent)mConstraintTable.getValueAt(i,1);
+ String val = null;
+ if (comp instanceof JTextField) {
+ val = ((JTextField)comp).getText().trim();
+ } else if (comp instanceof JComboBox) {
+ val = (String)(((JComboBox)comp).getSelectedItem());
+ }
+
+ String name1 = ((JLabel)(mConstraintTable.getValueAt(i,0))).getText();
+ nvp.put(name1, val);
+ }
+ instanceName = mPluginName.getText();
+//DestDef.DEST_CA_PROFILE_ADMIN,
+ mAdminConnection.modify(mDest,
+ ScopeDef.SC_PROFILE_CONSTRAINT_POLICY, name, nvp);
+
+ this.dispose();
+ }
+ catch (EAdminException ex) {
+ mModel.progressStop();
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ ex.toString(),CMSAdminUtil.ERROR_MESSAGE);
+ }
+ }
+
+ if (evt.getSource().equals(mCancel)) {
+ this.dispose();
+ }
+
+ }
+
+ private String getHelpDescription(String value) {
+ int start_pos = value.indexOf(';');
+ int end_pos = value.lastIndexOf(';');
+ int end1_pos = value.lastIndexOf(';',end_pos-1);
+ String syntax = null;
+ String syntaxVal = null;
+ String v = null;
+ syntax = value.substring(0,start_pos);
+ syntaxVal = value.substring(start_pos+1, end_pos);
+ v = value.substring(end1_pos+1,end_pos);
+ return v;
+ }
+
+ private Object getComponent(String value) {
+ int start_pos = value.indexOf(';');
+ int end_pos = value.lastIndexOf(';');
+ int end1_pos = value.lastIndexOf(';',end_pos-1);
+ String syntax = null;
+ String syntaxVal = null;
+ String v = null;
+
+ syntax = value.substring(0,start_pos);
+ syntaxVal = value.substring(start_pos+1, end1_pos);
+ v = value.substring(end_pos+1);
+/*
+ StringTokenizer st = new StringTokenizer(value, ";");
+ while (st.hasMoreTokens()) {
+ try {
+ syntax = st.nextToken();
+ syntaxVal = st.nextToken();
+ v = st.nextToken();
+ } catch (Exception e) {
+ }
+ }
+*/
+
+ if (syntax != null) {
+ return CMSAdminUtil.createTableCell(syntax, syntaxVal, v);
+ }
+
+ return null;
+ }
+
+ public void showDialog(NameValuePairs data, String name) {
+
+ mHelpDesc.clear();
+
+ mModel.progressStart();
+
+ StringTokenizer st = new StringTokenizer(name, ";");
+ String profileId = st.nextToken();
+ String policyId = st.nextToken();
+ StringTokenizer st1 = new StringTokenizer(policyId, ":");
+ String setid = st1.nextToken();
+ String pid = st1.nextToken();
+
+ // retrieve profile information
+ NameValuePairs response = null;
+ NameValuePairs request = new NameValuePairs();
+ try {
+ //response = mAdminConnection.read(DestDef.DEST_CA_PROFILE_ADMIN,
+ response = mAdminConnection.read(mDest,
+ ScopeDef.SC_PROFILE_DEFAULT_POLICY,
+ name, request);
+ } catch (EAdminException e) {
+// CMSAdminUtil.showErrorDialog(mParentFrame, mResource, e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+
+ Vector defcolNames = new Vector();
+ defcolNames.addElement("Parameter");
+ defcolNames.addElement("Value");
+ Vector defdata = new Vector();
+
+ for (String entry : response.keySet()) {
+ entry = entry.trim();
+ String value = response.get(entry);
+ Debug.println("ProfilePolicyEditDialog entry= "+entry);
+ Debug.println("ProfilePolicyEditDialog value= "+value);
+
+ Object obj = getComponent(value);
+ Vector row = new Vector();
+ JLabel label = new JLabel(entry);
+ ((Component)obj).addFocusListener(this);
+ mHelpDesc.put(obj, getHelpDescription(value));
+ row.addElement(label);
+ row.addElement(obj);
+ defdata.addElement(row);
+ }
+ ProfilePolicyEditDataModel defmodel = new ProfilePolicyEditDataModel();
+ defmodel.setInfo(defdata, defcolNames);
+ mDefaultTable.setModel(defmodel);
+
+ if (response != null) {
+ mPluginName.setText(profileId);
+ mPluginName.setBackground(getBackground());
+ mPluginName.setEnabled(false);
+ mNameField.setText(response.get("name"));
+ mDescField.setText(setid);
+ mDescField.setBackground(getBackground());
+ mDescField.setEnabled(false);
+ mIdField.setText(pid);
+ mIdField.setBackground(getBackground());
+ mIdField.setEnabled(false);
+ }
+
+ // retrieve policy information
+ mModel.progressStart();
+ try {
+ //response = mAdminConnection.read(DestDef.DEST_CA_PROFILE_ADMIN,
+ response = mAdminConnection.read(mDest,
+ ScopeDef.SC_PROFILE_CONSTRAINT_POLICY,
+ name,
+ request);
+ } catch (EAdminException e) {
+// CMSAdminUtil.showErrorDialog(mParentFrame, mResource, e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+
+ Vector colNames = new Vector();
+ colNames.addElement("Parameter");
+ colNames.addElement("Value");
+ Vector d = new Vector();
+
+ for (String entry : response.keySet()) {
+ entry = entry.trim();
+ String value = response.get(entry);
+ Debug.println("entry= "+entry);
+ Debug.println("value= "+value);
+
+ Object obj = getComponent(value);
+ Vector row = new Vector();
+ JLabel label = new JLabel(entry);
+ ((Component)obj).addFocusListener(this);
+ mHelpDesc.put(obj, getHelpDescription(value));
+ row.addElement(label);
+ row.addElement(obj);
+ d.addElement(row);
+ }
+ ProfilePolicyEditDataModel model = new ProfilePolicyEditDataModel();
+ model.setInfo(d, colNames);
+ mConstraintTable.setModel(model);
+
+ this.show();
+ }
+
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(
+ new DefaultTableCellRenderer());
+ }
+
+ protected void setLabelCellEditor(JTable table, int index) {
+/*
+ table.getColumnModel().getColumn(index).setCellRenderer(
+ new PasswordCellRenderer());
+*/
+ table.getColumnModel().getColumn(index).setCellEditor(
+ new DefaultCellEditor(new JTextField()));
+ }
+
+ class JComponentCellRenderer implements TableCellRenderer {
+ public Component getTableCellRendererComponent(JTable table,
+ Object value, boolean isSelected, boolean hasFocus, int row,
+ int column) {
+ return (JComponent)value;
+ }
+ }
+
+ /**
+ * From focuslistener interface. This lets us know when a component
+ * has received focus, so we can update the help text.
+ */
+ public void focusGained(FocusEvent f) {
+ Debug.println("focusGained");
+ Component comp = f.getComponent();
+ String desc = (String)mHelpDesc.get(comp);
+ if (desc != null) {
+ mHelpLabel.setText(desc);
+ }
+ }
+
+ /** need to supply this method for focuslistener, but we
+ * really don't care about it
+ */
+ public void focusLost(FocusEvent f) {
+ Debug.println("focusLost");
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ProfilePolicyNewDialog.java b/base/console/src/com/netscape/admin/certsrv/config/ProfilePolicyNewDialog.java
new file mode 100644
index 000000000..941917808
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ProfilePolicyNewDialog.java
@@ -0,0 +1,714 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.table.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Policy Parameter Configuration Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ProfilePolicyNewDialog extends CMSBaseConfigDialog
+ implements ActionListener, FocusListener
+{
+ protected JButton mRefresh, mEdit, mAdd, mDelete, mOrder, mHelp;
+ protected JTextField mNameField=null, mIdField=null, mDescField=null, mConfigField=null;
+ protected JLabel mNameLabel=null, mIdLabel=null, mDescLabel = null, mConfigLabel =null;
+ protected JTable mDefaultTable = null, mConstraintTable = null;
+
+ private String mConstraintId = null, mDefaultId = null;
+
+ public String mDefSetId = null;
+ protected Hashtable mHelpDesc = new Hashtable();
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public ProfilePolicyNewDialog(String defSetId, NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest) {
+
+ super(parent, dest);
+
+ mDefSetId = defSetId;
+ PREFIX = "PROFILENEWDIALOG";
+ mHelpToken = "configuration-certificateprofiles";
+ mImplName_token = Constants.PR_POLICY_IMPL_NAME;
+ mImplType = Constants.PR_EXT_PLUGIN_IMPLTYPE_POLICY;
+
+ init(nvp,parent,conn,dest);
+ setSize(500, 415);
+ }
+
+
+ protected JPanel makeContentPane() {
+ JPanel mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ // 'Policy Rule ID' here
+ CMSAdminUtil.resetGBC(gbc);
+ mRulenameCaption = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "RULENAME", null);
+ mRulenameCaption.addMouseListener(this);
+ mPluginLabel = new JLabel();
+ mPluginLabel.setVisible(false);
+ mPluginName = new JTextField();
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add(mRulenameCaption, gbc);
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ 0,CMSAdminUtil.COMPONENT_SPACE);
+ mListPanel.add( mPluginName, gbc );
+ // mListPanel.add( mPluginLabel, gbc );
+
+ // name
+ CMSAdminUtil.resetGBC(gbc);
+ mNameLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "NAMENAME", null);
+ mNameLabel.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ // mListPanel.add( mNameLabel, gbc );
+ mNameLabel.setBackground(getBackground());
+ mNameLabel.setEnabled(false);
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mNameField = new JTextField();
+ // mListPanel.add( mNameField, gbc );
+
+ // desc
+ CMSAdminUtil.resetGBC(gbc);
+ mDescLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "DESCNAME", null);
+ // mDescLabel.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add( mDescLabel, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mDescField = new JTextField();
+ mListPanel.add( mDescField, gbc );
+
+
+ CMSAdminUtil.resetGBC(gbc);
+ mIdLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "IDNAME", null);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add( mIdLabel, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mIdField = new JTextField();
+ mListPanel.add( mIdField, gbc );
+
+ // config file
+/*
+ CMSAdminUtil.resetGBC(gbc);
+ mConfigLabel = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "CONFIGNAME", null);
+ mConfigLabel.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ // mListPanel.add( mConfigLabel, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mConfigField = new JTextField();
+ // mListPanel.add( mConfigField, gbc );
+*/
+
+
+ // 'Policy Plugin ID' here
+ CMSAdminUtil.resetGBC(gbc);
+ mImplnameCaption = CMSAdminUtil.makeJLabel(mResource, PREFIX,
+ "IMPLNAME", null);
+ mImplnameCaption.addMouseListener(this);
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ // mListPanel.add( mImplnameCaption, gbc );
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ mImplName = new JLabel();
+// mListPanel.add( mImplName, gbc );
+
+ /* Tab */
+ JTabbedPane tabPane = new JTabbedPane();
+ JPanel lpanel1 = createDefaultListPanel();
+ JPanel lpanel2 = createConstraintListPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.BOTH;
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(tabPane, gbc);
+ tabPane.addTab("Default", lpanel1);
+ tabPane.addTab("Constraint", lpanel2);
+ mListPanel.add(tabPane);
+
+ /* Panel for list of plugin's parameters */
+ mParamPanel = new JPanel();
+/*
+ mScrollPane = new JScrollPane(mParamPanel);
+ mScrollPane.setBorder(CMSAdminUtil.makeEtchedBorder());
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.BOTH;
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+*/
+
+ /* Panel in which to put plugin's help text */
+ mHelpPanel = new JPanel();
+ mHelpPanel.setBorder(CMSAdminUtil.makeEtchedBorder());
+ mHelpLabel = new JTextArea(3,0);
+ mHelpLabel.setLineWrap(true);
+ mHelpLabel.setWrapStyleWord(true);
+ mHelpLabel.setBackground(mHelpPanel.getBackground());
+ mHelpLabel.setEditable(false);
+ GridBagLayout gb2 = new GridBagLayout();
+ GridBagConstraints gbc2 = new GridBagConstraints();
+
+ CMSAdminUtil.resetGBC(gbc2);
+ gbc2.fill = gbc.BOTH;
+ gbc2.anchor = gbc.WEST;
+ gbc2.gridwidth = gbc.REMAINDER;
+ gbc2.weightx = 1.0;
+ gbc2.weighty = 1.0;
+ gb2.setConstraints(mHelpLabel, gbc2);
+ mHelpPanel.setLayout(gb2);
+ mHelpPanel.add(mHelpLabel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.SOUTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gb.setConstraints(mHelpPanel, gbc);
+ mListPanel.add(mHelpPanel);
+
+ return mListPanel;
+ }
+
+ public JPanel createDefaultListPanel()
+ {
+ Vector colNames = new Vector();
+ colNames.addElement("Parameter");
+ colNames.addElement("Value");
+ Vector data = new Vector();
+ Vector row = new Vector();
+ row.addElement("x");
+ row.addElement("x");
+ data.addElement(row);
+
+ JPanel mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ //center table
+ ProfilePolicyEditDataModel model = new ProfilePolicyEditDataModel();
+ model.setInfo(data, colNames);
+ mDefaultTable = new ProfileDataTable(model);
+ JScrollPane mScrollPane = JTable.createScrollPaneForTable(mDefaultTable);
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mDefaultTable.setAutoscrolls(true);
+ mDefaultTable.sizeColumnsToFit(true);
+ mDefaultTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ // mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ mDefaultTable.addMouseListener(this);
+ mDefaultTable.setDefaultRenderer(JComponent.class, new JComponentCellRenderer());
+ mDefaultTable.setDefaultEditor(JComponent.class, new ProfileComponentCellEditor());
+
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ // gbc.gridwidth = 1;
+ // gbc.weightx = 1.0;
+ gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+/*
+ JPanel buttonPanel = createUserButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ mListPanel.add(buttonPanel);
+*/
+
+ return mListPanel;
+ }
+
+ public JPanel createConstraintListPanel()
+ {
+ Vector colNames = new Vector();
+ colNames.addElement("Parameter");
+ colNames.addElement("Value");
+ Vector data = new Vector();
+ Vector row = new Vector();
+ row.addElement("x");
+ row.addElement("x");
+ data.addElement(row);
+
+ JPanel mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ //center table
+ ProfilePolicyEditDataModel model = new ProfilePolicyEditDataModel();
+ model.setInfo(data, colNames);
+ mConstraintTable = new ProfileDataTable(model);
+ JScrollPane mScrollPane = JTable.createScrollPaneForTable(mConstraintTable);
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mConstraintTable.setAutoscrolls(true);
+ mConstraintTable.sizeColumnsToFit(true);
+ mConstraintTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ // mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ mConstraintTable.addMouseListener(this);
+ mConstraintTable.setDefaultRenderer(JComponent.class, new JComponentCellRenderer());
+ mConstraintTable.setDefaultEditor(JComponent.class, new ProfileComponentCellEditor());
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ // gbc.gridwidth = 1;
+ // gbc.weightx = 1.0;
+ gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+/*
+ JPanel buttonPanel = createUserButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ mListPanel.add(buttonPanel);
+*/
+
+ return mListPanel;
+ }
+
+ protected JPanel createUserButtonPanel() {
+ Debug.println("CMSPluginInstanceTab::createUserButtonPanel()");
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mEdit = CMSAdminUtil.makeJButton(mResource, PREFIX, "EDIT", null, this);
+ mAdd = CMSAdminUtil.makeJButton(mResource, PREFIX, "ADD", null, this);
+ mDelete = CMSAdminUtil.makeJButton(mResource, PREFIX, "DELETE", null, this);
+ JButton[] buttons = {mAdd, mDelete, mEdit};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ public void actionPerformed(ActionEvent evt) {
+
+ if (evt.getSource().equals(mHelp)) {
+ CMSAdminUtil.help(mHelpToken);
+ }
+ if (evt.getSource().equals(mAdd)) {
+/*
+ Debug.println("Add");
+ PluginSelectionDialog dialog =
+ getPluginSelectionDialog(
+ mModel.getFrame(),
+ mConnection,
+ mDestination,
+ this
+ );
+
+ dialog.setModel(mModel);
+ dialog.showDialog();
+ refresh();
+*/
+ }
+ if (evt.getSource().equals(mDelete)) {
+ }
+ if (evt.getSource().equals(mEdit)) {
+ }
+
+ if (evt.getSource().equals(mOK)) {
+ try {
+ String policySetStr = mDescField.getText().trim();
+ String policyIDStr = mIdField.getText().trim();
+ if (policySetStr == null || policySetStr.length() == 0) {
+ String msg = mResource.getString(
+ PREFIX+"_DIALOG_BLANKPOLICYSET_MESSAGE");
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ msg ,CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ if (policyIDStr == null || policyIDStr.length() == 0) {
+ String msg = mResource.getString(
+ PREFIX+"_DIALOG_BLANKPOLICYID_MESSAGE");
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ msg ,CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ if (mModel != null) { mModel.progressStart(); }
+
+ NameValuePairs nvp = new NameValuePairs();
+ String instanceName = mPluginName.getText().trim();
+
+ // create policy
+ String policyId = policySetStr + ":" + policyIDStr;
+ String name = instanceName + ";" + policyId + ";" + mDefaultId + ";" + mConstraintId;
+ //mAdminConnection.add(DestDef.DEST_CA_PROFILE_ADMIN,
+ mAdminConnection.add(mDest,
+ ScopeDef.SC_PROFILE_POLICIES, name, nvp);
+
+/*
+ nvp.add("impl", mImplName.getText());
+ nvp.add("name", mNameField.getText());
+ nvp.add("desc", mDescField.getText());
+ nvp.add("config", mConfigField.getText());
+*/
+
+ for (int i = 0; i < mDefaultTable.getRowCount(); i++) {
+ JComponent comp = (JComponent)mDefaultTable.getValueAt(i,1);
+ String val = null;
+ if (comp instanceof JTextField) {
+ val = ((JTextField)comp).getText().trim();
+ } else if (comp instanceof JComboBox) {
+ val = (String)(((JComboBox)comp).getSelectedItem());
+ }
+ String name1 = ((JLabel)(mDefaultTable.getValueAt(i,0))).getText();
+ nvp.put(name1, val);
+ }
+
+
+ //mAdminConnection.add(DestDef.DEST_CA_PROFILE_ADMIN,
+ mAdminConnection.add(mDest,
+ ScopeDef.SC_PROFILE_DEFAULT_POLICY, name, nvp);
+
+ mIsOK = true;
+ if (mModel != null) { mModel.progressStop(); }
+
+ nvp = new NameValuePairs();
+ for (int i = 0; i < mConstraintTable.getRowCount(); i++) {
+ JComponent comp = (JComponent)mConstraintTable.getValueAt(i,1);
+ String val = null;
+ if (comp instanceof JTextField) {
+ val = ((JTextField)comp).getText().trim();
+ } else if (comp instanceof JComboBox) {
+ val = (String)(((JComboBox)comp).getSelectedItem());
+ }
+
+ String name1 = ((JLabel)(mConstraintTable.getValueAt(i,0))).getText();
+ nvp.put(name1, val);
+ }
+ instanceName = mPluginName.getText();
+ //mAdminConnection.add(DestDef.DEST_CA_PROFILE_ADMIN,
+ mAdminConnection.add(mDest,
+ ScopeDef.SC_PROFILE_CONSTRAINT_POLICY, name, nvp);
+
+ this.dispose();
+ }
+ catch (EAdminException ex) {
+ mModel.progressStop();
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ ex.toString(),CMSAdminUtil.ERROR_MESSAGE);
+ }
+ }
+
+ if (evt.getSource().equals(mCancel)) {
+ this.dispose();
+ }
+
+ }
+
+ public void showDialog(NameValuePairs data, String name) {
+
+ mModel.progressStart();
+
+ // name = profileId;defId;configid
+ StringTokenizer st = new StringTokenizer(name, ";");
+ String profileId = st.nextToken();
+ String defId = st.nextToken();
+ String conId = st.nextToken();
+
+ mDefaultId = defId;
+ mConstraintId = conId;
+
+ // retrieve profile information
+ NameValuePairs response = null;
+ NameValuePairs request = new NameValuePairs();
+ try {
+ name = profileId + ";" + defId;
+ response = mAdminConnection.read(DestDef.DEST_REGISTRY_ADMIN,
+ ScopeDef.SC_PROFILE_DEFAULT_POLICY,
+ defId, request);
+ } catch (EAdminException e) {
+// CMSAdminUtil.showErrorDialog(mParentFrame, mResource, e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+
+ Vector defcolNames = new Vector();
+ defcolNames.addElement("Parameter");
+ defcolNames.addElement("Value");
+ Vector defdata = new Vector();
+
+ for (String entry : response.keySet()) {
+ entry = entry.trim();
+ String value = response.get(entry);
+ Debug.println("entry= "+entry);
+ Debug.println("value= "+value);
+
+ Object obj = getComponent(value);
+ Vector row = new Vector();
+ ((Component)obj).addFocusListener(this);
+ mHelpDesc.put(obj, getHelpDescription(value));
+ row.addElement(new JLabel(entry));
+ row.addElement(obj);
+ defdata.addElement(row);
+ }
+ ProfilePolicyEditDataModel defmodel = new ProfilePolicyEditDataModel();
+ defmodel.setInfo(defdata, defcolNames);
+ mDefaultTable.setModel(defmodel);
+
+ if (response != null) {
+ mPluginName.setText(profileId);
+ mPluginName.setBackground(getBackground());
+ mPluginName.setEnabled(false);
+ mNameField.setText(response.get("name"));
+ mDescField.setText(response.get("desc"));
+ }
+
+ // retrieve policy information
+ mModel.progressStart();
+ try {
+ name = profileId + ";" + conId;
+ response = mAdminConnection.read(DestDef.DEST_REGISTRY_ADMIN,
+ ScopeDef.SC_PROFILE_CONSTRAINT_POLICY,
+ conId,
+ request);
+ } catch (EAdminException e) {
+// CMSAdminUtil.showErrorDialog(mParentFrame, mResource, e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+
+ Vector colNames = new Vector();
+ colNames.addElement("Parameter");
+ colNames.addElement("Value");
+ Vector d = new Vector();
+
+ for (String entry : response.keySet()) {
+ entry = entry.trim();
+ String value = response.get(entry);
+ Debug.println("entry= "+entry);
+ Debug.println("value= "+value);
+
+ Object obj = getComponent(value);
+ Vector row = new Vector();
+ ((Component)obj).addFocusListener(this);
+ mHelpDesc.put(obj, getHelpDescription(value));
+ row.addElement(new JLabel(entry));
+ row.addElement(obj);
+ d.addElement(row);
+ }
+ ProfilePolicyEditDataModel model = new ProfilePolicyEditDataModel();
+ model.setInfo(d, colNames);
+ mConstraintTable.setModel(model);
+
+ String desc = mDescField.getText();
+ if (desc == null || desc.equals("")) {
+ if (mDefSetId != null) {
+ mDescField.setText(mDefSetId);
+ }
+ }
+
+ this.show();
+ }
+
+ protected void setLabelCellEditor(JTable table, int index) {
+/*
+ table.getColumnModel().getColumn(index).setCellRenderer(
+ new PasswordCellRenderer());
+*/
+ table.getColumnModel().getColumn(index).setCellEditor(
+ new DefaultCellEditor(new JTextField()));
+ }
+
+ class JComponentCellRenderer implements TableCellRenderer {
+ public Component getTableCellRendererComponent(JTable table,
+ Object value, boolean isSelected, boolean hasFocus, int row,
+ int column) {
+ return (JComponent)value;
+ }
+ }
+
+ private Object getComponent(String value) {
+ int start_pos = value.indexOf(';');
+ int end_pos = value.lastIndexOf(';');
+ int end1_pos = value.lastIndexOf(';',end_pos-1);
+ String syntax = null;
+ String syntaxVal = null;
+ String v = null;
+
+ syntax = value.substring(0,start_pos);
+ syntaxVal = value.substring(start_pos+1, end1_pos);
+ v = value.substring(end_pos+1);
+/*
+ StringTokenizer st = new StringTokenizer(value, ";");
+ String syntax = null;
+ String syntaxVal = null;
+ String v = null;
+ while (st.hasMoreTokens()) {
+ try {
+ syntax = st.nextToken();
+ syntaxVal = st.nextToken();
+ v = st.nextToken();
+ } catch (Exception e) {
+ }
+ }
+*/
+ if (syntax != null) {
+ return CMSAdminUtil.createTableCell(syntax, syntaxVal, v);
+ }
+
+ return null;
+ }
+
+ private String getHelpDescription(String value) {
+ int start_pos = value.indexOf(';');
+ int end_pos = value.lastIndexOf(';');
+ int end1_pos = value.lastIndexOf(';',end_pos-1);
+ String syntax = null;
+ String syntaxVal = null;
+ String v = null;
+ syntax = value.substring(0,start_pos);
+ syntaxVal = value.substring(start_pos+1, end_pos);
+ v = value.substring(end1_pos+1,end_pos);
+ return v;
+ }
+
+ /**
+ * From focuslistener interface. This lets us know when a component
+ * has received focus, so we can update the help text.
+ */
+ public void focusGained(FocusEvent f) {
+ Debug.println("focusGained");
+ Component comp = f.getComponent();
+ String desc = (String)mHelpDesc.get(comp);
+ if (desc != null) {
+ mHelpLabel.setText(desc);
+ }
+ }
+
+ /** need to supply this method for focuslistener, but we
+ * really don't care about it
+ */
+ public void focusLost(FocusEvent f) {
+ Debug.println("focusLost");
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ProfilePolicySelectionDialog.java b/base/console/src/com/netscape/admin/certsrv/config/ProfilePolicySelectionDialog.java
new file mode 100644
index 000000000..44fe9886b
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ProfilePolicySelectionDialog.java
@@ -0,0 +1,515 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Plugin Selection Dialog
+ *
+ * @author Jack Pan-chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ProfilePolicySelectionDialog extends JDialog
+ implements ActionListener, MouseListener, ListSelectionListener
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ protected JFrame mParentFrame;
+ protected AdminConnection mConnection;
+ protected ResourceBundle mResource;
+ protected DefaultListModel mConstraintModel;
+ protected DefaultListModel mDefaultModel;
+ protected String mDestination; //dest flag
+
+ private JScrollPane mScrollPane;
+ protected JList mDefaultList, mConstraintList;
+ protected Hashtable mDefaultData, mConstraintData;
+ protected JLabel mDefaultLabel, mConstraintLabel;
+ protected JButton mOK, mCancel, mHelp;
+ protected String mDefSetId;
+ protected String mPrefix;
+ protected String mScope;
+ protected String mInstanceScope;
+ protected String mImageName;
+ protected String mProfileId;
+ protected String mHelpToken="configuration-certificateprofiles";
+ protected CMSPluginInstanceTab mPluginInstanceDialog;
+ protected CMSBaseResourceModel mModel=null;
+ protected String mExtraDestination;
+
+ public ProfilePolicySelectionDialog(
+ String defSetId,
+ String profileId,
+ String prefix,
+ JFrame parent,
+ AdminConnection conn,
+ String dest)
+ {
+ this(defSetId, profileId, prefix, parent, conn, dest, null, null);
+ }
+
+ public ProfilePolicySelectionDialog(
+ String defSetId,
+ String profileId,
+ String prefix,
+ JFrame parent,
+ AdminConnection conn,
+ String dest, String extraDest)
+ {
+ this(defSetId, profileId, prefix,
+ parent,
+ conn,
+ dest, extraDest,
+ null );
+ }
+
+ public ProfilePolicySelectionDialog(
+ String defSetId,
+ String profileId,
+ String prefix,
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType) {
+ this(defSetId, profileId, prefix, parent, conn, dest, null, pluginType);
+ }
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public ProfilePolicySelectionDialog(
+ String defSetId,
+ String profileId,
+ String prefix,
+ JFrame parent,
+ AdminConnection conn,
+ String dest, String extraDest,
+ CMSPluginInstanceTab pluginType)
+ {
+ super(parent,true);
+ mDefSetId = defSetId;
+ mProfileId = profileId;
+ mParentFrame = parent;
+ mConnection = conn;
+ mDestination = dest;
+ mExtraDestination = extraDest;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mDefaultModel = new DefaultListModel();
+ mConstraintModel = new DefaultListModel();
+ mDefaultData = new Hashtable();
+ mConstraintData = new Hashtable();
+ mPrefix = prefix;
+ mPluginInstanceDialog = pluginType;
+
+ setTitle(mResource.getString(mPrefix+"_TITLE"));
+ setSize(440, 250);
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ public void setModel(CMSBaseResourceModel model)
+ {
+ mModel = model;
+ }
+
+ /**
+ * show the windows
+ * @param users list of current groups
+ */
+ public void showDialog() {
+
+ mConstraintModel.clear();
+ mDefaultModel.clear();
+
+ if(!update("defaultPolicy", mDefaultModel, mDefaultData))
+ return;
+/*
+ if(!update("constraintPolicy", mConstraintModel))
+ return;
+*/
+/*
+ refresh();
+ setArrowButtons();
+*/
+ this.show();
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent evt) {
+
+ if (evt.getSource().equals(mOK)) {
+
+ // check selection lists
+ if (mDefaultList.getSelectedIndex() < 0) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource, "Must select default", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+
+ if (mConstraintList.getSelectedIndex() < 0) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource, "Must select constraint", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+
+ NameValuePairs response = null;
+/*
+ try {
+ response = getDefaultConfig();
+ } catch (EAdminException e) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ Debug.println(response.toString());
+ String id = ((JLabel)mDefaultModel.elementAt(mDefaultList.getSelectedIndex())).getText();
+ response.add(Constants.PR_POLICY_IMPL_NAME,id);
+*/
+ ProfilePolicyNewDialog dialog =
+ new ProfilePolicyNewDialog(
+ mDefSetId,
+ response,
+ mParentFrame,
+ mConnection,
+ mExtraDestination);
+
+ dialog.setModel(mModel);
+ dialog.setInstanceScope(mInstanceScope);
+
+ // profile;defClass;conClass
+ String defaultName = ((JLabel)mDefaultModel.elementAt(mDefaultList.getSelectedIndex())).getText();
+ String conName = ((JLabel)mConstraintModel.elementAt(mConstraintList.getSelectedIndex())).getText();
+
+
+ String namex = mProfileId + ";" + getID(defaultName, mDefaultData) +
+ ";" + getID(conName, mConstraintData);
+ dialog.showDialog(response,namex);
+
+ if(!dialog.isOK()) {
+ this.dispose();
+ return;
+ }
+
+ //response = dialog.getData();
+ // String name = dialog.getRuleName();
+
+ // Debug.println(response.toString());
+
+ dialog.dispose();
+ this.dispose();
+ }
+
+
+ if (evt.getSource().equals(mCancel)) {
+ this.dispose();
+ }
+ if (evt.getSource().equals(mHelp)) {
+ CMSAdminUtil.help(mHelpToken);
+ }
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setArrowButtons();
+ }
+
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {
+ setArrowButtons();
+ }
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {
+ setArrowButtons();
+ }
+
+ protected void setDisplay() {
+ Debug.println("*** PluginSelectionDialog.setDisplay() - 1");
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ // default content panel
+ mDefaultLabel = CMSAdminUtil.makeJLabel(mResource, mPrefix,
+ "DEFAULTNAME", null);
+ center.add(mDefaultLabel);
+
+ JPanel content = makeDefaultContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ // constraint content panel
+ mConstraintLabel = CMSAdminUtil.makeJLabel(mResource, mPrefix,
+ "CONSTRAINTNAME", null);
+ center.add(mConstraintLabel);
+
+ JPanel content1 = makeConstraintContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gb.setConstraints(content1, gbc);
+ center.add(content1);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ //create botton action panel
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, mPrefix, "OK", null, this);
+ mCancel = CMSAdminUtil.makeJButton(mResource, mPrefix, "CANCEL", null, this);
+ mHelp = CMSAdminUtil.makeJButton(mResource, mPrefix, "HELP", null, this);
+ //JButton[] buttons = { mOK, mCancel, mHelp};
+ JButton[] buttons = { mOK, mCancel};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonPanel( buttons, true);
+ }
+
+ private JPanel makeDefaultContentPane() {
+ JPanel mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+ //content.setBorder(CMSAdminUtil.makeEtchedBorder());
+
+ //left side certificate table
+ mDefaultList = CMSAdminUtil.makeJList(mDefaultModel,9);
+ mDefaultList.addListSelectionListener(this);
+ Debug.println("PluginSelectionDialog.makeContentPane() - making mList("+mDefaultList+")");
+ mScrollPane = new JScrollPane(mDefaultList,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mDefaultList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION );
+ mDefaultList.addMouseListener(this);
+ mScrollPane.setBackground(Color.white);
+ mScrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ return mListPanel;
+ }
+
+ private JPanel makeConstraintContentPane() {
+ JPanel mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+ //content.setBorder(CMSAdminUtil.makeEtchedBorder());
+
+ //left side certificate table
+ mConstraintList = CMSAdminUtil.makeJList(mConstraintModel,9);
+ Debug.println("PluginSelectionDialog.makeContentPane() - making mList("+mConstraintList+")");
+ mScrollPane = new JScrollPane(mConstraintList,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mConstraintList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION );
+ mConstraintList.addMouseListener(this);
+ mScrollPane.setBackground(Color.white);
+ mScrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ return mListPanel;
+ }
+
+
+ //set arrow buttons
+ private void setArrowButtons() {
+
+ //enable and diable buttons accordingly
+ //Debug.println("setArrowButtons() - "+mList.getSelectedIndex());
+
+ if (mDefaultList.getSelectedIndex()< 0 && mConstraintList.getSelectedIndex()<0) {
+ mOK.setEnabled(false);
+ return;
+ }
+
+ mOK.setEnabled(true);
+ }
+
+ //refresh the table content
+ private void refresh() {
+ //mScrollPane.invalidate();
+ //mScrollPane.validate();
+ //repaint();
+ }
+
+ public void valueChanged(ListSelectionEvent e) {
+ if (e.getSource().equals(mDefaultList)) {
+ if (mDefaultList.getSelectedIndex() < 0)
+ return;
+ String name = ((JLabel)mDefaultModel.elementAt(mDefaultList.getSelectedIndex())).getText();
+ NameValuePairs response=null;
+
+ try {
+ response = mConnection.read(mDestination,
+ ScopeDef.SC_SUPPORTED_CONSTRAINTPOLICIES,
+ getID(name, mDefaultData), new NameValuePairs());
+ Debug.println(response.toString());
+ } catch (Exception ex) {
+ Debug.println(ex.toString());
+ }
+
+ mConstraintModel.clear();
+ mConstraintData.clear();
+ parseData(response, mConstraintModel, mConstraintData);
+ mConstraintList.invalidate();
+ mConstraintList.validate();
+ repaint();
+ }
+ }
+
+ //=================================================
+ // RETRIEVE INFO FROM SERVER SIDE
+ //=================================================
+
+ //save order information to the server
+ protected boolean update(String scope, DefaultListModel model,
+ Hashtable data) {
+
+ NameValuePairs response;
+ NameValuePairs params = new NameValuePairs();
+ try {
+ response = mConnection.search(mDestination, scope,
+ params);
+ } catch (EAdminException e) {
+ //display error dialog
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ return false;
+ }
+
+ Debug.println(response.toString());
+
+ model.clear();
+ data.clear();
+ parseData(response, model, data);
+ return true;
+ }
+
+ private void parseData(NameValuePairs response, DefaultListModel model,
+ Hashtable data) {
+ //parse the data
+ String[] vals = new String[response.size()];
+ int i=0;
+ for (String name : response.keySet()) {
+ name = name.trim();
+ String val = response.get(name);
+ StringTokenizer st = new StringTokenizer(val, ",");
+ String className = st.nextToken();
+ String desc = st.nextToken();
+ String friendlyName = st.nextToken();
+ vals[i++] = friendlyName.trim();
+ data.put(name, friendlyName);
+ Debug.println("PluginSelectionDialog::update() - adding '"+vals[i-1]+"'");
+ }
+
+ CMSAdminUtil.bubbleSort(vals);
+
+ for (int y=0; y< vals.length ; y++) {
+ try {
+ model.addElement(new JLabel(vals[y],
+ CMSAdminUtil.getImage(mImageName), JLabel.LEFT));
+ }
+ catch (Exception ex) {
+ Debug.println("PluginSelectionDialog could not get image for '"+
+ mImageName+"'. Adding without image");
+ model.addElement(new JLabel(vals[y],
+ JLabel.LEFT));
+ }
+ }
+ }
+
+ //this returns the default configuration
+ protected NameValuePairs getDefaultConfig() throws EAdminException {
+ String name = ((JLabel)mDefaultModel.elementAt(mDefaultList.getSelectedIndex())).getText();
+ NameValuePairs response;
+ response = mConnection.read(mDestination,
+ ScopeDef.SC_SUPPORTED_CONSTRAINTPOLICIES, getID(name.trim(), mDefaultData),
+ new NameValuePairs());
+
+ Debug.println(response.toString());
+
+ return response;
+ }
+
+ private String getID(String name, Hashtable t) {
+ Enumeration keys = t.keys();
+ while (keys.hasMoreElements()) {
+ String key = (String)keys.nextElement();
+ String val = (String)t.get(key);
+ if (val.equals(name)) {
+ return key;
+ }
+ }
+ return "";
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ProfileRegisterDialog.java b/base/console/src/com/netscape/admin/certsrv/config/ProfileRegisterDialog.java
new file mode 100644
index 000000000..c576adbe6
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ProfileRegisterDialog.java
@@ -0,0 +1,303 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+
+/**
+ * Policy Implementation Registration Editor
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ProfileRegisterDialog extends JDialog
+ implements ActionListener, DocumentListener, MouseListener
+{
+
+ private final static String PREFIX = "PROFILEREGISTERDIALOG";
+
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private JFrame mParentFrame;
+ private AdminConnection mConnection;
+ private ResourceBundle mResource;
+
+ private JTextField mNameField, mClassField, mTypeField, mDescField;
+ private JButton mOK, mCancel;
+
+ protected String mDestination; //DEST_TAG to support RA/KRA/CA dest
+ protected String mScope;
+ protected String mPrefix;
+ private boolean mIsOK = false;
+ protected boolean mType = false;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public ProfileRegisterDialog(String prefix, JFrame parent, AdminConnection conn) {
+ super(parent,true);
+ mParentFrame = parent;
+ mPrefix = prefix;
+ mConnection = conn;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ setSize(360, 216);
+ setTitle(mResource.getString(mPrefix+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ //setDisplay(); SUBCLASS MUST call setDiaply() in its constructor
+ }
+
+ public ProfileRegisterDialog(JFrame parent, AdminConnection conn) {
+ this(PREFIX, parent, conn);
+ mType = true;
+ setDisplay();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * show the windows
+ */
+ public void showDialog(String destination, String scope) {
+ //initialize and setup
+ mNameField.setText("");
+ mClassField.setText("");
+ mTypeField.setText("");
+ mDescField.setText("");
+ mDestination=destination;
+ mScope=scope;
+ this.show();
+ }
+
+ protected void setDestination(String destination) {
+ mDestination = destination;
+ }
+
+ protected void setScope(String scope) {
+ mScope = scope;
+ }
+
+ public boolean isOK() {
+ return mIsOK;
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent evt) {
+
+ if (evt.getSource().equals(mCancel)) {
+ mIsOK = false;
+ this.hide();
+ }
+
+ if (evt.getSource().equals(mOK)) {
+
+ /* REPLACED BY PROACTIVE ENFORCEMENT
+ if (mNameField.getText().trim().equals("")) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, mResource, mPrefix,
+ "NONAME", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ if (mClassField.getText().trim().equals("")) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, mResource, mPrefix,
+ "NOCLASS", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ */
+
+ //save value
+ try {
+ addImpl();
+ } catch (EAdminException e) {
+ //display error dialog
+ Debug.println(e.toString());
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ mIsOK = false;
+ return;
+ }
+ mIsOK = true;
+ this.hide();
+ }
+ }
+
+ //== DocumentListener ==
+ public void insertUpdate(DocumentEvent e) {
+ setButtons();
+ }
+
+ public void removeUpdate(DocumentEvent e){
+ setButtons();
+ }
+
+ public void changedUpdate(DocumentEvent e){
+ setButtons();
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {}
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+
+ protected void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ //set arrow buttons
+ private void setButtons() {
+ if ( (mNameField.getText().trim().equals("")) ||
+ (mClassField.getText().trim().equals("")) ) {
+ mOK.setEnabled(false);
+ } else {
+ mOK.setEnabled(true);
+ }
+ }
+
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, mPrefix, "OK", null, this);
+ mOK.setEnabled(false);
+ mCancel = CMSAdminUtil.makeJButton(mResource, mPrefix, "CANCEL", null, this);
+ JButton[] buttons = { mOK, mCancel};
+ return CMSAdminUtil.makeJButtonPanel( buttons );
+ }
+
+ private JPanel makeContentPane() {
+ JPanel content = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ content.setLayout(gb3);
+ //content.setBorder(CMSAdminUtil.makeEtchedBorder());
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label1 = CMSAdminUtil.makeJLabel(mResource, mPrefix, "NAME", null);
+ mNameField = new JTextField();
+ mNameField.getDocument().addDocumentListener(this);
+ mNameField.addMouseListener(this);
+ CMSAdminUtil.addEntryField(content, label1, mNameField, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ // gbc.gridheight = gbc.REMAINDER;
+ JLabel label2 = CMSAdminUtil.makeJLabel(mResource, mPrefix, "CLASS", null);
+ mClassField = new JTextField();
+ mClassField.getDocument().addDocumentListener(this);
+ mClassField.addMouseListener(this);
+ CMSAdminUtil.addEntryField(content, label2, mClassField, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ // gbc.gridheight = gbc.REMAINDER;
+ JLabel label3 = CMSAdminUtil.makeJLabel(mResource, mPrefix, "TYPE", null);
+ mTypeField = new JTextField();
+ mTypeField.getDocument().addDocumentListener(this);
+ mTypeField.addMouseListener(this);
+ CMSAdminUtil.addEntryField(content, label3, mTypeField, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.gridheight = gbc.REMAINDER;
+ JLabel label4 = CMSAdminUtil.makeJLabel(mResource, mPrefix, "DESC", null);
+ mDescField = new JTextField();
+ mDescField.getDocument().addDocumentListener(this);
+ mDescField.addMouseListener(this);
+ CMSAdminUtil.addEntryField(content, label4, mDescField, gbc);
+
+ return content;
+ }
+
+ //=================================================
+ // CONNECT TO SERVER SIDE
+ //=================================================
+
+ //add new group information
+ private void addImpl() throws EAdminException {
+
+ //construct NVP
+ NameValuePairs config = new NameValuePairs();
+ config.put(Constants.PR_POLICY_CLASS, mClassField.getText());
+ config.put(Constants.PR_POLICY_DESC, mDescField.getText());
+
+ if (mType) {
+ mScope=mTypeField.getText();
+ }
+
+ //send request
+ mConnection.add(mDestination,
+ mScope,
+ mNameField.getText().trim(),
+ config);
+ }
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ProfileRuleDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/ProfileRuleDataModel.java
new file mode 100644
index 000000000..7a3ba2827
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ProfileRuleDataModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+
+
+/**
+ * Policy instance Data model - represents the instance
+ * table information
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class ProfileRuleDataModel extends CMSRuleDataModel
+{
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public ProfileRuleDataModel() {
+ super();
+ }
+
+ protected String[] getColumns() {
+ String x[] = {PROFILE_RULE, STATUS};
+ return x;
+ }
+
+ public void processData(Object data) {
+ Vector v = new Vector();
+ NameValuePairs obj = (NameValuePairs) data;
+
+ //XXX NEED TO ADD STUFF
+ if (obj.get(RULE_STAT).equalsIgnoreCase("enabled")) {
+ v.addElement(new JLabel(obj.get(RULE_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE),
+ JLabel.LEFT));
+ v.addElement(mResource.getString("POLICYRULE_LABEL_ENABLED_LABEL"));
+ } else {
+ v.addElement(new JLabel(obj.get(RULE_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE_DISABLE),
+ JLabel.LEFT));
+ v.addElement(mResource.getString("POLICYRULE_LABEL_DISABLED_LABEL"));
+ }
+ addRow(v, data);
+ mRules.addElement(obj.get(RULE_NAME));
+ }
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/PublisherConfigDialog.java b/base/console/src/com/netscape/admin/certsrv/config/PublisherConfigDialog.java
new file mode 100644
index 000000000..90d67ba9e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/PublisherConfigDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import javax.swing.text.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Publisher Parameter Configuration Dialog
+ *
+ * @author Steve Parkinson
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class PublisherConfigDialog extends CMSBaseConfigDialog
+ implements ActionListener
+{
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public PublisherConfigDialog(NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest) {
+
+ super(parent, dest);
+
+ PREFIX = "PUBLISHERCONFIGDIALOG";
+ RAHELPINDEX = "configuration-ra-edit-publisherrule-dbox-help";
+ KRAHELPINDEX = "configuration-kra-edit-publisherrule-dbox-help";
+ CAHELPINDEX = "configuration-ca-edit-publisherrule-dbox-help";
+ mImplName_token = Constants.PR_PUBLISHER_IMPL_NAME;
+ mImplType = Constants.PR_EXT_PLUGIN_IMPLTYPE_PUBLISHER;
+
+ init(nvp,parent,conn,dest);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/PublisherImplDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/PublisherImplDataModel.java
new file mode 100644
index 000000000..aefa4b1cc
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/PublisherImplDataModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Policy Implementation Data model - represents the implementation
+ * table information
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class PublisherImplDataModel extends CMSContentTableModel
+ implements IDataProcessor
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String IMPL_NAME = "NAME";
+ public static final String IMPL_CLASS = "CLASS";
+ public static final String IMPL_DESC = "DESC";
+
+ private static String[] mColumns = {PUBLISHER_IMPL, CLASSNAME};
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public PublisherImplDataModel() {
+ super();
+ init(mColumns);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void processData(Object data) {
+ Vector v = new Vector();
+ NameValuePairs obj = (NameValuePairs) data;
+ v.addElement(new JLabel(obj.get(IMPL_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE_PLUGIN),
+ JLabel.LEFT));
+ v.addElement(obj.get(IMPL_CLASS));
+ //v.addElement(obj.getValue(IMPL_DESC));
+ addRow(v, data);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/PublisherImplTab.java b/base/console/src/com/netscape/admin/certsrv/config/PublisherImplTab.java
new file mode 100644
index 000000000..79fedfe5e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/PublisherImplTab.java
@@ -0,0 +1,321 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Publisher Instances Management Tab
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class PublisherImplTab extends CMSBaseUGTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String IMPL_NAME = PublisherImplDataModel.IMPL_NAME;
+ private static final String IMPL_CLASS = PublisherImplDataModel.IMPL_CLASS;
+ private static final String IMPL_DESC = PublisherImplDataModel.IMPL_DESC;
+
+ private static final String PANEL_NAME = "PUBLISHERIMPL";
+ private static final String DIALOG_PREFIX = "PUBLISHERREGISTERDIALOG";
+
+ private AdminConnection mConnection;
+ private String mDestination;
+
+ protected JScrollPane mScrollPane;
+ protected JTable mTable; //table
+ protected PublisherImplDataModel mDataModel; //table model
+ protected PublisherRegisterDialog mEditor=null; //keep single copy
+ protected ViewDialog mViewer=null; //keep single copy
+
+ protected JButton mRefresh, mAdd, mDelete, mView, mHelp;
+ private final static String RAHELPINDEX = "configuration-ra-publisherplugin-help";
+ private final static String CAHELPINDEX = "configuration-ca-publisherplugin-help";
+ private final static String KRAHELPINDEX = "configuration-publisherkra-plugin-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public PublisherImplTab(CMSBaseResourceModel model, String destination) {
+ super(PANEL_NAME, model);
+ mConnection = model.getServerInfo().getAdmin();
+ mDataModel = new PublisherImplDataModel();
+ mDestination = destination;
+ if (mDestination.equals(DestDef.DEST_RA_PUBLISHER_ADMIN))
+ mHelpToken = RAHELPINDEX;
+ else
+ mHelpToken = CAHELPINDEX;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mRefresh)) {
+ refresh();
+ }
+ if (e.getSource().equals(mAdd)) {
+ if (mEditor==null)
+ mEditor = new PublisherRegisterDialog(mModel.getFrame(),
+ mConnection);
+ mEditor.showDialog(mDestination, ScopeDef.SC_PUBLISHER_IMPLS);
+ refresh();
+ }
+ if (e.getSource().equals(mDelete)) {
+ Debug.println("Delete");
+ if(mTable.getSelectedRow()< 0)
+ return;
+ int i = showConfirmDialog("DELETE");
+ if (i == JOptionPane.YES_OPTION) {
+ delete();
+ Debug.println("Deleted");
+ }
+ }
+ if (e.getSource().equals(mView)) {
+ Debug.println("View");
+ if(mTable.getSelectedRow()< 0)
+ return;
+ NameValuePairs obj = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+ if (mViewer==null)
+ mViewer = new ViewDialog(mModel.getFrame());
+ mViewer.showDialog(obj.get(IMPL_NAME),
+ obj.get(IMPL_CLASS),
+ obj.get(IMPL_DESC));
+ }
+ if (e.getSource().equals(mHelp)) {
+ helpCallback();
+ }
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+ public void refresh() {
+
+ mDataModel.removeAllRows();
+ update();
+
+ setButtons();
+ mTable.invalidate();
+ mTable.validate();
+ mTable.repaint(1);
+ }
+
+ /**
+ * create the user action button panel
+ */
+ protected JPanel createButtonPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mAdd = makeJButton("ADD");
+ mDelete = makeJButton("DELETE");
+ mView = makeJButton("VIEW");
+ JButton[] buttons = {mAdd, mDelete, mView};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ protected JPanel createActionPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mRefresh = makeJButton("REFRESH");
+ mHelp = makeJButton("HELP");
+ //JButton[] buttons = { mRefresh, mHelp };
+ JButton[] buttons = { mRefresh };
+ return makeJButtonPanel(buttons, true);
+ }
+
+ protected JPanel createListPanel() {
+ mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ //center table
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ //mScrollPane.setBorder(CMSAdminUtil.makeTitledBorder(mResource,PANEL_NAME,"USERS"));
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ mTable.addMouseListener(this);
+ setLabelCellRenderer(mTable,0);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = 1;
+ gbc.weightx = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ JPanel buttonPanel = createButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ mListPanel.add(buttonPanel);
+
+ refresh();
+
+ return mListPanel;
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(new LabelCellRenderer(new JLabel()));
+ }
+
+
+ //set buttons
+ private void setButtons() {
+
+ //enable and diable buttons accordingly
+ //Debug.println("setButtons() - "+mTable.getSelectedRow());
+ //Debug.println("setButtons() - "+mTable.getSelectionModel().isSelectionEmpty());
+ if (mTable.getSelectionModel().isSelectionEmpty()) {
+ mDelete.setEnabled(false);
+ mView.setEnabled(false);
+ return;
+ }
+
+ if(mDataModel.getRowCount()<=0) {
+ mDelete.setEnabled(false);
+ mView.setEnabled(false);
+ return;
+ }
+
+ mDelete.setEnabled(true);
+ mView.setEnabled(true);
+
+ }
+
+ //=============================================
+ // SEND REQUESTS TO THE SERVER SIDE
+ //=============================================
+ private void update() {
+ //send request and parse data
+
+ mModel.progressStart();
+ NameValuePairs response;
+ try {
+ response = mConnection.search(mDestination,
+ "publisherImpls",
+ // ScopeDef.SC_PUBLISHER_IMPLS,
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+
+ Debug.println(response.toString());
+
+ //parse the data
+ int i=0;
+ String[] vals = new String[response.size()];
+ Hashtable data = new Hashtable();
+ for (String entry : response.keySet()) {
+ entry = entry.trim();
+ String value = response.get(entry);
+ int x = value.indexOf(",");
+ NameValuePairs obj = new NameValuePairs();
+ obj.put(IMPL_NAME, entry);
+ vals[i++]= entry ;
+ obj.put(IMPL_CLASS, value.substring(0, x));
+ obj.put(IMPL_DESC, value.substring(x + 1));
+ data.put(entry,obj);
+ }
+
+ CMSAdminUtil.bubbleSort(vals);
+
+ for (int y=0; y< vals.length ; y++) {
+ mDataModel.processData(data.get(vals[y]));
+ }
+
+ data.clear();
+
+ if (mDataModel.getRowCount() >0)
+ mTable.setRowSelectionInterval(0,0);
+
+ mModel.progressStop();
+ }
+
+ private void delete() {
+ //get entry name
+ mModel.progressStart();
+ NameValuePairs obj = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+
+ //send comment to server for the removal of user
+ try {
+ mConnection.delete(mDestination,
+ ScopeDef.SC_PUBLISHER_IMPLS,
+ obj.get(IMPL_NAME));
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+ mModel.progressStop();
+ //send comment to server and refetch the content
+ refresh();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/PublisherInstanceTab.java b/base/console/src/com/netscape/admin/certsrv/config/PublisherInstanceTab.java
new file mode 100644
index 000000000..e9d3bdbb0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/PublisherInstanceTab.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Publisher Instances Management Tab
+ *
+ * @author Steve Parkinson
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class PublisherInstanceTab extends CMSPluginInstanceTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PANEL_NAME = "PUBLISHERRULE";
+
+ private final static String RAHELPINDEX = "configuration-ra-publisherinstances-help";
+ private final static String CAHELPINDEX = "configuration-ca-publisherinstances-help";
+ private final static String KRAHELPINDEX = "configuration-kra-publisherinstances-help";
+
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public PublisherInstanceTab(CMSBaseResourceModel model, String dest) {
+ super(model,dest,PANEL_NAME);
+ Debug.println("PublisherInstanceTab::PublisherInstanceTab(<model>,"+dest);
+ mConnection = model.getServerInfo().getAdmin();
+ mDataModel = new PublisherRuleDataModel();
+ mScope = ScopeDef.SC_PUBLISHER_RULES;
+ RULE_NAME = PublisherRuleDataModel.RULE_NAME;
+ RULE_STAT = PublisherRuleDataModel.RULE_STAT;
+
+ if (mDestination.equals(DestDef.DEST_RA_PUBLISHER_ADMIN))
+ mHelpToken = RAHELPINDEX;
+ else
+ mHelpToken = CAHELPINDEX;
+ }
+
+
+ public CMSBaseConfigDialog makeNewConfigDialog(
+ NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest
+ )
+ {
+
+ return new PublisherConfigDialog(nvp,
+ parent,
+ conn,
+ dest);
+ }
+
+ public PluginSelectionDialog getPluginSelectionDialog(
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType
+ )
+ {
+ return new PublisherPluginSelectionDialog(parent,conn,dest,pluginType);
+ }
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/PublisherPluginSelectionDialog.java b/base/console/src/com/netscape/admin/certsrv/config/PublisherPluginSelectionDialog.java
new file mode 100644
index 000000000..536d9096f
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/PublisherPluginSelectionDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Publisher Plugin Selection Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class PublisherPluginSelectionDialog extends PluginSelectionDialog
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "PUBLISHERSELECTIONDIALOG";
+ private static final String CAHELPINDEX =
+ "configuration-ca-add-publisherrule-dbox-help";
+ private static final String RAHELPINDEX =
+ "configuration-ra-add-publisherrule-dbox-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public PublisherPluginSelectionDialog(
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType)
+ {
+ super(PREFIX, parent,conn, dest, pluginType);
+ mScope = ScopeDef.SC_PUBLISHER_IMPLS;
+ mInstanceScope = ScopeDef.SC_PUBLISHER_RULES;
+ mImageName = CMSAdminResources.IMAGE_RULE_PLUGIN;
+ if (dest.equals(DestDef.DEST_RA_PUBLISHER_ADMIN))
+ mHelpToken = RAHELPINDEX;
+ else
+ mHelpToken = CAHELPINDEX;
+ setDisplay();
+ }
+
+ /*==========================================================
+ * EVENT HANDLER METHODS
+ *==========================================================*/
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/PublisherRegisterDialog.java b/base/console/src/com/netscape/admin/certsrv/config/PublisherRegisterDialog.java
new file mode 100644
index 000000000..23e1a5913
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/PublisherRegisterDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+
+/**
+ * Publisher Implementation Registration Editor
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+
+public class PublisherRegisterDialog extends RegisterDialog {
+
+ private final static String PREFIX = "PUBLISHERREGISTERDIALOG";
+
+ public PublisherRegisterDialog(JFrame parent, AdminConnection conn) {
+ super(PREFIX, parent, conn);
+ setDisplay();
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/PublisherRuleDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/PublisherRuleDataModel.java
new file mode 100644
index 000000000..03faeac21
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/PublisherRuleDataModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.Debug;
+
+
+/**
+ * Publisher instance Data model - represents the instance
+ * table information
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class PublisherRuleDataModel extends CMSRuleDataModel
+{
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public PublisherRuleDataModel() {
+ super();
+ }
+
+ protected String[] getColumns() {
+ Debug.println("PublisherRuleDataModel.getColumns()");
+ String x[] = {PUBLISHER_RULE, PLUGIN};
+ return x;
+ }
+
+ public void processData(Object data) {
+ Vector v = new Vector();
+ NameValuePairs obj = (NameValuePairs) data;
+
+ v.addElement(new JLabel(obj.get(RULE_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE),
+ JLabel.LEFT));
+ v.addElement(obj.get(RULE_IMPL));
+ addRow(v, data);
+ }
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/RegisterDialog.java b/base/console/src/com/netscape/admin/certsrv/config/RegisterDialog.java
new file mode 100644
index 000000000..fe48419c7
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/RegisterDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Registration Editor
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class RegisterDialog extends JDialog
+ implements ActionListener, DocumentListener, MouseListener
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private JFrame mParentFrame;
+ private AdminConnection mConnection;
+ private ResourceBundle mResource;
+
+ private JTextField mNameField, mClassField, mTypeField;
+ private JButton mOK, mCancel;
+
+ protected String mDestination; //DEST_TAG to support RA/KRA/CA dest
+ protected String mScope;
+ protected String mPrefix;
+ private boolean mIsOK = false;
+ protected boolean mType = false;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public RegisterDialog(String prefix, JFrame parent, AdminConnection conn) {
+ super(parent,true);
+ mParentFrame = parent;
+ mPrefix = prefix;
+ mConnection = conn;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ setSize(360, 216);
+ setTitle(mResource.getString(mPrefix+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ //setDisplay(); SUBCLASS MUST call setDiaply() in its constructor
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * show the windows
+ */
+ public void showDialog(String destination, String scope) {
+ //initialize and setup
+ mNameField.setText("");
+ mClassField.setText("");
+ if (mType) {
+ mTypeField.setText("");
+ }
+ mDestination=destination;
+ mScope=scope;
+ this.show();
+ }
+
+ protected void setDestination(String destination) {
+ mDestination = destination;
+ }
+
+ protected void setScope(String scope) {
+ mScope = scope;
+ }
+
+ public boolean isOK() {
+ return mIsOK;
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent evt) {
+
+ if (evt.getSource().equals(mCancel)) {
+ mIsOK = false;
+ this.hide();
+ }
+
+ if (evt.getSource().equals(mOK)) {
+
+ /* REPLACED BY PROACTIVE ENFORCEMENT
+ if (mNameField.getText().trim().equals("")) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, mResource, mPrefix,
+ "NONAME", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ if (mClassField.getText().trim().equals("")) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, mResource, mPrefix,
+ "NOCLASS", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ */
+
+ //save value
+ try {
+ addImpl();
+ } catch (EAdminException e) {
+ //display error dialog
+ Debug.println(e.toString());
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ mIsOK = false;
+ return;
+ }
+ mIsOK = true;
+ this.hide();
+ }
+ }
+
+ //== DocumentListener ==
+ public void insertUpdate(DocumentEvent e) {
+ setButtons();
+ }
+
+ public void removeUpdate(DocumentEvent e){
+ setButtons();
+ }
+
+ public void changedUpdate(DocumentEvent e){
+ setButtons();
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {}
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+
+ protected void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ //set arrow buttons
+ private void setButtons() {
+ if ( (mNameField.getText().trim().equals("")) ||
+ (mClassField.getText().trim().equals("")) ) {
+ mOK.setEnabled(false);
+ } else {
+ mOK.setEnabled(true);
+ }
+ }
+
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, mPrefix, "OK", null, this);
+ mOK.setEnabled(false);
+ mCancel = CMSAdminUtil.makeJButton(mResource, mPrefix, "CANCEL", null, this);
+ JButton[] buttons = { mOK, mCancel};
+ return CMSAdminUtil.makeJButtonPanel( buttons );
+ }
+
+ private JPanel makeContentPane() {
+ JPanel content = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ content.setLayout(gb3);
+ //content.setBorder(CMSAdminUtil.makeEtchedBorder());
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label1 = CMSAdminUtil.makeJLabel(mResource, mPrefix, "NAME", null);
+ mNameField = new JTextField();
+ mNameField.getDocument().addDocumentListener(this);
+ mNameField.addMouseListener(this);
+ CMSAdminUtil.addEntryField(content, label1, mNameField, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ // gbc.gridheight = gbc.REMAINDER;
+ JLabel label2 = CMSAdminUtil.makeJLabel(mResource, mPrefix, "CLASS", null);
+ mClassField = new JTextField();
+ mClassField.getDocument().addDocumentListener(this);
+ mClassField.addMouseListener(this);
+ CMSAdminUtil.addEntryField(content, label2, mClassField, gbc);
+
+ if (mType) {
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.gridheight = gbc.REMAINDER;
+ JLabel label3 = CMSAdminUtil.makeJLabel(mResource, mPrefix, "TYPE", null);
+ mTypeField = new JTextField();
+ mTypeField.getDocument().addDocumentListener(this);
+ mTypeField.addMouseListener(this);
+ CMSAdminUtil.addEntryField(content, label3, mTypeField, gbc);
+ }
+
+ return content;
+ }
+
+ //=================================================
+ // CONNECT TO SERVER SIDE
+ //=================================================
+
+ //add new group information
+ private void addImpl() throws EAdminException {
+
+ //construct NVP
+ NameValuePairs config = new NameValuePairs();
+ config.put(Constants.PR_POLICY_CLASS, mClassField.getText());
+
+ if (mType) {
+ mScope=mTypeField.getText();
+ }
+
+ //send request
+ mConnection.add(mDestination,
+ mScope,
+ mNameField.getText().trim(),
+ config);
+ }
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/RuleConfigDialog.java b/base/console/src/com/netscape/admin/certsrv/config/RuleConfigDialog.java
new file mode 100644
index 000000000..7f7cff092
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/RuleConfigDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import javax.swing.text.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Rule Parameter Configuration Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class RuleConfigDialog extends CMSBaseConfigDialog
+ implements ActionListener
+{
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public RuleConfigDialog(NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest) {
+
+ super(parent, dest);
+ PREFIX = "RULECONFIGDIALOG";
+ RAHELPINDEX =
+ "configuration-ra-edit-rulerule-dbox-help";
+ CAHELPINDEX =
+ "configuration-ca-edit-rulerule-dbox-help";
+
+ mImplName_token = Constants.PR_RULE_IMPL_NAME;
+ mImplType = Constants.PR_EXT_PLUGIN_IMPLTYPE_PUBLISHRULE;
+
+ init(nvp,parent,conn,dest);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/RuleImplDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/RuleImplDataModel.java
new file mode 100644
index 000000000..86a4fa6d4
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/RuleImplDataModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Rule Implementation Data model - represents the implementation
+ * table information
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class RuleImplDataModel extends CMSContentTableModel
+ implements IDataProcessor
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String IMPL_NAME = "NAME";
+ public static final String IMPL_CLASS = "CLASS";
+ public static final String IMPL_DESC = "DESC";
+
+ private static String[] mColumns = {RULE_IMPL, CLASSNAME};
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public RuleImplDataModel() {
+ super();
+ init(mColumns);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void processData(Object data) {
+ Vector v = new Vector();
+ NameValuePairs obj = (NameValuePairs) data;
+ v.addElement(new JLabel(obj.get(IMPL_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE_PLUGIN),
+ JLabel.LEFT));
+ v.addElement(obj.get(IMPL_CLASS));
+ //v.addElement(obj.getValue(IMPL_DESC));
+ addRow(v, data);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/RuleImplTab.java b/base/console/src/com/netscape/admin/certsrv/config/RuleImplTab.java
new file mode 100644
index 000000000..098cbcbd1
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/RuleImplTab.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Rule Instances Management Tab
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class RuleImplTab extends CMSBaseUGTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String IMPL_NAME = RuleImplDataModel.IMPL_NAME;
+ private static final String IMPL_CLASS = RuleImplDataModel.IMPL_CLASS;
+ private static final String IMPL_DESC = RuleImplDataModel.IMPL_DESC;
+
+ private static final String PANEL_NAME = "RULEIMPL";
+ private static final String DIALOG_PREFIX = "RULEREGISTERDIALOG";
+
+ private AdminConnection mConnection;
+ private String mDestination;
+
+ protected JScrollPane mScrollPane;
+ protected JTable mTable; //table
+ protected RuleImplDataModel mDataModel; //table model
+ protected RuleRegisterDialog mEditor=null; //keep single copy
+ protected ViewDialog mViewer=null; //keep single copy
+
+ protected JButton mRefresh, mAdd, mDelete, mView, mHelp;
+ private final static String RAHELPINDEX = "configuration-ra-ruleplugin-help";
+ private final static String CAHELPINDEX = "configuration-ca-ruleplugin-help";
+ private final static String KRAHELPINDEX = "configuration-kra-ruleplugin-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public RuleImplTab(CMSBaseResourceModel model, String destination) {
+ super(PANEL_NAME, model);
+ mConnection = model.getServerInfo().getAdmin();
+ mDataModel = new RuleImplDataModel();
+ mDestination = destination;
+ if (mDestination.equals(DestDef.DEST_RA_RULE_ADMIN))
+ mHelpToken = RAHELPINDEX;
+ else
+ mHelpToken = CAHELPINDEX;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mRefresh)) {
+ refresh();
+ }
+ if (e.getSource().equals(mAdd)) {
+ if (mEditor==null)
+ mEditor = new RuleRegisterDialog(mModel.getFrame(),
+ mConnection);
+ mEditor.showDialog(mDestination, ScopeDef.SC_RULE_IMPLS);
+ refresh();
+ }
+ if (e.getSource().equals(mDelete)) {
+ Debug.println("Delete");
+ if(mTable.getSelectedRow()< 0)
+ return;
+ int i = showConfirmDialog("DELETE");
+ if (i == JOptionPane.YES_OPTION) {
+ delete();
+ Debug.println("Deleted");
+ }
+ }
+ if (e.getSource().equals(mView)) {
+ Debug.println("View");
+ if(mTable.getSelectedRow()< 0)
+ return;
+ NameValuePairs obj = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+ if (mViewer==null)
+ mViewer = new ViewDialog(mModel.getFrame());
+ mViewer.showDialog(obj.get(IMPL_NAME),
+ obj.get(IMPL_CLASS),
+ obj.get(IMPL_DESC));
+ }
+ if (e.getSource().equals(mHelp)) {
+ helpCallback();
+ }
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+ public void refresh() {
+
+ mDataModel.removeAllRows();
+ update();
+
+ setButtons();
+ mTable.invalidate();
+ mTable.validate();
+ mTable.repaint(1);
+ }
+
+ /**
+ * create the user action button panel
+ */
+ protected JPanel createButtonPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mAdd = makeJButton("ADD");
+ mDelete = makeJButton("DELETE");
+ mView = makeJButton("VIEW");
+ JButton[] buttons = {mAdd, mDelete, mView};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ protected JPanel createActionPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mRefresh = makeJButton("REFRESH");
+ mHelp = makeJButton("HELP");
+ //JButton[] buttons = { mRefresh, mHelp };
+ JButton[] buttons = { mRefresh };
+ return makeJButtonPanel(buttons, true);
+ }
+
+ protected JPanel createListPanel() {
+ mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ //center table
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ //mScrollPane.setBorder(CMSAdminUtil.makeTitledBorder(mResource,PANEL_NAME,"USERS"));
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ mTable.addMouseListener(this);
+ setLabelCellRenderer(mTable,0);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = 1;
+ gbc.weightx = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ JPanel buttonPanel = createButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ mListPanel.add(buttonPanel);
+
+ refresh();
+
+ return mListPanel;
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(new LabelCellRenderer(new JLabel()));
+ }
+
+
+ //set buttons
+ private void setButtons() {
+
+ //enable and diable buttons accordingly
+ //Debug.println("setButtons() - "+mTable.getSelectedRow());
+ //Debug.println("setButtons() - "+mTable.getSelectionModel().isSelectionEmpty());
+ if (mTable.getSelectionModel().isSelectionEmpty()) {
+ mDelete.setEnabled(false);
+ mView.setEnabled(false);
+ return;
+ }
+
+ if(mDataModel.getRowCount()<=0) {
+ mDelete.setEnabled(false);
+ mView.setEnabled(false);
+ return;
+ }
+
+ mDelete.setEnabled(true);
+ mView.setEnabled(true);
+
+ }
+
+ //=============================================
+ // SEND REQUESTS TO THE SERVER SIDE
+ //=============================================
+ private void update() {
+ //send request and parse data
+
+ mModel.progressStart();
+ NameValuePairs response;
+ try {
+ response = mConnection.search(mDestination,
+ ScopeDef.SC_RULE_IMPLS,
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+
+ Debug.println(response.toString());
+
+ //parse the data
+ int i=0;
+ String[] vals = new String[response.size()];
+ Hashtable data = new Hashtable();
+ for (String entry : response.keySet()) {
+ entry = entry.trim();
+ String value = response.get(entry);
+ int x = value.indexOf(",");
+ NameValuePairs obj = new NameValuePairs();
+ obj.put(IMPL_NAME, entry);
+ vals[i++]= entry ;
+ obj.put(IMPL_CLASS, value.substring(0, x));
+ obj.put(IMPL_DESC, value.substring(x + 1));
+ data.put(entry,obj);
+ }
+
+ CMSAdminUtil.bubbleSort(vals);
+
+ for (int y=0; y< vals.length ; y++) {
+ mDataModel.processData(data.get(vals[y]));
+ }
+
+ data.clear();
+
+ if (mDataModel.getRowCount() >0)
+ mTable.setRowSelectionInterval(0,0);
+
+ mModel.progressStop();
+ }
+
+ private void delete() {
+ //get entry name
+ mModel.progressStart();
+ NameValuePairs obj = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+
+ //send comment to server for the removal of user
+ try {
+ mConnection.delete(mDestination,
+ ScopeDef.SC_RULE_IMPLS,
+ obj.get(IMPL_NAME));
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+ mModel.progressStop();
+ //send comment to server and refetch the content
+ refresh();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/RuleInstanceTab.java b/base/console/src/com/netscape/admin/certsrv/config/RuleInstanceTab.java
new file mode 100644
index 000000000..04a649ed0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/RuleInstanceTab.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Publishing Rules - Instances Management Tab
+ *
+ * @author Steve Parkinson
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+
+/* A Rule Rule? Hmmm */
+
+public class RuleInstanceTab extends CMSPluginInstanceTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PANEL_NAME = "RULERULE";
+
+ private final static String RAHELPINDEX = "configuration-ra-ruleinstances-help";
+ private final static String CAHELPINDEX = "configuration-ca-ruleinstances-help";
+
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public RuleInstanceTab(CMSBaseResourceModel model, String dest) {
+ super(model,dest,PANEL_NAME);
+ Debug.println("RuleInstanceTab::RuleInstanceTab(<model>,"+dest);
+ mConnection = model.getServerInfo().getAdmin();
+ mDataModel = new RuleRuleDataModel();
+ mScope = ScopeDef.SC_RULE_RULES;
+ RULE_NAME = RuleRuleDataModel.RULE_NAME;
+ RULE_STAT = RuleRuleDataModel.RULE_STAT;
+
+ if (mDestination.equals(DestDef.DEST_RA_RULE_ADMIN))
+ mHelpToken = RAHELPINDEX;
+ else
+ mHelpToken = CAHELPINDEX;
+ }
+
+
+ public CMSBaseConfigDialog makeNewConfigDialog(
+ NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest
+ )
+ {
+
+ return new RuleConfigDialog(nvp,
+ parent,
+ conn,
+ dest);
+ }
+
+ public PluginSelectionDialog getPluginSelectionDialog(
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType
+ )
+ {
+ return new RulePluginSelectionDialog(parent,conn,dest,pluginType);
+ }
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/RulePluginSelectionDialog.java b/base/console/src/com/netscape/admin/certsrv/config/RulePluginSelectionDialog.java
new file mode 100644
index 000000000..f1021bc6c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/RulePluginSelectionDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Publishing Rule Plugin Selection Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class RulePluginSelectionDialog extends PluginSelectionDialog
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "RULESELECTIONDIALOG";
+ private static final String CAHELPINDEX =
+ "configuration-ca-add-rulerule-dbox-help";
+ private static final String RAHELPINDEX =
+ "configuration-ra-add-rulerule-dbox-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public RulePluginSelectionDialog(
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType)
+ {
+ super(PREFIX, parent,conn, dest, pluginType);
+ mScope = ScopeDef.SC_RULE_IMPLS;
+ mInstanceScope = ScopeDef.SC_RULE_RULES;
+ mImageName = CMSAdminResources.IMAGE_RULE_PLUGIN;
+ if (dest.equals(DestDef.DEST_RA_RULE_ADMIN))
+ mHelpToken = RAHELPINDEX;
+ else
+ mHelpToken = CAHELPINDEX;
+ setDisplay();
+ }
+
+ /*==========================================================
+ * EVENT HANDLER METHODS
+ *==========================================================*/
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/RuleRegisterDialog.java b/base/console/src/com/netscape/admin/certsrv/config/RuleRegisterDialog.java
new file mode 100644
index 000000000..34d1757e6
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/RuleRegisterDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+
+/**
+ * RUle Implementation Registration Editor
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+
+public class RuleRegisterDialog extends RegisterDialog {
+
+ private final static String PREFIX = "RULEREGISTERDIALOG";
+
+ public RuleRegisterDialog(JFrame parent, AdminConnection conn) {
+ super(PREFIX, parent, conn);
+ setDisplay();
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/RuleRuleDataModel.java b/base/console/src/com/netscape/admin/certsrv/config/RuleRuleDataModel.java
new file mode 100644
index 000000000..cee7727a1
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/RuleRuleDataModel.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.admin.certsrv.config;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.Debug;
+
+
+/**
+ * Rule instance Data model - represents the instance
+ * table information
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class RuleRuleDataModel extends CMSRuleDataModel
+{
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public RuleRuleDataModel() {
+ super();
+ }
+
+ protected String[] getColumns() {
+ Debug.println("PolicyRuleDataModel.getColumns()");
+ String x[] = {RULE_RULE, STATUS};
+ return x;
+ }
+
+ public void processData(Object data) {
+ Vector v = new Vector();
+ NameValuePairs obj = (NameValuePairs) data;
+
+ if (obj.get(RULE_STAT).equalsIgnoreCase("enabled")) {
+ v.addElement(new JLabel(obj.get(RULE_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE),
+ JLabel.LEFT));
+ v.addElement(mResource.getString("RULERULE_LABEL_ENABLED_LABEL"));
+ } else {
+ v.addElement(new JLabel(obj.get(RULE_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_RULE_DISABLE),
+ JLabel.LEFT));
+ v.addElement(mResource.getString("RULERULE_LABEL_DISABLED_LABEL"));
+ }
+ addRow(v, data);
+ mRules.addElement(obj.get(RULE_NAME));
+ }
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/TKSKeysTab.java b/base/console/src/com/netscape/admin/certsrv/config/TKSKeysTab.java
new file mode 100644
index 000000000..ac8b5e610
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/TKSKeysTab.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+import org.mozilla.jss.CryptoManager;
+/**
+ * User Certs Tab
+ *
+ * @author Khai Truong
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class TKSKeysTab extends CMSBaseUGTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PANEL_NAME = "TKSKEYS";
+ private CryptoManager mCryptoManager = null;
+
+ private AdminConnection mConnection;
+ private String mDestination;
+ private CMSBaseResourceModel mModel;
+ private ConsoleInfo mConsoleInfo;
+ private JComboBox mToken;
+ protected JScrollPane mScrollPane;
+ protected JTable mTable; //table
+ protected ListKeysModel mDataModel; //table model
+ protected KeyCreateDialog mEditor=null; //keep single copy
+
+ protected JButton mRefresh, mAdd, mHelp;
+ private final static String HELPINDEX = "configuration-log-plugin-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public TKSKeysTab(CMSBaseResourceModel model, String destination) {
+ super(PANEL_NAME, model);
+ mConnection = model.getServerInfo().getAdmin();
+ mModel = model;
+ mConsoleInfo = mModel.getConsoleInfo();
+ mDataModel = new ListKeysModel();
+ mDestination = destination;
+ mHelpToken = HELPINDEX;
+
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mRefresh)) {
+ refresh();
+ }
+ if (e.getSource().equals(mHelp)) {
+ helpCallback();
+ }
+ if (e.getSource().equals(mAdd)) {
+ if (mEditor==null)
+ mEditor = new KeyCreateDialog(mModel.getFrame(),mConnection);
+ mEditor.setToken((String)mToken.getSelectedItem());
+ mEditor.showDialog(mDestination, ScopeDef.SC_LOG_IMPLS);
+
+ //CertSetupWizardInfo info = new CertSetupWizardInfo(mConnection, mConsoleInfo);
+
+ // if it is "0", then it means it is root cert mode.
+ // if it is "1", then it means it is user cert mode.
+ //info.setMode("1");
+ //CertSetupWizard wizard = new CertSetupWizard(
+ // mModel, info);
+ refresh();
+ return;
+ }
+
+ int row = mTable.getSelectedRow();
+ if(row < 0)
+ return;
+
+
+
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+ public void refresh() {
+
+ mDataModel.removeAllRows();
+ update();
+
+ setButtons();
+ mTable.invalidate();
+ mTable.validate();
+ mTable.repaint(1);
+ }
+
+ /**
+ * create the user action button panel
+ */
+ protected JPanel createButtonPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+
+
+ mAdd = makeJButton("ADD");
+
+ JButton[] buttons = {mAdd};
+ JButtonFactory.resize( buttons );
+ JPanel rightPanel = CMSAdminUtil.makeJButtonVPanel( buttons );
+
+ return rightPanel;
+ }
+
+ protected JPanel createActionPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mRefresh = makeJButton("REFRESH");
+ mHelp = makeJButton("HELP");
+ //JButton[] buttons = { mRefresh, mHelp };
+ JButton[] buttons = { mRefresh };
+ return makeJButtonPanel(buttons, true);
+ }
+
+ protected JPanel createListPanel() {
+ mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ mToken = new JComboBox();
+ mToken.setPreferredSize(new java.awt.Dimension(54, 22));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.weightx = 0.0;
+ gbc.weighty = 0.0;
+ gbc.gridheight = 1;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE*30);
+ gb.setConstraints(mToken, gbc);
+ mListPanel.add(mToken);
+
+
+ //center table
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ //mScrollPane.setBorder(CMSAdminUtil.makeTitledBorder(mResource,PANEL_NAME,"USERS"));
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ mTable.addMouseListener(this);
+ setLabelCellRenderer(mTable,0);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = 1;
+ gbc.gridheight = 10;
+ gbc.weighty = 1.0;
+ gbc.weightx = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ JPanel buttonPanel = createButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ mListPanel.add(buttonPanel);
+
+ NameValuePairs response=null;
+ try {
+ response = mConnection.search(mDestination,
+ ScopeDef.SC_TOKEN, new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ }
+ if (response != null) {
+ mToken.removeAllItems();
+ String[] vals = new String[response.size()];
+ int i=0;
+ for (String entry : response.keySet()) {
+ vals[i++] = entry.trim();
+ }
+
+ int sindex = 0;
+ CMSAdminUtil.quickSort(vals, 0, response.size()-1);
+ for (i=0; i<vals.length; i++) {
+ Vector v = new Vector();
+ String entry = vals[i];
+ String value = response.get(entry);
+ // look for the comma separator
+
+ StringTokenizer st = new StringTokenizer(value, ",");
+ while (st.hasMoreTokens()) {
+ String currentToken= st.nextToken();
+ mToken.addItem(currentToken);
+ }
+
+ }
+ }
+
+ refresh();
+
+ return mListPanel;
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(new LabelCellRenderer(new JLabel()));
+ }
+
+
+ //set buttons
+ private void setButtons() {
+
+ //enable and diable buttons accordingly
+ //Debug.println("setButtons() - "+mTable.getSelectedRow());
+ //Debug.println("setButtons() - "+mTable.getSelectionModel().isSelectionEmpty());
+
+
+ }
+
+ //=============================================
+ // SEND REQUESTS TO THE SERVER SIDE
+ //=============================================
+ private void update() {
+ //send request and parse data
+
+ mModel.progressStart();
+
+ NameValuePairs response;
+ NameValuePairs request;
+ request = new NameValuePairs();
+ request.put(Constants.PR_TOKEN_LIST, (String) mToken.getSelectedItem());
+ try {
+ response = mConnection.search(mDestination,
+ ScopeDef.SC_TKSKEYSLIST, request);
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+
+ Debug.println(response.toString());
+
+ //parse the data
+ mDataModel.removeAllRows();
+ if (response != null) {
+ String[] vals = new String[response.size()];
+ int i=0;
+ for (String entry : response.keySet()) {
+ vals[i++] = entry.trim();
+ }
+
+ int sindex = 0;
+ CMSAdminUtil.quickSort(vals, 0, response.size()-1);
+ for (i=0; i<vals.length; i++) {
+ String entry = vals[i];
+ if (entry.equals(Constants.PR_TOKEN_LIST)) {
+ String value = response.get(entry);
+ // look for the comma separator
+ StringTokenizer st = new StringTokenizer(value, ",");
+ int numberOfKeys = 0;
+ while (st.hasMoreTokens()) {
+ Vector v = new Vector();
+ String currentKey = st.nextToken();
+ v.addElement(currentKey);
+ numberOfKeys++;
+ mDataModel.addRow(v);
+ }
+ if(numberOfKeys==0)
+ {
+ Vector v = new Vector();
+ String currentKey = new String("empty list");
+ v.addElement(currentKey);
+ mDataModel.addRow(v);
+ }
+ }
+ }
+ mTable.setRowSelectionInterval(0,0);
+ }
+
+
+ mModel.progressStop();
+ }
+
+ private void delete() {
+ mModel.progressStart();
+ int row = mTable.getSelectedRow();
+ String nickname = (String)(mDataModel.getValueAt(row, 3))+":"+
+ (String)(mDataModel.getValueAt(row, 0));
+ String id = nickname+":SERIAL#<"+mDataModel.getValueAt(row, 1)+">"
+ +mDataModel.getValueAt(row, 2);
+
+ //send comment to server for the removal of user
+ try {
+ mConnection.delete(mDestination, ScopeDef.SC_USERCERTSLIST, id);
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+ mModel.progressStop();
+ //send comment to server and refetch the content
+ refresh();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/UserCertsTab.java b/base/console/src/com/netscape/admin/certsrv/config/UserCertsTab.java
new file mode 100644
index 000000000..de0a075a1
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/UserCertsTab.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.keycert.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.ug.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * User Certs Tab
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class UserCertsTab extends CMSBaseUGTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PANEL_NAME = "USERCERTS";
+
+ private AdminConnection mConnection;
+ private String mDestination;
+ private CMSBaseResourceModel mModel;
+ private ConsoleInfo mConsoleInfo;
+
+ protected JScrollPane mScrollPane;
+ protected JTable mTable; //table
+ protected ListCertsModel mDataModel; //table model
+ protected CertViewDialog mEditor=null; //keep single copy
+
+ protected JButton mRefresh, mAdd, mDelete, mView, mHelp;
+ private final static String HELPINDEX = "configuration-log-plugin-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public UserCertsTab(CMSBaseResourceModel model, String destination) {
+ super(PANEL_NAME, model);
+ mConnection = model.getServerInfo().getAdmin();
+ mModel = model;
+ mConsoleInfo = mModel.getConsoleInfo();
+ mDataModel = new ListCertsModel();
+ mDestination = destination;
+ mHelpToken = HELPINDEX;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mRefresh)) {
+ refresh();
+ }
+ if (e.getSource().equals(mHelp)) {
+ helpCallback();
+ }
+ if (e.getSource().equals(mAdd)) {
+ CertSetupWizardInfo info = new CertSetupWizardInfo(mConnection, mConsoleInfo);
+
+ // if it is "0", then it means it is root cert mode.
+ // if it is "1", then it means it is user cert mode.
+ info.setMode("1");
+ CertSetupWizard wizard = new CertSetupWizard(
+ mModel, info);
+ refresh();
+ return;
+ }
+
+ int row = mTable.getSelectedRow();
+ if(row < 0)
+ return;
+
+ if (e.getSource().equals(mDelete)) {
+ Debug.println("Delete");
+ if(mTable.getSelectedRow()< 0)
+ return;
+ int i = showConfirmDialog("DELETE");
+ if (i == JOptionPane.YES_OPTION) {
+ delete();
+ Debug.println("Deleted");
+ }
+ }
+ if (e.getSource().equals(mView)) {
+ Debug.println("View");
+ String nickname = (String)(mTable.getValueAt(row, 3)) + ":" +
+ (String)(mTable.getValueAt(row, 0));
+ String serialno = (String)(mTable.getValueAt(row, 1));
+ String issuername = (String)(mTable.getValueAt(row, 2));
+
+ try {
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_NICK_NAME, nickname);
+ nvps.put(Constants.PR_SERIAL_NUMBER, serialno);
+ nvps.put(Constants.PR_ISSUER_NAME, issuername);
+ NameValuePairs results = mConnection.read(
+ DestDef.DEST_SERVER_ADMIN, ScopeDef.SC_CERT_PRETTY_PRINT,
+ Constants.RS_ID_CONFIG, nvps);
+ if (nvps.size() <= 0)
+ return;
+ String name = results.keySet().iterator().next(); // first element
+ String print = results.get(name);
+ CertViewDialog certdialog = new CertViewDialog(mModel.getFrame());
+ certdialog.showDialog(nickname, print);
+ } catch (EAdminException ex) {
+ CMSAdminUtil.showErrorDialog(mModel.getFrame(), mResource, ex.toString(),
+ CMSAdminUtil.ERROR_MESSAGE);
+ }
+ }
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+ public void refresh() {
+
+ mDataModel.removeAllRows();
+ update();
+
+ setButtons();
+ mTable.invalidate();
+ mTable.validate();
+ mTable.repaint(1);
+ }
+
+ /**
+ * create the user action button panel
+ */
+ protected JPanel createButtonPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mAdd = makeJButton("ADD");
+ mDelete = makeJButton("DELETE");
+ mView = makeJButton("VIEW");
+ JButton[] buttons = {mAdd, mDelete, mView};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ protected JPanel createActionPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mRefresh = makeJButton("REFRESH");
+ mHelp = makeJButton("HELP");
+ //JButton[] buttons = { mRefresh, mHelp };
+ JButton[] buttons = { mRefresh };
+ return makeJButtonPanel(buttons, true);
+ }
+
+ protected JPanel createListPanel() {
+ mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ //center table
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ //mScrollPane.setBorder(CMSAdminUtil.makeTitledBorder(mResource,PANEL_NAME,"USERS"));
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ mTable.addMouseListener(this);
+ setLabelCellRenderer(mTable,0);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = 1;
+ gbc.weightx = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ JPanel buttonPanel = createButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ mListPanel.add(buttonPanel);
+
+ refresh();
+
+ return mListPanel;
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(new LabelCellRenderer(new JLabel()));
+ }
+
+
+ //set buttons
+ private void setButtons() {
+
+ //enable and diable buttons accordingly
+ //Debug.println("setButtons() - "+mTable.getSelectedRow());
+ //Debug.println("setButtons() - "+mTable.getSelectionModel().isSelectionEmpty());
+ if (mTable.getSelectionModel().isSelectionEmpty()) {
+ mDelete.setEnabled(false);
+ mView.setEnabled(false);
+ return;
+ }
+
+ if(mDataModel.getRowCount()<=0) {
+ mDelete.setEnabled(false);
+ mView.setEnabled(false);
+ return;
+ }
+
+ mDelete.setEnabled(true);
+ mView.setEnabled(true);
+
+ }
+
+ //=============================================
+ // SEND REQUESTS TO THE SERVER SIDE
+ //=============================================
+ private void update() {
+ //send request and parse data
+
+ mModel.progressStart();
+ NameValuePairs response;
+ try {
+ response = mConnection.search(mDestination,
+ ScopeDef.SC_USERCERTSLIST, new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+
+ Debug.println(response.toString());
+
+ //parse the data
+ mDataModel.removeAllRows();
+ if (response != null) {
+ String[] vals = new String[response.size()];
+ int i=0;
+ for (String entry : response.keySet()) {
+ vals[i++] = entry.trim();
+ }
+
+ int sindex = 0;
+ String snickname = "";
+ CMSAdminUtil.quickSort(vals, 0, response.size()-1);
+ for (i=0; i<vals.length; i++) {
+ Vector v = new Vector();
+ String entry = vals[i];
+ String value = response.get(entry);
+
+ // look for the comma separator
+ int lastindex = entry.lastIndexOf(",");
+ if (lastindex != -1) {
+ String nickname = entry.substring(0, lastindex);
+ int colonindex = nickname.indexOf(":");
+ v.addElement(nickname.substring(colonindex+1));
+ v.addElement(entry.substring(lastindex+1));
+ v.addElement(value);
+ v.addElement(nickname.substring(0, colonindex));
+ mDataModel.addRow(v);
+ }
+ }
+ mTable.setRowSelectionInterval(0,0);
+ }
+
+ mModel.progressStop();
+ }
+
+ private void delete() {
+ mModel.progressStart();
+ int row = mTable.getSelectedRow();
+ String nickname = (String)(mDataModel.getValueAt(row, 3))+":"+
+ (String)(mDataModel.getValueAt(row, 0));
+ String id = nickname+":SERIAL#<"+mDataModel.getValueAt(row, 1)+">"
+ +mDataModel.getValueAt(row, 2);
+
+ //send comment to server for the removal of user
+ try {
+ mConnection.delete(mDestination, ScopeDef.SC_USERCERTSLIST, id);
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+ mModel.progressStop();
+ //send comment to server and refetch the content
+ refresh();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ViewDialog.java b/base/console/src/com/netscape/admin/certsrv/config/ViewDialog.java
new file mode 100644
index 000000000..277b3d2be
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ViewDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import javax.swing.table.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Policy Implementation Information viewer
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ViewDialog extends JDialog
+ implements ActionListener
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private String PREFIX = "VIEWDIALOG";
+
+ private JFrame mParentFrame;
+ private ResourceBundle mResource;
+ private JTextArea mTextArea;
+ private JLabel mNameField, mClassField;
+
+ private JButton mOK;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public ViewDialog(JFrame parent) {
+ super(parent,true);
+ mParentFrame = parent;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ setSize(400, 200);
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ setDisplay();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * show the windows
+ */
+ public void showDialog(String name, String classname, String desc) {
+ //initialize and setup
+ mNameField.setText(name);
+ mClassField.setText(classname);
+ mTextArea.setText(CMSAdminUtil.wrapText(desc,50));
+ mTextArea.setCaretPosition(0);
+ this.show();
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent evt) {
+ if (evt.getSource().equals(mOK)) {
+ this.hide();
+ }
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+ private void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null, this);
+ Dimension d = mOK.getMinimumSize();
+ if (d.width < CMSAdminUtil.DEFAULT_BUTTON_SIZE) {
+ d.width = CMSAdminUtil.DEFAULT_BUTTON_SIZE;
+ mOK.setMinimumSize(d);
+ }
+ JButton[] buttons = {mOK};
+ return CMSAdminUtil.makeJButtonPanel( buttons );
+ }
+
+ private JPanel makeContentPane() {
+ JPanel content = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ content.setLayout(gb3);
+ //content.setBorder(CMSAdminUtil.makeEtchedBorder());
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label1 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "NAME", null);
+ mNameField = new JLabel();
+ CMSAdminUtil.addEntryField(content, label1, mNameField, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label2 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "CLASS", null);
+ mClassField = new JLabel();
+ CMSAdminUtil.addEntryField(content, label2, mClassField, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label3 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "DESC", null);
+ label3.setHorizontalAlignment(JLabel.RIGHT);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc. insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ gb3.setConstraints(label3, gbc);
+ content.add(label3);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mTextArea = new JTextArea("",30,10);
+ mTextArea.setFont(mClassField.getFont());
+ mTextArea.setEditable(false);
+ mTextArea.setBackground(getBackground());
+ JScrollPane scrollPanel = new JScrollPane(mTextArea,
+ JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ scrollPanel.setAlignmentX(LEFT_ALIGNMENT);
+ scrollPanel.setAlignmentY(TOP_ALIGNMENT);
+ scrollPanel.setBackground(getBackground());
+ scrollPanel.setBorder(BorderFactory.createEmptyBorder());
+ scrollPanel.setPreferredSize(new Dimension(300, 500));
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx=1.0;
+ gbc.weighty=1.0;
+ gb3.setConstraints(scrollPanel, gbc);
+ content.add(scrollPanel);
+
+ return content;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ViewSelfTestsDialog.java b/base/console/src/com/netscape/admin/certsrv/config/ViewSelfTestsDialog.java
new file mode 100644
index 000000000..09d7892ef
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ViewSelfTestsDialog.java
@@ -0,0 +1,172 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+
+/**
+ * Self Tests Implementation Information viewer
+ *
+ * @author Matthew Harmsen
+ * @author Thomas Kwan
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ViewSelfTestsDialog extends JDialog
+ implements ActionListener
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private JFrame mParentFrame;
+ private JTextArea mTextArea;
+ private JButton mOK;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public ViewSelfTestsDialog( JFrame parent, String title )
+ {
+ super( parent, true );
+ mParentFrame = parent;
+ setSize( 550, 150 );
+ setTitle( title );
+ setLocationRelativeTo( parent );
+ getRootPane().setDoubleBuffered( true );
+ setDisplay();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * show the description
+ */
+ public void showDialog( String desc )
+ {
+ //initialize and setup
+ mTextArea.setText( CMSAdminUtil.wrapText( desc, 80 ) );
+ mTextArea.setCaretPosition( 0 );
+ this.show();
+ }
+
+ /*==========================================================
+ * EVENT HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed( ActionEvent evt )
+ {
+ if( evt.getSource().equals( mOK ) ) {
+ this.hide();
+ }
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+ private void setDisplay()
+ {
+ getContentPane().setLayout( new BorderLayout() );
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout( gb );
+
+ //content panel
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC( gbc );
+ gbc.fill = gbc.BOTH;
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints( content, gbc );
+ center.add( content );
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC( gbc );
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints( action, gbc );
+ center.add( action );
+
+ getContentPane().add( "Center", center );
+ }
+
+ private JPanel makeActionPane()
+ {
+ // add OK button
+ mOK = new JButton();
+ mOK.setText( "OK" );
+ mOK.addActionListener( this );
+ Dimension d = mOK.getMinimumSize();
+ if( d.width < CMSAdminUtil.DEFAULT_BUTTON_SIZE ) {
+ d.width = CMSAdminUtil.DEFAULT_BUTTON_SIZE;
+ mOK.setMinimumSize( d );
+ }
+ JButton[] buttons = { mOK };
+ return CMSAdminUtil.makeJButtonPanel( buttons );
+ }
+
+ private JPanel makeContentPane()
+ {
+ JPanel content = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ content.setLayout( gb3 );
+
+ CMSAdminUtil.resetGBC( gbc );
+ mTextArea = new JTextArea( "" );
+ mTextArea.setEditable( false );
+ mTextArea.setBackground( getBackground() );
+
+ JScrollPane
+ scrollPanel = new JScrollPane( mTextArea,
+ JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER );
+ scrollPanel.setAlignmentX( LEFT_ALIGNMENT );
+ scrollPanel.setAlignmentY( TOP_ALIGNMENT );
+ scrollPanel.setBackground( getBackground() );
+ scrollPanel.setBorder( BorderFactory.createLoweredBevelBorder() );
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb3.setConstraints( scrollPanel, gbc );
+ content.add( scrollPanel );
+
+ return content;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/ViewTableModel.java b/base/console/src/com/netscape/admin/certsrv/config/ViewTableModel.java
new file mode 100644
index 000000000..f634a182c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/ViewTableModel.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+
+/**
+ * Table Model for viewing configuration parameters
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class ViewTableModel extends CMSTableModel {
+ private static String[] mColumns = {CONFIG, VALUE};
+
+ public ViewTableModel() {
+ init(mColumns);
+ }
+
+ public boolean isCellEditable(int row, int col) {
+ return false;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/WBaseCertExtensionPage.java b/base/console/src/com/netscape/admin/certsrv/config/WBaseCertExtensionPage.java
new file mode 100644
index 000000000..6c92ed61e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/WBaseCertExtensionPage.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.admin.certsrv.config;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.install.InstallWizardInfo;
+
+/**
+ * Base class for the Certificate Extension wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+public class WBaseCertExtensionPage extends WizardBasePanel {
+ protected JCheckBox mMIMECheckBox, mBasicCheckBox, mExtendedKeyCheckBox;
+ protected JCheckBox mAKICheckBox, mSKICheckBox;
+ protected JCheckBox mCACheckBox, mCertPathBox, mKeyUsageBox;
+ protected JTextField mCertPathText;
+ protected JTextArea mMIMEText;
+ protected JLabel mCMCLabel;
+ protected JButton mPaste;
+ protected byte[] mDerByte;
+ protected Color mActiveColor;
+ protected JCheckBox mSSLClient, mSSLServer, mSSLMail, mObjectSigning, mTimeStamping;
+ protected JCheckBox mOCSPSigning, mOCSPNoCheck, mAIACheckBox;
+ protected static final String DEFAULT_CERT_LEN = "100";
+ protected String mPanelName;
+ protected boolean mModified=false;
+
+ public WBaseCertExtensionPage(String panelName) {
+ super(panelName);
+ }
+
+ public boolean validatePanel() {
+ if (mCertPathBox.isSelected()) {
+ String str = mCertPathText.getText().trim();
+ if (str.equals("")) {
+ setErrorMessage("BLANKLEN");
+ return false;
+ }
+
+ int len = 0;
+ try {
+ len = Integer.parseInt(str);
+ } catch (NumberFormatException e) {
+ setErrorMessage("NONINTEGER");
+ return false;
+ }
+
+ if (len < 0) {
+ setErrorMessage("INVALID");
+ return false;
+ }
+
+ }
+
+ if (mMIMECheckBox.isSelected()) {
+ String derString = mMIMEText.getText().trim();
+ if (derString.equals("")) {
+ setErrorMessage("DERBLANKFIELD");
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ if (!mModified) {
+ boolean basicConstraints = mBasicCheckBox.isSelected();
+ boolean extendedKey = mExtendedKeyCheckBox.isSelected();
+ boolean derExt = mMIMECheckBox.isSelected();
+
+ if (basicConstraints)
+ enableBasicConstraints(basicConstraints, mActiveColor);
+ else
+ enableBasicConstraints(basicConstraints, getBackground());
+
+ enableExtendedKey(extendedKey);
+
+ if (derExt)
+ enableMIMEExt(derExt, mActiveColor);
+ else
+ enableMIMEExt(derExt, getBackground());
+ }
+
+ if (info instanceof InstallWizardInfo) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ // If signed by self, no request will be generated
+ // check if a signing cert installed, make cmc note invisible
+ String type = wizardInfo.getCertType();
+ if ((type.equals(Constants.PR_KRA_TRANSPORT_CERT) &&
+ wizardInfo.isKRACertLocalCA()) ||
+ (type.equals(Constants.PR_SERVER_CERT) &&
+ wizardInfo.isSSLCertLocalCA()) ||
+ type.equals(Constants.PR_OCSP_SIGNING_CERT) ||
+ (type.equals(Constants.PR_CA_SIGNING_CERT) &&
+ wizardInfo.isCACertLocalCA()) ||
+ (type.equals(Constants.PR_SERVER_CERT) ||
+ type.equals(Constants.PR_KRA_TRANSPORT_CERT)) && (
+ (wizardInfo.isCAInstalled() &&
+ wizardInfo.isCACertInstalledDone()) ||
+ (wizardInfo.isRAInstalled() &&
+ wizardInfo.isRACertInstalledDone()) ||
+ (wizardInfo.isKRAInstalled() &&
+ wizardInfo.isKRACertInstalledDone()) ||
+ (wizardInfo.isOCSPInstalled() &&
+ wizardInfo.isOCSPCertInstalledDone()) ) ) {
+ mCMCLabel.setVisible(false);
+ CMSAdminUtil.repaintComp(mCMCLabel);
+ }
+ } else {
+ mCMCLabel.setVisible(false);
+ CMSAdminUtil.repaintComp(mCMCLabel);
+ }
+
+ return true;
+ }
+
+ protected void enableBasicConstraints(boolean enable, Color color) {
+ mCACheckBox.setEnabled(enable);
+ mCertPathBox.setEnabled(enable);
+ if (enable && !mCertPathBox.isSelected()) {
+ enableCertPath(!enable, getBackground());
+ } else {
+ enableCertPath(enable, color);
+ }
+ CMSAdminUtil.repaintComp(mCACheckBox);
+ CMSAdminUtil.repaintComp(mCertPathText);
+ }
+
+ protected void enableCertPath(boolean enable, Color color) {
+ mCertPathText.setEnabled(enable);
+ mCertPathText.setEditable(enable);
+ mCertPathText.setBackground(color);
+ CMSAdminUtil.repaintComp(mCertPathBox);
+ }
+
+ protected void enableExtendedKey(boolean enable) {
+ mSSLClient.setEnabled(enable);
+ mSSLServer.setEnabled(enable);
+ mSSLMail.setEnabled(enable);
+ mObjectSigning.setEnabled(enable);
+ mTimeStamping.setEnabled(enable);
+ mOCSPSigning.setEnabled(enable);
+
+ CMSAdminUtil.repaintComp(mSSLClient);
+ CMSAdminUtil.repaintComp(mSSLServer);
+ CMSAdminUtil.repaintComp(mSSLMail);
+ CMSAdminUtil.repaintComp(mObjectSigning);
+ CMSAdminUtil.repaintComp(mTimeStamping);
+ CMSAdminUtil.repaintComp(mOCSPSigning);
+ }
+
+ protected void enableMIMEExt(boolean enable, Color color) {
+ mMIMEText.setEnabled(enable);
+ mMIMEText.setEditable(enable);
+ mMIMEText.setBackground(color);
+ mPaste.setEnabled(enable);
+ CMSAdminUtil.repaintComp(mMIMEText);
+ CMSAdminUtil.repaintComp(mPaste);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea desc = createTextArea(mResource.getString(
+ mPanelName+"_TEXT_HEADING_LABEL"));
+ //"CERTEXTENSIONWIZARD_TEXT_HEADING_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ mBasicCheckBox = makeJCheckBox("BASIC");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ add(mBasicCheckBox, gbc);
+
+ mCACheckBox = makeJCheckBox("CA");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(0,4*COMPONENT_SPACE, 0,COMPONENT_SPACE);
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mCACheckBox, gbc);
+
+ JPanel panel = new JPanel();
+ GridBagLayout gb1 = new GridBagLayout();
+ panel.setLayout(gb1);
+
+ mCertPathBox = makeJCheckBox("CERTPATHLENGTH");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.insets = new Insets(0, 0, 0, COMPONENT_SPACE);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridheight = gbc.REMAINDER;
+ panel.add(mCertPathBox, gbc);
+
+ mCertPathText = makeJTextField(10);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.insets = new Insets(0,COMPONENT_SPACE, 0, COMPONENT_SPACE);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ panel.add(mCertPathText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0,4*COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE);
+ add(panel, gbc);
+
+/*
+ JTextArea dummy = createTextArea(" ", 1, 5);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.insets = new Insets(0,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(dummy, gbc);
+*/
+
+ mExtendedKeyCheckBox = makeJCheckBox("EXTENDEDKEY");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ add(mExtendedKeyCheckBox, gbc);
+
+ mSSLClient = makeJCheckBox("SSLCLIENT");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0,4*COMPONENT_SPACE, 0, COMPONENT_SPACE);
+ add(mSSLClient, gbc);
+
+ mSSLServer = makeJCheckBox("SSLSERVER");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0,COMPONENT_SPACE, 0, COMPONENT_SPACE);
+ add(mSSLServer, gbc);
+
+ mSSLMail = makeJCheckBox("EMAIL");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(0,COMPONENT_SPACE, 0, COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 1.0;
+ add(mSSLMail, gbc);
+
+ mObjectSigning = makeJCheckBox("OBJECTSIGNING");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0,4*COMPONENT_SPACE, 0, COMPONENT_SPACE);
+ add(mObjectSigning, gbc);
+
+ mTimeStamping = makeJCheckBox("TIMESTAMPING");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(mTimeStamping, gbc);
+
+ mOCSPSigning = makeJCheckBox("OCSPSIGNING");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(0,COMPONENT_SPACE, 0, COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 1.0;
+ add(mOCSPSigning, gbc);
+
+ mAIACheckBox = makeJCheckBox("AIA");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mAIACheckBox, gbc);
+
+ mAKICheckBox = makeJCheckBox("AKI");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mAKICheckBox, gbc);
+
+ mSKICheckBox = makeJCheckBox("SKI");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mSKICheckBox, gbc);
+
+ mOCSPNoCheck = makeJCheckBox("OCSPNOCHECK");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mOCSPNoCheck, gbc);
+
+ mCMCLabel = new JLabel(mResource.getString(
+ mPanelName + "_TEXT_CMC_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0,4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mCMCLabel, gbc);
+
+ mKeyUsageBox = makeJCheckBox("KEYUSAGE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mKeyUsageBox, gbc);
+ mKeyUsageBox.setSelected(true);
+
+ mMIMECheckBox = makeJCheckBox("MIME");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ add(mMIMECheckBox, gbc);
+
+ mMIMEText = new JTextArea("", 40, 70);
+ JScrollPane scrollPane = new JScrollPane(mMIMEText,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ scrollPane.setPreferredSize(new Dimension(50, 30));
+ //scrollPane.setAlignmentX(LEFT_ALIGNMENT);
+ //scrollPane.setAlignmentY(TOP_ALIGNMENT);
+ scrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.BOTH;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(scrollPane, gbc);
+ mActiveColor = mMIMEText.getBackground();
+
+ mPaste = makeJButton("PASTE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ add(mPaste, gbc);
+
+ super.init();
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ Object source = e.getSource();
+ if (source.equals(mPaste)) {
+ mMIMEText.paste();
+ } else if (source.equals(mBasicCheckBox)) {
+ if (mBasicCheckBox.isSelected())
+ enableBasicConstraints(true, mActiveColor);
+ else
+ enableBasicConstraints(false, getBackground());
+ } else if (source.equals(mExtendedKeyCheckBox)) {
+ if (mExtendedKeyCheckBox.isSelected())
+ enableExtendedKey(true);
+ else
+ enableExtendedKey(false);
+ } else if (source.equals(mMIMECheckBox)) {
+ if (mMIMECheckBox.isSelected())
+ enableMIMEExt(true, mActiveColor);
+ else
+ enableMIMEExt(false, getBackground());
+ } else if (source.equals(mCertPathBox)) {
+ if (mCertPathBox.isSelected())
+ enableCertPath(true, mActiveColor);
+ else
+ enableCertPath(false, getBackground());
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/WBaseCertRequestPage.java b/base/console/src/com/netscape/admin/certsrv/config/WBaseCertRequestPage.java
new file mode 100644
index 000000000..6b9a1667b
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/WBaseCertRequestPage.java
@@ -0,0 +1,261 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Certificate wizard page
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+public class WBaseCertRequestPage extends WizardBasePanel {
+ protected JButton mCopy;
+ protected JRadioButton mEmailBtn;
+ protected JRadioButton mURLBtn;
+ protected JRadioButton mManualBtn;
+ protected JTextArea mText;
+ protected JTextField mURLText;
+ protected JTextField mEmailText, mContactEmailTxt, mNameTxt, mContactPhoneTxt;
+ protected JLabel mContactPhoneLbl, mContactEmailLbl, mNameLbl;
+ protected JTextArea mContactText;
+
+ public WBaseCertRequestPage(String panelName) {
+ super(panelName);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+/*
+ JTextArea unixDesc = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "CERTREQUESTWIZARD_TEXT_UNIXDESC_LABEL"), 80), 3, 80);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(unixDesc, gbc);
+
+ JTextArea ntDesc = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "CERTREQUESTWIZARD_TEXT_NTDESC_LABEL"), 80), 3, 80);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(ntDesc, gbc);
+*/
+
+ JLabel desc = makeJLabel("DESC");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ mManualBtn = makeJRadioButton("MANUAL", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mManualBtn, gbc);
+
+ mText = new JTextArea(null, null, 0, 0);
+ //mText.setLineWrap(true);
+ //mText.setWrapStyleWord(true);
+ JScrollPane scrollPane = new JScrollPane(mText,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ scrollPane.setPreferredSize(new Dimension(50, 20));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.BOTH;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE, 0, COMPONENT_SPACE);
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(scrollPane, gbc);
+
+ mCopy = makeJButton("COPY");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mCopy, gbc);
+
+ mEmailBtn = makeJRadioButton("EMAIL", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mEmailBtn, gbc);
+
+ mEmailText = new JTextField(30);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0, COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mEmailText, gbc);
+
+ mURLBtn = makeJRadioButton("URL", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(mURLBtn, gbc);
+
+ mURLText = new JTextField(30);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mURLText, gbc);
+
+ ButtonGroup methodGroup = new ButtonGroup();
+ methodGroup.add(mEmailBtn);
+ methodGroup.add(mURLBtn);
+ methodGroup.add(mManualBtn);
+
+ mContactText = new JTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "COPYCERTREQUESTWIZARD_TEXT_CONTACT_LABEL"), 80), 2, 80);
+ mContactText.setBackground(getBackground());
+ mContactText.setEditable(false);
+ mContactText.setCaretColor(getBackground());
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.weightx = 1.0;
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(mContactText, gbc);
+
+ JPanel panel = new JPanel();
+ GridBagLayout gb1 = new GridBagLayout();
+ panel.setLayout(gb1);
+ //panel.setBorder(new EtchedBorder());
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0, 0);
+ add(panel, gbc);
+
+ mNameLbl = makeJLabel("NAME");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ panel.add(mNameLbl, gbc);
+
+ mNameTxt = new JTextField(30);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ panel.add(mNameTxt, gbc);
+
+ mContactEmailLbl = makeJLabel("EMAILADDRESS");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ panel.add(mContactEmailLbl, gbc);
+
+ mContactEmailTxt = new JTextField(30);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ panel.add(mContactEmailTxt, gbc);
+
+ mContactPhoneLbl = makeJLabel("PHONE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ panel.add(mContactPhoneLbl, gbc);
+
+ mContactPhoneTxt = new JTextField(30);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ panel.add(mContactPhoneTxt, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ panel.add(dummy, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+
+ public void actionPerformed(ActionEvent event) {
+ if (event.getSource().equals(mCopy)) {
+ mText.copy();
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/WBaseDNPage.java b/base/console/src/com/netscape/admin/certsrv/config/WBaseDNPage.java
new file mode 100644
index 000000000..97774727b
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/WBaseDNPage.java
@@ -0,0 +1,493 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import java.util.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * CA signing cert for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+public class WBaseDNPage extends WizardBasePanel implements IWizardPanel {
+ protected JTextField mCNText, mOUText, mOText, mLText, mSTText, mCText;
+ protected JTextArea mSubjectDNText;
+ public static final String CN = "CN=";
+ public static final String OU = "OU=";
+ public static final String O = "O=";
+ public static final String L = "L=";
+ public static final String ST = "ST=";
+ public static final String C = "C=";
+ public static final String cn = "cn=";
+ public static final String ou = "ou=";
+ public static final String o = "o=";
+ public static final String l = "l=";
+ public static final String st = "st=";
+ public static final String c = "c=";
+ protected JRadioButton mDNComponents;
+ protected JRadioButton mDNString;
+ protected JTextField mSubjectStringText;
+ protected JLabel cnLabel;
+ protected JLabel ouLabel;
+ protected JLabel oLabel;
+ protected JLabel lLabel;
+ protected JLabel stLabel;
+ protected JLabel cLabel;
+ protected JLabel subjectDNLabel;
+ protected Color mActiveColor;
+ //protected JTextArea dnDesc;
+ protected boolean displayWarning=false;
+ protected String mPanelName;
+
+
+ public WBaseDNPage(String panelName) {
+ super(panelName);
+ mPanelName = panelName;
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ return true;
+ }
+
+ public boolean validatePanel() {
+ String str = "";
+ if (mDNComponents.isSelected()) {
+ str = mOText.getText().trim();
+ } else {
+ String dnString = mSubjectStringText.getText().trim();
+ StringTokenizer tokenizer = new StringTokenizer(dnString, ",");
+ while (tokenizer.hasMoreTokens()) {
+ String element = ((String)tokenizer.nextToken()).trim();
+ if (element.startsWith(O) || element.startsWith(o)) {
+ int index = element.indexOf("=");
+ if (index > -1) {
+ str = element.substring(index+1);
+ break;
+ }
+ }
+ }
+ }
+
+ if (str.equals("") && !displayWarning) {
+ String errorMsg =
+ mResource.getString(mPanelName+"_DIALOG_MISSINGO_MESSAGE");
+ JOptionPane.showMessageDialog(new JFrame(), errorMsg, "Warning",
+ JOptionPane.WARNING_MESSAGE,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_WARN_ICON));
+/*
+ WarningDialog dialog = new WarningDialog(new JFrame(),
+ "_TEXT_MISSINGO_LABEL");
+*/
+ displayWarning = true;
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+
+ protected void populateDN(String str) {
+ StringTokenizer tokenizer = new StringTokenizer(str, ",");
+ boolean isDNString = false;
+ while (tokenizer.hasMoreTokens()) {
+ String element = (String)tokenizer.nextToken();
+ element = element.trim();
+ int index = element.indexOf('=');
+ String val = element.substring(index+1);
+ if (element.startsWith(CN) || element.startsWith(cn)) {
+ mCNText.setText(val);
+ } else if (element.startsWith(OU) || element.startsWith(ou)) {
+ mOUText.setText(val);
+ } else if (element.startsWith(O) || element.startsWith(o)) {
+ mOText.setText(val);
+ } else if (element.startsWith(L) || element.startsWith(l)) {
+ mLText.setText(val);
+ } else if (element.startsWith(ST) || element.startsWith(st)) {
+ mSTText.setText(val);
+ } else if (element.startsWith(C) || element.startsWith(c)) {
+ mCText.setText(val);
+ } else {
+ isDNString = true;
+ }
+ }
+
+ mSubjectStringText.setText(str);
+
+ if (isDNString) {
+ mDNString.setSelected(true);
+ enableFields(false, getBackground());
+ } else {
+ mDNComponents.setSelected(true);
+ enableFields(true, mActiveColor);
+ }
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+/*
+ JLabel currentDN = makeJLabel("SUBJECTNAME");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(currentDN, gbc);
+
+ dnDesc = createTextArea(" ", 2, 80);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(dnDesc, gbc);
+*/
+
+/*
+ JTextArea desc = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "CACERT2WIZARD_TEXT_DN_LABEL"), 80), 1, 80);
+*/
+
+ JTextArea desc = createTextArea(mResource.getString(
+ mPanelName+"_LABEL_DN_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ mDNComponents = makeJRadioButton("DNCOMP", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mDNComponents, gbc);
+
+ cnLabel = makeJLabel("CN");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(cnLabel, gbc);
+
+ mCNText = new JTextField(30);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mCNText, gbc);
+
+/*
+ JTextArea dummy = createTextArea(" ", 1, 1);
+ CMSAdminUtil.addComponents(this, cnLabel, mCNText, dummy, gbc);
+*/
+ //CMSAdminUtil.addComponents(this, cnLabel, mCNText, gbc);
+
+ ouLabel = makeJLabel("OU");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,4*COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(ouLabel, gbc);
+
+ mOUText = new JTextField(30);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mOUText, gbc);
+
+/*
+ JTextArea dummy1 = createTextArea(" ", 1, 1);
+ CMSAdminUtil.addComponents(this, ouLabel, mOUText, dummy1, gbc);
+*/
+// CMSAdminUtil.addComponents(this, ouLabel, mOUText, gbc);
+
+ oLabel = makeJLabel("O");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(oLabel, gbc);
+
+ mOText = new JTextField(30);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mOText, gbc);
+
+/*
+ JTextArea dummy2 = createTextArea(" ", 1, 1);
+ CMSAdminUtil.addComponents(this, oLabel, mOText, dummy2, gbc);
+*/
+ //CMSAdminUtil.addComponents(this, oLabel, mOText, gbc);
+
+ lLabel = makeJLabel("LOCALITY");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(lLabel, gbc);
+
+ mLText = new JTextField(30);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mLText, gbc);
+/*
+ JTextArea dummy3 = createTextArea(" ", 1, 1);
+ CMSAdminUtil.addComponents(this, lLabel, mLText, dummy3, gbc);
+*/
+ //CMSAdminUtil.addComponents(this, lLabel, mLText, gbc);
+
+ stLabel = makeJLabel("STATE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(stLabel, gbc);
+
+ mSTText = new JTextField(30);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mSTText, gbc);
+/*
+ JTextArea dummy4 = createTextArea(" ", 1, 1);
+ CMSAdminUtil.addComponents(this, stLabel, mSTText, dummy4, gbc);
+*/
+ //CMSAdminUtil.addComponents(this, stLabel, mSTText, gbc);
+
+ cLabel = makeJLabel("COUNTRY");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(cLabel, gbc);
+
+ mCText = new JTextField(30);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mCText, gbc);
+/*
+ JTextArea dummy5 = createTextArea(" ", 1, 1);
+ CMSAdminUtil.addComponents(this, cLabel, mCText, dummy5, gbc);
+*/
+ //CMSAdminUtil.addComponents(this, cLabel, mCText, gbc);
+
+ subjectDNLabel = makeJLabel("SELECTEDDN");
+ mSubjectDNText = new SubjectDNTextArea(3, 30);
+ mSubjectDNText.setLineWrap(true);
+ mSubjectDNText.setBackground(getBackground());
+ mSubjectDNText.setEditable(false);
+ mSubjectDNText.setCaretColor(getBackground());
+ CMSAdminUtil.resetGBC(gbc);
+ //gbc.weighty = 1.0;
+ CMSAdminUtil.addComponents(this, subjectDNLabel, mSubjectDNText, gbc);
+
+ mDNString = makeJRadioButton("DNSTRING", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mDNString, gbc);
+
+ ButtonGroup group = new ButtonGroup();
+ group.add(mDNString);
+ group.add(mDNComponents);
+
+ mSubjectStringText = new JTextField(256);
+/*
+ mSubjectStringText = new JTextArea(null, null, 0, 0);
+ mSubjectStringText.setBorder(BorderFactory.createLineBorder(Color.black));
+ JScrollPane scrollPane = new JScrollPane(mSubjectStringText,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ scrollPane.setPreferredSize(new Dimension(50, 20));
+*/
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ //gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mSubjectStringText, gbc);
+ //mSubjectStringText.setLineWrap(true);
+ mActiveColor = mCNText.getBackground();
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel d1 = new JLabel();
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(d1, gbc);
+
+
+ mCNText.getDocument().addDocumentListener((DocumentListener)mSubjectDNText);
+ mOUText.getDocument().addDocumentListener((DocumentListener)mSubjectDNText);
+ mOText.getDocument().addDocumentListener((DocumentListener)mSubjectDNText);
+ mLText.getDocument().addDocumentListener((DocumentListener)mSubjectDNText);
+ mSTText.getDocument().addDocumentListener((DocumentListener)mSubjectDNText);
+ mCText.getDocument().addDocumentListener((DocumentListener)mSubjectDNText);
+
+ super.init();
+ }
+
+ protected void enableFields(boolean enable, Color color) {
+ CMSAdminUtil.enableJTextField(mCNText, enable, color);
+ CMSAdminUtil.enableJTextField(mOUText, enable, color);
+ CMSAdminUtil.enableJTextField(mOText, enable, color);
+ CMSAdminUtil.enableJTextField(mLText, enable, color);
+ CMSAdminUtil.enableJTextField(mSTText, enable, color);
+ CMSAdminUtil.enableJTextField(mCText, enable, color);
+ cnLabel.setEnabled(enable);
+ ouLabel.setEnabled(enable);
+ oLabel.setEnabled(enable);
+ lLabel.setEnabled(enable);
+ stLabel.setEnabled(enable);
+ cLabel.setEnabled(enable);
+ subjectDNLabel.setEnabled(enable);
+ CMSAdminUtil.repaintComp(cnLabel);
+ CMSAdminUtil.repaintComp(ouLabel);
+ CMSAdminUtil.repaintComp(oLabel);
+ CMSAdminUtil.repaintComp(lLabel);
+ CMSAdminUtil.repaintComp(stLabel);
+ CMSAdminUtil.repaintComp(cLabel);
+ CMSAdminUtil.repaintComp(subjectDNLabel);
+ if (enable)
+ CMSAdminUtil.enableJTextField(mSubjectStringText, !enable,
+ getBackground());
+ else
+ CMSAdminUtil.enableJTextField(mSubjectStringText, !enable,
+ mActiveColor);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (mDNComponents.isSelected()) {
+ enableFields(true, mActiveColor);
+ } else {
+ enableFields(false, getBackground());
+ }
+ }
+
+ public class SubjectDNTextArea extends JTextArea implements
+ DocumentListener {
+
+ public SubjectDNTextArea(int rows, int columns) {
+ super(rows, columns);
+ }
+
+ public void insertUpdate(DocumentEvent e) {
+ super.setText(updateStr());
+ }
+
+ public void removeUpdate(DocumentEvent e) {
+ super.setText(updateStr());
+ }
+
+ public void changedUpdate(DocumentEvent e) {
+ super.setText(updateStr());
+ }
+
+ private String updateStr() {
+ String cnStr = mCNText.getText().trim();
+ String ouStr = mOUText.getText().trim();
+ String oStr = mOText.getText().trim();
+ String lStr = mLText.getText().trim();
+ String stStr = mSTText.getText().trim();
+ String cStr = mCText.getText().trim();
+
+ String result = "";
+ result = result+appendStr(result, CN, cnStr);
+ result = result+appendStr(result, OU, ouStr);
+ result = result+appendStr(result, O, oStr);
+ result = result+appendStr(result, L, lStr);
+ result = result+appendStr(result, ST, stStr);
+ result = result+appendStr(result, C, cStr);
+
+ return result;
+ }
+
+ private String appendStr(String origStr, String prefix, String suffix) {
+ String result = "";
+ if (suffix.equals(""))
+ return result;
+
+ result = prefix + suffix;
+ if (!origStr.equals("")) {
+ result = ", "+result;
+ }
+ return result;
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/WBaseDNValidityPage.java b/base/console/src/com/netscape/admin/certsrv/config/WBaseDNValidityPage.java
new file mode 100644
index 000000000..3a5837624
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/WBaseDNValidityPage.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.admin.certsrv.config;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * CA signing cert for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+public class WBaseDNValidityPage extends WizardBasePanel {
+ public JTextField mCNText, mOUText, mOText, mLText, mSTText, mCText;
+ public JTextField mValidityText;
+ public JComboBox mUnitBox;
+ public JLabel validityLbl;
+ public JTextArea mSubjectDNText, desc1;
+ public static final String CN = "CN=";
+ public static final String OU = "OU=";
+ public static final String O = "O=";
+ public static final String L = "L=";
+ public static final String ST = "ST=";
+ public static final String C = "C=";
+
+ public WBaseDNValidityPage(String panelName) {
+ super(panelName);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea desc = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "CACERT2WIZARD_TEXT_DN_LABEL"), 80), 1, 80);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ JLabel cnLabel = makeJLabel("CN");
+ mCNText = new JTextField(30);
+/*
+ JTextArea dummy = createTextArea(" ", 1, 1);
+ CMSAdminUtil.addComponents(this, cnLabel, mCNText, dummy, gbc);
+*/
+ CMSAdminUtil.addComponents(this, cnLabel, mCNText, gbc);
+
+ JLabel ouLabel = makeJLabel("OU");
+ mOUText = new JTextField(30);
+/*
+ JTextArea dummy1 = createTextArea(" ", 1, 1);
+ CMSAdminUtil.addComponents(this, ouLabel, mOUText, dummy1, gbc);
+*/
+ CMSAdminUtil.addComponents(this, ouLabel, mOUText, gbc);
+
+ JLabel oLabel = makeJLabel("O");
+ mOText = new JTextField(30);
+/*
+ JTextArea dummy2 = createTextArea(" ", 1, 1);
+ CMSAdminUtil.addComponents(this, oLabel, mOText, dummy2, gbc);
+*/
+ CMSAdminUtil.addComponents(this, oLabel, mOText, gbc);
+
+ JLabel lLabel = makeJLabel("LOCALITY");
+ mLText = new JTextField(30);
+/*
+ JTextArea dummy3 = createTextArea(" ", 1, 1);
+ CMSAdminUtil.addComponents(this, lLabel, mLText, dummy3, gbc);
+*/
+ CMSAdminUtil.addComponents(this, lLabel, mLText, gbc);
+
+ JLabel stLabel = makeJLabel("STATE");
+ mSTText = new JTextField(30);
+/*
+ JTextArea dummy4 = createTextArea(" ", 1, 1);
+ CMSAdminUtil.addComponents(this, stLabel, mSTText, dummy4, gbc);
+*/
+ CMSAdminUtil.addComponents(this, stLabel, mSTText, gbc);
+
+ JLabel cLabel = makeJLabel("COUNTRY");
+ mCText = new JTextField(30);
+/*
+ JTextArea dummy5 = createTextArea(" ", 1, 1);
+ CMSAdminUtil.addComponents(this, cLabel, mCText, dummy5, gbc);
+*/
+ CMSAdminUtil.addComponents(this, cLabel, mCText, gbc);
+
+ JLabel subjectDNLabel = makeJLabel("SELECTEDDN");
+ mSubjectDNText = new SubjectDNTextArea(3, 30);
+ mSubjectDNText.setLineWrap(true);
+ mSubjectDNText.setBackground(getBackground());
+ mSubjectDNText.setEditable(false);
+ mSubjectDNText.setCaretColor(getBackground());
+ CMSAdminUtil.resetGBC(gbc);
+ //gbc.weighty = 1.0;
+ CMSAdminUtil.addComponents(this, subjectDNLabel, mSubjectDNText, gbc);
+
+ desc1 = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "CACERT2WIZARD_TEXT_VALIDITY_LABEL"), 80), 1, 80);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc1, gbc);
+
+ validityLbl = makeJLabel("VALIDITY");
+ mValidityText = new JTextField(5);
+ mUnitBox = makeJComboBox("VALIDITY");
+ gbc.weighty = 1.0;
+ CMSAdminUtil.addComponents(this, validityLbl, mValidityText, mUnitBox,
+ gbc);
+
+ mCNText.getDocument().addDocumentListener((DocumentListener)mSubjectDNText);
+ mOUText.getDocument().addDocumentListener((DocumentListener)mSubjectDNText);
+ mOText.getDocument().addDocumentListener((DocumentListener)mSubjectDNText);
+ mLText.getDocument().addDocumentListener((DocumentListener)mSubjectDNText);
+ mSTText.getDocument().addDocumentListener((DocumentListener)mSubjectDNText);
+ mCText.getDocument().addDocumentListener((DocumentListener)mSubjectDNText);
+
+ super.init();
+ }
+
+ public class SubjectDNTextArea extends JTextArea implements
+ DocumentListener {
+
+ public SubjectDNTextArea(int rows, int columns) {
+ super(rows, columns);
+ }
+
+ public void insertUpdate(DocumentEvent e) {
+ super.setText(updateStr());
+ }
+
+ public void removeUpdate(DocumentEvent e) {
+ super.setText(updateStr());
+ }
+
+ public void changedUpdate(DocumentEvent e) {
+ super.setText(updateStr());
+ }
+
+ private String updateStr() {
+ String cnStr = mCNText.getText().trim();
+ String ouStr = mOUText.getText().trim();
+ String oStr = mOText.getText().trim();
+ String lStr = mLText.getText().trim();
+ String stStr = mSTText.getText().trim();
+ String cStr = mCText.getText().trim();
+
+ String result = "";
+ result = result+appendStr(result, CN, cnStr);
+ result = result+appendStr(result, OU, ouStr);
+ result = result+appendStr(result, O, oStr);
+ result = result+appendStr(result, L, lStr);
+ result = result+appendStr(result, ST, stStr);
+ result = result+appendStr(result, C, cStr);
+
+ return result;
+ }
+
+ private String appendStr(String origStr, String prefix, String suffix) {
+ String result = "";
+ if (suffix.equals(""))
+ return result;
+
+ result = prefix + suffix;
+ if (!origStr.equals("")) {
+ result = ", "+result;
+ }
+ return result;
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/WBaseKeyPage.java b/base/console/src/com/netscape/admin/certsrv/config/WBaseKeyPage.java
new file mode 100644
index 000000000..1266099b1
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/WBaseKeyPage.java
@@ -0,0 +1,248 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Setup CA signing cert for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+public class WBaseKeyPage extends WizardBasePanel {
+ protected JComboBox mKeyTypeBox;
+ protected JComboBox mKeyLengthBox;
+ //protected JComboBox mTokenBox;
+ //protected JPasswordField mPasswordText;
+ protected JTextField mKeyLengthText;
+
+ public WBaseKeyPage(String panelName) {
+ super(panelName);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea desc = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "CACERT1CUSTOMWIZARD_TEXT_HEADING_LABEL"), 80), 2, 80);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+/*
+ JTextArea desc1 = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "CACERT1CUSTOMWIZARD_TEXT_TOKENHEADING_LABEL"), 80), 1, 80);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc1, gbc);
+
+ JLabel tokenLbl = makeJLabel("TOKEN");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(tokenLbl, gbc);
+
+ mTokenBox = new JComboBox();
+ mTokenBox.addItem("internal");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,0,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(mTokenBox, gbc);
+
+ JTextArea dummy = createTextArea(" ", 1, 5);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,0,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(dummy, gbc);
+*/
+
+/*
+ JTextArea desc2 = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "CACERT1CUSTOMWIZARD_TEXT_HARDWARE_LABEL"), 80), 1, 80);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(2*COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc2, gbc);
+
+ JLabel pwdLbl = makeJLabel("PWD");
+ mPasswordText = makeJPasswordField(20);
+ //JTextArea dummy1 = createTextArea(" ", 1, 10);
+ //CMSAdminUtil.addComponents(this, pwdLbl, mPasswordText, dummy1, gbc);
+ CMSAdminUtil.addComponents(this, pwdLbl, mPasswordText, gbc);
+*/
+
+ JTextArea desc3 = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "CACERT1CUSTOMWIZARD_TEXT_KEY_LABEL"), 80), 1, 80);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(2*COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc3, gbc);
+
+/*
+ JLabel keyTypeLbl = makeJLabel("KEYTYPE");
+ mKeyTypeBox = makeJComboBox("KEYTYPE");
+ //JTextArea dummy2 = createTextArea(" ", 1, 10);
+ //CMSAdminUtil.addComponents(this, keyTypeLbl, mKeyTypeBox, dummy2, gbc);
+ CMSAdminUtil.addComponents(this, keyTypeLbl, mKeyTypeBox, gbc);
+*/
+
+ JPanel panel = new JPanel();
+ GridBagLayout gb1 = new GridBagLayout();
+ panel.setLayout(gb1);
+
+ JLabel keyTypeLbl = makeJLabel("KEYTYPE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel.add(keyTypeLbl, gbc);
+
+ mKeyTypeBox = makeJComboBox("KEYTYPE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ panel.add(mKeyTypeBox, gbc);
+
+ JLabel keyLengthLbl = makeJLabel("KEYLENGTH");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ //gbc.weighty = 1.0;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,0,COMPONENT_SPACE);
+ panel.add(keyLengthLbl, gbc);
+
+ mKeyLengthBox = makeJComboBox("KEYLENGTH");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ //gbc.weighty = 1.0;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,0,COMPONENT_SPACE);
+ panel.add(mKeyLengthBox, gbc);
+
+ JLabel unitLbl = makeJLabel("UNITS");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ //gbc.weighty = 1.0;
+ gbc.insets = new Insets(0, 0,0,COMPONENT_SPACE);
+ panel.add(unitLbl, gbc);
+
+ JPanel panel1 = new JPanel();
+ GridBagLayout gb2 = new GridBagLayout();
+ panel1.setLayout(gb2);
+
+ JLabel keyLengthCustomLbl = makeJLabel("KEYLENGTH");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,0,COMPONENT_SPACE);
+ panel1.add(keyLengthCustomLbl, gbc);
+
+ mKeyLengthText = makeJTextField(7);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, 0, 0);
+ panel1.add(mKeyLengthText, gbc);
+
+ JLabel unit1Lbl = makeJLabel("UNITS");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, 0, COMPONENT_SPACE);
+ panel1.add(unit1Lbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ add(panel, gbc);
+
+ JTextArea keyLengthCustomText = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "CACERT1CUSTOMWIZARD_TEXT_CUSTOMKEY_LABEL"), 80), 1, 80);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(keyLengthCustomText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ add(panel1, gbc);
+
+ super.init();
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/WBaseManualCertRequestPage.java b/base/console/src/com/netscape/admin/certsrv/config/WBaseManualCertRequestPage.java
new file mode 100644
index 000000000..195979f9c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/WBaseManualCertRequestPage.java
@@ -0,0 +1,508 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import java.util.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.install.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Certificate wizard page
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+public class WBaseManualCertRequestPage extends WizardBasePanel {
+
+ 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";
+
+ public static final String CERT_TYPE = "certType";
+ public static final String PKCS10_REQUEST = "pkcs10Request";
+ public static final String CMC_REQUEST = "cmcRequest";
+
+ protected JButton mCopy;
+ protected JTextArea mText;
+ protected String mPanelName, mDir;
+ protected JTextArea mFileName;
+ protected JTextArea mDesc;
+
+ protected JTextField mHostText, mPortText;
+ protected JLabel mHostLbl, mPortLbl;
+ protected JLabel mSSLText;
+ protected JCheckBox mSSL; // ssl or not
+ protected String mHost, mPort;
+ protected JLabel mSendNowText;
+ protected JCheckBox mSendNowBox;
+ protected Color mActiveColor;
+ public static final int MAX_PORT = 65535;
+ public static final int MIN_PORT = 1;
+ protected String mReq = null;
+ protected String mReqType = null;
+ protected String mReqFormat = null;
+
+ public WBaseManualCertRequestPage(String panelName) {
+ super(panelName);
+ mPanelName = panelName;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ mReqType = wizardInfo.getCertType();
+ mReqFormat = wizardInfo.getReqFormat(mReqType);
+
+ if (mReqType.equals(Constants.PR_CA_SIGNING_CERT)){
+ mReq = (String)wizardInfo.get(ConfigConstants.CA_CERT_REQUEST);
+ }else if (mReqType.equals(Constants.PR_SERVER_CERT) ){
+ mReq = (String)wizardInfo.get(ConfigConstants.SSL_CERT_REQUEST);
+ }else if (mReqType.equals(Constants.PR_KRA_TRANSPORT_CERT)){
+ mReq = (String)wizardInfo.get(ConfigConstants.KRA_CERT_REQUEST);
+ }else if (mReqType.equals(Constants.PR_OCSP_SIGNING_CERT)){
+ mReq = (String)wizardInfo.get(ConfigConstants.OCSP_CERT_REQUEST);
+ }else if (mReqType.equals(Constants.PR_RA_SIGNING_CERT)){
+ mReq = (String)wizardInfo.get(ConfigConstants.RA_CERT_REQUEST);
+ Debug.println("no request got from ra stage");
+ }else {
+ setErrorMessage("Wrong cert request type!");
+ return false;
+ }
+
+ if (mReq == null || mReq.equals("")){
+ mReq = wizardInfo.getCertRequest();
+ }
+ if (mReqFormat.equals(ConfigConstants.PR_REQUEST_PKCS10)){
+
+ // Break the long single line:header,64 byte lines,trailer
+ // Assuming this is the only format we generate.
+ String CERT_NEW_REQUEST_HEADER = "-----BEGIN NEW CERTIFICATE REQUEST-----";
+ String CERT_NEW_REQUEST_TRAILER = "-----END NEW CERTIFICATE REQUEST-----";
+ int head = mReq.indexOf(CERT_NEW_REQUEST_HEADER);
+ int trail = mReq.indexOf(CERT_NEW_REQUEST_TRAILER);
+ String unwrapped =
+ mReq.substring(head+CERT_NEW_REQUEST_HEADER.length(),trail);
+ String str = CERT_NEW_REQUEST_HEADER + "\n";
+ int len = unwrapped.length();
+ for (int i = 0; i < len; i=i+64){
+ if (i+64 < len)
+ str = str + unwrapped.substring(i,i+64) +"\n";
+ else
+ str = str + unwrapped.substring(i,len) +"\n";
+ }
+ str = str + CERT_NEW_REQUEST_TRAILER;
+ mReq = str;
+ } else if (mReqFormat.equals(ConfigConstants.PR_REQUEST_CMC)){
+ String str = "";
+ int len = mReq.length();
+ for (int i = 0; i < len; i=i+64){
+ if (i+64 < len)
+ str = str + mReq.substring(i,i+64) +"\n";
+ else
+ str = str + mReq.substring(i,len) +"\n";
+ }
+ mReq = str;
+ }
+
+ if (mReq == null)
+ return false;
+ mText.setText(mReq);
+
+ mText.selectAll();
+ setBorder(makeTitledBorder(mPanelName));
+
+ mDir = wizardInfo.getCertRequestDir();
+ String str = mResource.getString(mPanelName+"_TEXT_FILELOC_LABEL")+mDir+".";
+ mFileName.setText(str);
+
+ if (mSendNowBox.isSelected())
+ enableFields(true, mActiveColor);
+ else
+ enableFields(false, getBackground());
+
+ String host = wizardInfo.getCMHost();
+ if (host != null && !host.equals(""))
+ mHostText.setText(host);
+ String port = wizardInfo.getCMEEPort();
+ if (port != null && !port.equals(""))
+ mPortText.setText(port);
+
+ String portType = wizardInfo.getCMEEType();
+ if (portType != null && portType.equals("http"))
+ mSSL.setSelected(false);
+
+ String desc = "";
+ if (!wizardInfo.isNewRequest()) {
+ desc = mResource.getString(mPanelName+"_TEXT_IGNOR_LABEL")+
+ "\n";
+ }
+ String certType = wizardInfo.getCertType();
+ if (mReqFormat.equals(ConfigConstants.PR_REQUEST_PKCS10)) {
+ desc = desc + mResource.getString( mPanelName+"_TEXT_DESC_LABEL");
+ } else if (mReqFormat.equals(ConfigConstants.PR_REQUEST_CMC)) {
+ desc = desc + mResource.getString(
+ mPanelName+"_TEXT_CMCDESC_LABEL");
+ }
+ mDesc.setText(desc);
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ if (!mSendNowBox.isSelected()) {
+ mHost = "";
+ mPort = "";
+ return true;
+ }
+
+ mHost = mHostText.getText().trim();
+ mPort = mPortText.getText().trim();
+ if (mHost.equals("")) {
+ setErrorMessage("BLANKHOST");
+ return false;
+ }
+ if (mPort.equals("")) {
+ setErrorMessage("BLANKPORT");
+ return false;
+ }
+
+ try {
+ int portnumber = Integer.parseInt(mPort);
+ if (portnumber < MIN_PORT || portnumber > MAX_PORT) {
+ setErrorMessage("OUTOFRANGE");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ setErrorMessage("INVALIDPORT");
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ if (!mSendNowBox.isSelected())
+ return true;
+
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (mHost != null && !mHost.equals(""))
+ wizardInfo.setCMHost(mHost);
+ if (mPort != null && !mPort.equals(""))
+ wizardInfo.setCMEEPort(mPort);
+ if (mSSL.isSelected())
+ wizardInfo.setCMEEType("https");
+ else
+ wizardInfo.setCMEEType("http");
+
+ CMSRequestCert requestCertCgi = new CMSRequestCert();
+ requestCertCgi.initialize(wizardInfo);
+ Hashtable data = new Hashtable();
+
+ String certType = null;
+ if (mReqType.equals(Constants.PR_CA_SIGNING_CERT)){
+ data.put("profileId", "caCACert");
+ }else if (mReqType.equals(Constants.PR_SERVER_CERT) ||
+ mReqType.equals(Constants.PR_KRA_TRANSPORT_CERT)){
+ data.put("profileId", "caServerCert");
+ }else if (mReqType.equals(Constants.PR_OCSP_SIGNING_CERT)){
+ data.put("profileId", "caOCSPCert");
+ }else if (mReqType.equals(Constants.PR_RA_SIGNING_CERT)){
+ data.put("profileId", "caRACert");
+ }else {
+ setErrorMessage("Wrong cert request type!");
+ return false;
+ }
+
+ if (mReqFormat.equals(ConfigConstants.PR_REQUEST_PKCS10)){
+ data.put("cert_request_type", "pkcs10");
+ data.put("cert_request", mReq);
+ } else {
+ data.put("cert_request_type", "cmc");
+ data.put("cert_request", mReq);
+ // test full response, but we don't really need it
+ // data.put("fullResponse", "true");
+ }
+
+ startProgressStatus();
+ boolean ready = requestCertCgi.requestCert(data);
+ endProgressStatus();
+
+ if (!ready) {
+ String str = requestCertCgi.getErrorMessage();
+ if (str.equals(""))
+ setErrorMessage("Server Error");
+ else
+ setErrorMessage(str);
+ return ready;
+ }
+ wizardInfo.setRequestSent(ready);
+
+ //save the stage
+ String reqID = wizardInfo.getRequestID();
+ String reqStatus = wizardInfo.getRequestStatus();
+ String reqError = wizardInfo.getRequestError();
+
+ wizardInfo.setX509RequestID(reqID);
+ wizardInfo.setX509RequestStatus(reqStatus);
+ if (reqError != null)
+ wizardInfo.setX509RequestError(reqError);
+
+ // rejected request should not be saved as requestSuccStage!!
+ if ( (reqID != null) && !reqID.equals("") &&
+ (wizardInfo.getRequestError() == null) &&
+ (reqStatus.equals(Constants.PR_REQUEST_SUCCESS)
+ || reqStatus.equals(Constants.PR_REQUEST_PENDING)
+ || reqStatus.equals(Constants.PR_REQUEST_SVC_PENDING)) ) {
+ data = new Hashtable();
+
+ ConsoleInfo consoleInfo = wizardInfo.getAdminConsoleInfo();
+ data.put(ConfigConstants.TASKID, TaskId.TASK_REQUEST_SUCCESS);
+ data.put(ConfigConstants.OPTYPE, OpDef.OP_MODIFY);
+ data.put(ConfigConstants.PR_SERVER_ROOT,
+ consoleInfo.get(ConfigConstants.PR_SERVER_ROOT));
+ data.put(ConfigConstants.PR_CERT_INSTANCE_NAME,
+ consoleInfo.get(ConfigConstants.PR_CERT_INSTANCE_NAME));
+ data.put(Constants.PR_CERTIFICATE_TYPE, mReqType);
+ data.put(mReqType+ConfigConstants.PR_REQUEST_ID, reqID);
+
+ data.put(ConfigConstants.CA_EEPORT, mPortText.getText());
+ data.put(ConfigConstants.CA_EETYPE, wizardInfo.getCMEEType());
+ data.put(ConfigConstants.CA_HOST, mHostText.getText());
+ startProgressStatus();
+ CMSConfigCert configCertCgi = new CMSConfigCert();
+ configCertCgi.initialize(wizardInfo);
+ ready = configCertCgi.configCert(data);
+ endProgressStatus();
+
+ if (!ready) {
+ String str = configCertCgi.getErrorMessage();
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ mPanelName+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ return ready;
+ }
+ }
+ return ready;
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ mDesc = createTextArea(mResource.getString(
+ mPanelName+"_TEXT_DESC_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mDesc, gbc);
+
+ mActiveColor = mDesc.getBackground();
+
+ mText = new JTextArea(null, null, 10, 10);
+ //mText.setLineWrap(true);
+ //mText.setWrapStyleWord(true);
+ mText.setEditable(false);
+ JScrollPane scrollPane = new JScrollPane(mText,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ scrollPane.setPreferredSize(new Dimension(50, 50));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.BOTH;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, 0, COMPONENT_SPACE);
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.5;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(scrollPane, gbc);
+
+ mCopy = makeJButton("COPY");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mCopy, gbc);
+
+ mFileName = createTextArea("");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mFileName, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weighty = 0.5;
+ gbc.fill = gbc.BOTH;
+ add(dummy, gbc);
+
+ mSendNowBox = makeJCheckBox("SENDNOW", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mSendNowBox, gbc);
+
+ mSendNowText = new JLabel(mResource.getString(
+ mPanelName + "_TEXT_SENDNOW_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mSendNowText, gbc);
+
+ mHostLbl = makeJLabel("HOST");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mHostLbl, gbc);
+
+ mHostText = makeJTextField(30);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mHostText, gbc);
+ mActiveColor = mHostText.getBackground();
+
+ mPortLbl = makeJLabel("PORT");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mPortLbl, gbc);
+
+ mPortText = makeJTextField(10);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mPortText, gbc);
+
+ mSSLText = new JLabel(mResource.getString(
+ mPanelName+"_TEXT_SSL_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mSSLText, gbc);
+
+ mSSL = makeJCheckBox("SSL", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mSSL, gbc);
+
+ JLabel label = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(label, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+
+ public void actionPerformed(ActionEvent event) {
+ if (event.getSource().equals(mCopy)) {
+ mText.copy();
+ }
+ if (mSendNowBox.isSelected()) {
+ enableFields(true, mActiveColor);
+ } else {
+ enableFields(false, getBackground());
+ }
+ }
+
+ protected void enableFields(boolean enabled, Color color) {
+ mSendNowText.setEnabled(enabled);
+ //mSendNowText.setEditable(enabled);
+ CMSAdminUtil.repaintComp(mSendNowText);
+ mHostLbl.setEnabled(enabled);
+ mPortLbl.setEnabled(enabled);
+ mHostText.setEnabled(enabled);
+ mHostText.setEditable(enabled);
+ mHostText.setBackground(color);
+ mPortText.setEnabled(enabled);
+ mPortText.setEditable(enabled);
+ mPortText.setBackground(color);
+ CMSAdminUtil.repaintComp(mHostLbl);
+ CMSAdminUtil.repaintComp(mHostText);
+ CMSAdminUtil.repaintComp(mPortLbl);
+ CMSAdminUtil.repaintComp(mPortText);
+ mSSLText.setEnabled(enabled);
+ //mSSLText.setEditable(enabled);
+ CMSAdminUtil.repaintComp(mSSLText);
+ mSSL.setEnabled(enabled);
+ //mSSL.setEditable(enabled);
+ //mSSL.setBackground(color);
+ CMSAdminUtil.repaintComp(mSSL);
+
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/WBaseValidityPage.java b/base/console/src/com/netscape/admin/certsrv/config/WBaseValidityPage.java
new file mode 100644
index 000000000..61d9506e6
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/WBaseValidityPage.java
@@ -0,0 +1,258 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config;
+
+import java.awt.*;
+import java.text.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * CA signing cert for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+public class WBaseValidityPage extends WizardBasePanel {
+ protected String mPanelName = "";
+ protected JTextField mBYear, mBMonth, mBDay, mBHour, mBMin, mBSec;
+ protected JTextField mEYear, mEMonth, mEDay, mEHour, mEMin, mESec;
+ protected final static String DATE_PATTERN = "dd/MM/yyyy:HH:mm:ss";
+ protected Date mBeforeDate, mAfterDate;
+ protected boolean mWarningDisplayed = false;
+
+ public WBaseValidityPage(String panelName) {
+ super(panelName);
+ mPanelName = panelName;
+ }
+
+ public boolean validatePanel() {
+ String beginYear = mBYear.getText().trim();
+ String afterYear = mEYear.getText().trim();
+ String beginMonth = mBMonth.getText().trim();
+ String afterMonth = mEMonth.getText().trim();
+ String beginDay = mBDay.getText().trim();
+ String afterDay = mEDay.getText().trim();
+ String beginHour = mBHour.getText().trim();
+ String afterHour = mEHour.getText().trim();
+ String beginMin = mBMin.getText().trim();
+ String afterMin = mEMin.getText().trim();
+ String beginSec = mBSec.getText().trim();
+ String afterSec = mESec.getText().trim();
+
+ int bYear = Integer.parseInt(beginYear);
+ int aYear = Integer.parseInt(afterYear);
+
+/*
+POSIX timestamps used in most UNIX systems are 32-bit signed integers,
+which gives you 2^31 seconds or about 68 years of useful time. The
+epoch is 1970-01-01 00:00:00, so the counter will overflow sometime in
+January 2038.
+*/
+ // if (bYear > 2032 || aYear > 2032) {
+ if (bYear > 2037 || aYear > 2037) {
+ String errorMsg = mResource.getString(mPanelName+
+ "_LABEL_MAXYEAR_LABEL");
+ JOptionPane.showMessageDialog(mParent, errorMsg, "Warning",
+ JOptionPane.WARNING_MESSAGE,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_WARN_ICON));
+ return false;
+ }
+
+ String beginDateStr = beginDay+"/"+beginMonth+"/"+beginYear+":"
+ +beginHour+":"+beginMin+":"+beginSec;
+ String endDateStr = afterDay+"/"+afterMonth+"/"+afterYear+":"
+ +afterHour+":"+afterMin+":"+afterSec;
+
+ SimpleDateFormat format = new SimpleDateFormat(DATE_PATTERN);
+ format.setLenient(false);
+ mBeforeDate = null;
+ mAfterDate = null;
+
+ try {
+ mBeforeDate = format.parse(beginDateStr);
+ } catch (ParseException e) {
+ setErrorMessage("INVALIDBEGINDATE");
+ return false;
+ }
+
+ try {
+ mAfterDate = format.parse(endDateStr);
+ } catch (ParseException e) {
+ setErrorMessage("INVALIDENDDATE");
+ return false;
+ }
+
+ if (mAfterDate.before(mBeforeDate)) {
+ setErrorMessage("SMALLAFTERDATE");
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea heading = createTextArea(mResource.getString(
+ mPanelName+"_LABEL_VALIDITY_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ add(heading, gbc);
+
+ JLabel blank = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(blank, gbc);
+
+ JLabel yearLbl = makeJLabel("YEAR");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(yearLbl, gbc);
+
+ JLabel monthLbl = makeJLabel("MONTH");
+ add(monthLbl, gbc);
+
+ JLabel dayLbl = makeJLabel("DAY");
+ add(dayLbl, gbc);
+
+ JLabel hourLbl = makeJLabel("HOUR");
+ add(hourLbl, gbc);
+
+ JLabel minLbl = makeJLabel("MIN");
+ add(minLbl, gbc);
+
+ JLabel secLbl = makeJLabel("SEC");
+ gbc.gridwidth = gbc.REMAINDER;
+ add(secLbl, gbc);
+
+ JLabel beginLbl = makeJLabel("BEGIN");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ add(beginLbl, gbc);
+
+ //DateFormat dateFormat = DataFormat.getDateTimeInstance(
+ // DateFormat.FULL,DateFormat.MEDIUM);
+
+ Calendar nowDate = Calendar.getInstance();
+
+ Calendar afterDate = (Calendar)nowDate.clone();
+ afterDate.add(Calendar.YEAR, 5);
+
+ mBYear = new JTextField(""+nowDate.get(Calendar.YEAR));
+ mBYear.setColumns(4);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mBYear, gbc);
+
+ mBMonth = new JTextField(""+(nowDate.get(Calendar.MONTH)+1));
+ mBMonth.setColumns(3);
+ add(mBMonth, gbc);
+
+ mBDay = new JTextField(""+nowDate.get(Calendar.DAY_OF_MONTH));
+ mBDay.setColumns(3);
+ add(mBDay, gbc);
+
+ mBHour = new JTextField("00");
+ mBHour.setColumns(3);
+ add(mBHour, gbc);
+
+ mBMin = new JTextField("00");
+ mBMin.setColumns(3);
+ add(mBMin, gbc);
+
+ mBSec = new JTextField("00");
+ mBSec.setColumns(3);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mBSec, gbc);
+
+ JLabel expireLbl = makeJLabel("EXPIRE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ add(expireLbl, gbc);
+
+ mEYear = new JTextField(""+afterDate.get(Calendar.YEAR));
+ mEYear.setColumns(4);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mEYear, gbc);
+
+ mEMonth = new JTextField(""+(afterDate.get(Calendar.MONTH)+1));
+ mEMonth.setColumns(3);
+ add(mEMonth, gbc);
+
+ mEDay = new JTextField(""+afterDate.get(Calendar.DAY_OF_MONTH));
+ mEDay.setColumns(3);
+ add(mEDay, gbc);
+
+ mEHour = new JTextField("00");
+ mEHour.setColumns(3);
+ add(mEHour, gbc);
+
+ mEMin = new JTextField("00");
+ mEMin.setColumns(3);
+ add(mEMin, gbc);
+
+ mESec = new JTextField("00");
+ mESec.setColumns(3);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mESec, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.weighty = 1.0;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(dummy, gbc);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/WMNNewAgent.java b/base/console/src/com/netscape/admin/certsrv/config/WMNNewAgent.java
new file mode 100644
index 000000000..425eddaaa
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/WMNNewAgent.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.admin.certsrv.config;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.table.*;
+import javax.swing.text.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * New Agent names/passwords for reconfiguring the Recovery MN Scheme
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+class WMNNewAgent extends WizardBasePanel
+ implements IWizardPanel
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PANELNAME = "WMNNEWAGENT";
+
+ private int mNoAgent = 0;
+ private MNSchemeWizardInfo mInfo;
+ private NewAgentModel mDataModel;
+ private JTable mTable;
+ protected JScrollPane mScrollPane;
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-newagentpwd-keyscheme-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ WMNNewAgent() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public boolean initializePanel(WizardInfo info) {
+ //let's set the values
+ mInfo = (MNSchemeWizardInfo)info;
+ Debug.println(mInfo.toString());
+ try {
+ mNoAgent = Integer.parseInt(mInfo.getNewN());
+ } catch (Exception e) {
+ return false;
+ }
+
+ //add rows into tables
+ //zap passwords
+ mDataModel.removeAllRows();
+
+ Vector[] data = new Vector[mNoAgent];
+ for (int i=0; i<data.length; i++) {
+ data[i] = new Vector();
+ data[i].addElement(Integer.toString(i+1));
+ data[i].addElement("");
+ data[i].addElement("");
+ data[i].addElement("");
+ mDataModel.addRow(data[i]);
+ }
+ return true;
+ }
+
+ public boolean validatePanel() {
+
+ Component component = mTable.getEditorComponent();
+ if(component!= null) {
+ int col = mTable.getEditingColumn();
+ int row = mTable.getEditingRow();
+ if ((col>-1)&&(row>-1)) {
+ String str = ((JTextComponent)component).getText();
+ mTable.setValueAt(str, row, col);
+ }
+ }
+
+ if(!checkBlank()) {
+ setErrorMessage("CANNOTBEBLANK");
+ return false;
+ }
+
+ if(!checkConfirm()) {
+ setErrorMessage("PASSWORDERROR");
+ return false;
+ }
+
+ if (!checkDuplicate()) {
+ setErrorMessage("DUPLICATEERROR");
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ Debug.println("WMNNewAgent -- concludePanel() - START");
+ String val = getUIDPassword();
+ mInfo.add(Constants.PR_RECOVERY_AGENT,val);
+ try {
+ mInfo.changeScheme();
+ } catch (EAdminException e) {
+ mErrorString = e.toString();
+ return false;
+ }
+ return true;
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ //base class take care of these
+ //public String getTitle();
+ //public String getErrorMessage();
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(
+ new DefaultTableCellRenderer());
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellEditor(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(
+ new PasswordCellRenderer());
+ table.getColumnModel().getColumn(index).setCellEditor(
+ new DefaultCellEditor(new JPasswordField()));
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ //initialize the panel
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label3 = makeJLabel("DESC");
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ add(label3,gbc);
+
+ //table
+ mDataModel = new NewAgentModel();
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ //mScrollPane.setBorder(CMSAdminUtil.makeTitledBorder(mResource,PANEL_NAME,"USERS"));
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
+ //mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ setLabelCellRenderer(mTable, 1);
+ setLabelCellEditor(mTable, 2);
+ setLabelCellEditor(mTable, 3);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,COMPONENT_SPACE,COMPONENT_SPACE);
+ gb.setConstraints(mScrollPane, gbc);
+ add(mScrollPane);
+
+ super.init();
+ }
+
+ private boolean checkDuplicate() {
+ Hashtable table = new Hashtable();
+ for (int i=0; i<mDataModel.getRowCount(); i++) {
+ String val1 = (String)mDataModel.getValueAt(i,1);
+ table.put(val1.trim(), "1");
+ }
+ if (table.size() != mDataModel.getRowCount()) {
+ table = null;
+ return false;
+ }
+
+ table = null;
+ return true;
+ }
+
+ private boolean checkBlank() {
+ for (int i=0; i<mDataModel.getRowCount(); i++) {
+ String val1 = (String)mDataModel.getValueAt(i,1);
+ String val2 = (String)mDataModel.getValueAt(i,2);
+ String val3 = (String)mDataModel.getValueAt(i,3);
+ if ( (val1.trim().equals(""))||(val2.trim().equals(""))||
+ (val3.trim().equals(""))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean checkConfirm() {
+ for (int i=0; i<mDataModel.getRowCount(); i++) {
+ String val2 = (String)mDataModel.getValueAt(i,2);
+ String val3 = (String)mDataModel.getValueAt(i,3);
+ if (!val2.trim().equals(val3.trim())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private String getUIDPassword() {
+ String result = "";
+ for (int i=0; i<mDataModel.getRowCount(); i++) {
+ String val1 = (String)mDataModel.getValueAt(i,1);
+ String val2 = (String)mDataModel.getValueAt(i,2);
+ result = result+val1.trim()+"="+val2.trim();
+ if (i < (mDataModel.getRowCount()-1))
+ result = result+",";
+ }
+ return result;
+ }
+
+}
+
+class NewAgentModel extends CMSTableModel
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String COL1 = "NUMBER";
+ public static final String COL2 = "UID";
+ public static final String COL3 = "PASSWORD";
+ public static final String COL4 = "CONFIRM";
+
+
+ private static String[] mColumns = {COL1, COL2, COL3, COL4};
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public NewAgentModel() {
+ super();
+ init(mColumns);
+ }
+
+ public boolean isCellEditable(int row, int col) {
+ if(col >= 1)
+ return true;
+ return false;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/WMNOldAgent.java b/base/console/src/com/netscape/admin/certsrv/config/WMNOldAgent.java
new file mode 100644
index 000000000..07973f6c9
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/WMNOldAgent.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.admin.certsrv.config;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.table.*;
+import javax.swing.text.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Old Agent name/password for reconfiguring the Recovery MN Scheme
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+class WMNOldAgent extends WizardBasePanel
+ implements IWizardPanel
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PANELNAME = "WMNOLDAGENT";
+
+ private int mNoAgent = 0;
+ private MNSchemeWizardInfo mInfo;
+ private AutoRecoveryModel mDataModel;
+ private JTable mTable;
+ protected JScrollPane mScrollPane;
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-agentpwd-keyscheme-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ WMNOldAgent() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ public boolean initializePanel(WizardInfo info) {
+ //let's set the values
+ mInfo = (MNSchemeWizardInfo)info;
+ Debug.println(mInfo.toString());
+ try {
+ mNoAgent = Integer.parseInt(mInfo.getM());
+ } catch (Exception e) {
+ return false;
+ }
+
+ //add rows into tables
+ //zap passwords
+ mDataModel.removeAllRows();
+
+ Vector[] data = new Vector[mNoAgent];
+ for (int i=0; i<data.length; i++) {
+ data[i] = new Vector();
+ data[i].addElement(Integer.toString(i+1));
+ data[i].addElement("");
+ data[i].addElement("");
+ mDataModel.addRow(data[i]);
+ }
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+
+ Component component = mTable.getEditorComponent();
+ if(component!= null) {
+ int col = mTable.getEditingColumn();
+ int row = mTable.getEditingRow();
+ if ((col>-1)&&(row>-1)) {
+ String str = ((JTextComponent)component).getText();
+ mTable.setValueAt(str, row, col);
+ }
+ }
+
+ String val = getUIDPassword();
+ if(val.equals("")) {
+ setErrorMessage("CANNOTBEBLANK");
+ return false;
+ }
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ String val = getUIDPassword();
+ mInfo.add(Constants.PR_OLD_RECOVERY_AGENT,val);
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ //base class take care of these
+ //public String getTitle();
+ //public String getErrorMessage();
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(
+ new DefaultTableCellRenderer());
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellEditor(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(
+ new PasswordCellRenderer());
+ table.getColumnModel().getColumn(index).setCellEditor(
+ new DefaultCellEditor(new JPasswordField()));
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ //initialize the panel
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label3 = makeJLabel("DESC");
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ add(label3,gbc);
+
+ //table
+ mDataModel = new AutoRecoveryModel();
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ //mScrollPane.setBorder(CMSAdminUtil.makeTitledBorder(mResource,PANEL_NAME,"USERS"));
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
+ //mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ setLabelCellRenderer(mTable, 1);
+ setLabelCellEditor(mTable, 2);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,COMPONENT_SPACE,COMPONENT_SPACE);
+ gb.setConstraints(mScrollPane, gbc);
+ add(mScrollPane);
+
+ super.init();
+ }
+
+ private String getUIDPassword() {
+ String result = "";
+ for (int i=0; i<mDataModel.getRowCount(); i++) {
+ for (int j=1; j<mDataModel.getColumnCount(); j++) {
+ String val = (String)mDataModel.getValueAt(i, j);
+ if (val.equals(""))
+ return "";
+ else if (j == (mDataModel.getColumnCount()-1))
+ result = result+val;
+ else
+ result = result+val+"=";
+ }
+ if (i < (mDataModel.getRowCount()-1))
+ result = result+",";
+ }
+ return result;
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/WMNResultPage.java b/base/console/src/com/netscape/admin/certsrv/config/WMNResultPage.java
new file mode 100644
index 000000000..55b1d1ccf
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/WMNResultPage.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.admin.certsrv.config;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.table.*;
+import javax.swing.text.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Result page for the Recovery MN Scheme
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+class WMNResultPage extends WizardBasePanel
+ implements IWizardPanel
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PANELNAME = "WMNRESULTPAGE";
+
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-newagentpwd-keyscheme-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ WMNResultPage() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return true;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public boolean initializePanel(WizardInfo info) {
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ //initialize the panel
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label3 = makeJLabel("DESC");
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ add(label3,gbc);
+
+ super.init();
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/WMNSelection.java b/base/console/src/com/netscape/admin/certsrv/config/WMNSelection.java
new file mode 100644
index 000000000..db7753b1d
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/WMNSelection.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.admin.certsrv.config;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * MNSelection page for reconfiguring the Recovery MN Scheme
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+class WMNSelection extends WizardBasePanel
+ implements IWizardPanel
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PANELNAME = "WMNSELECTION";
+
+ private JTextField mMField, mNField;
+ private JLabel mMLabel, mNLabel;
+ private int mRequired, mAvail;
+
+ private MNSchemeWizardInfo mInfo;
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ WMNSelection() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ public boolean initializePanel(WizardInfo info) {
+ //let's set the values
+ mInfo = (MNSchemeWizardInfo)info;
+ mMField.setText(mInfo.getNewM());
+ mNField.setText(mInfo.getNewN());
+ mMLabel.setText(mInfo.getM());
+ mNLabel.setText(mInfo.getN());
+ return true;
+ }
+
+ public boolean validatePanel() {
+ if ((mMField.getText().trim().equals("")) ||
+ (mNField.getText().trim().equals("")) ) {
+ setErrorMessage("CANNOTBEBLANK");
+ return false;
+ }
+
+ String str = mMField.getText().trim();
+ if (str.equals("")) {
+ setErrorMessage("CANNOTBEBLANK");
+ return false;
+ }
+
+ try {
+ mRequired = Integer.parseInt(str);
+ str = mNField.getText().trim();
+ if (str.equals("")) {
+ setErrorMessage("CANNOTBEBLANK");
+ return false;
+ }
+ mAvail = Integer.parseInt(str);
+ } catch (NumberFormatException e) {
+ setErrorMessage("NOTINTEGER");
+ return false;
+ }
+
+ if (mRequired <= 0 || mAvail <= 0) {
+ setErrorMessage("NONZERO");
+ return false;
+ }
+
+ if (mRequired > mAvail) {
+ setErrorMessage("LARGER");
+ return false;
+ }
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ mInfo.add(Constants.PR_RECOVERY_M, mMField.getText().trim());
+ mInfo.add(Constants.PR_RECOVERY_N, mNField.getText().trim());
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ //base class take care of these
+ //public String getTitle();
+ //public String getErrorMessage();
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ //initialize the panel
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ //show icon
+ JLabel iconLabel = new JLabel(CMSAdminUtil.getImage(CMSAdminResources.IMAGE_CERTICON_LARGE));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gb.setConstraints(iconLabel,gbc);
+ add(iconLabel);
+
+ //show wizard description
+ JTextArea desc = new JTextArea(
+ CMSAdminUtil.wrapText(
+ mResource.getString("WMNSELECTION_TEXT_DESC_LABEL"),60),2,60);
+ desc.setBackground(getBackground());
+ desc.setEditable(false);
+ desc.setCaretColor(getBackground());
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.1;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ //current setting
+ JPanel oldPanel = new JPanel();
+ oldPanel.setBorder(makeTitledBorder("OLDSCHEME"));
+ GridBagLayout gb1 = new GridBagLayout();
+ oldPanel.setLayout(gb1);
+
+ //m
+ JLabel label1 = makeJLabel("M");
+ mMLabel = new JLabel("");
+ CMSAdminUtil.resetGBC(gbc);
+ CMSAdminUtil.addEntryField(oldPanel, label1, mMLabel, gbc);
+
+ //n
+ JLabel label3 = makeJLabel("N");
+ mNLabel = new JLabel("");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.gridheight = gbc.REMAINDER;
+ CMSAdminUtil.addEntryField(oldPanel, label3, mNLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gb.setConstraints(oldPanel,gbc);
+ add(oldPanel);
+
+ //new setting
+ JPanel newPanel = new JPanel();
+ newPanel.setBorder(makeTitledBorder("NEWSCHEME"));
+ GridBagLayout gb2 = new GridBagLayout();
+ newPanel.setLayout(gb2);
+
+ //m
+ JLabel label5 = makeJLabel("M");
+ mMField = new JTextField("");
+ CMSAdminUtil.resetGBC(gbc);
+ CMSAdminUtil.addEntryField(newPanel, label5, mMField, gbc);
+
+ //n
+ JLabel label6 = makeJLabel("N");
+ mNField = new JTextField("");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.gridheight = gbc.REMAINDER;
+ CMSAdminUtil.addEntryField(newPanel, label6, mNField, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.9;
+ gb.setConstraints(newPanel,gbc);
+ add(newPanel);
+
+ super.init();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/WMessageDigestPage.java b/base/console/src/com/netscape/admin/certsrv/config/WMessageDigestPage.java
new file mode 100644
index 000000000..ce0ced102
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/WMessageDigestPage.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.admin.certsrv.config;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Setup the message digest information for the installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+public class WMessageDigestPage extends WizardBasePanel implements IWizardPanel {
+ protected JComboBox mRSAHashTypeBox, mDSAHashTypeBox, mECCHashTypeBox;
+ protected JComboBox mRSASignedByTypeBox, mDSASignedByTypeBox, mECCSignedByTypeBox;
+ protected String mHelpIndex;
+ protected String mCAKeyType;
+ protected JTextArea mSignedByTypeLbl;
+ private static final String HELPINDEX = "install-cert-mda-wizard-help";
+
+ public WMessageDigestPage(String panelName) {
+ super(panelName);
+ mPanelName = panelName;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ setBorder(makeTitledBorder(mPanelName));
+
+ if (mCAKeyType.equals("RSA")) {
+ mECCHashTypeBox.setVisible(false);
+ mDSAHashTypeBox.setVisible(false);
+ mRSAHashTypeBox.setVisible(true);
+ String sha1 = mResource.getString(mPanelName+"_COMBOBOX_RSAHASHTYPE_VALUE_2");
+ mRSAHashTypeBox.setSelectedItem(sha1);
+ } else if (mCAKeyType.equals("ECC")) {
+ mECCHashTypeBox.setVisible(true);
+ mDSAHashTypeBox.setVisible(false);
+ mRSAHashTypeBox.setVisible(false);
+ } else {
+ mECCHashTypeBox.setVisible(false);
+ mDSAHashTypeBox.setVisible(true);
+ mRSAHashTypeBox.setVisible(false);
+ }
+
+ mHelpIndex = HELPINDEX;
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public void enableSignedByFields(boolean enable) {
+ if (!enable) {
+ mRSASignedByTypeBox.setVisible(false);
+ mDSASignedByTypeBox.setVisible(false);
+ mECCSignedByTypeBox.setVisible(false);
+ mSignedByTypeLbl.setVisible(false);
+ return;
+ }
+
+ if (mCAKeyType.equals("RSA")) {
+ mRSASignedByTypeBox.setVisible(true);
+ mDSASignedByTypeBox.setVisible(false);
+ mECCSignedByTypeBox.setVisible(false);
+ } else if (mCAKeyType.equals("ECC")) {
+ mRSASignedByTypeBox.setVisible(false);
+ mDSASignedByTypeBox.setVisible(false);
+ mECCSignedByTypeBox.setVisible(true);
+ } else {
+ mECCSignedByTypeBox.setVisible(false);
+ mDSASignedByTypeBox.setVisible(true);
+ mRSASignedByTypeBox.setVisible(false);
+ }
+
+ mSignedByTypeLbl.setVisible(true);
+ }
+
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(mHelpIndex);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea hashTypeLbl = createTextArea(mResource.getString(
+ mPanelName+"_TEXT_HASHTYPE_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(hashTypeLbl, gbc);
+
+ mRSAHashTypeBox = makeJComboBox("RSAHASHTYPE");
+ mRSAHashTypeBox.setVisible(true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mRSAHashTypeBox, gbc);
+
+ mDSAHashTypeBox = makeJComboBox("DSAHASHTYPE");
+ mDSAHashTypeBox.setVisible(false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mDSAHashTypeBox, gbc);
+
+ mECCHashTypeBox = makeJComboBox("ECCHASHTYPE");
+ mECCHashTypeBox.setVisible(false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mECCHashTypeBox, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, 0,COMPONENT_SPACE, COMPONENT_SPACE);
+ add(dummy, gbc);
+
+ JLabel dummy2 = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, 0,COMPONENT_SPACE, COMPONENT_SPACE);
+ add(dummy2, gbc);
+
+ mSignedByTypeLbl = createTextArea(mResource.getString(
+ mPanelName+"_TEXT_SIGNEDBYTYPE_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mSignedByTypeLbl, gbc);
+
+ mRSASignedByTypeBox = makeJComboBox("RSASIGNEDBYTYPE");
+ mRSASignedByTypeBox.setVisible(true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mRSASignedByTypeBox, gbc);
+
+ mDSASignedByTypeBox = makeJComboBox("DSASIGNEDBYTYPE");
+ mDSASignedByTypeBox.setVisible(false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mDSASignedByTypeBox, gbc);
+
+ mECCSignedByTypeBox = makeJComboBox("ECCSIGNEDBYTYPE");
+ mECCSignedByTypeBox.setVisible(false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mECCSignedByTypeBox, gbc);
+
+ JLabel dummy1 = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.CENTER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(0, 0,COMPONENT_SPACE, COMPONENT_SPACE);
+ add(dummy1, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/WarningDialog.java b/base/console/src/com/netscape/admin/certsrv/config/WarningDialog.java
new file mode 100644
index 000000000..bedf0b67f
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/WarningDialog.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.admin.certsrv.config;
+
+import com.netscape.admin.certsrv.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import javax.swing.table.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Certificate Information dialog
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.managecert
+ */
+public class WarningDialog extends JDialog
+ implements ActionListener {
+ private String PREFIX = "WARNINGDIALOG";
+
+ private JFrame mParent;
+ private ResourceBundle mResource;
+ private JTextArea mTextArea;
+ private JLabel mCertNameField;
+ private JButton mClose, mHelp, mTrust;
+ private AdminConnection mConn;
+ private String mCertName;
+ private String mCertDate;
+ private String mKey;
+
+ public WarningDialog(JFrame parent, String key) {
+ super(parent,true);
+ mParent = parent;
+ mKey = key;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ setSize(500, 300);
+ setResizable(false);
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ setDisplay();
+ }
+
+ public void actionPerformed(ActionEvent evt) {
+ if (evt.getSource().equals(mClose)) {
+ this.hide();
+ this.dispose();
+ }
+ }
+
+ private void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill=gbc.BOTH;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+
+ this.show();
+ }
+
+ private JPanel makeActionPane() {
+ mClose = CMSAdminUtil.makeJButton(mResource, PREFIX, "CLOSE",
+ null, this);
+
+ Dimension d = mClose.getMinimumSize();
+ if (d.width < CMSAdminUtil.DEFAULT_BUTTON_SIZE) {
+ d.width = CMSAdminUtil.DEFAULT_BUTTON_SIZE;
+ mClose.setMinimumSize(d);
+ }
+ JButton[] buttons = {mClose};
+ return CMSAdminUtil.makeJButtonPanel( buttons );
+ }
+
+ private JPanel makeContentPane() {
+ JPanel content = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ content.setLayout(gb3);
+/*
+ content.setBorder(CMSAdminUtil.makeTitledBorder(mResource,
+ "CERTINFODIALOG", "CERT"));
+*/
+
+ CMSAdminUtil.resetGBC(gbc);
+ Icon icon = CMSAdminUtil.getImage(CMSAdminResources.IMAGE_WARN_ICON);
+ JLabel label = new JLabel(icon);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,CMSAdminUtil.COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ content.add(label, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea desc = new JTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(PREFIX+mKey),65),10,65);
+ desc.setBackground(getBackground());
+ desc.setEditable(false);
+ desc.setCaretColor(getBackground());
+ JScrollPane scrollPane = new JScrollPane(desc,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill= gbc.BOTH;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ content.add(scrollPane, gbc);
+
+ return content;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/ComponentCellRenderer.java b/base/console/src/com/netscape/admin/certsrv/config/install/ComponentCellRenderer.java
new file mode 100644
index 000000000..f6dcff392
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/ComponentCellRenderer.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import javax.swing.table.*;
+
+class ComponentCellRenderer implements TableCellRenderer {
+ public Component getTableCellRendererComponent(JTable table,
+ Object value, boolean isSelected, boolean hasFocus, int row,
+ int column) {
+ return (JComponent)value;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/InstallWizard.java b/base/console/src/com/netscape/admin/certsrv/config/install/InstallWizard.java
new file mode 100644
index 000000000..557dc2739
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/InstallWizard.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.admin.certsrv.config.install;
+
+import java.util.*;
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.wizard.*;
+
+/**
+ * Wizard for Installation wizard
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+
+public class InstallWizard extends WizardWidget implements Runnable {
+
+ public InstallWizard(JFrame parent, InstallWizardInfo info,
+ IWizardDone wizDone) {
+ super(parent, wizDone);
+ setWizardInfo(info);
+ //addPage(new WIInstallCACertStatusPage());
+ addPage(new WIIntroPage(this, parent));
+ addPage(new WIMasterOrClone(this, parent));
+ addPage(new WIClonePage(this, parent));
+ addPage(new WILogonAllTokensPage(this, parent));
+ addPage(new WIInternalTokenLogonPage(this, parent));
+ addPage(new WIRecreateDBPage(this, parent));
+ addPage(new WIInternalDBPage(this, parent));
+ addPage(new WIExistingDBPage(this, parent));
+ addPage(new WICreateInternalDBPage(this, parent));
+ addPage(new WIInternalDBInfoPage(this, parent));
+ addPage(new WIReplAgreementPage(this, parent));
+ addPage(new WIAdminPage(this, parent));
+ addPage(new WIServicesPage(this, parent));
+ addPage(new WIInternalDBInfoPage(this, parent));
+/*
+ addPage(new WIRemoteCASubsystem(this, parent));
+ addPage(new WIRemoteKRASubsystem(this, parent));
+*/
+
+ // CA starting serial number
+ addPage(new WICASerialNumberPage(this,parent));
+ addPage(new WICAOCSPServicePage(this,parent));
+/*
+ addPage(new WINetworkPage(this, parent));
+*/
+
+ // CA signing certificate
+ addPage(new WIInternalDBInfoPage(this, parent));
+ addPage(new WICloneCAKeyCertPage(this, parent));
+
+ addPage(new WICACertSubmitPage(this, parent));
+ addPage(new WICAKeyPage(this, parent));
+ addPage(new WICAMessageDigestPage(this, parent));
+ addPage(new WICACertDNPage(this, parent));
+ addPage(new WICACertValidityPage(this, parent));
+ addPage(new WICACertExtensionPage(this, parent));
+ addPage(new WIGenCAKeyCertPage(this, parent));
+ addPage(new WIGenCAKeyCertReqPage(this, parent));
+ addPage(new WIManualCACertRequestPage(this, parent));
+ addPage(new WICARequestResultPage(this,parent));
+ addPage(new WIInstallCAIntroPage(this, parent));
+ addPage(new WICATokenLogonPage(this, parent));
+ addPage(new WIPasteCACertPage(this, parent));
+ addPage(new WIDisplayCACertPage(this, parent));
+ addPage(new WIInstallCACertStatusPage(this, parent));
+
+ // OCSP signing certificate
+ addPage(new WIInternalDBInfoPage(this, parent));
+ addPage(new WICloneOCSPKeyCertPage(this, parent));
+ addPage(new WIOCSPCertSubmitPage(this, parent));
+ addPage(new WIOCSPKeyPage(this, parent));
+ addPage(new WIOCSPMessageDigestPage(this, parent));
+ addPage(new WIOCSPCertDNPage(this, parent));
+ addPage(new WIGenOCSPKeyCertReqPage(this, parent));
+ addPage(new WIManualOCSPCertRequestPage(this, parent));
+ addPage(new WIOCSPRequestResultPage(this,parent));
+ addPage(new WIInstallOCSPIntroPage(this, parent));
+ addPage(new WIOCSPTokenLogonPage(this, parent));
+ addPage(new WIPasteOCSPCertPage(this, parent));
+ addPage(new WIDisplayOCSPCertPage(this, parent));
+ addPage(new WIInstallOCSPCertStatusPage(this, parent));
+
+ // RA signing certificate
+ addPage(new WIInternalDBInfoPage(this, parent));
+ addPage(new WICloneRAKeyCertPage(this, parent));
+ addPage(new WIRACertSubmitPage(this, parent));
+ addPage(new WIRAKeyPage(this, parent));
+ addPage(new WIRAMessageDigestPage(this, parent));
+ addPage(new WIRACertDNPage(this, parent));
+ addPage(new WIRACertValidityPage(this, parent));
+ addPage(new WIRACertExtensionPage(this, parent));
+ addPage(new WIGenRAKeyCertPage(this, parent));
+ addPage(new WIGenRAKeyCertReqPage(this, parent));
+ addPage(new WIManualRACertRequestPage(this, parent));
+ addPage(new WIRARequestResultPage(this,parent));
+ addPage(new WIInstallRAIntroPage(this, parent));
+ addPage(new WIRATokenLogonPage(this, parent));
+ addPage(new WIPasteRACertPage(this, parent));
+ addPage(new WIDisplayRACertPage(this, parent));
+ addPage(new WIInstallRACertStatusPage(this, parent));
+
+ // KRA transport certificate
+ addPage(new WIInternalDBInfoPage(this, parent));
+ addPage(new WIKRANumberPage(this, parent));
+ addPage(new WICloneKRAKeyCertPage(this, parent));
+ addPage(new WIKRACertSubmitPage(this, parent));
+ addPage(new WIKRAKeyPage(this, parent));
+ addPage(new WIKRAMessageDigestPage(this, parent));
+ addPage(new WIKRACertDNPage(this, parent));
+ addPage(new WIKRACertValidityPage(this, parent));
+ addPage(new WIKRACertExtensionPage(this, parent));
+ addPage(new WIGenKRAKeyCertPage(this, parent));
+ addPage(new WIGenKRAKeyCertReqPage(this, parent));
+ addPage(new WIManualKRACertRequestPage(this, parent));
+ addPage(new WIKRARequestResultPage(this,parent));
+ addPage(new WIInstallKRAIntroPage(this, parent));
+ addPage(new WIKRATokenLogonPage(this, parent));
+ addPage(new WIInternalTokenLogonPage(this, parent));
+ addPage(new WIPasteKRACertPage(this, parent));
+ addPage(new WIDisplayKRACertPage(this, parent));
+ addPage(new WIInstallKRACertStatusPage(this, parent));
+ addPage(new WIKRAStorageKeyPage(this, parent));
+
+ addPage(new WIKRAScheme1Page(this, parent));
+ addPage(new WIKRAScheme2Page(this, parent));
+
+ // SSL server certificate
+ addPage(new WIInternalDBInfoPage(this, parent));
+ addPage(new WICloneTKSKeyCertPage(this, parent));
+ addPage(new WIKRACertSubmitPage(this, parent));
+ addPage(new WIServerCertSubmitPage(this, parent));
+ addPage(new WIServerKeyPage(this, parent));
+ addPage(new WISSLMessageDigestPage(this, parent));
+ addPage(new WIServerCertDNPage(this, parent));
+ addPage(new WIServerCertValidityPage(this, parent));
+ addPage(new WIServerCertExtensionPage(this, parent));
+ addPage(new WIGenServerKeyCertPage(this, parent));
+ addPage(new WIGenSSLKeyCertReqPage(this, parent));
+ addPage(new WIManualSSLCertRequestPage(this, parent));
+ addPage(new WISSLRequestResultPage(this,parent));
+ addPage(new WIInstallSSLIntroPage(this, parent));
+ addPage(new WISSLTokenLogonPage(this, parent));
+ addPage(new WIPasteSSLCertPage(this, parent));
+ addPage(new WIDisplaySSLCertPage(this, parent));
+ addPage(new WIInstallSSLCertStatusPage(this, parent));
+
+ addPage(new WIAllCertsInstalledPage(this, parent));
+ addPage(new WISingleSignonPage(this, parent));
+ addPage(new WICertSetupStatusPage(this, parent));
+
+ show();
+ }
+
+ protected void callHelp() {
+ if (mCurrent instanceof IWizardPanel) {
+ ((IWizardPanel)mCurrent).callHelp();
+ }
+ }
+
+ protected void back_cb(WizardInfo info) {
+ if (mCurrent instanceof WIManualCertRequestPage) {
+ ((WIManualCertRequestPage)mCurrent).back_cb(info);
+ }
+ }
+
+ public void run() {
+ show();
+ }
+
+ public static void main(String[] args) {
+ JFrame.setDefaultLookAndFeelDecorated(true);
+ JFrame frame = new JFrame();
+ Cursor cursor = new Cursor(Cursor.HAND_CURSOR);
+ frame.setCursor(cursor);
+ frame.invalidate();
+ frame.validate();
+ frame.repaint(1);
+ InstallWizardInfo wizardInfo = new InstallWizardInfo();
+ InstallWizard wizard = new InstallWizard(frame, wizardInfo, null);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/InstallWizardInfo.java b/base/console/src/com/netscape/admin/certsrv/config/install/InstallWizardInfo.java
new file mode 100644
index 000000000..a88101cc4
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/InstallWizardInfo.java
@@ -0,0 +1,1724 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * WizardInfo for certificate setup wizard
+ * Once complete, we need to zap this object.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+public class InstallWizardInfo extends WizardInfo {
+ private static final int DB_PORT = 38900;
+ private static final String BINDDN = "cn=Directory Manager";
+ public static final String ALL_CERT_INFO = "allInfo";
+ private static final String CA_KEY_TYPE = "caKeyType";
+ private static final String CA_KEY_LEN = "caKeyLen";
+ private static final String OCSP_TOKEN_NAME = "ocspTokenName";
+ private static final String OCSP_TOKEN_PASSWD = "ocspTokenPwd";
+ private static final String CA_TOKEN_NAME = "caTokenName";
+ private static final String CA_TOKEN_PASSWD = "caTokenPwd";
+ private static final String RA_TOKEN_NAME = "raTokenName";
+ private static final String RA_TOKEN_PASSWD = "raTokenPwd";
+ private static final String KRA_TOKEN_NAME = "kraTokenName";
+ private static final String KRA_TOKEN_PASSWD = "kraTokenPwd";
+ private static final String SSL_TOKEN_NAME = "sslTokenName";
+ private static final String SSL_TOKEN_PASSWD = "sslTokenPwd";
+ private static final String MIGRATE_CA_TOKEN_NAME = "migrateCATokenName";
+ private static final String MIGRATE_SSL_TOKEN_NAME = "migrateSSLTokenName";
+ private static final String INSTALLCERT_NOW = "installCertNow";
+ private static final String CLONING = "cloning";
+ private static final String CACLONING = "cacloning";
+ private static final String RACLONING = "racloning";
+ private static final String KRACLONING = "kracloning";
+ private static final String SSLCLONING = "sslcloning";
+
+ private static final String CA_CLONING_CERT = "caSigningCert";
+ private static final String RA_CLONING_CERT = "raSigningCert";
+ private static final String KRA_CLONING_CERT = "kraTransportCert";
+ private static final String OCSP_CLONING_CERT = "ocspSigningCert";
+
+ private String mPassword = null;
+
+ private ConsoleInfo mConsoleInfo;
+
+ public InstallWizardInfo() {
+ super();
+ }
+
+ public InstallWizardInfo(ConsoleInfo consoleInfo) {
+ super();
+ mConsoleInfo = consoleInfo;
+ }
+
+ public JFrame getAdminFrame() {
+ return (JFrame)get("adminFrame");
+ }
+
+ public boolean doKeySplitting() {
+ String str = (String)get("kra.keySplitting");
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ else
+ return false;
+
+ }
+
+ public void setAdminFrame(JFrame frame) {
+ put("adminFrame", frame);
+ }
+
+ public ConsoleInfo getAdminConsoleInfo() {
+ return mConsoleInfo;
+ }
+
+ public String getStages() {
+ return (String)get(ConfigConstants.STAGES);
+ }
+
+ public String getCloneCertsList() {
+ String s = (String)get(ConfigConstants.PR_CLONE_CERTIFICATES);
+ if (s == null || s.equals(""))
+ return " ";
+ return s;
+ }
+
+ public String getCloneSubsystem() {
+
+ String s = (String)get("selected_sub");
+
+ if(s == null || s.equals(""))
+ return null;
+
+ return s;
+
+ }
+
+ public boolean isCACloningDone() {
+ String str = (String)get(ConfigConstants.STAGE_CACLONING);
+
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ else
+ return false;
+ }
+
+ public void setCACloningDone(String str) {
+ put(ConfigConstants.STAGE_CACLONING, str);
+ }
+
+ public boolean isOCSPCloningDone() {
+ String str = (String)get(ConfigConstants.STAGE_OCSPCLONING);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+
+ return false;
+ }
+
+ public void setOCSPCloningDone(String str) {
+ put(ConfigConstants.STAGE_OCSPCLONING, str);
+ }
+
+ public boolean isRACloningDone() {
+ String str = (String)get(ConfigConstants.STAGE_RACLONING);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+
+ return false;
+ }
+
+ public void setRACloningDone(String str) {
+ put(ConfigConstants.STAGE_RACLONING, str);
+ }
+
+ public boolean isKRACloningDone() {
+ String str = (String)get(ConfigConstants.STAGE_KRACLONING);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+
+ return false;
+ }
+
+ public boolean isTKSCloningDone() {
+ String str = (String)get(ConfigConstants.STAGE_TKSCLONING);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+
+ return false;
+ }
+
+ public void setUpdateDBInfoDone(String str) {
+ put(ConfigConstants.STAGE_UPDATE_DB_INFO, str);
+ }
+
+ public boolean isUpdateDBInfoDone() {
+ String str = (String)get(ConfigConstants.STAGE_UPDATE_DB_INFO);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public void setKRACloningDone(String str) {
+ put(ConfigConstants.STAGE_KRACLONING, str);
+ }
+
+ public boolean isSSLCloningDone() {
+ String str = (String)get(ConfigConstants.STAGE_SSLCLONING);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public void setSSLCloningDone(String str) {
+ put(ConfigConstants.STAGE_SSLCLONING, str);
+ }
+
+ public boolean isCloneCASubsystem() {
+ String str = (String)get(ConfigConstants.PR_CLONE_SUBSYSTEM);
+ if (str != null && str.equals(ConfigConstants.PR_CA))
+ return true;
+ return false;
+ }
+
+ public boolean isCloneRASubsystem() {
+ String str = (String)get(ConfigConstants.PR_CLONE_SUBSYSTEM);
+ if (str != null && str.equals(ConfigConstants.PR_RA))
+ return true;
+ return false;
+ }
+ public boolean isCloneKRASubsystem() {
+ String str = (String)get(ConfigConstants.PR_CLONE_SUBSYSTEM);
+ if (str != null && str.equals(ConfigConstants.PR_KRA))
+ return true;
+ return false;
+ }
+ public boolean isCloneOCSPSubsystem() {
+ String str = (String)get(ConfigConstants.PR_CLONE_SUBSYSTEM);
+ if (str != null && str.equals(ConfigConstants.PR_OCSP))
+ return true;
+ return false;
+ }
+ public boolean isCloneTKSSubsystem() {
+ String str = (String)get(ConfigConstants.PR_CLONE_SUBSYSTEM);
+ if (str != null && str.equals(ConfigConstants.PR_TKS))
+ return true;
+ return false;
+ }
+ public boolean isCloneMasterDone() {
+ String str = (String)get(ConfigConstants.STAGE_CLONEMASTER);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public void setCloneMasterDone(String str) {
+ put(ConfigConstants.STAGE_CLONEMASTER, str);
+ }
+
+ public boolean isNetworkDone() {
+ String str = (String)get(ConfigConstants.STAGE_SETUP_PORTS);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isAdministratorDone() {
+ String str = (String)get(ConfigConstants.STAGE_SETUP_ADMINISTRATOR);
+ if (str == null || str.equals("") || str.equals(ConfigConstants.FALSE))
+ return false;
+
+ return true;
+ }
+
+ public boolean isServicesDone() {
+ String str = (String)get(ConfigConstants.STAGE_SETUP_SUBSYSTEMS);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isMigrationDone() {
+ String str = (String)get(ConfigConstants.STAGE_DATA_MIGRATION);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isKRANMSchemeDone() {
+ String str = (String)get(ConfigConstants.STAGE_KRA_NM_SCHEME);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isCACertRequestBack() {
+ String str = (String)get(ConfigConstants.CA_CERT_REQUEST_BACK);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isRACertRequestBack() {
+ String str = (String)get(ConfigConstants.RA_CERT_REQUEST_BACK);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isOCSPCertRequestBack() {
+ String str = (String)get(ConfigConstants.OCSP_CERT_REQUEST_BACK);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isKRACertRequestBack() {
+ String str = (String)get(ConfigConstants.KRA_CERT_REQUEST_BACK);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isSSLCertRequestBack() {
+ String str = (String)get(ConfigConstants.SSL_CERT_REQUEST_BACK);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isSelfSignedCACertDone() {
+ String str = (String)get(ConfigConstants.STAGE_CA_SELFSIGNED_CERT);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isCACertRequestDone() {
+ String str = (String)get(ConfigConstants.STAGE_CA_CERT_REQUEST);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isCACertInstalledDone() {
+ String str = (String)get(ConfigConstants.STAGE_CA_CERT_INSTALL);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isCACertChainImportDone() {
+ String str = (String)get(ConfigConstants.STAGE_CA_CERTCHAIN_IMPORT);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+ public boolean isNumberPageDone(){
+ String str = (String)get(ConfigConstants.PR_SERIAL_REQUEST_NUMBER);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+ public void setNumberPageDone(String str) {
+ put(ConfigConstants.PR_SERIAL_REQUEST_NUMBER, str);
+ }
+ public boolean isClonePageDone(){
+ String str = (String)get(ConfigConstants.PR_CLONE_SETTING_DONE);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+ public void setClonePageDone(String str) {
+ put(ConfigConstants.PR_CLONE_SETTING_DONE, str);
+ }
+ public boolean isOCSPCertChainImportDone() {
+ String str = (String)get(ConfigConstants.STAGE_OCSP_CERTCHAIN_IMPORT);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isRALocalCertDone() {
+ String str = (String)get(ConfigConstants.STAGE_RA_LOCAL_CERT);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isRACertRequestDone() {
+ String str = (String)get(ConfigConstants.STAGE_RA_CERT_REQUEST);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isOCSPLocalCertDone() {
+ String str = (String)get(ConfigConstants.STAGE_OCSP_LOCAL_CERT);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isOCSPCertRequestDone() {
+ String str = (String)get(ConfigConstants.STAGE_OCSP_CERT_REQUEST);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isOCSPCertInstalledDone() {
+ String str = (String)get(ConfigConstants.STAGE_OCSP_CERT_INSTALL);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isRACertInstalledDone() {
+ String str = (String)get(ConfigConstants.STAGE_RA_CERT_INSTALL);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isRACertChainImportDone() {
+ String str = (String)get(ConfigConstants.STAGE_RA_CERTCHAIN_IMPORT);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isKRALocalCertDone() {
+ String str = (String)get(ConfigConstants.STAGE_KRA_LOCAL_CERT);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isKRACertRequestDone() {
+ String str = (String)get(ConfigConstants.STAGE_KRA_CERT_REQUEST);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isKRACertInstalledDone() {
+ String str = (String)get(ConfigConstants.STAGE_KRA_CERT_INSTALL);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isKRACertChainImportDone() {
+ String str = (String)get(ConfigConstants.STAGE_KRA_CERTCHAIN_IMPORT);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+ public boolean isSSLLocalCertDone() {
+ String str = (String)get(ConfigConstants.STAGE_SSL_LOCAL_CERT);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isSSLCertRequestDone() {
+ String str = (String)get(ConfigConstants.STAGE_SSL_CERT_REQUEST);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isSSLCertInstalledDone() {
+ String str = (String)get(ConfigConstants.STAGE_SSL_CERT_INSTALL);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isSSLCertChainImportDone() {
+ String str = (String)get(ConfigConstants.STAGE_SSL_CERTCHAIN_IMPORT);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+ public String getNextAvailPort() {
+ return (String)get(ConfigConstants.PR_NEXT_AVAIL_PORT);
+ }
+
+ public void setSubsystems(String str) {
+ put(ConfigConstants.PR_SUBSYSTEMS, str);
+ }
+
+ public String getSubsystems() {
+ return (String)get(ConfigConstants.PR_SUBSYSTEMS);
+ }
+
+ public void setReplicationEnabled(String str) {
+ put(ConfigConstants.PR_ENABLE_REPLICATION, str);
+ }
+
+ public boolean isReplicationEnabled() {
+ String str = (String)get(ConfigConstants.PR_ENABLE_REPLICATION);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public void setAgreementDone(String str) {
+ put(ConfigConstants.STAGE_REPLICATION_AGREEMENT, str);
+ }
+
+ public boolean isAgreementDone() {
+ String str = (String)get(ConfigConstants.STAGE_REPLICATION_AGREEMENT);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ else
+ return false;
+ }
+
+ public void setDBCreated(String str) {
+ put(ConfigConstants.PR_IS_DBCREATED, str);
+ }
+
+ public void setCloneDBCreated(String str) {
+ put(ConfigConstants.PR_IS_CLONEDDB_CREATED, str);
+ }
+
+ public boolean isDBCreated() {
+ String str = (String)get(ConfigConstants.PR_IS_DBCREATED);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isCloneDBCreated() {
+ String str = (String)get(ConfigConstants.PR_IS_CLONEDDB_CREATED);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public void setDBCreateNow(String str) {
+ put("dbCreateNow", str);
+ }
+
+ public boolean isDBCreateNow() {
+ String str = (String)get("dbCreateNow");
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public String getSingleSignOnPassword() {
+ return mPassword;
+ }
+
+ public void setSingleSignOnPassword(String password) {
+ mPassword = password;
+ }
+
+ public void setCertAdminUid(String uid) {
+ put(ConfigConstants.PR_CERT_ADMINUID, uid);
+ }
+
+ public String getCertAdminUid() {
+ return (String)get(ConfigConstants.PR_CERT_ADMINUID);
+ }
+
+ public void setCertAdminName(String name) {
+ put(ConfigConstants.PR_CERT_ADMINNAME, name);
+ }
+
+ public String getCertAdminName() {
+ return (String)get(ConfigConstants.PR_CERT_ADMINNAME);
+ }
+
+ public void setDBPort(String val) {
+ put(ConfigConstants.PR_DB_PORT, val);
+ }
+
+ public int getDBPort() {
+ String val = (String)get(ConfigConstants.PR_DB_PORT);
+ if (val != null)
+ return Integer.parseInt(val);
+ return 38900;
+ }
+
+ public void setDBName(String name) {
+ put(ConfigConstants.PR_DB_NAME, name);
+ }
+
+ public String getDBName() {
+ String dbName = (String)get(ConfigConstants.PR_DB_NAME);
+ if (dbName == null)
+ dbName = "";
+ return dbName;
+ }
+
+ public void setCloneDBName(String name) {
+ put(ConfigConstants.PR_CLONEDDB_NAME, name);
+ }
+
+ public String getCloneDBName() {
+ String dbName = (String)get(ConfigConstants.PR_CLONEDDB_NAME);
+ if (dbName == null)
+ dbName = "";
+ return dbName;
+ }
+
+ public void setDBBindDN(String val) {
+ put(ConfigConstants.PR_DB_BINDDN, val);
+ }
+
+ public String getDBBindDN() {
+ String dn = (String)get(ConfigConstants.PR_DB_BINDDN);
+ if (dn == null)
+ dn = BINDDN;
+ return dn;
+ }
+
+ public String getAdminPort() {
+ String val = (String)get(ConfigConstants.PR_RADM_PORT);
+ if (val == null)
+ val = "8200";
+ return val;
+ }
+
+ public void setAdminPort(String val) {
+ put(ConfigConstants.PR_RADM_PORT, val);
+ }
+
+ public String getEEPort() {
+ String val = (String)get(ConfigConstants.PR_EE_PORT);
+ if (val == null || val.equals(""))
+ val = "81";
+ return val;
+ }
+
+ public void setEEPort(String port) {
+ put(ConfigConstants.PR_EE_PORT, port);
+ }
+
+ public String getEESecurePort() {
+ String val = (String)get(ConfigConstants.PR_EE_SECURE_PORT);
+ if (val == null)
+ val = "8001";
+ return val;
+ }
+
+ public void setEESecurePort(String port) {
+ put(ConfigConstants.PR_EE_SECURE_PORT, port);
+ }
+
+ public String getAgentPort() {
+ String val = (String)get(ConfigConstants.PR_AGENT_PORT);
+ if (val == null)
+ val = "8100";
+ return val;
+ }
+
+ public void setAgentPort(String val) {
+ put(ConfigConstants.PR_AGENT_PORT, val);
+ }
+
+ public boolean isEEEnabled() {
+ String val = (String)get(ConfigConstants.PR_EE_PORT_ENABLE);
+ if (val != null && val.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ public void setEEEnable(String enable) {
+ put(ConfigConstants.PR_EE_PORT_ENABLE, enable);
+ }
+
+ public String getCertType() {
+ return (String)get(Constants.PR_CERTIFICATE_TYPE);
+ }
+
+ public void setCertType(String str) {
+ put(Constants.PR_CERTIFICATE_TYPE, str);
+ }
+
+ public String getReqFormat(String certType) {
+ return (String)get(certType+ConfigConstants.PR_REQUEST_FORMAT);
+ }
+
+ public void setReqFormat(String certType, String str) {
+ put(certType+ConfigConstants.PR_REQUEST_FORMAT , str);
+ }
+
+ public boolean isNewRequest() {
+ String val = (String)get(getCertType()+"new");
+ if (val != null && val.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ public void setNewRequest() {
+ put(getCertType()+"new", Constants.TRUE);
+ }
+
+ public boolean isCAReqResultDisplayed() {
+ String val = (String)get(ConfigConstants.CA_REQUEST_DISPLAYED);
+ if (val != null && val.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ public void setCAReqResultDisplayed(String val) {
+ put(ConfigConstants.CA_REQUEST_DISPLAYED, val);
+ }
+
+ public boolean isRAReqResultDisplayed() {
+ String val = (String)get(ConfigConstants.RA_REQUEST_DISPLAYED);
+ if (val != null && val.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ public void setRAReqResultDisplayed(String val) {
+ put(ConfigConstants.RA_REQUEST_DISPLAYED, val);
+ }
+
+ public boolean isOCSPReqResultDisplayed() {
+ String val = (String)get(ConfigConstants.OCSP_REQUEST_DISPLAYED);
+ if (val != null && val.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ public void setOCSPReqResultDisplayed(String val) {
+ put(ConfigConstants.OCSP_REQUEST_DISPLAYED, val);
+ }
+
+ public boolean isKRAReqResultDisplayed() {
+ String val = (String)get(ConfigConstants.KRA_REQUEST_DISPLAYED);
+ if (val != null && val.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ public void setKRAReqResultDisplayed(String val) {
+ put(ConfigConstants.KRA_REQUEST_DISPLAYED, val);
+ }
+
+ public boolean isSSLReqResultDisplayed() {
+ String val = (String)get(ConfigConstants.SSL_REQUEST_DISPLAYED);
+ if (val != null && val.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ public void setSSLReqResultDisplayed(String val) {
+ put(ConfigConstants.SSL_REQUEST_DISPLAYED, val);
+ }
+
+ public String getCertRequest() {
+ return (String)get(Constants.PR_CERT_REQUEST);
+ }
+
+ public void setCertRequest(String certReq) {
+ put(Constants.PR_CERT_REQUEST, certReq);
+ }
+
+ public String getCAKeyLength() {
+ return (String)get(CA_KEY_LEN);
+ }
+
+ public String getCATokenName() {
+ return (String)get(CA_TOKEN_NAME);
+ }
+
+ public void setCATokenName(String tokenname) {
+ put(CA_TOKEN_NAME, tokenname);
+ }
+
+ public String getOCSPTokenName() {
+ return (String)get(OCSP_TOKEN_NAME);
+ }
+
+ public void setOCSPTokenName(String tokenname) {
+ put(OCSP_TOKEN_NAME, tokenname);
+ }
+
+ public String getRATokenName() {
+ return (String)get(RA_TOKEN_NAME);
+ }
+
+ public void setRATokenName(String tokenname) {
+ put(RA_TOKEN_NAME, tokenname);
+ }
+
+ public String getKRATokenName() {
+ return (String)get(KRA_TOKEN_NAME);
+ }
+
+ public void setKRATokenName(String tokenname) {
+ put(KRA_TOKEN_NAME, tokenname);
+ }
+
+ public String getSSLTokenName() {
+ return (String)get(SSL_TOKEN_NAME);
+ }
+
+ public void setSSLTokenName(String tokenname) {
+ put(SSL_TOKEN_NAME, tokenname);
+ }
+
+ public String getMigrateCACertTokenName() {
+ return (String)get(MIGRATE_CA_TOKEN_NAME);
+ }
+
+ public void setMigrateCACertTokenName(String tokenname) {
+ put(MIGRATE_CA_TOKEN_NAME, tokenname);
+ }
+
+ public String getMigrateSSLCertTokenName() {
+ return (String)get(MIGRATE_SSL_TOKEN_NAME);
+ }
+
+ public void setMigrateSSLCertTokenName(String tokenname) {
+ put(MIGRATE_SSL_TOKEN_NAME, tokenname);
+ }
+
+ public String getTokenName() {
+ return (String)get(ConfigConstants.PR_TOKEN_NAME);
+ }
+
+ public String getTokensList() {
+ return (String)get(ConfigConstants.PR_TOKEN_NAMES);
+ }
+
+ public String getTokensInit() {
+ return (String)get(ConfigConstants.PR_TOKEN_INITIALIZED);
+ }
+
+ public String getTokensLogin() {
+ return (String)get(ConfigConstants.PR_TOKEN_LOGGED_IN);
+ }
+
+ public void setKeyLength(String val) {
+ put(ConfigConstants.PR_KEY_LEN, val);
+ }
+
+ public String getKeyLength() {
+ String val = (String)get(ConfigConstants.PR_KEY_LEN);
+ if (val == null)
+ val = "512";
+ return val;
+ }
+
+ public String getKeyCurveName() {
+ String val = (String)get(ConfigConstants.PR_KEY_CURVENAME);
+ if (val ==null)
+ val = "nistp521";
+ return val;
+ }
+
+ public void setKeyCurveName(String val) {
+ put(ConfigConstants.PR_KEY_CURVENAME, val);
+ }
+
+ public String getKeyType() {
+ String type = (String)get(ConfigConstants.PR_KEY_TYPE);
+ // work around the historical mistake,
+ // not touching files around the places.
+ if ( type == null || type.equals("")) {
+ String certType = getCertType();
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ type = (String)get("ca_keyType");
+ } else if (certType.equals(Constants.PR_RA_SIGNING_CERT)) {
+ type = (String)get("ra_keyType");
+ } else if (certType.equals(Constants.PR_OCSP_SIGNING_CERT)) {
+ type = (String)get("ocsp_keyType");
+ } else if (certType.equals(Constants.PR_KRA_TRANSPORT_CERT)) {
+ type = (String)get("kra_keyType");
+ } else if (certType.equals(Constants.PR_SERVER_CERT)) {
+ type = (String)get("ssl_keyType");
+ }
+ }
+ return type;
+ }
+
+ public String getSubjectName() {
+ return (String)get(ConfigConstants.PR_SUBJECT_NAME);
+ }
+
+ public void setSubjectName(String str) {
+ put(ConfigConstants.PR_SUBJECT_NAME, str);
+ }
+
+ public String getCASubjectName() {
+ return (String)get(ConfigConstants.PR_CA_SUBJECT_NAME);
+ }
+
+ public void setCASubjectName(String str) {
+ put(ConfigConstants.PR_CA_SUBJECT_NAME, str);
+ }
+
+ public String getRASubjectName() {
+ return (String)get(ConfigConstants.PR_RA_SUBJECT_NAME);
+ }
+
+ public void setRASubjectName(String str) {
+ put(ConfigConstants.PR_RA_SUBJECT_NAME, str);
+ }
+
+ public String getOCSPSubjectName() {
+ return (String)get(ConfigConstants.PR_OCSP_SUBJECT_NAME);
+ }
+
+ public void setOCSPSubjectName(String str) {
+ put(ConfigConstants.PR_OCSP_SUBJECT_NAME, str);
+ }
+
+ public String getKRASubjectName() {
+ return (String)get(ConfigConstants.PR_KRA_SUBJECT_NAME);
+ }
+
+ public void setKRASubjectName(String str) {
+ put(ConfigConstants.PR_KRA_SUBJECT_NAME, str);
+ }
+
+ public String getSSLSubjectName() {
+ return (String)get(ConfigConstants.PR_SSL_SUBJECT_NAME);
+ }
+
+ public void setSSLSubjectName(String str) {
+ put(ConfigConstants.PR_SSL_SUBJECT_NAME, str);
+ }
+
+ public NameValuePairs getAllCertInfo() {
+ return (NameValuePairs)get(ALL_CERT_INFO);
+ }
+
+ public String getBeginYear() {
+ return (String)get(Constants.PR_BEGIN_YEAR);
+ }
+
+ public String getBeginMonth() {
+ return (String)get(Constants.PR_BEGIN_MONTH);
+ }
+
+ public String getBeginDate() {
+ return (String)get(Constants.PR_BEGIN_DATE);
+ }
+
+ public String getBeginHour() {
+ return (String)get(Constants.PR_BEGIN_HOUR);
+ }
+
+ public String getBeginMin() {
+ return (String)get(Constants.PR_BEGIN_MIN);
+ }
+
+ public String getBeginSec() {
+ return (String)get(Constants.PR_BEGIN_SEC);
+ }
+
+ public String getAfterYear() {
+ return (String)get(Constants.PR_AFTER_YEAR);
+ }
+
+ public String getAfterMonth() {
+ return (String)get(Constants.PR_AFTER_MONTH);
+ }
+
+ public String getAfterDate() {
+ return (String)get(Constants.PR_AFTER_DATE);
+ }
+
+ public String getAfterHour() {
+ return (String)get(Constants.PR_AFTER_HOUR);
+ }
+
+ public String getAfterMin() {
+ return (String)get(Constants.PR_AFTER_MIN);
+ }
+
+ public String getAfterSec() {
+ return (String)get(Constants.PR_AFTER_SEC);
+ }
+
+ public boolean isSingleSignon() {
+ String val = (String)get(ConfigConstants.PR_SINGLE_SIGNON);
+ if (val != null && val.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isCACertLocalCA() {
+ String val = (String)get(ConfigConstants.PR_CACERT_LOCALCA);
+ if (val == null) {
+ return true;
+ }
+ else if (val.equals(Constants.TRUE)) {
+ return true;
+ }
+ return false;
+ }
+
+ // set true or false
+ public void setCACertLocalCA(String val) {
+ put(ConfigConstants.PR_CACERT_LOCALCA, val);
+ }
+
+ public boolean isRACertLocalCA() {
+ String val = (String)get(ConfigConstants.PR_RACERT_LOCALCA);
+ if (val == null)
+ return true;
+ else if (val.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ // set true or false
+ public void setRACertLocalCA(String val) {
+ put(ConfigConstants.PR_RACERT_LOCALCA, val);
+ }
+
+ public boolean isOCSPCertLocalCA() {
+ String val = (String)get(ConfigConstants.PR_OCSPCERT_LOCALCA);
+ if (val == null)
+ return true;
+ else if (val.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ // set true or false
+ public void setOCSPCertLocalCA(String val) {
+ put(ConfigConstants.PR_OCSPCERT_LOCALCA, val);
+ }
+
+ public boolean isKRACertLocalCA() {
+ String val = (String)get(ConfigConstants.PR_KRACERT_LOCALCA);
+ if (val == null)
+ return true;
+ else if (val.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ // set true or false
+ public void setKRACertLocalCA(String val) {
+ put(ConfigConstants.PR_KRACERT_LOCALCA, val);
+ }
+
+ public boolean isSSLCertLocalCA() {
+ String val = (String)get(ConfigConstants.PR_SSLCERT_LOCALCA);
+ if (val == null || val.equals(""))
+ return true;
+ else if (val.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ // set true or false
+ public void setSSLCertLocalCA(String val) {
+ put(ConfigConstants.PR_SSLCERT_LOCALCA, val);
+ }
+
+ public void setInstallCertNow(String val) {
+ put(INSTALLCERT_NOW, val);
+ }
+
+ public boolean isInstallCertNow() {
+ String val = (String)get(INSTALLCERT_NOW);
+ if (val == null)
+ return false;
+ else if (val.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ public String getCertContent() {
+ return (String)get(Constants.PR_CERT_CONTENT);
+ }
+
+ public String getNickname() {
+ return (String)get(Constants.PR_NICKNAME);
+ }
+
+ public String getCertOrder() {
+ return (String)get(ConfigConstants.PR_CERT_CONTENT_ORDER);
+ }
+
+ public String getPKCS10() {
+ String val = (String)get(Constants.PR_PKCS10);
+ if (val != null && !val.equals(""))
+ return val;
+ return null;
+ }
+
+ public void setPKCS10(String b64E) {
+ put(Constants.PR_PKCS10, b64E);
+ }
+
+ public String getCertFilePath() {
+ String val = (String)get(Constants.PR_CERT_FILEPATH);
+ if (val != null && !val.equals(""))
+ return val;
+ return null;
+ }
+
+ public void setCertFilePath(String path) {
+ put(Constants.PR_CERT_FILEPATH, path);
+ }
+
+ public String getMachineName() {
+ return (String)get(ConfigConstants.PR_MACHINE_NAME);
+ }
+
+ public void setEnableMigration(String val) {
+ put(ConfigConstants.PR_ENABLE_MIGRATION, val);
+ }
+
+ public boolean isMigrationEnable() {
+ String val = (String)get(ConfigConstants.PR_ENABLE_MIGRATION);
+ if (val != null && val.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public void setMigrationOutputPath(String path) {
+ put(ConfigConstants.PR_OUTPUT_PATH, path);
+ }
+
+ public String getMigrationOutputPath() {
+ return (String)get(ConfigConstants.PR_OUTPUT_PATH);
+ }
+
+ public void setInternalDBPasswd(String passwd) {
+ put(ConfigConstants.PR_DB_PWD, passwd);
+ }
+
+ public String getInternalDBPasswd() {
+ return (String)get(ConfigConstants.PR_DB_PWD);
+ }
+
+ public void setMigrationPasswd(String val) {
+ put(ConfigConstants.PR_MIGRATION_PASSWORD, val);
+ }
+
+ public String getMigrationPasswd() {
+ return (String)get(ConfigConstants.PR_MIGRATION_PASSWORD);
+ }
+
+ public void setSigningKeyMigrationToken(String tokenname) {
+ put(ConfigConstants.PR_SIGNING_KEY_MIGRATION_TOKEN, tokenname);
+ }
+
+ public String getSigningKeyMigrationToken() {
+ return (String)get(ConfigConstants.PR_SIGNING_KEY_MIGRATION_TOKEN);
+ }
+
+ public void setSSLKeyMigrationToken(String tokenname) {
+ put(ConfigConstants.PR_SSL_KEY_MIGRATION_TOKEN, tokenname);
+ }
+
+ public String getSSLKeyMigrationToken() {
+ return (String)get(ConfigConstants.PR_SSL_KEY_MIGRATION_TOKEN);
+ }
+
+ public void setSigningKeyMigrationPasswd(String val) {
+ put(ConfigConstants.PR_SIGNING_KEY_MIGRATION_TOKEN_PASSWD, val);
+ }
+
+ public String getSigningKeyMigrationPasswd() {
+ return (String)get(ConfigConstants.PR_SIGNING_KEY_MIGRATION_TOKEN_PASSWD);
+ }
+
+ public void setSigningKeyMigrationSOPPasswd(String val) {
+ put(ConfigConstants.PR_SIGNING_KEY_MIGRATION_TOKEN_SOPPASSWD, val);
+ }
+
+ public String getSigningKeyMigrationSOPPasswd() {
+ return (String)get(ConfigConstants.PR_SIGNING_KEY_MIGRATION_TOKEN_SOPPASSWD);
+ }
+
+ public void setSSLKeyMigrationPasswd(String val) {
+ put(ConfigConstants.PR_SSL_KEY_MIGRATION_TOKEN_PASSWD, val);
+ }
+
+ public String getSSLKeyMigrationPasswd() {
+ return (String)get(ConfigConstants.PR_SSL_KEY_MIGRATION_TOKEN_PASSWD);
+ }
+
+ public void setSSLKeyMigrationSOPPasswd(String val) {
+ put(ConfigConstants.PR_SSL_KEY_MIGRATION_TOKEN_SOPPASSWD, val);
+ }
+
+ public String getSSLKeyMigrationSOPPasswd() {
+ return (String)get(ConfigConstants.PR_SSL_KEY_MIGRATION_TOKEN_SOPPASSWD);
+ }
+
+ public void setInstalledOCSP(String val) {
+ put(ConfigConstants.PR_OCSP, val);
+ }
+
+ public void setInstalledCA(String val) {
+ put(ConfigConstants.PR_CA, val);
+ }
+
+ public boolean isOCSPInstalled() {
+ String str = (String)get(ConfigConstants.PR_OCSP);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public boolean isCAInstalled() {
+ String str = (String)get(ConfigConstants.PR_CA);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public void setInstalledRA(String val) {
+ put(ConfigConstants.PR_RA, val);
+ }
+
+ public boolean isRAInstalled() {
+ String str = (String)get(ConfigConstants.PR_RA);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public void setInstalledKRA(String val) {
+ put(ConfigConstants.PR_KRA, val);
+ }
+
+ public void setInstalledTKS(String val) {
+ put(ConfigConstants.PR_TKS, val);
+ }
+
+ public boolean isKRAInstalled() {
+ String str = (String)get(ConfigConstants.PR_KRA);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+ public boolean isTKSInstalled() {
+ String str = (String)get(ConfigConstants.PR_TKS);
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+ public boolean isOCSPServiceAdded() {
+ String str = (String)get(ConfigConstants.PR_CA_OCSP_SERVICE);
+ if (str == null || str.equals(ConfigConstants.FALSE))
+ return false;
+ return true;
+ }
+
+ public void setOCSPService(String val) {
+ put(ConfigConstants.PR_CA_OCSP_SERVICE, val);
+ }
+
+ public void setCMHost(String host) {
+ put(ConfigConstants.CA_HOST, host);
+ }
+
+ public String getCMHost() {
+ return (String)get(ConfigConstants.CA_HOST);
+ }
+
+ public void setCMPort(String port) {
+ put(ConfigConstants.CA_PORT, port);
+ }
+
+ public String getCMPort() {
+ return (String)get(ConfigConstants.CA_PORT);
+ }
+
+ public void setCMTimeout(String timeout) {
+ put(ConfigConstants.CA_TIMEOUT, timeout);
+ }
+
+ public String getCMTimeout() {
+ return (String)get(ConfigConstants.CA_TIMEOUT);
+ }
+
+ public void setCMEEPort(String port) {
+ put(ConfigConstants.CA_EEPORT, port);
+ }
+
+ public String getCMEEPort() {
+ return (String)get(ConfigConstants.CA_EEPORT);
+ }
+
+ public void setCMEEType(String type) {
+ put(ConfigConstants.CA_EETYPE, type);
+ }
+
+ public String getCMEEType() {
+ return (String)get(ConfigConstants.CA_EETYPE);
+ }
+
+ public void setRequestStatus(String requestStatus) {
+ put(getCertType()+ConfigConstants.PR_CERT_REQUEST+"Status", requestStatus);
+ }
+
+ public String getRequestStatus() {
+ return (String)get(getCertType()+ConfigConstants.PR_CERT_REQUEST+"Status");
+ }
+
+ public void setRequestID(String requestID) {
+ put(getCertType()+ConfigConstants.PR_REQUEST_ID, requestID);
+ }
+
+ public String getRequestID() {
+ return (String)get(getCertType()+ConfigConstants.PR_REQUEST_ID);
+ }
+
+ public void setX509RequestStatus(String requestStatus) {
+ put("x509"+ConfigConstants.PR_CERT_REQUEST+"Status", requestStatus);
+ }
+
+ public String getX509RequestStatus() {
+ return (String)get("x509"+ConfigConstants.PR_CERT_REQUEST+"Status");
+ }
+
+ public void setX509RequestID(String requestID) {
+ put("x509"+getCertRequest()+ConfigConstants.PR_CERT_REQUEST, requestID);
+ }
+
+ public String getX509RequestID() {
+ return (String)get("x509"+getCertRequest()+ConfigConstants.PR_CERT_REQUEST);
+ }
+
+ public void setRequestSent(boolean sent) {
+ if (sent)
+ put(getCertRequest()+"Sent", ConfigConstants.TRUE);
+ else
+ put(getCertRequest()+"Sent", ConfigConstants.FALSE);
+ }
+
+ public boolean requestSent() {
+ String str = (String)get(getCertRequest()+"Sent");
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ return false;
+ }
+
+ public void setRequestError(String error) {
+ put(getCertRequest()+"Error", error);
+ }
+
+ public String getRequestError() {
+ return (String)get(getCertRequest()+"Error");
+ }
+
+ public void setImportError(String error) {
+ put(getCertType()+"Error", error);
+ }
+
+ public String getImportError() {
+ return (String)get(getCertType()+"Error");
+ }
+
+ public void setX509RequestError(String error) {
+ put("x509"+getCertRequest()+"Error", error);
+ }
+
+ public String getX509RequestError() {
+ return (String)get("x509"+getCertRequest()+"Error");
+ }
+
+ public void setDRMHost(String host) {
+ put(ConfigConstants.KRA_HOST, host);
+ }
+
+ public String getDRMHost() {
+ return (String)get(ConfigConstants.KRA_HOST);
+ }
+
+ public void setDRMPort(String port) {
+ put(ConfigConstants.KRA_PORT, port);
+ }
+
+ public String getDRMPort() {
+ return (String)get(ConfigConstants.KRA_PORT);
+ }
+
+ public void setDRMTimeout(String timeout) {
+ put(ConfigConstants.KRA_TIMEOUT, timeout);
+ }
+
+ public String getDRMTimeout() {
+ return (String)get(ConfigConstants.KRA_TIMEOUT);
+ }
+
+ public void enableRemoteDRM(String enable) {
+ put(ConfigConstants.REMOTE_KRA_ENABLED, enable);
+ }
+
+ public boolean isRemoteDRM() {
+ String value = (String)get(ConfigConstants.REMOTE_KRA_ENABLED);
+ if (value == null || value.equals("") || value.equals(ConfigConstants.FALSE) ||
+ !value.equals(ConfigConstants.TRUE))
+ return false;
+ return true;
+ }
+
+ public String getSingleSignon() {
+ return (String)get(ConfigConstants.PR_SINGLE_SIGNON);
+ }
+
+ public void setRequiredAgents(String val) {
+ put(ConfigConstants.PR_AGENT_M, val);
+ }
+
+ public String getRequiredAgents() {
+ return (String)get(ConfigConstants.PR_AGENT_M);
+ }
+
+ public void setTotalAgents(String val) {
+ put(ConfigConstants.PR_AGENT_N, val);
+ }
+
+ public String getTotalAgents() {
+ return (String)get(ConfigConstants.PR_AGENT_N);
+ }
+
+ public String getHashType() {
+ return (String)get(ConfigConstants.PR_HASH_TYPE);
+ }
+
+ public void setHashType(String type) {
+ put(ConfigConstants.PR_HASH_TYPE, type);
+ }
+
+ public String getSignedByType() {
+ return (String)get(ConfigConstants.PR_SIGNEDBY_TYPE);
+ }
+
+ public void setSignedByType(String type) {
+ put(ConfigConstants.PR_SIGNEDBY_TYPE, type);
+ }
+
+ public String getCAKeyType() {
+ return (String)get(ConfigConstants.PR_CA_KEYTYPE);
+ }
+
+ public boolean hasEntireCAChain() {
+ String str = (String)get(Constants.PR_CA_SIGNING_CERT+
+ "hasEntireChain");
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ else
+ return false;
+ }
+
+ public boolean hasEntireSSLChain() {
+ String str = (String)get(Constants.PR_SERVER_CERT+
+ "hasEntireChain");
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ else
+ return false;
+ }
+
+ public boolean hasEntireKRAChain() {
+ String str = (String)get(Constants.PR_KRA_TRANSPORT_CERT+
+ "hasEntireChain");
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ else
+ return false;
+ }
+
+ public boolean hasEntireOCSPChain() {
+ String str = (String)get(Constants.PR_OCSP_SIGNING_CERT+
+ "hasEntireChain");
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ else
+ return false;
+ }
+
+ public boolean hasEntireRAChain() {
+ String str = (String)get(Constants.PR_RA_SIGNING_CERT+
+ "hasEntireChain");
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ else
+ return false;
+ }
+
+ public String getOComponent() {
+ return (String)get(ConfigConstants.PR_O_COMPONENT);
+ }
+
+ public void setOComponent(String str) {
+ put(ConfigConstants.PR_O_COMPONENT, str);
+ }
+
+ public String getOUComponent() {
+ return (String)get(ConfigConstants.PR_OU_COMPONENT);
+ }
+
+ public void setOUComponent(String str) {
+ put(ConfigConstants.PR_OU_COMPONENT, str);
+ }
+
+ public String getLComponent() {
+ return (String)get(ConfigConstants.PR_L_COMPONENT);
+ }
+
+ public void setLComponent(String str) {
+ put(ConfigConstants.PR_L_COMPONENT, str);
+ }
+
+ public String getSTComponent() {
+ return (String)get(ConfigConstants.PR_ST_COMPONENT);
+ }
+
+ public void setSTComponent(String str) {
+ put(ConfigConstants.PR_ST_COMPONENT, str);
+ }
+
+ public String getCComponent() {
+ return (String)get(ConfigConstants.PR_C_COMPONENT);
+ }
+
+ public void setCComponent(String str) {
+ put(ConfigConstants.PR_C_COMPONENT, str);
+ }
+
+ public String getCAOComp() {
+ String str = (String)get(ConfigConstants.PR_CA_O_COMPONENT);
+ return str;
+ }
+
+ public void setCAOComp(String str) {
+ put(ConfigConstants.PR_CA_O_COMPONENT, str);
+ }
+
+ public String getCACComp() {
+ String str = (String)get(ConfigConstants.PR_CA_C_COMPONENT);
+ return str;
+ }
+
+ public void setCACComp(String str) {
+ put(ConfigConstants.PR_CA_C_COMPONENT, str);
+ }
+
+ public String getOCSPOComp() {
+ String str = (String)get(ConfigConstants.PR_OCSP_O_COMPONENT);
+ return str;
+ }
+
+ public void setOCSPOComp(String str) {
+ put(ConfigConstants.PR_OCSP_O_COMPONENT, str);
+ }
+
+ public String getRAOComp() {
+ String str = (String)get(ConfigConstants.PR_RA_O_COMPONENT);
+ return str;
+ }
+
+ public void setRAOComp(String str) {
+ put(ConfigConstants.PR_RA_O_COMPONENT, str);
+ }
+
+ public String getOCSPCComp() {
+ String str = (String)get(ConfigConstants.PR_OCSP_C_COMPONENT);
+ return str;
+ }
+
+ public void setOCSPCComp(String str) {
+ put(ConfigConstants.PR_OCSP_C_COMPONENT, str);
+ }
+
+ public String getRACComp() {
+ String str = (String)get(ConfigConstants.PR_RA_C_COMPONENT);
+ return str;
+ }
+
+ public void setRACComp(String str) {
+ put(ConfigConstants.PR_RA_C_COMPONENT, str);
+ }
+
+ public String getCertRequestDir() {
+ return (String)get(Constants.PR_CERT_REQUEST_DIR);
+ }
+
+ public void setCASerialNumber(String str) {
+ put(ConfigConstants.PR_CA_SERIAL_NUMBER, str);
+ }
+ public void setRequestNumber(String str) {
+ put(ConfigConstants.PR_REQUEST_NUMBER, str);
+ }
+
+ public String getCASerialNumber() {
+ return (String)get(ConfigConstants.PR_CA_SERIAL_NUMBER);
+ }
+ public String getRequestNumber() {
+ return (String)get(ConfigConstants.PR_REQUEST_NUMBER);
+ }
+
+ public void clearRequestNumber() {
+ remove(ConfigConstants.PR_REQUEST_NUMBER);
+ }
+
+ public void setCAEndSerialNumber(String str) {
+ put(ConfigConstants.PR_CA_ENDSERIAL_NUMBER, str);
+ }
+
+ public String getCAEndSerialNumber() {
+ return (String)get(ConfigConstants.PR_CA_ENDSERIAL_NUMBER);
+ }
+
+ public void clearCAEndSerialNumber() {
+ remove(ConfigConstants.PR_CA_ENDSERIAL_NUMBER);
+ }
+ public String getEndRequestNumber() {
+ return (String)get(ConfigConstants.PR_ENDREQUEST_NUMBER);
+ }
+
+ public boolean isCloning() {
+ String str = (String)get("cloning");
+ if (str != null && str.equals(ConfigConstants.TRUE))
+ return true;
+ else
+ return false;
+ }
+ public void setCloning(String str) {
+ put("cloning", str);
+ }
+ public void setCLAHost(String host) {
+ put(ConfigConstants.CLA_HOST, host);
+ }
+
+ public String getCLAHost() {
+ return (String)get(ConfigConstants.CLA_HOST);
+ }
+
+ public void setCLAPort(String port) {
+ put(ConfigConstants.CLA_PORT, port);
+ }
+
+ public String getCLAPort() {
+ return (String)get(ConfigConstants.CLA_PORT);
+ }
+
+ public void setCLAPortEE(String port) {
+ put(ConfigConstants.CLA_PORT_EE, port);
+ }
+
+ public String getCLAPortEE() {
+ return (String)get(ConfigConstants.CLA_PORT_EE);
+ }
+
+ public void setCLATimeout(String timeout) {
+ put(ConfigConstants.CLA_TIMEOUT, timeout);
+ }
+
+ public String getCLATimeout() {
+ return (String)get(ConfigConstants.CLA_TIMEOUT);
+ }
+
+ public boolean isConnectDBDone() {
+ String val = (String)get(ConfigConstants.STAGE_CONNECT_DB);
+ if (val == null || val.equals("") || val.equals(ConfigConstants.FALSE))
+ return false;
+ return true;
+ }
+
+ public void setConnectDBDone(String s) {
+ put(ConfigConstants.STAGE_CONNECT_DB, s);
+ }
+
+ public boolean isCreateDBDone() {
+ String val = (String)get(ConfigConstants.STAGE_INTERNAL_DB);
+ if (val == null || val.equals("") || val.equals(ConfigConstants.FALSE))
+ return false;
+ return true;
+ }
+
+ public void setCreateDBDone(String s) {
+ put(ConfigConstants.STAGE_INTERNAL_DB, s);
+ }
+
+ public boolean isWebServerDone() {
+ String val = (String)get(ConfigConstants.STAGE_CONFIG_WEBSERVER);
+ if (val == null || val.equals("") || val.equals(ConfigConstants.FALSE))
+ return false;
+ return true;
+ }
+
+ public void setWebServerDone(String str) {
+ put(ConfigConstants.STAGE_CONFIG_WEBSERVER, str);
+ }
+
+ public boolean isOCSPServiceDone() {
+ String val = (String)get(ConfigConstants.STAGE_OCSP_SERVICE_ADDED);
+ if (val == null || val.equals("") || val.equals(ConfigConstants.FALSE))
+ return false;
+ return true;
+ }
+
+ public boolean isCACertRequestSucc() {
+ String str = (String)get(ConfigConstants.STAGE_CA_REQ_SUCCESS);
+ if (str == null || str.equals("") || str.equals(ConfigConstants.FALSE))
+ return false;
+ return true;
+ }
+
+ public boolean isRACertRequestSucc() {
+ String str = (String)get(ConfigConstants.STAGE_RA_REQ_SUCCESS);
+ if (str == null || str.equals("") || str.equals(ConfigConstants.FALSE))
+ return false;
+ return true;
+ }
+
+ public boolean isKRACertRequestSucc() {
+ String str = (String)get(ConfigConstants.STAGE_KRA_REQ_SUCCESS);
+ if (str == null || str.equals("") || str.equals(ConfigConstants.FALSE))
+ return false;
+ return true;
+ }
+
+ public boolean isSSLCertRequestSucc() {
+ String str = (String)get(ConfigConstants.STAGE_SSL_REQ_SUCCESS);
+ if (str == null || str.equals("") || str.equals(ConfigConstants.FALSE))
+ return false;
+ return true;
+ }
+
+ public boolean isOCSPCertRequestSucc() {
+ String str = (String)get(ConfigConstants.STAGE_OCSP_REQ_SUCCESS);
+ if (str == null || str.equals("") || str.equals(ConfigConstants.FALSE))
+ return false;
+ return true;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIAdminPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIAdminPage.java
new file mode 100644
index 000000000..467632102
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIAdminPage.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.admin.certsrv.config.install;
+
+import java.util.*;
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * Admin page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIAdminPage extends WizardBasePanel implements IWizardPanel {
+ private JCheckBox mEnable;
+ private JTextField mIDText, mFullNameText, mPasswordText,
+ mPasswordAgainText;
+ private static final String PANELNAME = "ADMININSTALLWIZARD";
+ private static final String HELPINDEX =
+ "install-administrator-configuration-wizard-help";
+
+ WIAdminPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIAdminPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isAgreementDone() &&
+ wizardInfo.isReplicationEnabled())
+ return false;
+ if (wizardInfo.isCloning() && !wizardInfo.isAgreementDone())
+ return false;
+ if (wizardInfo.isAdministratorDone())
+ return false;
+ mIDText.setText(wizardInfo.getCertAdminUid());
+ mFullNameText.setText(wizardInfo.getCertAdminName());
+
+ setBorder(makeTitledBorder(PANELNAME));
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ String password = mPasswordText.getText().trim();
+ String passwordAgain = mPasswordAgainText.getText().trim();
+ if (password.equals("") || passwordAgain.equals("")) {
+ setErrorMessage("BLANKPASSWD");
+ return false;
+ }
+
+ if (!password.equals(passwordAgain)) {
+ setErrorMessage("NOTSAMEPASSWD");
+ return false;
+ }
+
+ if (mIDText.getText().trim().equals("")) {
+ setErrorMessage("BLANKADMINID");
+ return false;
+ }
+
+ if (mFullNameText.getText().trim().equals("")) {
+ setErrorMessage("BLANKADMINNAME");
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_SETUP_ADMINISTRATOR;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ rawData = rawData+"&"+ConfigConstants.PR_CERT_ADMINUID+"="+mIDText.getText();
+ rawData = rawData+"&"+ConfigConstants.PR_CERT_ADMINNAME+"="+mFullNameText.getText();
+ rawData = rawData+"&"+ConfigConstants.PR_CERT_ADMINPASSWD+"="+mPasswordAgainText.getText();
+ if (mEnable.isSelected()) {
+ rawData = rawData+"&"+ConfigConstants.PR_ENABLE+"=true";
+ } else {
+ rawData = rawData+"&"+ConfigConstants.PR_ENABLE+"=false";
+ }
+ if (wizardInfo.getInternalDBPasswd() != null)
+ rawData = rawData+"&"+ConfigConstants.PR_DB_PWD+"="+wizardInfo.getInternalDBPasswd();
+ wizardInfo.setCertAdminUid(mIDText.getText().trim());
+ wizardInfo.setCertAdminName(mFullNameText.getText().trim());
+
+ startProgressStatus();
+ boolean ready = send(rawData, wizardInfo);
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage(wizardInfo);
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ PANELNAME+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea desc = createTextArea(mResource.getString(
+ "ADMININSTALLWIZARD_TEXT_HEADING_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel idLbl = makeJLabel("ADMINID");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.insets = new Insets(COMPONENT_SPACE,0,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ add(idLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mIDText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(mIDText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel nameLbl = makeJLabel("FULLNAME");
+ gbc.insets = new Insets(0, 0,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.NORTHEAST;
+ add(nameLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mFullNameText = makeJTextField(30);
+ gbc.insets = new Insets(0, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mFullNameText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel passwdLbl = makeJLabel("PASSWORD");
+ gbc.insets = new Insets(0, 0,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ add(passwdLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPasswordText = makeJPasswordField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(0,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mPasswordText, gbc);
+
+/*
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea dummy2 = createTextArea(" ", 1, 5);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(dummy2, gbc);
+*/
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel passwdAgainLbl = makeJLabel("PASSWORDAGAIN");
+ gbc.insets = new Insets(0, 0,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ add(passwdAgainLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPasswordAgainText = makeJPasswordField(30);
+ gbc.insets = new Insets(0, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mPasswordAgainText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel passwdAgainLbl1 = makeJLabel("DUMMY");
+ gbc.insets = new Insets(0, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.weighty = 1.0;
+ add(passwdAgainLbl1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEnable = makeJCheckBox("ENABLE");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.weighty = 1.0;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mEnable, gbc);
+ mEnable.setSelected(true);
+/*
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea dummy3 = createTextArea(" ", 1, 5);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(dummy3, gbc);
+*/
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIAllCertsInstalledPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIAllCertsInstalledPage.java
new file mode 100644
index 000000000..b84460814
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIAllCertsInstalledPage.java
@@ -0,0 +1,269 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Introduction page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIAllCertsInstalledPage extends WizardBasePanel implements IWizardPanel {
+ private JTextArea mLabel;
+ private static final String PANELNAME = "ALLCERTSINSTALLEDWIZARD";
+ private static final String HELPINDEX =
+ "install-allcerts-getinstalled-wizard-help";
+
+ WIAllCertsInstalledPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIAllCertsInstalledPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return true;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ if (wizardInfo.isCloning())
+ return false;
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled()) {
+ if (caCertInstalled(wizardInfo) && kraCertInstalled(wizardInfo))
+ return false;
+ if (wizardInfo.isCloning()) {
+ if (wizardInfo.isCACloningDone() && wizardInfo.isKRACloningDone()) {
+ if (wizardInfo.isSSLCloningDone())
+ return false;
+ else if (!wizardInfo.isSSLCloningDone()) {
+ if (wizardInfo.isSSLLocalCertDone() || wizardInfo.isSSLCertInstalledDone())
+ return false;
+ }
+ }
+ }
+ }
+
+ else if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled()) {
+ if (raCertInstalled(wizardInfo) && kraCertInstalled(wizardInfo))
+ return false;
+ if (wizardInfo.isCloning()) {
+ if (wizardInfo.isRACloningDone() && wizardInfo.isKRACloningDone()) {
+ if (wizardInfo.isSSLCloningDone())
+ return false;
+ else if (!wizardInfo.isSSLCloningDone()) {
+ if (wizardInfo.isSSLLocalCertDone() || wizardInfo.isSSLCertInstalledDone())
+ return false;
+ }
+ }
+ }
+ }
+
+ else if (wizardInfo.isCAInstalled()) {
+ if (caCertInstalled(wizardInfo))
+ return false;
+ if (wizardInfo.isCloning()) {
+ if (wizardInfo.isCACloningDone()) {
+ if (wizardInfo.isSSLCloningDone())
+ return false;
+ else if (!wizardInfo.isSSLCloningDone()) {
+ if (wizardInfo.isSSLLocalCertDone() || wizardInfo.isSSLCertInstalledDone())
+ return false;
+ }
+ }
+ }
+ }
+ else if (wizardInfo.isOCSPInstalled()) {
+ if (ocspCertInstalled(wizardInfo))
+ return false;
+ }
+
+ else if (wizardInfo.isRAInstalled()) {
+ if (raCertInstalled(wizardInfo))
+ return false;
+ if (wizardInfo.isCloning()) {
+ if (wizardInfo.isRACloningDone()) {
+ if (wizardInfo.isSSLCloningDone())
+ return false;
+ else if (!wizardInfo.isSSLCloningDone()) {
+ if (wizardInfo.isSSLLocalCertDone() || wizardInfo.isSSLCertInstalledDone())
+ return false;
+ }
+ }
+ }
+ }
+
+ else if (wizardInfo.isKRAInstalled()) {
+ if (kraCertInstalled(wizardInfo))
+ return false;
+ if (wizardInfo.isCloning()) {
+ if (wizardInfo.isKRACloningDone()) {
+ if (wizardInfo.isSSLCloningDone())
+ return false;
+ else if (!wizardInfo.isSSLCloningDone()) {
+ if (wizardInfo.isSSLLocalCertDone() || wizardInfo.isSSLCertInstalledDone())
+ return false;
+ }
+ }
+ }
+ }
+ else if (wizardInfo.isTKSInstalled()) {
+ if (tksCertInstalled(wizardInfo))
+ return false;
+ }
+ setBorder(makeTitledBorder(PANELNAME));
+ mLabel.setVisible(false);
+
+ return true;
+ }
+
+ private boolean caCertInstalled(InstallWizardInfo wizardInfo) {
+ if (wizardInfo.isMigrationEnable() ||
+ ((wizardInfo.isSelfSignedCACertDone() ||
+ wizardInfo.isCACertInstalledDone()) &&
+ (wizardInfo.isSSLLocalCertDone() || wizardInfo.isSSLCertInstalledDone())))
+ return true;
+ return false;
+ }
+
+ private boolean ocspCertInstalled(InstallWizardInfo wizardInfo) {
+ if (wizardInfo.isOCSPCertInstalledDone() &&
+ wizardInfo.isSSLCertInstalledDone())
+ return true;
+ return false;
+ }
+
+ private boolean raCertInstalled(InstallWizardInfo wizardInfo) {
+ if ((wizardInfo.isRALocalCertDone() ||
+ wizardInfo.isRACertInstalledDone()) &&
+ (wizardInfo.isMigrationEnable() || wizardInfo.isSSLLocalCertDone() ||
+ wizardInfo.isSSLCertInstalledDone()))
+ return true;
+ return false;
+ }
+
+ private boolean kraCertInstalled(InstallWizardInfo wizardInfo) {
+ if ((wizardInfo.isKRALocalCertDone() ||
+ wizardInfo.isKRACertInstalledDone()) &&
+ (wizardInfo.isMigrationEnable() || wizardInfo.isSSLLocalCertDone() ||
+ wizardInfo.isSSLCertInstalledDone()))
+ return true;
+ return false;
+ }
+ private boolean tksCertInstalled(InstallWizardInfo wizardInfo) {
+ if(wizardInfo.isSSLCertInstalledDone())
+ return true;
+ return false;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_GET_DEFAULT_INFO;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_READ;
+ // #344791 - help server to make up the hostname
+/*
+ data.put(ConfigConstants.PR_HOST,
+ consoleInfo.get(ConfigConstants.PR_HOST));
+*/
+ startProgressStatus();
+ boolean ready = send(rawData, wizardInfo);
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage();
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ PANELNAME+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea desc = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_DESC_LABEL"));
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ mLabel = createTextArea(mResource.getString(
+ "INTROINSTALLWIZARD_TEXT_HEADING_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ //gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mLabel, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICACert1CustomPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICACert1CustomPage.java
new file mode 100644
index 000000000..6f8c26032
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICACert1CustomPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * Setup CA signing cert for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICACert1CustomPage extends WBaseKeyPage implements IWizardPanel {
+ private static final String PANELNAME = "CACERT1CUSTOMWIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WICACert1CustomPage() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICACert1Page.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICACert1Page.java
new file mode 100644
index 000000000..c3ca75420
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICACert1Page.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Setup CA signing cert for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICACert1Page extends WizardBasePanel implements IWizardPanel {
+ private JComboBox mKeyTypeBox;
+ private JComboBox mKeyLengthBox;
+ //private JComboBox mTokenBox;
+ //private JPasswordField mPasswordText;
+
+ private static final String PANELNAME = "CACERT1WIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WICACert1Page() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ return true;
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea desc = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "CACERT1WIZARD_TEXT_HEADING_LABEL"), 80), 2, 80);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+/*
+ JTextArea desc1 = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "CACERT1WIZARD_TEXT_TOKENHEADING_LABEL"), 80), 1, 80);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc1, gbc);
+
+ JLabel tokenLbl = makeJLabel("TOKEN");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(tokenLbl, gbc);
+
+ mTokenBox = new JComboBox();
+ mTokenBox.addItem("internal");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,0,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(mTokenBox, gbc);
+
+ JTextArea dummy = createTextArea(" ", 1, 5);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,0,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(dummy, gbc);
+
+ JTextArea desc2 = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "CACERT1WIZARD_TEXT_HARDWARE_LABEL"), 80), 1, 80);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(2*COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc2, gbc);
+
+ JLabel pwdLbl = makeJLabel("PWD");
+ mPasswordText = makeJPasswordField(20);
+ //JTextArea dummy1 = createTextArea(" ", 1, 10);
+ //CMSAdminUtil.addComponents(this, pwdLbl, mPasswordText, dummy1, gbc);
+ CMSAdminUtil.addComponents(this, pwdLbl, mPasswordText, gbc);
+*/
+
+ JTextArea desc3 = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "CACERT1WIZARD_TEXT_KEY_LABEL"), 80), 1, 80);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(2*COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc3, gbc);
+
+ JPanel panel = new JPanel();
+ GridBagLayout gb1 = new GridBagLayout();
+ panel.setLayout(gb1);
+
+ JLabel keyTypeLbl = makeJLabel("KEYTYPE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel.add(keyTypeLbl, gbc);
+
+ mKeyTypeBox = makeJComboBox("KEYTYPE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ panel.add(mKeyTypeBox, gbc);
+
+ JLabel keyLengthLbl = makeJLabel("KEYLENGTH");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ //gbc.weighty = 1.0;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,0,COMPONENT_SPACE);
+ gbc.gridheight = gbc.REMAINDER;
+ panel.add(keyLengthLbl, gbc);
+
+ mKeyLengthBox = makeJComboBox("KEYLENGTH");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ //gbc.weighty = 1.0;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,0,COMPONENT_SPACE);
+ panel.add(mKeyLengthBox, gbc);
+
+ JLabel unitLbl = makeJLabel("UNITS");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ //gbc.weighty = 1.0;
+ gbc.insets = new Insets(0, 0,0,COMPONENT_SPACE);
+ panel.add(unitLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ add(panel, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICACert2Page.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICACert2Page.java
new file mode 100644
index 000000000..79fc00b02
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICACert2Page.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * CA signing cert for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICACert2Page extends WBaseDNPage implements IWizardPanel {
+ private static final String PANELNAME = "CACERT2WIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WICACert2Page() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICACertDNPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICACertDNPage.java
new file mode 100644
index 000000000..531de6be5
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICACertDNPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import javax.swing.*;
+
+/**
+ * Subject DN page for CA signing certificate
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICACertDNPage extends WICertDNPage {
+ private static final String PANELNAME = "INSTALLCACERTDNWIZARD";
+ private static final String CALOCALHELPINDEX = "install-cacertlocal-subjectdn-wizard-help";
+ private static final String CAREMOTEHELPINDEX = "install-cacertsub-subjectdn-wizard-help";
+ private static final String CAKRALOCALHELPINDEX = "install-cakracertlocal-subjectdn-wizard-help";
+ private static final String CAKRAREMOTEHELPINDEX = "install-cakracertsub-subjectdn-wizard-help";
+
+ WICACertDNPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WICACertDNPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isCACloningDone())
+ return false;
+
+ if (!wizardInfo.isCAInstalled() || wizardInfo.isMigrationEnable() ||
+ wizardInfo.isSelfSignedCACertDone() || wizardInfo.isCACertRequestDone() ||
+ wizardInfo.isCACertInstalledDone())
+ return false;
+ //dnDesc.setText(CA_DN);
+ String str = wizardInfo.getCASubjectName();
+ if (str == null || str.equals(""))
+ str = CA_CN+", "+CA_C;
+ wizardInfo.setCASubjectName(str);
+ populateDN(str);
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ if (wizardInfo.isCACertLocalCA())
+ mHelpIndex = CAKRALOCALHELPINDEX;
+ else
+ mHelpIndex = CAKRAREMOTEHELPINDEX;
+ else if (wizardInfo.isCACertLocalCA())
+ mHelpIndex = CALOCALHELPINDEX;
+ else
+ mHelpIndex = CAREMOTEHELPINDEX;
+ return super.initializePanel(info);
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ if (super.concludePanel(info)) {
+ wizardInfo.setCASubjectName(mStr);
+ return true;
+ }
+
+ return false;
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+/*
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String str = mOText.getText().trim();
+ wizardInfo.setCAOComp(str);
+ str = mCText.getText().trim();
+ wizardInfo.setCACComp(str);
+*/
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICACertExtensionPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICACertExtensionPage.java
new file mode 100644
index 000000000..1a1a1a8b9
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICACertExtensionPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.border.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * Certificate Extension page for CA signing Certificate.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICACertExtensionPage extends WICertExtensionPage {
+ private static final String PANELNAME = "INSTALLCACERTEXTENSION1WIZARD";
+ private static final String CAHELPINDEX = "install-cacert-extension-wizard-help";
+ private static final String CAKRAHELPINDEX = "install-cakracert-extension-wizard-help";
+
+ WICACertExtensionPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WICACertExtensionPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isCACloningDone())
+ return false;
+
+ if (!wizardInfo.isCAInstalled() || wizardInfo.isMigrationEnable() ||
+ wizardInfo.isSelfSignedCACertDone() ||
+ wizardInfo.isCACertRequestDone() || wizardInfo.isCACertInstalledDone())
+ return false;
+
+ if (!mModified) {
+ mBasicCheckBox.setSelected(true);
+ mAKICheckBox.setSelected(true);
+ mCACheckBox.setSelected(true);
+ mSKICheckBox.setSelected(true);
+ mCertPathBox.setSelected(false);
+ mExtendedKeyCheckBox.setSelected(false);
+ mKeyUsageBox.setSelected(true);
+ }
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else
+ mHelpIndex = CAHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICACertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICACertPage.java
new file mode 100644
index 000000000..b962c6ca1
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICACertPage.java
@@ -0,0 +1,172 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * This page allows the user to generate a CA certificate request.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICACertPage extends WizardBasePanel implements IWizardPanel {
+ private JRadioButton mSelfBtn, mSubordinateBtn, mEmailBtn;
+ private JRadioButton mUrlBtn, mManualBtn;
+ private JTextField mEmailText;
+ private JTextField mUrlText;
+ private static final String PANELNAME = "CACERTWIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WICACertPage() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea desc = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "CACERTWIZARD_TEXT_HEADING_LABEL"), 80), 1, 80);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ mSelfBtn = makeJRadioButton("SELF", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mSelfBtn, gbc);
+
+ mSubordinateBtn = makeJRadioButton("SUBORDINATE", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0,COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mSubordinateBtn, gbc);
+
+ JTextArea desc1 = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "CACERTWIZARD_TEXT_HEADING1_LABEL"), 80), 2, 80);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc1, gbc);
+
+ mEmailBtn = makeJRadioButton("EMAIL", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mEmailBtn, gbc);
+
+ mEmailText = makeJTextField(30);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mEmailText, gbc);
+
+ mUrlBtn = makeJRadioButton("URL", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mUrlBtn, gbc);
+
+ mUrlText = makeJTextField(30);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ add(mUrlText, gbc);
+
+ mManualBtn = makeJRadioButton("MANUAL", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mManualBtn, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(dummy, gbc);
+
+ ButtonGroup CAButtonGrp = new ButtonGroup();
+ CAButtonGrp.add(mSelfBtn);
+ CAButtonGrp.add(mSubordinateBtn);
+
+ ButtonGroup MethodButtonGrp = new ButtonGroup();
+ MethodButtonGrp.add(mEmailBtn);
+ MethodButtonGrp.add(mUrlBtn);
+ MethodButtonGrp.add(mManualBtn);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICACertSubmitPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICACertSubmitPage.java
new file mode 100644
index 000000000..efa2d8b0c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICACertSubmitPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * CA Certificate Submission.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICACertSubmitPage extends WICertSubmitPage implements IWizardPanel {
+ private static final String PANELNAME = "INSTALLCACERTWIZARD";
+ private static final String CAHELPINDEX = "install-catype-wizard-help";
+ private static final String CAKRAHELPINDEX = "install-cakratype-wizard-help";
+
+ WICACertSubmitPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WICACertSubmitPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ if (wizardInfo.isCloning() && wizardInfo.isCACloningDone())
+ return false;
+
+ wizardInfo.put(Constants.PR_CERTIFICATE_TYPE,
+ Constants.PR_CA_SIGNING_CERT);
+ if (!wizardInfo.isCAInstalled() || wizardInfo.isMigrationEnable() ||
+ wizardInfo.isSelfSignedCACertDone() || wizardInfo.isCACertRequestDone() ||
+ wizardInfo.isCACertInstalledDone())
+ return false;
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else
+ mHelpIndex = CAHELPINDEX;
+ return super.initializePanel(info);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (mSelfButton.isSelected())
+ wizardInfo.setCACertLocalCA(Constants.TRUE);
+ else
+ wizardInfo.setCACertLocalCA(Constants.FALSE);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICACertValidityPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICACertValidityPage.java
new file mode 100644
index 000000000..cb8fa550d
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICACertValidityPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * Validity page for CA signing certificate.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICACertValidityPage extends WICertValidityPage {
+ private static final String PANELNAME = "INSTALLCACERTVALIDWIZARD";
+ private static final String CAHELPINDEX = "install-cacert-validity-wizard-help";
+ private static final String CAKRAHELPINDEX = "install-cakracert-validity-wizard-help";
+
+ WICACertValidityPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WICACertValidityPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isCACloningDone())
+ return false;
+ if (!wizardInfo.isCAInstalled() || wizardInfo.isMigrationEnable() ||
+ wizardInfo.isSelfSignedCACertDone() || wizardInfo.isCACertRequestDone() ||
+ wizardInfo.isCACertInstalledDone())
+ return false;
+ if (super.initializePanel(info)) {
+ if (!wizardInfo.isCACertLocalCA())
+ return false;
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else
+ mHelpIndex = CAHELPINDEX;
+
+ return true;
+ }
+ return false;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICAKeyPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICAKeyPage.java
new file mode 100644
index 000000000..accc866b2
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICAKeyPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * Setup key information for CA signing certificate
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICAKeyPage extends WIKeyPage implements IWizardPanel {
+ private static final String PANELNAME = "INSTALLCAKEYWIZARD";
+ private static final String CALOCALHELPINDEX =
+ "install-cakeylocal-configuration-wizard-help";
+ private static final String CAREMOTEHELPINDEX =
+ "install-cakeysub-configuration-wizard-help";
+ private static final String CAKRALOCALHELPINDEX =
+ "install-cakrakeylocal-configuration-wizard-help";
+ private static final String CAKRAREMOTEHELPINDEX =
+ "install-cakrakeysub-configuration-wizard-help";
+
+ WICAKeyPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WICAKeyPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ mWizardInfo = (InstallWizardInfo)info;
+ if (mWizardInfo.isCloning() && mWizardInfo.isCACloningDone())
+ return false;
+
+ if (!mWizardInfo.isCAInstalled() || mWizardInfo.isMigrationEnable() ||
+ mWizardInfo.isSelfSignedCACertDone() || mWizardInfo.isCACertRequestDone() ||
+ mWizardInfo.isCACertInstalledDone())
+ return false;
+
+ if (super.initializePanel(info)) {
+ String caTokenName = mWizardInfo.getCATokenName();
+ if (caTokenName == null || caTokenName.equals("")) {
+ mTokenBox.setSelectedIndex(0);
+ } else {
+ if (caTokenName.equals(Constants.PR_INTERNAL_TOKEN_NAME))
+ mTokenBox.setSelectedIndex(0);
+ else
+ mTokenBox.setSelectedItem(caTokenName);
+ }
+ }
+
+ int counts = mKeyTypeBox.getItemCount();
+ if (counts == 1)
+ mKeyTypeBox.addItem("DSA");
+
+ if (mWizardInfo.isCAInstalled() && mWizardInfo.isKRAInstalled()) {
+ if (mWizardInfo.isCACertLocalCA())
+ mHelpIndex = CAKRALOCALHELPINDEX;
+ else
+ mHelpIndex = CAKRAREMOTEHELPINDEX;
+ } else if (mWizardInfo.isCACertLocalCA())
+ mHelpIndex = CALOCALHELPINDEX;
+ else
+ mHelpIndex = CAREMOTEHELPINDEX;
+
+ enableFields();
+ mIsCAKey = true;
+ return true;
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ super.getUpdateInfo(info);
+ mWizardInfo.setCATokenName(mWizardInfo.getTokenName());
+
+ if (mPassword.isEditable()) {
+ String tokenname = mWizardInfo.getCATokenName();
+
+ // this is used for single signon. The key is the token name with
+ // the prefix "TOKEN:" and the value is the token password.
+ mWizardInfo.put("TOKEN:"+tokenname, mPassword.getText().trim());
+ }
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICAMessageDigestPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICAMessageDigestPage.java
new file mode 100644
index 000000000..e19fc6586
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICAMessageDigestPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Setup the message digest information for the installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICAMessageDigestPage extends WMessageDigestPage {
+
+ private static final String PANELNAME = "INSTALLCAMESSAGEDIGESTWIZARD";
+
+ WICAMessageDigestPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WICAMessageDigestPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isCACloningDone())
+ return false;
+
+ if (!wizardInfo.isCAInstalled() || wizardInfo.isMigrationEnable() ||
+ !wizardInfo.isCACertLocalCA() || wizardInfo.isSelfSignedCACertDone() ||
+ wizardInfo.isCACertRequestDone() || wizardInfo.isCACertInstalledDone())
+ return false;
+
+ mCAKeyType = wizardInfo.getCAKeyType();
+
+ return super.initializePanel(info);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (mDSAHashTypeBox.isVisible())
+ wizardInfo.setHashType((String)mDSAHashTypeBox.getSelectedItem());
+ else
+ wizardInfo.setHashType((String)mRSAHashTypeBox.getSelectedItem());
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICAOCSPServicePage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICAOCSPServicePage.java
new file mode 100644
index 000000000..9245b14bf
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICAOCSPServicePage.java
@@ -0,0 +1,172 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import java.math.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * This panel asks for the starting serial number that the CA issues
+ *
+ * @author Michelle Zhao
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICAOCSPServicePage extends WizardBasePanel implements IWizardPanel {
+ private JTextArea mDesc;
+
+ private boolean mEnable;
+ private JCheckBox mOCSPServiceCB;
+ private JLabel mOCSPServiceLabel;
+
+ private static final String PANELNAME = "CAOCSPSERVICEWIZARD";
+ private static final String HELPINDEX =
+ "install-ca-ocspservice-wizard-help";
+
+ WICAOCSPServicePage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WICAOCSPServicePage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ String serial;
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ setBorder(makeTitledBorder(PANELNAME));
+ // If ca's signing cert is not generated,
+ // we allow "back" to modify the panel
+ if (!wizardInfo.isCAInstalled())
+ return false;
+ if (wizardInfo.isOCSPServiceDone())
+ return false;
+ if (wizardInfo.isOCSPInstalled())
+ return false;
+
+ mDesc.setText(mResource.getString(PANELNAME+"_TEXT_HEADING_LABEL"));
+
+ return true;
+ }
+
+ public boolean validatePanel()
+ {
+ mEnable = mOCSPServiceCB.isSelected();
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_ADD_OCSP_SERVICE;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ if (mEnable)
+ rawData = rawData+"&"+ConfigConstants.PR_CA_OCSP_SERVICE+"="+
+ "true";
+ else
+ rawData = rawData+"&"+ConfigConstants.PR_CA_OCSP_SERVICE+"="+
+ "false";
+
+ startProgressStatus();
+
+ boolean ready = send(rawData, wizardInfo);
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage(wizardInfo);
+ if (str.equals(""))
+ setErrorMessage("Server Error");
+ else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mDesc = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mDesc, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mOCSPServiceLabel = makeJLabel("OCSPSERVICE");
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mOCSPServiceLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mOCSPServiceCB = makeJCheckBox("OCSPSERVICE");
+ mOCSPServiceCB.setSelected(true);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mOCSPServiceCB, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (mEnable)
+ wizardInfo.setOCSPService(ConfigConstants.TRUE);
+ else
+ wizardInfo.setOCSPService(ConfigConstants.FALSE);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICARequestResultPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICARequestResultPage.java
new file mode 100644
index 000000000..f40898821
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICARequestResultPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Display the CA signing certificate request result
+ *
+ * @author Michelle Zhao
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICARequestResultPage extends WIRequestResultPage {
+ WICARequestResultPage(JDialog parent) {
+ super(parent);
+ }
+
+ WICARequestResultPage(JDialog parent, JFrame adminFrame) {
+ super( parent, adminFrame);
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isCACloningDone())
+ return false;
+
+ if (wizardInfo.isCACertLocalCA() || !wizardInfo.isCAInstalled() ||
+ wizardInfo.isMigrationEnable() ||
+ wizardInfo.isCACertInstalledDone() ||
+ (wizardInfo.isCACertRequestSucc() && wizardInfo.isCAReqResultDisplayed()) ||
+ wizardInfo.isSelfSignedCACertDone())
+ return false;
+
+ wizardInfo.setCAReqResultDisplayed(Constants.TRUE);
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICASerialNumberPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICASerialNumberPage.java
new file mode 100644
index 000000000..3b1653d7f
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICASerialNumberPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import java.math.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * This panel asks for the starting serial number that the CA issues
+ *
+ * @author Michelle Zhao
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICASerialNumberPage extends WizardBasePanel implements IWizardPanel {
+ private JTextArea mDesc;
+
+ private String mSerialNumber;
+ private JTextField mSerialNumberText;
+ private JLabel mSerialNumberLabel;
+
+ private String mEndSerialNumber = null;
+ private JTextField mEndSerialNumberText;
+ private JLabel mEndSerialNumberLabel;
+
+ private String mbeginRequestNumber;
+ private JTextField mbeginRequestNumberText;
+ private JLabel mbeginRequestNumberLabel;
+
+ private String mEndRequestNumber = null;
+ private JTextField mEndRequestNumberText;
+ private JLabel mEndRequestNumberLabel;
+
+ private static final String DEFAULT_SERIAL_NUMBER = "1";
+ private static final String PANELNAME = "CASERIALNUMBERWIZARD";
+ private static final String HELPINDEX =
+ "install-ca-serialnumber-wizard-help";
+
+ WICASerialNumberPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WICASerialNumberPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ String serial;
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ setBorder(makeTitledBorder(PANELNAME));
+ // If ca's signing cert is not generated,
+ // we allow "back" to modify the panel
+
+ if (!wizardInfo.isCAInstalled() || wizardInfo.isMigrationEnable() ||
+ wizardInfo.isSelfSignedCACertDone() || wizardInfo.isCACertRequestDone()
+ ||wizardInfo.isNumberPageDone())
+ return false;
+
+ if (wizardInfo.isCloning())
+ mDesc.setText(mResource.getString(PANELNAME+"_TEXT_HEADING_LABEL")
+ + mResource.getString(PANELNAME+"_TEXT_MORE_LABEL"));
+ else
+ mDesc.setText(mResource.getString(PANELNAME+"_TEXT_HEADING_LABEL"));
+
+
+ if ((serial = wizardInfo.getCASerialNumber()) != null)
+ mSerialNumberText.setText(serial);
+ else
+ mSerialNumberText.setText(DEFAULT_SERIAL_NUMBER);
+
+ if ((serial = wizardInfo.getRequestNumber()) != null)
+ mbeginRequestNumberText.setText(serial);
+ else
+ mbeginRequestNumberText.setText(DEFAULT_SERIAL_NUMBER);
+
+ if ((serial = wizardInfo.getCAEndSerialNumber()) != null)
+ mEndSerialNumberText.setText(serial);
+
+ if ((serial = wizardInfo.getEndRequestNumber()) != null)
+ mEndRequestNumberText.setText(serial);
+
+ return true;
+ }
+
+ private String hexToDecimal(String hex, boolean isHex)
+ {
+ //String newHex = hex.substring(2);
+ BigInteger bi;
+ if(isHex)
+ bi = new BigInteger(hex, 16);
+ else
+ bi = new BigInteger(hex, 10);
+ return bi.toString();
+ }
+
+ private String DecToHex(String dec)
+ {
+ BigInteger bi;
+ bi = new BigInteger(dec, 10);
+ return bi.toString(16);
+ }
+
+ private boolean validateNumber(JTextField beginNumberField, JTextField endNumberField,String beginText, String endText,boolean isSerialNumber)
+ {
+ BigInteger num = null;
+ BigInteger endNum = null;
+ String serial = null;
+ beginText = beginNumberField.getText().trim();
+ if (beginText != null && !beginText.equals("")) {
+ try {
+ if (beginText.startsWith("0x")) {
+ serial = hexToDecimal(beginText.substring(2),true);
+ } else {
+ serial = beginText;
+ }
+ num = new BigInteger(serial);
+ if (num.compareTo(new BigInteger("0")) < 0) {
+ setErrorMessage("You must specify a positive value.");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ setErrorMessage("You must specify a numeric value.");
+ return false;
+ }
+ if(isSerialNumber)
+ mSerialNumber = DecToHex(serial); // Hex to the server
+ else
+ mbeginRequestNumber = serial;
+ } else {
+ if(isSerialNumber)
+ mSerialNumber = "";
+ else
+ mbeginRequestNumber = "";
+ }
+ endText = endNumberField.getText().trim();
+ if (endText != null && !endText.equals("")) {
+ try {
+ if (endText.startsWith("0x")) {
+ serial = hexToDecimal(endText.substring(2),true);
+ } else {
+ serial = endText;
+ }
+ endNum = new BigInteger(serial);
+ if (endNum.compareTo(new BigInteger("0")) < 0) {
+ setErrorMessage("You must specify a positive value.");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ setErrorMessage("You must specify a numeric value.");
+ return false;
+ }
+ if(isSerialNumber)
+ mEndSerialNumber = DecToHex(serial); // Hex to the Server
+ else
+ mEndRequestNumber = serial;
+ } else {
+ if(isSerialNumber)
+ mEndSerialNumber = "";
+ else
+ mEndRequestNumber = "";
+ }
+
+ if (num != null && endNum != null && num.compareTo(endNum) > 0) {
+ setErrorMessage("Ending number must be greater than starting number.");
+ return false;
+ }
+ return true;
+ }
+ public boolean validatePanel() {
+
+ if(validateNumber(mSerialNumberText,mEndSerialNumberText,mSerialNumber,mEndSerialNumber,true)==false)
+ return false;
+ if(validateNumber(mbeginRequestNumberText,mEndRequestNumberText,mbeginRequestNumber,mEndRequestNumber,false)==false)
+ return false;
+
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (mSerialNumber != null && !mSerialNumber.equals(""))
+ wizardInfo.setCASerialNumber(mSerialNumber);
+ else {
+ wizardInfo.setCASerialNumber(DEFAULT_SERIAL_NUMBER);
+ mSerialNumber = DEFAULT_SERIAL_NUMBER;
+ }
+ if (mbeginRequestNumber != null && !mbeginRequestNumber.equals(""))
+ wizardInfo.setRequestNumber(mbeginRequestNumber);
+ else {
+ wizardInfo.setRequestNumber(DEFAULT_SERIAL_NUMBER);
+ mbeginRequestNumber = DEFAULT_SERIAL_NUMBER;
+ }
+
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_SET_CA_SERIAL;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ if (mSerialNumber != null && !mSerialNumber.equals(""))
+ rawData = rawData+"&"+ConfigConstants.PR_CA_SERIAL_NUMBER+"="+
+ mSerialNumber;
+ if (mEndSerialNumber != null && !mEndSerialNumber.equals(""))
+ rawData = rawData+"&"+ConfigConstants.PR_CA_ENDSERIAL_NUMBER+"="+
+ mEndSerialNumber;
+ if (mbeginRequestNumber != null && !mbeginRequestNumber.equals(""))
+ rawData = rawData+"&"+ConfigConstants.PR_REQUEST_NUMBER+"="+
+ mbeginRequestNumber;
+ if (mEndRequestNumber != null && !mEndSerialNumber.equals(""))
+ rawData = rawData+"&"+ConfigConstants.PR_ENDREQUEST_NUMBER+"="+
+ mEndRequestNumber;
+ if (wizardInfo.getInternalDBPasswd() != null)
+ rawData = rawData+"&"+ConfigConstants.PR_DB_PWD+"="+
+ wizardInfo.getInternalDBPasswd();
+
+ rawData = rawData+"&"+ConfigConstants.PR_SERIAL_REQUEST_NUMBER+"="+
+ ConfigConstants.TRUE;
+ startProgressStatus();
+
+ boolean ready = send(rawData, wizardInfo);
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage(wizardInfo);
+ if (str.equals(""))
+ setErrorMessage("Server Error");
+ else
+ setErrorMessage(str);
+ }else {
+ wizardInfo.setNumberPageDone(ConfigConstants.TRUE);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mDesc = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mDesc, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mSerialNumberLabel = makeJLabel("SERIALNUMBER");
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mSerialNumberLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mSerialNumberText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+// gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mSerialNumberText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEndSerialNumberLabel = makeJLabel("ENDSERIALNUMBER");
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mEndSerialNumberLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEndSerialNumberText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+// gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mEndSerialNumberText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mbeginRequestNumberLabel = makeJLabel("REQUESTNUMBER");
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mbeginRequestNumberLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mbeginRequestNumberText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+// gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mbeginRequestNumberText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEndRequestNumberLabel = makeJLabel("ENDREQUESTNUMBER");
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mEndRequestNumberLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEndRequestNumberText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+// gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mEndRequestNumberText, gbc);
+
+ /*
+ CMSAdminUtil.resetGBC(gbc);
+ mSerialNumberLabel = makeJLabel("PWD");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mSerialNumberLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mSerialNumberText = makeJSerialNumberField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mSerialNumberText, gbc);
+*/
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICATokenLogonPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICATokenLogonPage.java
new file mode 100644
index 000000000..f7068b3d3
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICATokenLogonPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * This panel asks for the information of the current internal database.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICATokenLogonPage extends WITokenLogonPage implements IWizardPanel {
+
+ private static final String HELPINDEX = "install-catoken-logon-wizard-help";
+ private static final String PANELNAME = "CATOKENLOGONWIZARD";
+
+ WICATokenLogonPage(JDialog dialog) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = dialog;
+ }
+
+ WICATokenLogonPage(JDialog dialog, JFrame adminFrame) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = dialog;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String tokenname = wizardInfo.getCATokenName();
+ String pwd = (String)wizardInfo.get("TOKEN:"+tokenname);
+ if (wizardInfo.isCloning() && wizardInfo.isCACloningDone()) {
+ if (pwd != null && !pwd.equals(""))
+ return false;
+ }
+
+ if (wizardInfo.isCACertLocalCA() || !wizardInfo.isInstallCertNow()
+ || !wizardInfo.isCAInstalled() || wizardInfo.isMigrationEnable()
+ || wizardInfo.isCACertInstalledDone())
+ return false;
+ if (pwd != null)
+ return false;
+
+ mTokenName = tokenname;
+ mTokenText.setText(tokenname);
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICertDNPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICertDNPage.java
new file mode 100644
index 000000000..cf7e623ad
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICertDNPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.management.client.console.*;
+import com.netscape.admin.certsrv.task.*;
+
+/**
+ * Specify Subject DN for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICertDNPage extends WBaseDNPage {
+ protected String mSubjectName;
+ protected String mHelpIndex;
+ protected static final String CA_CN = "CN=Certificate Manager";
+ protected static final String CA_C = "C=US";
+ protected static final String RA_CN = "CN=Registration Manager";
+ protected static final String RA_C = "C=US";
+ protected static final String OCSP_CN = "CN=Online Certificate Status Manager";
+ protected static final String OCSP_C = "C=US";
+ protected static final String KRA_CN = "CN=Data Recovery Manager";
+ protected static final String KRA_C = "C=US";
+ protected static final String SERVER_C = "C=US";
+ protected String mStr;
+
+ WICertDNPage(String panelName) {
+ super(panelName);
+ mPanelName = panelName;
+ init();
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ setBorder(makeTitledBorder(mPanelName));
+/*
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String str = wizardInfo.getSubjectName();
+
+ populateDN(str);
+*/
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return super.validatePanel();
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String str1 = mSubjectDNText.getText().trim();
+ String str2 = mSubjectStringText.getText().trim();
+ String str = "";
+
+ if (mDNComponents.isSelected()) {
+ str = str1;
+ } else {
+ str = str2;
+ }
+
+ if (str.equals("")) {
+ setErrorMessage("BLANKFIELD");
+ return false;
+ //str = dnDesc.getText().trim();
+ }
+
+ mStr = CMSAdminUtil.getPureString(str);
+
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_CHECK_DN;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ rawData = rawData+"&"+ConfigConstants.PR_CERTIFICATE_TYPE+"="+ wizardInfo.getCertType();
+ rawData = rawData+"&"+ConfigConstants.PR_SUBJECT_NAME+"="+mStr;
+
+ startProgressStatus();
+ boolean ready = send(rawData, wizardInfo);
+ endProgressStatus();
+
+ wizardInfo.setSubjectName(mStr);
+
+ if (!ready) {
+ String errstr = getErrorMessage();
+ if (errstr.equals("")) {
+ String errorMsg = mResource.getString(
+ mPanelName+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(errstr);
+ }
+
+/*
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ AdminConnection connection = wizardInfo.getAdminConnection();
+ NameValuePairs nvps = new NameValuePairs();
+
+ nvps.add(Constants.PR_SUBJECT_NAME, str);
+ wizardInfo.addEntry(Constants.PR_SUBJECT_NAME, str);
+
+ try {
+ connection.validate(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_SUBJECT_NAME, nvps);
+ } catch (EAdminException e) {
+ //showErrorDialog(e.toString());
+ setErrorMessage(e.toString());
+ return false;
+ }
+
+ nvps.add(Constants.PR_TOKEN_NAME, wizardInfo.getTokenName());
+ if (wizardInfo.isNewKey()) {
+ nvps.add(Constants.PR_KEY_LENGTH, wizardInfo.getKeyLength());
+ nvps.add(Constants.PR_KEY_TYPE, wizardInfo.getKeyType());
+ }
+
+ wizardInfo.addEntry(wizardInfo.ALL_INFO, nvps);
+*/
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(mHelpIndex);
+ }
+
+ protected void init() {
+ super.init();
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICertExtensionPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICertExtensionPage.java
new file mode 100644
index 000000000..8c989685a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICertExtensionPage.java
@@ -0,0 +1,168 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * Certificate Extension for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICertExtensionPage extends WBaseCertExtensionPage implements
+ IWizardPanel {
+ protected String mHelpIndex;
+
+ WICertExtensionPage(String panelName) {
+ super(panelName);
+ mPanelName = panelName;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ setBorder(makeTitledBorder(mPanelName));
+ return super.initializePanel(info);
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ boolean ready = false;
+
+ String rawData = "";
+ if (mMIMECheckBox.isSelected()) {
+ //Check the extension if it is valid
+ rawData = ConfigConstants.TASKID+"="+TaskId.TASK_CHECK_EXTENSION;
+ rawData = rawData+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ rawData = rawData+ConfigConstants.PR_CERTIFICATE_EXTENSION+"="+
+ mMIMEText.getText().trim();
+
+ startProgressStatus();
+ ready = send(rawData, wizardInfo);
+ endProgressStatus();
+ if (!ready) {
+ String str = getErrorMessage();
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ mPanelName+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ }
+ } else
+ ready = true;
+
+ if (ready) {
+ NameValuePairs nvps = new NameValuePairs();
+
+ nvps.put(Constants.PR_CERTIFICATE_TYPE, wizardInfo.getCertType());
+ nvps.put(Constants.PR_SUBJECT_NAME, wizardInfo.getSubjectName());
+ nvps.put(Constants.PR_TOKEN_NAME, wizardInfo.getTokenName());
+ nvps.put(Constants.PR_KEY_LENGTH, wizardInfo.getKeyLength());
+ nvps.put(Constants.PR_KEY_TYPE, wizardInfo.getKeyType());
+ nvps.put(Constants.PR_KEY_CURVENAME, wizardInfo.getKeyCurveName());
+ addValidityPeriod(wizardInfo, nvps);
+
+ if (mBasicCheckBox.isSelected())
+ addBasicConstraints(nvps);
+
+ if (mExtendedKeyCheckBox.isSelected())
+ addExtendedKey(nvps);
+
+ if (mAKICheckBox.isSelected())
+ nvps.put(Constants.PR_AKI, Constants.TRUE);
+
+ if (mSKICheckBox.isSelected())
+ nvps.put(Constants.PR_SKI, Constants.TRUE);
+
+ if (mKeyUsageBox.isSelected())
+ nvps.put(Constants.PR_KEY_USAGE, Constants.TRUE);
+
+ if (mMIMECheckBox.isSelected())
+ nvps.put(Constants.PR_DER_EXTENSION, mMIMEText.getText().trim());
+
+ wizardInfo.put(wizardInfo.ALL_CERT_INFO, nvps);
+ }
+
+ mModified = true;
+ return ready;
+ }
+
+ private void addValidityPeriod(InstallWizardInfo wizardInfo,
+ NameValuePairs nvps) {
+ nvps.put(Constants.PR_BEGIN_YEAR, wizardInfo.getBeginYear());
+ nvps.put(Constants.PR_BEGIN_MONTH, wizardInfo.getBeginMonth());
+ nvps.put(Constants.PR_BEGIN_DATE, wizardInfo.getBeginDate());
+ nvps.put(Constants.PR_BEGIN_HOUR, wizardInfo.getBeginHour());
+ nvps.put(Constants.PR_BEGIN_MIN, wizardInfo.getBeginMin());
+ nvps.put(Constants.PR_BEGIN_SEC, wizardInfo.getBeginSec());
+ nvps.put(Constants.PR_AFTER_YEAR, wizardInfo.getAfterYear());
+ nvps.put(Constants.PR_AFTER_MONTH, wizardInfo.getAfterMonth());
+ nvps.put(Constants.PR_AFTER_DATE, wizardInfo.getAfterDate());
+ nvps.put(Constants.PR_AFTER_HOUR, wizardInfo.getAfterHour());
+ nvps.put(Constants.PR_AFTER_MIN, wizardInfo.getAfterMin());
+ nvps.put(Constants.PR_AFTER_SEC, wizardInfo.getAfterSec());
+ }
+
+ private void addBasicConstraints(NameValuePairs nvps) {
+ if (mCACheckBox.isSelected())
+ nvps.put(Constants.PR_IS_CA, Constants.TRUE);
+
+ if (mCertPathBox.isSelected()) {
+ String certLen = mCertPathText.getText().trim();
+ if (!certLen.equals(""))
+ nvps.put(Constants.PR_CERT_LEN, certLen);
+ } else {
+ // negative number means infinity
+ nvps.put(Constants.PR_CERT_LEN, "-1");
+ }
+ }
+
+ private void addExtendedKey(NameValuePairs nvps) {
+ if (mSSLClient.isSelected())
+ nvps.put(Constants.PR_SSL_CLIENT_BIT, Constants.TRUE);
+ if (mSSLServer.isSelected())
+ nvps.put(Constants.PR_SSL_SERVER_BIT, Constants.TRUE);
+ if (mSSLMail.isSelected())
+ nvps.put(Constants.PR_SSL_MAIL_BIT, Constants.TRUE);
+ if (mObjectSigning.isSelected())
+ nvps.put(Constants.PR_OBJECT_SIGNING_BIT, Constants.TRUE);
+ if (mTimeStamping.isSelected())
+ nvps.put(Constants.PR_TIMESTAMPING_BIT, Constants.TRUE);
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(mHelpIndex);
+ }
+
+ protected void init() {
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICertRequestPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICertRequestPage.java
new file mode 100644
index 000000000..d4926e1e9
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICertRequestPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * Introduction page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICertRequestPage extends WBaseCertRequestPage implements IWizardPanel {
+ private JButton mCopy;
+ private JTextArea mText;
+ private static final String PANELNAME = "CERTREQUESTWIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WICertRequestPage() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICertSetupStatusPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICertSetupStatusPage.java
new file mode 100644
index 000000000..ff9ca97a6
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICertSetupStatusPage.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.admin.certsrv.config.install;
+
+import java.util.Hashtable;
+import java.net.URL;
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.awt.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.wizard.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.management.client.console.ConsoleInfo;
+import com.netscape.management.client.util.*;
+import com.netscape.management.client.comm.*;
+import com.netscape.management.client.*;
+
+/**
+ * Status page for the configuration of the certificate server.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICertSetupStatusPage extends WizardBasePanel implements IWizardPanel {
+ private JTextArea desc;
+ private static final String PANELNAME = "INSTALLCONFIGSTATUSWIZARD";
+ private static final String HELPINDEX = "install-certsetup-status-wizard-help";
+
+ WICertSetupStatusPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WICertSetupStatusPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return true;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String str = "";
+ if (wizardInfo.isCAInstalled()) {
+
+ String str1 = "";
+ // display status
+ str = mResource.getString(
+ "INSTALLCONFIGSTATUSWIZARD_CATEXT_DESC_LABEL");
+ if (wizardInfo.isKRAInstalled())
+ str1 = mResource.getString(
+ "INSTALLCONFIGSTATUSWIZARD_CAKRATEXT_DESC_LABEL");
+ String link = "https://"+wizardInfo.getMachineName()+":"+
+ wizardInfo.getAdminPort() + "/ca/adminEnroll.html";
+ desc.setText(str+"\n"+link+"\n\n"+str1);
+ } else if (wizardInfo.isOCSPInstalled()) {
+ desc.setText(mResource.getString(
+ "INSTALLCONFIGSTATUSWIZARD_OCSPTEXT_DESC_LABEL"));
+ } else if (wizardInfo.isRAInstalled()) {
+ if (wizardInfo.isKRAInstalled())
+ desc.setText(mResource.getString(
+ "INSTALLCONFIGSTATUSWIZARD_RAKRATEXT_DESC_LABEL"));
+ else
+ desc.setText(mResource.getString(
+ "INSTALLCONFIGSTATUSWIZARD_RATEXT_DESC_LABEL"));
+ } else if (wizardInfo.isKRAInstalled()) {
+ desc.setText(mResource.getString(
+ "INSTALLCONFIGSTATUSWIZARD_KRATEXT_DESC_LABEL"));
+ }
+ else if (wizardInfo.isTKSInstalled()) {
+ desc.setText(mResource.getString(
+ "INSTALLCONFIGSTATUSWIZARD_TKSTEXT_DESC_LABEL"));
+ }
+ setBorder(makeTitledBorder(PANELNAME));
+
+ CMSAdmin admin = (CMSAdmin)wizardInfo.get("CMSAdmin");
+ IPage viewInstance = (IPage)wizardInfo.get("viewInstance");
+ if (viewInstance != null)
+ admin.updateMenu(viewInstance);
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+/*
+ desc = new JTextArea("", 4, 80);
+ desc.setBackground(getBackground());
+ desc.setEditable(false);
+ desc.setCaretColor(getBackground());
+*/
+ desc = createTextArea("");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ add(desc, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICertSubmitPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICertSubmitPage.java
new file mode 100644
index 000000000..18beac219
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICertSubmitPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * Introduction page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICertSubmitPage extends WizardBasePanel implements IWizardPanel {
+ protected JRadioButton mSelfButton;
+ protected JRadioButton mSubordinateButton;
+ protected JTextArea mLabel;
+ protected String mHelpIndex;
+ private String mPanelName;
+ protected InstallWizardInfo mWizardInfo;
+
+ WICertSubmitPage(String panelName) {
+ super(panelName);
+ mPanelName = panelName;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ setBorder(makeTitledBorder(mPanelName));
+ mWizardInfo = (InstallWizardInfo)info;
+ if (!mWizardInfo.getCertType().equals(Constants.PR_CA_SIGNING_CERT)) {
+ if (mWizardInfo.isCACertRequestDone() &&
+ !mWizardInfo.isCACertInstalledDone()) {
+ mSubordinateButton.setSelected(true);
+ mSelfButton.setSelected(false);
+ }
+ }
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(mHelpIndex);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mLabel = createTextArea(mResource.getString(
+ mPanelName+"_TEXT_HEADING_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mLabel, gbc);
+
+ mSelfButton = makeJRadioButton("SELF", true);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mSelfButton, gbc);
+
+ mSubordinateButton = makeJRadioButton("SUB", false);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mSubordinateButton, gbc);
+
+ ButtonGroup buttonGroup = new ButtonGroup();
+ buttonGroup.add(mSelfButton);
+ buttonGroup.add(mSubordinateButton);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (!mWizardInfo.getCertType().equals(Constants.PR_CA_SIGNING_CERT)) {
+ if (e.getSource().equals(mSelfButton)) {
+ if (mWizardInfo.isCACertRequestDone() &&
+ !mWizardInfo.isCACertInstalledDone()) {
+ String errorMsg = mResource.getString(mPanelName+"_LABEL_INCOMPLETE_LABEL");
+ JOptionPane.showMessageDialog(mParent, errorMsg, "Warning",
+ JOptionPane.WARNING_MESSAGE,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_WARN_ICON));
+ mSelfButton.setSelected(false);
+ mSubordinateButton.setSelected(true);
+ }
+ }
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICertValidityPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICertValidityPage.java
new file mode 100644
index 000000000..8f2acd493
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICertValidityPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import java.text.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * Validity page for installation wizard
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICertValidityPage extends WBaseValidityPage implements IWizardPanel {
+ private String mPanelName;
+ protected String mHelpIndex;
+
+ WICertValidityPage(String panelName) {
+ super(panelName);
+ mPanelName = panelName;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ setBorder(makeTitledBorder(mPanelName));
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(mHelpIndex);
+ }
+
+ protected void init() {
+ super.init();
+ }
+
+ public boolean validatePanel() {
+ boolean status = super.validatePanel();
+ Date currTime = new Date();
+
+ if (status) {
+ if (currTime.before(mBeforeDate)) {
+ if (!mWarningDisplayed) {
+ setErrorMessage("INVALIDCERT");
+ mWarningDisplayed = true;
+ return false;
+ }
+ }
+ }
+
+ return status;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (!wizardInfo.getCertType().equals(Constants.PR_CA_SIGNING_CERT)) {
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_VALIDITY_PERIOD;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ rawData = rawData+"&"+ConfigConstants.PR_NOTAFTER+"="+mAfterDate.getTime();
+ startProgressStatus();
+ boolean ready = send(rawData, wizardInfo);
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage(wizardInfo);
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ mPanelName+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else if (str.equals("beyondCAValidity")) {
+ String errormsg = mResource.getString(mPanelName+"_BEYONDCAVALIDITY");
+ int status = JOptionPane.showConfirmDialog(mAdminFrame, errormsg, "Information",
+ JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_INFO_ICON));
+ if (status == JOptionPane.OK_OPTION) {
+ rawData = rawData+"&"+ConfigConstants.OVERRIDE_VALIDITY+"="+ConfigConstants.TRUE;
+ ready = send(rawData, wizardInfo);
+ return true;
+ } else {
+ setErrorMessage(mResource.getString(mPanelName+"_ERROR1"));
+ return false;
+ }
+ } else
+ setErrorMessage(str);
+ return ready;
+ }
+ }
+
+ return super.concludePanel(info);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ wizardInfo.addEntry(Constants.PR_BEGIN_YEAR, mBYear.getText().trim());
+ int beforeMonth = Integer.parseInt(mBMonth.getText().trim());
+ wizardInfo.addEntry(Constants.PR_BEGIN_MONTH, ""+(beforeMonth-1));
+ wizardInfo.addEntry(Constants.PR_BEGIN_DATE, mBDay.getText().trim());
+ wizardInfo.addEntry(Constants.PR_BEGIN_HOUR, mBHour.getText().trim());
+ wizardInfo.addEntry(Constants.PR_BEGIN_MIN, mBMin.getText().trim());
+ wizardInfo.addEntry(Constants.PR_BEGIN_SEC, mBSec.getText().trim());
+ wizardInfo.addEntry(Constants.PR_AFTER_YEAR, mEYear.getText().trim());
+ int afterMonth = Integer.parseInt(mEMonth.getText().trim());
+ wizardInfo.addEntry(Constants.PR_AFTER_MONTH, ""+(afterMonth-1));
+ wizardInfo.addEntry(Constants.PR_AFTER_DATE, mEDay.getText().trim());
+ wizardInfo.addEntry(Constants.PR_AFTER_HOUR, mEHour.getText().trim());
+ wizardInfo.addEntry(Constants.PR_AFTER_MIN, mEMin.getText().trim());
+ wizardInfo.addEntry(Constants.PR_AFTER_SEC, mESec.getText().trim());
+ //wizardInfo.addEntry(Constants.PR_VALIDITY_PERIOD, ""+period);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICloneCAKeyCertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICloneCAKeyCertPage.java
new file mode 100644
index 000000000..d5722df32
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICloneCAKeyCertPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * Introduction page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICloneCAKeyCertPage extends WizardBasePanel implements IWizardPanel {
+ private String mCANicknameStr, mSSLNicknameStr, mOCSPNicknameStr;
+ private String mCATokenname, mOCSPTokenname, mSSLTokenname;
+ protected InstallWizardInfo mWizardInfo;
+ protected JComboBox mCANicknameBox, mOCSPNicknameBox, mSSLNicknameBox;
+ private static final String PANELNAME = "CLONECAKEYCERTWIZARD";
+ private static final String CAHELPINDEX =
+ "install-cacertclone-wizard-help";
+
+
+ WICloneCAKeyCertPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ mCANicknameStr = "caSigningCert";
+ mSSLNicknameStr = "Server-Cert";
+ mOCSPNicknameStr = "ocspSigningCert";
+ init();
+ }
+
+ WICloneCAKeyCertPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ mCANicknameStr = "caSigningCert";
+ mSSLNicknameStr = "Server-Cert";
+ mOCSPNicknameStr = "ocspSigningCert";
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ mWizardInfo = wizardInfo;
+ if (!wizardInfo.isCloning())
+ return false;
+ if (!wizardInfo.isCloneCASubsystem())
+ return false;
+ if (wizardInfo.isCACloningDone())
+ return false;
+ if (!wizardInfo.isCAInstalled() || wizardInfo.isMigrationEnable()
+ || wizardInfo.isSelfSignedCACertDone()
+ || wizardInfo.isCACertRequestDone())
+ return false;
+
+ setBorder(makeTitledBorder(PANELNAME));
+ if (mCANicknameBox.getItemCount() > 0) {
+ mCANicknameBox.removeAllItems();
+ }
+
+ if (mOCSPNicknameBox.getItemCount() > 0) {
+ mOCSPNicknameBox.removeAllItems();
+ }
+
+ if (mSSLNicknameBox.getItemCount() > 0) {
+ mSSLNicknameBox.removeAllItems();
+ }
+ String certsList = mWizardInfo.getCloneCertsList();
+ StringTokenizer t1 = new StringTokenizer(certsList, ";");
+ while (t1.hasMoreTokens()) {
+ String s1 = (String)t1.nextToken();
+ if (s1.indexOf(mCANicknameStr) >= 0)
+ mCANicknameBox.addItem(s1);
+ }
+
+ StringTokenizer t2 = new StringTokenizer(certsList, ";");
+ while (t2.hasMoreTokens()) {
+ String s1 = (String)t2.nextToken();
+ if (s1.indexOf(mSSLNicknameStr) >= 0)
+ mSSLNicknameBox.addItem(s1);
+ }
+
+ StringTokenizer t3 = new StringTokenizer(certsList, ";");
+ while (t3.hasMoreTokens()) {
+ String s1 = (String)t3.nextToken();
+ if (s1.indexOf(mOCSPNicknameStr) >= 0)
+ mOCSPNicknameBox.addItem(s1);
+ }
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ String canickname = (String)mCANicknameBox.getSelectedItem();
+ mCATokenname = Constants.PR_INTERNAL_TOKEN_NAME;
+ int index = canickname.indexOf(":");
+ if (index > -1) {
+ mCATokenname = canickname.substring(0, index);
+ }
+ mWizardInfo.put(ConfigConstants.PR_CLONE_CA_TOKEN_NAME, mCATokenname);
+
+ String ocspnickname = (String)mOCSPNicknameBox.getSelectedItem();
+ mOCSPTokenname = Constants.PR_INTERNAL_TOKEN_NAME;
+ index = ocspnickname.indexOf(":");
+ if (index > -1) {
+ mOCSPTokenname = ocspnickname.substring(0, index);
+ }
+ mWizardInfo.put(ConfigConstants.PR_CLONE_OCSP_TOKEN_NAME, mOCSPTokenname);
+
+ String sslnickname = (String)mSSLNicknameBox.getSelectedItem();
+ mSSLTokenname = Constants.PR_INTERNAL_TOKEN_NAME;
+ index = sslnickname.indexOf(":");
+ if (index > -1) {
+ mSSLTokenname = sslnickname.substring(0, index);
+ }
+ mWizardInfo.put(ConfigConstants.PR_CLONE_SSL_TOKEN_NAME, mSSLTokenname);
+
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_CLONING;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ rawData = rawData+"&"+ConfigConstants.PR_SUBSYSTEM+"="+ConfigConstants.PR_CA;
+ rawData = rawData+"&"+ConfigConstants.PR_CLONE_CA_TOKEN_NAME+"="+
+ mCATokenname;
+ rawData = rawData+"&"+ConfigConstants.PR_CLONE_CA_NICKNAME+"="+
+ mCANicknameBox.getSelectedItem();
+ rawData = rawData+"&"+ConfigConstants.PR_CLONE_OCSP_TOKEN_NAME+"="+
+ mOCSPTokenname;
+ rawData = rawData+"&"+ConfigConstants.PR_CLONE_OCSP_NICKNAME+"="+
+ mOCSPNicknameBox.getSelectedItem();
+ rawData = rawData+"&"+ConfigConstants.PR_CLONE_SSL_TOKEN_NAME+"="+
+ mSSLTokenname;
+ rawData = rawData+"&"+ConfigConstants.PR_CLONE_SSL_NICKNAME+"="+
+ mSSLNicknameBox.getSelectedItem();
+
+ startProgressStatus();
+ boolean ready = send(rawData, wizardInfo);
+ endProgressStatus();
+
+ if (!ready) {
+ String errstr = getErrorMessage(wizardInfo);
+ if (errstr.equals("")) {
+ String errorMsg = mResource.getString(
+ PANELNAME+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(errstr);
+ }
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(CAHELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea heading = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(heading, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel caNicknameLbl = makeJLabel("CANICKNAME");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(caNicknameLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mCANicknameBox = new JComboBox();
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.weightx = 0.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mCANicknameBox, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea heading1 = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING1_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(heading1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel ocspNicknameLbl = makeJLabel("OCSPNICKNAME");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(ocspNicknameLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mOCSPNicknameBox = new JComboBox();
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.weightx = 0.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mOCSPNicknameBox, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea heading2 = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING2_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(heading2, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel sslNicknameLbl = makeJLabel("SSLNICKNAME");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(sslNicknameLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mSSLNicknameBox = new JComboBox();
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.weightx = 0.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mSSLNicknameBox, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ mWizardInfo.setCATokenName(mCATokenname);
+ mWizardInfo.setOCSPTokenName(mOCSPTokenname);
+ mWizardInfo.setSSLTokenName(mSSLTokenname);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICloneKRAKeyCertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICloneKRAKeyCertPage.java
new file mode 100644
index 000000000..bea79b2e0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICloneKRAKeyCertPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * Introduction page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICloneKRAKeyCertPage extends WizardBasePanel implements IWizardPanel {
+ private String mKRANicknameStr, mStorageNicknameStr, mSSLNicknameStr;
+ private String mKRATokenname, mStorageTokenname, mSSLTokenname;
+ protected InstallWizardInfo mWizardInfo;
+ protected JComboBox mKRANicknameBox, mStorageNicknameBox, mSSLNicknameBox;
+ private static final String PANELNAME = "CLONEKRAKEYCERTWIZARD";
+ private static final String KRAHELPINDEX =
+ "install-kracertclone-wizard-help";
+
+
+ WICloneKRAKeyCertPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ mKRANicknameStr = "kraTransportCert";
+ mSSLNicknameStr = "Server-Cert";
+ mStorageNicknameStr = "kraStorageCert";
+ init();
+ }
+
+ WICloneKRAKeyCertPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ mKRANicknameStr = "kraTransportCert";
+ mSSLNicknameStr = "Server-Cert";
+ mStorageNicknameStr = "kraStorageCert";
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ mWizardInfo = wizardInfo;
+ if (!wizardInfo.isCloning())
+ return false;
+ if (!wizardInfo.isCloneKRASubsystem())
+ return false;
+ if (wizardInfo.isKRACloningDone())
+ return false;
+
+ if (!wizardInfo.isKRAInstalled() ||
+ wizardInfo.isKRACertRequestDone()) {
+ return false;
+ }
+
+ setBorder(makeTitledBorder(PANELNAME));
+ if (mKRANicknameBox.getItemCount() > 0) {
+ mKRANicknameBox.removeAllItems();
+ }
+
+ if (mStorageNicknameBox.getItemCount() > 0) {
+ mStorageNicknameBox.removeAllItems();
+ }
+
+ if (mSSLNicknameBox.getItemCount() > 0) {
+ mSSLNicknameBox.removeAllItems();
+ }
+ String certsList = mWizardInfo.getCloneCertsList();
+ StringTokenizer t1 = new StringTokenizer(certsList, ";");
+ while (t1.hasMoreTokens()) {
+ String s1 = (String)t1.nextToken();
+ if (s1.indexOf(mStorageNicknameStr) >= 0)
+ mStorageNicknameBox.addItem(s1);
+ }
+
+ StringTokenizer t2 = new StringTokenizer(certsList, ";");
+ while (t2.hasMoreTokens()) {
+ String s1 = (String)t2.nextToken();
+ if (s1.indexOf(mSSLNicknameStr) >= 0)
+ mSSLNicknameBox.addItem(s1);
+ }
+
+ StringTokenizer t3 = new StringTokenizer(certsList, ";");
+ while (t3.hasMoreTokens()) {
+ String s1 = (String)t3.nextToken();
+ if (s1.indexOf(mKRANicknameStr) >= 0)
+ mKRANicknameBox.addItem(s1);
+ }
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ String kranickname = (String)mKRANicknameBox.getSelectedItem();
+ mKRATokenname = Constants.PR_INTERNAL_TOKEN_NAME;
+ int index = kranickname.indexOf(":");
+ if (index > -1) {
+ mKRATokenname = kranickname.substring(0, index);
+ }
+ mWizardInfo.put(ConfigConstants.PR_CLONE_KRA_TOKEN_NAME, mKRATokenname);
+
+ String storagenickname = (String)mStorageNicknameBox.getSelectedItem();
+ mStorageTokenname = Constants.PR_INTERNAL_TOKEN_NAME;
+ index = storagenickname.indexOf(":");
+ if (index > -1) {
+ mStorageTokenname = storagenickname.substring(0, index);
+ }
+ mWizardInfo.put(ConfigConstants.PR_CLONE_STORAGE_TOKEN_NAME, mStorageTokenname);
+
+ String sslnickname = (String)mSSLNicknameBox.getSelectedItem();
+ mSSLTokenname = Constants.PR_INTERNAL_TOKEN_NAME;
+ index = sslnickname.indexOf(":");
+ if (index > -1) {
+ mSSLTokenname = sslnickname.substring(0, index);
+ }
+ mWizardInfo.put(ConfigConstants.PR_CLONE_SSL_TOKEN_NAME, mSSLTokenname);
+
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_CLONING;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ rawData = rawData+"&"+ConfigConstants.PR_SUBSYSTEM+"="+ConfigConstants.PR_KRA;
+ rawData = rawData+"&"+ConfigConstants.PR_CLONE_KRA_TOKEN_NAME+"="+
+ mKRATokenname;
+ rawData = rawData+"&"+ConfigConstants.PR_CLONE_KRA_NICKNAME+"="+
+ mKRANicknameBox.getSelectedItem();
+ rawData = rawData+"&"+ConfigConstants.PR_CLONE_STORAGE_TOKEN_NAME+"="+
+ mStorageTokenname;
+ rawData = rawData+"&"+ConfigConstants.PR_CLONE_STORAGE_NICKNAME+"="+
+ mStorageNicknameBox.getSelectedItem();
+ rawData = rawData+"&"+ConfigConstants.PR_CLONE_SSL_TOKEN_NAME+"="+
+ mSSLTokenname;
+ rawData = rawData+"&"+ConfigConstants.PR_CLONE_SSL_NICKNAME+"="+
+ mSSLNicknameBox.getSelectedItem();
+
+ startProgressStatus();
+ boolean ready = send(rawData, wizardInfo);
+ endProgressStatus();
+
+ if (!ready) {
+ String errstr = getErrorMessage();
+ if (errstr.equals("")) {
+ String errorMsg = mResource.getString(
+ PANELNAME+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(errstr);
+ }
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(KRAHELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea heading = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(heading, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel kraNicknameLbl = makeJLabel("KRANICKNAME");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(kraNicknameLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mKRANicknameBox = new JComboBox();
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.weightx = 0.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mKRANicknameBox, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea heading1 = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING1_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(heading1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel storageNicknameLbl = makeJLabel("STORAGENICKNAME");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(storageNicknameLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mStorageNicknameBox = new JComboBox();
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.weightx = 0.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mStorageNicknameBox, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea heading2 = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING2_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(heading2, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel sslNicknameLbl = makeJLabel("SSLNICKNAME");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(sslNicknameLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mSSLNicknameBox = new JComboBox();
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.weightx = 0.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mSSLNicknameBox, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ mWizardInfo.setKRATokenName(mKRATokenname);
+ mWizardInfo.setSSLTokenName(mSSLTokenname);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICloneMasterPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICloneMasterPage.java
new file mode 100644
index 000000000..c8498f306
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICloneMasterPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+import javax.swing.*;
+import java.awt.*;
+import java.util.*;
+import java.awt.event.*;
+
+/**
+ * Clone CA getting Clone Master connector info.
+ *
+ * @author Christina Fu
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+
+class WICloneMasterPage extends WizardBasePanel implements IWizardPanel {
+ protected JTextField mHostText, mPortText, mPortEEText, mTimeoutText;
+ protected JLabel mHostLbl, mPortLbl, mPortEELbl, mTimeoutLbl, mTimeunitLbl;
+ protected JRadioButton mYes, mNo;
+ protected String mHost, mPort, mPortEE, mTimeout;
+ protected JTextArea mHeading;
+ protected Color mActiveColor;
+ public static final int MAX_PORT = 65535;
+ public static final int MIN_PORT = 1;
+ private static final String PANELNAME = "CLONEMASTERWIZARD";
+ private static final String HELPINDEX1 = "install-ca-clone-master-wizard-help";
+
+ private InstallWizardInfo mWizardInfo;
+
+ WICloneMasterPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WICloneMasterPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ mWizardInfo = wizardInfo;
+ Debug.println("WICloneMasterPage: initializing");
+
+ if (wizardInfo.isCloneMasterDone())
+ return false;
+
+ if (wizardInfo.isCloning()) {
+ Debug.println("WICloneMasterPage: is cloning");
+ setBorder(makeTitledBorder(PANELNAME));
+ if (mYes.isSelected())
+ enableFields(true, mActiveColor);
+ else
+ enableFields(false, getBackground());
+ return true;
+ }
+ return false;
+ }
+
+ public boolean validatePanel() {
+ if (mNo.isSelected()) {
+ mHost = "";
+ mPort = "";
+ mPortEE = "";
+ mTimeout = "";
+ return true;
+ }
+
+ mHost = mHostText.getText().trim();
+ mPort = mPortText.getText().trim();
+ mPortEE = mPortEEText.getText().trim();
+ mTimeout = mTimeoutText.getText().trim();
+ if (mHost.equals("")) {
+ setErrorMessage("BLANKHOST");
+ return false;
+ }
+ if (mPort.equals("")) {
+ setErrorMessage("BLANKPORT");
+ return false;
+ }
+ if (mPortEE.equals("")) {
+ setErrorMessage("BLANKPORT");
+ return false;
+ }
+ if (mTimeout.equals("")) {
+ setErrorMessage("BLANKTIMEOUT");
+ return false;
+ }
+
+ try {
+ int portnumber = Integer.parseInt(mPort);
+ if (portnumber < MIN_PORT || portnumber > MAX_PORT) {
+ setErrorMessage("OUTOFRANGE");
+ return false;
+ }
+ int portnumberEE = Integer.parseInt(mPortEE);
+ if (portnumberEE < MIN_PORT || portnumberEE > MAX_PORT) {
+ setErrorMessage("OUTOFRANGE");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ setErrorMessage("INVALIDPORT");
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ Debug.println("WICloneMasterPage: in concludePanel");
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ wizardInfo.setCLAHost(mHost);
+ wizardInfo.setCLAPort(mPort);
+ wizardInfo.setCLAPortEE(mPortEE);
+ wizardInfo.setCLATimeout(mTimeout);
+ ConsoleInfo consoleInfo = wizardInfo.getAdminConsoleInfo();
+ CMSConfigCert configCertCgi = new CMSConfigCert();
+ configCertCgi.initialize(wizardInfo);
+ Hashtable data = new Hashtable();
+ data.put(ConfigConstants.TASKID,TaskId.TASK_CLONE_MASTER);
+ data.put(ConfigConstants.OPTYPE, OpDef.OP_MODIFY);
+ data.put(ConfigConstants.PR_CERT_INSTANCE_NAME,
+ consoleInfo.get(ConfigConstants.PR_CERT_INSTANCE_NAME));
+ data.put(ConfigConstants.PR_DB_BINDDN, wizardInfo.getDBBindDN());
+ data.put(ConfigConstants.PR_DB_PWD, wizardInfo.getInternalDBPasswd());
+ data.put(ConfigConstants.PR_CLONING_INSTANCE,
+ wizardInfo.get(ConfigConstants.PR_CLONING_INSTANCE));
+
+ if (wizardInfo.isCAInstalled())
+ data.put(ConfigConstants.PR_CA, ConfigConstants.TRUE);
+ else
+ data.put(ConfigConstants.PR_CA, ConfigConstants.FALSE);
+
+ if (wizardInfo.isRAInstalled())
+ data.put(ConfigConstants.PR_RA, ConfigConstants.TRUE);
+ else
+ data.put(ConfigConstants.PR_RA, ConfigConstants.FALSE);
+
+ if (wizardInfo.isKRAInstalled())
+ data.put(ConfigConstants.PR_KRA, ConfigConstants.TRUE);
+ else
+ data.put(ConfigConstants.PR_KRA, ConfigConstants.FALSE);
+
+ String services = "";
+ if (wizardInfo.isCAInstalled()) {
+ if (!services.equals(""))
+ services = services+":";
+ services=services+ConfigConstants.PR_CA;
+ } else {
+ data.put(ConfigConstants.CA_HOST, wizardInfo.getCMHost());
+ data.put(ConfigConstants.CA_PORT, wizardInfo.getCMPort());
+ data.put(ConfigConstants.CA_TIMEOUT, wizardInfo.getCMTimeout());
+ }
+
+ if (wizardInfo.isRAInstalled()) {
+ if (!services.equals(""))
+ services = services+":";
+ services=services+ConfigConstants.PR_RA;
+ }
+ if (wizardInfo.isKRAInstalled()) {
+ if (!services.equals(""))
+ services = services+":";
+ services=services+ConfigConstants.PR_KRA;
+ } else {
+ // connect to the clone master (CLA)
+ Debug.println("WICloneMasterPage: Cloning page");
+ if (mYes.isSelected()) {
+ Debug.println("WICloneMasterPage: Cloning page yes selected");
+ data.put(ConfigConstants.CLA_HOST, wizardInfo.getCLAHost());
+ data.put(ConfigConstants.CLA_PORT, wizardInfo.getCLAPort());
+ data.put(ConfigConstants.CLA_PORT_EE, wizardInfo.getCLAPortEE());
+ data.put(ConfigConstants.CLA_TIMEOUT,
+ wizardInfo.getCLATimeout());
+ data.put(ConfigConstants.CLONE_CA, ConfigConstants.TRUE);
+ } else {
+ Debug.println("WICloneMasterPage: Cloning page yes NOT selected");
+ // admin will have to manually add if not through wizard
+ }
+ }
+
+ data.put(ConfigConstants.PR_SUBSYSTEMS, services);
+ wizardInfo.setSubsystems(services);
+ startProgressStatus();
+ CMSMessageBox dlg = new CMSMessageBox(mAdminFrame, "CGITASK", "CONFIGDB");
+ boolean ready = configCertCgi.configCert(data);
+ dlg.setVisible(false);
+
+ endProgressStatus();
+
+ if (!ready) {
+ String str = configCertCgi.getErrorMessage();
+ if (str.equals(""))
+ setErrorMessage("Server Error");
+ else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ if (mWizardInfo.isCAInstalled()) {
+ CMSAdminUtil.help(HELPINDEX1);
+ }
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea heading = createTextArea(mResource.getString(
+ "CLONEMASTERWIZARD_TEXT_ISCLONECA_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(heading, gbc);
+
+ mNo = makeJRadioButton("NO", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mNo, gbc);
+
+ mYes = makeJRadioButton("YES", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mYes, gbc);
+
+ ButtonGroup btnGroup = new ButtonGroup();
+ btnGroup.add(mNo);
+ btnGroup.add(mYes);
+
+ mHeading = createTextArea(mResource.getString(
+ "CLONEMASTERWIZARD_TEXT_HEADING_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0,4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mHeading, gbc);
+
+ mHostLbl = makeJLabel("HOST");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0,
+ COMPONENT_SPACE);
+ add(mHostLbl, gbc);
+
+ mHostText = makeJTextField(30);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mHostText, gbc);
+ mActiveColor = mHostText.getBackground();
+
+ mPortLbl = makeJLabel("PORT");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mPortLbl, gbc);
+
+ mPortText = makeJTextField(10);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mPortText, gbc);
+
+ mPortEELbl = makeJLabel("PORTEE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mPortEELbl, gbc);
+
+ mPortEEText = makeJTextField(10);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mPortEEText, gbc);
+
+ mTimeoutLbl = makeJLabel("TIMEOUT");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0,
+ COMPONENT_SPACE);
+ add(mTimeoutLbl, gbc);
+
+ mTimeoutText = makeJTextField("30", 10);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mTimeoutText, gbc);
+
+ /*mTimeunitLbl = makeJLabel("TIMEUNIT");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0,
+ COMPONENT_SPACE);
+ add(mTimeunitLbl, gbc);
+ */
+
+ JLabel label = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(label, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (mYes.isSelected()) {
+ enableFields(true, mActiveColor);
+ } else {
+ enableFields(false, getBackground());
+ }
+ }
+
+ private void enableFields(boolean enabled, Color color) {
+ mHeading.setEnabled(enabled);
+ mHostLbl.setEnabled(enabled);
+ mPortLbl.setEnabled(enabled);
+ mPortEELbl.setEnabled(enabled);
+ mTimeoutLbl.setEnabled(enabled);
+ mHostText.setEnabled(enabled);
+ mHostText.setEditable(enabled);
+ mHostText.setBackground(color);
+ mPortText.setEnabled(enabled);
+ mPortText.setEditable(enabled);
+ mPortText.setBackground(color);
+ mPortEEText.setEnabled(enabled);
+ mPortEEText.setEditable(enabled);
+ mPortEEText.setBackground(color);
+ mTimeoutText.setEnabled(enabled);
+ mTimeoutText.setEditable(enabled);
+ mTimeoutText.setBackground(color);
+ CMSAdminUtil.repaintComp(mHeading);
+ CMSAdminUtil.repaintComp(mHostLbl);
+ CMSAdminUtil.repaintComp(mHostText);
+ CMSAdminUtil.repaintComp(mPortLbl);
+ CMSAdminUtil.repaintComp(mPortText);
+ CMSAdminUtil.repaintComp(mPortEELbl);
+ CMSAdminUtil.repaintComp(mPortEEText);
+ CMSAdminUtil.repaintComp(mTimeoutLbl);
+ CMSAdminUtil.repaintComp(mTimeoutText);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICloneOCSPKeyCertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICloneOCSPKeyCertPage.java
new file mode 100644
index 000000000..9061b5f7a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICloneOCSPKeyCertPage.java
@@ -0,0 +1,237 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * Introduction page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICloneOCSPKeyCertPage extends WizardBasePanel implements IWizardPanel {
+ private String mOCSPNicknameStr, mSSLNicknameStr;
+ private String mOCSPTokenname, mSSLTokenname;
+ protected InstallWizardInfo mWizardInfo;
+ protected JComboBox mOCSPNicknameBox, mSSLNicknameBox;
+ private static final String PANELNAME = "CLONEOCSPKEYCERTWIZARD";
+ private static final String OCSPHELPINDEX =
+ "install-ocspcertclone-wizard-help";
+
+
+ WICloneOCSPKeyCertPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ mSSLNicknameStr = "Server-Cert";
+ mOCSPNicknameStr = "ocspSigningCert";
+ init();
+ }
+
+ WICloneOCSPKeyCertPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ mSSLNicknameStr = "Server-Cert";
+ mOCSPNicknameStr = "ocspSigningCert";
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ mWizardInfo = wizardInfo;
+ if (!wizardInfo.isCloning())
+ return false;
+ if (!wizardInfo.isCloneOCSPSubsystem())
+ return false;
+ if (wizardInfo.isOCSPCloningDone())
+ return false;
+
+ setBorder(makeTitledBorder(PANELNAME));
+
+ if (mOCSPNicknameBox.getItemCount() > 0) {
+ mOCSPNicknameBox.removeAllItems();
+ }
+
+ if (mSSLNicknameBox.getItemCount() > 0) {
+ mSSLNicknameBox.removeAllItems();
+ }
+ String certsList = mWizardInfo.getCloneCertsList();
+ StringTokenizer t2 = new StringTokenizer(certsList, ";");
+ while (t2.hasMoreTokens()) {
+ String s1 = (String)t2.nextToken();
+ if (s1.indexOf(mSSLNicknameStr) >= 0)
+ mSSLNicknameBox.addItem(s1);
+ }
+
+ StringTokenizer t3 = new StringTokenizer(certsList, ";");
+ while (t3.hasMoreTokens()) {
+ String s1 = (String)t3.nextToken();
+ if (s1.indexOf(mOCSPNicknameStr) >= 0)
+ mOCSPNicknameBox.addItem(s1);
+ }
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ String ocspnickname = (String)mOCSPNicknameBox.getSelectedItem();
+ mOCSPTokenname = Constants.PR_INTERNAL_TOKEN_NAME;
+ int index = ocspnickname.indexOf(":");
+ if (index > -1) {
+ mOCSPTokenname = ocspnickname.substring(0, index);
+ }
+ mWizardInfo.put(ConfigConstants.PR_CLONE_OCSP_TOKEN_NAME, mOCSPTokenname);
+
+ String sslnickname = (String)mSSLNicknameBox.getSelectedItem();
+ mSSLTokenname = Constants.PR_INTERNAL_TOKEN_NAME;
+ index = sslnickname.indexOf(":");
+ if (index > -1) {
+ mSSLTokenname = sslnickname.substring(0, index);
+ }
+ mWizardInfo.put(ConfigConstants.PR_CLONE_SSL_TOKEN_NAME, mSSLTokenname);
+
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_CLONING;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ rawData = rawData+"&"+ConfigConstants.PR_SUBSYSTEM+"="+
+ ConfigConstants.PR_OCSP;
+ rawData = rawData+"&"+ConfigConstants.PR_CLONE_OCSP_TOKEN_NAME+"="+
+ mOCSPTokenname;
+ rawData = rawData+"&"+ConfigConstants.PR_CLONE_OCSP_NICKNAME+"="+
+ mOCSPNicknameBox.getSelectedItem();
+ rawData = rawData+"&"+ConfigConstants.PR_CLONE_SSL_TOKEN_NAME+"="+
+ mSSLTokenname;
+ rawData = rawData+"&"+ConfigConstants.PR_CLONE_SSL_NICKNAME+"="+
+ mSSLNicknameBox.getSelectedItem();
+
+ startProgressStatus();
+ boolean ready = send(rawData, wizardInfo);
+ endProgressStatus();
+
+ if (!ready) {
+ String errstr = getErrorMessage();
+ if (errstr.equals("")) {
+ String errorMsg = mResource.getString(
+ PANELNAME+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(errstr);
+ }
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(OCSPHELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea heading1 = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING1_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(heading1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel ocspNicknameLbl = makeJLabel("OCSPNICKNAME");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(ocspNicknameLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mOCSPNicknameBox = new JComboBox();
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.weightx = 0.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mOCSPNicknameBox, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea heading2 = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING2_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(heading2, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel sslNicknameLbl = makeJLabel("SSLNICKNAME");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(sslNicknameLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mSSLNicknameBox = new JComboBox();
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.weightx = 0.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mSSLNicknameBox, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ mWizardInfo.setOCSPTokenName(mOCSPTokenname);
+ mWizardInfo.setSSLTokenName(mSSLTokenname);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIClonePage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIClonePage.java
new file mode 100644
index 000000000..cdfa23199
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIClonePage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Introduction page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIClonePage extends WizardBasePanel implements IWizardPanel {
+
+ private static final String PANELNAME = "CLONEINSTALLWIZARD";
+ private static final String HELPINDEX =
+ "install-general-intro-wizard-help";
+
+ WIClonePage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIClonePage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ setBorder(makeTitledBorder(PANELNAME));
+
+ if //(wizardInfo.isKRACertLocalCA() || !wizardInfo.isInstallCertNow() ||
+ (!wizardInfo.isCloning()||wizardInfo.isClonePageDone())
+ return false;
+
+ mAdminFrame = wizardInfo.getAdminFrame();
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ cleanUpWizardInfo(wizardInfo);
+ startProgressStatus();
+ Debug.println("WIClonePage:concludePanel() 1");
+
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_MASTER_OR_CLONE;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_READ;
+ rawData = rawData+"&"+ConfigConstants.PR_CLONE_SETTING_DONE+"="+
+ ConfigConstants.TRUE;
+ boolean ready = send(rawData, wizardInfo);
+
+ Debug.println("WIClonePage:concludePanel() 2");
+
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage(wizardInfo);
+ if (str == null)
+ setErrorMessage("Server Error");
+ else
+ setErrorMessage(str);
+ }else{
+ wizardInfo.setClonePageDone(ConfigConstants.TRUE);
+ }
+
+ return ready;
+ }
+
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea desc = createTextArea(mResource.getString(
+ "CLONEINSTALLWIZARD_TEXT_DESC_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICloneRAKeyCertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICloneRAKeyCertPage.java
new file mode 100644
index 000000000..7194ee3cc
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICloneRAKeyCertPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * Introduction page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICloneRAKeyCertPage extends WizardBasePanel implements IWizardPanel {
+ private String mRANicknameStr, mSSLNicknameStr;
+ private String mRATokenname, mSSLTokenname;
+ protected InstallWizardInfo mWizardInfo;
+ protected JComboBox mRANicknameBox, mSSLNicknameBox;
+ private static final String PANELNAME = "CLONERAKEYCERTWIZARD";
+ private static final String CAHELPINDEX =
+ "install-racertclone-wizard-help";
+
+
+ WICloneRAKeyCertPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ mRANicknameStr = "raSigningCert";
+ mSSLNicknameStr = "Server-Cert";
+ init();
+ }
+
+ WICloneRAKeyCertPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ mRANicknameStr = "raSigningCert";
+ mSSLNicknameStr = "Server-Cert";
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ mWizardInfo = wizardInfo;
+ if (!wizardInfo.isCloning())
+ return false;
+ if (!wizardInfo.isCloneRASubsystem())
+ return false;
+ if (wizardInfo.isRACloningDone())
+ return false;
+ if (!wizardInfo.isRAInstalled() ||
+ wizardInfo.isRACertRequestDone())
+ return false;
+
+ setBorder(makeTitledBorder(PANELNAME));
+ if (mRANicknameBox.getItemCount() > 0) {
+ mRANicknameBox.removeAllItems();
+ }
+
+ if (mSSLNicknameBox.getItemCount() > 0) {
+ mSSLNicknameBox.removeAllItems();
+ }
+ String certsList = mWizardInfo.getCloneCertsList();
+ StringTokenizer t1 = new StringTokenizer(certsList, ";");
+ while (t1.hasMoreTokens()) {
+ String s1 = (String)t1.nextToken();
+ if (s1.indexOf(mRANicknameStr) >= 0)
+ mRANicknameBox.addItem(s1);
+ }
+
+ StringTokenizer t2 = new StringTokenizer(certsList, ";");
+ while (t2.hasMoreTokens()) {
+ String s1 = (String)t2.nextToken();
+ if (s1.indexOf(mSSLNicknameStr) >= 0)
+ mSSLNicknameBox.addItem(s1);
+ }
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ String ranickname = (String)mRANicknameBox.getSelectedItem();
+ mRATokenname = Constants.PR_INTERNAL_TOKEN_NAME;
+ int index = ranickname.indexOf(":");
+ if (index > -1) {
+ mRATokenname = ranickname.substring(0, index);
+ }
+ mWizardInfo.put(ConfigConstants.PR_CLONE_RA_TOKEN_NAME, mRATokenname);
+
+ String sslnickname = (String)mSSLNicknameBox.getSelectedItem();
+ mSSLTokenname = Constants.PR_INTERNAL_TOKEN_NAME;
+ index = sslnickname.indexOf(":");
+ if (index > -1) {
+ mSSLTokenname = sslnickname.substring(0, index);
+ }
+ mWizardInfo.put(ConfigConstants.PR_CLONE_SSL_TOKEN_NAME, mSSLTokenname);
+
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ ConsoleInfo consoleInfo = wizardInfo.getAdminConsoleInfo();
+ CMSConfigCert configCertCgi = new CMSConfigCert();
+ configCertCgi.initialize(wizardInfo);
+ Hashtable data = new Hashtable();
+ data.put(ConfigConstants.TASKID,TaskId.TASK_CLONING);
+ data.put(ConfigConstants.OPTYPE, OpDef.OP_MODIFY);
+ data.put(ConfigConstants.PR_SUBSYSTEM, ConfigConstants.PR_RA);
+ data.put(ConfigConstants.PR_CERT_INSTANCE_NAME,
+ consoleInfo.get(ConfigConstants.PR_CERT_INSTANCE_NAME));
+ data.put(ConfigConstants.PR_CLONE_RA_TOKEN_NAME, mRATokenname);
+ data.put(ConfigConstants.PR_CLONE_RA_NICKNAME,
+ mRANicknameBox.getSelectedItem());
+ data.put(ConfigConstants.PR_CLONE_SSL_TOKEN_NAME, mSSLTokenname);
+ data.put(ConfigConstants.PR_CLONE_SSL_NICKNAME,
+ mSSLNicknameBox.getSelectedItem());
+
+ startProgressStatus();
+ boolean ready = configCertCgi.configCert(data);
+ endProgressStatus();
+
+ if (!ready) {
+ String errstr = configCertCgi.getErrorMessage();
+ if (errstr.equals("")) {
+ String errorMsg = mResource.getString(
+ PANELNAME+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(errstr);
+ }
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(CAHELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea heading = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(heading, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel raNicknameLbl = makeJLabel("RANICKNAME");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(raNicknameLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRANicknameBox = new JComboBox();
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.weightx = 0.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mRANicknameBox, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea heading1 = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING1_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(heading1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel sslNicknameLbl = makeJLabel("SSLNICKNAME");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(sslNicknameLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mSSLNicknameBox = new JComboBox();
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.weightx = 0.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mSSLNicknameBox, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ mWizardInfo.setRATokenName(mRATokenname);
+ mWizardInfo.setSSLTokenName(mSSLTokenname);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICloneTKSKeyCertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICloneTKSKeyCertPage.java
new file mode 100644
index 000000000..baeaaec8d
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICloneTKSKeyCertPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * Introduction page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICloneTKSKeyCertPage extends WizardBasePanel implements IWizardPanel {
+ private String mSSLNicknameStr, mSSLTokenname;
+ protected InstallWizardInfo mWizardInfo;
+ protected JComboBox mSSLNicknameBox;
+ private static final String PANELNAME = "CLONETKSKEYCERTWIZARD";
+ private static final String TKSHELPINDEX =
+ "install-tkscertclone-wizard-help";
+
+
+ WICloneTKSKeyCertPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ mSSLNicknameStr = "Server-Cert";
+ init();
+ }
+
+ WICloneTKSKeyCertPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ mSSLNicknameStr = "Server-Cert";
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ mWizardInfo = wizardInfo;
+ if (!wizardInfo.isCloning())
+ return false;
+ if (!wizardInfo.isCloneTKSSubsystem())
+ return false;
+ if (wizardInfo.isTKSCloningDone())
+ return false;
+
+ setBorder(makeTitledBorder(PANELNAME));
+
+ if (mSSLNicknameBox.getItemCount() > 0) {
+ mSSLNicknameBox.removeAllItems();
+ }
+ String certsList = mWizardInfo.getCloneCertsList();
+ StringTokenizer t = new StringTokenizer(certsList, ";");
+ while (t.hasMoreTokens()) {
+ String s1 = (String)t.nextToken();
+ if (s1.indexOf(mSSLNicknameStr) >= 0)
+ mSSLNicknameBox.addItem(s1);
+ }
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ String sslnickname = (String)mSSLNicknameBox.getSelectedItem();
+ mSSLTokenname = Constants.PR_INTERNAL_TOKEN_NAME;
+ int index = sslnickname.indexOf(":");
+ if (index > -1) {
+ mSSLTokenname = sslnickname.substring(0, index);
+ }
+ mWizardInfo.put(ConfigConstants.PR_CLONE_SSL_TOKEN_NAME, mSSLTokenname);
+
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_CLONING;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ rawData = rawData+"&"+ConfigConstants.PR_SUBSYSTEM+"="+ConfigConstants.PR_TKS;
+ rawData = rawData+"&"+ConfigConstants.PR_CLONE_SSL_TOKEN_NAME+"="+
+ mSSLTokenname;
+ rawData = rawData+"&"+ConfigConstants.PR_CLONE_SSL_NICKNAME+"="+
+ mSSLNicknameBox.getSelectedItem();
+
+ startProgressStatus();
+ boolean ready = send(rawData, wizardInfo);
+ endProgressStatus();
+
+ if (!ready) {
+ String errstr = getErrorMessage();
+ if (errstr.equals("")) {
+ String errorMsg = mResource.getString(
+ PANELNAME+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(errstr);
+ }
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(TKSHELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea heading = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(heading, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel sslNicknameLbl = makeJLabel("SSLNICKNAME");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(sslNicknameLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mSSLNicknameBox = new JComboBox();
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.weightx = 0.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mSSLNicknameBox, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ mWizardInfo.setSSLTokenName(mSSLTokenname);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIConfigWebServerPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIConfigWebServerPage.java
new file mode 100644
index 000000000..ad9e8b4d6
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIConfigWebServerPage.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.admin.certsrv.config.install;
+
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Web Server Configuration.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIConfigWebServerPage extends WizardBasePanel implements IWizardPanel {
+ private Color mActiveColor;
+ private JTextField mServerRootText;
+ private JTextField mUserIDText;
+
+ private static final String PANELNAME = "WEBSERVERCONFIGWIZARD";
+ private static final String HELPINDEX =
+ "install-webserver-configuration-wizard-help";
+
+ WIConfigWebServerPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIConfigWebServerPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isWebServerDone())
+ return false;
+ setBorder(makeTitledBorder(PANELNAME));
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ ConsoleInfo consoleInfo = wizardInfo.getAdminConsoleInfo();
+ CMSConfigCert configCertCgi = new CMSConfigCert();
+ configCertCgi.initialize(wizardInfo);
+ Hashtable data = new Hashtable();
+
+ data.put(ConfigConstants.TASKID,TaskId.TASK_CONFIG_WEB_SERVER);
+ data.put(ConfigConstants.OPTYPE, OpDef.OP_MODIFY);
+ data.put(ConfigConstants.PR_CERT_INSTANCE_NAME,
+ consoleInfo.get(ConfigConstants.PR_CERT_INSTANCE_NAME));
+
+ data.put(ConfigConstants.PR_WEB_SERVERROOT,
+ mServerRootText.getText().trim());
+ data.put(ConfigConstants.PR_USER_ID,
+ mUserIDText.getText().trim());
+
+ startProgressStatus();
+ CMSMessageBox dlg = new CMSMessageBox(mAdminFrame, "CGITASK", "CREATEWEBSERVER");
+
+ boolean ready = configCertCgi.configCert(data);
+ dlg.setVisible(false);
+
+ endProgressStatus();
+
+ if (!ready) {
+ String str = configCertCgi.getErrorMessage();
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ PANELNAME+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea desc = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel serverRootLbl = makeJLabel("SERVERROOT");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(serverRootLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mServerRootText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mServerRootText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel userIDLbl = makeJLabel("USERID");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(userIDLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mUserIDText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mUserIDText, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ wizardInfo.setWebServerDone(ConfigConstants.TRUE);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WICreateInternalDBPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WICreateInternalDBPage.java
new file mode 100644
index 000000000..4aee62e27
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WICreateInternalDBPage.java
@@ -0,0 +1,581 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Introduction page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WICreateInternalDBPage extends WizardBasePanel implements IWizardPanel {
+ private Color mActiveColor;
+ private JTextField mPortText, mBindAsText, mInstanceIDText;
+ private JTextField mRemoteHostText, mRemotePortText, mRemoteBaseDNText;
+ private JTextField mRemoteBindAsText,mRemotePasswordText, mRemoteDatabaseText;
+ private JPasswordField mPasswordText, mPasswordAgainText;
+ private JLabel mBindAsLabel, mPasswordLabel, mPasswordAgainLabel;
+ private JComboBox mVersionBox;
+ private JCheckBox mEnable, mSchema;
+ private JRadioButton mLocal, mRemote;
+ private static final String PANELNAME = "CREATEINTERNALDBWIZARD";
+ private static final String HELPINDEX =
+ "install-internaldb-configuration-wizard-help";
+ private static final String EMPTYSTR = " ";
+
+ WICreateInternalDBPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WICreateInternalDBPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mEnable)) {
+ enableLocalDB(mEnable.isSelected());
+ enableRemoteDB(mEnable.isSelected());
+ mLocal.setEnabled(mEnable.isSelected());
+ mRemote.setEnabled(mEnable.isSelected());
+ } else if (e.getSource().equals(mLocal)) {
+ enableLocalDB(mEnable.isSelected());
+ enableRemoteDB(mEnable.isSelected());
+ } else if (e.getSource().equals(mRemote)) {
+ enableLocalDB(mEnable.isSelected());
+ enableRemoteDB(mEnable.isSelected());
+ }
+ }
+
+ private void enableLocalDB(boolean e)
+ {
+ Color c;
+ if (e) {
+ if (mLocal.isSelected())
+ c = mActiveColor;
+ else
+ c = getBackground();
+ } else {
+ c = getBackground();
+ }
+ mPortText.setEditable(e);
+ mPortText.setEnabled(e);
+ mPortText.setBackground(c);
+ mBindAsText.setEditable(e);
+ mBindAsText.setEnabled(e);
+ mBindAsText.setBackground(c);
+ mInstanceIDText.setEditable(e);
+ mInstanceIDText.setEnabled(e);
+ mInstanceIDText.setBackground(c);
+ mPasswordText.setEditable(e);
+ mPasswordText.setEnabled(e);
+ mPasswordText.setBackground(c);
+ mPasswordAgainText.setEditable(e);
+ mPasswordAgainText.setEnabled(e);
+ mPasswordAgainText.setBackground(c);
+ }
+
+ private void enableRemoteDB(boolean e) {
+ Color c;
+ if (e) {
+ if (mRemote.isSelected())
+ c = mActiveColor;
+ else
+ c = getBackground();
+ } else {
+ c = getBackground();
+ }
+ mRemoteHostText.setEditable(e);
+ mRemoteHostText.setEnabled(e);
+ mRemoteHostText.setBackground(c);
+ mRemotePortText.setEditable(e);
+ mRemotePortText.setEnabled(e);
+ mRemotePortText.setBackground(c);
+ mRemoteBaseDNText.setEditable(e);
+ mRemoteBaseDNText.setEnabled(e);
+ mRemoteBaseDNText.setBackground(c);
+ mRemoteBindAsText.setEditable(e);
+ mRemoteBindAsText.setEnabled(e);
+ mRemoteBindAsText.setBackground(c);
+ mRemotePasswordText.setEditable(e);
+ mRemotePasswordText.setEnabled(e);
+ mRemotePasswordText.setBackground(c);
+ mRemoteDatabaseText.setEditable(e);
+ mRemoteDatabaseText.setEnabled(e);
+ mRemoteDatabaseText.setBackground(c);
+ mSchema.setEnabled(e);
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ if (wizardInfo.isCloning() && wizardInfo.isUpdateDBInfoDone())
+ return false;
+ if (wizardInfo.isCloning() && !wizardInfo.isCreateDBDone()) {
+ setBorder(makeTitledBorder(PANELNAME));
+ mEnable.setSelected(true);
+ mInstanceIDText.setText(wizardInfo.getCloneDBName());
+ mPortText.setText(""+wizardInfo.getNextAvailPort());
+ mBindAsText.setText(wizardInfo.getDBBindDN());
+ mPasswordText.setText("");
+ mPasswordAgainText.setText("");
+ mRemoteBaseDNText.setText("o=netscapeCertificateServer");
+ mRemoteDatabaseText.setText("userRoot");
+ mRemoteBindAsText.setText("cn=directory manager");
+ enableLocalDB(mEnable.isSelected());
+ enableRemoteDB(mEnable.isSelected());
+ mLocal.setEnabled(mEnable.isSelected());
+ mRemote.setEnabled(mEnable.isSelected());
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean validatePanel() {
+ if (!mEnable.isSelected())
+ return true;
+ if (mLocal.isSelected()) {
+ String passwd = mPasswordText.getText().trim();
+ String passwdAgain = mPasswordAgainText.getText().trim();
+ String instanceId = mInstanceIDText.getText().trim();
+ String bindAs = mBindAsText.getText().trim();
+ String port = mPortText.getText().trim();
+
+ if (instanceId.equals("") || bindAs.equals("") ||
+ port.equals("")) {
+ setErrorMessage("BLANKFIELD");
+ return false;
+ }
+
+ if (passwd.equals("") || passwdAgain.equals("")) {
+ setErrorMessage("BLANKPASSWD");
+ return false;
+ }
+ if (!passwd.equals(passwdAgain)) {
+ setErrorMessage("NOTSAMEPASSWD");
+ return false;
+ }
+
+ try {
+ Integer num = new Integer(mPortText.getText().trim());
+ } catch (NumberFormatException e) {
+ setErrorMessage("NUMBERFORMAT");
+ return false;
+ }
+ } else {
+ String host = mRemoteHostText.getText().trim();
+ String port = mRemotePortText.getText().trim();
+ String baseDN = mRemoteBaseDNText.getText().trim();
+ String bindAs = mRemoteBindAsText.getText().trim();
+ String passwd = mRemotePasswordText.getText().trim();
+ String dbname = mRemoteDatabaseText.getText().trim();
+ if (host.equals("") || port.equals("") || bindAs.equals("") ||
+ baseDN.equals("") || dbname.equals("")) {
+ setErrorMessage("BLANKFIELD");
+ return false;
+ }
+ if (passwd.equals("")) {
+ setErrorMessage("BLANKPASSWD");
+ return false;
+ }
+ try {
+ Integer num = new Integer(port);
+ } catch (NumberFormatException e) {
+ setErrorMessage("NUMBERFORMAT");
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String rawData = "";
+ if (!mEnable.isSelected()) {
+ rawData = rawData+ConfigConstants.TASKID+"="+TaskId.TASK_UPDATE_DB_INFO;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ boolean ready = send(rawData, wizardInfo);
+ if (!ready) {
+ String str = getErrorMessage(wizardInfo);
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ PANELNAME+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ if (mRemote.isSelected()) {
+ rawData = ConfigConstants.TASKID+"="+TaskId.TASK_ADD_DBSCHEMA_INDEXES;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ rawData = rawData+"&"+ConfigConstants.PR_HOST+"="+mRemoteHostText.getText().trim();
+ rawData = rawData+"&"+ConfigConstants.PR_DB_PORT+"="+mRemotePortText.getText().trim();
+ rawData = rawData+"&"+ConfigConstants.PR_DB_BINDDN+"="+mRemoteBindAsText.getText().trim();
+ rawData = rawData+"&"+ConfigConstants.PR_DB_PWD+"="+mRemotePasswordText.getText().trim();
+ rawData = rawData+"&"+ConfigConstants.PR_DB_NAME+"="+mRemoteBaseDNText.getText().trim();
+ rawData = rawData+"&"+ConfigConstants.PR_LDAP_DB_NAME+"="+mRemoteDatabaseText.getText().trim();
+ rawData = rawData+"&"+ConfigConstants.PR_DB_SCHEMA+"="+mSchema.isSelected();
+ rawData = rawData+"&"+ConfigConstants.PR_DB_MODE+"=remote";
+ } else {
+ rawData = ConfigConstants.TASKID+"="+TaskId.TASK_CREATE_INTERNALDB;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ rawData = rawData+"&"+ConfigConstants.PR_IS_CLONEDDB_CREATED+"=true";
+ rawData = rawData+"&"+ConfigConstants.PR_DB_MODE+"=local";
+ rawData = rawData+"&"+ConfigConstants.PR_DB_PORT+"="+mPortText.getText();
+ rawData = rawData+"&"+ConfigConstants.PR_DB_BINDDN+"="+mBindAsText.getText();
+ rawData = rawData+"&"+ConfigConstants.PR_DB_NAME+"="+mInstanceIDText.getText();
+ rawData = rawData+"&"+ConfigConstants.PR_DB_PWD+"="+mPasswordText.getText();
+ wizardInfo.setInternalDBPasswd(mPasswordText.getText().trim());
+ wizardInfo.setDBBindDN(mBindAsText.getText().trim());
+ wizardInfo.setDBName(mInstanceIDText.getText().trim());
+ }
+
+ startProgressStatus();
+ //CMSMessageBox dlg = new CMSMessageBox(mAdminFrame, "CGITASK", "CREATEDB");
+
+ boolean ready = send(rawData, wizardInfo);
+
+ if (ready) {
+ rawData = ConfigConstants.TASKID+"="+TaskId.TASK_TOKEN_INFO;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_READ;
+ ready = send(rawData, wizardInfo);
+ }
+ //dlg.setVisible(false);
+
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage(wizardInfo);
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ PANELNAME+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea desc = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEnable = makeJCheckBox("ENABLE");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mEnable, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mLocal = makeJRadioButton("LOCAL", true);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, 2*COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ add(mLocal, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel instanceIDLbl = makeJLabel("INSTANCEID");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(instanceIDLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mInstanceIDText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mInstanceIDText, gbc);
+ mActiveColor = mInstanceIDText.getBackground();
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel portNumber = makeJLabel("PORT");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 0,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(portNumber, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPortText = makeJTextField(10);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(mPortText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mBindAsLabel = makeJLabel("ADMIN");
+ //gbc.anchor = gbc.NORTHWEST;
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 2*COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mBindAsLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mBindAsText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mBindAsText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPasswordLabel = makeJLabel("PWD");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mPasswordLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPasswordText = makeJPasswordField(30);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mPasswordText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPasswordAgainLabel = makeJLabel("PWDAGAIN");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mPasswordAgainLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPasswordAgainText = makeJPasswordField(30);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mPasswordAgainText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRemote = makeJRadioButton("REMOTE", false);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, 2*COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ add(mRemote, gbc);
+
+ ButtonGroup buttonGroup = new ButtonGroup();
+ buttonGroup.add(mLocal);
+ buttonGroup.add(mRemote);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel hostLbl = makeJLabel("HOST");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(hostLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRemoteHostText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mRemoteHostText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel portNumber1 = makeJLabel("PORT");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 0,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(portNumber1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRemotePortText = makeJTextField(10);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(mRemotePortText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel baseDNLbl = makeJLabel("BASEDN");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 0,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(baseDNLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRemoteBaseDNText = makeJTextField(30);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(mRemoteBaseDNText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel bindAsLabel = makeJLabel("ADMIN");
+ //gbc.anchor = gbc.NORTHWEST;
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 2*COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(bindAsLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRemoteBindAsText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mRemoteBindAsText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel passwordLabel = makeJLabel("PWD");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(passwordLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRemotePasswordText = makeJPasswordField(30);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mRemotePasswordText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel databaseLabel = makeJLabel("DNAME");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 3*COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(databaseLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRemoteDatabaseText = makeJTextField(30);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mRemoteDatabaseText, gbc);
+
+ JLabel dummy1 = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(dummy1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mSchema = makeJCheckBox("SCHEMA", true);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mSchema, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ wizardInfo.setDBCreated(ConfigConstants.TRUE);
+ wizardInfo.setDBCreateNow(ConfigConstants.FALSE);
+ wizardInfo.setCreateDBDone(ConfigConstants.TRUE);
+
+ if (mEnable.isSelected())
+ wizardInfo.setCloneDBCreated("true");
+ else {
+ wizardInfo.setUpdateDBInfoDone(ConfigConstants.TRUE);
+ wizardInfo.setCloneDBCreated("false");
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIDBEnrollPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIDBEnrollPage.java
new file mode 100644
index 000000000..d63a07129
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIDBEnrollPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Introduction page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIDBEnrollPage extends WizardBasePanel implements IWizardPanel {
+ private JCheckBox mEnable;
+ private JTextField mHostNameText, mPortText, mBaseDNText;
+ private JComboBox mVersionBox;
+
+ private static final String PANELNAME = "DBENROLLWIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WIDBEnrollPage() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea desc = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "DBENROLLWIZARD_TEXT_HEADING_LABEL"), 80), 1, 80);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEnable = makeJCheckBox("ENABLE");
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mEnable, gbc);
+
+ JPanel panel = new JPanel();
+ panel.setBorder(CMSAdminUtil.makeTitledBorder(mResource,
+ PANELNAME, "DESTINATION"));
+ GridBagLayout gb1 = new GridBagLayout();
+ panel.setLayout(gb1);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.weighty = 1.0;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(panel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel hostName = makeJLabel("HOST");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ panel.add(hostName, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mHostNameText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ panel.add(mHostNameText, gbc);
+
+/*
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea dummy = createTextArea(" ", 2, 5);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ add(dummy, gbc);
+*/
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel portNumber = makeJLabel("PORT");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ panel.add(portNumber, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPortText = makeJTextField(10);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ panel.add(mPortText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel versionLbl = makeJLabel("VERSION");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel.add(versionLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mVersionBox = makeJComboBox("VERSION");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel.add(mVersionBox, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel dummy = new JLabel(" ");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel.add(dummy, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel baseDNLbl = makeJLabel("BASEDN");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel.add(baseDNLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mBaseDNText = makeJTextField(20);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel.add(mBaseDNText, gbc);
+
+/*
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea dummy1 = createTextArea(" ", 2, 30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(dummy1, gbc);
+*/
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIDisplayCACertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIDisplayCACertPage.java
new file mode 100644
index 000000000..442fa2b29
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIDisplayCACertPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import javax.swing.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * The panel displays the certificate which will be installed in the token.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIDisplayCACertPage extends WIDisplayCertPage {
+ private static final String PANELNAME = "INSTALLDISPLAYCACERTWIZARD";
+ private static final String CAHELPINDEX = "install-cacert-display-wizard-help";
+ private static final String CAKRAHELPINDEX = "install-cakracert-display-wizard-help";
+
+ WIDisplayCACertPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIDisplayCACertPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isCACloningDone())
+ return false;
+
+ if (wizardInfo.isCACertLocalCA() || !wizardInfo.isInstallCertNow() ||
+ !wizardInfo.isCAInstalled() || wizardInfo.isMigrationEnable() ||
+ wizardInfo.isCACertInstalledDone())
+ return false;
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else
+ mHelpIndex = CAHELPINDEX;
+ return super.initializePanel(info);
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ if (super.concludePanel(info)) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ wizardInfo.put(ConfigConstants.STAGE_CA_CERT_REQUEST,
+ ConfigConstants.TRUE);
+ return true;
+ }
+
+ return false;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIDisplayCertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIDisplayCertPage.java
new file mode 100644
index 000000000..30e0bac13
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIDisplayCertPage.java
@@ -0,0 +1,205 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * This page is to install the certificate in the internal token. It
+ * displays the certificate information.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIDisplayCertPage extends WizardBasePanel implements IWizardPanel {
+ private JTextArea mTextArea;
+ private JTextField mCertNameField;
+ protected String mPanelName;
+ protected String mHelpIndex;
+
+ WIDisplayCertPage(String panelName) {
+ super(panelName);
+ mPanelName = panelName;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ setBorder(makeTitledBorder(mPanelName));
+ String content = wizardInfo.getCertContent();
+ String certOrder = wizardInfo.getCertOrder();
+ String str = reformat(content, certOrder);
+ mTextArea.setText(str);
+ mCertNameField.setEditable(false);
+ mCertNameField.setBackground(getBackground());
+ String tokenName = null;
+ String certType = wizardInfo.getCertType();
+ if (certType != null) {
+ if (certType.equalsIgnoreCase(Constants.PR_CA_SIGNING_CERT)) {
+ tokenName = wizardInfo.getCATokenName();
+ } else if (certType.equalsIgnoreCase(Constants.PR_RA_SIGNING_CERT)) {
+ tokenName = wizardInfo.getRATokenName();
+ } else if (certType.equalsIgnoreCase(Constants.PR_OCSP_SIGNING_CERT)) {
+ tokenName = wizardInfo.getOCSPTokenName();
+ } else if (certType.equalsIgnoreCase(Constants.PR_KRA_TRANSPORT_CERT)) {
+ tokenName = wizardInfo.getKRATokenName();
+ } else if (certType.equalsIgnoreCase(Constants.PR_SERVER_CERT)) {
+ tokenName = wizardInfo.getSSLTokenName();
+ } else {
+ Debug.println("WIDisplayCertPage: unrecognized certType: "+
+ certType);
+ }
+ }
+ if ((tokenName != null) &&
+ !(tokenName.equalsIgnoreCase(Constants.PR_INTERNAL_TOKEN_NAME))) {
+ Debug.println("tokenName="+tokenName);
+ mCertNameField.setText(tokenName+":"+wizardInfo.getNickname());
+ } else {
+ Debug.println("tokenName=null");
+ mCertNameField.setText(wizardInfo.getNickname());
+ }
+ return true;
+ }
+
+ private String reformat(String content, String certOrder) {
+ StringBuffer buffer = new StringBuffer(content);
+ StringTokenizer tokenizer = new StringTokenizer(certOrder, ":");
+ int len = 0;
+ while (tokenizer.hasMoreTokens()) {
+ String str = (String)tokenizer.nextToken();
+ int index = len+Integer.parseInt(str);
+ if (index >= buffer.length())
+ break;
+ buffer.insert(index, "\n");
+ len = index+1;
+ }
+ return buffer.toString();
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_INSTALL_CERT;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ String val = wizardInfo.getPKCS10();
+ if (val == null) {
+ rawData = rawData+"&"+Constants.PR_CERT_FILEPATH+"="+
+ wizardInfo.getCertFilePath();
+ } else {
+ rawData = rawData+"&"+Constants.PR_PKCS10+"="+
+ wizardInfo.getPKCS10();
+ }
+ rawData = rawData+"&"+Constants.PR_CERTIFICATE_TYPE+"="+wizardInfo.getCertType();
+ rawData = rawData+"&"+Constants.PR_NICKNAME+"="+wizardInfo.getNickname();
+ if (wizardInfo.getInternalDBPasswd() != null)
+ rawData = rawData+"&"+ConfigConstants.PR_DB_PWD+"="+wizardInfo.getInternalDBPasswd();
+
+ startProgressStatus();
+ boolean ready = send(rawData, wizardInfo);
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage();
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ mPanelName+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(mHelpIndex);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label1 = makeJLabel("NAME");
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE);
+ add(label1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mCertNameField = new JTextField(30);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.anchor = gbc.WEST;
+ gbc.weightx=1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ add(mCertNameField, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel certLbl = makeJLabel("CONTENT");
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ add(certLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mTextArea = new JTextArea("",100,90);
+ mTextArea.setEditable(false);
+ mTextArea.setBackground(getBackground());
+ JScrollPane scrollPanel = new JScrollPane(mTextArea,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ scrollPanel.setAlignmentX(LEFT_ALIGNMENT);
+ scrollPanel.setAlignmentY(TOP_ALIGNMENT);
+ scrollPanel.setBorder(BorderFactory.createLoweredBevelBorder());
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx=1.0;
+ gbc.weighty=1.0;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(scrollPanel, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIDisplayKRACertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIDisplayKRACertPage.java
new file mode 100644
index 000000000..cae06e6cf
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIDisplayKRACertPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import javax.swing.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * The panel displays the certificate which will be installed in the token.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIDisplayKRACertPage extends WIDisplayCertPage {
+ private static final String PANELNAME = "INSTALLDISPLAYKRACERTWIZARD";
+ private static final String KRAHELPINDEX = "install-kracert-display-wizard-help";
+ private static final String CAKRAHELPINDEX = "install-cakra-kracert-display-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakra-kracert-display-wizard-help";
+
+ WIDisplayKRACertPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIDisplayKRACertPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isKRACloningDone())
+ return false;
+ if (wizardInfo.isKRACertLocalCA() || !wizardInfo.isInstallCertNow() ||
+ !wizardInfo.isKRAInstalled() || wizardInfo.isKRACertInstalledDone())
+ return false;
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = KRAHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ if (super.concludePanel(info)) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ wizardInfo.put(ConfigConstants.STAGE_KRA_CERT_REQUEST,
+ ConfigConstants.TRUE);
+ return true;
+ }
+
+ return false;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIDisplayOCSPCertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIDisplayOCSPCertPage.java
new file mode 100644
index 000000000..e9db0e436
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIDisplayOCSPCertPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import javax.swing.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * The panel displays the certificate which will be installed in the token.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIDisplayOCSPCertPage extends WIDisplayCertPage {
+ private static final String PANELNAME = "INSTALLDISPLAYOCSPCERTWIZARD";
+ private static final String OCSPHELPINDEX = "install-ocspcert-display-wizard-help";
+
+ WIDisplayOCSPCertPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIDisplayOCSPCertPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isOCSPCloningDone())
+ return false;
+
+ if (wizardInfo.isOCSPCertLocalCA() || !wizardInfo.isInstallCertNow() ||
+ !wizardInfo.isOCSPInstalled() || wizardInfo.isOCSPCertInstalledDone())
+ return false;
+
+ mHelpIndex = OCSPHELPINDEX;
+ return super.initializePanel(info);
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ if (super.concludePanel(info)) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ wizardInfo.put(ConfigConstants.STAGE_OCSP_CERT_REQUEST,
+ ConfigConstants.TRUE);
+ return true;
+ }
+
+ return false;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIDisplayRACertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIDisplayRACertPage.java
new file mode 100644
index 000000000..891e68038
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIDisplayRACertPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import javax.swing.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * The panel displays the certificate which will be installed in the token.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIDisplayRACertPage extends WIDisplayCertPage {
+ private static final String PANELNAME = "INSTALLDISPLAYRACERTWIZARD";
+ private static final String RAHELPINDEX = "install-racert-display-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakracert-display-wizard-help";
+
+ WIDisplayRACertPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIDisplayRACertPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isRACloningDone())
+ return false;
+ if (wizardInfo.isRACertLocalCA() || !wizardInfo.isInstallCertNow() ||
+ !wizardInfo.isRAInstalled() || wizardInfo.isRACertInstalledDone())
+ return false;
+
+ if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = RAHELPINDEX;
+ return super.initializePanel(info);
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ if (super.concludePanel(info)) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ wizardInfo.put(ConfigConstants.STAGE_RA_CERT_REQUEST,
+ ConfigConstants.TRUE);
+ return true;
+ }
+
+ return false;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIDisplaySSLCertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIDisplaySSLCertPage.java
new file mode 100644
index 000000000..3a791b4ed
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIDisplaySSLCertPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import javax.swing.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * The panel displays the certificate which will be installed in the token.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIDisplaySSLCertPage extends WIDisplayCertPage {
+ private static final String PANELNAME = "INSTALLDISPLAYSSLCERTWIZARD";
+ private static final String HELPINDEX = "install-sslcert-display-wizard-help";
+
+ WIDisplaySSLCertPage(JDialog parent) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = parent;
+ }
+
+ WIDisplaySSLCertPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning())
+ return false;
+ if (wizardInfo.isSSLCertLocalCA() || !wizardInfo.isInstallCertNow() ||
+ wizardInfo.isMigrationEnable() || wizardInfo.isSSLCertInstalledDone())
+ return false;
+
+ return super.initializePanel(info);
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ if (super.concludePanel(info)) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ wizardInfo.put(ConfigConstants.STAGE_SSL_CERT_REQUEST,
+ ConfigConstants.TRUE);
+ return true;
+ }
+
+ return false;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIExistingDBPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIExistingDBPage.java
new file mode 100644
index 000000000..93bbde830
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIExistingDBPage.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.admin.certsrv.config.install;
+
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * This panel is for cloning. It lets the user to enter the configuration
+ * information for the master database.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIExistingDBPage extends WizardBasePanel implements IWizardPanel {
+ private JTextField mRMPortText, mRMBindAsText, mRMHostText;
+ private JTextField mRMBaseDNText;
+ private JPasswordField mRMPasswordText;
+
+ private static final String PANELNAME = "EXISTINGDBWIZARD";
+ private static final String HELPINDEX =
+ "install-internaldb-configuration-wizard-help";
+ private static final String EMPTYSTR = " ";
+
+ WIExistingDBPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIExistingDBPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ if (wizardInfo.isCloning() && !wizardInfo.isConnectDBDone()) {
+ setBorder(makeTitledBorder(PANELNAME));
+ mRMBindAsText.setText(wizardInfo.getDBBindDN());
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean validatePanel() {
+ String rmhostname = mRMHostText.getText().trim();
+ String rmport = mRMPortText.getText().trim();
+ String rmbindDN = mRMBindAsText.getText().trim();
+ String rmpasswd = mRMPasswordText.getText().trim();
+
+ if (rmhostname.equals("")) {
+ setErrorMessage("EMPTYHOST");
+ return false;
+ }
+
+ if (rmport.equals("")) {
+ setErrorMessage("EMPTYPORT");
+ return false;
+ }
+
+ if (rmbindDN.equals("")) {
+ setErrorMessage("EMPTYBINDDN");
+ return false;
+ }
+
+ if (rmpasswd.equals("")) {
+ setErrorMessage("EMPTYPASSWD");
+ return false;
+ }
+
+ try {
+ Integer num = new Integer(rmport);
+ } catch (NumberFormatException e) {
+ setErrorMessage("NUMBERFORMAT");
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ cleanUpWizardInfo(wizardInfo);
+
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_CREATE_INTERNALDB;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ rawData = rawData+"&"+ConfigConstants.PR_DB_MODE+"=remote";
+ rawData = rawData+"&"+ConfigConstants.PR_HOST+"="+mRMHostText.getText();
+ rawData = rawData+"&"+ConfigConstants.PR_DB_PORT+"="+mRMPortText.getText();
+ rawData = rawData+"&"+ConfigConstants.PR_DB_BINDDN+"="+mRMBindAsText.getText();
+ rawData = rawData+"&"+ConfigConstants.PR_DB_PWD+"="+mRMPasswordText.getText();
+ rawData = rawData+"&"+ConfigConstants.PR_DB_NAME+"="+mRMBaseDNText.getText();
+ wizardInfo.setInternalDBPasswd(mRMPasswordText.getText().trim());
+ wizardInfo.setDBBindDN(mRMBindAsText.getText().trim());
+
+ startProgressStatus();
+ //CMSMessageBox dlg = new CMSMessageBox(mAdminFrame, "CGITASK", "CONNECTDB");
+
+ boolean ready = send(rawData, wizardInfo);
+
+ if (ready) {
+ rawData = ConfigConstants.TASKID+"="+TaskId.TASK_TOKEN_INFO;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_READ;
+ ready = send(rawData, wizardInfo);
+ }
+ //dlg.setVisible(false);
+
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage(wizardInfo);
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ PANELNAME+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea desc = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel instanceIDLbl = makeJLabel("REMOTEHOST");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(instanceIDLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRMHostText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mRMHostText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel portNumber = makeJLabel("REMOTEPORT");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 0,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(portNumber, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRMPortText = makeJTextField(10);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(mRMPortText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel mRMBindAsLabel = makeJLabel("REMOTEADMIN");
+ //gbc.anchor = gbc.NORTHWEST;
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mRMBindAsLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRMBindAsText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mRMBindAsText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel mRMPasswordLabel = makeJLabel("REMOTEPWD");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mRMPasswordLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRMPasswordText = makeJPasswordField(30);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mRMPasswordText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel mRMBaseDNLabel = makeJLabel("REMOTEBASEDN");
+ //gbc.anchor = gbc.NORTHWEST;
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mRMBaseDNLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRMBaseDNText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mRMBaseDNText, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ wizardInfo.setDBCreated(ConfigConstants.TRUE);
+ wizardInfo.setDBCreateNow(ConfigConstants.FALSE);
+ wizardInfo.setConnectDBDone(ConfigConstants.TRUE);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIGenCAKeyCertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenCAKeyCertPage.java
new file mode 100644
index 000000000..2bbb2f570
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenCAKeyCertPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Generate the CA signing certificate
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WIGenCAKeyCertPage extends WIGenKeyCertPage {
+ private static final String PANELNAME = "INSTALLGENCAWIZARD";
+ private static final String CAHELPINDEX = "install-cacert-creation-wizard-help";
+ private static final String CAKRAHELPINDEX = "install-cakracert-creation-wizard-help";
+
+ WIGenCAKeyCertPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIGenCAKeyCertPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isCACloningDone())
+ return false;
+
+ if (!wizardInfo.isCACertLocalCA() || !wizardInfo.isCAInstalled() ||
+ wizardInfo.isMigrationEnable() || wizardInfo.isSelfSignedCACertDone() ||
+ wizardInfo.isCACertRequestDone() || wizardInfo.isCACertInstalledDone())
+ return false;
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else
+ mHelpIndex = CAHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIGenCAKeyCertReqPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenCAKeyCertReqPage.java
new file mode 100644
index 000000000..c1f3c11ea
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenCAKeyCertReqPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Generate the CA signing certificate request
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIGenCAKeyCertReqPage extends WIGenKeyCertReqPage {
+ private static final String PANELNAME = "INSTALLGENCACERTREQWIZARD";
+ private static final String CAHELPINDEX = "install-cacert-request-wizard-help";
+ private static final String CAKRAHELPINDEX = "install-cakracert-request-wizard-help";
+
+ WIGenCAKeyCertReqPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIGenCAKeyCertReqPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isCACloningDone())
+ return false;
+
+ if (wizardInfo.isCACertLocalCA() || !wizardInfo.isCAInstalled() ||
+ wizardInfo.isMigrationEnable() || wizardInfo.isSelfSignedCACertDone()
+ || (wizardInfo.isCACertRequestDone() &&
+ !wizardInfo.isCACertRequestBack()) ||
+ wizardInfo.isCACertInstalledDone())
+ return false;
+
+ if (wizardInfo.isCACertRequestBack()) {
+ wizardInfo.put(ConfigConstants.STAGE_CA_CERT_REQUEST,
+ ConfigConstants.FALSE);
+ wizardInfo.put(ConfigConstants.CA_CERT_REQUEST_BACK,
+ ConfigConstants.FALSE);
+ }
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else
+ mHelpIndex = CAHELPINDEX;
+
+ mTokenName = wizardInfo.getCATokenName();
+ wizardInfo.setCertType(Constants.PR_CA_SIGNING_CERT);
+ wizardInfo.setNewRequest();
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIGenKRAKeyCertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenKRAKeyCertPage.java
new file mode 100644
index 000000000..98ef24812
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenKRAKeyCertPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Generate the KRA transport certificate
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WIGenKRAKeyCertPage extends WIGenKeyCertPage {
+ private static final String PANELNAME = "INSTALLGENKRAWIZARD";
+ private static final String KRAHELPINDEX = "install-kracert-creation-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakracert-creation-wizard-help";
+ private static final String CAKRAHELPINDEX = "install-cakra-kracert-creation-wizard-help";
+
+ WIGenKRAKeyCertPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIGenKRAKeyCertPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isKRACloningDone())
+ return false;
+ if (!wizardInfo.isKRACertLocalCA() || !wizardInfo.isKRAInstalled() ||
+ wizardInfo.isKRALocalCertDone() || wizardInfo.isKRACertRequestDone() ||
+ wizardInfo.isKRACertInstalledDone())
+ return false;
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = KRAHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIGenKRAKeyCertReqPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenKRAKeyCertReqPage.java
new file mode 100644
index 000000000..f6e5df9fe
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenKRAKeyCertReqPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Generate the KRA signing certificate request
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIGenKRAKeyCertReqPage extends WIGenKeyCertReqPage {
+ private static final String PANELNAME = "INSTALLGENKRACERTREQWIZARD";
+ private static final String KRAHELPINDEX = "install-kracert-request-wizard-help";
+ private static final String CAKRAHELPINDEX = "install-cakra-kracert-request-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakra-kracert-request-wizard-help";
+
+ WIGenKRAKeyCertReqPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIGenKRAKeyCertReqPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isKRACloningDone())
+ return false;
+ if (wizardInfo.isKRACertLocalCA() || !wizardInfo.isKRAInstalled() ||
+ (wizardInfo.isKRACertRequestDone() &&
+ !wizardInfo.isKRACertRequestBack()) ||
+ wizardInfo.isKRALocalCertDone() ||
+ wizardInfo.isKRACertInstalledDone())
+ return false;
+
+ if (wizardInfo.isCACertRequestBack()) {
+ wizardInfo.put(ConfigConstants.STAGE_KRA_CERT_REQUEST,
+ ConfigConstants.FALSE);
+ wizardInfo.put(ConfigConstants.KRA_CERT_REQUEST_BACK,
+ ConfigConstants.FALSE);
+ }
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = KRAHELPINDEX;
+
+ mTokenName = wizardInfo.getKRATokenName();
+ wizardInfo.setCertType(Constants.PR_KRA_TRANSPORT_CERT);
+ wizardInfo.setNewRequest();
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIGenKeyCertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenKeyCertPage.java
new file mode 100644
index 000000000..8272d44df
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenKeyCertPage.java
@@ -0,0 +1,143 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Generate the certificate
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WIGenKeyCertPage extends WizardBasePanel implements IWizardPanel {
+ private JTextArea desc;
+ private String mPanelName;
+ protected String mHelpIndex;
+
+ WIGenKeyCertPage(String panelName) {
+ super(panelName);
+ mPanelName = panelName;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ setBorder(makeTitledBorder(mPanelName));
+
+ String str = mResource.getString(mPanelName+"_TEXT_NEWKEY_LABEL");
+ desc.setText(str);
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ NameValuePairs nvps = wizardInfo.getAllCertInfo();
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_CREATE_CERT;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ rawData = rawData+"&"+ConfigConstants.PR_HASH_TYPE+"="+wizardInfo.getHashType();
+ if (wizardInfo.getCertType().equals(Constants.PR_CA_SIGNING_CERT)) {
+ String OComp = wizardInfo.getCAOComp();
+ if (OComp != null && !OComp.equals("")) {
+ rawData = rawData+"&"+ConfigConstants.PR_CA_O_COMPONENT+"="+
+ wizardInfo.getCAOComp();
+ }
+ String CComp = wizardInfo.getCACComp();
+ if (CComp != null && !CComp.equals(""))
+ rawData = rawData+"&"+ConfigConstants.PR_CA_C_COMPONENT+"="+
+ wizardInfo.getCACComp();
+ }
+
+ // testing, please remove after finish testing
+ if (wizardInfo.getInternalDBPasswd() != null)
+ rawData = rawData+"&"+ConfigConstants.PR_DB_PWD+"="+wizardInfo.getInternalDBPasswd();
+
+ if (nvps != null) {
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name);
+ rawData = rawData+"&"+name+"="+value;
+ }
+ }
+
+ startProgressStatus();
+
+ //CMSMessageBox dlg = new CMSMessageBox(mAdminFrame, "CGITASK", "CREATECERT");
+
+ boolean ready = send(rawData, wizardInfo);
+
+ //dlg.setVisible(false);
+
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage();
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ mPanelName+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(mHelpIndex);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+/*
+ desc = new JTextArea(2, 80);
+ desc.setBackground(getBackground());
+ desc.setEditable(false);
+ desc.setCaretColor(getBackground());
+*/
+ desc = createTextArea("");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIGenKeyCertReqPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenKeyCertReqPage.java
new file mode 100644
index 000000000..b5c0378c3
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenKeyCertReqPage.java
@@ -0,0 +1,291 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Generate the certificate request
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIGenKeyCertReqPage extends WizardBasePanel implements IWizardPanel {
+ private JTextArea desc;
+ private String mPanelName;
+ private static final String CERTREQ_BEGIN_HEADING =
+ "-----BEGIN NEW CERTIFICATE REQUEST-----";
+ private static final String CERTREQ_END_HEADING =
+ "-----END NEW CERTIFICATE REQUEST-----";
+ private static final int LINE_COUNT = 76;
+ protected String mHelpIndex;
+ protected String mTokenName;
+
+ protected JRadioButton mPKCS10;
+ protected JRadioButton mCMC;
+ protected String mSigningCert = null;
+
+ WIGenKeyCertReqPage(String panelName) {
+ super(panelName);
+ mPanelName = panelName;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ setBorder(makeTitledBorder(mPanelName));
+
+ String str = mResource.getString(mPanelName+"_TEXT_NEWKEY_LABEL");
+ desc.setText(str);
+ // check subject key identifier to enable cmc or not
+ NameValuePairs nvps =
+ (NameValuePairs)wizardInfo.get(wizardInfo.ALL_CERT_INFO);
+ if (nvps != null) {
+ str = (String)nvps.get(Constants.PR_SKI);
+ if (str != null && str.equals(ConfigConstants.TRUE)) {
+ mCMC.setEnabled(true);
+ mCMC.setVisible(true);
+ mPKCS10.setVisible(true);
+ } else if (str == null || str.equals(ConfigConstants.FALSE)){
+ mCMC.setEnabled(false);
+ mCMC.setVisible(false);
+ mPKCS10.setVisible(false);
+ }
+ CMSAdminUtil.repaintComp(mCMC);
+ CMSAdminUtil.repaintComp(mPKCS10);
+ }
+ // check if a signing cert installed
+ String type = wizardInfo.getCertType();
+ if (!mCMC.isEnabled() &&
+ (type.equals(Constants.PR_SERVER_CERT) ||
+ type.equals(Constants.PR_KRA_TRANSPORT_CERT)) ) {
+ if (wizardInfo.isCAInstalled() &&
+ wizardInfo.isCACertInstalledDone()) {
+ mSigningCert = Constants.PR_CA_SIGNING_CERT;
+ mCMC.setEnabled(true);
+ mCMC.setVisible(true);
+ CMSAdminUtil.repaintComp(mCMC);
+ mPKCS10.setVisible(true);
+ CMSAdminUtil.repaintComp(mPKCS10);
+ } else if (wizardInfo.isRAInstalled() &&
+ wizardInfo.isRACertInstalledDone()) {
+ mSigningCert = Constants.PR_RA_SIGNING_CERT;
+ mCMC.setEnabled(true);
+ mCMC.setVisible(true);
+ CMSAdminUtil.repaintComp(mCMC);
+ mPKCS10.setVisible(true);
+ CMSAdminUtil.repaintComp(mPKCS10);
+ } else if (wizardInfo.isKRAInstalled() &&
+ wizardInfo.isKRACertInstalledDone()) {
+ mSigningCert = Constants.PR_KRA_TRANSPORT_CERT;
+ mCMC.setEnabled(true);
+ mCMC.setVisible(true);
+ CMSAdminUtil.repaintComp(mCMC);
+ mPKCS10.setVisible(true);
+ CMSAdminUtil.repaintComp(mPKCS10);
+ } else if (wizardInfo.isOCSPInstalled() &&
+ wizardInfo.isOCSPCertInstalledDone()) {
+ mSigningCert = Constants.PR_OCSP_SIGNING_CERT;
+ mCMC.setEnabled(true);
+ mCMC.setVisible(true);
+ CMSAdminUtil.repaintComp(mCMC);
+ mPKCS10.setVisible(true);
+ CMSAdminUtil.repaintComp(mPKCS10);
+ }
+ }
+
+ if (type.equals(Constants.PR_OCSP_SIGNING_CERT)) {
+ mCMC.setEnabled(false);
+ mCMC.setVisible(false);
+ CMSAdminUtil.repaintComp(mCMC);
+ mPKCS10.setVisible(false);
+ CMSAdminUtil.repaintComp(mPKCS10);
+ }
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_CERT_REQUEST;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+
+ if (wizardInfo.getSubjectName() == null) {
+ setErrorMessage("Subject Name is not available. Please redo all the request generation procedure. ");
+ return false;
+ }
+ rawData = rawData+"&"+Constants.PR_SUBJECT_NAME+"="+wizardInfo.getSubjectName();
+ if (mTokenName == null) {
+ setErrorMessage("Token Name is not available. Please redo all the request generation procedure. ");
+ return false;
+ }
+ rawData = rawData+"&"+Constants.PR_TOKEN_NAME+"="+mTokenName;
+ if (wizardInfo.getKeyLength() == null) {
+ setErrorMessage("Key Length is not available. Please redo all the request generation procedure. ");
+ return false;
+ }
+ rawData = rawData+"&"+Constants.PR_KEY_LENGTH+"="+wizardInfo.getKeyLength();
+ if (wizardInfo.getKeyType() == null) {
+ setErrorMessage("Key Type is not available. Please redo all the request generation procedure. ");
+ return false;
+ }
+ rawData = rawData+"&"+Constants.PR_KEY_TYPE+"="+wizardInfo.getKeyType();
+ if (wizardInfo.getCertType() == null) {
+ setErrorMessage("CertType is not available. Please redo all the request generation procedure. ");
+ return false;
+ }
+ rawData = rawData+"&"+Constants.PR_CERTIFICATE_TYPE+"="+wizardInfo.getCertType();
+
+ NameValuePairs nvps = wizardInfo.getAllCertInfo();//extensions
+ if (nvps != null) {
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name);
+ if (name != null && value != null)
+ rawData = rawData+"&"+name+"="+value;
+ }
+ }
+
+ if (mSigningCert != null) {
+ rawData = rawData+"&"+"signing_cert="+mSigningCert;
+ }
+
+ if (mPKCS10.isSelected()) {
+ rawData = rawData+"&"+wizardInfo.getCertType()+ConfigConstants.PR_REQUEST_FORMAT+
+ "="+ConfigConstants.PR_REQUEST_PKCS10;
+ } else if (mCMC.isSelected()) {
+ rawData = rawData+"&"+wizardInfo.getCertType()+ConfigConstants.PR_REQUEST_FORMAT+"="+ConfigConstants.PR_REQUEST_CMC;
+ }
+
+ startProgressStatus();
+ //CMSMessageBox dlg = new CMSMessageBox(mAdminFrame, "CGITASK", "CREATEREQ");
+ boolean ready = send(rawData, wizardInfo);
+ if (ready) {
+ String pkcs = wizardInfo.getCertRequest();
+ wizardInfo.setCertRequest(reformat(pkcs));
+ }
+ //dlg.setVisible(false);
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage();
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ mPanelName+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ private String reformat(String pkcs) {
+ int beginIndex = CERTREQ_BEGIN_HEADING.length();
+ int endIndex = CERTREQ_END_HEADING.length();
+ int totalLen = pkcs.length();
+ String content = pkcs.substring(beginIndex, totalLen-endIndex);
+ String result = CERTREQ_BEGIN_HEADING+"\n";
+ int index = 0;
+ while (content.length() >= LINE_COUNT) {
+ result = result+content.substring(0, LINE_COUNT)+"\n";
+ content = content.substring(LINE_COUNT);
+ }
+ if (content.length() > 0) {
+ result = result+content+"\n"+CERTREQ_END_HEADING;
+ } else {
+ result = result+CERTREQ_END_HEADING;
+ }
+
+ return result;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(mHelpIndex);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+/*
+ desc = new JTextArea(2, 80);
+ desc.setBackground(getBackground());
+ desc.setEditable(false);
+ desc.setCaretColor(getBackground());
+*/
+ desc = createTextArea("");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ //gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ mPKCS10 = makeJRadioButton("PKCS10", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mPKCS10, gbc);
+
+ mCMC = makeJRadioButton("CMC", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mCMC, gbc);
+
+ ButtonGroup group = new ButtonGroup();
+ group.add(mCMC);
+ group.add(mPKCS10);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel d1 = new JLabel(" ");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(d1, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIGenOCSPKeyCertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenOCSPKeyCertPage.java
new file mode 100644
index 000000000..2e2fbdbed
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenOCSPKeyCertPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Generate the OCSP signing certificate
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WIGenOCSPKeyCertPage extends WIGenKeyCertPage {
+ private static final String PANELNAME = "INSTALLGENOCSPWIZARD";
+ private static final String OCSPHELPINDEX = "install-ocspcert-creation-wizard-help";
+
+ WIGenOCSPKeyCertPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIGenOCSPKeyCertPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+Debug.println("+++++++++++++++++++++++++++++=WIGenOCSPKeyCertPage ");
+ if (!wizardInfo.isOCSPInstalled())
+ return false;
+
+ mHelpIndex = OCSPHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIGenOCSPKeyCertReqPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenOCSPKeyCertReqPage.java
new file mode 100644
index 000000000..7c27f673d
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenOCSPKeyCertReqPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Generate the OCSP signing certificate request
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIGenOCSPKeyCertReqPage extends WIGenKeyCertReqPage {
+ private static final String PANELNAME = "INSTALLGENOCSPCERTREQWIZARD";
+ private static final String OCSPHELPINDEX = "install-ocspcert-request-wizard-help";
+
+ WIGenOCSPKeyCertReqPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIGenOCSPKeyCertReqPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isOCSPCloningDone())
+ return false;
+
+ if (wizardInfo.isOCSPCertLocalCA() || !wizardInfo.isOCSPInstalled() ||
+ (wizardInfo.isOCSPCertRequestDone() &&
+ !wizardInfo.isOCSPCertRequestBack()) ||
+ wizardInfo.isOCSPLocalCertDone() ||
+ wizardInfo.isOCSPCertInstalledDone())
+ return false;
+
+ if (wizardInfo.isOCSPCertRequestBack()) {
+ wizardInfo.put(ConfigConstants.STAGE_OCSP_CERT_REQUEST,
+ ConfigConstants.FALSE);
+ wizardInfo.put(ConfigConstants.OCSP_CERT_REQUEST_BACK,
+ ConfigConstants.FALSE);
+ }
+
+ mHelpIndex = OCSPHELPINDEX;
+
+ mTokenName = wizardInfo.getOCSPTokenName();
+ wizardInfo.setCertType(Constants.PR_OCSP_SIGNING_CERT);
+ wizardInfo.setNewRequest();
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIGenRAKeyCertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenRAKeyCertPage.java
new file mode 100644
index 000000000..05859e54c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenRAKeyCertPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Generate the RA signing certificate
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WIGenRAKeyCertPage extends WIGenKeyCertPage {
+ private static final String PANELNAME = "INSTALLGENRAWIZARD";
+ private static final String RAHELPINDEX = "install-racert-creation-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakracert-creation-wizard-help";
+
+ WIGenRAKeyCertPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIGenRAKeyCertPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isRACloningDone())
+ return false;
+ if (!wizardInfo.isRACertLocalCA() || !wizardInfo.isRAInstalled() ||
+ wizardInfo.isRALocalCertDone() || wizardInfo.isRACertRequestDone() ||
+ wizardInfo.isRACertInstalledDone())
+ return false;
+
+ if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = RAHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIGenRAKeyCertReqPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenRAKeyCertReqPage.java
new file mode 100644
index 000000000..89aa21f14
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenRAKeyCertReqPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Generate the RA signing certificate request
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIGenRAKeyCertReqPage extends WIGenKeyCertReqPage {
+ private static final String PANELNAME = "INSTALLGENRACERTREQWIZARD";
+ private static final String RAHELPINDEX = "install-racert-request-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakracert-request-wizard-help";
+
+ WIGenRAKeyCertReqPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIGenRAKeyCertReqPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isRACloningDone())
+ return false;
+ if (wizardInfo.isRACertLocalCA() || !wizardInfo.isRAInstalled() ||
+ (wizardInfo.isRACertRequestDone() &&
+ !wizardInfo.isRACertRequestBack()) ||
+ wizardInfo.isRALocalCertDone() ||
+ wizardInfo.isRACertInstalledDone())
+ return false;
+
+ if (wizardInfo.isRACertRequestBack()) {
+ wizardInfo.put(ConfigConstants.STAGE_RA_CERT_REQUEST,
+ ConfigConstants.FALSE);
+ wizardInfo.put(ConfigConstants.RA_CERT_REQUEST_BACK,
+ ConfigConstants.FALSE);
+ }
+
+ if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = RAHELPINDEX;
+
+ mTokenName = wizardInfo.getRATokenName();
+ wizardInfo.setCertType(Constants.PR_RA_SIGNING_CERT);
+ wizardInfo.setNewRequest();
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIGenSSLKeyCertReqPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenSSLKeyCertReqPage.java
new file mode 100644
index 000000000..58a85f790
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenSSLKeyCertReqPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Generate the SSL server certificate request
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIGenSSLKeyCertReqPage extends WIGenKeyCertReqPage {
+ private static final String PANELNAME = "INSTALLGENSSLCERTREQWIZARD";
+ private static final String HELPINDEX = "install-sslcert-request-wizard-help";
+
+ WIGenSSLKeyCertReqPage(JDialog parent) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = parent;
+ }
+
+ WIGenSSLKeyCertReqPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning())
+ return false;
+ if (wizardInfo.isSSLCertLocalCA() || wizardInfo.isMigrationEnable() ||
+ (wizardInfo.isSSLCertRequestDone() &&
+ !wizardInfo.isSSLCertRequestBack()) ||
+ wizardInfo.isSSLLocalCertDone() ||
+ wizardInfo.isSSLCertInstalledDone())
+ return false;
+
+
+ if (wizardInfo.isSSLCertRequestBack()) {
+ wizardInfo.put(ConfigConstants.STAGE_SSL_CERT_REQUEST,
+ ConfigConstants.FALSE);
+ wizardInfo.put(ConfigConstants.SSL_CERT_REQUEST_BACK,
+ ConfigConstants.FALSE);
+ }
+
+ mTokenName = wizardInfo.getSSLTokenName();
+ wizardInfo.setCertType(Constants.PR_SERVER_CERT);
+ wizardInfo.setNewRequest();
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIGenServerKeyCertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenServerKeyCertPage.java
new file mode 100644
index 000000000..e93c378f6
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIGenServerKeyCertPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Generate the SSL server certificate
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WIGenServerKeyCertPage extends WIGenKeyCertPage {
+ private static final String PANELNAME = "INSTALLGENSSLWIZARD";
+ private static final String HELPINDEX = "install-sslcert-creation-wizard-help";
+
+ WIGenServerKeyCertPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIGenServerKeyCertPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning())
+ return false;
+ if (!wizardInfo.isSSLCertLocalCA() || wizardInfo.isMigrationEnable() ||
+ wizardInfo.isSSLLocalCertDone() || wizardInfo.isSSLCertRequestDone() ||
+ wizardInfo.isSSLCertInstalledDone())
+ return false;
+
+ mHelpIndex = HELPINDEX;
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallCACertStatusPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallCACertStatusPage.java
new file mode 100644
index 000000000..d26b79ab0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallCACertStatusPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import javax.swing.*;
+
+/**
+ * The panel asks the user to paste the certificate.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIInstallCACertStatusPage extends WIInstallCertStatusPage {
+ private static final String PANELNAME = "INSTALLCACERTSTATUSWIZARD";
+ private static final String CAHELPINDEX = "install-cacert-status-wizard-help";
+ private static final String CAKRAHELPINDEX = "install-cakracert-status-wizard-help";
+
+ WIInstallCACertStatusPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIInstallCACertStatusPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isCACloningDone())
+ return false;
+ if (wizardInfo.isCACertLocalCA() || !wizardInfo.isCACertInstalledDone() ||
+ !wizardInfo.isCAInstalled() || wizardInfo.isMigrationEnable() ||
+ wizardInfo.isCACertChainImportDone())
+ return false;
+
+ if (wizardInfo.hasEntireCAChain())
+ return false;
+
+ wizardInfo.setCertType(Constants.PR_CA_SIGNING_CERT);
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else
+ mHelpIndex = CAHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+}
+
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallCAIntroPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallCAIntroPage.java
new file mode 100644
index 000000000..033897c79
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallCAIntroPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import javax.swing.*;
+
+/**
+ * The panel asks if the user wants to install the CA certificate now.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIInstallCAIntroPage extends WIInstallIntroPage {
+ private static final String PANELNAME = "INSTALLCAINTROWIZARD";
+ private static final String CAHELPINDEX = "install-cacert-installintro-wizard-help";
+ private static final String CAKRAHELPINDEX = "install-cakracert-installintro-wizard-help";
+
+ WIInstallCAIntroPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIInstallCAIntroPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isCACloningDone())
+ return false;
+
+ if (wizardInfo.isCACertLocalCA() || !wizardInfo.isCAInstalled() ||
+ wizardInfo.isMigrationEnable() || wizardInfo.isCACertInstalledDone())
+ return false;
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else
+ mHelpIndex = CAHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallCert1Page.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallCert1Page.java
new file mode 100644
index 000000000..240134536
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallCert1Page.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * This page is to install the certificate in the internal token. The user can
+ * import the cert from the file or paste the Base 64 encoded blob in the
+ * text area.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIInstallCert1Page extends WizardBasePanel implements IWizardPanel {
+ private JRadioButton mFileBtn;
+ private JRadioButton mBase64Btn;
+ private JTextField mFileText;
+ private JTextArea mBase64Text;
+ private JButton mPaste;
+ private static final String PANELNAME = "INSTALLCERT1WIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WIInstallCert1Page() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ mFileBtn = makeJRadioButton("FILE", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mFileBtn, gbc);
+
+ mFileText = makeJTextField(50);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE, 0);
+ add(mFileText, gbc);
+
+ mBase64Btn = makeJRadioButton("BASE64", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mBase64Btn, gbc);
+
+ JTextArea desc = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "INSTALLCERT1WIZARD_TEXT_DESC_LABEL"), 80), 2, 80);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ mPaste = makeJButton("PASTE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mPaste, gbc);
+
+ mBase64Text = new JTextArea(null, null, 0, 0);
+ mBase64Text.setLineWrap(true);
+ mBase64Text.setWrapStyleWord(true);
+ JScrollPane scrollPane = new JScrollPane(mBase64Text,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ scrollPane.setPreferredSize(new Dimension(50, 20));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(scrollPane, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ add(dummy, gbc);
+
+ ButtonGroup buttonGrp = new ButtonGroup();
+ buttonGrp.add(mFileBtn);
+ buttonGrp.add(mBase64Btn);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallCert2Page.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallCert2Page.java
new file mode 100644
index 000000000..fc9eaacb0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallCert2Page.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 com.netscape.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * This page is to install the certificate in the internal token. It
+ * displays the certificate information.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIInstallCert2Page extends WizardBasePanel implements IWizardPanel {
+ private JButton mAdd;
+ private static final String PANELNAME = "INSTALLCERT2WIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WIInstallCert2Page() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JLabel subjectDNLbl = makeJLabel("SUBJECTDN");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(subjectDNLbl, gbc);
+
+ JLabel issuerLbl = makeJLabel("ISSUE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(issuerLbl, gbc);
+
+ JTextArea subjectText = new JTextArea(null, null, 0, 0);
+ JScrollPane subjectScrollPane = new JScrollPane(subjectText,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ //subjectScrollPane.setPreferredSize(new Dimension(50, 30));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE, 0 );
+ gbc.weighty = 1.0;
+ gbc.weightx = 1.0;
+ gbc.fill = gbc.BOTH;
+ add(subjectScrollPane, gbc);
+
+ JTextArea issueText = new JTextArea(null, null, 0, 0);
+ JScrollPane issueScrollPane = new JScrollPane(issueText,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ //issueScrollPane.setPreferredSize(new Dimension(50, 30));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weighty = 1.0;
+ gbc.weightx = 1.0;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(issueScrollPane, gbc);
+
+ JTextArea infoText = new JTextArea(null, null, 0, 0);
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ infoText.setPreferredSize(new Dimension(50, 20));
+ gbc.fill = gbc.BOTH;
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(infoText, gbc);
+
+ mAdd = makeJButton("ADD");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mAdd, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallCertStatusPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallCertStatusPage.java
new file mode 100644
index 000000000..860e5b60e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallCertStatusPage.java
@@ -0,0 +1,248 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.io.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * Status page of certificate installation.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIInstallCertStatusPage extends WizardBasePanel implements IWizardPanel {
+ private Color mActiveColor;
+ private JTextArea desc;
+ private JRadioButton mFileBtn;
+ private JRadioButton mBase64Btn;
+ private String mPanelName;
+ protected JTextArea mBase64Text;
+ private JTextField mFileText;
+ protected JButton mPaste;
+ protected String mHelpIndex;
+ protected String mCertChain;
+ protected String mCertFilePath;
+
+ WIInstallCertStatusPage(String panelName) {
+ super(panelName);
+ mPanelName = panelName;
+ init();
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ setBorder(makeTitledBorder(mPanelName));
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String str = mResource.getString(mPanelName+"_TEXT_DESC_LABEL");
+ desc.setText(str);
+ return true;
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean validatePanel() {
+ if (mFileBtn.isSelected()) {
+ mCertFilePath = mFileText.getText().trim();
+ if (mCertFilePath.equals("")) {
+ setErrorMessage("EMPTYFILEFIELD");
+ return false;
+ }
+ } else if (mBase64Btn.isSelected()) {
+ mCertChain = mBase64Text.getText().trim();
+ if (mCertChain.equals("")) {
+ setErrorMessage("B64EEMPTY");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_IMPORT_CERT_CHAIN;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_READ;
+ if (mFileBtn.isSelected()) {
+ rawData = rawData+"&"+Constants.PR_CERT_FILEPATH+"="+mCertFilePath;
+ } else if (mBase64Btn.isSelected()) {
+ rawData = rawData+"&"+ConfigConstants.PR_CERT_CHAIN+"="+mCertChain;
+ }
+
+ rawData = rawData+"&"+Constants.PR_CERTIFICATE_TYPE+"="+wizardInfo.getCertType();
+
+ startProgressStatus();
+ boolean ready = send(rawData, wizardInfo);
+ endProgressStatus();
+ if (!ready) {
+ String str = getErrorMessage();
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ mPanelName+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else if (str.equals("incompleteCertChain")) {
+ String errormsg = mResource.getString(mPanelName+"_INCOMPLETECERTCHAIN");
+ int status = JOptionPane.showConfirmDialog(mAdminFrame, errormsg, "Information",
+ JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_INFO_ICON));
+ if (status == JOptionPane.OK_OPTION) {
+ rawData = rawData+"&"+ConfigConstants.NOT_IMPORT_CHAIN+"="+
+ ConfigConstants.TRUE;
+ ready = send(rawData, wizardInfo);
+ return true;
+ } else {
+ setErrorMessage(mResource.getString(mPanelName+"_ERROR1"));
+ return false;
+ }
+ } else
+ setErrorMessage(str);
+ }
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(mHelpIndex);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ desc = createTextArea("");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ //gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ mFileBtn = makeJRadioButton("FILE", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mFileBtn, gbc);
+
+ mFileText = makeJTextField(50);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE, COMPONENT_SPACE, 0);
+ add(mFileText, gbc);
+ mActiveColor = mFileText.getBackground();
+
+ mBase64Btn = makeJRadioButton("BASE64", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mBase64Btn, gbc);
+
+ ButtonGroup btngroup = new ButtonGroup();
+ btngroup.add(mFileBtn);
+ btngroup.add(mBase64Btn);
+
+ JTextArea desc1 = createTextArea(mResource.getString(
+ mPanelName+"_TEXT_DESC1_LABEL"));
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,4*COMPONENT_SPACE,0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc1, gbc);
+
+ mBase64Text = new JTextArea(null, null, 0, 0);
+ JScrollPane scrollPane = new JScrollPane(mBase64Text,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ scrollPane.setPreferredSize(new Dimension(50, 20));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(scrollPane, gbc);
+
+ mPaste = makeJButton("PASTE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mPaste, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ add(dummy, gbc);
+
+ enableFields(mFileText, true, mActiveColor);
+ enableFields(mBase64Text, false, getBackground());
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mPaste)) {
+ mBase64Text.paste();
+ } else if (e.getSource().equals(mFileBtn)) {
+ enableFields(mFileText, true, mActiveColor);
+ enableFields(mBase64Text, false, getBackground());
+ } else if (e.getSource().equals(mBase64Btn)) {
+ enableFields(mFileText, false, getBackground());
+ enableFields(mBase64Text, true, mActiveColor);
+ }
+ }
+
+ private void enableFields(JTextComponent comp1, boolean enable, Color color) {
+ comp1.setEnabled(enable);
+ comp1.setEditable(enable);
+ comp1.setBackground(color);
+ CMSAdminUtil.repaintComp(comp1);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallIntroPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallIntroPage.java
new file mode 100644
index 000000000..29ddd0a46
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallIntroPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * Setup Single Signon for the installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIInstallIntroPage extends WizardBasePanel implements IWizardPanel {
+ protected JRadioButton mYes;
+ protected JRadioButton mNo;
+ protected String mPanelName;
+ protected String mHelpIndex;
+
+ WIInstallIntroPage(String panelName) {
+ super(panelName);
+ mPanelName = panelName;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ setBorder(makeTitledBorder(mPanelName));
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(mHelpIndex);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea heading = createTextArea(mResource.getString(
+ mPanelName+"_TEXT_HEADING_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(heading, gbc);
+
+ mNo = makeJRadioButton("NO", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mNo, gbc);
+
+ mYes = makeJRadioButton("YES", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(0,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mYes, gbc);
+
+ JLabel dummy = new JLabel("");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(dummy, gbc);
+
+ ButtonGroup buttonGrp = new ButtonGroup();
+ buttonGrp.add(mYes);
+ buttonGrp.add(mNo);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (mNo.isSelected())
+ wizardInfo.setInstallCertNow(Constants.FALSE);
+ else
+ wizardInfo.setInstallCertNow(Constants.TRUE);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallKRACertStatusPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallKRACertStatusPage.java
new file mode 100644
index 000000000..d33601151
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallKRACertStatusPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import javax.swing.*;
+
+/**
+ * The panel asks the user to paste the certificate.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIInstallKRACertStatusPage extends WIInstallCertStatusPage {
+ private static final String PANELNAME = "INSTALLKRACERTSTATUSWIZARD";
+ private static final String KRAHELPINDEX = "install-kracert-status-wizard-help";
+ private static final String CAKRAHELPINDEX = "install-cakra-kracert-status-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakra-kracert-status-wizard-help";
+
+ WIInstallKRACertStatusPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIInstallKRACertStatusPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isKRACloningDone())
+ return false;
+ if (wizardInfo.isKRACertLocalCA() || !wizardInfo.isKRACertInstalledDone() ||
+ !wizardInfo.isKRAInstalled() || wizardInfo.isKRACertChainImportDone())
+ return false;
+
+ if (wizardInfo.hasEntireKRAChain())
+ return false;
+
+ wizardInfo.setCertType(Constants.PR_KRA_TRANSPORT_CERT);
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = KRAHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+}
+
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallKRAIntroPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallKRAIntroPage.java
new file mode 100644
index 000000000..cba792c1c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallKRAIntroPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import javax.swing.*;
+
+/**
+ * The panel asks if the user wants to install the KR certificate now.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIInstallKRAIntroPage extends WIInstallIntroPage {
+ private static final String PANELNAME = "INSTALLKRAINTROWIZARD";
+ private static final String KRAHELPINDEX = "install-kracert-installintro-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakra-kracert-installintro-wizard-help";
+ private static final String CAKRAHELPINDEX = "install-cakra-kracert-installintro-wizard-help";
+
+
+ WIInstallKRAIntroPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIInstallKRAIntroPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isKRACloningDone())
+ return false;
+ if (wizardInfo.isKRACertLocalCA() || !wizardInfo.isKRAInstalled() ||
+ wizardInfo.isKRACertInstalledDone())
+ return false;
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = KRAHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallOCSPCertStatusPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallOCSPCertStatusPage.java
new file mode 100644
index 000000000..c98b7b045
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallOCSPCertStatusPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import javax.swing.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * The panel asks the user to paste the certificate.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIInstallOCSPCertStatusPage extends WIInstallCertStatusPage {
+ private static final String PANELNAME = "INSTALLOCSPCERTSTATUSWIZARD";
+ private static final String OCSPHELPINDEX = "install-ocspcert-status-wizard-help";
+
+ WIInstallOCSPCertStatusPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIInstallOCSPCertStatusPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isOCSPCloningDone())
+ return false;
+
+ if (wizardInfo.isOCSPCertLocalCA() || !wizardInfo.isOCSPCertInstalledDone() ||
+ !wizardInfo.isOCSPInstalled() || wizardInfo.isOCSPCertChainImportDone())
+ return false;
+
+ if (wizardInfo.hasEntireOCSPChain())
+ return false;
+
+ wizardInfo.setCertType(Constants.PR_OCSP_SIGNING_CERT);
+
+ mHelpIndex = OCSPHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+}
+
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallOCSPIntroPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallOCSPIntroPage.java
new file mode 100644
index 000000000..96c843e57
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallOCSPIntroPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import javax.swing.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * The panel asks if the user wants to install the RA certificate now.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIInstallOCSPIntroPage extends WIInstallIntroPage {
+
+ private static final String PANELNAME = "INSTALLOCSPINTROWIZARD";
+ private static final String OCSPHELPINDEX = "install-ocspcert-installintro-wizard-help";
+
+ WIInstallOCSPIntroPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIInstallOCSPIntroPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ if (wizardInfo.isCloning() && wizardInfo.isOCSPCloningDone())
+ return false;
+ if (wizardInfo.isOCSPCertLocalCA() || !wizardInfo.isOCSPInstalled() ||
+ wizardInfo.isOCSPCertInstalledDone())
+ return false;
+
+ mHelpIndex = OCSPHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallRACertStatusPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallRACertStatusPage.java
new file mode 100644
index 000000000..326f5067a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallRACertStatusPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import javax.swing.*;
+
+/**
+ * The panel asks the user to paste the certificate.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIInstallRACertStatusPage extends WIInstallCertStatusPage {
+ private static final String PANELNAME = "INSTALLRACERTSTATUSWIZARD";
+ private static final String RAHELPINDEX = "install-racert-status-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakracert-status-wizard-help";
+
+ WIInstallRACertStatusPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIInstallRACertStatusPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isRACloningDone())
+ return false;
+ if (wizardInfo.isRACertLocalCA() || !wizardInfo.isRACertInstalledDone() ||
+ !wizardInfo.isRAInstalled() || wizardInfo.isRACertChainImportDone())
+ return false;
+
+ if (wizardInfo.hasEntireRAChain())
+ return false;
+
+ wizardInfo.setCertType(Constants.PR_RA_SIGNING_CERT);
+
+ if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = RAHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+}
+
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallRAIntroPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallRAIntroPage.java
new file mode 100644
index 000000000..d3d48492c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallRAIntroPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import javax.swing.*;
+
+/**
+ * The panel asks if the user wants to install the RA certificate now.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIInstallRAIntroPage extends WIInstallIntroPage {
+ private static final String PANELNAME = "INSTALLRAINTROWIZARD";
+ private static final String RAHELPINDEX = "install-racert-installintro-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakracert-installintro-wizard-help";
+
+ WIInstallRAIntroPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIInstallRAIntroPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isRACloningDone())
+ return false;
+ if (wizardInfo.isRACertLocalCA() || !wizardInfo.isRAInstalled() ||
+ wizardInfo.isRACertInstalledDone())
+ return false;
+
+ if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = RAHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallSSLCertStatusPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallSSLCertStatusPage.java
new file mode 100644
index 000000000..27ca1755f
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallSSLCertStatusPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import javax.swing.*;
+
+/**
+ * The panel asks the user to paste the certificate.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIInstallSSLCertStatusPage extends WIInstallCertStatusPage {
+ private static final String PANELNAME = "INSTALLSSLCERTSTATUSWIZARD";
+ private static final String HELPINDEX = "install-sslcert-status-wizard-help";
+
+ WIInstallSSLCertStatusPage(JDialog parent) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = parent;
+ }
+
+ WIInstallSSLCertStatusPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning())
+ return false;
+ if (wizardInfo.isSSLCertLocalCA() || !wizardInfo.isSSLCertInstalledDone() ||
+ wizardInfo.isMigrationEnable() || wizardInfo.isSSLCertChainImportDone())
+ return false;
+
+ if (wizardInfo.hasEntireSSLChain())
+ return false;
+
+ wizardInfo.setCertType(Constants.PR_SERVER_CERT);
+
+ return super.initializePanel(info);
+ }
+}
+
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallSSLIntroPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallSSLIntroPage.java
new file mode 100644
index 000000000..7115f96bf
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIInstallSSLIntroPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import javax.swing.*;
+
+/**
+ * The panel asks if the user wants to install the SSL certificate now.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIInstallSSLIntroPage extends WIInstallIntroPage {
+ private static final String PANELNAME = "INSTALLSSLINTROWIZARD";
+ private static final String HELPINDEX = "install-sslcert-installintro-wizard-help";
+
+ WIInstallSSLIntroPage(JDialog parent) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = parent;
+ }
+
+ WIInstallSSLIntroPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning())
+ return false;
+
+ if (wizardInfo.isSSLCertLocalCA() || wizardInfo.isMigrationEnable() ||
+ wizardInfo.isSSLCertInstalledDone())
+ return false;
+
+ return super.initializePanel(info);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIInternalDBInfoPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIInternalDBInfoPage.java
new file mode 100644
index 000000000..5338e820d
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIInternalDBInfoPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * This panel asks for the information of the current internal database.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIInternalDBInfoPage extends WizardBasePanel implements IWizardPanel {
+ private JTextField mBindAsText;
+ private JPasswordField mPasswordText;
+ private JLabel mBindAsLabel, mPasswordLabel;
+
+ private static final String PANELNAME = "INTERNALDBINFOWIZARD";
+ private static final String HELPINDEX =
+ "install-internaldb-logon-wizard-help";
+
+ WIInternalDBInfoPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIInternalDBInfoPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.getInternalDBPasswd() != null)
+ return false;
+ setBorder(makeTitledBorder(PANELNAME));
+ mBindAsText.setText(wizardInfo.getDBBindDN());
+ return true;
+ }
+
+ public boolean validatePanel() {
+ String passwd = mPasswordText.getText();
+ if (passwd.equals("")) {
+ setErrorMessage("BLANKPASSWD");
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ wizardInfo.setDBBindDN(mBindAsText.getText().trim());
+ wizardInfo.setInternalDBPasswd(mPasswordText.getText().trim());
+
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_VALIDATE_DSPASSWD;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ rawData = rawData+"&"+ConfigConstants.PR_DB_PWD+"="+wizardInfo.getInternalDBPasswd();
+ rawData = rawData+"&"+ConfigConstants.PR_DB_BINDDN+"="+wizardInfo.getDBBindDN();
+
+ startProgressStatus();
+
+ boolean ready = send(rawData, wizardInfo);
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage(wizardInfo);
+ if (str.equals(""))
+ setErrorMessage("Server Error");
+ else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea desc = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mBindAsLabel = makeJLabel("ADMIN");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mBindAsLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mBindAsText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mBindAsText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPasswordLabel = makeJLabel("PWD");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mPasswordLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPasswordText = makeJPasswordField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ // gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mPasswordText, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIInternalDBPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIInternalDBPage.java
new file mode 100644
index 000000000..936d252d8
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIInternalDBPage.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.admin.certsrv.config.install;
+
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Introduction page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIInternalDBPage extends WizardBasePanel implements IWizardPanel {
+ private Color mActiveColor;
+
+ private JCheckBox mSchema;
+ private JTextField mRMPortText, mRMBindAsText, mRMBaseText;
+ private JTextField mRMHostText,mRMDBNameAsText;
+ private JPasswordField mRMPasswordText;
+ private JLabel mRMHostLabel, mRMDBNameAsLabel;
+ private JLabel mRMBaseLabel, mRMBindAsLabel, mRMPasswordLabel;
+
+ private static final String PANELNAME = "INTERNALDBWIZARD";
+ private static final String HELPINDEX =
+ "install-internaldb-configuration-wizard-help";
+ private static final String EMPTYSTR = " ";
+
+ WIInternalDBPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIInternalDBPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mSchema)) {
+ if (mSchema.isSelected()) {
+ mRMDBNameAsText.setEnabled(true);
+ mRMDBNameAsText.setBackground(mActiveColor);
+ } else {
+ mRMDBNameAsText.setEnabled(false);
+ mRMDBNameAsText.setBackground(getBackground());
+ }
+ } else {
+ super.actionPerformed(e);
+ }
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ if (wizardInfo.isCloning())
+ return false;
+ if (wizardInfo.isDBCreateNow()) {
+ setBorder(makeTitledBorder(PANELNAME));
+ mRMBaseText.setText("o="+wizardInfo.getDBName()+", o=netscapeCertificateServer");
+ mRMBindAsText.setText(wizardInfo.getDBBindDN());
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ cleanUpWizardInfo(wizardInfo);
+
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_CREATE_INTERNALDB;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ rawData = rawData+"&"+ConfigConstants.PR_CMS_SEED+"="+
+ (new Long(WizardBasePanel.mSeed).toString());
+ // remote database
+ rawData = rawData+"&"+ConfigConstants.PR_HOST+"="
+ +mRMHostText.getText();
+ rawData = rawData+"&"+ConfigConstants.PR_LDAP_DB_NAME+"="
+ +mRMDBNameAsText.getText();
+ rawData = rawData+"&"+ConfigConstants.PR_DB_PORT+"="+mRMPortText.getText();
+ rawData = rawData+"&"+ConfigConstants.PR_DB_BINDDN+"="+mRMBindAsText.getText();
+ rawData = rawData+"&"+ConfigConstants.PR_DB_NAME+"="+mRMBaseText.getText();
+ rawData = rawData+"&"+ConfigConstants.PR_DB_PWD+"="+mRMPasswordText.getText();
+ if (mSchema.isSelected()) {
+ rawData = rawData+"&"+ConfigConstants.PR_DB_SCHEMA+"="+"true";
+ } else {
+ rawData = rawData+"&"+ConfigConstants.PR_DB_SCHEMA+"="+"false";
+ }
+ wizardInfo.setInternalDBPasswd(mRMPasswordText.getText().trim());
+ wizardInfo.setDBBindDN(mRMBindAsText.getText().trim());
+ wizardInfo.setDBName(mRMBaseText.getText().trim());
+
+ startProgressStatus();
+ //CMSMessageBox dlg = new CMSMessageBox(mAdminFrame, "CGITASK", "CREATEDB");
+
+ boolean ready = send(rawData, wizardInfo);
+
+ if (ready) {
+ rawData = ConfigConstants.TASKID+"="+TaskId.TASK_TOKEN_INFO;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_READ;
+ ready = send(rawData, wizardInfo);
+ }
+ //dlg.setVisible(false);
+
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage(wizardInfo);
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ PANELNAME+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea desc = createTextArea(mResource.getString(
+ "INTERNALDBWIZARD_TEXT_HEADING_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel instanceIDLbl = makeJLabel("REMOTEHOST");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(instanceIDLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRMHostText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mRMHostText, gbc);
+
+ mActiveColor = mRMHostText.getBackground();
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel portNumber = makeJLabel("REMOTEPORT");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 0,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(portNumber, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRMPortText = makeJTextField(10);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(mRMPortText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRMBaseLabel = makeJLabel("REMOTEDN");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mRMBaseLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRMBaseText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mRMBaseText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRMBindAsLabel = makeJLabel("REMOTEADMIN");
+ //gbc.anchor = gbc.NORTHWEST;
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mRMBindAsLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRMBindAsText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mRMBindAsText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRMPasswordLabel = makeJLabel("REMOTEPWD");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mRMPasswordLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRMPasswordText = makeJPasswordField(30);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mRMPasswordText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRMDBNameAsLabel = makeJLabel("DATABASE");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mRMDBNameAsLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRMDBNameAsText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mRMDBNameAsText, gbc);
+
+ JLabel dummy1 = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(dummy1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mSchema = makeJCheckBox("SCHEMA", true);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mSchema, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ wizardInfo.setDBCreated(ConfigConstants.TRUE);
+ wizardInfo.setDBCreateNow(ConfigConstants.FALSE);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIInternalTokenLogonPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIInternalTokenLogonPage.java
new file mode 100644
index 000000000..3bc9bd2f3
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIInternalTokenLogonPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * This panel asks for the information of the current internal database.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIInternalTokenLogonPage extends WITokenLogonPage implements IWizardPanel {
+
+ private static final String HELPINDEX = "install-internaltoken-logon-wizard-help";
+ private static final String PANELNAME = "INTERNALTOKENLOGONWIZARD";
+
+ WIInternalTokenLogonPage(JDialog dialog) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = dialog;
+ }
+
+ WIInternalTokenLogonPage(JDialog dialog, JFrame adminFrame) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = dialog;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String pwd =
+ (String)wizardInfo.get("TOKEN:"+Constants.PR_INTERNAL_TOKEN_NAME);
+ if (pwd != null)
+ return false;
+
+ mTokenName = "Internal";
+ mTokenText.setText(Constants.PR_INTERNAL_TOKEN_NAME);
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIIntroMigrationPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIIntroMigrationPage.java
new file mode 100644
index 000000000..616911252
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIIntroMigrationPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * Data Migration.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIIntroMigrationPage extends WizardBasePanel implements IWizardPanel {
+ private JRadioButton mYes;
+ private JRadioButton mNo;
+ private static final String PANELNAME = "INTROMIGRATIONWIZARD";
+ private String mHelpIndex;
+ private static final String CAHELPINDEX =
+ "install-ca-migration-enable-wizard-help";
+ private static final String CAKRAHELPINDEX =
+ "install-cakra-migration-enable-wizard-help";
+
+ WIIntroMigrationPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIIntroMigrationPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (!wizardInfo.isCAInstalled() || wizardInfo.isMigrationDone())
+ return false;
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else
+ mHelpIndex = CAHELPINDEX;
+ setBorder(makeTitledBorder(PANELNAME));
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ Hashtable data = new Hashtable();
+
+ boolean ready = false;
+ if (mYes.isSelected()) {
+ wizardInfo.setEnableMigration(ConfigConstants.TRUE);
+ data.put(ConfigConstants.TASKID, TaskId.TASK_TOKEN_INFO);
+ data.put(ConfigConstants.OPTYPE, OpDef.OP_READ);
+ } else {
+ wizardInfo.setEnableMigration(ConfigConstants.FALSE);
+ // do the data migration
+ data.put(ConfigConstants.TASKID, TaskId.TASK_MIGRATION);
+ data.put(ConfigConstants.OPTYPE, OpDef.OP_MODIFY);
+ data.put(ConfigConstants.PR_ENABLE_MIGRATION,
+ ConfigConstants.FALSE);
+ }
+
+ startProgressStatus();
+
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage(wizardInfo);
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ PANELNAME+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(mHelpIndex);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea label = createTextArea(mResource.getString(
+ PANELNAME+"_LABEL_DESC_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(label, gbc);
+
+ mYes = makeJRadioButton("YES", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mYes, gbc);
+
+ mNo = makeJRadioButton("NO", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(0,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.weighty = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ add(mNo, gbc);
+
+ ButtonGroup group = new ButtonGroup();
+ group.add(mYes);
+ group.add(mNo);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIIntroPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIIntroPage.java
new file mode 100644
index 000000000..208a92cb8
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIIntroPage.java
@@ -0,0 +1,217 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Introduction page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIIntroPage extends WizardBasePanel implements IWizardPanel {
+ private JRadioButton mDbButton;
+ private JRadioButton mNetworkButton;
+ private JRadioButton mAdminButton;
+ private JRadioButton mSubsystemButton;
+ private JRadioButton mMigrationButton;
+ private JTextArea mLabel;
+ private static final String PANELNAME = "INTROINSTALLWIZARD";
+ private static final String HELPINDEX =
+ "install-general-intro-wizard-help";
+
+ WIIntroPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIIntroPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ setBorder(makeTitledBorder(PANELNAME));
+ mAdminFrame = wizardInfo.getAdminFrame();
+ mLabel.setVisible(false);
+ mDbButton.setVisible(false);
+ mNetworkButton.setVisible(false);
+ mAdminButton.setVisible(false);
+ mSubsystemButton.setVisible(false);
+ mMigrationButton.setVisible(false);
+ String stages = wizardInfo.getStages();
+
+ if (stages != null && !stages.equals("")) {
+ StringTokenizer tokenizer = new StringTokenizer(stages, ":");
+ mLabel.setVisible(true);
+ while (tokenizer.hasMoreTokens()) {
+ String str = (String)tokenizer.nextToken();
+ if (str.equals(ConfigConstants.STAGE_INTERNAL_DB)) {
+ mDbButton.setVisible(true);
+ } else if (str.equals(ConfigConstants.STAGE_SETUP_PORTS)) {
+ mNetworkButton.setVisible(true);
+ } else if (str.equals(ConfigConstants.STAGE_SETUP_ADMINISTRATOR)) {
+ mAdminButton.setVisible(true);
+ }
+ }
+ }
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ cleanUpWizardInfo(wizardInfo);
+
+ startProgressStatus();
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_GET_DEFAULT_INFO;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+ OpDef.OP_READ;
+ boolean ready = send(rawData, wizardInfo);
+ if (ready) {
+ rawData = ConfigConstants.TASKID+"="+TaskId.TASK_TOKEN_INFO;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_READ;
+ rawData = rawData+"&"+ConfigConstants.PR_CMS_SEED+"="+
+ (new Long(WizardBasePanel.mSeed).toString());
+
+ ready = send(rawData, wizardInfo);
+ }
+
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage(wizardInfo);
+ if (str == null)
+ setErrorMessage("Server Error");
+ else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea desc = createTextArea(mResource.getString(
+ "INTROINSTALLWIZARD_TEXT_DESC_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ mLabel = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "INTROINSTALLWIZARD_TEXT_HEADING_LABEL"), 80), 2, 80);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mLabel, gbc);
+
+ mDbButton = makeJRadioButton("CREATEDB");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mDbButton, gbc);
+
+ mNetworkButton = makeJRadioButton("NETWORK");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mNetworkButton, gbc);
+
+ mAdminButton = makeJRadioButton("ADMIN");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mAdminButton, gbc);
+
+ mSubsystemButton = makeJRadioButton("SUBSYSTEMS");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mSubsystemButton, gbc);
+
+ mMigrationButton = makeJRadioButton("MIGRATION");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mMigrationButton, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIIntroSingleSignonPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIIntroSingleSignonPage.java
new file mode 100644
index 000000000..659dd6969
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIIntroSingleSignonPage.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.admin.certsrv.config.install;
+
+import java.io.*;
+import java.net.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.comm.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Setup Single Signon for the installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIIntroSingleSignonPage extends WizardBasePanel implements IWizardPanel {
+ private JRadioButton mYes;
+ private JRadioButton mNo;
+ private static final String HELPINDEX =
+ "install-single-signon-enable-wizard-help";
+ private static final String PANELNAME = "INSTALLINTROSINGLESIGNON";
+
+ WIIntroSingleSignonPage() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ setBorder(makeTitledBorder(PANELNAME));
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ if (mNo.isSelected()) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ Hashtable data = new Hashtable();
+ ConsoleInfo consoleInfo = wizardInfo.getAdminConsoleInfo();
+ CMSConfigCert configCertCgi = new CMSConfigCert();
+ configCertCgi.initialize(wizardInfo);
+ data.put(ConfigConstants.TASKID, TaskId.TASK_MISCELLANEOUS);
+ data.put(ConfigConstants.OPTYPE, OpDef.OP_MODIFY);
+ data.put(ConfigConstants.PR_CERT_INSTANCE_NAME,
+ consoleInfo.get(ConfigConstants.PR_CERT_INSTANCE_NAME));
+ data.put(ConfigConstants.PR_ADMIN_PASSWD,
+ (String)consoleInfo.get(ConfigConstants.PR_ADMIN_PASSWD));
+
+ boolean ready = configCertCgi.configCert(data);
+ return ready;
+ }
+
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+/*
+ JTextArea heading = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ PANELNAME+"_TEXT_HEADING_LABEL"), 80), 1, 80);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(heading, gbc);
+*/
+ JLabel heading = makeJLabel("HEADING");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(heading, gbc);
+
+ mNo = makeJRadioButton("NO", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mNo, gbc);
+
+ mYes = makeJRadioButton("YES", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(0,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mYes, gbc);
+
+ JLabel dummy = new JLabel("");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(dummy, gbc);
+
+ ButtonGroup buttonGrp = new ButtonGroup();
+ buttonGrp.add(mYes);
+ buttonGrp.add(mNo);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (mNo.isSelected())
+ wizardInfo.put(ConfigConstants.PR_SINGLE_SIGNON, ConfigConstants.FALSE);
+ else
+ wizardInfo.put(ConfigConstants.PR_SINGLE_SIGNON, ConfigConstants.TRUE);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIKRACertDNPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRACertDNPage.java
new file mode 100644
index 000000000..2dca713b5
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRACertDNPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import javax.swing.*;
+
+/**
+ * Subject DN page for KRA transport certificate
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIKRACertDNPage extends WICertDNPage {
+ private static final String PANELNAME = "INSTALLKRACERTDNWIZARD";
+ private static final String CAKRALOCALHELPINDEX = "install-cakra-kracertlocal-subjectdn-wizard-help";
+ private static final String CAKRAREMOTEHELPINDEX = "install-cakra-kracertsub-subjectdn-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakra-kracertsub-subjectdn-wizard-help";
+ private static final String KRAHELPINDEX = "install-kracertsub-subjectdn-wizard-help";
+
+ WIKRACertDNPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIKRACertDNPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isKRACloningDone())
+ return false;
+ if (!wizardInfo.isKRAInstalled() || wizardInfo.isKRALocalCertDone() ||
+ wizardInfo.isKRACertRequestDone() || wizardInfo.isKRACertInstalledDone())
+ return false;
+// dnDesc.setText(KRA_DN);
+ String str = wizardInfo.getKRASubjectName();
+ String OComp = null;
+ String CComp = null;
+ if (wizardInfo.isCAInstalled()) {
+ // get O component
+ OComp = wizardInfo.getCAOComp();
+ CComp = wizardInfo.getCACComp();
+ }
+
+ if (str == null || str.equals("")) {
+ if (OComp != null && !OComp.equals("")) {
+ if (CComp == null || CComp.equals(""))
+ str = KRA_CN+", O="+OComp;
+ else
+ str = KRA_CN+", O="+OComp+", C="+CComp;
+ } else {
+ if (CComp == null || CComp.equals(""))
+ str = KRA_CN;
+ else
+ str = KRA_CN+", C="+CComp;
+ }
+ }
+ wizardInfo.setKRASubjectName(str);
+ populateDN(str);
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ if (wizardInfo.isKRACertLocalCA())
+ mHelpIndex = CAKRALOCALHELPINDEX;
+ else
+ mHelpIndex = CAKRAREMOTEHELPINDEX;
+ else if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = KRAHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ if (super.concludePanel(info)) {
+ wizardInfo.setKRASubjectName(mStr);
+ return true;
+ }
+
+ return false;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIKRACertExtensionPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRACertExtensionPage.java
new file mode 100644
index 000000000..2b1f0dc99
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRACertExtensionPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.border.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * Certificate Extension page for KRA transport certificate.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIKRACertExtensionPage extends WICertExtensionPage {
+ private static final String PANELNAME = "INSTALLKRACERTEXTENSION1WIZARD";
+ private static final String KRAHELPINDEX = "install-kracert-extension-wizard-help";
+ private static final String CAKRAHELPINDEX = "install-cakra-kracert-extension-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakracert-extension-wizard-help";
+
+ WIKRACertExtensionPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIKRACertExtensionPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isKRACloningDone())
+ return false;
+ if (!wizardInfo.isKRAInstalled() ||
+ wizardInfo.isKRALocalCertDone() || wizardInfo.isKRACertRequestDone() ||
+ wizardInfo.isKRACertInstalledDone())
+ return false;
+
+ if (!mModified)
+ mAKICheckBox.setSelected(true);
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = KRAHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIKRACertSubmitPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRACertSubmitPage.java
new file mode 100644
index 000000000..992bd7f14
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRACertSubmitPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * KRA Certificate Submission.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIKRACertSubmitPage extends WICertSubmitPage implements IWizardPanel {
+ private static final String PANELNAME = "INSTALLKRACERTWIZARD";
+ private static final String KRAHELPINDEX = "install-kratype-wizard-help";
+ private static final String CAKRAHELPINDEX = "install-cakratype-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakratype-wizard-help";
+
+ WIKRACertSubmitPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isKRACloningDone())
+ return false;
+ wizardInfo.put(Constants.PR_CERTIFICATE_TYPE,
+ Constants.PR_KRA_TRANSPORT_CERT);
+ if (!wizardInfo.isKRAInstalled() ||
+ wizardInfo.isKRACertRequestDone() || wizardInfo.isKRACertInstalledDone() ||
+ !wizardInfo.isCAInstalled()) {
+ wizardInfo.setKRACertLocalCA(Constants.FALSE);
+ return false;
+ }
+
+ if (wizardInfo.isKRALocalCertDone())
+ return false;
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = KRAHELPINDEX;
+ else if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (mSelfButton.isSelected())
+ wizardInfo.setKRACertLocalCA(Constants.TRUE);
+ else
+ wizardInfo.setKRACertLocalCA(Constants.FALSE);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIKRACertValidityPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRACertValidityPage.java
new file mode 100644
index 000000000..feaa29983
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRACertValidityPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * Validity page for KRA transport certificate.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIKRACertValidityPage extends WICertValidityPage {
+ private static final String PANELNAME = "INSTALLKRACERTVALIDWIZARD";
+ private static final String KRAHELPINDEX = "install-kracert-validity-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakracert-validity-wizard-help";
+ private static final String CAKRAHELPINDEX = "install-cakra-kracert-validity-wizard-help";
+
+ WIKRACertValidityPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIKRACertValidityPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isKRACloningDone())
+ return false;
+ if (!wizardInfo.isKRAInstalled() || wizardInfo.isKRALocalCertDone() ||
+ wizardInfo.isKRACertRequestDone() || wizardInfo.isKRACertInstalledDone())
+ return false;
+ if (super.initializePanel(info)) {
+ if (!wizardInfo.isKRACertLocalCA())
+ return false;
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = KRAHELPINDEX;
+
+ return true;
+ }
+ return false;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIKRAKeyPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRAKeyPage.java
new file mode 100644
index 000000000..00b12d43c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRAKeyPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * Setup key information for KRA transport certificate
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIKRAKeyPage extends WIKeyPage implements IWizardPanel {
+ private static final String PANELNAME = "INSTALLKRAKEYWIZARD";
+ private static final String KRAHELPINDEX =
+ "install-krakeysub-configuration-wizard-help";
+ private static final String CAKRALOCALHELPINDEX =
+ "install-cakra-krakeylocal-configuration-wizard-help";
+ private static final String CAKRAREMOTEHELPINDEX =
+ "install-cakra-krakeysub-configuration-wizard-help";
+ private static final String RAKRAHELPINDEX =
+ "install-rakra-krakeysub-configuration-wizard-help";
+
+ WIKRAKeyPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIKRAKeyPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ mWizardInfo = (InstallWizardInfo)info;
+ if (mWizardInfo.isCloning() && mWizardInfo.isKRACloningDone())
+ return false;
+ if (!mWizardInfo.isKRAInstalled() || mWizardInfo.isKRALocalCertDone() ||
+ mWizardInfo.isKRACertRequestDone() || mWizardInfo.isKRACertInstalledDone())
+ return false;
+ if (super.initializePanel(info)) {
+ String kraTokenName = mWizardInfo.getKRATokenName();
+ if (kraTokenName == null || kraTokenName.equals("")) {
+ mTokenBox.setSelectedIndex(0);
+ } else {
+ if (kraTokenName.equals(Constants.PR_INTERNAL_TOKEN_NAME))
+ mTokenBox.setSelectedIndex(0);
+ else
+ mTokenBox.setSelectedItem(kraTokenName);
+ }
+ }
+
+ if (mWizardInfo.isCAInstalled() && mWizardInfo.isKRAInstalled()) {
+ if (mWizardInfo.isKRACertLocalCA())
+ mHelpIndex = CAKRALOCALHELPINDEX;
+ else
+ mHelpIndex = CAKRAREMOTEHELPINDEX;
+ } else if (mWizardInfo.isRAInstalled() && mWizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = KRAHELPINDEX;
+
+ enableFields();
+ mIsCAKey = false;
+ return true;
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ super.getUpdateInfo(info);
+ mWizardInfo.setKRATokenName(mWizardInfo.getTokenName());
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIKRAMessageDigestPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRAMessageDigestPage.java
new file mode 100644
index 000000000..38941ec7b
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRAMessageDigestPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Setup the message digest information for the installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIKRAMessageDigestPage extends WMessageDigestPage {
+
+ private static final String PANELNAME = "INSTALLKRAMESSAGEDIGESTWIZARD";
+
+ WIKRAMessageDigestPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIKRAMessageDigestPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isKRACloningDone())
+ return false;
+ if (!wizardInfo.isKRAInstalled() || !wizardInfo.isKRACertLocalCA() ||
+ wizardInfo.isKRALocalCertDone() || wizardInfo.isKRACertRequestDone() ||
+ wizardInfo.isKRACertInstalledDone())
+ return false;
+
+ mCAKeyType = wizardInfo.getCAKeyType();
+
+ return super.initializePanel(info);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (mDSAHashTypeBox.isVisible())
+ wizardInfo.setHashType((String)mDSAHashTypeBox.getSelectedItem());
+ else
+ wizardInfo.setHashType((String)mRSAHashTypeBox.getSelectedItem());
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIKRANumberPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRANumberPage.java
new file mode 100644
index 000000000..000b3eb9f
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRANumberPage.java
@@ -0,0 +1,378 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import java.math.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * This panel asks for the starting serial number that the CA issues
+ *
+ * @author Michelle Zhao
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIKRANumberPage extends WizardBasePanel implements IWizardPanel {
+ private JTextArea mDesc;
+
+ private String mSerialNumber;
+ private JTextField mSerialNumberText;
+ private JLabel mSerialNumberLabel;
+
+ private String mEndSerialNumber = null;
+ private JTextField mEndSerialNumberText;
+ private JLabel mEndSerialNumberLabel;
+
+ private String mbeginRequestNumber;
+ private JTextField mbeginRequestNumberText;
+ private JLabel mbeginRequestNumberLabel;
+
+ private String mEndRequestNumber = null;
+ private JTextField mEndRequestNumberText;
+ private JLabel mEndRequestNumberLabel;
+
+ private static final String DEFAULT_SERIAL_NUMBER = "1";
+ private static final String PANELNAME = "KRAREQUESTNUMBERWIZARD";
+ private static final String HELPINDEX =
+ "install-ca-serialnumber-wizard-help";
+
+ WIKRANumberPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIKRANumberPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ String serial;
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ setBorder(makeTitledBorder(PANELNAME));
+ if (//wizardInfo.isKRACertLocalCA() || !wizardInfo.isInstallCertNow() ||
+ !wizardInfo.isKRAInstalled() || wizardInfo.isKRACertInstalledDone()||
+ wizardInfo.isNumberPageDone())
+ return false;
+
+ if (wizardInfo.isCloning())
+ mDesc.setText(mResource.getString(PANELNAME+"_TEXT_HEADING_LABEL")
+ + mResource.getString(PANELNAME+"_TEXT_MORE_LABEL"));
+ else
+ mDesc.setText(mResource.getString(PANELNAME+"_TEXT_HEADING_LABEL"));
+
+
+ if ((serial = wizardInfo.getCASerialNumber()) != null)
+ mSerialNumberText.setText(serial);
+ else
+ mSerialNumberText.setText(DEFAULT_SERIAL_NUMBER);
+
+ if ((serial = wizardInfo.getRequestNumber()) != null)
+ mbeginRequestNumberText.setText(serial);
+ else
+ mbeginRequestNumberText.setText(DEFAULT_SERIAL_NUMBER);
+
+ if ((serial = wizardInfo.getCAEndSerialNumber()) != null)
+ mEndSerialNumberText.setText(serial);
+
+ if ((serial = wizardInfo.getEndRequestNumber()) != null)
+ mEndRequestNumberText.setText(serial);
+ return true;
+ }
+
+ private String hexToDecimal(String hex, boolean isHex)
+ {
+ //String newHex = hex.substring(2);
+ BigInteger bi;
+ if(isHex)
+ bi = new BigInteger(hex, 16);
+ else
+ bi = new BigInteger(hex, 10);
+ return bi.toString();
+ }
+
+ private String DecToHex(String dec)
+ {
+ BigInteger bi;
+ bi = new BigInteger(dec, 10);
+ return bi.toString(16);
+ }
+
+ private boolean validateNumber(JTextField beginNumberField, JTextField endNumberField,String beginText, String endText,boolean isSerialNumber)
+ {
+ BigInteger num = null;
+ BigInteger endNum = null;
+ String serial = null;
+ beginText = beginNumberField.getText().trim();
+ if (beginText != null && !beginText.equals("")) {
+ try {
+ if (beginText.startsWith("0x")) {
+ serial = hexToDecimal(beginText.substring(2),true);
+ } else {
+ serial = beginText;
+ }
+ num = new BigInteger(serial);
+ if (num.compareTo(new BigInteger("0")) < 0) {
+ setErrorMessage("You must specify a positive value.");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ setErrorMessage("You must specify a numeric value.");
+ return false;
+ }
+ if(isSerialNumber)
+ mSerialNumber = DecToHex(serial);
+ else
+ mbeginRequestNumber = serial;
+ } else {
+ if(isSerialNumber)
+ mSerialNumber = "";
+ else
+ mbeginRequestNumber = "";
+ }
+
+ endText = endNumberField.getText().trim();
+ if (endText != null && !endText.equals("")) {
+ try {
+ if (endText.startsWith("0x")) {
+ serial = hexToDecimal(endText.substring(2),true);
+ } else {
+ serial = endText;
+ }
+ endNum = new BigInteger(serial);
+ if (endNum.compareTo(new BigInteger("0")) < 0) {
+ setErrorMessage("You must specify a positive value.");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ setErrorMessage("You must specify a numeric value.");
+ return false;
+ }
+ if(isSerialNumber)
+ mEndSerialNumber = DecToHex(serial);
+ else
+ mEndRequestNumber = serial;
+ } else {
+ if(isSerialNumber)
+ mEndSerialNumber = "";
+ else
+ mEndRequestNumber = "";
+ }
+
+ if (num != null && endNum != null && num.compareTo(endNum) > 0) {
+ setErrorMessage("Ending number must be greater than starting number.");
+ return false;
+ }
+ return true;
+ }
+
+ public boolean validatePanel() {
+ if(validateNumber(mSerialNumberText,mEndSerialNumberText,mSerialNumber,mEndSerialNumber,true)==false)
+ return false;
+ if(validateNumber(mbeginRequestNumberText,mEndRequestNumberText,mbeginRequestNumber,mEndRequestNumber,false)==false)
+ return false;
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (mSerialNumber != null && !mSerialNumber.equals(""))
+ wizardInfo.setCASerialNumber(mSerialNumber);
+ else {
+ wizardInfo.setCASerialNumber(DEFAULT_SERIAL_NUMBER);
+ mSerialNumber = DEFAULT_SERIAL_NUMBER;
+ }
+ if (mbeginRequestNumber != null && !mbeginRequestNumber.equals(""))
+ wizardInfo.setRequestNumber(mbeginRequestNumber);
+ else {
+ wizardInfo.setRequestNumber(DEFAULT_SERIAL_NUMBER);
+ mbeginRequestNumber = DEFAULT_SERIAL_NUMBER;
+ }
+
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_SET_KRA_NUMBER;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ if (mSerialNumber != null && !mSerialNumber.equals(""))
+ rawData = rawData+"&"+ConfigConstants.PR_CA_SERIAL_NUMBER+"="+
+ mSerialNumber;
+ if (mEndSerialNumber != null && !mEndSerialNumber.equals(""))
+ rawData = rawData+"&"+ConfigConstants.PR_CA_ENDSERIAL_NUMBER+"="+
+ mEndSerialNumber;
+ if (mbeginRequestNumber != null && !mbeginRequestNumber.equals(""))
+ rawData = rawData+"&"+ConfigConstants.PR_REQUEST_NUMBER+"="+
+ mbeginRequestNumber;
+ if (mEndRequestNumber != null && !mEndSerialNumber.equals(""))
+ rawData = rawData+"&"+ConfigConstants.PR_ENDREQUEST_NUMBER+"="+
+ mEndRequestNumber;
+ if (wizardInfo.getInternalDBPasswd() != null)
+ rawData = rawData+"&"+ConfigConstants.PR_DB_PWD+"="+
+ wizardInfo.getInternalDBPasswd();
+ rawData = rawData+"&"+ConfigConstants.PR_SERIAL_REQUEST_NUMBER+"="+
+ ConfigConstants.TRUE;
+
+ startProgressStatus();
+
+ boolean ready = send(rawData, wizardInfo);
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage();
+ if (str.equals(""))
+ setErrorMessage("Server Error");
+ else
+ setErrorMessage(str);
+ }else {
+ wizardInfo.setNumberPageDone(ConfigConstants.TRUE);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mDesc = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mDesc, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mSerialNumberLabel = makeJLabel("SERIALNUMBER");
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mSerialNumberLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mSerialNumberText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+// gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mSerialNumberText, gbc);
+
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEndSerialNumberLabel = makeJLabel("ENDSERIALNUMBER");
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mEndSerialNumberLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEndSerialNumberText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+// gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mEndSerialNumberText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mbeginRequestNumberLabel = makeJLabel("REQUESTNUMBER");
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mbeginRequestNumberLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mbeginRequestNumberText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+// gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mbeginRequestNumberText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEndRequestNumberLabel = makeJLabel("ENDREQUESTNUMBER");
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mEndRequestNumberLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEndRequestNumberText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+// gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mEndRequestNumberText, gbc);
+
+ /*
+ CMSAdminUtil.resetGBC(gbc);
+ mSerialNumberLabel = makeJLabel("PWD");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mSerialNumberLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mSerialNumberText = makeJSerialNumberField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mSerialNumberText, gbc);
+*/
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIKRARequestResultPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRARequestResultPage.java
new file mode 100644
index 000000000..1580b7101
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRARequestResultPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Display the KRA transport certificate request result
+ *
+ * @author Michelle Zhao
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIKRARequestResultPage extends WIRequestResultPage {
+
+ WIKRARequestResultPage(JDialog parent) {
+ super(parent);
+ }
+
+ WIKRARequestResultPage(JDialog parent, JFrame adminFrame) {
+ super( parent, adminFrame);
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isKRACloningDone())
+ return false;
+ if (wizardInfo.isKRACertLocalCA() || !wizardInfo.isKRAInstalled() ||
+ wizardInfo.isKRALocalCertDone() ||
+ (wizardInfo.isKRACertRequestSucc() && wizardInfo.isKRAReqResultDisplayed()) ||
+ wizardInfo.isKRACertInstalledDone())
+ return false;
+
+ wizardInfo.setKRAReqResultDisplayed(Constants.TRUE);
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIKRAScheme1Page.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRAScheme1Page.java
new file mode 100644
index 000000000..d6171e651
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRAScheme1Page.java
@@ -0,0 +1,188 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * KRA Key recovery for installation wizard: specify number of required and
+ * available agents
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIKRAScheme1Page extends WizardBasePanel implements IWizardPanel {
+ private JTextField mRequiredText;
+ private JTextField mAvailText;
+ private String mHelpIndex;
+ private static final String PANELNAME = "KRASCHEME1WIZARD";
+ private static final String KRAHELPINDEX =
+ "install-kra-mnscheme-wizard-help";
+ private static final String CAKRAHELPINDEX =
+ "install-cakra-mnscheme-wizard-help";
+ private static final String RAKRAHELPINDEX =
+ "install-rakra-mnscheme-wizard-help";
+ private int mRequired, mAvail;
+
+ WIKRAScheme1Page(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIKRAScheme1Page(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (!wizardInfo.doKeySplitting())
+ return false;
+ if (wizardInfo.isCloning())
+ return false;
+ if (!wizardInfo.isKRAInstalled() || wizardInfo.isKRANMSchemeDone())
+ return false;
+ setBorder(makeTitledBorder(PANELNAME));
+ mRequiredText.setText(wizardInfo.getRequiredAgents());
+ mAvailText.setText(wizardInfo.getTotalAgents());
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = KRAHELPINDEX;
+ return true;
+ }
+
+ public boolean validatePanel() {
+ String str = mRequiredText.getText().trim();
+ if (str.equals("")) {
+ setErrorMessage("CANNOTBEBLANK");
+ return false;
+ }
+
+ try {
+ mRequired = Integer.parseInt(str);
+ str = mAvailText.getText().trim();
+ if (str.equals("")) {
+ setErrorMessage("CANNOTBEBLANK");
+ return false;
+ }
+ mAvail = Integer.parseInt(str);
+ } catch (NumberFormatException e) {
+ setErrorMessage("NOTINTEGER");
+ return false;
+ }
+
+ if (mRequired <= 0 || mAvail <= 0) {
+ setErrorMessage("NONZERO");
+ return false;
+ }
+
+ if (mRequired > mAvail) {
+ setErrorMessage("LARGER");
+ return false;
+ }
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(mHelpIndex);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel requiredLbl = makeJLabel("REQUIRED");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ add(requiredLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRequiredText = makeJTextField(5);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ add(mRequiredText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea dummy = createTextArea(" ", 1, 15);
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(dummy, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel availLbl = makeJLabel("AVAILABLE");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.insets = new Insets(0,COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.NONE;
+ add(availLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mAvailText = makeJTextField(5);
+ gbc.insets = new Insets(0,COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.NONE;
+ add(mAvailText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea dummy1 = createTextArea(" ", 1, 15);
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(0,COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(dummy1, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ wizardInfo.setRequiredAgents(mRequiredText.getText().trim());
+ wizardInfo.setTotalAgents(mAvailText.getText());
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIKRAScheme2Page.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRAScheme2Page.java
new file mode 100644
index 000000000..f8c9c9f8e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRAScheme2Page.java
@@ -0,0 +1,309 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import java.util.*;
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import javax.swing.table.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * KRA Key recovery for installation wizard: specify the uid and password
+ * for all the available agents
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIKRAScheme2Page extends WizardBasePanel implements IWizardPanel {
+ private JTable mTable;
+ private NewAgentModel mDataModel;
+ private String mHelpIndex;
+ private static final String PANELNAME = "KRASCHEME2WIZARD";
+ private static final String KRAHELPINDEX =
+ "install-kra-scheme-usrpwds-wizard-help";
+ private static final String CAKRAHELPINDEX =
+ "install-cakra-scheme-usrpwds-wizard-help";
+ private static final String RAKRAHELPINDEX =
+ "install-rakra-scheme-usrpwds-wizard-help";
+
+ WIKRAScheme2Page(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIKRAScheme2Page(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (!wizardInfo.doKeySplitting())
+ return false;
+ if (wizardInfo.isCloning())
+ return false;
+ if (!wizardInfo.isKRAInstalled() || wizardInfo.isKRANMSchemeDone())
+ return false;
+
+ String val = wizardInfo.getTotalAgents();
+ int M = Integer.parseInt(val);
+ mDataModel.removeAllRows();
+
+ Vector[] data = new Vector[M];
+ for (int i=0; i<data.length; i++) {
+ data[i] = new Vector();
+ data[i].addElement(Integer.toString(i+1));
+ // initialize userid
+ data[i].addElement("agent"+(i+1));
+ data[i].addElement("");
+ data[i].addElement("");
+ mDataModel.addRow(data[i]);
+ }
+
+ setBorder(makeTitledBorder(PANELNAME));
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = KRAHELPINDEX;
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+
+ Component component = mTable.getEditorComponent();
+ if(component!= null) {
+ int col = mTable.getEditingColumn();
+ int row = mTable.getEditingRow();
+ if ((col>-1)&&(row>-1)) {
+ String str = ((JTextComponent)component).getText();
+ mTable.setValueAt(str, row, col);
+ }
+ }
+
+ if(!checkBlank()) {
+ setErrorMessage("CANNOTBEBLANK");
+ return false;
+ }
+
+ if(!checkConfirm()) {
+ setErrorMessage("PASSWORDERROR");
+ return false;
+ }
+
+ if (!checkDuplicate()) {
+ setErrorMessage("DUPLICATEERROR");
+ return false;
+ }
+
+ return true;
+ }
+
+ private boolean checkBlank() {
+ for (int i=0; i<mDataModel.getRowCount(); i++) {
+ String val1 = (String)mDataModel.getValueAt(i,1);
+ String val2 = (String)mDataModel.getValueAt(i,2);
+ String val3 = (String)mDataModel.getValueAt(i,3);
+ if ( (val1.trim().equals(""))||(val2.trim().equals(""))||
+ (val3.trim().equals(""))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean checkDuplicate() {
+ Hashtable table = new Hashtable();
+ for (int i=0; i<mDataModel.getRowCount(); i++) {
+ String val1 = (String)mDataModel.getValueAt(i,1);
+ table.put(val1.trim(), "1");
+ }
+ if (table.size() != mDataModel.getRowCount()) {
+ table = null;
+ return false;
+ }
+
+ table = null;
+ return true;
+ }
+
+ private boolean checkConfirm() {
+ for (int i=0; i<mDataModel.getRowCount(); i++) {
+ String val2 = (String)mDataModel.getValueAt(i,2);
+ String val3 = (String)mDataModel.getValueAt(i,3);
+ if (!val2.trim().equals(val3.trim())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private String getUIDPassword() {
+ String result = "";
+ for (int i=0; i<mDataModel.getRowCount(); i++) {
+ String val1 = (String)mDataModel.getValueAt(i,1);
+ String val2 = (String)mDataModel.getValueAt(i,2);
+ result = result+val1.trim()+"="+val2.trim();
+ if (i < (mDataModel.getRowCount()-1))
+ result = result+",";
+ }
+ return result;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ String rawData = "";
+ int total = Integer.parseInt(wizardInfo.getTotalAgents());
+ for (int i=0; i<total; i++) {
+ String val1 = (String)mDataModel.getValueAt(i,1);
+ String val2 = (String)mDataModel.getValueAt(i,2);
+ rawData = rawData+ConfigConstants.PR_AGENT_UID+i+"="+val1;
+ rawData = rawData+"&"+ConfigConstants.PR_AGENT_PWD+i+"="+val2;
+ }
+
+ rawData = rawData+"&"+ConfigConstants.TASKID+"="+TaskId.TASK_AGENTS;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ rawData = rawData+"&"+ConfigConstants.PR_AGENT_N+"="+
+ wizardInfo.getTotalAgents();
+ rawData = rawData+"&"+ConfigConstants.PR_AGENT_M+"="+
+ wizardInfo.getRequiredAgents();
+ startProgressStatus();
+ boolean ready = send(rawData, wizardInfo);
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage();
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ PANELNAME+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(mHelpIndex);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea headingLbl = createTextArea(mResource.getString(
+ PANELNAME+"_LABEL_HEADING_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(headingLbl, gbc);
+
+ mDataModel = new NewAgentModel();
+ mTable = new JTable(mDataModel);
+ JScrollPane scrollPane = JTable.createScrollPaneForTable(mTable);
+ scrollPane.setHorizontalScrollBarPolicy(scrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ scrollPane.setVerticalScrollBarPolicy(scrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
+ scrollPane.setBackground(Color.white);
+ setLabelCellRenderer(mTable, 1);
+ setLabelCellEditor(mTable, 2);
+ setLabelCellEditor(mTable, 3);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.BOTH;
+ gbc.weighty = 1.0;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gb.setConstraints(scrollPane, gbc);
+ add(scrollPane);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(
+ new DefaultTableCellRenderer());
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellEditor(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(
+ new PasswordCellRenderer());
+ table.getColumnModel().getColumn(index).setCellEditor(
+ new DefaultCellEditor(new JPasswordField()));
+ }
+}
+
+class NewAgentModel extends CMSTableModel
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String COL1 = "NUMBER";
+ public static final String COL2 = "UID";
+ public static final String COL3 = "PASSWORD";
+ public static final String COL4 = "CONFIRM";
+
+
+ private static String[] mColumns = {COL1, COL2, COL3, COL4};
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public NewAgentModel() {
+ super();
+ init(mColumns);
+ }
+
+ public boolean isCellEditable(int row, int col) {
+ if(col >= 1)
+ return true;
+ return false;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIKRAStorageKeyPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRAStorageKeyPage.java
new file mode 100644
index 000000000..6cce19d95
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRAStorageKeyPage.java
@@ -0,0 +1,356 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import java.util.*;
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.console.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+
+/**
+ * Install KRA storage key.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIKRAStorageKeyPage extends WizardBasePanel implements IWizardPanel {
+ private String mHelpIndex;
+ private static final String PANELNAME = "INSTALLKRASTORAGEKEYWIZARD";
+ private static final String KRAHELPINDEX =
+ "install-kra-storagekey-wizard-help";
+ private static final String CAKRAHELPINDEX =
+ "install-cakra-storagekey-wizard-help";
+ private static final String RAKRAHELPINDEX =
+ "install-rakra-storagekey-wizard-help";
+
+ protected JComboBox mKeyTypeBox, mKeyLengthBox, mDSAKeyLengthBox, mTokenBox;
+ protected JPasswordField mPassword, mPasswordAgain, mSOPPassword;
+ protected JLabel keyTypeLbl, keyLengthCustomText, keyLengthLbl, unitLbl,
+ keyLengthCustomLbl, unit1Lbl, mTokenLbl;
+ protected JLabel mPasswdLbl, mPasswdAgainLbl, mSOPLbl;
+ protected JCheckBox mHardwareSplit;
+ protected String[] mTokenInitialized;
+ protected String[] mTokenLogin;
+ private Color mActiveColor;
+
+ WIKRAStorageKeyPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIKRAStorageKeyPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning())
+ return false;
+ if (!wizardInfo.isKRAInstalled() || wizardInfo.isKRANMSchemeDone())
+ return false;
+ setBorder(makeTitledBorder(PANELNAME));
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = KRAHELPINDEX;
+
+ wizardInfo = (InstallWizardInfo)info;
+ setBorder(makeTitledBorder(mPanelName));
+ if (mTokenBox.getItemCount() > 0) {
+ mTokenBox.removeAllItems();
+ }
+
+ String tokenList = wizardInfo.getTokensList();
+ StringTokenizer tokenizer = new StringTokenizer(tokenList, ":");
+ int count = tokenizer.countTokens();
+ while (tokenizer.hasMoreTokens()) {
+ mTokenBox.addItem((String)tokenizer.nextToken());
+ }
+
+ String initializedList = wizardInfo.getTokensInit();
+ tokenizer = new StringTokenizer(initializedList, ":");
+ int i=0;
+ mTokenInitialized = new String[count];
+ while (tokenizer.hasMoreElements()) {
+ mTokenInitialized[i] = (String)tokenizer.nextToken();
+ i++;
+ }
+
+ String loginList = wizardInfo.getTokensLogin();
+ tokenizer = new StringTokenizer(loginList, ":");
+ i=0;
+ mTokenLogin = new String[count];
+ while (tokenizer.hasMoreElements()) {
+ mTokenLogin[i] = (String)tokenizer.nextToken();
+ i++;
+ }
+
+ //mTokenBox.setSelectedIndex(0);
+ mTokenBox.addItemListener(this);
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ int index = mTokenBox.getSelectedIndex();
+ if (index > 0) {
+ mPassword.setEnabled(true);
+ mPassword.setBackground(mActiveColor);
+ } else {
+ // Internal Token
+ mPassword.setEnabled(false);
+ mPassword.setBackground(getBackground());
+ }
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ ConsoleInfo consoleInfo = wizardInfo.getAdminConsoleInfo();
+ CMSConfigCert configCertCgi = new CMSConfigCert();
+ configCertCgi.initialize(wizardInfo);
+ Hashtable data = new Hashtable();
+
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_STORAGE_KEY;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ wizardInfo.setKeyLength((String)mKeyLengthBox.getSelectedItem());
+ rawData = rawData+"&"+ConfigConstants.PR_KEY_LEN+"="+wizardInfo.getKeyLength();
+ rawData = rawData+"&"+ConfigConstants.PR_TOKEN_NAME+"="+(String)mTokenBox.getSelectedItem();
+ rawData = rawData+"&"+ConfigConstants.PR_TOKEN_PASSWD+"="+
+ (String)mPassword.getText().trim();
+ startProgressStatus();
+ boolean ready = send(rawData, wizardInfo);
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage();
+ if (str.equals(""))
+ setErrorMessage("Server Error");
+ else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(mHelpIndex);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JPanel panel = new JPanel();
+ GridBagLayout gb1 = new GridBagLayout();
+ panel.setLayout(gb1);
+
+ JPanel panel2 = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ panel2.setLayout(gb3);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ add(panel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ add(panel2, gbc);
+
+ JTextArea selectTokenLbl = createTextArea(mResource.getString(
+ mPanelName+"_LABEL_SELECTTOKEN_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,0);
+ panel.add(selectTokenLbl, gbc);
+
+ JLabel tokenLbl = makeJLabel("TOKEN");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.CENTER;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ panel.add(tokenLbl, gbc);
+
+ mTokenBox = new JComboBox();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.weightx = 1.0;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ panel.add(mTokenBox, gbc);
+ mTokenBox.addActionListener(this);
+
+ JTextArea dummy2 = createTextArea(" ", 1, 5);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ panel.add(dummy2, gbc);
+
+ mTokenLbl = new JLabel("");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ panel2.add(mTokenLbl, gbc);
+
+ mPasswdLbl = makeJLabel("PASSWD");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0,
+ COMPONENT_SPACE);
+ panel2.add(mPasswdLbl, gbc);
+
+ mPassword = new JPasswordField();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ panel2.add(mPassword, gbc);
+ mActiveColor = mPassword.getBackground();
+
+/**
+ mPasswdAgainLbl = makeJLabel("PASSWDAGAIN");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0,
+ COMPONENT_SPACE);
+ panel2.add(mPasswdAgainLbl, gbc);
+
+ mPasswordAgain = new JPasswordField();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ panel2.add(mPasswordAgain, gbc);
+
+ mSOPLbl = makeJLabel("SOP");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel2.add(mSOPLbl, gbc);
+
+ mSOPPassword = new JPasswordField();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel2.add(mSOPPassword, gbc);
+ **/
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea label = createTextArea(mResource.getString(
+ PANELNAME+"_LABEL_HEADING_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gbc.weightx = 1.0;
+ add(label, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel keyLengthLbl = makeJLabel("KEYLENGTH");
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ add(keyLengthLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mKeyLengthBox = makeJComboBox("KEYLENGTH");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mKeyLengthBox, gbc);
+
+/**
+ CMSAdminUtil.resetGBC(gbc);
+ mHardwareSplit = makeJCheckBox("HARDWARE_SPLIT");
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.weightx = 0.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE - COMPONENT_SPACE,0,COMPONENT_SPACE);
+ add(mHardwareSplit, gbc);
+ mHardwareSplit.setEnabled(false);
+ mHardwareSplit.setSelected(false);
+ **/
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel dummy = new JLabel(" ");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(dummy, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIKRATokenLogonPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRATokenLogonPage.java
new file mode 100644
index 000000000..82857a154
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIKRATokenLogonPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * This panel asks for the information of the current internal database.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIKRATokenLogonPage extends WITokenLogonPage implements IWizardPanel {
+
+ private static final String HELPINDEX = "install-kratoken-logon-wizard-help";
+ private static final String PANELNAME = "KRATOKENLOGONWIZARD";
+
+ WIKRATokenLogonPage(JDialog dialog) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = dialog;
+ }
+
+ WIKRATokenLogonPage(JDialog dialog, JFrame adminFrame) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = dialog;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String tokenname = wizardInfo.getKRATokenName();
+ String pwd = (String)wizardInfo.get("TOKEN:"+tokenname);
+ if (wizardInfo.isCloning() && wizardInfo.isKRACloningDone()) {
+ if (pwd != null && !pwd.equals(""))
+ return false;
+ }
+ if (wizardInfo.isKRACertLocalCA() || !wizardInfo.isInstallCertNow() ||
+ !wizardInfo.isKRAInstalled() || wizardInfo.isKRACertInstalledDone())
+ return false;
+ if (pwd != null)
+ return false;
+
+ mTokenText.setText(tokenname);
+ mTokenName = tokenname;
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIKeyPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIKeyPage.java
new file mode 100644
index 000000000..d67d0e339
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIKeyPage.java
@@ -0,0 +1,641 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Setup key information for certificate setup wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIKeyPage extends WizardBasePanel implements IWizardPanel, ItemListener {
+ protected Color mActiveColor;
+ protected JComboBox mKeyTypeBox, mKeyLengthBox, mDSAKeyLengthBox, mTokenBox;
+ protected JTextField mKeyLengthText;
+ protected JPasswordField mPassword, mPasswordAgain, mSOPPassword;
+ protected JLabel keyTypeLbl, keyLengthCustomText, keyLengthLbl, unitLbl,
+ keyLengthCustomLbl, unit1Lbl, mTokenLbl;
+ protected JTextArea keyHeading;
+ protected JLabel mPasswdLbl, mPasswdAgainLbl, mSOPLbl;
+ private String mPanelName;
+ protected String[] mTokenInitialized;
+ protected String[] mTokenLogin;
+ protected InstallWizardInfo mWizardInfo;
+ protected String mHelpIndex;
+ protected boolean mIsCAKey;
+
+ WIKeyPage(String panelName) {
+ super(panelName);
+ mPanelName = panelName;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ mWizardInfo = (InstallWizardInfo)info;
+ setBorder(makeTitledBorder(mPanelName));
+ if (mTokenBox.getItemCount() > 0) {
+ mTokenBox.removeAllItems();
+ }
+
+ String tokenList = mWizardInfo.getTokensList();
+ StringTokenizer tokenizer = new StringTokenizer(tokenList, ":");
+ int count = tokenizer.countTokens();
+ while (tokenizer.hasMoreTokens()) {
+ mTokenBox.addItem((String)tokenizer.nextToken());
+ }
+
+ String initializedList = mWizardInfo.getTokensInit();
+ tokenizer = new StringTokenizer(initializedList, ":");
+ int i=0;
+ mTokenInitialized = new String[count];
+ while (tokenizer.hasMoreElements()) {
+ mTokenInitialized[i] = (String)tokenizer.nextToken();
+ i++;
+ }
+
+ String loginList = mWizardInfo.getTokensLogin();
+ tokenizer = new StringTokenizer(loginList, ":");
+ i=0;
+ mTokenLogin = new String[count];
+ while (tokenizer.hasMoreElements()) {
+ mTokenLogin[i] = (String)tokenizer.nextToken();
+ i++;
+ }
+
+ //mTokenBox.setSelectedIndex(0);
+ mTokenBox.addItemListener(this);
+
+ String type = (String)mKeyTypeBox.getSelectedItem();
+ if (type.equals("RSA")) {
+ mDSAKeyLengthBox.setVisible(false);
+ mKeyLengthBox.setVisible(true);
+ } else {
+ mKeyLengthBox.setVisible(false);
+ mDSAKeyLengthBox.setVisible(true);
+ }
+
+ enableKeyLengthFields();
+ return true;
+ }
+
+ public boolean validatePanel() {
+ int index = mTokenBox.getSelectedIndex();
+
+ if (mKeyLengthText.isEnabled()) {
+ String str = mKeyLengthText.getText().trim();
+ if (str.equals("")) {
+ setErrorMessage("BLANKLEN");
+ return false;
+ } else {
+ try {
+ int num = Integer.parseInt(str);
+ if (num <= 0) {
+ setErrorMessage("INVALIDKEYLEN");
+ return false;
+ }else if (mKeyTypeBox.isVisible()) {
+ String type = (String)mKeyTypeBox.getSelectedItem();
+ if (type.equals("RSA")) {
+ float fraction = (float)num / (float)8.0;
+ int wholeNumber = (int)fraction;
+ if((fraction - wholeNumber)!=0) {
+ setErrorMessage("RSAINVALID");
+ return false;
+ }
+ }else {
+ float fraction = (float)num / (float)64.0;
+ int wholeNumber = (int)fraction;
+ if(num < 512 || num > 1024 || (fraction - wholeNumber)!=0){
+ setErrorMessage("DSAINVALID");
+ return false;
+ }
+ }
+ }
+ } catch (NumberFormatException e) {
+ setErrorMessage("NONINTEGER");
+ return false;
+ }
+ }
+ }
+
+ if (index > 0)
+ return validateHardwareToken(index);
+ else
+ return validateInternalToken(index);
+ }
+
+ private boolean validateHardwareToken(int index) {
+ String passwd = mPassword.getText();
+ String passwdAgain = mPasswordAgain.getText();
+ String sopPasswd = mSOPPassword.getText();
+ if (mTokenLogin[index].equals(ConfigConstants.TRUE)) {
+ return true;
+ }
+
+ if (mTokenInitialized[index].equals(ConfigConstants.TRUE)) {
+ if (passwd.equals("")) {
+ setErrorMessage("BLANKPASSWD");
+ return false;
+ }
+ return true;
+ }
+
+ if (passwd.equals("") || passwdAgain.equals("") || sopPasswd.equals("")) {
+ setErrorMessage("BLANKPASSWD");
+ return false;
+ }
+ if (!passwd.equals(passwdAgain)) {
+ setErrorMessage("NOTSAMEPASSWD");
+ return false;
+ }
+ return true;
+ }
+
+ private boolean validateInternalToken(int index) {
+ String passwd = mPassword.getText();
+ String passwdAgain = mPasswordAgain.getText();
+ if (mTokenLogin[index].equals(ConfigConstants.TRUE)) {
+ return true;
+ }
+
+ if (mTokenInitialized[index].equals(ConfigConstants.TRUE)) {
+ if (passwd.equals("")) {
+ setErrorMessage("BLANKPASSWD");
+ return false;
+ }
+ return true;
+ }
+
+ if (passwd.equals("") || passwdAgain.equals("")) {
+ setErrorMessage("BLANKPASSWD");
+ return false;
+ }
+ if (!passwd.equals(passwdAgain)) {
+ setErrorMessage("NOTSAMEPASSWD");
+ return false;
+ }
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ mWizardInfo = (InstallWizardInfo)info;
+
+ String customLen = "";
+ if (mKeyLengthText.isEnabled())
+ customLen = mKeyLengthText.getText();
+
+ if (customLen != null && (!customLen.trim().equals(""))) {
+ mWizardInfo.put(ConfigConstants.PR_KEY_LEN, customLen);
+ } else {
+ if (mKeyLengthBox.isVisible()) {
+ mWizardInfo.put(ConfigConstants.PR_KEY_LEN,
+ mKeyLengthBox.getSelectedItem());
+ } else if (mDSAKeyLengthBox.isVisible()) {
+ mWizardInfo.put(ConfigConstants.PR_KEY_LEN,
+ mDSAKeyLengthBox.getSelectedItem());
+ }
+ }
+
+ if (mIsCAKey) {
+ mWizardInfo.put(ConfigConstants.PR_CA_KEYTYPE, mKeyTypeBox.getSelectedItem());
+ mWizardInfo.put(ConfigConstants.PR_CA_KEYTYPE, mKeyTypeBox.getSelectedItem());
+ }
+
+ mWizardInfo.put(ConfigConstants.PR_KEY_TYPE, mKeyTypeBox.getSelectedItem());
+
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_INIT_TOKEN;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ rawData = rawData+"&"+ConfigConstants.PR_TOKEN_NAME+"="+(String)mTokenBox.getSelectedItem();
+ rawData = rawData+"&"+ConfigConstants.PR_TOKEN_PASSWD+"="+mPassword.getText().trim();
+ String sop = mSOPPassword.getText().trim();
+ if (sop != null) {
+ rawData = rawData+"&"+ConfigConstants.PR_TOKEN_SOP+"="+sop;
+ }
+ rawData = rawData+"&"+ConfigConstants.PR_KEY_LEN+"="+mWizardInfo.getKeyLength();
+ rawData = rawData+"&"+ConfigConstants.PR_KEY_TYPE+"="+mWizardInfo.getKeyType();
+ rawData = rawData+"&"+ConfigConstants.PR_CERTIFICATE_TYPE+"="+mWizardInfo.getCertType();
+
+ startProgressStatus();
+// CMSMessageBox dlg = new CMSMessageBox(mAdminFrame, "CGITASK", "INITTOKEN");
+
+ boolean ready = send(rawData, mWizardInfo);
+
+ if (ready) {
+ rawData = rawData+"&"+ConfigConstants.TASKID+"="+TaskId.TASK_TOKEN_INFO;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_READ;
+ ready = send(rawData, mWizardInfo);
+ }
+
+ if (ready) {
+ rawData = rawData+"&"+ConfigConstants.TASKID+"="+TaskId.TASK_CHECK_KEYLENGTH;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ ready = send(rawData, mWizardInfo);
+ }
+
+ //dlg.setVisible(false);
+
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage();
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ mPanelName+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(mHelpIndex);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JPanel panel = new JPanel();
+ GridBagLayout gb1 = new GridBagLayout();
+ panel.setLayout(gb1);
+
+ JPanel panel2 = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ panel2.setLayout(gb3);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ add(panel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ add(panel2, gbc);
+
+ JTextArea selectTokenLbl = createTextArea(mResource.getString(
+ mPanelName+"_LABEL_SELECTTOKEN_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,0);
+ panel.add(selectTokenLbl, gbc);
+
+ JLabel tokenLbl = makeJLabel("TOKEN");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.CENTER;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ panel.add(tokenLbl, gbc);
+
+ mTokenBox = new JComboBox();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.weightx = 1.0;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ panel.add(mTokenBox, gbc);
+
+ JTextArea dummy2 = createTextArea(" ", 1, 5);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ panel.add(dummy2, gbc);
+
+ mTokenLbl = new JLabel("");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ panel2.add(mTokenLbl, gbc);
+
+ mPasswdLbl = makeJLabel("PASSWD");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0,
+ COMPONENT_SPACE);
+ panel2.add(mPasswdLbl, gbc);
+
+ mPassword = new JPasswordField();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ panel2.add(mPassword, gbc);
+
+ mPasswdAgainLbl = makeJLabel("PASSWDAGAIN");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0,
+ COMPONENT_SPACE);
+ panel2.add(mPasswdAgainLbl, gbc);
+
+ mPasswordAgain = new JPasswordField();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ panel2.add(mPasswordAgain, gbc);
+
+ mSOPLbl = makeJLabel("SOP");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel2.add(mSOPLbl, gbc);
+
+ mSOPPassword = new JPasswordField();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel2.add(mSOPPassword, gbc);
+
+ keyHeading = createTextArea(mResource.getString(
+ mPanelName+"_LABEL_KEY_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ add(keyHeading, gbc);
+
+ keyTypeLbl = makeJLabel("KEYTYPE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(keyTypeLbl, gbc);
+
+ mKeyTypeBox = makeJComboBox("KEYTYPE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ add(mKeyTypeBox, gbc);
+
+ keyLengthLbl = makeJLabel("KEYLENGTH");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(keyLengthLbl, gbc);
+
+ mDSAKeyLengthBox = makeJComboBox("DSAKEYLENGTH");
+ mDSAKeyLengthBox.setVisible(false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mDSAKeyLengthBox, gbc);
+
+ mKeyLengthBox = makeJComboBox("KEYLENGTH");
+ mKeyLengthBox.setVisible(true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mKeyLengthBox, gbc);
+
+ unitLbl = makeJLabel("UNITS");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.CENTER;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, 0,COMPONENT_SPACE, COMPONENT_SPACE);
+ add(unitLbl, gbc);
+
+ JPanel panel1 = new JPanel();
+ GridBagLayout gb2 = new GridBagLayout();
+ panel1.setLayout(gb2);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, 0, 0, 0);
+ add(panel1, gbc);
+
+ keyLengthCustomText = makeJLabel("CUSTOMKEY");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ panel1.add(keyLengthCustomText, gbc);
+
+/*
+ keyLengthCustomLbl = makeJLabel("KEYLENGTH");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.CENTER;
+ gbc.fill = gbc.NONE;
+ //gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,0,COMPONENT_SPACE);
+ add(keyLengthCustomLbl, gbc);
+*/
+
+ mKeyLengthText = makeJTextField(7);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ //gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,
+ COMPONENT_SPACE, 0);
+ panel1.add(mKeyLengthText, gbc);
+ mActiveColor = mKeyLengthText.getBackground();
+
+ unit1Lbl = makeJLabel("UNITS");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE);
+ panel1.add(unit1Lbl, gbc);
+
+ JLabel dummy1 = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(dummy1, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ mWizardInfo = (InstallWizardInfo)info;
+ String name = (String)mTokenBox.getSelectedItem();
+ if (name.equalsIgnoreCase(Constants.PR_INTERNAL_TOKEN))
+ name = Constants.PR_INTERNAL_TOKEN_NAME;
+ mWizardInfo.put(ConfigConstants.PR_TOKEN_NAME, name);
+ if (mPassword.isEditable()) {
+ // this is used for single signon. The key is the token name with
+ // the prefix "TOKEN:" and the value is the token password.
+ mWizardInfo.put("TOKEN:"+name, mPassword.getText().trim());
+ }
+
+ mTokenBox.removeItemListener(this);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ }
+
+ public void itemStateChanged(ItemEvent e){
+ //super.itemStateChanged(e);
+ if (e.getSource().equals(mTokenBox)) {
+ JComboBox c = (JComboBox)(e.getSource());
+ if (c.getItemCount() > 0)
+ enableFields();
+ } else if (e.getSource().equals(mKeyLengthBox) ||
+ e.getSource().equals(mDSAKeyLengthBox)) {
+ enableKeyLengthFields();
+ } else if (e.getSource().equals(mKeyTypeBox)) {
+ String type = (String)mKeyTypeBox.getSelectedItem();
+ if (type.equals("RSA")) {
+ mDSAKeyLengthBox.setVisible(false);
+ mKeyLengthBox.setVisible(true);
+ } else {
+ mDSAKeyLengthBox.setVisible(true);
+ mKeyLengthBox.setVisible(false);
+ }
+ enableKeyLengthFields();
+ CMSAdminUtil.repaintComp(this);
+ }
+ }
+
+ protected void enableKeyLengthFields() {
+ String value = "";
+ if (mKeyLengthBox.isVisible())
+ value = (String)mKeyLengthBox.getSelectedItem();
+ else
+ value = (String)mDSAKeyLengthBox.getSelectedItem();
+
+ if (value.equals("Custom")) {
+ enableFields(keyLengthCustomText, mKeyLengthText, true, mActiveColor);
+ enableFields(unit1Lbl, null, true, mActiveColor);
+ } else {
+ enableFields(keyLengthCustomText, mKeyLengthText, false,
+ getBackground());
+ enableFields(unit1Lbl, null, false, getBackground());
+ }
+ }
+
+ protected void enableFields(JComponent comp1, JTextComponent comp2, boolean enable,
+ Color color) {
+ if (comp1 != null) {
+ comp1.setEnabled(enable);
+ CMSAdminUtil.repaintComp(comp1);
+ }
+ if (comp2 != null) {
+ comp2.setEnabled(enable);
+ comp2.setBackground(color);
+ comp2.setEditable(enable);
+ CMSAdminUtil.repaintComp(comp2);
+ }
+ }
+
+
+ protected void enableFields() {
+ int index = mTokenBox.getSelectedIndex();
+
+ if (mTokenLogin[index].equals(ConfigConstants.TRUE)) {
+ mTokenLbl.setText("");
+ enableFields(mTokenLbl, null, false, null);
+ enableFields(mSOPLbl, mSOPPassword, false, getBackground());
+ enableFields(mPasswdLbl, mPassword, false, getBackground());
+ enableFields(mPasswdAgainLbl, mPasswordAgain, false, getBackground());
+ } else {
+ if (mTokenInitialized[index].equals(ConfigConstants.TRUE)) {
+ String str = mResource.getString(mPanelName+"_LABEL_LOGIN_LABEL");
+ mTokenLbl.setText(str);
+ enableFields(mTokenLbl, null, true, null);
+ enableFields(mPasswdAgainLbl, mPasswordAgain, false, getBackground());
+ enableFields(mPasswdLbl, mPassword, true, mActiveColor);
+ enableFields(mSOPLbl, mSOPPassword, false, getBackground());
+/*
+ if (index == 0) {
+ enableFields(mSOPLbl, mSOPPassword, false, getBackground());
+ } else {
+ enableFields(mSOPLbl, mSOPPassword, true, mActiveColor);
+ }
+*/
+ } else {
+ String str = mResource.getString(mPanelName+"_LABEL_INITIALIZE_LABEL");
+ mTokenLbl.setText(str);
+ enableFields(mTokenLbl, null, true, null);
+ enableFields(mTokenLbl, null, true, null);
+ enableFields(mPasswdAgainLbl, mPasswordAgain, true, mActiveColor);
+ enableFields(mPasswdLbl, mPassword, true, mActiveColor);
+ if (index == 0) {
+ enableFields(mSOPLbl, mSOPPassword, false, getBackground());
+ } else {
+ enableFields(mSOPLbl, mSOPPassword, true, mActiveColor);
+ }
+ }
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WILDAPPublishingPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WILDAPPublishingPage.java
new file mode 100644
index 000000000..5cb6b3db3
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WILDAPPublishingPage.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 com.netscape.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Introduction page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WILDAPPublishingPage extends WizardBasePanel implements IWizardPanel {
+ private JTextField mHostNameText, mPortText, mBindAsText;
+ private JCheckBox mSecurePort, mEnable;
+ private JLabel mBindAsLabel, mCertLabel;
+ private JComboBox mAuthBox, mCertBox, mVersionBox;
+
+ private static final String PANELNAME = "LDAPPUBLISHINGWIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+ private static final String EMPTYSTR = " ";
+ private static final String DELIMITER = ",";
+ private final static String[] AUTHTYPE = {Constants.PR_BASIC_AUTH,
+ Constants.PR_SSL_AUTH};
+
+ WILDAPPublishingPage() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea desc = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "INTERNALDBWIZARD_TEXT_HEADING_LABEL"), 80), 2, 80);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ mEnable = makeJCheckBox("ENABLE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mEnable, gbc);
+
+ JPanel panel = new JPanel();
+ panel.setBorder(CMSAdminUtil.makeTitledBorder(mResource,
+ PANELNAME, "DESTINATION"));
+ GridBagLayout gb1 = new GridBagLayout();
+ panel.setLayout(gb1);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.weighty = 1.0;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(panel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel hostName = makeJLabel("HOST");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ panel.add(hostName, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mHostNameText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ panel.add(mHostNameText, gbc);
+
+/*
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea dummy = createTextArea(" ", 2, 5);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ add(dummy, gbc);
+*/
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel portNumber = makeJLabel("PORT");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ panel.add(portNumber, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPortText = makeJTextField(10);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ panel.add(mPortText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mSecurePort = makeJCheckBox("SECUREPORT");
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.weightx = 0.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE - COMPONENT_SPACE,0,COMPONENT_SPACE);
+ panel.add(mSecurePort, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel versionLbl = makeJLabel("VERSION");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel.add(versionLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mVersionBox = makeJComboBox("VERSION");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel.add(mVersionBox, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel dummy = new JLabel(" ");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel.add(dummy, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mBindAsLabel = makeJLabel("BINDAS");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel.add(mBindAsLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mBindAsText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel.add(mBindAsText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mCertLabel = makeJLabel("CERTLIST");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel.add(mCertLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mCertBox = new JComboBox();
+ mCertBox.addItem("internal");
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel.add(mCertBox, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel dummy1 = new JLabel(" ");
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel.add(dummy1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel authLbl = makeJLabel("AUTHTYPE");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.gridheight = gbc.REMAINDER;
+ //gbc.weighty = 1.0;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel.add(authLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mAuthBox = makeJComboBox("AUTHTYPE");
+ //gbc.weighty = 1.0;
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel.add(mAuthBox, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel dummy2 = new JLabel(" ");
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ //gbc.weighty = 1.0;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel.add(dummy2, gbc);
+
+/*
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea dummy1 = createTextArea(" ", 2, 30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(dummy1, gbc);
+*/
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WILoggingPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WILoggingPage.java
new file mode 100644
index 000000000..a28a4795d
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WILoggingPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Introduction page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WILoggingPage extends WizardBasePanel implements IWizardPanel {
+ private JCheckBox mEnableSysLog;
+ private JCheckBox mEnableErrorLog;
+ private JCheckBox mEnableAuditLog;
+ private JComboBox mlogFQC, mLogLevel;
+ private JTextField mlogMaxSizText, mlogBufSizText;
+ private static final String PANELNAME = "LOGGINGWIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+ private static final String EMPTYSTR = " ";
+
+ protected final static int YEAR = 31536000;
+ protected final static int MONTH = 2592000;
+ protected final static int WEEK = 604800;
+ protected final static int DAY = 86400;
+ protected final static int HOUR = 3600;
+
+ WILoggingPage() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEnableSysLog = makeJCheckBox("SYSLOG");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mEnableSysLog, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEnableErrorLog = makeJCheckBox("ERRORLOG");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mEnableErrorLog, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEnableAuditLog = makeJCheckBox("AUDITLOG");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mEnableAuditLog, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel logFQC = makeJLabel("LOGFQC");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ add(logFQC, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mlogFQC = makeJComboBox("LOGFQC");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 0.0;
+ add(mlogFQC, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea dummy1 = new JTextArea(EMPTYSTR, 1, 20);
+ dummy1.setBackground(getBackground());
+ dummy1.setEditable(false);
+ dummy1.setCaretColor(getBackground());
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(dummy1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel logMaxSiz = makeJLabel("LOGMAXSIZ");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ add(logMaxSiz, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mlogMaxSizText = makeJTextField(10);
+ gbc.anchor = gbc.NORTHWEST;
+ add(mlogMaxSizText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel maxLabel = makeJLabel("SIZEUNIT");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(maxLabel, gbc);
+ //mActiveColor = mlogMaxSizText.getBackground();
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel logBufSiz = makeJLabel("LOGBUFSIZ");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ add(logBufSiz, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mlogBufSizText = makeJTextField(10);
+ gbc.anchor = gbc.NORTHWEST;
+ add(mlogBufSizText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel bufferLabel = makeJLabel("SIZEUNIT");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(bufferLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel logLevel = makeJLabel("LOGLEVEL");
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.NORTHEAST;
+ add(logLevel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mLogLevel = makeJComboBox("LOGLEVEL");
+ gbc.anchor = gbc.NORTHWEST;
+ add(mLogLevel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel dummy4 = new JLabel(EMPTYSTR);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(dummy4, gbc);
+
+/*
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel dummy = new JLabel(" ");
+ JLabel dummy5 = new JLabel(" ");
+ gbc.weighty = 0.1;
+ CMSAdminUtil.addEntryField(this, dummy, dummy5, gbc);
+*/
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WILogonAllTokensPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WILogonAllTokensPage.java
new file mode 100644
index 000000000..9a8060b30
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WILogonAllTokensPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import javax.swing.table.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * This panel asks for the information of the current internal database.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WILogonAllTokensPage extends WizardBasePanel implements IWizardPanel {
+ private ProfileDataTable mTable;
+ private static final String EMPTYSTR = " ";
+ private static final String PANELNAME = "LOGONALLTOKENSWIZARD";
+ private static final String HELPINDEX = "install-internaldb-configuration-wizard-help";
+
+ WILogonAllTokensPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WILogonAllTokensPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ setBorder(makeTitledBorder(PANELNAME));
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ String tokenList = wizardInfo.getTokensList();
+ String tokenLoggedIn = wizardInfo.getTokensLogin();
+ String tokenInits = wizardInfo.getTokensInit();
+ StringTokenizer tokenizer = new StringTokenizer(tokenList, ":");
+ StringTokenizer tokenizerLoggedIn = new StringTokenizer(tokenLoggedIn, ":");
+ StringTokenizer tokenizerInits = new StringTokenizer(tokenInits, ":");
+ String loggedIn = "";
+ String inits = "";
+
+ boolean logon = false;
+ Vector defcolNames = new Vector();
+ defcolNames.addElement("Token Name");
+ defcolNames.addElement("Password");
+ Vector defdata = new Vector();
+
+ while (tokenizer.hasMoreElements()) {
+ String token = (String)tokenizer.nextElement();
+ loggedIn = (String)tokenizerLoggedIn.nextElement();
+ inits = (String)tokenizerInits.nextElement();
+
+ // if (loggedIn.equals("false")) {
+ // always logon to the token.
+ if (inits.equals("true")) {
+ Vector v = new Vector();
+ v.addElement(new JLabel(token));
+ v.addElement(new JPasswordField());
+ defdata.addElement(v);
+ logon = true;
+ }
+ //}
+ }
+
+ ProfilePolicyEditDataModel defmodel = new ProfilePolicyEditDataModel();
+ defmodel.setInfo(defdata, defcolNames);
+ mTable.setModel(defmodel);
+
+ return logon;
+ }
+
+ public boolean validatePanel() {
+ for (int i=0; i<mTable.getRowCount(); i++) {
+ JComponent comp = (JComponent)mTable.getValueAt(i,1);
+ if (comp instanceof JPasswordField) {
+ String val2 = ((JPasswordField)comp).getText().trim();
+ if (val2.trim().equals("")) {
+ setErrorMessage("CANNOTBEBLANK");
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ cleanUpWizardInfo(wizardInfo);
+ String tokenNames = "";
+ String pwds = "";
+
+ String val1 = "";
+ String val2 = "";
+ for (int i=0; i<mTable.getRowCount(); i++) {
+ JComponent comp = (JComponent)mTable.getValueAt(i,0);
+ if (comp instanceof JLabel) {
+ val1 = ((JLabel)comp).getText().trim();
+ }
+ JComponent comp1 = (JComponent)mTable.getValueAt(i,1);
+ if (comp1 instanceof JPasswordField) {
+ val2 = ((JPasswordField)comp1).getText().trim();
+ }
+ wizardInfo.put("TOKEN:"+val1, val2);
+ if (i == 0) {
+ tokenNames = val1;
+ pwds = val2;
+ } else {
+ tokenNames = tokenNames+":"+val1;
+ pwds = pwds+":"+val2;
+ }
+ }
+
+ startProgressStatus();
+ String rawData = ConfigConstants.PR_TOKEN_LOGONLIST+"="+tokenNames;
+ rawData = rawData+"&"+ConfigConstants.PR_TOKEN_LOGON_PWDS+"="+pwds;
+ rawData = rawData+"&"+ConfigConstants.TASKID+"="+TaskId.TASK_LOGON_ALL_TOKENS;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ rawData = rawData+"&"+ConfigConstants.PR_CMS_SEED+"="+
+ (new Long(WizardBasePanel.mSeed).toString());
+
+ boolean ready = send(rawData, wizardInfo);
+
+ if (!ready) {
+ String str = getErrorMessage(wizardInfo);
+ if (str == null) {
+ String errorMsg = mResource.getString(
+ PANELNAME+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ } else {
+ rawData = ConfigConstants.TASKID+"="+TaskId.TASK_TOKEN_INFO;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_READ;
+ ready = send(rawData, wizardInfo);
+ }
+
+ if (!ready) {
+ String str = getErrorMessage(wizardInfo);
+ if (str == null)
+ setErrorMessage("Server Error");
+ else
+ setErrorMessage(str);
+ }
+
+ endProgressStatus();
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea desc = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ Vector colNames = new Vector();
+ colNames.addElement("Token Name");
+ colNames.addElement("Password");
+ Vector data = new Vector();
+ Vector row = new Vector();
+ row.addElement("x");
+ row.addElement("x");
+ data.addElement(row);
+ ProfilePolicyEditDataModel dataModel = new ProfilePolicyEditDataModel();
+ dataModel.setInfo(data, colNames);
+ mTable = new ProfileDataTable(dataModel);
+ JScrollPane scrollPane = JTable.createScrollPaneForTable(mTable);
+ scrollPane.setHorizontalScrollBarPolicy(
+ scrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ scrollPane.setVerticalScrollBarPolicy(
+ scrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(
+ ListSelectionModel.SINGLE_INTERVAL_SELECTION);
+ scrollPane.setBackground(Color.white);
+ mTable.setDefaultRenderer(JComponent.class, new ComponentCellRenderer());
+ mTable.setDefaultEditor(JComponent.class,
+ new ProfileComponentCellEditor());
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.BOTH;
+ gbc.weighty = 1.0;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gb.setConstraints(scrollPane, gbc);
+ add(scrollPane, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+
+ private void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(
+ new DefaultTableCellRenderer());
+ }
+
+ private void setLabelCellEditor(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(
+ new PasswordCellRenderer());
+ table.getColumnModel().getColumn(index).setCellEditor(
+ new DefaultCellEditor(new JPasswordField()));
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIManualCACertRequestPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIManualCACertRequestPage.java
new file mode 100644
index 000000000..cb1e092de
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIManualCACertRequestPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * Generate the CA signing certificate request
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIManualCACertRequestPage extends WIManualCertRequestPage {
+ private static final String PANELNAME = "INSTALLMANUALCACERTREQUESTWIZARD";
+ private static final String CAHELPINDEX = "install-cacertrequest-manual-wizard-help";
+ private static final String CAKRAHELPINDEX = "install-cakracertrequest-manual-wizard-help";
+
+ WIManualCACertRequestPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIManualCACertRequestPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isCACloningDone())
+ return false;
+
+ if (wizardInfo.isCACertLocalCA() || !wizardInfo.isCAInstalled() ||
+ wizardInfo.isMigrationEnable() ||
+ wizardInfo.isCACertInstalledDone() ||
+ wizardInfo.isCACertRequestSucc() ||
+ wizardInfo.isSelfSignedCACertDone())
+ return false;
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else
+ mHelpIndex = CAHELPINDEX;
+
+/*
+ mDesc.setText(mResource.getString(
+ mPanelName+"_TEXT_DESC_LABEL"));
+*/
+
+ return super.initializePanel(info);
+ }
+
+ public void back_cb(WizardInfo info) {
+ super.back_cb(info);
+ info.put(ConfigConstants.CA_CERT_REQUEST_BACK,ConfigConstants.TRUE);
+ info.put(ConfigConstants.CA_CERT_REQUEST_BACK,ConfigConstants.TRUE);
+ }
+
+}
+
+
+
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIManualCertRequestPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIManualCertRequestPage.java
new file mode 100644
index 000000000..37adddb98
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIManualCertRequestPage.java
@@ -0,0 +1,178 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.io.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Manual certificate request page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIManualCertRequestPage extends WBaseManualCertRequestPage implements IWizardPanel {
+// private static final String PANELNAME = "INSTALLMANUALCERTREQUESTWIZARD";
+ String mHelpIndex;
+
+ WIManualCertRequestPage(String panelName) {
+ super(panelName);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ return super.initializePanel(info);
+ }
+
+ public boolean validatePanel() {
+ return super.validatePanel();
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ if (!mSendNowBox.isSelected())
+ return true;
+
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (mHost != null && !mHost.equals(""))
+ wizardInfo.setCMHost(mHost);
+ if (mPort != null && !mPort.equals(""))
+ wizardInfo.setCMEEPort(mPort);
+ if (mSSL.isSelected())
+ wizardInfo.setCMEEType("https");
+ else
+ wizardInfo.setCMEEType("http");
+ String certType = null;
+ String rawData = "";
+ if (mReqType.equals(Constants.PR_CA_SIGNING_CERT)){
+ rawData = "profileId=caCACert";
+ }else if (mReqType.equals(Constants.PR_SERVER_CERT) ||
+ mReqType.equals(Constants.PR_KRA_TRANSPORT_CERT)){
+ rawData = "profileId=caServerCert";
+ }else if (mReqType.equals(Constants.PR_OCSP_SIGNING_CERT)){
+ rawData = "profileId=caOCSPCert";
+ }else if (mReqType.equals(Constants.PR_RA_SIGNING_CERT)){
+ rawData = "profileId=caRACert";
+ }else {
+ setErrorMessage("Wrong cert request type!");
+ return false;
+ }
+
+ if (mReqFormat.equals(ConfigConstants.PR_REQUEST_PKCS10)){
+ rawData = rawData+"&cert_request_type=pkcs10";
+ rawData = rawData+"&cert_request="+mReq;
+ } else {
+ rawData = rawData+"&cert_request_type=cmc";
+ rawData = rawData+"&cert_request="+mReq;
+ // test full response, but we don't really need it
+ // data.put("fullResponse", "true");
+ }
+
+ startProgressStatus();
+ boolean ready = send(mHost, Integer.parseInt(mPort),
+ "/ca/ee/ca/profileSubmit", rawData, wizardInfo);
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage();
+ if (str.equals(""))
+ setErrorMessage("Server Error");
+ else
+ setErrorMessage(str);
+ return ready;
+ }
+
+ wizardInfo.setRequestSent(ready);
+
+ //save the stage
+ String reqID = wizardInfo.getRequestID();
+ String reqStatus = wizardInfo.getRequestStatus();
+ String reqError = wizardInfo.getRequestError();
+
+ wizardInfo.setX509RequestID(reqID);
+ wizardInfo.setX509RequestStatus(reqStatus);
+ if (reqError != null)
+ wizardInfo.setX509RequestError(reqError);
+
+ // rejected request should not be saved as requestSuccStage!!
+ if ( (reqID != null) && !reqID.equals("") &&
+ (wizardInfo.getRequestError() == null) &&
+ (reqStatus.equals(Constants.PR_REQUEST_SUCCESS)
+ || reqStatus.equals(Constants.PR_REQUEST_PENDING)
+ || reqStatus.equals(Constants.PR_REQUEST_SVC_PENDING)) ) {
+ rawData = ConfigConstants.TASKID+"="+TaskId.TASK_REQUEST_SUCCESS;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ rawData = rawData+"&"+Constants.PR_CERTIFICATE_TYPE+"="+mReqType;
+ rawData = rawData+"&"+mReqType+ConfigConstants.PR_REQUEST_ID+"="+
+ reqID;
+ rawData = rawData+"&"+ConfigConstants.CA_EEPORT+"="+
+ mPortText.getText();
+ rawData = rawData+"&"+ConfigConstants.CA_EETYPE+"="+
+ wizardInfo.getCMEEType();
+ rawData = rawData+"&"+ConfigConstants.CA_HOST+"="+
+ mHostText.getText();
+
+ startProgressStatus();
+ ready = send(rawData, wizardInfo);
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage();
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ mPanelName+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ return ready;
+ }
+ }
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(mHelpIndex);
+ }
+
+ protected void back_cb(WizardInfo info) {
+ // clear up the status
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ wizardInfo.remove(wizardInfo.getCertType()+ConfigConstants.PR_CERT_REQUEST+"Status");
+ wizardInfo.remove(wizardInfo.getCertRequest()+"Error");
+ wizardInfo.remove(wizardInfo.getCertType()+ConfigConstants.PR_REQUEST_ID);
+ }
+
+ protected void init() {
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIManualKRACertRequestPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIManualKRACertRequestPage.java
new file mode 100644
index 000000000..c1355b3d5
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIManualKRACertRequestPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Generate the CA signing certificate request
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIManualKRACertRequestPage extends WIManualCertRequestPage {
+ private static final String PANELNAME = "INSTALLMANUALKRACERTREQUESTWIZARD";
+ private static final String KRAHELPINDEX = "install-kracertrequest-manual-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakra-kracertrequest-manual-wizard-help";
+ private static final String CAKRAHELPINDEX = "install-cakra-kracertrequest-manual-wizard-help";
+
+ WIManualKRACertRequestPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIManualKRACertRequestPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isKRACloningDone())
+ return false;
+ if (wizardInfo.isKRACertLocalCA() || !wizardInfo.isKRAInstalled() ||
+ wizardInfo.isKRALocalCertDone() ||
+ wizardInfo.isKRACertInstalledDone() ||
+ wizardInfo.isKRACertRequestSucc())
+ return false;
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = KRAHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+
+ public void back_cb(WizardInfo info) {
+ super.back_cb(info);
+ info.put(ConfigConstants.KRA_CERT_REQUEST_BACK,ConfigConstants.TRUE);
+ info.put(ConfigConstants.KRA_REQUEST_DISPLAYED,ConfigConstants.FALSE);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIManualOCSPCertRequestPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIManualOCSPCertRequestPage.java
new file mode 100644
index 000000000..268c6c395
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIManualOCSPCertRequestPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Generate the OCSP signing certificate request
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIManualOCSPCertRequestPage extends WIManualCertRequestPage {
+ private static final String PANELNAME = "INSTALLMANUALOCSPCERTREQUESTWIZARD";
+ private static final String OCSPHELPINDEX = "install-ocspcertrequest-manual-wizard-help";
+
+ WIManualOCSPCertRequestPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIManualOCSPCertRequestPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ if (wizardInfo.isCloning() && wizardInfo.isOCSPCloningDone())
+ return false;
+ if (wizardInfo.isOCSPCertLocalCA() || !wizardInfo.isOCSPInstalled() ||
+ wizardInfo.isOCSPLocalCertDone() ||
+ wizardInfo.isOCSPCertInstalledDone() ||
+ wizardInfo.isOCSPCertRequestSucc() )
+ return false;
+
+ mHelpIndex = OCSPHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+
+ public void back_cb(WizardInfo info) {
+ super.back_cb(info);
+ info.put(ConfigConstants.OCSP_CERT_REQUEST_BACK,ConfigConstants.TRUE);
+ info.put(ConfigConstants.OCSP_REQUEST_DISPLAYED,ConfigConstants.FALSE);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIManualRACertRequestPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIManualRACertRequestPage.java
new file mode 100644
index 000000000..7439ed7b5
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIManualRACertRequestPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Generate the CA signing certificate request
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIManualRACertRequestPage extends WIManualCertRequestPage {
+ private static final String PANELNAME = "INSTALLMANUALRACERTREQUESTWIZARD";
+ private static final String RAHELPINDEX = "install-racertrequest-manual-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakracertrequest-manual-wizard-help";
+
+ WIManualRACertRequestPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIManualRACertRequestPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isRACloningDone())
+ return false;
+ if (wizardInfo.isRACertLocalCA() || !wizardInfo.isRAInstalled() ||
+ wizardInfo.isRALocalCertDone() ||
+ wizardInfo.isRACertInstalledDone() ||
+ wizardInfo.isRACertRequestSucc() )
+ return false;
+
+ if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = RAHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+
+ public void back_cb(WizardInfo info) {
+ super.back_cb(info);
+ info.put(ConfigConstants.RA_CERT_REQUEST_BACK,ConfigConstants.TRUE);
+ info.put(ConfigConstants.RA_REQUEST_DISPLAYED,ConfigConstants.FALSE);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIManualSSLCertRequestPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIManualSSLCertRequestPage.java
new file mode 100644
index 000000000..f96ea5208
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIManualSSLCertRequestPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Generate the CA signing certificate request
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIManualSSLCertRequestPage extends WIManualCertRequestPage {
+ private static final String PANELNAME = "INSTALLMANUALSSLCERTREQUESTWIZARD";
+ private static final String HELPINDEX = "install-sslcertrequest-manual-wizard-help";
+
+ WIManualSSLCertRequestPage(JDialog parent) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = parent;
+ }
+
+ WIManualSSLCertRequestPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning())
+ return false;
+ if (wizardInfo.isSSLCertLocalCA() || wizardInfo.isMigrationEnable() ||
+ wizardInfo.isSSLLocalCertDone() ||
+ wizardInfo.isSSLCertInstalledDone() ||
+ wizardInfo.isSSLCertRequestSucc())
+ return false;
+ return super.initializePanel(info);
+ }
+
+ public void back_cb(WizardInfo info) {
+ super.back_cb(info);
+ info.put(ConfigConstants.SSL_CERT_REQUEST_BACK,ConfigConstants.TRUE);
+ info.put(ConfigConstants.SSL_REQUEST_DISPLAYED,ConfigConstants.FALSE);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIMasterOrClone.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIMasterOrClone.java
new file mode 100644
index 000000000..96c764381
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIMasterOrClone.java
@@ -0,0 +1,172 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Introduction page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIMasterOrClone extends WizardBasePanel implements IWizardPanel {
+ protected JRadioButton mYes;
+ protected JRadioButton mNo;
+ protected JTextArea mLabel;
+ private static final String PANELNAME = "MASTERORCLONE";
+ private static final String HELPINDEX =
+ "install-internaldb-createdbagain-help";
+
+ WIMasterOrClone(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIMasterOrClone(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ setBorder(makeTitledBorder(PANELNAME));
+ if(wizardInfo.isCloning()) {
+ mYes.setSelected(true);
+ mNo.setSelected(false);
+ }else{
+ mYes.setSelected(false);
+ mNo.setSelected(true);
+ }
+ if(wizardInfo.isClonePageDone())
+ return false;
+ else
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ cleanUpWizardInfo(wizardInfo);
+ startProgressStatus();
+ Debug.println("WIMasterOrClone:concludePanel() 1");
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_MASTER_OR_CLONE;
+ rawData = rawData+"&"+ ConfigConstants.OPTYPE+"="+OpDef.OP_READ;
+ if (mYes.isSelected()) {
+ rawData = rawData+"&"+"cloning="+ConfigConstants.TRUE;
+ } else {
+ rawData = rawData+"&"+"cloning="+ConfigConstants.FALSE;
+ rawData = rawData+"&"+ConfigConstants.PR_CLONE_SETTING_DONE+"="+ConfigConstants.TRUE;
+ }
+ rawData = rawData+"&"+ConfigConstants.PR_CMS_SEED+"="+(new Long(WizardBasePanel.mSeed).toString());
+ Debug.println("WIMasterOrClone:concludePanel() 2");
+ boolean ready = send(rawData, wizardInfo);
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage(wizardInfo);
+ if (str == null)
+ setErrorMessage("Server Error");
+ else
+ setErrorMessage(str);
+ }else if (!mYes.isSelected()){
+ wizardInfo.setClonePageDone(ConfigConstants.TRUE);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mLabel = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mLabel, gbc);
+
+
+ mYes = makeJRadioButton("YES", false);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mYes, gbc);
+
+ mNo = makeJRadioButton("NO", false);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mNo, gbc);
+
+ ButtonGroup buttonGroup = new ButtonGroup();
+ buttonGroup.add(mYes);
+ buttonGroup.add(mNo);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (mYes.isSelected()) {
+ wizardInfo.setCloning(ConfigConstants.TRUE);
+ } else {
+ wizardInfo.setCloning(ConfigConstants.FALSE);
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIMigrationPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIMigrationPage.java
new file mode 100644
index 000000000..ab9bcebb9
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIMigrationPage.java
@@ -0,0 +1,715 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * Migration page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIMigrationPage extends WizardBasePanel implements IWizardPanel, ItemListener {
+ private JLabel mTransportLbl, mDBLbl;
+ private JPasswordField mTransportPassword, mDBPassword;
+ private JLabel mCAPasswdLbl, mCAPasswdAgainLbl, mCASOPLbl;
+ private JPasswordField mCAPassword, mCAPasswordAgain, mCASOPPassword;
+ private JLabel mSSLPasswdLbl, mSSLPasswdAgainLbl, mSSLSOPLbl;
+ private JPasswordField mSSLPassword, mSSLPasswordAgain, mSSLSOPPassword;
+ private JLabel mPathLbl, mCATokenHeading, mSSLTokenHeading;
+ private JLabel mCATokenLbl, mSSLTokenLbl;
+ private JTextField mPathText;
+ private JComboBox mCATokenBox, mSSLTokenBox;
+ private String[] mTokenInitialized;
+ private String[] mTokenLogin;
+ private Color mActiveColor;
+ private JLabel mLogonInitCATokenLbl, mLogonInitSSLTokenLbl;
+ private String mHelpIndex;
+ private InstallWizardInfo mWizardInfo;
+ private static final String PANELNAME = "MIGRATIONWIZARD";
+ private static final String CAHELPINDEX =
+ "install-ca-migration-configuration-wizard-help";
+ private static final String CAKRAHELPINDEX =
+ "install-cakra-migration-configuration-wizard-help";
+
+ WIMigrationPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIMigrationPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ mWizardInfo = (InstallWizardInfo)info;
+ if (!mWizardInfo.isMigrationEnable() || !mWizardInfo.isCAInstalled() ||
+ mWizardInfo.isMigrationDone())
+ return false;
+ setBorder(makeTitledBorder(PANELNAME));
+ initializeTokenBox(mCATokenBox);
+
+ if (mSSLTokenBox.getItemCount() > 0)
+ mSSLTokenBox.removeAllItems();
+ for (int i=0; i<mCATokenBox.getItemCount(); i++) {
+ String str = (String)mCATokenBox.getItemAt(i);
+ mSSLTokenBox.addItem(str);
+ }
+ int index = mCATokenBox.getSelectedIndex();
+ mWizardInfo.setMigrateCACertTokenName((String)mCATokenBox.getSelectedItem());
+ enableFields(index, mLogonInitCATokenLbl, mCAPasswdLbl, mCAPassword,
+ mCAPasswdAgainLbl, mCAPasswordAgain, mCASOPLbl, mCASOPPassword);
+
+ index = mSSLTokenBox.getSelectedIndex();
+ mWizardInfo.setMigrateSSLCertTokenName((String)mSSLTokenBox.getSelectedItem());
+ enableFields(index, mLogonInitSSLTokenLbl, mSSLPasswdLbl, mSSLPassword,
+ mSSLPasswdAgainLbl, mSSLPasswordAgain, mSSLSOPLbl, mSSLSOPPassword);
+
+ mCATokenBox.addItemListener(this);
+ mSSLTokenBox.addItemListener(this);
+ enablePasswordFields();
+
+ if (mWizardInfo.isCAInstalled() && mWizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else
+ mHelpIndex = CAHELPINDEX;
+
+ return true;
+ }
+
+ private void initializeTokenBox(JComboBox tokenBox) {
+ if (tokenBox.getItemCount() > 0)
+ tokenBox.removeAllItems();
+
+ String tokenList = mWizardInfo.getTokensList();
+ StringTokenizer tokenizer = new StringTokenizer(tokenList, ":");
+ int count = tokenizer.countTokens();
+ while (tokenizer.hasMoreTokens()) {
+ tokenBox.addItem((String)tokenizer.nextToken());
+ }
+
+ String initializedList = mWizardInfo.getTokensInit();
+ tokenizer = new StringTokenizer(initializedList, ":");
+ int i=0;
+ mTokenInitialized = new String[count];
+ while (tokenizer.hasMoreElements()) {
+ mTokenInitialized[i] = (String)tokenizer.nextToken();
+ i++;
+ }
+
+ String loginList = mWizardInfo.getTokensLogin();
+ tokenizer = new StringTokenizer(loginList, ":");
+ i=0;
+ mTokenLogin = new String[count];
+ while (tokenizer.hasMoreElements()) {
+ mTokenLogin[i] = (String)tokenizer.nextToken();
+ i++;
+ }
+ }
+
+ public boolean validatePanel() {
+ int caindex = mCATokenBox.getSelectedIndex();
+ boolean status = false;
+
+ if (caindex > 0) {
+ status = validateHardwareToken(caindex, mCAPassword, mCAPasswordAgain,
+ mCASOPPassword);
+ } else {
+ status = validateInternalToken(caindex, mCAPassword, mCAPasswordAgain);
+ }
+
+ if (!status)
+ return false;
+
+ int sslindex = mSSLTokenBox.getSelectedIndex();
+ if (sslindex != caindex) {
+ if (sslindex > 0) {
+ status = validateHardwareToken(sslindex, mSSLPassword, mSSLPasswordAgain,
+ mSSLSOPPassword);
+ } else {
+ status = validateInternalToken(sslindex, mSSLPassword, mSSLPasswordAgain);
+ }
+ }
+
+ return status;
+ }
+
+ private boolean validateHardwareToken(int index, JPasswordField passwdField,
+ JPasswordField passwdAgainField, JPasswordField sopPasswdField) {
+ String caPasswd = mCAPassword.getText().trim();
+ String caPasswdAgain = mCAPasswordAgain.getText().trim();
+ String sslPasswd = mSSLPassword.getText().trim();
+ String sslPasswdAgain = mSSLPasswordAgain.getText().trim();
+ String sopPasswd = sopPasswdField.getText();
+ if (mTokenLogin[index].equals(ConfigConstants.TRUE)) {
+ return true;
+ }
+
+ if (mTokenInitialized[index].equals(ConfigConstants.TRUE)) {
+ if (caPasswd.equals("")) {
+ //if (caPasswd.equals("") || sopPasswd.equals("")) {
+ setErrorMessage("BLANKPASSWD");
+ return false;
+ }
+ return true;
+ }
+
+ if (caPasswd.equals("") || caPasswdAgain.equals("") || sopPasswd.equals("")) {
+ setErrorMessage("BLANKPASSWD");
+ return false;
+ }
+ if (!caPasswd.equals(caPasswdAgain)) {
+ setErrorMessage("NOTSAMEPASSWD");
+ return false;
+ }
+ return true;
+ }
+
+ private boolean validateInternalToken(int index, JPasswordField passwdField,
+ JPasswordField passwdAgainField) {
+ String passwd = passwdField.getText();
+ String passwdAgain = passwdAgainField.getText();
+ if (mTokenLogin[index].equals(ConfigConstants.TRUE)) {
+ return true;
+ }
+
+ if (mTokenInitialized[index].equals(ConfigConstants.TRUE)) {
+ if (passwd.equals("")) {
+ setErrorMessage("BLANKPASSWD");
+ return false;
+ }
+ return true;
+ }
+
+ if (passwd.equals("") || passwdAgain.equals("")) {
+ setErrorMessage("BLANKPASSWD");
+ return false;
+ }
+ if (!passwd.equals(passwdAgain)) {
+ setErrorMessage("NOTSAMEPASSWD");
+ return false;
+ }
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ Hashtable data = new Hashtable();
+ String caTokenName = "";
+ String sslTokenName = "";
+ if (mCATokenBox.getSelectedIndex() == 0) {
+ caTokenName = Constants.PR_INTERNAL_TOKEN_NAME;
+ } else {
+ caTokenName = (String)mCATokenBox.getSelectedItem();
+ }
+ if (mSSLTokenBox.getSelectedIndex() == 0) {
+ sslTokenName = Constants.PR_INTERNAL_TOKEN_NAME;
+ } else {
+ sslTokenName = (String)mSSLTokenBox.getSelectedItem();
+ }
+
+ mWizardInfo.setCATokenName(caTokenName);
+ mWizardInfo.setSSLTokenName(sslTokenName);
+ mWizardInfo.setMigrationOutputPath(mPathText.getText().trim());
+ //mWizardInfo.setInternalDBPasswd(mDBPassword.getText().trim());
+ mWizardInfo.setMigrationPasswd(mTransportPassword.getText().trim());
+ mWizardInfo.setSigningKeyMigrationToken(caTokenName);
+ mWizardInfo.setSigningKeyMigrationPasswd(mCAPassword.getText().trim());
+ if (mCATokenBox.getSelectedIndex() > 0) {
+ mWizardInfo.setSigningKeyMigrationSOPPasswd(mCASOPPassword.getText().trim());
+ data.put(ConfigConstants.PR_SIGNING_KEY_MIGRATION_TOKEN_SOPPASSWD,
+ mWizardInfo.getSigningKeyMigrationSOPPasswd());
+ }
+ mWizardInfo.setSSLKeyMigrationToken(sslTokenName);
+
+ if (caTokenName.equals(sslTokenName))
+ mWizardInfo.setSSLKeyMigrationPasswd(mCAPassword.getText().trim());
+ else
+ mWizardInfo.setSSLKeyMigrationPasswd(mSSLPassword.getText().trim());
+
+ if (mSSLTokenBox.getSelectedIndex() > 0) {
+ mWizardInfo.setSSLKeyMigrationSOPPasswd(mSSLSOPPassword.getText().trim());
+ data.put(ConfigConstants.PR_SSL_KEY_MIGRATION_TOKEN_SOPPASSWD,
+ mWizardInfo.getSSLKeyMigrationSOPPasswd());
+ }
+ ConsoleInfo consoleInfo = mWizardInfo.getAdminConsoleInfo();
+ CMSConfigCert configCertCgi = new CMSConfigCert();
+ configCertCgi.initialize(mWizardInfo);
+ data.put(ConfigConstants.PR_CERT_INSTANCE_NAME,
+ consoleInfo.get(ConfigConstants.PR_CERT_INSTANCE_NAME));
+
+ data.put(ConfigConstants.TASKID, TaskId.TASK_MIGRATION);
+ data.put(ConfigConstants.OPTYPE, OpDef.OP_MODIFY);
+ if (mWizardInfo.isMigrationEnable())
+ data.put(ConfigConstants.PR_ENABLE_MIGRATION, ConfigConstants.TRUE);
+ else
+ data.put(ConfigConstants.PR_ENABLE_MIGRATION, ConfigConstants.FALSE);
+ data.put(ConfigConstants.PR_OUTPUT_PATH,
+ mWizardInfo.getMigrationOutputPath());
+ if (mWizardInfo.getInternalDBPasswd() != null)
+ data.put(ConfigConstants.PR_DB_PWD,
+ mWizardInfo.getInternalDBPasswd());
+ data.put(ConfigConstants.PR_MIGRATION_PASSWORD,
+ mWizardInfo.getMigrationPasswd());
+ data.put(ConfigConstants.PR_SIGNING_KEY_MIGRATION_TOKEN,
+ mWizardInfo.getSigningKeyMigrationToken());
+ data.put(ConfigConstants.PR_SIGNING_KEY_MIGRATION_TOKEN_PASSWD,
+ mWizardInfo.getSigningKeyMigrationPasswd());
+ data.put(ConfigConstants.PR_SSL_KEY_MIGRATION_TOKEN,
+ mWizardInfo.getSSLKeyMigrationToken());
+ data.put(ConfigConstants.PR_SSL_KEY_MIGRATION_TOKEN_PASSWD,
+ mWizardInfo.getSSLKeyMigrationPasswd());
+
+ startProgressStatus();
+ boolean ready = configCertCgi.configCert(data);
+ endProgressStatus();
+
+ mWizardInfo.put("TOKEN:"+caTokenName, mCAPassword.getText().trim());
+ mWizardInfo.put("TOKEN:"+sslTokenName,
+ mSSLPassword.getText().trim());
+
+ if (!ready) {
+ String str = configCertCgi.getErrorMessage();
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ PANELNAME+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void itemStateChanged(ItemEvent e) {
+ super.itemStateChanged(e);
+ int index = 0;
+ if (e.getSource().equals(mCATokenBox)) {
+ index = mCATokenBox.getSelectedIndex();
+ mWizardInfo.setMigrateCACertTokenName((String)mCATokenBox.getSelectedItem());
+ enableFields(index, mLogonInitCATokenLbl, mCAPasswdLbl, mCAPassword,
+ mCAPasswdAgainLbl, mCAPasswordAgain, mCASOPLbl, mCASOPPassword);
+ enablePasswordFields();
+ } else if (e.getSource().equals(mSSLTokenBox)) {
+ index = mSSLTokenBox.getSelectedIndex();
+ mWizardInfo.setMigrateSSLCertTokenName((String)mSSLTokenBox.getSelectedItem());
+ enableFields(index, mLogonInitSSLTokenLbl, mSSLPasswdLbl, mSSLPassword,
+ mSSLPasswdAgainLbl, mSSLPasswordAgain, mSSLSOPLbl, mSSLSOPPassword);
+ enablePasswordFields();
+ }
+ }
+
+ private void enableFields(int index, JLabel logonInitLbl, JLabel passwdLbl,
+ JPasswordField passwd, JLabel passwdAgainLbl, JPasswordField passwdAgain,
+ JLabel sopLbl, JPasswordField sopPasswd) {
+ if (mTokenLogin[index].equals(ConfigConstants.TRUE)) {
+ logonInitLbl.setText("");
+ enableFields(logonInitLbl, null, false, null);
+ enableFields(sopLbl, sopPasswd, false, getBackground());
+ enableFields(passwdLbl, passwd, false, getBackground());
+ enableFields(passwdAgainLbl, passwdAgain, false, getBackground());
+ } else {
+ if (mTokenInitialized[index].equals(ConfigConstants.TRUE)) {
+ String str = mResource.getString(PANELNAME+"_LABEL_LOGIN_LABEL");
+ logonInitLbl.setText(str);
+ enableFields(logonInitLbl, null, true, null);
+ enableFields(passwdAgainLbl, passwdAgain, false, getBackground());
+ enableFields(passwdLbl, passwd, true, mActiveColor);
+ enableFields(sopLbl, sopPasswd, false, getBackground());
+ } else {
+ String str = mResource.getString(PANELNAME+"_LABEL_INITIALIZE_LABEL")
+;
+ logonInitLbl.setText(str);
+ enableFields(logonInitLbl, null, true, null);
+ enableFields(logonInitLbl, null, true, null);
+ enableFields(passwdAgainLbl, passwdAgain, true, mActiveColor);
+ enableFields(passwdLbl, passwd, true, mActiveColor);
+ if (index == 0) {
+ enableFields(sopLbl, sopPasswd, false, getBackground());
+ } else {
+ enableFields(sopLbl, sopPasswd, true, mActiveColor);
+ }
+ }
+ }
+ }
+
+ protected void enableFields(JComponent comp1, JTextComponent comp2,
+ boolean enable, Color color) {
+ if (comp1 != null) {
+ comp1.setEnabled(enable);
+ CMSAdminUtil.repaintComp(comp1);
+ }
+ if (comp2 != null) {
+ comp2.setEnabled(enable);
+ comp2.setBackground(color);
+ comp2.setEditable(enable);
+ CMSAdminUtil.repaintComp(comp2);
+ }
+ }
+
+ protected void enablePasswordFields() {
+ String caTokenStr = (String)mCATokenBox.getSelectedItem();
+ String sslTokenStr = (String)mSSLTokenBox.getSelectedItem();
+ if (caTokenStr.equals(sslTokenStr)) {
+ enableFields(mSSLPasswdLbl, mSSLPassword, false, getBackground());
+ enableFields(mSSLPasswdAgainLbl, mSSLPasswordAgain, false, getBackground());
+ } else {
+ enableFields(mSSLPasswdLbl, mSSLPassword, true, mActiveColor);
+ enableFields(mSSLPasswdAgainLbl, mSSLPasswordAgain, true, mActiveColor);
+ }
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(mHelpIndex);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+/*
+ JTextArea desc = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "MIGRATIONWIZARD_TEXT_DESC_LABEL"), 80), 1, 80);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+*/
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPathLbl = makeJLabel("PATH");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(mPathLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPathText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mPathText, gbc);
+
+ mTransportLbl = makeJLabel("TRANSPORTPASSWORD");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(mTransportLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mTransportPassword = makeJPasswordField(20);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mTransportPassword, gbc);
+ mActiveColor = mTransportPassword.getBackground();
+
+/*
+ mDBLbl = makeJLabel("DBPASSWORD");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mDBLbl, gbc);
+
+ mDBPassword = makeJPasswordField(20);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mDBPassword, gbc);
+*/
+
+ JPanel panel1 = new JPanel();
+ GridBagLayout gb1 = new GridBagLayout();
+ panel1.setLayout(gb1);
+
+ mCATokenHeading = makeJLabel("SELECTCATOKEN");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel1.add(mCATokenHeading, gbc);
+
+ mCATokenLbl = makeJLabel("TOKEN");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ panel1.add(mCATokenLbl, gbc);
+
+ mCATokenBox = new JComboBox();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ //gbc.weightx = 1.0;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ panel1.add(mCATokenBox, gbc);
+
+ JTextArea dummy1 = createTextArea(" ", 1, 5);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ panel1.add(dummy1, gbc);
+
+ JPanel panel1a = new JPanel();
+ GridBagLayout gb1a = new GridBagLayout();
+ panel1a.setLayout(gb1a);
+
+ mLogonInitCATokenLbl = new JLabel("Initialize the selected token:");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, 0, 0, COMPONENT_SPACE);
+ panel1a.add(mLogonInitCATokenLbl, gbc);
+
+ mCAPasswdLbl = makeJLabel("PASSWD");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0,
+ COMPONENT_SPACE);
+ panel1a.add(mCAPasswdLbl, gbc);
+
+ mCAPassword = new JPasswordField();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ panel1a.add(mCAPassword, gbc);
+
+ mCAPasswdAgainLbl = makeJLabel("PASSWDAGAIN");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0,
+ COMPONENT_SPACE);
+ panel1a.add(mCAPasswdAgainLbl, gbc);
+
+ mCAPasswordAgain = new JPasswordField();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ panel1a.add(mCAPasswordAgain, gbc);
+
+ mCASOPLbl = makeJLabel("SOP");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel1a.add(mCASOPLbl, gbc);
+
+ mCASOPPassword = new JPasswordField();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel1a.add(mCASOPPassword, gbc);
+
+ JPanel panel2 = new JPanel();
+ GridBagLayout gb2 = new GridBagLayout();
+ panel2.setLayout(gb2);
+
+ mSSLTokenHeading = makeJLabel("SELECTSSLTOKEN");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel2.add(mSSLTokenHeading, gbc);
+
+ mSSLTokenLbl = makeJLabel("TOKEN");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ panel2.add(mSSLTokenLbl, gbc);
+
+ mSSLTokenBox = new JComboBox();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ //gbc.weightx = 1.0;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ panel2.add(mSSLTokenBox, gbc);
+
+ JTextArea dummy1a = createTextArea(" ", 1, 5);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ panel2.add(dummy1a, gbc);
+
+ JPanel panel2a = new JPanel();
+ GridBagLayout gb2a = new GridBagLayout();
+ panel2a.setLayout(gb2a);
+
+ mLogonInitSSLTokenLbl = new JLabel("Initialize the SSL token");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, 0, 0, COMPONENT_SPACE);
+ panel2a.add(mLogonInitSSLTokenLbl, gbc);
+
+ mSSLPasswdLbl = makeJLabel("PASSWD");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0,
+ COMPONENT_SPACE);
+ panel2a.add(mSSLPasswdLbl, gbc);
+
+ mSSLPassword = new JPasswordField();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ panel2a.add(mSSLPassword, gbc);
+
+ mSSLPasswdAgainLbl = makeJLabel("PASSWDAGAIN");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0,
+ COMPONENT_SPACE);
+ panel2a.add(mSSLPasswdAgainLbl, gbc);
+
+ mSSLPasswordAgain = new JPasswordField();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ panel2a.add(mSSLPasswordAgain, gbc);
+
+ mSSLSOPLbl = makeJLabel("SOP");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel2a.add(mSSLSOPLbl, gbc);
+
+ mSSLSOPPassword = new JPasswordField();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ panel2a.add(mSSLSOPPassword, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gbc.weightx = 1.0;
+ add(panel1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gbc.weightx = 1.0;
+ add(panel1a, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gbc.weightx = 1.0;
+ add(panel2, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gbc.weightx = 1.0;
+ add(panel2a, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel dumLbl = new JLabel("");
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ add(dumLbl, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WINetworkPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WINetworkPage.java
new file mode 100644
index 000000000..823980d56
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WINetworkPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * Network panel for configurating the admin and EE port.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+class WINetworkPage extends WizardBasePanel implements IWizardPanel {
+ private Color mActiveColor;
+
+ // TextField for port
+ private JTextField mAdminSSLPortText;
+ private JTextField mAgentSSLPortText;
+ private JTextField mGatewayPortText;
+ private JTextField mGatewaySSLPortText;
+ private JCheckBox mEnable;
+
+ private JTextArea mAgentDesc;
+ private JLabel mAgentPortLbl;
+ private JTextField mPortText;
+
+ protected AdminConnection mAdmin;
+ private boolean mBlankFieldError = false;
+ private boolean mNumberError = false;
+ private JLabel mPortLabel, mSSLPortLabel;
+
+ private static final String HELPINDEX =
+ "install-network-configuration-wizard-help";
+ private static final String PANELNAME = "NETWORKWIZARD";
+ private static final int MAX_PORT = 65535;
+ private static final int MIN_PORT = 1;
+ private boolean mEnableEEPorts;
+ private InstallWizardInfo mWizardInfo;
+ private boolean mWarning;
+
+ WINetworkPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WINetworkPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ mWizardInfo = wizardInfo;
+ if (wizardInfo.isNetworkDone())
+ return false;
+ setBorder(makeTitledBorder(PANELNAME));
+ boolean cloning = mWizardInfo.isCloning();
+ String selected_sub = mWizardInfo.getCloneSubsystem();
+ if (!cloning ||
+ (cloning && (selected_sub != null && !selected_sub.equals("ca")))) {
+ mAgentDesc.setVisible(false);
+ mAgentPortLbl.setVisible(false);
+ mPortText.setVisible(false);
+ }
+
+ if (wizardInfo.isOCSPInstalled() || wizardInfo.isOCSPServiceAdded()) {
+ mEnable.setSelected(true);
+ } else {
+ mEnable.setSelected(wizardInfo.isEEEnabled());
+ }
+
+ if (wizardInfo.isRAInstalled())
+ mEnable.setSelected(true);
+ mAdminSSLPortText.setText(wizardInfo.getAdminPort());
+ mAgentSSLPortText.setText(wizardInfo.getAgentPort());
+ if (!wizardInfo.isCAInstalled() && !wizardInfo.isRAInstalled() &&
+ wizardInfo.isKRAInstalled()) {
+ enableFields(mPortLabel, mGatewayPortText, false, getBackground());
+ enableFields(mSSLPortLabel, mGatewaySSLPortText, false, getBackground());
+ mEnable.setEnabled(false);
+ mEnableEEPorts = false;
+ } else {
+ mGatewaySSLPortText.setText(wizardInfo.getEESecurePort());
+ mGatewayPortText.setText(wizardInfo.getEEPort());
+ mEnable.setEnabled(true);
+ if (mEnable.isSelected()) {
+ enableFields(true, mActiveColor);
+ enableFields(mPortLabel, mGatewayPortText, true, mActiveColor);
+ } else {
+ enableFields(false, getBackground());
+ enableFields(mPortLabel, mGatewayPortText, false, getBackground());
+ }
+ enableFields(mSSLPortLabel, mGatewaySSLPortText, true, mActiveColor);
+ mEnableEEPorts = true;
+ }
+
+ return true;
+ }
+
+ private void enableFields(JComponent comp1, JTextComponent comp2,
+ boolean enable, Color color) {
+ if (comp1 != null) {
+ comp1.setEnabled(enable);
+ CMSAdminUtil.repaintComp(comp1);
+ }
+ if (comp2 != null) {
+ comp2.setEnabled(enable);
+ comp2.setBackground(color);
+ comp2.setEditable(enable);
+ CMSAdminUtil.repaintComp(comp2);
+ }
+ }
+
+ public boolean validatePanel() {
+ String adminPort = mAdminSSLPortText.getText().trim();
+ String agentPort = mAgentSSLPortText.getText().trim();
+ String eePort = mGatewayPortText.getText().trim();
+ String sslEEPort = mGatewaySSLPortText.getText().trim();
+ String masteragentport = mPortText.getText().trim();
+
+ if (adminPort.equals("") || agentPort.equals("")) {
+ setErrorMessage("BLANKFIELD");
+ return false;
+ }
+
+ if (mEnableEEPorts) {
+ if (sslEEPort.equals("") || (mEnable.isSelected() && eePort.equals(""))) {
+ setErrorMessage("BLANKFIELD");
+ return false;
+ }
+ }
+
+ boolean cloning = mWizardInfo.isCloning();
+ String selected_sub = mWizardInfo.getCloneSubsystem();
+ if (cloning && (selected_sub != null && selected_sub.equals("ca"))) {
+ if (masteragentport.equals("")) {
+ setErrorMessage("BLANKFIELD");
+ return false;
+ }
+ }
+
+ int num = 0;
+ try {
+ num = Integer.parseInt(adminPort);
+ if (num < MIN_PORT || num > MAX_PORT) {
+ setErrorMessage("PORTRANGE");
+ return false;
+ }
+ num = Integer.parseInt(agentPort);
+ if (num < MIN_PORT || num > MAX_PORT) {
+ setErrorMessage("PORTRANGE");
+ return false;
+ }
+ if (mEnableEEPorts) {
+ num = Integer.parseInt(sslEEPort);
+ if (num < MIN_PORT || num > MAX_PORT) {
+ setErrorMessage("PORTRANGE");
+ return false;
+ }
+ if (mEnable.isSelected()) {
+ num = Integer.parseInt(eePort);
+ if (num < MIN_PORT || num > MAX_PORT) {
+ setErrorMessage("PORTRANGE");
+ return false;
+ }
+ }
+ }
+ if (cloning && (selected_sub != null && selected_sub.equals("ca")))
+ num = Integer.parseInt(masteragentport);
+ } catch (NumberFormatException e) {
+ setErrorMessage("NUMBERFORMAT");
+ return false;
+ }
+
+ if (adminPort.equals(agentPort) || agentPort.equals(sslEEPort) ||
+ (mEnable.isSelected() && eePort.equals(sslEEPort))) {
+ setErrorMessage("SAMEPORT");
+ return false;
+ }
+
+ if (mEnableEEPorts) {
+ if (agentPort.equals(sslEEPort) ||
+ (mEnable.isSelected() && eePort.equals(sslEEPort))) {
+ setErrorMessage("SAMEPORT");
+ return false;
+ }
+ }
+ setErrorMessage("");
+ return true;
+ }
+
+ private void setEEPorts(InstallWizardInfo wizardInfo, Hashtable data) {
+ String eePort = mGatewayPortText.getText().trim();
+ String eeSSLPort = mGatewaySSLPortText.getText().trim();
+ wizardInfo.setEEPort(eePort);
+ wizardInfo.setEESecurePort(eeSSLPort);
+ data.put(ConfigConstants.PR_EE_PORT, eePort);
+ data.put(ConfigConstants.PR_EE_SECURE_PORT, eeSSLPort);
+ if (mEnable.isSelected()) {
+ data.put(ConfigConstants.PR_EE_PORT_ENABLE,
+ ConfigConstants.TRUE);
+ wizardInfo.setEEEnable(ConfigConstants.TRUE);
+ } else {
+ data.put(ConfigConstants.PR_EE_PORT_ENABLE,
+ ConfigConstants.FALSE);
+ wizardInfo.setEEEnable(ConfigConstants.FALSE);
+ }
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ ConsoleInfo consoleInfo = wizardInfo.getAdminConsoleInfo();
+ CMSConfigCert configCertCgi = new CMSConfigCert();
+ configCertCgi.initialize(wizardInfo);
+ Hashtable data = new Hashtable();
+ data.put(ConfigConstants.TASKID, TaskId.TASK_CONFIGURE_NETWORK);
+ data.put(ConfigConstants.OPTYPE, OpDef.OP_MODIFY);
+ String agentPort = mAgentSSLPortText.getText().trim();
+ String radmPort = mAdminSSLPortText.getText().trim();
+ wizardInfo.setAgentPort(agentPort);
+ wizardInfo.setAdminPort(radmPort);
+ data.put(ConfigConstants.PR_AGENT_PORT, agentPort);
+ data.put(ConfigConstants.PR_RADM_PORT, radmPort);
+ data.put(ConfigConstants.PR_CERT_INSTANCE_NAME,
+ consoleInfo.get(ConfigConstants.PR_CERT_INSTANCE_NAME));
+ boolean cloning = mWizardInfo.isCloning();
+ String selected_sub = mWizardInfo.getCloneSubsystem();
+ if (cloning && (selected_sub != null && selected_sub.equals("ca")))
+ data.put(Constants.PR_MASTER_AGENT_PORT, mPortText.getText().trim());
+
+ if (mEnableEEPorts) {
+ setEEPorts(wizardInfo, data);
+ data.put(ConfigConstants.PR_EE_PORTS_ENABLE, ConfigConstants.TRUE);
+ } else
+ data.put(ConfigConstants.PR_EE_PORTS_ENABLE, ConfigConstants.FALSE);
+
+ startProgressStatus();
+ boolean ready = configCertCgi.configCert(data);
+ endProgressStatus();
+
+ if (!ready) {
+ String str = configCertCgi.getErrorMessage();
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ PANELNAME+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea heading = createTextArea(mResource.getString(
+ "NETWORKWIZARD_TEXT_DESC_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(heading, gbc);
+
+ JLabel adminSSLport = makeJLabel("ADMINSSLPORT");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ add(adminSSLport, gbc);
+
+ mAdminSSLPortText = makeJTextField(10);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ //gbc.gridwidth = gbc.REMAINDER;
+ //gbc.fill = gbc.NONE;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(mAdminSSLPortText, gbc);
+ mActiveColor = mAdminSSLPortText.getBackground();
+
+ JLabel dummy2a = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ add(dummy2a, gbc);
+
+ JLabel agentPort = makeJLabel("AGENTSSLPORT");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ add(agentPort, gbc);
+
+ mAgentSSLPortText = makeJTextField(10);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ //gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ //gbc.gridwidth = gbc.REMAINDER;
+ add(mAgentSSLPortText, gbc);
+
+ JLabel dummy2b = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ add(dummy2b, gbc);
+
+ mSSLPortLabel = makeJLabel("GATEWAYSSLPORT");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.anchor = gbc.EAST;
+ add(mSSLPortLabel, gbc);
+
+ mGatewaySSLPortText = makeJTextField(10);
+ CMSAdminUtil.resetGBC(gbc);
+ //gbc.fill = gbc.NONE;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.anchor = gbc.WEST;
+ //gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mGatewaySSLPortText, gbc);
+
+ JLabel dummy2c = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ add(dummy2c, gbc);
+
+ mPortLabel = makeJLabel("GATEWAYPORT");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,COMPONENT_SPACE);
+ add(mPortLabel, gbc);
+
+ mGatewayPortText = makeJTextField(10);
+ CMSAdminUtil.resetGBC(gbc);
+ //gbc.fill = gbc.NONE;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.anchor = gbc.WEST;
+ add(mGatewayPortText, gbc);
+
+ // 610632 - remove the enable button
+
+ JLabel enableLbl = makeJLabel("ENABLED");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.CENTER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ // add(enableLbl, gbc);
+
+ mEnable = new JCheckBox();
+ mEnable.addActionListener(this);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ // add(mEnable, gbc);
+
+ JLabel dummy1 = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ add(dummy1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mAgentDesc = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING1_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(2*COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mAgentDesc, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mAgentPortLbl = makeJLabel("AGENTPORT");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mAgentPortLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPortText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mPortText, gbc);
+
+ JLabel dummy2 = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ add(dummy2, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (mEnable.isSelected()) {
+ enableFields(true, mActiveColor);
+ } else {
+ if (!mWarning && (mWizardInfo.isOCSPInstalled() || mWizardInfo.isOCSPServiceAdded())) {
+ mWarning = true;
+ String errormsg = mResource.getString(mPanelName+"_WARNING");
+ JOptionPane.showMessageDialog(mAdminFrame, errormsg, "Warning",
+ JOptionPane.WARNING_MESSAGE,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_WARN_ICON));
+ } else {
+ enableFields(false, getBackground());
+ }
+ }
+ }
+
+ private void enableFields(boolean enable, Color color) {
+ mPortLabel.setEnabled(enable);
+ mGatewayPortText.setEnabled(enable);
+ mGatewayPortText.setEditable(enable);
+ mGatewayPortText.setBackground(color);
+ CMSAdminUtil.repaintComp(mPortLabel);
+ CMSAdminUtil.repaintComp(mGatewayPortText);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPCertDNPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPCertDNPage.java
new file mode 100644
index 000000000..d13124de6
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPCertDNPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import javax.swing.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Subject DN page for RA signing certificate
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIOCSPCertDNPage extends WICertDNPage {
+ private static final String PANELNAME = "INSTALLOCSPCERTDNWIZARD";
+ private static final String OCSPHELPINDEX = "install-ocspcert-subjectdn-wizard-help";
+
+ WIOCSPCertDNPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIOCSPCertDNPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isOCSPCloningDone())
+ return false;
+
+ if (!wizardInfo.isOCSPInstalled() || wizardInfo.isOCSPLocalCertDone() ||
+ wizardInfo.isOCSPCertRequestDone() || wizardInfo.isOCSPCertInstalledDone())
+ return false;
+ String str = wizardInfo.getOCSPSubjectName();
+ if (str == null || str.equals(""))
+ str = OCSP_CN+", "+OCSP_C;
+ wizardInfo.setOCSPSubjectName(str);
+ populateDN(str);
+ mHelpIndex = OCSPHELPINDEX;
+ return super.initializePanel(info);
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ if (super.concludePanel(info)) {
+ wizardInfo.setOCSPSubjectName(mStr);
+ return true;
+ }
+
+ return false;
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String str = mOText.getText().trim();
+ wizardInfo.setOCSPOComp(str);
+ str = mCText.getText().trim();
+ wizardInfo.setOCSPCComp(str);
+ }
+
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPCertSubmitPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPCertSubmitPage.java
new file mode 100644
index 000000000..dd58b5f1a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPCertSubmitPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * OCSP Certificate Submission.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIOCSPCertSubmitPage extends WICertSubmitPage implements IWizardPanel {
+ private static final String PANELNAME = "INSTALLOCSPCERTWIZARD";
+ private static final String OCSPHELPINDEX = "install-ocsptype-wizard-help";
+
+ WIOCSPCertSubmitPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isOCSPCloningDone())
+ return false;
+ wizardInfo.put(Constants.PR_CERTIFICATE_TYPE,
+ Constants.PR_OCSP_SIGNING_CERT);
+
+ if (!wizardInfo.isOCSPInstalled() ||
+ wizardInfo.isOCSPCertRequestDone() || wizardInfo.isOCSPCertInstalledDone()
+ ||
+ !wizardInfo.isCAInstalled()) {
+ wizardInfo.setOCSPCertLocalCA(Constants.FALSE);
+ return false;
+ }
+ if (wizardInfo.isOCSPLocalCertDone())
+ return false;
+
+ mHelpIndex = OCSPHELPINDEX;
+ return super.initializePanel(info);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (mSelfButton.isSelected())
+ wizardInfo.setOCSPCertLocalCA(Constants.TRUE);
+ else
+ wizardInfo.setOCSPCertLocalCA(Constants.FALSE);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPKeyPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPKeyPage.java
new file mode 100644
index 000000000..a49b428a7
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPKeyPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Setup key information for RA signing certificate
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIOCSPKeyPage extends WIKeyPage implements IWizardPanel {
+ private static final String PANELNAME = "INSTALLOCSPKEYWIZARD";
+ private static final String OCSPHELPINDEX =
+ "install-ocspkey-configuration-wizard-help";
+
+ WIOCSPKeyPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIOCSPKeyPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ mWizardInfo = (InstallWizardInfo)info;
+
+ if (mWizardInfo.isCloning() && mWizardInfo.isOCSPCloningDone())
+ return false;
+ if (!mWizardInfo.isOCSPInstalled() || mWizardInfo.isOCSPLocalCertDone() ||
+ mWizardInfo.isOCSPCertRequestDone() || mWizardInfo.isOCSPCertInstalledDone())
+ return false;
+
+ if (super.initializePanel(info)) {
+ String ocspTokenName = mWizardInfo.getOCSPTokenName();
+ if (ocspTokenName == null || ocspTokenName.equals("")) {
+ mTokenBox.setSelectedIndex(0);
+ } else {
+ if (ocspTokenName.equals(Constants.PR_INTERNAL_TOKEN_NAME))
+ mTokenBox.setSelectedIndex(0);
+ else
+ mTokenBox.setSelectedItem(ocspTokenName);
+ }
+ }
+
+ mHelpIndex = OCSPHELPINDEX;
+
+ enableFields();
+ mIsCAKey = false;
+ mWizardInfo.setCertType(Constants.PR_OCSP_SIGNING_CERT);
+ return true;
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ super.getUpdateInfo(info);
+ mWizardInfo.setOCSPTokenName(mWizardInfo.getTokenName());
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPMessageDigestPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPMessageDigestPage.java
new file mode 100644
index 000000000..ec250dcd1
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPMessageDigestPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Setup the message digest information for the installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIOCSPMessageDigestPage extends WMessageDigestPage {
+
+ private static final String PANELNAME = "INSTALLOCSPMESSAGEDIGESTWIZARD";
+
+ WIOCSPMessageDigestPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIOCSPMessageDigestPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isOCSPCloningDone())
+ return false;
+
+ if (!wizardInfo.isOCSPInstalled() || !wizardInfo.isOCSPCertLocalCA() ||
+ wizardInfo.isOCSPLocalCertDone() || wizardInfo.isOCSPCertRequestDone() ||
+ wizardInfo.isOCSPCertInstalledDone())
+ return false;
+
+ mCAKeyType = wizardInfo.getCAKeyType();
+
+ return super.initializePanel(info);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (mDSAHashTypeBox.isVisible())
+ wizardInfo.setHashType((String)mDSAHashTypeBox.getSelectedItem());
+ else
+ wizardInfo.setHashType((String)mRSAHashTypeBox.getSelectedItem());
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPRequestResultPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPRequestResultPage.java
new file mode 100644
index 000000000..a94fbf6e3
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPRequestResultPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Display the OCSP signing certificate request result
+ *
+ * @author Michelle Zhao
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIOCSPRequestResultPage extends WIRequestResultPage {
+
+ WIOCSPRequestResultPage(JDialog parent) {
+ super(parent);
+ }
+
+ WIOCSPRequestResultPage(JDialog parent, JFrame adminFrame) {
+ super( parent, adminFrame);
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isOCSPCloningDone())
+ return false;
+
+ if (wizardInfo.isOCSPCertLocalCA() || !wizardInfo.isOCSPInstalled() ||
+ wizardInfo.isOCSPLocalCertDone() ||
+ (wizardInfo.isOCSPCertRequestSucc() && wizardInfo.isOCSPReqResultDisplayed()) ||
+ wizardInfo.isOCSPCertInstalledDone())
+ return false;
+
+ wizardInfo.setOCSPReqResultDisplayed(Constants.TRUE);
+ return super.initializePanel(info);
+ }
+
+}
+
+
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPTokenLogonPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPTokenLogonPage.java
new file mode 100644
index 000000000..aa4be933a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIOCSPTokenLogonPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * This panel asks for the information of the current internal database.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIOCSPTokenLogonPage extends WITokenLogonPage implements IWizardPanel {
+
+ private static final String OCSPHELPINDEX = "install-ocsptoken-logon-wizard-help";
+ private static final String PANELNAME = "OCSPTOKENLOGONWIZARD";
+
+ WIOCSPTokenLogonPage(JDialog dialog) {
+ super(PANELNAME);
+ mHelpIndex = OCSPHELPINDEX;
+ mParent = dialog;
+ }
+
+ WIOCSPTokenLogonPage(JDialog dialog, JFrame adminFrame) {
+ super(PANELNAME);
+ mHelpIndex = OCSPHELPINDEX;
+ mParent = dialog;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String tokenname = wizardInfo.getOCSPTokenName();
+ String pwd = (String)wizardInfo.get("TOKEN:"+tokenname);
+
+ if (wizardInfo.isOCSPCertLocalCA() || !wizardInfo.isInstallCertNow()
+ || !wizardInfo.isOCSPInstalled() || wizardInfo.isOCSPCertInstalledDone())
+ return false;
+
+ if (pwd != null)
+ return false;
+
+ mTokenText.setText(tokenname);
+ mTokenName = tokenname;
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIPasteCACertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIPasteCACertPage.java
new file mode 100644
index 000000000..816554588
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIPasteCACertPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import javax.swing.*;
+
+/**
+ * The panel asks the user to paste the certificate.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIPasteCACertPage extends WIPasteCertPage {
+ private static final String PANELNAME = "INSTALLPASTECACERTWIZARD";
+ private static final String CAHELPINDEX = "install-cacert-paste-wizard-help";
+ private static final String CAKRAHELPINDEX = "install-cakracert-paste-wizard-help";
+
+ WIPasteCACertPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIPasteCACertPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isCACloningDone())
+ return false;
+
+ if (wizardInfo.isCACertLocalCA() || !wizardInfo.isInstallCertNow()
+ || !wizardInfo.isCAInstalled() || wizardInfo.isMigrationEnable()
+ || wizardInfo.isCACertInstalledDone())
+ return false;
+
+ wizardInfo.setCertType(Constants.PR_CA_SIGNING_CERT);
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else
+ mHelpIndex = CAHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIPasteCertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIPasteCertPage.java
new file mode 100644
index 000000000..063382f32
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIPasteCertPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.io.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * This page is to install the certificate in the internal token. The user can
+ * import the cert from the file, paste the Base 64 encoded blob in the
+ * text area or get the cert from the CMS where the request was sent.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIPasteCertPage extends WizardBasePanel implements IWizardPanel {
+ static private int transId = 1;
+ private JRadioButton mFileBtn;
+ private JRadioButton mBase64Btn;
+ private JTextField mFileText;
+ private JTextArea mBase64Text;
+ private JButton mPaste;
+ private String mCertContent = "";
+ private String mCertFilePath = "";
+ protected String mPanelName;
+ protected String mHelpIndex;
+ protected Color mActiveColor;
+ protected JTextArea introLbl;
+
+ protected JTextField mHostText, mPortText, mRIDText;
+ protected JLabel mHostLbl, mPortLbl, mRIDLbl;
+ protected String mHost, mPort, mRID;
+ protected JLabel mSSLText;
+ protected JCheckBox mSSL; // ssl or not
+ protected JLabel mQueryText;
+ protected JRadioButton mQueryBtn;
+
+ public static final int MAX_PORT = 65535;
+ public static final int MIN_PORT = 1;
+
+ WIPasteCertPage(String panelName) {
+ super(panelName);
+ mPanelName = panelName;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (mQueryBtn.isSelected())
+ enableFields(true, mActiveColor);
+ else
+ enableFields(false, getBackground());
+
+ String host = wizardInfo.getCMHost();
+ if (host != null && !host.equals(""))
+ mHostText.setText(host);
+ String port = wizardInfo.getCMEEPort();
+ if (port != null && !port.equals(""))
+ mPortText.setText(port);
+
+ String portType = wizardInfo.getCMEEType();
+ if (portType != null && portType.equals("http"))
+ mSSL.setSelected(false);
+
+ String rid = wizardInfo.getRequestID();
+ if (rid != null && !rid.equals(""))
+ mRIDText.setText(rid);
+
+ setBorder(makeTitledBorder(mPanelName));
+ return true;
+ }
+
+ public boolean validatePanel() {
+ if (mBase64Btn.isSelected()) {
+ mCertContent = mBase64Text.getText().trim();
+ if (mCertContent.equals("")) {
+ setErrorMessage("B64EEMPTY");
+ return false;
+ }
+ } else if (mFileBtn.isSelected()) {
+ mCertFilePath = mFileText.getText().trim();
+ if (mCertFilePath.equals("")) {
+ setErrorMessage("EMPTYFILE");
+ return false;
+ }
+ } else if (mQueryBtn.isSelected()) {
+ mHost = mHostText.getText().trim();
+ mPort = mPortText.getText().trim();
+ mRID = mRIDText.getText().trim();
+
+ if (mRID.equals("")) {
+ setErrorMessage("BLANKRID");
+ return false;
+ }
+ try {
+ int ridnumber = Integer.parseInt(mRID);
+ } catch (NumberFormatException e) {
+ setErrorMessage("INVALIDRID");
+ return false;
+ }
+
+ if (mHost.equals("")) {
+ setErrorMessage("BLANKHOST");
+ return false;
+ }
+ if (mPort.equals("")) {
+ setErrorMessage("BLANKPORT");
+ return false;
+ }
+
+ try {
+ int portnumber = Integer.parseInt(mPort);
+ if (portnumber < MIN_PORT || portnumber > MAX_PORT) {
+ setErrorMessage("OUTOFRANGE");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ setErrorMessage("INVALIDPORT");
+ return false;
+ }
+ return true;
+ }
+ return true;
+
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_GET_CERT_CONTENT;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_READ;
+ String reqType = wizardInfo.getCertType();
+ rawData = rawData+"&"+Constants.PR_CERTIFICATE_TYPE+"="+reqType;
+ if (mFileBtn.isSelected()) {
+ rawData = rawData+"&"+Constants.PR_CERT_FILEPATH+"="+mCertFilePath;
+ wizardInfo.setCertFilePath(mCertFilePath);
+ wizardInfo.setPKCS10("");
+ } else if (mBase64Btn.isSelected()) {
+ rawData = rawData+"&"+Constants.PR_PKCS10+"="+mCertContent;
+ //xxx It's not pkcs10, it's certificate.
+ wizardInfo.setPKCS10(mCertContent);
+ wizardInfo.setCertFilePath("");
+ } else if (mQueryBtn.isSelected()) {
+ if (mRID != null && !mRID.equals(""))
+ wizardInfo.setRequestID(mRID);
+ if (mHost != null && !mHost.equals(""))
+ wizardInfo.setCMHost(mHost);
+ if (mPort != null && !mPort.equals(""))
+ wizardInfo.setCMEEPort(mPort);
+ if (mSSL.isSelected())
+ wizardInfo.setCMEEType("https");
+ else
+ wizardInfo.setCMEEType("http");
+
+ String rawData1 = "importCert=true";
+ rawData1=rawData1+"&"+"requestId="+mRID;
+/*
+ CMSImportCert importCertCgi = new CMSImportCert();
+ importCertCgi.initialize(wizardInfo);
+ Hashtable data1 = new Hashtable();
+ data1.put("importCert", "true");
+ data1.put("requestId", mRID);
+*/
+
+ startProgressStatus();
+ boolean ready = send(mHost, Integer.parseInt(mPort), "/checkRequest",
+ rawData1, wizardInfo);
+
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage();
+ if (str.equals(""))
+ setErrorMessage("Server Error");
+ else
+ setErrorMessage(str);
+ return ready;
+ }
+ String certS= wizardInfo.getPKCS10();
+ // Break the long single line:header,64 byte lines,trailer
+ // Assuming this is the only format we generate.
+ String CERT_NEW_HEADER = "-----BEGIN CERTIFICATE-----";
+ String CERT_NEW_TRAILER = "-----END CERTIFICATE-----";
+ String str = CERT_NEW_HEADER + "\n";
+ int len = certS.length();
+ for (int i = 0; i < len; i=i+64){
+ if (i+64 < len)
+ str = str + certS.substring(i,i+64) +"\n";
+ else
+ str = str + certS.substring(i,len) +"\n";
+ }
+ str = str + CERT_NEW_TRAILER;
+ certS = str;
+ rawData = rawData+"&"+Constants.PR_PKCS10+"="+certS;
+ wizardInfo.setPKCS10(certS);
+ wizardInfo.setCertFilePath("");
+ }
+
+ startProgressStatus();
+ boolean ready = send(rawData, wizardInfo);
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage();
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ mPanelName+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(mHelpIndex);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ introLbl = createTextArea(mResource.getString(
+ mPanelName+"_LABEL_INTRO_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(introLbl, gbc);
+
+ mFileBtn = makeJRadioButton("FILE", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mFileBtn, gbc);
+
+ mFileText = makeJTextField(50);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE, COMPONENT_SPACE, 0);
+ add(mFileText, gbc);
+ mActiveColor = mFileText.getBackground();
+
+ mBase64Btn = makeJRadioButton("BASE64", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mBase64Btn, gbc);
+
+ JTextArea desc = createTextArea(mResource.getString(
+ "PASTECERTWIZARD_TEXT_DESC_LABEL"));
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,4*COMPONENT_SPACE,0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ mBase64Text = new JTextArea(null, null, 6, 10);
+ JScrollPane scrollPane = new JScrollPane(mBase64Text,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ scrollPane.setPreferredSize(new Dimension(30, 50));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.5;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, 0, COMPONENT_SPACE);
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(scrollPane, gbc);
+
+ mPaste = makeJButton("PASTE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mPaste, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ add(dummy, gbc);
+
+ mQueryBtn = makeJRadioButton("QUERY", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mQueryBtn, gbc);
+
+ mQueryText = new JLabel(mResource.getString(
+ mPanelName + "_TEXT_QUERY_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mQueryText, gbc);
+
+ mHostLbl = makeJLabel("HOST");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mHostLbl, gbc);
+
+ mHostText = makeJTextField(23);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mHostText, gbc);
+ mActiveColor = mHostText.getBackground();
+
+ mPortLbl = makeJLabel("PORT");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mPortLbl, gbc);
+
+ mPortText = makeJTextField(23);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mPortText, gbc);
+
+ mSSLText = new JLabel(mResource.getString(
+ mPanelName+"_TEXT_SSL_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ //gbc.gridwidth = gbc.REMAINDER;
+ add(mSSLText, gbc);
+
+ mSSL = makeJCheckBox("SSL", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mSSL, gbc);
+
+ mRIDLbl = makeJLabel("RID");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mRIDLbl, gbc);
+
+ mRIDText = makeJTextField(23);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mRIDText, gbc);
+
+ JLabel label = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(label, gbc);
+
+ ButtonGroup buttonGrp = new ButtonGroup();
+ buttonGrp.add(mFileBtn);
+ buttonGrp.add(mBase64Btn);
+ buttonGrp.add(mQueryBtn);
+
+ enableFields(mFileText, true, mActiveColor);
+ enableFields(mBase64Text, false, getBackground());
+ enableFields(false,getBackground());
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mPaste)) {
+ mBase64Text.paste();
+ } else if (e.getSource().equals(mFileBtn)) {
+ enableFields(mFileText, true, mActiveColor);
+ enableFields(mBase64Text, false, getBackground());
+ enableFields(false, getBackground());
+ } else if (e.getSource().equals(mBase64Btn)) {
+ enableFields(mFileText, false, getBackground());
+ enableFields(mBase64Text, true, mActiveColor);
+ enableFields(false, getBackground());
+ } else if (e.getSource().equals(mQueryBtn)) {
+ enableFields(mFileText, false, getBackground());
+ enableFields(mBase64Text, false, getBackground());
+ enableFields(true, mActiveColor);
+ }
+ }
+
+ private void enableFields(JTextComponent comp1, boolean enable, Color color) {
+ comp1.setEnabled(enable);
+ comp1.setEditable(enable);
+ comp1.setBackground(color);
+ CMSAdminUtil.repaintComp(comp1);
+ }
+
+ protected void enableFields(boolean enabled, Color color) {
+ mQueryText.setEnabled(enabled);
+ //mQueryText.setEditable(enabled);
+ CMSAdminUtil.repaintComp(mQueryText);
+ mHostLbl.setEnabled(enabled);
+ mPortLbl.setEnabled(enabled);
+ mRIDLbl.setEnabled(enabled);
+ mHostText.setEnabled(enabled);
+ mHostText.setEditable(enabled);
+ mHostText.setBackground(color);
+ mPortText.setEnabled(enabled);
+ mPortText.setEditable(enabled);
+ mPortText.setBackground(color);
+ mRIDText.setEnabled(enabled);
+ mRIDText.setEditable(enabled);
+ mRIDText.setBackground(color);
+ CMSAdminUtil.repaintComp(mHostLbl);
+ CMSAdminUtil.repaintComp(mHostText);
+ CMSAdminUtil.repaintComp(mPortLbl);
+ CMSAdminUtil.repaintComp(mPortText);
+ CMSAdminUtil.repaintComp(mRIDLbl);
+ CMSAdminUtil.repaintComp(mRIDText);
+ mSSLText.setEnabled(enabled);
+ //mSSLText.setEditable(enabled);
+ CMSAdminUtil.repaintComp(mSSLText);
+ mSSL.setEnabled(enabled);
+ //mSSL.setEditable(enabled);
+ //mSSL.setBackground(color);
+ CMSAdminUtil.repaintComp(mSSL);
+
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIPasteKRACertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIPasteKRACertPage.java
new file mode 100644
index 000000000..7166d64bf
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIPasteKRACertPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import javax.swing.*;
+
+/**
+ * The panel asks the user to paste the certificate.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIPasteKRACertPage extends WIPasteCertPage {
+ private static final String PANELNAME = "INSTALLPASTEKRACERTWIZARD";
+ private static final String KRAHELPINDEX = "install-kracert-paste-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakra-kracert-paste-wizard-help";
+ private static final String CAKRAHELPINDEX = "install-cakra-kracert-paste-wizard-help";
+
+ WIPasteKRACertPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIPasteKRACertPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isKRACloningDone())
+ return false;
+ if (wizardInfo.isKRACertLocalCA() || !wizardInfo.isInstallCertNow() ||
+ !wizardInfo.isKRAInstalled() || wizardInfo.isKRACertInstalledDone())
+ return false;
+
+ wizardInfo.setCertType(Constants.PR_KRA_TRANSPORT_CERT);
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = CAKRAHELPINDEX;
+ else if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = KRAHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIPasteOCSPCertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIPasteOCSPCertPage.java
new file mode 100644
index 000000000..783d87da7
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIPasteOCSPCertPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import javax.swing.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * The panel asks the user to paste the certificate.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIPasteOCSPCertPage extends WIPasteCertPage {
+
+ private static final String PANELNAME = "INSTALLPASTEOCSPCERTWIZARD";
+ private static final String OCSPHELPINDEX = "install-ocspcert-paste-wizard-help";
+
+ WIPasteOCSPCertPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIPasteOCSPCertPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ if (wizardInfo.isCloning() && wizardInfo.isOCSPCloningDone())
+ return false;
+ if (wizardInfo.isOCSPCertLocalCA() || !wizardInfo.isInstallCertNow()
+ || !wizardInfo.isOCSPInstalled() || wizardInfo.isOCSPCertInstalledDone())
+ return false;
+
+ wizardInfo.setCertType(Constants.PR_OCSP_SIGNING_CERT);
+
+ mHelpIndex = OCSPHELPINDEX;
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIPasteRACertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIPasteRACertPage.java
new file mode 100644
index 000000000..584c375d4
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIPasteRACertPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import javax.swing.*;
+
+/**
+ * The panel asks the user to paste the certificate.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIPasteRACertPage extends WIPasteCertPage {
+ private static final String PANELNAME = "INSTALLPASTERACERTWIZARD";
+ private static final String RAHELPINDEX = "install-racert-paste-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakracert-paste-wizard-help";
+
+ WIPasteRACertPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIPasteRACertPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isRACloningDone())
+ return false;
+ if (wizardInfo.isRACertLocalCA() || !wizardInfo.isInstallCertNow()
+ || !wizardInfo.isRAInstalled() || wizardInfo.isRACertInstalledDone())
+ return false;
+
+ wizardInfo.setCertType(Constants.PR_RA_SIGNING_CERT);
+
+ if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = RAHELPINDEX;
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIPasteSSLCertPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIPasteSSLCertPage.java
new file mode 100644
index 000000000..bf133bc15
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIPasteSSLCertPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import javax.swing.*;
+
+/**
+ * The panel asks the user to paste the certificate.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIPasteSSLCertPage extends WIPasteCertPage {
+ private static final String PANELNAME = "INSTALLPASTESSLCERTWIZARD";
+ private static final String HELPINDEX = "install-sslcert-paste-wizard-help";
+
+ WIPasteSSLCertPage(JDialog parent) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = parent;
+ }
+
+ WIPasteSSLCertPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning())
+ return false;
+ if (wizardInfo.isSSLCertLocalCA() || !wizardInfo.isInstallCertNow() ||
+ wizardInfo.isMigrationEnable() || wizardInfo.isSSLCertInstalledDone())
+ return false;
+
+ wizardInfo.setCertType(Constants.PR_SERVER_CERT);
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIRACertDNPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIRACertDNPage.java
new file mode 100644
index 000000000..788fab869
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIRACertDNPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import javax.swing.*;
+
+/**
+ * Subject DN page for RA signing certificate
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIRACertDNPage extends WICertDNPage {
+ private static final String PANELNAME = "INSTALLRACERTDNWIZARD";
+ private static final String RAHELPINDEX = "install-racert-subjectdn-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakracert-subjectdn-wizard-help";
+
+ WIRACertDNPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIRACertDNPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ if (wizardInfo.isCloning() && wizardInfo.isRACloningDone())
+ return false;
+ if (!wizardInfo.isRAInstalled() || wizardInfo.isRALocalCertDone() ||
+ wizardInfo.isRACertRequestDone() || wizardInfo.isRACertInstalledDone())
+ return false;
+ String str = wizardInfo.getRASubjectName();
+ if (str == null || str.equals(""))
+ str = RA_CN+", "+RA_C;
+ wizardInfo.setRASubjectName(str);
+ populateDN(str);
+ if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = RAHELPINDEX;
+ return super.initializePanel(info);
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ if (super.concludePanel(info)) {
+ wizardInfo.setRASubjectName(mStr);
+ return true;
+ }
+
+ return false;
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String str = mOText.getText().trim();
+ wizardInfo.setRAOComp(str);
+ str = mCText.getText().trim();
+ wizardInfo.setRACComp(str);
+ }
+
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIRACertExtensionPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIRACertExtensionPage.java
new file mode 100644
index 000000000..85553c5c7
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIRACertExtensionPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.border.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * Certificate Extension page for RA signing Certificate.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIRACertExtensionPage extends WICertExtensionPage {
+ private static final String PANELNAME = "INSTALLRACERTEXTENSION1WIZARD";
+ private static final String RAHELPINDEX = "install-racert-extension-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakracert-extension-wizard-help";
+
+ WIRACertExtensionPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIRACertExtensionPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isRACloningDone())
+ return false;
+ if (!wizardInfo.isRAInstalled() ||
+ wizardInfo.isRALocalCertDone() || wizardInfo.isRACertRequestDone() ||
+ wizardInfo.isRACertInstalledDone())
+ return false;
+
+ if (!mModified) {
+ mAKICheckBox.setSelected(true);
+ mExtendedKeyCheckBox.setSelected(true);
+ mSSLClient.setSelected(true);
+ }
+
+ if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = RAHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIRACertSubmitPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIRACertSubmitPage.java
new file mode 100644
index 000000000..771aa51b3
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIRACertSubmitPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * RA Certificate Submission.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIRACertSubmitPage extends WICertSubmitPage implements IWizardPanel {
+ private static final String PANELNAME = "INSTALLRACERTWIZARD";
+ private static final String RAHELPINDEX = "install-ratype-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakratype-wizard-help";
+
+ WIRACertSubmitPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isRACloningDone())
+ return false;
+ wizardInfo.put(Constants.PR_CERTIFICATE_TYPE,
+ Constants.PR_RA_SIGNING_CERT);
+ if (!wizardInfo.isRAInstalled() ||
+ wizardInfo.isRACertRequestDone() || wizardInfo.isRACertInstalledDone() ||
+ !wizardInfo.isCAInstalled()) {
+ wizardInfo.setRACertLocalCA(Constants.FALSE);
+ return false;
+ }
+ if (wizardInfo.isRALocalCertDone())
+ return false;
+ if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = RAHELPINDEX;
+ return super.initializePanel(info);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (mSelfButton.isSelected())
+ wizardInfo.setRACertLocalCA(Constants.TRUE);
+ else
+ wizardInfo.setRACertLocalCA(Constants.FALSE);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIRACertValidityPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIRACertValidityPage.java
new file mode 100644
index 000000000..fec7619df
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIRACertValidityPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * Validity page for RA signing certificate.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIRACertValidityPage extends WICertValidityPage {
+ private static final String PANELNAME = "INSTALLRACERTVALIDWIZARD";
+ private static final String RAHELPINDEX = "install-racert-validity-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakracert-validity-wizard-help";
+
+ WIRACertValidityPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIRACertValidityPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isRACloningDone())
+ return false;
+ if (!wizardInfo.isRAInstalled() || wizardInfo.isRALocalCertDone() ||
+ wizardInfo.isRACertRequestDone() || wizardInfo.isRACertInstalledDone())
+ return false;
+ if (super.initializePanel(info)) {
+ if (!wizardInfo.isRACertLocalCA())
+ return false;
+
+ if (wizardInfo.isRAInstalled() && wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = RAHELPINDEX;
+
+ return true;
+ }
+ return false;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIRAKeyPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIRAKeyPage.java
new file mode 100644
index 000000000..9abb9e0ac
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIRAKeyPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * Setup key information for RA signing certificate
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIRAKeyPage extends WIKeyPage implements IWizardPanel {
+ private static final String PANELNAME = "INSTALLRAKEYWIZARD";
+ private static final String RAHELPINDEX =
+ "install-rakey-configuration-wizard-help";
+ private static final String RAKRAHELPINDEX =
+ "install-rakrakey-configuration-wizard-help";
+
+ WIRAKeyPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIRAKeyPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ mWizardInfo = (InstallWizardInfo)info;
+
+ if (mWizardInfo.isCloning() && mWizardInfo.isRACloningDone())
+ return false;
+
+ if (!mWizardInfo.isRAInstalled() || mWizardInfo.isRALocalCertDone() ||
+ mWizardInfo.isRACertRequestDone() || mWizardInfo.isRACertInstalledDone())
+ return false;
+
+ if (super.initializePanel(info)) {
+ String raTokenName = mWizardInfo.getRATokenName();
+ if (raTokenName == null || raTokenName.equals("")) {
+ mTokenBox.setSelectedIndex(0);
+ } else {
+ if (raTokenName.equals(Constants.PR_INTERNAL_TOKEN_NAME))
+ mTokenBox.setSelectedIndex(0);
+ else
+ mTokenBox.setSelectedItem(raTokenName);
+ }
+ }
+
+ if (mWizardInfo.isRAInstalled() && mWizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = RAHELPINDEX;
+
+ enableFields();
+ mIsCAKey = false;
+ return true;
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ super.getUpdateInfo(info);
+ mWizardInfo.setRATokenName(mWizardInfo.getTokenName());
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIRAMessageDigestPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIRAMessageDigestPage.java
new file mode 100644
index 000000000..ef843ba37
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIRAMessageDigestPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Setup the message digest information for the installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIRAMessageDigestPage extends WMessageDigestPage {
+
+ private static final String PANELNAME = "INSTALLRAMESSAGEDIGESTWIZARD";
+
+ WIRAMessageDigestPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIRAMessageDigestPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning() && wizardInfo.isRACloningDone())
+ return false;
+ if (!wizardInfo.isRAInstalled() || !wizardInfo.isRACertLocalCA() ||
+ wizardInfo.isRALocalCertDone() || wizardInfo.isRACertRequestDone() ||
+ wizardInfo.isRACertInstalledDone())
+ return false;
+
+ mCAKeyType = wizardInfo.getCAKeyType();
+
+ return super.initializePanel(info);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (mDSAHashTypeBox.isVisible())
+ wizardInfo.setHashType((String)mDSAHashTypeBox.getSelectedItem());
+ else
+ wizardInfo.setHashType((String)mRSAHashTypeBox.getSelectedItem());
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIRARequestResultPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIRARequestResultPage.java
new file mode 100644
index 000000000..36c81b7d9
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIRARequestResultPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Display the RA signing certificate request result
+ *
+ * @author Michelle Zhao
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIRARequestResultPage extends WIRequestResultPage {
+
+ WIRARequestResultPage(JDialog parent) {
+ super(parent);
+ }
+
+ WIRARequestResultPage(JDialog parent, JFrame adminFrame) {
+ super( parent, adminFrame);
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isRACertLocalCA() || !wizardInfo.isRAInstalled() ||
+ wizardInfo.isRALocalCertDone() ||
+ (wizardInfo.isRACertRequestSucc() && wizardInfo.isRAReqResultDisplayed()) ||
+ wizardInfo.isRACertInstalledDone())
+ return false;
+
+ wizardInfo.setRAReqResultDisplayed(Constants.TRUE);
+ return super.initializePanel(info);
+ }
+}
+
+
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIRATokenLogonPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIRATokenLogonPage.java
new file mode 100644
index 000000000..d6f9dbafe
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIRATokenLogonPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * This panel asks for the information of the current internal database.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIRATokenLogonPage extends WITokenLogonPage implements IWizardPanel {
+
+ private static final String HELPINDEX = "install-ratoken-logon-wizard-help";
+ private static final String PANELNAME = "RATOKENLOGONWIZARD";
+
+ WIRATokenLogonPage(JDialog dialog) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = dialog;
+ }
+
+ WIRATokenLogonPage(JDialog dialog, JFrame adminFrame) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = dialog;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String tokenname = wizardInfo.getRATokenName();
+ String pwd = (String)wizardInfo.get("TOKEN:"+tokenname);
+ if (wizardInfo.isCloning() && wizardInfo.isRACloningDone()) {
+ if (pwd != null && !pwd.equals(""))
+ return false;
+ }
+
+ if (wizardInfo.isRACertLocalCA() || !wizardInfo.isInstallCertNow()
+ || !wizardInfo.isRAInstalled() || wizardInfo.isRACertInstalledDone())
+ return false;
+ if (pwd != null)
+ return false;
+
+ mTokenText.setText(tokenname);
+ mTokenName = tokenname;
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIRecreateDBPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIRecreateDBPage.java
new file mode 100644
index 000000000..f07de3134
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIRecreateDBPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * Introduction page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIRecreateDBPage extends WizardBasePanel implements IWizardPanel {
+ protected JRadioButton mYes;
+ protected JRadioButton mNo;
+ protected JTextArea mLabel;
+ private static final String PANELNAME = "INSTALLDBAGAIN";
+ private static final String HELPINDEX =
+ "install-internaldb-createdbagain-help";
+
+ WIRecreateDBPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIRecreateDBPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning())
+ return false;
+ if (wizardInfo.isDBCreated()) {
+ setBorder(makeTitledBorder(PANELNAME));
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mLabel = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mLabel, gbc);
+
+ mYes = makeJRadioButton("YES", false);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mYes, gbc);
+
+ mNo = makeJRadioButton("NO", true);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mNo, gbc);
+
+ ButtonGroup buttonGroup = new ButtonGroup();
+ buttonGroup.add(mYes);
+ buttonGroup.add(mNo);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (mYes.isSelected()) {
+ wizardInfo.setDBCreateNow(ConfigConstants.TRUE);
+ } else {
+ wizardInfo.setDBCreateNow(ConfigConstants.FALSE);
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIRemoteCASubsystem.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIRemoteCASubsystem.java
new file mode 100644
index 000000000..890c8ce4b
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIRemoteCASubsystem.java
@@ -0,0 +1,291 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.certsrv.common.*;
+import javax.swing.*;
+import java.awt.*;
+import java.util.*;
+
+/**
+ * Remote subsystems.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+
+class WIRemoteCASubsystem extends WizardBasePanel implements IWizardPanel {
+ protected JTextField mHostText;
+ protected JTextField mPortText;
+ protected JTextField mTimeoutText;
+ protected String mHost;
+ protected String mPort;
+ protected String mTimeout;
+ private String mHelpIndex;
+ public static final int MAX_PORT = 65535;
+ public static final int MIN_PORT = 1;
+ private static final String PANELNAME = "REMOTECAWIZARD";
+ private static final String RAHELPINDEX = "install-remote-ca-wizard-help";
+ private static final String RAKRAHELPINDEX = "install-rakra-remote-ca-wizard-help";
+
+ WIRemoteCASubsystem(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIRemoteCASubsystem(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isServicesDone())
+ return false;
+ if (wizardInfo.isRAInstalled() && !wizardInfo.isCAInstalled()) {
+ setBorder(makeTitledBorder(PANELNAME));
+ if (wizardInfo.isKRAInstalled())
+ mHelpIndex = RAKRAHELPINDEX;
+ else
+ mHelpIndex = RAHELPINDEX;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean validatePanel() {
+ mHost = mHostText.getText().trim();
+ mPort = mPortText.getText().trim();
+ mTimeout = mTimeoutText.getText().trim();
+ if (mHost.equals("")) {
+ setErrorMessage("BLANKHOST");
+ return false;
+ }
+ if (mPort.equals("")) {
+ setErrorMessage("BLANKPORT");
+ return false;
+ }
+ if (mTimeout.equals("")) {
+ setErrorMessage("BLANKTIMEOUT");
+ return false;
+ }
+
+ try {
+ int portnumber = Integer.parseInt(mPort);
+ if (portnumber < MIN_PORT || portnumber > MAX_PORT) {
+ setErrorMessage("OUTOFRANGE");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ setErrorMessage("INVALIDPORT");
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ wizardInfo.setCMHost(mHost);
+ wizardInfo.setCMPort(mPort);
+ wizardInfo.setCMTimeout(mTimeout);
+
+ if ((wizardInfo.isCAInstalled() || wizardInfo.isRAInstalled())
+ && !wizardInfo.isKRAInstalled()) {
+ return true;
+ }
+
+ ConsoleInfo consoleInfo = wizardInfo.getAdminConsoleInfo();
+ CMSConfigCert configCertCgi = new CMSConfigCert();
+ configCertCgi.initialize(wizardInfo);
+ Hashtable data = new Hashtable();
+
+ data.put(ConfigConstants.TASKID,TaskId.TASK_SELECT_SUBSYSTEMS);
+ data.put(ConfigConstants.OPTYPE, OpDef.OP_MODIFY);
+ data.put(ConfigConstants.PR_CERT_INSTANCE_NAME,
+ consoleInfo.get(ConfigConstants.PR_CERT_INSTANCE_NAME));
+ if (wizardInfo.getDBBindDN() != null)
+ data.put(ConfigConstants.PR_DB_BINDDN, wizardInfo.getDBBindDN());
+ if (wizardInfo.getInternalDBPasswd() != null)
+ data.put(ConfigConstants.PR_DB_PWD, wizardInfo.getInternalDBPasswd());
+ if (wizardInfo.isCAInstalled())
+ data.put(ConfigConstants.PR_CA, ConfigConstants.TRUE);
+ else
+ data.put(ConfigConstants.PR_CA, ConfigConstants.FALSE);
+
+ if (wizardInfo.isRAInstalled())
+ data.put(ConfigConstants.PR_RA, ConfigConstants.TRUE);
+ else
+ data.put(ConfigConstants.PR_RA, ConfigConstants.FALSE);
+
+ if (wizardInfo.isKRAInstalled())
+ data.put(ConfigConstants.PR_KRA, ConfigConstants.TRUE);
+ else
+ data.put(ConfigConstants.PR_KRA, ConfigConstants.FALSE);
+
+ String services = "";
+ if (wizardInfo.isCAInstalled()) {
+ if (!services.equals(""))
+ services = services+":";
+ services=services+ConfigConstants.PR_CA;
+ }
+ if (wizardInfo.isRAInstalled()) {
+ if (!services.equals(""))
+ services = services+":";
+ services=services+ConfigConstants.PR_RA;
+ //data.put(ConfigConstants.CA_HOST, wizardInfo.getCMHost());
+ //data.put(ConfigConstants.CA_PORT, wizardInfo.getCMPort());
+ }
+ if (wizardInfo.isKRAInstalled()) {
+ if (!services.equals(""))
+ services = services+":";
+ services=services+ConfigConstants.PR_KRA;
+ }
+ data.put(ConfigConstants.PR_SUBSYSTEMS, services);
+ data.put(ConfigConstants.REMOTE_KRA_ENABLED, ConfigConstants.FALSE);
+ data.put(ConfigConstants.CA_HOST, wizardInfo.getCMHost());
+ data.put(ConfigConstants.CA_PORT, wizardInfo.getCMPort());
+ data.put(ConfigConstants.CA_TIMEOUT, wizardInfo.getCMTimeout());
+ wizardInfo.enableRemoteDRM(ConfigConstants.FALSE);
+ wizardInfo.setSubsystems(services);
+ startProgressStatus();
+
+ CMSMessageBox dlg = new CMSMessageBox(mAdminFrame, "CGITASK", "CONFIGDB");
+
+ boolean ready = configCertCgi.configCert(data);
+
+ dlg.setVisible(false);
+
+ endProgressStatus();
+
+ if (!ready) {
+ String str = configCertCgi.getErrorMessage();
+ if (str.equals(""))
+ setErrorMessage("Server Error");
+ else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(mHelpIndex);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea heading = createTextArea(mResource.getString(
+ "REMOTECAWIZARD_TEXT_HEADING_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(heading, gbc);
+
+ JLabel hostLbl = makeJLabel("HOST");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0,
+ COMPONENT_SPACE);
+ add(hostLbl, gbc);
+
+ mHostText = makeJTextField(30);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mHostText, gbc);
+
+ JLabel portLbl = makeJLabel("PORT");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(portLbl, gbc);
+
+ mPortText = makeJTextField(10);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mPortText, gbc);
+
+ JLabel timeoutLbl = makeJLabel("TIMEOUT");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0,
+ COMPONENT_SPACE);
+ add(timeoutLbl, gbc);
+
+ mTimeoutText = makeJTextField("30", 10);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mTimeoutText, gbc);
+
+ /*JLabel timeunitLbl = makeJLabel("TIMEUNIT");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0,
+ COMPONENT_SPACE);
+ add(timeunitLbl, gbc);
+ */
+
+ JLabel label = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(label, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIRemoteKRASubsystem.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIRemoteKRASubsystem.java
new file mode 100644
index 000000000..29beb04af
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIRemoteKRASubsystem.java
@@ -0,0 +1,371 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import javax.swing.*;
+import java.awt.*;
+import java.util.*;
+import java.awt.event.*;
+
+/**
+ * Remote subsystems.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+
+class WIRemoteKRASubsystem extends WizardBasePanel implements IWizardPanel {
+ protected JTextField mHostText, mPortText, mTimeoutText;
+ protected JLabel mHostLbl, mPortLbl, mTimeoutLbl, mTimeunitLbl;
+ protected JRadioButton mYes, mNo;
+ protected String mHost, mPort, mTimeout;
+ protected JTextArea mHeading;
+ protected Color mActiveColor;
+ public static final int MAX_PORT = 65535;
+ public static final int MIN_PORT = 1;
+ private static final String PANELNAME = "REMOTEKRAWIZARD";
+ private static final String HELPINDEX1 = "install-ca-remote-kra-wizard-help";
+ private static final String HELPINDEX2 = "install-ra-remote-kra-wizard-help";
+ private InstallWizardInfo mWizardInfo;
+
+ WIRemoteKRASubsystem(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIRemoteKRASubsystem(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ mWizardInfo = wizardInfo;
+ if (wizardInfo.isServicesDone())
+ return false;
+ if ((wizardInfo.isCAInstalled() || wizardInfo.isRAInstalled())
+ && !wizardInfo.isKRAInstalled()) {
+ setBorder(makeTitledBorder(PANELNAME));
+ if (mYes.isSelected())
+ enableFields(true, mActiveColor);
+ else
+ enableFields(false, getBackground());
+ return true;
+ }
+ return false;
+ }
+
+ public boolean validatePanel() {
+ if (mNo.isSelected()) {
+ mHost = "";
+ mPort = "";
+ mTimeout = "";
+ return true;
+ }
+
+ mHost = mHostText.getText().trim();
+ mPort = mPortText.getText().trim();
+ mTimeout = mTimeoutText.getText().trim();
+ if (mHost.equals("")) {
+ setErrorMessage("BLANKHOST");
+ return false;
+ }
+ if (mPort.equals("")) {
+ setErrorMessage("BLANKPORT");
+ return false;
+ }
+ if (mTimeout.equals("")) {
+ setErrorMessage("BLANKTIMEOUT");
+ return false;
+ }
+
+ try {
+ int portnumber = Integer.parseInt(mPort);
+ if (portnumber < MIN_PORT || portnumber > MAX_PORT) {
+ setErrorMessage("OUTOFRANGE");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ setErrorMessage("INVALIDPORT");
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ wizardInfo.setDRMHost(mHost);
+ wizardInfo.setDRMPort(mPort);
+ wizardInfo.setDRMTimeout(mTimeout);
+ ConsoleInfo consoleInfo = wizardInfo.getAdminConsoleInfo();
+ CMSConfigCert configCertCgi = new CMSConfigCert();
+ configCertCgi.initialize(wizardInfo);
+ Hashtable data = new Hashtable();
+ data.put(ConfigConstants.TASKID,TaskId.TASK_SELECT_SUBSYSTEMS);
+ data.put(ConfigConstants.OPTYPE, OpDef.OP_MODIFY);
+ data.put(ConfigConstants.PR_CERT_INSTANCE_NAME,
+ consoleInfo.get(ConfigConstants.PR_CERT_INSTANCE_NAME));
+ if (wizardInfo.getDBBindDN() != null)
+ data.put(ConfigConstants.PR_DB_BINDDN, wizardInfo.getDBBindDN());
+ if (wizardInfo.getInternalDBPasswd() != null)
+ data.put(ConfigConstants.PR_DB_PWD, wizardInfo.getInternalDBPasswd());
+
+ if (wizardInfo.isCAInstalled())
+ data.put(ConfigConstants.PR_CA, ConfigConstants.TRUE);
+ else
+ data.put(ConfigConstants.PR_CA, ConfigConstants.FALSE);
+
+ if (wizardInfo.isRAInstalled())
+ data.put(ConfigConstants.PR_RA, ConfigConstants.TRUE);
+ else
+ data.put(ConfigConstants.PR_RA, ConfigConstants.FALSE);
+
+ if (wizardInfo.isKRAInstalled())
+ data.put(ConfigConstants.PR_KRA, ConfigConstants.TRUE);
+ else
+ data.put(ConfigConstants.PR_KRA, ConfigConstants.FALSE);
+
+ String services = "";
+ if (wizardInfo.isCAInstalled()) {
+ if (!services.equals(""))
+ services = services+":";
+ services=services+ConfigConstants.PR_CA;
+ } else {
+ data.put(ConfigConstants.CA_HOST, wizardInfo.getCMHost());
+ data.put(ConfigConstants.CA_PORT, wizardInfo.getCMPort());
+ data.put(ConfigConstants.CA_TIMEOUT, wizardInfo.getCMTimeout());
+ }
+
+ if (wizardInfo.isRAInstalled()) {
+ if (!services.equals(""))
+ services = services+":";
+ services=services+ConfigConstants.PR_RA;
+ }
+ if (wizardInfo.isKRAInstalled()) {
+ if (!services.equals(""))
+ services = services+":";
+ services=services+ConfigConstants.PR_KRA;
+ } else {
+ // connect to the remote KRA subystem
+ if (mYes.isSelected()) {
+ data.put(ConfigConstants.KRA_HOST, wizardInfo.getDRMHost());
+ data.put(ConfigConstants.KRA_PORT, wizardInfo.getDRMPort());
+ data.put(ConfigConstants.KRA_TIMEOUT, wizardInfo.getDRMTimeout());
+ data.put(ConfigConstants.REMOTE_KRA_ENABLED,
+ ConfigConstants.TRUE);
+ wizardInfo.enableRemoteDRM(ConfigConstants.TRUE);
+ } else {
+ data.put(ConfigConstants.REMOTE_KRA_ENABLED,
+ ConfigConstants.FALSE);
+ wizardInfo.enableRemoteDRM(ConfigConstants.FALSE);
+ }
+ }
+
+ data.put(ConfigConstants.PR_SUBSYSTEMS, services);
+ wizardInfo.setSubsystems(services);
+ startProgressStatus();
+ CMSMessageBox dlg = new CMSMessageBox(mAdminFrame, "CGITASK", "CONFIGDB");
+ boolean ready = configCertCgi.configCert(data);
+ dlg.setVisible(false);
+
+ endProgressStatus();
+
+ if (!ready) {
+ String str = configCertCgi.getErrorMessage();
+ if (str.equals(""))
+ setErrorMessage("Server Error");
+ else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ if (mWizardInfo.isCAInstalled()) {
+ CMSAdminUtil.help(HELPINDEX1);
+ } else {
+ CMSAdminUtil.help(HELPINDEX2);
+ }
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea heading = createTextArea(mResource.getString(
+ "REMOTEKRAWIZARD_TEXT_ISREMOTEKRA_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(heading, gbc);
+
+ mNo = makeJRadioButton("NO", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mNo, gbc);
+
+ mYes = makeJRadioButton("YES", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mYes, gbc);
+
+ ButtonGroup btnGroup = new ButtonGroup();
+ btnGroup.add(mNo);
+ btnGroup.add(mYes);
+
+ mHeading = createTextArea(mResource.getString(
+ "REMOTEKRAWIZARD_TEXT_HEADING_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0,4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mHeading, gbc);
+
+ mHostLbl = makeJLabel("HOST");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0,
+ COMPONENT_SPACE);
+ add(mHostLbl, gbc);
+
+ mHostText = makeJTextField(30);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mHostText, gbc);
+ mActiveColor = mHostText.getBackground();
+
+ mPortLbl = makeJLabel("PORT");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ add(mPortLbl, gbc);
+
+ mPortText = makeJTextField(10);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mPortText, gbc);
+
+ mTimeoutLbl = makeJLabel("TIMEOUT");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.EAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0,
+ COMPONENT_SPACE);
+ add(mTimeoutLbl, gbc);
+
+ mTimeoutText = makeJTextField("30", 10);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mTimeoutText, gbc);
+
+ /*mTimeunitLbl = makeJLabel("TIMEUNIT");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0, 0,
+ COMPONENT_SPACE);
+ add(mTimeunitLbl, gbc);
+ */
+
+ JLabel label = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(label, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (mYes.isSelected()) {
+ enableFields(true, mActiveColor);
+ } else {
+ enableFields(false, getBackground());
+ }
+ }
+
+ private void enableFields(boolean enabled, Color color) {
+ mHeading.setEnabled(enabled);
+ mHostLbl.setEnabled(enabled);
+ mPortLbl.setEnabled(enabled);
+ mTimeoutLbl.setEnabled(enabled);
+ mHostText.setEnabled(enabled);
+ mHostText.setEditable(enabled);
+ mHostText.setBackground(color);
+ mPortText.setEnabled(enabled);
+ mPortText.setEditable(enabled);
+ mPortText.setBackground(color);
+ mTimeoutText.setEnabled(enabled);
+ mTimeoutText.setEditable(enabled);
+ mTimeoutText.setBackground(color);
+ CMSAdminUtil.repaintComp(mHeading);
+ CMSAdminUtil.repaintComp(mHostLbl);
+ CMSAdminUtil.repaintComp(mHostText);
+ CMSAdminUtil.repaintComp(mPortLbl);
+ CMSAdminUtil.repaintComp(mPortText);
+ CMSAdminUtil.repaintComp(mTimeoutLbl);
+ CMSAdminUtil.repaintComp(mTimeoutText);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIReplAgreementPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIReplAgreementPage.java
new file mode 100644
index 000000000..df9bb1ab0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIReplAgreementPage.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.admin.certsrv.config.install;
+
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Replication Agreeemnt
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIReplAgreementPage extends WizardBasePanel implements IWizardPanel {
+ private Color mActiveColor;
+ private JCheckBox mEnable;
+ private JTextField mAgreementText1, mAgreementText2;
+ private JPasswordField mManagerPwd1, mManagerPwdAgain1;
+ private JPasswordField mManagerPwd2, mManagerPwdAgain2;
+
+ private static final String PANELNAME = "REPLDBWIZARD";
+ private static final String HELPINDEX =
+ "install-internaldb-configuration-wizard-help";
+ private static final String EMPTYSTR = " ";
+
+ WIReplAgreementPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIReplAgreementPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mEnable)) {
+ enableAgreement(mEnable.isSelected());
+ }
+ }
+
+ private void enableAgreement(boolean e) {
+ Color c;
+ if (e) {
+ c = mActiveColor;
+ } else {
+ c = getBackground();
+ }
+ mAgreementText1.setEditable(e);
+ mAgreementText1.setEnabled(e);
+ mAgreementText1.setBackground(c);
+ mManagerPwd1.setEditable(e);
+ mManagerPwd1.setEnabled(e);
+ mManagerPwd1.setBackground(c);
+ mManagerPwdAgain1.setEditable(e);
+ mManagerPwdAgain1.setEnabled(e);
+ mManagerPwdAgain1.setBackground(c);
+ mAgreementText2.setEditable(e);
+ mAgreementText2.setEnabled(e);
+ mAgreementText2.setBackground(c);
+ mManagerPwd2.setEditable(e);
+ mManagerPwd2.setEnabled(e);
+ mManagerPwd2.setBackground(c);
+ mManagerPwdAgain2.setEditable(e);
+ mManagerPwdAgain2.setEnabled(e);
+ mManagerPwdAgain2.setBackground(c);
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ if (!wizardInfo.isCloneDBCreated())
+ return false;
+
+ if (wizardInfo.isCloning() && !wizardInfo.isAgreementDone()) {
+ setBorder(makeTitledBorder(PANELNAME));
+ mAgreementText1.setText("masterToconsumer");
+ mAgreementText2.setText("consumerTomaster");
+ return true;
+ }
+ return false;
+ }
+
+ public boolean validatePanel() {
+ if (!mEnable.isSelected())
+ return true;
+ String passwd1 = mManagerPwd1.getText().trim();
+ String passwdAgain1 = mManagerPwdAgain1.getText().trim();
+ String name1 = mAgreementText1.getText().trim();
+
+ if (passwd1.equals("") || passwdAgain1.equals("")) {
+ setErrorMessage("EMPTYPASSWORD");
+ return false;
+ }
+
+ if (!passwdAgain1.equals(passwd1)) {
+ setErrorMessage("NOTSAMEPASSWORD");
+ return false;
+ }
+
+ if (name1.equals("")) {
+ setErrorMessage("EMPTYNAME");
+ return false;
+ }
+
+ String passwd2 = mManagerPwd2.getText().trim();
+ String passwdAgain2 = mManagerPwdAgain2.getText().trim();
+ String name2 = mAgreementText2.getText().trim();
+
+ if (passwd2.equals("") || passwdAgain2.equals("")) {
+ setErrorMessage("EMPTYPASSWORD");
+ return false;
+ }
+
+ if (!passwdAgain2.equals(passwd2)) {
+ setErrorMessage("NOTSAMEPASSWORD");
+ return false;
+ }
+
+ if (name2.equals("")) {
+ setErrorMessage("EMPTYNAME");
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_CREATE_REPLICATION_AGREEMENT;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ boolean ready = false;
+ if (!mEnable.isSelected()) {
+ rawData = rawData+"&"+ConfigConstants.PR_ENABLE_REPLICATION+"="+
+ ConfigConstants.FALSE;
+ ready = send(rawData, wizardInfo);
+ } else {
+ rawData = rawData+"&"+ConfigConstants.PR_ENABLE_REPLICATION+"="+
+ ConfigConstants.TRUE;
+ rawData = rawData+"&"+ConfigConstants.PR_AGREEMENT_NAME_1+"="+
+ mAgreementText1.getText().trim();
+ rawData = rawData+"&"+ConfigConstants.PR_REPLICATION_MANAGER_PASSWD_1+"="+mManagerPwd1.getText().trim();
+ rawData = rawData+"&"+ConfigConstants.PR_AGREEMENT_NAME_2+"="+mAgreementText2.getText().trim();
+ rawData = rawData+"&"+ConfigConstants.PR_REPLICATION_MANAGER_PASSWD_2+"="+mManagerPwd2.getText().trim();
+
+ startProgressStatus();
+/*
+ CMSMessageBox dlg = new CMSMessageBox(mAdminFrame,
+ "CGITASK", "CREATEREPLICATIONAGREEMENT");
+*/
+ ready = send(rawData, wizardInfo);
+ // dlg.setVisible(false);
+ endProgressStatus();
+ }
+
+ if (!ready) {
+ String str = getErrorMessage(wizardInfo);
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ PANELNAME+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea desc = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mEnable = makeJCheckBox("ENABLE");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mEnable, gbc);
+ mEnable.setSelected(true);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea desc1 = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_MASTER1_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel passwdLbl1 = makeJLabel("PASSWORD");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(passwdLbl1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mManagerPwd1 = makeJPasswordField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mManagerPwd1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel passwdAgainLbl1 = makeJLabel("PASSWORDAGAIN");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(passwdAgainLbl1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mManagerPwdAgain1 = makeJPasswordField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mManagerPwdAgain1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel desc2 = makeJLabel("MASTER2");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc2, gbc);
+/*
+ JTextArea desc2 = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_MASTER2_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc2, gbc);
+*/
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel passwdLbl2 = makeJLabel("PASSWORD");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(passwdLbl2, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mManagerPwd2 = makeJPasswordField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mManagerPwd2, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel passwdAgainLbl2 = makeJLabel("PASSWORDAGAIN");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(passwdAgainLbl2, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mManagerPwdAgain2 = makeJPasswordField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mManagerPwdAgain2, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea desc3 = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_AGREEMENT_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(2*COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc3, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea desc4 = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_AGREEMENT1_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc4, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel agreementLbl1 = makeJLabel("NAME");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(agreementLbl1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mAgreementText1 = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mAgreementText1, gbc);
+ mActiveColor = mAgreementText1.getBackground();
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea desc5 = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_AGREEMENT2_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc5, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel agreementLbl2 = makeJLabel("NAME");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(agreementLbl2, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mAgreementText2 = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mAgreementText2, gbc);
+ mActiveColor = mAgreementText2.getBackground();
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ wizardInfo.setAgreementDone(ConfigConstants.TRUE);
+ if (!mEnable.isSelected())
+ wizardInfo.setReplicationEnabled(ConfigConstants.FALSE);
+ else
+ wizardInfo.setReplicationEnabled(ConfigConstants.TRUE);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIRequestResultPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIRequestResultPage.java
new file mode 100644
index 000000000..e3f9c53f3
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIRequestResultPage.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.admin.certsrv.config.install;
+
+import java.util.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.install.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Certificate wizard request result page
+ *
+ * @author Michelle Zhao
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+public class WIRequestResultPage extends WizardBasePanel implements IWizardPanel {
+ private static final String PANELNAME = "REQUESTRESULTWIZARD";
+ private static final String HELPINDEX =
+ "install-request-result-wizard-help";
+
+ protected String mPanelName = PANELNAME;
+ protected String mHelpIndex = HELPINDEX;
+ protected JTextArea mDesc;
+ protected boolean print2RequestIDs = false;
+
+ protected String mRequestId;
+
+ WIRequestResultPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIRequestResultPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ if (!wizardInfo.requestSent())
+ return false;
+
+ setBorder(makeTitledBorder(PANELNAME));
+
+ String status = wizardInfo.getX509RequestStatus();
+ String str = wizardInfo.getX509RequestID();
+ String error = wizardInfo.getX509RequestError();
+
+ if (str != null && !str.equals("")) {
+ if (status != null && status.equals(Constants.PR_REQUEST_REJECTED)) {
+ // rejected
+ mDesc.setText(mResource.getString(mPanelName+"_TEXT_REJECT_LABEL") +
+ error + "\n\n"+ mResource.getString(mPanelName+"_TEXT_ID_LABEL") + str +
+ mResource.getString(mPanelName+"_TEXT_REJECTEND_LABEL"));
+ } else {
+ mDesc.setText(mResource.getString(mPanelName+"_TEXT_DESC_LABEL") +
+ mResource.getString(mPanelName+"_TEXT_ID_LABEL") + str +
+ mResource.getString(mPanelName+"_TEXT_END_LABEL"));
+ }
+ } else if (error != null && !error.equals(""))
+ mDesc.setText(error);
+ else
+ mDesc.setText(mResource.getString(mPanelName+"_TEXT_DESC_LABEL") +
+ mResource.getString(mPanelName+"_TEXT_NOID_LABEL"));
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ mDesc = createTextArea(mResource.getString(
+ mPanelName+"_TEXT_DESC_LABEL"));
+ //mDesc = createTextArea("request id");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mDesc, gbc);
+
+ JLabel label = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(label, gbc);
+
+ super.init();
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(mHelpIndex);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+
+ public void actionPerformed(ActionEvent event) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WISMTPPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WISMTPPage.java
new file mode 100644
index 000000000..3b7ba9d00
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WISMTPPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * SMTP page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WISMTPPage extends WizardBasePanel implements IWizardPanel {
+ private JTextField mServerTxt, mPortTxt;
+ private static final String PANELNAME = "SMTPWIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WISMTPPage() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ return true;
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel headingLbl = makeJLabel("HEADING");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ add(headingLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel serverLbl = makeJLabel("SERVERNAME");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.weightx = 0.0;
+ gbc.weighty = 0.0;
+ gbc.fill = gbc.NONE;
+ add(serverLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mServerTxt = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 0.0;
+ gbc.weighty = 0.0;
+ add(mServerTxt, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel dummy2 = new JLabel(" ");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(dummy2, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel portLbl = makeJLabel("PORT");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ add(portLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPortTxt = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ add(mPortTxt, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel dummy3 = new JLabel(" ");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(dummy3, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WISSLMessageDigestPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WISSLMessageDigestPage.java
new file mode 100644
index 000000000..820c17646
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WISSLMessageDigestPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Setup the message digest information for the installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WISSLMessageDigestPage extends WMessageDigestPage {
+
+ private static final String PANELNAME = "INSTALLSSLMESSAGEDIGESTWIZARD";
+
+ WISSLMessageDigestPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WISSLMessageDigestPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning())
+ return false;
+ if (wizardInfo.isMigrationEnable() || !wizardInfo.isSSLCertLocalCA() ||
+ wizardInfo.isSSLLocalCertDone() || wizardInfo.isSSLCertRequestDone() ||
+ wizardInfo.isSSLCertInstalledDone())
+ return false;
+
+ mCAKeyType = wizardInfo.getCAKeyType();
+
+ return super.initializePanel(info);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (mDSAHashTypeBox.isVisible())
+ wizardInfo.setHashType((String)mDSAHashTypeBox.getSelectedItem());
+ else
+ wizardInfo.setHashType((String)mRSAHashTypeBox.getSelectedItem());
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WISSLRequestResultPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WISSLRequestResultPage.java
new file mode 100644
index 000000000..119221105
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WISSLRequestResultPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Display the SSL certificate request result
+ *
+ * @author Michelle Zhao
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WISSLRequestResultPage extends WIRequestResultPage {
+
+ WISSLRequestResultPage(JDialog parent) {
+ super(parent);
+ }
+
+ WISSLRequestResultPage(JDialog parent, JFrame adminFrame) {
+ super( parent, adminFrame);
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning())
+ return false;
+ if (wizardInfo.isSSLCertLocalCA() || wizardInfo.isMigrationEnable() ||
+ wizardInfo.isSSLLocalCertDone()||
+ (wizardInfo.isSSLCertRequestSucc() && wizardInfo.isSSLReqResultDisplayed()) ||
+ wizardInfo.isSSLCertInstalledDone())
+ return false;
+
+ wizardInfo.setSSLReqResultDisplayed(Constants.TRUE);
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WISSLTokenLogonPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WISSLTokenLogonPage.java
new file mode 100644
index 000000000..ff1ed7826
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WISSLTokenLogonPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * This panel asks for the information of the current internal database.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WISSLTokenLogonPage extends WITokenLogonPage implements IWizardPanel {
+
+ private static final String HELPINDEX = "install-ssltoken-logon-wizard-help";
+ private static final String PANELNAME = "SSLTOKENLOGONWIZARD";
+
+ WISSLTokenLogonPage(JDialog dialog) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = dialog;
+ }
+
+ WISSLTokenLogonPage(JDialog dialog, JFrame adminFrame) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = dialog;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String tokenname = wizardInfo.getSSLTokenName();
+ String pwd = (String)wizardInfo.get("TOKEN:"+tokenname);
+ if (wizardInfo.isCloning())
+ return false;
+ if (wizardInfo.isSSLCertLocalCA() || !wizardInfo.isInstallCertNow() ||
+ wizardInfo.isMigrationEnable() || wizardInfo.isSSLCertInstalledDone())
+ return false;
+ if (pwd != null)
+ return false;
+
+ mTokenName = tokenname;
+ mTokenText.setText(tokenname);
+ return super.initializePanel(info);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIServerCertDNPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIServerCertDNPage.java
new file mode 100644
index 000000000..b6ee85acc
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIServerCertDNPage.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.admin.certsrv.config.install;
+
+import com.netscape.admin.certsrv.wizard.*;
+import javax.swing.*;
+
+/**
+ * Subject DN page for SSL server certificate
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIServerCertDNPage extends WICertDNPage {
+ private static final String PANELNAME = "INSTALLSSLCERTDNWIZARD";
+ private static final String LOCALHELPINDEX = "install-sslcertlocal-subjectdn-wizard-help";
+ private static final String REMOTEHELPINDEX = "install-sslcertsub-subjectdn-wizard-help";
+
+ WIServerCertDNPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIServerCertDNPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning())
+ return false;
+ if (wizardInfo.isMigrationEnable() || wizardInfo.isSSLLocalCertDone() ||
+ wizardInfo.isSSLCertRequestDone() || wizardInfo.isSSLCertInstalledDone())
+ return false;
+ String machineName = wizardInfo.getMachineName();
+// dnDesc.setText("CN="+machineName+", O=Netscape Communications, C=US");
+ String str = wizardInfo.getSSLSubjectName();
+/*
+ if (wizardInfo.isCAInstalled()) { // It is for SSL Server cert for CA
+ // get O component
+ OComp = wizardInfo.getCAOComp();
+ CComp = wizardInfo.getCACComp();
+ }
+ else if (wizardInfo.isRAInstalled()) { // It is for SSL Server cert for RA
+ OComp = wizardInfo.getRAOComp();
+ CComp = wizardInfo.getRACComp();
+ }
+*/
+
+ String OUComp = wizardInfo.getOUComponent();
+ String OComp = wizardInfo.getOComponent();
+ String LComp = wizardInfo.getLComponent();
+ String STComp = wizardInfo.getSTComponent();
+ String CComp = wizardInfo.getCComponent();
+
+ if (str == null || str.equals("")) {
+ str = "CN="+machineName;
+ if (OUComp != null && !OUComp.equals("")) {
+ str = str+", OU="+OUComp;
+ }
+ if (OComp != null && !OComp.equals("")) {
+ str = str+", O="+OComp;
+ }
+ if (LComp != null && !LComp.equals("")) {
+ str = str+", L="+LComp;
+ }
+ if (STComp != null && !STComp.equals("")) {
+ str = str+", ST="+STComp;
+ }
+ if (CComp != null && !CComp.equals("")) {
+ str = str+", C="+CComp;
+ } else {
+ str = str+", "+SERVER_C;
+ }
+ }
+ wizardInfo.setSSLSubjectName(str);
+ populateDN(str);
+
+ if (wizardInfo.isSSLCertLocalCA())
+ mHelpIndex = LOCALHELPINDEX;
+ else
+ mHelpIndex = REMOTEHELPINDEX;
+
+ return super.initializePanel(info);
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ if (super.concludePanel(info)) {
+ wizardInfo.setSSLSubjectName(mStr);
+ return true;
+ }
+
+ return false;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIServerCertExtensionPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIServerCertExtensionPage.java
new file mode 100644
index 000000000..f958c88a1
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIServerCertExtensionPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.border.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * Certificate Extension page for SSL server Certificate.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIServerCertExtensionPage extends WICertExtensionPage {
+ private static final String PANELNAME = "INSTALLSERVERCERTEXTENSION1WIZARD";
+ private static final String HELPINDEX = "install-sslcert-extension-wizard-help";
+
+ WIServerCertExtensionPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ mHelpIndex = HELPINDEX;
+ }
+
+ WIServerCertExtensionPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mHelpIndex = HELPINDEX;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning())
+ return false;
+ if (wizardInfo.isMigrationEnable() ||
+ wizardInfo.isSSLLocalCertDone() || wizardInfo.isSSLCertRequestDone() ||
+ wizardInfo.isSSLCertInstalledDone())
+ return false;
+
+ if (!mModified) {
+ mExtendedKeyCheckBox.setSelected(true);
+ mAKICheckBox.setSelected(true);
+ mSSLServer.setSelected(true);
+ mSSLClient.setSelected(true);
+ }
+ return super.initializePanel(info);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIServerCertSubmitPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIServerCertSubmitPage.java
new file mode 100644
index 000000000..417e706a5
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIServerCertSubmitPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * Server Certificate Submission.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIServerCertSubmitPage extends WICertSubmitPage implements IWizardPanel {
+ private static final String PANELNAME = "INSTALLSERVERCERTWIZARD";
+ private static final String CALOCALHELPINDEX = "install-cassltypelocal-wizard-help";
+ private static final String CAREMOTEHELPINDEX = "install-cassltypesub-wizard-help";
+ private static final String CAKRALOCALHELPINDEX = "install-cakrassltypelocal-wizard-help";
+ private static final String CAKRAREMOTEHELPINDEX = "install-cakrassltypesub-wizard-help";
+
+ WIServerCertSubmitPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ wizardInfo.put(Constants.PR_CERTIFICATE_TYPE,
+ Constants.PR_SERVER_CERT);
+
+ if (wizardInfo.isCloning())
+ return false;
+
+ if (wizardInfo.isMigrationEnable() ||
+ wizardInfo.isSSLCertRequestDone() || wizardInfo.isSSLCertInstalledDone() ||
+ !wizardInfo.isCAInstalled()) {
+ wizardInfo.setSSLCertLocalCA(Constants.FALSE);
+ return false;
+ }
+
+ if (wizardInfo.isSSLLocalCertDone())
+ return false;
+
+ if (wizardInfo.isCAInstalled() && wizardInfo.isKRAInstalled()) {
+ if (wizardInfo.isSSLCertLocalCA()) {
+ mHelpIndex = CAKRALOCALHELPINDEX;
+ } else
+ mHelpIndex = CAKRAREMOTEHELPINDEX;
+ } else if (wizardInfo.isSSLCertLocalCA()) {
+ mHelpIndex = CALOCALHELPINDEX;
+ } else {
+ mHelpIndex = CAREMOTEHELPINDEX;
+ }
+
+ return super.initializePanel(info);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (mSelfButton.isSelected())
+ wizardInfo.setSSLCertLocalCA(Constants.TRUE);
+ else
+ wizardInfo.setSSLCertLocalCA(Constants.FALSE);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIServerCertValidityPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIServerCertValidityPage.java
new file mode 100644
index 000000000..047b9d7e8
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIServerCertValidityPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * Validity page for SSL server certificate.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIServerCertValidityPage extends WICertValidityPage {
+ private static final String PANELNAME = "INSTALLSERVERCERTVALIDWIZARD";
+ private static final String HELPINDEX = "install-sslcert-validity-wizard-help";
+
+ WIServerCertValidityPage(JDialog parent) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = parent;
+ }
+
+ WIServerCertValidityPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mHelpIndex = HELPINDEX;
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (wizardInfo.isCloning())
+ return false;
+ if (wizardInfo.isMigrationEnable() || wizardInfo.isSSLLocalCertDone() ||
+ wizardInfo.isSSLCertRequestDone() || wizardInfo.isSSLCertInstalledDone())
+ return false;
+ if (super.initializePanel(info)) {
+ if (!wizardInfo.isSSLCertLocalCA())
+ return false;
+ return true;
+ }
+ return false;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIServerKeyPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIServerKeyPage.java
new file mode 100644
index 000000000..c14d0d2b3
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIServerKeyPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * Setup key information for ssl server certificate
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIServerKeyPage extends WIKeyPage implements IWizardPanel {
+ private static final String PANELNAME = "INSTALLSERVERKEYWIZARD";
+ private static final String LOCALHELPINDEX =
+ "install-serverkeylocal-configuration-wizard-help";
+ private static final String REMOTEHELPINDEX =
+ "install-serverkeysub-configuration-wizard-help";
+
+ WIServerKeyPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WIServerKeyPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ mWizardInfo = (InstallWizardInfo)info;
+
+ if (mWizardInfo.isCloning())
+ return false;
+
+ if (mWizardInfo.isMigrationEnable() || mWizardInfo.isSSLLocalCertDone() ||
+ mWizardInfo.isSSLCertRequestDone() || mWizardInfo.isSSLCertInstalledDone())
+ return false;
+ if (super.initializePanel(info)) {
+ String sslTokenName = mWizardInfo.getSSLTokenName();
+ if (sslTokenName == null || sslTokenName.equals("")) {
+ mTokenBox.setSelectedIndex(0);
+ } else {
+ if (sslTokenName.equals(Constants.PR_INTERNAL_TOKEN_NAME))
+ mTokenBox.setSelectedIndex(0);
+ else
+ mTokenBox.setSelectedItem(sslTokenName);
+ }
+ }
+
+ if (mWizardInfo.isSSLCertLocalCA())
+ mHelpIndex = LOCALHELPINDEX;
+ else
+ mHelpIndex = REMOTEHELPINDEX;
+
+ enableFields();
+ mIsCAKey = false;
+ return true;
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ super.getUpdateInfo(info);
+ mWizardInfo.setSSLTokenName(mWizardInfo.getTokenName());
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WIServicesPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WIServicesPage.java
new file mode 100644
index 000000000..fb524e62f
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WIServicesPage.java
@@ -0,0 +1,425 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Introduction page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WIServicesPage extends WizardBasePanel implements IWizardPanel {
+ private JRadioButton mCACheckBox;
+ private JRadioButton mRACheckBox;
+ private JRadioButton mOCSPCheckBox;
+ private JRadioButton mKRACheckBox;
+
+ private JRadioButton mTKSCheckBox;
+ private JTextArea mServiceLbl;
+
+ private static final String PANELNAME = "SERVICESWIZARD";
+ private static final String HELPINDEX =
+ "install-services-configuration-wizard-help";
+
+ private String mClonedSubsystem = null;
+
+ WIServicesPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIServicesPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ /* bug#54369 - disable RA for netkey */
+ mRACheckBox.setEnabled(false);
+
+ mClonedSubsystem = wizardInfo.getCloneSubsystem();
+
+
+ if(mClonedSubsystem != null)
+ {
+
+ mServiceLbl.setText(mResource.getString(PANELNAME +"_LABEL_INSTALL_CLONE_LABEL"));
+ if(mClonedSubsystem.equals(ConfigConstants.PR_CA))
+ {
+ mCACheckBox.setSelected(true);
+ }
+ else
+ mCACheckBox.setEnabled(false);
+
+ /* bug#54369 - disable RA for netkey
+ if(mClonedSubsystem.equals(ConfigConstants.PR_RA))
+ {
+ mRACheckBox.setSelected(true);
+ }
+ else
+ mRACheckBox.setEnabled(false);
+ */
+
+ if(mClonedSubsystem.equals(ConfigConstants.PR_KRA))
+ {
+ mKRACheckBox.setSelected(true);
+ }
+ else
+ mKRACheckBox.setEnabled(false);
+
+ if(mClonedSubsystem.equals(ConfigConstants.PR_TKS))
+ {
+ mTKSCheckBox.setSelected(true);
+ }
+ else
+ mTKSCheckBox.setEnabled(false);
+
+ if(mClonedSubsystem.equals(ConfigConstants.PR_OCSP))
+ {
+ mOCSPCheckBox.setSelected(true);
+ }
+ else
+ mOCSPCheckBox.setEnabled(false);
+
+ }
+
+
+ Debug.println("WIServicesPage: initializePanel.");
+ Debug.println("WIServicesPage: mClonedSubsystem " + mClonedSubsystem);
+
+
+ if (wizardInfo.isServicesDone())
+ return false;
+
+ setBorder(makeTitledBorder(PANELNAME));
+ String subsystemList = wizardInfo.getSubsystems();
+ if (subsystemList == null || subsystemList.equals("")) {
+ if (!mRACheckBox.isSelected() && mClonedSubsystem == null)
+ mCACheckBox.setSelected(true);
+
+ return true;
+ }
+
+
+
+ // get the subsystems from the list
+ int start = 0;
+ int end;
+ do {
+ end = subsystemList.indexOf(':', start);
+ if( end == -1 ) {
+ end = subsystemList.length(); // last string ends at end-of-line
+ }
+ if( end-start < 1 ) {
+ setErrorMessage("INCORRECTRESPONSE");
+ return false;
+ }
+ String sub = subsystemList.substring(start, end);
+ if( ConfigConstants.PR_CA.equals(sub) ) {
+ mCACheckBox.setSelected(true);
+ } else if( ConfigConstants.PR_RA.equals(sub) ) {
+ mRACheckBox.setSelected(true);
+ } else if( ConfigConstants.PR_KRA.equals(sub) ) {
+ mKRACheckBox.setSelected(true);
+ } else if( ConfigConstants.PR_TKS.equals(sub) ) {
+ mTKSCheckBox.setSelected(true);
+ } else if( ConfigConstants.PR_OCSP.equals(sub) ) {
+ mOCSPCheckBox.setSelected(true);
+ } else {
+ setErrorMessage("INCORRECTRESPONSE");
+ return false;
+ }
+ start = end+1;
+ } while( start < subsystemList.length() );
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ if (mCACheckBox.isSelected() && mRACheckBox.isSelected()) {
+ setErrorMessage("NOCOLOCATED");
+ return false;
+ }
+
+ if (!mCACheckBox.isSelected() && !mRACheckBox.isSelected() &&
+ !mOCSPCheckBox.isSelected() && !mKRACheckBox.isSelected() && !mTKSCheckBox.isSelected()) {
+ setErrorMessage("NOSERVICESINSTALLED");
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ Hashtable data = new Hashtable();
+ String services = "";
+ if (mCACheckBox.isSelected()) {
+ wizardInfo.setInstalledCA(ConfigConstants.TRUE);
+ data.put(ConfigConstants.PR_CA, ConfigConstants.TRUE);
+ if (!services.equals(""))
+ services = services+":";
+ services=services+ConfigConstants.PR_CA;
+ } else {
+ wizardInfo.setInstalledCA(ConfigConstants.FALSE);
+ data.put(ConfigConstants.PR_CA, ConfigConstants.FALSE);
+ }
+
+ if (mRACheckBox.isSelected()) {
+ wizardInfo.setInstalledRA(ConfigConstants.TRUE);
+ data.put(ConfigConstants.PR_RA, ConfigConstants.TRUE);
+ if (!services.equals(""))
+ services = services+":";
+ services=services+ConfigConstants.PR_RA;
+ } else {
+ wizardInfo.setInstalledRA(ConfigConstants.FALSE);
+ data.put(ConfigConstants.PR_RA, ConfigConstants.FALSE);
+ }
+ if (mKRACheckBox.isSelected()) {
+ wizardInfo.setInstalledKRA(ConfigConstants.TRUE);
+ data.put(ConfigConstants.PR_KRA, ConfigConstants.TRUE);
+ if (!services.equals(""))
+ services = services+":";
+ services=services+ConfigConstants.PR_KRA;
+ } else {
+ wizardInfo.setInstalledKRA(ConfigConstants.FALSE);
+ data.put(ConfigConstants.PR_KRA, ConfigConstants.FALSE);
+ }
+ if (mTKSCheckBox.isSelected()) {
+ wizardInfo.setInstalledTKS(ConfigConstants.TRUE);
+ data.put(ConfigConstants.PR_TKS, ConfigConstants.TRUE);
+ if (!services.equals(""))
+ services = services+":";
+ services=services+ConfigConstants.PR_TKS;
+ } else {
+ wizardInfo.setInstalledTKS(ConfigConstants.FALSE);
+ data.put(ConfigConstants.PR_TKS, ConfigConstants.FALSE);
+ }
+ if (mOCSPCheckBox.isSelected()) {
+ wizardInfo.setInstalledOCSP(ConfigConstants.TRUE);
+ data.put(ConfigConstants.PR_OCSP, ConfigConstants.TRUE);
+ if (!services.equals(""))
+ services = services+":";
+ services=services+ConfigConstants.PR_OCSP;
+ } else {
+ wizardInfo.setInstalledOCSP(ConfigConstants.FALSE);
+ data.put(ConfigConstants.PR_OCSP, ConfigConstants.FALSE);
+ }
+
+ if (services != null && !services.equals("")) {
+ wizardInfo.setSubsystems(services);
+ }
+
+
+ String rawData = ConfigConstants.PR_SUBSYSTEMS+"="+services;
+ rawData = rawData+"&"+ConfigConstants.TASKID+"="+TaskId.TASK_SELECT_SUBSYSTEMS;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ if (wizardInfo.getDBBindDN() != null)
+ rawData = rawData+"&"+ConfigConstants.PR_DB_BINDDN+"="+wizardInfo.getDBBindDN();
+ if (wizardInfo.getInternalDBPasswd() != null)
+ rawData = rawData+"&"+ConfigConstants.PR_DB_PWD+"="+
+ wizardInfo.getInternalDBPasswd();
+
+ rawData = rawData+"&"+ConfigConstants.REMOTE_KRA_ENABLED+"="+
+ ConfigConstants.FALSE;
+ wizardInfo.enableRemoteDRM(ConfigConstants.FALSE);
+ startProgressStatus();
+
+ //CMSMessageBox dlg = new CMSMessageBox(mAdminFrame, "CGITASK", "CREATESUB");
+ boolean ready = send(rawData, wizardInfo);
+ //dlg.setVisible(false);
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage(wizardInfo);
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ PANELNAME+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mCACheckBox)) {
+ mTKSCheckBox.setSelected(false);
+ mKRACheckBox.setSelected(false);
+ mOCSPCheckBox.setSelected(false);
+ if(mClonedSubsystem != null)
+ mCACheckBox.setSelected(true);
+
+ mRACheckBox.setSelected(false);
+ } else if (e.getSource().equals(mOCSPCheckBox)) {
+ mTKSCheckBox.setSelected(false);
+ mKRACheckBox.setSelected(false);
+ mCACheckBox.setSelected(false);
+ mRACheckBox.setSelected(false);
+ if(mClonedSubsystem != null)
+ mOCSPCheckBox.setSelected(true);
+ } else if (e.getSource().equals(mRACheckBox)) {
+ mCACheckBox.setSelected(false);
+ mTKSCheckBox.setSelected(false);
+ mKRACheckBox.setSelected(false);
+ mOCSPCheckBox.setSelected(false);
+ if(mClonedSubsystem != null)
+ mRACheckBox.setSelected(true);
+ } else if (e.getSource().equals(mKRACheckBox)) {
+ mTKSCheckBox.setSelected(false);
+ mCACheckBox.setSelected(false);
+ mRACheckBox.setSelected(false);
+ mOCSPCheckBox.setSelected(false);
+ if(mClonedSubsystem != null)
+ mKRACheckBox.setSelected(true);
+ }else if (e.getSource().equals(mTKSCheckBox)) {
+ mCACheckBox.setSelected(false);
+ mRACheckBox.setSelected(false);
+ mOCSPCheckBox.setSelected(false);
+ mKRACheckBox.setSelected(false);
+ if(mClonedSubsystem != null)
+ mTKSCheckBox.setSelected(true);
+ }
+
+ super.actionPerformed(e);
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ mServiceLbl = createTextArea(mResource.getString(
+ PANELNAME+"_LABEL_INSTALL_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mServiceLbl, gbc);
+
+ mCACheckBox = makeJRadioButton("CA");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mCACheckBox, gbc);
+
+ mOCSPCheckBox = makeJRadioButton("OCSP");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mOCSPCheckBox, gbc);
+
+ mRACheckBox = makeJRadioButton("RA");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0, COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mRACheckBox, gbc);
+
+ mKRACheckBox = makeJRadioButton("KRA");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ //gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mKRACheckBox, gbc);
+
+ mTKSCheckBox = makeJRadioButton("TKS");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ //gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mTKSCheckBox, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(dummy, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ if (mCACheckBox.isSelected())
+ wizardInfo.setInstalledCA(ConfigConstants.TRUE);
+ else
+ wizardInfo.setInstalledCA(ConfigConstants.FALSE);
+ if (mRACheckBox.isSelected())
+ wizardInfo.setInstalledRA(ConfigConstants.TRUE);
+ else
+ wizardInfo.setInstalledRA(ConfigConstants.FALSE);
+ if (mKRACheckBox.isSelected())
+ wizardInfo.setInstalledKRA(ConfigConstants.TRUE);
+ else
+ wizardInfo.setInstalledKRA(ConfigConstants.FALSE);
+ if (mTKSCheckBox.isSelected())
+ wizardInfo.setInstalledTKS(ConfigConstants.TRUE);
+ else
+ wizardInfo.setInstalledTKS(ConfigConstants.FALSE);
+ if (mOCSPCheckBox.isSelected())
+ wizardInfo.setInstalledOCSP(ConfigConstants.TRUE);
+ else
+ wizardInfo.setInstalledOCSP(ConfigConstants.FALSE);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WISingleSignonPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WISingleSignonPage.java
new file mode 100644
index 000000000..49e06ac1e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WISingleSignonPage.java
@@ -0,0 +1,532 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.config.install;
+
+import java.io.*;
+import java.net.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import javax.swing.text.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.comm.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Setup Single Signon for the installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WISingleSignonPage extends WizardBasePanel implements IWizardPanel, CommClient {
+
+ public static final String PW_TAG_INTERNAL_LDAP_DB = "Internal LDAP Database";
+ public static final String PW_TAG_INTERNAL_STORAGE_TOKEN = "internal";
+
+ private Color mActiveColor;
+ // private JPasswordField mSingleSignonPassword, mSingleSignonPasswordAgain;
+ private JCheckBox mPasswordConf;
+ private static final String HELPINDEX = "install-single-signon-wizard-help";
+ private static final String PANELNAME = "INSTALLSINGLESIGNON";
+ private boolean ca;
+ private boolean ra;
+ private boolean kra;
+ private String mDBPasswd;
+ private String capassword, rapassword, krapassword, sslpassword;
+ private JComboBox mTokenBox;
+ private static final String START_TASK_CGI = "Tasks/Operation/start";
+ private static final String PREFIX = "CGITASK";
+ private boolean mFinished = false;
+ protected String mCmd = null;
+ private String mAdminURL = null;
+ protected boolean mSuccess = false;
+ private String mReply = null;
+ protected String mSection = "";
+ protected String mErrorMsg = "";
+ private ConsoleInfo _consoleInfo = null;
+
+ WISingleSignonPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WISingleSignonPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ String tokenList = wizardInfo.getTokensList();
+ StringTokenizer st1 = new StringTokenizer(tokenList, ":");
+
+ mTokenBox.removeAllItems();
+ while (st1.hasMoreElements()) {
+ String t1 = (String)st1.nextElement();
+ mTokenBox.addItem(t1);
+ }
+
+ mDBPasswd = wizardInfo.getInternalDBPasswd();
+
+ String tokenname = "";
+ String password = "";
+ if (wizardInfo.isCAInstalled()) {
+ tokenname = wizardInfo.getCATokenName();
+ password = (String)wizardInfo.get("TOKEN:"+tokenname);
+ if (password == null || password.equals("")) {
+ capassword = "";
+ } else {
+ capassword = password;
+ }
+ ca = true;
+ } else {
+ capassword = "";
+ ca = false;
+ }
+
+ if (wizardInfo.isRAInstalled()) {
+ tokenname = wizardInfo.getRATokenName();
+ password = (String)wizardInfo.get("TOKEN:"+tokenname);
+ if (password == null || password.equals("")) {
+ rapassword = "";
+ } else {
+ rapassword = password;
+ }
+ ra = true;
+ } else {
+ rapassword = "";
+ ra = false;
+ }
+
+ if (wizardInfo.isKRAInstalled()) {
+ tokenname = wizardInfo.getKRATokenName();
+ password = (String)wizardInfo.get("TOKEN:"+tokenname);
+ if (password == null || password.equals("")) {
+ krapassword = "";
+ } else {
+ krapassword = password;
+ }
+ kra = true;
+ } else {
+ krapassword = "";
+ kra = false;
+ }
+
+ tokenname = wizardInfo.getSSLTokenName();
+ password = (String)wizardInfo.get("TOKEN:"+tokenname);
+ if (password == null || password.equals("")) {
+ sslpassword = "";
+ } else {
+ sslpassword = password;
+ }
+ setBorder(makeTitledBorder(PANELNAME));
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+
+ /**
+ * Copy from CGITask.java
+ */
+ public boolean run(String cmd) {
+ // get the admin URL location first
+ String mAdminURL = _consoleInfo.getAdminURL();
+ if ( mAdminURL == null ) {
+ return false;
+ }
+
+ // Allow specifying e.g. "slapd-install" for instance
+ String instance = (String)_consoleInfo.get( cmd );
+ if (instance == null)
+ instance = (String)_consoleInfo.get( "ServerInstance" );
+ String fullCmd = mAdminURL + instance + "/" + cmd;
+
+ HttpManager h = new HttpManager();
+ // tell the http manager to use UTF8 encoding
+ h.setSendUTF8(true);
+
+ try {
+ mSuccess = false;
+ mFinished = false;
+
+ // _consoleInfo.get("arguments") is a hashtable of key/value pairs
+ // to use as the arguments to the CGI
+ Hashtable args = (Hashtable)_consoleInfo.get("arguments");
+ ByteArrayInputStream data = null;
+ if (args != null && !args.isEmpty())
+ data = com.netscape.admin.certsrv.task.CGITask.encode(args);
+ Debug.println( "Posting " + fullCmd );
+ // tell the http manager to notify us immediately of replies
+ // if we're using async mode
+ int flags = 0;
+ if (data == null)
+ h.post(new URL(fullCmd), this, null, null, 0, flags);
+ else
+ h.post(new URL(fullCmd), this, null, data, data.available(),
+ flags);
+ awaitSuccess();
+ Debug.println( "Command executed: " + fullCmd );
+ } catch (Exception e) {
+ if (e instanceof java.net.ConnectException) {
+ CMSAdminUtil.showMessageDialog(mResource,
+ PREFIX, "SERVERDOWN", CMSAdminUtil.ERROR_MESSAGE);
+ }
+ Debug.println( "Command " + fullCmd + " failed: " + e );
+ }
+ return mSuccess;
+ }
+
+ /**
+ * waiting for the http transaction to be finished.
+ */
+ public synchronized void awaitSuccess() {
+ while (!mFinished) {
+ try {
+ wait();
+ } catch (Exception e) { }
+ }
+ }
+
+ /**
+ * http transaction finished, notify the process
+ */
+ public synchronized void finish() {
+ mFinished = true;
+ notifyAll();
+ }
+
+ /**
+ * the operation is finished after we receive the http stream
+ */
+ public void replyHandler(InputStream response, CommRecord cr) {
+ try {
+ int nBytes = response.available();
+ if ( nBytes > 0 ) {
+ // the response from the DS CGIs will typically be in
+ // UTF8 encoding
+ byte[] data = new byte[nBytes];
+ nBytes = response.read( data );
+ mReply = new String( data, 0, nBytes, "UTF8" );
+ Debug.println( "CGITask.replyHandler: Response (" + nBytes +
+ " bytes) = " + mReply );
+ int index = 0;
+ if ((mReply.indexOf("NMC_") != -1) &&
+ ((index = mReply.indexOf(":")) != -1)) {
+ String sName = mReply.substring(0, index).trim();
+ String sValue = mReply.substring(index+1).trim();
+ if (sName.equalsIgnoreCase("NMC_Status")) {
+ int code = Integer.parseInt(sValue);
+ mSuccess = (code == 0);
+ } else if (sName.equalsIgnoreCase("NMC_ERRINFO")) {
+ mErrorMsg = sValue; }
+ }
+ }
+ } catch ( Exception e ) {
+ Debug.println( "CGITask.replyHandler: " + e.toString() );
+ }
+ finish();
+ }
+
+ /**
+ * this function will be called if error occurs
+ */
+ public void errorHandler(Exception error, CommRecord cr) {
+ Debug.println("CGITask.errorHandler: " + error );
+
+ // this is a hack. now we dont know how to set the timeout period longer.
+ // We always assume everything is fine so that we can proceed to the next
+ // config-cert panel.
+ mSuccess = true;
+ finish();
+ }
+
+ /**
+ * pass the username to the admin server
+ */
+ public String username(Object authObject, CommRecord cr) {
+ Debug.println( "username = " +
+ (String)_consoleInfo.getAuthenticationDN());
+ return _consoleInfo.getAuthenticationDN();
+ }
+
+ /**
+ * pass the user password to the admin server
+ */
+ public String password(Object authObject, CommRecord cr) {
+ Debug.println( "password = " +
+ (String)_consoleInfo.get( "AdminUserPassword" ) );
+ return (String)_consoleInfo.get( "AdminUserPassword" );
+ }
+ /**
+ * Starts CMS server.
+ */
+ public boolean startServer(InstallWizardInfo info) {
+ _consoleInfo = info.getAdminConsoleInfo();
+
+ Hashtable configParams = new Hashtable();
+ configParams.put("serverRoot",_consoleInfo.get("serverRoot"));
+ String servid = (String)_consoleInfo.get("servid");
+ int index = servid.indexOf("-");
+ if (index != -1) {
+ servid = servid.substring(index+1);
+ }
+ configParams.put("instanceID", servid);
+ // configParams.put("password", info.getSingleSignOnPassword());
+ _consoleInfo.put( "ServerInstance", "cert-" + servid);
+ _consoleInfo.put("arguments", configParams);
+ // Debug.println("password "+dialog.getPassword());
+
+ if (_consoleInfo.get("AdminUsername") == null) {
+ _consoleInfo.put("AdminUsername", _consoleInfo.getAuthenticationDN()
+);
+ }
+ Debug.println("AdminUsername = " + _consoleInfo.get("AdminUsername"));
+
+ if (_consoleInfo.get("AdminUserPassword") == null) {
+ _consoleInfo.put("AdminUserPassword", _consoleInfo.getAuthenticationPassword());
+ }
+ Debug.println("AdminUserPassword = " + _consoleInfo.get("AdminUserPassword"));
+ // call the CGI program
+ Debug.println("CMSStart: start() before run task="+START_TASK_CGI);
+ boolean status;
+ try {
+ status = run(START_TASK_CGI);
+ } catch (Exception e) {
+ Debug.println("Unexpected Error"+e.toString());
+ status = false;
+ }
+ Debug.println("CMSStart: start() after run status="+status);
+
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ // Comment out the single signon codes for now.
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_SINGLE_SIGNON;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ String tags = PW_TAG_INTERNAL_LDAP_DB;
+ rawData = rawData+"&"+PW_TAG_INTERNAL_LDAP_DB+"="+mDBPasswd;
+ rawData = rawData+"&pwcTokenname="+(String)(mTokenBox.getSelectedItem());
+
+ String tokenname = "";
+ if (!capassword.equals("")) {
+ tokenname = wizardInfo.getCATokenName();
+ rawData = rawData+"&"+tokenname+"="+capassword;
+ tags = tags+":"+tokenname;
+ }
+
+ if (!rapassword.equals("")) {
+ tokenname = wizardInfo.getRATokenName();
+ rawData = rawData+"&"+tokenname+"="+rapassword;
+ tags = tags+":"+tokenname;
+ }
+
+ if (!krapassword.equals("")) {
+ tokenname = wizardInfo.getKRATokenName();
+ rawData = rawData+"&"+tokenname+"="+krapassword;
+ tags = tags+":"+tokenname;
+ }
+
+ if (!sslpassword.equals("")) {
+ tokenname = wizardInfo.getSSLTokenName();
+ rawData = rawData+"&"+tokenname+"="+sslpassword;
+ tags = tags+":"+tokenname;
+ }
+
+ if (mPasswordConf.isSelected()) {
+ rawData = rawData+"&"+ConfigConstants.PR_DELETE_PASSWD_CONF+"="+
+ ConfigConstants.TRUE;
+ } else {
+ rawData = rawData+"&"+ConfigConstants.PR_DELETE_PASSWD_CONF+"="+
+ ConfigConstants.FALSE;
+ }
+ rawData = rawData+"&"+ConfigConstants.PR_SINGLE_SIGNON_PW_TAGS+"="+tags;
+ //data.put(ConfigConstants.PR_SINGLE_SIGNON, ConfigConstants.FALSE);
+
+ startProgressStatus();
+ //CMSMessageBox dlg = new CMSMessageBox(mAdminFrame, "CGITASK", "CREATESSON");
+
+ // boolean ready = send(rawData, wizardInfo);
+
+ boolean ready = true;
+ if (ready) {
+ rawData = ConfigConstants.TASKID+"="+TaskId.TASK_MISCELLANEOUS;
+/*
+ data.put(ConfigConstants.PR_ADMIN_PASSWD,
+ (String)consoleInfo.get(ConfigConstants.PR_ADMIN_PASSWD));
+*/
+ ready = send(rawData, wizardInfo);
+ } else {
+ String str = getErrorMessage();
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ PANELNAME+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ //dlg.setVisible(false);
+
+ endProgressStatus();
+ return false;
+ }
+
+ //startServer(wizardInfo);
+
+ //dlg.setVisible(false);
+
+ endProgressStatus();
+
+ if (!ready) {
+ String str = getErrorMessage(wizardInfo);
+ if (str.equals("")) {
+ String errorMsg = mResource.getString(
+ PANELNAME+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ }
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea desc = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+/*
+ JPanel panel1 = new JPanel();
+ GridBagLayout gb1 = new GridBagLayout();
+ panel1.setLayout(gb1);
+ //panel1.setBorder(new EtchedBorder());
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ add(panel1, gbc);
+*/
+
+ JTextArea heading = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_HEADING1_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.fill = gbc.NONE;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(2*COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE, 0);
+ add(heading, gbc);
+
+ JLabel tokenLbl = makeJLabel("TOKEN");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ //gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE, 0, COMPONENT_SPACE);
+ add(tokenLbl, gbc);
+
+ mTokenBox = new JComboBox();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0, 0);
+ add(mTokenBox, gbc);
+
+ JLabel dum = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.fill = gbc.BOTH;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, 0, 0);
+ add(dum, gbc);
+
+ JTextArea passwordConfText = createTextArea(mResource.getString(
+ PANELNAME+"_TEXT_PASSWDCONF_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(4*COMPONENT_SPACE,COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(passwordConfText, gbc);
+
+ mPasswordConf = makeJCheckBox("PASSWDCONF");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,2*COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mPasswordConf, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.fill = gbc.BOTH;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WITokenLogonPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WITokenLogonPage.java
new file mode 100644
index 000000000..b3ecdbf5a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WITokenLogonPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * This panel asks for the information of the current internal database.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WITokenLogonPage extends WizardBasePanel implements IWizardPanel {
+ protected JTextField mTokenText;
+ protected JLabel mPasswordAgainLabel;
+ protected JPasswordField mPasswordText, mPasswordAgainText;
+ private static final String EMPTYSTR = " ";
+ protected String mHelpIndex;
+ protected String mPanelName;
+ protected JTextArea mDesc;
+ protected Color mActiveColor;
+ protected String mTokenName;
+
+ WITokenLogonPage(String panelName) {
+ super(panelName);
+ mPanelName = panelName;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ setBorder(makeTitledBorder(mPanelName));
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+
+ String tokenList = wizardInfo.getTokensList();
+ String tokenLoggedIn = wizardInfo.getTokensLogin();
+ String tokenInits = wizardInfo.getTokensInit();
+ StringTokenizer tokenizer = new StringTokenizer(tokenList, ":");
+ StringTokenizer tokenizerLoggedIn = new StringTokenizer(tokenLoggedIn, ":");
+ StringTokenizer tokenizerInits = new StringTokenizer(tokenInits, ":");
+ int index = 0;
+ String loggedIn = "";
+ String inits = "";
+ while (tokenizer.hasMoreElements()) {
+ String token = (String)tokenizer.nextElement();
+ loggedIn = (String)tokenizerLoggedIn.nextElement();
+ inits = (String)tokenizerInits.nextElement();
+ if (token.equalsIgnoreCase(mTokenName)) {
+ break;
+ }
+ index++;
+ }
+
+ if (inits.equals(Constants.FALSE)) {
+ mDesc.setText(mResource.getString(mPanelName+"_TEXT_INIT_LABEL"));
+ enableFields(mPasswordAgainLabel, mPasswordAgainText, true, mActiveColor);
+ } else {
+ mDesc.setText(mResource.getString(mPanelName+"_TEXT_HEADING_LABEL"));
+ enableFields(mPasswordAgainLabel, mPasswordAgainText, false, getBackground());
+ }
+
+ mTokenText.setEnabled(false);
+ mTokenText.setEditable(false);
+ mTokenText.setBackground(getBackground());
+ CMSAdminUtil.repaintComp(mTokenText);
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ String passwd = mPasswordText.getText();
+ if (passwd.equals("")) {
+ setErrorMessage("BLANKPASSWD");
+ return false;
+ }
+ if (mPasswordAgainText.isEnabled()) {
+ String passwdAgain = mPasswordAgainText.getText();
+ if (!passwd.equals(passwdAgain)) {
+ setErrorMessage("NOTSAMEPASSWD");
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)info;
+ cleanUpWizardInfo(wizardInfo);
+
+ String tokenname = mTokenText.getText().trim();
+ String pwd = mPasswordText.getText().trim();
+ wizardInfo.put("TOKEN:"+tokenname, pwd);
+
+ String rawData = ConfigConstants.TASKID+"="+TaskId.TASK_INIT_TOKEN;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_MODIFY;
+ rawData = rawData+"&"+ConfigConstants.PR_TOKEN_NAME+"="+tokenname;
+ rawData = rawData+"&"+ConfigConstants.PR_TOKEN_PASSWD+"="+pwd;
+ rawData = rawData+"&"+ConfigConstants.PR_CMS_SEED+"="+
+ (new Long(WizardBasePanel.mSeed).toString());
+
+ startProgressStatus();
+ boolean ready = send(rawData, wizardInfo);
+
+ if (!ready) {
+ String str = getErrorMessage(wizardInfo);
+ if (str == null) {
+ String errorMsg = mResource.getString(
+ mPanelName+"_ERRORMSG");
+ setErrorMessage(errorMsg);
+ } else
+ setErrorMessage(str);
+ } else {
+ rawData = ConfigConstants.TASKID+"="+TaskId.TASK_TOKEN_INFO;
+ rawData = rawData+"&"+ConfigConstants.OPTYPE+"="+OpDef.OP_READ;
+ ready = send(rawData, wizardInfo);
+ }
+
+ if (!ready) {
+ String str = getErrorMessage(wizardInfo);
+ if (str.equals(""))
+ setErrorMessage("Server Error");
+ else
+ setErrorMessage(str);
+ }
+
+ endProgressStatus();
+
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(mHelpIndex);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mDesc = createTextArea("");
+/*
+ mDesc = createTextArea(mResource.getString(
+ mPanelName+"_TEXT_HEADING_LABEL"));
+*/
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mDesc, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel tokenLabel = makeJLabel("TOKEN");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(tokenLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mTokenText = makeJTextField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mTokenText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel passwordLabel = makeJLabel("PWD");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(passwordLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPasswordText = makeJPasswordField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ // gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mPasswordText, gbc);
+ mActiveColor = mPasswordText.getBackground();
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPasswordAgainLabel = makeJLabel("PWDAGAIN");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mPasswordAgainLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPasswordAgainText = makeJPasswordField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ // gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mPasswordAgainText, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+
+ protected void enableFields(JComponent comp1, JTextComponent comp2, boolean enable, Color color) {
+ comp1.setEnabled(enable);
+ comp2.setEnabled(enable);
+ comp2.setEditable(enable);
+ comp2.setBackground(color);
+ CMSAdminUtil.repaintComp(comp1);
+ CMSAdminUtil.repaintComp(comp2);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/config/install/WITrustDBPage.java b/base/console/src/com/netscape/admin/certsrv/config/install/WITrustDBPage.java
new file mode 100644
index 000000000..cd19963ff
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/config/install/WITrustDBPage.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.admin.certsrv.config.install;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Trust database page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WITrustDBPage extends WizardBasePanel implements IWizardPanel {
+ private JPasswordField mPassword;
+ private JPasswordField mPasswordAgain;
+ private static final String PANELNAME = "TRUSTDBWIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WITrustDBPage() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea desc = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "TRUSTDBWIZARD_TEXT_DESC_LABEL"), 80), 2, 80);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ JLabel passwdLbl = makeJLabel("PASSWD");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(passwdLbl, gbc);
+
+ mPassword = makeJPasswordField(20);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(mPassword, gbc);
+
+ JTextArea dummy = createTextArea(" ", 1, 15);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(dummy, gbc);
+
+ JLabel passwdAgainLbl = makeJLabel("PASSWDAGAIN");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0,COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.weighty = 1.0;
+ add(passwdAgainLbl, gbc);
+
+ mPasswordAgain = makeJPasswordField(20);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.weighty = 1.0;
+ add(mPasswordAgain, gbc);
+
+ JTextArea dummy1 = createTextArea(" ", 1, 15);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.insets = new Insets(0, COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(dummy1, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/connection/AdminConnection.java b/base/console/src/com/netscape/admin/certsrv/connection/AdminConnection.java
new file mode 100644
index 000000000..acb023132
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/connection/AdminConnection.java
@@ -0,0 +1,818 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.connection;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.preferences.*;
+
+/**
+ * This class represents an administration connection shell
+ * to the certificate server. The user need to specify the
+ * connection factory
+ *
+ * @author thomask
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.certsrv.client.connection
+ * @see com.netscape.certsrv.client
+ */
+public class AdminConnection {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static int NO_TIMEOUT = 0;
+ public static int DEFAULT_TIMEOUT = 600000; //600 sec
+
+ private IConnectionFactory mFactory= null;
+ private IConnection mConn = null;
+ private IAuthenticator mAuth = null;
+ private int mDefaultTimeout = DEFAULT_TIMEOUT;
+ private int mCurrentTimeout = DEFAULT_TIMEOUT;
+ private boolean mIsKeepAlive = false;
+ private String mHost;
+ private int mPort;
+ private IConnectionListener mConnectionListener;
+ private String mAuthType="";
+ private String mPath=null;
+ private static FilePreferenceManager mPM = null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ /**
+ * Default Constructor<p>
+ * Construct an administartion connection with keep alive disabled
+ *
+ * @param auth authentication mechanism object
+ * @param factory factory used to create server connection
+ * @param host server host name
+ * @param port server port number
+ *
+ * @see com.netscape.certsrv.client.connection.IConnection
+ * @see com.netscape.certsrv.client.connection.IConnectionFactory
+ * @see com.netscape.certsrv.client.connection.IAuthenticator
+ */
+ public AdminConnection( IAuthenticator auth,
+ IConnectionFactory factory,
+ String host, int port, String path) {
+ if (mPM == null) {
+ mPM = new FilePreferenceManager(Framework.IDENTIFIER,
+ Framework.VERSION);
+ }
+ Preferences p = mPM.getPreferences(
+ Framework.PREFERENCES_GENERAL);
+ int timeout = p.getInt("CMSConnTimeout", 600000);
+ setDefaultTimeout(timeout);
+ setCurrentTimeout(timeout);
+ Debug.println("AdminConnection: " + timeout + " " +
+ mPM.getClass().getName());
+
+ mAuth = auth;
+ mFactory = factory;
+ mHost = host;
+ mPort = port;
+ mPath = path;
+ }
+
+ /**
+ * Default Constructor<p>
+ * Construct an administartion connection
+ *
+ * @param auth authentication mechanism object
+ * @param factory factory used to create server connection
+ * @param enableKeepAlive enable HTTP keep alive or not
+ * @param host server host name
+ * @param port server port number
+ *
+ * @see com.netscape.certsrv.client.connection.IConnection
+ * @see com.netscape.certsrv.client.connection.IConnectionFactory
+ * @see com.netscape.certsrv.client.connection.IAuthenticator
+ */
+ public AdminConnection( IAuthenticator auth,
+ IConnectionFactory factory,
+ boolean enableKeepAlive,
+ String host, int port, String path) {
+ if (mPM == null) {
+ mPM = new FilePreferenceManager(Framework.IDENTIFIER,
+ Framework.VERSION);
+ }
+ Preferences p = mPM.getPreferences(
+ Framework.PREFERENCES_GENERAL);
+ int timeout = p.getInt("CMSConnTimeout", 600000);
+ setDefaultTimeout(timeout);
+ setCurrentTimeout(timeout);
+ Debug.println("AdminConnection: " + timeout + " " +
+ mPM.getClass().getName());
+
+ mAuth = auth;
+ mFactory = factory;
+ mIsKeepAlive = enableKeepAlive;
+ mHost = host;
+ mPort = port;
+ mPath = path;
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ private String b64encode (byte[] data) {
+ int i, k, n;
+ int len = data.length;
+ byte b;
+ StringBuffer b64 = new StringBuffer();
+ String base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+ for (i = 0; i < len; i += 3) {
+ byte d0 = data[i];
+ byte d1 = (i+1<len)? data[i+1]: (byte)0;
+ byte d2 = (i+2<len)? data[i+2]: (byte)0;
+ b = (byte)((d0 & (byte)0xFC) >>> 2);
+ b64.append(base64.charAt((int)b));
+ b = (byte)(((d0 & 0x03) << 4) | ((d1 & 0xF0) >>> 4));
+ b64.append(base64.charAt((int)b));
+ b = (byte)(((d1 & 0x0F) << 2) | ((d2 & 0xC0) >>> 6));
+ if (i+1 < len) {
+ b64.append(base64.charAt((int)b));
+ } else {
+ b64.append('=');
+ }
+ b = (byte)(d2 & 0x3F);
+ if (i+2 < len) {
+ b64.append(base64.charAt((int)b));
+ } else {
+ b64.append('=');
+ }
+ }
+
+ b64.append('\n');
+
+ return b64.toString();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Set the listener.
+ */
+ public void setConnectionListener(IConnectionListener l) {
+ mConnectionListener = l;
+ }
+
+ /**
+ * Returns the authentication object for this connection.<p>
+ * The choice of authentication object is dependding on the
+ * authentication method used on the server side.
+ *
+ * @return authentication object
+ * @see com.netscape.certsrv.client.connection.IAuthenticator
+ * @see com.netscape.certsrv.client.connection.BasicAuthenticator
+ */
+ public IAuthenticator getAuthenticator() {
+ return mAuth;
+ }
+
+ /**
+ * Returns the connection object used to establish the connection
+ * This can be SSLavaConnection or SSLConnection. THIS OBJECT REFERENCE
+ * IS NOT STABLE, SINCE IT IS RECREATED EACH TIME IF KEEPALIVE IS NOT
+ * ENABLE.
+ *
+ * @return connection object
+ */
+ public IConnection getIConnection() {
+ return mConn;
+ }
+
+ /**
+ * Sets the one time current timeout value for specific operation
+ * if less then default timeout the default timeout is used.
+ *
+ * @param timeout time in ms
+ */
+ public void setCurrentTimeout(int timeout) {
+ mCurrentTimeout = timeout;
+ }
+
+
+ /**
+ * Sets the default timeout value
+ * @param timeout time in ms
+ */
+ public void setDefaultTimeout(int timeout) {
+ mDefaultTimeout = timeout;
+ }
+
+ /**
+ * OPERATION: ADD<p>
+ *
+ * <pre>
+ * FORMAT:
+ *
+ * GET/[OP_DEST]?
+ * OP_TYPE=[OP_TYPE]&
+ * OP_SCOPE=[OP_SCOPE]&
+ * RS_ID=[RS_ID]&
+ * [NAME=VALUE][&[NAME=VALUE]]
+ *
+ * </pre>
+ *
+ * Add new entries into the scope using the NVP information provided.
+ * This operation will ONLY be used by DYNAMIC content and
+ * configuartion, such as Users and Groups, and Policies.
+ *
+ * @param dest OP_DEST
+ * @param scope OP_SCOPE
+ * @param id RS_ID
+ * @param pairs NVP info
+ *
+ * @see http://warp/server/certificate/columbo/design/ui/admin-protocol-definition.html
+ *
+ */
+ public void add(String dest, String scope, String id, NameValuePairs pairs)
+ throws EAdminException {
+
+ checkParams(dest,scope,id,pairs);
+ Request request = new Request(mPath + "/" + dest);
+ request.set(Constants.OP_TYPE, OpDef.OP_ADD);
+ request.set(Constants.OP_SCOPE, scope);
+ request.set(Constants.RS_ID, id);
+ for (String name : pairs.keySet()) {
+ String value = pairs.get(name);
+ request.set(name, value);
+ }
+ Response response = sendRequest(request);
+ if (response.getReturnCode() == Response.SUCCESS) {
+ return;
+ }
+ throw new EAdminException(response.getErrorMessage(), true);
+ }
+
+ /**
+ * OPERATION: DELETE<p>
+ *
+ * <pre>
+ * FORMAT:
+ *
+ * GET/[OP_DEST]?
+ * OP_TYPE=[OP_TYPE]&
+ * OP_SCOPE=[OP_SCOPE]&
+ * RS_ID=[RS_ID]&
+ *
+ * </pre>
+ *
+ * Removing an entry with specified id from the scope specified.
+ *
+ * @param dest OP_DEST
+ * @param scope OP_SCOPE
+ * @param id RS_ID
+ *
+ * @see http://warp/server/certificate/columbo/design/ui/admin-protocol-definition.html
+ *
+ */
+ public void delete(String dest, String scope, String id)
+ throws EAdminException {
+
+ checkParams(dest,scope,id);
+ Request request = new Request(mPath + "/" + dest);
+ request.set(Constants.OP_TYPE, OpDef.OP_DELETE);
+ request.set(Constants.OP_SCOPE, scope);
+ request.set(Constants.RS_ID, id);
+ Response response = sendRequest(request);
+ if (response.getReturnCode() == Response.SUCCESS) {
+ return;
+ }
+ throw new EAdminException(response.getErrorMessage(), true);
+ }
+
+ public void delete(String dest, String scope, String id, NameValuePairs pairs)
+ throws EAdminException {
+
+ checkParams(dest,scope,id,pairs);
+ Request request = new Request(mPath + "/" + dest);
+ request.set(Constants.OP_TYPE, OpDef.OP_DELETE);
+ request.set(Constants.OP_SCOPE, scope);
+ request.set(Constants.RS_ID, id);
+ for (String name : pairs.keySet()) {
+ String value = pairs.get(name);
+ request.set(name, value);
+ }
+ Response response = sendRequest(request);
+ if (response.getReturnCode() == Response.SUCCESS) {
+ return;
+ }
+ throw new EAdminException(response.getErrorMessage(), true);
+ }
+
+ /**
+ * OPERATION: AUTH<p>
+ *
+ * <pre>
+ * FORMAT:
+ *
+ * GET/[OP_DEST]?
+ * OP_TYPE=[OP_TYPE]&
+ * OP_SCOPE=[OP_SCOPE]&
+ * [NAME=VALUE][&[NAME=VALUE]]
+ *
+ * </pre>
+ *
+ * getting properties (name-value pairs) using some criteria
+ * specified in NVP.
+ *
+ * @param dest OP_DEST
+ * @param scope OP_SCOPE
+ * @param pairs NVP search filter
+ *
+ * @see http://warp/server/certificate/columbo/design/ui/admin-protocol-definition.html
+ *
+ */
+ public void auth(String dest, String scope) throws EAdminException {
+ Request request = new Request(mPath + "/" + dest);
+ request.set(Constants.OP_TYPE, OpDef.OP_AUTH);
+ request.set(Constants.OP_SCOPE, scope);
+ Response response = sendRequest(request);
+ if (response.getReturnCode() == Response.SUCCESS) {
+ return;
+ }
+ throw new EAdminException(response.getErrorMessage(), true);
+ }
+
+ public String authType(String dest, String scope) throws EAdminException {
+ Request request = new Request(mPath + "/" + dest);
+ request.set(Constants.OP_TYPE, OpDef.OP_AUTH);
+ request.set(Constants.OP_SCOPE, scope);
+
+ Response response = sendRequest(request);
+ if (response.getReturnCode() == Response.SUCCESS) {
+ Enumeration e = response.getNames();
+ while (e.hasMoreElements()) {
+ String n = (String)e.nextElement();
+ if (n.equals("authType"))
+ mAuthType = response.get(n);
+ return mAuthType;
+ }
+ return "";
+ }
+ throw new EAdminException(response.getErrorMessage(), true);
+ }
+
+ /**
+ * OPERATION: SEARCH<p>
+ *
+ * <pre>
+ * FORMAT:
+ *
+ * GET/[OP_DEST]?
+ * OP_TYPE=[OP_TYPE]&
+ * OP_SCOPE=[OP_SCOPE]&
+ * [NAME=VALUE][&[NAME=VALUE]]
+ *
+ * </pre>
+ *
+ * getting properties (name-value pairs) using some criteria
+ * specified in NVP.
+ *
+ * @param dest OP_DEST
+ * @param scope OP_SCOPE
+ * @param pairs NVP search filter
+ *
+ * @see http://warp/server/certificate/columbo/design/ui/admin-protocol-definition.html
+ *
+ */
+ public NameValuePairs search(String dest, String scope, NameValuePairs filters)
+ throws EAdminException {
+
+ checkParams(dest,scope,"",filters);
+ Request request = new Request(mPath + "/" + dest);
+ request.set(Constants.OP_TYPE, OpDef.OP_SEARCH);
+ request.set(Constants.OP_SCOPE, scope);
+ for (String name : filters.keySet()) {
+ String value = filters.get(name);
+ request.set(name, value);
+ }
+
+ Response response = sendRequest(request);
+
+ if (response.getReturnCode() == Response.SUCCESS) {
+ NameValuePairs newpairs = new NameValuePairs();
+ Enumeration e = response.getNames();
+ while (e.hasMoreElements()) {
+ String n = (String)e.nextElement();
+ newpairs.put(n, response.get(n));
+ }
+ return newpairs;
+ }
+ throw new EAdminException(response.getErrorMessage(), true);
+ }
+
+ /**
+ * OPERATION: READ<p>
+ *
+ * <pre>
+ * FORMAT:
+ *
+ * GET/[OP_DEST]?
+ * OP_TYPE=[OP_TYPE]&
+ * OP_SCOPE=[OP_SCOPE]&
+ * RS_ID=[RS_ID]&
+ * [NAME=VALUE][&[NAME=VALUE]]
+ *
+ * </pre>
+ *
+ * getting specific properties (name-value pairs) using
+ * attributes specified in NVP.
+ *
+ * @param dest OP_DEST
+ * @param scope OP_SCOPE
+ * @param id RS_ID
+ * @param pairs NVP info
+ *
+ * @see http://warp/server/certificate/columbo/design/ui/admin-protocol-definition.html
+ *
+ */
+ public NameValuePairs read(String dest, String scope, String id, NameValuePairs pairs)
+ throws EAdminException {
+
+ checkParams(dest,scope,id);
+ Request request = new Request(mPath + "/" + dest);
+ request.set(Constants.OP_TYPE, OpDef.OP_READ);
+ request.set(Constants.OP_SCOPE, scope);
+ request.set(Constants.RS_ID, id);
+ for (String name : pairs.keySet()) {
+ String value = pairs.get(name);
+ request.set(name, value);
+ }
+
+ Response response = sendRequest(request);
+
+ if (response.getReturnCode() == Response.SUCCESS) {
+ NameValuePairs newpairs = new NameValuePairs();
+ Enumeration e = response.getNames();
+ while (e.hasMoreElements()) {
+ String n = (String)e.nextElement();
+ newpairs.put(n, response.get(n));
+ }
+ return newpairs;
+ }
+ throw new EAdminException(response.getErrorMessage(), true);
+ }
+
+ public NameValuePairs process(String dest, String scope, String id,
+ NameValuePairs pairs) throws EAdminException {
+ return process(dest, scope, id, pairs, false);
+ }
+
+ public NameValuePairs process(String dest, String scope, String id,
+ NameValuePairs pairs, boolean useGET) throws EAdminException {
+ Request request = new Request(mPath + "/" + dest);
+ request.set(Constants.OP_TYPE, OpDef.OP_PROCESS);
+ request.set(Constants.OP_SCOPE, scope);
+ request.set(Constants.RS_ID, id);
+
+ for (String name : pairs.keySet()) {
+ String value = pairs.get(name);
+ request.set(name, value);
+ }
+
+ Response response = sendRequest(request, useGET);
+ if (response.getReturnCode() == Response.SUCCESS) {
+ NameValuePairs newpairs = new NameValuePairs();
+ Enumeration e = response.getNames();
+ while (e.hasMoreElements()) {
+ String n = (String)e.nextElement();
+ newpairs.put(n, response.get(n));
+ }
+ return newpairs;
+ }
+ throw new EAdminException(response.getErrorMessage(), true);
+ }
+
+ public void validate(String dest, String scope, NameValuePairs pairs)
+ throws EAdminException {
+ Request request = new Request(mPath + "/" + dest);
+ request.set(Constants.OP_TYPE, OpDef.OP_VALIDATE);
+ request.set(Constants.OP_SCOPE, scope);
+ for (String name : pairs.keySet()) {
+ String value = pairs.get(name);
+ request.set(name, value);
+ }
+
+ Response response = sendRequest(request);
+ if (response.getReturnCode() == Response.SUCCESS) {
+ return;
+ }
+ throw new EAdminException(response.getErrorMessage(), true);
+ }
+
+ /**
+ * OPERATION: MODIFY<p>
+ *
+ * <pre>
+ * FORMAT:
+ *
+ * GET/[OP_DEST]?
+ * OP_TYPE=[OP_TYPE]&
+ * OP_SCOPE=[OP_SCOPE]&
+ * RS_ID=[RS_ID]&
+ * [NAME=VALUE][&[NAME=VALUE]]
+ *
+ * </pre>
+ *
+ * Modify an existing entry's attributes.
+ *
+ * @param dest OP_DEST
+ * @param scope OP_SCOPE
+ * @param id RS_ID
+ * @param pairs NVP info
+ *
+ * @see http://warp/server/certificate/columbo/design/ui/admin-protocol-definition.html
+ *
+ */
+ public void modify(String dest, String scope, String id, NameValuePairs pairs)
+ throws EAdminException {
+ modify(dest, scope, id, pairs, false);
+ }
+
+ public void modify(String dest, String scope, String id, NameValuePairs pairs, boolean useGET)
+ throws EAdminException {
+
+ checkParams(dest,scope,id,pairs);
+ Request request = new Request(mPath + "/" + dest);
+ request.set(Constants.OP_TYPE, OpDef.OP_MODIFY);
+ request.set(Constants.OP_SCOPE, scope);
+ request.set(Constants.RS_ID, id);
+ for (String name : pairs.keySet()) {
+ String value = pairs.get(name);
+ request.set(name, value);
+ }
+ Response response = sendRequest(request, useGET);
+ if (response.getReturnCode() == Response.SUCCESS) {
+ return;
+ } else if (response.getReturnCode() == Response.RESTART) {
+ mConnectionListener.restartCallback();
+ return;
+ }
+ throw new EAdminException(response.getErrorMessage(), true);
+ }
+
+ private synchronized void retryConnection() throws EAdminException {
+ if (mConn instanceof JSSConnection) {
+ JSSConnection conn = (JSSConnection)mConn;
+ if (!conn.isTokenPasswordInit()) {
+ mConn = null;
+ if (!conn.isSamePwd()) {
+ throw new EAdminException(CMSAdminResources.SERVERCONNECTION_DIFFERENT_PWD, false);
+ }
+ throw new EAdminException(CMSAdminResources.SERVERCONNECTION_TOKEN_INIT_FAILED, false);
+ }
+
+ if (!conn.isServerCertImported()) {
+ mConn = null;
+ throw new EAdminException(CMSAdminResources.SERVERCONNECTION_SERVER_CERT_IMPORTED_FAILED, false);
+ }
+ if (!conn.isCertAccepted()) {
+ mConn = null;
+ throw new EAdminException(CMSAdminResources.SERVERCONNECTION_SERVER_CERT_DENIED, false);
+ }
+ if (conn != null && conn.isAbortAction() && conn.isClientAuth()) {
+ mConn = null;
+ throw new EAdminException(CMSAdminResources.SERVERCONNECTION_NO_CLIENT_CERT, false);
+ }
+ if (conn != null && !conn.hasClientCert()) {
+ mConn = null;
+ throw new EAdminException(CMSAdminResources.SERVERCONNECTION_NO_CLIENT_CERT, false);
+ }
+ }
+ try {
+ mConn = mFactory.create(mHost, mPort);
+ } catch (UnknownHostException e) {
+ mConn = null;
+ throw new EAdminException(CMSAdminResources.UNKNOWNHOST, false);
+ } catch (IOException e) {
+ mConn = null;
+ throw new EAdminException(CMSAdminResources.SERVER_UNREACHABLE, false);
+ } catch (Exception e) {
+ mConn = null;
+ if (Debug.isEnabled()) {
+ e.printStackTrace();
+ }
+ throw new EAdminException(CMSAdminResources.UNKNOWNEXCEPTION, false);
+ }
+ }
+
+ /**
+ * Deliver the request through the connection object
+ *
+ * @param request request object
+ * @return response object
+ * @see com.netscape.certsrv.client.connection.Response
+ */
+ private synchronized Response sendRequest(Request request)
+ throws EAdminException {
+ return sendRequest(request, false);
+ }
+
+ private synchronized Response sendRequest(Request request, boolean useGET)
+ throws EAdminException {
+
+ try {
+ if (mConn == null) {
+ mConn = mFactory.create(mHost, mPort);
+ }
+ } catch (UnknownHostException e) {
+ mConn = null;
+ throw new EAdminException(CMSAdminResources.UNKNOWNHOST, false);
+ } catch (IOException e) {
+ retryConnection();
+ throw new EAdminException(CMSAdminResources.SERVER_UNREACHABLE, false);
+ } catch (Exception e) {
+ retryConnection();
+ if (Debug.isEnabled()) {
+ e.printStackTrace();
+ }
+ throw new EAdminException(CMSAdminResources.UNKNOWNEXCEPTION, false);
+ }
+
+ try {
+ return processRequest(request, useGET);
+ //all errors will set the connection to null
+ //to force re-connection and avoid null ptr exception
+
+ } catch (Exception e) {
+ retryConnection();
+
+ try {
+ return processRequest(request, useGET);
+ } catch (InterruptedIOException ex) {
+
+ //timeout occurred
+ mConn = null;
+
+ //set time out back to original
+ mCurrentTimeout = mDefaultTimeout;
+ throw new EAdminException(CMSAdminResources.SERVER_NORESPONSE, false);
+ } catch (SocketException ex) {
+ mConn = null;
+ throw new EAdminException(CMSAdminResources.SERVER_UNREACHABLE, false);
+ } catch (IOException ex) {
+ if (Debug.isEnabled()) {
+ ex.printStackTrace();
+ }
+ mConn = null;
+ throw new EAdminException(CMSAdminResources.SERVER_UNREACHABLE, false);
+ } catch (EAdminException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ mConn = null;
+ if (Debug.isEnabled()) {
+ ex.printStackTrace();
+ }
+ throw new EAdminException(CMSAdminResources.UNKNOWNEXCEPTION, false);
+ }
+ }
+ }
+
+ private Response processRequest(Request request, boolean useGET) throws Exception {
+ //packaging the request
+ StringBuffer sb = new StringBuffer();
+ if (useGET) {
+ sb.append("GET /" + request.getPrefix() + "?");
+ Enumeration names = request.getElements();
+ while (names.hasMoreElements()) {
+ String name = (String)names.nextElement();
+ sb.append(name);
+ sb.append("=");
+ if (request.get(name) != null) {
+ sb.append(java.net.URLEncoder.encode(request.get(name)));
+ }
+ if (names.hasMoreElements())
+ sb.append("&");
+ }
+ } else {
+ sb.append("POST /" + request.getPrefix());
+ }
+ sb.append(" HTTP/1.0\n");
+
+ StringBuffer sb1 = new StringBuffer();
+ if (!useGET) {
+ sb.append("Content-type: application/x-www-form-urlencoded\n");
+ Enumeration names = request.getElements();
+ while (names.hasMoreElements()) {
+ String name = (String)names.nextElement();
+ sb1.append(name);
+ sb1.append("=");
+ if (request.get(name) != null) {
+ sb1.append(java.net.URLEncoder.encode(request.get(name)));
+ }
+ if (names.hasMoreElements())
+ sb1.append("&");
+ }
+ sb.append("Content-length: " + sb1.toString().length() + "\n");
+ }
+
+ sb.append("Pragma: no-cache\n");
+ if (mIsKeepAlive) {
+ sb.append("Connection: Keep-Alive\n");
+ }
+
+ if (mAuthType.equals("") || mAuthType.equals("pwd")) {
+ BasicAuthenticator auth = (BasicAuthenticator)mAuth;
+ // sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
+ // sb.append("Authorization: Basic " +
+ // encoder.encodeBuffer((auth.getUserid() +
+ // ":" + auth.getPassword()).getBytes()) + "\n");
+ sb.append("Authorization: Basic " +
+ b64encode((auth.getUserid() +
+ ":" + auth.getPassword()).getBytes()) + "\n");
+ } else if (mAuthType.equals("sslclientauth")) {
+ sb.append("\n");
+ } else {
+ throw new EAdminException(CMSAdminResources.AUTHENNOTSUPPORTED, false);
+ }
+
+ if (!useGET) {
+ sb.append(sb1.toString());
+ }
+ //Debug.println(sb.toString());
+
+ //System.out.println("AdminConnection: sendRequest() - sending");
+ int timeout = mDefaultTimeout;
+ if (mCurrentTimeout > mDefaultTimeout)
+ timeout = mCurrentTimeout;
+ mConn.setSoTimeout(timeout);
+ mConn.sendRequest(sb.toString());
+
+ Response resp = new Response(mConn.getResponse());
+
+ if (!mIsKeepAlive) {
+ mConn.disconnect();
+ mConn = null;
+ }
+
+ //set time out back to original
+ mConn.setSoTimeout(mDefaultTimeout);
+ mCurrentTimeout = mDefaultTimeout;
+ return resp;
+ }
+
+ private void checkParams(String dest,String scope,String id)
+ {
+ NameValuePairs pairs = new NameValuePairs();
+
+ checkParams(dest,scope,id,pairs);
+ }
+
+ private void checkParams(String dest,String scope,String id, NameValuePairs pairs)
+ {
+ boolean bad=false;
+ if (dest == null) {
+ Debug.println("** WARNING **: 'dest' = null");
+ bad = true;
+ }
+ if (scope == null) {
+ Debug.println("** WARNING ** : 'scope' = null");
+ bad = true;
+ }
+ if (id == null) {
+ Debug.println("** WARNING ** : 'id' = null");
+ bad = true;
+ }
+ if (pairs == null) {
+ Debug.println("** WARNING ** : 'pairs' = null");
+ bad = true;
+ }
+ if (bad) {
+ Debug.println("dest = "+dest);
+ Debug.println("scope = "+scope);
+ Debug.println("id = "+id);
+ Debug.println("---------");
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/connection/BasicAuthenticator.java b/base/console/src/com/netscape/admin/certsrv/connection/BasicAuthenticator.java
new file mode 100644
index 000000000..1d3796968
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/connection/BasicAuthenticator.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.admin.certsrv.connection;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * An interface represents authentiator.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class BasicAuthenticator implements IAuthenticator {
+
+ private String mUserid = null;
+ private String mPassword = null;
+
+ public BasicAuthenticator(String userid, String password) {
+ mUserid = userid;
+ mPassword = password;
+ }
+
+ public String getUserid() {
+ return mUserid;
+ }
+
+ public String getPassword() {
+ return mPassword;
+ }
+
+ public void setUserId(String userid) {
+ mUserid = userid;
+ }
+
+ public void setPassword(String password) {
+ mPassword = password;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/connection/IAuthenticator.java b/base/console/src/com/netscape/admin/certsrv/connection/IAuthenticator.java
new file mode 100644
index 000000000..c91b7d8bc
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/connection/IAuthenticator.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.admin.certsrv.connection;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * An interface represents authentiator.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public interface IAuthenticator {
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/connection/IConnection.java b/base/console/src/com/netscape/admin/certsrv/connection/IConnection.java
new file mode 100644
index 000000000..0643e50eb
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/connection/IConnection.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.admin.certsrv.connection;
+
+import java.io.IOException;
+import java.net.SocketException;
+
+/**
+ * Interface for all connection objects. Primarily act as
+ * the abstartion layer for SSLavaConnection and SSLConnection.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.certsrv.client.connection.SSLavaConnection
+ * @see com.netscape.certsrv.client.connection.SSLConnection
+ */
+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/base/console/src/com/netscape/admin/certsrv/connection/IConnectionFactory.java b/base/console/src/com/netscape/admin/certsrv/connection/IConnectionFactory.java
new file mode 100644
index 000000000..4c8573f23
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/connection/IConnectionFactory.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.admin.certsrv.connection;
+
+import java.net.*;
+import java.io.*;
+
+/**
+ * Interface for all connection factory. Primarily act as
+ * the abstartion layer for different kind of connection factory.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.certsrv.client.connection
+ */
+public interface IConnectionFactory {
+
+ /**
+ * Creates connection using the host and port
+ */
+ public IConnection create(String host, int port)
+ throws IOException, UnknownHostException;
+
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/connection/JSSConnection.java b/base/console/src/com/netscape/admin/certsrv/connection/JSSConnection.java
new file mode 100644
index 000000000..27292b3d9
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/connection/JSSConnection.java
@@ -0,0 +1,761 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.connection;
+
+import java.util.*;
+import java.net.*;
+import java.io.*;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.Debug;
+import com.netscape.management.client.util.*;
+import org.mozilla.jss.ssl.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.util.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.pkcs11.*;
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * JSSConnection deals with establishing a connection to
+ * a server, sending requests and reading responses.
+ *
+ * XXX - Performance optimizations if any, persistent connection
+ * support, server auth verification and client authentication
+ * support to be added. NEED TO COME BACK AND CLEAN UP - coding
+ * standard.
+ *
+ * @author Jack Pan-Chen
+ * @author kanda
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class JSSConnection implements IConnection, SSLCertificateApprovalCallback,
+ SSLClientCertificateSelectionCallback {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+
+ /* static variables */
+ static CryptoManager cryptoManager;
+ static CertificateFactory cf;
+ static SelectCertDialog selectCertDialog = null;
+ static PromptForTrustDialog promptForTrustDialog = null;
+
+ /* private valiable */
+ private InputStream httpIn;
+ private OutputStream httpOut;
+ private byte[] body;
+ private int bodyLen;
+ private String header;
+ private int available;
+ private int totalRead;
+ private boolean endOfHeader = false;
+
+ private static int HTTP_OK_RESPONSE = 200;
+ private static final String PANELNAME = "SSLCLIENT";
+ private boolean abort = false;;
+ private boolean mClientAuth = false;
+ private boolean mCertAccepted = true;
+ private boolean mClientCertFound = true;
+ private boolean mServerCertImported = true;
+ private boolean mTokenPasswordInit = true;
+ private boolean mTokenPasswdSame = true;
+
+ protected SSLSocket s = null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public JSSConnection(String host, int port)
+ throws IOException, UnknownHostException {
+
+ UtilConsoleGlobals.initJSS();
+ cf = UtilConsoleGlobals.getX509CertificateFactory();
+ try {
+ cryptoManager = CryptoManager.getInstance();
+ } catch (Exception e) {
+ }
+
+ // SSLSocket needs to be set before getting an instance
+ // to get the ciphers
+ SSLSocket.enableSSL2Default(false);
+ SSLSocket.enableSSL3Default(true);
+ int TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA = 0xC005;
+ int TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A;
+
+ int ciphers[] = SSLSocket.getImplementedCipherSuites();
+ for (int i = 0; ciphers != null && i < ciphers.length; i++) {
+ // make sure SSLv2 ciphers are not enabled
+ if ((ciphers[i] & 0xfff0) !=0xff00) {
+ Debug.println("JSSConnection Debug: non-SSL2 NSS Cipher Supported '0x" +
+ Integer.toHexString(ciphers[i]) + "'");
+ SSLSocket.setCipherPreferenceDefault(ciphers[i], true);
+ } else {
+ Debug.println("JSSConnection Debug: SSL2 (turned off) NSS Cipher Supported '0x" +
+ Integer.toHexString(ciphers[i]) + "'");
+ SSLSocket.setCipherPreferenceDefault(ciphers[i], false);
+ }
+
+ /* Enable ECC Cipher */
+
+ if (ciphers[i] == TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA) {
+ Debug.println("JSSConnection Debug: found TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, setting preference");
+ SSLSocket.setCipherPreferenceDefault(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, true);
+ }
+ if (ciphers[i] == TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA) {
+ Debug.println("JSSConnection Debug: found TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, setting preference");
+ SSLSocket.setCipherPreferenceDefault(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, true);
+ }
+ }
+ s = new SSLSocket(host, port, null, 0, this, this);
+ s.enableSSL2(false);
+ s.enableSSL2Default(false);
+ s.enableV2CompatibleHello(false);
+ s.enableSSL3(true);
+ s.enableSSL3Default(true);
+
+ // Initialze Http Input and Output Streams
+ httpIn = s.getInputStream();
+ httpOut = s.getOutputStream();
+ cryptoManager.setPasswordCallback(new pwcb());
+ Debug.println("JSSConnection Debug: end of JSSConnection constructor");
+ }
+
+ public boolean approve(org.mozilla.jss.crypto.X509Certificate serverCert,
+ ValidityStatus status)
+ {
+ if (!mCertAccepted)
+ return false;
+
+ boolean promptForTrust = true;
+
+ //if server auth is not enabled
+ if (!(UtilConsoleGlobals.isServerAuthEnabled())) {
+ return mCertAccepted;
+ }
+
+ Enumeration errors = status.getReasons();
+ //if there are more then 1 error we need to propmt user for trust
+ promptForTrust = errors.hasMoreElements();
+
+ /* if trusted already */
+ if (!promptForTrust)
+ return mCertAccepted;
+
+ //the x509certificate pass in by jss is lacking some
+ //api. so I am getting the encoding then
+ //use the default security provider provided by sun
+ //to decode certificate.
+ //due to the fact that current JSS(version2.1) will clobber
+ //the way jdk loads the default sun security provider I am
+ //using the workaround for now. Which is to load the sun
+ //provider before jss is loaded. (see static section above)
+ X509Certificate x509Cert = null;
+ try {
+ ByteArrayInputStream bais = new ByteArrayInputStream(serverCert.getEncoded());
+
+ while (bais.available() > 0) {
+ x509Cert = (X509Certificate)(cf.generateCertificate(bais));
+ Debug.println(x509Cert.toString());
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ //bring up the trust dialog
+ promptForTrustDialog = new PromptForTrustDialog(getFrame(), x509Cert, status);
+ promptForTrustDialog.setVisible(true);
+ mCertAccepted = promptForTrustDialog.isCertAccepted();
+ if (mCertAccepted) {
+ //user want to save this certificate not just this session
+ //so we have to store the cert as perm cert.
+ if (!(promptForTrustDialog.isAcceptedForOneSession())) {
+ try {
+ String nickname = serverCert.getNickname();
+
+ CryptoToken internalToken =
+ cryptoManager.getInternalKeyStorageToken();
+
+ if (!internalToken.passwordIsInitialized()) {
+ InitPasswordDialog initPasswordDialog =
+ new InitPasswordDialog(internalToken);
+ initPasswordDialog.setVisible(true);
+ if (initPasswordDialog.isCancel()) {
+ mTokenPasswordInit = false;
+ return false;
+ }
+ if (!initPasswordDialog.isPwdSame()) {
+ mTokenPasswdSame = false;
+ mTokenPasswordInit = false;
+ return false;
+ }
+ if (!initPasswordDialog.isTokenInit()) {
+ mTokenPasswordInit = false;
+ return false;
+ }
+ }
+
+ if (!internalToken.isLoggedIn()) {
+ internalToken.login(new pwcb());
+ }
+ if (abort) {
+ mServerCertImported = false;
+ mCertAccepted = false;
+ return false;
+ }
+ InternalCertificate internalCert =
+ cryptoManager.importCertToPerm(serverCert,
+ (nickname==null)?serverCert.getSubjectDN().toString():nickname);
+ internalCert.setSSLTrust(
+ org.mozilla.jss.crypto.InternalCertificate.TRUSTED_PEER |
+ org.mozilla.jss.crypto.InternalCertificate.VALID_PEER);
+ } catch (Exception e) {
+ mServerCertImported = false;
+ mCertAccepted = false;
+ if (Debug.getTrace()) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+ }
+ }
+
+ return mCertAccepted;
+ }
+
+ public boolean isSamePwd() {
+ return mTokenPasswdSame;
+ }
+
+ public boolean isTokenPasswordInit() {
+ return mTokenPasswordInit;
+ }
+
+ public boolean hasClientCert() {
+ return mClientCertFound;
+ }
+
+ public boolean isClientAuth() {
+ return mClientAuth;
+ }
+
+ public boolean isCertAccepted() {
+ return mCertAccepted;
+ }
+
+ public boolean isAbortAction() {
+ return abort;
+ }
+
+ public boolean isServerCertImported() {
+ return mServerCertImported;
+ }
+
+ public String select(Vector nicknames)
+ {
+ selectCertDialog = null;
+ mClientAuth = true;
+ if (nicknames == null || nicknames.size() == 0) {
+ mClientCertFound = false;
+ return "";
+ }
+
+ selectCertDialog = new JSSConnection.SelectCertDialog();
+
+ Debug.println("JSSConnection::select(...) - SELECT CERTIFICATE");
+ selectCertDialog.setCertList(nicknames);
+ selectCertDialog.setVisible(true);
+ return (selectCertDialog.isCancel()?"":selectCertDialog.getSelectedCert());
+ }
+
+ public class pwcb implements PasswordCallback {
+ private int nthPrompt = 0;
+ private static final int MAX_PASSWORD_PROMPT = 20;
+ GetPasswordDialog getPasswordDialog = null;
+
+ public Password getPasswordFirstAttempt(PasswordCallbackInfo info)
+ throws PasswordCallback.GiveUpException {
+
+ if (abort)
+ throw new PasswordCallback.GiveUpException();
+
+ nthPrompt++;
+
+ if (getPasswordDialog == null)
+ getPasswordDialog = new GetPasswordDialog();
+
+ getPasswordDialog.setPasswordInfo(info, false);
+ getPasswordDialog.setVisible(true);
+
+ if (getPasswordDialog.isCancel()) {
+ nthPrompt = 0;
+ abort = true;
+ throw new PasswordCallback.GiveUpException();
+ }
+
+ return getPasswordDialog.getPassword();
+ }
+
+ public Password getPasswordAgain(PasswordCallbackInfo info)
+ throws GiveUpException
+ {
+
+ if (abort)
+ throw new PasswordCallback.GiveUpException();
+ nthPrompt++;
+ if (nthPrompt > MAX_PASSWORD_PROMPT || getPasswordDialog.isCancel()) {
+ nthPrompt = 0;
+ abort = true;
+ throw new PasswordCallback.GiveUpException();
+ }
+
+ getPasswordDialog.setPasswordInfo(info, true);
+ getPasswordDialog.setVisible(true);
+
+ return getPasswordDialog.getPassword();
+ }
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Send request to the server using this connection
+ *
+ * @param req request object
+ * @return status 1-success, 0- failed
+ * @excpetion IOExcpetion
+ */
+ public int sendRequest(String req)
+ throws IOException {
+
+ int stat = 1;
+ if (req == null)
+ {
+ //System.out.println("Request is null");
+ return 0;
+ }
+ endOfHeader = false;
+
+ PrintStream ps = new PrintStream(httpOut);
+ ps.println(req);
+ ps.println();
+ ps.flush();
+ try
+ {
+ Thread.sleep(100);
+ }
+ catch (Exception e) {
+ Debug.println("JSSConnection Debug: in sendRequest:"+e.toString());
+ System.out.println("sleeping "+e.toString());
+ }
+ //System.out.println("Request Sent - bytes:" + httpOut.getTotal());
+
+ // Init the Reply stream
+ totalRead = 0;
+ header = null;
+ initReadResponse();
+ return stat;
+ }
+
+ /**
+ * Retrieve the input stream
+ */
+ public InputStream getInputStream()
+ throws IOException {
+
+ return s.getInputStream();
+ }
+
+ /**
+ * Read
+ */
+ public int read(byte[] buf)
+ throws IOException {
+
+ return httpIn.read(buf, 0, buf.length);
+ }
+
+ /**
+ * Get Header
+ */
+ public String getHeader() {
+ if (header == null)
+ return "No Header Read";
+ else
+ return header;
+ }
+
+ /**
+ * Get response
+ */
+ public byte[] getResponse() {
+ if (totalRead == 0)
+ return null;
+ else {
+ byte[] buf = new byte[bodyLen];
+ System.arraycopy(body, 0, buf, 0, bodyLen);
+ return buf;
+ }
+ }
+
+ /**
+ * get available
+ */
+ public int available()
+ throws IOException {
+
+ return httpIn.available();
+ }
+
+ /**
+ * Disconnect this connection
+ */
+ public void disconnect() {
+ try {
+ s.close();
+ } catch (Exception e) {
+ //ignor ?
+ }
+ }
+
+ /**
+ * Set time out
+ */
+ public void setSoTimeout(int timeout) throws SocketException {
+ //System.out.println("JSSConnection: setSoTimeout() - "+timeout);
+ s.setSoTimeout(timeout);
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ private JFrame getFrame() {
+ if (UtilConsoleGlobals.getActivatedFrame() != null)
+ return UtilConsoleGlobals.getActivatedFrame();
+ return new JFrame();
+ }
+
+ private void initReadResponse()
+ throws IOException {
+
+ readHeader();
+ readBody();
+ }
+
+ private int readLineFromStream(InputStream is, byte line[],
+ int startpos, int len) throws IOException {
+ //return is.readLine(line, startpos, len);
+ int pos = startpos;
+ int count = 0;
+ while (len > 0)
+ {
+ int nRead = httpIn.read(line, pos, 1);
+ if (nRead == -1)
+ break;
+ count++;
+ if (line[pos] == '\n') {
+ break;
+ }
+ pos++;
+ }
+ return count > 0 ? count : -1;
+ }
+
+ private void readHeader() throws IOException
+ {
+ // Read the status line of response and parse for
+ // Errors.
+ byte[] headerLine = new byte[1096];
+ int nRead = readLineFromStream(httpIn, headerLine, 0, 1096);
+
+ //System.out.println("XXX read " + nRead);
+
+ if (requestFailed(new String(headerLine))) {
+ Debug.println("JSSConnection Debug: in readHeader requestFailed");
+ throw new IOException(getReasonPhrase(new String (headerLine)));
+ }
+
+ while (true) {
+ nRead = readLineFromStream(httpIn, headerLine, 0, 1096);
+ int available = httpIn.available();
+
+ //System.out.println("Available: " + available);
+
+ if (nRead == -1) {
+ System.out.println("Unexpected end of stream");
+ break;
+ }
+
+ processHeader(headerLine, nRead);
+
+ if (endOfHeader) {
+ //System.out.println("End of Header");
+ break;
+ } else {
+ //System.out.println("Header: " + new String(headerLine)
+ // + ", nRead: " + nRead);
+ }
+ }
+ }
+
+ private boolean endOfHeader(byte[] hdr, int available) {
+ if (available == 2) {
+ int c1 = (int)hdr[0];
+ int c2 = (int)hdr[1];
+
+ //System.out.println("C1= " + c1);
+ //System.out.println("C2= " + c2);
+
+ return true;
+ } else
+ return false;
+ }
+
+ private void readBody()
+ throws IOException {
+
+ body = new byte[bodyLen];
+ totalRead = 0;
+ while (totalRead < bodyLen) {
+ int nRead = httpIn.read(body, totalRead, bodyLen - totalRead);
+ totalRead += nRead;
+ }
+ }
+
+
+ private void processHeader(byte[] buf, int nRead)
+ {
+ if (endOfHeader(buf, nRead)) {
+ endOfHeader = true;
+ return;
+ }
+
+ String hdr = new String(buf, 0, nRead);
+ int index = 0;
+ if (hdr.toLowerCase().startsWith("content-length: ")) {
+ try {
+ String length = hdr.substring(hdr.indexOf(": ") + 1);
+ bodyLen = Integer.parseInt(length.trim());
+ return;
+ } catch (Exception e){e.printStackTrace(); }
+ }
+ }
+
+ private boolean requestFailed(String header) {
+ return (header.indexOf(Integer.toString(HTTP_OK_RESPONSE)) > 0) ? false: true;
+ }
+
+ private String getReasonPhrase(String header) {
+ String str1 = header.substring(header.indexOf(' ') +1);
+ return str1.substring(str1.indexOf(' ') +1);
+ }
+
+ class InitPasswordDialog extends AbstractDialog {
+ protected ResourceBundle mResource =
+ ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ SingleBytePasswordField pwd;
+ SingleBytePasswordField pwdAgain;
+ CryptoToken mToken;
+ boolean tokenPasswdInit = true;
+ boolean pwdSame = true;
+
+ public InitPasswordDialog(CryptoToken token) {
+ super(null,"",true, OK|CANCEL);
+ setMinimumSize(300, 150);
+ mToken = token;
+ setTitle(mResource.getString("SSLCLIENT_INITPASSWORD_DIALOG_TITLE"));
+ Container p = getContentPane();
+ p.setLayout(new GridBagLayout());
+
+ int y = 0;
+ pwd = new SingleBytePasswordField();
+ pwdAgain = new SingleBytePasswordField();
+ JLabel pwdLbl = new JLabel();
+ JLabel pwdAgainLbl = new JLabel();
+ pwdLbl.setText(mResource.getString("SSLCLIENT_INITPASSWORD_PWD_LABEL"));
+ pwdAgainLbl.setText(
+ mResource.getString("SSLCLIENT_INITPASSWORD_PWDAGAIN_LABEL"));
+ GridBagUtil.constrain(p, pwdLbl,
+ 0, y, 1, 1,
+ 0.0, 0.0,
+ GridBagConstraints.EAST, GridBagConstraints.NONE);
+ GridBagUtil.constrain(p, pwd,
+ 1, y, GridBagConstraints.REMAINDER, 1,
+ 1.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL);
+ GridBagUtil.constrain(p, pwdAgainLbl,
+ 0, ++y, 1, 1,
+ 0.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.NONE);
+ GridBagUtil.constrain(p, pwdAgain,
+ 1, y, GridBagConstraints.REMAINDER, 1,
+ 1.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL);
+/*
+ GridBagUtil.constrain(p, pwd,
+ 0, ++y, 1, 1,
+ 1.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ 0, 0, 0, 0);
+*/
+
+ pack();
+ }
+
+ protected void okInvoked() {
+ if (!pwd.getText().equals(pwdAgain.getText())) {
+ pwdSame = false;
+ dispose();
+ return;
+ }
+
+ try {
+ mToken.initPassword(null, getPassword());
+ dispose();
+ } catch (Exception e) {
+ tokenPasswdInit = false;
+ }
+ }
+
+ public boolean isPwdSame() {
+ return pwdSame;
+ }
+
+ public boolean isTokenInit() {
+ return tokenPasswdInit;
+ }
+
+ public void setVisible(boolean visible) {
+ pack();
+ pwd.grabFocus();
+ super.setVisible(visible);
+ }
+
+ public Password getPassword() {
+ Password jssPwd = new Password(pwd.getText().toCharArray());
+ return jssPwd;
+ }
+ }
+
+ class GetPasswordDialog extends AbstractDialog {
+
+ MultilineLabel enterPwdLabel = new MultilineLabel();
+ protected ResourceBundle mResource =
+ ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ SingleBytePasswordField pwd;
+ public GetPasswordDialog() {
+ super(null,"",true, OK|CANCEL);
+ setTitle(mResource.getString("SSLCLIENT_PASSWORD_DIALOG_TITLE"));
+ Container p = getContentPane();
+ p.setLayout(new GridBagLayout());
+
+ int y = 0;
+ GridBagUtil.constrain(p, enterPwdLabel,
+ 0, y, 1, 1,
+ 1.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ 0, 0, 0, 0);
+
+ pwd = new SingleBytePasswordField();
+ GridBagUtil.constrain(p, pwd,
+ 0, ++y, 1, 1,
+ 1.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ 0, 0, 0, 0);
+
+ pack();
+ }
+
+ public void setVisible(boolean visible) {
+ pack();
+ pwd.grabFocus();
+ super.setVisible(visible);
+ }
+
+ public void setPasswordInfo(PasswordCallbackInfo info, boolean getPwdAgain) {
+ if (getPwdAgain)
+ enterPwdLabel.setText(mResource.getString(
+ "SSLCLIENT_PASSWORDAGAIN_DIALOG_LABEL")+" "+info.getName()+":");
+ else
+ enterPwdLabel.setText(mResource.getString(
+ "SSLCLIENT_PASSWORD_DIALOG_LABEL")+" "+ info.getName()+":");
+ Debug.println(info.getName());
+ }
+
+ public Password getPassword() {
+ Password jssPwd = new Password(pwd.getText().toCharArray());
+ return jssPwd;
+ }
+ }
+
+
+ class SelectCertDialog extends AbstractDialog {
+
+ JComboBox certList = new JComboBox();
+ protected ResourceBundle mResource = ResourceBundle.getBundle(
+ CMSAdminResources.class.getName());
+ public SelectCertDialog() {
+ super(null,"", true, OK|CANCEL);
+ setTitle(mResource.getString("SSLCLIENT_CERTSELECT_DIALOG_TITLE"));
+
+ Container p = getContentPane();
+ p.setLayout(new GridBagLayout());
+
+ int y = 0;
+ GridBagUtil.constrain(p, new JLabel(
+ mResource.getString("SSLCLIENT_CERTSELECT_DIALOG_LABEL")),
+ 0, y, 1, 1,
+ 1.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ 0, 0, 0, 0);
+
+ GridBagUtil.constrain(p, certList,
+ 0, ++y, 1, 1,
+ 1.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ 0, 0, 0, 0);
+ pack();
+ }
+
+ public void setCertList(Vector nicknames) {
+ certList.removeAllItems();
+ Enumeration enum1 = nicknames.elements();
+ while (enum1.hasMoreElements()) {
+ certList.insertItemAt(enum1.nextElement(), 0);
+ }
+ try {
+ certList.setSelectedIndex(0);
+ } catch (Exception e) {
+ }
+ }
+
+ public String getSelectedCert() {
+ return certList.getSelectedItem().toString();
+ }
+
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/connection/PromptForTrustDialog.java b/base/console/src/com/netscape/admin/certsrv/connection/PromptForTrustDialog.java
new file mode 100644
index 000000000..868eccc1b
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/connection/PromptForTrustDialog.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.management.client.security;
+package com.netscape.admin.certsrv.connection;
+
+import com.netscape.management.nmclf.SuiConstants;
+import com.netscape.management.nmclf.SuiLookAndFeel;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.ug.*;
+
+import java.awt.event.*;
+import java.awt.*;
+import javax.swing.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.text.*;
+import java.security.cert.X509Certificate;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+
+import org.mozilla.jss.ssl.SSLCertificateApprovalCallback.ValidityStatus;
+
+/**
+ * Dialog box that prompts user to either accept or reject
+ * an untrusted certificate.
+ */
+public class PromptForTrustDialog extends AbstractDialog implements SuiConstants {
+
+ private static boolean certIsAccepted = false;
+ private static boolean acceptedForSingleSession = false;
+ private X509Certificate mCert;
+
+ private UserConfirmationActionListener buttonActionListener =
+ new UserConfirmationActionListener();
+ protected ResourceBundle mResource;
+ //static ResourceSet _resource = new ResourceSet("com.netscape.admin.certsrv.connection.ServerAuthResource");
+
+ CertViewDialog viewCertDialog;
+ //ViewCertificateDialog viewCertDialog;
+ JCheckBox oneSession;
+
+
+ /**
+ * create a dialog that prompt user to either accept or reject an untrusted certificate
+ * @param parent the owner of the dialog
+ * @param cert certificate chain
+ * @param certChain_errCode cert chain errors (0 if no errors)
+ * @param serverCert_errCode server cert errors (0 if no errors)
+ *
+ *
+ */
+ public PromptForTrustDialog(Frame parent, X509Certificate cert,
+ ValidityStatus status) {
+ super(parent, "", true);
+ mResource = ResourceBundle.getBundle(
+ CMSAdminResources.class.getName());
+ mCert = cert;
+
+ setTitle(mResource.getString("SSLCLIENT_TRUST_DIALOG_TITLE"));
+
+ getContentPane().setLayout(new GridBagLayout());
+
+
+ //Add action button pane first so the accept button will
+ //get default focus. Already try various way with *Focus() call
+ //none of them work.
+ GridBagUtil.constrain(getContentPane(), createActionButtons(),
+ 0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.SOUTHEAST,
+ GridBagConstraints.NONE, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(getContentPane(), siteAlert(), 0, 0, 1,
+ 1, 1.0, 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, VERT_WINDOW_INSET,
+ VERT_WINDOW_INSET, 0, 0);
+
+ //viewCertDialog = new ViewCertificateDialog(parent, cert, status);
+ viewCertDialog = new CertViewDialog((JFrame)parent);
+
+ setMinimumSize(400, 250);
+ if (parent == null) {
+ ModalDialogUtil.setCenteredDialog(this);
+ }
+ pack();
+ }
+
+
+ /**
+ * Handles all the action (Ok, Accept, Reject, and Help)
+ *
+ */
+ class UserConfirmationActionListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ if (e.getActionCommand().equals("ACCEPT")) {
+ certIsAccepted = true;
+ setVisible(false);
+ } else if (e.getActionCommand().equals("REJECT")) {
+ certIsAccepted = false;
+ setVisible(false);
+ } else if (e.getActionCommand().equals("VIEWCERT")) {
+ String certContent = getPrettyPrint(mCert);
+ viewCertDialog.showDialog("", certContent);
+ }
+ }
+ }
+
+ private final static String spaces =
+ " " +
+ " " +
+ " " +
+ " " +
+ " ";
+ private static final char[] hexdigits = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F'
+ };
+
+ private String indent(int size) {
+ return spaces.substring(0, size);
+ }
+
+ private String getPrettyPrint(X509Certificate cert) {
+ String subjectdn = cert.getSubjectDN().toString();
+ String issuerdn = cert.getIssuerDN().toString();
+ String serial = cert.getSerialNumber().toString();
+ SimpleDateFormat formatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy");
+ String before = formatter.format(cert.getNotBefore());
+ String after = formatter.format(cert.getNotAfter());
+ String fingerprint = getHexString(cert.getSignature(), 16, 16, ":");
+ String str = "Subject name: "+subjectdn+"\n"+
+ "Issuer name: "+issuerdn+"\n"+"Serial number: "+serial+"\n"+
+ "Validity: "+before+" to "+after+"\n"+"Signature:\n"+
+ fingerprint+"\n";
+ return str;
+ }
+
+ private String getHexString(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();
+ }
+
+ /**
+ * @return true if certificate is accepted
+ */
+ public boolean isCertAccepted() {
+ return certIsAccepted;
+ }
+
+ /**
+ * @return true certificate should only be accept for a single session
+ */
+ public boolean isAcceptedForOneSession() {
+ return oneSession.isSelected();
+ }
+
+
+ /**
+ * Allow reuse of this dialog, if it is not disposed.
+ * @param cert certificate chain
+ * @param certChain_errCode cert chain errors (0 if no errors)
+ * @param serverCert_errCode server cert errors (0 if no errors)
+ *
+ */
+ public void setCertificateInfo(X509Certificate cert,
+ ValidityStatus status) {
+ //viewCertDialog.setCertificate(cert, status);
+ }
+
+
+ /**
+ * Create a warning message panel
+ */
+ private JPanel siteAlert() {
+ JPanel notTrustedSiteWarning = new JPanel();
+ notTrustedSiteWarning.setLayout(new GridBagLayout());
+
+ JLabel warningImage = new JLabel(UIManager.getIcon("OptionPane.warningIcon"));
+ MultilineLabel warningMsg = new MultilineLabel(
+ mResource.getString("SSLCLIENT_TRUST_DIALOG_WARNMSG"));
+ oneSession = new JCheckBox(
+ mResource.getString("SSLCLIENT_TRUST_DIALOG_ACCEPTONESESSION"),
+ false);
+
+ GridBagUtil.constrain(notTrustedSiteWarning, warningImage, 0,
+ 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST,
+ GridBagConstraints.NONE, 0, 0, 0,
+ DIFFERENT_COMPONENT_SPACE);
+
+ GridBagUtil.constrain(notTrustedSiteWarning, warningMsg, 1, 0,
+ 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST,
+ GridBagConstraints.BOTH, 0, 0,
+ DIFFERENT_COMPONENT_SPACE, VERT_WINDOW_INSET);
+
+ GridBagUtil.constrain(notTrustedSiteWarning, oneSession, 1, 1,
+ 1, 1, 0.0, 0.0, GridBagConstraints.SOUTHWEST,
+ GridBagConstraints.NONE, 0, 0, 0, VERT_WINDOW_INSET);
+
+ GridBagUtil.constrain(notTrustedSiteWarning,
+ Box.createVerticalGlue(), 1, 2, 2, 1, 1.0, 1.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, 0, 0);
+ return notTrustedSiteWarning;
+ }
+
+ JButton accept;
+ public void setVisible(boolean visible) {
+ if (visible) {
+ accept.grabFocus();
+ setDefaultButton(accept);
+ }
+ super.setVisible(visible);
+ }
+
+ /**
+ * create all the action buttons (Accept, Reject, View Certificate, and Help)
+ */
+ private JPanel createActionButtons() {
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.setLayout(new GridBagLayout());
+
+ accept = JButtonFactory.create(
+ mResource.getString("SSLCLIENT_TRUST_DIALOG_ACCEPT"),
+ buttonActionListener, "ACCEPT");
+ accept.registerKeyboardAction(buttonActionListener, "ACCEPT",
+ KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
+ JComponent.WHEN_IN_FOCUSED_WINDOW);
+
+ JButton reject = JButtonFactory.create(
+ mResource.getString("SSLCLIENT_TRUST_DIALOG_REJECT"),
+ buttonActionListener, "REJECT");
+ reject.registerKeyboardAction(buttonActionListener, "REJECT",
+ KeyStroke.getKeyStroke(KeyEvent.VK_R, 0),
+ JComponent.WHEN_IN_FOCUSED_WINDOW);
+
+ JButton viewCert = JButtonFactory.create(
+ mResource.getString("SSLCLIENT_TRUST_DIALOG_VIEWCERT"), buttonActionListener, "VIEWCERT");
+ viewCert.registerKeyboardAction(buttonActionListener, "VIEWCERT",
+ KeyStroke.getKeyStroke(KeyEvent.VK_V, 0),
+ JComponent.WHEN_IN_FOCUSED_WINDOW);
+ JButtonFactory.resizeGroup(accept, reject);
+
+ int x = 0;
+ GridBagUtil.constrain(buttonPanel, accept, x, 0, 1, 1, 0.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, DIFFERENT_COMPONENT_SPACE, 0,
+ 0, COMPONENT_SPACE);
+
+ GridBagUtil.constrain(buttonPanel, reject, ++x, 0, 1, 1, 0.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, DIFFERENT_COMPONENT_SPACE, 0,
+ 0, COMPONENT_SPACE);
+
+ GridBagUtil.constrain(buttonPanel, viewCert, ++x, 0, 1, 1, 0.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, DIFFERENT_COMPONENT_SPACE, 0,
+ 0, DIFFERENT_COMPONENT_SPACE);
+
+ return buttonPanel;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/connection/Request.java b/base/console/src/com/netscape/admin/certsrv/connection/Request.java
new file mode 100644
index 000000000..8ed61e998
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/connection/Request.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.admin.certsrv.connection;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * A class represents a connection to certificate server.
+ *
+ * @author thomask
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class Request {
+
+ private String mPrefix = null;
+
+ //internal structure is changed to vector to maintain
+ //the ordering
+
+ private Vector mName = new Vector();
+ private Vector mValue = new Vector();
+
+ public Request(String prefix) {
+ mPrefix = prefix;
+ }
+
+ public String getPrefix() {
+ return mPrefix;
+ }
+
+ public void set(String name, String value) {
+ mName.addElement(name);
+ mValue.addElement(value);
+ }
+
+ public String get(String name) {
+ int i = mName.indexOf(name);
+ try {
+ return (String) mValue.elementAt(i);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ return "";
+ }
+ }
+
+ public Enumeration getElements() {
+ return mName.elements();
+ }
+
+ public void removeAll() {
+ mName.removeAllElements();
+ mValue.removeAllElements();
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/connection/Response.java b/base/console/src/com/netscape/admin/certsrv/connection/Response.java
new file mode 100644
index 000000000..bbb511443
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/connection/Response.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.admin.certsrv.connection;
+
+import java.net.*;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Response - now use vector to maintain the oredering
+ *
+ * @author kanda
+ * @author thomask
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class Response {
+ boolean debug = true;
+ boolean test = true;
+ boolean testsuccess = true; // test success condition?
+
+ public static final int SUCCESS = 0;
+ public static final int RESTART = -1;
+
+ private int mRetcode;
+ private String mErrorMsg;
+
+ //internal structure is changed to vector to maintain
+ //the ordering
+
+ private Vector mName = new Vector();
+ private Vector mValue = new Vector();
+
+ public Response() {
+ // for testing only
+
+ }
+
+ public Response(byte[] resp) throws IOException {
+ ByteArrayInputStream bis = new ByteArrayInputStream(resp);
+ DataInputStream dis = new DataInputStream(bis);
+ mRetcode = dis.readInt();
+ byte[] mContents = null;
+
+ if (debug)
+ //System.out.println("===in Response===\n");
+
+ if ((mRetcode != SUCCESS) && (mRetcode != RESTART)) {
+ mErrorMsg = dis.readUTF();
+ } else {
+ if (resp.length > 4) {
+ mContents = new byte[resp.length - 4];
+ dis.read(mContents);
+ }
+ }
+ if (mContents != null) {
+ String resultStr = new String(mContents);
+ StringTokenizer st = new StringTokenizer(resultStr,
+ "&");
+ while (st.hasMoreTokens()) {
+ String p = st.nextToken();
+ int i = p.indexOf("=");
+ if (i == -1) {
+ return;
+ }
+ String t = URLdecode(p.substring(0, i));
+ String v = URLdecode(p.substring(i + 1));
+ mName.addElement(t);
+ mValue.addElement(v);
+ }
+ }
+ }
+
+ public int getReturnCode() {
+ return mRetcode;
+ }
+
+ public String getErrorMessage() {
+ return mErrorMsg;
+ }
+
+ /**
+ * URL decodes the given string.
+ */
+ public 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();
+ }
+
+ public Enumeration getNames() {
+ return mName.elements();
+ }
+
+ public String get(String name) {
+ int i = mName.indexOf(name);
+ String value;
+ try {
+ value = (String) mValue.elementAt(i);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ value = "";
+ }
+ return value;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/connection/SSLConnectionFactory.java b/base/console/src/com/netscape/admin/certsrv/connection/SSLConnectionFactory.java
new file mode 100644
index 000000000..7c74a239d
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/connection/SSLConnectionFactory.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.admin.certsrv.connection;
+
+import java.net.*;
+import java.io.*;
+
+/**
+ * SSLConnectionFactory - factory method for creating supported SSL
+ * Connection type: SSLAVA_CONNECTION, SSL_CONNECTION. DEFAULT connection
+ * SSLAVA_CONNECTION will be used if type specified is incorrect.
+ *
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.certsrv.client.connection
+ */
+public class SSLConnectionFactory implements IConnectionFactory {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String JSS_CONNECTION = "JSS";
+ public static final String SSL_CONNECTION = "SSL";
+
+ private String mType;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ /**
+ * Construct a specific SSL connection factory object
+ *
+ * DEFAULT connection SSLAVA_CONNECTION will be used if
+ * type specified is incorrect.
+ *
+ * @param type supported SSL connection type:
+ * SSLAVA_CONNECTION, SSL_CONNECTION
+ */
+ public SSLConnectionFactory(String type) {
+ if ((!type.equals(JSS_CONNECTION))&&(!type.equals(SSL_CONNECTION)) ) {
+ System.out.println("SSL Connection Type not found default is used");
+ mType = JSS_CONNECTION;
+ } else {
+ mType = type;
+ }
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Creates connection using the host and port
+ */
+ public IConnection create(String host, int port)
+ throws IOException, UnknownHostException {
+
+ if (mType.equals(JSS_CONNECTION))
+ return new JSSConnection(host, port);
+ return new JSSConnection(host, port);
+ //return new SSLConnection(host, port);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/images/CertificateServer.gif b/base/console/src/com/netscape/admin/certsrv/images/CertificateServer.gif
new file mode 100644
index 000000000..ed84e0540
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/CertificateServer.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/CertificateServerL.gif b/base/console/src/com/netscape/admin/certsrv/images/CertificateServerL.gif
new file mode 100644
index 000000000..99e27663a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/CertificateServerL.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/LOGobjs.gif b/base/console/src/com/netscape/admin/certsrv/images/LOGobjs.gif
new file mode 100644
index 000000000..05fab2ad7
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/LOGobjs.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/UGobjs.gif b/base/console/src/com/netscape/admin/certsrv/images/UGobjs.gif
new file mode 100644
index 000000000..7f5ff1ee2
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/UGobjs.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/acl.gif b/base/console/src/com/netscape/admin/certsrv/images/acl.gif
new file mode 100644
index 000000000..8c706b81c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/acl.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/aclobj.gif b/base/console/src/com/netscape/admin/certsrv/images/aclobj.gif
new file mode 100644
index 000000000..95eb0e93b
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/aclobj.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/aclplugin.gif b/base/console/src/com/netscape/admin/certsrv/images/aclplugin.gif
new file mode 100644
index 000000000..61b75df0e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/aclplugin.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/alertl.gif b/base/console/src/com/netscape/admin/certsrv/images/alertl.gif
new file mode 100644
index 000000000..453d1b2bd
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/alertl.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/allfolder16n.gif b/base/console/src/com/netscape/admin/certsrv/images/allfolder16n.gif
new file mode 100644
index 000000000..50bb5c4d0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/allfolder16n.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/allgroup16n.gif b/base/console/src/com/netscape/admin/certsrv/images/allgroup16n.gif
new file mode 100644
index 000000000..45a69a7be
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/allgroup16n.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/alllogdoc16n.gif b/base/console/src/com/netscape/admin/certsrv/images/alllogdoc16n.gif
new file mode 100644
index 000000000..e517db51c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/alllogdoc16n.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/alllogfolder16n.gif b/base/console/src/com/netscape/admin/certsrv/images/alllogfolder16n.gif
new file mode 100644
index 000000000..14453609e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/alllogfolder16n.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/alluser16n.gif b/base/console/src/com/netscape/admin/certsrv/images/alluser16n.gif
new file mode 100644
index 000000000..d37b766f5
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/alluser16n.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/alluserwithcert16n.gif b/base/console/src/com/netscape/admin/certsrv/images/alluserwithcert16n.gif
new file mode 100644
index 000000000..69b0da381
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/alluserwithcert16n.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/auth.gif b/base/console/src/com/netscape/admin/certsrv/images/auth.gif
new file mode 100644
index 000000000..6ede96ae2
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/auth.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/authobj.gif b/base/console/src/com/netscape/admin/certsrv/images/authobj.gif
new file mode 100644
index 000000000..26f58c19c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/authobj.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/authplugin.gif b/base/console/src/com/netscape/admin/certsrv/images/authplugin.gif
new file mode 100644
index 000000000..b1015ad97
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/authplugin.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/cert24.gif b/base/console/src/com/netscape/admin/certsrv/images/cert24.gif
new file mode 100644
index 000000000..99e27663a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/cert24.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/cert41.gif b/base/console/src/com/netscape/admin/certsrv/images/cert41.gif
new file mode 100644
index 000000000..c33d7cfa0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/cert41.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/cert42.gif b/base/console/src/com/netscape/admin/certsrv/images/cert42.gif
new file mode 100644
index 000000000..23f38b9d5
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/cert42.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/cms-branding.gif b/base/console/src/com/netscape/admin/certsrv/images/cms-branding.gif
new file mode 100644
index 000000000..b696929e5
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/cms-branding.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/error.gif b/base/console/src/com/netscape/admin/certsrv/images/error.gif
new file mode 100644
index 000000000..ba9c07e17
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/error.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/genobject.gif b/base/console/src/com/netscape/admin/certsrv/images/genobject.gif
new file mode 100644
index 000000000..93f9ab123
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/genobject.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/jobobj.gif b/base/console/src/com/netscape/admin/certsrv/images/jobobj.gif
new file mode 100644
index 000000000..95eb0e93b
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/jobobj.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/jobplugin.gif b/base/console/src/com/netscape/admin/certsrv/images/jobplugin.gif
new file mode 100644
index 000000000..61b75df0e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/jobplugin.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/jobs.gif b/base/console/src/com/netscape/admin/certsrv/images/jobs.gif
new file mode 100644
index 000000000..8c706b81c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/jobs.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/ldapub.gif b/base/console/src/com/netscape/admin/certsrv/images/ldapub.gif
new file mode 100644
index 000000000..c709d2b62
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/ldapub.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/messagel.gif b/base/console/src/com/netscape/admin/certsrv/images/messagel.gif
new file mode 100644
index 000000000..e46c67a09
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/messagel.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/notsecure.gif b/base/console/src/com/netscape/admin/certsrv/images/notsecure.gif
new file mode 100644
index 000000000..4c52ba9d9
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/notsecure.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/plug.gif b/base/console/src/com/netscape/admin/certsrv/images/plug.gif
new file mode 100644
index 000000000..83a230d4d
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/plug.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/plugin.gif b/base/console/src/com/netscape/admin/certsrv/images/plugin.gif
new file mode 100644
index 000000000..a12b2cd0e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/plugin.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/pluginfolder.gif b/base/console/src/com/netscape/admin/certsrv/images/pluginfolder.gif
new file mode 100644
index 000000000..3499e9077
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/pluginfolder.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/red-ball-small.gif b/base/console/src/com/netscape/admin/certsrv/images/red-ball-small.gif
new file mode 100644
index 000000000..f6b3c372c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/red-ball-small.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/rule-16.gif b/base/console/src/com/netscape/admin/certsrv/images/rule-16.gif
new file mode 100644
index 000000000..bbaa218f5
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/rule-16.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/ruleDisable-16.gif b/base/console/src/com/netscape/admin/certsrv/images/ruleDisable-16.gif
new file mode 100644
index 000000000..c54f5e6bb
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/ruleDisable-16.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/ruleplugin-16.gif b/base/console/src/com/netscape/admin/certsrv/images/ruleplugin-16.gif
new file mode 100644
index 000000000..aa3ba590b
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/ruleplugin-16.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/rulesobj.gif b/base/console/src/com/netscape/admin/certsrv/images/rulesobj.gif
new file mode 100644
index 000000000..bdbf3b80c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/rulesobj.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/secure.gif b/base/console/src/com/netscape/admin/certsrv/images/secure.gif
new file mode 100644
index 000000000..352ad2f82
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/secure.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/servlet-16.gif b/base/console/src/com/netscape/admin/certsrv/images/servlet-16.gif
new file mode 100644
index 000000000..6274a8006
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/servlet-16.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/servlet-plugin-16.gif b/base/console/src/com/netscape/admin/certsrv/images/servlet-plugin-16.gif
new file mode 100644
index 000000000..8ebbdad58
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/servlet-plugin-16.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/images/servletobj.gif b/base/console/src/com/netscape/admin/certsrv/images/servletobj.gif
new file mode 100644
index 000000000..9b83ac34d
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/images/servletobj.gif
Binary files differ
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/CertSetupWizard.java b/base/console/src/com/netscape/admin/certsrv/keycert/CertSetupWizard.java
new file mode 100644
index 000000000..f7650decb
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/CertSetupWizard.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.wizard.*;
+
+/**
+ * Wizard for Key and Certificate management
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+
+public class CertSetupWizard extends WizardWidget {
+
+ public CertSetupWizard(CMSBaseResourceModel parent, CertSetupWizardInfo info) {
+ super(parent.getFrame());
+ JFrame frame = parent.getFrame();
+ info.addEntry(info.FRAME, frame);
+ info.addEntry(info.SERVERINFO, parent.getServerInfo());
+ setWizardInfo(info);
+ addPage(new WIntroPage(this, frame));
+// addPage(new WTokenSelectionPage());
+ addPage(new WOperationSelectionPage(this, frame));
+// addPage(new WGenerateReqPage(this));
+ addPage(new WCertTypePage(this, frame));
+ //addPage(new WServerCertSubmitPage(this, frame));
+// addPage(new WCACertRequest1Page());
+// addPage(new WOtherCertRequest1Page());
+// addPage(new WCAKeyPage());
+ addPage(new WKeyPage(this, frame));
+ addPage(new WTokenLogonPage(this, frame));
+ addPage(new WCertMessageDigestPage(this, frame));
+// addPage(new WWarningPage());
+ addPage(new WCertDNPage(this, frame));
+ addPage(new WCertValidityPage(this, frame));
+// addPage(new WCertDNValidityPage());
+// addPage(new WWarningExecute1Page());
+ addPage(new WCertExtensionPage(this, frame));
+ addPage(new WExecute1Page(this, frame));
+// addPage(new WRAKeyPage());
+// addPage(new WSSLKeyPage());
+// addPage(new WWarningExecutePage());
+ addPage(new WExecutePage(this, frame));
+ addPage(new WIssueImportStatusPage(this, frame));
+ addPage(new WManualCertRequestPage(this, frame));
+ addPage(new WRequestStatusPage(this, frame));
+// addPage(new WIntroInstallCertPage());
+ addPage(new WInstallOpPage(this, frame));
+ addPage(new WInstallCertChainPage(this, frame));
+ addPage(new WPasteCertPage(this, frame));
+ addPage(new WDisplayCertPage(this, frame));
+ addPage(new WInstallStatusPage(this, frame));
+ show();
+ }
+
+ protected void callHelp() {
+ if (mCurrent instanceof IWizardPanel) {
+ ((IWizardPanel)mCurrent).callHelp();
+ }
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/CertSetupWizardInfo.java b/base/console/src/com/netscape/admin/certsrv/keycert/CertSetupWizardInfo.java
new file mode 100644
index 000000000..81ffc2d0e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/CertSetupWizardInfo.java
@@ -0,0 +1,412 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.keycert;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * WizardInfo for certificate setup wizard
+ * Once complete, we need to zap this object.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+public class CertSetupWizardInfo extends WizardInfo {
+
+ private AdminConnection mConnection;
+ private ConsoleInfo mConsoleInfo;
+ public static final String FRAME = "frame";
+ public static final String SERVERINFO = "serverInfo";
+ public static final String TOKENNAME = "tokenName";
+ public static final String DBPASSWD = "dbPasswd";
+ public static final String OPTYPE = "operationType";
+ public static final String INSTALLTYPE = "install";
+ public static final String REQUESTTYPE = "request";
+// public static final String CA_SIGNING_CERT = "caSigningCert";
+ // public static final String RA_SIGNING_CERT = " raSigningCert";
+ // public static final String KRA_TRANSPORT_CERT = "kraTransportCert";
+ // public static final String SSL_SERVER_CERT = "sslServerCert";
+ public static final String SERVER_CERT_CHAIN = "serverCertChain";
+ public static final String TRUSTED_CA_CERT = "trustedCACert";
+ public static final String TRUSTED_CERT = "trustedCert";
+// public static final String SERVER_CERT = "serverCert";
+ public static final String SELF_SIGNED = "selfSigned";
+ public static final String SUBORDINATE_CA = "subordinateCA";
+ public static final String CA_EMAIL = "caEmail";
+ public static final String CA_URL = "caUrl";
+ public static final String MANUAL = "manual";
+ public static final String SUBMIT_METHOD = "reqSubmitMethod";
+ public static final String KEY_MATERIAL = "keyMaterial";
+ public static final String CA_TYPE = "caType";
+ public static final String DERVALUE = "derValue";
+ public static final String INSTALLCERTTYPE = "installCertType";
+ public static final String ALL_INFO = "allInfo";
+ public static final String BEGIN_YEAR = "beginYear";
+ public static final String BEGIN_MONTH = "beginMonth";
+ public static final String BEGIN_DATE = "beginDate";
+ public static final String BEGIN_HOUR = "beginHour";
+ public static final String BEGIN_MIN = "beginMin";
+ public static final String BEGIN_SEC = "beginSec";
+ public static final String AFTER_YEAR = "afterYear";
+ public static final String AFTER_MONTH = "afterMonth";
+ public static final String AFTER_DATE = "afterDate";
+ public static final String AFTER_HOUR = "afterHour";
+ public static final String AFTER_MIN = "afterMin";
+ public static final String AFTER_SEC = "afterSec";
+ public static final String NICKNAME = "nickname";
+ public static final String CERT_CONTENT = "certContent";
+
+ public CertSetupWizardInfo(AdminConnection conn, ConsoleInfo info) {
+ super();
+ mConnection = conn;
+ mConsoleInfo = info;
+ }
+
+ public JFrame getFrame() {
+ return (JFrame)get(FRAME);
+ }
+
+ public CMSServerInfo getServerInfo() {
+ return (CMSServerInfo)get(SERVERINFO);
+ }
+
+ public AdminConnection getAdminConnection() {
+ return mConnection;
+ }
+
+ public ConsoleInfo getAdminConsoleInfo() {
+ return mConsoleInfo;
+ }
+
+ // if mode = 0, then it is in root cert mode.
+ // if mode = 1, then it is in user cert mode.
+ public void setMode(String mode) {
+ put("mode", mode);
+ }
+
+ public String getMode() {
+ return (String)get("mode");
+ }
+
+ public String getCertType() {
+ return (String)get(Constants.PR_CERTIFICATE_TYPE);
+ }
+
+ public void setCertType(String certType) {
+ put(Constants.PR_CERTIFICATE_TYPE, certType);
+ }
+
+ public String getSubmitMethod() {
+ return (String)get(SUBMIT_METHOD);
+ }
+
+ public String getCAType() {
+ return (String)get(CA_TYPE);
+ }
+
+ public boolean isNewKey() {
+ String isNew = (String)get(KEY_MATERIAL);
+ if (isNew != null && isNew.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ public String getOperationType() {
+ String opType = (String)get(OPTYPE);
+ return opType;
+ }
+
+ public boolean isSSLCertLocalCA() {
+ String val = (String)get(ConfigConstants.PR_SSLCERT_LOCALCA);
+ if (val == null)
+ return false;
+ else if (val.equals(Constants.TRUE))
+ return true;
+ return false;
+ }
+
+ // set true or false
+ public void setSSLCertLocalCA(String val) {
+ put(ConfigConstants.PR_SSLCERT_LOCALCA, val);
+ }
+
+ public byte[] getDERValue() {
+ byte[] derValue = (byte[])get(DERVALUE);
+ return derValue;
+ }
+
+ public String getTokenName() {
+ return (String)get(TOKENNAME);
+ }
+
+ public String getKeyLength() {
+ return (String)get(Constants.PR_KEY_LENGTH);
+ }
+
+ public String getKeyCurveName() {
+ return (String)get(Constants.PR_KEY_CURVENAME);
+ }
+
+ public String getKeyType() {
+ return (String)get(Constants.PR_KEY_TYPE);
+ }
+
+ public String getSubjectName() {
+ return (String)get(Constants.PR_SUBJECT_NAME);
+ }
+
+ public void setSubjectName(String str) {
+ put(Constants.PR_SUBJECT_NAME, str);
+ }
+
+ public String getCSR() {
+ return (String)get(Constants.PR_CSR);
+ }
+
+ public String getPKCS10() {
+ String val = (String)get(Constants.PR_PKCS10);
+ if (val != null && !val.equals(""))
+ return val;
+ return null;
+ }
+
+ public void setPKCS10(String b64E) {
+ put(Constants.PR_PKCS10, b64E);
+ }
+
+ public String getCertFilePath() {
+ String val = (String)get(Constants.PR_CERT_FILEPATH);
+ if (val != null && !val.equals(""))
+ return val;
+ return null;
+ }
+
+ public void setCertFilePath(String path) {
+ put(Constants.PR_CERT_FILEPATH, path);
+ }
+
+ public String getCertSubjectName() {
+ return (String)get(Constants.PR_CERT_SUBJECT_NAME);
+ }
+
+ public String getIssuerName() {
+ return (String)get(Constants.PR_ISSUER_NAME);
+ }
+
+ public String getSerialNumber() {
+ return (String)get(Constants.PR_SERIAL_NUMBER);
+ }
+
+ public String getNotBefore() {
+ return (String)get(Constants.PR_BEFORE_VALIDDATE);
+ }
+
+ public String getNotAfter() {
+ return (String)get(Constants.PR_AFTER_VALIDDATE);
+ }
+
+ public String getInstallCertType() {
+ return (String)get(INSTALLCERTTYPE);
+ }
+
+ public String getValidityPeriod() {
+ return (String)get(Constants.PR_VALIDITY_PERIOD);
+ }
+
+ public String getTokenList() {
+ return (String)get(Constants.PR_TOKEN_LIST);
+ }
+
+ public Boolean isCertAdded() {
+ return (Boolean)get(Constants.PR_ADD_CERT);
+ }
+
+ public NameValuePairs getNameValuePairs() {
+ return (NameValuePairs)get(ALL_INFO);
+ }
+
+ public String getBeginYear() {
+ return (String)get(Constants.PR_BEGIN_YEAR);
+ }
+
+ public String getBeginMonth() {
+ return (String)get(Constants.PR_BEGIN_MONTH);
+ }
+
+ public String getBeginDate() {
+ return (String)get(Constants.PR_BEGIN_DATE);
+ }
+
+ public String getBeginHour() {
+ return (String)get(Constants.PR_BEGIN_HOUR);
+ }
+
+ public String getBeginMin() {
+ return (String)get(Constants.PR_BEGIN_MIN);
+ }
+
+ public String getBeginSec() {
+ return (String)get(Constants.PR_BEGIN_SEC);
+ }
+
+ public String getAfterYear() {
+ return (String)get(Constants.PR_AFTER_YEAR);
+ }
+
+ public String getAfterMonth() {
+ return (String)get(Constants.PR_AFTER_MONTH);
+ }
+
+ public String getAfterDate() {
+ return (String)get(Constants.PR_AFTER_DATE);
+ }
+
+ public String getAfterHour() {
+ return (String)get(Constants.PR_AFTER_HOUR);
+ }
+
+ public String getAfterMin() {
+ return (String)get(Constants.PR_AFTER_MIN);
+ }
+
+ public String getAfterSec() {
+ return (String)get(Constants.PR_AFTER_SEC);
+ }
+
+ public String getNickname() {
+ return (String)get(Constants.PR_NICKNAME);
+ }
+
+ public String getCertContent() {
+ return (String)get(Constants.PR_CERT_CONTENT);
+ }
+
+ public String getHashType() {
+ return (String)get(ConfigConstants.PR_HASH_TYPE);
+ }
+
+ public void setHashType(String type) {
+ put(ConfigConstants.PR_HASH_TYPE, type);
+ }
+
+ public String getSignedByType() {
+ return (String)get(ConfigConstants.PR_SIGNEDBY_TYPE);
+ }
+
+ public void setSignedByType(String type) {
+ put(ConfigConstants.PR_SIGNEDBY_TYPE, type);
+ }
+
+
+ public boolean isLoggedIn() {
+ String value = (String)get(Constants.PR_LOGGED_IN);
+ if (value != null && value.equals(Constants.FALSE))
+ return false;
+ return true;
+ }
+
+ public String getCertRequestDir() {
+ return (String)get(Constants.PR_CERT_REQUEST_DIR);
+ }
+
+ public void setCMHost(String host) {
+ put(ConfigConstants.CA_HOST, host);
+ }
+
+ public String getCMHost() {
+ return (String)get(ConfigConstants.CA_HOST);
+ }
+
+ public void setCMEEPort(String port) {
+ put(ConfigConstants.CA_EEPORT, port);
+ }
+
+ public String getCMEEPort() {
+ return (String)get(ConfigConstants.CA_EEPORT);
+ }
+
+ public void setCMEEType(String type) {
+ put(ConfigConstants.CA_EETYPE, type);
+ }
+
+ public String getCMEEType() {
+ return (String)get(ConfigConstants.CA_EETYPE);
+ }
+
+ public void setRequestStatus(String requestStatus) {
+ put(getCertType()+ConfigConstants.PR_CERT_REQUEST+"Status", requestStatus);
+ }
+
+ public String getRequestStatus() {
+ return (String)get(getCertType()+ConfigConstants.PR_CERT_REQUEST+"Status");
+ }
+
+ public void setRequestID(String requestID) {
+ put(getCertType()+ConfigConstants.PR_CERT_REQUEST, requestID);
+ }
+
+ public String getRequestID() {
+ return (String)get(getCertType()+ConfigConstants.PR_CERT_REQUEST);
+ }
+
+ public void setRequestSent(boolean sent) {
+ if (sent)
+ put(getCertType()+"Sent", ConfigConstants.TRUE);
+ else
+ put(getCertType()+"Sent", ConfigConstants.FALSE);
+ }
+
+ public boolean requestSent() {
+ String str = (String)get(getCertType()+"Sent");
+ if (str == null || str.equals(ConfigConstants.FALSE))
+ return false;
+ return true;
+ }
+
+ public void setRequestError(String error) {
+ put(getCertType()+"Error", error);
+ }
+
+ public String getRequestError() {
+ return (String)get(getCertType()+"Error");
+ }
+
+ public void setCertSubType(String str) {
+ put(Constants.PR_CERTIFICATE_SUBTYPE, str);
+ }
+
+ public String getCertSubType() {
+ return (String)get(Constants.PR_CERTIFICATE_SUBTYPE);
+ }
+
+ public void setNicknames(String str) {
+ put(Constants.PR_ALL_NICKNAMES, str);
+ }
+
+ public String getNicknames() {
+ return (String)get(Constants.PR_ALL_NICKNAMES);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WCACertRequest1Page.java b/base/console/src/com/netscape/admin/certsrv/keycert/WCACertRequest1Page.java
new file mode 100644
index 000000000..fe5ebd2d7
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WCACertRequest1Page.java
@@ -0,0 +1,237 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.keycert;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Certificate Request from certificate setup wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WCACertRequest1Page extends WizardBasePanel implements IWizardPanel {
+ private JTextArea mMethodText;
+ private JRadioButton mCABtn;
+ private JRadioButton mSubBtn;
+ private JRadioButton mExistingKeyBtn;
+ private JRadioButton mNewKeyBtn;
+ private JRadioButton mEmailBtn;
+ private JRadioButton mURLBtn;
+ private JRadioButton mManualBtn;
+ private Color mActiveColor;
+ private static final String PANELNAME = "CACERTREQUESTWIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WCACertRequest1Page() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ if (wizardInfo.getOperationType().equals(wizardInfo.INSTALLTYPE))
+ return false;
+
+ if (wizardInfo.getCertType().equals(Constants.PR_CA_SIGNING_CERT))
+ return true;
+
+ return false;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JLabel caLbl = makeJLabel("CATYPE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(caLbl, gbc);
+
+ mCABtn = makeJRadioButton("SELFSIGN", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0,4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mCABtn, gbc);
+
+ mSubBtn = makeJRadioButton("SUBORDINATE", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0,4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mSubBtn, gbc);
+
+ ButtonGroup caGroup = new ButtonGroup();
+ caGroup.add(mCABtn);
+ caGroup.add(mSubBtn);
+
+ JLabel keyLbl = makeJLabel("KEYPAIR");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(keyLbl, gbc);
+
+ mExistingKeyBtn = makeJRadioButton("OLDKEY", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mExistingKeyBtn, gbc);
+
+ mNewKeyBtn = makeJRadioButton("NEWKEY", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mNewKeyBtn, gbc);
+
+ ButtonGroup keyGroup = new ButtonGroup();
+ keyGroup.add(mExistingKeyBtn);
+ keyGroup.add(mNewKeyBtn);
+
+ mMethodText = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "CACERTREQUESTWIZARD_TEXT_METHOD_LABEL"), 100), 1, 100);
+ mActiveColor = mMethodText.getBackground();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mMethodText, gbc);
+
+ mEmailBtn = makeJRadioButton("EMAIL", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mEmailBtn, gbc);
+
+ mURLBtn = makeJRadioButton("URL", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mURLBtn, gbc);
+
+ mManualBtn = makeJRadioButton("MANUAL", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(mManualBtn, gbc);
+
+ ButtonGroup methodGroup = new ButtonGroup();
+ methodGroup.add(mEmailBtn);
+ methodGroup.add(mURLBtn);
+ methodGroup.add(mManualBtn);
+
+ enableFields(false, getBackground());
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+
+ if (mCABtn.isSelected())
+ wizardInfo.addEntry(wizardInfo.CA_TYPE, wizardInfo.SELF_SIGNED);
+ else if (mSubBtn.isSelected())
+ wizardInfo.addEntry(wizardInfo.CA_TYPE, wizardInfo.SUBORDINATE_CA);
+
+ if (mNewKeyBtn.isSelected())
+ wizardInfo.addEntry(wizardInfo.KEY_MATERIAL, Constants.TRUE);
+ else if (mExistingKeyBtn.isSelected())
+ wizardInfo.addEntry(wizardInfo.KEY_MATERIAL, Constants.FALSE);
+
+ if (mEmailBtn.isSelected())
+ wizardInfo.addEntry(wizardInfo.SUBMIT_METHOD, wizardInfo.CA_EMAIL);
+ else if (mURLBtn.isSelected())
+ wizardInfo.addEntry(wizardInfo.SUBMIT_METHOD, wizardInfo.CA_URL);
+ else if (mManualBtn.isSelected())
+ wizardInfo.addEntry(wizardInfo.SUBMIT_METHOD, wizardInfo.MANUAL);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mCABtn))
+ if (mCABtn.isSelected())
+ enableFields(false, getBackground());
+ else
+ enableFields(true, mActiveColor);
+ else if (e.getSource().equals(mSubBtn))
+ if (mSubBtn.isSelected())
+ enableFields(true, mActiveColor);
+ else
+ enableFields(false, getBackground());
+ }
+
+ private void enableFields(boolean enable, Color color) {
+ mMethodText.setEnabled(enable);
+ mEmailBtn.setEnabled(enable);
+ mURLBtn.setEnabled(enable);
+ mManualBtn.setEnabled(enable);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WCAKeyPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WCAKeyPage.java
new file mode 100644
index 000000000..fe06a6313
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WCAKeyPage.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * Setup CA signing cert for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WCAKeyPage extends WBaseKeyPage implements IWizardPanel {
+ private static final String PANELNAME = "CAKEYWIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WCAKeyPage() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ if (wizardInfo.getOperationType().equals(wizardInfo.INSTALLTYPE))
+ // (wizardInfo.isNewKey()))
+ return false;
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+/*
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ AdminConnection connection = wizardInfo.getAdminConnection();
+ NameValuePairs nvps = new NameValuePairs();
+
+ nvps.add(Constants.PR_TOKEN_NAME, wizardInfo.getTokenName());
+ nvps.add(Constants.PR_KEY_LENGTH, (String)mKeyLengthBox.getSelectedItem());
+ nvps.add(Constants.PR_KEY_TYPE, (String)mKeyTypeBox.getSelectedItem());
+
+ try {
+ NameValuePairs response = connection.process(
+ DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_CA_SIGNINGCERT,
+ Constants.PR_CERT_REQUEST, nvps);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ return false;
+ }
+*/
+
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ super.init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ wizardInfo.addEntry(Constants.PR_KEY_LENGTH,
+ (String)mKeyLengthBox.getSelectedItem());
+ wizardInfo.addEntry(Constants.PR_KEY_TYPE,
+ (String)mKeyTypeBox.getSelectedItem());
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WCertDNPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WCertDNPage.java
new file mode 100644
index 000000000..1c2268bb2
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WCertDNPage.java
@@ -0,0 +1,196 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.keycert;
+
+import javax.swing.*;
+import javax.swing.border.*;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * CA signing cert for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WCertDNPage extends WBaseDNPage implements IWizardPanel {
+ private static final String PANELNAME = "CERTDNWIZARD";
+ private static final String HELPINDEX =
+ "configuration-keycert-wizard-subjectdn-help";
+
+ private String certType = "";
+
+ WCertDNPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WCertDNPage(JDialog parent, JFrame frame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = frame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_SUBJECT_NAME, wizardInfo.getSubjectName());
+ wizardInfo.addEntry(wizardInfo.ALL_INFO, nvps);
+
+ if (wizardInfo.getOperationType().equals(wizardInfo.INSTALLTYPE) ||
+ !wizardInfo.isNewKey())
+ return false;
+
+ String title = "";
+ certType = wizardInfo.getCertType();
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT))
+ title = mResource.getString("CERTDNWIZARD_BORDER_CASIGNING_LABEL");
+ else if (certType.equals(Constants.PR_OCSP_SIGNING_CERT))
+ title = mResource.getString("CERTDNWIZARD_BORDER_OCSPSIGNING_LABEL");
+ else if (certType.equals(Constants.PR_RA_SIGNING_CERT))
+ title = mResource.getString("CERTDNWIZARD_BORDER_RASIGNING_LABEL");
+ else if (certType.equals(Constants.PR_KRA_TRANSPORT_CERT))
+ title = mResource.getString("CERTDNWIZARD_BORDER_KRATRANSPORT_LABEL");
+ else if (certType.equals(Constants.PR_SERVER_CERT) ||
+ certType.equals(Constants.PR_SERVER_CERT_RADM))
+ title = mResource.getString("CERTDNWIZARD_BORDER_SERVER_LABEL");
+ else if (certType.equals(Constants.PR_OTHER_CERT))
+ title = mResource.getString("CERTDNWIZARD_BORDER_OTHER_LABEL");
+ setBorder(new TitledBorder(title));
+
+/*
+ if (wizardInfo.getOperationType().equals(wizardInfo.INSTALLTYPE) ||
+ (wizardInfo.getCAType().equals(wizardInfo.SELF_SIGNED)))
+ return false;
+*/
+
+ String subjectName = wizardInfo.getSubjectName();
+
+ //mSubjectStringText.setText(subjectName)
+
+ //dnDesc.setText(subjectName);
+ //enableFields(true, mActiveColor);
+ if (subjectName != null)
+ populateDN(subjectName);
+ return true;
+ }
+
+ public boolean validatePanel() {
+ if (certType.equals(Constants.PR_SERVER_CERT_RADM))
+ return true;
+ return super.validatePanel();
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ startProgressStatus();
+ String str1 = mSubjectDNText.getText().trim();
+ String str2 = mSubjectStringText.getText().trim();
+ String str = "";
+
+ if (mDNComponents.isSelected()) {
+ str = str1;
+ } else {
+ str = str2;
+ }
+
+ if (str.equals("")) {
+ setErrorMessage("BLANKFIELD");
+ return false;
+ //str = dnDesc.getText().trim();
+ }
+
+ str = CMSAdminUtil.getPureString(str);
+
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ AdminConnection connection = wizardInfo.getAdminConnection();
+ NameValuePairs nvps = new NameValuePairs();
+
+ nvps.put(Constants.PR_SUBJECT_NAME, str);
+ wizardInfo.addEntry(Constants.PR_SUBJECT_NAME, str);
+
+ try {
+ connection.validate(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_SUBJECT_NAME, nvps);
+ } catch (EAdminException e) {
+ //showErrorDialog(e.toString());
+ setErrorMessage(e.toString());
+ endProgressStatus();
+ return false;
+ }
+
+ if (wizardInfo.isNewKey()) {
+ String type = wizardInfo.getKeyType();
+ if (type.equals("ECC")) {
+ nvps.put(Constants.PR_KEY_CURVENAME, wizardInfo.getKeyCurveName());
+ } else {
+ nvps.put(Constants.PR_KEY_LENGTH, wizardInfo.getKeyLength());
+ }
+
+ nvps.put(Constants.PR_KEY_TYPE, type);
+ nvps.put(Constants.PR_TOKEN_NAME, wizardInfo.getTokenName());
+ }
+
+ wizardInfo.addEntry(wizardInfo.ALL_INFO, nvps);
+/*
+ try {
+ NameValuePairs response = connection.process(
+ DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_CERT_REQUEST, wizardInfo.getCertType(), nvps);
+ for (int i=0; i<response.size(); i++) {
+ NameValuePair nvp = response.elementAt(i);
+ String key = nvp.getName();
+ String value = nvp.getValue();
+ if (key.equals(Constants.PR_CSR)) {
+ wizardInfo.addEntry(Constants.PR_CSR, value);
+ break;
+ }
+ }
+ } catch (EAdminException e) {
+ //showErrorDialog(e.toString());
+ setErrorMessage(e.toString());
+ return false;
+ }
+*/
+
+ endProgressStatus();
+ wizardInfo.setSubjectName(str);
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WCertDNValidityPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WCertDNValidityPage.java
new file mode 100644
index 000000000..d6359cf6c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WCertDNValidityPage.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * CA signing cert for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WCertDNValidityPage extends WBaseDNValidityPage implements IWizardPanel {
+ private static final String PANELNAME = "CERTDNVALIDWIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WCertDNValidityPage() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ if (wizardInfo.getOperationType().equals(wizardInfo.INSTALLTYPE) ||
+ (wizardInfo.getCAType().equals(wizardInfo.SUBORDINATE_CA)))
+ return false;
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ String str = mSubjectDNText.getText().trim();
+
+ if (str.equals("")) {
+ setErrorMessage("BLANKFIELD");
+ return false;
+ }
+
+ str = CMSAdminUtil.getPureString(str);
+
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ wizardInfo.addEntry(Constants.PR_SUBJECT_NAME, str);
+
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ String valid = mValidityText.getText().trim();
+ int period = Integer.parseInt(valid);
+ int index = mUnitBox.getSelectedIndex();
+
+ if (index == 1) {
+ period = period*30;
+ } else if (index == 2) {
+ period = period*365;
+ }
+ wizardInfo.addEntry(Constants.PR_VALIDITY_PERIOD, ""+period);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WCertExtensionPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WCertExtensionPage.java
new file mode 100644
index 000000000..f7505be2e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WCertExtensionPage.java
@@ -0,0 +1,273 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.keycert;
+
+import javax.swing.border.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * Certificate Extension for setup wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WCertExtensionPage extends WBaseCertExtensionPage implements
+ IWizardPanel {
+ private static final String PANELNAME = "CERTEXTENSION1WIZARD";
+ private static final String HELPINDEX =
+ "configuration-keycert-wizard-extension-help";
+
+ WCertExtensionPage(JDialog parent) {
+ super(PANELNAME);
+ mPanelName = PANELNAME;
+ mParent = parent;
+ init();
+ }
+
+ WCertExtensionPage(JDialog parent, JFrame frame) {
+ super(PANELNAME);
+ mPanelName = PANELNAME;
+ mParent = parent;
+ mAdminFrame = frame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ //System.out.println("extension");
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ if (wizardInfo.getOperationType().equals(wizardInfo.INSTALLTYPE))
+ return false;
+
+ if (wizardInfo.getCAType().equals(wizardInfo.SUBORDINATE_CA)
+ && !(wizardInfo.isSSLCertLocalCA()))
+ return false;
+
+ String title = "";
+
+ if (!mModified) {
+ String certType = wizardInfo.getCertType();
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ title = mResource.getString(
+ "CERTEXTENSION1WIZARD_BORDER_CASIGNING_LABEL");
+ mBasicCheckBox.setSelected(true);
+ mAKICheckBox.setSelected(true);
+ mCACheckBox.setSelected(true);
+ mSKICheckBox.setSelected(true);
+ mCertPathBox.setSelected(false);
+ mExtendedKeyCheckBox.setSelected(false);
+ mExtendedKeyCheckBox.setEnabled(true);
+ mKeyUsageBox.setSelected(true);
+ mOCSPNoCheck.setSelected(false);
+ mOCSPNoCheck.setEnabled(true);
+ mAIACheckBox.setSelected(true);
+ } else if (certType.equals(Constants.PR_OCSP_SIGNING_CERT)) {
+ title = mResource.getString(
+ "CERTEXTENSION1WIZARD_BORDER_OCSPSIGNING_LABEL");
+ mKeyUsageBox.setSelected(true);
+ mSKICheckBox.setSelected(false);
+ mSKICheckBox.setEnabled(true);
+ mBasicCheckBox.setEnabled(false);
+ mAKICheckBox.setSelected(true);
+ mAKICheckBox.setEnabled(true);
+ mCACheckBox.setSelected(false);
+ mCACheckBox.setEnabled(false);
+ mCertPathBox.setEnabled(false);
+ mExtendedKeyCheckBox.setSelected(true);
+ mOCSPSigning.setSelected(true);
+ mOCSPNoCheck.setSelected(false);
+ mOCSPNoCheck.setEnabled(true);
+ mAIACheckBox.setSelected(true);
+ } else if (certType.equals(Constants.PR_RA_SIGNING_CERT)) {
+ title = mResource.getString(
+ "CERTEXTENSION1WIZARD_BORDER_RASIGNING_LABEL");
+ mAKICheckBox.setSelected(true);
+ mExtendedKeyCheckBox.setSelected(true);
+ mSSLClient.setSelected(true);
+ } else if (certType.equals(Constants.PR_KRA_TRANSPORT_CERT)) {
+ title = mResource.getString(
+ "CERTEXTENSION1WIZARD_BORDER_KRATRANSPORT_LABEL");
+ mAKICheckBox.setSelected(true);
+ } else if (certType.equals(Constants.PR_SERVER_CERT)) {
+ title = mResource.getString(
+ "CERTEXTENSION1WIZARD_BORDER_SERVER_LABEL");
+ mExtendedKeyCheckBox.setSelected(true);
+ mSSLServer.setSelected(true);
+ mAKICheckBox.setSelected(true);
+ mSKICheckBox.setSelected(false);
+ mSKICheckBox.setEnabled(true);
+ mOCSPNoCheck.setSelected(false);
+ mOCSPNoCheck.setEnabled(true);
+ mAIACheckBox.setSelected(true);
+ } else if (certType.equals(Constants.PR_SERVER_CERT_RADM)) {
+ title = mResource.getString(
+ "CERTEXTENSION1WIZARD_BORDER_SERVER_LABEL");
+ mExtendedKeyCheckBox.setSelected(true);
+ mAKICheckBox.setSelected(true);
+ mSSLServer.setSelected(true);
+ }
+ }
+
+ setBorder(new TitledBorder(title));
+
+ return super.initializePanel(info);
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+
+ if (mMIMECheckBox.isSelected()) {
+ startProgressStatus();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(ConfigConstants.PR_CERTIFICATE_EXTENSION, mMIMEText.getText().trim());
+ AdminConnection connection = wizardInfo.getAdminConnection();
+ try {
+ connection.validate(
+ DestDef.DEST_SERVER_ADMIN, ScopeDef.SC_CERTIFICATE_EXTENSION, nvps);
+ } catch (EAdminException e) {
+ setErrorMessage(e.toString());
+ return false;
+ }
+ endProgressStatus();
+ }
+
+ NameValuePairs nvps = new NameValuePairs();
+
+ nvps.put(Constants.PR_SUBJECT_NAME, wizardInfo.getSubjectName());
+ if (wizardInfo.isNewKey()) {
+ String type = wizardInfo.getKeyType();
+ if (type.equals("ECC")) {
+ nvps.put(Constants.PR_KEY_CURVENAME, wizardInfo.getKeyCurveName());
+ } else {
+ nvps.put(Constants.PR_KEY_LENGTH, wizardInfo.getKeyLength());
+ }
+ nvps.put(Constants.PR_KEY_TYPE, type);
+ nvps.put(Constants.PR_TOKEN_NAME, wizardInfo.getTokenName());
+ }
+ //nvps.add(Constants.PR_VALIDITY_PERIOD, wizardInfo.getValidityPeriod());
+ addValidityPeriod(wizardInfo, nvps);
+
+ if (mBasicCheckBox.isSelected())
+ addBasicConstraints(nvps);
+
+ if (mExtendedKeyCheckBox.isSelected())
+ addExtendedKey(nvps);
+
+ if (mAIACheckBox.isSelected())
+ nvps.put(Constants.PR_AIA, Constants.TRUE);
+
+ if (mAKICheckBox.isSelected())
+ nvps.put(Constants.PR_AKI, Constants.TRUE);
+
+ if (mSKICheckBox.isSelected())
+ nvps.put(Constants.PR_SKI, Constants.TRUE);
+
+ if (mOCSPNoCheck.isSelected())
+ nvps.put(Constants.PR_OCSP_NOCHECK, Constants.TRUE);
+
+ if (mKeyUsageBox.isSelected())
+ nvps.put(Constants.PR_KEY_USAGE, Constants.TRUE);
+
+ if (mMIMECheckBox.isSelected())
+ nvps.put(Constants.PR_DER_EXTENSION, mMIMEText.getText().trim());
+
+ wizardInfo.addEntry(wizardInfo.ALL_INFO, nvps);
+
+ mModified = true;
+ return true;
+ }
+
+ private void addValidityPeriod(CertSetupWizardInfo wizardInfo,
+ NameValuePairs nvps) {
+ nvps.put(Constants.PR_BEGIN_YEAR, wizardInfo.getBeginYear());
+ nvps.put(Constants.PR_BEGIN_MONTH, wizardInfo.getBeginMonth());
+ nvps.put(Constants.PR_BEGIN_DATE, wizardInfo.getBeginDate());
+ nvps.put(Constants.PR_BEGIN_HOUR, wizardInfo.getBeginHour());
+ nvps.put(Constants.PR_BEGIN_MIN, wizardInfo.getBeginMin());
+ nvps.put(Constants.PR_BEGIN_SEC, wizardInfo.getBeginSec());
+ nvps.put(Constants.PR_AFTER_YEAR, wizardInfo.getAfterYear());
+ nvps.put(Constants.PR_AFTER_MONTH, wizardInfo.getAfterMonth());
+ nvps.put(Constants.PR_AFTER_DATE, wizardInfo.getAfterDate());
+ nvps.put(Constants.PR_AFTER_HOUR, wizardInfo.getAfterHour());
+ nvps.put(Constants.PR_AFTER_MIN, wizardInfo.getAfterMin());
+ nvps.put(Constants.PR_AFTER_SEC, wizardInfo.getAfterSec());
+ }
+
+ private void addBasicConstraints(NameValuePairs nvps) {
+
+ if (mCACheckBox.isSelected())
+ nvps.put(Constants.PR_IS_CA, Constants.TRUE);
+
+ String certLen = mCertPathText.getText().trim();
+ if (!certLen.equals(""))
+ nvps.put(Constants.PR_CERT_LEN, certLen);
+ }
+
+ private void addExtendedKey(NameValuePairs nvps) {
+
+ if (mSSLClient.isSelected())
+ nvps.put(Constants.PR_SSL_CLIENT_BIT, Constants.TRUE);
+ if (mSSLServer.isSelected())
+ nvps.put(Constants.PR_SSL_SERVER_BIT, Constants.TRUE);
+ if (mSSLMail.isSelected())
+ nvps.put(Constants.PR_SSL_MAIL_BIT, Constants.TRUE);
+ if (mObjectSigning.isSelected())
+ nvps.put(Constants.PR_OBJECT_SIGNING_BIT, Constants.TRUE);
+ if (mTimeStamping.isSelected())
+ nvps.put(Constants.PR_TIMESTAMPING_BIT, Constants.TRUE);
+ if (mOCSPSigning.isSelected())
+ nvps.put(Constants.PR_OCSP_SIGNING, Constants.TRUE);
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+
+ private String getScope(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ String certType = wizardInfo.getCertType();
+ String scope = "";
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ scope = ScopeDef.SC_CA_SIGNINGCERT;
+ } else if (certType.equals(Constants.PR_RA_SIGNING_CERT)) {
+ scope = ScopeDef.SC_RA_SIGNINGCERT;
+ } else if (certType.equals(Constants.PR_KRA_TRANSPORT_CERT)) {
+ scope = ScopeDef.SC_KRA_TRANSPORTCERT;
+ } else if (certType.equals(Constants.PR_SERVER_CERT)) {
+ scope = ScopeDef.SC_SERVER_CERT;
+ }
+
+ return scope;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WCertMessageDigestPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WCertMessageDigestPage.java
new file mode 100644
index 000000000..a378e91d3
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WCertMessageDigestPage.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.task.*;
+
+/**
+ * Setup the message digest information for the installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WCertMessageDigestPage extends WMessageDigestPage {
+
+ private static final String PANELNAME = "CERTMESSAGEDIGESTWIZARD";
+ private static final String HELPINDEX =
+ "configuration-keycert-wizard-messagedigest-help";
+
+ WCertMessageDigestPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ }
+
+ WCertMessageDigestPage(JDialog parent, JFrame adminFrame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = adminFrame;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ String certType = wizardInfo.getCertType();
+
+ mCAKeyType = (String)wizardInfo.get(Constants.PR_KEY_TYPE);
+
+ if (wizardInfo.getOperationType().equals(wizardInfo.INSTALLTYPE))
+ return false;
+
+ if ((wizardInfo.getCAType().equals(wizardInfo.SUBORDINATE_CA))
+ && !(wizardInfo.isSSLCertLocalCA()))
+ return false;
+
+ if (!wizardInfo.isNewKey())
+ return false;
+
+ if (wizardInfo.getCAType().equals(wizardInfo.SELF_SIGNED) &&
+ certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ enableSignedByFields(true);
+ } else {
+ enableSignedByFields(false);
+ }
+
+ if ((!certType.equals(Constants.PR_CA_SIGNING_CERT)) &&
+ (!certType.equals(Constants.PR_OCSP_SIGNING_CERT))) {
+
+ // (!certType.equals(Constants.PR_KRA_TRANSPORT_CERT))) {
+ // non-signing cert, algorithm specified by CA
+ return false;
+ }
+
+ return super.initializePanel(info);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ if (mDSAHashTypeBox.isVisible())
+ wizardInfo.setHashType((String)mDSAHashTypeBox.getSelectedItem());
+ else if (mECCHashTypeBox.isVisible())
+ wizardInfo.setHashType((String)mECCHashTypeBox.getSelectedItem());
+ else if (mRSAHashTypeBox.isVisible())
+ wizardInfo.setHashType((String)mRSAHashTypeBox.getSelectedItem());
+
+ if (mDSASignedByTypeBox.isVisible())
+ wizardInfo.setSignedByType((String)mDSASignedByTypeBox.getSelectedItem());
+ else if (mECCSignedByTypeBox.isVisible())
+ wizardInfo.setSignedByType((String)mECCSignedByTypeBox.getSelectedItem());
+ else if (mRSASignedByTypeBox.isVisible())
+ wizardInfo.setSignedByType((String)mRSASignedByTypeBox.getSelectedItem());
+
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WCertRequestPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WCertRequestPage.java
new file mode 100644
index 000000000..8fa126148
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WCertRequestPage.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * Introduction page for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WCertRequestPage extends WBaseCertRequestPage implements IWizardPanel {
+ private static final String PANELNAME = "COPYCERTREQUESTWIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WCertRequestPage() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+
+ if (wizardInfo.getOperationType().equals(wizardInfo.INSTALLTYPE) ||
+ wizardInfo.getCAType().equals(wizardInfo.SELF_SIGNED))
+ return false;
+
+ String str = wizardInfo.getCSR();
+// mText.setText(CMSAdminUtil.certRequestWrapText(str, 40));
+ mText.setText(str);
+ setBorder(makeTitledBorder("COPYCERTREQUESTWIZARD"));
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WCertTypePage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WCertTypePage.java
new file mode 100644
index 000000000..88350fc32
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WCertTypePage.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Select certificate type from certificate setup wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WCertTypePage extends WizardBasePanel implements IWizardPanel,
+ ItemListener {
+ private String mCASigningCert;
+ private String mRASigningCert;
+ private String mOCSPSigningCert;
+ private String mServerCert, mServerCertRadm, mOtherCert;
+ private String mKRATransportCert;
+ private JTextArea mCALbl;
+ private JRadioButton mCABtn;
+ private JRadioButton mSubBtn;
+ private JComboBox mCertBox;
+ private JTextArea mCertType;
+ private JTextField mCertTypeText;
+ private Color mActiveColor;
+ private static final String PANELNAME = "CERTTYPEWIZARD";
+ private static final String HELPINDEX =
+ "configuration-keycert-wizard-certtype-help";
+
+ WCertTypePage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WCertTypePage(JDialog parent, JFrame frame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = frame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ if (wizardInfo.getOperationType().equals(wizardInfo.INSTALLTYPE))
+ return false;
+
+ setBorder(makeTitledBorder(PANELNAME));
+ if (wizardInfo.getCertType() != null) {
+ return true;
+ }
+
+ AdminConnection connection = wizardInfo.getAdminConnection();
+ NameValuePairs nvps = new NameValuePairs();
+
+ try {
+ NameValuePairs response = connection.search(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_SUBSYSTEM, nvps);
+
+ for (String name : response.keySet()) {
+ String type = response.get(name);
+
+ if (type.equals(Constants.PR_RA_INSTANCE))
+ mRASigningCert = mResource.getString(
+ "CERTTYPEWIZARD_LABEL_RASIGNINGCERT_LABEL");
+ else if (type.equals(Constants.PR_CA_INSTANCE))
+ mCASigningCert = mResource.getString(
+ "CERTTYPEWIZARD_LABEL_CASIGNINGCERT_LABEL");
+ else if (type.equals(Constants.PR_KRA_INSTANCE))
+ mKRATransportCert = mResource.getString(
+ "CERTTYPEWIZARD_LABEL_KRATRANSPORTCERT_LABEL");
+ }
+ } catch (EAdminException e) {
+ //showErrorDialog(e.toString());
+ setErrorMessage(e.toString());
+ }
+
+ mOCSPSigningCert = mResource.getString(
+ "CERTTYPEWIZARD_LABEL_OCSPSIGNINGCERT_LABEL");
+
+ mServerCert = mResource.getString(
+ "CERTTYPEWIZARD_LABEL_SERVERCERT_LABEL");
+
+ mServerCertRadm = mResource.getString(
+ "CERTTYPEWIZARD_LABEL_SERVERCERTRADM_LABEL");
+
+ mOtherCert = mResource.getString(
+ "CERTTYPEWIZARD_LABEL_OTHER_LABEL");
+
+ mCertBox.removeAllItems();
+
+ if (mCASigningCert != null)
+ mCertBox.addItem(mCASigningCert);
+
+ if (mRASigningCert != null)
+ mCertBox.addItem(mRASigningCert);
+
+ if (mKRATransportCert != null)
+ mCertBox.addItem(mKRATransportCert);
+
+ if (mOCSPSigningCert != null)
+ mCertBox.addItem(mOCSPSigningCert);
+
+ if (mServerCert != null)
+ mCertBox.addItem(mServerCert);
+
+/*
+ if (mServerCertRadm != null)
+ mCertBox.addItem(mServerCertRadm);
+*/
+
+ mCertBox.addItem(mOtherCert);
+ mCertBox.setSelectedIndex(0);
+
+ String certType = (String)mCertBox.getSelectedItem();
+
+ if (certType.equals(mOtherCert)) {
+ mCABtn.setEnabled(false);
+ mSubBtn.setEnabled(false);
+ mCALbl.setEnabled(false);
+ mCertType.setEnabled(true);
+ mCertTypeText.setEnabled(true);
+ mCertTypeText.setBackground(mActiveColor);
+ } else {
+ mCABtn.setEnabled(true);
+ mSubBtn.setEnabled(true);
+ mCALbl.setEnabled(true);
+ mCertType.setEnabled(false);
+ mCertTypeText.setEnabled(false);
+ mCertTypeText.setBackground(getBackground());
+ if ((mCASigningCert != null) && (certType.equals(mCASigningCert)))
+ enableFields(true,"casigning");
+ else if ((mCASigningCert != null) && (mOCSPSigningCert != null)
+ && (certType.equals(mOCSPSigningCert)))
+ enableFields(true,"ocspsigning");
+ else if ((mCASigningCert != null) && (mServerCert != null)
+ && (certType.equals(mServerCert)))
+ enableFields(true,"server");
+ else if ((mCASigningCert != null) && (mServerCertRadm != null)
+ && (certType.equals(mServerCertRadm)))
+ enableFields(true,"server");
+ else
+ enableFields(false,"other");
+ }
+
+ CMSAdminUtil.repaintComp(mCABtn);
+ CMSAdminUtil.repaintComp(mSubBtn);
+ CMSAdminUtil.repaintComp(mCALbl);
+ CMSAdminUtil.repaintComp(mCertType);
+ CMSAdminUtil.repaintComp(mCertTypeText);
+ return true;
+ }
+
+ public boolean validatePanel() {
+ String str = (String)mCertBox.getSelectedItem();
+ if (str.equals(mOtherCert)) {
+ if (mCertTypeText.getText().equals("")) {
+ setErrorMessage("BLANKCERTTYPE");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ NameValuePairs nvps = new NameValuePairs();
+ AdminConnection connection = wizardInfo.getAdminConnection();
+ startProgressStatus();
+ String item = ((String)mCertBox.getSelectedItem()).trim();
+
+ if (mCASigningCert != null && item.equals(mCASigningCert.trim()))
+ wizardInfo.put(Constants.PR_CERTIFICATE_TYPE,
+ Constants.PR_CA_SIGNING_CERT);
+ else if (mRASigningCert != null && item.equals(mRASigningCert.trim()))
+ wizardInfo.put(Constants.PR_CERTIFICATE_TYPE,
+ Constants.PR_RA_SIGNING_CERT);
+ else if (mKRATransportCert != null &&
+ item.equals(mKRATransportCert.trim()))
+ wizardInfo.put(Constants.PR_CERTIFICATE_TYPE,
+ Constants.PR_KRA_TRANSPORT_CERT);
+ else if (mServerCert != null && item.equals(mServerCert.trim()))
+ wizardInfo.put(Constants.PR_CERTIFICATE_TYPE,
+ Constants.PR_SERVER_CERT);
+ else if (mServerCertRadm != null && item.equals(mServerCertRadm.trim()))
+ wizardInfo.put(Constants.PR_CERTIFICATE_TYPE,
+ Constants.PR_SERVER_CERT_RADM);
+ else if (mOCSPSigningCert != null && item.equals(mOCSPSigningCert.trim()))
+ wizardInfo.put(Constants.PR_CERTIFICATE_TYPE,
+ Constants.PR_OCSP_SIGNING_CERT);
+ else if (mOtherCert != null && item.equals(mOtherCert.trim()))
+ wizardInfo.put(Constants.PR_CERTIFICATE_TYPE,
+ Constants.PR_OTHER_CERT);
+
+ if (item.equals(mOtherCert.trim())) {
+ try {
+ NameValuePairs response = null;
+
+ response = connection.read(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_GET_NICKNAMES, wizardInfo.getCertType(), nvps);
+ String value = response.get(Constants.PR_ALL_NICKNAMES);
+ wizardInfo.setNicknames(value);
+ } catch (EAdminException e) {
+ setErrorMessage(e.toString());
+ endProgressStatus();
+ return false;
+ }
+ }
+
+ endProgressStatus();
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+/*
+ JTextArea desc = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "CERTTYPEWIZARD_TEXT_HEADING_LABEL"), 80), 1, 80);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+*/
+ JTextArea heading = createTextArea(mResource.getString(
+ PANELNAME+"_LABEL_HEADING_LABEL"));
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(heading, gbc);
+
+ JTextArea heading1 = createTextArea(mResource.getString(
+ PANELNAME+"_LABEL_HEADING1_LABEL"));
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(heading1, gbc);
+
+ mCertBox = new JComboBox();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(mCertBox, gbc);
+ mCertBox.addItemListener(this);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(dummy, gbc);
+
+ mCertType = createTextArea(mResource.getString(
+ PANELNAME+"_LABEL_CERTTYPE_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mCertType, gbc);
+
+/*
+ JLabel dummy1 = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(dummy1, gbc);
+*/
+
+ mCertTypeText = makeJTextField(10);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(mCertTypeText, gbc);
+ mActiveColor = mCertTypeText.getBackground();
+
+ JLabel dummy2 = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(dummy2, gbc);
+
+ mCALbl = createTextArea(mResource.getString(
+ "CERTTYPEWIZARD_TEXT_CATYPE_LABEL"));
+/*
+ mCALbl = makeJLabel("CATYPE");
+*/
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.insets = new Insets(2*COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ add(mCALbl, gbc);
+
+ mCABtn = makeJRadioButton("SELFSIGN", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mCABtn, gbc);
+
+ mSubBtn = makeJRadioButton("SUBORDINATE", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(0,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mSubBtn, gbc);
+
+ ButtonGroup caGroup = new ButtonGroup();
+ caGroup.add(mCABtn);
+ caGroup.add(mSubBtn);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ String str = (String)mCertBox.getSelectedItem();
+
+ /*
+ if ((mCASigningCert == null) || (!str.equals(mCASigningCert))) {
+ wizardInfo.addEntry(wizardInfo.CA_TYPE, wizardInfo.SUBORDINATE_CA);
+ return;
+ }
+ */
+
+ if ((mCASigningCert != null) && (str.equals(mCASigningCert))) {
+ if (mCABtn.isSelected()) {
+ wizardInfo.addEntry(wizardInfo.CA_TYPE, wizardInfo.SELF_SIGNED);
+ } else if (mSubBtn.isSelected()) {
+ wizardInfo.addEntry(wizardInfo.CA_TYPE,
+ wizardInfo.SUBORDINATE_CA);
+ }
+ } else if ((mCASigningCert != null) && (mServerCert != null)
+ && (str.equals(mServerCert))) {
+ wizardInfo.addEntry(wizardInfo.CA_TYPE, wizardInfo.SUBORDINATE_CA);
+ if (mCABtn.isSelected())
+ wizardInfo.setSSLCertLocalCA(Constants.TRUE);
+ else if (mSubBtn.isSelected())
+ wizardInfo.setSSLCertLocalCA(Constants.FALSE);
+ } else if ((mCASigningCert != null) && (mServerCertRadm != null)
+ && (str.equals(mServerCertRadm))) {
+ wizardInfo.addEntry(wizardInfo.CA_TYPE, wizardInfo.SUBORDINATE_CA);
+ if (mCABtn.isSelected())
+ wizardInfo.setSSLCertLocalCA(Constants.TRUE);
+ else if (mSubBtn.isSelected())
+ wizardInfo.setSSLCertLocalCA(Constants.FALSE);
+ } else if ((mCASigningCert != null) && (mOCSPSigningCert != null)
+ && (str.equals(mOCSPSigningCert))) {
+ wizardInfo.addEntry(wizardInfo.CA_TYPE, wizardInfo.SUBORDINATE_CA);
+ if (mCABtn.isSelected())
+ wizardInfo.setSSLCertLocalCA(Constants.TRUE);
+ else if (mSubBtn.isSelected())
+ wizardInfo.setSSLCertLocalCA(Constants.FALSE);
+ } else if (mOtherCert != null && str.equals(mOtherCert)) {
+ wizardInfo.addEntry(wizardInfo.CA_TYPE, wizardInfo.SUBORDINATE_CA);
+ wizardInfo.setCertSubType(mCertTypeText.getText());
+ } else {
+ wizardInfo.addEntry(wizardInfo.CA_TYPE, wizardInfo.SUBORDINATE_CA);
+ }
+ }
+
+ public void itemStateChanged(ItemEvent e) {
+ if (e.getSource().equals(mCertBox)) {
+ String str = (String)mCertBox.getSelectedItem();
+ if (str == null)
+ return;
+
+ if (str.equals(mOtherCert)) {
+ mCABtn.setEnabled(false);
+ mSubBtn.setEnabled(false);
+ mCALbl.setEnabled(false);
+ mCertType.setEnabled(true);
+ mCertTypeText.setEnabled(true);
+ mCertTypeText.setBackground(mActiveColor);
+ } else {
+ mCABtn.setEnabled(true);
+ mSubBtn.setEnabled(true);
+ mCALbl.setEnabled(true);
+ mCertType.setEnabled(false);
+ mCertTypeText.setEnabled(false);
+ mCertTypeText.setBackground(getBackground());
+ if ((mCASigningCert != null) && (str.equals(mCASigningCert)))
+ enableFields(true,"casigning");
+ else if ((mCASigningCert != null) && (mOCSPSigningCert != null)
+ && (str.equals(mOCSPSigningCert)))
+ enableFields(true,"ocspsigning");
+ else if ((mCASigningCert != null) && (mServerCert != null)
+ && (str.equals(mServerCert)))
+ enableFields(true,"server");
+ else if ((mCASigningCert != null) && (mServerCertRadm != null)
+ && (str.equals(mServerCertRadm)))
+ enableFields(true,"server");
+ else
+ enableFields(false,"other");
+ }
+ CMSAdminUtil.repaintComp(mCertType);
+ CMSAdminUtil.repaintComp(mCertTypeText);
+ }
+ }
+
+ private void enableFields(boolean enable,String type) {
+ String label = null;
+ String b1 = null;
+ String b2 = null;
+ if (type.equals("casigning")) {
+ label =
+ mResource.getString("CERTTYPEWIZARD_TEXT_CATYPE_LABEL");
+ b1 =
+ mResource.getString("CERTTYPEWIZARD_RADIOBUTTON_SELFSIGN_LABEL");
+ b2 =
+ mResource.getString("CERTTYPEWIZARD_RADIOBUTTON_SUBORDINATE_LABEL");
+ } else if (type.equals("server")) {
+ label =
+ mResource.getString("CERTTYPEWIZARD_TEXT_SERVERTYPE_LABEL");
+ b1 =
+ mResource.getString("CERTTYPEWIZARD_RADIOBUTTON_SERVER_SELFSIGN_LABEL");
+ b2 =
+ mResource.getString("CERTTYPEWIZARD_RADIOBUTTON_SERVER_SUBORDINATE_LABEL");
+ } else if (type.equals("ocspsigning")) {
+ label =
+ mResource.getString("CERTTYPEWIZARD_TEXT_OCSPTYPE_LABEL");
+ b1 =
+ mResource.getString("CERTTYPEWIZARD_RADIOBUTTON_SELFSIGNOCSP_LABEL");
+ b2 =
+ mResource.getString("CERTTYPEWIZARD_RADIOBUTTON_SUBORDINATEOCSP_LABEL");
+ }
+
+ mCALbl.setEnabled(enable);
+ mCALbl.invalidate();
+ mCALbl.validate();
+ if (label != null) mCALbl.setText(label);
+ mCALbl.repaint(1);
+ mCABtn.setEnabled(enable);
+ mCABtn.invalidate();
+ mCABtn.validate();
+ if (b1 != null) mCABtn.setText(b1);
+ mCABtn.repaint(1);
+ mSubBtn.setEnabled(enable);
+ mSubBtn.invalidate();
+ mSubBtn.validate();
+ if (b2 != null) mSubBtn.setText(b2);
+ mSubBtn.repaint(1);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WCertValidityPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WCertValidityPage.java
new file mode 100644
index 000000000..8567703d4
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WCertValidityPage.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * CA signing cert for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WCertValidityPage extends WBaseValidityPage implements IWizardPanel {
+ private static final String PANELNAME = "CERTVALIDWIZARD";
+ private String mCertType = "";
+ private static final String HELPINDEX =
+ "configuration-keycert-wizard-validityperiod-help";
+
+ WCertValidityPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WCertValidityPage(JDialog parent, JFrame frame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = frame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ if (wizardInfo.getOperationType().equals(wizardInfo.INSTALLTYPE) )
+ return false;
+ if ((wizardInfo.getCAType().equals(wizardInfo.SUBORDINATE_CA))
+ && !(wizardInfo.isSSLCertLocalCA()))
+ return false;
+
+ String title = "";
+ mCertType = wizardInfo.getCertType();
+ if (mCertType.equals(Constants.PR_CA_SIGNING_CERT))
+ title = mResource.getString("CERTVALIDWIZARD_BORDER_CASIGNING_LABEL");
+ else if (mCertType.equals(Constants.PR_OCSP_SIGNING_CERT))
+ title = mResource.getString("CERTVALIDWIZARD_BORDER_OCSPSIGNING_LABEL");
+ else if (mCertType.equals(Constants.PR_RA_SIGNING_CERT))
+ title = mResource.getString("CERTVALIDWIZARD_BORDER_RASIGNING_LABEL");
+ else if (mCertType.equals(Constants.PR_KRA_TRANSPORT_CERT))
+ title = mResource.getString("CERTVALIDWIZARD_BORDER_KRATRANSPORT_LABEL");
+ else if (mCertType.equals(Constants.PR_SERVER_CERT) ||
+ mCertType.equals(Constants.PR_SERVER_CERT_RADM))
+ title = mResource.getString("CERTVALIDWIZARD_BORDER_SERVER_LABEL");
+ setBorder(new TitledBorder(title));
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ boolean status = super.validatePanel();
+ if (status && !mWarningDisplayed) {
+ Date currTime = new Date();
+ if (currTime.before(mBeforeDate)) {
+ if (mCertType.equals(Constants.PR_CA_SIGNING_CERT))
+ setErrorMessage("INVALIDCACERT");
+ else if (mCertType.equals(Constants.PR_OCSP_SIGNING_CERT))
+ setErrorMessage("INVALIDOCSPCERT");
+ else if (mCertType.equals(Constants.PR_RA_SIGNING_CERT))
+ setErrorMessage("INVALIDRACERT");
+ else if (mCertType.equals(Constants.PR_KRA_TRANSPORT_CERT))
+ setErrorMessage("INVALIDKRACERT");
+ else if (mCertType.equals(Constants.PR_SERVER_CERT))
+ setErrorMessage("INVALIDSSLCERT");
+ mWarningDisplayed = true;
+ return false;
+ }
+ }
+ return status;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ protected void init() {
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ wizardInfo.addEntry(Constants.PR_BEGIN_YEAR, mBYear.getText().trim());
+ int beforeMonth = Integer.parseInt(mBMonth.getText().trim());
+ wizardInfo.addEntry(Constants.PR_BEGIN_MONTH, ""+(beforeMonth-1));
+ wizardInfo.addEntry(Constants.PR_BEGIN_DATE, mBDay.getText().trim());
+ wizardInfo.addEntry(Constants.PR_BEGIN_HOUR, mBHour.getText().trim());
+ wizardInfo.addEntry(Constants.PR_BEGIN_MIN, mBMin.getText().trim());
+ wizardInfo.addEntry(Constants.PR_BEGIN_SEC, mBSec.getText().trim());
+ wizardInfo.addEntry(Constants.PR_AFTER_YEAR, mEYear.getText().trim());
+ int afterMonth = Integer.parseInt(mEMonth.getText().trim());
+ wizardInfo.addEntry(Constants.PR_AFTER_MONTH, ""+(afterMonth-1));
+ wizardInfo.addEntry(Constants.PR_AFTER_DATE, mEDay.getText().trim());
+ wizardInfo.addEntry(Constants.PR_AFTER_HOUR, mEHour.getText().trim());
+ wizardInfo.addEntry(Constants.PR_AFTER_MIN, mEMin.getText().trim());
+ wizardInfo.addEntry(Constants.PR_AFTER_SEC, mESec.getText().trim());
+ //wizardInfo.addEntry(Constants.PR_VALIDITY_PERIOD, ""+period);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WDisplayCertPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WDisplayCertPage.java
new file mode 100644
index 000000000..a7fe56352
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WDisplayCertPage.java
@@ -0,0 +1,258 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.keycert;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * This page is to install the certificate in the internal token. It
+ * displays the certificate information.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WDisplayCertPage extends WizardBasePanel implements IWizardPanel {
+ private CertSetupWizardInfo wizardInfo;
+ private JButton mAdd;
+ private boolean isAdd = false;
+ private static final String PANELNAME = "DISPLAYCERTWIZARD";
+ private static final String HELPINDEX =
+ "configuration-keycert-wizard-displaycert-help";
+ private JTextArea mTextArea;
+ private JTextField mCertNameField;
+ private Color mActiveColor;
+
+ WDisplayCertPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WDisplayCertPage(JDialog parent, JFrame frame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = frame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ wizardInfo = (CertSetupWizardInfo)info;
+ if (wizardInfo.getOperationType().equals(wizardInfo.REQUESTTYPE))
+ return false;
+
+ setBorder(makeTitledBorder(PANELNAME));
+ mTextArea.setText(wizardInfo.getCertContent());
+ if (wizardInfo.getInstallCertType().equals(Constants.PR_OTHER_CERT)) {
+ mCertNameField.setEditable(true);
+ mCertNameField.setBackground(mActiveColor);
+ mCertNameField.setEnabled(true);
+ } else {
+ mCertNameField.setEditable(false);
+ mCertNameField.setBackground(getBackground());
+ mCertNameField.setEnabled(false);
+ }
+
+ String certName = wizardInfo.getNickname();
+ if (certName != null && !certName.equals(""))
+ mCertNameField.setText(certName);
+
+ CMSAdminUtil.repaintComp(mCertNameField);
+ return true;
+ }
+
+ public boolean validatePanel() {
+ if (mCertNameField.isEditable()) {
+ String str = mCertNameField.getText();
+ if (str == null || str.length() == 0) {
+ setErrorMessage("EMPTYCERTNAME");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ AdminConnection connection = wizardInfo.getAdminConnection();
+ CMSServerInfo serverInfo = wizardInfo.getServerInfo();
+ String certType = wizardInfo.getInstallCertType();
+ String pathname = "";
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ pathname = "prevCACert.txt";
+ } else if (certType.equals(Constants.PR_OCSP_SIGNING_CERT)) {
+ pathname = "prevOCSPCert.txt";
+ } else if (certType.equals(Constants.PR_RA_SIGNING_CERT)) {
+ pathname = "prevRACert.txt";
+ } else if (certType.equals(Constants.PR_KRA_TRANSPORT_CERT)) {
+ pathname = "prevKRACert.txt";
+ } else if (certType.equals(Constants.PR_SERVER_CERT)) {
+ pathname = "prevSSLCert.txt";
+ } else if (certType.equals(Constants.PR_SERVER_CERT_RADM)) {
+ pathname = "prevSSLCertRadm.txt";
+ } else if (certType.equals(Constants.PR_CROSS_CERT)) {
+ pathname = "prevCROSSCert.txt";
+ } else if (certType.equals(Constants.PR_OTHER_CERT)) {
+ pathname = "prevOTHERCert.txt";
+ }
+
+ NameValuePairs nvps = new NameValuePairs();
+ String cert = wizardInfo.getPKCS10();
+
+ if (cert == null) {
+ nvps.put(Constants.PR_CERT_FILEPATH,
+ wizardInfo.getCertFilePath());
+ } else {
+ nvps.put(Constants.PR_PKCS10, wizardInfo.getPKCS10());
+ }
+
+ nvps.put(Constants.PR_NICKNAME, mCertNameField.getText().trim());
+ nvps.put("pathname", pathname);
+ nvps.put(Constants.PR_SERVER_ROOT, serverInfo.getServerRoot());
+ nvps.put(Constants.PR_SERVER_ID, serverInfo.getServerId());
+
+ try {
+ connection.modify(
+ DestDef.DEST_SERVER_ADMIN,
+ (certType.equals(Constants.PR_CROSS_CERT))?
+ (ScopeDef.SC_IMPORT_CROSS_CERT):(ScopeDef.SC_INSTALL_CERT),
+ certType, nvps);
+ } catch (EAdminException ex) {
+ showErrorDialog(ex.toString());
+ //setErrorMessage(ex.toString());
+ wizardInfo.addEntry(Constants.PR_ADD_CERT, new Boolean(false));
+ return false;
+ }
+ wizardInfo.addEntry(Constants.PR_ADD_CERT, new Boolean(true));
+/*
+ CMSAdminUtil.showMessageDialog(mResource, PANELNAME,
+ "INSTALL", JOptionPane.INFORMATION_MESSAGE);
+*/
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label1 = makeJLabel("NAME");
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE);
+ add(label1, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mCertNameField = new JTextField(30);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.anchor = gbc.WEST;
+ gbc.weightx=1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ add(mCertNameField, gbc);
+ mActiveColor = mCertNameField.getBackground();
+
+ mCertNameField.setEditable(false);
+ mCertNameField.setBackground(getBackground());
+ mCertNameField.setEnabled(false);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel certLbl = makeJLabel("CONTENT");
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ add(certLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mTextArea = new JTextArea("",100,90);
+ Font f = new Font("Monospaced", Font.PLAIN, 12);
+ if (f != null) mTextArea.setFont(f);
+ mTextArea.setEditable(false);
+ mTextArea.setBackground(getBackground());
+ JScrollPane scrollPanel = new JScrollPane(mTextArea,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ scrollPanel.setAlignmentX(LEFT_ALIGNMENT);
+ scrollPanel.setAlignmentY(TOP_ALIGNMENT);
+ scrollPanel.setBorder(BorderFactory.createLoweredBevelBorder());
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx=1.0;
+ gbc.weighty=1.0;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(scrollPanel, gbc);
+
+/*
+ mAdd = makeJButton("ADD");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ add(mAdd, gbc);
+*/
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ Boolean bool = wizardInfo.isCertAdded();
+ if (bool == null)
+ wizardInfo.addEntry(Constants.PR_ADD_CERT, new Boolean(false));
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mAdd)) {
+
+ }
+ }
+
+ private String[] parseStr(String dn) {
+ StringTokenizer tokenizer = new StringTokenizer(dn, ",");
+ int numTokens = tokenizer.countTokens();
+ String[] results = new String[numTokens];
+ int i=0;
+ while (tokenizer.hasMoreElements()) {
+ results[i] = (String)tokenizer.nextToken();
+ i++;
+ }
+ return results;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WExecute1Page.java b/base/console/src/com/netscape/admin/certsrv/keycert/WExecute1Page.java
new file mode 100644
index 000000000..d13bca6e4
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WExecute1Page.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Introduction page for certificate setup wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WExecute1Page extends WizardBasePanel implements IWizardPanel {
+ private static final String PANELNAME = "EXECUTE1WIZARD";
+ private static final String HELPINDEX =
+ "configuration-keycert-wizard-certrequest-help";
+ private JTextArea desc;
+
+ WExecute1Page(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WExecute1Page(JDialog parent, JFrame frame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = frame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ if (wizardInfo.getOperationType().equals(wizardInfo.REQUESTTYPE) &&
+// !wizardInfo.isNewKey() &&
+ wizardInfo.getCAType().equals(wizardInfo.SUBORDINATE_CA) &&
+ !(wizardInfo.isSSLCertLocalCA())) {
+
+ String title = "";
+ String certType = wizardInfo.getCertType();
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT))
+ title = mResource.getString("EXECUTE1WIZARD_BORDER_CASIGNING_LABEL");
+ else if (certType.equals(Constants.PR_OCSP_SIGNING_CERT))
+ title = mResource.getString("EXECUTE1WIZARD_BORDER_OCSPSIGNING_LABEL");
+ else if (certType.equals(Constants.PR_RA_SIGNING_CERT))
+ title = mResource.getString("EXECUTE1WIZARD_BORDER_RASIGNING_LABEL");
+ else if (certType.equals(Constants.PR_KRA_TRANSPORT_CERT))
+ title = mResource.getString("EXECUTE1WIZARD_BORDER_KRATRANSPORT_LABEL");
+ else if (certType.equals(Constants.PR_SERVER_CERT) ||
+ certType.equals(Constants.PR_SERVER_CERT_RADM))
+ title = mResource.getString("EXECUTE1WIZARD_BORDER_SERVER_LABEL");
+ else if (certType.equals(Constants.PR_OTHER_CERT))
+ title = mResource.getString("EXECUTE1WIZARD_BORDER_OTHER_LABEL");
+ setBorder(new TitledBorder(title));
+
+ String str = "";
+ if (wizardInfo.isNewKey()) {
+ str = mResource.getString("EXECUTE1WIZARD_TEXT_NEWKEY_LABEL");
+ } else {
+ str = mResource.getString("EXECUTE1WIZARD_TEXT_OLDKEY_LABEL");
+ }
+ desc.setText(str);
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ startProgressStatus();
+ AdminConnection connection = wizardInfo.getAdminConnection();
+ NameValuePairs nvps = wizardInfo.getNameValuePairs();
+ if (wizardInfo.getCertType().equals(Constants.PR_OTHER_CERT) &&
+ !wizardInfo.isNewKey()) {
+ nvps.put(Constants.PR_NICKNAME, wizardInfo.getNickname());
+ }
+
+ try {
+ NameValuePairs response = connection.process(
+ DestDef.DEST_SERVER_ADMIN, ScopeDef.SC_CERT_REQUEST,
+ wizardInfo.getCertType(), nvps);
+ for (String key : response.keySet()) {
+ String value = response.get(key);
+ if (key.equals(Constants.PR_CSR)) {
+ wizardInfo.addEntry(Constants.PR_CSR, value);
+ } else if (key.equals(Constants.PR_CERT_REQUEST_DIR)) {
+ wizardInfo.addEntry(Constants.PR_CERT_REQUEST_DIR, value);
+ }
+ }
+ } catch (EAdminException e) {
+ setErrorMessage(e.toString());
+ endProgressStatus();
+ return false;
+ }
+
+ endProgressStatus();
+
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ desc = createTextArea("");
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WExecutePage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WExecutePage.java
new file mode 100644
index 000000000..a3ce14257
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WExecutePage.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Introduction page for certificate setup wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WExecutePage extends WizardBasePanel implements IWizardPanel {
+ private static final String PANELNAME = "EXECUTEWIZARD";
+ private static final String HELPINDEX =
+ "configuration-keycert-wizard-selfsignedcert-help";
+ private JTextArea desc;
+
+ WExecutePage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WExecutePage(JDialog parent, JFrame frame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = frame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ if (wizardInfo.getOperationType().equals(wizardInfo.REQUESTTYPE) &&
+// !wizardInfo.isNewKey() &&
+ ((wizardInfo.getCertType().equals(Constants.PR_CA_SIGNING_CERT) &&
+ wizardInfo.getCAType().equals(wizardInfo.SELF_SIGNED))
+ ||
+ (wizardInfo.getCertType().equals(Constants.PR_OCSP_SIGNING_CERT) &&
+ wizardInfo.isSSLCertLocalCA())
+ ||
+ (wizardInfo.getCertType().equals(Constants.PR_SERVER_CERT) &&
+ wizardInfo.isSSLCertLocalCA())
+ ||
+ (wizardInfo.getCertType().equals(Constants.PR_SERVER_CERT_RADM) &&
+ wizardInfo.isSSLCertLocalCA()))) {
+
+ setBorder(makeTitledBorder(PANELNAME));
+
+ if (wizardInfo.isNewKey()) {
+ String str = mResource.getString(
+ "EXECUTEWIZARD_TEXT_NEWKEY_LABEL");
+ desc.setText(str);
+ } else {
+ String str = mResource.getString(
+ "EXECUTEWIZARD_TEXT_OLDKEY_LABEL");
+ desc.setText(str);
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ startProgressStatus();
+ AdminConnection connection = wizardInfo.getAdminConnection();
+ CMSServerInfo serverInfo = wizardInfo.getServerInfo();
+
+ String dir = "";
+ if (wizardInfo.getCertType().equals(Constants.PR_CA_SIGNING_CERT))
+ dir = "prevCACert.txt";
+ else if (wizardInfo.getCertType().equals(Constants.PR_OCSP_SIGNING_CERT))
+ dir = "prevOCSPCert.txt";
+ else if (wizardInfo.getCertType().equals(Constants.PR_SERVER_CERT))
+ dir = "prevSSLCert.txt";
+ else if (wizardInfo.getCertType().equals(Constants.PR_SERVER_CERT_RADM))
+ dir = "prevSSLCertRadm.txt";
+
+ NameValuePairs nvps = wizardInfo.getNameValuePairs();
+
+ if (wizardInfo.isNewKey()) {
+ if (wizardInfo.getHashType() != null)
+ nvps.put(ConfigConstants.PR_HASH_TYPE, wizardInfo.getHashType());
+ if (wizardInfo.getSignedByType() != null)
+ nvps.put(ConfigConstants.PR_SIGNEDBY_TYPE, wizardInfo.getSignedByType());
+ }
+
+ nvps.put("pathname", dir);
+ try {
+ connection.modify(
+ DestDef.DEST_SERVER_ADMIN, ScopeDef.SC_ISSUE_IMPORT_CERT,
+ wizardInfo.getCertType(), nvps);
+ } catch (EAdminException e) {
+ setErrorMessage(e.toString());
+ endProgressStatus();
+ return false;
+ }
+
+ endProgressStatus();
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ desc = createTextArea("");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WGenerateReqPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WGenerateReqPage.java
new file mode 100644
index 000000000..b2a0005b6
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WGenerateReqPage.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Generate Request page for certificate setup wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WGenerateReqPage extends WizardBasePanel implements IWizardPanel {
+ private static final String PANELNAME = "GENERATEREQWIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WGenerateReqPage() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ if (wizardInfo.getOperationType().equals(wizardInfo.INSTALLTYPE))
+ return false;
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea desc = new JTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "GENERATEREQWIZARD_TEXT_REQUEST_LABEL"), 80), 2, 80);
+
+ desc.setBackground(getBackground());
+ desc.setEditable(false);
+ desc.setCaretColor(getBackground());
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WInstallCertChainPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WInstallCertChainPage.java
new file mode 100644
index 000000000..0ea476b6a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WInstallCertChainPage.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * This page allows the user to do such selections as the installation of
+ * certificates, server certificate chain, or trusted CA.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WInstallCertChainPage extends WizardBasePanel implements IWizardPanel {
+ private JComboBox mCertBox;
+ private String mTrustedCACert;
+ private String mTrustedCert, mOtherCert, mCrossCert;
+ private static final String PANELNAME = "INSTALLCERTCHAINWIZARD";
+ private static final String HELPINDEX =
+ "configuration-keycert-wizard-installcerttype-help";
+
+ WInstallCertChainPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WInstallCertChainPage(JDialog parent, JFrame frame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = frame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ if (wizardInfo.getOperationType().equals(wizardInfo.REQUESTTYPE))
+ return false;
+
+ setBorder(makeTitledBorder(PANELNAME));
+
+ String mode = wizardInfo.getMode();
+ if (mode != null && mode.equals("0")) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea introLbl = createTextArea(mResource.getString(
+ PANELNAME+"_LABEL_INTRO_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(introLbl, gbc);
+
+ JTextArea opLbl = createTextArea(mResource.getString(
+ PANELNAME+"_LABEL_INSTALLCERT_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(opLbl, gbc);
+
+ mCertBox = makeJComboBox("CERTCHAINTYPE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.weighty = 1.0;
+ add(mCertBox, gbc);
+
+ JTextArea dummy = createTextArea(" ", 1, 10);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,COMPONENT_SPACE);
+ add(dummy, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ String str = (String)(mCertBox.getSelectedItem());
+ if (str.startsWith("Trusted")) {
+ wizardInfo.addEntry(wizardInfo.INSTALLCERTTYPE, Constants.PR_TRUSTED_CA_CERT);
+ } else if (str.startsWith("Untrusted")) {
+ wizardInfo.addEntry(wizardInfo.INSTALLCERTTYPE, Constants.PR_SERVER_CERT_CHAIN);
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WInstallOpPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WInstallOpPage.java
new file mode 100644
index 000000000..5b4d2d340
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WInstallOpPage.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * This page allows the user to do such selections as the installation of
+ * certificates, server certificate chain, or trusted CA.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WInstallOpPage extends WizardBasePanel implements IWizardPanel {
+ private JComboBox mCertBox;
+ private String mCASigningCert;
+ private String mOCSPSigningCert;
+ private String mRASigningCert;
+ private String mKRATransportCert;
+ private String mServerCert, mServerCertRadm;
+ private String mOtherCert, mCrossCert;
+ private Vector mCerts;
+ private static final String PANELNAME = "INSTALLOPWIZARD";
+ private static final String HELPINDEX =
+ "configuration-keycert-wizard-installcerttype-help";
+
+ WInstallOpPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ mCerts = new Vector();
+ init();
+ }
+
+ WInstallOpPage(JDialog parent, JFrame frame) {
+ super(PANELNAME);
+ mParent = parent;
+ mCerts = new Vector();
+ mAdminFrame = frame;
+ init();
+ }
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ if (wizardInfo.getOperationType().equals(wizardInfo.REQUESTTYPE))
+ return false;
+ String mode = wizardInfo.getMode();
+ if (mode != null && mode.equals("0"))
+ return false;
+
+ setBorder(makeTitledBorder(PANELNAME));
+
+ if (wizardInfo.getInstallCertType() != null) {
+ return true;
+ }
+
+ AdminConnection connection = wizardInfo.getAdminConnection();
+ NameValuePairs nvps = new NameValuePairs();
+
+ try {
+ NameValuePairs response = connection.search(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_SUBSYSTEM, nvps);
+ for (String name : response.keySet()) {
+ String type = response.get(name);
+
+ if (type.equals(Constants.PR_RA_INSTANCE))
+ mRASigningCert = mResource.getString(
+ PANELNAME+"_LABEL_RASIGNINGCERT_LABEL");
+ else if (type.equals(Constants.PR_CA_INSTANCE))
+ mCASigningCert = mResource.getString(
+ PANELNAME+"_LABEL_CASIGNINGCERT_LABEL");
+ else if (type.equals(Constants.PR_KRA_INSTANCE))
+ mKRATransportCert = mResource.getString(
+ PANELNAME+"_LABEL_KRATRANSPORTCERT_LABEL");
+ }
+ } catch (EAdminException e) {
+ //showErrorDialog(e.toString());
+ setErrorMessage(e.toString());
+ }
+
+ mOCSPSigningCert = mResource.getString(
+ PANELNAME+"_LABEL_OCSPSIGNINGCERT_LABEL");
+ mServerCert = mResource.getString(
+ PANELNAME+"_LABEL_SERVERCERT_LABEL");
+ mServerCertRadm = mResource.getString(
+ PANELNAME+"_LABEL_SERVERCERTRADM_LABEL");
+ mCrossCert = mResource.getString(
+ PANELNAME+"_LABEL_CROSSCERT_LABEL");
+ mOtherCert = mResource.getString(
+ PANELNAME+"_LABEL_OTHERCERT_LABEL");
+
+ mCertBox.removeAllItems();
+ mCerts.removeAllElements();
+
+ if (mCASigningCert != null) {
+ mCertBox.addItem(mCASigningCert);
+ mCerts.addElement(Constants.PR_CA_SIGNING_CERT);
+ }
+ if (mOCSPSigningCert != null) {
+ mCertBox.addItem(mOCSPSigningCert);
+ mCerts.addElement(Constants.PR_OCSP_SIGNING_CERT);
+ }
+ if (mRASigningCert != null) {
+ mCertBox.addItem(mRASigningCert);
+ mCerts.addElement(Constants.PR_RA_SIGNING_CERT);
+ }
+ if (mKRATransportCert != null) {
+ mCertBox.addItem(mKRATransportCert);
+ mCerts.addElement(Constants.PR_KRA_TRANSPORT_CERT);
+ }
+ if (mServerCert != null) {
+ mCertBox.addItem(mServerCert);
+ mCerts.addElement(Constants.PR_SERVER_CERT);
+ }
+
+ if (mCrossCert != null) {
+ mCertBox.addItem(mCrossCert);
+ mCerts.addElement(Constants.PR_CROSS_CERT);
+ }
+
+ if (mOtherCert != null) {
+ mCertBox.addItem(mOtherCert);
+ mCerts.addElement(Constants.PR_OTHER_CERT);
+ }
+
+ // that means the wizard is launched from the task page
+ if (mode == null) {
+ mCertBox.addItem("Untrusted CA Certificate Chain");
+ mCertBox.addItem("Trusted CA Certificate Chain");
+ }
+
+ mCertBox.setSelectedIndex(0);
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea introLbl = createTextArea(mResource.getString(
+ PANELNAME+"_LABEL_INTRO_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(introLbl, gbc);
+
+ JTextArea opLbl = createTextArea(mResource.getString(
+ PANELNAME+"_LABEL_INSTALLCERT_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(opLbl, gbc);
+
+ mCertBox = makeJComboBox("CERTTYPE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.weighty = 1.0;
+ add(mCertBox, gbc);
+
+ JTextArea dummy = createTextArea(" ", 1, 10);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,COMPONENT_SPACE);
+ add(dummy, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ int index = mCertBox.getSelectedIndex();
+ wizardInfo.addEntry(wizardInfo.INSTALLCERTTYPE, mCerts.elementAt(index));
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WInstallStatusPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WInstallStatusPage.java
new file mode 100644
index 000000000..25022bbb9
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WInstallStatusPage.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Introduction page for certificate setup wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WInstallStatusPage extends WizardBasePanel implements IWizardPanel {
+ private JTextArea mDesc;
+ private static final String PANELNAME = "INSTALLSTATUSWIZARD";
+ private static final String HELPINDEX =
+ "configuration-keycert-wizard-installcertstatus-help";
+
+ WInstallStatusPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WInstallStatusPage(JDialog parent, JFrame frame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = frame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ if (wizardInfo.getOperationType().equals(wizardInfo.REQUESTTYPE))
+ return false;
+ if (wizardInfo.isCertAdded().booleanValue())
+ mDesc.setText(mResource.getString(
+ "INSTALLSTATUSWIZARD_TEXT_SUCCESS_LABEL"));
+ else
+ mDesc.setText(mResource.getString(
+ "INSTALLSTATUSWIZARD_TEXT_FAIL_LABEL"));
+
+ setBorder(makeTitledBorder(PANELNAME));
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ mDesc = createTextArea("");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mDesc, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WIntroInstallCertPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WIntroInstallCertPage.java
new file mode 100644
index 000000000..18c6ef068
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WIntroInstallCertPage.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Introduction page for certificate setup wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WIntroInstallCertPage extends WizardBasePanel implements IWizardPanel {
+ private static final String PANELNAME = "INTROINSTALLCERTWIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WIntroInstallCertPage() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ if (wizardInfo.getOperationType().equals(wizardInfo.REQUESTTYPE))
+ return false;
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea desc = new JTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "INTROINSTALLCERTWIZARD_TEXT_DESC_LABEL"), 80), 2, 80);
+
+ desc.setBackground(getBackground());
+ desc.setEditable(false);
+ desc.setCaretColor(getBackground());
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WIntroPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WIntroPage.java
new file mode 100644
index 000000000..abcec63f3
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WIntroPage.java
@@ -0,0 +1,120 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.keycert;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Introduction page for certificate setup wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WIntroPage extends WizardBasePanel implements IWizardPanel {
+ private static final String PANELNAME = "INTROKEYCERTWIZARD";
+ private static final String HELPINDEX =
+ "configuration-keycert-wizard-introduction-help";
+
+ WIntroPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIntroPage(JDialog parent, JFrame frame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = frame;
+ init();
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ setBorder(makeTitledBorder(PANELNAME));
+ return true;
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ startProgressStatus();
+ AdminConnection connection = wizardInfo.getAdminConnection();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_TOKEN_LIST, "");
+ try {
+ NameValuePairs response = connection.read(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_TOKEN, Constants.RS_ID_CONFIG, nvps);
+ for (String name : response.keySet()) {
+ String value = response.get(name);
+ if (name.equals(Constants.PR_TOKEN_LIST))
+ wizardInfo.addEntry(name, value);
+ }
+ } catch (EAdminException e) {
+ //showErrorDialog(e.toString());
+ setErrorMessage(e.toString());
+ endProgressStatus();
+ return false;
+ }
+ endProgressStatus();
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+/*
+ JTextArea desc = new JTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "INTROKEYCERTWIZARD_TEXT_DESC_LABEL"), 80), 2, 80);
+*/
+ JTextArea desc = createTextArea(mResource.getString(
+ "INTROKEYCERTWIZARD_TEXT_DESC_LABEL"));
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WIssueImportStatusPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WIssueImportStatusPage.java
new file mode 100644
index 000000000..65e02ddd7
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WIssueImportStatusPage.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Introduction page for certificate setup wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WIssueImportStatusPage extends WizardBasePanel implements IWizardPanel {
+ private static final String PANELNAME = "ISSUEIMPORTSTATUSWIZARD";
+ private static final String HELPINDEX =
+ "configuration-keycert-wizard-selfsignedstatus-help";
+ private JTextArea desc;
+
+ WIssueImportStatusPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WIssueImportStatusPage(JDialog parent, JFrame frame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = frame;
+ init();
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ setBorder(makeTitledBorder(PANELNAME));
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ String str = "";
+
+ if (wizardInfo.getOperationType().equals(wizardInfo.REQUESTTYPE) &&
+ (wizardInfo.getCAType().equals(wizardInfo.SELF_SIGNED) ||
+ wizardInfo.isSSLCertLocalCA())) {
+ str = mResource.getString(
+ "ISSUEIMPORTSTATUSWIZARD_TEXT_DESC_LABEL");
+ desc.setText(str);
+ return true;
+ }
+ return false;
+ }
+
+ public boolean isLastPage() {
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ desc = createTextArea("");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WKeyPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WKeyPage.java
new file mode 100644
index 000000000..40d601c1d
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WKeyPage.java
@@ -0,0 +1,809 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.keycert;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+import javax.swing.text.*;
+
+/**
+ * Setup key information for certificate setup wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WKeyPage extends WizardBasePanel implements IWizardPanel, ItemListener {
+ private Color mActiveColor;
+ private JPanel mNicknamePanel;
+ private JRadioButton mExistingKeyBtn;
+ private JRadioButton mNewKeyBtn;
+ private JComboBox mKeyTypeBox, mDSAKeyTypeBox;
+ private JComboBox mKeyLengthBox, mDSAKeyLengthBox, mKeyCurveBox;
+ private JComboBox mTokenBox, mNicknameBox;
+ private JTextField mKeyLengthText;
+ private JTextField mKeyCurveText;
+ private JLabel keyHeading, keyTypeLbl, keyLengthLbl, keyCurveLbl, unitLbl,
+ unit1Lbl, mTokenLbl, mNicknameLbl;
+ private JLabel keyLengthCustomText, keyCurveCustomText;
+ private static final String PANELNAME = "KEYWIZARD";
+ private CertSetupWizardInfo wizardInfo;
+ private static final String HELPINDEX =
+ "configuration-keycert-wizard-key-help";
+
+ WKeyPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WKeyPage(JDialog parent, JFrame frame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = frame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ wizardInfo = (CertSetupWizardInfo)info;
+ if (wizardInfo.getOperationType().equals(wizardInfo.INSTALLTYPE))
+ return false;
+
+ String title = "";
+ String certType = wizardInfo.getCertType();
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT))
+ title = mResource.getString("KEYWIZARD_BORDER_CASIGNING_LABEL");
+ else if (certType.equals(Constants.PR_RA_SIGNING_CERT))
+ title = mResource.getString("KEYWIZARD_BORDER_RASIGNING_LABEL");
+ else if (certType.equals(Constants.PR_KRA_TRANSPORT_CERT))
+ title = mResource.getString("KEYWIZARD_BORDER_KRATRANSPORT_LABEL");
+ else if (certType.equals(Constants.PR_OCSP_SIGNING_CERT))
+ title = mResource.getString("KEYWIZARD_BORDER_OCSPSIGNING_LABEL");
+ else if (certType.equals(Constants.PR_SERVER_CERT) ||
+ certType.equals(Constants.PR_SERVER_CERT_RADM))
+ title = mResource.getString("KEYWIZARD_BORDER_SERVER_LABEL");
+ else if (certType.equals(Constants.PR_OTHER_CERT))
+ title = mResource.getString("KEYWIZARD_BORDER_OTHER_LABEL");
+
+ setBorder(new TitledBorder(title));
+ if (certType.equals(Constants.PR_OTHER_CERT)) {
+ mNicknamePanel.setVisible(true);
+ mNicknameLbl.setVisible(true);
+ mNicknameBox.setVisible(true);
+ if (mNicknameBox.getItemCount() <= 0) {
+ String str = wizardInfo.getNicknames();
+ StringTokenizer tokenizer1 = new StringTokenizer(str, ",");
+ while (tokenizer1.hasMoreTokens()) {
+ mNicknameBox.addItem((String)tokenizer1.nextToken());
+ }
+ }
+ } else {
+ mNicknamePanel.setVisible(false);
+ mNicknameLbl.setVisible(false);
+ mNicknameBox.setVisible(false);
+ }
+
+ if (mTokenBox.getItemCount() > 0) {
+/*
+ if (mNewKeyBtn.isSelected() || certType.equals(Constants.PR_OTHER_CERT)) {
+ mTokenBox.setEnabled(true);
+ mTokenLbl.setEnabled(true);
+ } else {
+ mTokenBox.setEnabled(false);
+ mTokenLbl.setEnabled(false);
+ }
+*/
+ return true;
+ }
+
+ String tokenList = wizardInfo.getTokenList();
+ StringTokenizer tokenizer = new StringTokenizer(tokenList, ",");
+ while (tokenizer.hasMoreTokens()) {
+ mTokenBox.addItem((String)tokenizer.nextToken());
+ }
+
+ mTokenBox.addItemListener(this);
+
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT) ||
+ certType.equals(Constants.PR_RA_SIGNING_CERT) ||
+ certType.equals(Constants.PR_OCSP_SIGNING_CERT) ) {
+ mDSAKeyTypeBox.setVisible(true);
+ mKeyTypeBox.setVisible(false);
+ } else {
+ mDSAKeyTypeBox.setVisible(false);
+ mKeyTypeBox.setVisible(true);
+ }
+
+ String type = (String)mKeyTypeBox.getSelectedItem();
+ if (mDSAKeyTypeBox.isVisible()) {
+ type = (String)mDSAKeyTypeBox.getSelectedItem();
+ }
+
+ setLengthCurveFields(type);
+ enableKeyLengthFields();
+
+ //if (mNewKeyBtn.isSelected() || certType.equals(Constants.PR_OTHER_CERT)) {
+ if (mNewKeyBtn.isSelected()) {
+ mTokenBox.setEnabled(true);
+ mTokenLbl.setEnabled(true);
+ } else {
+ mTokenBox.setEnabled(false);
+ mTokenLbl.setEnabled(false);
+ }
+
+/*
+ if (certType.equals(Constants.PR_SERVER_CERT)) {
+ mKeyLengthBox.removeItem("4096");
+ mKeyLengthBox.setSelectedIndex(0);
+ }
+*/
+
+ if (certType.equals(Constants.PR_SERVER_CERT_RADM)) {
+ mKeyLengthBox.removeItem("768");
+ mKeyLengthBox.removeItem("4096");
+ mKeyLengthBox.removeItem("Custom");
+ mKeyLengthBox.setSelectedIndex(0);
+ }
+
+ CMSAdminUtil.repaintComp(mTokenBox);
+ CMSAdminUtil.repaintComp(mTokenLbl);
+ CMSAdminUtil.repaintComp(mNicknamePanel);
+ CMSAdminUtil.repaintComp(mNicknameLbl);
+ CMSAdminUtil.repaintComp(mNicknameBox);
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ if (mKeyLengthText.isVisible() && mKeyLengthText.isEnabled()) {
+ String str = mKeyLengthText.getText().trim();
+ if (str.equals("")) {
+ setErrorMessage("BLANKLEN");
+ return false;
+ } else {
+ try {
+ int num = Integer.parseInt(str);
+ if (num <= 0) {
+ setErrorMessage("INVALIDKEYLEN");
+ return false;
+ }
+ } catch (NumberFormatException e) {
+ setErrorMessage("NONINTEGER");
+ return false;
+ }
+ }
+ }
+
+ /*
+ if (mKeyCurveText.isVisible() && mKeyCurveText.isEnabled()) {
+ String str = mKeyCurveText.getText().trim();
+ if (str.equals("")) {
+ setErrorMessage("BLANKCURVE");
+ return false;
+ }
+ }*/
+
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ AdminConnection connection = wizardInfo.getAdminConnection();
+ NameValuePairs nvps = new NameValuePairs();
+
+ if (mNewKeyBtn.isSelected()) {
+ String val = "";
+
+ if (mKeyLengthBox.isVisible()) {
+ val = (String)mKeyLengthBox.getSelectedItem();
+ } else if (mKeyCurveBox.isVisible()) {
+ val = (String)mKeyCurveBox.getSelectedItem();
+ } else {
+ if (mDSAKeyLengthBox.isVisible())
+ val = (String)mDSAKeyLengthBox.getSelectedItem();
+ }
+
+ if (val.equals("Custom")) {
+ if (mKeyCurveBox.isVisible()) { // ECC
+ wizardInfo.addEntry(Constants.PR_KEY_CURVENAME,
+ mKeyCurveText.getText().trim());
+ nvps.put(Constants.PR_KEY_CURVENAME, mKeyCurveText.getText().trim());
+ } else {
+ wizardInfo.addEntry(Constants.PR_KEY_LENGTH,
+ mKeyLengthText.getText().trim());
+ nvps.put(Constants.PR_KEY_LENGTH, mKeyLengthText.getText().trim());
+ }
+ } else {
+ if (mKeyCurveBox.isVisible()) { // ECC
+ wizardInfo.addEntry(Constants.PR_KEY_CURVENAME, val.trim());
+ nvps.put(Constants.PR_KEY_CURVENAME, val.trim());
+ } else {
+ wizardInfo.addEntry(Constants.PR_KEY_LENGTH, val.trim());
+ nvps.put(Constants.PR_KEY_LENGTH, val.trim());
+ }
+ }
+
+ if (mKeyTypeBox.isVisible()) {
+ wizardInfo.addEntry(Constants.PR_KEY_TYPE,
+ (String)mKeyTypeBox.getSelectedItem());
+ nvps.put(Constants.PR_KEY_TYPE, (String) mKeyTypeBox.getSelectedItem());
+ } else if (mDSAKeyTypeBox.isVisible()) {
+ wizardInfo.addEntry(Constants.PR_KEY_TYPE,
+ (String)mDSAKeyTypeBox.getSelectedItem());
+ nvps.put(Constants.PR_KEY_TYPE, (String) mDSAKeyTypeBox.getSelectedItem());
+ }
+ }
+
+ startProgressStatus();
+
+ String certType = wizardInfo.getCertType();
+ nvps.put(Constants.PR_SUBJECT_NAME, "");
+ nvps.put(Constants.PR_CERTIFICATE_TYPE, certType);
+
+ try {
+ // validate the key length or curvename
+ if (mKeyCurveBox.isVisible()) { //ECC
+ connection.validate(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_KEY_CURVENAME, nvps);
+ } else {
+ connection.validate(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_KEY_LENGTH, nvps);
+ }
+
+ NameValuePairs response = null;
+ if (!mNewKeyBtn.isSelected()) {
+
+ if (mNicknameBox.isVisible()) {
+ String nicknameStr = (String)mNicknameBox.getSelectedItem();
+ nvps.put(Constants.PR_NICKNAME, nicknameStr);
+ response = connection.process(
+ DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_SUBJECT_NAME,
+ wizardInfo.getCertType(), nvps);
+ wizardInfo.addEntry(Constants.PR_NICKNAME, nicknameStr);
+ } else {
+ response = connection.read(
+ DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_SUBJECT_NAME,
+ wizardInfo.getCertType(), nvps);
+ }
+
+ String value = response.get(Constants.PR_SUBJECT_NAME);
+ wizardInfo.addEntry(Constants.PR_SUBJECT_NAME, value);
+ }
+
+ if (mNewKeyBtn.isSelected()) {
+ String tokenName = (String)mTokenBox.getSelectedItem();
+ if (tokenName.equals("internal"))
+ tokenName = Constants.PR_INTERNAL_TOKEN_NAME;
+ nvps.clear();
+ nvps.put(Constants.PR_TOKEN_NAME, tokenName);
+ response = connection.process(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_TOKEN_STATUS, Constants.RS_ID_CONFIG, nvps);
+
+ String value = response.get(Constants.PR_LOGGED_IN);
+ wizardInfo.addEntry(Constants.PR_LOGGED_IN, value);
+ wizardInfo.addEntry(Constants.PR_TOKEN_NAME, tokenName);
+ }
+ } catch (EAdminException e) {
+ //showErrorDialog(e.toString());
+ setErrorMessage(e.toString());
+ endProgressStatus();
+ return false;
+ }
+
+ endProgressStatus();
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JPanel panel = new JPanel();
+ GridBagLayout gb1 = new GridBagLayout();
+ panel.setLayout(gb1);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ add(panel, gbc);
+
+ JTextArea selectTokenLbl = createTextArea(mResource.getString(
+ PANELNAME+"_LABEL_SELECTTOKEN_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,0);
+ panel.add(selectTokenLbl, gbc);
+
+ mTokenLbl = makeJLabel("TOKEN");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.CENTER;
+ gbc.insets = new Insets(COMPONENT_SPACE, 0,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ panel.add(mTokenLbl, gbc);
+
+ mTokenBox = new JComboBox();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.weightx = 1.0;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ panel.add(mTokenBox, gbc);
+
+ JTextArea dummy2 = createTextArea(" ", 1, 5);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ panel.add(dummy2, gbc);
+
+ JTextArea createKeyLbl = createTextArea(mResource.getString(
+ PANELNAME+"_LABEL_KEYPAIR_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(createKeyLbl, gbc);
+
+ mExistingKeyBtn = makeJRadioButton("OLDKEY", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mExistingKeyBtn, gbc);
+
+ mNicknamePanel = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ mNicknamePanel.setLayout(gb3);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gbc.fill = gbc.BOTH;
+ gbc.weightx = 1.0;
+ add(mNicknamePanel, gbc);
+
+ mNicknameLbl = makeJLabel("NICKNAME");
+ CMSAdminUtil.resetGBC(gbc);
+ //gbc.anchor = gbc.CENTER;
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ //gbc.fill = gbc.NONE;
+ gbc.fill = gbc.HORIZONTAL;
+ mNicknamePanel.add(mNicknameLbl, gbc);
+
+ JLabel dummy18 = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.fill = gbc.HORIZONTAL;
+ mNicknamePanel.add(dummy18, gbc);
+
+ mNicknameBox = new JComboBox();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.fill = gbc.NONE;
+ gbc.fill = gbc.BOTH;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, 2*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ mNicknamePanel.add(mNicknameBox, gbc);
+
+/*
+ JTextArea dummy22 = createTextArea(" ", 1, 5);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ mNicknamePanel.add(dummy22, gbc);
+*/
+
+ mNewKeyBtn = makeJRadioButton("NEWKEY", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mNewKeyBtn, gbc);
+
+ ButtonGroup grp = new ButtonGroup();
+ grp.add(mExistingKeyBtn);
+ grp.add(mNewKeyBtn);
+
+/*
+ JPanel panel = new JPanel();
+ GridBagLayout gb1 = new GridBagLayout();
+ panel.setLayout(gb1);
+*/
+
+ keyHeading = makeJLabel("KEY");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ add(keyHeading, gbc);
+
+ keyTypeLbl = makeJLabel("KEYTYPE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.CENTER;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(keyTypeLbl, gbc);
+
+ mKeyTypeBox = makeJComboBox("KEYTYPE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ add(mKeyTypeBox, gbc);
+
+ mDSAKeyTypeBox = makeJComboBox("DSAKEYTYPE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.NONE;
+ add(mDSAKeyTypeBox, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(dummy, gbc);
+
+ keyLengthLbl = makeJLabel("KEYLENGTH");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.CENTER;
+ gbc.fill = gbc.NONE;
+ //gbc.weighty = 1.0;
+ //gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(keyLengthLbl, gbc);
+ //panel.add(keyLengthLbl, gbc);
+
+ mKeyLengthBox = makeJComboBox("KEYLENGTH");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ //gbc.weighty = 1.0;
+ //gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mKeyLengthBox, gbc);
+ //panel.add(mKeyLengthBox, gbc);
+
+ mDSAKeyLengthBox = makeJComboBox("DSAKEYLENGTH");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ //gbc.weighty = 1.0;
+ //gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mDSAKeyLengthBox, gbc);
+ //panel.add(mDSAKeyLengthBox, gbc);
+
+ keyCurveLbl = makeJLabel("KEYCURVE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.CENTER;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(keyCurveLbl, gbc);
+
+ mKeyCurveBox = makeJComboBox("KEYCURVE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mKeyCurveBox, gbc);
+
+ unitLbl = makeJLabel("UNITS");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.CENTER;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ //gbc.weighty = 1.0;
+ gbc.insets = new Insets(0, 0,COMPONENT_SPACE, COMPONENT_SPACE);
+ add(unitLbl, gbc);
+ //panel.add(unitLbl, gbc);
+
+ JPanel panel1 = new JPanel();
+ GridBagLayout gb2 = new GridBagLayout();
+ panel1.setLayout(gb2);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, 0, 0, 0);
+ add(panel1, gbc);
+
+ keyLengthCustomText = makeJLabel("CUSTOMKEY");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ panel1.add(keyLengthCustomText, gbc);
+
+ keyCurveCustomText = makeJLabel("CUSTOMKEYCURVE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ panel1.add(keyCurveCustomText, gbc);
+
+ mKeyLengthText = makeJTextField(7);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ //gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, 0, 0);
+ panel1.add(mKeyLengthText, gbc);
+ mActiveColor = mKeyLengthText.getBackground();
+
+ mKeyCurveText = makeJTextField(7);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, 0, 0);
+ panel1.add(mKeyCurveText, gbc);
+
+ unit1Lbl = makeJLabel("UNITS");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ //gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, 0, COMPONENT_SPACE);
+ panel1.add(unit1Lbl, gbc);
+
+ JLabel dummy1 = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(dummy1, gbc);
+
+ enableFields(false, getBackground());
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ if (mNewKeyBtn.isSelected()) {
+ wizardInfo.addEntry(wizardInfo.KEY_MATERIAL, Constants.TRUE);
+ } else if (mExistingKeyBtn.isSelected())
+ wizardInfo.addEntry(wizardInfo.KEY_MATERIAL, Constants.FALSE);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ Object source = e.getSource();
+ if (source.equals(mExistingKeyBtn)) {
+ enableFields(false, getBackground());
+ enableKeyLengthFields();
+ mTokenBox.setEnabled(false);
+ mTokenLbl.setEnabled(false);
+ } else if (source.equals(mNewKeyBtn)) {
+ String certType = wizardInfo.getCertType();
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ WarningDialog dialog = new WarningDialog(wizardInfo.getFrame(),
+ "_TEXT_DESC_LABEL");
+ }
+ enableFields(true, mActiveColor);
+ enableKeyLengthFields();
+ mTokenBox.setEnabled(true);
+ mTokenLbl.setEnabled(true);
+ }
+ CMSAdminUtil.repaintComp(mTokenBox);
+ CMSAdminUtil.repaintComp(mTokenLbl);
+ }
+
+ public void setLengthCurveFields(String type) {
+ if (type.equals("RSA")) {
+ mDSAKeyLengthBox.setVisible(false);
+ mKeyLengthBox.setVisible(true);
+ mKeyCurveBox.setVisible(false);
+ keyLengthCustomText.setVisible(true);
+ keyCurveCustomText.setVisible(false);
+ keyLengthLbl.setVisible(true);
+ keyCurveLbl.setVisible(false);
+ unit1Lbl.setVisible(true);
+ unitLbl.setVisible(true);
+ mKeyLengthText.setVisible(true);
+ mKeyCurveText.setVisible(false);
+ } else if (type.equals("ECC")) {
+ mDSAKeyLengthBox.setVisible(false);
+ mKeyLengthBox.setVisible(false);
+ mKeyCurveBox.setVisible(true);
+ keyLengthCustomText.setVisible(false);
+ keyCurveCustomText.setVisible(true);
+ keyLengthLbl.setVisible(false);
+ keyCurveLbl.setVisible(true);
+ unit1Lbl.setVisible(false);
+ unitLbl.setVisible(false);
+ mKeyLengthText.setVisible(false);
+ mKeyCurveText.setVisible(true);
+ } else {
+ mDSAKeyLengthBox.setVisible(true);
+ mKeyLengthBox.setVisible(false);
+ mKeyCurveBox.setVisible(false);
+ keyLengthCustomText.setVisible(true);
+ keyCurveCustomText.setVisible(false);
+ keyLengthLbl.setVisible(true);
+ keyCurveLbl.setVisible(false);
+ unit1Lbl.setVisible(true);
+ unitLbl.setVisible(true);
+ mKeyLengthText.setVisible(true);
+ mKeyCurveText.setVisible(false);
+ }
+ }
+
+
+ public void itemStateChanged(ItemEvent e) {
+ if (e.getSource().equals(mKeyLengthBox) ||
+ e.getSource().equals(mKeyCurveBox) ||
+ e.getSource().equals(mDSAKeyLengthBox)) {
+ enableKeyLengthFields();
+ } else if (e.getSource().equals(mKeyTypeBox) ||
+ e.getSource().equals(mDSAKeyTypeBox)) {
+ String type = "";
+ if (mKeyTypeBox.isVisible())
+ type = (String)mKeyTypeBox.getSelectedItem();
+ else if (mDSAKeyTypeBox.isVisible())
+ type = (String)mDSAKeyTypeBox.getSelectedItem();
+
+ setLengthCurveFields(type);
+ enableKeyLengthFields();
+ CMSAdminUtil.repaintComp(this);
+ }
+ }
+
+ private void enableKeyLengthFields() {
+ String value = "";
+
+ if (mKeyLengthBox.isVisible())
+ value = (String)mKeyLengthBox.getSelectedItem();
+ else if (mKeyCurveBox.isVisible())
+ value = (String)mKeyCurveBox.getSelectedItem();
+ else
+ value = (String)mDSAKeyLengthBox.getSelectedItem();
+
+ if (value.equals("Custom") && mNewKeyBtn.isSelected()) {
+ if (mKeyCurveBox.isVisible()) { //ECC
+ enableFields(keyCurveCustomText, mKeyCurveText, true, mActiveColor);
+ } else {
+ enableFields(keyLengthCustomText, mKeyLengthText, true, mActiveColor);
+ enableFields(unit1Lbl, null, true, mActiveColor);
+ }
+ } else {
+ if (mKeyCurveBox.isVisible()) { //ECC
+ enableFields(keyCurveCustomText, mKeyCurveText, false,
+ getBackground());
+ } else {
+ enableFields(keyLengthCustomText, mKeyLengthText, false,
+ getBackground());
+ enableFields(unit1Lbl, null, false, getBackground());
+ }
+ }
+ }
+
+ protected void enableFields(JComponent comp1, JTextComponent comp2,
+ boolean enable, Color color) {
+ if (comp1 != null) {
+ comp1.setEnabled(enable);
+ CMSAdminUtil.repaintComp(comp1);
+ }
+ if (comp2 != null) {
+ comp2.setEnabled(enable);
+ comp2.setBackground(color);
+ comp2.setEditable(enable);
+ CMSAdminUtil.repaintComp(comp2);
+ }
+ }
+
+ private void enableFields(boolean enable, Color color) {
+ keyHeading.setEnabled(enable);
+ keyTypeLbl.setEnabled(enable);
+ keyLengthLbl.setEnabled(enable);
+ keyCurveLbl.setEnabled(enable);
+ unitLbl.setEnabled(enable);
+ unit1Lbl.setEnabled(enable);
+ keyLengthCustomText.setEnabled(enable);
+ keyCurveCustomText.setEnabled(enable);
+ mKeyLengthText.setEnabled(enable);
+ mKeyLengthText.setEditable(enable);
+ mKeyLengthText.setBackground(color);
+ mKeyCurveText.setEnabled(enable);
+ mKeyCurveText.setEditable(enable);
+ mKeyCurveText.setBackground(color);
+ mKeyTypeBox.setEnabled(enable);
+ mDSAKeyTypeBox.setEnabled(enable);
+ mKeyLengthBox.setEnabled(enable);
+ mKeyCurveBox.setEnabled(enable);
+ mDSAKeyLengthBox.setEnabled(enable);
+ repaintComp(keyHeading);
+ repaintComp(keyTypeLbl);
+ repaintComp(keyLengthLbl);
+ repaintComp(keyCurveLbl);
+ repaintComp(unitLbl);
+ repaintComp(unit1Lbl);
+ repaintComp(keyLengthCustomText);
+ repaintComp(keyCurveCustomText);
+ repaintComp(mKeyLengthText);
+ repaintComp(mKeyCurveText);
+ repaintComp(mKeyTypeBox);
+ repaintComp(mDSAKeyTypeBox);
+ repaintComp(mKeyLengthBox);
+ repaintComp(mKeyCurveBox);
+ repaintComp(mDSAKeyLengthBox);
+ }
+
+ private void repaintComp(JComponent component) {
+ component.invalidate();
+ component.validate();
+ component.repaint(1);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WManualCertRequestPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WManualCertRequestPage.java
new file mode 100644
index 000000000..4ad069133
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WManualCertRequestPage.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.admin.certsrv.keycert;
+
+import java.util.*;
+import java.awt.*;
+import java.io.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.task.*;
+
+/**
+ * Generate cert request page for cert setup wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WManualCertRequestPage extends WBaseManualCertRequestPage implements IWizardPanel {
+
+ 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";
+
+ private static final String PANELNAME = "MANUALCERTREQUESTWIZARD";
+ private static final String HELPINDEX =
+ "configuration-keycert-wizard-displaycertrequest-help";
+
+ WManualCertRequestPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WManualCertRequestPage(JDialog parent, JFrame frame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = frame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+
+ if (wizardInfo.getOperationType().equals(wizardInfo.INSTALLTYPE) ||
+ wizardInfo.getCAType().equals(wizardInfo.SELF_SIGNED))
+ return false;
+
+ String str = wizardInfo.getCSR();
+// mText.setText(CMSAdminUtil.certRequestWrapText(str, 40));
+ mText.setText(str);
+ mText.selectAll();
+ setBorder(makeTitledBorder(PANELNAME));
+
+ CMSServerInfo serverInfo = wizardInfo.getServerInfo();
+ String certType = wizardInfo.getCertType();
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ mDesc.setText(mResource.getString(mPanelName+"_TEXT_CADESC_LABEL"));
+ str = mResource.getString(mPanelName+"_TEXT_CAFILELOC_LABEL");
+ } else if (certType.equals(Constants.PR_OCSP_SIGNING_CERT)) {
+ str = mResource.getString(mPanelName+"_TEXT_OCSPFILELOC_LABEL");
+ mDesc.setText(mResource.getString(mPanelName+"_TEXT_RADESC_LABEL"));
+ } else if (certType.equals(Constants.PR_RA_SIGNING_CERT)) {
+ str = mResource.getString(mPanelName+"_TEXT_RAFILELOC_LABEL");
+ mDesc.setText(mResource.getString(mPanelName+"_TEXT_RADESC_LABEL"));
+ } else if (certType.equals(Constants.PR_KRA_TRANSPORT_CERT)) {
+ str = mResource.getString(mPanelName+"_TEXT_KRAFILELOC_LABEL");
+ mDesc.setText(mResource.getString(mPanelName+"_TEXT_KRADESC_LABEL"));
+ } else if (certType.equals(Constants.PR_SERVER_CERT)) {
+ str = mResource.getString(mPanelName+"_TEXT_SSLFILELOC_LABEL");
+ mDesc.setText(mResource.getString(mPanelName+"_TEXT_SSLDESC_LABEL"));
+ } else if (certType.equals(Constants.PR_SERVER_CERT_RADM)) {
+ str = mResource.getString(mPanelName+"_TEXT_SSLRADMFILELOC_LABEL");
+ mDesc.setText(mResource.getString(mPanelName+"_TEXT_SSLDESC_LABEL"));
+ } else if (certType.equals(Constants.PR_OTHER_CERT)) {
+ str = mResource.getString(mPanelName+"_TEXT_OTHERFILELOC_LABEL");
+ mDesc.setText(mResource.getString(mPanelName+"_TEXT_OTHERDESC_LABEL"));
+ }
+
+ String dir = wizardInfo.getCertRequestDir();
+ mFileName.setText(str+dir+".");
+
+ if (mSendNowBox.isSelected())
+ enableFields(true, mActiveColor);
+ else
+ enableFields(false, getBackground());
+ String host = wizardInfo.getCMHost();
+ if (host != null && !host.equals(""))
+ mHostText.setText(host);
+ String port = wizardInfo.getCMEEPort();
+ if (port != null && !port.equals(""))
+ mPortText.setText(port);
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return super.validatePanel();
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ if (!mSendNowBox.isSelected())
+ return true;
+
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ if (mHost != null && !mHost.equals(""))
+ wizardInfo.setCMHost(mHost);
+ if (mPort != null && !mPort.equals(""))
+ wizardInfo.setCMEEPort(mPort);
+ if (mSSL.isSelected())
+ wizardInfo.setCMEEType("https");
+ else
+ wizardInfo.setCMEEType("http");
+
+ CMSCertRequest requestCertCgi = new CMSCertRequest();
+ requestCertCgi.initialize(wizardInfo);
+ Hashtable data = new Hashtable();
+
+ String certType = null;
+
+ String mReqType = wizardInfo.getCertType();
+ String mReq = null;
+
+ mReq = wizardInfo.getCSR();
+
+ if (mReqType.equals(Constants.PR_CA_SIGNING_CERT)){
+ data.put("profileId", "caCACert");
+ }else if (mReqType.equals(Constants.PR_SERVER_CERT) ||
+ mReqType.equals(Constants.PR_KRA_TRANSPORT_CERT)){
+ data.put("profileId", "caServerCert");
+ }else if (mReqType.equals(Constants.PR_OCSP_SIGNING_CERT)){
+ data.put("profileId", "caOCSPCert");
+ }else if (mReqType.equals(Constants.PR_RA_SIGNING_CERT)){
+ data.put("profileId", "caRACert");
+ }else if (mReqType.equals(Constants.PR_OTHER_CERT)) {
+ data.put("profileId", "caOtherCert");
+ } else {
+ data.put("profileId", mReqType);
+ }
+
+ data.put("cert_request_type", "pkcs10");
+ data.put("cert_request", mReq);
+
+ startProgressStatus();
+ boolean ready = requestCertCgi.requestCert(data);
+ endProgressStatus();
+
+ if (!ready) {
+ String str = requestCertCgi.getErrorMessage();
+ if (str.equals(""))
+ setErrorMessage("Server Error");
+ else
+ setErrorMessage(str);
+ }
+
+ wizardInfo.setRequestSent(ready);
+ return ready;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WOperationSelectionPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WOperationSelectionPage.java
new file mode 100644
index 000000000..f2cdeff3d
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WOperationSelectionPage.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Operation Selection page for certificate setup wizard
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WOperationSelectionPage extends WizardBasePanel implements IWizardPanel {
+ private JRadioButton mInstallBtn;
+ private JRadioButton mRequestBtn;
+ private JComboBox mToken;
+ private static final String PANELNAME = "OPERATIONSELECTIONWIZARD";
+ private static final String HELPINDEX =
+ "configuration-keycert-wizard-operationselection-help";
+
+ WOperationSelectionPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WOperationSelectionPage(JDialog parent, JFrame frame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = frame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ String mode = wizardInfo.getMode();
+ // Fixes Bugscape Bug #55862: console - Certificate Setup Wizard
+ // throws Null Pointer Exception
+ if (mode != null && mode.equals("0")) {
+ info.addEntry(wizardInfo.OPTYPE, wizardInfo.INSTALLTYPE);
+ return false;
+ }
+ setBorder(makeTitledBorder(PANELNAME));
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ startProgressStatus();
+ if (mRequestBtn.isSelected())
+ info.addEntry(wizardInfo.OPTYPE, wizardInfo.REQUESTTYPE);
+ else
+ info.addEntry(wizardInfo.OPTYPE, wizardInfo.INSTALLTYPE);
+ endProgressStatus();
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JTextArea operationTypeLbl = createTextArea(mResource.getString(
+ PANELNAME+"_LABEL_OPERATIONTYPE_LABEL"));
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(operationTypeLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRequestBtn = makeJRadioButton("REQUEST", true);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mRequestBtn, gbc);
+
+ ButtonGroup btnGroup = new ButtonGroup();
+ CMSAdminUtil.resetGBC(gbc);
+ mInstallBtn = makeJRadioButton("INSTALL", false);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(0,COMPONENT_SPACE,COMPONENT_SPACE, 0);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mInstallBtn, gbc);
+
+ btnGroup.add(mInstallBtn);
+ btnGroup.add(mRequestBtn);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WOtherCertRequest1Page.java b/base/console/src/com/netscape/admin/certsrv/keycert/WOtherCertRequest1Page.java
new file mode 100644
index 000000000..1dbd614d1
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WOtherCertRequest1Page.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Certificate Request from certificate setup wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WOtherCertRequest1Page extends WizardBasePanel implements IWizardPanel {
+ private JRadioButton mExistingKeyBtn;
+ private JRadioButton mNewKeyBtn;
+ private JRadioButton mEmailBtn;
+ private JRadioButton mURLBtn;
+ private JRadioButton mManualBtn;
+ private static final String PANELNAME = "CACERTREQUESTWIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WOtherCertRequest1Page() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ if (wizardInfo.getOperationType().equals(wizardInfo.INSTALLTYPE))
+ return false;
+
+ String type = wizardInfo.getCertType();
+ if (type.equals(Constants.PR_CA_SIGNING_CERT))
+ return false;
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+
+ if (mNewKeyBtn.isSelected())
+ wizardInfo.addEntry(wizardInfo.KEY_MATERIAL, Constants.TRUE);
+ else if (mExistingKeyBtn.isSelected())
+ wizardInfo.addEntry(wizardInfo.KEY_MATERIAL, Constants.FALSE);
+
+ if (mEmailBtn.isSelected())
+ wizardInfo.addEntry(wizardInfo.SUBMIT_METHOD, wizardInfo.CA_EMAIL);
+ else if (mURLBtn.isSelected())
+ wizardInfo.addEntry(wizardInfo.SUBMIT_METHOD, wizardInfo.CA_URL);
+ else if (mManualBtn.isSelected())
+ wizardInfo.addEntry(wizardInfo.SUBMIT_METHOD, wizardInfo.MANUAL);
+
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ JTextArea methodText = createTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "CACERTREQUESTWIZARD_TEXT_METHOD_LABEL"), 80), 2, 80);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(methodText, gbc);
+
+ mEmailBtn = makeJRadioButton("EMAIL", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mEmailBtn, gbc);
+
+ mURLBtn = makeJRadioButton("URL", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mURLBtn, gbc);
+
+ mManualBtn = makeJRadioButton("MANUAL", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mManualBtn, gbc);
+
+ JLabel keyLbl = makeJLabel("KEYPAIR");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(keyLbl, gbc);
+
+ mExistingKeyBtn = makeJRadioButton("OLDKEY", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mExistingKeyBtn, gbc);
+
+ mNewKeyBtn = makeJRadioButton("NEWKEY", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(mNewKeyBtn, gbc);
+
+ ButtonGroup methodGroup = new ButtonGroup();
+ methodGroup.add(mURLBtn);
+ methodGroup.add(mManualBtn);
+ methodGroup.add(mEmailBtn);
+
+ ButtonGroup keyGroup = new ButtonGroup();
+ keyGroup.add(mExistingKeyBtn);
+ keyGroup.add(mNewKeyBtn);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WPasteCertPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WPasteCertPage.java
new file mode 100644
index 000000000..50e14a50e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WPasteCertPage.java
@@ -0,0 +1,261 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.keycert;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * This page is to install the certificate in the internal token. The user can
+ * import the cert from the file or paste the Base 64 encoded blob in the
+ * text area.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WPasteCertPage extends WizardBasePanel implements IWizardPanel {
+ private JRadioButton mFileBtn;
+ private JRadioButton mBase64Btn;
+ private JTextField mFileText;
+ private JTextArea mBase64Text;
+ private JButton mPaste;
+ private JTextArea introLbl;
+ private Color mActiveColor;
+ private String mCertContent = "";
+ private String mCertFilePath = "";
+ private static final String PANELNAME = "PASTECERTWIZARD";
+ private static final String HELPINDEX =
+ "configuration-keycert-wizard-pastecert-help";
+
+ WPasteCertPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WPasteCertPage(JDialog parent, JFrame frame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = frame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ if (wizardInfo.getOperationType().equals(wizardInfo.REQUESTTYPE))
+ return false;
+ setBorder(makeTitledBorder(PANELNAME));
+ return true;
+ }
+
+ public boolean validatePanel() {
+ if (mBase64Btn.isSelected()) {
+ mCertContent = mBase64Text.getText().trim();
+ if (mCertContent.equals("")) {
+ setErrorMessage("B64EEMPTY");
+ return false;
+ }
+ } else if (mFileBtn.isSelected()) {
+ mCertFilePath = mFileText.getText().trim();
+ if (mCertFilePath.equals("")) {
+ setErrorMessage("EMPTYFILE");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ startProgressStatus();
+ wizardInfo.addEntry(Constants.PR_PKCS10, mCertContent);
+ //cert = CMSAdminUtil.getPureString(mBase64Text.getText().trim());
+
+ AdminConnection connection = wizardInfo.getAdminConnection();
+ NameValuePairs nvps = new NameValuePairs();
+
+ if (mFileBtn.isSelected()) {
+ nvps.put(Constants.PR_CERT_FILEPATH, mCertFilePath);
+ wizardInfo.setCertFilePath(mCertFilePath);
+ wizardInfo.setPKCS10("");
+ } else if (mBase64Btn.isSelected()) {
+ nvps.put(Constants.PR_PKCS10, mCertContent);
+ wizardInfo.setPKCS10(mCertContent);
+ wizardInfo.setCertFilePath("");
+ }
+
+ try {
+ NameValuePairs response = connection.process(
+ DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_CERTINFO, wizardInfo.getInstallCertType(), nvps);
+
+ for (String name : response.keySet()) {
+ String str = response.get(name);
+ wizardInfo.addEntry(name, str);
+ }
+/*
+ for (int i=0; i<response.size(); i++) {
+ NameValuePair nvp = response.elementAt(i);
+ String name = nvp.getName();
+ String str = nvp.getValue();
+ wizardInfo.addEntry(name, str);
+ }
+*/
+ } catch (EAdminException e) {
+ //showErrorDialog(e.toString());
+ setErrorMessage(e.toString());
+ endProgressStatus();
+ return false;
+ }
+
+ endProgressStatus();
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ introLbl = createTextArea(mResource.getString(
+ PANELNAME+"_LABEL_INTRO_LABEL"));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(introLbl, gbc);
+
+ mFileBtn = makeJRadioButton("FILE", true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mFileBtn, gbc);
+
+ mFileText = makeJTextField(50);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE, COMPONENT_SPACE, 0);
+ add(mFileText, gbc);
+ mActiveColor = mFileText.getBackground();
+
+ mBase64Btn = makeJRadioButton("BASE64", false);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mBase64Btn, gbc);
+
+ JTextArea desc = createTextArea(mResource.getString(
+ "PASTECERTWIZARD_TEXT_DESC_LABEL"));
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,4*COMPONENT_SPACE,0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ mBase64Text = new JTextArea(null, null, 0, 0);
+ Font f = new Font("Monospaced", Font.PLAIN, 12);
+ if (f != null) mBase64Text.setFont(f);
+ JScrollPane scrollPane = new JScrollPane(mBase64Text,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ scrollPane.setPreferredSize(new Dimension(50, 20));
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, 4*COMPONENT_SPACE, 0,
+ COMPONENT_SPACE);
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(scrollPane, gbc);
+
+ mPaste = makeJButton("PASTE");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,0,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mPaste, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ add(dummy, gbc);
+
+ ButtonGroup buttonGrp = new ButtonGroup();
+ buttonGrp.add(mFileBtn);
+ buttonGrp.add(mBase64Btn);
+
+ enableFields(mFileText, true, mActiveColor);
+ enableFields(mBase64Text, false, getBackground());
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mPaste)) {
+ mBase64Text.paste();
+ } else if (e.getSource().equals(mFileBtn)) {
+ enableFields(mFileText, true, mActiveColor);
+ enableFields(mBase64Text, false, getBackground());
+ } else if (e.getSource().equals(mBase64Btn)) {
+ enableFields(mFileText, false, getBackground());
+ enableFields(mBase64Text, true, mActiveColor);
+ }
+ }
+
+ private void enableFields(JTextComponent comp1, boolean enable, Color color) {
+ comp1.setEnabled(enable);
+ comp1.setEditable(enable);
+ comp1.setBackground(color);
+ CMSAdminUtil.repaintComp(comp1);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WRAKeyPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WRAKeyPage.java
new file mode 100644
index 000000000..616deb74f
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WRAKeyPage.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * Setup CA signing cert for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WRAKeyPage extends WBaseKeyPage implements IWizardPanel {
+ private static final String PANELNAME = "RAKEYWIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WRAKeyPage() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WRequestStatusPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WRequestStatusPage.java
new file mode 100644
index 000000000..a52def44a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WRequestStatusPage.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.install.*;
+
+/**
+ * Request status page for certificate setup wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WRequestStatusPage extends WizardBasePanel implements IWizardPanel {
+ private static final String PANELNAME = "REQUESTSTATUSWIZARD";
+ private static final String HELPINDEX =
+ "configuration-keycert-wizard-certrequeststatus-help";
+ protected JTextArea mDesc;
+
+ protected String mRequestId;
+
+ WRequestStatusPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WRequestStatusPage(JDialog parent, JFrame frame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = frame;
+ init();
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ setBorder(makeTitledBorder(PANELNAME));
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+
+ if (!wizardInfo.requestSent()) {
+ String str = "";
+ if (wizardInfo.getOperationType().equals(wizardInfo.REQUESTTYPE) &&
+ (!wizardInfo.getCAType().equals(wizardInfo.SELF_SIGNED))) {
+ str = mResource.getString(
+ "REQUESTSTATUSWIZARD_TEXT_REQUEST_LABEL");
+ mDesc.setText(str);
+ return true;
+ }
+ return false;
+ } else {
+ String status = wizardInfo.getRequestStatus();
+ String str = wizardInfo.getRequestID();
+ String error = wizardInfo.getRequestError();
+
+ if (str != null && !str.equals("")) {
+ if (status != null && status.equals("5")) {
+ // rejected
+ mDesc.setText(mResource.getString("REQUESTRESULTWIZARD_TEXT_REJECT_LABEL") + error + "\n\n"+ mResource.getString("REQUESTRESULTWIZARD_TEXT_ID_LABEL") + str + mResource.getString("REQUESTRESULTWIZARD_TEXT_REJECTEND_LABEL"));
+ } else {
+ // success
+ mDesc.setText(mResource.getString("REQUESTRESULTWIZARD_TEXT_DESC_LABEL") +
+ mResource.getString("REQUESTRESULTWIZARD_TEXT_ID_LABEL") + str +
+ mResource.getString("REQUESTRESULTWIZARD_TEXT_END_LABEL"));
+ }
+ }
+ else if (error != null)
+ mDesc.setText(error);
+ else
+ mDesc.setText(mResource.getString("REQUESTRESULTWIZARD_TEXT_DESC_LABEL") +
+ mResource.getString("REQUESTRESULTWIZARD_TEXT_NOID_LABEL"));
+ }
+ return true;
+ }
+
+ public boolean isLastPage() {
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ mDesc = createTextArea(" ");
+ //mDesc = createTextArea("request id");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mDesc, gbc);
+
+ JLabel label = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(label, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WSSLKeyPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WSSLKeyPage.java
new file mode 100644
index 000000000..7065f68b6
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WSSLKeyPage.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.config.*;
+
+/**
+ * Setup CA signing cert for installation wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config.install
+ */
+class WSSLKeyPage extends WBaseKeyPage implements IWizardPanel {
+ private static final String PANELNAME = "SSLKEYWIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WSSLKeyPage() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WTokenLogonPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WTokenLogonPage.java
new file mode 100644
index 000000000..53a623d0a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WTokenLogonPage.java
@@ -0,0 +1,178 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.keycert;
+
+import java.awt.*;
+import javax.swing.*;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * This panel asks for the user to logon to the keycert token .
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WTokenLogonPage extends WizardBasePanel implements IWizardPanel {
+ protected JLabel mTokenNameText;
+ protected JPasswordField mPasswordText, mPasswordAgainText;
+ private static final String EMPTYSTR = " ";
+ protected JTextArea mDesc;
+ protected String mTokenName;
+ private static final String PANELNAME = "TOKENLOGONWIZARD";
+ private static final String HELPINDEX =
+ "configuration-keycert-wizard-tokenlogon-help";
+
+ WTokenLogonPage(JDialog parent) {
+ super(PANELNAME);
+ mParent = parent;
+ init();
+ }
+
+ WTokenLogonPage(JDialog parent, JFrame frame) {
+ super(PANELNAME);
+ mParent = parent;
+ mAdminFrame = frame;
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ setBorder(makeTitledBorder(mPanelName));
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+
+ if (!wizardInfo.isNewKey() || wizardInfo.isLoggedIn())
+ return false;
+
+ mDesc.setText(mResource.getString(mPanelName+"_TEXT_HEADING_LABEL"));
+ mTokenNameText.setText(wizardInfo.getTokenName());
+
+ return true;
+ }
+
+ public boolean validatePanel() {
+ String passwd = mPasswordText.getText();
+ if (passwd.equals("")) {
+ setErrorMessage("BLANKPASSWD");
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ AdminConnection connection = wizardInfo.getAdminConnection();
+ String tokenname = mTokenNameText.getText().trim();
+
+ if (tokenname.equals("internal")) {
+ tokenname = Constants.PR_INTERNAL_TOKEN_NAME;
+ }
+
+ String pwd = mPasswordText.getText().trim();
+ startProgressStatus();
+
+ try {
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_TOKEN_NAME, tokenname);
+ nvps.put(Constants.PR_TOKEN_PASSWD, pwd);
+ connection.modify(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_TOKEN_LOGON, Constants.RS_ID_CONFIG, nvps);
+ } catch (EAdminException e) {
+ setErrorMessage(e.toString());
+ endProgressStatus();
+ return false;
+ }
+
+ endProgressStatus();
+
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mDesc = createTextArea("");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mDesc, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel tokenLabel = makeJLabel("TOKEN");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(tokenLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mTokenNameText = new JLabel(" ");
+ gbc.anchor = gbc.NORTHWEST;
+ //gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mTokenNameText, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel passwordLabel = makeJLabel("PWD");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(passwordLabel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPasswordText = makeJPasswordField(30);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0, COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ add(mPasswordText, gbc);
+
+ JLabel dummy = new JLabel(" ");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ add(dummy, gbc);
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WTokenSelectionPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WTokenSelectionPage.java
new file mode 100644
index 000000000..b595e1ffd
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WTokenSelectionPage.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Token Selection page for certificate setup wizard
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WTokenSelectionPage extends WizardBasePanel implements IWizardPanel {
+ private JRadioButton mInstallBtn;
+ private JRadioButton mRequestBtn;
+ private JComboBox mToken;
+ private static final String PANELNAME = "TOKENSELECTIONWIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WTokenSelectionPage() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ String tokenList = (String)wizardInfo.getEntry(Constants.PR_TOKEN_LIST);
+ StringTokenizer tokenizer = new StringTokenizer(tokenList, ",");
+ while (tokenizer.hasMoreTokens()) {
+ mToken.addItem((String)tokenizer.nextToken());
+ }
+ return true;
+ }
+
+ public boolean validatePanel() {
+ return true;
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ info.addEntry(wizardInfo.TOKENNAME, (String)mToken.getSelectedItem());
+ if (mRequestBtn.isSelected())
+ info.addEntry(wizardInfo.OPTYPE, wizardInfo.REQUESTTYPE);
+ else
+ info.addEntry(wizardInfo.OPTYPE, wizardInfo.INSTALLTYPE);
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel operationTypeLbl = makeJLabel("OPERATIONTYPE");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(operationTypeLbl, gbc);
+
+ ButtonGroup btnGroup = new ButtonGroup();
+ CMSAdminUtil.resetGBC(gbc);
+ mInstallBtn = makeJRadioButton("INSTALL", true);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,4*COMPONENT_SPACE,
+ COMPONENT_SPACE, 0);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mInstallBtn, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mRequestBtn = makeJRadioButton("REQUEST", false);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(0, 4*COMPONENT_SPACE, 2*COMPONENT_SPACE,
+ COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mRequestBtn, gbc);
+
+ btnGroup.add(mInstallBtn);
+ btnGroup.add(mRequestBtn);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel tokenTypeLbl = makeJLabel("TOKENSELECTION");
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(tokenTypeLbl, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel tokenLbl = makeJLabel("TOKEN");
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.weighty = 0.0;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,4*COMPONENT_SPACE, COMPONENT_SPACE,0);
+ add(tokenLbl, gbc);
+
+ mToken = new JComboBox();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.fill = gbc.NONE;
+ gbc.weighty = 0.0;
+ gbc.insets = new Insets(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(mToken, gbc);
+
+ JTextArea dummy2 = createTextArea(" ", 1, 20);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ add(dummy2, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WWarningExecute1Page.java b/base/console/src/com/netscape/admin/certsrv/keycert/WWarningExecute1Page.java
new file mode 100644
index 000000000..be844576c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WWarningExecute1Page.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Introduction page for certificate setup wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WWarningExecute1Page extends WizardBasePanel implements IWizardPanel {
+ private JButton mAgree;
+ private boolean mIsAgree = false;
+ private static final String PANELNAME = "WARNINGEXECUTE1WIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WWarningExecute1Page() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ if (wizardInfo.getOperationType().equals(wizardInfo.REQUESTTYPE) &&
+ wizardInfo.isNewKey() &&
+ wizardInfo.getCertType().equals(Constants.PR_CA_SIGNING_CERT) &&
+ wizardInfo.getCAType().equals(wizardInfo.SUBORDINATE_CA))
+ return true;
+
+ return false;
+ }
+
+ public boolean validatePanel() {
+ if (mIsAgree)
+ return true;
+ else {
+ setErrorMessage("PROCEED");
+ return false;
+ }
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ AdminConnection connection = wizardInfo.getAdminConnection();
+ NameValuePairs nvps = wizardInfo.getNameValuePairs();
+ try {
+ NameValuePairs response = connection.process(
+ DestDef.DEST_SERVER_ADMIN, ScopeDef.SC_CERT_REQUEST,
+ wizardInfo.getCertType(), nvps);
+ for (String key : response.keySet()) {
+ String value = response.get(key);
+ if (key.equals(Constants.PR_CSR)) {
+ wizardInfo.addEntry(Constants.PR_CSR, value);
+ break;
+ }
+ }
+ } catch (EAdminException e) {
+ setErrorMessage(e.toString());
+ return false;
+ }
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ Icon icon = CMSAdminUtil.getImage(CMSAdminResources.IMAGE_WARN_ICON);
+
+ JLabel label = new JLabel(icon);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(label, gbc);
+
+ JTextArea desc = new JTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "WARNINGEXECUTE1WIZARD_TEXT_DESC_LABEL"), 80), 3, 80);
+
+ desc.setBackground(getBackground());
+ desc.setEditable(false);
+ desc.setCaretColor(getBackground());
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ JTextArea desc1 = new JTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "WARNINGEXECUTE1WIZARD_LABEL_WARNING_LABEL"), 60), 3, 60);
+ desc1.setBackground(getBackground());
+ desc1.setEditable(false);
+ desc1.setCaretColor(getBackground());
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(desc1, gbc);
+
+ mAgree = makeJButton("OK");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mAgree, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mAgree)) {
+ mIsAgree = true;
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WWarningExecutePage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WWarningExecutePage.java
new file mode 100644
index 000000000..a64f67188
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WWarningExecutePage.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.admin.certsrv.keycert;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Introduction page for certificate setup wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WWarningExecutePage extends WizardBasePanel implements IWizardPanel {
+ private JButton mAgree;
+ private boolean mIsAgree = false;
+ private static final String PANELNAME = "WARNINGEXECUTEWIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WWarningExecutePage() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ if (wizardInfo.getOperationType().equals(wizardInfo.REQUESTTYPE) &&
+ wizardInfo.isNewKey() &&
+ wizardInfo.getCertType().equals(Constants.PR_CA_SIGNING_CERT) &&
+ wizardInfo.getCAType().equals(wizardInfo.SELF_SIGNED))
+ return true;
+
+ return false;
+ }
+
+ public boolean validatePanel() {
+ if (mIsAgree)
+ return true;
+ else {
+ setErrorMessage("PROCEED");
+ return false;
+ }
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+ AdminConnection connection = wizardInfo.getAdminConnection();
+ NameValuePairs nvps = wizardInfo.getNameValuePairs();
+ try {
+ connection.modify(
+ DestDef.DEST_SERVER_ADMIN, ScopeDef.SC_ISSUE_IMPORT_CERT,
+ wizardInfo.getCertType(), nvps);
+ } catch (EAdminException e) {
+ setErrorMessage(e.toString());
+ return false;
+ }
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ Icon icon = CMSAdminUtil.getImage(CMSAdminResources.IMAGE_WARN_ICON);
+
+ JLabel label = new JLabel(icon);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(label, gbc);
+
+ JTextArea desc = new JTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "WARNINGEXECUTEWIZARD_TEXT_DESC_LABEL"), 80), 3, 80);
+
+ desc.setBackground(getBackground());
+ desc.setEditable(false);
+ desc.setCaretColor(getBackground());
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ JTextArea desc1 = new JTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "WARNINGEXECUTEWIZARD_LABEL_WARNING_LABEL"), 60), 3, 60);
+ desc1.setBackground(getBackground());
+ desc1.setEditable(false);
+ desc1.setCaretColor(getBackground());
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(desc1, gbc);
+
+ mAgree = makeJButton("OK");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mAgree, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mAgree)) {
+ mIsAgree = true;
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/keycert/WWarningPage.java b/base/console/src/com/netscape/admin/certsrv/keycert/WWarningPage.java
new file mode 100644
index 000000000..7a4eabe57
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/keycert/WWarningPage.java
@@ -0,0 +1,143 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.keycert;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.wizard.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Introduction page for certificate setup wizard.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.keycert
+ */
+class WWarningPage extends WizardBasePanel implements IWizardPanel {
+ private JButton mAgree;
+ private boolean mIsAgree = false;
+ private static final String PANELNAME = "WARNINGWIZARD";
+ private static final String HELPINDEX =
+ "configuration-kra-wizard-change-keyscheme-help";
+
+ WWarningPage() {
+ super(PANELNAME);
+ init();
+ }
+
+ public boolean isLastPage() {
+ return false;
+ }
+
+ public boolean initializePanel(WizardInfo info) {
+ CertSetupWizardInfo wizardInfo = (CertSetupWizardInfo)info;
+
+ if (wizardInfo.getOperationType().equals(wizardInfo.REQUESTTYPE) &&
+ wizardInfo.isNewKey() &&
+ wizardInfo.getCertType().equals(Constants.PR_CA_SIGNING_CERT))
+ return true;
+
+ return false;
+ }
+
+ public boolean validatePanel() {
+ if (mIsAgree)
+ return true;
+ else {
+ setErrorMessage("PROCEED");
+ return false;
+ }
+ }
+
+ public boolean concludePanel(WizardInfo info) {
+ return true;
+ }
+
+ public void callHelp() {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+
+ protected void init() {
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ setLayout(gb);
+
+ Icon icon = CMSAdminUtil.getImage(CMSAdminResources.IMAGE_WARN_ICON);
+
+ JLabel label = new JLabel(icon);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(label, gbc);
+
+ JTextArea desc = new JTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "WARNINGWIZARD_TEXT_DESC_LABEL"), 80), 3, 80);
+
+ desc.setBackground(getBackground());
+ desc.setEditable(false);
+ desc.setCaretColor(getBackground());
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(desc, gbc);
+
+ JTextArea desc1 = new JTextArea(
+ CMSAdminUtil.wrapText(mResource.getString(
+ "WARNINGWIZARD_LABEL_WARNING_LABEL"), 80), 1, 80);
+ desc1.setBackground(getBackground());
+ desc1.setEditable(false);
+ desc1.setCaretColor(getBackground());
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ add(desc1, gbc);
+
+ mAgree = makeJButton("OK");
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ add(mAgree, gbc);
+
+ super.init();
+ }
+
+ public void getUpdateInfo(WizardInfo info) {
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mAgree)) {
+ mIsAgree = true;
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/managecert/CertificateInfoDialog.java b/base/console/src/com/netscape/admin/certsrv/managecert/CertificateInfoDialog.java
new file mode 100644
index 000000000..3a5c43705
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/managecert/CertificateInfoDialog.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.admin.certsrv.managecert;
+
+import com.netscape.admin.certsrv.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Certificate Information dialog
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.managecert
+ */
+public class CertificateInfoDialog extends JDialog
+ implements ActionListener {
+ private String PREFIX = "CERTINFODIALOG";
+
+ private JFrame mParent;
+ private ResourceBundle mResource;
+ private JTextArea mTextArea;
+ private JLabel mCertNameField, mStatusLbl;
+ private JButton mClose, mHelp, mTrust;
+ private AdminConnection mConn;
+ private String mCertName;
+ private String mCertDate;
+ private JButton mActionBtn;
+ private static final String HELPINDEX =
+ "configuration-managecert-wizard-trustcert-help";
+
+ JLabel changeLbl = null;
+
+ public CertificateInfoDialog(JFrame parent) {
+ super(parent,true);
+ mParent = parent;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ setSize(650, 400);
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ setDisplay();
+ }
+
+ public void showDialog(String name, String content, String trust) {
+ mCertNameField.setText(name);
+ mTextArea.setText(content);
+ String actionStr = "";
+ String statusStr = "";
+ if (trust.equals("Trust")) {
+ //mTrust.setText(" Trust ");
+ actionStr = mResource.getString(PREFIX+"_BUTTON_UNTRUST_LABEL");
+ statusStr = mResource.getString(PREFIX+"_LABEL_TRUSTSTATUS_LABEL");
+ mActionBtn.setText(actionStr);
+ mStatusLbl.setText(statusStr);
+ } else if (trust.equals("Untrust")){
+ //mTrust.setText(trust);
+ actionStr = mResource.getString(PREFIX+"_BUTTON_TRUST_LABEL");
+ statusStr = mResource.getString(PREFIX+"_LABEL_UNTRUSTSTATUS_LABEL");
+ mActionBtn.setText(actionStr);
+ mStatusLbl.setText(statusStr);
+ } else { /* user certs can't be changed */
+ actionStr = mResource.getString(PREFIX+"_BUTTON_USER_LABEL");
+ statusStr = mResource.getString(PREFIX+"_LABEL_USER_LABEL");
+ mActionBtn.setText(actionStr);
+ mActionBtn.setEnabled(false);
+ mStatusLbl.setText(statusStr);
+ changeLbl.setEnabled(false);
+ }
+ this.show();
+ }
+
+ public void showDialog(String name, String content, String trust,
+ String date, AdminConnection conn) {
+ mConn = conn;
+ mCertName = name;
+ mCertDate = date;
+ showDialog(name, content, trust);
+ }
+
+ public void actionPerformed(ActionEvent evt) {
+ if (evt.getSource().equals(mClose)) {
+ this.hide();
+ this.dispose();
+ } else if (evt.getSource().equals(mActionBtn)) {
+ String trustLbl = mActionBtn.getText().trim();
+ String trustaction = mResource.getString(PREFIX+"_BUTTON_TRUST_LABEL");
+ String untrustaction = mResource.getString(PREFIX+"_BUTTON_UNTRUST_LABEL");
+ String trust = "";
+ if (trustLbl.equals(trustaction))
+ trust = "Trust";
+ else if (trustLbl.equals(untrustaction))
+ trust = "Untrust";
+ else // user certs not to be changable
+ return;
+
+ NameValuePairs nvps = new NameValuePairs();
+ String value = mCertName+";"+mCertDate;
+ nvps.put("certName0", value);
+
+ try {
+ mConn.modify(DestDef.DEST_SERVER_ADMIN, ScopeDef.SC_TRUST,
+ trust, nvps);
+ String actionStr = "";
+ String statusStr = "";
+ if (trust.equals("Trust")) {
+ actionStr = mResource.getString(PREFIX+"_BUTTON_UNTRUST_LABEL");
+ statusStr = mResource.getString(PREFIX+"_LABEL_TRUSTSTATUS_LABEL");
+ } else {
+ actionStr = mResource.getString(PREFIX+"_BUTTON_TRUST_LABEL");
+ statusStr = mResource.getString(PREFIX+"_LABEL_UNTRUSTSTATUS_LABEL");
+ }
+
+ mActionBtn.setText(actionStr);
+ mStatusLbl.setText(statusStr);
+ } catch (EAdminException ex) {
+ CMSAdminUtil.showErrorDialog(mParent, mResource, ex.toString(),
+ CMSAdminUtil.ERROR_MESSAGE);
+ }
+ } else if (evt.getSource().equals(mHelp)) {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+ }
+
+/*
+ private void refresh() {
+ try {
+ NameValuePairs results = mConn.process(
+ DestDef.DEST_SERVER_ADMIN, ScopeDef.SC_CERT_PRETTY_PRINT,
+ Constants.RS_ID_CONFIG, nvps);
+ if (nvps.size() <= 0)
+ return;
+ NameValuePair nvp = results.elementAt(0);
+ String name = nvp.getName();
+ String value = nvp.getValue();
+ CertificateInfoDialog dialog = new CertificateInfoDialog(mParent);
+ dialog.showDialog(name, value);
+ } catch (EAdminException ex) {
+ CMSAdminUtil.showErrorDialog(mParent, mResource, ex.toString(),
+ CMSAdminUtil.ERROR_MESSAGE);
+ }
+ }
+*/
+
+ private void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.BOTH;
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ private JPanel makeActionPane() {
+ mClose = CMSAdminUtil.makeJButton(mResource, PREFIX, "CLOSE",
+ null, this);
+
+ mHelp = CMSAdminUtil.makeJButton(mResource, PREFIX, "HELP", null, this);
+ Dimension d = mClose.getMinimumSize();
+ if (d.width < CMSAdminUtil.DEFAULT_BUTTON_SIZE) {
+ d.width = CMSAdminUtil.DEFAULT_BUTTON_SIZE;
+ mClose.setMinimumSize(d);
+ }
+ d = mHelp.getMinimumSize();
+ if (d.width < CMSAdminUtil.DEFAULT_BUTTON_SIZE) {
+ d.width = CMSAdminUtil.DEFAULT_BUTTON_SIZE;
+ mHelp.setMinimumSize(d);
+ }
+ //JButton[] buttons = {mClose, mHelp};
+ JButton[] buttons = {mClose};
+ return CMSAdminUtil.makeJButtonPanel( buttons );
+ }
+
+ private JPanel makeContentPane() {
+ JPanel content = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ content.setLayout(gb3);
+ content.setBorder(CMSAdminUtil.makeTitledBorder(mResource,
+ "CERTINFODIALOG", "CERT"));
+
+ JPanel panel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ panel.setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.insets = new Insets(0, 0, 0, 0);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.fill = gbc.BOTH;
+ content.add(panel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label1 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "CERTNAME",
+ null);
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ 0, //CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+ gb.setConstraints(label1, gbc);
+ panel.add(label1);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mCertNameField = new JLabel(" ");
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.anchor = gbc.WEST;
+ gbc.weightx=1.0;
+ //gbc.fill = gbc.NONE;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+ gb.setConstraints(mCertNameField, gbc);
+ panel.add(mCertNameField);
+
+
+ //CMSAdminUtil.addEntryField(content, label1, mCertNameField, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label2 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "CONTENT", null);
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.WEST;
+ //gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+ gb.setConstraints(label2, gbc);
+ panel.add(label2);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label3 = new JLabel(" ");
+ //gbc.fill = gbc.NONE;
+ gbc.weightx = 1.0;
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(0,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+ gb.setConstraints(label3, gbc);
+ panel.add(label3);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mTextArea = new JTextArea("",100,90);
+ mTextArea.setEditable(false);
+ mTextArea.setBackground(getBackground());
+ JScrollPane scrollPanel = new JScrollPane(mTextArea,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ scrollPanel.setAlignmentX(LEFT_ALIGNMENT);
+ scrollPanel.setAlignmentY(TOP_ALIGNMENT);
+ scrollPanel.setBorder(BorderFactory.createLoweredBevelBorder());
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+// gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx=1.0;
+ gbc.weighty=1.0;
+ gbc.insets = new Insets(0,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+ gb3.setConstraints(scrollPanel, gbc);
+ content.add(scrollPanel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mStatusLbl = CMSAdminUtil.makeJLabel(mResource, PREFIX, "TRUSTSTATUS", null);
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(0,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+ gb3.setConstraints(mStatusLbl, gbc);
+ content.add(mStatusLbl);
+
+ CMSAdminUtil.resetGBC(gbc);
+ changeLbl = CMSAdminUtil.makeJLabel(mResource, PREFIX, "MODIFY", null);
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(0,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+ gb3.setConstraints(changeLbl, gbc);
+ content.add(changeLbl);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mActionBtn = CMSAdminUtil.makeJButton(mResource, PREFIX,"UNTRUST", null, this);
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(0,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.fill = gbc.NONE;
+ gb3.setConstraints(mActionBtn, gbc);
+ content.add(mActionBtn);
+/*
+ CMSAdminUtil.resetGBC(gbc);
+ mTrust = CMSAdminUtil.makeJButton(mResource, PREFIX, "TRUST", null, this);
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(0,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+ gbc.gridwidth = gbc.REMAINDER;
+ gb3.setConstraints(mTrust, gbc);
+ content.add(mTrust);
+*/
+
+ return content;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/managecert/ManageCertDialog.java b/base/console/src/com/netscape/admin/certsrv/managecert/ManageCertDialog.java
new file mode 100644
index 000000000..4fd902584
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/managecert/ManageCertDialog.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.admin.certsrv.managecert;
+
+import java.util.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.table.*;
+import javax.swing.*;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * This class lists out all the CA certificates from the internal token.
+ *
+ * @author chrisho
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.managecert
+ */
+public class ManageCertDialog extends JDialog implements ActionListener,
+ MouseListener {
+ private static final String PANELNAME = "MANAGECERTDIALOG";
+ static final Dimension DEFAULT_SIZE = new Dimension(460,500);
+ static final Dimension BUTTON_MIN_SIZE = new Dimension(100,30);
+
+ protected ResourceBundle mResource;
+ private JFrame mParent;
+ private JTable mTable;
+ private ManageCertModel mDataModel;
+ private JButton mClose, mDelete, mEdit, mHelp;
+ private AdminConnection mConn;
+ private static final String HELPINDEX =
+ "configuration-managecert-wizard-certlists-help";
+
+ public ManageCertDialog(JFrame parent) {
+ super(parent, true);
+ mParent = parent;
+ setSize(460,500);
+ getRootPane().setDoubleBuffered(true);
+ setLocationRelativeTo(parent);
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ setTitle(mResource.getString(PANELNAME+"_TITLE"));
+ setDisplay();
+ }
+
+ public void showDialog(AdminConnection conn) {
+ mConn = conn;
+ refresh();
+ this.show();
+ }
+
+ private void refresh() {
+ NameValuePairs response=null;
+ try {
+ response = mConn.search(DestDef.DEST_SERVER_ADMIN, ScopeDef.SC_ALL_CERTLIST,
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ CMSAdminUtil.showErrorDialog(mParent, mResource, e.toString(),
+ CMSAdminUtil.ERROR_MESSAGE);
+ }
+
+ if (response == null) { /* we must have gotten timed out */
+ return;
+ }
+
+ mDataModel.removeAllRows();
+
+ String[] vals = new String[response.size()];
+ int i=0;
+ for (String entry : response.keySet()) {
+ vals[i++] = entry.trim();
+ }
+
+ CMSAdminUtil.bubbleSort(vals);
+
+ for (i=0; i<vals.length; i++) {
+ String entry = vals[i];
+ String value = response.get(entry);
+ addRows(entry, value);
+ }
+ mTable.getSelectionModel().clearSelection();
+ setButtons();
+ }
+
+ private void addRows(String entry, String value) {
+ StringTokenizer tokenizer = new StringTokenizer(value, ";");
+ int numTokens = tokenizer.countTokens();
+ while (tokenizer.hasMoreTokens()) {
+ String token = (String)tokenizer.nextToken();
+ String expiredDate = token.substring(0, token.length()-2);
+ String trust = token.substring(token.length()-1);
+ Vector v = new Vector();
+ v.addElement(entry);
+ v.addElement(expiredDate);
+ if (trust.equals("T"))
+ v.addElement("Trusted");
+ else if (trust.equals("U"))
+ v.addElement("Untrusted");
+ else if (trust.equals("u"))
+ v.addElement("N/A");
+ mDataModel.addRow(v);
+ }
+ }
+
+ private void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.fill = gbc.BOTH;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ public JPanel makeActionPane() {
+ JPanel panel = new JPanel();
+
+ mClose = new JButton();
+ mClose.setText(mResource.getString(
+ "MANAGECERTDIALOG_BUTTON_CLOSE_LABEL"));
+ mClose.addActionListener(this);
+
+ mEdit = new JButton();
+ mEdit.setText(mResource.getString(
+ "MANAGECERTDIALOG_BUTTON_EDIT_VIEW_LABEL"));
+ mEdit.addActionListener(this);
+
+ mDelete = new JButton();
+ mDelete.setText(mResource.getString(
+ "MANAGECERTDIALOG_BUTTON_DELETE_LABEL"));
+ mDelete.addActionListener(this);
+
+ mHelp = new JButton();
+ mHelp.setText(mResource.getString(
+ "MANAGECERTDIALOG_BUTTON_HELP_LABEL"));
+ mHelp.addActionListener(this);
+
+ //JButton[] buttons = {mClose, mEdit, mDelete, mHelp};
+ JButton[] buttons = {mClose, mEdit, mDelete};
+ return CMSAdminUtil.makeJButtonPanel(buttons, true);
+ }
+
+ public JPanel makeContentPane() {
+ JPanel content = new JPanel();
+ content.setBorder(CMSAdminUtil.makeTitledBorder(mResource,
+ "MANAGECERTDIALOG", "CERT"));
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ content.setLayout(gb);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mDataModel = new ManageCertModel();
+ mTable = new JTable(mDataModel);
+ JScrollPane scrollPane = JTable.createScrollPaneForTable(mTable);
+ scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setPreferredScrollableViewportSize(new Dimension(200, 350));
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.addMouseListener(this);
+ scrollPane.setBackground(Color.white);
+ setLabelCellRenderer(mTable, 0);
+ setLabelCellRenderer(mTable, 1);
+ setLabelCellRenderer(mTable, 2);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE);
+ gb.setConstraints(scrollPane, gbc);
+ content.add(scrollPane);
+
+ return content;
+ }
+
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(
+ new DefaultTableCellRenderer());
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ Object source = e.getSource();
+ if (source.equals(mClose)) {
+ this.hide();
+ this.dispose();
+ } else if (source.equals(mDelete)) {
+ try {
+ // make sure selected cert is not a user cert
+ boolean userCert = false;
+ int[] rows = mTable.getSelectedRows();
+ for (int i=0; i<rows.length; i++) {
+ String trust =
+ (String)mDataModel.getValueAt(rows[i], 2);
+ if (trust.equals("N/A")) {
+ userCert = true;
+ }
+
+ String value = (String)mDataModel.getValueAt(rows[i], 0);
+ if (
+ (value.indexOf(Constants.PR_CA_SIGNING_NICKNAME) != -1) || (value.indexOf(Constants.PR_OCSP_SIGNING_CERT) != -1) ) {
+ userCert = true;
+ }
+ }
+
+ if (userCert == false) {
+ NameValuePairs nvps = getCerts();
+ mConn.modify(DestDef.DEST_SERVER_ADMIN, ScopeDef.SC_DELETE_CERTS,
+ Constants.RS_ID_CONFIG, nvps);
+ refresh();
+ } else {
+ // user certs can't be removed from here
+ CMSAdminUtil.showErrorDialog(mParent, mResource,
+ mResource.getString("CERTIMPORTDIALOG_DIALOG_CANTDELETE_MESSAGE"),
+ CMSAdminUtil.ERROR_MESSAGE);
+ }
+ } catch (EAdminException ex) {
+ CMSAdminUtil.showErrorDialog(mParent, mResource, ex.toString(),
+ CMSAdminUtil.ERROR_MESSAGE);
+ }
+ } else if (source.equals(mEdit)) {
+ displayCert();
+ } else if (source.equals(mHelp)) {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+ }
+
+ private void displayCert() {
+ try {
+ NameValuePairs nvps = getCerts();
+ NameValuePairs results = mConn.process(
+ DestDef.DEST_SERVER_ADMIN, ScopeDef.SC_CERT_PRETTY_PRINT,
+ Constants.RS_ID_CONFIG, nvps);
+ if (nvps.size() <= 0)
+ return;
+ String name = results.keySet().iterator().next(); // first element
+ String print = results.get(name);
+ CertificateInfoDialog dialog = new CertificateInfoDialog(mParent);
+ dialog.showDialog(name, print, getTrustLbl(), getDate(),mConn);
+ refresh();
+ } catch (EAdminException ex) {
+ CMSAdminUtil.showErrorDialog(mParent, mResource, ex.toString(),
+ CMSAdminUtil.ERROR_MESSAGE);
+ }
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+
+ //we track the double click action on the table entry - View op
+ if(mTable.getSelectedRow() >= 0) {
+ if(e.getClickCount() == 2) {
+ displayCert();
+ }
+ }
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ }
+
+ public void mousePressed(MouseEvent e) {
+ }
+
+ public void mouseEntered(MouseEvent e) {
+ }
+
+ public void mouseExited(MouseEvent e) {
+ }
+
+ private void setButtons() {
+ //enable and disable buttons accordingly
+ if (mTable.getSelectionModel().isSelectionEmpty()) {
+ mDelete.setEnabled(false);
+ mEdit.setEnabled(false);
+ return;
+ }
+
+ if(mDataModel.getRowCount()< 0) {
+ mDelete.setEnabled(false);
+ mEdit.setEnabled(false);
+ return;
+ }
+
+ mDelete.setEnabled(true);
+ mEdit.setEnabled(true);
+ }
+
+ private NameValuePairs getCerts() {
+ int[] rows = mTable.getSelectedRows();
+ NameValuePairs nvps = new NameValuePairs();
+ String name = "certName";
+ for (int i=0; i<rows.length; i++) {
+ String value = (String)mDataModel.getValueAt(rows[i], 0);
+ String date = (String)mDataModel.getValueAt(rows[i], 1);
+ nvps.put(name + i, value + ";" + date);
+ }
+ return nvps;
+ }
+
+ private String getTrustLbl() {
+ int row = mTable.getSelectedRow();
+ String trust = (String)mDataModel.getValueAt(row, 2);
+ if (trust.equals("Trusted"))
+ return "Trust";
+ else if (trust.equals("Untrusted"))
+ return "Untrust";
+ else if (trust.equals("N/A"))
+ return "N/A";
+ else
+ return "Unknown";
+
+ }
+
+ private String getDate() {
+ int row = mTable.getSelectedRow();
+ return (String)mDataModel.getValueAt(row, 1);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/managecert/ManageCertModel.java b/base/console/src/com/netscape/admin/certsrv/managecert/ManageCertModel.java
new file mode 100644
index 000000000..2cae90759
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/managecert/ManageCertModel.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.admin.certsrv.managecert;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Manage certificate data model - represents the instance
+ * table information
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class ManageCertModel extends CMSTableModel
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String COL1 = "CERTNAME";
+ public static final String COL2 = "EXPIRED";
+ public static final String COL3 = "TRUST";
+
+ private static String[] mColumns = {COL1, COL2, COL3};
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public ManageCertModel() {
+ super();
+ init(mColumns);
+ }
+
+ public boolean isCellEditable(int row, int col) {
+ return false;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/menu/CertManagementAction.java b/base/console/src/com/netscape/admin/certsrv/menu/CertManagementAction.java
new file mode 100644
index 000000000..a7300e973
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/menu/CertManagementAction.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.admin.certsrv.menu;
+
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.client.console.*;
+import com.netscape.admin.certsrv.security.*;
+import com.netscape.admin.certsrv.*;
+
+/**
+ * Certificate Management
+ *
+ * This class is responsible for calling the cert management wizard
+ * when user select the cert management menu item
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @date 04/07/97
+ */
+public class CertManagementAction implements IMenuAction {
+
+ protected ConsoleInfo mConsoleInfo;
+
+ public CertManagementAction(ConsoleInfo info) {
+ mConsoleInfo = info;
+ }
+
+ public void perform(IPage viewInstance) {
+ (new CertManagementDialog( mConsoleInfo )).showModal();
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/menu/KeyCertAction.java b/base/console/src/com/netscape/admin/certsrv/menu/KeyCertAction.java
new file mode 100644
index 000000000..e10f92c78
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/menu/KeyCertAction.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.admin.certsrv.menu;
+
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.client.console.*;
+import com.netscape.admin.certsrv.security.*;
+import com.netscape.admin.certsrv.*;
+
+/**
+ * Key and Certificate Wizard action
+ *
+ * This class is responsible for calling the key and cert wizard
+ * when user select the key and cert menu item
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @date 04/07/97
+ */
+public class KeyCertAction implements IMenuAction {
+
+ protected ConsoleInfo mConsoleInfo;
+
+ public KeyCertAction(ConsoleInfo info) {
+ mConsoleInfo = info;
+ }
+
+ public void perform(IPage viewInstance) {
+ KeyCertWizard wizard = new KeyCertWizard(mConsoleInfo);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/menu/PKCS11ManagementAction.java b/base/console/src/com/netscape/admin/certsrv/menu/PKCS11ManagementAction.java
new file mode 100644
index 000000000..57dde4e66
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/menu/PKCS11ManagementAction.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.admin.certsrv.menu;
+
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.client.console.*;
+import com.netscape.admin.certsrv.security.*;
+import com.netscape.admin.certsrv.*;
+
+/**
+ * PKCS#11 Management
+ *
+ * This class is responsible for calling the PKCS11 management wizard
+ * when user select the pkcs11 management menu item
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @date 04/07/97
+ */
+public class PKCS11ManagementAction implements IMenuAction {
+
+ protected ConsoleInfo mConsoleInfo;
+
+ public PKCS11ManagementAction(ConsoleInfo info) {
+ mConsoleInfo = info;
+ }
+
+ public void perform(IPage viewInstance) {
+ (new PKCS11ManagementDialog( mConsoleInfo )).showModal();
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/menu/RefreshTabPane.java b/base/console/src/com/netscape/admin/certsrv/menu/RefreshTabPane.java
new file mode 100644
index 000000000..f52a7f1a6
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/menu/RefreshTabPane.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.admin.certsrv.menu;
+
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.client.console.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.ug.*;
+import java.awt.*;
+
+/**
+ * Refresh Tab Pane
+ *
+ * This class is responsible for refreshing the selected tab pane
+ * when user selects the refresh menu item
+ *
+ * @author Christine Ho
+ * @author jpanchen
+ *
+ * @version $Revision$, $Date$
+ *
+ * @see com.netscape.admin.certsrv.IRefreshTab
+ * @see com.netscape.admin.certsrv.IRefreshTabPanel
+ * @see com.netscape.admin.certsrv.CMSBaseResourceModel
+ * @see com.netscape.admin.certsrv.IMenuAction
+ */
+public class RefreshTabPane implements IMenuAction {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ protected IRefreshTabPanel mPanel; //object ref to selected tab pane
+
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ /**
+ * Default Constructor that creates the refresh menu
+ * call back item.
+ */
+ public RefreshTabPane(CMSBaseResourceModel model) {
+ model.setRefreshCallback(this);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * perform the refresh function on the selected
+ * tab panel, if the tab panel support the IRefreshTab
+ * intreface.
+ */
+ public void perform(IPage viewInstance) {
+ if (mPanel != null) {
+ if (mPanel instanceof IRefreshTabPanel) {
+ CMSBasePanel panel = mPanel.getSelectedTab();
+ if (panel instanceof IRefreshTab) {
+ IRefreshTab tab = (IRefreshTab)panel;
+ tab.refresh();
+ }
+ }
+ }
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ /**
+ * Accepts the selection notification from the
+ * resource model. we must verify the class and
+ * determine if the tab support the IRefreshTab
+ * interface. If not, null is set.
+ */
+ public void select(Component c) {
+ if (c instanceof IRefreshTabPanel) {
+ mPanel = (IRefreshTabPanel)c;
+ } else {
+ mPanel = null;
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/misc/MessageFormatter.java b/base/console/src/com/netscape/admin/certsrv/misc/MessageFormatter.java
new file mode 100644
index 000000000..1ec1e72ba
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/misc/MessageFormatter.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.admin.certsrv.misc;
+
+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>
+ *
+ * @author galperin
+ * @version $Revision$, $Date$
+ * @see java.text.MessageFormat
+ * @see java.util.ResourceBundle
+ */
+public class MessageFormatter {
+
+ private static final Class [] toStringSignature = { Locale.class };
+
+ public static String getLocalizedString(
+ Locale locale, String resourceBundleBaseName,
+ String keyword) {
+ return getLocalizedString(locale, resourceBundleBaseName,
+ keyword, null);
+ }
+
+ public static String getLocalizedString(
+ Locale locale, String resourceBundleBaseName,
+ String keyword, Object params) {
+ Object o[] = new Object[1];
+ o[0] = params;
+ return getLocalizedString(locale, resourceBundleBaseName,
+ keyword, o);
+ }
+
+ public static String getLocalizedString(
+ String resourceBundleBaseName,
+ String keyword, Object param) {
+ Object o[] = new Object[1];
+ o[0] = param;
+ return getLocalizedString(Locale.getDefault(), resourceBundleBaseName,
+ keyword, o);
+ }
+
+ public static String getLocalizedString(
+ String resourceBundleBaseName,
+ String keyword, Object [] params) {
+ return getLocalizedString(Locale.getDefault(), resourceBundleBaseName,
+ keyword, params);
+ }
+
+ public static String getLocalizedString(
+ Locale locale, String resourceBundleBaseName,
+ String keyword, Object [] params) {
+
+ String localizedFormat = null;
+
+ 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(keyword);
+ } catch (MissingResourceException e) {
+ return "Failed resolving format [" + keyword +
+ "] in resource bundle [" +
+ resourceBundleBaseName + "] for locale [" +
+ locale + "]";
+ }
+ 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;
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/notification/RequestCompletePanel.java b/base/console/src/com/netscape/admin/certsrv/notification/RequestCompletePanel.java
new file mode 100644
index 000000000..c01407193
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/notification/RequestCompletePanel.java
@@ -0,0 +1,280 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.notification;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.config.*;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * notification settings tab for RequestCompletion
+ *
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class RequestCompletePanel extends CMSBaseTab implements ItemListener {
+ private static final String RA_HELPINDEX =
+ "notification-ra-certissued-help";
+ private static final String CA_HELPINDEX =
+ "notification-ca-certissued-help";
+ private JTextField mEmailFormText;
+ private JTextField mEmailSubjectText;
+ private JCheckBox mEnable;
+ private Color mActiveColor;
+ private JLabel mEmailFormLabel;
+ private JLabel mEmailSubjectLabel;
+ private JTextField mSenderEmailText;
+ private JLabel mSenderEmailLabel;
+ protected AdminConnection mAdmin;
+ protected CMSBaseResourceModel mModel;
+ private String mServletName;
+ private CMSTabPanel mParent;
+ private String mPanelName;
+
+ /*
+ public RequestCompletePanel(String panelName, CMSTabPanel parent) {
+ this(panelName, parent, true);
+ mPanelName = panelName;
+ }
+ */
+ public RequestCompletePanel(String panelName, CMSTabPanel parent,
+ String servletName) {
+ super(panelName, parent);
+ if (servletName.equals(DestDef.DEST_RA_ADMIN)) {
+ mHelpToken = RA_HELPINDEX;
+ } else {
+ mHelpToken = CA_HELPINDEX;
+ }
+ mServletName = servletName;
+ mModel = parent.getResourceModel();
+ mParent = parent;
+ }
+
+ public void init() {
+ mAdmin = mModel.getServerInfo().getAdmin();
+ JPanel emailInfo = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mCenterPanel.setLayout(gb);
+
+ //add the enable checkbox
+ mEnable = makeJCheckBox("ENABLE");
+ mEnable.setSelected(true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(DIFFERENT_COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE,
+ 0,
+ DIFFERENT_COMPONENT_SPACE);
+ gb.setConstraints(mEnable, gbc);
+ mCenterPanel.add(mEnable);
+
+ //add the setting panel
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(emailInfo, gbc);
+ mCenterPanel.add(emailInfo);
+
+ GridBagLayout gb1 = new GridBagLayout();
+ emailInfo.setLayout(gb1);
+ emailInfo.setBorder(makeTitledBorder("EMAILINFO"));
+
+ // add sender email label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ mSenderEmailLabel = makeJLabel("SENDER");
+ mSenderEmailText = makeJTextField(30);
+ mActiveColor = mSenderEmailText.getBackground();
+ CMSAdminUtil.addEntryField(emailInfo,
+ mSenderEmailLabel, mSenderEmailText, gbc);
+
+ // add email subject label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ mEmailSubjectLabel = makeJLabel("SUBJECT");
+ mEmailSubjectText = makeJTextField(30);
+ mActiveColor = mEmailSubjectText.getBackground();
+ CMSAdminUtil.addEntryField(emailInfo,
+ mEmailSubjectLabel, mEmailSubjectText, gbc);
+
+ // add form name label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ mEmailFormLabel = makeJLabel("FORMNAME");
+ mEmailFormText = makeJTextField(30);
+ mActiveColor = mEmailFormText.getBackground();
+ CMSAdminUtil.addEntryField(emailInfo,
+ mEmailFormLabel, mEmailFormText, gbc);
+
+ refresh();
+ }
+
+ public void refresh() {
+ mModel.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_ENABLE, "");
+ nvps.put(Constants.PR_NOTIFICATION_FORM_NAME, "");
+ nvps.put(Constants.PR_NOTIFICATION_SUBJECT, "");
+ nvps.put(Constants.PR_NOTIFICATION_SENDER, "");
+
+ try {
+ NameValuePairs val = mAdmin.read(mServletName,
+ ScopeDef.SC_NOTIFICATION_REQ_COMP, Constants.RS_ID_CONFIG, nvps);
+
+ populate(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+ }
+
+ protected void populate(NameValuePairs nvps) {
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name);
+ if (name.equals(Constants.PR_NOTIFICATION_FORM_NAME)) {
+ mEmailFormText.setText(value);
+ } else if (name.equals(Constants.PR_NOTIFICATION_SUBJECT)) {
+ mEmailSubjectText.setText(value);
+ } else if (name.equals(Constants.PR_NOTIFICATION_SENDER)) {
+ mSenderEmailText.setText(value);
+ } else if (name.equals(Constants.PR_ENABLE)) {
+ if (value.equals(Constants.TRUE))
+ mEnable.setSelected(true);
+ else
+ mEnable.setSelected(false);
+ }
+ }
+
+ if (mEnable.isSelected())
+ enableFields(true, mActiveColor);
+ else
+ enableFields(false, getBackground());
+ }
+
+ private int getIndex(String val, String[] array) {
+ for (int i=0; i<array.length; i++) {
+ if (val.equals(array[i]))
+ return i;
+ }
+ return -1;
+ }
+
+ private void enableFields(boolean enable, Color color) {
+ mEmailFormText.setEnabled(enable);
+ mEmailFormText.setEditable(enable);
+ mEmailFormText.setBackground(color);
+ mEmailFormLabel.setEnabled(enable);
+ mEmailFormLabel.setBackground(color);
+
+ mEmailSubjectText.setEnabled(enable);
+ mEmailSubjectText.setEditable(enable);
+ mEmailSubjectText.setBackground(color);
+ mEmailSubjectLabel.setEnabled(enable);
+ mEmailSubjectLabel.setBackground(color);
+
+ mSenderEmailText.setEnabled(enable);
+ mSenderEmailText.setEditable(enable);
+ mSenderEmailText.setBackground(color);
+ mSenderEmailLabel.setEnabled(enable);
+ mSenderEmailLabel.setBackground(color);
+
+ repaintComp(mEmailFormLabel);
+ repaintComp(mSenderEmailLabel);
+ repaintComp(mEmailSubjectLabel);
+ }
+
+ private void repaintComp(JComponent component) {
+ component.invalidate();
+ component.validate();
+ component.repaint(1);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ super.actionPerformed(e);
+ if (mEnable.isSelected()) {
+ enableFields(true, mActiveColor);
+ } else {
+ enableFields(false, getBackground());
+ }
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ // check blank fields
+ String emailForm = mEmailFormText.getText().trim();
+ String emailSubject = mEmailSubjectText.getText().trim();
+ String senderEmail = mSenderEmailText.getText().trim();
+
+ if (mEnable.isSelected() && (emailForm.equals("") ||
+ senderEmail.equals("") ||
+ emailSubject.equals(""))) {
+ showMessageDialog("BLANKFIELD");
+ return false;
+ }
+
+ NameValuePairs nvps = new NameValuePairs();
+ if (mEnable.isSelected())
+ nvps.put(Constants.PR_ENABLE, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_ENABLE, Constants.FALSE);
+
+ if (mEnable.isSelected()){
+ nvps.put(Constants.PR_NOTIFICATION_FORM_NAME, emailForm);
+ nvps.put(Constants.PR_NOTIFICATION_SUBJECT, emailSubject);
+ nvps.put(Constants.PR_NOTIFICATION_SENDER, senderEmail);
+ }
+
+ mModel.progressStart();
+ try {
+ mAdmin.modify(mServletName, ScopeDef.SC_NOTIFICATION_REQ_COMP,
+ Constants.RS_ID_CONFIG, nvps);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ return false;
+ }
+
+ mModel.progressStop();
+ clearDirtyFlag();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/notification/RequestInQPanel.java b/base/console/src/com/netscape/admin/certsrv/notification/RequestInQPanel.java
new file mode 100644
index 000000000..aa37ed149
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/notification/RequestInQPanel.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.admin.certsrv.notification;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.config.*;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * notification settings tab for RequestInQueue
+ *
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class RequestInQPanel extends CMSBaseTab implements ItemListener {
+ private static final String RA_HELPINDEX =
+ "notification-ra-reqinq-help";
+ private static final String CA_HELPINDEX =
+ "notification-ca-reqinq-help";
+ private JTextField mEmailFormText;
+ private JTextField mEmailSubjectText;
+ private JCheckBox mEnable;
+ private Color mActiveColor;
+ private JLabel mEmailFormLabel;
+ private JLabel mEmailSubjectLabel;
+ private JTextField mSenderEmailText;
+ private JLabel mSenderEmailLabel;
+ private JTextField mReceiverEmailText;
+ private JLabel mReceiverEmailLabel;
+ protected AdminConnection mAdmin;
+ protected CMSBaseResourceModel mModel;
+ private String mServletName;
+ private CMSTabPanel mParent;
+ private String mPanelName;
+ /*
+ public RequestInQPanel(String panelName, CMSTabPanel parent) {
+ this(panelName, parent, true);
+ mPanelName = panelName;
+ }
+ */
+ public RequestInQPanel(String panelName, CMSTabPanel parent,
+ String servletName) {
+ super(panelName, parent);
+ if (servletName.equals(DestDef.DEST_RA_ADMIN)) {
+ mHelpToken = RA_HELPINDEX;
+ } else {
+ mHelpToken = CA_HELPINDEX;
+ }
+ mServletName = servletName;
+ mModel = parent.getResourceModel();
+ mParent = parent;
+ }
+
+ public void init() {
+ mAdmin = mModel.getServerInfo().getAdmin();
+ JPanel emailInfo = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mCenterPanel.setLayout(gb);
+
+ //add the enable checkbox
+ mEnable = makeJCheckBox("ENABLE");
+ mEnable.setSelected(true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(DIFFERENT_COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE,
+ 0,
+ DIFFERENT_COMPONENT_SPACE);
+ gb.setConstraints(mEnable, gbc);
+ mCenterPanel.add(mEnable);
+
+ //add the setting panel
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(emailInfo, gbc);
+ mCenterPanel.add(emailInfo);
+
+ GridBagLayout gb1 = new GridBagLayout();
+ emailInfo.setLayout(gb1);
+ emailInfo.setBorder(makeTitledBorder("EMAILINFO"));
+
+ // add sender email label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ mSenderEmailLabel = makeJLabel("SENDER");
+ mSenderEmailText = makeJTextField(30);
+ mActiveColor = mSenderEmailText.getBackground();
+ CMSAdminUtil.addEntryField(emailInfo,
+ mSenderEmailLabel, mSenderEmailText, gbc);
+
+ // add email subject label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ mEmailSubjectLabel = makeJLabel("SUBJECT");
+ mEmailSubjectText = makeJTextField(30);
+ mActiveColor = mEmailSubjectText.getBackground();
+ CMSAdminUtil.addEntryField(emailInfo,
+ mEmailSubjectLabel, mEmailSubjectText, gbc);
+
+ // add receiver email label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ mReceiverEmailLabel = makeJLabel("RECEIVER");
+ mReceiverEmailText = makeJTextField(30);
+ mActiveColor = mReceiverEmailText.getBackground();
+ CMSAdminUtil.addEntryField(emailInfo,
+ mReceiverEmailLabel, mReceiverEmailText, gbc);
+
+ // add form name label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ mEmailFormLabel = makeJLabel("FORMNAME");
+ mEmailFormText = makeJTextField(30);
+ mActiveColor = mEmailFormText.getBackground();
+ CMSAdminUtil.addEntryField(emailInfo,
+ mEmailFormLabel, mEmailFormText, gbc);
+
+ refresh();
+ }
+
+ public void refresh() {
+ mModel.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_ENABLE, "");
+ nvps.put(Constants.PR_NOTIFICATION_FORM_NAME, "");
+ nvps.put(Constants.PR_NOTIFICATION_SUBJECT, "");
+ nvps.put(Constants.PR_NOTIFICATION_SENDER, "");
+ nvps.put(Constants.PR_NOTIFICATION_RECEIVER, "");
+
+ try {
+ NameValuePairs val = mAdmin.read(mServletName,
+ ScopeDef.SC_NOTIFICATION_RIQ, Constants.RS_ID_CONFIG, nvps);
+
+ populate(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+ }
+
+ protected void populate(NameValuePairs nvps) {
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name);
+ if (name.equals(Constants.PR_NOTIFICATION_FORM_NAME)) {
+ mEmailFormText.setText(value);
+ } else if (name.equals(Constants.PR_NOTIFICATION_SUBJECT)) {
+ mEmailSubjectText.setText(value);
+ } else if (name.equals(Constants.PR_NOTIFICATION_SENDER)) {
+ mSenderEmailText.setText(value);
+ } else if (name.equals(Constants.PR_NOTIFICATION_RECEIVER)) {
+ mReceiverEmailText.setText(value);
+ } else if (name.equals(Constants.PR_ENABLE)) {
+ if (value.equals(Constants.TRUE))
+ mEnable.setSelected(true);
+ else
+ mEnable.setSelected(false);
+ }
+ }
+
+ if (mEnable.isSelected())
+ enableFields(true, mActiveColor);
+ else
+ enableFields(false, getBackground());
+ }
+
+ private int getIndex(String val, String[] array) {
+ for (int i=0; i<array.length; i++) {
+ if (val.equals(array[i]))
+ return i;
+ }
+ return -1;
+ }
+
+ private void enableFields(boolean enable, Color color) {
+ mEmailFormText.setEnabled(enable);
+ mEmailFormText.setEditable(enable);
+ mEmailFormText.setBackground(color);
+ mEmailFormLabel.setEnabled(enable);
+ mEmailFormLabel.setBackground(color);
+
+ mEmailSubjectText.setEnabled(enable);
+ mEmailSubjectText.setEditable(enable);
+ mEmailSubjectText.setBackground(color);
+ mEmailSubjectLabel.setEnabled(enable);
+ mEmailSubjectLabel.setBackground(color);
+
+ mSenderEmailText.setEnabled(enable);
+ mSenderEmailText.setEditable(enable);
+ mSenderEmailText.setBackground(color);
+ mSenderEmailLabel.setEnabled(enable);
+ mSenderEmailLabel.setBackground(color);
+
+ mReceiverEmailText.setEnabled(enable);
+ mReceiverEmailText.setEditable(enable);
+ mReceiverEmailText.setBackground(color);
+ mReceiverEmailLabel.setEnabled(enable);
+ mReceiverEmailLabel.setBackground(color);
+
+ repaintComp(mEmailFormLabel);
+ repaintComp(mSenderEmailLabel);
+ repaintComp(mReceiverEmailLabel);
+ repaintComp(mEmailSubjectLabel);
+ }
+
+ private void repaintComp(JComponent component) {
+ component.invalidate();
+ component.validate();
+ component.repaint(1);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ super.actionPerformed(e);
+ if (mEnable.isSelected()) {
+ enableFields(true, mActiveColor);
+ } else {
+ enableFields(false, getBackground());
+ }
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ // check blank fields
+ String emailForm = mEmailFormText.getText().trim();
+ String emailSubject = mEmailSubjectText.getText().trim();
+ String senderEmail = mSenderEmailText.getText().trim();
+ String receiverEmail = mReceiverEmailText.getText().trim();
+
+ if (mEnable.isSelected() && (emailForm.equals("") ||
+ senderEmail.equals("") ||
+ emailSubject.equals("") ||
+ receiverEmail.equals(""))) {
+ showMessageDialog("BLANKFIELD");
+ return false;
+ }
+
+ NameValuePairs nvps = new NameValuePairs();
+ if (mEnable.isSelected())
+ nvps.put(Constants.PR_ENABLE, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_ENABLE, Constants.FALSE);
+
+ if (mEnable.isSelected()){
+ nvps.put(Constants.PR_NOTIFICATION_FORM_NAME, emailForm);
+ nvps.put(Constants.PR_NOTIFICATION_SUBJECT, emailSubject);
+ nvps.put(Constants.PR_NOTIFICATION_SENDER, senderEmail);
+ nvps.put(Constants.PR_NOTIFICATION_RECEIVER, receiverEmail);
+ }
+
+ mModel.progressStart();
+ try {
+ mAdmin.modify(mServletName, ScopeDef.SC_NOTIFICATION_RIQ,
+ Constants.RS_ID_CONFIG, nvps);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ return false;
+ }
+
+ mModel.progressStop();
+ clearDirtyFlag();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/notification/RequestRevokedPanel.java b/base/console/src/com/netscape/admin/certsrv/notification/RequestRevokedPanel.java
new file mode 100644
index 000000000..60b0e2949
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/notification/RequestRevokedPanel.java
@@ -0,0 +1,283 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.notification;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.config.*;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * notification settings tab for RequestCompletion
+ *
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class RequestRevokedPanel extends CMSBaseTab implements ItemListener {
+ private static final String RA_HELPINDEX =
+ "configuration-notifications";
+ private static final String CA_HELPINDEX =
+ "configuration-notifications";
+ private JTextField mEmailFormText;
+ private JTextField mEmailSubjectText;
+ private JCheckBox mEnable;
+ private Color mActiveColor;
+ private JLabel mEmailFormLabel;
+ private JLabel mEmailSubjectLabel;
+ private JTextField mSenderEmailText;
+ private JLabel mSenderEmailLabel;
+ protected AdminConnection mAdmin;
+ protected CMSBaseResourceModel mModel;
+ private String mServletName;
+ private CMSTabPanel mParent;
+ private String mPanelName;
+
+ /*
+ public RequestRevokedPanel(String panelName, CMSTabPanel parent) {
+ this(panelName, parent, true);
+ mPanelName = panelName;
+ }
+ */
+ public RequestRevokedPanel(String panelName, CMSTabPanel parent,
+ String servletName) {
+ super(panelName, parent);
+ if (servletName.equals(DestDef.DEST_RA_ADMIN)) {
+ mHelpToken = RA_HELPINDEX;
+ } else {
+ mHelpToken = CA_HELPINDEX;
+ }
+ mServletName = servletName;
+ mModel = parent.getResourceModel();
+ mParent = parent;
+ }
+
+ public void init() {
+ mAdmin = mModel.getServerInfo().getAdmin();
+ JPanel emailInfo = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mCenterPanel.setLayout(gb);
+
+ //add the enable checkbox
+ mEnable = makeJCheckBox("ENABLE");
+ mEnable.setSelected(true);
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets = new Insets(DIFFERENT_COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE,
+ 0,
+ DIFFERENT_COMPONENT_SPACE);
+ gb.setConstraints(mEnable, gbc);
+ mCenterPanel.add(mEnable);
+
+ //add the setting panel
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(emailInfo, gbc);
+ mCenterPanel.add(emailInfo);
+
+ GridBagLayout gb1 = new GridBagLayout();
+ emailInfo.setLayout(gb1);
+ emailInfo.setBorder(makeTitledBorder("EMAILINFO"));
+
+ // add sender email label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ mSenderEmailLabel = makeJLabel("SENDER");
+ mSenderEmailText = makeJTextField(30);
+ mActiveColor = mSenderEmailText.getBackground();
+ CMSAdminUtil.addEntryField(emailInfo,
+ mSenderEmailLabel, mSenderEmailText, gbc);
+
+ // add email subject label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ mEmailSubjectLabel = makeJLabel("SUBJECT");
+ mEmailSubjectText = makeJTextField(30);
+ mActiveColor = mEmailSubjectText.getBackground();
+ CMSAdminUtil.addEntryField(emailInfo,
+ mEmailSubjectLabel, mEmailSubjectText, gbc);
+
+ // add form name label and text field
+ CMSAdminUtil.resetGBC(gbc);
+ mEmailFormLabel = makeJLabel("FORMNAME");
+ mEmailFormText = makeJTextField(30);
+ mActiveColor = mEmailFormText.getBackground();
+ CMSAdminUtil.addEntryField(emailInfo,
+ mEmailFormLabel, mEmailFormText, gbc);
+
+ refresh();
+ }
+
+ public void refresh() {
+ mModel.progressStart();
+ NameValuePairs nvps = new NameValuePairs();
+ nvps.put(Constants.PR_ENABLE, "");
+ nvps.put(Constants.PR_NOTIFICATION_FORM_NAME, "");
+ nvps.put(Constants.PR_NOTIFICATION_SUBJECT, "");
+ nvps.put(Constants.PR_NOTIFICATION_SENDER, "");
+
+ try {
+ NameValuePairs val = mAdmin.read(mServletName,
+ ScopeDef.SC_NOTIFICATION_REV_COMP, Constants.RS_ID_CONFIG, nvps);
+
+ populate(val);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ }
+ mModel.progressStop();
+ clearDirtyFlag();
+ mParent.setOKCancel();
+ }
+
+ protected void populate(NameValuePairs nvps) {
+ String clientCert = "";
+
+ String version = "";
+ for (String name : nvps.keySet()) {
+ String value = nvps.get(name);
+ if (name.equals(Constants.PR_NOTIFICATION_FORM_NAME)) {
+ mEmailFormText.setText(value);
+ } else if (name.equals(Constants.PR_NOTIFICATION_SUBJECT)) {
+ mEmailSubjectText.setText(value);
+ } else if (name.equals(Constants.PR_NOTIFICATION_SENDER)) {
+ mSenderEmailText.setText(value);
+ } else if (name.equals(Constants.PR_ENABLE)) {
+ if (value.equals(Constants.TRUE))
+ mEnable.setSelected(true);
+ else
+ mEnable.setSelected(false);
+ }
+ }
+
+ if (mEnable.isSelected())
+ enableFields(true, mActiveColor);
+ else
+ enableFields(false, getBackground());
+ }
+
+ private int getIndex(String val, String[] array) {
+ for (int i=0; i<array.length; i++) {
+ if (val.equals(array[i]))
+ return i;
+ }
+ return -1;
+ }
+
+ private void enableFields(boolean enable, Color color) {
+ mEmailFormText.setEnabled(enable);
+ mEmailFormText.setEditable(enable);
+ mEmailFormText.setBackground(color);
+ mEmailFormLabel.setEnabled(enable);
+ mEmailFormLabel.setBackground(color);
+
+ mEmailSubjectText.setEnabled(enable);
+ mEmailSubjectText.setEditable(enable);
+ mEmailSubjectText.setBackground(color);
+ mEmailSubjectLabel.setEnabled(enable);
+ mEmailSubjectLabel.setBackground(color);
+
+ mSenderEmailText.setEnabled(enable);
+ mSenderEmailText.setEditable(enable);
+ mSenderEmailText.setBackground(color);
+ mSenderEmailLabel.setEnabled(enable);
+ mSenderEmailLabel.setBackground(color);
+
+ repaintComp(mEmailFormLabel);
+ repaintComp(mSenderEmailLabel);
+ repaintComp(mEmailSubjectLabel);
+ }
+
+ private void repaintComp(JComponent component) {
+ component.invalidate();
+ component.validate();
+ component.repaint(1);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ super.actionPerformed(e);
+ if (mEnable.isSelected()) {
+ enableFields(true, mActiveColor);
+ } else {
+ enableFields(false, getBackground());
+ }
+ }
+
+ /**
+ * Implementation for saving panel information
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean applyCallback() {
+ // check blank fields
+ String emailForm = mEmailFormText.getText().trim();
+ String emailSubject = mEmailSubjectText.getText().trim();
+ String senderEmail = mSenderEmailText.getText().trim();
+
+ if (mEnable.isSelected() && (emailForm.equals("") ||
+ senderEmail.equals("") ||
+ emailSubject.equals(""))) {
+ showMessageDialog("BLANKFIELD");
+ return false;
+ }
+
+ NameValuePairs nvps = new NameValuePairs();
+ if (mEnable.isSelected())
+ nvps.put(Constants.PR_ENABLE, Constants.TRUE);
+ else
+ nvps.put(Constants.PR_ENABLE, Constants.FALSE);
+
+ if (mEnable.isSelected()){
+ nvps.put(Constants.PR_NOTIFICATION_FORM_NAME, emailForm);
+ nvps.put(Constants.PR_NOTIFICATION_SUBJECT, emailSubject);
+ nvps.put(Constants.PR_NOTIFICATION_SENDER, senderEmail);
+ }
+
+ mModel.progressStart();
+ try {
+ mAdmin.modify(mServletName, ScopeDef.SC_NOTIFICATION_REV_COMP,
+ Constants.RS_ID_CONFIG, nvps);
+ } catch (EAdminException e) {
+ showErrorDialog(e.toString());
+ mModel.progressStop();
+ return false;
+ }
+
+ mModel.progressStop();
+ clearDirtyFlag();
+ return true;
+ }
+
+ /**
+ * Implementation for reset values
+ * @return true if save successful; otherwise, false.
+ */
+ public boolean resetCallback() {
+ refresh();
+ return true;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/security/AbstractCipher.java b/base/console/src/com/netscape/admin/certsrv/security/AbstractCipher.java
new file mode 100644
index 000000000..ec330fc0c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/AbstractCipher.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.admin.certsrv.security;
+
+import javax.swing.*;
+import javax.swing.border.*;
+import com.netscape.management.nmclf.*;
+
+/**
+ *
+ * Representation of a cipher under cipher preference.
+ *
+ * @version 1.0 98/07/10
+ * @author <A HREF="mailto:shihcm@netscape.com">shihcm@netscape.com</A>
+ *
+ * @see com.netscape.admin.certsrv.security.AbstractCipher
+ * @see com.netscape.admin.certsrv.security.IAbstractCipherSet
+ * @see com.netscape.admin.certsrv.security.AbstractCipher
+ */
+
+public final class AbstractCipher extends JCheckBox {
+
+ /**
+ *
+ * Symbolic name, used for storage purpose
+ * for example we currently use ssl2-RC4EXPORT to represent:
+ * "RC4 with 40 bit encryption and MD5 message authentication"
+ */
+ private String symbolicName = "";
+
+ /**
+ * Create an abstric cipher
+ *
+ * @param displayName cipher representation to be displayed
+ * @param symbolicName cipher name used for reference and storage
+ *
+ */
+ public AbstractCipher(String displayName, String symbolicName) {
+ this(displayName, symbolicName, false);
+ }
+
+ /**
+ * Create an abstric cipher
+ *
+ * @param displayName cipher representation to be displayed
+ * @param symbolicName cipher name used for reference and storage
+ * @param enabled enable cipher
+ *
+ */
+ public AbstractCipher(String displayName, String symbolicName,
+ boolean enabled) {
+ super(displayName, enabled);
+ this.symbolicName = symbolicName;
+ }
+
+ /**
+ *
+ * Get symbolic name
+ *
+ * @return string, symbolic name
+ *
+ */
+ public String getSymbolicName() {
+ return symbolicName;
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/AbstractCipherPreference.java b/base/console/src/com/netscape/admin/certsrv/security/AbstractCipherPreference.java
new file mode 100644
index 000000000..c9e92561f
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/AbstractCipherPreference.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 com.netscape.admin.certsrv.security;
+
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.plaf.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+/**
+ *
+ * Abstract cipher preference panel.
+ * Use with AbstractCipher and IAbstractCipherSet to customize server
+ * specific cipher preference dialog/panel.
+ *
+ * @version 1.0 98/07/10
+ * @author shihcm@netscape.com
+ *
+ * @see com.netscape.admin.certsrv.security.AbstractCipher
+ * @see com.netscape.admin.certsrv.security.IAbstractCipherSet
+ * @see com.netscape.admin.certsrv.security.AbstractCipher
+ */
+public class AbstractCipherPreference extends JPanel {
+
+ /**
+ * Main listener for all the cipher component under AbstractCipherPreference panel.
+ * This listener will catch all the cipher event(on/off) occures with in this panel.
+ */
+ CipherPrefActionListener listener = new CipherPrefActionListener();
+
+ /**
+ * Other listeners are stored in this vector, event catch in the "listener"(above) will
+ * also be routed to all the listener store in this vector
+ * Listener stored here are added by programmer via addActionListener(actionListener) call
+ */
+ Vector listenerList = new Vector();
+
+
+ /**
+ * This panel holds all the Ciper entry
+ */
+ JPanel cipherPane = new JPanel();
+
+ /**
+ * To determain whether if any cipher[s] changed status since last save.
+ */
+ boolean _ismodified = false;
+
+ /**
+ * Store the old setting, for reset purpose.
+ */
+ Hashtable oldValue = new Hashtable();
+
+ /**
+ * Create an abstract cipher preference
+ *
+ *
+ */
+ public AbstractCipherPreference() {}
+
+ /**
+ * Create an abstract cipher preference
+ *
+ * @param cipherList Interface to getCipherList()
+ *
+ *
+ */
+ public AbstractCipherPreference(IAbstractCipherSet cipherList) {
+ super();
+ initialize(cipherList);
+ }
+
+
+ class CipherPrefActionListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ _ismodified = true;
+ Enumeration l = listenerList.elements();
+ while (l.hasMoreElements()) {
+ ((ActionListener)(l.nextElement())).actionPerformed(e);
+ }
+ }
+ }
+
+
+ /**
+ * Initializer for cipher preference.
+ * Cipher are obtain via getCipherList() from IAbstractCipherSet
+ *
+ * @param cipherList Interface to getCipherList()
+ *
+ *
+ */
+ protected void initialize(IAbstractCipherSet cipherList) {
+
+ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+
+ cipherPane.setLayout(new BoxLayout(cipherPane, BoxLayout.Y_AXIS));
+ add(cipherPane);
+
+ Vector ciphers = cipherList.getCipherList();
+ for (Enumeration e = ciphers.elements(); e.hasMoreElements();) {
+ addCipher((AbstractCipher)(e.nextElement()));
+ }
+ }
+
+ /**
+ *
+ * Adds an ActionListener to all the ciphers
+ *
+ * @param l
+ *
+ */
+ public void addActionListener(ActionListener l) {
+ if (!(listenerList.contains(l))) {
+ listenerList.addElement(l);
+ }
+ }
+
+
+ /**
+ *
+ * Adds cipher ui
+ *
+ * @param l
+ *
+ */
+ public void addCipher(AbstractCipher cipher) {
+ oldValue.put(cipher.getSymbolicName(),
+ cipher.isSelected() ? "1":"0");
+ cipherPane.add(cipher);
+ cipher.addActionListener(listener);
+ }
+
+
+ /**
+ *
+ * Call setEnable(enabled) on each cipher.
+ * This is different then set cipher selected state.
+ * if cipher selected state on all cipher is required try
+ * getCipherList() then setCipherEnabled(boolean) on each
+ * cipher.
+ *
+ * @param enabled enable/disable all ciphers
+ *
+ */
+ public void setEnableAll(boolean enabled) {
+ Component[] c = cipherPane.getComponents();
+ for (int i = c.length - 1; i >= 0; i--) {
+ c[i].setEnabled(enabled);
+ }
+ }
+
+
+
+ /**
+ *
+ * Get entire cipher list
+ *
+ *
+ */
+ public String[] getCipherList() {
+ Component[] c = cipherPane.getComponents();
+ String[] ciphers = new String[c.length];
+ for (int i = c.length - 1; i >= 0; i--) {
+ ciphers[i] = ((AbstractCipher) c[i]).getSymbolicName();
+ }
+ return ciphers;
+ }
+
+ private AbstractCipher findCipher(String symbolicName) {
+ Component[] c = cipherPane.getComponents();
+
+ AbstractCipher cipher = null;
+
+ for (int i = c.length - 1; i >= 0; i--) {
+ if (((AbstractCipher) c[i]).getSymbolicName().
+ equalsIgnoreCase(symbolicName)) {
+ cipher = (AbstractCipher) c[i];
+ }
+ }
+
+ return cipher;
+ }
+
+
+ /**
+ *
+ * Set cipher to selected state
+ *
+ * @param cipher Cipher to enable/disable
+ * @param enabled enable cipher if true
+ *
+ */
+ public void setCipherEnabled(String cipher, boolean enabled) {
+ AbstractCipher c = findCipher(cipher);
+ if (c != null) {
+ c.setSelected(enabled);
+ }
+ }
+
+ /**
+ *
+ * Check weather a cipher is enabled or disabled
+ *
+ * @param cipher Cipher to check
+ *
+ */
+ public boolean isCipherEnabled(String cipher) {
+ AbstractCipher c = findCipher(cipher);
+ if (c != null) {
+ return c.isSelected();
+ }
+ return false;
+ }
+
+ /**
+ * Check weather any ciphers has been modified
+ *
+ * @see #isModified
+ * @see #setSaved
+ *
+ */
+ public boolean isModified() {
+ return _ismodified;
+ }
+
+ /**
+ * Reset all changes since last save
+ *
+ * @see #setSaved
+ */
+ public void reset() {
+ Enumeration keys = oldValue.keys();
+ while (keys.hasMoreElements()) {
+ String cipherName = (String)(keys.nextElement());
+ setCipherEnabled(cipherName,
+ "1".equals(oldValue.get(cipherName)) ? true : false);
+ }
+ _ismodified = false;
+ }
+
+
+ /**
+ * Set the state to saved.
+ *
+ * @see #reset
+ */
+ public void setSaved() {
+ oldValue.clear();
+
+ Component[] c = cipherPane.getComponents();
+ for (int i = c.length - 1; i >= 0; i--) {
+ AbstractCipher cipher = (AbstractCipher)(c[i]);
+ oldValue.put(cipher.getSymbolicName(),
+ cipher.isSelected() ? "1":"0");
+ }
+
+ _ismodified = false;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CRLAddCertDialog.java b/base/console/src/com/netscape/admin/certsrv/security/CRLAddCertDialog.java
new file mode 100644
index 000000000..7982d310d
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CRLAddCertDialog.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.admin.certsrv.security;
+
+import javax.swing.*;
+import javax.swing.border.*;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+
+import com.netscape.management.client.console.ConsoleInfo;
+
+
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+class CRLAddCertDialog extends AbstractDialog implements SuiConstants {
+
+ ConsoleInfo _consoleInfo;
+
+ KeyCertTaskInfo _taskInfo;
+ static boolean modified = false;
+
+ String _sie;
+ String _filename;
+ String _listtype;
+
+ JButton bClose;
+ JButton bAction;
+ JButton bHelp;
+
+ CertInfo _certInfo;
+ ResourceSet _resource;
+
+
+ CRLCertInfoPane _crlCertInfoPane;
+
+
+ class CRLAddCertActionListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ modified = false;
+ if (e.getActionCommand().equals("ACTION")) {
+ //call delete cert cgi
+ _taskInfo.clear();
+ _taskInfo.put("crl_file", _filename);
+ _taskInfo.put("sie", _sie);
+ _taskInfo.put(
+ (_certInstInfo.get("crl_action").equals("add"))
+ ? "addbutton":"repbutton", "1");
+ _taskInfo.put("list_type", _listtype);
+
+ Response response = null;
+ try {
+ response = _taskInfo.exec(_taskInfo.SEC_ICRL);
+ } catch (Exception error) {
+ SuiOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(),
+ error.getMessage());
+ return;
+ }
+
+ if (!(((Message)(response.getMessages().elementAt(0))).
+ isFailure())) {
+ if (_certInstInfo.get("crl_action").equals("add") ||
+ _certInstInfo.get("crl_action").equals("replace")) {
+ modified = true;
+ }
+ setVisible(false);
+ } else {
+ try {
+ MessageDialog.messageDialog( (Message)
+ (response.getMessages().elementAt(0)));
+ } catch (Exception e2) {
+ //shouldn't even be here in the first place. if cgi fail or return nothing
+ //then it should be handle right after KeyCertTaskInfo.exec(...) is called
+ //If exception occure here here then something is really mess up.
+ Debug.println("Error in decoding server messages");
+ }
+ }
+ } else if (e.getActionCommand().equals("CLOSE")) {
+ setVisible(false);
+ } else if (e.getActionCommand().equals("HELP")) {
+ Help help = new Help(_resource);
+ help.help("CRLDeleteCertDialog", "help");
+ }
+
+ }
+ }
+
+
+ public boolean isModified() {
+ return modified;
+ }
+
+ public CertInfo getCertInfo() {
+ return _certInfo;
+ }
+
+ Hashtable _certInstInfo = new Hashtable();
+ public void show(String filename, String list_type) {
+ _filename = filename;
+ _listtype = list_type;
+
+ _taskInfo.clear();
+ _taskInfo.put("crl_file", filename);
+ _taskInfo.put("sie", _sie);
+ _taskInfo.put("list_type", list_type);
+
+ try {
+ _taskInfo.exec(_taskInfo.SEC_ICRL);
+ } catch (Exception error) {
+ SuiOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(),
+ error.getMessage());
+ return;
+ }
+
+ if (_taskInfo.getResponse().hasCertInstInfo()) {
+ _certInstInfo = _taskInfo.getResponse().getCertInstInfo();
+ } else {
+ _certInstInfo.put("crl_action", "add");
+ _certInstInfo.put("crl_file", filename);
+ }
+ if (_taskInfo.getResponse().hasCertInfo()) {
+ setInfo(_taskInfo.getResponse().getCertInfo());
+ super.show();
+ } else {
+ try {
+ MessageDialog.messageDialog( (Message)
+ (_taskInfo.getResponse().getMessages().
+ elementAt(0)));
+ } catch (Exception e2) {
+ //shouldn't even be here in the first place. if cgi fail or return nothing
+ //then it should be handle right after KeyCertTaskInfo.exec(...) is called
+ //If exception occure here here then something is really mess up.
+ Debug.println("Error in decoding server messages");
+ }
+ }
+ }
+
+ private void setInfo(CertInfo certInfo) {
+ _certInfo = certInfo;
+ _crlCertInfoPane.setCertInfo(certInfo);
+
+ try {
+ if (((String)(_certInstInfo.get("crl_action"))).equals("add")) {
+ bAction.setText(
+ _resource.getString("CRLAddCertDialog", "add"));
+ } else {
+ bAction.setText(
+ _resource.getString("CRLAddCertDialog", "replace"));
+ }
+ JButtonFactory.resizeGroup(bHelp, bClose, bAction);
+ } catch (Exception e) {
+ }
+ }
+
+ public CRLAddCertDialog(ConsoleInfo consoleInfo, ResourceSet resource) {
+ super(null, "", true, NO_BUTTONS);
+
+ _consoleInfo = consoleInfo;
+ _sie = KeyCertUtility.createTokenName(_consoleInfo);
+ _resource = resource;
+ _taskInfo = new KeyCertTaskInfo(consoleInfo);
+
+ _crlCertInfoPane = new CRLCertInfoPane(resource);
+
+ Container mainPane = getContentPane();
+ mainPane.setLayout(new GridBagLayout());
+
+ GridBagUtil.constrain(mainPane, _crlCertInfoPane, 0, 0, 4, 1,
+ 1.0, 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0,
+ SuiConstants.DIFFERENT_COMPONENT_SPACE, 0);
+
+ CRLAddCertActionListener listener = new CRLAddCertActionListener();
+
+ bClose = JButtonFactory.createCloseButton(listener);
+ GridBagUtil.constrain(mainPane, bClose, 1, 1, 1, 1, 1.0, 0.0,
+ GridBagConstraints.SOUTHEAST, GridBagConstraints.NONE,
+ 0, 0, 0, SuiConstants.COMPONENT_SPACE);
+
+
+ bAction = JButtonFactory.create("");
+ bAction.addActionListener(listener);
+ bAction.setActionCommand("ACTION");
+ GridBagUtil.constrain(mainPane, bAction, 2, 1, 1, 1, 0.0, 0.0,
+ GridBagConstraints.SOUTHEAST, GridBagConstraints.NONE,
+ 0, 0, 0, SuiConstants.SEPARATED_COMPONENT_SPACE);
+
+
+ bHelp = JButtonFactory.createHelpButton(listener);
+ GridBagUtil.constrain(mainPane, bHelp, 3, 1, 1, 1, 0.0, 0.0,
+ GridBagConstraints.SOUTHEAST, GridBagConstraints.NONE,
+ 0, 0, 0, 0);
+
+ setMinimumSize(400, 225);
+ setResizable(false);
+ }
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ f.setSize(400,400);
+ f.show();
+
+ CRLAddCertDialog d = new CRLAddCertDialog(new ConsoleInfo(), new ResourceSet("com.netscape.admin.certsrv.security.CertManagementResource"), "buddha.txt");
+ d.show();
+ }*/
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CRLCertInfoPane.java b/base/console/src/com/netscape/admin/certsrv/security/CRLCertInfoPane.java
new file mode 100644
index 000000000..8e1b99b22
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CRLCertInfoPane.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.admin.certsrv.security;
+
+import javax.swing.*;
+import javax.swing.border.*;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+
+import com.netscape.management.client.console.ConsoleInfo;
+
+
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+class CRLCertInfoPane extends JPanel implements SuiConstants {
+
+
+ JLabel _certName;
+ MultilineLabel _issuer;
+ //MultilineLabel _subject;
+ MultilineLabel _valid;
+ ResourceSet _resource;
+
+ public void setCertInfo(CertInfo certInfo) {
+ _certName.setText(certInfo.getCertName());
+ _issuer.setText(certInfo.getIssuer());
+ //_subject.setText(certInfo.getSubject());
+ _valid.setText( KeyCertUtility.replace( KeyCertUtility.replace(
+ _resource.getString("CRLDetailInfoDialog",
+ "validFromTo"), "%FROM", certInfo.getValidFrom()), "%TO",
+ certInfo.getValidTo()));
+
+ }
+
+ public CRLCertInfoPane(ResourceSet resource) {
+ setLayout(new GridBagLayout());
+
+ _resource = resource;
+
+ _certName = new JLabel();
+ _issuer = new MultilineLabel();
+ //_subject = new MultilineLabel();
+ _valid = new MultilineLabel();
+
+
+ setBorder( new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE)));
+
+
+
+ GridBagUtil.constrain(this,
+ new JLabel(
+ _resource.getString("CRLInfoDialog", "issuer")), 0, 0,
+ 1, 1, 1.0, 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.HORIZONTAL, 0, 0, COMPONENT_SPACE, 0);
+
+ JScrollPane issuerScrollPane = new JScrollPane(_issuer,
+ JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+ JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ issuerScrollPane.setBorder(
+ new CompoundBorder(UITools.createLoweredBorder(),
+ new EmptyBorder(VERT_COMPONENT_INSET,
+ HORIZ_COMPONENT_INSET, VERT_COMPONENT_INSET,
+ HORIZ_COMPONENT_INSET)));
+ GridBagUtil.constrain(this, issuerScrollPane, 0, 1, 1, 1, 1.0,
+ 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.HORIZONTAL, 0, 0,
+ DIFFERENT_COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this, _valid, 0, 2, 1, 1, 1.0, 1.0,
+ GridBagConstraints.NORTH,
+ GridBagConstraints.HORIZONTAL, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(this, Box.createGlue(), 0, 3, 1, 1, 1.0,
+ 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+ }
+
+ public CRLCertInfoPane(CertInfo certInfo, ResourceSet resource) {
+ this(resource);
+
+ setCertInfo(certInfo);
+ }
+
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ f.setSize(400,400);
+ f.getContentPane().add(new CRLCertInfoPane(new CertInfo("Buddha", "Netscape", "Netscape", null, null, "Jan 1, 1998", "Jan 1, 2000", null, null, null, null), new ResourceSet("com.netscape.admin.certsrv.security.CertManagementResource")));
+ f.show();
+
+ }*/
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CRLDeleteCertDialog.java b/base/console/src/com/netscape/admin/certsrv/security/CRLDeleteCertDialog.java
new file mode 100644
index 000000000..6b1132ced
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CRLDeleteCertDialog.java
@@ -0,0 +1,201 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.security;
+
+import javax.swing.*;
+import javax.swing.border.*;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+
+import com.netscape.management.client.console.ConsoleInfo;
+
+
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+class CRLDeleteCertDialog extends AbstractDialog implements SuiConstants {
+
+
+
+ ConsoleInfo _consoleInfo;
+
+ KeyCertTaskInfo _taskInfo;
+ static boolean delete = false;
+
+ String _sie;
+
+ JButton bClose;
+ JButton bDelete;
+ JButton bHelp;
+
+ CertInfo _certInfo;
+ ResourceSet _resource;
+ String _crlname;
+ String _listtype;
+
+ CRLCertInfoPane _crlCertInfoPane;
+
+
+ class CRLDeleteCertActionListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ if (e.getActionCommand().equals("DELETE")) {
+ //call delete cert cgi
+ _taskInfo.clear();
+ _taskInfo.put("formop", "D");
+ _taskInfo.put("crlname", _crlname);
+ _taskInfo.put("sie", _sie);
+ _taskInfo.put("list_type", _listtype);
+
+ Response response = null;
+ try {
+ response = _taskInfo.exec(_taskInfo.SEC_ECRL);
+ } catch (Exception error) {
+ SuiOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(),
+ error.getMessage());
+ return;
+ }
+ if (!(((Message)(response.getMessages().elementAt(0))).
+ isFailure())) {
+ delete = true;
+ setVisible(false);
+ } else {
+ try {
+ MessageDialog.messageDialog( (Message)
+ (response.getMessages().elementAt(0)));
+ } catch (Exception e2) {
+ //shouldn't even be here in the first place. if cgi fail or return nothing
+ //then it should be handle right after KeyCertTaskInfo.exec(...) is called
+ //If exception occure here here then something is really mess up.
+ Debug.println("Error in decoding server messages");
+ }
+ }
+ } else if (e.getActionCommand().equals("CLOSE")) {
+ setVisible(false);
+ } else if (e.getActionCommand().equals("HELP")) {
+ Help help = new Help(_resource);
+ help.help("CRLDeleteCertDialog", "help");
+ }
+ }
+ }
+
+ public boolean isDeleted() {
+ return delete;
+ }
+
+ protected void show(String crlname, String list_type) {
+ delete = false;
+ _crlname = crlname;
+ _listtype = list_type;
+
+ _taskInfo.clear();
+ _taskInfo.put("sie", _sie);
+ _taskInfo.put("crlname", crlname);
+ _taskInfo.put("list_type", list_type);
+ try {
+ _taskInfo.exec(_taskInfo.SEC_ECRL);
+ } catch (Exception e) {
+ SuiOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(), e.getMessage());
+ return;
+ }
+
+ if (_taskInfo.getResponse().hasCertInfo()) {
+ setInfo(_taskInfo.getResponse().getCertInfo());
+ super.show();
+ } else {
+ Object[] message = new Object[2];
+ message[0] = _resource.getString("CRLDeleteCertDialog", "error");
+ SuiOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(), message);
+ }
+ }
+
+ private void setInfo(CertInfo certInfo) {
+ _certInfo = certInfo;
+
+ _crlCertInfoPane.setCertInfo(certInfo);
+ }
+
+
+ public CRLDeleteCertDialog(ConsoleInfo consoleInfo,
+ ResourceSet resource) {
+ super(null, "", true, NO_BUTTONS);
+
+ _consoleInfo = consoleInfo;
+ _sie = KeyCertUtility.createTokenName(_consoleInfo);
+ _resource = resource;
+ _taskInfo = new KeyCertTaskInfo(consoleInfo);
+
+ _crlCertInfoPane = new CRLCertInfoPane(resource);
+
+ Container mainPane = getContentPane();
+ mainPane.setLayout(new GridBagLayout());
+
+ GridBagUtil.constrain(mainPane, _crlCertInfoPane, 0, 0, 4, 1,
+ 1.0, 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0,
+ SuiConstants.DIFFERENT_COMPONENT_SPACE, 0);
+
+
+ CRLDeleteCertActionListener listener =
+ new CRLDeleteCertActionListener();
+
+ bClose = JButtonFactory.createCloseButton(listener);
+ GridBagUtil.constrain(mainPane, bClose, 1, 1, 1, 1, 1.0, 0.0,
+ GridBagConstraints.SOUTHEAST, GridBagConstraints.NONE,
+ 0, 0, 0, SuiConstants.COMPONENT_SPACE);
+
+
+ bDelete = JButtonFactory.createDeleteButton(listener);
+ GridBagUtil.constrain(mainPane, bDelete, 2, 1, 1, 1, 0.0, 0.0,
+ GridBagConstraints.SOUTHEAST, GridBagConstraints.NONE,
+ 0, 0, 0, SuiConstants.SEPARATED_COMPONENT_SPACE);
+
+
+ bHelp = JButtonFactory.createHelpButton(listener);
+ GridBagUtil.constrain(mainPane, bHelp, 3, 1, 1, 1, 0.0, 0.0,
+ GridBagConstraints.SOUTHEAST, GridBagConstraints.NONE,
+ 0, 0, 0, 0);
+
+
+
+ JButtonFactory.resizeGroup(bHelp, bClose, bDelete);
+
+ setSize(400, 225);
+ setResizable(false);
+ }
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ f.setSize(400,400);
+ f.show();
+
+ try {
+ UIManager.setLookAndFeel("javax.swing.plaf.windows.WindowsLookAndFeel");
+ SwingUtilities.updateComponentTreeUI(f.getContentPane());
+ } catch (Exception e) {}
+
+
+ CRLDeleteCertDialog d = new CRLDeleteCertDialog(new ConsoleInfo(), new ResourceSet("com.netscape.admin.certsrv.security.CertManagementResource"));
+ d.show();
+ }*/
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CRLManagementDialog.java b/base/console/src/com/netscape/admin/certsrv/security/CRLManagementDialog.java
new file mode 100644
index 000000000..f284fbb9c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CRLManagementDialog.java
@@ -0,0 +1,309 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.security;
+
+import com.netscape.management.client.console.ConsoleInfo;
+import com.netscape.management.client.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.table.*;
+import javax.swing.event.*;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+
+import netscape.ldap.*;
+
+import com.netscape.management.nmclf.*;
+
+/**
+ *
+ * Certificate Revocation List management dialog.
+ * This is a self contain dialog, that allow use to
+ * add/remove certificate fron a certificate revocation
+ * list. This is only the front end, the actuall work
+ * of removing and adding certificate will be handled
+ * by the server
+ *
+ * @version 1.0 98/07/10
+ * @author <A HREF="mailto:shihcm@netscape.com">shihcm@netscape.com</A>
+ *
+ */
+public class CRLManagementDialog extends AbstractDialog {
+
+ JButton bClose;
+ JButton bView;
+ JButton bAdd;
+ JButton bHelp;
+
+ ConsoleInfo _consoleInfo;
+
+ ResourceSet resource = new ResourceSet("com.netscape.admin.certsrv.security.CertManagementResource");
+
+ AddCRLCertificateDialog addCRLCertificateDialog;
+
+ CRLTable _crlTable;
+
+
+ private void parseCRLInfo(String response) {
+ }
+
+ //since can't over load protected and I don't
+ //want the interface to show so...
+ private void privateHelpInvoked() {
+ Help help = new Help(resource);
+ help.help("CRLManagementDialog", "help");
+ }
+
+
+ //since can't over load protected and I don't
+ //want the interface to show so...
+ private void privateCloseInvoked() {
+ super.okInvoked();
+ }
+
+ class CertManagementActionListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ if (e.getActionCommand().equals("CLOSE")) {
+ privateCloseInvoked();
+ } else if (e.getActionCommand().equals("HELP")) {
+ privateHelpInvoked();
+ } else if (e.getActionCommand().equals("VIEW")) {
+ _crlTable.showCert();
+ } else if (e.getActionCommand().equals("ADD")) {
+ addCRLCertificateDialog.show();
+ }
+ }
+ }
+
+
+ private JPanel getCertListPane() {
+ JPanel certListPane = new JPanel();
+ certListPane.setLayout(new GridBagLayout());
+ certListPane.setBorder( new TitledBorder(
+ new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE)),
+ resource.getString("CRLManagementDialog", "certificate")));
+
+
+ GridBagUtil.constrain(certListPane,
+ new JLabel(
+ resource.getString("CRLManagementDialog", "certDB")),
+ 0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.NONE, 0, 0, COMPONENT_SPACE, 0);
+
+
+ GridBagUtil.constrain(certListPane,
+ new JLabel(
+ resource.getString("CRLManagementDialog", "defaultToken"),
+ JLabel.RIGHT), 1, 0, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, 0);
+
+ _crlTable = new CRLTable(_consoleInfo, resource);
+ GridBagUtil.constrain(certListPane, _crlTable, 0, 1, 2, 1, 1.0,
+ 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+
+ return certListPane;
+ }
+
+ class AddCRLCertificateDialog extends AbstractDialog {
+ KeyCertTaskInfo _taskInfo;
+ JTextField _filename;
+ JRadioButton _ckl;
+ JRadioButton _crl;
+
+ public AddCRLCertificateDialog(ConsoleInfo consoleInfo) {
+ super(null,
+ CRLManagementDialog.this.resource.getString("AddCRLCertificateDialog",
+ "dialogTitle"), true, OK | CANCEL | HELP);
+ _taskInfo = new KeyCertTaskInfo(consoleInfo);
+
+ Container p = getContentPane();
+ p.setLayout(new GridBagLayout());
+
+ _crl = new JRadioButton(
+ resource.getString("AddCRLCertificateDialog",
+ "crlfiletype"), true);
+ _ckl = new JRadioButton(
+ resource.getString("AddCRLCertificateDialog",
+ "cklfiletype"), false);
+
+ ButtonGroup buttonGroup = new ButtonGroup();
+ buttonGroup.add(_crl);
+ buttonGroup.add(_ckl);
+
+ GridBagUtil.constrain(p,
+ new JLabel(
+ resource.getString("AddCRLCertificateDialog",
+ "filename")), 0, 0, 2, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH,
+ 0, 0, SuiConstants.COMPONENT_SPACE, 0);
+
+ _filename = new JTextField(30);
+ GridBagUtil.constrain(p, _filename, 0, 1, 2, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH,
+ 0, 0, 0, 0);
+
+ GridBagUtil.constrain(p, (Component)_crl, 0, 2, 2, 1, 1.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(p, (Component)_ckl, 0, 3, 2, 1, 1.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ pack();
+ setResizable(false);
+ }
+
+
+ CRLAddCertDialog _crlAddCertDialog =
+ new CRLAddCertDialog(_consoleInfo, resource);
+ protected void okInvoked() {
+ _crlAddCertDialog.show(_filename.getText(),
+ _ckl.isSelected() ? "CKL" : "CRL");
+ setVisible(false);
+ if (_crlAddCertDialog.isModified()) {
+ CertInfo certInfo = _crlAddCertDialog.getCertInfo();
+ //only need the first line where the issuer's name locate
+ String issuer = certInfo.getIssuer();
+ _crlTable.addCert(
+ issuer.substring(0, issuer.indexOf("\n")),
+ certInfo.getValidTo(),
+ _ckl.isSelected() ? "CKL" : "CRL");
+ UtilConsoleGlobals.getActivatedFrame().setCursor(
+ new Cursor(Cursor.WAIT_CURSOR));
+ _crlTable.update();
+ UtilConsoleGlobals.getActivatedFrame().setCursor(
+ new Cursor(Cursor.DEFAULT_CURSOR));
+ }
+ }
+
+ protected void helpInvoked() {
+ Help help = new Help(resource);
+ help.help("AddCRLCertificateDialog", "help");
+ }
+ }
+
+
+ private JPanel getControlButtons() {
+ JPanel controlPanel = new JPanel();
+ controlPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 0, 0));
+ controlPanel.setBorder(
+ new EmptyBorder(SuiConstants.VERT_WINDOW_INSET, 0, 0, 0));
+
+ CertManagementActionListener listener =
+ new CertManagementActionListener();
+
+ bClose = JButtonFactory.createCloseButton(listener);
+ controlPanel.add(bClose);
+
+ controlPanel.add( Box.createRigidArea(
+ new Dimension(SuiConstants.COMPONENT_SPACE, 0)));
+
+ bView = JButtonFactory.create(
+ resource.getString("CRLManagementDialog", "view"));
+ bView.addActionListener(listener);
+ bView.setActionCommand("VIEW");
+ controlPanel.add(bView);
+
+ controlPanel.add( Box.createRigidArea(
+ new Dimension(SuiConstants.COMPONENT_SPACE, 0)));
+
+ bAdd = JButtonFactory.create(
+ resource.getString("CRLManagementDialog", "add"));
+ bAdd.addActionListener(listener);
+ bAdd.setActionCommand("ADD");
+ controlPanel.add(bAdd);
+
+ controlPanel.add( Box.createRigidArea(
+ new Dimension(SuiConstants.SEPARATED_COMPONENT_SPACE, 0)));
+
+ bHelp = JButtonFactory.createHelpButton(listener);
+ controlPanel.add(bHelp);
+
+ JButtonFactory.resizeGroup(bHelp, bClose, bView, bAdd);
+
+ return controlPanel;
+ }
+
+ /**
+ * Create a Certificate Revocation List Management dialog
+ *
+ * @param consoleInfo Console information
+ *
+ */
+ public CRLManagementDialog(ConsoleInfo consoleInfo) {
+ super(null, "", true, NO_BUTTONS);
+
+ _consoleInfo = consoleInfo;
+ addCRLCertificateDialog = new AddCRLCertificateDialog(_consoleInfo);
+
+
+ UtilConsoleGlobals.getActivatedFrame().setCursor(
+ new Cursor(Cursor.WAIT_CURSOR));
+
+ //_consoleInfo = consoleInfo;
+
+ setTitle(resource.getString("CRLManagementDialog", "title"));
+
+ JPanel mainPane = new JPanel();
+ mainPane.setLayout(new BorderLayout());
+
+
+ mainPane.add("Center", getCertListPane());
+
+ mainPane.add("South", getControlButtons());
+
+ getContentPane().add(mainPane);
+
+ //pack();
+ setMinimumSize(400, 400);
+ //setResizable(false);
+
+ UtilConsoleGlobals.getActivatedFrame().setCursor(
+ new Cursor(Cursor.DEFAULT_CURSOR));
+
+ if (!(_crlTable.isTableSetup())) {
+ return;
+ }
+
+ validate();
+ invalidate();
+ show();
+ }
+
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ f.setSize(200,200);
+ f.show();
+ UtilConsoleGlobals.setActivatedFrame(f);
+ try {
+ UIManager.setLookAndFeel("javax.swing.plaf.windows.WindowsLookAndFeel");
+ SwingUtilities.updateComponentTreeUI(f.getContentPane());
+ } catch (Exception e) {}
+
+ CRLManagementDialog d = new CRLManagementDialog(new ConsoleInfo());
+ }*/
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CRLTable.java b/base/console/src/com/netscape/admin/certsrv/security/CRLTable.java
new file mode 100644
index 000000000..b56a3c585
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CRLTable.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.admin.certsrv.security;
+
+import com.netscape.management.client.console.ConsoleInfo;
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+import javax.swing.*;
+import javax.swing.table.*;
+
+import java.awt.event.*;
+import java.util.*;
+import java.io.*;
+import java.awt.*;
+
+
+class CRLTable extends JPanel implements MouseListener {
+
+ ResourceSet _resource;
+ KeyCertTaskInfo _taskInfo;
+ String _sie;
+ ConsoleInfo _consoleInfo;
+
+ CRLDeleteCertDialog _crlDeleteCertDialog = null;
+
+ String startCRL = "-----BEGIN CRL LIST-----";
+ String endCRL = "-----END CRL LIST-----";
+ String startCKL = "-----BEGIN CKL LIST-----";
+ String endCKL = "-----END CKL LIST-----";
+
+ String certName;
+ boolean setupComplete;
+
+ private Vector getRowData(String data) {
+ Vector rowData = new Vector();
+ BufferedReader stream = new BufferedReader(new StringReader(data));
+
+ // First, read CRL's
+ try {
+ while (!(stream.readLine().equals(startCRL))) {
+ }
+
+ String line;
+ while (!((line = stream.readLine()).equals(endCRL))) {
+ StringTokenizer token =
+ new StringTokenizer(line, ";", false);
+ Vector row = new Vector();
+ //get cert name and expire date and setup a row
+ row.addElement(token.nextToken());
+ row.addElement(token.nextToken());
+ row.addElement((String)"CRL");
+ rowData.addElement(row);
+ }
+ } catch (IOException e) { /*error message here */
+ }
+
+ // Next, read CKL's
+ try {
+ while (!(stream.readLine().equals(startCKL))) {
+ }
+
+ String line;
+ while (!((line = stream.readLine()).equals(endCKL))) {
+ StringTokenizer token =
+ new StringTokenizer(line, ";", false);
+ Vector row = new Vector();
+ //get cert name and expire date and setup a row
+ row.addElement(token.nextToken());
+ row.addElement(token.nextToken());
+ row.addElement((String)"CKL");
+ rowData.addElement(row);
+ }
+ } catch (IOException e) { /*error message here */
+ }
+
+ return rowData;
+ }
+
+ private Vector getColumnHeader() {
+ Vector column = new Vector();
+ column.addElement(_resource.getString("CRLTable", "column1"));
+ column.addElement(_resource.getString("CRLTable", "column2"));
+ column.addElement(_resource.getString("CRLTable", "column3"));
+ return column;
+ }
+
+ public void showCert() {
+ if (_crlTable.getSelectedRow() != -1) {
+ _crlDeleteCertDialog.show( (String)
+ (_crlTable.getValueAt(_crlTable.getSelectedRow(),
+ 0)), (String)
+ (_crlTable.getValueAt(_crlTable.getSelectedRow(), 2)));
+ if (_crlDeleteCertDialog.isDeleted()) {
+ _crlTableModel.deleteRow(_crlTable.getSelectedRow());
+ repaint();
+ }
+ }
+
+ }
+
+ JTable _crlTable;
+ public void mouseClicked(MouseEvent e) {
+ int row = _crlTable.rowAtPoint(e.getPoint());
+
+ if (e.getClickCount() < 2)
+ return;
+ if (row == -1) {
+ _crlTable.clearSelection();
+ } else {
+ showCert();
+ }
+ }
+ public void mouseEntered(MouseEvent e) { }
+ public void mouseExited(MouseEvent e) { }
+ public void mousePressed(MouseEvent e) { }
+ public void mouseReleased(MouseEvent e) { }
+
+
+ public void update() {
+ _taskInfo = new KeyCertTaskInfo(_consoleInfo);
+ _sie = KeyCertUtility.createTokenName(_consoleInfo);
+ _crlDeleteCertDialog =
+ new CRLDeleteCertDialog(_consoleInfo, _resource);
+
+ _taskInfo.put("sie", _sie);
+ try {
+ _taskInfo.exec(_taskInfo.SEC_MGCRL);
+ } catch (Exception e) {
+ SuiOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(), e.getMessage());
+ setupComplete = false;
+ return;
+ }
+
+ if (_crlTableModel == null) {
+ _crlTableModel = new CRLTableModel( getRowData(
+ _taskInfo.getResponse().getServerResponse()),
+ getColumnHeader());
+ } else {
+ _crlTableModel.update( getRowData(
+ _taskInfo.getResponse().getServerResponse()),
+ getColumnHeader());
+ }
+
+ }
+
+ public CRLTable(ConsoleInfo consoleInfo, ResourceSet resource) {
+ setLayout(new BorderLayout());
+
+ setupComplete = true;
+
+ _resource = resource;
+ _consoleInfo = consoleInfo;
+
+ update();
+
+ _crlTable = new SuiTable();
+ //_crlTableModel = new CRLTableModel(getRowData(_taskInfo.getResponse().getServerResponse()), getColumnHeader());
+ _crlTable.setModel(_crlTableModel);
+ _crlTable.setAutoResizeMode(_crlTable.AUTO_RESIZE_ALL_COLUMNS);
+ _crlTable.addMouseListener(this);
+ //_crlTable.setMultipleSelectionAllowed(false);
+ _crlTable.getSelectionModel().setSelectionMode(
+ DefaultListSelectionModel.SINGLE_SELECTION);
+ //_crlTable.setSelectionModel(new DefaultSingleSelectionModel());
+
+
+ // Put the table and header into a scrollPane
+ JScrollPane scrollPane = new JScrollPane(
+ JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ JTableHeader tableHeader = _crlTable.getTableHeader();
+
+ // create and add the column heading to the scrollpane's
+ // column header viewport
+ JViewport headerViewport = new JViewport();
+ headerViewport.setLayout(new BorderLayout()/*new BoxLayout(headerViewport, BoxLayout.X_AXIS)*/);
+ headerViewport.add(tableHeader);
+ scrollPane.setColumnHeader(headerViewport);
+
+ // add the table to the viewport
+ JViewport mainViewPort = scrollPane.getViewport();
+ mainViewPort.add(_crlTable);
+
+ // speed up resizing repaints by turning off live cell updates
+ tableHeader.setUpdateTableInRealTime(false);
+
+ add(scrollPane);
+
+ }
+
+ CRLTableModel _crlTableModel;
+
+ public void repaint() {
+ _crlTable.validate();
+ _crlTable.repaint();
+ super.repaint();
+ }
+
+ public void addCert(String issuer, String expires, String type) {
+ _crlTableModel.addRow(issuer, expires, type);
+ repaint();
+ }
+
+ public boolean isTableSetup() {
+ return setupComplete;
+
+ }
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ //f.setSize(400,400);
+ ResourceSet resource = new ResourceSet("com.netscape.admin.certsrv.security.CertManagementResource");
+ f.getContentPane().add(new CRLTable(new ConsoleInfo(), resource));
+ f.pack();
+ f.show();
+ }*/
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CRLTableModel.java b/base/console/src/com/netscape/admin/certsrv/security/CRLTableModel.java
new file mode 100644
index 000000000..4fe7ded08
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CRLTableModel.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.admin.certsrv.security;
+
+import java.util.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+import javax.swing.table.*;
+import javax.swing.event.*;
+
+
+class CRLTableModel extends AbstractTableModel {
+
+ Vector _header;
+ Vector _rowData = new Vector();
+ Vector _tableModelListener = new Vector();
+
+ public CRLTableModel(Vector CRL, Vector columnIdentifier) {
+ update(CRL, columnIdentifier);
+ }
+
+ public void update(Vector CRL, Vector columnIdentifier) {
+ _header = columnIdentifier;
+ _rowData = CRL;
+ }
+
+ public void addRow(String issuer, String expires, String type) {
+ Vector row = new Vector();
+ row.addElement(issuer);
+ row.addElement(expires);
+ row.addElement(type);
+ _rowData.addElement(row);
+ }
+
+ public int getRowCount() {
+ return _rowData.size();
+ }
+
+ public int getColumnCount() {
+ return _header.size();
+ }
+
+ public String getColumnName(int columnIndex) {
+ return (columnIndex >= _header.size() ? "":
+ (String)(_header.elementAt(columnIndex)));
+ }
+
+ public Object getValueAt(int rowIndex, int columnIndex) {
+ Object o = null;
+
+ try {
+ o = ((Vector)(_rowData.elementAt(rowIndex))).elementAt(
+ columnIndex);
+ } catch (Exception e) {}
+
+ return o;
+ }
+
+
+ public void deleteRow(int rowIndex) {
+ try {
+ _rowData.removeElementAt(rowIndex);
+ } catch (Exception e) {}
+ }
+
+ public void deleteAllRows() {
+ _rowData.removeAllElements();
+ }
+
+ public void addTableModelListener(TableModelListener l) {
+ _tableModelListener.addElement(l);
+ }
+
+ public void removeTableModelListener(TableModelListener l) {
+ _tableModelListener.removeElement(l);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CertBasicInfo.java b/base/console/src/com/netscape/admin/certsrv/security/CertBasicInfo.java
new file mode 100644
index 000000000..0d746324d
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CertBasicInfo.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.admin.certsrv.security;
+
+import java.util.*;
+
+import com.netscape.management.client.util.ResourceSet;
+
+class CertBasicInfo {
+ String _certName;
+ String _certType;
+ String _certExpiration;
+
+ String _certNameLabel;
+ String _certTypeLabel;
+ String _certExpirationLabel;
+
+ public CertBasicInfo(String certName, String certType,
+ String certExpiration) {
+ _certName = certName;
+ _certType = certType;
+ _certExpiration = certExpiration;
+
+ ResourceSet resource = new ResourceSet("com.netscape.admin.certsrv.security.CertManagementResource");
+ _certNameLabel = resource.getString("CertBasicInfo", "labelName");
+ _certTypeLabel = resource.getString("CertBasicInfo", "lableType");
+ _certExpirationLabel = resource.getString("CertBasicInfo", "labelExpire");
+ }
+
+ public String getCertName() {
+ return _certName;
+ }
+
+ public String getCertType() {
+ return _certType;
+ }
+
+ public String getCertExpiration() {
+ return _certExpiration;
+ }
+
+
+ public String getCertInfo(String headerIndex) {
+ String nReturn = "";
+
+ if (headerIndex.equals(_certNameLabel)) {
+ nReturn = getCertName();
+ } else if (headerIndex.equals(_certTypeLabel)) {
+ nReturn = getCertType();
+ } else if (headerIndex.equals(_certExpirationLabel)) {
+ nReturn = getCertExpiration();
+ }
+
+ return nReturn;
+ }
+
+ static public Vector getCertTitleLabels() {
+ Vector title = new Vector();
+
+ ResourceSet resource = new ResourceSet("com.netscape.admin.certsrv.security.CertManagementResource");
+ title.addElement(resource.getString("CertBasicInfo", "labelName"));
+ title.addElement(resource.getString("CertBasicInfo", "lableType"));
+ title.addElement(resource.getString("CertBasicInfo", "labelExpire"));
+
+ return title;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CertDetailInfoDialog.java b/base/console/src/com/netscape/admin/certsrv/security/CertDetailInfoDialog.java
new file mode 100644
index 000000000..3c1e39821
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CertDetailInfoDialog.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.admin.certsrv.security;
+
+import javax.swing.*;
+import javax.swing.border.*;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+
+import com.netscape.management.client.console.ConsoleInfo;
+
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+class CertDetailInfoDialog extends AbstractDialog implements SuiConstants {
+
+
+ JLabel serialNumber = new JLabel();
+ JLabel valid = new JLabel();
+ JLabel fingerprint = new JLabel();
+ JLabel trust = new JLabel();
+ JPanel mainPane = new JPanel();
+
+ ResourceSet resource = new ResourceSet("com.netscape.admin.certsrv.security.CertManagementResource");
+
+ void setCertInfo(CertInfo certInfo) {
+
+ serialNumber.setText(certInfo.getSerialNumber());
+ valid.setText( KeyCertUtility.replace( KeyCertUtility.replace(
+ resource.getString("CertDetailInfoDialog",
+ "validFromTo"), "%FROM", certInfo.getValidFrom()), "%TO",
+ certInfo.getValidTo()));
+ fingerprint.setText(certInfo.getFingerPrint());
+ trust.setText(certInfo.trusted() ?
+ resource.getString("CertDetailInfoDialog", "trustString") :
+ resource.getString("CertDetailInfoDialog", "notTrustString"));
+
+ mainPane.doLayout();
+ mainPane.repaint();
+
+ pack();
+ }
+
+ public CertDetailInfoDialog(JFrame parent, CertInfo certInfo) {
+ super(parent, "", true, CLOSE);
+
+ setTitle(resource.getString("CertDetailInfoDialog", "title"));
+
+ mainPane.setLayout(new GridBagLayout());
+ mainPane.setBorder( new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE)));
+
+ int y = 0;
+ GridBagUtil.constrain(mainPane,
+ new JLabel( resource.getString("CertDetailInfoDialog",
+ "serialNumberLabel")), 0, y, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(mainPane, serialNumber, 0, ++y, 1, 1,
+ 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, DIFFERENT_COMPONENT_SPACE,
+ COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(mainPane, valid, 0, ++y, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(mainPane,
+ new JLabel( resource.getString("CertDetailInfoDialog",
+ "fingerprintLabel")), 0, ++y, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(mainPane, fingerprint, 0, ++y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, DIFFERENT_COMPONENT_SPACE,
+ COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(mainPane, trust, 0, ++y, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, 0);
+
+ getContentPane().add(mainPane);
+
+ setCertInfo(certInfo);
+
+ pack();
+ setMinimumSize(getSize());
+ setResizable(false);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CertInfo.java b/base/console/src/com/netscape/admin/certsrv/security/CertInfo.java
new file mode 100644
index 000000000..40cd071d4
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CertInfo.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.admin.certsrv.security;
+
+
+class CertInfo {
+
+ String _certName;
+ String _issuer;
+ String _subject;
+ String _serialNumber;
+ String _version;
+ String _validFrom;
+ String _validTo;
+ String _fingerPrint;
+ boolean _trustCert;
+ boolean _certDeleted;
+ String _certTitle;
+
+
+ public CertInfo(String certName, String issuer, String subject,
+ String serialNumber, String version, String validFrom,
+ String validTo, String fingerPrint, String trustCert,
+ String certDeleted, String certTitle) {
+ _certName = certName;
+ _issuer = issuer;
+ _subject = subject;
+ _serialNumber = serialNumber;
+ _version = version;
+ _validFrom = validFrom;
+ _validTo = validTo;
+ _fingerPrint = fingerPrint;
+ _trustCert = (trustCert != null) ? trustCert.equals("1") : false;
+ _certDeleted =
+ (certDeleted != null) ? certDeleted.equals("1") : false;
+ _certTitle = certTitle;
+ }
+
+ public String getCertName() {
+ return _certName;
+ }
+ public String getIssuer() {
+ return _issuer;
+ }
+ public String getSubject() {
+ return _subject;
+ }
+ public String getSerialNumber() {
+ return _serialNumber;
+ }
+ public String getVersion() {
+ return _version;
+ }
+ public String getValidFrom() {
+ return _validFrom;
+ }
+ public String getValidTo() {
+ return _validTo;
+ }
+ public String getFingerPrint() {
+ return _fingerPrint;
+ }
+ public boolean trusted() {
+ return _trustCert;
+ }
+ public boolean getCertDeleted() {
+ return _certDeleted;
+ }
+ public String getCertTitle() {
+ return _certTitle;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CertInfoDialog.java b/base/console/src/com/netscape/admin/certsrv/security/CertInfoDialog.java
new file mode 100644
index 000000000..910d38a9c
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CertInfoDialog.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.admin.certsrv.security;
+
+import javax.swing.*;
+import javax.swing.border.*;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+
+import com.netscape.management.client.console.ConsoleInfo;
+
+
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+/**
+ *
+ * UI to display subject and issuer of the certificate, and
+ * allow user to change trust, delete, or view detail information
+ * of this certificate
+ *
+ * @version 1.0 98/07/10
+ * @author shihcm@netscape.com
+ * @see com.netscape.admin.certsrv.security.CertDetailInfoDialog
+ * @see com.netscape.admin.certsrv.security.CertInfo
+ *
+ */
+class CertInfoDialog extends AbstractDialog implements SuiConstants {
+
+
+ /**
+ * String for trust and none trusted status of the certificate
+ * String is localized and will be retrived from the properties file
+ */
+ String trustString, notTrustString;
+
+ /**
+ * Task info, the communication channel that calls the server to execute the cgi
+ */
+ KeyCertTaskInfo _taskInfo;
+
+
+ /**
+ * Certificate information, certificate info used to populate this gui
+ */
+ CertInfo _certInfo;
+
+ /**
+ * cn of the sie. ie. admin-serv-buddha
+ * Note that the key & cert db file are named using the sie.
+ */
+ String alias;
+
+ /**
+ * Properties file, contain all the localized string
+ */
+ ResourceSet resource = new ResourceSet("com.netscape.admin.certsrv.security.CertManagementResource");
+
+ /**
+ * After this dilaog is disposed, the routine(CertManagementDialog) that opens this ui will
+ * need to know whether the cert presented has been deleted and update it's gui accordingly.
+ */
+ static boolean delete = false;
+
+ /**
+ * Owner of this dialog
+ */
+ JFrame _parent;
+
+ JLabel certName = new JLabel();
+ MultilineLabel issuer = new MultilineLabel(6, 5);
+ MultilineLabel subject = new MultilineLabel(6, 5);
+
+ JButton bDetail;
+ JButton bDelete;
+ JButton bTrust;
+
+ JLabel _issuerLabel;
+ JLabel _subjectLabel;
+
+ /**
+ * Trust status of the cert that is presented
+ */
+ boolean trustedCert;
+
+
+ private boolean promptBeforeDelete() {
+ return SuiOptionPane.showConfirmDialog(this,
+ resource.getString("CertInfoDialog", "areYouSure"),
+ resource.getString("CertInfoDialog", "confirmTitle"),
+ SuiOptionPane.YES_NO_OPTION) == SuiOptionPane.YES_OPTION;
+ }
+
+ private void deleteSuccess() {
+ SuiOptionPane.showMessageDialog(this,
+ resource.getString("CertInfoDialog", "certDeleted"));
+ }
+
+ /**
+ *
+ * Inner class, where all the action will execute.
+ * 3 action can be taken on the certificate: Detail, Delete, [Trust|Reject]
+ *
+ * Detail: vew other certificate information that is not currently been
+ * displayed by this dialog
+ * Delete: Delete certificate from the certificate database
+ * Trust: Change the certificate's trust status to trust
+ * Reject: Change the certificate's trust status to do not trust
+ *
+ * @see com.netscape.admin.certsrv.security.CertDetailInfoDialog
+ */
+ class CertInfoActionListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ delete = false;
+
+ if (_taskInfo == null) {
+ if (e.getActionCommand().equals("CLOSE")) {
+ CertInfoDialog.this.closeInvoked();
+ } else if (e.getActionCommand().equals("DELETE")) {
+ if (promptBeforeDelete()) {
+ deleteSuccess();
+ delete = true;
+ setVisible(false);
+ }
+ } else if (e.getActionCommand().equals("HELP")) {
+ helpInvoked();
+ }
+
+ } else {
+ if (e.getActionCommand().equals("DETAIL")) {
+ (new CertDetailInfoDialog(_parent, _certInfo)).show();
+ } else if (e.getActionCommand().equals("DELETE")) {
+ if (!promptBeforeDelete()) {
+ return;
+ }
+ //call delete cert cgi
+ _taskInfo.clear();
+ _taskInfo.put("certnn", _certInfo.getCertName());
+ _taskInfo.put("formop", "D");
+ _taskInfo.put("alias", alias);
+ Response response = null;
+ try {
+ response = _taskInfo.exec(_taskInfo.SEC_ECRT);
+ } catch (Exception error) {
+ SuiOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(),
+ error.getMessage());
+ return;
+ }
+
+ //if (response.hasCertInfo()) {
+ if (!(((Message)(response.getMessages().elementAt(0))).
+ isFailure())) {
+ deleteSuccess();
+ delete = true;
+ setVisible(false);
+ } else {
+ try {
+ MessageDialog.messageDialog( (Message)
+ (response.getMessages().elementAt(0)));
+ } catch (Exception e2) {
+ //shouldn't even be here in the first place. if cgi fail or return nothing
+ //then it should be handle right after KeyCertTaskInfo.exec(...) is called
+ //If exception occure here here then something is really mess up
+ Debug.println("Error in decoding server messages");
+ }
+ }
+ }
+ else if (e.getActionCommand().equals("TRUST")) {
+ //call trust cert cgi
+ //need to display a warning message first
+ _taskInfo.clear();
+ _taskInfo.put("certnn", _certInfo.getCertName());
+ _taskInfo.put("formop", "C");
+ _taskInfo.put("alias", alias);
+ Response response = null;
+ try {
+ response = _taskInfo.exec(_taskInfo.SEC_ECRT);
+ } catch (Exception error2) {
+ SuiOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(),
+ error2.getMessage());
+ return;
+ }
+ /*if (response.hasCertInfo()) {
+ setCertInfo(response.getCertInfo());
+ }*/
+
+ try {
+ if (!(((Message)
+ (response.getMessages().elementAt(0))).
+ isFailure())) {
+ trustedCert = !trustedCert;
+ bTrust.setText(trustedCert ?
+ resource.getString("CertInfoDialog",
+ "reject") :
+ resource.getString("CertInfoDialog",
+ "trust"));
+ }
+
+ MessageDialog.messageDialog( (Message)
+ (response.getMessages().elementAt(0)));
+ } catch (Exception e3) {
+ //shouldn't even be here in the first place. if cgi fail or return nothing
+ //then it should be handle right after KeyCertTaskInfo.exec(...) is called
+ //If exception occure here here then something is really mess up.
+ Debug.println("Error in decoding server messages");
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ *
+ * Update certificate information.
+ * Without disposing the dialog this method allows the reuse the the same dialog
+ * by repopulating it with new certificate information
+ *
+ * @param certInfo contain certificate information to be displayed
+ *
+ */
+ void setCertInfo(CertInfo certInfo) {
+ _certInfo = certInfo;
+
+ certName.setText(certInfo.getCertName());
+ issuer.setText(certInfo.getIssuer());
+ subject.setText(certInfo.getSubject());
+
+ if (_taskInfo != null) {
+ trustedCert = certInfo.trusted();
+ bTrust.setText(trustedCert ?
+ resource.getString("CertInfoDialog", "reject") :
+ resource.getString("CertInfoDialog", "trust"));
+ }
+ }
+
+
+ /**
+ *
+ * Invoke on-line help
+ *
+ */
+ protected void helpInvoked() {
+ Help help = new Help(resource);
+ help.help("CertInfoDialog", "help");
+ }
+
+ protected void closeInvoked() {
+ super.closeInvoked();
+ }
+
+
+ /**
+ *
+ * @return a panel contain subject and issuer
+ *
+ * [Panel]
+ * [Subject] [Issuer]
+ * [Panel]
+ *
+ */
+ private JPanel getSubjectIssuerPane() {
+ JPanel subjectIssuerPane = new JPanel();
+ subjectIssuerPane.setLayout(new GridBagLayout());
+
+ _issuerLabel =
+ new JLabel(resource.getString("CertInfoDialog", "issuer"));
+ _subjectLabel =
+ new JLabel(resource.getString("CertInfoDialog", "subject"));
+
+ //issuer.getCaret().setVisible(false);
+ //issuer.setSelectionColor(issuer.getBackground());
+ //issuer.setEditable(false);
+ //subject.getCaret().setVisible(false);
+ //subject.setSelectionColor(issuer.getBackground());
+ //subject.setEditable(false);
+
+ GridBagUtil.constrain(subjectIssuerPane, _subjectLabel, 0, 0,
+ 1, 1, 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(subjectIssuerPane, _issuerLabel, 2, 0, 1,
+ 1, 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(subjectIssuerPane,
+ Box.createRigidArea(new Dimension(COMPONENT_SPACE, 0))
+ , 1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.NONE, 0, 0, 0, 0);
+
+ JScrollPane subjectScrollPane = new JScrollPane(subject,
+ JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+ JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ subjectScrollPane.setBorder(
+ new CompoundBorder(UITools.createLoweredBorder(),
+ new EmptyBorder(VERT_COMPONENT_INSET,
+ HORIZ_COMPONENT_INSET, VERT_COMPONENT_INSET,
+ HORIZ_COMPONENT_INSET)));
+ GridBagUtil.constrain(subjectIssuerPane, subjectScrollPane, 0,
+ 1, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.HORIZONTAL, 0, 0,
+ DIFFERENT_COMPONENT_SPACE, 0);
+
+ JScrollPane issuerScrollPane = new JScrollPane(issuer,
+ JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+ JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ issuerScrollPane.setBorder(
+ new CompoundBorder(UITools.createLoweredBorder(),
+ new EmptyBorder(VERT_COMPONENT_INSET,
+ HORIZ_COMPONENT_INSET, VERT_COMPONENT_INSET,
+ HORIZ_COMPONENT_INSET)));
+ GridBagUtil.constrain(subjectIssuerPane, issuerScrollPane, 2,
+ 1, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.HORIZONTAL, 0, 0,
+ DIFFERENT_COMPONENT_SPACE, 0);
+
+ return subjectIssuerPane;
+ }
+
+ /**
+ *
+ * @return a panel contain certificate name and what ever was return by getSubjectIssuerPane()
+ * [PANEL]
+ * Certificate Name
+ * getSubjectIssuerPane()
+ * [PANEL]
+ *
+ * @see #getSubjectIssuerPane
+ */
+ private JPanel getInfoPane() {
+ JPanel infoPane = new JPanel();
+ infoPane.setLayout(new GridBagLayout());
+
+ int y = 0;
+
+
+ GridBagUtil.constrain(infoPane, certName, 0, y, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH,
+ COMPONENT_SPACE, 0, COMPONENT_SPACE, 0);
+
+
+ GridBagUtil.constrain(infoPane, getSubjectIssuerPane(), 0, ++y,
+ 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ return infoPane;
+ }
+
+
+
+ /**
+ *
+ * @return Panel contain a row of button(Delete, View, [Trust|Reject])
+ * [PANEL]
+ * [bDetail] [bDelete] [bTrust|bReject]
+ * [PANEL]
+ *
+ */
+ private JPanel getControlPane() {
+
+ JPanel controlPane = new JPanel();
+ controlPane.setLayout(new GridBagLayout());
+ CertInfoActionListener listener = new CertInfoActionListener();
+
+ if (_taskInfo == null) {
+
+ GridBagUtil.constrain(controlPane,
+ JButtonFactory.createCloseButton(listener), 0, 0,
+ 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH,
+ DIFFERENT_COMPONENT_SPACE, 0, 0, COMPONENT_SPACE);
+
+ GridBagUtil.constrain(controlPane,
+ JButtonFactory.create(
+ resource.getString("CertInfoDialog", "delete"),
+ listener, "DELETE"), 1, 0, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH,
+ DIFFERENT_COMPONENT_SPACE, 0, 0, COMPONENT_SPACE);
+
+ GridBagUtil.constrain(controlPane,
+ JButtonFactory.createHelpButton(listener), 2, 0,
+ 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH,
+ DIFFERENT_COMPONENT_SPACE, 0, 0, 0);
+ } else {
+ JPanel certButtonPane = new JPanel();
+ //certButtonPane.setLayout(new BoxLayout(certButtonPane, BoxLayout.X_AXIS));
+ certButtonPane.setLayout(new GridBagLayout());
+
+ certButtonPane.setBorder( new TitledBorder(
+ new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE)),
+ resource.getString("CertInfoDialog", "certificate")));
+
+ bDetail = JButtonFactory.create(
+ resource.getString("CertInfoDialog", "detail"));
+ bDetail.addActionListener(listener);
+ bDetail.setActionCommand("DETAIL");
+
+ bDelete = JButtonFactory.create(
+ resource.getString("CertInfoDialog", "delete"));
+ bDelete.addActionListener(listener);
+ bDelete.setActionCommand("DELETE");
+
+ JButtonFactory.resizeGroup(bDetail, bDelete);
+
+ setTitle(resource.getString("CertInfoDialog", "certificate"));
+
+ //certButtonPane.add(bDetail);
+ //certButtonPane.add(Box.createRigidArea(new Dimension(COMPONENT_SPACE, 0)));
+ //certButtonPane.add(bDelete);
+ GridBagUtil.constrain(certButtonPane, bDetail, 0, 0, 1, 1,
+ 1.0, 0.0, GridBagConstraints.WEST,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+ GridBagUtil.constrain(certButtonPane, bDelete, 1, 0, 1, 1,
+ 1.0, 0.0, GridBagConstraints.EAST,
+ GridBagConstraints.BOTH, 0, COMPONENT_SPACE, 0, 0);
+
+ JPanel trustCAButtonPane = new JPanel();
+ trustCAButtonPane.setLayout(new GridBagLayout());
+ trustCAButtonPane.setBorder( new TitledBorder(
+ new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE)),
+ resource.getString("CertInfoDialog", "trustCA")));
+
+
+
+ bTrust = JButtonFactory.create(
+ resource.getString("CertInfoDialog", "reject"));
+ bTrust.addActionListener(listener);
+ bTrust.setActionCommand("TRUST");
+
+ JButtonFactory.resizeGroup(bTrust,
+ JButtonFactory.create(
+ resource.getString("CertInfoDialog", "reject")));
+
+ //trustCAButtonPane.add(bTrust);
+ GridBagUtil.constrain(trustCAButtonPane, bTrust, 0, 0, 1,
+ 1, 1.0, 0.0, GridBagConstraints.WEST,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(controlPane, certButtonPane, 0, 0, 1,
+ 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(controlPane, trustCAButtonPane, 1, 0,
+ 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+ }
+
+ return controlPane;
+ }
+
+
+ void init(CertInfo certInfo) {
+ JPanel mainPane = new JPanel();
+ mainPane.setBorder( new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE)));
+ mainPane.setLayout(new BorderLayout());
+
+ mainPane.add("Center", getInfoPane());
+
+ if (_taskInfo == null) {
+ getContentPane().add("South", getControlPane());
+ } else {
+ mainPane.add("South", getControlPane());
+ }
+
+ getContentPane().add(mainPane);
+
+ setCertInfo(certInfo);
+
+ pack();
+ setMinimumSize(getSize());
+ setResizable(false);
+ }
+
+ /**
+ *
+ * Construct a certificate information dialog
+ *
+ * @param parent the owner of the dialog
+ * @param certInfo contain certificate information to be displayed
+ * @param taskInfo task module that carry out the action for change trust, delete, or get certificate information
+ *
+ */
+ public CertInfoDialog(JFrame parent, CertInfo certInfo,
+ KeyCertTaskInfo taskInfo) {
+ super(parent, "", true, CLOSE | HELP);
+
+ _taskInfo = taskInfo;
+ _parent = parent;
+
+ alias = (String)(taskInfo.get("alias"));
+
+ init(certInfo);
+ }
+
+ public CertInfoDialog(JFrame parent, CertInfo certInfo) {
+ super(parent, "", true/*, CLOSE | HELP*/);
+
+ _parent = parent;
+
+ init(certInfo);
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CertInstallCertInfoPane.java b/base/console/src/com/netscape/admin/certsrv/security/CertInstallCertInfoPane.java
new file mode 100644
index 000000000..2f43e9f32
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CertInstallCertInfoPane.java
@@ -0,0 +1,391 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.security;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+/**
+ *
+ * Step 3 of the certificate installation under Key & Cert wizard.
+ * This pane display to user the certificate taht is about to be installed.
+ *
+ * @version 1.0 98/07/10
+ * @author shihcm@netscape.com
+ *
+ */
+class CertInstallCertInfoPane extends JPanel implements SuiConstants,
+IKeyCertPage {
+
+
+ JLabel _subjectLabel;
+ JLabel _issuerLabel;
+
+ JLabel certName = new JLabel();
+ MultilineLabel issuer = new MultilineLabel(6, 5);
+ MultilineLabel subject = new MultilineLabel(6, 5);
+
+ MultilineLabel serialNum = new MultilineLabel();
+ MultilineLabel valid = new MultilineLabel();
+ MultilineLabel fingerprint = new MultilineLabel();
+ MultilineLabel addReplaceLabel = new MultilineLabel();
+ JButton addReplaceButton = new JButton();
+
+ String certNameLabel;
+
+ /**
+ * Reference to a copy of WizardObservable that was pass in via pageShow
+ * WizardObservable contain shared information between all the panels
+ * under Key & Cert Wizard.
+ */
+ WizardObservable obs;
+
+ /**
+ * Communication module that does the actually sends the cgi request to install
+ * the certificate.
+ */
+ KeyCertTaskInfo taskInfo;
+
+
+ /**
+ * Properties file, contain all the localized string
+ */
+ ResourceSet resource;
+
+ /**
+ * Get the panel that is going to be displayed
+ * @return a panel to be displayed by the key & cert wizard
+ */
+ public JPanel getPanel() {
+ return this;
+ }
+
+ /**
+ * Checks if this panel can be shown
+ * @return true if this page can be shown
+ */
+ public boolean pageShow(WizardObservable observable) {
+ obs = observable;
+ boolean show =
+ ((Boolean)(observable.get("installCert"))).booleanValue();
+ if (show) {
+
+ StatusPane statusPane = (StatusPane)(obs.get("statusPane"));
+ statusPane.setLastPage(false);
+
+ taskInfo = observable.getTaskInfo();
+
+ Hashtable certInstInfo = (Hashtable)(observable.get("certInstInfo"));
+ certInstInfo.put("tokenName", observable.get("tokenName"));
+
+ if (certInstInfo.get("repbutton") != null) {
+ try {
+ addReplaceLabel.setText(
+ resource.getString("CertInstallCertInfoPane",
+ "replaceCert"));
+ addReplaceButton.setText(
+ resource.getString("CertInstallCertInfoPane",
+ "replace"));
+ } catch (Exception e) {}
+ } else {
+ try {
+ addReplaceLabel.setText(
+ resource.getString("CertInstallCertInfoPane",
+ "addCert"));
+ addReplaceButton.setText(
+ resource.getString("CertInstallCertInfoPane",
+ "add"));
+ } catch (Exception e) {}
+ }
+ CertInfo certInfo = (CertInfo)(observable.get("certInfo"));
+
+ subject.setText(certInfo.getSubject());
+ issuer.setText(certInfo.getIssuer());
+ certName.setText(certNameLabel + certInfo.getCertName());
+ serialNum.setText(certInfo.getSerialNumber());
+ fingerprint.setText(certInfo.getFingerPrint());
+
+ String validFromToLabel = null;
+ try {
+ validFromToLabel =
+ resource.getString("CertInstallCertInfoPane",
+ "validFromTo");
+ } catch (Exception e) {}
+
+ valid.setText( KeyCertUtility.replace(
+ KeyCertUtility.replace(validFromToLabel, "%FROM",
+ certInfo.getValidFrom()), "%TO",
+ certInfo.getValidTo()));
+
+
+
+ }
+ return show;
+ }
+
+ /**
+ * Checks if this panel can be hidden
+ * @return true if this page can be hide
+ */
+ public boolean pageHide(WizardObservable observable) {
+ return true;
+ }
+
+
+ /**
+ *
+ * Inner class to handle add/replace certificate.
+ * If add/replace action occure method within this inner
+ * class will call the cgi to do the work.
+ *
+ */
+ class CertInfoActionListener implements ActionListener {
+ public void actionPerformed(ActionEvent event) {
+ if (event.getActionCommand().equals("add_replace")) {
+ Hashtable certInstInfo = (Hashtable)(obs.get("certInstInfo"));
+ Enumeration keys = certInstInfo.keys();
+ while (keys.hasMoreElements()) {
+ String key = (String)(keys.nextElement());
+ taskInfo.put(key, certInstInfo.get(key));
+ }
+
+ try {
+ taskInfo.put("keyfilepw", obs.get("keyfilepw"));
+ taskInfo.exec(taskInfo.SEC_ICRT);
+ taskInfo.clear();
+ } catch (Exception e) {
+ SuiOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(),
+ e.getMessage());
+ //((IWizardControl)(obs.get("Wizard"))).cancelInvoked();
+ return;
+ }
+
+ Vector messages = taskInfo.getResponse().getMessages();
+ //int nMessages = messages.size();
+
+ StatusPane statusPane = (StatusPane)(obs.get("statusPane"));
+ statusPane.setMessage(messages);
+ statusPane.setShow(true);
+ statusPane.setLastPage(true);
+
+ ((IWizardControl)(obs.get("Wizard"))).setIsLastPage(false);
+ ((IWizardControl)(obs.get("Wizard"))).setCanGoForward(
+ false);
+ ;
+ ((IWizardControl)(obs.get("Wizard"))).nextInvoked();
+ }
+ }
+ }
+
+
+
+
+ /**
+ *
+ * @return a panel contain subject and issuer
+ *
+ * [Panel]
+ * [Subject] [Issuer]
+ * [Panel]
+ *
+ */
+ private JPanel getSubjectIssuerPane() {
+ JPanel subjectIssuerPane = new JPanel();
+ subjectIssuerPane.setLayout(new GridBagLayout());
+
+ addReplaceButton.setActionCommand("add_replace");
+ addReplaceButton.addActionListener(new CertInfoActionListener());
+
+ GridBagUtil.constrain(subjectIssuerPane, _subjectLabel, 0, 0,
+ 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(subjectIssuerPane, _issuerLabel, 2, 0, 1,
+ 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(subjectIssuerPane,
+ Box.createRigidArea(new Dimension(COMPONENT_SPACE, 0))
+ , 1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.NONE, 0, 0, 0, 0);
+
+ JScrollPane subjectScrollPane = new JScrollPane(subject,
+ JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+ JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ subjectScrollPane.setBorder(
+ new CompoundBorder(UITools.createLoweredBorder(),
+ new EmptyBorder(VERT_COMPONENT_INSET,
+ HORIZ_COMPONENT_INSET, VERT_COMPONENT_INSET,
+ HORIZ_COMPONENT_INSET)));
+
+ GridBagUtil.constrain(subjectIssuerPane, subjectScrollPane, 0,
+ 1, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ JScrollPane issuerScrollPane = new JScrollPane(issuer,
+ JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+ JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ issuerScrollPane.setBorder(
+ new CompoundBorder(UITools.createLoweredBorder(),
+ new EmptyBorder(VERT_COMPONENT_INSET,
+ HORIZ_COMPONENT_INSET, VERT_COMPONENT_INSET,
+ HORIZ_COMPONENT_INSET)));
+ GridBagUtil.constrain(subjectIssuerPane, issuerScrollPane, 2,
+ 1, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ return subjectIssuerPane;
+ }
+
+
+ /**
+ *
+ * A panel contain a string telling user whether a add or a replace can
+ * take place for this certificate
+ * [panel]
+ * [string telling use if they can add or replace] [add|replace button]
+ * [panel]
+ *
+ */
+ private JPanel getAddReplacePane() {
+ JPanel addReplacePane = new JPanel();
+ addReplacePane.setLayout(new GridBagLayout());
+
+ GridBagUtil.constrain(addReplacePane, addReplaceLabel, 0, 0, 1,
+ 1, 1.0, 0.0, GridBagConstraints.WEST,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(addReplacePane, addReplaceButton, 1, 0,
+ 1, 1, 1.0, 0.0, GridBagConstraints.EAST,
+ GridBagConstraints.NONE, 0, 0, 0, 0);
+
+ return addReplacePane;
+ }
+
+ /**
+ *
+ * This panel contain certificate informations, serial number, finger print,
+ * validation date. Also make a cal to getSubjectIssuerPanel() to obtain
+ * subject and issuer ui
+ * [panel]
+ * [subject] [issuer]
+ * [serial number[
+ * [finger print]
+ * [validation]
+ * [panel]
+ *
+ */
+ private JPanel getInfoPane() {
+ JPanel infoPane = new JPanel();
+ infoPane.setLayout(new GridBagLayout());
+
+ int y = 0;
+
+ GridBagUtil.constrain(infoPane, certName, 0, y, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, 0);
+
+
+ GridBagUtil.constrain(infoPane, getSubjectIssuerPane(), 0, ++y,
+ 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0,
+ SEPARATED_COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(infoPane,
+ new JLabel( resource.getString("CertInstallCertInfoPane",
+ "serialLabel")), 0, ++y, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, 0, 0);
+
+ GridBagUtil.constrain(infoPane, serialNum, 0, ++y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(infoPane,
+ new JLabel( resource.getString("CertInstallCertInfoPane",
+ "fingerprintLabel")), 0, ++y, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, 0, 0);
+
+ GridBagUtil.constrain(infoPane, fingerprint, 0, ++y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(infoPane, valid, 0, ++y, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, 0);
+
+ return infoPane;
+ }
+
+
+
+ /**
+ *
+ * Constructor, create a certificate information pane and a action button allow
+ * user to add or replace certificate.
+ *
+ */
+ public CertInstallCertInfoPane() {
+ super();
+ setLayout(new GridBagLayout());
+
+ resource = KeyCertUtility.getKeyCertWizardResourceSet();
+
+ certNameLabel = resource.getString("CertInstallCertInfoPane", "certNameLabel");
+
+ _subjectLabel = new JLabel(
+ resource.getString("CertInstallCertInfoPane", "subjectLabel"));
+ _issuerLabel = new JLabel(
+ resource.getString("CertInstallCertInfoPane", "issuerLabel"));
+
+
+ setBorder( new TitledBorder( new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE)),
+ resource.getString("CertInstallCertInfoPane", "title")));
+
+ int y = 0;
+
+ GridBagUtil.constrain(this, getInfoPane(), 0, ++y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(this, Box.createVerticalGlue(), 0, ++y,
+ 1, 1, 1.0, 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(this, getAddReplacePane(), 0, ++y, 1, 1,
+ 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+ }
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ f.getContentPane().add("North", new CertInstallCertInfoPane());
+ f.setSize(400,400);
+ f.show();
+ }*/
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CertInstallCertPane.java b/base/console/src/com/netscape/admin/certsrv/security/CertInstallCertPane.java
new file mode 100644
index 000000000..210cfc9bf
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CertInstallCertPane.java
@@ -0,0 +1,236 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.security;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+class CertInstallCertPane extends JPanel implements SuiConstants,
+IKeyCertPage {
+
+ JRadioButton certInFile;
+ JTextField certFilename = new JTextField(20);
+ JRadioButton certInText;
+ JTextArea certText = new JTextArea(7, 10);
+ JButton paste;
+
+ IWizardControl control = null;
+ boolean modified = false;
+
+ public JPanel getPanel() {
+ return this;
+ }
+
+ public boolean pageShow(WizardObservable observable) {
+
+ if (control == null) {
+ control = (IWizardControl)(observable.get("Wizard"));
+ setEnableNextButton();
+ }
+
+ return ((Boolean)(observable.get("installCert"))).booleanValue();
+ }
+
+ public boolean pageHide(WizardObservable observable) {
+ boolean hide = true;
+
+ if (modified) {
+ observable.put("CertInstModified", new Boolean(true));
+ modified = false;
+ }
+
+ if (((Boolean)(observable.get("CertInstModified"))).booleanValue()) {
+ CertInstallTypePane.param.put("inputtype" ,
+ certInFile.isSelected() ? "0":"1");
+ CertInstallTypePane.param.put("cert_file",
+ certFilename.getText());
+ CertInstallTypePane.param.put("cert_txt" , certText.getText());
+ CertInstallTypePane.param.put("tokenName", observable.get("tokenName"));
+
+ KeyCertTaskInfo taskInfo = observable.getTaskInfo();
+ Enumeration cgiParam = CertInstallTypePane.param.keys();
+ while (cgiParam.hasMoreElements()) {
+ String key = (String)(cgiParam.nextElement());
+ taskInfo.put(key, CertInstallTypePane.param.get(key));
+ }
+
+ Response response = null;
+ try {
+ response = taskInfo.exec(taskInfo.SEC_ICRT);
+ taskInfo.clear();
+ } catch (Exception e) {
+ SuiOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(),
+ e.getMessage());
+ hide = false;
+ }
+
+ if (response.hasCertInstInfo() && response.hasCertInfo()) {
+ observable.put("certInstInfo", response.getCertInstInfo());
+ observable.put("certInfo", response.getCertInfo());
+ observable.put("CertInstModified", new Boolean(false));
+ } else {
+ //hide = false;
+ //MessageDialog.messageDialog((Message)(taskInfo.getResponse().getMessages().elementAt(0)));
+ StatusPane statusPane = (StatusPane)(observable.get("statusPane"));
+
+ statusPane.setMessage( (Message)
+ (taskInfo.getResponse().getMessages().
+ elementAt(0)));
+ statusPane.setShow(true);
+ }
+ }
+
+ return hide;
+ }
+
+
+ class CertPaneActionListener implements ActionListener, KeyListener {
+ public void keyTyped(KeyEvent e) {}
+ public void keyPressed(KeyEvent e) {}
+ public void keyReleased(KeyEvent e) {
+ setEnableNextButton();
+ }
+
+ public void actionPerformed(ActionEvent event) {
+ modified = true;
+
+ if (event.getActionCommand().equals("PASTE")) {
+ certText.paste();
+ }
+
+ setEnableNextButton();
+ }
+ }
+
+ void setEnableNextButton() {
+ if ((certInFile.isSelected() &&
+ (certFilename.getText().length() != 0)) ||
+ (certInText.isSelected() &&
+ (certText.getText().length() != 0))) {
+ control.setCanGoForward(true);
+ } else {
+ control.setCanGoForward(false);
+ }
+
+ if (certInFile.isSelected()) {
+ certText.setEnabled(false);
+ certFilename.setEnabled(true);
+ } else {
+ certText.setEnabled(true);
+ certFilename.setEnabled(false);
+ }
+ }
+
+
+ public CertInstallCertPane() {
+ super();
+ setLayout(new GridBagLayout());
+
+ ResourceSet resource = KeyCertUtility.getKeyCertWizardResourceSet();
+
+ certInFile = new JRadioButton(
+ resource.getString("CertInstallCertPane",
+ "certInFileLabel"), false);
+ certInText = new JRadioButton(
+ resource.getString("CertInstallCertPane",
+ "certInTextLabel"), true);
+ paste = new JButton(resource.getString("CertInstallCertPane", "pasteLabel"));
+
+ ButtonGroup buttonGroup = new ButtonGroup();
+ buttonGroup.add(certInFile);
+ buttonGroup.add(certInText);
+
+ int y = 0;
+
+ CertPaneActionListener listener = new CertPaneActionListener();
+ certFilename.addKeyListener(listener);
+
+ //certText.addActionListener(listener);
+ certText.addKeyListener(listener);
+
+ certInText.addActionListener(listener);
+ certInFile.addActionListener(listener);
+
+ paste.setActionCommand("PASTE");
+ paste.addActionListener(listener);
+
+
+ setBorder( new TitledBorder( new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE)),
+ resource.getString("CertInstallCertPane", "title")));
+
+
+ GridBagUtil.constrain(this, certInFile, 0, ++y, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this, certFilename, 0, ++y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
+ 0, 0, DIFFERENT_COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this, certInText, 0, ++y, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this,
+ new MultilineLabel(
+ resource.getString("CertInstallCertPane",
+ "certTextExplain")), 0, ++y, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, 0);
+
+
+ JScrollPane scrollPane = new JScrollPane(certText,
+ JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+ JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ scrollPane.setBorder(UITools.createLoweredBorder());
+ GridBagUtil.constrain(this, scrollPane, 0, ++y, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, DIFFERENT_COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this, paste, 0, ++y, 1, 1, 0.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.NONE, 0,
+ 0, DIFFERENT_COMPONENT_SPACE, 0);
+
+
+ GridBagUtil.constrain(this, Box.createVerticalGlue(), 0, ++y,
+ 1, 1, 1.0, 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+
+ JLabel _next = new JLabel(resource.getString(null, "clickNextToContinue"));
+ GridBagUtil.constrain(this, _next, 0, ++y, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, 0, 0);
+ }
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ f.getContentPane().add("North", new CertInstallCertPane());
+ f.setSize(400,400);
+ f.show();
+ }*/
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CertInstallTypePane.java b/base/console/src/com/netscape/admin/certsrv/security/CertInstallTypePane.java
new file mode 100644
index 000000000..a55fce2ec
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CertInstallTypePane.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.admin.certsrv.security;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+class CertInstallTypePane extends JPanel implements SuiConstants,
+IKeyCertPage {
+
+ JRadioButton thisServer;
+ JRadioButton certChain;
+ JRadioButton ca;
+
+ JLabel tokenName = new JLabel();
+ SingleBytePasswordField passwd = new SingleBytePasswordField(20);
+ JLabel certName = new JLabel();
+
+ JLabel _certnameLabel;
+ JLabel _tokenLabel;
+ JLabel _certType;
+ JLabel _passwordLabel;
+
+ public static Hashtable param = new Hashtable();
+
+ IWizardControl control;
+ boolean modified = true;
+
+ public JPanel getPanel() {
+ return this;
+ }
+
+ public boolean pageShow(WizardObservable observable) {
+ boolean show =
+ ((Boolean)(observable.get("installCert"))).booleanValue();
+
+ control = (IWizardControl)(observable.get("Wizard"));
+
+ passwd.setText((String)(observable.get("keyPasswd")));
+ if (passwd.getText().length() == 0) {
+ control = (IWizardControl)(observable.get("Wizard"));
+ setEnableNextButton();
+ }
+
+ if (show) {
+ tokenName.setText((String)(observable.get("tokenName")));
+ certName.setText((String)(observable.get("certName")));
+ }
+
+ return show;
+ }
+
+ public boolean pageHide(WizardObservable observable) {
+
+
+ if (modified) {
+ observable.put("keyfilepw", passwd.getText());
+
+ observable.put("CertInstModified", new Boolean(true));
+
+ param.put("certtype" ,
+ thisServer.isSelected() ? "0":
+ (certChain.isSelected() ? "1":"2"));
+ param.put("alias" , observable.get("sie"));
+ param.put("keyfilepw", passwd.getText());
+ observable.put("keyPasswd", passwd.getText());
+
+ if (thisServer.isSelected()) {
+ param.put("certname", (String)(observable.get("certName")));
+ } else {
+ param.remove("certname");
+ }
+
+ modified = false;
+ }
+
+ return true;
+ }
+
+ void setEnableNextButton() {
+ if (passwd.getText().length() == 0) {
+ control.setCanGoForward(false);
+ } else {
+ control.setCanGoForward(true);
+ }
+ }
+
+ class TypeActionListener implements ActionListener, KeyListener {
+ public void keyTyped(KeyEvent e) {}
+ public void keyPressed(KeyEvent e) {}
+ public void keyReleased(KeyEvent e) {
+ modified = true;
+ setEnableNextButton();
+ }
+
+ public void actionPerformed(ActionEvent event) {
+ modified = true;
+
+ if (thisServer.isSelected()) {
+ certName.setVisible(true);
+ _certnameLabel.setVisible(true);
+
+ _passwordLabel.setVisible(true);
+ passwd.setVisible(true);
+
+ setEnableNextButton();
+ } else {
+ certName.setVisible(false);
+ _certnameLabel.setVisible(false);
+
+ _passwordLabel.setVisible(false);
+ passwd.setVisible(false);
+
+ control.setCanGoForward(true);
+ }
+ }
+ }
+
+
+
+ private JPanel getCertTypePane() {
+ JPanel certTypePane = new JPanel();
+ certTypePane.setLayout(new GridBagLayout());
+ int y = 0, x = 0;
+
+ TypeActionListener listener = new TypeActionListener();
+ thisServer.addActionListener(listener);
+ certChain.addActionListener(listener);
+ ca.addActionListener(listener);
+ passwd.addKeyListener(listener);
+
+ GridBagUtil.constrain(certTypePane,
+ Box.createRigidArea(
+ new Dimension(DIFFERENT_COMPONENT_SPACE, 0)), x, y, 1,
+ 1, 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(certTypePane, new JLabel("1. "), ++x,
+ ++y, 1, 1, 0.0, 0.0, GridBagConstraints.WEST,
+ GridBagConstraints.NONE, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(certTypePane, _certType, ++x, y, 1, 1,
+ 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(certTypePane, thisServer, x, ++y, 1, 1,
+ 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(certTypePane, certChain, x, ++y, 1, 1,
+ 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(certTypePane, ca, x, ++y, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, 0, 0);
+
+ return certTypePane;
+ }
+
+
+
+ private JLabel createRightAlignLabel(String label) {
+ return new JLabel(label, JLabel.RIGHT);
+ }
+
+
+ private JPanel getTokenInfoPane() {
+ JPanel tokenInfoPane = new JPanel();
+ tokenInfoPane.setLayout(new GridBagLayout());
+ int y = 0;
+
+
+ GridBagUtil.constrain(tokenInfoPane, _tokenLabel, 0, y, 1, 1,
+ 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(tokenInfoPane, tokenName, 1, y, 1, 1,
+ 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, DIFFERENT_COMPONENT_SPACE,
+ COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(tokenInfoPane, _passwordLabel, 0, ++y, 1,
+ 1, 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(tokenInfoPane, passwd, 1, y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, DIFFERENT_COMPONENT_SPACE,
+ COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(tokenInfoPane, _certnameLabel, 0, ++y, 1,
+ 1, 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(tokenInfoPane, certName, 1, y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE, 0);
+
+ return tokenInfoPane;
+ }
+
+
+ public CertInstallTypePane() {
+ super();
+ setLayout(new GridBagLayout());
+
+ ResourceSet resource = KeyCertUtility.getKeyCertWizardResourceSet();
+ thisServer = new JRadioButton(
+ resource.getString("CertInstallTypePane",
+ "thisServerLabel"), true);
+ certChain = new JRadioButton(
+ resource.getString("CertInstallTypePane",
+ "certChainLabel"), false);
+ ca = new JRadioButton(
+ resource.getString("CertInstallTypePane", "caLabel"),
+ false);
+
+ ButtonGroup buttonGroup = new ButtonGroup();
+ buttonGroup.add(thisServer);
+ buttonGroup.add(certChain);
+ buttonGroup.add(ca);
+
+
+ _certnameLabel =
+ new JLabel(resource.getString("CertInstallTypePane", "certnameLabel"));
+ _tokenLabel = createRightAlignLabel(
+ resource.getString("CertInstallTypePane", "tokenLabel"));
+ _certType =
+ new JLabel(resource.getString("CertInstallTypePane", "certType"));
+ _passwordLabel = createRightAlignLabel(
+ resource.getString("CertInstallTypePane", "passwordLabel"));
+
+ setBorder( new TitledBorder( new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE)),
+ resource.getString("CertInstallTypePane", "title")));
+
+ int y = 0;
+
+ GridBagUtil.constrain(this, getCertTypePane(), 0, ++y, 1, 1,
+ 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0,
+ DIFFERENT_COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this,
+ new JLabel(
+ resource.getString("CertInstallTypePane", "promptPasswd"))
+ , 0, ++y, 1, 1, 0.0, 0.0, GridBagConstraints.WEST,
+ GridBagConstraints.NONE, 0, 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this, getTokenInfoPane(), 0, ++y, 1, 1,
+ 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0,
+ DIFFERENT_COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this, Box.createVerticalGlue(), 0, ++y,
+ 1, 1, 1.0, 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(this,
+ new JLabel(
+ resource.getString(null, "clickNextToContinue")), 0,
+ ++y, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+ }
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ f.getContentPane().add("North", new CertInstallTypePane());
+ f.setSize(400,400);
+ f.show();
+ }*/
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CertListTable.java b/base/console/src/com/netscape/admin/certsrv/security/CertListTable.java
new file mode 100644
index 000000000..62f58d9c2
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CertListTable.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.admin.certsrv.security;
+
+
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+import java.util.*;
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+import javax.swing.table.*;
+import javax.swing.event.*;
+
+//import crysec.SSL.DBManager;
+//import crysec.X509;
+//import crysec.X500Name;
+//import crysec.Utils;
+
+class CertListTable extends JPanel implements MouseListener, Runnable {
+ JTable _table;
+ CertListTableModel _dataModel;
+ KeyCertTaskInfo _taskInfo;
+
+ String alias;
+ String _certName;
+ boolean local = false;
+ boolean setupComplete;
+ Vector certList;
+ // DBManager trustdb;
+
+ //IBackgroundLoaderCallback _callback;
+
+ ConsoleInfo _consoleInfo;
+
+ private String formatLineString(String val, String option,
+ boolean newLine) {
+ if (val != null) {
+ return val + (newLine ? option + "\n":option);
+ } else {
+ return "";
+ }
+ }
+
+ public void showCert() {
+// to get it compile
+/*
+ int row = _table.getSelectedRow();
+ if (row == -1)
+ return;
+
+ //show cert here
+
+ if (local) {
+ X509 cert = (X509)(certList.elementAt(row));
+ X500Name holder = (X500Name)(cert.getHolder());
+ X500Name issuer = (X500Name)(cert.getIssuer());
+
+ StringBuffer subjectString = new StringBuffer();
+ StringBuffer issuerString = new StringBuffer();
+
+ subjectString.append(
+ formatLineString(holder.getName(), "", true));
+ subjectString.append(
+ formatLineString(holder.getEmail(), "", true));
+ subjectString.append(
+ formatLineString(holder.getOrganizationName(), "",
+ true));
+ subjectString.append(
+ formatLineString(holder.getOrgUnitName(), "", true));
+ subjectString.append(
+ formatLineString(holder.getLocalityName(), "", true));
+ subjectString.append(
+ formatLineString(holder.getStateName(), ", ",
+ false) + holder.getCountryName());
+
+ issuerString.append(
+ formatLineString(issuer.getName(), "", true));
+ issuerString.append(
+ formatLineString(issuer.getEmail(), "", true));
+ issuerString.append(
+ formatLineString(issuer.getOrganizationName(), "",
+ true));
+ issuerString.append(
+ formatLineString(issuer.getOrgUnitName(), "", true));
+ issuerString.append(
+ formatLineString(issuer.getLocalityName(), "", true));
+ issuerString.append(
+ formatLineString(issuer.getStateName(), ", ",
+ false) + issuer.getCountryName());
+
+ CertInfo ci = new CertInfo(holder.getName(),
+ issuerString.toString(), subjectString.toString(),
+ "", "", cert.getNotBeforeDate().toString(),
+ cert.getNotAfterDate().toString(),
+ new String(cert.getFingerprint()), "1", "0",
+ holder.getOrganizationName());
+
+ CertInfoDialog infoDialog = new CertInfoDialog(null, ci);
+ infoDialog.show();
+
+ if (CertInfoDialog.delete) {
+ deleteRow(row);
+
+ trustdb.remove(Utils.toHexString(cert.getFingerprint()));
+ trustdb.save();
+ }
+ } else {
+ _taskInfo.clear();
+ _taskInfo.put("certnn", getRow(row).getCertName());
+ _taskInfo.put("alias", alias);
+ Response response = null;
+ try {
+ response = _taskInfo.exec(_taskInfo.SEC_ECRT);
+ } catch (Exception e) {
+ SuiOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(),
+ e.getMessage());
+ return;
+ }
+
+ if (response.hasCertInfo()) {
+ CertInfoDialog infoDialog =
+ new CertInfoDialog(null,
+ response.getCertInfo(), _taskInfo);
+ ModalDialogUtil.setDialogLocation(infoDialog, this);
+ infoDialog.show();
+ //since CertInfoDialog is a modal dialog we will wait until it comes back to check wheather the cer
+ //has been deleted if it is deleted then we need to refresh the table
+ if (CertInfoDialog.delete) {
+ deleteRow(row);
+ }
+ }
+
+ //MessageDialog.messageDialog((Message)(response.getMessages().elementAt(0)));
+ }
+ */
+ }
+
+
+ public void mouseClicked(MouseEvent e) {
+ int row = _table.rowAtPoint(e.getPoint());
+
+ if (e.getClickCount() < 2)
+ return;
+
+ if (row == -1) {
+ _table.clearSelection();
+ } else {
+ showCert();
+ }
+ }
+
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {}
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {}
+
+ public boolean isTableSetup() {
+ return setupComplete;
+ }
+
+
+ public CertListTable() {
+ super(true);
+ local = true;
+
+ setLayout(new BorderLayout());
+
+ setupComplete = true;
+
+ // trustdb = new DBManager();
+ // Enumeration e = trustdb.elements();
+ Enumeration e = null;
+ certList = new Vector();
+ Vector v = new Vector();
+ // while (e.hasMoreElements()) {
+ // X509 cert = (X509)(e.nextElement());
+ // certList.addElement(cert);
+// v.addElement(
+ // new CertBasicInfo(cert.getHolder().getName(), "Trust Server Certificate",
+ // cert.getNotAfterDate().toString()));
+ // }
+
+ _dataModel = new CertListTableModel(
+ CertBasicInfo.getCertTitleLabels(), v);
+ setupTable(_dataModel);
+ }
+
+
+ public CertListTable(String certName, ConsoleInfo consoleInfo/*, IBackgroundLoaderCallback callback*/) {
+ super(true);
+ _consoleInfo = consoleInfo;
+ _certName = certName;
+ //_callback = callback;
+ setLayout(new BorderLayout());
+
+ setupComplete = true;
+
+ run();
+
+ /*setBackground( Color.white );*/
+ }
+
+
+
+ private void setupTable(CertListTableModel _tableModel) {
+ // Create the table
+ _table = new SuiTable(_tableModel);
+ _table.addMouseListener(this);
+ _table.setColumnSelectionAllowed(false);
+ /*_table.setMultipleSelectionAllowed(false);*/
+
+ // Put the table and header into a scrollPane
+ JScrollPane scrollpane = new JScrollPane();
+ JTableHeader tableHeader = _table.getTableHeader();
+
+ // create and add the column heading to the scrollpane's
+ // column header viewport
+ JViewport headerViewport = new JViewport();
+ headerViewport.setLayout(
+ new BoxLayout(headerViewport, BoxLayout.X_AXIS));
+ headerViewport.add(tableHeader);
+ scrollpane.setColumnHeader(headerViewport);
+
+ // add the table to the viewport
+ JViewport mainViewPort = scrollpane.getViewport();
+ mainViewPort.add(_table);
+
+ // speed up resizing repaints by turning off live cell updates
+ tableHeader.setUpdateTableInRealTime(false);
+
+ add("Center", scrollpane);
+
+ setPreferredSize(new Dimension(0, 0));
+ //_callback.classLoaded(this, "CertListTable");
+ }
+
+ //public void setCertList(String certName) {
+ public void run() {
+
+ _taskInfo = new KeyCertTaskInfo(_consoleInfo);
+ _dataModel = new CertListTableModel(
+ CertBasicInfo.getCertTitleLabels(), new Vector());
+ //setCertList(certName);
+
+ //_dataModel.deleteAllRows();
+ //call cgi here to get the cert information
+ _taskInfo.put("alias", _certName);
+ alias = _certName;
+ Response response = null;
+ try {
+ response = _taskInfo.exec(_taskInfo.SEC_MGCRT);
+ } catch (Exception e) {
+ SuiOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(), e.getMessage());
+ setupComplete = false;
+ return;
+ }
+
+ if (response.hasCertList()) {
+ _dataModel.setRowData(response.getCertList());
+ //repaint();
+ }
+
+ setupTable(_dataModel);
+ }
+
+ /**
+ *
+ * @return LDAPEntry at specified index, null if index > number of rows
+ *
+ */
+ public CertBasicInfo getRow(int index) {
+ return _dataModel.getRow(index);
+ }
+
+ /**
+ *
+ * @return the number of rows in the table.
+ *
+ */
+ public int getRowCount() {
+ return _dataModel.getRowCount();
+ }
+
+ /**
+ *
+ * Removes the first occurrence of the LDAPEntry from this table. If the object is found.
+ *
+ * @param ldapEntry LDAPEntry to delete from this table.
+ *
+ */
+ public void deleteRow(int rowIndex) {
+ _dataModel.deleteRow(rowIndex);
+ repaint();
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CertListTableModel.java b/base/console/src/com/netscape/admin/certsrv/security/CertListTableModel.java
new file mode 100644
index 000000000..fb9423093
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CertListTableModel.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.admin.certsrv.security;
+
+import java.util.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+import javax.swing.table.*;
+import javax.swing.event.*;
+
+
+class CertListTableModel extends AbstractTableModel {
+
+ Vector _header;
+
+ Vector _rowData = new Vector();
+
+ Vector _tableModelListener = new Vector();
+
+ public CertListTableModel(Vector columnIdentifier, Vector certList) {
+ _header = columnIdentifier;
+ _rowData = certList;
+ }
+
+ public void setRowData(Vector rowData) {
+ _rowData = rowData;
+ }
+
+ public int getRowCount() {
+ return _rowData.size();
+ }
+
+ public int getColumnCount() {
+ return _header.size();
+ }
+
+ public String getColumnName(int columnIndex) {
+ return (columnIndex >= _header.size() ? "":
+ (String)(_header.elementAt(columnIndex)));
+ }
+
+ public Object getValueAt(int rowIndex, int columnIndex) {
+ Object o = null;
+
+ try {
+ o = ((CertBasicInfo)(_rowData.elementAt(rowIndex))).
+ getCertInfo((String)(_header.elementAt(columnIndex)));
+ } catch (Exception e) {}
+
+ return o;
+ }
+
+ public void deleteRow(int rowIndex) {
+ try {
+ _rowData.removeElementAt(rowIndex);
+ } catch (Exception e) {}
+ }
+
+ public void deleteAllRows() {
+ _rowData.removeAllElements();
+ }
+
+ public CertBasicInfo getRow(int index) {
+ return index < _rowData.size() ?
+ (CertBasicInfo)(_rowData.elementAt(index)) : null;
+ }
+
+ public void addTableModelListener(TableModelListener l) {
+ _tableModelListener.addElement(l);
+ }
+
+ public void removeTableModelListener(TableModelListener l) {
+ _tableModelListener.removeElement(l);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CertManagementDialog.java b/base/console/src/com/netscape/admin/certsrv/security/CertManagementDialog.java
new file mode 100644
index 000000000..f780314cd
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CertManagementDialog.java
@@ -0,0 +1,220 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.security;
+
+import com.netscape.management.client.console.ConsoleInfo;
+import com.netscape.management.client.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.table.*;
+import javax.swing.event.*;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+
+import com.netscape.management.nmclf.*;
+
+/**
+ *
+ * Certificate management dialog.
+ * This is a self contain dialog, that allow use to
+ * view, delete, and change the trut status of a certificate.
+ * This is only the front end, the actuall work
+ * of looking up, delete, and modified certificate are handled
+ * at the server side.
+ *
+ * @version 1.0 98/07/10
+ * @author <A HREF="mailto:shihcm@netscape.com">shihcm@netscape.com</A>
+ *
+ */
+public class CertManagementDialog extends AbstractDialog {
+
+ CertListTable certListTable;
+ KeyCertTaskInfo taskInfo;
+ ConsoleInfo _consoleInfo;
+
+ JButton bClose;
+ JButton bEdit;
+ JButton bHelp;
+
+ ResourceSet resource = new ResourceSet("com.netscape.admin.certsrv.security.CertManagementResource");
+
+ //since can't over load protected and I don't
+ //want the interface to show so...
+ private void privateHelpInvoked() {
+ Help help = new Help(resource);
+ help.help("CertManagementDialog", "help");
+ }
+
+
+ //since can't over load protected and I don't
+ //want the interface to show so...
+ private void privateCloseInvoked() {
+ super.okInvoked();
+ }
+
+ class CertManagementActionListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ if (e.getActionCommand().equals("CLOSE")) {
+ privateCloseInvoked();
+ } else if (e.getActionCommand().equals("HELP")) {
+ privateHelpInvoked();
+ } else if (e.getActionCommand().equals("EDIT")) {
+ certListTable.showCert();
+ }
+ }
+ }
+
+
+ private JPanel getCertListPane() {
+ JPanel certListPane = new JPanel();
+ certListPane.setLayout(new GridBagLayout());
+ certListPane.setBorder( new TitledBorder(
+ new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE)),
+ resource.getString("CertManagementDialog", "certificate")));
+
+
+ GridBagUtil.constrain(certListPane,
+ new JLabel(
+ resource.getString("CertManagementDialog", "certDB")),
+ 0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.NONE, 0, 0, COMPONENT_SPACE, 0);
+
+
+ GridBagUtil.constrain(certListPane,
+ new JLabel( resource.getString("CertManagementDialog",
+ "defaultToken"), JLabel.RIGHT), 1, 0, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(certListPane, certListTable, 0, 1, 2, 1,
+ 1.0, 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+
+ return certListPane;
+ }
+
+
+ private JPanel getControlButtons() {
+ JPanel controlPanel = new JPanel();
+ controlPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 0, 0));
+ controlPanel.setBorder(
+ new EmptyBorder(SuiConstants.VERT_WINDOW_INSET, 0, 0, 0));
+
+ CertManagementActionListener listener =
+ new CertManagementActionListener();
+
+ bClose = JButtonFactory.createCloseButton(listener);
+ controlPanel.add(bClose);
+
+ controlPanel.add( Box.createRigidArea(
+ new Dimension(SuiConstants.COMPONENT_SPACE, 0)));
+
+ bEdit = JButtonFactory.create(
+ resource.getString("CertManagementDialog", "edit"));
+ bEdit.addActionListener(listener);
+ bEdit.setActionCommand("EDIT");
+ controlPanel.add(bEdit);
+
+ controlPanel.add( Box.createRigidArea(
+ new Dimension(SuiConstants.SEPARATED_COMPONENT_SPACE, 0)));
+
+ bHelp = JButtonFactory.createHelpButton(listener);
+ controlPanel.add(bHelp);
+
+ JButtonFactory.resizeGroup(bHelp, bClose, bEdit);
+
+ return controlPanel;
+ }
+
+
+
+ /**
+ * Create an certificate management dialog to
+ * manage remote certificate database
+ *
+ * @param consoleInfo Console information
+ *
+ */
+ public CertManagementDialog(ConsoleInfo consoleInfo) {
+ super(null, "", true, NO_BUTTONS);
+
+ UtilConsoleGlobals.getActivatedFrame().setCursor(
+ new Cursor(Cursor.WAIT_CURSOR));
+
+ _consoleInfo = consoleInfo;
+
+ setTitle(resource.getString("CertManagementDialog", "title"));
+
+ JPanel mainPane = new JPanel();
+ mainPane.setLayout(new BorderLayout());
+
+ certListTable = new CertListTable(
+ KeyCertUtility.createTokenName(_consoleInfo), consoleInfo);
+ mainPane.add("Center", getCertListPane());
+ mainPane.add("South", getControlButtons());
+
+ getContentPane().add(mainPane);
+
+ //pack();
+ setMinimumSize(400, 400);
+ //setResizable(false);
+
+ UtilConsoleGlobals.getActivatedFrame().setCursor(
+ new Cursor(Cursor.DEFAULT_CURSOR));
+
+ if (!(certListTable.isTableSetup())) {
+ return;
+ }
+
+ show();
+ }
+
+ /**
+ * Create an certificate management dialog to
+ * manage local trust database.
+ *
+ *
+ */
+ public CertManagementDialog() {
+ super(null, "", true, NO_BUTTONS);
+
+ setTitle(resource.getString("CertManagementDialog", "title"));
+
+ JPanel mainPane = new JPanel();
+ mainPane.setLayout(new BorderLayout());
+
+ certListTable = new CertListTable();
+ mainPane.add("Center", getCertListPane());
+ mainPane.add("South", getControlButtons());
+
+ getContentPane().add(mainPane);
+
+ setSize(400, 400);
+
+ if (!(certListTable.isTableSetup())) {
+ return;
+ }
+
+ show();
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CertRequestCertPane.java b/base/console/src/com/netscape/admin/certsrv/security/CertRequestCertPane.java
new file mode 100644
index 000000000..46ae3852f
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CertRequestCertPane.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.admin.certsrv.security;
+
+import java.awt.*;
+import java.util.*;
+import java.net.*;
+import java.io.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.text.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+import com.netscape.management.client.comm.HttpChannel;
+
+class CertRequestCertPane extends JPanel implements SuiConstants,
+IKeyCertPage {
+
+ JTextArea certReq = new JTextArea(7, 10);
+ JScrollPane scrollPane = new JScrollPane(certReq,
+ JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+ JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ String explainEMail, explainURL;
+ JButton copy;
+ String oldUrl = "";
+
+
+
+ public JPanel getPanel() {
+ return this;
+ }
+
+
+
+ class CertPaneActionListener implements ActionListener {
+ public void actionPerformed(ActionEvent event) {
+ if (event.getActionCommand().equals("COPY")) {
+ certReq.selectAll();
+ certReq.copy();
+ certReq.setSelectionEnd(certReq.getSelectionEnd());
+ }
+ }
+ }
+
+ public boolean pageHide(WizardObservable observable) {
+ return true;
+ }
+
+ public boolean pageShow(WizardObservable observable) {
+ boolean show =
+ ((Boolean)(observable.get("requestCert"))).booleanValue();
+
+
+ Hashtable param = (Hashtable)(observable.get("CertReqCGIParam"));
+ if (show && param.get("xmt_select").equals("1")) {
+
+ Hashtable urlParam = new Hashtable();
+ urlParam.put("op" , "submitCSR");
+ urlParam.put("csrCertType" , "server");
+ urlParam.put("csrRequestorName" , param.get("requestor_name"));
+ urlParam.put("csrRequestorEmail" , param.get("email_address"));
+ urlParam.put("csrRequestorPhone" , param.get("telephone"));
+ urlParam.put("csrRequestorComments", "");
+ urlParam.put("pkcs10Request" , observable.get("CertReq"));
+
+ if (((Boolean)(observable.get("newCertReq"))).booleanValue()
+ && !(oldUrl.equals(param.get("url")))) {
+ try {
+ //attempt to contect cms
+ oldUrl = (String)(param.get("url"));
+ Comm cmsUrl = new Comm(oldUrl, /*null*/urlParam, true);
+ cmsUrl.run();
+ /*System.out.println(cmsUrl.getData());*/
+ //explain.setVisible(false);
+ explain.setText(explainURL);
+ if (cmsUrl.getError() != null) {
+ //cms didn't respond
+ certReq.setText(
+ resource.getString("CertRequestCertPane",
+ "cmsNotResponding"));
+ Debug.println("CertRequestCertPane:"+
+ cmsUrl.getError());
+ } else if ((cmsUrl.getData() != null) &&
+ (cmsUrl.getData().trim().length() != 0)) {
+ //cms return a message
+
+ JEditorPane editor = new JEditorPane();
+ editor.setBorder(new EmptyBorder(0, 0, 0, 0));
+ editor.setEditable(false);
+ //editor.setOpaque(false);
+
+ //display cms's message
+ Debug.println(cmsUrl.getData());
+ StringReader reader =
+ new StringReader(cmsUrl.getData());
+ editor.setEditorKit(
+ editor.createEditorKitForContentType("text/html"));
+ Document dstDoc = editor.getDocument();
+ editor.getEditorKit().read(reader, dstDoc, 0);
+
+ certReq.setText(editor.getText());
+ }
+
+ observable.put("newCertReq", new Boolean(false));
+ } catch (Exception e) {
+ certReq.setText(
+ resource.getString("CertRequestCertPane", "unableToParse"));
+ Debug.println("CertRequestCertPane:"+e);
+
+ }
+ }
+
+ } else if (show) {
+ //if request via e-mail
+ explain.setText(explainEMail);
+ certReq.setText((String)(observable.get("CertReq")));
+ explain.setVisible(true);
+ }
+
+ scrollPane.validate();
+
+ return show;
+ }
+
+ MultilineLabel explain;
+ ResourceSet resource = KeyCertUtility.getKeyCertWizardResourceSet();
+ public CertRequestCertPane() {
+ super();
+ setLayout(new GridBagLayout());
+
+
+ copy = JButtonFactory.create(
+ resource.getString("CertRequestCertPane", "copyLabel"));
+
+ setBorder( new TitledBorder( new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE)),
+ resource.getString("CertRequestCertPane", "title")));
+
+ int y = 0;
+
+ explainEMail = resource.getString("CertRequestCertPane", "explain");
+ explainURL = resource.getString("CertRequestCertPane", "explain2");
+
+
+ explain = new MultilineLabel(explainEMail);
+ GridBagUtil.constrain(this, explain, 0, ++y, 1, 1, 1.0, 1.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, DIFFERENT_COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this, scrollPane, 0, ++y, 1, 1, 0.0, 0.0,
+ GridBagConstraints.NORTH,
+ GridBagConstraints.HORIZONTAL, 0, 0,
+ DIFFERENT_COMPONENT_SPACE, 0);
+
+
+ copy.setActionCommand("COPY");
+ copy.addActionListener(new CertPaneActionListener());
+ GridBagUtil.constrain(this, copy, 0, ++y, 1, 1, 0.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.NONE, 0,
+ 0, DIFFERENT_COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this, Box.createVerticalGlue(), 0, ++y,
+ 1, 1, 1.0, 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(this,
+ new JLabel(
+ resource.getString(null, "clickNextToContinue")), 0,
+ ++y, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+ }
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ f.getContentPane().add("North", new CertRequestCertPane());
+ f.setSize(400,400);
+ f.show();
+ }*/
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CertRequestEnterPasswordPane.java b/base/console/src/com/netscape/admin/certsrv/security/CertRequestEnterPasswordPane.java
new file mode 100644
index 000000000..d051ee167
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CertRequestEnterPasswordPane.java
@@ -0,0 +1,217 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.security;
+
+import java.awt.*;
+import java.util.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+class CertRequestEnterPasswordPane extends JPanel implements SuiConstants,
+IKeyCertPage {
+
+
+ JLabel _passwdLabel;
+ JLabel _tokenLabel;
+
+ JLabel _selectedToken = new JLabel();
+ SingleBytePasswordField _passwd = new SingleBytePasswordField(20);
+
+ IWizardControl control;
+ boolean modified = false;
+
+ public JPanel getPanel() {
+ return this;
+ }
+
+ public boolean pageShow(WizardObservable observable) {
+ boolean show =
+ ((Boolean)(observable.get("requestCert"))).booleanValue();
+ if (show) {
+ _passwd.setText((String)(observable.get("keyPasswd")));
+ control = (IWizardControl)(observable.get("Wizard"));
+ if (_passwd.getText().length() == 0) {
+ control.setCanGoForward(false);
+ }
+
+ boolean isInternal = ((Boolean)(observable.get("isInternal"))).
+ booleanValue();
+
+ _selectedToken.setText((String)(observable.get("tokenName")));
+ }
+
+ return show;
+ }
+
+ public boolean pageHide(WizardObservable observable) {
+ boolean hide = true;
+ KeyCertTaskInfo taskInfo = observable.getTaskInfo();
+
+ if (modified || ((Boolean)(observable.get("CertReqModified"))).
+ booleanValue()) {
+ observable.put("CertReqModified", new Boolean(true));
+ Hashtable param = (Hashtable)(observable.get("CertReqCGIParam"));
+ //param.put("alias" , ((Boolean)(observable.get("isInternal"))).booleanValue()?observable.get("sie"):observable.get("tokenName"));
+ param.put("alias" , observable.get("sie"));
+
+ param.put("keyfilepw" , _passwd.getText());
+ observable.put("keyPasswd", _passwd.getText());
+
+
+ Enumeration cgiParam = param.keys();
+ while (cgiParam.hasMoreElements()) {
+ String key = (String)(cgiParam.nextElement());
+ taskInfo.put(key, param.get(key));
+ }
+
+ Response response = null;
+
+ try {
+ response = taskInfo.exec(taskInfo.SEC_GCRT);
+ taskInfo.clear();
+ } catch (Exception e) {
+ SuiOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(),
+ e.getMessage());
+ hide = false;
+ }
+
+ if (!(response.hasCert())) {
+ //MessageDialog.messageDialog((Message)(taskInfo.getResponse().getMessages().elementAt(0)));
+ StatusPane statusPane = (StatusPane)(observable.get("statusPane"));
+ statusPane.setMessage( (Message)
+ (taskInfo.getResponse().getMessages().
+ elementAt(0)));
+ statusPane.setShow(true);
+ modified = true;
+ } else {
+ observable.put("CertReq",
+ ((Message)(response.getMessages().elementAt(0))
+ ).getExtraMessage());
+ observable.put("CertReqModified", new Boolean(false));
+ modified = false;
+
+ //Need this inorder to know if a new request has been issued, so
+ //request via url can execute again
+ observable.put("newCertReq", new Boolean(true));
+ }
+
+
+ }
+ return hide;
+ }
+
+ class KeyActionListener implements KeyListener {
+ public void keyTyped(KeyEvent e) {}
+ public void keyPressed(KeyEvent e) {}
+ public void keyReleased(KeyEvent e) {
+ if (_passwd.getText().length() > 0) {
+ control.setCanGoForward(true);
+ } else {
+ control.setCanGoForward(false);
+ }
+ modified = true;
+ }
+ }
+
+ private JPanel getPasswdPane() {
+ JPanel passwdPane = new JPanel();
+ passwdPane.setLayout(new GridBagLayout());
+ int y = 0;
+
+
+ GridBagUtil.constrain(passwdPane, _tokenLabel, 0, ++y, 1, 1,
+ 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(passwdPane, _selectedToken, 1, y, 1, 1,
+ 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, DIFFERENT_COMPONENT_SPACE,
+ COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(passwdPane, _passwdLabel, 0, ++y, 1, 1,
+ 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, COMPONENT_SPACE, 0);
+
+ _passwd.addKeyListener(new KeyActionListener());
+ GridBagUtil.constrain(passwdPane, _passwd, 1, y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, DIFFERENT_COMPONENT_SPACE,
+ COMPONENT_SPACE, 0);
+
+
+ return passwdPane;
+ }
+
+ public CertRequestEnterPasswordPane() {
+ super();
+ setLayout(new GridBagLayout());
+
+ ResourceSet resource = KeyCertUtility.getKeyCertWizardResourceSet();
+
+ _passwdLabel = new JLabel(
+ resource.getString("CertRequestEnterPasswordPane",
+ "passwdLabel"), JLabel.RIGHT);
+ _tokenLabel = new JLabel(
+ resource.getString("CertRequestEnterPasswordPane",
+ "tokenLabel"), JLabel.RIGHT);
+
+
+ setBorder( new TitledBorder( new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE)),
+ resource.getString("CertRequestEnterPasswordPane", "title")));
+
+ int y = 0;
+
+
+ GridBagUtil.constrain(this,
+ new MultilineLabel(
+ resource.getString("CertRequestEnterPasswordPane",
+ "explain")), 0, ++y, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, DIFFERENT_COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this, getPasswdPane(), 0, ++y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0,
+ DIFFERENT_COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this, Box.createVerticalGlue(), 0, ++y,
+ 1, 1, 1.0, 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(this,
+ new JLabel(
+ resource.getString(null, "clickNextToContinue")), 0,
+ ++y, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+ }
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ f.getContentPane().setLayout(new BorderLayout());
+ f.getContentPane().add("Center", new CertRequestEnterPasswordPane());
+ f.setSize(400,400);
+ f.show();
+ }*/
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CertRequestInfoPane.java b/base/console/src/com/netscape/admin/certsrv/security/CertRequestInfoPane.java
new file mode 100644
index 000000000..0bc25ea1a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CertRequestInfoPane.java
@@ -0,0 +1,403 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.security;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+class CertRequestInfoPane extends JPanel implements SuiConstants,
+IKeyCertPage {
+
+ boolean modified = false;
+
+ JTextField name = new JTextField();
+ JTextField phone = new JTextField();
+ SingleByteTextField dn = new SingleByteTextField();
+ SingleByteTextField email = new SingleByteTextField();
+ JTextField o = new JTextField();
+ JTextField ou = new JTextField();
+ JTextField l = new JTextField();
+ JComboBox st;
+ JComboBox c;
+
+
+ JLabel _nameLabel;
+ JLabel _phoneLabel;
+ JLabel _dnLabel;
+ JLabel _emailLabel;
+ JLabel _oLabel;
+ JLabel _ouLabel;
+ JLabel _lLabel;
+ JLabel _stLabel;
+ JLabel _cLabel;
+ JLabel _requiredLabel;
+
+ JLabel _dnExample;
+
+ IWizardControl control;
+
+ ResourceSet resource;
+
+ JPanel statePanel = new JPanel();
+
+ public JPanel getPanel() {
+ return this;
+ }
+
+ public boolean pageShow(WizardObservable observable) {
+ boolean show =
+ ((Boolean)(observable.get("requestCert"))).booleanValue();
+
+ if (show) {
+ control = (IWizardControl)(observable.get("Wizard"));
+ setEnableNextButton();
+ }
+ return show;
+ }
+
+ public boolean pageHide(WizardObservable observable) {
+
+ KeyCertTaskInfo taskInfo = observable.getTaskInfo();
+
+ if (modified) {
+ observable.put("CertReqModified", new Boolean(true));
+
+ Hashtable param = (Hashtable)(observable.get("CertReqCGIParam"));
+ param.put("requestor_name", name.getText());
+ param.put("telephone" , phone.getText());
+ param.put("common_name" , dn.getText());
+ param.put("email_address" , email.getText());
+ param.put("organization" , o.getText());
+ param.put("org_unit" , ou.getText());
+ param.put("locality" , l.getText());
+ param.put("state" ,
+ st.getSelectedItem() == null ? "":
+ st.getSelectedItem());
+ param.put("country" ,
+ ((String)(c.getSelectedItem())).substring(0, 2));
+ param.put("tokenName" , observable.get("tokenName"));
+ }
+
+ return true;
+ }
+
+ void setEnableNextButton() {
+ if ((name.getText().length() == 0) ||
+ (dn.getText().length() == 0) ||
+ (phone.getText().length() == 0) ||
+ (email.getText().length() == 0) ||
+ (o.getText().length() == 0) ||
+ (((String)(c.getSelectedItem())).length() < 2) ||
+ (dn.getText().indexOf(".") == -1)) {
+ control.setCanGoForward(false);
+ } else {
+ control.setCanGoForward(true);
+ }
+ }
+
+ class InfoPaneActionListener implements ActionListener, KeyListener, FocusListener{
+ public void actionPerformed(ActionEvent e) {
+ modified = true;
+ setEnableNextButton();
+
+ if (e.getSource() == c) {
+ setupState(c.getSelectedItem().toString());
+ }
+ }
+ public void keyTyped(KeyEvent e) {}
+ public void keyPressed(KeyEvent e) {}
+ public void keyReleased(KeyEvent e) {
+ modified = true;
+ setEnableNextButton();
+
+ if (e.getSource() == c) {
+ setupState(c.getSelectedItem().toString());
+ }
+ }
+
+ public void focusGained(FocusEvent e) {}
+ public void focusLost(FocusEvent e) {
+ if (!(e.isTemporary()) && (e.getComponent() == dn) &&
+ (dn.getText().indexOf(".") == -1)) {
+ JOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(),
+ resource.getString("CertRequestInfoPane", "invalidFQDN"),
+ resource.getString("CertRequestInfoPane",
+ "invalidFQDNDialogTitle"),
+ JOptionPane.ERROR_MESSAGE);
+ control.setCanGoForward(false);
+ }
+ }
+ }
+
+ private JLabel rightAlignLabel(String label) {
+ return new JLabel(label, JLabel.RIGHT);
+ }
+
+ private JPanel getInfoPane() {
+ JPanel infoPane = new JPanel();
+ infoPane.setLayout(new GridBagLayout());
+
+ InfoPaneActionListener listener = new InfoPaneActionListener();
+ name.addActionListener(listener);
+ phone.addActionListener(listener);
+ dn.addActionListener(listener);
+ email.addActionListener(listener);
+ o.addActionListener(listener);
+ ou.addActionListener(listener);
+ l.addActionListener(listener);
+ st.addActionListener(listener);
+ c.addActionListener(listener);
+
+ name.addKeyListener(listener);
+ phone.addKeyListener(listener);
+ dn.addKeyListener(listener);
+ email.addKeyListener(listener);
+ o.addKeyListener(listener);
+ ou.addKeyListener(listener);
+ l.addKeyListener(listener);
+ st.addKeyListener(listener);
+ c.addKeyListener(listener);
+
+ dn.addFocusListener(listener);
+
+ st.setEditable(true);
+ c.setEditable(true);
+
+
+
+ int y = 0;
+
+ GridBagUtil.constrain(infoPane, _nameLabel, 0, y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.BOTH,
+ 0, 0, COMPONENT_SPACE, DIFFERENT_COMPONENT_SPACE);
+
+ GridBagUtil.constrain(infoPane, name, 1, y, 1, 1, 0.0, 0.0,
+ GridBagConstraints.EAST, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(infoPane, _phoneLabel, 0, ++y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.BOTH,
+ 0, 0, COMPONENT_SPACE, DIFFERENT_COMPONENT_SPACE);
+
+ GridBagUtil.constrain(infoPane, phone, 1, y, 1, 1, 0.0, 0.0,
+ GridBagConstraints.EAST, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(infoPane, _dnLabel, 0, ++y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.BOTH,
+ 0, 0, 0, DIFFERENT_COMPONENT_SPACE);
+
+ GridBagUtil.constrain(infoPane, dn, 1, y, 1, 1, 0.0, 0.0,
+ GridBagConstraints.EAST, GridBagConstraints.BOTH, 0,
+ 0, 0, 0);
+
+ GridBagUtil.constrain(infoPane, _dnExample, 0, ++y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.EAST, GridBagConstraints.BOTH,
+ 0, 0, COMPONENT_SPACE, DIFFERENT_COMPONENT_SPACE);
+
+ GridBagUtil.constrain(infoPane, _emailLabel, 0, ++y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.BOTH,
+ 0, 0, COMPONENT_SPACE, DIFFERENT_COMPONENT_SPACE);
+
+ GridBagUtil.constrain(infoPane, email, 1, y, 1, 1, 0.0, 0.0,
+ GridBagConstraints.EAST, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(infoPane, _oLabel, 0, ++y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.BOTH,
+ 0, 0, COMPONENT_SPACE, DIFFERENT_COMPONENT_SPACE);
+
+ GridBagUtil.constrain(infoPane, o, 1, y, 1, 1, 0.0, 0.0,
+ GridBagConstraints.EAST, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(infoPane, _ouLabel, 0, ++y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.BOTH,
+ 0, 0, COMPONENT_SPACE, DIFFERENT_COMPONENT_SPACE);
+
+ GridBagUtil.constrain(infoPane, ou, 1, y, 1, 1, 0.0, 0.0,
+ GridBagConstraints.EAST, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(infoPane, _lLabel, 0, ++y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.BOTH,
+ 0, 0, COMPONENT_SPACE, DIFFERENT_COMPONENT_SPACE);
+
+ GridBagUtil.constrain(infoPane, l, 1, y, 1, 1, 0.0, 0.0,
+ GridBagConstraints.EAST, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(infoPane, _stLabel, 0, ++y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.BOTH,
+ 0, 0, COMPONENT_SPACE, DIFFERENT_COMPONENT_SPACE);
+
+
+ GridBagUtil.constrain(infoPane, statePanel/*st*/, 1, y, 1, 1,
+ 0.0, 0.0, GridBagConstraints.EAST,
+ GridBagConstraints.BOTH, 0, 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(infoPane, _cLabel, 0, ++y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.BOTH,
+ 0, 0, COMPONENT_SPACE, DIFFERENT_COMPONENT_SPACE);
+
+ GridBagUtil.constrain(infoPane, c, 1, y, 1, 1, 0.0, 0.0,
+ GridBagConstraints.EAST, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(infoPane, _requiredLabel, 1, ++y, 1, 1,
+ 1.0, 0.0, GridBagConstraints.WEST,
+ GridBagConstraints.BOTH, 0, 0, COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE);
+
+
+ return infoPane;
+ }
+
+ private void setupState(String country) {
+ String stList;
+ statePanel.remove(st);
+ try {
+ stList = resource.getString("CertRequestInfoPane",
+ "state-"+country.substring(0, 2).toUpperCase());
+ if (stList != null && !(stList.equals(""))) {
+
+ StringTokenizer stateTokens =
+ new StringTokenizer(stList, ",", false);
+ Vector states = new Vector();
+ while (stateTokens.hasMoreTokens()) {
+ states.addElement(stateTokens.nextToken());
+ }
+ //this will make it load faster.
+ //It will do some extra work if we call addItem() one at a time
+
+ st = new JComboBox(states);
+ }
+ else {
+ st.removeAllItems();
+ }
+ }
+ catch (Exception e) {
+ st.removeAllItems();
+ }
+
+ GridBagUtil.constrain(statePanel, st, 0, 0, 1, 1, 1.0, 1.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, 0, 0);
+
+ statePanel.validate();
+ statePanel.repaint();
+
+ try {
+ st.setSelectedItem( resource.getString("CertRequestInfoPane",
+ "defaultState-"+
+ country.substring(0, 1).toUpperCase()));
+ } catch (Exception e) {}
+
+ }
+
+ public CertRequestInfoPane() {
+ super();
+ setLayout(new GridBagLayout());
+ statePanel.setLayout(new GridBagLayout());
+
+ resource = KeyCertUtility.getKeyCertWizardResourceSet();
+
+ _nameLabel = rightAlignLabel(
+ resource.getString("CertRequestInfoPane", "nameLabel"));
+ _phoneLabel = rightAlignLabel(
+ resource.getString("CertRequestInfoPane", "phoneLabel"));
+ _dnLabel = rightAlignLabel(
+ resource.getString("CertRequestInfoPane", "dnLabel"));
+ _emailLabel = rightAlignLabel(
+ resource.getString("CertRequestInfoPane", "emailLabel"));
+ _oLabel = rightAlignLabel(
+ resource.getString("CertRequestInfoPane", "oLabel"));
+ _ouLabel = rightAlignLabel(
+ resource.getString("CertRequestInfoPane", "ouLabel"));
+ _lLabel = rightAlignLabel(
+ resource.getString("CertRequestInfoPane", "lLabel"));
+ _stLabel = rightAlignLabel(
+ resource.getString("CertRequestInfoPane", "stLabel"));
+ _cLabel = rightAlignLabel(
+ resource.getString("CertRequestInfoPane", "cLabel"));
+
+
+ _dnExample = rightAlignLabel(
+ resource.getString("CertRequestInfoPane", "dnExample"));
+
+ _requiredLabel =
+ new JLabel(resource.getString("CertRequestInfoPane", "requiredLabel"));
+
+
+ String cList = resource.getString("CertRequestInfoPane", "country");
+ StringTokenizer countryTokens =
+ new StringTokenizer(cList, ",", false);
+ Vector countries = new Vector();
+ while (countryTokens.hasMoreTokens()) {
+ countries.addElement(countryTokens.nextToken());
+ }
+
+ st = new JComboBox();
+ c = new JComboBox(countries);
+
+ try {
+ c.setSelectedItem(
+ resource.getString("CertRequestInfoPane", "defaultCountry"));
+ } catch (Exception e) {}
+
+ setupState(c.getSelectedItem().toString());
+
+
+ setBorder( new TitledBorder( new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE)),
+ resource.getString("CertRequestInfoPane", "title")));
+
+ int y = 0;
+
+ GridBagUtil.constrain(this, getInfoPane(), 0, ++y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this, Box.createVerticalGlue(), 0, ++y,
+ 1, 1, 1.0, 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(this,
+ new JLabel(
+ resource.getString(null, "clickNextToContinue")), 0,
+ ++y, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+ }
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ f.getContentPane().add("North", new CertRequestInfoPane());
+ f.setSize(400,400);
+ //f.pack();
+ f.show();
+ }*/
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CertRequestSelectTokenPane.java b/base/console/src/com/netscape/admin/certsrv/security/CertRequestSelectTokenPane.java
new file mode 100644
index 000000000..cab38e8d3
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CertRequestSelectTokenPane.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.admin.certsrv.security;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+/**
+ *
+ * Prompt user to see which token they want to use, and weather or not
+ * certificate has been installed or not.
+ *
+ * @version 1.0 98/07/10
+ * @author <A HREF="mailto:shihcm@netscape.com">shihcm@netscape.com</A>
+ *
+ */
+class CertRequestSelectTokenPane extends JPanel implements SuiConstants,
+IKeyCertPage {
+
+ JComboBox tokenSelection = new JComboBox();
+ JRadioButton _no;
+ JRadioButton _yes;
+ JRadioButton _noneed;
+
+ String _defaultToken;
+ String _internal;
+
+ /**
+ * Determain whether a cgi need to be call again
+ */
+ boolean modified = true;
+
+
+ /**
+ * Get the panel that is going to be displayed
+ * @return a panel to be displayed by the key & cert wizard
+ */
+ public JPanel getPanel() {
+ return this;
+ }
+
+ /**
+ * Checks if this panel can be shown
+ * @return true if this page can be shown
+ */
+ public boolean pageShow(WizardObservable observable) {
+ //might have to call cgi that loadmodule...
+ observable.put("sie",
+ KeyCertUtility.createTokenName(
+ observable.getConsoleInfo()));
+
+ if (tokenSelection.getItemCount() == 0) {
+ observable.put("createTrust" , new Boolean(true));
+
+ KeyCertTaskInfo taskInfo = observable.getTaskInfo();
+ taskInfo.put("sie", observable.get("sie"));
+
+ try {
+ taskInfo.exec(taskInfo.SEC_LSTOKEN);
+ } catch (Exception e) {
+ SuiOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(),
+ e.getMessage());
+ return true;
+ }
+
+ Vector cipherList = taskInfo.getResponse().getFamilyList();
+ for (int i = 0; i < cipherList.size(); i++) {
+ CipherEntry cipher = (CipherEntry)(cipherList.elementAt(i));
+ JComboBox tokenNames = cipher.getTokenComboBox();
+ for (int j = 0; j < cipher.getTokenCount(); j++) {
+ tokenSelection.addItem(tokenNames.getItemAt(j));
+ }
+ if (tokenSelection.getItemCount() > 0) {
+ observable.put("createTrust" , new Boolean(false));
+ }
+ }
+
+
+ boolean noDefaultToken = true;
+ for (int i = tokenSelection.getItemCount() - 1; i >= 0; i--) {
+ if (tokenSelection.getItemAt(i).equals(_defaultToken)) {
+ noDefaultToken = false;
+ }
+ }
+ if (noDefaultToken) {
+ tokenSelection.addItem(_defaultToken);
+ observable.put("createTrust" , new Boolean(true));
+ }
+
+ try {
+ tokenSelection.setSelectedIndex(0);
+ } catch (Exception e) {}
+ }
+
+ return true;
+ }
+
+
+ /**
+ * Checks if this panel can be hidden
+ * @return true if this page can be hide
+ */
+ public boolean pageHide(WizardObservable observable) {
+ /*observable.put("isInternal" , ((TOGGLEPANEeditor)(questionPane.getCtrlByName("isInternal"))).getValue());*/
+
+ try {
+ observable.put("isInternal" , new Boolean(true));
+ if (!(((String)(tokenSelection.getSelectedItem())).
+ toLowerCase()).startsWith(_internal.toLowerCase())) {
+ observable.put("isInternal" , new Boolean(false));
+ }
+ } catch (Exception e) {}
+ if (modified) {
+ observable.put("CertReqModified", new Boolean(true));
+ observable.put("tokenName" , tokenSelection.getSelectedItem());
+ observable.put("requestCert" , new Boolean(_no.isSelected()));
+ observable.put("installCert" ,
+ new Boolean(!(_noneed.isSelected())));
+ observable.put("noneed" , new Boolean(_noneed.isSelected()));
+ modified = false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Listen to changes to determain if cgi need to be called again
+ *
+ */
+ class ModifiedActionListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ modified = true;
+ }
+ }
+
+
+
+ /**
+ *
+ * Convinent method for create a numbered component:
+ * [panel]
+ * 1. bla bla bla
+ * 2. bla bla bla
+ * [panel]
+ *
+ */
+ private void addNumberedComponent(JPanel p, int count, Component c,
+ Vector components) {
+ //JPanel entry = new JPanel();
+ //entry.setLayout(new GridBagLayout());
+ GridBagUtil.constrain(p,
+ Box.createRigidArea(
+ new Dimension(SEPARATED_COMPONENT_SPACE, 0)), 0,
+ count - 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+ GridBagUtil.constrain(p,
+ new JLabel(Integer.toString(count) + ". "), 1,
+ count - 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.NONE, 0, 0, 0, 0);
+ GridBagUtil.constrain(p, c, 2, count - 1, 1, 1, 0.0, 0.0,
+ GridBagConstraints.NORTH,
+ GridBagConstraints.HORIZONTAL, 0, 0,
+ DIFFERENT_COMPONENT_SPACE, 0);
+
+
+ for (int i = 0; i < components.size(); i++) {
+ GridBagUtil.constrain(p,
+ (Component)(components.elementAt(i)), 2,
+ count + i, 1, 1, 1.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.NONE,
+ 0, 0, 0, 0);
+ }
+
+ //p.add(entry);
+ }
+
+ /**
+ *
+ * Create a token selection panel for Key & Cert wizard.
+ *
+ */
+ public CertRequestSelectTokenPane() {
+ super();
+ setLayout(new GridBagLayout());
+
+ ResourceSet resource = KeyCertUtility.getKeyCertWizardResourceSet();
+
+ _internal = resource.getString("SelectToken", "internal");
+ _defaultToken = resource.getString("SelectToken", "defaultToken");
+
+ _no = new JRadioButton(resource.getString("SelectToken", "no"),
+ true);
+ _yes = new JRadioButton(resource.getString("SelectToken", "yes"),
+ false);
+ _noneed =
+ new JRadioButton(resource.getString("SelectToken", "noNeed"),
+ false);
+
+ JLabel useExt_noneed =
+ new JLabel(resource.getString("SelectToken", "noNeed_ext"));
+ Insets b = _noneed.getMargin();
+ useExt_noneed.setBorder( new EmptyBorder( new Insets(0,
+ 12 + b.right + _noneed.getHorizontalTextPosition(),
+ b.bottom, b.right)));
+
+
+
+ ModifiedActionListener listener = new ModifiedActionListener();
+ _no.addActionListener(listener);
+ _yes.addActionListener(listener);
+ _noneed.addActionListener(listener);
+ tokenSelection.addActionListener(listener);
+
+
+ ButtonGroup buttonGroup = new ButtonGroup();
+ buttonGroup.add(_no);
+ buttonGroup.add(_yes);
+ buttonGroup.add(_noneed);
+
+
+ int y = 0;
+
+ setBorder( new TitledBorder( new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE)),
+ resource.getString("SelectToken", "title")));
+
+
+ JPanel tokenSelectPane = new JPanel();
+ //tokenSelectPane.setLayout(new BoxLayout(tokenSelectPane, BoxLayout.Y_AXIS));
+ tokenSelectPane.setLayout(new GridBagLayout());
+
+ JLabel _pickToken =
+ new JLabel(resource.getString("SelectToken", "pickToken"));
+ Vector components = new Vector();
+ components.addElement(tokenSelection);
+ addNumberedComponent(tokenSelectPane, ++y, _pickToken, components);
+ GridBagUtil.constrain(this, tokenSelectPane, 0, y, 1, 1, 0.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0,
+ DIFFERENT_COMPONENT_SPACE, 0);
+
+
+ JPanel certInstPane = new JPanel();
+ //certInstPane.setLayout(new BoxLayout(certInstPane, BoxLayout.Y_AXIS));
+ certInstPane.setLayout(new GridBagLayout());
+
+ components = new Vector();
+ components.addElement(_no);
+ components.addElement(_yes);
+ //need a radio button that can wrap the string.
+ components.addElement(_noneed);
+ components.addElement(useExt_noneed);
+ addNumberedComponent(certInstPane, ++y,
+ new MultilineLabel(
+ resource.getString("SelectToken", "certReadyForInst")),
+ components);
+ GridBagUtil.constrain(this, certInstPane, 0, y, 1, 1, 0.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, DIFFERENT_COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this, Box.createVerticalGlue(), 0, ++y,
+ 1, 1, 1.0, 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(this,
+ new JLabel(
+ resource.getString(null, "clickNextToContinue")), 0,
+ ++y, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+ }
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ CertRequestSelectTokenPane c = new CertRequestSelectTokenPane();
+ f.getContentPane().add("North",c );
+ f.setSize(400,400);
+ f.show();
+ }*/
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CertRequestTypePane.java b/base/console/src/com/netscape/admin/certsrv/security/CertRequestTypePane.java
new file mode 100644
index 000000000..cc36771a6
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CertRequestTypePane.java
@@ -0,0 +1,390 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.security;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+/**
+ *
+ * Step 2 of the certificate request under Key & Cert wizard.
+ * Pompt user to enter which type of certificate they want to request
+ * and the email address of the CA the request will be sent to.
+ *
+ * @version 1.0 98/07/10
+ * @author <A HREF="mailto:shihcm@netscape.com">shihcm@netscape.com</A>
+ *
+ */
+class CertRequestTypePane extends JPanel implements SuiConstants,
+IKeyCertPage {
+
+ JRadioButton _email;
+ SingleByteTextField _emailAddr = new SingleByteTextField();
+ JRadioButton _url;
+ SingleByteTextField _urlAddr = new SingleByteTextField();
+
+ JLabel _caEmailAddr;
+
+ JRadioButton _new;
+ JRadioButton _renew;
+
+ /**
+ * Get the panel that is going to be displayed
+ * @return a panel to be displayed by the key & cert wizard
+ */
+ IWizardControl control;
+ JButton _caButton;
+
+ MultilineLabel _showCALabel;
+
+ /**
+ * Determain whether a cgi need to be call again to decode
+ */
+ boolean modified = false;
+
+ public static Hashtable param = new Hashtable();
+
+ /**
+ * Get the panel that is going to be displayed
+ * @return a panel to be displayed by the key & cert wizard
+ */
+ public JPanel getPanel() {
+ return this;
+ }
+
+
+ /**
+ * Checks if this panel can be shown
+ * @return true if this page can be shown
+ */
+ public boolean pageShow(WizardObservable observable) {
+
+ boolean show =
+ ((Boolean)(observable.get("requestCert"))).booleanValue();
+
+ if (show) {
+ control = (IWizardControl)(observable.get("Wizard"));
+ setEnableNextButton();
+ }
+
+ if (observable.get("CertReqCGIParam") == null) {
+ observable.put("CertReqCGIParam", param);
+ }
+
+ return show;
+ }
+
+
+ /**
+ * Checks if this panel can be hidden
+ * @return true if this page can be hide
+ */
+ public boolean pageHide(WizardObservable observable) {
+ KeyCertTaskInfo taskInfo = observable.getTaskInfo();
+
+ //see if this page has been modified.
+ if (modified) {
+ observable.put("CertReqModified", new Boolean(true));
+
+ //radio button in a group will called twice one for the component that is loosing the focus
+ //and one for the component that is getting the focus
+ param.put("cert_type" , _new.isSelected() ? "0":"1");
+
+ //remove url support
+ param.put("xmt_select" , _email.isSelected() ? "0":"1");
+ param.put("url" , _urlAddr.getText());
+ param.put("cert_auth" , _emailAddr.getText());
+
+ //support only e-mail at this moment
+ //param.put("xmt_select" , "0");
+ //param.put("cert_auth" , _emailAddr.getText());
+
+ modified = false;
+ }
+
+ return true;
+ }
+
+
+ /**
+ * Listen to changes (key strokes or change in text area or text field)
+ * then determain (call setEnableNextButton()) if wizard can proceed
+ */
+ class TypeActionListener implements KeyListener, ActionListener {
+ public void keyTyped(KeyEvent e) {}
+ public void keyPressed(KeyEvent e) {}
+ public void keyReleased(KeyEvent e) {
+ setEnableNextButton();
+ modified = true;
+ }
+ public void actionPerformed(ActionEvent e) {
+
+ if (e.getActionCommand().equals("SHOWCA")) {
+ Browser browser = new Browser();
+ browser.open("https://certs.netscape.com/server.html",
+ browser.NEW_WINDOW);
+ } else {
+ if (_email.isSelected()) {
+ _urlAddr.setEnabled(false);
+ _emailAddr.setEnabled(true);
+ } else {
+ _urlAddr.setEnabled(true);
+ _emailAddr.setEnabled(false);
+ }
+ setEnableNextButton();
+ modified = true;
+ }
+ }
+ }
+
+ /**
+ * Detarmain all the require field has been fill in, if true the
+ * enable the "Next >" button.
+ */
+ void setEnableNextButton() {
+ if ((_email.isSelected() && (_emailAddr.getText().length() > 0)) ||
+ (_url.isSelected() && (_urlAddr.getText().length() > 0))) {
+ control.setCanGoForward(true);
+ } else {
+ control.setCanGoForward(false);
+ }
+ }
+
+ /**
+ *
+ * Convinent method for create a numbered component:
+ * [panel]
+ * 1. bla bla bla
+ * 2. bla bla bla
+ * [panel]
+ *
+ */
+ private void addNumberedComponent(JPanel p, int count, Component c,
+ Vector components) {
+ //JPanel entry = new JPanel();
+ //entry.setLayout(new GridBagLayout());
+ GridBagUtil.constrain(p,
+ Box.createRigidArea(
+ new Dimension(DIFFERENT_COMPONENT_SPACE, 0)), 0,
+ count - 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.NONE, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(p,
+ new JLabel(Integer.toString(count) + ". "), 1,
+ count - 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.NONE, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(p, c, 2, count - 1, 1, 1, 0.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, 0);
+
+ for (int i = 0; i < components.size(); i++) {
+ GridBagUtil.constrain(p,
+ (Component)(components.elementAt(i)), 2,
+ count + i, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH,
+ 0, 0, 0, 0);
+ }
+
+ //p.add(entry);
+ }
+
+
+
+ TypeActionListener listener = new TypeActionListener();
+
+
+ /**
+ * Prompt user to enter e-mail address of the CA where the
+ * cert request will submit.
+ *
+ * Comment out submit by url, will not support in 4.0 but will
+ * after 4.1 with agree upon standard between kingpin and cert
+ * server.
+ *
+ */
+ private JPanel getRequestViaPane() {
+ JPanel requestViaPane = new JPanel();
+ requestViaPane.setLayout(new GridBagLayout());
+
+ ButtonGroup buttonTypeGroup = new ButtonGroup();
+ buttonTypeGroup.add(_new);
+ buttonTypeGroup.add(_renew);
+
+ ButtonGroup buttonViaGroup = new ButtonGroup();
+ buttonViaGroup.add(_email);
+ buttonViaGroup.add(_url);
+
+ int y = 0;
+
+ _email.addActionListener(listener);
+ GridBagUtil.constrain(requestViaPane, _email, 0, y, 1, 1, 0.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, COMPONENT_SPACE, 0);
+
+ /*GridBagUtil.constrain(requestViaPane, _caEmailAddr,
+ 0, y, 1, 1,
+ 0.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH,
+ 0, 0, COMPONENT_SPACE, 0);*/
+
+ _emailAddr.addKeyListener(listener);
+ GridBagUtil.constrain(requestViaPane, _emailAddr, 1, y, 1, 1,
+ 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.HORIZONTAL, 0,
+ DIFFERENT_COMPONENT_SPACE, COMPONENT_SPACE, 0);
+
+ _url.addActionListener(listener);
+ GridBagUtil.constrain(requestViaPane, _url, 0, ++y, 1, 1, 0.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, COMPONENT_SPACE, 0);
+
+ _urlAddr.addKeyListener(listener);
+ GridBagUtil.constrain(requestViaPane, _urlAddr, 1, y, 1, 1,
+ 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.HORIZONTAL, 0,
+ DIFFERENT_COMPONENT_SPACE, COMPONENT_SPACE, 0);
+ _urlAddr.setEnabled(false);
+
+ return requestViaPane;
+ }
+
+
+
+ /**
+ *
+ * return a panel contain a button which if clicked will lunch browser
+ * and connect to netscape's cert server site.
+ * The site contain links and information regarding CAs and certificate.
+ *
+ */
+ private JPanel getCAButtonPane() {
+ JPanel caButtonPane = new JPanel();
+ caButtonPane.setLayout(new GridBagLayout());
+
+ GridBagUtil.constrain(caButtonPane, _showCALabel, 0, 0, 1, 1,
+ 1.0, 0.0, GridBagConstraints.WEST,
+ GridBagConstraints.BOTH, 0, 0, COMPONENT_SPACE, 0);
+
+ _caButton.addActionListener(listener);
+ _caButton.setActionCommand("SHOWCA");
+ GridBagUtil.constrain(caButtonPane, _caButton, 1, 0, 1, 1, 1.0,
+ 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE,
+ 0, DIFFERENT_COMPONENT_SPACE, COMPONENT_SPACE, 0);
+
+ return caButtonPane;
+ }
+
+ /**
+ *
+ * Create a certificate request type selection pane for key & cert wizard
+ *
+ *
+ */
+ public CertRequestTypePane() {
+ super();
+ setLayout(new GridBagLayout());
+
+ ResourceSet resource = KeyCertUtility.getKeyCertWizardResourceSet();
+
+ _caButton = JButtonFactory.create(
+ resource.getString("CertRequestTypePane", "showCAButtonLabel"));
+ _email = new JRadioButton( resource.getString("CertRequestTypePane",
+ "emailLabel"), true);
+ _url = new JRadioButton(
+ resource.getString("CertRequestTypePane", "urlLabel"),
+ false);
+ _new = new JRadioButton( resource.getString("CertRequestTypePane",
+ "newcertLabel"), true);
+ _renew = new JRadioButton( resource.getString("CertRequestTypePane",
+ "renewcertLabel"), false);
+
+ _caEmailAddr =
+ new JLabel(resource.getString("CertRequestTypePane", "caEmailLabel"));
+
+ _showCALabel = new MultilineLabel(
+ resource.getString("CertRequestTypePane", "showCALabel"));
+
+ setBorder( new TitledBorder( new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE)),
+ resource.getString("CertRequestTypePane", "title")));
+
+ int y = 0;
+
+ JPanel requestTypePane = new JPanel();
+ //requestTypePane.setLayout(new BoxLayout(requestTypePane, BoxLayout.Y_AXIS));
+ requestTypePane.setLayout(new GridBagLayout());
+ Vector components = new Vector();
+ _new.addActionListener(listener);
+ _renew.addActionListener(listener);
+ components.addElement(_new);
+ components.addElement(_renew);
+ addNumberedComponent(requestTypePane, ++y,
+ new MultilineLabel(
+ resource.getString("CertRequestTypePane",
+ "requestType")), components);
+ GridBagUtil.constrain(this, requestTypePane, 0, y, 1, 1, 0.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0,
+ DIFFERENT_COMPONENT_SPACE, 0);
+
+ JPanel requestViaPane = new JPanel();
+ //requestViaPane.setLayout(new BoxLayout(requestViaPane, BoxLayout.Y_AXIS));
+ requestViaPane.setLayout(new GridBagLayout());
+ components = new Vector();
+ components.addElement(getRequestViaPane());
+ addNumberedComponent(requestViaPane, ++y,
+ new MultilineLabel(
+ resource.getString("CertRequestTypePane",
+ "requestVia")), components);
+ //addNumberedComponent(requestViaPane, ++y, new MultilineLabel(resource.getString("CertRequestTypePane", "requestViaEmail")), components);
+ GridBagUtil.constrain(this, requestViaPane, 0, y, 1, 1, 0.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0,
+ DIFFERENT_COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this, getCAButtonPane(), 0, ++y, 1, 1,
+ 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0,
+ DIFFERENT_COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this, Box.createVerticalGlue(), 0, ++y,
+ 1, 1, 1.0, 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(this,
+ new JLabel(
+ resource.getString(null, "clickNextToContinue")), 0,
+ ++y, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+ }
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ f.getContentPane().add("North", new CertRequestTypePane());
+ f.setSize(400,400);
+ f.show();
+ }*/
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/ChangeKeyPasswordDialog.java b/base/console/src/com/netscape/admin/certsrv/security/ChangeKeyPasswordDialog.java
new file mode 100644
index 000000000..f939dfc89
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/ChangeKeyPasswordDialog.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.admin.certsrv.security;
+
+import com.netscape.management.client.console.ConsoleInfo;
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ *
+ * Change A Key Pair File Password
+ *
+ * @version 1.0 98/07/10
+ * @author <A HREF="mailto:shihcm@netscape.com">shihcm@netscape.com</A>
+ *
+ */
+public class ChangeKeyPasswordDialog extends AbstractDialog {
+
+ KeyCertTaskInfo taskInfo;
+ ConsoleInfo _consoleInfo;
+
+ String oldPasswdLabel;
+ String newPasswdLabel;
+ String confirmPasswdLabel;
+
+ //create password field with default width of 20 characters
+ SingleBytePasswordField oldPasswd = new SingleBytePasswordField(20);
+ SingleBytePasswordField newPasswd = new SingleBytePasswordField(20);
+ SingleBytePasswordField confirmPasswd = new SingleBytePasswordField(20);
+
+ ResourceSet resource = new ResourceSet("com.netscape.admin.certsrv.security.ChangeKeyPasswordDialogResource");
+
+ /**
+ * Called when OK button is pressed, and start the password change process
+ *
+ */
+ protected void okInvoked() {
+
+ taskInfo = new KeyCertTaskInfo(_consoleInfo);
+ taskInfo.clear();
+ taskInfo.put("sie", KeyCertUtility.createTokenName(_consoleInfo));
+ taskInfo.put("oldkfpw", oldPasswd.getText());
+ taskInfo.put("keyfilepw", newPasswd.getText());
+ taskInfo.put("keyfilepwv", confirmPasswd.getText());
+
+ if (!KeyCertUtility.validPassword(newPasswd.getText(),
+ confirmPasswd.getText(), _consoleInfo)) {
+ return;
+ }
+ Response response = null;
+ try {
+ response = taskInfo.exec(taskInfo.SEC_CHANGEPW);
+ } catch (Exception e) {
+ SuiOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(), e.getMessage());
+ return;
+ }
+
+ try {
+ MessageDialog.messageDialog(
+ (Message)(response.getMessages().elementAt(0)));
+ } catch (Exception ex) {}
+
+ if (((Message)(response.getMessages().elementAt(0))).getStatus()
+ == Message.NMC_SUCCESS)
+ super.okInvoked();
+ }
+
+ /**
+ * Called when HELP button is pressed, invoke online help
+ */
+ protected void helpInvoked() {
+ Help help = new Help(resource);
+ help.help("ChangeKeyPasswordDialog", "help");
+ }
+
+
+ private JLabel createRightAlignLabel(String label) {
+ return new JLabel(label, JLabel.RIGHT);
+ }
+
+ private JPanel getPasswdPane() {
+ JPanel passwdPane = new JPanel();
+ passwdPane.setLayout(new GridBagLayout());
+ int y = 0;
+
+ GridBagUtil.constrain(passwdPane,
+ createRightAlignLabel(
+ resource.getString("ChangeKeyPasswordDialog",
+ "oldPasswdLabel")), 0, y, 1, 1, 0.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH,
+ SEPARATED_COMPONENT_SPACE, 0, COMPONENT_SPACE,
+ COMPONENT_SPACE);
+
+ GridBagUtil.constrain(passwdPane, oldPasswd, 1, y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, SEPARATED_COMPONENT_SPACE, 0,
+ COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(passwdPane,
+ createRightAlignLabel(
+ resource.getString("ChangeKeyPasswordDialog",
+ "newPasswdLabel")), 0, ++y, 1, 1, 0.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, COMPONENT_SPACE);
+
+ GridBagUtil.constrain(passwdPane, newPasswd, 1, y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(passwdPane,
+ createRightAlignLabel(
+ resource.getString("ChangeKeyPasswordDialog",
+ "confirmPasswdLabel")), 0, ++y, 1, 1, 0.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, COMPONENT_SPACE);
+
+ GridBagUtil.constrain(passwdPane, confirmPasswd, 1, y, 1, 1,
+ 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, COMPONENT_SPACE, 0);
+
+ return passwdPane;
+ }
+
+
+ /**
+ * Create a dialog with 3 password field, for changing
+ * trust db password.
+ *
+ * @param consoleInfo Console information
+ *
+ */
+ public ChangeKeyPasswordDialog(ConsoleInfo consoleInfo) {
+ super(null, "", true, OK | CANCEL | HELP);
+
+ _consoleInfo = consoleInfo;
+
+ JPanel pane = new JPanel();
+ pane.setLayout(new BorderLayout());
+
+ //add some space between the explain text and the password prompt
+ //pane.add(Box.createRigidArea(new Dimension(0, SEPARATED_COMPONENT_SPACE)));
+
+ //add the password pane
+ pane.add("Center", getPasswdPane());
+
+ getContentPane().add(pane);
+ setTitle(resource.getString("ChangeKeyPasswordDialog", "explainText"));
+
+ pack();
+ show();
+ }
+
+ /*public static void main(String arg[]) {
+ ChangeKeyPasswordDialog c = (new ChangeKeyPasswordDialog(new ConsoleInfo()));
+ }*/
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CipherEntry.java b/base/console/src/com/netscape/admin/certsrv/security/CipherEntry.java
new file mode 100644
index 000000000..52f23ad4b
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CipherEntry.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.admin.certsrv.security;
+
+import java.util.*;
+import javax.swing.*;
+import java.awt.event.*;
+import com.netscape.management.client.util.*;
+
+class CipherEntry {
+ private JCheckBox _cipherEnable;
+ private JComboBox _tokenList;
+ private JComboBox _certList;
+
+
+ ResourceSet resource = new ResourceSet("com.netscape.admin.certsrv.security.EncryptionPaneResource");
+
+ private Hashtable _tokenCertList;
+ public CipherEntry(String cipherName, Hashtable tokenCertList) {
+ _cipherEnable = new JCheckBox(cipherName);
+
+ Vector tokenList = new Vector();
+ Enumeration tokens = tokenCertList.keys();
+ while (tokens.hasMoreElements()) {
+ tokenList.addElement(tokens.nextElement());
+ }
+
+ if (tokenList.size() == 0) {
+ tokenList.addElement(resource.getString("CipherEntry", "noToken"));
+ }
+
+ _tokenList = new JComboBox(tokenList);
+ _tokenCertList = tokenCertList;
+ _tokenList.addItemListener(new TokenListListener());
+
+ _certList = new JComboBox();
+
+ try {
+ _tokenList.setSelectedIndex(0);
+ } catch (Exception e) {}
+
+ }
+
+
+ public int getTokenCount() {
+ return _tokenCertList.size();
+ }
+
+ class TokenListListener implements ItemListener {
+ public void itemStateChanged(ItemEvent e) {
+ if (e.getStateChange() == e.SELECTED) {
+ //code here to swap in/out cert list
+ _certList.removeAllItems();
+ _certList.setEditable(false);
+ if (_tokenCertList.get(e.getItem()) != null) {
+ Vector certList =
+ (Vector)(_tokenCertList.get(e.getItem()));
+ if (certList.size() != 0) {
+ if (((String)(certList.elementAt(0))).
+ toLowerCase().indexOf("unknown") != -1) {
+ _certList.addItem(
+ resource.getString("CipherEntry", "enterCert"));
+ _certList.setEditable(true);
+ } else {
+ for (int i = 0; i < certList.size(); i++) {
+ _certList.addItem(certList.elementAt(i));
+ }
+ }
+ } else {
+ _certList.addItem(
+ resource.getString("CipherEntry", "noCert"));
+ }
+ } else {
+ _certList.addItem(
+ resource.getString("CipherEntry", "noCert"));
+ }
+ try {
+ _certList.setSelectedIndex(0);
+ _certList.validate();
+ _certList.repaint();
+ } catch (Exception exception) {}
+ }
+ }
+ }
+
+ public JCheckBox getCipherCheckBox() {
+ return _cipherEnable;
+ }
+ public JComboBox getTokenComboBox() {
+ return _tokenList;
+ }
+ public JComboBox getCertComboBox() {
+ return _certList;
+ }
+ public String getCipherName() {
+ return _cipherEnable.getText();
+ }
+
+ public String getSelectedToken() {
+ String selected = (String)(_tokenList.getSelectedItem());
+ if (selected.equalsIgnoreCase(
+ resource.getString("CipherEntry", "noToken"))) {
+ selected = "";
+ }
+ return selected;
+ }
+
+ public String getSelectedCertName() {
+ String selected = (String)(_certList.getSelectedItem());
+ if (selected == null || selected.equalsIgnoreCase(
+ resource.getString("CipherEntry", "noCert")) ||
+ selected.equalsIgnoreCase(
+ resource.getString("CipherEntry", "enterCert"))) {
+ selected = "";
+ }
+
+ return selected;
+ }
+
+ public boolean isEnabled() {
+ return _cipherEnable.isSelected();
+ }
+
+ public void setSelectedToken(String token) {
+ _tokenList.setSelectedItem(token);
+ }
+
+ public void setSelectedCert(String cert) {
+ //if (_certList.getModel().contains(java.lang.Object elem) ) {
+ _certList.setSelectedItem(cert);
+ //}
+ }
+
+ public void setSelected(boolean enabled) {
+ _cipherEnable.setSelected(enabled);
+ }
+
+ public void setEnabledAll(boolean enabled) {
+ _cipherEnable.setEnabled(enabled);
+ _tokenList.setEnabled(enabled);
+ _certList.setEnabled(enabled);
+ }
+
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+
+ Hashtable h = new Hashtable();
+ Vector v1 = new Vector();
+ Vector v2 = new Vector();
+ v1.addElement("v1.1");
+ v1.addElement("v1.2");
+ v1.addElement("v1.3");
+ v1.addElement("v1.4");
+ v2.addElement("v2.1");
+ v2.addElement("v2.2");
+ v2.addElement("v2.3");
+ v2.addElement("v2.4");
+ h.put("v1", v1);
+ h.put("v2", v2);
+
+ CipherEntry my = new CipherEntry("my", h);
+
+ JPanel p = new JPanel();
+ p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
+ p.add(my.getCipherCheckBox());
+ p.add(my.getTokenComboBox());
+ p.add(my.getCertComboBox());
+
+ f.getContentPane().add(p);
+ f.setSize(400,400);
+ f.show();
+ }*/
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CipherPreferenceDialog.java b/base/console/src/com/netscape/admin/certsrv/security/CipherPreferenceDialog.java
new file mode 100644
index 000000000..8a3564de0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CipherPreferenceDialog.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.admin.certsrv.security;
+
+import java.awt.*;
+import javax.swing.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+/**
+ * General dialog which display the ciper preference.
+ *
+ * @author <a href=mailto:shihcm@netscape.com>Chih Ming Shih</a>
+ * @version 0.2 9/3/97
+ */
+
+public class CipherPreferenceDialog extends AbstractDialog implements ICipherConstants {
+ SSL2CipherPreference ssl2CipherPref = null;
+ SSL3CipherPreference ssl3CipherPref = null;
+
+ /**SSL Version 2*/
+ public final static int SSL2 = 1;
+ /**SSL Version 3*/
+ public final static int SSL3 = 2;
+
+ private JPanel cipherPreferencePane;
+
+ boolean modified = true;
+ Help help;
+
+
+ /**
+ * Constructor, ciphers will default to SSL2 and SSL3
+ *
+ * @param parent The owner of the dialog
+ * @param isDomestic Software built domestic(allow stonger cipher) or export use
+ *
+ */
+ public CipherPreferenceDialog(JFrame parent, boolean isDomestic) {
+ this(parent, isDomestic, false);
+ }
+
+ /**
+ * Constructor, ciphers will default to SSL2 and SSL3
+ *
+ * @param parent The owner of the dialog
+ * @param isDomestic Software built domestic(allow stonger cipher) or export use
+ * @param hasFortezza Fortezza enabled server
+ *
+ */
+ public CipherPreferenceDialog(JFrame parent, boolean isDomestic,
+ boolean hasFortezza) {
+ this(parent, isDomestic, hasFortezza, SSL2 | SSL3);
+ }
+
+
+ /**
+ * Constructor
+ *
+ * @param parent The owner of the dialog
+ * @param isDomestic Software built domestic(allow stonger cipher) or export use
+ * @param hasFortezza Fortezza enabled server
+ * @param SSLVersion SSL version ciphers to display, SSL2 and/or SSL3
+ *
+ */
+ public CipherPreferenceDialog(JFrame parent, boolean isDomestic,
+ boolean hasFortezza, int SSLVersion) {
+ super(parent, "", true, OK | CANCEL | HELP);
+
+ ResourceSet r = new CipherResourceSet();
+ help = new Help(r);
+
+
+ cipherPreferencePane = new JPanel();
+ cipherPreferencePane.setLayout(
+ new BoxLayout(cipherPreferencePane, BoxLayout.Y_AXIS));
+ if ((SSL2 & SSLVersion) == SSL2) {
+ ssl2CipherPref = new SSL2CipherPreference(isDomestic);
+ cipherPreferencePane.add(ssl2CipherPref);
+ }
+
+ if ((SSL3 & SSLVersion) == SSL3) {
+ ssl3CipherPref =
+ new SSL3CipherPreference(isDomestic, hasFortezza);
+ cipherPreferencePane.add(ssl3CipherPref);
+ }
+
+ cipherPreferencePane.add(Box.createRigidArea(new Dimension(0, 4)));
+
+ getContentPane().add(cipherPreferencePane);
+
+ pack();
+ }
+
+ /**
+ * Remove SSL preference pane, currently only support SSL2 and SSL3.
+ * Will support Fortezza if only Phaos will support it.
+ *
+ * @param sslVersion SSL version to be removed
+ *
+ */
+ public void removeSSLVersion(int sslVersion) {
+ switch (sslVersion) {
+ case SSL2:
+ cipherPreferencePane.remove(ssl2CipherPref);
+ break;
+ case SSL3:
+ cipherPreferencePane.remove(ssl3CipherPref);
+ break;
+ }
+ pack();
+ }
+
+ /**
+ * Determines whether a cipher is enabled.
+ * @param cipher Cipher name
+ *
+ * @see #getSSLPreference
+ * @see #setCipherEnabled
+ *
+ * @return True if a cipher is enabled
+ */
+ public boolean isCipherEnabled(String cipher) {
+ return ( ((ssl2CipherPref == null) ? false :
+ ssl2CipherPref.isCipherEnabled(cipher)) ||
+ ((ssl3CipherPref == null) ? false :
+ ssl3CipherPref.isCipherEnabled(cipher)));
+ }
+
+ /**
+ * Enable or disable a cipher.
+ * @param cipher Cipher name
+ * @param enable Enable the cipher
+ *
+ * @see #isCipherEnabled
+ * @see #getSSLPreference
+ */
+ public void setCipherEnabled(String cipher, boolean enable) {
+ if (ssl2CipherPref != null) {
+ ssl2CipherPref.setCipherEnabled(cipher, enable);
+ }
+ if (ssl3CipherPref != null) {
+ ssl3CipherPref.setCipherEnabled(cipher, enable);
+ }
+ }
+
+ /**
+ * Get a list of supported ciphers.
+ * @param sslVersion SSL version
+ *
+ * @see #isCipherEnabled
+ * @see #setCipherEnabled
+ *
+ * @return An array that contains the name of supported ciphers under SSL version
+ */
+ public String[] getSSLPreference(int sslVersion) {
+ String[] ciphers = null;
+
+ switch (sslVersion) {
+ case SSL2:
+ ciphers = ssl2CipherPref.getCipherList();
+ break;
+ case SSL3:
+ ciphers = ssl3CipherPref.getCipherList();
+ break;
+ default :
+ //programmer's fault, do nothing here
+ Debug.println("Cipher Preference : Invalid ssl version "+
+ sslVersion);
+ break;
+ }
+ return ciphers;
+ }
+
+
+ /**
+ * Determines whether a cipher group(ssl version) is enabled.
+ * @param sslVersion SSL version
+ *
+ * @see #setSSLEnabled
+ *
+ * @return True if the speicified SSL version is enabled
+ */
+ public boolean isSSLEnabled(int sslVersion) {
+ boolean enable = false;
+ switch (sslVersion) {
+ case SSL2:
+ enable = ssl2CipherPref.isEnabled();
+ break;
+ case SSL3:
+ enable = ssl3CipherPref.isEnabled();
+ break;
+ default:
+ //programmer's fault, do nothing here
+ Debug.println("Cipher Preference : Invalid ssl version "+
+ sslVersion);
+ break;
+ }
+ return enable;
+ }
+
+ /**
+ * Enable or disable a cipher group.
+ * @param sslVersion SSL Version
+ * @param enable Enable the SSL version
+ *
+ * @see #isSSLEnabled
+ */
+ public void setSSLEnabled(int sslVersion, boolean enable) {
+ switch (sslVersion) {
+ case SSL2:
+ ssl2CipherPref.setEnabled(enable);
+ break;
+ case SSL3:
+ ssl3CipherPref.setEnabled(enable);
+ break;
+ default:
+ //programmer's fault, do nothing here
+ Debug.println("Cipher Preference : Invalid ssl version "+
+ sslVersion);
+ break;
+ }
+ }
+
+
+
+ /**
+ * Check weather any ciphers has been modified
+ *
+ */
+ public boolean isModified() {
+ return modified;
+ }
+
+ /**
+ * Reset all changes since last save
+ *
+ * @see #setSaved
+ */
+ public void reset() {
+ if (ssl2CipherPref != null) {
+ ssl2CipherPref.reset();
+ }
+ if (ssl3CipherPref != null) {
+ ssl3CipherPref.reset();
+ }
+ }
+
+
+
+ /**
+ * Set the state to save.
+ *
+ * @see #reset
+ */
+ public void setSaved() {
+ if (ssl2CipherPref != null) {
+ ssl2CipherPref.setSaved();
+ }
+
+ if (ssl3CipherPref != null) {
+ ssl3CipherPref.setSaved();
+ }
+ }
+
+ /**
+ * Set the state to save.
+ *
+ * @see #reset
+ * @derprecated replaced by setSaved()
+ */
+ public void setSaved(boolean saved) {
+
+ if (saved) {
+ if (ssl2CipherPref != null) {
+ ssl2CipherPref.setSaved();
+ }
+
+ if (ssl3CipherPref != null) {
+ ssl3CipherPref.setSaved();
+ }
+ }
+ }
+
+ protected void cancelInvoked() {
+ reset();
+ modified = false;
+ super.cancelInvoked();
+ }
+
+ protected void okInvoked() {
+ modified = (((ssl2CipherPref == null) ? false :
+ ssl2CipherPref.isModified()) ||
+ ((ssl3CipherPref == null) ? false :
+ ssl3CipherPref.isModified()));
+ setSaved();
+ super.okInvoked();
+ }
+
+
+ protected void helpInvoked() {
+ help.help("SSL", "Preference");
+ }
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+
+ try {
+ UIManager.setLookAndFeel("javax.swing.plaf.windows.WindowsLookAndFeel");
+ SwingUtilities.updateComponentTreeUI(f.getContentPane());
+ } catch (Exception e) {}
+
+ CipherPreferenceDialog c = new CipherPreferenceDialog(f, true, false, SSL3);
+
+ c.show();
+ }*/
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CipherResourceSet.java b/base/console/src/com/netscape/admin/certsrv/security/CipherResourceSet.java
new file mode 100644
index 000000000..3adf50548
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CipherResourceSet.java
@@ -0,0 +1,26 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.security;
+
+import com.netscape.management.client.util.ResourceSet;
+
+class CipherResourceSet extends ResourceSet {
+ public CipherResourceSet() {
+ super("com.netscape.admin.certsrv.security.CipherResource");
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/Comm.java b/base/console/src/com/netscape/admin/certsrv/security/Comm.java
new file mode 100644
index 000000000..1bbd022bf
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/Comm.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.admin.certsrv.security;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import com.netscape.management.client.comm.*;
+import com.netscape.management.client.util.*;
+
+/**
+ *
+ * Extends dt's comm package to do some communication with backend.
+ * eventually this will be phase out, and key cert related tasks that
+ * require cgi call will use AdmTask.java instead of this one.
+ *
+ * @version 1.0 98/07/10
+ * @author <A HREF="mailto:shihcm@netscape.com">shihcm@netscape.com</A>
+ *
+ */
+class Comm implements CommClient, Runnable {
+ public static final int DEFAULT_TIMEOUT_PERIOD = 30000; // 30 seconds
+ public boolean finished = false;
+ public String value = null;
+
+
+ static String server_response = null;
+
+ String url_cgi;
+ Hashtable cgi_arg;
+ boolean waitForResponse;
+
+ String id = "Admin";
+ String pw = "Admin";
+
+ Exception error = null;
+
+ public Comm(String url_cgi, Hashtable cgi_arg,
+ boolean waitForResponse) {
+ this.url_cgi = url_cgi;
+ this.cgi_arg = cgi_arg;
+ this.waitForResponse = waitForResponse;
+ }
+
+
+ public void setAuth(String userName, String password) {
+ this.id = userName;
+ this.pw = password;
+ }
+
+ public Exception getError() {
+ return error;
+ }
+
+ public static String getData() {
+ return server_response;
+ }
+
+ public void run() {
+ HttpManager h = new HttpManager();
+
+ try {
+ ByteArrayInputStream value = HttpChannel.encode(cgi_arg);
+ h.post(new URL(url_cgi), this, null, value,
+ value == null ? 0 : value.available(),
+ CommManager.FORCE_BASIC_AUTH);
+ awaitValue();
+ } catch (InterruptedIOException timeout) {
+ error = timeout;
+ }
+ catch (ConnectException connectError) {
+ error = connectError;
+ }
+ catch (IOException ioError) {
+ error = ioError;
+ }
+ catch (Exception e) {
+ error = e;
+ }
+ }
+
+ public synchronized void awaitValue() {
+ try {
+ wait(DEFAULT_TIMEOUT_PERIOD);
+ } catch (Exception e) {
+ error = e;
+ }
+ if (value == null) {
+ error = new InterruptedIOException("HTTP response timeout");
+ }
+ }
+
+
+ public synchronized void finish() {
+ finished = true;
+ notifyAll();
+ }
+
+ public synchronized void setValue(String s) {
+ value = s;
+
+ server_response = s;
+
+ notifyAll();
+ }
+
+ public void replyHandler(InputStream response, CommRecord cr) {
+ try {
+ InputStreamReader reader =
+ new InputStreamReader(response, "UTF8");
+ int c = reader.read();
+
+ if (c == 'S') {
+ finish();
+ return;
+ }
+ String s = (char) c + "";
+
+ while ((c = reader.read()) != -1) {
+ s += (char) c + "";
+ }
+
+ setValue(s);
+ } catch (Exception e) {
+ error = e;
+ }
+ }
+
+ public void errorHandler(Exception exception, CommRecord cr) {
+ error = exception;
+ Debug.println("errorHandler: " + exception);
+ finish();
+ }
+
+ public String username(Object auth, CommRecord cr) {
+ return id;
+ }
+
+ public String password(Object auth, CommRecord cr) {
+ return pw;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/CreateTrustPane.java b/base/console/src/com/netscape/admin/certsrv/security/CreateTrustPane.java
new file mode 100644
index 000000000..03b5c32d6
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/CreateTrustPane.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.admin.certsrv.security;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+class CreateTrustPane extends JPanel implements SuiConstants, IKeyCertPage {
+
+ SingleBytePasswordField _passwd = new SingleBytePasswordField(20);
+ SingleBytePasswordField _confirmPasswd =
+ new SingleBytePasswordField(20);
+ JLabel _selectedToken = new JLabel();
+
+ JLabel _passwdLabel;
+ JLabel _tokenLabel;
+ JLabel _confirmPasswdLabel;
+
+ IWizardControl control;
+
+ String _noNeedToRequestInstallCert;
+
+ public JPanel getPanel() {
+ return this;
+ }
+
+ public boolean pageShow(WizardObservable observable) {
+ boolean show = false;
+
+ ((StatusPane)(observable.get("statusPane"))).setShow(false);
+ if (((Boolean)(observable.get("createTrust"))).booleanValue()) {
+ show = true;
+
+ if ((_passwd.getText().length() == 0) ||
+ (_confirmPasswd.getText().length() == 0)) {
+ control = (IWizardControl)(observable.get("Wizard"));
+ control.setCanGoForward(false);
+ }
+
+ _selectedToken.setText((String)(observable.get("sie")));
+ } else if (((Boolean)(observable.get("noneed"))).booleanValue()) {
+ StatusPane statusPane = (StatusPane)(observable.get("statusPane"));
+ statusPane.setMessage(_noNeedToRequestInstallCert);
+ statusPane.setShow(true);
+ statusPane.setLastPage(true);
+
+ ((IWizardControl)(observable.get("Wizard"))).setIsLastPage(
+ true);
+ }
+
+ return show;
+ }
+
+ public boolean pageHide(WizardObservable observable) {
+ boolean hide = false;
+
+ String dbName = (String)(observable.get("sie"));
+
+ if (!KeyCertUtility.validPassword(_passwd.getText(),
+ _confirmPasswd.getText(), (observable.getConsoleInfo()))) {
+ hide = false;
+ } else if ( (_passwd.getText().equals(_confirmPasswd.getText())) &&
+ (!(dbName.equals("")))) {
+ KeyCertTaskInfo taskInfo =
+ ((WizardObservable) observable).getTaskInfo();
+ taskInfo.put("alias", dbName);
+ taskInfo.put("keyfilepw", _confirmPasswd.getText());
+ observable.put("keyPasswd", _confirmPasswd.getText());
+ try {
+ taskInfo.exec(taskInfo.SEC_TRUST);
+ } catch (Exception e) {
+ SuiOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(),
+ e.getMessage());
+ return false;
+ }
+
+
+ //MessageDialog.messageDialog((Message)(taskInfo.getResponse().getMessages().elementAt(0)));
+ StatusPane statusPane = (StatusPane)(observable.get("statusPane"));
+ statusPane.setMessage( (Message)
+ (taskInfo.getResponse().getMessages().elementAt(0)));
+ statusPane.setShow(true);
+
+ if (((Message)
+ (taskInfo.getResponse().getMessages().elementAt(0))
+ ).getStatus() == Message.NMC_SUCCESS) {
+ hide = true;
+ observable.put("createTrust", new Boolean(false));
+
+ if (((Boolean)(observable.get("noneed"))).booleanValue()) {
+ statusPane.appendMessage("\n\n"+
+ _noNeedToRequestInstallCert);
+ statusPane.setLastPage(true);
+ ((IWizardControl)(observable.get("Wizard"))).
+ setIsLastPage(true);
+ }
+ }
+ }
+
+ return hide;
+ }
+
+
+ class KeyActionListener implements KeyListener {
+ public void keyTyped(KeyEvent e) {}
+ public void keyPressed(KeyEvent e) {}
+ public void keyReleased(KeyEvent e) {
+ if (_passwd.getText().length() > 0) {
+ control.setCanGoForward(true);
+ } else {
+ control.setCanGoForward(false);
+ }
+ }
+ }
+
+ private JPanel getPasswdPane() {
+ JPanel passwdPane = new JPanel();
+ passwdPane.setLayout(new GridBagLayout());
+ int y = 0;
+
+
+ GridBagUtil.constrain(passwdPane, _tokenLabel, 0, ++y, 1, 1,
+ 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, COMPONENT_SPACE, 0);
+
+
+ GridBagUtil.constrain(passwdPane, _selectedToken, 1, y, 1, 1,
+ 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, DIFFERENT_COMPONENT_SPACE,
+ COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(passwdPane, _passwdLabel, 0, ++y, 1, 1,
+ 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, COMPONENT_SPACE, 0);
+
+ _passwd.addKeyListener(new KeyActionListener());
+ GridBagUtil.constrain(passwdPane, _passwd, 1, y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, DIFFERENT_COMPONENT_SPACE,
+ COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(passwdPane, _confirmPasswdLabel, 0, ++y,
+ 1, 1, 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, COMPONENT_SPACE, 0);
+
+ _confirmPasswd.addKeyListener(new KeyActionListener());
+ GridBagUtil.constrain(passwdPane, _confirmPasswd, 1, y, 1, 1,
+ 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, DIFFERENT_COMPONENT_SPACE,
+ COMPONENT_SPACE, 0);
+
+ return passwdPane;
+ }
+
+ public CreateTrustPane() {
+ super();
+ setLayout(new GridBagLayout());
+
+ ResourceSet resource = KeyCertUtility.getKeyCertWizardResourceSet();
+ _passwdLabel = new JLabel(
+ resource.getString("CreateTrustPane", "passwdLabel"),
+ JLabel.RIGHT);
+ _tokenLabel = new JLabel(
+ resource.getString("CreateTrustPane", "tokenLabel"),
+ JLabel.RIGHT);
+ _confirmPasswdLabel = new JLabel(
+ resource.getString("CreateTrustPane", "confirmPasswdLabel"),
+ JLabel.RIGHT);
+
+ _noNeedToRequestInstallCert =
+ resource.getString("CreateTrustPane", "noNeedToRequestInstallCert");
+
+
+ setBorder( new TitledBorder( new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE)),
+ resource.getString("CreateTrustPane", "title")));
+
+ int y = 0;
+
+ GridBagUtil.constrain(this,
+ new MultilineLabel(
+ resource.getString("CreateTrustPane", "explain")), 0,
+ ++y, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0,
+ DIFFERENT_COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this, getPasswdPane(), 0, ++y, 1, 1, 1.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0,
+ DIFFERENT_COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this, Box.createVerticalGlue(), 0, ++y,
+ 1, 1, 1.0, 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(this,
+ new JLabel(
+ resource.getString(null, "clickNextToContinue")), 0,
+ ++y, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+ }
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ f.getContentPane().add("North", new CreateTrustPane());
+ f.setSize(400,400);
+ f.show();
+ }*/
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/EncryptionPane.java b/base/console/src/com/netscape/admin/certsrv/security/EncryptionPane.java
new file mode 100644
index 000000000..1a472ca76
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/EncryptionPane.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.admin.certsrv.security;
+
+import java.awt.*;
+import java.util.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+import com.netscape.management.client.console.*;
+import javax.swing.plaf.*;
+
+import java.io.*;
+
+/**
+ *
+ * Encryption panel used for server configuration.
+ *
+ *
+ * @version 1.0 98/07/10
+ * @author <A HREF="mailto:shihcm@netscape.com">shihcm@netscape.com</A>
+ *
+ */
+public class EncryptionPane extends JPanel implements ActionListener {
+
+ private JCheckBox on;
+ String title;
+
+ JPanel top;
+ JPanel cipherPane;
+
+ private Vector cipherList = new Vector();
+
+ boolean isFortezza = false;
+ boolean isDomestic = false;
+
+ ConsoleInfo _consoleInfo;
+ String certdbName;
+
+ JButton bCipherPref;
+ JButton wizardButton;
+
+ JLabel cipherTitle;
+ JLabel tokenTitle;
+ JLabel certTitle;
+
+
+ Vector encryptionPaneListeners = new Vector();
+
+ EncryptionPaneActionListener actionListener =
+ new EncryptionPaneActionListener();
+
+ KeyCertTaskInfo taskInfo;
+
+ ResourceSet resource;
+
+ /**
+ *
+ * @deprecated implement IEncryptionPaneListener instead
+ */
+ public void actionPerformed(ActionEvent e) {
+ }
+
+
+ class EncryptionPaneActionListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ if (e.getActionCommand().equals(".doCipherSetting")) {
+ for (int i = 0; i < encryptionPaneListeners.size(); i++) {
+ ((IEncryptionPaneListener)
+ (encryptionPaneListeners.elementAt(i))).
+ showCipherPreferenceDialog();
+ }
+ } else if (e.getActionCommand().equals("ENABLED")) {
+ for (int i = 0; i < encryptionPaneListeners.size(); i++) {
+ ((IEncryptionPaneListener)
+ (encryptionPaneListeners.elementAt(i))).
+ sslStateChanged(on.isSelected());
+ }
+ } else {
+ for (int i = 0; i < encryptionPaneListeners.size(); i++) {
+ Object cipher = getCipher(e.getActionCommand());
+ ((IEncryptionPaneListener)
+ (encryptionPaneListeners.elementAt(i))).
+ cipherStateChanged(isEnabled(cipher),
+ getCipherName(cipher), getToken(cipher),
+ getCertificateName(cipher));
+ }
+ }
+ }
+ }
+
+ /**
+ * Add a listener to the list that's notified each time a change to the selection occurs.
+ *
+ */
+ public void addEncryptionPaneListener(
+ IEncryptionPaneListener listener) {
+ encryptionPaneListeners.addElement(listener);
+ }
+
+
+
+ /**
+ *
+ * Create an encryption panel
+ *
+ * @param consoleInfo server sepcific information
+ */
+ public EncryptionPane(ConsoleInfo consoleInfo) {
+ this(consoleInfo, null);
+ }
+
+ /**
+ *
+ * Create an encryption panel
+ *
+ * @param consoleInfo server sepcific information
+ * @param addPanel add customized panel into encryption panel
+ */
+ public EncryptionPane(ConsoleInfo consoleInfo, JPanel addPanel) {
+ super();
+
+ //actionListener
+
+ _consoleInfo = consoleInfo;
+ certdbName = KeyCertUtility.createTokenName(consoleInfo);
+
+
+ setLayout(new BorderLayout());
+
+ //setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+ JPanel mainPane = new JPanel();
+ //mainPane.setLayout(new BorderLayout());
+ mainPane.setLayout(new GridBagLayout());
+
+
+ resource = new ResourceSet("com.netscape.admin.certsrv.security.EncryptionPaneResource");
+
+ on = new JCheckBox(resource.getString("EncryptionPane", "enableSSL"),
+ false);
+ on.setActionCommand("ENABLED");
+ on.addActionListener(new CipherPaneToggleListener());
+
+ on.addActionListener(actionListener);
+
+
+ top = new JPanel();
+ top.setAlignmentX(0.0f);
+ top.setLayout(new BoxLayout(top, BoxLayout.X_AXIS));
+ top.add(on);
+
+ //mainPane.setBorder(new ToggleBorder(top, SwingConstants.TOP));
+ mainPane.setBorder( new CompoundBorder(
+ new ToggleBorder(top, SwingConstants.TOP),
+ new EmptyBorder(0, SuiConstants.COMPONENT_SPACE,
+ SuiConstants.COMPONENT_SPACE, 0)));
+
+ GridBagUtil.constrain(mainPane, top, 0, 0, 1, 1, 0.0, 0.0,
+ GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
+ 0, 0, 0, 0);
+
+
+ cipherPane = new JPanel();
+ cipherPane.setLayout(new BorderLayout());
+
+ GridBagUtil.constrain(mainPane, cipherPane, 0, 1, 2, 1, 1.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0,
+ SuiConstants.COMPONENT_SPACE, 0);
+
+ bCipherPref = JButtonFactory.create(
+ resource.getString("EncryptionPane", "cipherPrefTitle"));
+ wizardButton = JButtonFactory.create(
+ resource.getString("EncryptionPane", "wizardTitle"));
+
+ bCipherPref.setActionCommand(".doCipherSetting");
+ bCipherPref.addActionListener(this);
+
+ bCipherPref.addActionListener(actionListener);
+
+ wizardButton.setActionCommand("WIZARD");
+ wizardButton.addActionListener(new wizardButtonActionListener());
+
+
+ updateEncryptionUI();
+
+ add("North", mainPane);
+
+
+ //other pane contain server specific pane and a wizrad button.
+ JPanel otherPane = new JPanel();
+ otherPane.setLayout(new BoxLayout(otherPane, BoxLayout.Y_AXIS));
+ //otherPane.setLayout(new GridBagLayout());
+
+ if (addPanel != null) {
+ otherPane.add(addPanel);
+ }
+
+ otherPane.add( Box.createRigidArea(
+ new Dimension(0, SuiConstants.COMPONENT_SPACE)));
+
+ add("Center", otherPane);
+
+ JPanel buttonPane = new JPanel();
+ buttonPane.setLayout(new GridBagLayout());
+ GridBagUtil.constrain(buttonPane, wizardButton, 0, 0, 1, 1,
+ 0.0, 0.0, GridBagConstraints.SOUTHWEST,
+ GridBagConstraints.NONE, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(buttonPane, Box.createHorizontalGlue(),
+ 1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.SOUTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ //add("South", wizardButton);
+ add("South", buttonPane);
+
+ }
+
+ /**
+ * Returns a vector containing cipher objects
+ * @see #getCipherCount
+ * @see #getCipherAt
+ *
+ * @return a vector contains cipher object as element
+ */
+ public Vector getCipherList() {
+ return cipherList;
+ }
+
+
+ /**
+ * Returns the number of cipher objects in encryption pane
+ *
+ * @see #getCipherList
+ * @see #getCipherAt
+ *
+ * @return the number of cipher object in encryption pane
+ */
+ public int getCipherCount() {
+ return cipherList.size();
+ }
+
+ /**
+ * Returns the cipher object at the specified index.
+ *
+ * @param index an index into cipher list.
+ *
+ * @see #getCipherList
+ * @see #getCipherCount
+ *
+ * @return the number of cipher object in encryption pane
+ */
+ public Object getCipherAt(int index) {
+ return cipherList.elementAt(index);
+ }
+
+ private CipherEntry getCipher(String cipherName) {
+ int count = getCipherCount();
+ for (int i = count - 1; i >= 0; i--) {
+ Object cipher = getCipherAt(i);
+ if (cipherName.equals(getCipherName(cipher))) {
+ return ((CipherEntry) cipher);
+ }
+ }
+ return null;
+ }
+
+
+ /**
+ * Return cipher name
+ *
+ * @param cipher cipher object
+ *
+ * @return cipher name
+ */
+ public String getCipherName(Object cipher) {
+ return ((CipherEntry) cipher).getCipherName();
+ }
+
+
+ /**
+ * Return selected token name
+ *
+ * @param cipher cipher object
+ *
+ * @return selected token
+ */
+ public String getToken(Object cipher) {
+ return ((CipherEntry) cipher).getSelectedToken();
+ }
+
+
+ /**
+ * Set token selection. Default will be taken if no selection
+ * match the token user specified.
+ *
+ * @param cipher cipher object
+ *
+ */
+ public void setToken(Object cipher, String token) {
+ ((CipherEntry) cipher).setSelectedToken(token);
+ }
+
+
+
+ /**
+ * Return certificate name
+ *
+ * @param cipher cipher object
+ *
+ * @return certificate name
+ *
+ */
+ public String getCertificateName(Object cipher) {
+ return ((CipherEntry) cipher).getSelectedCertName();
+
+ }
+
+ /**
+ * Set the certificate field to the specified certificate name
+ *
+ * @param cipher cipher object
+ * @param certificateName certificate name
+ *
+ */
+ public void setCertificateName(Object cipher, String certificateName) {
+ ((CipherEntry) cipher).setSelectedCert(certificateName);
+ }
+
+ /**
+ * Return cipher state, true a cipher is enabled
+ *
+ * @param cipher cipher object
+ *
+ * @return true if a cipher is enabled false other wise
+ */
+ public boolean isEnabled(Object cipher) {
+ return ((CipherEntry) cipher).isEnabled();
+ }
+
+ /**
+ * Set cipher state
+ *
+ * @param cipher cipher object
+ * @param on cipher state
+ *
+ */
+ public void setEnabled(Object cipher, boolean on) {
+ ((CipherEntry) cipher).setSelected(on);
+ }
+
+
+ /**
+ * Return encryption setting
+ *
+ * @return true if SSL on/off is on.
+ */
+ public boolean isEncryptionEnabled() {
+ return on.isSelected();
+ //return ((Boolean)(encryptionOnOff.getValue())).booleanValue();
+ }
+
+ /**
+ * Set encryption on/off
+ *
+ */
+ public void setEncryption(boolean on) {
+ setEnableAll(on);
+ this.on.setSelected(on);
+ //encryptionOnOff.setValue(new Boolean(on));
+ }
+
+ /**
+ * Return certificate database file name
+ *
+ * @param certificate database file name
+ */
+ public String getCertificateDBName() {
+ return certdbName;
+ }
+
+ /**
+ * A convenience function to setup an cipher.
+ * If no matching cipherName found in the encryption
+ * pane, this function will do nothing.
+ *
+ * @param on cipher state
+ * @param cipherName cipher name
+ * @param token token name
+ * @param personality personality name
+ *
+ * @see #setEnabled
+ */
+ public void setCipherSetting(boolean on, String cipherName,
+ String token, String personality) {
+ int count = getCipherCount();
+ for (int i = count - 1; i >= 0; i--) {
+ Object cipher = getCipherAt(i);
+ if (cipherName.equals(getCipherName(cipher))) {
+ setEnabled(cipher, on);
+ setToken(cipher, token);
+ setCertificateName(cipher, personality);
+ }
+ }
+ }
+
+ /**
+ *
+ * @return true if fortezza is detected on the server
+ */
+ public boolean hasFortezza() {
+ return isFortezza;
+ }
+
+
+ /**
+ *
+ * @return true if a domestic server is detected
+ */
+ public boolean isSecurityDomestic() {
+ return isDomestic;
+ }
+
+ /**
+ *
+ * @return encryption pane
+ */
+ public JPanel getPanel() {
+ return this;
+ }
+
+
+
+ private JLabel leftAlignLabel(String label) {
+ return new JLabel(label, JLabel.LEFT);
+ }
+
+ private void updateCipherEntry() {
+ }
+
+
+ /**
+ * Update ui
+ *
+ */
+ public void refresh() {
+ updateEncryptionUI();
+ }
+
+ JPanel cPane = new JPanel();
+ private void updateEncryptionUI() {
+ cPane.removeAll();
+
+ cPane.setLayout(new GridBagLayout());
+
+ int y = 0;
+
+ cipherTitle =
+ leftAlignLabel(resource.getString("EncryptionPane", "cipherTitle"));
+ tokenTitle =
+ leftAlignLabel(resource.getString("EncryptionPane", "tokenTitle"));
+ certTitle =
+ leftAlignLabel(resource.getString("EncryptionPane", "certTitle"));
+
+ GridBagUtil.constrain(cPane, cipherTitle, 0, y, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH,
+ SuiConstants.HORIZ_COMPONENT_INSET, 0,
+ SuiConstants.COMPONENT_SPACE,
+ SuiConstants.SEPARATED_COMPONENT_SPACE);
+ GridBagUtil.constrain(cPane, tokenTitle, 1, y, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, SuiConstants.COMPONENT_SPACE,
+ SuiConstants.SEPARATED_COMPONENT_SPACE);
+ GridBagUtil.constrain(cPane, certTitle, 2, y, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, SuiConstants.COMPONENT_SPACE, 0);
+
+ taskInfo = new KeyCertTaskInfo(_consoleInfo);
+ taskInfo.clear();
+
+ taskInfo.put("sie", certdbName);
+
+ try {
+ taskInfo.exec(taskInfo.SEC_LSTOKEN);
+ } catch (Exception e) {
+ SuiOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(), e.getMessage());
+ return;
+ }
+
+ cipherList = taskInfo.getResponse().getFamilyList();
+
+ isFortezza = taskInfo.getResponse().isSecurityFortezza();
+ isDomestic = taskInfo.getResponse().isSecurityDomestic();
+
+
+ for (int index = cipherList.size() - 1; index >= 0; index--) {
+ CipherEntry cipher = (CipherEntry)(cipherList.elementAt(index));
+ cipher.getCipherCheckBox().addActionListener(this);
+ cipher.getTokenComboBox().addActionListener(this);
+ cipher.getCertComboBox().addActionListener(this);
+
+ String name = cipher.getCipherCheckBox().getText();
+ cipher.getCipherCheckBox().setActionCommand(name);
+ cipher.getTokenComboBox().setActionCommand(name);
+ cipher.getCertComboBox().setActionCommand(name);
+
+ cipher.getCipherCheckBox().addActionListener(actionListener);
+ cipher.getTokenComboBox().addActionListener(actionListener);
+ cipher.getCertComboBox().addActionListener(actionListener);
+
+ GridBagUtil.constrain(cPane, cipher.getCipherCheckBox(), 0,
+ ++y, 1, 1, 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0,
+ SuiConstants.COMPONENT_SPACE,
+ SuiConstants.COMPONENT_SPACE);
+ GridBagUtil.constrain(cPane, cipher.getTokenComboBox(), 1,
+ y, 1, 1, 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0,
+ SuiConstants.COMPONENT_SPACE,
+ SuiConstants.COMPONENT_SPACE);
+ GridBagUtil.constrain(cPane, cipher.getCertComboBox(), 2,
+ y, 1, 1, 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0,
+ SuiConstants.COMPONENT_SPACE,
+ SuiConstants.COMPONENT_SPACE);
+ }
+
+ GridBagUtil.constrain(cPane, bCipherPref, 1, ++y, 2, 1, 1.0,
+ 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0,
+ SuiConstants.COMPONENT_SPACE);
+
+
+ setEnableAll(false);
+ cipherPane.add("North", cPane);
+ cPane.validate();
+ cPane.repaint();
+ }
+
+ class wizardButtonActionListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ if (e.getActionCommand().equals("WIZARD")) {
+ //save the old setting
+ Vector oldEntry = getCipherList();
+
+ //lunch the wizard
+ KeyCertWizard wizard = new KeyCertWizard(_consoleInfo);
+
+ UtilConsoleGlobals.getActivatedFrame().setCursor(
+ new Cursor(Cursor.WAIT_CURSOR));
+
+ //update the cipher entries
+ //well it is inefficient, but unless more api
+ //is added to wizard it self we can't tell if
+ //a new cert is been added or not
+ updateEncryptionUI();
+
+ //restore the setting
+ for (int i = oldEntry.size() - 1; i >= 0; i--) {
+ Object cipher = oldEntry.elementAt(i);
+ setCipherSetting(isEnabled(cipher),
+ getCipherName(cipher), getToken(cipher),
+ getCertificateName(cipher));
+ }
+
+ setEnableAll(isEncryptionEnabled());
+
+ UtilConsoleGlobals.getActivatedFrame().setCursor(
+ new Cursor(Cursor.DEFAULT_CURSOR));
+
+ }
+ }
+ }
+
+
+ private void setEnableAll(boolean enable) {
+ int count = getCipherCount();
+ for (int i = 0; i < count; i++) {
+ ((CipherEntry) cipherList.elementAt(i)).setEnabledAll(enable);
+ }
+ bCipherPref.setEnabled(enable);
+ cipherTitle.setEnabled(enable);
+ tokenTitle.setEnabled(enable);
+ certTitle.setEnabled(enable);
+ invalidate();
+ repaint();
+ }
+
+ class CipherPaneToggleListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ if (e.getActionCommand().equals("ENABLED")) {
+ setEnableAll(on.isSelected());
+ EncryptionPane.this.actionPerformed(e);
+ validate();
+ repaint();
+ }
+ }
+ }
+
+ class ToggleBorder extends EtchedBorder {
+ private JComponent _switchPanel;
+ private int _switchAlign;
+
+ public ToggleBorder(JComponent sp, int align) {
+ _switchPanel = sp;
+ _switchAlign = align;
+ }
+
+ public void paintBorder(Component c, Graphics g, int x, int y,
+ int width, int height) {
+ Color save = g.getColor();
+
+ int top = y + (_switchPanel.getHeight() >> 1);
+ int new_height = height - top;
+
+ BorderUIResource.getEtchedBorderUIResource().paintBorder(c,
+ g, x, top, width, new_height);
+ }
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/GuideCertInstallPane.java b/base/console/src/com/netscape/admin/certsrv/security/GuideCertInstallPane.java
new file mode 100644
index 000000000..76580ecf0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/GuideCertInstallPane.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.admin.certsrv.security;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+class GuideCertInstallPane extends JPanel implements SuiConstants,
+IKeyCertPage {
+
+ public JPanel getPanel() {
+ return this;
+ }
+
+ public boolean pageShow(WizardObservable observable) {
+ return ((Boolean)(observable.get("installCert"))).booleanValue();
+ }
+
+ public boolean pageHide(WizardObservable observable) {
+ return true;
+ }
+
+
+ public GuideCertInstallPane() {
+ super();
+ setLayout(new GridBagLayout());
+
+ ResourceSet resource = KeyCertUtility.getKeyCertWizardResourceSet();
+
+ setBorder( new TitledBorder( new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE)),
+ resource.getString("GuideCertInstallPane", "title")));
+
+ int y = 0;
+
+
+ GridBagUtil.constrain(this,
+ new MultilineLabel(
+ resource.getString("GuideCertInstallPane", "explain")),
+ 0, ++y, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0,
+ SEPARATED_COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this, Box.createVerticalGlue(), 0, ++y,
+ 1, 1, 1.0, 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(this,
+ new JLabel(
+ resource.getString(null, "clickNextToContinue")), 0,
+ ++y, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ }
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ f.getContentPane().add("North", new GuideCertInstallPane());
+ f.setSize(400,400);
+ f.show();
+ }*/
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/GuideCertRequestPane.java b/base/console/src/com/netscape/admin/certsrv/security/GuideCertRequestPane.java
new file mode 100644
index 000000000..51ae0959e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/GuideCertRequestPane.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.admin.certsrv.security;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+class GuideCertRequestPane extends JPanel implements SuiConstants,
+IKeyCertPage {
+
+ public JPanel getPanel() {
+ return this;
+ }
+
+ public boolean pageShow(WizardObservable observable) {
+ return ((Boolean)(observable.get("requestCert"))).booleanValue();
+ }
+
+ public boolean pageHide(WizardObservable observable) {
+ return true;
+ }
+
+
+
+ public GuideCertRequestPane() {
+ super();
+ setLayout(new GridBagLayout());
+
+ ResourceSet resource = KeyCertUtility.getKeyCertWizardResourceSet();
+
+ setBorder( new TitledBorder( new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE)),
+ resource.getString("GuideCertRequestPane", "title")));
+
+ int y = 0;
+ GridBagUtil.constrain(this,
+ new MultilineLabel(
+ resource.getString("GuideCertRequestPane", "explain")),
+ 0, ++y, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0,
+ SEPARATED_COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this, Box.createVerticalGlue(), 0, ++y,
+ 1, 1, 1.0, 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(this,
+ new JLabel(
+ resource.getString(null, "clickNextToContinue")), 0,
+ ++y, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+ }
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ f.getContentPane().add("North", new GuideCertRequestPane());
+ f.setSize(400,400);
+ f.show();
+ }*/
+
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/security/GuideCreateTrustPane.java b/base/console/src/com/netscape/admin/certsrv/security/GuideCreateTrustPane.java
new file mode 100644
index 000000000..9eaf3607f
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/GuideCreateTrustPane.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.admin.certsrv.security;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+class GuideCreateTrustPane extends JPanel implements SuiConstants,
+IKeyCertPage {
+
+ public JPanel getPanel() {
+ return this;
+ }
+
+ public boolean pageShow(WizardObservable observable) {
+ return ((Boolean)(observable.get("createTrust"))).booleanValue();
+ }
+
+ public boolean pageHide(WizardObservable observable) {
+ return true;
+ }
+
+ public GuideCreateTrustPane() {
+ super();
+ setLayout(new GridBagLayout());
+
+ ResourceSet resource = KeyCertUtility.getKeyCertWizardResourceSet();
+
+ setBorder( new TitledBorder( new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE)),
+ resource.getString("GuideCreateTrustPane", "title")));
+
+ int y = 0;
+ GridBagUtil.constrain(this,
+ new MultilineLabel(
+ resource.getString("GuideCreateTrustPane", "explain")),
+ 0, ++y, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0,
+ SEPARATED_COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this, Box.createVerticalGlue(), 0, ++y,
+ 1, 1, 1.0, 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+
+ GridBagUtil.constrain(this,
+ new JLabel(
+ resource.getString(null, "clickNextToContinue")), 0,
+ ++y, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+ }
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ f.getContentPane().add("North", new GuideCreateTrustPane());
+ f.setSize(400,400);
+ f.show();
+ }*/
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/GuideIntroPane.java b/base/console/src/com/netscape/admin/certsrv/security/GuideIntroPane.java
new file mode 100644
index 000000000..30bc92200
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/GuideIntroPane.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.admin.certsrv.security;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+class GuideIntroPane extends JPanel implements SuiConstants, IKeyCertPage {
+
+ public JPanel getPanel() {
+ return this;
+ }
+
+ public boolean pageShow(WizardObservable observable) {
+ return true;
+ }
+
+ public boolean pageHide(WizardObservable observable) {
+ return true;
+ }
+
+ private void addNumberedComponent(JPanel p, int count, Component c) {
+ //JPanel entry = new JPanel();
+ //entry.setLayout(new GridBagLayout());
+
+ GridBagUtil.constrain(p,
+ Box.createRigidArea(
+ new Dimension(SEPARATED_COMPONENT_SPACE, 0)), 0,
+ count - 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.NONE, 0, 0, 0, 0);
+ GridBagUtil.constrain(p,
+ new JLabel(Integer.toString(count) + ". "), 1,
+ count - 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.NONE, 0, 0, 0, 0);
+ GridBagUtil.constrain(p, c, 2, count - 1, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, 0);
+ //p.add(entry);
+ }
+
+
+ public GuideIntroPane() {
+ super();
+ setLayout(new GridBagLayout());
+
+ int y = 0;
+
+
+ ResourceSet resource = KeyCertUtility.getKeyCertWizardResourceSet();
+
+
+ setBorder( new TitledBorder( new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE)),
+ resource.getString("GuideIntroPane", "title")));
+
+ GridBagUtil.constrain(this,
+ new MultilineLabel(
+ resource.getString("GuideIntroPane", "explain")), 0,
+ ++y, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0,
+ SEPARATED_COMPONENT_SPACE, 0);
+
+ JPanel p = new JPanel();
+ //p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
+ p.setLayout(new GridBagLayout());
+ int count = 0;
+
+ MultilineLabel _step1 = new MultilineLabel(
+ resource.getString("GuideIntroPane", "step1"));
+ MultilineLabel _step2 = new MultilineLabel(
+ resource.getString("GuideIntroPane", "step2"));
+ MultilineLabel _step3 = new MultilineLabel(
+ resource.getString("GuideIntroPane", "step3"));
+ addNumberedComponent(p, ++count, _step1);
+ addNumberedComponent(p, ++count, _step2);
+ addNumberedComponent(p, ++count, _step3);
+ GridBagUtil.constrain(this, p, 0, ++y, 1, 1, 0.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(this, Box.createVerticalGlue(), 0, ++y,
+ 1, 1, 1.0, 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(this,
+ new JLabel(
+ resource.getString(null, "clickNextToContinue")), 0,
+ ++y, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+ }
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ f.getContentPane().add(new GuideIntroPane());
+ //f.getContentPane().add(new MultilineLabel("adsf;klj a;sldkj ;alskj ;alsj f;alsdjf ;lakjfd ;asdjf ;aldsjf "));
+ f.setSize(400,400);
+ f.show();
+ }*/
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/IAbstractCipherSet.java b/base/console/src/com/netscape/admin/certsrv/security/IAbstractCipherSet.java
new file mode 100644
index 000000000..77ff5072b
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/IAbstractCipherSet.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.admin.certsrv.security;
+
+import java.util.Vector;
+
+/**
+ *
+ * The interface for abstract cipher preference
+ *
+ * @version 1.0 98/07/10
+ * @author <A HREF="mailto:shihcm@netscape.com">shihcm@netscape.com</A>
+ *
+ */
+public abstract interface IAbstractCipherSet {
+
+ /**
+ * Return cipher list
+ *
+ */
+ public Vector getCipherList();
+
+ /**
+ * Return title.
+ * For purpose of setting title if cipher is placed in a dialog or TitleBorder
+ *
+ */
+ public String getTitle();
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/ICipherConstants.java b/base/console/src/com/netscape/admin/certsrv/security/ICipherConstants.java
new file mode 100644
index 000000000..42a43c7d5
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/ICipherConstants.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.admin.certsrv.security;
+
+/**
+ * This interface contains all the internal string constants for each
+ * cipher encrytion methods.
+ *
+ * @version 1.0 98/07/10
+ * @author <A HREF="mailto:shihcm@netscape.com">shihcm@netscape.com</A>
+ *
+ */
+public interface ICipherConstants {
+ // export ssl2 cipher
+ /**SSL2 Export - RC4 with 40 bit encryption and MD5 message authentication*/
+ public final static String RC4EXPORT = "rc4export";
+ /**SSL2 Export - RC2 with 40 bit encryption and MD5 message authentication*/
+ public final static String RC2EXPORT = "rc2export";
+
+ // domestic ssl2 cipher
+ /**SSL2 Domestic - RC4 with 128 bit encryption and MD5 message authentication*/
+ public final static String RC4 = "rc4";
+ /**SSL2 Domestic - RC2 with 128 bit encryption and MD5 message authentication*/
+ public final static String RC2 = "rc2";
+ /**SSL2 Domestic - DES with 56 bit encryption and MD5 message authentication*/
+ public final static String DES = "des";
+ /**SSL2 Domestic - Triple DES with 168 bit encryption and MD5 message authentication*/
+ public final static String DES3 = "desede3";
+
+ // export ssl3 cipher
+ /**SSL3 Export - RC4 with 40 bit encryption and MD5 message authentication*/
+ public final static String RSA_RC4_40_MD5 = "rsa_rc4_40_md5";
+ /**SSL3 Export - RC2 with 40 bit encryption and MD5 message authentication*/
+ public final static String RSA_RC2_40_MD5 = "rsa_rc2_40_md5";
+ /**SSL3 Export - No encryption, only MD5 message authentication*/
+ public final static String RSA_NULL_MD5 = "rsa_null_md5";
+ /**SSL3 Export - TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA */
+ public final static String TLS_RSA_DES_SHA = "tls_rsa_export1024_with_des_cbc_sha";
+ /**SSL3 Export - TLS_RSA_EXPORT1024_WITH_RC4_56_SHA */
+ public final static String TLS_RSA_RC4_SHA = "tls_rsa_export1024_with_rc4_56_sha";
+
+ // domestic ssl3 cipher
+ /**SSL3 Domestic - DES with 56 bit encryption and SHA message authentication*/
+ public final static String RSA_DES_SHA = "rsa_des_sha";
+ /**SSL3 Domestic - RC4 with 128 bit encryption and MD5 message authentication*/
+ public final static String RSA_RC4_128_MD5 = "rsa_rc4_128_md5";
+ /**SSL3 Domestic - Triple DES with 168 bit encryption and SHA message authentication*/
+ public final static String RSA_3DES_SHA = "rsa_3des_sha";
+
+ // fortezza ciphers
+ /**SSL3 Domestic - Fortezza with 80 bit encryption and SHA message authentication */
+ public final static String FORTEZZA = "fortezza";
+ /**SSL3 Domestic - RC4 with 128 bit encryption and Fortezza/SHA message authentication */
+ public final static String FORTEZZA_RC4_128_SHA = "fortezza_rc4_128_sha";
+ /**SSL3 Domestic - No encryption, only Fortezza and SHA message authentication */
+ public final static String FORTEZZA_NULL = "fortezza_null";
+
+ // FIPS ciphers
+ public final static String RSA_FIPS_DES_SHA = "rsa_fips_des_sha";
+ public final static String RSA_FIPS_3DES_SHA = "rsa_fips_3des_sha";
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/IEncryptionPaneListener.java b/base/console/src/com/netscape/admin/certsrv/security/IEncryptionPaneListener.java
new file mode 100644
index 000000000..96d1b4077
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/IEncryptionPaneListener.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.admin.certsrv.security;
+
+/**
+ * Interface which specify the encryption panel listen method.
+ *
+ * @author <a href=mailto:dshihcm@netscape.com>Chih Ming Shih</a>
+ * @version 0.2 9/3/97
+ */
+
+public interface IEncryptionPaneListener {
+
+ /**
+ * called when cipher change state(on/off, token name change, cert name change)
+ *
+ * @param cipherEnbled enable cipher
+ * @param cipherName cipher name
+ * @param tokenName token name
+ * @param certName certificate name
+ */
+ public void cipherStateChanged(boolean cipherEnabled,
+ String cipherName, String tokenName, String certName);
+
+ /**
+ * called when ssl change state
+ *
+ * @param sslEnabled enable ssl
+ */
+ public void sslStateChanged(boolean sslEnabled);
+
+ /**
+ * called to invoke cipher preference dialog
+ *
+ */
+ public void showCipherPreferenceDialog();
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/IKeyCertPage.java b/base/console/src/com/netscape/admin/certsrv/security/IKeyCertPage.java
new file mode 100644
index 000000000..02ec98d9d
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/IKeyCertPage.java
@@ -0,0 +1,26 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.security;
+
+import javax.swing.JPanel;
+
+interface IKeyCertPage {
+ public abstract JPanel getPanel();
+ public abstract boolean pageShow(WizardObservable observable);
+ public abstract boolean pageHide(WizardObservable observable);
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/KeyCertTaskInfo.java b/base/console/src/com/netscape/admin/certsrv/security/KeyCertTaskInfo.java
new file mode 100644
index 000000000..9ffe7b2b5
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/KeyCertTaskInfo.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.admin.certsrv.security;
+
+import com.netscape.management.client.console.ConsoleInfo;
+import com.netscape.management.client.util.*;
+
+import javax.swing.*;
+
+import java.awt.event.*;
+import java.util.*;
+import java.io.*;
+import java.net.*;
+
+import netscape.ldap.*;
+
+/*-----IMPLEMENTATION-----*/
+//need to implementation timer...if server don't response in 30 sec then
+//we will pop up a message telling the user that server side cgi
+//has not response in a resonable amount of time...and should check
+//the server or call the cgi again.
+
+class KeyCertTaskInfo extends Hashtable {
+
+ //need to replace this by useful name later since the name will
+ //be map and no need to use real name.
+ //So a more descriptive name will probably be more useful.
+ public static final String SEC_LSALIAS = "ListAlias"; //"sec-lsalias";
+ public static final String SEC_GCRT = "CertRequest"; //""sec-gcrt";
+ public static final String SEC_ICRT = "CertInstall"; //"sec-icrt";
+ public static final String SEC_MGCRT = "CertListing"; //"sec-mgcrt"
+ public static final String SEC_ECRT = "GetCertInfo"; //"sec-ecrt";
+ public static final String SEC_TRUST = "CreateTrustDB"; //"sec-trust";
+ public static final String SSL_ON_OFF = "SSLActivate"; //"sec-activate"
+ public static final String SEC_LSTOKEN = "ListToken"; //"sec-lstoken"
+ public static final String SEC_LSMODULE = "ListModule"; //"sec-lsmodule"
+ public static final String SEC_MIGRATE = "KeyCertMigration"; //"sec-migrate"
+ public static final String SEC_ADDMOD = "AddModule"; //"sec-addmod"
+ public static final String SEC_CHANGEPW = "ChangeTrustPW"; //"sec-passwd"
+ public static final String SEC_MGCRL = "CRLListing"; //"sec-mgcrl"
+ public static final String SEC_ICRL = "CRLInstall"; //"sec-icrl"
+ public static final String SEC_ECRL = "GetCRLInfo"; //"sec-ecrl"
+
+ String _URL;
+ ConsoleInfo _consoleInfo;
+
+ //contains the last response from the cgi
+ Response _response = null;
+
+ private static ResourceSet resource = new ResourceSet("com.netscape.admin.certsrv.security.KeyCertTaskInfoResource");
+
+ //Call's the appropriate cgi and pass in the appropriate arguments
+ public Response exec(String operation) throws Exception {
+ String operationURL = _URL + operation;
+
+ Debug.println(operationURL + "\n"+this);
+
+ Comm kComm = null;
+
+ try {
+ kComm = new Comm(operationURL, this, true);
+
+ kComm.setAuth(_consoleInfo.getAuthenticationDN(),
+ _consoleInfo.getAuthenticationPassword());
+ kComm.run();
+ if (kComm.getError() instanceof Exception) {
+ if (kComm.getError() instanceof InterruptedIOException) {
+ throw (new Exception(
+ resource.getString("KeyCertTaskInfo", "timeoutError")));
+ } else if (kComm.getError() instanceof ConnectException) {
+ throw (new Exception(
+ resource.getString("KeyCertTaskInfo", "connectionError")));
+ } else if (kComm.getError() instanceof IOException) {
+ throw (new Exception(
+ resource.getString("KeyCertTaskInfo", "ioError")));
+ } else {
+ throw kComm.getError();
+ }
+ }
+ } catch (Exception e) {
+ throw (new Exception(resource.getString("KeyCertTaskInfo", "serverError")));
+ }
+ Debug.println(kComm.getData());
+ _response = new Response(kComm.getData());
+
+ return (_response);
+ }
+
+ public Response getResponse() {
+ return _response;
+ }
+
+ public KeyCertTaskInfo(ConsoleInfo consoleInfo) {
+ super();
+
+ _consoleInfo = consoleInfo;
+ _URL = consoleInfo.getAdminURL() + "admin-serv/tasks/configuration/";
+ }
+
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/security/KeyCertUtility.java b/base/console/src/com/netscape/admin/certsrv/security/KeyCertUtility.java
new file mode 100644
index 000000000..26032fc0f
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/KeyCertUtility.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.admin.certsrv.security;
+
+import com.netscape.management.nmclf.*;
+import com.netscape.management.client.console.ConsoleInfo;
+import com.netscape.management.client.util.*;
+import javax.swing.*;
+
+import java.awt.SystemColor;
+import java.util.*;
+import java.io.*;
+
+class KeyCertUtility {
+
+ static ResourceSet _resource = null;
+ public static ResourceSet getKeyCertWizardResourceSet() {
+ if (_resource == null) {
+ _resource = new ResourceSet("com.netscape.admin.certsrv.security.KeyCertWizardResource");
+ }
+
+ return _resource;
+ }
+
+ public static String createTokenName(ConsoleInfo consoleInfo) {
+ String tokenName = "";
+
+ tokenName = (String)(consoleInfo.get("SIE"));
+ if (tokenName == null) {
+ Debug.println("SIE entry was not set in the ConsoleInfo...");
+ try {
+ String currentDN = consoleInfo.getCurrentDN().toLowerCase();
+ tokenName = currentDN.substring(currentDN.indexOf("cn=") +
+ 3, currentDN.indexOf(","));
+ } catch (Exception e2) {
+ tokenName = "Unknow-Server";
+ }
+ }
+
+
+ return (tokenName);
+ }
+
+ //replace any occurance of 'val' in 'oldStr' with 'replacement'
+ public static String replace(String oldStr, String val,
+ String replacement) {
+ String output = new String(oldStr);
+
+ int index;
+
+ while ((index = output.indexOf(val)) != -1) {
+ output = output.substring(0, index) + replacement +
+ output.substring(index + val.length());
+ }
+
+ return output;
+ }
+
+ //a valid is a password that has more then 8 character and contain one or more
+ //none alphabetic character
+ public static boolean validPassword(String passwd,
+ String confirmPasswd, ConsoleInfo consoleInfo) {
+ boolean valid = true;
+ if (!(passwd.equals(confirmPasswd))) {
+ valid = false;
+ SuiOptionPane.showMessageDialog(consoleInfo.getFrame(),
+ getKeyCertWizardResourceSet().getString("KeyCertUtility",
+ "passwdMissMatch"));
+ ModalDialogUtil.sleep();
+ } else if (passwd.length() < 8) {
+ valid = false;
+ SuiOptionPane.showMessageDialog(consoleInfo.getFrame(),
+ getKeyCertWizardResourceSet().getString("KeyCertUtility",
+ "lessThen8Char"));
+ ModalDialogUtil.sleep();
+ } else {
+ boolean allChar = true;
+ int length = confirmPasswd.length();
+ for (int i = 0; i < length; i++) {
+ char ch = confirmPasswd.charAt(i);
+ if (!((ch >= 'A') && (ch <= 'Z')) &&
+ !((ch >= 'a') && (ch <= 'z'))) {
+ allChar = false;
+ break;
+ }
+ }
+ if (allChar) {
+ valid = false;
+ SuiOptionPane.showMessageDialog(consoleInfo.getFrame(),
+ getKeyCertWizardResourceSet().getString("KeyCertUtility",
+ "noNumericChar"));
+ ModalDialogUtil.sleep();
+ }
+ }
+
+ return valid;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/KeyCertWizard.java b/base/console/src/com/netscape/admin/certsrv/security/KeyCertWizard.java
new file mode 100644
index 000000000..017647488
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/KeyCertWizard.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.admin.certsrv.security;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.io.*;
+
+import javax.swing.*;
+
+import com.netscape.management.client.util.Help;
+import com.netscape.management.client.util.Debug;
+import com.netscape.management.client.console.ConsoleInfo;
+import netscape.ldap.*;
+
+import com.netscape.management.client.util.*;
+
+/**
+ *
+ * Key and certificate setup wizard
+ *
+ * @version 1.0 98/07/10
+ * @author <A HREF="mailto:shihcm@netscape.com">shihcm@netscape.com</A>
+ *
+ */
+public class KeyCertWizard {
+
+ final int FIRSTPAGE = 0;
+
+ WizardObservable wizardObservable;
+ IWizardControl owner;
+ Wizard wizard;
+
+ Vector pages;
+ int thisPage = 0;
+
+ ConsoleInfo _consoleInfo;
+
+ ResourceSet resource;
+ Help help;
+
+ void init(ConsoleInfo consoleInfo, String certName) {
+ UtilConsoleGlobals.getActivatedFrame().setCursor(
+ new Cursor(Cursor.WAIT_CURSOR));
+
+ resource = KeyCertUtility.getKeyCertWizardResourceSet();
+ help = new Help(resource);
+
+ wizardObservable = new WizardObservable(consoleInfo);
+ _consoleInfo = consoleInfo;
+
+ pages = new Vector();
+ pages.addElement(new GuideIntroPane());
+ //((IKeyCertPage)(pages.elementAt(thisPage))).pageShow(wizardObservable);
+ pages.addElement(new CertRequestSelectTokenPane());
+ pages.addElement(new GuideCreateTrustPane());
+ pages.addElement(new CreateTrustPane());
+ StatusPane statusPane = new StatusPane();
+ pages.addElement(statusPane);
+ pages.addElement(new GuideCertRequestPane());
+ pages.addElement(new CertRequestTypePane());
+ pages.addElement(new CertRequestInfoPane());
+ pages.addElement(new CertRequestEnterPasswordPane());
+ pages.addElement(statusPane);
+ pages.addElement(new CertRequestCertPane());
+ pages.addElement(new GuideCertInstallPane());
+ pages.addElement(new CertInstallTypePane());
+ pages.addElement(new CertInstallCertPane());
+ pages.addElement(statusPane);
+ pages.addElement(new CertInstallCertInfoPane());
+ pages.addElement(statusPane);
+
+ wizardObservable.put("statusPane", statusPane);
+
+ try {
+ wizard = new Wizard(null,
+ resource.getString("KeyCertWizard", "title"),
+ new WizardControlListener());
+ } catch (Exception e) {
+ wizard = new Wizard(null, "", new WizardControlListener());
+ }
+
+ if ((certName == null) || (certName.length() == 0)) {
+ wizardObservable.put("certName", "Server-Cert");
+ } else {
+ wizardObservable.put("certName", certName);
+ }
+
+ wizard.setMinimumSize(425, 425);
+ wizard.start();
+ }
+
+
+ /**
+ * Create a key and certificate setup wizard
+ *
+ * @param consoleInfo
+ *
+ */
+ public KeyCertWizard(ConsoleInfo consoleInfo, String certName) {
+ super();
+ init(consoleInfo, certName);
+ }
+
+ /**
+ * Create a key and certificate setup wizard
+ *
+ *
+ *
+ */
+ public KeyCertWizard(ConsoleInfo consoleInfo) {
+ super();
+ init(consoleInfo, null);
+ }
+
+
+ class WizardControlListener implements IWizardPageControl {
+ public JPanel getCurrentPage() {
+ try {
+ return ( (IKeyCertPage)(pages.elementAt(thisPage))).
+ getPanel();
+ } catch (Exception e) {
+ return new JPanel();
+ }
+ }
+
+ public JPanel getNextPage() {
+ IKeyCertPage ipage = (IKeyCertPage)(pages.elementAt(thisPage));
+ UtilConsoleGlobals.getActivatedFrame().setCursor(
+ new Cursor(Cursor.WAIT_CURSOR));
+ try {
+ if (!(ipage.pageHide(wizardObservable))) {
+ //check to see if we need to display some error message
+ //from cgi
+ } else {
+
+
+
+ while (true) {
+ ipage = (IKeyCertPage)(pages.elementAt(++thisPage));
+ if (ipage.pageShow(wizardObservable)) {
+ break;
+ }
+ }
+ if ((ipage instanceof StatusPane) &&
+ ((StatusPane) ipage).hasError()) {
+ owner.setCanGoForward(false);
+ }
+
+ //-2 because we don't want to count the last status page as one of the normal
+ //page. Also it's only managed by the certinfo page.
+ if (thisPage == (pages.size() - 2)) {
+ //owner.setIsLastPage(true);
+ owner.setCanGoForward(false);
+ } else if (thisPage == (pages.size() - 1)) {
+ owner.setCanGoForward(true);
+ owner.setIsLastPage(true);
+ }
+
+ owner.setCanGoBackword(true);
+
+ }
+ }
+ catch (Exception e) {
+ Debug.println(e + ":next page");
+ }
+
+ UtilConsoleGlobals.getActivatedFrame().setCursor(
+ new Cursor(Cursor.DEFAULT_CURSOR));
+ return ipage.getPanel();
+ }
+
+
+ public JPanel getPrevPage() {
+ IKeyCertPage page = null;
+ UtilConsoleGlobals.getActivatedFrame().setCursor(
+ new Cursor(Cursor.WAIT_CURSOR));
+ try {
+ while (true) {
+ page = (IKeyCertPage)(pages.elementAt(--thisPage));
+ if ((page != null) && page.pageShow(wizardObservable)) {
+ break;
+ }
+ }
+
+ owner.setIsLastPage(false);
+ owner.setCanGoForward(true);
+
+ if (thisPage == FIRSTPAGE) {
+ owner.setCanGoBackword(false);
+ }
+
+ if (thisPage == ((pages.size()) - 1)) {
+ owner.setIsLastPage(true);
+ } else if (thisPage == (pages.size() - 2)) {
+ owner.setCanGoForward(false);
+ }
+ } catch (Exception e) {
+ Debug.println(e + ":prev page");
+ }
+
+ UtilConsoleGlobals.getActivatedFrame().setCursor(
+ new Cursor(Cursor.DEFAULT_CURSOR));
+ return page.getPanel();
+ }
+
+
+ public void wizardCompleted() {
+ //do clean up
+ cleanUp();
+ }
+ public void wizardCanceled() {
+ //do clean up
+ cleanUp();
+ }
+
+ public void cleanUp() {
+ wizardObservable = null;
+ owner = null;
+ wizard = null;
+
+ pages = null;
+
+ _consoleInfo = null;
+
+ help = null;
+ }
+
+ public void helpInvoked() {
+ Object currentPage = pages.elementAt(thisPage);
+ if (currentPage instanceof GuideIntroPane) {
+ help.help("GuideIntroPane", "help");
+ } else if (currentPage instanceof CertRequestSelectTokenPane) {
+ help.help("SelectToken", "help");
+ } else if (currentPage instanceof GuideCreateTrustPane) {
+ help.help("GuideCreateTrustPane", "help");
+ } else if (currentPage instanceof CreateTrustPane) {
+ help.help("CreateTrustPane", "help");
+ } else if ((currentPage instanceof StatusPane) &&
+ (pages.elementAt(thisPage -
+ 1) instanceof CreateTrustPane)) {
+ help.help("CreateTrustPane", "help");
+ } else if (currentPage instanceof GuideCertRequestPane) {
+ help.help("GuideCertRequestPane", "help");
+ } else if (
+ currentPage instanceof CertRequestEnterPasswordPane) {
+ help.help("CertRequestEnterPasswordPane", "help");
+ } else if (currentPage instanceof CertRequestTypePane) {
+ help.help("CertRequestTypePane", "help");
+ } else if ((currentPage instanceof StatusPane) &&
+ (pages.elementAt(thisPage -
+ 1) instanceof CertRequestTypePane)) {
+ help.help("CertRequestTypePane", "help");
+ } else if (currentPage instanceof CertRequestInfoPane) {
+ help.help("CertRequestInfoPane", "help");
+ } else if (currentPage instanceof CertRequestCertPane) {
+ help.help("CertRequestCertPane", "help");
+ } else if (currentPage instanceof GuideCertInstallPane) {
+ help.help("GuideCertInstallPane", "help");
+ } else if (currentPage instanceof CertInstallTypePane) {
+ help.help("CertInstallTypePane", "help");
+ } else if (currentPage instanceof CertInstallCertPane) {
+ help.help("CertInstallCertPane", "help");
+ } else if ((currentPage instanceof StatusPane) &&
+ (pages.elementAt(thisPage -
+ 1) instanceof CertInstallCertPane)) {
+ help.help("CertInstallCertPane", "help");
+ } else if (currentPage instanceof CertInstallCertInfoPane) {
+ help.help("CertInstallCertInfoPane", "help");
+ } else if ((currentPage instanceof StatusPane) &&
+ (pages.elementAt(thisPage -
+ 1) instanceof CertInstallCertInfoPane)) {
+ help.help("CertInstallCertInfoPane", "help");
+ }
+ }
+
+ public void setOwner(IWizardControl wizardControl) {
+ wizardObservable.put("Wizard", wizardControl);
+
+ owner = wizardControl;
+ }
+ }
+
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ ConsoleInfo consoleInfo = null;
+ UtilConsoleGlobals.setActivatedFrame(f);
+ f.setSize(400,400);
+
+ try {
+ UIManager.setLookAndFeel("javax.swing.plaf.windows.WindowsLookAndFeel");
+ SwingUtilities.updateComponentTreeUI(f.getContentPane());
+ } catch (Exception e) {}
+
+ f.show();
+ String host = "buddha";
+ try {
+ consoleInfo = new ConsoleInfo(host+".mcom.com", 389, "admin", "admin", "o=airius.com");
+ LDAPConnection connection = new LDAPConnection();
+ consoleInfo.setAdminURL("https://"+host+".mcom.com:8081/");
+ consoleInfo.setBaseDN("cn=admin-serv-"+host+", ou=Netscape SuiteSpot, o=Airius.com");
+ consoleInfo.setCurrentDN("cn=admin-serv-"+host+", ou=Netscape SuiteSpot, o=Airius.com");
+ } catch (Exception e) {System.out.println(e);}
+
+
+ KeyCertWizard kc = new KeyCertWizard(consoleInfo);
+
+ // f.setIconImage((new RemoteImage("com/netscape/management/client/images/AdminServer.gif")).getImage());
+ //f.show();
+ }*/
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/Message.java b/base/console/src/com/netscape/admin/certsrv/security/Message.java
new file mode 100644
index 000000000..96f6bc9f7
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/Message.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.admin.certsrv.security;
+
+import java.util.*;
+import java.io.*;
+import com.netscape.management.client.util.Debug;
+
+class Index {
+ String _indexValue;
+ int _pos;
+
+ public Index(String indexValue, int pos) {
+ _indexValue = indexValue;
+ _pos = pos;
+ }
+
+ public String getIndexValue() {
+ return _indexValue;
+ }
+
+ public int getPos() {
+ return _pos;
+ }
+}
+class Message {
+
+ public final static int NMC_SUCCESS = 0;
+ public final static int NMC_FAILURE = 1;
+ public final static int NMC_WARNING = 2;
+ public final static int NMC_UNKNOWN = 3;
+
+ /* final static int FILE_ERROR = 0;
+ final static int MEMORY_ERROR = 1;
+ final static int SYSTEM_ERROR = 2;
+ final static int INCORRECT_USAGE = 3;
+ final static int ELEM_MISSING = 4;
+ final static int REGISTRY_DATABASE_ERROR = 5;
+ final static int NETWORK_ERROR = 6;
+ final static int GENERAL_FAILURE = 7;
+ final static int APP_ERROR = 8;
+ final static int WARNING = 9;*/
+
+ final static int DEFAULT_ERROR = 3;
+
+ final static String NMC_STATUS = "NMC_Status:";
+ final static String NMC_ERRTYPE = "NMC_ErrType:";
+ final static String NMC_ERRINFO = "NMC_ErrInfo:";
+ final static String NMC_ERRDETAIL = "NMC_ErrDetail:";
+ final static String NMC_DESCRIPTION = "NMC_Description:";
+ final static String NMC_EXTRA = "NMC_EXTRA:";
+
+ int NMC_Status = -1;
+ //int NMC_ErrType = -1;
+ String NMC_ErrType = "";
+ String NMC_ErrInfo = "";
+ String NMC_ErrDetail = "";
+ String NMC_Description = "";
+ String NMC_Extra = "";
+
+ public Message(String message) {
+ Vector indexes = new Vector();
+ int pos1 = message.indexOf(NMC_STATUS);
+ if (pos1 != -1) {
+ indexes.addElement(new Index(NMC_STATUS, pos1));
+ }
+
+ int pos2 = message.indexOf(NMC_ERRTYPE);
+ if (pos2 != -1) {
+ indexes.addElement(new Index(NMC_ERRTYPE, pos2));
+ }
+
+ int pos3 = message.indexOf(NMC_ERRINFO);
+ if (pos3 != -1) {
+ indexes.addElement(new Index(NMC_ERRINFO, pos3));
+ }
+
+ int pos4 = message.indexOf(NMC_ERRDETAIL);
+ if (pos4 != -1) {
+ indexes.addElement(new Index(NMC_ERRDETAIL, pos4));
+ }
+
+ int pos5 = message.indexOf(NMC_DESCRIPTION);
+ if (pos5 != -1) {
+ indexes.addElement(new Index(NMC_DESCRIPTION, pos5));
+ }
+
+ int extraIndex = message.indexOf('\n',
+ Math.max(
+ Math.max(Math.max(pos1, pos2), Math.max(pos3, pos4)),
+ pos5));
+ if (extraIndex != -1) {
+ NMC_Extra = message.substring(extraIndex + 1, message.length());
+
+ /* temp solution until Yu-Jen can think up another header schema */
+ NMC_Extra =
+ KeyCertUtility.replace(NMC_Extra, "Content-type: text/html", "");
+ }
+ indexes.addElement(new Index(NMC_EXTRA, extraIndex + 1));
+
+ int size = indexes.size();
+ for (int i = 0; i < size - 1; i++) {
+ Index beginIndex = (Index)(indexes.elementAt(i));
+ Index endIndex = (Index)(indexes.elementAt(i + 1));
+ if (beginIndex.getIndexValue().equals(NMC_STATUS)) {
+ String val = message.substring(beginIndex.getPos() +
+ NMC_STATUS.length(), endIndex.getPos());
+ NMC_Status = Integer.parseInt(val.trim());
+ } else if (
+ beginIndex.getIndexValue().equals(NMC_DESCRIPTION)) {
+ NMC_Description = message.substring(beginIndex.getPos() +
+ NMC_DESCRIPTION.length(), endIndex.getPos());
+ } else if (beginIndex.getIndexValue().equals(NMC_ERRTYPE)) {
+ NMC_ErrType = message.substring(beginIndex.getPos() +
+ NMC_ERRTYPE.length(), endIndex.getPos());
+ } else if (beginIndex.getIndexValue().equals(NMC_ERRINFO)) {
+ NMC_ErrInfo = message.substring(beginIndex.getPos() +
+ NMC_ERRINFO.length(), endIndex.getPos());
+ } else if (beginIndex.getIndexValue().equals(NMC_ERRDETAIL)) {
+ NMC_ErrDetail = message.substring(beginIndex.getPos() +
+ NMC_ERRDETAIL.length(), endIndex.getPos());
+ }
+ }
+
+ }
+
+ public int getStatus() {
+ return NMC_Status;
+ }
+
+ public boolean isSuccess() {
+ return (getStatus() == NMC_SUCCESS);
+ }
+ public boolean isFailure() {
+ return (getStatus() == NMC_FAILURE);
+ }
+ public boolean isWarning() {
+ return (getStatus() == NMC_WARNING);
+ }
+ public boolean isUnknown() {
+ return (getStatus() == NMC_UNKNOWN);
+ }
+
+ public String getStatusString() {
+ String status = "";
+ switch (NMC_Status) {
+ case NMC_SUCCESS:
+ status = "Success";
+ break;
+ case NMC_FAILURE:
+ status = "Failure";
+ break;
+ case NMC_WARNING:
+ status = "Warning";
+ break;
+ case NMC_UNKNOWN:
+ status = "Unknown";
+ break;
+ }
+ return status;
+ }
+
+ public String getErrorType() {
+ return NMC_ErrType;
+ }
+
+ /*int getErrorType(String errorType) {
+ int errVal = -1;
+ if (errorType.indexOf("FILE ERROR") != -1) {
+ errVal = FILE_ERROR;
+ } else if (errorType.indexOf("MEMORY ERROR") != -1) {
+ errVal = MEMORY_ERROR;
+ } else if (errorType.indexOf("SYSTEM ERROR") != -1) {
+ errVal = SYSTEM_ERROR;
+ } else if (errorType.indexOf("INCORRECT USAGE") != -1) {
+ errVal = INCORRECT_USAGE;
+ } else if (errorType.indexOf("ELEMENT MISSING") != -1) {
+ errVal = ELEM_MISSING;
+ } else if (errorType.indexOf("REGISTRY DATABASE ERROR") != -1) {
+ errVal = REGISTRY_DATABASE_ERROR;
+ } else if (errorType.indexOf("NETWORK ERROR") != -1) {
+ errVal = NETWORK_ERROR;
+ } else if (errorType.indexOf("GENERAL FAILURE") != -1) {
+ errVal = GENERAL_FAILURE;
+ } else if (errorType.indexOf("APPLICATION ERROR") != -1) {
+ errVal = APP_ERROR;
+ } else if (errorType.indexOf("WARNING") != -1) {
+ errVal = WARNING;
+ }
+ return errVal;
+ }
+
+ public String getErrorTypeString() {
+ String type = "";
+ switch (NMC_ErrType) {
+ case FILE_ERROR : type = "FILE ERROR"; break;
+ case MEMORY_ERROR : type = "MEMORY ERROR"; break;
+ case SYSTEM_ERROR : type = "SYSTEM ERROR"; break;
+ case INCORRECT_USAGE : type = "INCORRECT USAGE"; break;
+ case ELEM_MISSING : type = "ELEMENT MISSING"; break;
+ case REGISTRY_DATABASE_ERROR : type = "REGISTRY DATABASE ERROR"; break;
+ case NETWORK_ERROR : type = "NETWORK ERROR"; break;
+ case GENERAL_FAILURE : type = "GENERAL FAILURE"; break;
+ case APP_ERROR : type = "APPLICATION ERROR"; break;
+ case WARNING : type = "WARNING"; break;
+ default : type = "UNKNOW ERROR"; break;
+ }
+ return type;
+ }*/
+
+ public String getErrorInfo() {
+ return NMC_ErrInfo;
+ }
+
+ public String getErrorDetail() {
+ return NMC_ErrDetail;
+ }
+
+ public String getDescription() {
+ return NMC_Description;
+ }
+
+ public String getExtraMessage() {
+ return NMC_Extra;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/MessageDialog.java b/base/console/src/com/netscape/admin/certsrv/security/MessageDialog.java
new file mode 100644
index 000000000..d303de839
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/MessageDialog.java
@@ -0,0 +1,66 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.security;
+
+import javax.swing.*;
+
+import java.awt.SystemColor;
+import java.util.*;
+import com.netscape.management.client.util.UtilConsoleGlobals;
+import com.netscape.management.nmclf.*;
+
+class MessageDialog {
+
+ public static void rpt_success(Message message) {
+ SuiOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(),
+ message.getDescription());
+ }
+
+ public static void rpt_error(Message message) {
+ Object m[] = new Object[6];
+ m[0] = message.getErrorType();
+ m[2] = " ";
+ m[1] = message.getErrorInfo();
+ m[3] = message.getErrorDetail();
+ if (message.getExtraMessage().length() != 0) {
+ m[4] = " ";
+ m[5] = message.getExtraMessage();
+ }
+ SuiOptionPane.showMessageDialog((new JFrame()), m);
+ }
+
+ public static void messageDialog(Message cgiMessage) {
+ switch (cgiMessage.getStatus()) {
+ case Message.NMC_SUCCESS:
+ rpt_success(cgiMessage);
+ break;
+ case Message.NMC_FAILURE:
+ rpt_error(cgiMessage);
+ break;
+ case Message.NMC_WARNING:
+ rpt_error(cgiMessage);
+ break;
+ case Message.NMC_UNKNOWN:
+ rpt_success(cgiMessage);
+ break;
+ default :
+ break;
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/PKCS11AddModuleDialog.java b/base/console/src/com/netscape/admin/certsrv/security/PKCS11AddModuleDialog.java
new file mode 100644
index 000000000..7b5fe12a6
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/PKCS11AddModuleDialog.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.admin.certsrv.security;
+
+import com.netscape.management.client.console.ConsoleInfo;
+
+import javax.swing.*;
+import javax.swing.JFileChooser;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+
+class PKCS11AddModuleDialog extends AbstractDialog {
+
+ KeyCertTaskInfo taskInfo;
+
+ ResourceSet resource = new ResourceSet("com.netscape.admin.certsrv.security.PKCS11ManagementResource");
+
+ JRadioButton _isDLL;
+ JRadioButton _isJAR;
+ JTextField _dllname = new JTextField(10);
+ JTextField _filename = new JTextField(10);
+
+ boolean moduleAdded;
+
+ protected boolean isAdded() {
+ return moduleAdded;
+ }
+
+ protected void okInvoked() {
+ moduleAdded = false;
+ taskInfo.clear();
+
+ taskInfo.put("filename", _filename.getText());
+ taskInfo.put("format", _isDLL.isSelected() ? "dll" : "jar");
+ if (_isDLL.isSelected())
+ taskInfo.put("dllname", _dllname.getText());
+
+ Response response = null;
+ try {
+ response = taskInfo.exec(taskInfo.SEC_ADDMOD);
+ } catch (Exception e) {
+ SuiOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(), e.getMessage());
+ return;
+ }
+
+ try {
+ Message m = (Message)(response.getMessages().elementAt(0));
+ MessageDialog.messageDialog(m);
+ moduleAdded = m.isSuccess();
+ } catch (Exception ex) {}
+
+ if (((Message) response.getMessages().elementAt(0)).getStatus()
+ == Message.NMC_SUCCESS)
+ super.okInvoked();
+ }
+
+ protected void helpInvoked() {
+ Help help = new Help(resource);
+ help.help("PKCS11AddModuleDialog", "help");
+ }
+
+
+ /**
+ * Listen to changes (key strokes or change in text area or text field)
+ * then determain (call setEnableNextButton()) if wizard can proceed
+ */
+ class MyActionListener implements KeyListener, ActionListener {
+ public void keyTyped(KeyEvent e) {}
+ public void keyPressed(KeyEvent e) {}
+ public void keyReleased(KeyEvent e) {}
+ public void actionPerformed(ActionEvent e) {
+ if (e.getActionCommand().equals("ENABLED"))
+ _dllname.setEnabled(_isDLL.isSelected());
+ }
+ }
+
+ public PKCS11AddModuleDialog(ConsoleInfo consoleInfo) {
+ super(null, "", true, OK | CANCEL | HELP);
+
+ setTitle(resource.getString("PKCS11AddModuleDialog", "dialogTitle"));
+
+
+ taskInfo = new KeyCertTaskInfo(consoleInfo);
+
+ Container mainPane = getContentPane();
+ mainPane.setLayout(new GridBagLayout());
+
+ _isDLL = new JRadioButton(
+ resource.getString("PKCS11AddModuleDialog", "DLL"), true);
+ _isJAR = new JRadioButton(
+ resource.getString("PKCS11AddModuleDialog", "JAR"), false);
+
+ ButtonGroup buttonGroup = new ButtonGroup();
+ buttonGroup.add(_isDLL);
+ buttonGroup.add(_isJAR);
+
+ _isDLL.setActionCommand("ENABLED");
+ _isDLL.addActionListener(new MyActionListener());
+ _isJAR.setActionCommand("ENABLED");
+ _isJAR.addActionListener(new MyActionListener());
+
+ GridBagUtil.constrain(mainPane,
+ new JLabel( resource.getString("PKCS11AddModuleDialog",
+ "fileType")), 0, 0, 1, 1, 1.0, 1.0,
+ GridBagConstraints.NORTH,
+ GridBagConstraints.HORIZONTAL, 0, 0,
+ DIFFERENT_COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(mainPane, _isDLL, 0, 1, 1, 1, 1.0, 1.0,
+ GridBagConstraints.NORTH,
+ GridBagConstraints.HORIZONTAL, 0, 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(mainPane, _dllname, 1, 1, 1, 1, 1.0, 1.0,
+ GridBagConstraints.NORTH,
+ GridBagConstraints.HORIZONTAL, 0, 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(mainPane, _isJAR, 0, 2, 1, 1, 1.0, 1.0,
+ GridBagConstraints.NORTH,
+ GridBagConstraints.HORIZONTAL, 0, 0, COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(mainPane, Box.createVerticalGlue(), 0, 3,
+ 1, 1, 1.0, 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.HORIZONTAL, 0, 0, 0, 0);
+
+ GridBagUtil.constrain(mainPane,
+ new JLabel( resource.getString("PKCS11AddModuleDialog",
+ "fileName")), 0, 4, 1, 1, 1.0, 1.0,
+ GridBagConstraints.NORTH,
+ GridBagConstraints.HORIZONTAL, 0, 0,
+ DIFFERENT_COMPONENT_SPACE, 0);
+
+ GridBagUtil.constrain(mainPane, _filename, 0, 5, 1, 1, 1.0,
+ 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.HORIZONTAL, 0, 0, COMPONENT_SPACE, 0);
+
+ //getContentPane().add(mainPane);
+
+ pack();
+ setMinimumSize(getSize());
+ }
+
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/security/PKCS11ManagementDialog.java b/base/console/src/com/netscape/admin/certsrv/security/PKCS11ManagementDialog.java
new file mode 100644
index 000000000..277605fc8
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/PKCS11ManagementDialog.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.admin.certsrv.security;
+
+import com.netscape.management.client.console.ConsoleInfo;
+
+import javax.swing.*;
+import javax.swing.border.*;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+import netscape.ldap.*;
+
+/**
+ *
+ * Public-Key Cryptography Standards #11 (PKCS#11) Management dialog
+ *
+ * @version 1.0 98/07/10
+ * @author <A HREF="mailto:shihcm@netscape.com">shihcm@netscape.com</A>
+ *
+ */
+public class PKCS11ManagementDialog extends AbstractDialog {
+
+ KeyCertTaskInfo taskInfo;
+ ConsoleInfo _consoleInfo;
+ boolean setupComplete;
+
+ ResourceSet resource = new ResourceSet("com.netscape.admin.certsrv.security.PKCS11ManagementResource");
+
+ JPanel moduleList = new JPanel();
+ JButton bClose;
+ JButton bAdd;
+ JButton bHelp;
+
+ //since can't over load protected and I don't
+ //want the interface to show so...
+
+ private void privateHelpInvoked() {
+ Help help = new Help(resource);
+ help.help("PKCS11ManagementDialog", "help");
+ }
+
+ //since can't over load protected and I don't
+ //want the interface to show so...
+ private void privateCloseInvoked() {
+ super.okInvoked();
+ }
+
+ private JPanel getModuleListPanel() {
+ JPanel moduleListPanel = new JPanel();
+ moduleListPanel.setLayout(new GridBagLayout());
+
+ moduleListPanel.setBorder( new TitledBorder(
+ new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(SuiConstants.COMPONENT_SPACE,
+ SuiConstants.COMPONENT_SPACE, SuiConstants.COMPONENT_SPACE,
+ SuiConstants.COMPONENT_SPACE)),
+ resource.getString("PKCS11ManagementDialog", "title")));
+
+ JScrollPane scrollPane = new JScrollPane(moduleList,
+ JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+ JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ scrollPane.setBorder(
+ new CompoundBorder(UITools.createLoweredBorder(),
+ new EmptyBorder(VERT_COMPONENT_INSET,
+ HORIZ_COMPONENT_INSET, VERT_COMPONENT_INSET,
+ HORIZ_COMPONENT_INSET)));
+ GridBagUtil.constrain(moduleListPanel, scrollPane, 0, 0, 1, 1,
+ 1.0, 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+
+ return moduleListPanel;
+ }
+
+
+ private PKCS11AddModuleDialog addDialog;
+ private void addInvoked() {
+ addDialog.show();
+ if (addDialog.isAdded()) {
+ setupModules();
+ }
+ }
+
+ class PKCS11ActionListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ if (e.getActionCommand().equals("CLOSE")) {
+ privateCloseInvoked();
+ } else if (e.getActionCommand().equals("ADD")) {
+ addInvoked();
+
+ } else if (e.getActionCommand().equals("HELP")) {
+ privateHelpInvoked();
+ }
+ }
+ }
+
+ private JPanel getControlPanel() {
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 0, 0));
+ buttonPanel.setBorder(
+ new EmptyBorder(SuiConstants.VERT_WINDOW_INSET, 0, 0, 0));
+
+
+ PKCS11ActionListener listener = new PKCS11ActionListener();
+
+ bClose = JButtonFactory.createCloseButton(listener);
+ buttonPanel.add(bClose);
+ buttonPanel.add( Box.createRigidArea(
+ new Dimension(SuiConstants.COMPONENT_SPACE, 0)));
+
+ bAdd = JButtonFactory.create(
+ resource.getString("PKCS11ManagementDialog", "add"));
+ buttonPanel.add(bAdd);
+ bAdd.setActionCommand("ADD");
+ bAdd.addActionListener(listener);
+ buttonPanel.add( Box.createRigidArea(
+ new Dimension(SuiConstants.SEPARATED_COMPONENT_SPACE, 0)));
+
+ bHelp = JButtonFactory.createHelpButton(listener);
+ buttonPanel.add(bHelp);
+
+ JButtonFactory.resizeGroup(bHelp, bClose, bAdd);
+
+ return buttonPanel;
+ }
+
+
+ private void setupModules() {
+ taskInfo = new KeyCertTaskInfo(_consoleInfo);
+ taskInfo.put("sie", KeyCertUtility.createTokenName(_consoleInfo));
+ try {
+ taskInfo.exec(taskInfo.SEC_LSMODULE);
+ } catch (Exception e) {
+ SuiOptionPane.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(), e.getMessage());
+ setupComplete = false;
+ return;
+ }
+
+ setModal(true);
+
+ moduleList.removeAll();
+ Vector modules = taskInfo.getResponse().getModuleList();
+ for (int i = 0; i < modules.size(); i++) {
+ moduleList.add(new JLabel((String) modules.elementAt(i)));
+ }
+
+ moduleList.doLayout();
+ moduleList.repaint();
+ }
+
+ /**
+ * Create a PKCS#11 managemnt dialog
+ *
+ * @param consoleInfo Console information
+ *
+ */
+ public PKCS11ManagementDialog(ConsoleInfo consoleInfo) {
+ super(null, "", true, NO_BUTTONS);
+
+ setupComplete = true;
+
+ setTitle(resource.getString("PKCS11ManagementDialog", "dialogTitle"));
+
+
+ //Cursor oldCursor = UtilConsoleGlobals.getRootFrame().getCursor();
+ UtilConsoleGlobals.getActivatedFrame().setCursor(
+ new Cursor(Cursor.WAIT_CURSOR));
+
+ _consoleInfo = consoleInfo;
+ addDialog = new PKCS11AddModuleDialog(_consoleInfo);
+
+ JPanel mainPanel = new JPanel();
+ mainPanel.setLayout(new BorderLayout());
+ mainPanel.add("Center", getModuleListPanel());
+ mainPanel.add("South", getControlPanel());
+
+ getContentPane().add(mainPanel);
+
+ setMinimumSize(400, 275);
+ //setResizable(false);
+
+ moduleList.setLayout(new BoxLayout(moduleList, BoxLayout.Y_AXIS));
+
+ setupModules();
+
+ UtilConsoleGlobals.getActivatedFrame().setCursor(
+ new Cursor(Cursor.DEFAULT_CURSOR));
+
+ if (!setupComplete) {
+ return;
+ }
+
+ show();
+ }
+
+ /*public static void main(String arg[]) {
+ ConsoleInfo consoleInfo = null;
+ String host = "buddha";
+
+ JFrame f = new JFrame();
+ f.setSize(500,500);
+ f.show();
+ UtilConsoleGlobals.setRootFrame(f);
+
+ try {
+ UIManager.setLookAndFeel("javax.swing.plaf.windows.WindowsLookAndFeel");
+ SwingUtilities.updateComponentTreeUI(f.getContentPane());
+ } catch (Exception e) {}
+
+ try {
+ consoleInfo = new ConsoleInfo("awing.mcom.com", 3890, "admin", "admin", "o=mcom.com");
+ LDAPConnection connection = new LDAPConnection();
+ consoleInfo.setAdminURL("http://"+host+".mcom.com:8081/");
+ consoleInfo.setBaseDN("cn=admin-serv-"+host+", ou=Netscape SuiteSpot, o=Airius.com");
+ consoleInfo.setCurrentDN("cn=admin-serv-"+host+", ou=Netscape SuiteSpot, o=Airius.com");
+ } catch (Exception e) {System.out.println(e);}
+
+ PKCS11ManagementDialog d = new PKCS11ManagementDialog(consoleInfo);
+ }*/
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/security/Response.java b/base/console/src/com/netscape/admin/certsrv/security/Response.java
new file mode 100644
index 000000000..5d311d33b
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/Response.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.admin.certsrv.security;
+
+/**
+ *
+ * Parse the response that was sent back by the cgi
+ *
+ */
+
+import java.util.*;
+import java.io.*;
+import com.netscape.management.client.util.Debug;
+
+//this class need some optimization....
+
+class Response {
+
+ String _response;
+ String _cert = "";
+ Vector _messages = new Vector();
+ Vector _certList = null;
+ CertInfo _certInfo = null;
+ Hashtable _certInstInfo = null;
+
+ Hashtable _ssl2Preference = null;
+ Hashtable _ssl3Preference = null;
+
+ String startCert = "-----BEGIN NEW CERTIFICATE REQUEST-----";
+ String endCert = "-----END NEW CERTIFICATE REQUEST-----";
+ String startCertList = "-----BEGIN CERT LIST-----";
+ String endCertList = "-----END CERT LIST-----";
+ String startCertInfo = "-----BEGIN CERTIFICATE INFO-----";
+ String endCertInfo = "-----END CERTIFICATE INFO-----";
+ String startCRLCertInfo = "-----BEGIN CRL INFO-----";
+ String endCRLCertInfo = "-----END CRL INFO-----";
+
+ String startCertInstInfo = "-----BEGIN CERTIFICATE INSTALL INFO-----";
+ String endCertInstInfo = "-----END CERTIFICATE INSTALL INFO-----";
+ String startCRLCertInstInfo = "-----BEGIN CRL INSTALL INFO-----";
+ String endCRLCertInstInfo = "-----END CRL INSTALL INFO-----";
+
+ boolean _fCert = false, _fCertList = false, _fCertInfo = false,
+ _fCertInstInfo = false;
+ boolean _fsecurityDomestic = false, _fsecurityFortezza = false;
+
+ void parseCertificate(String response) {
+ if (response.indexOf(startCert) != -1) {
+ _cert = response.substring(response.indexOf(startCert),
+ response.indexOf(endCert) + endCert.length());
+ _fCert = true;
+ }
+ }
+
+ void parseCertificateList(String response) {
+ if (response.indexOf(startCertList) != -1) {
+ _certList = new Vector();
+
+ try {
+ BufferedReader stream =
+ new BufferedReader(new StringReader(response));
+ while (!(stream.readLine().equals(startCertList))) {
+ }
+
+ String line;
+ while (!((line = stream.readLine()).equals(endCertList))) {
+ //need to hack the string that return by the NS secutiry code.
+ //it assumes we are working with html
+ line = urlDecode(line);
+ StringTokenizer token =
+ new StringTokenizer(line, "=;\n", false);
+ Debug.print(line);
+
+ String certName = "", certType = "", certExpire = "";
+ try {
+ certName = token.nextToken();
+ certType = token.nextToken();
+ certExpire = token.nextToken();
+ } catch (NoSuchElementException noToken) { }
+
+ _certList.addElement(
+ new CertBasicInfo(certName, certType,
+ certExpire));
+ }
+ } catch (IOException e) {
+ Debug.println(e.getMessage());
+ }
+
+ _fCertList = true;
+ }
+
+ }
+
+ void parseCertificateInfo(String response) {
+ if ((response.indexOf(startCertInfo) != -1) ||
+ (response.indexOf(startCRLCertInfo) != -1)) {
+
+ try {
+ BufferedReader stream =
+ new BufferedReader(new StringReader(response));
+ String line;
+ while (! (((line =
+ stream.readLine()).equals(startCertInfo)) ||
+ (line.equals(startCRLCertInfo)))) {
+ }
+
+ String issuer = "", subject = "", serialNumber = "",
+ version = "", validFrom = "", validTo = "";
+ String fingerPrint = "", trustCert = "", certName = "",
+ certDeleted = "0", certTitle = "";
+
+ while (!((line = stream.readLine()).equals(endCertInfo))
+ && !(line.equals(endCRLCertInfo))) {
+
+ //need to hack the string that was returned by the NS secutiry code.
+ //it assumes we are working with html
+ line = urlDecode(line);
+ StringTokenizer token =
+ new StringTokenizer(line, "=\n", false);
+ Debug.print(line);
+
+
+ try {
+ String keyWord = token.nextToken();
+ if (keyWord.equals("ISSUER")) {
+ //have to hack again because of the stupid html in the data
+ issuer = KeyCertUtility.replace(
+ token.nextToken(), "<br>", "\n");
+ ;
+ } else if (keyWord.equals("SUBJECT")) {
+ subject = KeyCertUtility.replace(
+ token.nextToken(), "<br>", "\n");
+ ;
+ } else if (keyWord.equals("SERIALNUMBER")) {
+ serialNumber = token.nextToken();
+ } else if (keyWord.equals("VERSION")) {
+ version = token.nextToken();
+ } else if (keyWord.equals("NOTBEFORE")) {
+ validFrom = token.nextToken();
+ } else if (keyWord.equals("NOTAFTER")) {
+ validTo = token.nextToken();
+ } else if (keyWord.equals("FINGERPRINT")) {
+ fingerPrint = token.nextToken();
+ } else if (keyWord.equals("TRUSTED")) {
+ trustCert = token.nextToken();
+ } else if (keyWord.equals("CERTNAME")) {
+ certName = token.nextToken();
+ } else if (keyWord.equals("CERTDELETED")) {
+ certDeleted = token.nextToken();
+ } else if (keyWord.equals("CERTTITLE")) {
+ certTitle = token.nextToken();
+ }
+ } catch (NoSuchElementException noToken) {
+ Debug.print(noToken.getMessage());
+ }
+
+ }
+
+ _certInfo = new CertInfo(certName, issuer, subject,
+ serialNumber, version, validFrom, validTo,
+ fingerPrint, trustCert, certDeleted, certTitle);
+ } catch (IOException e) {
+ Debug.println(e.getMessage());
+ }
+
+ _fCertInfo = true;
+ }
+
+ }
+
+ void parseCertificateInstInfo(String response) {
+ if ((response.indexOf(startCertInstInfo) != -1) ||
+ (response.indexOf(startCRLCertInstInfo) != -1)) {
+ _certInstInfo = new Hashtable();
+
+ try {
+ BufferedReader stream =
+ new BufferedReader(new StringReader(response));
+ String line;
+
+ while (! (((line =
+ stream.readLine()).equals(startCertInstInfo))
+ || (line.equals(startCRLCertInstInfo)))) {
+ }
+
+
+ while (! ((line =
+ stream.readLine()).equals(endCertInstInfo)) &&
+ !(line.equals(endCRLCertInstInfo))) {
+ StringTokenizer token =
+ new StringTokenizer(line, "=\n", false);
+ Debug.print(line);
+ try {
+ String key = token.nextToken();
+ String val = token.nextToken();
+ _certInstInfo.put(key, val);
+ } catch (NoSuchElementException noToken) {
+ Debug.print(noToken.getMessage());
+ }
+ }
+ } catch (IOException e) {
+ Debug.println(e.getMessage());
+ }
+ _fCertInstInfo = true;
+ }
+ }
+
+ public static String urlDecode(String urlString) {
+ ByteArrayOutputStream out =
+ new ByteArrayOutputStream(urlString.length());
+
+ for (int i = 0; i < urlString.length(); i++) {
+ int c = (int) urlString.charAt(i);
+ if (c == '+') {
+ out.write(' ');
+ } else if (c == '%') {
+ int c1 = Character.digit(urlString.charAt(++i), 16);
+ int c2 = Character.digit(urlString.charAt(++i), 16);
+ out.write((char)(c1 * 16 + c2));
+ } else {
+ out.write(c);
+ }
+ }
+
+ return out.toString();
+ }
+
+ Vector familyList;
+ public Vector parseFamilyList(String response) {
+ familyList = new Vector();
+ _fsecurityFortezza = false;
+ _fsecurityDomestic = false;
+ try {
+ BufferedReader stream =
+ new BufferedReader(new StringReader(response));
+ String line = null;
+
+ while (!(((line = stream.readLine()).startsWith("NULL")))) {
+ String cipherName = line.substring(0, line.indexOf("="));
+
+ StringTokenizer st = new StringTokenizer(
+ line.substring(line.indexOf("=") + 1,
+ line.length()), ",\n", false);
+ Vector tokenList = new Vector();
+ Hashtable tokenCertList = new Hashtable();
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ tokenList.addElement(token);
+ tokenCertList.put(token, "");
+ }
+
+ Enumeration e = tokenList.elements();
+ while (e.hasMoreElements()) {
+ String token = (String)(e.nextElement());
+ line = stream.readLine();
+ String certListString = line.substring(
+ (token + "-certs=").length(), line.length());
+ StringTokenizer certNames =
+ new StringTokenizer(certListString, ",\n",
+ false);
+ Vector certList = new Vector();
+ while (certNames.hasMoreTokens()) {
+ certList.addElement(certNames.nextToken());
+ }
+ tokenCertList.put(token, certList);
+ }
+
+ familyList.addElement(
+ new CipherEntry(cipherName, tokenCertList));
+ }
+ if ((line = stream.readLine()).startsWith("security")) {
+ if (line.endsWith("fortezza")) {
+ _fsecurityFortezza = true;
+ _fsecurityDomestic = true;
+ }
+ if (line.endsWith("domestic")) {
+ _fsecurityDomestic = true;
+ }
+ }
+ } catch (Exception e) {
+ Debug.println("com.netscape.admin.certsrv.security.response:"+
+ e.toString());
+ }
+ return familyList;
+ }
+
+
+ Vector moduleList;
+ public Vector parseModuleList(String response) {
+
+ moduleList = new Vector();
+
+ try {
+ BufferedReader stream =
+ new BufferedReader(new StringReader(response));
+ String line = stream.readLine();
+
+ StringTokenizer st = new StringTokenizer(
+ line.substring(line.indexOf("=") + 1,
+ line.length()), ",\n", false);
+ while (st.hasMoreTokens())
+ moduleList.addElement(st.nextToken());
+ } catch (Exception e) {/*System.out.println(e);*/
+ }
+ return moduleList;
+ }
+
+
+ public Response(String response) {
+
+ //Debug.print(response);
+ if (response == null) {
+ return;
+ }
+
+ _response = response;
+
+ int beginIndex = 0, endIndex = 0;
+ while (true) {
+ beginIndex = response.indexOf(Message.NMC_STATUS, endIndex);
+ endIndex = response.indexOf(Message.NMC_STATUS,
+ beginIndex + Message.NMC_STATUS.length());
+ if ((endIndex == -1) && (beginIndex == -1)) {
+ break;
+ }
+ if (endIndex != -1) {
+ _messages.addElement( new Message( KeyCertUtility.replace(
+ response.substring(beginIndex, endIndex), "\r",
+ "")));
+ } else {
+ _messages.addElement( new Message( KeyCertUtility.replace(
+ response.substring(beginIndex,
+ response.length()), "\r", "")));
+ break;
+ }
+ }
+ }
+
+ public Vector getFamilyList() {
+ return parseFamilyList(_response);
+ }
+
+ public Vector getModuleList() {
+ return parseModuleList(_response);
+ }
+
+ public boolean isSecurityDomestic() {
+ return _fsecurityDomestic;
+ }
+
+ public boolean isSecurityFortezza() {
+ return _fsecurityFortezza;
+ }
+ public boolean hasCert() {
+ parseCertificate(_response);
+ return _fCert;
+ }
+ public boolean hasMessage() {
+ return (_messages.size() > 0);
+ }
+
+ public boolean hasCertList() {
+ parseCertificateList(_response);
+ return _fCertList;
+ }
+ public boolean hasCertInfo() {
+ parseCertificateInfo(_response);
+ return _fCertInfo;
+ }
+ public boolean hasCertInstInfo() {
+ parseCertificateInstInfo(_response);
+ return _fCertInstInfo;
+ }
+ public String getCert() {
+ return _fCert ? _cert : "";
+ }
+ public Vector getMessages() {
+ return _messages;
+ }
+ public Vector getCertList() {
+ return _fCertList ? _certList : (new Vector());
+ }
+ public CertInfo getCertInfo() {
+ return _certInfo;
+ }
+ public Hashtable getCertInstInfo() {
+ return _certInstInfo;
+ }
+ public String getServerResponse() {
+ return _response;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/SSL2CipherPreference.java b/base/console/src/com/netscape/admin/certsrv/security/SSL2CipherPreference.java
new file mode 100644
index 000000000..4625a11d5
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/SSL2CipherPreference.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.admin.certsrv.security;
+
+import javax.swing.*;
+
+/**
+ *
+ * Convenient class to construct SSL2 cipher preference toggle pane
+ *
+ * @version 1.0 98/07/10
+ * @author <A HREF="mailto:shihcm@netscape.com">shihcm@netscape.com</A>
+ *
+ *
+ * @see com.netscape.admin.certsrv.security.SSL2CipherSet
+ * @see com.netscape.admin.certsrv.security.ToggleCipherPreferencePane
+ * @see com.netscape.admin.certsrv.security.SSL3CipherPreference
+ */
+public class SSL2CipherPreference extends ToggleCipherPreferencePane implements ICipherConstants {
+
+ //private static final String sslVersion = "SSL 2.0 Ciphers";
+
+ /**
+ * Create a SSL2 cipher preference toggle pane
+ *
+ * @param isDomestic show domestic ssl2 ciphers if true
+ *
+ */
+ public SSL2CipherPreference(boolean isDomestic) {
+ super(new SSL2CipherSet(isDomestic), true);
+ }
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ f.getContentPane().add(new SSL2CipherPreference(true));
+ f.getContentPane().add(new AbstractCipherPreference(new SSL2CipherSet(true)));
+ f.pack();
+ f.show();
+ }*/
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/SSL2CipherSet.java b/base/console/src/com/netscape/admin/certsrv/security/SSL2CipherSet.java
new file mode 100644
index 000000000..0bdf7684f
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/SSL2CipherSet.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.admin.certsrv.security;
+
+import java.util.Vector;
+
+/**
+ *
+ * Convenient class to construct a SSL2 cipher list.
+ *
+ * @version 1.0 98/07/10
+ * @author <A HREF="mailto:shihcm@netscape.com">shihcm@netscape.com</A>
+ *
+ * @see com.netscape.admin.certsrv.security.SSL2CipherPreference
+ */
+public final class SSL2CipherSet implements ICipherConstants,
+IAbstractCipherSet {
+
+
+ Vector abstractCipherList = new Vector();
+ String title;
+
+ final boolean defaultOn = true;
+
+ /**
+ * Create a SSL2 cipher set
+ *
+ * @param isDomestic show domestic ssl2 ciphers if true
+ *
+ */
+ public SSL2CipherSet(boolean isDomestic) {
+ CipherResourceSet resource = new CipherResourceSet();
+
+ abstractCipherList.addElement( new AbstractCipher(
+ resource.getString("ssl2", "RC4EXPORT"), RC4EXPORT,
+ defaultOn));
+ abstractCipherList.addElement( new AbstractCipher(
+ resource.getString("ssl2", "RC2EXPORT"), RC2EXPORT,
+ defaultOn));
+ if (isDomestic) {
+ abstractCipherList.addElement( new AbstractCipher(
+ resource.getString("ssl2", "RC4"), RC4 , defaultOn));
+ abstractCipherList.addElement( new AbstractCipher(
+ resource.getString("ssl2", "RC2"), RC2 , defaultOn));
+ abstractCipherList.addElement( new AbstractCipher(
+ resource.getString("ssl2", "DES"), DES , defaultOn));
+ abstractCipherList.addElement( new AbstractCipher(
+ resource.getString("ssl2", "DES3"), DES3 , defaultOn));
+ }
+
+ title = resource.getString("ssl2", "CipherTitle");
+ }
+
+ /**
+ * Return title.
+ * For purpose of setting title if cipher is placed in a dialog or TitleBorder
+ *
+ */
+ public String getTitle() {
+ return title;
+ }
+
+ /**
+ * Return cipher list
+ *
+ */
+ public Vector getCipherList() {
+ return abstractCipherList;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/SSL3CipherPreference.java b/base/console/src/com/netscape/admin/certsrv/security/SSL3CipherPreference.java
new file mode 100644
index 000000000..e6773a27e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/SSL3CipherPreference.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.admin.certsrv.security;
+
+import javax.swing.*;
+
+/**
+ *
+ * Convenient class to construct SSL3 cipher preference toggle pane
+ *
+ * @version 1.0 98/07/10
+ * @author <A HREF="mailto:shihcm@netscape.com">shihcm@netscape.com</A>
+ *
+ *
+ * @see com.netscape.admin.certsrv.security.SSL3CipherSet
+ * @see com.netscape.admin.certsrv.security.ToggleCipherPreferencePane
+ * @see com.netscape.admin.certsrv.security.SSL2CipherPreference
+ */
+public class SSL3CipherPreference extends ToggleCipherPreferencePane implements ICipherConstants {
+
+
+ /**
+ * Create a SSL3 cipher preference toggle pane
+ *
+ * @param isDomestic show domestic ssl3 ciphers if true
+ * @param hasFortezza show fortezza ciphers if true
+ *
+ */
+ public SSL3CipherPreference(boolean isDomestic, boolean hasFortezza) {
+ super(new SSL3CipherSet(isDomestic, hasFortezza), true);
+ }
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ SSL3CipherPreference s = new SSL3CipherPreference(false, false);
+ f.getContentPane().add(s);
+ f.pack();
+ f.show();
+ String[] my = s.getCipherList();
+ for (int i=0; i <my.length; i++) {
+ System.out.println(my[i]);
+ }
+
+ System.out.println(s.isCipherEnabled(SSL3CipherPreference.FORTEZZA));
+ s.setCipherEnabled(SSL3CipherPreference.FORTEZZA, false);
+ System.out.println(s.isCipherEnabled(SSL3CipherPreference.FORTEZZA));
+ }*/
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/SSL3CipherSet.java b/base/console/src/com/netscape/admin/certsrv/security/SSL3CipherSet.java
new file mode 100644
index 000000000..417ce5d49
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/SSL3CipherSet.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.admin.certsrv.security;
+
+import java.util.Vector;
+
+/**
+ *
+ * Convenient class to construct a SSL3 cipher list.
+ *
+ * @version 1.0 98/07/10
+ * @author <A HREF="mailto:shihcm@netscape.com">shihcm@netscape.com</A>
+ *
+ * @see com.netscape.admin.certsrv.security.SSL3CipherPreference
+ */
+public final class SSL3CipherSet implements ICipherConstants,
+IAbstractCipherSet {
+
+ Vector abstractCipherList = new Vector();
+ String title;
+
+ final boolean defaultOn = true;
+
+ /**
+ * Create a SSL2 cipher set
+ *
+ * @param isDomestic show domestic ssl3 ciphers if true
+ * @param hasFortezza show fortezza ciphers if true
+ *
+ */
+ public SSL3CipherSet(boolean isDomestic, boolean hasFortezza) {
+ CipherResourceSet resource = new CipherResourceSet();
+
+ abstractCipherList.addElement( new AbstractCipher(
+ resource.getString("ssl3", "RSA_RC4_40_MD5"),
+ RSA_RC4_40_MD5 , defaultOn));
+ abstractCipherList.addElement( new AbstractCipher(
+ resource.getString("ssl3", "RSA_RC2_40_MD5"),
+ RSA_RC2_40_MD5 , defaultOn));
+
+ abstractCipherList.addElement( new AbstractCipher(
+ resource.getString("ssl3", "TLS_RSA_DES_SHA"),
+ TLS_RSA_DES_SHA, defaultOn));
+
+ abstractCipherList.addElement( new AbstractCipher(
+ resource.getString("ssl3", "TLS_RSA_RC4_SHA"),
+ TLS_RSA_RC4_SHA, defaultOn));
+
+ if (isDomestic) {
+ abstractCipherList.addElement( new AbstractCipher(
+ resource.getString("ssl3", "RSA_DES_SHA"),
+ RSA_DES_SHA , defaultOn));
+ abstractCipherList.addElement( new AbstractCipher(
+ resource.getString("ssl3", "RSA_RC4_128_MD5"),
+ RSA_RC4_128_MD5 , defaultOn));
+ abstractCipherList.addElement( new AbstractCipher(
+ resource.getString("ssl3", "RSA_3DES_SHA"),
+ RSA_3DES_SHA , defaultOn));
+
+ abstractCipherList.addElement( new AbstractCipher(
+ resource.getString("ssl3", "RSA_FIPS_DES_SHA"),
+ RSA_FIPS_DES_SHA , !defaultOn));
+ abstractCipherList.addElement( new AbstractCipher(
+ resource.getString("ssl3", "RSA_FIPS_3DES_SHA"),
+ RSA_FIPS_3DES_SHA , !defaultOn));
+
+ if (hasFortezza) {
+ abstractCipherList.addElement( new AbstractCipher(
+ resource.getString("ssl3", "FORTEZZA"),
+ FORTEZZA , defaultOn));
+ abstractCipherList.addElement( new AbstractCipher(
+ resource.getString("ssl3", "FORTEZZA_RC4_128_SHA"),
+ FORTEZZA_RC4_128_SHA, defaultOn));
+ abstractCipherList.addElement( new AbstractCipher(
+ resource.getString("ssl3", "FORTEZZA_NULL"),
+ FORTEZZA_NULL , !defaultOn));
+ }
+
+ }
+
+ abstractCipherList.addElement( new AbstractCipher(
+ resource.getString("ssl3", "RSA_NULL_MD5"),
+ RSA_NULL_MD5 , !defaultOn));
+
+ title = resource.getString("ssl3", "CipherTitle");
+ }
+
+ /**
+ * Return title.
+ * For purpose of setting title if cipher is placed in a dialog or TitleBorder
+ *
+ */
+ public String getTitle() {
+ return title;
+ }
+
+ /**
+ * Return cipher list
+ *
+ */
+ public Vector getCipherList() {
+ return abstractCipherList;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/StatusPane.java b/base/console/src/com/netscape/admin/certsrv/security/StatusPane.java
new file mode 100644
index 000000000..9eb5b1ba2
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/StatusPane.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.admin.certsrv.security;
+
+import javax.swing.*;
+import javax.swing.border.*;
+
+import java.util.*;
+import java.awt.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.management.nmclf.*;
+
+class StatusPane extends JPanel implements IKeyCertPage, SuiConstants {
+
+ boolean show = false;
+ boolean error = false;
+
+ MultilineLabel statusText = new MultilineLabel();
+
+ public JPanel getPanel() {
+ show = false;
+ return this;
+ }
+
+ public boolean pageShow(WizardObservable observable) {
+ return show;
+ }
+
+ public boolean pageHide(WizardObservable observable) {
+ show = false;
+ error = false;
+ return true;
+ }
+
+ public void setShow(boolean show) {
+ this.show = show;
+ }
+
+
+ public boolean hasError() {
+ return error;
+ }
+
+ public void setMessage(Vector messages) {
+ String status = "";
+ int nMessage = messages.size();
+ for (int i = 0; i < nMessage; i++) {
+ if (getMessage((Message)(messages.elementAt(i))).length() !=
+ 0) {
+ status += getMessage((Message)(messages.elementAt(i))) +
+ "\n\n";
+ }
+ }
+
+ //((LABELeditor)(statusPane.getCtrlByName("statusText"))).setValueS(status);
+ statusText.setText(status);
+
+ }
+
+ public void setMessage(String message) {
+ statusText.setText(message);
+ }
+
+ public void appendMessage(String message) {
+ StringBuffer sb = new StringBuffer(statusText.getText().trim());
+ sb.append(message);
+ statusText.setText(sb.toString());
+ }
+
+
+ String getMessage(Message message) {
+ String status = "";
+
+ if (message.getStatus() == message.NMC_SUCCESS) {
+ status = message.getDescription() + message.getExtraMessage();
+ } else if (message.getStatus() == message.NMC_FAILURE) {
+ status += message.getErrorType() + "\n";
+ status += message.getErrorInfo() + "\n";
+ status += message.getErrorDetail();
+ error = true;
+ } else if (message.getStatus() == message.NMC_WARNING) {
+ status += message.getDescription();
+ } else if (message.getStatus() == message.NMC_UNKNOWN) {
+ status += message.getDescription();
+ error = true;
+ }
+
+ return status;
+ }
+
+ public void setMessage(Message message) {
+ //((LABELeditor)(statusPane.getCtrlByName("statusText"))).setValueS(getMessage(message));
+ statusText.setText(getMessage(message));
+ }
+
+ public void setLastPage(boolean isLastpage) {
+ if (isLastpage) {
+ next.setText("");
+ } else {
+ next.setText(resource.getString(null, "clickNextToContinue"));
+ }
+ }
+
+
+ ResourceSet resource = KeyCertUtility.getKeyCertWizardResourceSet();
+ JLabel next = new JLabel();
+
+ public StatusPane() {
+ //set up layout here;
+ super();
+
+ //setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+ setLayout(new GridBagLayout());
+
+ setBorder( new TitledBorder( new CompoundBorder(new EtchedBorder(),
+ new EmptyBorder(COMPONENT_SPACE, COMPONENT_SPACE,
+ COMPONENT_SPACE, COMPONENT_SPACE)),
+ resource.getString("StatusPane", "title")));
+
+ GridBagUtil.constrain(this, statusText, 0, 0, 1, 1, 1.0, 1.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, 0, 0);
+
+ GridBagUtil.constrain(this, Box.createVerticalGlue(), 0, 1, 1,
+ 1, 1.0, 1.0, GridBagConstraints.NORTH,
+ GridBagConstraints.BOTH, 0, 0, 0, 0);
+
+ next.setText(resource.getString(null, "clickNextToContinue"));
+
+ GridBagUtil.constrain(this, next, 0, 2, 1, 1, 1.0, 0.0,
+ GridBagConstraints.NORTH, GridBagConstraints.BOTH, 0,
+ 0, 0, 0);
+
+
+ //add(statusText);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/security/ToggleCipherPreferencePane.java b/base/console/src/com/netscape/admin/certsrv/security/ToggleCipherPreferencePane.java
new file mode 100644
index 000000000..eca1e0b02
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/ToggleCipherPreferencePane.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.admin.certsrv.security;
+
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.plaf.*;
+import java.awt.event.*;
+import java.awt.*;
+
+import com.netscape.management.nmclf.*;
+
+/**
+ *
+ * Convenient class to create a toggle cipher preference pane
+ *
+ * @version 1.0 98/07/10
+ * @author <A HREF="mailto:shihcm@netscape.com">shihcm@netscape.com</A>
+ *
+ * @see com.netscape.admin.certsrv.security.SSL2CipherPreference
+ * @see com.netscape.admin.certsrv.security.SSL3CipherPreference
+ */
+public class ToggleCipherPreferencePane extends AbstractCipherPreference implements ICipherConstants {
+ private JCheckBox on;
+ private JPanel top = new JPanel();
+ boolean _ismodified;
+
+ boolean oldValue;
+
+ /**
+ * Create a toggle cipher preference pane
+ *
+ * @param cipherSet Interface to obtain cipher preference list, and title for toggle pane
+ *
+ */
+ public ToggleCipherPreferencePane(IAbstractCipherSet cipherSet) {
+ this(cipherSet, true);
+ }
+
+ /**
+ * Create a toggle cipher preference pane
+ *
+ *
+ * @param cipherSet Interface to obtain cipher preference list, and title for toggle pane
+ * @param enabled enable/disable toggle pane
+ *
+ */
+ public ToggleCipherPreferencePane(IAbstractCipherSet cipherSet,
+ boolean enabled) {
+ oldValue = enabled;
+
+ on = new JCheckBox(cipherSet.getTitle(), enabled);
+ on.setActionCommand("ENABLED");
+ on.addActionListener(new actionListener());
+
+ top.setAlignmentX(0.0f);
+ top.setLayout(new BoxLayout(top, BoxLayout.Y_AXIS));
+ top.add(on);
+ setBorder( new CompoundBorder(
+ new ToggleBorder(top, SwingConstants.TOP),
+ new EmptyBorder(0, SuiConstants.COMPONENT_SPACE,
+ SuiConstants.COMPONENT_SPACE, 0)));
+ add(top);
+
+ initialize(cipherSet);
+
+ add(Box.createHorizontalGlue());
+ }
+
+ class actionListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ if (e.getActionCommand().equals("ENABLED")) {
+ _ismodified = true;
+ setEnableAll(on.isSelected());
+ }
+ }
+ }
+
+
+ /**
+ * Enable or disable toggle pane
+ *
+ * @param enable
+ *
+ */
+ public void setEnabled(boolean enable) {
+ on.setSelected(enable);
+ super.setEnableAll(enable);
+ }
+
+ /**
+ * Check weather toggle pane is enabled
+ *
+ */
+ public boolean isEnabled() {
+ return on.isSelected();
+ }
+
+
+ //steal from Mac's layout manager
+ class ToggleBorder extends EtchedBorder {
+ private JComponent _switchPanel;
+ private int _switchAlign;
+
+ public ToggleBorder(JComponent sp, int align) {
+ _switchPanel = sp;
+ _switchAlign = align;
+ }
+
+ public void paintBorder(Component c, Graphics g, int x, int y,
+ int width, int height) {
+ Color save = g.getColor();
+
+ int top = y + (_switchPanel.getHeight() >> 1);
+ int new_height = height - top;
+
+ BorderUIResource.getEtchedBorderUIResource().paintBorder(c,
+ g, x, top, width, new_height);
+ }
+ }
+
+ /**
+ * Check weather any ciphers has been modified
+ *
+ * @see #isModified
+ * @see #setSaved
+ *
+ */
+ public boolean isModified() {
+ return (_ismodified | super.isModified());
+ }
+
+ /**
+ * Reset all changes since last save
+ *
+ * @see #setSaved
+ */
+ public void reset() {
+ setEnabled(oldValue);
+ _ismodified = false;
+ super.reset();
+ }
+
+
+ /**
+ * Set the state to save.
+ *
+ * @see #reset
+ */
+ public void setSaved() {
+ oldValue = isEnabled();
+ _ismodified = false;
+ super.setSaved();
+ }
+
+ /*public static void main(String arg[]) {
+ JFrame f = new JFrame();
+ f.getContentPane().add(new ToggleCipherPreferencePane(new SSL3CipherSet(true, true)));
+ f.pack();
+ f.show();
+ }*/
+
+}
+
+
+
diff --git a/base/console/src/com/netscape/admin/certsrv/security/WizardObservable.java b/base/console/src/com/netscape/admin/certsrv/security/WizardObservable.java
new file mode 100644
index 000000000..ca36816af
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/security/WizardObservable.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.admin.certsrv.security;
+
+
+import com.netscape.management.client.console.ConsoleInfo;
+
+
+import javax.swing.*;
+import java.awt.event.*;
+import java.util.*;
+
+class WizardObservable extends Hashtable {
+
+
+ KeyCertTaskInfo taskInfo;
+ ConsoleInfo consoleInfo;
+
+ public WizardObservable(ConsoleInfo consoleInfo) {
+ taskInfo = new KeyCertTaskInfo(consoleInfo);
+ this.consoleInfo = consoleInfo;
+ }
+
+ public KeyCertTaskInfo getTaskInfo() {
+ return taskInfo;
+ }
+
+ public ConsoleInfo getConsoleInfo() {
+ return consoleInfo;
+ }
+
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/status/AccessLogDataModel.java b/base/console/src/com/netscape/admin/certsrv/status/AccessLogDataModel.java
new file mode 100644
index 000000000..c0edc5270
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/status/AccessLogDataModel.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.admin.certsrv.status;
+
+/**
+ * AccessLogDataModel
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.status
+ */
+public class AccessLogDataModel extends LogDataModel {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ //protected String[] mColumns = {DATE, TIME, DETAILS}; //overwrites the default
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public AccessLogDataModel() {
+ //XXX SET CORRECT PARSER HERE
+ super();
+ }
+
+ //parser here
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/status/AuditLogDataModel.java b/base/console/src/com/netscape/admin/certsrv/status/AuditLogDataModel.java
new file mode 100644
index 000000000..39bdffc0e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/status/AuditLogDataModel.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.admin.certsrv.status;
+
+/**
+ * AuditLogDataModel
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.status
+ */
+public class AuditLogDataModel extends LogDataModel {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ //protected String[] mColumns = {DATE, TIME, DETAILS}; //overwrites the default
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public AuditLogDataModel() {
+ //XXX SET CORRECT PARSER HERE
+ super();
+ }
+
+ //parser here
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/status/CMSLogPanel.java b/base/console/src/com/netscape/admin/certsrv/status/CMSLogPanel.java
new file mode 100644
index 000000000..5329b1148
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/status/CMSLogPanel.java
@@ -0,0 +1,360 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.status;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.table.*;
+import javax.swing.border.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Log Panel to be displayed at the right hand side
+ * <pre>
+ * Top Panel with filter input:
+ * Number of entries: default 25
+ * Source: default all
+ * Log Level: default warning
+ * </pre>
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.status
+ */
+public abstract class CMSLogPanel extends CMSBasePanel
+ implements IResourceSelectionListener, IRefreshTab, IRefreshTabPanel, MouseListener
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static String PANELNAME = "LOGCONTENT";
+
+ public static int DEFAULT_LOG_ENTRY = 25;
+
+ protected JPanel mFilterPanel, mListPanel, mActionPanel; //panels
+ protected boolean mInit = false; // true if this panel is initialized
+ protected CMSBaseResourceModel mModel;
+ protected LogDataModel mDataModel; //table data model
+
+ protected JScrollPane mScrollPane;
+ protected JTable mTable; //table
+ protected JButton mView, mRefresh, mHelp; //action buttons
+ protected JTextField mNoRecord;
+ protected JComboBox mSource, mLevel, mFile;
+ protected String mHelpToken;
+ protected LogEntryViewDialog mViewer;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSLogPanel( CMSBaseResourceModel model,LogDataModel dataModel) {
+ super(PANELNAME);
+ model.addIResourceSelectionListener(this);
+ mModel = model;
+ mDataModel = dataModel;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Actual construction of the panel
+ */
+ public void init() {
+ setLayout(new BorderLayout());
+
+ //======== filter panel ======================
+ mFilterPanel = createFilterPanel();
+ add("North",mFilterPanel);
+
+ //======== list panel ========================
+ mListPanel = createListPanel();
+ mListPanel.setBorder(new EmptyBorder(SEPARATED_COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE - COMPONENT_SPACE,
+ COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE - COMPONENT_SPACE));
+ add("Center",mListPanel);
+
+ //====== action panel ===========================
+ mActionPanel = createActionPanel();
+ add("South",mActionPanel);
+ updateArchive();
+ refresh();
+ }
+
+ //== IResourceListener ===
+
+ public void select(IResourceObject parent, Object viewInstance) {
+ if (!mInit) {
+ init();
+ mInit = true;
+ }
+
+ //refresh the screen
+ invalidate();
+ validate();
+ repaint(1);
+ }
+
+ public boolean unselect(IResourceObject parent, Object viewInstance) {
+ return true;
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mRefresh)) {
+ Debug.println("AccessLogPanel: Refresh Log");
+ refresh();
+ }else if (e.getSource().equals(mView)) {
+ if (mDataModel.getRowCount() == 0) {
+ refresh();
+ } else {
+ viewDetail();
+ }
+ }else if (e.getSource().equals(mHelp)) {
+ CMSAdminUtil.help(mHelpToken);
+ } else if (e.getSource().equals(mLevel) || e.getSource().equals(mSource)
+ || e.getSource().equals(mFile)) {
+ Debug.println("AccessLogPanel: Changed Log Level or Source or File");
+ refresh();
+ }
+ }
+
+ public CMSBasePanel getSelectedTab() {
+ return this;
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ //Debug.println("CertRepositoryPanel: mouseClicked() -"+e.toString());
+
+ //we track the double click action on the table entry - View op
+ if(e.getClickCount() == 2) {
+ //Debug.println("View Detail");
+ viewDetail();
+ }
+ }
+
+ public void mousePressed(MouseEvent e) { }
+ public void mouseReleased(MouseEvent e) { }
+ public void mouseEntered(MouseEvent e) { }
+ public void mouseExited(MouseEvent e) { }
+
+ /**
+ * refresh the table data
+ */
+ public void refresh() {
+ mDataModel.removeAllRows();
+ Debug.println("CMSLogPanel: refresh()");
+
+ update();
+
+ mTable.invalidate();
+ mTable.validate();
+ mTable.repaint(1);
+ mScrollPane.invalidate();
+ mScrollPane.validate();
+ mScrollPane.repaint(1);
+ if (mDataModel.getRowCount() > 0) {
+ mTable.setRowSelectionInterval(0,0);
+ }
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+
+ /**
+ * View the log entry in a dialog box
+ * (no assumption of validity)
+ */
+ protected void viewDetail() {
+ //check item selected
+ if (mTable.getSelectedRow()>= 0) {
+ if (mViewer == null)
+ mViewer = new LogEntryViewDialog(mModel.getFrame());
+ mViewer.showDialog(
+ (String)mDataModel.getValueAt(mTable.getSelectedRow(),0),
+ (String)mDataModel.getValueAt(mTable.getSelectedRow(),1),
+ (String)mDataModel.getValueAt(mTable.getSelectedRow(),2),
+ (String)mDataModel.getValueAt(mTable.getSelectedRow(),3),
+ ((JLabel)mDataModel.getValueAt(mTable.getSelectedRow(),4)).getText());
+ }
+ }
+
+
+ /**
+ * create action button panel
+ */
+ protected JPanel createActionPanel() {
+ //actionlister to this object
+ mView = makeJButton("VIEW");
+ mRefresh = makeJButton("REFRESH");
+ mHelp = makeJButton("HELP");
+ //JButton[] buttons = { mView,mRefresh,mHelp };
+ JButton[] buttons = { mView,mRefresh };
+ return makeJButtonPanel(buttons,true,true);
+ }
+
+ /**
+ * create log listing panel
+ */
+ protected JPanel createListPanel() {
+ mListPanel = new JPanel();
+ mListPanel.setLayout(new BorderLayout());
+
+ //center table
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
+ mTable.setAutoscrolls(true);
+ mTable.addMouseListener(this);
+ //setColumnWidth(mTable);
+ mTable.setAutoResizeMode(mTable.AUTO_RESIZE_OFF);
+ setColumnWidth(mTable);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ mListPanel.add("Center",mScrollPane);
+ setLabelCellRenderer(mTable,4);
+ mScrollPane.setBackground(Color.white);
+ return mListPanel;
+ }
+
+
+ protected void setColumnWidth(JTable table) {
+ int i = table.getColumnModel().getColumnCount();
+ for (int x=0; x< i-1; x++) {
+ TableColumn col = table.getColumnModel().getColumn(x);
+ col.setMinWidth(50);
+ col.setResizable( true );
+ }
+ TableColumn col = table.getColumnModel().getColumn(i-1);
+ col.setMinWidth(400);
+ col.setResizable( true );
+ }
+
+ /**
+ * create filter criteria panel
+ */
+ protected JPanel createFilterPanel() {
+ JPanel panel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ panel.setBorder(makeTitledBorder("OPTIONS"));
+ panel.setLayout(gb);
+
+ //entry
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel noRec = makeJLabel("NUMBERREC");
+ mNoRecord = makeJTextField(10);
+ mNoRecord.setText(Integer.toString(DEFAULT_LOG_ENTRY));
+ addEntryField(panel, noRec, mNoRecord, gbc);
+
+ //source and level
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label1 = makeJLabel("SOURCE");
+ mSource = makeJComboBox("SOURCE");
+ JLabel label2 = makeJLabel("LOGLEVEL");
+ mLevel = makeJComboBox("LOGLEVEL");
+ CMSAdminUtil.addEntryField(panel, label1, mSource, label2, mLevel, gbc);
+ mLevel.addActionListener(this);
+ mSource.addActionListener(this);
+
+
+ //file
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.gridheight = gbc.REMAINDER;
+ JLabel label3 = makeJLabel("FILE");
+ mFile = new JComboBox();
+ CMSAdminUtil.addEntryField(panel, label3, mFile, gbc);
+ mFile.addActionListener(this);
+
+ return panel;
+ }
+
+ /**
+ * retrieve log entries from the server side and
+ * populate the data model.
+ */
+ protected abstract void update();
+
+ /**
+ * retrieve archieve log file listing from the server
+ * side and poupulate the combobox
+ */
+ protected abstract void updateArchive();
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(new LabelCellRenderer(new JLabel()));
+ }
+
+ //=== OVERWRITE DIALOG MESSAGE =====================
+
+ protected void showMessageDialog(String keyword, int messageType ) {
+ CMSAdminUtil.showMessageDialog(mModel.getFrame(), mResource, mPanelName, keyword, messageType);
+ }
+
+ protected void showMessageDialog(String keyword) {
+ showMessageDialog(keyword, ERROR_MESSAGE);
+ }
+
+ protected int showConfirmDialog(String keyword, int messageType ) {
+ return CMSAdminUtil.showConfirmDialog(mModel.getFrame(), mResource, mPanelName, keyword, messageType);
+ }
+
+ protected int showConfirmDialog(String keyword) {
+ return showConfirmDialog(keyword, WARNING_MESSAGE);
+ }
+
+ protected void showErrorDialog(String message) {
+ CMSAdminUtil.showErrorDialog(mModel.getFrame(), mResource, message, ERROR_MESSAGE);
+ }
+
+
+ private static void addEntryField(JPanel panel, JComponent label,
+ JComponent field, GridBagConstraints gbc) {
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.gridx = 0;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(COMPONENT_SPACE,DIFFERENT_COMPONENT_SPACE,0,0);
+ panel.add( label, gbc );
+
+ gbc.gridx++;
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ 0,DIFFERENT_COMPONENT_SPACE);
+ panel.add( field, gbc );
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/status/DefaultLogParser.java b/base/console/src/com/netscape/admin/certsrv/status/DefaultLogParser.java
new file mode 100644
index 000000000..b69eac3a6
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/status/DefaultLogParser.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.admin.certsrv.status;
+
+import java.awt.*;
+import java.util.*;
+import java.text.*;
+import java.io.*;
+import java.awt.event.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Parse the log in the following default format:
+ * pid.thread - [SIMPLEDATEFORMAT][resource][level][message]
+ *
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.status
+ */
+class DefaultLogParser implements ILogParser {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private final String SOURCE_PROPERTY = "LOGCONTENT_COMBOBOX_SOURCE_VALUE_";
+ private final String LEVEL_PROPERTY = "LOGCONTENT_COMBOBOX_LOGLEVEL_VALUE_";
+
+ private final String DATE_PATTERN = "dd/MMM/yyyy:hh:mm:ss z";
+ protected ResourceBundle mResource;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public DefaultLogParser() {
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public Vector parse(Object entry) throws ParseException {
+ String logEntry = (String)entry;
+ //parsing the log Entry and return segments
+ //Debug.println("LogDataModel: DefaultLogParser: parse() -" +logEntry);
+ int x = logEntry.indexOf("[");
+ if (x == -1)
+ throw new ParseException(logEntry,0);
+ String temp = logEntry.substring(x+1);
+ x = temp.indexOf("]");
+ if (x == -1)
+ throw new ParseException(logEntry,0);
+
+ String dateStr = temp.substring(0,x);
+ //Debug.println("LogDataModel: DefaultLogParser: parse() -"+dateStr+" "+temp);
+ SimpleDateFormat format = new SimpleDateFormat(DATE_PATTERN);
+ Date date = format.parse(dateStr);
+ String dateColumn = DateFormat.getDateInstance().format(date);
+ String timeColumn = DateFormat.getTimeInstance().format(date);
+
+ //Debug.println("LogDataModel: DefaultLogParser: parse() -"+dateColumn+" "+timeColumn);
+ temp = temp.substring(x+2);
+ x = temp.indexOf("]");
+ if (x == -1)
+ throw new ParseException(logEntry,0);
+ String source = temp.substring(1,x);
+ temp = temp.substring(x+2);
+ x = temp.indexOf("]");
+ if (x == -1)
+ throw new ParseException(logEntry,0);
+ String level = temp.substring(1,x);
+ temp = temp.substring(x+2);
+ Vector row = new Vector();
+ row.addElement(getSourceString(source));
+ row.addElement(getLevelString(level));
+ row.addElement(dateColumn);
+ row.addElement(timeColumn);
+ JLabel detail = new JLabel(temp);
+ detail.setToolTipText(temp);
+ row.addElement(detail);
+ return row;
+ }
+
+ public String getSourceString(String code) {
+ try {
+ return mResource.getString(SOURCE_PROPERTY+code);
+ } catch (MissingResourceException e) {
+ return code;
+ }
+ }
+
+ public String getLevelString(String code) {
+ try {
+ return mResource.getString(LEVEL_PROPERTY+code);
+ } catch (MissingResourceException e) {
+ return code;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/base/console/src/com/netscape/admin/certsrv/status/ErrorLogDataModel.java b/base/console/src/com/netscape/admin/certsrv/status/ErrorLogDataModel.java
new file mode 100644
index 000000000..df97978b5
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/status/ErrorLogDataModel.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.admin.certsrv.status;
+
+/**
+ * ErrorLogDataModel
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.status
+ */
+public class ErrorLogDataModel extends LogDataModel {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ //protected String[] mColumns = {DATE, TIME, DETAILS}; //overwrites the default
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public ErrorLogDataModel() {
+ //XXX SET CORRECT PARSER HERE
+ super();
+ }
+
+ //parser here
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/status/ILogParser.java b/base/console/src/com/netscape/admin/certsrv/status/ILogParser.java
new file mode 100644
index 000000000..c0defd681
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/status/ILogParser.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.admin.certsrv.status;
+
+import java.text.*;
+import java.util.*;
+
+/**
+ * Interface for the log parser
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @date 02/04/97
+ */
+public interface ILogParser {
+
+ /**
+ * Parse the log entry into logical data display segments to be displayed
+ * in the table.
+ * Currently, only String object is supported by the log viewer.
+ */
+ public Vector parse(Object logEntry) throws ParseException;
+} \ No newline at end of file
diff --git a/base/console/src/com/netscape/admin/certsrv/status/LogDataModel.java b/base/console/src/com/netscape/admin/certsrv/status/LogDataModel.java
new file mode 100644
index 000000000..61d127524
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/status/LogDataModel.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.admin.certsrv.status;
+
+import java.awt.*;
+import java.util.*;
+import java.text.*;
+import java.io.*;
+import java.awt.event.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.*;
+
+/**
+ * LogDataModel to be displayed at the right hand side
+ *
+ * We need the log order in REVERSE.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.status
+ */
+public class LogDataModel extends CMSTableModel
+ implements IDataProcessor
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static String ILOGENTRY = "ILOGENTRY";
+
+ protected String[] mColumns = {SOURCE, SEVERITY, DATE, TIME, DETAILS};
+ protected ILogParser mParser = null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public LogDataModel() {
+ super();
+ init(mColumns);
+ }
+
+ public LogDataModel(ILogParser parser) {
+ this();
+ mParser = parser;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * set the log parser
+ */
+ public void setParser(ILogParser parser) {
+ mParser = parser;
+ }
+
+
+ /**
+ * Process data called back
+ */
+ public void processData(Object data) {
+ Vector row;
+ if (mParser == null)
+ mParser = new DefaultLogParser();
+ try {
+ row = mParser.parse((String) data);
+ } catch (ParseException e) {
+ //Debug.println("LogDataModel: processData()");
+ return;
+ }
+ addRow(row);
+ }
+
+ /**
+ * NEED TO OVERWRITE THE TABLE MODEL ADD FUNCTION
+ * SINCE WE ARE PROVIDING REVERSE ORDER ENTRIES IN
+ * LOG FILES
+ */
+ public synchronized void addRow(Vector values) {
+ int row = 0;
+ for (int i=0; i < values.size(); i++) {
+ Vector v = (Vector)_tableColumns.elementAt(i);
+ v.insertElementAt(values.elementAt(i),0);
+ if (i == 0)
+ row = v.size() - 1;
+ }
+ fireTableDataChanged();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/status/LogEntryViewDialog.java b/base/console/src/com/netscape/admin/certsrv/status/LogEntryViewDialog.java
new file mode 100644
index 000000000..c86ff02ff
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/status/LogEntryViewDialog.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.admin.certsrv.status;
+
+import com.netscape.admin.certsrv.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import javax.swing.table.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Policy Implementation Information viewer
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class LogEntryViewDialog extends JDialog
+ implements ActionListener
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private String PREFIX = "LOGENTRYVIEWDIALOG";
+
+ private JFrame mParentFrame;
+ private ResourceBundle mResource;
+ private JTextArea mTextArea;
+ private JLabel mSource, mLevel, mDate, mTime;
+
+ private JButton mOK;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public LogEntryViewDialog(JFrame parent) {
+ super(parent,true);
+ mParentFrame = parent;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ setSize(600, 400);
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ setDisplay();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * show the windows
+ */
+ public void showDialog(String source, String level,
+ String date, String time, String desc) {
+ //initialize and setup
+ mSource.setText(source);
+ mLevel.setText(level);
+ mDate.setText(date);
+ mTime.setText(time);
+ mTextArea.setText(desc);
+ mTextArea.setCaretPosition(0);
+ this.show();
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent evt) {
+ if (evt.getSource().equals(mOK)) {
+ this.hide();
+ }
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+ private void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null, this);
+ Dimension d = mOK.getMinimumSize();
+ if (d.width < CMSAdminUtil.DEFAULT_BUTTON_SIZE) {
+ d.width = CMSAdminUtil.DEFAULT_BUTTON_SIZE;
+ mOK.setMinimumSize(d);
+ }
+ JButton[] buttons = {mOK};
+ return CMSAdminUtil.makeJButtonPanel( buttons );
+ }
+
+ private JPanel makeContentPane() {
+ JPanel content = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ content.setLayout(gb3);
+ //content.setBorder(CMSAdminUtil.makeEtchedBorder());
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label1 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "SOURCE", null);
+ mSource = new JLabel();
+ CMSAdminUtil.addEntryField(content, label1, mSource, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label2 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "LEVEL", null);
+ mLevel = new JLabel();
+ CMSAdminUtil.addEntryField(content, label2, mLevel, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label3 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "DATE", null);
+ mDate = new JLabel();
+ CMSAdminUtil.addEntryField(content, label3, mDate, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label4 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "TIME", null);
+ mTime = new JLabel();
+ CMSAdminUtil.addEntryField(content, label4, mTime, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label5 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "DESC", null);
+ label5.setHorizontalAlignment(JLabel.RIGHT);
+ gbc.anchor = gbc.NORTHEAST;
+ gbc. insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ gb3.setConstraints(label5, gbc);
+ content.add(label5);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mTextArea = new JTextArea("",40,500);
+ mTextArea.setLineWrap(true);
+ mTextArea.setFont(mSource.getFont());
+ mTextArea.setEditable(false);
+ mTextArea.setBackground(getBackground());
+ JScrollPane scrollPanel = new JScrollPane(mTextArea,
+ JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ scrollPanel.setAlignmentX(LEFT_ALIGNMENT);
+ scrollPanel.setAlignmentY(TOP_ALIGNMENT);
+ scrollPanel.setBackground(getBackground());
+ scrollPanel.setBorder(BorderFactory.createEmptyBorder());
+ scrollPanel.setPreferredSize(new Dimension(500, 200));
+ //gbc.fill = gbc.VERTICAL;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx=1.0;
+ gbc.weighty=1.0;
+ gb3.setConstraints(scrollPanel, gbc);
+ content.add(scrollPanel);
+
+ return content;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/status/LogInstancePanel.java b/base/console/src/com/netscape/admin/certsrv/status/LogInstancePanel.java
new file mode 100644
index 000000000..dc6a8da27
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/status/LogInstancePanel.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.admin.certsrv.status;
+
+
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+
+import java.awt.event.*;
+
+/**
+ * Transactions Log Panel to be displayed at the right hand side
+ *
+ * @author Jack Pan-Chen
+ * @author Michelle Zhao
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.status
+ */
+public class LogInstancePanel extends CMSLogPanel {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private String mSelectedFile;
+ private String mInstanceName;
+ private static final String HELPINDEX = "status-logs-help";
+ private static final String AUDITHELPINDEX = "status-logs-audit-help";
+ private static final String SYSTEMHELPINDEX = "status-logs-system-help";
+ private static final String ERRORHELPINDEX = "status-logs-error-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public LogInstancePanel(CMSBaseResourceModel model) {
+ super(model, new LogDataModel());
+ mHelpToken = HELPINDEX;
+ }
+
+ public LogInstancePanel(String name, CMSBaseResourceModel model) {
+ super(model, new LogDataModel());
+ mInstanceName = name;
+ // xxx this is temperary
+ if (name.equals("transactions"))
+ mHelpToken = AUDITHELPINDEX;
+ else if (name.equals("system"))
+ mHelpToken = SYSTEMHELPINDEX;
+ else if (name.equals("error"))
+ mHelpToken = ERRORHELPINDEX;
+ else
+ mHelpToken = HELPINDEX;
+ }
+
+ /**
+ * retrieve data and process it
+ */
+ protected void update() {
+ AdminConnection connection = mModel.getServerInfo().getAdmin();
+
+ //construct NVP
+ NameValuePairs config = new NameValuePairs();
+ config.put(Constants.PR_LOG_INSTANCE, mInstanceName);
+ config.put(Constants.PR_LOG_ENTRY, mNoRecord.getText().trim());
+ config.put(Constants.PR_LOG_SOURCE, Integer.toString(mSource.getSelectedIndex()));
+ config.put(Constants.PR_LOG_LEVEL, Integer.toString(mLevel.getSelectedIndex()));
+ if ((mFile.getSelectedIndex()< 0) || (mFile.getSelectedIndex()< 0)) {
+ config.put(Constants.PR_LOG_NAME, Constants.PR_CURRENT_LOG);
+ mSelectedFile = mResource.getString("LOGCONTENT_COMBOBOX_FILE_DEFAULT");
+ } else {
+ String filename = (String) mFile.getSelectedItem();
+ if (filename.equalsIgnoreCase(Constants.PR_CURRENT_LOG))
+ filename = Constants.PR_CURRENT_LOG;
+ config.put(Constants.PR_LOG_NAME, filename);
+ mSelectedFile = (String) mFile.getSelectedItem();
+ }
+ NameValuePairs response;
+ mModel.progressStart();
+ try {
+ response = connection.search(DestDef.DEST_LOG_ADMIN,
+ ScopeDef.SC_LOG_CONTENT,
+ config);
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+
+ mModel.progressStop();
+ Debug.println(response.toString());
+
+ //update the table
+ for (String entry : response.keySet()) {
+ mDataModel.processData(entry);
+ }
+
+ updateArchive();
+ }
+
+ /**
+ * retrieve archieve log file listing from the server
+ * side and poupulate the combobox
+ */
+ protected void updateArchive() {
+ AdminConnection connection = mModel.getServerInfo().getAdmin();
+ String value = mResource.getString("LOGCONTENT_COMBOBOX_FILE_DEFAULT");
+ mFile.removeAllItems();
+ mFile.addItem(value);
+
+ //get stuff
+ NameValuePairs response;
+ mModel.progressStart();
+ //construct NVP
+ NameValuePairs config = new NameValuePairs();
+ config.put(Constants.PR_LOG_INSTANCE, mInstanceName);
+ try {
+ response = connection.search(DestDef.DEST_LOG_ADMIN,
+ ScopeDef.SC_LOG_ARCH,
+ config);
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+
+ //update the combo
+ for (String entry : response.keySet()) {
+ mFile.addItem(entry);
+ }
+ mModel.progressStop();
+ mFile.setSelectedItem(mSelectedFile);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ super.actionPerformed(e);
+ if (e.getSource().equals(mHelp)) {
+ CMSAdminUtil.help(mHelpToken);
+ }
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/status/StatusPanel.java b/base/console/src/com/netscape/admin/certsrv/status/StatusPanel.java
new file mode 100644
index 000000000..431d0d61f
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/status/StatusPanel.java
@@ -0,0 +1,246 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.status;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import com.netscape.admin.certsrv.*;
+
+import java.awt.event.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Status to be placed at the right hand side
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.status
+ */
+public class StatusPanel extends CMSBasePanel
+ implements IResourceSelectionListener, IRefreshTab, IRefreshTabPanel
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static String PANEL_NAME = "STATUSPANEL";
+
+ protected boolean mInit = false; // true if this panel is initialized
+ protected JPanel mStatPanel, mActionPanel; //panels
+ protected JButton mRefresh, mHelp; //action buttons
+ protected JLabel mServerName, mServerVersion, mInstallDate, mServerStart, mServerTime;
+
+ protected CMSBaseResourceModel mModel;
+ private AdminConnection mConnection;
+ private static final String HELPINDEX = "status-certsrv-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public StatusPanel(CMSBaseResourceModel model) {
+ super(PANEL_NAME);
+ model.addIResourceSelectionListener(this);
+ mModel = model;
+ mConnection = model.getServerInfo().getAdmin();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Actual Instanciation of the UI components
+ */
+ public void init() {
+ setLayout(new BorderLayout());
+
+ //======== stat panel ========================
+ mStatPanel = createStatPanel();
+ mStatPanel.setBorder(new EmptyBorder(DIFFERENT_COMPONENT_SPACE,COMPONENT_SPACE,COMPONENT_SPACE,COMPONENT_SPACE));
+ add("Center",mStatPanel);
+
+ //====== action panel ========================
+ mActionPanel = createActionPanel();
+ add("South",mActionPanel);
+ refresh();
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //== IResourceListener ===
+
+ public void select(IResourceObject parent, Object viewInstance) {
+ if (!mInit) {
+ init();
+ mInit = true;
+ }
+
+ //refresh the screen
+ invalidate();
+ validate();
+ repaint(1);
+ }
+
+ public boolean unselect(IResourceObject parent, Object viewInstance) {
+ return true;
+ }
+
+ public CMSBasePanel getSelectedTab() {
+ return this;
+ }
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mRefresh)) {
+ Debug.println("StatusPanel: Refresh");
+ refresh();
+ }
+ if (e.getSource().equals(mHelp)) {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+ }
+
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+
+ /**
+ * create action button panel
+ */
+ protected JPanel createActionPanel() {
+ //actionlister to this object
+ mRefresh = makeJButton("REFRESH");
+ mHelp = makeJButton("HELP");
+ //JButton[] buttons = { mRefresh,mHelp };
+ JButton[] buttons = { mRefresh };
+ return makeJButtonPanel(buttons,true,true);
+ }
+
+ /**
+ * create log listing panel
+ */
+ protected JPanel createStatPanel() {
+ JPanel outPanel = new JPanel();
+ GridBagLayout gb2 = new GridBagLayout();
+ GridBagConstraints gbc2 = new GridBagConstraints();
+ outPanel.setLayout(gb2);
+
+ JPanel panel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ panel.setLayout(gb);
+ panel.setBorder(CMSAdminUtil.makeTitledBorder(mResource, PANEL_NAME, "GENERALINFO"));
+
+ CMSAdminUtil.resetGBC(gbc2);
+ gbc2.anchor = gbc2.NORTH;
+ gbc2.weightx = 1.0;
+ gbc2.weighty = 1.0;
+ gbc2.gridwidth = gbc2.REMAINDER;
+ gbc2.gridheight = gbc2.REMAINDER;
+ outPanel.add(panel, gbc2);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label1 = makeJLabel("SERVERNAME");
+ mServerName = new JLabel();
+ CMSAdminUtil.addEntryField(panel, label1, mServerName, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label2 = makeJLabel("SERVERVERSION");
+ mServerVersion = new JLabel();
+ CMSAdminUtil.addEntryField(panel, label2, mServerVersion, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label5 = makeJLabel("INSTALLDATE");
+ mInstallDate = new JLabel();
+ CMSAdminUtil.addEntryField(panel, label5, mInstallDate, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label3 = makeJLabel("SERVERSTARTUP");
+ mServerStart = new JLabel();
+ CMSAdminUtil.addEntryField(panel, label3, mServerStart, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ JLabel label4 = makeJLabel("SERVERTIME");
+ mServerTime = new JLabel();
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.gridx = 0;
+ gbc.anchor = gbc.EAST;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,COMPONENT_SPACE,0);
+ panel.add( label4, gbc );
+
+ gbc.gridx++;
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ panel.add( mServerTime, gbc );
+
+ return outPanel;
+ }
+
+
+ //=============================================
+ // SEND REQUESTS TO THE SERVER SIDE
+ //=============================================
+
+ //retrieve stat from server
+ public void refresh() {
+
+ NameValuePairs params = new NameValuePairs();
+ params.put(Constants.PR_STAT_STARTUP, "");
+ params.put(Constants.PR_STAT_TIME, "");
+
+ NameValuePairs response;
+ mModel.progressStart();
+ try {
+ response = mConnection.read(DestDef.DEST_SERVER_ADMIN,
+ ScopeDef.SC_STAT,
+ Constants.RS_ID_CONFIG,
+ params);
+ } catch (EAdminException e) {
+ //display error dialog
+ CMSAdminUtil.showErrorDialog(mModel.getFrame(), mResource,
+ e.toString(), ERROR_MESSAGE);
+ mModel.progressStop();
+ return;
+ }
+
+ mModel.progressStop();
+ Debug.println("StatusPanel: refresh() "+ response.toString());
+
+ //populate data
+ mServerName.setText(response.get(Constants.PR_STAT_INSTANCEID));
+ mServerVersion.setText(response.get(Constants.PR_STAT_VERSION));
+ mInstallDate.setText(response.get(Constants.PR_STAT_INSTALLDATE));
+ mServerStart.setText(response.get(Constants.PR_STAT_STARTUP));
+ mServerTime.setText(response.get(Constants.PR_STAT_TIME));
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/task/AuthDialog.java b/base/console/src/com/netscape/admin/certsrv/task/AuthDialog.java
new file mode 100644
index 000000000..f4d305096
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/task/AuthDialog.java
@@ -0,0 +1,244 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.task;
+
+import java.awt.*;
+import java.util.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.border.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Display this dialog to get the instance name and password.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class AuthDialog extends JDialog
+ implements ActionListener, DocumentListener, MouseListener
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "AUTHDIALOG";
+
+ private static final int WIDTH = 300;
+ private static final int HEIGHT = 150;
+ private JPasswordField mPasswordField;
+ private boolean mCanceled = true; // exit state of the dialog
+ private String mPassword;
+ private JFrame mParentFrame;
+ private ResourceBundle mResource;
+ private JButton mOK, mCancel;
+ private KeyListener mTextFieldKeyListener;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ /**
+ * @param parent parent frame
+ */
+ public AuthDialog(JFrame parent) {
+ super(parent, true);
+ mParentFrame = parent;
+ mResource =
+ ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mTextFieldKeyListener = new TextFieldKeyListener();
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+
+ JPanel center = new JPanel();
+ getContentPane().setLayout(new BorderLayout());
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ JPanel contentPanel = new JPanel();
+ GridBagLayout gb1 = new GridBagLayout();
+ contentPanel.setLayout(gb1);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(contentPanel, gbc);
+ center.add(contentPanel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel lPassword =
+ new JLabel(mResource.getString(PREFIX+"_LABEL_PASSWORD_LABEL"));
+ mPasswordField = new JPasswordField();
+ mPasswordField.addKeyListener(mTextFieldKeyListener);
+ mPasswordField.getDocument().addDocumentListener(this);
+ mPasswordField.addMouseListener(this);
+
+ CMSAdminUtil.addEntryField(contentPanel, lPassword, mPasswordField,
+ gbc);
+
+ JPanel actionPanel = makeActionPane();
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(actionPanel, gbc);
+ center.add(actionPanel);
+
+ getContentPane().add("Center",center);
+
+ mCanceled=false;
+ mPassword = "";
+
+ setSize( WIDTH, HEIGHT );
+
+ addWindowListener(
+ new WindowAdapter() {
+ public void windowOpened(WindowEvent e) {
+ mPasswordField.requestFocus();
+ }
+ }
+ );
+
+ addWindowListener(
+ new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ //setVisible(false);
+ dispose();
+ mCanceled = true;
+ }
+ }
+ );
+
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * return the exit status of the dialog
+ *
+ * @return true if the user hits the cancel button.
+ */
+ public boolean isCancel() {
+ return mCanceled;
+ }
+
+ public String getPassword() {
+ return mPassword;
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+ public void actionPerformed(ActionEvent evt) {
+ if (evt.getSource().equals(mOK)) {
+ mPassword = mPasswordField.getText().trim();
+ mCanceled = false;
+ //setVisible(false);
+ this.dispose();
+ return;
+
+ }
+ if (evt.getSource().equals(mCancel)) {
+ //setVisible(false);
+ mCanceled = true;
+ this.dispose();
+ return;
+ }
+ }
+
+ //== DocumentListener ==
+ public void insertUpdate(DocumentEvent e) {
+ setButtons();
+ }
+
+ public void removeUpdate(DocumentEvent e){
+ setButtons();
+ }
+
+ public void changedUpdate(DocumentEvent e){
+ setButtons();
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {}
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null,
+ this);
+ mOK.setEnabled(false);
+ mCancel = CMSAdminUtil.makeJButton(mResource, PREFIX, "CANCEL",
+ null, this);
+
+ JButton[] buttons = { mOK, mCancel};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonPanel(buttons, false);
+ }
+
+ //set buttons
+ private void setButtons() {
+ if (mPasswordField.getText().trim().equals("")){
+ mOK.setEnabled(false);
+ } else {
+ mOK.setEnabled(true);
+ getRootPane().setDefaultButton(mOK);
+ }
+ }
+
+ /**
+ * Inner class which handles key events for JTextField components.
+ */
+ class TextFieldKeyListener implements KeyListener
+ {
+ public void keyTyped(KeyEvent e) {
+ }
+
+ public void keyPressed(KeyEvent e) {
+ }
+
+ public void keyReleased(KeyEvent e) {
+ if(e.getKeyCode() == KeyEvent.VK_ENTER) {
+ if (!mPasswordField.getText().trim().equals("")) {
+ mOK.doClick();
+ }
+ }
+ }
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/task/CGITask.java b/base/console/src/com/netscape/admin/certsrv/task/CGITask.java
new file mode 100644
index 000000000..8406e1005
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/task/CGITask.java
@@ -0,0 +1,400 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.task;
+
+import com.netscape.admin.certsrv.*;
+import java.util.*;
+import java.io.*;
+import java.net.URL;
+import javax.swing.JFrame;
+import com.netscape.management.client.TaskObject;
+import com.netscape.management.client.IPage;
+import com.netscape.management.client.console.ConsoleInfo;
+import com.netscape.management.client.comm.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Netscape Certificate Server 4.0 CGI base task
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class CGITask extends CMSTaskObject
+ implements CommClient
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "CGITASK";
+
+ protected boolean mFinished = false;
+ protected String mCmd = null;
+ protected String mAdminURL = null;
+ protected boolean mSuccess = false;
+ private String mReply = null;
+ protected String mSection = "";
+ protected String mErrorMsg = "";
+ protected String mWarnMsg = "";
+
+ private boolean mForceBasicAuth = false;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CGITask() {
+ super();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Force the operation to complete with basic auth, instead
+ * of the default option, which is to first try a non
+ * authenticated request, then an authenticated one.
+ */
+
+ public void setForceBasicAuth(boolean value) {
+ mForceBasicAuth = value;
+ }
+
+ /**
+ * Send an http request to the server and then popup a dialog if the
+ * operation is successful.
+ *
+ * @param viewInstance The calling page
+ */
+ public boolean run(IPage viewInstance) {
+ if ( mCmd == null ) {
+ Debug.println( "Could not get execref for " + getDN() );
+ return false;
+ }
+
+ return run( viewInstance, mCmd );
+ }
+
+ /**
+ * Send an http request to the server. Return true if we're sure it
+ * succeeded, otherwise false.
+ *
+ * @param viewInstance The calling page
+ * @param cmd Command to execute
+ */
+ boolean run(IPage viewInstance, String cmd) {
+
+ // get the admin URL location first
+ mAdminURL = _consoleInfo.getAdminURL();
+ if ( mAdminURL == null ) {
+ Debug.println( "Could not get adminURL for " + getDN() );
+ return false;
+ }
+
+ // Allow specifying e.g. "slapd-install" for instance
+ String instance = (String)_consoleInfo.get( cmd );
+
+ if ( instance == null )
+ instance = (String)_consoleInfo.get( "ServerInstance" );
+ String fullCmd = mAdminURL + instance + "/" + cmd;
+
+ HttpManager h = new HttpManager();
+ // tell the http manager to use UTF8 encoding
+ h.setResponseTimeout(60000);
+ h.setSendUTF8(true);
+
+ try {
+ mSuccess = false;
+ mFinished = false;
+
+ // _consoleInfo.get("arguments") is a hashtable of key/value pairs
+ // to use as the arguments to the CGI
+ Hashtable args = (Hashtable)_consoleInfo.get("arguments");
+ ByteArrayInputStream data = null;
+ if (args != null && !args.isEmpty())
+ data = encode(args);
+ Debug.println( "Posting " + fullCmd );
+ // tell the http manager to notify us immediately of replies
+ // if we're using async mode
+ int flags = 0;
+
+ if (mForceBasicAuth) {
+ flags |= CommManager.FORCE_BASIC_AUTH;
+ }
+
+ if (data == null)
+ h.post(new URL(fullCmd), this, null, null, 0,
+ flags);
+ else
+ h.post(new URL(fullCmd), this, null, data, data.available(),
+ flags);
+ awaitSuccess();
+ Debug.println( "Command executed: " + fullCmd );
+ } catch (Exception e) {
+ if ( e instanceof java.net.ConnectException ) {
+ CMSAdminUtil.showMessageDialog(mResource,
+ PREFIX, "SERVERDOWN", CMSAdminUtil.ERROR_MESSAGE);
+ }
+ Debug.println( "Command " + fullCmd + " failed: " + e );
+ }
+ return mSuccess;
+ }
+
+ /**
+ * waiting for the http transaction to be finished.
+ */
+ public synchronized void awaitSuccess() {
+ while (!mFinished) {
+ try {wait();}
+ catch (Exception e) { }
+ }
+ }
+
+ /**
+ * http transaction finished, notify the process
+ */
+ public synchronized void finish() {
+ mFinished = true;
+ notifyAll();
+ }
+
+ /**
+ * the operation is finished after we receive the http stream
+ */
+ public void replyHandler(InputStream response, CommRecord cr) {
+/*
+ try {
+ int nBytes = response.available();
+ if ( nBytes > 0 ) {
+ // the response from the DS CGIs will typically be in
+ // UTF8 encoding
+ byte[] data = new byte[nBytes];
+ nBytes = response.read( data );
+ mReply = new String( data, 0, nBytes, "UTF8" );
+ Debug.println( "CGITask.replyHandler: Response (" + nBytes +
+ " bytes) = " + mReply );
+ int index = 0;
+ if ((mReply.indexOf("NMC_") != -1) &&
+ ((index = mReply.indexOf(":")) != -1)) {
+ String sName = mReply.substring(0, index).trim();
+ String sValue = mReply.substring(index+1).trim();
+ if (sName.equalsIgnoreCase("NMC_Status")) {
+ int code = Integer.parseInt(sValue);
+ mSuccess = (code == 0);
+ } else if (sName.equalsIgnoreCase("NMC_ERRINFO")) {
+ mErrorMsg = sValue;
+ } else if (sName.equalsIgnoreCase("NMC_WARNINFO")) {
+ mWarnMsg = sValue;
+ }
+ }
+ }
+ } catch ( Exception e ) {
+ Debug.println( "CGITask.replyHandler: " + e.toString() );
+ mSuccess = false;
+ }
+ finish();
+*/
+
+ try {
+ BufferedReader rspStream =
+ new BufferedReader(new InputStreamReader(response, "UTF8"));
+ String rspStr;
+
+ Debug.println("replyHandler() - start");
+ while ((rspStr = rspStream.readLine()) != null)
+ {
+ Debug.println("replyHandler() - read [" + rspStr + "]");
+ // NMC_ messages are parsed, but not shown to the user
+ /*
+ if (_statusText != null && !rspStr.startsWith("NMC_")) {
+ _statusText.append(rspStr + "\n");
+ Thread.yield(); // allow graphics repaints
+ }
+ */
+ Debug.println("Start parsing");
+ parse(rspStr);
+ }
+ } catch (Exception e) {
+ Debug.println("ConfigCert.Exception : " + e.toString());
+ }
+
+ Debug.println("ConfigCert.replyHandler: finished, mSuccess=" +
+ mSuccess);
+
+ finish();
+ }
+
+ /**
+ * return the value for the given keyword in the reply
+ */
+ private void parse(String s) {
+ String sName;
+ String sValue;
+ int iIndex;
+
+ Debug.println("Parse input: " + s);
+
+ if ((iIndex=s.indexOf(":")) != (-1))
+ {
+ sName = s.substring(0, iIndex).trim();
+ sValue = s.substring(iIndex+1).trim();
+ Debug.println("Parse input: name=" + sName + " value=" + sValue);
+ //mWizardInfo.put(sName, sValue);
+/*
+ if (mCgiResponse == null)
+ mCgiResponse = new Hashtable();
+ mCgiResponse.put(sName, sValue);
+*/
+ if (sName.equalsIgnoreCase("NMC_Status"))
+ {
+ int code = Integer.parseInt(sValue);
+ mSuccess = (code == 0);
+ Debug.println("Parse input: code=" + code + " mSuccess=" +
+ mSuccess);
+ } else if (sName.equalsIgnoreCase("NMC_ERRINFO")) {
+ mErrorMsg = sValue;
+ } else if (sName.equalsIgnoreCase("NMC_WARNINFO")) {
+ mWarnMsg = sValue;
+ }
+ }
+
+ Debug.println("Parse finished");
+ }
+
+ public String getErrorMessage() {
+ return mErrorMsg;
+ }
+
+ /**
+ * this function will be called if error occurs
+ */
+ public void errorHandler(Exception error, CommRecord cr) {
+ Debug.println("CGITask.errorHandler: " + error );
+
+ mSuccess = false;
+ finish();
+ }
+
+
+ public String getDN() {
+ return _consoleInfo.getCurrentDN();
+ }
+
+ public String getReply() {
+ return mReply;
+ }
+
+ /**
+ * Return the command, which should have been stored in the info.
+ */
+ private String getCommand() {
+ String s = (String)_consoleInfo.get( "execref" );
+ if ( s != null )
+ return "bin/" + s;
+ return null;
+ }
+
+ /**
+ * pass the username to the admin server
+ */
+ public String username(Object authObject, CommRecord cr) {
+ Debug.println( "username = " +
+ (String)_consoleInfo.getAuthenticationDN());
+ return _consoleInfo.getAuthenticationDN();
+ }
+
+ /**
+ * pass the user password to the admin server
+ */
+ public String password(Object authObject, CommRecord cr) {
+ Debug.println( "password = " +
+ (String)_consoleInfo.get( "AdminUserPassword" ) );
+ return (String)_consoleInfo.get( "AdminUserPassword" );
+ }
+
+/*
+ protected void showDialog( JFrame frame, String msg, String item,
+ boolean error ) {
+ // display a message
+ if ( error ) {
+ DSUtil.showErrorDialog( frame, msg, item, "dirtask" );
+ } else {
+ DSUtil.showInformationDialog( frame, msg, item, "dirtask" );
+ }
+ }
+
+ protected void showResultDialog( boolean success ) {
+ // popup a dialog
+ if ( success ) {
+ showDialog( new JFrame(), mSection+"-success", "",
+ false );
+ } else {
+ showDialog( new JFrame(), mSection+"-failed", "",
+ true );
+ }
+ }
+
+ protected void showResultDialog( int errorCode, String arg ) {
+ // popup a dialog
+ String error = "error-" + Integer.toString( errorCode ) + "-msg";
+ String title = mSection + "-failed-title";
+ DSUtil.showErrorDialog( null,
+ title,
+ error,
+ arg, "dirtask" );
+ }
+
+ protected void showResultDialog( CGIThread thread ) {
+ CGIReportTask task = thread.getTask();
+ if ( task.getStatus() != 0 ) {
+ showResultDialog( task.getStatus(),
+ (String)task.getResult("NMC_ErrInfo") );
+ } else {
+ showResultDialog( task.getStatus() == 0 );
+ }
+ }
+ */
+
+ /**
+ * Translates a hashtable into <code>x-www-form-urlencoded</code> format.
+ * Values are converted from Unicode to UTF8 before URL encoding.
+ *
+ * @param args <code>Hashtable</code> containing name/value pairs to be translated.
+ * @return a ByteArrayInputStream to the translated <code>Hashtable</code> contents.
+ */
+ public static ByteArrayInputStream encode(Hashtable args)
+ {
+ if ((args == null) || (args.size() == 0))
+ return (null);
+
+ String p = "";
+ Enumeration e = args.keys();
+
+ while (e.hasMoreElements())
+ {
+ String name = (String)e.nextElement();
+ String value = URLByteEncoder.encodeUTF8(args.get(name).toString());
+ Debug.println("********** Encoding name --> "+name+" value --> "+value);
+ p += URLByteEncoder.encodeUTF8(name) + "=" +
+ value + (e.hasMoreElements()?"&":"");
+ }
+
+ return new ByteArrayInputStream(p.getBytes());
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/task/CMSCertRequest.java b/base/console/src/com/netscape/admin/certsrv/task/CMSCertRequest.java
new file mode 100644
index 000000000..bf391c4e4
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/task/CMSCertRequest.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.admin.certsrv.task;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.management.client.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.keycert.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.topology.*;
+import com.netscape.management.client.comm.*;
+import java.net.*;
+import java.io.*;
+import netscape.ldap.*;
+import netscape.ldap.util.*;
+
+/**
+ * Perform certificate request in certificate setup wizard.
+ *
+ * @author Michelle Zhao
+ * @version $Revision$, $Date$
+ */
+public class CMSCertRequest extends CGITask {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "CGITASK";
+ private String mCgiTask = null; // CGI task to call
+ private CertSetupWizardInfo mWizardInfo;
+ private String mPolicyMsg = null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSCertRequest() {
+ super();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void initialize(CertSetupWizardInfo info) {
+ Debug.println("CMSRequestCert: initialize()");
+ _consoleInfo = info.getAdminConsoleInfo();
+
+ // the results coming back from the daemon will be added to the
+ // wizard information.
+ mWizardInfo = info;
+ }
+
+ /**
+ * Collect the data in name value pairs format and then send them to the
+ * cgi process.
+ */
+ public boolean requestCert(Hashtable data) {
+ boolean status = false; // return value
+
+ try {
+ status = run(data);
+ } catch (Exception e) {
+ Debug.println("Unexpected Error"+e.toString());
+ status = false;
+ }
+ Debug.println("CMSRequestCert: requestCert() after run status=" +
+ status + " mSuccess=" + mSuccess);
+
+ return mSuccess;
+ }
+
+ /**
+ * the operation is finished after we receive the http stream
+ */
+ public void replyHandler(InputStream response, CommRecord cr) {
+ mSuccess = false;
+
+ try {
+ BufferedReader rspStream =
+ new BufferedReader(new InputStreamReader(response, "UTF8"));
+ String rspStr;
+
+ Debug.println("CMSRequestCert: replyHandler() - start");
+ mErrorMsg = mResource.getString("REQUESTRESULTWIZARD_TEXT_ERRORDESC_LABEL");
+ while ((rspStr = rspStream.readLine()) != null && !mSuccess)
+ {
+ Debug.println("RequestCert: replyHandler() - read [" + rspStr + "]");
+ // NMC_ messages are parsed, but not shown to the user
+ parse2(rspStr);
+ }
+ mErrorMsg = mErrorMsg +
+ mResource.getString("REQUESTRESULTWIZARD_TEXT_ERROREND_LABEL");
+ String requestStatus =mWizardInfo.getRequestStatus();
+ if ((mWizardInfo.getRequestError() != null) &&
+ mWizardInfo.getRequestError().equals("true")) {
+ mWizardInfo.setRequestError(mErrorMsg);
+ mErrorMsg = null;
+ mSuccess = true;
+ } else if (requestStatus == null) {
+ // agent port, Unauthorizied access
+ mErrorMsg = mResource.getString("CGITASK_DIALOG_WRONGSERVER_MESSAGE");
+ } else if (requestStatus.equals("5")) {
+ // rejected
+ if (mPolicyMsg == null) {
+ mWizardInfo.setRequestError(mResource.getString("REQUESTRESULTWIZARD_TEXT_NODETAIL_LABEL"));
+ } else {
+ mWizardInfo.setRequestError(mPolicyMsg);
+ mPolicyMsg = null;
+ }
+ mSuccess = true;
+ }
+ // Use the same format for other status:success,pending,svcPending
+ } catch (Exception e) {
+ Debug.println("RequestCert.Exception : " + e.toString());
+ }
+
+ Debug.println("RequestCert.replyHandler: finished, mSuccess=" +
+ mSuccess);
+
+ finish();
+ }
+
+ private void parse2(String s)
+ {
+ int iIndex;
+ Debug.println("Parse2 input: " + s);
+ if ((iIndex=s.indexOf("errorCode")) != (-1))
+ {
+ String errorCode = s.substring(s.indexOf("\"") + 1,
+ s.lastIndexOf("\""));
+ Debug.println("errorCode: " + errorCode);
+ if (errorCode.equals("2")) { // pending
+ mWizardInfo.setRequestError("false");
+ mSuccess = true;
+ mWizardInfo.setRequestStatus("0");
+ } else if (errorCode.equals("1")) { // error
+ mWizardInfo.setRequestError("true");
+ mWizardInfo.setRequestStatus("5");
+ mSuccess = false;
+ } else {
+ mWizardInfo.setRequestError("true");
+ mWizardInfo.setRequestStatus("0");
+ mSuccess = false;
+ }
+ }
+ else if ((iIndex=s.indexOf("requestList.requestId")) != (-1))
+ {
+ String requestId = s.substring(s.indexOf("\"") + 1,
+ s.lastIndexOf("\""));
+ Debug.println("requestId: " + requestId);
+ mWizardInfo.setRequestID(requestId);
+ }
+ else if ((iIndex=s.indexOf("errorReason")) != (-1))
+ {
+ String errorReason = s.substring(s.indexOf("\"") + 1,
+ s.lastIndexOf("\""));
+ Debug.println("errorReason: " + errorReason);
+ mErrorMsg = mErrorMsg + "\n " + errorReason;
+ }
+ }
+
+ /**
+ * return the value for the given keyword in the reply
+ */
+ private void parse(String s) {
+ String sName;
+ String sValue = null;
+ int iIndex;
+
+ Debug.println("Parse input: " + s);
+
+ // XXXX We need to know all possible response.
+ // If cmsgateway changes, this will be broken.
+ if ((iIndex=s.indexOf("requestStatus = ")) != (-1))
+ {
+ sName = s.substring(iIndex + 17).trim();
+ if ((iIndex = sName.indexOf("\"")) != (-1))
+ sValue = sName.substring(0,iIndex);
+
+ Debug.println("Parse input: name=" + sName + " output="
+ + sValue + " index=" + iIndex);
+ if (sValue != null && !sValue.equals("")) {
+ mWizardInfo.setRequestStatus(sValue);
+ if (sValue.equals("2") || sValue.equals("3")
+ || sValue.equals("4"))
+ // success, pending, svcPending
+ mSuccess = true;
+ }
+ }
+ else if ((iIndex=s.indexOf("requestId = ")) != (-1))
+ {
+ sName = s.substring(iIndex + 13).trim();
+ if ((iIndex = sName.indexOf("\"")) != (-1))
+ sValue = sName.substring(0,iIndex);
+
+ Debug.println("Parse input: name=" + sName + " output="
+ + sValue + " index=" + iIndex);
+ if (sValue != null && !sValue.equals("")) {
+ mWizardInfo.setRequestID(sValue);
+ //mSuccess = true;
+ }
+ }
+ else if ((iIndex=s.indexOf("unexpectedError = ")) != (-1))
+ {
+ sName = s.substring(iIndex + 19).trim();
+ if ((iIndex = sName.indexOf("\"")) != (-1))
+ sValue = sName.substring(0,iIndex);
+
+ Debug.println("Parse input: name=" + sName + " output="
+ + sValue + " index=" + iIndex);
+ if (sValue != null && !sValue.equals("")) {
+ mErrorMsg = mErrorMsg + "\n " + sValue;
+ mWizardInfo.setRequestError("true");
+ }
+ }
+ else if ((iIndex=s.indexOf("errorDetails = ")) != (-1))
+ {
+ sName = s.substring(iIndex + 16).trim();
+ if ((iIndex = sName.indexOf("\"")) != (-1))
+ sValue = sName.substring(0,iIndex);
+
+ Debug.println("Parse input: name=" + sName + " output="
+ + sValue + " index=" + iIndex);
+ if (sValue != null && !sValue.equals("")) {
+ mErrorMsg = mErrorMsg + "\n " + sValue;
+ mWizardInfo.setRequestError("true");
+ }
+ }
+ else if ((iIndex=s.indexOf("result.recordSet.length = ")) != (-1))
+ {
+ sName = s.substring(iIndex + 27).trim();
+ if ((iIndex = sName.indexOf("\"")) != (-1))
+ sValue = sName.substring(0,iIndex);
+
+ Debug.println("Parse input: name=" + sName + " output="
+ + sValue + " index=" + iIndex);
+ if (sValue != null && !sValue.equals("") && !sValue.equals("0")) {
+ mErrorMsg = mErrorMsg + mResource.getString("REQUESTRESULTWIZARD_TEXT_DETAIL_LABEL");;
+ }
+ }
+ else if ((iIndex=s.indexOf("errorDescription = ")) != (-1))
+ {
+ sName = s.substring(iIndex + 20).trim();
+ if ((iIndex = sName.indexOf("\"")) != (-1))
+ sValue = sName.substring(0,iIndex);
+
+ Debug.println("Parse input: name=" + sName + " output="
+ + sValue + " index=" + iIndex);
+ if (sValue != null && !sValue.equals("")) {
+ mErrorMsg = mErrorMsg + "\n " + sValue;
+ }
+ }
+ else if ((iIndex=s.indexOf("record.policyMessage=")) != (-1))
+ {
+ sName = s.substring(iIndex + 22).trim();
+ if ((iIndex = sName.indexOf("\"")) != (-1))
+ sValue = sName.substring(0,iIndex);
+
+ Debug.println("Parse input: name=" + sName + " output="
+ + sValue + " index=" + iIndex);
+ if (sValue != null && !sValue.equals("")) {
+ if (mPolicyMsg == null)
+ mPolicyMsg = " " + sValue;
+ else
+ mPolicyMsg = mPolicyMsg + "\n " + sValue;
+ }
+ }
+
+ Debug.println("Parse finished");
+ }
+
+ /**
+ * Send an http request to the server. Return true if we're sure it
+ * succeeded, otherwise false.
+ */
+ boolean run(Hashtable args) {
+
+ String fullCmd = mWizardInfo.getCMEEType() + "://" +
+ mWizardInfo.getCMHost() + ":" +
+ mWizardInfo.getCMEEPort() + "/ca/ee/ca/profileSubmit";
+
+ HttpManager h = new HttpManager();
+ // tell the http manager to use UTF8 encoding
+ h.setSendUTF8(true);
+
+ try {
+ mSuccess = false;
+ mFinished = false;
+
+ ByteArrayInputStream data = null;
+ if (args != null && !args.isEmpty())
+ data = encode(args);
+ Debug.println( "Posting " + fullCmd );
+ // tell the http manager to notify us immediately of replies
+ // if we're using async mode
+ int flags = 0;
+ CommRecord postResult = null;
+ if (data == null)
+ postResult = h.post(new URL(fullCmd), this, null, null, 0,
+ flags);
+ else
+ postResult = h.post(new URL(fullCmd), this, null, data, data.available(),
+ flags);
+
+ /*
+ AdmTask admTask = new AdmTask(new URL(fullCmd),null,null);
+ admTask.setArguments(args);
+ admTask.exec(h);
+ */
+
+ awaitSuccess();
+
+ Object postStatus = postResult.getStatus();
+ //Debug.println("status: " + postStatus);
+ if (postStatus != null &&
+ postStatus.toString().equals(CommRecord.ERROR)) {
+ // If it happens to be it's not CMS server who is listening
+ // e.g. the cms agent port or yahoo server
+ // you may get here
+ mErrorMsg = mResource.getString("CGITASK_DIALOG_WRONGSERVER_MESSAGE");
+ }
+
+ Debug.println( "Command executed: " + fullCmd );
+ } catch (Exception e) {
+ // This is very fragile. We have to handle it case by case.
+ // Handled the ones that I know of properly, but there may
+ // be other cases that I don't know, display the exception
+ // detail.
+ String detail = e.toString();
+ if (detail == null || detail.trim().equals(""))
+ detail = "No detail of the exception provided.";
+ if ( e instanceof java.net.ConnectException ) {
+ mErrorMsg = mResource.getString("CGITASK_DIALOG_CMSDOWN_MESSAGE");
+ //CMSAdminUtil.showMessageDialog(mResource,
+ // PREFIX, "CMSDOWN", CMSAdminUtil.ERROR_MESSAGE);
+ } else if ( e instanceof java.net.NoRouteToHostException ) {
+ // java.net.NoRouteToHostException: Connection timed out
+ // It takes 3-4 mins to time out, looks like hang to impatient
+ // ones. https://www.netscape.com:443
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_CMSDOWN_MESSAGE")
+;
+ } else if ( e instanceof java.net.SocketException ) {
+ if (detail.indexOf("Socket write failed") > -1){
+ // retry
+ run(args);
+ } else if ((detail.indexOf("Connection shutdown") > -1) ||
+ (detail.indexOf("Connection timed out") > -1) ) {
+ // java.net.NoRouteToHostException: Connection timed out
+ // double insurance
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_CMSDOWN_MESSAGE");
+ } else {
+ // need to determine case by case
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_CMSDOWN_MESSAGE")+ " java.net.SocketException: " + detail;
+ }
+
+ } else if ( e instanceof java.io.IOException ) {
+ if (e.toString().indexOf("Broken pipe") > -1){
+ // broken pipe, retry
+ run(args);
+ } else if (detail.indexOf("Unknown public-key algorithm")
+> -1) {
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_UNKNOWNALG_MESSAGE")
+;
+ } else if (detail.indexOf("End of input") > -1) {
+ // http://www.netscape.com:80/enrollment
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_CMSDOWN_MESSAGE")
+;
+ } else if (detail.indexOf("Certificate fingerprint =") > -1) {
+ // reject the cms certificate
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_REJECTCERT_MESSAGE");
+ } else {
+ // need to determine case by case
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_CMSDOWN_MESSAGE"
+) + " java.io.IOException: " + detail;
+ }
+ } else {
+ // need to determine case by case
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_CMSDOWN_MESSAGE")
++ " Exception: " + detail;
+ }
+ Debug.println( "Command " + fullCmd + " failed: " + e );
+ }
+ return mSuccess;
+ }
+
+}
+
+
+
diff --git a/base/console/src/com/netscape/admin/certsrv/task/CMSConfigCert.java b/base/console/src/com/netscape/admin/certsrv/task/CMSConfigCert.java
new file mode 100644
index 000000000..7d85d161f
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/task/CMSConfigCert.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.admin.certsrv.task;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.management.client.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.config.install.*;
+import com.netscape.admin.certsrv.wizard.WizardBasePanel;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.topology.*;
+import com.netscape.management.client.comm.*;
+import java.net.*;
+import java.io.*;
+import netscape.ldap.*;
+import netscape.ldap.util.*;
+
+/**
+ * Perform certificate server configuration.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class CMSConfigCert extends CGITask {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "CMSCONFIGCERT";
+
+ public static final String CONFIG_CERT_CGI = "Tasks/Operation/config-cert";
+
+ //private boolean mSuccess = false; // status of last executed CGI
+ //private Hashtable mCgiResponse = null; // holds parsed contents of CGI return
+ private String mCgiTask = null; // CGI task to call
+ private InstallWizardInfo mWizardInfo;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSConfigCert() {
+ super();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void initialize(InstallWizardInfo info) {
+ _consoleInfo = info.getAdminConsoleInfo();
+
+ // the results coming back from the daemon will be added to the
+ // wizard information.
+ mWizardInfo = info;
+
+ setForceBasicAuth(true);
+ }
+
+ /**
+ * Collect the data in name value pairs format and then send them to the
+ * cgi process.
+ */
+ public boolean configCert(Hashtable data) {
+ JFrame mActiveFrame = UtilConsoleGlobals.getActivatedFrame();
+ if (_consoleInfo.get("AdminUsername") == null)
+ _consoleInfo.put("AdminUsername", _consoleInfo.getAuthenticationDN());
+ Debug.println("AdminUsername = " + _consoleInfo.get("AdminUsername"));
+
+ if (_consoleInfo.get("AdminUserPassword") == null)
+ _consoleInfo.put("AdminUserPassword",
+ _consoleInfo.getAuthenticationPassword());
+ Debug.println("AdminUserPassword = " + _consoleInfo.get("AdminUserPassword"));
+ data.put("AdminUserPassword", _consoleInfo.getAuthenticationPassword());
+ _consoleInfo.put("arguments", data);
+
+ // Send Random value for RNG entropy
+ data.put(ConfigConstants.PR_CMS_SEED, new Long(WizardBasePanel.mSeed).toString());
+
+ boolean status = false; // return value
+
+ Cursor cursor = mActiveFrame.getCursor();
+ int type = cursor.getType();
+ cursor = new Cursor(Cursor.WAIT_CURSOR);
+ mActiveFrame.setCursor(cursor);
+
+ try {
+ status = super.run(null, CONFIG_CERT_CGI);
+ } catch (Exception e) {
+ Debug.println("Unexpected Error"+e.toString());
+ status = false;
+ }
+ Debug.println("CMSConfigCert: configCert() after run status=" +
+ status + " mSuccess=" + mSuccess);
+
+ if (!mSuccess) {
+ Debug.println("Show error dialog");
+ String errorMsg = getErrorMessage();
+/*
+ if (errorMsg == null || errorMsg.equals(""))
+ CMSAdminUtil.showMessageDialog(mActiveFrame, mResource, PREFIX,
+ "SYSTEMERROR", CMSAdminUtil.ERROR_MESSAGE);
+ else
+ JOptionPane.showMessageDialog(mActiveFrame, errorMsg,
+ "Error", CMSAdminUtil.ERROR_MESSAGE,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_ERROR_ICON));
+*/
+ }
+
+ cursor = new Cursor(type);
+ mActiveFrame.setCursor(cursor);
+
+ return mSuccess;
+ }
+
+ /**
+ * the operation is finished after we receive the http stream
+ */
+ public void replyHandler(InputStream response, CommRecord cr) {
+ mSuccess = false;
+/*
+ if (mCgiResponse != null)
+ mCgiResponse.clear();
+*/
+
+ try {
+ BufferedReader rspStream =
+ new BufferedReader(new InputStreamReader(response, "UTF8"));
+ String rspStr;
+
+ Debug.println("CMSConfigCert: replyHandler() - start");
+ while ((rspStr = rspStream.readLine()) != null)
+ {
+ Debug.println("ConfigCert: replyHandler() - read [" + rspStr + "]");
+ // NMC_ messages are parsed, but not shown to the user
+ /*
+ if (_statusText != null && !rspStr.startsWith("NMC_")) {
+ _statusText.append(rspStr + "\n");
+ Thread.yield(); // allow graphics repaints
+ }
+ */
+ parse(rspStr);
+ }
+ } catch (Exception e) {
+ Debug.println("ConfigCert.Exception : " + e.toString());
+ }
+
+ Debug.println("ConfigCert.replyHandler: finished, mSuccess=" +
+ mSuccess);
+
+ finish();
+ }
+
+ /**
+ * return the value for the given keyword in the reply
+ */
+ private void parse(String s) {
+ String sName;
+ String sValue;
+ int iIndex;
+
+ Debug.println("Parse input: " + s);
+
+ if ((iIndex=s.indexOf(":")) != (-1))
+ {
+ sName = s.substring(0, iIndex).trim();
+ sValue = s.substring(iIndex+1).trim();
+ Debug.println("Parse input: name=" + sName + " value=" + sValue);
+ mWizardInfo.put(sName, sValue);
+/*
+ if (mCgiResponse == null)
+ mCgiResponse = new Hashtable();
+ mCgiResponse.put(sName, sValue);
+*/
+ if (sName.equalsIgnoreCase("NMC_Status"))
+ {
+ int code = Integer.parseInt(sValue);
+ mSuccess = (code == 0);
+ Debug.println("Parse input: code=" + code + " mSuccess=" + mSuccess);
+ } else if (sName.equalsIgnoreCase("NMC_ERRINFO"))
+ mErrorMsg = sValue;
+ Debug.println("ErrorMsg : " + mErrorMsg);
+ }
+
+ Debug.println("Parse finished");
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/task/CMSImportCert.java b/base/console/src/com/netscape/admin/certsrv/task/CMSImportCert.java
new file mode 100644
index 000000000..b285b2284
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/task/CMSImportCert.java
@@ -0,0 +1,429 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.task;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.management.client.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.config.install.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.topology.*;
+import com.netscape.management.client.comm.*;
+import java.net.*;
+import java.io.*;
+import netscape.ldap.*;
+import netscape.ldap.util.*;
+
+/**
+ * Perform certificate import.
+ *
+ * @author Michelle Zhao
+ * @version $Revision$, $Date$
+ */
+public class CMSImportCert extends CGITask {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "CGITASK";
+ private String mCgiTask = null; // CGI task to call
+ private InstallWizardInfo mWizardInfo;
+ private String mPolicyMsg = null;
+
+ // To support Thawte's header and footer
+ public static final String BEGIN_PKCS7_HEADER =
+ "-----BEGIN PKCS #7 SIGNED DATA-----";
+ public static final String END_PKCS7_HEADER =
+ "-----END PKCS #7 SIGNED DATA-----";
+ public static final String BEGIN_HEADER = "-----BEGIN CERTIFICATE-----";
+ public static final String END_HEADER = "-----END CERTIFICATE-----";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSImportCert() {
+ super();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void initialize(InstallWizardInfo info) {
+ Debug.println("CMSImportCert: initialize()");
+ _consoleInfo = info.getAdminConsoleInfo();
+
+ // the results coming back from the daemon will be added to the
+ // wizard information.
+ mWizardInfo = info;
+ }
+
+ /**
+ * Collect the data in name value pairs format and then send them to the
+ * cgi process.
+ */
+ public boolean importCert(Hashtable data) {
+ boolean status = false; // return value
+
+ try {
+ status = run(data);
+ } catch (Exception e) {
+ Debug.println("Unexpected Error"+e.toString());
+ status = false;
+ }
+ Debug.println("CMSImportCert: ImportCert() after run status=" +
+ status + " mSuccess=" + mSuccess);
+
+ return mSuccess;
+ }
+
+ /**
+ * the operation is finished after we receive the http stream
+ */
+ public void replyHandler(InputStream response, CommRecord cr) {
+ mSuccess = false;
+
+ try {
+ BufferedReader rspStream =
+ new BufferedReader(new InputStreamReader(response, "UTF8"));
+ String rspStr;
+
+ Debug.println("CMSImportCert: replyHandler() - start");
+
+ mWizardInfo.setImportError("");
+ while ((rspStr = rspStream.readLine()) != null && !mSuccess)
+ {
+ Debug.println("ImportCert: replyHandler() - read [" + rspStr + "]");
+ // NMC_ messages are parsed, but not shown to the user
+ parse(rspStr);
+ }
+
+ String importError = mWizardInfo.getImportError();
+ if (importError != null && !importError.equals("")) {
+ mErrorMsg = importError;
+ mSuccess = false;
+ } else if (!mSuccess) {
+ // agent port, Unauthorizied access
+ mErrorMsg = mResource.getString("CGITASK_DIALOG_WRONGSERVER_MESSAGE");
+ }
+ } catch (Exception e) {
+ Debug.println("ImportCert.Exception : " + e.toString());
+ }
+
+ Debug.println("ImportCert.replyHandler: finished, mSuccess=" +
+ mSuccess);
+
+ finish();
+ }
+
+ /**
+ * return the value for the given keyword in the reply
+ */
+ private void parse(String s) {
+ String sName;
+ String sValue = null;
+ int iIndex;
+
+ Debug.println("Parse input: " + s);
+
+ if ((iIndex=s.indexOf("status = ")) != (-1))
+ {
+ sName = s.substring(iIndex + 10).trim();
+ if ((iIndex = sName.indexOf("\"")) != (-1))
+ sValue = sName.substring(0,iIndex);
+
+ Debug.println("Parse input: name=" + sName + " output="
+ + sValue + " index=" + iIndex);
+ if (sValue != null && !sValue.equals("")) {
+ if (sValue.equals(ConfigConstants.PENDING_STRING) ||
+ sValue.equals(ConfigConstants.APPROVED_STRING) ||
+ sValue.equals(ConfigConstants.SVC_PENDING_STRING)) {
+ mWizardInfo.setImportError("Request " +
+ mWizardInfo.getRequestID() +
+ " is " + sValue +
+ ".\nYou can contact an authorized agent or local administrator for further assistance by referring to the request ID.");
+ mSuccess = true;
+ } else if (sValue.equals(ConfigConstants.CANCELED_STRING) ||
+ sValue.equals(ConfigConstants.REJECTED_STRING) ) {
+ String stage =
+ getStage(mWizardInfo.getCertType());
+ if (stage != null)
+ mWizardInfo.put(stage, ConfigConstants.FALSE);
+ mWizardInfo.setImportError("Request " +
+ mWizardInfo.getRequestID() +
+ " is " + sValue +
+ ".\nYou can contact an authorized agent or local administrator for further assistance by referring to the request ID." + "\nYou will be able to regenerate a new request if you click back." );
+ mSuccess = true;
+ }
+ }
+ }
+ else if ((iIndex=s.indexOf("pkcs7ChainBase64 = ")) != (-1))
+ {
+ sName = s.substring(iIndex + 20).trim();
+ if ((iIndex = sName.indexOf("\"")) != (-1))
+ sValue = sName.substring(0,iIndex);
+
+ Debug.println("Parse input: name=" + sName + " output="
+ + sValue + " index=" + iIndex);
+ if (sValue != null && !sValue.equals("")) {
+ String val = sValue.trim();
+ String result = normalizeCertStr(val);
+ Debug.println("After removing all the carriage returns:");
+ Debug.println(result);
+ mWizardInfo.setPKCS10(result);
+ mSuccess = true;
+
+ }
+ }
+ else if ((iIndex=s.indexOf("unexpectedError = ")) != (-1))
+ {
+ sName = s.substring(iIndex + 19).trim();
+ if ((iIndex = sName.indexOf("\"")) != (-1))
+ sValue = sName.substring(0,iIndex);
+
+ Debug.println("Parse input: name=" + sName + " output="
+ + sValue + " index=" + iIndex);
+ if (sValue != null && !sValue.equals("")) {
+ mErrorMsg = mErrorMsg + "\n " + sValue;
+ mWizardInfo.setRequestError("true");
+ }
+ }
+ else if ((iIndex=s.indexOf("errorDetails = ")) != (-1))
+ {
+ sName = s.substring(iIndex + 16).trim();
+ if ((iIndex = sName.indexOf("\"")) != (-1))
+ sValue = sName.substring(0,iIndex);
+
+ Debug.println("Parse input: name=" + sName + " output="
+ + sValue + " index=" + iIndex);
+ if (sValue != null && !sValue.equals("")) {
+ mErrorMsg = mErrorMsg + "\n " + sValue;
+ mWizardInfo.setRequestError("true");
+ }
+ }
+ else if ((iIndex=s.indexOf("result.recordSet.length = ")) != (-1))
+ {
+ sName = s.substring(iIndex + 27).trim();
+ if ((iIndex = sName.indexOf("\"")) != (-1))
+ sValue = sName.substring(0,iIndex);
+
+ Debug.println("Parse input: name=" + sName + " output="
+ + sValue + " index=" + iIndex);
+ if (sValue != null && !sValue.equals("") && !sValue.equals("0")) {
+ mErrorMsg = mErrorMsg + mResource.getString("REQUESTRESULTWIZARD_TEXT_DETAIL_LABEL");;
+ }
+ }
+ else if ((iIndex=s.indexOf("errorDescription = ")) != (-1))
+ {
+ sName = s.substring(iIndex + 20).trim();
+ if ((iIndex = sName.indexOf("\"")) != (-1))
+ sValue = sName.substring(0,iIndex);
+
+ Debug.println("Parse input: name=" + sName + " output="
+ + sValue + " index=" + iIndex);
+ if (sValue != null && !sValue.equals("")) {
+ mErrorMsg = mErrorMsg + "\n " + sValue;
+ }
+ }
+ else if ((iIndex=s.indexOf("record.policyMessage=")) != (-1))
+ {
+ sName = s.substring(iIndex + 22).trim();
+ if ((iIndex = sName.indexOf("\"")) != (-1))
+ sValue = sName.substring(0,iIndex);
+
+ Debug.println("Parse input: name=" + sName + " output="
+ + sValue + " index=" + iIndex);
+ if (sValue != null && !sValue.equals("")) {
+ if (mPolicyMsg == null)
+ mPolicyMsg = " " + sValue;
+ else
+ mPolicyMsg = mPolicyMsg + "\n " + sValue;
+ }
+ }
+
+ Debug.println("Parse finished");
+ }
+
+ /**
+ * Send an http request to the server. Return true if we're sure it
+ * succeeded, otherwise false.
+ */
+ boolean run(Hashtable args) {
+
+ String fullCmd = mWizardInfo.getCMEEType() + "://" +
+ mWizardInfo.getCMHost() + ":" +
+ mWizardInfo.getCMEEPort() + "/checkRequest";
+
+ HttpManager h = new HttpManager();
+ // tell the http manager to use UTF8 encoding
+ h.setSendUTF8(true);
+
+ try {
+ mSuccess = false;
+ mFinished = false;
+
+ ByteArrayInputStream data = null;
+ if (args != null && !args.isEmpty())
+ data = encode(args);
+ Debug.println( "Posting " + fullCmd );
+ // tell the http manager to notify us immediately of replies
+ // if we're using async mode
+ int flags = 0;
+ CommRecord postResult = null;
+ if (data == null)
+ postResult = h.post(new URL(fullCmd), this, null, null, 0,
+ flags);
+ else
+ postResult = h.post(new URL(fullCmd), this, null, data, data.available(),
+ flags);
+
+ /*
+ AdmTask admTask = new AdmTask(new URL(fullCmd),null,null);
+ admTask.setArguments(args);
+ admTask.exec(h);
+ */
+
+ awaitSuccess();
+
+ Object postStatus = postResult.getStatus();
+ //Debug.println("status: " + postStatus);
+ if (postStatus != null &&
+ postStatus.toString().equals(CommRecord.ERROR)) {
+ // If it happens to be it's not CMS server who is listening
+ // e.g. the cms agent port or yahoo server
+ // you may get here
+ mErrorMsg = mResource.getString("CGITASK_DIALOG_WRONGSERVER_MESSAGE");
+ }
+
+ Debug.println( "Command executed: " + fullCmd );
+ } catch (Exception e) {
+ // This is very fragile. We have to handle it case by case.
+ // Handled the ones that I know of properly, but there may
+ // be other cases that I don't know, display the exception
+ // detail.
+ String detail = e.toString();
+ if (detail == null || detail.trim().equals(""))
+ detail = "No detail of the exception provided.";
+ if ( e instanceof java.net.ConnectException ) {
+ mErrorMsg = mResource.getString("CGITASK_DIALOG_CMSDOWN_MESSAGE");
+ //CMSAdminUtil.showMessageDialog(mResource,
+ // PREFIX, "CMSDOWN", CMSAdminUtil.ERROR_MESSAGE);
+ } else if ( e instanceof java.net.NoRouteToHostException ) {
+ // java.net.NoRouteToHostException: Connection timed out
+ // It takes 3-4 mins to time out, looks like hang to impatient
+ // ones. https://www.netscape.com:443
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_CMSDOWN_MESSAGE")
+;
+ } else if ( e instanceof java.net.SocketException ) {
+ if (detail.indexOf("Socket write failed") > -1){
+ // retry
+ run(args);
+ } else if ((detail.indexOf("Connection shutdown") > -1) ||
+ (detail.indexOf("Connection timed out") > -1) ) {
+ // java.net.NoRouteToHostException: Connection timed out
+ // double insurance
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_CMSDOWN_MESSAGE");
+ } else {
+ // need to determine case by case
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_CMSDOWN_MESSAGE")+ " java.net.SocketException: " + detail;
+ }
+
+ } else if ( e instanceof java.io.IOException ) {
+ if (e.toString().indexOf("Broken pipe") > -1){
+ // broken pipe, retry
+ run(args);
+ } else if (detail.indexOf("Unknown public-key algorithm")
+> -1) {
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_UNKNOWNALG_MESSAGE")
+;
+ } else if (detail.indexOf("End of input") > -1) {
+ // http://www.netscape.com:80/enrollment
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_CMSDOWN_MESSAGE")
+;
+ } else if (detail.indexOf("Certificate fingerprint =") > -1) {
+ // reject the cms certificate
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_REJECTCERT_MESSAGE");
+ } else {
+ // need to determine case by case
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_CMSDOWN_MESSAGE"
+) + " java.io.IOException: " + detail;
+ }
+ } else {
+ // need to determine case by case
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_CMSDOWN_MESSAGE")
++ " Exception: " + detail;
+ }
+ Debug.println( "Command " + fullCmd + " failed: " + e );
+ }
+ return mSuccess;
+ }
+
+ String getStage(String reqType){
+ if (reqType.equals(Constants.PR_CA_SIGNING_CERT)){
+ return ConfigConstants.STAGE_CA_REQ_SUCCESS;
+ }else if (reqType.equals(Constants.PR_SERVER_CERT)){
+ return ConfigConstants.STAGE_SSL_REQ_SUCCESS;
+ }else if (reqType.equals(Constants.PR_KRA_TRANSPORT_CERT)){
+ return ConfigConstants.STAGE_KRA_REQ_SUCCESS;
+ }else if (reqType.equals(Constants.PR_RA_SIGNING_CERT)){
+ return ConfigConstants.STAGE_RA_REQ_SUCCESS;
+ }else if (reqType.equals(Constants.PR_OCSP_SIGNING_CERT)){
+ return ConfigConstants.STAGE_OCSP_REQ_SUCCESS;
+ }else
+ return null;
+ }
+
+
+ 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) == '\\' && s.charAt(i+1) == 'r') {
+ i++;
+ continue;
+ } else if (s.charAt(i) == '"') {
+ continue;
+ } else if (s.charAt(i) == ' ') {
+ continue;
+ }
+ val += s.charAt(i);
+ }
+ return val;
+ }
+
+}
+
+
diff --git a/base/console/src/com/netscape/admin/certsrv/task/CMSMigrateCreate.java b/base/console/src/com/netscape/admin/certsrv/task/CMSMigrateCreate.java
new file mode 100644
index 000000000..c7ff02c36
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/task/CMSMigrateCreate.java
@@ -0,0 +1,340 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.task;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.management.client.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.topology.*;
+import com.netscape.management.client.comm.*;
+import java.net.*;
+import java.io.*;
+import netscape.ldap.*;
+import netscape.ldap.util.*;
+
+/**
+ * Create or Migrate the Certificate Server
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class CMSMigrateCreate extends CGITask
+ implements IProductObject
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "CMSMIGRATECREATE";
+
+ private static final String CREATE_CGI_NAME = "Tasks/Operation/Create";
+
+ //private boolean mSuccess = false; // status of last executed CGI
+ private Hashtable mCgiResponse = null; // holds parsed contents of CGI return
+ private String mCgiTask = null; // CGI task to call
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSMigrateCreate() {
+ super();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void initialize(ConsoleInfo info) {
+ Debug.println("CMSMigrateCreate: initialize()");
+ _consoleInfo = info;
+ }
+
+ public boolean migrate(String serverRoot,
+ String server,
+ String targetDN,
+ boolean flag) {
+
+ Debug.println("CMSMigrateCreate: migrate()");
+
+ return false;
+ }
+
+ /**
+ * Starts the server specific creation code, providing the DN for the
+ * target admin group. The method returns true or false depending
+ * on whether it was successful.
+ *
+ * @param targetDN - the admin group DN where the new instance is to be
+ * created.
+ * @return boolean value indicating whether the process succeeded (true)
+ * or failed (false).
+ */
+ public boolean createNewInstance(String targetDN) {
+ //Debug.println("CMSMigrateCreate: createNewInstance()- "+targetDN);
+ //targetDN: cn=Server Group, cn=cynthiar.mcom.com, ou=mcom.com, o=NetscapeRoot
+
+ JFrame mActiveFrame = UtilConsoleGlobals.getActivatedFrame();
+ boolean status = false; // return value
+ //show dialog
+ CreateInstanceDialog dialog = new CreateInstanceDialog(mActiveFrame);
+ // UtilConsoleGlobals.getActivatedFrame());
+ dialog.show();
+ if (dialog.isCancel()) {
+ return status;
+ }
+
+ //construct the rest of the configuration parameters
+ //serverName=cynthiar.mcom.com
+ //sieURL=ldap://laiking.mcom.com:389/o=netscapeRoot
+ //adminUID=admin
+ //adminPWD=admin
+ //instanceID=cert-data
+ //serverRoot=/u/thomask/s4
+ //adminDomain=mcom.com
+
+ Hashtable configParams = new Hashtable();
+
+ configParams.put("instanceID",dialog.getInstanceName());
+
+ String[] entries = LDAPDN.explodeDN(targetDN, false);
+ String DN = entries[entries.length-3] + ", " +
+ entries[entries.length-2] + ", " +
+ entries[entries.length-1];
+
+ //DN: cn=cynthiar.mcom.com, ou=mcom.com, o=NetscapeRoot
+
+ configParams.put("machineName", getValue(DN, "serverHostName",
+ LDAPConnection.SCOPE_BASE, null));
+ configParams.put("serverRoot", getValue(targetDN, "nsconfigroot",
+ LDAPConnection.SCOPE_BASE, null));
+ LDAPConnection ldc = _consoleInfo.getLDAPConnection();
+ String ssdn = ldc.getAuthenticationDN();
+ String[] avas = LDAPDN.explodeDN(ssdn, false);
+ String uid = avas[0];
+ if (!uid.startsWith("uid")) {
+ CMSAdminUtil.showMessageDialog(mActiveFrame,
+ mResource, PREFIX, "RESTARTADMINERROR",
+ CMSAdminUtil.ERROR_MESSAGE);
+ return false;
+ }
+ configParams.put("adminUID", uid.substring(4,uid.length()));
+
+ configParams.put("adminPWD",ldc.getAuthenticationPassword());
+ String ldapUrl = "ldap://" + ldc.getHost() + ":" +
+ Integer.toString(ldc.getPort()) + "/" +
+ (String)_consoleInfo.get("BaseDN");
+ configParams.put("sieURL", ldapUrl);
+
+ String searchDN = entries[entries.length-2];
+ configParams.put("adminDomain", searchDN.substring(3,searchDN.length()));
+
+ Debug.println("CMSMigrateCreate: createNewInstance()- "+configParams.toString());
+
+ // set the arguments for the CGI call
+ _consoleInfo.put("arguments", configParams);
+ _consoleInfo.put(CREATE_CGI_NAME, "cert");
+ if (_consoleInfo.get("AdminUsername") == null)
+ _consoleInfo.put("AdminUsername", _consoleInfo.getAuthenticationDN());
+ Debug.println("AdminUsername = " + _consoleInfo.get("AdminUsername"));
+
+ if (_consoleInfo.get("AdminUserPassword") == null)
+ _consoleInfo.put("AdminUserPassword",
+ _consoleInfo.getAuthenticationPassword());
+ Debug.println("AdminUserPassword = " + _consoleInfo.get("AdminUserPassword"));
+
+ // call the CGI program
+ Debug.println("CMSMigrateCreate: createNewInstance() before run task="+CREATE_CGI_NAME);
+ mCgiTask = CREATE_CGI_NAME;
+
+ Cursor cursor = mActiveFrame.getCursor();
+ int type = cursor.getType();
+ cursor = new Cursor(Cursor.WAIT_CURSOR);
+ mActiveFrame.setCursor(cursor);
+
+ try {
+ status = super.run(null, CREATE_CGI_NAME);
+ } catch (Exception e) {
+ Debug.println("Unexpected Error"+e.toString());
+ status = false;
+ }
+
+ Debug.println("CMSMigrateCreate: createNewInstance() after run status=" +
+ status + " mSuccess=" + mSuccess);
+
+ if (!mSuccess) {
+ Debug.println("Show error dialog");
+ String errorMsg = getErrorMessage();
+ if (errorMsg == null || errorMsg.equals(""))
+ CMSAdminUtil.showMessageDialog(mActiveFrame, mResource, PREFIX,
+ "SYSTEMERROR", CMSAdminUtil.ERROR_MESSAGE);
+ else
+ JOptionPane.showMessageDialog(mActiveFrame, errorMsg,
+ "Error", CMSAdminUtil.ERROR_MESSAGE,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_ERROR_ICON));
+ }
+
+ cursor = new Cursor(type);
+ mActiveFrame.setCursor(cursor);
+
+ return mSuccess;
+ }
+
+ /**
+ * the operation is finished after we receive the http stream
+ */
+ public void replyHandler(InputStream response, CommRecord cr) {
+ mSuccess = false;
+ if (mCgiResponse != null)
+ mCgiResponse.clear();
+
+ try {
+ BufferedReader rspStream =
+ new BufferedReader(new InputStreamReader(response, "UTF8"));
+ String rspStr;
+
+ Debug.println("CMSMigrateCreate: replyHandler() - start");
+ while ((rspStr = rspStream.readLine()) != null)
+ {
+ Debug.println("CMSMigrateCreate: replyHandler() - read [" + rspStr + "]");
+ // NMC_ messages are parsed, but not shown to the user
+ /*
+ if (_statusText != null && !rspStr.startsWith("NMC_")) {
+ _statusText.append(rspStr + "\n");
+ Thread.yield(); // allow graphics repaints
+ }
+ */
+ parse(rspStr);
+ }
+ } catch (Exception e) {
+ Debug.println("MigrateCreate.replyHandler: " + e.toString());
+ }
+
+ Debug.println("MigrateCreate.replyHandler: finished, mSuccess=" +
+ mSuccess);
+
+ finish();
+ }
+
+ /**
+ * return the value for the given keyword in the reply
+ */
+ private void parse(String s) {
+ String sName;
+ String sValue;
+ int iIndex;
+
+ Debug.println("Parse input: " + s);
+
+ if ((iIndex=s.indexOf(":")) != (-1))
+ {
+ sName = s.substring(0, iIndex).trim();
+ sValue = s.substring(iIndex+1).trim();
+ Debug.println("Parse input: name=" + sName + " value=" + sValue);
+ if (mCgiResponse == null)
+ mCgiResponse = new Hashtable();
+ mCgiResponse.put(sName, sValue);
+ if (sName.equalsIgnoreCase("NMC_Status")) {
+ int code = Integer.parseInt(sValue);
+ mSuccess = (code == 0);
+ Debug.println("Parse input: code=" + code + " mSuccess=" + mSuccess);
+ } else if (sName.equalsIgnoreCase("NMC_ERRINFO")) {
+ mErrorMsg = sValue;
+ }
+ }
+
+ Debug.println("Parse finished");
+ }
+
+ /**
+ * Get one value for one specified attribute from the given DN.
+ * If there is more than 1 entry which matches the given criteria, the
+ * first one will be used.
+ *
+ * @param DN DN of the entry with the specified attributes
+ * @param attr Attribute to get the value of
+ * @param scope LDAPConnection SCOPE_BASE SCOPE_ONE SCOPE_SUB
+ * @param filter LDAP search filter; if null, default is objectclass=*
+ * @return The string value of the attribute; multi-valued
+ * attributes are returned as 1 value, space delimited
+ * (flattened)
+ **/
+ protected String getValue(String DN, String attr, int scope,
+ String filter) {
+ String[] attrs = { attr };
+ String[] values = getValues(DN, attrs, scope, filter);
+ if (values != null)
+ return values[0];
+
+ return null;
+ }
+
+ /**
+ * Get the values for several specified attributes from the given DN.
+ * If there is more than 1 entry which matches the given criteria, the
+ * first one will be used.
+ *
+ * @param DN DN of the entry with the specified attributes
+ * @param attrs Array of attributes to get the values of
+ * @param scope LDAPConnection SCOPE_BASE SCOPE_ONE SCOPE_SUB
+ * @param filter LDAP search filter; if null, default is objectclass=*
+ * @return An array of string values for each attribute; multi-valued
+ * attributes are returned as 1 value, space delimited
+ * (flattened)
+ **/
+ protected String[] getValues(String DN, String[] attrs, int scope,
+ String filter) {
+ String[] values = null;
+ LDAPSearchResults results = null;
+ if (filter == null)
+ filter = "(objectclass=*)";
+
+ try {
+ LDAPConnection ldc = _consoleInfo.getLDAPConnection();
+ if (ldc != null)
+ {
+ results = ldc.search(DN, scope, filter, attrs, false);
+ }
+ } catch (LDAPException e) {
+ Debug.println("error MigrateCreate.getValues: LDAP read failed " +
+ "for DN=" + DN + " attributes " + attrs);
+ Debug.println("error MigrateCreate.getValues: LDAP Exception:" +
+ e);
+ }
+
+ if (results != null && results.hasMoreElements()) {
+ values = new String[attrs.length];
+ LDAPEntry entry = (LDAPEntry)results.nextElement();
+ for (int ii = 0; entry != null && ii < attrs.length; ++ii) {
+ values[ii] = LDAPUtil.flatting(entry.getAttribute(attrs[ii]));
+ }
+ } else {
+ Debug.println("error MigrateCreate.getValues: LDAP read failed " +
+ "for DN=" + DN + " attributes=" + attrs);
+ }
+
+ return values;
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/task/CMSRemove.java b/base/console/src/com/netscape/admin/certsrv/task/CMSRemove.java
new file mode 100644
index 000000000..57473c5e0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/task/CMSRemove.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.admin.certsrv.task;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.console.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+import netscape.ldap.*;
+
+/**
+ * Remove the server
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class CMSRemove extends CGITask
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "TASKREMOVE";
+ public static final String REMOVE_TASK_CGI = "Tasks/Operation/remove";
+ private Hashtable mCgiResponse = null;
+ private String mCgiTask = null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ public CMSRemove() {
+ super();
+ setName(mResource.getString(PREFIX+"_REMOVE_LABEL"));
+ setDescription(mResource.getString(PREFIX+"_REMOVE_DESC"));
+ }
+
+ public void initialize(ConsoleInfo info) {
+ Debug.println("CMSRemove: initialize()");
+ _consoleInfo = info;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public boolean run(IPage viewInstance)
+ {
+ Debug.println("CMSRemove: run()");
+ boolean status = false; // return value
+ Hashtable configParams = new Hashtable();
+ configParams.put("serverRoot",_consoleInfo.get("serverRoot"));
+ String servid = (String)_consoleInfo.get("servid");
+ int index = servid.indexOf("-");
+ if (index != -1) {
+ servid = servid.substring(index+1);
+ }
+ configParams.put("instanceID", servid);
+
+ // get the CMS instance host and port
+ servid = (String)_consoleInfo.get("servid");
+ String configDN = _consoleInfo.getCurrentDN();
+
+ try {
+ LDAPConnection ldc = _consoleInfo.getLDAPConnection();
+ if (ldc == null) {
+ ldc = new LDAPConnection();
+ }
+ if (ldc.isConnected() == false) {
+ ldc.connect(_consoleInfo.getHost(), _consoleInfo.getPort(),
+ _consoleInfo.getAuthenticationDN(),
+ _consoleInfo.getAuthenticationPassword());
+ }
+ LDAPEntry entry = ldc.read(configDN);
+ String cmsHost = LDAPUtil.flatting(
+ entry.getAttribute("serverHostName",
+ LDAPUtil.getLDAPAttributeLocale()));
+ String cmsPort = LDAPUtil.flatting(
+ entry.getAttribute("nsServerPort",
+ LDAPUtil.getLDAPAttributeLocale()));
+
+ Debug.println("host:" + cmsHost+" port:"+cmsPort);
+ configParams.put("cmsHost", cmsHost);
+ configParams.put("cmsPort", cmsPort);
+ }
+ catch (LDAPException e) {
+ Debug.println(
+ "ERROR CMSRemove: LDAP read failed: " +
+ configDN);
+ }
+ _consoleInfo.put("arguments", configParams);
+
+ String authdn = _consoleInfo.getAuthenticationDN();
+
+ if (_consoleInfo.get("AdminUsername") == null)
+ _consoleInfo.put("AdminUsername", authdn);
+
+ if (!authdn.startsWith("uid")) {
+ JFrame mActiveFrame = UtilConsoleGlobals.getActivatedFrame();
+ CMSAdminUtil.showMessageDialog(mActiveFrame,
+ mResource, PREFIX, "RESTARTADMINERROR",
+ CMSAdminUtil.ERROR_MESSAGE);
+ return false;
+ }
+
+ Debug.println("AdminUsername = " + _consoleInfo.get("AdminUsername"));
+
+ if (_consoleInfo.get("AdminUserPassword") == null)
+ _consoleInfo.put("AdminUserPassword",
+ _consoleInfo.getAuthenticationPassword());
+ Debug.println("AdminUserPassword = " + _consoleInfo.get("AdminUserPassword"));
+ // call the CGI program
+ Debug.println("CMSRemove: remove() before run task="+REMOVE_TASK_CGI);
+ try {
+ status = super.run(null, REMOVE_TASK_CGI);
+ } catch (Exception e) {
+ Debug.println("Unexpected Error"+e.toString());
+ status = false;
+ }
+ Debug.println("CMSRemove: remove() after run status="+status);
+
+ String title = mResource.getString("REMOVERESULTDIALOG_TITLE");
+
+ if (!status) {
+ Debug.println("Show error dialog");
+ // if no error message from the server, then just show the generic
+ // error message.
+ if (mErrorMsg.equals(""))
+ CMSAdminUtil.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(),
+ mResource, PREFIX, "SYSTEMERROR", CMSAdminUtil.ERROR_MESSAGE);
+ else {
+ String errorMsg =
+ mResource.getString("REMOVERESULTDIALOG_FAILED_TEXT")+mErrorMsg;
+ Icon icon = CMSAdminUtil.getImage(CMSAdminResources.IMAGE_ERROR_ICON);
+ JOptionPane.showMessageDialog(UtilConsoleGlobals.getActivatedFrame(),
+ errorMsg, title, JOptionPane.ERROR_MESSAGE, icon);
+ }
+ } else {
+ Debug.println("Successful operation");
+ String msg = mResource.getString("REMOVERESULTDIALOG_SUCCESS_TEXT");
+ Icon icon = CMSAdminUtil.getImage(CMSAdminResources.IMAGE_INFO_ICON);
+ JOptionPane.showMessageDialog(UtilConsoleGlobals.getActivatedFrame(),
+ msg, title, JOptionPane.INFORMATION_MESSAGE, icon);
+ }
+ return status;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/task/CMSRequestCert.java b/base/console/src/com/netscape/admin/certsrv/task/CMSRequestCert.java
new file mode 100644
index 000000000..8b3cfef6b
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/task/CMSRequestCert.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.admin.certsrv.task;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.management.client.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.config.install.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.topology.*;
+import com.netscape.management.client.comm.*;
+import java.net.*;
+import java.io.*;
+import netscape.ldap.*;
+import netscape.ldap.util.*;
+
+/**
+ * Perform certificate request.
+ *
+ * @author Michelle Zhao
+ * @version $Revision$, $Date$
+ */
+public class CMSRequestCert extends CGITask {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "CGITASK";
+ private String mCgiTask = null; // CGI task to call
+ private InstallWizardInfo mWizardInfo;
+ private String mPolicyMsg = null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSRequestCert() {
+ super();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void initialize(InstallWizardInfo info) {
+ Debug.println("CMSRequestCert: initialize()");
+ _consoleInfo = info.getAdminConsoleInfo();
+
+ // the results coming back from the daemon will be added to the
+ // wizard information.
+ mWizardInfo = info;
+ }
+
+ /**
+ * Collect the data in name value pairs format and then send them to the
+ * cgi process.
+ */
+ public boolean requestCert(Hashtable data) {
+ boolean status = false; // return value
+
+ try {
+ status = run(data);
+ } catch (Exception e) {
+ Debug.println("Unexpected Error"+e.toString());
+ status = false;
+ }
+ Debug.println("CMSRequestCert: requestCert() after run status=" +
+ status + " mSuccess=" + mSuccess);
+
+ return mSuccess;
+ }
+
+ /**
+ * the operation is finished after we receive the http stream
+ */
+ public void replyHandler(InputStream response, CommRecord cr) {
+ mSuccess = false;
+
+ try {
+ BufferedReader rspStream =
+ new BufferedReader(new InputStreamReader(response, "UTF8"));
+ String rspStr;
+
+ Debug.println("CMSRequestCert: replyHandler() - start");
+ mErrorMsg = mResource.getString("REQUESTRESULTWIZARD_TEXT_ERRORDESC_LABEL");
+ while ((rspStr = rspStream.readLine()) != null && !mSuccess)
+ {
+ Debug.println("RequestCert: replyHandler() - read [" + rspStr + "]");
+ // NMC_ messages are parsed, but not shown to the user
+ parse2(rspStr);
+ }
+ mErrorMsg = mErrorMsg +
+ mResource.getString("REQUESTRESULTWIZARD_TEXT_ERROREND_LABEL");
+ String requestStatus =mWizardInfo.getRequestStatus();
+ if ((mWizardInfo.getRequestError() != null) &&
+ mWizardInfo.getRequestError().equals("true")) {
+ mWizardInfo.setRequestError(mErrorMsg);
+ mErrorMsg = null;
+ mSuccess = true;
+ } else if (requestStatus == null) {
+ // agent port, Unauthorizied access
+ mErrorMsg = mResource.getString("CGITASK_DIALOG_WRONGSERVER_MESSAGE");
+ } else if (requestStatus.equals("5")) {
+ // rejected
+ if (mPolicyMsg == null) {
+ mWizardInfo.setRequestError(mResource.getString("REQUESTRESULTWIZARD_TEXT_NODETAIL_LABEL"));
+ } else {
+ mWizardInfo.setRequestError(mPolicyMsg);
+ mPolicyMsg = null;
+ }
+ mSuccess = true;
+ }
+ // Use the same format for other status:success,pending,svcPending
+ } catch (Exception e) {
+ Debug.println("RequestCert.Exception : " + e.toString());
+ }
+
+ Debug.println("RequestCert.replyHandler: finished, mSuccess=" +
+ mSuccess);
+
+ finish();
+ }
+
+
+ private void parse2(String s)
+ {
+ int iIndex;
+ Debug.println("Parse2 input: " + s);
+ if ((iIndex=s.indexOf("errorCode")) != (-1))
+ {
+ String errorCode = s.substring(s.indexOf("\"") + 1,
+ s.lastIndexOf("\""));
+ Debug.println("errorCode: " + errorCode);
+ if (errorCode.equals("2")) { // pending
+ mWizardInfo.setRequestError("false");
+ mSuccess = true;
+ mWizardInfo.setRequestStatus("0");
+ } else if (errorCode.equals("1")) { // error
+ mWizardInfo.setRequestError("true");
+ mWizardInfo.setRequestStatus("5");
+ mSuccess = false;
+ } else {
+ mWizardInfo.setRequestError("true");
+ mWizardInfo.setRequestStatus("0");
+ mSuccess = false;
+ }
+ }
+ else if ((iIndex=s.indexOf("requestList.requestId")) != (-1))
+ {
+ String requestId = s.substring(s.indexOf("\"") + 1,
+ s.lastIndexOf("\""));
+ Debug.println("requestId: " + requestId);
+ mWizardInfo.setRequestID(requestId);
+ }
+ else if ((iIndex=s.indexOf("errorReason")) != (-1))
+ {
+ String errorReason = s.substring(s.indexOf("\"") + 1,
+ s.lastIndexOf("\""));
+ Debug.println("errorReason: " + errorReason);
+ mErrorMsg = mErrorMsg + "\n " + errorReason;
+ }
+ }
+
+
+
+ /**
+ * return the value for the given keyword in the reply
+ */
+ private void parse(String s) {
+ String sName;
+ String sValue = null;
+ int iIndex;
+
+ Debug.println("Parse input: " + s);
+
+ if ((iIndex=s.indexOf("requestStatus = ")) != (-1))
+ {
+ sName = s.substring(iIndex + 17).trim();
+ if ((iIndex = sName.indexOf("\"")) != (-1))
+ sValue = sName.substring(0,iIndex);
+
+ Debug.println("Parse input: name=" + sName + " output="
+ + sValue + " index=" + iIndex);
+ if (sValue != null && !sValue.equals("")) {
+ mWizardInfo.setRequestStatus(sValue);
+ if (sValue.equals("2") || sValue.equals("3")
+ || sValue.equals("4")){
+ //mSuccess = true;
+ }
+ }
+ }
+ else if ((iIndex=s.indexOf("requestId = ")) != (-1))
+ {
+ sName = s.substring(iIndex + 13).trim();
+ if ((iIndex = sName.indexOf("\"")) != (-1))
+ sValue = sName.substring(0,iIndex);
+
+ Debug.println("Parse input: name=" + sName + " output="
+ + sValue + " index=" + iIndex);
+ if (sValue != null && !sValue.equals("")) {
+ mWizardInfo.setRequestID(sValue);
+ //mSuccess = true;
+ }
+ }
+ else if ((iIndex=s.indexOf("unexpectedError = ")) != (-1))
+ {
+ sName = s.substring(iIndex + 19).trim();
+ if ((iIndex = sName.indexOf("\"")) != (-1))
+ sValue = sName.substring(0,iIndex);
+
+ Debug.println("Parse input: name=" + sName + " output="
+ + sValue + " index=" + iIndex);
+ if (sValue != null && !sValue.equals("")) {
+ mErrorMsg = mErrorMsg + "\n " + sValue;
+ mWizardInfo.setRequestError("true");
+ }
+ }
+ else if ((iIndex=s.indexOf("errorDetails = ")) != (-1))
+ {
+ sName = s.substring(iIndex + 16).trim();
+ if ((iIndex = sName.indexOf("\"")) != (-1))
+ sValue = sName.substring(0,iIndex);
+
+ Debug.println("Parse input: name=" + sName + " output="
+ + sValue + " index=" + iIndex);
+ if (sValue != null && !sValue.equals("")) {
+ mErrorMsg = mErrorMsg + "\n " + sValue;
+ mWizardInfo.setRequestError("true");
+ }
+ }
+ else if ((iIndex=s.indexOf("result.recordSet.length = ")) != (-1))
+ {
+ sName = s.substring(iIndex + 27).trim();
+ if ((iIndex = sName.indexOf("\"")) != (-1))
+ sValue = sName.substring(0,iIndex);
+
+ Debug.println("Parse input: name=" + sName + " output="
+ + sValue + " index=" + iIndex);
+ if (sValue != null && !sValue.equals("") && !sValue.equals("0")) {
+ mErrorMsg = mErrorMsg + mResource.getString("REQUESTRESULTWIZARD_TEXT_DETAIL_LABEL");;
+ }
+ }
+ else if ((iIndex=s.indexOf("errorDescription = ")) != (-1))
+ {
+ sName = s.substring(iIndex + 20).trim();
+ if ((iIndex = sName.indexOf("\"")) != (-1))
+ sValue = sName.substring(0,iIndex);
+
+ Debug.println("Parse input: name=" + sName + " output="
+ + sValue + " index=" + iIndex);
+ if (sValue != null && !sValue.equals("")) {
+ mErrorMsg = mErrorMsg + "\n " + sValue;
+ }
+ }
+ else if ((iIndex=s.indexOf("record.policyMessage=")) != (-1))
+ {
+ sName = s.substring(iIndex + 22).trim();
+ if ((iIndex = sName.indexOf("\"")) != (-1))
+ sValue = sName.substring(0,iIndex);
+
+ Debug.println("Parse input: name=" + sName + " output="
+ + sValue + " index=" + iIndex);
+ if (sValue != null && !sValue.equals("")) {
+ if (mPolicyMsg == null)
+ mPolicyMsg = " " + sValue;
+ else
+ mPolicyMsg = mPolicyMsg + "\n " + sValue;
+ }
+ }
+ else if ((iIndex=s.indexOf("/HTML")) != (-1))
+ mSuccess = true; // no need to parse further
+
+ Debug.println("Parse finished");
+ }
+
+ /**
+ * Send an http request to the server. Return true if we're sure it
+ * succeeded, otherwise false.
+ */
+ boolean run(Hashtable args) {
+
+ String fullCmd = mWizardInfo.getCMEEType() + "://" +
+ mWizardInfo.getCMHost() + ":" +
+ mWizardInfo.getCMEEPort() + "/ca/ee/ca/profileSubmit";
+
+ HttpManager h = new HttpManager();
+ // tell the http manager to use UTF8 encoding
+ h.setSendUTF8(true);
+
+ try {
+ mSuccess = false;
+ mFinished = false;
+
+ ByteArrayInputStream data = null;
+ if (args != null && !args.isEmpty())
+ data = encode(args);
+ Debug.println( "Posting " + fullCmd );
+ // tell the http manager to notify us immediately of replies
+ // if we're using async mode
+ int flags = 0;
+ CommRecord postResult = null;
+ if (data == null)
+ postResult = h.post(new URL(fullCmd), this, null, null, 0,
+ flags);
+ else
+ postResult = h.post(new URL(fullCmd), this, null, data, data.available(),
+ flags);
+
+ /*
+ AdmTask admTask = new AdmTask(new URL(fullCmd),null,null);
+ admTask.setArguments(args);
+ admTask.exec(h);
+ */
+
+ awaitSuccess();
+
+ Object postStatus = postResult.getStatus();
+ //Debug.println("status: " + postStatus);
+ if (postStatus != null &&
+ postStatus.toString().equals(CommRecord.ERROR)) {
+ // If it happens to be it's not CMS server who is listening
+ // e.g. the cms agent port or yahoo server
+ // you may get here
+ mErrorMsg = mResource.getString("CGITASK_DIALOG_WRONGSERVER_MESSAGE");
+ }
+
+ Debug.println( "Command executed: " + fullCmd );
+ } catch (Exception e) {
+ // This is very fragile. We have to handle it case by case.
+ // Handled the ones that I know of properly, but there may
+ // be other cases that I don't know, display the exception
+ // detail.
+ String detail = e.toString();
+ if (detail == null || detail.trim().equals(""))
+ detail = "No detail of the exception provided.";
+ if ( e instanceof java.net.ConnectException ) {
+ mErrorMsg = mResource.getString("CGITASK_DIALOG_CMSDOWN_MESSAGE");
+ //CMSAdminUtil.showMessageDialog(mResource,
+ // PREFIX, "CMSDOWN", CMSAdminUtil.ERROR_MESSAGE);
+ } else if ( e instanceof java.net.NoRouteToHostException ) {
+ // java.net.NoRouteToHostException: Connection timed out
+ // It takes 3-4 mins to time out, looks like hang to impatient
+ // ones. https://www.netscape.com:443
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_CMSDOWN_MESSAGE")
+;
+ } else if ( e instanceof java.net.SocketException ) {
+ if (detail.indexOf("Socket write failed") > -1){
+ // retry
+ run(args);
+ } else if ((detail.indexOf("Connection shutdown") > -1) ||
+ (detail.indexOf("Connection timed out") > -1) ) {
+ // java.net.NoRouteToHostException: Connection timed out
+ // double insurance
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_CMSDOWN_MESSAGE");
+ } else {
+ // need to determine case by case
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_CMSDOWN_MESSAGE")+ " java.net.SocketException: " + detail;
+ }
+
+ } else if ( e instanceof java.io.IOException ) {
+ if (e.toString().indexOf("Broken pipe") > -1){
+ // broken pipe, retry
+ run(args);
+ } else if (detail.indexOf("Unknown public-key algorithm")
+> -1) {
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_UNKNOWNALG_MESSAGE")
+;
+ } else if (detail.indexOf("End of input") > -1) {
+ // http://www.netscape.com:80/enrollment
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_CMSDOWN_MESSAGE")
+;
+ } else if (detail.indexOf("Certificate fingerprint =") > -1) {
+ // reject the cms certificate
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_REJECTCERT_MESSAGE");
+ } else {
+ // need to determine case by case
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_CMSDOWN_MESSAGE"
+) + " java.io.IOException: " + detail;
+ }
+ } else {
+ // need to determine case by case
+ mErrorMsg =
+ mResource.getString("CGITASK_DIALOG_CMSDOWN_MESSAGE")
++ " Exception: " + detail;
+ }
+ Debug.println( "Command " + fullCmd + " failed: " + e );
+ }
+ return mSuccess;
+ }
+
+}
+
+
+
diff --git a/base/console/src/com/netscape/admin/certsrv/task/CMSRestart.java b/base/console/src/com/netscape/admin/certsrv/task/CMSRestart.java
new file mode 100644
index 000000000..fa9d59ddd
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/task/CMSRestart.java
@@ -0,0 +1,186 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.task;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.console.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+import netscape.ldap.*;
+
+/**
+ * Start the server
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class CMSRestart extends CGITask
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "TASKRESTART";
+ public static final String RESTART_TASK_CGI = "Tasks/Operation/restart";
+ //public static final String START_TASK_CGI = "Tasks/Operation/start";
+ //public static final String STOP_TASK_CGI = "Tasks/Operation/stop";
+ private Hashtable mCgiResponse = null;
+ private String mCgiTask = null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ public CMSRestart() {
+ super();
+ setName(mResource.getString(PREFIX+"_RESTART_LABEL"));
+ setDescription(mResource.getString(PREFIX+"_RESTART_DESC"));
+ }
+
+ public void initialize(ConsoleInfo info) {
+ Debug.println("CMSStart: initialize()");
+ _consoleInfo = info;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public boolean run(IPage viewInstance)
+ {
+ Debug.println("CMSRestart: run()");
+ boolean status = false; // return value
+ AuthDialog dialog = new AuthDialog(UtilConsoleGlobals.getActivatedFrame());
+ // dialog.show();
+ if (dialog.isCancel())
+ return false;
+
+ Hashtable configParams = new Hashtable();
+ configParams.put("serverRoot",_consoleInfo.get("serverRoot"));
+
+ String servid = (String)_consoleInfo.get("servid");
+ int index = servid.indexOf("-");
+ if (index != -1) {
+ servid = servid.substring(index+1);
+ }
+ configParams.put("instanceID", servid);
+ configParams.put("password",dialog.getPassword());
+ //configParams.put("instanceID",dialog.getInstanceName());
+ Debug.println("password "+dialog.getPassword());
+
+ // get the CMS instance host and port
+ servid = (String)_consoleInfo.get("servid");
+ String configDN = _consoleInfo.getCurrentDN();
+
+ try {
+ LDAPConnection ldc = _consoleInfo.getLDAPConnection();
+ if (ldc == null) {
+ ldc = new LDAPConnection();
+ }
+ if (ldc.isConnected() == false) {
+ ldc.connect(_consoleInfo.getHost(), _consoleInfo.getPort(),
+ _consoleInfo.getAuthenticationDN(),
+ _consoleInfo.getAuthenticationPassword());
+ }
+ LDAPEntry entry = ldc.read(configDN);
+ String cmsHost = LDAPUtil.flatting(
+ entry.getAttribute("serverHostName",
+ LDAPUtil.getLDAPAttributeLocale()));
+ String cmsPort = LDAPUtil.flatting(
+ entry.getAttribute("nsServerPort",
+ LDAPUtil.getLDAPAttributeLocale()));
+
+ Debug.println("host:" + cmsHost+" port:"+cmsPort);
+ configParams.put("cmsHost", cmsHost);
+ configParams.put("cmsPort", cmsPort);
+ }
+ catch (LDAPException e) {
+ Debug.println(
+ "ERROR CMSStatus: LDAP read failed: " +
+ configDN);
+ }
+ _consoleInfo.put("arguments", configParams);
+
+ if (_consoleInfo.get("AdminUsername") == null)
+ _consoleInfo.put("AdminUsername", _consoleInfo.getAuthenticationDN()
+);
+ Debug.println("AdminUsername = " + _consoleInfo.get("AdminUsername"));
+
+ if (_consoleInfo.get("AdminUserPassword") == null)
+ _consoleInfo.put("AdminUserPassword",
+ _consoleInfo.getAuthenticationPassword());
+ Debug.println("AdminUserPassword = " + _consoleInfo.get("AdminUserPassword"));
+ // call the CGI program
+ Debug.println("CMSRestart: restart() before run task="+RESTART_TASK_CGI);
+ try {
+ status = super.run(null, RESTART_TASK_CGI);
+ } catch (Exception e) {
+ Debug.println("Unexpected Error"+e.toString());
+ status = false;
+ }
+ Debug.println("CMSRestart: start() after run status="+status);
+
+ String title = mResource.getString("RESTARTRESULTDIALOG_TITLE");
+
+ if (!status) {
+ Debug.println("Show error dialog");
+ // if no error message from the server, then just show the generic
+ // error message.
+ if (mErrorMsg.equals(""))
+ CMSAdminUtil.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(),
+ mResource, PREFIX, "SYSTEMERROR", CMSAdminUtil.ERROR_MESSAGE);
+ else {
+ String errorMsg =
+ mResource.getString("RESTARTRESULTDIALOG_FAILED_TEXT")+mErrorMsg;
+ Icon icon = CMSAdminUtil.getImage(CMSAdminResources.IMAGE_ERROR_ICON);
+ JOptionPane.showMessageDialog(UtilConsoleGlobals.getActivatedFrame(),
+ errorMsg, title, JOptionPane.ERROR_MESSAGE, icon);
+ }
+ } else {
+ CMSAdmin cmsAdmin = (CMSAdmin)(_consoleInfo.get("CMSAdmin"));
+ cmsAdmin.getServerStatus();
+ Debug.println("Successful operation");
+ String msg = "";
+ // If warning message is received along with the started
+ // signal from the start.cc, we want to display the
+ // warning.
+ if (mWarnMsg.equals("")) {
+ msg = mResource.getString("RESTARTRESULTDIALOG_SUCCESS_TEXT");
+ Icon icon = CMSAdminUtil.getImage(CMSAdminResources.IMAGE_INFO_ICON);
+ JOptionPane.showMessageDialog(UtilConsoleGlobals.getActivatedFrame(),
+ msg, title, JOptionPane.INFORMATION_MESSAGE, icon);
+ } else {
+ StringTokenizer st = new StringTokenizer(mWarnMsg, "|");
+ while (st.hasMoreTokens()) {
+ msg += st.nextToken();
+ if (st.hasMoreTokens()) {
+ msg += "\n";
+ }
+ }
+ StatusDialog sd = new StatusDialog(UtilConsoleGlobals.getActivatedFrame());
+ sd.showDialog(mResource.getString("RESTARTRESULTDIALOG_SUCCESS_TEXT"), msg);
+ }
+ }
+
+ return status;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/task/CMSStart.java b/base/console/src/com/netscape/admin/certsrv/task/CMSStart.java
new file mode 100644
index 000000000..2122145c3
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/task/CMSStart.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.admin.certsrv.task;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.console.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+import netscape.ldap.*;
+
+/**
+ * Start the server
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class CMSStart extends CGITask
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "TASKSTART";
+ public static final String START_TASK_CGI = "Tasks/Operation/start";
+ private Hashtable mCgiResponse = null;
+ private String mCgiTask = null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ public CMSStart() {
+ super();
+ setName(mResource.getString(PREFIX+"_START_LABEL"));
+ setDescription(mResource.getString(PREFIX+"_START_DESC"));
+ }
+
+ public void initialize(ConsoleInfo info) {
+ Debug.println("CMSStart: initialize()");
+ _consoleInfo = info;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public boolean run(IPage viewInstance)
+ {
+ Debug.println("CMSStart: run()");
+ boolean status = false; // return value
+ AuthDialog dialog = new AuthDialog(UtilConsoleGlobals.getActivatedFrame());
+ // dialog.show();
+ if (dialog.isCancel())
+ return false;
+
+ Hashtable configParams = new Hashtable();
+ configParams.put("serverRoot",_consoleInfo.get("serverRoot"));
+ String servid = (String)_consoleInfo.get("servid");
+ int index = servid.indexOf("-");
+ if (index != -1) {
+ servid = servid.substring(index+1);
+ }
+ configParams.put("instanceID", servid);
+ configParams.put("password",dialog.getPassword());
+ //configParams.put("instanceID",dialog.getInstanceName());
+ Debug.println("password "+dialog.getPassword());
+
+ // get the CMS instance host and port
+ servid = (String)_consoleInfo.get("servid");
+ String configDN = _consoleInfo.getCurrentDN();
+
+ try {
+ LDAPConnection ldc = _consoleInfo.getLDAPConnection();
+ if (ldc == null) {
+ ldc = new LDAPConnection();
+ }
+ if (ldc.isConnected() == false) {
+ ldc.connect(_consoleInfo.getHost(), _consoleInfo.getPort(),
+ _consoleInfo.getAuthenticationDN(),
+ _consoleInfo.getAuthenticationPassword());
+ }
+ LDAPEntry entry = ldc.read(configDN);
+ String cmsHost = LDAPUtil.flatting(
+ entry.getAttribute("serverHostName",
+ LDAPUtil.getLDAPAttributeLocale()));
+ String cmsPort = LDAPUtil.flatting(
+ entry.getAttribute("nsServerPort",
+ LDAPUtil.getLDAPAttributeLocale()));
+
+ Debug.println("host:" + cmsHost+" port:"+cmsPort);
+ configParams.put("cmsHost", cmsHost);
+ configParams.put("cmsPort", cmsPort);
+ }
+ catch (LDAPException e) {
+ Debug.println(
+ "ERROR CMSStatus: LDAP read failed: " +
+ configDN);
+ }
+ _consoleInfo.put("arguments", configParams);
+
+ if (_consoleInfo.get("AdminUsername") == null)
+ _consoleInfo.put("AdminUsername", _consoleInfo.getAuthenticationDN()
+);
+ Debug.println("AdminUsername = " + _consoleInfo.get("AdminUsername"));
+
+ if (_consoleInfo.get("AdminUserPassword") == null)
+ _consoleInfo.put("AdminUserPassword",
+ _consoleInfo.getAuthenticationPassword());
+ Debug.println("AdminUserPassword = " + _consoleInfo.get("AdminUserPassword"));
+ // call the CGI program
+ Debug.println("CMSStart: start() before run task="+START_TASK_CGI);
+ try {
+ status = super.run(null, START_TASK_CGI);
+ } catch (Exception e) {
+ Debug.println("Unexpected Error"+e.toString());
+ status = false;
+ }
+ Debug.println("CMSStart: start() after run status="+status);
+
+ String title = mResource.getString("STARTRESULTDIALOG_TITLE");
+
+ if (!status) {
+ Debug.println("Show error dialog");
+ // if no error message from the server, then just show the generic
+ // error message.
+ if (mErrorMsg.equals(""))
+ CMSAdminUtil.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(),
+ mResource, PREFIX, "SYSTEMERROR", CMSAdminUtil.ERROR_MESSAGE);
+ else {
+ String errorMsg =
+ mResource.getString("STARTRESULTDIALOG_FAILED_TEXT")+mErrorMsg;
+ Icon icon = CMSAdminUtil.getImage(CMSAdminResources.IMAGE_ERROR_ICON);
+ JOptionPane.showMessageDialog(UtilConsoleGlobals.getActivatedFrame(),
+ errorMsg, title, JOptionPane.ERROR_MESSAGE, icon);
+ }
+ } else {
+ Debug.println("Successful operation");
+ String msg = "";
+ // If warning message is received along with the started
+ // signal from the start.cc, we want to display the
+ // warning.
+ if (mWarnMsg.equals("")) {
+ msg = mResource.getString("STARTRESULTDIALOG_SUCCESS_TEXT");
+ Icon icon = CMSAdminUtil.getImage(CMSAdminResources.IMAGE_INFO_ICON);
+ JOptionPane.showMessageDialog(UtilConsoleGlobals.getActivatedFrame(),
+ msg, title, JOptionPane.INFORMATION_MESSAGE, icon);
+ } else {
+ StringTokenizer st = new StringTokenizer(mWarnMsg, "|");
+ while (st.hasMoreTokens()) {
+ msg += st.nextToken();
+ if (st.hasMoreTokens()) {
+ msg += "\n";
+ }
+ }
+ StatusDialog sd = new StatusDialog(UtilConsoleGlobals.getActivatedFrame());
+ sd.showDialog(mResource.getString("STARTRESULTDIALOG_SUCCESS_TEXT"), msg);
+ }
+ }
+ return status;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/task/CMSStartDaemon.java b/base/console/src/com/netscape/admin/certsrv/task/CMSStartDaemon.java
new file mode 100644
index 000000000..510bf0661
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/task/CMSStartDaemon.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.admin.certsrv.task;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.management.client.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.management.client.console.*;
+import com.netscape.management.client.topology.*;
+import com.netscape.management.client.comm.*;
+import java.net.*;
+import java.io.*;
+import netscape.ldap.*;
+import netscape.ldap.util.*;
+
+/**
+ * Start daemon to do the certificate server configuration.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class CMSStartDaemon extends CGITask {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "CMSSTARTDAEMON";
+
+ public static final String START_DAEMON_CGI = "Tasks/Operation/start-daemon";
+
+ private boolean mSuccess = false; // status of last executed CGI
+ private Hashtable mCgiResponse = null; // holds parsed contents of CGI return
+ private String mCgiTask = null; // CGI task to call
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSStartDaemon() {
+ super();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void initialize(ConsoleInfo info) {
+ Debug.println("CMSStartDaemon: initialize()");
+ _consoleInfo = info;
+ }
+
+ /**
+ * Starts the server specific creation code, providing the DN for the
+ * target admin group. The method returns true or false depending
+ * on whether it was successful.
+ *
+ * @param targetDN - the admin group DN where the new instance is to be
+ * created.
+ * @return boolean value indicating whether the process succeeded (true)
+ * or failed (false).
+ */
+ public boolean runDaemon(Hashtable configParams) {
+ String response = null;
+/*
+ LDAPConnection ldc = _consoleInfo.getLDAPConnection();
+ String ssdn = ldc.getAuthenticationDN();
+ String[] avas = LDAPDN.explodeDN(ssdn, false);
+ String uid = avas[0];
+ configParams.put("adminUID", uid.substring(4,uid.length()));
+
+ configParams.put("adminPWD",ldc.getAuthenticationPassword());
+
+ _consoleInfo.put(START_DAEMON_CGI, "cert-bcsnpk");
+*/
+ _consoleInfo.put("arguments", configParams);
+
+ if (_consoleInfo.get("AdminUsername") == null)
+ _consoleInfo.put("AdminUsername", _consoleInfo.getAuthenticationDN());
+ Debug.println("AdminUsername = " + _consoleInfo.get("AdminUsername"));
+
+ if (_consoleInfo.get("AdminUserPassword") == null)
+ _consoleInfo.put("AdminUserPassword",
+ _consoleInfo.getAuthenticationPassword());
+ Debug.println("AdminUserPassword = " + _consoleInfo.get("AdminUserPassword"));
+
+ Debug.println("Current DN = "+_consoleInfo.getCurrentDN());
+ boolean status = false; // return value
+
+ try {
+ status = super.run(null, START_DAEMON_CGI);
+ } catch (Exception e) {
+ Debug.println("Unexpected Error"+e.toString());
+ status = false;
+ }
+ Debug.println("CMSStartDaemon: startDaemon() after run status=" +
+ status + " mSuccess=" + mSuccess);
+again:
+ if (!mSuccess) {
+ response = (String) mCgiResponse.get("NMC_ERRINFO");
+ if ((response != null) && response.equalsIgnoreCase("daemon found lock file")) {
+ int result = CMSAdminUtil.showConfirmDialog(mResource, "CMSSTARTDAEMON"/*PREFIX*/,
+ "LOCKDELETECONFIRM", CMSAdminUtil.WARNING_MESSAGE);
+ if (result == CMSAdminUtil.OK_OPTION) {
+ Debug.println("User wants to delete lock file.");
+ configParams.put("IGNORE", "TRUE");
+ status = super.run(null, START_DAEMON_CGI);
+ break again;
+ }
+ else
+ Debug.println("User doesn't want to delete lock file.");
+ }
+ else {
+ Debug.println("Show error dialog");
+ CMSAdminUtil.showMessageDialog(UtilConsoleGlobals.getActivatedFrame(), mResource, PREFIX,
+ "SYSTEMERROR", CMSAdminUtil.ERROR_MESSAGE);
+ }
+ }
+
+ return mSuccess;
+ }
+
+ /**
+ * the operation is finished after we receive the http stream
+ */
+ public void replyHandler(InputStream response, CommRecord cr) {
+ mSuccess = false;
+ if (mCgiResponse != null)
+ mCgiResponse.clear();
+
+ try {
+ BufferedReader rspStream =
+ new BufferedReader(new InputStreamReader(response, "UTF8"));
+ String rspStr;
+
+ Debug.println("CMSStartDaemon: replyHandler() - start");
+ while ((rspStr = rspStream.readLine()) != null)
+ {
+ Debug.println("CMSStartDaemon: replyHandler() - read [" + rspStr + "]");
+ // NMC_ messages are parsed, but not shown to the user
+ /*
+ if (_statusText != null && !rspStr.startsWith("NMC_")) {
+ _statusText.append(rspStr + "\n");
+ Thread.yield(); // allow graphics repaints
+ }
+ */
+ parse(rspStr);
+ }
+ } catch (Exception e) {
+ Debug.println("StartDaemon.replyHandler: " + e.toString());
+ }
+
+ Debug.println("StartDaemon.replyHandler: finished, mSuccess=" +
+ mSuccess);
+
+ finish();
+ }
+
+ /**
+ * return the value for the given keyword in the reply
+ */
+ private void parse(String s) {
+ String sName;
+ String sValue;
+ int iIndex;
+
+ Debug.println("Parse input: " + s);
+
+ if ((iIndex=s.indexOf(":")) != (-1))
+ {
+ sName = s.substring(0, iIndex).trim();
+ sValue = s.substring(iIndex+1).trim();
+ Debug.println("Parse input: name=" + sName + " value=" + sValue);
+ if (mCgiResponse == null)
+ mCgiResponse = new Hashtable();
+ mCgiResponse.put(sName, sValue);
+ if (sName.equalsIgnoreCase("NMC_Status"))
+ {
+ int code = Integer.parseInt(sValue);
+ mSuccess = (code == 0);
+ Debug.println("Parse input: code=" + code + " mSuccess=" + mSuccess);
+ }
+ }
+
+ Debug.println("Parse finished");
+ }
+
+ /**
+ * return the value for the response
+ */
+ public Hashtable getResponse() {
+ return mCgiResponse;
+ }
+
+ /**
+ * Get one value for one specified attribute from the given DN.
+ * If there is more than 1 entry which matches the given criteria, the
+ * first one will be used.
+ *
+ * @param DN DN of the entry with the specified attributes
+ * @param attr Attribute to get the value of
+ * @param scope LDAPConnection SCOPE_BASE SCOPE_ONE SCOPE_SUB
+ * @param filter LDAP search filter; if null, default is objectclass=*
+ * @return The string value of the attribute; multi-valued
+ * attributes are returned as 1 value, space delimited
+ * (flattened)
+ **/
+ protected String getValue(String DN, String attr, int scope,
+ String filter) {
+ String[] attrs = { attr };
+ String[] values = getValues(DN, attrs, scope, filter);
+ if (values != null)
+ return values[0];
+
+ return null;
+ }
+
+ /**
+ * Get the values for several specified attributes from the given DN.
+ * If there is more than 1 entry which matches the given criteria, the
+ * first one will be used.
+ *
+ * @param DN DN of the entry with the specified attributes
+ * @param attrs Array of attributes to get the values of
+ * @param scope LDAPConnection SCOPE_BASE SCOPE_ONE SCOPE_SUB
+ * @param filter LDAP search filter; if null, default is objectclass=*
+ * @return An array of string values for each attribute; multi-valued
+ * attributes are returned as 1 value, space delimited
+ * (flattened)
+ **/
+ protected String[] getValues(String DN, String[] attrs, int scope,
+ String filter) {
+ String[] values = null;
+ LDAPSearchResults results = null;
+ if (filter == null)
+ filter = "(objectclass=*)";
+
+ try {
+ LDAPConnection ldc = _consoleInfo.getLDAPConnection();
+ if (ldc != null)
+ {
+ results = ldc.search(DN, scope, filter, attrs, false);
+ }
+ } catch (LDAPException e) {
+ Debug.println("error MigrateCreate.getValues: LDAP read failed " +
+ "for DN=" + DN + " attributes " + attrs);
+ Debug.println("error MigrateCreate.getValues: LDAP Exception:" +
+ e);
+ }
+
+ if (results != null && results.hasMoreElements()) {
+ values = new String[attrs.length];
+ LDAPEntry entry = (LDAPEntry)results.nextElement();
+ for (int ii = 0; entry != null && ii < attrs.length; ++ii) {
+ values[ii] = LDAPUtil.flatting(entry.getAttribute(attrs[ii]));
+ }
+ } else {
+ Debug.println("error MigrateCreate.getValues: LDAP read failed " +
+ "for DN=" + DN + " attributes=" + attrs);
+ }
+
+ return values;
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/task/CMSStatus.java b/base/console/src/com/netscape/admin/certsrv/task/CMSStatus.java
new file mode 100644
index 000000000..edd80b5b2
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/task/CMSStatus.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.admin.certsrv.task;
+
+import java.util.*;
+import java.io.*;
+import java.net.URL;
+import javax.swing.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.console.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+import com.netscape.management.client.comm.*;
+import netscape.ldap.*;
+
+/**
+ * Retrieve the status of the server
+ *
+ * @author Ross Fubini
+ * @version $Revision$, $Date$
+ */
+public class CMSStatus extends CGITask
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "TASKSTATUS";
+ public static final String STATUS_TASK_CGI = "Tasks/Operation/status";
+ private Hashtable mCgiResponse = null;
+ private String mCgiTask = null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ public CMSStatus() {
+ super();
+/*
+ setName(mResource.getString(PREFIX+"_STATUS_LABEL"));
+ setDescription(mResource.getString(PREFIX+"_STATUS_DESC"));
+*/
+ }
+
+ public void initialize(ConsoleInfo info) {
+ Debug.println("CMSStatus: initialize()");
+ _consoleInfo = info;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public boolean run(IPage viewInstance)
+ {
+ Debug.println("CMSStatus: run()");
+ boolean status = false; // return value
+
+ Hashtable configParams = new Hashtable();
+ configParams.put("serverRoot",_consoleInfo.get("serverRoot"));
+ String servid = (String)_consoleInfo.get("servid");
+ int index = servid.indexOf("-");
+ if (index != -1) {
+ servid = servid.substring(index+1);
+ }
+ configParams.put("instanceID", servid);
+
+ // get the CMS instance host and port
+ servid = (String)_consoleInfo.get("servid");
+ String configDN = _consoleInfo.getCurrentDN();
+
+ try {
+ LDAPConnection ldc = _consoleInfo.getLDAPConnection();
+ if (ldc == null) {
+ ldc = new LDAPConnection();
+ }
+ if (ldc.isConnected() == false) {
+ ldc.connect(_consoleInfo.getHost(), _consoleInfo.getPort(),
+ _consoleInfo.getAuthenticationDN(),
+ _consoleInfo.getAuthenticationPassword());
+ }
+ LDAPEntry entry = ldc.read(configDN);
+ String cmsHost = LDAPUtil.flatting(
+ entry.getAttribute("serverHostName",
+ LDAPUtil.getLDAPAttributeLocale()));
+ String cmsPort = LDAPUtil.flatting(
+ entry.getAttribute("nsServerPort",
+ LDAPUtil.getLDAPAttributeLocale()));
+
+ Debug.println("host:" + cmsHost+" port:"+cmsPort);
+ configParams.put("cmsHost", cmsHost);
+ configParams.put("cmsPort", cmsPort);
+ }
+ catch (LDAPException e) {
+ Debug.println(
+ "ERROR CMSStatus: LDAP read failed: " +
+ configDN);
+ }
+ _consoleInfo.put("arguments", configParams);
+
+ if (_consoleInfo.get("AdminUsername") == null)
+ _consoleInfo.put("AdminUsername", _consoleInfo.getAuthenticationDN()
+);
+ Debug.println("AdminUsername = " + _consoleInfo.get("AdminUsername"));
+
+ if (_consoleInfo.get("AdminUserPassword") == null)
+ _consoleInfo.put("AdminUserPassword",
+ _consoleInfo.getAuthenticationPassword());
+ Debug.println("AdminUserPassword = " + _consoleInfo.get("AdminUserPassword"));
+
+ // call the CGI program
+ Debug.println("CMSStatus: status() before run task="+STATUS_TASK_CGI);
+ try {
+ status = getStatusWithFallback(null, STATUS_TASK_CGI);
+ } catch (Exception e) {
+ Debug.println("Unexpected Error"+e.toString());
+ status = false;
+ }
+ Debug.println("CMSStatus: status() after run status="+status);
+
+ if (!status) {
+ Debug.println("Status task returned false");
+ } else {
+ Debug.println("Successful operation");
+ }
+ return status;
+ }
+
+
+ /**
+ * Send an http request to the server.
+ * if the admin serever is down do
+ * Return true if we're sure it
+ * succeeded, otherwise false.
+ *
+ * @param viewInstance The calling page
+ * @param cmd Command to execute
+ */
+ boolean getStatusWithFallback(IPage viewInstance, String cmd) {
+ // get the admin URL location first
+ mAdminURL = _consoleInfo.getAdminURL();
+ if ( mAdminURL == null ) {
+ Debug.println( "Could not get adminURL for " + getDN() );
+ return false;
+ }
+
+ // Allow specifying e.g. "slapd-install" for instance
+ String instance = (String)_consoleInfo.get( cmd );
+
+ if ( instance == null )
+ instance = (String)_consoleInfo.get( "ServerInstance" );
+ String fullCmd = mAdminURL + instance + "/" + cmd;
+
+ HttpManager h = new HttpManager();
+ // tell the http manager to use UTF8 encoding
+ h.setSendUTF8(true);
+
+ try {
+ mSuccess = false;
+ mFinished = false;
+
+ // _consoleInfo.get("arguments") is a hashtable of key/value pairs
+ // to use as the arguments to the CGI
+ Hashtable args = (Hashtable)_consoleInfo.get("arguments");
+ ByteArrayInputStream data = null;
+ if (args != null && !args.isEmpty())
+ data = encode(args);
+ Debug.println( "Posting " + fullCmd );
+ // tell the http manager to notify us immediately of replies
+ // if we're using async mode
+ int flags = 0;
+ if (data == null)
+ h.post(new URL(fullCmd), this, null, null, 0,
+ flags);
+ else
+ h.post(new URL(fullCmd), this, null, data, data.available(),
+ flags);
+ awaitSuccess();
+ Debug.println( "Command executed: " + fullCmd );
+ } catch (Exception e) {
+ if ( e instanceof java.net.ConnectException ) {
+ Debug.println( "Admin server failed to status task" );
+ CMSAdmin cmsAdmin = (CMSAdmin)(_consoleInfo.get("CMSAdmin"));
+ mSuccess = cmsAdmin.getStatusFromAgentPort();
+ }
+ Debug.println( "Falling back to get status by connecting to the server");
+
+ }
+ return mSuccess;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/task/CMSStop.java b/base/console/src/com/netscape/admin/certsrv/task/CMSStop.java
new file mode 100644
index 000000000..b2a909633
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/task/CMSStop.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.admin.certsrv.task;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.console.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+import netscape.ldap.*;
+
+/**
+ * Stop the server
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class CMSStop extends CGITask
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "TASKSTOP";
+ public static final String STOP_TASK_CGI = "Tasks/Operation/stop";
+ private Hashtable mCgiResponse = null;
+ private String mCgiTask = null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ public CMSStop() {
+ super();
+ setName(mResource.getString(PREFIX+"_STOP_LABEL"));
+ setDescription(mResource.getString(PREFIX+"_STOP_DESC"));
+ }
+
+ public void initialize(ConsoleInfo info) {
+ _consoleInfo = info;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public boolean run(IPage viewInstance)
+ {
+ Debug.println("CMSStop: run()");
+ boolean status = false; // return value
+ /*
+ AuthDialog dialog = new AuthDialog(UtilConsoleGlobals.getActivatedFrame());
+ dialog.show();
+ if (dialog.isCancel())
+ return false;
+ */
+ Hashtable configParams = new Hashtable();
+ configParams.put("serverRoot", _consoleInfo.get("serverRoot"));
+ String servid = (String)_consoleInfo.get("servid");
+ int index = servid.indexOf("-");
+ if (index != -1) {
+ servid = servid.substring(index+1);
+ }
+ configParams.put("instanceID", servid);
+ // configParams.put("password",dialog.getPassword());
+
+ // get the CMS instance host and port
+ servid = (String)_consoleInfo.get("servid");
+ String configDN = _consoleInfo.getCurrentDN();
+
+ try {
+ LDAPConnection ldc = _consoleInfo.getLDAPConnection();
+ if (ldc == null) {
+ ldc = new LDAPConnection();
+ }
+ if (ldc.isConnected() == false) {
+ ldc.connect(_consoleInfo.getHost(), _consoleInfo.getPort(),
+ _consoleInfo.getAuthenticationDN(),
+ _consoleInfo.getAuthenticationPassword());
+ }
+ LDAPEntry entry = ldc.read(configDN);
+ String cmsHost = LDAPUtil.flatting(
+ entry.getAttribute("serverHostName",
+ LDAPUtil.getLDAPAttributeLocale()));
+ String cmsPort = LDAPUtil.flatting(
+ entry.getAttribute("nsServerPort",
+ LDAPUtil.getLDAPAttributeLocale()));
+
+ Debug.println("host:" + cmsHost+" port:"+cmsPort);
+ configParams.put("cmsHost", cmsHost);
+ configParams.put("cmsPort", cmsPort);
+ }
+ catch (LDAPException e) {
+ Debug.println(
+ "ERROR CMSStatus: LDAP read failed: " +
+ configDN);
+ }
+ _consoleInfo.put("arguments", configParams);
+
+ if (_consoleInfo.get("AdminUsername") == null)
+ _consoleInfo.put("AdminUsername", _consoleInfo.getAuthenticationDN()
+);
+ Debug.println("AdminUsername = " + _consoleInfo.get("AdminUsername"));
+
+ if (_consoleInfo.get("AdminUserPassword") == null)
+ _consoleInfo.put("AdminUserPassword",
+ _consoleInfo.getAuthenticationPassword());
+ Debug.println("AdminUserPassword = " + _consoleInfo.get("AdminUserPassword"));
+ // call the CGI program
+ Debug.println("CMSStop: stop() before run task="+STOP_TASK_CGI);
+ try {
+ status = super.run(null, STOP_TASK_CGI);
+ } catch (Exception e) {
+ Debug.println("Unexpected Error"+e.toString());
+ status = false;
+ }
+ Debug.println("CMSStop: stop() after run status="+status);
+
+ String title = mResource.getString("STOPRESULTDIALOG_TITLE");
+ if (!status) {
+ Debug.println("Show error dialog");
+ // if no error message from the server, then just show the generic
+ // error message.
+ if (mErrorMsg.equals(""))
+ CMSAdminUtil.showMessageDialog(
+ UtilConsoleGlobals.getActivatedFrame(),
+ mResource, PREFIX, "SYSTEMERROR", CMSAdminUtil.ERROR_MESSAGE);
+ else {
+ String errorMsg =
+ mResource.getString("STOPRESULTDIALOG_FAILED_TEXT")+mErrorMsg;
+ Icon icon = CMSAdminUtil.getImage(CMSAdminResources.IMAGE_ERROR_ICON);
+ JOptionPane.showMessageDialog(UtilConsoleGlobals.getActivatedFrame(),
+ errorMsg, title, JOptionPane.ERROR_MESSAGE, icon);
+ }
+ } else {
+ Debug.println("Successful operation");
+ String msg = mResource.getString("STOPRESULTDIALOG_SUCCESS_TEXT");
+ Icon icon = CMSAdminUtil.getImage(CMSAdminResources.IMAGE_INFO_ICON);
+ JOptionPane.showMessageDialog(UtilConsoleGlobals.getActivatedFrame(),
+ msg, title, JOptionPane.INFORMATION_MESSAGE, icon);
+ }
+ return status;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/task/CreateInstanceDialog.java b/base/console/src/com/netscape/admin/certsrv/task/CreateInstanceDialog.java
new file mode 100644
index 000000000..3092bf16d
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/task/CreateInstanceDialog.java
@@ -0,0 +1,246 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.task;
+
+import java.awt.*;
+import java.util.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.border.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Display this dialog to get the certificate
+ * instance name.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class CreateInstanceDialog extends JDialog
+ implements ActionListener, DocumentListener, MouseListener
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "CREATEINSTANCE";
+
+ private static final int WIDTH = 300;
+ private static final int HEIGHT = 150;
+ private JTextField mInstanceField; // username textfield
+ private boolean mCanceled = true; // exit state of the dialog
+ private String mInstanceName; // username
+ private JFrame mParentFrame;
+ private ResourceBundle mResource;
+ private JButton mOK, mCancel;
+ private KeyListener mTextFieldKeyListener;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ /**
+ * @param parent parent frame
+ */
+ public CreateInstanceDialog(JFrame parent) {
+ super(parent, true);
+ mParentFrame = parent;
+ mResource =
+ ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mTextFieldKeyListener = new TextFieldKeyListener();
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+
+ JPanel center = new JPanel();
+ getContentPane().setLayout(new BorderLayout());
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ JPanel contentPanel = new JPanel();
+ GridBagLayout gb1 = new GridBagLayout();
+ contentPanel.setLayout(gb1);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(contentPanel, gbc);
+ center.add(contentPanel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel lUsername =
+ new JLabel(mResource.getString(PREFIX+"_LABEL_INSTANCE_LABEL"));
+ lUsername.setToolTipText(
+ mResource.getString(PREFIX+"_LABEL_INSTANCE_TTIP"));
+
+ mInstanceField = new JTextField();
+ mInstanceField.addKeyListener(mTextFieldKeyListener);
+ mInstanceField.getDocument().addDocumentListener(this);
+ mInstanceField.addMouseListener(this);
+
+ CMSAdminUtil.addEntryField(contentPanel, lUsername, mInstanceField,
+ gbc);
+
+ JPanel actionPanel = makeActionPane();
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(actionPanel, gbc);
+ center.add(actionPanel);
+
+ getContentPane().add("Center",center);
+
+ mCanceled=false;
+ mInstanceName="";
+
+ setSize( WIDTH, HEIGHT );
+
+ addWindowListener(
+ new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ //setVisible(false);
+ dispose();
+ mCanceled = true;
+ }
+ }
+ );
+
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * return the exit status of the dialog
+ *
+ * @return true if the user hits the cancel button.
+ */
+ public boolean isCancel() {
+ return mCanceled;
+ }
+
+ /**
+ * Returns the username typed in by the user, on OK.
+ *
+ * @return The selected username, if the user hits the OK button.
+ */
+ public String getInstanceName() {
+ return mInstanceName;
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+ public void actionPerformed(ActionEvent evt) {
+ if (evt.getSource().equals(mOK)) {
+ mInstanceName = mInstanceField.getText().trim();
+
+ mCanceled = false;
+ //setVisible(false);
+ this.dispose();
+ return;
+
+ }
+ if (evt.getSource().equals(mCancel)) {
+ //setVisible(false);
+ mCanceled = true;
+ this.dispose();
+ return;
+ }
+ }
+
+ //== DocumentListener ==
+ public void insertUpdate(DocumentEvent e) {
+ setButtons();
+ }
+
+ public void removeUpdate(DocumentEvent e){
+ setButtons();
+ }
+
+ public void changedUpdate(DocumentEvent e){
+ setButtons();
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {}
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null,
+ this);
+ mOK.setEnabled(false);
+ mCancel = CMSAdminUtil.makeJButton(mResource, PREFIX, "CANCEL",
+ null, this);
+
+ JButton[] buttons = { mOK, mCancel};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonPanel(buttons, false);
+ }
+
+ //set buttons
+ private void setButtons() {
+ if (mInstanceField.getText().trim().equals("")){
+ mOK.setEnabled(false);
+ } else {
+ mOK.setEnabled(true);
+ getRootPane().setDefaultButton(mOK);
+ }
+ }
+
+ /**
+ * Inner class which handles key events for JTextField components.
+ */
+ class TextFieldKeyListener implements KeyListener
+ {
+ public void keyTyped(KeyEvent e) {
+ }
+
+ public void keyPressed(KeyEvent e) {
+ }
+
+ public void keyReleased(KeyEvent e) {
+ if(e.getKeyCode() == KeyEvent.VK_ENTER) {
+ if (!mInstanceField.getText().trim().equals("")) {
+ mOK.doClick();
+ }
+ }
+ }
+ }
+
+} \ No newline at end of file
diff --git a/base/console/src/com/netscape/admin/certsrv/task/KeyCert.java b/base/console/src/com/netscape/admin/certsrv/task/KeyCert.java
new file mode 100644
index 000000000..589983f61
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/task/KeyCert.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.admin.certsrv.task;
+
+import java.util.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.console.*;
+import com.netscape.admin.certsrv.keycert.*;
+
+/**
+ * Restart the server
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class KeyCert extends CMSTaskObject
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static String PREFIX = "TASKKEYCERT_";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ public KeyCert() {
+ setName(mResource.getString(PREFIX+"KEYCERT_LABEL"));
+ setDescription(mResource.getString(PREFIX+"KEYCERT_DESC"));
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public boolean run(IPage viewInstance) {
+ ConsoleInfo console = getConsoleInfo();
+ CMSServerInfo serverInfo = (CMSServerInfo)console.get("serverInfo");
+ CMSBaseResourceModel model = new CMSBaseResourceModel(console, serverInfo);
+ AdminConnection admin = serverInfo.getAdmin();
+ CertSetupWizardInfo wizardinfo = new CertSetupWizardInfo(admin, console);
+ CertSetupWizard wizard = new CertSetupWizard(model, wizardinfo);
+ return true;
+ }
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/task/StatusDialog.java b/base/console/src/com/netscape/admin/certsrv/task/StatusDialog.java
new file mode 100644
index 000000000..0cd11beb5
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/task/StatusDialog.java
@@ -0,0 +1,186 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.task;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import javax.swing.table.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Policy Implementation Information viewer
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class StatusDialog extends JDialog
+ implements ActionListener
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private String PREFIX = "STATUSDIALOG";
+
+ private JFrame mParentFrame;
+ private ResourceBundle mResource;
+ private JTextArea mTextArea;
+ private JLabel mTitle, mDetails;
+
+ private JButton mOK;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public StatusDialog(JFrame parent) {
+ super(parent,true);
+ mParentFrame = parent;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ setSize(300, 200);
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ setDisplay();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * show the windows
+ */
+ public void showDialog(String title, String desc) {
+ //initialize and setup
+ mTitle.setText(title);
+ mDetails.setText("Details:");
+ mTextArea.setText(desc);
+ mTextArea.setCaretPosition(0);
+ this.show();
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent evt) {
+ if (evt.getSource().equals(mOK)) {
+ this.hide();
+ }
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+ private void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.BOTH;
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null, this);
+ Dimension d = mOK.getMinimumSize();
+ if (d.width < CMSAdminUtil.DEFAULT_BUTTON_SIZE) {
+ d.width = CMSAdminUtil.DEFAULT_BUTTON_SIZE;
+ mOK.setMinimumSize(d);
+ }
+ JButton[] buttons = {mOK};
+ return CMSAdminUtil.makeJButtonPanel( buttons );
+ }
+
+ private JPanel makeContentPane() {
+ JPanel content = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ content.setLayout(gb3);
+
+ mTitle = new JLabel();
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx=1.0;
+ gbc.weighty=0.0;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE,CMSAdminUtil.COMPONENT_SPACE);
+ gb3.setConstraints(mTitle, gbc);
+ content.add(mTitle);
+
+ mDetails = new JLabel();
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx=1.0;
+ gbc.weighty=0.0;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,CMSAdminUtil.COMPONENT_SPACE, CMSAdminUtil.COMPONENT_SPACE,CMSAdminUtil.COMPONENT_SPACE);
+ gb3.setConstraints(mDetails, gbc);
+ content.add(mDetails);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mTextArea = new JTextArea("",3,50);
+ mTextArea.setFont(mTitle.getFont());
+ mTextArea.setEditable(false);
+ mTextArea.setBackground(getBackground());
+ JScrollPane scrollPanel = new JScrollPane(mTextArea,
+ JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+ JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ scrollPanel.setAlignmentX(LEFT_ALIGNMENT);
+ scrollPanel.setAlignmentY(TOP_ALIGNMENT);
+ scrollPanel.setBackground(getBackground());
+ //scrollPanel.setBorder(BorderFactory.createEmptyBorder());
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx=1.0;
+ gbc.weighty=1.0;
+ gb3.setConstraints(scrollPanel, gbc);
+ content.add(scrollPanel);
+
+ return content;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/AuthBaseDialog.java b/base/console/src/com/netscape/admin/certsrv/ug/AuthBaseDialog.java
new file mode 100644
index 000000000..6656b3abb
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/AuthBaseDialog.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.admin.certsrv.ug;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Auth Parameter Configuration Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.ug
+ */
+public class AuthBaseDialog extends JDialog
+ implements ActionListener
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ protected JFrame mParentFrame;
+ protected ResourceBundle mResource;
+ protected CMSTableModel mDataModel;
+ protected NameValuePairs mData;
+ protected JScrollPane mScrollPane;
+ protected JTable mTable;
+ protected String mRuleName;
+ protected String mPrefix;
+ protected String mType;
+ protected JButton mOK, mCancel, mHelp;
+ protected JTextField mAuthName;
+ protected JLabel mImplName, mAuthLabel;
+ protected AdminConnection mConn;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public AuthBaseDialog(JFrame parent, String type, String prefix) {
+ super(parent, true);
+ mParentFrame = parent;
+ mPrefix = prefix;
+ mType = type;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ setSize(360, 316);
+ setTitle(mResource.getString(mPrefix+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * show the windows
+ * @param users list of current groups
+ */
+ // Changed by beomsuk
+ /*public void showDialog(NameValuePairs data, String name,
+ boolean pinDirExist, boolean userDirExist) {*/
+ public void showDialog(NameValuePairs data, String name,
+ boolean pinDirExist, boolean userDirExist, boolean portalExist) {
+ // Change end
+ mDataModel.removeAllRows();
+ mData = data;
+
+ mImplName.setText(data.get(Constants.PR_AUTH_IMPL_NAME));
+
+ for (String entry : data.keySet()) {
+ entry = entry.trim();
+ if (!entry.equals(Constants.PR_AUTH_IMPL_NAME)) {
+ String value = data.get(entry);
+ Vector v = new Vector();
+ v.addElement(entry);
+ v.addElement(value);
+ mDataModel.addRow(v);
+ }
+ }
+
+ if ((name==null)||name.equals("")) {
+ //new policy
+ mAuthName.setVisible(true);
+ mAuthName.setText("");
+ mAuthLabel.setVisible(false);
+ String str = mImplName.getText().trim();
+ if (!pinDirExist && str.equals("UidPwdPinDirAuth"))
+ mAuthName.setText("PinDirEnrollment");
+ else if (!userDirExist && str.equals("UidPwdDirAuth"))
+ mAuthName.setText("UserDirEnrollment");
+ else if (!userDirExist && str.equals("UdnPwdDirAuth"))
+ mAuthName.setText("UserDnEnrollment");
+ else if (str.equals("NISAuth"))
+ mAuthName.setText("NISAuth");
+ // Inserted by beomsuk
+ else if (!portalExist && str.equals("PortalEnroll"))
+ mAuthName.setText("PortalEnrollment");
+ // Insert end
+ } else {
+ //old one
+ mRuleName = name;
+ mAuthName.setVisible(false);
+ mAuthLabel.setVisible(true);
+ mAuthLabel.setText(name);
+ }
+
+ this.show();
+ }
+
+ protected NameValuePairs getData() {
+ NameValuePairs response = new NameValuePairs();
+ response.put(Constants.PR_AUTH_IMPL_NAME, mImplName.getText());
+ for (int i=0; i< mDataModel.getRowCount(); i++) {
+ response.put((String) mDataModel.getValueAt(i, 0),
+ (String) mDataModel.getValueAt(i, 1));
+ }
+ return response;
+ }
+
+ protected String getRuleName() {
+ return mRuleName;
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent evt) {
+
+ if (evt.getSource().equals(mOK)) {
+
+ if(mAuthName.isVisible()) {
+ mRuleName = mAuthName.getText();
+ if (mRuleName.trim().equals("")) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ mResource.getString(mPrefix+"_DIALOG_NORULENAME_MESSAGE"),
+ CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ }
+
+ //save any current edit component
+ Component component = mTable.getEditorComponent();
+ if (component!= null) {
+ int col = mTable.getEditingColumn();
+ int row = mTable.getEditingRow();
+ if ((col>-1)&&(row>-1)) {
+ String str = ((JTextComponent)component).getText();
+ mTable.setValueAt(str, row, col);
+ }
+ }
+
+ try {
+ if (mAuthName.isVisible())
+ addPolicyRule(getData(), getRuleName());
+ else
+ modifyPolicyRule(getData(), getRuleName());
+ } catch (EAdminException e) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.toString(),CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ }
+
+ if (evt.getSource().equals(mOK) || evt.getSource().equals(mCancel))
+ this.dispose();
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+ protected void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ //create botton action panel
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, mPrefix, "OK", null, this);
+ if (mType.equals(Constants.VIEW))
+ mOK.setEnabled(false);
+ else
+ mOK.setEnabled(true);
+ mCancel = CMSAdminUtil.makeJButton(mResource, mPrefix, "CANCEL", null, this);
+ mHelp = CMSAdminUtil.makeJButton(mResource, mPrefix, "HELP", null, this);
+ // JButton[] buttons = { mOK, mCancel, mHelp};
+ JButton[] buttons = { mOK, mCancel};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonPanel( buttons, true);
+ }
+
+ private JPanel makeContentPane() {
+ JPanel mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+ //content.setBorder(CMSAdminUtil.makeEtchedBorder());
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label1 = CMSAdminUtil.makeJLabel(mResource, mPrefix, "RULENAME", null);
+ mAuthLabel = new JLabel();
+ mAuthLabel.setVisible(false);
+ mAuthName = new JTextField();
+
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.anchor = gbc.EAST;
+ gbc. insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ mListPanel.add(label1, gbc);
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc. insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ 0,CMSAdminUtil.COMPONENT_SPACE);
+ mListPanel.add( mAuthLabel, gbc );
+ mListPanel.add( mAuthName, gbc );
+
+ JLabel dummy = new JLabel();
+ dummy.setVisible(false);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ mListPanel.add( dummy, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label3 = CMSAdminUtil.makeJLabel(mResource, mPrefix, "IMPLNAME", null);
+ mImplName = new JLabel();
+ CMSAdminUtil.addEntryField(mListPanel, label3, mImplName, gbc);
+
+ //left side certificate table
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ //mScrollPane.setBorder(CMSAdminUtil.makeTitledBorder(mResource,PANEL_NAME,"USERS"));
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
+ //mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ setLabelCellRenderer(mTable,0);
+ setLabelCellRenderer(mTable,1);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ return mListPanel;
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ //table.getColumnModel().getColumn(index).setCellRenderer(new DefaultTableCellRenderer());
+ JLabel label = new JLabel();
+ if (mType.equals(Constants.VIEW)) {
+ label.setEnabled(false);
+ table.getColumnModel().getColumn(index).setCellRenderer(
+ new CustomLabelCellRenderer(label));
+ } else {
+ label.setEnabled(true);
+ table.getColumnModel().getColumn(index).setCellRenderer(
+ new LabelCellRenderer(label));
+ }
+ }
+
+ public class CustomLabelCellRenderer extends LabelCellRenderer {
+ public CustomLabelCellRenderer(JLabel x) {
+ super(x);
+ }
+
+ public Component getTableCellRendererComponent(JTable table,
+ Object value, boolean isSelected, boolean hasFocus, int row,
+ int column) {
+
+ if(value == null) {
+ value = table.getModel().getValueAt(row, column);
+ }
+ this.value.setValue(value);
+ component.setBackground(WHITECOLOR);
+ component.setForeground(WHITECOLOR);
+ return component;
+ }
+ }
+
+ protected void addPolicyRule(NameValuePairs config, String name)
+ throws EAdminException
+ {
+ mConn.add(DestDef.DEST_AUTH_ADMIN,
+ ScopeDef.SC_AUTH_MGR_INSTANCE,
+ name, config);
+ }
+
+ protected void modifyPolicyRule(NameValuePairs config, String name)
+ throws EAdminException
+ {
+ mConn.modify(DestDef.DEST_AUTH_ADMIN,
+ ScopeDef.SC_AUTH_MGR_INSTANCE,
+ name, config);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/AuthConfigDialog.java b/base/console/src/com/netscape/admin/certsrv/ug/AuthConfigDialog.java
new file mode 100644
index 000000000..aa756b388
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/AuthConfigDialog.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.admin.certsrv.ug;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import javax.swing.text.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+
+/**
+ * Auth Parameter Configuration Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.ug
+ */
+public class AuthConfigDialog extends CMSBaseConfigDialog
+{
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ public AuthConfigDialog(NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest) {
+
+ super(parent,dest);
+
+ PREFIX = "AUTHCONFIGDIALOG";
+ RAHELPINDEX = "authentication-certsrv-edit-authrule-dbox-help";
+ KRAHELPINDEX = "authentication-certsrv-edit-authrule-dbox-help";
+ CAHELPINDEX = "authentication-certsrv-edit-authrule-dbox-help";
+ mImplName_token = Constants.PR_AUTH_IMPL_NAME;
+ mImplType = Constants.PR_EXT_PLUGIN_IMPLTYPE_AUTH;
+ mHelpToken = "configuration-authentication";
+ init (nvp,parent,conn,dest);
+ }
+
+ public String getDefaultInstanceName(String implName)
+ {
+ Debug.println("Getting DefaultInstanceName for "+implName);
+ String instanceName = "";
+ if (implName.equals("UidPwdDirAuth")) {
+ instanceName = "UserDirEnrollment";
+ }
+ else if (implName.equals("UidPwdPinDirAuth")) {
+ instanceName = "PinDirEnrollment";
+ }
+ else if (implName.equals("UdnPwdDirAuth")) {
+ instanceName = "UserDnEnrollment";
+ }
+ else if (implName.equals("NISAuth")) {
+ instanceName = "NISAuth";
+ }
+ else if (implName.equals("PortalEnroll")) {
+ instanceName = "PortalEnrollment";
+ }
+
+ Debug.println("Returning instance name "+instanceName);
+ return instanceName;
+
+ }
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/AuthImplDataModel.java b/base/console/src/com/netscape/admin/certsrv/ug/AuthImplDataModel.java
new file mode 100644
index 000000000..98214871e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/AuthImplDataModel.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.admin.certsrv.ug;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.*;
+
+/**
+ * Auth Plugin Implementation Data model - represents the implementation
+ * table information
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.ug
+ */
+public class AuthImplDataModel extends CMSContentTableModel
+ implements IDataProcessor
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String IMPL_NAME = "NAME";
+ public static final String IMPL_CLASS = "CLASS";
+ public static final String IMPL_DESC = "DESC";
+ public static final String IMPL_TYPE = "TYPE";
+
+ private static String[] mColumns = {POLICY_IMPL, CLASSNAME};
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public AuthImplDataModel() {
+ super();
+ init(mColumns);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void processData(Object data) {
+ Vector v = new Vector();
+ NameValuePairs obj = (NameValuePairs) data;
+ JLabel label = new JLabel(obj.get(IMPL_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_AUTH_PLUGIN),
+ JLabel.LEFT);
+ if(!obj.get(IMPL_DESC).trim().equals(""))
+ label.setToolTipText(obj.get(IMPL_DESC));
+ v.addElement(label);
+ v.addElement(obj.get(IMPL_CLASS));
+ //v.addElement(obj.getValue(IMPL_DESC));
+ addRow(v, data);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/AuthImplTab.java b/base/console/src/com/netscape/admin/certsrv/ug/AuthImplTab.java
new file mode 100644
index 000000000..0cc964c60
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/AuthImplTab.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) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.ug;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Auth Plugin Management Tab
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.ug
+ */
+public class AuthImplTab extends CMSBaseUGTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String IMPL_NAME = AuthImplDataModel.IMPL_NAME;
+ private static final String IMPL_CLASS = AuthImplDataModel.IMPL_CLASS;
+ private static final String IMPL_DESC = AuthImplDataModel.IMPL_DESC;
+ private static final String IMPL_TYPE = AuthImplDataModel.IMPL_TYPE;
+
+ private static final String PANEL_NAME = "AUTHIMPL";
+ private static final String TOKEN = ";";
+
+ private AdminConnection mConnection;
+ private String mDestination;
+
+ protected JScrollPane mScrollPane;
+ protected JTable mTable; //table
+ protected AuthImplDataModel mDataModel; //table model
+ protected AuthRegisterDialog mEditor=null; //keep single copy
+ protected JButton mRefresh, mAdd, mDelete, mHelp;
+ private static final String HELPINDEX =
+ "authentication-certsrv-authplugin-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public AuthImplTab(CMSBaseResourceModel model) {
+ super(PANEL_NAME, model);
+ mConnection = model.getServerInfo().getAdmin();
+ mDataModel = new AuthImplDataModel();
+ mDestination = DestDef.DEST_AUTH_ADMIN;
+ mHelpToken = HELPINDEX;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mRefresh)) {
+ refresh();
+ }
+ if (e.getSource().equals(mAdd)) {
+ if (mEditor==null)
+ mEditor = new AuthRegisterDialog(mModel.getFrame(), mConnection);
+ mEditor.showDialog(mDestination, ScopeDef.SC_AUTH_IMPLS);
+
+ if (mEditor.isOK())
+ refresh();
+ }
+ if (e.getSource().equals(mDelete)) {
+ Debug.println("Delete");
+ if(mTable.getSelectedRow()< 0)
+ return;
+ int i = showConfirmDialog("DELETE");
+ if (i == JOptionPane.YES_OPTION) {
+ delete();
+ Debug.println("Deleted");
+ }
+ }
+ if (e.getSource().equals(mHelp)) {
+ helpCallback();
+ }
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+ public void refresh() {
+
+ mDataModel.removeAllRows();
+ update();
+
+ setButtons();
+ mTable.invalidate();
+ mTable.validate();
+ mScrollPane.invalidate();
+ mScrollPane.validate();
+ mScrollPane.repaint(1);
+ }
+
+ /**
+ * create the user action button panel
+ */
+ protected JPanel createButtonPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mAdd = makeJButton("ADD");
+ mDelete = makeJButton("DELETE");
+ JButton[] buttons = {mAdd, mDelete};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ protected JPanel createActionPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mRefresh = makeJButton("REFRESH");
+ mHelp = makeJButton("HELP");
+ //JButton[] buttons = { mRefresh, mHelp };
+ JButton[] buttons = { mRefresh };
+ return makeJButtonPanel(buttons, true);
+ }
+
+ protected JPanel createListPanel() {
+ mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ //center table
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ //mScrollPane.setBorder(CMSAdminUtil.makeTitledBorder(mResource,PANEL_NAME,"USERS"));
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ mTable.getSelectionModel().addListSelectionListener(this);
+ mScrollPane.setBackground(Color.white);
+ mTable.addMouseListener(this);
+ setLabelCellRenderer(mTable,0);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = 1;
+ gbc.weightx = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ JPanel buttonPanel = createButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ mListPanel.add(buttonPanel);
+
+ refresh();
+
+ return mListPanel;
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(new LabelCellRenderer(new JLabel()));
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ //set buttons
+ private void setButtons() {
+
+ //enable and diable buttons accordingly
+ //Debug.println("setButtons() - "+mTable.getSelectedRow());
+ //Debug.println("setButtons() - "+mTable.getSelectionModel().isSelectionEmpty());
+ if (mTable.getSelectionModel().isSelectionEmpty()) {
+ mDelete.setEnabled(false);
+ return;
+ }
+
+ if(mDataModel.getRowCount()< 0) {
+ mDelete.setEnabled(false);
+ return;
+ }
+
+ mDelete.setEnabled(true);
+ int index = mTable.getSelectedRow();
+
+ if (index >= 0) {
+ NameValuePairs nvp =
+ (NameValuePairs)mDataModel.getObjectValueAt(index);
+ String type = nvp.get(IMPL_TYPE);
+ if (type.equals(Constants.VIEW) || type.equals(Constants.VIEW))
+ mDelete.setEnabled(false);
+ }
+ }
+
+ //=============================================
+ // SEND REQUESTS TO THE SERVER SIDE
+ //=============================================
+ private void update() {
+ //send request and parse data
+
+ mModel.progressStart();
+ NameValuePairs response;
+ try {
+ response = mConnection.search(mDestination,
+ ScopeDef.SC_AUTH_IMPLS,
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+
+ Debug.println(response.toString());
+
+ //parse the response
+ //The response is a set of name
+ int i=0;
+ String[] vals = new String[response.size()];
+ Hashtable data = new Hashtable();
+ for (String entry : response.keySet()) {
+ entry = entry.trim();
+ String value = response.get(entry);
+ Debug.println("AuthImplTab.java update(): "+
+ "entry="+entry+
+ "value="+value
+ );
+ int x = value.indexOf(",");
+ int y = value.indexOf(TOKEN);
+ NameValuePairs obj = new NameValuePairs();
+ obj.put(IMPL_NAME, entry);
+ Debug.println("x="+x);
+ if(x != -1) {
+ Debug.println("0 obj.add(IMPL_CLASS,"+value.substring(0,x));
+ obj.put(IMPL_CLASS, value.substring(0, x));
+ if (y == -1) {
+ Debug.println("1 obj.add(IMPL_DESC,"+value.substring(0,x));
+ obj.put(IMPL_DESC, value.substring(x + 1));
+ }
+ else {
+ Debug.println("1 obj.add(IMPL_DESC,"+value.substring(x+1,y));
+ obj.put(IMPL_DESC, value.substring(x + 1, y));
+ }
+ } else {
+ Debug.println(" 2 obj.add(IMPL_CLASS,"+value.substring(0,y));
+ obj.put(IMPL_CLASS, value.substring(0, y));
+ Debug.println(" 2 obj.add(IMPL_DESC,\"\"");
+ obj.put(IMPL_DESC, "");
+ }
+
+ String type = "";
+ Debug.println("y="+y);
+ if (y == -1) {
+ type = Constants.EDIT;
+ obj.put(IMPL_TYPE, Constants.EDIT);
+ } else {
+ type = value.substring(y+1);
+ obj.put(IMPL_TYPE, type);
+ }
+ if (type.equals(Constants.EDIT)) {
+ data.put(entry,obj);
+ vals[i++]= entry ;
+ }
+ }
+
+ if (i >= 1) {
+ String[] valCopy = new String[i];
+ System.arraycopy(vals, 0, valCopy, 0, i);
+ CMSAdminUtil.bubbleSort(valCopy);
+ for (int y=0; y< valCopy.length ; y++) {
+ if (data.get(valCopy[y]) instanceof String) {
+ Debug.println("processData: "+(String)data.get(valCopy[y]));
+ }
+ mDataModel.processData(data.get(valCopy[y]));
+ }
+
+ data.clear();
+ }
+
+ if (mDataModel.getRowCount() >0)
+ mTable.setRowSelectionInterval(0,0);
+
+ mModel.progressStop();
+ }
+
+ private void delete() {
+ //get entry name
+ mModel.progressStart();
+ NameValuePairs obj = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+
+ //send comment to server for the removal of user
+ try {
+ mConnection.delete(mDestination,
+ ScopeDef.SC_AUTH_IMPLS,
+ obj.get(IMPL_NAME));
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+ mModel.progressStop();
+ //send comment to server and refetch the content
+ refresh();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/AuthInstanceTab.java b/base/console/src/com/netscape/admin/certsrv/ug/AuthInstanceTab.java
new file mode 100644
index 000000000..929f99aef
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/AuthInstanceTab.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.admin.certsrv.ug;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.admin.certsrv.config.*;
+import javax.swing.*;
+
+import com.netscape.certsrv.common.*;
+
+/**
+ * Auth Instances Management Tab
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.ug
+ */
+public class AuthInstanceTab extends CMSPluginInstanceTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PANEL_NAME = "AUTHRULE";
+ private static final String ADMINRULE = "adminAuth";
+ private static final String AGENTRULE = "agentAuth";
+
+ private static final String HELPINDEX =
+ "authentication-certsrv-authrules-help";
+
+ private static final String DEST = DestDef.DEST_AUTH_ADMIN;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public AuthInstanceTab(CMSBaseResourceModel model) {
+ super(model,DEST, PANEL_NAME );
+ RULE_NAME = AuthRuleDataModel.RULE_NAME;
+ RULE_IMPL = AuthRuleDataModel.RULE_IMPL;
+ RULE_TYPE = AuthRuleDataModel.RULE_TYPE;
+ mConnection = model.getServerInfo().getAdmin();
+ mDataModel = new AuthRuleDataModel();
+ mScope = ScopeDef.SC_AUTH_MGR_INSTANCE;
+ mHelpToken = HELPINDEX;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ public CMSBaseConfigDialog makeNewConfigDialog(
+ NameValuePairs nvp,
+ JFrame parent,
+ AdminConnection conn,
+ String dest
+ )
+ {
+
+ return new AuthConfigDialog(nvp,
+ parent,
+ conn,
+ dest);
+ }
+
+ public PluginSelectionDialog getPluginSelectionDialog(
+ JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType
+ )
+ {
+ return new AuthPluginSelectionDialog(parent,conn,dest,pluginType);
+ }
+
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+
+
+ //=============================================
+ // SEND REQUESTS TO THE SERVER SIDE
+ //=============================================
+
+ private void delete() {
+
+ mModel.progressStart();
+ //get entry name
+ NameValuePairs data = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+
+ //send comment to server for the removal of user
+ try {
+ mConnection.delete(DestDef.DEST_AUTH_ADMIN,
+ ScopeDef.SC_AUTH_MGR_INSTANCE,
+ data.get(RULE_NAME));
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+
+ mModel.progressStop();
+ //send comment to server and refetch the content
+ refresh();
+
+ }
+
+ //this returns the configuration
+ private NameValuePairs getConfig() throws EAdminException {
+ NameValuePairs data = (NameValuePairs)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+
+ NameValuePairs response;
+ response = mConnection.read(DestDef.DEST_AUTH_ADMIN,
+ ScopeDef.SC_AUTH_MGR_INSTANCE,
+ data.get(RULE_NAME),
+ new NameValuePairs());
+ return response;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/AuthPluginSelectionDialog.java b/base/console/src/com/netscape/admin/certsrv/ug/AuthPluginSelectionDialog.java
new file mode 100644
index 000000000..8721363d1
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/AuthPluginSelectionDialog.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.admin.certsrv.ug;
+
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Auth Plugin Selection Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.ug
+ */
+public class AuthPluginSelectionDialog extends PluginSelectionDialog
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static String PREFIX = "AUTHSELECTIONDIALOG";
+
+/*
+ private final static String token = ";";
+ private JFrame mParentFrame;
+ private AdminConnection mConnection;
+ private ResourceBundle mResource;
+ protected DefaultListModel mDataModel;
+ private CMSBaseResourceModel mModel;
+
+ private JScrollPane mScrollPane;
+ private JList mList;
+
+ private JButton mOK, mCancel, mHelp;
+*/
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public AuthPluginSelectionDialog(JFrame parent,
+ AdminConnection conn,
+ String dest,
+ CMSPluginInstanceTab pluginType) {
+
+ super(PREFIX,parent,conn,dest,pluginType);
+ mScope = ScopeDef.SC_AUTH_IMPLS;
+ mInstanceScope = ScopeDef.SC_AUTH_MGR_INSTANCE;
+ mImageName = CMSAdminResources.IMAGE_RULE_PLUGIN;
+
+ mHelpToken = "authentication-certsrv-add-authrule-dbox-help";
+ setDisplay();
+/****
+ super(model.getFrame(),true);
+ mParentFrame = model.getFrame();
+ mModel = model;
+ mConnection = model.getServerInfo().getAdmin();
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mDataModel = new DefaultListModel();
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(mParentFrame);
+ getRootPane().setDoubleBuffered(true);
+ setDisplay();
+***/
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/AuthRegisterDialog.java b/base/console/src/com/netscape/admin/certsrv/ug/AuthRegisterDialog.java
new file mode 100644
index 000000000..f97a11388
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/AuthRegisterDialog.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.admin.certsrv.ug;
+
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+
+/**
+ * Auth Plugin Implementation Registration Editor
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.ug
+ */
+
+public class AuthRegisterDialog extends RegisterDialog {
+
+ private final static String PREFIX = "AUTHREGISTERDIALOG";
+
+ public AuthRegisterDialog(JFrame parent, AdminConnection conn) {
+ super(PREFIX, parent, conn);
+ setDisplay();
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/AuthRuleDataModel.java b/base/console/src/com/netscape/admin/certsrv/ug/AuthRuleDataModel.java
new file mode 100644
index 000000000..35e08d0eb
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/AuthRuleDataModel.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.admin.certsrv.ug;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.management.client.util.Debug;
+
+
+/**
+ * Auth instance Data model - represents the instance
+ * table information
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class AuthRuleDataModel extends CMSRuleDataModel
+{
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public AuthRuleDataModel() {
+ super();
+ }
+
+ protected String[] getColumns() {
+ Debug.println("PolicyRuleDataModel.getColumns()");
+ String x[] = {RULE, PLUGIN};
+ return x;
+ }
+
+ public void processData(Object data) {
+ Vector v = new Vector();
+ NameValuePairs obj = (NameValuePairs) data;
+
+ //XXX NEED TO ADD STUFF
+ v.addElement(new JLabel(obj.get(RULE_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_AUTH),
+ JLabel.LEFT));
+ v.addElement(obj.get(RULE_IMPL));
+ addRow(v, data);
+ }
+
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/AuthViewDialog.java b/base/console/src/com/netscape/admin/certsrv/ug/AuthViewDialog.java
new file mode 100644
index 000000000..6f3ed575a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/AuthViewDialog.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.admin.certsrv.ug;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.config.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import javax.swing.text.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Authentication Parameter View Dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.ug
+ */
+public class AuthViewDialog extends AuthBaseDialog
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PREFIX = "AUTHVIEWDIALOG";
+ private static final String HELPINDEX =
+ "authentication-certsrv-view-authrule-dbox-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public AuthViewDialog(CMSBaseResourceModel model) {
+ super(model.getFrame(), Constants.VIEW, PREFIX);
+ mConn = model.getServerInfo().getAdmin();
+ mDataModel = new ViewTableModel();
+ setDisplay();
+ }
+
+ public void actionPerformed(ActionEvent evt) {
+ super.actionPerformed(evt);
+ if (evt.getSource().equals(mHelp))
+ CMSAdminUtil.help(HELPINDEX);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/CMSBaseUGTab.java b/base/console/src/com/netscape/admin/certsrv/ug/CMSBaseUGTab.java
new file mode 100644
index 000000000..8e7fb34dd
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/CMSBaseUGTab.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.admin.certsrv.ug;
+
+import com.netscape.admin.certsrv.*;
+import java.util.*;
+import java.awt.event.*;
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.border.*;
+
+/**
+ * Base class for the tabs in the User and group tabbed pane.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public abstract class CMSBaseUGTab extends CMSBasePanel
+ implements MouseListener, IRefreshTab
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ protected CMSBaseResourceModel mModel; //resource model
+
+ private String mTitle; // panel title actually shows
+ protected boolean mInit = false; // true if this panel is initialized
+ protected JPanel mListPanel, mActionPanel; //panels
+ protected String mHelpToken;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSBaseUGTab(String panelName, CMSBaseResourceModel model) {
+ super(panelName);
+ mModel = model;
+ try {
+ String title = mResource.getString(mPanelName+"_TITLE");
+ mTitle = title;
+ } catch (MissingResourceException e) {
+ mTitle = "Missing Title";
+ }
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Initialization of the panel. Subcalss must provide
+ * the proper implementation.
+ */
+ public void init() {
+ setLayout(new BorderLayout());
+
+ //======== list panel ========================
+ mListPanel = createListPanel();
+ mListPanel.setBorder(new EmptyBorder(DIFFERENT_COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE - COMPONENT_SPACE,
+ DIFFERENT_COMPONENT_SPACE));
+ add("Center",mListPanel);
+
+ //====== action panel ===========================
+ mActionPanel = createActionPanel();
+ add("South",mActionPanel);
+ }
+
+ /**
+ * Called by the Tab parent to initialize the panel
+ */
+ public void initialize() {
+ if (!mInit) {
+ init();
+ mInit = true;
+ }
+ }
+
+
+ /**
+ * Returns the title of the tab
+ * @return string representation of the title
+ */
+ public String getTitle() {
+ return mTitle;
+ }
+
+ /**
+ * set the title of the tab
+ */
+ public void setTitle(String title) {
+ mTitle = title;
+ }
+
+ public void helpCallback() {
+ CMSAdminUtil.help(mHelpToken);
+ }
+
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {}
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {}
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+ protected abstract JPanel createActionPanel();
+ protected abstract JPanel createListPanel();
+
+ //=== OVERWRITE DIALOG MESSAGE =====================
+
+ protected void showMessageDialog(String keyword, int messageType ) {
+ CMSAdminUtil.showMessageDialog(mModel.getFrame(), mResource, mPanelName, keyword, messageType);
+ }
+
+ protected void showMessageDialog(String keyword) {
+ showMessageDialog(keyword, ERROR_MESSAGE);
+ }
+
+ protected int showConfirmDialog(String keyword, int messageType ) {
+ return CMSAdminUtil.showConfirmDialog(mModel.getFrame(), mResource, mPanelName, keyword, messageType);
+ }
+
+ protected int showConfirmDialog(String keyword) {
+ return showConfirmDialog(keyword, WARNING_MESSAGE);
+ }
+
+ protected int showConfirmDialog(String keyword, String[] params) {
+ return showConfirmDialog(keyword, params, WARNING_MESSAGE);
+ }
+
+ protected void showErrorDialog(String message) {
+ CMSAdminUtil.showErrorDialog(mModel.getFrame(), mResource, message, ERROR_MESSAGE);
+ }
+
+ public abstract void refresh();
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/CMSUGTabPanel.java b/base/console/src/com/netscape/admin/certsrv/ug/CMSUGTabPanel.java
new file mode 100644
index 000000000..b2f2b1c37
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/CMSUGTabPanel.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.admin.certsrv.ug;
+
+import com.netscape.admin.certsrv.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import javax.swing.tree.*;
+import java.awt.event.*;
+import java.awt.*;
+
+/**
+ * Base Class for Tabbed right hand pane
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class CMSUGTabPanel extends CMSBasePanel
+ implements IResourceSelectionListener, ChangeListener,
+ IRefreshTabPanel
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static String PANEL_NAME = "CMSUGTABPANEL";
+
+ protected JTabbedPane mTabbedPane; //tabbed panel
+ protected CMSBaseResourceModel mModel; //resource model
+ protected ResourceObject mParent; //tree node parent
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CMSUGTabPanel(CMSBaseResourceModel model, ResourceObject parent) {
+ super(PANEL_NAME);
+ mModel = model;
+ mParent = parent;
+ mModel.addIResourceSelectionListener(this);
+
+ setLayout(new BorderLayout());
+ // Look and Feel
+ mTabbedPane = new NSTabbedPane();
+ add("Center", mTabbedPane);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * Retrieve Resource Model
+ */
+ public CMSBaseResourceModel getResourceModel() {
+ return mModel;
+ }
+
+ //== IResourceListener ===
+
+ public void select(IResourceObject parent, Object viewInstance) {
+ //System.out.println("CMSTabPanel: select() "+ parent);
+ if (parent == mParent) {
+ try {
+ mTabbedPane.addChangeListener(this);
+ mTabbedPane.setSelectedIndex(0);
+ CMSBaseUGTab selectedPanel = (CMSBaseUGTab) mTabbedPane.getComponentAt(0);
+ if ( selectedPanel != null )
+ selectedPanel.initialize();
+ mTabbedPane.invalidate();
+ mTabbedPane.validate();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //NO TAB SO IGNORE
+ }
+ }
+ }
+
+ public boolean unselect(IResourceObject parent, Object viewInstance) {
+ return true;
+ }
+
+ public CMSBasePanel getSelectedTab() {
+ //Debug.println("CMSUGTabPanel: getSelectedTab()");
+ return (CMSBasePanel)mTabbedPane.getSelectedComponent();
+ }
+
+ //== ChangeListener ==
+ public void stateChanged(ChangeEvent e) {
+ //Debug.println("CMSTabPanel: stateChanged()");
+ CMSBaseUGTab selectedPanel = (CMSBaseUGTab)mTabbedPane.getSelectedComponent();
+ if ( selectedPanel != null )
+ selectedPanel.initialize();
+ mTabbedPane.invalidate();
+ mTabbedPane.validate();
+ mTabbedPane.repaint(1);
+ }
+
+ /**
+ * Add Panels to the Tab Panel. ChangeListener is
+ * added automatically.
+ *
+ * @param p CMS Panel to be added
+ */
+ public void addTab(CMSBaseUGTab p) {
+ mTabbedPane.addTab(p.getTitle(), p);
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+
+ //look and feel
+ class NSTabbedPane extends JTabbedPane {
+/*
+ public String getUIClassID() {
+ return "SecondaryTabbedPaneUI";
+ }
+*/
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/CertDataModel.java b/base/console/src/com/netscape/admin/certsrv/ug/CertDataModel.java
new file mode 100644
index 000000000..de6a588f6
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/CertDataModel.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.admin.certsrv.ug;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+import java.util.*;
+import javax.swing.*;
+
+/**
+ * Certificate Data Model
+ * Single column display with internal data object as NVP
+ * which stores Name and Data Blob (PrettyPrint or B64E)
+ */
+public class CertDataModel extends CMSContentTableModel
+ implements IDataProcessor
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String CERT_NAME="CERT_NAME";
+ public static final String CERT_DATA="CERT_DATA";
+ public static final String CERT_VIEW="CERT_VIEW";
+ public static final String CERT_B64E="CERT_B64E";
+ public static final String CERT_PP="CERT_PP";
+
+ private static String[] mColumns = {CERTIFICATE};
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CertDataModel() {
+ super();
+ init(mColumns);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void processData(Object data) {
+ Vector v = new Vector();
+
+ NameValuePairs obj = (NameValuePairs) data;
+
+ //XXX NEED TO CHANGE if we are going to have multi-column table
+ v.addElement(new JLabel(obj.get(CERT_NAME),
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_CERTICON_SMALL),
+ JLabel.LEFT));
+ addRow(v, data);
+ }
+
+ /**
+ * Retrieve the data blob, Certificate Pretty Print
+ * or Base64Encode cert, from the data object. Used
+ * by the view functionality.
+ *
+ * @param row cert table row number
+ * @retrun data in string format
+ */
+ public String getDataBlob(int row) {
+ try {
+ NameValuePairs obj = (NameValuePairs)getObjectValueAt(row);
+ return obj.get(CERT_DATA);
+ } catch (Exception e) {
+ Debug.println("CertDataModel: getDataBlob()- "+e.toString());
+ return "";
+ }
+ }
+} \ No newline at end of file
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/CertImportDialog.java b/base/console/src/com/netscape/admin/certsrv/ug/CertImportDialog.java
new file mode 100644
index 000000000..758dda109
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/CertImportDialog.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.admin.certsrv.ug;
+
+import com.netscape.admin.certsrv.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import javax.swing.table.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Certificate Import Editor - this UI will take Base64Encoded
+ * certificate block with BEGIN and END comment and deliver it
+ * to server side for processing. EOL, CRT, EOF characters are
+ * removed from the output.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.ug.CertManagementDialog
+ */
+public class CertImportDialog extends JDialog
+ implements ActionListener, DocumentListener, MouseListener
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private String PREFIX = "CERTIMPORTDIALOG";
+
+ private JFrame mParentFrame;
+ private ResourceBundle mResource;
+
+ private JTextArea mTextArea;
+ private JButton mOK, mCancel;
+ private String mB64E;
+ private boolean mIsOk = false;
+ private JButton mPaste;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CertImportDialog(JFrame parent) {
+ super(parent,true);
+ mParentFrame = parent;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ setSize(500, 400);
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ setDisplay();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * show the windows
+ */
+ public void showDialog() {
+ //initialize and setup
+ mTextArea.setText("");
+ mIsOk = false;
+ this.show();
+ }
+
+ /**
+ * get Base 64 Encoded blob
+ */
+ public String getB64E() {
+ return mB64E;
+ }
+
+ /**
+ * get the exit code
+ * @return true if ok; otherwise false
+ */
+ public boolean isOK() {
+ return mIsOk;
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent evt) {
+
+ if (evt.getSource().equals(mPaste)) {
+ mTextArea.paste();
+ return;
+ }
+
+ if (evt.getSource().equals(mCancel)) {
+ this.hide();
+ }
+
+ if (evt.getSource().equals(mOK)) {
+
+ //set values
+ mB64E = mTextArea.getText().trim();
+ mIsOk = true;
+ this.hide();
+ }
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {}
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {
+ setButtons();
+ }
+
+ //== DocumentListener ==
+ public void insertUpdate(DocumentEvent e) {
+ setButtons();
+ }
+
+ public void removeUpdate(DocumentEvent e){
+ setButtons();
+ }
+
+ public void changedUpdate(DocumentEvent e){
+ setButtons();
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ /**
+ * set buttons - proactive verification
+ */
+ private void setButtons() {
+ if (mTextArea.getText().trim().equals("")) {
+ mOK.setEnabled(false);
+ } else {
+ mOK.setEnabled(true);
+ }
+ }
+
+ /**
+ * Setup the initial UI components
+ */
+ private void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.BOTH;
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null, this);
+ mOK.setEnabled(false);
+ mCancel = CMSAdminUtil.makeJButton(mResource, PREFIX, "CANCEL", null, this);
+ JButton[] buttons = { mOK, mCancel};
+ return CMSAdminUtil.makeJButtonPanel( buttons );
+ }
+
+ private JPanel makeContentPane() {
+ JPanel content = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ content.setLayout(gb3);
+ //content.setBorder(CMSAdminUtil.makeEtchedBorder());
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label2 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "B64E", null);
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.WEST;
+ gbc.weightx=0.0;
+ gb3.setConstraints(label2, gbc);
+ content.add(label2);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mPaste = CMSAdminUtil.makeJButton(mResource, PREFIX, "PASTE", null, this);
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.EAST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx=1.0;
+ gb3.setConstraints(mPaste, gbc);
+ content.add(mPaste);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mTextArea = new JTextArea("",40,70);
+ Font f = new Font("Monospaced", Font.PLAIN, 12);
+ if (f != null) mTextArea.setFont(f);
+ mTextArea.getDocument().addDocumentListener(this);
+ mTextArea.addMouseListener(this);
+ JScrollPane scrollPanel = new JScrollPane(mTextArea,
+ JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+ JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ scrollPanel.setAlignmentX(LEFT_ALIGNMENT);
+ scrollPanel.setAlignmentY(TOP_ALIGNMENT);
+ scrollPanel.setBorder(BorderFactory.createLoweredBevelBorder());
+ scrollPanel.setPreferredSize(new Dimension(300, 500));
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx=1.0;
+ gbc.weighty=1.0;
+ gb3.setConstraints(scrollPanel, gbc);
+ content.add(scrollPanel);
+
+ return content;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/CertManagementDialog.java b/base/console/src/com/netscape/admin/certsrv/ug/CertManagementDialog.java
new file mode 100644
index 000000000..82083649e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/CertManagementDialog.java
@@ -0,0 +1,441 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.ug;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * User Certificate Management Dialog - <p>
+ *
+ * The administrator can use this dialog to management the
+ * certificates of specific user. This allows the import of
+ * new certificates and delete/view of existing certificates.
+ *
+ * This dialog is launched by clicking on the certificate button
+ * on the main user management tab.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.ug.CertImportDialog
+ * @see com.netscape.admin.certsrv.ug.CertViewDialog
+ * @see com.netscape.admin.certsrv.ug.UserTab
+ */
+public class CertManagementDialog extends JDialog
+ implements ActionListener, MouseListener
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private String PREFIX = "CERTMANAGEMENTDIALOG";
+
+ private JFrame mParentFrame;
+ private AdminConnection mConnection;
+ private ResourceBundle mResource;
+ protected DefaultListModel mDataModel;
+ protected Vector mPPData;
+ protected String mUID; //dest flag
+ protected CertViewDialog mViewDialog = null; //keeping a copy for reuse
+ protected CertImportDialog mCertDialog = null; //keeping a copy for reuse
+
+ private JScrollPane mScrollPane;
+ private JList mList;
+
+ private JButton mOK, mCancel, mAdd, mDelete, mView, mHelp;
+ private final static String HELPINDEX =
+ "usersgroups-certsrv-manage-usercert-dbox-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CertManagementDialog(JFrame parent, AdminConnection conn) {
+ super(parent,true);
+ mParentFrame = parent;
+ mConnection = conn;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mDataModel = new DefaultListModel();
+ mPPData = new Vector();
+ setSize(800, 216);
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ setDisplay();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * show the windows
+ * @param uid current user id
+ */
+ public void showDialog(String uid) {
+ mUID = uid;
+
+ if (!refresh())
+ return;
+ setButtons();
+ this.show();
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent evt) {
+
+ if (evt.getSource().equals(mOK)) {
+ //nothing to do here
+ this.dispose();
+ } else if (evt.getSource().equals(mCancel)) {
+ this.dispose();
+ } else if (evt.getSource().equals(mAdd)) {
+ //call cert import editor
+ if (mCertDialog==null)
+ mCertDialog = new CertImportDialog(mParentFrame);
+ mCertDialog.showDialog();
+ if (!mCertDialog.isOK())
+ return;
+ addCert(mCertDialog.getB64E());
+ refresh();
+ setButtons();
+ } else if (evt.getSource().equals(mDelete)) {
+ int i = CMSAdminUtil.showConfirmDialog(mParentFrame, mResource, "USERCERTS",
+ "DELETE", JOptionPane.INFORMATION_MESSAGE);
+ if (i == JOptionPane.YES_OPTION) {
+ deleteCert();
+ refresh();
+ setButtons();
+ }
+ } else if (evt.getSource().equals(mView)) {
+ if (mViewDialog==null)
+ mViewDialog = new CertViewDialog(mParentFrame);
+ String id = ((JLabel)mDataModel.elementAt(mList.getSelectedIndex())).getText();
+ mViewDialog.showDialog(id,(String)mPPData.elementAt(mList.getSelectedIndex()));
+ } else if (evt.getSource().equals(mHelp)) {
+ CMSAdminUtil.help(HELPINDEX);
+ }
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {}
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {}
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ /**
+ * Setup the initial UI components
+ */
+ private void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.BOTH;
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ /**
+ * create the bottom action button panel
+ */
+ protected JPanel createUDButtonPanel() {
+ //up, down buttons required
+ //actionlister to this object
+ mAdd = CMSAdminUtil.makeJButton(mResource, PREFIX, "IMPORT", null, this);
+ mDelete = CMSAdminUtil.makeJButton(mResource, PREFIX, "DELETE", null, this);
+ mView = CMSAdminUtil.makeJButton(mResource, PREFIX, "VIEW", null, this);
+ JButton[] buttons = { mAdd, mDelete, mView};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ //create botton action panel
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null, this);
+ mCancel = CMSAdminUtil.makeJButton(mResource, PREFIX, "CANCEL", null, this);
+ mHelp = CMSAdminUtil.makeJButton(mResource, PREFIX, "HELP", null, this);
+ // JButton[] buttons = { mOK, mHelp};
+ JButton[] buttons = { mOK};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonPanel( buttons, true);
+ }
+
+ private JPanel makeContentPane() {
+ JPanel mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+ //content.setBorder(CMSAdminUtil.makeEtchedBorder());
+
+ //left side certificate table
+ mList = CMSAdminUtil.makeJList(mDataModel,10);
+ mScrollPane = new JScrollPane(mList,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ mList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION );
+ mList.addMouseListener(this);
+ mScrollPane.setBackground(Color.white);
+ mScrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = 1;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,CMSAdminUtil.COMPONENT_SPACE,0,0);
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ JPanel buttonPanel = createUDButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ 0,0,CMSAdminUtil.COMPONENT_SPACE);
+ gb.setConstraints(buttonPanel, gbc);
+ mListPanel.add(buttonPanel);
+
+ return mListPanel;
+ }
+
+ /**
+ * set buttons - proactive verification
+ */
+ private void setButtons() {
+
+ //enable and diable buttons accordingly
+ //Debug.println("setButtons() - "+mList.getSelectedIndex());
+ if (mList.getSelectedIndex()< 0) {
+ mDelete.setEnabled(false);
+ mView.setEnabled(false);
+ return;
+ }
+ mDelete.setEnabled(true);
+ mView.setEnabled(true);
+ }
+
+ //=================================================
+ // RETRIEVE INFO FROM SERVER SIDE
+ //=================================================
+
+ //refresh the table content
+ private boolean refresh() {
+
+ mDataModel.clear();
+ mPPData.removeAllElements();
+
+ NameValuePairs response;
+ try {
+ response = mConnection.read(DestDef.DEST_USER_ADMIN,
+ ScopeDef.SC_USER_CERTS,
+ mUID, new NameValuePairs());
+ } catch (EAdminException e) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ return false;
+ }
+
+ //parse data
+ String[] vals = new String[response.size()];
+ int i=0;
+
+ for (String entry : response.keySet()) {
+ vals[i++] = entry.trim();
+ }
+
+ CMSAdminUtil.bubbleSort(vals);
+
+ for (int y=0; y< vals.length ; y++) {
+ String str = reformat(vals[y]);
+ mDataModel.addElement(new JLabel(str,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_CERTICON_SMALL),
+ JLabel.LEFT));
+ mPPData.addElement(response.get(vals[y]));
+ }
+
+ return true;
+ }
+
+ /**
+ * Change DN from the following format:
+ * Serial:0x0 Subject:<DN> Issuer:<DN>
+ * to the following fomrat:
+ * <version>;<serial>;<subject>;<issuer>
+ */
+ private String toServerFormat(String val) {
+ if (val == null)
+ return "";
+ int subject_pos = val.indexOf("Subject:");
+ if (subject_pos == -1)
+ return "";
+ int issuer_pos = val.indexOf("Issuer:");
+ if (issuer_pos == -1)
+ return "";
+ // we lost the version in reformat()
+
+ String serial = val.substring(9, subject_pos).trim();
+ long num = CMSAdminUtil.hexToLong(serial);
+ try {
+ return "-1;" +
+ num + ";" +
+ val.substring(issuer_pos+7).trim() + ";" +
+ val.substring(subject_pos+8, issuer_pos).trim();
+ } catch (NumberFormatException e) {
+ return "-1;" + num+";"+
+ val.substring(issuer_pos+7).trim() + ";" +
+ val.substring(subject_pos+8, issuer_pos).trim();
+ }
+ }
+
+ // swap the issuer name order with the subject name
+ private String reformat(String val) {
+
+ String name = "";
+
+ StringTokenizer st = new StringTokenizer(val,";",false);
+ String version=null; // I think this is cert version #
+ String serial=null;
+ String issuer=null;
+ String subject=null;
+
+ try {
+ version = st.nextToken();
+ serial = st.nextToken();
+ issuer = st.nextToken();
+ subject = st.nextToken();
+ } catch (Exception e) {}
+
+ try {
+ if (serial != null) {
+ String hexserial = Integer.toHexString(Integer.parseInt(serial));
+ name = name + "Serial:0x"+hexserial;
+ }
+ } catch (Exception e) {}
+
+
+ if (subject != null) {
+ name = name + " Subject:"+subject;
+ }
+
+ if (issuer != null) {
+ name = name + " Issuer:"+issuer;
+ }
+
+ return name;
+ }
+
+ private void addCert(String B64E) {
+ //send comment to server for the removal of user
+ NameValuePairs config = new NameValuePairs();
+ config.put(Constants.PR_USER_CERT, cleanupCertData(B64E));
+ try {
+ mConnection.add(DestDef.DEST_USER_ADMIN,
+ ScopeDef.SC_USER_CERTS,
+ mUID,
+ config);
+ } catch (EAdminException e) {
+ //display error dialog
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ }
+
+ /**
+ * routine to cleanup the certificate data
+ * this removes end of line embedded in the
+ * certificate data.
+ *
+ * @param data b64e cert request blob
+ */
+ private String cleanupCertData(String data) {
+ StringBuffer input = new StringBuffer(data);
+ StringBuffer buff = new StringBuffer();
+ for (int i=0; i< input.length(); i++) {
+ char c = input.charAt(i);
+ if ((c != '\n') && (c != '\r'))
+ buff.append(c);
+ }
+ return buff.toString();
+ }
+
+ private void deleteCert() {
+ //get entry name
+ String dn = ((JLabel)mDataModel.elementAt(mList.getSelectedIndex())).getText();
+ dn = toServerFormat(dn);
+ NameValuePairs config = new NameValuePairs();
+ config.put(Constants.PR_USER_CERT, dn);
+
+ //send comment to server for the removal of user
+ try {
+ mConnection.modify(DestDef.DEST_USER_ADMIN,
+ ScopeDef.SC_USER_CERTS,
+ mUID,
+ config);
+ } catch (EAdminException e) {
+ //display error dialog
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/CertViewDialog.java b/base/console/src/com/netscape/admin/certsrv/ug/CertViewDialog.java
new file mode 100644
index 000000000..ae4cfd113
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/CertViewDialog.java
@@ -0,0 +1,201 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.ug;
+
+import com.netscape.admin.certsrv.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import javax.swing.table.*;
+import com.netscape.admin.certsrv.connection.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Certificate Import Editor
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.ug
+ */
+public class CertViewDialog extends JDialog
+ implements ActionListener
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private String PREFIX = "CERTVIEWDIALOG";
+
+ private JFrame mParentFrame;
+ private ResourceBundle mResource;
+ private JTextArea mTextArea;
+ private JLabel mCertNameField;
+
+ private JButton mOK;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public CertViewDialog(JFrame parent) {
+ super(parent,true);
+ mParentFrame = parent;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ //setSize(800, 700);
+ setSize(400, 350);
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ setDisplay();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * show the windows
+ */
+ public void showDialog(String name, String pp) {
+ //initialize and setup
+ String certName = "";
+ if (name != null && name.length() > 0) {
+ int j = name.indexOf("Subject:");
+ int i = name.indexOf("Issuer:");
+ if (j < i) {
+ certName = name.substring(j, i);
+ }
+ }
+ mCertNameField.setText(certName);
+ mTextArea.setText(pp);
+ this.show();
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent evt) {
+ if (evt.getSource().equals(mOK)) {
+ this.hide();
+ }
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+ private void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.BOTH;
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null, this);
+ Dimension d = mOK.getMinimumSize();
+ if (d.width < CMSAdminUtil.DEFAULT_BUTTON_SIZE) {
+ d.width = CMSAdminUtil.DEFAULT_BUTTON_SIZE;
+ mOK.setMinimumSize(d);
+ }
+ JButton[] buttons = {mOK};
+ return CMSAdminUtil.makeJButtonPanel( buttons );
+ }
+
+ private JPanel makeContentPane() {
+ JPanel content = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ content.setLayout(gb3);
+ //content.setBorder(CMSAdminUtil.makeEtchedBorder());
+
+ CMSAdminUtil.resetGBC(gbc);
+ //JLabel label1 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "CERTNAME", null);
+ mCertNameField = new JLabel();
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx=1.0;
+ gbc.weightx=0.0;
+ gb3.setConstraints(mCertNameField, gbc);
+ content.add(mCertNameField);
+ //CMSAdminUtil.addEntryField(content, label1, mCertNameField, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label2 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "PP", null);
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.WEST;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx=1.0;
+ gb3.setConstraints(label2, gbc);
+ content.add(label2);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mTextArea = new JTextArea("",40,70);
+ Font f = new Font("Monospaced", Font.PLAIN, 12);
+ if (f != null) mTextArea.setFont(f);
+ mTextArea.setEditable(false);
+ mTextArea.setBackground(getBackground());
+ JScrollPane scrollPanel = new JScrollPane(mTextArea,
+ JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+ JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ scrollPanel.setAlignmentX(LEFT_ALIGNMENT);
+ scrollPanel.setAlignmentY(TOP_ALIGNMENT);
+ scrollPanel.setBorder(BorderFactory.createLoweredBevelBorder());
+ scrollPanel.setPreferredSize(new Dimension(300, 500));
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx=1.0;
+ gbc.weighty=1.0;
+// gbc.insets = new Insets(0, CMSAdminUtil.COMPONENT_SPACE,
+// CMSAdminUtil.COMPONENT_SPACE,
+// CMSAdminUtil.COMPONENT_SPACE);
+ gb3.setConstraints(scrollPanel, gbc);
+ content.add(scrollPanel);
+
+ return content;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/GroupDataModel.java b/base/console/src/com/netscape/admin/certsrv/ug/GroupDataModel.java
new file mode 100644
index 000000000..779e9903e
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/GroupDataModel.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.admin.certsrv.ug;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+
+/**
+ * Group Data model - represents the group table information
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class GroupDataModel extends CMSContentTableModel {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static String[] mColumns = {GROUPNAME, GROUPDESC};
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public GroupDataModel() {
+ super();
+ init(mColumns);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void processData(String name, String desc) {
+ Vector v = new Vector();
+
+ //XXX NEED TO CHANGE if we are going to have multi-column table
+ v.addElement(new JLabel((String)name,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_USERGROUP),
+ JLabel.LEFT));
+ v.addElement(desc);
+ addRow(v,name);
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/GroupEditor.java b/base/console/src/com/netscape/admin/certsrv/ug/GroupEditor.java
new file mode 100644
index 000000000..e9693b15d
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/GroupEditor.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.admin.certsrv.ug;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Group Membership Editor
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.ug
+ */
+public class GroupEditor extends JDialog
+ implements ActionListener, ListSelectionListener
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private String PREFIX = "GROUPEDITOR";
+
+ private JFrame mParentFrame;
+ private AdminConnection mConnection;
+ private String mGroupName;
+ private boolean mIsNewGroup = false;
+ private ResourceBundle mResource;
+ protected DefaultListModel mDataModel;
+ protected UserListDialog mUserDialog = null; //keeping a copy for reuse
+
+ protected JScrollPane mScrollPane;
+ protected JList mList;
+
+ private JButton mOK, mCancel, mHelp, mAddUser, mDelete;
+ private JTextField mGroupNameField, mGroupDescField;
+ private JLabel mGroupNameLabel;
+
+ private static final String ADDHELPINDEX =
+ "usersgroups-certsrv-add-group-dbox-help";
+ private static final String EDITHELPINDEX =
+ "usersgroups-certsrv-edit-group-dbox-help";
+ private String mHelpToken;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public GroupEditor(JFrame parent, AdminConnection conn) {
+ super(parent,true);
+ mParentFrame = parent;
+ mConnection = conn;
+ mDataModel = new DefaultListModel();
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+
+ setSize(360, 300);
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ setDisplay();
+ //toFront();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * show the windows
+ * @param users list of current groups
+ */
+ public void showDialog(String group, boolean isNew) {
+
+ //initialize and setup
+ mGroupName = group;
+ mIsNewGroup = isNew;
+
+ if (isNew)
+ mHelpToken = ADDHELPINDEX;
+ else
+ mHelpToken = EDITHELPINDEX;
+
+ mGroupDescField.setText("");
+ mGroupNameField.setText("");
+
+ mDataModel.clear();
+
+ //disable name change
+ if(!mIsNewGroup) {
+ mGroupNameField.setVisible(false);
+ mGroupNameLabel.setVisible(true);
+ mGroupNameLabel.setText(mGroupName);
+ } else {
+ mGroupNameField.setVisible(true);
+ mGroupNameLabel.setVisible(false);
+ }
+
+ //retrieve the user record from the server
+ try {
+ if (mIsNewGroup == false)
+ refresh();
+ } catch (EAdminException ex) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ ex.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+
+ setButtons();
+ this.show();
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+
+ public void actionPerformed(ActionEvent evt) {
+
+ if (evt.getSource().equals(mOK)) {
+
+ if (mIsNewGroup) {
+
+ //check text fields
+ if (mGroupNameField.getText().trim().equals("")) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, mResource, PREFIX,
+ "NOGROUPNAME", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+
+ try {
+ mGroupName = mGroupNameField.getText().trim();
+ addGroup();
+ } catch (EAdminException e) {
+ //display error dialog
+ Debug.println(e.toString());
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+
+ } else {
+
+ try {
+ modifyGroup();
+ } catch (EAdminException e) {
+ //display error dialog
+ Debug.println(e.toString());
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+
+ }
+ this.hide();
+ }
+
+ if (evt.getSource().equals(mCancel)) {
+ Debug.println("Cancel Pressed");
+
+ //display are you sure dialog
+ this.hide();
+ }
+
+ if (evt.getSource().equals(mHelp)) {
+ CMSAdminUtil.help(mHelpToken);
+ }
+
+ if (evt.getSource().equals(mAddUser)) {
+ //bring up the list for selection
+
+ //create vector here
+ Vector currentUser = new Vector();
+ for (int i=0; i<mDataModel.getSize(); i++) {
+ currentUser.addElement((String)mDataModel.getElementAt(i));
+ }
+
+ NameValuePairs response;
+ try {
+ response = mConnection.search(DestDef.DEST_USER_ADMIN,
+ ScopeDef.SC_USERS, new NameValuePairs());
+ boolean hasNewUser = false;
+ for (String entry : response.keySet()) {
+ entry = entry.trim();
+ if (currentUser.indexOf(entry)== -1)
+ hasNewUser = true;
+ }
+ if (!hasNewUser) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, mResource, PREFIX,
+ "ALLUSERS", CMSAdminUtil.INFORMATION_MESSAGE);
+ return;
+ }
+ } catch (EAdminException e) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+
+ if (mUserDialog==null)
+ mUserDialog = new UserListDialog(mParentFrame, mConnection);
+
+ mUserDialog.showDialog(currentUser);
+
+ //get selection
+ if (!mUserDialog.isOK())
+ return;
+
+ //create user NVP data object and add user entry
+ Vector selectedUser = mUserDialog.getSelectedUser();
+ //Debug.println("Selected User = "+selectedUser.toString());
+
+
+ for(int i=0; i<selectedUser.size(); i++) {
+ String name = ((String) selectedUser.elementAt(i)).trim();
+ if (!isDuplicate(name))
+ mDataModel.addElement(name);
+ }
+
+ refreshTable();
+ }
+
+ if (evt.getSource().equals(mDelete)) {
+ if(mList.getSelectedIndex()< 0)
+ return;
+ int i = CMSAdminUtil.showConfirmDialog(mParentFrame, mResource,
+ PREFIX, "DELETE", CMSAdminUtil.WARNING_MESSAGE);
+ if (i == JOptionPane.YES_OPTION) {
+ deleteMember();
+ Debug.println("Member Deleted");
+ }
+ setButtons();
+ }
+ }
+
+ private boolean isDuplicate(String name) {
+ for (int i=0; i<mDataModel.getSize(); i++) {
+ String name1 = ((String)mDataModel.getElementAt(i)).trim();
+ if (name1.equals(name))
+ return true;
+ }
+ return false;
+ }
+
+ public void valueChanged(ListSelectionEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+ private void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+
+ }
+
+ //resize vertical buttons
+ private void resizeButtons() {
+ mAddUser = CMSAdminUtil.makeJButton(mResource, PREFIX,"ADDUSER", null, this);
+ //mAddGroup = CMSAdminUtil.makeJButton(mResource, PREFIX, "ADDGROUP", null, this);
+ mDelete = CMSAdminUtil.makeJButton(mResource, PREFIX, "DELETE", null, this);
+ JButton[] buttons = {mAddUser, mDelete};
+ //JButton[] buttons = {mAddUser, mAddGroup, mDelete};
+ JButtonFactory.resize( buttons );
+ }
+
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null, this);
+ mCancel = CMSAdminUtil.makeJButton(mResource, PREFIX, "CANCEL", null, this);
+ mHelp = CMSAdminUtil.makeJButton(mResource, PREFIX, "HELP", null, this);
+ //JButton[] buttons = { mOK, mCancel, mHelp };
+ JButton[] buttons = { mOK, mCancel };
+ return CMSAdminUtil.makeJButtonPanel( buttons, true);
+ }
+
+
+ //create the vertical button panel for System Groups
+ private JPanel createMemberButtonPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ JButton[] buttons = {mAddUser, mDelete};
+ //JButton[] buttons = {mAddUser, mAddGroup, mDelete};
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ private JPanel makeContentPane() {
+ JPanel content = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ content.setLayout(gb3);
+ //content.setBorder(CMSAdminUtil.makeEtchedBorder());
+
+ Insets insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,0,
+ CMSAdminUtil.COMPONENT_SPACE,0);
+
+ //top panel
+ JPanel top = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ CMSAdminUtil.resetGBC(gbc);
+ top.setLayout(gb);
+
+ JLabel label1 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "GROUPNAME", null);
+ mGroupNameField = new JTextField();
+ mGroupNameLabel = new JLabel();
+ mGroupNameLabel.setVisible(false);
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.anchor = gbc.EAST;
+ gbc. insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ top.add(label1, gbc);
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc. insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ 0,CMSAdminUtil.DIFFERENT_COMPONENT_SPACE);
+ top.add( mGroupNameLabel, gbc );
+ top.add( mGroupNameField, gbc );
+
+ JLabel dummy = new JLabel();
+ dummy.setVisible(false);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ top.add( dummy, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ //gbc.gridheight = gbc.REMAINDER;
+ JLabel label2 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "GROUPDESC", null);
+ mGroupDescField = new JTextField();
+ CMSAdminUtil.addEntryField(top, label2, mGroupDescField, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ JLabel label3 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "MEMBER", null);
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.fill = gbc.NONE;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.anchor = gbc.WEST;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.DIFFERENT_COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0);
+ top.add(label3, gbc );
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+ gb3.setConstraints(top, gbc);
+ content.add(top);
+
+ //bottom panel
+ JPanel bottom = new JPanel();
+ //bottom.setBorder(BorderFactory.createEtchedBorder());
+ GridBagLayout gb2 = new GridBagLayout();
+ CMSAdminUtil.resetGBC(gbc);
+ bottom.setLayout(gb2);
+
+ resizeButtons();
+
+ //group membership table
+
+
+ mList = makeJList(mDataModel,9);
+ mList.addListSelectionListener(this);
+ mScrollPane = new JScrollPane(mList,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ //mList.addMouseListener(this);
+ mScrollPane.setBackground(Color.white);
+ mScrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = 1;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ 0);
+ gb2.setConstraints(mScrollPane, gbc);
+ bottom.add(mScrollPane);
+
+ JPanel memberButtonPanel = createMemberButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,0,
+ CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.DIFFERENT_COMPONENT_SPACE);
+ gb2.setConstraints(memberButtonPanel, gbc);
+ bottom.add(memberButtonPanel);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.insets = CMSAdminUtil.DEFAULT_EMPTY_INSETS;
+ gb3.setConstraints(bottom, gbc);
+ content.add(bottom);
+
+
+ return content;
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(new LabelCellRenderer(new JLabel()));
+ }
+
+ private void setButtons() {
+ if (mList.getSelectedIndex() < 0) {
+ mDelete.setEnabled(false);
+ } else
+ mDelete.setEnabled(true);
+ CMSAdminUtil.repaintComp(mDelete);
+ }
+
+ //=================================================
+ // RETRIEVE INFO FROM SERVER SIDE
+ //=================================================
+
+ //retrieve group information from the server
+ private void refresh() throws EAdminException {
+ //Call AdminConnection to get data mGroupName
+ //mDataModel.removeAllRows();
+
+ //construct NVP
+ NameValuePairs config = new NameValuePairs();
+ config.put(Constants.PR_GROUP_DESC, "");
+ config.put(Constants.PR_GROUP_USER, "");
+ config.put(Constants.PR_GROUP_GROUP, "");
+
+ NameValuePairs response;
+ response = mConnection.read(DestDef.DEST_GROUP_ADMIN,
+ ScopeDef.SC_GROUPS,
+ mGroupName,
+ config);
+
+ Debug.println("Received Memebership: "+response.toString());
+ //setup the ui
+ mGroupNameField.setText(mGroupName);
+ mGroupDescField.setText(response.get(Constants.PR_GROUP_DESC));
+
+ //setup the member table
+
+ //parse user entry
+ String user = response.get(Constants.PR_GROUP_USER).trim();
+ StringTokenizer tokenizer = new StringTokenizer(user, ",");
+ while (tokenizer.hasMoreTokens()) {
+ String user_str = tokenizer.nextToken().trim();
+ mDataModel.addElement(user_str);
+ }
+
+ }
+
+ //add new group information
+ private void addGroup() throws EAdminException {
+
+ //construct NVP
+ NameValuePairs config = new NameValuePairs();
+ config.put(Constants.PR_GROUP_DESC, mGroupName);
+ createUGString(config);
+
+ //send request
+ mConnection.add(DestDef.DEST_GROUP_ADMIN,
+ ScopeDef.SC_GROUPS,
+ mGroupName,
+ config);
+ }
+
+ //change new group information
+ private void modifyGroup() throws EAdminException {
+
+ //construct NVP
+ NameValuePairs config = new NameValuePairs();
+ config.put(Constants.PR_GROUP_DESC, mGroupDescField.getText());
+ createUGString(config);
+
+ //send request
+ mConnection.modify(DestDef.DEST_GROUP_ADMIN,
+ ScopeDef.SC_GROUPS,
+ mGroupName,
+ config);
+
+ }
+
+ //remove member from the member list
+ private void deleteMember() {
+ Debug.println("GroupEditor: deleteMember()");
+ int i = mList.getSelectedIndex();
+ try{
+ mDataModel.removeElementAt(i);
+ } catch (Exception e) {
+ Debug.println("GroupEditor: deleteMember()-" +e.toString());
+ }
+ refreshTable();
+ }
+
+ //create user and group membership string
+ private void createUGString(NameValuePairs config) {
+ StringBuffer userBuf = new StringBuffer();
+
+ //go through membership table
+ if(mDataModel.getSize()>0)
+ for (int i=0; i<mDataModel.getSize(); i++) {
+ String data = (String)mDataModel.getElementAt(i);
+ if (userBuf.length()>0)
+ userBuf.append(",");
+ userBuf.append(data);
+ }
+
+ //set parameters
+ config.put(Constants.PR_GROUP_USER, userBuf.toString());
+ }
+
+ //refresh the table content
+ private void refreshTable() {
+ //Debug.println("GroupEditor: refreshTable() - start");
+ //mTable.invalidate();
+ //mTable.validate();
+ //mTable.repaint(1);
+ //mScrollPane.invalidate();
+ //mScrollPane.validate();
+ //mScrollPane.repaint(1);
+ //Debug.println("GroupEditor: refreshTable() - end");
+ }
+
+ public JList makeJList(DefaultListModel listModel, int visibleCount) {
+ JList listbox = new JList(listModel);
+ listbox.setCellRenderer(new AttrCellRenderer());
+ listbox.setSelectionModel(new DefaultListSelectionModel());
+ listbox.setVisibleRowCount(visibleCount);
+ if(listModel.size()!=0)
+ listbox.setSelectedIndex(0);
+ return listbox;
+ }
+
+}
+
+
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/GroupListDataModel.java b/base/console/src/com/netscape/admin/certsrv/ug/GroupListDataModel.java
new file mode 100644
index 000000000..7893d9cb0
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/GroupListDataModel.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.admin.certsrv.ug;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+
+/**
+ * Group List Data model - represents the group selection information
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class GroupListDataModel extends CMSContentTableModel
+ implements IDataProcessor
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static String[] mColumns = {GROUPNAME};
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public GroupListDataModel() {
+ super();
+ init(mColumns);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void processData(Object data) {
+ Vector v = new Vector();
+
+ String entry = (String)data;
+ String name;
+ if (entry.startsWith(PrefixDef.PX_SYS))
+ name = entry.substring(PrefixDef.PX_SYS.length());
+ else
+ name = entry.substring(PrefixDef.PX_DEF.length());
+
+ v.addElement(new JLabel(name,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_USERGROUP),
+ JLabel.LEFT));
+ addRow(v, data);
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/GroupListDialog.java b/base/console/src/com/netscape/admin/certsrv/ug/GroupListDialog.java
new file mode 100644
index 000000000..d5931a6f8
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/GroupListDialog.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.admin.certsrv.ug;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+import javax.swing.table.*;
+import com.netscape.management.client.*;
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Group Listing Dialog - <p>
+ *
+ * This dialog support multiple group selection and displays
+ * only groups that are not in the current group. This dialog
+ * will be created once and being reused per group editor.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.ug
+ */
+public class GroupListDialog extends JDialog
+ implements ActionListener
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private String PREFIX = "GROUPLISTDIALOG";
+
+ private JFrame mParentFrame;
+ private AdminConnection mConnection;
+ private ResourceBundle mResource;
+ protected GroupListDataModel mDataModel;
+ protected Vector mCurrentGroups;
+ protected Vector mSelectedGroups;
+
+ private JScrollPane mScrollPane;
+ private JTable mTable;
+
+ private JButton mOK, mCancel;
+ private boolean mIsOk = false;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public GroupListDialog(JFrame parent, AdminConnection conn) {
+ super(parent,true);
+ mParentFrame = parent;
+ mConnection = conn;
+ mSelectedGroups = new Vector();
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mDataModel = new GroupListDataModel();
+ setSize(350, 300);
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ setDisplay();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * show the windows
+ * @param users list of current groups
+ */
+ public void showDialog(Vector groups) {
+
+ mCurrentGroups = groups;
+ mSelectedGroups.removeAllElements();
+
+ //retrieve the cert record from the server
+ try {
+ refresh();
+ } catch (EAdminException ex) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, mResource, PREFIX,
+ "SERVERERROR", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ mIsOk = false;
+ this.show();
+ }
+
+
+ /**
+ * if selection is ok, the group names will be returned
+ * otherwise, empty vector will be returned.
+ * @return group names
+ */
+ public Vector getSelectedGroup() {
+ return mSelectedGroups;
+ }
+
+ /**
+ * get the exit code
+ * @return true if ok; otherwise false
+ */
+ public boolean isOK() {
+ return mIsOk;
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent evt) {
+ if (evt.getSource().equals(mOK)) {
+ //check if selection has been made
+ //Debug.println("Row Selected = "+mDataModel.getRowCount());
+ if(mDataModel.getRowCount()<=0) {
+ //display error message
+ CMSAdminUtil.showMessageDialog(mParentFrame, mResource, PREFIX,
+ "NOSELECTION", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+
+ //get selection
+ //int i = mTable.getSelectedRowCount();
+ //Debug.println("Rows Selected ="+i);
+ int[] rowIndex = mTable.getSelectedRows();
+ //Debug.println("Rows Selected ="+rowIndex.length);
+ for (int j=0; j< rowIndex.length; j++)
+ mSelectedGroups.addElement(
+ mDataModel.getObjectValueAt(rowIndex[j]));
+
+ //set return flag
+ mIsOk = true;
+ this.hide();
+ }
+
+ if (evt.getSource().equals(mCancel)) {
+ this.hide();
+ }
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+ private void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null, this);
+ mCancel = CMSAdminUtil.makeJButton(mResource, PREFIX, "CANCEL", null, this);
+ JButton[] buttons = { mOK, mCancel};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonPanel( buttons );
+ }
+
+ private JPanel makeContentPane() {
+ JPanel content = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ content.setLayout(gb3);
+ //content.setBorder(CMSAdminUtil.makeEtchedBorder());
+
+ //left side certificate table
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ //mScrollPane.setBorder(CMSAdminUtil.makeTitledBorder(mResource,PREFIX,"CERTIFICATE"));
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ int width = CMSAdminUtil.getTotalColumnWidth( mTable );
+ //Dimension d = new Dimension( width, mTable.getRowHeight()*14);
+ //mTable.setMinimumSize( d );
+ //mTable.setSize( d );
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+ //mTable.getSelectionModel().addListSelectionListener(new StandardListSelectionListener());
+ //mTable.addMouseListener(this);
+ //mTable.setPreferredScrollableViewportSize(d);
+ setLabelCellRenderer(mTable,0);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ gbc.weightx = 1.0;
+ gb3.setConstraints(mScrollPane, gbc);
+ content.add(mScrollPane);
+
+ return content;
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(new LabelCellRenderer(new JLabel()));
+ }
+
+ //=================================================
+ // RETRIEVE INFO FROM SERVER SIDE
+ //=================================================
+
+ //retrieve group information from the server
+ private void refresh() throws EAdminException {
+ mDataModel.removeAllRows();
+
+ NameValuePairs response;
+ try {
+ response = mConnection.search(DestDef.DEST_GROUP_ADMIN,
+ ScopeDef.SC_GROUPS,
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+
+ //parse the data
+ for (String entry : response.keySet()) {
+ entry = entry.trim();
+ //check if not already in current list
+ if (mCurrentGroups.indexOf(entry)== -1)
+ mDataModel.processData(entry);
+ }
+
+ refreshTable();
+ }
+
+ //refresh the table content
+ private void refreshTable() {
+ mTable.invalidate();
+ mTable.validate();
+ //mTable.repaint(1);
+ mScrollPane.invalidate();
+ mScrollPane.validate();
+ //mScrollPane.repaint(1);
+ repaint();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/GroupTab.java b/base/console/src/com/netscape/admin/certsrv/ug/GroupTab.java
new file mode 100644
index 000000000..e80cc7047
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/GroupTab.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.admin.certsrv.ug;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * Group Tab
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class GroupTab extends CMSBaseUGTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PANEL_NAME = "GROUPTAB";
+ private AdminConnection mConnection;
+
+ protected JScrollPane mScrollPane;
+ protected JTable mTable; //table
+ protected GroupDataModel mDataModel; //table model
+ protected GroupEditor mEditor=null; //keep single copy
+
+ protected JButton mRefresh, mEdit, mAdd, mDelete, mHelp;
+ private static final String HELPINDEX = "usersgroups-certsrv-groups-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public GroupTab(CMSBaseResourceModel model) {
+ super(PANEL_NAME, model);
+ mConnection = model.getServerInfo().getAdmin();
+ mDataModel = new GroupDataModel();
+ mHelpToken = HELPINDEX;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+
+ if (e.getSource().equals(mRefresh)) {
+ Debug.println("Refresh Group");
+ refresh();
+ }
+ if (e.getSource().equals(mEdit)) {
+ if(mTable.getSelectedRow()< 0)
+ return;
+
+ Debug.println("Edit Groups "+mTable.getSelectedRow());
+ String groupName = (String) mDataModel.getObjectValueAt(mTable.getSelectedRow());
+
+ if (mEditor==null){
+ mEditor = new GroupEditor(mModel.getFrame(), mConnection);
+ }
+
+ mEditor.showDialog(groupName, false);
+ refresh();
+
+ }
+ if (e.getSource().equals(mAdd)) {
+ Debug.println("Show Editor");
+ if (mEditor==null)
+ mEditor = new GroupEditor(mModel.getFrame(), mConnection);
+ mEditor.showDialog("",true);
+ refresh();
+ }
+ if (e.getSource().equals(mDelete)) {
+ if(mTable.getSelectedRow()< 0)
+ return;
+ int i = showConfirmDialog("DELETE");
+ if (i == JOptionPane.YES_OPTION) {
+ deleteGroup();
+ Debug.println("Group Deleted");
+ }
+ }
+ if (e.getSource().equals(mHelp)) {
+ helpCallback();
+ }
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+
+ /*
+
+ //NEED TO DISABLE THIS DUE TO BUG THAT WILL RE-DISPLAY
+ //THE DISLOG WINDOW AFTER CLOSING
+
+ //NEED TO PUT CODE TO DO PROACTIVE VERIFICATION
+
+ Debug.println("GroupTab: mouseClicked() -"+e.toString());
+
+ //we track the double click action on the table entry - View op
+ if(mTable.getSelectedRow() >= 0) {
+ if(e.getClickCount() == 2) {
+ Debug.println("Edit System group");
+ String groupName = (String)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+ mEditor = new GroupEditor(mModel.getFrame(), mConnection);
+ mEditor.showDialog(PrefixDef.PX_SYS+groupName,false);
+ refresh();
+ }
+ }
+
+ //we track the double click action on the table entry - View op
+ if(mDefTable.getSelectedRow() >= 0) {
+ if(e.getClickCount() == 2) {
+ Debug.println("Edit Admin Define Group");
+ String groupName = (String)
+ mDefDataModel.getObjectValueAt(mDefTable.getSelectedRow());
+ mEditor = new GroupEditor(mModel.getFrame(), mConnection);
+ mEditor.showDialog(PrefixDef.PX_DEF+groupName,false);
+ refresh();
+ }
+ }
+ */
+
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+
+ /**
+ * Updates the groups
+ */
+ public void refresh() {
+ //Debug.println("refresh group");
+
+ mDataModel.removeAllRows();
+
+ updateGroup();
+ setButtons();
+
+ mTable.invalidate();
+ mTable.validate();
+ mTable.repaint(1);
+ mScrollPane.invalidate();
+ mScrollPane.validate();
+ mScrollPane.repaint(1);
+ }
+
+ //resize vertical buttons
+ protected void resizeButtons() {
+ mEdit = makeJButton("EDIT");
+ mAdd = makeJButton("ADD");
+ mDelete = makeJButton("DELETE");
+ //JButton[] buttons = {mEdit};
+ JButton[] buttons = {mAdd, mDelete, mEdit};
+ JButtonFactory.resize( buttons );
+ }
+
+ /**
+ * create the bottom action button panel
+ */
+ protected JPanel createUDButtonPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ // JButton[] buttons = { mEdit };
+ JButton[] buttons = { mAdd, mDelete, mEdit };
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ /**
+ * create the bottom action button panel
+ */
+ protected JPanel createActionPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mRefresh = makeJButton("REFRESH");
+ mHelp = makeJButton("HELP");
+ // JButton[] buttons = { mRefresh, mHelp };
+ JButton[] buttons = { mRefresh };
+ return makeJButtonPanel( buttons, true);
+ }
+
+ /**
+ * create the center listing panel
+ */
+ protected JPanel createListPanel() {
+ mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ resizeButtons();
+
+ //top standard table
+ //fix the size of the top table - since the content will be fixed
+ //also fixed the problem of resizing.
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ //mScrollPane.setBorder(CMSAdminUtil.makeTitledBorder(mResource,PANEL_NAME,"STANDARD"));
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ //int width = CMSAdminUtil.getTotalColumnWidth( mTable );
+ //Dimension d = new Dimension( width, mTable.getRowHeight()*8);
+ //mTable.setMinimumSize( d );
+ //mTable.setSize( d );
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ //mTable.getSelectionModel().addListSelectionListener(new StandardListSelectionListener());
+ mTable.addMouseListener(this);
+ //mTable.setPreferredScrollableViewportSize(d);
+ mScrollPane.setBackground(Color.white);
+ setLabelCellRenderer(mTable,0);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = 1;
+ gbc.weightx = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ JPanel buttonPanel = createUDButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ mListPanel.add(buttonPanel);
+
+ refresh();
+
+ return mListPanel;
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(new LabelCellRenderer(new JLabel()));
+ }
+
+ //=============================================
+ // SEND REQUESTS TO THE SERVER SIDE
+ //=============================================
+
+
+ /**
+ * set buttons - proactive verification
+ */
+ private void setButtons() {
+
+ //enable and diable buttons accordingly
+ if (mTable.getSelectionModel().isSelectionEmpty()) {
+ mDelete.setEnabled(false);
+ mEdit.setEnabled(false);
+ return;
+ }
+
+ if(mDataModel.getRowCount()< 0) {
+ mDelete.setEnabled(false);
+ mEdit.setEnabled(false);
+ return;
+ }
+
+ mDelete.setEnabled(true);
+ mEdit.setEnabled(true);
+
+ }
+
+ private void updateGroup() {
+ //send request and parse data
+
+ NameValuePairs response;
+ mModel.progressStart();
+ try {
+ response = mConnection.search(DestDef.DEST_GROUP_ADMIN,
+ ScopeDef.SC_GROUPS,
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+
+ Debug.println(response.toString());
+
+ //parse the data
+ Vector store = new Vector();
+ for (String entry : response.keySet()) {
+ store.addElement(entry.trim());
+ }
+
+ String[] vals = new String[store.size()];
+ store.copyInto(vals);
+
+ CMSAdminUtil.bubbleSort(vals);
+
+ for (int y=0; y< vals.length ; y++) {
+ String value = response.get(vals[y]);
+ mDataModel.processData(vals[y],value);
+ }
+
+ if (mDataModel.getRowCount() >0)
+ mTable.setRowSelectionInterval(0,0);
+
+ mModel.progressStop();
+ }
+
+ private void deleteGroup() {
+ //get entry name
+ String groupName = (String)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+
+ //send comment to server for the removal of the admin
+ //defined group - no multiple groups selection - append
+ //admin prefix
+ mModel.progressStart();
+ try {
+ mConnection.delete(DestDef.DEST_GROUP_ADMIN,
+ ScopeDef.SC_GROUPS,
+ groupName);
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+ mModel.progressStop();
+ //send comment to server and refetch the content
+ refresh();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/MemberDataModel.java b/base/console/src/com/netscape/admin/certsrv/ug/MemberDataModel.java
new file mode 100644
index 000000000..6b1fbfeec
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/MemberDataModel.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 com.netscape.admin.certsrv.ug;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.management.client.util.*;
+
+/**
+ * Group Membership model - represents the group table information
+ * We will need to store the user and group information in separate
+ * vector also for comparison purpose.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class MemberDataModel extends CMSContentTableModel
+ implements IDataProcessor
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ public static final String MEMBER_NAME = "MEMBER_NAME";
+ public static final String MEMBER_TYPE = "MEMBER_TYPE";
+ public static final String MEMBER_GROUP = "MEMBER_GROUP";
+ public static final String MEMBER_USER = "MEMBER_USER";
+
+ private static String[] mColumns = {MEMBER};
+
+ private Vector mUsers = new Vector();
+ private Vector mGroups = new Vector();
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public MemberDataModel() {
+ super();
+ init(mColumns);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void processData(Object data) {
+ Vector v = new Vector();
+
+ NameValuePairs rec = (NameValuePairs)data;
+
+ Icon icon;
+ icon = (rec.get(MEMBER_TYPE).equals(MEMBER_GROUP))?
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_USERGROUP):
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_USER);
+
+ String entry = rec.get(MEMBER_NAME);
+ String name = entry;
+ if(rec.get(MEMBER_TYPE).equals(MEMBER_GROUP)) {
+ if (entry.startsWith(PrefixDef.PX_SYS))
+ name = entry.substring(PrefixDef.PX_SYS.length());
+ else
+ name = entry.substring(PrefixDef.PX_DEF.length());
+ }
+ v.addElement(new JLabel(name,icon, JLabel.LEFT));
+ addRow(v, data);
+ }
+
+ /**
+ * clean up the table including the datat objects
+ */
+ public void removeAllRows() {
+ super.removeAllRows();
+ mObjectContainer.removeAllElements();
+ mUsers.removeAllElements();
+ mGroups.removeAllElements();
+ }
+
+ /**
+ * Remove row at the specified index position
+ * @param index row index to be removed
+ */
+ public void removeRow(int index)
+ throws ArrayIndexOutOfBoundsException
+ {
+ Debug.println("MemberDataModel: removeRow() - start");
+ NameValuePairs data = (NameValuePairs)getObjectValueAt(index);
+ if (data.get(MEMBER_TYPE).equals(MEMBER_GROUP))
+ mGroups.removeElement(data.get(MEMBER_NAME));
+ else
+ mUsers.removeElement(data.get(MEMBER_NAME));
+ super.removeRow(index);
+ Debug.println("MemberDataModel: removeRow() - end");
+ }
+
+ /**
+ * Add data row and data object associated with this row
+ * @param values row values for the table
+ * @param obj data object
+ */
+ public void addRow(Vector values, Object obj) {
+ super.addRow(values);
+ mObjectContainer.addElement(obj);
+ NameValuePairs rec = (NameValuePairs)obj;
+ if (rec.get(MEMBER_TYPE).equals(MEMBER_GROUP))
+ mGroups.addElement(rec.get(MEMBER_NAME));
+ else
+ mUsers.addElement(rec.get(MEMBER_NAME));
+ }
+
+ /**
+ * get user vector for comparison
+ */
+ public Vector getUsers() {
+ return (Vector)mUsers.clone();
+ }
+
+ /**
+ * get group vector for comparison
+ */
+ public Vector getGroups() {
+ return (Vector)mGroups.clone();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/UserDataModel.java b/base/console/src/com/netscape/admin/certsrv/ug/UserDataModel.java
new file mode 100644
index 000000000..c3b74ce35
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/UserDataModel.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.admin.certsrv.ug;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+
+/**
+ * User Data model - represents the user table information
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class UserDataModel extends CMSContentTableModel {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static String[] mColumns = {USERID, FULLNAME};
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public UserDataModel() {
+ super();
+ init(mColumns);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void processData(String uid, String name) {
+ Vector v = new Vector();
+
+ v.addElement(new JLabel(uid,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_USER),
+ JLabel.LEFT));
+ v.addElement(name);
+
+ addRow(v,uid);
+ }
+
+ /**
+ * get user vector for comparison
+ */
+ public Vector getUsers() {
+ return (Vector) mObjectContainer.clone();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/UserEditor.java b/base/console/src/com/netscape/admin/certsrv/ug/UserEditor.java
new file mode 100644
index 000000000..75908fe6a
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/UserEditor.java
@@ -0,0 +1,627 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.ug;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * User Information Editor - UI provides the user information
+ * management functionality. The management of user certificate
+ * is done by certificate management dialog
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ *
+ * @see com.netscape.admin.certsrv.ug.UserTab
+ */
+public class UserEditor extends JDialog
+ implements ActionListener, MouseListener, DocumentListener
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private String PREFIX = "USEREDITOR";
+
+ private JFrame mParentFrame;
+ private AdminConnection mConnection;
+ private String mUserName;
+ private boolean mIsNewUser = false;
+ private ResourceBundle mResource;
+ private Color mActiveColor;
+ protected DefaultListModel mDataModel;
+
+ protected JScrollPane mScrollPane;
+ protected JList mList;
+
+ private boolean mUserAdded;
+ private JButton mOK, mCancel, mHelp;
+ private JLabel mPasswordLbl, mPasswordConfirmLbl;
+ private JTextField mUserNameField, mFullNameField, mEMailField, mPhoneField, mStateField;
+ private JPasswordField mPasswordField;
+ private JPasswordField mPasswordConfirm;
+ private JLabel mUserLabel, mMembership, mGroupLbl, dummy1;
+ private JComboBox mGroupBox;
+ private static final String ADDHELPINDEX =
+ "usersgroups-certsrv-add-user-dbox-help";
+ private static final String EDITHELPINDEX =
+ "usersgroups-certsrv-edit-user-dbox-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public UserEditor( JFrame parent,
+ AdminConnection conn, boolean isNew) {
+ super(parent,true);
+ mParentFrame = parent;
+ mConnection = conn;
+ mDataModel = new DefaultListModel();
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ mIsNewUser = isNew;
+ if(!mIsNewUser)
+ setSize(360, 370);
+ else
+ setSize(360, 350);
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ setDisplay();
+
+ if(!mIsNewUser) {
+ mUserNameField.setVisible(false);
+ mUserLabel.setVisible(true);
+ mMembership.setVisible(true);
+ mScrollPane.setVisible(true);
+ mGroupLbl.setVisible(false);
+ mGroupBox.setVisible(false);
+ dummy1.setVisible(false);
+ } else {
+ mUserNameField.setVisible(true);
+ mUserNameField.setText("");
+ mUserLabel.setVisible(false);
+ mUserLabel.setText("");
+ mMembership.setVisible(false);
+ mScrollPane.setVisible(false);
+ mGroupLbl.setVisible(true);
+ mGroupBox.setVisible(true);
+ dummy1.setVisible(true);
+ }
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * show the windows
+ * @param user user name
+ * @param isNew true if this is a new entry
+ */
+ public void showDialog(String user) {
+
+ //initialize and setup
+ mUserName = user;
+ mFullNameField.setText("");
+ mEMailField.setText("");
+ mPhoneField.setText("");
+ mStateField.setText("");
+ mPasswordField.setText("");
+ mPasswordConfirm.setText("");
+
+ mDataModel.clear();
+ //mViewCert.setEnabled(false);
+
+ if(!mIsNewUser) {
+ mUserLabel.setText(user);
+ } else {
+ mUserNameField.setText("");
+ mUserLabel.setText("");
+ mStateField.setText("1");
+ }
+
+ //retrieve the cert record from the server
+ try {
+ if (mIsNewUser == false)
+ refresh();
+ else {
+ addGroup();
+ }
+ } catch (EAdminException ex) {
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ ex.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ updateView();
+ this.show();
+ }
+
+ private void enablePasswordFields(boolean enable, Color color) {
+ mPasswordField.setVisible(enable);
+ mPasswordLbl.setVisible(enable);
+ mPasswordConfirm.setVisible(enable);
+ mPasswordConfirmLbl.setVisible(enable);
+ CMSAdminUtil.repaintComp(mPasswordField);
+ CMSAdminUtil.repaintComp(mPasswordConfirm);
+ CMSAdminUtil.repaintComp(mPasswordLbl);
+ CMSAdminUtil.repaintComp(mPasswordConfirmLbl);
+ }
+
+ public boolean isUserAdded() {
+ return mUserAdded;
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+
+ public void actionPerformed(ActionEvent evt) {
+
+ mUserAdded = false;
+ if (evt.getSource().equals(mOK)) {
+
+ //check password field
+ String pwd = mPasswordField.getText().trim();
+ if (!pwd.equals("")) {
+ if (!mPasswordConfirm.getText().trim().equals(pwd)) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, mResource, PREFIX,
+ "PWDNOTMATCH", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ }
+
+ if (mIsNewUser) {
+
+ //check text fields
+ if (mUserNameField.getText().trim().equals("")) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, mResource, PREFIX,
+ "NOUSERNAME", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+
+ try {
+ addUser();
+ mUserAdded = true;
+ } catch (EAdminException e) {
+ //display error dialog
+ Debug.println(e.toString());
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+
+ } else {
+
+ try {
+ modifyUser();
+ } catch (EAdminException e) {
+ //display error dialog
+ Debug.println(e.toString());
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.toString(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+
+ }
+ this.hide();
+ }
+
+ if (evt.getSource().equals(mCancel)) {
+ Debug.println("Cancel Pressed");
+
+ //display are you sure dialog
+ this.hide();
+ }
+
+ if (evt.getSource().equals(mHelp)) {
+ if (mIsNewUser)
+ CMSAdminUtil.help(ADDHELPINDEX);
+ else
+ CMSAdminUtil.help(EDITHELPINDEX);
+ }
+
+ /*
+ * possible enhancement here to put in
+ * a WIZARD that will take 1) B64E ,2)
+ * ldap dir, 3) cert server for retrieval
+ * we will do B64E first
+ *
+ if (evt.getSource().equals(mAddCert)) {
+ //display dialog to add B64E
+ if (mCertDialog==null)
+ mCertDialog = new CertImportDialog(mParentFrame);
+ mCertDialog.showDialog();
+ if (!mCertDialog.isOK())
+ return;
+
+ //add entry
+ Debug.println("Name="+mCertDialog.getCertName());
+ Debug.println("B64E= "+mCertDialog.getB64E());
+ NameValuePairs data = new NameValuePairs();
+ data.add(CERT_NAME,mCertDialog.getCertName());
+ data.add(CERT_DATA,mCertDialog.getB64E());
+ data.add(CERT_VIEW,CERT_B64E);
+ mDataModel.processData(data);
+ refreshTable();
+ }
+
+ if (evt.getSource().equals(mViewCert)) {
+ //display certificate pp
+ NameValuePairs obj = (NameValuePairs)mDataModel.getObjectValueAt
+ (mTable.getSelectedRow());
+ if (mViewDialog==null)
+ mViewDialog = new CertViewDialog(mParentFrame);
+ mViewDialog.showDialog(obj.getValue(CERT_NAME),obj.getValue(CERT_DATA));
+ }
+
+ if (evt.getSource().equals(mDeleteCert)) {
+ if(mTable.getSelectedRow()< 0)
+ return;
+ int i = CMSAdminUtil.showConfirmDialog(mParentFrame, mResource,
+ PREFIX, "DELETE", CMSAdminUtil.WARNING_MESSAGE);
+ if (i == JOptionPane.YES_OPTION) {
+ deleteCert();
+ Debug.println("Cert Deleted");
+ }
+ }
+ */
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ //check if stuff is selected
+ updateView();
+ }
+
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {
+ updateView();
+ }
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {}
+
+
+ //== DocumentListener ==
+ public void insertUpdate(DocumentEvent e) {
+ updateView();
+ }
+
+ public void removeUpdate(DocumentEvent e){
+ updateView();
+ }
+
+ public void changedUpdate(DocumentEvent e){
+ updateView();
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ /**
+ * proactive verification
+ */
+ private void updateView() {
+ if (mIsNewUser) {
+ if (mUserNameField.getText().trim().equals("")) {
+ mOK.setEnabled(false);
+ return;
+ }
+ }
+ if (mFullNameField.getText().trim().equals("")) {
+ mOK.setEnabled(false);
+ return;
+ }
+ /* ONLY UID is verify now
+ if (mPasswordField.getText().trim().equals("")) {
+ mOK.setEnabled(false);
+ return;
+ }
+ */
+ mOK.setEnabled(true);
+ }
+
+ /**
+ * Construction of the initial UI components
+ */
+ private void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+
+ }
+
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null, this);
+ mCancel = CMSAdminUtil.makeJButton(mResource, PREFIX, "CANCEL", null, this);
+ mHelp = CMSAdminUtil.makeJButton(mResource, PREFIX, "HELP", null, this);
+ //JButton[] buttons = { mOK, mCancel, mHelp };
+ JButton[] buttons = { mOK, mCancel };
+ return CMSAdminUtil.makeJButtonPanel( buttons, true);
+ }
+
+ private JPanel makeContentPane() {
+
+ Insets insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,0,
+ CMSAdminUtil.COMPONENT_SPACE,0);
+
+ //top panel
+ JPanel top = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ CMSAdminUtil.resetGBC(gbc);
+ top.setLayout(gb);
+
+ JLabel label1 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "USERNAME", null);
+ mUserNameField = new JTextField();
+ mUserNameField.addMouseListener(this);
+ mUserNameField.getDocument().addDocumentListener(this);
+ mUserLabel = new JLabel();
+ mUserLabel.setVisible(false);
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.anchor = gbc.EAST;
+ gbc. insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ top.add(label1, gbc);
+
+ gbc.anchor = gbc.WEST;
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.weightx = 1.0;
+ gbc. insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,
+ 0,CMSAdminUtil.COMPONENT_SPACE);
+ top.add( mUserLabel, gbc );
+ top.add( mUserNameField, gbc );
+
+ JLabel dummy = new JLabel();
+ dummy.setVisible(false);
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ top.add( dummy, gbc);
+
+ JLabel label2 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "FULLNAME", null);
+ mFullNameField = new JTextField();
+ mFullNameField.addMouseListener(this);
+ mFullNameField.getDocument().addDocumentListener(this);
+ CMSAdminUtil.addEntryField(top, label2, mFullNameField, gbc);
+
+ mPasswordLbl = CMSAdminUtil.makeJLabel(mResource, PREFIX, "PASSWORD", null);
+ mPasswordField = new JPasswordField();
+ mPasswordField.addMouseListener(this);
+ mPasswordField.getDocument().addDocumentListener(this);
+ mActiveColor = mPasswordField.getBackground();
+ CMSAdminUtil.addEntryField(top, mPasswordLbl, mPasswordField, gbc);
+
+ mPasswordConfirmLbl = CMSAdminUtil.makeJLabel(mResource, PREFIX, "PASSWORDCONFIRM", null);
+ mPasswordConfirm = new JPasswordField();
+ mPasswordConfirm.addMouseListener(this);
+ mPasswordConfirm.getDocument().addDocumentListener(this);
+ CMSAdminUtil.addEntryField(top, mPasswordConfirmLbl, mPasswordConfirm, gbc);
+
+ JLabel label4 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "EMAIL", null);
+ mEMailField = new JTextField();
+ CMSAdminUtil.addEntryField(top, label4, mEMailField, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ //gbc.gridheight = gbc.REMAINDER;
+ JLabel label5 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "PHONE", null);
+ mPhoneField = new JTextField();
+ CMSAdminUtil.addEntryField(top, label5, mPhoneField, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ //gbc.gridheight = gbc.REMAINDER;
+ JLabel label51 = CMSAdminUtil.makeJLabel(mResource, PREFIX, "STATE", null);
+ mStateField = new JTextField();
+ CMSAdminUtil.addEntryField(top, label51, mStateField, gbc);
+
+ CMSAdminUtil.resetGBC(gbc);
+ mGroupLbl = CMSAdminUtil.makeJLabel(mResource, PREFIX, "GROUP",null);
+ mGroupBox = new JComboBox();
+ //mGroupBox.addItem("Admin group");
+ dummy1 = new JLabel(" ");
+ CMSAdminUtil.addEntryField(top, mGroupLbl, mGroupBox, dummy1, gbc);
+
+ mMembership = CMSAdminUtil.makeJLabel(mResource, PREFIX, "MEMBER", null);
+ //group membership table
+ mList = CMSAdminUtil.makeJList(mDataModel,6);
+ mScrollPane = new JScrollPane(mList,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION );
+ mList.addMouseListener(this);
+ mScrollPane.setBackground(Color.white);
+
+ mScrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
+ //setLabelCellRenderer(mTable,0);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.fill = gbc.NONE;
+ gbc.weightx = 0.0;
+ gbc.gridwidth = 1;
+ gbc.gridx = 0;
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,0);
+ top.add( mMembership, gbc );
+
+ gbc.gridx++;
+ gbc.anchor = gbc.NORTHWEST;
+ gbc.fill = gbc.BOTH;
+ gbc.weightx = 0.5;
+ gbc.weighty=1.0;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(CMSAdminUtil.COMPONENT_SPACE,
+ CMSAdminUtil.COMPONENT_SPACE,0,CMSAdminUtil.COMPONENT_SPACE);
+ top.add( mScrollPane, gbc );
+
+ return top;
+ }
+
+ //=================================================
+ // RETRIEVE INFO FROM SERVER SIDE
+ //=================================================
+
+ //retrieve group information from the server
+ private void refresh() throws EAdminException {
+
+ //construct NVP
+ NameValuePairs config = new NameValuePairs();
+ config.put(Constants.PR_USER_FULLNAME, "");
+ config.put(Constants.PR_USER_EMAIL, "");
+ config.put(Constants.PR_USER_PHONE, "");
+ config.put(Constants.PR_USER_STATE, "");
+ config.put(Constants.PR_USER_GROUP, "");
+
+ NameValuePairs response;
+ response = mConnection.read(DestDef.DEST_USER_ADMIN,
+ ScopeDef.SC_USERS,
+ mUserName,
+ config);
+
+ //setup the ui
+ mUserNameField.setText(mUserName);
+ mFullNameField.setText(response.get(Constants.PR_USER_FULLNAME));
+ mEMailField.setText(response.get(Constants.PR_USER_EMAIL));
+ mPhoneField.setText(response.get(Constants.PR_USER_PHONE));
+ mStateField.setText(response.get(Constants.PR_USER_STATE));
+
+ //parse group entry
+ String userStr = response.get(Constants.PR_USER_GROUP);
+ if ( (userStr != null) && (!userStr.trim().equals("")) ) {
+ StringTokenizer tokenizer = new StringTokenizer(userStr, ",");
+ while (tokenizer.hasMoreTokens()) {
+ String groupstr = tokenizer.nextToken().trim();
+ mDataModel.addElement(groupstr);
+ }
+ }
+
+ }
+
+ private void addGroup() throws EAdminException {
+ NameValuePairs response = mConnection.search(DestDef.DEST_GROUP_ADMIN,
+ ScopeDef.SC_GROUPS, new NameValuePairs());
+ if (mGroupBox.getItemCount() > 0)
+ mGroupBox.removeAllItems();
+ for (String groupname : response.keySet()) {
+ mGroupBox.addItem(groupname.trim());
+ }
+
+ }
+
+ //add new group information
+ private void addUser() throws EAdminException {
+
+ //construct NVP
+ NameValuePairs config = new NameValuePairs();
+ config.put(Constants.PR_USER_FULLNAME, mFullNameField.getText().trim());
+ config.put(Constants.PR_USER_PASSWORD, mPasswordField.getText().trim());
+ config.put(Constants.PR_USER_EMAIL, mEMailField.getText().trim());
+ config.put(Constants.PR_USER_PHONE, mPhoneField.getText().trim());
+ config.put(Constants.PR_USER_STATE, mStateField.getText().trim());
+ config.put(Constants.PR_USER_GROUP, (String) mGroupBox.getSelectedItem());
+ config.put(Constants.PR_USER_TYPE, "");
+ //config.add(Constants.PR_USER_CERT,"");
+ //createCertEntry(config);
+
+ //send request
+ mConnection.add(DestDef.DEST_USER_ADMIN,
+ ScopeDef.SC_USERS,
+ mUserNameField.getText().trim(),
+ config);
+ }
+
+ //change new group information
+ private void modifyUser() throws EAdminException {
+
+ //construct NVP
+ NameValuePairs config = new NameValuePairs();
+ config.put(Constants.PR_USER_FULLNAME, mFullNameField.getText().trim());
+ config.put(Constants.PR_USER_PASSWORD, mPasswordField.getText().trim());
+ config.put(Constants.PR_USER_EMAIL, mEMailField.getText().trim());
+ config.put(Constants.PR_USER_PHONE, mPhoneField.getText().trim());
+ config.put(Constants.PR_USER_STATE, mStateField.getText().trim());
+ config.put(Constants.PR_USER_TYPE, "");
+ //createCertEntry(config);
+
+ //send request
+ mConnection.modify(DestDef.DEST_USER_ADMIN,
+ ScopeDef.SC_USERS,
+ mUserName,
+ config);
+
+ // #343872
+ // see if it is password change of the currently logged-in
+ // user. If it is the case, we need to update Console password
+ // cache
+ String pwd = mPasswordField.getText().trim();
+ if (!pwd.equals("")) {
+ BasicAuthenticator auth = (BasicAuthenticator)
+ mConnection.getAuthenticator();
+ if (mUserName.equals(auth.getUserid()) &&
+ !pwd.equals(auth.getPassword())) {
+ auth.setPassword(pwd);
+ }
+ }
+ }
+
+ //refresh the table content
+ private void refreshTable() {
+ mScrollPane.repaint(1);
+ }
+
+
+}
+
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/UserListDataModel.java b/base/console/src/com/netscape/admin/certsrv/ug/UserListDataModel.java
new file mode 100644
index 000000000..e66c14d94
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/UserListDataModel.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.admin.certsrv.ug;
+
+import java.util.*;
+import javax.swing.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+
+/**
+ * User List Data model - represents the single column user
+ * table information
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class UserListDataModel extends CMSContentTableModel
+ implements IDataProcessor
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static String[] mColumns = {USERID};
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public UserListDataModel() {
+ super();
+ init(mColumns);
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void processData(Object data) {
+ Vector v = new Vector();
+
+ //XXX NEED TO CHANGE if we are going to have multi-column table
+ v.addElement(new JLabel((String)data,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_USER),
+ JLabel.LEFT));
+ addRow(v, data);
+ }
+
+ /**
+ * get user vector for comparison
+ */
+ public Vector getUsers() {
+ return (Vector) mObjectContainer.clone();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/UserListDialog.java b/base/console/src/com/netscape/admin/certsrv/ug/UserListDialog.java
new file mode 100644
index 000000000..6f0c6215b
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/UserListDialog.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.admin.certsrv.ug;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * User Listing Dialog - <p>
+ *
+ * This dialog support multiple user selection and displays
+ * only users that are not in the current group. This dialog
+ * will be created once and being reused per group editor.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.ug
+ */
+public class UserListDialog extends JDialog
+ implements ActionListener, MouseListener
+{
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private String PREFIX = "USERLISTDIALOG";
+
+ private JFrame mParentFrame;
+ private AdminConnection mConnection;
+ private ResourceBundle mResource;
+ protected DefaultListModel mDataModel;
+ protected Vector mCurrentUsers;
+ protected Vector mSelectedUser;
+
+ private JScrollPane mScrollPane;
+ private JList mList;
+
+ private JButton mOK, mCancel;
+ private boolean mIsOk = false;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public UserListDialog(JFrame parent, AdminConnection conn) {
+ super(parent,true);
+ mParentFrame = parent;
+ mConnection = conn;
+ mSelectedUser = new Vector();
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+ mDataModel = new DefaultListModel();
+ setSize(360, 216);
+ setTitle(mResource.getString(PREFIX+"_TITLE"));
+ setLocationRelativeTo(parent);
+ getRootPane().setDoubleBuffered(true);
+ setDisplay();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * show the windows
+ * @param users list of current users
+ */
+ public void showDialog(Vector users) {
+
+ mCurrentUsers = users;
+ mSelectedUser.removeAllElements();
+
+ //retrieve the cert record from the server
+ try {
+ refresh();
+ } catch (EAdminException ex) {
+ CMSAdminUtil.showMessageDialog(mParentFrame, mResource, PREFIX,
+ "SERVERERROR", CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+ setButtons();
+ mIsOk = false;
+ this.show();
+ }
+
+
+ /**
+ * if selection is ok, the user name will be returned
+ * otherwise, empty string will be returned.
+ * @return user name
+ */
+ public Vector getSelectedUser() {
+ return mSelectedUser;
+ }
+
+ /**
+ * get the exit code
+ * @return true if ok; otherwise false
+ */
+ public boolean isOK() {
+ return mIsOk;
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent evt) {
+ if (evt.getSource().equals(mOK)) {
+ //get selected user
+ int[] rowIndex = mList.getSelectedIndices();
+ //Debug.println("Rows Selected ="+rowIndex.length);
+ for (int j=0; j< rowIndex.length; j++)
+ mSelectedUser.addElement(
+ ((JLabel)mDataModel.elementAt(rowIndex[j])).getText());
+
+ //set return flag
+ mIsOk = true;
+ this.hide();
+ }
+
+ if (evt.getSource().equals(mCancel)) {
+ this.hide();
+ }
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ setButtons();
+ }
+
+ public void mousePressed(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {}
+
+ public void mouseEntered(MouseEvent e) {
+ setButtons();
+ }
+ public void mouseExited(MouseEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ //set buttons
+ private void setButtons() {
+ if (mList.getSelectedIndex()< 0) {
+ mOK.setEnabled(false);
+ return;
+ }
+ mOK.setEnabled(true);
+ }
+
+ private void setDisplay() {
+ getContentPane().setLayout(new BorderLayout());
+ JPanel center = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ center.setLayout(gb);
+
+ //content panel
+ JPanel content = makeContentPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.fill = gbc.BOTH;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gb.setConstraints(content, gbc);
+ center.add(content);
+
+ //action panel
+ JPanel action = makeActionPane();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gb.setConstraints(action, gbc);
+ center.add(action);
+
+ getContentPane().add("Center",center);
+ }
+
+ private JPanel makeActionPane() {
+ mOK = CMSAdminUtil.makeJButton(mResource, PREFIX, "OK", null, this);
+ mCancel = CMSAdminUtil.makeJButton(mResource, PREFIX, "CANCEL", null, this);
+ JButton[] buttons = { mOK, mCancel};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonPanel( buttons );
+ }
+
+ private JPanel makeContentPane() {
+ JPanel mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ mList = CMSAdminUtil.makeJList(mDataModel,9);
+ mScrollPane = new JScrollPane(mList,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+ mList.addMouseListener(this);
+ mScrollPane.setBackground(Color.white);
+ mScrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = gbc.BOTH;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ return mListPanel;
+
+ /*
+ JPanel content = new JPanel();
+ GridBagLayout gb3 = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ content.setLayout(gb3);
+ //content.setBorder(CMSAdminUtil.makeEtchedBorder());
+
+ //left side certificate table
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ //mScrollPane.setBorder(CMSAdminUtil.makeTitledBorder(mResource,PREFIX,"CERTIFICATE"));
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ int width = CMSAdminUtil.getTotalColumnWidth( mTable );
+ //Dimension d = new Dimension( width, mTable.getRowHeight()*14);
+ //mTable.setMinimumSize( d );
+ //mTable.setSize( d );
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+ //mTable.getSelectionModel().addListSelectionListener(new StandardListSelectionListener());
+ //mTable.addMouseListener(this);
+ //mTable.setPreferredScrollableViewportSize(d);
+ setLabelCellRenderer(mTable,0);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weighty = 1.0;
+ gbc.weightx = 1.0;
+ gb3.setConstraints(mScrollPane, gbc);
+ content.add(mScrollPane);
+
+ return content;
+ */
+ }
+
+ /*Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(new LabelCellRenderer(new JLabel()));
+ }
+ */
+
+ //=================================================
+ // RETRIEVE INFO FROM SERVER SIDE
+ //=================================================
+
+ //retrieve group information from the server
+ private void refresh() throws EAdminException {
+ mDataModel.removeAllElements();
+
+ NameValuePairs response;
+ try {
+ response = mConnection.search(DestDef.DEST_USER_ADMIN,
+ ScopeDef.SC_USERS,
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ CMSAdminUtil.showErrorDialog(mParentFrame, mResource,
+ e.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
+ return;
+ }
+
+ //parse the data
+/*
+ Vector store = new Vector();
+ for (Enumeration e = response.getNames(); e.hasMoreElements() ;) {
+ String entry = ((String)e.nextElement()).trim();
+ if (mCurrentUsers.indexOf(entry)== -1)
+ store.addElement(entry);
+ }
+
+ String[] vals = new String[store.size()];
+ store.copyInto(vals);
+*/
+
+ String responseValue = response.get("userInfo");
+
+ StringTokenizer tokenizer = new StringTokenizer(responseValue, ";");
+ StringTokenizer subTokenizer = null;
+
+ Vector store = new Vector();
+ Hashtable table = new Hashtable();
+
+ while (tokenizer.hasMoreTokens()) {
+ String t = (String)tokenizer.nextToken();
+ subTokenizer = new StringTokenizer(t, ":");
+ int i=0;
+ String str1 = null;
+ String str2 = null;
+ while (subTokenizer.hasMoreTokens()) {
+ if (i == 0) {
+ str1 = (String)subTokenizer.nextToken();
+ store.addElement(str1);
+ } else {
+ str2 = (String)subTokenizer.nextToken();
+ table.put(str1, str2);
+ }
+ i++;
+ }
+ }
+
+ String[] vals = new String[store.size()];
+ store.copyInto(vals);
+
+ CMSAdminUtil.bubbleSort(vals);
+
+ for (int y=0; y< vals.length ; y++) {
+ mDataModel.addElement(new JLabel(vals[y],
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_USER),
+ JLabel.LEFT));
+ }
+
+ refreshTable();
+ }
+
+ //refresh the table content
+ private void refreshTable() {
+ //mTable.invalidate();
+ //mTable.validate();
+ //mTable.repaint(1);
+ //mScrollPane.invalidate();
+ //mScrollPane.validate();
+ //mScrollPane.repaint(1);
+ //repaint();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/ug/UserTab.java b/base/console/src/com/netscape/admin/certsrv/ug/UserTab.java
new file mode 100644
index 000000000..78b7e5252
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/ug/UserTab.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.admin.certsrv.ug;
+
+import com.netscape.admin.certsrv.*;
+import com.netscape.admin.certsrv.connection.*;
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+import java.util.*;
+
+import com.netscape.management.client.util.*;
+import com.netscape.certsrv.common.*;
+
+/**
+ * User Tab - this UI component provides the user
+ * management functionality of the certificate server.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ *
+ * @see com.netscape.admin.certsrv.ug.CertImportDialog
+ * @see com.netscape.admin.certsrv.ug.CertManagementDialog
+ * @see com.netscape.admin.certsrv.ug.CertViewDialog
+ * @see com.netscape.admin.certsrv.ug.UserEditor
+ */
+public class UserTab extends CMSBaseUGTab {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PANEL_NAME = "USERTAB";
+ private AdminConnection mConnection;
+
+ protected JScrollPane mScrollPane;
+ protected JTable mTable; //table
+ protected UserDataModel mDataModel; //table model
+ protected UserEditor mEditor=null; //keep single copy
+ protected UserEditor mAddEditor=null; //keep single copy
+ protected CertManagementDialog mCertEditor=null; //single copy
+ protected JButton mRefresh, mEdit, mAdd, mDelete, mHelp, mCert;
+ private final static String HELPINDEX = "usersgroups-certsrv-users-help";
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public UserTab(CMSBaseResourceModel model) {
+ super(PANEL_NAME, model);
+ mConnection = model.getServerInfo().getAdmin();
+ mDataModel = new UserDataModel();
+ mHelpToken = HELPINDEX;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * refresh the content of the tab
+ * IRefreshTab menthod
+ */
+ public void refresh() {
+ //Debug.println("refresh() user tab");
+
+ mDataModel.removeAllRows();
+ updateUser();
+ setButtons();
+ mTable.invalidate();
+ mTable.validate();
+ mScrollPane.invalidate();
+ mScrollPane.validate();
+ mScrollPane.repaint(1);
+ }
+
+ /*==========================================================
+ * EVNET HANDLER METHODS
+ *==========================================================*/
+
+ //=== ACTIONLISTENER =====================
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(mRefresh)) {
+ Debug.println("Refresh User");
+ refresh();
+ } else if (e.getSource().equals(mEdit)) {
+ if(mTable.getSelectedRow()< 0)
+ return;
+
+ Debug.println("Edit User");
+ String userName = (String)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+
+ mAddEditor = new UserEditor(mModel.getFrame(), mConnection,
+ false);
+ mAddEditor.showDialog(userName);
+ mAddEditor.dispose();
+ refresh();
+ } else if (e.getSource().equals(mAdd)) {
+ mAddEditor = new UserEditor(mModel.getFrame(), mConnection, true);
+ mAddEditor.showDialog("");
+ if (mAddEditor.isUserAdded())
+ refresh();
+ mAddEditor.dispose();
+ } else if (e.getSource().equals(mDelete)) {
+ Debug.println("Delete User");
+ if(mTable.getSelectedRow()< 0)
+ return;
+ int i = showConfirmDialog("DELETE");
+ if (i == JOptionPane.YES_OPTION) {
+ deleteUser();
+ Debug.println("User Deleted");
+ }
+ } else if (e.getSource().equals(mHelp)) {
+ helpCallback();
+ } else if (e.getSource().equals(mCert)) {
+ String userName = (String)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+ if (mCertEditor==null)
+ mCertEditor = new CertManagementDialog(mModel.getFrame(), mConnection);
+ mCertEditor.showDialog(userName);
+ Debug.println("Cert");
+ //refresh();
+ //XXX HELP
+ }
+ }
+
+ //==== MOUSELISTENER ======================
+ public void mouseClicked(MouseEvent e) {
+ //Debug.println("CertRepositoryPanel: mouseClicked() -"+e.toString());
+ setButtons();
+
+ //we track the double click action on the table entry - View op
+ if(mTable.getSelectedRow() >= 0) {
+ if(e.getClickCount() == 2) {
+ Debug.println("Edit User");
+ //editUser();
+ }
+ }
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ setButtons();
+ }
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+
+ /**
+ * create the user action button panel
+ */
+ protected JPanel createUserButtonPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mEdit = makeJButton("EDIT");
+ mAdd = makeJButton("ADD");
+ mDelete = makeJButton("DELETE");
+ mCert = makeJButton("CERT");
+ JButton[] buttons = {mAdd, mDelete, mEdit, mCert};
+ JButtonFactory.resize( buttons );
+ return CMSAdminUtil.makeJButtonVPanel( buttons );
+ }
+
+ protected JPanel createActionPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+ mRefresh = makeJButton("REFRESH");
+ mHelp = makeJButton("HELP");
+ //JButton[] buttons = { mRefresh, mHelp };
+ JButton[] buttons = { mRefresh };
+ return makeJButtonPanel( buttons, true);
+ }
+
+ protected JPanel createListPanel() {
+ mListPanel = new JPanel();
+ GridBagLayout gb = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+ mListPanel.setLayout(gb);
+
+ //center table
+ mTable = new JTable(mDataModel);
+ mScrollPane = JTable.createScrollPaneForTable(mTable);
+ //mScrollPane.setBorder(CMSAdminUtil.makeTitledBorder(mResource,PANEL_NAME,"USERS"));
+ mScrollPane.setHorizontalScrollBarPolicy(mScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mScrollPane.setVerticalScrollBarPolicy(mScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ mTable.setAutoscrolls(true);
+ mTable.sizeColumnsToFit(true);
+ mTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ mTable.getSelectionModel().addListSelectionListener(this);
+ mTable.addMouseListener(this);
+ mScrollPane.setBackground(Color.white);
+ setLabelCellRenderer(mTable,0);
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.fill = gbc.BOTH;
+ gbc.gridwidth = 1;
+ gbc.weightx = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(mScrollPane, gbc);
+ mListPanel.add(mScrollPane);
+
+ JPanel buttonPanel = createUserButtonPanel();
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.NORTH;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.weightx = 0.0;
+ gbc.weighty = 1.0;
+ gbc.insets = EMPTY_INSETS;
+ gb.setConstraints(buttonPanel, gbc);
+ mListPanel.add(buttonPanel);
+
+ refresh();
+
+ return mListPanel;
+ }
+
+ //Set the first column's cellrender as label cell
+ protected void setLabelCellRenderer(JTable table, int index) {
+ table.getColumnModel().getColumn(index).setCellRenderer(new LabelCellRenderer(new JLabel()));
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ /**
+ * set buttons - proactive verification
+ */
+ private void setButtons() {
+
+ //enable and diable buttons accordingly
+ if (mTable.getSelectionModel().isSelectionEmpty()) {
+ mDelete.setEnabled(false);
+ mEdit.setEnabled(false);
+ mCert.setEnabled(false);
+ return;
+ }
+
+ if(mDataModel.getRowCount()< 0) {
+ mDelete.setEnabled(false);
+ mEdit.setEnabled(false);
+ mCert.setEnabled(false);
+ return;
+ }
+
+ mDelete.setEnabled(true);
+ mEdit.setEnabled(true);
+ mCert.setEnabled(true);
+
+ }
+
+ //=============================================
+ // SEND REQUESTS TO THE SERVER SIDE
+ //=============================================
+
+ private void updateUser() {
+ //send request and parse data
+
+ NameValuePairs response;
+ mModel.progressStart();
+
+ try {
+ response = mConnection.search(DestDef.DEST_USER_ADMIN,
+ ScopeDef.SC_USERS,
+ new NameValuePairs());
+ } catch (EAdminException e) {
+ //display error dialog
+ showErrorDialog(e.getMessage());
+ mModel.progressStop();
+ return;
+ }
+
+ Debug.println(response.toString());
+
+ String responseValue = response.get("userInfo");
+
+ StringTokenizer tokenizer = new StringTokenizer(responseValue, ";");
+ StringTokenizer subTokenizer = null;
+
+ Vector store = new Vector();
+ Hashtable table = new Hashtable();
+
+ while (tokenizer.hasMoreTokens()) {
+ String t = (String)tokenizer.nextToken();
+ subTokenizer = new StringTokenizer(t, ":");
+ int i=0;
+ String str1 = null;
+ String str2 = null;
+ while (subTokenizer.hasMoreTokens()) {
+ if (i == 0) {
+ str1 = (String)subTokenizer.nextToken();
+ store.addElement(str1);
+ } else {
+ str2 = (String)subTokenizer.nextToken();
+ table.put(str1, str2);
+ }
+ i++;
+ }
+ }
+
+ String[] names = new String[store.size()];
+ store.copyInto(names);
+
+ if (names.length > 1) {
+ names = CMSAdminUtil.randomize(names);
+ CMSAdminUtil.quickSort(names, 0, names.length-1);
+ }
+
+ for (int y=0; y< names.length ; y++) {
+ String s = (String)table.get(names[y]);
+ mDataModel.processData(names[y], s);
+ }
+
+ if (mDataModel.getRowCount() >0)
+ mTable.setRowSelectionInterval(0,0);
+
+ mModel.progressStop();
+ }
+
+ private void deleteUser() {
+ //get entry name
+ String userName = (String)
+ mDataModel.getObjectValueAt(mTable.getSelectedRow());
+
+ mModel.progressStart();
+ //send comment to server for the removal of user
+ try {
+ mConnection.delete(DestDef.DEST_USER_ADMIN,
+ ScopeDef.SC_USERS,
+ userName);
+ } catch (EAdminException e) {
+ String str = e.toString();
+
+ if (str.indexOf("The user") == 0) {
+ int i =
+ JOptionPane.showConfirmDialog(new JFrame(), str,
+ "Information", JOptionPane.YES_NO_OPTION,
+ JOptionPane.INFORMATION_MESSAGE,
+ CMSAdminUtil.getImage(CMSAdminResources.IMAGE_INFO_ICON));
+ if (i == JOptionPane.YES_OPTION) {
+ Debug.println("User Deleted");
+ try {
+ mConnection.delete(DestDef.DEST_USER_ADMIN,
+ ScopeDef.SC_USERS,
+ userName+":true");
+ } catch (EAdminException ee) {
+ showErrorDialog(ee.getMessage());
+ }
+ }
+ }
+ }
+
+ mModel.progressStop();
+ //send comment to server and refetch the content
+ refresh();
+ }
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/wizard/ConfigServlet.java b/base/console/src/com/netscape/admin/certsrv/wizard/ConfigServlet.java
new file mode 100644
index 000000000..5ed3195b9
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/wizard/ConfigServlet.java
@@ -0,0 +1,24 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.wizard;
+
+import java.net.*;
+
+public interface ConfigServlet {
+ public boolean send(String s, WizardInfo wizardInfo);
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/wizard/IWizardDone.java b/base/console/src/com/netscape/admin/certsrv/wizard/IWizardDone.java
new file mode 100644
index 000000000..5576278c4
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/wizard/IWizardDone.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.admin.certsrv.wizard;
+
+import javax.swing.*;
+
+public interface IWizardDone {
+
+ /**
+ * Called by WizardWidget when all panels are executed.
+ */
+ public void notify(WizardWidget w);
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/wizard/IWizardPanel.java b/base/console/src/com/netscape/admin/certsrv/wizard/IWizardPanel.java
new file mode 100644
index 000000000..1b729b70f
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/wizard/IWizardPanel.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.admin.certsrv.wizard;
+
+import javax.swing.*;
+
+/**
+ * Interface for WizardWidget delegation.<p>
+ * The methods will be call in the following order: <br>
+ * <pre>
+ * initialize(WizardInfo);
+ * validate();
+ * conclude(WizardInfo);
+ * getUpdateInfo(WizardInfo);
+ * </pre>
+ * For example, you can assume the WizardPanel is validated already
+ * when getUpdateInfo() is called.<p>
+ * REMEMBER TO SET THE ERROR WHEN ERROR OCCURRED!<p>
+ *
+ * @author jpanchen
+ * @version %I%, %G%
+ * @date 12/02/97
+ * @see com.netscape.admin.certsrv.wizard
+ */
+public interface IWizardPanel {
+
+ /**
+ * Initialize the panel. Data are passed in
+ * as WinzardInfo. Class implements this interface is responsible
+ * for maintaining the state information. Usually, you just
+ * need to have a dummy function if you are not using
+ * information provided by the previous screen to config/generate
+ * this screen. If error occurred, return false and set error
+ * message to be retrieved by getErrorMessage().
+ * @return true if ok; otherwise, false.
+ */
+ public abstract boolean initializePanel(WizardInfo info);
+
+ /**
+ * Verify the panel. The implementation should check for
+ * errors at this time. If error found, return false, and
+ * set error message to be retrieved by getErrorMessage().
+ * @return true if ok; otherwise, false.
+ */
+ public abstract boolean validatePanel();
+
+ /**
+ * Performs post processing. This function is call after
+ * the panel is verified.
+ * Ususally the LAST IWizardPanel use this method to perform
+ * save/update operation on the server via cgi/rmi/ldap.
+ * Similar to validate(), if error found, return false and
+ * set error message to be retrieved by getErrorMessage().
+ * @return true if ok; otherwise, false.
+ */
+ public abstract boolean concludePanel(WizardInfo info);
+
+ /**
+ * Save panel information into the WizardInfo to be passed
+ * on to the next screen.
+ */
+ public abstract void getUpdateInfo(WizardInfo info);
+
+ /**
+ * Error Message delegation. This method should return
+ * an I18N supported string detailing the error.
+ * @return string represenation of error
+ */
+ public abstract String getErrorMessage();
+
+ /**
+ * Display Help for this page
+ */
+ public abstract void callHelp();
+
+ /**
+ * Get title for this page
+ */
+ public abstract String getTitle();
+
+ public boolean isLastPage();
+
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/wizard/WizardBasePanel.java b/base/console/src/com/netscape/admin/certsrv/wizard/WizardBasePanel.java
new file mode 100644
index 000000000..c31767d99
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/wizard/WizardBasePanel.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.admin.certsrv.wizard;
+
+import java.awt.*;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionListener;
+import java.util.*;
+import javax.swing.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.management.client.util.*;
+import javax.swing.border.*;
+import java.net.*;
+import java.io.*;
+
+/**
+ * Wizard Base Panel
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ * @see com.netscape.admin.certsrv.config
+ */
+public class WizardBasePanel extends CMSBasePanel implements MouseMotionListener,
+ ConfigServlet {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ protected String mTitle;
+ protected String mErrorString;
+ protected String mNextString =
+ mResource.getString("GENERALWIZARD_LABEL_NEXT_LABEL");
+ protected String mPanelName;
+ public static long mSeed;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public WizardBasePanel(String name) {
+ super(name);
+ mTitle = mResource.getString(name+"_TITLE");
+ mPanelName = name;
+ addMouseMotionListener(this);
+ }
+
+ public WizardBasePanel(String name, ResourceBundle rb) {
+ super(name, rb);
+ mPanelName = name;
+ try {
+ mTitle = mResource.getString(name+"_TITLE");
+ } catch (MissingResourceException e) {
+ mTitle = "Missing Title";
+ }
+ addMouseMotionListener(this);
+ }
+
+ protected void init() {
+
+/*
+ GridBagConstraints gbc = new GridBagConstraints();
+
+ CMSAdminUtil.resetGBC(gbc);
+ gbc.anchor = gbc.SOUTHWEST;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.gridheight = gbc.REMAINDER;
+ gbc.insets = new Insets(COMPONENT_SPACE,COMPONENT_SPACE,
+ COMPONENT_SPACE,COMPONENT_SPACE);
+ JLabel nextLabel = new JLabel(mNextString);
+ add(nextLabel, gbc);
+
+ setBorder(makeTitledBorder(mPanelName));
+*/
+ }
+
+ protected JTextArea createTextArea(String str, int row, int col) {
+ JTextArea desc = new JTextArea(str, row, col);
+ desc.setBackground(getBackground());
+ desc.setEditable(false);
+ desc.setCaretColor(getBackground());
+
+ return desc;
+ }
+
+ protected JTextArea createTextArea(String str) {
+ JTextArea desc = new JTextArea(str);
+ desc.setBackground(getBackground());
+ desc.setEditable(false);
+ desc.setCaretColor(getBackground());
+ desc.setLineWrap(true);
+ desc.setWrapStyleWord(true);
+
+ return desc;
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ /**
+ * Returns the title of the tab
+ * @return string representation of the title
+ */
+ public String getTitle() {
+ return mTitle;
+ }
+
+ /**
+ * Returns the error string
+ */
+ public String getErrorMessage() {
+ return mErrorString;
+ }
+
+ /**
+ * Set error string
+ */
+ public void setErrorMessage(String keyword) {
+ try {
+ String err = mResource.getString(mPanelName+"_DIALOG_"+keyword+"_MESSAGE");
+ mErrorString = err;
+ } catch (MissingResourceException e) {
+ mErrorString = keyword;
+ }
+ }
+
+ public void cleanUpWizardInfo(WizardInfo wizardInfo) {
+ wizardInfo.remove("NMC_WARNINFO");
+ wizardInfo.remove("NMC_ERRINFO");
+ wizardInfo.remove("NMC_STATUS");
+ }
+
+ public String getErrorMessage(WizardInfo wizardInfo) {
+ String value = (String)wizardInfo.get("NMC_ERRINFO");
+ if (value != null || value.trim().length() == 0)
+ return value;
+ value = (String)wizardInfo.get("NMC_WARNINFO");
+ if (value != null || value.trim().length() == 0)
+ return value;
+
+ return null;
+ }
+
+ public boolean send(String host, int port, String servlet, String rawData,
+ WizardInfo wizardInfo) {
+ try {
+ Socket socket = new Socket(host, port);
+ DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
+ InputStream is = socket.getInputStream();
+ String spost = "POST "+servlet+" HTTP/1.0\r\n";
+ byte[] b = rawData.getBytes();
+ dos.writeBytes(spost);
+ dos.writeBytes("User-Agent: HTTPTool/1.0\r\n");
+ dos.writeBytes("Content-length: " + b.length + "\r\n");
+ dos.writeBytes("Content-Type: application/x-www-form-urlencoded\r\n");
+ dos.writeBytes("\r\n");
+ dos.write(b);
+ dos.writeBytes("\r\n");
+ dos.flush();
+
+ ByteArrayOutputStream bstream = new ByteArrayOutputStream(10000);
+ while (true)
+ {
+ int r = is.read();
+ if (r == -1)
+ break;
+ bstream.write(r);
+ }
+
+ socket.close();
+ String test = bstream.toString();
+
+ StringTokenizer tokenizer = new StringTokenizer(test, "\r\n");
+ while (tokenizer.hasMoreTokens()) {
+ String nvalue = tokenizer.nextToken();
+ System.out.println("tokenizer="+nvalue);
+ StringTokenizer tokenizer1 = new StringTokenizer(nvalue, ":");
+ int numTokens = tokenizer1.countTokens();
+ if (numTokens == 2) {
+ String name = tokenizer1.nextToken().trim();
+ String value = tokenizer1.nextToken().trim();
+ wizardInfo.put(name, value);
+ }
+ }
+ bstream.close();
+ String sendStatus = (String)wizardInfo.get("NMC_STATUS");
+ if (sendStatus.equals("0")) {
+ return true;
+ } else {
+ return false;
+ }
+ } catch (Exception e) {
+ }
+
+ return false;
+ }
+
+ public boolean send(String rawData, WizardInfo wizardInfo) {
+ try {
+ Socket socket = new Socket("droopy-linux.sfbay.redhat.com", 1924);
+ DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
+ InputStream is = socket.getInputStream();
+ String servlet = "/config/configSubsystem";
+ String spost = "POST "+servlet+" HTTP/1.0\r\n";
+ byte[] b = rawData.getBytes();
+ dos.writeBytes(spost);
+ dos.writeBytes("User-Agent: HTTPTool/1.0\r\n");
+ dos.writeBytes("Content-length: " + b.length + "\r\n");
+ dos.writeBytes("Content-Type: application/x-www-form-urlencoded\r\n");
+ dos.writeBytes("\r\n");
+ dos.write(b);
+ dos.writeBytes("\r\n");
+ dos.flush();
+
+ ByteArrayOutputStream bstream = new ByteArrayOutputStream(10000);
+ while (true)
+ {
+ int r = is.read();
+ if (r == -1)
+ break;
+ bstream.write(r);
+ }
+
+ socket.close();
+ String test = bstream.toString();
+
+ StringTokenizer tokenizer = new StringTokenizer(test, "\r\n");
+ while (tokenizer.hasMoreTokens()) {
+ String nvalue = tokenizer.nextToken();
+ System.out.println("tokenizer="+nvalue);
+ StringTokenizer tokenizer1 = new StringTokenizer(nvalue, ":");
+ int numTokens = tokenizer1.countTokens();
+ if (numTokens == 2) {
+ String name = tokenizer1.nextToken().trim();
+ String value = tokenizer1.nextToken().trim();
+ wizardInfo.put(name, value);
+ }
+ }
+ bstream.close();
+ String sendStatus = (String)wizardInfo.get("NMC_STATUS");
+ if (sendStatus.equals("0")) {
+ return true;
+ } else {
+ return false;
+ }
+ } catch (Exception e) {
+ }
+
+ return false;
+ }
+
+ /*==========================================================
+ * EVENT HANDLER METHODS
+ *==========================================================*/
+
+ /*
+ * mouselistener events - for JPanel
+ */
+
+ /**
+ * This lets us know when someone move the mouse, so we can
+ * keep coordidate of mouse posion and use this value as a random seed
+ */
+ public void mouseDragged(MouseEvent e) {
+ // Do nothing for this
+ }
+
+ public void mouseMoved(MouseEvent e) {
+ // Keep tracking coordinate values
+ long x = e.getX();
+ long y = e.getY();
+
+ long top = mSeed >> 62;
+ mSeed = ((mSeed << 2) ^ top ^ (x<<8) ^ (y)) % Long.MAX_VALUE;
+ }
+}
diff --git a/base/console/src/com/netscape/admin/certsrv/wizard/WizardInfo.java b/base/console/src/com/netscape/admin/certsrv/wizard/WizardInfo.java
new file mode 100644
index 000000000..5085d43b4
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/wizard/WizardInfo.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.admin.certsrv.wizard;
+
+import javax.swing.*;
+import java.util.Properties;
+
+/**
+ * Wizard Data Container
+ */
+public class WizardInfo extends Properties {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ protected JButton mBNext_Done, mBCancel, mBBack;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+ public WizardInfo() {
+ super();
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+ public void addEntry(String name, Object entry) {
+ put(name, entry);
+ }
+
+ public Object getEntry(String name) {
+ return get(name);
+ }
+
+ /**
+ * access method to NEXT-DONE function buttons
+ */
+ public JButton getNextDoneButton() {
+ return mBNext_Done;
+ }
+
+ /**
+ * access method to CANCEL function buttons
+ */
+ public JButton getCancelButton() {
+ return mBCancel;
+ }
+
+ /**
+ * access method to BACK function buttons
+ */
+ public JButton getBackButton() {
+ return mBBack;
+ }
+
+ /*==========================================================
+ * package methods
+ *==========================================================*/
+
+ /**
+ * set function buttons. Called by the WizardWidget to set the
+ * button reference.
+ */
+ void setButtons(JButton next, JButton cancel, JButton back ) {
+ mBNext_Done = next;
+ mBCancel = cancel;
+ mBBack = back;
+ }
+}
+
+
+
diff --git a/base/console/src/com/netscape/admin/certsrv/wizard/WizardWidget.java b/base/console/src/com/netscape/admin/certsrv/wizard/WizardWidget.java
new file mode 100644
index 000000000..c98d37b51
--- /dev/null
+++ b/base/console/src/com/netscape/admin/certsrv/wizard/WizardWidget.java
@@ -0,0 +1,428 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.admin.certsrv.wizard;
+
+import java.util.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import com.netscape.admin.certsrv.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.management.client.util.*;
+import com.netscape.admin.certsrv.config.install.*;
+import com.netscape.admin.certsrv.task.*;
+import com.netscape.management.client.console.*;
+
+/**
+ * WizardWidget provides the most fundamental functionalities
+ * of an wizard widget.
+ *
+ * @author jpanchen
+ * @version %I%, %G%
+ * @date 12/02/97
+ * @see com.netscape.admin.certsrv.wizard
+ */
+public class WizardWidget extends JDialog implements ActionListener
+{
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private static final String PANELNAME = "WIZARD";
+ //static final Dimension DEFAULT_SIZE = new Dimension(460,520);
+ static final Dimension DEFAULT_SIZE = new Dimension(480,600);
+ static final Dimension BUTTON_MIN_SIZE = new Dimension(100,30);
+ static final int STRUT_SIZE = 10;
+
+ //private variables
+ private JButton mBNext_Done, mBCancel, mBBack, mBHelp;
+ private Stack mPrevScreen = new Stack();
+ private Stack mNextScreen = new Stack();
+ protected JPanel mCurrent = null;
+ protected JPanel mDisplay;
+ private String mDoneLabel, mNextLabel;
+
+ protected ResourceBundle mResource;
+ private WizardInfo mInfo;
+ private JFrame mParent;
+ private Dimension mSize;
+ private IWizardDone mWizDone;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ /**
+ * Construct Wizard with specified title and parent frame.
+ * @param parent parent frame
+ * @param title string to be displayed on the dialog box title bar
+ * @param size specify wizard size
+ */
+ public WizardWidget(JFrame parent, Dimension size, IWizardDone wizDone) {
+ this(parent, wizDone);
+ mSize = size;
+ setSize(size.width, size.height);
+ }
+
+ /**
+ * Construct Wizard with specified title and parent frame.
+ * @param parent parent frame
+ * @title string to be displayed on the dialog box title bar
+ */
+ public WizardWidget(JFrame parent) {
+ this(parent, null);
+ }
+
+ public WizardWidget(JFrame parent, IWizardDone wizDone) {
+ //super(parent, title, true); XXX JDK 1.1.4 Bug
+ super(parent, true);
+ mSize = DEFAULT_SIZE;
+ mParent = parent;
+ getContentPane().setLayout(new BorderLayout());
+ setSize(mSize.width, mSize.height);
+ getRootPane().setDoubleBuffered(true);
+ setLocationRelativeTo(parent);
+ mInfo = new WizardInfo();
+ mWizDone = wizDone;
+ mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
+
+ mNextLabel = mResource.getString(CMSAdminResources.GENERAL_NEXT);
+ mDoneLabel = mResource.getString(CMSAdminResources.GENERAL_DONE);
+
+ //create display panel
+ mDisplay = new JPanel();
+ mDisplay.setLayout(new BorderLayout());
+ mDisplay.setBorder(new EmptyBorder(CMSAdminUtil.DIFFERENT_COMPONENT_SPACE,
+ CMSAdminUtil.DIFFERENT_COMPONENT_SPACE,
+ 0,CMSAdminUtil.DIFFERENT_COMPONENT_SPACE));
+/*
+ mDisplay.setBorder(new CompoundBorder(
+ new EmptyBorder(CMSAdminUtil.DIFFERENT_COMPONENT_SPACE,
+ CMSAdminUtil.DIFFERENT_COMPONENT_SPACE,
+ 0,CMSAdminUtil.DIFFERENT_COMPONENT_SPACE),
+ BorderFactory.createEtchedBorder()));
+*/
+ getContentPane().add("Center",mDisplay);
+
+ //create button panel
+
+ //buttonPanel.add(Box.createGlue());
+ getContentPane().add("South", createActionPanel());
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * get parent frame
+ * @return parent frame
+ */
+ public JFrame getFrame() {
+ return mParent;
+ }
+
+ /**
+ * Add a IWizardPanel into wizard. Note the sequence you add
+ * will the be the sequence it will appear.
+ * @param page IWizardPanel to be displayed
+ */
+ public void addPage(JPanel page) {
+ if (mCurrent == null) {
+ mCurrent = page;
+ mDisplay.add("Center",page);
+ initializeWizardPanel();
+ } else {
+ mNextScreen.insertElementAt(page, 0);
+ }
+ }
+
+ /**
+ * Action Performed when button pressed. ActionListener implementation.
+ * @param event
+ */
+ public void actionPerformed(ActionEvent e) {
+
+ //DONE or NEXT Pressed
+ if (e.getSource().equals(mBNext_Done)) {
+
+ if (!validateWizardPanel()) {
+ return;
+ }
+
+ if (concludeWizardPanel()) {
+
+ if (mNextScreen.empty() || mBNext_Done.getText().equals("Done")) {
+ //killDaemon();
+ this.dispose();
+ if (mWizDone != null) {
+ mWizDone.notify(this);
+ }
+ return;
+ } else {
+ updateWizardInfo();
+ mPrevScreen.push(mCurrent);
+ mDisplay.remove(mCurrent);
+ mCurrent = (JPanel)(mNextScreen.pop());
+ while (!initializeWizardPanel()) {
+ //move to next
+ if (mNextScreen.empty()) {
+ this.dispose();
+ return;
+ }
+ mPrevScreen.push(mCurrent);
+ mCurrent = (JPanel)(mNextScreen.pop());
+ }
+ mDisplay.add("Center",mCurrent);
+ mDisplay.invalidate();
+ mDisplay.validate();
+ mDisplay.repaint(1);
+ getRootPane().paintImmediately(getRootPane().getVisibleRect());
+ }
+
+ } else {
+ return;
+ }
+ }
+
+ //Cancel Pressed
+ if (e.getSource().equals(mBCancel)) {
+ //prompt for confirm
+ int option = CMSAdminUtil.showConfirmDialog(mParent, mResource,
+ PANELNAME, "EXIT",
+ JOptionPane.YES_NO_OPTION);
+ if (option == JOptionPane.YES_OPTION) {
+ //killDaemon();
+ this.dispose();
+ }
+ }
+
+ //Back Pressed
+ if (e.getSource().equals(mBBack)) {
+ back_cb(mInfo);
+ //move back to previous page
+ if (!(mPrevScreen.empty())) {
+ mNextScreen.push(mCurrent);
+ mDisplay.remove(mCurrent);
+ mCurrent = (JPanel)(mPrevScreen.pop());
+ while (!initializeWizardPanel()) {
+ //move to prev
+ if (mPrevScreen.empty()) {
+ return;
+ }
+ mNextScreen.push(mCurrent);
+ mCurrent = (JPanel)(mPrevScreen.pop());
+ }
+ mDisplay.add("Center",mCurrent);
+ mDisplay.invalidate();
+ mDisplay.validate();
+ mDisplay.repaint(1);
+ getRootPane().paintImmediately(getRootPane().getVisibleRect());
+ }
+ }
+
+ //Help Pressed
+ if (e.getSource().equals(mBHelp)) {
+ callHelp();
+ }
+
+ changeButton();
+ }
+
+ /**
+ * This method is only for installation wizard.
+ */
+/*
+ private void killDaemon() {
+ if (mInfo instanceof InstallWizardInfo) {
+ InstallWizardInfo wizardInfo = (InstallWizardInfo)mInfo;
+ ConsoleInfo consoleInfo = wizardInfo.getAdminConsoleInfo();
+ CMSConfigCert configCertCgi = new CMSConfigCert();
+ configCertCgi.initialize(wizardInfo);
+ Hashtable data = new Hashtable();
+ data.put(ConfigConstants.TASKID, TaskId.TASK_EXIT);
+ data.put(ConfigConstants.OPTYPE, OpDef.OP_MODIFY);
+ data.put(ConfigConstants.PR_CERT_INSTANCE_NAME,
+ consoleInfo.get(ConfigConstants.PR_CERT_INSTANCE_NAME));
+ data.put(ConfigConstants.PR_SERVER_ROOT,
+ consoleInfo.get(ConfigConstants.PR_SERVER_ROOT));
+ boolean ready = configCertCgi.configCert(data);
+ data.clear();
+ data = null;
+ }
+ }
+*/
+
+ /*==========================================================
+ * protected methods
+ *==========================================================*/
+
+ protected JPanel createActionPanel() {
+ //edit, add, delete, help buttons required
+ //actionlister to this object
+
+ mBBack = new JButton();
+ mBBack.setText(mResource.getString(CMSAdminResources.GENERAL_BACK));
+ mBBack.addActionListener(this);
+ mBBack.setEnabled(false);
+
+ mBNext_Done = new JButton();
+ mBNext_Done.setText(mNextLabel);
+ mBNext_Done.addActionListener(this);
+
+ mBCancel = new JButton();
+ mBCancel.setText(mResource.getString(CMSAdminResources.GENERAL_CANCEL));
+ mBCancel.addActionListener(this);
+
+ mBHelp = new JButton();
+ mBHelp.setText(mResource.getString(CMSAdminResources.GENERAL_HELP));
+ mBHelp.addActionListener(this);
+
+ //JButton[] buttons = {mBBack, mBNext_Done, mBCancel, mBHelp };
+ JButton[] buttons = {mBBack, mBNext_Done, mBCancel};
+
+ //pass the buttons reference to wizardinfo
+ mInfo.setButtons(mBNext_Done, mBCancel, mBBack);
+
+ return CMSAdminUtil.makeJButtonPanel( buttons, true);
+ }
+
+
+ /**
+ * Returns wizard data container
+ */
+ protected WizardInfo getWizardInfo() {
+ return mInfo;
+ }
+
+ /**
+ * set wizard data container
+ */
+ protected void setWizardInfo(WizardInfo info) {
+ mInfo = info;
+ }
+
+ /**
+ * Initialize currently displayed panel
+ * Implemetation is delegated to initialize() method
+ * of IWizardPanel. It retruns false, if the panel is
+ * to be skipped.
+ */
+ protected boolean initializeWizardPanel() {
+
+ if (mCurrent instanceof IWizardPanel) {
+ boolean status = ((IWizardPanel)mCurrent).initializePanel(mInfo);
+ setTitle( ((IWizardPanel)mCurrent).getTitle() );
+ return status;
+ }
+ return true;
+ }
+
+ /**
+ * Verify if a page is complete. It means all the
+ * require fields are fill out. It delegates implementation
+ * details to validate() method of the IWizardPanel obejct.
+ * If failed, error dialog is displayed but not terminated.
+ */
+ boolean validateWizardPanel() {
+ boolean complete = true;
+
+ if (mCurrent instanceof IWizardPanel) {
+ if (!( (IWizardPanel)mCurrent ).validatePanel()) {
+ String msg = ((IWizardPanel)mCurrent).getErrorMessage();
+ if (msg != null && !msg.equals(""))
+ CMSAdminUtil.showErrorDialog(mParent, mResource, msg,
+ JOptionPane.ERROR_MESSAGE);
+ complete = false;
+ }
+ }
+
+ return complete;
+ }
+
+ /**
+ * Some panel may require post-processing before moving to next stage.
+ * Ususally the last IWizardPanel use this method to perform
+ * save/update operation on the server via cgi/rmi/ldap.
+ * If error occurred, wizard will be terminated.
+ */
+ boolean concludeWizardPanel() {
+ boolean complete = true;
+ if(mCurrent instanceof IWizardPanel) {
+ if (!((IWizardPanel)mCurrent).concludePanel(mInfo)) {
+ CMSAdminUtil.showErrorDialog(mParent, mResource,
+ ((IWizardPanel)mCurrent).getErrorMessage(),
+ JOptionPane.ERROR_MESSAGE);
+ complete = false;
+ }
+ }
+ return complete;
+ }
+
+ /**
+ * Retrieve the update information from the
+ * IWizardPanel into WizardInfo.
+ */
+ void updateWizardInfo() {
+ if(mCurrent instanceof IWizardPanel) {
+ ((IWizardPanel)mCurrent).getUpdateInfo(mInfo);
+ }
+ }
+
+ protected void callHelp() {
+ Debug.println("Overwrite this method");
+ }
+
+ protected void back_cb(WizardInfo info) {
+ Debug.println("Overwrite this method");
+ }
+
+ /*==========================================================
+ * private methods
+ *==========================================================*/
+
+ /**
+ * Button enable/disable and label changes
+ */
+ private void changeButton() {
+
+ if (mPrevScreen.size()==0) {
+ mBBack.setEnabled(false);
+ mBBack.repaint();
+ } else {
+ mBBack.setEnabled(true);
+ mBBack.repaint();
+ }
+
+ boolean lastPage = ((IWizardPanel)mCurrent).isLastPage();
+ if ((mNextScreen.size()==0) || (lastPage)) {
+ mBNext_Done.setText(mDoneLabel);
+ mBCancel.setEnabled(false);
+ mBBack.setEnabled(false);
+ } else {
+ mBNext_Done.setText(mNextLabel);
+ mBCancel.setEnabled(true);
+ }
+ mBNext_Done.repaint();
+ mBCancel.repaint();
+ mBBack.repaint();
+ }
+}
+
+
diff --git a/base/console/src/com/netscape/certsrv/common/ConfigConstants.java b/base/console/src/com/netscape/certsrv/common/ConfigConstants.java
new file mode 100644
index 000000000..437974f13
--- /dev/null
+++ b/base/console/src/com/netscape/certsrv/common/ConfigConstants.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) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.certsrv.common;
+
+
+/**
+ * Constants that are used by daemon and UI configuration.
+ *
+ * @author Christine Ho
+ * @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_CONNECT_DB = "stageConnectDB";
+ public static final String STAGE_INTERNAL_DB = "stageInternalDB";
+ 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_SSLCLONING = "stageSSLCloning";
+ public static final String STAGE_OCSPCLONING = "stageOCSPCloning";
+ public static final String STAGE_TKSCLONING = "stageTKSCloning";
+ 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_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_KEY_CURVENAME = "keyCurveName";
+ 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_SIGNEDBY_TYPE = "signedBy";
+ 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 serial 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/base/console/src/com/netscape/certsrv/common/Constants.java b/base/console/src/com/netscape/certsrv/common/Constants.java
new file mode 100644
index 000000000..6f3e3acdf
--- /dev/null
+++ b/base/console/src/com/netscape/certsrv/common/Constants.java
@@ -0,0 +1,749 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 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;
+
+
+/**
+ * Constants that are shared by certificate server
+ * and its client SDK.
+ *
+ * @author Jack Pan-Chen
+ * @author Christine Ho
+ * @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";
+
+ /* 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/base/console/src/com/netscape/certsrv/common/DestDef.java b/base/console/src/com/netscape/certsrv/common/DestDef.java
new file mode 100644
index 000000000..313ed9d22
--- /dev/null
+++ b/base/console/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
+ * currently in use.
+ *
+ * @author Jack Pan-Chen
+ * @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/base/console/src/com/netscape/certsrv/common/NameValuePairs.java b/base/console/src/com/netscape/certsrv/common/NameValuePairs.java
new file mode 100644
index 000000000..5e7d79cde
--- /dev/null
+++ b/base/console/src/com/netscape/certsrv/common/NameValuePairs.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.common;
+
+import java.util.LinkedHashMap;
+import java.util.StringTokenizer;
+
+/**
+ * A class represents an ordered list of name
+ * value pairs.
+ *
+ * @version $Revision$, $Date$
+ */
+public class NameValuePairs extends LinkedHashMap<String, String> {
+
+ /**
+ * Constructs name value pairs.
+ */
+ public NameValuePairs() {
+ }
+
+ /**
+ * Show the content of this name value container as
+ * string representation.
+ *
+ * @return string representation
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+
+ for (String name : keySet()) {
+ String value = get(name);
+
+ buf.append(name + "=" + value);
+ 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.put(n, v);
+ }
+ return true;
+ }
+}
diff --git a/base/console/src/com/netscape/certsrv/common/OpDef.java b/base/console/src/com/netscape/certsrv/common/OpDef.java
new file mode 100644
index 000000000..734cd75d3
--- /dev/null
+++ b/base/console/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
+ * currently in use.
+ *
+ * @author Jack Pan-Chen
+ * @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/base/console/src/com/netscape/certsrv/common/PrefixDef.java b/base/console/src/com/netscape/certsrv/common/PrefixDef.java
new file mode 100644
index 000000000..b4476a9d9
--- /dev/null
+++ b/base/console/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
+ * currently in use.
+ *
+ * @author Jack Pan-Chen
+ * @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/base/console/src/com/netscape/certsrv/common/ScopeDef.java b/base/console/src/com/netscape/certsrv/common/ScopeDef.java
new file mode 100644
index 000000000..b3e4a79a6
--- /dev/null
+++ b/base/console/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
+ * currently in use.
+ *
+ * @author Jack Pan-Chen
+ * @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_IMPORT_CROSS_CERT = "importXCert";
+ public final static String SC_ISSUE_IMPORT_CERT = "issueImportCert";
+ public final static String SC_INSTALL_CERT = "installCert";
+ 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/base/console/src/com/netscape/certsrv/common/TaskId.java b/base/console/src/com/netscape/certsrv/common/TaskId.java
new file mode 100644
index 000000000..6e093d5eb
--- /dev/null
+++ b/base/console/src/com/netscape/certsrv/common/TaskId.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.certsrv.common;
+
+
+/**
+ * This interface defines all the tasks currently in use for the
+ * certificate server configuration.
+ *
+ * @author Christine Ho
+ * @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";
+
+ // 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 KRA request and key starting and ending 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/base/console/templates/CMakeLists.txt b/base/console/templates/CMakeLists.txt
new file mode 100644
index 000000000..7978c7491
--- /dev/null
+++ b/base/console/templates/CMakeLists.txt
@@ -0,0 +1,12 @@
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pki_console_wrapper ${CMAKE_CURRENT_BINARY_DIR}/pkiconsole COPYONLY)
+
+install(
+ FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/pkiconsole
+ DESTINATION
+ ${BIN_INSTALL_DIR}
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
diff --git a/base/console/templates/pki_console_wrapper b/base/console/templates/pki_console_wrapper
new file mode 100755
index 000000000..eec4725b6
--- /dev/null
+++ b/base/console/templates/pki_console_wrapper
@@ -0,0 +1,167 @@
+#!/bin/sh
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+
+# 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 '$0' from non-existent directory!"
+ exit 255
+fi
+
+
+###############################################################################
+## (1) Specify variables used by this script. ##
+###############################################################################
+
+PRODUCT="pki"
+
+
+###############################################################################
+## (2) Check for valid usage of this command wrapper. ##
+###############################################################################
+
+usage() {
+ echo "Usage: $0 <url>"
+ echo
+ echo " where <url> is the url to the administration port of your"
+ echo " Certificate Subsystem. For example:"
+ echo
+ echo " https://<hostname>:9445/ca"
+ echo
+}
+
+if [ $# -ne 1 ] ; then
+ usage
+ exit 255
+fi
+
+
+###############################################################################
+## (3) Define helper functions. ##
+###############################################################################
+
+invalid_operating_system() {
+ echo
+ echo "ERROR: '$0' does not execute on the '$1' operating system!"
+ echo
+}
+
+invalid_architecture() {
+ echo
+ echo "ERROR: '$0' does not execute on the '$1' architecture!"
+ echo
+}
+
+
+###############################################################################
+## (4) Set the LD_LIBRARY_PATH environment variable to determine the ##
+## search order this command wrapper uses to find shared libraries. ##
+###############################################################################
+
+OS=`uname -s`
+ARCHITECTURE=""
+
+if [ "${OS}" = "Linux" ] ; then
+ ARCHITECTURE=`uname -i`
+ JAVA="java"
+ JAVA_OPTIONS=""
+
+ if [ "${ARCHITECTURE}" = "i386" ] ; then
+ LD_LIBRARY_PATH=/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/jss:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ elif [ "${ARCHITECTURE}" = "x86_64" ] ; then
+ LD_LIBRARY_PATH=/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib64:/lib64:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib64/jss:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ else
+ invalid_architecture "${ARCHITECTURE}"
+ exit 255
+ fi
+elif [ "${OS}" = "SunOS" ] ; then
+ ARCHITECTURE=`uname -p`
+ if [ "${ARCHITECTURE}" = "sparc" ] &&
+ [ -d "/usr/lib/sparcv9/" ] ; then
+ ARCHITECTURE="sparcv9"
+ fi
+ if [ "${ARCHITECTURE}" = "sparc" ] ; then
+ JAVA="/usr/jdk/instances/jdk1.5.0/jre/bin/java"
+ JAVA_OPTIONS=""
+
+ LD_LIBRARY_PATH=/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ elif [ "${ARCHITECTURE}" = "sparcv9" ] ; then
+ JAVA="/usr/jdk/instances/jdk1.5.0/jre/bin/java"
+ JAVA_OPTIONS="-d64"
+
+ LD_LIBRARY_PATH=/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9:/lib/sparcv9:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/${PRODUCT}:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ else
+ invalid_architecture "${ARCHITECTURE}"
+ exit 255
+ fi
+else
+ invalid_operating_system "${OS}"
+ exit 255
+fi
+
+
+###############################################################################
+## (5) Set the CP environment variable to determine the search ##
+## order this command wrapper uses to find jar files. ##
+###############################################################################
+
+CP=/usr/lib/java/jss4.jar
+CP=/usr/lib/java/dirsec/jss4.jar:${CP}
+if [ "${OS}" = "Linux" ] &&
+ [ "${ARCHITECTURE}" = "x86_64" ] ; then
+ # Fedora 16+
+ CP=/usr/lib64/java/jss4.jar
+fi
+CP=/usr/share/java/ldapjdk.jar:${CP}
+CP=/usr/share/java/idm-console-nmclf.jar:${CP}
+CP=/usr/share/java/idm-console-nmclf_en.jar:${CP}
+CP=/usr/share/java/idm-console-mcc.jar:${CP}
+CP=/usr/share/java/idm-console-mcc_en.jar:${CP}
+CP=/usr/share/java/idm-console-base.jar:${CP}
+CP=/usr/share/java/389-console_en.jar:${CP}
+CP=/usr/share/java/${PRODUCT}/pki-console-theme.jar:${CP}
+CP=/usr/share/java/${PRODUCT}/pki-console.jar:${CP}
+export CP
+
+
+###############################################################################
+## (6) Execute the java command specified by this java command wrapper ##
+## based upon the preset LD_LIBRARY_PATH and CP environment variables. ##
+###############################################################################
+
+${JAVA} ${JAVA_OPTIONS} -cp ${CP} -Djava.util.prefs.systemRoot=/tmp/.java -Djava.util.prefs.userRoot=/tmp/java com.netscape.admin.certsrv.Console -s instanceID -a $1
+exit $?
+
diff --git a/base/deploy/CMakeLists.txt b/base/deploy/CMakeLists.txt
new file mode 100644
index 000000000..11d70c55d
--- /dev/null
+++ b/base/deploy/CMakeLists.txt
@@ -0,0 +1,137 @@
+project(deploy)
+
+install(
+ FILES
+ src/pkispawn
+ src/pkidestroy
+ DESTINATION
+ ${BIN_INSTALL_DIR}
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+install(
+ FILES
+ config/pkideployment.cfg
+ DESTINATION
+ ${DATA_INSTALL_DIR}/deployment/config
+ PERMISSIONS
+ OWNER_WRITE OWNER_READ
+ GROUP_READ
+ WORLD_READ
+)
+
+find_package(PythonInterp REQUIRED)
+execute_process(
+ COMMAND
+ ${PYTHON_EXECUTABLE} -c
+ "from distutils.sysconfig import get_python_lib; print get_python_lib()"
+ OUTPUT_VARIABLE
+ PYTHON_SITE_PACKAGES
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+install(
+ FILES
+ src/scriptlets/instance.py
+ src/scriptlets/pkiconfig.py
+ src/scriptlets/pkihelper.py
+ src/scriptlets/pkimessages.py
+ src/scriptlets/pkilogging.py
+ src/scriptlets/pkiscriptlet.py
+ src/scriptlets/security_databases.py
+ DESTINATION
+ ${PYTHON_SITE_PACKAGES}/pki/deployment
+ PERMISSIONS
+ OWNER_WRITE OWNER_READ
+ GROUP_READ
+ WORLD_READ
+)
+install(
+ CODE
+ "execute_process(
+ COMMAND
+ ${CMAKE_COMMAND} -E touch
+ \"\$ENV{DESTDIR}${PYTHON_SITE_PACKAGES}/pki/__init__.py\")"
+)
+install(
+ CODE
+ "execute_process(
+ COMMAND
+ ${CMAKE_COMMAND} -E touch
+ \"\$ENV{DESTDIR}${PYTHON_SITE_PACKAGES}/pki/deployment/__init__.py\")"
+)
+
+#install(
+# FILES
+# jars/resteasy-jettison-provider-2.3-RC1.jar
+# DESTINATION
+# ${JAVA_JAR_INSTALL_DIR}
+# PERMISSIONS
+# OWNER_EXECUTE OWNER_WRITE OWNER_READ
+# GROUP_EXECUTE GROUP_READ
+# WORLD_EXECUTE WORLD_READ
+#)
+
+# install empty directories
+#install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${VAR_INSTALL_DIR}/lock/pki)")
+#install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${VAR_INSTALL_DIR}/run/pki)")
+
+# install subsystem directories for pkispawn
+install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/ca)")
+install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/kra)")
+install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/ocsp)")
+install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/ra)")
+install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/tks)")
+install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/tps)")
+
+# install subsystem directories for pkidestroy
+install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/ca)")
+install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/kra)")
+install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/ocsp)")
+install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/ra)")
+install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/tks)")
+install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/tps)")
+
+# generate and install symbolic links for pkispawn CA
+install(
+ CODE
+ "execute_process(
+ COMMAND
+ ${CMAKE_COMMAND} -E create_symlink
+ \"${PYTHON_SITE_PACKAGES}/pki/deployment/instance.py\"
+ \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/ca/0010_instance\")"
+)
+install(
+ CODE
+ "execute_process(
+ COMMAND
+ ${CMAKE_COMMAND} -E create_symlink
+ \"${PYTHON_SITE_PACKAGES}/pki/deployment/security_databases.py\"
+ \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/ca/0020_security_databases\")"
+)
+
+# generate and install symbolic links for pkispawn KRA
+
+# generate and install symbolic links for pkispawn OCSP
+
+# generate and install symbolic links for pkispawn RA
+
+# generate and install symbolic links for pkispawn TKS
+
+# generate and install symbolic links for pkispawn TPS
+
+
+# generate and install symbolic links for pkidestroy CA
+
+# generate and install symbolic links for pkidestroy KRA
+
+# generate and install symbolic links for pkidestroy OCSP
+
+# generate and install symbolic links for pkidestroy RA
+
+# generate and install symbolic links for pkidestroy TKS
+
+# generate and install symbolic links for pkidestroy TPS
+
diff --git a/base/deploy/LICENSE b/base/deploy/LICENSE
new file mode 100644
index 000000000..e281f4362
--- /dev/null
+++ b/base/deploy/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/base/deploy/config/pkideployment.cfg b/base/deploy/config/pkideployment.cfg
new file mode 100644
index 000000000..db9ce54dd
--- /dev/null
+++ b/base/deploy/config/pkideployment.cfg
@@ -0,0 +1,28 @@
+[Common]
+pki_instance_root=/var/lib/pki
+pki_instance_name=instance
+pki_user=pkiuser
+pki_group=pkiuser
+pki_audit_group=pkiaudit
+[Apache]
+pki_web_server=Apache
+pki_http_port=80
+pki_https_port=443
+[Tomcat]
+pki_web_server=Tomcat
+pki_http_port=8080
+pki_https_port=8443
+pki_ajp_port=8009
+pki_security_manager=true
+[CA]
+pki_subsystem=CA
+[KRA]
+pki_subsystem=KRA
+[OCSP]
+pki_subsystem=OCSP
+[RA]
+pki_subsystem=RA
+[TKS]
+pki_subsystem=TKS
+[TPS]
+pki_subsystem=TPS
diff --git a/base/deploy/src/pkidestroy b/base/deploy/src/pkidestroy
new file mode 100755
index 000000000..a762e143a
--- /dev/null
+++ b/base/deploy/src/pkidestroy
@@ -0,0 +1,151 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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) 2011 Red Hat, Inc.
+# All rights reserved.
+#
+
+# System Imports
+import sys
+if not hasattr(sys, "hexversion") or sys.hexversion < 0x020700f0:
+ print "Python version %s.%s.%s is too old." % sys.version_info[:3]
+ print "Please upgrade to at least Python 2.7.0."
+ sys.exit(1)
+try:
+ import argparse
+ import logging
+ import os
+ import pprint
+ from pki.deployment import pkiconfig as config
+ from pki.deployment import pkihelper
+ from pki.deployment import pkilogging
+ from pki.deployment import pkimessages as log
+except ImportError:
+ print >> sys.stderr, """\
+There was a problem importing one of the required Python modules. The
+error was:
+
+ %s
+""" % sys.exc_value
+ sys.exit(1)
+
+
+# PKI Deployment Functions
+def main(argv):
+ "main entry point"
+
+ # Only run this program as "root".
+ if not os.geteuid() == 0:
+ sys.exit("'%s' must be run as root!" % argv[0])
+
+ # Initialize 'pretty print' for objects
+ pp = pprint.PrettyPrinter(indent=4)
+
+ # Read and process command-line arguments.
+ pkihelper.process_command_line_arguments(argv)
+
+ # Enable 'pkidestroy' logging.
+ config.pki_log_dir = config.pki_root_prefix +\
+ config.PKIDESTROY_LOG_PATH
+ config.pki_log_name = config.PKIDESTROY_LOG_PREFIX +\
+ config.pki_subsystem.lower() +\
+ config.PKIDESTROY_LOG_SUFFIX
+ rv = pkilogging.enable_pki_logger(config.pki_log_dir,
+ config.pki_log_name,
+ config.pki_log_level,
+ config.pki_console_log_level,
+ config.PKIDESTROY_LOGGER)
+ if rv != OSError:
+ config.pki_log = rv
+ else:
+ print log.PKI_UNABLE_TO_CREATE_LOG_DIRECTORY_1 % config.pki_log_dir
+ sys.exit(1)
+
+ # Read the specified PKI configuration file.
+ rv = pkihelper.read_pki_configuration_file()
+ if rv != 0:
+ config.pki_log.error(PKI_UNABLE_TO_PARSE_1, rv)
+ sys.exit(1)
+ else:
+ config.pki_log.debug(log.PKI_DICTIONARY_COMMON)
+ config.pki_log.debug(pp.pformat(config.pki_common_dict))
+ config.pki_log.debug(log.PKI_DICTIONARY_WEB_SERVER)
+ config.pki_log.debug(pp.pformat(config.pki_web_server_dict))
+ config.pki_log.debug(log.PKI_DICTIONARY_SUBSYSTEM)
+ config.pki_log.debug(pp.pformat(config.pki_subsystem_dict))
+
+ # Override PKI configuration file values with 'custom' command-line values.
+ if not config.pki_instance_name is None:
+ config.pki_common_dict['pki_instance_name'] =\
+ config.pki_instance_name
+ if not config.pki_http_port is None:
+ config.pki_web_server_dict['pki_http_port'] =\
+ config.pki_http_port
+ if not config.pki_https_port is None:
+ config.pki_web_server_dict['pki_https_port'] =\
+ config.pki_https_port
+ if not config.pki_ajp_port is None:
+ config.pki_web_server_dict['pki_ajp_port'] =\
+ config.pki_ajp_port
+ config.pki_log.debug(log.PKI_DICTIONARY_COMMON)
+ config.pki_log.debug(pp.pformat(config.pki_common_dict))
+ config.pki_log.debug(log.PKI_DICTIONARY_WEB_SERVER)
+ config.pki_log.debug(pp.pformat(config.pki_web_server_dict))
+ config.pki_log.debug(log.PKI_DICTIONARY_SUBSYSTEM)
+ config.pki_log.debug(pp.pformat(config.pki_subsystem_dict))
+
+ # Combine the various sectional dictionaries into a PKI master dictionary
+ pkihelper.create_pki_master_dictionary()
+ config.pki_log.debug(log.PKI_DICTIONARY_MASTER)
+ config.pki_log.debug(pp.pformat(config.pki_master_dict))
+
+ # Remove the specified PKI subsystem.
+ pki_scriptlets_path = config.pki_root_prefix +\
+ config.PKIDESTROY_PATH +\
+ "/" + config.pki_subsystem.lower()
+ if not os.path.exists(pki_scriptlets_path) or\
+ not os.path.isdir(pki_scriptlets_path):
+ config.pki_log.error(log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1,
+ pki_scriptlets_path)
+ sys.exit(1)
+ pki_subsystem_scriptlets = os.listdir(pki_scriptlets_path)
+ pki_subsystem_scriptlets.sort()
+
+ # Process the various "scriptlets" for the specified PKI subsystem.
+ rv = 0
+ config.pki_log.info(log.PKIDESTROY_BEGIN_MESSAGE_2,
+ config.pki_subsystem,
+ config.pki_master_dict['pki_instance_name'])
+ for pki_scriptlet in pki_subsystem_scriptlets:
+ scriptlet = __import__(config.PKI_DEPLOYMENT_SCRIPTLETS_MODULE +\
+ '.' + pki_scriptlet[5:],
+ fromlist = [pki_scriptlet[5:]])
+ instance = scriptlet.PkiScriptlet()
+ rv = instance.destroy()
+ if rv != 0:
+ sys.exit(1)
+ config.pki_log.info(log.PKIDESTROY_END_MESSAGE_2,
+ config.pki_subsystem,
+ config.pki_master_dict['pki_instance_name'])
+ config.pki_log.debug(log.PKI_DICTIONARY_MASTER)
+ config.pki_log.debug(pp.pformat(config.pki_master_dict))
+
+
+# PKI Deployment Entry Point
+if __name__ == "__main__":
+ main(sys.argv)
+
diff --git a/base/deploy/src/pkispawn b/base/deploy/src/pkispawn
new file mode 100755
index 000000000..a48a4753c
--- /dev/null
+++ b/base/deploy/src/pkispawn
@@ -0,0 +1,174 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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) 2011 Red Hat, Inc.
+# All rights reserved.
+#
+
+# System Imports
+import sys
+if not hasattr(sys, "hexversion") or sys.hexversion < 0x020700f0:
+ print "Python version %s.%s.%s is too old." % sys.version_info[:3]
+ print "Please upgrade to at least Python 2.7.0."
+ sys.exit(1)
+try:
+ import argparse
+ import logging
+ import os
+ import pprint
+ from pki.deployment import pkiconfig as config
+ from pki.deployment import pkihelper
+ from pki.deployment import pkilogging
+ from pki.deployment import pkimessages as log
+except ImportError:
+ print >> sys.stderr, """\
+There was a problem importing one of the required Python modules. The
+error was:
+
+ %s
+""" % sys.exc_value
+ sys.exit(1)
+
+
+# PKI Deployment Functions
+def main(argv):
+ "main entry point"
+
+ # Only run this program as "root".
+ if not os.geteuid() == 0:
+ sys.exit("'%s' must be run as root!" % argv[0])
+
+ # Set the umask
+ os.umask(config.PKI_DEPLOYMENT_DEFAULT_UMASK)
+
+ # Initialize 'pretty print' for objects
+ pp = pprint.PrettyPrinter(indent=4)
+
+ # Read and process command-line arguments.
+ pkihelper.process_command_line_arguments(argv)
+
+ # Enable 'pkispawn' logging.
+ rv = 0
+ if not config.pki_update_flag:
+ pki_deployment_begin = log.PKISPAWN_BEGIN_MESSAGE_2
+ pki_deployment_end = log.PKISPAWN_END_MESSAGE_2
+ config.pki_log_dir = config.pki_root_prefix +\
+ config.PKISPAWN_LOG_PATH
+ config.pki_log_name = config.PKISPAWN_LOG_PREFIX +\
+ config.pki_subsystem.lower() +\
+ config.PKISPAWN_LOG_SUFFIX
+ rv = pkilogging.enable_pki_logger(config.pki_log_dir,
+ config.pki_log_name,
+ config.pki_log_level,
+ config.pki_console_log_level,
+ config.PKISPAWN_LOGGER)
+ else:
+ pki_deployment_begin = log.PKIRESPAWN_BEGIN_MESSAGE_2
+ pki_deployment_end = log.PKIRESPAWN_END_MESSAGE_2
+ config.pki_log_dir = config.pki_root_prefix +\
+ config.PKIRESPAWN_LOG_PATH
+ config.pki_log_name = config.PKIRESPAWN_LOG_PREFIX +\
+ config.pki_subsystem.lower() +\
+ config.PKIRESPAWN_LOG_SUFFIX
+ rv = pkilogging.enable_pki_logger(config.pki_log_dir,
+ config.pki_log_name,
+ config.pki_log_level,
+ config.pki_console_log_level,
+ config.PKIRESPAWN_LOGGER)
+ if rv != OSError:
+ config.pki_log = rv
+ else:
+ print log.PKI_UNABLE_TO_CREATE_LOG_DIRECTORY_1 % config.pki_log_dir
+ sys.exit(1)
+
+ # Read the specified PKI configuration file.
+ rv = pkihelper.read_pki_configuration_file()
+ if rv != 0:
+ config.pki_log.error(PKI_UNABLE_TO_PARSE_1, rv)
+ sys.exit(1)
+ else:
+ config.pki_log.debug(log.PKI_DICTIONARY_COMMON)
+ config.pki_log.debug(pp.pformat(config.pki_common_dict))
+ config.pki_log.debug(log.PKI_DICTIONARY_WEB_SERVER)
+ config.pki_log.debug(pp.pformat(config.pki_web_server_dict))
+ config.pki_log.debug(log.PKI_DICTIONARY_SUBSYSTEM)
+ config.pki_log.debug(pp.pformat(config.pki_subsystem_dict))
+
+ # Override PKI configuration file values with 'custom' command-line values.
+ if not config.pki_instance_name is None:
+ config.pki_common_dict['pki_instance_name'] =\
+ config.pki_instance_name
+ if not config.pki_http_port is None:
+ config.pki_web_server_dict['pki_http_port'] =\
+ config.pki_http_port
+ if not config.pki_https_port is None:
+ config.pki_web_server_dict['pki_https_port'] =\
+ config.pki_https_port
+ if not config.pki_ajp_port is None:
+ config.pki_web_server_dict['pki_ajp_port'] =\
+ config.pki_ajp_port
+ config.pki_log.debug(log.PKI_DICTIONARY_COMMON)
+ config.pki_log.debug(pp.pformat(config.pki_common_dict))
+ config.pki_log.debug(log.PKI_DICTIONARY_WEB_SERVER)
+ config.pki_log.debug(pp.pformat(config.pki_web_server_dict))
+ config.pki_log.debug(log.PKI_DICTIONARY_SUBSYSTEM)
+ config.pki_log.debug(pp.pformat(config.pki_subsystem_dict))
+
+ # Combine the various sectional dictionaries into a PKI master dictionary
+ pkihelper.create_pki_master_dictionary()
+ config.pki_log.debug(log.PKI_DICTIONARY_MASTER)
+ config.pki_log.debug(pp.pformat(config.pki_master_dict))
+
+ # Install and configure the specified PKI subsystem.
+ pki_scriptlets_path = config.pki_root_prefix +\
+ config.PKISPAWN_PATH +\
+ "/" + config.pki_subsystem.lower()
+ if not os.path.exists(pki_scriptlets_path) or\
+ not os.path.isdir(pki_scriptlets_path):
+ config.pki_log.error(log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1,
+ pki_scriptlets_path)
+ sys.exit(1)
+ pki_subsystem_scriptlets = os.listdir(pki_scriptlets_path)
+ pki_subsystem_scriptlets.sort()
+
+ # Process the various "scriptlets" for the specified PKI subsystem.
+ rv = 0
+ config.pki_log.info(pki_deployment_begin,
+ config.pki_subsystem,
+ config.pki_master_dict['pki_instance_name'])
+ for pki_scriptlet in pki_subsystem_scriptlets:
+ scriptlet = __import__(config.PKI_DEPLOYMENT_SCRIPTLETS_MODULE +\
+ '.' + pki_scriptlet[5:],
+ fromlist = [pki_scriptlet[5:]])
+ instance = scriptlet.PkiScriptlet()
+ if not config.pki_update_flag:
+ rv = instance.spawn()
+ else:
+ rv = instance.respawn()
+ if rv != 0:
+ sys.exit(1)
+ config.pki_log.info(pki_deployment_end,
+ config.pki_subsystem,
+ config.pki_master_dict['pki_instance_name'])
+ config.pki_log.debug(log.PKI_DICTIONARY_MASTER)
+ config.pki_log.debug(pp.pformat(config.pki_master_dict))
+
+
+# PKI Deployment Entry Point
+if __name__ == "__main__":
+ main(sys.argv)
+
diff --git a/base/deploy/src/scriptlets/instance.py b/base/deploy/src/scriptlets/instance.py
new file mode 100644
index 000000000..a7ca35c69
--- /dev/null
+++ b/base/deploy/src/scriptlets/instance.py
@@ -0,0 +1,105 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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) 2011 Red Hat, Inc.
+# All rights reserved.
+#
+
+# System Imports
+import os
+import grp
+import pwd
+
+# PKI Deployment Imports
+import pkiconfig as config
+import pkimessages as log
+import pkiscriptlet
+
+
+# PKI Deployment Instance Population Classes
+class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
+ rv = 0
+ pki_path = config.pki_root_prefix +\
+ config.pki_master_dict['pki_instance_root']
+ pki_instance_path = pki_path + "/" +\
+ config.pki_master_dict['pki_instance_name']
+ pki_subsystem_path = pki_instance_path + "/" +\
+ config.pki_master_dict['pki_subsystem'].lower()
+
+ def spawn(self):
+ if not os.path.exists(self.pki_subsystem_path):
+ config.pki_log.info(log.INSTANCE_SPAWN_1, __name__)
+ config.pki_log.info(log.INSTANCE_SPAWN_MKDIR_1,
+ self.pki_subsystem_path)
+ if not config.pki_dry_run_flag:
+ try:
+ pki_gid = grp.getgrnam(
+ config.pki_master_dict['pki_group'])[2]
+ pki_uid = pwd.getpwnam(
+ config.pki_master_dict['pki_user'])[2]
+ os.mkdir(self.pki_path,
+ config.PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS)
+ os.chown(self.pki_path,
+ pki_uid,
+ pki_gid)
+ os.mkdir(self.pki_instance_path,
+ config.PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS)
+ os.chown(self.pki_instance_path,
+ pki_uid,
+ pki_gid)
+ os.mkdir(self.pki_subsystem_path,
+ config.PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS)
+ os.chown(self.pki_subsystem_path,
+ pki_uid,
+ pki_gid)
+ except KeyError:
+ self.rv = KeyError
+ except OSError:
+ self.rv = OSError
+ elif not os.path.isdir(self.pki_subsystem_path):
+ config.pki_log.error(
+ log.PKI_DIRECTORY_ALREADY_EXISTS_NOT_A_DIRECTORY_1,
+ self.pki_subsystem_path)
+ self.rv = -1
+ else:
+ config.pki_log.error(log.PKI_DIRECTORY_ALREADY_EXISTS_1,
+ self.pki_subsystem_path)
+ self.rv = -1
+ return self.rv
+
+ def respawn(self):
+ if not os.path.exists(self.pki_subsystem_path) or\
+ not os.path.isdir(self.pki_subsystem_path):
+ config.pki_log.error(
+ log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1,
+ self.pki_subsystem_path)
+ self.rv = -1
+ else:
+ config.pki_log.info(log.INSTANCE_RESPAWN_1, __name__)
+ return self.rv
+
+ def destroy(self):
+ if not os.path.exists(self.pki_subsystem_path) or\
+ not os.path.isdir(self.pki_subsystem_path):
+ config.pki_log.error(
+ log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1,
+ self.pki_subsystem_path)
+ self.rv = -1
+ else:
+ config.pki_log.info(log.INSTANCE_DESTROY_1, __name__)
+ return self.rv
+
diff --git a/base/deploy/src/scriptlets/pkiconfig.py b/base/deploy/src/scriptlets/pkiconfig.py
new file mode 100644
index 000000000..7d676c00d
--- /dev/null
+++ b/base/deploy/src/scriptlets/pkiconfig.py
@@ -0,0 +1,96 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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) 2011 Red Hat, Inc.
+# All rights reserved.
+#
+
+# System Imports
+import logging
+
+
+# PKI Deployment Constants
+PKI_DEPLOYMENT_PATH = "/usr/share/pki/deployment"
+PKI_DEPLOYMENT_CONFIG_PATH = PKI_DEPLOYMENT_PATH + "/" + "config"
+PKI_DEPLOYMENT_SCRIPTLETS_MODULE = "pki.deployment"
+PKI_DEPLOYMENT_VERBOSITY=\
+"VERBOSITY FLAGS CONSOLE MESSAGE LEVEL LOG MESSAGE LEVEL\n"\
+"=======================================================================\n"\
+" NONE error|warning error|warning|info\n"\
+" -v error|warning|info error|warning|info\n"\
+" -vv error|warning|info error|warning|info|debug\n"\
+" -vvv error|warning|info|debug error|warning|info|debug\n"\
+" "
+PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS = 00770
+PKI_DEPLOYMENT_DEFAULT_EXE_PERMISSIONS = 00770
+PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS = 00660
+PKI_DEPLOYMENT_DEFAULT_UMASK = 00002
+
+PKIDESTROY_PATH = PKI_DEPLOYMENT_PATH + "/" + "destroy"
+PKIDESTROY_LOG_PATH = "/var/log"
+PKIDESTROY_LOG_PREFIX = "pki-"
+PKIDESTROY_LOG_SUFFIX = "-destroy.log"
+PKIDESTROY_LOGGER = "pkidestroy"
+
+PKIRESPAWN_PATH = PKI_DEPLOYMENT_PATH + "/" + "spawn"
+PKIRESPAWN_LOG_PATH = "/var/log"
+PKIRESPAWN_LOG_PREFIX = "pki-"
+PKIRESPAWN_LOG_SUFFIX = "-respawn.log"
+PKIRESPAWN_LOGGER = "pkirespawn"
+
+PKISPAWN_PATH = PKI_DEPLOYMENT_PATH + "/" + "spawn"
+PKISPAWN_LOG_PATH = "/var/log"
+PKISPAWN_LOG_PREFIX = "pki-"
+PKISPAWN_LOG_SUFFIX = "-spawn.log"
+PKISPAWN_LOGGER = "pkispawn"
+
+PKI_SECURITY_DATABASE_DIR = "alias"
+PKI_SUBSYSTEMS = ["CA","KRA","OCSP","RA","TKS","TPS"]
+PKI_APACHE_SUBSYSTEMS = ["RA","TPS"]
+PKI_TOMCAT_SUBSYSTEMS = ["CA","KRA","OCSP","TKS"]
+
+
+# PKI Deployment "Mandatory" Command-Line Variables
+pki_subsystem = None
+
+# PKI Deployment "Optional" Command-Line Variables
+pkideployment_cfg = PKI_DEPLOYMENT_CONFIG_PATH + "/" + "pkideployment.cfg"
+pki_dry_run_flag = False
+pki_root_prefix = None
+pki_update_flag = False
+
+# PKI Deployment "Custom" Command-Line Variables
+pki_instance_name = None
+pki_http_port = None
+pki_https_port = None
+pki_ajp_port = None
+
+
+# PKI Deployment Logger Variables
+pki_log = None
+pki_log_dir = None
+pki_log_name = None
+pki_log_level = logging.INFO
+pki_console_log_level = logging.WARNING
+
+
+# PKI Deployment Global Dictionaries
+pki_common_dict = None
+pki_web_server_dict = None
+pki_subsystem_dict = None
+pki_master_dict = None
+
diff --git a/base/deploy/src/scriptlets/pkihelper.py b/base/deploy/src/scriptlets/pkihelper.py
new file mode 100644
index 000000000..ee2bdd249
--- /dev/null
+++ b/base/deploy/src/scriptlets/pkihelper.py
@@ -0,0 +1,222 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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) 2011 Red Hat, Inc.
+# All rights reserved.
+#
+
+# System Imports
+import ConfigParser
+import argparse
+import logging
+import os
+
+
+# PKI Deployment Imports
+import pkiconfig as config
+import pkimessages as log
+
+
+# PKI Deployment Helper Functions
+def process_command_line_arguments(argv):
+ "Read and process command-line options"
+ description = None
+ if os.path.basename(argv[0]) == 'pkispawn':
+ description = 'PKI Instance Installation and Configuration'
+ elif os.path.basename(argv[0]) == 'pkidestroy':
+ description = 'PKI Instance Removal'
+ parser = argparse.ArgumentParser(
+ description=description,
+ add_help=False,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ epilog=config.PKI_DEPLOYMENT_VERBOSITY)
+ mandatory = parser.add_argument_group('mandatory arguments')
+ mandatory.add_argument('-s',
+ dest='pki_subsystem', action='store',
+ nargs=1, choices=config.PKI_SUBSYSTEMS,
+ required=True, metavar='<subsystem>',
+ help='where <subsystem> is '
+ 'CA, KRA, OCSP, RA, TKS, or TPS')
+ optional = parser.add_argument_group('optional arguments')
+ optional.add_argument('--dry_run',
+ dest='pki_dry_run_flag', action='store_true',
+ help='do not actually perform any actions')
+ optional.add_argument('-f',
+ dest='pkideployment_cfg', action='store',
+ nargs=1, metavar='<file>',
+ help='overrides default configuration filename')
+ optional.add_argument('-h', '--help',
+ dest='help', action='help',
+ help='show this help message and exit')
+ optional.add_argument('-p',
+ dest='pki_root_prefix', action='store',
+ nargs=1, metavar='<prefix>',
+ help='directory prefix to specify local directory')
+ if os.path.basename(argv[0]) == 'pkispawn':
+ optional.add_argument('-u',
+ dest='pki_update_flag', action='store_true',
+ help='update instance of specified subsystem')
+ optional.add_argument('-v',
+ dest='pki_verbosity', action='count',
+ help='display verbose information (details below)')
+ custom = parser.add_argument_group('custom arguments '
+ '(OVERRIDES configuration file values)')
+ custom.add_argument('-i',
+ dest='pki_instance_name', action='store',
+ nargs=1, metavar='<instance>',
+ help='PKI instance name (MUST specify REQUIRED ports)')
+ custom.add_argument('--http_port',
+ dest='pki_http_port', action='store',
+ nargs=1, metavar='<port>',
+ help='HTTP port (CA, KRA, OCSP, RA, TKS, TPS)')
+ custom.add_argument('--https_port',
+ dest='pki_https_port', action='store',
+ nargs=1, metavar='<port>',
+ help='HTTPS port (CA, KRA, OCSP, RA, TKS, TPS)')
+ custom.add_argument('--ajp_port',
+ dest='pki_ajp_port', action='store',
+ nargs=1, metavar='<port>',
+ help='AJP port (CA, KRA, OCSP, TKS)')
+ args = parser.parse_args()
+
+ config.pki_subsystem = str(args.pki_subsystem).strip('[\']')
+ if args.pki_dry_run_flag:
+ config.pki_dry_run_flag = args.pki_dry_run_flag
+ if not args.pkideployment_cfg is None:
+ config.pkideployment_cfg = str(args.pkideployment_cfg).strip('[\']')
+ if not os.path.exists(config.pkideployment_cfg) or\
+ not os.path.isfile(config.pkideployment_cfg):
+ print "ERROR: " +\
+ log.PKI_FILE_MISSING_OR_NOT_A_FILE_1 %\
+ config.pkideployment_cfg
+ print
+ parser.print_help()
+ parser.exit(-1);
+ if not args.pki_root_prefix is None:
+ config.pki_root_prefix = str(args.pki_root_prefix).strip('[\']')
+ if config.pki_root_prefix is None or\
+ len(config.pki_root_prefix) == 0:
+ config.pki_root_prefix = ""
+ elif not os.path.exists(config.pki_root_prefix) or\
+ not os.path.isdir(config.pki_root_prefix):
+ print "ERROR: " +\
+ log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1 %\
+ config.pki_root_prefix
+ print
+ parser.print_help()
+ parser.exit(-1);
+ if os.path.basename(argv[0]) == 'pkispawn':
+ if args.pki_update_flag:
+ config.pki_update_flag = args.pki_update_flag
+ if args.pki_verbosity == 1:
+ config.pki_console_log_level = logging.INFO
+ config.pki_log_level = logging.INFO
+ elif args.pki_verbosity == 2:
+ config.pki_console_log_level = logging.INFO
+ config.pki_log_level = logging.DEBUG
+ elif args.pki_verbosity == 3:
+ config.pki_console_log_level = logging.DEBUG
+ config.pki_log_level = logging.DEBUG
+ elif args.pki_verbosity > 3:
+ print "ERROR: " + log.PKI_VERBOSITY_LEVELS_MESSAGE
+ print
+ parser.print_help()
+ parser.exit(-1);
+ if not args.pki_instance_name is None:
+ config.pki_instance_name = str(args.pki_instance_name).strip('[\']')
+ if not args.pki_http_port is None:
+ config.pki_http_port = str(args.pki_http_port).strip('[\']')
+ if not args.pki_https_port is None:
+ config.pki_https_port = str(args.pki_https_port).strip('[\']')
+ if not args.pki_ajp_port is None:
+ if config.pki_subsystem in config.PKI_TOMCAT_SUBSYSTEMS:
+ config.pki_ajp_port = str(args.pki_ajp_port).strip('[\']')
+ else:
+ print "ERROR: " +\
+ log.PKI_CUSTOM_TOMCAT_AJP_PORT_1 %\
+ config.pki_subsystem
+ print
+ parser.print_help()
+ parser.exit(-1);
+ if not args.pki_instance_name is None or\
+ not args.pki_http_port is None or\
+ not args.pki_https_port is None or\
+ not args.pki_ajp_port is None:
+ if config.pki_subsystem in config.PKI_APACHE_SUBSYSTEMS:
+ if args.pki_instance_name is None or\
+ args.pki_http_port is None or\
+ args.pki_https_port is None:
+ print "ERROR: " + log.PKI_CUSTOM_APACHE_INSTANCE_1 %\
+ config.pki_subsystem
+ print
+ parser.print_help()
+ parser.exit(-1);
+ elif config.pki_subsystem in config.PKI_TOMCAT_SUBSYSTEMS:
+ if args.pki_instance_name is None or\
+ args.pki_http_port is None or\
+ args.pki_https_port is None or\
+ args.pki_ajp_port is None:
+ print "ERROR: " + log.PKI_CUSTOM_TOMCAT_INSTANCE_1 %\
+ config.pki_subsystem
+ print
+ parser.print_help()
+ parser.exit(-1);
+
+
+def read_pki_configuration_file():
+ "Read configuration file sections into dictionaries"
+ rv = 0
+ try:
+ parser = ConfigParser.ConfigParser()
+ parser.read(config.pkideployment_cfg)
+ config.pki_common_dict = dict(parser._sections['Common'])
+ if config.pki_subsystem == "CA":
+ config.pki_web_server_dict = dict(parser._sections['Tomcat'])
+ config.pki_subsystem_dict = dict(parser._sections['CA'])
+ elif config.pki_subsystem == "KRA":
+ config.pki_web_server_dict = dict(parser._sections['Tomcat'])
+ config.pki_subsystem_dict = dict(parser._sections['KRA'])
+ elif config.pki_subsystem == "OCSP":
+ config.pki_web_server_dict = dict(parser._sections['Tomcat'])
+ config.pki_subsystem_dict = dict(parser._sections['OCSP'])
+ elif config.pki_subsystem == "RA":
+ config.pki_web_server_dict = dict(parser._sections['Apache'])
+ config.pki_subsystem_dict = dict(parser._sections['RA'])
+ elif config.pki_subsystem == "TKS":
+ config.pki_web_server_dict = dict(parser._sections['Tomcat'])
+ config.pki_subsystem_dict = dict(parser._sections['TKS'])
+ elif config.pki_subsystem == "TPS":
+ config.pki_web_server_dict = dict(parser._sections['Apache'])
+ config.pki_subsystem_dict = dict(parser._sections['TPS'])
+ # Insert empty record into dictionaries for "pretty print" statements
+ config.pki_common_dict[0] = None
+ config.pki_web_server_dict[0] = None
+ config.pki_subsystem_dict[0] = None
+ except ConfigParser.ParsingError, err:
+ rv = err
+ return rv
+
+
+def create_pki_master_dictionary():
+ "Create a single master PKI dictionary from the sectional dictionaries"
+ config.pki_master_dict = dict()
+ config.pki_master_dict.update(config.pki_common_dict)
+ config.pki_master_dict.update(config.pki_web_server_dict)
+ config.pki_master_dict.update(config.pki_subsystem_dict)
+ config.pki_master_dict.update(__name__="PKI Master Dictionary")
+ return
+
diff --git a/base/deploy/src/scriptlets/pkilogging.py b/base/deploy/src/scriptlets/pkilogging.py
new file mode 100644
index 000000000..776677cfd
--- /dev/null
+++ b/base/deploy/src/scriptlets/pkilogging.py
@@ -0,0 +1,46 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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) 2011 Red Hat, Inc.
+# All rights reserved.
+#
+
+# System Imports
+import logging
+import os
+
+
+# PKI Deployment Logging Functions
+def enable_pki_logger(log_dir, log_name, log_level, console_log_level, logger):
+ if not os.path.isdir(log_dir):
+ try:
+ os.makedirs(log_dir)
+ except OSError:
+ return OSError
+ logging.basicConfig(level=log_level,
+ format='%(asctime)s %(name)-12s ' +\
+ '%(levelname)-8s %(message)s',
+ datefmt='%Y-%m-%d %H:%M:%S',
+ filename=log_dir + "/" + log_name,
+ filemode='w')
+ console = logging.StreamHandler()
+ console.setLevel(console_log_level)
+ formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
+ console.setFormatter(formatter)
+ logging.getLogger('').addHandler(console)
+ return logging.getLogger(logger)
+
diff --git a/base/deploy/src/scriptlets/pkimessages.py b/base/deploy/src/scriptlets/pkimessages.py
new file mode 100644
index 000000000..e6a9f95aa
--- /dev/null
+++ b/base/deploy/src/scriptlets/pkimessages.py
@@ -0,0 +1,86 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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) 2011 Red Hat, Inc.
+# All rights reserved.
+#
+
+# PKI Deployment Engine Messages
+PKI_CUSTOM_APACHE_INSTANCE_1 = "When a custom '%s' subsystem is being "\
+ "deployed, the 'instance', 'http_port', and "\
+ "'https_port' must ALL be specified!"
+PKI_CUSTOM_TOMCAT_INSTANCE_1 = "When a custom '%s' subsystem is being "\
+ "deployed, the 'instance', 'http_port', "\
+ "'https_port', and 'ajp_port' must ALL be "\
+ "specified!"
+PKI_CUSTOM_TOMCAT_AJP_PORT_1 = "When a custom '%s' subsystem is being "\
+ "deployed, ONLY the 'instance', "\
+ "'http_port', and 'https_port' MUST be "\
+ "specified; NO 'ajp_port' should be requested!"
+PKI_DICTIONARY_COMMON ="\n"\
+"=====================================================\n"\
+" DISPLAY CONTENTS OF PKI COMMON DICTIONARY\n"\
+"====================================================="
+PKI_DICTIONARY_MASTER="\n"\
+"=====================================================\n"\
+" DISPLAY CONTENTS OF PKI MASTER DICTIONARY\n"\
+"====================================================="
+PKI_DICTIONARY_SUBSYSTEM="\n"\
+"=====================================================\n"\
+" DISPLAY CONTENTS OF PKI SUBSYSTEM DICTIONARY\n"\
+"====================================================="
+PKI_DICTIONARY_WEB_SERVER="\n"\
+"=====================================================\n"\
+" DISPLAY CONTENTS OF PKI WEB SERVER DICTIONARY\n"\
+"====================================================="
+PKI_DIRECTORY_ALREADY_EXISTS_1 = "Directory '%s' already exists!"
+PKI_DIRECTORY_ALREADY_EXISTS_NOT_A_DIRECTORY_1 = "Directory '%s' already "\
+ "exists BUT it is NOT a "\
+ "directory!"
+PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1 = "Directory '%s' is either "\
+ "missing or is NOT a directory!"
+PKI_FILE_MISSING_OR_NOT_A_FILE_1 = "File '%s' is either missing "\
+ "or is NOT a regular file!"
+PKI_UNABLE_TO_PARSE_1 = "'Could not parse: '%s'"
+PKI_UNABLE_TO_CREATE_LOG_DIRECTORY_1 = "Could not create log directory '%s'!"
+PKI_VERBOSITY_LEVELS_MESSAGE = "Only up to 3 levels of verbosity are supported!"
+
+
+# PKI Deployment 'pkispawn' and 'pkidestroy' Messages
+PKIDESTROY_BEGIN_MESSAGE_2 = "BEGIN destroying subsystem '%s' of "\
+ "instance '%s' . . ."
+PKIDESTROY_END_MESSAGE_2 = "END destroying subsystem '%s' of "\
+ "instance '%s'."
+PKIRESPAWN_BEGIN_MESSAGE_2 = "BEGIN respawning subsystem '%s' of "\
+ "instance '%s' . . ."
+PKIRESPAWN_END_MESSAGE_2 = "END respawning subsystem '%s' of "\
+ "instance '%s'."
+PKISPAWN_BEGIN_MESSAGE_2 = "BEGIN spawning subsystem '%s' of "\
+ "instance '%s' . . ."
+PKISPAWN_END_MESSAGE_2 = "END spawning subsystem '%s' of "\
+ "instance '%s'."
+
+
+# PKI Deployment "Scriptlet" Messages
+INSTANCE_DESTROY_1 = " depopulating '%s'"
+INSTANCE_RESPAWN_1 = " repopulating '%s'"
+INSTANCE_SPAWN_1 = " populating '%s'"
+INSTANCE_SPAWN_MKDIR_1 = " mkdir '%s'"
+SECURITY_DATABASES_DESTROY_1 = " removing '%s'"
+SECURITY_DATABASES_RESPAWN_1 = " regenerating '%s'"
+SECURITY_DATABASES_SPAWN_1 = " generating '%s'"
+
diff --git a/base/deploy/src/scriptlets/pkiscriptlet.py b/base/deploy/src/scriptlets/pkiscriptlet.py
new file mode 100644
index 000000000..5befd993a
--- /dev/null
+++ b/base/deploy/src/scriptlets/pkiscriptlet.py
@@ -0,0 +1,47 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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) 2011 Red Hat, Inc.
+# All rights reserved.
+#
+
+# System Imports
+import abc
+
+
+# PKI Deployment Classes
+class AbstractBasePkiScriptlet(object):
+ __metaclass__ = abc.ABCMeta
+
+ @abc.abstractmethod
+ def spawn(self):
+ """Retrieve data from the specified PKI dictionary and
+ use it to install a new PKI instance."""
+ return
+
+ @abc.abstractmethod
+ def respawn(self):
+ """Retrieve data from the specified PKI dictionary and
+ use it to update an existing PKI instance."""
+ return
+
+ @abc.abstractmethod
+ def destroy(self):
+ """Retrieve data from the specified PKI dictionary and
+ use it to destroy an existing PKI instance."""
+ return
+
diff --git a/base/deploy/src/scriptlets/security_databases.py b/base/deploy/src/scriptlets/security_databases.py
new file mode 100644
index 000000000..af47cbd5d
--- /dev/null
+++ b/base/deploy/src/scriptlets/security_databases.py
@@ -0,0 +1,78 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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) 2011 Red Hat, Inc.
+# All rights reserved.
+#
+
+# System Imports
+import os
+
+# PKI Deployment Imports
+import pkiconfig as config
+import pkimessages as log
+import pkiscriptlet
+
+
+# PKI Deployment Security Database Classes
+class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
+ rv = 0
+ pki_path = config.pki_root_prefix +\
+ config.pki_master_dict['pki_instance_root']
+ pki_instance_path = pki_path + "/" +\
+ config.pki_master_dict['pki_instance_name']
+ pki_subsystem_path = pki_instance_path + "/" +\
+ config.pki_master_dict['pki_subsystem'].lower()
+ pki_database_path = pki_subsystem_path + "/" +\
+ config.PKI_SECURITY_DATABASE_DIR
+
+ def spawn(self):
+ if not os.path.exists(self.pki_database_path):
+ config.pki_log.info(log.SECURITY_DATABASES_SPAWN_1, __name__)
+ elif not os.path.isdir(self.pki_database_path):
+ config.pki_log.error(
+ log.PKI_DIRECTORY_ALREADY_EXISTS_NOT_A_DIRECTORY_1,
+ self.pki_database_path)
+ self.rv = -1
+ else:
+ config.pki_log.error(log.PKI_DIRECTORY_ALREADY_EXISTS_1,
+ self.pki_database_path)
+ self.rv = -1
+ return self.rv
+
+ def respawn(self):
+ if not os.path.exists(self.pki_database_path) or\
+ not os.path.isdir(self.pki_database_path):
+ config.pki_log.error(
+ log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1,
+ self.pki_database_path)
+ self.rv = -1
+ else:
+ config.pki_log.info(log.SECURITY_DATABASES_RESPAWN_1, __name__)
+ return self.rv
+
+ def destroy(self):
+ if not os.path.exists(self.pki_database_path) or\
+ not os.path.isdir(self.pki_database_path):
+ config.pki_log.error(
+ log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1,
+ self.pki_database_path)
+ self.rv = -1
+ else:
+ config.pki_log.info(log.SECURITY_DATABASES_DESTROY_1, __name__)
+ return self.rv
+
diff --git a/base/java-tools/CMakeLists.txt b/base/java-tools/CMakeLists.txt
new file mode 100644
index 000000000..427ded555
--- /dev/null
+++ b/base/java-tools/CMakeLists.txt
@@ -0,0 +1,4 @@
+project(java-tools Java)
+
+add_subdirectory(src)
+add_subdirectory(templates)
diff --git a/base/java-tools/LICENSE b/base/java-tools/LICENSE
new file mode 100644
index 000000000..e281f4362
--- /dev/null
+++ b/base/java-tools/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/base/java-tools/doc/README b/base/java-tools/doc/README
new file mode 100644
index 000000000..fa0af7d4b
--- /dev/null
+++ b/base/java-tools/doc/README
@@ -0,0 +1,161 @@
+ Certificate System
+ Java Command Line Utilities
+
+
+Command Line Utility Purpose
+==============================================================================
+AtoB <input file> <output file> A command line utility utilized
+ to convert an ASCII BASE 64
+ blob into a BINARY BASE 64 blob.
+
+AuditVerify A command line utility utilized
+ to verify signatures in signed
+ audit log files.
+
+BtoA <input file> <output file> A command line utility utilized
+ to convert a BINARY BASE 64
+ blob into an ASCII BASE 64 blob.
+
+CMCEnroll A command line utility used to
+ sign a certificate enrollment
+ request with an agent's
+ certificate.
+
+CMCRequest A command line utility used to
+ construct a Certificate
+ Management Messages over
+ CMS (CMC) request.
+
+CMCResponse A command line utility used to
+ parse a CMC response.
+
+CMCRevoke A command line utility used to
+ sign a revocation request with
+ an agent's certificate.
+
+CRMFPopClient A command line utility used to
+ generate CRMF requests with
+ proof of possession (POP).
+
+DRMTool -drmtool_config_file A command line utility used to
+ <path + drmtool config file> change the storage key used
+ -source_ldif_file to wrap the symmetric key
+ <path + source ldif file> which is used to encrypt the
+ -target_ldif_file user's private key.
+ <path + target ldif file> Optionally, this utility
+ -log_file may also be used to re-index IDs
+ <path + log file > associated with the various
+ [-source_pki_security_database_path records which may be useful
+ <path to PKI source databases> for DRM consolidation.
+ -source_storage_token_name
+ '<source token>'
+ -source_storage_certificate_nickname
+ '<source nickname>'
+ -target_storage_certificate_file
+ <path to target certificate file>
+ [-source_pki_security_database_pwdfile
+ <path + pwdfile>]]
+ [-append_id_offset
+ <numeric offset> ||
+ -remove_id_offset
+ <numeric offset>]
+ [-source_drm_naming_context
+ <source DRM naming context>]
+ [-target_drm_naming_context
+ <target DRM naming context>]
+ [-process_requests_and_key_records_only]
+
+ExtJoiner <ext_file0> . . . <ext_file9> A command line utility utilized
+ to join a sequence of extensions
+ together so that the final
+ output can be used in the
+ configuration wizard for
+ specifying extra extensions
+ in default certificates
+ (i. e. - CA certificate,
+ SSL certificate).
+
+GenExtKeyUsage [true|false] A command line utility utilized
+ <OID_1> . . . <OID_9> to generate a DER-encoded
+ Extended Key Usage extension.
+ The first parameter is the
+ criticality of the extension,
+ true or false. The OIDs to be
+ included in the extension are
+ passed as command-line
+ arguments. The OIDs are
+ described in RFC 2459. For
+ example, the OID for code
+ signing is 1.3.6.1.5.5.7.3.3.
+
+GenIssuerAltNameExt <general_type0> A command line utility utilized
+ <general_name0> to generate an issuer
+ . . . alternative name extension in
+ <general_type3> base-64 encoding. The encoding
+ <general_name3> output can be used with the
+ configuration wizard, where:
+ <general_type#> can be one
+ of the following strings:
+ DNSName
+ EDIPartyName
+ IPAddressName
+ URIName
+ RFC822Name
+ OIDName
+ X500Name
+ <general_name#> is a string
+
+GenSubjectAltNameExt <general_type0> A command line utility utilized
+ <general_name0> to generate a subject
+ . . . alternative name extension in
+ <general_type3> base-64 encoding. The encoding
+ <general_name3> output can be used with the
+ configuration wizard, where:
+ <general_type#> can be one
+ of the following strings:
+ DNSName
+ EDIPartyName
+ IPAddressName
+ URIName
+ RFC822Name
+ OIDName
+ X500Name
+ <general_name#> is a string
+
+HttpClient A command line utility used
+ to communicate with any
+ http/https server.
+
+OCSPClient A command line utility that
+ verifies certificate status by
+ submitting Online Certificate
+ Status Protocol (OCSP) requests
+ to an instance of an OCSP
+ subsystem.
+
+PKCS10Client A command line utility that
+ generates a Public Key
+ Cryptography Standards
+ (PKCS) #10 enrollment
+ request.
+
+PKCS12Export A command line utility utilized
+ to create PKCS12 file.
+
+PrettyPrintCert <input file> [output file] A command line utility utilized
+ to print the contents of a
+ certificate stored as an ASCII
+ BASE 64 encoded blob in a
+ user-friendly manner.
+
+PrettyPrintCrl <input file> [output file] A command line utility utilized
+ to print the contents of a
+ Certificate Revocation List
+ (CRL) stored as an ASCII
+ BASE 64 encoded blob in a
+ user-friendly manner.
+
+TokenInfo A command line utility utilized
+ to display all external HSMs
+ visible to JSS.
+
diff --git a/base/java-tools/src/CMakeLists.txt b/base/java-tools/src/CMakeLists.txt
new file mode 100644
index 000000000..0411a54c7
--- /dev/null
+++ b/base/java-tools/src/CMakeLists.txt
@@ -0,0 +1,87 @@
+project(pki-tools_java Java)
+
+find_file(JSS_JAR
+ NAMES
+ jss4.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(COMMONS_CODEC_JAR
+ NAMES
+ commons-codec.jar
+ PATHS
+ /usr/share/java
+)
+
+find_file(XALAN_JAR
+ NAMES
+ xalan-j2.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(XERCES_JAR
+ NAMES
+ xerces-j2.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+set(pki-tools_java_SRCS
+ com/netscape/cmstools/PrettyPrintCrl.java
+ com/netscape/cmstools/BtoA.java
+ com/netscape/cmstools/PasswordCache.java
+ com/netscape/cmstools/OCSPClient.java
+ com/netscape/cmstools/PKCS12Export.java
+ com/netscape/cmstools/TestCRLSigning.java
+ com/netscape/cmstools/CRMFPopClient.java
+ com/netscape/cmstools/AuditVerify.java
+ com/netscape/cmstools/PrettyPrintCert.java
+ com/netscape/cmstools/HttpClient.java
+ com/netscape/cmstools/GenExtKeyUsage.java
+ com/netscape/cmstools/CMCRevoke.java
+ com/netscape/cmstools/TokenInfo.java
+ com/netscape/cmstools/CMCEnroll.java
+ com/netscape/cmstools/ExtJoiner.java
+ com/netscape/cmstools/CMCRequest.java
+ com/netscape/cmstools/AtoB.java
+ com/netscape/cmstools/GenIssuerAltNameExt.java
+ com/netscape/cmstools/GenSubjectAltNameExt.java
+ com/netscape/cmstools/CMCResponse.java
+ com/netscape/cmstools/PKCS10Client.java
+ com/netscape/cmstools/DRMTool.java
+)
+
+set(CMAKE_JAVA_INCLUDE_PATH
+ ${PKI_NSUTIL_JAR} ${PKI_CMSUTIL_JAR}
+ ${XALAN_JAR} ${XERCES_JAR}
+ ${JSS_JAR} ${COMMONS_CODEC_JAR})
+
+set(CMAKE_JAVA_TARGET_VERSION ${APPLICATION_VERSION})
+
+# build pki-tools
+add_jar(pki-tools ${pki-tools_java_SRCS})
+add_dependencies(pki-tools pki-nsutil pki-cmsutil)
+install(
+ FILES
+ com/netscape/cmstools/DRMTool.cfg
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/pki/java-tools/
+)
+install_jar(pki-tools ${JAVA_JAR_INSTALL_DIR}/pki)
+set(PKI_TOOLS_JAR ${pki-tools_JAR_FILE} CACHE INTERNAL "pki-tools jar file")
+
+create_javadoc(pki-java-tools-${APPLICATION_VERSION}
+ FILES ${pki-tools_java_SRCS}
+ CLASSPATH ${CMAKE_JAVA_INCLUDE_PATH}
+ WINDOWTITLE "pki-java-tools"
+ DOCTITLE "<h1>pki-java-tools</h1>"
+ AUTHOR TRUE
+ USE TRUE
+ VERSION TRUE
+)
+add_dependencies(pki-java-tools-${APPLICATION_VERSION}_javadoc pki-tools)
diff --git a/base/java-tools/src/com/netscape/cmstools/AtoB.java b/base/java-tools/src/com/netscape/cmstools/AtoB.java
new file mode 100644
index 000000000..48301e492
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/AtoB.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.cmstools;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * The AtoB class is a utility program designed to "translate" an ASCII
+ * BASE 64 encoded blob into a BINARY BASE 64 encoded blob. It assumes
+ * that the name of a data file is passed to the program via the command line,
+ * and that the contents contain a blob encoded in an ASCII BASE 64
+ * format. Note that the data file may contain an optional "-----BEGIN" header
+ * and/or an optional "-----END" trailer.
+ *
+ * <P>
+ * The program may be invoked as follows:
+ *
+ * <PRE>
+ *
+ * AtoB &lt;input filename&gt; &lt;output filename&gt;
+ *
+ * NOTE: &lt;input filename&gt; must contain an ASCII
+ * BASE 64 encoded blob
+ *
+ * &lt;output filename&gt; contains a BINARY
+ * BASE 64 encoded blob
+ * </PRE>
+ *
+ * @version $Revision$, $Date$
+ */
+public class AtoB {
+ // Define constants
+ public static final int ARGC = 2;
+ public static final String HEADER = "-----BEGIN";
+ public static final String TRAILER = "-----END";
+
+ public static void main(String argv[]) {
+
+ BufferedReader inputBlob = null;
+ String asciiBASE64BlobChunk = new String();
+ String asciiBASE64Blob = new String();
+ byte binaryBASE64Blob[] = null;
+ FileOutputStream outputBlob = null;
+
+ // (1) Check that two arguments were submitted to the program
+ if (argv.length != ARGC) {
+ System.out.println("Usage: AtoB " +
+ "<input filename> " +
+ "<output filename>");
+ return;
+ }
+
+ // (2) Create a DataInputStream() object to the BASE 64
+ // encoded blob contained within the file
+ // specified on the command line
+ try {
+ inputBlob = new BufferedReader(new InputStreamReader(
+ new BufferedInputStream(
+ new FileInputStream(
+ argv[0]))));
+ } catch (FileNotFoundException e) {
+ System.out.println("AtoB(): can''t find file " +
+ argv[0] + ":\n" + e);
+ return;
+ }
+
+ // (3) Read the entire contents of the specified BASE 64 encoded
+ // blob into a String() object throwing away any
+ // headers beginning with HEADER and any trailers beginning
+ // with TRAILER
+ try {
+ while ((asciiBASE64BlobChunk = inputBlob.readLine()) != null) {
+ if (!(asciiBASE64BlobChunk.startsWith(HEADER)) &&
+ !(asciiBASE64BlobChunk.startsWith(TRAILER))) {
+ asciiBASE64Blob += asciiBASE64BlobChunk.trim();
+ }
+ }
+ } catch (IOException e) {
+ System.out.println("AtoB(): Unexpected BASE64 " +
+ "encoded error encountered in readLine():\n" +
+ e);
+ }
+
+ // (4) Close the DataInputStream() object
+ try {
+ inputBlob.close();
+ } catch (IOException e) {
+ System.out.println("AtoB(): Unexpected BASE64 " +
+ "encoded error encountered in close():\n" + e);
+ }
+
+ // (5) Decode the ASCII BASE 64 blob enclosed in the
+ // String() object into a BINARY BASE 64 byte[] object
+
+ binaryBASE64Blob = Utils.base64decode(asciiBASE64Blob);
+
+ // (6) Finally, print the actual AtoB blob to the
+ // specified output file
+ try {
+ outputBlob = new FileOutputStream(argv[1]);
+ } catch (IOException e) {
+ System.out.println("AtoB(): unable to open file " +
+ argv[1] + " for writing:\n" + e);
+ return;
+ }
+
+ try {
+ outputBlob.write(binaryBASE64Blob);
+ } catch (IOException e) {
+ System.out.println("AtoB(): I/O error " +
+ "encountered during write():\n" +
+ e);
+ }
+
+ try {
+ outputBlob.close();
+ } catch (IOException e) {
+ System.out.println("AtoB(): Unexpected error " +
+ "encountered while attempting to close() " +
+ argv[1] + ":\n" + e);
+ }
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/AuditVerify.java b/base/java-tools/src/com/netscape/cmstools/AuditVerify.java
new file mode 100644
index 000000000..fb23e89fd
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/AuditVerify.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.cmstools;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.interfaces.DSAPublicKey;
+import java.security.interfaces.RSAPublicKey;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.security.x509.X509CertImpl;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.ObjectNotFoundException;
+import org.mozilla.jss.crypto.X509Certificate;
+
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * Tool for verifying signed audit logs
+ *
+ * @version $Revision$, $Date$
+ */
+public class AuditVerify {
+
+ private static void usage() {
+ System.out
+ .println("Usage: AuditVerify -d <dbdir> -n <signing certificate nickname> -a <log list file> [-P <cert/key db prefix>] [-v]");
+ System.exit(1);
+ }
+
+ public static final String CRYPTO_PROVIDER = "Mozilla-JSS";
+
+ public static byte[] base64decode(String input) throws Exception {
+ return Utils.base64decode(input);
+ }
+
+ // We always sign 0x0a as the line separator, regardless of what
+ // line separator characters are used in the log file. This helps
+ // signature verification be platform-independent.
+ private static final byte LINE_SEP_BYTE = 0x0a;
+
+ private static void output(int linenum, String mesg) throws IOException {
+ System.out.println("Line " + linenum + ": " + mesg);
+ }
+
+ private static void writeFile(String curfileName) {
+ System.out.println("======\nFile: " + curfileName + "\n======");
+ }
+
+ private static void writeSigStatus(int linenum, String sigStartFile,
+ int sigStartLine, String sigStopFile, int sigStopLine, String mesg)
+ throws IOException {
+ output(linenum, mesg + ": signature of " + sigStartFile + ":" +
+ sigStartLine + " to " + sigStopFile + ":" + sigStopLine);
+ }
+
+ private static class PrefixFilter implements FilenameFilter {
+ private String prefix;
+
+ public PrefixFilter(String prefix) {
+ this.prefix = prefix;
+ }
+
+ public boolean accept(File dir, String name) {
+ // look for <prefix>cert* in this directory
+ return (name.indexOf(prefix + "cert") != -1);
+ }
+ }
+
+ public static boolean validPrefix(String configDir, String prefix)
+ throws IOException {
+ File dir = new File(configDir);
+ if (!dir.isDirectory()) {
+ System.out.println("ERROR: \"" + dir + "\" is not a directory");
+ usage();
+ }
+
+ String matchingFiles[] = dir.list(new PrefixFilter(prefix));
+
+ // prefix may be valid if at least one file matched the pattern
+ return (matchingFiles.length > 0);
+ }
+
+ 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 void main(String args[]) {
+ try {
+
+ String dbdir = null;
+ String logListFile = null;
+ String signerNick = null;
+ String prefix = null;
+ boolean verbose = false;
+
+ for (int i = 0; i < args.length; ++i) {
+ if (args[i].equals("-d")) {
+ if (++i >= args.length)
+ usage();
+ dbdir = args[i];
+ } else if (args[i].equals("-a")) {
+ if (++i >= args.length)
+ usage();
+ logListFile = args[i];
+ } else if (args[i].equals("-n")) {
+ if (++i >= args.length)
+ usage();
+ signerNick = args[i];
+ } else if (args[i].equals("-P")) {
+ if (++i >= args.length)
+ usage();
+ prefix = args[i];
+ } else if (args[i].equals("-v")) {
+ verbose = true;
+ } else {
+ System.out.println("Unrecognized argument(" + i + "): "
+ + args[i]);
+ usage();
+ }
+ }
+ if (dbdir == null || logListFile == null || signerNick == null) {
+ System.out.println("Argument omitted");
+ usage();
+ }
+
+ // get list of log files
+ Vector<String> logFiles = new Vector<String>();
+ BufferedReader r = new BufferedReader(new FileReader(logListFile));
+ String listLine;
+ while ((listLine = r.readLine()) != null) {
+ StringTokenizer tok = new StringTokenizer(listLine, ",");
+ while (tok.hasMoreElements()) {
+ logFiles.addElement(((String) tok.nextElement()).trim());
+ }
+ }
+ if (logFiles.size() == 0) {
+ System.out.println("Error: no log files listed in " + logListFile);
+ System.exit(1);
+ }
+
+ // initialize crypto stuff
+ if (prefix == null) {
+ if (!validPrefix(dbdir, "")) {
+ System.out.println("ERROR: \"" + dbdir +
+ "\" does not contain any security databases");
+ usage();
+ }
+ CryptoManager.initialize(dbdir);
+ } else {
+ if (!validPrefix(dbdir, prefix)) {
+ System.out.println("ERROR: \"" + prefix +
+ "\" is not a valid prefix");
+ usage();
+ }
+ CryptoManager.initialize(
+ new CryptoManager.InitializationValues(dbdir, prefix, prefix,
+ "secmod.db")
+ );
+ }
+ CryptoManager cm = CryptoManager.getInstance();
+ X509Certificate signerCert = cm.findCertByNickname(signerNick);
+
+ X509CertImpl cert_i = null;
+ if (signerCert != null) {
+ byte[] signerCert_b = signerCert.getEncoded();
+ cert_i = new X509CertImpl(signerCert_b);
+ } else {
+ System.out.println("ERROR: signing certificate not found");
+ System.exit(1);
+ }
+
+ // verify signer's certificate
+ // not checking validity because we want to allow verifying old logs
+ //
+ if (!isSigningCert(cert_i)) {
+ System.out.println("info: signing certificate is not a signing certificate");
+ System.exit(1);
+ }
+
+ PublicKey pubk = signerCert.getPublicKey();
+ String sigAlgorithm = null;
+ if (pubk instanceof RSAPublicKey) {
+ sigAlgorithm = "SHA-256/RSA";
+ } else if (pubk instanceof DSAPublicKey) {
+ sigAlgorithm = "SHA-256/DSA";
+ } else {
+ System.out.println("Error: unknown key type: " +
+ pubk.getAlgorithm());
+ System.exit(1);
+ }
+ Signature sig = Signature.getInstance(sigAlgorithm, CRYPTO_PROVIDER);
+ sig.initVerify(pubk);
+
+ int goodSigCount = 0;
+ int badSigCount = 0;
+
+ int lastFileWritten = -1;
+
+ int sigStartLine = 1;
+ int sigStopLine = 1;
+ String sigStartFile = (String) logFiles.elementAt(0);
+ String sigStopFile = null;
+ int signedLines = 1;
+
+ for (int curfile = 0; curfile < logFiles.size(); ++curfile) {
+ String curfileName = (String) logFiles.elementAt(curfile);
+ BufferedReader br = new BufferedReader(new FileReader(curfileName));
+
+ if (verbose) {
+ writeFile(curfileName);
+ lastFileWritten = curfile;
+ }
+
+ String curLine;
+ int linenum = 0;
+ while ((curLine = br.readLine()) != null) {
+ ++linenum;
+ if (curLine.indexOf("AUDIT_LOG_SIGNING") != -1) {
+ if (curfile == 0 && linenum == 1) {
+ // Ignore the first signature of the first file,
+ // since it signs data we don't have access to.
+ if (verbose) {
+ output(linenum,
+ "Ignoring first signature of log series");
+ }
+ } else {
+ int sigStart = curLine.indexOf("sig: ") + 5;
+ if (sigStart < 5) {
+ output(linenum, "INVALID SIGNATURE");
+ ++badSigCount;
+ } else {
+ byte[] logSig =
+ base64decode(curLine.substring(sigStart));
+
+ // verify the signature
+ if (sig.verify(logSig)) {
+ // signature verifies correctly
+ if (verbose) {
+ writeSigStatus(linenum, sigStartFile,
+ sigStartLine, sigStopFile, sigStopLine,
+ "verification succeeded");
+ }
+ ++goodSigCount;
+ } else {
+ if (lastFileWritten < curfile) {
+ writeFile(curfileName);
+ lastFileWritten = curfile;
+ }
+ writeSigStatus(linenum, sigStartFile,
+ sigStartLine, sigStopFile, sigStopLine,
+ "VERIFICATION FAILED");
+ ++badSigCount;
+ }
+ }
+ sig.initVerify(pubk);
+ signedLines = 0;
+ sigStartLine = linenum;
+ sigStartFile = curfileName;
+ }
+ }
+
+ byte[] lineBytes = curLine.getBytes("UTF-8");
+ sig.update(lineBytes);
+ sig.update(LINE_SEP_BYTE);
+ ++signedLines;
+ sigStopLine = linenum;
+ sigStopFile = curfileName;
+ }
+
+ }
+
+ // Make sure there were no unsigned log entries at the end.
+ // The first signed line is the previous signature, but anything
+ // more than that is data.
+ if (signedLines > 1) {
+ System.out.println(
+ "ERROR: log entries after " + sigStartFile
+ + ":" + sigStartLine + " are UNSIGNED");
+ badSigCount++;
+ }
+
+ System.out.println("\nVerification process complete.");
+ System.out.println("Valid signatures: " + goodSigCount);
+ System.out.println("Invalid signatures: " + badSigCount);
+
+ if (badSigCount > 0) {
+ System.exit(2);
+ } else {
+ System.exit(0);
+ }
+
+ } catch (FileNotFoundException fnfe) {
+ System.out.println(fnfe);
+ } catch (ObjectNotFoundException onfe) {
+ System.out.println("ERROR: certificate not found");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ System.out.println("Verification process FAILED.");
+ System.exit(1);
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/BtoA.java b/base/java-tools/src/com/netscape/cmstools/BtoA.java
new file mode 100644
index 000000000..4c2e5c22a
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/BtoA.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.cmstools;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * The BtoA class is a utility program designed to "translate" a BINARY
+ * BASE 64 encoded blob into an ASCII BASE 64 encoded blob. It assumes
+ * that the name of a data file is passed to the program via the command line,
+ * and that the contents contain a blob encoded in a BINARY BASE 64
+ * format.
+ *
+ * <P>
+ * The program may be invoked as follows:
+ *
+ * <PRE>
+ *
+ * BtoA &lt;input filename&gt; &lt;output filename&gt;
+ *
+ * NOTE: &lt;input filename&gt; must contain a BINARY
+ * BASE 64 encoded blob
+ *
+ * &lt;output filename&gt; contains an ASCII
+ * BASE 64 encoded blob
+ * </PRE>
+ *
+ * @version $Revision$, $Date$
+ */
+public class BtoA {
+ // Define constants
+ public static final int ARGC = 2;
+
+ public static void main(String argv[]) {
+
+ FileInputStream inputBlob = null;
+ FileOutputStream outputBlob = null;
+
+ // (1) Check that two arguments were submitted to the program
+ if (argv.length != ARGC) {
+ System.out.println("Usage: BtoA " +
+ "<input filename> " +
+ "<output filename>");
+ return;
+ }
+
+ // (2) Create a DataInputStream() object to the BASE 64
+ // encoded blob contained within the file
+ // specified on the command line
+ try {
+ inputBlob = new FileInputStream(argv[0]);
+ } catch (FileNotFoundException e) {
+ System.out.println("BtoA(): can''t find file " +
+ argv[0] + ":\n" + e);
+ return;
+ }
+
+ // (3) Create a FileOutputStream() object to the BASE 64
+ // specified output file
+ try {
+ outputBlob = new FileOutputStream(argv[1]);
+ } catch (IOException e) {
+ System.out.println("BtoA(): unable to open file " +
+ argv[1] + " for writing:\n" + e);
+ return;
+ }
+
+ // (4) Convert the BINARY BASE 64 blob into an ASCII BASE 64 blob
+
+ try {
+ byte data[] = new byte[inputBlob.available()];
+ inputBlob.read(data);
+ String out = Utils.base64encode(data);
+ outputBlob.write(out.getBytes());
+ } catch (IOException e) {
+ System.out.println("BtoA(): Unexpected BASE64 " +
+ "encoded error encountered:\n" +
+ e);
+ }
+
+ // (5) Close the DataInputStream() object
+ try {
+ inputBlob.close();
+ } catch (IOException e) {
+ System.out.println("BtoA(): Unexpected input error " +
+ "encountered while attempting to close() " +
+ argv[0] + ":\n" + e);
+ }
+
+ // (6) Close the FileOutputStream() object
+ try {
+ outputBlob.close();
+ } catch (IOException e) {
+ System.out.println("BtoA(): Unexpected output error " +
+ "encountered while attempting to close() " +
+ argv[1] + ":\n" + e);
+ }
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/CMCEnroll.java b/base/java-tools/src/com/netscape/cmstools/CMCEnroll.java
new file mode 100644
index 000000000..e2e51a29d
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/CMCEnroll.java
@@ -0,0 +1,467 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmstools;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SignatureException;
+import java.util.Date;
+
+import netscape.security.pkcs.PKCS10;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.DigestAlgorithm;
+import org.mozilla.jss.crypto.ObjectNotFoundException;
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.pkcs10.CertificationRequest;
+import org.mozilla.jss.pkix.cmc.PKIData;
+import org.mozilla.jss.pkix.cmc.TaggedAttribute;
+import org.mozilla.jss.pkix.cmc.TaggedCertificationRequest;
+import org.mozilla.jss.pkix.cmc.TaggedRequest;
+import org.mozilla.jss.pkix.cms.ContentInfo;
+import org.mozilla.jss.pkix.cms.EncapsulatedContentInfo;
+import org.mozilla.jss.pkix.cms.IssuerAndSerialNumber;
+import org.mozilla.jss.pkix.cms.SignedData;
+import org.mozilla.jss.pkix.cms.SignerIdentifier;
+import org.mozilla.jss.pkix.cms.SignerInfo;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.pkix.primitive.Name;
+import org.mozilla.jss.util.Password;
+
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * Tool for signing PKCS #10 , return CMC enrollment request
+ *
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMCEnroll {
+
+ public static final String PR_REQUEST_CMC = "CMC";
+ public static final String PR_REQUEST_PKCS10 = "PKCS10";
+
+ public static final int ARGC = 4;
+ private static final String CERTDB = "cert8.db";
+ private static final String KEYDB = "key3.db";
+ public static final String HEADER = "-----BEGIN NEW CERTIFICATE REQUEST-----";
+ public static final String TRAILER = "-----END NEW CERTIFICATE REQUEST-----";
+
+ void cleanArgs(String[] s) {
+
+ }
+
+ public static X509Certificate getCertificate(String tokenname,
+ String nickname) throws Exception {
+ CryptoManager manager = CryptoManager.getInstance();
+ CryptoToken token = null;
+
+ if (tokenname.equals("internal")) {
+ 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 IOException("Signing Certificate not found");
+ }
+ }
+
+ public static java.security.PrivateKey getPrivateKey(String tokenname, String nickname)
+ throws Exception {
+
+ X509Certificate cert = getCertificate(tokenname, nickname);
+
+ return CryptoManager.getInstance().findPrivKeyByCert(cert);
+ }
+
+ /**
+ * getCMCBlob create and return the enrollent request.
+ * <P>
+ *
+ * @param signerCert the certificate of the authorized signer of the CMC revocation request.
+ * @param manager the crypto manger.
+ * @param nValue the nickname of the certificate inside the token.
+ * @param rValue request PKCS#10 file name.
+ * @return the CMC revocation request encoded in base64
+ */
+ static String getCMCBlob(X509Certificate signerCert, CryptoManager manager, String nValue, String rValue) {
+
+ String asciiBASE64Blob = rValue; // input pkcs10 blob
+ String tokenname = "internal";
+
+ try {
+
+ java.security.PrivateKey privKey = null;
+ PKCS10 pkcs = null;
+ SignerIdentifier si = null;
+ ContentInfo fullEnrollmentReq = null;
+
+ try {
+ byte[] decodedBytes = Utils.base64decode(asciiBASE64Blob);
+
+ pkcs = new PKCS10(decodedBytes);
+ } catch (IOException e) {
+ throw new IOException("Internal Error - " + e.toString());
+ } catch (SignatureException e) {
+ throw new IOException("Internal Error - " + e.toString());
+ } catch (NoSuchAlgorithmException e) {
+ throw new IOException("Internal Error - " + e.toString());
+ }
+
+ BigInteger serialno = signerCert.getSerialNumber();
+ byte[] certB = signerCert.getEncoded();
+ X509CertImpl impl = new X509CertImpl(certB);
+ X500Name issuerName = (X500Name) impl.getIssuerDN();
+ byte[] issuerByte = issuerName.getEncoded();
+ ByteArrayInputStream istream = new ByteArrayInputStream(issuerByte);
+
+ Name issuer = (Name) Name.getTemplate().decode(istream);
+ IssuerAndSerialNumber ias = new IssuerAndSerialNumber(issuer, new INTEGER(serialno.toString()));
+
+ si = new SignerIdentifier(SignerIdentifier.ISSUER_AND_SERIALNUMBER, ias, null);
+ privKey = getPrivateKey(tokenname, nValue);
+
+ // create CMC req
+ // transfer pkcs10 to jss class
+ int bpid = 1;
+ ByteArrayInputStream crInputStream = new ByteArrayInputStream(pkcs.toByteArray());
+ CertificationRequest cr = (CertificationRequest) CertificationRequest.getTemplate().decode(crInputStream);
+
+ TaggedCertificationRequest tcr = new
+ TaggedCertificationRequest(new
+ INTEGER(bpid++), cr);
+ TaggedRequest trq = new
+ TaggedRequest(TaggedRequest.PKCS10, tcr,
+ null);
+
+ SEQUENCE reqSequence = new SEQUENCE();
+
+ reqSequence.addElement(trq);
+
+ // Add some control sequence
+ // Verisign has transactionID,senderNonce
+ SEQUENCE controlSeq = new SEQUENCE();
+
+ 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 sn = Utils.base64encode(dig);
+
+ TaggedAttribute senderNonce = new TaggedAttribute(new
+ INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_senderNonce,
+ new OCTET_STRING(sn.getBytes()));
+
+ controlSeq.addElement(senderNonce);
+
+ // Verisign recommend transactionId be MD5 hash of publicKey
+ byte[] transId;
+
+ try {
+ MessageDigest MD5Digest = MessageDigest.getInstance("MD5");
+
+ transId = MD5Digest.digest(pkcs.getSubjectPublicKeyInfo().getKey());
+ } catch (Exception ex) {
+ transId = salt.getBytes();
+ }
+
+ TaggedAttribute transactionId = new TaggedAttribute(new
+ INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_transactionId,
+ new INTEGER(1, transId));
+
+ controlSeq.addElement(transactionId);
+
+ PKIData pkidata = new PKIData(controlSeq, reqSequence, new SEQUENCE(), new SEQUENCE());
+
+ EncapsulatedContentInfo ci = new
+ EncapsulatedContentInfo(OBJECT_IDENTIFIER.id_cct_PKIData,
+ pkidata);
+ // SHA1 is the default digest Alg for now.
+ DigestAlgorithm digestAlg = null;
+ SignatureAlgorithm signAlg = SignatureAlgorithm.RSASignatureWithSHA1Digest;
+ org.mozilla.jss.crypto.PrivateKey.Type signingKeyType =
+ ((org.mozilla.jss.crypto.PrivateKey) privKey).getType();
+
+ if (signingKeyType.equals(org.mozilla.jss.crypto.PrivateKey.Type.DSA))
+ signAlg = SignatureAlgorithm.DSASignatureWithSHA1Digest;
+ MessageDigest SHADigest = null;
+ byte[] digest = null;
+
+ try {
+ SHADigest = MessageDigest.getInstance("SHA1");
+ digestAlg = DigestAlgorithm.SHA1;
+
+ ByteArrayOutputStream ostream = new ByteArrayOutputStream();
+
+ pkidata.encode((OutputStream) ostream);
+ digest = SHADigest.digest(ostream.toByteArray());
+ } catch (NoSuchAlgorithmException e) {
+ }
+ SignerInfo signInfo = new
+ SignerInfo(si, null, null, OBJECT_IDENTIFIER.id_cct_PKIData, digest, signAlg,
+ (org.mozilla.jss.crypto.PrivateKey) 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);
+ }
+
+ org.mozilla.jss.crypto.X509Certificate[] agentChain = manager.buildCertificateChain(signerCert);
+ SET certs = new SET();
+
+ for (int i = 0; i < agentChain.length; i++) {
+ ANY cert = new ANY(agentChain[i].getEncoded());
+
+ certs.addElement(cert);
+ }
+ SignedData req = new SignedData(digestAlgs, ci, certs, null, signInfos);
+
+ fullEnrollmentReq = new
+ ContentInfo(req);
+
+ ByteArrayOutputStream bs = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(bs);
+
+ // format is PR_REQUEST_CMC
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+
+ fullEnrollmentReq.encode(os);
+ ps.print(Utils.base64encode(os.toByteArray()));
+ //fullEnrollmentReq.print(ps); // no header/trailer
+ asciiBASE64Blob = bs.toString();
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ return asciiBASE64Blob;
+ }
+
+ /** Creates a new instance of CMCEnroll */
+ public static void main(String[] s) {
+
+ String dValue = null, nValue = null, rValue = null, pValue = null;
+ FileOutputStream outputBlob = null;
+
+ // default path is "."
+ String mPath = ".";
+ // default prefix is ""
+ String mPrefix = "";
+
+ boolean bWrongParam = false;
+
+ // (1) Check that two arguments were submitted to the program
+ if (s.length != (ARGC * 2)) {
+ System.out.println("Wrong number of parameters:" + s.length);
+ System.out.println("Usage: CMCEnroll " +
+ "-d <dir to cert8.db, key3.db> " +
+ "-n <nickname> " +
+ "-r <request PKCS#10 file name> " +
+ "-p <password>"
+ );
+ bWrongParam = true;
+ } else {
+ int length;
+ int i;
+
+ length = s.length;
+ for (i = 0; i < length; i++) {
+ if (s[i].equals("-d")) {
+ dValue = s[i + 1];
+ } else if (s[i].equals("-n")) {
+ nValue = s[i + 1];
+ } else if (s[i].equals("-r")) {
+ rValue = s[i + 1];
+ } else if (s[i].equals("-p")) {
+ pValue = s[i + 1];
+ }
+ if (s[i].equals(""))
+ bWrongParam = true;
+
+ }
+
+ if (dValue == null || nValue == null || rValue == null || pValue == null)
+ bWrongParam = true;
+ else if (dValue.length() == 0 || nValue.length() == 0 || rValue.length() == 0 ||
+ pValue.length() == 0)
+ bWrongParam = true;
+ if (bWrongParam == true) {
+ System.out.println("Usage: CMCEnroll " +
+ "-d <dir to cert8.db, key3.db> " +
+ "-n <nickname> " +
+ "-r <request PKCS#10 file name> " +
+ "-p <password>"
+ );
+ System.exit(0);
+ }
+
+ try {
+ // initialize CryptoManager
+ mPath = dValue;
+ System.out.println("cert/key prefix = " + mPrefix);
+ System.out.println("path = " + mPath);
+ CryptoManager.InitializationValues vals =
+ new CryptoManager.InitializationValues(mPath, mPrefix,
+ mPrefix, "secmod.db");
+
+ CryptoManager.initialize(vals);
+
+ CryptoManager cm = CryptoManager.getInstance();
+ CryptoToken token = cm.getInternalKeyStorageToken();
+ Password pass = new Password(pValue.toCharArray());
+
+ token.login(pass);
+ X509Certificate signerCert = null;
+
+ signerCert = cm.findCertByNickname(nValue);
+
+ BufferedReader inputBlob = null;
+
+ try {
+ inputBlob = new BufferedReader(new InputStreamReader(
+ new BufferedInputStream(
+ new FileInputStream(
+ rValue))));
+ } catch (FileNotFoundException e) {
+ System.out.println("CMCEnroll: can''t find file " +
+ rValue + ":\n" + e);
+ return;
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ // (3) Read the entire contents of the specified BASE 64 encoded
+ // blob into a String() object throwing away any
+ // headers beginning with HEADER and any trailers beginning
+ // with TRAILER
+ String asciiBASE64BlobChunk = new String();
+ String asciiBASE64Blob = new String();
+
+ try {
+ while ((asciiBASE64BlobChunk = inputBlob.readLine()) != null) {
+ if (!(asciiBASE64BlobChunk.startsWith(HEADER)) &&
+ !(asciiBASE64BlobChunk.startsWith(TRAILER))) {
+ asciiBASE64Blob += asciiBASE64BlobChunk.trim();
+ }
+ }
+ } catch (IOException e) {
+ System.out.println("CMCEnroll: Unexpected BASE64 " +
+ "encoded error encountered in readLine():\n" +
+ e);
+ }
+ // (4) Close the DataInputStream() object
+ try {
+ inputBlob.close();
+ } catch (IOException e) {
+ System.out.println("CMCEnroll(): Unexpected BASE64 " +
+ "encoded error encountered in close():\n" + e);
+ }
+
+ asciiBASE64Blob = getCMCBlob(signerCert, cm, nValue, asciiBASE64Blob);
+ // (5) Decode the ASCII BASE 64 blob enclosed in the
+ // String() object into a BINARY BASE 64 byte[] object
+
+ @SuppressWarnings("unused")
+ byte binaryBASE64Blob[] =
+ Utils.base64decode(asciiBASE64Blob); // check for errors
+
+ // (6) Finally, print the actual CMCEnroll blob to the
+ // specified output file
+ try {
+ outputBlob = new FileOutputStream(rValue + ".out");
+ } catch (IOException e) {
+ System.out.println("CMCEnroll: unable to open file " +
+ rValue + ".out" + " for writing:\n" + e);
+ return;
+ }
+
+ System.out.println(HEADER);
+ System.out.println(asciiBASE64Blob + TRAILER);
+ try {
+ asciiBASE64Blob = HEADER + "\n" + asciiBASE64Blob + TRAILER;
+ outputBlob.write(asciiBASE64Blob.getBytes());
+ } catch (IOException e) {
+ System.out.println("CMCEnroll: I/O error " +
+ "encountered during write():\n" +
+ e);
+ }
+
+ try {
+ outputBlob.close();
+ } catch (IOException e) {
+ System.out.println("CMCEnroll: Unexpected error " +
+ "encountered while attempting to close() " +
+ "\n" + e);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ return;
+ }
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/CMCRequest.java b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java
new file mode 100644
index 000000000..591361149
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java
@@ -0,0 +1,1129 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmstools;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SignatureException;
+import java.util.Date;
+import java.util.StringTokenizer;
+
+import netscape.security.pkcs.PKCS10;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.BIT_STRING;
+import org.mozilla.jss.asn1.ENUMERATED;
+import org.mozilla.jss.asn1.GeneralizedTime;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.asn1.UTF8String;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.DigestAlgorithm;
+import org.mozilla.jss.crypto.ObjectNotFoundException;
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.pkcs10.CertificationRequest;
+import org.mozilla.jss.pkix.cmc.CMCCertId;
+import org.mozilla.jss.pkix.cmc.GetCert;
+import org.mozilla.jss.pkix.cmc.LraPopWitness;
+import org.mozilla.jss.pkix.cmc.OtherMsg;
+import org.mozilla.jss.pkix.cmc.PKIData;
+import org.mozilla.jss.pkix.cmc.TaggedAttribute;
+import org.mozilla.jss.pkix.cmc.TaggedCertificationRequest;
+import org.mozilla.jss.pkix.cmc.TaggedRequest;
+import org.mozilla.jss.pkix.cmmf.RevRequest;
+import org.mozilla.jss.pkix.cms.ContentInfo;
+import org.mozilla.jss.pkix.cms.EncapsulatedContentInfo;
+import org.mozilla.jss.pkix.cms.IssuerAndSerialNumber;
+import org.mozilla.jss.pkix.cms.SignedData;
+import org.mozilla.jss.pkix.cms.SignerIdentifier;
+import org.mozilla.jss.pkix.cms.SignerInfo;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.crmf.CertTemplate;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.pkix.primitive.Name;
+import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
+import org.mozilla.jss.util.Password;
+
+import com.netscape.cmsutil.util.HMACDigest;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * Tool for creating CMC full request
+ *
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ *
+ */
+public class CMCRequest {
+
+ public static final String PR_REQUEST_CMC = "CMC";
+ public static final String PR_REQUEST_CRMF = "CRMF";
+
+ public static final int ARGC = 1;
+ private static final String CERTDB = "cert8.db";
+ private static final String KEYDB = "key3.db";
+ public static final String HEADER = "-----BEGIN NEW CERTIFICATE REQUEST-----";
+ public static final String TRAILER = "-----END NEW CERTIFICATE REQUEST-----";
+
+ void cleanArgs(String[] s) {
+
+ }
+
+ public static X509Certificate getCertificate(String tokenname,
+ String nickname) throws Exception {
+ CryptoManager manager = CryptoManager.getInstance();
+ CryptoToken token = null;
+
+ if (tokenname.equals("internal")) {
+ 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 IOException("Signing Certificate not found");
+ }
+ }
+
+ public static java.security.PrivateKey getPrivateKey(String tokenname, String nickname)
+ throws Exception {
+
+ X509Certificate cert = getCertificate(tokenname, nickname);
+
+ return CryptoManager.getInstance().findPrivKeyByCert(cert);
+ }
+
+ /**
+ * getCMCBlob create and return the enrollent request.
+ * <P>
+ *
+ * @param signerCert the certificate of the authorized signer of the CMC revocation request.
+ * @param nickname the nickname of the certificate inside the token.
+ * @param rValue CRMF/PKCS10 request.
+ * @param format either crmf or pkcs10
+ * @return the CMC enrollment request encoded in base64
+ */
+ static ContentInfo getCMCBlob(X509Certificate signerCert, String nickname,
+ String[] rValue, String format, CryptoManager manager, String transactionMgtEnable,
+ String transactionMgtId, String identityProofEnable, String identityProofSharedSecret,
+ SEQUENCE controlSeq, SEQUENCE otherMsgSeq, int bpid) {
+
+ String tokenname = "internal";
+
+ ContentInfo fullEnrollmentReq = null;
+ try {
+ java.security.PrivateKey privKey = null;
+ SignerIdentifier si = null;
+
+ BigInteger serialno = signerCert.getSerialNumber();
+ byte[] certB = signerCert.getEncoded();
+ X509CertImpl impl = new X509CertImpl(certB);
+ X500Name issuerName = (X500Name) impl.getIssuerDN();
+ byte[] issuerByte = issuerName.getEncoded();
+ ByteArrayInputStream istream = new ByteArrayInputStream(issuerByte);
+
+ Name issuer = (Name) Name.getTemplate().decode(istream);
+ IssuerAndSerialNumber ias = new IssuerAndSerialNumber(
+ issuer, new INTEGER(serialno.toString()));
+
+ si = new SignerIdentifier(
+ SignerIdentifier.ISSUER_AND_SERIALNUMBER, ias, null);
+ privKey = getPrivateKey(tokenname, nickname);
+
+ TaggedRequest trq = null;
+ PKCS10 pkcs = null;
+ CertReqMsg certReqMsg = null;
+
+ // create CMC req
+ SEQUENCE reqSequence = new SEQUENCE();
+ try {
+ for (int k = 0; k < rValue.length; k++) {
+ String asciiBASE64Blob = rValue[k];
+ byte[] decodedBytes = Utils.base64decode(asciiBASE64Blob);
+
+ if (format.equals("crmf")) {
+ ByteArrayInputStream reqBlob =
+ new ByteArrayInputStream(decodedBytes);
+ SEQUENCE crmfMsgs = null;
+ try {
+ crmfMsgs = (SEQUENCE) new SEQUENCE.OF_Template(new
+ CertReqMsg.Template()).decode(reqBlob);
+ } catch (InvalidBERException ee) {
+ System.out.println("This is not a crmf request. Or this request has an error.");
+ System.exit(1);
+ }
+ certReqMsg = (CertReqMsg) crmfMsgs.elementAt(0);
+ trq = new TaggedRequest(TaggedRequest.CRMF, null,
+ certReqMsg);
+ } else if (format.equals("pkcs10")) {
+ try {
+ pkcs = new PKCS10(decodedBytes);
+ } catch (IllegalArgumentException e) {
+ System.out.println("This is not a PKCS10 request.");
+ System.exit(1);
+ }
+ ByteArrayInputStream crInputStream = new ByteArrayInputStream(
+ pkcs.toByteArray());
+ CertificationRequest cr = (CertificationRequest)
+ CertificationRequest.getTemplate().decode(crInputStream);
+ TaggedCertificationRequest tcr = new TaggedCertificationRequest(
+ new INTEGER(bpid++), cr);
+ trq = new
+ TaggedRequest(TaggedRequest.PKCS10, tcr, null);
+ } else {
+ System.out.println("Unrecognized request format: " + format);
+ System.exit(1);
+ }
+ reqSequence.addElement(trq);
+ }
+ } catch (IOException e) {
+ throw new IOException("Internal Error - " + e.toString());
+ } catch (SignatureException e) {
+ throw new IOException("Internal Error - " + e.toString());
+ } catch (NoSuchAlgorithmException e) {
+ throw new IOException("Internal Error - " + e.toString());
+ }
+
+ if (transactionMgtEnable.equals("true"))
+ bpid = addTransactionAttr(bpid, controlSeq, transactionMgtId, format,
+ pkcs, certReqMsg);
+
+ if (identityProofEnable.equals("true"))
+ bpid = addIdentityProofAttr(bpid, controlSeq, reqSequence,
+ identityProofSharedSecret);
+
+ PKIData pkidata = new PKIData(controlSeq, reqSequence, new SEQUENCE(), otherMsgSeq);
+
+ EncapsulatedContentInfo ci = new
+ EncapsulatedContentInfo(OBJECT_IDENTIFIER.id_cct_PKIData, pkidata);
+ // SHA1 is the default digest Alg for now.
+ DigestAlgorithm digestAlg = null;
+ SignatureAlgorithm signAlg = SignatureAlgorithm.RSASignatureWithSHA1Digest;
+ org.mozilla.jss.crypto.PrivateKey.Type signingKeyType =
+ ((org.mozilla.jss.crypto.PrivateKey) privKey).getType();
+
+ if (signingKeyType.equals(org.mozilla.jss.crypto.PrivateKey.Type.DSA))
+ signAlg = SignatureAlgorithm.DSASignatureWithSHA1Digest;
+ MessageDigest SHADigest = null;
+
+ byte[] digest = null;
+ try {
+ SHADigest = MessageDigest.getInstance("SHA1");
+ digestAlg = DigestAlgorithm.SHA1;
+
+ ByteArrayOutputStream ostream = new ByteArrayOutputStream();
+
+ pkidata.encode((OutputStream) ostream);
+ digest = SHADigest.digest(ostream.toByteArray());
+ } catch (NoSuchAlgorithmException e) {
+ }
+ SignerInfo signInfo = new
+ SignerInfo(si, null, null, OBJECT_IDENTIFIER.id_cct_PKIData, digest, signAlg,
+ (org.mozilla.jss.crypto.PrivateKey) 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);
+ }
+
+ org.mozilla.jss.crypto.X509Certificate[] agentChain = manager.buildCertificateChain(signerCert);
+ SET certs = new SET();
+
+ for (int i = 0; i < agentChain.length; i++) {
+ ANY cert = new ANY(agentChain[i].getEncoded());
+ certs.addElement(cert);
+ }
+ SignedData req = new SignedData(digestAlgs, ci, certs, null, signInfos);
+ fullEnrollmentReq = new ContentInfo(req);
+ ByteArrayOutputStream bs = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(bs);
+
+ if (fullEnrollmentReq != null) {
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+
+ fullEnrollmentReq.encode(os);
+ ps.print(Utils.base64encode(os.toByteArray()));
+ }
+ String asciiBASE64Blob = bs.toString();
+
+ System.out.println("");
+ System.out.println("The CMC enrollment request in base-64 encoded format:");
+ System.out.println("");
+ System.out.println(asciiBASE64Blob);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ return fullEnrollmentReq;
+ }
+
+ static void printUsage() {
+ System.out.println("");
+ System.out.println("Usage: CMCRequest <configuration file>");
+ System.out.println("For example, CMCRequest CMCRequest.cfg");
+ System.out.println("");
+ System.out.println("The configuration file should look like as follows:");
+ System.out.println("");
+ System.out.println("#numRequests: Total number of PKCS10 requests or CRMF requests.");
+ System.out.println("numRequests=1");
+ System.out.println("");
+ System.out.println("#input: full path for the PKCS10 request or CRMF request,");
+ System.out.println("#the content must be in Base-64 encoded format");
+ System.out.println("#Multiple files are supported. They must be separated by space.");
+ System.out.println("input=crmf1");
+ System.out.println("");
+ System.out.println("#output: full path for the CMC request in binary format");
+ System.out.println("output=/u/doc/cmcReq");
+ System.out.println("");
+ System.out.println("#nickname: nickname for agent certificate which will be used");
+ System.out.println("#to sign the CMC full request.");
+ System.out.println("nickname=CMS Agent Certificate");
+ System.out.println("");
+ System.out.println("#dbdir: directory for cert8.db, key3.db and secmod.db");
+ System.out.println("dbdir=/u/smith/.netscape");
+ System.out.println("");
+ System.out.println("#password: password for cert8.db which stores the agent");
+ System.out.println("#certificate");
+ System.out.println("password=pass");
+ System.out.println("");
+ System.out.println("#format: request format, either pkcs10 or crmf");
+ System.out.println("format=crmf");
+ System.out.println("");
+ System.out.println("#confirmCertAcceptance.enable: if true, then the request will");
+ System.out.println("#contain this control. Otherwise, false.");
+ System.out.println("confirmCertAcceptance.enable=true");
+ System.out.println("");
+ System.out.println("#confirmCertAcceptance.serial: The serial number for");
+ System.out.println("#confirmCertAcceptance control");
+ System.out.println("confirmCertAcceptance.serial=3");
+ System.out.println("");
+ System.out.println("#confirmCertAcceptance.issuer: The issuer name for");
+ System.out.println("#confirmCertAcceptance control");
+ System.out.println("confirmCertAcceptance.issuer=cn=Certificate Manager,c=us");
+ System.out.println("");
+ System.out.println("#getCert.enable: if true, then the request will contain this");
+ System.out.println("#control. Otherwise, false.");
+ System.out.println("getCert.enable=true");
+ System.out.println("");
+ System.out.println("#getCert.serial: The serial number for getCert control");
+ System.out.println("getCert.serial=3");
+ System.out.println("");
+ System.out.println("#getCert.issuer: The issuer name for getCert control");
+ System.out.println("getCert.issuer=cn=Certificate Manager,c=us");
+ System.out.println("");
+ System.out.println("#dataReturn.enable: if true, then the request will contain");
+ System.out.println("#this control. Otherwise, false.");
+ System.out.println("dataReturn.enable=true");
+ System.out.println("");
+ System.out.println("#dataReturn.data: data contained in the control.");
+ System.out.println("dataReturn.data=test");
+ System.out.println("");
+ System.out.println("#transactionMgt.enable: if true, then the request will contain");
+ System.out.println("#this control. Otherwise, false.");
+ System.out.println("transactionMgt.enable=true");
+ System.out.println("");
+ System.out.println("#transactionMgt.id: transaction identifier. Verisign recommend");
+ System.out.println("#transactionId to be MD5 hash of publicKey.");
+ System.out.println("transactionMgt.id=");
+ System.out.println("");
+ System.out.println("#senderNonce.enable: if true, then the request will contain this");
+ System.out.println("#control. Otherwise, false.");
+ System.out.println("senderNonce.enable=true");
+ System.out.println("");
+ System.out.println("#senderNonce.id: sender nonce");
+ System.out.println("senderNonce.id=");
+ System.out.println("");
+ System.out.println("#revRequest.enable: if true, then the request will contain this");
+ System.out.println("#control. Otherwise, false.");
+ System.out.println("revRequest.enable=true");
+ System.out.println("");
+ System.out.println("#revRequest.nickname: The nickname for the revoke certificate");
+ System.out.println("revRequest.nickname=newuser's 102504a ID");
+ System.out.println("");
+ System.out.println("#revRequest.issuer: The issuer name for the certificate being");
+ System.out.println("#revoked.");
+ System.out.println("revRequest.issuer=cn=Certificate Manager,c=us");
+ System.out.println("");
+ System.out.println("#revRequest.serial: The serial number for the certificate being");
+ System.out.println("#revoked.");
+ System.out.println("revRequest.serial=61");
+ System.out.println("");
+ System.out.println("#revRequest.reason: The reason for revoking this certificate: ");
+ System.out.println("# unspecified, keyCompromise, caCompromise,");
+ System.out.println("# affiliationChanged, superseded, cessationOfOperation,");
+ System.out.println("# certificateHold, removeFromCRL");
+ System.out.println("revRequest.reason=unspecified");
+ System.out.println("");
+ System.out.println("#revRequest.sharedSecret: The sharedSecret");
+ System.out.println("revRequest.sharedSecret=");
+ System.out.println("");
+ System.out.println("#revRequest.comment: The human readable comment");
+ System.out.println("revRequest.comment=");
+ System.out.println("");
+ System.out.println("#revRequest.invalidityDatePresent: if true, the current time will be the");
+ System.out.println("# invalidityDate. If false, no invalidityDate");
+ System.out.println("# is present.");
+ System.out.println("revRequest.invalidityDatePresent=false");
+ System.out.println("");
+ System.out.println("#identityProof.enable: if true, then the request will contain");
+ System.out.println("#this control. Otherwise, false.");
+ System.out.println("identityProof.enable=true");
+ System.out.println("");
+ System.out.println("#identityProof.sharedSecret: Shared Secret");
+ System.out.println("identityProof.sharedSecret=testing");
+ System.out.println("");
+ System.out.println("#popLinkWitness.enable: if true, then the request will contain");
+ System.out.println("#this control. Otherwise, false.");
+ System.out.println("#If you want to test this control, make sure to use CRMFPopClient ");
+ System.out.println("# to generate the CRMF request which will include the ");
+ System.out.println("#idPOPLinkWitness attribute in the controls section of the ");
+ System.out.println("#CertRequest structure.");
+ System.out.println("popLinkWitness.enable=false");
+ System.out.println("");
+ System.out.println("#LraPopWitness.enable: if true, then the request will contain this");
+ System.out.println("#control. Otherwise, false.");
+ System.out.println("LraPopWitness.enable=true");
+ System.out.println("");
+ System.out.println("#LraPopWitness.bodyPartIDs: List of body part IDs");
+ System.out.println("#Each id is separated by space.");
+ System.out.println("LraPopWitness.bodyPartIDs=1");
+ System.exit(1);
+ }
+
+ private static int addLraPopWitnessAttr(int bpid, SEQUENCE seq, String bodyPartIDs) {
+ StringTokenizer tokenizer = new StringTokenizer(bodyPartIDs, " ");
+ SEQUENCE bodyList = new SEQUENCE();
+ while (tokenizer.hasMoreTokens()) {
+ String s = (String) tokenizer.nextToken();
+ bodyList.addElement(new INTEGER(s));
+ }
+ LraPopWitness lra = new LraPopWitness(new INTEGER(0), bodyList);
+ TaggedAttribute cont = new TaggedAttribute(new
+ INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_lraPOPWitness, lra);
+ System.out.println("Successfully create LRA POP witness control. bpid = " + (bpid - 1));
+ System.out.println("");
+ seq.addElement(cont);
+ return bpid;
+ }
+
+ private static int addConfirmCertAttr(int bpid, SEQUENCE seq, String confirmCertIssuer,
+ String confirmCertSerial) {
+ try {
+ INTEGER serial = new INTEGER(confirmCertSerial);
+ X500Name issuername = new X500Name(confirmCertIssuer);
+ byte[] issuerbyte = issuername.getEncoded();
+ ANY issuern = new ANY(issuerbyte);
+ CMCCertId cmcCertId = new CMCCertId(issuern, serial, null);
+ TaggedAttribute cmcCertIdControl = new TaggedAttribute(new
+ INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_idConfirmCertAcceptance, cmcCertId);
+ System.out.println("Successfully create confirm certificate acceptance control. bpid = " + (bpid - 1));
+ System.out.println("");
+ seq.addElement(cmcCertIdControl);
+ } catch (Exception e) {
+ System.out.println("Error in creating confirm certificate acceptance control. Check the parameters.");
+ System.exit(1);
+ }
+ return bpid;
+ }
+
+ private static ENUMERATED toCRLReason(String str) {
+ if (str.equalsIgnoreCase("unspecified")) {
+ return RevRequest.unspecified;
+ } else if (str.equalsIgnoreCase("keyCompromise")) {
+ return RevRequest.keyCompromise;
+ } else if (str.equalsIgnoreCase("caCompromise")) {
+ return RevRequest.cACompromise;
+ } else if (str.equalsIgnoreCase("affiliationChanged")) {
+ return RevRequest.affiliationChanged;
+ } else if (str.equalsIgnoreCase("superseded")) {
+ return RevRequest.superseded;
+ } else if (str.equalsIgnoreCase("cessationOfOperation")) {
+ return RevRequest.cessationOfOperation;
+ } else if (str.equalsIgnoreCase("certificateHold")) {
+ return RevRequest.certificateHold;
+ } else if (str.equalsIgnoreCase("removeFromCRL")) {
+ return RevRequest.removeFromCRL;
+ }
+
+ System.out.println("Unrecognized CRL reason");
+ System.exit(1);
+
+ return RevRequest.unspecified;
+ }
+
+ private static int addIdentityProofAttr(int bpid, SEQUENCE seq, SEQUENCE reqSequence,
+ String sharedSecret) {
+ byte[] b = ASN1Util.encode(reqSequence);
+ byte[] key = null;
+ byte[] finalDigest = null;
+ try {
+ MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1");
+ key = SHA1Digest.digest(sharedSecret.getBytes());
+ } catch (NoSuchAlgorithmException ex) {
+ System.out.println("CMCRequest::addIdentityProofAttr() - "
+ + "No such algorithm!");
+ return -1;
+ }
+
+ try {
+ MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1");
+ HMACDigest hmacDigest = new HMACDigest(SHA1Digest, key);
+ hmacDigest.update(b);
+ finalDigest = hmacDigest.digest();
+ } catch (NoSuchAlgorithmException ex) {
+ }
+
+ TaggedAttribute identityProof = new TaggedAttribute(new
+ INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_identityProof,
+ new OCTET_STRING(finalDigest));
+ seq.addElement(identityProof);
+ System.out.println("Identity Proof control: ");
+ System.out.print(" Value: ");
+ for (int i = 0; i < finalDigest.length; i++) {
+ System.out.print(finalDigest[i] + " ");
+ }
+ System.out.println("");
+ System.out.println("Successfully create identityProof control. bpid = " + (bpid - 1));
+ System.out.println("");
+ return bpid;
+ }
+
+ private static int addRevRequestAttr(int bpid, SEQUENCE seq, SEQUENCE otherMsgSeq, String nickname,
+ String revRequestIssuer, String revRequestSerial, String revRequestReason,
+ String revRequestSharedSecret, String revRequestComment, String invalidityDatePresent,
+ CryptoManager manager) {
+ try {
+ if (nickname.length() <= 0) {
+ System.out.println("The nickname for the certificate being revoked is null");
+ System.exit(1);
+ }
+ String nickname1 = nickname;
+ UTF8String comment = null;
+ OCTET_STRING sharedSecret = null;
+ GeneralizedTime d = null;
+ X500Name subjectname = new X500Name(revRequestIssuer);
+ INTEGER snumber = new INTEGER(revRequestSerial);
+ ENUMERATED reason = toCRLReason(revRequestReason);
+ if (revRequestSharedSecret.length() > 0)
+ sharedSecret = new OCTET_STRING(revRequestSharedSecret.getBytes());
+ if (revRequestComment.length() > 0)
+ comment = new UTF8String(revRequestComment);
+ if (invalidityDatePresent.equals("true"))
+ d = new GeneralizedTime(new Date());
+ RevRequest revRequest =
+ new RevRequest(new ANY(subjectname.getEncoded()), snumber,
+ reason, d, sharedSecret, comment);
+ int revokeBpid = bpid;
+ TaggedAttribute revRequestControl = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_revokeRequest, revRequest);
+ seq.addElement(revRequestControl);
+
+ if (sharedSecret != null) {
+ System.out.println("Successfully create revRequest control. bpid = " + (bpid - 1));
+ System.out.println("");
+ return bpid;
+ }
+
+ EncapsulatedContentInfo revokeContent = new EncapsulatedContentInfo(
+ OBJECT_IDENTIFIER.id_cct_PKIData, revRequestControl);
+ DigestAlgorithm digestAlg1 = null;
+ SignatureAlgorithm signAlg1 = SignatureAlgorithm.RSASignatureWithSHA1Digest;
+ java.security.PrivateKey revokePrivKey = null;
+ X509Certificate revokeCert = null;
+ try {
+ revokeCert = manager.findCertByNickname(nickname1);
+ } catch (ObjectNotFoundException e) {
+ System.out.println("Certificate not found: " + nickname1);
+ System.exit(1);
+ }
+ revokePrivKey = manager.findPrivKeyByCert(revokeCert);
+ org.mozilla.jss.crypto.PrivateKey.Type signingKeyType1 =
+ ((org.mozilla.jss.crypto.PrivateKey) revokePrivKey).getType();
+ if (signingKeyType1.equals(org.mozilla.jss.crypto.PrivateKey.Type.DSA))
+ signAlg1 = SignatureAlgorithm.DSASignatureWithSHA1Digest;
+
+ MessageDigest rSHADigest = null;
+ byte[] rdigest = null;
+ try {
+ rSHADigest = MessageDigest.getInstance("SHA1");
+ digestAlg1 = DigestAlgorithm.SHA1;
+
+ ByteArrayOutputStream ostream = new ByteArrayOutputStream();
+
+ revRequestControl.encode((OutputStream) ostream);
+ rdigest = rSHADigest.digest(ostream.toByteArray());
+ } catch (NoSuchAlgorithmException e) {
+ }
+
+ ByteArrayInputStream bistream =
+ new ByteArrayInputStream(subjectname.getEncoded());
+ Name iname = (Name) Name.getTemplate().decode(bistream);
+ IssuerAndSerialNumber ias1 = new IssuerAndSerialNumber(iname, snumber);
+
+ SignerIdentifier rsi = new SignerIdentifier(
+ SignerIdentifier.ISSUER_AND_SERIALNUMBER, ias1, null);
+
+ SignerInfo signInfo1 = new SignerInfo(rsi, null, null,
+ OBJECT_IDENTIFIER.id_cct_PKIData, rdigest, signAlg1,
+ (org.mozilla.jss.crypto.PrivateKey) revokePrivKey);
+
+ SET signInfos1 = new SET();
+ signInfos1.addElement(signInfo1);
+ SET digestAlgs1 = new SET();
+ if (digestAlg1 != null) {
+ AlgorithmIdentifier ai1 = new AlgorithmIdentifier(digestAlg1.toOID(), null);
+ digestAlgs1.addElement(ai1);
+ }
+
+ org.mozilla.jss.crypto.X509Certificate[] revokeCertChain =
+ manager.buildCertificateChain(revokeCert);
+ SET certs1 = new SET();
+ for (int i = 0; i < revokeCertChain.length; i++) {
+ ANY cert1 = new ANY(revokeCertChain[i].getEncoded());
+ certs1.addElement(cert1);
+ }
+
+ SignedData sData = new SignedData(digestAlgs1, revokeContent, certs1, null, signInfos1);
+ OBJECT_IDENTIFIER signedDataOID = new OBJECT_IDENTIFIER("1.2.840.113549.1.7.2");
+ ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
+ sData.encode(bos1);
+ OtherMsg otherMsg = new OtherMsg(new INTEGER(revokeBpid), signedDataOID, new ANY(bos1.toByteArray()));
+ otherMsgSeq.addElement(otherMsg);
+ System.out.println("Successfully create revRequest control. bpid = " + (bpid - 1));
+ System.out.println("");
+ } catch (Exception e) {
+ System.out.println("Error in creating revRequest control. Check the parameters.");
+ System.exit(1);
+ }
+
+ return bpid;
+ }
+
+ private static int addGetCertAttr(int bpid, SEQUENCE seq, String issuer, String serial) {
+ try {
+ INTEGER serialno = new INTEGER(serial);
+ X500Name issuername = new X500Name(issuer);
+ byte[] issuerbyte = issuername.getEncoded();
+ ANY issuern = new ANY(issuerbyte);
+ GetCert getCert = new GetCert(issuern, serialno);
+ TaggedAttribute getCertControl = new TaggedAttribute(new
+ INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_getCert, getCert);
+ System.out.println("Successfully create get certificate control. bpid = " + (bpid - 1));
+ System.out.println("");
+ seq.addElement(getCertControl);
+ } catch (Exception e) {
+ System.out.println("Error in creating get certificate control. Check the parameters.");
+ System.exit(1);
+ }
+
+ return bpid;
+ }
+
+ private static int addDataReturnAttr(int bpid, SEQUENCE seq, String str) {
+ try {
+ byte bvalue[] = str.getBytes();
+ System.out.println("Data Return Control: ");
+ String ss = " Value: ";
+ for (int m = 0; m < bvalue.length; m++) {
+ ss = ss + bvalue[m] + " ";
+ }
+ System.out.println(ss);
+ OCTET_STRING s = new OCTET_STRING(bvalue);
+ TaggedAttribute dataReturnControl = new TaggedAttribute(new
+ INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_dataReturn, s);
+ seq.addElement(dataReturnControl);
+ System.out.println("Successfully create data return control. bpid = " + (bpid - 1));
+ System.out.println("");
+ } catch (Exception e) {
+ System.out.println("Error in creating data return control. Check the parameters.");
+ System.exit(1);
+ }
+
+ return bpid;
+ }
+
+ private static int addTransactionAttr(int bpid, SEQUENCE seq, String id, String format,
+ PKCS10 pkcs, CertReqMsg certReqMsg) {
+ byte[] transId = null;
+ Date date = new Date();
+ String salt = "lala123" + date.toString();
+ if (id == null || id.equals("")) {
+ try {
+ MessageDigest MD5Digest = MessageDigest.getInstance("MD5");
+ if (format.equals("crmf")) {
+ CertRequest certreq = certReqMsg.getCertReq();
+ CertTemplate certTemplate = certreq.getCertTemplate();
+ SubjectPublicKeyInfo pkinfo = certTemplate.getPublicKey();
+ BIT_STRING bitString = pkinfo.getSubjectPublicKey();
+ byte[] b = bitString.getBits();
+ transId = MD5Digest.digest(b);
+ } else if (format.equals("pkcs10")) {
+ transId = MD5Digest.digest(pkcs.getSubjectPublicKeyInfo().getKey());
+ }
+ } catch (Exception ex) {
+ transId = salt.getBytes();
+ }
+ } else {
+ transId = id.getBytes();
+ }
+
+ if (transId == null) {
+ System.out.println("CMCRequest::addTransactionAttr() - "
+ + "transId is null!");
+ return -1;
+ }
+
+ INTEGER ii = new INTEGER(1, transId);
+ TaggedAttribute transactionId = new TaggedAttribute(new
+ INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_transactionId, ii);
+ System.out.println("Transaction ID control: ");
+ System.out.println(" Value: " + ii.toString());
+ System.out.println("Successfully create transaction management control. bpid = " + (bpid - 1));
+ System.out.println("");
+
+ seq.addElement(transactionId);
+
+ return bpid;
+ }
+
+ private static int addSenderNonceAttr(int bpid, SEQUENCE seq, String nonce) {
+ byte[] dig;
+ String sn = nonce;
+ if (nonce == null || nonce.equals("")) {
+ // Verisign has transactionID,senderNonce
+ Date date = new Date();
+ String salt = "lala123" + date.toString();
+
+ try {
+ MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1");
+
+ dig = SHA1Digest.digest(salt.getBytes());
+ } catch (NoSuchAlgorithmException ex) {
+ dig = salt.getBytes();
+ }
+
+ sn = Utils.base64encode(dig);
+ }
+ byte bb[] = sn.getBytes();
+ System.out.println("SenderNonce control: ");
+ String ss = " Value: ";
+ for (int m = 0; m < bb.length; m++) {
+ ss = ss + bb[m] + " ";
+ }
+ System.out.println(ss);
+ TaggedAttribute senderNonce = new TaggedAttribute(new
+ INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_senderNonce,
+ new OCTET_STRING(sn.getBytes()));
+ System.out.println("Successfully create sender nonce control. bpid = " + (bpid - 1));
+ System.out.println("");
+ seq.addElement(senderNonce);
+ return bpid;
+ }
+
+ private static int addPopLinkWitnessAttr(int bpid, SEQUENCE controlSeq) {
+ byte[] seed =
+ { 0x10, 0x53, 0x42, 0x24, 0x1a, 0x2a, 0x35, 0x3c,
+ 0x7a, 0x52, 0x54, 0x56, 0x71, 0x65, 0x66, 0x4c,
+ 0x51, 0x34, 0x35, 0x23, 0x3c, 0x42, 0x43, 0x45,
+ 0x61, 0x4f, 0x6e, 0x43, 0x1e, 0x2a, 0x2b, 0x31,
+ 0x32, 0x34, 0x35, 0x36, 0x55, 0x51, 0x48, 0x14,
+ 0x16, 0x29, 0x41, 0x42, 0x43, 0x7b, 0x63, 0x44,
+ 0x6a, 0x12, 0x6b, 0x3c, 0x4c, 0x3f, 0x00, 0x14,
+ 0x51, 0x61, 0x15, 0x22, 0x23, 0x5f, 0x5e, 0x69 };
+
+ TaggedAttribute idPOPLinkRandom = new TaggedAttribute(new
+ INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_idPOPLinkRandom,
+ new OCTET_STRING(seed));
+ controlSeq.addElement(idPOPLinkRandom);
+ System.out.println("Successfully create PopLinkWitness control. bpid = " + (bpid - 1));
+ System.out.println("");
+ return bpid;
+ }
+
+ public static void main(String[] s) {
+ String numRequests = null;
+ String dbdir = null, nickname = null;
+ String ifilename = null, ofilename = null, password = null, format = null;
+ String confirmCertEnable = "false", confirmCertIssuer = null, confirmCertSerial = null;
+ String getCertEnable = "false", getCertIssuer = null, getCertSerial = null;
+ String dataReturnEnable = "false", dataReturnData = null;
+ String transactionMgtEnable = "false", transactionMgtId = null;
+ String senderNonceEnable = "false", senderNonce = null;
+ String revCertNickname = "";
+ String revRequestEnable = "false", revRequestIssuer = null, revRequestSerial = null;
+ String revRequestReason = null, revRequestSharedSecret = null, revRequestComment = null;
+ String revRequestInvalidityDatePresent = "false";
+ String identityProofEnable = "false", identityProofSharedSecret = null;
+ String popLinkWitnessEnable = "false";
+ String bodyPartIDs = null, lraPopWitnessEnable = "false";
+
+ System.out.println("");
+
+ // Check that the correct # of arguments were submitted to the program
+ if (s.length != (ARGC)) {
+ System.out.println("Wrong number of parameters:" + s.length);
+ printUsage();
+ }
+
+ String configFile = s[0];
+ BufferedReader reader = null;
+ try {
+ reader = new BufferedReader(new InputStreamReader(
+ new BufferedInputStream(
+ new FileInputStream(
+ configFile))));
+ } catch (FileNotFoundException e) {
+ System.out.println("CMCRequest: can't find configuration file: " + configFile);
+ printUsage();
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ try {
+ String str = "";
+ while ((str = reader.readLine()) != null) {
+ str = str.trim();
+ if (!str.startsWith("#") && str.length() > 0) {
+ int index = str.indexOf("=");
+ String name = "";
+ String val = "";
+ if (index == -1) {
+ System.out.println("Error in configuration file: " + str);
+ System.exit(1);
+ }
+ name = str.substring(0, index);
+ if (index != str.length() - 1)
+ val = str.substring(index + 1);
+
+ if (name.equals("format")) {
+ format = val;
+ } else if (name.equals("dbdir")) {
+ dbdir = val;
+ } else if (name.equals("nickname")) {
+ nickname = val;
+ } else if (name.equals("password")) {
+ password = val;
+ } else if (name.equals("output")) {
+ ofilename = val;
+ } else if (name.equals("input")) {
+ ifilename = val;
+ } else if (name.equals("confirmCertAcceptance.serial")) {
+ confirmCertSerial = val;
+ } else if (name.equals("confirmCertAcceptance.issuer")) {
+ confirmCertIssuer = val;
+ } else if (name.equals("confirmCertAcceptance.enable")) {
+ confirmCertEnable = val;
+ } else if (name.equals("getCert.enable")) {
+ getCertEnable = val;
+ } else if (name.equals("getCert.issuer")) {
+ getCertIssuer = val;
+ } else if (name.equals("getCert.serial")) {
+ getCertSerial = val;
+ } else if (name.equals("dataReturn.enable")) {
+ dataReturnEnable = val;
+ } else if (name.equals("dataReturn.data")) {
+ dataReturnData = val;
+ } else if (name.equals("transactionMgt.enable")) {
+ transactionMgtEnable = val;
+ } else if (name.equals("transactionMgt.id")) {
+ transactionMgtId = val;
+ } else if (name.equals("senderNonce.enable")) {
+ senderNonceEnable = val;
+ } else if (name.equals("senderNonce")) {
+ senderNonce = val;
+ } else if (name.equals("revRequest.enable")) {
+ revRequestEnable = val;
+ } else if (name.equals("revRequest.issuer")) {
+ revRequestIssuer = val;
+ } else if (name.equals("revRequest.serial")) {
+ revRequestSerial = val;
+ } else if (name.equals("revRequest.reason")) {
+ revRequestReason = val;
+ } else if (name.equals("revRequest.sharedSecret")) {
+ revRequestSharedSecret = val;
+ } else if (name.equals("revRequest.comment")) {
+ revRequestComment = val;
+ } else if (name.equals("revRequest.invalidityDatePresent")) {
+ revRequestInvalidityDatePresent = val;
+ } else if (name.equals("revRequest.nickname")) {
+ revCertNickname = val;
+ } else if (name.equals("identityProof.enable")) {
+ identityProofEnable = val;
+ } else if (name.equals("identityProof.sharedSecret")) {
+ identityProofSharedSecret = val;
+ } else if (name.equals("popLinkWitness.enable")) {
+ popLinkWitnessEnable = val;
+ } else if (name.equals("LraPopWitness.enable")) {
+ lraPopWitnessEnable = val;
+ } else if (name.equals("LraPopWitness.bodyPartIDs")) {
+ bodyPartIDs = val;
+ } else if (name.equals("numRequests")) {
+ numRequests = val;
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ printUsage();
+ }
+
+ if (ifilename == null) {
+ System.out.println("Missing input filename for PKCS10 or CRMF.");
+ printUsage();
+ }
+
+ int num = 0;
+ if (numRequests == null) {
+ System.out.println("Missing numRequests.");
+ printUsage();
+ } else {
+ try {
+ num = Integer.parseInt(numRequests);
+ } catch (Exception ee) {
+ System.out.println("numRequests must be integer");
+ System.exit(1);
+ }
+ }
+
+ StringTokenizer tokenizer = new StringTokenizer(ifilename, " ");
+ String[] ifiles = new String[num];
+ for (int i = 0; i < num; i++) {
+ String ss = (String) tokenizer.nextToken();
+ ifiles[i] = ss;
+ if (ss == null) {
+ System.out.println("Missing input file for the request.");
+ System.exit(1);
+ }
+ }
+
+ if (ofilename == null) {
+ System.out.println("Missing output filename for the CMC request.");
+ printUsage();
+ }
+
+ if (format == null) {
+ System.out.println("Missing format.");
+ printUsage();
+ }
+
+ if (password == null) {
+ System.out.println("Missing password.");
+ printUsage();
+ }
+
+ if (nickname == null) {
+ System.out.println("Missing nickname.");
+ printUsage();
+ }
+
+ try {
+ // initialize CryptoManager
+ if (dbdir == null)
+ dbdir = ".";
+ String mPrefix = "";
+ System.out.println("cert/key prefix = " + mPrefix);
+ System.out.println("path = " + dbdir);
+ CryptoManager.InitializationValues vals =
+ new CryptoManager.InitializationValues(dbdir, mPrefix,
+ mPrefix, "secmod.db");
+
+ CryptoManager.initialize(vals);
+ CryptoManager cm = CryptoManager.getInstance();
+ CryptoToken token = cm.getInternalKeyStorageToken();
+ Password pass = new Password(password.toCharArray());
+
+ token.login(pass);
+ X509Certificate signerCert = null;
+
+ signerCert = cm.findCertByNickname(nickname);
+
+ String[] requests = new String[num];
+ for (int i = 0; i < num; i++) {
+ BufferedReader inputBlob = null;
+ try {
+ inputBlob = new BufferedReader(new InputStreamReader(
+ new BufferedInputStream(new FileInputStream(ifiles[i]))));
+ } catch (FileNotFoundException e) {
+ System.out.println("CMCRequest: can't find file " +
+ ifiles[i] + ":\n" + e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ // (3) Read the entire contents of the specified BASE 64 encoded
+ // blob into a String() object throwing away any
+ // headers beginning with HEADER and any trailers beginning
+ // with TRAILER
+ String asciiBASE64BlobChunk = new String();
+ String asciiBASE64Blob = new String();
+
+ try {
+ while ((asciiBASE64BlobChunk = inputBlob.readLine()) != null) {
+ if (!(asciiBASE64BlobChunk.startsWith(HEADER)) &&
+ !(asciiBASE64BlobChunk.startsWith(TRAILER))) {
+ asciiBASE64Blob += asciiBASE64BlobChunk.trim();
+ }
+ }
+ requests[i] = asciiBASE64Blob;
+ } catch (IOException e) {
+ System.out.println("CMCRequest: Unexpected BASE64 " +
+ "encoded error encountered in readLine():\n" +
+ e);
+ }
+ // (4) Close the DataInputStream() object
+ try {
+ inputBlob.close();
+ } catch (IOException e) {
+ System.out.println("CMCRequest(): Unexpected BASE64 " +
+ "encoded error encountered in close():\n" + e);
+ }
+ }
+
+ SEQUENCE controlSeq = new SEQUENCE();
+ int bpid = 1;
+ if (confirmCertEnable.equalsIgnoreCase("true")) {
+ if (confirmCertIssuer.length() == 0 || confirmCertSerial.length() == 0) {
+ System.out.println("Illegal parameters for confirm certificate acceptance control");
+ printUsage();
+ System.exit(1);
+ }
+ bpid = addConfirmCertAttr(bpid, controlSeq, confirmCertIssuer, confirmCertSerial);
+ }
+
+ if (lraPopWitnessEnable.equalsIgnoreCase("true")) {
+ if (bodyPartIDs.length() == 0) {
+ System.out.println("Illegal parameters for Lra Pop Witness control");
+ printUsage();
+ System.exit(1);
+ }
+
+ bpid = addLraPopWitnessAttr(bpid, controlSeq, bodyPartIDs);
+ }
+
+ if (getCertEnable.equalsIgnoreCase("true")) {
+ if (getCertIssuer.length() == 0 || getCertSerial.length() == 0) {
+ System.out.println("Illegal parameters for get certificate control");
+ printUsage();
+ System.exit(1);
+ }
+
+ bpid = addGetCertAttr(bpid, controlSeq, getCertIssuer, getCertSerial);
+ }
+
+ if (dataReturnEnable.equalsIgnoreCase("true")) {
+ if (dataReturnData.length() == 0) {
+ System.out.println("Illegal parameters for data return control");
+ printUsage();
+ System.exit(1);
+ }
+
+ bpid = addDataReturnAttr(bpid, controlSeq, dataReturnData);
+ }
+
+ if (senderNonceEnable.equalsIgnoreCase("true"))
+ bpid = addSenderNonceAttr(bpid, controlSeq, senderNonce);
+
+ if (popLinkWitnessEnable.equalsIgnoreCase("true"))
+ bpid = addPopLinkWitnessAttr(bpid, controlSeq);
+
+ SEQUENCE otherMsgSeq = new SEQUENCE();
+ if (revRequestEnable.equalsIgnoreCase("true")) {
+ if (revRequestIssuer.length() == 0 || revRequestSerial.length() == 0 ||
+ revRequestReason.length() == 0) {
+ System.out.println("Illegal parameters for revRequest control");
+ printUsage();
+ System.exit(1);
+ }
+
+ bpid = addRevRequestAttr(bpid, controlSeq, otherMsgSeq, revCertNickname,
+ revRequestIssuer, revRequestSerial, revRequestReason, revRequestSharedSecret,
+ revRequestComment, revRequestInvalidityDatePresent, cm);
+ }
+
+ ContentInfo cmcblob = getCMCBlob(signerCert, nickname, requests, format,
+ cm, transactionMgtEnable, transactionMgtId, identityProofEnable,
+ identityProofSharedSecret, controlSeq, otherMsgSeq, bpid);
+
+ // (6) Finally, print the actual CMC blob to the
+ // specified output file
+ FileOutputStream os = null;
+ try {
+ os = new FileOutputStream(ofilename);
+ cmcblob.encode(os);
+ System.out.println("");
+ System.out.println("");
+ System.out.println("The CMC enrollment request in binary format is stored in " +
+ ofilename + ".");
+ } catch (IOException e) {
+ System.out.println("CMCRequest: unable to open file " + ofilename +
+ " for writing:\n" + e);
+ }
+
+ try {
+ os.close();
+ } catch (IOException e) {
+ System.out.println("CMCRequest: Unexpected error " +
+ "encountered while attempting to close() " +
+ "\n" + e);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/CMCResponse.java b/base/java-tools/src/com/netscape/cmstools/CMCResponse.java
new file mode 100644
index 000000000..4d68dd151
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/CMCResponse.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 com.netscape.cmstools;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+import netscape.security.util.CertPrettyPrint;
+import netscape.security.x509.X509CertImpl;
+
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.pkix.cmc.CMCStatusInfo;
+import org.mozilla.jss.pkix.cmc.OtherInfo;
+import org.mozilla.jss.pkix.cmc.PendInfo;
+import org.mozilla.jss.pkix.cmc.ResponseBody;
+import org.mozilla.jss.pkix.cmc.TaggedAttribute;
+import org.mozilla.jss.pkix.cms.EncapsulatedContentInfo;
+
+/**
+ * Tool for parsing a CMC response
+ *
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ *
+ */
+public class CMCResponse {
+
+ public CMCResponse() {
+ }
+
+ public static void printOutput(String path, String filename) {
+ byte[] bb = new byte[10000];
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(filename);
+ while (fis.available() > 0)
+ fis.read(bb, 0, 10000);
+ } catch (Exception e) {
+ System.out.println("Error reading the response. Exception: " + e.toString());
+ System.exit(1);
+ }
+
+ try {
+ ByteArrayInputStream bis = new ByteArrayInputStream(bb);
+ org.mozilla.jss.pkix.cms.ContentInfo cii = (org.mozilla.jss.pkix.cms.ContentInfo)
+ org.mozilla.jss.pkix.cms.ContentInfo.getTemplate().decode(bis);
+
+ org.mozilla.jss.pkix.cms.SignedData cmcFullResp =
+ (org.mozilla.jss.pkix.cms.SignedData) cii.getInterpretedContent();
+
+ String content = "";
+ if (cmcFullResp.hasCertificates()) {
+ SET certs = cmcFullResp.getCertificates();
+ int numCerts = certs.size();
+
+ for (int i = 0; i < numCerts; i++) {
+ Certificate cert = (Certificate) certs.elementAt(i);
+ X509CertImpl certImpl = new X509CertImpl(ASN1Util.encode(cert));
+ CertPrettyPrint print = new CertPrettyPrint(certImpl);
+ content += print.toString(Locale.getDefault());
+ }
+ }
+
+ System.out.println("Certificates: ");
+ System.out.println(content);
+ System.out.println("");
+ EncapsulatedContentInfo ci = cmcFullResp.getContentInfo();
+ OBJECT_IDENTIFIER id = ci.getContentType();
+ OBJECT_IDENTIFIER dataid = new OBJECT_IDENTIFIER("1.2.840.113549.1.7.1");
+ if (!id.equals(OBJECT_IDENTIFIER.id_cct_PKIResponse) && !id.equals(dataid)) {
+ System.out.println("Invalid CMC Response Format");
+ }
+
+ if (!ci.hasContent())
+ return;
+
+ OCTET_STRING content1 = ci.getContent();
+ ByteArrayInputStream bbis = new ByteArrayInputStream(content1.toByteArray());
+ ResponseBody responseBody = (ResponseBody) (new ResponseBody.Template()).decode(bbis);
+ SEQUENCE controlSequence = responseBody.getControlSequence();
+
+ int numControls = controlSequence.size();
+ System.out.println("Number of controls is " + numControls);
+
+ for (int i = 0; i < numControls; i++) {
+ TaggedAttribute taggedAttr = (TaggedAttribute) controlSequence.elementAt(i);
+ OBJECT_IDENTIFIER type = taggedAttr.getType();
+
+ if (type.equals(OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo)) {
+ System.out.println("Control #" + i + ": CMCStatusInfo");
+ System.out.println(" OID: " + type.toString());
+ SET sts = taggedAttr.getValues();
+ int numSts = sts.size();
+ for (int j = 0; j < numSts; j++) {
+ CMCStatusInfo cst = (CMCStatusInfo) ASN1Util.decode(CMCStatusInfo.getTemplate(),
+ ASN1Util.encode(sts.elementAt(j)));
+ SEQUENCE seq = cst.getBodyList();
+
+ String s = " BodyList: ";
+ for (int k = 0; k < seq.size(); k++) {
+ INTEGER n = (INTEGER) seq.elementAt(k);
+ s = s + n.toString() + " ";
+ }
+ System.out.println(s);
+ int st = cst.getStatus();
+ if (st != CMCStatusInfo.SUCCESS && st != CMCStatusInfo.CONFIRM_REQUIRED) {
+ String stString = cst.getStatusString();
+ if (stString != null)
+ System.out.println(" Status String: " + stString);
+ OtherInfo oi = cst.getOtherInfo();
+ OtherInfo.Type t = oi.getType();
+ if (t == OtherInfo.FAIL)
+ System.out.println(" OtherInfo type: FAIL");
+ else if (t == OtherInfo.PEND) {
+ System.out.println(" OtherInfo type: PEND");
+ PendInfo pi = oi.getPendInfo();
+ if (pi.getPendTime() != null) {
+ String datePattern = "dd/MMM/yyyy:HH:mm:ss z";
+ SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern);
+ Date d = pi.getPendTime().toDate();
+ System.out.println(" Date: " + dateFormat.format(d));
+ }
+ }
+ } else if (st == CMCStatusInfo.SUCCESS) {
+ System.out.println(" Status: SUCCESS");
+ }
+ }
+ } else if (type.equals(OBJECT_IDENTIFIER.id_cmc_transactionId)) {
+ System.out.println("Control #" + i + ": CMC Transaction Id");
+ System.out.println(" OID: " + type.toString());
+ SET transIds = taggedAttr.getValues();
+ INTEGER num = (INTEGER) (ASN1Util.decode(INTEGER.getTemplate(),
+ ASN1Util.encode(transIds.elementAt(0))));
+ System.out.println(" INTEGER: " + num);
+ } else if (type.equals(OBJECT_IDENTIFIER.id_cmc_recipientNonce)) {
+ System.out.println("Control #" + i + ": CMC Recipient Nonce");
+ System.out.println(" OID: " + type.toString());
+ SET recipientN = taggedAttr.getValues();
+ OCTET_STRING str =
+ (OCTET_STRING) (ASN1Util.decode(OCTET_STRING.getTemplate(),
+ ASN1Util.encode(recipientN.elementAt(0))));
+ byte b[] = str.toByteArray();
+ String s = " Value: ";
+ for (int m = 0; m < b.length; m++) {
+ s = s + b[m] + " ";
+ }
+ System.out.println(s);
+ } else if (type.equals(OBJECT_IDENTIFIER.id_cmc_senderNonce)) {
+ System.out.println("Control #" + i + ": CMC Sender Nonce");
+ System.out.println(" OID: " + type.toString());
+ SET senderN = taggedAttr.getValues();
+ OCTET_STRING str =
+ (OCTET_STRING) (ASN1Util.decode(OCTET_STRING.getTemplate(),
+ ASN1Util.encode(senderN.elementAt(0))));
+ byte b[] = str.toByteArray();
+ String s = " Value: ";
+ for (int m = 0; m < b.length; m++) {
+ s = s + b[m] + " ";
+ }
+ System.out.println(s);
+ } else if (type.equals(OBJECT_IDENTIFIER.id_cmc_dataReturn)) {
+ System.out.println("Control #" + i + ": CMC Data Return");
+ System.out.println(" OID: " + type.toString());
+ SET dataReturn = taggedAttr.getValues();
+ OCTET_STRING str =
+ (OCTET_STRING) (ASN1Util.decode(OCTET_STRING.getTemplate(),
+ ASN1Util.encode(dataReturn.elementAt(0))));
+ byte b[] = str.toByteArray();
+ String s = " Value: ";
+ for (int m = 0; m < b.length; m++) {
+ s = s + b[m] + " ";
+ }
+ System.out.println(s);
+ }
+ }
+ } catch (Exception e) {
+ System.out.println("Error found in the response. Exception: " + e.toString());
+ System.exit(1);
+
+ }
+ }
+
+ private static void printUsage() {
+ System.out.println("");
+ System.out.println(
+ "Usage: CMCResponse -d <pathname for cert8.db> -i <pathname for CMC response in binary format> ");
+ }
+
+ public static void main(String args[]) {
+ String filename = null, path = null;
+ if (args.length != 4) {
+ printUsage();
+ System.exit(1);
+ }
+
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].equals("-d"))
+ path = args[i + 1];
+ else if (args[i].equals("-i"))
+ filename = args[i + 1];
+ }
+
+ if (filename == null || path == null) {
+ printUsage();
+ System.exit(1);
+ }
+ printOutput(path, filename);
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/CMCRevoke.java b/base/java-tools/src/com/netscape/cmstools/CMCRevoke.java
new file mode 100644
index 000000000..f29984713
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/CMCRevoke.java
@@ -0,0 +1,426 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmstools;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Date;
+
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.NoSuchTokenException;
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.asn1.ENUMERATED;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.asn1.UTF8String;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.DigestAlgorithm;
+import org.mozilla.jss.crypto.ObjectNotFoundException;
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.pkix.cmc.PKIData;
+import org.mozilla.jss.pkix.cmc.TaggedAttribute;
+import org.mozilla.jss.pkix.cms.ContentInfo;
+import org.mozilla.jss.pkix.cms.EncapsulatedContentInfo;
+import org.mozilla.jss.pkix.cms.IssuerAndSerialNumber;
+import org.mozilla.jss.pkix.cms.SignedData;
+import org.mozilla.jss.pkix.cms.SignerIdentifier;
+import org.mozilla.jss.pkix.cms.SignerInfo;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.pkix.primitive.Name;
+import org.mozilla.jss.util.Password;
+
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * Tool for signing a CMC revocation request with an agent's certificate.
+ *
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMCRevoke {
+ public static final int ARGC = 7;
+ private static final String CERTDB = "cert8.db";
+ private static final String KEYDB = "key3.db";
+ public static final String HEADER = "-----BEGIN NEW CERTIFICATE REQUEST-----";
+ public static final String TRAILER = "-----END NEW CERTIFICATE REQUEST-----";
+ static String dValue = null, nValue = null, iValue = null, sValue = null, mValue = null, hValue = null,
+ cValue = null;
+
+ public static final String CMS_BASE_CA_SIGNINGCERT_NOT_FOUND = "CA signing certificate not found";
+ public static final String PR_INTERNAL_TOKEN_NAME = "internal";
+ public static final String PR_REQUEST_CMC = "CMC";
+
+ static String cleanArgs(String s) {
+ if (s.startsWith("\"") && s.endsWith("\""))
+ return s.substring(1, s.length() - 2);
+ else if (s.startsWith("\'") && s.endsWith("\'"))
+ return new String(s.substring(1, s.length() - 2));
+ else
+ return s;
+ }
+
+ /**
+ * Creates a new instance of CMCRevoke.
+ */
+ public static void main(String[] s) {
+
+ // default path is "."
+ String mPath = ".";
+ // default prefix is ""
+ String mPrefix = "";
+
+ boolean bWrongParam = false;
+
+ // (1) Check that two arguments were submitted to the program
+ if (s.length != (ARGC) && s.length != (ARGC - 1)) {
+
+ bWrongParam = true;
+ System.out.println("Wrong number of parameters:" + s.length);
+ System.out.println("Usage: CMCRevoke " +
+ "-d<dir to cert8.db, key3.db> " +
+ "-n<nickname> " +
+ "-i<issuerName> " +
+ "-s<serialName> " +
+ "-m<reason to revoke> " +
+ "-h<password to db> " +
+ "-c<comment> ");
+ for (int i = 0; i < s.length; i++) {
+ System.out.println(i + ":" + s[i]);
+ }
+ } else {
+ int length;
+ int i;
+
+ length = s.length;
+ for (i = 0; i < length; i++) {
+ if (s[i].startsWith("-d")) {
+ dValue = cleanArgs(s[i].substring(2));
+ } else if (s[i].startsWith("-n")) {
+ nValue = cleanArgs(s[i].substring(2));
+ } else if (s[i].startsWith("-i")) {
+ iValue = cleanArgs(s[i].substring(2));
+ } else if (s[i].startsWith("-s")) {
+ sValue = cleanArgs(s[i].substring(2));
+ } else if (s[i].startsWith("-m")) {
+ mValue = cleanArgs(s[i].substring(2));
+ } else if (s[i].startsWith("-h")) {
+ hValue = cleanArgs(s[i].substring(2));
+ } else if (s[i].startsWith("-c")) {
+ cValue = cleanArgs(s[i].substring(2));
+ }
+
+ }
+ // optional parameter
+ if (cValue == null)
+ cValue = new String();
+ if (dValue == null
+ || nValue == null || iValue == null || sValue == null || mValue == null || hValue == null)
+ bWrongParam = true;
+ else if (dValue.length() == 0 || nValue.length() == 0 || iValue.length() == 0 ||
+ sValue.length() == 0 || mValue.length() == 0 || hValue.length() == 0)
+ bWrongParam = true;
+
+ if (bWrongParam == true) {
+ System.out.println("Usage: CMCRevoke " +
+ "-d<dir to cert8.db, key3.db> " +
+ "-n<nickname> " +
+ "-i<issuerName> " +
+ "-s<serialName> " +
+ "-m<reason to revoke> " +
+ "-h<password to db> " +
+ "-c<comment> ");
+ for (i = 0; i < s.length; i++) {
+ System.out.println(i + ":" + s[i]);
+ }
+ System.exit(0);
+ }
+
+ try {
+ // initialize CryptoManager
+ mPath = dValue;
+ System.out.println("cert/key prefix = " + mPrefix);
+ System.out.println("path = " + mPath);
+ CryptoManager.InitializationValues vals =
+ new CryptoManager.InitializationValues(mPath, mPrefix, mPrefix, "secmod.db");
+
+ CryptoManager.initialize(vals);
+
+ CryptoManager cm = CryptoManager.getInstance();
+ CryptoToken token = cm.getInternalKeyStorageToken();
+ Password pass = new Password(hValue.toCharArray());
+
+ token.login(pass);
+ X509Certificate signerCert = null;
+
+ signerCert = cm.findCertByNickname(nValue);
+ String outBlob = createRevokeReq(signerCert, cm, nValue);
+
+ printCMCRevokeRequest(outBlob);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ return;
+ }
+ }
+
+ /**
+ * printout CMC revoke request in Base64 encoding to a file CMCRevoke.out
+ * <P>
+ *
+ * @param asciiBASE64Blob the ascii string of the request
+ */
+ static void printCMCRevokeRequest(String asciiBASE64Blob) {
+
+ // (6) Finally, print the actual CMCSigning blob to the
+ // specified output file
+ FileOutputStream outputBlob = null;
+
+ try {
+ outputBlob = new FileOutputStream("CMCRevoke.out");
+ } catch (IOException e) {
+ System.out.println("CMCSigning: unable to open file CMCRevoke.out for writing:\n" + e);
+ return;
+ }
+
+ System.out.println(HEADER);
+ System.out.println(asciiBASE64Blob + TRAILER);
+ try {
+ asciiBASE64Blob = HEADER + "\n" + asciiBASE64Blob + TRAILER;
+ outputBlob.write(asciiBASE64Blob.getBytes());
+ } catch (IOException e) {
+ System.out.println("CMCSigning: I/O error " +
+ "encountered during write():\n" +
+ e);
+ }
+
+ try {
+ outputBlob.close();
+ } catch (IOException e) {
+ System.out.println("CMCSigning: Unexpected error " +
+ "encountered while attempting to close() " +
+ "\n" + e);
+ }
+ }
+
+ /**
+ * getCertificate find the certicate inside the token by its nickname.
+ * <P>
+ *
+ * @param manager the CrytoManager
+ * @param tokenname the name of the token. it's set to "internal".
+ * @param nickname the nickname of the certificate inside the token.
+ * @return the X509Certificate.
+ */
+ public static X509Certificate getCertificate(CryptoManager manager, String tokenname,
+ String nickname) throws NoSuchTokenException,
+ Exception, TokenException {
+ CryptoToken token = null;
+
+ if (tokenname.equals(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 Exception(CMS_BASE_CA_SIGNINGCERT_NOT_FOUND);
+ }
+ }
+
+ /**
+ * createRevokeReq create and return the revocation request.
+ * <P>
+ *
+ * @param signerCert the certificate of the authorized signer of the CMC revocation request.
+ * @param manager the crypto manger.
+ * @param nValue the nickname of the certificate inside the token.
+ * @return the CMC revocation request encoded in base64
+ */
+ static String createRevokeReq(X509Certificate signerCert, CryptoManager manager, String nValue) {
+
+ java.security.PrivateKey privKey = null;
+ SignerIdentifier si = null;
+ ContentInfo fullEnrollmentReq = null;
+ String tokenname = "internal";
+ String asciiBASE64Blob = new String();
+
+ try {
+
+ BigInteger serialno = signerCert.getSerialNumber();
+ byte[] certB = signerCert.getEncoded();
+ X509CertImpl impl = new X509CertImpl(certB);
+ X500Name issuerName = (X500Name) impl.getIssuerDN();
+ byte[] issuerByte = issuerName.getEncoded();
+ ByteArrayInputStream istream = new ByteArrayInputStream(issuerByte);
+
+ Name issuer = (Name) Name.getTemplate().decode(istream);
+ IssuerAndSerialNumber ias = new IssuerAndSerialNumber(issuer, new INTEGER(serialno.toString()));
+
+ si = new SignerIdentifier(SignerIdentifier.ISSUER_AND_SERIALNUMBER, ias, null);
+ X509Certificate cert = getCertificate(manager, tokenname, nValue);
+
+ privKey = manager.findPrivKeyByCert(cert);
+
+ if (privKey == null) {
+ System.out.println("CMCRevoke::createRevokeReq() - " +
+ "privKey is null!");
+ return "";
+ }
+
+ int bpid = 1;
+ // Add some control sequence
+ // Verisign has transactionID,senderNonce
+ SEQUENCE controlSeq = new SEQUENCE();
+
+ 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 sn = Utils.base64encode(dig);
+
+ TaggedAttribute senderNonce =
+ new TaggedAttribute(new INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_senderNonce,
+ new OCTET_STRING(sn.getBytes()));
+
+ controlSeq.addElement(senderNonce);
+
+ Name subjectName = new Name();
+
+ subjectName.addCommonName(iValue);
+ org.mozilla.jss.pkix.cmmf.RevRequest lRevokeRequest =
+ new org.mozilla.jss.pkix.cmmf.RevRequest(new ANY((new X500Name(iValue)).getEncoded()),
+ new INTEGER(sValue),
+ //org.mozilla.jss.pkix.cmmf.RevRequest.unspecified,
+ new ENUMERATED((new Integer(mValue)).longValue()),
+ //new GeneralizedTime(new Date(lValue)),
+ new OCTET_STRING(hValue.getBytes()),
+ new UTF8String(cValue.toCharArray()));
+ //byte[] encoded = ASN1Util.encode(lRevokeRequest);
+ //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)
+ // template.decode(new java.io.ByteArrayInputStream(
+ // encoded));
+
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ //lRevokeRequest.encode(os); // khai
+ TaggedAttribute revokeRequestTag =
+ new TaggedAttribute(new INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_revokeRequest,
+ lRevokeRequest);
+
+ controlSeq.addElement(revokeRequestTag);
+ PKIData pkidata = new PKIData(controlSeq, new SEQUENCE(), new SEQUENCE(), new SEQUENCE());
+
+ EncapsulatedContentInfo ci = new EncapsulatedContentInfo(OBJECT_IDENTIFIER.id_cct_PKIData, pkidata);
+ // SHA1 is the default digest Alg for now.
+ DigestAlgorithm digestAlg = null;
+ SignatureAlgorithm signAlg = SignatureAlgorithm.RSASignatureWithSHA1Digest;
+ org.mozilla.jss.crypto.PrivateKey.Type signingKeyType =
+ ((org.mozilla.jss.crypto.PrivateKey) privKey).getType();
+
+ if (signingKeyType.equals(org.mozilla.jss.crypto.PrivateKey.Type.DSA))
+ signAlg = SignatureAlgorithm.DSASignatureWithSHA1Digest;
+ MessageDigest SHADigest = null;
+ byte[] digest = null;
+
+ try {
+ SHADigest = MessageDigest.getInstance("SHA1");
+ digestAlg = DigestAlgorithm.SHA1;
+
+ ByteArrayOutputStream ostream = new ByteArrayOutputStream();
+
+ pkidata.encode((OutputStream) ostream);
+ digest = SHADigest.digest(ostream.toByteArray());
+ } catch (NoSuchAlgorithmException e) {
+ }
+ SignerInfo signInfo = new SignerInfo(si, null, null, OBJECT_IDENTIFIER.id_cct_PKIData, digest, signAlg,
+ (org.mozilla.jss.crypto.PrivateKey) 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);
+ }
+
+ org.mozilla.jss.crypto.X509Certificate[] agentChain = manager.buildCertificateChain(signerCert);
+ SET certs = new SET();
+
+ for (int i = 0; i < agentChain.length; i++) {
+ ANY certificate = new ANY(agentChain[i].getEncoded());
+
+ certs.addElement(certificate);
+ }
+ SignedData req = new SignedData(digestAlgs, ci, certs, null, signInfos);
+
+ fullEnrollmentReq = new ContentInfo(req);
+
+ ByteArrayOutputStream bs = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(bs);
+
+ if (fullEnrollmentReq != null) {
+ // format is PR_REQUEST_CMC
+ fullEnrollmentReq.encode(os);
+ ps.print(Utils.base64encode(os.toByteArray()));
+ ////fullEnrollmentReq.print(ps); // no header/trailer
+ }
+
+ asciiBASE64Blob = bs.toString();
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ return asciiBASE64Blob;
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
new file mode 100644
index 000000000..c1d463cdb
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
@@ -0,0 +1,620 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmstools;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.security.KeyPair;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import netscape.security.x509.X500Name;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.BIT_STRING;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.PrintableString;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.IVParameterSpec;
+import org.mozilla.jss.crypto.KeyGenAlgorithm;
+import org.mozilla.jss.crypto.KeyGenerator;
+import org.mozilla.jss.crypto.KeyPairAlgorithm;
+import org.mozilla.jss.crypto.KeyPairGenerator;
+import org.mozilla.jss.crypto.KeyWrapAlgorithm;
+import org.mozilla.jss.crypto.KeyWrapper;
+import org.mozilla.jss.crypto.Signature;
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+import org.mozilla.jss.crypto.SymmetricKey;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.crmf.CertTemplate;
+import org.mozilla.jss.pkix.crmf.EncryptedKey;
+import org.mozilla.jss.pkix.crmf.EncryptedValue;
+import org.mozilla.jss.pkix.crmf.PKIArchiveOptions;
+import org.mozilla.jss.pkix.crmf.POPOSigningKey;
+import org.mozilla.jss.pkix.crmf.ProofOfPossession;
+import org.mozilla.jss.pkix.primitive.AVA;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.pkix.primitive.Name;
+import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
+import org.mozilla.jss.util.Password;
+
+import com.netscape.cmsutil.util.HMACDigest;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * A command-line utility used to generate a Certificate Request Message
+ * Format (CRMF) request with proof of possesion (POP).
+ *
+ * Usage:
+ *
+ * <pre>
+ * CRMFPopClient TOKEN_PWD
+ * PROFILE_NAME HOST PORT USER_NAME REQUESTOR_NAME
+ * POP_OPTION
+ * SUBJECT_DN [OUTPUT_CERT_REQ]
+ *
+ * --- or ---
+ *
+ * CRMFPopClient TOKEN_PWD
+ * POP_OPTION
+ * OUTPUT_CERT_REQ SUBJECT_DN
+ *
+ *
+ * where POP_OPTION can be [POP_SUCCESS or POP_FAIL or POP_NONE]
+ * </pre>
+ * <p>
+ * Examples:
+ *
+ * <pre>
+ * CRMFPopClient password123
+ * caEncUserCert host.example.com 1026 MyUid MyUid
+ * [POP_SUCCESS or POP_FAIL or POP_NONE]
+ * CN=MyTest,C=US,UID=MyUid
+ *
+ * --- or ---
+ *
+ * CRMFPopClient password123
+ * caEncUserCert host.example.com 1026 joe joe
+ * [POP_SUCCESS or POP_FAIL or POP_NONE]
+ * CN=MyTest,C=US,UID=MyUid OUTPUT_CERT_REQ
+ *
+ * --- or ---
+ *
+ * CRMFPopClient password123
+ * [POP_SUCCESS or POP_FAIL or POP_NONE]
+ * OUTPUT_CERT_REQ CN=MyTest,C=US,UID=MyUid
+ * </pre>
+ * <p>
+ *
+ * <pre>
+ * IMPORTANT: The file "transport.txt" needs to be created to contain the
+ * transport certificate in its base64 encoded format. This
+ * file should consist of one line containing a single certificate
+ * in base64 encoded format with the header and footer removed.
+ * </pre>
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public class CRMFPopClient {
+
+ private static void usage() {
+ System.out.println("");
+ System.out.println("Description: A command-line utility used to generate a");
+ System.out.println(" Certificate Request Message Format (CRMF)");
+ System.out.println(" request with proof of possesion (POP).\n\n");
+ System.out.println("Usage:");
+ System.out.println("");
+ System.out.println(" CRMFPopClient TOKEN_PWD");
+ System.out.println(" PROFILE_NAME HOST PORT USER_NAME REQUESTOR_NAME");
+ System.out.println(" POP_OPTION");
+ System.out.println(" SUBJECT_DN [OUTPUT_CERT_REQ] \n");
+ System.out.println(" --- or ---\n");
+ System.out.println(" CRMFPopClient TOKEN_PWD");
+ System.out.println(" POP_OPTION");
+ System.out.println(" OUTPUT_CERT_REQ SUBJECT_DN\n\n");
+ System.out.println(" where POP_OPTION can be [POP_SUCCESS or POP_FAIL or POP_NONE]\n\n");
+ System.out.println("Examples:");
+ System.out.println("");
+ System.out.println(" CRMFPopClient password123");
+ System.out.println(" caEncUserCert host.example.com 1026 MyUid MyUid");
+ System.out.println(" [POP_SUCCESS or POP_FAIL or POP_NONE]");
+ System.out.println(" CN=MyTest,C=US,UID=MyUid\n");
+ System.out.println(" --- or ---\n");
+ System.out.println(" CRMFPopClient password123");
+ System.out.println(" caEncUserCert host.example.com 1026 MyUid myUid");
+ System.out.println(" [POP_SUCCESS or POP_FAIL or POP_NONE]");
+ System.out.println(" CN=MyTest,C=US,UID=MyUid OUTPUT_CERT_REQ\n");
+ System.out.println(" --- or ---\n");
+ System.out.println(" CRMFPopClient password123");
+ System.out.println(" [POP_SUCCESS or POP_FAIL or POP_NONE]");
+ System.out.println(" OUTPUT_CERT_REQ CN=MyTest,C=US,UID=MyUid");
+ System.out.println("\n");
+ System.out.println("IMPORTANT: The file \"transport.txt\" needs to be created to contain the");
+ System.out.println(" transport certificate in its base64 encoded format. This");
+ System.out.println(" file should consist of one line containing a single certificate");
+ System.out.println(" in base64 encoded format with the header and footer removed.\n");
+ }
+
+ private static int getRealArgsLength(String args[]) {
+
+ int len = args.length;
+
+ String curArg = "";
+ int finalLen = len;
+
+ for (int i = 0; i < len; i++) {
+
+ curArg = args[i];
+ // System.out.println("arg[" + i + "] " + curArg);
+
+ if (curArg == null || curArg.equalsIgnoreCase("")) {
+ finalLen--;
+ }
+
+ }
+
+ //System.out.println("getRealArgsLength: returning " + finalLen);
+
+ if (finalLen < 0)
+ finalLen = 0;
+
+ return finalLen;
+
+ }
+
+ public static void main(String args[]) {
+
+ int argsLen = getRealArgsLength(args);
+
+ // System.out.println("args length " + argsLen);
+
+ System.out.println("\n\nProof Of Possession Utility....");
+ System.out.println("");
+
+ if (argsLen == 0 || (argsLen != 8 && argsLen != 9 && argsLen != 10 && argsLen != 4)) {
+ usage();
+ return;
+ }
+
+ String DB_DIR = "./";
+ String TOKEN_PWD = args[0];
+ int KEY_LEN = 1024;
+
+ int PORT = 0;
+ String USER_NAME = null;
+ String REQUESTOR_NAME = null;
+ String PROFILE_NAME = null;
+
+ String HOST = null;
+ String SUBJ_DN = null;
+
+ if (argsLen >= 8) {
+ PROFILE_NAME = args[1];
+ HOST = args[2];
+
+ PORT = Integer.parseInt(args[3]);
+
+ USER_NAME = args[4];
+ REQUESTOR_NAME = args[5];
+
+ SUBJ_DN = args[7];
+
+ }
+
+ String POP_OPTION = null;
+ String OUTPUT_CERT_REQ = null;
+
+ if (argsLen == 4)
+ POP_OPTION = args[1];
+ else
+ POP_OPTION = args[6];
+
+ int doServerHit = 1;
+
+ if (argsLen >= 9) {
+ OUTPUT_CERT_REQ = args[8];
+ }
+
+ if (argsLen == 4) {
+ doServerHit = 0;
+ OUTPUT_CERT_REQ = args[2];
+ SUBJ_DN = args[3];
+ }
+
+ int dont_do_pop = 0;
+
+ if (POP_OPTION.equals("POP_NONE")) {
+ dont_do_pop = 1;
+ }
+
+ URL url = null;
+ URLConnection conn = null;
+ InputStream is = null;
+ BufferedReader reader = null;
+ KeyPair pair = null;
+
+ boolean foundTransport = false;
+ String transportCert = null;
+ try {
+ BufferedReader br = new BufferedReader(new FileReader("./transport.txt"));
+ transportCert = br.readLine();
+ foundTransport = true;
+ } catch (Exception e) {
+ System.out.println("ERROR: cannot find ./transport.txt, so no key archival");
+
+ return;
+ }
+
+ try {
+ CryptoManager.initialize(DB_DIR);
+ } catch (Exception e) {
+ // it is ok if it is already initialized
+ System.out.println("INITIALIZATION ERROR: " + e.toString());
+ // return;
+ }
+
+ try {
+ CryptoManager manager = CryptoManager.getInstance();
+ String token_pwd = TOKEN_PWD;
+ CryptoToken token = manager.getInternalKeyStorageToken();
+ Password password = new Password(token_pwd.toCharArray());
+ try {
+ token.login(password);
+ } catch (Exception e) {
+ //System.out.println("login Exception: " + e.toString());
+ if (!token.isLoggedIn()) {
+ token.initPassword(password, password);
+ }
+ }
+
+ System.out.println("."); //"done with cryptomanager");
+
+ KeyPairGenerator kg = token.getKeyPairGenerator(
+ KeyPairAlgorithm.RSA);
+ kg.initialize(KEY_LEN);
+
+ String profileName = PROFILE_NAME;
+ pair = kg.genKeyPair();
+
+ System.out.println("."); //key pair generated");
+
+ // wrap private key
+ byte transport[] = Utils.base64decode(transportCert);
+
+ X509Certificate tcert = manager.importCACertPackage(transport);
+
+ byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
+
+ KeyGenerator kg1 = token.getKeyGenerator(KeyGenAlgorithm.DES3);
+ SymmetricKey sk = kg1.generate();
+
+ System.out.println("."); //before KeyWrapper");
+
+ // wrap private key using session
+ KeyWrapper wrapper1 =
+ token.getKeyWrapper(KeyWrapAlgorithm.DES3_CBC_PAD);
+
+ System.out.println("."); //key wrapper created");
+
+ wrapper1.initWrap(sk, new IVParameterSpec(iv));
+
+ System.out.println("."); //key wrapper inited");
+ byte key_data[] = wrapper1.wrap((org.mozilla.jss.crypto.PrivateKey) pair.getPrivate());
+
+ System.out.println("."); //key wrapper wrapped");
+
+ // wrap session using transport
+ KeyWrapper rsaWrap = token.getKeyWrapper(
+ KeyWrapAlgorithm.RSA);
+
+ System.out.println("."); //got rsaWrapper");
+
+ rsaWrap.initWrap(tcert.getPublicKey(), null);
+
+ System.out.println("."); //rsaWrap inited");
+
+ byte session_data[] = rsaWrap.wrap(sk);
+
+ System.out.println("."); //rsaWrapped");
+
+ try {
+ // create CRMF
+ CertTemplate certTemplate = new CertTemplate();
+ certTemplate.setVersion(new INTEGER(2));
+
+ Name n1 = getJssName(SUBJ_DN);
+
+ Name n = new Name();
+
+ n.addCommonName("Me");
+ n.addCountryName("US");
+ n.addElement(new AVA(new OBJECT_IDENTIFIER("0.9.2342.19200300.100.1.1"), new PrintableString("MyUid")));
+
+ if (n1 != null)
+ certTemplate.setSubject(n1);
+ else
+ certTemplate.setSubject(n);
+
+ certTemplate.setPublicKey(new SubjectPublicKeyInfo(pair.getPublic()));
+ // set extension
+ AlgorithmIdentifier algS =
+ new AlgorithmIdentifier(new OBJECT_IDENTIFIER("1.2.840.113549.3.7"), new OCTET_STRING(iv));
+ EncryptedValue encValue =
+ new EncryptedValue(null, algS, new BIT_STRING(session_data, 0), null, null, new BIT_STRING(
+ key_data, 0));
+ EncryptedKey key = new EncryptedKey(encValue);
+ PKIArchiveOptions opt = new PKIArchiveOptions(key);
+ SEQUENCE seq = new SEQUENCE();
+ if (foundTransport) {
+ seq.addElement(new AVA(new OBJECT_IDENTIFIER("1.3.6.1.5.5.7.5.1.4"), opt));
+ }
+
+ // Add idPOPLinkWitness control
+ String secretValue = "testing";
+ byte[] key1 = null;
+ byte[] finalDigest = null;
+ try {
+ MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1");
+ key1 = SHA1Digest.digest(secretValue.getBytes());
+ } catch (NoSuchAlgorithmException ex) {
+ }
+
+ /* Example of adding the POP link witness control to CRMF */
+ byte[] b =
+ { 0x10, 0x53, 0x42, 0x24, 0x1a, 0x2a, 0x35, 0x3c,
+ 0x7a, 0x52, 0x54, 0x56, 0x71, 0x65, 0x66, 0x4c,
+ 0x51, 0x34, 0x35, 0x23, 0x3c, 0x42, 0x43, 0x45,
+ 0x61, 0x4f, 0x6e, 0x43, 0x1e, 0x2a, 0x2b, 0x31,
+ 0x32, 0x34, 0x35, 0x36, 0x55, 0x51, 0x48, 0x14,
+ 0x16, 0x29, 0x41, 0x42, 0x43, 0x7b, 0x63, 0x44,
+ 0x6a, 0x12, 0x6b, 0x3c, 0x4c, 0x3f, 0x00, 0x14,
+ 0x51, 0x61, 0x15, 0x22, 0x23, 0x5f, 0x5e, 0x69 };
+
+ try {
+ MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1");
+ HMACDigest hmacDigest = new HMACDigest(SHA1Digest, key1);
+ hmacDigest.update(b);
+ finalDigest = hmacDigest.digest();
+ } catch (NoSuchAlgorithmException ex) {
+ }
+
+ OCTET_STRING ostr = new OCTET_STRING(finalDigest);
+ seq.addElement(new AVA(OBJECT_IDENTIFIER.id_cmc_idPOPLinkWitness, ostr));
+ CertRequest certReq = new CertRequest(new INTEGER(1), certTemplate, seq);
+
+ System.out.println("."); //CertRequest created");
+
+ ByteArrayOutputStream bo = new ByteArrayOutputStream();
+ certReq.encode(bo);
+ byte[] toBeVerified = bo.toByteArray();
+
+ byte signature[];
+
+ System.out.println("."); //CertRequest encoded");
+
+ Signature signer = token.getSignatureContext(
+ SignatureAlgorithm.RSASignatureWithMD5Digest);
+
+ System.out.println("."); //signer created");
+
+ signer.initSign((org.mozilla.jss.crypto.PrivateKey) pair.getPrivate());
+
+ System.out.println("."); //signer inited");
+
+ System.out.println("."); //FAIL_OR_SUCC " + FAIL_OR_SUCC);
+
+ if (POP_OPTION.equals("POP_SUCCESS")) {
+ System.out.println("Generating Legal POP Data.....");
+ signer.update(toBeVerified);
+ } else if (POP_OPTION.equals("POP_FAIL")) {
+ System.out.println("Generating Illegal POP Data.....");
+ signer.update(iv);
+ } else if (dont_do_pop == 1) {
+ System.out.println("Generating NO POP Data.....");
+ }
+
+ System.out.println("."); //signer updated");
+
+ CertReqMsg crmfMsg = null;
+
+ if (dont_do_pop == 0) {
+ signature = signer.sign();
+
+ System.out.println("Signature completed...");
+ System.out.println("");
+
+ AlgorithmIdentifier algID =
+ new AlgorithmIdentifier(SignatureAlgorithm.RSASignatureWithMD5Digest.toOID(), null);
+ POPOSigningKey popoKey = new POPOSigningKey(null, algID, new BIT_STRING(signature, 0));
+
+ ProofOfPossession pop = ProofOfPossession.createSignature(popoKey);
+
+ crmfMsg = new CertReqMsg(certReq, pop, null);
+
+ } else {
+ crmfMsg = new CertReqMsg(certReq, null, null);
+
+ }
+
+ //crmfMsg.verify();
+
+ SEQUENCE s1 = new SEQUENCE();
+ s1.addElement(crmfMsg);
+ byte encoded[] = ASN1Util.encode(s1);
+
+ String Req1 = Utils.base64encode(encoded);
+
+ if (OUTPUT_CERT_REQ != null) {
+ System.out.println("Generated Cert Request: ...... ");
+ System.out.println("");
+
+ System.out.println(Req1);
+ System.out.println("");
+ System.out.println("End Request:");
+
+ if (doServerHit == 0)
+ return;
+ }
+
+ String Req = URLEncoder.encode(Req1, "UTF-8");
+
+ // post PKCS10
+
+ url =
+ new URL("http://"
+ + HOST + ":" + PORT + "/ca/ee/ca/profileSubmit?cert_request_type=crmf&cert_request="
+ + Req + "&renewal=false&uid=" + USER_NAME + "&xmlOutput=false&&profileId="
+ + profileName + "&sn_uid=" + USER_NAME + "&SubId=profile&requestor_name="
+ + REQUESTOR_NAME);
+ //System.out.println("Posting " + url);
+
+ System.out.println("");
+ System.out.println("Server Response.....");
+ System.out.println("--------------------");
+ System.out.println("");
+
+ conn = url.openConnection();
+ is = conn.getInputStream();
+ reader = new BufferedReader(new InputStreamReader(is));
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ System.out.println(line);
+ if (line.equals("CMS Enroll Request Success")) {
+ System.out.println("Enrollment Successful: ......");
+ System.out.println("");
+ }
+ } /* while */
+
+ } catch (Exception e) {
+ System.out.println("WARNING: " + e.toString());
+ e.printStackTrace();
+ }
+ } catch (Exception e) {
+ System.out.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+
+ static Name getJssName(String dn) {
+
+ X500Name x5Name = null;
+
+ try {
+ x5Name = new X500Name(dn);
+
+ } catch (IOException e) {
+
+ System.out.println("Illegal Subject Name: " + dn + " Error: " + e.toString());
+ System.out.println("Filling in default Subject Name......");
+ return null;
+ }
+
+ Name ret = new Name();
+
+ netscape.security.x509.RDN[] names = null;
+
+ names = x5Name.getNames();
+
+ int nameLen = x5Name.getNamesLength();
+
+ // System.out.println("x5Name len: " + nameLen);
+
+ netscape.security.x509.RDN cur = null;
+
+ for (int i = 0; i < nameLen; i++) {
+ cur = names[i];
+
+ String rdnStr = cur.toString();
+
+ String[] split = rdnStr.split("=");
+
+ if (split.length != 2)
+ continue;
+
+ try {
+
+ if (split[0].equals("UID")) {
+
+ ret.addElement(new AVA(new OBJECT_IDENTIFIER("0.9.2342.19200300.100.1.1"), new PrintableString(
+ split[1])));
+ // System.out.println("UID found : " + split[1]);
+
+ }
+
+ if (split[0].equals("C")) {
+ ret.addCountryName(split[1]);
+ // System.out.println("C found : " + split[1]);
+ continue;
+
+ }
+
+ if (split[0].equals("CN")) {
+ ret.addCommonName(split[1]);
+ // System.out.println("CN found : " + split[1]);
+ continue;
+ }
+
+ if (split[0].equals("L")) {
+ ret.addLocalityName(split[1]);
+ // System.out.println("L found : " + split[1]);
+ continue;
+ }
+
+ if (split[0].equals("O")) {
+ ret.addOrganizationName(split[1]);
+ // System.out.println("O found : " + split[1]);
+ continue;
+ }
+
+ if (split[0].equals("ST")) {
+ ret.addStateOrProvinceName(split[1]);
+ // System.out.println("ST found : " + split[1]);
+ continue;
+ }
+
+ if (split[0].equals("OU")) {
+ ret.addOrganizationalUnitName(split[1]);
+ // System.out.println("OU found : " + split[1]);
+ continue;
+ }
+ } catch (Exception e) {
+ System.out.println("Error constructing RDN: " + rdnStr + " Error: " + e.toString());
+
+ continue;
+ }
+
+ }
+
+ return ret;
+
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/DRMTool.cfg b/base/java-tools/src/com/netscape/cmstools/DRMTool.cfg
new file mode 100644
index 000000000..b43441e19
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/DRMTool.cfg
@@ -0,0 +1,160 @@
+drmtool.ldif.caEnrollmentRequest._000=########################################
+drmtool.ldif.caEnrollmentRequest._001=## DRM CA Enrollment Request ##
+drmtool.ldif.caEnrollmentRequest._002=########################################
+drmtool.ldif.caEnrollmentRequest._003=## ##
+drmtool.ldif.caEnrollmentRequest._004=## NEVER allow 'DRMTOOL' the ability ##
+drmtool.ldif.caEnrollmentRequest._005=## to change the CA 'naming context' ##
+drmtool.ldif.caEnrollmentRequest._006=## data in the following fields: ##
+drmtool.ldif.caEnrollmentRequest._007=## ##
+drmtool.ldif.caEnrollmentRequest._008=## extdata-auth--005ftoken;uid ##
+drmtool.ldif.caEnrollmentRequest._009=## extdata-auth--005ftoken;userid ##
+drmtool.ldif.caEnrollmentRequest._010=## extdata-updatedby ##
+drmtool.ldif.caEnrollmentRequest._011=## ##
+drmtool.ldif.caEnrollmentRequest._012=## NEVER allow 'DRMTOOL' the ability ##
+drmtool.ldif.caEnrollmentRequest._013=## to change CA 'numeric' data in ##
+drmtool.ldif.caEnrollmentRequest._014=## the following fields: ##
+drmtool.ldif.caEnrollmentRequest._015=## ##
+drmtool.ldif.caEnrollmentRequest._016=## extdata-requestId ##
+drmtool.ldif.caEnrollmentRequest._017=## ##
+drmtool.ldif.caEnrollmentRequest._018=########################################
+drmtool.ldif.caEnrollmentRequest.cn=true
+drmtool.ldif.caEnrollmentRequest.dateOfModify=true
+drmtool.ldif.caEnrollmentRequest.dn=true
+drmtool.ldif.caEnrollmentRequest.extdata.keyRecord=true
+drmtool.ldif.caEnrollmentRequest.extdata.requestNotes=true
+drmtool.ldif.caEnrollmentRequest.requestId=true
+drmtool.ldif.caKeyRecord._000=#########################################
+drmtool.ldif.caKeyRecord._001=## DRM CA Key Record ##
+drmtool.ldif.caKeyRecord._002=#########################################
+drmtool.ldif.caKeyRecord._003=## ##
+drmtool.ldif.caKeyRecord._004=## NEVER allow 'DRMTOOL' the ability ##
+drmtool.ldif.caKeyRecord._005=## to change the CA 'naming context' ##
+drmtool.ldif.caKeyRecord._006=## data in the following fields: ##
+drmtool.ldif.caKeyRecord._007=## ##
+drmtool.ldif.caKeyRecord._008=## archivedBy ##
+drmtool.ldif.caKeyRecord._009=## ##
+drmtool.ldif.caKeyRecord._010=#########################################
+drmtool.ldif.caKeyRecord.cn=true
+drmtool.ldif.caKeyRecord.dateOfModify=true
+drmtool.ldif.caKeyRecord.dn=true
+drmtool.ldif.caKeyRecord.privateKeyData=true
+drmtool.ldif.caKeyRecord.serialno=true
+drmtool.ldif.namingContext._000=############################################
+drmtool.ldif.namingContext._001=## DRM Naming Context Fields ##
+drmtool.ldif.namingContext._002=############################################
+drmtool.ldif.namingContext._003=## ##
+drmtool.ldif.namingContext._004=## NEVER allow 'DRMTOOL' the ability to ##
+drmtool.ldif.namingContext._005=## change the CA 'naming context' data ##
+drmtool.ldif.namingContext._006=## in the following 'non-KeyRecord / ##
+drmtool.ldif.namingContext._007=## non-Request' fields (as these records ##
+drmtool.ldif.namingContext._008=## should be removed via the option to ##
+drmtool.ldif.namingContext._009=## process requests and key records only ##
+drmtool.ldif.namingContext._010=## if this is a DRM migration): ##
+drmtool.ldif.namingContext._011=## ##
+drmtool.ldif.namingContext._012=## cn ##
+drmtool.ldif.namingContext._013=## sn ##
+drmtool.ldif.namingContext._014=## uid ##
+drmtool.ldif.namingContext._015=## uniqueMember ##
+drmtool.ldif.namingContext._016=## ##
+drmtool.ldif.namingContext._017=## NEVER allow 'DRMTOOL' the ability to ##
+drmtool.ldif.namingContext._018=## change the DRM 'naming context' data ##
+drmtool.ldif.namingContext._019=## in the following 'non-KeyRecord / ##
+drmtool.ldif.namingContext._020=## non-Request' fields (as these records ##
+drmtool.ldif.namingContext._021=## should be removed via the option to ##
+drmtool.ldif.namingContext._022=## process requests and key records only ##
+drmtool.ldif.namingContext._023=## if this is a DRM migration): ##
+drmtool.ldif.namingContext._024=## ##
+drmtool.ldif.namingContext._025=## dc ##
+drmtool.ldif.namingContext._026=## dn ##
+drmtool.ldif.namingContext._027=## uniqueMember ##
+drmtool.ldif.namingContext._028=## ##
+drmtool.ldif.namingContext._029=## NEVER allow 'DRMTOOL' the ability to ##
+drmtool.ldif.namingContext._030=## change the TPS 'naming context' data ##
+drmtool.ldif.namingContext._031=## in the following 'non-KeyRecord / ##
+drmtool.ldif.namingContext._032=## non-Request' fields (as these records ##
+drmtool.ldif.namingContext._033=## should be removed via the option to ##
+drmtool.ldif.namingContext._034=## process requests and key records only ##
+drmtool.ldif.namingContext._035=## if this is a DRM migration): ##
+drmtool.ldif.namingContext._036=## ##
+drmtool.ldif.namingContext._037=## uid ##
+drmtool.ldif.namingContext._038=## uniqueMember ##
+drmtool.ldif.namingContext._039=## ##
+drmtool.ldif.namingContext._040=## If '-source_naming_context ##
+drmtool.ldif.namingContext._041=## <original source DRM naming context>' ##
+drmtool.ldif.namingContext._042=## and '-target_naming_context ##
+drmtool.ldif.namingContext._043=## <renamed target DRM naming context>' ##
+drmtool.ldif.namingContext._044=## options are specified, ALWAYS ##
+drmtool.ldif.namingContext._045=## require 'DRMTOOL' to change the ##
+drmtool.ldif.namingContext._046=## DRM 'naming context' data in ALL of ##
+drmtool.ldif.namingContext._047=## the following fields in EACH of the ##
+drmtool.ldif.namingContext._048=## following types of records: ##
+drmtool.ldif.namingContext._049=## ##
+drmtool.ldif.namingContext._050=## caEnrollmentRequest: ##
+drmtool.ldif.namingContext._051=## ##
+drmtool.ldif.namingContext._052=## dn ##
+drmtool.ldif.namingContext._053=## extdata-auth--005ftoken;user ##
+drmtool.ldif.namingContext._054=## extdata-auth--005ftoken;userdn ##
+drmtool.ldif.namingContext._055=## ##
+drmtool.ldif.namingContext._056=## caKeyRecord: ##
+drmtool.ldif.namingContext._057=## ##
+drmtool.ldif.namingContext._058=## dn ##
+drmtool.ldif.namingContext._059=## ##
+drmtool.ldif.namingContext._060=## recoveryRequest: ##
+drmtool.ldif.namingContext._061=## ##
+drmtool.ldif.namingContext._062=## dn ##
+drmtool.ldif.namingContext._063=## ##
+drmtool.ldif.namingContext._064=## tpsKeyRecord: ##
+drmtool.ldif.namingContext._065=## ##
+drmtool.ldif.namingContext._066=## dn ##
+drmtool.ldif.namingContext._067=## ##
+drmtool.ldif.namingContext._068=## tpsNetkeyKeygenRequest: ##
+drmtool.ldif.namingContext._069=## ##
+drmtool.ldif.namingContext._070=## dn ##
+drmtool.ldif.namingContext._071=## ##
+drmtool.ldif.namingContext._072=############################################
+drmtool.ldif.recoveryRequest._000=#####################################
+drmtool.ldif.recoveryRequest._001=## DRM CA / TPS Recovery Request ##
+drmtool.ldif.recoveryRequest._002=#####################################
+drmtool.ldif.recoveryRequest.cn=true
+drmtool.ldif.recoveryRequest.dateOfModify=true
+drmtool.ldif.recoveryRequest.dn=true
+drmtool.ldif.recoveryRequest.extdata.requestId=true
+drmtool.ldif.recoveryRequest.extdata.requestNotes=true
+drmtool.ldif.recoveryRequest.extdata.serialnumber=true
+drmtool.ldif.recoveryRequest.requestId=true
+drmtool.ldif.tpsKeyRecord._000=#########################################
+drmtool.ldif.tpsKeyRecord._001=## DRM TPS Key Record ##
+drmtool.ldif.tpsKeyRecord._002=#########################################
+drmtool.ldif.tpsKeyRecord._003=## ##
+drmtool.ldif.tpsKeyRecord._004=## NEVER allow 'DRMTOOL' the ability ##
+drmtool.ldif.tpsKeyRecord._005=## to change the TPS 'naming context' ##
+drmtool.ldif.tpsKeyRecord._006=## data in the following fields: ##
+drmtool.ldif.tpsKeyRecord._007=## ##
+drmtool.ldif.tpsKeyRecord._008=## archivedBy ##
+drmtool.ldif.tpsKeyRecord._009=## ##
+drmtool.ldif.tpsKeyRecord._010=#########################################
+drmtool.ldif.tpsKeyRecord.cn=true
+drmtool.ldif.tpsKeyRecord.dateOfModify=true
+drmtool.ldif.tpsKeyRecord.dn=true
+drmtool.ldif.tpsKeyRecord.privateKeyData=true
+drmtool.ldif.tpsKeyRecord.serialno=true
+drmtool.ldif.tpsNetkeyKeygenRequest._000=#####################################
+drmtool.ldif.tpsNetkeyKeygenRequest._001=## DRM TPS Netkey Keygen Request ##
+drmtool.ldif.tpsNetkeyKeygenRequest._002=#####################################
+drmtool.ldif.tpsNetkeyKeygenRequest._003=## ##
+drmtool.ldif.tpsNetkeyKeygenRequest._004=## NEVER allow 'DRMTOOL' the ##
+drmtool.ldif.tpsNetkeyKeygenRequest._005=## ability to change the ##
+drmtool.ldif.tpsNetkeyKeygenRequest._006=## TPS 'naming context' data in ##
+drmtool.ldif.tpsNetkeyKeygenRequest._007=## the following fields: ##
+drmtool.ldif.tpsNetkeyKeygenRequest._008=## ##
+drmtool.ldif.tpsNetkeyKeygenRequest._009=## extdata-updatedby ##
+drmtool.ldif.tpsNetkeyKeygenRequest._010=## ##
+drmtool.ldif.tpsNetkeyKeygenRequest._011=#####################################
+drmtool.ldif.tpsNetkeyKeygenRequest.cn=true
+drmtool.ldif.tpsNetkeyKeygenRequest.dateOfModify=true
+drmtool.ldif.tpsNetkeyKeygenRequest.dn=true
+drmtool.ldif.tpsNetkeyKeygenRequest.extdata.keyRecord=true
+drmtool.ldif.tpsNetkeyKeygenRequest.extdata.requestId=true
+drmtool.ldif.tpsNetkeyKeygenRequest.extdata.requestNotes=true
+drmtool.ldif.tpsNetkeyKeygenRequest.requestId=true
+
diff --git a/base/java-tools/src/com/netscape/cmstools/DRMTool.java b/base/java-tools/src/com/netscape/cmstools/DRMTool.java
new file mode 100644
index 000000000..e2fd2c538
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/DRMTool.java
@@ -0,0 +1,5120 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmstools;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.cert.CertificateException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Vector;
+import java.util.regex.PatternSyntaxException;
+
+import netscape.security.provider.RSAPublicKey;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.x509.X509CertImpl;
+
+import org.mozilla.jss.CertDatabaseException;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.KeyDatabaseException;
+import org.mozilla.jss.crypto.AlreadyInitializedException;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.InvalidKeyFormatException;
+import org.mozilla.jss.crypto.KeyWrapAlgorithm;
+import org.mozilla.jss.crypto.KeyWrapper;
+import org.mozilla.jss.crypto.ObjectNotFoundException;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.crypto.SymmetricKey;
+import org.mozilla.jss.crypto.TokenCertificate;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.pkcs11.PK11PubKey;
+import org.mozilla.jss.util.Password;
+
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * The DRMTool class is a utility program designed to operate on an LDIF file
+ * to perform one or more of the following tasks:
+ *
+ * <PRE>
+ * (A) Use a new storage key (e. g. - a 2048-bit key to replace a
+ * 1024-bit key) to rewrap the existing triple DES symmetric key
+ * that was used to wrap a user's private key.
+ *
+ * STARTING INVENTORY:
+ *
+ * (1) a DRMTOOL configuration file containing DRM LDIF record
+ * types and the processing status of their associated fields
+ *
+ * (2) an LDIF file containing 'exported' DRM data
+ * (referred to as the "source" DRM)
+ *
+ * NOTE: If this LDIF file contains data that was originally
+ * from a DRM instance that was prior to RHCS 8, it
+ * must have previously undergone the appropriate
+ * migration steps.
+ *
+ * (3) the NSS security databases (e. g. - cert8.db, key3.db,
+ * and secmod.db) associated with the data contained in
+ * the source LDIF file
+ *
+ * NOTE: If the storage key was located on an HSM, then the
+ * HSM must be available to the machine on which the
+ * DRMTool is being executed (since the RSA private
+ * storage key is required for unwrapping the
+ * symmetric triple DES key). Additionally, a
+ * password may be required to unlock access to
+ * this key (e. g. - which may be located in
+ * the source DRM's 'password.conf' file).
+ *
+ * (4) a file containing the ASCII BASE-64 storage certificate
+ * from the DRM instance for which the output LDIF file is
+ * intended (referred to as the "target")
+ *
+ * ENDING INVENTORY:
+ *
+ * (1) all items listed in the STARTING INVENTORY (unchanged)
+ *
+ * (2) a log file containing information suitable for audit
+ * purposes
+ *
+ * (3) an LDIF file containing the revised data suitable for
+ * 'import' into a new DRM (referred to as the "target" DRM)
+ *
+ * DRMTool PARAMETERS:
+ *
+ * (1) the name of the DRMTOOL configuration file containing
+ * DRM LDIF record types and the processing status of their
+ * associated fields
+ *
+ * (2) the name of the input LDIF file containing data which was
+ * 'exported' from the source DRM instance
+ *
+ * (3) the name of the output LDIF file intended to contain the
+ * revised data suitable for 'import' to a target DRM instance
+ *
+ * (4) the name of the log file that may be used for auditing
+ * purposes
+ *
+ * (5) the path to the security databases that were used by
+ * the source DRM instance
+ *
+ * (6) the name of the token that was used by
+ * the source DRM instance
+ *
+ * (7) the name of the storage certificate that was used by
+ * the source DRM instance
+ *
+ * (8) the name of the file containing the ASCII BASE-64 storage
+ * certificate from the target DRM instance for which the
+ * output LDIF file is intended
+ *
+ * (9) OPTIONALLY, the name of a file which ONLY contains the
+ * password needed to access the source DRM instance's
+ * security databases
+ *
+ * (10) OPTIONALLY, choose to change the specified source DRM naming
+ * context to the specified target DRM naming context
+ *
+ * (11) OPTIONALLY, choose to ONLY process CA enrollment requests,
+ * CA recovery requests, CA key records, TPS netkeyKeygen
+ * enrollment requests, TPS recovery requests, and
+ * TPS key records
+ *
+ * DATA FIELDS AFFECTED (using default config file values):
+ *
+ * (1) CA DRM enrollment request
+ *
+ * (a) dateOfModify
+ * (b) extdata-requestnotes
+ *
+ * (2) CA DRM key record
+ *
+ * (a) dateOfModify
+ * (b) privateKeyData
+ *
+ * (3) CA DRM recovery request
+ *
+ * (a) dateOfModify
+ * (b) extdata-requestnotes (NEW)
+ *
+ * (4) TPS DRM netkeyKeygen (enrollment) request
+ *
+ * (a) dateOfModify
+ * (b) extdata-requestnotes (NEW)
+ *
+ * (5) TPS DRM key record
+ *
+ * (a) dateOfModify
+ * (b) privateKeyData
+ *
+ * (6) TPS DRM recovery request
+ *
+ * (a) dateOfModify
+ * (b) extdata-requestnotes (NEW)
+ *
+ * (B) Specify an ID offset to append to existing numeric data
+ * (e. g. - to renumber data for use in DRM consolidation efforts).
+ *
+ * STARTING INVENTORY:
+ *
+ * (1) a DRMTOOL configuration file containing DRM LDIF record
+ * types and the processing status of their associated fields
+ *
+ * (2) an LDIF file containing 'exported' DRM data
+ * (referred to as the "source" DRM)
+ *
+ * NOTE: If this LDIF file contains data that was originally
+ * from a DRM instance that was prior to RHCS 8, it
+ * must have previously undergone the appropriate
+ * migration steps.
+ *
+ * ENDING INVENTORY:
+ *
+ * (1) all items listed in the STARTING INVENTORY (unchanged)
+ *
+ * (2) a log file containing information suitable for audit
+ * purposes
+ *
+ * (3) an LDIF file containing the revised data suitable for
+ * 'import' into a new DRM (referred to as the "target" DRM)
+ *
+ * DRMTool PARAMETERS:
+ *
+ * (1) the name of the DRMTOOL configuration file containing
+ * DRM LDIF record types and the processing status of their
+ * associated fields
+ *
+ * (2) the name of the input LDIF file containing data which was
+ * 'exported' from the source DRM instance
+ *
+ * (3) the name of the output LDIF file intended to contain the
+ * revised data suitable for 'import' to a target DRM instance
+ *
+ * (4) the name of the log file that may be used for auditing
+ * purposes
+ *
+ * (5) a large numeric ID offset (mask) to be appended to existing
+ * numeric data in the source DRM instance's LDIF file
+ *
+ * (6) OPTIONALLY, choose to change the specified source DRM naming
+ * context to the specified target DRM naming context
+ *
+ * (7) OPTIONALLY, choose to ONLY process CA enrollment requests,
+ * CA recovery requests, CA key records, TPS netkeyKeygen
+ * enrollment requests, TPS recovery requests, and
+ * TPS key records
+ *
+ * DATA FIELDS AFFECTED (using default config file values):
+ *
+ * (1) CA DRM enrollment request
+ *
+ * (a) cn
+ * (b) dateOfModify
+ * (c) extdata-keyrecord
+ * (d) extdata-requestnotes
+ * (e) requestId
+ *
+ * (2) CA DRM key record
+ *
+ * (a) cn
+ * (b) dateOfModify
+ * (c) serialno
+ *
+ * (3) CA DRM recovery request
+ *
+ * (a) cn
+ * (b) dateOfModify
+ * (c) extdata-requestid
+ * (d) extdata-requestnotes (NEW)
+ * (e) extdata-serialnumber
+ * (f) requestId
+ *
+ * (4) TPS DRM netkeyKeygen (enrollment) request
+ *
+ * (a) cn
+ * (b) dateOfModify
+ * (c) extdata-keyrecord
+ * (d) extdata-requestid
+ * (e) extdata-requestnotes (NEW)
+ * (f) requestId
+ *
+ * (5) TPS DRM key record
+ *
+ * (a) cn
+ * (b) dateOfModify
+ * (c) serialno
+ *
+ * (6) TPS DRM recovery request
+ *
+ * (a) cn
+ * (b) dateOfModify
+ * (c) extdata-requestid
+ * (d) extdata-requestnotes (NEW)
+ * (e) extdata-serialnumber
+ * (f) requestId
+ *
+ * (C) Specify an ID offset to be removed from existing numeric data
+ * (e. g. - to undo renumbering used in DRM consolidation efforts).
+ *
+ * STARTING INVENTORY:
+ *
+ * (1) a DRMTOOL configuration file containing DRM LDIF record
+ * types and the processing status of their associated fields
+ *
+ * (2) an LDIF file containing 'exported' DRM data
+ * (referred to as the "source" DRM)
+ *
+ * NOTE: If this LDIF file contains data that was originally
+ * from a DRM instance that was prior to RHCS 8, it
+ * must have previously undergone the appropriate
+ * migration steps.
+ *
+ * ENDING INVENTORY:
+ *
+ * (1) all items listed in the STARTING INVENTORY (unchanged)
+ *
+ * (2) a log file containing information suitable for audit
+ * purposes
+ *
+ * (3) an LDIF file containing the revised data suitable for
+ * 'import' into a new DRM (referred to as the "target" DRM)
+ *
+ * DRMTool PARAMETERS:
+ *
+ * (1) the name of the DRMTOOL configuration file containing
+ * DRM LDIF record types and the processing status of their
+ * associated fields
+ *
+ * (2) the name of the input LDIF file containing data which was
+ * 'exported' from the source DRM instance
+ *
+ * (3) the name of the output LDIF file intended to contain the
+ * revised data suitable for 'import' to a target DRM instance
+ *
+ * (4) the name of the log file that may be used for auditing
+ * purposes
+ *
+ * (5) a large numeric ID offset (mask) to be removed from existing
+ * numeric data in the source DRM instance's LDIF file
+ *
+ * (6) OPTIONALLY, choose to change the specified source DRM naming
+ * context to the specified target DRM naming context
+ *
+ * (7) OPTIONALLY, choose to ONLY process CA enrollment requests,
+ * CA recovery requests, CA key records, TPS netkeyKeygen
+ * enrollment requests, TPS recovery requests, and
+ * TPS key records
+ *
+ * DATA FIELDS AFFECTED (using default config file values):
+ *
+ * (1) CA DRM enrollment request
+ *
+ * (a) cn
+ * (b) dateOfModify
+ * (c) extdata-keyrecord
+ * (d) extdata-requestnotes
+ * (e) requestId
+ *
+ * (2) CA DRM key record
+ *
+ * (a) cn
+ * (b) dateOfModify
+ * (c) serialno
+ *
+ * (3) CA DRM recovery request
+ *
+ * (a) cn
+ * (b) dateOfModify
+ * (c) extdata-requestid
+ * (d) extdata-requestnotes (NEW)
+ * (e) extdata-serialnumber
+ * (f) requestId
+ *
+ * (4) TPS DRM netkeyKeygen (enrollment) request
+ *
+ * (a) cn
+ * (b) dateOfModify
+ * (c) extdata-keyrecord
+ * (d) extdata-requestid
+ * (e) extdata-requestnotes (NEW)
+ * (f) requestId
+ *
+ * (5) TPS DRM key record
+ *
+ * (a) cn
+ * (b) dateOfModify
+ * (c) serialno
+ *
+ * (6) TPS DRM recovery request
+ *
+ * (a) cn
+ * (b) dateOfModify
+ * (c) extdata-requestid
+ * (d) extdata-requestnotes (NEW)
+ * (e) extdata-serialnumber
+ * (f) requestId
+ *
+ * </PRE>
+ *
+ * <P>
+ * DRMTool may be invoked as follows:
+ *
+ * <PRE>
+ *
+ * DRMTool
+ * -drmtool_config_file &lt;path + drmtool config file&gt;
+ * -source_ldif_file &lt;path + source ldif file&gt;
+ * -target_ldif_file &lt;path + target ldif file&gt;
+ * -log_file &lt;path + log file&gt;
+ * [-source_pki_security_database_path &lt;path to PKI source database&gt;]
+ * [-source_storage_token_name '&lt;source token&gt;']
+ * [-source_storage_certificate_nickname '&lt;source nickname&gt;']
+ * [-target_storage_certificate_file &lt;path to target certificate file&gt;]
+ * [-source_pki_security_database_pwdfile &lt;path to PKI password file&gt;]
+ * [-append_id_offset &lt;numeric offset&gt;]
+ * [-remove_id_offset &lt;numeric offset&gt;]
+ * [-source_drm_naming_context '&lt;original source DRM naming context&gt;']
+ * [-target_drm_naming_context '&lt;renamed target DRM naming context&gt;']
+ * [-process_requests_and_key_records_only]
+ *
+ * where the following options are 'Mandatory':
+ *
+ * -drmtool_config_file &lt;path + drmtool config file&gt;
+ * -source_ldif_file &lt;path + source ldif file&gt;
+ * -target_ldif_file &lt;path + target ldif file&gt;
+ * -log_file &lt;path + log file&gt;
+ *
+ * AND at least ONE of the following are a 'Mandatory' set of options:
+ *
+ * (a) options for using a new storage key for rewrapping:
+ *
+ * [-source_pki_security_database_path
+ * &lt;path to PKI source database&gt;]
+ * [-source_storage_token_name '&lt;source token&gt;']
+ * [-source_storage_certificate_nickname '&lt;source nickname&gt;']
+ * [-target_storage_certificate_file
+ * &lt;path to target certificate file&gt;]
+ *
+ * AND OPTIONALLY, specify the name of a file which ONLY contains
+ * the password needed to access the source DRM instance's
+ * security databases:
+ *
+ * [-source_pki_security_database_pwdfile
+ * &lt;path to PKI password file&gt;]
+ *
+ * AND OPTIONALLY, rename source DRM naming context --> target
+ * DRM naming context:
+ *
+ * [-source_drm_naming_context '&lt;source DRM naming context&gt;']
+ * [-target_drm_naming_context '&lt;target DRM naming context&gt;']
+ *
+ * AND OPTIONALLY, process requests and key records ONLY:
+ *
+ * [-process_requests_and_key_records_only]
+ *
+ * (b) option for appending the specified numeric ID offset
+ * to existing numerical data:
+ *
+ * [-append_id_offset &lt;numeric offset&gt;]
+ *
+ * AND OPTIONALLY, rename source DRM naming context --> target
+ * DRM naming context:
+ *
+ * [-source_drm_naming_context '&lt;source DRM naming context&gt;']
+ * [-target_drm_naming_context '&lt;target DRM naming context&gt;']
+ *
+ * AND OPTIONALLY, process requests and key records ONLY:
+ *
+ * [-process_requests_and_key_records_only]
+ *
+ * (c) option for removing the specified numeric ID offset
+ * from existing numerical data:
+ *
+ * AND OPTIONALLY, rename source DRM naming context --> target
+ * DRM naming context:
+ *
+ * [-source_drm_naming_context '&lt;source DRM naming context&gt;']
+ * [-target_drm_naming_context '&lt;target DRM naming context&gt;']
+ *
+ * [-remove_id_offset &lt;numeric offset&gt;]
+ *
+ * AND OPTIONALLY, process requests and key records ONLY:
+ *
+ * [-process_requests_and_key_records_only]
+ *
+ * (d) (a) rewrap AND (b) append ID offset
+ * [AND OPTIONALLY, rename source DRM naming context --> target
+ * DRM naming context]
+ * [AND OPTIONALLY process requests and key records ONLY]
+ *
+ * (e) (a) rewrap AND (c) remove ID offset
+ * [AND OPTIONALLY, rename source DRM naming context --> target
+ * DRM naming context]
+ * [AND OPTIONALLY process requests and key records ONLY]
+ *
+ * NOTE: Options (b) and (c) are mutually exclusive!
+ *
+ * </PRE>
+ *
+ * @author mharmsen
+ * @version $Revision$, $Date$
+ */
+public class DRMTool {
+ /*************/
+ /* Constants */
+ /*************/
+
+ // Constants: Miscellaneous
+ private static final boolean FAILURE = false;
+ private static final boolean SUCCESS = true;
+ private static final String COLON = ":";
+ private static final String COMMA = ",";
+ private static final String DOT = ".";
+ private static final String EQUAL_SIGN = "=";
+ private static final String HASH = "#";
+ private static final String LEFT_BRACE = "[";
+ private static final String NEWLINE = "\n";
+ private static final String PLUS = "+";
+ private static final String RIGHT_BRACE = "]";
+ private static final String SPACE = " ";
+ private static final String TIC = "'";
+
+ // Constants: Calendar
+ private static final String DATE_OF_MODIFY_PATTERN = "yyyyMMddHHmmss'Z'";
+ private static final String LOGGING_DATE_PATTERN = "dd/MMM/yyyy:HH:mm:ss z";
+
+ // Constants: PKCS #11 Information
+ private static final String INTERNAL_TOKEN = "Internal Key Storage Token";
+
+ // Constants: Command-line Options
+ private static final int ID_OFFSET_NAME_VALUE_PAIRS = 1;
+ private static final int PWDFILE_NAME_VALUE_PAIRS = 1;
+ private static final int NAMING_CONTEXT_NAME_VALUE_PAIRS = 2;
+ private static final int MANDATORY_NAME_VALUE_PAIRS = 4;
+ private static final int REWRAP_NAME_VALUE_PAIRS = 4;
+ private static final int ID_OFFSET_ARGS = 10;
+ private static final int REWRAP_ARGS = 16;
+ private static final int REWRAP_AND_ID_OFFSET_ARGS = 18;
+
+ // Constants: Command-line Options (Mandatory)
+ private static final String DRM_TOOL = "DRMTool";
+
+ private static final String DRMTOOL_CFG_FILE = "-drmtool_config_file";
+
+ private static final String DRMTOOL_CFG_DESCRIPTION = " <complete path to the drmtool config file"
+ + NEWLINE
+ + " "
+ + " ending with the drmtool config file name>";
+
+ private static final String DRMTOOL_CFG_FILE_EXAMPLE = DRMTOOL_CFG_FILE
+ + " "
+ + "/usr/share/pki/java-tools/DRMTool.cfg";
+
+ private static final String SOURCE_LDIF_FILE = "-source_ldif_file";
+
+ private static final String SOURCE_LDIF_DESCRIPTION = " <complete path to the source LDIF input file"
+ + NEWLINE
+ + " "
+ + " ending with the source LDIF file name>";
+
+ private static final String SOURCE_LDIF_FILE_EXAMPLE = SOURCE_LDIF_FILE
+ + " "
+ + "/export/pki/source.ldif";
+
+ private static final String TARGET_LDIF_FILE = "-target_ldif_file";
+
+ private static final String TARGET_LDIF_DESCRIPTION = " <complete path to the target LDIF output file"
+ + NEWLINE
+ + " "
+ + " ending with the target LDIF file name>";
+
+ private static final String TARGET_LDIF_FILE_EXAMPLE = TARGET_LDIF_FILE
+ + " "
+ + "/export/pki/target.ldif";
+
+ private static final String LOG_FILE = "-log_file";
+
+ private static final String LOG_DESCRIPTION = " <complete path to the log file"
+ + NEWLINE
+ + " "
+ + " ending with the log file name>";
+
+ private static final String LOG_FILE_EXAMPLE = LOG_FILE
+ + " "
+ + "/export/pki/DRMTool.log";
+
+ // Constants: Command-line Options (Rewrap)
+ private static final String SOURCE_NSS_DB_PATH = "-source_pki_security_database_path";
+
+ private static final String SOURCE_NSS_DB_DESCRIPTION = " <complete path to the "
+ + "source security databases"
+ + NEWLINE
+ + " "
+ + " used by data in the source LDIF file>";
+
+ private static final String SOURCE_NSS_DB_PATH_EXAMPLE = SOURCE_NSS_DB_PATH
+ + " "
+ + "/export/pki";
+
+ private static final String SOURCE_STORAGE_TOKEN_NAME = "-source_storage_token_name";
+
+ private static final String SOURCE_STORAGE_TOKEN_DESCRIPTION = " <name of the token containing "
+ + "the source storage token>";
+
+ private static final String SOURCE_STORAGE_TOKEN_NAME_EXAMPLE = SOURCE_STORAGE_TOKEN_NAME
+ + " "
+ + TIC
+ + "Internal Key Storage Token"
+ + TIC;
+
+ private static final String SOURCE_STORAGE_CERT_NICKNAME = "-source_storage_certificate_nickname";
+
+ private static final String SOURCE_STORAGE_CERT_NICKNAME_DESCRIPTION = " <nickname of the source "
+ + "storage certificate>";
+
+ private static final String SOURCE_STORAGE_CERT_NICKNAME_EXAMPLE = SOURCE_STORAGE_CERT_NICKNAME
+ + " "
+ + TIC
+ + "storageCert cert-pki-kra"
+ + TIC;
+
+ private static final String TARGET_STORAGE_CERTIFICATE_FILE = "-target_storage_certificate_file";
+
+ private static final String TARGET_STORAGE_CERTIFICATE_DESCRIPTION = " <complete path to the target "
+ + "storage certificate file"
+ + NEWLINE
+ + " "
+ + " ending with the target "
+ + "storage certificate file name;"
+ + NEWLINE
+ + " "
+ + " the target storage "
+ + "certificate is stored in"
+ + NEWLINE
+ + " "
+ + " an ASCII format between a "
+ + "header and footer>";
+
+ private static final String TARGET_STORAGE_CERTIFICATE_FILE_EXAMPLE = TARGET_STORAGE_CERTIFICATE_FILE
+ + " "
+ + "/export/pki/target_storage.cert";
+
+ private static final String SOURCE_NSS_DB_PWDFILE = "-source_pki_security_database_pwdfile";
+
+ private static final String SOURCE_NSS_DB_PWDFILE_DESCRIPTION = " <complete path to the password "
+ + "file which ONLY contains the"
+ + NEWLINE
+ + " "
+ + " password used to access the "
+ + "source security databases>";
+
+ private static final String SOURCE_NSS_DB_PWDFILE_EXAMPLE = SOURCE_NSS_DB_PWDFILE
+ + " "
+ + "/export/pki/pwdfile";
+
+ // Constants: Command-line Options (ID Offset)
+ private static final String APPEND_ID_OFFSET = "-append_id_offset";
+
+ private static final String APPEND_ID_OFFSET_DESCRIPTION = " <ID offset that is appended to "
+ + "each record's source ID>";
+
+ private static final String APPEND_ID_OFFSET_EXAMPLE = APPEND_ID_OFFSET
+ + " "
+ + "100000000000";
+
+ private static final String REMOVE_ID_OFFSET = "-remove_id_offset";
+
+ private static final String REMOVE_ID_OFFSET_DESCRIPTION = " <ID offset that is removed from "
+ + "each record's source ID>";
+
+ private static final String REMOVE_ID_OFFSET_EXAMPLE = REMOVE_ID_OFFSET
+ + " "
+ + "100000000000";
+
+ // Constants: Command-line Options
+ private static final String SOURCE_DRM_NAMING_CONTEXT = "-source_drm_naming_context";
+
+ private static final String SOURCE_DRM_NAMING_CONTEXT_DESCRIPTION = " <source DRM naming context>";
+
+ private static final String SOURCE_DRM_NAMING_CONTEXT_EXAMPLE = SOURCE_DRM_NAMING_CONTEXT
+ + " "
+ + TIC
+ + "alpha.example.com-pki-kra"
+ + TIC;
+
+ private static final String TARGET_DRM_NAMING_CONTEXT = "-target_drm_naming_context";
+
+ private static final String TARGET_DRM_NAMING_CONTEXT_DESCRIPTION = " <target DRM naming context>";
+
+ private static final String TARGET_DRM_NAMING_CONTEXT_EXAMPLE = TARGET_DRM_NAMING_CONTEXT
+ + " "
+ + TIC
+ + "omega.example.com-pki-kra"
+ + TIC;
+
+ private static final String PROCESS_REQUESTS_AND_KEY_RECORDS_ONLY =
+ "-process_requests_and_key_records_only";
+
+ // Constants: DRMTOOL Config File
+ private static final String DRMTOOL_CFG_PREFIX = "drmtool.ldif";
+ private static final String DRMTOOL_CFG_ENROLLMENT = "caEnrollmentRequest";
+ private static final String DRMTOOL_CFG_CA_KEY_RECORD = "caKeyRecord";
+ private static final String DRMTOOL_CFG_RECOVERY = "recoveryRequest";
+ private static final String DRMTOOL_CFG_TPS_KEY_RECORD = "tpsKeyRecord";
+ private static final String DRMTOOL_CFG_KEYGEN = "tpsNetkeyKeygenRequest";
+
+ // Constants: DRMTOOL Config File (DRM CA Enrollment Request Fields)
+ private static final String DRMTOOL_CFG_ENROLLMENT_CN = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_ENROLLMENT
+ + DOT
+ + "cn";
+ private static final String DRMTOOL_CFG_ENROLLMENT_DATE_OF_MODIFY = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_ENROLLMENT
+ + DOT
+ + "dateOfModify";
+ private static final String DRMTOOL_CFG_ENROLLMENT_DN = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_ENROLLMENT
+ + DOT
+ + "dn";
+ private static final String DRMTOOL_CFG_ENROLLMENT_EXTDATA_KEY_RECORD = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_ENROLLMENT
+ + DOT
+ + "extdata.keyRecord";
+ private static final String DRMTOOL_CFG_ENROLLMENT_EXTDATA_REQUEST_NOTES = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_ENROLLMENT
+ + DOT
+ + "extdata.requestNotes";
+ private static final String DRMTOOL_CFG_ENROLLMENT_REQUEST_ID = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_ENROLLMENT
+ + DOT
+ + "requestId";
+
+ // Constants: DRMTOOL Config File (DRM CA Key Record Fields)
+ private static final String DRMTOOL_CFG_CA_KEY_RECORD_CN = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_CA_KEY_RECORD
+ + DOT
+ + "cn";
+ private static final String DRMTOOL_CFG_CA_KEY_RECORD_DATE_OF_MODIFY = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_CA_KEY_RECORD
+ + DOT
+ + "dateOfModify";
+ private static final String DRMTOOL_CFG_CA_KEY_RECORD_DN = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_ENROLLMENT
+ + DOT
+ + "dn";
+ private static final String DRMTOOL_CFG_CA_KEY_RECORD_PRIVATE_KEY_DATA = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_CA_KEY_RECORD
+ + DOT
+ + "privateKeyData";
+ private static final String DRMTOOL_CFG_CA_KEY_RECORD_SERIAL_NO = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_CA_KEY_RECORD
+ + DOT
+ + "serialno";
+
+ // Constants: DRMTOOL Config File (DRM CA / TPS Recovery Request Fields)
+ private static final String DRMTOOL_CFG_RECOVERY_CN = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_RECOVERY
+ + DOT
+ + "cn";
+ private static final String DRMTOOL_CFG_RECOVERY_DATE_OF_MODIFY = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_RECOVERY
+ + DOT
+ + "dateOfModify";
+ private static final String DRMTOOL_CFG_RECOVERY_DN = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_RECOVERY
+ + DOT
+ + "dn";
+ private static final String DRMTOOL_CFG_RECOVERY_EXTDATA_REQUEST_ID = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_RECOVERY
+ + DOT
+ + "extdata.requestId";
+ private static final String DRMTOOL_CFG_RECOVERY_EXTDATA_REQUEST_NOTES = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_RECOVERY
+ + DOT
+ + "extdata.requestNotes";
+ private static final String DRMTOOL_CFG_RECOVERY_EXTDATA_SERIAL_NUMBER = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_RECOVERY
+ + DOT
+ + "extdata.serialnumber";
+ private static final String DRMTOOL_CFG_RECOVERY_REQUEST_ID = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_RECOVERY
+ + DOT
+ + "requestId";
+
+ // Constants: DRMTOOL Config File (DRM TPS Key Record Fields)
+ private static final String DRMTOOL_CFG_TPS_KEY_RECORD_CN = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_TPS_KEY_RECORD
+ + DOT
+ + "cn";
+ private static final String DRMTOOL_CFG_TPS_KEY_RECORD_DATE_OF_MODIFY = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_TPS_KEY_RECORD
+ + DOT
+ + "dateOfModify";
+ private static final String DRMTOOL_CFG_TPS_KEY_RECORD_DN = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_TPS_KEY_RECORD
+ + DOT
+ + "dn";
+ private static final String DRMTOOL_CFG_TPS_KEY_RECORD_PRIVATE_KEY_DATA = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_TPS_KEY_RECORD
+ + DOT
+ + "privateKeyData";
+ private static final String DRMTOOL_CFG_TPS_KEY_RECORD_SERIAL_NO = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_TPS_KEY_RECORD
+ + DOT
+ + "serialno";
+
+ // Constants: DRMTOOL Config File (DRM TPS Netkey Keygen Request Fields)
+ private static final String DRMTOOL_CFG_KEYGEN_CN = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_KEYGEN
+ + DOT
+ + "cn";
+ private static final String DRMTOOL_CFG_KEYGEN_DATE_OF_MODIFY = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_KEYGEN
+ + DOT
+ + "dateOfModify";
+ private static final String DRMTOOL_CFG_KEYGEN_DN = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_KEYGEN
+ + DOT
+ + "dn";
+ private static final String DRMTOOL_CFG_KEYGEN_EXTDATA_KEY_RECORD = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_KEYGEN
+ + DOT
+ + "extdata.keyRecord";
+ private static final String DRMTOOL_CFG_KEYGEN_EXTDATA_REQUEST_ID = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_KEYGEN
+ + DOT
+ + "extdata.requestId";
+ private static final String DRMTOOL_CFG_KEYGEN_EXTDATA_REQUEST_NOTES = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_KEYGEN
+ + DOT
+ + "extdata.requestNotes";
+ private static final String DRMTOOL_CFG_KEYGEN_REQUEST_ID = DRMTOOL_CFG_PREFIX
+ + DOT
+ + DRMTOOL_CFG_KEYGEN
+ + DOT
+ + "requestId";
+
+ // Constants: Target Certificate Information
+ private static final String HEADER = "-----BEGIN";
+ private static final String TRAILER = "-----END";
+ private static final String X509_INFO = "x509.INFO";
+
+ // Constants: DRM LDIF Record Fields
+ private static final String DRM_LDIF_ARCHIVED_BY = "archivedBy:";
+ private static final String DRM_LDIF_CN = "cn:";
+ private static final String DRM_LDIF_DATE_OF_MODIFY = "dateOfModify:";
+ private static final String DRM_LDIF_DN = "dn:";
+ private static final String DRM_LDIF_DN_EMBEDDED_CN_DATA = "dn: cn";
+ private static final String DRM_LDIF_EXTDATA_AUTH_TOKEN_USER = "extdata-auth--005ftoken;user:";
+ private static final String DRM_LDIF_EXTDATA_AUTH_TOKEN_USER_DN = "extdata-auth--005ftoken;userdn:";
+ private static final String DRM_LDIF_EXTDATA_KEY_RECORD = "extdata-keyrecord:";
+ private static final String DRM_LDIF_EXTDATA_REQUEST_ID = "extdata-requestid:";
+ private static final String DRM_LDIF_EXTDATA_REQUEST_NOTES = "extdata-requestnotes:";
+ private static final String DRM_LDIF_EXTDATA_REQUEST_TYPE = "extdata-requesttype:";
+ private static final String DRM_LDIF_EXTDATA_SERIAL_NUMBER = "extdata-serialnumber:";
+ private static final String DRM_LDIF_PRIVATE_KEY_DATA = "privateKeyData::";
+ private static final String DRM_LDIF_REQUEST_ID = "requestId:";
+ private static final String DRM_LDIF_REQUEST_TYPE = "requestType:";
+ private static final String DRM_LDIF_SERIAL_NO = "serialno:";
+
+ // Constants: DRM LDIF Record Values
+ private static final int INITIAL_LDIF_RECORD_CAPACITY = 0;
+ private static final int EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH = 56;
+ private static final int PRIVATE_KEY_DATA_FIRST_LINE_DATA_LENGTH = 60;
+ private static final String DRM_LDIF_RECORD = "Generic";
+ private static final String DRM_LDIF_CA_KEY_RECORD = "CA";
+ private static final String DRM_LDIF_ENROLLMENT = "enrollment";
+ private static final String DRM_LDIF_KEYGEN = "netkeyKeygen";
+ private static final String DRM_LDIF_RECOVERY = "recovery";
+ private static final String DRM_LDIF_TPS_KEY_RECORD = "TPS";
+
+ // Constants: DRM LDIF Record Messages
+ private static final String DRM_LDIF_REWRAP_MESSAGE = "REWRAPPED the '"
+ + "existing DES3 "
+ + "symmetric "
+ + "session key"
+ + "' with the '";
+ private static final String DRM_LDIF_RSA_MESSAGE = "-bit RSA public key' "
+ + "obtained from the "
+ + "target storage "
+ + "certificate";
+ private static final String DRM_LDIF_USED_PWDFILE_MESSAGE =
+ "USED source PKI security database "
+ + "password file";
+ private static final String DRM_LDIF_APPENDED_ID_OFFSET_MESSAGE =
+ "APPENDED ID offset";
+ private static final String DRM_LDIF_REMOVED_ID_OFFSET_MESSAGE =
+ "REMOVED ID offset";
+ private static final String DRM_LDIF_SOURCE_NAME_CONTEXT_MESSAGE =
+ "RENAMED source DRM naming context '";
+ private static final String DRM_LDIF_TARGET_NAME_CONTEXT_MESSAGE =
+ "' to target DRM naming context '";
+ private static final String DRM_LDIF_PROCESS_REQUESTS_AND_KEY_RECORDS_ONLY_MESSAGE =
+ "PROCESSED requests and key records ONLY!";
+
+ /*************/
+ /* Variables */
+ /*************/
+
+ // Variables: Calendar
+ private static String mDateOfModify = null;
+
+ // Variables: Command-Line Options
+ private static boolean mMandatoryFlag = false;
+ private static boolean mRewrapFlag = false;
+ private static boolean mPwdfileFlag = false;
+ private static boolean mAppendIdOffsetFlag = false;
+ private static boolean mRemoveIdOffsetFlag = false;
+ private static boolean mDrmNamingContextsFlag = false;
+ private static boolean mProcessRequestsAndKeyRecordsOnlyFlag = false;
+ private static int mMandatoryNameValuePairs = 0;
+ private static int mRewrapNameValuePairs = 0;
+ private static int mPKISecurityDatabasePwdfileNameValuePairs = 0;
+ private static int mAppendIdOffsetNameValuePairs = 0;
+ private static int mRemoveIdOffsetNameValuePairs = 0;
+ private static int mDrmNamingContextNameValuePairs = 0;
+
+ // Variables: Command-Line Values (Mandatory)
+ private static String mDrmtoolCfgFilename = null;
+ private static String mSourceLdifFilename = null;
+ private static String mTargetLdifFilename = null;
+ private static String mLogFilename = null;
+
+ // Variables: Command-Line Values (Rewrap)
+ private static String mSourcePKISecurityDatabasePath = null;
+ private static String mSourceStorageTokenName = null;
+ private static String mSourceStorageCertNickname = null;
+ private static String mTargetStorageCertificateFilename = null;
+
+ // Variables: Command-Line Values (Rewrap Password File)
+ private static String mSourcePKISecurityDatabasePwdfile = null;
+
+ // Variables: Command-Line Values (ID Offset)
+ private static BigInteger mAppendIdOffset = null;
+ private static BigInteger mRemoveIdOffset = null;
+
+ // Variables: Command-Line Values (DRM Naming Contexts)
+ private static String mSourceDrmNamingContext = null;
+ private static String mTargetDrmNamingContext = null;
+
+ // Variables: DRMTOOL Config File Parameters of Interest
+ private static Hashtable<String, Boolean> drmtoolCfg = null;
+
+ // Variables: DRMTOOL LDIF File Parameters of Interest
+ private static Vector<String> record = null;
+ private static Iterator<String> ldif_record = null;
+
+ // Variables: Logging
+ private static boolean mDebug = false; // set 'true' for debug messages
+ private static PrintWriter logger = null;
+ private static String current_date_and_time = null;
+
+ // Variables: PKCS #11 Information
+ private static CryptoToken mSourceToken = null;
+ private static X509Certificate mUnwrapCert = null;
+ private static PrivateKey mUnwrapPrivateKey = null;
+ private static PublicKey mWrapPublicKey = null;
+ private static int mPublicKeySize = 0;
+
+ // Variables: DRM LDIF Record Messages
+ private static String mSourcePKISecurityDatabasePwdfileMessage = null;
+ private static String mDrmNamingContextMessage = null;
+ private static String mProcessRequestsAndKeyRecordsOnlyMessage = null;
+
+ /********************/
+ /* Calendar Methods */
+ /********************/
+
+ /**
+ * This method is used to get the current date and time.
+ * <P>
+ *
+ * @param pattern string containing desired format of date and time
+ * @return a formatted string containing the current date and time
+ */
+ private static String now(String pattern) {
+ Calendar cal = Calendar.getInstance();
+ SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+ return sdf.format(cal.getTime());
+ }
+
+ /*****************/
+ /* Usage Methods */
+ /*****************/
+
+ /**
+ * This method prints out the proper command-line usage required to
+ * execute DRMTool.
+ */
+ private static void printUsage() {
+ System.out.println("Usage: "
+ + DRM_TOOL
+ + NEWLINE
+ + " "
+ + DRMTOOL_CFG_FILE
+ + NEWLINE
+ + " "
+ + DRMTOOL_CFG_DESCRIPTION
+ + NEWLINE
+ + " "
+ + SOURCE_LDIF_FILE
+ + NEWLINE
+ + " "
+ + SOURCE_LDIF_DESCRIPTION
+ + NEWLINE
+ + " "
+ + TARGET_LDIF_FILE
+ + NEWLINE
+ + " "
+ + TARGET_LDIF_DESCRIPTION
+ + NEWLINE
+ + " "
+ + LOG_FILE
+ + NEWLINE
+ + " "
+ + LOG_DESCRIPTION
+ + NEWLINE
+ + " "
+ + "["
+ + SOURCE_NSS_DB_PATH
+ + NEWLINE
+ + " "
+ + SOURCE_NSS_DB_DESCRIPTION
+ + "]"
+ + NEWLINE
+ + " "
+ + "["
+ + SOURCE_STORAGE_TOKEN_NAME
+ + NEWLINE
+ + " "
+ + SOURCE_STORAGE_TOKEN_DESCRIPTION
+ + "]"
+ + NEWLINE
+ + " "
+ + "["
+ + SOURCE_STORAGE_CERT_NICKNAME
+ + NEWLINE
+ + " "
+ + SOURCE_STORAGE_CERT_NICKNAME_DESCRIPTION
+ + "]"
+ + NEWLINE
+ + " "
+ + "["
+ + TARGET_STORAGE_CERTIFICATE_FILE
+ + NEWLINE
+ + " "
+ + TARGET_STORAGE_CERTIFICATE_DESCRIPTION
+ + "]"
+ + NEWLINE
+ + " "
+ + "["
+ + SOURCE_NSS_DB_PWDFILE
+ + NEWLINE
+ + " "
+ + SOURCE_NSS_DB_PWDFILE_DESCRIPTION
+ + "]"
+ + NEWLINE
+ + " "
+ + "["
+ + APPEND_ID_OFFSET
+ + NEWLINE
+ + " "
+ + APPEND_ID_OFFSET_DESCRIPTION
+ + "]"
+ + NEWLINE
+ + " "
+ + "["
+ + REMOVE_ID_OFFSET
+ + NEWLINE
+ + " "
+ + REMOVE_ID_OFFSET_DESCRIPTION
+ + "]"
+ + NEWLINE
+ + " "
+ + "["
+ + SOURCE_DRM_NAMING_CONTEXT
+ + NEWLINE
+ + " "
+ + SOURCE_DRM_NAMING_CONTEXT_DESCRIPTION
+ + "]"
+ + NEWLINE
+ + " "
+ + "["
+ + TARGET_DRM_NAMING_CONTEXT
+ + NEWLINE
+ + " "
+ + TARGET_DRM_NAMING_CONTEXT_DESCRIPTION
+ + "]"
+ + NEWLINE
+ + " "
+ + "["
+ + PROCESS_REQUESTS_AND_KEY_RECORDS_ONLY
+ + "]"
+ + NEWLINE);
+
+ System.out.println("Example of 'Rewrap and Append ID Offset':"
+ + NEWLINE
+ + NEWLINE
+ + " "
+ + DRM_TOOL
+ + NEWLINE
+ + " "
+ + DRMTOOL_CFG_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_LDIF_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + TARGET_LDIF_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + LOG_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_NSS_DB_PATH_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_STORAGE_TOKEN_NAME_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_STORAGE_CERT_NICKNAME_EXAMPLE
+ + NEWLINE
+ + " "
+ + TARGET_STORAGE_CERTIFICATE_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_NSS_DB_PWDFILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + APPEND_ID_OFFSET_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_DRM_NAMING_CONTEXT_EXAMPLE
+ + NEWLINE
+ + " "
+ + TARGET_DRM_NAMING_CONTEXT_EXAMPLE
+ + NEWLINE
+ + " "
+ + PROCESS_REQUESTS_AND_KEY_RECORDS_ONLY
+ + NEWLINE);
+
+ System.out.println("Example of 'Rewrap and Remove ID Offset':"
+ + NEWLINE
+ + NEWLINE
+ + " "
+ + DRM_TOOL
+ + NEWLINE
+ + " "
+ + DRMTOOL_CFG_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_LDIF_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + TARGET_LDIF_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + LOG_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_NSS_DB_PATH_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_STORAGE_TOKEN_NAME_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_STORAGE_CERT_NICKNAME_EXAMPLE
+ + NEWLINE
+ + " "
+ + TARGET_STORAGE_CERTIFICATE_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_NSS_DB_PWDFILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + REMOVE_ID_OFFSET_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_DRM_NAMING_CONTEXT_EXAMPLE
+ + NEWLINE
+ + " "
+ + TARGET_DRM_NAMING_CONTEXT_EXAMPLE
+ + NEWLINE
+ + " "
+ + PROCESS_REQUESTS_AND_KEY_RECORDS_ONLY
+ + NEWLINE);
+
+ System.out.println("Example of 'Rewrap':"
+ + NEWLINE
+ + NEWLINE
+ + " "
+ + DRM_TOOL
+ + NEWLINE
+ + " "
+ + DRMTOOL_CFG_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_LDIF_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + TARGET_LDIF_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + LOG_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_NSS_DB_PATH_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_STORAGE_TOKEN_NAME_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_STORAGE_CERT_NICKNAME_EXAMPLE
+ + NEWLINE
+ + " "
+ + TARGET_STORAGE_CERTIFICATE_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_NSS_DB_PWDFILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_DRM_NAMING_CONTEXT_EXAMPLE
+ + NEWLINE
+ + " "
+ + TARGET_DRM_NAMING_CONTEXT_EXAMPLE
+ + NEWLINE
+ + " "
+ + PROCESS_REQUESTS_AND_KEY_RECORDS_ONLY
+ + NEWLINE);
+
+ System.out.println("Example of 'Append ID Offset':"
+ + NEWLINE
+ + NEWLINE
+ + " "
+ + DRM_TOOL
+ + NEWLINE
+ + " "
+ + DRMTOOL_CFG_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_LDIF_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + TARGET_LDIF_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + LOG_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + APPEND_ID_OFFSET_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_DRM_NAMING_CONTEXT_EXAMPLE
+ + NEWLINE
+ + " "
+ + TARGET_DRM_NAMING_CONTEXT_EXAMPLE
+ + NEWLINE
+ + " "
+ + PROCESS_REQUESTS_AND_KEY_RECORDS_ONLY
+ + NEWLINE);
+
+ System.out.println("Example of 'Remove ID Offset':"
+ + NEWLINE
+ + NEWLINE
+ + " "
+ + DRM_TOOL
+ + NEWLINE
+ + " "
+ + DRMTOOL_CFG_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_LDIF_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + TARGET_LDIF_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + LOG_FILE_EXAMPLE
+ + NEWLINE
+ + " "
+ + REMOVE_ID_OFFSET_EXAMPLE
+ + NEWLINE
+ + " "
+ + SOURCE_DRM_NAMING_CONTEXT_EXAMPLE
+ + NEWLINE
+ + " "
+ + TARGET_DRM_NAMING_CONTEXT_EXAMPLE
+ + NEWLINE
+ + " "
+ + PROCESS_REQUESTS_AND_KEY_RECORDS_ONLY
+ + NEWLINE);
+ }
+
+ /*******************/
+ /* Logging Methods */
+ /*******************/
+
+ /**
+ * This method opens a new log file for writing.
+ * <P>
+ *
+ * @param logfile string containing the name of the log file to be opened
+ */
+ private static void open_log(String logfile) {
+ try {
+ logger = new PrintWriter(
+ new BufferedWriter(
+ new FileWriter(logfile)));
+ } catch (IOException eFile) {
+ System.err.println("ERROR: Unable to open file '"
+ + logfile
+ + "' for writing: '"
+ + eFile.toString()
+ + "'"
+ + NEWLINE);
+ System.exit(0);
+ }
+ }
+
+ /**
+ * This method closes the specified log file.
+ * <P>
+ *
+ * @param logfile string containing the name of the log file to be closed
+ */
+ private static void close_log(String logfile) {
+ logger.close();
+ }
+
+ /**
+ * This method writes the specified message to the log file, and also
+ * to 'stderr' if the boolean flag is set to 'true'.
+ * <P>
+ *
+ * @param msg string containing the message to be written to the log file
+ * @param stderr boolean which also writes the message to 'stderr' if 'true'
+ */
+ private static void log(String msg, boolean stderr) {
+ current_date_and_time = now(LOGGING_DATE_PATTERN);
+ if (stderr) {
+ System.err.println(msg);
+ }
+ logger.write("["
+ + current_date_and_time
+ + "]: "
+ + msg);
+ logger.flush();
+ }
+
+ /*********************************************/
+ /* PKCS #11: Rewrap RSA Storage Key Methods */
+ /*********************************************/
+
+ /**
+ * Helper method to determine if two arrays contain the same values.
+ *
+ * This method is based upon code from 'com.netscape.kra.StorageKeyUnit'.
+ * <P>
+ *
+ * @param bytes first array of bytes
+ * @param ints second array of bytes
+ * @return true if the two arrays are identical
+ */
+ private static boolean arraysEqual(byte[] bytes, byte[] ints) {
+ if (bytes == null || ints == null) {
+ return false;
+ }
+
+ if (bytes.length != ints.length) {
+ return false;
+ }
+
+ for (int i = 0; i < bytes.length; i++) {
+ if (bytes[i] != ints[i]) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * This method is used to obtain the private RSA storage key from
+ * the "source" DRM instance's security databases.
+ *
+ * This method is based upon code from 'com.netscape.kra.StorageKeyUnit'.
+ * <P>
+ *
+ * @return the private RSA storage key from the "source" DRM
+ */
+ private static PrivateKey getPrivateKey() {
+ try {
+ PrivateKey pk[] = mSourceToken.getCryptoStore().getPrivateKeys();
+
+ for (int i = 0; i < pk.length; i++) {
+ if (arraysEqual(pk[i].getUniqueID(),
+ ((TokenCertificate)
+ mUnwrapCert).getUniqueID())) {
+ return pk[i];
+ }
+ }
+ } catch (TokenException exToken) {
+ log("ERROR: Getting private key - "
+ + "TokenException: '"
+ + exToken.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ }
+
+ return null;
+ }
+
+ /**
+ * This method gets the public key from the certificate stored
+ * in the "target" DRM storage certificate file. It also obtains
+ * the keysize of this RSA key.
+ *
+ * This method is based upon code from
+ * 'com.netscape.cmstools.PrettyPrintCert'.
+ * <P>
+ *
+ * @return the public RSA storage key from the "target" DRM
+ */
+ private static PublicKey getPublicKey() {
+ BufferedReader inputCert = null;
+ String encodedBASE64CertChunk = new String();
+ String encodedBASE64Cert = new String();
+ byte decodedBASE64Cert[] = null;
+ X509CertImpl cert = null;
+ PublicKey key = null;
+ RSAPublicKey rsakey = null;
+
+ // Create a DataInputStream() object to the BASE 64
+ // encoded certificate contained within the file
+ // specified on the command line
+ try {
+ inputCert = new BufferedReader(
+ new InputStreamReader(
+ new BufferedInputStream(
+ new FileInputStream(
+ mTargetStorageCertificateFilename
+ ))));
+ } catch (FileNotFoundException exWrapFileNotFound) {
+ log("ERROR: No target storage "
+ + "certificate file named '"
+ + mTargetStorageCertificateFilename
+ + "' exists! FileNotFoundException: '"
+ + exWrapFileNotFound.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ }
+
+ // Read the entire contents of the specified BASE 64 encoded
+ // certificate into a String() object throwing away any
+ // headers beginning with HEADER and any trailers beginning
+ // with TRAILER
+ try {
+ while ((encodedBASE64CertChunk = inputCert.readLine()) != null) {
+ if (!(encodedBASE64CertChunk.startsWith(HEADER)) &&
+ !(encodedBASE64CertChunk.startsWith(TRAILER))) {
+ encodedBASE64Cert += encodedBASE64CertChunk.trim();
+ }
+ }
+ } catch (IOException exWrapReadLineIO) {
+ log("ERROR: Unexpected BASE64 "
+ + "encoded error encountered while reading '"
+ + mTargetStorageCertificateFilename
+ + "'! IOException: '"
+ + exWrapReadLineIO.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ }
+
+ // Close the DataInputStream() object
+ try {
+ inputCert.close();
+ } catch (IOException exWrapCloseIO) {
+ log("ERROR: Unexpected BASE64 "
+ + "encoded error encountered in closing '"
+ + mTargetStorageCertificateFilename
+ + "'! IOException: '"
+ + exWrapCloseIO.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ }
+
+ // Decode the ASCII BASE 64 certificate enclosed in the
+ // String() object into a BINARY BASE 64 byte[] object
+ decodedBASE64Cert = Utils.base64decode(
+ encodedBASE64Cert);
+
+ // Create an X509CertImpl() object from
+ // the BINARY BASE 64 byte[] object
+ try {
+ cert = new X509CertImpl(decodedBASE64Cert);
+ } catch (CertificateException exWrapCertificate) {
+ log("ERROR: Error encountered "
+ + "in parsing certificate in '"
+ + mTargetStorageCertificateFilename
+ + "' CertificateException: '"
+ + exWrapCertificate.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ }
+
+ // Extract the Public Key
+ key = cert.getPublicKey();
+ if (key == null) {
+ log("ERROR: Unable to extract public key "
+ + "from certificate that was stored in '"
+ + mTargetStorageCertificateFilename
+ + "'."
+ + NEWLINE, true);
+ System.exit(0);
+ }
+
+ // Convert this X.509 public key --> RSA public key
+ try {
+ rsakey = new RSAPublicKey(key.getEncoded());
+ } catch (InvalidKeyException exInvalidKey) {
+ log("ERROR: Converting X.509 public key --> RSA public key - "
+ + "InvalidKeyException: '"
+ + exInvalidKey.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ }
+
+ // Obtain the Public Key's keysize
+ mPublicKeySize = rsakey.getKeySize();
+
+ return key;
+ }
+
+ /**
+ * This method is used to obtain the private RSA storage key
+ * from the "source" DRM instance's security databases and
+ * the public RSA storage key from the certificate stored in
+ * the "target" DRM storage certificate file.
+ * <P>
+ *
+ * @return true if successfully able to obtain both keys
+ */
+ private static boolean obtain_RSA_rewrapping_keys() {
+ CryptoManager cm = null;
+
+ // Initialize the source security databases
+ try {
+ log("Initializing source PKI security databases in '"
+ + mSourcePKISecurityDatabasePath + "'."
+ + NEWLINE, true);
+
+ CryptoManager.initialize(mSourcePKISecurityDatabasePath);
+ } catch (KeyDatabaseException exKey) {
+ log("ERROR: source_pki_security_database_path='"
+ + mSourcePKISecurityDatabasePath
+ + "' KeyDatabaseException: '"
+ + exKey.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ } catch (CertDatabaseException exCert) {
+ log("ERROR: source_pki_security_database_path='"
+ + mSourcePKISecurityDatabasePath
+ + "' CertDatabaseException: '"
+ + exCert.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ } catch (AlreadyInitializedException exAlreadyInitialized) {
+ log("ERROR: source_pki_security_database_path='"
+ + mSourcePKISecurityDatabasePath
+ + "' AlreadyInitializedException: '"
+ + exAlreadyInitialized.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ } catch (GeneralSecurityException exSecurity) {
+ log("ERROR: source_pki_security_database_path='"
+ + mSourcePKISecurityDatabasePath
+ + "' GeneralSecurityException: '"
+ + exSecurity.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ }
+
+ // Retrieve the source storage token by its name
+ try {
+ log("Retrieving token from CryptoManager."
+ + NEWLINE, true);
+ cm = CryptoManager.getInstance();
+
+ log("Retrieving source storage token called '"
+ + mSourceStorageTokenName
+ + "'."
+ + NEWLINE, true);
+
+ if (mSourceStorageTokenName.equals(INTERNAL_TOKEN)) {
+ mSourceToken = cm.getInternalKeyStorageToken();
+ } else {
+ mSourceToken = cm.getTokenByName(mSourceStorageTokenName);
+ }
+
+ if (mSourceToken == null) {
+ return FAILURE;
+ }
+
+ if (mPwdfileFlag) {
+ BufferedReader in = null;
+ String pwd = null;
+ Password mPwd = null;
+
+ try {
+ in = new BufferedReader(
+ new FileReader(
+ mSourcePKISecurityDatabasePwdfile));
+ pwd = in.readLine();
+
+ mPwd = new Password(pwd.toCharArray());
+
+ mSourceToken.login(mPwd);
+ } catch (Exception exReadPwd) {
+ log("ERROR: Failed to read the keydb password from "
+ + "the file '"
+ + mSourcePKISecurityDatabasePwdfile
+ + "'. Exception: '"
+ + exReadPwd.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ }
+ }
+ } catch (Exception exUninitialized) {
+ log("ERROR: Uninitialized CryptoManager - '"
+ + exUninitialized.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ }
+
+ // Retrieve the source storage cert by its nickname
+ try {
+ if (mSourceStorageTokenName.equals(INTERNAL_TOKEN)) {
+ log("Retrieving source storage cert with nickname of '"
+ + mSourceStorageCertNickname
+ + "'."
+ + NEWLINE, true);
+
+ mUnwrapCert = cm.findCertByNickname(mSourceStorageCertNickname
+ );
+ } else {
+ log("Retrieving source storage cert with nickname of '"
+ + mSourceStorageTokenName
+ + ":"
+ + mSourceStorageCertNickname
+ + "'. "
+ + NEWLINE, true);
+ mUnwrapCert = cm.findCertByNickname(mSourceStorageTokenName
+ + ":"
+ + mSourceStorageCertNickname
+ );
+ }
+
+ if (mUnwrapCert == null) {
+ return FAILURE;
+ }
+ } catch (ObjectNotFoundException exUnwrapObjectNotFound) {
+ if (mSourceStorageTokenName.equals(INTERNAL_TOKEN)) {
+ log("ERROR: No internal "
+ + "source storage cert named '"
+ + mSourceStorageCertNickname
+ + "' exists! ObjectNotFoundException: '"
+ + exUnwrapObjectNotFound.toString()
+ + "'"
+ + NEWLINE, true);
+ } else {
+ log("ERROR: No "
+ + "source storage cert named '"
+ + mSourceStorageTokenName
+ + ":"
+ + mSourceStorageCertNickname
+ + "' exists! ObjectNotFoundException: '"
+ + exUnwrapObjectNotFound
+ + "'"
+ + NEWLINE, true);
+ }
+ System.exit(0);
+ } catch (TokenException exUnwrapToken) {
+ if (mSourceStorageTokenName.equals(INTERNAL_TOKEN)) {
+ log("ERROR: No internal "
+ + "source storage cert named '"
+ + mSourceStorageCertNickname
+ + "' exists! TokenException: '"
+ + exUnwrapToken.toString()
+ + "'"
+ + NEWLINE, true);
+ } else {
+ log("ERROR: No "
+ + "source storage cert named '"
+ + mSourceStorageTokenName
+ + ":"
+ + mSourceStorageCertNickname
+ + "' exists! TokenException: '"
+ + exUnwrapToken
+ + "'"
+ + NEWLINE, true);
+ }
+ System.exit(0);
+ }
+
+ // Extract the private key from the source storage token
+ log("BEGIN: Obtaining the private key from "
+ + "the source storage token . . ."
+ + NEWLINE, true);
+
+ mUnwrapPrivateKey = getPrivateKey();
+
+ if (mUnwrapPrivateKey == null) {
+ log("ERROR: Failed extracting "
+ + "private key from the source storage token."
+ + NEWLINE, true);
+ System.exit(0);
+ }
+
+ log("FINISHED: Obtaining the private key from "
+ + "the source storage token."
+ + NEWLINE, true);
+
+ // Extract the public key from the target storage certificate
+ try {
+ log("BEGIN: Obtaining the public key from "
+ + "the target storage certificate . . ."
+ + NEWLINE, true);
+
+ mWrapPublicKey = (PublicKey)
+ (PK11PubKey.fromSPKI(
+ getPublicKey().getEncoded()));
+
+ if (mWrapPublicKey == null) {
+ log("ERROR: Failed extracting "
+ + "public key from target storage certificate stored in '"
+ + mTargetStorageCertificateFilename
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ }
+
+ log("FINISHED: Obtaining the public key from "
+ + "the target storage certificate."
+ + NEWLINE, true);
+ } catch (InvalidKeyFormatException exInvalidPublicKey) {
+ log("ERROR: Failed extracting "
+ + "public key from target storage certificate stored in '"
+ + mTargetStorageCertificateFilename
+ + "' InvalidKeyFormatException '"
+ + exInvalidPublicKey.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ }
+
+ return SUCCESS;
+ }
+
+ /**
+ * This method basically rewraps the "wrappedKeyData" by implementiing
+ * "mStorageUnit.decryptInternalPrivate( byte wrappedKeyData[] )" and
+ * "mStorageUnit.encryptInternalPrivate( byte priKey[] )", where
+ * "wrappedKeyData" uses the following structure:
+ *
+ * SEQUENCE {
+ * encryptedSession OCTET STRING,
+ * encryptedPrivate OCTET STRING
+ * }
+ *
+ * This method is based upon code from
+ * 'com.netscape.kra.EncryptionUnit'.
+ * <P>
+ *
+ * @return a byte[] containing the rewrappedKeyData
+ */
+ private static byte[] rewrap_wrapped_key_data(byte[] wrappedKeyData)
+ throws Exception {
+ DerValue val = null;
+ DerInputStream in = null;
+ DerValue dSession = null;
+ byte source_session[] = null;
+ DerValue dPri = null;
+ byte pri[] = null;
+ KeyWrapper source_rsaWrap = null;
+ SymmetricKey sk = null;
+ KeyWrapper target_rsaWrap = null;
+ byte target_session[] = null;
+ DerOutputStream tmp = null;
+ DerOutputStream out = null;
+ byte[] rewrappedKeyData = null;
+
+ // public byte[]
+ // mStorageUnit.decryptInternalPrivate( byte wrappedKeyData[] );
+ // throws EBaseException
+ try {
+ val = new DerValue(wrappedKeyData);
+ in = val.data;
+ dSession = in.getDerValue();
+ source_session = dSession.getOctetString();
+ dPri = in.getDerValue();
+ pri = dPri.getOctetString();
+ source_rsaWrap = mSourceToken.getKeyWrapper(
+ KeyWrapAlgorithm.RSA);
+ source_rsaWrap.initUnwrap(mUnwrapPrivateKey, null);
+ sk = source_rsaWrap.unwrapSymmetric(source_session,
+ SymmetricKey.DES3,
+ SymmetricKey.Usage.DECRYPT,
+ 0);
+ if (mDebug) {
+ log("DEBUG: sk = '"
+ + Utils.base64encode(sk.getEncoded())
+ + "' length = '"
+ + sk.getEncoded().length
+ + "'"
+ + NEWLINE, false);
+ log("DEBUG: pri = '"
+ + Utils.base64encode(pri)
+ + "' length = '"
+ + pri.length
+ + "'"
+ + NEWLINE, false);
+ }
+ } catch (IOException exUnwrapIO) {
+ log("ERROR: Unwrapping key data - "
+ + "IOException: '"
+ + exUnwrapIO.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ } catch (NoSuchAlgorithmException exUnwrapAlgorithm) {
+ log("ERROR: Unwrapping key data - "
+ + "NoSuchAlgorithmException: '"
+ + exUnwrapAlgorithm.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ } catch (TokenException exUnwrapToken) {
+ log("ERROR: Unwrapping key data - "
+ + "TokenException: '"
+ + exUnwrapToken.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ } catch (InvalidKeyException exUnwrapInvalidKey) {
+ log("ERROR: Unwrapping key data - "
+ + "InvalidKeyException: '"
+ + exUnwrapInvalidKey.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ } catch (InvalidAlgorithmParameterException exUnwrapInvalidAlgorithm) {
+ log("ERROR: Unwrapping key data - "
+ + "InvalidAlgorithmParameterException: '"
+ + exUnwrapInvalidAlgorithm.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ } catch (IllegalStateException exUnwrapState) {
+ log("ERROR: Unwrapping key data - "
+ + "InvalidStateException: '"
+ + exUnwrapState.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ }
+
+ // public byte[]
+ // mStorageUnit.encryptInternalPrivate( byte priKey[] )
+ // throws EBaseException
+ try {
+ // Use "mSourceToken" to get "KeyWrapAlgorithm.RSA"
+ target_rsaWrap = mSourceToken.getKeyWrapper(
+ KeyWrapAlgorithm.RSA);
+ target_rsaWrap.initWrap(mWrapPublicKey, null);
+ target_session = target_rsaWrap.wrap(sk);
+
+ tmp = new DerOutputStream();
+ out = new DerOutputStream();
+
+ tmp.putOctetString(target_session);
+ tmp.putOctetString(pri);
+ out.write(DerValue.tag_Sequence, tmp);
+
+ rewrappedKeyData = out.toByteArray();
+ } catch (NoSuchAlgorithmException exWrapAlgorithm) {
+ log("ERROR: Wrapping key data - "
+ + "NoSuchAlgorithmException: '"
+ + exWrapAlgorithm.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ } catch (TokenException exWrapToken) {
+ log("ERROR: Wrapping key data - "
+ + "TokenException: '"
+ + exWrapToken.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ } catch (InvalidKeyException exWrapInvalidKey) {
+ log("ERROR: Wrapping key data - "
+ + "InvalidKeyException: '"
+ + exWrapInvalidKey.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ } catch (InvalidAlgorithmParameterException exWrapInvalidAlgorithm) {
+ log("ERROR: Wrapping key data - "
+ + "InvalidAlgorithmParameterException: '"
+ + exWrapInvalidAlgorithm.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ } catch (IllegalStateException exWrapState) {
+ log("ERROR: Wrapping key data - "
+ + "InvalidStateException: '"
+ + exWrapState.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ } catch (IOException exWrapIO) {
+ log("ERROR: Wrapping key data - "
+ + "IOException: '"
+ + exWrapIO.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ }
+
+ return rewrappedKeyData;
+ }
+
+ /**
+ * Helper method used to remove all EOLs ('\n' and '\r')
+ * from the passed in string.
+ * <P>
+ *
+ * @param data consisting of a string containing EOLs
+ * @return a string consisting of a string with no EOLs
+ */
+ private static String stripEOL(String data) {
+ StringBuffer buffer = new StringBuffer();
+ String revised_data = null;
+
+ for (int i = 0; i < data.length(); i++) {
+ if ((data.charAt(i) != '\n') &&
+ (data.charAt(i) != '\r')) {
+ buffer.append(data.charAt(i));
+ }
+ }
+
+ revised_data = buffer.toString();
+
+ return revised_data;
+ }
+
+ /**
+ * Helper method used to format a string containing unformatted data
+ * into a string containing formatted data suitable as an entry for
+ * an LDIF file.
+ * <P>
+ *
+ * @param length the length of the first line of data
+ * @param data a string containing unformatted data
+ * @return formatted data consisting of data formatted for an LDIF record
+ * suitable for an LDIF file
+ */
+ private static String format_ldif_data(int length, String data) {
+ String revised_data = "";
+
+ if (data.length() > length) {
+ // process first line
+ for (int i = 0; i < length; i++) {
+ revised_data += data.charAt(i);
+ }
+
+ // terminate first line
+ revised_data += '\n';
+
+ // process remaining lines
+ int j = 0;
+ for (int i = length; i < data.length(); i++) {
+ if (j == 0) {
+ revised_data += ' ';
+ }
+
+ revised_data += data.charAt(i);
+
+ j++;
+
+ if (j == 76) {
+ revised_data += '\n';
+ j = 0;
+ }
+ }
+ }
+
+ return revised_data.replaceAll("\\s+$", "");
+ }
+
+ /*********************/
+ /* ID Offset Methods */
+ /*********************/
+
+ /**
+ * Helper method which converts an "indexed" BigInteger into
+ * its String representation.
+ *
+ * <PRE>
+ *
+ * NOTE: Indexed data means that the numeric data
+ * is stored with a prepended length
+ * (e. g. - record '73' is stored as '0273').
+ *
+ * Indexed data is currently limited to '99' digits
+ * (an index of '00' is invalid). See
+ * 'com.netscape.cmscore.dbs.BigIntegerMapper.java'
+ * for details.
+ *
+ * </PRE>
+ *
+ * This method is based upon code from
+ * 'com.netscape.cmscore.dbs.BigIntegerMapper'.
+ * <P>
+ *
+ * @param i an "indexed " BigInteger
+ * @return the string representation of the "indexed" BigInteger
+ */
+ private 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;
+ }
+
+ /**
+ * Helper method which converts the string representation of an
+ * "indexed" integer into a BigInteger.
+ *
+ * <PRE>
+ * NOTE: Indexed data means that the numeric data
+ * is stored with a prepended length
+ * (e. g. - record '73' is stored as '0273').
+ *
+ * Indexed data is currently limited to '99' digits
+ * (an index of '00' is invalid). See
+ * 'com.netscape.cmscore.dbs.BigIntegerMapper.java'
+ * for details.
+ * </PRE>
+ *
+ * This method is based upon code from
+ * 'com.netscape.cmscore.dbs.BigIntegerMapper'.
+ * <P>
+ *
+ * @param i the string representation of the "indexed" integer
+ * @return an "indexed " BigInteger
+ */
+ private static BigInteger BigIntegerFromDB(String i) {
+ String s = i.substring(2);
+
+ // possibly check length
+ return new BigInteger(s);
+ }
+
+ /**
+ * This method accepts an "attribute", its "delimiter", a string
+ * representation of numeric data, and a flag indicating whether
+ * or not the string representation is "indexed".
+ *
+ * An "attribute" consists of one of the following values:
+ *
+ * <PRE>
+ * DRM_LDIF_CN = "cn:";
+ * DRM_LDIF_DN_EMBEDDED_CN_DATA = "dn: cn";
+ * DRM_LDIF_EXTDATA_KEY_RECORD = "extdata-keyrecord:";
+ * DRM_LDIF_EXTDATA_REQUEST_ID = "extdata-requestid:";
+ * DRM_LDIF_EXTDATA_SERIAL_NUMBER = "extdata-serialnumber:";
+ * DRM_LDIF_REQUEST_ID = "requestId:";
+ * DRM_LDIF_SERIAL_NO = "serialno:";
+ *
+ *
+ * NOTE: Indexed data means that the numeric data
+ * is stored with a prepended length
+ * (e. g. - record '73' is stored as '0273').
+ *
+ * Indexed data is currently limited to '99' digits
+ * (an index of '00' is invalid). See
+ * 'com.netscape.cmscore.dbs.BigIntegerMapper.java'
+ * for details.
+ * </PRE>
+ *
+ * <P>
+ *
+ * @param attribute the string representation of the "name"
+ * @param delimiter the separator between the attribute and its contents
+ * @param source_line the string containing the "name" and "value"
+ * @param indexed boolean flag indicating if the "value" is "indexed"
+ * @return a revised line containing the "name" and "value" with the
+ * specified ID offset applied as a "mask" to the "value"
+ */
+ private static String compose_numeric_line(String attribute,
+ String delimiter,
+ String source_line,
+ boolean indexed) {
+ String target_line = null;
+ String data = null;
+ String revised_data = null;
+ BigInteger value = null;
+
+ // Since both "-append_id_offset" and "-remove_id_offset" are OPTIONAL
+ // parameters, first check to see if either has been selected
+ if (!mAppendIdOffsetFlag &&
+ !mRemoveIdOffsetFlag) {
+ return source_line;
+ }
+
+ try {
+ // extract the data
+ data = source_line.substring(attribute.length() + 1).trim();
+
+ // skip values which are non-numeric
+ if (!data.matches("[0-9]++")) {
+ // set the target_line to the unchanged source_line
+ target_line = source_line;
+
+ // log this information
+ log("Skipped changing non-numeric line '"
+ + source_line
+ + "'."
+ + NEWLINE, false);
+ } else {
+ // if indexed, first strip the index from the data
+ if (indexed) {
+ // NOTE: Indexed data means that the numeric data
+ // is stored with a prepended length
+ // (e. g. - record '73' is stored as '0273').
+ //
+ // Indexed data is currently limited to '99' digits
+ // (an index of '00' is invalid). See
+ // 'com.netscape.cmscore.dbs.BigIntegerMapper.java'
+ // for details.
+ value = BigIntegerFromDB(data);
+ } else {
+ value = new BigInteger(data);
+ }
+
+ // compare the specified target ID offset
+ // with the actual value of the attribute
+ if (mAppendIdOffsetFlag) {
+ if (mAppendIdOffset.compareTo(value) == 1) {
+ // add the target ID offset to this value
+ if (indexed) {
+ revised_data = BigIntegerToDB(
+ value.add(mAppendIdOffset)
+ ).toString();
+ } else {
+ revised_data = value.add(
+ mAppendIdOffset).toString();
+ }
+ } else {
+ log("ERROR: attribute='"
+ + attribute
+ + "' is greater than the specified "
+ + "append_id_offset='"
+ + mAppendIdOffset.toString()
+ + "'!"
+ + NEWLINE, true);
+ System.exit(0);
+ }
+ } else if (mRemoveIdOffsetFlag) {
+ if (mRemoveIdOffset.compareTo(value) <= 0) {
+ // subtract the target ID offset to this value
+ if (indexed) {
+ revised_data = BigIntegerToDB(
+ value.subtract(mRemoveIdOffset)
+ ).toString();
+ } else {
+ revised_data = value.subtract(mRemoveIdOffset
+ ).toString();
+ }
+ } else {
+ log("ERROR: attribute='"
+ + attribute
+ + "' is less than the specified "
+ + "remove_id_offset='"
+ + mRemoveIdOffset.toString()
+ + "'!"
+ + NEWLINE, true);
+ System.exit(0);
+ }
+ }
+
+ // set the target_line to the revised data
+ target_line = attribute + delimiter + revised_data;
+
+ // log this information
+ log("Changed numeric data '"
+ + data
+ + "' to '"
+ + revised_data
+ + "'."
+ + NEWLINE, false);
+ }
+ } catch (IndexOutOfBoundsException exBounds) {
+ log("ERROR: source_line='"
+ + source_line
+ + "' IndexOutOfBoundsException: '"
+ + exBounds.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ } catch (PatternSyntaxException exPattern) {
+ log("ERROR: data='"
+ + data
+ + "' PatternSyntaxException: '"
+ + exPattern.toString()
+ + "'"
+ + NEWLINE, true);
+ System.exit(0);
+ }
+
+ return target_line;
+ }
+
+ /***********************/
+ /* LDIF Parser Methods */
+ /***********************/
+
+ /**
+ * Helper method which composes the output line for DRM_LDIF_CN.
+ * <P>
+ *
+ * @param record_type the string representation of the input record type
+ * @param line the string representation of the input line
+ * @return the composed output line
+ */
+ private static String output_cn(String record_type,
+ String line) {
+ String output = null;
+
+ if (record_type.equals(DRM_LDIF_ENROLLMENT)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_ENROLLMENT_CN)) {
+ output = compose_numeric_line(DRM_LDIF_CN,
+ SPACE,
+ line,
+ false);
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_CA_KEY_RECORD)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_CA_KEY_RECORD_CN)) {
+ output = compose_numeric_line(DRM_LDIF_CN,
+ SPACE,
+ line,
+ false);
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_RECOVERY)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_RECOVERY_CN)) {
+ output = compose_numeric_line(DRM_LDIF_CN,
+ SPACE,
+ line,
+ false);
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_TPS_KEY_RECORD)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_TPS_KEY_RECORD_CN)) {
+ output = compose_numeric_line(DRM_LDIF_CN,
+ SPACE,
+ line,
+ false);
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_KEYGEN)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_KEYGEN_CN)) {
+ output = compose_numeric_line(DRM_LDIF_CN,
+ SPACE,
+ line,
+ false);
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_RECORD)) {
+ // Non-Request / Non-Key Record:
+ // Pass through the original
+ // 'cn' line UNCHANGED
+ // so that it is ALWAYS written
+ output = line;
+ } else {
+ log("ERROR: Mismatched record field='"
+ + DRM_LDIF_CN
+ + "' for record type='"
+ + record_type
+ + "'!"
+ + NEWLINE, true);
+ }
+
+ return output;
+ }
+
+ /**
+ * Helper method which composes the output line for DRM_LDIF_DATE_OF_MODIFY.
+ * <P>
+ *
+ * @param record_type the string representation of the input record type
+ * @param line the string representation of the input line
+ * @return the composed output line
+ */
+ private static String output_date_of_modify(String record_type,
+ String line) {
+ String output = null;
+
+ if (record_type.equals(DRM_LDIF_ENROLLMENT)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_ENROLLMENT_DATE_OF_MODIFY)) {
+ output = DRM_LDIF_DATE_OF_MODIFY
+ + SPACE
+ + mDateOfModify;
+
+ log("Changed '"
+ + line
+ + "' to '"
+ + output
+ + "'."
+ + NEWLINE, false);
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_CA_KEY_RECORD)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_CA_KEY_RECORD_DATE_OF_MODIFY)) {
+ output = DRM_LDIF_DATE_OF_MODIFY
+ + SPACE
+ + mDateOfModify;
+
+ log("Changed '"
+ + line
+ + "' to '"
+ + output
+ + "'."
+ + NEWLINE, false);
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_RECOVERY)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_RECOVERY_DATE_OF_MODIFY)) {
+ output = DRM_LDIF_DATE_OF_MODIFY
+ + SPACE
+ + mDateOfModify;
+
+ log("Changed '"
+ + line
+ + "' to '"
+ + output
+ + "'."
+ + NEWLINE, false);
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_TPS_KEY_RECORD)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_TPS_KEY_RECORD_DATE_OF_MODIFY)) {
+ output = DRM_LDIF_DATE_OF_MODIFY
+ + SPACE
+ + mDateOfModify;
+
+ log("Changed '"
+ + line
+ + "' to '"
+ + output
+ + "'."
+ + NEWLINE, false);
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_KEYGEN)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_KEYGEN_DATE_OF_MODIFY)) {
+ output = DRM_LDIF_DATE_OF_MODIFY
+ + SPACE
+ + mDateOfModify;
+
+ log("Changed '"
+ + line
+ + "' to '"
+ + output
+ + "'."
+ + NEWLINE, false);
+ } else {
+ output = line;
+ }
+ } else {
+ log("ERROR: Mismatched record field='"
+ + DRM_LDIF_DATE_OF_MODIFY
+ + "' for record type='"
+ + record_type
+ + "'!"
+ + NEWLINE, true);
+ }
+
+ return output;
+ }
+
+ /**
+ * Helper method which composes the output line for DRM_LDIF_DN.
+ * <P>
+ *
+ * @param record_type the string representation of the input record type
+ * @param line the string representation of the input line
+ * @return the composed output line
+ */
+ private static String output_dn(String record_type,
+ String line) {
+ String embedded_cn_data[] = null;
+ String embedded_cn_output = null;
+ String input = null;
+ String output = null;
+
+ try {
+ if (record_type.equals(DRM_LDIF_ENROLLMENT)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_ENROLLMENT_DN)) {
+
+ // First check for an embedded "cn=<value>"
+ // name-value pair
+ if (line.startsWith(DRM_LDIF_DN_EMBEDDED_CN_DATA)) {
+ // At this point, always extract
+ // the embedded "cn=<value>" name-value pair
+ // which will ALWAYS be the first
+ // portion of the "dn: " attribute
+ embedded_cn_data = line.split(COMMA, 2);
+
+ embedded_cn_output = compose_numeric_line(
+ DRM_LDIF_DN_EMBEDDED_CN_DATA,
+ EQUAL_SIGN,
+ embedded_cn_data[0],
+ false);
+
+ input = embedded_cn_output
+ + COMMA
+ + embedded_cn_data[1];
+ } else {
+ input = line;
+ }
+
+ // Since "-source_drm_naming_context", and
+ // "-target_drm_naming_context" are OPTIONAL
+ // parameters, ONLY process this portion of the field
+ // if both of these options have been selected
+ if (mDrmNamingContextsFlag) {
+ output = input.replace(mSourceDrmNamingContext,
+ mTargetDrmNamingContext);
+ } else {
+ output = input;
+ }
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_CA_KEY_RECORD)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_CA_KEY_RECORD_DN)) {
+
+ // First check for an embedded "cn=<value>"
+ // name-value pair
+ if (line.startsWith(DRM_LDIF_DN_EMBEDDED_CN_DATA)) {
+ // At this point, always extract
+ // the embedded "cn=<value>" name-value pair
+ // which will ALWAYS be the first
+ // portion of the "dn: " attribute
+ embedded_cn_data = line.split(COMMA, 2);
+
+ embedded_cn_output = compose_numeric_line(
+ DRM_LDIF_DN_EMBEDDED_CN_DATA,
+ EQUAL_SIGN,
+ embedded_cn_data[0],
+ false);
+
+ input = embedded_cn_output
+ + COMMA
+ + embedded_cn_data[1];
+ } else {
+ input = line;
+ }
+
+ // Since "-source_drm_naming_context", and
+ // "-target_drm_naming_context" are OPTIONAL
+ // parameters, ONLY process this portion of the field
+ // if both of these options have been selected
+ if (mDrmNamingContextsFlag) {
+ output = input.replace(mSourceDrmNamingContext,
+ mTargetDrmNamingContext);
+ } else {
+ output = input;
+ }
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_RECOVERY)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_RECOVERY_DN)) {
+
+ // First check for an embedded "cn=<value>"
+ // name-value pair
+ if (line.startsWith(DRM_LDIF_DN_EMBEDDED_CN_DATA)) {
+ // At this point, always extract
+ // the embedded "cn=<value>" name-value pair
+ // which will ALWAYS be the first
+ // portion of the "dn: " attribute
+ embedded_cn_data = line.split(COMMA, 2);
+
+ embedded_cn_output = compose_numeric_line(
+ DRM_LDIF_DN_EMBEDDED_CN_DATA,
+ EQUAL_SIGN,
+ embedded_cn_data[0],
+ false);
+
+ input = embedded_cn_output
+ + COMMA
+ + embedded_cn_data[1];
+ } else {
+ input = line;
+ }
+
+ // Since "-source_drm_naming_context", and
+ // "-target_drm_naming_context" are OPTIONAL
+ // parameters, ONLY process this portion of the field
+ // if both of these options have been selected
+ if (mDrmNamingContextsFlag) {
+ output = input.replace(mSourceDrmNamingContext,
+ mTargetDrmNamingContext);
+ } else {
+ output = input;
+ }
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_TPS_KEY_RECORD)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_TPS_KEY_RECORD_DN)) {
+
+ // First check for an embedded "cn=<value>"
+ // name-value pair
+ if (line.startsWith(DRM_LDIF_DN_EMBEDDED_CN_DATA)) {
+ // At this point, always extract
+ // the embedded "cn=<value>" name-value pair
+ // which will ALWAYS be the first
+ // portion of the "dn: " attribute
+ embedded_cn_data = line.split(COMMA, 2);
+
+ embedded_cn_output = compose_numeric_line(
+ DRM_LDIF_DN_EMBEDDED_CN_DATA,
+ EQUAL_SIGN,
+ embedded_cn_data[0],
+ false);
+
+ input = embedded_cn_output
+ + COMMA
+ + embedded_cn_data[1];
+ } else {
+ input = line;
+ }
+
+ // Since "-source_drm_naming_context", and
+ // "-target_drm_naming_context" are OPTIONAL
+ // parameters, ONLY process this portion of the field
+ // if both of these options have been selected
+ if (mDrmNamingContextsFlag) {
+ output = input.replace(mSourceDrmNamingContext,
+ mTargetDrmNamingContext);
+ } else {
+ output = input;
+ }
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_KEYGEN)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_KEYGEN_DN)) {
+
+ // First check for an embedded "cn=<value>"
+ // name-value pair
+ if (line.startsWith(DRM_LDIF_DN_EMBEDDED_CN_DATA)) {
+ // At this point, always extract
+ // the embedded "cn=<value>" name-value pair
+ // which will ALWAYS be the first
+ // portion of the "dn: " attribute
+ embedded_cn_data = line.split(COMMA, 2);
+
+ embedded_cn_output = compose_numeric_line(
+ DRM_LDIF_DN_EMBEDDED_CN_DATA,
+ EQUAL_SIGN,
+ embedded_cn_data[0],
+ false);
+
+ input = embedded_cn_output
+ + COMMA
+ + embedded_cn_data[1];
+ } else {
+ input = line;
+ }
+
+ // Since "-source_drm_naming_context", and
+ // "-target_drm_naming_context" are OPTIONAL
+ // parameters, ONLY process this portion of the field
+ // if both of these options have been selected
+ if (mDrmNamingContextsFlag) {
+ output = input.replace(mSourceDrmNamingContext,
+ mTargetDrmNamingContext);
+ } else {
+ output = input;
+ }
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_RECORD)) {
+ // Non-Request / Non-Key Record:
+ // Pass through the original
+ // 'dn' line UNCHANGED
+ // so that it is ALWAYS written
+ output = line;
+ } else {
+ log("ERROR: Mismatched record field='"
+ + DRM_LDIF_DN
+ + "' for record type='"
+ + record_type
+ + "'!"
+ + NEWLINE, true);
+ }
+ } catch (PatternSyntaxException exDnEmbeddedCnNameValuePattern) {
+ log("ERROR: line='"
+ + line
+ + "' PatternSyntaxException: '"
+ + exDnEmbeddedCnNameValuePattern.toString()
+ + "'"
+ + NEWLINE, true);
+ } catch (NullPointerException exNullPointerException) {
+ log("ERROR: Unable to replace source DRM naming context '"
+ + mSourceDrmNamingContext
+ + "' with target DRM naming context '"
+ + mTargetDrmNamingContext
+ + "' NullPointerException: '"
+ + exNullPointerException.toString()
+ + "'"
+ + NEWLINE, true);
+ }
+
+ return output;
+ }
+
+ /**
+ * Helper method which composes the output line for
+ * DRM_LDIF_EXTDATA_KEY_RECORD.
+ * <P>
+ *
+ * @param record_type the string representation of the input record type
+ * @param line the string representation of the input line
+ * @return the composed output line
+ */
+ private static String output_extdata_key_record(String record_type,
+ String line) {
+ String output = null;
+
+ if (record_type.equals(DRM_LDIF_ENROLLMENT)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_ENROLLMENT_EXTDATA_KEY_RECORD)) {
+ output = compose_numeric_line(DRM_LDIF_EXTDATA_KEY_RECORD,
+ SPACE,
+ line,
+ false);
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_KEYGEN)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_KEYGEN_EXTDATA_KEY_RECORD)) {
+ output = compose_numeric_line(DRM_LDIF_EXTDATA_KEY_RECORD,
+ SPACE,
+ line,
+ false);
+ } else {
+ output = line;
+ }
+ } else {
+ log("ERROR: Mismatched record field='"
+ + DRM_LDIF_EXTDATA_KEY_RECORD
+ + "' for record type='"
+ + record_type
+ + "'!"
+ + NEWLINE, true);
+ }
+
+ return output;
+ }
+
+ /**
+ * Helper method which composes the output line for
+ * DRM_LDIF_EXTDATA_REQUEST_ID.
+ * <P>
+ *
+ * @param record_type the string representation of the input record type
+ * @param line the string representation of the input line
+ * @return the composed output line
+ */
+ private static String output_extdata_request_id(String record_type,
+ String line) {
+ String output = null;
+
+ if (record_type.equals(DRM_LDIF_ENROLLMENT)) {
+ // ALWAYS pass-through "extdata-requestId" for
+ // DRM_LDIF_ENROLLMENT records UNCHANGED because the
+ // value in this field is associated with the issuing CA!
+ output = line;
+ } else if (record_type.equals(DRM_LDIF_RECOVERY)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_RECOVERY_EXTDATA_REQUEST_ID)) {
+ output = compose_numeric_line(DRM_LDIF_EXTDATA_REQUEST_ID,
+ SPACE,
+ line,
+ false);
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_KEYGEN)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_KEYGEN_EXTDATA_REQUEST_ID)) {
+ output = compose_numeric_line(DRM_LDIF_EXTDATA_REQUEST_ID,
+ SPACE,
+ line,
+ false);
+ } else {
+ output = line;
+ }
+ } else {
+ log("ERROR: Mismatched record field='"
+ + DRM_LDIF_EXTDATA_REQUEST_ID
+ + "' for record type='"
+ + record_type
+ + "'!"
+ + NEWLINE, true);
+ }
+
+ return output;
+ }
+
+ /**
+ * Helper method which composes the output line for
+ * DRM_LDIF_EXTDATA_REQUEST_NOTES.
+ * <P>
+ *
+ * @param record_type the string representation of the input record type
+ * @param line the string representation of the input line
+ * @return the composed output line
+ */
+ private static String output_extdata_request_notes(String record_type,
+ String line) {
+ String input = null;
+ String data = null;
+ String unformatted_data = null;
+ String output = null;
+ String next_line = null;
+
+ // extract the data
+ if (line.length() > DRM_LDIF_EXTDATA_REQUEST_NOTES.length()) {
+ input = line.substring(
+ DRM_LDIF_EXTDATA_REQUEST_NOTES.length() + 1
+ ).trim();
+ } else {
+ input = line.substring(
+ DRM_LDIF_EXTDATA_REQUEST_NOTES.length()
+ ).trim();
+ }
+
+ while ((line = ldif_record.next()) != null) {
+ if (line.startsWith(SPACE)) {
+ // Do NOT use "trim()";
+ // remove single leading space and
+ // trailing carriage returns and newlines ONLY!
+ input += line.replaceFirst(" ", "").replace('\r', '\0').replace('\n', '\0');
+ } else {
+ next_line = line;
+ break;
+ }
+ }
+
+ if (record_type.equals(DRM_LDIF_ENROLLMENT)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_ENROLLMENT_EXTDATA_REQUEST_NOTES)) {
+ // write out a revised 'extdata-requestnotes' line
+ if (mRewrapFlag && mAppendIdOffsetFlag) {
+ data = input
+ + SPACE
+ + LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_REWRAP_MESSAGE
+ + mPublicKeySize
+ + DRM_LDIF_RSA_MESSAGE
+ + mSourcePKISecurityDatabasePwdfileMessage
+ + SPACE
+ + PLUS + SPACE
+ + DRM_LDIF_APPENDED_ID_OFFSET_MESSAGE
+ + SPACE
+ + TIC
+ + mAppendIdOffset.toString()
+ + TIC
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ } else if (mRewrapFlag && mRemoveIdOffsetFlag) {
+ data = input
+ + SPACE
+ + LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_REWRAP_MESSAGE
+ + mPublicKeySize
+ + DRM_LDIF_RSA_MESSAGE
+ + mSourcePKISecurityDatabasePwdfileMessage
+ + SPACE
+ + PLUS + SPACE
+ + DRM_LDIF_REMOVED_ID_OFFSET_MESSAGE
+ + SPACE
+ + TIC
+ + mRemoveIdOffset.toString()
+ + TIC
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ } else if (mRewrapFlag) {
+ data = input
+ + SPACE
+ + LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_REWRAP_MESSAGE
+ + mPublicKeySize
+ + DRM_LDIF_RSA_MESSAGE
+ + mSourcePKISecurityDatabasePwdfileMessage
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ } else if (mAppendIdOffsetFlag) {
+ data = input
+ + SPACE
+ + LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_APPENDED_ID_OFFSET_MESSAGE
+ + SPACE
+ + TIC
+ + mAppendIdOffset.toString()
+ + TIC
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ } else if (mRemoveIdOffsetFlag) {
+ data = input
+ + SPACE
+ + LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_REMOVED_ID_OFFSET_MESSAGE
+ + SPACE
+ + TIC
+ + mRemoveIdOffset.toString()
+ + TIC
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ }
+
+ // log this information
+ log("Changed:"
+ + NEWLINE
+ + TIC
+ + DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ input)
+ + TIC
+ + NEWLINE
+ + "--->"
+ + NEWLINE
+ + TIC
+ + output
+ + TIC
+ + NEWLINE, false);
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_RECOVERY)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_RECOVERY_EXTDATA_REQUEST_NOTES)) {
+ // write out a revised 'extdata-requestnotes' line
+ if (mRewrapFlag && mAppendIdOffsetFlag) {
+ data = input
+ + SPACE
+ + LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_REWRAP_MESSAGE
+ + mPublicKeySize
+ + DRM_LDIF_RSA_MESSAGE
+ + mSourcePKISecurityDatabasePwdfileMessage
+ + SPACE
+ + PLUS + SPACE
+ + DRM_LDIF_APPENDED_ID_OFFSET_MESSAGE
+ + SPACE
+ + TIC
+ + mAppendIdOffset.toString()
+ + TIC
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ } else if (mRewrapFlag && mRemoveIdOffsetFlag) {
+ data = input
+ + SPACE
+ + LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_REWRAP_MESSAGE
+ + mPublicKeySize
+ + DRM_LDIF_RSA_MESSAGE
+ + mSourcePKISecurityDatabasePwdfileMessage
+ + SPACE
+ + PLUS + SPACE
+ + DRM_LDIF_REMOVED_ID_OFFSET_MESSAGE
+ + SPACE
+ + TIC
+ + mRemoveIdOffset.toString()
+ + TIC
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ } else if (mRewrapFlag) {
+ data = input
+ + SPACE
+ + LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_REWRAP_MESSAGE
+ + mPublicKeySize
+ + DRM_LDIF_RSA_MESSAGE
+ + mSourcePKISecurityDatabasePwdfileMessage
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ } else if (mAppendIdOffsetFlag) {
+ data = input
+ + SPACE
+ + LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_APPENDED_ID_OFFSET_MESSAGE
+ + SPACE
+ + TIC
+ + mAppendIdOffset.toString()
+ + TIC
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ } else if (mRemoveIdOffsetFlag) {
+ data = input
+ + SPACE
+ + LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_REMOVED_ID_OFFSET_MESSAGE
+ + SPACE
+ + TIC
+ + mRemoveIdOffset.toString()
+ + TIC
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ }
+
+ // log this information
+ log("Changed:"
+ + NEWLINE
+ + TIC
+ + DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ input)
+ + TIC
+ + NEWLINE
+ + "--->"
+ + NEWLINE
+ + TIC
+ + output
+ + TIC
+ + NEWLINE, false);
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_KEYGEN)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_KEYGEN_EXTDATA_REQUEST_NOTES)) {
+ // write out a revised 'extdata-requestnotes' line
+ if (mRewrapFlag && mAppendIdOffsetFlag) {
+ data = input
+ + SPACE
+ + LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_REWRAP_MESSAGE
+ + mPublicKeySize
+ + DRM_LDIF_RSA_MESSAGE
+ + mSourcePKISecurityDatabasePwdfileMessage
+ + SPACE
+ + PLUS + SPACE
+ + DRM_LDIF_APPENDED_ID_OFFSET_MESSAGE
+ + SPACE
+ + TIC
+ + mAppendIdOffset.toString()
+ + TIC
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ } else if (mRewrapFlag && mRemoveIdOffsetFlag) {
+ data = input
+ + SPACE
+ + LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_REWRAP_MESSAGE
+ + mPublicKeySize
+ + DRM_LDIF_RSA_MESSAGE
+ + mSourcePKISecurityDatabasePwdfileMessage
+ + SPACE
+ + PLUS + SPACE
+ + DRM_LDIF_REMOVED_ID_OFFSET_MESSAGE
+ + SPACE
+ + TIC
+ + mRemoveIdOffset.toString()
+ + TIC
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ } else if (mRewrapFlag) {
+ data = input
+ + SPACE
+ + LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_REWRAP_MESSAGE
+ + mPublicKeySize
+ + DRM_LDIF_RSA_MESSAGE
+ + mSourcePKISecurityDatabasePwdfileMessage
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ } else if (mAppendIdOffsetFlag) {
+ data = input
+ + SPACE
+ + LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_APPENDED_ID_OFFSET_MESSAGE
+ + SPACE
+ + TIC
+ + mAppendIdOffset.toString()
+ + TIC
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ } else if (mRemoveIdOffsetFlag) {
+ data = input
+ + SPACE
+ + LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_REMOVED_ID_OFFSET_MESSAGE
+ + SPACE
+ + TIC
+ + mRemoveIdOffset.toString()
+ + TIC
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ }
+
+ // log this information
+ log("Changed:"
+ + NEWLINE
+ + TIC
+ + DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ input)
+ + TIC
+ + NEWLINE
+ + "--->"
+ + NEWLINE
+ + TIC
+ + output
+ + TIC
+ + NEWLINE, false);
+ } else {
+ output = line;
+ }
+ } else {
+ log("ERROR: Mismatched record field='"
+ + DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + "' for record type='"
+ + record_type
+ + "'!"
+ + NEWLINE, true);
+ }
+
+ if (output != null) {
+ output += NEWLINE + next_line;
+ }
+
+ return output;
+ }
+
+ /**
+ * Helper method which composes the output line for
+ * DRM_LDIF_EXTDATA_REQUEST_NOTES.
+ * <P>
+ *
+ * @param record_type the string representation of the input record type
+ * @param previous_line the string representation of the previous input line
+ * @param writer the PrintWriter used to output this new LDIF line
+ * @return the composed output line
+ */
+ private static void create_extdata_request_notes(String record_type,
+ String previous_line,
+ PrintWriter writer) {
+ String data = null;
+ String unformatted_data = null;
+ String output = null;
+
+ if (record_type.equals(DRM_LDIF_RECOVERY)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_RECOVERY_EXTDATA_REQUEST_NOTES)) {
+ if (!previous_line.startsWith(DRM_LDIF_EXTDATA_REQUEST_NOTES)) {
+ // write out the missing 'extdata-requestnotes' line
+ if (mRewrapFlag && mAppendIdOffsetFlag) {
+ data = LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_REWRAP_MESSAGE
+ + mPublicKeySize
+ + DRM_LDIF_RSA_MESSAGE
+ + mSourcePKISecurityDatabasePwdfileMessage
+ + SPACE
+ + PLUS + SPACE
+ + DRM_LDIF_APPENDED_ID_OFFSET_MESSAGE
+ + SPACE
+ + TIC
+ + mAppendIdOffset.toString()
+ + TIC
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ } else if (mRewrapFlag && mRemoveIdOffsetFlag) {
+ data = LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_REWRAP_MESSAGE
+ + mPublicKeySize
+ + DRM_LDIF_RSA_MESSAGE
+ + mSourcePKISecurityDatabasePwdfileMessage
+ + SPACE
+ + PLUS + SPACE
+ + DRM_LDIF_REMOVED_ID_OFFSET_MESSAGE
+ + SPACE
+ + TIC
+ + mRemoveIdOffset.toString()
+ + TIC
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ } else if (mRewrapFlag) {
+ data = LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_REWRAP_MESSAGE
+ + mPublicKeySize
+ + DRM_LDIF_RSA_MESSAGE
+ + mSourcePKISecurityDatabasePwdfileMessage
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ } else if (mAppendIdOffsetFlag) {
+ data = LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_APPENDED_ID_OFFSET_MESSAGE
+ + SPACE
+ + TIC
+ + mAppendIdOffset.toString()
+ + TIC
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ } else if (mRemoveIdOffsetFlag) {
+ data = LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_REMOVED_ID_OFFSET_MESSAGE
+ + SPACE
+ + TIC
+ + mRemoveIdOffset.toString()
+ + TIC
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ }
+
+ // log this information
+ log("Created:"
+ + NEWLINE
+ + TIC
+ + output
+ + TIC
+ + NEWLINE, false);
+
+ // Write out this revised line
+ // and flush the buffer
+ writer.write(output + NEWLINE);
+ writer.flush();
+ System.out.print(".");
+ }
+ }
+ } else if (record_type.equals(DRM_LDIF_KEYGEN)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_KEYGEN_EXTDATA_REQUEST_NOTES)) {
+ if (!previous_line.startsWith(DRM_LDIF_EXTDATA_REQUEST_NOTES)) {
+ // write out the missing 'extdata-requestnotes' line
+ if (mRewrapFlag && mAppendIdOffsetFlag) {
+ data = LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_REWRAP_MESSAGE
+ + mPublicKeySize
+ + DRM_LDIF_RSA_MESSAGE
+ + mSourcePKISecurityDatabasePwdfileMessage
+ + SPACE
+ + PLUS + SPACE
+ + DRM_LDIF_APPENDED_ID_OFFSET_MESSAGE
+ + SPACE
+ + TIC
+ + mAppendIdOffset.toString()
+ + TIC
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ } else if (mRewrapFlag && mRemoveIdOffsetFlag) {
+ data = LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_REWRAP_MESSAGE
+ + mPublicKeySize
+ + DRM_LDIF_RSA_MESSAGE
+ + mSourcePKISecurityDatabasePwdfileMessage
+ + SPACE
+ + PLUS + SPACE
+ + DRM_LDIF_REMOVED_ID_OFFSET_MESSAGE
+ + SPACE
+ + TIC
+ + mRemoveIdOffset.toString()
+ + TIC
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ } else if (mRewrapFlag) {
+ data = LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_REWRAP_MESSAGE
+ + mPublicKeySize
+ + DRM_LDIF_RSA_MESSAGE
+ + mSourcePKISecurityDatabasePwdfileMessage
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ } else if (mAppendIdOffsetFlag) {
+ data = LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_APPENDED_ID_OFFSET_MESSAGE
+ + SPACE
+ + TIC
+ + mAppendIdOffset.toString()
+ + TIC
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ } else if (mRemoveIdOffsetFlag) {
+ data = LEFT_BRACE
+ + mDateOfModify
+ + RIGHT_BRACE
+ + COLON + SPACE
+ + DRM_LDIF_REMOVED_ID_OFFSET_MESSAGE
+ + SPACE
+ + TIC
+ + mRemoveIdOffset.toString()
+ + TIC
+ + mDrmNamingContextMessage
+ + mProcessRequestsAndKeyRecordsOnlyMessage;
+
+ // Unformat the data
+ unformatted_data = stripEOL(data);
+
+ // Format the unformatted_data
+ // to match the desired LDIF format
+ output = DRM_LDIF_EXTDATA_REQUEST_NOTES
+ + SPACE
+ + format_ldif_data(
+ EXTDATA_REQUEST_NOTES_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+ }
+
+ // log this information
+ log("Created:"
+ + NEWLINE
+ + TIC
+ + output
+ + TIC
+ + NEWLINE, false);
+
+ // Write out this revised line
+ // and flush the buffer
+ writer.write(output + NEWLINE);
+ writer.flush();
+ System.out.print(".");
+ }
+ }
+ }
+ }
+
+ /**
+ * Helper method which composes the output line for
+ * DRM_LDIF_EXTDATA_SERIAL_NUMBER.
+ * <P>
+ *
+ * @param record_type the string representation of the input record type
+ * @param line the string representation of the input line
+ * @return the composed output line
+ */
+ private static String output_extdata_serial_number(String record_type,
+ String line) {
+ String output = null;
+
+ if (record_type.equals(DRM_LDIF_RECOVERY)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_RECOVERY_EXTDATA_SERIAL_NUMBER)) {
+ output = compose_numeric_line(DRM_LDIF_EXTDATA_SERIAL_NUMBER,
+ SPACE,
+ line,
+ false);
+ } else {
+ output = line;
+ }
+ } else {
+ log("ERROR: Mismatched record field='"
+ + DRM_LDIF_EXTDATA_SERIAL_NUMBER
+ + "' for record type='"
+ + record_type
+ + "'!"
+ + NEWLINE, true);
+ }
+
+ return output;
+ }
+
+ /**
+ * Helper method which composes the output line for
+ * DRM_LDIF_PRIVATE_KEY_DATA.
+ * <P>
+ *
+ * @param record_type the string representation of the input record type
+ * @param line the string representation of the input line
+ * @return the composed output line
+ */
+ private static String output_private_key_data(String record_type,
+ String line) {
+ byte source_wrappedKeyData[] = null;
+ byte target_wrappedKeyData[] = null;
+ String data = null;
+ String revised_data = null;
+ String unformatted_data = null;
+ String formatted_data = null;
+ String output = null;
+
+ try {
+ if (record_type.equals(DRM_LDIF_CA_KEY_RECORD)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_CA_KEY_RECORD_PRIVATE_KEY_DATA)) {
+ // Since "-source_pki_security_database_path",
+ // "-source_storage_token_name",
+ // "-source_storage_certificate_nickname", and
+ // "-target_storage_certificate_file" are OPTIONAL
+ // parameters, ONLY process this field if all of
+ // these options have been selected
+ if (mRewrapFlag) {
+ // extract the data
+ data = line.substring(
+ DRM_LDIF_PRIVATE_KEY_DATA.length() + 1
+ ).trim();
+
+ while ((line = ldif_record.next()) != null) {
+ if (line.startsWith(SPACE)) {
+ data += line.trim();
+ } else {
+ break;
+ }
+ }
+
+ // Decode the ASCII BASE 64 certificate
+ // enclosed in the String() object
+ // into a BINARY BASE 64 byte[] object
+ source_wrappedKeyData =
+ Utils.base64decode(data);
+
+ // rewrap the source wrapped private key data
+ target_wrappedKeyData = rewrap_wrapped_key_data(
+ source_wrappedKeyData);
+
+ // Encode the BINARY BASE 64 byte[] object
+ // into an ASCII BASE 64 certificate
+ // enclosed in a String() object
+ revised_data = Utils.base64encode(
+ target_wrappedKeyData);
+
+ // Unformat the ASCII BASE 64 certificate
+ // for the log file
+ unformatted_data = stripEOL(revised_data);
+
+ // Format the ASCII BASE 64 certificate
+ // to match the desired LDIF format
+ formatted_data = format_ldif_data(
+ PRIVATE_KEY_DATA_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+
+ // construct a revised 'privateKeyData' line
+ output = DRM_LDIF_PRIVATE_KEY_DATA
+ + SPACE
+ + formatted_data
+ + NEWLINE
+ + line;
+
+ // log this information
+ log("Changed 'privateKeyData' from:"
+ + NEWLINE
+ + TIC
+ + data
+ + TIC
+ + NEWLINE
+ + " to:"
+ + NEWLINE
+ + TIC
+ + unformatted_data
+ + TIC
+ + NEWLINE, false);
+ } else {
+ output = line;
+ }
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_TPS_KEY_RECORD)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_TPS_KEY_RECORD_PRIVATE_KEY_DATA)) {
+ // Since "-source_pki_security_database_path",
+ // "-source_storage_token_name",
+ // "-source_storage_certificate_nickname", and
+ // "-target_storage_certificate_file" are OPTIONAL
+ // parameters, ONLY process this field if all of
+ // these options have been selected
+ if (mRewrapFlag) {
+ // extract the data
+ data = line.substring(
+ DRM_LDIF_PRIVATE_KEY_DATA.length() + 1
+ ).trim();
+
+ while ((line = ldif_record.next()) != null) {
+ if (line.startsWith(SPACE)) {
+ data += line.trim();
+ } else {
+ break;
+ }
+ }
+
+ // Decode the ASCII BASE 64 certificate
+ // enclosed in the String() object
+ // into a BINARY BASE 64 byte[] object
+ source_wrappedKeyData =
+ Utils.base64decode(data);
+
+ // rewrap the source wrapped private key data
+ target_wrappedKeyData = rewrap_wrapped_key_data(
+ source_wrappedKeyData);
+
+ // Encode the BINARY BASE 64 byte[] object
+ // into an ASCII BASE 64 certificate
+ // enclosed in a String() object
+ revised_data = Utils.base64encode(
+ target_wrappedKeyData);
+
+ // Unformat the ASCII BASE 64 certificate
+ // for the log file
+ unformatted_data = stripEOL(revised_data);
+
+ // Format the ASCII BASE 64 certificate
+ // to match the desired LDIF format
+ formatted_data = format_ldif_data(
+ PRIVATE_KEY_DATA_FIRST_LINE_DATA_LENGTH,
+ unformatted_data);
+
+ // construct a revised 'privateKeyData' line
+ output = DRM_LDIF_PRIVATE_KEY_DATA
+ + SPACE
+ + formatted_data
+ + NEWLINE
+ + line;
+
+ // log this information
+ log("Changed 'privateKeyData' from:"
+ + NEWLINE
+ + TIC
+ + data
+ + TIC
+ + NEWLINE
+ + " to:"
+ + NEWLINE
+ + TIC
+ + unformatted_data
+ + TIC
+ + NEWLINE, false);
+ } else {
+ output = line;
+ }
+ } else {
+ output = line;
+ }
+ } else {
+ log("ERROR: Mismatched record field='"
+ + DRM_LDIF_PRIVATE_KEY_DATA
+ + "' for record type='"
+ + record_type
+ + "'!"
+ + NEWLINE, true);
+ }
+ } catch (Exception exRewrap) {
+ log("ERROR: Unable to rewrap BINARY BASE 64 data. "
+ + "Exception: '"
+ + exRewrap.toString()
+ + "'"
+ + NEWLINE, true);
+ }
+
+ return output;
+ }
+
+ /**
+ * Helper method which composes the output line for DRM_LDIF_REQUEST_ID.
+ * <P>
+ *
+ * @param record_type the string representation of the input record type
+ * @param line the string representation of the input line
+ * @return the composed output line
+ */
+ private static String output_request_id(String record_type,
+ String line) {
+ String output = null;
+
+ if (record_type.equals(DRM_LDIF_ENROLLMENT)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_ENROLLMENT_REQUEST_ID)) {
+ output = compose_numeric_line(DRM_LDIF_REQUEST_ID,
+ SPACE,
+ line,
+ true);
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_RECOVERY)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_RECOVERY_REQUEST_ID)) {
+ output = compose_numeric_line(DRM_LDIF_REQUEST_ID,
+ SPACE,
+ line,
+ true);
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_KEYGEN)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_KEYGEN_REQUEST_ID)) {
+ output = compose_numeric_line(DRM_LDIF_REQUEST_ID,
+ SPACE,
+ line,
+ true);
+ } else {
+ output = line;
+ }
+ } else {
+ log("ERROR: Mismatched record field='"
+ + DRM_LDIF_REQUEST_ID
+ + "' for record type='"
+ + record_type
+ + "'!"
+ + NEWLINE, true);
+ }
+
+ return output;
+ }
+
+ /**
+ * Helper method which composes the output line for DRM_LDIF_SERIAL_NO.
+ * <P>
+ *
+ * @param record_type the string representation of the input record type
+ * @param line the string representation of the input line
+ * @return the composed output line
+ */
+ private static String output_serial_no(String record_type,
+ String line) {
+ String output = null;
+
+ if (record_type.equals(DRM_LDIF_CA_KEY_RECORD)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_CA_KEY_RECORD_SERIAL_NO)) {
+ output = compose_numeric_line(DRM_LDIF_SERIAL_NO,
+ SPACE,
+ line,
+ true);
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_TPS_KEY_RECORD)) {
+ if (drmtoolCfg.get(DRMTOOL_CFG_TPS_KEY_RECORD_SERIAL_NO)) {
+ output = compose_numeric_line(DRM_LDIF_SERIAL_NO,
+ SPACE,
+ line,
+ true);
+ } else {
+ output = line;
+ }
+ } else if (record_type.equals(DRM_LDIF_RECORD)) {
+ // Non-Request / Non-Key Record:
+ // Pass through the original
+ // 'serialno' line UNCHANGED
+ // so that it is ALWAYS written
+ output = line;
+ } else {
+ log("ERROR: Mismatched record field='"
+ + DRM_LDIF_SERIAL_NO
+ + "' for record type='"
+ + record_type
+ + "'!"
+ + NEWLINE, true);
+ }
+
+ return output;
+ }
+
+ /**
+ * Helper method which composes the output line for
+ * DRM_LDIF_EXTDATA_AUTH_TOKEN_USER.
+ * <P>
+ *
+ * @param record_type the string representation of the input record type
+ * @param line the string representation of the input line
+ * @return the composed output line
+ */
+ private static String output_extdata_auth_token_user(String record_type,
+ String line) {
+ String output = null;
+
+ try {
+ if (record_type.equals(DRM_LDIF_ENROLLMENT)) {
+ // Since "-source_drm_naming_context", and
+ // "-target_drm_naming_context" are OPTIONAL
+ // parameters, ONLY process this field if both of
+ // these options have been selected
+ if (mDrmNamingContextsFlag) {
+ output = line.replace(mSourceDrmNamingContext,
+ mTargetDrmNamingContext);
+ } else {
+ output = line;
+ }
+ } else {
+ log("ERROR: Mismatched record field='"
+ + DRM_LDIF_EXTDATA_AUTH_TOKEN_USER
+ + "' for record type='"
+ + record_type
+ + "'!"
+ + NEWLINE, true);
+ }
+ } catch (NullPointerException exNullPointerException) {
+ log("ERROR: Unable to replace source DRM naming context '"
+ + mSourceDrmNamingContext
+ + "' with target DRM naming context '"
+ + mTargetDrmNamingContext
+ + "' NullPointerException: '"
+ + exNullPointerException.toString()
+ + "'"
+ + NEWLINE, true);
+ }
+
+ return output;
+ }
+
+ /**
+ * Helper method which composes the output line for
+ * DRM_LDIF_EXTDATA_AUTH_TOKEN_USER_DN.
+ * <P>
+ *
+ * @param record_type the string representation of the input record type
+ * @param line the string representation of the input line
+ * @return the composed output line
+ */
+ private static String output_extdata_auth_token_user_dn(String record_type,
+ String line) {
+ String output = null;
+
+ try {
+ if (record_type.equals(DRM_LDIF_ENROLLMENT)) {
+ // Since "-source_drm_naming_context", and
+ // "-target_drm_naming_context" are OPTIONAL
+ // parameters, ONLY process this field if both of
+ // these options have been selected
+ if (mDrmNamingContextsFlag) {
+ output = line.replace(mSourceDrmNamingContext,
+ mTargetDrmNamingContext);
+ } else {
+ output = line;
+ }
+ } else {
+ log("ERROR: Mismatched record field='"
+ + DRM_LDIF_EXTDATA_AUTH_TOKEN_USER_DN
+ + "' for record type='"
+ + record_type
+ + "'!"
+ + NEWLINE, true);
+ }
+ } catch (NullPointerException exNullPointerException) {
+ log("ERROR: Unable to replace source DRM naming context '"
+ + mSourceDrmNamingContext
+ + "' with target DRM naming context '"
+ + mTargetDrmNamingContext
+ + "' NullPointerException: '"
+ + exNullPointerException.toString()
+ + "'"
+ + NEWLINE, true);
+ }
+
+ return output;
+ }
+
+ /**
+ * This method performs the actual parsing of the "source" LDIF file
+ * and produces the "target" LDIF file.
+ * <P>
+ *
+ * @return true if the "target" LDIF file is successfully created
+ */
+ private static boolean convert_source_ldif_to_target_ldif() {
+ boolean success = false;
+ BufferedReader reader = null;
+ PrintWriter writer = null;
+ String input = null;
+ String line = null;
+ String previous_line = null;
+ String output = null;
+ String data = null;
+ String record_type = null;
+
+ if (mRewrapFlag) {
+ success = obtain_RSA_rewrapping_keys();
+ if (!success) {
+ return FAILURE;
+ }
+ }
+
+ // Create a vector for LDIF input
+ record = new Vector<String>(INITIAL_LDIF_RECORD_CAPACITY);
+
+ // Process each line in the source LDIF file
+ // and store it in the target LDIF file
+ try {
+ // Open source LDIF file for reading
+ reader = new BufferedReader(
+ new FileReader(mSourceLdifFilename));
+
+ // Open target LDIF file for writing
+ writer = new PrintWriter(
+ new BufferedWriter(
+ new FileWriter(mTargetLdifFilename)));
+
+ System.out.print("PROCESSING: ");
+ while ((input = reader.readLine()) != null) {
+ // Read in a record from the source LDIF file and
+ // add this line of input into the record vector
+ success = record.add(input);
+ if (!success) {
+ return FAILURE;
+ }
+
+ // Check for the end of an LDIF record
+ if (!input.equals("")) {
+ // Check to see if input line identifies the record type
+ if (input.startsWith(DRM_LDIF_REQUEST_TYPE)) {
+ // set the record type:
+ //
+ // * DRM_LDIF_ENROLLMENT
+ // * DRM_LDIF_KEYGEN
+ // * DRM_LDIF_RECOVERY
+ //
+ record_type = input.substring(
+ DRM_LDIF_REQUEST_TYPE.length() + 1
+ ).trim();
+ if (!record_type.equals(DRM_LDIF_ENROLLMENT) &&
+ !record_type.equals(DRM_LDIF_KEYGEN) &&
+ !record_type.equals(DRM_LDIF_RECOVERY)) {
+ log("ERROR: Unknown LDIF record type='"
+ + record_type
+ + "'!"
+ + NEWLINE, true);
+ return FAILURE;
+ }
+ } else if (input.startsWith(DRM_LDIF_ARCHIVED_BY)) {
+ // extract the data
+ data = input.substring(
+ DRM_LDIF_ARCHIVED_BY.length() + 1
+ ).trim();
+
+ // set the record type:
+ //
+ // * DRM_LDIF_CA_KEY_RECORD
+ // * DRM_LDIF_TPS_KEY_RECORD
+ //
+ if (data.startsWith(DRM_LDIF_TPS_KEY_RECORD)) {
+ record_type = DRM_LDIF_TPS_KEY_RECORD;
+ } else if (data.startsWith(DRM_LDIF_CA_KEY_RECORD)) {
+ record_type = DRM_LDIF_CA_KEY_RECORD;
+ } else {
+ log("ERROR: Unable to determine LDIF record type "
+ + "from data='"
+ + data
+ + "'!"
+ + NEWLINE, true);
+ return FAILURE;
+ }
+ }
+
+ // continue adding input lines into this record
+ continue;
+ }
+
+ // If record type is unset, then this record is neither
+ // an LDIF request record nor an LDIF key record; check
+ // to see if it needs to be written out to the target
+ // LDIF file or thrown away.
+ if ((record_type == null) &&
+ mProcessRequestsAndKeyRecordsOnlyFlag) {
+ // Mark each removed record with an 'x'
+ System.out.print("x");
+
+ // log this information
+ log("INFO: Throwing away an LDIF record which is "
+ + "neither a Request nor a Key Record!"
+ + NEWLINE, false);
+
+ // clear this LDIF record from the record vector
+ record.clear();
+
+ // NOTE: there is no need to reset the record type
+
+ // begin adding input lines into a new record
+ continue;
+ } else if (record_type == null) {
+ // Set record type to specify a "generic" LDIF record
+ record_type = DRM_LDIF_RECORD;
+ }
+
+ ldif_record = record.iterator();
+
+ // Process each line of the record:
+ // * If LDIF Record Type for this line is 'valid'
+ // * If DRMTOOL Configuration File Parameter is 'true'
+ // * Process this data
+ // * Else If DRMTOOL Configuration File Parameter is 'false'
+ // * Pass through this data unchanged
+ // * Else If LDIF Record Type for this line is 'invalid'
+ // * Log error and leave method returning 'false'
+ while (ldif_record.hasNext()) {
+
+ line = ldif_record.next();
+
+ if (line.startsWith(DRM_LDIF_CN)) {
+ output = output_cn(record_type, line);
+ if (output == null) {
+ return FAILURE;
+ }
+ } else if (line.startsWith(DRM_LDIF_DATE_OF_MODIFY)) {
+ output = output_date_of_modify(record_type, line);
+ if (output == null) {
+ return FAILURE;
+ }
+ } else if (line.startsWith(DRM_LDIF_DN)) {
+ output = output_dn(record_type, line);
+ if (output == null) {
+ return FAILURE;
+ }
+ } else if (line.startsWith(DRM_LDIF_EXTDATA_KEY_RECORD)) {
+ output = output_extdata_key_record(record_type,
+ line);
+ if (output == null) {
+ return FAILURE;
+ }
+ } else if (line.startsWith(DRM_LDIF_EXTDATA_REQUEST_ID)) {
+ output = output_extdata_request_id(record_type,
+ line);
+ if (output == null) {
+ return FAILURE;
+ }
+ } else if (line.startsWith(DRM_LDIF_EXTDATA_REQUEST_NOTES)) {
+ output = output_extdata_request_notes(record_type,
+ line);
+ if (output == null) {
+ return FAILURE;
+ }
+ } else if (line.startsWith(DRM_LDIF_EXTDATA_REQUEST_TYPE)) {
+ // if one is not already present,
+ // compose and write out the missing
+ // 'extdata_requestnotes' line
+ create_extdata_request_notes(record_type,
+ previous_line,
+ writer);
+
+ // ALWAYS pass through the original
+ // 'extdata-requesttype' line UNCHANGED
+ // so that it is ALWAYS written
+ output = line;
+ } else if (line.startsWith(DRM_LDIF_EXTDATA_SERIAL_NUMBER)) {
+ output = output_extdata_serial_number(record_type,
+ line);
+ if (output == null) {
+ return FAILURE;
+ }
+ } else if (line.startsWith(DRM_LDIF_PRIVATE_KEY_DATA)) {
+ output = output_private_key_data(record_type,
+ line);
+ if (output == null) {
+ return FAILURE;
+ }
+ } else if (line.startsWith(DRM_LDIF_REQUEST_ID)) {
+ output = output_request_id(record_type, line);
+ if (output == null) {
+ return FAILURE;
+ }
+ } else if (line.startsWith(DRM_LDIF_SERIAL_NO)) {
+ output = output_serial_no(record_type, line);
+ if (output == null) {
+ return FAILURE;
+ }
+ } else if (previous_line != null &&
+ previous_line.startsWith(
+ DRM_LDIF_EXTDATA_AUTH_TOKEN_USER)) {
+ output = output_extdata_auth_token_user(record_type,
+ line);
+ if (output == null) {
+ return FAILURE;
+ }
+ } else if (previous_line != null &&
+ previous_line.startsWith(
+ DRM_LDIF_EXTDATA_AUTH_TOKEN_USER_DN)) {
+ output = output_extdata_auth_token_user_dn(record_type,
+ line);
+ if (output == null) {
+ return FAILURE;
+ }
+ } else {
+ // Pass through line unchanged
+ output = line;
+ }
+
+ // Always save a copy of this line
+ previous_line = output;
+
+ // Always write out the output line and flush the buffer
+ writer.write(output + NEWLINE);
+ writer.flush();
+ System.out.print(".");
+ }
+ // Mark the end of the LDIF record
+ System.out.print("!");
+
+ // clear this LDIF record from the record vector
+ record.clear();
+ }
+ System.out.println(" FINISHED." + NEWLINE);
+ } catch (IOException exIO) {
+ log("ERROR: line='"
+ + line
+ + "' OR output='"
+ + output
+ + "' IOException: '"
+ + exIO.toString()
+ + "'"
+ + NEWLINE, true);
+ return FAILURE;
+ }
+
+ return SUCCESS;
+ }
+
+ /**************************************/
+ /* DRMTOOL Config File Parser Methods */
+ /**************************************/
+
+ /**
+ * This method performs the actual parsing of the DRMTOOL config file
+ * and initializes how the DRM Record Fields should be processed.
+ * <P>
+ *
+ * @return true if the DRMTOOL config file is successfully processed
+ */
+ private static boolean process_drmtool_config_file() {
+ BufferedReader reader = null;
+ String line = null;
+ String name_value_pair[] = null;
+ String name = null;
+ Boolean value = null;
+
+ // Process each line containing a name/value pair
+ // in the DRMTOOL config file
+ try {
+ // Open DRMTOOL config file for reading
+ reader = new BufferedReader(
+ new FileReader(mDrmtoolCfgFilename));
+
+ // Create a hashtable for relevant name/value pairs
+ drmtoolCfg = new Hashtable<String, Boolean>();
+
+ System.out.print("PROCESSING DRMTOOL CONFIG FILE: ");
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DRMTOOL_CFG_PREFIX)) {
+ // obtain "name=value" pair
+ name_value_pair = line.split(EQUAL_SIGN);
+
+ // obtain "name"
+ name = name_value_pair[0];
+
+ // compute "boolean" value
+ if (name_value_pair[1].equals("true")) {
+ value = Boolean.TRUE;
+ } else {
+ value = Boolean.FALSE;
+ }
+
+ // store relevant DRM LDIF fields for processing
+ if (name.equals(DRMTOOL_CFG_ENROLLMENT_CN)
+ || name.equals(DRMTOOL_CFG_ENROLLMENT_DATE_OF_MODIFY)
+ || name.equals(DRMTOOL_CFG_ENROLLMENT_DN)
+ || name.equals(DRMTOOL_CFG_ENROLLMENT_EXTDATA_KEY_RECORD)
+ || name.equals(DRMTOOL_CFG_ENROLLMENT_EXTDATA_REQUEST_NOTES)
+ || name.equals(DRMTOOL_CFG_ENROLLMENT_REQUEST_ID)
+ || name.equals(DRMTOOL_CFG_CA_KEY_RECORD_CN)
+ || name.equals(DRMTOOL_CFG_CA_KEY_RECORD_DATE_OF_MODIFY)
+ || name.equals(DRMTOOL_CFG_CA_KEY_RECORD_DN)
+ || name.equals(DRMTOOL_CFG_CA_KEY_RECORD_PRIVATE_KEY_DATA)
+ || name.equals(DRMTOOL_CFG_CA_KEY_RECORD_SERIAL_NO)
+ || name.equals(DRMTOOL_CFG_RECOVERY_CN)
+ || name.equals(DRMTOOL_CFG_RECOVERY_DATE_OF_MODIFY)
+ || name.equals(DRMTOOL_CFG_RECOVERY_DN)
+ || name.equals(DRMTOOL_CFG_RECOVERY_EXTDATA_REQUEST_ID)
+ || name.equals(DRMTOOL_CFG_RECOVERY_EXTDATA_REQUEST_NOTES)
+ || name.equals(DRMTOOL_CFG_RECOVERY_EXTDATA_SERIAL_NUMBER)
+ || name.equals(DRMTOOL_CFG_RECOVERY_REQUEST_ID)
+ || name.equals(DRMTOOL_CFG_TPS_KEY_RECORD_CN)
+ || name.equals(DRMTOOL_CFG_TPS_KEY_RECORD_DATE_OF_MODIFY)
+ || name.equals(DRMTOOL_CFG_TPS_KEY_RECORD_DN)
+ || name.equals(DRMTOOL_CFG_TPS_KEY_RECORD_PRIVATE_KEY_DATA)
+ || name.equals(DRMTOOL_CFG_TPS_KEY_RECORD_SERIAL_NO)
+ || name.equals(DRMTOOL_CFG_KEYGEN_CN)
+ || name.equals(DRMTOOL_CFG_KEYGEN_DATE_OF_MODIFY)
+ || name.equals(DRMTOOL_CFG_KEYGEN_DN)
+ || name.equals(DRMTOOL_CFG_KEYGEN_EXTDATA_KEY_RECORD)
+ || name.equals(DRMTOOL_CFG_KEYGEN_EXTDATA_REQUEST_ID)
+ || name.equals(DRMTOOL_CFG_KEYGEN_EXTDATA_REQUEST_NOTES)
+ || name.equals(DRMTOOL_CFG_KEYGEN_REQUEST_ID)) {
+ drmtoolCfg.put(name, value);
+ System.out.print(".");
+ }
+ }
+ }
+ System.out.println(" FINISHED." + NEWLINE);
+ } catch (FileNotFoundException exDrmtoolCfgFileNotFound) {
+ log("ERROR: No DRMTOOL config file named '"
+ + mDrmtoolCfgFilename
+ + "' exists! FileNotFoundException: '"
+ + exDrmtoolCfgFileNotFound.toString()
+ + "'"
+ + NEWLINE, true);
+ return FAILURE;
+ } catch (IOException exDrmtoolCfgIO) {
+ log("ERROR: line='"
+ + line
+ + "' IOException: '"
+ + exDrmtoolCfgIO.toString()
+ + "'"
+ + NEWLINE, true);
+ return FAILURE;
+ } catch (PatternSyntaxException exDrmtoolCfgNameValuePattern) {
+ log("ERROR: line='"
+ + line
+ + "' PatternSyntaxException: '"
+ + exDrmtoolCfgNameValuePattern.toString()
+ + "'"
+ + NEWLINE, true);
+ return FAILURE;
+ }
+
+ return SUCCESS;
+ }
+
+ /************/
+ /* DRM Tool */
+ /************/
+
+ /**
+ * The main DRMTool method.
+ * <P>
+ *
+ * @param args DRMTool options
+ */
+ public static void main(String[] args) {
+ // Variables
+ String append_id_offset = null;
+ String remove_id_offset = null;
+ String process_drm_naming_context_fields = null;
+ String process_requests_and_key_records_only = null;
+ String use_PKI_security_database_pwdfile = null;
+ File cfgFile = null;
+ File sourceFile = null;
+ File sourceDBPath = null;
+ File sourceDBPwdfile = null;
+ File targetStorageCertFile = null;
+ File targetFile = null;
+ File logFile = null;
+ boolean success = false;
+
+ // Get current date and time
+ mDateOfModify = now(DATE_OF_MODIFY_PATTERN);
+
+ // Check that the correct number of arguments were
+ // submitted to the program
+ if ((args.length != ID_OFFSET_ARGS) &&
+ (args.length != (ID_OFFSET_ARGS + 1)) &&
+ (args.length != (ID_OFFSET_ARGS + 4)) &&
+ (args.length != (ID_OFFSET_ARGS + 5)) &&
+ (args.length != REWRAP_ARGS) &&
+ (args.length != (REWRAP_ARGS + 1)) &&
+ (args.length != (REWRAP_ARGS + 2)) &&
+ (args.length != (REWRAP_ARGS + 3)) &&
+ (args.length != (REWRAP_ARGS + 4)) &&
+ (args.length != (REWRAP_ARGS + 5)) &&
+ (args.length != (REWRAP_ARGS + 6)) &&
+ (args.length != (REWRAP_ARGS + 7)) &&
+ (args.length != REWRAP_AND_ID_OFFSET_ARGS) &&
+ (args.length != (REWRAP_AND_ID_OFFSET_ARGS + 1)) &&
+ (args.length != (REWRAP_AND_ID_OFFSET_ARGS + 2)) &&
+ (args.length != (REWRAP_AND_ID_OFFSET_ARGS + 3)) &&
+ (args.length != (REWRAP_AND_ID_OFFSET_ARGS + 4)) &&
+ (args.length != (REWRAP_AND_ID_OFFSET_ARGS + 5)) &&
+ (args.length != (REWRAP_AND_ID_OFFSET_ARGS + 6)) &&
+ (args.length != (REWRAP_AND_ID_OFFSET_ARGS + 7))) {
+ System.err.println("ERROR: Incorrect number of arguments!"
+ + NEWLINE);
+ printUsage();
+ System.exit(0);
+ }
+
+ // Process command-line arguments
+ for (int i = 0; i < args.length; i += 2) {
+ if (args[i].equals(DRMTOOL_CFG_FILE)) {
+ mDrmtoolCfgFilename = args[i + 1];
+ mMandatoryNameValuePairs++;
+ } else if (args[i].equals(SOURCE_LDIF_FILE)) {
+ mSourceLdifFilename = args[i + 1];
+ mMandatoryNameValuePairs++;
+ } else if (args[i].equals(TARGET_LDIF_FILE)) {
+ mTargetLdifFilename = args[i + 1];
+ mMandatoryNameValuePairs++;
+ } else if (args[i].equals(LOG_FILE)) {
+ mLogFilename = args[i + 1];
+ mMandatoryNameValuePairs++;
+ } else if (args[i].equals(SOURCE_NSS_DB_PATH)) {
+ mSourcePKISecurityDatabasePath = args[i + 1];
+ mRewrapNameValuePairs++;
+ } else if (args[i].equals(SOURCE_STORAGE_TOKEN_NAME)) {
+ mSourceStorageTokenName = args[i + 1];
+ mRewrapNameValuePairs++;
+ } else if (args[i].equals(SOURCE_STORAGE_CERT_NICKNAME)) {
+ mSourceStorageCertNickname = args[i + 1];
+ mRewrapNameValuePairs++;
+ } else if (args[i].equals(TARGET_STORAGE_CERTIFICATE_FILE)) {
+ mTargetStorageCertificateFilename = args[i + 1];
+ mRewrapNameValuePairs++;
+ } else if (args[i].equals(SOURCE_NSS_DB_PWDFILE)) {
+ mSourcePKISecurityDatabasePwdfile = args[i + 1];
+ mPKISecurityDatabasePwdfileNameValuePairs++;
+ } else if (args[i].equals(APPEND_ID_OFFSET)) {
+ append_id_offset = args[i + 1];
+ mAppendIdOffsetNameValuePairs++;
+ } else if (args[i].equals(REMOVE_ID_OFFSET)) {
+ remove_id_offset = args[i + 1];
+ mRemoveIdOffsetNameValuePairs++;
+ } else if (args[i].equals(SOURCE_DRM_NAMING_CONTEXT)) {
+ mSourceDrmNamingContext = args[i + 1];
+ mDrmNamingContextNameValuePairs++;
+ } else if (args[i].equals(TARGET_DRM_NAMING_CONTEXT)) {
+ mTargetDrmNamingContext = args[i + 1];
+ mDrmNamingContextNameValuePairs++;
+ } else if (args[i].equals(PROCESS_REQUESTS_AND_KEY_RECORDS_ONLY)) {
+ mProcessRequestsAndKeyRecordsOnlyFlag = true;
+ i -= 1;
+ } else {
+ System.err.println("ERROR: Unknown argument '"
+ + args[i]
+ + "'!"
+ + NEWLINE);
+ printUsage();
+ System.exit(0);
+ }
+ }
+
+ // Verify that correct number of valid mandatory
+ // arguments were submitted to the program
+ if (mMandatoryNameValuePairs != MANDATORY_NAME_VALUE_PAIRS ||
+ mDrmtoolCfgFilename == null ||
+ mDrmtoolCfgFilename.length() == 0 ||
+ mSourceLdifFilename == null ||
+ mSourceLdifFilename.length() == 0 ||
+ mTargetLdifFilename == null ||
+ mTargetLdifFilename.length() == 0 ||
+ mLogFilename == null ||
+ mLogFilename.length() == 0) {
+ System.err.println("ERROR: Missing mandatory arguments!"
+ + NEWLINE);
+ printUsage();
+ System.exit(0);
+ } else {
+ // Check for a valid DRMTOOL config file
+ cfgFile = new File(mDrmtoolCfgFilename);
+ if (!cfgFile.exists() ||
+ !cfgFile.isFile() ||
+ (cfgFile.length() == 0)) {
+ System.err.println("ERROR: '"
+ + mDrmtoolCfgFilename
+ + "' does NOT exist, is NOT a file, "
+ + "or is empty!"
+ + NEWLINE);
+ printUsage();
+ System.exit(0);
+ }
+
+ // Check for a valid source LDIF file
+ sourceFile = new File(mSourceLdifFilename);
+ if (!sourceFile.exists() ||
+ !sourceFile.isFile() ||
+ (sourceFile.length() == 0)) {
+ System.err.println("ERROR: '"
+ + mSourceLdifFilename
+ + "' does NOT exist, is NOT a file, "
+ + "or is empty!"
+ + NEWLINE);
+ printUsage();
+ System.exit(0);
+ }
+
+ // Check that the target LDIF file does NOT exist
+ targetFile = new File(mTargetLdifFilename);
+ if (targetFile.exists()) {
+ System.err.println("ERROR: '"
+ + mTargetLdifFilename
+ + "' ALREADY exists!"
+ + NEWLINE);
+ printUsage();
+ System.exit(0);
+ }
+
+ // Check that the log file does NOT exist
+ logFile = new File(mLogFilename);
+ if (logFile.exists()) {
+ System.err.println("ERROR: '"
+ + mLogFilename
+ + "' ALREADY exists!"
+ + NEWLINE);
+ printUsage();
+ System.exit(0);
+ }
+
+ // Mark the 'Mandatory' flag true
+ mMandatoryFlag = true;
+ }
+
+ // Check to see that if the 'Rewrap' command-line options were
+ // specified, that they are all present and accounted for
+ if (mRewrapNameValuePairs > 0) {
+ if (mRewrapNameValuePairs != REWRAP_NAME_VALUE_PAIRS ||
+ mSourcePKISecurityDatabasePath == null ||
+ mSourcePKISecurityDatabasePath.length() == 0 ||
+ mSourceStorageTokenName == null ||
+ mSourceStorageTokenName.length() == 0 ||
+ mSourceStorageCertNickname == null ||
+ mSourceStorageCertNickname.length() == 0 ||
+ mTargetStorageCertificateFilename == null ||
+ mTargetStorageCertificateFilename.length() == 0) {
+ System.err.println("ERROR: Missing 'Rewrap' arguments!"
+ + NEWLINE);
+ printUsage();
+ System.exit(0);
+ } else {
+ // Check for a valid path to the PKI security databases
+ sourceDBPath = new File(mSourcePKISecurityDatabasePath);
+ if (!sourceDBPath.exists() ||
+ !sourceDBPath.isDirectory()) {
+ System.err.println("ERROR: '"
+ + mSourcePKISecurityDatabasePath
+ + "' does NOT exist or "
+ + "'is NOT a directory!"
+ + NEWLINE);
+ printUsage();
+ System.exit(0);
+ }
+
+ // Check for a valid target storage certificate file
+ targetStorageCertFile = new File(
+ mTargetStorageCertificateFilename);
+ if (!targetStorageCertFile.exists() ||
+ !targetStorageCertFile.isFile() ||
+ (targetStorageCertFile.length() == 0)) {
+ System.err.println("ERROR: '"
+ + mTargetStorageCertificateFilename
+ + "' does NOT exist, is NOT a file, "
+ + "or is empty!"
+ + NEWLINE);
+ printUsage();
+ System.exit(0);
+ }
+
+ // Mark the 'Rewrap' flag true
+ mRewrapFlag = true;
+ }
+ }
+
+ // Check to see that BOTH append 'ID Offset' command-line options
+ // and remove 'ID Offset' command-line options were NOT specified
+ // since these two command-line options are mutually exclusive!
+ if ((mAppendIdOffsetNameValuePairs > 0) &&
+ (mRemoveIdOffsetNameValuePairs > 0)) {
+ System.err.println("ERROR: The 'append ID Offset' option "
+ + "and the 'remove ID Offset' option are "
+ + "mutually exclusive!"
+ + NEWLINE);
+ printUsage();
+ System.exit(0);
+ }
+
+ // Check to see that if the 'append ID Offset' command-line options
+ // were specified, that they are all present and accounted for
+ if (mAppendIdOffsetNameValuePairs > 0) {
+ if (mAppendIdOffsetNameValuePairs == ID_OFFSET_NAME_VALUE_PAIRS &&
+ append_id_offset != null &&
+ append_id_offset.length() != 0) {
+ try {
+ if (!append_id_offset.matches("[0-9]++")) {
+ System.err.println("ERROR: '"
+ + append_id_offset
+ + "' contains non-numeric "
+ + "characters!"
+ + NEWLINE);
+ printUsage();
+ System.exit(0);
+ } else {
+ mAppendIdOffset = new BigInteger(
+ append_id_offset);
+
+ // Mark the 'append ID Offset' flag true
+ mAppendIdOffsetFlag = true;
+ }
+ } catch (PatternSyntaxException exAppendPattern) {
+ System.err.println("ERROR: append_id_offset='"
+ + append_id_offset
+ + "' PatternSyntaxException: '"
+ + exAppendPattern.toString()
+ + "'"
+ + NEWLINE);
+ System.exit(0);
+ }
+ } else {
+ System.err.println("ERROR: Missing "
+ + "'append ID Offset' arguments!"
+ + NEWLINE);
+ printUsage();
+ System.exit(0);
+ }
+ }
+
+ // Check to see that if the 'remove ID Offset' command-line options
+ // were specified, that they are all present and accounted for
+ if (mRemoveIdOffsetNameValuePairs > 0) {
+ if (mRemoveIdOffsetNameValuePairs == ID_OFFSET_NAME_VALUE_PAIRS &&
+ remove_id_offset != null &&
+ remove_id_offset.length() != 0) {
+ try {
+ if (!remove_id_offset.matches("[0-9]++")) {
+ System.err.println("ERROR: '"
+ + remove_id_offset
+ + "' contains non-numeric "
+ + "characters!"
+ + NEWLINE);
+ printUsage();
+ System.exit(0);
+ } else {
+ mRemoveIdOffset = new BigInteger(
+ remove_id_offset);
+
+ // Mark the 'remove ID Offset' flag true
+ mRemoveIdOffsetFlag = true;
+ }
+ } catch (PatternSyntaxException exRemovePattern) {
+ System.err.println("ERROR: remove_id_offset='"
+ + remove_id_offset
+ + "' PatternSyntaxException: '"
+ + exRemovePattern.toString()
+ + "'"
+ + NEWLINE);
+ System.exit(0);
+ }
+ } else {
+ System.err.println("ERROR: Missing "
+ + "'remove ID Offset' arguments!"
+ + NEWLINE);
+ printUsage();
+ System.exit(0);
+ }
+ }
+
+ // Make certain that at least one of the "Rewrap", "Append ID Offset",
+ // or "Remove ID Offset" options has been specified
+ if (!mRewrapFlag &&
+ !mAppendIdOffsetFlag &&
+ !mRemoveIdOffsetFlag) {
+ System.err.println("ERROR: At least one of the 'rewrap', "
+ + "'append ID Offset', or 'remove ID Offset' "
+ + "options MUST be specified!"
+ + NEWLINE);
+ printUsage();
+ System.exit(0);
+ }
+
+ // Check to see that if the OPTIONAL
+ // 'PKI Security Database Password File'
+ // command-line options were specified,
+ // that they are all present and accounted for
+ if (mPKISecurityDatabasePwdfileNameValuePairs > 0) {
+ if (mPKISecurityDatabasePwdfileNameValuePairs !=
+ PWDFILE_NAME_VALUE_PAIRS ||
+ mSourcePKISecurityDatabasePwdfile == null ||
+ mSourcePKISecurityDatabasePwdfile.length() == 0) {
+ System.err.println("ERROR: Missing 'Password File' "
+ + "arguments!"
+ + NEWLINE);
+ printUsage();
+ System.exit(0);
+ } else {
+ if (mRewrapFlag) {
+ // Check for a valid source PKI
+ // security database password file
+ sourceDBPwdfile = new
+ File(mSourcePKISecurityDatabasePwdfile);
+ if (!sourceDBPwdfile.exists() ||
+ !sourceDBPwdfile.isFile() ||
+ (sourceDBPwdfile.length() == 0)) {
+ System.err.println("ERROR: '"
+ + mSourcePKISecurityDatabasePwdfile
+ + "' does NOT exist, is NOT a file, "
+ + "or is empty!"
+ + NEWLINE);
+ printUsage();
+ System.exit(0);
+ }
+
+ use_PKI_security_database_pwdfile = SPACE
+ + SOURCE_NSS_DB_PWDFILE
+ + SPACE
+ + TIC
+ + mSourcePKISecurityDatabasePwdfile
+ + TIC;
+
+ mSourcePKISecurityDatabasePwdfileMessage = SPACE
+ + PLUS
+ + SPACE
+ + DRM_LDIF_USED_PWDFILE_MESSAGE;
+
+ // Mark the 'Password File' flag true
+ mPwdfileFlag = true;
+ } else {
+ System.err.println("ERROR: The "
+ + TIC
+ + SOURCE_NSS_DB_PWDFILE
+ + TIC
+ + " option is ONLY valid when "
+ + "performing rewrapping."
+ + NEWLINE);
+ printUsage();
+ System.exit(0);
+ }
+ }
+ } else {
+ use_PKI_security_database_pwdfile = "";
+ mSourcePKISecurityDatabasePwdfileMessage = "";
+ }
+
+ // Check to see that if the OPTIONAL 'DRM Naming Context' command-line
+ // options were specified, that they are all present and accounted for
+ if (mDrmNamingContextNameValuePairs > 0) {
+ if (mDrmNamingContextNameValuePairs !=
+ NAMING_CONTEXT_NAME_VALUE_PAIRS ||
+ mSourceDrmNamingContext == null ||
+ mSourceDrmNamingContext.length() == 0 ||
+ mTargetDrmNamingContext == null ||
+ mTargetDrmNamingContext.length() == 0) {
+ System.err.println("ERROR: Both 'source DRM naming context' "
+ + "and 'target DRM naming context' "
+ + "options MUST be specified!"
+ + NEWLINE);
+ printUsage();
+ System.exit(0);
+ } else {
+ process_drm_naming_context_fields = SPACE
+ + SOURCE_DRM_NAMING_CONTEXT
+ + SPACE
+ + TIC
+ + mSourceDrmNamingContext
+ + TIC
+ + SPACE
+ + TARGET_DRM_NAMING_CONTEXT
+ + SPACE
+ + TIC
+ + mTargetDrmNamingContext
+ + TIC;
+
+ mDrmNamingContextMessage = SPACE
+ + PLUS
+ + SPACE
+ + DRM_LDIF_SOURCE_NAME_CONTEXT_MESSAGE
+ + mSourceDrmNamingContext
+ + DRM_LDIF_TARGET_NAME_CONTEXT_MESSAGE
+ + mTargetDrmNamingContext
+ + TIC;
+
+ // Mark the 'DRM Naming Contexts' flag true
+ mDrmNamingContextsFlag = true;
+ }
+ } else {
+ process_drm_naming_context_fields = "";
+ mDrmNamingContextMessage = "";
+ }
+
+ // Check for OPTIONAL "Process Requests and Key Records ONLY" option
+ if (mProcessRequestsAndKeyRecordsOnlyFlag) {
+ process_requests_and_key_records_only = SPACE
+ + PROCESS_REQUESTS_AND_KEY_RECORDS_ONLY;
+ mProcessRequestsAndKeyRecordsOnlyMessage = SPACE + PLUS + SPACE +
+ DRM_LDIF_PROCESS_REQUESTS_AND_KEY_RECORDS_ONLY_MESSAGE;
+ } else {
+ process_requests_and_key_records_only = "";
+ mProcessRequestsAndKeyRecordsOnlyMessage = "";
+ }
+
+ // Enable logging process . . .
+ open_log(mLogFilename);
+
+ // Begin logging progress . . .
+ if (mRewrapFlag && mAppendIdOffsetFlag) {
+ log("BEGIN \""
+ + DRM_TOOL + SPACE
+ + DRMTOOL_CFG_FILE + SPACE
+ + mDrmtoolCfgFilename + SPACE
+ + SOURCE_LDIF_FILE + SPACE
+ + mSourceLdifFilename + SPACE
+ + TARGET_LDIF_FILE + SPACE
+ + mTargetLdifFilename + SPACE
+ + LOG_FILE + SPACE
+ + mLogFilename + SPACE
+ + SOURCE_NSS_DB_PATH + SPACE
+ + mSourcePKISecurityDatabasePath + SPACE
+ + SOURCE_STORAGE_TOKEN_NAME + SPACE
+ + TIC + mSourceStorageTokenName + TIC + SPACE
+ + SOURCE_STORAGE_CERT_NICKNAME + SPACE
+ + TIC + mSourceStorageCertNickname + TIC + SPACE
+ + TARGET_STORAGE_CERTIFICATE_FILE + SPACE
+ + mTargetStorageCertificateFilename + SPACE
+ + use_PKI_security_database_pwdfile
+ + APPEND_ID_OFFSET + SPACE
+ + append_id_offset
+ + process_drm_naming_context_fields
+ + process_requests_and_key_records_only
+ + "\" . . ."
+ + NEWLINE, true);
+ } else if (mRewrapFlag && mRemoveIdOffsetFlag) {
+ log("BEGIN \""
+ + DRM_TOOL + SPACE
+ + DRMTOOL_CFG_FILE + SPACE
+ + mDrmtoolCfgFilename + SPACE
+ + SOURCE_LDIF_FILE + SPACE
+ + mSourceLdifFilename + SPACE
+ + TARGET_LDIF_FILE + SPACE
+ + mTargetLdifFilename + SPACE
+ + LOG_FILE + SPACE
+ + mLogFilename + SPACE
+ + SOURCE_NSS_DB_PATH + SPACE
+ + mSourcePKISecurityDatabasePath + SPACE
+ + SOURCE_STORAGE_TOKEN_NAME + SPACE
+ + TIC + mSourceStorageTokenName + TIC + SPACE
+ + SOURCE_STORAGE_CERT_NICKNAME + SPACE
+ + TIC + mSourceStorageCertNickname + TIC + SPACE
+ + TARGET_STORAGE_CERTIFICATE_FILE + SPACE
+ + mTargetStorageCertificateFilename + SPACE
+ + use_PKI_security_database_pwdfile
+ + REMOVE_ID_OFFSET + SPACE
+ + remove_id_offset
+ + process_drm_naming_context_fields
+ + process_requests_and_key_records_only
+ + "\" . . ."
+ + NEWLINE, true);
+ } else if (mRewrapFlag) {
+ log("BEGIN \""
+ + DRM_TOOL + SPACE
+ + DRMTOOL_CFG_FILE + SPACE
+ + mDrmtoolCfgFilename + SPACE
+ + SOURCE_LDIF_FILE + SPACE
+ + mSourceLdifFilename + SPACE
+ + TARGET_LDIF_FILE + SPACE
+ + mTargetLdifFilename + SPACE
+ + LOG_FILE + SPACE
+ + mLogFilename + SPACE
+ + SOURCE_NSS_DB_PATH + SPACE
+ + mSourcePKISecurityDatabasePath + SPACE
+ + SOURCE_STORAGE_TOKEN_NAME + SPACE
+ + TIC + mSourceStorageTokenName + TIC + SPACE
+ + SOURCE_STORAGE_CERT_NICKNAME + SPACE
+ + TIC + mSourceStorageCertNickname + TIC + SPACE
+ + TARGET_STORAGE_CERTIFICATE_FILE + SPACE
+ + mTargetStorageCertificateFilename
+ + use_PKI_security_database_pwdfile
+ + process_drm_naming_context_fields
+ + process_requests_and_key_records_only
+ + "\" . . ."
+ + NEWLINE, true);
+ } else if (mAppendIdOffsetFlag) {
+ log("BEGIN \""
+ + DRM_TOOL + SPACE
+ + DRMTOOL_CFG_FILE + SPACE
+ + mDrmtoolCfgFilename + SPACE
+ + SOURCE_LDIF_FILE + SPACE
+ + mSourceLdifFilename + SPACE
+ + TARGET_LDIF_FILE + SPACE
+ + mTargetLdifFilename + SPACE
+ + LOG_FILE + SPACE
+ + mLogFilename + SPACE
+ + APPEND_ID_OFFSET + SPACE
+ + append_id_offset
+ + process_drm_naming_context_fields
+ + process_requests_and_key_records_only
+ + "\" . . ."
+ + NEWLINE, true);
+ } else if (mRemoveIdOffsetFlag) {
+ log("BEGIN \""
+ + DRM_TOOL + SPACE
+ + DRMTOOL_CFG_FILE + SPACE
+ + mDrmtoolCfgFilename + SPACE
+ + SOURCE_LDIF_FILE + SPACE
+ + mSourceLdifFilename + SPACE
+ + TARGET_LDIF_FILE + SPACE
+ + mTargetLdifFilename + SPACE
+ + LOG_FILE + SPACE
+ + mLogFilename + SPACE
+ + REMOVE_ID_OFFSET + SPACE
+ + remove_id_offset
+ + process_drm_naming_context_fields
+ + process_requests_and_key_records_only
+ + "\" . . ."
+ + NEWLINE, true);
+ }
+
+ // Process the DRMTOOL config file
+ success = process_drmtool_config_file();
+ if (!success) {
+ log("FAILED processing drmtool config file!"
+ + NEWLINE, true);
+ } else {
+ log("SUCCESSFULLY processed drmtool config file!"
+ + NEWLINE, true);
+
+ // Convert the source LDIF file to a target LDIF file
+ success = convert_source_ldif_to_target_ldif();
+ if (!success) {
+ log("FAILED converting source LDIF file --> target LDIF file!"
+ + NEWLINE, true);
+ } else {
+ log("SUCCESSFULLY converted source LDIF file --> "
+ + "target LDIF file!"
+ + NEWLINE, true);
+ }
+ }
+
+ // Finish logging progress
+ if (mRewrapFlag && mAppendIdOffsetFlag) {
+ log("FINISHED \""
+ + DRM_TOOL + SPACE
+ + DRMTOOL_CFG_FILE + SPACE
+ + mDrmtoolCfgFilename + SPACE
+ + SOURCE_LDIF_FILE + SPACE
+ + mSourceLdifFilename + SPACE
+ + TARGET_LDIF_FILE + SPACE
+ + mTargetLdifFilename + SPACE
+ + LOG_FILE + SPACE
+ + mLogFilename + SPACE
+ + SOURCE_NSS_DB_PATH + SPACE
+ + mSourcePKISecurityDatabasePath + SPACE
+ + SOURCE_STORAGE_TOKEN_NAME + SPACE
+ + TIC + mSourceStorageTokenName + TIC + SPACE
+ + SOURCE_STORAGE_CERT_NICKNAME + SPACE
+ + TIC + mSourceStorageCertNickname + TIC + SPACE
+ + TARGET_STORAGE_CERTIFICATE_FILE + SPACE
+ + mTargetStorageCertificateFilename + SPACE
+ + use_PKI_security_database_pwdfile
+ + APPEND_ID_OFFSET + SPACE
+ + append_id_offset
+ + process_drm_naming_context_fields
+ + process_requests_and_key_records_only
+ + "\"."
+ + NEWLINE, true);
+ } else if (mRewrapFlag && mRemoveIdOffsetFlag) {
+ log("FINISHED \""
+ + DRM_TOOL + SPACE
+ + DRMTOOL_CFG_FILE + SPACE
+ + mDrmtoolCfgFilename + SPACE
+ + SOURCE_LDIF_FILE + SPACE
+ + mSourceLdifFilename + SPACE
+ + TARGET_LDIF_FILE + SPACE
+ + mTargetLdifFilename + SPACE
+ + LOG_FILE + SPACE
+ + mLogFilename + SPACE
+ + SOURCE_NSS_DB_PATH + SPACE
+ + mSourcePKISecurityDatabasePath + SPACE
+ + SOURCE_STORAGE_TOKEN_NAME + SPACE
+ + TIC + mSourceStorageTokenName + TIC + SPACE
+ + SOURCE_STORAGE_CERT_NICKNAME + SPACE
+ + TIC + mSourceStorageCertNickname + TIC + SPACE
+ + TARGET_STORAGE_CERTIFICATE_FILE + SPACE
+ + mTargetStorageCertificateFilename + SPACE
+ + use_PKI_security_database_pwdfile
+ + REMOVE_ID_OFFSET + SPACE
+ + remove_id_offset
+ + process_drm_naming_context_fields
+ + process_requests_and_key_records_only
+ + "\"."
+ + NEWLINE, true);
+ } else if (mRewrapFlag) {
+ log("FINISHED \""
+ + DRM_TOOL + SPACE
+ + DRMTOOL_CFG_FILE + SPACE
+ + mDrmtoolCfgFilename + SPACE
+ + SOURCE_LDIF_FILE + SPACE
+ + mSourceLdifFilename + SPACE
+ + TARGET_LDIF_FILE + SPACE
+ + mTargetLdifFilename + SPACE
+ + LOG_FILE + SPACE
+ + mLogFilename + SPACE
+ + SOURCE_NSS_DB_PATH + SPACE
+ + mSourcePKISecurityDatabasePath + SPACE
+ + SOURCE_STORAGE_TOKEN_NAME + SPACE
+ + TIC + mSourceStorageTokenName + TIC + SPACE
+ + SOURCE_STORAGE_CERT_NICKNAME + SPACE
+ + TIC + mSourceStorageCertNickname + TIC + SPACE
+ + TARGET_STORAGE_CERTIFICATE_FILE + SPACE
+ + mTargetStorageCertificateFilename
+ + use_PKI_security_database_pwdfile
+ + process_drm_naming_context_fields
+ + process_requests_and_key_records_only
+ + "\"."
+ + NEWLINE, true);
+ } else if (mAppendIdOffsetFlag) {
+ log("FINISHED \""
+ + DRM_TOOL + SPACE
+ + DRMTOOL_CFG_FILE + SPACE
+ + mDrmtoolCfgFilename + SPACE
+ + SOURCE_LDIF_FILE + SPACE
+ + mSourceLdifFilename + SPACE
+ + TARGET_LDIF_FILE + SPACE
+ + mTargetLdifFilename + SPACE
+ + LOG_FILE + SPACE
+ + mLogFilename + SPACE
+ + APPEND_ID_OFFSET + SPACE
+ + append_id_offset
+ + process_drm_naming_context_fields
+ + process_requests_and_key_records_only
+ + "\"."
+ + NEWLINE, true);
+ } else if (mRemoveIdOffsetFlag) {
+ log("FINISHED \""
+ + DRM_TOOL + SPACE
+ + DRMTOOL_CFG_FILE + SPACE
+ + mDrmtoolCfgFilename + SPACE
+ + SOURCE_LDIF_FILE + SPACE
+ + mSourceLdifFilename + SPACE
+ + TARGET_LDIF_FILE + SPACE
+ + mTargetLdifFilename + SPACE
+ + LOG_FILE + SPACE
+ + mLogFilename + SPACE
+ + REMOVE_ID_OFFSET + SPACE
+ + remove_id_offset
+ + process_drm_naming_context_fields
+ + process_requests_and_key_records_only
+ + "\"."
+ + NEWLINE, true);
+ }
+
+ // Shutdown logging process
+ close_log(mLogFilename);
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/ExtJoiner.java b/base/java-tools/src/com/netscape/cmstools/ExtJoiner.java
new file mode 100644
index 000000000..48f180add
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/ExtJoiner.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.cmstools;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import com.netscape.cmsutil.util.Utils;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This program joins a sequence of extensions together
+ * so that the final output can be used in configuration
+ * wizard for specifing extra extensions in default
+ * certificates (i.e. CA certificate, SSL certificate).
+ *
+ * Usage:
+ *
+ * <pre>
+ * ExtJoiner \
+ * &lt;ext_file0&gt; &lt;ext_file1&gt; ... &lt;ext_fileN&gt;
+ *
+ * where,
+ * &lt;ext_file&gt; is a file that has the base64
+ * encoded DER encoding of an X509 Extension
+ *
+ * ExtensionSequence ::= SEQUENCE OF Extension;
+ *
+ * 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
+ * : }
+ * : }
+ * </pre>
+ *
+ * @version $Revision$, $Date$
+ */
+public class ExtJoiner {
+
+ public static void main(String args[]) {
+ try {
+ if (args.length == 0) {
+ System.out.println("Usage: ExtJoiner <ext_file0> <ext_file1> ... <ext_fileN>");
+ System.exit(0);
+ }
+ DerValue exts[] = new DerValue[args.length];
+
+ for (int i = 0; i < args.length; i++) {
+ byte data[] = getFileData(args[i]);
+
+ exts[i] = new DerValue(data);
+ }
+ DerOutputStream out = new DerOutputStream();
+
+ out.putSequence(exts);
+ System.out.println(Utils.base64encode(out.toByteArray()));
+ } catch (IOException e) {
+ System.out.println(e.toString());
+ }
+ }
+
+ public static byte[] getFileData(String fileName)
+ throws IOException {
+ FileInputStream fis = new FileInputStream(fileName);
+
+ byte data[] = new byte[fis.available()];
+ try {
+ fis.read(data);
+ } finally {
+ fis.close();
+ }
+ return Utils.base64decode(new String(data));
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/GenExtKeyUsage.java b/base/java-tools/src/com/netscape/cmstools/GenExtKeyUsage.java
new file mode 100644
index 000000000..35072aae3
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/GenExtKeyUsage.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.cmstools;
+
+import java.util.Vector;
+
+import com.netscape.cmsutil.util.Utils;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.Extension;
+
+/**
+ * Generates a DER-encoded Extended Key Usage extension.
+ * The first parameter is the criticality of the extension, true or false.
+ * The OIDs to be included in the extension are passed as command-line
+ * arguments. The OIDs are described in RFC 2459. For example,
+ * the OID for code signing is 1.3.6.1.5.5.7.3.3.
+ *
+ * @version $Revision$, $Date$
+ */
+public class GenExtKeyUsage {
+
+ public static void main(String[] args) {
+ try {
+ if (args.length < 2) {
+ System.out.println("Usage: GenExtKeyUsage [true|false] <OID> ...");
+ System.exit(-1);
+ }
+
+ boolean critical = false;
+
+ if (args[0].equalsIgnoreCase("true")) {
+ critical = true;
+ } else if (args[0].equalsIgnoreCase("false")) {
+ critical = false;
+ } else {
+ System.out.println("Usage: GenExtKeyUsage [true|false] <OID> ...");
+ System.exit(-1);
+ }
+
+ // Generate vector of object identifiers from command line
+ Vector<ObjectIdentifier> oids = new Vector<ObjectIdentifier>();
+
+ for (int i = 1; i < args.length; i++) {
+ ObjectIdentifier oid = new ObjectIdentifier(args[i]);
+
+ oids.addElement(oid);
+ }
+
+ // encode all the object identifiers to the DerOutputStream
+ DerOutputStream contents = new DerOutputStream();
+
+ for (int i = 0; i < oids.size(); i++) {
+ contents.putOID(oids.elementAt(i));
+ }
+
+ // stuff the object identifiers into a SEQUENCE
+ DerOutputStream seq = new DerOutputStream();
+
+ seq.write(DerValue.tag_Sequence, contents);
+
+ // encode the SEQUENCE in an octet string
+ DerOutputStream octetString = new DerOutputStream();
+
+ octetString.putOctetString(seq.toByteArray());
+
+ // Construct an extension
+ ObjectIdentifier extKeyUsageOID = new ObjectIdentifier("2.5.29.37");
+ Extension extn = new Extension(extKeyUsageOID, critical,
+ octetString.toByteArray());
+ DerOutputStream extdos = new DerOutputStream();
+
+ extn.encode(extdos);
+
+ // BASE64 encode the whole thing and write it to stdout
+
+ System.out.println(Utils.base64encode(extdos.toByteArray()));
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/GenIssuerAltNameExt.java b/base/java-tools/src/com/netscape/cmstools/GenIssuerAltNameExt.java
new file mode 100644
index 000000000..5c905278f
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/GenIssuerAltNameExt.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.cmstools;
+
+import java.io.ByteArrayOutputStream;
+import java.net.InetAddress;
+
+import com.netscape.cmsutil.util.Utils;
+
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.DNSName;
+import netscape.security.x509.GeneralNameInterface;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.IPAddressName;
+import netscape.security.x509.IssuerAlternativeNameExtension;
+import netscape.security.x509.OIDName;
+import netscape.security.x509.RFC822Name;
+import netscape.security.x509.URIName;
+import netscape.security.x509.X500Name;
+
+/**
+ * This program generates an issuer alternative name extension
+ * in base-64 encoding. The encoding output can be used with
+ * the configuration wizard.
+ *
+ * Usage:
+ *
+ * <pre>
+ * GenIssuerAltNameExt \
+ * &lt;general_type0&gt; &lt;general_name0&gt; ... &lt;general_typeN&gt; &lt;general_nameN&gt;
+ *
+ * where,
+ * &lt;general_type&gt; can be one of the following string:
+ * DNSName
+ * EDIPartyName
+ * IPAddressName
+ * URIName
+ * RFC822Name
+ * OIDName
+ * X500Name
+ * &lt;general_name&gt; is string
+ * </pre>
+ *
+ * @version $Revision$, $Date$
+ */
+public class GenIssuerAltNameExt {
+
+ public static void main(String args[]) {
+ try {
+ if ((args.length == 0) || (args.length % 2 != 0)) {
+ doUsage();
+ System.exit(0);
+ }
+ GeneralNames gns = new GeneralNames();
+
+ for (int i = 0; i < args.length; i += 2) {
+ GeneralNameInterface gni =
+ buildGeneralNameInterface(
+ args[i], args[i + 1]);
+
+ gns.addElement(gni);
+ }
+
+ IssuerAlternativeNameExtension sane =
+ new IssuerAlternativeNameExtension(gns);
+
+ output(sane);
+ } catch (Exception e) {
+ System.out.println(e.toString());
+ }
+ }
+
+ public static void output(IssuerAlternativeNameExtension ext)
+ throws Exception {
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+
+ ext.encode(os);
+
+ System.out.println(
+ Utils.base64encode(os.toByteArray())
+ );
+ }
+
+ public static void doUsage() {
+ System.out.println();
+ System.out.println(
+ "Usage: GenIssuerAltNameExt <general_type0> <general_name0> ... <general_typeN> <general_nameN>");
+ System.out.println("where,");
+ System.out.println("<general_type> can be one of the following string:");
+ System.out.println("\tDNSName");
+ System.out.println("\tEDIPartyName");
+ System.out.println("\tIPAddressName");
+ System.out.println("\tURIName");
+ System.out.println("\tRFC822Name");
+ System.out.println("\tOIDName");
+ System.out.println("\tX500Name");
+ System.out.println("<general_name> is a string");
+ }
+
+ public static GeneralNameInterface buildGeneralNameInterface(
+ String type, String value) throws Exception {
+ if (type.equals("DNSName")) {
+ return new DNSName(value);
+ } else if (type.equals("EDIPartyName")) {
+ return new DNSName(value);
+ } else if (type.equals("IPAddressName")) {
+ InetAddress addr = InetAddress.getByName(value);
+
+ return new IPAddressName(addr.getAddress());
+ } else if (type.equals("URIName")) {
+ return new URIName(value);
+ } else if (type.equals("OIDName")) {
+ return new OIDName(new ObjectIdentifier(value));
+ } else if (type.equals("RFC822Name")) {
+ return new RFC822Name(value);
+ } else if (type.equals("X500Name")) {
+ return new X500Name(value);
+ } else {
+ System.out.println("Error: unknown general_type " +
+ type);
+ doUsage();
+ System.exit(0);
+ return null;
+ }
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/GenSubjectAltNameExt.java b/base/java-tools/src/com/netscape/cmstools/GenSubjectAltNameExt.java
new file mode 100644
index 000000000..35e07f772
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/GenSubjectAltNameExt.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.cmstools;
+
+import java.io.ByteArrayOutputStream;
+import java.net.InetAddress;
+
+import com.netscape.cmsutil.util.Utils;
+
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.DNSName;
+import netscape.security.x509.GeneralNameInterface;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.IPAddressName;
+import netscape.security.x509.OIDName;
+import netscape.security.x509.RFC822Name;
+import netscape.security.x509.SubjectAlternativeNameExtension;
+import netscape.security.x509.URIName;
+import netscape.security.x509.X500Name;
+
+/**
+ * This program generates an subject alternative name extension
+ * in base-64 encoding. The encoding output can be used with
+ * the configuration wizard.
+ *
+ * Usage:
+ *
+ * <pre>
+ * GenSubjectAltNameExt \
+ * &lt;general_type0&gt; &lt;general_name0&gt; ... &lt;general_typeN&gt; &lt;general_nameN&gt;
+ *
+ * where,
+ * &lt;general_type&gt; can be one of the following string:
+ * DNSName
+ * EDIPartyName
+ * IPAddressName
+ * URIName
+ * RFC822Name
+ * OIDName
+ * X500Name
+ * &lt;general_name&gt; is string
+ * </pre>
+ *
+ * @version $Revision$, $Date$
+ */
+public class GenSubjectAltNameExt {
+
+ public static void main(String args[]) {
+ try {
+ if ((args.length == 0) || (args.length % 2 != 0)) {
+ doUsage();
+ System.exit(0);
+ }
+ GeneralNames gns = new GeneralNames();
+
+ for (int i = 0; i < args.length; i += 2) {
+ GeneralNameInterface gni =
+ buildGeneralNameInterface(
+ args[i], args[i + 1]);
+
+ gns.addElement(gni);
+ }
+
+ SubjectAlternativeNameExtension sane =
+ new SubjectAlternativeNameExtension(gns);
+
+ output(sane);
+ } catch (Exception e) {
+ System.out.println(e.toString());
+ }
+ }
+
+ public static void output(SubjectAlternativeNameExtension ext)
+ throws Exception {
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+
+ ext.encode(os);
+
+ System.out.println(
+ Utils.base64encode(os.toByteArray())
+ );
+ }
+
+ public static void doUsage() {
+ System.out.println();
+ System.out
+ .println("Usage: GenSubjectAltNameExt <general_type0> <general_name0> ... <general_typeN> <general_nameN>");
+ System.out.println("where,");
+ System.out.println("<general_type> can be one of the following string:");
+ System.out.println("\tDNSName");
+ System.out.println("\tEDIPartyName");
+ System.out.println("\tIPAddressName");
+ System.out.println("\tURIName");
+ System.out.println("\tRFC822Name");
+ System.out.println("\tOIDName");
+ System.out.println("\tX500Name");
+ System.out.println("<general_name> is a string");
+ }
+
+ public static GeneralNameInterface buildGeneralNameInterface(
+ String type, String value) throws Exception {
+ if (type.equals("DNSName")) {
+ return new DNSName(value);
+ } else if (type.equals("EDIPartyName")) {
+ return new DNSName(value);
+ } else if (type.equals("IPAddressName")) {
+ InetAddress addr = InetAddress.getByName(value);
+
+ return new IPAddressName(addr.getAddress());
+ } else if (type.equals("URIName")) {
+ return new URIName(value);
+ } else if (type.equals("OIDName")) {
+ return new OIDName(new ObjectIdentifier(value));
+ } else if (type.equals("RFC822Name")) {
+ return new RFC822Name(value);
+ } else if (type.equals("X500Name")) {
+ return new X500Name(value);
+ } else {
+ System.out.println("Error: unknown general_type " +
+ type);
+ doUsage();
+ System.exit(0);
+ return null;
+ }
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/HttpClient.java b/base/java-tools/src/com/netscape/cmstools/HttpClient.java
new file mode 100644
index 000000000..c8817b52f
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/HttpClient.java
@@ -0,0 +1,403 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmstools;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.net.Socket;
+import java.net.SocketException;
+import java.util.StringTokenizer;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.ssl.SSLHandshakeCompletedEvent;
+import org.mozilla.jss.ssl.SSLHandshakeCompletedListener;
+import org.mozilla.jss.ssl.SSLSocket;
+import org.mozilla.jss.util.Password;
+
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * This class implements a CMC Enroll client for testing.
+ *
+ * @version $Revision$, $Date$
+ */
+public class HttpClient {
+ private String _host = null;
+ private int _port = 0;
+ private boolean _secure = false;
+
+ public static final int ARGC = 1;
+ static final int cipherSuites[] = {
+ SSLSocket.SSL3_RSA_WITH_RC4_128_MD5,
+ SSLSocket.SSL3_RSA_WITH_3DES_EDE_CBC_SHA,
+ SSLSocket.SSL3_RSA_WITH_DES_CBC_SHA,
+ SSLSocket.SSL3_RSA_EXPORT_WITH_RC4_40_MD5,
+ SSLSocket.SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
+ SSLSocket.SSL3_RSA_WITH_NULL_MD5,
+ 0
+ };
+
+ public HttpClient(String host, int port, String secure)
+ throws Exception {
+ _host = host;
+ _port = port;
+ if (secure.equals("true"))
+ _secure = true;
+ }
+
+ public static byte[] getBytesFromFile(String filename) throws IOException {
+ File file = new File(filename);
+ FileInputStream is = new FileInputStream(file);
+
+ long length = file.length();
+
+ if (length > Integer.MAX_VALUE) {
+ throw new IOException("Input file " + filename +
+ " is too large. Must be smaller than " + Integer.MAX_VALUE);
+ }
+
+ byte[] bytes = new byte[(int) length];
+
+ int offset = 0;
+ int numRead = 0;
+ while (offset < bytes.length
+ && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
+ offset += numRead;
+ }
+
+ if (offset < bytes.length) {
+ throw new IOException("Could not completely read file " + filename);
+ }
+
+ is.close();
+ return bytes;
+ }
+
+ public void send(String ifilename, String ofilename, String dbdir,
+ String nickname, String password, String servlet, String clientmode)
+ throws Exception {
+ byte[] b = getBytesFromFile(ifilename);
+
+ System.out.println("Total number of bytes read = " + b.length);
+
+ DataOutputStream dos = null;
+ InputStream is = null;
+ if (_secure) {
+ try {
+ CryptoManager.InitializationValues vals =
+ new CryptoManager.InitializationValues(dbdir, "", "", "secmod.db");
+ CryptoManager.initialize(vals);
+ SSLSocket socket = new SSLSocket(_host, _port);
+ int i;
+
+ for (i = SSLSocket.SSL2_RC4_128_WITH_MD5; i <= SSLSocket.SSL2_RC2_128_CBC_EXPORT40_WITH_MD5; ++i) {
+ try {
+ socket.setCipherPreference(i, true);
+ } catch (SocketException e) {
+ }
+ }
+ //skip SSL_EN_IDEA_128_EDE3_CBC_WITH_MD5
+ for (i = SSLSocket.SSL2_DES_64_CBC_WITH_MD5; i <= SSLSocket.SSL2_DES_192_EDE3_CBC_WITH_MD5; ++i) {
+ try {
+ socket.setCipherPreference(i, true);
+ } catch (SocketException e) {
+ }
+ }
+ for (i = 0; cipherSuites[i] != 0; ++i) {
+ try {
+ socket.setCipherPreference(cipherSuites[i], true);
+ } catch (SocketException e) {
+ }
+ }
+ SSLHandshakeCompletedListener listener = new ClientHandshakeCB(this);
+ socket.addHandshakeCompletedListener(listener);
+
+ if (clientmode != null && clientmode.equals("true")) {
+ CryptoManager cm = CryptoManager.getInstance();
+ CryptoToken token = cm.getInternalKeyStorageToken();
+ Password pass = new Password(password.toCharArray());
+ token.login(pass);
+ X509Certificate cert = cm.findCertByNickname(nickname);
+ if (cert == null)
+ System.out.println("client cert is null");
+ else
+ System.out.println("client cert is not null");
+ socket.setUseClientMode(true);
+ socket.setClientCertNickname(nickname);
+ }
+
+ socket.forceHandshake();
+ dos = new DataOutputStream(socket.getOutputStream());
+ is = socket.getInputStream();
+ } catch (Exception e) {
+ System.out.println("Exception: " + e.toString());
+ return;
+ }
+ } else {
+ Socket socket = new Socket(_host, _port);
+ dos = new DataOutputStream(socket.getOutputStream());
+ is = socket.getInputStream();
+ }
+
+ // send request
+ if (servlet == null) {
+ System.out.println("Missing servlet name.");
+ printUsage();
+ } else {
+ String s = "POST " + servlet + " HTTP/1.0\r\n";
+ dos.writeBytes(s);
+ }
+ dos.writeBytes("Content-length: " + b.length + "\r\n");
+ dos.writeBytes("\r\n");
+ dos.write(b);
+ dos.flush();
+
+ FileOutputStream fof = new FileOutputStream(ofilename);
+ boolean startSaving = false;
+ int sum = 0;
+ boolean hack = false;
+ try {
+ while (true) {
+ int r = is.read();
+ if (r == -1)
+ break;
+ if (r == 10) {
+ sum++;
+ }
+ if (sum == 6) {
+ startSaving = true;
+ continue;
+ }
+ if (startSaving) {
+ if (hack) {
+ fof.write(r);
+ }
+ if (hack == false) {
+ hack = true;
+ }
+ }
+ }
+ } catch (IOException e) {
+ }
+ fof.close();
+
+ byte[] bout = getBytesFromFile(ofilename);
+ System.out.println("Total number of bytes read = " + bout.length);
+
+ ByteArrayOutputStream bs = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(bs);
+ ps.print(Utils.base64encode(bout));
+ System.out.println(bs.toString());
+
+ System.out.println("");
+ System.out.println("The response in binary format is stored in " + ofilename);
+ System.out.println("");
+ }
+
+ static void printUsage() {
+ System.out.println("");
+ System.out.println("Usage: HttpClient <configuration file>");
+ System.out.println("For example, HttpClient HttpClient.cfg");
+ System.out.println("");
+ System.out.println("The configuration file should look like as follows:");
+ System.out.println("");
+ System.out.println("#host: host name for the http server");
+ System.out.println("host=host1.a.com");
+ System.out.println("");
+ System.out.println("#port: port number");
+ System.out.println("port=1025");
+ System.out.println("");
+ System.out.println("#secure: true for secure connection, false for nonsecure connection");
+ System.out.println("secure=false");
+ System.out.println("");
+ System.out.println("#input: full path for the enrollment request, the content must be in binary format");
+ System.out.println("input=/u/doc/cmcReqCRMFBin");
+ System.out.println("");
+ System.out.println("#output: full path for the response in binary format");
+ System.out.println("output=/u/doc/cmcResp");
+ System.out.println("");
+ System.out.println("#dbdir: directory for cert8.db, key3.db and secmod.db");
+ System.out.println("#This parameter will be ignored if secure=false");
+ System.out.println("dbdir=/u/smith/.netscape");
+ System.out.println("");
+ System.out.println("#clientmode: true for client authentication, false for no client authentication");
+ System.out.println("#This parameter will be ignored if secure=false");
+ System.out.println("clientmode=false");
+ System.out.println("");
+ System.out.println("#password: password for cert8.db");
+ System.out.println("#This parameter will be ignored if secure=false and clientauth=false");
+ System.out.println("password=");
+ System.out.println("");
+ System.out.println("#nickname: nickname for client certificate");
+ System.out.println("#This parameter will be ignored if clientmode=false");
+ System.out.println("nickname=");
+ System.out.println("");
+ System.out.println("#servlet: servlet name");
+ System.out.println("servlet=/ca/profileSubmitCMCFull");
+ System.out.println("");
+ System.exit(0);
+ }
+
+ public static void main(String args[]) {
+ String host = null, portstr = null, secure = null, dbdir = null, nickname = null;
+ String password = null, ofilename = null, ifilename = null;
+ String servlet = null;
+ String clientmode = null;
+
+ System.out.println("");
+
+ // Check that the correct # of arguments were submitted to the program
+ if (args.length != (ARGC)) {
+ System.out.println("Wrong number of parameters:" + args.length);
+ printUsage();
+ }
+
+ String configFile = args[0];
+ BufferedReader reader = null;
+ try {
+ reader = new BufferedReader(new InputStreamReader(
+ new BufferedInputStream(
+ new FileInputStream(configFile))));
+ } catch (FileNotFoundException e) {
+ System.out.println("HttpClient: can't find configuration file: " + configFile);
+ printUsage();
+ System.exit(1);
+ } catch (Exception e) {
+ e.printStackTrace();
+ printUsage();
+ return;
+ }
+
+ try {
+ String str = "";
+ while ((str = reader.readLine()) != null) {
+ str = str.trim();
+ if (!str.startsWith("#") && str.length() > 0) {
+ StringTokenizer tokenizer = new StringTokenizer(str, "=");
+ if (tokenizer.hasMoreTokens()) {
+ String name = tokenizer.nextToken();
+ String val = null;
+ if (tokenizer.countTokens() > 0)
+ val = tokenizer.nextToken();
+ if (name.equals("host")) {
+ host = val;
+ } else if (name.equals("port")) {
+ portstr = val;
+ } else if (name.equals("secure")) {
+ secure = val;
+ } else if (name.equals("dbdir")) {
+ dbdir = val;
+ } else if (name.equals("nickname")) {
+ nickname = val;
+ } else if (name.equals("password")) {
+ password = val;
+ } else if (name.equals("output")) {
+ ofilename = val;
+ } else if (name.equals("input")) {
+ ifilename = val;
+ } else if (name.equals("clientmode")) {
+ clientmode = val;
+ } else if (name.equals("servlet")) {
+ servlet = val;
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ printUsage();
+ }
+
+ if (host == null) {
+ System.out.println("Missing host name.");
+ printUsage();
+ }
+
+ if (portstr == null) {
+ System.out.println("Missing port number.");
+ printUsage();
+ }
+
+ if (servlet == null) {
+ System.out.println("Missing servlet name.");
+ printUsage();
+ }
+
+ if (ifilename == null) {
+ System.out.println("Missing input filename for the enrollment request.");
+ printUsage();
+ }
+
+ if (ofilename == null) {
+ System.out.println("Missing output filename for the response.");
+ printUsage();
+ }
+
+ int port = Integer.parseInt(portstr);
+
+ if (secure != null && secure.equals("true")) {
+ if (dbdir == null) {
+ System.out.println("Missing directory name for the cert7.db.");
+ printUsage();
+ }
+
+ if (clientmode != null && clientmode.equals("true")) {
+ if (password == null) {
+ System.out.println("Missing password for the cert7.db.");
+ printUsage();
+ }
+ if (nickname == null) {
+ System.out.println("Missing nickname for the client certificate");
+ printUsage();
+ }
+ }
+ }
+
+ try {
+ HttpClient client =
+ new HttpClient(host, port, secure);
+ client.send(ifilename, ofilename, dbdir, nickname, password, servlet, clientmode);
+ } catch (Exception e) {
+ System.out.println("Error: " + e.toString());
+ }
+ }
+
+ class ClientHandshakeCB implements SSLHandshakeCompletedListener {
+ Object sc;
+
+ public ClientHandshakeCB(Object sc) {
+ this.sc = sc;
+ }
+
+ public void handshakeCompleted(SSLHandshakeCompletedEvent event) {
+ System.out.println("handshake happened");
+ }
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/OCSPClient.java b/base/java-tools/src/com/netscape/cmstools/OCSPClient.java
new file mode 100644
index 000000000..5b9abe495
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/OCSPClient.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.cmstools;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Socket;
+import java.security.MessageDigest;
+
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509Key;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.NULL;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+
+import com.netscape.cmsutil.ocsp.BasicOCSPResponse;
+import com.netscape.cmsutil.ocsp.CertID;
+import com.netscape.cmsutil.ocsp.CertStatus;
+import com.netscape.cmsutil.ocsp.GoodInfo;
+import com.netscape.cmsutil.ocsp.OCSPRequest;
+import com.netscape.cmsutil.ocsp.OCSPResponse;
+import com.netscape.cmsutil.ocsp.Request;
+import com.netscape.cmsutil.ocsp.ResponseBytes;
+import com.netscape.cmsutil.ocsp.ResponseData;
+import com.netscape.cmsutil.ocsp.RevokedInfo;
+import com.netscape.cmsutil.ocsp.SingleResponse;
+import com.netscape.cmsutil.ocsp.TBSRequest;
+import com.netscape.cmsutil.ocsp.UnknownInfo;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * This class implements a OCSP client for testing.
+ *
+ * @version $Revision$, $Date$
+ */
+public class OCSPClient {
+ private String _host = null;
+ private int _port = 0;
+
+ public OCSPClient(String host, int port, String dbdir)
+ throws Exception {
+ _host = host;
+ _port = port;
+ CryptoManager.initialize(dbdir);
+ }
+
+ public void send(String uri, String nickname, int serialno, String output)
+ throws Exception {
+ CryptoManager manager = CryptoManager.getInstance();
+ X509Certificate caCert = manager.findCertByNickname(nickname);
+ OCSPRequest request = getOCSPRequest(caCert, serialno);
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ request.encode(os);
+ byte request_data[] = os.toByteArray();
+ sendOCSPRequest(uri, _host, _port, request_data, output);
+ }
+
+ public void sendRequestData(String uri, String nickname, byte request_data[], String output)
+ throws Exception {
+ sendOCSPRequest(uri, _host, _port, request_data, output);
+ }
+
+ public OCSPRequest getOCSPRequest(X509Certificate caCert, int serialno)
+ throws Exception {
+ MessageDigest md = MessageDigest.getInstance("SHA");
+
+ // calculate issuer key hash
+ X509CertImpl x509Cert = new X509CertImpl(caCert.getEncoded());
+ X509Key x509key = (X509Key) x509Cert.getPublicKey();
+ byte issuerKeyHash[] = md.digest(x509key.getKey());
+
+ // calculate name hash
+ X500Name name = (X500Name) x509Cert.getSubjectDN();
+ byte issuerNameHash[] = md.digest(name.getEncoded());
+ // constructing the OCSP request
+ CertID certid = new CertID(
+ new AlgorithmIdentifier(
+ new OBJECT_IDENTIFIER("1.3.14.3.2.26"), new NULL()),
+ new OCTET_STRING(issuerNameHash),
+ new OCTET_STRING(issuerKeyHash),
+ new INTEGER(serialno));
+ Request request = new Request(certid, null);
+ SEQUENCE requestList = new SEQUENCE();
+ requestList.addElement(request);
+ TBSRequest tbsRequest = new TBSRequest(null, null, requestList, null);
+ return new OCSPRequest(tbsRequest, null);
+ }
+
+ public void sendOCSPRequest(String uri, String host, int port,
+ byte request_data[], String output) throws Exception {
+ Socket socket = new Socket(host, port);
+
+ // send request
+ System.out.println("URI: " + uri);
+
+ DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
+ dos.writeBytes("POST " + uri + " HTTP/1.0\r\n");
+ dos.writeBytes("Content-length: " + request_data.length + "\r\n");
+ dos.writeBytes("\r\n");
+ dos.write(request_data);
+ dos.flush();
+
+ System.out.println("Data Length: " + request_data.length);
+ System.out.println("Data: " + Utils.base64encode(request_data));
+
+ InputStream iiss = socket.getInputStream();
+ FileOutputStream fof = new FileOutputStream(output);
+ boolean startSaving = false;
+ int sum = 0;
+ boolean hack = false;
+ try {
+ while (true) {
+ int r = iiss.read();
+ if (r == -1)
+ break;
+ if (r == 10) {
+ sum++;
+ }
+ if (sum == 6) {
+ startSaving = true;
+ continue;
+ }
+ if (startSaving) {
+ if (hack) {
+ fof.write(r);
+ }
+ if (hack == false) {
+ hack = true;
+ }
+ }
+ } // while
+ } catch (IOException e) {
+ }
+ fof.close();
+
+ // parse OCSPResponse
+ BufferedInputStream fis =
+ new BufferedInputStream(
+ new FileInputStream(output));
+ OCSPResponse resp = (OCSPResponse)
+ OCSPResponse.getTemplate().decode(fis);
+ ResponseBytes bytes = resp.getResponseBytes();
+ BasicOCSPResponse basic = (BasicOCSPResponse)
+ BasicOCSPResponse.getTemplate().decode(
+ new ByteArrayInputStream(bytes.getResponse().toByteArray()));
+ ResponseData rd = basic.getResponseData();
+ for (int i = 0; i < rd.getResponseCount(); i++) {
+ SingleResponse rd1 = rd.getResponseAt(i);
+ System.out.println("CertID.serialNumber=" +
+ rd1.getCertID().getSerialNumber());
+ CertStatus status1 = rd1.getCertStatus();
+ if (status1 instanceof GoodInfo) {
+ System.out.println("CertStatus=Good");
+ }
+ if (status1 instanceof UnknownInfo) {
+ System.out.println("CertStatus=Unknown");
+ }
+ if (status1 instanceof RevokedInfo) {
+ System.out.println("CertStatus=Revoked");
+ }
+ }
+ }
+
+ public static void printUsage() {
+ System.out.println("Usage: OCSPClient " +
+ "<host> <port> <dbdir> <nickname> <serialno_or_filename> <output> <times>");
+ System.out.println(" <host> = OCSP server hostname");
+ System.out.println(" <port> = OCSP server port number");
+ System.out.println(" <dbdir> = Certificate Database Directory");
+ System.out.println(" <nickname> = Nickname of CA Certificate");
+ System.out.println(
+ " <serialno_or_filename> = Serial Number Being Checked, Or Name of file that contains the request");
+ System.out.println(" <output> = Filename of Response in DER encoding");
+ System.out.println(" <times> = Submit Request Multiple Times");
+ System.out.println(" [<uri>] = OCSP Service URI (i.e. /ocsp/ee/ocsp)");
+ }
+
+ public static void main(String args[]) {
+ if (args.length != 7 && args.length != 8) {
+ System.out.println("ERROR: Invalid number of arguments - got "
+ + args.length + " expected 7!");
+ for (int i = 0; i < args.length; i++) {
+ System.out.println("arg[" + i + "]=" + args[i]);
+ }
+ printUsage();
+ System.exit(0);
+ }
+
+ String host = args[0];
+ int port = -1;
+ try {
+ port = Integer.parseInt(args[1]);
+ } catch (Exception e) {
+ System.out.println("Error: Invalid Port Number");
+ printUsage();
+ System.exit(0);
+ }
+ String dbdir = args[2];
+ String nickname = args[3];
+ int serialno = -1;
+ byte data[] = null;
+ try {
+ serialno = Integer.parseInt(args[4]);
+ } catch (Exception e) {
+ try {
+ System.out.println("Warning: Serial Number not found. It may be a filename.");
+ /* it could be a file name */
+ FileInputStream fis = new FileInputStream(args[4]);
+ System.out.println("File Size: " + fis.available());
+ data = new byte[fis.available()];
+ fis.read(data);
+ } catch (Exception e1) {
+ System.out.println("Error: Invalid Serial Number or File Name");
+ printUsage();
+ System.exit(0);
+ }
+ }
+ String output = args[5];
+ int times = 1;
+ try {
+ times = Integer.parseInt(args[6]);
+ } catch (Exception e) {
+ System.out.println("Error: Invalid Times");
+ printUsage();
+ System.exit(0);
+ }
+ String uri = "/ocsp/ee/ocsp";
+ if (args.length > 7) {
+ uri = args[7];
+ }
+ try {
+ OCSPClient client =
+ new OCSPClient(host, port, dbdir);
+ for (int i = 0; i < times; i++) {
+ if (data != null) {
+ client.sendRequestData(uri, nickname, data, output);
+ } else {
+ client.send(uri, nickname, serialno, output);
+ }
+ }
+ System.out.println("Success: Output " + output);
+ } catch (Exception e) {
+ System.out.println("Error: " + e.toString());
+ printUsage();
+ System.exit(0);
+ }
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/PKCS10Client.java b/base/java-tools/src/com/netscape/cmstools/PKCS10Client.java
new file mode 100644
index 000000000..7cd50a37a
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/PKCS10Client.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.cmstools;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.security.KeyPair;
+import java.security.MessageDigest;
+
+import netscape.security.x509.X500Name;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.PrintableString;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.KeyPairAlgorithm;
+import org.mozilla.jss.crypto.KeyPairGenerator;
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+import org.mozilla.jss.pkcs10.CertificationRequest;
+import org.mozilla.jss.pkcs10.CertificationRequestInfo;
+import org.mozilla.jss.pkix.primitive.AVA;
+import org.mozilla.jss.pkix.primitive.Attribute;
+import org.mozilla.jss.pkix.primitive.Name;
+import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
+import org.mozilla.jss.util.Password;
+
+import com.netscape.cmsutil.util.HMACDigest;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * Generates a 1024-bit RSA key pair in the security database, constructs a
+ * PKCS#10 certificate request with the public key, and outputs the request
+ * to a file.
+ * <p>
+ * PKCS #10 is a certification request syntax standard defined by RSA. A CA may support multiple types of certificate
+ * requests. The Certificate System CA supports KEYGEN, PKCS#10, CRMF, and CMC.
+ * <p>
+ * To get a certificate from the CA, the certificate request needs to be submitted to and approved by a CA agent. Once
+ * approved, a certificate is created for the request, and certificate attributes, such as extensions, are populated
+ * according to certificate profiles.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public class PKCS10Client {
+
+ private static void printUsage() {
+ System.out.println(
+ "Usage: PKCS10Client -p <certdb password> -d <location of certdb> -o <output file which saves the base64 PKCS10> -s <subjectDN>\n");
+ }
+
+ public static void main(String args[]) {
+ String dbdir = null, ofilename = null, password = null, subjectName = null;
+
+ if (args.length != 8) {
+ printUsage();
+ System.exit(1);
+ }
+
+ for (int i = 0; i < args.length; i++) {
+ String name = args[i];
+ if (name.equals("-p")) {
+ password = args[i + 1];
+ } else if (name.equals("-d")) {
+ dbdir = args[i + 1];
+ } else if (name.equals("-o")) {
+ ofilename = args[i + 1];
+ } else if (name.equals("-s")) {
+ subjectName = args[i + 1];
+ }
+ }
+
+ if (password == null || ofilename == null || subjectName == null) {
+ System.out.println("Illegal input parameters.");
+ printUsage();
+ System.exit(1);
+ }
+
+ if (dbdir == null)
+ dbdir = ".";
+
+ try {
+ String mPrefix = "";
+ CryptoManager.InitializationValues vals =
+ new CryptoManager.InitializationValues(dbdir, mPrefix,
+ mPrefix, "secmod.db");
+
+ CryptoManager.initialize(vals);
+ CryptoManager cm = CryptoManager.getInstance();
+ CryptoToken token = cm.getInternalKeyStorageToken();
+ Password pass = new Password(password.toCharArray());
+
+ token.login(pass);
+ KeyPairGenerator kg = token.getKeyPairGenerator(KeyPairAlgorithm.RSA);
+ kg.initialize(1024);
+ KeyPair pair = kg.genKeyPair();
+
+ // Add idPOPLinkWitness control
+ String secretValue = "testing";
+ byte[] key1 = null;
+ byte[] finalDigest = null;
+ MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1");
+ key1 = SHA1Digest.digest(secretValue.getBytes());
+
+ /* seed */
+ byte[] b =
+ { 0x10, 0x53, 0x42, 0x24, 0x1a, 0x2a, 0x35, 0x3c,
+ 0x7a, 0x52, 0x54, 0x56, 0x71, 0x65, 0x66, 0x4c,
+ 0x51, 0x34, 0x35, 0x23, 0x3c, 0x42, 0x43, 0x45,
+ 0x61, 0x4f, 0x6e, 0x43, 0x1e, 0x2a, 0x2b, 0x31,
+ 0x32, 0x34, 0x35, 0x36, 0x55, 0x51, 0x48, 0x14,
+ 0x16, 0x29, 0x41, 0x42, 0x43, 0x7b, 0x63, 0x44,
+ 0x6a, 0x12, 0x6b, 0x3c, 0x4c, 0x3f, 0x00, 0x14,
+ 0x51, 0x61, 0x15, 0x22, 0x23, 0x5f, 0x5e, 0x69 };
+
+ HMACDigest hmacDigest = new HMACDigest(SHA1Digest, key1);
+ hmacDigest.update(b);
+ finalDigest = hmacDigest.digest();
+
+ OCTET_STRING ostr = new OCTET_STRING(finalDigest);
+ Attribute attr = new Attribute(OBJECT_IDENTIFIER.id_cmc_idPOPLinkWitness, ostr);
+
+ SET attributes = new SET();
+ attributes.addElement(attr);
+ Name n = getJssName(subjectName);
+ SubjectPublicKeyInfo subjectPub = new SubjectPublicKeyInfo(pair.getPublic());
+ CertificationRequestInfo certReqInfo =
+ new CertificationRequestInfo(new INTEGER(0), n, subjectPub, attributes);
+ CertificationRequest certRequest = new CertificationRequest(certReqInfo,
+ pair.getPrivate(), SignatureAlgorithm.RSASignatureWithMD5Digest);
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ certRequest.encode(bos);
+ byte[] bb = bos.toByteArray();
+
+ String b64E = Utils.base64encode(bb);
+
+ System.out.println("");
+ System.out.println(b64E);
+ System.out.println("");
+
+ PrintStream ps = null;
+ ps = new PrintStream(new FileOutputStream(ofilename));
+ ps.println(b64E);
+ ps.flush();
+ ps.close();
+ } catch (Exception e) {
+ }
+ }
+
+ static Name getJssName(String dn) {
+
+ X500Name x5Name = null;
+
+ try {
+ x5Name = new X500Name(dn);
+ } catch (IOException e) {
+
+ System.out.println("Illegal Subject Name: " + dn + " Error: " + e.toString());
+ System.out.println("Filling in default Subject Name......");
+ return null;
+ }
+
+ Name ret = new Name();
+ netscape.security.x509.RDN[] names = null;
+ names = x5Name.getNames();
+ int nameLen = x5Name.getNamesLength();
+
+ netscape.security.x509.RDN cur = null;
+
+ for (int i = 0; i < nameLen; i++) {
+ cur = names[i];
+ String rdnStr = cur.toString();
+ String[] split = rdnStr.split("=");
+
+ if (split.length != 2)
+ continue;
+
+ try {
+ if (split[0].equals("UID")) {
+ ret.addElement(new AVA(new OBJECT_IDENTIFIER("0.9.2342.19200300.100.1.1"), new PrintableString(
+ split[1])));
+ // System.out.println("UID found : " + split[1]);
+ }
+
+ if (split[0].equals("C")) {
+ ret.addCountryName(split[1]);
+ // System.out.println("C found : " + split[1]);
+ continue;
+ }
+
+ if (split[0].equals("CN")) {
+ ret.addCommonName(split[1]);
+ // System.out.println("CN found : " + split[1]);
+ continue;
+ }
+
+ if (split[0].equals("L")) {
+ ret.addLocalityName(split[1]);
+ // System.out.println("L found : " + split[1]);
+ continue;
+ }
+
+ if (split[0].equals("O")) {
+ ret.addOrganizationName(split[1]);
+ // System.out.println("O found : " + split[1]);
+ continue;
+ }
+
+ if (split[0].equals("ST")) {
+ ret.addStateOrProvinceName(split[1]);
+ // System.out.println("ST found : " + split[1]);
+ continue;
+ }
+
+ if (split[0].equals("OU")) {
+ ret.addOrganizationalUnitName(split[1]);
+ // System.out.println("OU found : " + split[1]);
+ continue;
+ }
+ } catch (Exception e) {
+ System.out.println("Error constructing RDN: " + rdnStr + " Error: " + e.toString());
+ continue;
+ }
+ }
+
+ return ret;
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/PKCS12Export.java b/base/java-tools/src/com/netscape/cmstools/PKCS12Export.java
new file mode 100644
index 000000000..8d8e858f2
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/PKCS12Export.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.cmstools;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.security.MessageDigest;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.BMPString;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.crypto.Cipher;
+import org.mozilla.jss.crypto.CryptoStore;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.EncryptionAlgorithm;
+import org.mozilla.jss.crypto.IVParameterSpec;
+import org.mozilla.jss.crypto.KeyGenAlgorithm;
+import org.mozilla.jss.crypto.KeyGenerator;
+import org.mozilla.jss.crypto.KeyWrapAlgorithm;
+import org.mozilla.jss.crypto.KeyWrapper;
+import org.mozilla.jss.crypto.PBEAlgorithm;
+import org.mozilla.jss.crypto.SymmetricKey;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.pkcs12.AuthenticatedSafes;
+import org.mozilla.jss.pkcs12.CertBag;
+import org.mozilla.jss.pkcs12.PFX;
+import org.mozilla.jss.pkcs12.PasswordConverter;
+import org.mozilla.jss.pkcs12.SafeBag;
+import org.mozilla.jss.pkix.primitive.EncryptedPrivateKeyInfo;
+import org.mozilla.jss.pkix.primitive.PrivateKeyInfo;
+import org.mozilla.jss.util.Password;
+
+/**
+ * Tool for creating PKCS12 file
+ *
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ *
+ */
+public class PKCS12Export {
+
+ private static boolean debugMode = false;
+
+ private static void debug(String s) {
+ if (debugMode)
+ System.out.println("PKCS12Export debug: " + s);
+ }
+
+ private static void printUsage() {
+ System.out.println(
+ "Usage: PKCS12Export -d <cert/key db directory> -p <file containing password for keydb> -w <file containing pkcs12 password> -o <output file for pkcs12>");
+ System.out.println("");
+ System.out.println("If you want to turn on debug, do the following:");
+ System.out.println(
+ "Usage: PKCS12Export -debug -d <cert/key db directory> -p <file containing password for keydb> -w <file containing pkcs12 password> -o <output file for pkcs12>");
+ }
+
+ private static byte[] getEncodedKey(org.mozilla.jss.crypto.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) {
+ debug("PKCS12Export getEncodedKey: Exception=" + e.toString());
+ System.exit(1);
+ }
+
+ return null;
+ }
+
+ private static void addKeyBag(org.mozilla.jss.crypto.PrivateKey pkey, X509Certificate x509cert,
+ Password pass, byte[] localKeyId, SEQUENCE safeContents) {
+ try {
+ PasswordConverter passConverter = new PasswordConverter();
+ byte salt[] = { 0x01, 0x01, 0x01, 0x01 };
+ 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) {
+ debug("PKCS12Export addKeyBag: Exception=" + e.toString());
+ System.exit(1);
+ }
+ }
+
+ private static 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) {
+ debug("PKCS12Export addCertBag: " + e.toString());
+ System.exit(1);
+ }
+
+ return localKeyId;
+ }
+
+ private static byte[] createLocalKeyId(X509Certificate cert) {
+ try {
+ // SHA1 hash of the X509Cert der encoding
+ byte certDer[] = cert.getEncoded();
+
+ MessageDigest md = MessageDigest.getInstance("SHA");
+
+ md.update(certDer);
+ return md.digest();
+ } catch (Exception e) {
+ debug("PKCS12Export createLocalKeyId: Exception: " + e.toString());
+ System.exit(1);
+ }
+
+ return null;
+ }
+
+ private static 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 (Exception e) {
+ debug("PKCS12Export createBagAttrs: Exception=" + e.toString());
+ System.exit(1);
+ }
+
+ return null;
+ }
+
+ public static void main(String args[]) {
+ if (args.length < 8) {
+ printUsage();
+ System.exit(1);
+ }
+
+ String pwdfile = null;
+ String dir = null;
+ String pk12pwdfile = null;
+ String pk12output = null;
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].equals("-d")) {
+ dir = args[i + 1];
+ } else if (args[i].equals("-p")) {
+ pwdfile = args[i + 1];
+ } else if (args[i].equals("-s")) {
+ // snickname = args[i + 1];
+ } else if (args[i].equals("-w")) {
+ pk12pwdfile = args[i + 1];
+ } else if (args[i].equals("-o")) {
+ pk12output = args[i + 1];
+ } else if (args[i].equals("-debug")) {
+ debugMode = true;
+ }
+ }
+
+ debug("The directory for certdb/keydb is " + dir);
+ debug("The password file for keydb is " + pwdfile);
+
+ // get password
+ String pwd = null;
+ try {
+ BufferedReader in = new BufferedReader(new FileReader(pwdfile));
+ pwd = in.readLine();
+ } catch (Exception e) {
+ debug("Failed to read the keydb password from the file. Exception: " + e.toString());
+ System.exit(1);
+ }
+
+ String pk12pwd = null;
+ try {
+ BufferedReader in = new BufferedReader(new FileReader(pk12pwdfile));
+ pk12pwd = in.readLine();
+ } catch (Exception e) {
+ debug("Failed to read the keydb password from the file. Exception: " + e.toString());
+ System.exit(1);
+ }
+
+ CryptoManager cm = null;
+ try {
+ CryptoManager.InitializationValues vals =
+ new CryptoManager.InitializationValues(dir, "", "", "secmod.db");
+ CryptoManager.initialize(vals);
+ cm = CryptoManager.getInstance();
+ } catch (Exception e) {
+ debug("Failed to initialize the certdb.");
+ System.exit(1);
+ }
+
+ SEQUENCE encSafeContents = new SEQUENCE();
+ SEQUENCE safeContents = new SEQUENCE();
+ try {
+ CryptoToken token = cm.getInternalKeyStorageToken();
+ Password pass = new Password(pwd.toCharArray());
+ token.login(pass);
+ CryptoStore store = token.getCryptoStore();
+ X509Certificate[] certs = store.getCertificates();
+ debug("Number of user certificates = " + certs.length);
+ Password pass12 = new Password(pk12pwd.toCharArray());
+ for (int i = 0; i < certs.length; i++) {
+ String nickname = certs[i].getNickname();
+ debug("Certificate nickname = " + nickname);
+ org.mozilla.jss.crypto.PrivateKey prikey = null;
+ try {
+ prikey = cm.findPrivKeyByCert(certs[i]);
+ } catch (Exception e) {
+ debug("PKCS12Export Exception: " + e.toString());
+ }
+
+ if (prikey == null) {
+ debug("Private key is null");
+ addCertBag(certs[i], null, safeContents);
+ } else {
+ debug("Private key is not null");
+ byte localKeyId[] =
+ addCertBag(certs[i], nickname, safeContents);
+ addKeyBag(prikey, certs[i], pass12, localKeyId, encSafeContents);
+ }
+ }
+
+ AuthenticatedSafes authSafes = new AuthenticatedSafes();
+ authSafes.addSafeContents(safeContents);
+ authSafes.addSafeContents(encSafeContents);
+ PFX pfx = new PFX(authSafes);
+ pfx.computeMacData(pass12, null, 5);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ pfx.encode(bos);
+ FileOutputStream fos = new FileOutputStream(pk12output);
+ fos.write(bos.toByteArray());
+ fos.flush();
+ fos.close();
+ pass.clear();
+ pass12.clear();
+ } catch (Exception e) {
+ debug("PKCS12Export Exception: " + e.toString());
+ System.exit(1);
+ }
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/PasswordCache.java b/base/java-tools/src/com/netscape/cmstools/PasswordCache.java
new file mode 100644
index 000000000..ba7fb72a4
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/PasswordCache.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.cmstools;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.SecretDecoderRing.Decryptor;
+import org.mozilla.jss.SecretDecoderRing.Encryptor;
+import org.mozilla.jss.SecretDecoderRing.KeyManager;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.util.Base64OutputStream;
+import org.mozilla.jss.util.Password;
+
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * Tool for interacting with the PWcache
+ *
+ * @version $Revision$, $Date$
+ */
+
+public class PasswordCache {
+
+ /* These are the tags that identify various passwords
+ * They should probably be converted instances of some
+ * class so that we can expose an API to add additional
+ * TAG's for use if I want to add a password for use
+ * with my own authenticaion module
+ */
+ public static final String PROP_PWC_NICKNAME = "sso_key";
+ public static final String PW_TAG_INTERNAL_LDAP_DB = "Internal LDAP Database";
+ private static final String WRONG_NUM_ARGS = "Error: wrong number of arguments";
+ private static final String CERTDB = "cert8.db";
+ private static final String KEYDB = "key3.db";
+
+ private static void usage() {
+ System.out.println(
+ "This tool has to be run from the same directory where pwcache.db file resides, normally <cms instance>/config directory, unless the file's full path is specified in the -c option..\nUsage: PasswordCache <SSO_PASSWORD> <-d cert/key db directory> <-h tokenName> <-P cert/key db prefix> <-c pwcache.db_file_full_path> <-k file containing Base64EncodedKeyID> <COMMAND> ...");
+ System.out.println(" commands:");
+ System.out.println(" 'add <password_name> <password>'");
+ System.out.println(" 'change <password_name> <password>'");
+ System.out.println(" 'delete <password_name>'");
+ System.out.println(" 'rekey'");
+ System.out.println(" 'list'");
+ System.out.println(
+ "\nExample:\n\tPasswordCache thePassword1 -d /usr/netscape/servers/cms/alias -P cert-instance1-machine1- -c pwcache.db -k keyidFile list");
+ System.exit(1);
+ }
+
+ private static boolean debugMode = false;
+
+ public PasswordCache() {
+ }
+
+ private static void debug(String s) {
+ if (debugMode == true)
+ System.out.println("PasswordCache debug: " + s);
+ }
+
+ /**
+ * clean up an argv by removing the trailing, empty arguments
+ *
+ * This is necessary to support the script wrapper which calls the
+ * tool with arguments in quotes such as:
+ * "$1" "$2"
+ * if $2 is not specified, the empty arg "" gets passed, which causes
+ * an error in the arg-count checking code.
+ */
+ private static String[] cleanArgs(String[] s) {
+ int length;
+ int i;
+
+ length = s.length;
+ debug("before cleanArgs argv length =" + length);
+
+ for (i = length - 1; i >= 0; i--) {
+ if (s[i].equals("")) {
+ length--;
+ } else {
+ break;
+ }
+ }
+
+ String[] new_av = new String[length];
+ for (i = 0; i < length; i++) {
+ new_av[i] = s[i];
+ debug("arg " + i + " is " + new_av[i]);
+ }
+ debug("after cleanArgs argv length =" + length);
+
+ return new_av;
+ }
+
+ public static byte[] base64Decode(String s) throws IOException {
+ byte[] d = Utils.base64decode(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");
+ }
+
+ public static void main(String[] av) {
+ // default path is "."
+ String mPath = ".";
+ String mTokenName = null;
+ // default prefix is ""
+ String mPrefix = "";
+ String mKeyIdString = null;
+ byte[] mKeyId = null;
+ String mCacheFile = "pwcache.db";
+
+ String pwdPath = null;
+ String instancePath = null;
+ String instanceName = null;
+
+ String[] argv = cleanArgs(av);
+
+ if (argv.length < 2) {
+ usage();
+ }
+
+ String pw = argv[0];
+
+ char[] testpw = pw.toCharArray();
+ Password pass = new Password(testpw);
+
+ String command = "";
+ String aTag = "";
+ String aPasswd = "";
+
+ int i = 0;
+ for (i = 1; i < argv.length; ++i) {
+ if (argv[i].equals("-d")) {
+ if (++i >= argv.length)
+ usage();
+ mPath = argv[i];
+ } else if (argv[i].equals("-h")) {
+ if (++i >= argv.length)
+ usage();
+ mTokenName = argv[i];
+ } else if (argv[i].equals("-P")) {
+ if (++i >= argv.length)
+ usage();
+ mPrefix = argv[i];
+ } else if (argv[i].equals("-c")) {
+ if (++i >= argv.length)
+ usage();
+ mCacheFile = argv[i];
+ } else if (argv[i].equals("-k")) {
+ if (++i >= argv.length)
+ usage();
+ String keyFile = argv[i];
+ try {
+ BufferedReader r = new BufferedReader(new FileReader(keyFile));
+ mKeyIdString = r.readLine();
+ } catch (Exception e) {
+ System.out.println("Error: " + e.toString());
+ System.exit(1);
+ }
+
+ if (mKeyIdString != null) {
+ try {
+ mKeyId = base64Decode(mKeyIdString);
+ debug("base64Decode of key id string successful");
+ } catch (IOException e) {
+ System.out.println("base64Decode of key id string failed");
+ System.exit(1);
+ }
+ }
+ } else {
+ command = argv[i++];
+ debug("command = " + command);
+
+ if ((command.equals("add")) ||
+ (command.equals("change"))) {
+ aTag = argv[i++];
+ aPasswd = argv[i];
+ debug("command is " + command + " " + aTag + ":" + aPasswd);
+ } else if (command.equals("delete")) {
+ aTag = argv[i];
+ } else if (command.equals("list")) {
+ } else if (command.equals("rekey")) {
+ }
+ break;
+ }
+ }
+
+ try {
+ // initialize CryptoManager
+ System.out.println("cert/key prefix = " + mPrefix);
+ System.out.println("cert/key db path = " + mPath);
+ System.out.println("password cache file = " + mCacheFile);
+
+ CryptoManager.InitializationValues vals =
+ new CryptoManager.InitializationValues(mPath, mPrefix,
+ mPrefix, "secmod.db");
+
+ CryptoManager.initialize(vals);
+
+ CryptoManager cm = CryptoManager.getInstance();
+ CryptoToken token = null;
+ if (mTokenName == null) {
+ token = cm.getInternalKeyStorageToken();
+ System.out.println("token name = internal");
+ } else {
+ token = cm.getTokenByName(mTokenName);
+ System.out.println("token name = " + mTokenName);
+ }
+
+ token.login(pass);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ // generating new key
+ if (command.equals("rekey")) {
+ System.out.println("generating new key...");
+ PWsdrCache cache = null;
+ try {
+ // compose instance name
+ File passwordCacheDB = new File(mCacheFile);
+ pwdPath = passwordCacheDB.getAbsolutePath();
+ int beginIndex = pwdPath.lastIndexOf("cert-");
+ instancePath = pwdPath.substring(beginIndex);
+ int endIndex = 0;
+ endIndex = instancePath.lastIndexOf("config");
+ instanceName = instancePath.substring(0, (endIndex - 1));
+
+ cache = new PWsdrCache(mCacheFile, mTokenName, null, true);
+ cache.deleteUniqueNamedKey(PROP_PWC_NICKNAME
+ + " "
+ + instanceName);
+ byte[] newKeyId = cache.generateSDRKeyWithNickName(
+ PROP_PWC_NICKNAME
+ + " "
+ + instanceName);
+ if (newKeyId != null) {
+ String newKeyIDString = base64Encode(newKeyId);
+ System.out.println("key generated successfully with key id = " +
+ newKeyIDString);
+ System.out.println("Save the VALUE portion of this key id in a local file,");
+ System.out.println("and under variable \"pwcKeyid\" in CS.cfg !!");
+ System.out.println("If you have not already done so,");
+ System.out.println("remove the old pwcache.db and use this local file to add passwords.");
+ // job is done
+ System.exit(0);
+ } else {
+ System.out.println("key expected to be generated but wasn't");
+ System.exit(1);
+ }
+ } catch (Exception e) {
+ System.out.println(e.toString());
+ System.exit(1);
+ }
+ }
+
+ PWsdrCache cache = null;
+ try {
+ cache = new PWsdrCache(mCacheFile, mTokenName, mKeyId, true);
+ } catch (Exception e) {
+ System.out.println(e.toString());
+ System.exit(1);
+ }
+
+ if ((command.equals("add")) || (command.equals("change"))) {
+ // current key id must be specified
+ if (mKeyId == null) {
+ System.out.println("operation failed: no key id specified");
+ System.exit(1);
+ }
+
+ try {
+ System.out.println("adding " + aTag + ":" + aPasswd);
+ cache.addEntry(aTag, aPasswd);
+ } catch (Exception e) {
+ System.out.println("--failed--" + e.toString());
+ }
+ } else if (command.equals("list")) {
+ cache.pprint();
+ } else if (command.equals("delete")) {
+ // current key id must be specified
+ if (mKeyId == null) {
+ System.out.println("operation failed: no key id specified");
+ System.exit(1);
+ }
+
+ try {
+ cache.deleteEntry(aTag);
+ } catch (Exception e) {
+ System.out.println("User not found");
+ }
+ } else {
+ System.out.println("Illegal command: " + command);
+ System.exit(1);
+ }
+ }
+}
+
+/*
+ * A class for managing passwords in the SDR password cache
+ *
+ * @author Christina Fu
+ * @version $Revision$, $Date$
+ */
+class PWsdrCache {
+
+ public static final String PROP_PWC_NICKNAME = "sso_key";
+
+ private String mPWcachedb = null;
+ private byte[] mKeyID = null;
+ private String mTokenName = null;
+ private CryptoToken mToken = null;
+
+ // mTool tells if this is called from the PasswordCache tool
+ private boolean mIsTool = false;
+
+ // for PasswordCache tool (isTool == true)
+ 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);
+ 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);
+ debug("PWsdrCache: SDR key generated");
+ }
+ } catch (TokenException e) {
+ log(0, "generateSDRKey() failed on " + e.toString());
+ throw e;
+ }
+ }
+ } catch (Exception e) {
+ log(0, e.toString());
+ throw e;
+ }
+ return mKeyID;
+ }
+
+ public void addEntry(String tag, String pwd) throws IOException {
+ addEntry(tag, pwd, (Hashtable<String, String>) null);
+ }
+
+ /*
+ * Store passwd in pwcache.
+ */
+ public void addEntry(Hashtable<String, String> ht) throws IOException {
+ addEntry((String) null, (String) null, ht);
+ }
+
+ /*
+ * add passwd in pwcache.
+ */
+ public void addEntry(String tag, String pwd, Hashtable<String, String> tagPwds) throws IOException {
+ System.out.println("PWsdrCache: in addEntry");
+ String stringToAdd = null;
+ String bufs = null;
+
+ if (tagPwds == null) {
+ stringToAdd = tag + ":" + pwd + "\n";
+ } else {
+ Enumeration<String> enum1 = tagPwds.keys();
+
+ while (enum1.hasMoreElements()) {
+ tag = enum1.nextElement();
+ pwd = 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();
+ System.out.println("PWsdrCache: after readPWcache()");
+ if (dcrypts != null) {
+ // converts to Hashtable, replace if tag exists, add
+ // if tag doesn't exist
+ Hashtable<String, String> 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 IOException {
+ String bufs = null;
+
+ String dcrypts = readPWcache();
+
+ if (dcrypts != null) {
+ // converts to Hashtable, replace if tag exists, add
+ // if tag doesn't exist
+ Hashtable<String, String> 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 IOException {
+ debug("about to read password cache");
+ String dcrypts = null;
+ if (mToken == null) {
+ debug("mToken is null");
+ throw new IOException("token must be specified");
+ }
+
+ 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) {
+ System.out.println("Failed for file " + mPWcachedb + " " + e.toString());
+ throw new IOException(e.toString() + ": " + mPWcachedb);
+ } catch (IOException e) {
+ System.out.println("Failed for file " + mPWcachedb + " " + e.toString());
+ throw new IOException(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 (TokenException e) {
+ System.out.println("password cache decrypto failed " + e.toString());
+ e.printStackTrace();
+ throw new IOException("password cache decrypt failed");
+ } catch (UnsupportedEncodingException e) {
+ System.out.println("password cache decrypto failed " + e.toString());
+ e.printStackTrace();
+ throw new IOException("password cache decrypt failed");
+ } catch (Exception e) {
+ System.out.println("password cache decrypto failed " + e.toString());
+ e.printStackTrace();
+ throw new IOException("password cache decrypt failed");
+ }
+ }
+
+ return dcrypts;
+ }
+
+ /*
+ * encrypts and writes the whole String buf into pwcache.db
+ */
+ public void writePWcache(String bufs) throws IOException {
+
+ 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) {
+ System.out.println("password cache encrypt failed " + e.toString());
+ e.printStackTrace();
+ throw new IOException("password cache encrypt failed");
+ }
+
+ File tmpPWcache = new File(mPWcachedb + ".tmp");
+
+ if (tmpPWcache.exists()) {
+ // it wasn't removed?
+ tmpPWcache.delete();
+ }
+ FileOutputStream outstream = new FileOutputStream(mPWcachedb + ".tmp");
+
+ outstream.write(writebuf);
+ outstream.close();
+
+ // Make certain that this temporary file has
+ // the correct permissions.
+ if (!isNT()) {
+ exec("chmod 00660 " + tmpPWcache.getAbsolutePath());
+ }
+
+ File origFile = new File(mPWcachedb);
+
+ try {
+ // Always remove any pre-existing target file
+ if (origFile.exists()) {
+ origFile.delete();
+ }
+
+ if (isNT()) {
+ // NT is very picky on the path
+ exec("copy " +
+ tmpPWcache.getAbsolutePath().replace('/', '\\') + " " +
+ origFile.getAbsolutePath().replace('/', '\\'));
+ } else {
+ // Create a copy of the temporary file which
+ // preserves the temporary file's permissions.
+ exec("cp -p " + tmpPWcache.getAbsolutePath() + " " +
+ origFile.getAbsolutePath());
+ }
+
+ // Remove the temporary file if and only if
+ // the "rename" was successful.
+ if (origFile.exists()) {
+ tmpPWcache.delete();
+
+ // Make certain that the final file has
+ // the correct permissions.
+ if (!isNT()) {
+ exec("chmod 00660 " + origFile.getAbsolutePath());
+ }
+
+ // report success
+ debug("Renaming operation completed for " + mPWcachedb);
+ } else {
+ // report failure and exit
+ debug("Renaming operation failed for " + mPWcachedb);
+ System.exit(1);
+ }
+ } catch (IOException exx) {
+ System.out.println("sdrPWcache: Error " + exx.toString());
+ throw new IOException(exx.toString() + ": " + mPWcachedb);
+ }
+ } catch (FileNotFoundException e) {
+ System.out.println("sdrPWcache: Error " + e.toString());
+ throw new IOException(e.toString() + ": " + mPWcachedb);
+ } catch (IOException e) {
+ System.out.println("Failed for file " + mPWcachedb + " " + e.toString());
+ throw new IOException(e.toString() + ": " + mPWcachedb);
+ } catch (Exception e) {
+ System.out.println("sdrPWcache: Error " + e.toString());
+ throw new IOException(e.toString());
+ }
+ }
+
+ public String hashtable2String(Hashtable<String, String> ht) {
+ Enumeration<String> enum1 = ht.keys();
+ String returnString = null;
+
+ while (enum1.hasMoreElements()) {
+ String tag = enum1.nextElement();
+ String pwd = ht.get(tag);
+
+ if (returnString == null) {
+ returnString = tag + ":" + pwd + "\n";
+ } else {
+ returnString += tag + ":" + pwd + "\n";
+ }
+ }
+ return returnString;
+ }
+
+ public Hashtable<String, String> string2Hashtable(String cache) {
+ Hashtable<String, String> ht = new Hashtable<String, String>();
+
+ // 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<String, String> 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 (IOException e) {
+ System.out.println("dfailed readPWcache() " + 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 {
+ System.out.println("getEntry did not get password for 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 IOException {
+ 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();
+
+ 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) {
+ System.out.println(msg);
+ }
+
+ public void log(int level, String msg) {
+ System.out.println(msg);
+ }
+
+ /*
+ * list passwds in pwcache.
+ */
+ public boolean pprint() {
+ String dcrypts = null;
+
+ try {
+ dcrypts = readPWcache();
+ } catch (IOException e) {
+ System.out.println("failed readPWcache() " + 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/base/java-tools/src/com/netscape/cmstools/PrettyPrintCert.java b/base/java-tools/src/com/netscape/cmstools/PrettyPrintCert.java
new file mode 100644
index 000000000..382c4e312
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/PrettyPrintCert.java
@@ -0,0 +1,248 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmstools;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.security.cert.CertificateException;
+import java.util.Locale;
+
+import com.netscape.cmsutil.util.Utils;
+
+import netscape.security.util.CertPrettyPrint;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.RDN;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+/**
+ * The PrettyPrintCert class is a utility program designed to "pretty print"
+ * a certificate. It assumes that the name of a data file is passed to the
+ * program via the command line, and that the contents contain a certificate
+ * encoded in an ASCII BASE 64 format. Note that the data file may contain
+ * an optional "-----BEGIN" header and/or an optional "-----END" trailer.
+ *
+ * <P>
+ * The program may be invoked as follows:
+ *
+ * <PRE>
+ *
+ * PrettyPrintCert &lt;input filename&gt; [output filename]
+ *
+ * NOTE: &lt;input filename&gt; must contain an ASCII
+ * BASE 64 encoded certificate
+ *
+ * &lt;output filename&gt; contains a certificate displayed
+ * in a "pretty print" ASCII format
+ * </PRE>
+ *
+ * @version $Revision$, $Date$
+ */
+
+public class PrettyPrintCert {
+ // Define constants
+ public static final int ARGC = 2;
+ public static final String HEADER = "-----BEGIN";
+ public static final String TRAILER = "-----END";
+
+ public static void usageAndExit() {
+ System.out.println("Usage: PrettyPrintCert " +
+ "[options] " +
+ "<input filename> " +
+ "[output filename]");
+ System.out.println("\n options: ");
+ System.out.println(" -simpleinfo : prints limited cert info in easy to parse format");
+ System.exit(0);
+ }
+
+ public static void main(String argv[]) {
+
+ BufferedReader inputCert = null;
+ String encodedBASE64CertChunk = new String();
+ String encodedBASE64Cert = new String();
+ byte decodedBASE64Cert[] = null;
+ X509CertImpl cert = null;
+ Locale aLocale = null;
+ CertPrettyPrint certDetails = null;
+ String pp = new String();
+ FileOutputStream outputCert = null;
+ boolean mSimpleInfo = false;
+ String inputfile = null;
+ String outputfile = null;
+
+ // parse arguments
+
+ for (int i = 0; i < argv.length; i++) {
+
+ // deal with empty arguments passed in by script
+ if (argv[i].equals("")) {
+ continue;
+ }
+
+ // parse options
+ if (argv[i].charAt(0) == '-') {
+ if (argv[i].equals("-simpleinfo")) {
+ mSimpleInfo = true;
+ continue;
+ } else {
+ System.out.println("Illegal option: " + argv[i]);
+ usageAndExit();
+ }
+ }
+
+ // deal with filename
+
+ if (inputfile == null) {
+ inputfile = argv[i];
+ continue;
+ }
+
+ if (outputfile == null) {
+ outputfile = argv[i];
+ continue;
+ }
+
+ System.out.println("Error - Too many arguments");
+ System.exit(0);
+ }
+
+ if (inputfile == null) {
+ usageAndExit();
+ }
+
+ // (2) Create a DataInputStream() object to the BASE 64
+ // encoded certificate contained within the file
+ // specified on the command line
+ try {
+ inputCert = new BufferedReader(new InputStreamReader(
+ new BufferedInputStream(
+ new FileInputStream(
+ inputfile))));
+ } catch (FileNotFoundException e) {
+ System.out.println("PrettyPrintCert: can't find file " +
+ inputfile + ":\n" + e);
+ return;
+ }
+
+ // (3) Read the entire contents of the specified BASE 64 encoded
+ // certificate into a String() object throwing away any
+ // headers beginning with HEADER and any trailers beginning
+ // with TRAILER
+ try {
+ while ((encodedBASE64CertChunk = inputCert.readLine()) != null) {
+ if (!(encodedBASE64CertChunk.startsWith(HEADER)) &&
+ !(encodedBASE64CertChunk.startsWith(TRAILER))) {
+ encodedBASE64Cert += encodedBASE64CertChunk.trim();
+ }
+ }
+ } catch (IOException e) {
+ System.out.println("PrettyPrintCert: Unexpected BASE64 " +
+ "encoded error encountered in readLine():\n" +
+ e);
+ }
+
+ // (4) Close the DataInputStream() object
+ try {
+ inputCert.close();
+ } catch (IOException e) {
+ System.out.println("PrettyPrintCert: Unexpected BASE64 " +
+ "encoded error encountered in close():\n" + e);
+ }
+
+ // (5) Decode the ASCII BASE 64 certificate enclosed in the
+ // String() object into a BINARY BASE 64 byte[] object
+
+ decodedBASE64Cert = Utils.base64decode(encodedBASE64Cert);
+
+ // (6) Create an X509CertImpl() object from the BINARY BASE 64
+ // byte[] object
+ try {
+ cert = new X509CertImpl(decodedBASE64Cert);
+ } catch (CertificateException e) {
+ System.out.println("PrettyPrintCert: Error encountered " +
+ "on parsing certificate :\n" + e);
+ }
+
+ if (mSimpleInfo) {
+ try {
+ X509CertInfo certinfo = (X509CertInfo) cert.get("x509.INFO");
+
+ CertificateSubjectName csn = (CertificateSubjectName)
+ certinfo.get(X509CertInfo.SUBJECT);
+
+ X500Name dname = (X500Name) csn.get(CertificateSubjectName.DN_NAME);
+
+ pp = "";
+ RDN[] rdns = dname.getNames();
+
+ for (int i = rdns.length - 1; i >= 0; i--) {
+ pp = pp + rdns[i] + "\n";
+ }
+
+ } catch (Exception e) {
+ System.out.println("ERROR");
+ e.printStackTrace();
+ }
+ } else {
+ // (7) For this utility, always specify the default Locale
+ aLocale = Locale.getDefault();
+
+ // (8) Create a CertPrettyPrint() object
+ certDetails = new CertPrettyPrint(cert);
+
+ // (9) Convert the CertPrettyPrint() object into a String() object
+ pp = certDetails.toString(aLocale);
+ }
+
+ // (10) Finally, "pretty print" the actual certificate to the console
+ // unless an output file has been specified
+ if (outputfile == null) {
+ System.out.println(pp);
+ } else {
+ try {
+ outputCert = new FileOutputStream(outputfile);
+ } catch (Exception e) {
+ System.out.println("PrettyPrintCert: unable to open file " +
+ argv[1] + " for writing:\n" + e);
+ return;
+ }
+
+ try {
+ outputCert.write(pp.getBytes());
+ } catch (IOException e) {
+ System.out.println("PrettyPrintCert: Unexpected error " +
+ "encountered while attempting to write() " +
+ outputfile + ":\n" + e);
+ }
+
+ try {
+ outputCert.close();
+ } catch (IOException e) {
+ System.out.println("PrettyPrintCert: Unexpected error " +
+ "encountered while attempting to close() " +
+ outputfile + ":\n" + e);
+ }
+ }
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/PrettyPrintCrl.java b/base/java-tools/src/com/netscape/cmstools/PrettyPrintCrl.java
new file mode 100644
index 000000000..8801b2423
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/PrettyPrintCrl.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.cmstools;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.security.cert.CRLException;
+import java.security.cert.CertificateException;
+import java.util.Locale;
+
+import com.netscape.cmsutil.util.Utils;
+
+import netscape.security.util.CrlPrettyPrint;
+import netscape.security.x509.DeltaCRLIndicatorExtension;
+import netscape.security.x509.HoldInstructionExtension;
+import netscape.security.x509.InvalidityDateExtension;
+import netscape.security.x509.IssuingDistributionPointExtension;
+import netscape.security.x509.OIDMap;
+import netscape.security.x509.X509CRLImpl;
+import netscape.security.x509.X509ExtensionException;
+
+/**
+ * The PrettyPrintCrl class is a utility program designed to "pretty print"
+ * a CRL. It assumes that the name of a data file is passed to the
+ * program via the command line, and that the contents contain a CRL
+ * encoded in an ASCII BASE 64 format. Note that the data file may contain
+ * an optional "-----BEGIN" header and/or an optional "-----END" trailer.
+ *
+ * <P>
+ * The program may be invoked as follows:
+ *
+ * <PRE>
+ *
+ * PrettyPrintCrl &lt;input filename&gt; [output filename]
+ *
+ * NOTE: &lt;input filename&gt; must contain an ASCII
+ * BASE 64 encoded CRL
+ *
+ * &lt;output filename&gt; contains a CRL displayed
+ * in a "pretty print" ASCII format
+ * </PRE>
+ *
+ * @version $Revision$, $Date$
+ */
+
+public class PrettyPrintCrl {
+ // Define constants
+ public static final int ARGC = 2;
+ public static final String HEADER = "-----BEGIN";
+ public static final String TRAILER = "-----END";
+
+ public static void main(String argv[]) {
+
+ BufferedReader inputCrl = null;
+ String encodedBASE64CrlChunk = new String();
+ String encodedBASE64Crl = new String();
+ byte decodedBASE64Crl[] = null;
+ X509CRLImpl crl = null;
+ Locale aLocale = null;
+ CrlPrettyPrint CrlDetails = null;
+ String pp = new String();
+ FileOutputStream outputCrl = null;
+
+ // (1) Check that at least one argument was submitted to the program
+ if ((argv.length < 1) || (argv.length > ARGC)) {
+ System.out.println("Usage: PrettyPrintCrl " +
+ "<input filename> " +
+ "[output filename]");
+ return;
+ }
+
+ try {
+ OIDMap.addAttribute(DeltaCRLIndicatorExtension.class.getName(),
+ DeltaCRLIndicatorExtension.OID,
+ DeltaCRLIndicatorExtension.NAME);
+ } catch (CertificateException e) {
+ }
+ try {
+ OIDMap.addAttribute(HoldInstructionExtension.class.getName(),
+ HoldInstructionExtension.OID,
+ HoldInstructionExtension.NAME);
+ } catch (CertificateException e) {
+ }
+ try {
+ OIDMap.addAttribute(InvalidityDateExtension.class.getName(),
+ InvalidityDateExtension.OID,
+ InvalidityDateExtension.NAME);
+ } catch (CertificateException e) {
+ }
+ try {
+ OIDMap.addAttribute(IssuingDistributionPointExtension.class.getName(),
+ IssuingDistributionPointExtension.OID,
+ IssuingDistributionPointExtension.NAME);
+ } catch (CertificateException e) {
+ }
+
+ // (2) Create a DataInputStream() object to the BASE 64
+ // encoded CRL contained within the file
+ // specified on the command line
+ try {
+ inputCrl = new BufferedReader(new InputStreamReader(
+ new BufferedInputStream(
+ new FileInputStream(
+ argv[0]))));
+ } catch (FileNotFoundException e) {
+ System.out.println("PrettyPrintCrl(): can''t find file " +
+ argv[0] + ":\n" + e);
+ return;
+ }
+
+ // (3) Read the entire contents of the specified BASE 64 encoded
+ // CRL into a String() object throwing away any
+ // headers beginning with HEADER and any trailers beginning
+ // with TRAILER
+ try {
+ while ((encodedBASE64CrlChunk = inputCrl.readLine()) != null) {
+ if (!(encodedBASE64CrlChunk.startsWith(HEADER)) &&
+ !(encodedBASE64CrlChunk.startsWith(TRAILER))) {
+ encodedBASE64Crl += encodedBASE64CrlChunk.trim();
+ }
+ }
+ } catch (IOException e) {
+ System.out.println("PrettyPrintCrl(): Unexpected BASE64 " +
+ "encoded error encountered in readLine():\n" +
+ e);
+ }
+
+ // (4) Close the DataInputStream() object
+ try {
+ inputCrl.close();
+ } catch (IOException e) {
+ System.out.println("PrettyPrintCrl(): Unexpected BASE64 " +
+ "encoded error encountered in close():\n" + e);
+ }
+
+ // (5) Decode the ASCII BASE 64 CRL enclosed in the
+ // String() object into a BINARY BASE 64 byte[] object
+
+ decodedBASE64Crl = Utils.base64decode(encodedBASE64Crl);
+
+ // (6) Create an X509CRLImpl() object from the BINARY BASE 64
+ // byte[] object
+ try {
+ crl = new X509CRLImpl(decodedBASE64Crl);
+ } catch (CRLException e) {
+ System.out.println("PrettyPrintCrl(): Error encountered " +
+ "on parsing and initialization errors:\n" + e);
+ } catch (X509ExtensionException e) {
+ System.out.println("PrettyPrintCrl(): Error encountered " +
+ "on parsing and initialization errors:\n" + e);
+ }
+
+ // (7) For this utility, always specify the default Locale
+ aLocale = Locale.getDefault();
+
+ // (8) Create a CrlPrettyPrint() object
+ CrlDetails = new CrlPrettyPrint(crl);
+
+ // (9) Convert the CrlPrettyPrint() object into a String() object
+ pp = CrlDetails.toString(aLocale);
+
+ // (10) Finally, "pretty print" the actual CRL to the console
+ // unless an output file has been specified
+ if (argv.length != ARGC) {
+ System.out.println(pp);
+ } else {
+ try {
+ outputCrl = new FileOutputStream(argv[1]);
+ } catch (IOException e) {
+ System.out.println("PrettyPrintCrl(): unable to open file " +
+ argv[1] + " for writing:\n" + e);
+ return;
+ }
+
+ try {
+ outputCrl.write(pp.getBytes());
+ } catch (IOException e) {
+ System.out.println("PrettyPrintCrl(): I/O error " +
+ "encountered during write():\n" +
+ e);
+ }
+
+ try {
+ outputCrl.close();
+ } catch (IOException e) {
+ System.out.println("PrettyPrintCrl(): Unexpected error " +
+ "encountered while attempting to close() " +
+ argv[1] + ":\n" + e);
+ }
+ }
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/TestCRLSigning.java b/base/java-tools/src/com/netscape/cmstools/TestCRLSigning.java
new file mode 100644
index 000000000..369010abf
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/TestCRLSigning.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.cmstools;
+
+import java.math.BigInteger;
+import java.security.KeyPair;
+import java.util.Date;
+import java.util.Hashtable;
+
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.RevokedCertificate;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CRLImpl;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.KeyPairAlgorithm;
+import org.mozilla.jss.crypto.KeyPairGenerator;
+import org.mozilla.jss.util.Password;
+
+/**
+ * Tool used to test out signing a CRL
+ *
+ * <p>
+ *
+ * @version $Revision$ Date: $
+ */
+public class TestCRLSigning {
+ public static void printUsage() {
+ System.out.println("Command <dbdir> <numreovked> <keysize> <tokenname> <tokenpwd>");
+ }
+
+ public static void main(String args[]) throws Exception {
+ String dir = args[0];
+ String num = args[1];
+ String keysize = args[2];
+ String tokenname = args[3];
+ String tokenpwd = args[4];
+
+ // initialize JSS
+ CryptoManager cm = null;
+ CryptoManager.InitializationValues vals =
+ new CryptoManager.InitializationValues(dir, "", "", "secmod.db");
+ CryptoManager.initialize(vals);
+ cm = CryptoManager.getInstance();
+
+ // Login to token
+ CryptoToken token = null;
+ if (tokenname.equals("internal")) {
+ token = cm.getInternalKeyStorageToken();
+ } else {
+ token = cm.getTokenByName(tokenname);
+ }
+ Password pass = new Password(tokenpwd.toCharArray());
+ token.login(pass);
+
+ // generate key pair
+ KeyPairGenerator g = token.getKeyPairGenerator(KeyPairAlgorithm.RSA);
+ g.initialize(Integer.parseInt(keysize));
+ KeyPair pair = g.genKeyPair();
+
+ // generate revoked certificates
+ long startPutting = System.currentTimeMillis();
+ Date curDate = new Date();
+ Hashtable<BigInteger, RevokedCertificate> badCerts = new Hashtable<BigInteger, RevokedCertificate>();
+ int n = Integer.parseInt(num);
+ for (int i = 0; i < n; i++) {
+ badCerts.put(new BigInteger(Integer.toString(i)),
+ new RevokedCertImpl(new BigInteger(Integer.toString(i)), curDate));
+ }
+ long endPutting = System.currentTimeMillis();
+
+ long startConstructing = System.currentTimeMillis();
+ X509CRLImpl crl = new X509CRLImpl(
+ new X500Name("CN=Signer"),
+ null,
+ curDate,
+ curDate,
+ badCerts,
+ null);
+ long endConstructing = System.currentTimeMillis();
+
+ System.out.println("Start signing");
+ long startSigning = System.currentTimeMillis();
+ crl.sign(pair.getPrivate(), "SHA1withRSA");
+ long endSigning = System.currentTimeMillis();
+ System.out.println("Done signing");
+
+ long startData = System.currentTimeMillis();
+ byte data[] = crl.getTBSCertList();
+ long endData = System.currentTimeMillis();
+
+ System.out.println("Summary:");
+ System.out.println("Insertion time (ms): " + Long.toString(endPutting - startPutting));
+ System.out.println("Construction time (ms): " + Long.toString(endConstructing - startConstructing));
+ System.out.println("Signing time (ms): " + Long.toString(endSigning - startSigning));
+ System.out.println("Data time (ms): " + Long.toString(endData - startData));
+ System.out.println("Data size (bytes): " + Long.toString(data.length));
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/TokenInfo.java b/base/java-tools/src/com/netscape/cmstools/TokenInfo.java
new file mode 100644
index 000000000..fc3d13b42
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/TokenInfo.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.cmstools;
+
+import java.util.Enumeration;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.pkcs11.PK11Module;
+
+/**
+ * Tool used to determine which external hardware tokens are visible to the
+ * Certificate System subsystem. This can be used to diagnose whether problems
+ * using tokens are related to the Certificate System being unable to detect it.
+ *
+ * <p>
+ *
+ * @version $Revision$ Date: $
+ */
+public class TokenInfo {
+
+ /**
+ * Creates a new instance of CMCRevoke.
+ */
+ public static void main(String[] args) {
+ try {
+ if (args.length != 1) {
+ System.out.println("Usage: TokenInfo <alias directory>");
+ System.exit(0);
+ }
+ System.out.println("Database Path: " + args[0]);
+
+ CryptoManager.InitializationValues vals =
+ new CryptoManager.InitializationValues(args[0],
+ "", "", "secmod.db");
+
+ CryptoManager.initialize(vals);
+
+ CryptoManager cm = CryptoManager.getInstance();
+ @SuppressWarnings("unchecked")
+ Enumeration<PK11Module> modules = cm.getModules();
+ while (modules.hasMoreElements()) {
+ PK11Module m = modules.nextElement();
+ System.out.println("Found external module '" + m.getName() + "'");
+ }
+ @SuppressWarnings("unchecked")
+ Enumeration<CryptoToken> tokens = cm.getExternalTokens();
+
+ while (tokens.hasMoreElements()) {
+ CryptoToken t = tokens.nextElement();
+ System.out.println("Found external token '" + t.getName() + "'");
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ }
+}
diff --git a/base/java-tools/templates/CMakeLists.txt b/base/java-tools/templates/CMakeLists.txt
new file mode 100644
index 000000000..b7c6e891c
--- /dev/null
+++ b/base/java-tools/templates/CMakeLists.txt
@@ -0,0 +1,67 @@
+project(java-tools-wrapper)
+
+set(PKI_PRODUCT pki)
+set(PKI_COMMANDS
+ AtoB
+ AuditVerify
+ BtoA
+ CMCEnroll
+ CMCRequest
+ CMCResponse
+ CMCRevoke
+ CRMFPopClient
+ DRMTool
+ ExtJoiner
+ GenExtKeyUsage
+ GenIssuerAltNameExt
+ GenSubjectAltNameExt
+ HttpClient
+ OCSPClient
+ PKCS10Client
+ PKCS12Export
+ TokenInfo
+)
+
+foreach(PKI_COMMAND ${PKI_COMMANDS})
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pki_java_command_wrapper.in ${CMAKE_CURRENT_BINARY_DIR}/${PKI_COMMAND} @ONLY)
+
+ install(
+ FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKI_COMMAND}
+ DESTINATION
+ ${BIN_INSTALL_DIR}
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+ )
+endforeach(PKI_COMMAND)
+
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pretty_print_cert_command_wrapper.in ${CMAKE_CURRENT_BINARY_DIR}/PrettyPrintCert @ONLY)
+
+install(
+ FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/PrettyPrintCert
+ DESTINATION
+ ${BIN_INSTALL_DIR}
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pretty_print_crl_command_wrapper.in ${CMAKE_CURRENT_BINARY_DIR}/PrettyPrintCrl @ONLY)
+
+install(
+ FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/PrettyPrintCrl
+ DESTINATION
+ ${BIN_INSTALL_DIR}
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
diff --git a/base/java-tools/templates/pki_java_command_wrapper.in b/base/java-tools/templates/pki_java_command_wrapper.in
new file mode 100644
index 000000000..b0d406161
--- /dev/null
+++ b/base/java-tools/templates/pki_java_command_wrapper.in
@@ -0,0 +1,150 @@
+#!/bin/sh
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+
+# 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 '$0' from non-existent directory!"
+ exit 255
+fi
+
+
+###############################################################################
+## (1) Specify variables used by this script. ##
+###############################################################################
+
+PRODUCT=@PKI_PRODUCT@
+COMMAND=@PKI_COMMAND@
+
+
+###############################################################################
+## (2) Check for valid usage of this command wrapper. ##
+###############################################################################
+
+
+
+###############################################################################
+## (3) Define helper functions. ##
+###############################################################################
+
+invalid_operating_system() {
+ echo
+ echo "ERROR: '$0' does not execute on the '$1' operating system!"
+ echo
+}
+
+invalid_architecture() {
+ echo
+ echo "ERROR: '$0' does not execute on the '$1' architecture!"
+ echo
+}
+
+
+###############################################################################
+## (4) Set the LD_LIBRARY_PATH environment variable to determine the ##
+## search order this command wrapper uses to find shared libraries. ##
+###############################################################################
+
+OS=`uname -s`
+
+if [ "${OS}" = "Linux" ] ; then
+ ARCHITECTURE=`uname -i`
+ JAVA="java"
+ JAVA_OPTIONS=""
+
+ if [ "${ARCHITECTURE}" = "i386" ] ; then
+ LD_LIBRARY_PATH=/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/jss:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ elif [ "${ARCHITECTURE}" = "x86_64" ] ; then
+ LD_LIBRARY_PATH=/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/jss:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib64:/lib64:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib64/jss:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ else
+ invalid_architecture "${ARCHITECTURE}"
+ exit 255
+ fi
+elif [ "${OS}" = "SunOS" ] ; then
+ ARCHITECTURE=`uname -p`
+ if [ "${ARCHITECTURE}" = "sparc" ] &&
+ [ -d "/usr/lib/sparcv9/" ] ; then
+ ARCHITECTURE="sparcv9"
+ fi
+ if [ "${ARCHITECTURE}" = "sparc" ] ; then
+ JAVA="/usr/jdk/instances/jdk1.5.0/jre/bin/java"
+ JAVA_OPTIONS=""
+
+ LD_LIBRARY_PATH=/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ elif [ "${ARCHITECTURE}" = "sparcv9" ] ; then
+ JAVA="/usr/jdk/instances/jdk1.5.0/jre/bin/java"
+ JAVA_OPTIONS="-d64"
+
+ LD_LIBRARY_PATH=/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9:/lib/sparcv9:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/${PRODUCT}:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ else
+ invalid_architecture "${ARCHITECTURE}"
+ exit 255
+ fi
+else
+ invalid_operating_system "${OS}"
+ exit 255
+fi
+
+
+###############################################################################
+## (5) Set the CP environment variable to determine the search ##
+## order this command wrapper uses to find jar files. ##
+###############################################################################
+
+CP=/usr/lib/java/jss4.jar
+CP=/usr/lib/java/dirsec/jss4.jar:${CP}
+if [ "${OS}" = "Linux" ] &&
+ [ "${ARCHITECTURE}" = "x86_64" ] ; then
+ # Fedora 16+
+ CP=/usr/lib64/java/jss4.jar
+fi
+CP=/usr/share/java/commons-codec.jar:${CP}
+CP=/usr/share/java/ldapjdk.jar:${CP}
+CP=/usr/share/java/${PRODUCT}/pki-nsutil.jar:${CP}
+CP=/usr/share/java/${PRODUCT}/pki-cmsutil.jar:${CP}
+CP=/usr/share/java/${PRODUCT}/pki-tools.jar:${CP}
+export CP
+
+
+###############################################################################
+## (6) Execute the java command specified by this java command wrapper ##
+## based upon the preset LD_LIBRARY_PATH and CP environment variables. ##
+###############################################################################
+
+${JAVA} ${JAVA_OPTIONS} -cp ${CP} com.netscape.cmstools.${COMMAND} "$@"
+exit $?
+
diff --git a/base/java-tools/templates/pretty_print_cert_command_wrapper.in b/base/java-tools/templates/pretty_print_cert_command_wrapper.in
new file mode 100644
index 000000000..7f3331357
--- /dev/null
+++ b/base/java-tools/templates/pretty_print_cert_command_wrapper.in
@@ -0,0 +1,178 @@
+#!/bin/sh
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+
+# 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 '$0' from non-existent directory!"
+ exit 255
+fi
+
+
+###############################################################################
+## (1) Specify variables used by this script. ##
+###############################################################################
+
+PRODUCT=@PKI_PRODUCT@
+COMMAND=@PKI_COMMAND@
+
+
+###############################################################################
+## (2) Check for valid usage of this command wrapper. ##
+###############################################################################
+
+
+
+###############################################################################
+## (3) Define helper functions. ##
+###############################################################################
+
+invalid_operating_system() {
+ echo
+ echo "ERROR: '$0' does not execute on the '$1' operating system!"
+ echo
+}
+
+invalid_architecture() {
+ echo
+ echo "ERROR: '$0' does not execute on the '$1' architecture!"
+ echo
+}
+
+
+###############################################################################
+## (4) Set the LD_LIBRARY_PATH environment variable to determine the ##
+## search order this command wrapper uses to find shared libraries. ##
+###############################################################################
+
+OS=`uname -s`
+
+if [ "${OS}" = "Linux" ] ; then
+ ARCHITECTURE=`uname -i`
+ JAVA="java"
+ JAVA_OPTIONS=""
+
+ if [ "${ARCHITECTURE}" = "i386" ] ; then
+ LD_LIBRARY_PATH=/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/jss:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ elif [ "${ARCHITECTURE}" = "x86_64" ] ; then
+ LD_LIBRARY_PATH=/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/jss:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib64:/lib64:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib64/jss:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ else
+ invalid_architecture "${ARCHITECTURE}"
+ exit 255
+ fi
+elif [ "${OS}" = "SunOS" ] ; then
+ ARCHITECTURE=`uname -p`
+ if [ "${ARCHITECTURE}" = "sparc" ] &&
+ [ -d "/usr/lib/sparcv9/" ] ; then
+ ARCHITECTURE="sparcv9"
+ fi
+ if [ "${ARCHITECTURE}" = "sparc" ] ; then
+ JAVA="/usr/jdk/instances/jdk1.5.0/jre/bin/java"
+ JAVA_OPTIONS=""
+
+ LD_LIBRARY_PATH=/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ elif [ "${ARCHITECTURE}" = "sparcv9" ] ; then
+ JAVA="/usr/jdk/instances/jdk1.5.0/jre/bin/java"
+ JAVA_OPTIONS="-d64"
+
+ LD_LIBRARY_PATH=/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9:/lib/sparcv9:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/${PRODUCT}:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ else
+ invalid_architecture "${ARCHITECTURE}"
+ exit 255
+ fi
+else
+ invalid_operating_system "${OS}"
+ exit 255
+fi
+
+
+###############################################################################
+## (5) Set the CP environment variable to determine the search ##
+## order this command wrapper uses to find jar files. ##
+###############################################################################
+
+CP=/usr/lib/java/jss4.jar
+CP=/usr/lib/java/dirsec/jss4.jar:${CP}
+if [ "${OS}" = "Linux" ] &&
+ [ "${ARCHITECTURE}" = "x86_64" ] ; then
+ # Fedora 16+
+ CP=/usr/lib64/java/jss4.jar
+fi
+CP=/usr/share/java/commons-codec.jar:${CP}
+CP=/usr/share/java/ldapjdk.jar:${CP}
+CP=/usr/share/java/${PRODUCT}/pki-nsutil.jar:${CP}
+CP=/usr/share/java/${PRODUCT}/pki-cmsutil.jar:${CP}
+CP=/usr/share/java/${PRODUCT}/pki-tools.jar:${CP}
+export CP
+
+
+###############################################################################
+## (6) Execute the java command specified by this java command wrapper ##
+## based upon the preset LD_LIBRARY_PATH and CP environment variables. ##
+###############################################################################
+
+if [ $# -eq 1 ] ||
+ [ $# -eq 2 ] ||
+ [ $# -eq 3 ]
+then
+ if [ "$1" = "-simpleinfo" ]
+ then
+ file $2 | grep 'ASCII text' > /dev/null
+ if [ $? -ne 0 ] ; then
+ ${JAVA} ${JAVA_OPTIONS} -cp ${CP} com.netscape.cmstools.${COMMAND}
+ printf "\n"
+ printf " ERROR: '$2' is not an ASCII file!\n\n"
+ printf " First, use 'BtoA $2 $2.b64'\n"
+ printf " to convert a binary file into an ASCII file.\n\n"
+ exit 255
+ fi
+ else
+ file $1 | grep 'ASCII text' > /dev/null
+ if [ $? -ne 0 ] ; then
+ ${JAVA} ${JAVA_OPTIONS} -cp ${CP} com.netscape.cmstools.${COMMAND}
+ printf "\n"
+ printf " ERROR: '$1' is not an ASCII file!\n\n"
+ printf " First, use 'BtoA $1 $1.b64'\n"
+ printf " to convert a binary file into an ASCII file.\n\n"
+ exit 255
+ fi
+ fi
+fi
+
+${JAVA} ${JAVA_OPTIONS} -cp ${CP} com.netscape.cmstools.${COMMAND} "$@"
+exit $?
+
diff --git a/base/java-tools/templates/pretty_print_crl_command_wrapper.in b/base/java-tools/templates/pretty_print_crl_command_wrapper.in
new file mode 100644
index 000000000..95a559503
--- /dev/null
+++ b/base/java-tools/templates/pretty_print_crl_command_wrapper.in
@@ -0,0 +1,164 @@
+#!/bin/sh
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+
+# 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 '$0' from non-existent directory!"
+ exit 255
+fi
+
+
+###############################################################################
+## (1) Specify variables used by this script. ##
+###############################################################################
+
+PRODUCT=@PKI_PRODUCT@
+COMMAND=@PKI_COMMAND@
+
+
+###############################################################################
+## (2) Check for valid usage of this command wrapper. ##
+###############################################################################
+
+
+
+###############################################################################
+## (3) Define helper functions. ##
+###############################################################################
+
+invalid_operating_system() {
+ echo
+ echo "ERROR: '$0' does not execute on the '$1' operating system!"
+ echo
+}
+
+invalid_architecture() {
+ echo
+ echo "ERROR: '$0' does not execute on the '$1' architecture!"
+ echo
+}
+
+
+###############################################################################
+## (4) Set the LD_LIBRARY_PATH environment variable to determine the ##
+## search order this command wrapper uses to find shared libraries. ##
+###############################################################################
+
+OS=`uname -s`
+
+if [ "${OS}" = "Linux" ] ; then
+ ARCHITECTURE=`uname -i`
+ JAVA="java"
+ JAVA_OPTIONS=""
+
+ if [ "${ARCHITECTURE}" = "i386" ] ; then
+ LD_LIBRARY_PATH=/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/jss:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ elif [ "${ARCHITECTURE}" = "x86_64" ] ; then
+ LD_LIBRARY_PATH=/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/jss:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib64:/lib64:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib64/jss:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ else
+ invalid_architecture "${ARCHITECTURE}"
+ exit 255
+ fi
+elif [ "${OS}" = "SunOS" ] ; then
+ ARCHITECTURE=`uname -p`
+ if [ "${ARCHITECTURE}" = "sparc" ] &&
+ [ -d "/usr/lib/sparcv9/" ] ; then
+ ARCHITECTURE="sparcv9"
+ fi
+ if [ "${ARCHITECTURE}" = "sparc" ] ; then
+ JAVA="/usr/jdk/instances/jdk1.5.0/jre/bin/java"
+ JAVA_OPTIONS=""
+
+ LD_LIBRARY_PATH=/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ elif [ "${ARCHITECTURE}" = "sparcv9" ] ; then
+ JAVA="/usr/jdk/instances/jdk1.5.0/jre/bin/java"
+ JAVA_OPTIONS="-d64"
+
+ LD_LIBRARY_PATH=/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9:/lib/sparcv9:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/${PRODUCT}:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ else
+ invalid_architecture "${ARCHITECTURE}"
+ exit 255
+ fi
+else
+ invalid_operating_system "${OS}"
+ exit 255
+fi
+
+
+###############################################################################
+## (5) Set the CP environment variable to determine the search ##
+## order this command wrapper uses to find jar files. ##
+###############################################################################
+
+CP=/usr/lib/java/jss4.jar
+CP=/usr/lib/java/dirsec/jss4.jar:${CP}
+if [ "${OS}" = "Linux" ] &&
+ [ "${ARCHITECTURE}" = "x86_64" ] ; then
+ # Fedora 16+
+ CP=/usr/lib64/java/jss4.jar
+fi
+CP=/usr/share/java/commons-codec.jar:${CP}
+CP=/usr/share/java/ldapjdk.jar:${CP}
+CP=/usr/share/java/${PRODUCT}/pki-nsutil.jar:${CP}
+CP=/usr/share/java/${PRODUCT}/pki-cmsutil.jar:${CP}
+CP=/usr/share/java/${PRODUCT}/pki-tools.jar:${CP}
+export CP
+
+
+###############################################################################
+## (6) Execute the java command specified by this java command wrapper ##
+## based upon the preset LD_LIBRARY_PATH and CP environment variables. ##
+###############################################################################
+
+if [ $# -eq 1 ] ||
+ [ $# -eq 2 ]
+then
+ file $1 | grep 'ASCII text' > /dev/null
+ if [ $? -ne 0 ] ; then
+ ${JAVA} ${JAVA_OPTIONS} -cp ${CP} com.netscape.cmstools.${COMMAND}
+ printf "\n"
+ printf "ERROR: '$1' is not an ASCII file!\n\n"
+ printf " First, use 'BtoA $1 $1.b64'\n"
+ printf " to convert a binary file into an ASCII file.\n\n"
+ exit 255
+ fi
+fi
+
+${JAVA} ${JAVA_OPTIONS} -cp ${CP} com.netscape.cmstools.${COMMAND} "$@"
+exit $?
+
diff --git a/base/kra/CMakeLists.txt b/base/kra/CMakeLists.txt
new file mode 100644
index 000000000..0e15b2d52
--- /dev/null
+++ b/base/kra/CMakeLists.txt
@@ -0,0 +1,66 @@
+project(kra Java)
+
+add_subdirectory(src)
+add_subdirectory(setup)
+add_subdirectory(shared/conf)
+
+# install systemd scripts
+install(
+ FILES
+ shared/lib/systemd/system/pki-krad.target
+ shared/lib/systemd/system/pki-krad@.service
+ DESTINATION
+ ${SYSTEMD_LIB_INSTALL_DIR}
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+# install init script
+install(
+ FILES
+ shared/etc/init.d/pki-krad
+ DESTINATION
+ ${SYSCONF_INSTALL_DIR}/rc.d/init.d
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+# install directories
+install(
+ DIRECTORY
+ shared/
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}
+ PATTERN
+ "CMakeLists.txt" EXCLUDE
+ PATTERN
+ "etc/*" EXCLUDE
+ PATTERN
+ "conf/CS.cfg.in" EXCLUDE
+ PATTERN
+ "lib/*" EXCLUDE
+)
+
+# install empty directories
+install(
+ DIRECTORY
+ DESTINATION
+ ${VAR_INSTALL_DIR}/lock/pki/kra
+)
+
+install(
+ DIRECTORY
+ DESTINATION
+ ${VAR_INSTALL_DIR}/run/pki/kra
+)
+
+install(
+ DIRECTORY
+ DESTINATION
+ ${SYSTEMD_ETC_INSTALL_DIR}/pki-krad.target.wants
+)
+
diff --git a/base/kra/LICENSE b/base/kra/LICENSE
new file mode 100644
index 000000000..e281f4362
--- /dev/null
+++ b/base/kra/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/base/kra/functional/drmclient.py b/base/kra/functional/drmclient.py
new file mode 100644
index 000000000..e9b0ccb49
--- /dev/null
+++ b/base/kra/functional/drmclient.py
@@ -0,0 +1,1014 @@
+# Authors:
+# Ade Lee <alee@redhat.com>
+#
+# Copyright (C) 2012 Red Hat
+# see file 'COPYING' for use and warranty information
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+'''
+
+============================================================
+Python Test client for KRA using the new RESTful interface
+============================================================
+
+This is a python client that can be used to retrieve key requests
+and keys from a KRA using the new RESTful interface. Moreover, given
+a PKIArchiveOptions structure containing either a passphrase or a symmetric
+key, this data can be stored in and retrieved from the KRA.
+
+A sample test execution is provided at the end of the file.
+'''
+
+from lxml import etree
+import nss.nss as nss
+import httplib
+from ipapython import nsslib, ipautil
+from nss.error import NSPRError
+from ipalib.errors import NetworkError, CertificateOperationError
+from urllib import urlencode, quote_plus
+from datetime import datetime
+import logging
+import base64
+
+CERT_HEADER = "-----BEGIN NEW CERTIFICATE REQUEST-----"
+CERT_FOOTER = "-----END NEW CERTIFICATE REQUEST-----"
+
+def _(string):
+ return string
+
+def parse_key_request_info_xml(doc):
+ '''
+ :param doc: The root node of the xml document to parse
+ :returns: result dict
+ :except ValueError:
+
+ After parsing the results are returned in a result dict. The following
+ table illustrates the mapping from the CMS data item to what may be found in
+ the result dict. If a CMS data item is absent it will also be absent in the
+ result dict.
+
+ +----------------------+----------------+-----------------------+---------------+
+ |cms name |cms type |result name |result type |
+ +======================+================+=======================+===============+
+ |requestType |string |request_type |string |
+ +----------------------+----------------+-----------------------+---------------+
+ |requestStatus |string |request_status |string |
+ +----------------------+----------------+-----------------------+---------------+
+ |requestURL |string |request_id |string |
+ +----------------------+----------------+-----------------------+---------------+
+ |keyURL |string |key_id |string |
+ +----------------------+----------------+-----------------------+---------------+
+ '''
+ response = {}
+
+ request_type = doc.xpath('requestType')
+ if len(request_type) == 1:
+ request_type = etree.tostring(request_type[0], method='text',
+ encoding=unicode).strip()
+ response['request_type'] = request_type
+
+ request_status = doc.xpath('requestStatus')
+ if len(request_status) == 1:
+ request_status = etree.tostring(request_status[0], method='text',
+ encoding=unicode).strip()
+ response['request_status'] = request_status
+
+ request_url = doc.xpath('requestURL')
+ if len(request_url) == 1:
+ request_url = etree.tostring(request_url[0], method='text',
+ encoding=unicode).strip()
+ response['request_id'] = request_url.rsplit('/',1)[1]
+
+ key_url = doc.xpath('keyURL')
+ if len(key_url) == 1:
+ key_url = etree.tostring(key_url[0], method='text',
+ encoding=unicode).strip()
+ response['key_id'] = key_url.rsplit('/',1)[1]
+
+ return response
+
+def parse_key_request_infos_xml(doc):
+ '''
+ :param doc: The root node of the xml document to parse
+ :returns: result dict
+ :except ValueError:
+
+ After parsing the results are returned in a result dict. The following
+ table illustrates the mapping from the CMS data item to what may be found in
+ the result dict. If a CMS data item is absent it will also be absent in the
+ result dict.
+
+ +----------------------+------------------------+-----------------------+---------------+
+ |cms name |cms type |result name |result type |
+ +======================+========================+=======================+===============+
+ |next |Link |next_id |unicode [1] |
+ +----------------------+------------------------+-----------------------+---------------+
+ |prev |Link |prev_id |unicode [1] |
+ +----------------------+------------------------+-----------------------+---------------+
+ |info for each request |SecurityDataRequestInfo |request_id [2] |dict |
+ +----------------------+------------------------+-----------------------+---------------+
+
+ [1] prev_id and next_id are the starting ids for the previous and next pages
+ respectively. They are extracted from the href elements of the Link
+ nodes (if they exist)
+ [2] For each key request info returned, we store a dict containing the key request data.
+ See parse_key_request_info_xml for details. Each dict is referenced by the id
+ of the key request (extracted from the key request URL).
+ '''
+ response = {}
+ next_link = doc.xpath('//Link[@rel="next"]/href')
+ if len(next_link) == 1:
+ next_link = etree.tostring(next_link[0], method='text',
+ encoding=unicode).strip()
+ next_link = next_link.rsplit('/',1)[1]
+ response['next_id'] = next_link
+
+ prev_link = doc.xpath('//Link[@rel="previous"]/href')
+ if len(prev_link) == 1:
+ prev_link = etree.tostring(prev_link[0], method='text',
+ encoding=unicode).strip()
+ prev_link = prev_link.rsplit('/', 1)[1]
+ response['prev_id'] = prev_link
+
+ key_request_infos = doc.xpath('//SecurityDataRequestInfo')
+ for key_request in key_request_infos:
+ node = parse_key_request_info_xml(key_request)
+ response[node['request_id']] = node
+
+ return response
+
+def parse_key_data_info_xml(doc):
+ '''
+ :param doc: The root node of the xml document to parse
+ :returns: result dict
+ :except ValueError:
+
+ After parsing the results are returned in a result dict. The following
+ table illustrates the mapping from the CMS data item to what may be found in
+ the result dict. If a CMS data item is absent it will also be absent in the
+ result dict.
+
+ +----------------------+----------------+-----------------------+---------------+
+ |cms name |cms type |result name |result type |
+ +======================+================+=======================+===============+
+ |clientID |string |client_id |string |
+ +----------------------+----------------+-----------------------+---------------+
+ |keyURL |string |key_url |string |
+ +----------------------+----------------+-----------------------+---------------+
+ '''
+ response = {}
+
+ client_id = doc.xpath('clientID')
+ if len(client_id) == 1:
+ client_id = etree.tostring(client_id[0], method='text',
+ encoding=unicode).strip()
+ response['client_id'] = client_id
+
+ key_url = doc.xpath('keyURL')
+ if len(key_url) == 1:
+ key_url = etree.tostring(key_url[0], method='text',
+ encoding=unicode).strip()
+ response['key_url'] = key_url
+
+ return response
+
+def parse_key_data_infos_xml(doc):
+ '''
+ :param doc: The root node of the xml document to parse
+ :returns: result dict
+ :except ValueError:
+
+ After parsing the results are returned in a result dict. The following
+ table illustrates the mapping from the CMS data item to what may be found in
+ the result dict. If a CMS data item is absent it will also be absent in the
+ result dict.
+
+ +----------------------+-----------------+-----------------------+---------------+
+ |cms name |cms type |result name |result type |
+ +======================+=================+=======================+===============+
+ |next |Link |next_id |unicode [1] |
+ +----------------------+-----------------+-----------------------+---------------+
+ |prev |Link |prev_id |unicode [1] |
+ +----------------------+-----------------+-----------------------+---------------+
+ |info for each key |SecurityDataInfo |key_id [2] |dict |
+ +----------------------+-----------------+-----------------------+---------------+
+
+ [1] prev_id and next_id are the starting ids for the previous and next pages
+ respectively. They are extracted from the href elements of the Link
+ nodes (if they exist)
+ [2] For each key info returned, we store a dict containing the key data.
+ See parse_key_data_info_xml for details. Each dict is referenced by the id
+ of the key (extracted from the key URL).
+ '''
+ response = {}
+
+ next_link = doc.xpath('//Link[@rel="next"]/href')
+ if len(next_link) == 1:
+ next_link = etree.tostring(next_link[0], method='text',
+ encoding=unicode).strip()
+ next_link = next_link.rsplit('/',1)[1]
+ response['next_id'] = next_link
+
+ prev_link = doc.xpath('//Link[@rel="previous"]/href')
+ if len(prev_link) == 1:
+ prev_link = etree.tostring(prev_link[0], method='text',
+ encoding=unicode).strip()
+ prev_link = prev_link.rsplit('/', 1)[1]
+ response['prev_id'] = prev_link
+
+ key_data_infos = doc.xpath('//SecurityDataInfo')
+ for key_data in key_data_infos:
+ node = parse_key_data_info_xml(key_data)
+ response[node['key_url'].rsplit('/',1)[1]] = node
+
+ return response
+
+def parse_key_data_xml(doc):
+ '''
+ :param doc: The root node of the xml document to parse
+ :returns: result dict
+ :except ValueError:
+
+ After parsing the results are returned in a result dict.
+
+ +----------------------+----------------+-----------------------+---------------+
+ |cms name |cms type |result name |result type |
+ +======================+================+=======================+===============+
+ |wrappedPrivateData |string |wrapped_data |unicode |
+ +----------------------+----------------+-----------------------+---------------+
+ |nonceData |string |nonce_data |unicode |
+ +----------------------+----------------+-----------------------+---------------+
+
+ '''
+ response = {}
+
+ wrapped_data = doc.xpath('wrappedPrivateData')
+ if len(wrapped_data) == 1:
+ wrapped_data = etree.tostring(wrapped_data[0], method='text',
+ encoding=unicode).strip()
+ response['wrapped_data'] = wrapped_data
+
+ nonce_data = doc.xpath('nonceData')
+ if len(nonce_data) == 1:
+ nonce_data = etree.tostring(nonce_data[0], method='text',
+ encoding=unicode).strip()
+ response['nonce_data'] = nonce_data
+
+ return response
+
+def parse_certificate_data_xml(doc):
+ '''
+ :param doc: The root node of the xml document to parse
+ :returns: result dict
+ :except ValueError:
+
+ After parsing the results are returned in a result dict.
+
+ +----------------------+----------------+-----------------------+---------------+
+ |cms name |cms type |result name |result type |
+ +======================+================+=======================+===============+
+ |b64 |string [1] |cert |unicode |
+ +----------------------+----------------+-----------------------+---------------+
+
+ [1] Base-64 encoded certificate with header and footer
+ '''
+ response = {}
+
+ b64 = doc.xpath('b64')
+ if len(b64) == 1:
+ b64 = etree.tostring(b64[0], method='text',
+ encoding=unicode).strip()
+ response['cert'] = b64.replace(CERT_HEADER, "").replace(CERT_FOOTER, "")
+
+ return response
+
+def https_request(host, port, url, secdir, password, nickname, operation, args, **kw):
+ """
+ :param url: The URL to post to.
+ :param operation: GET, POST, (PUT and DELETE not yet implemented)
+ :param args: arguments for GET command line, or for POST
+ :param kw: Keyword arguments to encode into POST body.
+ :return: (http_status, http_reason_phrase, http_headers, http_body)
+ as (integer, unicode, dict, str)
+
+ Perform a client authenticated HTTPS request
+ """
+ if isinstance(host, unicode):
+ host = host.encode('utf-8')
+ uri = 'https://%s%s' % (ipautil.format_netloc(host, port), url)
+ logging.info('sslget %r', uri)
+
+ request_headers = {"Content-type": "application/xml",
+ "Accept": "application/xml"}
+ if operation == "POST":
+ if args != None:
+ post = args
+ elif kw != None:
+ post = urlencode(kw)
+ request_headers = {"Content-type": "application/x-www-form-urlencoded",
+ "Accept": "text/plain"}
+ try:
+ conn = nsslib.NSSConnection(host, port, dbdir=secdir)
+ conn.set_debuglevel(0)
+ conn.connect()
+ conn.sock.set_client_auth_data_callback(nsslib.client_auth_data_callback,
+ nickname,
+ password, nss.get_default_certdb())
+ if operation == "GET":
+ url = url + "?" + args
+ conn.request("GET", url)
+ elif operation == "POST":
+ conn.request("POST", url, post, request_headers)
+
+ res = conn.getresponse()
+
+ http_status = res.status
+ http_reason_phrase = unicode(res.reason, 'utf-8')
+ http_headers = res.msg.dict
+ http_body = res.read()
+ conn.close()
+ except Exception, e:
+ raise NetworkError(uri=uri, error=str(e))
+
+ return http_status, http_reason_phrase, http_headers, http_body
+
+def http_request(host, port, url, operation, args):
+ """
+ :param url: The URL to post to.
+ :param operation: GET, POST, (PUT and DELETE not yet implemented)
+ :param args: arguments for GET command line, or for POST
+ :return: (http_status, http_reason_phrase, http_headers, http_body)
+ as (integer, unicode, dict, str)
+
+ Perform an HTTP request.
+ """
+ if isinstance(host, unicode):
+ host = host.encode('utf-8')
+ uri = 'http://%s%s' % (ipautil.format_netloc(host, port), url)
+ logging.info('request %r', uri)
+ request_headers = {"Content-type": "application/xml",
+ "Accept": "application/xml"}
+ if operation == "POST":
+ if args != None:
+ post = args
+ else:
+ post = ""
+ conn = httplib.HTTPConnection(host, port)
+ try:
+ if operation == "GET":
+ if args != None:
+ url = url + "?" + args
+ conn.request("GET", url)
+ elif operation == "POST":
+ conn.request("POST", url, post, request_headers)
+
+ res = conn.getresponse()
+
+ http_status = res.status
+ http_reason_phrase = unicode(res.reason, 'utf-8')
+ http_headers = res.msg.dict
+ http_body = res.read()
+ conn.close()
+ except NSPRError, e:
+ raise NetworkError(uri=uri, error=str(e))
+
+ logging.debug('request status %d', http_status)
+ logging.debug('request reason_phrase %r', http_reason_phrase)
+ logging.debug('request headers %s', http_headers)
+ logging.debug('request body %r', http_body)
+
+ return http_status, http_reason_phrase, http_headers, http_body
+
+class kra:
+ """
+ Key Repository Authority backend plugin.
+ """
+
+ POST = "POST"
+ GET = "GET"
+ transport_cert = "byte array with transport cert"
+ mechanism = nss.CKM_DES_CBC_PAD
+ iv = "e4:bb:3b:d3:c3:71:2e:58"
+ fullname = "kra"
+
+
+ def __init__(self, work_dir, kra_host, kra_port, kra_nickname):
+ #crypto
+ self.sec_dir = work_dir
+ self.pwd_file = work_dir + "/pwdfile.txt"
+ self.transport_cert_nickname = kra_nickname
+ self.mechanism = nss.CKM_DES3_CBC_PAD
+ try:
+ f = open(self.pwd_file, "r")
+ self.password = f.readline().strip()
+ f.close()
+ except IOError:
+ self.password = ''
+
+ #set up key db for crypto functions
+ try:
+ nss.nss_init(self.sec_dir)
+ except Exception, e:
+ raise CertificateOperationError(error=_('Error in initializing certdb (%s)') \
+ + e.strerror)
+ self.transport_cert = nss.find_cert_from_nickname(self.transport_cert_nickname)
+
+ # DRM info
+ self.kra_host = kra_host
+ self.kra_agent_port = kra_port
+ '''super(kra, self).__init__()'''
+
+ def setup_contexts(self, mechanism, sym_key, iv):
+ # Get a PK11 slot based on the cipher
+ slot = nss.get_best_slot(mechanism)
+
+ if sym_key == None:
+ sym_key = slot.key_gen(mechanism, None, slot.get_best_key_length(mechanism))
+
+ # If initialization vector was supplied use it, otherwise set it to None
+ if iv:
+ iv_data = nss.read_hex(iv)
+ iv_si = nss.SecItem(iv_data)
+ iv_param = nss.param_from_iv(mechanism, iv_si)
+ else:
+ iv_length = nss.get_iv_length(mechanism)
+ if iv_length > 0:
+ iv_data = nss.generate_random(iv_length)
+ iv_si = nss.SecItem(iv_data)
+ iv_param = nss.param_from_iv(mechanism, iv_si)
+ else:
+ iv_param = None
+
+ # Create an encoding context
+ encoding_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_ENCRYPT,
+ sym_key, iv_param)
+
+ # Create a decoding context
+ decoding_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_DECRYPT,
+ sym_key, iv_param)
+
+ return encoding_ctx, decoding_ctx
+
+ def debug(self, message, *args):
+ print message % args
+
+ def _request(self, url, port, operation, args):
+ """
+ :param url: The URL to post to.
+ :param port: The port to post to
+ :param operation: GET/POST/PUT/DELETE (as supported by sslget)
+ :param args: A string containing arguments for a GET or POST request
+ :return: (http_status, http_reason_phrase, http_headers, http_body)
+ as (integer, unicode, dict, str)
+
+ Perform an HTTP request.
+ """
+ return http_request(self.kra_host, port, url, operation, args)
+
+ def _sslget(self, url, port, operation, args, **kw):
+ """
+ :param url: The URL to post to.
+ :param port: The port to post to
+ :param operation: GET/POST/PUT/DELETE (as supported by sslget)
+ :param args: A string containing arguments for a GET or POST request
+ :param kw: Alternatively, keyword arguments to be form-encoded into POST body.
+ :return: (http_status, http_reason_phrase, http_headers, http_body)
+ as (integer, unicode, dict, str)
+
+ Perform an HTTPS request
+ """
+ return https_request(self.kra_host, port, url, self.sec_dir, self.password,
+ self.ipa_certificate_nickname, operation, args, **kw)
+
+ def symmetric_wrap(self, data, wrapping_key):
+ """
+ :param data: Data to be wrapped
+ :param wrapping_key Symmetric key to wrap data
+
+ Wrap (encrypt) data using the supplied symmetric key
+ """
+ encoding_ctx, decoding_ctx = self.setup_contexts(self.mechanism, wrapping_key, self.iv)
+ wrapped_data = encoding_ctx.cipher_op(data) + encoding_ctx.digest_final()
+ return wrapped_data
+
+ def asymmetric_wrap(self, data, wrapping_cert):
+ """
+ :param data: Data to be wrapped
+ :param wrapping_cert Public key to wrap data
+
+ Wrap (encrypt) data using the supplied asymmetric key
+ """
+
+ return None
+
+ def symmetric_unwrap(self, data, wrapping_key, iv = None):
+ """
+ :param data: Data to be unwrapped
+ :param wrapping_key Symmetric key to unwrap data
+
+ Unwrap (decrypt) data using the supplied symmetric key
+ """
+ if iv == None:
+ iv = self.iv
+ encoding_ctx, decoding_ctx = self.setup_contexts(self.mechanism, wrapping_key, iv)
+ unwrapped_data = decoding_ctx.cipher_op(data) + decoding_ctx.digest_final()
+ return unwrapped_data
+
+ def get_parse_result_xml(self, xml_text, parse_func):
+ '''
+ :param xml_text: The XML text to parse
+ :param parse_func: The XML parsing function to apply to the parsed DOM tree.
+ :return: parsed result dict
+
+ Utility routine which parses the input text into an XML DOM tree
+ and then invokes the parsing function on the DOM tree in order
+ to get the parsing result as a dict of key/value pairs.
+ '''
+ parser = etree.XMLParser()
+ doc = etree.fromstring(xml_text, parser)
+ result = parse_func(doc)
+ self.debug("%s() xml_text:\n%s\nparse_result:\n%s" % (parse_func.__name__, xml_text, result))
+ return result
+
+ def create_archival_request(self, client_id, security_data, data_type):
+ """
+ :param :param client_id: identifier to be used for this stored key
+ :param security_data: data blob (PKIArchiveOptions) containing passphrase
+ or symmetric key to be archived
+ :param data_type: data type (symmetricKey, pass_phrase, asymmetricKey)
+ :return doc: xml doc with archival request
+ """
+ self.debug('%s.create_archival_request()', self.fullname)
+ root = etree.Element("SecurityDataArchivalRequest")
+ client_id_element = etree.SubElement(root, "clientId")
+ client_id_element.text = client_id
+ wrapped_private_data_element = etree.SubElement(root, "wrappedPrivateData")
+ wrapped_private_data_element.text = security_data
+ data_type_element = etree.SubElement(root, "dataType")
+ data_type_element.text = data_type
+ return etree.ElementTree(root)
+
+ def create_recovery_request(self, key_id, request_id, session_key, passphrase, nonce = None):
+ """
+ :param key_id: identifier of key to be recovered
+ :param request_id: id for the recovery request
+ :param session_key session key wrapped in transport key
+ :param passphrase passphrase wrapped in session key
+ :return doc: xml doc with archival request
+
+ """
+ self.debug('%s.create_recovery_request()', self.fullname)
+ root = etree.Element("SecurityDataRecoveryRequest")
+ if key_id != None:
+ key_id_element = etree.SubElement(root, "keyId")
+ key_id_element.text = key_id
+ if request_id != None:
+ request_id_element = etree.SubElement(root, "requestId")
+ request_id_element.text = request_id
+ if session_key != None:
+ session_key_element = etree.SubElement(root, "transWrappedSessionKey")
+ session_key_element.text = session_key
+ if passphrase != None:
+ passphrase_element = etree.SubElement(root, "sessionWrappedPassphrase")
+ passphrase_element.text = passphrase
+ if nonce != None:
+ nonce_element = etree.SubElement(root, "nonceData")
+ nonce_element.text = nonce
+ return etree.ElementTree(root)
+
+ def archive_security_data(self, client_id, security_data, data_type):
+ """
+ :param client_id: identifier to be used for this stored key
+ :param security_data: data blob (PKIArchiveOptions) containing passphrase
+ or symmetric key to be archived
+ :param data_type: data type (symmetricKey, pass_phrase, asymmetricKey)
+
+ Archives security data packaged in a PKIArchiveOptions blob
+
+ The command returns a dict with key/value pairs as defined in
+ parse_key_request_info_xml(). These include the request_id of the created
+ archival request, the status of the request, and the key_id of the archived
+ key.
+ """
+ self.debug('%s.archive_security_data()', self.fullname)
+
+ # check clientID and security data
+ if ((client_id == None) or (security_data == None)):
+ raise CertificateOperationError(error=_('Bad arguments to archive_security_data'))
+
+ request = self.create_archival_request(client_id, security_data, data_type)
+
+ #Call CMS
+ http_status, http_reason_phrase, http_headers, http_body = \
+ self._request('/kra/pki/keyrequest/archive',
+ self.kra_agent_port,
+ self.POST,
+ etree.tostring(request.getroot(), encoding='UTF-8'))
+
+ # Parse and handle errors
+ if (http_status != 200):
+ raise CertificateOperationError(error=_('Error in archiving request (%s)') % \
+ http_reason_phrase)
+
+ parse_result = self.get_parse_result_xml(http_body, parse_key_request_info_xml)
+ return parse_result
+
+ def get_transport_cert(self, etag=None):
+ """
+ :param etag: etag info for last cert retrieval from DRM
+
+ Gets the transport certificate from the DRM
+
+ The command returns a dict as defined in parse_certificate_data_xml()
+ """
+ self.debug('%s.get_transport_cert()', self.fullname)
+
+ #Call CMS
+ http_status, http_reason_phrase, http_headers, http_body = \
+ self._request('/kra/pki/config/cert/transport',
+ self.kra_agent_port,
+ self.GET,
+ None)
+
+ self.debug("headers: %s" , http_headers)
+ # Parse and handle errors
+ if (http_status != 200):
+ raise CertificateOperationError(error=_('Error in archiving request (%s)') % \
+ http_reason_phrase)
+
+ parse_result = self.get_parse_result_xml(http_body, parse_certificate_data_xml)
+ return parse_result
+
+ def list_security_data(self, client_id, key_state = None, next_id = None):
+ """
+ :param client_id: identifier to be searched for
+ :param key_state: state for key (active, inactive, all)
+ :param next_id: id for starting key on next page (if more than one page)
+
+ List security data matching the specified client id and state
+
+ The command returns a dict as specified in parse_key_data_infos_xml().
+ """
+ self.debug('%s.list_security_data()', self.fullname)
+ if client_id == None:
+ raise CertificateOperationError(error=_('Bad argument to list_security_data'))
+ get_args = "clientID=" + quote_plus(client_id)
+
+ if key_state != None:
+ get_args = get_args + "&status=" + quote_plus(key_state)
+
+ if next_id != None:
+ # currnently not implemented on server
+ get_args = get_args + "&start=" + quote_plus(next_id)
+
+ #Call CMS
+ http_status, http_reason_phrase, http_headers, http_body = \
+ self._request('/kra/pki/keys',
+ self.kra_agent_port,
+ self.GET,
+ get_args)
+
+ # Parse and handle errors
+ if (http_status != 200):
+ raise CertificateOperationError(error=_('Error in listing keys (%s)') % \
+ http_reason_phrase)
+
+ parse_result = self.get_parse_result_xml(http_body, parse_key_data_infos_xml)
+ return parse_result
+
+ def list_key_requests(self, request_state = None, request_type = None, client_id = None,
+ next_id = None):
+ """
+ :param request_state: state of request (pending, complete, cancelled, rejected, approved)
+ :param request_type: request type (enrollment, recovery)
+ :param next_id: id for starting key on next page (if more than one page)
+
+ List security data matching the specified client id and state
+
+ The command returns a dict as specified in parse_key_request_infos_xml().
+ """
+ self.debug('%s.list_key_requests()', self.fullname)
+ get_args = ""
+
+ if request_state != None:
+ get_args = get_args + "&requestState=" + quote_plus(request_state)
+
+ if request_type != None:
+ get_args = get_args + "&requestType=" + quote_plus(request_type)
+
+ if client_id != None:
+ get_args = get_args + "&clientID=" + quote_plus(client_id)
+
+ if next_id != None:
+ # currnently not implemented on server
+ get_args = get_args + "&start=" + quote_plus(next_id)
+
+ #Call CMS
+ http_status, http_reason_phrase, http_headers, http_body = \
+ self._request('/kra/pki/keyrequests',
+ self.kra_agent_port,
+ self.GET,
+ get_args)
+
+ # Parse and handle errors
+ if (http_status != 200):
+ raise CertificateOperationError(error=_('Error in listing key requests (%s)') % \
+ http_reason_phrase)
+
+ parse_result = self.get_parse_result_xml(http_body, parse_key_request_infos_xml)
+ return parse_result
+
+ def submit_recovery_request(self, key_id):
+ """
+ :param key_id: identifier of data to be recovered
+
+ Create a recovery request for a passphrase or symmetric key
+
+ The command returns a dict as described in the comments to
+ parse_key_request_info_xml(). This data includes the request_id
+ of the created recovery request
+ """
+ self.debug('%s.submit_recovery_request()', self.fullname)
+
+ # check clientID and security data
+ if key_id == None:
+ raise CertificateOperationError(error=_('Bad argument to archive_security_data'))
+
+ request = self.create_recovery_request(key_id, None, None, None)
+
+ #Call CMS
+ http_status, http_reason_phrase, http_headers, http_body = \
+ self._request('/kra/pki/keyrequest/recover',
+ self.kra_agent_port,
+ self.POST,
+ etree.tostring(request.getroot(), encoding='UTF-8'))
+
+ # Parse and handle errors
+ if (http_status != 200):
+ raise CertificateOperationError(error=_('Error in archiving request (%s)') % \
+ http_reason_phrase)
+
+ parse_result = self.get_parse_result_xml(http_body, parse_key_request_info_xml)
+ return parse_result
+
+ def check_request_status(self, request_id):
+ """
+ :param recovery_request_id: identifier of key recovery request
+
+ Check recovery request status
+
+ The command returns a dict with these possible key/value pairs.
+ Some key/value pairs may be absent
+
+ +-----------------+---------------+-------------------------------------- +
+ |result name |result type |comments |
+ +=================+===============+=======================================+
+ |request_status |String | status of request (pending, rejected, |
+ | | | approved) |
+ +-----------------+---------------+---------------------------------------|
+ |approvers_needed |int | If pending, number of approvers |
+ | | | needed |
+ +-----------------+---------------+---------------------------------------+
+ |approvers_list |String | list of approvers |
+ +-----------------+---------------+---------------------------------------+
+ """
+ self.debug('%s.check_request_status()', self.fullname)
+
+ def approve_recovery_request(self, request_id):
+ """
+ :param request_id: identifier of key recovery request
+
+ Approve recovery request
+ """
+ self.debug('%s.approve_recovery_request()', self.fullname)
+ if request_id == None:
+ raise CertificateOperationError(error=_('Bad argument to approve_recovery_request'))
+
+ #Call CMS
+ http_status, http_reason_phrase, http_headers, http_body = \
+ self._request('/kra/pki/keyrequest/approve/'+ request_id,
+ self.kra_agent_port,
+ self.POST,
+ None)
+
+ # Parse and handle errors
+ if (http_status > 399):
+ raise CertificateOperationError(error=_('Error in approving request (%s)') % \
+ http_reason_phrase)
+
+ def reject_recovery_request(self, request_id):
+ """
+ :param recovery_request_id: identifier of key recovery request
+
+ Reject recovery request
+ """
+ self.debug('%s.reject_recovery_request()', self.fullname)
+ if request_id == None:
+ raise CertificateOperationError(error=_('Bad argument to reject_recovery_request'))
+
+ #Call CMS
+ http_status, http_reason_phrase, http_headers, http_body = \
+ self._request('/kra/pki/keyrequest/reject/'+ request_id,
+ self.kra_agent_port,
+ self.POST,
+ None)
+
+ # Parse and handle errors
+ if (http_status > 399):
+ raise CertificateOperationError(error=_('Error in rejecting request (%s)') % \
+ http_reason_phrase)
+
+ def cancel_recovery_request(self, request_id):
+ """
+ :param recovery_request_id: identifier of key recovery request
+
+ Cancel recovery request
+ """
+ self.debug('%s.cancel_recovery_request()', self.fullname)
+ if request_id == None:
+ raise CertificateOperationError(error=_('Bad argument to cancel_recovery_request'))
+
+ #Call CMS
+ http_status, http_reason_phrase, http_headers, http_body = \
+ self._request('/kra/pki/keyrequest/cancel/'+ request_id,
+ self.kra_agent_port,
+ self.POST,
+ None)
+
+ # Parse and handle errors
+ if (http_status > 399):
+ raise CertificateOperationError(error=_('Error in cancelling request (%s)') % \
+ http_reason_phrase)
+
+ def retrieve_security_data(self, recovery_request_id, passphrase=None):
+ """
+ :param recovery_request_id: identifier of key recovery request
+ :param passphrase: passphrase to be used to wrap the data
+
+ Recover the passphrase or symmetric key. We require an approved
+ recovery request.
+
+ If a passphrase is provided, the DRM will return a blob that can be decrypted
+ with the passphrase. If not, then a symmetric key will be created to wrap the
+ data for transport to this server. Upon receipt, the data will be unwrapped
+ and returned unencrypted.
+
+ The command returns a dict with the values described in parse_key_data_xml(),
+ as well as the following field
+
+ +-----------------+---------------+-------------------------------------- +
+ |result name |result type |comments |
+ +=================+===============+=======================================+
+ |data |String | Key data (either wrapped using |
+ | | | passphrase or unwrapped) |
+ +-----------------+---------------+---------------------------------------+
+ """
+ self.debug('%s.retrieve_security_data()', self.fullname)
+
+ if recovery_request_id == None:
+ raise CertificateOperationError(error=_('Bad arguments to retrieve_security_data'))
+
+ # generate symmetric key
+ slot = nss.get_best_slot(self.mechanism)
+ session_key = slot.key_gen(self.mechanism, None, slot.get_best_key_length(self.mechanism))
+
+ # wrap this key with the transport cert
+ public_key = self.transport_cert.subject_public_key_info.public_key
+ wrapped_session_key = base64.b64encode(nss.pub_wrap_sym_key(self.mechanism, public_key, session_key))
+ wrapped_passphrase = None
+ if passphrase != None:
+ # wrap passphrase with session key
+ wrapped_session_key = base64.b64encode(self.symmetric_wrap(passphrase, session_key))
+
+ request = self.create_recovery_request(None, recovery_request_id,
+ wrapped_session_key,
+ wrapped_passphrase)
+
+ #Call CMS
+ http_status, http_reason_phrase, http_headers, http_body = \
+ self._request('/kra/pki/key/retrieve',
+ self.kra_agent_port,
+ self.POST,
+ etree.tostring(request.getroot(), encoding='UTF-8'))
+
+ # Parse and handle errors
+ if (http_status != 200):
+ raise CertificateOperationError(error=_('Error in retrieving security data (%s)') % \
+ http_reason_phrase)
+
+ parse_result = self.get_parse_result_xml(http_body, parse_key_data_xml)
+
+ if passphrase == None:
+ iv = nss.data_to_hex(base64.decodestring(parse_result['nonce_data']))
+ parse_result['data'] = self.symmetric_unwrap(base64.decodestring(parse_result['wrapped_data']),
+ session_key, iv)
+
+ return parse_result
+
+ def recover_security_data(self, key_id, passphrase=None):
+ """
+ :param key_id: identifier of key to be recovered
+ :param passphrase: passphrase to wrap key data for delivery outside of this server
+
+ Recover the key data (symmetric key or passphrase) in a one step process.
+ This is the case when only one approver is required to extract a key such that
+ the agent submitting the recovery request is the only approver required.
+
+ In this case, the request is automatically approved, and the KRA just returns the
+ key data.
+
+ This has not yet been implemented on the server
+ """
+ self.debug('%s.recover_security_data()', self.fullname)
+ pass
+
+""" Sample Test execution starts here """
+import argparse
+
+parser = argparse.ArgumentParser(description="Sample Test execution")
+parser.add_argument('-d', default='/tmp/drmtest', dest='work_dir', help='Working directory')
+parser.add_argument('--options', default='options.out', dest='options_file',
+ help='File containing test PKIArchiveOptions to be archived')
+parser.add_argument('--symkey', default='symkey.out', dest='symkey_file',
+ help='File containing test symkey')
+parser.add_argument('--host', default='localhost', dest='kra_host', help='DRM hostname')
+parser.add_argument('-p', default='10080', type=int, dest='kra_port', help='DRM Port')
+parser.add_argument('-n', default='DRM TransportCert Nickname', dest='kra_nickname',
+ help="DRM Nickname")
+
+args = parser.parse_args()
+work_dir = args.work_dir
+kra_host = args.kra_host
+kra_port = args.kra_port
+kra_nickname = args.kra_nickname
+options_file = args.options_file
+symkey_file = args.symkey_file
+
+test_kra = kra(work_dir, kra_host, kra_port, kra_nickname)
+
+# list requests
+requests = test_kra.list_key_requests()
+print requests
+
+# get transport cert
+transport_cert = test_kra.get_transport_cert()
+print transport_cert
+
+#archive symmetric key
+f = open(work_dir + "/" + options_file)
+wrapped_key = f.read()
+client_id = "Python symmetric key " + datetime.now().strftime("%Y-%m-%d %H:%M")
+response = test_kra.archive_security_data(client_id, wrapped_key,"symmetricKey")
+print response
+
+# list keys with client_id
+response = test_kra.list_security_data(client_id, "active")
+print response
+
+#create recovery request
+key_id = response.keys()[0]
+print key_id
+response = test_kra.submit_recovery_request(key_id)
+print response
+
+# approve recovery request
+request_id = response['request_id']
+test_kra.approve_recovery_request(request_id)
+
+# test invalid request
+print "Testing invalid request ID"
+try:
+ response = test_kra.retrieve_security_data("INVALID")
+ print "Failure: No exception thrown"
+except CertificateOperationError, e:
+ if 'Error in retrieving security data (Bad Request)' == e.error:
+ print "Success: " + e.error
+ else:
+ print "Failure: Wrong error message: " + e.error
+
+# retrieve key
+response = test_kra.retrieve_security_data(request_id)
+print response
+print "retrieved data is " + base64.encodestring(response['data'])
+
+#read original symkey from file
+f = open(work_dir + "/" + symkey_file)
+orig_key = f.read()
+print "orig key is " + orig_key
+
+if orig_key.strip() == base64.encodestring(response['data']).strip():
+ print "Success: the keys match"
+else:
+ print "Failure: keys do not match"
diff --git a/base/kra/functional/drmclient.readme.txt b/base/kra/functional/drmclient.readme.txt
new file mode 100644
index 000000000..833c5ce3c
--- /dev/null
+++ b/base/kra/functional/drmclient.readme.txt
@@ -0,0 +1,50 @@
+Running drmclient.py:
+
+The python drmclient currently requires a little setup to be run.
+
+1. Create a working directory - the code uses /tmp/drmtest
+2. In that directory, create an NSS database. In this doc, we will use the
+ password redhat123 as the password for the NSS db.
+
+ certutil -N -d /tmp/drmtest
+
+3. Add a password file /tmp/drmtest/pwdfile.txt. It should contain the password for
+ the NSS database.
+
+4. Put the transport certificate in a file /tmp/drmtest/transport.crt in binary format.
+
+ certutil -L -d /var/lib/pki-kra/alias -n "DRM Transport Certificate" -a > /tmp/drmtest/transport.asc
+ AtoB /tmp/drmtest/transport.asc /tmp/drmtest/transport.crt
+
+5. Import the transport certificate into the certificate databse in /tmp/drmtest.
+ certutil -A -d /tmp/drmtest -n "DRM Transport Certificate" -i /tmp/drmtest/transport.asc
+
+5. Run GeneratePKIArchiveOptions to generate some test data. Specifically we will be
+ using it to generate a symmetric key and its associated PKIArchoveOptions structure
+ to be archived.
+
+ GeneratePKIArchiveOptions -k /tmp/drmtest/symkey.out -w redhat123 -t /tmp/drmtest -o /tmp/drmtest/options.out
+
+6. Run the python code. You will likely need some python modules - python-lxml, python-nss
+ and ipapython.
+
+ The code has the following usage:
+
+usage: drmclient.py [-h] [-d WORK_DIR] [--options OPTIONS_FILE]
+ [--symkey SYMKEY_FILE] [--host KRA_HOST] [-p KRA_PORT]
+ [-n KRA_NICKNAME]
+
+Sample Test execution
+
+optional arguments:
+ -h, --help show this help message and exit
+ -d WORK_DIR Working directory
+ --options OPTIONS_FILE
+ File containing test PKIArchiveOptions to be archived
+ --symkey SYMKEY_FILE File containing test symkey
+ --host KRA_HOST DRM hostname
+ -p KRA_PORT DRM Port
+ -n KRA_NICKNAME DRM Nickname
+
+For example:
+python pki/base/kra/functional/drmclient.py -d /tmp/drmtest -p 10200 -n "DRM Transport Certificate - alee eclipse domain 2"
diff --git a/base/kra/functional/src/com/netscape/cms/servlet/test/DRMRestClient.java b/base/kra/functional/src/com/netscape/cms/servlet/test/DRMRestClient.java
new file mode 100644
index 000000000..651873b20
--- /dev/null
+++ b/base/kra/functional/src/com/netscape/cms/servlet/test/DRMRestClient.java
@@ -0,0 +1,266 @@
+package com.netscape.cms.servlet.test;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.Socket;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Iterator;
+
+import org.apache.commons.httpclient.ConnectTimeoutException;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.params.HttpConnectionParams;
+import org.apache.commons.httpclient.protocol.Protocol;
+import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
+import org.jboss.resteasy.client.ClientExecutor;
+import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.client.ProxyFactory;
+import com.netscape.certsrv.dbs.keydb.KeyId;
+import com.netscape.certsrv.request.RequestId;
+import org.jboss.resteasy.client.core.executors.ApacheHttpClientExecutor;
+import com.netscape.cms.servlet.admin.SystemCertificateResource;
+import com.netscape.cms.servlet.cert.model.CertificateData;
+import com.netscape.cms.servlet.key.KeyResource;
+import com.netscape.cms.servlet.key.KeysResource;
+import com.netscape.cms.servlet.key.model.KeyData;
+import com.netscape.cms.servlet.key.model.KeyDataInfo;
+import com.netscape.cms.servlet.key.model.KeyDataInfos;
+import com.netscape.cms.servlet.request.KeyRequestResource;
+import com.netscape.cms.servlet.request.KeyRequestsResource;
+import com.netscape.cms.servlet.request.model.ArchivalRequestData;
+import com.netscape.cms.servlet.request.model.KeyRequestInfo;
+import com.netscape.cms.servlet.request.model.KeyRequestInfos;
+import com.netscape.cms.servlet.request.model.RecoveryRequestData;
+import com.netscape.cmsutil.util.Utils;
+
+import org.mozilla.jss.ssl.SSLCertificateApprovalCallback;
+import org.mozilla.jss.ssl.SSLClientCertificateSelectionCallback;
+import org.mozilla.jss.ssl.SSLSocket;
+
+public class DRMRestClient {
+
+ // Callback to approve or deny returned SSL server certs
+ // Right now, simply approve the cert.
+ // ToDO: Look into taking this JSS http client code and move it into
+ // its own class to be used by possible future clients.
+ private class ServerCertApprovalCB implements SSLCertificateApprovalCallback {
+
+ public boolean approve(org.mozilla.jss.crypto.X509Certificate servercert,
+ SSLCertificateApprovalCallback.ValidityStatus status) {
+
+ //For now lets just accept the server cert. This is a test tool, being
+ // pointed at a well know kra instance.
+
+
+ if (servercert != null) {
+ System.out.println("Peer cert details: " +
+ "\n subject: " + servercert.getSubjectDN().toString() +
+ "\n issuer: " + servercert.getIssuerDN().toString() +
+ "\n serial: " + servercert.getSerialNumber().toString()
+ );
+ }
+
+ SSLCertificateApprovalCallback.ValidityItem item;
+
+ Enumeration<?> errors = status.getReasons();
+ int i = 0;
+ while (errors.hasMoreElements()) {
+ i++;
+ item = (SSLCertificateApprovalCallback.ValidityItem) errors.nextElement();
+ System.out.println("item " + i +
+ " reason=" + item.getReason() +
+ " depth=" + item.getDepth());
+
+ int reason = item.getReason();
+
+ if (reason ==
+ SSLCertificateApprovalCallback.ValidityStatus.UNTRUSTED_ISSUER ||
+ reason == SSLCertificateApprovalCallback.ValidityStatus.BAD_CERT_DOMAIN) {
+
+ //Allow these two since we haven't necessarily installed the CA cert for trust
+ // and we are choosing "localhost" as the host for this client.
+
+ return true;
+
+ }
+ }
+
+ //For other errors return false
+
+ return false;
+ }
+ }
+
+ private class JSSProtocolSocketFactory implements ProtocolSocketFactory {
+
+ @Override
+ public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
+
+ SSLSocket sock = createJSSSocket(host,port, null, 0, null);
+ return (Socket) sock;
+ }
+
+ @Override
+ public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException,
+ UnknownHostException {
+
+ SSLSocket sock = createJSSSocket(host,port, clientHost, clientPort, null);
+ return (Socket) sock;
+ }
+
+ @Override
+ public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params)
+ throws IOException, UnknownHostException, ConnectTimeoutException {
+
+ SSLSocket sock = createJSSSocket(host, port, localAddress, localPort, null);
+ return (Socket) sock;
+ }
+ }
+
+ private SSLSocket createJSSSocket(String host, int port, InetAddress localAddress,
+ int localPort, SSLClientCertificateSelectionCallback clientCertSelectionCallback)
+ throws IOException, UnknownHostException, ConnectTimeoutException {
+
+ SSLSocket sock = new SSLSocket(InetAddress.getByName(host),
+ port,
+ localAddress,
+ localPort,
+ new ServerCertApprovalCB(),
+ null);
+
+ if(sock != null && clientCertNickname != null) {
+ sock.setClientCertNickname(clientCertNickname);
+ }
+
+ return sock;
+
+ }
+ private KeyResource keyClient;
+ private KeysResource keysClient;
+ private KeyRequestsResource keyRequestsClient;
+ private KeyRequestResource keyRequestClient;
+ private SystemCertificateResource systemCertClient;
+
+ private String clientCertNickname = null;
+
+ public DRMRestClient(String baseUri, String clientCertNick) throws MalformedURLException {
+
+ // For SSL we are assuming the caller has already intialized JSS and has
+ // a valid CryptoManager and CryptoToken
+ // optional clientCertNickname is provided for use if required.
+
+
+ URL url = new URL(baseUri);
+
+ String protocol = url.getProtocol();
+ int port = url.getPort();
+
+ clientCertNickname = null;
+ if(protocol != null && protocol.equals("https")) {
+ if (clientCertNick != null) {
+ clientCertNickname = clientCertNick;
+ }
+
+ Protocol.registerProtocol("https",
+ new Protocol(protocol, new JSSProtocolSocketFactory(), port));
+ }
+
+ HttpClient httpclient = new HttpClient();
+ ClientExecutor executor = new ApacheHttpClientExecutor(httpclient);
+
+ systemCertClient = ProxyFactory.create(SystemCertificateResource.class, baseUri, executor);
+ keyRequestsClient = ProxyFactory.create(KeyRequestsResource.class, baseUri, executor);
+ keyRequestClient = ProxyFactory.create(KeyRequestResource.class, baseUri, executor);
+ keysClient = ProxyFactory.create(KeysResource.class, baseUri, executor);
+ keyClient = ProxyFactory.create(KeyResource.class, baseUri, executor);
+ }
+
+ public String getTransportCert() {
+ @SuppressWarnings("unchecked")
+ ClientResponse<CertificateData> response = (ClientResponse<CertificateData>) systemCertClient.getTransportCert();
+ CertificateData certData = response.getEntity();
+ String transportCert = certData.getB64();
+ return transportCert;
+ }
+
+ public Collection<KeyRequestInfo> listRequests(String requestState, String requestType) {
+ KeyRequestInfos infos = keyRequestsClient.listRequests(
+ requestState, requestType, null, new RequestId(0), 100, 100, 10
+ );
+ Collection<KeyRequestInfo> list = infos.getRequests();
+ return list;
+ }
+
+ public KeyRequestInfo archiveSecurityData(byte[] encoded, String clientId, String dataType) {
+ // create archival request
+ ArchivalRequestData data = new ArchivalRequestData();
+ String req1 = Utils.base64encode(encoded);
+ data.setWrappedPrivateData(req1);
+ data.setClientId(clientId);
+ data.setDataType(dataType);
+
+ KeyRequestInfo info = keyRequestClient.archiveKey(data);
+ return info;
+ }
+
+ public KeyDataInfo getKeyData(String clientId, String status) {
+ KeyDataInfos infos = keysClient.listKeys(clientId, status, 100, 10);
+ Collection<KeyDataInfo> list = infos.getKeyInfos();
+ Iterator<KeyDataInfo> iter = list.iterator();
+
+ while (iter.hasNext()) {
+ KeyDataInfo info = iter.next();
+ if (info != null) {
+ // return the first one
+ return info;
+ }
+ }
+ return null;
+ }
+
+ public KeyRequestInfo requestRecovery(KeyId keyId, byte[] rpwd, byte[] rkey, byte[] nonceData) {
+ // create recovery request
+ RecoveryRequestData data = new RecoveryRequestData();
+ data.setKeyId(keyId);
+ if (rpwd != null) {
+ data.setSessionWrappedPassphrase(Utils.base64encode(rpwd));
+ }
+ if (rkey != null) {
+ data.setTransWrappedSessionKey(Utils.base64encode(rkey));
+ }
+
+ if (nonceData != null) {
+ data.setNonceData(Utils.base64encode(nonceData));
+ }
+
+ KeyRequestInfo info = keyRequestClient.recoverKey(data);
+ return info;
+ }
+
+ public void approveRecovery(RequestId recoveryId) {
+ keyRequestClient.approveRequest(recoveryId);
+ }
+
+ public KeyData retrieveKey(KeyId keyId, RequestId requestId, byte[] rpwd, byte[] rkey, byte[] nonceData) {
+ // create recovery request
+ RecoveryRequestData data = new RecoveryRequestData();
+ data.setKeyId(keyId);
+ data.setRequestId(requestId);
+ if (rkey != null) {
+ data.setTransWrappedSessionKey(Utils.base64encode(rkey));
+ }
+ if (rpwd != null) {
+ data.setSessionWrappedPassphrase(Utils.base64encode(rpwd));
+ }
+
+ if (nonceData != null) {
+ data.setNonceData(Utils.base64encode(nonceData));
+ }
+
+ KeyData key = keyClient.retrieveKey(data);
+ return key;
+ }
+}
diff --git a/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java b/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java
new file mode 100644
index 000000000..8d83247b8
--- /dev/null
+++ b/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java
@@ -0,0 +1,503 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.test;
+
+import java.net.MalformedURLException;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Random;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.AlreadyInitializedException;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.EncryptionAlgorithm;
+import org.mozilla.jss.crypto.IVParameterSpec;
+import org.mozilla.jss.crypto.KeyGenAlgorithm;
+import org.mozilla.jss.crypto.SymmetricKey;
+import org.mozilla.jss.util.Password;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.cli.PosixParser;
+
+import com.netscape.certsrv.dbs.keydb.KeyId;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.cms.servlet.base.CMSResourceService;
+import com.netscape.cms.servlet.key.model.KeyData;
+import com.netscape.cms.servlet.key.model.KeyDataInfo;
+import com.netscape.cms.servlet.request.KeyRequestResource;
+import com.netscape.cms.servlet.request.model.KeyRequestInfo;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+import com.netscape.cmsutil.util.Utils;
+
+public class DRMTest {
+
+ public static void usage(Options options) {
+ HelpFormatter formatter = new HelpFormatter();
+ formatter.printHelp("DRMTest", options);
+ System.exit(1);
+ }
+
+ public static void main(String args[]) {
+ String host = null;
+ String port = null;
+ String token_pwd = null;
+ String db_dir = "./";
+ String protocol = "http";
+ String clientCertNickname = "KRA Administrator of Instance pki-kra's SjcRedhat Domain ID";
+
+ // parse command line arguments
+ Options options = new Options();
+ options.addOption("h", true, "Hostname of the DRM");
+ options.addOption("p", true, "Port of the DRM");
+ options.addOption("w", true, "Token password");
+ options.addOption("d", true, "Directory for tokendb");
+ options.addOption("s", true, "Attempt Optional Secure SSL connection");
+ options.addOption("c", true, "Optional SSL Client cert Nickname");
+
+ try {
+ CommandLineParser parser = new PosixParser();
+ CommandLine cmd = parser.parse(options, args);
+
+ if (cmd.hasOption("h")) {
+ host = cmd.getOptionValue("h");
+ } else {
+ System.err.println("Error: no hostname provided.");
+ usage(options);
+ }
+
+ if (cmd.hasOption("p")) {
+ port = cmd.getOptionValue("p");
+ } else {
+ System.err.println("Error: no port provided");
+ usage(options);
+ }
+
+ if (cmd.hasOption("w")) {
+ token_pwd = cmd.getOptionValue("w");
+ } else {
+ System.err.println("Error: no token password provided");
+ usage(options);
+ }
+
+ if (cmd.hasOption("d")) {
+ db_dir = cmd.getOptionValue("d");
+ }
+
+ if (cmd.hasOption("s")) {
+ if(cmd.getOptionValue("s") != null && cmd.getOptionValue("s").equals("true")) {
+ protocol = "https";
+ }
+ }
+
+ if (cmd.hasOption("c")) {
+ String nick = cmd.getOptionValue("c");
+
+ if (nick != null && protocol.equals("https")) {
+ clientCertNickname = nick;
+ }
+ }
+
+ } catch (ParseException e) {
+ System.err.println("Error in parsing command line options: " + e.getMessage());
+ usage(options);
+ }
+
+ // used for crypto operations
+ byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
+ IVParameterSpec ivps = null;
+ IVParameterSpec ivps_server = null;
+
+ try {
+ ivps = genIV(8);
+ } catch (Exception e) {
+ log("Can't generate initialization vector use default: " + e.toString());
+ ivps = new IVParameterSpec(iv);
+ }
+
+ CryptoManager manager = null;
+ CryptoToken token = null;
+
+ // used for wrapping to send data to DRM
+ String transportCert = null;
+
+ // Data to be archived
+ SymmetricKey vek = null;
+ String passphrase = null;
+
+ // Session keys and passphrases for recovery
+ SymmetricKey recoveryKey = null;
+ byte[] wrappedRecoveryKey = null;
+ String recoveryPassphrase = null;
+ byte[] wrappedRecoveryPassphrase = null;
+
+ // retrieved data (should match archived data)
+ String wrappedRecoveredKey = null;
+ String recoveredKey = null;
+
+ // various ids used in recovery/archival operations
+ KeyId keyId = null;
+ String clientId = null;
+ RequestId recoveryRequestId = null;
+
+ // Variables for data structures from calls
+ KeyRequestInfo requestInfo = null;
+ KeyData keyData = null;
+ KeyDataInfo keyInfo = null;
+
+ // Initialize token
+ try {
+ CryptoManager.initialize(db_dir);
+ } catch (AlreadyInitializedException e) {
+ // it is ok if it is already initialized
+ } catch (Exception e) {
+ log("INITIALIZATION ERROR: " + e.toString());
+ System.exit(1);
+ }
+
+ // log into token
+ try {
+ manager = CryptoManager.getInstance();
+ token = manager.getInternalKeyStorageToken();
+ Password password = new Password(token_pwd.toCharArray());
+ try {
+ token.login(password);
+ } catch (Exception e) {
+ log("login Exception: " + e.toString());
+ if (!token.isLoggedIn()) {
+ token.initPassword(password, password);
+ }
+ }
+ } catch (Exception e) {
+ log("Exception in logging into token:" + e.toString());
+ }
+
+ // Set base URI and get client
+
+
+ String baseUri = protocol + "://" + host + ":" + port + "/kra/pki";
+ DRMRestClient client;
+ try {
+ client = new DRMRestClient(baseUri, clientCertNickname);
+ } catch (MalformedURLException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ return;
+ }
+
+ // Test 1: Get transport certificate from DRM
+ transportCert = client.getTransportCert();
+ transportCert = transportCert.substring(CMSResourceService.HEADER.length(),
+ transportCert.indexOf(CMSResourceService.TRAILER));
+
+ log("Transport Cert retrieved from DRM: " + transportCert);
+
+ // Test 2: Get list of completed key archival requests
+ log("\n\nList of completed archival requests");
+ Collection<KeyRequestInfo> list = client.listRequests("complete", "securityDataEnrollment");
+ if (list == null) {
+ log("No requests found");
+ } else {
+ Iterator<KeyRequestInfo> iter = list.iterator();
+ while (iter.hasNext()) {
+ KeyRequestInfo info = iter.next();
+ printRequestInfo(info);
+ }
+ }
+
+ // Test 3: Get list of key recovery requests
+ log("\n\nList of completed recovery requests");
+ Collection<KeyRequestInfo> list2 = client.listRequests("complete", "securityDataRecovery");
+ if (list2 == null) {
+ log("No requests found");
+ } else {
+ Iterator<KeyRequestInfo> iter2 = list2.iterator();
+ while (iter2.hasNext()) {
+ KeyRequestInfo info = iter2.next();
+ printRequestInfo(info);
+ }
+ }
+
+ // Test 4: Generate and archive a symmetric key
+ log("Archiving symmetric key");
+ clientId = "UUID: 123-45-6789 VEK " + Calendar.getInstance().getTime().toString();
+ try {
+ vek = CryptoUtil.generateKey(token, KeyGenAlgorithm.DES3);
+ byte[] encoded = CryptoUtil.createPKIArchiveOptions(manager, token, transportCert, vek, null,
+ KeyGenAlgorithm.DES3, ivps);
+
+ KeyRequestInfo info = client.archiveSecurityData(encoded, clientId, KeyRequestResource.SYMMETRIC_KEY_TYPE);
+ log("Archival Results:");
+ printRequestInfo(info);
+ keyId = info.getKeyId();
+ } catch (Exception e) {
+ log("Exception in archiving symmetric key:" + e.getMessage());
+ e.printStackTrace();
+ }
+
+ //Test 5: Get keyId for active key with client ID
+
+ log("Getting key ID for symmetric key");
+ keyInfo = client.getKeyData(clientId, "active");
+ KeyId keyId2 = keyInfo.getKeyId();
+ if (keyId2 == null) {
+ log("No archived key found");
+ } else {
+ log("Archived Key found: " + keyId);
+ }
+
+ if (!keyId.equals(keyId2)) {
+ log("Error: key ids from search and archival do not match");
+ } else {
+ log("Success: keyids from search and archival match.");
+ }
+
+ // Test 6: Submit a recovery request for the symmetric key using a session key
+ log("Submitting a recovery request for the symmetric key using session key");
+ try {
+ recoveryKey = CryptoUtil.generateKey(token, KeyGenAlgorithm.DES3);
+ wrappedRecoveryKey = CryptoUtil.wrapSymmetricKey(manager, token, transportCert, recoveryKey);
+ KeyRequestInfo info = client.requestRecovery(keyId, null, wrappedRecoveryKey, ivps.getIV());
+ recoveryRequestId = info.getRequestId();
+ } catch (Exception e) {
+ log("Exception in recovering symmetric key using session key: " + e.getMessage());
+ }
+
+ // Test 7: Approve recovery
+ log("Approving recovery request: " + recoveryRequestId);
+ client.approveRecovery(recoveryRequestId);
+
+ // Test 8: Get key
+ log("Getting key: " + keyId);
+
+ keyData = client.retrieveKey(keyId, recoveryRequestId, null, wrappedRecoveryKey, ivps.getIV());
+ wrappedRecoveredKey = keyData.getWrappedPrivateData();
+
+ ivps_server = new IVParameterSpec(Utils.base64decode(keyData.getNonceData()));
+ try {
+ recoveredKey = CryptoUtil.unwrapUsingSymmetricKey(token, ivps_server,
+ Utils.base64decode(wrappedRecoveredKey),
+ recoveryKey, EncryptionAlgorithm.DES3_CBC_PAD);
+ } catch (Exception e) {
+ log("Exception in unwrapping key: " + e.toString());
+ e.printStackTrace();
+ }
+
+ if (!recoveredKey.equals(Utils.base64encode(vek.getEncoded()))) {
+ log("Error: recovered and archived keys do not match!");
+ } else {
+ log("Success: recoverd and archived keys match!");
+ }
+
+ // Test 9: Submit a recovery request for the symmetric key using a passphrase
+ log("Submitting a recovery request for the symmetric key using a passphrase");
+ recoveryPassphrase = "Gimme me keys please";
+
+ try {
+ recoveryKey = CryptoUtil.generateKey(token, KeyGenAlgorithm.DES3);
+ wrappedRecoveryPassphrase = CryptoUtil.wrapPassphrase(token, recoveryPassphrase, ivps, recoveryKey,
+ EncryptionAlgorithm.DES3_CBC_PAD);
+ wrappedRecoveryKey = CryptoUtil.wrapSymmetricKey(manager, token, transportCert, recoveryKey);
+
+ requestInfo = client.requestRecovery(keyId, wrappedRecoveryPassphrase, wrappedRecoveryKey, ivps.getIV());
+ recoveryRequestId = requestInfo.getRequestId();
+ } catch (Exception e) {
+ log("Exception in recovering symmetric key using passphrase" + e.toString());
+ e.printStackTrace();
+ }
+
+ //Test 10: Approve recovery
+ log("Approving recovery request: " + recoveryRequestId);
+ client.approveRecovery(recoveryRequestId);
+
+ // Test 11: Get key
+ log("Getting key: " + keyId);
+ keyData = client.retrieveKey(keyId, recoveryRequestId, wrappedRecoveryPassphrase, wrappedRecoveryKey, ivps.getIV());
+ wrappedRecoveredKey = keyData.getWrappedPrivateData();
+
+ try {
+ recoveredKey = CryptoUtil.unwrapUsingPassphrase(wrappedRecoveredKey, recoveryPassphrase);
+ } catch (Exception e) {
+ log("Error: unable to unwrap key using passphrase");
+ e.printStackTrace();
+ }
+
+ if (recoveredKey == null || !recoveredKey.equals(Utils.base64encode(vek.getEncoded()))) {
+ log("Error: recovered and archived keys do not match!");
+ } else {
+ log("Success: recovered and archived keys do match!");
+ }
+
+
+ passphrase = "secret12345";
+ // Test 12: Generate and archive a passphrase
+ clientId = "UUID: 123-45-6789 RKEK " + Calendar.getInstance().getTime().toString();
+ try {
+ byte[] encoded = CryptoUtil.createPKIArchiveOptions(manager, token, transportCert, null, passphrase,
+ KeyGenAlgorithm.DES3, ivps);
+ requestInfo = client.archiveSecurityData(encoded, clientId, KeyRequestResource.PASS_PHRASE_TYPE);
+ log("Archival Results:");
+ printRequestInfo(requestInfo);
+ keyId = requestInfo.getKeyId();
+ } catch (Exception e) {
+ log("Exception in archiving symmetric key:" + e.toString());
+ e.printStackTrace();
+ }
+
+ //Test 13: Get keyId for active passphrase with client ID
+ log("Getting key ID for passphrase");
+ keyInfo = client.getKeyData(clientId, "active");
+ keyId2 = keyInfo.getKeyId();
+ if (keyId2 == null) {
+ log("No archived key found");
+ } else {
+ log("Archived Key found: " + keyId);
+ }
+
+ if (!keyId.equals(keyId2)) {
+ log("Error: key ids from search and archival do not match");
+ } else {
+ log("Success: key ids from search and archival do match!");
+ }
+
+ // Test 14: Submit a recovery request for the passphrase using a session key
+ log("Submitting a recovery request for the passphrase using session key");
+ recoveryKey = null;
+ recoveryRequestId = null;
+ wrappedRecoveryKey = null;
+ try {
+ recoveryKey = CryptoUtil.generateKey(token, KeyGenAlgorithm.DES3);
+ wrappedRecoveryKey = CryptoUtil.wrapSymmetricKey(manager, token, transportCert, recoveryKey);
+ wrappedRecoveryPassphrase = CryptoUtil.wrapPassphrase(token, recoveryPassphrase, ivps, recoveryKey,
+ EncryptionAlgorithm.DES3_CBC_PAD);
+ requestInfo = client.requestRecovery(keyId, null, wrappedRecoveryKey, ivps.getIV());
+ recoveryRequestId = requestInfo.getRequestId();
+ } catch (Exception e) {
+ log("Exception in recovering passphrase using session key: " + e.getMessage());
+ }
+
+ // Test 15: Approve recovery
+ log("Approving recovery request: " + recoveryRequestId);
+ client.approveRecovery(recoveryRequestId);
+
+ // Test 16: Get key
+ log("Getting passphrase: " + keyId);
+
+ keyData = client.retrieveKey(keyId, recoveryRequestId, null, wrappedRecoveryKey, ivps.getIV());
+ wrappedRecoveredKey = keyData.getWrappedPrivateData();
+ ivps_server = new IVParameterSpec( Utils.base64decode(keyData.getNonceData()));
+ try {
+ recoveredKey = CryptoUtil.unwrapUsingSymmetricKey(token, ivps_server,
+ Utils.base64decode(wrappedRecoveredKey),
+ recoveryKey, EncryptionAlgorithm.DES3_CBC_PAD);
+ recoveredKey = new String(Utils.base64decode(recoveredKey), "UTF-8");
+ } catch (Exception e) {
+ log("Exception in unwrapping key: " + e.toString());
+ e.printStackTrace();
+ }
+
+ if (recoveredKey == null || !recoveredKey.equals(passphrase)) {
+ log("Error: recovered and archived passphrases do not match!");
+ } else {
+ log("Success: recovered and archived passphrases do match!");
+ }
+
+ // Test 17: Submit a recovery request for the passphrase using a passphrase
+ log("Submitting a recovery request for the passphrase using a passphrase");
+ requestInfo = client.requestRecovery(keyId, wrappedRecoveryPassphrase, wrappedRecoveryKey, ivps.getIV());
+ recoveryRequestId = requestInfo.getRequestId();
+
+ //Test 18: Approve recovery
+ log("Approving recovery request: " + recoveryRequestId);
+ client.approveRecovery(recoveryRequestId);
+
+ // Test 19: Get key
+ log("Getting passphrase: " + keyId);
+ keyData = client.retrieveKey(keyId, recoveryRequestId, wrappedRecoveryPassphrase, wrappedRecoveryKey, ivps.getIV());
+ wrappedRecoveredKey = keyData.getWrappedPrivateData();
+ try {
+ recoveredKey = CryptoUtil.unwrapUsingPassphrase(wrappedRecoveredKey, recoveryPassphrase);
+ recoveredKey = new String(Utils.base64decode(recoveredKey), "UTF-8");
+ } catch (Exception e) {
+ log("Error: cannot unwrap key using passphrase");
+ e.printStackTrace();
+ }
+
+ if (recoveredKey == null || !recoveredKey.equals(passphrase)) {
+ log("Error: recovered and archived passphrases do not match!");
+ } else {
+ log("Success: recovered and archived passphrases do match!");
+ }
+
+ // Test 20: Submit a recovery request for the passphrase using a passphrase
+ //Wait until retrieving key before sending input data.
+
+ log("Submitting a recovery request for the passphrase using a passphrase, wait till end to provide recovery data.");
+ requestInfo = client.requestRecovery(keyId, null, null, null);
+ recoveryRequestId = requestInfo.getRequestId();
+
+ //Test 21: Approve recovery
+ log("Approving recovery request: " + recoveryRequestId);
+ client.approveRecovery(recoveryRequestId);
+
+ // Test 22: Get key
+ log("Getting passphrase: " + keyId);
+ keyData = client.retrieveKey(keyId, recoveryRequestId, wrappedRecoveryPassphrase, wrappedRecoveryKey, ivps.getIV());
+ wrappedRecoveredKey = keyData.getWrappedPrivateData();
+ try {
+ recoveredKey = CryptoUtil.unwrapUsingPassphrase(wrappedRecoveredKey, recoveryPassphrase);
+ recoveredKey = new String(Utils.base64decode(recoveredKey), "UTF-8");
+ } catch (Exception e) {
+ log("Error: Can't unwrap recovered key using passphrase");
+ e.printStackTrace();
+ }
+
+ if (recoveredKey == null || !recoveredKey.equals(passphrase)) {
+ log("Error: recovered and archived passphrases do not match!");
+ } else {
+ log("Success: recovered and archived passphrases do match!");
+ }
+ }
+
+ private static void log(String string) {
+ // TODO Auto-generated method stub
+ System.out.println(string);
+ }
+
+ private static void printRequestInfo(KeyRequestInfo info) {
+ log("KeyRequestURL: " + info.getRequestURL());
+ log("Key URL: " + info.getKeyURL());
+ log("Status: " + info.getRequestStatus());
+ log("Type: " + info.getRequestType());
+ }
+
+ //Use this when we actually create random initialization vectors
+ private static IVParameterSpec genIV(int blockSize) throws Exception {
+ // generate an IV
+ byte[] iv = new byte[blockSize];
+
+ Random rnd = new Random();
+ rnd.nextBytes(iv);
+
+ return new IVParameterSpec(iv);
+ }
+}
diff --git a/base/kra/functional/src/com/netscape/cms/servlet/test/GeneratePKIArchiveOptions.java b/base/kra/functional/src/com/netscape/cms/servlet/test/GeneratePKIArchiveOptions.java
new file mode 100644
index 000000000..604430b57
--- /dev/null
+++ b/base/kra/functional/src/com/netscape/cms/servlet/test/GeneratePKIArchiveOptions.java
@@ -0,0 +1,222 @@
+package com.netscape.cms.servlet.test;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedWriter;
+import java.io.CharConversionException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateEncodingException;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.cli.PosixParser;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.crypto.AlreadyInitializedException;
+import org.mozilla.jss.crypto.BadPaddingException;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.IVParameterSpec;
+import org.mozilla.jss.crypto.IllegalBlockSizeException;
+import org.mozilla.jss.crypto.KeyGenAlgorithm;
+import org.mozilla.jss.crypto.SymmetricKey;
+import org.mozilla.jss.crypto.SymmetricKey.NotExtractableException;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.util.Password;
+
+import com.netscape.cmsutil.crypto.CryptoUtil;
+import com.netscape.cmsutil.util.Utils;
+
+@SuppressWarnings("deprecation")
+public class GeneratePKIArchiveOptions {
+
+ public static void usage(Options options) {
+ HelpFormatter formatter = new HelpFormatter();
+ formatter.printHelp("GeneratePKIArchiveOptions", options);
+ System.exit(1);
+ }
+
+ private static void log(String string) {
+ // TODO Auto-generated method stub
+ System.out.println(string);
+ }
+
+ // read in byte array
+ // we must do this somewhere?
+ public static byte[] read(String fname) throws IOException {
+ File file = new File(fname);
+ byte[] result = new byte[(int) file.length()];
+ InputStream input = null;
+ try {
+ int totalBytesRead = 0;
+ input = new BufferedInputStream(new FileInputStream(file));
+ while (totalBytesRead < result.length) {
+ int bytesRemaining = result.length - totalBytesRead;
+ //input.read() returns -1, 0, or more :
+ int bytesRead = input.read(result, totalBytesRead, bytesRemaining);
+ if (bytesRead > 0) {
+ totalBytesRead = totalBytesRead + bytesRead;
+ }
+ }
+ } catch (Exception e) {
+ throw new IOException(e);
+ } finally {
+ if (input != null) {
+ input.close();
+ }
+ }
+
+ return result;
+ }
+
+ public static void write(byte[] aInput, String outFile) throws IOException {
+ OutputStream output = null;
+ try {
+ output = new BufferedOutputStream(new FileOutputStream(outFile));
+ output.write(aInput);
+ } catch (Exception e) {
+ throw new IOException(e);
+ } finally {
+ if (output != null) {
+ output.close();
+ }
+ }
+ }
+
+ private static void write_file(String data, String outFile) throws IOException {
+ FileWriter fstream = new FileWriter(outFile);
+ BufferedWriter out = new BufferedWriter(fstream);
+ out.write(data);
+ //Close the output stream
+ out.close();
+ }
+
+ public static void main(String args[]) throws InvalidKeyException, CertificateEncodingException,
+ CharConversionException, NoSuchAlgorithmException, InvalidAlgorithmParameterException,
+ IllegalStateException, TokenException, IOException, IllegalBlockSizeException, BadPaddingException,
+ InvalidBERException, NotExtractableException {
+ String token_pwd = null;
+ String db_dir = "./";
+ String out_file = "./options.out";
+ String transport_file = "./transport.crt";
+ String key_file = "./symkey.out";
+ String passphrase = null;
+ boolean passphraseMode = false;
+
+ // parse command line arguments
+ Options options = new Options();
+ options.addOption("w", true, "Token password (required)");
+ options.addOption("d", true, "Directory for tokendb");
+ options.addOption("p", true, "Passphrase");
+ options.addOption("t", true, "File with transport cert");
+ options.addOption("o", true, "Output file");
+ options.addOption("k", true, "Key file");
+
+ try {
+ CommandLineParser parser = new PosixParser();
+ CommandLine cmd = parser.parse(options, args);
+
+ if (cmd.hasOption("p")) {
+ passphrase = cmd.getOptionValue("p");
+ passphraseMode = true;
+ }
+
+ if (cmd.hasOption("o")) {
+ out_file = cmd.getOptionValue("o");
+ }
+
+ if (cmd.hasOption("k")) {
+ key_file = cmd.getOptionValue("k");
+ }
+
+ if (cmd.hasOption("t")) {
+ transport_file = cmd.getOptionValue("t");
+ }
+
+ if (cmd.hasOption("w")) {
+ token_pwd = cmd.getOptionValue("w");
+ } else {
+ System.err.println("Error: no token password provided");
+ usage(options);
+ }
+
+ if (cmd.hasOption("d")) {
+ db_dir = cmd.getOptionValue("d");
+ }
+
+ } catch (ParseException e) {
+ System.err.println("Error in parsing command line options: " + e.getMessage());
+ usage(options);
+ }
+
+ // used for crypto operations
+ byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
+ IVParameterSpec ivps = new IVParameterSpec(iv);
+ CryptoManager manager = null;
+ CryptoToken token = null;
+
+ // used for wrapping to send data to DRM
+ byte[] tcert = read(transport_file);
+ String transportCert = Utils.base64encode(tcert);
+
+ // Initialize token
+ try {
+ CryptoManager.initialize(db_dir);
+ } catch (AlreadyInitializedException e) {
+ // it is ok if it is already initialized
+ } catch (Exception e) {
+ log("INITIALIZATION ERROR: " + e.toString());
+ System.exit(1);
+ }
+
+ // log into token
+ try {
+ manager = CryptoManager.getInstance();
+ token = manager.getInternalKeyStorageToken();
+ Password password = new Password(token_pwd.toCharArray());
+ try {
+ token.login(password);
+ } catch (Exception e) {
+ log("login Exception: " + e.toString());
+ if (!token.isLoggedIn()) {
+ token.initPassword(password, password);
+ }
+ }
+ } catch (Exception e) {
+ log("Exception in logging into token:" + e.toString());
+ }
+
+ // Data to be archived
+ SymmetricKey vek = null;
+ if (!passphraseMode) {
+ vek = CryptoUtil.generateKey(token, KeyGenAlgorithm.DES3);
+ // store vek in file
+ write_file(Utils.base64encode(vek.getKeyData()), key_file);
+ }
+
+ byte[] encoded = null;
+
+ if (passphraseMode) {
+ encoded = CryptoUtil.createPKIArchiveOptions(manager, token, transportCert, null, passphrase,
+ KeyGenAlgorithm.DES3, ivps);
+ } else {
+ encoded = CryptoUtil.createPKIArchiveOptions(manager, token, transportCert, vek, null,
+ KeyGenAlgorithm.DES3, ivps);
+ }
+
+ // write encoded to file
+ write_file(Utils.base64encode(encoded), out_file);
+
+ }
+}
diff --git a/base/kra/setup/CMakeLists.txt b/base/kra/setup/CMakeLists.txt
new file mode 100644
index 000000000..f5f069cdb
--- /dev/null
+++ b/base/kra/setup/CMakeLists.txt
@@ -0,0 +1,8 @@
+set(VERSION ${APPLICATION_VERSION})
+
+install(
+ FILES
+ registry_instance
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/setup
+)
diff --git a/base/kra/setup/registry_instance b/base/kra/setup/registry_instance
new file mode 100644
index 000000000..3210b9131
--- /dev/null
+++ b/base/kra/setup/registry_instance
@@ -0,0 +1,63 @@
+# Establish PKI Variable "Slot" Substitutions
+
+PKI_FLAVOR=[PKI_FLAVOR]
+export PKI_FLAVOR
+
+PKI_SUBSYSTEM_TYPE=[PKI_SUBSYSTEM_TYPE]
+export PKI_SUBSYSTEM_TYPE
+
+PKI_USER=[PKI_USER]
+export PKI_USER
+
+PKI_GROUP=[PKI_GROUP]
+export PKI_GROUP
+
+PKI_INSTANCE_ID=[PKI_INSTANCE_ID]
+export PKI_INSTANCE_ID
+
+PKI_INSTANCE_PATH=[PKI_INSTANCE_PATH]
+export PKI_INSTANCE_PATH
+
+PKI_INSTANCE_INITSCRIPT=[PKI_INSTANCE_INITSCRIPT]
+export PKI_INSTANCE_INITSCRIPT
+
+PKI_SERVER_XML_CONF=[PKI_SERVER_XML_CONF]
+export PKI_SERVER_XML_CONF
+
+# Use CATALINA_BASE
+
+CATALINA_BASE=$PKI_INSTANCE_PATH
+export CATALINA_BASE
+
+TOMCAT_PROG=$PKI_INSTANCE_ID
+export TOMCAT_PROG
+
+TOMCAT_USER=$PKI_USER
+export TOMCAT_USER
+
+TOMCAT_GROUP=$PKI_GROUP
+export TOMCAT_GROUP
+
+PKI_LOCKDIR="/var/lock/${PKI_FLAVOR}/${PKI_SUBSYSTEM_TYPE}"
+export PKI_LOCKDIR
+
+PKI_LOCKFILE="${PKI_LOCKDIR}/${PKI_INSTANCE_ID}"
+export PKI_LOCKFILE
+
+PKI_PIDDIR="/var/run/${PKI_FLAVOR}/${PKI_SUBSYSTEM_TYPE}"
+export PKI_PIDDIR
+
+PKI_PIDFILE="${PKI_PIDDIR}/${PKI_INSTANCE_ID}.pid"
+export PKI_PIDFILE
+
+TOMCAT_LOCKFILE=/var/lock/subsys/${PKI_INSTANCE_ID}
+export TOMCAT_LOCKFILE
+
+TOMCAT_PIDFILE=[TOMCAT_PIDFILE]
+export TOMCAT_PIDFILE
+
+pki_instance_configuration_file=${PKI_INSTANCE_PATH}/conf/CS.cfg
+export pki_instance_configuration_file
+
+RESTART_SERVER=${PKI_INSTANCE_PATH}/conf/restart_server_after_configuration
+export RESTART_SERVER
diff --git a/base/kra/shared/conf/CMakeLists.txt b/base/kra/shared/conf/CMakeLists.txt
new file mode 100644
index 000000000..e3cef5915
--- /dev/null
+++ b/base/kra/shared/conf/CMakeLists.txt
@@ -0,0 +1,12 @@
+set(VERSION ${APPLICATION_VERSION})
+set(MAJOR_VERSION ${APPLICATION_VERSION_MAJOR})
+set(MINOR_VERSION ${APPLICATION_VERSION_MINOR})
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CS.cfg.in ${CMAKE_CURRENT_BINARY_DIR}/CS.cfg @ONLY)
+
+install(
+ FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/CS.cfg
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/conf
+)
diff --git a/base/kra/shared/conf/CS.cfg.in b/base/kra/shared/conf/CS.cfg.in
new file mode 100644
index 000000000..a6d49ceb5
--- /dev/null
+++ b/base/kra/shared/conf/CS.cfg.in
@@ -0,0 +1,383 @@
+_000=##
+_001=## Data Recovery Manager (DRM) Configuration File
+_002=##
+pkicreate.pki_instance_root=[PKI_INSTANCE_ROOT]
+pkicreate.pki_instance_name=[PKI_INSTANCE_ID]
+pkicreate.subsystem_type=[PKI_SUBSYSTEM_TYPE]
+pkicreate.agent_secure_port=[PKI_AGENT_SECURE_PORT]
+pkicreate.ee_secure_port=[PKI_EE_SECURE_PORT]
+pkicreate.admin_secure_port=[PKI_ADMIN_SECURE_PORT]
+pkicreate.secure_port=[PKI_SECURE_PORT]
+pkicreate.unsecure_port=[PKI_UNSECURE_PORT]
+pkicreate.tomcat_server_port=[TOMCAT_SERVER_PORT]
+pkicreate.user=[PKI_USER]
+pkicreate.group=[PKI_GROUP]
+pkicreate.systemd.servicename=[PKI_SYSTEMD_SERVICENAME]
+pkiremove.cert.subsystem.nickname=subsystemCert cert-[PKI_INSTANCE_ID]
+installDate=[INSTALL_TIME]
+preop.wizard.name=DRM Setup Wizard
+preop.product.name=CS
+preop.product.version=@VERSION@
+preop.system.name=DRM
+preop.system.fullname=Data Recovery Manager
+proxy.securePort=[PKI_PROXY_SECURE_PORT]
+proxy.unsecurePort=[PKI_PROXY_UNSECURE_PORT]
+cs.state=0
+cs.type=KRA
+admin.interface.uri=kra/admin/console/config/wizard
+agent.interface.uri=kra/agent/kra
+authType=pwd
+preop.securitydomain.admin_url=https://[PKI_MACHINE_NAME]:9445
+instanceRoot=[PKI_INSTANCE_PATH]
+machineName=[PKI_MACHINE_NAME]
+instanceId=[PKI_INSTANCE_ID]
+pidDir=[PKI_PIDDIR]
+service.machineName=[PKI_MACHINE_NAME]
+service.instanceDir=[PKI_INSTANCE_ROOT]
+service.securePort=[PKI_AGENT_SECURE_PORT]
+service.non_clientauth_securePort=[PKI_EE_SECURE_PORT]
+service.unsecurePort=[PKI_UNSECURE_PORT]
+service.instanceID=[PKI_INSTANCE_ID]
+preop.admin.name=Data Recovery Manager Administrator
+preop.admin.group=Data Recovery Manager Agents
+preop.admincert.profile=caAdminCert
+preop.pin=[PKI_RANDOM_NUMBER]
+kra.cert.list=transport,storage,sslserver,subsystem,audit_signing
+kra.cert.transport.certusage=SSLClient
+kra.cert.storage.certusage=SSLClient
+kra.cert.sslserver.certusage=SSLServer
+kra.cert.subsystem.certusage=SSLClient
+kra.cert.audit_signing.certusage=ObjectSigner
+preop.cert.list=transport,storage,sslserver,subsystem,audit_signing
+preop.cert.rsalist=transport,storage,audit_signing
+preop.cert.transport.enable=true
+preop.cert.storage.enable=true
+preop.cert.sslserver.enable=true
+preop.cert.subsystem.enable=true
+preop.cert.audit_signing.enable=true
+preop.cert.audit_signing.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.audit_signing.dn=CN=DRM Audit Signing Certificate
+preop.cert.audit_signing.keysize.custom_size=2048
+preop.cert.audit_signing.keysize.size=2048
+preop.cert.audit_signing.nickname=auditSigningCert cert-[PKI_INSTANCE_ID]
+preop.cert.audit_signing.profile=caInternalAuthAuditSigningCert
+preop.cert.audit_signing.signing.required=false
+preop.cert.audit_signing.subsystem=kra
+preop.cert.audit_signing.type=remote
+preop.cert.audit_signing.userfriendlyname=DRM Audit Signing Certificate
+preop.cert.audit_signing.cncomponent.override=true
+preop.cert.storage.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.storage.dn=CN=DRM Storage Certificate
+preop.cert.storage.keysize.custom_size=2048
+preop.cert.storage.keysize.size=2048
+preop.cert.storage.nickname=storageCert cert-[PKI_INSTANCE_ID]
+preop.cert.storage.profile=caInternalAuthDRMstorageCert
+preop.cert.storage.signing.required=false
+preop.cert.storage.subsystem=kra
+preop.cert.storage.type=remote
+preop.cert.storage.userfriendlyname=Storage Certificate
+preop.cert.storage.cncomponent.override=true
+preop.cert.transport.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.transport.dn=CN=DRM Transport Certificate
+preop.cert.transport.keysize.custom_size=2048
+preop.cert.transport.keysize.size=2048
+preop.cert.transport.nickname=transportCert cert-[PKI_INSTANCE_ID]
+preop.cert.transport.profile=caInternalAuthTransportCert
+preop.cert.transport.signing.required=true
+preop.cert.transport.subsystem=kra
+preop.cert.transport.type=remote
+preop.cert.transport.userfriendlyname=Transport Certificate
+preop.cert.transport.cncomponent.override=true
+preop.cert.sslserver.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.sslserver.dn=CN=[PKI_MACHINE_NAME]
+preop.cert.sslserver.keysize.custom_size=2048
+preop.cert.sslserver.keysize.size=2048
+preop.cert.sslserver.nickname=Server-Cert cert-[PKI_INSTANCE_ID]
+preop.cert.sslserver.profile=caInternalAuthServerCert
+preop.cert.sslserver.signing.required=false
+preop.cert.sslserver.subsystem=kra
+preop.cert.sslserver.type=remote
+preop.cert.sslserver.userfriendlyname=SSL Server Certificate
+preop.cert.sslserver.cncomponent.override=false
+preop.cert.subsystem.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.subsystem.dn=CN=DRM Subsystem Certificate
+preop.cert.subsystem.keysize.custom_size=2048
+preop.cert.subsystem.keysize.size=2048
+preop.cert.subsystem.nickname=subsystemCert cert-[PKI_INSTANCE_ID]
+preop.cert.subsystem.profile=caInternalAuthSubsystemCert
+preop.cert.subsystem.signing.required=false
+preop.cert.subsystem.subsystem=kra
+preop.cert.subsystem.type=remote
+preop.cert.subsystem.userfriendlyname=Subsystem Certificate
+preop.cert.subsystem.cncomponent.override=true
+preop.hierarchy.profile=caCert.profile
+preop.configModules.module0.userFriendlyName=NSS Internal PKCS #11 Module
+preop.configModules.module0.commonName=NSS Internal PKCS #11 Module
+preop.configModules.module0.imagePath=../img/clearpixel.gif
+preop.configModules.module1.userFriendlyName=nCipher's nFast Token Hardware Module
+preop.configModules.module1.commonName=nfast
+preop.configModules.module1.imagePath=../img/clearpixel.gif
+preop.configModules.module2.userFriendlyName=SafeNet's LunaSA Token Hardware Module
+preop.configModules.module2.commonName=lunasa
+preop.configModules.module2.imagePath=../img/clearpixel.gif
+preop.configModules.count=3
+preop.module.token=Internal Key Storage Token
+passwordFile=[PKI_INSTANCE_PATH]/conf/password.conf
+passwordClass=com.netscape.cmsutil.password.PlainPasswordFile
+multiroles=true
+multiroles.false.groupEnforceList=Administrators,Auditors,Trusted Managers,Certificate Manager Agents,Registration Manager Agents,Data Recovery Manager Agents,Online Certificate Status Manager Agents,Token Key Service Manager Agents,Enterprise CA Administrators,Enterprise KRA Adminstrators,Enterprise OCSP Administrators,Enterprise RA Administrators,Enterprise TKS Administrators,Enterprise TPS Administrators,Security Domain Administrators,Subsystem Group
+CrossCertPair._000=##
+CrossCertPair._001=## CrossCertPair Import
+CrossCertPair._002=##
+CrossCertPair.ldap=internaldb
+accessEvaluator.impl.group.class=com.netscape.cms.evaluators.GroupAccessEvaluator
+accessEvaluator.impl.ipaddress.class=com.netscape.cms.evaluators.IPAddressAccessEvaluator
+accessEvaluator.impl.user.class=com.netscape.cms.evaluators.UserAccessEvaluator
+auths._000=##
+auths._001=## new authentication
+auths._002=##
+auths.impl._000=##
+auths.impl._001=## authentication manager implementations
+auths.impl._002=##
+auths.impl.AgentCertAuth.class=com.netscape.cms.authentication.AgentCertAuthentication
+auths.impl.CMCAuth.class=com.netscape.cms.authentication.CMCAuth
+auths.impl.NISAuth.class=com.netscape.cms.authentication.NISAuth
+auths.impl.PortalEnroll.class=com.netscape.cms.authentication.PortalEnroll
+auths.impl.TokenAuth.class=com.netscape.cms.authentication.TokenAuthentication
+auths.impl.UdnPwdDirAuth.class=com.netscape.cms.authentication.UdnPwdDirAuthentication
+auths.impl.UidPwdDirAuth.class=com.netscape.cms.authentication.UidPwdDirAuthentication
+auths.impl.UidPwdPinDirAuth.class=com.netscape.cms.authentication.UidPwdPinDirAuthentication
+auths.instance.AgentCertAuth.agentGroup=Certificate Manager Agents
+auths.instance.AgentCertAuth.pluginName=AgentCertAuth
+auths.instance.TokenAuth.pluginName=TokenAuth
+auths.revocationChecking.bufferSize=50
+auths.revocationChecking.enabled=false
+auths.revocationChecking.kra=kra
+authz._000=##
+authz._001=## new authorizatioin
+authz._002=##
+authz.evaluateOrder=deny,allow
+authz.sourceType=ldap
+authz.impl._000=##
+authz.impl._001=## authorization manager implementations
+authz.impl._002=##
+authz.impl.BasicAclAuthz.class=com.netscape.cms.authorization.BasicAclAuthz
+authz.impl.DirAclAuthz.class=com.netscape.cms.authorization.DirAclAuthz
+authz.instance.BasicAclAuthz.pluginName=BasicAclAuthz
+authz.instance.DirAclAuthz.ldap=internaldb
+authz.instance.DirAclAuthz.pluginName=DirAclAuthz
+authz.instance.DirAclAuthz.ldap._000=##
+authz.instance.DirAclAuthz.ldap._001=## Internal Database
+authz.instance.DirAclAuthz.ldap._002=##
+cmc.cert.confirmRequired=false
+cmc.lraPopWitness.verify.allow=true
+cmc.revokeCert.verify=true
+cmc.revokeCert.sharedSecret.class=com.netscape.cms.authentication.SharedSecret
+cmc.sharedSecret.class=com.netscape.cms.authentication.SharedSecret
+cms.version=@MAJOR_VERSION@.@MINOR_VERSION@
+dbs.enableSerialManagement=false
+dbs.beginRequestNumber=1
+dbs.endRequestNumber=10000000
+dbs.requestIncrement=10000000
+dbs.requestLowWaterMark=2000000
+dbs.requestCloneTransferNumber=10000
+dbs.requestDN=ou=kra, ou=requests
+dbs.requestRangeDN=ou=requests, ou=ranges
+dbs.beginSerialNumber=1
+dbs.endSerialNumber=10000000
+dbs.serialIncrement=10000000
+dbs.serialLowWaterMark=2000000
+dbs.serialCloneTransferNumber=10000
+dbs.serialDN=ou=keyRepository, ou=kra
+dbs.serialRangeDN=ou=keyRepository, ou=ranges
+dbs.beginReplicaNumber=1
+dbs.endReplicaNumber=100
+dbs.replicaIncrement=100
+dbs.replicaLowWaterMark=20
+dbs.replicaCloneTransferNumber=5
+dbs.replicaDN=ou=replica
+dbs.replicaRangeDN=ou=replica, ou=ranges
+dbs.ldap=internaldb
+dbs.newSchemaEntryAdded=true
+debug.append=true
+debug.enabled=true
+debug.filename=[PKI_INSTANCE_PATH]/logs/debug
+debug.hashkeytypes=
+debug.level=0
+debug.showcaller=false
+keys.ecc.curve.list=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
+keys.ecc.curve.display.list=nistp256 (secp256r1),nistp384 (secp384r1),nistp521 (secp521r1),nistk163 (sect163k1),sect163r1,nistb163 (sect163r2),sect193r1,sect193r2,nistk233 (sect233k1),nistb233 (sect233r1),sect239k1,nistk283 (sect283k1),nistb283 (sect283r1),nistk409 (sect409k1),nistb409 (sect409r1),nistk571 (sect571k1),nistb571 (sect571r1),secp160k1,secp160r1,secp160r2,secp192k1,nistp192 (secp192r1, prime192v1),secp224k1,nistp224 (secp224r1),secp256k1,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
+keys.ecc.curve.default=nistp256
+keys.rsa.keysize.default=2048
+internaldb._000=##
+internaldb._001=## Internal Database
+internaldb._002=##
+internaldb.maxConns=15
+internaldb.minConns=3
+internaldb.ldapauth.authtype=BasicAuth
+internaldb.ldapauth.bindDN=cn=Directory Manager
+internaldb.ldapauth.bindPWPrompt=Internal LDAP Database
+internaldb.ldapauth.clientCertNickname=
+internaldb.ldapconn.host=
+internaldb.ldapconn.port=
+internaldb.ldapconn.secureConn=false
+preop.internaldb.schema.ldif=/usr/share/[PKI_FLAVOR]/kra/conf/schema.ldif
+preop.internaldb.ldif=/usr/share/[PKI_FLAVOR]/kra/conf/database.ldif
+preop.internaldb.data_ldif=/usr/share/[PKI_FLAVOR]/kra/conf/db.ldif,/usr/share/[PKI_FLAVOR]/kra/conf/acl.ldif
+preop.internaldb.index_ldif=
+preop.internaldb.manager_ldif=/usr/share/[PKI_FLAVOR]/ca/conf/manager.ldif
+preop.internaldb.post_ldif=/usr/share/[PKI_FLAVOR]/kra/conf/index.ldif,/usr/share/[PKI_FLAVOR]/kra/conf/vlv.ldif,/usr/share/[PKI_FLAVOR]/kra/conf/vlvtasks.ldif
+preop.internaldb.wait_dn=cn=index1160527115, cn=index, cn=tasks, cn=config
+internaldb.multipleSuffix.enable=false
+jobsScheduler._000=##
+jobsScheduler._001=## jobScheduler
+jobsScheduler._002=##
+jobsScheduler.enabled=false
+jobsScheduler.interval=1
+jss._000=##
+jss._001=## JSS
+jss._002=##
+jss.configDir=[PKI_INSTANCE_PATH]/alias/
+jss.enable=true
+jss.secmodName=secmod.db
+jss.ocspcheck.enable=false
+jss.ssl.cipherfortezza=true
+jss.ssl.cipherpref=
+jss.ssl.cipherversion=cipherdomestic
+kra.Policy._000=##
+kra.Policy._001=## Certificate Policy Framework (deprecated)
+kra.Policy._002=##
+kra.Policy._003=## Set 'kra.Policy.enable=true' to allow the following:
+kra.Policy._004=##
+kra.Policy._005=## SERVLET-NAME URL-PATTERN
+kra.Policy._006=## ====================================================
+kra.Policy._007=## krapolicy kra/krapolicy
+kra.Policy._008=##
+kra.Policy.enable=false
+kra.keySplitting=false
+kra.noOfRequiredRecoveryAgents=1
+kra.recoveryAgentGroup=Data Recovery Manager Agents
+kra.reqdbInc=20
+kra.entropy.bitsperkeypair=0
+kra.entropy.blockwarnms=0
+kra.storageUnit.nickName=storageCert cert-[PKI_INSTANCE_ID]
+kra.transportUnit.nickName=transportCert cert-[PKI_INSTANCE_ID]
+log._000=##
+log._001=## Logging
+log._002=##
+log.impl.file.class=com.netscape.cms.logging.RollingLogFile
+log.instance.SignedAudit._000=##
+log.instance.SignedAudit._001=## Signed Audit Logging
+log.instance.SignedAudit._002=##
+log.instance.SignedAudit._003=##
+log.instance.SignedAudit._004=## Available Audit events:
+log.instance.SignedAudit._005=## AUDIT_LOG_STARTUP,AUDIT_LOG_SHUTDOWN,ROLE_ASSUME,CONFIG_CERT_POLICY,CONFIG_CERT_PROFILE,CONFIG_CRL_PROFILE,CONFIG_OCSP_PROFILE,CONFIG_AUTH,CONFIG_ROLE,CONFIG_ACL,CONFIG_SIGNED_AUDIT,CONFIG_ENCRYPTION,CONFIG_TRUSTED_PUBLIC_KEY,CONFIG_DRM,SELFTESTS_EXECUTION,AUDIT_LOG_DELETE,LOG_PATH_CHANGE,LOG_EXPIRATION_CHANGE,PRIVATE_KEY_ARCHIVE_REQUEST,PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE,KEY_RECOVERY_REQUEST,KEY_RECOVERY_REQUEST_ASYNC,KEY_RECOVERY_AGENT_LOGIN,KEY_RECOVERY_REQUEST_PROCESSED,KEY_RECOVERY_REQUEST_PROCESSED_ASYNC,KEY_GEN_ASYMMETRIC,NON_PROFILE_CERT_REQUEST,PROFILE_CERT_REQUEST,CERT_REQUEST_PROCESSED,CERT_STATUS_CHANGE_REQUEST,CERT_STATUS_CHANGE_REQUEST_PROCESSED,AUTHZ_SUCCESS,AUTHZ_FAIL,INTER_BOUNDARY,AUTH_FAIL,AUTH_SUCCESS,CERT_PROFILE_APPROVAL,PROOF_OF_POSSESSION,CRL_RETRIEVAL,CRL_VALIDATION,CMC_SIGNED_REQUEST_SIG_VERIFY,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_FAILURE,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_SUCCESS,SERVER_SIDE_KEYGEN_REQUEST,COMPUTE_SESSION_KEY_REQUEST,COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS, COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE,DIVERSIFY_KEY_REQUEST,DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS, DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE,ENCRYPT_DATA_REQUEST,ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS,ENCRYPT_DATA_REQUEST_PROCESSED_FAILURE,OCSP_ADD_CA_REQUEST,OCSP_ADD_CA_REQUEST_PROCESSED,OCSP_REMOVE_CA_REQUEST,OCSP_REMOVE_CA_REQUEST_PROCESSED_SUCCESS,OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE,COMPUTE_RANDOM_DATA_REQUEST,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_SUCCESS,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_FAILURE,CIMC_CERT_VERIFICATION,CONFIG_SERIAL_NUMBER
+log.instance.SignedAudit._006=##
+log.instance.SignedAudit.bufferSize=512
+log.instance.SignedAudit.enable=true
+log.instance.SignedAudit.events=AUDIT_LOG_STARTUP,AUDIT_LOG_SHUTDOWN,ROLE_ASSUME,CONFIG_CERT_POLICY,CONFIG_CERT_PROFILE,CONFIG_CRL_PROFILE,CONFIG_OCSP_PROFILE,CONFIG_AUTH,CONFIG_ROLE,CONFIG_ACL,CONFIG_SIGNED_AUDIT,CONFIG_ENCRYPTION,CONFIG_TRUSTED_PUBLIC_KEY,CONFIG_DRM,SELFTESTS_EXECUTION,AUDIT_LOG_DELETE,LOG_PATH_CHANGE,PRIVATE_KEY_ARCHIVE_REQUEST,PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE,KEY_RECOVERY_REQUEST,KEY_RECOVERY_REQUEST_ASYNC,KEY_RECOVERY_AGENT_LOGIN,KEY_RECOVERY_REQUEST_PROCESSED,KEY_RECOVERY_REQUEST_PROCESSED_ASYNC,KEY_GEN_ASYMMETRIC,NON_PROFILE_CERT_REQUEST,PROFILE_CERT_REQUEST,CERT_REQUEST_PROCESSED,CERT_STATUS_CHANGE_REQUEST,CERT_STATUS_CHANGE_REQUEST_PROCESSED,AUTHZ_SUCCESS,AUTHZ_FAIL,INTER_BOUNDARY,AUTH_FAIL,AUTH_SUCCESS,CERT_PROFILE_APPROVAL,PROOF_OF_POSSESSION,CRL_RETRIEVAL,CRL_VALIDATION,CMC_SIGNED_REQUEST_SIG_VERIFY,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_FAILURE,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_SUCCESS,SERVER_SIDE_KEYGEN_REQUEST,COMPUTE_SESSION_KEY_REQUEST,COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS, COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE,DIVERSIFY_KEY_REQUEST,DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS, DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE,ENCRYPT_DATA_REQUEST,ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS,ENCRYPT_DATA_REQUEST_PROCESSED_FAILURE,OCSP_ADD_CA_REQUEST,OCSP_ADD_CA_REQUEST_PROCESSED,OCSP_REMOVE_CA_REQUEST,OCSP_REMOVE_CA_REQUEST_PROCESSED_SUCCESS,OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE,COMPUTE_RANDOM_DATA_REQUEST,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_SUCCESS,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_FAILURE,CIMC_CERT_VERIFICATION,CONFIG_SERIAL_NUMBER
+log.instance.SignedAudit.expirationTime=0
+log.instance.SignedAudit.fileName=[PKI_INSTANCE_PATH]/logs/signedAudit/kra_cert-kra_audit
+log.instance.SignedAudit.flushInterval=5
+log.instance.SignedAudit.level=1
+log.instance.SignedAudit.logSigning=false
+log.instance.SignedAudit.maxFileSize=2000
+log.instance.SignedAudit.pluginName=file
+log.instance.SignedAudit.rolloverInterval=2592000
+log.instance.SignedAudit.signedAudit:_000=##
+log.instance.SignedAudit.signedAudit:_001=## Fill in the nickname of a trusted signing certificate to allow KRA audit logs to be signed
+log.instance.SignedAudit.signedAudit:_002=##
+log.instance.SignedAudit.signedAuditCertNickname=auditSigningCert cert-[PKI_INSTANCE_ID]
+log.instance.SignedAudit.type=signedAudit
+log.instance.System._000=##
+log.instance.System._001=## System Logging
+log.instance.System._002=##
+log.instance.System.bufferSize=512
+log.instance.System.enable=true
+log.instance.System.expirationTime=0
+log.instance.System.fileName=[PKI_INSTANCE_PATH]/logs/system
+log.instance.System.flushInterval=5
+log.instance.System.level=3
+log.instance.System.maxFileSize=2000
+log.instance.System.pluginName=file
+log.instance.System.rolloverInterval=2592000
+log.instance.System.type=system
+log.instance.Transactions._000=##
+log.instance.Transactions._001=## Transaction Logging
+log.instance.Transactions._002=##
+log.instance.Transactions.bufferSize=512
+log.instance.Transactions.enable=true
+log.instance.Transactions.expirationTime=0
+log.instance.Transactions.fileName=[PKI_INSTANCE_PATH]/logs/transactions
+log.instance.Transactions.flushInterval=5
+log.instance.Transactions.level=1
+log.instance.Transactions.maxFileSize=2000
+log.instance.Transactions.pluginName=file
+log.instance.Transactions.rolloverInterval=2592000
+log.instance.Transactions.type=transaction
+logAudit.fileName=[PKI_INSTANCE_PATH]/logs/access
+logError.fileName=[PKI_INSTANCE_PATH]/logs/error
+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.extended_key_usage.class=netscape.security.extensions.ExtendedKeyUsageExtension
+oidmap.extended_key_usage.oid=2.5.29.37
+oidmap.extensions_requested_pkcs9.class=com.netscape.cms.servlet.cert.scep.ExtensionsRequested
+oidmap.extensions_requested_pkcs9.oid=1.2.840.113549.1.9.14
+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.netscape_comment.class=netscape.security.x509.NSCCommentExtension
+oidmap.netscape_comment.oid=2.16.840.1.113730.1.13
+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.pse.class=netscape.security.extensions.PresenceServerExtension
+oidmap.pse.oid=2.16.840.1.113730.1.18
+oidmap.subject_info_access.class=netscape.security.extensions.SubjectInfoAccessExtension
+oidmap.subject_info_access.oid=1.3.6.1.5.5.7.1.11
+os.serverName=cert-[PKI_INSTANCE_ID]
+os.userid=nobody
+registry.file=[PKI_INSTANCE_PATH]/conf/registry.cfg
+selftests._000=##
+selftests._001=## Self Tests
+selftests._002=##
+selftests._003=## The Self-Test plugin SystemCertsVerification uses the
+selftests._004=## following parameters (where certusage is optional):
+selftests._005=## kra.cert.list = <list of cert tag names deliminated by ",">
+selftests._006=## kra.cert.<cert tag name>.nickname
+selftests._007=## kra.cert.<cert tag name>.certusage
+selftests._008=##
+selftests.container.instance.KRAPresence=com.netscape.cms.selftests.kra.KRAPresence
+selftests.container.instance.SystemCertsVerification=com.netscape.cms.selftests.common.SystemCertsVerification
+selftests.container.logger.bufferSize=512
+selftests.container.logger.class=com.netscape.cms.logging.RollingLogFile
+selftests.container.logger.enable=true
+selftests.container.logger.expirationTime=0
+selftests.container.logger.fileName=[PKI_INSTANCE_PATH]/logs/selftests.log
+selftests.container.logger.flushInterval=5
+selftests.container.logger.level=1
+selftests.container.logger.maxFileSize=2000
+selftests.container.logger.register=false
+selftests.container.logger.rolloverInterval=2592000
+selftests.container.logger.type=transaction
+selftests.container.order.onDemand=KRAPresence:critical
+selftests.container.order.startup=SystemCertsVerification:critical
+selftests.plugin.KRAPresence.SubId=kra
+selftests.plugin.SystemCertsVerification.SubId=kra
+smtp.host=localhost
+smtp.port=25
+subsystem.0.class=com.netscape.kra.KeyRecoveryAuthority
+subsystem.0.id=kra
+subsystem.1.class=com.netscape.cmscore.selftests.SelfTestSubsystem
+subsystem.1.id=selftests
+subsystem.2.class=com.netscape.cmscore.util.StatsSubsystem
+subsystem.2.id=stats
+usrgrp._000=##
+usrgrp._001=## User/Group
+usrgrp._002=##
+usrgrp.ldap=internaldb
+multiroles._000=##
+multiroles._001=## multiroles
+multiroles._002=##
+multiroles.enable=true
+multiroles.false.groupEnforceList=Administrators,Auditors,Trusted Managers,Certificate Manager Agents,Registration Manager Agents,Data Recovery Manager Agents,Online Certificate Status Manager Agents,Token Key Service Manager Agents,Enterprise CA Administrators,Enterprise KRA Administrators,Enterprise OCSP Administrators,Enterprise RA Administrators,Enterprise TKS Administrators,Enterprise TPS Administrators,Security Domain Administrators,Subsystem Group,ClonedSubsystems
diff --git a/base/kra/shared/conf/acl.ldif b/base/kra/shared/conf/acl.ldif
new file mode 100644
index 000000000..38a9a088c
--- /dev/null
+++ b/base/kra/shared/conf/acl.ldif
@@ -0,0 +1,42 @@
+dn: cn=aclResources,{rootSuffix}
+objectClass: top
+objectClass: CertACLS
+cn: aclResources
+resourceACLS: certServer.general.configuration:read,modify,delete:allow (read) group="Administrators" || group="Auditors" || group="Data Recovery Manager Agents";allow (modify,delete) group="Administrators":Administrators, auditors, and agents are allowed to read CMS general configuration but only administrators are allowed to modify and delete
+resourceACLS: certServer.acl.configuration:read,modify:allow (read) group="Administrators" || group="Data Recovery Manager Agents" || group="Auditors";allow (modify) group="Administrators":Administrators, agents and auditors are allowed to read ACL configuration but only administrators allowed to modify
+resourceACLS: certServer.log.configuration:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Data Recovery Manager Agents";allow (modify) group="Administrators":Administrators, Agents, and auditors are allowed to read the log configuration but only administrators are allowed to modify
+resourceACLS: certServer.log.configuration.fileName:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Data Recovery Manager Agents";deny (modify) user=anybody:Nobody is allowed to modify a fileName parameter
+#resourceACLS: certServer.log.configuration.signedAudit.expirationTime:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Data Recovery Manager Agents";deny (modify) user=anybody:Nobody is allowed to modify an expirationTime parameter
+resourceACLS: certServer.log.content.signedAudit:read:allow (read) group="Auditors":Only auditor is allowed to read the signed audit log
+resourceACLS: certServer.log.content.system:read:allow (read) group="Administrators" || group="Data Recovery Manager Agents" || group="Auditors":Administrators, auditors, and agents are allowed to read the log content
+resourceACLS: certServer.log.content.transactions:read:allow (read) group="Administrators" || group="Data Recovery Manager Agents" || group="Auditors":Administrators, auditors, and agents are allowed to read the log content
+resourceACLS: certServer.auth.configuration:read,modify:allow (read) group="Administrators" || group="Data Recovery Manager Agents" || group="Auditors";allow (modify) group="Administrators":Administrators, agents, and auditors are allowed to read authentication configuration but only administrators allowed to modify
+resourceACLS: certServer.registry.configuration:read,modify:allow (read) group="Administrators" || group="Data Recovery Manager Agents" || group="Auditors";allow (modify) group="Administrators":this acl is shared by all admin servlets
+resourceACLS: certServer.job.configuration:read,modify:allow (read) group="Administrators" || group="Data Recovery Manager Agents" || group="Auditors";allow (modify) group="Administrators":Administrators, agents, and auditors are allowed to read job configuration but only administrators allowed to modify
+resourceACLS: certServer.kra.configuration:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Data Recovery Manager Agents";allow (modify) group="Administrators":Administrators, auditors, and agents are allowed to read DRM configuration but only administrators allowed to modify
+resourceACLS: certServer.kra.key:read,recover,download:allow (read,recover,download) group="Data Recovery Manager Agents":Only data recovery manager agents retrieve key information
+resourceACLS: certServer.kra.request:read:allow (read) group="Data Recovery Manager Agents":Data Recovery Manager Agents may read request
+resourceACLS: certServer.kra.keys:list:allow (list) group="Data Recovery Manager Agents":Only data recovery manager agents list keys
+resourceACLS: certServer.kra.requests:list:allow (list) group="Data Recovery Manager Agents":Only data recovery manager agents list key archival requests
+resourceACLS: certServer.admin.certificate:import:allow (import) user="anybody":Any user may import a certificate
+resourceACLS: certServer.admin.request.enrollment:submit,read,execute:allow (submit) user="anybody":Anybody may submit an enrollment request
+resourceACLS: certServer.kra.connector:submit:allow (submit) group="Trusted Managers":Only Trusted Managers submit requests
+resourceACLS: certServer.kra.systemstatus:read:allow (read) group="Data Recovery Manager Agents":Data Recovery Manager agents may view statistics
+resourceACLS: certServer.kra.certificate.transport:read:allow (read) user="anybody":Anybody is allowed to read transport certificate
+resourceACLS: certServer.kra.request.status:read:allow (read) group="Data Recovery Manager Agents":Only data recovery manager agents retrieve the remote key recovery approval status
+resourceACLS: certServer.kra.group:read,modify:allow (modify,read) group="Administrators":Only administrators are allowed to read and modify groups
+resourceACLS: certServer.kra.GenerateKeyPair:execute:allow (execute) group="Data Recovery Manager Agents":Only Data Recovery Manager Agents are allowed to execute requests
+resourceACLS: certServer.kra.TokenKeyRecovery:submit:allow (submit) group="Data Recovery Manager Agents":Only Data Recovery Manager Agents are allowed to submit requests
+resourceACLS: certServer.kra.registerUser:read,modify:allow (modify,read) group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise OCSP Administrators" || group="Enterprise TKS Administrators" || group="Enterprise TPS Administrators":Only Enterprise Administrators are allowed to register a new agent
+resourceACLS: certServer.kra.getTransportCert:read:allow (read) group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise OCSP Administrators" || group="Enterprise TKS Administrators" || group="Enterprise TPS Administrators":Only Enterprise Administrators are allowed to retrieve the transport cert
+resourceACLS: certServer.clone.configuration:read,modify:allow (modify,read) group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise OCSP Administrators" || group="Enterprise TKS Administrators":Only Enterprise Administrators are allowed to clone the configuration.
+resourceACLS: certServer.kra.pki.key.retrieve:execute:allow (execute) group="Data Recovery Manager Agents":Data Recovery Manager Agents may retrieve archived key
+resourceACLS: certServer.kra.pki.keyrequests:read:allow (read) group="Data Recovery Manager Agents":Data Recovery Manager Agents may read keyrequests data
+resourceACLS: certServer.kra.pki.keyrequest:read:allow (read) group="Data Recovery Manager Agents":Data Recovery Manager Agents may read keyrequest data
+resourceACLS: certServer.kra.pki.keyrequest.archive:execute:allow (execute) group="Data Recovery Manager Agents":Data Recovery Manager Agents may issue archival request
+resourceACLS: certServer.kra.pki.keyrequest.recover:execute:allow (execute) group="Data Recovery Manager Agents":Data Recovery Manager Agents may issue recovery request
+resourceACLS: certServer.kra.pki.keyrequest.approve:execute:allow (execute) group="Data Recovery Manager Agents":Data Recovery Manager Agents may approve security data request
+resourceACLS: certServer.kra.pki.keyrequest.reject:execute:allow (execute) group="Data Recovery Manager Agents":Data Recovery Manager Agents may reject key security data request
+resourceACLS: certServer.kra.pki.keyrequest.cancel:execute:allow (execute) group="Data Recovery Manager Agents":Data Recovery Manager Agents may cancel security data request
+resourceACLS: certServer.kra.pki.keys:read:allow (read) group="Data Recovery Manager Agents":Data Recovery Manager Agents may read security data
+resourceACLS: certServer.kra.pki.config.cert.transport:read:allow (read) group="Data Recovery Manager Agents":Data Recovery Manager Agents may read transport cert data
diff --git a/base/kra/shared/conf/catalina.policy b/base/kra/shared/conf/catalina.policy
new file mode 100644
index 000000000..cf8302cd0
--- /dev/null
+++ b/base/kra/shared/conf/catalina.policy
@@ -0,0 +1,184 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// Copyright (C) 2006-2010 Red Hat, Inc.
+// All rights reserved.
+// Modifications: configuration parameters
+// --- END COPYRIGHT BLOCK ---
+
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// ============================================================================
+// catalina.corepolicy - Security Policy Permissions for Tomcat 6
+//
+// This file contains a default set of security policies to be enforced (by the
+// JVM) when Catalina is executed with the "-security" option. In addition
+// to the permissions granted here, the following additional permissions are
+// granted to the codebase specific to each web application:
+//
+// * Read access to the document root directory
+//
+// $Id$
+// ============================================================================
+
+
+// ========== SYSTEM CODE PERMISSIONS =========================================
+
+
+// These permissions apply to javac
+grant codeBase "file:${java.home}/lib/-" {
+ permission java.security.AllPermission;
+};
+
+// These permissions apply to all shared system extensions
+grant codeBase "file:${java.home}/jre/lib/ext/-" {
+ permission java.security.AllPermission;
+};
+
+// These permissions apply to javac when ${java.home] points at $JAVA_HOME/jre
+grant codeBase "file:${java.home}/../lib/-" {
+ permission java.security.AllPermission;
+};
+
+// These permissions apply to all shared system extensions when
+// ${java.home} points at $JAVA_HOME/jre
+grant codeBase "file:${java.home}/lib/ext/-" {
+ permission java.security.AllPermission;
+};
+
+
+// ========== CATALINA CODE PERMISSIONS =======================================
+
+
+// These permissions apply to the daemon code
+grant codeBase "file:${catalina.home}/bin/commons-daemon.jar" {
+ permission java.security.AllPermission;
+};
+
+// These permissions apply to the logging API
+grant codeBase "file:${catalina.home}/bin/tomcat-juli.jar" {
+ permission java.util.PropertyPermission "java.util.logging.config.class", "read";
+ permission java.util.PropertyPermission "java.util.logging.config.file", "read";
+ permission java.io.FilePermission "${java.home}${file.separator}lib${file.separator}logging.properties", "read";
+ permission java.lang.RuntimePermission "shutdownHooks";
+ permission java.io.FilePermission "${catalina.base}${file.separator}conf${file.separator}logging.properties", "read";
+ permission java.util.PropertyPermission "catalina.base", "read";
+ permission java.util.logging.LoggingPermission "control";
+ permission java.io.FilePermission "${catalina.base}${file.separator}logs", "read, write";
+ permission java.io.FilePermission "${catalina.base}${file.separator}logs${file.separator}*", "read, write";
+ permission java.lang.RuntimePermission "getClassLoader";
+ // To enable per context logging configuration, permit read access to the appropriate file.
+ // Be sure that the logging configuration is secure before enabling such access
+ // eg for the examples web application:
+ // permission java.io.FilePermission "${catalina.base}${file.separator}webapps${file.separator}examples${file.separator}WEB-INF${file.separator}classes${file.separator}logging.properties", "read";
+};
+
+// These permissions apply to the server startup code
+grant codeBase "file:${catalina.home}/bin/bootstrap.jar" {
+ permission java.security.AllPermission;
+};
+
+// These permissions apply to the servlet API classes
+// and those that are shared across all class loaders
+// located in the "lib" directory
+grant codeBase "file:${catalina.home}/lib/-" {
+ permission java.security.AllPermission;
+};
+
+
+// ========== WEB APPLICATION PERMISSIONS =====================================
+
+
+// These permissions are granted by default to all web applications
+// In addition, a web application will be given a read FilePermission
+// and JndiPermission for all files and directories in its document root.
+grant {
+ // Required for JNDI lookup of named JDBC DataSource's and
+ // javamail named MimePart DataSource used to send mail
+ permission java.util.PropertyPermission "java.home", "read";
+ permission java.util.PropertyPermission "java.naming.*", "read";
+ permission java.util.PropertyPermission "javax.sql.*", "read";
+
+ // OS Specific properties to allow read access
+ permission java.util.PropertyPermission "os.name", "read";
+ permission java.util.PropertyPermission "os.version", "read";
+ permission java.util.PropertyPermission "os.arch", "read";
+ permission java.util.PropertyPermission "file.separator", "read";
+ permission java.util.PropertyPermission "path.separator", "read";
+ permission java.util.PropertyPermission "line.separator", "read";
+
+ // JVM properties to allow read access
+ permission java.util.PropertyPermission "java.version", "read";
+ permission java.util.PropertyPermission "java.vendor", "read";
+ permission java.util.PropertyPermission "java.vendor.url", "read";
+ permission java.util.PropertyPermission "java.class.version", "read";
+ permission java.util.PropertyPermission "java.specification.version", "read";
+ permission java.util.PropertyPermission "java.specification.vendor", "read";
+ permission java.util.PropertyPermission "java.specification.name", "read";
+
+ permission java.util.PropertyPermission "java.vm.specification.version", "read";
+ permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
+ permission java.util.PropertyPermission "java.vm.specification.name", "read";
+ permission java.util.PropertyPermission "java.vm.version", "read";
+ permission java.util.PropertyPermission "java.vm.vendor", "read";
+ permission java.util.PropertyPermission "java.vm.name", "read";
+
+ // Required for OpenJMX
+ permission java.lang.RuntimePermission "getAttribute";
+
+ // Allow read of JAXP compliant XML parser debug
+ permission java.util.PropertyPermission "jaxp.debug", "read";
+
+ // Precompiled JSPs need access to this package.
+ permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime";
+ permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime.*";
+
+ // Precompiled JSPs need access to this system property.
+ permission java.util.PropertyPermission "org.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER", "read";
+
+};
+
+
+// You can assign additional permissions to particular web applications by
+// adding additional "grant" entries here, based on the code base for that
+// application, /WEB-INF/classes/, or /WEB-INF/lib/ jar files.
+//
+// Different permissions can be granted to JSP pages, classes loaded from
+// the /WEB-INF/classes/ directory, all jar files in the /WEB-INF/lib/
+// directory, or even to individual jar files in the /WEB-INF/lib/ directory.
+//
+// For instance, assume that the standard "examples" application
+// included a JDBC driver that needed to establish a network connection to the
+// corresponding database and used the scrape taglib to get the weather from
+// the NOAA web server. You might create a "grant" entries like this:
+//
+// The permissions granted to the context root directory apply to JSP pages.
+// grant codeBase "file:${catalina.home}/webapps/examples/-" {
+// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
+// permission java.net.SocketPermission "*.noaa.gov:80", "connect";
+// };
+//
+// The permissions granted to the context WEB-INF/classes directory
+// grant codeBase "file:${catalina.home}/webapps/examples/WEB-INF/classes/-" {
+// };
+//
+// The permission granted to your JDBC driver
+// grant codeBase "jar:file:${catalina.home}/webapps/examples/WEB-INF/lib/driver.jar!/-" {
+// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
+// };
+// The permission granted to the scrape taglib
+// grant codeBase "jar:file:${catalina.home}/webapps/examples/WEB-INF/lib/scrape.jar!/-" {
+// permission java.net.SocketPermission "*.noaa.gov:80", "connect";
+// };
+
diff --git a/base/kra/shared/conf/catalina.properties b/base/kra/shared/conf/catalina.properties
new file mode 100644
index 000000000..70cb7c05e
--- /dev/null
+++ b/base/kra/shared/conf/catalina.properties
@@ -0,0 +1,87 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006-2010 Red Hat, Inc.
+# All rights reserved.
+# Modifications: configuration parameters
+# --- END COPYRIGHT BLOCK ---
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# List of comma-separated packages that start with or equal this string
+# will cause a security exception to be thrown when
+# passed to checkPackageAccess unless the
+# corresponding RuntimePermission ("accessClassInPackage."+package) has
+# been granted.
+package.access=sun.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper.,sun.beans.
+#
+# List of comma-separated packages that start with or equal this string
+# will cause a security exception to be thrown when
+# passed to checkPackageDefinition unless the
+# corresponding RuntimePermission ("defineClassInPackage."+package) has
+# been granted.
+#
+# by default, no packages are restricted for definition, and none of
+# the class loaders supplied with the JDK call checkPackageDefinition.
+#
+package.definition=sun.,java.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper.
+
+#
+#
+# List of comma-separated paths defining the contents of the "common"
+# classloader. Prefixes should be used to define what is the repository type.
+# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute.
+# If left as blank,the JVM system loader will be used as Catalina's "common"
+# loader.
+# Examples:
+# "foo": Add this folder as a class repository
+# "foo/*.jar": Add all the JARs of the specified folder as class
+# repositories
+# "foo/bar.jar": Add bar.jar as a class repository
+common.loader=${catalina.home}/lib,${catalina.home}/lib/*.jar,[TOMCAT_INSTANCE_COMMON_LIB]
+
+#
+# List of comma-separated paths defining the contents of the "server"
+# classloader. Prefixes should be used to define what is the repository type.
+# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute.
+# If left as blank, the "common" loader will be used as Catalina's "server"
+# loader.
+# Examples:
+# "foo": Add this folder as a class repository
+# "foo/*.jar": Add all the JARs of the specified folder as class
+# repositories
+# "foo/bar.jar": Add bar.jar as a class repository
+server.loader=
+
+#
+# List of comma-separated paths defining the contents of the "shared"
+# classloader. Prefixes should be used to define what is the repository type.
+# Path may be relative to the CATALINA_BASE path or absolute. If left as blank,
+# the "common" loader will be used as Catalina's "shared" loader.
+# Examples:
+# "foo": Add this folder as a class repository
+# "foo/*.jar": Add all the JARs of the specified folder as class
+# repositories
+# "foo/bar.jar": Add bar.jar as a class repository
+# Please note that for single jars, e.g. bar.jar, you need the URL form
+# starting with file:.
+shared.loader=
+
+#
+# String cache configuration.
+tomcat.util.buf.StringCache.byte.enabled=true
+#tomcat.util.buf.StringCache.char.enabled=true
+#tomcat.util.buf.StringCache.trainThreshold=500000
+#tomcat.util.buf.StringCache.cacheSize=5000
diff --git a/base/kra/shared/conf/context.xml b/base/kra/shared/conf/context.xml
new file mode 100644
index 000000000..8b6fe4905
--- /dev/null
+++ b/base/kra/shared/conf/context.xml
@@ -0,0 +1,40 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2006-2010 Red Hat, Inc.
+ All rights reserved.
+ Modifications: configuration parameters
+ END COPYRIGHT BLOCK -->
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- The contents of this file will be loaded for each web application -->
+<Context crossContext="true" allowLinking="true">
+
+ <!-- Default set of monitored resources -->
+ <WatchedResource>WEB-INF/web.xml</WatchedResource>
+
+ <!-- Uncomment this to disable session persistence across Tomcat restarts -->
+ <!--
+ <Manager pathname="" />
+ -->
+
+ <!-- Uncomment this to enable Comet connection tacking (provides events
+ on session expiration as well as webapp lifecycle) -->
+ <!--
+ <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
+ -->
+
+</Context>
diff --git a/base/kra/shared/conf/database.ldif b/base/kra/shared/conf/database.ldif
new file mode 100644
index 000000000..4dfdcea69
--- /dev/null
+++ b/base/kra/shared/conf/database.ldif
@@ -0,0 +1,4 @@
+dn: cn=config
+changetype: modify
+replace: nsslapd-maxbersize
+nsslapd-maxbersize: 209715200
diff --git a/base/kra/shared/conf/db.ldif b/base/kra/shared/conf/db.ldif
new file mode 100644
index 000000000..c07e9f1a6
--- /dev/null
+++ b/base/kra/shared/conf/db.ldif
@@ -0,0 +1,107 @@
+dn: ou=people,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: people
+aci: (targetattr!="userPassword")(version 3.0; acl "Enable anonymous access"; allow (read, search, compare)userdn="ldap:///anyone";)
+
+dn: ou=groups,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: groups
+
+dn: cn=Data Recovery Manager Agents,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Data Recovery Manager Agents
+description: Agents for Data Recovery Manager
+
+dn: cn=Subsystem Group, ou=groups, {rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Subsystem Group
+description: Subsystem Group
+
+dn: cn=Trusted Managers,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Trusted Managers
+description: Managers trusted by this PKI instance
+
+dn: cn=Administrators,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Administrators
+description: People who manage the Certificate System
+
+dn: cn=Auditors,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Auditors
+description: People who can read the signed audits
+
+dn: cn=ClonedSubsystems,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: ClonedSubsystems
+description: People who can clone the master subsystem
+
+dn: ou=requests,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: requests
+
+dn: cn=crossCerts,{rootSuffix}
+cn: crossCerts
+sn: crossCerts
+objectClass: top
+objectClass: person
+objectClass: pkiCA
+cACertificate;binary:
+authorityRevocationList;binary:
+certificateRevocationList;binary:
+crossCertificatePair;binary:
+
+dn: ou=kra, {rootSuffix}
+objectclass: top
+objectclass: organizationalUnit
+ou: kra
+
+dn: ou=keyRepository, ou=kra, {rootSuffix}
+objectclass: top
+objectclass: repository
+ou: keyRepository
+serialno: 010
+
+dn: ou=kra, ou=requests, {rootSuffix}
+objectclass: top
+objectclass: repository
+ou: kra
+serialno: 010
+
+dn: ou=replica,{rootSuffix}
+objectClass: top
+objectClass: repository
+ou: replica
+serialno: 010
+nextRange: 1000
+
+dn: ou=ranges,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: ranges
+
+dn: ou=replica, ou=ranges,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: replica
+
+dn: ou=requests, ou=ranges,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: requests
+
+dn: ou=keyRepository, ou=ranges,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: certificateRepository
+
diff --git a/base/kra/shared/conf/index.ldif b/base/kra/shared/conf/index.ldif
new file mode 100644
index 000000000..4bc8aebf9
--- /dev/null
+++ b/base/kra/shared/conf/index.ldif
@@ -0,0 +1,198 @@
+dn: cn=revokedby,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: revokedby
+
+dn: cn=issuedby,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: issuedby
+
+dn: cn=publicKeyData,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: publicKeyData
+
+dn: cn=clientId,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: clientId
+
+dn: cn=dataType,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: dataType
+
+dn: cn=status,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: status
+
+dn: cn=description,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: description
+
+dn: cn=serialno,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: serialno
+
+dn: cn=metaInfo,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: metaInfo
+
+dn: cn=certstatus,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: certstatus
+
+dn: cn=requestid,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: requestid
+
+dn: cn=requesttype,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: requesttype
+
+dn: cn=requeststate,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: requeststate
+
+dn: cn=requestowner,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: requestowner
+
+dn: cn=notbefore,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: notbefore
+
+dn: cn=notafter,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: notafter
+
+dn: cn=duration,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: duration
+
+dn: cn=dateOfCreate,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: dateOfCreate
+
+dn: cn=revokedOn,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: revokedOn
+
+dn: cn=archivedBy,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: archivedBy
+
+dn: cn=ownername,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsIndexType: sub
+nsSystemIndex: false
+cn: ownername
+
+dn: cn=subjectname,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsIndexType: sub
+nsSystemIndex: false
+cn: subjectname
+
+dn: cn=requestsourceid,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsIndexType: sub
+nsSystemIndex: false
+cn: requestsourceid
+
+dn: cn=revInfo,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsIndexType: sub
+nsSystemIndex: false
+cn: revInfo
+
+dn: cn=extension,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsIndexType: sub
+nsSystemIndex: false
+cn: extension
diff --git a/base/kra/shared/conf/jk2.manifest b/base/kra/shared/conf/jk2.manifest
new file mode 100644
index 000000000..986d7b874
--- /dev/null
+++ b/base/kra/shared/conf/jk2.manifest
@@ -0,0 +1,2 @@
+Main-Class: org.apache.jk.apr.TomcatStarter
+Class-Path: ../lib/tomcat.jar log4j.jar log4j-core.jar ../lib/common/log4j.jar ../lib/common/log4j-core.jar ../lib/common/classes ../lib/common/commons-logging.jar bootstrap.jar ../server/lib/commons-logging.jar ../server/lib/jmx.jar jmx.jar commons-logging-api.jar
diff --git a/base/kra/shared/conf/jk2.properties b/base/kra/shared/conf/jk2.properties
new file mode 100644
index 000000000..093bae802
--- /dev/null
+++ b/base/kra/shared/conf/jk2.properties
@@ -0,0 +1,26 @@
+## THIS FILE MAY BE OVERRIDEN AT RUNTIME. MAKE SURE TOMCAT IS STOPED
+## WHEN YOU EDIT THE FILE.
+
+## COMMENTS WILL BE _LOST_
+
+## DOCUMENTATION OF THE FORMAT IN JkMain javadoc.
+
+# Set the desired handler list
+# handler.list=apr,request,channelJni
+#
+# Override the default port for the socketChannel
+# channelSocket.port=8019
+# Default:
+# channelUnix.file=${jkHome}/work/jk2.socket
+# Just to check if the the config is working
+# shm.file=${jkHome}/work/jk2.shm
+
+# In order to enable jni use any channelJni directive
+# channelJni.disabled = 0
+# And one of the following directives:
+
+# apr.jniModeSo=/opt/apache2/modules/mod_jk2.so
+
+# If set to inprocess the mod_jk2 will Register natives itself
+# This will enable the starting of the Tomcat from mod_jk2
+# apr.jniModeSo=inprocess
diff --git a/base/kra/shared/conf/jkconf.ant.xml b/base/kra/shared/conf/jkconf.ant.xml
new file mode 100644
index 000000000..245cf98e2
--- /dev/null
+++ b/base/kra/shared/conf/jkconf.ant.xml
@@ -0,0 +1,51 @@
+<project name="jkconf" default="main" basedir=".">
+
+ <target name="init-3x" if="33.detect">
+ <taskdef name="jkconf"
+ classname="org.apache.jk.config.WebXml2Jk" >
+ <classpath>
+ <!-- 3.3 support -->
+ <pathelement location="/ws/jtc/jk/build/classes" />
+ <pathelement location="${tomcat.home}/lib/container/tomcat-jk2.jar" />
+ <pathelement location="${tomcat.home}/lib/container/crimson.jar"/>
+ <pathelement location="${tomcat.home}/lib/common/commons-logging.jar"/>
+ </classpath>
+ </taskdef>
+ </target>
+
+ <target name="init-4x" if="4x.detect" >
+ <path id="main.classpath">
+ <!-- 3.3 support -->
+ <fileset dir="${tomcat.home}/lib" includes="*.jar" />
+ <fileset dir="${tomcat.home}/server/lib" includes="*.jar" />
+ <fileset dir="${tomcat.home}/common/lib" includes="*.jar" />
+ </path>
+
+ <taskdef name="jkconf" classpathref="main.classpath"
+ classname="org.apache.jk.config.WebXml2Jk" />
+ </target>
+
+ <target name="detect" >
+ <property file="build.properties"/>
+ <property file="${user.home}/build.properties"/>
+ <property file="${user.home}/.build.properties"/>
+
+ <!-- default locations, overrident by properties.
+ This file must be installed in conf/ -->
+ <property name="tomcat.home" location=".." />
+
+ <available property="33.detect" file="${tomcat.home}/lib/container" />
+ <available property="4x.detect" file="${tomcat.home}/server/lib" />
+ </target>
+
+ <target name="init" depends="detect,init-3x,init-4x" />
+
+ <!-- ==================== Detection and reports ==================== -->
+
+
+ <target name="main" depends="init">
+ <jkconf docBase="${tomcat.home}/webapps/examples"
+ context="/examples" />
+ </target>
+
+</project>
diff --git a/base/kra/shared/conf/jkconfig.manifest b/base/kra/shared/conf/jkconfig.manifest
new file mode 100644
index 000000000..3ba1f2e3e
--- /dev/null
+++ b/base/kra/shared/conf/jkconfig.manifest
@@ -0,0 +1,2 @@
+Main-Class: org.apache.jk.config.WebXml2Jk
+Class-Path: tomcat-jk2.jar commons-logging.jar crimson.jar xercesImpl.jar xmlApis.jar tomcat-util.jar log4j.jar log4j-core.jar
diff --git a/base/kra/shared/conf/logging.properties b/base/kra/shared/conf/logging.properties
new file mode 100644
index 000000000..796cfc071
--- /dev/null
+++ b/base/kra/shared/conf/logging.properties
@@ -0,0 +1,70 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006-2010 Red Hat, Inc.
+# All rights reserved.
+# Modifications: configuration parameters
+# --- END COPYRIGHT BLOCK ---
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+handlers = 1catalina.org.apache.juli.FileHandler, 2localhost.org.apache.juli.FileHandler, 3manager.org.apache.juli.FileHandler, 4host-manager.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+
+.handlers = 1catalina.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+
+############################################################
+# Handler specific properties.
+# Describes specific configuration info for Handlers.
+############################################################
+
+1catalina.org.apache.juli.FileHandler.level = FINE
+1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+1catalina.org.apache.juli.FileHandler.prefix = catalina.
+
+2localhost.org.apache.juli.FileHandler.level = FINE
+2localhost.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+2localhost.org.apache.juli.FileHandler.prefix = localhost.
+
+3manager.org.apache.juli.FileHandler.level = FINE
+3manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+3manager.org.apache.juli.FileHandler.prefix = manager.
+
+4host-manager.org.apache.juli.FileHandler.level = FINE
+4host-manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+4host-manager.org.apache.juli.FileHandler.prefix = host-manager.
+
+java.util.logging.ConsoleHandler.level = FINE
+java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
+
+
+############################################################
+# Facility specific properties.
+# Provides extra control for each logger.
+############################################################
+
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler
+
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler
+
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler
+
+# For example, set the com.xyz.foo logger to only log SEVERE
+# messages:
+#org.apache.catalina.startup.ContextConfig.level = FINE
+#org.apache.catalina.startup.HostConfig.level = FINE
+#org.apache.catalina.session.ManagerBase.level = FINE
+#org.apache.catalina.core.AprLifecycleListener.level=FINE
diff --git a/base/kra/shared/conf/manager.ldif b/base/kra/shared/conf/manager.ldif
new file mode 100644
index 000000000..52e486987
--- /dev/null
+++ b/base/kra/shared/conf/manager.ldif
@@ -0,0 +1,48 @@
+# acis for cert manager
+
+dn: ou=csusers,cn=config
+objectClass: top
+objectClass: organizationalUnit
+ou: csusers
+
+dn: {rootSuffix}
+changetype: modify
+add: aci
+aci: (targetattr=*)(version 3.0; acl "cert manager access"; allow (all) userdn = "ldap:///{dbuser}";)
+
+dn: cn=ldbm database,cn=plugins,cn=config
+changetype: modify
+add: aci
+aci: (targetattr=*)(version 3.0; acl "Cert Manager access for VLV searches"; allow (read) userdn="ldap:///{dbuser}";)
+
+dn: cn=config
+changetype: modify
+add: aci
+aci: (targetattr != aci)(version 3.0; aci "cert manager read access"; allow (read, search, compare) userdn = "ldap:///{dbuser}";)
+
+dn: ou=csusers,cn=config
+changetype: modify
+add: aci
+aci: (targetattr != aci)(version 3.0; aci "cert manager manage replication users"; allow (all) userdn = "ldap:///{dbuser}";)
+
+dn: cn="{rootSuffix}",cn=mapping tree,cn=config
+changetype: modify
+add: aci
+aci: (targetattr=*)(version 3.0;acl "cert manager: Add Replication Agreements";allow (add) userdn = "ldap:///{dbuser}";)
+
+dn: cn="{rootSuffix}",cn=mapping tree,cn=config
+changetype: modify
+add: aci
+aci: (targetattr=*)(targetfilter="(|(objectclass=nsds5Replica)(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement)(objectClass=nsMappingTree))")(version 3.0; acl "cert manager: Modify Replication Agreements"; allow (read, write, search) userdn = "ldap:///{dbuser}";)
+
+dn: cn="{rootSuffix}",cn=mapping tree,cn=config
+changetype: modify
+add: aci
+aci: (targetattr=*)(targetfilter="(|(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement))")(version 3.0;acl "cert manager: Remove Replication Agreements";allow (delete) userdn = "ldap:///{dbuser}";)
+
+dn: cn=tasks,cn=config
+changetype: modify
+add: aci
+aci: (targetattr=*)(version 3.0; acl "cert manager: Run tasks after replica re-initialization"; allow (add) userdn = "ldap:///{dbuser}";)
+
+
diff --git a/base/kra/shared/conf/schema.ldif b/base/kra/shared/conf/schema.ldif
new file mode 100644
index 000000000..70578e21c
--- /dev/null
+++ b/base/kra/shared/conf/schema.ldif
@@ -0,0 +1,489 @@
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( usertype-oid NAME 'usertype' DESC 'Distinguish whether the user is administrator, agent or subsystem.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( userstate-oid NAME 'userstate' DESC 'Distinguish whether the user is administrator, agent or subsystem.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( cmsuser-oid NAME 'cmsuser' DESC 'CMS User' SUP top STRUCTURAL MUST usertype MAY userstate X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( archivedBy-oid NAME 'archivedBy' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( adminMessages-oid NAME 'adminMessages' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( algorithm-oid NAME 'algorithm' DESC 'CMS defined attribute'SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( algorithmId-oid NAME 'algorithmId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( signingAlgorithmId-oid NAME 'signingAlgorithmId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( autoRenew-oid NAME 'autoRenew' DESC 'CMS defined attribute'SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( certStatus-oid NAME 'certStatus' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( crlName-oid NAME 'crlName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( crlSize-oid NAME 'crlSize' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( deltaSize-oid NAME 'deltaSize' DESC 'CMS defined attribute'SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( crlNumber-oid NAME 'crlNumber' DESC 'CMS defined attribute'SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( deltaNumber-oid NAME 'deltaNumber' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( firstUnsaved-oid NAME 'firstUnsaved' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( crlCache-oid NAME 'crlCache' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( revokedCerts-oid NAME 'revokedCerts' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( unrevokedCerts-oid NAME 'unrevokedCerts' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( expiredCerts-oid NAME 'expiredCerts' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( crlExtensions-oid NAME 'crlExtensions' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dateOfArchival-oid NAME 'dateOfArchival' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dateOfRecovery-oid NAME 'dateOfRecovery' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dateOfRevocation-oid NAME 'dateOfRevocation' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dateOfCreate-oid NAME 'dateOfCreate' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dateOfModify-oid NAME 'dateOfModify' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( duration-oid NAME 'duration' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( extension-oid NAME 'extension' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( issuedBy-oid NAME 'issuedBy' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( issueInfo-oid NAME 'issueInfo' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( issuerName-oid NAME 'issuerName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( keySize-oid NAME 'keySize' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( clientId-oid NAME 'clientId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dataType-oid NAME 'dataType' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( status-oid NAME 'status' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( keyState-oid NAME 'keyState' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( metaInfo-oid NAME 'metaInfo' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( nextUpdate-oid NAME 'nextUpdate' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( notAfter-oid NAME 'notAfter' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( notBefore-oid NAME 'notBefore' DESC 'CMS defined attribute'SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( ownerName-oid NAME 'ownerName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( password-oid NAME 'password' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( p12Expiration-oid NAME 'p12Expiration' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( proofOfArchival-oid NAME 'proofOfArchival' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( publicKeyData-oid NAME 'publicKeyData' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( publicKeyFormat-oid NAME 'publicKeyFormat' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( privateKeyData-oid NAME 'privateKeyData' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestId-oid NAME 'requestId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestInfo-oid NAME 'requestInfo' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestState-oid NAME 'requestState' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestResult-oid NAME 'requestResult' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestOwner-oid NAME 'requestOwner' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestAgentGroup-oid NAME 'requestAgentGroup' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestSourceId-oid NAME 'requestSourceId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestType-oid NAME 'requestType' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestFlag-oid NAME 'requestFlag' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestError-oid NAME 'requestError' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( resourceACLS-oid NAME 'resourceACLS' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( revInfo-oid NAME 'revInfo' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( revokedBy-oid NAME 'revokedBy' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( revokedOn-oid NAME 'revokedOn' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( serialno-oid NAME 'serialno' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( nextRange-oid NAME 'nextRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( publishingStatus-oid NAME 'publishingStatus' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( beginRange-oid NAME 'beginRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( endRange-oid NAME 'endRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( subjectName-oid NAME 'subjectName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( sessionContext-oid NAME 'sessionContext' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( thisUpdate-oid NAME 'thisUpdate' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( transId-oid NAME 'transId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( transStatus-oid NAME 'transStatus' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( transName-oid NAME 'transName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( transOps-oid NAME 'transOps' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( userDN-oid NAME 'userDN' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( userMessages-oid NAME 'userMessages' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( version-oid NAME 'version' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( Clone-oid NAME 'Clone' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( DomainManager-oid NAME 'DomainManager' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SecurePort-oid NAME 'SecurePort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SecureAgentPort-oid NAME 'SecureAgentPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SecureAdminPort-oid NAME 'SecureAdminPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SecureEEClientAuthPort-oid NAME 'SecureEEClientAuthPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( UnSecurePort-oid NAME 'UnSecurePort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SubsystemName-oid NAME 'SubsystemName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( cmsUserGroup-oid NAME 'cmsUserGroup' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( CertACLS-oid NAME 'CertACLS' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY resourceACLS X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( repository-oid NAME 'repository' DESC 'CMS defined class' SUP top STRUCTURAL MUST ou MAY ( serialno $ description $ nextRange $ publishingStatus ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( request-oid NAME 'request' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( requestId $ dateOfCreate $ dateOfModify $ requestState $ requestResult $ requestOwner $ requestAgentGroup $ requestSourceId $ requestType $ requestFlag $ requestError $ userMessages $ adminMessages ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( transaction-oid NAME 'transaction' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( transId $ description $ transName $ transStatus $ transOps ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( crlIssuingPointRecord-oid NAME 'crlIssuingPointRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( dateOfCreate $ dateOfModify $ crlNumber $ crlSize $ thisUpdate $ nextUpdate $ deltaNumber $ deltaSize $ firstUnsaved $ certificateRevocationList $ deltaRevocationList $ crlCache $ revokedCerts $ unrevokedCerts $ expiredCerts $ cACertificate ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( certificateRecord-oid NAME 'certificateRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( serialno $ dateOfCreate $ dateOfModify $ certStatus $ autoRenew $ issueInfo $ metaInfo $ revInfo $ version $ duration $ notAfter $ notBefore $ algorithmId $ subjectName $ signingAlgorithmId $ userCertificate $ issuedBy $ revokedBy $ revokedOn $ extension $ publicKeyData $ issuerName ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( userDetails-oid NAME 'userDetails' DESC 'CMS defined class' SUP top STRUCTURAL MUST userDN MAY ( dateOfCreate $ dateOfModify $ password $ p12Expiration ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( keyRecord-oid NAME 'keyRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( serialno $ dateOfCreate $ dateOfModify $ keyState $ privateKeyData $ ownerName $ keySize $ metaInfo $ dateOfArchival $ dateOfRecovery $ algorithm $ publicKeyFormat $ publicKeyData $ archivedBy $ clientId $ dataType $ status ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( pkiSecurityDomain-oid NAME 'pkiSecurityDomain' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( ou $ name ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( pkiSecurityGroup-oid NAME 'pkiSecurityGroup' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( pkiSubsystem-oid NAME 'pkiSubsystem' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ Host $ SecurePort $ SubsystemName $ Clone ) MAY ( DomainManager $ SecureAgentPort $ SecureAdminPort $SecureEEClientAuthPort $ UnSecurePort ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( pkiRange-oid NAME 'pkiRange' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ beginRange $ endRange $ Host $ SecurePort ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( securityDomainSessionEntry-oid NAME 'securityDomainSessionEntry' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ host $ uid $ cmsUserGroup $ dateOfCreate ) X-ORIGIN 'user defined' )
diff --git a/base/kra/shared/conf/server-minimal.xml b/base/kra/shared/conf/server-minimal.xml
new file mode 100644
index 000000000..7b542b6cf
--- /dev/null
+++ b/base/kra/shared/conf/server-minimal.xml
@@ -0,0 +1,25 @@
+<Server port="8005" shutdown="SHUTDOWN">
+
+ <GlobalNamingResources>
+ <!-- Used by Manager webapp -->
+ <Resource name="UserDatabase" auth="Container"
+ type="org.apache.catalina.UserDatabase"
+ description="User database that can be updated and saved"
+ factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
+ pathname="conf/tomcat-users.xml" />
+ </GlobalNamingResources>
+
+ <Service name="Catalina">
+ <Connector port="8080" />
+
+ <!-- This is here for compatibility only, not required -->
+ <Connector port="8009" protocol="AJP/1.3" />
+
+ <Engine name="Catalina" defaultHost="localhost">
+ <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+ resourceName="UserDatabase" />
+ <Host name="localhost" appBase="webapps" />
+ </Engine>
+
+ </Service>
+</Server>
diff --git a/base/kra/shared/conf/server.xml b/base/kra/shared/conf/server.xml
new file mode 100644
index 000000000..58121d448
--- /dev/null
+++ b/base/kra/shared/conf/server.xml
@@ -0,0 +1,308 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2006-2010 Red Hat, Inc.
+ All rights reserved.
+ Modifications: configuration parameters
+ END COPYRIGHT BLOCK -->
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- Note: A "Server" is not itself a "Container", so you may not
+ define subcomponents such as "Valves" at this level.
+ Documentation at /docs/config/server.html
+ -->
+
+<!-- DO NOT REMOVE - Begin PKI Status Definitions -->
+<!--
+Unsecure Port = http://[PKI_MACHINE_NAME]:[PKI_UNSECURE_PORT]/[PKI_SUBSYSTEM_TYPE]/ee/[PKI_SUBSYSTEM_TYPE]
+Secure Agent Port = https://[PKI_MACHINE_NAME]:[PKI_AGENT_SECURE_PORT]/[PKI_SUBSYSTEM_TYPE]/agent/[PKI_SUBSYSTEM_TYPE]
+Secure EE Port = https://[PKI_MACHINE_NAME]:[PKI_EE_SECURE_PORT]/[PKI_SUBSYSTEM_TYPE]/ee/[PKI_SUBSYSTEM_TYPE]
+Secure Admin Port = https://[PKI_MACHINE_NAME]:[PKI_ADMIN_SECURE_PORT]/[PKI_SUBSYSTEM_TYPE]/services
+PKI Console Port = pkiconsole https://[PKI_MACHINE_NAME]:[PKI_ADMIN_SECURE_PORT]/[PKI_SUBSYSTEM_TYPE]
+Tomcat Port = [TOMCAT_SERVER_PORT] (for shutdown)
+-->
+<!-- DO NOT REMOVE - End PKI Status Definitions -->
+
+<Server port="[TOMCAT_SERVER_PORT]" shutdown="SHUTDOWN">
+
+ <!--APR library loader. Documentation at /docs/apr.html -->
+ <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
+ <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
+ <Listener className="org.apache.catalina.core.JasperListener" />
+ <!-- JMX Support for the Tomcat server. Documentation at /docs/non-existent.html -->
+ <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
+ <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
+
+ <!-- Global JNDI resources
+ Documentation at /docs/jndi-resources-howto.html
+ -->
+ <GlobalNamingResources>
+ <!-- Editable user database that can also be used by
+ UserDatabaseRealm to authenticate users
+ -->
+ <Resource name="UserDatabase" auth="Container"
+ type="org.apache.catalina.UserDatabase"
+ description="User database that can be updated and saved"
+ factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
+ pathname="conf/tomcat-users.xml" />
+ </GlobalNamingResources>
+
+ <!-- A "Service" is a collection of one or more "Connectors" that share
+ a single "Container" Note: A "Service" is not itself a "Container",
+ so you may not define subcomponents such as "Valves" at this level.
+ Documentation at /docs/config/service.html
+ -->
+ <Service name="Catalina">
+
+ <!--The connectors can use a shared executor, you can define one or more named thread pools-->
+ <!--
+ <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
+ maxThreads="150" minSpareThreads="4"/>
+ -->
+
+
+ <!-- A "Connector" represents an endpoint by which requests are received
+ and responses are returned. Documentation at :
+ Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
+ Java AJP Connector: /docs/config/ajp.html
+ APR (HTTP/AJP) Connector: /docs/apr.html
+ Define a non-SSL HTTP/1.1 Connector on port 8080
+ -->
+
+ [PKI_UNSECURE_PORT_SERVER_COMMENT]
+ <Connector name="[PKI_UNSECURE_PORT_CONNECTOR_NAME]" port="[PKI_UNSECURE_PORT]" protocol="HTTP/1.1" redirectPort="8443"
+ maxHttpHeaderSize="8192"
+ acceptCount="100" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+ enableLookups="false" connectionTimeout="20000" disableUploadTimeout="true"
+ />
+
+ <!-- Define a SSL HTTP/1.1 Connector on port 8443 -->
+ [PKI_SECURE_PORT_SERVER_COMMENT]
+ <!-- DO NOT REMOVE - Begin define PKI secure port
+ NOTE: The OCSP settings take effect globally, so it should only be set once.
+
+ In setup where SSL clientAuth="true", OCSP can be turned on by
+ setting enableOCSP to true like the following:
+ enableOCSP="true"
+ along with changes to related settings, especially:
+ ocspResponderURL=<see example in connector definition below>
+ ocspResponderCertNickname=<see example in connector definition below>
+ Here are the definition to all the OCSP-related settings:
+ enableOCSP - turns on/off the ocsp check
+ ocspResponderURL - sets the url where the ocsp requests are sent
+ ocspResponderCertNickname - sets the nickname of the cert that is
+ either CA's signing certificate or the OCSP server's signing
+ certificate.
+ The CA's signing certificate should already be in the db, in
+ case of the same security domain.
+ In case of an ocsp signing certificate, one must import the cert
+ into the subsystem's nss db and set trust. e.g.:
+ certutil -d . -A -n "ocspSigningCert cert-pki-ca" -t "C,," -a -i ocspCert.b64
+ ocspCacheSize - sets max cache entries
+ ocspMinCacheEntryDuration - sets minimum seconds to next fetch attempt
+ ocspMaxCacheEntryDuration - sets maximum seconds to next fetch attempt
+ ocspTimeout -sets OCSP timeout in seconds
+ -->
+ <Connector name="[PKI_SECURE_PORT_CONNECTOR_NAME]" port="[PKI_SECURE_PORT]" protocol="HTTP/1.1" SSLEnabled="true" sslProtocol="SSL" scheme="https" secure="true"
+ maxHttpHeaderSize="8192"
+ acceptCount="100" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+ enableLookups="false" disableUploadTimeout="true"
+ SSLImplementation="org.apache.tomcat.util.net.jss.JSSImplementation"
+ enableOCSP="false"
+ ocspResponderURL="http://[PKI_MACHINE_NAME]:9080/ca/ocsp"
+ ocspResponderCertNickname="ocspSigningCert cert-pki-ca"
+ ocspCacheSize="1000"
+ ocspMinCacheEntryDuration="60"
+ ocspMaxCacheEntryDuration="120"
+ ocspTimeout="10"
+ strictCiphers="false"
+ clientAuth="[PKI_AGENT_CLIENTAUTH]"
+ sslOptions="[TOMCAT_SSL_OPTIONS]"
+ ssl2Ciphers="[TOMCAT_SSL2_CIPHERS]"
+ ssl3Ciphers="[TOMCAT_SSL3_CIPHERS]"
+ tlsCiphers="[TOMCAT_TLS_CIPHERS]"
+ serverCertNickFile="[PKI_INSTANCE_PATH]/conf/serverCertNick.conf"
+ passwordFile="[PKI_INSTANCE_PATH]/conf/password.conf"
+ passwordClass="org.apache.tomcat.util.net.jss.PlainPasswordFile"
+ certdbDir="[PKI_INSTANCE_PATH]/alias"
+ />
+ <!-- DO NOT REMOVE - End define PKI secure port -->
+
+ [PKI_OPEN_SEPARATE_PORTS_SERVER_COMMENT][PKI_ADMIN_SECURE_PORT_SERVER_COMMENT]
+ <Connector name="[PKI_ADMIN_SECURE_PORT_CONNECTOR_NAME]" port="[PKI_ADMIN_SECURE_PORT]" SSLEnabled="true" sslProtocol="SSL" scheme="https" secure="true"
+ maxHttpHeaderSize="8192"
+ acceptCount="100" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+ enableLookups="false" disableUploadTimeout="true"
+ SSLImplementation="org.apache.tomcat.util.net.jss.JSSImplementation"
+ strictCiphers="false"
+ clientAuth="false"
+ sslOptions="[TOMCAT_SSL_OPTIONS]"
+ ssl2Ciphers="[TOMCAT_SSL2_CIPHERS]"
+ ssl3Ciphers="[TOMCAT_SSL3_CIPHERS]"
+ tlsCiphers="[TOMCAT_TLS_CIPHERS]"
+ serverCertNickFile="[PKI_INSTANCE_PATH]/conf/serverCertNick.conf"
+ passwordFile="[PKI_INSTANCE_PATH]/conf/password.conf"
+ passwordClass="org.apache.tomcat.util.net.jss.PlainPasswordFile"
+ certdbDir="[PKI_INSTANCE_PATH]/alias"/>
+ [PKI_CLOSE_SEPARATE_PORTS_SERVER_COMMENT]
+
+ [PKI_OPEN_SEPARATE_PORTS_SERVER_COMMENT][PKI_EE_SECURE_PORT_SERVER_COMMENT]
+ <Connector name="[PKI_EE_SECURE_PORT_CONNECTOR_NAME]" port="[PKI_EE_SECURE_PORT]" SSLEnabled="true" sslProtocol="SSL" scheme="https" secure="true"
+ maxHttpHeaderSize="8192"
+ acceptCount="100" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+ enableLookups="false" disableUploadTimeout="true"
+ SSLImplementation="org.apache.tomcat.util.net.jss.JSSImplementation"
+ strictCiphers="false"
+ clientAuth="false"
+ sslOptions="[TOMCAT_SSL_OPTIONS]"
+ ssl2Ciphers="[TOMCAT_SSL2_CIPHERS]"
+ ssl3Ciphers="[TOMCAT_SSL3_CIPHERS]"
+ tlsCiphers="[TOMCAT_TLS_CIPHERS]"
+ serverCertNickFile="[PKI_INSTANCE_PATH]/conf/serverCertNick.conf"
+ passwordFile="[PKI_INSTANCE_PATH]/conf/password.conf"
+ passwordClass="org.apache.tomcat.util.net.jss.PlainPasswordFile"
+ certdbDir="[PKI_INSTANCE_PATH]/alias"/>
+ [PKI_CLOSE_SEPARATE_PORTS_SERVER_COMMENT]
+
+ <!-- A "Connector" using the shared thread pool-->
+ <!--
+ <Connector executor="tomcatThreadPool"
+ port="8080" protocol="HTTP/1.1"
+ connectionTimeout="20000"
+ redirectPort="8443" />
+ -->
+ <!-- Define a SSL HTTP/1.1 Connector on port 8443
+ This connector uses the JSSE configuration, when using APR, the
+ connector should be using the OpenSSL style configuration
+ described in the APR documentation -->
+ <!--
+ <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
+ maxThreads="150" scheme="https" secure="true"
+ clientAuth="false" sslProtocol="TLS" />
+ -->
+
+ <!-- Define an AJP 1.3 Connector on port [PKI_AJP_PORT] -->
+[PKI_OPEN_AJP_PORT_COMMENT]
+ <Connector port="[PKI_AJP_PORT]" protocol="AJP/1.3" redirectPort="PKI_AJP_REDIRECT_PORT]" />
+[PKI_CLOSE_AJP_PORT_COMMENT]
+
+
+ <!-- An Engine represents the entry point (within Catalina) that processes
+ every request. The Engine implementation for Tomcat stand alone
+ analyzes the HTTP headers included with the request, and passes them
+ on to the appropriate Host (virtual host).
+ Documentation at /docs/config/engine.html -->
+
+ <!-- You should set jvmRoute to support load-balancing via AJP ie :
+ <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
+ -->
+ <Engine name="Catalina" defaultHost="localhost">
+
+ <!--For clustering, please take a look at documentation at:
+ /docs/cluster-howto.html (simple how to)
+ /docs/config/cluster.html (reference documentation) -->
+ <!--
+ <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
+ -->
+
+ <!-- The request dumper valve dumps useful debugging information about
+ the request and response data received and sent by Tomcat.
+ Documentation at: /docs/config/valve.html -->
+ <!--
+ <Valve className="org.apache.catalina.valves.RequestDumperValve"/>
+ -->
+
+ <!-- This Realm uses the UserDatabase configured in the global JNDI
+ resources under the key "UserDatabase". Any edits
+ that are performed against this UserDatabase are immediately
+ available for use by the Realm. -->
+
+ <!--
+ <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+ resourceName="UserDatabase"/>
+ -->
+
+ <!-- Custom PKIJNDI realm
+
+ Example:
+
+ <Realm className="com.netscape.cmscore.realm.PKIJNDIRealm" : classpath to realm
+ connectionURL="ldap://localhost:389" : standard JNDI connection URL
+ userBase="ou=people,dc=localhost-pki-kra" : standard JNDI userBase property
+ userSearch="(description={0})" : Attribute to search for user of incoming client auth certificate
+ : Use userSearch="(UID={0})" if wanting to search isolate user based on UID
+ : Also set the following: certUIDLabel="UID" or whatever the field containing
+ : the user's UID happens to be. This will cause the incoming's cert dn to be
+ : be searched for <certUIDLabel>=<uid value>
+
+ certAttrName="userCertificate" : Attribute containing user's client auth certificate
+ roleBase="ou=groups,dc=localhost-pki-kra" : Standard JNDI search base for roles or groups
+ roleName="cn" : Standard attribute name containg roles or groups
+ roleSubtree="true" : Standard JNDI roleSubtree property
+ roleSearch="(uniqueMember={0})" : How to search for a user in a specific role or group
+ connectionName="cn=Directory Manager" : Connection name, needs elevated privileges
+ connectionPassword="secret123" : Password for elevated user
+ aclBase ="cn=aclResources,dc=localhost-pki-kra" : Custom base location of PKI ACL's in directory
+ aclAttrName="resourceACLS" : Name of attribute containing PKI ACL's
+ />
+
+ Uncomment and customize below to activate Realm.
+ Also umcomment Security Constraints and login config values
+ in WEB-INF/web.xml as well.
+ -->
+
+ <!--
+ <Realm className="com.netscape.cmscore.realm.PKIJNDIRealm"
+ connectionURL="ldap://localhost:389"
+ userBase="ou=people,dc=localhost-pki-kra"
+ userSearch="(description={0})"
+ certAttrName="userCertificate"
+ roleBase="ou=groups,dc=localhost-pki-kra"
+ roleName="cn"
+ roleSubtree="true"
+ roleSearch="(uniqueMember={0})"
+ connectionName="cn=Directory Manager"
+ connectionPassword="netscape"
+ aclBase ="cn=aclResources,dc=localhost-pki-kra"
+ aclAttrName="resourceACLS"
+ />
+
+ -->
+
+ <!-- Define the default virtual host
+ Note: XML Schema validation will not work with Xerces 2.2.
+ -->
+ <Host name="localhost" appBase="webapps"
+ unpackWARs="true" autoDeploy="false"
+ xmlValidation="false" xmlNamespaceAware="false">
+
+ <!-- SingleSignOn valve, share authentication between web applications
+ Documentation at: /docs/config/valve.html -->
+ <!--
+ <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
+ -->
+
+ <!-- Access log processes all example.
+ Documentation at: /docs/config/valve.html -->
+ <!--
+ <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
+ prefix="localhost_access_log." suffix=".txt" pattern="common" resolveHosts="false"/>
+ -->
+
+ </Host>
+ </Engine>
+ </Service>
+</Server>
diff --git a/base/kra/shared/conf/serverCert.profile b/base/kra/shared/conf/serverCert.profile
new file mode 100644
index 000000000..adf6ee4ad
--- /dev/null
+++ b/base/kra/shared/conf/serverCert.profile
@@ -0,0 +1,37 @@
+#
+# Server Certificate
+#
+id=serverCert.profile
+name=All Purpose SSL server cert Profile
+description=This profile creates an SSL server certificate that is valid for SSL servers
+list=2,4,5,6,7
+2.default.class=com.netscape.cms.profile.def.ValidityDefault
+2.default.name=Validity Default
+2.default.params.range=720
+2.default.params.startTime=0
+4.default.class=com.netscape.cms.profile.def.AuthorityKeyIdentifierExtDefault
+4.default.name=Authority Key Identifier Default
+5.default.class=com.netscape.cms.profile.def.AuthInfoAccessExtDefault
+5.default.name=AIA Extension Default
+5.default.params.authInfoAccessADEnable_0=true
+5.default.params.authInfoAccessADLocationType_0=URIName
+5.default.params.authInfoAccessADLocation_0=
+5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+5.default.params.authInfoAccessCritical=false
+5.default.params.authInfoAccessNumADs=1
+6.default.class=com.netscape.cms.profile.def.KeyUsageExtDefault
+6.default.name=Key Usage Default
+6.default.params.keyUsageCritical=true
+6.default.params.keyUsageDigitalSignature=true
+6.default.params.keyUsageNonRepudiation=true
+6.default.params.keyUsageDataEncipherment=true
+6.default.params.keyUsageKeyEncipherment=true
+6.default.params.keyUsageKeyAgreement=false
+6.default.params.keyUsageKeyCertSign=false
+6.default.params.keyUsageCrlSign=false
+6.default.params.keyUsageEncipherOnly=false
+6.default.params.keyUsageDecipherOnly=false
+7.default.class=com.netscape.cms.profile.def.ExtendedKeyUsageExtDefault
+7.default.name=Extended Key Usage Extension Default
+7.default.params.exKeyUsageCritical=false
+7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.1
diff --git a/base/kra/shared/conf/serverCertNick.conf b/base/kra/shared/conf/serverCertNick.conf
new file mode 100644
index 000000000..1b1f4fcad
--- /dev/null
+++ b/base/kra/shared/conf/serverCertNick.conf
@@ -0,0 +1 @@
+Server-Cert cert-[PKI_INSTANCE_ID]
diff --git a/base/kra/shared/conf/shm.manifest b/base/kra/shared/conf/shm.manifest
new file mode 100644
index 000000000..0505c085b
--- /dev/null
+++ b/base/kra/shared/conf/shm.manifest
@@ -0,0 +1,2 @@
+Main-Class: org.apache.jk.common.Shm
+Class-Path: tomcat-jk2.jar commons-logging.jar tomcat-util.jar log4j.jar log4j-core.jar
diff --git a/base/kra/shared/conf/storageCert.profile b/base/kra/shared/conf/storageCert.profile
new file mode 100644
index 000000000..fe46c19c1
--- /dev/null
+++ b/base/kra/shared/conf/storageCert.profile
@@ -0,0 +1,37 @@
+#
+# DRM Storage Certificate
+#
+id=storageCert.profile
+name=DRM Key Storage Cert profile
+description=This profile creates a certificate that is good for DRM to encrypt private key materials in storage
+list=2,4,5,6,7
+2.default.class=com.netscape.cms.profile.def.ValidityDefault
+2.default.name=Validity Default
+2.default.params.range=720
+2.default.params.startTime=0
+4.default.class=com.netscape.cms.profile.def.AuthorityKeyIdentifierExtDefault
+4.default.name=Authority Key Identifier Default
+5.default.class=com.netscape.cms.profile.def.AuthInfoAccessExtDefault
+5.default.name=AIA Extension Default
+5.default.params.authInfoAccessADEnable_0=true
+5.default.params.authInfoAccessADLocationType_0=URIName
+5.default.params.authInfoAccessADLocation_0=
+5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+5.default.params.authInfoAccessCritical=false
+5.default.params.authInfoAccessNumADs=1
+6.default.class=com.netscape.cms.profile.def.KeyUsageExtDefault
+6.default.name=Key Usage Default
+6.default.params.keyUsageCritical=true
+6.default.params.keyUsageDigitalSignature=true
+6.default.params.keyUsageNonRepudiation=true
+6.default.params.keyUsageDataEncipherment=true
+6.default.params.keyUsageKeyEncipherment=true
+6.default.params.keyUsageKeyAgreement=false
+6.default.params.keyUsageKeyCertSign=false
+6.default.params.keyUsageCrlSign=false
+6.default.params.keyUsageEncipherOnly=false
+6.default.params.keyUsageDecipherOnly=false
+7.default.class=com.netscape.cms.profile.def.ExtendedKeyUsageExtDefault
+7.default.name=Extended Key Usage Extension Default
+7.default.params.exKeyUsageCritical=false
+7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2
diff --git a/base/kra/shared/conf/subsystemCert.profile b/base/kra/shared/conf/subsystemCert.profile
new file mode 100644
index 000000000..1fc1a6f71
--- /dev/null
+++ b/base/kra/shared/conf/subsystemCert.profile
@@ -0,0 +1,37 @@
+#
+# Subsystem Certificate
+#
+id=subsystemCert.profile
+name=subsystem cert Profile
+description=This profile creates a subsystem certificate that is valid for a CS subsystem
+list=2,4,5,6,7
+2.default.class=com.netscape.cms.profile.def.ValidityDefault
+2.default.name=Validity Default
+2.default.params.range=720
+2.default.params.startTime=0
+4.default.class=com.netscape.cms.profile.def.AuthorityKeyIdentifierExtDefault
+4.default.name=Authority Key Identifier Default
+5.default.class=com.netscape.cms.profile.def.AuthInfoAccessExtDefault
+5.default.name=AIA Extension Default
+5.default.params.authInfoAccessADEnable_0=true
+5.default.params.authInfoAccessADLocationType_0=URIName
+5.default.params.authInfoAccessADLocation_0=
+5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+5.default.params.authInfoAccessCritical=false
+5.default.params.authInfoAccessNumADs=1
+6.default.class=com.netscape.cms.profile.def.KeyUsageExtDefault
+6.default.name=Key Usage Default
+6.default.params.keyUsageCritical=true
+6.default.params.keyUsageDigitalSignature=true
+6.default.params.keyUsageNonRepudiation=true
+6.default.params.keyUsageDataEncipherment=true
+6.default.params.keyUsageKeyEncipherment=true
+6.default.params.keyUsageKeyAgreement=false
+6.default.params.keyUsageKeyCertSign=false
+6.default.params.keyUsageCrlSign=false
+6.default.params.keyUsageEncipherOnly=false
+6.default.params.keyUsageDecipherOnly=false
+7.default.class=com.netscape.cms.profile.def.ExtendedKeyUsageExtDefault
+7.default.name=Extended Key Usage Extension Default
+7.default.params.exKeyUsageCritical=false
+7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2
diff --git a/base/kra/shared/conf/tomcat-jk2.manifest b/base/kra/shared/conf/tomcat-jk2.manifest
new file mode 100644
index 000000000..acfef4a90
--- /dev/null
+++ b/base/kra/shared/conf/tomcat-jk2.manifest
@@ -0,0 +1,7 @@
+Manifest-version: 1.0
+Extension-Name: org.apache.jk
+Specification-Vendor: Apache Software Foundation
+Specification-Version: 2.0
+Implementation-Vendor-Id: org.apache
+Implementation-Vendor: Apache Software Foundation
+Implementation-Version: 2.1
diff --git a/base/kra/shared/conf/tomcat-users.xml b/base/kra/shared/conf/tomcat-users.xml
new file mode 100644
index 000000000..daa9260cc
--- /dev/null
+++ b/base/kra/shared/conf/tomcat-users.xml
@@ -0,0 +1,45 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2006-2010 Red Hat, Inc.
+ All rights reserved.
+ Modifications: configuration parameters
+ END COPYRIGHT BLOCK -->
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+ <role rolename="tomcat"/>
+ <role rolename="role1"/>
+ <user username="tomcat" password="tomcat" roles="tomcat"/>
+ <user username="both" password="tomcat" roles="tomcat,role1"/>
+ <user username="role1" password="tomcat" roles="role1"/>
+-->
+
+<!-- The host manager webapp is restricted to users with role "admin" -->
+<!--<user name="tomcat" password="password" roles="admin" />-->
+<!-- The manager webapp is restricted to users with role "manager" -->
+<!--<user name="tomcat" password="password" roles="manager" />-->
+<tomcat-users>
+ <role rolename="pkiuser"/>
+ <role rolename="tomcat"/>
+ <role rolename="manager"/>
+ <role rolename="admin"/>
+
+ <user username="pkiuser" password="pkiuser" roles="pkiuser"/>
+ <user username="tomcat" password="tomcat" roles="tomcat"/>
+ <user username="admin" password="netscape" roles="admin,manager"/>
+</tomcat-users>
diff --git a/base/kra/shared/conf/tomcat6.conf b/base/kra/shared/conf/tomcat6.conf
new file mode 100644
index 000000000..2d7def5ec
--- /dev/null
+++ b/base/kra/shared/conf/tomcat6.conf
@@ -0,0 +1,58 @@
+# Service-specific configuration file for tomcat6. This will be sourced by
+# the SysV init script after the global configuration file
+# /etc/tomcat6/tomcat6.conf, thus allowing values to be overridden in
+# a per-service manner.
+#
+# NEVER change the init script itself. To change values for all services make
+# your changes in /etc/tomcat6/tomcat6.conf
+#
+# To change values for a specific service make your edits here.
+# To create a new service create a link from /etc/init.d/<your new service> to
+# /etc/init.d/tomcat6 (do not copy the init script) and make a copy of the
+# /etc/sysconfig/tomcat6 file to /etc/sysconfig/<your new service> and change
+# the property values so the two services won't conflict. Register the new
+# service in the system as usual (see chkconfig and similars).
+#
+
+# Where your java installation lives
+#JAVA_HOME="/usr/lib/jvm/java"
+
+# Where your tomcat installation lives
+CATALINA_BASE="[PKI_INSTANCE_PATH]"
+#CATALINA_HOME="/usr/share/tomcat6"
+#JASPER_HOME="/usr/share/tomcat6"
+#CATALINA_TMPDIR="/var/cache/tomcat6/temp"
+
+# You can pass some parameters to java here if you wish to
+#JAVA_OPTS="-Xminf0.1 -Xmaxf0.3"
+
+# Use JAVA_OPTS to set java.library.path for libtcnative.so
+#JAVA_OPTS="-Djava.library.path=/usr/lib64"
+
+# What user should run tomcat
+TOMCAT_USER="[PKI_USER]"
+
+# You can change your tomcat locale here
+#LANG="en_US"
+
+# Run tomcat under the Java Security Manager
+#SECURITY_MANAGER="false"
+
+# Time to wait in seconds, before killing process
+#SHUTDOWN_WAIT="30"
+
+# Whether to annoy the user with "attempting to shut down" messages or not
+#SHUTDOWN_VERBOSE="false"
+
+# Set the TOMCAT_PID location
+CATALINA_PID="[TOMCAT_PIDFILE]"
+
+# Set the tomcat log file
+TOMCAT_LOG="[TOMCAT_LOG_DIR]/tomcat-initd.log"
+
+# Connector port is 8080 for this tomcat6 instance
+#CONNECTOR_PORT="8080"
+
+# If you wish to further customize your tomcat environment,
+# put your own definitions here
+# (i.e. LD_LIBRARY_PATH for some jdbc drivers)
diff --git a/base/kra/shared/conf/transportCert.profile b/base/kra/shared/conf/transportCert.profile
new file mode 100644
index 000000000..aba748bfe
--- /dev/null
+++ b/base/kra/shared/conf/transportCert.profile
@@ -0,0 +1,37 @@
+#
+# DRM Transport Certificate
+#
+id=transportCert.profile
+name=DRM Key Transport Cert profile
+description=This profile creates a certificate that is good for transporting private key materials
+list=2,4,5,6,7
+2.default.class=com.netscape.cms.profile.def.ValidityDefault
+2.default.name=Validity Default
+2.default.params.range=720
+2.default.params.startTime=0
+4.default.class=com.netscape.cms.profile.def.AuthorityKeyIdentifierExtDefault
+4.default.name=Authority Key Identifier Default
+5.default.class=com.netscape.cms.profile.def.AuthInfoAccessExtDefault
+5.default.name=AIA Extension Default
+5.default.params.authInfoAccessADEnable_0=true
+5.default.params.authInfoAccessADLocationType_0=URIName
+5.default.params.authInfoAccessADLocation_0=
+5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+5.default.params.authInfoAccessCritical=false
+5.default.params.authInfoAccessNumADs=1
+6.default.class=com.netscape.cms.profile.def.KeyUsageExtDefault
+6.default.name=Key Usage Default
+6.default.params.keyUsageCritical=true
+6.default.params.keyUsageDigitalSignature=true
+6.default.params.keyUsageNonRepudiation=true
+6.default.params.keyUsageDataEncipherment=true
+6.default.params.keyUsageKeyEncipherment=true
+6.default.params.keyUsageKeyAgreement=false
+6.default.params.keyUsageKeyCertSign=false
+6.default.params.keyUsageCrlSign=false
+6.default.params.keyUsageEncipherOnly=false
+6.default.params.keyUsageDecipherOnly=false
+7.default.class=com.netscape.cms.profile.def.ExtendedKeyUsageExtDefault
+7.default.name=Extended Key Usage Extension Default
+7.default.params.exKeyUsageCritical=false
+7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2
diff --git a/base/kra/shared/conf/uriworkermap.properties b/base/kra/shared/conf/uriworkermap.properties
new file mode 100644
index 000000000..c65445b10
--- /dev/null
+++ b/base/kra/shared/conf/uriworkermap.properties
@@ -0,0 +1,13 @@
+# uriworkermap.properties - IIS
+#
+# This file provides sample mappings for example ajp13w
+# worker defined in workermap.properties.minimal
+# The general sytax for this file is:
+# [URL]=[Worker name]
+
+/servlet-examples/*=ajp13w
+
+# Optionally filter out all .jpeg files inside that context
+# For no mapping the url has to start with exclamation (!)
+
+!/servlet-examples/*.jpeg=ajp13w
diff --git a/base/kra/shared/conf/vlv.ldif b/base/kra/shared/conf/vlv.ldif
new file mode 100644
index 000000000..b619e8657
--- /dev/null
+++ b/base/kra/shared/conf/vlv.ldif
@@ -0,0 +1,207 @@
+dn: cn=allKeys-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: allKeys-{instanceId}
+vlvBase: ou=keyRepository,ou=kra,{rootSuffix}
+vlvScope: 1
+vlvFilter: (&(&(objectClass=top)(objectClass=keyRecord))(serialno=*))
+
+dn: cn=kraAll-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: kraAll-{instanceId}
+vlvBase: ou=kra,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (requeststate=*)
+
+dn: cn=kraArchival-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: kraArchival-{instanceId}
+vlvBase: ou=kra,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (requesttype=enrollment)
+
+dn: cn=kraRecovery-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: kraRecovery-{instanceId}
+vlvBase: ou=kra,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (requesttype=recovery)
+
+dn: cn=kraCanceled-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: kraCanceled-{instanceId}
+vlvBase: ou=kra,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (requeststate=canceled)
+
+dn: cn=kraCanceledEnrollment-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: kraCanceledEnrollment-{instanceId}
+vlvBase: ou=kra,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (&(requeststate=canceled)(requesttype=enrollment))
+
+dn: cn=kraCanceledRecovery-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: kraCanceledRecovery-{instanceId}
+vlvBase: ou=kra,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (&(requeststate=canceled)(requesttype=recovery))
+
+dn: cn=kraRejected-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: kraRejected-{instanceId}
+vlvBase: ou=kra,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (requeststate=rejected)
+
+dn: cn=kraRejectedEnrollment-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: kraRejectedEnrollment-{instanceId}
+vlvBase: ou=kra,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (&(requeststate=rejected)(requesttype=enrollment))
+
+dn: cn=kraRejectedRecovery-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: kraRejectedRecovery-{instanceId}
+vlvBase: ou=kra,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (&(requeststate=rejected)(requesttype=recovery))
+
+dn: cn=kraComplete-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: kraComplete-{instanceId}
+vlvBase: ou=kra,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (requeststate=complete)
+
+dn: cn=kraCompleteEnrollment-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: kraCompleteEnrollment-{instanceId}
+vlvBase: ou=kra,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (&(requeststate=complete)(requesttype=enrollment))
+
+dn: cn=kraCompleteRecovery-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvSearch
+cn: kraCompleteRecovery-{instanceId}
+vlvBase: ou=kra,ou=requests,{rootSuffix}
+vlvScope: 1
+vlvFilter: (&(requeststate=complete)(requesttype=recovery))
+
+dn: cn=allKeys-{instanceId}Index, cn=allKeys-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: allKeys-{instanceId}Index
+vlvSort: serialno
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=kraAll-{instanceId}Index, cn=kraAll-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: kraAll-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=kraArchival-{instanceId}Index, cn=kraArchival-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: kraArchival-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=kraRecovery-{instanceId}Index, cn=kraRecovery-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: kraRecovery-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=kraCanceled-{instanceId}Index, cn=kraCanceled-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: kraCanceled-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=kraCanceledEnrollment-{instanceId}Index, cn=kraCanceledEnrollment-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: kraCanceledEnrollment-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=kraCanceledRecovery-{instanceId}Index, cn=kraCanceledRecovery-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: kraCanceledRecovery-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=kraRejected-{instanceId}Index, cn=kraRejected-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: kraRejected-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=kraRejectedEnrollment-{instanceId}Index, cn=kraRejectedEnrollment-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: kraRejectedEnrollment-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=kraRejectedRecovery-{instanceId}Index, cn=kraRejectedRecovery-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: kraRejectedRecovery-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=kraComplete-{instanceId}Index, cn=kraComplete-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: kraComplete-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=kraCompleteEnrollment-{instanceId}Index, cn=kraCompleteEnrollment-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: kraCompleteEnrollment-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
+
+dn: cn=kraCompleteRecovery-{instanceId}Index, cn=kraCompleteRecovery-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: vlvIndex
+cn: kraCompleteRecovery-{instanceId}Index
+vlvSort: requestId
+vlvEnabled: 0
+vlvUses: 0
diff --git a/base/kra/shared/conf/vlvtasks.ldif b/base/kra/shared/conf/vlvtasks.ldif
new file mode 100644
index 000000000..c8a27f170
--- /dev/null
+++ b/base/kra/shared/conf/vlvtasks.ldif
@@ -0,0 +1,19 @@
+dn: cn=index1160527115, cn=index, cn=tasks, cn=config
+objectclass: top
+objectclass: extensibleObject
+cn: index1160527115
+ttl: 10
+nsInstance: {database}
+nsIndexVLVAttribute: allKeys-{instanceId}Index
+nsIndexVLVAttribute: kraAll-{instanceId}Index
+nsIndexVLVAttribute: kraArchival-{instanceId}Index
+nsIndexVLVAttribute: kraRecovery-{instanceId}Index
+nsIndexVLVAttribute: kraCanceled-{instanceId}Index
+nsIndexVLVAttribute: kraCanceledEnrollment-{instanceId}Index
+nsIndexVLVAttribute: kraCanceledRecovery-{instanceId}Index
+nsIndexVLVAttribute: kraRejected-{instanceId}Index
+nsIndexVLVAttribute: kraRejectedEnrollment-{instanceId}Index
+nsIndexVLVAttribute: kraRejectedRecovery-{instanceId}Index
+nsIndexVLVAttribute: kraComplete-{instanceId}Index
+nsIndexVLVAttribute: kraCompleteEnrollment-{instanceId}Index
+nsIndexVLVAttribute: kraCompleteRecovery-{instanceId}Index
diff --git a/base/kra/shared/conf/web.xml b/base/kra/shared/conf/web.xml
new file mode 100644
index 000000000..fb22468ee
--- /dev/null
+++ b/base/kra/shared/conf/web.xml
@@ -0,0 +1,989 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+ version="2.4">
+
+ <!-- ======================== Introduction ============================== -->
+ <!-- This document defines default values for *all* web applications -->
+ <!-- loaded into this instance of Tomcat. As each application is -->
+ <!-- deployed, this file is processed, followed by the -->
+ <!-- "/WEB-INF/web.xml" deployment descriptor from your own -->
+ <!-- applications. -->
+ <!-- -->
+ <!-- WARNING: Do not configure application-specific resources here! -->
+ <!-- They should go in the "/WEB-INF/web.xml" file in your application. -->
+
+
+ <!-- ================== Built In Servlet Definitions ==================== -->
+
+
+ <!-- The default servlet for all web applications, that serves static -->
+ <!-- resources. It processes all requests that are not mapped to other -->
+ <!-- servlets with servlet mappings (defined either here or in your own -->
+ <!-- web.xml file. This servlet supports the following initialization -->
+ <!-- parameters (default values are in square brackets): -->
+ <!-- -->
+ <!-- debug Debugging detail level for messages logged -->
+ <!-- by this servlet. [0] -->
+ <!-- -->
+ <!-- fileEncoding Encoding to be used to read static resources -->
+ <!-- [platform default] -->
+ <!-- -->
+ <!-- input Input buffer size (in bytes) when reading -->
+ <!-- resources to be served. [2048] -->
+ <!-- -->
+ <!-- listings Should directory listings be produced if there -->
+ <!-- is no welcome file in this directory? [true] -->
+ <!-- -->
+ <!-- output Output buffer size (in bytes) when writing -->
+ <!-- resources to be served. [2048] -->
+ <!-- -->
+ <!-- readonly Is this context "read only", so HTTP -->
+ <!-- commands like PUT and DELETE are -->
+ <!-- rejected? [true] -->
+ <!-- -->
+ <!-- readmeFile File name to display with the directory -->
+ <!-- contents. [null] -->
+ <!-- -->
+ <!-- For directory listing customization. Checks localXsltFile, then -->
+ <!-- globalXsltFile, then defaults to original behavior. -->
+ <!-- -->
+ <!-- localXsltFile Make directory listings an XML doc and -->
+ <!-- pass the result to this style sheet residing -->
+ <!-- in that directory. This overrides -->
+ <!-- globalXsltFile[null] -->
+ <!-- -->
+ <!-- globalXsltFile Site wide configuration version of -->
+ <!-- localXsltFile This argument is expected -->
+ <!-- to be a physical file. [null] -->
+ <!-- -->
+ <!-- -->
+
+ <servlet>
+ <servlet-name>default</servlet-name>
+ <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
+ <init-param>
+ <param-name>debug</param-name>
+ <param-value>0</param-value>
+ </init-param>
+ <init-param>
+ <param-name>listings</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+
+ <!-- The "invoker" servlet, which executes anonymous servlet classes -->
+ <!-- that have not been defined in a web.xml file. Traditionally, this -->
+ <!-- servlet is mapped to the URL pattern "/servlet/*", but you can map -->
+ <!-- it to other patterns as well. The extra path info portion of such a -->
+ <!-- request must be the fully qualified class name of a Java class that -->
+ <!-- implements Servlet (or extends HttpServlet), or the servlet name -->
+ <!-- of an existing servlet definition. This servlet supports the -->
+ <!-- following initialization parameters (default values are in square -->
+ <!-- brackets): -->
+ <!-- -->
+ <!-- debug Debugging detail level for messages logged -->
+ <!-- by this servlet. [0] -->
+
+<!--
+ <servlet>
+ <servlet-name>invoker</servlet-name>
+ <servlet-class>
+ org.apache.catalina.servlets.InvokerServlet
+ </servlet-class>
+ <init-param>
+ <param-name>debug</param-name>
+ <param-value>0</param-value>
+ </init-param>
+ <load-on-startup>2</load-on-startup>
+ </servlet>
+-->
+
+
+ <!-- The JSP page compiler and execution servlet, which is the mechanism -->
+ <!-- used by Tomcat to support JSP pages. Traditionally, this servlet -->
+ <!-- is mapped to the URL pattern "*.jsp". This servlet supports the -->
+ <!-- following initialization parameters (default values are in square -->
+ <!-- brackets): -->
+ <!-- -->
+ <!-- checkInterval If development is false and checkInterval is -->
+ <!-- greater than zero, background compilations are -->
+ <!-- enabled. checkInterval is the time in seconds -->
+ <!-- between checks to see if a JSP page needs to -->
+ <!-- be recompiled. [0] -->
+ <!-- -->
+ <!-- modificationTestInterval -->
+ <!-- Causes a JSP (and its dependent files) to not -->
+ <!-- be checked for modification during the -->
+ <!-- specified time interval (in seconds) from the -->
+ <!-- last time the JSP was checked for -->
+ <!-- modification. A value of 0 will cause the JSP -->
+ <!-- to be checked on every access. -->
+ <!-- Used in development mode only. [4] -->
+ <!-- -->
+ <!-- compiler Which compiler Ant should use to compile JSP -->
+ <!-- pages. See the Ant documentation for more -->
+ <!-- information. [javac] -->
+ <!-- -->
+ <!-- classdebuginfo Should the class file be compiled with -->
+ <!-- debugging information? [true] -->
+ <!-- -->
+ <!-- classpath What class path should I use while compiling -->
+ <!-- generated servlets? [Created dynamically -->
+ <!-- based on the current web application] -->
+ <!-- -->
+ <!-- development Is Jasper used in development mode? If true, -->
+ <!-- the frequency at which JSPs are checked for -->
+ <!-- modification may be specified via the -->
+ <!-- modificationTestInterval parameter. [true] -->
+ <!-- -->
+ <!-- enablePooling Determines whether tag handler pooling is -->
+ <!-- enabled [true] -->
+ <!-- -->
+ <!-- fork Tell Ant to fork compiles of JSP pages so that -->
+ <!-- a separate JVM is used for JSP page compiles -->
+ <!-- from the one Tomcat is running in. [true] -->
+ <!-- -->
+ <!-- ieClassId The class-id value to be sent to Internet -->
+ <!-- Explorer when using <jsp:plugin> tags. -->
+ <!-- [clsid:8AD9C840-044E-11D1-B3E9-00805F499D93] -->
+ <!-- -->
+ <!-- javaEncoding Java file encoding to use for generating java -->
+ <!-- source files. [UTF8] -->
+ <!-- -->
+ <!-- keepgenerated Should we keep the generated Java source code -->
+ <!-- for each page instead of deleting it? [true] -->
+ <!-- -->
+ <!-- mappedfile Should we generate static content with one -->
+ <!-- print statement per input line, to ease -->
+ <!-- debugging? [true] -->
+ <!-- -->
+ <!-- trimSpaces Should white spaces in template text between -->
+ <!-- actions or directives be trimmed? [false] -->
+ <!-- -->
+ <!-- suppressSmap Should the generation of SMAP info for JSR45 -->
+ <!-- debugging be suppressed? [false] -->
+ <!-- -->
+ <!-- dumpSmap Should the SMAP info for JSR45 debugging be -->
+ <!-- dumped to a file? [false] -->
+ <!-- False if suppressSmap is true -->
+ <!-- -->
+ <!-- genStrAsCharArray Should text strings be generated as char -->
+ <!-- arrays, to improve performance in some cases? -->
+ <!-- [false] -->
+ <!-- -->
+ <!-- errorOnUseBeanInvalidClassAttribute -->
+ <!-- Should Jasper issue an error when the value of -->
+ <!-- the class attribute in an useBean action is -->
+ <!-- not a valid bean class? [true] -->
+ <!-- -->
+ <!-- scratchdir What scratch directory should we use when -->
+ <!-- compiling JSP pages? [default work directory -->
+ <!-- for the current web application] -->
+ <!-- -->
+ <!-- xpoweredBy Determines whether X-Powered-By response -->
+ <!-- header is added by generated servlet [false] -->
+ <!-- -->
+ <!-- If you wish to use Jikes to compile JSP pages: -->
+ <!-- Please see the "Using Jikes" section of the Jasper-HowTo -->
+ <!-- page in the Tomcat documentation. -->
+
+ <servlet>
+ <servlet-name>jsp</servlet-name>
+ <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
+ <init-param>
+ <param-name>fork</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ <init-param>
+ <param-name>xpoweredBy</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ <load-on-startup>3</load-on-startup>
+ </servlet>
+
+
+ <!-- Server Side Includes processing servlet, which processes SSI -->
+ <!-- directives in HTML pages consistent with similar support in web -->
+ <!-- servers like Apache. Traditionally, this servlet is mapped to the -->
+ <!-- URL pattern "*.shtml". This servlet supports the following -->
+ <!-- initialization parameters (default values are in square brackets): -->
+ <!-- -->
+ <!-- buffered Should output from this servlet be buffered? -->
+ <!-- (0=false, 1=true) [0] -->
+ <!-- -->
+ <!-- debug Debugging detail level for messages logged -->
+ <!-- by this servlet. [0] -->
+ <!-- -->
+ <!-- expires The number of seconds before a page with SSI -->
+ <!-- directives will expire. [No default] -->
+ <!-- -->
+ <!-- isVirtualWebappRelative -->
+ <!-- Should "virtual" paths be interpreted as -->
+ <!-- relative to the context root, instead of -->
+ <!-- the server root? (0=false, 1=true) [0] -->
+ <!-- -->
+ <!-- -->
+ <!-- IMPORTANT: To use the SSI servlet, you also need to rename the -->
+ <!-- $CATALINA_HOME/server/lib/servlets-ssi.renametojar file -->
+ <!-- to $CATALINA_HOME/server/lib/servlets-ssi.jar -->
+
+<!--
+ <servlet>
+ <servlet-name>ssi</servlet-name>
+ <servlet-class>
+ org.apache.catalina.ssi.SSIServlet
+ </servlet-class>
+ <init-param>
+ <param-name>buffered</param-name>
+ <param-value>1</param-value>
+ </init-param>
+ <init-param>
+ <param-name>debug</param-name>
+ <param-value>0</param-value>
+ </init-param>
+ <init-param>
+ <param-name>expires</param-name>
+ <param-value>666</param-value>
+ </init-param>
+ <init-param>
+ <param-name>isVirtualWebappRelative</param-name>
+ <param-value>0</param-value>
+ </init-param>
+ <load-on-startup>4</load-on-startup>
+ </servlet>
+-->
+
+
+ <!-- Common Gateway Includes (CGI) processing servlet, which supports -->
+ <!-- execution of external applications that conform to the CGI spec -->
+ <!-- requirements. Typically, this servlet is mapped to the URL pattern -->
+ <!-- "/cgi-bin/*", which means that any CGI applications that are -->
+ <!-- executed must be present within the web application. This servlet -->
+ <!-- supports the following initialization parameters (default values -->
+ <!-- are in square brackets): -->
+ <!-- -->
+ <!-- cgiPathPrefix The CGI search path will start at -->
+ <!-- webAppRootDir + File.separator + this prefix. -->
+ <!-- [WEB-INF/cgi] -->
+ <!-- -->
+ <!-- debug Debugging detail level for messages logged -->
+ <!-- by this servlet. [0] -->
+ <!-- -->
+ <!-- executable Name of the exectuable used to run the -->
+ <!-- script. [perl] -->
+ <!-- -->
+ <!-- parameterEncoding Name of parameter encoding to be used with -->
+ <!-- CGI servlet. -->
+ <!-- [System.getProperty("file.encoding","UTF-8")] -->
+ <!-- -->
+ <!-- passShellEnvironment Should the shell environment variables (if -->
+ <!-- any) be passed to the CGI script? [false] -->
+ <!-- -->
+ <!-- IMPORTANT: To use the CGI servlet, you also need to rename the -->
+ <!-- $CATALINA_HOME/server/lib/servlets-cgi.renametojar file -->
+ <!-- to $CATALINA_HOME/server/lib/servlets-cgi.jar -->
+
+<!--
+ <servlet>
+ <servlet-name>cgi</servlet-name>
+ <servlet-class>org.apache.catalina.servlets.CGIServlet</servlet-class>
+ <init-param>
+ <param-name>debug</param-name>
+ <param-value>6</param-value>
+ </init-param>
+ <init-param>
+ <param-name>cgiPathPrefix</param-name>
+ <param-value>WEB-INF/cgi</param-value>
+ </init-param>
+ <load-on-startup>5</load-on-startup>
+ </servlet>
+-->
+
+
+ <!-- ================ Built In Servlet Mappings ========================= -->
+
+
+ <!-- The servlet mappings for the built in servlets defined above. Note -->
+ <!-- that, by default, the CGI and SSI servlets are *not* mapped. You -->
+ <!-- must uncomment these mappings (or add them to your application's own -->
+ <!-- web.xml deployment descriptor) to enable these services -->
+
+ <!-- The mapping for the default servlet -->
+ <servlet-mapping>
+ <servlet-name>default</servlet-name>
+ <url-pattern>/</url-pattern>
+ </servlet-mapping>
+
+ <!-- The mapping for the invoker servlet -->
+<!--
+ <servlet-mapping>
+ <servlet-name>invoker</servlet-name>
+ <url-pattern>/servlet/*</url-pattern>
+ </servlet-mapping>
+-->
+
+ <!-- The mapping for the JSP servlet -->
+ <servlet-mapping>
+ <servlet-name>jsp</servlet-name>
+ <url-pattern>*.jsp</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>jsp</servlet-name>
+ <url-pattern>*.jspx</url-pattern>
+ </servlet-mapping>
+
+ <!-- The mapping for the SSI servlet -->
+<!--
+ <servlet-mapping>
+ <servlet-name>ssi</servlet-name>
+ <url-pattern>*.shtml</url-pattern>
+ </servlet-mapping>
+-->
+
+ <!-- The mapping for the CGI Gateway servlet -->
+
+<!--
+ <servlet-mapping>
+ <servlet-name>cgi</servlet-name>
+ <url-pattern>/cgi-bin/*</url-pattern>
+ </servlet-mapping>
+-->
+
+
+ <!-- ==================== Default Session Configuration ================= -->
+ <!-- You can set the default session timeout (in minutes) for all newly -->
+ <!-- created sessions by modifying the value below. -->
+
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+
+
+ <!-- ===================== Default MIME Type Mappings =================== -->
+ <!-- When serving static resources, Tomcat will automatically generate -->
+ <!-- a "Content-Type" header based on the resource's filename extension, -->
+ <!-- based on these mappings. Additional mappings can be added here (to -->
+ <!-- apply to all web applications), or in your own application's web.xml -->
+ <!-- deployment descriptor. -->
+
+ <mime-mapping>
+ <extension>abs</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ai</extension>
+ <mime-type>application/postscript</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>aif</extension>
+ <mime-type>audio/x-aiff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>aifc</extension>
+ <mime-type>audio/x-aiff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>aiff</extension>
+ <mime-type>audio/x-aiff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>aim</extension>
+ <mime-type>application/x-aim</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>art</extension>
+ <mime-type>image/x-jg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>asf</extension>
+ <mime-type>video/x-ms-asf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>asx</extension>
+ <mime-type>video/x-ms-asf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>au</extension>
+ <mime-type>audio/basic</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>avi</extension>
+ <mime-type>video/x-msvideo</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>avx</extension>
+ <mime-type>video/x-rad-screenplay</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>bcpio</extension>
+ <mime-type>application/x-bcpio</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>bin</extension>
+ <mime-type>application/octet-stream</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>bmp</extension>
+ <mime-type>image/bmp</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>body</extension>
+ <mime-type>text/html</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>cdf</extension>
+ <mime-type>application/x-cdf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>cer</extension>
+ <mime-type>application/x-x509-ca-cert</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>class</extension>
+ <mime-type>application/java</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>cpio</extension>
+ <mime-type>application/x-cpio</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>csh</extension>
+ <mime-type>application/x-csh</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>css</extension>
+ <mime-type>text/css</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>dib</extension>
+ <mime-type>image/bmp</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>doc</extension>
+ <mime-type>application/msword</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>dtd</extension>
+ <mime-type>application/xml-dtd</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>dv</extension>
+ <mime-type>video/x-dv</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>dvi</extension>
+ <mime-type>application/x-dvi</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>eps</extension>
+ <mime-type>application/postscript</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>etx</extension>
+ <mime-type>text/x-setext</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>exe</extension>
+ <mime-type>application/octet-stream</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>gif</extension>
+ <mime-type>image/gif</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>gtar</extension>
+ <mime-type>application/x-gtar</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>gz</extension>
+ <mime-type>application/x-gzip</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>hdf</extension>
+ <mime-type>application/x-hdf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>hqx</extension>
+ <mime-type>application/mac-binhex40</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>htc</extension>
+ <mime-type>text/x-component</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>htm</extension>
+ <mime-type>text/html</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>html</extension>
+ <mime-type>text/html</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>hqx</extension>
+ <mime-type>application/mac-binhex40</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ief</extension>
+ <mime-type>image/ief</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jad</extension>
+ <mime-type>text/vnd.sun.j2me.app-descriptor</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jar</extension>
+ <mime-type>application/java-archive</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>java</extension>
+ <mime-type>text/plain</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jnlp</extension>
+ <mime-type>application/x-java-jnlp-file</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jpe</extension>
+ <mime-type>image/jpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jpeg</extension>
+ <mime-type>image/jpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jpg</extension>
+ <mime-type>image/jpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>js</extension>
+ <mime-type>text/javascript</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jsf</extension>
+ <mime-type>text/plain</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jspf</extension>
+ <mime-type>text/plain</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>kar</extension>
+ <mime-type>audio/x-midi</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>latex</extension>
+ <mime-type>application/x-latex</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>m3u</extension>
+ <mime-type>audio/x-mpegurl</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mac</extension>
+ <mime-type>image/x-macpaint</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>man</extension>
+ <mime-type>application/x-troff-man</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mathml</extension>
+ <mime-type>application/mathml+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>me</extension>
+ <mime-type>application/x-troff-me</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mid</extension>
+ <mime-type>audio/x-midi</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>midi</extension>
+ <mime-type>audio/x-midi</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mif</extension>
+ <mime-type>application/x-mif</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mov</extension>
+ <mime-type>video/quicktime</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>movie</extension>
+ <mime-type>video/x-sgi-movie</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mp1</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mp2</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mp3</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpa</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpe</extension>
+ <mime-type>video/mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpeg</extension>
+ <mime-type>video/mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpega</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpg</extension>
+ <mime-type>video/mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpv2</extension>
+ <mime-type>video/mpeg2</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ms</extension>
+ <mime-type>application/x-wais-source</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>nc</extension>
+ <mime-type>application/x-netcdf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>oda</extension>
+ <mime-type>application/oda</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ogg</extension>
+ <mime-type>application/ogg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pbm</extension>
+ <mime-type>image/x-portable-bitmap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pct</extension>
+ <mime-type>image/pict</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pdf</extension>
+ <mime-type>application/pdf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pgm</extension>
+ <mime-type>image/x-portable-graymap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pic</extension>
+ <mime-type>image/pict</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pict</extension>
+ <mime-type>image/pict</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pls</extension>
+ <mime-type>audio/x-scpls</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>png</extension>
+ <mime-type>image/png</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pnm</extension>
+ <mime-type>image/x-portable-anymap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pnt</extension>
+ <mime-type>image/x-macpaint</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ppm</extension>
+ <mime-type>image/x-portable-pixmap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ppt</extension>
+ <mime-type>application/powerpoint</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ps</extension>
+ <mime-type>application/postscript</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>psd</extension>
+ <mime-type>image/x-photoshop</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>qt</extension>
+ <mime-type>video/quicktime</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>qti</extension>
+ <mime-type>image/x-quicktime</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>qtif</extension>
+ <mime-type>image/x-quicktime</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ras</extension>
+ <mime-type>image/x-cmu-raster</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>rdf</extension>
+ <mime-type>application/rdf+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>rgb</extension>
+ <mime-type>image/x-rgb</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>rm</extension>
+ <mime-type>application/vnd.rn-realmedia</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>roff</extension>
+ <mime-type>application/x-troff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>rtf</extension>
+ <mime-type>application/rtf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>rtx</extension>
+ <mime-type>text/richtext</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>sh</extension>
+ <mime-type>application/x-sh</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>shar</extension>
+ <mime-type>application/x-shar</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>smf</extension>
+ <mime-type>audio/x-midi</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>sit</extension>
+ <mime-type>application/x-stuffit</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>snd</extension>
+ <mime-type>audio/basic</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>src</extension>
+ <mime-type>application/x-wais-source</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>sv4cpio</extension>
+ <mime-type>application/x-sv4cpio</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>sv4crc</extension>
+ <mime-type>application/x-sv4crc</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>svg</extension>
+ <mime-type>image/svg+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>swf</extension>
+ <mime-type>application/x-shockwave-flash</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>t</extension>
+ <mime-type>application/x-troff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tar</extension>
+ <mime-type>application/x-tar</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tcl</extension>
+ <mime-type>application/x-tcl</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tex</extension>
+ <mime-type>application/x-tex</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>texi</extension>
+ <mime-type>application/x-texinfo</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>texinfo</extension>
+ <mime-type>application/x-texinfo</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tif</extension>
+ <mime-type>image/tiff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tiff</extension>
+ <mime-type>image/tiff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tr</extension>
+ <mime-type>application/x-troff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tsv</extension>
+ <mime-type>text/tab-separated-values</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>txt</extension>
+ <mime-type>text/plain</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ulw</extension>
+ <mime-type>audio/basic</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ustar</extension>
+ <mime-type>application/x-ustar</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>vxml</extension>
+ <mime-type>application/voicexml+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xbm</extension>
+ <mime-type>image/x-xbitmap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xht</extension>
+ <mime-type>application/xhtml+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xhtml</extension>
+ <mime-type>application/xhtml+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xml</extension>
+ <mime-type>application/xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xpm</extension>
+ <mime-type>image/x-xpixmap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xsl</extension>
+ <mime-type>application/xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xslt</extension>
+ <mime-type>application/xslt+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xul</extension>
+ <mime-type>application/vnd.mozilla.xul+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xwd</extension>
+ <mime-type>image/x-xwindowdump</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>wav</extension>
+ <mime-type>audio/x-wav</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>svg</extension>
+ <mime-type>image/svg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>svgz</extension>
+ <mime-type>image/svg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>vsd</extension>
+ <mime-type>application/x-visio</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <!-- Wireless Bitmap -->
+ <extension>wbmp</extension>
+ <mime-type>image/vnd.wap.wbmp</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <!-- WML Source -->
+ <extension>wml</extension>
+ <mime-type>text/vnd.wap.wml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <!-- Compiled WML -->
+ <extension>wmlc</extension>
+ <mime-type>application/vnd.wap.wmlc</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <!-- WML Script Source -->
+ <extension>wmls</extension>
+ <mime-type>text/vnd.wap.wmlscript</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <!-- Compiled WML Script -->
+ <extension>wmlscriptc</extension>
+ <mime-type>application/vnd.wap.wmlscriptc</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>wrl</extension>
+ <mime-type>x-world/x-vrml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>Z</extension>
+ <mime-type>application/x-compress</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>z</extension>
+ <mime-type>application/x-compress</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>zip</extension>
+ <mime-type>application/zip</mime-type>
+ </mime-mapping>
+
+
+ <!-- ==================== Default Welcome File List ===================== -->
+ <!-- When a request URI refers to a directory, the default servlet looks -->
+ <!-- for a "welcome file" within that directory and, if present, -->
+ <!-- to the corresponding resource URI for display. If no welcome file -->
+ <!-- is present, the default servlet either serves a directory listing, -->
+ <!-- or returns a 404 status, depending on how it is configured. -->
+ <!-- -->
+ <!-- If you define welcome files in your own application's web.xml -->
+ <!-- deployment descriptor, that list *replaces* the list configured -->
+ <!-- here, so be sure that you include any of the default values that -->
+ <!-- you wish to include. -->
+
+ <welcome-file-list>
+ <welcome-file>index.html</welcome-file>
+ <welcome-file>index.htm</welcome-file>
+ <welcome-file>index.jsp</welcome-file>
+ </welcome-file-list>
+
+ <error-page>
+ <error-code>404</error-code>
+ <location>/404.html</location>
+ </error-page>
+
+ <error-page>
+ <error-code>500</error-code>
+ <location>/500.html</location>
+ </error-page>
+
+</web-app>
diff --git a/base/kra/shared/conf/workers.properties b/base/kra/shared/conf/workers.properties
new file mode 100644
index 000000000..50d88557f
--- /dev/null
+++ b/base/kra/shared/conf/workers.properties
@@ -0,0 +1,206 @@
+# workers.properties -
+#
+# This file provides jk derived plugins with the needed information to
+# connect to the different tomcat workers. Note that the distributed
+# version of this file requires modification before it is usable by a
+# plugin.
+#
+# As a general note, the characters $( and ) are used internally to define
+# macros. Do not use them in your own configuration!!!
+#
+# Whenever you see a set of lines such as:
+# x=value
+# y=$(x)\something
+#
+# the final value for y will be value\something
+#
+# Normaly all you will need to do is un-comment and modify the first three
+# properties, i.e. workers.tomcat_home, workers.java_home and ps.
+# Most of the configuration is derived from these.
+#
+# When you are done updating workers.tomcat_home, workers.java_home and ps
+# you should have 3 workers configured:
+#
+# - An ajp12 worker that connects to localhost:8007
+# - An ajp13 worker that connects to localhost:8009
+# - A jni inprocess worker.
+# - A load balancer worker
+#
+# However by default the plugins will only use the ajp12 worker. To have
+# the plugins use other workers you should modify the worker.list property.
+#
+#
+
+# OPTIONS ( very important for jni mode )
+
+#
+# workers.tomcat_home should point to the location where you
+# installed tomcat. This is where you have your conf, webapps and lib
+# directories.
+#
+workers.tomcat_home=/var/tomcat3
+
+#
+# workers.java_home should point to your Java installation. Normally
+# you should have a bin and lib directories beneath it.
+#
+workers.java_home=/opt/IBMJava2-13
+
+#
+# You should configure your environment slash... ps=\ on NT and / on UNIX
+# and maybe something different elsewhere.
+#
+ps=/
+
+#
+#------ ADVANCED MODE ------------------------------------------------
+#---------------------------------------------------------------------
+#
+
+#
+#------ DEFAULT worket list ------------------------------------------
+#---------------------------------------------------------------------
+#
+#
+# The workers that your plugins should create and work with
+#
+# Add 'inprocess' if you want JNI connector
+worker.list=ajp12, ajp13
+# , inprocess
+
+
+#
+#------ DEFAULT ajp12 WORKER DEFINITION ------------------------------
+#---------------------------------------------------------------------
+#
+
+#
+# Defining a worker named ajp12 and of type ajp12
+# Note that the name and the type do not have to match.
+#
+worker.ajp12.port=8007
+worker.ajp12.host=localhost
+worker.ajp12.type=ajp12
+#
+# Specifies the load balance factor when used with
+# a load balancing worker.
+# Note:
+# ----> lbfactor must be > 0
+# ----> Low lbfactor means less work done by the worker.
+worker.ajp12.lbfactor=1
+
+#
+#------ DEFAULT ajp13 WORKER DEFINITION ------------------------------
+#---------------------------------------------------------------------
+#
+
+#
+# Defining a worker named ajp13 and of type ajp13
+# Note that the name and the type do not have to match.
+#
+worker.ajp13.port=8009
+worker.ajp13.host=localhost
+worker.ajp13.type=ajp13
+#
+# Specifies the load balance factor when used with
+# a load balancing worker.
+# Note:
+# ----> lbfactor must be > 0
+# ----> Low lbfactor means less work done by the worker.
+worker.ajp13.lbfactor=1
+
+#
+# Specify the size of the open connection cache.
+#worker.ajp13.cachesize
+
+#
+#------ DEFAULT LOAD BALANCER WORKER DEFINITION ----------------------
+#---------------------------------------------------------------------
+#
+
+#
+# The loadbalancer (type lb) workers perform wighted round-robin
+# load balancing with sticky sessions.
+# Note:
+# ----> If a worker dies, the load balancer will check its state
+# once in a while. Until then all work is redirected to peer
+# workers.
+worker.loadbalancer.type=lb
+worker.loadbalancer.balanced_workers=ajp12, ajp13
+
+
+#
+#------ DEFAULT JNI WORKER DEFINITION---------------------------------
+#---------------------------------------------------------------------
+#
+
+#
+# Defining a worker named inprocess and of type jni
+# Note that the name and the type do not have to match.
+#
+worker.inprocess.type=jni
+
+#
+#------ CLASSPATH DEFINITION -----------------------------------------
+#---------------------------------------------------------------------
+#
+
+#
+# Additional class path components.
+#
+worker.inprocess.class_path=$(workers.tomcat_home)$(ps)lib$(ps)tomcat.jar
+
+#
+# Setting the command line for tomcat.
+# Note: The cmd_line string may not contain spaces.
+#
+worker.inprocess.cmd_line=start
+
+# Not needed, but can be customized.
+#worker.inprocess.cmd_line=-config
+#worker.inprocess.cmd_line=$(workers.tomcat_home)$(ps)conf$(ps)server.xml
+#worker.inprocess.cmd_line=-home
+#worker.inprocess.cmd_line=$(workers.tomcat_home)
+
+#
+# The JVM that we are about to use
+#
+# This is for Java2
+#
+# Windows
+worker.inprocess.jvm_lib=$(workers.java_home)$(ps)jre$(ps)bin$(ps)classic$(ps)jvm.dll
+# IBM JDK1.3
+#worker.inprocess.jvm_lib=$(workers.java_home)$(ps)jre$(ps)bin$(ps)classic$(ps)libjvm.so
+# Unix - Sun VM or blackdown
+#worker.inprocess.jvm_lib=$(workers.java_home)$(ps)jre$(ps)lib$(ps)i386$(ps)classic$(ps)libjvm.so
+
+#
+# And this is for jdk1.1.X
+#
+#worker.inprocess.jvm_lib=$(workers.java_home)$(ps)bin$(ps)javai.dll
+
+
+#
+# Setting the place for the stdout and stderr of tomcat
+#
+worker.inprocess.stdout=$(workers.tomcat_home)$(ps)logs$(ps)inprocess.stdout
+worker.inprocess.stderr=$(workers.tomcat_home)$(ps)logs$(ps)inprocess.stderr
+
+#
+# Setting the tomcat.home Java property
+#
+#worker.inprocess.sysprops=tomcat.home=$(workers.tomcat_home)
+
+#
+# Java system properties
+#
+# worker.inprocess.sysprops=java.compiler=NONE
+# worker.inprocess.sysprops=myprop=mypropvalue
+
+#
+# Additional path components.
+#
+# worker.inprocess.ld_path=d:$(ps)SQLLIB$(ps)bin
+#
+
+
diff --git a/base/kra/shared/conf/workers.properties.minimal b/base/kra/shared/conf/workers.properties.minimal
new file mode 100644
index 000000000..e3b5942c2
--- /dev/null
+++ b/base/kra/shared/conf/workers.properties.minimal
@@ -0,0 +1,17 @@
+# workers.properties.minimal -
+#
+# This file provides minimal jk configuration properties needed to
+# connect to Tomcat.
+#
+# The workers that jk should create and work with
+#
+worker.list=ajp13w
+
+
+#
+# Defining a worker named ajp13w and of type ajp13
+# Note that the name and the type do not have to match.
+#
+worker.ajp13w.type=ajp13
+worker.ajp13w.host=localhost
+worker.ajp13w.port=8009
diff --git a/base/kra/shared/conf/workers2.properties b/base/kra/shared/conf/workers2.properties
new file mode 100644
index 000000000..778118ff2
--- /dev/null
+++ b/base/kra/shared/conf/workers2.properties
@@ -0,0 +1,132 @@
+[logger]
+level=DEBUG
+
+[config:]
+file=${serverRoot}/conf/workers2.properties
+debug=0
+debugEnv=0
+
+[uriMap:]
+info=Maps the requests. Options: debug
+debug=0
+
+# Alternate file logger
+#[logger.file:0]
+#level=DEBUG
+#file=${serverRoot}/logs/jk2.log
+
+[shm:]
+info=Scoreboard. Required for reconfiguration and status with multiprocess servers
+file=${serverRoot}/logs/jk2.shm
+size=1000000
+debug=0
+disabled=0
+
+[workerEnv:]
+info=Global server options
+timing=1
+debug=0
+# Default Native Logger (apache2 or win32 )
+# can be overriden to a file logger, useful
+# when tracing win32 related issues
+#logger=logger.file:0
+
+[lb:lb]
+info=Default load balancer.
+debug=0
+
+[lb:lb_1]
+info=A second load balancer.
+debug=0
+
+[channel.socket:localhost:8009]
+info=Ajp13 forwarding over socket
+debug=0
+tomcatId=localhost:8009
+
+[channel.socket:localhost:8019]
+info=A second tomcat instance.
+debug=0
+tomcatId=localhost:8019
+lb_factor=1
+#group=lb
+group:lb:lb
+#group=lb_1
+group:lb:lb_1
+disabled=0
+
+[channel.un:/opt/33/work/jk2.socket]
+info=A second channel connecting to localhost:8019 via unix socket
+tomcatId=localhost:8019
+lb_factor=1
+debug=0
+
+[channel.jni:jni]
+info=The jni channel, used if tomcat is started inprocess
+
+[status:]
+info=Status worker, displays runtime informations
+
+[vm:]
+info=Parameters used to load a JVM in the server process
+#JVM=C:\jdk\jre\bin\hotspot\jvm.dll
+classpath=${TOMCAT_HOME}/bin/tomcat-jni.jar
+classpath=${TOMCAT_HOME}/server/lib/commons-logging.jar
+OPT=-Dtomcat.home=${TOMCAT_HOME}
+OPT=-Dcatalina.home=${TOMCAT_HOME}
+OPT=-Xmx128M
+#OPT=-Djava.compiler=NONE
+disabled=1
+
+[worker.jni:onStartup]
+info=Command to be executed by the VM on startup. This one will start tomcat.
+class=org/apache/jk/apr/TomcatStarter
+ARG=start
+# For Tomcat 5 use the 'stard' for startup argument
+# ARG=stard
+disabled=1
+stdout=${serverRoot}/logs/stdout.log
+stderr=${serverRoot}/logs/stderr.log
+
+[worker.jni:onShutdown]
+info=Command to be executed by the VM on shutdown. This one will stop tomcat.
+class=org/apache/jk/apr/TomcatStarter
+ARG=stop
+disabled=1
+
+[uri:/jkstatus/*]
+info=Display status information and checks the config file for changes.
+group=status:
+
+[uri:127.0.0.1:8003]
+info=Example virtual host. Make sure myVirtualHost is in /etc/hosts to test it
+alias=myVirtualHost:8003
+
+[uri:127.0.0.1:8003/ex]
+info=Example webapp in the virtual host. It'll go to lb_1 ( i.e. localhost:8019 )
+context=/ex
+group=lb_1
+
+[uri:/examples]
+info=Example webapp in the default context.
+context=/examples
+debug=0
+
+[uri:/examples1/*]
+info=A second webapp, this time going to the second tomcat only.
+group=lb_1
+debug=0
+
+[uri:/examples/servlet/*]
+info=Prefix mapping
+
+[uri:/examples/*.jsp]
+info=Extension mapping
+
+[uri:/examples/*]
+info=Map the whole webapp
+
+[uri:/examples/servlet/HelloW]
+info=Example with debug enabled.
+debug=10
+
diff --git a/base/kra/shared/conf/workers2.properties.minimal b/base/kra/shared/conf/workers2.properties.minimal
new file mode 100644
index 000000000..41a0ba6c1
--- /dev/null
+++ b/base/kra/shared/conf/workers2.properties.minimal
@@ -0,0 +1,55 @@
+#
+# This is the minimal JK2 connector configuration file.
+#
+
+[logger]
+info=Native logger
+level=ERROR
+
+[config:]
+file=${serverRoot}/conf/workers2.properties
+debug=0
+debugEnv=0
+
+[uriMap:]
+info=Maps the requests.
+debug=0
+
+[shm:]
+info=Scoreboard. Required for reconfiguration and status with multiprocess servers
+file=anonymous
+debug=0
+
+[workerEnv:]
+info=Global server options
+timing=0
+debug=0
+
+[lb:lb]
+info=Default load balancer.
+debug=0
+
+[channel.socket:localhost:8009]
+info=Ajp13 forwarding over socket
+debug=0
+tomcatId=localhost:8009
+
+[uri:/admin]
+info=Tomcat HTML based administration web application.
+debug=0
+
+[uri:/manager]
+info=A scriptable management web application for the Tomcat Web Server.
+debug=0
+
+[uri:/jsp-examples]
+info=JSP 2.0 Examples.
+debug=0
+
+[uri:/servlets-examples]
+info=Servlet 2.4 Examples.
+debug=0
+
+[uri:/*.jsp]
+info=JSP Extension mapping.
+debug=0
diff --git a/base/kra/shared/etc/init.d/pki-krad b/base/kra/shared/etc/init.d/pki-krad
new file mode 100755
index 000000000..fe3f888b1
--- /dev/null
+++ b/base/kra/shared/etc/init.d/pki-krad
@@ -0,0 +1,87 @@
+#!/bin/bash
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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-2010 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+# pki-krad Startup script pki-kra with tomcat6
+#
+# chkconfig: - 82 18
+# description: Data Recovery Manager (Tomcat 6.0)
+# processname: pki-krad
+# piddir: /var/run/pki/kra
+#
+
+PROG_NAME=`basename $0`
+SERVICE_NAME="pki-krad"
+SERVICE_PROG="/sbin/service"
+PKI_PATH="/usr/share/pki/kra"
+PKI_REGISTRY="/etc/sysconfig/pki/kra"
+PKI_TYPE="pki-kra"
+PKI_TOTAL_PORTS=6
+
+# Avoid using 'systemctl' for now
+SYSTEMCTL_SKIP_REDIRECT=1
+export SYSTEMCTL_SKIP_REDIRECT
+
+# Disallow 'others' the ability to 'write' to new files
+umask 00002
+
+command="$1"
+pki_instance="$2"
+
+# Source function library.
+. /etc/init.d/functions
+
+# Source the PKI function library
+. /usr/share/pki/scripts/functions
+
+# See how we were called.
+case $command in
+ status)
+ registry_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 ${default_error}
+ ;;
+ *)
+ echo "unknown action ($command)"
+ usage
+ echo "where valid instance names include:"
+ list_instances
+ exit ${default_error}
+ ;;
+esac
+
diff --git a/base/kra/shared/lib/systemd/system/pki-krad.target b/base/kra/shared/lib/systemd/system/pki-krad.target
new file mode 100644
index 000000000..b7027fc72
--- /dev/null
+++ b/base/kra/shared/lib/systemd/system/pki-krad.target
@@ -0,0 +1,8 @@
+[Unit]
+Description=PKI Key Recovery Authority Server
+After=syslog.target network.target
+
+[Install]
+WantedBy=multi-user.target
+
+
diff --git a/base/kra/shared/lib/systemd/system/pki-krad@.service b/base/kra/shared/lib/systemd/system/pki-krad@.service
new file mode 100644
index 000000000..3c4f177a9
--- /dev/null
+++ b/base/kra/shared/lib/systemd/system/pki-krad@.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=PKI Key Recovery Authority Server %i
+After=pki-krad.target
+BindTo=pki-krad.target
+
+[Service]
+Type=forking
+ExecStart=/usr/bin/pkicontrol start kra %i
+ExecStop=/usr/bin/pkicontrol stop kra %i
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/base/kra/shared/webapps/ROOT/WEB-INF/web.xml b/base/kra/shared/webapps/ROOT/WEB-INF/web.xml
new file mode 100644
index 000000000..59245836e
--- /dev/null
+++ b/base/kra/shared/webapps/ROOT/WEB-INF/web.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ Copyright 2004 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+ version="2.4">
+
+ <display-name>Welcome to Tomcat</display-name>
+ <description>
+ Welcome to Tomcat
+ </description>
+
+</web-app>
+
diff --git a/base/kra/shared/webapps/ROOT/index.jsp b/base/kra/shared/webapps/ROOT/index.jsp
new file mode 100644
index 000000000..4b2b3c60a
--- /dev/null
+++ b/base/kra/shared/webapps/ROOT/index.jsp
@@ -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.
+
+ Copyright (C) 2010 Red Hat, Inc.
+ All rights reserved.
+ --- END COPYRIGHT BLOCK --- -->
+<%
+ // establish acceptable schemes
+ final String HTTP_SCHEME = "http";
+ final String HTTPS_SCHEME = "https";
+
+ // establish known ports
+ final int EE_HTTP_PORT = [PKI_UNSECURE_PORT];
+ final int AGENT_HTTPS_PORT = [PKI_AGENT_SECURE_PORT];
+ final int EE_HTTPS_PORT = [PKI_EE_SECURE_PORT];
+ final int ADMIN_HTTPS_PORT = [PKI_ADMIN_SECURE_PORT];
+
+ // establish known paths
+ final String ADMIN_PATH = "/[PKI_SUBSYSTEM_TYPE]/services";
+ final String AGENT_PATH = "/[PKI_SUBSYSTEM_TYPE]/agent/[PKI_SUBSYSTEM_TYPE]";
+ final String ERROR_PATH = "/[PKI_SUBSYSTEM_TYPE]/404.html";
+
+ // retrieve scheme from request
+ String scheme = request.getScheme();
+
+ // retrieve client hostname on which the request was sent
+ String client_hostname = request.getServerName();
+
+ // retrieve client port number on which the request was sent
+ int client_port = request.getServerPort();
+
+ // retrieve server hostname on which the request was received
+ String server_hostname = request.getLocalName();
+
+ // retrieve server port number on which the request was received
+ int server_port = request.getLocalPort();
+
+ // uncomment the following lines to write to 'catalina.out'
+ //System.out.println( "scheme = '" + scheme + "'" );
+ //System.out.println( "client hostname = '" + client_hostname + "'" );
+ //System.out.println( "client port = '" + client_port + "'" );
+ //System.out.println( "server hostname = '" + server_hostname + "'" );
+ //System.out.println( "server port = '" + server_port + "'" );
+
+ // compose the appropriate URL
+ String URL = "";
+
+ if( scheme.equals( HTTP_SCHEME ) ) {
+ if( server_port == EE_HTTP_PORT ) {
+ // always redirect to secure admin 'services' port
+ scheme = HTTPS_SCHEME;
+ client_port = ADMIN_HTTPS_PORT;
+ URL = scheme + "://" + client_hostname + ":" + client_port + ADMIN_PATH;
+ } else {
+ // unknown HTTP server port: should never get here
+ URL = scheme + "://" + client_hostname + ":" + client_port + ERROR_PATH;
+
+ // uncomment the following line to write to 'catalina.out'
+ //System.out.println( "Unknown HTTP server port: '" + server_port + "'" );
+ }
+ } else if( scheme.equals( HTTPS_SCHEME ) ) {
+ if( server_port == AGENT_HTTPS_PORT ) {
+ URL = scheme + "://" + client_hostname + ":" + client_port + AGENT_PATH;
+ } else if( server_port == EE_HTTPS_PORT ) {
+ // always redirect to secure admin 'services' port
+ client_port = ADMIN_HTTPS_PORT;
+ URL = scheme + "://" + client_hostname + ":" + client_port + ADMIN_PATH;
+ } else if( server_port == ADMIN_HTTPS_PORT ) {
+ URL = scheme + "://" + client_hostname + ":" + client_port + ADMIN_PATH;
+ } else {
+ // unknown HTTPS server port: should never get here
+ URL = scheme + "://" + client_hostname + ":" + client_port + ERROR_PATH;
+
+ // uncomment the following line to write to 'catalina.out'
+ //System.out.println( "Unknown HTTPS server port: '" + server_port + "'" );
+ }
+ } else {
+ // unacceptable scheme: should never get here
+ URL = scheme + "://" + client_hostname + ":" + client_port + ERROR_PATH;
+
+ // uncomment the following line to write to 'catalina.out'
+ //System.out.println( "Unacceptable scheme: '" + scheme + "'" );
+ }
+
+ // respond (back to browser) with the appropriate redirected URL
+ response.sendRedirect( URL );
+%>
diff --git a/base/kra/shared/webapps/kra/WEB-INF/auth.properties b/base/kra/shared/webapps/kra/WEB-INF/auth.properties
new file mode 100644
index 000000000..a206aa9e4
--- /dev/null
+++ b/base/kra/shared/webapps/kra/WEB-INF/auth.properties
@@ -0,0 +1,16 @@
+# Restful API auth/authz mapping info
+#
+# Format:
+# <Rest API URL> = <ACL Resource ID>,<ACL resource operation>
+# ex: /kra/pki/key/retrieve = certServer.kra.pki.key.retrieve,execute
+
+/kra/pki/key/retrieve = certServer.kra.pki.key.retrieve,execute
+/kra/pki/keyrequests = certServer.kra.pki.keyrequests,read
+/kra/pki/keyrequest = certServer.kra.pki.keyrequest,read
+/kra/pki/keyrequest/archive = certServer.kra.pki.keyrequest.archive,execute
+/kra/pki/keyrequest/recover = certServer.kra.pki.keyrequest.recover,execute
+/kra/pki/keyrequest/approve = certServer.kra.pki.keyrequest.approve,execute
+/kra/pki/keyrequest/reject = certServer.kra.pki.keyrequest.reject,execute
+/kra/pki/keyrequest/cancel = certServer.kra.pki.keyrequest.cancel,execute
+/kra/pki/keys = certServer.kra.pki.keys,read
+/kra/pki/config/cert/transport = certServer.kra.pki.config.cert.transport,read
diff --git a/base/kra/shared/webapps/kra/WEB-INF/velocity.properties b/base/kra/shared/webapps/kra/WEB-INF/velocity.properties
new file mode 100644
index 000000000..2dfae4bca
--- /dev/null
+++ b/base/kra/shared/webapps/kra/WEB-INF/velocity.properties
@@ -0,0 +1,8 @@
+resource.loader = file
+file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
+file.resource.loader.path = [PKI_INSTANCE_PATH]/[PKI_WEBAPPS_NAME]/[PKI_SUBSYSTEM_TYPE]
+file.resource.loader.cache = true
+file.resource.loader.modificationCheckInterval = 2
+input.encoding=UTF-8
+output.encoding=UTF-8
+runtime.log.logsystem.class=org.apache.velocity.runtime.log.NullLogSystem
diff --git a/base/kra/shared/webapps/kra/WEB-INF/web.xml b/base/kra/shared/webapps/kra/WEB-INF/web.xml
new file mode 100644
index 000000000..c6e9934eb
--- /dev/null
+++ b/base/kra/shared/webapps/kra/WEB-INF/web.xml
@@ -0,0 +1,1115 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE web-app
+ PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "file:///usr/share/pki/setup/web-app_2_3.dtd">
+<web-app>
+
+ <filter>
+ <filter-name>AgentRequestFilter</filter-name>
+ <filter-class>com.netscape.cms.servlet.filter.AgentRequestFilter</filter-class>
+ <init-param>
+ <param-name>https_port</param-name>
+ <param-value>[PKI_AGENT_SECURE_PORT]</param-value>
+ </init-param>
+[PKI_OPEN_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>proxy_port</param-name>
+ <param-value>[PKI_PROXY_SECURE_PORT]</param-value>
+ </init-param>
+[PKI_CLOSE_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>active</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ </filter>
+
+ <filter>
+ <filter-name>AdminRequestFilter</filter-name>
+ <filter-class>com.netscape.cms.servlet.filter.AdminRequestFilter</filter-class>
+ <init-param>
+ <param-name>https_port</param-name>
+ <param-value>[PKI_ADMIN_SECURE_PORT]</param-value>
+ </init-param>
+[PKI_OPEN_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>proxy_port</param-name>
+ <param-value>[PKI_PROXY_SECURE_PORT]</param-value>
+ </init-param>
+[PKI_CLOSE_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>active</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ </filter>
+
+ <filter>
+ <filter-name>EERequestFilter</filter-name>
+ <filter-class>com.netscape.cms.servlet.filter.EERequestFilter</filter-class>
+ <init-param>
+ <param-name>http_port</param-name>
+ <param-value>[PKI_UNSECURE_PORT]</param-value>
+ </init-param>
+ <init-param>
+ <param-name>https_port</param-name>
+ <param-value>[PKI_EE_SECURE_PORT]</param-value>
+ </init-param>
+[PKI_OPEN_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>proxy_port</param-name>
+ <param-value>[PKI_PROXY_SECURE_PORT]</param-value>
+ </init-param>
+ <init-param>
+ <param-name>proxy_http_port</param-name>
+ <param-value>[PKI_PROXY_UNSECURE_PORT]</param-value>
+ </init-param>
+[PKI_CLOSE_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>active</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ </filter>
+
+ <servlet>
+ <servlet-name>csadmin-wizard</servlet-name>
+ <servlet-class>com.netscape.cms.servlet.wizard.WizardServlet</servlet-class>
+ <init-param>
+ <param-name>properties</param-name>
+ <param-value>/WEB-INF/velocity.properties</param-value>
+ </init-param>
+ <init-param>
+ <param-name>name</param-name>
+ <param-value>DRM Setup Wizard</param-value>
+ </init-param>
+ <init-param>
+ <param-name>panels</param-name>
+ <param-value>welcome=com.netscape.cms.servlet.csadmin.WelcomePanel,module=com.netscape.cms.servlet.csadmin.ModulePanel,confighsmlogin=com.netscape.cms.servlet.csadmin.ConfigHSMLoginPanel,securitydomain=com.netscape.cms.servlet.csadmin.SecurityDomainPanel,securitydomain=com.netscape.cms.servlet.csadmin.DisplayCertChainPanel,subsystem=com.netscape.cms.servlet.csadmin.CreateSubsystemPanel,restorekeys=com.netscape.cms.servlet.csadmin.RestoreKeyCertPanel,databasepanel=com.netscape.cms.servlet.csadmin.DatabasePanel,sizepanel=com.netscape.cms.servlet.csadmin.SizePanel,namepanel=com.netscape.cms.servlet.csadmin.NamePanel,certrequestpanel=com.netscape.cms.servlet.csadmin.CertRequestPanel,backupkeys=com.netscape.cms.servlet.csadmin.BackupKeyCertPanel,savepk12=com.netscape.cms.servlet.csadmin.SavePKCS12Panel,adminpanel=com.netscape.cms.servlet.csadmin.AdminPanel,importadmincertpanel=com.netscape.cms.servlet.csadmin.ImportAdminCertPanel,donepanel=com.netscape.cms.servlet.csadmin.DonePanel</param-value>
+ </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name>csadmin-login</servlet-name>
+ <servlet-class>com.netscape.cms.servlet.csadmin.LoginServlet</servlet-class>
+ <init-param>
+ <param-name>properties</param-name>
+ <param-value>/WEB-INF/velocity.properties</param-value>
+ </init-param>
+ </servlet>
+
+
+ <servlet>
+ <servlet-name> kraKRADisplayBySerialForRecovery </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.key.DisplayBySerialForRecovery </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/kra/displayBySerialForRecovery.template </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraKRADisplayBySerialForRecovery </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.kra.key </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraGetConfigEntries </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.GetConfigEntries </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraGetConfigEntries </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> TokenAuth </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.clone.configuration.GetConfigEntries </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraKRAGrantRecovery </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.key.GrantRecovery </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/kra/grantRecovery.template</param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraKRAGrantRecovery </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.kra.key </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraKRAGrantAsyncRecovery </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.key.GrantAsyncRecovery </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/kra/grantAsyncRecovery.template</param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraKRAGrantAsyncRecovery </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.kra.key </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraports </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.PortsServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraports </param-value> </init-param>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraKRADisplayTransport </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.key.DisplayTransport </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraKRADisplayTransport </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.kra.certificate.transport </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraRegisterUser </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.RegisterUser </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraRegisterUser </param-value> </init-param>
+ <init-param><param-name> GroupName </param-name>
+ <param-value> Data Recovery Manager Agents </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> TokenAuth </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.kra.registerUser </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraGetTransportCert </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.GetTransportCert </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraGetTransportCert </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> TokenAuth </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.kra.getTransportCert </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraKRARecoverBySerial </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.key.RecoverBySerial </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/kra/recoverBySerial.template</param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraKRARecoverBySerial </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.kra.key </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraDynamicVariables </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.DynamicVariablesServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraDynamicVariables </param-value> </init-param>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> dynamicVariables </param-name>
+ <param-value> serverdate=serverdate(),subsystemname=subsystemname(),http=http(),authmgrs=authmgrs(),clacrlurl=clacrlurl() </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraheader </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.IndexServlet </servlet-class>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/header.template</param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraheader </param-value> </init-param>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> template </param-name>
+ <param-value> /agent/header.template </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraTokenKeyRecovery </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.connector.TokenKeyRecoveryServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraTokenKeyRecovery </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.kra.TokenKeyRecovery </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraSrchRecoverKey </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.DisplayHtmlServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> htmlPath </param-name>
+ <param-value> /agent/kra/SrchRecoverKey.html </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/kra/srchKeyForRecovery.template</param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraSrchRecoverKey </param-value> </init-param>
+ <init-param><param-name> unauthorizedTemplate </param-name>
+ <param-value> /agent/kra/GenUnauthorized.template </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraConnector </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.connector.ConnectorServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraConnector </param-value> </init-param>
+ <init-param><param-name> RequestEncoder </param-name>
+ <param-value> com.netscape.cmscore.connector.HttpRequestEncoder </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.kra.connector </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraSrchKey </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.DisplayHtmlServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> htmlPath </param-name>
+ <param-value> /agent/kra/SrchKey.html </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/kra/srchKey.template</param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraSrchKey </param-value> </init-param>
+ <init-param><param-name> unauthorizedTemplate </param-name>
+ <param-value> /agent/kra/GenUnauthorized.template </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraListRequests </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.DisplayHtmlServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> htmlPath </param-name>
+ <param-value> /agent/kra/ListRequests.html </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/kra/ListRequests.template</param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraListRequests </param-value> </init-param>
+ <init-param><param-name> unauthorizedTemplate </param-name>
+ <param-value> /agent/kra/GenUnauthorized.template </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraGenerateKeyPair </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.connector.GenerateKeyPairServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraGenerateKeyPair </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.kra.GenerateKeyPair </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraindex </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.IndexServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraindex </param-value> </init-param>
+ <init-param><param-name> template </param-name>
+ <param-value> index.template </param-value> </init-param>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraKRAGetApprovalStatus </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.key.GetApprovalStatus </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/kra/getApprovalStatus.template</param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraKRAGetApprovalStatus </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.kra.request.status </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraKRAProcessReq </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.request.ProcessReq </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> parser </param-name>
+ <param-value> KeyReqParser.PARSER </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/kra/processReq.template</param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraKRAProcessReq </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.kra.request </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraKRAExamineRecovery </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.key.ExamineRecovery </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/kra/examineRecovery.template</param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraKRAExamineRecovery </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.kra.key </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraKRASrchKey </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.key.SrchKey </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/kra/srchKey.template</param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraKRASrchKey </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.kra.keys </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraKRAGetPk12 </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.key.GetPk12 </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraKRAGetPk12 </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.kra.key </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraKRAGetAsyncPk12 </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.key.GetAsyncPk12 </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraKRAGetAsyncPk12 </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.kra.key </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraGrantRecovery </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.DisplayHtmlServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> htmlPath </param-name>
+ <param-value> /agent/kra/GrantRecovery.html </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/kra/grantRecovery.template</param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraGrantRecovery </param-value> </init-param>
+ <init-param><param-name> unauthorizedTemplate </param-name>
+ <param-value> /agent/kra/GenUnauthorized.template </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraKRASrchKeyForRecovery </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.key.SrchKeyForRecovery </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/kra/srchKeyForRecovery.template</param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraKRASrchKeyForRecovery </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.kra.keys </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> krakraqueryReq </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.request.QueryReq </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> parser </param-name>
+ <param-value> CertReqParser.NODETAIL_PARSER </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/kra/queryReq.template</param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> krakraqueryReq </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.kra.requests </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraKRADisplayBySerial </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.key.DisplayBySerial </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/kra/displayBySerial.template</param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraKRADisplayBySerial </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.kra.key </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> krapolicy </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.PolicyAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> krapolicy </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ </servlet>
+
+<!--
+ <servlet>
+ <servlet-name> krajobsScheduler </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.JobsAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> krajobsScheduler </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+-->
+
+ <servlet>
+ <servlet-name> kraauths </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.AuthAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraauths </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> krastart </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.CMSStartServlet </servlet-class>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> cfgPath </param-name>
+ <param-value> [PKI_INSTANCE_PATH]/conf/CS.cfg </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> krastart </param-value> </init-param>
+ <load-on-startup> 1 </load-on-startup>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraacl </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.ACLAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraacl </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraug </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.UsrGrpAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraug </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+
+ <servlet>
+ <servlet-name> kraserver </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.CMSAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraserver </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> krakra </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.KRAAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> krakra </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kralog </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.LogAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> kralog </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> services </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.MainPageServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authorityId </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> services </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /services.template </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraUpdateNumberRange </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.UpdateNumberRange </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraUpdateNumberRange </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> TokenAuth </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.clone.configuration.UpdateNumberRange </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraDownloadPKCS12 </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.DownloadPKCS12 </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraDownloadPKCS12 </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> TokenAuth </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.clone.configuration </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> kraGetTokenInfo </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.GetTokenInfo </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> kra </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> kraGetTokenInfo </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <context-param>
+ <param-name>resteasy.scan</param-name>
+ <param-value>true</param-value>
+ </context-param>
+
+ <context-param>
+ <param-name>resteasy.servlet.mapping.prefix</param-name>
+ <param-value>/pki</param-value>
+ </context-param>
+
+ <context-param>
+ <param-name>resteasy.resource.method-interceptors</param-name>
+ <param-value>
+ org.jboss.resteasy.core.ResourceMethodSecurityInterceptor
+ </param-value>
+ </context-param>
+
+ <servlet>
+ <servlet-name>Resteasy</servlet-name>
+ <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
+ </servlet>
+
+[PKI_OPEN_SEPARATE_PORTS_WEB_COMMENT]
+ <filter-mapping>
+ <filter-name> AgentRequestFilter </filter-name>
+ <url-pattern> /agent/* </url-pattern>
+ </filter-mapping>
+
+ <filter-mapping>
+ <filter-name> AdminRequestFilter </filter-name>
+ <url-pattern> /admin/* </url-pattern>
+ <url-pattern> /auths </url-pattern>
+ <url-pattern> /server </url-pattern>
+ <url-pattern> /log </url-pattern>
+ <url-pattern> /ug </url-pattern>
+ <url-pattern> /acl </url-pattern>
+ <url-pattern> /kra </url-pattern>
+ </filter-mapping>
+
+ <filter-mapping>
+ <filter-name> EERequestFilter </filter-name>
+ <url-pattern> /ee/* </url-pattern>
+ </filter-mapping>
+[PKI_CLOSE_SEPARATE_PORTS_WEB_COMMENT]
+
+ <servlet-mapping>
+ <servlet-name>Resteasy</servlet-name>
+ <url-pattern>/pki/*</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraserver </servlet-name>
+ <url-pattern> /server </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> krakra </servlet-name>
+ <url-pattern> /kra </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kralog </servlet-name>
+ <url-pattern> /log </url-pattern>
+ </servlet-mapping>
+
+
+ <servlet-mapping>
+ <servlet-name> kraug </servlet-name>
+ <url-pattern> /ug </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> krastart </servlet-name>
+ <url-pattern> /start </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraacl </servlet-name>
+ <url-pattern> /acl </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraauths </servlet-name>
+ <url-pattern> /auths </url-pattern>
+ </servlet-mapping>
+
+<!--
+ <servlet-mapping>
+ <servlet-name> krajobsScheduler </servlet-name>
+ <url-pattern> /jobsScheduler </url-pattern>
+ </servlet-mapping>
+-->
+
+ <servlet-mapping>
+ <servlet-name> krapolicy </servlet-name>
+ <url-pattern> /krapolicy </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraKRADisplayBySerialForRecovery </servlet-name>
+ <url-pattern> /agent/kra/displayBySerialForRecovery </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraKRAGrantRecovery </servlet-name>
+ <url-pattern> /agent/kra/grantRecovery </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraKRAGrantAsyncRecovery </servlet-name>
+ <url-pattern> /agent/kra/grantAsyncRecovery </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraports </servlet-name>
+ <url-pattern> /ee/kra/ports </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraKRADisplayTransport </servlet-name>
+ <url-pattern> /agent/kra/displayTransportCert </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraKRARecoverBySerial </servlet-name>
+ <url-pattern> /agent/kra/recoverBySerial </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraDynamicVariables </servlet-name>
+ <url-pattern> /dynamicVars.js </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraheader </servlet-name>
+ <url-pattern> /agent/header </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraTokenKeyRecovery </servlet-name>
+ <url-pattern> /agent/kra/TokenKeyRecovery </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraSrchRecoverKey </servlet-name>
+ <url-pattern> /agent/kra/srchRecoverKey.html </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraConnector </servlet-name>
+ <url-pattern> /agent/kra/connector </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraSrchKey </servlet-name>
+ <url-pattern> /agent/kra/srchKey.html </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraListRequests </servlet-name>
+ <url-pattern> /agent/kra/listRequests.html </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraGenerateKeyPair </servlet-name>
+ <url-pattern> /agent/kra/GenerateKeyPair </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraindex </servlet-name>
+ <url-pattern> /index </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraKRAGetApprovalStatus </servlet-name>
+ <url-pattern> /agent/kra/getApprovalStatus </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraKRAProcessReq </servlet-name>
+ <url-pattern> /agent/kra/processReq </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraKRAExamineRecovery </servlet-name>
+ <url-pattern> /agent/kra/examineRecovery </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraKRASrchKey </servlet-name>
+ <url-pattern> /agent/kra/srchKey </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraKRAGetPk12 </servlet-name>
+ <url-pattern> /agent/kra/getPk12 </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraKRAGetAsyncPk12 </servlet-name>
+ <url-pattern> /agent/kra/getAsyncPk12 </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraGrantRecovery </servlet-name>
+ <url-pattern> /agent/kra/grantRecovery.html </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraKRASrchKeyForRecovery </servlet-name>
+ <url-pattern> /agent/kra/srchKeyForRecovery </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> krakraqueryReq </servlet-name>
+ <url-pattern> /agent/kra/queryReq </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraKRADisplayBySerial </servlet-name>
+ <url-pattern> /agent/kra/displayBySerial </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>csadmin-login</servlet-name>
+ <url-pattern>/admin/console/config/login</url-pattern>
+ </servlet-mapping>
+
+
+ <servlet-mapping>
+ <servlet-name> kraRegisterUser </servlet-name>
+ <url-pattern> /admin/kra/registerUser </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraGetTransportCert </servlet-name>
+ <url-pattern> /admin/kra/getTransportCert </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>csadmin-wizard</servlet-name>
+ <url-pattern>/admin/console/config/wizard</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraGetConfigEntries </servlet-name>
+ <url-pattern> /admin/kra/getConfigEntries </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> services </servlet-name>
+ <url-pattern> /services </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraUpdateNumberRange </servlet-name>
+ <url-pattern> /ee/kra/updateNumberRange </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraDownloadPKCS12 </servlet-name>
+ <url-pattern> /admin/console/config/savepkcs12 </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> kraGetTokenInfo </servlet-name>
+ <url-pattern> /ee/kra/getTokenInfo </url-pattern>
+ </servlet-mapping>
+
+ <!-- ==================== Default Session Configuration =============== -->
+ <!-- You can set the default session timeout (in minutes) for all newly -->
+ <!-- created sessions by modifying the value below. -->
+ <!-- -->
+ <!-- To disable session timeouts for this instance, set a value of -1. -->
+
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+
+<!-- Default login configuration uses form-based authentication -->
+<!-- Security Constraint for agent access to the Security Data Rest Interface -->
+
+<!-- Uncomment to activate PKIJNDI realm as in conf/server.xml -->
+<!--
+<security-constraint>
+ <display-name>KRA Top Level Constraint</display-name>
+ <web-resource-collection>
+ <web-resource-name>KRA Protected Area</web-resource-name>
+ <url-pattern>/pki/*
+ </url-pattern>
+ </web-resource-collection>
+ <user-data-constraint>
+ <transport-guarantee>CONFIDENTIAL</transport-guarantee>
+ </user-data-constraint>
+ <auth-constraint>
+ <role-name>*</role-name>
+ </auth-constraint>
+</security-constraint>
+-->
+
+<!-- Security Constraint to deny certain http methods for key/retrieve -->
+<!-- Uncomment to activate PKIJNDI realm as in conf/server.xml -->
+<!--
+<security-constraint>
+<display-name>Key forbidden</display-name>
+<web-resource-collection>
+ <web-resource-name>Key forbidden</web-resource-name>
+ <url-pattern>/pki/key/retrieve</url-pattern>
+ <http-method>GET</http-method>
+ <http-method>PUT</http-method>
+ <http-method>DELETE</http-method>
+</web-resource-collection>
+<auth-constraint/>
+</security-constraint>
+-->
+
+<!-- Security Constraint to deny certain http methods for keyrequest/* -->
+<!-- Uncomment to activate PKIJNDI realm as in conf/server.xml -->
+
+<!--
+<security-constraint>
+<display-name>KeyRequest forbidden</display-name>
+<web-resource-collection>
+ <web-resource-name>KeyRequest forbidden</web-resource-name>
+ <url-pattern>/pki/keyrequest/archive</url-pattern>
+ <url-pattern>/pki/keyrequest/recover</url-pattern>
+ <url-pattern>/pki/keyrequest/approve/*</url-pattern>
+ <url-pattern>/pki/keyrequest/reject/*</url-pattern>
+ <url-pattern>/pki/keyrequest/cancel/*</url-pattern>
+ <http-method>GET</http-method>
+ <http-method>PUT</http-method>
+ <http-method>DELETE</http-method>
+</web-resource-collection>
+<auth-constraint/>
+</security-constraint>
+-->
+
+
+<!-- Customized SSL Client auth login config
+ uncomment to activate PKIJNDI realm as in conf/server.xml
+-->
+
+<!--
+
+<login-config>
+ <realm-name>PKIJNDIRealm</realm-name>
+ <auth-method>CLIENT-CERT</auth-method>
+ <realm-name>Client Cert Protected Area</realm-name>
+</login-config>
+
+<security-role>
+ <role-name>*</role-name>
+</security-role>
+
+-->
+
+</web-app>
diff --git a/base/kra/src/CMakeLists.txt b/base/kra/src/CMakeLists.txt
new file mode 100644
index 000000000..df7e1929b
--- /dev/null
+++ b/base/kra/src/CMakeLists.txt
@@ -0,0 +1,109 @@
+project(pki-kra_java Java)
+
+# '/usr/share/java/pki' jars
+find_file(PKI_CERTSRV_JAR
+ NAMES
+ pki-certsrv.jar
+ PATHS
+ /usr/share/java/pki
+)
+
+find_file(PKI_CMS_JAR
+ NAMES
+ pki-cms.jar
+ PATHS
+ /usr/share/java/pki
+)
+
+find_file(PKI_CMSCORE_JAR
+ NAMES
+ pki-cmscore.jar
+ PATHS
+ /usr/share/java/pki
+)
+
+find_file(PKI_CMSUTIL_JAR
+ NAMES
+ pki-cmsutil.jar
+ PATHS
+ /usr/share/java/pki
+)
+
+find_file(PKI_NSUTIL_JAR
+ NAMES
+ pki-nsutil.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java/pki
+)
+
+
+# '/usr/share/java' jars
+find_file(LDAPJDK_JAR
+ NAMES
+ ldapjdk.jar
+ PATHS
+ /usr/share/java
+)
+
+
+# '${JAVA_LIB_INSTALL_DIR}' jars
+find_file(JSS_JAR
+ NAMES
+ jss4.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+)
+
+find_file(COMMONS_CODEC_JAR
+ NAMES
+ commons-codec.jar
+ PATHS
+ /usr/share/java
+)
+
+find_file(SYMKEY_JAR
+ NAMES
+ symkey.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+)
+
+
+# identify java sources
+set(pki-kra_java_SRCS
+ com/netscape/kra/KeyRecoveryAuthority.java
+ com/netscape/kra/EnrollmentService.java
+ com/netscape/kra/RecoveryService.java
+ com/netscape/kra/SecurityDataRecoveryService.java
+ com/netscape/kra/TokenKeyRecoveryService.java
+ com/netscape/kra/EncryptionUnit.java
+ com/netscape/kra/KRAService.java
+ com/netscape/kra/NetkeyKeygenService.java
+ com/netscape/kra/SecurityDataService.java
+ com/netscape/kra/KRANotify.java
+ com/netscape/kra/KRAPolicy.java
+ com/netscape/kra/TransportKeyUnit.java
+ com/netscape/kra/StorageKeyUnit.java
+ com/netscape/kra/ArchiveOptions.java
+)
+
+
+# set classpath
+set(CMAKE_JAVA_INCLUDE_PATH
+ ${PKI_CERTSRV_JAR} ${PKI_CMS_JAR} ${PKI_CMSCORE_JAR}
+ ${PKI_CMSUTIL_JAR} ${PKI_NSUTIL_JAR}
+ ${LDAPJDK_JAR}
+ ${JSS_JAR} ${COMMONS_CODEC_JAR} ${SYMKEY_JAR})
+
+
+# set version
+set(CMAKE_JAVA_TARGET_VERSION ${APPLICATION_VERSION})
+
+
+# build pki-kra.jar
+add_jar(pki-kra ${pki-kra_java_SRCS})
+add_dependencies(pki-kra symkey pki-nsutil pki-cmsutil pki-certsrv pki-cms pki-cmscore)
+install_jar(pki-kra ${JAVA_JAR_INSTALL_DIR}/pki)
+set(PKI_KRA_JAR ${pki-kra_JAR_FILE} CACHE INTERNAL "pki-kra jar file")
+
diff --git a/base/kra/src/com/netscape/kra/ArchiveOptions.java b/base/kra/src/com/netscape/kra/ArchiveOptions.java
new file mode 100644
index 000000000..c4650f17e
--- /dev/null
+++ b/base/kra/src/com/netscape/kra/ArchiveOptions.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.kra;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.asn1.BIT_STRING;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.pkix.cms.EncryptedContentInfo;
+import org.mozilla.jss.pkix.cms.EnvelopedData;
+import org.mozilla.jss.pkix.cms.RecipientInfo;
+import org.mozilla.jss.pkix.crmf.EncryptedKey;
+import org.mozilla.jss.pkix.crmf.EncryptedValue;
+import org.mozilla.jss.pkix.crmf.PKIArchiveOptions;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+
+class ArchiveOptions {
+ private String mSymmAlgOID = null;
+ private byte mSymmAlgParams[] = null;
+ private byte mEncSymmKey[] = null;
+ private byte mEncValue[] = null;
+
+ public ArchiveOptions(PKIArchiveOptions opts) throws EBaseException {
+ try {
+ EncryptedKey key = opts.getEncryptedKey();
+ ANY enveloped_val = null;
+ EncryptedValue val = null;
+ AlgorithmIdentifier symmAlg = null;
+
+ if (key.getType() == org.mozilla.jss.pkix.crmf.EncryptedKey.ENVELOPED_DATA) {
+ CMS.debug("EnrollService: ArchiveOptions() EncryptedKey type= ENVELOPED_DATA");
+ // this is the new RFC4211 EncryptedKey that should
+ // have EnvelopedData to replace the deprecated EncryptedValue
+ enveloped_val = key.getEnvelopedData();
+ byte[] env_b = enveloped_val.getEncoded();
+ EnvelopedData.Template env_template = new EnvelopedData.Template();
+ EnvelopedData env_data =
+ (EnvelopedData) env_template.decode(new ByteArrayInputStream(env_b));
+ EncryptedContentInfo eCI = env_data.getEncryptedContentInfo();
+ symmAlg = eCI.getContentEncryptionAlgorithm();
+ mSymmAlgOID = symmAlg.getOID().toString();
+ mSymmAlgParams =
+ ((OCTET_STRING) ((ANY) symmAlg.getParameters()).decodeWith(OCTET_STRING.getTemplate()))
+ .toByteArray();
+
+ SET recipients = env_data.getRecipientInfos();
+ if (recipients.size() <= 0) {
+ CMS.debug("EnrollService: ArchiveOptions() - missing recipient information ");
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE",
+ "[PKIArchiveOptions] missing recipient information "));
+ }
+ //check recpient - later
+ //we only handle one recipient here anyways. so, either the key
+ //can be decrypted or it can't. No risk here.
+ RecipientInfo ri = (RecipientInfo) recipients.elementAt(0);
+ OCTET_STRING key_o = ri.getEncryptedKey();
+ mEncSymmKey = key_o.toByteArray();
+
+ OCTET_STRING oString = eCI.getEncryptedContent();
+ BIT_STRING encVal = new BIT_STRING(oString.toByteArray(), 0);
+ mEncValue = encVal.getBits();
+ CMS.debug("EnrollService: ArchiveOptions() EncryptedKey type= ENVELOPED_DATA done");
+ } else if (key.getType() == org.mozilla.jss.pkix.crmf.EncryptedKey.ENCRYPTED_VALUE) {
+ CMS.debug("EnrollService: ArchiveOptions() EncryptedKey type= ENCRYPTED_VALUE");
+ // this is deprecated: EncryptedValue
+ val = key.getEncryptedValue();
+ symmAlg = val.getSymmAlg();
+ mSymmAlgOID = symmAlg.getOID().toString();
+ mSymmAlgParams =
+ ((OCTET_STRING) ((ANY) symmAlg.getParameters()).decodeWith(OCTET_STRING.getTemplate()))
+ .toByteArray();
+ BIT_STRING encSymmKey = val.getEncSymmKey();
+
+ mEncSymmKey = encSymmKey.getBits();
+ BIT_STRING encVal = val.getEncValue();
+
+ mEncValue = encVal.getBits();
+ CMS.debug("EnrollService: ArchiveOptions() EncryptedKey type= ENCRYPTED_VALUE done");
+ } else {
+ CMS.debug("EnrollService: ArchiveOptions() invalid EncryptedKey type");
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", "[PKIArchiveOptions] type "
+ + key.getType()));
+ }
+
+ } catch (InvalidBERException e) {
+ CMS.debug("EnrollService: ArchiveOptions(): " + e.toString());
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE",
+ "[PKIArchiveOptions]" + e.toString()));
+ } catch (IOException e) {
+ CMS.debug("EnrollService: ArchiveOptions(): " + e.toString());
+ throw new EBaseException("ArchiveOptions() exception caught: " +
+ e.toString());
+ } catch (Exception e) {
+ CMS.debug("EnrollService: ArchiveOptions(): " + e.toString());
+ throw new EBaseException("ArchiveOptions() exception caught: " +
+ e.toString());
+ }
+
+ }
+
+ static public ArchiveOptions toArchiveOptions(byte options[]) throws
+ EBaseException {
+ ByteArrayInputStream bis = new ByteArrayInputStream(options);
+ PKIArchiveOptions archOpts = null;
+
+ try {
+ archOpts = (PKIArchiveOptions)
+ (new PKIArchiveOptions.Template()).decode(bis);
+ } catch (Exception e) {
+ throw new EBaseException("Failed to decode input PKIArchiveOptions.");
+ }
+
+ return new ArchiveOptions(archOpts);
+
+ }
+
+ public String getSymmAlgOID() {
+ return mSymmAlgOID;
+ }
+
+ public byte[] getSymmAlgParams() {
+ return mSymmAlgParams;
+ }
+
+ public byte[] getEncSymmKey() {
+ return mEncSymmKey;
+ }
+
+ public byte[] getEncValue() {
+ return mEncValue;
+ }
+}
diff --git a/base/kra/src/com/netscape/kra/EncryptionUnit.java b/base/kra/src/com/netscape/kra/EncryptionUnit.java
new file mode 100644
index 000000000..946f57613
--- /dev/null
+++ b/base/kra/src/com/netscape/kra/EncryptionUnit.java
@@ -0,0 +1,741 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.kra;
+
+import java.io.CharConversionException;
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+import org.mozilla.jss.crypto.BadPaddingException;
+import org.mozilla.jss.crypto.Cipher;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.EncryptionAlgorithm;
+import org.mozilla.jss.crypto.IVParameterSpec;
+import org.mozilla.jss.crypto.IllegalBlockSizeException;
+import org.mozilla.jss.crypto.KeyGenAlgorithm;
+import org.mozilla.jss.crypto.KeyWrapAlgorithm;
+import org.mozilla.jss.crypto.KeyWrapper;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.crypto.SymmetricKey;
+import org.mozilla.jss.crypto.TokenException;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.security.IEncryptionUnit;
+import com.netscape.cmscore.util.Debug;
+
+/**
+ * A class represents the transport key pair. This key pair
+ * is used to protected EE's private key in transit.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+@SuppressWarnings("deprecation")
+public abstract class EncryptionUnit implements IEncryptionUnit {
+
+ /* Establish one constant IV for base class, to be used for
+ internal operations. Constant IV acceptable for symmetric keys.
+ */
+ private byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
+ protected IVParameterSpec IV = null;
+
+ public EncryptionUnit() {
+ CMS.debug("EncryptionUnit.EncryptionUnit this: " + this.toString());
+
+ IV = new IVParameterSpec(iv);
+ }
+
+ public abstract CryptoToken getToken();
+
+ public abstract CryptoToken getInternalToken();
+
+ public abstract PublicKey getPublicKey();
+
+ public abstract PrivateKey getPrivateKey();
+
+ /**
+ * Protects the private key so that it can be stored in
+ * internal database.
+ */
+ public byte[] encryptInternalPrivate(byte priKey[])
+ throws EBaseException {
+ try {
+ CMS.debug("EncryptionUnit.encryptInternalPrivate");
+ CryptoToken internalToken = getInternalToken();
+
+ // (1) generate session key
+ org.mozilla.jss.crypto.KeyGenerator kg =
+ internalToken.getKeyGenerator(KeyGenAlgorithm.DES3);
+ SymmetricKey sk = kg.generate();
+
+ // (2) wrap private key with session key
+ Cipher cipher = internalToken.getCipherContext(
+ EncryptionAlgorithm.DES3_CBC_PAD);
+
+ cipher.initEncrypt(sk, IV);
+ byte pri[] = cipher.doFinal(priKey);
+
+ // (3) wrap session with transport public
+ KeyWrapper rsaWrap = internalToken.getKeyWrapper(
+ KeyWrapAlgorithm.RSA);
+
+ rsaWrap.initWrap(getPublicKey(), null);
+ byte session[] = rsaWrap.wrap(sk);
+
+ // use MY own structure for now:
+ // SEQUENCE {
+ // encryptedSession OCTET STRING,
+ // encryptedPrivate OCTET STRING
+ // }
+
+ DerOutputStream tmp = new DerOutputStream();
+ DerOutputStream out = new DerOutputStream();
+
+ tmp.putOctetString(session);
+ tmp.putOctetString(pri);
+ out.write(DerValue.tag_Sequence, tmp);
+
+ return out.toByteArray();
+ } catch (TokenException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_INTERNAL", e.toString()));
+ Debug.trace("EncryptionUnit::encryptInternalPrivate " + e.toString());
+ return null;
+ } catch (NoSuchAlgorithmException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_INTERNAL", e.toString()));
+ Debug.trace("EncryptionUnit::encryptInternalPrivate " + e.toString());
+ return null;
+ } catch (CharConversionException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_INTERNAL", e.toString()));
+ Debug.trace("EncryptionUnit::encryptInternalPrivate " + e.toString());
+ return null;
+ } catch (InvalidAlgorithmParameterException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_INTERNAL", e.toString()));
+ Debug.trace("EncryptionUnit::encryptInternalPrivate " + e.toString());
+ return null;
+ } catch (InvalidKeyException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_INTERNAL", e.toString()));
+ Debug.trace("EncryptionUnit::encryptInternalPrivate " + e.toString());
+ return null;
+ } catch (BadPaddingException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_INTERNAL", e.toString()));
+ Debug.trace("EncryptionUnit::encryptInternalPrivate " + e.toString());
+ return null;
+ } catch (IllegalBlockSizeException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_INTERNAL", e.toString()));
+ Debug.trace("EncryptionUnit::encryptInternalPrivate " + e.toString());
+ return null;
+ } catch (IOException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_INTERNAL", e.toString()));
+ Debug.trace("EncryptionUnit::encryptInternalPrivate " + e.toString());
+ return null;
+ } catch (Exception e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_INTERNAL", e.toString()));
+ Debug.trace("EncryptionUnit::encryptInternalPrivate " + e.toString());
+ return null;
+ }
+ }
+
+ public byte[] wrap(PrivateKey privKey) throws EBaseException {
+ return _wrap(privKey,null);
+ }
+
+ public byte[] wrap(SymmetricKey symmKey) throws EBaseException {
+ return _wrap(null,symmKey);
+ }
+ /**
+ * External unwrapping. Unwraps the data using
+ * the transport private key.
+ */
+ public SymmetricKey unwrap_sym(byte encSymmKey[], SymmetricKey.Usage usage) {
+ try {
+ CryptoToken token = getToken();
+
+ // (1) unwrap the session
+ PrivateKey priKey = getPrivateKey();
+ String priKeyAlgo = priKey.getAlgorithm();
+ CMS.debug("EncryptionUnit::unwrap_sym() private key algo: " + priKeyAlgo);
+ KeyWrapper keyWrapper = null;
+ if (priKeyAlgo.equals("EC")) {
+ keyWrapper = token.getKeyWrapper(KeyWrapAlgorithm.AES_ECB);
+ keyWrapper.initUnwrap(priKey, null);
+ } else {
+ keyWrapper = token.getKeyWrapper(KeyWrapAlgorithm.RSA);
+ keyWrapper.initUnwrap(priKey, null);
+ }
+ SymmetricKey sk = keyWrapper.unwrapSymmetric(encSymmKey,
+ SymmetricKey.DES3, usage,
+ 0);
+ CMS.debug("EncryptionUnit::unwrap_sym() unwrapped on slot: "
+ + token.getName());
+ return sk;
+ } catch (Exception e) {
+ CMS.debug("EncryptionUnit::unwrap_sym() error:" +
+ e.toString());
+ return null;
+ }
+ }
+
+ public SymmetricKey unwrap_sym(byte encSymmKey[]) {
+ return unwrap_sym(encSymmKey, SymmetricKey.Usage.WRAP);
+ }
+
+ public SymmetricKey unwrap_encrypt_sym(byte encSymmKey[]) {
+ return unwrap_sym(encSymmKey, SymmetricKey.Usage.ENCRYPT);
+ }
+
+ /**
+ * Decrypts the user private key.
+ */
+ public byte[] decryptExternalPrivate(byte encSymmKey[],
+ String symmAlgOID, byte symmAlgParams[],
+ byte encValue[])
+ throws EBaseException {
+ try {
+
+ CMS.debug("EncryptionUnit.decryptExternalPrivate");
+ CryptoToken token = getToken();
+
+ // (1) unwrap the session
+ KeyWrapper rsaWrap = token.getKeyWrapper(
+ KeyWrapAlgorithm.RSA);
+
+ rsaWrap.initUnwrap(getPrivateKey(), null);
+ SymmetricKey sk = rsaWrap.unwrapSymmetric(encSymmKey,
+ SymmetricKey.DES3, SymmetricKey.Usage.DECRYPT,
+ 0);
+
+ // (2) unwrap the pri
+ Cipher cipher = token.getCipherContext(
+ EncryptionAlgorithm.DES3_CBC_PAD // XXX
+ );
+
+ cipher.initDecrypt(sk, new IVParameterSpec(
+ symmAlgParams));
+ return cipher.doFinal(encValue);
+ } catch (IllegalBlockSizeException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_EXTERNAL", e.toString()));
+ Debug.trace("EncryptionUnit::decryptExternalPrivate " + e.toString());
+ return null;
+ } catch (BadPaddingException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_EXTERNAL", e.toString()));
+ Debug.trace("EncryptionUnit::decryptExternalPrivate " + e.toString());
+ return null;
+ } catch (TokenException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_EXTERNAL", e.toString()));
+ Debug.trace("EncryptionUnit::decryptExternalPrivate " + e.toString());
+ return null;
+ } catch (NoSuchAlgorithmException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_EXTERNAL", e.toString()));
+ Debug.trace("EncryptionUnit::decryptExternalPrivate " + e.toString());
+ return null;
+ } catch (InvalidAlgorithmParameterException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_EXTERNAL", e.toString()));
+ Debug.trace("EncryptionUnit::decryptExternalPrivate " + e.toString());
+ return null;
+ } catch (InvalidKeyException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_EXTERNAL", e.toString()));
+ Debug.trace("EncryptionUnit::decryptExternalPrivate " + e.toString());
+ return null;
+ } catch (Exception e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_EXTERNAL", e.toString()));
+ Debug.trace("EncryptionUnit::decryptExternalPrivate " + e.toString());
+ return null;
+ }
+ }
+
+ /**
+ * External unwrapping. Unwraps the symmetric key using
+ * the transport private key.
+ */
+ public SymmetricKey unwrap_symmetric(byte encSymmKey[],
+ String symmAlgOID, byte symmAlgParams[],
+ byte encValue[])
+ throws EBaseException {
+ try {
+ CryptoToken token = getToken();
+
+ // (1) unwrap the session
+ KeyWrapper rsaWrap = token.getKeyWrapper(
+ KeyWrapAlgorithm.RSA);
+
+ rsaWrap.initUnwrap(getPrivateKey(), null);
+ SymmetricKey sk = rsaWrap.unwrapSymmetric(encSymmKey,
+ SymmetricKey.DES3, SymmetricKey.Usage.UNWRAP,
+ 0);
+
+ // (2) unwrap the sym key
+ KeyWrapper wrapper = token.getKeyWrapper(
+ KeyWrapAlgorithm.DES3_CBC_PAD // XXX
+ );
+
+ wrapper.initUnwrap(sk, new IVParameterSpec(
+ symmAlgParams));
+
+ SymmetricKey symKey = wrapper.unwrapSymmetric(encValue, SymmetricKey.DES3, SymmetricKey.Usage.DECRYPT, 0);
+
+ return symKey;
+ } catch (TokenException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ return null;
+ } catch (NoSuchAlgorithmException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ return null;
+ } catch (InvalidAlgorithmParameterException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ return null;
+ } catch (InvalidKeyException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ return null;
+ } catch (Exception e) {
+ CMS.debug("EncryptionUnit.unwrap : Exception:" + e.toString());
+ return null;
+ }
+ }
+
+ /**
+ * External unwrapping. Unwraps the data using
+ * the transport private key.
+ */
+ public PrivateKey unwrap(byte encSymmKey[],
+ String symmAlgOID, byte symmAlgParams[],
+ byte encValue[], PublicKey pubKey)
+ throws EBaseException {
+ try {
+ CryptoToken token = getToken();
+
+ // (1) unwrap the session
+ KeyWrapper rsaWrap = token.getKeyWrapper(
+ KeyWrapAlgorithm.RSA);
+
+ rsaWrap.initUnwrap(getPrivateKey(), null);
+ SymmetricKey sk = rsaWrap.unwrapSymmetric(encSymmKey,
+ SymmetricKey.DES3, SymmetricKey.Usage.UNWRAP,
+ 0);
+
+ // (2) unwrap the pri
+ KeyWrapper wrapper = token.getKeyWrapper(
+ KeyWrapAlgorithm.DES3_CBC_PAD // XXX
+ );
+
+ wrapper.initUnwrap(sk, new IVParameterSpec(
+ symmAlgParams));
+
+ PrivateKey.Type keytype = null;
+ String alg = pubKey.getAlgorithm();
+ if (alg.equals("DSA")) {
+ keytype = PrivateKey.DSA;
+ } else if (alg.equals("EC")) {
+ keytype = PrivateKey.EC;
+ } else {
+ keytype = PrivateKey.RSA;
+ }
+ PrivateKey pk = wrapper.unwrapTemporaryPrivate(encValue,
+ keytype , pubKey);
+
+ return pk;
+ } catch (TokenException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ return null;
+ } catch (NoSuchAlgorithmException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ return null;
+ } catch (InvalidAlgorithmParameterException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ return null;
+ } catch (InvalidKeyException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ return null;
+ } catch (Exception e) {
+ CMS.debug("EncryptionUnit.unwrap : Exception:"+e.toString());
+ return null;
+ }
+ }
+
+ /**
+ * External unwrapping. Unwraps the data using
+ * the transport private key.
+ */
+
+ public byte[] decryptInternalPrivate(byte wrappedKeyData[])
+ throws EBaseException {
+ try {
+ CMS.debug("EncryptionUnit.decryptInternalPrivate");
+ DerValue val = new DerValue(wrappedKeyData);
+ // val.tag == DerValue.tag_Sequence
+ DerInputStream in = val.data;
+ DerValue dSession = in.getDerValue();
+ byte session[] = dSession.getOctetString();
+ DerValue dPri = in.getDerValue();
+ byte pri[] = dPri.getOctetString();
+
+ CryptoToken token = getToken();
+
+ // (1) unwrap the session
+ CMS.debug("decryptInternalPrivate(): getting key wrapper on slot:" + token.getName());
+ KeyWrapper rsaWrap = token.getKeyWrapper(
+ KeyWrapAlgorithm.RSA);
+
+ rsaWrap.initUnwrap(getPrivateKey(), null);
+ SymmetricKey sk = rsaWrap.unwrapSymmetric(session,
+ SymmetricKey.DES3, SymmetricKey.Usage.DECRYPT, 0);
+
+ // (2) unwrap the pri
+ Cipher cipher = token.getCipherContext(
+ EncryptionAlgorithm.DES3_CBC_PAD);
+
+ cipher.initDecrypt(sk, IV);
+ return cipher.doFinal(pri);
+ } catch (IllegalBlockSizeException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_DECRYPT", e.toString()));
+ Debug.trace("EncryptionUnit::decryptInternalPrivate " + e.toString());
+ return null;
+ } catch (BadPaddingException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_DECRYPT", e.toString()));
+ Debug.trace("EncryptionUnit::decryptInternalPrivate " + e.toString());
+ return null;
+ } catch (TokenException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_DECRYPT", e.toString()));
+ Debug.trace("EncryptionUnit::decryptInternalPrivate " + e.toString());
+ return null;
+ } catch (NoSuchAlgorithmException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_DECRYPT", e.toString()));
+ Debug.trace("EncryptionUnit::decryptInternalPrivate " + e.toString());
+ return null;
+ } catch (InvalidAlgorithmParameterException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_DECRYPT", e.toString()));
+ Debug.trace("EncryptionUnit::decryptInternalPrivate " + e.toString());
+ return null;
+ } catch (InvalidKeyException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_DECRYPT", e.toString()));
+ Debug.trace("EncryptionUnit::decryptInternalPrivate " + e.toString());
+ return null;
+ } catch (IOException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_DECRYPT", e.toString()));
+ Debug.trace("EncryptionUnit::decryptInternalPrivate " + e.toString());
+ return null;
+ } catch (Exception e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_DECRYPT", e.toString()));
+ Debug.trace("EncryptionUnit::decryptInternalPrivate " + e.toString());
+ return null;
+ }
+ }
+
+ /**
+ * External unwrapping of stored symmetric key.
+ */
+ public SymmetricKey unwrap(byte wrappedKeyData[])
+ throws EBaseException {
+ try {
+ DerValue val = new DerValue(wrappedKeyData);
+ // val.tag == DerValue.tag_Sequence
+ DerInputStream in = val.data;
+ DerValue dSession = in.getDerValue();
+ byte session[] = dSession.getOctetString();
+ DerValue dPri = in.getDerValue();
+ byte pri[] = dPri.getOctetString();
+
+ CryptoToken token = getToken();
+ // (1) unwrap the session key
+ KeyWrapper rsaWrap = token.getKeyWrapper(
+ KeyWrapAlgorithm.RSA);
+
+ rsaWrap.initUnwrap(getPrivateKey(), null);
+ SymmetricKey sk = rsaWrap.unwrapSymmetric(session,
+ SymmetricKey.DES3, SymmetricKey.Usage.UNWRAP, 0);
+
+ // (2) unwrap the symmetric key
+ KeyWrapper wrapper = token.getKeyWrapper(
+ KeyWrapAlgorithm.DES3_CBC_PAD);
+
+ wrapper.initUnwrap(sk, IV);
+
+ SymmetricKey sk_ret = wrapper.unwrapSymmetric(pri,
+ SymmetricKey.DES3, SymmetricKey.Usage.UNWRAP,
+ 0);
+
+ return sk_ret;
+ } catch (TokenException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ CMS.debug(e);
+ return null;
+ } catch (NoSuchAlgorithmException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ return null;
+ } catch (InvalidAlgorithmParameterException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ return null;
+ } catch (InvalidKeyException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.printStackTrace(e);
+ return null;
+ } catch (IOException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ return null;
+ } catch (Exception e) {
+ Debug.printStackTrace(e);
+ return null;
+ }
+ }
+
+ /**
+ * Internal unwrapping.
+ */
+ public PrivateKey unwrap_temp(byte wrappedKeyData[], PublicKey pubKey)
+ throws EBaseException {
+ return _unwrap(wrappedKeyData, pubKey, true);
+ }
+
+ /**
+ * Internal unwrapping.
+ */
+ public PrivateKey unwrap(byte wrappedKeyData[], PublicKey pubKey)
+ throws EBaseException {
+ return _unwrap(wrappedKeyData, pubKey, false);
+ }
+
+ /**
+ * Internal unwrapping.
+ */
+ private PrivateKey _unwrap(byte wrappedKeyData[], PublicKey
+ pubKey, boolean temporary)
+ throws EBaseException {
+ try {
+ DerValue val = new DerValue(wrappedKeyData);
+ // val.tag == DerValue.tag_Sequence
+ DerInputStream in = val.data;
+ DerValue dSession = in.getDerValue();
+ byte session[] = dSession.getOctetString();
+ DerValue dPri = in.getDerValue();
+ byte pri[] = dPri.getOctetString();
+
+ CryptoToken token = getToken();
+ // (1) unwrap the session
+ KeyWrapper rsaWrap = token.getKeyWrapper(
+ KeyWrapAlgorithm.RSA);
+
+ rsaWrap.initUnwrap(getPrivateKey(), null);
+ SymmetricKey sk = rsaWrap.unwrapSymmetric(session,
+ SymmetricKey.DES3, SymmetricKey.Usage.UNWRAP, 0);
+
+ // (2) unwrap the pri
+ KeyWrapper wrapper = token.getKeyWrapper(
+ KeyWrapAlgorithm.DES3_CBC_PAD);
+
+ wrapper.initUnwrap(sk, IV);
+
+ PrivateKey pk = null;
+ if (temporary) {
+ pk = wrapper.unwrapTemporaryPrivate(pri,
+ PrivateKey.RSA, pubKey);
+ } else {
+ pk = wrapper.unwrapPrivate(pri,
+ PrivateKey.RSA, pubKey);
+ }
+ return pk;
+ } catch (TokenException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ CMS.debug(e);
+ return null;
+ } catch (NoSuchAlgorithmException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ return null;
+ } catch (InvalidAlgorithmParameterException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ return null;
+ } catch (InvalidKeyException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.printStackTrace(e);
+ return null;
+ } catch (IOException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ return null;
+ } catch (Exception e) {
+ Debug.printStackTrace(e);
+ return null;
+ }
+ }
+
+ /***
+ * Internal wrap, accounts for either private or symmetric key
+ */
+ private byte[] _wrap(PrivateKey priKey, SymmetricKey symmKey) throws EBaseException {
+ try {
+ if ((priKey == null && symmKey == null) || (priKey != null && symmKey != null)) {
+ return null;
+ }
+ CMS.debug("EncryptionUnit.wrap interal.");
+ CryptoToken token = getToken();
+
+ // (1) generate session key
+ org.mozilla.jss.crypto.KeyGenerator kg =
+ token.getKeyGenerator(KeyGenAlgorithm.DES3);
+ // internalToken.getKeyGenerator(KeyGenAlgorithm.DES3);
+ SymmetricKey.Usage usages[] = new SymmetricKey.Usage[2];
+ usages[0] = SymmetricKey.Usage.WRAP;
+ usages[1] = SymmetricKey.Usage.UNWRAP;
+ kg.setKeyUsages(usages);
+ kg.temporaryKeys(true);
+ SymmetricKey sk = kg.generate();
+ CMS.debug("EncryptionUnit:wrap() session key generated on slot: " + token.getName());
+
+ // (2) wrap private key with session key
+ // KeyWrapper wrapper = internalToken.getKeyWrapper(
+ KeyWrapper wrapper = token.getKeyWrapper(
+ KeyWrapAlgorithm.DES3_CBC_PAD);
+
+ wrapper.initWrap(sk, IV);
+
+ byte pri[] = null;
+
+ if ( priKey != null) {
+ pri = wrapper.wrap(priKey);
+ } else if ( symmKey != null) {
+ pri = wrapper.wrap(symmKey);
+ }
+ CMS.debug("EncryptionUnit:wrap() privKey wrapped");
+
+ // (3) wrap session with transport public
+ KeyWrapper rsaWrap = token.getKeyWrapper(
+ KeyWrapAlgorithm.RSA);
+
+ rsaWrap.initWrap(getPublicKey(), null);
+ byte session[] = rsaWrap.wrap(sk);
+ CMS.debug("EncryptionUnit:wrap() sessin key wrapped");
+
+ // use MY own structure for now:
+ // SEQUENCE {
+ // encryptedSession OCTET STRING,
+ // encryptedPrivate OCTET STRING
+ // }
+
+ DerOutputStream tmp = new DerOutputStream();
+ DerOutputStream out = new DerOutputStream();
+
+ tmp.putOctetString(session);
+ tmp.putOctetString(pri);
+ out.write(DerValue.tag_Sequence, tmp);
+
+ return out.toByteArray();
+ } catch (TokenException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_WRAP", e.toString()));
+ Debug.trace("EncryptionUnit::wrap " + e.toString());
+ return null;
+ } catch (NoSuchAlgorithmException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_WRAP", e.toString()));
+ Debug.trace("EncryptionUnit::wrap " + e.toString());
+ return null;
+ } catch (CharConversionException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_WRAP", e.toString()));
+ Debug.trace("EncryptionUnit::wrap " + e.toString());
+ return null;
+ } catch (InvalidAlgorithmParameterException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_WRAP", e.toString()));
+ Debug.trace("EncryptionUnit::wrap " + e.toString());
+ return null;
+ } catch (InvalidKeyException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_WRAP", e.toString()));
+ Debug.trace("EncryptionUnit::wrap " + e.toString());
+ return null;
+ } catch (IOException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_WRAP", e.toString()));
+ Debug.trace("EncryptionUnit::wrap " + e.toString());
+ return null;
+ } catch (Exception e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_WRAP", e.toString()));
+ Debug.trace("EncryptionUnit::wrap " + e.toString());
+ return null;
+ }
+ }
+
+ /**
+ * Verify the given key pair.
+ */
+ public void verify(PublicKey publicKey, PrivateKey privateKey) throws
+ EBaseException {
+ }
+}
diff --git a/base/kra/src/com/netscape/kra/EnrollmentService.java b/base/kra/src/com/netscape/kra/EnrollmentService.java
new file mode 100644
index 000000000..37d1aea53
--- /dev/null
+++ b/base/kra/src/com/netscape/kra/EnrollmentService.java
@@ -0,0 +1,872 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.kra;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.cert.CertificateException;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.security.provider.RSAPublicKey;
+import netscape.security.util.BigInt;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.crmf.PKIArchiveOptions;
+import org.mozilla.jss.pkix.primitive.AVA;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.kra.EKRAException;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.kra.ProofOfArchival;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IService;
+import com.netscape.certsrv.security.IStorageKeyUnit;
+import com.netscape.certsrv.security.ITransportKeyUnit;
+import com.netscape.certsrv.util.IStatsSubsystem;
+import com.netscape.cmscore.crmf.CRMFParser;
+import com.netscape.cmscore.crmf.PKIArchiveOptionsContainer;
+import com.netscape.kra.ArchiveOptions;
+import com.netscape.cmscore.dbs.KeyRecord;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * A class represents archival request processor. It
+ * passes the request to the policy processor, and
+ * process the request according to the policy decision.
+ * <P>
+ * If policy returns ACCEPTED, the request will be processed immediately.
+ * <P>
+ * Upon processing, the incoming user key is unwrapped with the transport key of KRA, and then wrapped with the storage
+ * key. The encrypted key is stored in the internal database for long term storage.
+ * <P>
+ *
+ * @author thomask (original)
+ * @author cfu (non-RSA keys; private keys secure handling);
+ * @version $Revision$, $Date$
+ */
+public class EnrollmentService implements IService {
+
+ // constants
+ public static final String CRMF_REQUEST = "CRMFRequest";
+ public final static String ATTR_KEY_RECORD = "keyRecord";
+ public final static String ATTR_PROOF_OF_ARCHIVAL =
+ "proofOfArchival";
+
+ // private
+ private IKeyRecoveryAuthority mKRA = null;
+ private ITransportKeyUnit mTransportUnit = null;
+ private IStorageKeyUnit mStorageUnit = null;
+ private ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+
+ private final static byte EOL[] = { Character.LINE_SEPARATOR };
+ private final static String LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST =
+ "LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST_4";
+ private final static String LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED_3";
+ private final static String LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST =
+ "LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_4";
+ private final static String LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED_4";
+
+ /**
+ * Constructs request processor.
+ * <P>
+ *
+ * @param kra key recovery authority
+ */
+ public EnrollmentService(IKeyRecoveryAuthority kra) {
+ mKRA = kra;
+ mTransportUnit = kra.getTransportKeyUnit();
+ mStorageUnit = kra.getStorageKeyUnit();
+ }
+
+ 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: getPKIArchiveOptions " + e.toString());
+ }
+ return archOpts;
+ }
+
+ /**
+ * Services an enrollment/archival request.
+ * <P>
+ *
+ * @param request enrollment request
+ * @return serving successful or not
+ * @exception EBaseException failed to serve
+ */
+ public boolean serviceRequest(IRequest request)
+ throws EBaseException {
+
+ IStatsSubsystem statsSub = (IStatsSubsystem) CMS.getSubsystem("stats");
+ if (statsSub != null) {
+ statsSub.startTiming("archival", true /* main action */);
+ }
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = auditRequesterID();
+ String auditArchiveID = ILogger.UNIDENTIFIED;
+ String auditPublicKey = ILogger.UNIDENTIFIED;
+
+ String id = request.getRequestId().toString();
+ if (id != null) {
+ auditArchiveID = id.trim();
+ }
+ if (CMS.debugOn())
+ CMS.debug("EnrollmentServlet: KRA services enrollment request");
+
+ SessionContext sContext = SessionContext.getContext();
+ String agentId = (String) sContext.get(SessionContext.USER_ID);
+ AuthToken authToken = (AuthToken) sContext.get(SessionContext.AUTH_TOKEN);
+
+ mKRA.log(ILogger.LL_INFO, "KRA services enrollment request");
+ // unwrap user key with transport
+ byte unwrapped[] = null;
+ PKIArchiveOptionsContainer aOpts[] = null;
+
+ String profileId = request.getExtDataInString("profileId");
+
+ if (profileId == null || profileId.equals("")) {
+ try {
+ aOpts = CRMFParser.getPKIArchiveOptions(
+ request.getExtDataInString(IRequest.HTTP_PARAMS, CRMF_REQUEST));
+ } catch (IOException e) {
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+ throw new EKRAException(
+ CMS.getUserMessage("CMS_KRA_INVALID_PRIVATE_KEY"));
+ }
+ } else {
+ // profile-based request
+ PKIArchiveOptions options = (PKIArchiveOptions)
+ toPKIArchiveOptions(
+ request.getExtDataInByteArray(IEnrollProfile.REQUEST_ARCHIVE_OPTIONS));
+
+ aOpts = new PKIArchiveOptionsContainer[1];
+ aOpts[0] = new PKIArchiveOptionsContainer(options,
+ 0/* not matter */);
+
+ request.setExtData("dbStatus", "NOT_UPDATED");
+ }
+
+ for (int i = 0; i < aOpts.length; i++) {
+ ArchiveOptions opts = new ArchiveOptions(aOpts[i].mAO);
+
+ if (statsSub != null) {
+ statsSub.startTiming("decrypt_user_key");
+ }
+ mKRA.log(ILogger.LL_INFO, "KRA decrypts external private");
+ if (CMS.debugOn())
+ CMS.debug("EnrollmentService::about to decryptExternalPrivate");
+ unwrapped = mTransportUnit.decryptExternalPrivate(
+ opts.getEncSymmKey(),
+ opts.getSymmAlgOID(),
+ opts.getSymmAlgParams(),
+ opts.getEncValue());
+ if (statsSub != null) {
+ statsSub.endTiming("decrypt_user_key");
+ }
+ if (CMS.debugOn())
+ CMS.debug("EnrollmentService::finished decryptExternalPrivate");
+ if (unwrapped == null) {
+ mKRA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_UNWRAP_USER_KEY"));
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+ throw new EKRAException(
+ CMS.getUserMessage("CMS_KRA_INVALID_PRIVATE_KEY"));
+ }
+
+ // retrieve pubic key
+ X509Key publicKey = getPublicKey(request, aOpts[i].mReqPos);
+ byte publicKeyData[] = publicKey.getEncoded();
+
+ if (publicKeyData == null) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_PUBLIC_NOT_FOUND"));
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+ throw new EKRAException(
+ CMS.getUserMessage("CMS_KRA_INVALID_PUBLIC_KEY"));
+ }
+
+ /* Bugscape #54948 - verify public and private key before archiving key */
+
+ if (statsSub != null) {
+ statsSub.startTiming("verify_key");
+ }
+ if (verifyKeyPair(publicKeyData, unwrapped) == false) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_PUBLIC_NOT_FOUND"));
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+ throw new EKRAException(
+ CMS.getUserMessage("CMS_KRA_INVALID_PUBLIC_KEY"));
+ }
+ if (statsSub != null) {
+ statsSub.endTiming("verify_key");
+ }
+
+ /**
+ * mTransportKeyUnit.verify(pKey, unwrapped);
+ **/
+ // retrieve owner name
+ String owner = getOwnerName(request, aOpts[i].mReqPos);
+
+ if (owner == null) {
+ mKRA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_OWNER_NAME_NOT_FOUND"));
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_INVALID_KEYRECORD"));
+ }
+
+ //
+ // privateKeyData ::= SEQUENCE {
+ // sessionKey OCTET_STRING,
+ // encKey OCTET_STRING,
+ // }
+ //
+ mKRA.log(ILogger.LL_INFO, "KRA encrypts internal private");
+ if (statsSub != null) {
+ statsSub.startTiming("encrypt_user_key");
+ }
+ byte privateKeyData[] = mStorageUnit.encryptInternalPrivate(
+ unwrapped);
+ if (statsSub != null) {
+ statsSub.endTiming("encrypt_user_key");
+ }
+
+ if (privateKeyData == null) {
+ mKRA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_WRAP_USER_KEY"));
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+ throw new EKRAException(
+ CMS.getUserMessage("CMS_KRA_INVALID_PRIVATE_KEY"));
+ }
+
+ // create key record
+ KeyRecord rec = new KeyRecord(null, publicKeyData,
+ privateKeyData, owner,
+ publicKey.getAlgorithmId().getOID().toString(), agentId);
+
+ // we deal with RSA key only
+ try {
+ RSAPublicKey rsaPublicKey = new RSAPublicKey(publicKeyData);
+
+ rec.setKeySize(Integer.valueOf(rsaPublicKey.getKeySize()));
+ } catch (InvalidKeyException e) {
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_INVALID_KEYRECORD"));
+ }
+
+ // if record alreay has a serial number, yell out.
+ if (rec.getSerialNumber() != null) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_INVALID_SERIAL_NUMBER",
+ rec.getSerialNumber().toString()));
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_INVALID_STATE"));
+ }
+ IKeyRepository storage = mKRA.getKeyRepository();
+ BigInteger serialNo = storage.getNextSerialNumber();
+
+ if (serialNo == null) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_GET_NEXT_SERIAL"));
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_INVALID_STATE"));
+ }
+ if (i == 0) {
+ rec.set(KeyRecord.ATTR_ID, serialNo);
+ request.setExtData(ATTR_KEY_RECORD, serialNo);
+ } else {
+ rec.set(KeyRecord.ATTR_ID + i, serialNo);
+ request.setExtData(ATTR_KEY_RECORD + i, serialNo);
+ }
+
+ mKRA.log(ILogger.LL_INFO, "KRA adding key record " + serialNo);
+ if (statsSub != null) {
+ statsSub.startTiming("store_key");
+ }
+ storage.addKeyRecord(rec);
+ if (statsSub != null) {
+ statsSub.endTiming("store_key");
+ }
+
+ if (CMS.debugOn())
+ CMS.debug("EnrollmentService: key record 0x" + serialNo.toString(16)
+ + " (" + owner + ") archived");
+
+ mKRA.log(ILogger.LL_INFO, "key record 0x" +
+ serialNo.toString(16)
+ + " (" + owner + ") archived");
+
+ // for audit log
+ String authMgr = AuditFormat.NOAUTH;
+
+ if (authToken != null) {
+ authMgr =
+ authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ }
+ CMS.getLogger().log(ILogger.EV_AUDIT,
+ ILogger.S_KRA,
+ AuditFormat.LEVEL,
+ AuditFormat.FORMAT,
+ new Object[] {
+ IRequest.KEYARCHIVAL_REQUEST,
+ request.getRequestId(),
+ AuditFormat.FROMAGENT + " agentID: " + agentId,
+ authMgr,
+ "completed",
+ owner,
+ "serial number: 0x" + serialNo.toString(16) }
+ );
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+
+ // store a message in the signed audit log file
+ auditPublicKey = auditPublicKey(rec);
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditPublicKey);
+
+ audit(auditMessage);
+
+ // Xxx - should sign this proof of archival
+ ProofOfArchival mProof = new ProofOfArchival(serialNo,
+ owner, mKRA.getX500Name().toString(),
+ rec.getCreateTime());
+
+ DerOutputStream mProofOut = new DerOutputStream();
+ mProof.encode(mProofOut);
+ if (i == 0) {
+ request.setExtData(ATTR_PROOF_OF_ARCHIVAL,
+ mProofOut.toByteArray());
+ } else {
+ request.setExtData(ATTR_PROOF_OF_ARCHIVAL + i,
+ mProofOut.toByteArray());
+ }
+
+ } // for
+
+ /*
+ request.delete(IEnrollProfile.REQUEST_SUBJECT_NAME);
+ request.delete(IEnrollProfile.REQUEST_EXTENSIONS);
+ request.delete(IEnrollProfile.REQUEST_VALIDITY);
+ request.delete(IEnrollProfile.REQUEST_KEY);
+ request.delete(IEnrollProfile.REQUEST_SIGNING_ALGORITHM);
+ request.delete(IEnrollProfile.REQUEST_LOCALE);
+ */
+
+ request.setExtData(IRequest.RESULT, IRequest.RES_SUCCESS);
+
+ // update request
+ mKRA.log(ILogger.LL_INFO, "KRA updating request");
+ mKRA.getRequestQueue().updateRequest(request);
+
+ if (statsSub != null) {
+ statsSub.endTiming("archival");
+ }
+
+ return true;
+ }
+
+ public boolean verifyKeyPair(byte publicKeyData[], byte privateKeyData[]) {
+ try {
+ DerValue publicKeyVal = new DerValue(publicKeyData);
+ DerInputStream publicKeyIn = publicKeyVal.data;
+ publicKeyIn.getSequence(0);
+ DerValue publicKeyDer = new DerValue(publicKeyIn.getBitString());
+ DerInputStream publicKeyDerIn = publicKeyDer.data;
+ BigInt publicKeyModulus = publicKeyDerIn.getInteger();
+ BigInt publicKeyExponent = publicKeyDerIn.getInteger();
+
+ DerValue privateKeyVal = new DerValue(privateKeyData);
+ if (privateKeyVal.tag != DerValue.tag_Sequence)
+ return false;
+ DerInputStream privateKeyIn = privateKeyVal.data;
+ privateKeyIn.getInteger();
+ privateKeyIn.getSequence(0);
+ DerValue privateKeyDer = new DerValue(privateKeyIn.getOctetString());
+ DerInputStream privateKeyDerIn = privateKeyDer.data;
+
+ @SuppressWarnings("unused")
+ BigInt privateKeyVersion = privateKeyDerIn.getInteger();
+ BigInt privateKeyModulus = privateKeyDerIn.getInteger();
+ BigInt privateKeyExponent = privateKeyDerIn.getInteger();
+
+ if (!publicKeyModulus.equals(privateKeyModulus)) {
+ CMS.debug("verifyKeyPair modulus mismatch publicKeyModulus="
+ + publicKeyModulus + " privateKeyModulus=" + privateKeyModulus);
+ return false;
+ }
+
+ if (!publicKeyExponent.equals(privateKeyExponent)) {
+ CMS.debug("verifyKeyPair exponent mismatch publicKeyExponent="
+ + publicKeyExponent + " privateKeyExponent=" + privateKeyExponent);
+ return false;
+ }
+
+ return true;
+ } catch (Exception e) {
+ CMS.debug("verifyKeyPair error " + e);
+ return false;
+ }
+ }
+
+ 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 crmfBlob CRMF request
+ * @return PKIArchiveOptions
+ * @exception EBaseException failed to extrace option
+ */
+ public static PKIArchiveOptionsContainer[] getPKIArchiveOptions(String crmfBlob)
+ throws EBaseException {
+ Vector<PKIArchiveOptionsContainer> options = new Vector<PKIArchiveOptionsContainer>();
+
+ if (CMS.debugOn())
+ CMS.debug("EnrollmentService::getPKIArchiveOptions> crmfBlob=" + crmfBlob);
+ byte[] crmfBerBlob = null;
+
+ crmfBerBlob = Utils.base64decode(crmfBlob);
+ 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 EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", "[crmf msgs]" + e.toString()));
+ } catch (InvalidBERException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", "[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 EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", "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 EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE",
+ "[PKIArchiveOptions]" + e.toString()));
+ } catch (InvalidBERException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE",
+ "[PKIArchiveOptions]" + e.toString()));
+ }
+ options.addElement(new PKIArchiveOptionsContainer(archOpts, z));
+ }
+ }
+ if (options.size() == 0) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", "PKIArchiveOptions found"));
+ } else {
+ PKIArchiveOptionsContainer p[] = new PKIArchiveOptionsContainer[options.size()];
+
+ options.copyInto(p);
+ return p;
+ }
+ }
+
+ /**
+ * Retrieves public key from request.
+ *
+ * @param request CRMF request
+ * @return JSS public key
+ * @exception EBaseException failed to retrieve public key
+ */
+ private X509Key getPublicKey(IRequest request, int i) throws EBaseException {
+ String profileId = request.getExtDataInString("profileId");
+
+ if (profileId != null && !profileId.equals("")) {
+ byte[] certKeyData = request.getExtDataInByteArray(IEnrollProfile.REQUEST_KEY);
+ if (certKeyData != null) {
+ try {
+ CertificateX509Key x509key = new CertificateX509Key(
+ new ByteArrayInputStream(certKeyData));
+
+ return (X509Key) x509key.get(CertificateX509Key.KEY);
+ } catch (Exception e1) {
+ CMS.debug("EnrollService: (Archival) getPublicKey " +
+ e1.toString());
+ }
+ }
+ return null;
+ }
+
+ // retrieve x509 Key from request
+ X509CertInfo certInfo[] =
+ request.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+ CertificateX509Key pX509Key = null;
+
+ try {
+ pX509Key = (CertificateX509Key)
+ certInfo[i].get(X509CertInfo.KEY);
+ } catch (IOException e) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_GET_PUBLIC_KEY", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE",
+ "[" + X509CertInfo.KEY + "]" + e.toString()));
+ } catch (CertificateException e) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_GET_PUBLIC_KEY", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE",
+ "[" + X509CertInfo.KEY + "]" + e.toString()));
+ }
+ X509Key pKey = null;
+
+ try {
+ pKey = (X509Key) pX509Key.get(
+ CertificateX509Key.KEY);
+ } catch (IOException e) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_GET_PUBLIC_KEY", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", "["
+ + CertificateX509Key.KEY + "]" + e.toString()));
+ }
+ return pKey;
+ }
+
+ /**
+ * Retrieves key's owner name from request.
+ *
+ * @param request CRMF request
+ * @return owner name (subject name)
+ * @exception EBaseException failed to retrieve public key
+ */
+ private String getOwnerName(IRequest request, int i)
+ throws EBaseException {
+
+ String profileId = request.getExtDataInString("profileId");
+
+ if (profileId != null && !profileId.equals("")) {
+ CertificateSubjectName sub = request.getExtDataInCertSubjectName(
+ IEnrollProfile.REQUEST_SUBJECT_NAME);
+ if (sub != null) {
+ return sub.toString();
+ }
+ }
+
+ X509CertInfo certInfo[] =
+ request.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+ CertificateSubjectName pSub = null;
+
+ try {
+ pSub = (CertificateSubjectName)
+ certInfo[0].get(X509CertInfo.SUBJECT);
+ } catch (IOException e) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_GET_OWNER_NAME", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", "["
+ + X509CertInfo.SUBJECT + "]" + e.toString()));
+ } catch (CertificateException e) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_GET_OWNER_NAME", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", "["
+ + X509CertInfo.SUBJECT + "]" + e.toString()));
+ }
+ String owner = pSub.toString();
+
+ return owner;
+ }
+
+ /**
+ * Signed Audit Log Public Key
+ *
+ * This method is called to obtain the public key from the passed in
+ * "KeyRecord" for a signed audit log message.
+ * <P>
+ *
+ * @param rec a Key Record
+ * @return key string containing the certificate's public key
+ */
+ private String auditPublicKey(KeyRecord rec) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ if (rec == null) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ byte rawData[] = null;
+
+ try {
+ rawData = rec.getPublicKeyData();
+ } catch (EBaseException e) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ String key = "";
+
+ // convert "rawData" into "base64Data"
+ if (rawData != null) {
+ String base64Data = null;
+
+ base64Data = CMS.BtoA(rawData).trim();
+
+ // extract all line separators from the "base64Data"
+ StringTokenizer st = new StringTokenizer(base64Data, "\r\n");
+ while (st.hasMoreTokens()) {
+ key += st.nextToken();
+ }
+ }
+
+ key = key.trim();
+
+ if (key.equals("")) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ } else {
+ return key;
+ }
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Signed Audit Log Requester ID
+ *
+ * This method is called to obtain the "RequesterID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditRequesterID() {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requesterID = null;
+
+ // Initialize requesterID
+ SessionContext auditContext = SessionContext.getExistingContext();
+
+ if (auditContext != null) {
+ requesterID = (String)
+ auditContext.get(SessionContext.REQUESTER_ID);
+
+ if (requesterID != null) {
+ requesterID = requesterID.trim();
+ } else {
+ requesterID = ILogger.UNIDENTIFIED;
+ }
+ } else {
+ requesterID = ILogger.UNIDENTIFIED;
+ }
+
+ return requesterID;
+ }
+
+ /**
+ * 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);
+ }
+}
diff --git a/base/kra/src/com/netscape/kra/KRANotify.java b/base/kra/src/com/netscape/kra/KRANotify.java
new file mode 100644
index 000000000..29eaf477a
--- /dev/null
+++ b/base/kra/src/com/netscape/kra/KRANotify.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.kra;
+
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.request.ARequestNotifier;
+
+/**
+ * A class represents a KRA request queue notify. This
+ * object will be invoked by the request subsystem
+ * when a request is requested for processing.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class KRANotify extends ARequestNotifier {
+ private IKeyRecoveryAuthority mKRA = null;
+
+ /**
+ * default constructor
+ */
+ public KRANotify() {
+ super();
+ }
+
+ /**
+ * Creates KRA notify.
+ */
+ public KRANotify(IKeyRecoveryAuthority kra) {
+ super();
+ mKRA = kra;
+ }
+
+ // XXX may want to do something else with mKRA ?
+}
diff --git a/base/kra/src/com/netscape/kra/KRAPolicy.java b/base/kra/src/com/netscape/kra/KRAPolicy.java
new file mode 100644
index 000000000..aa2b2c2de
--- /dev/null
+++ b/base/kra/src/com/netscape/kra/KRAPolicy.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.kra;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.policy.IPolicyProcessor;
+import com.netscape.certsrv.request.IPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.cmscore.policy.GenericPolicyProcessor;
+import com.netscape.cmscore.util.Debug;
+
+/**
+ * KRA Policy.
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class KRAPolicy implements IPolicy {
+ IConfigStore mConfig = null;
+ IKeyRecoveryAuthority mKRA = null;
+
+ public GenericPolicyProcessor mPolicies = new GenericPolicyProcessor(false);
+
+ public KRAPolicy() {
+ }
+
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mKRA = (IKeyRecoveryAuthority) owner;
+ mConfig = config;
+ mPolicies.init(mKRA, mConfig);
+ }
+
+ public IPolicyProcessor getPolicyProcessor() {
+ return mPolicies;
+ }
+
+ /**
+ */
+ public PolicyResult apply(IRequest r) {
+ if (Debug.ON)
+ Debug.trace("KRA applies policies");
+ mKRA.log(ILogger.LL_INFO, "KRA applies policies");
+ PolicyResult result = mPolicies.apply(r);
+
+ if (result.equals(PolicyResult.DEFERRED)) {
+ // For KRA request, there is deferred
+ if (Debug.ON)
+ Debug.trace("KRA policies return DEFERRED");
+ return PolicyResult.REJECTED;
+ } else {
+ if (Debug.ON)
+ Debug.trace("KRA policies return ACCEPTED");
+ return mPolicies.apply(r);
+ }
+ }
+
+}
diff --git a/base/kra/src/com/netscape/kra/KRAService.java b/base/kra/src/com/netscape/kra/KRAService.java
new file mode 100644
index 000000000..4858e286a
--- /dev/null
+++ b/base/kra/src/com/netscape/kra/KRAService.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.kra;
+
+import java.util.Hashtable;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IService;
+import com.netscape.cmscore.util.Debug;
+
+/**
+ * A class represents a KRA request queue service. This
+ * is the service object that is registered with
+ * the request queue. And it acts as a broker to
+ * distribute request into different KRA specific
+ * services. This service registration allows us to support
+ * new request easier.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class KRAService implements IService {
+
+ public final static String ENROLLMENT =
+ IRequest.ENROLLMENT_REQUEST;
+ public final static String RECOVERY = IRequest.KEYRECOVERY_REQUEST;
+ public final static String NETKEY_KEYGEN = IRequest.NETKEY_KEYGEN_REQUEST;
+ public final static String NETKEY_KEYRECOVERY = IRequest.NETKEY_KEYRECOVERY_REQUEST;
+ public final static String SECURITY_DATA_ENROLLMENT = IRequest.SECURITY_DATA_ENROLLMENT_REQUEST;
+ public final static String SECURITY_DATA_RECOVERY = IRequest.SECURITY_DATA_RECOVERY_REQUEST;
+
+
+ // private variables
+ private IKeyRecoveryAuthority mKRA = null;
+ private Hashtable<String, IService> mServices = new Hashtable<String, IService>();
+
+ /**
+ * Constructs KRA service.
+ */
+ public KRAService(IKeyRecoveryAuthority kra) {
+ mKRA = kra;
+ mServices.put(ENROLLMENT, new EnrollmentService(kra));
+ mServices.put(RECOVERY, new RecoveryService(kra));
+ mServices.put(NETKEY_KEYGEN, new NetkeyKeygenService(kra));
+ mServices.put(NETKEY_KEYRECOVERY, new TokenKeyRecoveryService(kra));
+ mServices.put(SECURITY_DATA_ENROLLMENT, new SecurityDataService(kra));
+ mServices.put(SECURITY_DATA_RECOVERY, new SecurityDataRecoveryService(kra));
+ }
+
+ /**
+ * Processes a KRA request. This method is invoked by
+ * request subsystem.
+ *
+ * @param r request from request subsystem
+ * @exception EBaseException failed to serve
+ */
+ public boolean serviceRequest(IRequest r) throws EBaseException {
+ if (Debug.ON)
+ Debug.trace("KRA services request " +
+ r.getRequestId().toString());
+ mKRA.log(ILogger.LL_INFO, "KRA services request " +
+ r.getRequestId().toString());
+ IService s = mServices.get(r.getRequestType());
+
+ if (s == null) {
+ r.setExtData(IRequest.RESULT, IRequest.RES_ERROR);
+ r.setExtData(IRequest.ERROR, new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_OPERATION")));
+ return true;
+ }
+ try {
+ return s.serviceRequest(r);
+ } catch (EBaseException e) {
+ r.setExtData(IRequest.RESULT, IRequest.RES_ERROR);
+ r.setExtData(IRequest.ERROR, e);
+ // return true;
+ // #546508
+ return false;
+ }
+ }
+}
diff --git a/base/kra/src/com/netscape/kra/KeyRecoveryAuthority.java b/base/kra/src/com/netscape/kra/KeyRecoveryAuthority.java
new file mode 100644
index 000000000..8d8cafb84
--- /dev/null
+++ b/base/kra/src/com/netscape/kra/KeyRecoveryAuthority.java
@@ -0,0 +1,1785 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.kra;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.NoSuchTokenException;
+import org.mozilla.jss.crypto.CryptoToken;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.dbs.IDBSubsystem;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.dbs.replicadb.IReplicaIDRepository;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.kra.IKeyService;
+import com.netscape.certsrv.listeners.EListenersException;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.policy.IPolicyProcessor;
+import com.netscape.certsrv.request.ARequestNotifier;
+import com.netscape.certsrv.request.IPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestListener;
+import com.netscape.certsrv.request.IRequestNotifier;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.IRequestScheduler;
+import com.netscape.certsrv.request.IRequestSubsystem;
+import com.netscape.certsrv.request.IService;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.security.Credential;
+import com.netscape.certsrv.security.IStorageKeyUnit;
+import com.netscape.certsrv.security.ITransportKeyUnit;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.cmscore.dbs.DBSubsystem;
+import com.netscape.cmscore.dbs.KeyRecord;
+import com.netscape.cmscore.dbs.KeyRepository;
+import com.netscape.cmscore.dbs.ReplicaIDRepository;
+import com.netscape.cmscore.request.RequestSubsystem;
+
+/**
+ * A class represents an key recovery authority (KRA). A KRA
+ * is responsible to maintain key pairs that have been
+ * escrowed. It provides archive and recovery key pairs
+ * functionalities.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class KeyRecoveryAuthority implements IAuthority, IKeyService, IKeyRecoveryAuthority {
+
+ public final static String OFFICIAL_NAME = "Data Recovery Manager";
+
+ /**
+ * Internal Constants
+ */
+
+ private static final String PR_INTERNAL_TOKEN_NAME = "internal";
+ private static final String PARAM_CREDS = "creds";
+ private static final String PARAM_LOCK = "lock";
+ private static final String PARAM_PK12 = "pk12";
+ private static final String PARAM_ERROR = "error";
+ private static final String PARAM_AGENT = "agent";
+
+ private final static String KEY_RESP_NAME = "keyRepository";
+ private static final String PROP_REPLICAID_DN = "dbs.replicadn";
+
+ protected boolean mInitialized = false;
+ protected IConfigStore mConfig = null;
+ protected ILogger mLogger = CMS.getLogger();
+ protected KRAPolicy mPolicy = null;
+ protected X500Name mName = null;
+ protected boolean mQueueRequests = false;
+ protected String mId = null;
+ protected IRequestQueue mRequestQueue = null;
+ protected TransportKeyUnit mTransportKeyUnit = null;
+ protected StorageKeyUnit mStorageKeyUnit = null;
+ protected Hashtable<String, Credential[]> mAutoRecovery = new Hashtable<String, Credential[]>();
+ protected boolean mAutoRecoveryOn = false;
+ protected KeyRepository mKeyDB = null;
+ protected ReplicaIDRepository mReplicaRepot = null;
+ protected IRequestNotifier mNotify = null;
+ protected IRequestNotifier mPNotify = null;
+ protected ISubsystem mOwner = null;
+ protected int mRecoveryIDCounter = 0;
+ protected Hashtable<String, Hashtable<String, Object>> mRecoveryParams =
+ new Hashtable<String, Hashtable<String, Object>>();
+ protected org.mozilla.jss.crypto.X509Certificate mJssCert = null;
+ protected CryptoToken mKeygenToken = null;
+
+ // holds the number of bits of entropy to collect for each keygen
+ private int mEntropyBitsPerKeyPair = 0;
+
+ // the number of milliseconds which it is acceptable to block while
+ // getting entropy - anything longer will cause a warning.
+ // 0 means this warning is disabled
+ private int mEntropyBlockWarnMilliseconds = 0;
+
+ // for the notification listener
+ public IRequestListener mReqInQListener = null;
+
+ private ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+ private final static byte EOL[] = { Character.LINE_SEPARATOR };
+ private final static String SIGNED_AUDIT_AGENT_DELIMITER = ", ";
+ private final static String LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST =
+ "LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST_4";
+ private final static String LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED_3";
+ private final static String LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST =
+ "LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_4";
+ private final static String LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_ASYNC =
+ "LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_ASYNC_4";
+ private final static String LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED_4";
+ private final static String LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED_ASYNC =
+ "LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED_ASYNC_4";
+
+ /**
+ * Constructs an escrow authority.
+ * <P>
+ */
+ public KeyRecoveryAuthority() {
+ super();
+ }
+
+ /**
+ * Retrieves subsystem identifier.
+ *
+ * @return subsystem id
+ */
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * Sets subsystem identifier.
+ *
+ * @param id subsystem id
+ * @exception EBaseException failed to set id
+ */
+ public void setId(String id) throws EBaseException {
+ mId = id;
+ }
+
+ /**
+ * @deprecated
+ */
+ public IPolicyProcessor getPolicyProcessor() {
+ return mPolicy.getPolicyProcessor();
+ }
+
+ // initialize entropy collection parameters
+ private void initEntropy(IConfigStore config) {
+ mEntropyBitsPerKeyPair = 0;
+ mEntropyBlockWarnMilliseconds = 50;
+ // initialize entropy collection
+ IConfigStore ecs = config.getSubStore("entropy");
+ if (ecs != null) {
+ try {
+ mEntropyBitsPerKeyPair = ecs.getInteger("bitsperkeypair", 0);
+ mEntropyBlockWarnMilliseconds = ecs.getInteger("blockwarnms", 50);
+ } catch (EBaseException eb) {
+ // ok - we deal with missing parameters above
+ }
+ }
+ CMS.debug("KeyRecoveryAuthority Entropy bits = " + mEntropyBitsPerKeyPair);
+ if (mEntropyBitsPerKeyPair == 0) {
+ //log(ILogger.LL_INFO,
+ //CMS.getLogMessage("CMSCORE_KRA_ENTROPY_COLLECTION_DISABLED"));
+ } else {
+ //log(ILogger.LL_INFO,
+ //CMS.getLogMessage("CMSCORE_KRA_ENTROPY_COLLECTION_ENABLED"));
+ CMS.debug("KeyRecoveryAuthority about to add Entropy");
+ addEntropy(false);
+ CMS.debug("KeyRecoveryAuthority back from add Entropy");
+ }
+
+ }
+
+ public void addEntropy(boolean logflag) {
+ CMS.debug("KeyRecoveryAuthority addEntropy()");
+ if (mEntropyBitsPerKeyPair == 0) {
+ CMS.debug("KeyRecoveryAuthority returning - disabled()");
+ return;
+ }
+ long start = System.currentTimeMillis();
+ try {
+ com.netscape.cmscore.security.JssSubsystem.getInstance().
+ addEntropy(mEntropyBitsPerKeyPair);
+ } catch (Exception e) {
+ CMS.debug("KeyRecoveryAuthority returning - error - see log file");
+ CMS.debug("exception: " + e.getMessage());
+ CMS.debug(e);
+ if (logflag) {
+ log(ILogger.LL_INFO,
+ CMS.getLogMessage("CMSCORE_KRA_ENTROPY_ERROR",
+ e.getMessage()));
+ }
+ }
+ long end = System.currentTimeMillis();
+ long duration = end - start;
+
+ if (mEntropyBlockWarnMilliseconds > 0 &&
+ duration > mEntropyBlockWarnMilliseconds) {
+
+ CMS.debug("KeyRecoveryAuthority returning - warning - entropy took too long (ms=" +
+ duration + ")");
+ if (logflag) {
+ log(ILogger.LL_INFO,
+ CMS.getLogMessage("CMSCORE_KRA_ENTROPY_BLOCKED_WARNING",
+ "" + (int) duration));
+ }
+ }
+ CMS.debug("KeyRecoveryAuthority returning ");
+ }
+
+ /**
+ * Starts this subsystem. It loads and initializes all
+ * necessary components. This subsystem is started by
+ * KRASubsystem.
+ * <P>
+ *
+ * @param owner owner of this subsystem
+ * @param config configuration store for this subsystem
+ * @exception EBaseException failed to start subsystem
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ CMS.debug("KeyRecoveryAuthority init() begins");
+ if (mInitialized)
+ return;
+
+ mConfig = config;
+ mOwner = owner;
+
+ // initialize policy processor
+ mPolicy = new KRAPolicy();
+ mPolicy.init(this, mConfig.getSubStore(PROP_POLICY));
+
+ // create key repository
+ int keydb_inc = mConfig.getInteger(PROP_KEYDB_INC, 5);
+
+ mKeyDB = new KeyRepository(getDBSubsystem(),
+ keydb_inc,
+ "ou=" + KEY_RESP_NAME + ",ou=" +
+ getId() + "," +
+ getDBSubsystem().getBaseDN());
+
+ // read transport key from internal database
+ mTransportKeyUnit = new TransportKeyUnit();
+ try {
+ mTransportKeyUnit.init(this, mConfig.getSubStore(
+ PROP_TRANSPORT_KEY));
+ } catch (EBaseException e) {
+ CMS.debug("KeyRecoveryAuthority: transport unit exception " + e.toString());
+ //XXX throw e;
+ return;
+ }
+
+ // retrieve the authority name from transport cert
+ try {
+ mJssCert = mTransportKeyUnit.getCertificate();
+ X509CertImpl certImpl = new
+ X509CertImpl(mJssCert.getEncoded());
+
+ mName = (X500Name) certImpl.getSubjectDN();
+ } catch (CertificateEncodingException e) {
+ CMS.debug("KeyRecoveryAuthority: " + e.toString());
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_LOAD_FAILED",
+ "transport cert " + e.toString()));
+ } catch (CertificateException e) {
+ CMS.debug("KeyRecoveryAuthority: " + e.toString());
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_LOAD_FAILED",
+ "transport cert " + e.toString()));
+ }
+
+ // read transport key from storage key
+ mStorageKeyUnit = new StorageKeyUnit();
+ try {
+ mStorageKeyUnit.init(this,
+ mConfig.getSubStore(PROP_STORAGE_KEY));
+ } catch (EBaseException e) {
+ CMS.debug("KeyRecoveryAuthority: storage unit exception " + e.toString());
+ throw e;
+ }
+
+ // setup token for server-side key generation for user enrollments
+ String serverKeygenTokenName = mConfig.getString("serverKeygenTokenName", null);
+ if (serverKeygenTokenName == null) {
+ CMS.debug("serverKeygenTokenName set to nothing");
+ if (mStorageKeyUnit.getToken() != null) {
+ try {
+ String storageToken = mStorageKeyUnit.getToken().getName();
+ if (!storageToken.equals("internal")) {
+ CMS.debug("Auto set serverKeygenTokenName to " + storageToken);
+ serverKeygenTokenName = storageToken;
+ }
+ } catch (Exception e) {
+ }
+ }
+ }
+ if (serverKeygenTokenName == null) {
+ serverKeygenTokenName = "internal";
+ }
+ if (serverKeygenTokenName.equalsIgnoreCase(PR_INTERNAL_TOKEN_NAME))
+ serverKeygenTokenName = PR_INTERNAL_TOKEN_NAME;
+
+ try {
+ if (serverKeygenTokenName.equalsIgnoreCase(PR_INTERNAL_TOKEN_NAME)) {
+ CMS.debug("KeyRecoveryAuthority: getting internal crypto token for serverkeygen");
+ mKeygenToken = CryptoManager.getInstance().getInternalKeyStorageToken();
+ } else {
+ CMS.debug("KeyRecoveryAuthority: getting HSM token for serverkeygen");
+ mKeygenToken = CryptoManager.getInstance().getTokenByName(serverKeygenTokenName);
+ }
+ CMS.debug("KeyRecoveryAuthority: set up keygenToken");
+ } catch (NoSuchTokenException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", serverKeygenTokenName));
+ } catch (Exception e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ }
+
+ CMS.debug("KeyRecoveryAuthority: about to init entropy");
+ initEntropy(mConfig);
+ CMS.debug("KeyRecoveryAuthority: completed init of entropy");
+
+ getLogger().log(ILogger.EV_SYSTEM, ILogger.S_KRA,
+ ILogger.LL_INFO, mName.toString() + " is started");
+
+ // setup the KRA request queue
+ IService service = new KRAService(this);
+
+ mNotify = new KRANotify(this);
+ mPNotify = new ARequestNotifier();
+ IRequestSubsystem reqSub = RequestSubsystem.getInstance();
+ int reqdb_inc = mConfig.getInteger("reqdbInc", 5);
+
+ mRequestQueue = reqSub.getRequestQueue(getId(), reqdb_inc,
+ mPolicy, service, mNotify, mPNotify);
+
+ // set KeyStatusUpdateInterval to be 10 minutes if serial management is enabled.
+ mKeyDB.setKeyStatusUpdateInterval(
+ mRequestQueue.getRequestRepository(),
+ mConfig.getInteger("keyStatusUpdateInterval", 10 * 60));
+
+ // init request scheduler if configured
+ String schedulerClass =
+ mConfig.getString("requestSchedulerClass", null);
+
+ if (schedulerClass != null) {
+ try {
+ IRequestScheduler scheduler = (IRequestScheduler)
+ Class.forName(schedulerClass).newInstance();
+
+ mRequestQueue.setRequestScheduler(scheduler);
+ } catch (Exception e) {
+ // do nothing here
+ }
+ }
+ initNotificationListeners();
+
+ String replicaReposDN = mConfig.getString(PROP_REPLICAID_DN, null);
+ if (replicaReposDN == null) {
+ replicaReposDN = "ou=Replica," + getDBSubsystem().getBaseDN();
+ }
+
+ mReplicaRepot = new ReplicaIDRepository(
+ DBSubsystem.getInstance(), 1, replicaReposDN);
+ CMS.debug("Replica Repot inited");
+
+ }
+
+ public CryptoToken getKeygenToken() {
+ return mKeygenToken;
+ }
+
+ public IRequestListener getRequestInQListener() {
+ return mReqInQListener;
+ }
+
+ public org.mozilla.jss.crypto.X509Certificate getTransportCert() {
+ return mJssCert;
+ }
+
+ /**
+ * Clears up system during garbage collection.
+ */
+ public void finalize() {
+ shutdown();
+ }
+
+ /**
+ * Starts this service. When this method is called, all
+ * service
+ *
+ * @exception EBaseException failed to startup this subsystem
+ */
+ public void startup() throws EBaseException {
+ CMS.debug("KeyRecoveryAuthority startup() begins");
+
+ if (mRequestQueue != null) {
+ // setup administration operations if everything else is fine
+ mRequestQueue.recover();
+ CMS.debug("KeyRecoveryAuthority startup() call request Q recover");
+
+ // Note that we use our instance id for registration.
+ // This helps us to support multiple instances
+ // of a subsystem within server.
+
+ // register remote admin interface
+ mInitialized = true;
+ } else {
+ CMS.debug("KeyRecoveryAuthority: mRequestQueue is null, could be in preop mode");
+ }
+ }
+
+ /**
+ * Shutdowns this subsystem.
+ */
+ public void shutdown() {
+ if (!mInitialized)
+ return;
+
+ mTransportKeyUnit.shutdown();
+ mStorageKeyUnit.shutdown();
+ if (mKeyDB != null) {
+ mKeyDB.shutdown();
+ mKeyDB = null;
+ }
+ getLogger().log(ILogger.EV_SYSTEM, ILogger.S_KRA,
+ ILogger.LL_INFO, mName.toString() + " is stopped");
+ mInitialized = false;
+ }
+
+ /**
+ * Retrieves the configuration store of this subsystem.
+ * <P>
+ *
+ * @return configuration store
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Changes the auto recovery state.
+ *
+ * @param cs list of recovery agent credentials
+ * @param on turn of auto recovery or not
+ * @return operation success or not
+ */
+ public boolean setAutoRecoveryState(Credential cs[], boolean on) {
+ if (on == true) {
+ // check credential before enabling it
+ try {
+ getStorageKeyUnit().login(cs);
+ } catch (Exception e) {
+ return false;
+ }
+ }
+ // maintain in-memory variable; don't store it in config
+ mAutoRecoveryOn = on;
+ return true;
+ }
+
+ /**
+ * Retrieves the current auto recovery state.
+ *
+ * @return enable or not
+ */
+ public boolean getAutoRecoveryState() {
+ // maintain in-memory variable; don't store it in config
+ return mAutoRecoveryOn;
+ }
+
+ /**
+ * Returns a list of users who are in auto
+ * recovery mode.
+ *
+ * @return list of user IDs that are accepted in the
+ * auto recovery mode
+ */
+ public Enumeration<String> getAutoRecoveryIDs() {
+ return mAutoRecovery.keys();
+ }
+
+ /**
+ * Adds auto recovery mode to the given user id.
+ *
+ * @param id new identifier to the auto recovery mode
+ * @param creds list of credentials
+ */
+ public void addAutoRecovery(String id, Credential creds[]) {
+ mAutoRecovery.put(id, creds);
+ }
+
+ /**
+ * Removes auto recovery mode from the given user id.
+ *
+ * @param id id of user to be removed from auto
+ * recovery mode
+ */
+ public void removeAutoRecovery(String id) {
+ mAutoRecovery.remove(id);
+ }
+
+ /**
+ * Retrieves logger from escrow authority.
+ *
+ * @return logger
+ */
+ public ILogger getLogger() {
+ return CMS.getLogger();
+ }
+
+ /**
+ * Retrieves number of required agents for
+ * recovery operation.
+ *
+ * @return number of required agents
+ * @exception EBaseException failed to retrieve info
+ */
+ public int getNoOfRequiredAgents() throws EBaseException {
+ if (mConfig.getBoolean("keySplitting", false)) {
+ return mStorageKeyUnit.getNoOfRequiredAgents();
+ } else {
+ int ret = -1;
+ ret = mConfig.getInteger("noOfRequiredRecoveryAgents", 1);
+ if (ret <= 0) {
+ throw new EBaseException("Invalid parameter noOfRequiredecoveryAgents");
+ }
+ return ret;
+ }
+ }
+
+ /**
+ * Sets number of required agents for
+ * recovery operation
+ *
+ * @return none
+ * @exception EBaseException invalid setting
+ */
+ public void setNoOfRequiredAgents(int number) throws EBaseException {
+ if (mConfig.getBoolean("keySplitting")) {
+ mStorageKeyUnit.setNoOfRequiredAgents(number);
+ } else {
+ mConfig.putInteger("noOfRequiredRecoveryAgents", number);
+ }
+ }
+
+ /**
+ * Distributed recovery.
+ */
+ public String getRecoveryID() {
+ return Integer.toString(mRecoveryIDCounter++);
+ }
+
+ public Hashtable<String, Object> createRecoveryParams(String recoveryID)
+ throws EBaseException {
+ Hashtable<String, Object> h = new Hashtable<String, Object>();
+
+ h.put(PARAM_CREDS, new Vector<Credential>());
+ h.put(PARAM_LOCK, new Object());
+ mRecoveryParams.put(recoveryID, h);
+ return h;
+ }
+
+ public void destroyRecoveryParams(String recoveryID)
+ throws EBaseException {
+ mRecoveryParams.remove(recoveryID);
+ }
+
+ public Hashtable<String, Object> getRecoveryParams(String recoveryID)
+ throws EBaseException {
+ return (Hashtable<String, Object>) mRecoveryParams.get(recoveryID);
+ }
+
+ public void createPk12(String recoveryID, byte[] pk12)
+ throws EBaseException {
+ Hashtable<String, Object> h = getRecoveryParams(recoveryID);
+
+ h.put(PARAM_PK12, pk12);
+ }
+
+ public byte[] getPk12(String recoveryID)
+ throws EBaseException {
+ return (byte[]) getRecoveryParams(recoveryID).get(PARAM_PK12);
+ }
+
+ public void createError(String recoveryID, String error)
+ throws EBaseException {
+ Hashtable<String, Object> h = getRecoveryParams(recoveryID);
+
+ h.put(PARAM_ERROR, error);
+ }
+
+ public String getError(String recoveryID)
+ throws EBaseException {
+ return (String) getRecoveryParams(recoveryID).get(PARAM_ERROR);
+ }
+
+ /**
+ * Retrieve the current approval agents
+ */
+ public Vector<Credential> getAppAgents(
+ String recoveryID) throws EBaseException {
+ Hashtable<String, Object> h = getRecoveryParams(recoveryID);
+ @SuppressWarnings("unchecked")
+ Vector<Credential> dc = (Vector<Credential>) h.get(PARAM_CREDS);
+
+ return dc;
+ }
+
+ /**
+ * Retrieves a list credentials. This puts KRA in a waiting
+ * mode, it never returns until all the necessary passwords
+ * are collected.
+ */
+ public Credential[] getDistributedCredentials(
+ String recoveryID)
+ throws EBaseException {
+ Hashtable<String, Object> h = getRecoveryParams(recoveryID);
+ @SuppressWarnings("unchecked")
+ Vector<Credential> dc = (Vector<Credential>) h.get(PARAM_CREDS);
+ Object lock = (Object) h.get(PARAM_LOCK);
+
+ synchronized (lock) {
+ while (dc.size() < getNoOfRequiredAgents()) {
+ CMS.debug("KeyRecoveryAuthority: cfu in synchronized lock for getDistributedCredentials");
+ try {
+ lock.wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ Credential creds[] = new Credential[dc.size()];
+
+ dc.copyInto(creds);
+ return creds;
+ }
+ }
+
+ /**
+ * Verifies credential.
+ */
+ private void verifyCredential(Vector<Credential> creds, String uid,
+ String pwd) throws EBaseException {
+ // see if we have the uid already
+
+ if (!mConfig.getBoolean("keySplitting")) {
+ // check if the uid is in the specified group
+ IUGSubsystem ug = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG);
+ if (!ug.isMemberOf(uid, mConfig.getString("recoveryAgentGroup"))) {
+ // invalid group
+ throw new EBaseException(CMS.getUserMessage("CMS_KRA_CREDENTIALS_NOT_EXIST"));
+ }
+ }
+
+ for (int i = 0; i < creds.size(); i++) {
+ Credential c = creds.elementAt(i);
+
+ if (c.getIdentifier().equals(uid)) {
+ // duplicated uid
+ throw new EBaseException(CMS.getUserMessage("CMS_KRA_CREDENTIALS_EXIST"));
+ }
+ }
+ if (mConfig.getBoolean("keySplitting")) {
+ mStorageKeyUnit.checkPassword(uid, pwd);
+ }
+ }
+
+ /**
+ * Adds password.
+ */
+ public void addDistributedCredential(String recoveryID,
+ String uid, String pwd) throws EBaseException {
+ Hashtable<String, Object> h = getRecoveryParams(recoveryID);
+ @SuppressWarnings("unchecked")
+ Vector<Credential> dc = (Vector<Credential>) h.get(PARAM_CREDS);
+ Object lock = (Object) h.get(PARAM_LOCK);
+
+ synchronized (lock) {
+ verifyCredential(dc, uid, pwd);
+ // verify password
+ dc.addElement(new Credential(uid, pwd));
+ // modify status object
+ lock.notify();
+ }
+ }
+
+ /**
+ * Archives key. This creates a key record in the key
+ * repository.
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST used whenever a user private key archive
+ * request is made (this is when the DRM receives the request)
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED used whenever a user private key
+ * archive request is processed (this is when the DRM processes the request)
+ * </ul>
+ *
+ * @param rec key record to be archived
+ * @return executed request
+ * @exception EBaseException failed to archive key
+ * @return the request
+ * <P>
+ */
+ public IRequest archiveKey(KeyRecord rec)
+ throws EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = auditRequesterID();
+ String auditPublicKey = auditPublicKey(rec);
+ String auditArchiveID = ILogger.UNIDENTIFIED;
+
+ IRequestQueue queue = null;
+ IRequest r = null;
+ String id = null;
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ queue = getRequestQueue();
+
+ r = queue.newRequest(KRAService.ENROLLMENT);
+
+ if (r != null) {
+ // overwrite "auditArchiveID" if and only if "id" != null
+ id = r.getRequestId().toString();
+ if (id != null) {
+ auditArchiveID = id.trim();
+ }
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditArchiveID);
+
+ audit(auditMessage);
+
+ throw eAudit1;
+ }
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ if (r != null) {
+ r.setExtData(EnrollmentService.ATTR_KEY_RECORD, rec.getSerialNumber());
+ queue.processRequest(r);
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditPublicKey);
+
+ audit(auditMessage);
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditPublicKey);
+
+ audit(auditMessage);
+
+ throw eAudit1;
+ }
+
+ return r;
+ }
+
+ /**
+ * async key recovery initiation
+ */
+ public String initAsyncKeyRecovery(BigInteger kid, X509CertImpl cert, String agent)
+ throws EBaseException {
+
+ String auditPublicKey = auditPublicKey(cert);
+ String auditRecoveryID = "undefined";
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
+ IRequestQueue queue = null;
+ IRequest r = null;
+
+ try {
+ queue = getRequestQueue();
+ r = queue.newRequest(KRAService.RECOVERY);
+
+ r.setExtData(RecoveryService.ATTR_SERIALNO, kid);
+ r.setExtData(RecoveryService.ATTR_USER_CERT, cert);
+ // first one in the "approvingAgents" list is the initiating agent
+ r.setExtData(RecoveryService.ATTR_APPROVE_AGENTS, agent);
+ r.setRequestStatus(RequestStatus.PENDING);
+ queue.updateRequest(r);
+ auditRecoveryID = r.getRequestId().toString();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_ASYNC,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRecoveryID,
+ auditPublicKey);
+
+ audit(auditMessage);
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_ASYNC,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ auditPublicKey);
+
+ audit(auditMessage);
+
+ throw eAudit1;
+ }
+
+ //NO call to queue.processRequest(r) because it is only initiating
+ return r.getRequestId().toString();
+ }
+
+ /**
+ * is async recovery request status APPROVED -
+ * i.e. all required # of recovery agents approved
+ */
+ public boolean isApprovedAsyncKeyRecovery(String reqID)
+ throws EBaseException {
+ IRequestQueue queue = null;
+ IRequest r = null;
+
+ queue = getRequestQueue();
+ r = queue.findRequest(new RequestId(reqID));
+ if ((r.getRequestStatus() == RequestStatus.APPROVED)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * get async recovery request initiating agent
+ */
+ public String getInitAgentAsyncKeyRecovery(String reqID)
+ throws EBaseException {
+ IRequestQueue queue = null;
+ IRequest r = null;
+
+ queue = getRequestQueue();
+ r = queue.findRequest(new RequestId(reqID));
+
+ String agents = r.getExtDataInString(RecoveryService.ATTR_APPROVE_AGENTS);
+ if (agents != null) {
+ int i = agents.indexOf(",");
+ if (i == -1) {
+ return agents;
+ }
+ return agents.substring(0, i);
+ } else { // no approvingAgents existing, can't be async recovery
+ CMS.debug("getInitAgentAsyncKeyRecovery: no approvingAgents in request");
+ }
+
+ return null;
+ }
+
+ /**
+ * add async recovery agent to approving agent list of the recovery request
+ * record
+ * This method will check to see if the agent belongs to the recovery group
+ * first before adding.
+ */
+ public void addAgentAsyncKeyRecovery(String reqID, String agentID)
+ throws EBaseException {
+ IRequestQueue queue = null;
+ IRequest r = null;
+
+ // check if the uid is in the specified group
+ IUGSubsystem ug = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG);
+ if (!ug.isMemberOf(agentID, mConfig.getString("recoveryAgentGroup"))) {
+ // invalid group
+ throw new EBaseException(CMS.getUserMessage("CMS_KRA_CREDENTIALS_NOT_EXIST"));
+ }
+
+ queue = getRequestQueue();
+ r = queue.findRequest(new RequestId(reqID));
+
+ String agents = r.getExtDataInString(RecoveryService.ATTR_APPROVE_AGENTS);
+ if (agents != null) {
+ int count = 0;
+ StringTokenizer st = new StringTokenizer(agents, ",");
+ for (; st.hasMoreTokens();) {
+ String a = st.nextToken();
+ // first one is the initiating agent
+ if ((count != 0) && a.equals(agentID)) {
+ // duplicated uid
+ throw new EBaseException(CMS.getUserMessage("CMS_KRA_CREDENTIALS_EXIST"));
+ }
+ count++;
+ }
+
+ // note: if count==1 and required agents is 1, it's good to add
+ // and it'd look like "agent1,agent1" - that's the only dup allowed
+ if (count <= getNoOfRequiredAgents()) { //all good, add it
+ r.setExtData(RecoveryService.ATTR_APPROVE_AGENTS,
+ agents + "," + agentID);
+ if (count == getNoOfRequiredAgents()) {
+ r.setRequestStatus(RequestStatus.APPROVED);
+ } else {
+ r.setRequestStatus(RequestStatus.PENDING);
+ }
+ queue.updateRequest(r);
+ }
+ } else { // no approvingAgents existing, can't be async recovery
+ CMS.debug("addAgentAsyncKeyRecovery: no approvingAgents in request. Async recovery request not initiated?");
+ }
+ }
+
+ /**
+ * 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 kid key identifier
+ * @param creds list of recovery agent credentials
+ * @param password password of the PKCS12 package
+ * @param cert certficate that will be put in PKCS12
+ * @param delivery file, mail or something else
+ * @param nickname string containing the nickname of the id cert for this
+ * subsystem
+ * @exception EBaseException failed to recover key
+ * @return a byte array containing the key
+ */
+ public byte[] doKeyRecovery(BigInteger kid,
+ Credential creds[], String password,
+ X509CertImpl cert,
+ String delivery, String nickname,
+ String agent)
+ throws EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRecoveryID = auditRecoveryID();
+ String auditPublicKey = auditPublicKey(cert);
+ String auditAgents = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+
+ IRequestQueue queue = null;
+ IRequest r = null;
+ Hashtable<String, Object> params = null;
+
+ CMS.debug("KeyRecoveryAuthority: in synchronous doKeyRecovery()");
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ queue = getRequestQueue();
+ r = queue.newRequest(KRAService.RECOVERY);
+
+ // set transient parameters
+ params = createVolatileRequest(r.getRequestId());
+
+ if (mConfig.getBoolean("keySplitting")) {
+ params.put(RecoveryService.ATTR_AGENT_CREDENTIALS, creds);
+ }
+ params.put(RecoveryService.ATTR_TRANSPORT_PWD, password);
+
+ r.setExtData(RecoveryService.ATTR_SERIALNO, kid);
+ r.setExtData(RecoveryService.ATTR_USER_CERT, cert);
+ if (nickname != null) {
+ nickname = nickname.trim();
+ if (!nickname.equals("")) {
+ r.setExtData(RecoveryService.ATTR_NICKNAME, nickname);
+ }
+ }
+ // for both sync and async recovery
+ r.setExtData(RecoveryService.ATTR_APPROVE_AGENTS, agent);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRecoveryID,
+ auditPublicKey);
+
+ audit(auditMessage);
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ auditPublicKey);
+
+ audit(auditMessage);
+
+ throw eAudit1;
+ }
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ queue.processRequest(r);
+
+ if (r.getExtDataInString(IRequest.ERROR) == null) {
+ byte pkcs12[] = (byte[]) params.get(
+ RecoveryService.ATTR_PKCS12);
+
+ auditAgents = auditAgents(creds);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRecoveryID,
+ auditAgents);
+
+ audit(auditMessage);
+
+ destroyVolatileRequest(r.getRequestId());
+
+ return pkcs12;
+ } else {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ auditAgents);
+
+ audit(auditMessage);
+
+ throw new EBaseException(r.getExtDataInString(IRequest.ERROR));
+ }
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ auditAgents);
+
+ audit(auditMessage);
+
+ throw eAudit1;
+ }
+ }
+
+ /**
+ * 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 requestID 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 {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRecoveryID = reqID;
+ String auditAgents = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+
+ IRequestQueue queue = null;
+ IRequest r = null;
+ Hashtable<String, Object> params = null;
+
+ CMS.debug("KeyRecoveryAuthority: in asynchronous doKeyRecovery()");
+ queue = getRequestQueue();
+ r = queue.findRequest(new RequestId(reqID));
+
+ auditAgents =
+ r.getExtDataInString(RecoveryService.ATTR_APPROVE_AGENTS);
+
+ // set transient parameters
+ params = createVolatileRequest(r.getRequestId());
+ params.put(RecoveryService.ATTR_TRANSPORT_PWD, password);
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ CMS.debug("KeyRecoveryAuthority: in asynchronous doKeyRecovery(), request state ="
+ + r.getRequestStatus().toString());
+ // can only process requests in begin state
+ r.setRequestStatus(RequestStatus.BEGIN);
+ queue.processRequest(r);
+
+ if (r.getExtDataInString(IRequest.ERROR) == null) {
+ byte pkcs12[] = (byte[]) params.get(
+ RecoveryService.ATTR_PKCS12);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED_ASYNC,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRecoveryID,
+ auditAgents);
+
+ audit(auditMessage);
+
+ destroyVolatileRequest(r.getRequestId());
+
+ return pkcs12;
+ } else {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED_ASYNC,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ auditAgents);
+
+ audit(auditMessage);
+
+ throw new EBaseException(r.getExtDataInString(IRequest.ERROR));
+ }
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED_ASYNC,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ auditAgents);
+
+ audit(auditMessage);
+ throw eAudit1;
+ }
+ }
+
+ /**
+ * Constructs a recovery request and submits it
+ * to the request subsystem for processing.
+ *
+ * @param kid key identifier
+ * @param creds list of recovery agent credentials
+ * @param password password of the PKCS12 package
+ * @param cert certficate that will be put in PKCS12
+ * @param delivery file, mail or something else
+ * @return executed request
+ * @exception EBaseException failed to recover key
+ */
+ public IRequest recoverKey(BigInteger kid,
+ Credential creds[], String password,
+ X509CertImpl cert,
+ String delivery) throws EBaseException {
+ IRequestQueue queue = getRequestQueue();
+ IRequest r = queue.newRequest("recovery");
+
+ r.setExtData(RecoveryService.ATTR_SERIALNO, kid);
+ r.setExtData(RecoveryService.ATTR_TRANSPORT_PWD, password);
+ r.setExtData(RecoveryService.ATTR_USER_CERT, cert);
+ r.setExtData(RecoveryService.ATTR_DELIVERY, delivery);
+ queue.processRequest(r);
+ return r;
+ }
+
+ /**
+ * Recovers key for end-entities.
+ *
+ * @param creds list of credentials
+ * @param encryptionChain certificate chain
+ * @param signingCert signing cert
+ * @param transportCert certificate to protect in-transit key
+ * @param ownerName owner name
+ * @return executed request
+ * @exception EBaseException failed to recover key
+ */
+ public IRequest recoverKey(Credential creds[], CertificateChain
+ encryptionChain, X509CertImpl signingCert,
+ X509CertImpl transportCert,
+ X500Name ownerName) throws EBaseException {
+ IRequestQueue queue = getRequestQueue();
+ IRequest r = queue.newRequest("recovery");
+
+ ByteArrayOutputStream certChainOut = new ByteArrayOutputStream();
+ try {
+ encryptionChain.encode(certChainOut);
+ r.setExtData(RecoveryService.ATTR_ENCRYPTION_CERTS,
+ certChainOut.toByteArray());
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ "Error encoding certificate chain");
+ }
+
+ r.setExtData(RecoveryService.ATTR_SIGNING_CERT, signingCert);
+ r.setExtData(RecoveryService.ATTR_TRANSPORT_CERT, transportCert);
+
+ DerOutputStream ownerNameOut = new DerOutputStream();
+ try {
+ ownerName.encode(ownerNameOut);
+ r.setExtData(RecoveryService.ATTR_OWNER_NAME,
+ ownerNameOut.toByteArray());
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ "Error encoding X500Name for owner name");
+ }
+
+ queue.processRequest(r);
+ return r;
+ }
+
+ /**
+ * Retrieves the storage key unit. The storage key
+ * is used to wrap the user key for long term
+ * storage.
+ *
+ * @return storage key unit.
+ */
+ public IStorageKeyUnit getStorageKeyUnit() {
+ return mStorageKeyUnit;
+ }
+
+ /**
+ * Retrieves the transport key unit.
+ *
+ * @return transport key unit
+ */
+ public ITransportKeyUnit getTransportKeyUnit() {
+ return mTransportKeyUnit;
+ }
+
+ /**
+ * Returns the name of this subsystem. This name is
+ * extracted from the transport certificate.
+ *
+ * @return KRA name
+ */
+ public X500Name getX500Name() {
+ return mName;
+ }
+
+ public String getNickName() {
+ return getNickname();
+ }
+
+ /**
+ * Returns the nickname for the id cert of this
+ * subsystem.
+ *
+ * @return nickname of the transport certificate
+ */
+ public String getNickname() {
+ try {
+ return mTransportKeyUnit.getNickName();
+ } catch (EBaseException e) {
+ return null;
+ }
+ }
+
+ public void setNickname(String str) {
+ try {
+ mTransportKeyUnit.setNickName(str);
+ } catch (EBaseException e) {
+ }
+ }
+
+ public String getNewNickName() throws EBaseException {
+ return mConfig.getString(PROP_NEW_NICKNAME, "");
+ }
+
+ public void setNewNickName(String name) {
+ mConfig.putString(PROP_NEW_NICKNAME, name);
+ }
+
+ public IPolicy getPolicy() {
+ return mPolicy;
+ }
+
+ /**
+ * Retrieves KRA request repository.
+ * <P>
+ *
+ * @return request repository
+ */
+ public IRequestQueue getRequestQueue() {
+ return mRequestQueue;
+ }
+
+ /**
+ * Retrieves the key repository. The key repository
+ * stores archived keys.
+ * <P>
+ */
+ public IKeyRepository getKeyRepository() {
+ return mKeyDB;
+ }
+
+ /**
+ * Retrieves replica repository.
+ * <P>
+ *
+ * @return replica repository
+ */
+ public IReplicaIDRepository getReplicaRepository() {
+ return mReplicaRepot;
+ }
+
+ /**
+ * Retrieves the DN of this escrow authority.
+ * <P>
+ *
+ * @return distinguished name
+ */
+ protected String getDN() {
+ return getX500Name().toString();
+ }
+
+ /**
+ * Retrieves database connection.
+ */
+ public IDBSubsystem getDBSubsystem() {
+ return DBSubsystem.getInstance();
+ }
+
+ /**
+ * Logs an event.
+ *
+ * @param level log level
+ * @param msg message to log
+ */
+ public void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_KRA,
+ level, msg);
+ }
+
+ /**
+ * Registers a request listener.
+ *
+ * @param l request listener
+ */
+ public void registerRequestListener(IRequestListener l) {
+ // it's initialized.
+ if (mNotify != null)
+ mNotify.registerListener(l);
+ }
+
+ public void registerPendingListener(IRequestListener l) {
+ mPNotify.registerListener(l);
+ }
+
+ /**
+ * init notification related listeners -
+ * right now only RequestInQueue listener is available for KRA
+ */
+ private void initNotificationListeners() {
+ IConfigStore nc = null;
+
+ try {
+ nc = mConfig.getSubStore(PROP_NOTIFY_SUBSTORE);
+ if (nc != null && nc.size() > 0) {
+ // Initialize Request In Queue notification listener
+ String requestInQListenerClassName =
+ nc.getString("certificateIssuedListenerClassName",
+ "com.netscape.cms.listeners.RequestInQListener");
+
+ try {
+ mReqInQListener = (IRequestListener) Class.forName(requestInQListenerClassName).newInstance();
+ mReqInQListener.init(this, nc);
+ } catch (Exception e1) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_REGISTER_LISTENER", requestInQListenerClassName));
+ }
+ } else {
+ log(ILogger.LL_INFO,
+ "No KRA notification Module configuration found");
+ }
+ } catch (EPropertyNotFound e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_NOTIFY_ERROR", e.toString()));
+ } catch (EListenersException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_NOTIFY_ERROR", e.toString()));
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_NOTIFY_ERROR", e.toString()));
+ }
+ }
+
+ /**
+ * temporary accepted ras.
+ */
+ /* code no longer used
+ public X500Name[] getAcceptedRAs() {
+ // temporary. use usr/grp for real thing.
+ X500Name radn = null;
+ String raname = null;
+
+ try {
+ raname = mConfig.getString("acceptedRA", null);
+ if (raname != null) {
+ radn = new X500Name(raname);
+ }
+ } catch (IOException e) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_KRA,
+ ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_INVALID_RA_NAME", raname, e.toString()));
+ } catch (EBaseException e) {
+ // ignore - set to null.
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_KRA,
+ ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_INVALID_RA_SETUP", e.toString()));
+ }
+ return new X500Name[] { radn };
+ }
+ */
+
+ public Hashtable<String, Hashtable<String, Object>> mVolatileRequests =
+ new Hashtable<String, Hashtable<String, Object>>();
+
+ /**
+ * 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.
+ */
+ public Hashtable<String, Object> createVolatileRequest(RequestId id) {
+ Hashtable<String, Object> params = new Hashtable<String, Object>();
+
+ mVolatileRequests.put(id.toString(), params);
+ return params;
+ }
+
+ public Hashtable<String, Object> getVolatileRequest(RequestId id) {
+ return (Hashtable<String, Object>) mVolatileRequests.get(id.toString());
+ }
+
+ public void destroyVolatileRequest(RequestId id) {
+ mVolatileRequests.remove(id.toString());
+ }
+
+ public String getOfficialName() {
+ return OFFICIAL_NAME;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Signed Audit Log Requester ID
+ *
+ * This method is called to obtain the "RequesterID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditRequesterID() {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requesterID = null;
+
+ // Initialize requesterID
+ SessionContext auditContext = SessionContext.getExistingContext();
+
+ if (auditContext != null) {
+ requesterID = (String)
+ auditContext.get(SessionContext.REQUESTER_ID);
+
+ if (requesterID != null) {
+ requesterID = requesterID.trim();
+ } else {
+ requesterID = ILogger.UNIDENTIFIED;
+ }
+ } else {
+ requesterID = ILogger.UNIDENTIFIED;
+ }
+
+ return requesterID;
+ }
+
+ /**
+ * Signed Audit Log Recovery ID
+ *
+ * This method is called to obtain the "RecoveryID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @return id string containing the signed audit log message RecoveryID
+ */
+ private String auditRecoveryID() {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String recoveryID = null;
+
+ // Initialize recoveryID
+ SessionContext auditContext = SessionContext.getExistingContext();
+
+ if (auditContext != null) {
+ recoveryID = (String)
+ auditContext.get(SessionContext.RECOVERY_ID);
+
+ if (recoveryID != null) {
+ recoveryID = recoveryID.trim();
+ } else {
+ recoveryID = ILogger.UNIDENTIFIED;
+ }
+ } else {
+ recoveryID = ILogger.UNIDENTIFIED;
+ }
+
+ return recoveryID;
+ }
+
+ /**
+ * Signed Audit Log Public Key
+ *
+ * This method is called to obtain the public key from the passed in
+ * "X509Certificate" for a signed audit log message.
+ * <P>
+ *
+ * @param cert an X509Certificate
+ * @return key string containing the certificate's public key
+ */
+ private String auditPublicKey(X509Certificate cert) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ if (cert == null) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ byte rawData[] = cert.getPublicKey().getEncoded();
+
+ // convert "rawData" into "base64Data"
+ if (rawData != null) {
+ String base64Data = CMS.BtoA(rawData).trim();
+ String key = "";
+
+ // extract all line separators from the "base64Data"
+ for (int i = 0; i < base64Data.length(); i++) {
+ if (base64Data.substring(i, i).getBytes() != EOL) {
+ key += base64Data.substring(i, i);
+ }
+ }
+
+ return key;
+ }
+
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ /**
+ * Signed Audit Log Public Key
+ *
+ * This method is called to obtain the public key from the passed in
+ * "KeyRecord" for a signed audit log message.
+ * <P>
+ *
+ * @param rec a Key Record
+ * @return key string containing the certificate's public key
+ */
+ private String auditPublicKey(KeyRecord rec) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ if (rec == null) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ byte rawData[] = null;
+
+ try {
+ rawData = rec.getPublicKeyData();
+ } catch (EBaseException e) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ String key = null;
+
+ // convert "rawData" into "base64Data"
+ if (rawData != null) {
+ String base64Data = null;
+
+ base64Data = CMS.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) {
+ key += base64Data.substring(i, i);
+ }
+ }
+ }
+
+ 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;
+ }
+ }
+
+ /**
+ * Signed Audit Agents
+ *
+ * This method is called to extract agent uids from the passed in
+ * "Credentials[]" and return a string of comma-separated agent uids.
+ * <P>
+ *
+ * @param creds array of credentials
+ * @return a comma-separated string of agent uids
+ */
+ private String auditAgents(Credential creds[]) {
+ if (creds == null)
+ return null;
+
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String agents = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+
+ String uid = null;
+
+ for (int i = 0; i < creds.length; i++) {
+ uid = creds[i].getIdentifier();
+
+ if (uid != null) {
+ uid = uid.trim();
+ }
+
+ if (uid != null &&
+ !uid.equals("")) {
+
+ if (i == 0) {
+ agents = uid;
+ } else {
+ agents += SIGNED_AUDIT_AGENT_DELIMITER + uid;
+ }
+ }
+ }
+
+ return agents;
+ }
+}
diff --git a/base/kra/src/com/netscape/kra/NetkeyKeygenService.java b/base/kra/src/com/netscape/kra/NetkeyKeygenService.java
new file mode 100644
index 000000000..ecce2eaa9
--- /dev/null
+++ b/base/kra/src/com/netscape/kra/NetkeyKeygenService.java
@@ -0,0 +1,608 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.kra;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+import netscape.security.provider.RSAPublicKey;
+
+import org.mozilla.jss.crypto.Cipher;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.EncryptionAlgorithm;
+import org.mozilla.jss.crypto.IVParameterSpec;
+import org.mozilla.jss.crypto.KeyPairAlgorithm;
+import org.mozilla.jss.crypto.KeyPairGenerator;
+import org.mozilla.jss.crypto.KeyWrapAlgorithm;
+import org.mozilla.jss.crypto.KeyWrapper;
+import org.mozilla.jss.crypto.PQGParamGenException;
+import org.mozilla.jss.crypto.PQGParams;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.crypto.SymmetricKey;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.pkcs11.PK11SymKey;
+import org.mozilla.jss.pkix.crmf.PKIArchiveOptions;
+import org.mozilla.jss.util.Base64OutputStream;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IService;
+import com.netscape.certsrv.security.IStorageKeyUnit;
+import com.netscape.certsrv.security.ITransportKeyUnit;
+import com.netscape.cmscore.dbs.KeyRecord;
+import com.netscape.cmscore.util.Debug;
+
+/**
+ * A class representing keygen/archival request procesor for requests
+ * from netkey RAs.
+ * the user private key of the encryption cert is wrapped with a
+ * session symmetric key. The session symmetric key is wrapped with the
+ * storage key and stored in the internal database for long term
+ * storage.
+ * The user private key of the encryption cert is to be wrapped with the
+ * DES key which came in in the request wrapped with the KRA
+ * transport cert. The wrapped user private key is then sent back to
+ * the caller (netkey RA) ...netkey RA should already has kek-wrapped
+ * des key from the TKS. They are to be sent together back to
+ * the token.
+ *
+ * @author Christina Fu (cfu)
+ * @version $Revision$, $Date$
+ */
+
+public class NetkeyKeygenService implements IService {
+ public final static String ATTR_KEY_RECORD = "keyRecord";
+ public final static String ATTR_PROOF_OF_ARCHIVAL =
+ "proofOfArchival";
+
+ // private
+ private final static String LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST =
+ "LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST_4";
+ private final static String LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED_3";
+ // these need to be defined in LogMessages_en.properties later when we do this
+ private final static String LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_REQUEST =
+ "LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_REQUEST_3";
+ private final static String LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_SUCCESS =
+ "LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_SUCCESS_4";
+ private final static String LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_FAILURE =
+ "LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_FAILURE_3";
+ private final static String LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS =
+ "LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS_4";
+ private final static String LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE =
+ "LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE_4";
+ private IKeyRecoveryAuthority mKRA = null;
+ private ITransportKeyUnit mTransportUnit = null;
+ private IStorageKeyUnit mStorageUnit = null;
+ private ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+
+ /**
+ * Constructs request processor.
+ * <P>
+ *
+ * @param kra key recovery authority
+ */
+ public NetkeyKeygenService(IKeyRecoveryAuthority kra) {
+ mKRA = kra;
+ mTransportUnit = kra.getTransportKeyUnit();
+ mStorageUnit = kra.getStorageKeyUnit();
+ }
+
+ 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("NetkeyKeygenService: getPKIArchiveOptions " + e.toString());
+ }
+ return archOpts;
+ }
+
+ public KeyPair generateKeyPair(
+ KeyPairAlgorithm kpAlg, int keySize, PQGParams pqg)
+ throws NoSuchAlgorithmException, TokenException, InvalidAlgorithmParameterException,
+ InvalidParameterException, PQGParamGenException {
+
+ CryptoToken token = mKRA.getKeygenToken();
+
+ CMS.debug("NetkeyKeygenService: key pair is to be generated on slot: " + token.getName());
+
+ /*
+ make it temporary so can work with HSM
+ netHSM works with
+ temporary == true
+ sensitive == <do not specify>
+ extractable == <do not specify>
+ LunaSA2 works with
+ temporary == true
+ sensitive == true
+ extractable == true
+ */
+ KeyPairGenerator kpGen = token.getKeyPairGenerator(kpAlg);
+ IConfigStore config = CMS.getConfigStore();
+ IConfigStore kgConfig = config.getSubStore("kra.keygen");
+ boolean tp = false;
+ boolean sp = false;
+ boolean ep = false;
+ if (kgConfig != null) {
+ try {
+ tp = kgConfig.getBoolean("temporaryPairs", false);
+ sp = kgConfig.getBoolean("sensitivePairs", false);
+ ep = kgConfig.getBoolean("extractablePairs", false);
+ // by default, let nethsm work
+ if ((tp == false) && (sp == false) && (ep == false)) {
+ tp = true;
+ }
+ } catch (Exception e) {
+ CMS.debug("NetkeyKeygenService: kgConfig.getBoolean failed");
+ // by default, let nethsm work
+ tp = true;
+ }
+ } else {
+ // by default, let nethsm work
+ CMS.debug("NetkeyKeygenService: cannot find config store: kra.keygen, assume temporaryPairs==true");
+ tp = true;
+ }
+ /* only specified to "true" will it be set */
+ if (tp == true) {
+ CMS.debug("NetkeyKeygenService: setting temporaryPairs to true");
+ kpGen.temporaryPairs(true);
+ }
+ if (sp == true) {
+ CMS.debug("NetkeyKeygenService: setting sensitivePairs to true");
+ kpGen.sensitivePairs(true);
+ }
+ if (ep == true) {
+ CMS.debug("NetkeyKeygenService: setting extractablePairs to true");
+ kpGen.extractablePairs(true);
+ }
+
+ if (kpAlg == KeyPairAlgorithm.DSA) {
+ if (pqg == null) {
+ kpGen.initialize(keySize);
+ } else {
+ kpGen.initialize(pqg);
+ }
+ } else {
+ kpGen.initialize(keySize);
+ }
+
+ if (pqg == null) {
+ KeyPair kp = null;
+ synchronized (new Object()) {
+ CMS.debug("NetkeyKeygenService: key pair generation begins");
+ kp = kpGen.genKeyPair();
+ CMS.debug("NetkeyKeygenService: key pair generation done");
+ mKRA.addEntropy(true);
+ }
+ return kp;
+ } else {
+ // DSA
+ KeyPair kp = null;
+
+ /* no DSA for now... netkey prototype
+ do {
+ // 602548 NSS bug - to overcome it, we use isBadDSAKeyPair
+ kp = kpGen.genKeyPair();
+ }
+ while (isBadDSAKeyPair(kp));
+ */
+ return kp;
+ }
+ }
+
+ public KeyPair generateKeyPair(String alg,
+ int keySize, PQGParams pqg) throws EBaseException {
+
+ KeyPairAlgorithm kpAlg = null;
+
+ if (alg.equals("RSA"))
+ kpAlg = KeyPairAlgorithm.RSA;
+ else
+ kpAlg = KeyPairAlgorithm.DSA;
+
+ try {
+ KeyPair kp = generateKeyPair(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"));
+ }
+ }
+
+ private 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");
+ }
+
+ // this encrypts bytes with a symmetric key
+ public byte[] encryptIt(byte[] toBeEncrypted, SymmetricKey symKey, CryptoToken token,
+ IVParameterSpec IV) {
+ try {
+ Cipher cipher = token.getCipherContext(
+ EncryptionAlgorithm.DES3_CBC_PAD);
+
+ cipher.initEncrypt(symKey, IV);
+ byte pri[] = cipher.doFinal(toBeEncrypted);
+ return pri;
+ } catch (Exception e) {
+ CMS.debug("NetkeyKeygenService:initEncrypt() threw exception: " + e.toString());
+ return null;
+ }
+
+ }
+
+ /**
+ * Services an archival request from netkey.
+ * <P>
+ *
+ * @param request enrollment request
+ * @return serving successful or not
+ * @exception EBaseException failed to serve
+ */
+ public boolean serviceRequest(IRequest request)
+ throws EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = null;
+ String auditArchiveID = ILogger.UNIDENTIFIED;
+ byte[] wrapped_des_key;
+
+ byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
+ String iv_s = "";
+ try {
+ SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+ random.nextBytes(iv);
+ } catch (Exception e) {
+ CMS.debug("NetkeyKeygenService.serviceRequest: " + e.toString());
+ }
+
+ IVParameterSpec algParam = new IVParameterSpec(iv);
+
+ wrapped_des_key = null;
+ boolean archive = true;
+ PK11SymKey sk = null;
+ byte[] publicKeyData = null;
+ ;
+ String PubKey = "";
+
+ String id = request.getRequestId().toString();
+ if (id != null) {
+ auditArchiveID = id.trim();
+ }
+
+ String rArchive = request.getExtDataInString(IRequest.NETKEY_ATTR_ARCHIVE_FLAG);
+ if (rArchive.equals("true")) {
+ archive = true;
+ CMS.debug("NetkeyKeygenService: serviceRequest " + "archival requested for serverSideKeyGen");
+ } else {
+ archive = false;
+ CMS.debug("NetkeyKeygenService: serviceRequest " + "archival not requested for serverSideKeyGen");
+ }
+
+ String rCUID = request.getExtDataInString(IRequest.NETKEY_ATTR_CUID);
+ String rUserid = request.getExtDataInString(IRequest.NETKEY_ATTR_USERID);
+ String rKeysize = request.getExtDataInString(IRequest.NETKEY_ATTR_KEY_SIZE);
+ int keysize = Integer.parseInt(rKeysize);
+ auditSubjectID = rCUID + ":" + rUserid;
+
+ SessionContext sContext = SessionContext.getContext();
+ String agentId = "";
+ if (sContext != null) {
+ agentId =
+ (String) sContext.get(SessionContext.USER_ID);
+ }
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_REQUEST,
+ agentId,
+ ILogger.SUCCESS,
+ auditSubjectID);
+
+ audit(auditMessage);
+
+ String rWrappedDesKeyString = request.getExtDataInString(IRequest.NETKEY_ATTR_DRMTRANS_DES_KEY);
+ // CMS.debug("NetkeyKeygenService: received DRM-trans-wrapped DES key ="+rWrappedDesKeyString);
+ wrapped_des_key = com.netscape.cmsutil.util.Utils.SpecialDecode(rWrappedDesKeyString);
+ CMS.debug("NetkeyKeygenService: wrapped_des_key specialDecoded");
+
+ // get the token for generating user keys
+ CryptoToken keygenToken = mKRA.getKeygenToken();
+ if (keygenToken == null) {
+ CMS.debug("NetkeyKeygenService: failed getting keygenToken");
+ request.setExtData(IRequest.RESULT, Integer.valueOf(10));
+ return false;
+ } else
+ CMS.debug("NetkeyKeygenService: got keygenToken");
+
+ if ((wrapped_des_key != null) &&
+ (wrapped_des_key.length > 0)) {
+
+ // unwrap the DES key
+ sk = (PK11SymKey) mTransportUnit.unwrap_sym(wrapped_des_key);
+
+ /* XXX could be done in HSM*/
+ KeyPair keypair = null;
+
+ CMS.debug("NetkeyKeygenService: about to generate key pair");
+
+ keypair = generateKeyPair("RSA"/*alg*/,
+ keysize /*Integer.parseInt(len)*/, null /*pqgParams*/);
+
+ if (keypair == null) {
+ CMS.debug("NetkeyKeygenService: failed generating key pair for " + rCUID + ":" + rUserid);
+ request.setExtData(IRequest.RESULT, Integer.valueOf(4));
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_FAILURE,
+ agentId,
+ ILogger.FAILURE,
+ auditSubjectID);
+
+ audit(auditMessage);
+
+ return false;
+ }
+ CMS.debug("NetkeyKeygenService: finished generate key pair for " + rCUID + ":" + rUserid);
+
+ try {
+ publicKeyData = keypair.getPublic().getEncoded();
+ if (publicKeyData == null) {
+ request.setExtData(IRequest.RESULT, Integer.valueOf(4));
+ CMS.debug("NetkeyKeygenService: failed getting publickey encoded");
+ return false;
+ } else {
+ //CMS.debug("NetkeyKeygenService: public key binary length ="+ publicKeyData.length);
+ PubKey = base64Encode(publicKeyData);
+
+ //CMS.debug("NetkeyKeygenService: public key length =" + PubKey.length());
+ request.setExtData("public_key", PubKey);
+ }
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_SUCCESS,
+ agentId,
+ ILogger.SUCCESS,
+ auditSubjectID,
+ PubKey);
+
+ audit(auditMessage);
+
+ //...extract the private key handle (not privatekeydata)
+ java.security.PrivateKey privKey =
+ keypair.getPrivate();
+
+ if (privKey == null) {
+ request.setExtData(IRequest.RESULT, Integer.valueOf(4));
+ CMS.debug("NetkeyKeygenService: failed getting private key");
+ return false;
+ } else {
+ CMS.debug("NetkeyKeygenService: got private key");
+ }
+
+ if (sk == null) {
+ CMS.debug("NetkeyKeygenService: no DES key");
+ request.setExtData(IRequest.RESULT, Integer.valueOf(4));
+ return false;
+ } else {
+ CMS.debug("NetkeyKeygenService: received DES key");
+ }
+
+ // 3 wrapping should be done in HSM
+ // wrap private key with DES
+ KeyWrapper symWrap =
+ keygenToken.getKeyWrapper(KeyWrapAlgorithm.DES3_CBC_PAD);
+ CMS.debug("NetkeyKeygenService: wrapper token=" + keygenToken.getName());
+ CMS.debug("NetkeyKeygenService: got key wrapper");
+
+ CMS.debug("NetkeyKeygenService: key transport key is on slot: " + sk.getOwningToken().getName());
+ symWrap.initWrap((SymmetricKey) sk, algParam);
+ byte wrapped[] = symWrap.wrap((PrivateKey) privKey);
+ /*
+ CMS.debug("NetkeyKeygenService: wrap called");
+ CMS.debug(wrapped);
+ */
+ /* This is for using with my decryption tool and ASN1
+ decoder to see if the private key is indeed PKCS#8 format
+ { // cfu debug
+ String oFilePath = "/tmp/wrappedPrivKey.bin";
+ File file = new File(oFilePath);
+ FileOutputStream ostream = new FileOutputStream(oFilePath);
+ ostream.write(wrapped);
+ ostream.close();
+ }
+ */
+ String wrappedPrivKeyString = /*base64Encode(wrapped);*/
+ com.netscape.cmsutil.util.Utils.SpecialEncode(wrapped);
+ if (wrappedPrivKeyString == null) {
+ request.setExtData(IRequest.RESULT, Integer.valueOf(4));
+ CMS.debug("NetkeyKeygenService: failed generating wrapped private key");
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE,
+ agentId,
+ ILogger.FAILURE,
+ auditSubjectID,
+ PubKey);
+
+ audit(auditMessage);
+ return false;
+ } else {
+ request.setExtData("wrappedUserPrivate", wrappedPrivKeyString);
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS,
+ agentId,
+ ILogger.SUCCESS,
+ auditSubjectID,
+ PubKey);
+
+ audit(auditMessage);
+ }
+
+ iv_s = /*base64Encode(iv);*/com.netscape.cmsutil.util.Utils.SpecialEncode(iv);
+ request.setExtData("iv_s", iv_s);
+
+ /*
+ * archival - option flag "archive" controllable by the caller - TPS
+ */
+ if (archive) {
+ //
+ // privateKeyData ::= SEQUENCE {
+ // sessionKey OCTET_STRING,
+ // encKey OCTET_STRING,
+ // }
+ //
+ // mKRA.log(ILogger.LL_INFO, "KRA encrypts internal private");
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
+ agentId,
+ ILogger.SUCCESS,
+ auditSubjectID,
+ auditArchiveID);
+
+ audit(auditMessage);
+ CMS.debug("KRA encrypts private key to put on internal ldap db");
+ byte privateKeyData[] =
+ mStorageUnit.wrap((org.mozilla.jss.crypto.PrivateKey) privKey);
+
+ if (privateKeyData == null) {
+ request.setExtData(IRequest.RESULT, Integer.valueOf(4));
+ CMS.debug("NetkeyKeygenService: privatekey encryption by storage unit failed");
+ return false;
+ } else
+ CMS.debug("NetkeyKeygenService: privatekey encryption by storage unit successful");
+
+ // create key record
+ KeyRecord rec = new KeyRecord(null, publicKeyData,
+ privateKeyData, rCUID + ":" + rUserid,
+ keypair.getPublic().getAlgorithm(),
+ agentId);
+
+ CMS.debug("NetkeyKeygenService: got key record");
+
+ // we deal with RSA key only
+ try {
+ RSAPublicKey rsaPublicKey = new RSAPublicKey(publicKeyData);
+
+ rec.setKeySize(Integer.valueOf(rsaPublicKey.getKeySize()));
+ } catch (InvalidKeyException e) {
+ request.setExtData(IRequest.RESULT, Integer.valueOf(11));
+ CMS.debug("NetkeyKeygenService: failed:InvalidKeyException");
+ return false;
+ }
+ //??
+ IKeyRepository storage = mKRA.getKeyRepository();
+ BigInteger serialNo = storage.getNextSerialNumber();
+
+ if (serialNo == null) {
+ request.setExtData(IRequest.RESULT, Integer.valueOf(11));
+ CMS.debug("NetkeyKeygenService: serialNo null");
+ return false;
+ }
+ CMS.debug("NetkeyKeygenService: before addKeyRecord");
+ rec.set(KeyRecord.ATTR_ID, serialNo);
+ request.setExtData(ATTR_KEY_RECORD, serialNo);
+ storage.addKeyRecord(rec);
+ CMS.debug("NetkeyKeygenService: key archived for " + rCUID + ":" + rUserid);
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED,
+ agentId,
+ ILogger.SUCCESS,
+ PubKey);
+
+ audit(auditMessage);
+
+ } //if archive
+
+ request.setExtData(IRequest.RESULT, Integer.valueOf(1));
+ } catch (Exception e) {
+ CMS.debug("NetKeyKeygenService: " + e.toString());
+ Debug.printStackTrace(e);
+ request.setExtData(IRequest.RESULT, Integer.valueOf(4));
+ }
+ } else
+ request.setExtData(IRequest.RESULT, Integer.valueOf(2));
+
+ return true;
+ } //serviceRequest
+
+ /**
+ * Signed Audit Log
+ * y
+ * 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);
+ }
+}
diff --git a/base/kra/src/com/netscape/kra/RecoveryService.java b/base/kra/src/com/netscape/kra/RecoveryService.java
new file mode 100644
index 000000000..c8ecdcf5a
--- /dev/null
+++ b/base/kra/src/com/netscape/kra/RecoveryService.java
@@ -0,0 +1,710 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.kra;
+
+import java.io.ByteArrayOutputStream;
+import java.io.CharConversionException;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.Hashtable;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerValue;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509Key;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.BMPString;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.PBEAlgorithm;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.pkcs12.AuthenticatedSafes;
+import org.mozilla.jss.pkcs12.CertBag;
+import org.mozilla.jss.pkcs12.PFX;
+import org.mozilla.jss.pkcs12.PasswordConverter;
+import org.mozilla.jss.pkcs12.SafeBag;
+import org.mozilla.jss.pkix.primitive.EncryptedPrivateKeyInfo;
+import org.mozilla.jss.pkix.primitive.PrivateKeyInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.kra.EKRAException;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.AuditFormat;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IService;
+import com.netscape.certsrv.security.Credential;
+import com.netscape.certsrv.security.IStorageKeyUnit;
+import com.netscape.certsrv.util.IStatsSubsystem;
+import com.netscape.cmscore.dbs.KeyRecord;
+import com.netscape.cmscore.util.Debug;
+
+/**
+ * A class represents recovery request processor. There
+ * are 2 types of recovery modes: (1) administrator or
+ * (2) end-entity.
+ * <P>
+ * Administrator recovery will create a PKCS12 file where stores the certificate and the recovered key.
+ * <P>
+ * End Entity recovery will send RA or CA a response where stores the recovered key.
+ *
+ * @author thomask (original)
+ * @author cfu (non-RSA keys; private keys secure handling);
+ * @version $Revision$, $Date$
+ */
+public class RecoveryService implements IService {
+
+ public static final String ATTR_NICKNAME = "nickname";
+ public static final String ATTR_OWNER_NAME = "ownerName";
+ public static final String ATTR_SERIALNO = "serialNumber";
+ public static final String ATTR_PUBLIC_KEY_DATA = "publicKeyData";
+ public static final String ATTR_PRIVATE_KEY_DATA = "privateKeyData";
+ public static final String ATTR_TRANSPORT_CERT = "transportCert";
+ public static final String ATTR_TRANSPORT_PWD = "transportPwd";
+ public static final String ATTR_SIGNING_CERT = "signingCert";
+ public static final String ATTR_PKCS12 = "pkcs12";
+ public static final String ATTR_ENCRYPTION_CERTS =
+ "encryptionCerts";
+ public static final String ATTR_AGENT_CREDENTIALS =
+ "agentCredentials";
+ // same as encryption certs
+ public static final String ATTR_USER_CERT = "cert";
+ public static final String ATTR_DELIVERY = "delivery";
+
+ // for Async Key Recovery
+ public static final String ATTR_APPROVE_AGENTS = "approvingAgents";
+
+ private IKeyRecoveryAuthority mKRA = null;
+ private IKeyRepository mStorage = null;
+ private IStorageKeyUnit mStorageUnit = null;
+
+ /**
+ * Constructs request processor.
+ */
+ public RecoveryService(IKeyRecoveryAuthority kra) {
+ mKRA = kra;
+ mStorage = mKRA.getKeyRepository();
+ mStorageUnit = mKRA.getStorageKeyUnit();
+ }
+
+ /**
+ * Processes a recovery request. Based on the recovery mode
+ * (either Administrator or End-Entity), the method reads
+ * the key record from the database, and tried to recover the
+ * key with the storage key unit.
+ *
+ * @param request recovery request
+ * @return operation success or not
+ * @exception EBaseException failed to serve
+ */
+ public boolean serviceRequest(IRequest request) throws EBaseException {
+
+ CryptoManager cm = null;
+ IConfigStore config = null;
+ String tokName = "";
+ CryptoToken ct = null;
+ Boolean allowEncDecrypt_recovery = false;
+
+ try {
+ cm = CryptoManager.getInstance();
+ config = CMS.getConfigStore();
+ tokName = config.getString("kra.storageUnit.hardware", "internal");
+ if (tokName.equals("internal")) {
+ CMS.debug("RecoveryService: serviceRequest: use internal token ");
+ ct = cm.getInternalCryptoToken();
+ } else {
+ CMS.debug("RecoveryService: serviceRequest: tokenName=" + tokName);
+ ct = cm.getTokenByName(tokName);
+ }
+ allowEncDecrypt_recovery = config.getBoolean("kra.allowEncDecrypt.recovery", false);
+ } catch (Exception e) {
+ CMS.debug("RecoveryService exception: use internal token :"
+ + e.toString());
+ ct = cm.getInternalCryptoToken();
+ }
+ if (ct == null) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR" + "cannot get crypto token"));
+ }
+
+ IStatsSubsystem statsSub = (IStatsSubsystem) CMS.getSubsystem("stats");
+ if (statsSub != null) {
+ statsSub.startTiming("recovery", true /* main action */);
+ }
+
+ if (Debug.ON)
+ Debug.trace("KRA services recovery request");
+ mKRA.log(ILogger.LL_INFO, "KRA services recovery request");
+
+ // byte publicKey[] = (byte[])request.get(ATTR_PUBLIC_KEY_DATA);
+ // X500Name owner = (X500Name)request.get(ATTR_OWNER_NAME);
+
+ Hashtable<String, Object> params = mKRA.getVolatileRequest(
+ request.getRequestId());
+
+ if (params == null) {
+ // possibly we are in recovery mode
+ return true;
+ }
+
+ // retrieve based on serial no
+ BigInteger serialno = request.getExtDataInBigInteger(ATTR_SERIALNO);
+
+ mKRA.log(ILogger.LL_INFO, "KRA reading key record");
+ if (statsSub != null) {
+ statsSub.startTiming("get_key");
+ }
+ KeyRecord keyRecord = (KeyRecord) mStorage.readKeyRecord(serialno);
+ if (statsSub != null) {
+ statsSub.endTiming("get_key");
+ }
+
+ // see if the certificate matches the key
+ byte pubData[] = keyRecord.getPublicKeyData();
+ X509Certificate x509cert =
+ request.getExtDataInCert(ATTR_USER_CERT);
+ byte inputPubData[] = x509cert.getPublicKey().getEncoded();
+
+ if (inputPubData.length != pubData.length) {
+ mKRA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_PUBLIC_KEY_LEN"));
+ throw new EKRAException(
+ CMS.getUserMessage("CMS_KRA_PUBLIC_KEY_NOT_MATCHED"));
+ }
+ for (int i = 0; i < pubData.length; i++) {
+ if (pubData[i] != inputPubData[i]) {
+ mKRA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_PUBLIC_KEY_LEN"));
+ throw new EKRAException(
+ CMS.getUserMessage("CMS_KRA_PUBLIC_KEY_NOT_MATCHED"));
+ }
+ }
+
+ boolean isRSA = true;
+ String keyAlg = x509cert.getPublicKey().getAlgorithm();
+ if (keyAlg != null) {
+ CMS.debug("RecoveryService: publicKey alg =" + keyAlg);
+ if (!keyAlg.equals("RSA"))
+ isRSA = false;
+ }
+
+ // Unwrap the archived private key
+ byte privateKeyData[] = null;
+ X509Certificate transportCert =
+ request.getExtDataInCert(ATTR_TRANSPORT_CERT);
+
+ if (transportCert == null) {
+ if (statsSub != null) {
+ statsSub.startTiming("recover_key");
+ }
+
+ PrivateKey privKey = null;
+ if (allowEncDecrypt_recovery == true) {
+ privateKeyData = recoverKey(params, keyRecord);
+ } else {
+ privKey = recoverKey(params, keyRecord, isRSA);
+ }
+ if (statsSub != null) {
+ statsSub.endTiming("recover_key");
+ }
+
+ if ((isRSA == true) && (allowEncDecrypt_recovery == true)) {
+ if (statsSub != null) {
+ statsSub.startTiming("verify_key");
+ }
+ // verifyKeyPair() is RSA-centric
+ if (verifyKeyPair(pubData, privateKeyData) == false) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_PUBLIC_NOT_FOUND"));
+ throw new EKRAException(
+ CMS.getUserMessage("CMS_KRA_INVALID_PUBLIC_KEY"));
+ }
+ if (statsSub != null) {
+ statsSub.endTiming("verify_key");
+ }
+ }
+
+ if (statsSub != null) {
+ statsSub.startTiming("create_p12");
+ }
+ if (allowEncDecrypt_recovery == true) {
+ createPFX(request, params, privateKeyData);
+ } else {
+ createPFX(request, params, privKey, ct);
+ }
+ if (statsSub != null) {
+ statsSub.endTiming("create_p12");
+ }
+ } else {
+
+ if (CMS.getConfigStore().getBoolean("kra.keySplitting")) {
+ Credential creds[] = (Credential[])
+ params.get(ATTR_AGENT_CREDENTIALS);
+ mKRA.getStorageKeyUnit().login(creds);
+ }
+ if (statsSub != null) {
+ statsSub.startTiming("unwrap_key");
+ }
+ mKRA.getStorageKeyUnit().unwrap(
+ keyRecord.getPrivateKeyData(), null); // throw exception on error
+ if (statsSub != null) {
+ statsSub.endTiming("unwrap_key");
+ }
+
+ if (CMS.getConfigStore().getBoolean("kra.keySplitting")) {
+ mKRA.getStorageKeyUnit().logout();
+ }
+ }
+ mKRA.log(ILogger.LL_INFO, "key " +
+ serialno.toString() +
+ " recovered");
+
+ // for audit log
+ String authMgr = AuditFormat.NOAUTH;
+ String initiative = AuditFormat.FROMUSER;
+ SessionContext sContext = SessionContext.getContext();
+
+ if (sContext != null) {
+ String agentId =
+ (String) sContext.get(SessionContext.USER_ID);
+
+ initiative = AuditFormat.FROMAGENT + " agentID: " + agentId;
+ AuthToken authToken = (AuthToken) sContext.get(SessionContext.AUTH_TOKEN);
+
+ if (authToken != null) {
+ authMgr =
+ authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ }
+ }
+ CMS.getLogger().log(ILogger.EV_AUDIT,
+ ILogger.S_KRA,
+ AuditFormat.LEVEL,
+ AuditFormat.FORMAT,
+ new Object[] {
+ IRequest.KEYRECOVERY_REQUEST,
+ request.getRequestId(),
+ initiative,
+ authMgr,
+ "completed",
+ ((X509CertImpl) x509cert).getSubjectDN(),
+ "serial number: 0x" + serialno.toString(16) }
+ );
+
+ if (statsSub != null) {
+ statsSub.endTiming("recovery");
+ }
+
+ return true;
+ }
+
+ /*
+ * verifyKeyPair()- RSA-centric key verification
+ */
+ public boolean verifyKeyPair(byte publicKeyData[], byte privateKeyData[]) {
+ try {
+ DerValue publicKeyVal = new DerValue(publicKeyData);
+ DerInputStream publicKeyIn = publicKeyVal.data;
+ publicKeyIn.getSequence(0);
+ DerValue publicKeyDer = new DerValue(publicKeyIn.getBitString());
+ DerInputStream publicKeyDerIn = publicKeyDer.data;
+ BigInt publicKeyModulus = publicKeyDerIn.getInteger();
+ BigInt publicKeyExponent = publicKeyDerIn.getInteger();
+
+ DerValue privateKeyVal = new DerValue(privateKeyData);
+ if (privateKeyVal.tag != DerValue.tag_Sequence)
+ return false;
+ DerInputStream privateKeyIn = privateKeyVal.data;
+ privateKeyIn.getInteger();
+ privateKeyIn.getSequence(0);
+ DerValue privateKeyDer = new DerValue(privateKeyIn.getOctetString());
+ DerInputStream privateKeyDerIn = privateKeyDer.data;
+
+ @SuppressWarnings("unused")
+ BigInt privateKeyVersion = privateKeyDerIn.getInteger();
+ BigInt privateKeyModulus = privateKeyDerIn.getInteger();
+ BigInt privateKeyExponent = privateKeyDerIn.getInteger();
+
+ if (!publicKeyModulus.equals(privateKeyModulus)) {
+ CMS.debug("verifyKeyPair modulus mismatch publicKeyModulus="
+ + publicKeyModulus + " privateKeyModulus=" + privateKeyModulus);
+ return false;
+ }
+
+ if (!publicKeyExponent.equals(privateKeyExponent)) {
+ CMS.debug("verifyKeyPair exponent mismatch publicKeyExponent="
+ + publicKeyExponent + " privateKeyExponent=" + privateKeyExponent);
+ return false;
+ }
+
+ return true;
+ } catch (Exception e) {
+ CMS.debug("verifyKeyPair error " + e);
+ return false;
+ }
+ }
+
+ /**
+ * Recovers key. (using unwrapping/wrapping on token)
+ * - used when allowEncDecrypt_recovery is false
+ */
+ public synchronized PrivateKey recoverKey(Hashtable<String, Object> request, KeyRecord keyRecord, boolean isRSA)
+ throws EBaseException {
+
+ if (!isRSA) {
+ CMS.debug("RecoverService: recoverKey: currently, non-RSA keys are not supported when allowEncDecrypt_ is false");
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_RECOVERY_FAILED_1", "key type not supported"));
+ }
+ try {
+ if (CMS.getConfigStore().getBoolean("kra.keySplitting")) {
+ Credential creds[] = (Credential[])
+ request.get(ATTR_AGENT_CREDENTIALS);
+
+ mStorageUnit.login(creds);
+ }
+
+ /* wrapped retrieve session key and private key */
+ DerValue val = new DerValue(keyRecord.getPrivateKeyData());
+ DerInputStream in = val.data;
+ DerValue dSession = in.getDerValue();
+ byte session[] = dSession.getOctetString();
+ DerValue dPri = in.getDerValue();
+ byte pri[] = dPri.getOctetString();
+
+ /* debug */
+ byte publicKeyData[] = keyRecord.getPublicKeyData();
+ PublicKey pubkey = null;
+ try {
+ pubkey = X509Key.parsePublicKey(new DerValue(publicKeyData));
+ } catch (Exception e) {
+ CMS.debug("RecoverService: after parsePublicKey:" + e.toString());
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_RECOVERY_FAILED_1", "pubic key parsing failure"));
+ }
+ byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
+ PrivateKey privKey =
+ mStorageUnit.unwrap(
+ session,
+ keyRecord.getAlgorithm(),
+ iv,
+ pri,
+ (PublicKey) pubkey);
+
+ if (privKey == null) {
+ mKRA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_PRIVATE_KEY_NOT_FOUND"));
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_RECOVERY_FAILED_1",
+ "private key unwrapping failure"));
+ }
+ if (CMS.getConfigStore().getBoolean("kra.keySplitting")) {
+ mStorageUnit.logout();
+ }
+ return privKey;
+ } catch (Exception e) {
+ CMS.debug("RecoverService: recoverKey() failed with allowEncDecrypt_recovery=false:" + e.toString());
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_RECOVERY_FAILED_1",
+ "recoverKey() failed with allowEncDecrypt_recovery=false:" + e.toString()));
+ }
+ }
+
+ /**
+ * Creates a PFX (PKCS12) file. (the unwrapping/wrapping way)
+ * - used when allowEncDecrypt_recovery is false
+ *
+ * @param request CRMF recovery request
+ * @param priKey private key handle
+ * @exception EBaseException failed to create P12 file
+ */
+ public void createPFX(IRequest request, Hashtable<String, Object> params,
+ PrivateKey priKey, CryptoToken ct) throws EBaseException {
+ CMS.debug("RecoverService: createPFX() allowEncDecrypt_recovery=false");
+ try {
+ // create p12
+ X509Certificate x509cert =
+ request.getExtDataInCert(ATTR_USER_CERT);
+ String pwd = (String) params.get(ATTR_TRANSPORT_PWD);
+
+ // add certificate
+ mKRA.log(ILogger.LL_INFO, "KRA adds certificate to P12");
+ CMS.debug("RecoverService: createPFX() adds certificate to P12");
+ SEQUENCE encSafeContents = new SEQUENCE();
+ ASN1Value cert = new OCTET_STRING(x509cert.getEncoded());
+ String nickname = request.getExtDataInString(ATTR_NICKNAME);
+
+ if (nickname == null) {
+ nickname = x509cert.getSubjectDN().toString();
+ }
+ byte localKeyId[] = createLocalKeyId(x509cert);
+ SET certAttrs = createBagAttrs(
+ nickname, 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
+ mKRA.log(ILogger.LL_INFO, "KRA adds key to P12");
+ CMS.debug("RecoverService: createPFX() adds key to P12");
+ org.mozilla.jss.util.Password pass = new
+ org.mozilla.jss.util.Password(
+ pwd.toCharArray());
+
+ SEQUENCE safeContents = new SEQUENCE();
+ PasswordConverter passConverter = new
+ PasswordConverter();
+ byte salt[] = { 0x01, 0x01, 0x01, 0x01 };
+
+ ASN1Value key = EncryptedPrivateKeyInfo.createPBE(
+ PBEAlgorithm.PBE_SHA1_DES3_CBC,
+ pass, salt, 1, passConverter, priKey, ct);
+
+ 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
+ params.put(ATTR_PKCS12, fos.toByteArray());
+ } catch (Exception e) {
+ mKRA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_CONSTRUCT_P12", e.toString()));
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_PKCS12_FAILED_1", e.toString()));
+ }
+
+ // update request
+ mKRA.getRequestQueue().updateRequest(request);
+ }
+
+ /**
+ * Recovers key.
+ * - used when allowEncDecrypt_recovery is true
+ */
+ public synchronized byte[] recoverKey(Hashtable<String, Object> request, KeyRecord keyRecord)
+ throws EBaseException {
+ if (CMS.getConfigStore().getBoolean("kra.keySplitting")) {
+ Credential creds[] = (Credential[])
+ request.get(ATTR_AGENT_CREDENTIALS);
+
+ mStorageUnit.login(creds);
+ }
+ mKRA.log(ILogger.LL_INFO, "KRA decrypts internal private");
+ byte privateKeyData[] =
+ mStorageUnit.decryptInternalPrivate(
+ keyRecord.getPrivateKeyData());
+
+ if (CMS.getConfigStore().getBoolean("kra.keySplitting")) {
+ mStorageUnit.logout();
+ }
+ if (privateKeyData == null) {
+ mKRA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_PRIVATE_KEY_NOT_FOUND"));
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_RECOVERY_FAILED_1", "no private key"));
+ }
+ return privateKeyData;
+ }
+
+ /**
+ * Creates a PFX (PKCS12) file.
+ * - used when allowEncDecrypt_recovery is true
+ *
+ * @param request CRMF recovery request
+ * @param priData decrypted private key (PrivateKeyInfo)
+ * @exception EBaseException failed to create P12 file
+ */
+ public void createPFX(IRequest request, Hashtable<String, Object> params,
+ byte priData[]) throws EBaseException {
+ CMS.debug("RecoverService: createPFX() allowEncDecrypt_recovery=true");
+ try {
+ // create p12
+ X509Certificate x509cert =
+ request.getExtDataInCert(ATTR_USER_CERT);
+ String pwd = (String) params.get(ATTR_TRANSPORT_PWD);
+
+ // add certificate
+ mKRA.log(ILogger.LL_INFO, "KRA adds certificate to P12");
+ SEQUENCE encSafeContents = new SEQUENCE();
+ ASN1Value cert = new OCTET_STRING(x509cert.getEncoded());
+ String nickname = request.getExtDataInString(ATTR_NICKNAME);
+
+ if (nickname == null) {
+ nickname = x509cert.getSubjectDN().toString();
+ }
+ byte localKeyId[] = createLocalKeyId(x509cert);
+ SET certAttrs = createBagAttrs(
+ nickname, 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
+ mKRA.log(ILogger.LL_INFO, "KRA adds key to P12");
+ org.mozilla.jss.util.Password pass = new
+ org.mozilla.jss.util.Password(
+ pwd.toCharArray());
+
+ SEQUENCE safeContents = new SEQUENCE();
+ PasswordConverter passConverter = new
+ PasswordConverter();
+ byte salt[] = { 0x01, 0x01, 0x01, 0x01 };
+ 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);
+
+ // 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
+ params.put(ATTR_PKCS12, fos.toByteArray());
+ } catch (Exception e) {
+ mKRA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_CONSTRUCT_P12", e.toString()));
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_PKCS12_FAILED_1", e.toString()));
+ }
+
+ // update request
+ mKRA.getRequestQueue().updateRequest(request);
+ }
+
+ /**
+ * Creates local key identifier.
+ */
+ public byte[] createLocalKeyId(X509Certificate cert)
+ throws EBaseException {
+ try {
+ // SHA1 hash of the X509Cert der encoding
+ byte certDer[] = cert.getEncoded();
+
+ // XXX - should use JSS
+ MessageDigest md = MessageDigest.getInstance("SHA");
+
+ md.update(certDer);
+ return md.digest();
+ } catch (CertificateEncodingException e) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_CREAT_KEY_ID", e.toString()));
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_KEYID_FAILED_1", e.toString()));
+ } catch (NoSuchAlgorithmException e) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_CREAT_KEY_ID", e.toString()));
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_KEYID_FAILED_1", e.toString()));
+ }
+ }
+
+ /**
+ * Creates bag attributes.
+ */
+ public 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 (CharConversionException e) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_CREAT_KEY_BAG", e.toString()));
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_KEYBAG_FAILED_1", e.toString()));
+ }
+ }
+}
diff --git a/base/kra/src/com/netscape/kra/SecurityDataRecoveryService.java b/base/kra/src/com/netscape/kra/SecurityDataRecoveryService.java
new file mode 100644
index 000000000..f96ece890
--- /dev/null
+++ b/base/kra/src/com/netscape/kra/SecurityDataRecoveryService.java
@@ -0,0 +1,388 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.kra;
+
+import java.io.ByteArrayOutputStream;
+import java.io.CharConversionException;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Hashtable;
+import java.util.Random;
+
+import javax.crypto.spec.RC2ParameterSpec;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.crypto.Cipher;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.EncryptionAlgorithm;
+import org.mozilla.jss.crypto.IVParameterSpec;
+import org.mozilla.jss.crypto.KeyGenerator;
+import org.mozilla.jss.crypto.KeyWrapAlgorithm;
+import org.mozilla.jss.crypto.KeyWrapper;
+import org.mozilla.jss.crypto.PBEAlgorithm;
+import org.mozilla.jss.crypto.PBEKeyGenParams;
+import org.mozilla.jss.crypto.SymmetricKey;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.pkcs12.PasswordConverter;
+import org.mozilla.jss.pkcs7.ContentInfo;
+import org.mozilla.jss.pkcs7.EncryptedContentInfo;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.pkix.primitive.PBEParameter;
+import org.mozilla.jss.util.Password;
+
+import com.netscape.certsrv.kra.EKRAException;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.request.IService;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.security.IStorageKeyUnit;
+import com.netscape.certsrv.security.ITransportKeyUnit;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.cms.servlet.request.KeyRequestResource;
+import com.netscape.cmscore.dbs.KeyRecord;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * This implementation services SecurityData Recovery requests.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+@SuppressWarnings("deprecation")
+public class SecurityDataRecoveryService implements IService {
+
+ private IKeyRecoveryAuthority mKRA = null;
+
+ private IKeyRepository mStorage = null;
+ private IStorageKeyUnit mStorageUnit = null;
+ private ITransportKeyUnit mTransportUnit = null;
+
+ public static final String ATTR_SERIALNO = "serialNumber";
+ public static final String ATTR_KEY_RECORD = "keyRecord";
+
+ public SecurityDataRecoveryService(IKeyRecoveryAuthority kra) {
+ mKRA = kra;
+ mStorage = mKRA.getKeyRepository();
+ mStorageUnit = mKRA.getStorageKeyUnit();
+ mTransportUnit = mKRA.getTransportKeyUnit();
+
+ }
+
+ /**
+ * Performs the service (such as certificate generation)
+ * represented by this request.
+ * <p>
+ *
+ * @param request
+ * The SecurityData recovery 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.
+ */
+ public boolean serviceRequest(IRequest request)
+ throws EBaseException {
+
+ //Pave the way for allowing generated IV vector
+ byte iv[]= null;
+ byte iv_default[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
+ byte iv_in[] = null;
+
+ Hashtable<String, Object> params = mKRA.getVolatileRequest(
+ request.getRequestId());
+
+ if (params == null) {
+ CMS.debug("Can't get volatile params.");
+ throw new EBaseException("Can't obtain volatile params!");
+ }
+
+ BigInteger serialno = request.getExtDataInBigInteger(ATTR_SERIALNO);
+
+ request.setExtData(ATTR_KEY_RECORD, serialno);
+
+ byte[] wrappedPassPhrase = null;
+ byte[] wrappedSessKey = null;
+
+ String transWrappedSessKeyStr = (String) params.get(IRequest.SECURITY_DATA_TRANS_SESS_KEY);
+ if (transWrappedSessKeyStr != null) {
+ wrappedSessKey = Utils.base64decode(transWrappedSessKeyStr);
+ }
+
+ String sessWrappedPassPhraseStr = (String) params.get(IRequest.SECURITY_DATA_SESS_PASS_PHRASE);
+ if (sessWrappedPassPhraseStr != null) {
+ wrappedPassPhrase = Utils.base64decode(sessWrappedPassPhraseStr);
+ }
+
+ String ivInStr = (String) params.get(IRequest.SECURITY_DATA_IV_STRING_IN);
+ if (ivInStr != null) {
+ iv_in = Utils.base64decode(ivInStr);
+ }
+
+ if (transWrappedSessKeyStr == null && sessWrappedPassPhraseStr == null) {
+ //We may be in recovery case where no params were initially submitted.
+ return false;
+ }
+
+ //Create the return IV if needed.
+ iv = new byte[8];
+
+ try {
+ Random rnd = new Random();
+ rnd.nextBytes(iv);
+ } catch (Exception e) {
+ iv = iv_default;
+ }
+
+ String ivStr = Utils.base64encode(iv);
+
+ KeyRecord keyRecord = (KeyRecord) mStorage.readKeyRecord(serialno);
+
+ SymmetricKey unwrappedSess = null;
+
+ String dataType = (String) keyRecord.get(IKeyRecord.ATTR_DATA_TYPE);
+ SymmetricKey symKey = null;
+ byte[] unwrappedSecData = null;
+ if (dataType.equals(KeyRequestResource.SYMMETRIC_KEY_TYPE)) {
+ symKey = recoverSymKey(keyRecord);
+ } else if (dataType.equals(KeyRequestResource.PASS_PHRASE_TYPE)) {
+ unwrappedSecData = recoverSecurityData(keyRecord);
+ }
+
+ CryptoToken ct = mTransportUnit.getToken();
+
+ byte[] key_data = null;
+ String pbeWrappedData = null;
+
+ if (sessWrappedPassPhraseStr != null) { //We have a trans wrapped pass phrase, we will be doing PBE packaging
+ byte[] unwrappedPass = null;
+ Password pass = null;
+
+ try {
+ unwrappedSess = mTransportUnit.unwrap_sym(wrappedSessKey, SymmetricKey.Usage.DECRYPT);
+ Cipher decryptor = ct.getCipherContext(EncryptionAlgorithm.DES3_CBC_PAD);
+ decryptor.initDecrypt(unwrappedSess, new IVParameterSpec(iv_in));
+ unwrappedPass = decryptor.doFinal(wrappedPassPhrase);
+ String passStr = new String(unwrappedPass, "UTF-8");
+
+ pass = new Password(passStr.toCharArray());
+ passStr = null;
+
+ if (dataType.equals(KeyRequestResource.SYMMETRIC_KEY_TYPE)) {
+ pbeWrappedData = createEncryptedContentInfo(ct, symKey, null,
+ pass);
+ } else if (dataType.equals(KeyRequestResource.PASS_PHRASE_TYPE)) {
+ pbeWrappedData = createEncryptedContentInfo(ct, null, unwrappedSecData,
+ pass);
+ }
+
+ params.put(IRequest.SECURITY_DATA_PASS_WRAPPED_DATA, pbeWrappedData);
+
+ } catch (Exception e) {
+ throw new EBaseException("Can't unwrap pass phase! " + e.toString());
+ } finally {
+ if ( pass != null) {
+ pass.clear();
+ }
+
+ if ( unwrappedPass != null) {
+ java.util.Arrays.fill(unwrappedPass, (byte) 0);
+ }
+ }
+
+ } else { // No trans wrapped pass phrase, return session wrapped data.
+ if (dataType.equals(KeyRequestResource.SYMMETRIC_KEY_TYPE)) {
+ //wrap the key with session key
+ try {
+ unwrappedSess = mTransportUnit.unwrap_sym(wrappedSessKey, SymmetricKey.Usage.WRAP);
+ KeyWrapper wrapper = ct.getKeyWrapper(KeyWrapAlgorithm.DES3_CBC_PAD);
+ wrapper.initWrap(unwrappedSess, new IVParameterSpec(iv));
+ key_data = wrapper.wrap(symKey);
+ } catch (Exception e) {
+ throw new EBaseException("Can't wrap symmetric key! " + e.toString());
+ }
+
+ } else if (dataType.equals(KeyRequestResource.PASS_PHRASE_TYPE)) {
+ try {
+ unwrappedSess = mTransportUnit.unwrap_sym(wrappedSessKey, SymmetricKey.Usage.ENCRYPT);
+ Cipher encryptor = ct.getCipherContext(EncryptionAlgorithm.DES3_CBC_PAD);
+ if (encryptor != null) {
+ encryptor.initEncrypt(unwrappedSess, new IVParameterSpec(iv));
+ key_data = encryptor.doFinal(unwrappedSecData);
+ } else {
+ throw new IOException("Failed to create cipher");
+ }
+ } catch (Exception e) {
+ throw new EBaseException("Can't wrap pass phrase!");
+ }
+ }
+
+ String wrappedKeyData = Utils.base64encode(key_data);
+ params.put(IRequest.SECURITY_DATA_SESS_WRAPPED_DATA, wrappedKeyData);
+ params.put(IRequest.SECURITY_DATA_IV_STRING_OUT, ivStr);
+
+ }
+ return false;
+ }
+
+ public SymmetricKey recoverSymKey(KeyRecord keyRecord)
+ throws EBaseException {
+
+ try {
+ SymmetricKey symKey =
+ mStorageUnit.unwrap(
+ keyRecord.getPrivateKeyData());
+
+ if (symKey == null) {
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_RECOVERY_FAILED_1",
+ "symmetric key unwrapping failure"));
+ }
+
+ return symKey;
+ } catch (Exception e) {
+
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_RECOVERY_FAILED_1",
+ "recoverSymKey() " + e.toString()));
+ }
+ }
+
+ public byte[] recoverSecurityData(KeyRecord keyRecord)
+ throws EBaseException {
+
+ byte[] decodedData = null;
+
+ try {
+ decodedData = mStorageUnit.decryptInternalPrivate(
+ keyRecord.getPrivateKeyData());
+
+ if (decodedData == null) {
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_RECOVERY_FAILED_1",
+ "security data unwrapping failure"));
+ }
+
+ return decodedData;
+ } catch (Exception e) {
+
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_RECOVERY_FAILED_1",
+ "recoverSecurityData() " + e.toString()));
+ }
+ }
+
+ //ToDo: This might fit in JSS.
+ private static EncryptedContentInfo
+ createEncryptedContentInfoPBEOfSymmKey(PBEAlgorithm keyGenAlg, Password password, byte[] salt,
+ int iterationCount,
+ KeyGenerator.CharToByteConverter charToByteConverter,
+ SymmetricKey symKey, CryptoToken token)
+ throws CryptoManager.NotInitializedException, NoSuchAlgorithmException,
+ InvalidKeyException, InvalidAlgorithmParameterException, TokenException,
+ CharConversionException {
+
+ if (!(keyGenAlg instanceof PBEAlgorithm)) {
+ throw new NoSuchAlgorithmException("Key generation algorithm" +
+ " is not a PBE algorithm");
+ }
+ PBEAlgorithm pbeAlg = (PBEAlgorithm) keyGenAlg;
+
+ KeyGenerator kg = token.getKeyGenerator(keyGenAlg);
+ PBEKeyGenParams pbekgParams = new PBEKeyGenParams(
+ password, salt, iterationCount);
+ if (charToByteConverter != null) {
+ kg.setCharToByteConverter(charToByteConverter);
+ }
+ kg.initialize(pbekgParams);
+ SymmetricKey key = kg.generate();
+
+ EncryptionAlgorithm encAlg = pbeAlg.getEncryptionAlg();
+ AlgorithmParameterSpec params = null;
+ if (encAlg.getParameterClass().equals(IVParameterSpec.class)) {
+ params = new IVParameterSpec(kg.generatePBE_IV());
+ } else if (encAlg.getParameterClass().equals(
+ RC2ParameterSpec.class)) {
+ params = new RC2ParameterSpec(key.getStrength(),
+ kg.generatePBE_IV());
+ }
+
+ KeyWrapper wrapper = token.getKeyWrapper(
+ KeyWrapAlgorithm.DES3_CBC_PAD);
+ wrapper.initWrap(key, params);
+ byte encrypted[] = wrapper.wrap(symKey);
+
+ PBEParameter pbeParam = new PBEParameter(salt, iterationCount);
+ AlgorithmIdentifier encAlgID = new AlgorithmIdentifier(
+ keyGenAlg.toOID(), pbeParam);
+
+ EncryptedContentInfo encCI = new EncryptedContentInfo(
+ ContentInfo.DATA,
+ encAlgID,
+ new OCTET_STRING(encrypted));
+
+ return encCI;
+
+ }
+
+ private static String createEncryptedContentInfo(CryptoToken ct, SymmetricKey symKey, byte[] securityData,
+ Password password)
+ throws EBaseException {
+
+ EncryptedContentInfo cInfo = null;
+ String retData = null;
+ PBEAlgorithm keyGenAlg = PBEAlgorithm.PBE_SHA1_DES3_CBC;
+
+ byte[] encoded = null;
+ try {
+ PasswordConverter passConverter = new
+ PasswordConverter();
+ byte salt[] = { 0x01, 0x01, 0x01, 0x01 };
+ if (symKey != null) {
+
+ cInfo = createEncryptedContentInfoPBEOfSymmKey(keyGenAlg, password, salt,
+ 1,
+ passConverter,
+ symKey, ct);
+
+ } else if (securityData != null) {
+
+ cInfo = EncryptedContentInfo.createPBE(keyGenAlg, password, salt, 1, passConverter, securityData);
+ }
+
+ if(cInfo == null) {
+ throw new EBaseException("Can't create a PBE wrapped EncryptedContentInfo!");
+ }
+
+ ByteArrayOutputStream oStream = new ByteArrayOutputStream();
+ cInfo.encode(oStream);
+ encoded = oStream.toByteArray();
+ retData = Utils.base64encode(encoded);
+
+ } catch (Exception e) {
+ throw new EBaseException("Can't create a PBE wrapped EncryptedContentInfo! " + e.toString());
+ }
+
+ return retData;
+ }
+
+}
diff --git a/base/kra/src/com/netscape/kra/SecurityDataService.java b/base/kra/src/com/netscape/kra/SecurityDataService.java
new file mode 100644
index 000000000..fa009dac9
--- /dev/null
+++ b/base/kra/src/com/netscape/kra/SecurityDataService.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.kra;
+
+import java.math.BigInteger;
+import org.mozilla.jss.crypto.SymmetricKey;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.request.IService;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.security.IStorageKeyUnit;
+import com.netscape.certsrv.security.ITransportKeyUnit;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.cms.servlet.request.KeyRequestResource;
+import com.netscape.cmscore.dbs.KeyRecord;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * This implementation implements SecurityData archival operations.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public class SecurityDataService implements IService {
+
+ private final static String DEFAULT_OWNER = "IPA Agent";
+ public final static String ATTR_KEY_RECORD = "keyRecord";
+ private final static String STATUS_ACTIVE = "active";
+
+ private IKeyRecoveryAuthority mKRA = null;
+ private ITransportKeyUnit mTransportUnit = null;
+ private IStorageKeyUnit mStorageUnit = null;
+
+ public SecurityDataService(IKeyRecoveryAuthority kra) {
+ mKRA = kra;
+ mTransportUnit = kra.getTransportKeyUnit();
+ mStorageUnit = kra.getStorageKeyUnit();
+ }
+
+ /**
+ * Performs the service of archiving Security Data.
+ * 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.
+ */
+ public boolean serviceRequest(IRequest request)
+ throws EBaseException {
+ String id = request.getRequestId().toString();
+ String clientId = request.getExtDataInString(IRequest.SECURITY_DATA_CLIENT_ID);
+ String wrappedSecurityData = request.getExtDataInString(IEnrollProfile.REQUEST_ARCHIVE_OPTIONS);
+ String dataType = request.getExtDataInString(IRequest.SECURITY_DATA_TYPE);
+
+ CMS.debug("SecurityDataService.serviceRequest. Request id: " + id);
+ CMS.debug("SecurityDataService.serviceRequest wrappedSecurityData: " + wrappedSecurityData);
+
+ String owner = getOwnerName(request);
+
+ //Check here even though restful layer checks for this.
+ if(wrappedSecurityData == null || clientId == null || dataType == null) {
+ throw new EBaseException("Bad data in SecurityDataService.serviceRequest");
+ }
+ //We need some info from the PKIArchiveOptions wrapped security data
+
+ byte[] encoded = Utils.base64decode(wrappedSecurityData);
+
+ ArchiveOptions options = ArchiveOptions.toArchiveOptions(encoded);
+
+ //Check here just in case a null ArchiveOptions makes it this far
+ if(options == null) {
+ throw new EBaseException("Problem decofing PKIArchiveOptions.");
+ }
+
+ String algStr = options.getSymmAlgOID();
+
+ SymmetricKey securitySymKey = null;
+ byte[] securityData = null;
+
+ String keyType = null;
+ if (dataType.equals(KeyRequestResource.SYMMETRIC_KEY_TYPE)) {
+ // Symmetric Key
+ keyType = KeyRequestResource.SYMMETRIC_KEY_TYPE;
+ securitySymKey = mTransportUnit.unwrap_symmetric(options.getEncSymmKey(),
+ options.getSymmAlgOID(),
+ options.getSymmAlgParams(),
+ options.getEncValue());
+
+ } else if (dataType.equals(KeyRequestResource.PASS_PHRASE_TYPE)) {
+ keyType = KeyRequestResource.PASS_PHRASE_TYPE;
+ securityData = mTransportUnit.decryptExternalPrivate(options.getEncSymmKey(),
+ options.getSymmAlgOID(),
+ options.getSymmAlgParams(),
+ options.getEncValue());
+
+ }
+
+ byte[] publicKey = null;
+ byte privateSecurityData[] = null;
+
+ if (securitySymKey != null) {
+ privateSecurityData = mStorageUnit.wrap(securitySymKey);
+ } else if (securityData != null) {
+ privateSecurityData = mStorageUnit.encryptInternalPrivate(securityData);
+ } else { // We have no data.
+ throw new EBaseException("Failed to create security data to archive!");
+ }
+ // create key record
+ KeyRecord rec = new KeyRecord(null, publicKey,
+ privateSecurityData, owner,
+ algStr, owner);
+
+ rec.set(IKeyRecord.ATTR_CLIENT_ID, clientId);
+
+ //Now we need a serial number for our new key.
+
+ if (rec.getSerialNumber() != null) {
+ throw new EBaseException(CMS.getUserMessage("CMS_KRA_INVALID_STATE"));
+ }
+
+ IKeyRepository storage = mKRA.getKeyRepository();
+ BigInteger serialNo = storage.getNextSerialNumber();
+
+ if (serialNo == null) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_GET_NEXT_SERIAL"));
+ throw new EBaseException(CMS.getUserMessage("CMS_KRA_INVALID_STATE"));
+ }
+
+ rec.set(KeyRecord.ATTR_ID, serialNo);
+ rec.set(KeyRecord.ATTR_DATA_TYPE, keyType);
+ rec.set(KeyRecord.ATTR_STATUS, STATUS_ACTIVE);
+ request.setExtData(ATTR_KEY_RECORD, serialNo);
+
+ CMS.debug("KRA adding Security Data key record " + serialNo);
+
+ storage.addKeyRecord(rec);
+
+ return true;
+
+ }
+ //ToDo: return real owner with auth
+ private String getOwnerName(IRequest request) {
+ return DEFAULT_OWNER;
+ }
+} \ No newline at end of file
diff --git a/base/kra/src/com/netscape/kra/StorageKeyUnit.java b/base/kra/src/com/netscape/kra/StorageKeyUnit.java
new file mode 100644
index 000000000..c956bf8d8
--- /dev/null
+++ b/base/kra/src/com/netscape/kra/StorageKeyUnit.java
@@ -0,0 +1,978 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.kra;
+
+import java.io.CharConversionException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.cert.CertificateEncodingException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.BadPaddingException;
+import org.mozilla.jss.crypto.Cipher;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.EncryptionAlgorithm;
+import org.mozilla.jss.crypto.IllegalBlockSizeException;
+import org.mozilla.jss.crypto.KeyGenerator;
+import org.mozilla.jss.crypto.KeyWrapAlgorithm;
+import org.mozilla.jss.crypto.KeyWrapper;
+import org.mozilla.jss.crypto.ObjectNotFoundException;
+import org.mozilla.jss.crypto.PBEAlgorithm;
+import org.mozilla.jss.crypto.PBEKeyGenParams;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.crypto.SymmetricKey;
+import org.mozilla.jss.crypto.TokenCertificate;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.util.Password;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.kra.EKRAException;
+import com.netscape.certsrv.kra.IJoinShares;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.kra.IShare;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.security.Credential;
+import com.netscape.certsrv.security.IStorageKeyUnit;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * A class represents a storage key unit. Currently, this
+ * is implemented with cryptix, the final implementation
+ * should be built on JSS/HCL.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class StorageKeyUnit extends EncryptionUnit implements
+ ISubsystem, IStorageKeyUnit {
+
+ private IConfigStore mConfig = null;
+
+ // private RSAPublicKey mPublicKey = null;
+ // private RSAPrivateKey mPrivateKey = null;
+
+ private IConfigStore mStorageConfig = null;
+ private IKeyRecoveryAuthority mKRA = null;
+ private String mTokenFile = null;
+ private X509Certificate mCert = null;
+ private CryptoManager mManager = null;
+ private CryptoToken mToken = null;
+ private PrivateKey mPrivateKey = null;
+ private byte mPrivateKeyData[] = null;
+ private boolean mKeySplitting = false;
+
+ private static final String PROP_N = "n";
+ private static final String PROP_M = "m";
+ private static final String PROP_UID = "uid";
+ private static final String PROP_SHARE = "share";
+ private static final String PROP_HARDWARE = "hardware";
+ private static final String PROP_LOGOUT = "logout";
+ public static final String PROP_NICKNAME = "nickName";
+ public static final String PROP_KEYDB = "keydb";
+ public static final String PROP_CERTDB = "certdb";
+ public static final String PROP_MN = "mn";
+
+ /**
+ * Constructs this token.
+ */
+ public StorageKeyUnit() {
+ super();
+ }
+
+ /**
+ * Retrieves subsystem identifier.
+ */
+ public String getId() {
+ return "storageKeyUnit";
+ }
+
+ /**
+ * Sets subsystem identifier. Once the system is
+ * loaded, system identifier cannot be changed
+ * dynamically.
+ */
+ public void setId(String id) throws EBaseException {
+ throw new EBaseException(CMS.getUserMessage("CMS_INVALID_OPERATION"));
+ }
+
+ /**
+ * return true if byte arrays are equal, false otherwise
+ */
+ private boolean byteArraysMatch(byte a[], byte b[]) {
+ if (a == null || b == null) {
+ return false;
+ }
+ if (a.length != b.length) {
+ return false;
+ }
+ for (int i = 0; i < a.length; i++) {
+ if (a[i] != b[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Initializes this subsystem.
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mKRA = (IKeyRecoveryAuthority) owner;
+ mConfig = config;
+
+ mKeySplitting = owner.getConfigStore().getBoolean("keySplitting", false);
+
+ try {
+ mManager = CryptoManager.getInstance();
+ mToken = getToken();
+ } catch (org.mozilla.jss.CryptoManager.NotInitializedException e) {
+ mKRA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_STORAGE_INIT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ }
+
+ if (mConfig.getString(PROP_HARDWARE, null) != null) {
+ System.setProperty("cms.skip_token", mConfig.getString(PROP_HARDWARE));
+
+ // The strategy here is to read all the certs in the token
+ // and cycle through them until we find one that matches the
+ // kra-cert.db file
+
+ if (mKeySplitting) {
+
+ byte certFileData[] = null;
+ try {
+ File certFile = new File(
+ mConfig.getString(PROP_CERTDB));
+
+ certFileData = new byte[
+ (Long.valueOf(certFile.length())).intValue()];
+ FileInputStream fi = new FileInputStream(certFile);
+
+ fi.read(certFileData);
+ fi.close();
+
+ // pick up cert by nickName
+
+ } catch (IOException e) {
+ mKRA.log(ILogger.LL_INFO,
+ CMS.getLogMessage("CMSCORE_KRA_STORAGE_READ_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ }
+
+ try {
+ X509Certificate certs[] =
+ getToken().getCryptoStore().getCertificates();
+ for (int i = 0; i < certs.length; i++) {
+ if (byteArraysMatch(certs[i].getEncoded(), certFileData)) {
+ mCert = certs[i];
+ }
+ }
+ if (mCert == null) {
+ mKRA.log(ILogger.LL_FAILURE,
+ "Storage Cert could not be initialized. No cert in token matched kra-cert file");
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", "mCert == null"));
+ } else {
+ mKRA.log(ILogger.LL_INFO, "Using Storage Cert " + mCert.getSubjectDN());
+ }
+ } catch (CertificateEncodingException e) {
+ mKRA.log(ILogger.LL_FAILURE, "Error encoding cert ");
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ } catch (TokenException e) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_STORAGE_READ_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ }
+ }
+
+ } else {
+
+ // read certificate from file
+ byte certData[] = null;
+
+ try {
+ if (mKeySplitting) {
+ File certFile = new File(
+ mConfig.getString(PROP_CERTDB));
+
+ certData = new byte[
+ (Long.valueOf(certFile.length())).intValue()];
+ FileInputStream fi = new FileInputStream(certFile);
+
+ fi.read(certData);
+ fi.close();
+
+ // pick up cert by nickName
+ mCert = mManager.findCertByNickname(
+ config.getString(PROP_NICKNAME));
+
+ } else {
+ mCert = mManager.findCertByNickname(
+ config.getString(PROP_NICKNAME));
+ }
+ } catch (IOException e) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_STORAGE_READ_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ } catch (TokenException e) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_STORAGE_READ_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ } catch (ObjectNotFoundException e) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_STORAGE_READ_CERT", e.toString()));
+ // XXX - this import wont work
+ try {
+ mCert = mManager.importCertPackage(certData,
+ "kraStorageCert");
+ } catch (Exception ex) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_STORAGE_IMPORT_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", ex.toString()));
+ }
+ }
+
+ if (mKeySplitting) {
+ // read private key from the file
+ try {
+ File priFile = new File(mConfig.getString(PROP_KEYDB));
+
+ mPrivateKeyData = new byte[
+ (Long.valueOf(priFile.length())).intValue()];
+ FileInputStream fi = new FileInputStream(priFile);
+
+ fi.read(mPrivateKeyData);
+ fi.close();
+ } catch (IOException e) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_STORAGE_READ_PRIVATE", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1", e.toString()));
+ }
+ }
+
+ }
+
+ if (mKeySplitting) {
+ // open internal data storage configuration
+ mTokenFile = mConfig.getString(PROP_MN);
+ try {
+ // read m, n and no of identifier
+ mStorageConfig = CMS.createFileConfigStore(mTokenFile);
+ } catch (EBaseException e) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_STORAGE_READ_MN",
+ e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_OPERATION"));
+
+ }
+ }
+
+ try {
+ if (mCert == null) {
+ CMS.debug("mCert is null...retrieving " + config.getString(PROP_NICKNAME));
+ mCert = mManager.findCertByNickname(
+ config.getString(PROP_NICKNAME));
+ CMS.debug("mCert = " + mCert);
+ }
+ } catch (Exception e) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_STORAGE_READ_CERT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ }
+
+ }
+
+ /**
+ * Starts up this subsystem.
+ */
+ public void startup() throws EBaseException {
+ }
+
+ /**
+ * Shutdowns this subsystem.
+ */
+ public void shutdown() {
+ }
+
+ /**
+ * Returns the configuration store of this token.
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public static SymmetricKey buildSymmetricKeyWithInternalStorage(
+ String pin) throws EBaseException {
+ try {
+ return buildSymmetricKey(CryptoManager.getInstance().getInternalKeyStorageToken(), pin);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Builds symmetric key from the given password.
+ */
+ public static SymmetricKey buildSymmetricKey(CryptoToken token,
+ String pin) throws EBaseException {
+ try {
+
+ Password pass = new Password(pin.toCharArray());
+ KeyGenerator kg = null;
+
+ kg = token.getKeyGenerator(
+ PBEAlgorithm.PBE_SHA1_DES3_CBC);
+ byte salt[] = { 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01 };
+ PBEKeyGenParams kgp = new PBEKeyGenParams(pass,
+ salt, 5);
+
+ pass.clear();
+ kg.initialize(kgp);
+ return kg.generate();
+ } catch (TokenException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1",
+ "buildSymmetricKey:" +
+ e.toString()));
+ } catch (NoSuchAlgorithmException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1",
+ "buildSymmetricKey:" +
+ e.toString()));
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1",
+ "buildSymmetricKey:" +
+ e.toString()));
+ } catch (CharConversionException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1",
+ "buildSymmetricKey:" +
+ e.toString()));
+ }
+ }
+
+ /**
+ * Unwraps the storage key with the given symmetric key.
+ */
+ public PrivateKey unwrapStorageKey(CryptoToken token,
+ SymmetricKey sk, byte wrapped[],
+ PublicKey pubKey)
+ throws EBaseException {
+ try {
+
+ CMS.debug("StorageKeyUnit.unwrapStorageKey.");
+
+ KeyWrapper wrapper = token.getKeyWrapper(
+ KeyWrapAlgorithm.DES3_CBC_PAD);
+
+ wrapper.initUnwrap(sk, IV);
+
+ // XXX - it does not like the public key that is
+ // not a crypto X509Certificate
+ PrivateKey pk = wrapper.unwrapTemporaryPrivate(wrapped,
+ PrivateKey.RSA, pubKey);
+
+ return pk;
+ } catch (TokenException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1",
+ "unwrapStorageKey:" +
+ e.toString()));
+ } catch (NoSuchAlgorithmException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1",
+ "unwrapStorageKey:" +
+ e.toString()));
+ } catch (InvalidKeyException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1",
+ "unwrapStorageKey:" +
+ e.toString()));
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1",
+ "unwrapStorageKey:" +
+ e.toString()));
+ }
+ }
+
+ /**
+ * Used by config-cert.
+ */
+ public byte[] wrapStorageKey(CryptoToken token,
+ SymmetricKey sk, PrivateKey pri)
+ throws EBaseException {
+ CMS.debug("StorageKeyUnit.wrapStorageKey.");
+ try {
+ // move public & private to config/storage.dat
+ // delete private key
+ KeyWrapper wrapper = token.getKeyWrapper(
+ KeyWrapAlgorithm.DES3_CBC_PAD);
+
+ // next to randomly generate a symmetric
+ // password
+
+ wrapper.initWrap(sk, IV);
+ return wrapper.wrap(pri);
+ } catch (TokenException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1",
+ "wrapStorageKey:" +
+ e.toString()));
+ } catch (NoSuchAlgorithmException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1",
+ "wrapStorageKey:" +
+ e.toString()));
+ } catch (InvalidKeyException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1",
+ "wrapStorageKey:" +
+ e.toString()));
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1",
+ "wrapStorageKey:" +
+ e.toString()));
+ }
+ }
+
+ /**
+ * Logins to this token.
+ */
+ public void login(String pin) throws EBaseException {
+ if (mConfig.getString(PROP_HARDWARE, null) != null) {
+ try {
+ getToken().login(new Password(pin.toCharArray()));
+ PrivateKey pk[] = getToken().getCryptoStore().getPrivateKeys();
+
+ for (int i = 0; i < pk.length; i++) {
+ if (arraysEqual(pk[i].getUniqueID(),
+ ((TokenCertificate) mCert).getUniqueID())) {
+ mPrivateKey = pk[i];
+ }
+ }
+ } catch (Exception e) {
+ mKRA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_STORAGE_LOGIN", e.toString()));
+ }
+
+ } else {
+ try {
+ SymmetricKey sk = buildSymmetricKey(mToken, pin);
+
+ mPrivateKey = unwrapStorageKey(mToken, sk,
+ mPrivateKeyData, getPublicKey());
+ } catch (Exception e) {
+ mKRA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_STORAGE_LOGIN", e.toString()));
+ }
+ if (mPrivateKey == null) {
+ mPrivateKey = getPrivateKey();
+ }
+ }
+ }
+
+ /**
+ * Logins to this token.
+ */
+ public void login(Credential creds[])
+ throws EBaseException {
+ String pwd = constructPassword(creds);
+
+ login(pwd);
+ }
+
+ /**
+ * Logout from this token.
+ */
+ public void logout() {
+ try {
+ if (mConfig.getString(PROP_HARDWARE, null) != null) {
+ if (mConfig.getBoolean(PROP_LOGOUT, false)) {
+ getToken().logout();
+ }
+ }
+ } catch (Exception e) {
+ mKRA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_STORAGE_LOGOUT", e.toString()));
+
+ }
+ mPrivateKey = null;
+ }
+
+ /**
+ * Returns a list of recovery agent identifiers.
+ */
+ public Enumeration<String> getAgentIdentifiers() {
+ Vector<String> v = new Vector<String>();
+
+ for (int i = 0;; i++) {
+ try {
+ String uid =
+ mStorageConfig.getString(PROP_UID + i);
+
+ if (uid == null)
+ break;
+ v.addElement(uid);
+ } catch (EBaseException e) {
+ break;
+ }
+ }
+ return v.elements();
+ }
+
+ /**
+ * Changes agent password.
+ */
+ public boolean changeAgentPassword(String id, String oldpwd,
+ String newpwd) throws EBaseException {
+ // locate the id(s)
+ for (int i = 0;; i++) {
+ try {
+ String uid =
+ mStorageConfig.getString(PROP_UID + i);
+
+ if (uid == null)
+ break;
+ if (id.equals(uid)) {
+ byte share[] = decryptShareWithInternalStorage(mStorageConfig.getString(PROP_SHARE + i), oldpwd);
+
+ mStorageConfig.putString(PROP_SHARE + i,
+ encryptShareWithInternalStorage(
+ share, newpwd));
+ mStorageConfig.commit(false);
+ return true;
+ }
+ } catch (Exception e) {
+ break;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Changes the m out of n recovery schema.
+ */
+ public boolean changeAgentMN(int new_n, int new_m,
+ Credential oldcreds[],
+ Credential newcreds[])
+ throws EBaseException {
+
+ if (new_n != newcreds.length) {
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_INVALID_N"));
+ }
+
+ // XXX - verify and construct original password
+ String secret = constructPassword(oldcreds);
+
+ // XXX - remove extra configuration
+ for (int j = new_n; j < getNoOfAgents(); j++) {
+ mStorageConfig.remove(PROP_UID + j);
+ mStorageConfig.remove(PROP_SHARE + j);
+ }
+
+ // XXX - split pwd into n pieces
+ byte shares[][] = new byte[newcreds.length][];
+
+ IShare s = null;
+ try {
+ String className = mConfig.getString("share_class",
+ "com.netscape.cms.shares.OldShare");
+ s = (IShare) Class.forName(className).newInstance();
+ } catch (Exception e) {
+ CMS.debug("Loading Shares error " + e);
+ }
+ if (s == null) {
+ CMS.debug("Share plugin is not found");
+ return false;
+ }
+
+ try {
+ s.initialize(secret.getBytes(), new_m);
+ } catch (Exception e) {
+ CMS.debug("Failed to initialize Share plugin");
+ return false;
+ }
+
+ for (int i = 0; i < newcreds.length; i++) {
+ byte share[] = s.createShare(i + 1);
+
+ shares[i] = share;
+ }
+
+ // store the new shares into configuration
+ mStorageConfig.putInteger(PROP_N, new_n);
+ mStorageConfig.putInteger(PROP_M, new_m);
+ for (int i = 0; i < newcreds.length; i++) {
+ mStorageConfig.putString(PROP_UID + i,
+ newcreds[i].getIdentifier());
+ // use password to encrypt shares...
+ mStorageConfig.putString(PROP_SHARE + i,
+ encryptShareWithInternalStorage(shares[i],
+ newcreds[i].getPassword()));
+ }
+
+ try {
+ mStorageConfig.commit(false);
+ return true;
+ } catch (EBaseException e) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_STORAGE_CHANGE_MN", e.toString()));
+ }
+ return false;
+ }
+
+ /**
+ * Returns number of recovery agents.
+ */
+ public int getNoOfAgents() throws EBaseException {
+ return mStorageConfig.getInteger(PROP_N);
+ }
+
+ /**
+ * Returns number of recovery agents required for
+ * recovery operation.
+ */
+ public int getNoOfRequiredAgents() throws EBaseException {
+ return mStorageConfig.getInteger(PROP_M);
+ }
+
+ public void setNoOfRequiredAgents(int number) {
+ mStorageConfig.putInteger(PROP_M, number);
+ }
+
+ public CryptoToken getInternalToken() {
+ try {
+ return CryptoManager.getInstance().getInternalKeyStorageToken();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public CryptoToken getToken() {
+ try {
+ if (mConfig.getString(PROP_HARDWARE, null) != null) {
+ return mManager.getTokenByName(mConfig.getString(PROP_HARDWARE));
+ } else {
+ return CryptoManager.getInstance().getInternalKeyStorageToken();
+ }
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the certificate blob.
+ */
+ public PublicKey getPublicKey() {
+ // NEED to move this key into internal storage token.
+ return mCert.getPublicKey();
+ }
+
+ public PrivateKey getPrivateKey() {
+
+ if (!mKeySplitting) {
+ try {
+ PrivateKey pk[] = getToken().getCryptoStore().getPrivateKeys();
+ for (int i = 0; i < pk.length; i++) {
+ if (arraysEqual(pk[i].getUniqueID(),
+ ((TokenCertificate) mCert).getUniqueID())) {
+ return pk[i];
+ }
+ }
+ } catch (TokenException e) {
+ }
+ return null;
+ } else {
+ return mPrivateKey;
+ }
+ }
+
+ /**
+ * Verifies the integrity of the given key pairs.
+ */
+ public void verify(byte publicKey[], PrivateKey privateKey)
+ throws EBaseException {
+ // XXX
+ }
+
+ public String encryptShareWithInternalStorage(
+ byte share[], String pwd)
+ throws EBaseException {
+ try {
+ return encryptShare(CryptoManager.getInstance().getInternalKeyStorageToken(), share, pwd);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Protectes the share with the given password.
+ */
+ public String encryptShare(CryptoToken token,
+ byte share[], String pwd)
+ throws EBaseException {
+ try {
+ CMS.debug("StorageKeyUnit.encryptShare");
+ Cipher cipher = token.getCipherContext(
+ EncryptionAlgorithm.DES3_CBC_PAD);
+ SymmetricKey sk = StorageKeyUnit.buildSymmetricKey(token, pwd);
+
+ cipher.initEncrypt(sk, IV);
+ byte prev[] = preVerify(share);
+ byte enc[] = cipher.doFinal(prev);
+
+ return Utils.base64encode(enc).trim();
+ } catch (NoSuchAlgorithmException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1",
+ e.toString()));
+ } catch (TokenException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1",
+ e.toString()));
+ } catch (InvalidKeyException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1",
+ e.toString()));
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1",
+ e.toString()));
+ } catch (BadPaddingException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1",
+ e.toString()));
+ } catch (IllegalBlockSizeException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1",
+ e.toString()));
+ }
+ }
+
+ public static byte[] preVerify(byte share[]) {
+ byte data[] = new byte[share.length + 2];
+
+ data[0] = 0;
+ data[1] = 0;
+ for (int i = 0; i < share.length; i++) {
+ data[2 + i] = share[i];
+ }
+ return data;
+ }
+
+ public static boolean verifyShare(byte share[]) {
+ if (share[0] == 0 && share[1] == 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public static byte[] postVerify(byte share[]) {
+ byte data[] = new byte[share.length - 2];
+
+ for (int i = 2; i < share.length; i++) {
+ data[i - 2] = share[i];
+ }
+ return data;
+ }
+
+ public void checkPassword(String userid, String pwd) throws EBaseException {
+ for (int i = 0;; i++) {
+ String uid = null;
+
+ try {
+ uid = mStorageConfig.getString(PROP_UID + i);
+ if (uid == null)
+ break;
+ } catch (Exception e) {
+ break;
+ }
+ if (uid.equals(userid)) {
+ byte data[] = decryptShareWithInternalStorage(
+ mStorageConfig.getString(PROP_SHARE + i),
+ pwd);
+ if (data == null) {
+ throw new EBaseException(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+ return;
+ }
+ }
+ throw new EBaseException(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+
+ }
+
+ public byte[] decryptShareWithInternalStorage(
+ String encoding, String pwd)
+ throws EBaseException {
+ try {
+ return decryptShare(CryptoManager.getInstance().getInternalKeyStorageToken(), encoding, pwd);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Decrypts shares with the given password.
+ */
+ public byte[] decryptShare(CryptoToken token,
+ String encoding, String pwd)
+ throws EBaseException {
+ try {
+ CMS.debug("StorageKeyUnit.decryptShare");
+ byte share[] = CMS.AtoB(encoding);
+ Cipher cipher = token.getCipherContext(
+ EncryptionAlgorithm.DES3_CBC_PAD);
+ SymmetricKey sk = StorageKeyUnit.buildSymmetricKey(
+ token, pwd);
+
+ cipher.initDecrypt(sk, IV);
+ byte dec[] = cipher.doFinal(share);
+
+ if (dec == null || !verifyShare(dec)) {
+ // invalid passwod
+ throw new EBaseException(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+ return postVerify(dec);
+ } catch (OutOfMemoryError e) {
+ // XXX - this happens in cipher.doFinal when
+ // the given share is not valid (the password
+ // given from the agent is not correct).
+ // Actulla, cipher.doFinal should return
+ // something better than this!
+ //
+ // e.printStackTrace();
+ //
+ throw new EBaseException(CMS.getUserMessage("CMS_KRA_INVALID_PASSWORD",
+ e.toString()));
+ } catch (TokenException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_KRA_INVALID_PASSWORD",
+ e.toString()));
+ } catch (NoSuchAlgorithmException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_KRA_INVALID_PASSWORD",
+ e.toString()));
+ } catch (InvalidKeyException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_KRA_INVALID_PASSWORD",
+ e.toString()));
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_KRA_INVALID_PASSWORD",
+ e.toString()));
+ } catch (IllegalBlockSizeException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_KRA_INVALID_PASSWORD",
+ e.toString()));
+ } catch (BadPaddingException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_KRA_INVALID_PASSWORD",
+ e.toString()));
+ }
+ }
+
+ /**
+ * Reconstructs password from recovery agents.
+ */
+ private String constructPassword(Credential creds[])
+ throws EBaseException {
+ // sort the credential according to the order in
+ // configuration file
+ Hashtable<String, byte[]> v = new Hashtable<String, byte[]>();
+
+ for (int i = 0;; i++) {
+ String uid = null;
+
+ try {
+ uid = mStorageConfig.getString(PROP_UID + i);
+ if (uid == null)
+ break;
+ } catch (Exception e) {
+ break;
+ }
+ for (int j = 0; j < creds.length; j++) {
+ if (uid.equals(creds[j].getIdentifier())) {
+ byte pwd[] = decryptShareWithInternalStorage(
+ mStorageConfig.getString(
+ PROP_SHARE + i),
+ creds[j].getPassword());
+ if (pwd == null) {
+ throw new EBaseException(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+ v.put(Integer.toString(i), pwd);
+ break;
+ }
+ }
+ }
+
+ if (v.size() < 0) {
+ throw new EBaseException(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ if (v.size() != creds.length) {
+ throw new EBaseException(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ IJoinShares j = null;
+ try {
+ String className = mConfig.getString("joinshares_class",
+ "com.netscape.cms.shares.OldJoinShares");
+ j = (IJoinShares) Class.forName(className).newInstance();
+ } catch (Exception e) {
+ CMS.debug("JoinShares error " + e);
+ }
+ if (j == null) {
+ CMS.debug("JoinShares plugin is not found");
+ throw new EBaseException(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ try {
+ j.initialize(v.size());
+ } catch (Exception e) {
+ CMS.debug("Failed to initialize JoinShares");
+ throw new EBaseException(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+ Enumeration<String> e = v.keys();
+
+ while (e.hasMoreElements()) {
+ String next = e.nextElement();
+
+ j.addShare(Integer.parseInt(next) + 1,
+ (byte[]) v.get(next));
+ }
+ try {
+ byte secret[] = j.recoverSecret();
+ String pwd = new String(secret);
+
+ return pwd;
+ } catch (Exception ee) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_STORAGE_RECONSTRUCT", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_KRA_INVALID_PASSWORD",
+ ee.toString()));
+ }
+ }
+
+ public static boolean arraysEqual(byte[] bytes, byte[] ints) {
+ if (bytes == null || ints == null) {
+ return false;
+ }
+
+ if (bytes.length != ints.length) {
+ return false;
+ }
+
+ for (int i = 0; i < bytes.length; i++) {
+ if (bytes[i] != ints[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/base/kra/src/com/netscape/kra/TokenKeyRecoveryService.java b/base/kra/src/com/netscape/kra/TokenKeyRecoveryService.java
new file mode 100644
index 000000000..7575ea9f4
--- /dev/null
+++ b/base/kra/src/com/netscape/kra/TokenKeyRecoveryService.java
@@ -0,0 +1,627 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.kra;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.security.SecureRandom;
+import java.util.Hashtable;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerValue;
+
+import org.mozilla.jss.crypto.Cipher;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.EncryptionAlgorithm;
+import org.mozilla.jss.crypto.IVParameterSpec;
+import org.mozilla.jss.crypto.SymmetricKey;
+import org.mozilla.jss.pkcs11.PK11SymKey;
+import org.mozilla.jss.util.Base64OutputStream;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.kra.EKRAException;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IService;
+import com.netscape.certsrv.security.IStorageKeyUnit;
+import com.netscape.certsrv.security.ITransportKeyUnit;
+import com.netscape.cmscore.dbs.KeyRecord;
+import com.netscape.cmsutil.util.Cert;
+
+/**
+ * A class represents recovery request processor.
+ *
+ * @author Christina Fu (cfu)
+ * @version $Revision$, $Date$
+ */
+public class TokenKeyRecoveryService implements IService {
+
+ public static final String ATTR_NICKNAME = "nickname";
+ public static final String ATTR_OWNER_NAME = "ownerName";
+ public static final String ATTR_PUBLIC_KEY_DATA = "publicKeyData";
+ public static final String ATTR_PRIVATE_KEY_DATA = "privateKeyData";
+ public static final String ATTR_TRANSPORT_CERT = "transportCert";
+ public static final String ATTR_TRANSPORT_PWD = "transportPwd";
+ public static final String ATTR_SIGNING_CERT = "signingCert";
+ public static final String ATTR_PKCS12 = "pkcs12";
+ public static final String ATTR_ENCRYPTION_CERTS =
+ "encryptionCerts";
+ public static final String ATTR_AGENT_CREDENTIALS =
+ "agentCredentials";
+ // same as encryption certs
+ public static final String ATTR_USER_CERT = "cert";
+ public static final String ATTR_DELIVERY = "delivery";
+
+ private IKeyRecoveryAuthority mKRA = null;
+ private IKeyRepository mStorage = null;
+ private IStorageKeyUnit mStorageUnit = null;
+ private ITransportKeyUnit mTransportUnit = null;
+
+ private final static String LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST =
+ "LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_4";
+
+ private final static String LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED_4";
+ private ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+
+ /**
+ * Constructs request processor.
+ */
+ public TokenKeyRecoveryService(IKeyRecoveryAuthority kra) {
+ mKRA = kra;
+ mStorage = mKRA.getKeyRepository();
+ mStorageUnit = mKRA.getStorageKeyUnit();
+ mTransportUnit = kra.getTransportKeyUnit();
+ }
+
+ /**
+ * 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();
+ }
+
+ public static String normalizeCertStr(String s) {
+ String val = "";
+
+ for (int i = 0; i < s.length(); i++) {
+ if (s.charAt(i) == '\\') {
+ i++;
+ continue;
+ } else if (s.charAt(i) == '\\') {
+ i++;
+ continue;
+ } else if (s.charAt(i) == '"') {
+ continue;
+ } else if (s.charAt(i) == ' ') {
+ continue;
+ }
+ val += s.charAt(i);
+ }
+ return val;
+ }
+
+ private 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");
+ }
+
+ // this encrypts bytes with a symmetric key
+ public byte[] encryptIt(byte[] toBeEncrypted, SymmetricKey symKey, CryptoToken token,
+ IVParameterSpec IV) {
+ try {
+ Cipher cipher = token.getCipherContext(
+ EncryptionAlgorithm.DES3_CBC_PAD);
+
+ cipher.initEncrypt(symKey, IV);
+ byte pri[] = cipher.doFinal(toBeEncrypted);
+ return pri;
+ } catch (Exception e) {
+ CMS.debug("initEncrypt() threw exception: " + e.toString());
+ return null;
+ }
+
+ }
+
+ /**
+ * Processes a recovery request. The method reads
+ * the key record from the database, and tries to recover the
+ * key with the storage key unit. Once recovered, it wraps it
+ * with desKey
+ * In the params
+ * - cert is used for recovery record search
+ * - cuid may be used for additional validation check
+ * - userid may be used for additional validation check
+ * - wrappedDesKey is used for wrapping recovered private key
+ *
+ * @param request recovery request
+ * @return operation success or not
+ * @exception EBaseException failed to serve
+ */
+ public boolean serviceRequest(IRequest request) throws EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = null;
+ String auditRecoveryID = ILogger.UNIDENTIFIED;
+ String iv_s = "";
+
+ CMS.debug("KRA services token key recovery request");
+
+ byte[] wrapped_des_key;
+
+ byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
+ try {
+ SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+ random.nextBytes(iv);
+ } catch (Exception e) {
+ CMS.debug("TokenKeyRecoveryService.serviceRequest: " + e.toString());
+ }
+
+ String id = request.getRequestId().toString();
+ if (id != null) {
+ auditRecoveryID = id.trim();
+ }
+ SessionContext sContext = SessionContext.getContext();
+ String agentId = "";
+ if (sContext != null) {
+ agentId =
+ (String) sContext.get(SessionContext.USER_ID);
+ }
+
+ Hashtable<String, Object> params = mKRA.getVolatileRequest(
+ request.getRequestId());
+
+ if (params == null) {
+ // possibly we are in recovery mode
+ CMS.debug("getVolatileRequest params null");
+ // return true;
+ }
+
+ wrapped_des_key = null;
+
+ PK11SymKey sk = null;
+
+ String rCUID = request.getExtDataInString(IRequest.NETKEY_ATTR_CUID);
+ String rUserid = request.getExtDataInString(IRequest.NETKEY_ATTR_USERID);
+ String rWrappedDesKeyString = request.getExtDataInString(IRequest.NETKEY_ATTR_DRMTRANS_DES_KEY);
+ auditSubjectID = rCUID + ":" + rUserid;
+
+ CMS.debug("TokenKeyRecoveryService: received DRM-trans-wrapped des key =" + rWrappedDesKeyString);
+ wrapped_des_key = com.netscape.cmsutil.util.Utils.SpecialDecode(rWrappedDesKeyString);
+ CMS.debug("TokenKeyRecoveryService: wrapped_des_key specialDecoded");
+
+ if ((wrapped_des_key != null) &&
+ (wrapped_des_key.length > 0)) {
+
+ // unwrap the des key
+ sk = (PK11SymKey) mTransportUnit.unwrap_encrypt_sym(wrapped_des_key);
+
+ if (sk == null) {
+ CMS.debug("TokenKeyRecoveryService: no des key");
+ request.setExtData(IRequest.RESULT, Integer.valueOf(4));
+ } else {
+ CMS.debug("TokenKeyRecoveryService: received des key");
+ }
+ } else {
+ CMS.debug("TokenKeyRecoveryService: not receive des key");
+ request.setExtData(IRequest.RESULT, Integer.valueOf(4));
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ agentId);
+
+ audit(auditMessage);
+ return false;
+ }
+
+ // retrieve based on Certificate
+ String cert_s = request.getExtDataInString(ATTR_USER_CERT);
+ if (cert_s == null) {
+ CMS.debug("TokenKeyRecoveryService: not receive cert");
+ request.setExtData(IRequest.RESULT, Integer.valueOf(3));
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ agentId);
+
+ audit(auditMessage);
+ return false;
+ }
+
+ String cert = normalizeCertStr(cert_s);
+ java.security.cert.X509Certificate x509cert = null;
+ try {
+ x509cert = (java.security.cert.X509Certificate) Cert.mapCert(cert);
+ if (x509cert == null) {
+ CMS.debug("cert mapping failed");
+ request.setExtData(IRequest.RESULT, Integer.valueOf(5));
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ agentId);
+
+ audit(auditMessage);
+ return false;
+ }
+ } catch (IOException e) {
+ CMS.debug("TokenKeyRecoveryService: mapCert failed");
+ request.setExtData(IRequest.RESULT, Integer.valueOf(6));
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ agentId);
+
+ audit(auditMessage);
+ return false;
+ }
+
+ try {
+ /*
+ CryptoToken internalToken =
+ CryptoManager.getInstance().getInternalKeyStorageToken();
+ */
+ CryptoToken token = mStorageUnit.getToken();
+ CMS.debug("TokenKeyRecoveryService: got token slot:" + token.getName());
+ IVParameterSpec algParam = new IVParameterSpec(iv);
+
+ Cipher cipher = token.getCipherContext(EncryptionAlgorithm.DES3_CBC_PAD);
+
+ KeyRecord keyRecord = null;
+ CMS.debug("KRA reading key record");
+ try {
+ keyRecord = (KeyRecord) mStorage.readKeyRecord(cert);
+ if (keyRecord != null)
+ CMS.debug("read key record");
+ else {
+ CMS.debug("key record not found");
+ request.setExtData(IRequest.RESULT, Integer.valueOf(8));
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ agentId);
+
+ audit(auditMessage);
+ return false;
+ }
+ } catch (Exception e) {
+ com.netscape.cmscore.util.Debug.printStackTrace(e);
+ request.setExtData(IRequest.RESULT, Integer.valueOf(9));
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ agentId);
+
+ audit(auditMessage);
+ return false;
+ }
+
+ // see if the owner name matches (cuid:userid) -XXX need make this optional
+ String owner = keyRecord.getOwnerName();
+ CMS.debug("TokenKeyRecoveryService: owner name on record =" + owner);
+ CMS.debug("TokenKeyRecoveryService: owner name from TPS =" + rCUID + ":" + rUserid);
+ if (owner != null) {
+ if (owner.equals(rCUID + ":" + rUserid)) {
+ CMS.debug("TokenKeyRecoveryService: owner name matches");
+ } else {
+ CMS.debug("TokenKeyRecoveryService: owner name mismatches");
+ }
+ }
+
+ // see if the certificate matches the key
+ byte pubData[] = keyRecord.getPublicKeyData();
+ byte inputPubData[] = x509cert.getPublicKey().getEncoded();
+
+ if (inputPubData.length != pubData.length) {
+ mKRA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_PUBLIC_KEY_LEN"));
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ agentId);
+
+ audit(auditMessage);
+ throw new EKRAException(
+ CMS.getUserMessage("CMS_KRA_PUBLIC_KEY_NOT_MATCHED"));
+ }
+
+ for (int i = 0; i < pubData.length; i++) {
+ if (pubData[i] != inputPubData[i]) {
+ mKRA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_PUBLIC_KEY_LEN"));
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ agentId);
+
+ audit(auditMessage);
+ throw new EKRAException(
+ CMS.getUserMessage("CMS_KRA_PUBLIC_KEY_NOT_MATCHED"));
+ }
+ }
+
+ // Unwrap the archived private key
+ byte privateKeyData[] = null;
+ privateKeyData = recoverKey(params, keyRecord);
+ if (privateKeyData == null) {
+ request.setExtData(IRequest.RESULT, Integer.valueOf(4));
+ CMS.debug("TokenKeyRecoveryService: failed getting private key");
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ agentId);
+
+ audit(auditMessage);
+ return false;
+ }
+ CMS.debug("TokenKeyRecoveryService: got private key...about to verify");
+
+ iv_s = /*base64Encode(iv);*/com.netscape.cmsutil.util.Utils.SpecialEncode(iv);
+ request.setExtData("iv_s", iv_s);
+
+ CMS.debug("request.setExtData: iv_s: " + iv_s);
+
+ /* LunaSA returns data with padding which we need to remove */
+ ByteArrayInputStream dis = new ByteArrayInputStream(privateKeyData);
+ DerValue dv = new DerValue(dis);
+ byte p[] = dv.toByteArray();
+ int l = p.length;
+ CMS.debug("length different data length=" + l +
+ " real length=" + privateKeyData.length);
+ if (l != privateKeyData.length) {
+ privateKeyData = p;
+ }
+
+ if (verifyKeyPair(pubData, privateKeyData) == false) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_PUBLIC_NOT_FOUND"));
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ agentId);
+
+ audit(auditMessage);
+ throw new EKRAException(
+ CMS.getUserMessage("CMS_KRA_INVALID_PUBLIC_KEY"));
+ } else {
+ CMS.debug("TokenKeyRecoveryService: private key verified with public key");
+ }
+
+ //encrypt and put in private key
+ cipher.initEncrypt(sk, algParam);
+ byte wrapped[] = cipher.doFinal(privateKeyData);
+
+ String wrappedPrivKeyString =
+ com.netscape.cmsutil.util.Utils.SpecialEncode(wrapped);
+ if (wrappedPrivKeyString == null) {
+ request.setExtData(IRequest.RESULT, Integer.valueOf(4));
+ CMS.debug("TokenKeyRecoveryService: failed generating wrapped private key");
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ agentId);
+
+ audit(auditMessage);
+ return false;
+ } else {
+ CMS.debug("TokenKeyRecoveryService: got private key data wrapped");
+ request.setExtData("wrappedUserPrivate",
+ wrappedPrivKeyString);
+ request.setExtData(IRequest.RESULT, Integer.valueOf(1));
+ CMS.debug("TokenKeyRecoveryService: key for " + rCUID + ":" + rUserid + " recovered");
+ }
+
+ //convert and put in the public key
+ String b64PKey = base64Encode(pubData);
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRecoveryID,
+ b64PKey);
+
+ audit(auditMessage);
+
+ if (b64PKey == null) {
+ request.setExtData(IRequest.RESULT, Integer.valueOf(4));
+ CMS.debug("TokenKeyRecoveryService: failed getting publickey encoded");
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ agentId);
+
+ audit(auditMessage);
+ return false;
+ } else {
+ CMS.debug("TokenKeyRecoveryService: got publicKeyData b64 = " +
+ b64PKey);
+ }
+ request.setExtData("public_key", b64PKey);
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRecoveryID,
+ agentId);
+
+ audit(auditMessage);
+
+ return true;
+
+ } catch (Exception e) {
+ CMS.debug("TokenKeyRecoveryService: " + e.toString());
+ request.setExtData(IRequest.RESULT, Integer.valueOf(4));
+ }
+
+ return true;
+ }
+
+ public boolean verifyKeyPair(byte publicKeyData[], byte privateKeyData[]) {
+ try {
+ DerValue publicKeyVal = new DerValue(publicKeyData);
+ DerInputStream publicKeyIn = publicKeyVal.data;
+ publicKeyIn.getSequence(0);
+ DerValue publicKeyDer = new DerValue(publicKeyIn.getBitString());
+ DerInputStream publicKeyDerIn = publicKeyDer.data;
+ BigInt publicKeyModulus = publicKeyDerIn.getInteger();
+ BigInt publicKeyExponent = publicKeyDerIn.getInteger();
+
+ DerValue privateKeyVal = new DerValue(privateKeyData);
+ if (privateKeyVal.tag != DerValue.tag_Sequence)
+ return false;
+ DerInputStream privateKeyIn = privateKeyVal.data;
+ privateKeyIn.getInteger();
+ privateKeyIn.getSequence(0);
+ DerValue privateKeyDer = new DerValue(privateKeyIn.getOctetString());
+ DerInputStream privateKeyDerIn = privateKeyDer.data;
+
+ @SuppressWarnings("unused")
+ BigInt privateKeyVersion = privateKeyDerIn.getInteger(); // consume stream
+ BigInt privateKeyModulus = privateKeyDerIn.getInteger();
+ BigInt privateKeyExponent = privateKeyDerIn.getInteger();
+
+ if (!publicKeyModulus.equals(privateKeyModulus)) {
+ CMS.debug("verifyKeyPair modulus mismatch publicKeyModulus="
+ + publicKeyModulus + " privateKeyModulus=" + privateKeyModulus);
+ return false;
+ }
+
+ if (!publicKeyExponent.equals(privateKeyExponent)) {
+ CMS.debug("verifyKeyPair exponent mismatch publicKeyExponent="
+ + publicKeyExponent + " privateKeyExponent=" + privateKeyExponent);
+ return false;
+ }
+
+ return true;
+ } catch (Exception e) {
+ CMS.debug("verifyKeyPair error " + e);
+ return false;
+ }
+ }
+
+ /**
+ * Recovers key.
+ */
+ public synchronized byte[] recoverKey(Hashtable<String, Object> request, KeyRecord keyRecord)
+ throws EBaseException {
+ /*
+ Credential creds[] = (Credential[])
+ request.get(ATTR_AGENT_CREDENTIALS);
+
+ mStorageUnit.login(creds);
+ */
+ CMS.debug("KRA decrypts internal private");
+ byte privateKeyData[] =
+ mStorageUnit.decryptInternalPrivate(
+ keyRecord.getPrivateKeyData());
+ /*
+ mStorageUnit.logout();
+ */
+ if (privateKeyData == null) {
+ mKRA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_PRIVATE_KEY_NOT_FOUND"));
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_RECOVERY_FAILED_1", "no private key"));
+ }
+ return privateKeyData;
+ }
+
+ /**
+ * Signed Audit Log
+ * y
+ * 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);
+ }
+
+}
diff --git a/base/kra/src/com/netscape/kra/TransportKeyUnit.java b/base/kra/src/com/netscape/kra/TransportKeyUnit.java
new file mode 100644
index 000000000..90ac2120f
--- /dev/null
+++ b/base/kra/src/com/netscape/kra/TransportKeyUnit.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.kra;
+
+import java.security.PublicKey;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.ObjectNotFoundException;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.crypto.Signature;
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+import org.mozilla.jss.crypto.TokenException;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.security.ITransportKeyUnit;
+import com.netscape.cmsutil.util.Cert;
+
+/**
+ * A class represents the transport key pair. This key pair
+ * is used to protected EE's private key in transit.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class TransportKeyUnit extends EncryptionUnit implements
+ ISubsystem, ITransportKeyUnit {
+
+ public static final String PROP_NICKNAME = "nickName";
+ public static final String PROP_SIGNING_ALGORITHM = "signingAlgorithm";
+
+ // private RSAPublicKey mPublicKey = null;
+ // private RSAPrivateKey mPrivateKey = null;
+ private IConfigStore mConfig = null;
+ private org.mozilla.jss.crypto.X509Certificate mCert = null;
+ private CryptoManager mManager = null;
+
+ /**
+ * Constructs this token.
+ */
+ public TransportKeyUnit() {
+ super();
+ }
+
+ /**
+ * Retrieves subsystem identifier.
+ */
+ public String getId() {
+ return "transportKeyUnit";
+ }
+
+ /**
+ * Sets subsystem identifier.
+ */
+ public void setId(String id) throws EBaseException {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_OPERATION"));
+ }
+
+ /**
+ * Initializes this subsystem.
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+ try {
+ mManager = CryptoManager.getInstance();
+ mCert = mManager.findCertByNickname(getNickName());
+ String algo = config.getString("signingAlgorithm", "SHA256withRSA");
+
+ // #613795 - initialize this; otherwise JSS is not happy
+ CryptoToken token = getToken();
+ SignatureAlgorithm sigalg = Cert.mapAlgorithmToJss(algo);
+ Signature signer = token.getSignatureContext(sigalg);
+ signer.initSign(getPrivateKey());
+
+ } catch (org.mozilla.jss.CryptoManager.NotInitializedException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+
+ } catch (TokenException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (ObjectNotFoundException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (Exception e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+ }
+
+ public CryptoToken getInternalToken() {
+ try {
+ return CryptoManager.getInstance().getInternalKeyStorageToken();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public CryptoToken getToken() {
+ // 390148: returning the token that owns the private
+ // key.
+ return getPrivateKey().getOwningToken();
+ }
+
+ /**
+ * Starts up this subsystem.
+ */
+ public void startup() throws EBaseException {
+ }
+
+ /**
+ * Shutdowns this subsystem.
+ */
+ public void shutdown() {
+ }
+
+ /**
+ * Returns the configuration store of this token.
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public String getNickName() throws EBaseException {
+ return mConfig.getString(PROP_NICKNAME);
+ }
+
+ public void setNickName(String str) throws EBaseException {
+ mConfig.putString(PROP_NICKNAME, str);
+ }
+
+ public String getSigningAlgorithm() throws EBaseException {
+ return mConfig.getString(PROP_SIGNING_ALGORITHM);
+ }
+
+ public void setSigningAlgorithm(String str) throws EBaseException {
+ mConfig.putString(PROP_SIGNING_ALGORITHM, str);
+ }
+
+ /**
+ * Logins to this token.
+ */
+ public void login(String pin) throws EBaseException {
+ }
+
+ /**
+ * Logout from this token.
+ */
+ public void logout() {
+ }
+
+ /**
+ * Retrieves public key.
+ */
+ public org.mozilla.jss.crypto.X509Certificate getCertificate() {
+ return mCert;
+ }
+
+ public PublicKey getPublicKey() {
+ return mCert.getPublicKey();
+ }
+
+ public PrivateKey getPrivateKey() {
+ try {
+ return mManager.findPrivKeyByCert(mCert);
+ } catch (TokenException e) {
+ return null;
+ } catch (ObjectNotFoundException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Verifies the integrity of the given key pair.
+ */
+ public void verify(byte publicKey[], PrivateKey privateKey)
+ throws EBaseException {
+ // XXX
+ }
+}
diff --git a/base/migrate/41ToTxt/classes/CMS41LdifParser.class b/base/migrate/41ToTxt/classes/CMS41LdifParser.class
new file mode 100644
index 000000000..b787984a2
--- /dev/null
+++ b/base/migrate/41ToTxt/classes/CMS41LdifParser.class
Binary files differ
diff --git a/base/migrate/41ToTxt/classes/Main.class b/base/migrate/41ToTxt/classes/Main.class
new file mode 100644
index 000000000..87854eb4d
--- /dev/null
+++ b/base/migrate/41ToTxt/classes/Main.class
Binary files differ
diff --git a/base/migrate/41ToTxt/run.bat b/base/migrate/41ToTxt/run.bat
new file mode 100755
index 000000000..35a5fda9f
--- /dev/null
+++ b/base/migrate/41ToTxt/run.bat
@@ -0,0 +1,192 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM This program is free software; you can redistribute it and/or modify
+REM it under the terms of the GNU General Public License as published by
+REM the Free Software Foundation; version 2 of the License.
+REM
+REM This program is distributed in the hope that it will be useful,
+REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+REM GNU General Public License for more details.
+REM
+REM You should have received a copy of the GNU General Public License along
+REM with this program; if not, write to the Free Software Foundation, Inc.,
+REM 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script converts a pre-existing CMS 4.1 ldif data
+REM file (e. g. - created via a utility such as db2ldif)
+REM into a normalized CMS 4.1 ldif text file.
+REM
+REM This subsequent normalized CMS 4.1 ldif text file
+REM can be migrated into CMS 6.0 or later utilizing
+REM the corresponding TxtTo<Target CMS Version> script which
+REM converts this normalized CMS 4.1 ldif text file into
+REM a <Target CMS Version> ldif data file.
+REM
+REM This <Target CMS Version> ldif data file can then be
+REM imported into the internal database of the desired CMS
+REM server using a utility such as ldif2db.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM SERVER_ROOT - fully qualified path of the location of the server
+REM
+
+REM SET SERVER_ROOT=C:\cms41
+
+
+REM
+REM INSTANCE - if the CMS instance directory is called 'cert-ca',
+REM set the CMS instance to 'ca'
+REM
+REM NOTE: When a single SERVER_ROOT contains more than
+REM one CMS instance, this script must be run multiple
+REM times. To do this, there is only a need to change
+REM the INSTANCE parameter.
+REM
+
+REM SET INSTANCE=ca
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 4.1"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO USAGE
+IF "%3" == "" GOTO CHECK_INPUT_FILE
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0 input [errors] > output"
+ECHO.
+ECHO where: input - the specified %CMS% ldif data file,
+ECHO errors - an optional errors file containing
+ECHO skipped attributes, and
+ECHO output - the normalized %CMS% ldif text file.
+ECHO.
+ECHO NOTE: If no redirection is provided to
+ECHO 'output', then the normalized
+ECHO %CMS% ldif text will merely
+ECHO be echoed to stdout.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified "input" file exists
+REM
+
+:CHECK_INPUT_FILE
+IF EXIST %1 GOTO CHECK_ERRORS_FILE
+
+
+ECHO ERROR: The specified input file, %1, does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM If an "errors" file is specified, then check that it does not already
+REM exist.
+REM
+
+:CHECK_ERRORS_FILE
+IF "%2" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+IF EXIST %2 GOTO ERRORS_FILE_ERROR
+GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:ERRORS_FILE_ERROR
+ECHO ERROR: The specified errors file, %2, already exists!
+ECHO Please specify a different file!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%INSTANCE%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and INSTANCE
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_INSTANCE
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified INSTANCE exists
+REM
+
+:CHECK_INSTANCE
+IF EXIST %SERVER_ROOT%\cert-%INSTANCE% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified INSTANCE does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\base\jre\bin;%PATH%
+
+
+REM
+REM Convert the specified %CMS% ldif data file
+REM into a normalized %CMS% ldif text file.
+REM
+
+%SERVER_ROOT%\bin\cert\bin\jssjava.exe -classpath .\classes;%SERVER_ROOT%\cert-%INSTANCE%\classes;%SERVER_ROOT%\bin\cert\classes;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\jss.jar;%SERVER_ROOT%\bin\cert\jars\jssjdk12.jar;%SERVER_ROOT%\bin\base\jre\lib\rt.jar Main %1 %2
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/41ToTxt/run.sh b/base/migrate/41ToTxt/run.sh
new file mode 100755
index 000000000..390195ea1
--- /dev/null
+++ b/base/migrate/41ToTxt/run.sh
@@ -0,0 +1,191 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+
+#####################################################################
+### ###
+### This script converts a pre-existing CMS 4.1 ldif data ###
+### file (e. g. - created via a utility such as db2ldif) ###
+### into a normalized CMS 4.1 ldif text file. ###
+### ###
+### This subsequent normalized CMS 4.1 ldif text file ###
+### can be migrated into CMS 6.0 or later utilizing ###
+### the corresponding TxtTo<Target CMS Version> script which ###
+### converts this normalized CMS 4.1 ldif text file into ###
+### a <Target CMS Version> ldif data file. ###
+### ###
+### This <Target CMS Version> ldif data file can then be ###
+### imported into the internal database of the desired CMS ###
+### server using a utility such as ldif2db. ###
+### ###
+#####################################################################
+
+
+###
+### SERVER_ROOT - fully qualified path of the location of the server
+###
+
+#SERVER_ROOT=/export/home/migrate/cms41
+#export SERVER_ROOT
+
+
+###
+### INSTANCE - if the CMS instance directory is called 'cert-ca',
+### set the CMS instance to 'ca'
+###
+### NOTE: When a single SERVER_ROOT contains more than
+### one CMS instance, this script must be run multiple
+### times. To do this, there is only a need to change
+### the INSTANCE parameter.
+###
+
+#INSTANCE=ca
+#export INSTANCE
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 4.1"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+##
+## Perform a usage check for the appropriate number of arguments:
+##
+
+if [ $# -lt 1 -o $# -gt 2 ] ; then
+ echo
+ echo "Usage: $0 input [errors] > output"
+ echo
+ echo " where: input - the specified ${CMS} ldif data file,"
+ echo " errors - an optional errors file containing"
+ echo " skipped attributes, and"
+ echo " output - the normalized ${CMS} ldif text file."
+ echo
+ echo " NOTE: If no redirection is provided to"
+ echo " 'output', then the normalized"
+ echo " ${CMS} ldif text will merely"
+ echo " be echoed to stdout."
+ echo
+ exit 1
+fi
+
+
+###
+### Check that the specified "input" file exists and is a regular file.
+###
+
+if [ ! -f $1 ] ; then
+ echo "ERROR: Either the specified 'input' file, '$1', does not exist, "
+ echo " or it is not a regular file!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified "input" file exists and is not empty.
+###
+
+if [ ! -s $1 ] ; then
+ echo "ERROR: The specified 'input' file, '$1', is empty!"
+ echo
+ exit 3
+fi
+
+
+###
+### If an "errors" file is specified, then check that it does not already
+### exist.
+###
+
+if [ $# -eq 2 ] ; then
+ if [ -f $2 ] ; then
+ echo "ERROR: The specified 'errors' file, '$2', already exists!"
+ echo " Please specify a different file!"
+ echo
+ exit 4
+ fi
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${INSTANCE}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and INSTANCE "
+ echo " environment variables for this script!"
+ echo
+ exit 5
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 6
+fi
+
+
+###
+### Check that the specified INSTANCE exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}/cert-${INSTANCE}" ] ; then
+ echo "ERROR: Either the specified INSTANCE does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 7
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform (SunOS)
+###
+
+LD_LIBRARY_PATH=${SERVER_ROOT}/bin/base/jre/lib:${SERVER_ROOT}/bin/base/jre/lib/sparc/native_threads
+export LD_LIBRARY_PATH
+
+
+###
+### Convert the specified ${CMS} ldif data file
+### into a normalized ${CMS} ldif text file.
+###
+
+${SERVER_ROOT}/bin/cert/bin/jssjava -classpath ./classes:${SERVER_ROOT}/cert-${INSTANCE}/classes:${SERVER_ROOT}/bin/cert/classes:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/jss.jar:${SERVER_ROOT}/bin/cert/jars/jssjdk12.jar:${SERVER_ROOT}/bin/base/jre/lib/rt.jar:${SERVER_ROOT}/bin/cert/jre/lib/i18n.jar Main $1 $2
+
diff --git a/base/migrate/41ToTxt/src/Main.java b/base/migrate/41ToTxt/src/Main.java
new file mode 100644
index 000000000..758d725a9
--- /dev/null
+++ b/base/migrate/41ToTxt/src/Main.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 ---
+
+//
+// "41ToTxt/src/Main.java" represents the initial CMS "ToTxt" migration file.
+//
+// Always comment any new code sections with a "CMS 4.1" header, and
+// apply these changes forward to all other "*ToTxt/src/Main.java" files
+// (including this comment header) so that these differences will only
+// appear when this file is diffed against an earlier "*ToTxt" version.
+//
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+import sun.misc.*;
+import com.netscape.jss.*; // CMS 4.1/4.2/4.2 (SP 2)
+import netscape.security.util.*;
+
+public class Main
+{
+ public static void main(String args[])
+ {
+ try {
+ // initialize CryptoManager in CMS 4.1/4.2/4.2 (SP 2)
+ CryptoManager.initialize("./secmod.db", "./key3.db", "./cert7.db");
+ // load JSS provider in CMS 4.1/4.2/4.2 (SP 2)
+ java.security.Security.removeProvider("Netscape version 1.4");
+ java.security.Security.removeProvider("SunRsaSign version 1.0");
+// java.security.Security.insertProviderAt(
+// new netscape.security.provider.CMS(), 0);
+ java.security.Provider ps[] =
+ java.security.Security.getProviders();
+ if (ps == null || ps.length <= 0) {
+ System.err.println("Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ System.err.println("Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+
+ // Parse the File
+ CMS41LdifParser parser = null;
+ if (args.length == 1) {
+ parser = new CMS41LdifParser(args[0]);
+ } else if (args.length == 2) {
+ parser = new CMS41LdifParser(args[0], args[1]);
+ } else {
+ throw new IOException("Invalid Parameters");
+ }
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+}
+
+class CMS41LdifParser
+{
+ // constants
+ private static final String DN =
+ "dn:";
+ // Directory Servers in CMS 4.1/4.2/4.2 (SP 2)/4.5 use "requestattributes"
+ private static final String REQUEST_ATTRIBUTES =
+ "requestattributes::";
+ private static final String BEGIN =
+ "--- BEGIN ATTRIBUTES ---";
+ private static final String END =
+ "--- END ATTRIBUTES ---";
+
+ // variables
+ private String mFilename = null;
+ private String mErrorFilename = null;
+ private PrintWriter mErrorPrintWriter = null;
+
+ public CMS41LdifParser(String filename)
+ {
+ mFilename = filename;
+ }
+
+ public CMS41LdifParser(String filename, String errorFilename)
+ {
+ mFilename = filename;
+ mErrorFilename = errorFilename;
+ }
+
+ public void parse() throws Exception
+ {
+ if (mErrorFilename != null) {
+ mErrorPrintWriter = new PrintWriter(new FileOutputStream(mErrorFilename));
+ }
+ BufferedReader reader = new BufferedReader(
+ new FileReader(mFilename));
+ String line = null;
+ String dn = null;
+ StringBuffer requestAttributes = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DN)) {
+ dn = line;
+ }
+ if (line.startsWith(REQUEST_ATTRIBUTES)) {
+ requestAttributes = new StringBuffer();
+ // System.out.println(line);
+ requestAttributes.append(
+ line.substring(REQUEST_ATTRIBUTES.length(),
+ line.length()).trim());
+ continue;
+ }
+ if (requestAttributes == null) {
+ System.out.println(line);
+ continue;
+ }
+ if (line.startsWith(" ")) {
+ // System.out.println(line);
+ requestAttributes.append(line.trim());
+ } else {
+ parseAttributes(dn, requestAttributes);
+ requestAttributes = null;
+ System.out.println(line);
+ }
+ }
+ }
+
+ public void parseAttributes(String dn, StringBuffer attrs) throws Exception
+ {
+ BASE64Decoder decoder = new BASE64Decoder();
+ decodeHashtable(dn, decoder.decodeBuffer(attrs.toString()));
+
+// System.out.println(attrs);
+ }
+
+ public Object decode(byte[] data) throws
+ ObjectStreamException,
+ IOException,
+ ClassNotFoundException
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+ return is.readObject();
+ }
+
+ public void decodeHashtable(String dn, byte[] data) throws Exception
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+
+ System.out.println(BEGIN);
+ String key = null;
+ while (true)
+ {
+ key = (String)is.readObject();
+ // end of table is marked with null
+ if (key == null) break;
+ try {
+ byte[] bytes = (byte[])is.readObject();
+ Object obj = decode(bytes);
+ output(key, obj);
+ } catch (Exception e) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + key);
+ }
+ }
+ }
+ System.out.println(END);
+ }
+
+ public void output(String key, Object obj) throws Exception
+ {
+ if (obj instanceof String) {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ } else if (obj instanceof netscape.security.x509.CertificateX509Key) {
+ netscape.security.x509.CertificateX509Key o =
+ (netscape.security.x509.CertificateX509Key)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateSubjectName) {
+ netscape.security.x509.CertificateSubjectName o =
+ (netscape.security.x509.CertificateSubjectName)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateExtensions) {
+ netscape.security.x509.CertificateExtensions o =
+ (netscape.security.x509.CertificateExtensions)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertInfo) {
+ netscape.security.x509.X509CertInfo o =
+ (netscape.security.x509.X509CertInfo)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl) {
+ netscape.security.x509.X509CertImpl o =
+ (netscape.security.x509.X509CertImpl)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateChain) {
+ netscape.security.x509.CertificateChain o =
+ (netscape.security.x509.CertificateChain)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl[]) {
+ netscape.security.x509.X509CertImpl o[] =
+ (netscape.security.x509.X509CertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.X509CertInfo[]) {
+ netscape.security.x509.X509CertInfo o[] =
+ (netscape.security.x509.X509CertInfo[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() + "["+o.length + "," + i+"]"+"=" +
+ encoder.encodeBuffer(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.RevokedCertImpl[]) {
+ netscape.security.x509.RevokedCertImpl o[] =
+ (netscape.security.x509.RevokedCertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ DerOutputStream bos =
+ new DerOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof java.security.cert.Certificate[]) {
+ java.security.cert.Certificate o[] =
+ (java.security.cert.Certificate[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(o[i].getEncoded()));
+ }
+ } else if (obj instanceof com.netscape.certsrv.base.ArgBlock) {
+ com.netscape.certsrv.base.ArgBlock o =
+ (com.netscape.certsrv.base.ArgBlock)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" +(String)o.get(k));
+ }
+ } else if (obj instanceof com.netscape.certsrv.dbs.keydb.KeyRecord) {
+ com.netscape.certsrv.dbs.keydb.KeyRecord o =
+ (com.netscape.certsrv.dbs.keydb.KeyRecord)obj;
+ Enumeration e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ Object ob = o.get(k);
+ if (ob != null) {
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + encoder.encode((byte[])ob));
+
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ }
+ } else if (obj instanceof com.netscape.certsrv.kra.ProofOfArchival) {
+ com.netscape.certsrv.kra.ProofOfArchival o =
+ (com.netscape.certsrv.kra.ProofOfArchival)obj;
+ DerOutputStream bos =
+ new DerOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof com.netscape.certsrv.request.AgentApprovals) {
+ com.netscape.certsrv.request.AgentApprovals o =
+ (com.netscape.certsrv.request.AgentApprovals)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ com.netscape.certsrv.request.AgentApproval approval = (com.netscape.certsrv.request.AgentApproval)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ approval.getUserName() + ";" + approval.getDate().getTime());
+ }
+ } else if (obj instanceof com.netscape.certsrv.authentication.AuthToken) {
+ com.netscape.certsrv.authentication.AuthToken o =
+ (com.netscape.certsrv.authentication.AuthToken)obj;
+ Enumeration e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ Object ob = o.get(k);
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof java.math.BigInteger[]) {
+ // Bugzilla Bug #225031 (a.k.a. - Raidzilla Bug #58356)
+ java.math.BigInteger in[] = (java.math.BigInteger[])ob;
+ String numbers = "";
+ for (int i = 0; i < in.length; i++) {
+ if (numbers.equals("")) {
+ numbers = in[i].toString();
+ } else {
+ numbers = numbers + "," + in[i].toString();
+ }
+ }
+ System.out.println(" " +
+ key + ":" + "com.netscape.certsrv.authentication.AuthToken" + "=" +
+ k + ":java.lang.String=" + numbers);
+ } else if (ob instanceof String[]) {
+ // Bugzilla Bug #224763 (a.k.a. - Raidzilla Bug #57949)
+ // Bugzilla Bug #252240
+ String str[] = (String[])ob;
+ String v = "";
+ if (str != null) {
+ for (int i = 0; i < str.length; i++) {
+ if (i != 0) {
+ v += ",";
+ }
+ v += str[i];
+ }
+ }
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + "java.lang.String" + "=" + v);
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ } else if (obj instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key + ":byte[]="+
+ encoder.encode((byte[])obj));
+ } else if (obj instanceof Integer[]) {
+ Integer in[] = (Integer[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":Integer[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof BigInteger[]) {
+ // Bugzilla Bug #238779
+ BigInteger in[] = (BigInteger[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":java.math.BigInteger[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof String[]) {
+ // Bugzilla Bug #223360 (a.k.a - Raidzilla Bug #58086)
+ String str[] = (String[])obj;
+ for (int i = 0; i < str.length; i++) {
+ System.out.println(" " + key + ":java.lang.String[" + str.length + "," + i + "]="+ str[i]);
+ }
+ } else if (obj instanceof netscape.security.x509.CertificateAlgorithmId) {
+ netscape.security.x509.CertificateAlgorithmId o =
+ (netscape.security.x509.CertificateAlgorithmId)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateAlgorithmId="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateValidity) {
+ netscape.security.x509.CertificateValidity o =
+ (netscape.security.x509.CertificateValidity)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateValidity="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof java.util.Hashtable) {
+ // Bugzilla Bug #224800 (a.k.a - Raidzilla Bug #56953)
+ //
+ // Example: fingerprints:java.util.Hashtable=
+ // {SHA1=[B@52513a, MD5=[B@52c4d9, MD2=[B@799ff5}
+ //
+ java.util.Hashtable o = (java.util.Hashtable)obj;
+ BASE64Encoder encoder = new BASE64Encoder();
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" + encoder.encode((byte[])o.get(k)));
+ }
+ } else {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ }
+ }
+}
+
diff --git a/base/migrate/41ToTxt/src/compile.bat b/base/migrate/41ToTxt/src/compile.bat
new file mode 100755
index 000000000..fd92f3fb7
--- /dev/null
+++ b/base/migrate/41ToTxt/src/compile.bat
@@ -0,0 +1,150 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script creates the "41ToTxt/classes/Main.class" and
+REM "41ToTxt/classes/CMS41LdifParser.class" which are
+REM used to create a normalized CMS 4.1 ldif text file.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM Set SERVER_ROOT - identify the CMS <server_root> used to compile 41ToTxt
+REM
+
+REM SET SERVER_ROOT=C:\cms41
+
+
+REM
+REM Set JDK_VERSION - specify the JDK version used by this version of CMS
+REM
+REM CMS 4.1 NOTE: "WINNT" - 1.1.6
+REM
+
+REM SET JDK_VERSION=CMS_4.1
+
+
+REM
+REM Set JAVA_HOME - specify the complete path to the JDK
+REM
+REM example: \\bermuda.redhat.com\sbc mounted as Y:
+REM
+
+REM SET JAVA_HOME=Y:\cms_jdk\WINNT\%JDK_VERSION%
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 4.1"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0"
+ECHO.
+ECHO NOTE: No arguments are required to build the
+ECHO normalized %CMS% ldif text classes.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%JAVA_HOME%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and JAVA_HOME
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_JAVA_HOME
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified JAVA_HOME exists
+REM
+
+:CHECK_JAVA_HOME
+IF EXIST %JAVA_HOME% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified JAVA_HOME does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%JAVA_HOME%\bin;%JAVA_HOME%\lib;%PATH%
+
+
+REM
+REM Set TARGET - identify the complete path to the new classes target directory
+REM
+
+SET TARGET=..\classes
+
+
+REM
+REM Create the new classes target directory (if it does not already exist)
+REM
+
+IF EXIST %TARGET% goto COMPILE_CLASSES
+MKDIR %TARGET%
+
+
+REM
+REM Compile 41ToTxt - create "CMS41LdifParser.class" and "Main.class"
+REM
+
+:COMPILE_CLASSES
+%JAVA_HOME%\bin\javac.exe -d %TARGET% -classpath %JAVA_HOME%\lib\classes.zip;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\jss.jar;%SERVER_ROOT%\bin\cert\jars\jssjdk12.jar Main.java
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/41ToTxt/src/compile.sh b/base/migrate/41ToTxt/src/compile.sh
new file mode 100755
index 000000000..968190ff2
--- /dev/null
+++ b/base/migrate/41ToTxt/src/compile.sh
@@ -0,0 +1,150 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#####################################################################
+### ###
+### This script creates the "41ToTxt/classes/Main.class" and ###
+### "41ToTxt/classes/CMS41LdifParser.class" which are ###
+### used to create a normalized CMS 4.1 ldif text file. ###
+### ###
+#####################################################################
+
+
+###
+### Set SERVER_ROOT - identify the CMS <server_root> used to compile 41ToTxt
+###
+
+#SERVER_ROOT=/export/home/migrate/cms41
+#export SERVER_ROOT
+
+
+###
+### Set JDK_PLATFORM - must be "SunOS"
+###
+
+#JDK_PLATFORM=SunOS
+#export JDK_PLATFORM
+
+
+###
+### Set JDK_VERSION - specify the JDK version used by this version of CMS
+###
+### CMS 4.1 NOTE: "SunOS" - 1.1.6
+###
+
+#JDK_VERSION=CMS_4.1
+#export JDK_VERSION
+
+
+###
+### Set JAVA_HOME - specify the complete path to the JDK
+###
+
+#JAVA_HOME=/share/builds/components/cms_jdk/${JDK_PLATFORM}/${JDK_VERSION}
+#export JAVA_HOME
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 4.1"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -gt 0 ] ; then
+ echo
+ echo "Usage: $0"
+ echo
+ echo " NOTE: No arguments are required to build the"
+ echo " normalized ${CMS} ldif text classes."
+ echo
+ exit 1
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${JAVA_HOME}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and JAVA_HOME "
+ echo " environment variables for this script!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 3
+fi
+
+
+###
+### Check that the specified JAVA_HOME exists and is a directory
+###
+
+if [ ! -d "${JAVA_HOME}" ] ; then
+ echo "ERROR: Either the specified JAVA_HOME does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 4
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform (SunOS)
+###
+
+LD_LIBRARY_PATH=${JAVA_HOME}/lib:${JAVA_HOME}/lib/sparc/native_threads
+export LD_LIBRARY_PATH
+
+
+###
+### Set TARGET - identify the complete path to the new classes target directory
+###
+
+TARGET=../classes
+export TARGET
+
+
+###
+### Create the new classes target directory (if it does not already exist)
+###
+
+if [ ! -d ${TARGET} ]; then
+ mkdir -p ${TARGET}
+fi
+
+
+###
+### Compile 41ToTxt - create "CMS41LdifParser.class" and "Main.class"
+###
+
+${JAVA_HOME}/bin/javac -d ${TARGET} -classpath ${JAVA_HOME}/lib/classes.zip:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/jss.jar:${SERVER_ROOT}/bin/cert/jars/jssjdk12.jar Main.java
+
diff --git a/base/migrate/42SP2ToTxt/classes/CMS42SP2LdifParser.class b/base/migrate/42SP2ToTxt/classes/CMS42SP2LdifParser.class
new file mode 100644
index 000000000..dbf8a1170
--- /dev/null
+++ b/base/migrate/42SP2ToTxt/classes/CMS42SP2LdifParser.class
Binary files differ
diff --git a/base/migrate/42SP2ToTxt/classes/Main.class b/base/migrate/42SP2ToTxt/classes/Main.class
new file mode 100644
index 000000000..d881f3560
--- /dev/null
+++ b/base/migrate/42SP2ToTxt/classes/Main.class
Binary files differ
diff --git a/base/migrate/42SP2ToTxt/run.bat b/base/migrate/42SP2ToTxt/run.bat
new file mode 100755
index 000000000..ec2a5d6ff
--- /dev/null
+++ b/base/migrate/42SP2ToTxt/run.bat
@@ -0,0 +1,192 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM This program is free software; you can redistribute it and/or modify
+REM it under the terms of the GNU General Public License as published by
+REM the Free Software Foundation; version 2 of the License.
+REM
+REM This program is distributed in the hope that it will be useful,
+REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+REM GNU General Public License for more details.
+REM
+REM You should have received a copy of the GNU General Public License along
+REM with this program; if not, write to the Free Software Foundation, Inc.,
+REM 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script converts a pre-existing CMS 4.2 (SP 2) ldif data
+REM file (e. g. - created via a utility such as db2ldif)
+REM into a normalized CMS 4.2 (SP 2) ldif text file.
+REM
+REM This subsequent normalized CMS 4.2 (SP 2) ldif text file
+REM can be migrated into CMS 6.0 or later utilizing
+REM the corresponding TxtTo<Target CMS Version> script which
+REM converts this normalized CMS 4.2 (SP 2) ldif text file into
+REM a <Target CMS Version> ldif data file.
+REM
+REM This <Target CMS Version> ldif data file can then be
+REM imported into the internal database of the desired CMS
+REM server using a utility such as ldif2db.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM SERVER_ROOT - fully qualified path of the location of the server
+REM
+
+REM SET SERVER_ROOT=C:\cms43
+
+
+REM
+REM INSTANCE - if the CMS instance directory is called 'cert-ca',
+REM set the CMS instance to 'ca'
+REM
+REM NOTE: When a single SERVER_ROOT contains more than
+REM one CMS instance, this script must be run multiple
+REM times. To do this, there is only a need to change
+REM the INSTANCE parameter.
+REM
+
+REM SET INSTANCE=ca
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 4.2 (SP 2)"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO USAGE
+IF "%3" == "" GOTO CHECK_INPUT_FILE
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0 input [errors] > output"
+ECHO.
+ECHO where: input - the specified %CMS% ldif data file,
+ECHO errors - an optional errors file containing
+ECHO skipped attributes, and
+ECHO output - the normalized %CMS% ldif text file.
+ECHO.
+ECHO NOTE: If no redirection is provided to
+ECHO 'output', then the normalized
+ECHO %CMS% ldif text will merely
+ECHO be echoed to stdout.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified "input" file exists
+REM
+
+:CHECK_INPUT_FILE
+IF EXIST %1 GOTO CHECK_ERRORS_FILE
+
+
+ECHO ERROR: The specified input file, %1, does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM If an "errors" file is specified, then check that it does not already
+REM exist.
+REM
+
+:CHECK_ERRORS_FILE
+IF "%2" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+IF EXIST %2 GOTO ERRORS_FILE_ERROR
+GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:ERRORS_FILE_ERROR
+ECHO ERROR: The specified errors file, %2, already exists!
+ECHO Please specify a different file!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%INSTANCE%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and INSTANCE
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_INSTANCE
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified INSTANCE exists
+REM
+
+:CHECK_INSTANCE
+IF EXIST %SERVER_ROOT%\cert-%INSTANCE% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified INSTANCE does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%SERVER_ROOT%\bin\cert\jre\bin;%SERVER_ROOT\bin\cert\jre\bin\hotspot;%PATH%
+
+
+REM
+REM Convert the specified %CMS% ldif data file
+REM into a normalized %CMS% ldif text file.
+REM
+
+%SERVER_ROOT%\bin\cert\jre\bin\java.exe -classpath .\classes;%SERVER_ROOT%\cert-%INSTANCE%\classes;%SERVER_ROOT%\bin\cert\classes;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\jss21.jar;%SERVER_ROOT%\bin\cert\jre\lib\rt.jar Main %1 %2
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/42SP2ToTxt/run.sh b/base/migrate/42SP2ToTxt/run.sh
new file mode 100755
index 000000000..79a203700
--- /dev/null
+++ b/base/migrate/42SP2ToTxt/run.sh
@@ -0,0 +1,205 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+
+#####################################################################
+### ###
+### This script converts a pre-existing CMS 4.2 (SP 2) ldif data ###
+### file (e. g. - created via a utility such as db2ldif) ###
+### into a normalized CMS 4.2 (SP 2) ldif text file. ###
+### ###
+### This subsequent normalized CMS 4.2 (SP 2) ldif text file ###
+### can be migrated into CMS 6.0 or later utilizing ###
+### the corresponding TxtTo<Target CMS Version> script which ###
+### converts this normalized CMS 4.2 (SP 2) ldif text file into ###
+### a <Target CMS Version> ldif data file. ###
+### ###
+### This <Target CMS Version> ldif data file can then be ###
+### imported into the internal database of the desired CMS ###
+### server using a utility such as ldif2db. ###
+### ###
+#####################################################################
+
+
+###
+### SERVER_ROOT - fully qualified path of the location of the server
+###
+
+#SERVER_ROOT=/export/home/migrate/cms43
+#export SERVER_ROOT
+
+
+###
+### INSTANCE - if the CMS instance directory is called 'cert-ca',
+### set the CMS instance to 'ca'
+###
+### NOTE: When a single SERVER_ROOT contains more than
+### one CMS instance, this script must be run multiple
+### times. To do this, there is only a need to change
+### the INSTANCE parameter.
+###
+
+#INSTANCE=ca
+#export INSTANCE
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 4.2 (SP 2)"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+##
+## Perform a usage check for the appropriate number of arguments:
+##
+
+if [ $# -lt 1 -o $# -gt 2 ] ; then
+ echo
+ echo "Usage: $0 input [errors] > output"
+ echo
+ echo " where: input - the specified ${CMS} ldif data file,"
+ echo " errors - an optional errors file containing"
+ echo " skipped attributes, and"
+ echo " output - the normalized ${CMS} ldif text file."
+ echo
+ echo " NOTE: If no redirection is provided to"
+ echo " 'output', then the normalized"
+ echo " ${CMS} ldif text will merely"
+ echo " be echoed to stdout."
+ echo
+ exit 1
+fi
+
+
+###
+### Check that the specified "input" file exists and is a regular file.
+###
+
+if [ ! -f $1 ] ; then
+ echo "ERROR: Either the specified 'input' file, '$1', does not exist, "
+ echo " or it is not a regular file!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified "input" file exists and is not empty.
+###
+
+if [ ! -s $1 ] ; then
+ echo "ERROR: The specified 'input' file, '$1', is empty!"
+ echo
+ exit 3
+fi
+
+
+###
+### If an "errors" file is specified, then check that it does not already
+### exist.
+###
+
+if [ $# -eq 2 ] ; then
+ if [ -f $2 ] ; then
+ echo "ERROR: The specified 'errors' file, '$2', already exists!"
+ echo " Please specify a different file!"
+ echo
+ exit 4
+ fi
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${INSTANCE}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and INSTANCE "
+ echo " environment variables for this script!"
+ echo
+ exit 5
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 6
+fi
+
+
+###
+### Check that the specified INSTANCE exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}/cert-${INSTANCE}" ] ; then
+ echo "ERROR: Either the specified INSTANCE does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 7
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "AIX" ] ; then
+ LIBPATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/aix/native_threads
+ export LIBPATH
+elif [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+elif [ ${OS_NAME} = "OSF1" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/alpha/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Convert the specified ${CMS} ldif data file
+### into a normalized ${CMS} ldif text file.
+###
+
+${SERVER_ROOT}/bin/cert/jre/bin/java -classpath ./classes:${SERVER_ROOT}/cert-${INSTANCE}/classes:${SERVER_ROOT}/bin/cert/classes:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/jss21.jar:${SERVER_ROOT}/bin/cert/jre/lib/rt.jar:${SERVER_ROOT}/bin/cert/jre/lib/i18n.jar Main $1 $2
+
diff --git a/base/migrate/42SP2ToTxt/src/Main.java b/base/migrate/42SP2ToTxt/src/Main.java
new file mode 100644
index 000000000..1a324d8ee
--- /dev/null
+++ b/base/migrate/42SP2ToTxt/src/Main.java
@@ -0,0 +1,467 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+//
+// "42SP2ToTxt/src/Main.java" is based upon a copy "42ToTxt/src/Main.java".
+//
+// Always comment any new code sections with a "CMS 4.2 (SP 2)" header, and
+// apply these changes forward to all other "*ToTxt/src/Main.java" files
+// (including this comment header) so that these differences will only
+// appear when this file is diffed against an earlier "*ToTxt" version.
+//
+// This file should always be maintained by executing the following command:
+//
+// diff 42ToTxt/src/Main.java 42SP2ToTxt/src/Main.java
+//
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+import sun.misc.*;
+import com.netscape.jss.*; // CMS 4.1/4.2/4.2 (SP 2)
+import netscape.security.util.*;
+
+public class Main
+{
+ public static void main(String args[])
+ {
+ try {
+ // initialize CryptoManager in CMS 4.1/4.2/4.2 (SP 2)
+ CryptoManager.initialize("./secmod.db", "./key3.db", "./cert7.db");
+ // load JSS provider in CMS 4.1/4.2/4.2 (SP 2)
+ java.security.Security.removeProvider("Netscape version 1.4");
+ java.security.Security.removeProvider("SunRsaSign version 1.0");
+// java.security.Security.insertProviderAt(
+// new netscape.security.provider.CMS(), 0);
+ java.security.Provider ps[] =
+ java.security.Security.getProviders();
+ if (ps == null || ps.length <= 0) {
+ System.err.println("Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ System.err.println("Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+
+ // Parse the File
+ CMS42SP2LdifParser parser = null;
+ if (args.length == 1) {
+ parser = new CMS42SP2LdifParser(args[0]);
+ } else if (args.length == 2) {
+ parser = new CMS42SP2LdifParser(args[0], args[1]);
+ } else {
+ throw new IOException("Invalid Parameters");
+ }
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+}
+
+class CMS42SP2LdifParser
+{
+ // constants
+ private static final String DN =
+ "dn:";
+ // Directory Servers in CMS 4.1/4.2/4.2 (SP 2)/4.5 use "requestattributes"
+ private static final String REQUEST_ATTRIBUTES =
+ "requestattributes::";
+ private static final String BEGIN =
+ "--- BEGIN ATTRIBUTES ---";
+ private static final String END =
+ "--- END ATTRIBUTES ---";
+
+ // variables
+ private String mFilename = null;
+ private String mErrorFilename = null;
+ private PrintWriter mErrorPrintWriter = null;
+
+ public CMS42SP2LdifParser(String filename)
+ {
+ mFilename = filename;
+ }
+
+ public CMS42SP2LdifParser(String filename, String errorFilename)
+ {
+ mFilename = filename;
+ mErrorFilename = errorFilename;
+ }
+
+ public void parse() throws Exception
+ {
+ if (mErrorFilename != null) {
+ mErrorPrintWriter = new PrintWriter(new FileOutputStream(mErrorFilename));
+ }
+ BufferedReader reader = new BufferedReader(
+ new FileReader(mFilename));
+ String line = null;
+ String dn = null;
+ StringBuffer requestAttributes = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DN)) {
+ dn = line;
+ }
+ if (line.startsWith(REQUEST_ATTRIBUTES)) {
+ requestAttributes = new StringBuffer();
+ // System.out.println(line);
+ requestAttributes.append(
+ line.substring(REQUEST_ATTRIBUTES.length(),
+ line.length()).trim());
+ continue;
+ }
+ if (requestAttributes == null) {
+ System.out.println(line);
+ continue;
+ }
+ if (line.startsWith(" ")) {
+ // System.out.println(line);
+ requestAttributes.append(line.trim());
+ } else {
+ parseAttributes(dn, requestAttributes);
+ requestAttributes = null;
+ System.out.println(line);
+ }
+ }
+ }
+
+ public void parseAttributes(String dn, StringBuffer attrs) throws Exception
+ {
+ BASE64Decoder decoder = new BASE64Decoder();
+ decodeHashtable(dn, decoder.decodeBuffer(attrs.toString()));
+
+// System.out.println(attrs);
+ }
+
+ public Object decode(byte[] data) throws
+ ObjectStreamException,
+ IOException,
+ ClassNotFoundException
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+ return is.readObject();
+ }
+
+ public void decodeHashtable(String dn, byte[] data) throws Exception
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+
+ System.out.println(BEGIN);
+ String key = null;
+ while (true)
+ {
+ key = (String)is.readObject();
+ // end of table is marked with null
+ if (key == null) break;
+ try {
+ byte[] bytes = (byte[])is.readObject();
+ Object obj = decode(bytes);
+ output(key, obj);
+ } catch (Exception e) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + key);
+ }
+ }
+ }
+ System.out.println(END);
+ }
+
+ public void output(String key, Object obj) throws Exception
+ {
+ if (obj instanceof String) {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ } else if (obj instanceof netscape.security.x509.CertificateX509Key) {
+ netscape.security.x509.CertificateX509Key o =
+ (netscape.security.x509.CertificateX509Key)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateSubjectName) {
+ netscape.security.x509.CertificateSubjectName o =
+ (netscape.security.x509.CertificateSubjectName)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateExtensions) {
+ netscape.security.x509.CertificateExtensions o =
+ (netscape.security.x509.CertificateExtensions)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertInfo) {
+ netscape.security.x509.X509CertInfo o =
+ (netscape.security.x509.X509CertInfo)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl) {
+ netscape.security.x509.X509CertImpl o =
+ (netscape.security.x509.X509CertImpl)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateChain) {
+ netscape.security.x509.CertificateChain o =
+ (netscape.security.x509.CertificateChain)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl[]) {
+ netscape.security.x509.X509CertImpl o[] =
+ (netscape.security.x509.X509CertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.X509CertInfo[]) {
+ netscape.security.x509.X509CertInfo o[] =
+ (netscape.security.x509.X509CertInfo[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() + "["+o.length + "," + i+"]"+"=" +
+ encoder.encodeBuffer(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.RevokedCertImpl[]) {
+ netscape.security.x509.RevokedCertImpl o[] =
+ (netscape.security.x509.RevokedCertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ DerOutputStream bos =
+ new DerOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof java.security.cert.Certificate[]) {
+ java.security.cert.Certificate o[] =
+ (java.security.cert.Certificate[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(o[i].getEncoded()));
+ }
+ } else if (obj instanceof com.netscape.certsrv.base.ArgBlock) {
+ com.netscape.certsrv.base.ArgBlock o =
+ (com.netscape.certsrv.base.ArgBlock)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" +(String)o.get(k));
+ }
+ } else if (obj instanceof com.netscape.certsrv.dbs.keydb.KeyRecord) {
+ com.netscape.certsrv.dbs.keydb.KeyRecord o =
+ (com.netscape.certsrv.dbs.keydb.KeyRecord)obj;
+ Enumeration e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ Object ob = o.get(k);
+ if (ob != null) {
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + encoder.encode((byte[])ob));
+
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ }
+ } else if (obj instanceof com.netscape.certsrv.kra.ProofOfArchival) {
+ com.netscape.certsrv.kra.ProofOfArchival o =
+ (com.netscape.certsrv.kra.ProofOfArchival)obj;
+ DerOutputStream bos =
+ new DerOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof com.netscape.certsrv.request.AgentApprovals) {
+ com.netscape.certsrv.request.AgentApprovals o =
+ (com.netscape.certsrv.request.AgentApprovals)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ com.netscape.certsrv.request.AgentApproval approval = (com.netscape.certsrv.request.AgentApproval)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ approval.getUserName() + ";" + approval.getDate().getTime());
+ }
+ } else if (obj instanceof com.netscape.certsrv.authentication.AuthToken) {
+ com.netscape.certsrv.authentication.AuthToken o =
+ (com.netscape.certsrv.authentication.AuthToken)obj;
+ Enumeration e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ Object ob = o.get(k);
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof java.math.BigInteger[]) {
+ // Bugzilla Bug #225031 (a.k.a. - Raidzilla Bug #58356)
+ java.math.BigInteger in[] = (java.math.BigInteger[])ob;
+ String numbers = "";
+ for (int i = 0; i < in.length; i++) {
+ if (numbers.equals("")) {
+ numbers = in[i].toString();
+ } else {
+ numbers = numbers + "," + in[i].toString();
+ }
+ }
+ System.out.println(" " +
+ key + ":" + "com.netscape.certsrv.authentication.AuthToken" + "=" +
+ k + ":java.lang.String=" + numbers);
+ } else if (ob instanceof String[]) {
+ // Bugzilla Bug #224763 (a.k.a. - Raidzilla Bug #57949)
+ // Bugzilla Bug #252240
+ String str[] = (String[])ob;
+ String v = "";
+ if (str != null) {
+ for (int i = 0; i < str.length; i++) {
+ if (i != 0) {
+ v += ",";
+ }
+ v += str[i];
+ }
+ }
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + "java.lang.String" + "=" + v);
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ } else if (obj instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key + ":byte[]="+
+ encoder.encode((byte[])obj));
+ } else if (obj instanceof Integer[]) {
+ Integer in[] = (Integer[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":Integer[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof BigInteger[]) {
+ // Bugzilla Bug #238779
+ BigInteger in[] = (BigInteger[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":java.math.BigInteger[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof String[]) {
+ // Bugzilla Bug #223360 (a.k.a - Raidzilla Bug #58086)
+ String str[] = (String[])obj;
+ for (int i = 0; i < str.length; i++) {
+ System.out.println(" " + key + ":java.lang.String[" + str.length + "," + i + "]="+ str[i]);
+ }
+ } else if (obj instanceof netscape.security.x509.CertificateAlgorithmId) {
+ netscape.security.x509.CertificateAlgorithmId o =
+ (netscape.security.x509.CertificateAlgorithmId)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateAlgorithmId="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateValidity) {
+ netscape.security.x509.CertificateValidity o =
+ (netscape.security.x509.CertificateValidity)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateValidity="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof java.util.Hashtable) {
+ // Bugzilla Bug #224800 (a.k.a - Raidzilla Bug #56953)
+ //
+ // Example: fingerprints:java.util.Hashtable=
+ // {SHA1=[B@52513a, MD5=[B@52c4d9, MD2=[B@799ff5}
+ //
+ java.util.Hashtable o = (java.util.Hashtable)obj;
+ BASE64Encoder encoder = new BASE64Encoder();
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" + encoder.encode((byte[])o.get(k)));
+ }
+ } else {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ }
+ }
+}
+
diff --git a/base/migrate/42SP2ToTxt/src/compile.bat b/base/migrate/42SP2ToTxt/src/compile.bat
new file mode 100755
index 000000000..5b6c11566
--- /dev/null
+++ b/base/migrate/42SP2ToTxt/src/compile.bat
@@ -0,0 +1,152 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script creates the "42SP2ToTxt/classes/Main.class" and
+REM "42SP2ToTxt/classes/CMS42SP2LdifParser.class" which are
+REM used to create a normalized CMS 4.2 (SP 2) ldif text file.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM Set SERVER_ROOT - identify the CMS <server_root> used to compile 42SP2ToTxt
+REM
+
+REM SET SERVER_ROOT=C:\cms43
+
+
+REM
+REM Set JDK_VERSION - specify the JDK version used by this version of CMS
+REM
+REM CMS 4.2 (SP 2) NOTE: "WINNT" - 1.3.0
+REM
+REM CMS 4.2 (SP 2) CONSOLE NOTE: "WINNT" - 1.1.7A
+REM
+
+REM SET JDK_VERSION=CMS_4.3
+
+
+REM
+REM Set JAVA_HOME - specify the complete path to the JDK
+REM
+REM example: \\bermuda.redhat.com\sbc mounted as Y:
+REM
+
+REM SET JAVA_HOME=Y:\cms_jdk\WINNT\%JDK_VERSION%
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 4.2 (SP 2)"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0"
+ECHO.
+ECHO NOTE: No arguments are required to build the
+ECHO normalized %CMS% ldif text classes.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%JAVA_HOME%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and JAVA_HOME
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_JAVA_HOME
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified JAVA_HOME exists
+REM
+
+:CHECK_JAVA_HOME
+IF EXIST %JAVA_HOME% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified JAVA_HOME does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%JAVA_HOME%\bin;%JAVA_HOME%\lib;%PATH%
+
+
+REM
+REM Set TARGET - identify the complete path to the new classes target directory
+REM
+
+SET TARGET=..\classes
+
+
+REM
+REM Create the new classes target directory (if it does not already exist)
+REM
+
+IF EXIST %TARGET% goto COMPILE_CLASSES
+MKDIR %TARGET%
+
+
+REM
+REM Compile 42SP2ToTxt - create "CMS42SP2LdifParser.class" and "Main.class"
+REM
+
+:COMPILE_CLASSES
+%JAVA_HOME%\bin\javac.exe -d %TARGET% -classpath %JAVA_HOME%\jre\lib\rt.jar;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\jss21.jar Main.java
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/42SP2ToTxt/src/compile.sh b/base/migrate/42SP2ToTxt/src/compile.sh
new file mode 100755
index 000000000..26aa6140b
--- /dev/null
+++ b/base/migrate/42SP2ToTxt/src/compile.sh
@@ -0,0 +1,174 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#####################################################################
+### ###
+### This script creates the "42SP2ToTxt/classes/Main.class" and ###
+### "42SP2ToTxt/classes/CMS42SP2LdifParser.class" which are ###
+### used to create a normalized CMS 4.2 (SP 2) ldif text file. ###
+### ###
+#####################################################################
+
+
+###
+### Set SERVER_ROOT - identify the CMS <server_root> used to compile 42SP2ToTxt
+###
+
+#SERVER_ROOT=/export/home/migrate/cms42sp2
+#export SERVER_ROOT
+
+
+###
+### Set JDK_PLATFORM - must be "AIX", "HP-UX", "Linux", "OSF1", or "SunOS"
+###
+
+#JDK_PLATFORM=SunOS
+#export JDK_PLATFORM
+
+
+###
+### Set JDK_VERSION - specify the JDK version used by this version of CMS
+###
+### CMS 4.2 (SP 2) NOTE: "AIX" - 1.3.0
+### "HP-UX" - 1.3.0.00
+### "Linux" - 1.3.0
+### "OSF1" - 1.3.0-1
+### "SunOS" - 1.3.0
+###
+### CMS 4.2 (SP 2) CONSOLE NOTE: "AIX" - 1.1.6_10
+### "HP-UX" - 1.1.6
+### "Linux" - 1.1.7
+### "OSF1" - 1.1.6
+### "SunOS" - 1.1.6
+###
+
+#JDK_VERSION=CMS_4.3
+#export JDK_VERSION
+
+
+###
+### Set JAVA_HOME - specify the complete path to the JDK
+###
+
+#JAVA_HOME=/share/builds/components/cms_jdk/${JDK_PLATFORM}/${JDK_VERSION}
+#export JAVA_HOME
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 4.2 (SP 2)"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -gt 0 ] ; then
+ echo
+ echo "Usage: $0"
+ echo
+ echo " NOTE: No arguments are required to build the"
+ echo " normalized ${CMS} ldif text classes."
+ echo
+ exit 1
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${JAVA_HOME}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and JAVA_HOME "
+ echo " environment variables for this script!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 3
+fi
+
+
+###
+### Check that the specified JAVA_HOME exists and is a directory
+###
+
+if [ ! -d "${JAVA_HOME}" ] ; then
+ echo "ERROR: Either the specified JAVA_HOME does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 4
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "AIX" ] ; then
+ LIBPATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/aix/native_threads
+ export LIBPATH
+elif [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+elif [ ${OS_NAME} = "OSF1" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/alpha/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Set TARGET - identify the complete path to the new classes target directory
+###
+
+TARGET=../classes
+export TARGET
+
+
+###
+### Create the new classes target directory (if it does not already exist)
+###
+
+if [ ! -d ${TARGET} ]; then
+ mkdir -p ${TARGET}
+fi
+
+
+###
+### Compile 42SP2ToTxt - create "CMS42SP2LdifParser.class" and "Main.class"
+###
+
+${JAVA_HOME}/bin/javac -d ${TARGET} -classpath ${JAVA_HOME}/jre/lib/rt.jar:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/jss21.jar Main.java
+
diff --git a/base/migrate/42ToTxt/classes/CMS42LdifParser.class b/base/migrate/42ToTxt/classes/CMS42LdifParser.class
new file mode 100644
index 000000000..81c20523c
--- /dev/null
+++ b/base/migrate/42ToTxt/classes/CMS42LdifParser.class
Binary files differ
diff --git a/base/migrate/42ToTxt/classes/Main.class b/base/migrate/42ToTxt/classes/Main.class
new file mode 100644
index 000000000..7a75e96c0
--- /dev/null
+++ b/base/migrate/42ToTxt/classes/Main.class
Binary files differ
diff --git a/base/migrate/42ToTxt/run.bat b/base/migrate/42ToTxt/run.bat
new file mode 100755
index 000000000..43300869c
--- /dev/null
+++ b/base/migrate/42ToTxt/run.bat
@@ -0,0 +1,192 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM This program is free software; you can redistribute it and/or modify
+REM it under the terms of the GNU General Public License as published by
+REM the Free Software Foundation; version 2 of the License.
+REM
+REM This program is distributed in the hope that it will be useful,
+REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+REM GNU General Public License for more details.
+REM
+REM You should have received a copy of the GNU General Public License along
+REM with this program; if not, write to the Free Software Foundation, Inc.,
+REM 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script converts a pre-existing CMS 4.2 ldif data
+REM file (e. g. - created via a utility such as db2ldif)
+REM into a normalized CMS 4.2 ldif text file.
+REM
+REM This subsequent normalized CMS 4.2 ldif text file
+REM can be migrated into CMS 6.0 or later utilizing
+REM the corresponding TxtTo<Target CMS Version> script which
+REM converts this normalized CMS 4.2 ldif text file into
+REM a <Target CMS Version> ldif data file.
+REM
+REM This <Target CMS Version> ldif data file can then be
+REM imported into the internal database of the desired CMS
+REM server using a utility such as ldif2db.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM SERVER_ROOT - fully qualified path of the location of the server
+REM
+
+REM SET SERVER_ROOT=C:\cms42
+
+
+REM
+REM INSTANCE - if the CMS instance directory is called 'cert-ca',
+REM set the CMS instance to 'ca'
+REM
+REM NOTE: When a single SERVER_ROOT contains more than
+REM one CMS instance, this script must be run multiple
+REM times. To do this, there is only a need to change
+REM the INSTANCE parameter.
+REM
+
+REM SET INSTANCE=ca
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 4.2"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO USAGE
+IF "%3" == "" GOTO CHECK_INPUT_FILE
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0 input [errors] > output"
+ECHO.
+ECHO where: input - the specified %CMS% ldif data file,
+ECHO errors - an optional errors file containing
+ECHO skipped attributes, and
+ECHO output - the normalized %CMS% ldif text file.
+ECHO.
+ECHO NOTE: If no redirection is provided to
+ECHO 'output', then the normalized
+ECHO %CMS% ldif text will merely
+ECHO be echoed to stdout.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified "input" file exists
+REM
+
+:CHECK_INPUT_FILE
+IF EXIST %1 GOTO CHECK_ERRORS_FILE
+
+
+ECHO ERROR: The specified input file, %1, does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM If an "errors" file is specified, then check that it does not already
+REM exist.
+REM
+
+:CHECK_ERRORS_FILE
+IF "%2" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+IF EXIST %2 GOTO ERRORS_FILE_ERROR
+GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:ERRORS_FILE_ERROR
+ECHO ERROR: The specified errors file, %2, already exists!
+ECHO Please specify a different file!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%INSTANCE%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and INSTANCE
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_INSTANCE
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified INSTANCE exists
+REM
+
+:CHECK_INSTANCE
+IF EXIST %SERVER_ROOT%\cert-%INSTANCE% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified INSTANCE does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%SERVER_ROOT%\bin\cert\jre\bin;%PATH%
+
+
+REM
+REM Convert the specified %CMS% ldif data file
+REM into a normalized %CMS% ldif text file.
+REM
+
+%SERVER_ROOT%\bin\cert\jre\bin\jre.exe -classpath .\classes;%SERVER_ROOT%\cert-%INSTANCE%\classes;%SERVER_ROOT%\bin\cert\classes;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\jss.jar;%SERVER_ROOT%\bin\cert\jars\jssjdk12.jar;%SERVER_ROOT%\bin\cert\jre\lib\rt.jar Main %1 %2
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/42ToTxt/run.sh b/base/migrate/42ToTxt/run.sh
new file mode 100755
index 000000000..3172159f1
--- /dev/null
+++ b/base/migrate/42ToTxt/run.sh
@@ -0,0 +1,205 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+
+#####################################################################
+### ###
+### This script converts a pre-existing CMS 4.2 ldif data ###
+### file (e. g. - created via a utility such as db2ldif) ###
+### into a normalized CMS 4.2 ldif text file. ###
+### ###
+### This subsequent normalized CMS 4.2 ldif text file ###
+### can be migrated into CMS 6.0 or later utilizing ###
+### the corresponding TxtTo<Target CMS Version> script which ###
+### converts this normalized CMS 4.2 ldif text file into ###
+### a <Target CMS Version> ldif data file. ###
+### ###
+### This <Target CMS Version> ldif data file can then be ###
+### imported into the internal database of the desired CMS ###
+### server using a utility such as ldif2db. ###
+### ###
+#####################################################################
+
+
+###
+### SERVER_ROOT - fully qualified path of the location of the server
+###
+
+#SERVER_ROOT=/export/home/migrate/cms42
+#export SERVER_ROOT
+
+
+###
+### INSTANCE - if the CMS instance directory is called 'cert-ca',
+### set the CMS instance to 'ca'
+###
+### NOTE: When a single SERVER_ROOT contains more than
+### one CMS instance, this script must be run multiple
+### times. To do this, there is only a need to change
+### the INSTANCE parameter.
+###
+
+#INSTANCE=ca
+#export INSTANCE
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 4.2"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+##
+## Perform a usage check for the appropriate number of arguments:
+##
+
+if [ $# -lt 1 -o $# -gt 2 ] ; then
+ echo
+ echo "Usage: $0 input [errors] > output"
+ echo
+ echo " where: input - the specified ${CMS} ldif data file,"
+ echo " errors - an optional errors file containing"
+ echo " skipped attributes, and"
+ echo " output - the normalized ${CMS} ldif text file."
+ echo
+ echo " NOTE: If no redirection is provided to"
+ echo " 'output', then the normalized"
+ echo " ${CMS} ldif text will merely"
+ echo " be echoed to stdout."
+ echo
+ exit 1
+fi
+
+
+###
+### Check that the specified "input" file exists and is a regular file.
+###
+
+if [ ! -f $1 ] ; then
+ echo "ERROR: Either the specified 'input' file, '$1', does not exist, "
+ echo " or it is not a regular file!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified "input" file exists and is not empty.
+###
+
+if [ ! -s $1 ] ; then
+ echo "ERROR: The specified 'input' file, '$1', is empty!"
+ echo
+ exit 3
+fi
+
+
+###
+### If an "errors" file is specified, then check that it does not already
+### exist.
+###
+
+if [ $# -eq 2 ] ; then
+ if [ -f $2 ] ; then
+ echo "ERROR: The specified 'errors' file, '$2', already exists!"
+ echo " Please specify a different file!"
+ echo
+ exit 4
+ fi
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${INSTANCE}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and INSTANCE "
+ echo " environment variables for this script!"
+ echo
+ exit 5
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 6
+fi
+
+
+###
+### Check that the specified INSTANCE exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}/cert-${INSTANCE}" ] ; then
+ echo "ERROR: Either the specified INSTANCE does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 7
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "AIX" ] ; then
+ LIBPATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/aix/native_threads
+ export LIBPATH
+elif [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+elif [ ${OS_NAME} = "OSF1" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/alpha/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Convert the specified ${CMS} ldif data file
+### into a normalized ${CMS} ldif text file.
+###
+
+${SERVER_ROOT}/bin/cert/jre/bin/jre -classpath ./classes:${SERVER_ROOT}/cert-${INSTANCE}/classes:${SERVER_ROOT}/bin/cert/classes:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/jss.jar:${SERVER_ROOT}/bin/cert/jars/jssjdk12.jar:${SERVER_ROOT}/bin/cert/jre/lib/rt.jar:${SERVER_ROOT}/bin/cert/jre/lib/i18n.jar Main $1 $2
+
diff --git a/base/migrate/42ToTxt/src/Main.java b/base/migrate/42ToTxt/src/Main.java
new file mode 100644
index 000000000..55e64df08
--- /dev/null
+++ b/base/migrate/42ToTxt/src/Main.java
@@ -0,0 +1,467 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+//
+// "42ToTxt/src/Main.java" is based upon a copy "41ToTxt/src/Main.java".
+//
+// Always comment any new code sections with a "CMS 4.2" header, and
+// apply these changes forward to all other "*ToTxt/src/Main.java" files
+// (including this comment header) so that these differences will only
+// appear when this file is diffed against an earlier "*ToTxt" version.
+//
+// This file should always be maintained by executing the following command:
+//
+// diff 41ToTxt/src/Main.java 42ToTxt/src/Main.java
+//
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+import sun.misc.*;
+import com.netscape.jss.*; // CMS 4.1/4.2/4.2 (SP 2)
+import netscape.security.util.*;
+
+public class Main
+{
+ public static void main(String args[])
+ {
+ try {
+ // initialize CryptoManager in CMS 4.1/4.2/4.2 (SP 2)
+ CryptoManager.initialize("./secmod.db", "./key3.db", "./cert7.db");
+ // load JSS provider in CMS 4.1/4.2/4.2 (SP 2)
+ java.security.Security.removeProvider("Netscape version 1.4");
+ java.security.Security.removeProvider("SunRsaSign version 1.0");
+// java.security.Security.insertProviderAt(
+// new netscape.security.provider.CMS(), 0);
+ java.security.Provider ps[] =
+ java.security.Security.getProviders();
+ if (ps == null || ps.length <= 0) {
+ System.err.println("Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ System.err.println("Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+
+ // Parse the File
+ CMS42LdifParser parser = null;
+ if (args.length == 1) {
+ parser = new CMS42LdifParser(args[0]);
+ } else if (args.length == 2) {
+ parser = new CMS42LdifParser(args[0], args[1]);
+ } else {
+ throw new IOException("Invalid Parameters");
+ }
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+}
+
+class CMS42LdifParser
+{
+ // constants
+ private static final String DN =
+ "dn:";
+ // Directory Servers in CMS 4.1/4.2/4.2 (SP 2)/4.5 use "requestattributes"
+ private static final String REQUEST_ATTRIBUTES =
+ "requestattributes::";
+ private static final String BEGIN =
+ "--- BEGIN ATTRIBUTES ---";
+ private static final String END =
+ "--- END ATTRIBUTES ---";
+
+ // variables
+ private String mFilename = null;
+ private String mErrorFilename = null;
+ private PrintWriter mErrorPrintWriter = null;
+
+ public CMS42LdifParser(String filename)
+ {
+ mFilename = filename;
+ }
+
+ public CMS42LdifParser(String filename, String errorFilename)
+ {
+ mFilename = filename;
+ mErrorFilename = errorFilename;
+ }
+
+ public void parse() throws Exception
+ {
+ if (mErrorFilename != null) {
+ mErrorPrintWriter = new PrintWriter(new FileOutputStream(mErrorFilename));
+ }
+ BufferedReader reader = new BufferedReader(
+ new FileReader(mFilename));
+ String line = null;
+ String dn = null;
+ StringBuffer requestAttributes = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DN)) {
+ dn = line;
+ }
+ if (line.startsWith(REQUEST_ATTRIBUTES)) {
+ requestAttributes = new StringBuffer();
+ // System.out.println(line);
+ requestAttributes.append(
+ line.substring(REQUEST_ATTRIBUTES.length(),
+ line.length()).trim());
+ continue;
+ }
+ if (requestAttributes == null) {
+ System.out.println(line);
+ continue;
+ }
+ if (line.startsWith(" ")) {
+ // System.out.println(line);
+ requestAttributes.append(line.trim());
+ } else {
+ parseAttributes(dn, requestAttributes);
+ requestAttributes = null;
+ System.out.println(line);
+ }
+ }
+ }
+
+ public void parseAttributes(String dn, StringBuffer attrs) throws Exception
+ {
+ BASE64Decoder decoder = new BASE64Decoder();
+ decodeHashtable(dn, decoder.decodeBuffer(attrs.toString()));
+
+// System.out.println(attrs);
+ }
+
+ public Object decode(byte[] data) throws
+ ObjectStreamException,
+ IOException,
+ ClassNotFoundException
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+ return is.readObject();
+ }
+
+ public void decodeHashtable(String dn, byte[] data) throws Exception
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+
+ System.out.println(BEGIN);
+ String key = null;
+ while (true)
+ {
+ key = (String)is.readObject();
+ // end of table is marked with null
+ if (key == null) break;
+ try {
+ byte[] bytes = (byte[])is.readObject();
+ Object obj = decode(bytes);
+ output(key, obj);
+ } catch (Exception e) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + key);
+ }
+ }
+ }
+ System.out.println(END);
+ }
+
+ public void output(String key, Object obj) throws Exception
+ {
+ if (obj instanceof String) {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ } else if (obj instanceof netscape.security.x509.CertificateX509Key) {
+ netscape.security.x509.CertificateX509Key o =
+ (netscape.security.x509.CertificateX509Key)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateSubjectName) {
+ netscape.security.x509.CertificateSubjectName o =
+ (netscape.security.x509.CertificateSubjectName)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateExtensions) {
+ netscape.security.x509.CertificateExtensions o =
+ (netscape.security.x509.CertificateExtensions)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertInfo) {
+ netscape.security.x509.X509CertInfo o =
+ (netscape.security.x509.X509CertInfo)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl) {
+ netscape.security.x509.X509CertImpl o =
+ (netscape.security.x509.X509CertImpl)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateChain) {
+ netscape.security.x509.CertificateChain o =
+ (netscape.security.x509.CertificateChain)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl[]) {
+ netscape.security.x509.X509CertImpl o[] =
+ (netscape.security.x509.X509CertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.X509CertInfo[]) {
+ netscape.security.x509.X509CertInfo o[] =
+ (netscape.security.x509.X509CertInfo[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() + "["+o.length + "," + i+"]"+"=" +
+ encoder.encodeBuffer(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.RevokedCertImpl[]) {
+ netscape.security.x509.RevokedCertImpl o[] =
+ (netscape.security.x509.RevokedCertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ DerOutputStream bos =
+ new DerOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof java.security.cert.Certificate[]) {
+ java.security.cert.Certificate o[] =
+ (java.security.cert.Certificate[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(o[i].getEncoded()));
+ }
+ } else if (obj instanceof com.netscape.certsrv.base.ArgBlock) {
+ com.netscape.certsrv.base.ArgBlock o =
+ (com.netscape.certsrv.base.ArgBlock)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" +(String)o.get(k));
+ }
+ } else if (obj instanceof com.netscape.certsrv.dbs.keydb.KeyRecord) {
+ com.netscape.certsrv.dbs.keydb.KeyRecord o =
+ (com.netscape.certsrv.dbs.keydb.KeyRecord)obj;
+ Enumeration e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ Object ob = o.get(k);
+ if (ob != null) {
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + encoder.encode((byte[])ob));
+
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ }
+ } else if (obj instanceof com.netscape.certsrv.kra.ProofOfArchival) {
+ com.netscape.certsrv.kra.ProofOfArchival o =
+ (com.netscape.certsrv.kra.ProofOfArchival)obj;
+ DerOutputStream bos =
+ new DerOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof com.netscape.certsrv.request.AgentApprovals) {
+ com.netscape.certsrv.request.AgentApprovals o =
+ (com.netscape.certsrv.request.AgentApprovals)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ com.netscape.certsrv.request.AgentApproval approval = (com.netscape.certsrv.request.AgentApproval)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ approval.getUserName() + ";" + approval.getDate().getTime());
+ }
+ } else if (obj instanceof com.netscape.certsrv.authentication.AuthToken) {
+ com.netscape.certsrv.authentication.AuthToken o =
+ (com.netscape.certsrv.authentication.AuthToken)obj;
+ Enumeration e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ Object ob = o.get(k);
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof java.math.BigInteger[]) {
+ // Bugzilla Bug #225031 (a.k.a. - Raidzilla Bug #58356)
+ java.math.BigInteger in[] = (java.math.BigInteger[])ob;
+ String numbers = "";
+ for (int i = 0; i < in.length; i++) {
+ if (numbers.equals("")) {
+ numbers = in[i].toString();
+ } else {
+ numbers = numbers + "," + in[i].toString();
+ }
+ }
+ System.out.println(" " +
+ key + ":" + "com.netscape.certsrv.authentication.AuthToken" + "=" +
+ k + ":java.lang.String=" + numbers);
+ } else if (ob instanceof String[]) {
+ // Bugzilla Bug #224763 (a.k.a. - Raidzilla Bug #57949)
+ // Bugzilla Bug #252240
+ String str[] = (String[])ob;
+ String v = "";
+ if (str != null) {
+ for (int i = 0; i < str.length; i++) {
+ if (i != 0) {
+ v += ",";
+ }
+ v += str[i];
+ }
+ }
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + "java.lang.String" + "=" + v);
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ } else if (obj instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key + ":byte[]="+
+ encoder.encode((byte[])obj));
+ } else if (obj instanceof Integer[]) {
+ Integer in[] = (Integer[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":Integer[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof BigInteger[]) {
+ // Bugzilla Bug #238779
+ BigInteger in[] = (BigInteger[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":java.math.BigInteger[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof String[]) {
+ // Bugzilla Bug #223360 (a.k.a - Raidzilla Bug #58086)
+ String str[] = (String[])obj;
+ for (int i = 0; i < str.length; i++) {
+ System.out.println(" " + key + ":java.lang.String[" + str.length + "," + i + "]="+ str[i]);
+ }
+ } else if (obj instanceof netscape.security.x509.CertificateAlgorithmId) {
+ netscape.security.x509.CertificateAlgorithmId o =
+ (netscape.security.x509.CertificateAlgorithmId)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateAlgorithmId="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateValidity) {
+ netscape.security.x509.CertificateValidity o =
+ (netscape.security.x509.CertificateValidity)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateValidity="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof java.util.Hashtable) {
+ // Bugzilla Bug #224800 (a.k.a - Raidzilla Bug #56953)
+ //
+ // Example: fingerprints:java.util.Hashtable=
+ // {SHA1=[B@52513a, MD5=[B@52c4d9, MD2=[B@799ff5}
+ //
+ java.util.Hashtable o = (java.util.Hashtable)obj;
+ BASE64Encoder encoder = new BASE64Encoder();
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" + encoder.encode((byte[])o.get(k)));
+ }
+ } else {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ }
+ }
+}
+
diff --git a/base/migrate/42ToTxt/src/compile.bat b/base/migrate/42ToTxt/src/compile.bat
new file mode 100755
index 000000000..20ca0ebb5
--- /dev/null
+++ b/base/migrate/42ToTxt/src/compile.bat
@@ -0,0 +1,150 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script creates the "42ToTxt/classes/Main.class" and
+REM "42ToTxt/classes/CMS42LdifParser.class" which are
+REM used to create a normalized CMS 4.2 ldif text file.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM Set SERVER_ROOT - identify the CMS <server_root> used to compile 42ToTxt
+REM
+
+REM SET SERVER_ROOT=C:\cms42
+
+
+REM
+REM Set JDK_VERSION - specify the JDK version used by this version of CMS
+REM
+REM CMS 4.2 NOTE: "WINNT" - 1.1.7A
+REM
+
+REM SET JDK_VERSION=CMS_4.2
+
+
+REM
+REM Set JAVA_HOME - specify the complete path to the JDK
+REM
+REM example: \\bermuda.redhat.com\sbc mounted as Y:
+REM
+
+REM SET JAVA_HOME=Y:\cms_jdk\WINNT\%JDK_VERSION%
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 4.2"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0"
+ECHO.
+ECHO NOTE: No arguments are required to build the
+ECHO normalized %CMS% ldif text classes.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%JAVA_HOME%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and JAVA_HOME
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_JAVA_HOME
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified JAVA_HOME exists
+REM
+
+:CHECK_JAVA_HOME
+IF EXIST %JAVA_HOME% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified JAVA_HOME does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%JAVA_HOME%\bin;%JAVA_HOME%\lib;%PATH%
+
+
+REM
+REM Set TARGET - identify the complete path to the new classes target directory
+REM
+
+SET TARGET=..\classes
+
+
+REM
+REM Create the new classes target directory (if it does not already exist)
+REM
+
+IF EXIST %TARGET% goto COMPILE_CLASSES
+MKDIR %TARGET%
+
+
+REM
+REM Compile 42ToTxt - create "CMS42LdifParser.class" and "Main.class"
+REM
+
+:COMPILE_CLASSES
+%JAVA_HOME%\bin\javac.exe -d %TARGET% -classpath %JAVA_HOME%\lib\classes.zip;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\jss.jar;%SERVER_ROOT%\bin\cert\jars\jssjdk12.jar Main.java
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/42ToTxt/src/compile.sh b/base/migrate/42ToTxt/src/compile.sh
new file mode 100755
index 000000000..e8acf71bf
--- /dev/null
+++ b/base/migrate/42ToTxt/src/compile.sh
@@ -0,0 +1,168 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#####################################################################
+### ###
+### This script creates the "42ToTxt/classes/Main.class" and ###
+### "42ToTxt/classes/CMS42LdifParser.class" which are ###
+### used to create a normalized CMS 4.2 ldif text file. ###
+### ###
+#####################################################################
+
+
+###
+### Set SERVER_ROOT - identify the CMS <server_root> used to compile 42ToTxt
+###
+
+#SERVER_ROOT=/export/home/migrate/cms42
+#export SERVER_ROOT
+
+
+###
+### Set JDK_PLATFORM - must be "AIX", "HP-UX", "Linux", "OSF1", or "SunOS"
+###
+
+#JDK_PLATFORM=SunOS
+#export JDK_PLATFORM
+
+
+###
+### Set JDK_VERSION - specify the JDK version used by this version of CMS
+###
+### CMS 4.2 NOTE: "AIX" - 1.1.6_10
+### "HP-UX" - 1.1.6
+### "Linux" - 1.1.7
+### "OSF1" - 1.1.6
+### "SunOS" - 1.1.6
+###
+
+#JDK_VERSION=CMS_4.2
+#export JDK_VERSION
+
+
+###
+### Set JAVA_HOME - specify the complete path to the JDK
+###
+
+#JAVA_HOME=/share/builds/components/cms_jdk/${JDK_PLATFORM}/${JDK_VERSION}
+#export JAVA_HOME
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 4.2"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -gt 0 ] ; then
+ echo
+ echo "Usage: $0"
+ echo
+ echo " NOTE: No arguments are required to build the"
+ echo " normalized ${CMS} ldif text classes."
+ echo
+ exit 1
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${JAVA_HOME}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and JAVA_HOME "
+ echo " environment variables for this script!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 3
+fi
+
+
+###
+### Check that the specified JAVA_HOME exists and is a directory
+###
+
+if [ ! -d "${JAVA_HOME}" ] ; then
+ echo "ERROR: Either the specified JAVA_HOME does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 4
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "AIX" ] ; then
+ LIBPATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/aix/native_threads
+ export LIBPATH
+elif [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+elif [ ${OS_NAME} = "OSF1" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/alpha/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Set TARGET - identify the complete path to the new classes target directory
+###
+
+TARGET=../classes
+export TARGET
+
+
+###
+### Create the new classes target directory (if it does not already exist)
+###
+
+if [ ! -d ${TARGET} ]; then
+ mkdir -p ${TARGET}
+fi
+
+
+###
+### Compile 42ToTxt - create "CMS42LdifParser.class" and "Main.class"
+###
+
+${JAVA_HOME}/bin/javac -d ${TARGET} -classpath ${JAVA_HOME}/lib/classes.zip:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/jss.jar:${SERVER_ROOT}/bin/cert/jars/jssjdk12.jar Main.java
+
diff --git a/base/migrate/45ToTxt/classes/CMS45LdifParser.class b/base/migrate/45ToTxt/classes/CMS45LdifParser.class
new file mode 100644
index 000000000..75d4ab47c
--- /dev/null
+++ b/base/migrate/45ToTxt/classes/CMS45LdifParser.class
Binary files differ
diff --git a/base/migrate/45ToTxt/classes/Main.class b/base/migrate/45ToTxt/classes/Main.class
new file mode 100644
index 000000000..a1f3e91c2
--- /dev/null
+++ b/base/migrate/45ToTxt/classes/Main.class
Binary files differ
diff --git a/base/migrate/45ToTxt/run.bat b/base/migrate/45ToTxt/run.bat
new file mode 100755
index 000000000..8dfb4e77c
--- /dev/null
+++ b/base/migrate/45ToTxt/run.bat
@@ -0,0 +1,192 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM This program is free software; you can redistribute it and/or modify
+REM it under the terms of the GNU General Public License as published by
+REM the Free Software Foundation; version 2 of the License.
+REM
+REM This program is distributed in the hope that it will be useful,
+REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+REM GNU General Public License for more details.
+REM
+REM You should have received a copy of the GNU General Public License along
+REM with this program; if not, write to the Free Software Foundation, Inc.,
+REM 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script converts a pre-existing CMS 4.5 ldif data
+REM file (e. g. - created via a utility such as db2ldif)
+REM into a normalized CMS 4.5 ldif text file.
+REM
+REM This subsequent normalized CMS 4.5 ldif text file
+REM can be migrated into CMS 6.0 or later utilizing
+REM the corresponding TxtTo<Target CMS Version> script which
+REM converts this normalized CMS 4.5 ldif text file into
+REM a <Target CMS Version> ldif data file.
+REM
+REM This <Target CMS Version> ldif data file can then be
+REM imported into the internal database of the desired CMS
+REM server using a utility such as ldif2db.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM SERVER_ROOT - fully qualified path of the location of the server
+REM
+
+REM SET SERVER_ROOT=C:\cms45
+
+
+REM
+REM INSTANCE - if the CMS instance directory is called 'cert-ca',
+REM set the CMS instance to 'ca'
+REM
+REM NOTE: When a single SERVER_ROOT contains more than
+REM one CMS instance, this script must be run multiple
+REM times. To do this, there is only a need to change
+REM the INSTANCE parameter.
+REM
+
+REM SET INSTANCE=ca
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 4.5"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO USAGE
+IF "%3" == "" GOTO CHECK_INPUT_FILE
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0 input [errors] > output"
+ECHO.
+ECHO where: input - the specified %CMS% ldif data file,
+ECHO errors - an optional errors file containing
+ECHO skipped attributes, and
+ECHO output - the normalized %CMS% ldif text file.
+ECHO.
+ECHO NOTE: If no redirection is provided to
+ECHO 'output', then the normalized
+ECHO %CMS% ldif text will merely
+ECHO be echoed to stdout.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified "input" file exists
+REM
+
+:CHECK_INPUT_FILE
+IF EXIST %1 GOTO CHECK_ERRORS_FILE
+
+
+ECHO ERROR: The specified input file, %1, does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM If an "errors" file is specified, then check that it does not already
+REM exist.
+REM
+
+:CHECK_ERRORS_FILE
+IF "%2" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+IF EXIST %2 GOTO ERRORS_FILE_ERROR
+GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:ERRORS_FILE_ERROR
+ECHO ERROR: The specified errors file, %2, already exists!
+ECHO Please specify a different file!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%INSTANCE%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and INSTANCE
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_INSTANCE
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified INSTANCE exists
+REM
+
+:CHECK_INSTANCE
+IF EXIST %SERVER_ROOT%\cert-%INSTANCE% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified INSTANCE does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%SERVER_ROOT%\bin\cert\jre\bin;%SERVER_ROOT\bin\cert\jre\bin\hotspot;%PATH%
+
+
+REM
+REM Convert the specified %CMS% ldif data file
+REM into a normalized %CMS% ldif text file.
+REM
+
+%SERVER_ROOT%\bin\cert\jre\bin\java.exe -classpath .\classes;%SERVER_ROOT%\cert-%INSTANCE%\classes;%SERVER_ROOT%\bin\cert\classes;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar;%SERVER_ROOT%\bin\cert\jre\lib\rt.jar Main %1 %2
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/45ToTxt/run.sh b/base/migrate/45ToTxt/run.sh
new file mode 100755
index 000000000..f19a550d5
--- /dev/null
+++ b/base/migrate/45ToTxt/run.sh
@@ -0,0 +1,196 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+
+#####################################################################
+### ###
+### This script converts a pre-existing CMS 4.5 ldif data ###
+### file (e. g. - created via a utility such as db2ldif) ###
+### into a normalized CMS 4.5 ldif text file. ###
+### ###
+### This subsequent normalized CMS 4.5 ldif text file ###
+### can be migrated into CMS 6.0 or later utilizing ###
+### the corresponding TxtTo<Target CMS Version> script which ###
+### converts this normalized CMS 4.5 ldif text file into ###
+### a <Target CMS Version> ldif data file. ###
+### ###
+### This <Target CMS Version> ldif data file can then be ###
+### imported into the internal database of the desired CMS ###
+### server using a utility such as ldif2db. ###
+### ###
+#####################################################################
+
+
+###
+### SERVER_ROOT - fully qualified path of the location of the server
+###
+
+#SERVER_ROOT=/export/home/migrate/cms45
+#export SERVER_ROOT
+
+
+###
+### INSTANCE - if the CMS instance directory is called 'cert-ca',
+### set the CMS instance to 'ca'
+###
+### NOTE: When a single SERVER_ROOT contains more than
+### one CMS instance, this script must be run multiple
+### times. To do this, there is only a need to change
+### the INSTANCE parameter.
+###
+
+#INSTANCE=ca
+#export INSTANCE
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 4.5"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+##
+## Perform a usage check for the appropriate number of arguments:
+##
+
+if [ $# -lt 1 -o $# -gt 2 ] ; then
+ echo
+ echo "Usage: $0 input [errors] > output"
+ echo
+ echo " where: input - the specified ${CMS} ldif data file,"
+ echo " errors - an optional errors file containing"
+ echo " skipped attributes, and"
+ echo " output - the normalized ${CMS} ldif text file."
+ echo
+ echo " NOTE: If no redirection is provided to"
+ echo " 'output', then the normalized"
+ echo " ${CMS} ldif text will merely"
+ echo " be echoed to stdout."
+ echo
+ exit 1
+fi
+
+
+###
+### Check that the specified "input" file exists and is a regular file.
+###
+
+if [ ! -f $1 ] ; then
+ echo "ERROR: Either the specified 'input' file, '$1', does not exist, "
+ echo " or it is not a regular file!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified "input" file exists and is not empty.
+###
+
+if [ ! -s $1 ] ; then
+ echo "ERROR: The specified 'input' file, '$1', is empty!"
+ echo
+ exit 3
+fi
+
+
+###
+### If an "errors" file is specified, then check that it does not already
+### exist.
+###
+
+if [ $# -eq 2 ] ; then
+ if [ -f $2 ] ; then
+ echo "ERROR: The specified 'errors' file, '$2', already exists!"
+ echo " Please specify a different file!"
+ echo
+ exit 4
+ fi
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${INSTANCE}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and INSTANCE "
+ echo " environment variables for this script!"
+ echo
+ exit 5
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 6
+fi
+
+
+###
+### Check that the specified INSTANCE exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}/cert-${INSTANCE}" ] ; then
+ echo "ERROR: Either the specified INSTANCE does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 7
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Convert the specified ${CMS} ldif data file
+### into a normalized ${CMS} ldif text file.
+###
+
+${SERVER_ROOT}/bin/cert/jre/bin/java -classpath ./classes:${SERVER_ROOT}/cert-${INSTANCE}/classes:${SERVER_ROOT}/bin/cert/classes:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar:${SERVER_ROOT}/bin/cert/jre/lib/rt.jar:${SERVER_ROOT}/bin/cert/jre/lib/i18n.jar Main $1 $2
+
diff --git a/base/migrate/45ToTxt/src/Main.java b/base/migrate/45ToTxt/src/Main.java
new file mode 100644
index 000000000..916ca9cd1
--- /dev/null
+++ b/base/migrate/45ToTxt/src/Main.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 ---
+//
+// "45ToTxt/src/Main.java" is based upon a copy "42SP2ToTxt/src/Main.java".
+//
+// Always comment any new code sections with a "CMS 4.5" header, and
+// apply these changes forward to all other "*ToTxt/src/Main.java" files
+// (including this comment header) so that these differences will only
+// appear when this file is diffed against an earlier "*ToTxt" version.
+//
+// This file should always be maintained by executing the following command:
+//
+// diff 42SP2ToTxt/src/Main.java 45ToTxt/src/Main.java
+//
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+import sun.misc.*;
+import org.mozilla.jss.*; // CMS 4.5 and later
+import org.mozilla.jss.crypto.*; // CMS 4.5 and later
+import netscape.security.util.*;
+
+public class Main
+{
+ public static void main(String args[])
+ {
+ try {
+ // initialize CryptoManager in CMS 4.5 and later
+ CryptoManager.initialize(".");
+ // load JSS provider in CMS 4.5 and later
+ java.security.Security.removeProvider("SUN version 1.2");
+ // The following call to "java.security.Security.insertProviderAt()"
+ // is no longer commented out in CMS 4.5 and later
+ java.security.Security.insertProviderAt(
+ new netscape.security.provider.CMS(), 0);
+ java.security.Provider ps[] =
+ java.security.Security.getProviders();
+ if (ps == null || ps.length <= 0) {
+ System.err.println("Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ System.err.println("Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+
+ // Parse the File
+ CMS45LdifParser parser = null;
+ if (args.length == 1) {
+ parser = new CMS45LdifParser(args[0]);
+ } else if (args.length == 2) {
+ parser = new CMS45LdifParser(args[0], args[1]);
+ } else {
+ throw new IOException("Invalid Parameters");
+ }
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+}
+
+class CMS45LdifParser
+{
+ // constants
+ private static final String DN =
+ "dn:";
+ // Directory Servers in CMS 4.1/4.2/4.2 (SP 2)/4.5 use "requestattributes"
+ private static final String REQUEST_ATTRIBUTES =
+ "requestattributes::";
+ private static final String BEGIN =
+ "--- BEGIN ATTRIBUTES ---";
+ private static final String END =
+ "--- END ATTRIBUTES ---";
+
+ // variables
+ private String mFilename = null;
+ private String mErrorFilename = null;
+ private PrintWriter mErrorPrintWriter = null;
+
+ public CMS45LdifParser(String filename)
+ {
+ mFilename = filename;
+ }
+
+ public CMS45LdifParser(String filename, String errorFilename)
+ {
+ mFilename = filename;
+ mErrorFilename = errorFilename;
+ }
+
+ public void parse() throws Exception
+ {
+ if (mErrorFilename != null) {
+ mErrorPrintWriter = new PrintWriter(new FileOutputStream(mErrorFilename));
+ }
+ BufferedReader reader = new BufferedReader(
+ new FileReader(mFilename));
+ String line = null;
+ String dn = null;
+ StringBuffer requestAttributes = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DN)) {
+ dn = line;
+ }
+ if (line.startsWith(REQUEST_ATTRIBUTES)) {
+ requestAttributes = new StringBuffer();
+ // System.out.println(line);
+ requestAttributes.append(
+ line.substring(REQUEST_ATTRIBUTES.length(),
+ line.length()).trim());
+ continue;
+ }
+ if (requestAttributes == null) {
+ System.out.println(line);
+ continue;
+ }
+ if (line.startsWith(" ")) {
+ // System.out.println(line);
+ requestAttributes.append(line.trim());
+ } else {
+ parseAttributes(dn, requestAttributes);
+ requestAttributes = null;
+ System.out.println(line);
+ }
+ }
+ }
+
+ public void parseAttributes(String dn, StringBuffer attrs) throws Exception
+ {
+ BASE64Decoder decoder = new BASE64Decoder();
+ decodeHashtable(dn, decoder.decodeBuffer(attrs.toString()));
+
+// System.out.println(attrs);
+ }
+
+ public Object decode(byte[] data) throws
+ ObjectStreamException,
+ IOException,
+ ClassNotFoundException
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+ return is.readObject();
+ }
+
+ public void decodeHashtable(String dn, byte[] data) throws Exception
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+
+ System.out.println(BEGIN);
+ String key = null;
+ while (true)
+ {
+ key = (String)is.readObject();
+ // end of table is marked with null
+ if (key == null) break;
+ try {
+ byte[] bytes = (byte[])is.readObject();
+ Object obj = decode(bytes);
+ output(key, obj);
+ } catch (Exception e) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + key);
+ }
+ }
+ }
+ System.out.println(END);
+ }
+
+ public void output(String key, Object obj) throws Exception
+ {
+ if (obj instanceof String) {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ } else if (obj instanceof netscape.security.x509.CertificateX509Key) {
+ netscape.security.x509.CertificateX509Key o =
+ (netscape.security.x509.CertificateX509Key)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateSubjectName) {
+ netscape.security.x509.CertificateSubjectName o =
+ (netscape.security.x509.CertificateSubjectName)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateExtensions) {
+ netscape.security.x509.CertificateExtensions o =
+ (netscape.security.x509.CertificateExtensions)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertInfo) {
+ netscape.security.x509.X509CertInfo o =
+ (netscape.security.x509.X509CertInfo)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl) {
+ netscape.security.x509.X509CertImpl o =
+ (netscape.security.x509.X509CertImpl)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateChain) {
+ netscape.security.x509.CertificateChain o =
+ (netscape.security.x509.CertificateChain)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl[]) {
+ netscape.security.x509.X509CertImpl o[] =
+ (netscape.security.x509.X509CertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.X509CertInfo[]) {
+ netscape.security.x509.X509CertInfo o[] =
+ (netscape.security.x509.X509CertInfo[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() + "["+o.length + "," + i+"]"+"=" +
+ encoder.encodeBuffer(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.RevokedCertImpl[]) {
+ netscape.security.x509.RevokedCertImpl o[] =
+ (netscape.security.x509.RevokedCertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ DerOutputStream bos =
+ new DerOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof java.security.cert.Certificate[]) {
+ java.security.cert.Certificate o[] =
+ (java.security.cert.Certificate[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(o[i].getEncoded()));
+ }
+ } else if (obj instanceof com.netscape.certsrv.base.ArgBlock) {
+ com.netscape.certsrv.base.ArgBlock o =
+ (com.netscape.certsrv.base.ArgBlock)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" +(String)o.get(k));
+ }
+ } else if (obj instanceof com.netscape.certsrv.dbs.keydb.KeyRecord) {
+ com.netscape.certsrv.dbs.keydb.KeyRecord o =
+ (com.netscape.certsrv.dbs.keydb.KeyRecord)obj;
+ Enumeration e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ Object ob = o.get(k);
+ if (ob != null) {
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + encoder.encode((byte[])ob));
+
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ }
+ } else if (obj instanceof com.netscape.certsrv.kra.ProofOfArchival) {
+ com.netscape.certsrv.kra.ProofOfArchival o =
+ (com.netscape.certsrv.kra.ProofOfArchival)obj;
+ DerOutputStream bos =
+ new DerOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof com.netscape.certsrv.request.AgentApprovals) {
+ com.netscape.certsrv.request.AgentApprovals o =
+ (com.netscape.certsrv.request.AgentApprovals)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ com.netscape.certsrv.request.AgentApproval approval = (com.netscape.certsrv.request.AgentApproval)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ approval.getUserName() + ";" + approval.getDate().getTime());
+ }
+ } else if (obj instanceof com.netscape.certsrv.authentication.AuthToken) {
+ com.netscape.certsrv.authentication.AuthToken o =
+ (com.netscape.certsrv.authentication.AuthToken)obj;
+ Enumeration e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ Object ob = o.get(k);
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof java.math.BigInteger[]) {
+ // Bugzilla Bug #225031 (a.k.a. - Raidzilla Bug #58356)
+ java.math.BigInteger in[] = (java.math.BigInteger[])ob;
+ String numbers = "";
+ for (int i = 0; i < in.length; i++) {
+ if (numbers.equals("")) {
+ numbers = in[i].toString();
+ } else {
+ numbers = numbers + "," + in[i].toString();
+ }
+ }
+ System.out.println(" " +
+ key + ":" + "com.netscape.certsrv.authentication.AuthToken" + "=" +
+ k + ":java.lang.String=" + numbers);
+ } else if (ob instanceof String[]) {
+ // Bugzilla Bug #224763 (a.k.a. - Raidzilla Bug #57949)
+ // Bugzilla Bug #252240
+ String str[] = (String[])ob;
+ String v = "";
+ if (str != null) {
+ for (int i = 0; i < str.length; i++) {
+ if (i != 0) {
+ v += ",";
+ }
+ v += str[i];
+ }
+ }
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + "java.lang.String" + "=" + v);
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ } else if (obj instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key + ":byte[]="+
+ encoder.encode((byte[])obj));
+ } else if (obj instanceof Integer[]) {
+ Integer in[] = (Integer[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":Integer[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof BigInteger[]) {
+ // Bugzilla Bug #238779
+ BigInteger in[] = (BigInteger[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":java.math.BigInteger[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof String[]) {
+ // Bugzilla Bug #223360 (a.k.a - Raidzilla Bug #58086)
+ String str[] = (String[])obj;
+ for (int i = 0; i < str.length; i++) {
+ System.out.println(" " + key + ":java.lang.String[" + str.length + "," + i + "]="+ str[i]);
+ }
+ } else if (obj instanceof netscape.security.x509.CertificateAlgorithmId) {
+ netscape.security.x509.CertificateAlgorithmId o =
+ (netscape.security.x509.CertificateAlgorithmId)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateAlgorithmId="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateValidity) {
+ netscape.security.x509.CertificateValidity o =
+ (netscape.security.x509.CertificateValidity)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateValidity="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof java.util.Hashtable) {
+ // Bugzilla Bug #224800 (a.k.a - Raidzilla Bug #56953)
+ //
+ // Example: fingerprints:java.util.Hashtable=
+ // {SHA1=[B@52513a, MD5=[B@52c4d9, MD2=[B@799ff5}
+ //
+ java.util.Hashtable o = (java.util.Hashtable)obj;
+ BASE64Encoder encoder = new BASE64Encoder();
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" + encoder.encode((byte[])o.get(k)));
+ }
+ } else {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ }
+ }
+}
+
diff --git a/base/migrate/45ToTxt/src/compile.bat b/base/migrate/45ToTxt/src/compile.bat
new file mode 100755
index 000000000..11abbf103
--- /dev/null
+++ b/base/migrate/45ToTxt/src/compile.bat
@@ -0,0 +1,152 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script creates the "45ToTxt/classes/Main.class" and
+REM "45ToTxt/classes/CMS45LdifParser.class" which are
+REM used to create a normalized CMS 4.5 ldif text file.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM Set SERVER_ROOT - identify the CMS <server_root> used to compile 45ToTxt
+REM
+
+REM SET SERVER_ROOT=C:\cms45
+
+
+REM
+REM Set JDK_VERSION - specify the JDK version used by this version of CMS
+REM
+REM CMS 4.5 NOTE: "WINNT" - 1.3.0
+REM
+REM CMS 4.5 CONSOLE NOTE: "WINNT" - 1.1.7A
+REM
+
+REM SET JDK_VERSION=CMS_4.5
+
+
+REM
+REM Set JAVA_HOME - specify the complete path to the JDK
+REM
+REM example: \\bermuda.redhat.com\sbc mounted as Y:
+REM
+
+REM SET JAVA_HOME=Y:\cms_jdk\WINNT\%JDK_VERSION%
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 4.5"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0"
+ECHO.
+ECHO NOTE: No arguments are required to build the
+ECHO normalized %CMS% ldif text classes.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%JAVA_HOME%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and JAVA_HOME
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_JAVA_HOME
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified JAVA_HOME exists
+REM
+
+:CHECK_JAVA_HOME
+IF EXIST %JAVA_HOME% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified JAVA_HOME does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%JAVA_HOME%\bin;%JAVA_HOME%\lib;%PATH%
+
+
+REM
+REM Set TARGET - identify the complete path to the new classes target directory
+REM
+
+SET TARGET=..\classes
+
+
+REM
+REM Create the new classes target directory (if it does not already exist)
+REM
+
+IF EXIST %TARGET% goto COMPILE_CLASSES
+MKDIR %TARGET%
+
+
+REM
+REM Compile 45ToTxt - create "CMS45LdifParser.class" and "Main.class"
+REM
+
+:COMPILE_CLASSES
+%JAVA_HOME%\bin\javac.exe -d %TARGET% -classpath %JAVA_HOME%\jre\lib\rt.jar;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar Main.java
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/45ToTxt/src/compile.sh b/base/migrate/45ToTxt/src/compile.sh
new file mode 100755
index 000000000..a08eea1b7
--- /dev/null
+++ b/base/migrate/45ToTxt/src/compile.sh
@@ -0,0 +1,159 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#####################################################################
+### ###
+### This script creates the "45ToTxt/classes/Main.class" and ###
+### "45ToTxt/classes/CMS45LdifParser.class" which are ###
+### used to create a normalized CMS 4.5 ldif text file. ###
+### ###
+#####################################################################
+
+
+###
+### Set SERVER_ROOT - identify the CMS <server_root> used to compile 45ToTxt
+###
+
+#SERVER_ROOT=/export/home/migrate/cms45
+#export SERVER_ROOT
+
+
+###
+### Set JDK_PLATFORM - must be "Linux" or "SunOS"
+###
+
+#JDK_PLATFORM=SunOS
+#export JDK_PLATFORM
+
+
+###
+### Set JDK_VERSION - specify the JDK version used by this version of CMS
+###
+### CMS 4.5 NOTE: "Linux" - 1.3.0
+### "SunOS" - 1.3.0
+###
+### CMS 4.5 CONSOLE NOTE: "Linux" - 1.1.7
+### "SunOS" - 1.1.6
+###
+
+#JDK_VERSION=CMS_4.5
+#export JDK_VERSION
+
+
+###
+### Set JAVA_HOME - specify the complete path to the JDK
+###
+
+#JAVA_HOME=/share/builds/components/cms_jdk/${JDK_PLATFORM}/${JDK_VERSION}
+#export JAVA_HOME
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 4.5"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -gt 0 ] ; then
+ echo
+ echo "Usage: $0"
+ echo
+ echo " NOTE: No arguments are required to build the"
+ echo " normalized ${CMS} ldif text classes."
+ echo
+ exit 1
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${JAVA_HOME}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and JAVA_HOME "
+ echo " environment variables for this script!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 3
+fi
+
+
+###
+### Check that the specified JAVA_HOME exists and is a directory
+###
+
+if [ ! -d "${JAVA_HOME}" ] ; then
+ echo "ERROR: Either the specified JAVA_HOME does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 4
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Set TARGET - identify the complete path to the new classes target directory
+###
+
+TARGET=../classes
+export TARGET
+
+
+###
+### Create the new classes target directory (if it does not already exist)
+###
+
+if [ ! -d ${TARGET} ]; then
+ mkdir -p ${TARGET}
+fi
+
+
+###
+### Compile 45ToTxt - create "CMS45LdifParser.class" and "Main.class"
+###
+
+${JAVA_HOME}/bin/javac -d ${TARGET} -classpath ${JAVA_HOME}/jre/lib/rt.jar:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar Main.java
+
diff --git a/base/migrate/47ToTxt/classes/CMS47LdifParser.class b/base/migrate/47ToTxt/classes/CMS47LdifParser.class
new file mode 100644
index 000000000..79d1bc12d
--- /dev/null
+++ b/base/migrate/47ToTxt/classes/CMS47LdifParser.class
Binary files differ
diff --git a/base/migrate/47ToTxt/classes/Main.class b/base/migrate/47ToTxt/classes/Main.class
new file mode 100644
index 000000000..7ee99ee96
--- /dev/null
+++ b/base/migrate/47ToTxt/classes/Main.class
Binary files differ
diff --git a/base/migrate/47ToTxt/run.bat b/base/migrate/47ToTxt/run.bat
new file mode 100755
index 000000000..e658ab410
--- /dev/null
+++ b/base/migrate/47ToTxt/run.bat
@@ -0,0 +1,192 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM This program is free software; you can redistribute it and/or modify
+REM it under the terms of the GNU General Public License as published by
+REM the Free Software Foundation; version 2 of the License.
+REM
+REM This program is distributed in the hope that it will be useful,
+REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+REM GNU General Public License for more details.
+REM
+REM You should have received a copy of the GNU General Public License along
+REM with this program; if not, write to the Free Software Foundation, Inc.,
+REM 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script converts a pre-existing CMS 4.7 ldif data
+REM file (e. g. - created via a utility such as db2ldif)
+REM into a normalized CMS 4.7 ldif text file.
+REM
+REM This subsequent normalized CMS 4.7 ldif text file
+REM can be migrated into CMS 6.0 or later utilizing
+REM the corresponding TxtTo<Target CMS Version> script which
+REM converts this normalized CMS 4.7 ldif text file into
+REM a <Target CMS Version> ldif data file.
+REM
+REM This <Target CMS Version> ldif data file can then be
+REM imported into the internal database of the desired CMS
+REM server using a utility such as ldif2db.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM SERVER_ROOT - fully qualified path of the location of the server
+REM
+
+REM SET SERVER_ROOT=C:\cms47
+
+
+REM
+REM INSTANCE - if the CMS instance directory is called 'cert-ca',
+REM set the CMS instance to 'ca'
+REM
+REM NOTE: When a single SERVER_ROOT contains more than
+REM one CMS instance, this script must be run multiple
+REM times. To do this, there is only a need to change
+REM the INSTANCE parameter.
+REM
+
+REM SET INSTANCE=ca
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 4.7"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO USAGE
+IF "%3" == "" GOTO CHECK_INPUT_FILE
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0 input [errors] > output"
+ECHO.
+ECHO where: input - the specified %CMS% ldif data file,
+ECHO errors - an optional errors file containing
+ECHO skipped attributes, and
+ECHO output - the normalized %CMS% ldif text file.
+ECHO.
+ECHO NOTE: If no redirection is provided to
+ECHO 'output', then the normalized
+ECHO %CMS% ldif text will merely
+ECHO be echoed to stdout.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified "input" file exists
+REM
+
+:CHECK_INPUT_FILE
+IF EXIST %1 GOTO CHECK_ERRORS_FILE
+
+
+ECHO ERROR: The specified input file, %1, does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM If an "errors" file is specified, then check that it does not already
+REM exist.
+REM
+
+:CHECK_ERRORS_FILE
+IF "%2" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+IF EXIST %2 GOTO ERRORS_FILE_ERROR
+GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:ERRORS_FILE_ERROR
+ECHO ERROR: The specified errors file, %2, already exists!
+ECHO Please specify a different file!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%INSTANCE%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and INSTANCE
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_INSTANCE
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified INSTANCE exists
+REM
+
+:CHECK_INSTANCE
+IF EXIST %SERVER_ROOT%\cert-%INSTANCE% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified INSTANCE does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%SERVER_ROOT%\bin\cert\jre\bin;%SERVER_ROOT\bin\cert\jre\bin\hotspot;%PATH%
+
+
+REM
+REM Convert the specified %CMS% ldif data file
+REM into a normalized %CMS% ldif text file.
+REM
+
+%SERVER_ROOT%\bin\cert\jre\bin\java.exe -classpath .\classes;%SERVER_ROOT%\cert-%INSTANCE%\classes;%SERVER_ROOT%\bin\cert\classes;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar;%SERVER_ROOT%\bin\cert\jre\lib\rt.jar Main %1 %2
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/47ToTxt/run.sh b/base/migrate/47ToTxt/run.sh
new file mode 100755
index 000000000..35a41bc90
--- /dev/null
+++ b/base/migrate/47ToTxt/run.sh
@@ -0,0 +1,205 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+
+#####################################################################
+### ###
+### This script converts a pre-existing CMS 4.7 ldif data ###
+### file (e. g. - created via a utility such as db2ldif) ###
+### into a normalized CMS 4.7 ldif text file. ###
+### ###
+### This subsequent normalized CMS 4.7 ldif text file ###
+### can be migrated into CMS 6.0 or later utilizing ###
+### the corresponding TxtTo<Target CMS Version> script which ###
+### converts this normalized CMS 4.7 ldif text file into ###
+### a <Target CMS Version> ldif data file. ###
+### ###
+### This <Target CMS Version> ldif data file can then be ###
+### imported into the internal database of the desired CMS ###
+### server using a utility such as ldif2db. ###
+### ###
+#####################################################################
+
+
+###
+### SERVER_ROOT - fully qualified path of the location of the server
+###
+
+#SERVER_ROOT=/export/home/migrate/cms47
+#export SERVER_ROOT
+
+
+###
+### INSTANCE - if the CMS instance directory is called 'cert-ca',
+### set the CMS instance to 'ca'
+###
+### NOTE: When a single SERVER_ROOT contains more than
+### one CMS instance, this script must be run multiple
+### times. To do this, there is only a need to change
+### the INSTANCE parameter.
+###
+
+#INSTANCE=ca
+#export INSTANCE
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 4.7"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+##
+## Perform a usage check for the appropriate number of arguments:
+##
+
+if [ $# -lt 1 -o $# -gt 2 ] ; then
+ echo
+ echo "Usage: $0 input [errors] > output"
+ echo
+ echo " where: input - the specified ${CMS} ldif data file,"
+ echo " errors - an optional errors file containing"
+ echo " skipped attributes, and"
+ echo " output - the normalized ${CMS} ldif text file."
+ echo
+ echo " NOTE: If no redirection is provided to"
+ echo " 'output', then the normalized"
+ echo " ${CMS} ldif text will merely"
+ echo " be echoed to stdout."
+ echo
+ exit 1
+fi
+
+
+###
+### Check that the specified "input" file exists and is a regular file.
+###
+
+if [ ! -f $1 ] ; then
+ echo "ERROR: Either the specified 'input' file, '$1', does not exist, "
+ echo " or it is not a regular file!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified "input" file exists and is not empty.
+###
+
+if [ ! -s $1 ] ; then
+ echo "ERROR: The specified 'input' file, '$1', is empty!"
+ echo
+ exit 3
+fi
+
+
+###
+### If an "errors" file is specified, then check that it does not already
+### exist.
+###
+
+if [ $# -eq 2 ] ; then
+ if [ -f $2 ] ; then
+ echo "ERROR: The specified 'errors' file, '$2', already exists!"
+ echo " Please specify a different file!"
+ echo
+ exit 4
+ fi
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${INSTANCE}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and INSTANCE "
+ echo " environment variables for this script!"
+ echo
+ exit 5
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 6
+fi
+
+
+###
+### Check that the specified INSTANCE exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}/cert-${INSTANCE}" ] ; then
+ echo "ERROR: Either the specified INSTANCE does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 7
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "AIX" ] ; then
+ LIBPATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/aix/native_threads
+ export LIBPATH
+elif [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+elif [ ${OS_NAME} = "OSF1" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/alpha/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Convert the specified ${CMS} ldif data file
+### into a normalized ${CMS} ldif text file.
+###
+
+${SERVER_ROOT}/bin/cert/jre/bin/java -classpath ./classes:${SERVER_ROOT}/cert-${INSTANCE}/classes:${SERVER_ROOT}/bin/cert/classes:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar:${SERVER_ROOT}/bin/cert/jre/lib/rt.jar:${SERVER_ROOT}/bin/cert/jre/lib/i18n.jar Main $1 $2
+
diff --git a/base/migrate/47ToTxt/src/Main.java b/base/migrate/47ToTxt/src/Main.java
new file mode 100644
index 000000000..194c277f1
--- /dev/null
+++ b/base/migrate/47ToTxt/src/Main.java
@@ -0,0 +1,578 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+//
+// "47ToTxt/src/Main.java" is based upon a copy "42SP2ToTxt/src/Main.java"
+// with additional material provided from "45ToTxt/src/Main.java".
+//
+// Always comment any new code sections with a "CMS 4.7" header, and
+// apply these changes forward to all other "*ToTxt/src/Main.java" files
+// (including this comment header) so that these differences will only
+// appear when this file is diffed against an earlier "*ToTxt" version.
+//
+// This file should always be maintained by executing the following commands:
+//
+// diff 42SP2ToTxt/src/Main.java 47ToTxt/src/Main.java
+// diff 45ToTxt/src/Main.java 47ToTxt/src/Main.java
+//
+// NOTE: The "47ToTxt/src/Main.java" file will differ substantially
+// from the "42SP2ToTxt/src/Main.java" and "45ToTxt/src/Main.java"
+// files upon which it was based due to the changes that were
+// necessary to change "iplanet" to "netscape".
+//
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+import sun.misc.*;
+import org.mozilla.jss.*; // CMS 4.5 and later
+import org.mozilla.jss.crypto.*; // CMS 4.5 and later
+import iplanet.security.util.*;
+
+public class Main
+{
+ public static void main(String args[])
+ {
+ try {
+ // initialize CryptoManager in CMS 4.5 and later
+ CryptoManager.initialize(".");
+ // load JSS provider in CMS 4.5 and later
+ java.security.Security.removeProvider("SUN version 1.2");
+ // The following call to "java.security.Security.insertProviderAt()"
+ // is no longer commented out in CMS 4.5 and later
+ java.security.Security.insertProviderAt(
+ new iplanet.security.provider.CMS(), 0);
+ java.security.Provider ps[] =
+ java.security.Security.getProviders();
+ if (ps == null || ps.length <= 0) {
+ System.err.println("Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ System.err.println("Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+
+ // Parse the File
+ CMS47LdifParser parser = null;
+ if (args.length == 1) {
+ parser = new CMS47LdifParser(args[0]);
+ } else if (args.length == 2) {
+ parser = new CMS47LdifParser(args[0], args[1]);
+ } else {
+ throw new IOException("Invalid Parameters");
+ }
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+}
+
+class CMS47LdifParser
+{
+ // constants
+ private static final String DN =
+ "dn:";
+ // Directory Servers in CMS 4.7 and later use "requestAttributes"
+ private static final String REQUEST_ATTRIBUTES =
+ "requestAttributes::";
+ private static final String BEGIN =
+ "--- BEGIN ATTRIBUTES ---";
+ private static final String END =
+ "--- END ATTRIBUTES ---";
+
+ // variables
+ private String mFilename = null;
+ private String mErrorFilename = null;
+ private PrintWriter mErrorPrintWriter = null;
+
+ public CMS47LdifParser(String filename)
+ {
+ mFilename = filename;
+ }
+
+ public CMS47LdifParser(String filename, String errorFilename)
+ {
+ mFilename = filename;
+ mErrorFilename = errorFilename;
+ }
+
+ public void parse() throws Exception
+ {
+ if (mErrorFilename != null) {
+ mErrorPrintWriter = new PrintWriter(new FileOutputStream(mErrorFilename));
+ }
+ BufferedReader reader = new BufferedReader(
+ new FileReader(mFilename));
+ String line = null;
+ String dn = null;
+ StringBuffer requestAttributes = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DN)) {
+ dn = line;
+ }
+ if (line.startsWith(REQUEST_ATTRIBUTES)) {
+ requestAttributes = new StringBuffer();
+ // System.out.println(line);
+ requestAttributes.append(
+ line.substring(REQUEST_ATTRIBUTES.length(),
+ line.length()).trim());
+ continue;
+ }
+ if (requestAttributes == null) {
+ System.out.println(line);
+ continue;
+ }
+ if (line.startsWith(" ")) {
+ // System.out.println(line);
+ requestAttributes.append(line.trim());
+ } else {
+ parseAttributes(dn, requestAttributes);
+ requestAttributes = null;
+ System.out.println(line);
+ }
+ }
+ }
+
+ public void parseAttributes(String dn, StringBuffer attrs) throws Exception
+ {
+ BASE64Decoder decoder = new BASE64Decoder();
+ decodeHashtable(dn, decoder.decodeBuffer(attrs.toString()));
+
+// System.out.println(attrs);
+ }
+
+ public Object decode(byte[] data) throws
+ ObjectStreamException,
+ IOException,
+ ClassNotFoundException
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+ return is.readObject();
+ }
+
+ public void decodeHashtable(String dn, byte[] data) throws Exception
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+
+ System.out.println(BEGIN);
+ String key = null;
+ while (true)
+ {
+ key = (String)is.readObject();
+ // end of table is marked with null
+ if (key == null) break;
+ try {
+ byte[] bytes = (byte[])is.readObject();
+ Object obj = decode(bytes);
+ output(key, obj);
+ } catch (Exception e) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + key);
+ }
+ }
+ }
+ System.out.println(END);
+ }
+
+ public void output(String key, Object obj) throws Exception
+ {
+ String data_type = null;
+ String translation = null;
+ if (obj instanceof String) {
+ data_type = obj.getClass().getName();
+ if( data_type.startsWith( "iplanet" ) ) {
+ translation = "netscape"
+ + data_type.substring( 7 );
+ } else if( data_type.startsWith( "com.iplanet" ) ) {
+ translation = "com.netscape"
+ + data_type.substring( 11 );
+ } else {
+ translation = data_type;
+ }
+ System.out.println(" " +
+ key + ":" + translation + "=" +
+ obj);
+ } else if (obj instanceof iplanet.security.x509.CertificateX509Key) {
+ iplanet.security.x509.CertificateX509Key o =
+ (iplanet.security.x509.CertificateX509Key)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + "netscape.security.x509.CertificateX509Key" + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof iplanet.security.x509.CertificateSubjectName) {
+ iplanet.security.x509.CertificateSubjectName o =
+ (iplanet.security.x509.CertificateSubjectName)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + "netscape.security.x509.CertificateSubjectName" + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof iplanet.security.x509.CertificateExtensions) {
+ iplanet.security.x509.CertificateExtensions o =
+ (iplanet.security.x509.CertificateExtensions)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + "netscape.security.x509.CertificateExtensions" + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof iplanet.security.x509.X509CertInfo) {
+ iplanet.security.x509.X509CertInfo o =
+ (iplanet.security.x509.X509CertInfo)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + "netscape.security.x509.X509CertInfo" + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof iplanet.security.x509.X509CertImpl) {
+ iplanet.security.x509.X509CertImpl o =
+ (iplanet.security.x509.X509CertImpl)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + "netscape.security.x509.X509CertImpl" + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof iplanet.security.x509.CertificateChain) {
+ iplanet.security.x509.CertificateChain o =
+ (iplanet.security.x509.CertificateChain)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + "netscape.security.x509.CertificateChain" + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof iplanet.security.x509.X509CertImpl[]) {
+ iplanet.security.x509.X509CertImpl o[] =
+ (iplanet.security.x509.X509CertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + "netscape.security.x509.X509CertImpl" +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof iplanet.security.x509.X509CertInfo[]) {
+ iplanet.security.x509.X509CertInfo o[] =
+ (iplanet.security.x509.X509CertInfo[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + "netscape.security.x509.X509CertInfo" + "["+o.length + "," + i+"]"+"=" +
+ encoder.encodeBuffer(bos.toByteArray()));
+ }
+ } else if (obj instanceof iplanet.security.x509.RevokedCertImpl[]) {
+ iplanet.security.x509.RevokedCertImpl o[] =
+ (iplanet.security.x509.RevokedCertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ DerOutputStream bos =
+ new DerOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + "netscape.security.x509.RevokedCertImpl" +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof java.security.cert.Certificate[]) {
+ java.security.cert.Certificate o[] =
+ (java.security.cert.Certificate[])obj;
+ for (int i = 0; i < o.length; i++) {
+ data_type = o[i].getClass().getName();
+ if( data_type.startsWith( "iplanet" ) ) {
+ translation = "netscape"
+ + data_type.substring( 7 );
+ } else if( data_type.startsWith( "com.iplanet" ) ) {
+ translation = "com.netscape"
+ + data_type.substring( 11 );
+ } else {
+ translation = data_type;
+ }
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + translation +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(o[i].getEncoded()));
+ }
+ } else if (obj instanceof com.iplanet.certsrv.base.ArgBlock) {
+ com.iplanet.certsrv.base.ArgBlock o =
+ (com.iplanet.certsrv.base.ArgBlock)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + "com.netscape.certsrv.base.ArgBlock" + "=" +
+ k + "=" +(String)o.get(k));
+ }
+ } else if (obj instanceof com.iplanet.certsrv.dbs.keydb.KeyRecord) {
+ com.iplanet.certsrv.dbs.keydb.KeyRecord o =
+ (com.iplanet.certsrv.dbs.keydb.KeyRecord)obj;
+ Enumeration e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ Object ob = o.get(k);
+ if (ob != null) {
+ if (ob instanceof java.util.Date) {
+ data_type = ob.getClass().getName();
+ if( data_type.startsWith( "iplanet" ) ) {
+ translation = "netscape"
+ + data_type.substring( 7 );
+ } else if( data_type.startsWith( "com.iplanet" ) ) {
+ translation = "com.netscape"
+ + data_type.substring( 11 );
+ } else {
+ translation = data_type;
+ }
+ System.out.println(" " +
+ key + ":" + "com.netscape.certsrv.dbs.keydb.KeyRecord" + "=" +
+ k + ":" + translation + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof byte[]) {
+ data_type = ob.getClass().getName();
+ if( data_type.startsWith( "iplanet" ) ) {
+ translation = "netscape"
+ + data_type.substring( 7 );
+ } else if( data_type.startsWith( "com.iplanet" ) ) {
+ translation = "com.netscape"
+ + data_type.substring( 11 );
+ } else {
+ translation = data_type;
+ }
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + "com.netscape.certsrv.dbs.keydb.KeyRecord" + "=" +
+ k + ":" + translation + "=" + encoder.encode((byte[])ob));
+
+ } else {
+ data_type = ob.getClass().getName();
+ if( data_type.startsWith( "iplanet" ) ) {
+ translation = "netscape"
+ + data_type.substring( 7 );
+ } else if( data_type.startsWith( "com.iplanet" ) ) {
+ translation = "com.netscape"
+ + data_type.substring( 11 );
+ } else {
+ translation = data_type;
+ }
+ System.out.println(" " +
+ key + ":" + "com.netscape.certsrv.dbs.keydb.KeyRecord" + "=" +
+ k + ":" + translation + "=" + ob);
+ }
+ }
+ }
+ } else if (obj instanceof com.iplanet.certsrv.kra.ProofOfArchival) {
+ com.iplanet.certsrv.kra.ProofOfArchival o =
+ (com.iplanet.certsrv.kra.ProofOfArchival)obj;
+ DerOutputStream bos =
+ new DerOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + "com.netscape.certsrv.kra.ProofOfArchival" + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof com.iplanet.certsrv.request.AgentApprovals) {
+ com.iplanet.certsrv.request.AgentApprovals o =
+ (com.iplanet.certsrv.request.AgentApprovals)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ com.iplanet.certsrv.request.AgentApproval approval = (com.iplanet.certsrv.request.AgentApproval)e.nextElement();
+ System.out.println(" " +
+ "com.netscape.certsrv.request.AgentApprovals" + ":" + "com.netscape.certsrv.request.AgentApprovals" + "=" +
+ approval.getUserName() + ";" + approval.getDate().getTime());
+ }
+ } else if (obj instanceof com.iplanet.certsrv.authentication.AuthToken) {
+ com.iplanet.certsrv.authentication.AuthToken o =
+ (com.iplanet.certsrv.authentication.AuthToken)obj;
+ Enumeration e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ Object ob = o.get(k);
+ if (ob instanceof java.util.Date) {
+ data_type = ob.getClass().getName();
+ if( data_type.startsWith( "iplanet" ) ) {
+ translation = "netscape"
+ + data_type.substring( 7 );
+ } else if( data_type.startsWith( "com.iplanet" ) ) {
+ translation = "com.netscape"
+ + data_type.substring( 11 );
+ } else {
+ translation = data_type;
+ }
+ System.out.println(" " +
+ key + ":" + "com.netscape.certsrv.authentication.AuthToken" + "=" +
+ k + ":" + translation + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof java.math.BigInteger[]) {
+ // Bugzilla Bug #225031 (a.k.a. - Raidzilla Bug #58356)
+ java.math.BigInteger in[] = (java.math.BigInteger[])ob;
+ String numbers = "";
+ for (int i = 0; i < in.length; i++) {
+ if (numbers.equals("")) {
+ numbers = in[i].toString();
+ } else {
+ numbers = numbers + "," + in[i].toString();
+ }
+ }
+ System.out.println(" " +
+ key + ":" + "com.netscape.certsrv.authentication.AuthToken" + "=" +
+ k + ":java.lang.String=" + numbers);
+ } else if (ob instanceof String[]) {
+ // Bugzilla Bug #224763 (a.k.a. - Raidzilla Bug #57949)
+ // Bugzilla Bug #252240
+ data_type = o.getClass().getName();
+ if( data_type.startsWith( "iplanet" ) ) {
+ translation = "netscape"
+ + data_type.substring( 7 );
+ } else if( data_type.startsWith( "com.iplanet" ) ) {
+ translation = "com.netscape"
+ + data_type.substring( 11 );
+ } else {
+ translation = data_type;
+ }
+ String str[] = (String[])ob;
+ String v = "";
+ if (str != null) {
+ for (int i = 0; i < str.length; i++) {
+ if (i != 0) {
+ v += ",";
+ }
+ v += str[i];
+ }
+ }
+ System.out.println(" " +
+ key + ":" + translation + "=" +
+ k + ":" + "java.lang.String" + "=" + v);
+ } else {
+ data_type = ob.getClass().getName();
+ if( data_type.startsWith( "iplanet" ) ) {
+ translation = "netscape"
+ + data_type.substring( 7 );
+ } else if( data_type.startsWith( "com.iplanet" ) ) {
+ translation = "com.netscape"
+ + data_type.substring( 11 );
+ } else {
+ translation = data_type;
+ }
+ System.out.println(" " +
+ key + ":" + "com.netscape.certsrv.authentication.AuthToken" + "=" +
+ k + ":" + translation + "=" + ob);
+ }
+ }
+ } else if (obj instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key + ":byte[]="+
+ encoder.encode((byte[])obj));
+ } else if (obj instanceof Integer[]) {
+ Integer in[] = (Integer[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":Integer[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof BigInteger[]) {
+ // Bugzilla Bug #238779
+ BigInteger in[] = (BigInteger[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":java.math.BigInteger[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof String[]) {
+ // Bugzilla Bug #223360 (a.k.a - Raidzilla Bug #58086)
+ String str[] = (String[])obj;
+ for (int i = 0; i < str.length; i++) {
+ System.out.println(" " + key + ":java.lang.String[" + str.length + "," + i + "]="+ str[i]);
+ }
+ } else if (obj instanceof iplanet.security.x509.CertificateAlgorithmId) {
+ iplanet.security.x509.CertificateAlgorithmId o =
+ (iplanet.security.x509.CertificateAlgorithmId)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateAlgorithmId="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof iplanet.security.x509.CertificateValidity) {
+ iplanet.security.x509.CertificateValidity o =
+ (iplanet.security.x509.CertificateValidity)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateValidity="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof java.util.Hashtable) {
+ // Bugzilla Bug #224800 (a.k.a - Raidzilla Bug #56953)
+ //
+ // Example: fingerprints:java.util.Hashtable=
+ // {SHA1=[B@52513a, MD5=[B@52c4d9, MD2=[B@799ff5}
+ //
+ java.util.Hashtable o = (java.util.Hashtable)obj;
+ data_type = o.getClass().getName();
+ if( data_type.startsWith( "iplanet" ) ) {
+ translation = "netscape"
+ + data_type.substring( 7 );
+ } else if( data_type.startsWith( "com.iplanet" ) ) {
+ translation = "com.netscape"
+ + data_type.substring( 11 );
+ } else {
+ translation = data_type;
+ }
+ BASE64Encoder encoder = new BASE64Encoder();
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + translation + "=" +
+ k + "=" + encoder.encode((byte[])o.get(k)));
+ }
+ } else {
+ data_type = obj.getClass().getName();
+ if( data_type.startsWith( "iplanet" ) ) {
+ translation = "netscape"
+ + data_type.substring( 7 );
+ } else if( data_type.startsWith( "com.iplanet" ) ) {
+ translation = "com.netscape"
+ + data_type.substring( 11 );
+ } else {
+ translation = data_type;
+ }
+ System.out.println(" " +
+ key + ":" + translation + "=" +
+ obj);
+ }
+ }
+}
+
diff --git a/base/migrate/47ToTxt/src/compile.bat b/base/migrate/47ToTxt/src/compile.bat
new file mode 100755
index 000000000..553beca5c
--- /dev/null
+++ b/base/migrate/47ToTxt/src/compile.bat
@@ -0,0 +1,152 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script creates the "47ToTxt/classes/Main.class" and
+REM "47ToTxt/classes/CMS47LdifParser.class" which are
+REM used to create a normalized CMS 4.7 ldif text file.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM Set SERVER_ROOT - identify the CMS <server_root> used to compile 47ToTxt
+REM
+
+REM SET SERVER_ROOT=C:\cms47
+
+
+REM
+REM Set JDK_VERSION - specify the JDK version used by this version of CMS
+REM
+REM CMS 4.7 NOTE: "WINNT" - 1.3.0
+REM
+REM CMS 4.7 CONSOLE NOTE: "WINNT" - 1.1.7A
+REM
+
+REM SET JDK_VERSION=CMS_4.7
+
+
+REM
+REM Set JAVA_HOME - specify the complete path to the JDK
+REM
+REM example: \\bermuda.redhat.com\sbc mounted as Y:
+REM
+
+REM SET JAVA_HOME=Y:\cms_jdk\WINNT\%JDK_VERSION%
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 4.7"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0"
+ECHO.
+ECHO NOTE: No arguments are required to build the
+ECHO normalized %CMS% ldif text classes.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%JAVA_HOME%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and JAVA_HOME
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_JAVA_HOME
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified JAVA_HOME exists
+REM
+
+:CHECK_JAVA_HOME
+IF EXIST %JAVA_HOME% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified JAVA_HOME does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%JAVA_HOME%\bin;%JAVA_HOME%\lib;%PATH%
+
+
+REM
+REM Set TARGET - identify the complete path to the new classes target directory
+REM
+
+SET TARGET=..\classes
+
+
+REM
+REM Create the new classes target directory (if it does not already exist)
+REM
+
+IF EXIST %TARGET% goto COMPILE_CLASSES
+MKDIR %TARGET%
+
+
+REM
+REM Compile 47ToTxt - create "CMS47LdifParser.class" and "Main.class"
+REM
+
+:COMPILE_CLASSES
+%JAVA_HOME%\bin\javac.exe -d %TARGET% -classpath %JAVA_HOME%\jre\lib\rt.jar;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar Main.java
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/47ToTxt/src/compile.sh b/base/migrate/47ToTxt/src/compile.sh
new file mode 100755
index 000000000..8d91b4491
--- /dev/null
+++ b/base/migrate/47ToTxt/src/compile.sh
@@ -0,0 +1,174 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#####################################################################
+### ###
+### This script creates the "47ToTxt/classes/Main.class" and ###
+### "47ToTxt/classes/CMS47LdifParser.class" which are ###
+### used to create a normalized CMS 4.7 ldif text file. ###
+### ###
+#####################################################################
+
+
+###
+### Set SERVER_ROOT - identify the CMS <server_root> used to compile 47ToTxt
+###
+
+#SERVER_ROOT=/export/home/migrate/cms47
+#export SERVER_ROOT
+
+
+###
+### Set JDK_PLATFORM - must be "AIX", "HP-UX", "Linux", "OSF1", or "SunOS"
+###
+
+#JDK_PLATFORM=SunOS
+#export JDK_PLATFORM
+
+
+###
+### Set JDK_VERSION - specify the JDK version used by this version of CMS
+###
+### CMS 4.7 NOTE: "AIX" - 1.3.0
+### "HP-UX" - 1.3.0.00
+### "Linux" - 1.3.0
+### "OSF1" - 1.3.0-1
+### "SunOS" - 1.3.0
+###
+### CMS 4.7 CONSOLE NOTE: "AIX" - 1.1.6_10
+### "HP-UX" - 1.1.6
+### "Linux" - 1.1.7
+### "OSF1" - 1.1.6
+### "SunOS" - 1.1.6
+###
+
+#JDK_VERSION=CMS_4.7
+#export JDK_VERSION
+
+
+###
+### Set JAVA_HOME - specify the complete path to the JDK
+###
+
+#JAVA_HOME=/share/builds/components/cms_jdk/${JDK_PLATFORM}/${JDK_VERSION}
+#export JAVA_HOME
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 4.7"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -gt 0 ] ; then
+ echo
+ echo "Usage: $0"
+ echo
+ echo " NOTE: No arguments are required to build the"
+ echo " normalized ${CMS} ldif text classes."
+ echo
+ exit 1
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${JAVA_HOME}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and JAVA_HOME "
+ echo " environment variables for this script!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 3
+fi
+
+
+###
+### Check that the specified JAVA_HOME exists and is a directory
+###
+
+if [ ! -d "${JAVA_HOME}" ] ; then
+ echo "ERROR: Either the specified JAVA_HOME does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 4
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "AIX" ] ; then
+ LIBPATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/aix/native_threads
+ export LIBPATH
+elif [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+elif [ ${OS_NAME} = "OSF1" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/alpha/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Set TARGET - identify the complete path to the new classes target directory
+###
+
+TARGET=../classes
+export TARGET
+
+
+###
+### Create the new classes target directory (if it does not already exist)
+###
+
+if [ ! -d ${TARGET} ]; then
+ mkdir -p ${TARGET}
+fi
+
+
+###
+### Compile 47ToTxt - create "CMS47LdifParser.class" and "Main.class"
+###
+
+${JAVA_HOME}/bin/javac -d ${TARGET} -classpath ${JAVA_HOME}/jre/lib/rt.jar:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar Main.java
+
diff --git a/base/migrate/60ToTxt/classes/CMS60LdifParser.class b/base/migrate/60ToTxt/classes/CMS60LdifParser.class
new file mode 100644
index 000000000..f3ff43045
--- /dev/null
+++ b/base/migrate/60ToTxt/classes/CMS60LdifParser.class
Binary files differ
diff --git a/base/migrate/60ToTxt/classes/Main.class b/base/migrate/60ToTxt/classes/Main.class
new file mode 100644
index 000000000..6d0d3dcd3
--- /dev/null
+++ b/base/migrate/60ToTxt/classes/Main.class
Binary files differ
diff --git a/base/migrate/60ToTxt/run.bat b/base/migrate/60ToTxt/run.bat
new file mode 100755
index 000000000..cc24fd214
--- /dev/null
+++ b/base/migrate/60ToTxt/run.bat
@@ -0,0 +1,192 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM This program is free software; you can redistribute it and/or modify
+REM it under the terms of the GNU General Public License as published by
+REM the Free Software Foundation; version 2 of the License.
+REM
+REM This program is distributed in the hope that it will be useful,
+REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+REM GNU General Public License for more details.
+REM
+REM You should have received a copy of the GNU General Public License along
+REM with this program; if not, write to the Free Software Foundation, Inc.,
+REM 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script converts a pre-existing CMS 6.0/6.01 ldif data
+REM file (e. g. - created via a utility such as db2ldif)
+REM into a normalized CMS 6.0/6.01 ldif text file.
+REM
+REM This subsequent normalized CMS 6.0/6.01 ldif text file
+REM can be migrated into CMS 6.0/6.01 or later utilizing
+REM the corresponding TxtTo<Target CMS Version> script which
+REM converts this normalized CMS 6.0/6.01 ldif text file into
+REM a <Target CMS Version> ldif data file.
+REM
+REM This <Target CMS Version> ldif data file can then be
+REM imported into the internal database of the desired CMS
+REM server using a utility such as ldif2db.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM SERVER_ROOT - fully qualified path of the location of the server
+REM
+
+REM SET SERVER_ROOT=C:\cms601
+
+
+REM
+REM INSTANCE - if the CMS instance directory is called 'cert-ca',
+REM set the CMS instance to 'ca'
+REM
+REM NOTE: When a single SERVER_ROOT contains more than
+REM one CMS instance, this script must be run multiple
+REM times. To do this, there is only a need to change
+REM the INSTANCE parameter.
+REM
+
+REM SET INSTANCE=ca
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 6.0"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO USAGE
+IF "%3" == "" GOTO CHECK_INPUT_FILE
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0 input [errors] > output"
+ECHO.
+ECHO where: input - the specified %CMS% ldif data file,
+ECHO errors - an optional errors file containing
+ECHO skipped attributes, and
+ECHO output - the normalized %CMS% ldif text file.
+ECHO.
+ECHO NOTE: If no redirection is provided to
+ECHO 'output', then the normalized
+ECHO %CMS% ldif text will merely
+ECHO be echoed to stdout.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified "input" file exists
+REM
+
+:CHECK_INPUT_FILE
+IF EXIST %1 GOTO CHECK_ERRORS_FILE
+
+
+ECHO ERROR: The specified input file, %1, does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM If an "errors" file is specified, then check that it does not already
+REM exist.
+REM
+
+:CHECK_ERRORS_FILE
+IF "%2" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+IF EXIST %2 GOTO ERRORS_FILE_ERROR
+GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:ERRORS_FILE_ERROR
+ECHO ERROR: The specified errors file, %2, already exists!
+ECHO Please specify a different file!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%INSTANCE%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and INSTANCE
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_INSTANCE
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified INSTANCE exists
+REM
+
+:CHECK_INSTANCE
+IF EXIST %SERVER_ROOT%\cert-%INSTANCE% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified INSTANCE does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%SERVER_ROOT%\bin\cert\jre\bin;%SERVER_ROOT\bin\cert\jre\bin\hotspot;%PATH%
+
+
+REM
+REM Convert the specified %CMS% ldif data file
+REM into a normalized %CMS% ldif text file.
+REM
+
+%SERVER_ROOT%\bin\cert\jre\bin\java.exe -classpath .\classes;%SERVER_ROOT%\cert-%INSTANCE%\classes;%SERVER_ROOT%\bin\cert\classes;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar;%SERVER_ROOT%\bin\cert\jre\lib\rt.jar Main %1 %2
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/60ToTxt/run.sh b/base/migrate/60ToTxt/run.sh
new file mode 100755
index 000000000..d41d65294
--- /dev/null
+++ b/base/migrate/60ToTxt/run.sh
@@ -0,0 +1,199 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+
+#####################################################################
+### ###
+### This script converts a pre-existing CMS 6.0/6.01 ldif data ###
+### file (e. g. - created via a utility such as db2ldif) ###
+### into a normalized CMS 6.0/6.01 ldif text file. ###
+### ###
+### This subsequent normalized CMS 6.0/6.01 ldif text file ###
+### can be migrated into CMS 6.0/6.01 or later utilizing ###
+### the corresponding TxtTo<Target CMS Version> script which ###
+### converts this normalized CMS 6.0/6.01 ldif text file into ###
+### a <Target CMS Version> ldif data file. ###
+### ###
+### This <Target CMS Version> ldif data file can then be ###
+### imported into the internal database of the desired CMS ###
+### server using a utility such as ldif2db. ###
+### ###
+#####################################################################
+
+
+###
+### SERVER_ROOT - fully qualified path of the location of the server
+###
+
+#SERVER_ROOT=/export/home/migrate/cms601
+#export SERVER_ROOT
+
+
+###
+### INSTANCE - if the CMS instance directory is called 'cert-ca',
+### set the CMS instance to 'ca'
+###
+### NOTE: When a single SERVER_ROOT contains more than
+### one CMS instance, this script must be run multiple
+### times. To do this, there is only a need to change
+### the INSTANCE parameter.
+###
+
+#INSTANCE=ca
+#export INSTANCE
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 6.0"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -lt 1 -o $# -gt 2 ] ; then
+ echo
+ echo "Usage: $0 input [errors] > output"
+ echo
+ echo " where: input - the specified ${CMS} ldif data file,"
+ echo " errors - an optional errors file containing"
+ echo " skipped attributes, and"
+ echo " output - the normalized ${CMS} ldif text file."
+ echo
+ echo " NOTE: If no redirection is provided to"
+ echo " 'output', then the normalized"
+ echo " ${CMS} ldif text will merely"
+ echo " be echoed to stdout."
+ echo
+ exit 1
+fi
+
+
+###
+### Check that the specified "input" file exists and is a regular file.
+###
+
+if [ ! -f $1 ] ; then
+ echo "ERROR: Either the specified 'input' file, '$1', does not exist, "
+ echo " or it is not a regular file!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified "input" file exists and is not empty.
+###
+
+if [ ! -s $1 ] ; then
+ echo "ERROR: The specified 'input' file, '$1', is empty!"
+ echo
+ exit 3
+fi
+
+
+###
+### If an "errors" file is specified, then check that it does not already
+### exist.
+###
+
+if [ $# -eq 2 ] ; then
+ if [ -f $2 ] ; then
+ echo "ERROR: The specified 'errors' file, '$2', already exists!"
+ echo " Please specify a different file!"
+ echo
+ exit 4
+ fi
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${INSTANCE}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and INSTANCE "
+ echo " environment variables for this script!"
+ echo
+ exit 5
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 6
+fi
+
+
+###
+### Check that the specified INSTANCE exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}/cert-${INSTANCE}" ] ; then
+ echo "ERROR: Either the specified INSTANCE does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 7
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Convert the specified ${CMS} ldif data file
+### into a normalized ${CMS} ldif text file.
+###
+
+${SERVER_ROOT}/bin/cert/jre/bin/java -classpath ./classes:${SERVER_ROOT}/cert-${INSTANCE}/classes:${SERVER_ROOT}/bin/cert/classes:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar:${SERVER_ROOT}/bin/cert/jre/lib/rt.jar:${SERVER_ROOT}/bin/cert/jre/lib/i18n.jar Main $1 $2
+
diff --git a/base/migrate/60ToTxt/src/Main.java b/base/migrate/60ToTxt/src/Main.java
new file mode 100644
index 000000000..72de924c4
--- /dev/null
+++ b/base/migrate/60ToTxt/src/Main.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 ---
+//
+// "60ToTxt/src/Main.java" is based upon a copy "45ToTxt/src/Main.java"
+// with additional material provided from "47ToTxt/src/Main.java".
+//
+// Always comment any new code sections with a "CMS 6.0" header, and
+// apply these changes forward to all other "*ToTxt/src/Main.java" files
+// (including this comment header) so that these differences will only
+// appear when this file is diffed against an earlier "*ToTxt" version.
+//
+// This file should always be maintained by executing the following commands:
+//
+// diff 45ToTxt/src/Main.java 60ToTxt/src/Main.java
+// diff 47ToTxt/src/Main.java 60ToTxt/src/Main.java
+//
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+import sun.misc.*;
+import org.mozilla.jss.*; // CMS 4.5 and later
+import org.mozilla.jss.crypto.*; // CMS 4.5 and later
+import netscape.security.util.*;
+
+public class Main
+{
+ public static void main(String args[])
+ {
+ try {
+ // initialize CryptoManager in CMS 4.5 and later
+ CryptoManager.initialize(".");
+ // load JSS provider in CMS 4.5 and later
+ java.security.Security.removeProvider("SUN version 1.2");
+ // The following call to "java.security.Security.insertProviderAt()"
+ // is no longer commented out in CMS 4.5 and later
+ java.security.Security.insertProviderAt(
+ new netscape.security.provider.CMS(), 0);
+ java.security.Provider ps[] =
+ java.security.Security.getProviders();
+ if (ps == null || ps.length <= 0) {
+ System.err.println("Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ System.err.println("Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+
+ // Parse the File
+ CMS60LdifParser parser = null;
+ if (args.length == 1) {
+ parser = new CMS60LdifParser(args[0]);
+ } else if (args.length == 2) {
+ parser = new CMS60LdifParser(args[0], args[1]);
+ } else {
+ throw new IOException("Invalid Parameters");
+ }
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+}
+
+class CMS60LdifParser
+{
+ // constants
+ private static final String DN =
+ "dn:";
+ // Directory Servers in CMS 4.7 and later use "requestAttributes"
+ private static final String REQUEST_ATTRIBUTES =
+ "requestAttributes::";
+ private static final String BEGIN =
+ "--- BEGIN ATTRIBUTES ---";
+ private static final String END =
+ "--- END ATTRIBUTES ---";
+
+ // variables
+ private String mFilename = null;
+ private String mErrorFilename = null;
+ private PrintWriter mErrorPrintWriter = null;
+
+ public CMS60LdifParser(String filename)
+ {
+ mFilename = filename;
+ }
+
+ public CMS60LdifParser(String filename, String errorFilename)
+ {
+ mFilename = filename;
+ mErrorFilename = errorFilename;
+ }
+
+ public void parse() throws Exception
+ {
+ if (mErrorFilename != null) {
+ mErrorPrintWriter = new PrintWriter(new FileOutputStream(mErrorFilename));
+ }
+ BufferedReader reader = new BufferedReader(
+ new FileReader(mFilename));
+ String line = null;
+ String dn = null;
+ StringBuffer requestAttributes = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DN)) {
+ dn = line;
+ }
+ if (line.startsWith(REQUEST_ATTRIBUTES)) {
+ requestAttributes = new StringBuffer();
+ // System.out.println(line);
+ requestAttributes.append(
+ line.substring(REQUEST_ATTRIBUTES.length(),
+ line.length()).trim());
+ continue;
+ }
+ if (requestAttributes == null) {
+ System.out.println(line);
+ continue;
+ }
+ if (line.startsWith(" ")) {
+ // System.out.println(line);
+ requestAttributes.append(line.trim());
+ } else {
+ parseAttributes(dn, requestAttributes);
+ requestAttributes = null;
+ System.out.println(line);
+ }
+ }
+ }
+
+ public void parseAttributes(String dn, StringBuffer attrs) throws Exception
+ {
+ BASE64Decoder decoder = new BASE64Decoder();
+ decodeHashtable(dn, decoder.decodeBuffer(attrs.toString()));
+
+// System.out.println(attrs);
+ }
+
+ public Object decode(byte[] data) throws
+ ObjectStreamException,
+ IOException,
+ ClassNotFoundException
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+ return is.readObject();
+ }
+
+ public void decodeHashtable(String dn, byte[] data) throws Exception
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+
+ System.out.println(BEGIN);
+ String key = null;
+ while (true)
+ {
+ key = (String)is.readObject();
+ // end of table is marked with null
+ if (key == null) break;
+ try {
+ byte[] bytes = (byte[])is.readObject();
+ Object obj = decode(bytes);
+ output(key, obj);
+ } catch (Exception e) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + key);
+ }
+ }
+ }
+ System.out.println(END);
+ }
+
+ public void output(String key, Object obj) throws Exception
+ {
+ if (obj instanceof String) {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ } else if (obj instanceof netscape.security.x509.CertificateX509Key) {
+ netscape.security.x509.CertificateX509Key o =
+ (netscape.security.x509.CertificateX509Key)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateSubjectName) {
+ netscape.security.x509.CertificateSubjectName o =
+ (netscape.security.x509.CertificateSubjectName)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateExtensions) {
+ netscape.security.x509.CertificateExtensions o =
+ (netscape.security.x509.CertificateExtensions)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertInfo) {
+ netscape.security.x509.X509CertInfo o =
+ (netscape.security.x509.X509CertInfo)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl) {
+ netscape.security.x509.X509CertImpl o =
+ (netscape.security.x509.X509CertImpl)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateChain) {
+ netscape.security.x509.CertificateChain o =
+ (netscape.security.x509.CertificateChain)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl[]) {
+ netscape.security.x509.X509CertImpl o[] =
+ (netscape.security.x509.X509CertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.X509CertInfo[]) {
+ netscape.security.x509.X509CertInfo o[] =
+ (netscape.security.x509.X509CertInfo[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() + "["+o.length + "," + i+"]"+"=" +
+ encoder.encodeBuffer(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.RevokedCertImpl[]) {
+ netscape.security.x509.RevokedCertImpl o[] =
+ (netscape.security.x509.RevokedCertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ DerOutputStream bos =
+ new DerOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof java.security.cert.Certificate[]) {
+ java.security.cert.Certificate o[] =
+ (java.security.cert.Certificate[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(o[i].getEncoded()));
+ }
+ } else if (obj instanceof com.netscape.certsrv.base.ArgBlock) {
+ com.netscape.certsrv.base.ArgBlock o =
+ (com.netscape.certsrv.base.ArgBlock)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" +(String)o.get(k));
+ }
+ } else if (obj instanceof com.netscape.cmscore.dbs.KeyRecord) {
+ // CMS 6.0: moved "com.netscape.certsrv.dbs.keydb.KeyRecord"
+ // to "com.netscape.cmscore.dbs.KeyRecord"
+ com.netscape.cmscore.dbs.KeyRecord o =
+ (com.netscape.cmscore.dbs.KeyRecord)obj;
+ Enumeration<String> e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = e.nextElement();
+ Object ob = o.get(k);
+ if (ob != null) {
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + encoder.encode((byte[])ob));
+
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ }
+ } else if (obj instanceof com.netscape.cmscore.kra.ProofOfArchival) {
+ // CMS 6.0: moved "com.netscape.certsrv.kra.ProofOfArchival"
+ // to "com.netscape.cmscore.kra.ProofOfArchival"
+ com.netscape.cmscore.kra.ProofOfArchival o =
+ (com.netscape.cmscore.kra.ProofOfArchival)obj;
+ DerOutputStream bos =
+ new DerOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof com.netscape.certsrv.request.AgentApprovals) {
+ com.netscape.certsrv.request.AgentApprovals o =
+ (com.netscape.certsrv.request.AgentApprovals)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ com.netscape.certsrv.request.AgentApproval approval = (com.netscape.certsrv.request.AgentApproval)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ approval.getUserName() + ";" + approval.getDate().getTime());
+ }
+ } else if (obj instanceof com.netscape.certsrv.authentication.AuthToken) {
+ com.netscape.certsrv.authentication.AuthToken o =
+ (com.netscape.certsrv.authentication.AuthToken)obj;
+ Enumeration e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ Object ob = o.get(k);
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof java.math.BigInteger[]) {
+ // Bugzilla Bug #225031 (a.k.a. - Raidzilla Bug #58356)
+ java.math.BigInteger in[] = (java.math.BigInteger[])ob;
+ String numbers = "";
+ for (int i = 0; i < in.length; i++) {
+ if (numbers.equals("")) {
+ numbers = in[i].toString();
+ } else {
+ numbers = numbers + "," + in[i].toString();
+ }
+ }
+ System.out.println(" " +
+ key + ":" + "com.netscape.certsrv.authentication.AuthToken" + "=" +
+ k + ":java.lang.String=" + numbers);
+ } else if (ob instanceof String[]) {
+ // Bugzilla Bug #224763 (a.k.a. - Raidzilla Bug #57949)
+ // Bugzilla Bug #252240
+ String str[] = (String[])ob;
+ String v = "";
+ if (str != null) {
+ for (int i = 0; i < str.length; i++) {
+ if (i != 0) {
+ v += ",";
+ }
+ v += str[i];
+ }
+ }
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + "java.lang.String" + "=" + v);
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ } else if (obj instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key + ":byte[]="+
+ encoder.encode((byte[])obj));
+ } else if (obj instanceof Integer[]) {
+ Integer in[] = (Integer[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":Integer[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof BigInteger[]) {
+ // Bugzilla Bug #238779
+ BigInteger in[] = (BigInteger[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":java.math.BigInteger[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof String[]) {
+ // Bugzilla Bug #223360 (a.k.a - Raidzilla Bug #58086)
+ String str[] = (String[])obj;
+ for (int i = 0; i < str.length; i++) {
+ System.out.println(" " + key + ":java.lang.String[" + str.length + "," + i + "]="+ str[i]);
+ }
+ } else if (obj instanceof netscape.security.x509.CertificateAlgorithmId) {
+ netscape.security.x509.CertificateAlgorithmId o =
+ (netscape.security.x509.CertificateAlgorithmId)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateAlgorithmId="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateValidity) {
+ netscape.security.x509.CertificateValidity o =
+ (netscape.security.x509.CertificateValidity)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateValidity="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof java.util.Hashtable) {
+ // Bugzilla Bug #224800 (a.k.a - Raidzilla Bug #56953)
+ //
+ // Example: fingerprints:java.util.Hashtable=
+ // {SHA1=[B@52513a, MD5=[B@52c4d9, MD2=[B@799ff5}
+ //
+ java.util.Hashtable o = (java.util.Hashtable)obj;
+ BASE64Encoder encoder = new BASE64Encoder();
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" + encoder.encode((byte[])o.get(k)));
+ }
+ } else {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ }
+ }
+}
+
diff --git a/base/migrate/60ToTxt/src/compile.bat b/base/migrate/60ToTxt/src/compile.bat
new file mode 100755
index 000000000..8c8b122c0
--- /dev/null
+++ b/base/migrate/60ToTxt/src/compile.bat
@@ -0,0 +1,152 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script creates the "60ToTxt/classes/Main.class" and
+REM "60ToTxt/classes/CMS60LdifParser.class" which are
+REM used to create a normalized CMS 6.0/6.01 ldif text file.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM Set SERVER_ROOT - identify the CMS <server_root> used to compile 60ToTxt
+REM
+
+REM SET SERVER_ROOT=C:\cms601
+
+
+REM
+REM Set JDK_VERSION - specify the JDK version used by this version of CMS
+REM
+REM CMS 6.0 NOTE: "WINNT" - 1.3.1_02
+REM
+REM CMS 6.01 NOTE: "WINNT" - 1.3.1_02
+REM
+
+REM SET JDK_VERSION=CMS_6.01
+
+
+REM
+REM Set JAVA_HOME - specify the complete path to the JDK
+REM
+REM example: \\bermuda.redhat.com\sbc mounted as Y:
+REM
+
+REM SET JAVA_HOME=Y:\cms_jdk\WINNT\%JDK_VERSION%
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 6.0"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0"
+ECHO.
+ECHO NOTE: No arguments are required to build the
+ECHO normalized %CMS% ldif text classes.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%JAVA_HOME%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and JAVA_HOME
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_JAVA_HOME
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified JAVA_HOME exists
+REM
+
+:CHECK_JAVA_HOME
+IF EXIST %JAVA_HOME% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified JAVA_HOME does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%JAVA_HOME%\bin;%JAVA_HOME%\lib;%PATH%
+
+
+REM
+REM Set TARGET - identify the complete path to the new classes target directory
+REM
+
+SET TARGET=..\classes
+
+
+REM
+REM Create the new classes target directory (if it does not already exist)
+REM
+
+IF EXIST %TARGET% goto COMPILE_CLASSES
+MKDIR %TARGET%
+
+
+REM
+REM Compile 60ToTxt - create "CMS60LdifParser.class" and "Main.class"
+REM
+
+:COMPILE_CLASSES
+%JAVA_HOME%\bin\javac.exe -d %TARGET% -classpath %JAVA_HOME%\jre\lib\rt.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar Main.java
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/60ToTxt/src/compile.sh b/base/migrate/60ToTxt/src/compile.sh
new file mode 100755
index 000000000..5641688bb
--- /dev/null
+++ b/base/migrate/60ToTxt/src/compile.sh
@@ -0,0 +1,164 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#####################################################################
+### ###
+### This script creates the "60ToTxt/classes/Main.class" and ###
+### "60ToTxt/classes/CMS60LdifParser.class" which are ###
+### used to create a normalized CMS 6.0/6.01 ldif text file. ###
+### ###
+#####################################################################
+
+
+###
+### Set SERVER_ROOT - identify the CMS <server_root> used to compile 60ToTxt
+###
+
+#SERVER_ROOT=/export/home/migrate/cms601
+#export SERVER_ROOT
+
+
+###
+### Set JDK_PLATFORM - must be "HP-UX", "Linux", or "SunOS"
+###
+
+#JDK_PLATFORM=SunOS
+#export JDK_PLATFORM
+
+
+###
+### Set JDK_VERSION - specify the JDK version used by this version of CMS
+###
+### CMS 6.0 NOTE: "HP-UX" - 1.3.1.02
+### "Linux" - 1.3.1_02
+### "SunOS" - 1.3.1_02
+###
+### CMS 6.01 NOTE: "HP-UX" - 1.3.1.02
+### "Linux" - 1.4.0
+### "SunOS" - 1.3.1_02
+###
+
+#JDK_VERSION=CMS_6.01
+#export JDK_VERSION
+
+
+###
+### Set JAVA_HOME - specify the complete path to the JDK
+###
+
+#JAVA_HOME=/share/builds/components/cms_jdk/${JDK_PLATFORM}/${JDK_VERSION}
+#export JAVA_HOME
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 6.0"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -gt 0 ] ; then
+ echo
+ echo "Usage: $0"
+ echo
+ echo " NOTE: No arguments are required to build the"
+ echo " normalized ${CMS} ldif text classes."
+ echo
+ exit 1
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${JAVA_HOME}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and JAVA_HOME "
+ echo " environment variables for this script!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 3
+fi
+
+
+###
+### Check that the specified JAVA_HOME exists and is a directory
+###
+
+if [ ! -d "${JAVA_HOME}" ] ; then
+ echo "ERROR: Either the specified JAVA_HOME does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 4
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Set TARGET - identify the complete path to the new classes target directory
+###
+
+TARGET=../classes
+export TARGET
+
+
+###
+### Create the new classes target directory (if it does not already exist)
+###
+
+if [ ! -d ${TARGET} ]; then
+ mkdir -p ${TARGET}
+fi
+
+
+###
+### Compile 60ToTxt - create "CMS60LdifParser.class" and "Main.class"
+###
+
+${JAVA_HOME}/bin/javac -d ${TARGET} -classpath ${JAVA_HOME}/jre/lib/rt.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar Main.java
+
diff --git a/base/migrate/61ToTxt/classes/CMS61LdifParser.class b/base/migrate/61ToTxt/classes/CMS61LdifParser.class
new file mode 100644
index 000000000..4c08a38aa
--- /dev/null
+++ b/base/migrate/61ToTxt/classes/CMS61LdifParser.class
Binary files differ
diff --git a/base/migrate/61ToTxt/classes/Main.class b/base/migrate/61ToTxt/classes/Main.class
new file mode 100644
index 000000000..8f141215d
--- /dev/null
+++ b/base/migrate/61ToTxt/classes/Main.class
Binary files differ
diff --git a/base/migrate/61ToTxt/run.bat b/base/migrate/61ToTxt/run.bat
new file mode 100755
index 000000000..2386ab20b
--- /dev/null
+++ b/base/migrate/61ToTxt/run.bat
@@ -0,0 +1,192 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM This program is free software; you can redistribute it and/or modify
+REM it under the terms of the GNU General Public License as published by
+REM the Free Software Foundation; version 2 of the License.
+REM
+REM This program is distributed in the hope that it will be useful,
+REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+REM GNU General Public License for more details.
+REM
+REM You should have received a copy of the GNU General Public License along
+REM with this program; if not, write to the Free Software Foundation, Inc.,
+REM 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script converts a pre-existing CMS 6.1 ldif data
+REM file (e. g. - created via a utility such as db2ldif)
+REM into a normalized CMS 6.1 ldif text file.
+REM
+REM This subsequent normalized CMS 6.1 ldif text file
+REM can be migrated into CMS 6.1 or later utilizing
+REM the corresponding TxtTo<Target CMS Version> script which
+REM converts this normalized CMS 6.1 ldif text file into
+REM a <Target CMS Version> ldif data file.
+REM
+REM This <Target CMS Version> ldif data file can then be
+REM imported into the internal database of the desired CMS
+REM server using a utility such as ldif2db.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM SERVER_ROOT - fully qualified path of the location of the server
+REM
+
+REM SET SERVER_ROOT=C:\cms61
+
+
+REM
+REM INSTANCE - if the CMS instance directory is called 'cert-ca',
+REM set the CMS instance to 'ca'
+REM
+REM NOTE: When a single SERVER_ROOT contains more than
+REM one CMS instance, this script must be run multiple
+REM times. To do this, there is only a need to change
+REM the INSTANCE parameter.
+REM
+
+REM SET INSTANCE=ca
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 6.1"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO USAGE
+IF "%3" == "" GOTO CHECK_INPUT_FILE
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0 input [errors] > output"
+ECHO.
+ECHO where: input - the specified %CMS% ldif data file,
+ECHO errors - an optional errors file containing
+ECHO skipped attributes, and
+ECHO output - the normalized %CMS% ldif text file.
+ECHO.
+ECHO NOTE: If no redirection is provided to
+ECHO 'output', then the normalized
+ECHO %CMS% ldif text will merely
+ECHO be echoed to stdout.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified "input" file exists
+REM
+
+:CHECK_INPUT_FILE
+IF EXIST %1 GOTO CHECK_ERRORS_FILE
+
+
+ECHO ERROR: The specified input file, %1, does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM If an "errors" file is specified, then check that it does not already
+REM exist.
+REM
+
+:CHECK_ERRORS_FILE
+IF "%2" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+IF EXIST %2 GOTO ERRORS_FILE_ERROR
+GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:ERRORS_FILE_ERROR
+ECHO ERROR: The specified errors file, %2, already exists!
+ECHO Please specify a different file!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%INSTANCE%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and INSTANCE
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_INSTANCE
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified INSTANCE exists
+REM
+
+:CHECK_INSTANCE
+IF EXIST %SERVER_ROOT%\cert-%INSTANCE% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified INSTANCE does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%SERVER_ROOT%\bin\cert\jre\bin;%SERVER_ROOT\bin\cert\jre\bin\server;%PATH%
+
+
+REM
+REM Convert the specified %CMS% ldif data file
+REM into a normalized %CMS% ldif text file.
+REM
+
+%SERVER_ROOT%\bin\cert\jre\bin\java.exe -classpath .\classes;%SERVER_ROOT%\cert-%INSTANCE%\classes;%SERVER_ROOT%\bin\cert\classes;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar;%SERVER_ROOT%\bin\cert\jre\lib\rt.jar Main %1 %2
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/61ToTxt/run.sh b/base/migrate/61ToTxt/run.sh
new file mode 100755
index 000000000..9fa8ffe12
--- /dev/null
+++ b/base/migrate/61ToTxt/run.sh
@@ -0,0 +1,202 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+
+#####################################################################
+### ###
+### This script converts a pre-existing CMS 6.1 ldif data ###
+### file (e. g. - created via a utility such as db2ldif) ###
+### into a normalized CMS 6.1 ldif text file. ###
+### ###
+### This subsequent normalized CMS 6.1 ldif text file ###
+### can be migrated into CMS 6.1 or later utilizing ###
+### the corresponding TxtTo<Target CMS Version> script which ###
+### converts this normalized CMS 6.1 ldif text file into ###
+### a <Target CMS Version> ldif data file. ###
+### ###
+### This <Target CMS Version> ldif data file can then be ###
+### imported into the internal database of the desired CMS ###
+### server using a utility such as ldif2db. ###
+### ###
+#####################################################################
+
+
+###
+### SERVER_ROOT - fully qualified path of the location of the server
+###
+
+#SERVER_ROOT=/export/home/migrate/cms61
+#export SERVER_ROOT
+
+
+###
+### INSTANCE - if the CMS instance directory is called 'cert-ca',
+### set the CMS instance to 'ca'
+###
+### NOTE: When a single SERVER_ROOT contains more than
+### one CMS instance, this script must be run multiple
+### times. To do this, there is only a need to change
+### the INSTANCE parameter.
+###
+
+#INSTANCE=ca
+#export INSTANCE
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 6.1"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+##
+## Perform a usage check for the appropriate number of arguments:
+##
+
+if [ $# -lt 1 -o $# -gt 2 ] ; then
+ echo
+ echo "Usage: $0 input [errors] > output"
+ echo
+ echo " where: input - the specified ${CMS} ldif data file,"
+ echo " errors - an optional errors file containing"
+ echo " skipped attributes, and"
+ echo " output - the normalized ${CMS} ldif text file."
+ echo
+ echo " NOTE: If no redirection is provided to"
+ echo " 'output', then the normalized"
+ echo " ${CMS} ldif text will merely"
+ echo " be echoed to stdout."
+ echo
+ exit 1
+fi
+
+
+###
+### Check that the specified "input" file exists and is a regular file.
+###
+
+if [ ! -f $1 ] ; then
+ echo "ERROR: Either the specified 'input' file, '$1', does not exist, "
+ echo " or it is not a regular file!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified "input" file exists and is not empty.
+###
+
+if [ ! -s $1 ] ; then
+ echo "ERROR: The specified 'input' file, '$1', is empty!"
+ echo
+ exit 3
+fi
+
+
+###
+### If an "errors" file is specified, then check that it does not already
+### exist.
+###
+
+if [ $# -eq 2 ] ; then
+ if [ -f $2 ] ; then
+ echo "ERROR: The specified 'errors' file, '$2', already exists!"
+ echo " Please specify a different file!"
+ echo
+ exit 4
+ fi
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${INSTANCE}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and INSTANCE "
+ echo " environment variables for this script!"
+ echo
+ exit 5
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 6
+fi
+
+
+###
+### Check that the specified INSTANCE exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}/cert-${INSTANCE}" ] ; then
+ echo "ERROR: Either the specified INSTANCE does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 7
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Convert the specified ${CMS} ldif data file
+### into a normalized ${CMS} ldif text file.
+###
+### NOTE: As of SunOS JDK 1.4.0, the required "Unicode" classes
+### have been moved from "i18n.jar" to "rt.jar".
+###
+
+${SERVER_ROOT}/bin/cert/jre/bin/java -classpath ./classes:${SERVER_ROOT}/cert-${INSTANCE}/classes:${SERVER_ROOT}/bin/cert/classes:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar:${SERVER_ROOT}/bin/cert/jre/lib/rt.jar Main $1 $2
+
diff --git a/base/migrate/61ToTxt/src/Main.java b/base/migrate/61ToTxt/src/Main.java
new file mode 100644
index 000000000..cd235f73f
--- /dev/null
+++ b/base/migrate/61ToTxt/src/Main.java
@@ -0,0 +1,483 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+//
+// "61ToTxt/src/Main.java" is based upon a copy "60ToTxt/src/Main.java".
+//
+// Always comment any new code sections with a "CMS 6.1" header, and
+// apply these changes forward to all other "*ToTxt/src/Main.java" files
+// (including this comment header) so that these differences will only
+// appear when this file is diffed against an earlier "*ToTxt" version.
+//
+// This file should always be maintained by executing the following command:
+//
+// diff 60ToTxt/src/Main.java 61ToTxt/src/Main.java
+//
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+import sun.misc.*;
+import org.mozilla.jss.*; // CMS 4.5 and later
+import org.mozilla.jss.crypto.*; // CMS 4.5 and later
+import netscape.security.util.*;
+
+public class Main
+{
+ public static void main(String args[])
+ {
+ try {
+ // initialize CryptoManager in CMS 4.5 and later
+ CryptoManager.initialize(".");
+ // load JSS provider in CMS 4.5 and later
+ java.security.Security.removeProvider("SUN version 1.2");
+ // The following call to "java.security.Security.insertProviderAt()"
+ // is no longer commented out in CMS 4.5 and later
+ java.security.Security.insertProviderAt(
+ new netscape.security.provider.CMS(), 0);
+ java.security.Provider ps[] =
+ java.security.Security.getProviders();
+ if (ps == null || ps.length <= 0) {
+ System.err.println("Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ System.err.println("Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+
+ // Parse the File
+ CMS61LdifParser parser = null;
+ if (args.length == 1) {
+ parser = new CMS61LdifParser(args[0]);
+ } else if (args.length == 2) {
+ parser = new CMS61LdifParser(args[0], args[1]);
+ } else {
+ throw new IOException("Invalid Parameters");
+ }
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+}
+
+class CMS61LdifParser
+{
+ // constants
+ private static final String DN =
+ "dn:";
+ // Directory Servers in CMS 4.7 and later use "requestAttributes"
+ private static final String REQUEST_ATTRIBUTES =
+ "requestAttributes::";
+ private static final String BEGIN =
+ "--- BEGIN ATTRIBUTES ---";
+ private static final String END =
+ "--- END ATTRIBUTES ---";
+
+ // variables
+ private String mFilename = null;
+ private String mErrorFilename = null;
+ private PrintWriter mErrorPrintWriter = null;
+
+ public CMS61LdifParser(String filename)
+ {
+ mFilename = filename;
+ }
+
+ public CMS61LdifParser(String filename, String errorFilename)
+ {
+ mFilename = filename;
+ mErrorFilename = errorFilename;
+ }
+
+ public void parse() throws Exception
+ {
+ if (mErrorFilename != null) {
+ mErrorPrintWriter = new PrintWriter(new FileOutputStream(mErrorFilename));
+ }
+ BufferedReader reader = new BufferedReader(
+ new FileReader(mFilename));
+ String line = null;
+ String dn = null;
+ StringBuffer requestAttributes = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DN)) {
+ dn = line;
+ }
+ if (line.startsWith(REQUEST_ATTRIBUTES)) {
+ requestAttributes = new StringBuffer();
+ // System.out.println(line);
+ requestAttributes.append(
+ line.substring(REQUEST_ATTRIBUTES.length(),
+ line.length()).trim());
+ continue;
+ }
+ if (requestAttributes == null) {
+ System.out.println(line);
+ continue;
+ }
+ if (line.startsWith(" ")) {
+ // System.out.println(line);
+ requestAttributes.append(line.trim());
+ } else {
+ parseAttributes(dn, requestAttributes);
+ requestAttributes = null;
+ System.out.println(line);
+ }
+ }
+ }
+
+ public void parseAttributes(String dn, StringBuffer attrs) throws Exception
+ {
+ BASE64Decoder decoder = new BASE64Decoder();
+ decodeHashtable(dn, decoder.decodeBuffer(attrs.toString()));
+
+// System.out.println(attrs);
+ }
+
+ public Object decode(byte[] data) throws
+ ObjectStreamException,
+ IOException,
+ ClassNotFoundException
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+ return is.readObject();
+ }
+
+ public void decodeHashtable(String dn, byte[] data) throws Exception
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+
+ System.out.println(BEGIN);
+ String key = null;
+ while (true)
+ {
+ key = (String)is.readObject();
+ // end of table is marked with null
+ if (key == null) break;
+ try {
+ byte[] bytes = (byte[])is.readObject();
+ Object obj = decode(bytes);
+ output(key, obj);
+ } catch (Exception e) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + key);
+ }
+ }
+ }
+ System.out.println(END);
+ }
+
+ public void output(String key, Object obj) throws Exception
+ {
+ if (obj instanceof String) {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ } else if (obj instanceof netscape.security.x509.CertificateX509Key) {
+ netscape.security.x509.CertificateX509Key o =
+ (netscape.security.x509.CertificateX509Key)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateSubjectName) {
+ netscape.security.x509.CertificateSubjectName o =
+ (netscape.security.x509.CertificateSubjectName)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateExtensions) {
+ netscape.security.x509.CertificateExtensions o =
+ (netscape.security.x509.CertificateExtensions)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertInfo) {
+ netscape.security.x509.X509CertInfo o =
+ (netscape.security.x509.X509CertInfo)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl) {
+ netscape.security.x509.X509CertImpl o =
+ (netscape.security.x509.X509CertImpl)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateChain) {
+ netscape.security.x509.CertificateChain o =
+ (netscape.security.x509.CertificateChain)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl[]) {
+ netscape.security.x509.X509CertImpl o[] =
+ (netscape.security.x509.X509CertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.X509CertInfo[]) {
+ netscape.security.x509.X509CertInfo o[] =
+ (netscape.security.x509.X509CertInfo[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() + "["+o.length + "," + i+"]"+"=" +
+ encoder.encodeBuffer(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.RevokedCertImpl[]) {
+ netscape.security.x509.RevokedCertImpl o[] =
+ (netscape.security.x509.RevokedCertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ DerOutputStream bos =
+ new DerOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof java.security.cert.Certificate[]) {
+ java.security.cert.Certificate o[] =
+ (java.security.cert.Certificate[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(o[i].getEncoded()));
+ }
+ } else if (obj instanceof com.netscape.cmscore.base.ArgBlock) {
+ // CMS 6.1: created new "com.netscape.certsrv.base.IArgBlock" and
+ // moved old "com.netscape.certsrv.base.ArgBlock"
+ // to "com.netscape.cmscore.base.ArgBlock"
+ com.netscape.cmscore.base.ArgBlock o =
+ (com.netscape.cmscore.base.ArgBlock)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" +(String)o.get(k));
+ }
+ } else if (obj instanceof com.netscape.cmscore.dbs.KeyRecord) {
+ // CMS 6.0: moved "com.netscape.certsrv.dbs.keydb.KeyRecord"
+ // to "com.netscape.cmscore.dbs.KeyRecord"
+ com.netscape.cmscore.dbs.KeyRecord o =
+ (com.netscape.cmscore.dbs.KeyRecord)obj;
+ Enumeration<String> e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = e.nextElement();
+ Object ob = o.get(k);
+ if (ob != null) {
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + encoder.encode((byte[])ob));
+
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ }
+ } else if (obj instanceof com.netscape.cmscore.kra.ProofOfArchival) {
+ // CMS 6.0: moved "com.netscape.certsrv.kra.ProofOfArchival"
+ // to "com.netscape.cmscore.kra.ProofOfArchival"
+ com.netscape.cmscore.kra.ProofOfArchival o =
+ (com.netscape.cmscore.kra.ProofOfArchival)obj;
+ DerOutputStream bos =
+ new DerOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof com.netscape.certsrv.request.AgentApprovals) {
+ com.netscape.certsrv.request.AgentApprovals o =
+ (com.netscape.certsrv.request.AgentApprovals)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ com.netscape.certsrv.request.AgentApproval approval = (com.netscape.certsrv.request.AgentApproval)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ approval.getUserName() + ";" + approval.getDate().getTime());
+ }
+ } else if (obj instanceof com.netscape.certsrv.authentication.AuthToken) {
+ com.netscape.certsrv.authentication.AuthToken o =
+ (com.netscape.certsrv.authentication.AuthToken)obj;
+ Enumeration e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ Object ob = o.get(k);
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof java.math.BigInteger[]) {
+ // Bugzilla Bug #225031 (a.k.a. - Raidzilla Bug #58356)
+ java.math.BigInteger in[] = (java.math.BigInteger[])ob;
+ String numbers = "";
+ for (int i = 0; i < in.length; i++) {
+ if (numbers.equals("")) {
+ numbers = in[i].toString();
+ } else {
+ numbers = numbers + "," + in[i].toString();
+ }
+ }
+ System.out.println(" " +
+ key + ":" + "com.netscape.certsrv.authentication.AuthToken" + "=" +
+ k + ":java.lang.String=" + numbers);
+ } else if (ob instanceof String[]) {
+ // Bugzilla Bug #224763 (a.k.a. - Raidzilla Bug #57949)
+ // Bugzilla Bug #252240
+ String str[] = (String[])ob;
+ String v = "";
+ if (str != null) {
+ for (int i = 0; i < str.length; i++) {
+ if (i != 0) {
+ v += ",";
+ }
+ v += str[i];
+ }
+ }
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + "java.lang.String" + "=" + v);
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ } else if (obj instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key + ":byte[]="+
+ encoder.encode((byte[])obj));
+ } else if (obj instanceof Integer[]) {
+ Integer in[] = (Integer[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":Integer[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof BigInteger[]) {
+ // Bugzilla Bug #238779
+ BigInteger in[] = (BigInteger[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":java.math.BigInteger[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof String[]) {
+ // Bugzilla Bug #223360 (a.k.a - Raidzilla Bug #58086)
+ String str[] = (String[])obj;
+ for (int i = 0; i < str.length; i++) {
+ System.out.println(" " + key + ":java.lang.String[" + str.length + "," + i + "]="+ str[i]);
+ }
+ } else if (obj instanceof netscape.security.x509.CertificateAlgorithmId) {
+ netscape.security.x509.CertificateAlgorithmId o =
+ (netscape.security.x509.CertificateAlgorithmId)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateAlgorithmId="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateValidity) {
+ netscape.security.x509.CertificateValidity o =
+ (netscape.security.x509.CertificateValidity)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateValidity="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof byte[]) {
+ // Since 6.1's profile framework,
+ // req_archive_options is a byte array
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":byte[]="+
+ encoder.encode((byte[])obj));
+ } else if (obj instanceof java.util.Hashtable) {
+ // Bugzilla Bug #224800 (a.k.a - Raidzilla Bug #56953)
+ //
+ // Example: fingerprints:java.util.Hashtable=
+ // {SHA1=[B@52513a, MD5=[B@52c4d9, MD2=[B@799ff5}
+ //
+ java.util.Hashtable o = (java.util.Hashtable)obj;
+ BASE64Encoder encoder = new BASE64Encoder();
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" + encoder.encode((byte[])o.get(k)));
+ }
+ } else {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ }
+ }
+}
+
diff --git a/base/migrate/61ToTxt/src/compile.bat b/base/migrate/61ToTxt/src/compile.bat
new file mode 100755
index 000000000..48bb90018
--- /dev/null
+++ b/base/migrate/61ToTxt/src/compile.bat
@@ -0,0 +1,150 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script creates the "61ToTxt/classes/Main.class" and
+REM "61ToTxt/classes/CMS61LdifParser.class" which are
+REM used to create a normalized CMS 6.1 ldif text file.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM Set SERVER_ROOT - identify the CMS <server_root> used to compile 61ToTxt
+REM
+
+REM SET SERVER_ROOT=C:\cms61
+
+
+REM
+REM Set JDK_VERSION - specify the JDK version used by this version of CMS
+REM
+REM CMS 6.1 NOTE: "WINNT" - 1.4.0
+REM
+
+REM SET JDK_VERSION=CMS_6.1
+
+
+REM
+REM Set JAVA_HOME - specify the complete path to the JDK
+REM
+REM example: \\bermuda.redhat.com\sbc mounted as Y:
+REM
+
+REM SET JAVA_HOME=Y:\cms_jdk\WINNT\%JDK_VERSION%
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 6.1"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0"
+ECHO.
+ECHO NOTE: No arguments are required to build the
+ECHO normalized %CMS% ldif text classes.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%JAVA_HOME%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and JAVA_HOME
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_JAVA_HOME
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified JAVA_HOME exists
+REM
+
+:CHECK_JAVA_HOME
+IF EXIST %JAVA_HOME% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified JAVA_HOME does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%JAVA_HOME%\bin;%JAVA_HOME%\lib;%PATH%
+
+
+REM
+REM Set TARGET - identify the complete path to the new classes target directory
+REM
+
+SET TARGET=..\classes
+
+
+REM
+REM Create the new classes target directory (if it does not already exist)
+REM
+
+IF EXIST %TARGET% goto COMPILE_CLASSES
+MKDIR %TARGET%
+
+
+REM
+REM Compile 61ToTxt - create "CMS61LdifParser.class" and "Main.class"
+REM
+
+:COMPILE_CLASSES
+%JAVA_HOME%\bin\javac.exe -d %TARGET% -classpath %JAVA_HOME%\jre\lib\rt.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar Main.java
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/61ToTxt/src/compile.sh b/base/migrate/61ToTxt/src/compile.sh
new file mode 100755
index 000000000..b1f8c8505
--- /dev/null
+++ b/base/migrate/61ToTxt/src/compile.sh
@@ -0,0 +1,160 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#####################################################################
+### ###
+### This script creates the "61ToTxt/classes/Main.class" and ###
+### "61ToTxt/classes/CMS61LdifParser.class" which are ###
+### used to create a normalized CMS 6.1 ldif text file. ###
+### ###
+#####################################################################
+
+
+###
+### Set SERVER_ROOT - identify the CMS <server_root> used to compile 61ToTxt
+###
+
+#SERVER_ROOT=/export/home/migrate/cms61
+#export SERVER_ROOT
+
+
+###
+### Set JDK_PLATFORM - must be "HP-UX", "Linux", or "SunOS"
+###
+
+#JDK_PLATFORM=SunOS
+#export JDK_PLATFORM
+
+
+###
+### Set JDK_VERSION - specify the JDK version used by this version of CMS
+###
+### CMS 6.1 NOTE: "HP-UX" - 1.3.1.02
+### "Linux" - 1.3.1_02
+### "SunOS" - 1.3.1_02
+###
+
+#JDK_VERSION=CMS_6.1
+#export JDK_VERSION
+
+
+###
+### Set JAVA_HOME - specify the complete path to the JDK
+###
+
+#JAVA_HOME=/share/builds/components/cms_jdk/${JDK_PLATFORM}/${JDK_VERSION}
+#export JAVA_HOME
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 6.1"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -gt 0 ] ; then
+ echo
+ echo "Usage: $0"
+ echo
+ echo " NOTE: No arguments are required to build the"
+ echo " normalized ${CMS} ldif text classes."
+ echo
+ exit 1
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${JAVA_HOME}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and JAVA_HOME "
+ echo " environment variables for this script!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 3
+fi
+
+
+###
+### Check that the specified JAVA_HOME exists and is a directory
+###
+
+if [ ! -d "${JAVA_HOME}" ] ; then
+ echo "ERROR: Either the specified JAVA_HOME does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 4
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Set TARGET - identify the complete path to the new classes target directory
+###
+
+TARGET=../classes
+export TARGET
+
+
+###
+### Create the new classes target directory (if it does not already exist)
+###
+
+if [ ! -d ${TARGET} ]; then
+ mkdir -p ${TARGET}
+fi
+
+
+###
+### Compile 61ToTxt - create "CMS61LdifParser.class" and "Main.class"
+###
+
+${JAVA_HOME}/bin/javac -d ${TARGET} -classpath ${JAVA_HOME}/jre/lib/rt.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar Main.java
+
diff --git a/base/migrate/62ToTxt/classes/CMS62LdifParser.class b/base/migrate/62ToTxt/classes/CMS62LdifParser.class
new file mode 100644
index 000000000..8c413efe2
--- /dev/null
+++ b/base/migrate/62ToTxt/classes/CMS62LdifParser.class
Binary files differ
diff --git a/base/migrate/62ToTxt/classes/Main.class b/base/migrate/62ToTxt/classes/Main.class
new file mode 100644
index 000000000..a3b28db52
--- /dev/null
+++ b/base/migrate/62ToTxt/classes/Main.class
Binary files differ
diff --git a/base/migrate/62ToTxt/run.bat b/base/migrate/62ToTxt/run.bat
new file mode 100755
index 000000000..f182fd715
--- /dev/null
+++ b/base/migrate/62ToTxt/run.bat
@@ -0,0 +1,192 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM This program is free software; you can redistribute it and/or modify
+REM it under the terms of the GNU General Public License as published by
+REM the Free Software Foundation; version 2 of the License.
+REM
+REM This program is distributed in the hope that it will be useful,
+REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+REM GNU General Public License for more details.
+REM
+REM You should have received a copy of the GNU General Public License along
+REM with this program; if not, write to the Free Software Foundation, Inc.,
+REM 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script converts a pre-existing CMS 6.2 ldif data
+REM file (e. g. - created via a utility such as db2ldif)
+REM into a normalized CMS 6.2 ldif text file.
+REM
+REM This subsequent normalized CMS 6.2 ldif text file
+REM can be migrated into CMS 6.2 or later utilizing
+REM the corresponding TxtTo<Target CMS Version> script which
+REM converts this normalized CMS 6.2 ldif text file into
+REM a <Target CMS Version> ldif data file.
+REM
+REM This <Target CMS Version> ldif data file can then be
+REM imported into the internal database of the desired CMS
+REM server using a utility such as ldif2db.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM SERVER_ROOT - fully qualified path of the location of the server
+REM
+
+REM SET SERVER_ROOT=C:\cms62
+
+
+REM
+REM INSTANCE - if the CMS instance directory is called 'cert-ca',
+REM set the CMS instance to 'ca'
+REM
+REM NOTE: When a single SERVER_ROOT contains more than
+REM one CMS instance, this script must be run multiple
+REM times. To do this, there is only a need to change
+REM the INSTANCE parameter.
+REM
+
+REM SET INSTANCE=ca
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 6.2"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO USAGE
+IF "%3" == "" GOTO CHECK_INPUT_FILE
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0 input [errors] > output"
+ECHO.
+ECHO where: input - the specified %CMS% ldif data file,
+ECHO errors - an optional errors file containing
+ECHO skipped attributes, and
+ECHO output - the normalized %CMS% ldif text file.
+ECHO.
+ECHO NOTE: If no redirection is provided to
+ECHO 'output', then the normalized
+ECHO %CMS% ldif text will merely
+ECHO be echoed to stdout.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified "input" file exists
+REM
+
+:CHECK_INPUT_FILE
+IF EXIST %1 GOTO CHECK_ERRORS_FILE
+
+
+ECHO ERROR: The specified input file, %1, does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM If an "errors" file is specified, then check that it does not already
+REM exist.
+REM
+
+:CHECK_ERRORS_FILE
+IF "%2" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+IF EXIST %2 GOTO ERRORS_FILE_ERROR
+GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:ERRORS_FILE_ERROR
+ECHO ERROR: The specified errors file, %2, already exists!
+ECHO Please specify a different file!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%INSTANCE%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and INSTANCE
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_INSTANCE
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified INSTANCE exists
+REM
+
+:CHECK_INSTANCE
+IF EXIST %SERVER_ROOT%\cert-%INSTANCE% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified INSTANCE does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%SERVER_ROOT%\bin\cert\jre\bin;%SERVER_ROOT\bin\cert\jre\bin\server;%PATH%
+
+
+REM
+REM Convert the specified %CMS% ldif data file
+REM into a normalized %CMS% ldif text file.
+REM
+
+%SERVER_ROOT%\bin\cert\jre\bin\java.exe -classpath .\classes;%SERVER_ROOT%\cert-%INSTANCE%\classes;%SERVER_ROOT%\bin\cert\classes;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar;%SERVER_ROOT%\bin\cert\jre\lib\rt.jar Main %1 %2
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/62ToTxt/run.sh b/base/migrate/62ToTxt/run.sh
new file mode 100755
index 000000000..a192df1ce
--- /dev/null
+++ b/base/migrate/62ToTxt/run.sh
@@ -0,0 +1,202 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+
+#####################################################################
+### ###
+### This script converts a pre-existing CMS 6.2 ldif data ###
+### file (e. g. - created via a utility such as db2ldif) ###
+### into a normalized CMS 6.2 ldif text file. ###
+### ###
+### This subsequent normalized CMS 6.2 ldif text file ###
+### can be migrated into CMS 6.2 or later utilizing ###
+### the corresponding TxtTo<Target CMS Version> script which ###
+### converts this normalized CMS 6.2 ldif text file into ###
+### a <Target CMS Version> ldif data file. ###
+### ###
+### This <Target CMS Version> ldif data file can then be ###
+### imported into the internal database of the desired CMS ###
+### server using a utility such as ldif2db. ###
+### ###
+#####################################################################
+
+
+###
+### SERVER_ROOT - fully qualified path of the location of the server
+###
+
+#SERVER_ROOT=/export/home/migrate/cms62
+#export SERVER_ROOT
+
+
+###
+### INSTANCE - if the CMS instance directory is called 'cert-ca',
+### set the CMS instance to 'ca'
+###
+### NOTE: When a single SERVER_ROOT contains more than
+### one CMS instance, this script must be run multiple
+### times. To do this, there is only a need to change
+### the INSTANCE parameter.
+###
+
+#INSTANCE=ca
+#export INSTANCE
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 6.2"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+##
+## Perform a usage check for the appropriate number of arguments:
+##
+
+if [ $# -lt 1 -o $# -gt 2 ] ; then
+ echo
+ echo "Usage: $0 input [errors] > output"
+ echo
+ echo " where: input - the specified ${CMS} ldif data file,"
+ echo " errors - an optional errors file containing"
+ echo " skipped attributes, and"
+ echo " output - the normalized ${CMS} ldif text file."
+ echo
+ echo " NOTE: If no redirection is provided to"
+ echo " 'output', then the normalized"
+ echo " ${CMS} ldif text will merely"
+ echo " be echoed to stdout."
+ echo
+ exit 1
+fi
+
+
+###
+### Check that the specified "input" file exists and is a regular file.
+###
+
+if [ ! -f $1 ] ; then
+ echo "ERROR: Either the specified 'input' file, '$1', does not exist, "
+ echo " or it is not a regular file!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified "input" file exists and is not empty.
+###
+
+if [ ! -s $1 ] ; then
+ echo "ERROR: The specified 'input' file, '$1', is empty!"
+ echo
+ exit 3
+fi
+
+
+###
+### If an "errors" file is specified, then check that it does not already
+### exist.
+###
+
+if [ $# -eq 2 ] ; then
+ if [ -f $2 ] ; then
+ echo "ERROR: The specified 'errors' file, '$2', already exists!"
+ echo " Please specify a different file!"
+ echo
+ exit 4
+ fi
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${INSTANCE}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and INSTANCE "
+ echo " environment variables for this script!"
+ echo
+ exit 5
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 6
+fi
+
+
+###
+### Check that the specified INSTANCE exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}/cert-${INSTANCE}" ] ; then
+ echo "ERROR: Either the specified INSTANCE does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 7
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Convert the specified ${CMS} ldif data file
+### into a normalized ${CMS} ldif text file.
+###
+### NOTE: As of SunOS JDK 1.4.0, the required "Unicode" classes
+### have been moved from "i18n.jar" to "rt.jar".
+###
+
+${SERVER_ROOT}/bin/cert/jre/bin/java -classpath ./classes:${SERVER_ROOT}/cert-${INSTANCE}/classes:${SERVER_ROOT}/bin/cert/classes:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar:${SERVER_ROOT}/bin/cert/jre/lib/rt.jar Main $1 $2
+
diff --git a/base/migrate/62ToTxt/src/Main.java b/base/migrate/62ToTxt/src/Main.java
new file mode 100644
index 000000000..109162475
--- /dev/null
+++ b/base/migrate/62ToTxt/src/Main.java
@@ -0,0 +1,483 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+//
+// "62ToTxt/src/Main.java" is based upon a copy "61ToTxt/src/Main.java".
+//
+// Always comment any new code sections with a "CMS 6.2" header, and
+// apply these changes forward to all other "*ToTxt/src/Main.java" files
+// (including this comment header) so that these differences will only
+// appear when this file is diffed against an earlier "*ToTxt" version.
+//
+// This file should always be maintained by executing the following command:
+//
+// diff 61ToTxt/src/Main.java 62ToTxt/src/Main.java
+//
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+import sun.misc.*;
+import org.mozilla.jss.*; // CMS 4.5 and later
+import org.mozilla.jss.crypto.*; // CMS 4.5 and later
+import netscape.security.util.*;
+
+public class Main
+{
+ public static void main(String args[])
+ {
+ try {
+ // initialize CryptoManager in CMS 4.5 and later
+ CryptoManager.initialize(".");
+ // load JSS provider in CMS 4.5 and later
+ java.security.Security.removeProvider("SUN version 1.2");
+ // The following call to "java.security.Security.insertProviderAt()"
+ // is no longer commented out in CMS 4.5 and later
+ java.security.Security.insertProviderAt(
+ new netscape.security.provider.CMS(), 0);
+ java.security.Provider ps[] =
+ java.security.Security.getProviders();
+ if (ps == null || ps.length <= 0) {
+ System.err.println("Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ System.err.println("Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+
+ // Parse the File
+ CMS62LdifParser parser = null;
+ if (args.length == 1) {
+ parser = new CMS62LdifParser(args[0]);
+ } else if (args.length == 2) {
+ parser = new CMS62LdifParser(args[0], args[1]);
+ } else {
+ throw new IOException("Invalid Parameters");
+ }
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+}
+
+class CMS62LdifParser
+{
+ // constants
+ private static final String DN =
+ "dn:";
+ // Directory Servers in CMS 4.7 and later use "requestAttributes"
+ private static final String REQUEST_ATTRIBUTES =
+ "requestAttributes::";
+ private static final String BEGIN =
+ "--- BEGIN ATTRIBUTES ---";
+ private static final String END =
+ "--- END ATTRIBUTES ---";
+
+ // variables
+ private String mFilename = null;
+ private String mErrorFilename = null;
+ private PrintWriter mErrorPrintWriter = null;
+
+ public CMS62LdifParser(String filename)
+ {
+ mFilename = filename;
+ }
+
+ public CMS62LdifParser(String filename, String errorFilename)
+ {
+ mFilename = filename;
+ mErrorFilename = errorFilename;
+ }
+
+ public void parse() throws Exception
+ {
+ if (mErrorFilename != null) {
+ mErrorPrintWriter = new PrintWriter(new FileOutputStream(mErrorFilename));
+ }
+ BufferedReader reader = new BufferedReader(
+ new FileReader(mFilename));
+ String line = null;
+ String dn = null;
+ StringBuffer requestAttributes = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DN)) {
+ dn = line;
+ }
+ if (line.startsWith(REQUEST_ATTRIBUTES)) {
+ requestAttributes = new StringBuffer();
+ // System.out.println(line);
+ requestAttributes.append(
+ line.substring(REQUEST_ATTRIBUTES.length(),
+ line.length()).trim());
+ continue;
+ }
+ if (requestAttributes == null) {
+ System.out.println(line);
+ continue;
+ }
+ if (line.startsWith(" ")) {
+ // System.out.println(line);
+ requestAttributes.append(line.trim());
+ } else {
+ parseAttributes(dn, requestAttributes);
+ requestAttributes = null;
+ System.out.println(line);
+ }
+ }
+ }
+
+ public void parseAttributes(String dn, StringBuffer attrs) throws Exception
+ {
+ BASE64Decoder decoder = new BASE64Decoder();
+ decodeHashtable(dn, decoder.decodeBuffer(attrs.toString()));
+
+// System.out.println(attrs);
+ }
+
+ public Object decode(byte[] data) throws
+ ObjectStreamException,
+ IOException,
+ ClassNotFoundException
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+ return is.readObject();
+ }
+
+ public void decodeHashtable(String dn, byte[] data) throws Exception
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+
+ System.out.println(BEGIN);
+ String key = null;
+ while (true)
+ {
+ key = (String)is.readObject();
+ // end of table is marked with null
+ if (key == null) break;
+ try {
+ byte[] bytes = (byte[])is.readObject();
+ Object obj = decode(bytes);
+ output(key, obj);
+ } catch (Exception e) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + key);
+ }
+ }
+ }
+ System.out.println(END);
+ }
+
+ public void output(String key, Object obj) throws Exception
+ {
+ if (obj instanceof String) {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ } else if (obj instanceof netscape.security.x509.CertificateX509Key) {
+ netscape.security.x509.CertificateX509Key o =
+ (netscape.security.x509.CertificateX509Key)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateSubjectName) {
+ netscape.security.x509.CertificateSubjectName o =
+ (netscape.security.x509.CertificateSubjectName)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateExtensions) {
+ netscape.security.x509.CertificateExtensions o =
+ (netscape.security.x509.CertificateExtensions)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertInfo) {
+ netscape.security.x509.X509CertInfo o =
+ (netscape.security.x509.X509CertInfo)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl) {
+ netscape.security.x509.X509CertImpl o =
+ (netscape.security.x509.X509CertImpl)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateChain) {
+ netscape.security.x509.CertificateChain o =
+ (netscape.security.x509.CertificateChain)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl[]) {
+ netscape.security.x509.X509CertImpl o[] =
+ (netscape.security.x509.X509CertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.X509CertInfo[]) {
+ netscape.security.x509.X509CertInfo o[] =
+ (netscape.security.x509.X509CertInfo[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() + "["+o.length + "," + i+"]"+"=" +
+ encoder.encodeBuffer(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.RevokedCertImpl[]) {
+ netscape.security.x509.RevokedCertImpl o[] =
+ (netscape.security.x509.RevokedCertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ DerOutputStream bos =
+ new DerOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof java.security.cert.Certificate[]) {
+ java.security.cert.Certificate o[] =
+ (java.security.cert.Certificate[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(o[i].getEncoded()));
+ }
+ } else if (obj instanceof com.netscape.cmscore.base.ArgBlock) {
+ // CMS 6.1: created new "com.netscape.certsrv.base.IArgBlock" and
+ // moved old "com.netscape.certsrv.base.ArgBlock"
+ // to "com.netscape.cmscore.base.ArgBlock"
+ com.netscape.cmscore.base.ArgBlock o =
+ (com.netscape.cmscore.base.ArgBlock)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" +(String)o.get(k));
+ }
+ } else if (obj instanceof com.netscape.cmscore.dbs.KeyRecord) {
+ // CMS 6.0: moved "com.netscape.certsrv.dbs.keydb.KeyRecord"
+ // to "com.netscape.cmscore.dbs.KeyRecord"
+ com.netscape.cmscore.dbs.KeyRecord o =
+ (com.netscape.cmscore.dbs.KeyRecord)obj;
+ Enumeration<String> e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = e.nextElement();
+ Object ob = o.get(k);
+ if (ob != null) {
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + encoder.encode((byte[])ob));
+
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ }
+ } else if (obj instanceof com.netscape.cmscore.kra.ProofOfArchival) {
+ // CMS 6.0: moved "com.netscape.certsrv.kra.ProofOfArchival"
+ // to "com.netscape.cmscore.kra.ProofOfArchival"
+ com.netscape.cmscore.kra.ProofOfArchival o =
+ (com.netscape.cmscore.kra.ProofOfArchival)obj;
+ DerOutputStream bos =
+ new DerOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof com.netscape.certsrv.request.AgentApprovals) {
+ com.netscape.certsrv.request.AgentApprovals o =
+ (com.netscape.certsrv.request.AgentApprovals)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ com.netscape.certsrv.request.AgentApproval approval = (com.netscape.certsrv.request.AgentApproval)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ approval.getUserName() + ";" + approval.getDate().getTime());
+ }
+ } else if (obj instanceof com.netscape.certsrv.authentication.AuthToken) {
+ com.netscape.certsrv.authentication.AuthToken o =
+ (com.netscape.certsrv.authentication.AuthToken)obj;
+ Enumeration e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ Object ob = o.get(k);
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof java.math.BigInteger[]) {
+ // Bugzilla Bug #225031 (a.k.a. - Raidzilla Bug #58356)
+ java.math.BigInteger in[] = (java.math.BigInteger[])ob;
+ String numbers = "";
+ for (int i = 0; i < in.length; i++) {
+ if (numbers.equals("")) {
+ numbers = in[i].toString();
+ } else {
+ numbers = numbers + "," + in[i].toString();
+ }
+ }
+ System.out.println(" " +
+ key + ":" + "com.netscape.certsrv.authentication.AuthToken" + "=" +
+ k + ":java.lang.String=" + numbers);
+ } else if (ob instanceof String[]) {
+ // Bugzilla Bug #224763 (a.k.a. - Raidzilla Bug #57949)
+ // Bugzilla Bug #252240
+ String str[] = (String[])ob;
+ String v = "";
+ if (str != null) {
+ for (int i = 0; i < str.length; i++) {
+ if (i != 0) {
+ v += ",";
+ }
+ v += str[i];
+ }
+ }
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + "java.lang.String" + "=" + v);
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ } else if (obj instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key + ":byte[]="+
+ encoder.encode((byte[])obj));
+ } else if (obj instanceof Integer[]) {
+ Integer in[] = (Integer[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":Integer[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof BigInteger[]) {
+ // Bugzilla Bug #238779
+ BigInteger in[] = (BigInteger[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":java.math.BigInteger[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof String[]) {
+ // Bugzilla Bug #223360 (a.k.a - Raidzilla Bug #58086)
+ String str[] = (String[])obj;
+ for (int i = 0; i < str.length; i++) {
+ System.out.println(" " + key + ":java.lang.String[" + str.length + "," + i + "]="+ str[i]);
+ }
+ } else if (obj instanceof netscape.security.x509.CertificateAlgorithmId) {
+ netscape.security.x509.CertificateAlgorithmId o =
+ (netscape.security.x509.CertificateAlgorithmId)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateAlgorithmId="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateValidity) {
+ netscape.security.x509.CertificateValidity o =
+ (netscape.security.x509.CertificateValidity)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateValidity="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof byte[]) {
+ // Since 6.1's profile framework,
+ // req_archive_options is a byte array
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":byte[]="+
+ encoder.encode((byte[])obj));
+ } else if (obj instanceof java.util.Hashtable) {
+ // Bugzilla Bug #224800 (a.k.a - Raidzilla Bug #56953)
+ //
+ // Example: fingerprints:java.util.Hashtable=
+ // {SHA1=[B@52513a, MD5=[B@52c4d9, MD2=[B@799ff5}
+ //
+ java.util.Hashtable o = (java.util.Hashtable)obj;
+ BASE64Encoder encoder = new BASE64Encoder();
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" + encoder.encode((byte[])o.get(k)));
+ }
+ } else {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ }
+ }
+}
+
diff --git a/base/migrate/62ToTxt/src/compile.bat b/base/migrate/62ToTxt/src/compile.bat
new file mode 100755
index 000000000..c6bfff97e
--- /dev/null
+++ b/base/migrate/62ToTxt/src/compile.bat
@@ -0,0 +1,150 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script creates the "62ToTxt/classes/Main.class" and
+REM "62ToTxt/classes/CMS62LdifParser.class" which are
+REM used to create a normalized CMS 6.2 ldif text file.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM Set SERVER_ROOT - identify the CMS <server_root> used to compile 62ToTxt
+REM
+
+REM SET SERVER_ROOT=C:\cms62
+
+
+REM
+REM Set JDK_VERSION - specify the JDK version used by this version of CMS
+REM
+REM CMS 6.2 NOTE: "WINNT" - 1.4.0
+REM
+
+REM SET JDK_VERSION=CMS_6.2
+
+
+REM
+REM Set JAVA_HOME - specify the complete path to the JDK
+REM
+REM example: \\bermuda.redhat.com\sbc mounted as Y:
+REM
+
+REM SET JAVA_HOME=Y:\cms_jdk\WINNT\%JDK_VERSION%
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 6.2"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0"
+ECHO.
+ECHO NOTE: No arguments are required to build the
+ECHO normalized %CMS% ldif text classes.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%JAVA_HOME%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and JAVA_HOME
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_JAVA_HOME
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified JAVA_HOME exists
+REM
+
+:CHECK_JAVA_HOME
+IF EXIST %JAVA_HOME% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified JAVA_HOME does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%JAVA_HOME%\bin;%JAVA_HOME%\lib;%PATH%
+
+
+REM
+REM Set TARGET - identify the complete path to the new classes target directory
+REM
+
+SET TARGET=..\classes
+
+
+REM
+REM Create the new classes target directory (if it does not already exist)
+REM
+
+IF EXIST %TARGET% goto COMPILE_CLASSES
+MKDIR %TARGET%
+
+
+REM
+REM Compile 62ToTxt - create "CMS62LdifParser.class" and "Main.class"
+REM
+
+:COMPILE_CLASSES
+%JAVA_HOME%\bin\javac.exe -d %TARGET% -classpath %JAVA_HOME%\jre\lib\rt.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar Main.java
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/62ToTxt/src/compile.sh b/base/migrate/62ToTxt/src/compile.sh
new file mode 100755
index 000000000..163d5e440
--- /dev/null
+++ b/base/migrate/62ToTxt/src/compile.sh
@@ -0,0 +1,160 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#####################################################################
+### ###
+### This script creates the "62ToTxt/classes/Main.class" and ###
+### "62ToTxt/classes/CMS62LdifParser.class" which are ###
+### used to create a normalized CMS 6.2 ldif text file. ###
+### ###
+#####################################################################
+
+
+###
+### Set SERVER_ROOT - identify the CMS <server_root> used to compile 62ToTxt
+###
+
+#SERVER_ROOT=/export/home/migrate/cms62
+#export SERVER_ROOT
+
+
+###
+### Set JDK_PLATFORM - must be "HP-UX", "Linux", or "SunOS"
+###
+
+#JDK_PLATFORM=SunOS
+#export JDK_PLATFORM
+
+
+###
+### Set JDK_VERSION - specify the JDK version used by this version of CMS
+###
+### CMS 6.2 NOTE: "HP-UX" - 1.4.0.00
+### "Linux" - 1.4.0
+### "SunOS" - 1.4.0
+###
+
+#JDK_VERSION=CMS_6.2
+#export JDK_VERSION
+
+
+###
+### Set JAVA_HOME - specify the complete path to the JDK
+###
+
+#JAVA_HOME=/share/builds/components/cms_jdk/${JDK_PLATFORM}/${JDK_VERSION}
+#export JAVA_HOME
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 6.2"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -gt 0 ] ; then
+ echo
+ echo "Usage: $0"
+ echo
+ echo " NOTE: No arguments are required to build the"
+ echo " normalized ${CMS} ldif text classes."
+ echo
+ exit 1
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${JAVA_HOME}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and JAVA_HOME "
+ echo " environment variables for this script!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 3
+fi
+
+
+###
+### Check that the specified JAVA_HOME exists and is a directory
+###
+
+if [ ! -d "${JAVA_HOME}" ] ; then
+ echo "ERROR: Either the specified JAVA_HOME does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 4
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Set TARGET - identify the complete path to the new classes target directory
+###
+
+TARGET=../classes
+export TARGET
+
+
+###
+### Create the new classes target directory (if it does not already exist)
+###
+
+if [ ! -d ${TARGET} ]; then
+ mkdir -p ${TARGET}
+fi
+
+
+###
+### Compile 62ToTxt - create "CMS62LdifParser.class" and "Main.class"
+###
+
+${JAVA_HOME}/bin/javac -d ${TARGET} -classpath ${JAVA_HOME}/jre/lib/rt.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar Main.java
+
diff --git a/base/migrate/63ToTxt/classes/CMS63LdifParser.class b/base/migrate/63ToTxt/classes/CMS63LdifParser.class
new file mode 100644
index 000000000..39dde5f50
--- /dev/null
+++ b/base/migrate/63ToTxt/classes/CMS63LdifParser.class
Binary files differ
diff --git a/base/migrate/63ToTxt/classes/Main.class b/base/migrate/63ToTxt/classes/Main.class
new file mode 100644
index 000000000..d8885bc11
--- /dev/null
+++ b/base/migrate/63ToTxt/classes/Main.class
Binary files differ
diff --git a/base/migrate/63ToTxt/run.bat b/base/migrate/63ToTxt/run.bat
new file mode 100755
index 000000000..34c9422c8
--- /dev/null
+++ b/base/migrate/63ToTxt/run.bat
@@ -0,0 +1,192 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM This program is free software; you can redistribute it and/or modify
+REM it under the terms of the GNU General Public License as published by
+REM the Free Software Foundation; version 2 of the License.
+REM
+REM This program is distributed in the hope that it will be useful,
+REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+REM GNU General Public License for more details.
+REM
+REM You should have received a copy of the GNU General Public License along
+REM with this program; if not, write to the Free Software Foundation, Inc.,
+REM 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script converts a pre-existing CMS 6.3 ldif data
+REM file (e. g. - created via a utility such as db2ldif)
+REM into a normalized CMS 6.3 ldif text file.
+REM
+REM This subsequent normalized CMS 6.3 ldif text file
+REM can be migrated into CMS 6.3 or later utilizing
+REM the corresponding TxtTo<Target CMS Version> script which
+REM converts this normalized CMS 6.3 ldif text file into
+REM a <Target CMS Version> ldif data file.
+REM
+REM This <Target CMS Version> ldif data file can then be
+REM imported into the internal database of the desired CMS
+REM server using a utility such as ldif2db.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM SERVER_ROOT - fully qualified path of the location of the server
+REM
+
+REM SET SERVER_ROOT=C:\cms63
+
+
+REM
+REM INSTANCE - if the CMS instance directory is called 'cert-ca',
+REM set the CMS instance to 'ca'
+REM
+REM NOTE: When a single SERVER_ROOT contains more than
+REM one CMS instance, this script must be run multiple
+REM times. To do this, there is only a need to change
+REM the INSTANCE parameter.
+REM
+
+REM SET INSTANCE=ca
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 6.3"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO USAGE
+IF "%3" == "" GOTO CHECK_INPUT_FILE
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0 input [errors] > output"
+ECHO.
+ECHO where: input - the specified %CMS% ldif data file,
+ECHO errors - an optional errors file containing
+ECHO skipped attributes, and
+ECHO output - the normalized %CMS% ldif text file.
+ECHO.
+ECHO NOTE: If no redirection is provided to
+ECHO 'output', then the normalized
+ECHO %CMS% ldif text will merely
+ECHO be echoed to stdout.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified "input" file exists
+REM
+
+:CHECK_INPUT_FILE
+IF EXIST %1 GOTO CHECK_ERRORS_FILE
+
+
+ECHO ERROR: The specified input file, %1, does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM If an "errors" file is specified, then check that it does not already
+REM exist.
+REM
+
+:CHECK_ERRORS_FILE
+IF "%2" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+IF EXIST %2 GOTO ERRORS_FILE_ERROR
+GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:ERRORS_FILE_ERROR
+ECHO ERROR: The specified errors file, %2, already exists!
+ECHO Please specify a different file!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%INSTANCE%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and INSTANCE
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_INSTANCE
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified INSTANCE exists
+REM
+
+:CHECK_INSTANCE
+IF EXIST %SERVER_ROOT%\cert-%INSTANCE% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified INSTANCE does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%SERVER_ROOT%\bin\cert\jre\bin;%SERVER_ROOT\bin\cert\jre\bin\server;%PATH%
+
+
+REM
+REM Convert the specified %CMS% ldif data file
+REM into a normalized %CMS% ldif text file.
+REM
+
+%SERVER_ROOT%\bin\cert\jre\bin\java.exe -classpath .\classes;%SERVER_ROOT%\cert-%INSTANCE%\classes;%SERVER_ROOT%\bin\cert\classes;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar;%SERVER_ROOT%\bin\cert\jre\lib\rt.jar Main %1 %2
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/63ToTxt/run.sh b/base/migrate/63ToTxt/run.sh
new file mode 100755
index 000000000..d4aa5d5a2
--- /dev/null
+++ b/base/migrate/63ToTxt/run.sh
@@ -0,0 +1,202 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+
+#####################################################################
+### ###
+### This script converts a pre-existing CMS 6.3 ldif data ###
+### file (e. g. - created via a utility such as db2ldif) ###
+### into a normalized CMS 6.3 ldif text file. ###
+### ###
+### This subsequent normalized CMS 6.3 ldif text file ###
+### can be migrated into CMS 6.3 or later utilizing ###
+### the corresponding TxtTo<Target CMS Version> script which ###
+### converts this normalized CMS 6.3 ldif text file into ###
+### a <Target CMS Version> ldif data file. ###
+### ###
+### This <Target CMS Version> ldif data file can then be ###
+### imported into the internal database of the desired CMS ###
+### server using a utility such as ldif2db. ###
+### ###
+#####################################################################
+
+
+###
+### SERVER_ROOT - fully qualified path of the location of the server
+###
+
+#SERVER_ROOT=/export/home/migrate/cms63
+#export SERVER_ROOT
+
+
+###
+### INSTANCE - if the CMS instance directory is called 'cert-ca',
+### set the CMS instance to 'ca'
+###
+### NOTE: When a single SERVER_ROOT contains more than
+### one CMS instance, this script must be run multiple
+### times. To do this, there is only a need to change
+### the INSTANCE parameter.
+###
+
+#INSTANCE=ca
+#export INSTANCE
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 6.3"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+##
+## Perform a usage check for the appropriate number of arguments:
+##
+
+if [ $# -lt 1 -o $# -gt 2 ] ; then
+ echo
+ echo "Usage: $0 input [errors] > output"
+ echo
+ echo " where: input - the specified ${CMS} ldif data file,"
+ echo " errors - an optional errors file containing"
+ echo " skipped attributes, and"
+ echo " output - the normalized ${CMS} ldif text file."
+ echo
+ echo " NOTE: If no redirection is provided to"
+ echo " 'output', then the normalized"
+ echo " ${CMS} ldif text will merely"
+ echo " be echoed to stdout."
+ echo
+ exit 1
+fi
+
+
+###
+### Check that the specified "input" file exists and is a regular file.
+###
+
+if [ ! -f $1 ] ; then
+ echo "ERROR: Either the specified 'input' file, '$1', does not exist, "
+ echo " or it is not a regular file!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified "input" file exists and is not empty.
+###
+
+if [ ! -s $1 ] ; then
+ echo "ERROR: The specified 'input' file, '$1', is empty!"
+ echo
+ exit 3
+fi
+
+
+###
+### If an "errors" file is specified, then check that it does not already
+### exist.
+###
+
+if [ $# -eq 2 ] ; then
+ if [ -f $2 ] ; then
+ echo "ERROR: The specified 'errors' file, '$2', already exists!"
+ echo " Please specify a different file!"
+ echo
+ exit 4
+ fi
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${INSTANCE}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and INSTANCE "
+ echo " environment variables for this script!"
+ echo
+ exit 5
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 6
+fi
+
+
+###
+### Check that the specified INSTANCE exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}/cert-${INSTANCE}" ] ; then
+ echo "ERROR: Either the specified INSTANCE does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 7
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Convert the specified ${CMS} ldif data file
+### into a normalized ${CMS} ldif text file.
+###
+### NOTE: As of SunOS JDK 1.4.0, the required "Unicode" classes
+### have been moved from "i18n.jar" to "rt.jar".
+###
+
+${SERVER_ROOT}/bin/cert/jre/bin/java -classpath ./classes:${SERVER_ROOT}/cert-${INSTANCE}/classes:${SERVER_ROOT}/bin/cert/classes:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar:${SERVER_ROOT}/bin/cert/jre/lib/rt.jar Main $1 $2
+
diff --git a/base/migrate/63ToTxt/src/Main.java b/base/migrate/63ToTxt/src/Main.java
new file mode 100644
index 000000000..6066801e2
--- /dev/null
+++ b/base/migrate/63ToTxt/src/Main.java
@@ -0,0 +1,483 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+//
+// "63ToTxt/src/Main.java" is based upon a copy "62ToTxt/src/Main.java".
+//
+// Always comment any new code sections with a "CMS 6.3" header, and
+// apply these changes forward to all other "*ToTxt/src/Main.java" files
+// (including this comment header) so that these differences will only
+// appear when this file is diffed against an earlier "*ToTxt" version.
+//
+// This file should always be maintained by executing the following command:
+//
+// diff 62ToTxt/src/Main.java 63ToTxt/src/Main.java
+//
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+import sun.misc.*;
+import org.mozilla.jss.*; // CMS 4.5 and later
+import org.mozilla.jss.crypto.*; // CMS 4.5 and later
+import netscape.security.util.*;
+
+public class Main
+{
+ public static void main(String args[])
+ {
+ try {
+ // initialize CryptoManager in CMS 4.5 and later
+ CryptoManager.initialize(".");
+ // load JSS provider in CMS 4.5 and later
+ java.security.Security.removeProvider("SUN version 1.2");
+ // The following call to "java.security.Security.insertProviderAt()"
+ // is no longer commented out in CMS 4.5 and later
+ java.security.Security.insertProviderAt(
+ new netscape.security.provider.CMS(), 0);
+ java.security.Provider ps[] =
+ java.security.Security.getProviders();
+ if (ps == null || ps.length <= 0) {
+ System.err.println("Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ System.err.println("Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+
+ // Parse the File
+ CMS63LdifParser parser = null;
+ if (args.length == 1) {
+ parser = new CMS63LdifParser(args[0]);
+ } else if (args.length == 2) {
+ parser = new CMS63LdifParser(args[0], args[1]);
+ } else {
+ throw new IOException("Invalid Parameters");
+ }
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+}
+
+class CMS63LdifParser
+{
+ // constants
+ private static final String DN =
+ "dn:";
+ // Directory Servers in CMS 4.7 and later use "requestAttributes"
+ private static final String REQUEST_ATTRIBUTES =
+ "requestAttributes::";
+ private static final String BEGIN =
+ "--- BEGIN ATTRIBUTES ---";
+ private static final String END =
+ "--- END ATTRIBUTES ---";
+
+ // variables
+ private String mFilename = null;
+ private String mErrorFilename = null;
+ private PrintWriter mErrorPrintWriter = null;
+
+ public CMS63LdifParser(String filename)
+ {
+ mFilename = filename;
+ }
+
+ public CMS63LdifParser(String filename, String errorFilename)
+ {
+ mFilename = filename;
+ mErrorFilename = errorFilename;
+ }
+
+ public void parse() throws Exception
+ {
+ if (mErrorFilename != null) {
+ mErrorPrintWriter = new PrintWriter(new FileOutputStream(mErrorFilename));
+ }
+ BufferedReader reader = new BufferedReader(
+ new FileReader(mFilename));
+ String line = null;
+ String dn = null;
+ StringBuffer requestAttributes = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DN)) {
+ dn = line;
+ }
+ if (line.startsWith(REQUEST_ATTRIBUTES)) {
+ requestAttributes = new StringBuffer();
+ // System.out.println(line);
+ requestAttributes.append(
+ line.substring(REQUEST_ATTRIBUTES.length(),
+ line.length()).trim());
+ continue;
+ }
+ if (requestAttributes == null) {
+ System.out.println(line);
+ continue;
+ }
+ if (line.startsWith(" ")) {
+ // System.out.println(line);
+ requestAttributes.append(line.trim());
+ } else {
+ parseAttributes(dn, requestAttributes);
+ requestAttributes = null;
+ System.out.println(line);
+ }
+ }
+ }
+
+ public void parseAttributes(String dn, StringBuffer attrs) throws Exception
+ {
+ BASE64Decoder decoder = new BASE64Decoder();
+ decodeHashtable(dn, decoder.decodeBuffer(attrs.toString()));
+
+// System.out.println(attrs);
+ }
+
+ public Object decode(byte[] data) throws
+ ObjectStreamException,
+ IOException,
+ ClassNotFoundException
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+ return is.readObject();
+ }
+
+ public void decodeHashtable(String dn, byte[] data) throws Exception
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+
+ System.out.println(BEGIN);
+ String key = null;
+ while (true)
+ {
+ key = (String)is.readObject();
+ // end of table is marked with null
+ if (key == null) break;
+ try {
+ byte[] bytes = (byte[])is.readObject();
+ Object obj = decode(bytes);
+ output(key, obj);
+ } catch (Exception e) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + key);
+ }
+ }
+ }
+ System.out.println(END);
+ }
+
+ public void output(String key, Object obj) throws Exception
+ {
+ if (obj instanceof String) {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ } else if (obj instanceof netscape.security.x509.CertificateX509Key) {
+ netscape.security.x509.CertificateX509Key o =
+ (netscape.security.x509.CertificateX509Key)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateSubjectName) {
+ netscape.security.x509.CertificateSubjectName o =
+ (netscape.security.x509.CertificateSubjectName)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateExtensions) {
+ netscape.security.x509.CertificateExtensions o =
+ (netscape.security.x509.CertificateExtensions)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertInfo) {
+ netscape.security.x509.X509CertInfo o =
+ (netscape.security.x509.X509CertInfo)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl) {
+ netscape.security.x509.X509CertImpl o =
+ (netscape.security.x509.X509CertImpl)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateChain) {
+ netscape.security.x509.CertificateChain o =
+ (netscape.security.x509.CertificateChain)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl[]) {
+ netscape.security.x509.X509CertImpl o[] =
+ (netscape.security.x509.X509CertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.X509CertInfo[]) {
+ netscape.security.x509.X509CertInfo o[] =
+ (netscape.security.x509.X509CertInfo[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() + "["+o.length + "," + i+"]"+"=" +
+ encoder.encodeBuffer(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.RevokedCertImpl[]) {
+ netscape.security.x509.RevokedCertImpl o[] =
+ (netscape.security.x509.RevokedCertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ DerOutputStream bos =
+ new DerOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof java.security.cert.Certificate[]) {
+ java.security.cert.Certificate o[] =
+ (java.security.cert.Certificate[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(o[i].getEncoded()));
+ }
+ } else if (obj instanceof com.netscape.cmscore.base.ArgBlock) {
+ // CMS 6.1: created new "com.netscape.certsrv.base.IArgBlock" and
+ // moved old "com.netscape.certsrv.base.ArgBlock"
+ // to "com.netscape.cmscore.base.ArgBlock"
+ com.netscape.cmscore.base.ArgBlock o =
+ (com.netscape.cmscore.base.ArgBlock)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" +(String)o.get(k));
+ }
+ } else if (obj instanceof com.netscape.cmscore.dbs.KeyRecord) {
+ // CMS 6.0: moved "com.netscape.certsrv.dbs.keydb.KeyRecord"
+ // to "com.netscape.cmscore.dbs.KeyRecord"
+ com.netscape.cmscore.dbs.KeyRecord o =
+ (com.netscape.cmscore.dbs.KeyRecord)obj;
+ Enumeration<String> e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = e.nextElement();
+ Object ob = o.get(k);
+ if (ob != null) {
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + encoder.encode((byte[])ob));
+
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ }
+ } else if (obj instanceof com.netscape.cmscore.kra.ProofOfArchival) {
+ // CMS 6.0: moved "com.netscape.certsrv.kra.ProofOfArchival"
+ // to "com.netscape.cmscore.kra.ProofOfArchival"
+ com.netscape.cmscore.kra.ProofOfArchival o =
+ (com.netscape.cmscore.kra.ProofOfArchival)obj;
+ DerOutputStream bos =
+ new DerOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof com.netscape.certsrv.request.AgentApprovals) {
+ com.netscape.certsrv.request.AgentApprovals o =
+ (com.netscape.certsrv.request.AgentApprovals)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ com.netscape.certsrv.request.AgentApproval approval = (com.netscape.certsrv.request.AgentApproval)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ approval.getUserName() + ";" + approval.getDate().getTime());
+ }
+ } else if (obj instanceof com.netscape.certsrv.authentication.AuthToken) {
+ com.netscape.certsrv.authentication.AuthToken o =
+ (com.netscape.certsrv.authentication.AuthToken)obj;
+ Enumeration e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ Object ob = o.get(k);
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof java.math.BigInteger[]) {
+ // Bugzilla Bug #225031 (a.k.a. - Raidzilla Bug #58356)
+ java.math.BigInteger in[] = (java.math.BigInteger[])ob;
+ String numbers = "";
+ for (int i = 0; i < in.length; i++) {
+ if (numbers.equals("")) {
+ numbers = in[i].toString();
+ } else {
+ numbers = numbers + "," + in[i].toString();
+ }
+ }
+ System.out.println(" " +
+ key + ":" + "com.netscape.certsrv.authentication.AuthToken" + "=" +
+ k + ":java.lang.String=" + numbers);
+ } else if (ob instanceof String[]) {
+ // Bugzilla Bug #224763 (a.k.a. - Raidzilla Bug #57949)
+ // Bugzilla Bug #252240
+ String str[] = (String[])ob;
+ String v = "";
+ if (str != null) {
+ for (int i = 0; i < str.length; i++) {
+ if (i != 0) {
+ v += ",";
+ }
+ v += str[i];
+ }
+ }
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + "java.lang.String" + "=" + v);
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ } else if (obj instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key + ":byte[]="+
+ encoder.encode((byte[])obj));
+ } else if (obj instanceof Integer[]) {
+ Integer in[] = (Integer[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":Integer[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof BigInteger[]) {
+ // Bugzilla Bug #238779
+ BigInteger in[] = (BigInteger[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":java.math.BigInteger[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof String[]) {
+ // Bugzilla Bug #223360 (a.k.a - Raidzilla Bug #58086)
+ String str[] = (String[])obj;
+ for (int i = 0; i < str.length; i++) {
+ System.out.println(" " + key + ":java.lang.String[" + str.length + "," + i + "]="+ str[i]);
+ }
+ } else if (obj instanceof netscape.security.x509.CertificateAlgorithmId) {
+ netscape.security.x509.CertificateAlgorithmId o =
+ (netscape.security.x509.CertificateAlgorithmId)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateAlgorithmId="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateValidity) {
+ netscape.security.x509.CertificateValidity o =
+ (netscape.security.x509.CertificateValidity)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateValidity="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof byte[]) {
+ // Since 6.1's profile framework,
+ // req_archive_options is a byte array
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":byte[]="+
+ encoder.encode((byte[])obj));
+ } else if (obj instanceof java.util.Hashtable) {
+ // Bugzilla Bug #224800 (a.k.a - Raidzilla Bug #56953)
+ //
+ // Example: fingerprints:java.util.Hashtable=
+ // {SHA1=[B@52513a, MD5=[B@52c4d9, MD2=[B@799ff5}
+ //
+ java.util.Hashtable o = (java.util.Hashtable)obj;
+ BASE64Encoder encoder = new BASE64Encoder();
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" + encoder.encode((byte[])o.get(k)));
+ }
+ } else {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ }
+ }
+}
+
diff --git a/base/migrate/63ToTxt/src/compile.bat b/base/migrate/63ToTxt/src/compile.bat
new file mode 100755
index 000000000..f587dd7e8
--- /dev/null
+++ b/base/migrate/63ToTxt/src/compile.bat
@@ -0,0 +1,150 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script creates the "63ToTxt/classes/Main.class" and
+REM "63ToTxt/classes/CMS63LdifParser.class" which are
+REM used to create a normalized CMS 6.3 ldif text file.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM Set SERVER_ROOT - identify the CMS <server_root> used to compile 63ToTxt
+REM
+
+REM SET SERVER_ROOT=C:\cms63
+
+
+REM
+REM Set JDK_VERSION - specify the JDK version used by this version of CMS
+REM
+REM CMS 6.3 NOTE: "WINNT" - 1.4.2
+REM
+
+REM SET JDK_VERSION=CMS_6.3
+
+
+REM
+REM Set JAVA_HOME - specify the complete path to the JDK
+REM
+REM example: \\bermuda.redhat.com\sbc mounted as Y:
+REM
+
+REM SET JAVA_HOME=Y:\cms_jdk\WINNT\%JDK_VERSION%
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 6.3"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0"
+ECHO.
+ECHO NOTE: No arguments are required to build the
+ECHO normalized %CMS% ldif text classes.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%JAVA_HOME%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and JAVA_HOME
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_JAVA_HOME
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified JAVA_HOME exists
+REM
+
+:CHECK_JAVA_HOME
+IF EXIST %JAVA_HOME% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified JAVA_HOME does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%JAVA_HOME%\bin;%JAVA_HOME%\lib;%PATH%
+
+
+REM
+REM Set TARGET - identify the complete path to the new classes target directory
+REM
+
+SET TARGET=..\classes
+
+
+REM
+REM Create the new classes target directory (if it does not already exist)
+REM
+
+IF EXIST %TARGET% goto COMPILE_CLASSES
+MKDIR %TARGET%
+
+
+REM
+REM Compile 63ToTxt - create "CMS63LdifParser.class" and "Main.class"
+REM
+
+:COMPILE_CLASSES
+%JAVA_HOME%\bin\javac.exe -d %TARGET% -classpath %JAVA_HOME%\jre\lib\rt.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar Main.java
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/63ToTxt/src/compile.sh b/base/migrate/63ToTxt/src/compile.sh
new file mode 100755
index 000000000..57b9c7718
--- /dev/null
+++ b/base/migrate/63ToTxt/src/compile.sh
@@ -0,0 +1,160 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#####################################################################
+### ###
+### This script creates the "63ToTxt/classes/Main.class" and ###
+### "63ToTxt/classes/CMS63LdifParser.class" which are ###
+### used to create a normalized CMS 6.3 ldif text file. ###
+### ###
+#####################################################################
+
+
+###
+### Set SERVER_ROOT - identify the CMS <server_root> used to compile 63ToTxt
+###
+
+#SERVER_ROOT=/export/home/migrate/cms63
+#export SERVER_ROOT
+
+
+###
+### Set JDK_PLATFORM - must be "HP-UX", "Linux", or "SunOS"
+###
+
+#JDK_PLATFORM=SunOS
+#export JDK_PLATFORM
+
+
+###
+### Set JDK_VERSION - specify the JDK version used by this version of CMS
+###
+### CMS 6.3 NOTE: "HP-UX" - 1.4.0.00
+### "Linux" - 1.4.2
+### "SunOS" - 1.4.2
+###
+
+#JDK_VERSION=CMS_6.3
+#export JDK_VERSION
+
+
+###
+### Set JAVA_HOME - specify the complete path to the JDK
+###
+
+#JAVA_HOME=/share/builds/components/cms_jdk/${JDK_PLATFORM}/${JDK_VERSION}
+#export JAVA_HOME
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 6.3"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -gt 0 ] ; then
+ echo
+ echo "Usage: $0"
+ echo
+ echo " NOTE: No arguments are required to build the"
+ echo " normalized ${CMS} ldif text classes."
+ echo
+ exit 1
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${JAVA_HOME}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and JAVA_HOME "
+ echo " environment variables for this script!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 3
+fi
+
+
+###
+### Check that the specified JAVA_HOME exists and is a directory
+###
+
+if [ ! -d "${JAVA_HOME}" ] ; then
+ echo "ERROR: Either the specified JAVA_HOME does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 4
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Set TARGET - identify the complete path to the new classes target directory
+###
+
+TARGET=../classes
+export TARGET
+
+
+###
+### Create the new classes target directory (if it does not already exist)
+###
+
+if [ ! -d ${TARGET} ]; then
+ mkdir -p ${TARGET}
+fi
+
+
+###
+### Compile 63ToTxt - create "CMS63LdifParser.class" and "Main.class"
+###
+
+${JAVA_HOME}/bin/javac -d ${TARGET} -classpath ${JAVA_HOME}/jre/lib/rt.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar Main.java
+
diff --git a/base/migrate/70ToTxt/classes/CMS70LdifParser.class b/base/migrate/70ToTxt/classes/CMS70LdifParser.class
new file mode 100644
index 000000000..e6900f5aa
--- /dev/null
+++ b/base/migrate/70ToTxt/classes/CMS70LdifParser.class
Binary files differ
diff --git a/base/migrate/70ToTxt/classes/Main.class b/base/migrate/70ToTxt/classes/Main.class
new file mode 100644
index 000000000..0743af44a
--- /dev/null
+++ b/base/migrate/70ToTxt/classes/Main.class
Binary files differ
diff --git a/base/migrate/70ToTxt/run.bat b/base/migrate/70ToTxt/run.bat
new file mode 100755
index 000000000..3adeee6f9
--- /dev/null
+++ b/base/migrate/70ToTxt/run.bat
@@ -0,0 +1,192 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM This program is free software; you can redistribute it and/or modify
+REM it under the terms of the GNU General Public License as published by
+REM the Free Software Foundation; version 2 of the License.
+REM
+REM This program is distributed in the hope that it will be useful,
+REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+REM GNU General Public License for more details.
+REM
+REM You should have received a copy of the GNU General Public License along
+REM with this program; if not, write to the Free Software Foundation, Inc.,
+REM 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script converts a pre-existing CMS 7.0 ldif data
+REM file (e. g. - created via a utility such as db2ldif)
+REM into a normalized CMS 7.0 ldif text file.
+REM
+REM This subsequent normalized CMS 7.0 ldif text file
+REM can be migrated into CMS 7.0 or later utilizing
+REM the corresponding TxtTo<Target CMS Version> script which
+REM converts this normalized CMS 7.0 ldif text file into
+REM a <Target CMS Version> ldif data file.
+REM
+REM This <Target CMS Version> ldif data file can then be
+REM imported into the internal database of the desired CMS
+REM server using a utility such as ldif2db.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM SERVER_ROOT - fully qualified path of the location of the server
+REM
+
+REM SET SERVER_ROOT=C:\cms70
+
+
+REM
+REM INSTANCE - if the CMS instance directory is called 'cert-ca',
+REM set the CMS instance to 'ca'
+REM
+REM NOTE: When a single SERVER_ROOT contains more than
+REM one CMS instance, this script must be run multiple
+REM times. To do this, there is only a need to change
+REM the INSTANCE parameter.
+REM
+
+REM SET INSTANCE=ca
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 7.0"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO USAGE
+IF "%3" == "" GOTO CHECK_INPUT_FILE
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0 input [errors] > output"
+ECHO.
+ECHO where: input - the specified %CMS% ldif data file,
+ECHO errors - an optional errors file containing
+ECHO skipped attributes, and
+ECHO output - the normalized %CMS% ldif text file.
+ECHO.
+ECHO NOTE: If no redirection is provided to
+ECHO 'output', then the normalized
+ECHO %CMS% ldif text will merely
+ECHO be echoed to stdout.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified "input" file exists
+REM
+
+:CHECK_INPUT_FILE
+IF EXIST %1 GOTO CHECK_ERRORS_FILE
+
+
+ECHO ERROR: The specified input file, %1, does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM If an "errors" file is specified, then check that it does not already
+REM exist.
+REM
+
+:CHECK_ERRORS_FILE
+IF "%2" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+IF EXIST %2 GOTO ERRORS_FILE_ERROR
+GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:ERRORS_FILE_ERROR
+ECHO ERROR: The specified errors file, %2, already exists!
+ECHO Please specify a different file!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%INSTANCE%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and INSTANCE
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_INSTANCE
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified INSTANCE exists
+REM
+
+:CHECK_INSTANCE
+IF EXIST %SERVER_ROOT%\cert-%INSTANCE% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified INSTANCE does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%SERVER_ROOT%\bin\cert\jre\bin;%SERVER_ROOT\bin\cert\jre\bin\server;%PATH%
+
+
+REM
+REM Convert the specified %CMS% ldif data file
+REM into a normalized %CMS% ldif text file.
+REM
+
+%SERVER_ROOT%\bin\cert\jre\bin\java.exe -classpath .\classes;%SERVER_ROOT%\cert-%INSTANCE%\classes;%SERVER_ROOT%\bin\cert\classes;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar;%SERVER_ROOT%\bin\cert\jre\lib\rt.jar Main %1 %2
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/70ToTxt/run.sh b/base/migrate/70ToTxt/run.sh
new file mode 100755
index 000000000..294bb63c7
--- /dev/null
+++ b/base/migrate/70ToTxt/run.sh
@@ -0,0 +1,202 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+
+#####################################################################
+### ###
+### This script converts a pre-existing CMS 7.0/7.01 ldif data ###
+### file (e. g. - created via a utility such as db2ldif) ###
+### into a normalized CMS 7.0/7.01 ldif text file. ###
+### ###
+### This subsequent normalized CMS 7.0/7.01 ldif text file ###
+### can be migrated into CMS 7.0/7.01 or later utilizing ###
+### the corresponding TxtTo<Target CMS Version> script which ###
+### converts this normalized CMS 7.0/7.01 ldif text file into ###
+### a <Target CMS Version> ldif data file. ###
+### ###
+### This <Target CMS Version> ldif data file can then be ###
+### imported into the internal database of the desired CMS ###
+### server using a utility such as ldif2db. ###
+### ###
+#####################################################################
+
+
+###
+### SERVER_ROOT - fully qualified path of the location of the server
+###
+
+#SERVER_ROOT=/export/home/migrate/cms701
+#export SERVER_ROOT
+
+
+###
+### INSTANCE - if the CMS instance directory is called 'cert-ca',
+### set the CMS instance to 'ca'
+###
+### NOTE: When a single SERVER_ROOT contains more than
+### one CMS instance, this script must be run multiple
+### times. To do this, there is only a need to change
+### the INSTANCE parameter.
+###
+
+#INSTANCE=ca
+#export INSTANCE
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 7.0"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+##
+## Perform a usage check for the appropriate number of arguments:
+##
+
+if [ $# -lt 1 -o $# -gt 2 ] ; then
+ echo
+ echo "Usage: $0 input [errors] > output"
+ echo
+ echo " where: input - the specified ${CMS} ldif data file,"
+ echo " errors - an optional errors file containing"
+ echo " skipped attributes, and"
+ echo " output - the normalized ${CMS} ldif text file."
+ echo
+ echo " NOTE: If no redirection is provided to"
+ echo " 'output', then the normalized"
+ echo " ${CMS} ldif text will merely"
+ echo " be echoed to stdout."
+ echo
+ exit 1
+fi
+
+
+###
+### Check that the specified "input" file exists and is a regular file.
+###
+
+if [ ! -f $1 ] ; then
+ echo "ERROR: Either the specified 'input' file, '$1', does not exist, "
+ echo " or it is not a regular file!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified "input" file exists and is not empty.
+###
+
+if [ ! -s $1 ] ; then
+ echo "ERROR: The specified 'input' file, '$1', is empty!"
+ echo
+ exit 3
+fi
+
+
+###
+### If an "errors" file is specified, then check that it does not already
+### exist.
+###
+
+if [ $# -eq 2 ] ; then
+ if [ -f $2 ] ; then
+ echo "ERROR: The specified 'errors' file, '$2', already exists!"
+ echo " Please specify a different file!"
+ echo
+ exit 4
+ fi
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${INSTANCE}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and INSTANCE "
+ echo " environment variables for this script!"
+ echo
+ exit 5
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 6
+fi
+
+
+###
+### Check that the specified INSTANCE exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}/cert-${INSTANCE}" ] ; then
+ echo "ERROR: Either the specified INSTANCE does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 7
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Convert the specified ${CMS} ldif data file
+### into a normalized ${CMS} ldif text file.
+###
+### NOTE: As of SunOS JDK 1.4.0, the required "Unicode" classes
+### have been moved from "i18n.jar" to "rt.jar".
+###
+
+${SERVER_ROOT}/bin/cert/jre/bin/java -classpath ./classes:${SERVER_ROOT}/cert-${INSTANCE}/classes:${SERVER_ROOT}/bin/cert/classes:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar:${SERVER_ROOT}/bin/cert/jre/lib/rt.jar Main $1 $2
+
diff --git a/base/migrate/70ToTxt/src/Main.java b/base/migrate/70ToTxt/src/Main.java
new file mode 100644
index 000000000..133671267
--- /dev/null
+++ b/base/migrate/70ToTxt/src/Main.java
@@ -0,0 +1,483 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+//
+// "70ToTxt/src/Main.java" is based upon a copy "62ToTxt/src/Main.java".
+//
+// Always comment any new code sections with a "CMS 7.0" header, and
+// apply these changes forward to all other "*ToTxt/src/Main.java" files
+// (including this comment header) so that these differences will only
+// appear when this file is diffed against an earlier "*ToTxt" version.
+//
+// This file should always be maintained by executing the following command:
+//
+// diff 62ToTxt/src/Main.java 70ToTxt/src/Main.java
+//
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+import sun.misc.*;
+import org.mozilla.jss.*; // CMS 4.5 and later
+import org.mozilla.jss.crypto.*; // CMS 4.5 and later
+import netscape.security.util.*;
+
+public class Main
+{
+ public static void main(String args[])
+ {
+ try {
+ // initialize CryptoManager in CMS 4.5 and later
+ CryptoManager.initialize(".");
+ // load JSS provider in CMS 4.5 and later
+ java.security.Security.removeProvider("SUN version 1.2");
+ // The following call to "java.security.Security.insertProviderAt()"
+ // is no longer commented out in CMS 4.5 and later
+ java.security.Security.insertProviderAt(
+ new netscape.security.provider.CMS(), 0);
+ java.security.Provider ps[] =
+ java.security.Security.getProviders();
+ if (ps == null || ps.length <= 0) {
+ System.err.println("Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ System.err.println("Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+
+ // Parse the File
+ CMS70LdifParser parser = null;
+ if (args.length == 1) {
+ parser = new CMS70LdifParser(args[0]);
+ } else if (args.length == 2) {
+ parser = new CMS70LdifParser(args[0], args[1]);
+ } else {
+ throw new IOException("Invalid Parameters");
+ }
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+}
+
+class CMS70LdifParser
+{
+ // constants
+ private static final String DN =
+ "dn:";
+ // Directory Servers in CMS 4.7 and later use "requestAttributes"
+ private static final String REQUEST_ATTRIBUTES =
+ "requestAttributes::";
+ private static final String BEGIN =
+ "--- BEGIN ATTRIBUTES ---";
+ private static final String END =
+ "--- END ATTRIBUTES ---";
+
+ // variables
+ private String mFilename = null;
+ private String mErrorFilename = null;
+ private PrintWriter mErrorPrintWriter = null;
+
+ public CMS70LdifParser(String filename)
+ {
+ mFilename = filename;
+ }
+
+ public CMS70LdifParser(String filename, String errorFilename)
+ {
+ mFilename = filename;
+ mErrorFilename = errorFilename;
+ }
+
+ public void parse() throws Exception
+ {
+ if (mErrorFilename != null) {
+ mErrorPrintWriter = new PrintWriter(new FileOutputStream(mErrorFilename));
+ }
+ BufferedReader reader = new BufferedReader(
+ new FileReader(mFilename));
+ String line = null;
+ String dn = null;
+ StringBuffer requestAttributes = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DN)) {
+ dn = line;
+ }
+ if (line.startsWith(REQUEST_ATTRIBUTES)) {
+ requestAttributes = new StringBuffer();
+ // System.out.println(line);
+ requestAttributes.append(
+ line.substring(REQUEST_ATTRIBUTES.length(),
+ line.length()).trim());
+ continue;
+ }
+ if (requestAttributes == null) {
+ System.out.println(line);
+ continue;
+ }
+ if (line.startsWith(" ")) {
+ // System.out.println(line);
+ requestAttributes.append(line.trim());
+ } else {
+ parseAttributes(dn, requestAttributes);
+ requestAttributes = null;
+ System.out.println(line);
+ }
+ }
+ }
+
+ public void parseAttributes(String dn, StringBuffer attrs) throws Exception
+ {
+ BASE64Decoder decoder = new BASE64Decoder();
+ decodeHashtable(dn, decoder.decodeBuffer(attrs.toString()));
+
+// System.out.println(attrs);
+ }
+
+ public Object decode(byte[] data) throws
+ ObjectStreamException,
+ IOException,
+ ClassNotFoundException
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+ return is.readObject();
+ }
+
+ public void decodeHashtable(String dn, byte[] data) throws Exception
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+
+ System.out.println(BEGIN);
+ String key = null;
+ while (true)
+ {
+ key = (String)is.readObject();
+ // end of table is marked with null
+ if (key == null) break;
+ try {
+ byte[] bytes = (byte[])is.readObject();
+ Object obj = decode(bytes);
+ output(key, obj);
+ } catch (Exception e) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + key);
+ }
+ }
+ }
+ System.out.println(END);
+ }
+
+ public void output(String key, Object obj) throws Exception
+ {
+ if (obj instanceof String) {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ } else if (obj instanceof netscape.security.x509.CertificateX509Key) {
+ netscape.security.x509.CertificateX509Key o =
+ (netscape.security.x509.CertificateX509Key)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateSubjectName) {
+ netscape.security.x509.CertificateSubjectName o =
+ (netscape.security.x509.CertificateSubjectName)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateExtensions) {
+ netscape.security.x509.CertificateExtensions o =
+ (netscape.security.x509.CertificateExtensions)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertInfo) {
+ netscape.security.x509.X509CertInfo o =
+ (netscape.security.x509.X509CertInfo)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl) {
+ netscape.security.x509.X509CertImpl o =
+ (netscape.security.x509.X509CertImpl)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateChain) {
+ netscape.security.x509.CertificateChain o =
+ (netscape.security.x509.CertificateChain)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl[]) {
+ netscape.security.x509.X509CertImpl o[] =
+ (netscape.security.x509.X509CertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.X509CertInfo[]) {
+ netscape.security.x509.X509CertInfo o[] =
+ (netscape.security.x509.X509CertInfo[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() + "["+o.length + "," + i+"]"+"=" +
+ encoder.encodeBuffer(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.RevokedCertImpl[]) {
+ netscape.security.x509.RevokedCertImpl o[] =
+ (netscape.security.x509.RevokedCertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ DerOutputStream bos =
+ new DerOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof java.security.cert.Certificate[]) {
+ java.security.cert.Certificate o[] =
+ (java.security.cert.Certificate[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(o[i].getEncoded()));
+ }
+ } else if (obj instanceof com.netscape.cmscore.base.ArgBlock) {
+ // CMS 6.1: created new "com.netscape.certsrv.base.IArgBlock" and
+ // moved old "com.netscape.certsrv.base.ArgBlock"
+ // to "com.netscape.cmscore.base.ArgBlock"
+ com.netscape.cmscore.base.ArgBlock o =
+ (com.netscape.cmscore.base.ArgBlock)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" +(String)o.get(k));
+ }
+ } else if (obj instanceof com.netscape.cmscore.dbs.KeyRecord) {
+ // CMS 6.0: moved "com.netscape.certsrv.dbs.keydb.KeyRecord"
+ // to "com.netscape.cmscore.dbs.KeyRecord"
+ com.netscape.cmscore.dbs.KeyRecord o =
+ (com.netscape.cmscore.dbs.KeyRecord)obj;
+ Enumeration<String> e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = e.nextElement();
+ Object ob = o.get(k);
+ if (ob != null) {
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + encoder.encode((byte[])ob));
+
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ }
+ } else if (obj instanceof com.netscape.cmscore.kra.ProofOfArchival) {
+ // CMS 6.0: moved "com.netscape.certsrv.kra.ProofOfArchival"
+ // to "com.netscape.cmscore.kra.ProofOfArchival"
+ com.netscape.cmscore.kra.ProofOfArchival o =
+ (com.netscape.cmscore.kra.ProofOfArchival)obj;
+ DerOutputStream bos =
+ new DerOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof com.netscape.certsrv.request.AgentApprovals) {
+ com.netscape.certsrv.request.AgentApprovals o =
+ (com.netscape.certsrv.request.AgentApprovals)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ com.netscape.certsrv.request.AgentApproval approval = (com.netscape.certsrv.request.AgentApproval)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ approval.getUserName() + ";" + approval.getDate().getTime());
+ }
+ } else if (obj instanceof com.netscape.certsrv.authentication.AuthToken) {
+ com.netscape.certsrv.authentication.AuthToken o =
+ (com.netscape.certsrv.authentication.AuthToken)obj;
+ Enumeration e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ Object ob = o.get(k);
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof java.math.BigInteger[]) {
+ // Bugzilla Bug #225031 (a.k.a. - Raidzilla Bug #58356)
+ java.math.BigInteger in[] = (java.math.BigInteger[])ob;
+ String numbers = "";
+ for (int i = 0; i < in.length; i++) {
+ if (numbers.equals("")) {
+ numbers = in[i].toString();
+ } else {
+ numbers = numbers + "," + in[i].toString();
+ }
+ }
+ System.out.println(" " +
+ key + ":" + "com.netscape.certsrv.authentication.AuthToken" + "=" +
+ k + ":java.lang.String=" + numbers);
+ } else if (ob instanceof String[]) {
+ // Bugzilla Bug #224763 (a.k.a. - Raidzilla Bug #57949)
+ // Bugzilla Bug #252240
+ String str[] = (String[])ob;
+ String v = "";
+ if (str != null) {
+ for (int i = 0; i < str.length; i++) {
+ if (i != 0) {
+ v += ",";
+ }
+ v += str[i];
+ }
+ }
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + "java.lang.String" + "=" + v);
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ } else if (obj instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key + ":byte[]="+
+ encoder.encode((byte[])obj));
+ } else if (obj instanceof Integer[]) {
+ Integer in[] = (Integer[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":Integer[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof BigInteger[]) {
+ // Bugzilla Bug #238779
+ BigInteger in[] = (BigInteger[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":java.math.BigInteger[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof String[]) {
+ // Bugzilla Bug #223360 (a.k.a - Raidzilla Bug #58086)
+ String str[] = (String[])obj;
+ for (int i = 0; i < str.length; i++) {
+ System.out.println(" " + key + ":java.lang.String[" + str.length + "," + i + "]="+ str[i]);
+ }
+ } else if (obj instanceof netscape.security.x509.CertificateAlgorithmId) {
+ netscape.security.x509.CertificateAlgorithmId o =
+ (netscape.security.x509.CertificateAlgorithmId)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateAlgorithmId="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateValidity) {
+ netscape.security.x509.CertificateValidity o =
+ (netscape.security.x509.CertificateValidity)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateValidity="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof byte[]) {
+ // Since 6.1's profile framework,
+ // req_archive_options is a byte array
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":byte[]="+
+ encoder.encode((byte[])obj));
+ } else if (obj instanceof java.util.Hashtable) {
+ // Bugzilla Bug #224800 (a.k.a - Raidzilla Bug #56953)
+ //
+ // Example: fingerprints:java.util.Hashtable=
+ // {SHA1=[B@52513a, MD5=[B@52c4d9, MD2=[B@799ff5}
+ //
+ java.util.Hashtable o = (java.util.Hashtable)obj;
+ BASE64Encoder encoder = new BASE64Encoder();
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" + encoder.encode((byte[])o.get(k)));
+ }
+ } else {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ }
+ }
+}
+
diff --git a/base/migrate/70ToTxt/src/compile.bat b/base/migrate/70ToTxt/src/compile.bat
new file mode 100755
index 000000000..164cdc321
--- /dev/null
+++ b/base/migrate/70ToTxt/src/compile.bat
@@ -0,0 +1,152 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script creates the "70ToTxt/classes/Main.class" and
+REM "70ToTxt/classes/CMS70LdifParser.class" which are
+REM used to create a normalized CMS 7.0 ldif text file.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM Set SERVER_ROOT - identify the CMS <server_root> used to compile 70ToTxt
+REM
+
+REM SET SERVER_ROOT=C:\cms701
+
+
+REM
+REM Set JDK_VERSION - specify the JDK version used by this version of CMS
+REM
+REM CMS 7.0 NOTE: "WINNT" - 1.4.2
+REM
+REM CMS 7.01 NOTE: "WINNT" - 1.4.2
+REM
+
+REM SET JDK_VERSION=CMS_7.01
+
+
+REM
+REM Set JAVA_HOME - specify the complete path to the JDK
+REM
+REM example: \\bermuda.redhat.com\sbc mounted as Y:
+REM
+
+REM SET JAVA_HOME=Y:\cms_jdk\WINNT\%JDK_VERSION%
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 7.0"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0"
+ECHO.
+ECHO NOTE: No arguments are required to build the
+ECHO normalized %CMS% ldif text classes.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%JAVA_HOME%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and JAVA_HOME
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_JAVA_HOME
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified JAVA_HOME exists
+REM
+
+:CHECK_JAVA_HOME
+IF EXIST %JAVA_HOME% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified JAVA_HOME does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%JAVA_HOME%\bin;%JAVA_HOME%\lib;%PATH%
+
+
+REM
+REM Set TARGET - identify the complete path to the new classes target directory
+REM
+
+SET TARGET=..\classes
+
+
+REM
+REM Create the new classes target directory (if it does not already exist)
+REM
+
+IF EXIST %TARGET% goto COMPILE_CLASSES
+MKDIR %TARGET%
+
+
+REM
+REM Compile 70ToTxt - create "CMS70LdifParser.class" and "Main.class"
+REM
+
+:COMPILE_CLASSES
+%JAVA_HOME%\bin\javac.exe -d %TARGET% -classpath %JAVA_HOME%\jre\lib\rt.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar Main.java
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/70ToTxt/src/compile.sh b/base/migrate/70ToTxt/src/compile.sh
new file mode 100755
index 000000000..7c9de9b89
--- /dev/null
+++ b/base/migrate/70ToTxt/src/compile.sh
@@ -0,0 +1,160 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#####################################################################
+### ###
+### This script creates the "70ToTxt/classes/Main.class" and ###
+### "70ToTxt/classes/CMS70LdifParser.class" which are ###
+### used to create a normalized CMS 7.0 ldif text file. ###
+### ###
+#####################################################################
+
+
+###
+### Set SERVER_ROOT - identify the CMS <server_root> used to compile 70ToTxt
+###
+
+#SERVER_ROOT=/export/home/migrate/cms70
+#export SERVER_ROOT
+
+
+###
+### Set JDK_PLATFORM - must be "HP-UX", "Linux", or "SunOS"
+###
+
+#JDK_PLATFORM=SunOS
+#export JDK_PLATFORM
+
+
+###
+### Set JDK_VERSION - specify the JDK version used by this version of CMS
+###
+### CMS 7.0 NOTE: "HP-UX" - 1.4.0.00
+### "Linux" - 1.4.2
+### "SunOS" - 1.4.2
+###
+
+#JDK_VERSION=CMS_7.0
+#export JDK_VERSION
+
+
+###
+### Set JAVA_HOME - specify the complete path to the JDK
+###
+
+#JAVA_HOME=/share/builds/components/cms_jdk/${JDK_PLATFORM}/${JDK_VERSION}
+#export JAVA_HOME
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 7.0"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -gt 0 ] ; then
+ echo
+ echo "Usage: $0"
+ echo
+ echo " NOTE: No arguments are required to build the"
+ echo " normalized ${CMS} ldif text classes."
+ echo
+ exit 1
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${JAVA_HOME}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and JAVA_HOME "
+ echo " environment variables for this script!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 3
+fi
+
+
+###
+### Check that the specified JAVA_HOME exists and is a directory
+###
+
+if [ ! -d "${JAVA_HOME}" ] ; then
+ echo "ERROR: Either the specified JAVA_HOME does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 4
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Set TARGET - identify the complete path to the new classes target directory
+###
+
+TARGET=../classes
+export TARGET
+
+
+###
+### Create the new classes target directory (if it does not already exist)
+###
+
+if [ ! -d ${TARGET} ]; then
+ mkdir -p ${TARGET}
+fi
+
+
+###
+### Compile 70ToTxt - create "CMS70LdifParser.class" and "Main.class"
+###
+
+${JAVA_HOME}/bin/javac -d ${TARGET} -classpath ${JAVA_HOME}/jre/lib/rt.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar Main.java
+
diff --git a/base/migrate/71ToTxt/classes/CMS71LdifParser.class b/base/migrate/71ToTxt/classes/CMS71LdifParser.class
new file mode 100644
index 000000000..b78e44623
--- /dev/null
+++ b/base/migrate/71ToTxt/classes/CMS71LdifParser.class
Binary files differ
diff --git a/base/migrate/71ToTxt/classes/Main.class b/base/migrate/71ToTxt/classes/Main.class
new file mode 100644
index 000000000..e37d5400a
--- /dev/null
+++ b/base/migrate/71ToTxt/classes/Main.class
Binary files differ
diff --git a/base/migrate/71ToTxt/run.bat b/base/migrate/71ToTxt/run.bat
new file mode 100755
index 000000000..4dbe2f5cd
--- /dev/null
+++ b/base/migrate/71ToTxt/run.bat
@@ -0,0 +1,192 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM This program is free software; you can redistribute it and/or modify
+REM it under the terms of the GNU General Public License as published by
+REM the Free Software Foundation; version 2 of the License.
+REM
+REM This program is distributed in the hope that it will be useful,
+REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+REM GNU General Public License for more details.
+REM
+REM You should have received a copy of the GNU General Public License along
+REM with this program; if not, write to the Free Software Foundation, Inc.,
+REM 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script converts a pre-existing CS 7.1 ldif data
+REM file (e. g. - created via a utility such as db2ldif)
+REM into a normalized CS 7.1 ldif text file.
+REM
+REM This subsequent normalized CS 7.1 ldif text file
+REM can be migrated into CS 7.1 or later utilizing
+REM the corresponding TxtTo<Target CS Version> script which
+REM converts this normalized CS 7.1 ldif text file into
+REM a <Target CS Version> ldif data file.
+REM
+REM This <Target CS Version> ldif data file can then be
+REM imported into the internal database of the desired CS
+REM server using a utility such as ldif2db.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM SERVER_ROOT - fully qualified path of the location of the server
+REM
+
+REM SET SERVER_ROOT=C:\cs71
+
+
+REM
+REM INSTANCE - if the CS instance directory is called 'cert-ca',
+REM set the CS instance to 'ca'
+REM
+REM NOTE: When a single SERVER_ROOT contains more than
+REM one CS instance, this script must be run multiple
+REM times. To do this, there is only a need to change
+REM the INSTANCE parameter.
+REM
+
+REM SET INSTANCE=ca
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CS="CS 7.1"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO USAGE
+IF "%3" == "" GOTO CHECK_INPUT_FILE
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0 input [errors] > output"
+ECHO.
+ECHO where: input - the specified %CS% ldif data file,
+ECHO errors - an optional errors file containing
+ECHO skipped attributes, and
+ECHO output - the normalized %CS% ldif text file.
+ECHO.
+ECHO NOTE: If no redirection is provided to
+ECHO 'output', then the normalized
+ECHO %CS% ldif text will merely
+ECHO be echoed to stdout.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified "input" file exists
+REM
+
+:CHECK_INPUT_FILE
+IF EXIST %1 GOTO CHECK_ERRORS_FILE
+
+
+ECHO ERROR: The specified input file, %1, does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM If an "errors" file is specified, then check that it does not already
+REM exist.
+REM
+
+:CHECK_ERRORS_FILE
+IF "%2" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+IF EXIST %2 GOTO ERRORS_FILE_ERROR
+GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:ERRORS_FILE_ERROR
+ECHO ERROR: The specified errors file, %2, already exists!
+ECHO Please specify a different file!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%INSTANCE%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and INSTANCE
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_INSTANCE
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified INSTANCE exists
+REM
+
+:CHECK_INSTANCE
+IF EXIST %SERVER_ROOT%\cert-%INSTANCE% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified INSTANCE does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%SERVER_ROOT%\bin\cert\jre\bin;%SERVER_ROOT\bin\cert\jre\bin\server;%PATH%
+
+
+REM
+REM Convert the specified %CS% ldif data file
+REM into a normalized %CS% ldif text file.
+REM
+
+%SERVER_ROOT%\bin\cert\jre\bin\java.exe -classpath .\classes;%SERVER_ROOT%\cert-%INSTANCE%\classes;%SERVER_ROOT%\bin\cert\classes;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar;%SERVER_ROOT%\bin\cert\jre\lib\rt.jar Main %1 %2
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/71ToTxt/run.sh b/base/migrate/71ToTxt/run.sh
new file mode 100755
index 000000000..e1a33a541
--- /dev/null
+++ b/base/migrate/71ToTxt/run.sh
@@ -0,0 +1,202 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+
+#####################################################################
+### ###
+### This script converts a pre-existing CS 7.1 ldif data ###
+### file (e. g. - created via a utility such as db2ldif) ###
+### into a normalized CS 7.1 ldif text file. ###
+### ###
+### This subsequent normalized CS 7.1 ldif text file ###
+### can be migrated into CS 7.1 or later utilizing ###
+### the corresponding TxtTo<Target CS Version> script which ###
+### converts this normalized CS 7.1 ldif text file into ###
+### a <Target CS Version> ldif data file. ###
+### ###
+### This <Target CS Version> ldif data file can then be ###
+### imported into the internal database of the desired CS ###
+### server using a utility such as ldif2db. ###
+### ###
+#####################################################################
+
+
+###
+### SERVER_ROOT - fully qualified path of the location of the server
+###
+
+#SERVER_ROOT=/export/home/migrate/cs71
+#export SERVER_ROOT
+
+
+###
+### INSTANCE - if the CS instance directory is called 'cert-ca',
+### set the CS instance to 'ca'
+###
+### NOTE: When a single SERVER_ROOT contains more than
+### one CS instance, this script must be run multiple
+### times. To do this, there is only a need to change
+### the INSTANCE parameter.
+###
+
+#INSTANCE=ca
+#export INSTANCE
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CS="CS 7.1"
+export CS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+##
+## Perform a usage check for the appropriate number of arguments:
+##
+
+if [ $# -lt 1 -o $# -gt 2 ] ; then
+ echo
+ echo "Usage: $0 input [errors] > output"
+ echo
+ echo " where: input - the specified ${CS} ldif data file,"
+ echo " errors - an optional errors file containing"
+ echo " skipped attributes, and"
+ echo " output - the normalized ${CS} ldif text file."
+ echo
+ echo " NOTE: If no redirection is provided to"
+ echo " 'output', then the normalized"
+ echo " ${CS} ldif text will merely"
+ echo " be echoed to stdout."
+ echo
+ exit 1
+fi
+
+
+###
+### Check that the specified "input" file exists and is a regular file.
+###
+
+if [ ! -f $1 ] ; then
+ echo "ERROR: Either the specified 'input' file, '$1', does not exist, "
+ echo " or it is not a regular file!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified "input" file exists and is not empty.
+###
+
+if [ ! -s $1 ] ; then
+ echo "ERROR: The specified 'input' file, '$1', is empty!"
+ echo
+ exit 3
+fi
+
+
+###
+### If an "errors" file is specified, then check that it does not already
+### exist.
+###
+
+if [ $# -eq 2 ] ; then
+ if [ -f $2 ] ; then
+ echo "ERROR: The specified 'errors' file, '$2', already exists!"
+ echo " Please specify a different file!"
+ echo
+ exit 4
+ fi
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${INSTANCE}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and INSTANCE "
+ echo " environment variables for this script!"
+ echo
+ exit 5
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 6
+fi
+
+
+###
+### Check that the specified INSTANCE exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}/cert-${INSTANCE}" ] ; then
+ echo "ERROR: Either the specified INSTANCE does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 7
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Convert the specified ${CS} ldif data file
+### into a normalized ${CS} ldif text file.
+###
+### NOTE: As of SunOS JDK 1.4.0, the required "Unicode" classes
+### have been moved from "i18n.jar" to "rt.jar".
+###
+
+${SERVER_ROOT}/bin/cert/jre/bin/java -classpath ./classes:${SERVER_ROOT}/cert-${INSTANCE}/classes:${SERVER_ROOT}/bin/cert/classes:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar:${SERVER_ROOT}/bin/cert/jre/lib/rt.jar Main $1 $2
+
diff --git a/base/migrate/71ToTxt/src/Main.java b/base/migrate/71ToTxt/src/Main.java
new file mode 100644
index 000000000..f7f3a5b95
--- /dev/null
+++ b/base/migrate/71ToTxt/src/Main.java
@@ -0,0 +1,483 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+//
+// "71ToTxt/src/Main.java" is based upon a copy "70ToTxt/src/Main.java".
+//
+// Always comment any new code sections with a "CMS 7.1" header, and
+// apply these changes forward to all other "*ToTxt/src/Main.java" files
+// (including this comment header) so that these differences will only
+// appear when this file is diffed against an earlier "*ToTxt" version.
+//
+// This file should always be maintained by executing the following command:
+//
+// diff 70ToTxt/src/Main.java 71ToTxt/src/Main.java
+//
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+import sun.misc.*;
+import org.mozilla.jss.*; // CMS 4.5 and later
+import org.mozilla.jss.crypto.*; // CMS 4.5 and later
+import netscape.security.util.*;
+
+public class Main
+{
+ public static void main(String args[])
+ {
+ try {
+ // initialize CryptoManager in CMS 4.5 and later
+ CryptoManager.initialize(".");
+ // load JSS provider in CMS 4.5 and later
+ java.security.Security.removeProvider("SUN version 1.2");
+ // The following call to "java.security.Security.insertProviderAt()"
+ // is no longer commented out in CMS 4.5 and later
+ java.security.Security.insertProviderAt(
+ new netscape.security.provider.CMS(), 0);
+ java.security.Provider ps[] =
+ java.security.Security.getProviders();
+ if (ps == null || ps.length <= 0) {
+ System.err.println("Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ System.err.println("Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+
+ // Parse the File
+ CMS71LdifParser parser = null;
+ if (args.length == 1) {
+ parser = new CMS71LdifParser(args[0]);
+ } else if (args.length == 2) {
+ parser = new CMS71LdifParser(args[0], args[1]);
+ } else {
+ throw new IOException("Invalid Parameters");
+ }
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+}
+
+class CMS71LdifParser
+{
+ // constants
+ private static final String DN =
+ "dn:";
+ // Directory Servers in CMS 4.7 and later use "requestAttributes"
+ private static final String REQUEST_ATTRIBUTES =
+ "requestAttributes::";
+ private static final String BEGIN =
+ "--- BEGIN ATTRIBUTES ---";
+ private static final String END =
+ "--- END ATTRIBUTES ---";
+
+ // variables
+ private String mFilename = null;
+ private String mErrorFilename = null;
+ private PrintWriter mErrorPrintWriter = null;
+
+ public CMS71LdifParser(String filename)
+ {
+ mFilename = filename;
+ }
+
+ public CMS71LdifParser(String filename, String errorFilename)
+ {
+ mFilename = filename;
+ mErrorFilename = errorFilename;
+ }
+
+ public void parse() throws Exception
+ {
+ if (mErrorFilename != null) {
+ mErrorPrintWriter = new PrintWriter(new FileOutputStream(mErrorFilename));
+ }
+ BufferedReader reader = new BufferedReader(
+ new FileReader(mFilename));
+ String line = null;
+ String dn = null;
+ StringBuffer requestAttributes = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DN)) {
+ dn = line;
+ }
+ if (line.startsWith(REQUEST_ATTRIBUTES)) {
+ requestAttributes = new StringBuffer();
+ // System.out.println(line);
+ requestAttributes.append(
+ line.substring(REQUEST_ATTRIBUTES.length(),
+ line.length()).trim());
+ continue;
+ }
+ if (requestAttributes == null) {
+ System.out.println(line);
+ continue;
+ }
+ if (line.startsWith(" ")) {
+ // System.out.println(line);
+ requestAttributes.append(line.trim());
+ } else {
+ parseAttributes(dn, requestAttributes);
+ requestAttributes = null;
+ System.out.println(line);
+ }
+ }
+ }
+
+ public void parseAttributes(String dn, StringBuffer attrs) throws Exception
+ {
+ BASE64Decoder decoder = new BASE64Decoder();
+ decodeHashtable(dn, decoder.decodeBuffer(attrs.toString()));
+
+// System.out.println(attrs);
+ }
+
+ public Object decode(byte[] data) throws
+ ObjectStreamException,
+ IOException,
+ ClassNotFoundException
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+ return is.readObject();
+ }
+
+ public void decodeHashtable(String dn, byte[] data) throws Exception
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+
+ System.out.println(BEGIN);
+ String key = null;
+ while (true)
+ {
+ key = (String)is.readObject();
+ // end of table is marked with null
+ if (key == null) break;
+ try {
+ byte[] bytes = (byte[])is.readObject();
+ Object obj = decode(bytes);
+ output(key, obj);
+ } catch (Exception e) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + key);
+ }
+ }
+ }
+ System.out.println(END);
+ }
+
+ public void output(String key, Object obj) throws Exception
+ {
+ if (obj instanceof String) {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ } else if (obj instanceof netscape.security.x509.CertificateX509Key) {
+ netscape.security.x509.CertificateX509Key o =
+ (netscape.security.x509.CertificateX509Key)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateSubjectName) {
+ netscape.security.x509.CertificateSubjectName o =
+ (netscape.security.x509.CertificateSubjectName)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateExtensions) {
+ netscape.security.x509.CertificateExtensions o =
+ (netscape.security.x509.CertificateExtensions)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertInfo) {
+ netscape.security.x509.X509CertInfo o =
+ (netscape.security.x509.X509CertInfo)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl) {
+ netscape.security.x509.X509CertImpl o =
+ (netscape.security.x509.X509CertImpl)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateChain) {
+ netscape.security.x509.CertificateChain o =
+ (netscape.security.x509.CertificateChain)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl[]) {
+ netscape.security.x509.X509CertImpl o[] =
+ (netscape.security.x509.X509CertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.X509CertInfo[]) {
+ netscape.security.x509.X509CertInfo o[] =
+ (netscape.security.x509.X509CertInfo[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() + "["+o.length + "," + i+"]"+"=" +
+ encoder.encodeBuffer(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.RevokedCertImpl[]) {
+ netscape.security.x509.RevokedCertImpl o[] =
+ (netscape.security.x509.RevokedCertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ DerOutputStream bos =
+ new DerOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof java.security.cert.Certificate[]) {
+ java.security.cert.Certificate o[] =
+ (java.security.cert.Certificate[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(o[i].getEncoded()));
+ }
+ } else if (obj instanceof com.netscape.cmscore.base.ArgBlock) {
+ // CMS 6.1: created new "com.netscape.certsrv.base.IArgBlock" and
+ // moved old "com.netscape.certsrv.base.ArgBlock"
+ // to "com.netscape.cmscore.base.ArgBlock"
+ com.netscape.cmscore.base.ArgBlock o =
+ (com.netscape.cmscore.base.ArgBlock)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" +(String)o.get(k));
+ }
+ } else if (obj instanceof com.netscape.cmscore.dbs.KeyRecord) {
+ // CMS 6.0: moved "com.netscape.certsrv.dbs.keydb.KeyRecord"
+ // to "com.netscape.cmscore.dbs.KeyRecord"
+ com.netscape.cmscore.dbs.KeyRecord o =
+ (com.netscape.cmscore.dbs.KeyRecord)obj;
+ Enumeration<String> e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = e.nextElement();
+ Object ob = o.get(k);
+ if (ob != null) {
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + encoder.encode((byte[])ob));
+
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ }
+ } else if (obj instanceof com.netscape.cmscore.kra.ProofOfArchival) {
+ // CMS 6.0: moved "com.netscape.certsrv.kra.ProofOfArchival"
+ // to "com.netscape.cmscore.kra.ProofOfArchival"
+ com.netscape.cmscore.kra.ProofOfArchival o =
+ (com.netscape.cmscore.kra.ProofOfArchival)obj;
+ DerOutputStream bos =
+ new DerOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof com.netscape.certsrv.request.AgentApprovals) {
+ com.netscape.certsrv.request.AgentApprovals o =
+ (com.netscape.certsrv.request.AgentApprovals)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ com.netscape.certsrv.request.AgentApproval approval = (com.netscape.certsrv.request.AgentApproval)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ approval.getUserName() + ";" + approval.getDate().getTime());
+ }
+ } else if (obj instanceof com.netscape.certsrv.authentication.AuthToken) {
+ com.netscape.certsrv.authentication.AuthToken o =
+ (com.netscape.certsrv.authentication.AuthToken)obj;
+ Enumeration e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ Object ob = o.get(k);
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof java.math.BigInteger[]) {
+ // Bugzilla Bug #225031 (a.k.a. - Raidzilla Bug #58356)
+ java.math.BigInteger in[] = (java.math.BigInteger[])ob;
+ String numbers = "";
+ for (int i = 0; i < in.length; i++) {
+ if (numbers.equals("")) {
+ numbers = in[i].toString();
+ } else {
+ numbers = numbers + "," + in[i].toString();
+ }
+ }
+ System.out.println(" " +
+ key + ":" + "com.netscape.certsrv.authentication.AuthToken" + "=" +
+ k + ":java.lang.String=" + numbers);
+ } else if (ob instanceof String[]) {
+ // Bugzilla Bug #224763 (a.k.a. - Raidzilla Bug #57949)
+ // Bugzilla Bug #252240
+ String str[] = (String[])ob;
+ String v = "";
+ if (str != null) {
+ for (int i = 0; i < str.length; i++) {
+ if (i != 0) {
+ v += ",";
+ }
+ v += str[i];
+ }
+ }
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + "java.lang.String" + "=" + v);
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ } else if (obj instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key + ":byte[]="+
+ encoder.encode((byte[])obj));
+ } else if (obj instanceof Integer[]) {
+ Integer in[] = (Integer[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":Integer[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof BigInteger[]) {
+ // Bugzilla Bug #238779
+ BigInteger in[] = (BigInteger[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":java.math.BigInteger[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof String[]) {
+ // Bugzilla Bug #223360 (a.k.a - Raidzilla Bug #58086)
+ String str[] = (String[])obj;
+ for (int i = 0; i < str.length; i++) {
+ System.out.println(" " + key + ":java.lang.String[" + str.length + "," + i + "]="+ str[i]);
+ }
+ } else if (obj instanceof netscape.security.x509.CertificateAlgorithmId) {
+ netscape.security.x509.CertificateAlgorithmId o =
+ (netscape.security.x509.CertificateAlgorithmId)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateAlgorithmId="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateValidity) {
+ netscape.security.x509.CertificateValidity o =
+ (netscape.security.x509.CertificateValidity)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateValidity="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof byte[]) {
+ // Since 6.1's profile framework,
+ // req_archive_options is a byte array
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":byte[]="+
+ encoder.encode((byte[])obj));
+ } else if (obj instanceof java.util.Hashtable) {
+ // Bugzilla Bug #224800 (a.k.a - Raidzilla Bug #56953)
+ //
+ // Example: fingerprints:java.util.Hashtable=
+ // {SHA1=[B@52513a, MD5=[B@52c4d9, MD2=[B@799ff5}
+ //
+ java.util.Hashtable o = (java.util.Hashtable)obj;
+ BASE64Encoder encoder = new BASE64Encoder();
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" + encoder.encode((byte[])o.get(k)));
+ }
+ } else {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ }
+ }
+}
+
diff --git a/base/migrate/71ToTxt/src/compile.bat b/base/migrate/71ToTxt/src/compile.bat
new file mode 100755
index 000000000..49ba89621
--- /dev/null
+++ b/base/migrate/71ToTxt/src/compile.bat
@@ -0,0 +1,150 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script creates the "71ToTxt/classes/Main.class" and
+REM "71ToTxt/classes/CMS71LdifParser.class" which are
+REM used to create a normalized CS 7.1 ldif text file.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM Set SERVER_ROOT - identify the CS <server_root> used to compile 71ToTxt
+REM
+
+REM SET SERVER_ROOT=C:\cs71
+
+
+REM
+REM Set JDK_VERSION - specify the JDK version used by this version of CS
+REM
+REM CS 7.1 NOTE: "WINNT" - 1.4.2
+REM
+
+REM SET JDK_VERSION=CS_7.1
+
+
+REM
+REM Set JAVA_HOME - specify the complete path to the JDK
+REM
+REM example: \\bermuda.redhat.com\sbc mounted as Y:
+REM
+
+REM SET JAVA_HOME=Y:\cms_jdk\WINNT\%JDK_VERSION%
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CS="CS 7.1"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0"
+ECHO.
+ECHO NOTE: No arguments are required to build the
+ECHO normalized %CS% ldif text classes.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%JAVA_HOME%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and JAVA_HOME
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_JAVA_HOME
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified JAVA_HOME exists
+REM
+
+:CHECK_JAVA_HOME
+IF EXIST %JAVA_HOME% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified JAVA_HOME does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%JAVA_HOME%\bin;%JAVA_HOME%\lib;%PATH%
+
+
+REM
+REM Set TARGET - identify the complete path to the new classes target directory
+REM
+
+SET TARGET=..\classes
+
+
+REM
+REM Create the new classes target directory (if it does not already exist)
+REM
+
+IF EXIST %TARGET% goto COMPILE_CLASSES
+MKDIR %TARGET%
+
+
+REM
+REM Compile 71ToTxt - create "CMS71LdifParser.class" and "Main.class"
+REM
+
+:COMPILE_CLASSES
+%JAVA_HOME%\bin\javac.exe -d %TARGET% -classpath %JAVA_HOME%\jre\lib\rt.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar Main.java
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/71ToTxt/src/compile.sh b/base/migrate/71ToTxt/src/compile.sh
new file mode 100755
index 000000000..23464bcb3
--- /dev/null
+++ b/base/migrate/71ToTxt/src/compile.sh
@@ -0,0 +1,160 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#####################################################################
+### ###
+### This script creates the "71ToTxt/classes/Main.class" and ###
+### "71ToTxt/classes/CMS71LdifParser.class" which are ###
+### used to create a normalized CS 7.1 ldif text file. ###
+### ###
+#####################################################################
+
+
+###
+### Set SERVER_ROOT - identify the CS <server_root> used to compile 71ToTxt
+###
+
+#SERVER_ROOT=/export/home/migrate/cs71
+#export SERVER_ROOT
+
+
+###
+### Set JDK_PLATFORM - must be "HP-UX", "Linux", or "SunOS"
+###
+
+#JDK_PLATFORM=SunOS
+#export JDK_PLATFORM
+
+
+###
+### Set JDK_VERSION - specify the JDK version used by this version of CS
+###
+### CS 7.1 NOTE: "HP-UX" - 1.4.0.00
+### "Linux" - 1.4.2
+### "SunOS" - 1.4.2
+###
+
+#JDK_VERSION=CS_7.1
+#export JDK_VERSION
+
+
+###
+### Set JAVA_HOME - specify the complete path to the JDK
+###
+
+#JAVA_HOME=/share/builds/components/cms_jdk/${JDK_PLATFORM}/${JDK_VERSION}
+#export JAVA_HOME
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CS="CS 7.1"
+export CS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -gt 0 ] ; then
+ echo
+ echo "Usage: $0"
+ echo
+ echo " NOTE: No arguments are required to build the"
+ echo " normalized ${CS} ldif text classes."
+ echo
+ exit 1
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${JAVA_HOME}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and JAVA_HOME "
+ echo " environment variables for this script!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 3
+fi
+
+
+###
+### Check that the specified JAVA_HOME exists and is a directory
+###
+
+if [ ! -d "${JAVA_HOME}" ] ; then
+ echo "ERROR: Either the specified JAVA_HOME does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 4
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Set TARGET - identify the complete path to the new classes target directory
+###
+
+TARGET=../classes
+export TARGET
+
+
+###
+### Create the new classes target directory (if it does not already exist)
+###
+
+if [ ! -d ${TARGET} ]; then
+ mkdir -p ${TARGET}
+fi
+
+
+###
+### Compile 71ToTxt - create "CMS71LdifParser.class" and "Main.class"
+###
+
+${JAVA_HOME}/bin/javac -d ${TARGET} -classpath ${JAVA_HOME}/jre/lib/rt.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar Main.java
+
diff --git a/base/migrate/72ToTxt/classes/CMS72LdifParser.class b/base/migrate/72ToTxt/classes/CMS72LdifParser.class
new file mode 100644
index 000000000..707657160
--- /dev/null
+++ b/base/migrate/72ToTxt/classes/CMS72LdifParser.class
Binary files differ
diff --git a/base/migrate/72ToTxt/classes/Main.class b/base/migrate/72ToTxt/classes/Main.class
new file mode 100644
index 000000000..470df979a
--- /dev/null
+++ b/base/migrate/72ToTxt/classes/Main.class
Binary files differ
diff --git a/base/migrate/72ToTxt/run.bat b/base/migrate/72ToTxt/run.bat
new file mode 100755
index 000000000..9613fe5d5
--- /dev/null
+++ b/base/migrate/72ToTxt/run.bat
@@ -0,0 +1,192 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM This program is free software; you can redistribute it and/or modify
+REM it under the terms of the GNU General Public License as published by
+REM the Free Software Foundation; version 2 of the License.
+REM
+REM This program is distributed in the hope that it will be useful,
+REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+REM GNU General Public License for more details.
+REM
+REM You should have received a copy of the GNU General Public License along
+REM with this program; if not, write to the Free Software Foundation, Inc.,
+REM 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script converts a pre-existing CS 7.2 ldif data
+REM file (e. g. - created via a utility such as db2ldif)
+REM into a normalized CS 7.2 ldif text file.
+REM
+REM This subsequent normalized CS 7.2 ldif text file
+REM can be migrated into CS 7.2 or later utilizing
+REM the corresponding TxtTo<Target CS Version> script which
+REM converts this normalized CS 7.2 ldif text file into
+REM a <Target CS Version> ldif data file.
+REM
+REM This <Target CS Version> ldif data file can then be
+REM imported into the internal database of the desired CS
+REM server using a utility such as ldif2db.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM SERVER_ROOT - fully qualified path of the location of the server
+REM
+
+REM SET SERVER_ROOT=C:\cs72
+
+
+REM
+REM INSTANCE - if the CS instance directory is called 'cert-ca',
+REM set the CS instance to 'ca'
+REM
+REM NOTE: When a single SERVER_ROOT contains more than
+REM one CS instance, this script must be run multiple
+REM times. To do this, there is only a need to change
+REM the INSTANCE parameter.
+REM
+
+REM SET INSTANCE=ca
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CS="CS 7.2"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO USAGE
+IF "%3" == "" GOTO CHECK_INPUT_FILE
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0 input [errors] > output"
+ECHO.
+ECHO where: input - the specified %CS% ldif data file,
+ECHO errors - an optional errors file containing
+ECHO skipped attributes, and
+ECHO output - the normalized %CS% ldif text file.
+ECHO.
+ECHO NOTE: If no redirection is provided to
+ECHO 'output', then the normalized
+ECHO %CS% ldif text will merely
+ECHO be echoed to stdout.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified "input" file exists
+REM
+
+:CHECK_INPUT_FILE
+IF EXIST %1 GOTO CHECK_ERRORS_FILE
+
+
+ECHO ERROR: The specified input file, %1, does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM If an "errors" file is specified, then check that it does not already
+REM exist.
+REM
+
+:CHECK_ERRORS_FILE
+IF "%2" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+IF EXIST %2 GOTO ERRORS_FILE_ERROR
+GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:ERRORS_FILE_ERROR
+ECHO ERROR: The specified errors file, %2, already exists!
+ECHO Please specify a different file!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%INSTANCE%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and INSTANCE
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_INSTANCE
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified INSTANCE exists
+REM
+
+:CHECK_INSTANCE
+IF EXIST %SERVER_ROOT%\cert-%INSTANCE% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified INSTANCE does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%SERVER_ROOT%\bin\cert\jre\bin;%SERVER_ROOT\bin\cert\jre\bin\server;%PATH%
+
+
+REM
+REM Convert the specified %CS% ldif data file
+REM into a normalized %CS% ldif text file.
+REM
+
+%SERVER_ROOT%\bin\cert\jre\bin\java.exe -classpath .\classes;%SERVER_ROOT%\cert-%INSTANCE%\classes;%SERVER_ROOT%\bin\cert\classes;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar;%SERVER_ROOT%\bin\cert\jre\lib\rt.jar Main %1 %2
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/72ToTxt/run.sh b/base/migrate/72ToTxt/run.sh
new file mode 100755
index 000000000..ccdd00630
--- /dev/null
+++ b/base/migrate/72ToTxt/run.sh
@@ -0,0 +1,158 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+
+#####################################################################
+### ###
+### This script converts a pre-existing CS 7.2 ldif data ###
+### file (e. g. - created via a utility such as db2ldif) ###
+### into a normalized CS 7.2 ldif text file. ###
+### ###
+### This subsequent normalized CS 7.2 ldif text file ###
+### can be migrated into CS 7.2 or later utilizing ###
+### the corresponding TxtTo<Target CS Version> script which ###
+### converts this normalized CS 7.2 ldif text file into ###
+### a <Target CS Version> ldif data file. ###
+### ###
+### This <Target CS Version> ldif data file can then be ###
+### imported into the internal database of the desired CS ###
+### server using a utility such as ldif2db. ###
+### ###
+#####################################################################
+
+###
+### Java Runtime Environment
+###
+JRE_ROOT=/usr/lib/jvm/jre-1.5.0
+export JRE_ROOT
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+###
+### Script-defined constants
+###
+
+CS="CS 7.2"
+export CS
+
+OS_NAME=`uname`
+export OS_NAME
+
+ARCH=`uname -i`
+export ARCH
+
+
+##
+## Perform a usage check for the appropriate number of arguments:
+##
+
+if [ $# -lt 1 -o $# -gt 2 ] ; then
+ echo
+ echo "Usage: $0 input [errors] > output"
+ echo
+ echo " where: input - the specified ${CS} ldif data file,"
+ echo " errors - an optional errors file containing"
+ echo " skipped attributes, and"
+ echo " output - the normalized ${CS} ldif text file."
+ echo
+ echo " NOTE: If no redirection is provided to"
+ echo " 'output', then the normalized"
+ echo " ${CS} ldif text will merely"
+ echo " be echoed to stdout."
+ echo
+ exit 1
+fi
+
+
+###
+### Check that the specified "input" file exists and is a regular file.
+###
+
+if [ ! -f $1 ] ; then
+ echo "ERROR: Either the specified 'input' file, '$1', does not exist, "
+ echo " or it is not a regular file!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified "input" file exists and is not empty.
+###
+
+if [ ! -s $1 ] ; then
+ echo "ERROR: The specified 'input' file, '$1', is empty!"
+ echo
+ exit 3
+fi
+
+
+###
+### If an "errors" file is specified, then check that it does not already
+### exist.
+###
+
+if [ $# -eq 2 ] ; then
+ if [ -f $2 ] ; then
+ echo "ERROR: The specified 'errors' file, '$2', already exists!"
+ echo " Please specify a different file!"
+ echo
+ exit 4
+ fi
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+###
+### NOTE: As of SunOS JDK 1.4.0, the required "Unicode" classes
+### have been moved from "i18n.jar" to "rt.jar".
+###
+CLASSPATH=/usr/share/rhpki/migrate/72ToTxt/classes:/usr/share/java/rhpki/certsrv.jar:/usr/share/java/rhpki/cmscore.jar:/usr/share/java/rhpki/nsutil.jar:/usr/lib/java/dirsec/jss4.jar:${JRE_ROOT}/lib/rt.jar
+export CLASSPATH
+
+if [ ${OS_NAME} = "Linux" ] ; then
+ if [ ${ARCH} = "i386" ] ; then
+ LD_LIBRARY_PATH=/usr/lib/dirsec:/usr/lib:${JRE_ROOT}/lib:${JRE_ROOT}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+ else # x86_64
+ LD_LIBRARY_PATH=/usr/lib64/dirsec:/usr/lib64:${JRE_ROOT}/lib:${JRE_ROOT}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+ CLASSPATH=/usr/share/rhpki/migrate/72ToTxt/classes:/usr/share/java/rhpki/certsrv.jar:/usr/share/java/rhpki/cmscore.jar:/usr/share/java/rhpki/nsutil.jar:/usr/lib64/java/dirsec/jss4.jar:${JRE_ROOT}/lib/rt.jar
+ export CLASSPATH
+ fi
+else # SunOS 64-bits
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/dirsec:/usr/lib/sparcv9:${JRE_ROOT}/lib:${JRE_ROOT}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+ CLASSPATH=/usr/share/rhpki/migrate/72ToTxt/classes:/usr/share/java/rhpki/certsrv.jar:/usr/share/java/rhpki/cmscore.jar:/usr/share/java/rhpki/nsutil.jar:/usr/lib/sparcv9/java/dirsec/jss4.jar:${JRE_ROOT}/lib/rt.jar
+ export CLASSPATH
+fi
+
+
+###
+### Convert the specified ${CS} ldif data file
+### into a normalized ${CS} ldif text file.
+###
+
+${JRE_ROOT}/bin/java -classpath ${CLASSPATH} Main $1 $2
diff --git a/base/migrate/72ToTxt/src/Main.java b/base/migrate/72ToTxt/src/Main.java
new file mode 100644
index 000000000..0a0dc812e
--- /dev/null
+++ b/base/migrate/72ToTxt/src/Main.java
@@ -0,0 +1,485 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+//
+// "71ToTxt/src/Main.java" is based upon a copy "70ToTxt/src/Main.java".
+//
+// Always comment any new code sections with a "CMS 7.1" header, and
+// apply these changes forward to all other "*ToTxt/src/Main.java" files
+// (including this comment header) so that these differences will only
+// appear when this file is diffed against an earlier "*ToTxt" version.
+//
+// This file should always be maintained by executing the following command:
+//
+// diff 70ToTxt/src/Main.java 71ToTxt/src/Main.java
+//
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+import sun.misc.*;
+import org.mozilla.jss.*; // CMS 4.5 and later
+import org.mozilla.jss.crypto.*; // CMS 4.5 and later
+import netscape.security.util.*;
+
+public class Main
+{
+ public static void main(String args[])
+ {
+ try {
+ // initialize CryptoManager in CMS 4.5 and later
+ CryptoManager.initialize(".");
+ // load JSS provider in CMS 4.5 and later
+ java.security.Security.removeProvider("SUN version 1.2");
+ // The following call to "java.security.Security.insertProviderAt()"
+ // is no longer commented out in CMS 4.5 and later
+ java.security.Security.insertProviderAt(
+ new netscape.security.provider.CMS(), 0);
+ java.security.Provider ps[] =
+ java.security.Security.getProviders();
+ if (ps == null || ps.length <= 0) {
+ System.err.println("Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ System.err.println("Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+
+ // Parse the File
+ CMS72LdifParser parser = null;
+ if (args.length == 1) {
+ parser = new CMS72LdifParser(args[0]);
+ } else if (args.length == 2) {
+ parser = new CMS72LdifParser(args[0], args[1]);
+ } else {
+ throw new IOException("Invalid Parameters");
+ }
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+}
+
+class CMS72LdifParser
+{
+ // constants
+ private static final String DN =
+ "dn:";
+ // Directory Servers in CMS 4.7 and later use "requestAttributes"
+ private static final String REQUEST_ATTRIBUTES =
+ "requestAttributes::";
+ private static final String BEGIN =
+ "--- BEGIN ATTRIBUTES ---";
+ private static final String END =
+ "--- END ATTRIBUTES ---";
+
+ // variables
+ private String mFilename = null;
+ private String mErrorFilename = null;
+ private PrintWriter mErrorPrintWriter = null;
+
+ public CMS72LdifParser(String filename)
+ {
+ mFilename = filename;
+ }
+
+ public CMS72LdifParser(String filename, String errorFilename)
+ {
+ mFilename = filename;
+ mErrorFilename = errorFilename;
+ }
+
+ public void parse() throws Exception
+ {
+ if (mErrorFilename != null) {
+ mErrorPrintWriter = new PrintWriter(new FileOutputStream(mErrorFilename));
+ }
+ BufferedReader reader = new BufferedReader(
+ new FileReader(mFilename));
+ String line = null;
+ String dn = null;
+ StringBuffer requestAttributes = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DN)) {
+ dn = line;
+ }
+ if (line.startsWith(REQUEST_ATTRIBUTES)) {
+ requestAttributes = new StringBuffer();
+ // System.out.println(line);
+ requestAttributes.append(
+ line.substring(REQUEST_ATTRIBUTES.length(),
+ line.length()).trim());
+ continue;
+ }
+ if (requestAttributes == null) {
+ System.out.println(line);
+ continue;
+ }
+ if (line.startsWith(" ")) {
+ // System.out.println(line);
+ requestAttributes.append(line.trim());
+ } else {
+ parseAttributes(dn, requestAttributes);
+ requestAttributes = null;
+ System.out.println(line);
+ }
+ }
+ }
+
+ public void parseAttributes(String dn, StringBuffer attrs) throws Exception
+ {
+ BASE64Decoder decoder = new BASE64Decoder();
+ decodeHashtable(dn, decoder.decodeBuffer(attrs.toString()));
+
+// System.out.println(attrs);
+ }
+
+ public Object decode(byte[] data) throws
+ ObjectStreamException,
+ IOException,
+ ClassNotFoundException
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+ return is.readObject();
+ }
+
+ public void decodeHashtable(String dn, byte[] data) throws Exception
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+
+ System.out.println(BEGIN);
+ String key = null;
+ while (true)
+ {
+ key = (String)is.readObject();
+ // end of table is marked with null
+ if (key == null) break;
+ try {
+ byte[] bytes = (byte[])is.readObject();
+ Object obj = decode(bytes);
+ output(key, obj);
+ } catch (Exception e) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + key);
+ }
+ }
+ }
+ System.out.println(END);
+ }
+
+ public void output(String key, Object obj) throws Exception
+ {
+ if (obj instanceof String) {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ } else if (obj instanceof netscape.security.x509.CertificateX509Key) {
+ netscape.security.x509.CertificateX509Key o =
+ (netscape.security.x509.CertificateX509Key)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateSubjectName) {
+ netscape.security.x509.CertificateSubjectName o =
+ (netscape.security.x509.CertificateSubjectName)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateExtensions) {
+ netscape.security.x509.CertificateExtensions o =
+ (netscape.security.x509.CertificateExtensions)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertInfo) {
+ netscape.security.x509.X509CertInfo o =
+ (netscape.security.x509.X509CertInfo)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl) {
+ netscape.security.x509.X509CertImpl o =
+ (netscape.security.x509.X509CertImpl)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateChain) {
+ netscape.security.x509.CertificateChain o =
+ (netscape.security.x509.CertificateChain)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl[]) {
+ netscape.security.x509.X509CertImpl o[] =
+ (netscape.security.x509.X509CertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.X509CertInfo[]) {
+ netscape.security.x509.X509CertInfo o[] =
+ (netscape.security.x509.X509CertInfo[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() + "["+o.length + "," + i+"]"+"=" +
+ encoder.encodeBuffer(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.RevokedCertImpl[]) {
+ netscape.security.x509.RevokedCertImpl o[] =
+ (netscape.security.x509.RevokedCertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ DerOutputStream bos =
+ new DerOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof java.security.cert.Certificate[]) {
+ java.security.cert.Certificate o[] =
+ (java.security.cert.Certificate[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(o[i].getEncoded()));
+ }
+ } else if (obj instanceof com.netscape.cmscore.base.ArgBlock) {
+ // CMS 6.1: created new "com.netscape.certsrv.base.IArgBlock" and
+ // moved old "com.netscape.certsrv.base.ArgBlock"
+ // to "com.netscape.cmscore.base.ArgBlock"
+ com.netscape.cmscore.base.ArgBlock o =
+ (com.netscape.cmscore.base.ArgBlock)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" +(String)o.get(k));
+ }
+ } else if (obj instanceof com.netscape.cmscore.dbs.KeyRecord) {
+ // CMS 6.0: moved "com.netscape.certsrv.dbs.keydb.KeyRecord"
+ // to "com.netscape.cmscore.dbs.KeyRecord"
+ com.netscape.cmscore.dbs.KeyRecord o =
+ (com.netscape.cmscore.dbs.KeyRecord)obj;
+ Enumeration<String> e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = e.nextElement();
+ Object ob = o.get(k);
+ if (ob != null) {
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + encoder.encode((byte[])ob));
+
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ }
+ } else if (obj instanceof com.netscape.certsrv.kra.ProofOfArchival) {
+ // CS 7.2: moved com.netscape.cmscore.kra.ProofOfArchival
+ // to com.netscape.certsrv.kra.ProofOfArchival
+ // CMS 6.0: moved "com.netscape.certsrv.kra.ProofOfArchival"
+ // to "com.netscape.cmscore.kra.ProofOfArchival"
+ com.netscape.certsrv.kra.ProofOfArchival o =
+ (com.netscape.certsrv.kra.ProofOfArchival)obj;
+ DerOutputStream bos =
+ new DerOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof com.netscape.certsrv.request.AgentApprovals) {
+ com.netscape.certsrv.request.AgentApprovals o =
+ (com.netscape.certsrv.request.AgentApprovals)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ com.netscape.certsrv.request.AgentApproval approval = (com.netscape.certsrv.request.AgentApproval)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ approval.getUserName() + ";" + approval.getDate().getTime());
+ }
+ } else if (obj instanceof com.netscape.certsrv.authentication.AuthToken) {
+ com.netscape.certsrv.authentication.AuthToken o =
+ (com.netscape.certsrv.authentication.AuthToken)obj;
+ Enumeration e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ Object ob = o.get(k);
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof java.math.BigInteger[]) {
+ // Bugzilla Bug #225031 (a.k.a. - Raidzilla Bug #58356)
+ java.math.BigInteger in[] = (java.math.BigInteger[])ob;
+ String numbers = "";
+ for (int i = 0; i < in.length; i++) {
+ if (numbers.equals("")) {
+ numbers = in[i].toString();
+ } else {
+ numbers = numbers + "," + in[i].toString();
+ }
+ }
+ System.out.println(" " +
+ key + ":" + "com.netscape.certsrv.authentication.AuthToken" + "=" +
+ k + ":java.lang.String=" + numbers);
+ } else if (ob instanceof String[]) {
+ // Bugzilla Bug #224763 (a.k.a. - Raidzilla Bug #57949)
+ // Bugzilla Bug #252240
+ String str[] = (String[])ob;
+ String v = "";
+ if (str != null) {
+ for (int i = 0; i < str.length; i++) {
+ if (i != 0) {
+ v += ",";
+ }
+ v += str[i];
+ }
+ }
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + "java.lang.String" + "=" + v);
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ } else if (obj instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key + ":byte[]="+
+ encoder.encode((byte[])obj));
+ } else if (obj instanceof Integer[]) {
+ Integer in[] = (Integer[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":Integer[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof BigInteger[]) {
+ // Bugzilla Bug #238779
+ BigInteger in[] = (BigInteger[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":java.math.BigInteger[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof String[]) {
+ // Bugzilla Bug #223360 (a.k.a - Raidzilla Bug #58086)
+ String str[] = (String[])obj;
+ for (int i = 0; i < str.length; i++) {
+ System.out.println(" " + key + ":java.lang.String[" + str.length + "," + i + "]="+ str[i]);
+ }
+ } else if (obj instanceof netscape.security.x509.CertificateAlgorithmId) {
+ netscape.security.x509.CertificateAlgorithmId o =
+ (netscape.security.x509.CertificateAlgorithmId)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateAlgorithmId="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateValidity) {
+ netscape.security.x509.CertificateValidity o =
+ (netscape.security.x509.CertificateValidity)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateValidity="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof byte[]) {
+ // Since 6.1's profile framework,
+ // req_archive_options is a byte array
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":byte[]="+
+ encoder.encode((byte[])obj));
+ } else if (obj instanceof java.util.Hashtable) {
+ // Bugzilla Bug #224800 (a.k.a - Raidzilla Bug #56953)
+ //
+ // Example: fingerprints:java.util.Hashtable=
+ // {SHA1=[B@52513a, MD5=[B@52c4d9, MD2=[B@799ff5}
+ //
+ java.util.Hashtable o = (java.util.Hashtable)obj;
+ BASE64Encoder encoder = new BASE64Encoder();
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" + encoder.encode((byte[])o.get(k)));
+ }
+ } else {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ }
+ }
+}
+
diff --git a/base/migrate/72ToTxt/src/compile.bat b/base/migrate/72ToTxt/src/compile.bat
new file mode 100755
index 000000000..c0377e5e5
--- /dev/null
+++ b/base/migrate/72ToTxt/src/compile.bat
@@ -0,0 +1,150 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script creates the "72ToTxt/classes/Main.class" and
+REM "72ToTxt/classes/CMS72LdifParser.class" which are
+REM used to create a normalized CS 7.2 ldif text file.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM Set SERVER_ROOT - identify the CS <server_root> used to compile 72ToTxt
+REM
+
+REM SET SERVER_ROOT=C:\cs72
+
+
+REM
+REM Set JDK_VERSION - specify the JDK version used by this version of CS
+REM
+REM CS 7.2 NOTE: "WINNT" - 1.4.2
+REM
+
+REM SET JDK_VERSION=CS_7.2
+
+
+REM
+REM Set JAVA_HOME - specify the complete path to the JDK
+REM
+REM example: \\bermuda.redhat.com\sbc mounted as Y:
+REM
+
+REM SET JAVA_HOME=Y:\cms_jdk\WINNT\%JDK_VERSION%
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CS="CS 7.2"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0"
+ECHO.
+ECHO NOTE: No arguments are required to build the
+ECHO normalized %CS% ldif text classes.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%JAVA_HOME%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and JAVA_HOME
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_JAVA_HOME
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified JAVA_HOME exists
+REM
+
+:CHECK_JAVA_HOME
+IF EXIST %JAVA_HOME% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified JAVA_HOME does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%JAVA_HOME%\bin;%JAVA_HOME%\lib;%PATH%
+
+
+REM
+REM Set TARGET - identify the complete path to the new classes target directory
+REM
+
+SET TARGET=..\classes
+
+
+REM
+REM Create the new classes target directory (if it does not already exist)
+REM
+
+IF EXIST %TARGET% goto COMPILE_CLASSES
+MKDIR %TARGET%
+
+
+REM
+REM Compile 72ToTxt - create "CMS72LdifParser.class" and "Main.class"
+REM
+
+:COMPILE_CLASSES
+%JAVA_HOME%\bin\javac.exe -d %TARGET% -classpath %JAVA_HOME%\jre\lib\rt.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar Main.java
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/72ToTxt/src/compile.sh b/base/migrate/72ToTxt/src/compile.sh
new file mode 100755
index 000000000..6c616cd40
--- /dev/null
+++ b/base/migrate/72ToTxt/src/compile.sh
@@ -0,0 +1,139 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#####################################################################
+### ###
+### This script creates the "72ToTxt/classes/Main.class" and ###
+### "72ToTxt/classes/CMS72LdifParser.class" which are ###
+### used to create a normalized CS 7.2 ldif text file. ###
+### ###
+#####################################################################
+
+
+###
+### Set JDK_PLATFORM - must be "HP-UX", "Linux", or "SunOS"
+###
+
+#JDK_PLATFORM=Linux
+#export JDK_PLATFORM
+
+
+###
+### Set JDK_VERSION - specify the JDK version used by this version of CS
+###
+### CS 7.2 NOTE: "Linux" - 1.5.0 (IBM)
+### "SunOS" - 1.5.0
+###
+
+#JDK_VERSION=CS_7.2.0
+#export JDK_VERSION
+
+
+###
+### Set JAVA_HOME - specify the complete path to the JDK
+###
+
+#JAVA_HOME=/share/builds/components/cms_jdk/${JDK_PLATFORM}/${JDK_VERSION}
+#export JAVA_HOME
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CS="CS 7.2"
+export CS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -gt 0 ] ; then
+ echo
+ echo "Usage: $0"
+ echo
+ echo " NOTE: No arguments are required to build the"
+ echo " normalized ${CS} ldif text classes."
+ echo
+ exit 1
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${JAVA_HOME}" ] ; then
+ echo "ERROR: Please specify the JAVA_HOME "
+ echo " environment variables for this script!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified JAVA_HOME exists and is a directory
+###
+
+if [ ! -d "${JAVA_HOME}" ] ; then
+ echo "ERROR: Either the specified JAVA_HOME does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 4
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=/usr/lib:/usr/lib/dirsec:${JAVA_HOME}/lib:${JAVA_HOME}/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=/usr/lib:/usr/lib/dirsec:${JAVA_HOME}/lib:${JAVA_HOME}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=/usr/lib:/usr/lib/dirsec:${JAVA_HOME}/lib:${JAVA_HOME}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Set TARGET - identify the complete path to the new classes target directory
+###
+
+TARGET=../classes
+export TARGET
+
+
+###
+### Create the new classes target directory (if it does not already exist)
+###
+
+if [ ! -d ${TARGET} ]; then
+ mkdir -p ${TARGET}
+fi
+
+
+###
+### Compile 72ToTxt - create "CMS72LdifParser.class" and "Main.class"
+###
+
+${JAVA_HOME}/bin/javac -d ${TARGET} -classpath ${JAVA_HOME}/jre/lib/rt.jar:/usr/share/java/rhpki/nsutil.jar:/usr/share/java/rhpki/certsrv.jar:/usr/share/java/rhpki/cmscore.jar:/usr/lib/java/rhpki/ca/ca.jar:/usr/lib/java/rhpki/tks/tks.jar:/usr/lib/java/rhpki/ocsp/ocsp.jar:/usr/lib/java/rhpki/kra/kra.jar:/usr/lib/java/dirsec/jss4.jar Main.java
+
diff --git a/base/migrate/73ToTxt/classes/CMS73LdifParser.class b/base/migrate/73ToTxt/classes/CMS73LdifParser.class
new file mode 100644
index 000000000..9ca1fdfd5
--- /dev/null
+++ b/base/migrate/73ToTxt/classes/CMS73LdifParser.class
Binary files differ
diff --git a/base/migrate/73ToTxt/classes/Main.class b/base/migrate/73ToTxt/classes/Main.class
new file mode 100644
index 000000000..30a21375d
--- /dev/null
+++ b/base/migrate/73ToTxt/classes/Main.class
Binary files differ
diff --git a/base/migrate/73ToTxt/run.bat b/base/migrate/73ToTxt/run.bat
new file mode 100755
index 000000000..f360f44d0
--- /dev/null
+++ b/base/migrate/73ToTxt/run.bat
@@ -0,0 +1,192 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM This program is free software; you can redistribute it and/or modify
+REM it under the terms of the GNU General Public License as published by
+REM the Free Software Foundation; version 2 of the License.
+REM
+REM This program is distributed in the hope that it will be useful,
+REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+REM GNU General Public License for more details.
+REM
+REM You should have received a copy of the GNU General Public License along
+REM with this program; if not, write to the Free Software Foundation, Inc.,
+REM 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script converts a pre-existing CS 7.3 ldif data
+REM file (e. g. - created via a utility such as db2ldif)
+REM into a normalized CS 7.3 ldif text file.
+REM
+REM This subsequent normalized CS 7.3 ldif text file
+REM can be migrated into CS 7.3 or later utilizing
+REM the corresponding TxtTo<Target CS Version> script which
+REM converts this normalized CS 7.3 ldif text file into
+REM a <Target CS Version> ldif data file.
+REM
+REM This <Target CS Version> ldif data file can then be
+REM imported into the internal database of the desired CS
+REM server using a utility such as ldif2db.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM SERVER_ROOT - fully qualified path of the location of the server
+REM
+
+REM SET SERVER_ROOT=C:\cs73
+
+
+REM
+REM INSTANCE - if the CS instance directory is called 'cert-ca',
+REM set the CS instance to 'ca'
+REM
+REM NOTE: When a single SERVER_ROOT contains more than
+REM one CS instance, this script must be run multiple
+REM times. To do this, there is only a need to change
+REM the INSTANCE parameter.
+REM
+
+REM SET INSTANCE=ca
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CS="CS 7.3"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO USAGE
+IF "%3" == "" GOTO CHECK_INPUT_FILE
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0 input [errors] > output"
+ECHO.
+ECHO where: input - the specified %CS% ldif data file,
+ECHO errors - an optional errors file containing
+ECHO skipped attributes, and
+ECHO output - the normalized %CS% ldif text file.
+ECHO.
+ECHO NOTE: If no redirection is provided to
+ECHO 'output', then the normalized
+ECHO %CS% ldif text will merely
+ECHO be echoed to stdout.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified "input" file exists
+REM
+
+:CHECK_INPUT_FILE
+IF EXIST %1 GOTO CHECK_ERRORS_FILE
+
+
+ECHO ERROR: The specified input file, %1, does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM If an "errors" file is specified, then check that it does not already
+REM exist.
+REM
+
+:CHECK_ERRORS_FILE
+IF "%2" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+IF EXIST %2 GOTO ERRORS_FILE_ERROR
+GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:ERRORS_FILE_ERROR
+ECHO ERROR: The specified errors file, %2, already exists!
+ECHO Please specify a different file!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%INSTANCE%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and INSTANCE
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_INSTANCE
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified INSTANCE exists
+REM
+
+:CHECK_INSTANCE
+IF EXIST %SERVER_ROOT%\cert-%INSTANCE% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified INSTANCE does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%SERVER_ROOT%\bin\cert\jre\bin;%SERVER_ROOT\bin\cert\jre\bin\server;%PATH%
+
+
+REM
+REM Convert the specified %CS% ldif data file
+REM into a normalized %CS% ldif text file.
+REM
+
+%SERVER_ROOT%\bin\cert\jre\bin\java.exe -classpath .\classes;%SERVER_ROOT%\cert-%INSTANCE%\classes;%SERVER_ROOT%\bin\cert\classes;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar;%SERVER_ROOT%\bin\cert\jre\lib\rt.jar Main %1 %2
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/73ToTxt/run.sh b/base/migrate/73ToTxt/run.sh
new file mode 100755
index 000000000..a35994fb0
--- /dev/null
+++ b/base/migrate/73ToTxt/run.sh
@@ -0,0 +1,157 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+
+#####################################################################
+### ###
+### This script converts a pre-existing CS 7.3 ldif data ###
+### file (e. g. - created via a utility such as db2ldif) ###
+### into a normalized CS 7.3 ldif text file. ###
+### ###
+### This subsequent normalized CS 7.3 ldif text file ###
+### can be migrated into CS 7.3 or later utilizing ###
+### the corresponding TxtTo<Target CS Version> script which ###
+### converts this normalized CS 7.3 ldif text file into ###
+### a <Target CS Version> ldif data file. ###
+### ###
+### This <Target CS Version> ldif data file can then be ###
+### imported into the internal database of the desired CS ###
+### server using a utility such as ldif2db. ###
+### ###
+#####################################################################
+
+###
+### Java Runtime Environment
+###
+JRE_ROOT=/usr/lib/jvm/jre-1.5.0
+export JRE_ROOT
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+###
+### Script-defined constants
+###
+
+CS="CS 7.3"
+export CS
+
+OS_NAME=`uname`
+export OS_NAME
+
+ARCH=`uname -i`
+export ARCH
+
+
+##
+## Perform a usage check for the appropriate number of arguments:
+##
+
+if [ $# -lt 1 -o $# -gt 2 ] ; then
+ echo
+ echo "Usage: $0 input [errors] > output"
+ echo
+ echo " where: input - the specified ${CS} ldif data file,"
+ echo " errors - an optional errors file containing"
+ echo " skipped attributes, and"
+ echo " output - the normalized ${CS} ldif text file."
+ echo
+ echo " NOTE: If no redirection is provided to"
+ echo " 'output', then the normalized"
+ echo " ${CS} ldif text will merely"
+ echo " be echoed to stdout."
+ echo
+ exit 1
+fi
+
+
+###
+### Check that the specified "input" file exists and is a regular file.
+###
+
+if [ ! -f $1 ] ; then
+ echo "ERROR: Either the specified 'input' file, '$1', does not exist, "
+ echo " or it is not a regular file!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified "input" file exists and is not empty.
+###
+
+if [ ! -s $1 ] ; then
+ echo "ERROR: The specified 'input' file, '$1', is empty!"
+ echo
+ exit 3
+fi
+
+
+###
+### If an "errors" file is specified, then check that it does not already
+### exist.
+###
+
+if [ $# -eq 2 ] ; then
+ if [ -f $2 ] ; then
+ echo "ERROR: The specified 'errors' file, '$2', already exists!"
+ echo " Please specify a different file!"
+ echo
+ exit 4
+ fi
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+### NOTE: As of SunOS JDK 1.4.0, the required "Unicode" classes
+### have been moved from "i18n.jar" to "rt.jar".
+###
+CLASSPATH=/usr/share/rhpki/migrate/73ToTxt/classes:/usr/share/java/rhpki/certsrv.jar:/usr/share/java/rhpki/cmscore.jar:/usr/share/java/rhpki/nsutil.jar:/usr/lib/java/dirsec/jss4.jar:${JRE_ROOT}/lib/rt.jar
+export CLASSPATH
+
+if [ ${OS_NAME} = "Linux" ] ; then
+ if [ ${ARCH} = "i386" ] ; then
+ LD_LIBRARY_PATH=/usr/lib/dirsec:/usr/lib:${JRE_ROOT}/lib:${JRE_ROOT}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+ else # x86_64
+ LD_LIBRARY_PATH=/usr/lib64/dirsec:/usr/lib64:${JRE_ROOT}/lib:${JRE_ROOT}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+ CLASSPATH=/usr/share/rhpki/migrate/73ToTxt/classes:/usr/share/java/rhpki/certsrv.jar:/usr/share/java/rhpki/cmscore.jar:/usr/share/java/rhpki/nsutil.jar:/usr/lib64/java/dirsec/jss4.jar:${JRE_ROOT}/lib/rt.jar
+ export CLASSPATH
+ fi
+else # SunOS 64-bits
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/dirsec:/usr/lib/sparcv9:${JRE_ROOT}/lib:${JRE_ROOT}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+ CLASSPATH=/usr/share/rhpki/migrate/73ToTxt/classes:/usr/share/java/rhpki/certsrv.jar:/usr/share/java/rhpki/cmscore.jar:/usr/share/java/rhpki/nsutil.jar:/usr/lib/sparcv9/java/dirsec/jss4.jar:${JRE_ROOT}/lib/rt.jar
+ export CLASSPATH
+fi
+
+
+###
+### Convert the specified ${CS} ldif data file
+### into a normalized ${CS} ldif text file.
+###
+
+${JRE_ROOT}/bin/java -classpath ${CLASSPATH} Main $1 $2
diff --git a/base/migrate/73ToTxt/src/Main.java b/base/migrate/73ToTxt/src/Main.java
new file mode 100644
index 000000000..be26e9858
--- /dev/null
+++ b/base/migrate/73ToTxt/src/Main.java
@@ -0,0 +1,485 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+//
+// "71ToTxt/src/Main.java" is based upon a copy "70ToTxt/src/Main.java".
+//
+// Always comment any new code sections with a "CMS 7.1" header, and
+// apply these changes forward to all other "*ToTxt/src/Main.java" files
+// (including this comment header) so that these differences will only
+// appear when this file is diffed against an earlier "*ToTxt" version.
+//
+// This file should always be maintained by executing the following command:
+//
+// diff 70ToTxt/src/Main.java 71ToTxt/src/Main.java
+//
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import sun.misc.*;
+import org.mozilla.jss.*; // CMS 4.5 and later
+import org.mozilla.jss.crypto.*; // CMS 4.5 and later
+import netscape.security.util.*;
+
+public class Main
+{
+ public static void main(String args[])
+ {
+ try {
+ // initialize CryptoManager in CMS 4.5 and later
+ CryptoManager.initialize(".");
+ // load JSS provider in CMS 4.5 and later
+ java.security.Security.removeProvider("SUN version 1.2");
+ // The following call to "java.security.Security.insertProviderAt()"
+ // is no longer commented out in CMS 4.5 and later
+ java.security.Security.insertProviderAt(
+ new netscape.security.provider.CMS(), 0);
+ java.security.Provider ps[] =
+ java.security.Security.getProviders();
+ if (ps == null || ps.length <= 0) {
+ System.err.println("Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ System.err.println("Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+
+ // Parse the File
+ CMS73LdifParser parser = null;
+ if (args.length == 1) {
+ parser = new CMS73LdifParser(args[0]);
+ } else if (args.length == 2) {
+ parser = new CMS73LdifParser(args[0], args[1]);
+ } else {
+ throw new IOException("Invalid Parameters");
+ }
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+}
+
+class CMS73LdifParser
+{
+ // constants
+ private static final String DN =
+ "dn:";
+ // Directory Servers in CMS 4.7 and later use "requestAttributes"
+ private static final String REQUEST_ATTRIBUTES =
+ "requestAttributes::";
+ private static final String BEGIN =
+ "--- BEGIN ATTRIBUTES ---";
+ private static final String END =
+ "--- END ATTRIBUTES ---";
+
+ // variables
+ private String mFilename = null;
+ private String mErrorFilename = null;
+ private PrintWriter mErrorPrintWriter = null;
+
+ public CMS73LdifParser(String filename)
+ {
+ mFilename = filename;
+ }
+
+ public CMS73LdifParser(String filename, String errorFilename)
+ {
+ mFilename = filename;
+ mErrorFilename = errorFilename;
+ }
+
+ public void parse() throws Exception
+ {
+ if (mErrorFilename != null) {
+ mErrorPrintWriter = new PrintWriter(new FileOutputStream(mErrorFilename));
+ }
+ BufferedReader reader = new BufferedReader(
+ new FileReader(mFilename));
+ String line = null;
+ String dn = null;
+ StringBuffer requestAttributes = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DN)) {
+ dn = line;
+ }
+ if (line.startsWith(REQUEST_ATTRIBUTES)) {
+ requestAttributes = new StringBuffer();
+ // System.out.println(line);
+ requestAttributes.append(
+ line.substring(REQUEST_ATTRIBUTES.length(),
+ line.length()).trim());
+ continue;
+ }
+ if (requestAttributes == null) {
+ System.out.println(line);
+ continue;
+ }
+ if (line.startsWith(" ")) {
+ // System.out.println(line);
+ requestAttributes.append(line.trim());
+ } else {
+ parseAttributes(dn, requestAttributes);
+ requestAttributes = null;
+ System.out.println(line);
+ }
+ }
+ }
+
+ public void parseAttributes(String dn, StringBuffer attrs) throws Exception
+ {
+ BASE64Decoder decoder = new BASE64Decoder();
+ decodeHashtable(dn, decoder.decodeBuffer(attrs.toString()));
+
+// System.out.println(attrs);
+ }
+
+ public Object decode(byte[] data) throws
+ ObjectStreamException,
+ IOException,
+ ClassNotFoundException
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+ return is.readObject();
+ }
+
+ public void decodeHashtable(String dn, byte[] data) throws Exception
+ {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInputStream is = new ObjectInputStream(bis);
+
+ System.out.println(BEGIN);
+ String key = null;
+ while (true)
+ {
+ key = (String)is.readObject();
+ // end of table is marked with null
+ if (key == null) break;
+ try {
+ byte[] bytes = (byte[])is.readObject();
+ Object obj = decode(bytes);
+ output(key, obj);
+ } catch (Exception e) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + key);
+ }
+ }
+ }
+ System.out.println(END);
+ }
+
+ public void output(String key, Object obj) throws Exception
+ {
+ if (obj instanceof String) {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ } else if (obj instanceof netscape.security.x509.CertificateX509Key) {
+ netscape.security.x509.CertificateX509Key o =
+ (netscape.security.x509.CertificateX509Key)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateSubjectName) {
+ netscape.security.x509.CertificateSubjectName o =
+ (netscape.security.x509.CertificateSubjectName)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateExtensions) {
+ netscape.security.x509.CertificateExtensions o =
+ (netscape.security.x509.CertificateExtensions)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertInfo) {
+ netscape.security.x509.X509CertInfo o =
+ (netscape.security.x509.X509CertInfo)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl) {
+ netscape.security.x509.X509CertImpl o =
+ (netscape.security.x509.X509CertImpl)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateChain) {
+ netscape.security.x509.CertificateChain o =
+ (netscape.security.x509.CertificateChain)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.X509CertImpl[]) {
+ netscape.security.x509.X509CertImpl o[] =
+ (netscape.security.x509.X509CertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.X509CertInfo[]) {
+ netscape.security.x509.X509CertInfo o[] =
+ (netscape.security.x509.X509CertInfo[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() + "["+o.length + "," + i+"]"+"=" +
+ encoder.encodeBuffer(bos.toByteArray()));
+ }
+ } else if (obj instanceof netscape.security.x509.RevokedCertImpl[]) {
+ netscape.security.x509.RevokedCertImpl o[] =
+ (netscape.security.x509.RevokedCertImpl[])obj;
+ for (int i = 0; i < o.length; i++) {
+ DerOutputStream bos =
+ new DerOutputStream();
+ o[i].encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(bos.toByteArray()));
+ }
+ } else if (obj instanceof java.security.cert.Certificate[]) {
+ java.security.cert.Certificate o[] =
+ (java.security.cert.Certificate[])obj;
+ for (int i = 0; i < o.length; i++) {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o[i].getClass().getName() +"["+o.length+","+i+"]" + "=" +
+ encoder.encode(o[i].getEncoded()));
+ }
+ } else if (obj instanceof com.netscape.cmscore.base.ArgBlock) {
+ // CMS 6.1: created new "com.netscape.certsrv.base.IArgBlock" and
+ // moved old "com.netscape.certsrv.base.ArgBlock"
+ // to "com.netscape.cmscore.base.ArgBlock"
+ com.netscape.cmscore.base.ArgBlock o =
+ (com.netscape.cmscore.base.ArgBlock)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" +(String)o.get(k));
+ }
+ } else if (obj instanceof com.netscape.cmscore.dbs.KeyRecord) {
+ // CMS 6.0: moved "com.netscape.certsrv.dbs.keydb.KeyRecord"
+ // to "com.netscape.cmscore.dbs.KeyRecord"
+ com.netscape.cmscore.dbs.KeyRecord o =
+ (com.netscape.cmscore.dbs.KeyRecord)obj;
+ Enumeration<String> e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = e.nextElement();
+ Object ob = o.get(k);
+ if (ob != null) {
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + encoder.encode((byte[])ob));
+
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ }
+ } else if (obj instanceof com.netscape.certsrv.kra.ProofOfArchival) {
+ // CS 7.2: moved com.netscape.cmscore.kra.ProofOfArchival
+ // to com.netscape.certsrv.kra.ProofOfArchival
+ // CMS 6.0: moved "com.netscape.certsrv.kra.ProofOfArchival"
+ // to "com.netscape.cmscore.kra.ProofOfArchival"
+ com.netscape.certsrv.kra.ProofOfArchival o =
+ (com.netscape.certsrv.kra.ProofOfArchival)obj;
+ DerOutputStream bos =
+ new DerOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof com.netscape.certsrv.request.AgentApprovals) {
+ com.netscape.certsrv.request.AgentApprovals o =
+ (com.netscape.certsrv.request.AgentApprovals)obj;
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ com.netscape.certsrv.request.AgentApproval approval = (com.netscape.certsrv.request.AgentApproval)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ approval.getUserName() + ";" + approval.getDate().getTime());
+ }
+ } else if (obj instanceof com.netscape.certsrv.authentication.AuthToken) {
+ com.netscape.certsrv.authentication.AuthToken o =
+ (com.netscape.certsrv.authentication.AuthToken)obj;
+ Enumeration e = o.getElements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ Object ob = o.get(k);
+ if (ob instanceof java.util.Date) {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ((java.util.Date)ob).getTime());
+ } else if (ob instanceof java.math.BigInteger[]) {
+ // Bugzilla Bug #225031 (a.k.a. - Raidzilla Bug #58356)
+ java.math.BigInteger in[] = (java.math.BigInteger[])ob;
+ String numbers = "";
+ for (int i = 0; i < in.length; i++) {
+ if (numbers.equals("")) {
+ numbers = in[i].toString();
+ } else {
+ numbers = numbers + "," + in[i].toString();
+ }
+ }
+ System.out.println(" " +
+ key + ":" + "com.netscape.certsrv.authentication.AuthToken" + "=" +
+ k + ":java.lang.String=" + numbers);
+ } else if (ob instanceof String[]) {
+ // Bugzilla Bug #224763 (a.k.a. - Raidzilla Bug #57949)
+ // Bugzilla Bug #252240
+ String str[] = (String[])ob;
+ String v = "";
+ if (str != null) {
+ for (int i = 0; i < str.length; i++) {
+ if (i != 0) {
+ v += ",";
+ }
+ v += str[i];
+ }
+ }
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + "java.lang.String" + "=" + v);
+ } else {
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + ":" + ob.getClass().getName() + "=" + ob);
+ }
+ }
+ } else if (obj instanceof byte[]) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key + ":byte[]="+
+ encoder.encode((byte[])obj));
+ } else if (obj instanceof Integer[]) {
+ Integer in[] = (Integer[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":Integer[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof BigInteger[]) {
+ // Bugzilla Bug #238779
+ BigInteger in[] = (BigInteger[])obj;
+ for (int i = 0; i < in.length; i++) {
+ System.out.println(" " + key + ":java.math.BigInteger[" + in.length + "," + i + "]="+ in[i]);
+ }
+ } else if (obj instanceof String[]) {
+ // Bugzilla Bug #223360 (a.k.a - Raidzilla Bug #58086)
+ String str[] = (String[])obj;
+ for (int i = 0; i < str.length; i++) {
+ System.out.println(" " + key + ":java.lang.String[" + str.length + "," + i + "]="+ str[i]);
+ }
+ } else if (obj instanceof netscape.security.x509.CertificateAlgorithmId) {
+ netscape.security.x509.CertificateAlgorithmId o =
+ (netscape.security.x509.CertificateAlgorithmId)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateAlgorithmId="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof netscape.security.x509.CertificateValidity) {
+ netscape.security.x509.CertificateValidity o =
+ (netscape.security.x509.CertificateValidity)obj;
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ o.encode(bos);
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":netscape.security.x509.CertificateValidity="+
+ encoder.encode(bos.toByteArray()));
+ } else if (obj instanceof byte[]) {
+ // Since 6.1's profile framework,
+ // req_archive_options is a byte array
+ BASE64Encoder encoder = new BASE64Encoder();
+ System.out.println(" " + key +
+ ":byte[]="+
+ encoder.encode((byte[])obj));
+ } else if (obj instanceof java.util.Hashtable) {
+ // Bugzilla Bug #224800 (a.k.a - Raidzilla Bug #56953)
+ //
+ // Example: fingerprints:java.util.Hashtable=
+ // {SHA1=[B@52513a, MD5=[B@52c4d9, MD2=[B@799ff5}
+ //
+ java.util.Hashtable o = (java.util.Hashtable)obj;
+ BASE64Encoder encoder = new BASE64Encoder();
+ Enumeration e = o.elements();
+ while (e.hasMoreElements()) {
+ String k = (String)e.nextElement();
+ System.out.println(" " +
+ key + ":" + o.getClass().getName() + "=" +
+ k + "=" + encoder.encode((byte[])o.get(k)));
+ }
+ } else {
+ System.out.println(" " +
+ key + ":" + obj.getClass().getName() + "=" +
+ obj);
+ }
+ }
+}
+
diff --git a/base/migrate/73ToTxt/src/compile.bat b/base/migrate/73ToTxt/src/compile.bat
new file mode 100755
index 000000000..f5b720e54
--- /dev/null
+++ b/base/migrate/73ToTxt/src/compile.bat
@@ -0,0 +1,150 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script creates the "73ToTxt/classes/Main.class" and
+REM "73ToTxt/classes/CMS73LdifParser.class" which are
+REM used to create a normalized CS 7.3 ldif text file.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM Set SERVER_ROOT - identify the CS <server_root> used to compile 73ToTxt
+REM
+
+REM SET SERVER_ROOT=C:\cs73
+
+
+REM
+REM Set JDK_VERSION - specify the JDK version used by this version of CS
+REM
+REM CS 7.3 NOTE: "WINNT" - 1.4.2
+REM
+
+REM SET JDK_VERSION=CS_7.3
+
+
+REM
+REM Set JAVA_HOME - specify the complete path to the JDK
+REM
+REM example: \\bermuda.redhat.com\sbc mounted as Y:
+REM
+
+REM SET JAVA_HOME=Y:\cms_jdk\WINNT\%JDK_VERSION%
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CS="CS 7.3"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0"
+ECHO.
+ECHO NOTE: No arguments are required to build the
+ECHO normalized %CS% ldif text classes.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%JAVA_HOME%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and JAVA_HOME
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_JAVA_HOME
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified JAVA_HOME exists
+REM
+
+:CHECK_JAVA_HOME
+IF EXIST %JAVA_HOME% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified JAVA_HOME does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%JAVA_HOME%\bin;%JAVA_HOME%\lib;%PATH%
+
+
+REM
+REM Set TARGET - identify the complete path to the new classes target directory
+REM
+
+SET TARGET=..\classes
+
+
+REM
+REM Create the new classes target directory (if it does not already exist)
+REM
+
+IF EXIST %TARGET% goto COMPILE_CLASSES
+MKDIR %TARGET%
+
+
+REM
+REM Compile 73ToTxt - create "CMS73LdifParser.class" and "Main.class"
+REM
+
+:COMPILE_CLASSES
+%JAVA_HOME%\bin\javac.exe -d %TARGET% -classpath %JAVA_HOME%\jre\lib\rt.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar Main.java
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/73ToTxt/src/compile.sh b/base/migrate/73ToTxt/src/compile.sh
new file mode 100755
index 000000000..0c8975c4a
--- /dev/null
+++ b/base/migrate/73ToTxt/src/compile.sh
@@ -0,0 +1,138 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#####################################################################
+### ###
+### This script creates the "73ToTxt/classes/Main.class" and ###
+### "73ToTxt/classes/CMS73LdifParser.class" which are ###
+### used to create a normalized CS 7.3 ldif text file. ###
+### ###
+#####################################################################
+
+
+###
+### Set JDK_PLATFORM - must be "HP-UX", "Linux", or "SunOS"
+###
+
+JDK_PLATFORM=Linux
+export JDK_PLATFORM
+
+
+###
+### Set JDK_VERSION - specify the JDK version used by this version of CS
+###
+### CS 7.3 NOTE: "Linux" - 1.5.0 (IBM)
+### "SunOS" - 1.5.0
+###
+
+JDK_VERSION=PKI_7.3.0
+export JDK_VERSION
+
+
+###
+### Set JAVA_HOME - specify the complete path to the JDK
+###
+
+JAVA_HOME=/share/builds/components/cms_jdk/${JDK_PLATFORM}/${JDK_VERSION}
+export JAVA_HOME
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CS="CS 7.3"
+export CS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -gt 0 ] ; then
+ echo
+ echo "Usage: $0"
+ echo
+ echo " NOTE: No arguments are required to build the"
+ echo " normalized ${CS} ldif text classes."
+ echo
+ exit 1
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${JAVA_HOME}" ] ; then
+ echo "ERROR: Please specify the JAVA_HOME "
+ echo " environment variables for this script!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified JAVA_HOME exists and is a directory
+###
+
+if [ ! -d "${JAVA_HOME}" ] ; then
+ echo "ERROR: Either the specified JAVA_HOME does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 4
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=/usr/lib:/usr/lib/dirsec:${JAVA_HOME}/lib:${JAVA_HOME}/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=/usr/lib:/usr/lib/dirsec:${JAVA_HOME}/lib:${JAVA_HOME}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=/usr/lib:/usr/lib/dirsec:${JAVA_HOME}/lib:${JAVA_HOME}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Set TARGET - identify the complete path to the new classes target directory
+###
+
+TARGET=../classes
+export TARGET
+
+
+###
+### Create the new classes target directory (if it does not already exist)
+###
+
+if [ ! -d ${TARGET} ]; then
+ mkdir -p ${TARGET}
+fi
+
+
+###
+### Compile 73ToTxt - create "CMS73LdifParser.class" and "Main.class"
+###
+
+${JAVA_HOME}/bin/javac -d ${TARGET} -classpath ${JAVA_HOME}/jre/lib/rt.jar:/usr/share/java/rhpki/nsutil.jar:/usr/share/java/rhpki/certsrv.jar:/usr/share/java/rhpki/cmscore.jar:/usr/lib/java/rhpki/ca/ca.jar:/usr/lib/java/rhpki/tks/tks.jar:/usr/lib/java/rhpki/ocsp/ocsp.jar:/usr/lib/java/rhpki/kra/kra.jar:/usr/lib/java/dirsec/jss4.jar Main.java
+
diff --git a/base/migrate/80/MigrateSecurityDomain.class b/base/migrate/80/MigrateSecurityDomain.class
new file mode 100644
index 000000000..f2a174dab
--- /dev/null
+++ b/base/migrate/80/MigrateSecurityDomain.class
Binary files differ
diff --git a/base/migrate/80/MigrateSecurityDomain.java b/base/migrate/80/MigrateSecurityDomain.java
new file mode 100644
index 000000000..4624f1259
--- /dev/null
+++ b/base/migrate/80/MigrateSecurityDomain.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) 2008 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+
+import com.netscape.cmscore.base.FileConfigStore;
+import com.netscape.cmscore.ldapconn.LdapJssSSLSocketFactory;
+import com.netscape.cmsutil.ldap.LDAPUtil;
+import com.netscape.cmsutil.xml.XMLObject;
+
+public class MigrateSecurityDomain {
+
+ private static LDAPConnection getLDAPConn(FileConfigStore cs, String passwd)
+ throws IOException {
+
+ String host = "";
+ String port = "";
+ String binddn = "";
+ String security = "";
+
+ 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) {
+ System.out.println("MigrateSecurityDomain: getLDAPConnection" + e.toString());
+ throw new IOException(
+ "Failed to retrieve LDAP information from CS.cfg.");
+ }
+
+ int p = -1;
+
+ try {
+ p = Integer.parseInt(port);
+ } catch (Exception e) {
+ System.out.println("MigrateSecurityDomain getLDAPConn: " + e.toString());
+ throw new IOException("Port is not valid");
+ }
+
+ LDAPConnection conn = null;
+ if (security.equals("true")) {
+ System.out.println("MigrateSecurityDomain getLDAPConn: creating secure (SSL) connection for internal ldap");
+ conn = new LDAPConnection(new LdapJssSSLSocketFactory());
+ } else {
+ System.out.println(
+ "MigrateSecurityDomain getLDAPConn: creating non-secure (non-SSL) connection for internal ldap");
+ conn = new LDAPConnection();
+ }
+
+ System.out.println("MigrateSecurityDomain connecting to " + host + ":" + p);
+ try {
+ conn.connect(host, p, binddn, passwd);
+ } catch (LDAPException e) {
+ System.out.println("MigrateSecurityDomain getLDAPConn: " + e.toString());
+ throw new IOException("Failed to connect to the internal database.");
+ }
+
+ return conn;
+ }
+
+ public static void main(String args[]) throws Exception {
+ if (args.length != 2) {
+ System.out.println("Usage: MigrateSecurityDomain <instance root path> <directory manager password>");
+ System.exit(0);
+ }
+
+ String instRoot = args[0];
+ String dmPass = args[1];
+
+ XMLObject parser = null;
+ // get the security domain data from the domain.xml file
+ try {
+ String path = instRoot + "/conf/domain.xml";
+ System.out.println("MigrateSecurityDomain: Reading domain.xml from file ...");
+ parser = new XMLObject(new FileInputStream(path));
+
+ } catch (Exception e) {
+ System.out.println("MigrateSecurityDomain: Unable to get domain info from domain.xml file");
+ System.out.println(e.toString());
+ System.exit(1);
+ }
+
+ try {
+ String configFile = instRoot + "/conf/CS.cfg";
+ FileConfigStore cs = new FileConfigStore(configFile);
+
+ LDAPConnection conn = null;
+ conn = MigrateSecurityDomain.getLDAPConn(cs, dmPass);
+ if (conn == null) {
+ System.out.println("MigrateSecurityDomain: Failed to connect to internal database");
+ System.exit(1);
+ }
+
+ // add new schema elements
+ String importFile = "./schema-add.ldif";
+ ArrayList<String> errors = new ArrayList<String>();
+ try {
+ LDAPUtil.importLDIF(conn, importFile, errors);
+ if (! errors.isEmpty()) {
+ System.out.println("MigrateSecurityDomain: Errors in adding new schema elements:");
+ for (String error: errors) {
+ System.out.println(error);
+ }
+ }
+ } catch (Exception e) {
+ System.out.println("MigrateSecurityDomain: Error in adding new schema elements");
+ System.exit(1);
+ }
+ // create the containers
+ String basedn = cs.getString("internaldb.basedn");
+ String secdomain = parser.getValue("Name");
+
+ try {
+ String dn = "ou=Security Domain," + basedn;
+ System.out.println("MigrateSecurityDomain: creating ldap entry : " + dn);
+
+ 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("name", secdomain));
+ attrs.add(new LDAPAttribute("ou", "Security Domain"));
+ entry = new LDAPEntry(dn, attrs);
+ conn.add(entry);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() != 68) {
+ System.out.println("Unable to create security domain" + e.toString());
+ System.exit(1);
+ }
+ }
+
+ // create list containers
+ String clist[] = { "CAList", "OCSPList", "KRAList", "RAList", "TKSList", "TPSList" };
+ for (int i = 0; i < 6; 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);
+ try {
+ conn.add(entry);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() != 68) {
+ System.out.println("Unable to create security domain list entry " + dn + ": " + e.toString());
+ System.exit(1);
+ }
+ }
+ }
+
+ // create system entries
+ String tlist[] = { "CA", "OCSP", "KRA", "RA", "TKS", "TPS" };
+ Document doc = parser.getDocument();
+ for (int j = 0; j < 6; j++) {
+ String type = tlist[j];
+ NodeList nodeList = doc.getElementsByTagName(type);
+ int len = nodeList.getLength();
+ for (int i = 0; i < len; i++) {
+ Vector<String> v_clone = parser.getValuesFromContainer(nodeList.item(i), "Clone");
+ Vector<String> v_name = parser.getValuesFromContainer(nodeList.item(i), "SubsystemName");
+ Vector<String> v_host = parser.getValuesFromContainer(nodeList.item(i), "Host");
+ Vector<String> v_port = parser.getValuesFromContainer(nodeList.item(i), "SecurePort");
+
+ String cn = (String) v_host.elementAt(0) + ":" + (String) v_port.elementAt(0);
+ String dn = "cn=" + cn + ",cn=" + type + "List,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", (String) v_host.elementAt(0)));
+ attrs.add(new LDAPAttribute("SecurePort", (String) v_port.elementAt(0)));
+ attrs.add(new LDAPAttribute("Clone", (String) v_clone.elementAt(0)));
+ attrs.add(new LDAPAttribute("SubsystemName", (String) v_name.elementAt(0)));
+ attrs.add(new LDAPAttribute("cn", cn));
+ attrs.add(new LDAPAttribute("DomainManager", "true"));
+ // Since the initial port separation feature didn't occur
+ // until an RHCS 7.3 errata, simply store the "SecurePort"
+ // value for BOTH the "SecureAgentPort" and the
+ // "SecureAdminPort", and DON'T store any values for the
+ // "UnSecurePort"
+ attrs.add(new LDAPAttribute("SecureAgentPort", (String) v_port.elementAt(0)));
+ attrs.add(new LDAPAttribute("SecureAdminPort", (String) v_port.elementAt(0)));
+ entry = new LDAPEntry(dn, attrs);
+
+ try {
+ conn.add(entry);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() != 68) {
+ System.out.println("Unable to create entry " + dn + ": " + e.toString());
+ }
+ }
+ }
+ }
+ cs.putString("securitydomain.store", "ldap");
+ cs.commit(false);
+ System.out.println("MigrateSecurityDomain: Domain successfully migrated.");
+ } catch (Exception e) {
+ System.out.println("MigrateSecurityDomain: Migration failed. " + e.toString());
+ }
+ System.exit(0);
+ }
+
+}
diff --git a/base/migrate/80/readme b/base/migrate/80/readme
new file mode 100644
index 000000000..50365c985
--- /dev/null
+++ b/base/migrate/80/readme
@@ -0,0 +1,29 @@
+Date
+
+ Fri Oct 3 00:37:14 EDT 2008
+
+Version
+
+ CMS 8.0
+
+Overview
+
+ In CMS8.0, the security domain data has been migrated into the
+ internal LDAP database to allow easier replication of this data
+ when cloning. Prior to this release, this information was stored
+ in the domain.xml configuration file on the CA serving as the Domain
+ Master.
+
+Program
+
+ MigrateSecurityDomain - This command will add the relevant schema and migrate
+ security domain data that resides in domain.xml into the internal database.
+ The program needs only two arguments - the location of the instance root directory
+ (like /var/lib/pki-ca) and the directory user's password.
+
+Example
+
+ Here is an example of MigrateSecurityDomain usage
+java -cp /usr/share/java/ldapjdk.jar:/usr/share/java/pki/cmscore.jar:/usr/share/java/pki/cmsutil.jar:/usr/share/java/pki/certsrv.jar:. MigrateSecurityDomain /var/lib/pki-ca mypassword
+
+
diff --git a/base/migrate/80/schema-add.ldif b/base/migrate/80/schema-add.ldif
new file mode 100644
index 000000000..fe6577e51
--- /dev/null
+++ b/base/migrate/80/schema-add.ldif
@@ -0,0 +1,50 @@
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( Clone-oid NAME 'Clone' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( DomainManager-oid NAME 'DomainManager' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SecurePort-oid NAME 'SecurePort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SecureAgentPort-oid NAME 'SecureAgentPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SecureAdminPort-oid NAME 'SecureAdminPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( UnSecurePort-oid NAME 'UnSecurePort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SubsystemName-oid NAME 'SubsystemName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( pkiSecurityDomain-oid NAME 'pkiSecurityDomain' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ name ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( pkiSecurityGroup-oid NAME 'pkiSecurityGroup' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( pkiSubsystem-oid NAME 'pkiSubsystem' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ Host $ SecurePort $ SubsystemName $ Clone ) MAY ( DomainManager $ SecureAgentPort $ SecureAdminPort $ UnSecurePort ) X-ORIGIN 'user defined' )
+
diff --git a/base/migrate/CMakeLists.txt b/base/migrate/CMakeLists.txt
new file mode 100644
index 000000000..94cc990f6
--- /dev/null
+++ b/base/migrate/CMakeLists.txt
@@ -0,0 +1,36 @@
+project(migrate)
+
+set(INSTALL_DIRS
+ 41ToTxt
+ 42SP2ToTxt
+ 42ToTxt
+ 45ToTxt
+ 47ToTxt
+ 60ToTxt
+ 61ToTxt
+ 62ToTxt
+ 63ToTxt
+ 70ToTxt
+ 71ToTxt
+ 72ToTxt
+ 73ToTxt
+ 80
+ TpsTo80
+ TxtTo60
+ TxtTo61
+ TxtTo62
+ TxtTo70
+ TxtTo71
+ TxtTo72
+ TxtTo73
+ TxtTo80
+)
+
+foreach(INSTALL_DIR ${INSTALL_DIRS})
+ install(
+ DIRECTORY
+ ${INSTALL_DIR}
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/${INSTALL_DIR}
+ )
+endforeach(INSTALL_DIR ${INSTALL_DIRS})
diff --git a/base/migrate/LICENSE b/base/migrate/LICENSE
new file mode 100644
index 000000000..e281f4362
--- /dev/null
+++ b/base/migrate/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/base/migrate/TpsTo80/Makefile b/base/migrate/TpsTo80/Makefile
new file mode 100644
index 000000000..99c0d275c
--- /dev/null
+++ b/base/migrate/TpsTo80/Makefile
@@ -0,0 +1,36 @@
+OS_ARCH := $(subst /,_,$(shell uname -s))
+
+ifeq ($(OS_ARCH), Linux)
+ CC = gcc
+ CFLAGS = -g
+ LDFLAGS = -s -lldif60 -lplc4 -lplds4 -lnspr4
+else
+ifeq ($(OS_ARCH), SunOS)
+ CC = cc
+ LINTFLAGS = -c
+ CFLAGS = -dalign -xO2 -xarch=v9 -DSOLARIS
+ INCLUDE_PATH = -I/usr/include/dirsec
+ LDFLAGS = -s -L/usr/lib/64 -lldif60 -L/usr/lib/64/dirsec -R/usr/lib/64/dirsec -lplc4 -lplds4 -lnspr4
+endif # SunOS
+endif # Linux
+
+OBJS = migrateTPSData.o
+
+SRCS = migrateTPSData.c
+
+all: migrateTPSData
+
+$(OBJS): $(SRCS)
+ $(CC) $(CFLAGS) $(INCLUDE_PATH) -c $< \
+ -o $*.o
+
+migrateTPSData: $(OBJS)
+ $(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS)
+
+lint: $(SRCS)
+ lint $(LINTFLAGS) $(CFLAGS) $(INCLUDE_PATH) $(SRCS)
+
+clean:
+ -rm migrateTPSData.ln
+ -rm migrateTPSData.o
+ -rm migrateTPSData
diff --git a/base/migrate/TpsTo80/linux/migrateTPSData.i386 b/base/migrate/TpsTo80/linux/migrateTPSData.i386
new file mode 100755
index 000000000..9fd4b3906
--- /dev/null
+++ b/base/migrate/TpsTo80/linux/migrateTPSData.i386
Binary files differ
diff --git a/base/migrate/TpsTo80/linux/migrateTPSData.x86_64 b/base/migrate/TpsTo80/linux/migrateTPSData.x86_64
new file mode 100755
index 000000000..d89125c7e
--- /dev/null
+++ b/base/migrate/TpsTo80/linux/migrateTPSData.x86_64
Binary files differ
diff --git a/base/migrate/TpsTo80/migrateTPSData.c b/base/migrate/TpsTo80/migrateTPSData.c
new file mode 100644
index 000000000..a4cf340ab
--- /dev/null
+++ b/base/migrate/TpsTo80/migrateTPSData.c
@@ -0,0 +1,501 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef SOLARIS
+#include <mozldap6/ldif.h>
+#else
+#include <mozldap/ldif.h>
+#endif
+#include <ctype.h>
+#include <nspr4/nspr.h>
+#include <nspr4/plstr.h>
+#include <nspr4/plhash.h>
+#include <nspr4/prmem.h>
+#include <nspr4/prprf.h>
+#include <nspr4/prsystem.h>
+#include <errno.h>
+#include <string.h>
+
+#define SHORT_LEN 512
+#define NO_TOKEN_TYPE "no_token_type"
+
+static PLHashTable *token_set;
+static FILE *infile;
+static FILE *outfile;
+
+/* hash functions */
+static PR_CALLBACK void*
+_AllocTable(void* pool, PRSize size)
+{
+ return PR_MALLOC(size);
+}
+
+static PR_CALLBACK void
+_FreeTable(void* pool, void* item)
+{
+ PR_DELETE(item);
+}
+
+static PR_CALLBACK PLHashEntry*
+_AllocEntry(void* pool, const void* key)
+{
+ return PR_NEW(PLHashEntry);
+}
+
+static PR_CALLBACK void
+_FreeEntry(void* pool, PLHashEntry* he, PRUintn flag)
+{
+ if( he == NULL ) {
+ return;
+ }
+
+ if (flag == HT_FREE_VALUE) {
+ if( he->value != NULL ) {
+ PL_strfree( ( char* ) he->value );
+ he->value = NULL;
+ }
+ } else if (flag == HT_FREE_ENTRY) {
+ if( he->key != NULL ) {
+ PL_strfree( ( char* ) he->key );
+ he->key = NULL;
+ }
+ if( he->value != NULL ) {
+ PL_strfree( ( char* ) he->value );
+ he->value = NULL;
+ }
+ PR_DELETE(he);
+ }
+}
+
+static PLHashAllocOps _AllocOps = {
+ _AllocTable,
+ _FreeTable,
+ _AllocEntry,
+ _FreeEntry
+};
+
+/* utility functions */
+#ifdef SOLARIS
+void do_free(char * buf)
+{
+ if (buf != NULL) {
+ PR_Free(buf);
+ buf = NULL;
+ }
+}
+#else
+inline void do_free(char * buf)
+{
+ if (buf != NULL) {
+ PR_Free(buf);
+ buf = NULL;
+ }
+}
+#endif
+
+
+
+char *get_field( char *s, char* fname, int len)
+{
+ char *end = NULL;
+ int n;
+
+ if( ( s = PL_strstr( s, fname ) ) == NULL ) {
+ return NULL;
+ }
+
+ s += strlen(fname);
+ end = PL_strchr( s, ' ' );
+
+ if( end != NULL ) {
+ n = end - s;
+ } else {
+ n = PL_strlen( s );
+ }
+
+ if (n == 0) {
+ return NULL;
+ } else if (n > len) {
+ /* string too long */
+ return NULL;
+ } else {
+ return PL_strndup( s, n );
+ }
+}
+
+/*
+ * Read the ldif, munge the entry and write to output.
+ */
+int read_and_modify_ldif() {
+ // user changes
+ static char agent_entry[] = "dn: cn=TUS Agents,ou=Groups";
+ static int agent_ent_len = sizeof(agent_entry)-1;
+ static char admin_entry[] = "dn: cn=TUS Adminstrators,ou=Groups";
+ static int admin_ent_len = sizeof(admin_entry)-1;
+ static char operator_entry[] = "dn: cn=TUS Officers,ou=Groups";
+ static int operator_ent_len = sizeof(operator_entry)-1;
+ static char user_entry[] = "ou=People";
+
+ // token changes
+ static char token_entry[] = "ou=Tokens";
+
+ // activity changes
+ static char activity_entry[] = "ou=Activities";
+
+ char *entry = 0;
+ int lineno = 0;
+
+ while ((entry = ldif_get_entry(infile, &lineno))) {
+ char *begin = entry;
+
+ if (!PL_strncasecmp(entry, agent_entry, agent_ent_len)) {
+ process_agent_entry(entry);
+ } else if (!PL_strncasecmp(entry, admin_entry, admin_ent_len)) {
+ process_admin_entry(entry);
+ } else if (!PL_strncasecmp(entry, operator_entry, operator_ent_len)) {
+ process_operator_entry(entry);
+ } else if (PL_strstr(entry, token_entry) != NULL) {
+ process_token_entry(entry);
+ } else if (PL_strstr(entry, activity_entry) != NULL) {
+ process_activity_entry(entry);
+ } else if ((PL_strstr(entry, user_entry) != NULL) &&
+ (PL_strstr(entry, "objectClass: organizationalunit") == NULL)) {
+ process_user_entry(entry);
+ } else {
+ process_unchanged_entry(entry);
+ fprintf(outfile, "\n");
+ }
+ free(begin);
+ }
+ return 0;
+}
+
+/**
+ * read the file, parse the activity records
+ * record the tokenTypes found for later use
+ */
+int parse_ldif_activities() {
+ // activity changes
+ static char activity_entry[] = "ou=Activities";
+
+ char *entry = 0;
+ int lineno = 0;
+
+ while ((entry = ldif_get_entry(infile, &lineno))) {
+ char *begin = entry;
+ if (PL_strstr(entry, activity_entry) != NULL) {
+ parse_activity_entry(entry);
+ }
+ free(begin);
+ }
+ return 0;
+}
+
+int parse_activity_entry(char* entry) {
+ static char tokenMsg_attr[] = "tokenMsg";
+ static char tokenid_attr[] = "tokenID";
+ char *line = entry;
+ char *tokenType = NULL;
+ char *cuid = NULL;
+ while ((line = ldif_getline(&entry))) {
+ char *type, *value;
+ int vlen = 0;
+ int rc;
+
+ if ( *line == '\n' || *line == '\0' ) {
+ break;
+ }
+
+ /* this call modifies line */
+ rc = ldif_parse_line(line, &type, &value, &vlen);
+ if (rc != 0) {
+ printf("Unknown error processing ldif entry: %s\n", entry);
+ } else {
+ if (!PL_strncasecmp(type, tokenMsg_attr, SHORT_LEN)) {
+ tokenType = get_field(value, "tokenType=",SHORT_LEN);
+ } else if (!PL_strncasecmp(type, tokenid_attr, SHORT_LEN)) {
+ cuid = PL_strdup(value);
+ }
+ }
+ }
+
+ if ((tokenType != NULL) && (cuid != NULL)) {
+ if ((char *) PL_HashTableLookupConst(token_set, cuid) == NULL) {
+ PL_HashTableAdd(token_set, PL_strdup(cuid), PL_strdup(tokenType));
+ //printf("Adding entry: %s %s to hash\n", cuid, tokenType);
+ }
+ }
+ do_free(cuid);
+ do_free(tokenType);
+ return 0;
+}
+
+
+
+/* change uniqueMember -> member */
+int process_agent_entry(char* entry) {
+ static char member_attr[] = "uniqueMember";
+
+ char *line = entry;
+ while ((line = ldif_getline(&entry))) {
+ char *type, *value;
+ int vlen = 0;
+ int rc;
+
+ if ( *line == '\n' || *line == '\0' ) {
+ break;
+ }
+
+ /* this call modifies line */
+ rc = ldif_parse_line(line, &type, &value, &vlen);
+ if (rc != 0) {
+ printf("Unknown error processing ldif entry: %s\n", entry);
+ } else {
+ if (!PL_strncasecmp(type, member_attr, SHORT_LEN)) {
+ fprintf(outfile, "member: %s\n", value);
+ } else if ((!PL_strncasecmp(type, "objectClass", SHORT_LEN)) && (!PL_strncasecmp(value, "groupOfUniqueNames", SHORT_LEN))) {
+ fprintf(outfile, "objectClass: groupOfNames\n");
+ } else {
+ fprintf(outfile, "%s", ldif_type_and_value(type, value, vlen));
+ }
+ }
+ }
+ fprintf(outfile, "\n");
+ return 0;
+}
+
+/* same as agent */
+int process_operator_entry(char* entry) {
+ return process_agent_entry(entry);
+}
+
+/* change uniqueMember -> member
+ * change typo in dn
+ */
+int process_admin_entry(char* entry) {
+ static char member_attr[] = "uniqueMember";
+ static char dn_attr[] = "dn";
+
+ char *line = entry;
+ while ((line = ldif_getline(&entry))) {
+ char *type, *value;
+ int vlen = 0;
+ int rc;
+
+ if ( *line == '\n' || *line == '\0' ) {
+ break;
+ }
+
+ /* this call modifies line */
+ rc = ldif_parse_line(line, &type, &value, &vlen);
+ if (rc != 0) {
+ printf("Unknown error processing ldif entry: %s", entry);
+ } else {
+ if (!PL_strncasecmp(type, member_attr, SHORT_LEN)) {
+ fprintf(outfile, "member: %s\n", value);
+ } else if (!PL_strncasecmp(type, dn_attr, SHORT_LEN)) {
+ int rep_size = PL_strlen("cn=TUS Adminstrators,ou=Groups,");
+ fprintf(outfile, "dn: cn=TUS Administrators,ou=Groups,%s\n", value + rep_size);
+ } else if ((!PL_strncasecmp(type, "objectClass", SHORT_LEN)) && (!PL_strncasecmp(value, "groupOfUniqueNames", SHORT_LEN))) {
+ fprintf(outfile, "objectClass: groupOfNames\n");
+ } else {
+ fprintf(outfile, "%s", ldif_type_and_value(type, value, vlen));
+ }
+ }
+ }
+ fprintf(outfile, "\n");
+ return 0;
+}
+
+int process_user_entry(char *entry) {
+ process_unchanged_entry(entry);
+ fprintf(outfile, "objectClass: tpsProfileId\n");
+ fprintf(outfile, "profileID: All Profiles\n");
+ fprintf(outfile, "\n");
+ return 0;
+}
+
+int process_unchanged_entry(char *entry) {
+ char *line = entry;
+ while ((line = ldif_getline(&entry))) {
+ char *type, *value;
+ int vlen = 0;
+ int rc;
+
+ if ( *line == '\n' || *line == '\0' ) {
+ break;
+ }
+
+ /* this call modifies line */
+ rc = ldif_parse_line(line, &type, &value, &vlen);
+ if (rc != 0) {
+ printf("Unknown error processing ldif entry: %s\n", entry);
+ } else {
+ fprintf(outfile, "%s", ldif_type_and_value(type, value, vlen));
+ }
+ }
+ return 0;
+}
+
+int process_activity_entry(char *entry) {
+ static char tokenmsg_attr[] = "tokenMsg";
+ static char tokenid_attr[] = "tokenID";
+ char *line = entry;
+ char *tokenType = NULL;
+ char *cuid = NULL;
+ char *dn = NULL;
+ while ((line = ldif_getline(&entry))) {
+ char *type, *value;
+ int vlen = 0;
+ int rc;
+
+ if ( *line == '\n' || *line == '\0' ) {
+ break;
+ }
+
+ /* this call modifies line */
+ rc = ldif_parse_line(line, &type, &value, &vlen);
+ if (rc != 0) {
+ printf("Unknown error processing ldif entry: %s\n", entry);
+ } else {
+ fprintf(outfile, "%s", ldif_type_and_value(type, value, vlen));
+
+ if (!PL_strncasecmp(type, tokenmsg_attr, SHORT_LEN)) {
+ tokenType = get_field(value, "tokenType=",SHORT_LEN);
+ if (tokenType != NULL) {
+ fprintf(outfile, "tokenType: %s\n", tokenType);
+ }
+ } else if (!PL_strncasecmp(type, tokenid_attr, SHORT_LEN)) {
+ cuid = PL_strdup(value);
+ } else if (!PL_strncasecmp(type, tokenid_attr, SHORT_LEN)) {
+ dn = PL_strdup(value);
+ }
+ }
+ }
+
+ if ((tokenType == NULL) && (cuid!= NULL)) {
+ // check hash for a value
+ if (PL_HashTableLookupConst(token_set, cuid) != NULL) {
+ fprintf(outfile, "tokenType: %s\n", (char *) PL_HashTableLookupConst(token_set, cuid));
+ } else {
+ fprintf(outfile, "tokenType: %s\n", NO_TOKEN_TYPE);
+ // log error here - unable to set token type using dn
+ }
+ }
+ fprintf(outfile, "\n");
+ do_free(cuid);
+ do_free(dn);
+ do_free(tokenType);
+
+ return 0;
+}
+
+int process_token_entry(char* entry) {
+ static char cn_attr[] = "cn";
+ static char dn_attr[] = "dn";
+ char *line = entry;
+ char *tokenType = NULL;
+ char *dn = NULL;
+ while ((line = ldif_getline(&entry))) {
+ char *type, *value;
+ int vlen = 0;
+ int rc;
+
+ if ( *line == '\n' || *line == '\0' ) {
+ break;
+ }
+
+ /* this call modifies line */
+ rc = ldif_parse_line(line, &type, &value, &vlen);
+ if (rc != 0) {
+ printf("Unknown error processing ldif entry: %s\n", entry);
+ } else {
+ fprintf(outfile, "%s", ldif_type_and_value(type, value, vlen));
+
+ if (!PL_strncasecmp(type, cn_attr, SHORT_LEN)) {
+ if (value != NULL) {
+ tokenType = (char *) PL_HashTableLookupConst(token_set, value);
+ }
+ if (tokenType != NULL) {
+ fprintf(outfile, "tokenType: %s\n", tokenType);
+ } else {
+ fprintf(outfile, "tokenType: %s\n", NO_TOKEN_TYPE);
+ }
+ } else if (!PL_strncasecmp(type, dn_attr, SHORT_LEN)) {
+ dn = PL_strdup(value);
+ }
+ }
+ }
+ if ((tokenType == NULL) && (dn != NULL)) {
+ //log the error
+ }
+ fprintf(outfile, "\n");
+ do_free(dn);
+ return 0;
+}
+
+
+int main (int argc, char *argv[]) {
+ char *in_fname = NULL;
+ char *out_fname = NULL;
+
+ if (argc < 3) {
+ printf ("Usage:\n %s infile outfile\n", argv[0]);
+ return 1;
+ }
+
+ in_fname = argv[1];
+ infile = fopen(in_fname, "r");
+ if (infile == NULL) {
+ perror("Error opening input file");
+ return 1;
+ }
+
+ out_fname = argv[2];
+ outfile = fopen(out_fname, "w");
+ if (outfile == NULL) {
+ perror("Error opening output file");
+ return 1;
+ }
+
+ //declare hash
+ token_set = PL_NewHashTable(3, PL_HashString,
+ PL_CompareStrings, PL_CompareValues,
+ &_AllocOps, NULL);
+
+ printf("Parsing LDIF file for Token Activities\n");
+ parse_ldif_activities();
+ rewind(infile);
+
+ printf("Parsing old LDIF file, and creating new LDIF file\n\n");
+ read_and_modify_ldif();
+
+ printf("Operation is complete.\nA new LDIF file has been written at %s, \n", out_fname);
+ printf("to be imported into the database of your new TPS. \nPlease attend to any errors reported.\n\n");
+
+ fclose(infile);
+ fclose(outfile);
+ return 0;
+}
+
diff --git a/base/migrate/TpsTo80/readme b/base/migrate/TpsTo80/readme
new file mode 100644
index 000000000..aa98de930
--- /dev/null
+++ b/base/migrate/TpsTo80/readme
@@ -0,0 +1,44 @@
+Date
+
+ Tue May 12 14:37:14 EDT 2009
+
+Version
+
+ CMS 8.0
+
+Overview
+
+ In CMS8.0, the database schema for the TPS has changed. The following
+ changes were made:
+ 1. The objectclass of the LDAP groups TUS Administrators, TUS Agents and TUS Officers has been
+ changed from groupOfUniqueNames to groupOfNames. This also means that the attribute "uniqueMember"
+ must change to "member".
+ 2. The dn of the TUS Administrators group was originally misspelled. This has been fixed.
+ 3. A tokenType field has been added to the tokenRecord and tokenActivity tables.
+ 4. Users that have administrator, admin or officer access to the TUS are stored under ou=People, $basedn.
+ These users now require an auxilliary class tpsProfileId to be added, with the attribute profileID.
+ This multi-valued attribute profileID contains profiles for which this user has access in the TPS UI
+ pages. See the admin guide for more details. Because the previous versions of the TPS allowed
+ access to all profiles, a value for "All Profiles" will be added for all users by the migrateTpsData
+ program. If this is not desired, change the access of specific users using the UI.
+
+Program
+
+ migrateTpsData(.x86_64 or .i386) will perform the above operations on an LDIF file and create a new
+ output LDIF file with the appropriate data to be imported into the new TPS instance. The input LDIF
+ file can be generated by running db2ldif on the old database for suffix containing the TPS data.
+
+ The program requires two arguments - the location of the LDIF file containing a dump of the old data,
+ and the location of the output file.
+
+ Any errors reported by the program should be investigated and fixed in the output LDIF file. Once
+ this file is corrected, it can be imported into the new TPS database.
+
+ Note: This program should be run to migrate data into a configured TPS system.
+
+Example
+
+ Here is an example of migrateTpsData usage
+ (for x86_64)
+ migrateTpsData.x86_64 old.ldif new.ldif
+
diff --git a/base/migrate/TpsTo80/solaris/migrateTPSData.sol9sparc b/base/migrate/TpsTo80/solaris/migrateTPSData.sol9sparc
new file mode 100755
index 000000000..082201859
--- /dev/null
+++ b/base/migrate/TpsTo80/solaris/migrateTPSData.sol9sparc
Binary files differ
diff --git a/base/migrate/TxtTo60/classes/CMS60LdifParser.class b/base/migrate/TxtTo60/classes/CMS60LdifParser.class
new file mode 100644
index 000000000..e65aea96f
--- /dev/null
+++ b/base/migrate/TxtTo60/classes/CMS60LdifParser.class
Binary files differ
diff --git a/base/migrate/TxtTo60/classes/DummyAuthManager.class b/base/migrate/TxtTo60/classes/DummyAuthManager.class
new file mode 100644
index 000000000..c713d8604
--- /dev/null
+++ b/base/migrate/TxtTo60/classes/DummyAuthManager.class
Binary files differ
diff --git a/base/migrate/TxtTo60/classes/Main.class b/base/migrate/TxtTo60/classes/Main.class
new file mode 100644
index 000000000..5fa0c203e
--- /dev/null
+++ b/base/migrate/TxtTo60/classes/Main.class
Binary files differ
diff --git a/base/migrate/TxtTo60/run.bat b/base/migrate/TxtTo60/run.bat
new file mode 100755
index 000000000..bd7d582ed
--- /dev/null
+++ b/base/migrate/TxtTo60/run.bat
@@ -0,0 +1,186 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM This program is free software; you can redistribute it and/or modify
+REM it under the terms of the GNU General Public License as published by
+REM the Free Software Foundation; version 2 of the License.
+REM
+REM This program is distributed in the hope that it will be useful,
+REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+REM GNU General Public License for more details.
+REM
+REM You should have received a copy of the GNU General Public License along
+REM with this program; if not, write to the Free Software Foundation, Inc.,
+REM 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script converts a normalized <Source CMS Version> ldif
+REM text file (e. g. - created via a <Source CMS Version>ToTxt
+REM script) into a CMS 6.0/6.01 ldif data file.
+REM
+REM This CMS 6.0/6.01 ldif data file can then be imported into the
+REM internal database of the desired CMS 6.0/6.01 server using a
+REM utility such as ldif2db.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM SERVER_ROOT - fully qualified path of the location of the server
+REM
+
+REM SET SERVER_ROOT=C:\cms601
+
+
+REM
+REM INSTANCE - if the CMS instance directory is called 'cert-ca',
+REM set the CMS instance to 'ca'
+REM
+REM NOTE: When a single SERVER_ROOT contains more than
+REM one CMS instance, this script must be run multiple
+REM times. To do this, there is only a need to change
+REM the INSTANCE parameter.
+REM
+
+REM SET INSTANCE=ca
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 6.0"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO USAGE
+IF "%3" == "" GOTO CHECK_INPUT_FILE
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0 input [errors] > output"
+ECHO.
+ECHO where: input - the specified %CMS% ldif data file,
+ECHO errors - an optional errors file containing
+ECHO skipped attributes, and
+ECHO output - the normalized %CMS% ldif text file.
+ECHO.
+ECHO NOTE: If no redirection is provided to
+ECHO 'output', then the normalized
+ECHO %CMS% ldif text will merely
+ECHO be echoed to stdout.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified "input" file exists
+REM
+
+:CHECK_INPUT_FILE
+IF EXIST %1 GOTO CHECK_ERRORS_FILE
+
+
+ECHO ERROR: The specified input file, %1, does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM If an "errors" file is specified, then check that it does not already
+REM exist.
+REM
+
+:CHECK_ERRORS_FILE
+IF "%2" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+IF EXIST %2 GOTO ERRORS_FILE_ERROR
+GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:ERRORS_FILE_ERROR
+ECHO ERROR: The specified errors file, %2, already exists!
+ECHO Please specify a different file!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%INSTANCE%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and INSTANCE
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_INSTANCE
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified INSTANCE exists
+REM
+
+:CHECK_INSTANCE
+IF EXIST %SERVER_ROOT%\cert-%INSTANCE% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified INSTANCE does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%SERVER_ROOT%\bin\cert\jre\bin;%SERVER_ROOT\bin\cert\jre\bin\hotspot;%PATH%
+
+
+REM
+REM Convert the specified %CMS% ldif data file
+REM into a normalized %CMS% ldif text file.
+REM
+
+%SERVER_ROOT%\bin\cert\jre\bin\java.exe -classpath .\classes;%SERVER_ROOT%\cert-%INSTANCE%\classes;%SERVER_ROOT%\bin\cert\classes;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar;%SERVER_ROOT%\bin\cert\jre\lib\rt.jar Main %1 %2
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/TxtTo60/run.sh b/base/migrate/TxtTo60/run.sh
new file mode 100755
index 000000000..80856e207
--- /dev/null
+++ b/base/migrate/TxtTo60/run.sh
@@ -0,0 +1,193 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+
+#####################################################################
+### ###
+### This script converts a normalized <Source CMS Version> ldif ###
+### text file (e. g. - created via a <Source CMS Version>ToTxt ###
+### script) into a CMS 6.0/6.01 ldif data file. ###
+### ###
+### This CMS 6.0/6.01 ldif data file can then be imported into ###
+### the internal database of the desired CMS 6.0/6.01 server ###
+### using a utility such as ldif2db. ###
+### ###
+#####################################################################
+
+
+###
+### SERVER_ROOT - fully qualified path of the location of the server
+###
+
+#SERVER_ROOT=/export/home/migrate/cms601
+#export SERVER_ROOT
+
+
+###
+### INSTANCE - if the CMS instance directory is called 'cert-ca',
+### set the CMS instance to 'ca'
+###
+### NOTE: When a single SERVER_ROOT contains more than
+### one CMS instance, this script must be run multiple
+### times. To do this, there is only a need to change
+### the INSTANCE parameter.
+###
+
+#INSTANCE=ca
+#export INSTANCE
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 6.0"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+##
+## Perform a usage check for the appropriate number of arguments:
+##
+
+if [ $# -lt 1 -o $# -gt 2 ] ; then
+ echo
+ echo "Usage: $0 input [errors] > output"
+ echo
+ echo " where: input - the specified ${CMS} ldif data file,"
+ echo " errors - an optional errors file containing"
+ echo " skipped attributes, and"
+ echo " output - the normalized ${CMS} ldif text file."
+ echo
+ echo " NOTE: If no redirection is provided to"
+ echo " 'output', then the normalized"
+ echo " ${CMS} ldif text will merely"
+ echo " be echoed to stdout."
+ echo
+ exit 1
+fi
+
+
+###
+### Check that the specified "input" file exists and is a regular file.
+###
+
+if [ ! -f $1 ] ; then
+ echo "ERROR: Either the specified 'input' file, '$1', does not exist, "
+ echo " or it is not a regular file!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified "input" file exists and is not empty.
+###
+
+if [ ! -s $1 ] ; then
+ echo "ERROR: The specified 'input' file, '$1', is empty!"
+ echo
+ exit 3
+fi
+
+
+###
+### If an "errors" file is specified, then check that it does not already
+### exist.
+###
+
+if [ $# -eq 2 ] ; then
+ if [ -f $2 ] ; then
+ echo "ERROR: The specified 'errors' file, '$2', already exists!"
+ echo " Please specify a different file!"
+ echo
+ exit 4
+ fi
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${INSTANCE}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and INSTANCE "
+ echo " environment variables for this script!"
+ echo
+ exit 5
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 6
+fi
+
+
+###
+### Check that the specified INSTANCE exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}/cert-${INSTANCE}" ] ; then
+ echo "ERROR: Either the specified INSTANCE does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 7
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Convert the specified ${CMS} ldif data file
+### into a normalized ${CMS} ldif text file.
+###
+
+${SERVER_ROOT}/bin/cert/jre/bin/java -classpath ./classes:${SERVER_ROOT}/cert-${INSTANCE}/classes:${SERVER_ROOT}/bin/cert/classes:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar:${SERVER_ROOT}/bin/cert/jre/lib/rt.jar:${SERVER_ROOT}/bin/cert/jre/lib/i18n.jar Main $1 $2
+
diff --git a/base/migrate/TxtTo60/src/Main.java b/base/migrate/TxtTo60/src/Main.java
new file mode 100644
index 000000000..3c47d8ad7
--- /dev/null
+++ b/base/migrate/TxtTo60/src/Main.java
@@ -0,0 +1,630 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+//
+// "TxtTo60/src/Main.java" represents the initial CMS "TxtTo" migration file.
+//
+// Always comment any new code sections with a "CMS 6.0" header, and
+// apply these changes forward to all other "TxtTo*/src/Main.java" files
+// (including this comment header) so that these differences will only
+// appear when this file is diffed against an earlier "TxtTo*" version.
+//
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import sun.misc.*;
+import org.mozilla.jss.*; // CMS 4.5 and later
+import org.mozilla.jss.crypto.*; // CMS 4.5 and later
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import netscape.security.util.*;
+import java.lang.reflect.*;
+
+public class Main
+{
+ public static void main(String args[])
+ {
+ try {
+ // initialize CryptoManager in CMS 4.5 and later
+ CryptoManager.initialize(".");
+ // load JSS provider in CMS 4.5 and later
+ java.security.Security.removeProvider("SUN version 1.2");
+ // The following call to "java.security.Security.insertProviderAt()"
+ // is no longer commented out in CMS 4.5 and later
+ java.security.Security.insertProviderAt(
+ new netscape.security.provider.CMS(), 0);
+ java.security.Provider ps[] =
+ java.security.Security.getProviders();
+ if (ps == null || ps.length <= 0) {
+ System.err.println("Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ System.err.println("Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+
+ // Parse the File
+ CMS60LdifParser parser = null;
+ if (args.length == 1) {
+ parser = new CMS60LdifParser(args[0]);
+ } else if (args.length == 2) {
+ parser = new CMS60LdifParser(args[0], args[1]);
+ } else {
+ throw new IOException("Invalid Parameters");
+ }
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+}
+
+class CMS60LdifParser
+{
+ // constants
+ private static final String DN =
+ "dn:";
+ // Directory Servers in CMS 4.7 and later use "requestAttributes"
+ private static final String REQUEST_ATTRIBUTES =
+ "requestAttributes::";
+ private static final String BEGIN =
+ "--- BEGIN ATTRIBUTES ---";
+ private static final String END =
+ "--- END ATTRIBUTES ---";
+
+ // variables
+ private String mFilename = null;
+ private String mErrorFilename = null;
+ private PrintWriter mErrorPrintWriter = null;
+
+ public CMS60LdifParser(String filename)
+ {
+ mFilename = filename;
+ }
+
+ public CMS60LdifParser(String filename, String errorFilename)
+ {
+ mFilename = filename;
+ mErrorFilename = errorFilename;
+ }
+
+ public void parse() throws Exception
+ {
+ if (mErrorFilename != null) {
+ mErrorPrintWriter = new PrintWriter(new FileOutputStream(mErrorFilename));
+ }
+ BufferedReader reader = new BufferedReader(
+ new FileReader(mFilename));
+ String line = null;
+ String dn = null;
+ Vector requestAttributes = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DN)) {
+ dn = line;
+ }
+ if (line.equals(BEGIN)) {
+ requestAttributes = new Vector();
+ continue;
+ }
+ if (requestAttributes == null) {
+ System.out.println(line);
+ continue;
+ }
+ if (line.equals(END)) {
+ parseAttributes(dn, requestAttributes);
+ requestAttributes = null;
+ continue;
+ }
+ if (line.startsWith(" ")) { // begining of attr
+ requestAttributes.addElement(
+ line.substring(1, line.length()));
+ } else {
+ requestAttributes.setElementAt(
+ (String)
+ requestAttributes.lastElement() +
+ "\n" +
+ line,
+ requestAttributes.size() - 1);
+ }
+ }
+ }
+
+ private byte[] encode(Object value) throws Exception
+ {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(bos);
+
+ os.writeObject(value);
+ os.close();
+ return bos.toByteArray();
+ }
+
+ public void parseAttributes(String dn, Vector attrs) throws Exception
+ {
+ Hashtable hashtable = new Hashtable();
+ for (int i = 0; i < attrs.size(); i++) {
+ String attr = (String)attrs.elementAt(i);
+ buildHashtable(dn, hashtable, attr);
+ }
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(bos);
+ Enumeration e = hashtable.keys();
+ while (e.hasMoreElements()) {
+ String key = (String)e.nextElement();
+ Object value = hashtable.get(key);
+
+ try {
+ byte data[] = null;
+ data = encode(value);
+ os.writeObject(key);
+ os.writeObject(data);
+ } catch (Exception ex) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + key);
+ }
+ }
+ } // while
+ os.writeObject(null);
+ os.close();
+
+ // print the BASE64 encoding of the Hashtable
+ BASE64Encoder encoder = new BASE64Encoder();
+ String attrsStr = encoder.encodeBuffer(bos.toByteArray());
+ // trim the last "\n"
+ StringBuffer buffer = null;
+ attrsStr = attrsStr.trim();
+ StringTokenizer st = new StringTokenizer(attrsStr, "\r\n");
+ while (st.hasMoreTokens()) {
+ if (buffer == null) {
+ buffer = new StringBuffer();
+ buffer.append(st.nextToken());
+ } else {
+ buffer.append("\r\n " + st.nextToken());
+ }
+ }
+
+ System.out.println(REQUEST_ATTRIBUTES + " " + buffer);
+ }
+
+ public void buildHashtable(String dn, Hashtable table, String attr)
+ throws Exception
+ {
+ // attribute format [name]:[type]=[value]
+
+ int colon = attr.indexOf(':');
+ if (colon == -1) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+ int equal = attr.indexOf('=');
+ if (equal == -1) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+ String name = null;
+ String type = null;
+ String value = null;
+ try {
+ name = attr.substring(0, colon);
+ type = attr.substring(colon+1, equal);
+ value = attr.substring(equal+1);
+ } catch (Exception e) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+
+ if (name.startsWith("serviceErrors")) {
+ // #56953 - skip serviceErrors
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+ if (name.startsWith("Error")) {
+ // #56953 - skip serviceErrors
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+
+ // To account for '47ToTxt' data files that have previously
+ // been generated, ALWAYS convert 'iplanet' to 'netscape'.
+ //
+ // Bugzilla Bug #224801 (a.k.a - Raidzilla Bug #56981)
+ // Bugzilla Bug #483519
+ //
+ String translation = null;
+ if( type.startsWith( "iplanet" ) ) {
+ translation = "netscape"
+ + type.substring( 7 );
+ type = translation;
+ } else if( type.startsWith( "com.iplanet" ) ) {
+ translation = "com.netscape"
+ + type.substring( 11 );
+ type = translation;
+ }
+
+ if (type.startsWith("com.netscape.certsrv.request.AgentApprovals")) {
+ com.netscape.certsrv.request.AgentApprovals obj =
+ (com.netscape.certsrv.request.AgentApprovals)table.get(name);
+ if (obj == null) {
+ obj = new com.netscape.certsrv.request.AgentApprovals();
+ table.put(name, obj);
+ }
+ obj.addApproval(value.substring(0,value.indexOf(';')));
+ } else if (type.startsWith("com.netscape.certsrv.base.ArgBlock")) {
+ com.netscape.certsrv.base.ArgBlock obj =
+ (com.netscape.certsrv.base.ArgBlock)table.get(name);
+ if (obj == null) {
+ obj = new com.netscape.certsrv.base.ArgBlock();
+ table.put(name, obj);
+ }
+ String valuekey = value.substring(0, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ obj.set(valuekey, valuevalue);
+ } else if (type.startsWith("com.netscape.certsrv.authentication.AuthToken")) {
+ com.netscape.certsrv.authentication.AuthToken obj =
+ (com.netscape.certsrv.authentication.AuthToken)table.get(name);
+ if (obj == null) {
+ com.netscape.certsrv.authentication.IAuthManager mgr =
+ new DummyAuthManager();
+ obj = new com.netscape.certsrv.authentication.AuthToken(mgr);
+ table.put(name, obj);
+ }
+ String valuekey = value.substring(0, value.indexOf(':'));
+ String valuetype = value.substring(value.indexOf(':')+1, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ if (valuetype.equals("java.lang.String")) {
+ // Processes 'java.math.BigInteger[]':
+ //
+ // Bugzilla Bug #225031 (a.k.a - Raidzilla Bug #58356)
+ //
+ // Processes 'java.lang.String[]':
+ //
+ // Bugzilla Bug #224763 (a.k.a - Raidzilla Bug #57949)
+ // Bugzilla Bug #252240
+ //
+ obj.set(valuekey, valuevalue);
+ } else if (valuetype.equals("java.util.Date")) {
+ obj.set(valuekey, new Date(Long.parseLong(valuevalue)));
+ } else {
+ System.err.println("ERROR AuthToken type - " + attr);
+ System.exit(0);
+ }
+ } else if (type.startsWith("java.math.BigInteger[")) {
+ // Bugzilla Bug #238779
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ java.math.BigInteger objs[] = (java.math.BigInteger[])table.get(name);
+ if (objs == null) {
+ objs = new java.math.BigInteger[size];
+ table.put(name, objs);
+ }
+ objs[index] = new java.math.BigInteger(value);
+ } else if (type.startsWith("java.math.BigInteger")) {
+ table.put(name, new java.math.BigInteger(value));
+ } else if (type.startsWith("byte[]")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ table.put(name, decoder.decodeBuffer(value));
+ } else if (type.startsWith("byte[")) {
+ // byte array
+ BASE64Decoder decoder = new BASE64Decoder();
+ table.put(name, decoder.decodeBuffer(value));
+ } else if (type.startsWith("netscape.security.x509.CertificateAlgorithmId")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateAlgorithmId obj =
+ new netscape.security.x509.CertificateAlgorithmId(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateChain")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateChain obj =
+ new netscape.security.x509.CertificateChain();
+ ByteArrayInputStream bis = new ByteArrayInputStream(decoder.decodeBuffer(value));
+ obj.decode(bis);
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateExtensions")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateExtensions obj =
+ new netscape.security.x509.CertificateExtensions(
+ new DerInputStream(decoder.decodeBuffer(value)));
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateSubjectName")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateSubjectName obj =
+ new netscape.security.x509.CertificateSubjectName(
+ new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ table.put(name, obj);
+ } else if (type.startsWith("netscape.security.x509.CertificateValidity")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateValidity obj =
+ new netscape.security.x509.CertificateValidity();
+ ByteArrayInputStream bis = new ByteArrayInputStream(decoder.decodeBuffer(value));
+ obj.decode(bis);
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateX509Key")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateX509Key obj =
+ new netscape.security.x509.CertificateX509Key(
+ new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ table.put(name, obj);
+ } else if (type.startsWith("com.netscape.certsrv.cert.CertInfo")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.extensions.CertInfo objs[] = (netscape.security.extensions.CertInfo[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.extensions.CertInfo[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.extensions.CertInfo();
+ objs[index].decode(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ } else if (type.startsWith("java.util.Hashtable")) {
+ // Bugzilla Bug #224800 (a.k.a - Raidzilla Bug #56953)
+ java.util.Hashtable obj = (java.util.Hashtable)table.get(name);
+ if (obj == null) {
+ obj = new java.util.Hashtable();
+ table.put(name, obj);
+ }
+ BASE64Decoder decoder = new BASE64Decoder();
+ String valuekey = value.substring(0, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ obj.put(valuekey, decoder.decodeBuffer(valuevalue));
+ } else if (type.startsWith("Integer[")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ Integer objs[] = (Integer[])table.get(name);
+ if (objs == null) {
+ objs = new Integer[size];
+ table.put(name, objs);
+ }
+ objs[index] = new Integer(value);
+ } else if (type.startsWith("java.lang.Integer")) {
+ table.put(name, new Integer(value));
+ } else if (type.startsWith("com.netscape.certsrv.dbs.keydb.KeyRecord")
+ || type.startsWith("com.netscape.cmscore.dbs.KeyRecord")) {
+ com.netscape.cmscore.dbs.KeyRecord obj =
+ (com.netscape.cmscore.dbs.KeyRecord)table.get(name);
+ if (obj == null) {
+ obj = new com.netscape.cmscore.dbs.KeyRecord();
+ table.put(name, obj);
+ }
+ String valuekey = value.substring(0, value.indexOf(':'));
+ String valuetype = value.substring(value.indexOf(':')+1, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ if (valuetype.equals("java.lang.String")) {
+ obj.set(valuekey, valuevalue);
+ } else if (valuetype.equals("java.util.Date")) {
+ obj.set(valuekey, new Date(Long.parseLong(valuevalue)));
+ } else if (valuetype.equals("java.math.BigInteger")) {
+ obj.set(valuekey, new java.math.BigInteger(valuevalue));
+ } else if (valuetype.equals("java.lang.Integer")) {
+ obj.set(valuekey, new Integer(valuevalue));
+ } else if (valuetype.equals("com.netscape.certsrv.dbs.keydb.KeyState")) {
+ obj.set(valuekey, com.netscape.certsrv.dbs.keydb.KeyState.toKeyState(valuevalue));
+ } else if (valuetype.equals("[B")) {
+ // byte array
+
+ BASE64Decoder decoder = new BASE64Decoder();
+ obj.set(valuekey, decoder.decodeBuffer(valuevalue));
+ } else {
+ System.err.println("ERROR KeyRecord type - " + attr);
+ System.exit(0);
+ }
+ } else if (type.startsWith("com.netscape.certsrv.kra.ProofOfArchival")
+ || type.startsWith("com.netscape.cmscore.kra.ProofOfArchival")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(decoder.decodeBuffer(value));
+ com.netscape.cmscore.kra.ProofOfArchival obj =
+ buildPOA(decoder.decodeBuffer(value));
+ table.put(name, obj);
+ } else if (type.startsWith("netscape.security.x509.RevokedCertImpl")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.x509.RevokedCertImpl objs[] = (netscape.security.x509.RevokedCertImpl[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.x509.RevokedCertImpl[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.x509.RevokedCertImpl(decoder.decodeBuffer(value));
+ } else if (type.startsWith("java.lang.String[")) {
+ // Bugzilla Bug #223360 (a.k.a - Raidzilla Bug #58086)
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ java.lang.String objs[] = (java.lang.String[])table.get(name);
+ if (objs == null) {
+ objs = new java.lang.String[size];
+ table.put(name, objs);
+ }
+ objs[index] = new java.lang.String(value);
+ } else if (type.startsWith("java.lang.String")) {
+ table.put(name, value);
+ } else if (type.startsWith("java.util.Vector")) {
+ Vector obj =
+ (Vector)table.get(name);
+ if (obj == null) {
+ obj = new Vector();
+ table.put(name, obj);
+ }
+ obj.addElement(value);
+ } else if (type.startsWith("netscape.security.x509.X509CertImpl[")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.x509.X509CertImpl objs[] = (netscape.security.x509.X509CertImpl[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.x509.X509CertImpl[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.x509.X509CertImpl(decoder.decodeBuffer(value));
+ } else if (type.equals("netscape.security.x509.X509CertImpl")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.X509CertImpl obj =
+ new netscape.security.x509.X509CertImpl(
+ decoder.decodeBuffer(value));
+ table.put(name, obj);
+ } else if (type.startsWith("netscape.security.x509.X509CertInfo")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.x509.X509CertInfo objs[] = (netscape.security.x509.X509CertInfo[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.x509.X509CertInfo[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.x509.X509CertInfo();
+ objs[index].decode(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ } else if (type.equals("netscape.security.x509.X509CertInfo")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.X509CertInfo obj =
+ new netscape.security.x509.X509CertInfo(
+ decoder.decodeBuffer(value));
+ table.put(name, obj);
+ } else if( type.endsWith( "Exception" ) ) {
+ Class[] argClass = { String.class }; // the argument's class
+ Object[] argValue = { value }; // the argument's value
+
+ Class x = Class.forName( type );
+ Constructor ctr = x.getConstructor( argClass );
+ Exception e = ( Exception ) ctr.newInstance( argValue );
+ } else {
+ System.err.println("ERROR type - " + type + " - "+ attr);
+ System.exit(0);
+ }
+ }
+
+ public com.netscape.cmscore.kra.ProofOfArchival buildPOA(byte data[])
+ throws Exception
+ {
+ DerInputStream dis = new DerInputStream(data);
+ DerValue seq[] = dis.getSequence(0);
+
+ BigInteger mSerialNo = seq[0].getInteger().toBigInteger();
+
+ // subject
+ DerValue subject = seq[1];
+ netscape.security.x509.X500Name mSubject =
+ new netscape.security.x509.X500Name(subject.toByteArray());
+
+ // issuer
+ DerValue issuer = seq[2];
+ netscape.security.x509.X500Name mIssuer =
+ new netscape.security.x509.X500Name(issuer.toByteArray());
+
+ // date of archival
+ DerInputStream dateOfArchival = new DerInputStream(seq[3].toByteArray());
+ Date mDateOfArchival = dateOfArchival.getUTCTime();
+ com.netscape.cmscore.kra.ProofOfArchival obj =
+ new com.netscape.cmscore.kra.ProofOfArchival(mSerialNo,
+ mSubject.toString(), mIssuer.toString(), mDateOfArchival);
+ return obj;
+ }
+}
+
+class DummyAuthManager implements com.netscape.certsrv.authentication.IAuthManager
+{
+ public String getName()
+ {
+ return "dummy";
+ }
+
+ public String getImplName()
+ {
+ return "dummy";
+ }
+
+ public IAuthToken authenticate(IAuthCredentials authCred)
+ throws EMissingCredential, EInvalidCredentials, EBaseException
+ {
+ return null;
+ }
+
+ /**
+ * 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
+ {
+ }
+
+ public void shutdown()
+ {
+ }
+
+ public String[] getRequiredCreds()
+ {
+ return null;
+ }
+
+ /**
+ * 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.
+ *
+ * @param implName The authentication manager plugin name.
+ * @exception EBaseException If an internal error occurred
+ */
+ public String[] getConfigParams()
+ throws EBaseException
+ {
+ return null;
+ }
+
+ /**
+ * Get the configuration store for this authentication manager.
+ * @return The configuration store of this authentication manager.
+ */
+ public IConfigStore getConfigStore()
+ {
+ return null;
+ }
+}
+
diff --git a/base/migrate/TxtTo60/src/compile.bat b/base/migrate/TxtTo60/src/compile.bat
new file mode 100755
index 000000000..bc21bb20e
--- /dev/null
+++ b/base/migrate/TxtTo60/src/compile.bat
@@ -0,0 +1,154 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script creates the "TxtTo60/classes/Main.class",
+REM "TxtTo60/classes/CMS60LdifParser.class", and
+REM "TxtTo60/classes/DummyAuthManager.class" which are
+REM used to create a CMS 6.0/6.01 ldif data file.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM Set SERVER_ROOT - identify the CMS <server_root> used to compile TxtTo60
+REM
+
+REM SET SERVER_ROOT=C:\cms601
+
+
+REM
+REM Set JDK_VERSION - specify the JDK version used by this version of CMS
+REM
+REM CMS 6.0 NOTE: "WINNT" - 1.3.1_02
+REM
+REM CMS 6.01 NOTE: "WINNT" - 1.3.1_02
+REM
+
+REM SET JDK_VERSION=CMS_6.01
+
+
+REM
+REM Set JAVA_HOME - specify the complete path to the JDK
+REM
+REM example: \\bermuda.redhat.com\sbc mounted as Y:
+REM
+
+REM SET JAVA_HOME=Y:\cms_jdk\WINNT\%JDK_VERSION%
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 6.0"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0"
+ECHO.
+ECHO NOTE: No arguments are required to build the
+ECHO %CMS% ldif data classes.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%JAVA_HOME%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and JAVA_HOME
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_JAVA_HOME
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified JAVA_HOME exists
+REM
+
+:CHECK_JAVA_HOME
+IF EXIST %JAVA_HOME% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified JAVA_HOME does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%JAVA_HOME%\bin;%JAVA_HOME%\lib;%PATH%
+
+
+REM
+REM Set TARGET - identify the complete path to the new classes target directory
+REM
+
+SET TARGET=..\classes
+
+
+REM
+REM Create the new classes target directory (if it does not already exist)
+REM
+
+IF EXIST %TARGET% goto COMPILE_CLASSES
+MKDIR %TARGET%
+
+
+REM
+REM Compile TxtTo60 - create "CMS60LdifParser.class", "DummyAuthManager.class",
+REM and "Main.class"
+REM
+
+:COMPILE_CLASSES
+%JAVA_HOME%\bin\javac.exe -d %TARGET% -classpath %JAVA_HOME%\jre\lib\rt.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar Main.java
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/TxtTo60/src/compile.sh b/base/migrate/TxtTo60/src/compile.sh
new file mode 100755
index 000000000..a15b6a670
--- /dev/null
+++ b/base/migrate/TxtTo60/src/compile.sh
@@ -0,0 +1,166 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#####################################################################
+### ###
+### This script creates the "TxtTo60/classes/Main.class", ###
+### "TxtTo60/classes/CMS60LdifParser.class", and ###
+### "TxtTo60/classes/DummyAuthManager.class" which are ###
+### used to create a CMS 6.0/6.01 ldif data file. ###
+### ###
+#####################################################################
+
+
+###
+### Set SERVER_ROOT - identify the CMS <server_root> used to compile TxtTo60
+###
+
+#SERVER_ROOT=/export/home/migrate/cms601
+#export SERVER_ROOT
+
+
+###
+### Set JDK_PLATFORM - must be "HP-UX", "Linux", or "SunOS"
+###
+
+#JDK_PLATFORM=SunOS
+#export JDK_PLATFORM
+
+
+###
+### Set JDK_VERSION - specify the JDK version used by this version of CMS
+###
+### CMS 6.0 NOTE: "HP-UX" - 1.3.1.02
+### "Linux" - 1.3.1_02
+### "SunOS" - 1.3.1_02
+###
+### CMS 6.01 NOTE: "HP-UX" - 1.3.1.02
+### "Linux" - 1.4.0
+### "SunOS" - 1.3.1_02
+###
+
+#JDK_VERSION=CMS_6.01
+#export JDK_VERSION
+
+
+###
+### Set JAVA_HOME - specify the complete path to the JDK
+###
+
+#JAVA_HOME=/share/builds/components/cms_jdk/${JDK_PLATFORM}/${JDK_VERSION}
+#export JAVA_HOME
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 6.0"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -gt 0 ] ; then
+ echo
+ echo "Usage: $0"
+ echo
+ echo " NOTE: No arguments are required to build the"
+ echo " ${CMS} ldif data classes."
+ echo
+ exit 1
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${JAVA_HOME}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and JAVA_HOME "
+ echo " environment variables for this script!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 3
+fi
+
+
+###
+### Check that the specified JAVA_HOME exists and is a directory
+###
+
+if [ ! -d "${JAVA_HOME}" ] ; then
+ echo "ERROR: Either the specified JAVA_HOME does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 4
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Set TARGET - identify the complete path to the new classes target directory
+###
+
+TARGET=../classes
+export TARGET
+
+
+###
+### Create the new classes target directory (if it does not already exist)
+###
+
+if [ ! -d ${TARGET} ]; then
+ mkdir -p ${TARGET}
+fi
+
+
+###
+### Compile TxtTo60 - create "CMS60LdifParser.class", "DummyAuthManager.class",
+### and "Main.class"
+###
+
+${JAVA_HOME}/bin/javac -d ${TARGET} -classpath ${JAVA_HOME}/jre/lib/rt.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar Main.java
+
diff --git a/base/migrate/TxtTo61/classes/CMS61LdifParser.class b/base/migrate/TxtTo61/classes/CMS61LdifParser.class
new file mode 100644
index 000000000..03f2d90af
--- /dev/null
+++ b/base/migrate/TxtTo61/classes/CMS61LdifParser.class
Binary files differ
diff --git a/base/migrate/TxtTo61/classes/DummyAuthManager.class b/base/migrate/TxtTo61/classes/DummyAuthManager.class
new file mode 100644
index 000000000..8b2039e74
--- /dev/null
+++ b/base/migrate/TxtTo61/classes/DummyAuthManager.class
Binary files differ
diff --git a/base/migrate/TxtTo61/classes/Main.class b/base/migrate/TxtTo61/classes/Main.class
new file mode 100644
index 000000000..2f0c1663e
--- /dev/null
+++ b/base/migrate/TxtTo61/classes/Main.class
Binary files differ
diff --git a/base/migrate/TxtTo61/run.bat b/base/migrate/TxtTo61/run.bat
new file mode 100755
index 000000000..a63296608
--- /dev/null
+++ b/base/migrate/TxtTo61/run.bat
@@ -0,0 +1,186 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM This program is free software; you can redistribute it and/or modify
+REM it under the terms of the GNU General Public License as published by
+REM the Free Software Foundation; version 2 of the License.
+REM
+REM This program is distributed in the hope that it will be useful,
+REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+REM GNU General Public License for more details.
+REM
+REM You should have received a copy of the GNU General Public License along
+REM with this program; if not, write to the Free Software Foundation, Inc.,
+REM 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script converts a normalized <Source CMS Version> ldif
+REM text file (e. g. - created via a <Source CMS Version>ToTxt
+REM script) into a CMS 6.1 ldif data file.
+REM
+REM This CMS 6.1 ldif data file can then be imported into the
+REM internal database of the desired CMS 6.1 server using a
+REM utility such as ldif2db.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM SERVER_ROOT - fully qualified path of the location of the server
+REM
+
+REM SET SERVER_ROOT=C:\cms61
+
+
+REM
+REM INSTANCE - if the CMS instance directory is called 'cert-ca',
+REM set the CMS instance to 'ca'
+REM
+REM NOTE: When a single SERVER_ROOT contains more than
+REM one CMS instance, this script must be run multiple
+REM times. To do this, there is only a need to change
+REM the INSTANCE parameter.
+REM
+
+REM SET INSTANCE=ca
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 6.1"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO USAGE
+IF "%3" == "" GOTO CHECK_INPUT_FILE
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0 input [errors] > output"
+ECHO.
+ECHO where: input - the specified %CMS% ldif data file,
+ECHO errors - an optional errors file containing
+ECHO skipped attributes, and
+ECHO output - the normalized %CMS% ldif text file.
+ECHO.
+ECHO NOTE: If no redirection is provided to
+ECHO 'output', then the normalized
+ECHO %CMS% ldif text will merely
+ECHO be echoed to stdout.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified "input" file exists
+REM
+
+:CHECK_INPUT_FILE
+IF EXIST %1 GOTO CHECK_ERRORS_FILE
+
+
+ECHO ERROR: The specified input file, %1, does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM If an "errors" file is specified, then check that it does not already
+REM exist.
+REM
+
+:CHECK_ERRORS_FILE
+IF "%2" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+IF EXIST %2 GOTO ERRORS_FILE_ERROR
+GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:ERRORS_FILE_ERROR
+ECHO ERROR: The specified errors file, %2, already exists!
+ECHO Please specify a different file!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%INSTANCE%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and INSTANCE
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_INSTANCE
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified INSTANCE exists
+REM
+
+:CHECK_INSTANCE
+IF EXIST %SERVER_ROOT%\cert-%INSTANCE% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified INSTANCE does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%SERVER_ROOT%\bin\cert\jre\bin;%SERVER_ROOT\bin\cert\jre\bin\server;%PATH%
+
+
+REM
+REM Convert the specified %CMS% ldif data file
+REM into a normalized %CMS% ldif text file.
+REM
+
+%SERVER_ROOT%\bin\cert\jre\bin\java.exe -classpath .\classes;%SERVER_ROOT%\cert-%INSTANCE%\classes;%SERVER_ROOT%\bin\cert\classes;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar;%SERVER_ROOT%\bin\cert\jre\lib\rt.jar Main %1 %2
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/TxtTo61/run.sh b/base/migrate/TxtTo61/run.sh
new file mode 100755
index 000000000..6ef1cae42
--- /dev/null
+++ b/base/migrate/TxtTo61/run.sh
@@ -0,0 +1,196 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+
+#####################################################################
+### ###
+### This script converts a normalized <Source CMS Version> ldif ###
+### text file (e. g. - created via a <Source CMS Version>ToTxt ###
+### script) into a CMS 6.1 ldif data file. ###
+### ###
+### This CMS 6.1 ldif data file can then be imported into the ###
+### internal database of the desired CMS 6.1 server using a ###
+### utility such as ldif2db. ###
+### ###
+#####################################################################
+
+
+###
+### SERVER_ROOT - fully qualified path of the location of the server
+###
+
+#SERVER_ROOT=/export/home/migrate/cms61
+#export SERVER_ROOT
+
+
+###
+### INSTANCE - if the CMS instance directory is called 'cert-ca',
+### set the CMS instance to 'ca'
+###
+### NOTE: When a single SERVER_ROOT contains more than
+### one CMS instance, this script must be run multiple
+### times. To do this, there is only a need to change
+### the INSTANCE parameter.
+###
+
+#INSTANCE=ca
+#export INSTANCE
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 6.1"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+##
+## Perform a usage check for the appropriate number of arguments:
+##
+
+if [ $# -lt 1 -o $# -gt 2 ] ; then
+ echo
+ echo "Usage: $0 input [errors] > output"
+ echo
+ echo " where: input - the specified ${CMS} ldif data file,"
+ echo " errors - an optional errors file containing"
+ echo " skipped attributes, and"
+ echo " output - the normalized ${CMS} ldif text file."
+ echo
+ echo " NOTE: If no redirection is provided to"
+ echo " 'output', then the normalized"
+ echo " ${CMS} ldif text will merely"
+ echo " be echoed to stdout."
+ echo
+ exit 1
+fi
+
+
+###
+### Check that the specified "input" file exists and is a regular file.
+###
+
+if [ ! -f $1 ] ; then
+ echo "ERROR: Either the specified 'input' file, '$1', does not exist, "
+ echo " or it is not a regular file!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified "input" file exists and is not empty.
+###
+
+if [ ! -s $1 ] ; then
+ echo "ERROR: The specified 'input' file, '$1', is empty!"
+ echo
+ exit 3
+fi
+
+
+###
+### If an "errors" file is specified, then check that it does not already
+### exist.
+###
+
+if [ $# -eq 2 ] ; then
+ if [ -f $2 ] ; then
+ echo "ERROR: The specified 'errors' file, '$2', already exists!"
+ echo " Please specify a different file!"
+ echo
+ exit 4
+ fi
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${INSTANCE}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and INSTANCE "
+ echo " environment variables for this script!"
+ echo
+ exit 5
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 6
+fi
+
+
+###
+### Check that the specified INSTANCE exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}/cert-${INSTANCE}" ] ; then
+ echo "ERROR: Either the specified INSTANCE does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 7
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Convert the specified ${CMS} ldif data file
+### into a normalized ${CMS} ldif text file.
+###
+### NOTE: As of SunOS JDK 1.4.0, the required "Unicode" classes
+### have been moved from "i18n.jar" to "rt.jar".
+###
+
+${SERVER_ROOT}/bin/cert/jre/bin/java -classpath ./classes:${SERVER_ROOT}/cert-${INSTANCE}/classes:${SERVER_ROOT}/bin/cert/classes:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar:${SERVER_ROOT}/bin/cert/jre/lib/rt.jar Main $1 $2
+
diff --git a/base/migrate/TxtTo61/src/Main.java b/base/migrate/TxtTo61/src/Main.java
new file mode 100644
index 000000000..8b95ccc97
--- /dev/null
+++ b/base/migrate/TxtTo61/src/Main.java
@@ -0,0 +1,644 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+//
+// "TxtTo61/src/Main.java" is based upon a copy "TxtTo60/src/Main.java".
+//
+// Always comment any new code sections with a "CMS 6.1" header, and
+// apply these changes forward to all other "TxtTo*/src/Main.java" files
+// (including this comment header) so that these differences will only
+// appear when this file is diffed against an earlier "TxtTo*" version.
+//
+// This file should always be maintained by executing the following command:
+//
+// diff TxtTo60/src/Main.java TxtTo61/src/Main.java
+//
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import sun.misc.*;
+import org.mozilla.jss.*; // CMS 4.5 and later
+import org.mozilla.jss.crypto.*; // CMS 4.5 and later
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import netscape.security.util.*;
+import java.lang.reflect.*;
+
+public class Main
+{
+ public static void main(String args[])
+ {
+ try {
+ // initialize CryptoManager in CMS 4.5 and later
+ CryptoManager.initialize(".");
+ // load JSS provider in CMS 4.5 and later
+ java.security.Security.removeProvider("SUN version 1.2");
+ // The following call to "java.security.Security.insertProviderAt()"
+ // is no longer commented out in CMS 4.5 and later
+ java.security.Security.insertProviderAt(
+ new netscape.security.provider.CMS(), 0);
+ java.security.Provider ps[] =
+ java.security.Security.getProviders();
+ if (ps == null || ps.length <= 0) {
+ System.err.println("Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ System.err.println("Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+
+ // Parse the File
+ CMS61LdifParser parser = null;
+ if (args.length == 1) {
+ parser = new CMS61LdifParser(args[0]);
+ } else if (args.length == 2) {
+ parser = new CMS61LdifParser(args[0], args[1]);
+ } else {
+ throw new IOException("Invalid Parameters");
+ }
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+}
+
+class CMS61LdifParser
+{
+ // constants
+ private static final String DN =
+ "dn:";
+ // Directory Servers in CMS 4.7 and later use "requestAttributes"
+ private static final String REQUEST_ATTRIBUTES =
+ "requestAttributes::";
+ private static final String BEGIN =
+ "--- BEGIN ATTRIBUTES ---";
+ private static final String END =
+ "--- END ATTRIBUTES ---";
+
+ // variables
+ private String mFilename = null;
+ private String mErrorFilename = null;
+ private PrintWriter mErrorPrintWriter = null;
+
+ public CMS61LdifParser(String filename)
+ {
+ mFilename = filename;
+ }
+
+ public CMS61LdifParser(String filename, String errorFilename)
+ {
+ mFilename = filename;
+ mErrorFilename = errorFilename;
+ }
+
+ public void parse() throws Exception
+ {
+ if (mErrorFilename != null) {
+ mErrorPrintWriter = new PrintWriter(new FileOutputStream(mErrorFilename));
+ }
+ BufferedReader reader = new BufferedReader(
+ new FileReader(mFilename));
+ String line = null;
+ String dn = null;
+ Vector requestAttributes = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DN)) {
+ dn = line;
+ }
+ if (line.equals(BEGIN)) {
+ requestAttributes = new Vector();
+ continue;
+ }
+ if (requestAttributes == null) {
+ System.out.println(line);
+ continue;
+ }
+ if (line.equals(END)) {
+ parseAttributes(dn, requestAttributes);
+ requestAttributes = null;
+ continue;
+ }
+ if (line.startsWith(" ")) { // begining of attr
+ requestAttributes.addElement(
+ line.substring(1, line.length()));
+ } else {
+ requestAttributes.setElementAt(
+ (String)
+ requestAttributes.lastElement() +
+ "\n" +
+ line,
+ requestAttributes.size() - 1);
+ }
+ }
+ }
+
+ private byte[] encode(Object value) throws Exception
+ {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(bos);
+
+ os.writeObject(value);
+ os.close();
+ return bos.toByteArray();
+ }
+
+ public void parseAttributes(String dn, Vector attrs) throws Exception
+ {
+ Hashtable hashtable = new Hashtable();
+ for (int i = 0; i < attrs.size(); i++) {
+ String attr = (String)attrs.elementAt(i);
+ buildHashtable(dn, hashtable, attr);
+ }
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(bos);
+ Enumeration e = hashtable.keys();
+ while (e.hasMoreElements()) {
+ String key = (String)e.nextElement();
+ Object value = hashtable.get(key);
+
+ try {
+ byte data[] = null;
+ data = encode(value);
+ os.writeObject(key);
+ os.writeObject(data);
+ } catch (Exception ex) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + key);
+ }
+ }
+ } // while
+ os.writeObject(null);
+ os.close();
+
+ // print the BASE64 encoding of the Hashtable
+ BASE64Encoder encoder = new BASE64Encoder();
+ String attrsStr = encoder.encodeBuffer(bos.toByteArray());
+ // trim the last "\n"
+ StringBuffer buffer = null;
+ attrsStr = attrsStr.trim();
+ StringTokenizer st = new StringTokenizer(attrsStr, "\r\n");
+ while (st.hasMoreTokens()) {
+ if (buffer == null) {
+ buffer = new StringBuffer();
+ buffer.append(st.nextToken());
+ } else {
+ buffer.append("\r\n " + st.nextToken());
+ }
+ }
+
+ System.out.println(REQUEST_ATTRIBUTES + " " + buffer);
+ }
+
+ public void buildHashtable(String dn, Hashtable table, String attr)
+ throws Exception
+ {
+ // attribute format [name]:[type]=[value]
+
+ int colon = attr.indexOf(':');
+ if (colon == -1) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+ int equal = attr.indexOf('=');
+ if (equal == -1) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+ String name = null;
+ String type = null;
+ String value = null;
+ try {
+ name = attr.substring(0, colon);
+ type = attr.substring(colon+1, equal);
+ value = attr.substring(equal+1);
+ } catch (Exception e) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+
+ if (name.startsWith("serviceErrors")) {
+ // #56953 - skip serviceErrors
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+ if (name.startsWith("Error")) {
+ // #56953 - skip serviceErrors
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+
+ // To account for '47ToTxt' data files that have previously
+ // been generated, ALWAYS convert 'iplanet' to 'netscape'.
+ //
+ // Bugzilla Bug #224801 (a.k.a - Raidzilla Bug #56981)
+ // Bugzilla Bug #483519
+ //
+ String translation = null;
+ if( type.startsWith( "iplanet" ) ) {
+ translation = "netscape"
+ + type.substring( 7 );
+ type = translation;
+ } else if( type.startsWith( "com.iplanet" ) ) {
+ translation = "com.netscape"
+ + type.substring( 11 );
+ type = translation;
+ }
+
+ if (type.startsWith("com.netscape.certsrv.request.AgentApprovals")) {
+ com.netscape.certsrv.request.AgentApprovals obj =
+ (com.netscape.certsrv.request.AgentApprovals)table.get(name);
+ if (obj == null) {
+ obj = new com.netscape.certsrv.request.AgentApprovals();
+ table.put(name, obj);
+ }
+ obj.addApproval(value.substring(0,value.indexOf(';')));
+ } else if (type.startsWith("com.netscape.certsrv.base.ArgBlock")
+ || type.startsWith("com.netscape.cmscore.base.ArgBlock")) {
+ // CMS 6.1: created new "com.netscape.certsrv.base.IArgBlock" and
+ // moved old "com.netscape.certsrv.base.ArgBlock"
+ // to "com.netscape.cmscore.base.ArgBlock"
+ com.netscape.cmscore.base.ArgBlock obj =
+ (com.netscape.cmscore.base.ArgBlock)table.get(name);
+ if (obj == null) {
+ // CMS 6.1: created new "com.netscape.certsrv.base.IArgBlock" and
+ // moved old "com.netscape.certsrv.base.ArgBlock"
+ // to "com.netscape.cmscore.base.ArgBlock"
+ obj = new com.netscape.cmscore.base.ArgBlock();
+ table.put(name, obj);
+ }
+ String valuekey = value.substring(0, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ obj.set(valuekey, valuevalue);
+ } else if (type.startsWith("com.netscape.certsrv.authentication.AuthToken")) {
+ com.netscape.certsrv.authentication.AuthToken obj =
+ (com.netscape.certsrv.authentication.AuthToken)table.get(name);
+ if (obj == null) {
+ com.netscape.certsrv.authentication.IAuthManager mgr =
+ new DummyAuthManager();
+ obj = new com.netscape.certsrv.authentication.AuthToken(mgr);
+ table.put(name, obj);
+ }
+ String valuekey = value.substring(0, value.indexOf(':'));
+ String valuetype = value.substring(value.indexOf(':')+1, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ if (valuetype.equals("java.lang.String")) {
+ // Processes 'java.math.BigInteger[]':
+ //
+ // Bugzilla Bug #225031 (a.k.a - Raidzilla Bug #58356)
+ //
+ // Processes 'java.lang.String[]':
+ //
+ // Bugzilla Bug #224763 (a.k.a - Raidzilla Bug #57949)
+ // Bugzilla Bug #252240
+ //
+ obj.set(valuekey, valuevalue);
+ } else if (valuetype.equals("java.util.Date")) {
+ obj.set(valuekey, new Date(Long.parseLong(valuevalue)));
+ } else {
+ System.err.println("ERROR AuthToken type - " + attr);
+ System.exit(0);
+ }
+ } else if (type.startsWith("java.math.BigInteger[")) {
+ // Bugzilla Bug #238779
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ java.math.BigInteger objs[] = (java.math.BigInteger[])table.get(name);
+ if (objs == null) {
+ objs = new java.math.BigInteger[size];
+ table.put(name, objs);
+ }
+ objs[index] = new java.math.BigInteger(value);
+ } else if (type.startsWith("java.math.BigInteger")) {
+ table.put(name, new java.math.BigInteger(value));
+ } else if (type.startsWith("byte[]")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ table.put(name, decoder.decodeBuffer(value));
+ } else if (type.startsWith("byte[")) {
+ // byte array
+ BASE64Decoder decoder = new BASE64Decoder();
+ table.put(name, decoder.decodeBuffer(value));
+ } else if (type.startsWith("netscape.security.x509.CertificateAlgorithmId")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateAlgorithmId obj =
+ new netscape.security.x509.CertificateAlgorithmId(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateChain")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateChain obj =
+ new netscape.security.x509.CertificateChain();
+ ByteArrayInputStream bis = new ByteArrayInputStream(decoder.decodeBuffer(value));
+ obj.decode(bis);
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateExtensions")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateExtensions obj =
+ new netscape.security.x509.CertificateExtensions(
+ new DerInputStream(decoder.decodeBuffer(value)));
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateSubjectName")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateSubjectName obj =
+ new netscape.security.x509.CertificateSubjectName(
+ new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ table.put(name, obj);
+ } else if (type.startsWith("netscape.security.x509.CertificateValidity")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateValidity obj =
+ new netscape.security.x509.CertificateValidity();
+ ByteArrayInputStream bis = new ByteArrayInputStream(decoder.decodeBuffer(value));
+ obj.decode(bis);
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateX509Key")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateX509Key obj =
+ new netscape.security.x509.CertificateX509Key(
+ new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ table.put(name, obj);
+ } else if (type.startsWith("com.netscape.certsrv.cert.CertInfo")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.extensions.CertInfo objs[] = (netscape.security.extensions.CertInfo[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.extensions.CertInfo[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.extensions.CertInfo();
+ objs[index].decode(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ } else if (type.startsWith("java.util.Hashtable")) {
+ // Bugzilla Bug #224800 (a.k.a - Raidzilla Bug #56953)
+ java.util.Hashtable obj = (java.util.Hashtable)table.get(name);
+ if (obj == null) {
+ obj = new java.util.Hashtable();
+ table.put(name, obj);
+ }
+ BASE64Decoder decoder = new BASE64Decoder();
+ String valuekey = value.substring(0, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ obj.put(valuekey, decoder.decodeBuffer(valuevalue));
+ } else if (type.startsWith("Integer[")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ Integer objs[] = (Integer[])table.get(name);
+ if (objs == null) {
+ objs = new Integer[size];
+ table.put(name, objs);
+ }
+ objs[index] = new Integer(value);
+ } else if (type.startsWith("java.lang.Integer")) {
+ table.put(name, new Integer(value));
+ } else if (type.startsWith("com.netscape.certsrv.dbs.keydb.KeyRecord")
+ || type.startsWith("com.netscape.cmscore.dbs.KeyRecord")) {
+ com.netscape.cmscore.dbs.KeyRecord obj =
+ (com.netscape.cmscore.dbs.KeyRecord)table.get(name);
+ if (obj == null) {
+ obj = new com.netscape.cmscore.dbs.KeyRecord();
+ table.put(name, obj);
+ }
+ String valuekey = value.substring(0, value.indexOf(':'));
+ String valuetype = value.substring(value.indexOf(':')+1, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ if (valuetype.equals("java.lang.String")) {
+ obj.set(valuekey, valuevalue);
+ } else if (valuetype.equals("java.util.Date")) {
+ obj.set(valuekey, new Date(Long.parseLong(valuevalue)));
+ } else if (valuetype.equals("java.math.BigInteger")) {
+ obj.set(valuekey, new java.math.BigInteger(valuevalue));
+ } else if (valuetype.equals("java.lang.Integer")) {
+ obj.set(valuekey, new Integer(valuevalue));
+ } else if (valuetype.equals("com.netscape.certsrv.dbs.keydb.KeyState")) {
+ obj.set(valuekey, com.netscape.certsrv.dbs.keydb.KeyState.toKeyState(valuevalue));
+ } else if (valuetype.equals("[B")) {
+ // byte array
+
+ BASE64Decoder decoder = new BASE64Decoder();
+ obj.set(valuekey, decoder.decodeBuffer(valuevalue));
+ } else {
+ System.err.println("ERROR KeyRecord type - " + attr);
+ System.exit(0);
+ }
+ } else if (type.startsWith("com.netscape.certsrv.kra.ProofOfArchival")
+ || type.startsWith("com.netscape.cmscore.kra.ProofOfArchival")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(decoder.decodeBuffer(value));
+ com.netscape.cmscore.kra.ProofOfArchival obj =
+ buildPOA(decoder.decodeBuffer(value));
+ table.put(name, obj);
+ } else if (type.startsWith("netscape.security.x509.RevokedCertImpl")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.x509.RevokedCertImpl objs[] = (netscape.security.x509.RevokedCertImpl[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.x509.RevokedCertImpl[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.x509.RevokedCertImpl(decoder.decodeBuffer(value));
+ } else if (type.startsWith("java.lang.String[")) {
+ // Bugzilla Bug #223360 (a.k.a - Raidzilla Bug #58086)
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ java.lang.String objs[] = (java.lang.String[])table.get(name);
+ if (objs == null) {
+ objs = new java.lang.String[size];
+ table.put(name, objs);
+ }
+ objs[index] = new java.lang.String(value);
+ } else if (type.startsWith("java.lang.String")) {
+ table.put(name, value);
+ } else if (type.startsWith("java.util.Vector")) {
+ Vector obj =
+ (Vector)table.get(name);
+ if (obj == null) {
+ obj = new Vector();
+ table.put(name, obj);
+ }
+ obj.addElement(value);
+ } else if (type.startsWith("netscape.security.x509.X509CertImpl[")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.x509.X509CertImpl objs[] = (netscape.security.x509.X509CertImpl[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.x509.X509CertImpl[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.x509.X509CertImpl(decoder.decodeBuffer(value));
+ } else if (type.equals("netscape.security.x509.X509CertImpl")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.X509CertImpl obj =
+ new netscape.security.x509.X509CertImpl(
+ decoder.decodeBuffer(value));
+ table.put(name, obj);
+ } else if (type.startsWith("netscape.security.x509.X509CertInfo[")) {
+ // CMS 6.1: "netscape.security.x509.X509CertInfo"
+ // now always utilizes arrays such as
+ // "netscape.security.x509.X509CertInfo["
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.x509.X509CertInfo objs[] = (netscape.security.x509.X509CertInfo[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.x509.X509CertInfo[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.x509.X509CertInfo();
+ objs[index].decode(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ } else if (type.equals("netscape.security.x509.X509CertInfo")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.X509CertInfo obj =
+ new netscape.security.x509.X509CertInfo(
+ decoder.decodeBuffer(value));
+ table.put(name, obj);
+ } else if( type.endsWith( "Exception" ) ) {
+ Class[] argClass = { String.class }; // the argument's class
+ Object[] argValue = { value }; // the argument's value
+
+ Class x = Class.forName( type );
+ Constructor ctr = x.getConstructor( argClass );
+ Exception e = ( Exception ) ctr.newInstance( argValue );
+ } else {
+ System.err.println("ERROR type - " + type + " - "+ attr);
+ System.exit(0);
+ }
+ }
+
+ public com.netscape.cmscore.kra.ProofOfArchival buildPOA(byte data[])
+ throws Exception
+ {
+ DerInputStream dis = new DerInputStream(data);
+ DerValue seq[] = dis.getSequence(0);
+
+ BigInteger mSerialNo = seq[0].getInteger().toBigInteger();
+
+ // subject
+ DerValue subject = seq[1];
+ netscape.security.x509.X500Name mSubject =
+ new netscape.security.x509.X500Name(subject.toByteArray());
+
+ // issuer
+ DerValue issuer = seq[2];
+ netscape.security.x509.X500Name mIssuer =
+ new netscape.security.x509.X500Name(issuer.toByteArray());
+
+ // date of archival
+ DerInputStream dateOfArchival = new DerInputStream(seq[3].toByteArray());
+ Date mDateOfArchival = dateOfArchival.getUTCTime();
+ com.netscape.cmscore.kra.ProofOfArchival obj =
+ new com.netscape.cmscore.kra.ProofOfArchival(mSerialNo,
+ mSubject.toString(), mIssuer.toString(), mDateOfArchival);
+ return obj;
+ }
+}
+
+class DummyAuthManager implements com.netscape.certsrv.authentication.IAuthManager
+{
+ public String getName()
+ {
+ return "dummy";
+ }
+
+ public String getImplName()
+ {
+ return "dummy";
+ }
+
+ public IAuthToken authenticate(IAuthCredentials authCred)
+ throws EMissingCredential, EInvalidCredentials, EBaseException
+ {
+ return null;
+ }
+
+ /**
+ * 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
+ {
+ }
+
+ public void shutdown()
+ {
+ }
+
+ public String[] getRequiredCreds()
+ {
+ return null;
+ }
+
+ /**
+ * 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.
+ *
+ * @param implName The authentication manager plugin name.
+ * @exception EBaseException If an internal error occurred
+ */
+ public String[] getConfigParams()
+ throws EBaseException
+ {
+ return null;
+ }
+
+ /**
+ * Get the configuration store for this authentication manager.
+ * @return The configuration store of this authentication manager.
+ */
+ public IConfigStore getConfigStore()
+ {
+ return null;
+ }
+}
+
diff --git a/base/migrate/TxtTo61/src/compile.bat b/base/migrate/TxtTo61/src/compile.bat
new file mode 100755
index 000000000..8b2a3bff9
--- /dev/null
+++ b/base/migrate/TxtTo61/src/compile.bat
@@ -0,0 +1,152 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script creates the "TxtTo61/classes/Main.class",
+REM "TxtTo61/classes/CMS61LdifParser.class", and
+REM "TxtTo61/classes/DummyAuthManager.class" which are
+REM used to create a CMS 6.1 ldif data file.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM Set SERVER_ROOT - identify the CMS <server_root> used to compile TxtTo61
+REM
+
+REM SET SERVER_ROOT=C:\cms61
+
+
+REM
+REM Set JDK_VERSION - specify the JDK version used by this version of CMS
+REM
+REM CMS 6.1 NOTE: "WINNT" - 1.4.0
+REM
+
+REM SET JDK_VERSION=CMS_6.1
+
+
+REM
+REM Set JAVA_HOME - specify the complete path to the JDK
+REM
+REM example: \\bermuda.redhat.com\sbc mounted as Y:
+REM
+
+REM SET JAVA_HOME=Y:\cms_jdk\WINNT\%JDK_VERSION%
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 6.1"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0"
+ECHO.
+ECHO NOTE: No arguments are required to build the
+ECHO %CMS% ldif data classes.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%JAVA_HOME%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and JAVA_HOME
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_JAVA_HOME
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified JAVA_HOME exists
+REM
+
+:CHECK_JAVA_HOME
+IF EXIST %JAVA_HOME% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified JAVA_HOME does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%JAVA_HOME%\bin;%JAVA_HOME%\lib;%PATH%
+
+
+REM
+REM Set TARGET - identify the complete path to the new classes target directory
+REM
+
+SET TARGET=..\classes
+
+
+REM
+REM Create the new classes target directory (if it does not already exist)
+REM
+
+IF EXIST %TARGET% goto COMPILE_CLASSES
+MKDIR %TARGET%
+
+
+REM
+REM Compile TxtTo61 - create "CMS61LdifParser.class", "DummyAuthManager.class",
+REM and "Main.class"
+REM
+
+:COMPILE_CLASSES
+%JAVA_HOME%\bin\javac.exe -d %TARGET% -classpath %JAVA_HOME%\jre\lib\rt.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar Main.java
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/TxtTo61/src/compile.sh b/base/migrate/TxtTo61/src/compile.sh
new file mode 100755
index 000000000..3ec4885c9
--- /dev/null
+++ b/base/migrate/TxtTo61/src/compile.sh
@@ -0,0 +1,162 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#####################################################################
+### ###
+### This script creates the "TxtTo61/classes/Main.class", ###
+### "TxtTo61/classes/CMS61LdifParser.class", and ###
+### "TxtTo61/classes/DummyAuthManager.class" which are ###
+### used to create a CMS 6.1 ldif data file. ###
+### ###
+#####################################################################
+
+
+###
+### Set SERVER_ROOT - identify the CMS <server_root> used to compile TxtTo61
+###
+
+#SERVER_ROOT=/export/home/migrate/cms61
+#export SERVER_ROOT
+
+
+###
+### Set JDK_PLATFORM - must be "HP-UX", "Linux", or "SunOS"
+###
+
+#JDK_PLATFORM=SunOS
+#export JDK_PLATFORM
+
+
+###
+### Set JDK_VERSION - specify the JDK version used by this version of CMS
+###
+### CMS 6.1 NOTE: "HP-UX" - 1.3.1.02
+### "Linux" - 1.3.1_02
+### "SunOS" - 1.3.1_02
+###
+
+#JDK_VERSION=CMS_6.1
+#export JDK_VERSION
+
+
+###
+### Set JAVA_HOME - specify the complete path to the JDK
+###
+
+#JAVA_HOME=/share/builds/components/cms_jdk/${JDK_PLATFORM}/${JDK_VERSION}
+#export JAVA_HOME
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 6.1"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -gt 0 ] ; then
+ echo
+ echo "Usage: $0"
+ echo
+ echo " NOTE: No arguments are required to build the"
+ echo " ${CMS} ldif data classes."
+ echo
+ exit 1
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${JAVA_HOME}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and JAVA_HOME "
+ echo " environment variables for this script!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 3
+fi
+
+
+###
+### Check that the specified JAVA_HOME exists and is a directory
+###
+
+if [ ! -d "${JAVA_HOME}" ] ; then
+ echo "ERROR: Either the specified JAVA_HOME does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 4
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Set TARGET - identify the complete path to the new classes target directory
+###
+
+TARGET=../classes
+export TARGET
+
+
+###
+### Create the new classes target directory (if it does not already exist)
+###
+
+if [ ! -d ${TARGET} ]; then
+ mkdir -p ${TARGET}
+fi
+
+
+###
+### Compile TxtTo61 - create "CMS61LdifParser.class", "DummyAuthManager.class",
+### and "Main.class"
+###
+
+${JAVA_HOME}/bin/javac -d ${TARGET} -classpath ${JAVA_HOME}/jre/lib/rt.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar Main.java
+
diff --git a/base/migrate/TxtTo62/classes/CMS62LdifParser.class b/base/migrate/TxtTo62/classes/CMS62LdifParser.class
new file mode 100644
index 000000000..ca25274a8
--- /dev/null
+++ b/base/migrate/TxtTo62/classes/CMS62LdifParser.class
Binary files differ
diff --git a/base/migrate/TxtTo62/classes/DummyAuthManager.class b/base/migrate/TxtTo62/classes/DummyAuthManager.class
new file mode 100644
index 000000000..387cde908
--- /dev/null
+++ b/base/migrate/TxtTo62/classes/DummyAuthManager.class
Binary files differ
diff --git a/base/migrate/TxtTo62/classes/Main.class b/base/migrate/TxtTo62/classes/Main.class
new file mode 100644
index 000000000..e2e92309e
--- /dev/null
+++ b/base/migrate/TxtTo62/classes/Main.class
Binary files differ
diff --git a/base/migrate/TxtTo62/run.bat b/base/migrate/TxtTo62/run.bat
new file mode 100755
index 000000000..1e342ed24
--- /dev/null
+++ b/base/migrate/TxtTo62/run.bat
@@ -0,0 +1,186 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM This program is free software; you can redistribute it and/or modify
+REM it under the terms of the GNU General Public License as published by
+REM the Free Software Foundation; version 2 of the License.
+REM
+REM This program is distributed in the hope that it will be useful,
+REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+REM GNU General Public License for more details.
+REM
+REM You should have received a copy of the GNU General Public License along
+REM with this program; if not, write to the Free Software Foundation, Inc.,
+REM 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script converts a normalized <Source CMS Version> ldif
+REM text file (e. g. - created via a <Source CMS Version>ToTxt
+REM script) into a CMS 6.2 ldif data file.
+REM
+REM This CMS 6.2 ldif data file can then be imported into the
+REM internal database of the desired CMS 6.2 server using a
+REM utility such as ldif2db.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM SERVER_ROOT - fully qualified path of the location of the server
+REM
+
+REM SET SERVER_ROOT=C:\cms62
+
+
+REM
+REM INSTANCE - if the CMS instance directory is called 'cert-ca',
+REM set the CMS instance to 'ca'
+REM
+REM NOTE: When a single SERVER_ROOT contains more than
+REM one CMS instance, this script must be run multiple
+REM times. To do this, there is only a need to change
+REM the INSTANCE parameter.
+REM
+
+REM SET INSTANCE=ca
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 6.2"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO USAGE
+IF "%3" == "" GOTO CHECK_INPUT_FILE
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0 input [errors] > output"
+ECHO.
+ECHO where: input - the specified %CMS% ldif data file,
+ECHO errors - an optional errors file containing
+ECHO skipped attributes, and
+ECHO output - the normalized %CMS% ldif text file.
+ECHO.
+ECHO NOTE: If no redirection is provided to
+ECHO 'output', then the normalized
+ECHO %CMS% ldif text will merely
+ECHO be echoed to stdout.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified "input" file exists
+REM
+
+:CHECK_INPUT_FILE
+IF EXIST %1 GOTO CHECK_ERRORS_FILE
+
+
+ECHO ERROR: The specified input file, %1, does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM If an "errors" file is specified, then check that it does not already
+REM exist.
+REM
+
+:CHECK_ERRORS_FILE
+IF "%2" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+IF EXIST %2 GOTO ERRORS_FILE_ERROR
+GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:ERRORS_FILE_ERROR
+ECHO ERROR: The specified errors file, %2, already exists!
+ECHO Please specify a different file!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%INSTANCE%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and INSTANCE
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_INSTANCE
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified INSTANCE exists
+REM
+
+:CHECK_INSTANCE
+IF EXIST %SERVER_ROOT%\cert-%INSTANCE% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified INSTANCE does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%SERVER_ROOT%\bin\cert\jre\bin;%SERVER_ROOT\bin\cert\jre\bin\server;%PATH%
+
+
+REM
+REM Convert the specified %CMS% ldif data file
+REM into a normalized %CMS% ldif text file.
+REM
+
+%SERVER_ROOT%\bin\cert\jre\bin\java.exe -classpath .\classes;%SERVER_ROOT%\cert-%INSTANCE%\classes;%SERVER_ROOT%\bin\cert\classes;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar;%SERVER_ROOT%\bin\cert\jre\lib\rt.jar Main %1 %2
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/TxtTo62/run.sh b/base/migrate/TxtTo62/run.sh
new file mode 100755
index 000000000..fdd6b2ee9
--- /dev/null
+++ b/base/migrate/TxtTo62/run.sh
@@ -0,0 +1,196 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+
+#####################################################################
+### ###
+### This script converts a normalized <Source CMS Version> ldif ###
+### text file (e. g. - created via a <Source CMS Version>ToTxt ###
+### script) into a CMS 6.2 ldif data file. ###
+### ###
+### This CMS 6.2 ldif data file can then be imported into the ###
+### internal database of the desired CMS 6.2 server using a ###
+### utility such as ldif2db. ###
+### ###
+#####################################################################
+
+
+###
+### SERVER_ROOT - fully qualified path of the location of the server
+###
+
+#SERVER_ROOT=/export/home/migrate/cms62
+#export SERVER_ROOT
+
+
+###
+### INSTANCE - if the CMS instance directory is called 'cert-ca',
+### set the CMS instance to 'ca'
+###
+### NOTE: When a single SERVER_ROOT contains more than
+### one CMS instance, this script must be run multiple
+### times. To do this, there is only a need to change
+### the INSTANCE parameter.
+###
+
+#INSTANCE=ca
+#export INSTANCE
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 6.2"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+##
+## Perform a usage check for the appropriate number of arguments:
+##
+
+if [ $# -lt 1 -o $# -gt 2 ] ; then
+ echo
+ echo "Usage: $0 input [errors] > output"
+ echo
+ echo " where: input - the specified ${CMS} ldif data file,"
+ echo " errors - an optional errors file containing"
+ echo " skipped attributes, and"
+ echo " output - the normalized ${CMS} ldif text file."
+ echo
+ echo " NOTE: If no redirection is provided to"
+ echo " 'output', then the normalized"
+ echo " ${CMS} ldif text will merely"
+ echo " be echoed to stdout."
+ echo
+ exit 1
+fi
+
+
+###
+### Check that the specified "input" file exists and is a regular file.
+###
+
+if [ ! -f $1 ] ; then
+ echo "ERROR: Either the specified 'input' file, '$1', does not exist, "
+ echo " or it is not a regular file!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified "input" file exists and is not empty.
+###
+
+if [ ! -s $1 ] ; then
+ echo "ERROR: The specified 'input' file, '$1', is empty!"
+ echo
+ exit 3
+fi
+
+
+###
+### If an "errors" file is specified, then check that it does not already
+### exist.
+###
+
+if [ $# -eq 2 ] ; then
+ if [ -f $2 ] ; then
+ echo "ERROR: The specified 'errors' file, '$2', already exists!"
+ echo " Please specify a different file!"
+ echo
+ exit 4
+ fi
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${INSTANCE}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and INSTANCE "
+ echo " environment variables for this script!"
+ echo
+ exit 5
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 6
+fi
+
+
+###
+### Check that the specified INSTANCE exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}/cert-${INSTANCE}" ] ; then
+ echo "ERROR: Either the specified INSTANCE does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 7
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Convert the specified ${CMS} ldif data file
+### into a normalized ${CMS} ldif text file.
+###
+### NOTE: As of SunOS JDK 1.4.0, the required "Unicode" classes
+### have been moved from "i18n.jar" to "rt.jar".
+###
+
+${SERVER_ROOT}/bin/cert/jre/bin/java -classpath ./classes:${SERVER_ROOT}/cert-${INSTANCE}/classes:${SERVER_ROOT}/bin/cert/classes:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar:${SERVER_ROOT}/bin/cert/jre/lib/rt.jar Main $1 $2
+
diff --git a/base/migrate/TxtTo62/src/Main.java b/base/migrate/TxtTo62/src/Main.java
new file mode 100644
index 000000000..da48981b7
--- /dev/null
+++ b/base/migrate/TxtTo62/src/Main.java
@@ -0,0 +1,655 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+//
+// "TxtTo62/src/Main.java" is based upon a copy "TxtTo61/src/Main.java".
+//
+// Always comment any new code sections with a "CMS 6.2" header, and
+// apply these changes forward to all other "TxtTo*/src/Main.java" files
+// (including this comment header) so that these differences will only
+// appear when this file is diffed against an earlier "TxtTo*" version.
+//
+// This file should always be maintained by executing the following command:
+//
+// diff TxtTo61/src/Main.java TxtTo62/src/Main.java
+//
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import sun.misc.*;
+import org.mozilla.jss.*; // CMS 4.5 and later
+import org.mozilla.jss.crypto.*; // CMS 4.5 and later
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import netscape.security.util.*;
+import java.lang.reflect.*;
+
+public class Main
+{
+ public static void main(String args[])
+ {
+ try {
+ // initialize CryptoManager in CMS 4.5 and later
+ CryptoManager.initialize(".");
+ // load JSS provider in CMS 4.5 and later
+ java.security.Security.removeProvider("SUN version 1.2");
+ // The following call to "java.security.Security.insertProviderAt()"
+ // is no longer commented out in CMS 4.5 and later
+ java.security.Security.insertProviderAt(
+ new netscape.security.provider.CMS(), 0);
+ java.security.Provider ps[] =
+ java.security.Security.getProviders();
+ if (ps == null || ps.length <= 0) {
+ System.err.println("Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ System.err.println("Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+
+ // Parse the File
+ CMS62LdifParser parser = null;
+ if (args.length == 1) {
+ parser = new CMS62LdifParser(args[0]);
+ } else if (args.length == 2) {
+ parser = new CMS62LdifParser(args[0], args[1]);
+ } else {
+ throw new IOException("Invalid Parameters");
+ }
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+}
+
+class CMS62LdifParser
+{
+ // constants
+ private static final String DN =
+ "dn:";
+ // Directory Servers in CMS 4.7 and later use "requestAttributes"
+ private static final String REQUEST_ATTRIBUTES =
+ "requestAttributes::";
+ private static final String BEGIN =
+ "--- BEGIN ATTRIBUTES ---";
+ private static final String END =
+ "--- END ATTRIBUTES ---";
+
+ // variables
+ private String mFilename = null;
+ private String mErrorFilename = null;
+ private PrintWriter mErrorPrintWriter = null;
+
+ public CMS62LdifParser(String filename)
+ {
+ mFilename = filename;
+ }
+
+ public CMS62LdifParser(String filename, String errorFilename)
+ {
+ mFilename = filename;
+ mErrorFilename = errorFilename;
+ }
+
+ public void parse() throws Exception
+ {
+ if (mErrorFilename != null) {
+ mErrorPrintWriter = new PrintWriter(new FileOutputStream(mErrorFilename));
+ }
+ BufferedReader reader = new BufferedReader(
+ new FileReader(mFilename));
+ String line = null;
+ String dn = null;
+ Vector requestAttributes = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DN)) {
+ dn = line;
+ }
+ if (line.equals(BEGIN)) {
+ requestAttributes = new Vector();
+ continue;
+ }
+ if (requestAttributes == null) {
+ System.out.println(line);
+ continue;
+ }
+ if (line.equals(END)) {
+ parseAttributes(dn, requestAttributes);
+ requestAttributes = null;
+ continue;
+ }
+ if (line.startsWith(" ")) { // begining of attr
+ requestAttributes.addElement(
+ line.substring(1, line.length()));
+ } else {
+ requestAttributes.setElementAt(
+ (String)
+ requestAttributes.lastElement() +
+ "\n" +
+ line,
+ requestAttributes.size() - 1);
+ }
+ }
+ }
+
+ private byte[] encode(Object value) throws Exception
+ {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(bos);
+
+ os.writeObject(value);
+ os.close();
+ return bos.toByteArray();
+ }
+
+ public void parseAttributes(String dn, Vector attrs) throws Exception
+ {
+ Hashtable hashtable = new Hashtable();
+ for (int i = 0; i < attrs.size(); i++) {
+ String attr = (String)attrs.elementAt(i);
+ buildHashtable(dn, hashtable, attr);
+ }
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(bos);
+ Enumeration e = hashtable.keys();
+ while (e.hasMoreElements()) {
+ String key = (String)e.nextElement();
+ Object value = hashtable.get(key);
+
+ try {
+ byte data[] = null;
+ data = encode(value);
+ os.writeObject(key);
+ os.writeObject(data);
+ } catch (Exception ex) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + key);
+ }
+ }
+ } // while
+ os.writeObject(null);
+ os.close();
+
+ // print the BASE64 encoding of the Hashtable
+ BASE64Encoder encoder = new BASE64Encoder();
+ String attrsStr = encoder.encodeBuffer(bos.toByteArray());
+ // trim the last "\n"
+ StringBuffer buffer = null;
+ attrsStr = attrsStr.trim();
+ StringTokenizer st = new StringTokenizer(attrsStr, "\r\n");
+ while (st.hasMoreTokens()) {
+ if (buffer == null) {
+ buffer = new StringBuffer();
+ buffer.append(st.nextToken());
+ } else {
+ buffer.append("\r\n " + st.nextToken());
+ }
+ }
+
+ System.out.println(REQUEST_ATTRIBUTES + " " + buffer);
+ }
+
+ public void buildHashtable(String dn, Hashtable table, String attr)
+ throws Exception
+ {
+ // attribute format [name]:[type]=[value]
+
+ int colon = attr.indexOf(':');
+ if (colon == -1) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+ int equal = attr.indexOf('=');
+ if (equal == -1) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+ String name = null;
+ String type = null;
+ String value = null;
+ try {
+ name = attr.substring(0, colon);
+ type = attr.substring(colon+1, equal);
+ value = attr.substring(equal+1);
+ } catch (Exception e) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+
+ if (name.startsWith("serviceErrors")) {
+ // #56953 - skip serviceErrors
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+ if (name.startsWith("Error")) {
+ // #56953 - skip serviceErrors
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+
+ // To account for '47ToTxt' data files that have previously
+ // been generated, ALWAYS convert 'iplanet' to 'netscape'.
+ //
+ // Bugzilla Bug #224801 (a.k.a - Raidzilla Bug #56981)
+ // Bugzilla Bug #483519
+ //
+ String translation = null;
+ if( type.startsWith( "iplanet" ) ) {
+ translation = "netscape"
+ + type.substring( 7 );
+ type = translation;
+ } else if( type.startsWith( "com.iplanet" ) ) {
+ translation = "com.netscape"
+ + type.substring( 11 );
+ type = translation;
+ }
+
+ if (type.startsWith("com.netscape.certsrv.request.AgentApprovals")) {
+ com.netscape.certsrv.request.AgentApprovals obj =
+ (com.netscape.certsrv.request.AgentApprovals)table.get(name);
+ if (obj == null) {
+ obj = new com.netscape.certsrv.request.AgentApprovals();
+ table.put(name, obj);
+ }
+ obj.addApproval(value.substring(0,value.indexOf(';')));
+ } else if (type.startsWith("com.netscape.certsrv.base.ArgBlock")
+ || type.startsWith("com.netscape.cmscore.base.ArgBlock")) {
+ // CMS 6.1: created new "com.netscape.certsrv.base.IArgBlock" and
+ // moved old "com.netscape.certsrv.base.ArgBlock"
+ // to "com.netscape.cmscore.base.ArgBlock"
+ com.netscape.cmscore.base.ArgBlock obj =
+ (com.netscape.cmscore.base.ArgBlock)table.get(name);
+ if (obj == null) {
+ // CMS 6.1: created new "com.netscape.certsrv.base.IArgBlock" and
+ // moved old "com.netscape.certsrv.base.ArgBlock"
+ // to "com.netscape.cmscore.base.ArgBlock"
+ obj = new com.netscape.cmscore.base.ArgBlock();
+ table.put(name, obj);
+ }
+ String valuekey = value.substring(0, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ obj.set(valuekey, valuevalue);
+ } else if (type.startsWith("com.netscape.certsrv.authentication.AuthToken")) {
+ com.netscape.certsrv.authentication.AuthToken obj =
+ (com.netscape.certsrv.authentication.AuthToken)table.get(name);
+ if (obj == null) {
+ com.netscape.certsrv.authentication.IAuthManager mgr =
+ new DummyAuthManager();
+ obj = new com.netscape.certsrv.authentication.AuthToken(mgr);
+ table.put(name, obj);
+ }
+ String valuekey = value.substring(0, value.indexOf(':'));
+ String valuetype = value.substring(value.indexOf(':')+1, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ if (valuetype.equals("java.lang.String")) {
+ // Processes 'java.math.BigInteger[]':
+ //
+ // Bugzilla Bug #225031 (a.k.a - Raidzilla Bug #58356)
+ //
+ // Processes 'java.lang.String[]':
+ //
+ // Bugzilla Bug #224763 (a.k.a - Raidzilla Bug #57949)
+ // Bugzilla Bug #252240
+ //
+ obj.set(valuekey, valuevalue);
+ } else if (valuetype.equals("java.util.Date")) {
+ obj.set(valuekey, new Date(Long.parseLong(valuevalue)));
+ } else {
+ System.err.println("ERROR AuthToken type - " + attr);
+ System.exit(0);
+ }
+ } else if (type.startsWith("java.math.BigInteger[")) {
+ // Bugzilla Bug #238779
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ java.math.BigInteger objs[] = (java.math.BigInteger[])table.get(name);
+ if (objs == null) {
+ objs = new java.math.BigInteger[size];
+ table.put(name, objs);
+ }
+ objs[index] = new java.math.BigInteger(value);
+ } else if (type.startsWith("java.math.BigInteger")) {
+ table.put(name, new java.math.BigInteger(value));
+ } else if (type.startsWith("byte[]")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ table.put(name, decoder.decodeBuffer(value));
+ } else if (type.startsWith("byte[")) {
+ // byte array
+ BASE64Decoder decoder = new BASE64Decoder();
+ table.put(name, decoder.decodeBuffer(value));
+ } else if (type.startsWith("netscape.security.x509.CertificateAlgorithmId")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateAlgorithmId obj =
+ new netscape.security.x509.CertificateAlgorithmId(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateChain")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateChain obj =
+ new netscape.security.x509.CertificateChain();
+ ByteArrayInputStream bis = new ByteArrayInputStream(decoder.decodeBuffer(value));
+ obj.decode(bis);
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateExtensions")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateExtensions obj =
+ new netscape.security.x509.CertificateExtensions();
+ obj.decodeEx(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ // CMS 6.2: revised method of decoding objects of type
+ // "netscape.security.x509.CertificateExtensions"
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateSubjectName")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateSubjectName obj =
+ new netscape.security.x509.CertificateSubjectName(new DerInputStream(decoder.decodeBuffer(value)));
+ // CMS 6.2: revised method of decoding objects of type
+ // "netscape.security.x509.CertificateSubjectName"
+ table.put(name, obj);
+ } else if (type.startsWith("netscape.security.x509.CertificateValidity")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateValidity obj =
+ new netscape.security.x509.CertificateValidity();
+ ByteArrayInputStream bis = new ByteArrayInputStream(decoder.decodeBuffer(value));
+ obj.decode(bis);
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateX509Key")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateX509Key obj =
+ new netscape.security.x509.CertificateX509Key(
+ new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ table.put(name, obj);
+ } else if (type.startsWith("com.netscape.certsrv.cert.CertInfo")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.extensions.CertInfo objs[] = (netscape.security.extensions.CertInfo[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.extensions.CertInfo[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.extensions.CertInfo();
+ objs[index].decode(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ } else if (type.startsWith("java.util.Hashtable")) {
+ // Bugzilla Bug #224800 (a.k.a - Raidzilla Bug #56953)
+ java.util.Hashtable obj = (java.util.Hashtable)table.get(name);
+ if (obj == null) {
+ obj = new java.util.Hashtable();
+ table.put(name, obj);
+ }
+ BASE64Decoder decoder = new BASE64Decoder();
+ String valuekey = value.substring(0, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ obj.put(valuekey, decoder.decodeBuffer(valuevalue));
+ } else if (type.startsWith("Integer[")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ Integer objs[] = (Integer[])table.get(name);
+ if (objs == null) {
+ objs = new Integer[size];
+ table.put(name, objs);
+ }
+ objs[index] = new Integer(value);
+ } else if (type.startsWith("java.lang.Integer")) {
+ table.put(name, new Integer(value));
+ } else if (type.startsWith("com.netscape.certsrv.dbs.keydb.KeyRecord")
+ || type.startsWith("com.netscape.cmscore.dbs.KeyRecord")) {
+ com.netscape.cmscore.dbs.KeyRecord obj =
+ (com.netscape.cmscore.dbs.KeyRecord)table.get(name);
+ if (obj == null) {
+ obj = new com.netscape.cmscore.dbs.KeyRecord();
+ table.put(name, obj);
+ }
+ String valuekey = value.substring(0, value.indexOf(':'));
+ String valuetype = value.substring(value.indexOf(':')+1, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ if (valuetype.equals("java.lang.String")) {
+ obj.set(valuekey, valuevalue);
+ } else if (valuetype.equals("java.util.Date")) {
+ obj.set(valuekey, new Date(Long.parseLong(valuevalue)));
+ } else if (valuetype.equals("java.math.BigInteger")) {
+ obj.set(valuekey, new java.math.BigInteger(valuevalue));
+ } else if (valuetype.equals("java.lang.Integer")) {
+ obj.set(valuekey, new Integer(valuevalue));
+ } else if (valuetype.equals("com.netscape.certsrv.dbs.keydb.KeyState")) {
+ obj.set(valuekey, com.netscape.certsrv.dbs.keydb.KeyState.toKeyState(valuevalue));
+ } else if (valuetype.equals("[B")) {
+ // byte array
+
+ BASE64Decoder decoder = new BASE64Decoder();
+ obj.set(valuekey, decoder.decodeBuffer(valuevalue));
+ } else {
+ System.err.println("ERROR KeyRecord type - " + attr);
+ System.exit(0);
+ }
+ } else if (type.startsWith("com.netscape.certsrv.kra.ProofOfArchival")
+ || type.startsWith("com.netscape.cmscore.kra.ProofOfArchival")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(decoder.decodeBuffer(value));
+ com.netscape.cmscore.kra.ProofOfArchival obj =
+ buildPOA(decoder.decodeBuffer(value));
+ table.put(name, obj);
+ } else if (type.startsWith("netscape.security.x509.RevokedCertImpl")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.x509.RevokedCertImpl objs[] = (netscape.security.x509.RevokedCertImpl[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.x509.RevokedCertImpl[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.x509.RevokedCertImpl(decoder.decodeBuffer(value));
+ } else if (type.startsWith("java.lang.String[")) {
+ // Bugzilla Bug #223360 (a.k.a - Raidzilla Bug #58086)
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ java.lang.String objs[] = (java.lang.String[])table.get(name);
+ if (objs == null) {
+ objs = new java.lang.String[size];
+ table.put(name, objs);
+ }
+ objs[index] = new java.lang.String(value);
+ } else if (type.startsWith("java.lang.String")) {
+ table.put(name, value);
+ } else if (type.startsWith("java.util.Locale")) {
+ // CMS 6.2: begin checking for new type
+ // "java.util.Locale"
+ table.put(name, Locale.getDefault());
+ } else if (type.startsWith("java.util.Vector")) {
+ Vector obj =
+ (Vector)table.get(name);
+ if (obj == null) {
+ obj = new Vector();
+ table.put(name, obj);
+ }
+ obj.addElement(value);
+ } else if (type.startsWith("netscape.security.x509.X509CertImpl[")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.x509.X509CertImpl objs[] = (netscape.security.x509.X509CertImpl[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.x509.X509CertImpl[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.x509.X509CertImpl(decoder.decodeBuffer(value));
+ } else if (type.equals("netscape.security.x509.X509CertImpl")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.X509CertImpl obj =
+ new netscape.security.x509.X509CertImpl(
+ decoder.decodeBuffer(value));
+ table.put(name, obj);
+ } else if (type.startsWith("netscape.security.x509.X509CertInfo[")
+ || type.startsWith("netscape.security.extensions.CertInfo[")) {
+ // CMS 6.2: begin checking for additional new type
+ // "netscape.security.extensions.CertInfo["
+ //
+ // CMS 6.1: "netscape.security.x509.X509CertInfo"
+ // now always utilizes arrays such as
+ // "netscape.security.x509.X509CertInfo["
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.x509.X509CertInfo objs[] = (netscape.security.x509.X509CertInfo[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.x509.X509CertInfo[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.x509.X509CertInfo();
+ objs[index].decode(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ } else if (type.equals("netscape.security.x509.X509CertInfo")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.X509CertInfo obj =
+ new netscape.security.x509.X509CertInfo(
+ decoder.decodeBuffer(value));
+ table.put(name, obj);
+ } else if( type.endsWith( "Exception" ) ) {
+ Class[] argClass = { String.class }; // the argument's class
+ Object[] argValue = { value }; // the argument's value
+
+ Class x = Class.forName( type );
+ Constructor ctr = x.getConstructor( argClass );
+ Exception e = ( Exception ) ctr.newInstance( argValue );
+ } else {
+ System.err.println("ERROR type - " + type + " - "+ attr);
+ System.exit(0);
+ }
+ }
+
+ public com.netscape.cmscore.kra.ProofOfArchival buildPOA(byte data[])
+ throws Exception
+ {
+ DerInputStream dis = new DerInputStream(data);
+ DerValue seq[] = dis.getSequence(0);
+
+ BigInteger mSerialNo = seq[0].getInteger().toBigInteger();
+
+ // subject
+ DerValue subject = seq[1];
+ netscape.security.x509.X500Name mSubject =
+ new netscape.security.x509.X500Name(subject.toByteArray());
+
+ // issuer
+ DerValue issuer = seq[2];
+ netscape.security.x509.X500Name mIssuer =
+ new netscape.security.x509.X500Name(issuer.toByteArray());
+
+ // date of archival
+ DerInputStream dateOfArchival = new DerInputStream(seq[3].toByteArray());
+ Date mDateOfArchival = dateOfArchival.getUTCTime();
+ com.netscape.cmscore.kra.ProofOfArchival obj =
+ new com.netscape.cmscore.kra.ProofOfArchival(mSerialNo,
+ mSubject.toString(), mIssuer.toString(), mDateOfArchival);
+ return obj;
+ }
+}
+
+class DummyAuthManager implements com.netscape.certsrv.authentication.IAuthManager
+{
+ public String getName()
+ {
+ return "dummy";
+ }
+
+ public String getImplName()
+ {
+ return "dummy";
+ }
+
+ public IAuthToken authenticate(IAuthCredentials authCred)
+ throws EMissingCredential, EInvalidCredentials, EBaseException
+ {
+ return null;
+ }
+
+ /**
+ * 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
+ {
+ }
+
+ public void shutdown()
+ {
+ }
+
+ public String[] getRequiredCreds()
+ {
+ return null;
+ }
+
+ /**
+ * 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.
+ *
+ * @param implName The authentication manager plugin name.
+ * @exception EBaseException If an internal error occurred
+ */
+ public String[] getConfigParams()
+ throws EBaseException
+ {
+ return null;
+ }
+
+ /**
+ * Get the configuration store for this authentication manager.
+ * @return The configuration store of this authentication manager.
+ */
+ public IConfigStore getConfigStore()
+ {
+ return null;
+ }
+}
+
diff --git a/base/migrate/TxtTo62/src/compile.bat b/base/migrate/TxtTo62/src/compile.bat
new file mode 100755
index 000000000..063b8969f
--- /dev/null
+++ b/base/migrate/TxtTo62/src/compile.bat
@@ -0,0 +1,152 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script creates the "TxtTo62/classes/Main.class",
+REM "TxtTo62/classes/CMS62LdifParser.class", and
+REM "TxtTo62/classes/DummyAuthManager.class" which are
+REM used to create a CMS 6.2 ldif data file.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM Set SERVER_ROOT - identify the CMS <server_root> used to compile TxtTo62
+REM
+
+REM SET SERVER_ROOT=C:\cms62
+
+
+REM
+REM Set JDK_VERSION - specify the JDK version used by this version of CMS
+REM
+REM CMS 6.2 NOTE: "WINNT" - 1.4.0
+REM
+
+REM SET JDK_VERSION=CMS_6.2
+
+
+REM
+REM Set JAVA_HOME - specify the complete path to the JDK
+REM
+REM example: \\bermuda.redhat.com\sbc mounted as Y:
+REM
+
+REM SET JAVA_HOME=Y:\cms_jdk\WINNT\%JDK_VERSION%
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 6.2"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0"
+ECHO.
+ECHO NOTE: No arguments are required to build the
+ECHO %CMS% ldif data classes.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%JAVA_HOME%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and JAVA_HOME
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_JAVA_HOME
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified JAVA_HOME exists
+REM
+
+:CHECK_JAVA_HOME
+IF EXIST %JAVA_HOME% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified JAVA_HOME does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%JAVA_HOME%\bin;%JAVA_HOME%\lib;%PATH%
+
+
+REM
+REM Set TARGET - identify the complete path to the new classes target directory
+REM
+
+SET TARGET=..\classes
+
+
+REM
+REM Create the new classes target directory (if it does not already exist)
+REM
+
+IF EXIST %TARGET% goto COMPILE_CLASSES
+MKDIR %TARGET%
+
+
+REM
+REM Compile TxtTo62 - create "CMS62LdifParser.class", "DummyAuthManager.class",
+REM and "Main.class"
+REM
+
+:COMPILE_CLASSES
+%JAVA_HOME%\bin\javac.exe -d %TARGET% -classpath %JAVA_HOME%\jre\lib\rt.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar Main.java
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/TxtTo62/src/compile.sh b/base/migrate/TxtTo62/src/compile.sh
new file mode 100755
index 000000000..4ab44f966
--- /dev/null
+++ b/base/migrate/TxtTo62/src/compile.sh
@@ -0,0 +1,162 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#####################################################################
+### ###
+### This script creates the "TxtTo62/classes/Main.class", ###
+### "TxtTo62/classes/CMS62LdifParser.class", and ###
+### "TxtTo62/classes/DummyAuthManager.class" which are ###
+### used to create a CMS 6.2 ldif data file. ###
+### ###
+#####################################################################
+
+
+###
+### Set SERVER_ROOT - identify the CMS <server_root> used to compile TxtTo62
+###
+
+#SERVER_ROOT=/export/home/migrate/cms62
+#export SERVER_ROOT
+
+
+###
+### Set JDK_PLATFORM - must be "HP-UX", "Linux", or "SunOS"
+###
+
+#JDK_PLATFORM=SunOS
+#export JDK_PLATFORM
+
+
+###
+### Set JDK_VERSION - specify the JDK version used by this version of CMS
+###
+### CMS 6.2 NOTE: "HP-UX" - 1.4.0.00
+### "Linux" - 1.4.0
+### "SunOS" - 1.4.0
+###
+
+#JDK_VERSION=CMS_6.2
+#export JDK_VERSION
+
+
+###
+### Set JAVA_HOME - specify the complete path to the JDK
+###
+
+#JAVA_HOME=/share/builds/components/cms_jdk/${JDK_PLATFORM}/${JDK_VERSION}
+#export JAVA_HOME
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 6.2"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -gt 0 ] ; then
+ echo
+ echo "Usage: $0"
+ echo
+ echo " NOTE: No arguments are required to build the"
+ echo " ${CMS} ldif data classes."
+ echo
+ exit 1
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${JAVA_HOME}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and JAVA_HOME "
+ echo " environment variables for this script!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 3
+fi
+
+
+###
+### Check that the specified JAVA_HOME exists and is a directory
+###
+
+if [ ! -d "${JAVA_HOME}" ] ; then
+ echo "ERROR: Either the specified JAVA_HOME does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 4
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Set TARGET - identify the complete path to the new classes target directory
+###
+
+TARGET=../classes
+export TARGET
+
+
+###
+### Create the new classes target directory (if it does not already exist)
+###
+
+if [ ! -d ${TARGET} ]; then
+ mkdir -p ${TARGET}
+fi
+
+
+###
+### Compile TxtTo62 - create "CMS62LdifParser.class", "DummyAuthManager.class",
+### and "Main.class"
+###
+
+${JAVA_HOME}/bin/javac -d ${TARGET} -classpath ${JAVA_HOME}/jre/lib/rt.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar Main.java
+
diff --git a/base/migrate/TxtTo70/classes/CMS70LdifParser.class b/base/migrate/TxtTo70/classes/CMS70LdifParser.class
new file mode 100644
index 000000000..3f4ed9b52
--- /dev/null
+++ b/base/migrate/TxtTo70/classes/CMS70LdifParser.class
Binary files differ
diff --git a/base/migrate/TxtTo70/classes/DummyAuthManager.class b/base/migrate/TxtTo70/classes/DummyAuthManager.class
new file mode 100644
index 000000000..387cde908
--- /dev/null
+++ b/base/migrate/TxtTo70/classes/DummyAuthManager.class
Binary files differ
diff --git a/base/migrate/TxtTo70/classes/Main.class b/base/migrate/TxtTo70/classes/Main.class
new file mode 100644
index 000000000..09498213f
--- /dev/null
+++ b/base/migrate/TxtTo70/classes/Main.class
Binary files differ
diff --git a/base/migrate/TxtTo70/run.bat b/base/migrate/TxtTo70/run.bat
new file mode 100755
index 000000000..3e70ee8cd
--- /dev/null
+++ b/base/migrate/TxtTo70/run.bat
@@ -0,0 +1,186 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM This program is free software; you can redistribute it and/or modify
+REM it under the terms of the GNU General Public License as published by
+REM the Free Software Foundation; version 2 of the License.
+REM
+REM This program is distributed in the hope that it will be useful,
+REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+REM GNU General Public License for more details.
+REM
+REM You should have received a copy of the GNU General Public License along
+REM with this program; if not, write to the Free Software Foundation, Inc.,
+REM 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script converts a normalized <Source CMS Version> ldif
+REM text file (e. g. - created via a <Source CMS Version>ToTxt
+REM script) into a CMS 7.0 ldif data file.
+REM
+REM This CMS 7.0 ldif data file can then be imported into the
+REM internal database of the desired CMS 7.0 server using a
+REM utility such as ldif2db.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM SERVER_ROOT - fully qualified path of the location of the server
+REM
+
+REM SET SERVER_ROOT=C:\cms70
+
+
+REM
+REM INSTANCE - if the CMS instance directory is called 'cert-ca',
+REM set the CMS instance to 'ca'
+REM
+REM NOTE: When a single SERVER_ROOT contains more than
+REM one CMS instance, this script must be run multiple
+REM times. To do this, there is only a need to change
+REM the INSTANCE parameter.
+REM
+
+REM SET INSTANCE=ca
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 7.0"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO USAGE
+IF "%3" == "" GOTO CHECK_INPUT_FILE
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0 input [errors] > output"
+ECHO.
+ECHO where: input - the specified %CMS% ldif data file,
+ECHO errors - an optional errors file containing
+ECHO skipped attributes, and
+ECHO output - the normalized %CMS% ldif text file.
+ECHO.
+ECHO NOTE: If no redirection is provided to
+ECHO 'output', then the normalized
+ECHO %CMS% ldif text will merely
+ECHO be echoed to stdout.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified "input" file exists
+REM
+
+:CHECK_INPUT_FILE
+IF EXIST %1 GOTO CHECK_ERRORS_FILE
+
+
+ECHO ERROR: The specified input file, %1, does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM If an "errors" file is specified, then check that it does not already
+REM exist.
+REM
+
+:CHECK_ERRORS_FILE
+IF "%2" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+IF EXIST %2 GOTO ERRORS_FILE_ERROR
+GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:ERRORS_FILE_ERROR
+ECHO ERROR: The specified errors file, %2, already exists!
+ECHO Please specify a different file!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%INSTANCE%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and INSTANCE
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_INSTANCE
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified INSTANCE exists
+REM
+
+:CHECK_INSTANCE
+IF EXIST %SERVER_ROOT%\cert-%INSTANCE% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified INSTANCE does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%SERVER_ROOT%\bin\cert\jre\bin;%SERVER_ROOT\bin\cert\jre\bin\server;%PATH%
+
+
+REM
+REM Convert the specified %CMS% ldif data file
+REM into a normalized %CMS% ldif text file.
+REM
+
+%SERVER_ROOT%\bin\cert\jre\bin\java.exe -classpath .\classes;%SERVER_ROOT%\cert-%INSTANCE%\classes;%SERVER_ROOT%\bin\cert\classes;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar;%SERVER_ROOT%\bin\cert\jre\lib\rt.jar Main %1 %2
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/TxtTo70/run.sh b/base/migrate/TxtTo70/run.sh
new file mode 100755
index 000000000..c7e0a3140
--- /dev/null
+++ b/base/migrate/TxtTo70/run.sh
@@ -0,0 +1,196 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+
+#####################################################################
+### ###
+### This script converts a normalized <Source CMS Version> ldif ###
+### text file (e. g. - created via a <Source CMS Version>ToTxt ###
+### script) into a CMS 7.0 ldif data file. ###
+### ###
+### This CMS 7.0 ldif data file can then be imported into ###
+### the internal database of the desired CMS 7.0 server ###
+### using a utility such as ldif2db. ###
+### ###
+#####################################################################
+
+
+###
+### SERVER_ROOT - fully qualified path of the location of the server
+###
+
+#SERVER_ROOT=/export/home/migrate/cms70
+#export SERVER_ROOT
+
+
+###
+### INSTANCE - if the CMS instance directory is called 'cert-ca',
+### set the CMS instance to 'ca'
+###
+### NOTE: When a single SERVER_ROOT contains more than
+### one CMS instance, this script must be run multiple
+### times. To do this, there is only a need to change
+### the INSTANCE parameter.
+###
+
+#INSTANCE=ca
+#export INSTANCE
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 7.0"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+##
+## Perform a usage check for the appropriate number of arguments:
+##
+
+if [ $# -lt 1 -o $# -gt 2 ] ; then
+ echo
+ echo "Usage: $0 input [errors] > output"
+ echo
+ echo " where: input - the specified ${CMS} ldif data file,"
+ echo " errors - an optional errors file containing"
+ echo " skipped attributes, and"
+ echo " output - the normalized ${CMS} ldif text file."
+ echo
+ echo " NOTE: If no redirection is provided to"
+ echo " 'output', then the normalized"
+ echo " ${CMS} ldif text will merely"
+ echo " be echoed to stdout."
+ echo
+ exit 1
+fi
+
+
+###
+### Check that the specified "input" file exists and is a regular file.
+###
+
+if [ ! -f $1 ] ; then
+ echo "ERROR: Either the specified 'input' file, '$1', does not exist, "
+ echo " or it is not a regular file!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified "input" file exists and is not empty.
+###
+
+if [ ! -s $1 ] ; then
+ echo "ERROR: The specified 'input' file, '$1', is empty!"
+ echo
+ exit 3
+fi
+
+
+###
+### If an "errors" file is specified, then check that it does not already
+### exist.
+###
+
+if [ $# -eq 2 ] ; then
+ if [ -f $2 ] ; then
+ echo "ERROR: The specified 'errors' file, '$2', already exists!"
+ echo " Please specify a different file!"
+ echo
+ exit 4
+ fi
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${INSTANCE}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and INSTANCE "
+ echo " environment variables for this script!"
+ echo
+ exit 5
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 6
+fi
+
+
+###
+### Check that the specified INSTANCE exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}/cert-${INSTANCE}" ] ; then
+ echo "ERROR: Either the specified INSTANCE does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 7
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Convert the specified ${CMS} ldif data file
+### into a normalized ${CMS} ldif text file.
+###
+### NOTE: As of SunOS JDK 1.4.0, the required "Unicode" classes
+### have been moved from "i18n.jar" to "rt.jar".
+###
+
+${SERVER_ROOT}/bin/cert/jre/bin/java -classpath ./classes:${SERVER_ROOT}/cert-${INSTANCE}/classes:${SERVER_ROOT}/bin/cert/classes:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar:${SERVER_ROOT}/bin/cert/jre/lib/rt.jar Main $1 $2
+
diff --git a/base/migrate/TxtTo70/src/Main.java b/base/migrate/TxtTo70/src/Main.java
new file mode 100644
index 000000000..bcb1b5a15
--- /dev/null
+++ b/base/migrate/TxtTo70/src/Main.java
@@ -0,0 +1,655 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+//
+// "TxtTo70/src/Main.java" is based upon a copy "TxtTo62/src/Main.java".
+//
+// Always comment any new code sections with a "CMS 7.0" header, and
+// apply these changes forward to all other "TxtTo*/src/Main.java" files
+// (including this comment header) so that these differences will only
+// appear when this file is diffed against an earlier "TxtTo*" version.
+//
+// This file should always be maintained by executing the following command:
+//
+// diff TxtTo62/src/Main.java TxtTo70/src/Main.java
+//
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import sun.misc.*;
+import org.mozilla.jss.*; // CMS 4.5 and later
+import org.mozilla.jss.crypto.*; // CMS 4.5 and later
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import netscape.security.util.*;
+import java.lang.reflect.*;
+
+public class Main
+{
+ public static void main(String args[])
+ {
+ try {
+ // initialize CryptoManager in CMS 4.5 and later
+ CryptoManager.initialize(".");
+ // load JSS provider in CMS 4.5 and later
+ java.security.Security.removeProvider("SUN version 1.2");
+ // The following call to "java.security.Security.insertProviderAt()"
+ // is no longer commented out in CMS 4.5 and later
+ java.security.Security.insertProviderAt(
+ new netscape.security.provider.CMS(), 0);
+ java.security.Provider ps[] =
+ java.security.Security.getProviders();
+ if (ps == null || ps.length <= 0) {
+ System.err.println("Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ System.err.println("Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+
+ // Parse the File
+ CMS70LdifParser parser = null;
+ if (args.length == 1) {
+ parser = new CMS70LdifParser(args[0]);
+ } else if (args.length == 2) {
+ parser = new CMS70LdifParser(args[0], args[1]);
+ } else {
+ throw new IOException("Invalid Parameters");
+ }
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+}
+
+class CMS70LdifParser
+{
+ // constants
+ private static final String DN =
+ "dn:";
+ // Directory Servers in CMS 4.7 and later use "requestAttributes"
+ private static final String REQUEST_ATTRIBUTES =
+ "requestAttributes::";
+ private static final String BEGIN =
+ "--- BEGIN ATTRIBUTES ---";
+ private static final String END =
+ "--- END ATTRIBUTES ---";
+
+ // variables
+ private String mFilename = null;
+ private String mErrorFilename = null;
+ private PrintWriter mErrorPrintWriter = null;
+
+ public CMS70LdifParser(String filename)
+ {
+ mFilename = filename;
+ }
+
+ public CMS70LdifParser(String filename, String errorFilename)
+ {
+ mFilename = filename;
+ mErrorFilename = errorFilename;
+ }
+
+ public void parse() throws Exception
+ {
+ if (mErrorFilename != null) {
+ mErrorPrintWriter = new PrintWriter(new FileOutputStream(mErrorFilename));
+ }
+ BufferedReader reader = new BufferedReader(
+ new FileReader(mFilename));
+ String line = null;
+ String dn = null;
+ Vector requestAttributes = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DN)) {
+ dn = line;
+ }
+ if (line.equals(BEGIN)) {
+ requestAttributes = new Vector();
+ continue;
+ }
+ if (requestAttributes == null) {
+ System.out.println(line);
+ continue;
+ }
+ if (line.equals(END)) {
+ parseAttributes(dn, requestAttributes);
+ requestAttributes = null;
+ continue;
+ }
+ if (line.startsWith(" ")) { // begining of attr
+ requestAttributes.addElement(
+ line.substring(1, line.length()));
+ } else {
+ requestAttributes.setElementAt(
+ (String)
+ requestAttributes.lastElement() +
+ "\n" +
+ line,
+ requestAttributes.size() - 1);
+ }
+ }
+ }
+
+ private byte[] encode(Object value) throws Exception
+ {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(bos);
+
+ os.writeObject(value);
+ os.close();
+ return bos.toByteArray();
+ }
+
+ public void parseAttributes(String dn, Vector attrs) throws Exception
+ {
+ Hashtable hashtable = new Hashtable();
+ for (int i = 0; i < attrs.size(); i++) {
+ String attr = (String)attrs.elementAt(i);
+ buildHashtable(dn, hashtable, attr);
+ }
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(bos);
+ Enumeration e = hashtable.keys();
+ while (e.hasMoreElements()) {
+ String key = (String)e.nextElement();
+ Object value = hashtable.get(key);
+
+ try {
+ byte data[] = null;
+ data = encode(value);
+ os.writeObject(key);
+ os.writeObject(data);
+ } catch (Exception ex) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + key);
+ }
+ }
+ } // while
+ os.writeObject(null);
+ os.close();
+
+ // print the BASE64 encoding of the Hashtable
+ BASE64Encoder encoder = new BASE64Encoder();
+ String attrsStr = encoder.encodeBuffer(bos.toByteArray());
+ // trim the last "\n"
+ StringBuffer buffer = null;
+ attrsStr = attrsStr.trim();
+ StringTokenizer st = new StringTokenizer(attrsStr, "\r\n");
+ while (st.hasMoreTokens()) {
+ if (buffer == null) {
+ buffer = new StringBuffer();
+ buffer.append(st.nextToken());
+ } else {
+ buffer.append("\r\n " + st.nextToken());
+ }
+ }
+
+ System.out.println(REQUEST_ATTRIBUTES + " " + buffer);
+ }
+
+ public void buildHashtable(String dn, Hashtable table, String attr)
+ throws Exception
+ {
+ // attribute format [name]:[type]=[value]
+
+ int colon = attr.indexOf(':');
+ if (colon == -1) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+ int equal = attr.indexOf('=');
+ if (equal == -1) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+ String name = null;
+ String type = null;
+ String value = null;
+ try {
+ name = attr.substring(0, colon);
+ type = attr.substring(colon+1, equal);
+ value = attr.substring(equal+1);
+ } catch (Exception e) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+
+ if (name.startsWith("serviceErrors")) {
+ // #56953 - skip serviceErrors
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+ if (name.startsWith("Error")) {
+ // #56953 - skip serviceErrors
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+
+ // To account for '47ToTxt' data files that have previously
+ // been generated, ALWAYS convert 'iplanet' to 'netscape'.
+ //
+ // Bugzilla Bug #224801 (a.k.a - Raidzilla Bug #56981)
+ // Bugzilla Bug #483519
+ //
+ String translation = null;
+ if( type.startsWith( "iplanet" ) ) {
+ translation = "netscape"
+ + type.substring( 7 );
+ type = translation;
+ } else if( type.startsWith( "com.iplanet" ) ) {
+ translation = "com.netscape"
+ + type.substring( 11 );
+ type = translation;
+ }
+
+ if (type.startsWith("com.netscape.certsrv.request.AgentApprovals")) {
+ com.netscape.certsrv.request.AgentApprovals obj =
+ (com.netscape.certsrv.request.AgentApprovals)table.get(name);
+ if (obj == null) {
+ obj = new com.netscape.certsrv.request.AgentApprovals();
+ table.put(name, obj);
+ }
+ obj.addApproval(value.substring(0,value.indexOf(';')));
+ } else if (type.startsWith("com.netscape.certsrv.base.ArgBlock")
+ || type.startsWith("com.netscape.cmscore.base.ArgBlock")) {
+ // CMS 6.1: created new "com.netscape.certsrv.base.IArgBlock" and
+ // moved old "com.netscape.certsrv.base.ArgBlock"
+ // to "com.netscape.cmscore.base.ArgBlock"
+ com.netscape.cmscore.base.ArgBlock obj =
+ (com.netscape.cmscore.base.ArgBlock)table.get(name);
+ if (obj == null) {
+ // CMS 6.1: created new "com.netscape.certsrv.base.IArgBlock" and
+ // moved old "com.netscape.certsrv.base.ArgBlock"
+ // to "com.netscape.cmscore.base.ArgBlock"
+ obj = new com.netscape.cmscore.base.ArgBlock();
+ table.put(name, obj);
+ }
+ String valuekey = value.substring(0, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ obj.set(valuekey, valuevalue);
+ } else if (type.startsWith("com.netscape.certsrv.authentication.AuthToken")) {
+ com.netscape.certsrv.authentication.AuthToken obj =
+ (com.netscape.certsrv.authentication.AuthToken)table.get(name);
+ if (obj == null) {
+ com.netscape.certsrv.authentication.IAuthManager mgr =
+ new DummyAuthManager();
+ obj = new com.netscape.certsrv.authentication.AuthToken(mgr);
+ table.put(name, obj);
+ }
+ String valuekey = value.substring(0, value.indexOf(':'));
+ String valuetype = value.substring(value.indexOf(':')+1, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ if (valuetype.equals("java.lang.String")) {
+ // Processes 'java.math.BigInteger[]':
+ //
+ // Bugzilla Bug #225031 (a.k.a - Raidzilla Bug #58356)
+ //
+ // Processes 'java.lang.String[]':
+ //
+ // Bugzilla Bug #224763 (a.k.a - Raidzilla Bug #57949)
+ // Bugzilla Bug #252240
+ //
+ obj.set(valuekey, valuevalue);
+ } else if (valuetype.equals("java.util.Date")) {
+ obj.set(valuekey, new Date(Long.parseLong(valuevalue)));
+ } else {
+ System.err.println("ERROR AuthToken type - " + attr);
+ System.exit(0);
+ }
+ } else if (type.startsWith("java.math.BigInteger[")) {
+ // Bugzilla Bug #238779
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ java.math.BigInteger objs[] = (java.math.BigInteger[])table.get(name);
+ if (objs == null) {
+ objs = new java.math.BigInteger[size];
+ table.put(name, objs);
+ }
+ objs[index] = new java.math.BigInteger(value);
+ } else if (type.startsWith("java.math.BigInteger")) {
+ table.put(name, new java.math.BigInteger(value));
+ } else if (type.startsWith("byte[]")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ table.put(name, decoder.decodeBuffer(value));
+ } else if (type.startsWith("byte[")) {
+ // byte array
+ BASE64Decoder decoder = new BASE64Decoder();
+ table.put(name, decoder.decodeBuffer(value));
+ } else if (type.startsWith("netscape.security.x509.CertificateAlgorithmId")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateAlgorithmId obj =
+ new netscape.security.x509.CertificateAlgorithmId(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateChain")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateChain obj =
+ new netscape.security.x509.CertificateChain();
+ ByteArrayInputStream bis = new ByteArrayInputStream(decoder.decodeBuffer(value));
+ obj.decode(bis);
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateExtensions")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateExtensions obj =
+ new netscape.security.x509.CertificateExtensions();
+ obj.decodeEx(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ // CMS 6.2: revised method of decoding objects of type
+ // "netscape.security.x509.CertificateExtensions"
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateSubjectName")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateSubjectName obj =
+ new netscape.security.x509.CertificateSubjectName(new DerInputStream(decoder.decodeBuffer(value)));
+ // CMS 6.2: revised method of decoding objects of type
+ // "netscape.security.x509.CertificateSubjectName"
+ table.put(name, obj);
+ } else if (type.startsWith("netscape.security.x509.CertificateValidity")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateValidity obj =
+ new netscape.security.x509.CertificateValidity();
+ ByteArrayInputStream bis = new ByteArrayInputStream(decoder.decodeBuffer(value));
+ obj.decode(bis);
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateX509Key")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateX509Key obj =
+ new netscape.security.x509.CertificateX509Key(
+ new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ table.put(name, obj);
+ } else if (type.startsWith("com.netscape.certsrv.cert.CertInfo")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.extensions.CertInfo objs[] = (netscape.security.extensions.CertInfo[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.extensions.CertInfo[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.extensions.CertInfo();
+ objs[index].decode(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ } else if (type.startsWith("java.util.Hashtable")) {
+ // Bugzilla Bug #224800 (a.k.a - Raidzilla Bug #56953)
+ java.util.Hashtable obj = (java.util.Hashtable)table.get(name);
+ if (obj == null) {
+ obj = new java.util.Hashtable();
+ table.put(name, obj);
+ }
+ BASE64Decoder decoder = new BASE64Decoder();
+ String valuekey = value.substring(0, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ obj.put(valuekey, decoder.decodeBuffer(valuevalue));
+ } else if (type.startsWith("Integer[")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ Integer objs[] = (Integer[])table.get(name);
+ if (objs == null) {
+ objs = new Integer[size];
+ table.put(name, objs);
+ }
+ objs[index] = new Integer(value);
+ } else if (type.startsWith("java.lang.Integer")) {
+ table.put(name, new Integer(value));
+ } else if (type.startsWith("com.netscape.certsrv.dbs.keydb.KeyRecord")
+ || type.startsWith("com.netscape.cmscore.dbs.KeyRecord")) {
+ com.netscape.cmscore.dbs.KeyRecord obj =
+ (com.netscape.cmscore.dbs.KeyRecord)table.get(name);
+ if (obj == null) {
+ obj = new com.netscape.cmscore.dbs.KeyRecord();
+ table.put(name, obj);
+ }
+ String valuekey = value.substring(0, value.indexOf(':'));
+ String valuetype = value.substring(value.indexOf(':')+1, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ if (valuetype.equals("java.lang.String")) {
+ obj.set(valuekey, valuevalue);
+ } else if (valuetype.equals("java.util.Date")) {
+ obj.set(valuekey, new Date(Long.parseLong(valuevalue)));
+ } else if (valuetype.equals("java.math.BigInteger")) {
+ obj.set(valuekey, new java.math.BigInteger(valuevalue));
+ } else if (valuetype.equals("java.lang.Integer")) {
+ obj.set(valuekey, new Integer(valuevalue));
+ } else if (valuetype.equals("com.netscape.certsrv.dbs.keydb.KeyState")) {
+ obj.set(valuekey, com.netscape.certsrv.dbs.keydb.KeyState.toKeyState(valuevalue));
+ } else if (valuetype.equals("[B")) {
+ // byte array
+
+ BASE64Decoder decoder = new BASE64Decoder();
+ obj.set(valuekey, decoder.decodeBuffer(valuevalue));
+ } else {
+ System.err.println("ERROR KeyRecord type - " + attr);
+ System.exit(0);
+ }
+ } else if (type.startsWith("java.util.Locale")) {
+ // CMS 6.2: begin checking for new type
+ // "java.util.Locale"
+ table.put(name, Locale.getDefault());
+ } else if (type.startsWith("com.netscape.certsrv.kra.ProofOfArchival")
+ || type.startsWith("com.netscape.cmscore.kra.ProofOfArchival")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(decoder.decodeBuffer(value));
+ com.netscape.cmscore.kra.ProofOfArchival obj =
+ buildPOA(decoder.decodeBuffer(value));
+ table.put(name, obj);
+ } else if (type.startsWith("netscape.security.x509.RevokedCertImpl")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.x509.RevokedCertImpl objs[] = (netscape.security.x509.RevokedCertImpl[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.x509.RevokedCertImpl[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.x509.RevokedCertImpl(decoder.decodeBuffer(value));
+ } else if (type.startsWith("java.lang.String[")) {
+ // Bugzilla Bug #223360 (a.k.a - Raidzilla Bug #58086)
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ java.lang.String objs[] = (java.lang.String[])table.get(name);
+ if (objs == null) {
+ objs = new java.lang.String[size];
+ table.put(name, objs);
+ }
+ objs[index] = new java.lang.String(value);
+ } else if (type.startsWith("java.lang.String")) {
+ table.put(name, value);
+ } else if (type.startsWith("java.util.Vector")) {
+ Vector obj =
+ (Vector)table.get(name);
+ if (obj == null) {
+ obj = new Vector();
+ table.put(name, obj);
+ }
+ obj.addElement(value);
+ } else if (type.startsWith("netscape.security.x509.X509CertImpl[")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.x509.X509CertImpl objs[] = (netscape.security.x509.X509CertImpl[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.x509.X509CertImpl[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.x509.X509CertImpl(decoder.decodeBuffer(value));
+ } else if (type.equals("netscape.security.x509.X509CertImpl")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.X509CertImpl obj =
+ new netscape.security.x509.X509CertImpl(
+ decoder.decodeBuffer(value));
+ table.put(name, obj);
+ } else if (type.startsWith("netscape.security.x509.X509CertInfo[")
+ || type.startsWith("netscape.security.extensions.CertInfo[")) {
+ // CMS 6.2: begin checking for additional new type
+ // "netscape.security.extensions.CertInfo["
+ //
+ // CMS 6.1: "netscape.security.x509.X509CertInfo"
+ // now always utilizes arrays such as
+ // "netscape.security.x509.X509CertInfo["
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.x509.X509CertInfo objs[] = (netscape.security.x509.X509CertInfo[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.x509.X509CertInfo[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.x509.X509CertInfo();
+ objs[index].decode(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ } else if (type.equals("netscape.security.x509.X509CertInfo")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.X509CertInfo obj =
+ new netscape.security.x509.X509CertInfo(
+ decoder.decodeBuffer(value));
+ table.put(name, obj);
+ } else if( type.endsWith( "Exception" ) ) {
+ Class[] argClass = { String.class }; // the argument's class
+ Object[] argValue = { value }; // the argument's value
+
+ Class x = Class.forName( type );
+ Constructor ctr = x.getConstructor( argClass );
+ Exception e = ( Exception ) ctr.newInstance( argValue );
+ } else {
+ System.err.println("ERROR type - " + type + " - "+ attr);
+ System.exit(0);
+ }
+ }
+
+ public com.netscape.cmscore.kra.ProofOfArchival buildPOA(byte data[])
+ throws Exception
+ {
+ DerInputStream dis = new DerInputStream(data);
+ DerValue seq[] = dis.getSequence(0);
+
+ BigInteger mSerialNo = seq[0].getInteger().toBigInteger();
+
+ // subject
+ DerValue subject = seq[1];
+ netscape.security.x509.X500Name mSubject =
+ new netscape.security.x509.X500Name(subject.toByteArray());
+
+ // issuer
+ DerValue issuer = seq[2];
+ netscape.security.x509.X500Name mIssuer =
+ new netscape.security.x509.X500Name(issuer.toByteArray());
+
+ // date of archival
+ DerInputStream dateOfArchival = new DerInputStream(seq[3].toByteArray());
+ Date mDateOfArchival = dateOfArchival.getUTCTime();
+ com.netscape.cmscore.kra.ProofOfArchival obj =
+ new com.netscape.cmscore.kra.ProofOfArchival(mSerialNo,
+ mSubject.toString(), mIssuer.toString(), mDateOfArchival);
+ return obj;
+ }
+}
+
+class DummyAuthManager implements com.netscape.certsrv.authentication.IAuthManager
+{
+ public String getName()
+ {
+ return "dummy";
+ }
+
+ public String getImplName()
+ {
+ return "dummy";
+ }
+
+ public IAuthToken authenticate(IAuthCredentials authCred)
+ throws EMissingCredential, EInvalidCredentials, EBaseException
+ {
+ return null;
+ }
+
+ /**
+ * 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
+ {
+ }
+
+ public void shutdown()
+ {
+ }
+
+ public String[] getRequiredCreds()
+ {
+ return null;
+ }
+
+ /**
+ * 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.
+ *
+ * @param implName The authentication manager plugin name.
+ * @exception EBaseException If an internal error occurred
+ */
+ public String[] getConfigParams()
+ throws EBaseException
+ {
+ return null;
+ }
+
+ /**
+ * Get the configuration store for this authentication manager.
+ * @return The configuration store of this authentication manager.
+ */
+ public IConfigStore getConfigStore()
+ {
+ return null;
+ }
+}
+
diff --git a/base/migrate/TxtTo70/src/compile.bat b/base/migrate/TxtTo70/src/compile.bat
new file mode 100755
index 000000000..f4d496a42
--- /dev/null
+++ b/base/migrate/TxtTo70/src/compile.bat
@@ -0,0 +1,154 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script creates the "TxtTo70/classes/Main.class",
+REM "TxtTo70/classes/CMS70LdifParser.class", and
+REM "TxtTo70/classes/DummyAuthManager.class" which are
+REM used to create a CMS 7.0/7.01 ldif data file.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM Set SERVER_ROOT - identify the CMS <server_root> used to compile TxtTo70
+REM
+
+REM SET SERVER_ROOT=C:\cms701
+
+
+REM
+REM Set JDK_VERSION - specify the JDK version used by this version of CMS
+REM
+REM CMS 7.0 NOTE: "WINNT" - 1.4.2
+REM
+REM CMS 7.01 NOTE: "WINNT" - 1.4.2
+REM
+
+REM SET JDK_VERSION=CMS_7.01
+
+
+REM
+REM Set JAVA_HOME - specify the complete path to the JDK
+REM
+REM example: \\bermuda.redhat.com\sbc mounted as Y:
+REM
+
+REM SET JAVA_HOME=Y:\cms_jdk\WINNT\%JDK_VERSION%
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CMS="CMS 7.0"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0"
+ECHO.
+ECHO NOTE: No arguments are required to build the
+ECHO %CMS% ldif data classes.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%JAVA_HOME%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and JAVA_HOME
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_JAVA_HOME
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified JAVA_HOME exists
+REM
+
+:CHECK_JAVA_HOME
+IF EXIST %JAVA_HOME% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified JAVA_HOME does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%JAVA_HOME%\bin;%JAVA_HOME%\lib;%PATH%
+
+
+REM
+REM Set TARGET - identify the complete path to the new classes target directory
+REM
+
+SET TARGET=..\classes
+
+
+REM
+REM Create the new classes target directory (if it does not already exist)
+REM
+
+IF EXIST %TARGET% goto COMPILE_CLASSES
+MKDIR %TARGET%
+
+
+REM
+REM Compile TxtTo70 - create "CMS70LdifParser.class", "DummyAuthManager.class",
+REM and "Main.class"
+REM
+
+:COMPILE_CLASSES
+%JAVA_HOME%\bin\javac.exe -d %TARGET% -classpath %JAVA_HOME%\jre\lib\rt.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar Main.java
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/TxtTo70/src/compile.sh b/base/migrate/TxtTo70/src/compile.sh
new file mode 100755
index 000000000..11b1b6df8
--- /dev/null
+++ b/base/migrate/TxtTo70/src/compile.sh
@@ -0,0 +1,162 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#####################################################################
+### ###
+### This script creates the "TxtTo70/classes/Main.class", ###
+### "TxtTo70/classes/CMS70LdifParser.class", and ###
+### "TxtTo70/classes/DummyAuthManager.class" which are ###
+### used to create a CMS 7.0 ldif data file. ###
+### ###
+#####################################################################
+
+
+###
+### Set SERVER_ROOT - identify the CMS <server_root> used to compile TxtTo70
+###
+
+#SERVER_ROOT=/export/home/migrate/cms70
+#export SERVER_ROOT
+
+
+###
+### Set JDK_PLATFORM - must be "HP-UX", "Linux", or "SunOS"
+###
+
+#JDK_PLATFORM=SunOS
+#export JDK_PLATFORM
+
+
+###
+### Set JDK_VERSION - specify the JDK version used by this version of CMS
+###
+### CMS 7.0 NOTE: "HP-UX" - 1.4.0.00
+### "Linux" - 1.4.2
+### "SunOS" - 1.4.2
+###
+
+#JDK_VERSION=CMS_7.0
+#export JDK_VERSION
+
+
+###
+### Set JAVA_HOME - specify the complete path to the JDK
+###
+
+#JAVA_HOME=/share/builds/components/cms_jdk/${JDK_PLATFORM}/${JDK_VERSION}
+#export JAVA_HOME
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CMS="CMS 7.0"
+export CMS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -gt 0 ] ; then
+ echo
+ echo "Usage: $0"
+ echo
+ echo " NOTE: No arguments are required to build the"
+ echo " ${CMS} ldif data classes."
+ echo
+ exit 1
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${JAVA_HOME}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and JAVA_HOME "
+ echo " environment variables for this script!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 3
+fi
+
+
+###
+### Check that the specified JAVA_HOME exists and is a directory
+###
+
+if [ ! -d "${JAVA_HOME}" ] ; then
+ echo "ERROR: Either the specified JAVA_HOME does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 4
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Set TARGET - identify the complete path to the new classes target directory
+###
+
+TARGET=../classes
+export TARGET
+
+
+###
+### Create the new classes target directory (if it does not already exist)
+###
+
+if [ ! -d ${TARGET} ]; then
+ mkdir -p ${TARGET}
+fi
+
+
+###
+### Compile TxtTo70 - create "CMS70LdifParser.class", "DummyAuthManager.class",
+### and "Main.class"
+###
+
+${JAVA_HOME}/bin/javac -d ${TARGET} -classpath ${JAVA_HOME}/jre/lib/rt.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar Main.java
+
diff --git a/base/migrate/TxtTo71/classes/CMS71LdifParser.class b/base/migrate/TxtTo71/classes/CMS71LdifParser.class
new file mode 100644
index 000000000..fb449c41f
--- /dev/null
+++ b/base/migrate/TxtTo71/classes/CMS71LdifParser.class
Binary files differ
diff --git a/base/migrate/TxtTo71/classes/DummyAuthManager.class b/base/migrate/TxtTo71/classes/DummyAuthManager.class
new file mode 100644
index 000000000..387cde908
--- /dev/null
+++ b/base/migrate/TxtTo71/classes/DummyAuthManager.class
Binary files differ
diff --git a/base/migrate/TxtTo71/classes/Main.class b/base/migrate/TxtTo71/classes/Main.class
new file mode 100644
index 000000000..8f02b13db
--- /dev/null
+++ b/base/migrate/TxtTo71/classes/Main.class
Binary files differ
diff --git a/base/migrate/TxtTo71/run.bat b/base/migrate/TxtTo71/run.bat
new file mode 100755
index 000000000..1682bacbc
--- /dev/null
+++ b/base/migrate/TxtTo71/run.bat
@@ -0,0 +1,186 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM This program is free software; you can redistribute it and/or modify
+REM it under the terms of the GNU General Public License as published by
+REM the Free Software Foundation; version 2 of the License.
+REM
+REM This program is distributed in the hope that it will be useful,
+REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+REM GNU General Public License for more details.
+REM
+REM You should have received a copy of the GNU General Public License along
+REM with this program; if not, write to the Free Software Foundation, Inc.,
+REM 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script converts a normalized <Source CS Version> ldif
+REM text file (e. g. - created via a <Source CS Version>ToTxt
+REM script) into a CS 7.1 ldif data file.
+REM
+REM This CS 7.1 ldif data file can then be imported into the
+REM internal database of the desired CS 7.1 server using a
+REM utility such as ldif2db.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM SERVER_ROOT - fully qualified path of the location of the server
+REM
+
+REM SET SERVER_ROOT=C:\cs71
+
+
+REM
+REM INSTANCE - if the CS instance directory is called 'cert-ca',
+REM set the CS instance to 'ca'
+REM
+REM NOTE: When a single SERVER_ROOT contains more than
+REM one CS instance, this script must be run multiple
+REM times. To do this, there is only a need to change
+REM the INSTANCE parameter.
+REM
+
+REM SET INSTANCE=ca
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CS="CS 7.1"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO USAGE
+IF "%3" == "" GOTO CHECK_INPUT_FILE
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0 input [errors] > output"
+ECHO.
+ECHO where: input - the specified %CS% ldif data file,
+ECHO errors - an optional errors file containing
+ECHO skipped attributes, and
+ECHO output - the normalized %CS% ldif text file.
+ECHO.
+ECHO NOTE: If no redirection is provided to
+ECHO 'output', then the normalized
+ECHO %CS% ldif text will merely
+ECHO be echoed to stdout.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified "input" file exists
+REM
+
+:CHECK_INPUT_FILE
+IF EXIST %1 GOTO CHECK_ERRORS_FILE
+
+
+ECHO ERROR: The specified input file, %1, does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM If an "errors" file is specified, then check that it does not already
+REM exist.
+REM
+
+:CHECK_ERRORS_FILE
+IF "%2" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+IF EXIST %2 GOTO ERRORS_FILE_ERROR
+GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:ERRORS_FILE_ERROR
+ECHO ERROR: The specified errors file, %2, already exists!
+ECHO Please specify a different file!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%INSTANCE%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and INSTANCE
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_INSTANCE
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified INSTANCE exists
+REM
+
+:CHECK_INSTANCE
+IF EXIST %SERVER_ROOT%\cert-%INSTANCE% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified INSTANCE does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%SERVER_ROOT%\bin\cert\jre\bin;%SERVER_ROOT\bin\cert\jre\bin\server;%PATH%
+
+
+REM
+REM Convert the specified %CS% ldif data file
+REM into a normalized %CS% ldif text file.
+REM
+
+%SERVER_ROOT%\bin\cert\jre\bin\java.exe -classpath .\classes;%SERVER_ROOT%\cert-%INSTANCE%\classes;%SERVER_ROOT%\bin\cert\classes;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar;%SERVER_ROOT%\bin\cert\jre\lib\rt.jar Main %1 %2
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/TxtTo71/run.sh b/base/migrate/TxtTo71/run.sh
new file mode 100755
index 000000000..04e8d4587
--- /dev/null
+++ b/base/migrate/TxtTo71/run.sh
@@ -0,0 +1,196 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+
+#####################################################################
+### ###
+### This script converts a normalized <Source CS Version> ldif ###
+### text file (e. g. - created via a <Source CS Version>ToTxt ###
+### script) into a CS 7.1 ldif data file. ###
+### ###
+### This CS 7.1 ldif data file can then be imported into ###
+### the internal database of the desired CS 7.1 server ###
+### using a utility such as ldif2db. ###
+### ###
+#####################################################################
+
+
+###
+### SERVER_ROOT - fully qualified path of the location of the server
+###
+
+#SERVER_ROOT=/export/home/migrate/cs71
+#export SERVER_ROOT
+
+
+###
+### INSTANCE - if the CS instance directory is called 'cert-ca',
+### set the CS instance to 'ca'
+###
+### NOTE: When a single SERVER_ROOT contains more than
+### one CS instance, this script must be run multiple
+### times. To do this, there is only a need to change
+### the INSTANCE parameter.
+###
+
+#INSTANCE=ca
+#export INSTANCE
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CS="CS 7.1"
+export CS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+##
+## Perform a usage check for the appropriate number of arguments:
+##
+
+if [ $# -lt 1 -o $# -gt 2 ] ; then
+ echo
+ echo "Usage: $0 input [errors] > output"
+ echo
+ echo " where: input - the specified ${CS} ldif data file,"
+ echo " errors - an optional errors file containing"
+ echo " skipped attributes, and"
+ echo " output - the normalized ${CS} ldif text file."
+ echo
+ echo " NOTE: If no redirection is provided to"
+ echo " 'output', then the normalized"
+ echo " ${CS} ldif text will merely"
+ echo " be echoed to stdout."
+ echo
+ exit 1
+fi
+
+
+###
+### Check that the specified "input" file exists and is a regular file.
+###
+
+if [ ! -f $1 ] ; then
+ echo "ERROR: Either the specified 'input' file, '$1', does not exist, "
+ echo " or it is not a regular file!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified "input" file exists and is not empty.
+###
+
+if [ ! -s $1 ] ; then
+ echo "ERROR: The specified 'input' file, '$1', is empty!"
+ echo
+ exit 3
+fi
+
+
+###
+### If an "errors" file is specified, then check that it does not already
+### exist.
+###
+
+if [ $# -eq 2 ] ; then
+ if [ -f $2 ] ; then
+ echo "ERROR: The specified 'errors' file, '$2', already exists!"
+ echo " Please specify a different file!"
+ echo
+ exit 4
+ fi
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${INSTANCE}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and INSTANCE "
+ echo " environment variables for this script!"
+ echo
+ exit 5
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 6
+fi
+
+
+###
+### Check that the specified INSTANCE exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}/cert-${INSTANCE}" ] ; then
+ echo "ERROR: Either the specified INSTANCE does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 7
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${SERVER_ROOT}/bin/cert/jre/lib:${SERVER_ROOT}/bin/cert/jre/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Convert the specified ${CS} ldif data file
+### into a normalized ${CS} ldif text file.
+###
+### NOTE: As of SunOS JDK 1.4.0, the required "Unicode" classes
+### have been moved from "i18n.jar" to "rt.jar".
+###
+
+${SERVER_ROOT}/bin/cert/jre/bin/java -classpath ./classes:${SERVER_ROOT}/cert-${INSTANCE}/classes:${SERVER_ROOT}/bin/cert/classes:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar:${SERVER_ROOT}/bin/cert/jre/lib/rt.jar Main $1 $2
+
diff --git a/base/migrate/TxtTo71/src/Main.java b/base/migrate/TxtTo71/src/Main.java
new file mode 100644
index 000000000..7dcb13943
--- /dev/null
+++ b/base/migrate/TxtTo71/src/Main.java
@@ -0,0 +1,655 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+//
+// "TxtTo71/src/Main.java" is based upon a copy "TxtTo70/src/Main.java".
+//
+// Always comment any new code sections with a "CMS 7.1" header, and
+// apply these changes forward to all other "TxtTo*/src/Main.java" files
+// (including this comment header) so that these differences will only
+// appear when this file is diffed against an earlier "TxtTo*" version.
+//
+// This file should always be maintained by executing the following command:
+//
+// diff TxtTo70/src/Main.java TxtTo71/src/Main.java
+//
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import sun.misc.*;
+import org.mozilla.jss.*; // CMS 4.5 and later
+import org.mozilla.jss.crypto.*; // CMS 4.5 and later
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import netscape.security.util.*;
+import java.lang.reflect.*;
+
+public class Main
+{
+ public static void main(String args[])
+ {
+ try {
+ // initialize CryptoManager in CMS 4.5 and later
+ CryptoManager.initialize(".");
+ // load JSS provider in CMS 4.5 and later
+ java.security.Security.removeProvider("SUN version 1.2");
+ // The following call to "java.security.Security.insertProviderAt()"
+ // is no longer commented out in CMS 4.5 and later
+ java.security.Security.insertProviderAt(
+ new netscape.security.provider.CMS(), 0);
+ java.security.Provider ps[] =
+ java.security.Security.getProviders();
+ if (ps == null || ps.length <= 0) {
+ System.err.println("Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ System.err.println("Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+
+ // Parse the File
+ CMS71LdifParser parser = null;
+ if (args.length == 1) {
+ parser = new CMS71LdifParser(args[0]);
+ } else if (args.length == 2) {
+ parser = new CMS71LdifParser(args[0], args[1]);
+ } else {
+ throw new IOException("Invalid Parameters");
+ }
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+}
+
+class CMS71LdifParser
+{
+ // constants
+ private static final String DN =
+ "dn:";
+ // Directory Servers in CMS 4.7 and later use "requestAttributes"
+ private static final String REQUEST_ATTRIBUTES =
+ "requestAttributes::";
+ private static final String BEGIN =
+ "--- BEGIN ATTRIBUTES ---";
+ private static final String END =
+ "--- END ATTRIBUTES ---";
+
+ // variables
+ private String mFilename = null;
+ private String mErrorFilename = null;
+ private PrintWriter mErrorPrintWriter = null;
+
+ public CMS71LdifParser(String filename)
+ {
+ mFilename = filename;
+ }
+
+ public CMS71LdifParser(String filename, String errorFilename)
+ {
+ mFilename = filename;
+ mErrorFilename = errorFilename;
+ }
+
+ public void parse() throws Exception
+ {
+ if (mErrorFilename != null) {
+ mErrorPrintWriter = new PrintWriter(new FileOutputStream(mErrorFilename));
+ }
+ BufferedReader reader = new BufferedReader(
+ new FileReader(mFilename));
+ String line = null;
+ String dn = null;
+ Vector requestAttributes = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DN)) {
+ dn = line;
+ }
+ if (line.equals(BEGIN)) {
+ requestAttributes = new Vector();
+ continue;
+ }
+ if (requestAttributes == null) {
+ System.out.println(line);
+ continue;
+ }
+ if (line.equals(END)) {
+ parseAttributes(dn, requestAttributes);
+ requestAttributes = null;
+ continue;
+ }
+ if (line.startsWith(" ")) { // begining of attr
+ requestAttributes.addElement(
+ line.substring(1, line.length()));
+ } else {
+ requestAttributes.setElementAt(
+ (String)
+ requestAttributes.lastElement() +
+ "\n" +
+ line,
+ requestAttributes.size() - 1);
+ }
+ }
+ }
+
+ private byte[] encode(Object value) throws Exception
+ {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(bos);
+
+ os.writeObject(value);
+ os.close();
+ return bos.toByteArray();
+ }
+
+ public void parseAttributes(String dn, Vector attrs) throws Exception
+ {
+ Hashtable hashtable = new Hashtable();
+ for (int i = 0; i < attrs.size(); i++) {
+ String attr = (String)attrs.elementAt(i);
+ buildHashtable(dn, hashtable, attr);
+ }
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(bos);
+ Enumeration e = hashtable.keys();
+ while (e.hasMoreElements()) {
+ String key = (String)e.nextElement();
+ Object value = hashtable.get(key);
+
+ try {
+ byte data[] = null;
+ data = encode(value);
+ os.writeObject(key);
+ os.writeObject(data);
+ } catch (Exception ex) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + key);
+ }
+ }
+ } // while
+ os.writeObject(null);
+ os.close();
+
+ // print the BASE64 encoding of the Hashtable
+ BASE64Encoder encoder = new BASE64Encoder();
+ String attrsStr = encoder.encodeBuffer(bos.toByteArray());
+ // trim the last "\n"
+ StringBuffer buffer = null;
+ attrsStr = attrsStr.trim();
+ StringTokenizer st = new StringTokenizer(attrsStr, "\r\n");
+ while (st.hasMoreTokens()) {
+ if (buffer == null) {
+ buffer = new StringBuffer();
+ buffer.append(st.nextToken());
+ } else {
+ buffer.append("\r\n " + st.nextToken());
+ }
+ }
+
+ System.out.println(REQUEST_ATTRIBUTES + " " + buffer);
+ }
+
+ public void buildHashtable(String dn, Hashtable table, String attr)
+ throws Exception
+ {
+ // attribute format [name]:[type]=[value]
+
+ int colon = attr.indexOf(':');
+ if (colon == -1) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+ int equal = attr.indexOf('=');
+ if (equal == -1) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+ String name = null;
+ String type = null;
+ String value = null;
+ try {
+ name = attr.substring(0, colon);
+ type = attr.substring(colon+1, equal);
+ value = attr.substring(equal+1);
+ } catch (Exception e) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+
+ if (name.startsWith("serviceErrors")) {
+ // #56953 - skip serviceErrors
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+ if (name.startsWith("Error")) {
+ // #56953 - skip serviceErrors
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+
+ // To account for '47ToTxt' data files that have previously
+ // been generated, ALWAYS convert 'iplanet' to 'netscape'.
+ //
+ // Bugzilla Bug #224801 (a.k.a - Raidzilla Bug #56981)
+ // Bugzilla Bug #483519
+ //
+ String translation = null;
+ if( type.startsWith( "iplanet" ) ) {
+ translation = "netscape"
+ + type.substring( 7 );
+ type = translation;
+ } else if( type.startsWith( "com.iplanet" ) ) {
+ translation = "com.netscape"
+ + type.substring( 11 );
+ type = translation;
+ }
+
+ if (type.startsWith("com.netscape.certsrv.request.AgentApprovals")) {
+ com.netscape.certsrv.request.AgentApprovals obj =
+ (com.netscape.certsrv.request.AgentApprovals)table.get(name);
+ if (obj == null) {
+ obj = new com.netscape.certsrv.request.AgentApprovals();
+ table.put(name, obj);
+ }
+ obj.addApproval(value.substring(0,value.indexOf(';')));
+ } else if (type.startsWith("com.netscape.certsrv.base.ArgBlock")
+ || type.startsWith("com.netscape.cmscore.base.ArgBlock")) {
+ // CMS 6.1: created new "com.netscape.certsrv.base.IArgBlock" and
+ // moved old "com.netscape.certsrv.base.ArgBlock"
+ // to "com.netscape.cmscore.base.ArgBlock"
+ com.netscape.cmscore.base.ArgBlock obj =
+ (com.netscape.cmscore.base.ArgBlock)table.get(name);
+ if (obj == null) {
+ // CMS 6.1: created new "com.netscape.certsrv.base.IArgBlock" and
+ // moved old "com.netscape.certsrv.base.ArgBlock"
+ // to "com.netscape.cmscore.base.ArgBlock"
+ obj = new com.netscape.cmscore.base.ArgBlock();
+ table.put(name, obj);
+ }
+ String valuekey = value.substring(0, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ obj.set(valuekey, valuevalue);
+ } else if (type.startsWith("com.netscape.certsrv.authentication.AuthToken")) {
+ com.netscape.certsrv.authentication.AuthToken obj =
+ (com.netscape.certsrv.authentication.AuthToken)table.get(name);
+ if (obj == null) {
+ com.netscape.certsrv.authentication.IAuthManager mgr =
+ new DummyAuthManager();
+ obj = new com.netscape.certsrv.authentication.AuthToken(mgr);
+ table.put(name, obj);
+ }
+ String valuekey = value.substring(0, value.indexOf(':'));
+ String valuetype = value.substring(value.indexOf(':')+1, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ if (valuetype.equals("java.lang.String")) {
+ // Processes 'java.math.BigInteger[]':
+ //
+ // Bugzilla Bug #225031 (a.k.a - Raidzilla Bug #58356)
+ //
+ // Processes 'java.lang.String[]':
+ //
+ // Bugzilla Bug #224763 (a.k.a - Raidzilla Bug #57949)
+ // Bugzilla Bug #252240
+ //
+ obj.set(valuekey, valuevalue);
+ } else if (valuetype.equals("java.util.Date")) {
+ obj.set(valuekey, new Date(Long.parseLong(valuevalue)));
+ } else {
+ System.err.println("ERROR AuthToken type - " + attr);
+ System.exit(0);
+ }
+ } else if (type.startsWith("java.math.BigInteger[")) {
+ // Bugzilla Bug #238779
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ java.math.BigInteger objs[] = (java.math.BigInteger[])table.get(name);
+ if (objs == null) {
+ objs = new java.math.BigInteger[size];
+ table.put(name, objs);
+ }
+ objs[index] = new java.math.BigInteger(value);
+ } else if (type.startsWith("java.math.BigInteger")) {
+ table.put(name, new java.math.BigInteger(value));
+ } else if (type.startsWith("byte[]")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ table.put(name, decoder.decodeBuffer(value));
+ } else if (type.startsWith("byte[")) {
+ // byte array
+ BASE64Decoder decoder = new BASE64Decoder();
+ table.put(name, decoder.decodeBuffer(value));
+ } else if (type.startsWith("netscape.security.x509.CertificateAlgorithmId")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateAlgorithmId obj =
+ new netscape.security.x509.CertificateAlgorithmId(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateChain")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateChain obj =
+ new netscape.security.x509.CertificateChain();
+ ByteArrayInputStream bis = new ByteArrayInputStream(decoder.decodeBuffer(value));
+ obj.decode(bis);
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateExtensions")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateExtensions obj =
+ new netscape.security.x509.CertificateExtensions();
+ obj.decodeEx(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ // CMS 6.2: revised method of decoding objects of type
+ // "netscape.security.x509.CertificateExtensions"
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateSubjectName")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateSubjectName obj =
+ new netscape.security.x509.CertificateSubjectName(new DerInputStream(decoder.decodeBuffer(value)));
+ // CMS 6.2: revised method of decoding objects of type
+ // "netscape.security.x509.CertificateSubjectName"
+ table.put(name, obj);
+ } else if (type.startsWith("netscape.security.x509.CertificateValidity")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateValidity obj =
+ new netscape.security.x509.CertificateValidity();
+ ByteArrayInputStream bis = new ByteArrayInputStream(decoder.decodeBuffer(value));
+ obj.decode(bis);
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateX509Key")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateX509Key obj =
+ new netscape.security.x509.CertificateX509Key(
+ new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ table.put(name, obj);
+ } else if (type.startsWith("com.netscape.certsrv.cert.CertInfo")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.extensions.CertInfo objs[] = (netscape.security.extensions.CertInfo[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.extensions.CertInfo[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.extensions.CertInfo();
+ objs[index].decode(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ } else if (type.startsWith("java.util.Hashtable")) {
+ // Bugzilla Bug #224800 (a.k.a - Raidzilla Bug #56953)
+ java.util.Hashtable obj = (java.util.Hashtable)table.get(name);
+ if (obj == null) {
+ obj = new java.util.Hashtable();
+ table.put(name, obj);
+ }
+ BASE64Decoder decoder = new BASE64Decoder();
+ String valuekey = value.substring(0, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ obj.put(valuekey, decoder.decodeBuffer(valuevalue));
+ } else if (type.startsWith("Integer[")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ Integer objs[] = (Integer[])table.get(name);
+ if (objs == null) {
+ objs = new Integer[size];
+ table.put(name, objs);
+ }
+ objs[index] = new Integer(value);
+ } else if (type.startsWith("java.lang.Integer")) {
+ table.put(name, new Integer(value));
+ } else if (type.startsWith("com.netscape.certsrv.dbs.keydb.KeyRecord")
+ || type.startsWith("com.netscape.cmscore.dbs.KeyRecord")) {
+ com.netscape.cmscore.dbs.KeyRecord obj =
+ (com.netscape.cmscore.dbs.KeyRecord)table.get(name);
+ if (obj == null) {
+ obj = new com.netscape.cmscore.dbs.KeyRecord();
+ table.put(name, obj);
+ }
+ String valuekey = value.substring(0, value.indexOf(':'));
+ String valuetype = value.substring(value.indexOf(':')+1, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ if (valuetype.equals("java.lang.String")) {
+ obj.set(valuekey, valuevalue);
+ } else if (valuetype.equals("java.util.Date")) {
+ obj.set(valuekey, new Date(Long.parseLong(valuevalue)));
+ } else if (valuetype.equals("java.math.BigInteger")) {
+ obj.set(valuekey, new java.math.BigInteger(valuevalue));
+ } else if (valuetype.equals("java.lang.Integer")) {
+ obj.set(valuekey, new Integer(valuevalue));
+ } else if (valuetype.equals("com.netscape.certsrv.dbs.keydb.KeyState")) {
+ obj.set(valuekey, com.netscape.certsrv.dbs.keydb.KeyState.toKeyState(valuevalue));
+ } else if (valuetype.equals("[B")) {
+ // byte array
+
+ BASE64Decoder decoder = new BASE64Decoder();
+ obj.set(valuekey, decoder.decodeBuffer(valuevalue));
+ } else {
+ System.err.println("ERROR KeyRecord type - " + attr);
+ System.exit(0);
+ }
+ } else if (type.startsWith("java.util.Locale")) {
+ // CMS 6.2: begin checking for new type
+ // "java.util.Locale"
+ table.put(name, Locale.getDefault());
+ } else if (type.startsWith("com.netscape.certsrv.kra.ProofOfArchival")
+ || type.startsWith("com.netscape.cmscore.kra.ProofOfArchival")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(decoder.decodeBuffer(value));
+ com.netscape.cmscore.kra.ProofOfArchival obj =
+ buildPOA(decoder.decodeBuffer(value));
+ table.put(name, obj);
+ } else if (type.startsWith("netscape.security.x509.RevokedCertImpl")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.x509.RevokedCertImpl objs[] = (netscape.security.x509.RevokedCertImpl[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.x509.RevokedCertImpl[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.x509.RevokedCertImpl(decoder.decodeBuffer(value));
+ } else if (type.startsWith("java.lang.String[")) {
+ // Bugzilla Bug #223360 (a.k.a - Raidzilla Bug #58086)
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ java.lang.String objs[] = (java.lang.String[])table.get(name);
+ if (objs == null) {
+ objs = new java.lang.String[size];
+ table.put(name, objs);
+ }
+ objs[index] = new java.lang.String(value);
+ } else if (type.startsWith("java.lang.String")) {
+ table.put(name, value);
+ } else if (type.startsWith("java.util.Vector")) {
+ Vector obj =
+ (Vector)table.get(name);
+ if (obj == null) {
+ obj = new Vector();
+ table.put(name, obj);
+ }
+ obj.addElement(value);
+ } else if (type.startsWith("netscape.security.x509.X509CertImpl[")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.x509.X509CertImpl objs[] = (netscape.security.x509.X509CertImpl[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.x509.X509CertImpl[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.x509.X509CertImpl(decoder.decodeBuffer(value));
+ } else if (type.equals("netscape.security.x509.X509CertImpl")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.X509CertImpl obj =
+ new netscape.security.x509.X509CertImpl(
+ decoder.decodeBuffer(value));
+ table.put(name, obj);
+ } else if (type.startsWith("netscape.security.x509.X509CertInfo[")
+ || type.startsWith("netscape.security.extensions.CertInfo[")) {
+ // CMS 6.2: begin checking for additional new type
+ // "netscape.security.extensions.CertInfo["
+ //
+ // CMS 6.1: "netscape.security.x509.X509CertInfo"
+ // now always utilizes arrays such as
+ // "netscape.security.x509.X509CertInfo["
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.x509.X509CertInfo objs[] = (netscape.security.x509.X509CertInfo[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.x509.X509CertInfo[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.x509.X509CertInfo();
+ objs[index].decode(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ } else if (type.equals("netscape.security.x509.X509CertInfo")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.X509CertInfo obj =
+ new netscape.security.x509.X509CertInfo(
+ decoder.decodeBuffer(value));
+ table.put(name, obj);
+ } else if( type.endsWith( "Exception" ) ) {
+ Class[] argClass = { String.class }; // the argument's class
+ Object[] argValue = { value }; // the argument's value
+
+ Class x = Class.forName( type );
+ Constructor ctr = x.getConstructor( argClass );
+ Exception e = ( Exception ) ctr.newInstance( argValue );
+ } else {
+ System.err.println("ERROR type - " + type + " - "+ attr);
+ System.exit(0);
+ }
+ }
+
+ public com.netscape.cmscore.kra.ProofOfArchival buildPOA(byte data[])
+ throws Exception
+ {
+ DerInputStream dis = new DerInputStream(data);
+ DerValue seq[] = dis.getSequence(0);
+
+ BigInteger mSerialNo = seq[0].getInteger().toBigInteger();
+
+ // subject
+ DerValue subject = seq[1];
+ netscape.security.x509.X500Name mSubject =
+ new netscape.security.x509.X500Name(subject.toByteArray());
+
+ // issuer
+ DerValue issuer = seq[2];
+ netscape.security.x509.X500Name mIssuer =
+ new netscape.security.x509.X500Name(issuer.toByteArray());
+
+ // date of archival
+ DerInputStream dateOfArchival = new DerInputStream(seq[3].toByteArray());
+ Date mDateOfArchival = dateOfArchival.getUTCTime();
+ com.netscape.cmscore.kra.ProofOfArchival obj =
+ new com.netscape.cmscore.kra.ProofOfArchival(mSerialNo,
+ mSubject.toString(), mIssuer.toString(), mDateOfArchival);
+ return obj;
+ }
+}
+
+class DummyAuthManager implements com.netscape.certsrv.authentication.IAuthManager
+{
+ public String getName()
+ {
+ return "dummy";
+ }
+
+ public String getImplName()
+ {
+ return "dummy";
+ }
+
+ public IAuthToken authenticate(IAuthCredentials authCred)
+ throws EMissingCredential, EInvalidCredentials, EBaseException
+ {
+ return null;
+ }
+
+ /**
+ * 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
+ {
+ }
+
+ public void shutdown()
+ {
+ }
+
+ public String[] getRequiredCreds()
+ {
+ return null;
+ }
+
+ /**
+ * 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.
+ *
+ * @param implName The authentication manager plugin name.
+ * @exception EBaseException If an internal error occurred
+ */
+ public String[] getConfigParams()
+ throws EBaseException
+ {
+ return null;
+ }
+
+ /**
+ * Get the configuration store for this authentication manager.
+ * @return The configuration store of this authentication manager.
+ */
+ public IConfigStore getConfigStore()
+ {
+ return null;
+ }
+}
+
diff --git a/base/migrate/TxtTo71/src/compile.bat b/base/migrate/TxtTo71/src/compile.bat
new file mode 100755
index 000000000..d0a1be0b2
--- /dev/null
+++ b/base/migrate/TxtTo71/src/compile.bat
@@ -0,0 +1,152 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script creates the "TxtTo71/classes/Main.class",
+REM "TxtTo71/classes/CMS71LdifParser.class", and
+REM "TxtTo71/classes/DummyAuthManager.class" which are
+REM used to create a CS 7.1 ldif data file.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM Set SERVER_ROOT - identify the CS <server_root> used to compile TxtTo71
+REM
+
+REM SET SERVER_ROOT=C:\cs71
+
+
+REM
+REM Set JDK_VERSION - specify the JDK version used by this version of CS
+REM
+REM CS 7.1 NOTE: "WINNT" - 1.4.2
+REM
+
+REM SET JDK_VERSION=CS_7.1
+
+
+REM
+REM Set JAVA_HOME - specify the complete path to the JDK
+REM
+REM example: \\bermuda.redhat.com\sbc mounted as Y:
+REM
+
+REM SET JAVA_HOME=Y:\cms_jdk\WINNT\%JDK_VERSION%
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CS="CS 7.1"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0"
+ECHO.
+ECHO NOTE: No arguments are required to build the
+ECHO %CS% ldif data classes.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%JAVA_HOME%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and JAVA_HOME
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_JAVA_HOME
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified JAVA_HOME exists
+REM
+
+:CHECK_JAVA_HOME
+IF EXIST %JAVA_HOME% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified JAVA_HOME does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%JAVA_HOME%\bin;%JAVA_HOME%\lib;%PATH%
+
+
+REM
+REM Set TARGET - identify the complete path to the new classes target directory
+REM
+
+SET TARGET=..\classes
+
+
+REM
+REM Create the new classes target directory (if it does not already exist)
+REM
+
+IF EXIST %TARGET% goto COMPILE_CLASSES
+MKDIR %TARGET%
+
+
+REM
+REM Compile TxtTo71 - create "CMS71LdifParser.class", "DummyAuthManager.class",
+REM and "Main.class"
+REM
+
+:COMPILE_CLASSES
+%JAVA_HOME%\bin\javac.exe -d %TARGET% -classpath %JAVA_HOME%\jre\lib\rt.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar Main.java
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/TxtTo71/src/compile.sh b/base/migrate/TxtTo71/src/compile.sh
new file mode 100755
index 000000000..397912a3f
--- /dev/null
+++ b/base/migrate/TxtTo71/src/compile.sh
@@ -0,0 +1,162 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#####################################################################
+### ###
+### This script creates the "TxtTo71/classes/Main.class", ###
+### "TxtTo71/classes/CMS71LdifParser.class", and ###
+### "TxtTo71/classes/DummyAuthManager.class" which are ###
+### used to create a CS 7.1 ldif data file. ###
+### ###
+#####################################################################
+
+
+###
+### Set SERVER_ROOT - identify the CS <server_root> used to compile TxtTo71
+###
+
+#SERVER_ROOT=/export/home/migrate/cs71
+#export SERVER_ROOT
+
+
+###
+### Set JDK_PLATFORM - must be "HP-UX", "Linux", or "SunOS"
+###
+
+#JDK_PLATFORM=SunOS
+#export JDK_PLATFORM
+
+
+###
+### Set JDK_VERSION - specify the JDK version used by this version of CS
+###
+### CS 7.1 NOTE: "HP-UX" - 1.4.0.00
+### "Linux" - 1.4.2
+### "SunOS" - 1.4.2
+###
+
+#JDK_VERSION=CS_7.1
+#export JDK_VERSION
+
+
+###
+### Set JAVA_HOME - specify the complete path to the JDK
+###
+
+#JAVA_HOME=/share/builds/components/cms_jdk/${JDK_PLATFORM}/${JDK_VERSION}
+#export JAVA_HOME
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CS="CS 7.1"
+export CS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -gt 0 ] ; then
+ echo
+ echo "Usage: $0"
+ echo
+ echo " NOTE: No arguments are required to build the"
+ echo " ${CS} ldif data classes."
+ echo
+ exit 1
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${SERVER_ROOT}" -o -z "${JAVA_HOME}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and JAVA_HOME "
+ echo " environment variables for this script!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified SERVER_ROOT exists and is a directory
+###
+
+if [ ! -d "${SERVER_ROOT}" ] ; then
+ echo "ERROR: Either the specified SERVER_ROOT does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 3
+fi
+
+
+###
+### Check that the specified JAVA_HOME exists and is a directory
+###
+
+if [ ! -d "${JAVA_HOME}" ] ; then
+ echo "ERROR: Either the specified JAVA_HOME does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 4
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=${SERVER_ROOT}/bin/cert/lib:${JAVA_HOME}/lib:${JAVA_HOME}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Set TARGET - identify the complete path to the new classes target directory
+###
+
+TARGET=../classes
+export TARGET
+
+
+###
+### Create the new classes target directory (if it does not already exist)
+###
+
+if [ ! -d ${TARGET} ]; then
+ mkdir -p ${TARGET}
+fi
+
+
+###
+### Compile TxtTo71 - create "CMS71LdifParser.class", "DummyAuthManager.class",
+### and "Main.class"
+###
+
+${JAVA_HOME}/bin/javac -d ${TARGET} -classpath ${JAVA_HOME}/jre/lib/rt.jar:${SERVER_ROOT}/bin/cert/jars/nsutil.jar:${SERVER_ROOT}/bin/cert/jars/certsrv.jar:${SERVER_ROOT}/bin/cert/jars/cmscore.jar:${SERVER_ROOT}/bin/cert/jars/jss3.jar Main.java
+
diff --git a/base/migrate/TxtTo72/classes/CMS72LdifParser.class b/base/migrate/TxtTo72/classes/CMS72LdifParser.class
new file mode 100644
index 000000000..c3b8d5643
--- /dev/null
+++ b/base/migrate/TxtTo72/classes/CMS72LdifParser.class
Binary files differ
diff --git a/base/migrate/TxtTo72/classes/DummyAuthManager.class b/base/migrate/TxtTo72/classes/DummyAuthManager.class
new file mode 100644
index 000000000..323081a39
--- /dev/null
+++ b/base/migrate/TxtTo72/classes/DummyAuthManager.class
Binary files differ
diff --git a/base/migrate/TxtTo72/classes/Main.class b/base/migrate/TxtTo72/classes/Main.class
new file mode 100644
index 000000000..2512afa7d
--- /dev/null
+++ b/base/migrate/TxtTo72/classes/Main.class
Binary files differ
diff --git a/base/migrate/TxtTo72/run.bat b/base/migrate/TxtTo72/run.bat
new file mode 100755
index 000000000..852158747
--- /dev/null
+++ b/base/migrate/TxtTo72/run.bat
@@ -0,0 +1,186 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM This program is free software; you can redistribute it and/or modify
+REM it under the terms of the GNU General Public License as published by
+REM the Free Software Foundation; version 2 of the License.
+REM
+REM This program is distributed in the hope that it will be useful,
+REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+REM GNU General Public License for more details.
+REM
+REM You should have received a copy of the GNU General Public License along
+REM with this program; if not, write to the Free Software Foundation, Inc.,
+REM 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script converts a normalized <Source CS Version> ldif
+REM text file (e. g. - created via a <Source CS Version>ToTxt
+REM script) into a CS 7.2 ldif data file.
+REM
+REM This CS 7.2 ldif data file can then be imported into the
+REM internal database of the desired CS 7.2 server using a
+REM utility such as ldif2db.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM SERVER_ROOT - fully qualified path of the location of the server
+REM
+
+REM SET SERVER_ROOT=C:\cs72
+
+
+REM
+REM INSTANCE - if the CS instance directory is called 'cert-ca',
+REM set the CS instance to 'ca'
+REM
+REM NOTE: When a single SERVER_ROOT contains more than
+REM one CS instance, this script must be run multiple
+REM times. To do this, there is only a need to change
+REM the INSTANCE parameter.
+REM
+
+REM SET INSTANCE=ca
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CS="CS 7.2"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO USAGE
+IF "%3" == "" GOTO CHECK_INPUT_FILE
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0 input [errors] > output"
+ECHO.
+ECHO where: input - the specified %CS% ldif data file,
+ECHO errors - an optional errors file containing
+ECHO skipped attributes, and
+ECHO output - the normalized %CS% ldif text file.
+ECHO.
+ECHO NOTE: If no redirection is provided to
+ECHO 'output', then the normalized
+ECHO %CS% ldif text will merely
+ECHO be echoed to stdout.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified "input" file exists
+REM
+
+:CHECK_INPUT_FILE
+IF EXIST %1 GOTO CHECK_ERRORS_FILE
+
+
+ECHO ERROR: The specified input file, %1, does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM If an "errors" file is specified, then check that it does not already
+REM exist.
+REM
+
+:CHECK_ERRORS_FILE
+IF "%2" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+IF EXIST %2 GOTO ERRORS_FILE_ERROR
+GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:ERRORS_FILE_ERROR
+ECHO ERROR: The specified errors file, %2, already exists!
+ECHO Please specify a different file!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%INSTANCE%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and INSTANCE
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_INSTANCE
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified INSTANCE exists
+REM
+
+:CHECK_INSTANCE
+IF EXIST %SERVER_ROOT%\cert-%INSTANCE% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified INSTANCE does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%SERVER_ROOT%\bin\cert\jre\bin;%SERVER_ROOT\bin\cert\jre\bin\server;%PATH%
+
+
+REM
+REM Convert the specified %CS% ldif data file
+REM into a normalized %CS% ldif text file.
+REM
+
+%SERVER_ROOT%\bin\cert\jre\bin\java.exe -classpath .\classes;%SERVER_ROOT%\cert-%INSTANCE%\classes;%SERVER_ROOT%\bin\cert\classes;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar;%SERVER_ROOT%\bin\cert\jre\lib\rt.jar Main %1 %2
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/TxtTo72/run.sh b/base/migrate/TxtTo72/run.sh
new file mode 100755
index 000000000..972686e3b
--- /dev/null
+++ b/base/migrate/TxtTo72/run.sh
@@ -0,0 +1,152 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+
+#####################################################################
+### ###
+### This script converts a normalized <Source CS Version> ldif ###
+### text file (e. g. - created via a <Source CS Version>ToTxt ###
+### script) into a CS 7.2 ldif data file. ###
+### ###
+### This CS 7.2 ldif data file can then be imported into ###
+### the internal database of the desired CS 7.2 server ###
+### using a utility such as ldif2db. ###
+### ###
+#####################################################################
+
+###
+### Java Runtime Environment
+###
+JRE_ROOT=/usr/lib/jvm/jre-1.5.0
+export JRE_ROOT
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CS="CS 7.2"
+export CS
+
+OS_NAME=`uname`
+export OS_NAME
+
+ARCH=`uname -i`
+export ARCH
+
+
+##
+## Perform a usage check for the appropriate number of arguments:
+##
+
+if [ $# -lt 1 -o $# -gt 2 ] ; then
+ echo
+ echo "Usage: $0 input [errors] > output"
+ echo
+ echo " where: input - the specified ${CS} ldif data file,"
+ echo " errors - an optional errors file containing"
+ echo " skipped attributes, and"
+ echo " output - the normalized ${CS} ldif text file."
+ echo
+ echo " NOTE: If no redirection is provided to"
+ echo " 'output', then the normalized"
+ echo " ${CS} ldif text will merely"
+ echo " be echoed to stdout."
+ echo
+ exit 1
+fi
+
+
+###
+### Check that the specified "input" file exists and is a regular file.
+###
+
+if [ ! -f $1 ] ; then
+ echo "ERROR: Either the specified 'input' file, '$1', does not exist, "
+ echo " or it is not a regular file!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified "input" file exists and is not empty.
+###
+
+if [ ! -s $1 ] ; then
+ echo "ERROR: The specified 'input' file, '$1', is empty!"
+ echo
+ exit 3
+fi
+
+
+###
+### If an "errors" file is specified, then check that it does not already
+### exist.
+###
+
+if [ $# -eq 2 ] ; then
+ if [ -f $2 ] ; then
+ echo "ERROR: The specified 'errors' file, '$2', already exists!"
+ echo " Please specify a different file!"
+ echo
+ exit 4
+ fi
+fi
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+### NOTE: As of SunOS JDK 1.4.0, the required "Unicode" classes
+### have been moved from "i18n.jar" to "rt.jar".
+###
+
+CLASSPATH=/usr/share/rhpki/migrate/TxtTo72/classes:/usr/share/java/rhpki/certsrv.jar:/usr/share/java/rhpki/cmscore.jar:/usr/share/java/rhpki/nsutil.jar:/usr/lib/java/dirsec/jss4.jar:${JRE_ROOT}/lib/rt.jar
+export CLASSPATH
+
+if [ ${OS_NAME} = "Linux" ] ; then
+ if [ ${ARCH} = "i386" ] ; then
+ LD_LIBRARY_PATH=/usr/lib/dirsec:/usr/lib:${JRE_ROOT}/lib:${JRE_ROOT}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+ else # x86_64
+ LD_LIBRARY_PATH=/usr/lib64/dirsec:/usr/lib64:${JRE_ROOT}/lib:${JRE_ROOT}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+ CLASSPATH=/usr/share/rhpki/migrate/TxtTo72/classes:/usr/share/java/rhpki/certsrv.jar:/usr/share/java/rhpki/cmscore.jar:/usr/share/java/rhpki/nsutil.jar:/usr/lib64/java/dirsec/jss4.jar:${JRE_ROOT}/lib/rt.jar
+ export CLASSPATH
+ fi
+else # SunOS 64-bits
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/dirsec:/usr/lib/sparcv9:${JRE_ROOT}/lib:${JRE_ROOT}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+ CLASSPATH=/usr/share/rhpki/migrate/TxtTo72/classes:/usr/share/java/rhpki/certsrv.jar:/usr/share/java/rhpki/cmscore.jar:/usr/share/java/rhpki/nsutil.jar:/usr/lib/sparcv9/java/dirsec/jss4.jar:${JRE_ROOT}/lib/rt.jar
+ export CLASSPATH
+fi
+
+
+###
+### Convert the specified ${CS} ldif data file
+### into a normalized ${CS} ldif text file.
+###
+
+${JRE_ROOT}/bin/java -classpath ${CLASSPATH} Main $1 $2
diff --git a/base/migrate/TxtTo72/src/Main.java b/base/migrate/TxtTo72/src/Main.java
new file mode 100644
index 000000000..9b22cd84d
--- /dev/null
+++ b/base/migrate/TxtTo72/src/Main.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 ---
+//
+// "TxtTo71/src/Main.java" is based upon a copy "TxtTo70/src/Main.java".
+//
+// Always comment any new code sections with a "CMS 7.1" header, and
+// apply these changes forward to all other "TxtTo*/src/Main.java" files
+// (including this comment header) so that these differences will only
+// appear when this file is diffed against an earlier "TxtTo*" version.
+//
+// This file should always be maintained by executing the following command:
+//
+// diff TxtTo70/src/Main.java TxtTo71/src/Main.java
+//
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import sun.misc.*;
+import org.mozilla.jss.*; // CMS 4.5 and later
+import org.mozilla.jss.crypto.*; // CMS 4.5 and later
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import netscape.security.util.*;
+import java.lang.reflect.*;
+
+public class Main
+{
+ public static void main(String args[])
+ {
+ try {
+ // initialize CryptoManager in CMS 4.5 and later
+ CryptoManager.initialize(".");
+ // load JSS provider in CMS 4.5 and later
+ java.security.Security.removeProvider("SUN version 1.2");
+ // The following call to "java.security.Security.insertProviderAt()"
+ // is no longer commented out in CMS 4.5 and later
+ java.security.Security.insertProviderAt(
+ new netscape.security.provider.CMS(), 0);
+ java.security.Provider ps[] =
+ java.security.Security.getProviders();
+ if (ps == null || ps.length <= 0) {
+ System.err.println("Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ System.err.println("Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+
+ // Parse the File
+ CMS72LdifParser parser = null;
+ if (args.length == 1) {
+ parser = new CMS72LdifParser(args[0]);
+ } else if (args.length == 2) {
+ parser = new CMS72LdifParser(args[0], args[1]);
+ } else {
+ throw new IOException("Invalid Parameters");
+ }
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+}
+
+class CMS72LdifParser
+{
+ // constants
+ private static final String DN =
+ "dn:";
+ // Directory Servers in CMS 4.7 and later use "requestAttributes"
+ private static final String REQUEST_ATTRIBUTES =
+ "requestAttributes::";
+ private static final String BEGIN =
+ "--- BEGIN ATTRIBUTES ---";
+ private static final String END =
+ "--- END ATTRIBUTES ---";
+
+ // variables
+ private String mFilename = null;
+ private String mErrorFilename = null;
+ private PrintWriter mErrorPrintWriter = null;
+
+ public CMS72LdifParser(String filename)
+ {
+ mFilename = filename;
+ }
+
+ public CMS72LdifParser(String filename, String errorFilename)
+ {
+ mFilename = filename;
+ mErrorFilename = errorFilename;
+ }
+
+ public void parse() throws Exception
+ {
+ if (mErrorFilename != null) {
+ mErrorPrintWriter = new PrintWriter(new FileOutputStream(mErrorFilename));
+ }
+ BufferedReader reader = new BufferedReader(
+ new FileReader(mFilename));
+ String line = null;
+ String dn = null;
+ Vector requestAttributes = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DN)) {
+ dn = line;
+ }
+ if (line.equals(BEGIN)) {
+ requestAttributes = new Vector();
+ continue;
+ }
+ if (requestAttributes == null) {
+ System.out.println(line);
+ continue;
+ }
+ if (line.equals(END)) {
+ parseAttributes(dn, requestAttributes);
+ requestAttributes = null;
+ continue;
+ }
+ if (line.startsWith(" ")) { // begining of attr
+ requestAttributes.addElement(
+ line.substring(1, line.length()));
+ } else {
+ requestAttributes.setElementAt(
+ (String)
+ requestAttributes.lastElement() +
+ "\n" +
+ line,
+ requestAttributes.size() - 1);
+ }
+ }
+ }
+
+ private byte[] encode(Object value) throws Exception
+ {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(bos);
+
+ os.writeObject(value);
+ os.close();
+ return bos.toByteArray();
+ }
+
+ public void parseAttributes(String dn, Vector attrs) throws Exception
+ {
+ Hashtable hashtable = new Hashtable();
+ for (int i = 0; i < attrs.size(); i++) {
+ String attr = (String)attrs.elementAt(i);
+ buildHashtable(dn, hashtable, attr);
+ }
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(bos);
+ Enumeration e = hashtable.keys();
+ while (e.hasMoreElements()) {
+ String key = (String)e.nextElement();
+ Object value = hashtable.get(key);
+
+ try {
+ byte data[] = null;
+ data = encode(value);
+ os.writeObject(key);
+ os.writeObject(data);
+ } catch (Exception ex) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + key);
+ }
+ }
+ } // while
+ os.writeObject(null);
+ os.close();
+
+ // print the BASE64 encoding of the Hashtable
+ BASE64Encoder encoder = new BASE64Encoder();
+ String attrsStr = encoder.encodeBuffer(bos.toByteArray());
+ // trim the last "\n"
+ StringBuffer buffer = null;
+ attrsStr = attrsStr.trim();
+ StringTokenizer st = new StringTokenizer(attrsStr, "\r\n");
+ while (st.hasMoreTokens()) {
+ if (buffer == null) {
+ buffer = new StringBuffer();
+ buffer.append(st.nextToken());
+ } else {
+ buffer.append("\r\n " + st.nextToken());
+ }
+ }
+
+ System.out.println(REQUEST_ATTRIBUTES + " " + buffer);
+ }
+
+ public void buildHashtable(String dn, Hashtable table, String attr)
+ throws Exception
+ {
+ // attribute format [name]:[type]=[value]
+
+ int colon = attr.indexOf(':');
+ if (colon == -1) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+ int equal = attr.indexOf('=');
+ if (equal == -1) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+ String name = null;
+ String type = null;
+ String value = null;
+ try {
+ name = attr.substring(0, colon);
+ type = attr.substring(colon+1, equal);
+ value = attr.substring(equal+1);
+ } catch (Exception e) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+
+ if (name.startsWith("serviceErrors")) {
+ // #56953 - skip serviceErrors
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+ if (name.startsWith("Error")) {
+ // #56953 - skip serviceErrors
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+
+ // To account for '47ToTxt' data files that have previously
+ // been generated, ALWAYS convert 'iplanet' to 'netscape'.
+ //
+ // Bugzilla Bug #224801 (a.k.a - Raidzilla Bug #56981)
+ // Bugzilla Bug #483519
+ //
+ String translation = null;
+ if( type.startsWith( "iplanet" ) ) {
+ translation = "netscape"
+ + type.substring( 7 );
+ type = translation;
+ } else if( type.startsWith( "com.iplanet" ) ) {
+ translation = "com.netscape"
+ + type.substring( 11 );
+ type = translation;
+ }
+
+ if (type.startsWith("com.netscape.certsrv.request.AgentApprovals")) {
+ com.netscape.certsrv.request.AgentApprovals obj =
+ (com.netscape.certsrv.request.AgentApprovals)table.get(name);
+ if (obj == null) {
+ obj = new com.netscape.certsrv.request.AgentApprovals();
+ table.put(name, obj);
+ }
+ obj.addApproval(value.substring(0,value.indexOf(';')));
+ } else if (type.startsWith("com.netscape.certsrv.base.ArgBlock")
+ || type.startsWith("com.netscape.cmscore.base.ArgBlock")) {
+ // CMS 6.1: created new "com.netscape.certsrv.base.IArgBlock" and
+ // moved old "com.netscape.certsrv.base.ArgBlock"
+ // to "com.netscape.cmscore.base.ArgBlock"
+ com.netscape.cmscore.base.ArgBlock obj =
+ (com.netscape.cmscore.base.ArgBlock)table.get(name);
+ if (obj == null) {
+ // CMS 6.1: created new "com.netscape.certsrv.base.IArgBlock" and
+ // moved old "com.netscape.certsrv.base.ArgBlock"
+ // to "com.netscape.cmscore.base.ArgBlock"
+ obj = new com.netscape.cmscore.base.ArgBlock();
+ table.put(name, obj);
+ }
+ String valuekey = value.substring(0, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ obj.set(valuekey, valuevalue);
+ } else if (type.startsWith("com.netscape.certsrv.authentication.AuthToken")) {
+ com.netscape.certsrv.authentication.AuthToken obj =
+ (com.netscape.certsrv.authentication.AuthToken)table.get(name);
+ if (obj == null) {
+ com.netscape.certsrv.authentication.IAuthManager mgr =
+ new DummyAuthManager();
+ obj = new com.netscape.certsrv.authentication.AuthToken(mgr);
+ table.put(name, obj);
+ }
+ String valuekey = value.substring(0, value.indexOf(':'));
+ String valuetype = value.substring(value.indexOf(':')+1, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ if (valuetype.equals("java.lang.String")) {
+ // Processes 'java.math.BigInteger[]':
+ //
+ // Bugzilla Bug #225031 (a.k.a - Raidzilla Bug #58356)
+ //
+ // Processes 'java.lang.String[]':
+ //
+ // Bugzilla Bug #224763 (a.k.a - Raidzilla Bug #57949)
+ // Bugzilla Bug #252240
+ //
+ obj.set(valuekey, valuevalue);
+ } else if (valuetype.equals("java.util.Date")) {
+ obj.set(valuekey, new Date(Long.parseLong(valuevalue)));
+ } else {
+ System.err.println("ERROR AuthToken type - " + attr);
+ System.exit(0);
+ }
+ } else if (type.startsWith("java.math.BigInteger[")) {
+ // Bugzilla Bug #238779
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ java.math.BigInteger objs[] = (java.math.BigInteger[])table.get(name);
+ if (objs == null) {
+ objs = new java.math.BigInteger[size];
+ table.put(name, objs);
+ }
+ objs[index] = new java.math.BigInteger(value);
+ } else if (type.startsWith("java.math.BigInteger")) {
+ table.put(name, new java.math.BigInteger(value));
+ } else if (type.startsWith("byte[]")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ table.put(name, decoder.decodeBuffer(value));
+ } else if (type.startsWith("byte[")) {
+ // byte array
+ BASE64Decoder decoder = new BASE64Decoder();
+ table.put(name, decoder.decodeBuffer(value));
+ } else if (type.startsWith("netscape.security.x509.CertificateAlgorithmId")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateAlgorithmId obj =
+ new netscape.security.x509.CertificateAlgorithmId(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateChain")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateChain obj =
+ new netscape.security.x509.CertificateChain();
+ ByteArrayInputStream bis = new ByteArrayInputStream(decoder.decodeBuffer(value));
+ obj.decode(bis);
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateExtensions")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateExtensions obj =
+ new netscape.security.x509.CertificateExtensions();
+ obj.decodeEx(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ // CMS 6.2: revised method of decoding objects of type
+ // "netscape.security.x509.CertificateExtensions"
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateSubjectName")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateSubjectName obj =
+ new netscape.security.x509.CertificateSubjectName(new DerInputStream(decoder.decodeBuffer(value)));
+ // CMS 6.2: revised method of decoding objects of type
+ // "netscape.security.x509.CertificateSubjectName"
+ table.put(name, obj);
+ } else if (type.startsWith("netscape.security.x509.CertificateValidity")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateValidity obj =
+ new netscape.security.x509.CertificateValidity();
+ ByteArrayInputStream bis = new ByteArrayInputStream(decoder.decodeBuffer(value));
+ obj.decode(bis);
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateX509Key")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateX509Key obj =
+ new netscape.security.x509.CertificateX509Key(
+ new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ table.put(name, obj);
+ } else if (type.startsWith("com.netscape.certsrv.cert.CertInfo")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.extensions.CertInfo objs[] = (netscape.security.extensions.CertInfo[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.extensions.CertInfo[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.extensions.CertInfo();
+ objs[index].decode(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ } else if (type.startsWith("java.util.Hashtable")) {
+ // Bugzilla Bug #224800 (a.k.a - Raidzilla Bug #56953)
+ java.util.Hashtable obj = (java.util.Hashtable)table.get(name);
+ if (obj == null) {
+ obj = new java.util.Hashtable();
+ table.put(name, obj);
+ }
+ BASE64Decoder decoder = new BASE64Decoder();
+ String valuekey = value.substring(0, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ obj.put(valuekey, decoder.decodeBuffer(valuevalue));
+ } else if (type.startsWith("Integer[")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ Integer objs[] = (Integer[])table.get(name);
+ if (objs == null) {
+ objs = new Integer[size];
+ table.put(name, objs);
+ }
+ objs[index] = new Integer(value);
+ } else if (type.startsWith("java.lang.Integer")) {
+ table.put(name, new Integer(value));
+ } else if (type.startsWith("org.mozilla.jss.asn1.INTEGER")) {
+ // CMS 7.1 stores bodyPartId as INTEGER
+ // CS 72. fixed the problem by storing it as String
+ table.put(name, value);
+ } else if (type.startsWith("com.netscape.certsrv.dbs.keydb.KeyRecord")
+ || type.startsWith("com.netscape.cmscore.dbs.KeyRecord")) {
+ com.netscape.cmscore.dbs.KeyRecord obj =
+ (com.netscape.cmscore.dbs.KeyRecord)table.get(name);
+ if (obj == null) {
+ obj = new com.netscape.cmscore.dbs.KeyRecord();
+ table.put(name, obj);
+ }
+ String valuekey = value.substring(0, value.indexOf(':'));
+ String valuetype = value.substring(value.indexOf(':')+1, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ if (valuetype.equals("java.lang.String")) {
+ obj.set(valuekey, valuevalue);
+ } else if (valuetype.equals("java.util.Date")) {
+ obj.set(valuekey, new Date(Long.parseLong(valuevalue)));
+ } else if (valuetype.equals("java.math.BigInteger")) {
+ obj.set(valuekey, new java.math.BigInteger(valuevalue));
+ } else if (valuetype.equals("java.lang.Integer")) {
+ obj.set(valuekey, new Integer(valuevalue));
+ } else if (valuetype.equals("com.netscape.certsrv.dbs.keydb.KeyState")) {
+ obj.set(valuekey, com.netscape.certsrv.dbs.keydb.KeyState.toKeyState(valuevalue));
+ } else if (valuetype.equals("[B")) {
+ // byte array
+
+ BASE64Decoder decoder = new BASE64Decoder();
+ obj.set(valuekey, decoder.decodeBuffer(valuevalue));
+ } else {
+ System.err.println("ERROR KeyRecord type - " + attr);
+ System.exit(0);
+ }
+ } else if (type.startsWith("java.util.Locale")) {
+ // CMS 6.2: begin checking for new type
+ // "java.util.Locale"
+ table.put(name, Locale.getDefault());
+ } else if (type.startsWith("com.netscape.certsrv.kra.ProofOfArchival")
+ || type.startsWith("com.netscape.cmscore.kra.ProofOfArchival")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(decoder.decodeBuffer(value));
+ com.netscape.certsrv.kra.ProofOfArchival obj =
+ buildPOA(decoder.decodeBuffer(value));
+ table.put(name, obj);
+ } else if (type.startsWith("netscape.security.x509.RevokedCertImpl")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.x509.RevokedCertImpl objs[] = (netscape.security.x509.RevokedCertImpl[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.x509.RevokedCertImpl[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.x509.RevokedCertImpl(decoder.decodeBuffer(value));
+ } else if (type.startsWith("java.lang.String[")) {
+ // Bugzilla Bug #223360 (a.k.a - Raidzilla Bug #58086)
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ java.lang.String objs[] = (java.lang.String[])table.get(name);
+ if (objs == null) {
+ objs = new java.lang.String[size];
+ table.put(name, objs);
+ }
+ objs[index] = new java.lang.String(value);
+ } else if (type.startsWith("java.lang.String")) {
+ table.put(name, value);
+ } else if (type.startsWith("java.util.Vector")) {
+ Vector obj =
+ (Vector)table.get(name);
+ if (obj == null) {
+ obj = new Vector();
+ table.put(name, obj);
+ }
+ obj.addElement(value);
+ } else if (type.startsWith("netscape.security.x509.X509CertImpl[")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.x509.X509CertImpl objs[] = (netscape.security.x509.X509CertImpl[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.x509.X509CertImpl[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.x509.X509CertImpl(decoder.decodeBuffer(value));
+ } else if (type.equals("netscape.security.x509.X509CertImpl")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.X509CertImpl obj =
+ new netscape.security.x509.X509CertImpl(
+ decoder.decodeBuffer(value));
+ table.put(name, obj);
+ } else if (type.startsWith("netscape.security.x509.X509CertInfo[")
+ || type.startsWith("netscape.security.extensions.CertInfo[")) {
+ // CMS 6.2: begin checking for additional new type
+ // "netscape.security.extensions.CertInfo["
+ //
+ // CMS 6.1: "netscape.security.x509.X509CertInfo"
+ // now always utilizes arrays such as
+ // "netscape.security.x509.X509CertInfo["
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.x509.X509CertInfo objs[] = (netscape.security.x509.X509CertInfo[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.x509.X509CertInfo[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.x509.X509CertInfo();
+ objs[index].decode(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ } else if (type.equals("netscape.security.x509.X509CertInfo")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.X509CertInfo obj =
+ new netscape.security.x509.X509CertInfo(
+ decoder.decodeBuffer(value));
+ table.put(name, obj);
+ } else if( type.endsWith( "Exception" ) ) {
+ Class[] argClass = { String.class }; // the argument's class
+ Object[] argValue = { value }; // the argument's value
+
+ Class x = Class.forName( type );
+ Constructor ctr = x.getConstructor( argClass );
+ Exception e = ( Exception ) ctr.newInstance( argValue );
+ } else {
+ System.err.println("ERROR type - " + type + " - "+ attr);
+ System.exit(0);
+ }
+ }
+
+ public com.netscape.certsrv.kra.ProofOfArchival buildPOA(byte data[])
+ throws Exception
+ {
+ DerInputStream dis = new DerInputStream(data);
+ DerValue seq[] = dis.getSequence(0);
+
+ BigInteger mSerialNo = seq[0].getInteger().toBigInteger();
+
+ // subject
+ DerValue subject = seq[1];
+ netscape.security.x509.X500Name mSubject =
+ new netscape.security.x509.X500Name(subject.toByteArray());
+
+ // issuer
+ DerValue issuer = seq[2];
+ netscape.security.x509.X500Name mIssuer =
+ new netscape.security.x509.X500Name(issuer.toByteArray());
+
+ // date of archival
+ DerInputStream dateOfArchival = new DerInputStream(seq[3].toByteArray());
+ Date mDateOfArchival = dateOfArchival.getUTCTime();
+ com.netscape.certsrv.kra.ProofOfArchival obj =
+ new com.netscape.certsrv.kra.ProofOfArchival(mSerialNo,
+ mSubject.toString(), mIssuer.toString(), mDateOfArchival);
+ return obj;
+ }
+}
+
+class DummyAuthManager implements com.netscape.certsrv.authentication.IAuthManager
+{
+ public String getName()
+ {
+ return "dummy";
+ }
+
+ public String getImplName()
+ {
+ return "dummy";
+ }
+
+ public IAuthToken authenticate(IAuthCredentials authCred)
+ throws EMissingCredential, EInvalidCredentials, EBaseException
+ {
+ return null;
+ }
+
+ /**
+ * 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
+ {
+ }
+
+ public void shutdown()
+ {
+ }
+
+ public String[] getRequiredCreds()
+ {
+ return null;
+ }
+
+ /**
+ * 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.
+ *
+ * @param implName The authentication manager plugin name.
+ * @exception EBaseException If an internal error occurred
+ */
+ public String[] getConfigParams()
+ throws EBaseException
+ {
+ return null;
+ }
+
+ /**
+ * Get the configuration store for this authentication manager.
+ * @return The configuration store of this authentication manager.
+ */
+ public IConfigStore getConfigStore()
+ {
+ return null;
+ }
+}
+
diff --git a/base/migrate/TxtTo72/src/compile.bat b/base/migrate/TxtTo72/src/compile.bat
new file mode 100755
index 000000000..2c50e988e
--- /dev/null
+++ b/base/migrate/TxtTo72/src/compile.bat
@@ -0,0 +1,152 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script creates the "TxtTo72/classes/Main.class",
+REM "TxtTo72/classes/CMS72LdifParser.class", and
+REM "TxtTo72/classes/DummyAuthManager.class" which are
+REM used to create a CS 7.2 ldif data file.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM Set SERVER_ROOT - identify the CS <server_root> used to compile TxtTo72
+REM
+
+REM SET SERVER_ROOT=C:\cs72
+
+
+REM
+REM Set JDK_VERSION - specify the JDK version used by this version of CS
+REM
+REM CS 7.2 NOTE: "WINNT" - 1.4.2
+REM
+
+REM SET JDK_VERSION=CS_7.2
+
+
+REM
+REM Set JAVA_HOME - specify the complete path to the JDK
+REM
+REM example: \\bermuda.redhat.com\sbc mounted as Y:
+REM
+
+REM SET JAVA_HOME=Y:\cms_jdk\WINNT\%JDK_VERSION%
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CS="CS 7.2"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0"
+ECHO.
+ECHO NOTE: No arguments are required to build the
+ECHO %CS% ldif data classes.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%JAVA_HOME%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and JAVA_HOME
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_JAVA_HOME
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified JAVA_HOME exists
+REM
+
+:CHECK_JAVA_HOME
+IF EXIST %JAVA_HOME% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified JAVA_HOME does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%JAVA_HOME%\bin;%JAVA_HOME%\lib;%PATH%
+
+
+REM
+REM Set TARGET - identify the complete path to the new classes target directory
+REM
+
+SET TARGET=..\classes
+
+
+REM
+REM Create the new classes target directory (if it does not already exist)
+REM
+
+IF EXIST %TARGET% goto COMPILE_CLASSES
+MKDIR %TARGET%
+
+
+REM
+REM Compile TxtTo72 - create "CMS72LdifParser.class", "DummyAuthManager.class",
+REM and "Main.class"
+REM
+
+:COMPILE_CLASSES
+%JAVA_HOME%\bin\javac.exe -d %TARGET% -classpath %JAVA_HOME%\jre\lib\rt.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar Main.java
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/TxtTo72/src/compile.sh b/base/migrate/TxtTo72/src/compile.sh
new file mode 100755
index 000000000..ec0b466ba
--- /dev/null
+++ b/base/migrate/TxtTo72/src/compile.sh
@@ -0,0 +1,141 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#####################################################################
+### ###
+### This script creates the "TxtTo72/classes/Main.class", ###
+### "TxtTo72/classes/CMS72LdifParser.class", and ###
+### "TxtTo72/classes/DummyAuthManager.class" which are ###
+### used to create a CS 7.2 ldif data file. ###
+### ###
+#####################################################################
+
+
+###
+### Set JDK_PLATFORM - must be "HP-UX", "Linux", or "SunOS"
+###
+
+#JDK_PLATFORM=Linux
+#export JDK_PLATFORM
+
+
+###
+### Set JDK_VERSION - specify the JDK version used by this version of CS
+###
+### CS 7.2 NOTE: "Linux" - 1.5.0 (IBM)
+### "SunOS" - 1.5.0
+###
+
+#JDK_VERSION=CS_7.2.0
+#export JDK_VERSION
+
+
+###
+### Set JAVA_HOME - specify the complete path to the JDK
+###
+
+#JAVA_HOME=/share/builds/components/cms_jdk/${JDK_PLATFORM}/${JDK_VERSION}
+#export JAVA_HOME
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CS="CS 7.2"
+export CS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -gt 0 ] ; then
+ echo
+ echo "Usage: $0"
+ echo
+ echo " NOTE: No arguments are required to build the"
+ echo " ${CS} ldif data classes."
+ echo
+ exit 1
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${JAVA_HOME}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and JAVA_HOME "
+ echo " environment variables for this script!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified JAVA_HOME exists and is a directory
+###
+
+if [ ! -d "${JAVA_HOME}" ] ; then
+ echo "ERROR: Either the specified JAVA_HOME does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 4
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=/usr/lib:/usr/lib/dirsec:${JAVA_HOME}/lib:${JAVA_HOME}/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=/usr/lib:/usr/lib/dirsec:${JAVA_HOME}/lib:${JAVA_HOME}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=/usr/lib:/usr/lib/dirsec:${JAVA_HOME}/lib:${JAVA_HOME}/lib/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Set TARGET - identify the complete path to the new classes target directory
+###
+
+TARGET=../classes
+export TARGET
+
+
+###
+### Create the new classes target directory (if it does not already exist)
+###
+
+if [ ! -d ${TARGET} ]; then
+ mkdir -p ${TARGET}
+fi
+
+
+###
+### Compile TxtTo72 - create "CMS72LdifParser.class", "DummyAuthManager.class",
+### and "Main.class"
+###
+
+${JAVA_HOME}/bin/javac -d ${TARGET} -classpath ${JAVA_HOME}/jre/lib/rt.jar:/usr/share/java/rhpki/nsutil.jar:/usr/share/java/rhpki/certsrv.jar:/usr/share/java/rhpki/cmscore.jar:/usr/lib/java/rhpki/ca/ca.jar:/usr/lib/java/rhpki/tks/tks.jar:/usr/lib/java/rhpki/ocsp/ocsp.jar:/usr/lib/java/rhpki/kra/kra.jar:/usr/lib/java/dirsec/jss4.jar Main.java
+
diff --git a/base/migrate/TxtTo73/classes/CMS73LdifParser.class b/base/migrate/TxtTo73/classes/CMS73LdifParser.class
new file mode 100644
index 000000000..03a09612d
--- /dev/null
+++ b/base/migrate/TxtTo73/classes/CMS73LdifParser.class
Binary files differ
diff --git a/base/migrate/TxtTo73/classes/DummyAuthManager.class b/base/migrate/TxtTo73/classes/DummyAuthManager.class
new file mode 100644
index 000000000..323081a39
--- /dev/null
+++ b/base/migrate/TxtTo73/classes/DummyAuthManager.class
Binary files differ
diff --git a/base/migrate/TxtTo73/classes/Main.class b/base/migrate/TxtTo73/classes/Main.class
new file mode 100644
index 000000000..6609674ae
--- /dev/null
+++ b/base/migrate/TxtTo73/classes/Main.class
Binary files differ
diff --git a/base/migrate/TxtTo73/run.bat b/base/migrate/TxtTo73/run.bat
new file mode 100755
index 000000000..9e3898a47
--- /dev/null
+++ b/base/migrate/TxtTo73/run.bat
@@ -0,0 +1,186 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM This program is free software; you can redistribute it and/or modify
+REM it under the terms of the GNU General Public License as published by
+REM the Free Software Foundation; version 2 of the License.
+REM
+REM This program is distributed in the hope that it will be useful,
+REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+REM GNU General Public License for more details.
+REM
+REM You should have received a copy of the GNU General Public License along
+REM with this program; if not, write to the Free Software Foundation, Inc.,
+REM 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script converts a normalized <Source CS Version> ldif
+REM text file (e. g. - created via a <Source CS Version>ToTxt
+REM script) into a CS 7.3 ldif data file.
+REM
+REM This CS 7.3 ldif data file can then be imported into the
+REM internal database of the desired CS 7.3 server using a
+REM utility such as ldif2db.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM SERVER_ROOT - fully qualified path of the location of the server
+REM
+
+REM SET SERVER_ROOT=C:\cs73
+
+
+REM
+REM INSTANCE - if the CS instance directory is called 'cert-ca',
+REM set the CS instance to 'ca'
+REM
+REM NOTE: When a single SERVER_ROOT contains more than
+REM one CS instance, this script must be run multiple
+REM times. To do this, there is only a need to change
+REM the INSTANCE parameter.
+REM
+
+REM SET INSTANCE=ca
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CS="CS 7.3"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO USAGE
+IF "%3" == "" GOTO CHECK_INPUT_FILE
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0 input [errors] > output"
+ECHO.
+ECHO where: input - the specified %CS% ldif data file,
+ECHO errors - an optional errors file containing
+ECHO skipped attributes, and
+ECHO output - the normalized %CS% ldif text file.
+ECHO.
+ECHO NOTE: If no redirection is provided to
+ECHO 'output', then the normalized
+ECHO %CS% ldif text will merely
+ECHO be echoed to stdout.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified "input" file exists
+REM
+
+:CHECK_INPUT_FILE
+IF EXIST %1 GOTO CHECK_ERRORS_FILE
+
+
+ECHO ERROR: The specified input file, %1, does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM If an "errors" file is specified, then check that it does not already
+REM exist.
+REM
+
+:CHECK_ERRORS_FILE
+IF "%2" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+IF EXIST %2 GOTO ERRORS_FILE_ERROR
+GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:ERRORS_FILE_ERROR
+ECHO ERROR: The specified errors file, %2, already exists!
+ECHO Please specify a different file!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%INSTANCE%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and INSTANCE
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_INSTANCE
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified INSTANCE exists
+REM
+
+:CHECK_INSTANCE
+IF EXIST %SERVER_ROOT%\cert-%INSTANCE% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified INSTANCE does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%SERVER_ROOT%\bin\cert\jre\bin;%SERVER_ROOT\bin\cert\jre\bin\server;%PATH%
+
+
+REM
+REM Convert the specified %CS% ldif data file
+REM into a normalized %CS% ldif text file.
+REM
+
+%SERVER_ROOT%\bin\cert\jre\bin\java.exe -classpath .\classes;%SERVER_ROOT%\cert-%INSTANCE%\classes;%SERVER_ROOT%\bin\cert\classes;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar;%SERVER_ROOT%\bin\cert\jre\lib\rt.jar Main %1 %2
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/TxtTo73/run.sh b/base/migrate/TxtTo73/run.sh
new file mode 100755
index 000000000..52469acca
--- /dev/null
+++ b/base/migrate/TxtTo73/run.sh
@@ -0,0 +1,152 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+
+#####################################################################
+### ###
+### This script converts a normalized <Source CS Version> ldif ###
+### text file (e. g. - created via a <Source CS Version>ToTxt ###
+### script) into a CS 7.3 ldif data file. ###
+### ###
+### This CS 7.3 ldif data file can then be imported into ###
+### the internal database of the desired CS 7.3 server ###
+### using a utility such as ldif2db. ###
+### ###
+#####################################################################
+
+###
+### Java Runtime Environment
+###
+JRE_ROOT=/usr/lib/jvm/jre-1.5.0
+export JRE_ROOT
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CS="CS 7.3"
+export CS
+
+OS_NAME=`uname`
+export OS_NAME
+
+ARCH=`uname -i`
+export ARCH
+
+
+##
+## Perform a usage check for the appropriate number of arguments:
+##
+
+if [ $# -lt 1 -o $# -gt 2 ] ; then
+ echo
+ echo "Usage: $0 input [errors] > output"
+ echo
+ echo " where: input - the specified ${CS} ldif data file,"
+ echo " errors - an optional errors file containing"
+ echo " skipped attributes, and"
+ echo " output - the normalized ${CS} ldif text file."
+ echo
+ echo " NOTE: If no redirection is provided to"
+ echo " 'output', then the normalized"
+ echo " ${CS} ldif text will merely"
+ echo " be echoed to stdout."
+ echo
+ exit 1
+fi
+
+
+###
+### Check that the specified "input" file exists and is a regular file.
+###
+
+if [ ! -f $1 ] ; then
+ echo "ERROR: Either the specified 'input' file, '$1', does not exist, "
+ echo " or it is not a regular file!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified "input" file exists and is not empty.
+###
+
+if [ ! -s $1 ] ; then
+ echo "ERROR: The specified 'input' file, '$1', is empty!"
+ echo
+ exit 3
+fi
+
+
+###
+### If an "errors" file is specified, then check that it does not already
+### exist.
+###
+
+if [ $# -eq 2 ] ; then
+ if [ -f $2 ] ; then
+ echo "ERROR: The specified 'errors' file, '$2', already exists!"
+ echo " Please specify a different file!"
+ echo
+ exit 4
+ fi
+fi
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+### NOTE: As of SunOS JDK 1.4.0, the required "Unicode" classes
+### have been moved from "i18n.jar" to "rt.jar".
+###
+
+CLASSPATH=/usr/share/rhpki/migrate/TxtTo73/classes:/usr/share/java/rhpki/certsrv.jar:/usr/share/java/rhpki/cmscore.jar:/usr/share/java/rhpki/nsutil.jar:/usr/lib/java/dirsec/jss4.jar:${JRE_ROOT}/lib/rt.jar
+export CLASSPATH
+
+if [ ${OS_NAME} = "Linux" ] ; then
+ if [ ${ARCH} = "i386" ] ; then
+ LD_LIBRARY_PATH=/usr/lib/dirsec:/usr/lib:${JRE_ROOT}/lib:${JRE_ROOT}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+ else # x86_64
+ LD_LIBRARY_PATH=/usr/lib64/dirsec:/usr/lib64:${JRE_ROOT}/lib:${JRE_ROOT}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+ CLASSPATH=/usr/share/rhpki/migrate/TxtTo73/classes:/usr/share/java/rhpki/certsrv.jar:/usr/share/java/rhpki/cmscore.jar:/usr/share/java/rhpki/nsutil.jar:/usr/lib64/java/dirsec/jss4.jar:${JRE_ROOT}/lib/rt.jar
+ export CLASSPATH
+ fi
+else # SunOS 64-bits
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/dirsec:/usr/lib/sparcv9:${JRE_ROOT}/lib:${JRE_ROOT}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+ CLASSPATH=/usr/share/rhpki/migrate/TxtTo73/classes:/usr/share/java/rhpki/certsrv.jar:/usr/share/java/rhpki/cmscore.jar:/usr/share/java/rhpki/nsutil.jar:/usr/lib/sparcv9/java/dirsec/jss4.jar:${JRE_ROOT}/lib/rt.jar
+ export CLASSPATH
+fi
+
+
+###
+### Convert the specified ${CS} ldif data file
+### into a normalized ${CS} ldif text file.
+###
+
+${JRE_ROOT}/bin/java -classpath ${CLASSPATH} Main $1 $2
diff --git a/base/migrate/TxtTo73/src/Main.java b/base/migrate/TxtTo73/src/Main.java
new file mode 100644
index 000000000..4ffe0c120
--- /dev/null
+++ b/base/migrate/TxtTo73/src/Main.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 ---
+//
+// "TxtTo71/src/Main.java" is based upon a copy "TxtTo70/src/Main.java".
+//
+// Always comment any new code sections with a "CMS 7.1" header, and
+// apply these changes forward to all other "TxtTo*/src/Main.java" files
+// (including this comment header) so that these differences will only
+// appear when this file is diffed against an earlier "TxtTo*" version.
+//
+// This file should always be maintained by executing the following command:
+//
+// diff TxtTo70/src/Main.java TxtTo71/src/Main.java
+//
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import sun.misc.*;
+import org.mozilla.jss.*; // CMS 4.5 and later
+import org.mozilla.jss.crypto.*; // CMS 4.5 and later
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import netscape.security.util.*;
+import java.lang.reflect.*;
+
+public class Main
+{
+ public static void main(String args[])
+ {
+ try {
+ // initialize CryptoManager in CMS 4.5 and later
+ CryptoManager.initialize(".");
+ // load JSS provider in CMS 4.5 and later
+ java.security.Security.removeProvider("SUN version 1.2");
+ // The following call to "java.security.Security.insertProviderAt()"
+ // is no longer commented out in CMS 4.5 and later
+ java.security.Security.insertProviderAt(
+ new netscape.security.provider.CMS(), 0);
+ java.security.Provider ps[] =
+ java.security.Security.getProviders();
+ if (ps == null || ps.length <= 0) {
+ System.err.println("Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ System.err.println("Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+
+ // Parse the File
+ CMS73LdifParser parser = null;
+ if (args.length == 1) {
+ parser = new CMS73LdifParser(args[0]);
+ } else if (args.length == 2) {
+ parser = new CMS73LdifParser(args[0], args[1]);
+ } else {
+ throw new IOException("Invalid Parameters");
+ }
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+}
+
+class CMS73LdifParser
+{
+ // constants
+ private static final String DN =
+ "dn:";
+ // Directory Servers in CMS 4.7 and later use "requestAttributes"
+ private static final String REQUEST_ATTRIBUTES =
+ "requestAttributes::";
+ private static final String BEGIN =
+ "--- BEGIN ATTRIBUTES ---";
+ private static final String END =
+ "--- END ATTRIBUTES ---";
+
+ // variables
+ private String mFilename = null;
+ private String mErrorFilename = null;
+ private PrintWriter mErrorPrintWriter = null;
+
+ public CMS73LdifParser(String filename)
+ {
+ mFilename = filename;
+ }
+
+ public CMS73LdifParser(String filename, String errorFilename)
+ {
+ mFilename = filename;
+ mErrorFilename = errorFilename;
+ }
+
+ public void parse() throws Exception
+ {
+ if (mErrorFilename != null) {
+ mErrorPrintWriter = new PrintWriter(new FileOutputStream(mErrorFilename));
+ }
+ BufferedReader reader = new BufferedReader(
+ new FileReader(mFilename));
+ String line = null;
+ String dn = null;
+ Vector requestAttributes = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DN)) {
+ dn = line;
+ }
+ if (line.equals(BEGIN)) {
+ requestAttributes = new Vector();
+ continue;
+ }
+ if (requestAttributes == null) {
+ System.out.println(line);
+ continue;
+ }
+ if (line.equals(END)) {
+ parseAttributes(dn, requestAttributes);
+ requestAttributes = null;
+ continue;
+ }
+ if (line.startsWith(" ")) { // begining of attr
+ requestAttributes.addElement(
+ line.substring(1, line.length()));
+ } else {
+ requestAttributes.setElementAt(
+ (String)
+ requestAttributes.lastElement() +
+ "\n" +
+ line,
+ requestAttributes.size() - 1);
+ }
+ }
+ }
+
+ private byte[] encode(Object value) throws Exception
+ {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(bos);
+
+ os.writeObject(value);
+ os.close();
+ return bos.toByteArray();
+ }
+
+ public void parseAttributes(String dn, Vector attrs) throws Exception
+ {
+ Hashtable hashtable = new Hashtable();
+ for (int i = 0; i < attrs.size(); i++) {
+ String attr = (String)attrs.elementAt(i);
+ buildHashtable(dn, hashtable, attr);
+ }
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(bos);
+ Enumeration e = hashtable.keys();
+ while (e.hasMoreElements()) {
+ String key = (String)e.nextElement();
+ Object value = hashtable.get(key);
+
+ try {
+ byte data[] = null;
+ data = encode(value);
+ os.writeObject(key);
+ os.writeObject(data);
+ } catch (Exception ex) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + key);
+ }
+ }
+ } // while
+ os.writeObject(null);
+ os.close();
+
+ // print the BASE64 encoding of the Hashtable
+ BASE64Encoder encoder = new BASE64Encoder();
+ String attrsStr = encoder.encodeBuffer(bos.toByteArray());
+ // trim the last "\n"
+ StringBuffer buffer = null;
+ attrsStr = attrsStr.trim();
+ StringTokenizer st = new StringTokenizer(attrsStr, "\r\n");
+ while (st.hasMoreTokens()) {
+ if (buffer == null) {
+ buffer = new StringBuffer();
+ buffer.append(st.nextToken());
+ } else {
+ buffer.append("\r\n " + st.nextToken());
+ }
+ }
+
+ System.out.println(REQUEST_ATTRIBUTES + " " + buffer);
+ }
+
+ public void buildHashtable(String dn, Hashtable table, String attr)
+ throws Exception
+ {
+ // attribute format [name]:[type]=[value]
+
+ int colon = attr.indexOf(':');
+ if (colon == -1) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+ int equal = attr.indexOf('=');
+ if (equal == -1) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+ String name = null;
+ String type = null;
+ String value = null;
+ try {
+ name = attr.substring(0, colon);
+ type = attr.substring(colon+1, equal);
+ value = attr.substring(equal+1);
+ } catch (Exception e) {
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+
+ if (name.startsWith("serviceErrors")) {
+ // #56953 - skip serviceErrors
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+ if (name.startsWith("Error")) {
+ // #56953 - skip serviceErrors
+ if (mErrorPrintWriter != null) {
+ if (dn != null) {
+ mErrorPrintWriter.println(dn);
+ }
+ mErrorPrintWriter.println("Skipped " + attr);
+ }
+ return;
+ }
+
+ // To account for '47ToTxt' data files that have previously
+ // been generated, ALWAYS convert 'iplanet' to 'netscape'.
+ //
+ // Bugzilla Bug #224801 (a.k.a - Raidzilla Bug #56981)
+ // Bugzilla Bug #483519
+ //
+ String translation = null;
+ if( type.startsWith( "iplanet" ) ) {
+ translation = "netscape"
+ + type.substring( 7 );
+ type = translation;
+ } else if( type.startsWith( "com.iplanet" ) ) {
+ translation = "com.netscape"
+ + type.substring( 11 );
+ type = translation;
+ }
+
+ if (type.startsWith("com.netscape.certsrv.request.AgentApprovals")) {
+ com.netscape.certsrv.request.AgentApprovals obj =
+ (com.netscape.certsrv.request.AgentApprovals)table.get(name);
+ if (obj == null) {
+ obj = new com.netscape.certsrv.request.AgentApprovals();
+ table.put(name, obj);
+ }
+ obj.addApproval(value.substring(0,value.indexOf(';')));
+ } else if (type.startsWith("com.netscape.certsrv.base.ArgBlock")
+ || type.startsWith("com.netscape.cmscore.base.ArgBlock")) {
+ // CMS 6.1: created new "com.netscape.certsrv.base.IArgBlock" and
+ // moved old "com.netscape.certsrv.base.ArgBlock"
+ // to "com.netscape.cmscore.base.ArgBlock"
+ com.netscape.cmscore.base.ArgBlock obj =
+ (com.netscape.cmscore.base.ArgBlock)table.get(name);
+ if (obj == null) {
+ // CMS 6.1: created new "com.netscape.certsrv.base.IArgBlock" and
+ // moved old "com.netscape.certsrv.base.ArgBlock"
+ // to "com.netscape.cmscore.base.ArgBlock"
+ obj = new com.netscape.cmscore.base.ArgBlock();
+ table.put(name, obj);
+ }
+ String valuekey = value.substring(0, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ obj.set(valuekey, valuevalue);
+ } else if (type.startsWith("com.netscape.certsrv.authentication.AuthToken")) {
+ com.netscape.certsrv.authentication.AuthToken obj =
+ (com.netscape.certsrv.authentication.AuthToken)table.get(name);
+ if (obj == null) {
+ com.netscape.certsrv.authentication.IAuthManager mgr =
+ new DummyAuthManager();
+ obj = new com.netscape.certsrv.authentication.AuthToken(mgr);
+ table.put(name, obj);
+ }
+ String valuekey = value.substring(0, value.indexOf(':'));
+ String valuetype = value.substring(value.indexOf(':')+1, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ if (valuetype.equals("java.lang.String")) {
+ // Processes 'java.math.BigInteger[]':
+ //
+ // Bugzilla Bug #225031 (a.k.a - Raidzilla Bug #58356)
+ //
+ // Processes 'java.lang.String[]':
+ //
+ // Bugzilla Bug #224763 (a.k.a - Raidzilla Bug #57949)
+ // Bugzilla Bug #252240
+ //
+ obj.set(valuekey, valuevalue);
+ } else if (valuetype.equals("java.util.Date")) {
+ obj.set(valuekey, new Date(Long.parseLong(valuevalue)));
+ } else {
+ System.err.println("ERROR AuthToken type - " + attr);
+ System.exit(0);
+ }
+ } else if (type.startsWith("java.math.BigInteger[")) {
+ // Bugzilla Bug #238779
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ java.math.BigInteger objs[] = (java.math.BigInteger[])table.get(name);
+ if (objs == null) {
+ objs = new java.math.BigInteger[size];
+ table.put(name, objs);
+ }
+ objs[index] = new java.math.BigInteger(value);
+ } else if (type.startsWith("java.math.BigInteger")) {
+ table.put(name, new java.math.BigInteger(value));
+ } else if (type.startsWith("byte[]")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ table.put(name, decoder.decodeBuffer(value));
+ } else if (type.startsWith("byte[")) {
+ // byte array
+ BASE64Decoder decoder = new BASE64Decoder();
+ table.put(name, decoder.decodeBuffer(value));
+ } else if (type.startsWith("netscape.security.x509.CertificateAlgorithmId")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateAlgorithmId obj =
+ new netscape.security.x509.CertificateAlgorithmId(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateChain")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateChain obj =
+ new netscape.security.x509.CertificateChain();
+ ByteArrayInputStream bis = new ByteArrayInputStream(decoder.decodeBuffer(value));
+ obj.decode(bis);
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateExtensions")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateExtensions obj =
+ new netscape.security.x509.CertificateExtensions();
+ obj.decodeEx(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ // CMS 6.2: revised method of decoding objects of type
+ // "netscape.security.x509.CertificateExtensions"
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateSubjectName")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateSubjectName obj =
+ new netscape.security.x509.CertificateSubjectName(new DerInputStream(decoder.decodeBuffer(value)));
+ // CMS 6.2: revised method of decoding objects of type
+ // "netscape.security.x509.CertificateSubjectName"
+ table.put(name, obj);
+ } else if (type.startsWith("netscape.security.x509.CertificateValidity")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateValidity obj =
+ new netscape.security.x509.CertificateValidity();
+ ByteArrayInputStream bis = new ByteArrayInputStream(decoder.decodeBuffer(value));
+ obj.decode(bis);
+ table.put(name, obj);
+ } else if (type.equals("netscape.security.x509.CertificateX509Key")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.CertificateX509Key obj =
+ new netscape.security.x509.CertificateX509Key(
+ new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ table.put(name, obj);
+ } else if (type.startsWith("com.netscape.certsrv.cert.CertInfo")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.extensions.CertInfo objs[] = (netscape.security.extensions.CertInfo[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.extensions.CertInfo[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.extensions.CertInfo();
+ objs[index].decode(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ } else if (type.startsWith("java.util.Hashtable")) {
+ // Bugzilla Bug #224800 (a.k.a - Raidzilla Bug #56953)
+ java.util.Hashtable obj = (java.util.Hashtable)table.get(name);
+ if (obj == null) {
+ obj = new java.util.Hashtable();
+ table.put(name, obj);
+ }
+ BASE64Decoder decoder = new BASE64Decoder();
+ String valuekey = value.substring(0, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ obj.put(valuekey, decoder.decodeBuffer(valuevalue));
+ } else if (type.startsWith("Integer[")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ Integer objs[] = (Integer[])table.get(name);
+ if (objs == null) {
+ objs = new Integer[size];
+ table.put(name, objs);
+ }
+ objs[index] = new Integer(value);
+ } else if (type.startsWith("java.lang.Integer")) {
+ table.put(name, new Integer(value));
+ } else if (type.startsWith("org.mozilla.jss.asn1.INTEGER")) {
+ // CMS 7.1 stores bodyPartId as INTEGER
+ // CS 72. fixed the problem by storing it as String
+ table.put(name, value);
+ } else if (type.startsWith("com.netscape.certsrv.dbs.keydb.KeyRecord")
+ || type.startsWith("com.netscape.cmscore.dbs.KeyRecord")) {
+ com.netscape.cmscore.dbs.KeyRecord obj =
+ (com.netscape.cmscore.dbs.KeyRecord)table.get(name);
+ if (obj == null) {
+ obj = new com.netscape.cmscore.dbs.KeyRecord();
+ table.put(name, obj);
+ }
+ String valuekey = value.substring(0, value.indexOf(':'));
+ String valuetype = value.substring(value.indexOf(':')+1, value.indexOf('='));
+ String valuevalue = value.substring(value.indexOf('=')+1);
+ if (valuetype.equals("java.lang.String")) {
+ obj.set(valuekey, valuevalue);
+ } else if (valuetype.equals("java.util.Date")) {
+ obj.set(valuekey, new Date(Long.parseLong(valuevalue)));
+ } else if (valuetype.equals("java.math.BigInteger")) {
+ obj.set(valuekey, new java.math.BigInteger(valuevalue));
+ } else if (valuetype.equals("java.lang.Integer")) {
+ obj.set(valuekey, new Integer(valuevalue));
+ } else if (valuetype.equals("com.netscape.certsrv.dbs.keydb.KeyState")) {
+ obj.set(valuekey, com.netscape.certsrv.dbs.keydb.KeyState.toKeyState(valuevalue));
+ } else if (valuetype.equals("[B")) {
+ // byte array
+
+ BASE64Decoder decoder = new BASE64Decoder();
+ obj.set(valuekey, decoder.decodeBuffer(valuevalue));
+ } else {
+ System.err.println("ERROR KeyRecord type - " + attr);
+ System.exit(0);
+ }
+ } else if (type.startsWith("java.util.Locale")) {
+ // CMS 6.2: begin checking for new type
+ // "java.util.Locale"
+ table.put(name, Locale.getDefault());
+ } else if (type.startsWith("com.netscape.certsrv.kra.ProofOfArchival")
+ || type.startsWith("com.netscape.cmscore.kra.ProofOfArchival")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(decoder.decodeBuffer(value));
+ com.netscape.certsrv.kra.ProofOfArchival obj =
+ buildPOA(decoder.decodeBuffer(value));
+ table.put(name, obj);
+ } else if (type.startsWith("netscape.security.x509.RevokedCertImpl")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.x509.RevokedCertImpl objs[] = (netscape.security.x509.RevokedCertImpl[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.x509.RevokedCertImpl[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.x509.RevokedCertImpl(decoder.decodeBuffer(value));
+ } else if (type.startsWith("java.lang.String[")) {
+ // Bugzilla Bug #223360 (a.k.a - Raidzilla Bug #58086)
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ java.lang.String objs[] = (java.lang.String[])table.get(name);
+ if (objs == null) {
+ objs = new java.lang.String[size];
+ table.put(name, objs);
+ }
+ objs[index] = new java.lang.String(value);
+ } else if (type.startsWith("java.lang.String")) {
+ table.put(name, value);
+ } else if (type.startsWith("java.util.Vector")) {
+ Vector obj =
+ (Vector)table.get(name);
+ if (obj == null) {
+ obj = new Vector();
+ table.put(name, obj);
+ }
+ obj.addElement(value);
+ } else if (type.startsWith("netscape.security.x509.X509CertImpl[")) {
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.x509.X509CertImpl objs[] = (netscape.security.x509.X509CertImpl[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.x509.X509CertImpl[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.x509.X509CertImpl(decoder.decodeBuffer(value));
+ } else if (type.equals("netscape.security.x509.X509CertImpl")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.X509CertImpl obj =
+ new netscape.security.x509.X509CertImpl(
+ decoder.decodeBuffer(value));
+ table.put(name, obj);
+ } else if (type.startsWith("netscape.security.x509.X509CertInfo[")
+ || type.startsWith("netscape.security.extensions.CertInfo[")) {
+ // CMS 6.2: begin checking for additional new type
+ // "netscape.security.extensions.CertInfo["
+ //
+ // CMS 6.1: "netscape.security.x509.X509CertInfo"
+ // now always utilizes arrays such as
+ // "netscape.security.x509.X509CertInfo["
+ int size = Integer.parseInt(type.substring(type.indexOf('[')+ 1, type.indexOf(',')));
+ int index = Integer.parseInt(type.substring(type.indexOf(',')+1, type.indexOf(']')));
+ netscape.security.x509.X509CertInfo objs[] = (netscape.security.x509.X509CertInfo[])table.get(name);
+ BASE64Decoder decoder = new BASE64Decoder();
+ if (objs == null) {
+ objs = new netscape.security.x509.X509CertInfo[size];
+ table.put(name, objs);
+ }
+ objs[index] = new netscape.security.x509.X509CertInfo();
+ objs[index].decode(new ByteArrayInputStream(decoder.decodeBuffer(value)));
+ } else if (type.equals("netscape.security.x509.X509CertInfo")) {
+ BASE64Decoder decoder = new BASE64Decoder();
+ netscape.security.x509.X509CertInfo obj =
+ new netscape.security.x509.X509CertInfo(
+ decoder.decodeBuffer(value));
+ table.put(name, obj);
+ } else if( type.endsWith( "Exception" ) ) {
+ Class[] argClass = { String.class }; // the argument's class
+ Object[] argValue = { value }; // the argument's value
+
+ Class x = Class.forName( type );
+ Constructor ctr = x.getConstructor( argClass );
+ Exception e = ( Exception ) ctr.newInstance( argValue );
+ } else {
+ System.err.println("ERROR type - " + type + " - "+ attr);
+ System.exit(0);
+ }
+ }
+
+ public com.netscape.certsrv.kra.ProofOfArchival buildPOA(byte data[])
+ throws Exception
+ {
+ DerInputStream dis = new DerInputStream(data);
+ DerValue seq[] = dis.getSequence(0);
+
+ BigInteger mSerialNo = seq[0].getInteger().toBigInteger();
+
+ // subject
+ DerValue subject = seq[1];
+ netscape.security.x509.X500Name mSubject =
+ new netscape.security.x509.X500Name(subject.toByteArray());
+
+ // issuer
+ DerValue issuer = seq[2];
+ netscape.security.x509.X500Name mIssuer =
+ new netscape.security.x509.X500Name(issuer.toByteArray());
+
+ // date of archival
+ DerInputStream dateOfArchival = new DerInputStream(seq[3].toByteArray());
+ Date mDateOfArchival = dateOfArchival.getUTCTime();
+ com.netscape.certsrv.kra.ProofOfArchival obj =
+ new com.netscape.certsrv.kra.ProofOfArchival(mSerialNo,
+ mSubject.toString(), mIssuer.toString(), mDateOfArchival);
+ return obj;
+ }
+}
+
+class DummyAuthManager implements com.netscape.certsrv.authentication.IAuthManager
+{
+ public String getName()
+ {
+ return "dummy";
+ }
+
+ public String getImplName()
+ {
+ return "dummy";
+ }
+
+ public IAuthToken authenticate(IAuthCredentials authCred)
+ throws EMissingCredential, EInvalidCredentials, EBaseException
+ {
+ return null;
+ }
+
+ /**
+ * 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
+ {
+ }
+
+ public void shutdown()
+ {
+ }
+
+ public String[] getRequiredCreds()
+ {
+ return null;
+ }
+
+ /**
+ * 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.
+ *
+ * @param implName The authentication manager plugin name.
+ * @exception EBaseException If an internal error occurred
+ */
+ public String[] getConfigParams()
+ throws EBaseException
+ {
+ return null;
+ }
+
+ /**
+ * Get the configuration store for this authentication manager.
+ * @return The configuration store of this authentication manager.
+ */
+ public IConfigStore getConfigStore()
+ {
+ return null;
+ }
+}
+
diff --git a/base/migrate/TxtTo73/src/compile.bat b/base/migrate/TxtTo73/src/compile.bat
new file mode 100755
index 000000000..db46fa019
--- /dev/null
+++ b/base/migrate/TxtTo73/src/compile.bat
@@ -0,0 +1,152 @@
+@ECHO OFF
+REM --- BEGIN COPYRIGHT BLOCK ---
+REM Copyright (C) 2007 Red Hat, Inc.
+REM All rights reserved.
+REM --- END COPYRIGHT BLOCK ---
+
+REM
+REM This script creates the "TxtTo73/classes/Main.class",
+REM "TxtTo73/classes/CMS73LdifParser.class", and
+REM "TxtTo73/classes/DummyAuthManager.class" which are
+REM used to create a CS 7.3 ldif data file.
+REM
+
+
+SETLOCAL
+
+
+REM
+REM Set SERVER_ROOT - identify the CS <server_root> used to compile TxtTo73
+REM
+
+REM SET SERVER_ROOT=C:\cs73
+
+
+REM
+REM Set JDK_VERSION - specify the JDK version used by this version of CS
+REM
+REM CS 7.3 NOTE: "WINNT" - 1.4.2
+REM
+
+REM SET JDK_VERSION=CS_7.3
+
+
+REM
+REM Set JAVA_HOME - specify the complete path to the JDK
+REM
+REM example: \\bermuda.redhat.com\sbc mounted as Y:
+REM
+
+REM SET JAVA_HOME=Y:\cms_jdk\WINNT\%JDK_VERSION%
+
+
+REM
+REM *** DON'T CHANGE ANYTHING BELOW THIS LINE ***
+REM
+
+
+REM
+REM Script-defined constants
+REM
+
+SET CS="CS 7.3"
+
+
+REM
+REM Perform a usage check for the appropriate number of arguments:
+REM
+
+IF "%1" == "" GOTO CHECK_ENVIRONMENT_VARIABLES
+
+
+:USAGE
+ECHO.
+ECHO Usage: "%0"
+ECHO.
+ECHO NOTE: No arguments are required to build the
+ECHO %CS% ldif data classes.
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check presence of user-defined variables
+REM
+
+:CHECK_ENVIRONMENT_VARIABLES
+IF !%SERVER_ROOT%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+IF !%JAVA_HOME%==! GOTO ENVIRONMENT_VARIABLES_ERROR
+GOTO CHECK_SERVER_ROOT
+
+
+:ENVIRONMENT_VARIABLES_ERROR
+ECHO ERROR: Please specify the SERVER_ROOT and JAVA_HOME
+ECHO environment variables for this script!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified SERVER_ROOT exists
+REM
+
+:CHECK_SERVER_ROOT
+IF EXIST %SERVER_ROOT% GOTO CHECK_JAVA_HOME
+
+
+ECHO ERROR: The specified SERVER_ROOT does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Check that the specified JAVA_HOME exists
+REM
+
+:CHECK_JAVA_HOME
+IF EXIST %JAVA_HOME% GOTO SET_LIBRARY_PATH
+
+
+ECHO ERROR: The specified JAVA_HOME does not exist!
+ECHO.
+GOTO EXIT_PROCESS
+
+
+REM
+REM Setup the appropriate library path environment variable
+REM based upon the platform (WINNT)
+REM
+
+:SET_LIBRARY_PATH
+SET PATH=%SERVER_ROOT%\bin\cert\lib;%JAVA_HOME%\bin;%JAVA_HOME%\lib;%PATH%
+
+
+REM
+REM Set TARGET - identify the complete path to the new classes target directory
+REM
+
+SET TARGET=..\classes
+
+
+REM
+REM Create the new classes target directory (if it does not already exist)
+REM
+
+IF EXIST %TARGET% goto COMPILE_CLASSES
+MKDIR %TARGET%
+
+
+REM
+REM Compile TxtTo73 - create "CMS73LdifParser.class", "DummyAuthManager.class",
+REM and "Main.class"
+REM
+
+:COMPILE_CLASSES
+%JAVA_HOME%\bin\javac.exe -d %TARGET% -classpath %JAVA_HOME%\jre\lib\rt.jar;%SERVER_ROOT%\bin\cert\jars\nsutil.jar;%SERVER_ROOT%\bin\cert\jars\certsrv.jar;%SERVER_ROOT%\bin\cert\jars\cmscore.jar;%SERVER_ROOT%\bin\cert\jars\jss3.jar Main.java
+
+
+:EXIT_PROCESS
+
+
+ENDLOCAL
+
diff --git a/base/migrate/TxtTo73/src/compile.sh b/base/migrate/TxtTo73/src/compile.sh
new file mode 100755
index 000000000..a8230e673
--- /dev/null
+++ b/base/migrate/TxtTo73/src/compile.sh
@@ -0,0 +1,141 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#####################################################################
+### ###
+### This script creates the "TxtTo73/classes/Main.class", ###
+### "TxtTo73/classes/CMS73LdifParser.class", and ###
+### "TxtTo73/classes/DummyAuthManager.class" which are ###
+### used to create a CS 7.3 ldif data file. ###
+### ###
+#####################################################################
+
+
+###
+### Set JDK_PLATFORM - must be "HP-UX", "Linux", or "SunOS"
+###
+
+JDK_PLATFORM=Linux
+export JDK_PLATFORM
+
+
+###
+### Set JDK_VERSION - specify the JDK version used by this version of CS
+###
+### CS 7.3 NOTE: "Linux" - 1.5.0 (IBM)
+### "SunOS" - 1.5.0
+###
+
+JDK_VERSION=PKI_7.3.0
+export JDK_VERSION
+
+
+###
+### Set JAVA_HOME - specify the complete path to the JDK
+###
+
+JAVA_HOME=/share/builds/components/cms_jdk/${JDK_PLATFORM}/${JDK_VERSION}
+export JAVA_HOME
+
+
+############################################################################
+### ###
+### *** DON'T CHANGE ANYTHING BELOW THIS LINE *** ###
+### ###
+############################################################################
+
+
+###
+### Script-defined constants
+###
+
+CS="CS 7.3"
+export CS
+
+
+OS_NAME=`uname`
+export OS_NAME
+
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -gt 0 ] ; then
+ echo
+ echo "Usage: $0"
+ echo
+ echo " NOTE: No arguments are required to build the"
+ echo " ${CS} ldif data classes."
+ echo
+ exit 1
+fi
+
+
+###
+### Check presence of user-defined variables
+###
+
+if [ -z "${JAVA_HOME}" ] ; then
+ echo "ERROR: Please specify the SERVER_ROOT and JAVA_HOME "
+ echo " environment variables for this script!"
+ echo
+ exit 2
+fi
+
+
+###
+### Check that the specified JAVA_HOME exists and is a directory
+###
+
+if [ ! -d "${JAVA_HOME}" ] ; then
+ echo "ERROR: Either the specified JAVA_HOME does not exist, "
+ echo " or it is not a directory!"
+ echo
+ exit 4
+fi
+
+
+###
+### Setup the appropriate library path environment variable
+### based upon the platform
+###
+
+if [ ${OS_NAME} = "HP-UX" ] ; then
+ SHLIB_PATH=/usr/lib:/usr/lib/dirsec:${JAVA_HOME}/lib:${JAVA_HOME}/lib/PA_RISC/native_threads
+ export SHLIB_PATH
+elif [ ${OS_NAME} = "Linux" ] ; then
+ LD_LIBRARY_PATH=/usr/lib:/usr/lib/dirsec:${JAVA_HOME}/lib:${JAVA_HOME}/lib/i386/native_threads
+ export LD_LIBRARY_PATH
+else # SunOS
+ LD_LIBRARY_PATH=/usr/lib:/usr/lib/dirsec:${JAVA_HOME}/lib:${JAVA_HOME}/lib/sparc/native_threads
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Set TARGET - identify the complete path to the new classes target directory
+###
+
+TARGET=../classes
+export TARGET
+
+
+###
+### Create the new classes target directory (if it does not already exist)
+###
+
+if [ ! -d ${TARGET} ]; then
+ mkdir -p ${TARGET}
+fi
+
+
+###
+### Compile TxtTo73 - create "CMS73LdifParser.class", "DummyAuthManager.class",
+### and "Main.class"
+###
+
+${JAVA_HOME}/bin/javac -d ${TARGET} -classpath ${JAVA_HOME}/jre/lib/rt.jar:/usr/share/java/rhpki/nsutil.jar:/usr/share/java/rhpki/certsrv.jar:/usr/share/java/rhpki/cmscore.jar:/usr/lib/java/rhpki/ca/ca.jar:/usr/lib/java/rhpki/tks/tks.jar:/usr/lib/java/rhpki/ocsp/ocsp.jar:/usr/lib/java/rhpki/kra/kra.jar:/usr/lib/java/dirsec/jss4.jar Main.java
+
diff --git a/base/migrate/TxtTo80/classes/CS80LdifParser.class b/base/migrate/TxtTo80/classes/CS80LdifParser.class
new file mode 100644
index 000000000..1265fd153
--- /dev/null
+++ b/base/migrate/TxtTo80/classes/CS80LdifParser.class
Binary files differ
diff --git a/base/migrate/TxtTo80/classes/Main.class b/base/migrate/TxtTo80/classes/Main.class
new file mode 100644
index 000000000..0f162327d
--- /dev/null
+++ b/base/migrate/TxtTo80/classes/Main.class
Binary files differ
diff --git a/base/migrate/TxtTo80/run.sh b/base/migrate/TxtTo80/run.sh
new file mode 100755
index 000000000..6dde55758
--- /dev/null
+++ b/base/migrate/TxtTo80/run.sh
@@ -0,0 +1,394 @@
+#!/bin/sh
+
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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) 2009 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+
+#####################################################################
+### ###
+### This script converts a normalized <Source CS Version> ldif ###
+### text file (e. g. - created via a <Source CS Version>ToTxt ###
+### script) into a CS 8.0 ldif data file. ###
+### ###
+### This CS 8.0 ldif data file can then be imported into ###
+### the internal database of the desired CS 8.0 server ###
+### using a utility such as ldif2db. ###
+### ###
+#####################################################################
+
+###
+### Provide a usage function
+###
+
+usage() {
+ echo
+ echo "Usage: $0 input [errors] > output"
+ echo
+ echo " where: input - a "normalized" CS ldif data file,"
+ echo " errors - an optional errors file containing"
+ echo " skipped attributes, and"
+ echo " output - the CS 8.0 ldif text file."
+ echo
+ echo " NOTE: If no redirection is provided to"
+ echo " 'output', then the CS 8.0 ldif text"
+ echo " file will merely be echoed to stdout."
+ echo
+ exit 255
+}
+
+
+##
+## Perform a usage check for the appropriate number of arguments:
+##
+
+if [ $# -lt 1 -o $# -gt 2 ] ; then
+ usage
+fi
+
+
+###
+### Check that the specified "input" file exists and is a regular file.
+###
+
+if [ ! -f $1 ] ; then
+ echo "ERROR: Either the specified 'input' file, '$1', does not exist, "
+ echo " or it is not a regular file!"
+ echo
+ usage
+fi
+
+
+###
+### Check that the specified "input" file exists and is not empty.
+###
+
+if [ ! -s $1 ] ; then
+ echo "ERROR: The specified 'input' file, '$1', is empty!"
+ echo
+ usage
+fi
+
+
+###
+### If an "errors" file is specified, then check that it does not already
+### exist.
+###
+
+if [ $# -eq 2 ] ; then
+ if [ -f $2 ] ; then
+ echo "ERROR: The specified 'errors' file, '$2', already exists!"
+ echo " Please specify a different file!"
+ echo
+ usage
+ fi
+fi
+
+
+###
+### Set PKI_OS
+###
+### CS 8.0 NOTE: "Linux"
+### "SunOS"
+###
+
+PKI_OS=`uname`
+export PKI_OS
+
+if [ "${PKI_OS}" != "Linux" ] &&
+ [ "${PKI_OS}" != "SunOS" ]; then
+ printf "This '$0' script is ONLY executable\n"
+ printf "on either a 'Linux' or 'Solaris' machine!\n"
+ exit 255
+fi
+
+
+###
+### Set PKI_ARCHITECTURE
+###
+### CS 8.0 NOTE: "Linux i386" - 32-bit ("i386")
+### "Linux x86_64" - 64-bit ("x86_64")
+### "SunOS sparc" - 64-bit ("sparcv9")
+###
+
+if [ "${PKI_OS}" == "Linux" ]; then
+ PKI_PLATFORM=`uname -i`
+ export PKI_PLATFORM
+ if [ "${PKI_PLATFORM}" == "i386" ] ||
+ [ "${PKI_PLATFORM}" == "x86_64" ]; then
+ PKI_ARCHITECTURE="${PKI_PLATFORM}"
+ export PKI_ARCHITECTURE
+ else
+ printf "On 'Linux', this '$0' script is ONLY executable\n"
+ printf "on either an 'i386' or 'x86_64' architecture!\n"
+ exit 255
+ fi
+elif [ "${PKI_OS}" == "SunOS" ]; then
+ PKI_PLATFORM=`uname -p`
+ export PKI_PLATFORM
+ if [ "${PKI_PLATFORM}" == "sparc" ]; then
+ PKI_ARCHITECTURE="sparcv9"
+ export PKI_ARCHITECTURE
+ else
+ printf "On 'Solaris', this '$0' script is ONLY executable\n"
+ printf "on a 'sparcv9' architecture!\n"
+ exit 255
+ fi
+fi
+
+
+###
+### Set PKI_OS_DISTRIBUTION
+###
+### CS 8.0 NOTE: "Linux Fedora 8" - "Fedora"
+### "Linux Fedora 9" - "Fedora"
+### "Linux Fedora 10" - "Fedora"
+### "Linux RHEL 5" - "Red Hat"
+### "SunOS 5.9" - "Solaris"
+###
+
+if [ "${PKI_OS}" == "Linux" ]; then
+ IS_FEDORA=`test -e /etc/fedora-release && echo 1 || echo 0`
+ if [ "${IS_FEDORA}" -eq 1 ]; then
+ PKI_DISTRIBUTION="Fedora"
+ export PKI_DISTRIBUTION
+ PKI_OS_RPM_VERSION=`rpm -qf --qf='%{VERSION}' /etc/fedora-release`
+ export PKI_OS_RPM_VERSION
+ PKI_OS_VERSION=`echo "${PKI_OS_RPM_VERSION}" | tr -d [A-Za-z]`
+ export PKI_OS_VERSION
+ else
+ IS_REDHAT=`test -e /etc/redhat-release && echo 1 || echo 0`
+ if [ "${IS_REDHAT}" -eq 1 ]; then
+ PKI_DISTRIBUTION="Red Hat"
+ export PKI_DISTRIBUTION
+ PKI_OS_RPM_VERSION=`rpm -qf --qf='%{VERSION}' /etc/redhat-release`
+ export PKI_OS_RPM_VERSION
+ PKI_OS_VERSION=`echo "${PKI_OS_RPM_VERSION}" | tr -d [A-Za-z]`
+ export PKI_OS_VERSION
+ else
+ printf "On 'Linux',this '$0' script is ONLY executable\n"
+ printf "on either a 'Fedora' or 'Red Hat' machine!\n"
+ exit 255
+ fi
+ fi
+elif [ "${PKI_OS}" == "SunOS" ]; then
+ PKI_DISTRIBUTION="Solaris"
+ export PKI_DISTRIBUTION
+ PKI_OS_VERSION=`uname -r | awk -F. '{print $2}'`
+ export PKI_OS_VERSION
+fi
+
+
+###
+### Set JAVA_HOME
+###
+### CS 8.0 NOTE: "Linux Fedora 8" - JRE 1.7.0 (IcedTea)
+### "Linux Fedora 9" - JRE 1.6.0 (OpenJDK)
+### "Linux Fedora 10" - JRE 1.6.0 (OpenJDK)
+### "Linux RHEL 5" - JRE 1.6.0 (OpenJDK)
+### "SunOS 5.9" - JRE 1.6.0 (Sun JDK)
+###
+### "Linux" - ALWAYS set specific JAVA_HOME
+### "SunOS" - ALLOW JAVA_HOME to be pre-defined
+###
+
+if [ "${PKI_OS}" == "Linux" ]; then
+ if [ "${PKI_DISTRIBUTION}" == "Fedora" ]; then
+ if [ ${PKI_OS_VERSION} -eq 8 ]; then
+ if [ "${PKI_ARCHITECTURE}" == "i386" ]; then
+ JAVA_HOME="/usr/lib/jvm/jre-1.7.0-icedtea"
+ JAVA_ARCHITECTURE="i386"
+ else # "x86_64"
+ JAVA_HOME="/usr/lib/jvm/jre-1.7.0-icedtea.${PKI_ARCHITECTURE}"
+ JAVA_ARCHITECTURE="amd64"
+ fi
+ if [ ! -x "${JAVA_HOME}/bin/java" ] &&
+ [ ! -f "${JAVA_HOME}/lib/rt.jar" ] &&
+ [ ! -d "${JAVA_HOME}/lib/${JAVA_ARCHITECTURE}" ] &&
+ [ ! -d "${JAVA_HOME}/lib/${JAVA_ARCHITECTURE}/native_threads" ]; then
+ printf "On 'Fedora 8', this '$0' script is ONLY executable\n"
+ printf "by 'JRE 1.7.0 (IcedTea)'!\n"
+ exit 255
+ fi
+ elif [ ${PKI_OS_VERSION} -gt 8 ]; then
+ if [ "${PKI_ARCHITECTURE}" == "i386" ]; then
+ JAVA_HOME="/usr/lib/jvm/jre-1.6.0-openjdk"
+ JAVA_ARCHITECTURE="i386"
+ else # "x86_64"
+ JAVA_HOME="/usr/lib/jvm/jre-1.6.0-openjdk.${PKI_ARCHITECTURE}"
+ JAVA_ARCHITECTURE="amd64"
+ fi
+ if [ ! -x "${JAVA_HOME}/bin/java" ] &&
+ [ ! -f "${JAVA_HOME}/lib/rt.jar" ] &&
+ [ ! -d "${JAVA_HOME}/lib/${JAVA_ARCHITECTURE}" ] &&
+ [ ! -d "${JAVA_HOME}/lib/${JAVA_ARCHITECTURE}/native_threads" ]; then
+ printf "On 'Fedora ${PKI_OS_VERSION}', "
+ printf "this '$0' script is ONLY executable\n"
+ printf "by 'JRE 1.6.0 (OpenJDK)'!\n"
+ exit 255
+ fi
+ else
+ printf "On 'Fedora', this '$0' script is ONLY executable\n"
+ printf "on 'Fedora 8' or later!\n"
+ exit 255
+ fi
+ elif [ "${PKI_DISTRIBUTION}" == "Red Hat" ]; then
+ if [ ${PKI_OS_VERSION} -ge 5 ]; then
+ if [ "${PKI_ARCHITECTURE}" == "i386" ]; then
+ JAVA_HOME="/usr/lib/jvm/jre-1.6.0-openjdk"
+ JAVA_ARCHITECTURE="i386"
+ else # "x86_64"
+ JAVA_HOME="/usr/lib/jvm/jre-1.6.0-openjdk.${PKI_ARCHITECTURE}"
+ JAVA_ARCHITECTURE="amd64"
+ fi
+ if [ ! -x "${JAVA_HOME}/bin/java" ] &&
+ [ ! -f "${JAVA_HOME}/lib/rt.jar" ] &&
+ [ ! -d "${JAVA_HOME}/lib/${JAVA_ARCHITECTURE}" ] &&
+ [ ! -d "${JAVA_HOME}/lib/${JAVA_ARCHITECTURE}/native_threads" ]; then
+ printf "On 'RHEL ${PKI_OS_VERSION}', "
+ printf "this '$0' script is ONLY executable\n"
+ printf "by 'JRE 1.6.0 (OpenJDK)'!\n"
+ exit 255
+ fi
+ else
+ printf "On 'Red Hat', this '$0' script is ONLY executable\n"
+ printf "on 'RHEL 5' or later!\n"
+ exit 255
+ fi
+ fi
+ JRE_EXE="${JAVA_HOME}/bin/java"
+ export JRE_EXE
+ JRE_VERSION=`${JAVA_HOME}/bin/java -version 2>&1 | cut -b15-19 | sed -n '/[0-9]\.[0-9]\.[0-9]/p'`
+ export JRE_VERSION
+elif [ "${PKI_OS}" == "SunOS" ]; then
+ if [ "${JAVA_HOME}" == "" ]; then
+ JAVA_HOME="/usr/java"
+ fi
+ JRE_EXE="${JAVA_HOME}/bin/${PKI_ARCHITECTURE}/java"
+ export JRE_EXE
+ JRE_VERSION=`${JAVA_HOME}/bin/${PKI_ARCHITECTURE}/java -version 2>&1 | cut -b15-19 | sed -n '/[0-9]\.[0-9]\.[0-9]/p'`
+ export JRE_VERSION
+ if [ ${PKI_OS_VERSION} -eq 9 ]; then
+ if [ "${JRE_VERSION}" != "1.6.0" ]; then
+ printf "On 'Solaris ${PKI_OS_VERSION}', "
+ printf "this '$0' script is ONLY executable\n"
+ printf "by 'JRE 1.6.0'!\n"
+ exit 255
+ fi
+ if [ ! -x "${JAVA_HOME}/bin/${PKI_ARCHITECTURE}/java" ] &&
+ [ ! -f "${JAVA_HOME}/jre/lib/rt.jar" ] &&
+ [ ! -d "${JAVA_HOME}/jre/lib/${PKI_ARCHITECTURE}" ] &&
+ [ ! -d "${JAVA_HOME}/jre/lib/${PKI_ARCHITECTURE}/native_threads" ]; then
+ printf "On 'Solaris ${PKI_OS_VERSION}', "
+ printf "this '$0' script is ONLY executable\n"
+ printf "by 'JRE 1.6.0 (Sun JDK)'!\n"
+ exit 255
+ fi
+ else
+ printf "On 'Solaris', this '$0' script is ONLY executable\n"
+ printf "on 'Solaris 9'!\n"
+ exit 255
+ fi
+fi
+
+
+###
+### Setup the appropriate CLASSPATH and LD_LIBRARY_PATH
+### environment variables based upon the platform
+###
+### NOTE: As of SunOS JDK 1.4.0, the required "Unicode" classes
+### have been moved from "i18n.jar" to "rt.jar".
+###
+
+if [ ! -f "/usr/share/java/pki/cmscore.jar" ] &&
+ [ ! -f "/usr/share/java/pki/certsrv.jar" ]; then
+ printf "This '$0' script must be EXECUTED against\n"
+ printf "the 'pki-common' package!\n"
+ exit 255
+fi
+if [ ! -f "/usr/share/java/pki/nsutil.jar" ]; then
+ printf "This '$0' script must be EXECUTED against\n"
+ printf "the 'pki-util' package!\n"
+ exit 255
+fi
+if [ ! -d "/usr/share/pki/migrate/TxtTo80/classes" ]; then
+ printf "This '$0' script must be EXECUTED against\n"
+ printf "the 'pki-migrate' package!\n"
+ exit 255
+fi
+
+if [ ${PKI_OS} = "Linux" ] ; then
+ if [ ! -f "/usr/lib/java/jss4.jar" ]; then
+ printf "This '$0' script must be EXECUTED against\n"
+ printf "the 'jss' package!\n"
+ exit 255
+ fi
+ CLASSPATH=${JAVA_HOME}/lib/rt.jar
+ CLASSPATH=/usr/lib/java/jss4.jar:${CLASSPATH}
+ CLASSPATH=/usr/share/java/pki/nsutil.jar:${CLASSPATH}
+ CLASSPATH=/usr/share/java/pki/cmscore.jar:${CLASSPATH}
+ CLASSPATH=/usr/share/java/pki/certsrv.jar:${CLASSPATH}
+ CLASSPATH=/usr/share/pki/migrate/TxtTo80/classes:${CLASSPATH}
+ export CLASSPATH
+ if [ ${PKI_ARCHITECTURE} = "i386" ] ; then
+ LD_LIBRARY_PATH=${JAVA_HOME}/lib/${JAVA_ARCHITECTURE}/native_threads
+ LD_LIBRARY_PATH=${JAVA_HOME}/lib/${JAVA_ARCHITECTURE}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ else # "x86_64"
+ LD_LIBRARY_PATH=${JAVA_HOME}/lib/${JAVA_ARCHITECTURE}/native_threads
+ LD_LIBRARY_PATH=${JAVA_HOME}/lib/${JAVA_ARCHITECTURE}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib64:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ fi
+else # "SunOS"
+ if [ ! -f "/usr/lib/java/dirsec/jss4.jar" ]; then
+ printf "This '$0' script must be EXECUTED against\n"
+ printf "the 'dirsec-jss' package!\n"
+ exit 255
+ fi
+ CLASSPATH=${JAVA_HOME}/jre/lib/rt.jar
+ CLASSPATH=/usr/lib/java/dirsec/jss4.jar:${CLASSPATH}
+ CLASSPATH=/usr/share/java/pki/nsutil.jar:${CLASSPATH}
+ CLASSPATH=/usr/share/java/pki/cmscore.jar:${CLASSPATH}
+ CLASSPATH=/usr/share/java/pki/certsrv.jar:${CLASSPATH}
+ CLASSPATH=/usr/share/pki/migrate/TxtTo80/classes:${CLASSPATH}
+ export CLASSPATH
+ LD_LIBRARY_PATH=${JAVA_HOME}/jre/lib/${PKI_ARCHITECTURE}/native_threads
+ LD_LIBRARY_PATH=${JAVA_HOME}/jre/lib/${PKI_ARCHITECTURE}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/${PKI_ARCHITECTURE}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/${PKI_ARCHITECTURE}/dirsec:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Execute TxtTo80 to convert the "normalized" CS ldif data file in to
+### a CS 8.0 ldif text file suitable for import in to a CS 8.0 LDAP DB.
+###
+
+# printf "================================================================\n"
+# printf "PKI_OS='${PKI_OS}'\n"
+# printf "PKI_DISTRIBUTION='${PKI_DISTRIBUTION}'\n"
+# printf "PKI_OS_VERSION='${PKI_OS_VERSION}'\n"
+# printf "PKI_ARCHITECTURE='${PKI_ARCHITECTURE}'\n"
+# printf "JAVA_HOME='${JAVA_HOME}'\n"
+# printf "JRE_EXE='${JRE_EXE}'\n"
+# printf "JRE_VERSION='${JRE_VERSION}'\n"
+# printf "================================================================\n\n"
+
+${JRE_EXE} -classpath ${CLASSPATH} Main $1 $2
+
diff --git a/base/migrate/TxtTo80/src/Main.java b/base/migrate/TxtTo80/src/Main.java
new file mode 100644
index 000000000..ad9eb6b18
--- /dev/null
+++ b/base/migrate/TxtTo80/src/Main.java
@@ -0,0 +1,593 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License 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 ---
+//
+// "TxtTo80/src/Main.java" is based upon a copy "TxtTo80/src/Main.java".
+//
+// Always comment any new code sections with a "CS 8.0" header, and
+// apply these changes forward to all other "TxtTo*/src/Main.java" files
+// (including this comment header) so that these differences will only
+// appear when this file is diffed against an earlier "TxtTo*" version.
+//
+// This file should always be maintained by executing the following command:
+//
+// diff TxtTo73/src/Main.java TxtTo80/src/Main.java
+//
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import org.mozilla.jss.*; // CMS 4.5 and later
+import org.mozilla.jss.crypto.*; // CMS 4.5 and later
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import netscape.security.util.*;
+import java.lang.reflect.*;
+
+public class Main
+{
+ public static void main(String args[])
+ {
+ try {
+ // initialize CryptoManager in CMS 4.5 and later
+ CryptoManager.initialize(".");
+ // load JSS provider in CMS 4.5 and later
+ java.security.Security.removeProvider("SUN version 1.2");
+ // The following call to "java.security.Security.insertProviderAt()"
+ // is no longer commented out in CMS 4.5 and later
+ java.security.Security.insertProviderAt(
+ new netscape.security.provider.CMS(), 0);
+ java.security.Provider ps[] =
+ java.security.Security.getProviders();
+ if (ps == null || ps.length <= 0) {
+ System.err.println("Java Security Provider NONE");
+ } else {
+ for (int x = 0; x < ps.length; x++) {
+ System.err.println("Java Security Provider " + x + " class=" + ps[x]);
+ }
+ }
+
+ // Parse the File
+ CS80LdifParser parser = null;
+ if (args.length == 1) {
+ parser = new CS80LdifParser(args[0]);
+ } else if (args.length == 2) {
+ parser = new CS80LdifParser(args[0], args[1]);
+ } else {
+ throw new IOException("Invalid Parameters");
+ }
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+}
+
+class CS80LdifParser
+{
+ // constants
+ private static final String DN =
+ "dn:";
+ // Directory Servers in CS 8.0 and later use "extdata-"
+ private static final String extAttrPrefix =
+ "extdata-";
+ private static final String BEGIN =
+ "--- BEGIN ATTRIBUTES ---";
+ private static final String END =
+ "--- END ATTRIBUTES ---";
+
+ // variables
+ private String mFilename = null;
+ private String mErrorFilename = null;
+ private PrintWriter mErrorPrintWriter = null;
+
+ public CS80LdifParser(String filename)
+ {
+ mFilename = filename;
+ }
+
+ public CS80LdifParser(String filename, String errorFilename)
+ {
+ mFilename = filename;
+ mErrorFilename = errorFilename;
+ }
+
+ public void parse() throws Exception
+ {
+ if (mErrorFilename != null) {
+ mErrorPrintWriter = new PrintWriter(new FileOutputStream(mErrorFilename));
+ }
+ BufferedReader reader = new BufferedReader(
+ new FileReader(mFilename));
+ String line = null;
+ String dn = null;
+ Vector requestAttributes = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(DN)) {
+ dn = line;
+ }
+ if (line.equals(BEGIN)) {
+ requestAttributes = new Vector();
+ continue;
+ }
+ if (requestAttributes == null) {
+ // Since we are not in the midst of a Request Attribute,
+ // simply print out the line.
+ System.out.println(line);
+
+ // New in CS 8.0:
+ if( line.equals( "objectClass: request" ) ) {
+ // Since Request Objects now contain individual undefined
+ // schema attributes (rather than a single serialized blob),
+ // we disable schema checking to allow them to be stored as
+ // Multi-Value strings by adding an "extensibleObject"
+ // objectclass to each Request Object entry.
+ System.out.println( "objectClass: extensibleObject" );
+ }
+ continue;
+ }
+ if (line.equals(END)) {
+ parseAttributes(dn, requestAttributes);
+ requestAttributes = null;
+ continue;
+ }
+ if (line.startsWith(" ")) { // beginning of attr
+ requestAttributes.addElement(
+ line.substring(1, line.length()));
+ } else {
+ // #737216 - skip unnecessary empty lines in attributes
+ if (line.trim().length() == 0) continue;
+ requestAttributes.setElementAt(
+ (String)
+ requestAttributes.lastElement() +
+ "\n" +
+ line,
+ requestAttributes.size() - 1);
+ }
+ }
+ }
+
+ public String getKey( String dn, String attr )
+ {
+ String key = null;
+
+ int colon = attr.indexOf( ':' );
+ if (colon == -1) {
+ return key;
+ }
+
+ int equal = attr.indexOf( '=' );
+ if( equal == -1 ) {
+ return key;
+ }
+
+ key = attr.substring( 0, colon );
+ if( key.startsWith( "serviceErrors" ) ) {
+ // #56953 - skip serviceErrors
+ return key;
+ }
+
+ if( key.startsWith( "Error" ) ) {
+ // #56953 - skip Error
+ return key;
+ }
+
+ return key;
+ }
+
+ public void parseAttributes(String dn, Vector attrs) throws Exception
+ {
+ for( int i = 0; i < attrs.size(); i++ ) {
+ String attr = ( String ) attrs.elementAt( i );
+ try {
+ translateAttributes( dn, attr );
+ } catch( Exception e ) {
+ if( mErrorPrintWriter != null ) {
+ mErrorPrintWriter.println( dn );
+ }
+ String key = getKey( dn, attr );
+ if( key != null ) {
+ mErrorPrintWriter.println( "Skipped " + key );
+ }
+ }
+ }
+ }
+
+ /*************************************************************************/
+ /* The following two functions: */
+ /* */
+ /* protected boolean isAlphaNum(char in) {} */
+ /* */
+ /* public String encodeKey(String key) {} */
+ /* */
+ /* were copied from the private class called: */
+ /* */
+ /* class ExtAttrDynMapper implements IDBDynAttrMapper {} */
+ /* */
+ /* in the file called: */
+ /* */
+ /* pki/base/common/src/com/netscape/cmscore/request/RequestRecord.java */
+ /* */
+ /*************************************************************************/
+
+ 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;
+ }
+
+ /**
+ * 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();
+ }
+ }
+
+ public String formatData( String data ) {
+ StringBuffer output = null;
+ char[] input = data.toCharArray();
+ int startCopyIndex = 0;
+
+ // Every string buffer has a capacity. As long as the length of the
+ // character sequence contained in the string buffer does not exceed
+ // the capacity, it is not necessary to allocate a new internal buffer
+ // array. If the internal buffer overflows, it is automatically made
+ // larger.
+ //
+ // Start out with an output buffer at least as big as the input buffer.
+ output = new StringBuffer( input.length );
+
+ int index = 0;
+ while( index < input.length ) {
+ if( input[index] != '\n' ) {
+ output.append( input[index] );
+ } else {
+ output.append( input[index] );
+ if( index != ( input.length - 1 ) ) {
+ // Place an initial space after each carriage return
+ // with the exception of the last one
+ output.append( ' ' );
+ }
+ }
+
+ index++;
+ }
+
+ return( output.toString() );
+ }
+
+ public void translateAttributes( String dn, String attr )
+ throws Exception
+ {
+ // attribute format [key]:[type]=[data]
+
+ int colon = attr.indexOf( ':' );
+ if( colon == -1 ) {
+ if( mErrorPrintWriter != null ) {
+ if( dn != null ) {
+ mErrorPrintWriter.println( dn );
+ }
+ mErrorPrintWriter.println( "Skipped " + attr );
+ }
+ return;
+ }
+ int equal = attr.indexOf( '=' );
+ if( equal == -1 ) {
+ if( mErrorPrintWriter != null ) {
+ if( dn != null ) {
+ mErrorPrintWriter.println( dn );
+ }
+ mErrorPrintWriter.println( "Skipped " + attr );
+ }
+ return;
+ }
+
+ String key = attr.substring( 0, colon );
+ String type = attr.substring( colon + 1, equal );
+ String data = attr.substring( equal + 1 );
+
+ if( key.startsWith( "serviceErrors" ) ) {
+ // #56953 - skip serviceErrors
+ if( mErrorPrintWriter != null ) {
+ if( dn != null ) {
+ mErrorPrintWriter.println( dn );
+ }
+ mErrorPrintWriter.println( "Skipped " + attr );
+ }
+ return;
+ }
+
+ if( key.startsWith( "Error" ) ) {
+ // #56953 - skip serviceErrors
+ if( mErrorPrintWriter != null ) {
+ if( dn != null ) {
+ mErrorPrintWriter.println( dn );
+ }
+ mErrorPrintWriter.println( "Skipped " + attr );
+ }
+ return;
+ }
+
+ // To account for '47ToTxt' data files that have previously
+ // been generated, ALWAYS convert 'iplanet' to 'netscape'.
+ //
+ // Bugzilla Bug #224801 (a.k.a - Raidzilla Bug #56981)
+ // Bugzilla Bug #483519
+ //
+ String translation = null;
+ if( type.startsWith( "iplanet" ) ) {
+ translation = "netscape"
+ + type.substring( 7 );
+ type = translation;
+ } else if( type.startsWith( "com.iplanet" ) ) {
+ translation = "com.netscape"
+ + type.substring( 11 );
+ type = translation;
+ }
+
+ if( type.startsWith( "com.netscape.certsrv.request.AgentApprovals" ) ) {
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.startsWith( "com.netscape.certsrv.base.ArgBlock" )
+ || type.startsWith( "com.netscape.cmscore.base.ArgBlock" ) ) {
+ // CMS 6.1: created new "com.netscape.certsrv.base.IArgBlock" and
+ // moved old "com.netscape.certsrv.base.ArgBlock"
+ // to "com.netscape.cmscore.base.ArgBlock"
+
+ // Bugzilla Bug #737217 - adding proper "ext-data" array format
+ int secondEqual = data.indexOf('=');
+ if (secondEqual == -1) {
+ if( mErrorPrintWriter != null ) {
+ if( dn != null ) {
+ mErrorPrintWriter.println( dn );
+ }
+ mErrorPrintWriter.println( "Skipped " + attr );
+ }
+ return;
+ }
+ String subKey = data.substring( 0, secondEqual );
+ String subKeyData = data.substring( secondEqual + 1 );
+ System.out.println( extAttrPrefix + encodeKey( key ) + ";" +
+ subKey + ": " + formatData( subKeyData ) );
+ } else if( type.startsWith( "com.netscape.certsrv.authentication.AuthToken" ) ) {
+ // Processes 'java.math.BigInteger[]':
+ //
+ // Bugzilla Bug #225031 (a.k.a - Raidzilla Bug #58356)
+ //
+ // Processes 'java.lang.String[]':
+ //
+ // Bugzilla Bug #224763 (a.k.a - Raidzilla Bug #57949)
+ // Bugzilla Bug #252240
+ //
+
+ // Bugzilla Bug #737217 - adding proper "ext-data" array format
+ int secondColon = data.indexOf(':');
+ int secondEqual = data.indexOf('=');
+ if (secondEqual == -1 || secondColon >= secondEqual) {
+ if( mErrorPrintWriter != null ) {
+ if( dn != null ) {
+ mErrorPrintWriter.println( dn );
+ }
+ mErrorPrintWriter.println( "Skipped " + attr );
+ }
+ return;
+ }
+ if (secondColon == -1) {
+ secondColon = secondEqual;
+ }
+ String subKey = data.substring( 0, secondColon );
+ String subKeyData = data.substring( secondEqual + 1 );
+ System.out.println( extAttrPrefix + encodeKey( key ) + ";" +
+ subKey + ": " + formatData( subKeyData ) );
+ } else if( type.startsWith( "java.math.BigInteger[" ) ) {
+ // Bugzilla Bug #238779
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.startsWith( "java.math.BigInteger" ) ) {
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.startsWith( "byte[]" ) ) {
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.startsWith( "byte[" ) ) {
+ // byte array
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.startsWith( "netscape.security.x509.CertificateAlgorithmId" ) ) {
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.equals( "netscape.security.x509.CertificateChain" ) ) {
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.equals( "netscape.security.x509.CertificateExtensions" ) ) {
+ // XXX - "db2ldif" appears dumps these as ":" values, but they
+ // always appear as "::" base-64 encoded values?
+ // CMS 6.2: revised method of decoding objects of type
+ // "netscape.security.x509.CertificateExtensions"
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.equals( "netscape.security.x509.CertificateSubjectName" ) ) {
+ // CMS 6.2: revised method of decoding objects of type
+ // "netscape.security.x509.CertificateSubjectName"
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.startsWith( "netscape.security.x509.CertificateValidity" ) ) {
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.equals( "netscape.security.x509.CertificateX509Key" ) ) {
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.startsWith( "com.netscape.certsrv.cert.CertInfo" ) ) {
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if (type.startsWith("java.util.Hashtable")) {
+ // Bugzilla Bug #224800 (a.k.a - Raidzilla Bug #56953)
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.startsWith( "Integer[" ) ) {
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.startsWith( "java.lang.Integer" ) ) {
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.startsWith( "org.mozilla.jss.asn1.INTEGER" ) ) {
+ // CS 7.1 stores bodyPartId as INTEGER
+ // CS 7.2 fixed the problem by storing it as String
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.startsWith( "com.netscape.certsrv.dbs.keydb.KeyRecord" )
+ || type.startsWith( "com.netscape.cmscore.dbs.KeyRecord" ) ) {
+ // Bugzilla Bug #508191 - These only apply to KRA; and in CS 8.0,
+ // since KRA requests only need to refer
+ // to the actual "keyRecord" referenced
+ // by the "keySerialNumber" data,
+ // all other "KeyRecord" request data is
+ // ignored, since it is already stored
+ // in the actual "keyRecord".
+ if( data.startsWith( "keySerialNumber" ) ) {
+ String keySerialNumber = data.substring( data.indexOf( "=" ) + 1 );
+ System.out.println( extAttrPrefix +
+ encodeKey( key.toLowerCase() ) + ": " +
+ formatData( keySerialNumber ) );
+ }
+ } else if( type.startsWith( "java.util.Locale" ) ) {
+ // CMS 6.2: begin checking for new type
+ // "java.util.Locale"
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.startsWith( "com.netscape.certsrv.kra.ProofOfArchival" )
+ || type.startsWith( "com.netscape.cmscore.kra.ProofOfArchival" ) ) {
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.startsWith( "netscape.security.x509.RevokedCertImpl" ) ) {
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.startsWith( "java.lang.String[" ) ) {
+ // Bugzilla Bug #223360 (a.k.a - Raidzilla Bug #58086)
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if (type.startsWith("java.lang.String")) {
+ // Examples:
+ //
+ // key.equals( "publickey" )
+ // key.equals( "cert_request" )
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.startsWith( "java.util.Vector" ) ) {
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.startsWith( "netscape.security.x509.X509CertImpl[" ) ) {
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.equals( "netscape.security.x509.X509CertImpl" ) ) {
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.startsWith( "netscape.security.x509.X509CertInfo[" )
+ || type.startsWith( "netscape.security.extensions.CertInfo[" ) )
+ {
+ // CMS 6.2: begin checking for additional new type
+ // "netscape.security.extensions.CertInfo["
+ //
+ // CMS 6.1: "netscape.security.x509.X509CertInfo"
+ // now always utilizes arrays such as
+ // "netscape.security.x509.X509CertInfo["
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.equals( "netscape.security.x509.X509CertInfo" ) ) {
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else if( type.endsWith( "Exception" ) ) {
+ System.out.println( extAttrPrefix + encodeKey( key ) + ": " +
+ formatData( data ) );
+ } else {
+ System.err.println( "ERROR type - " + type + " - "+ attr );
+ System.exit( 0 );
+ }
+ }
+}
+
diff --git a/base/migrate/TxtTo80/src/compile.sh b/base/migrate/TxtTo80/src/compile.sh
new file mode 100755
index 000000000..c8dd848e0
--- /dev/null
+++ b/base/migrate/TxtTo80/src/compile.sh
@@ -0,0 +1,345 @@
+#!/bin/bash
+
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2009 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+
+#####################################################################
+### ###
+### This script creates: ###
+### ###
+### "TxtTo80/classes/CS80LdifParser.class", ###
+### "TxtTo80/classes/DummyAuthManager.class", and ###
+### "TxtTo80/classes/Main.class", ###
+### ###
+### which may be used to convert a "normalized" ldif data file ###
+### exported from a version of CS prior to 8.0 into a CS 8.0 ###
+### ldif data file suitable for import into a CS 8.0 LDAP DB. ###
+### ###
+#####################################################################
+
+###
+### Provide a usage function
+###
+
+usage() {
+ echo
+ echo "Usage: $0"
+ echo
+ echo " NOTE: No arguments are required to build the"
+ echo " CS 8.0 ldif data classes."
+ echo
+ exit 255
+}
+
+###
+### Perform a usage check for the appropriate number of arguments:
+###
+
+if [ $# -gt 0 ] ; then
+ usage
+fi
+
+
+###
+### Set PKI_OS
+###
+### CS 8.0 NOTE: "Linux"
+### "SunOS"
+###
+
+PKI_OS=`uname`
+export PKI_OS
+
+if [ "${PKI_OS}" != "Linux" ] &&
+ [ "${PKI_OS}" != "SunOS" ]; then
+ printf "This '$0' script is ONLY executable\n"
+ printf "on either a 'Linux' or 'Solaris' machine!\n"
+ exit 255
+fi
+
+
+###
+### Set PKI_ARCHITECTURE
+###
+### CS 8.0 NOTE: "Linux i386" - 32-bit ("i386")
+### "Linux x86_64" - 64-bit ("x86_64")
+### "SunOS sparc" - 64-bit ("sparcv9")
+###
+
+if [ "${PKI_OS}" == "Linux" ]; then
+ PKI_PLATFORM=`uname -i`
+ export PKI_PLATFORM
+ if [ "${PKI_PLATFORM}" == "i386" ] ||
+ [ "${PKI_PLATFORM}" == "x86_64" ]; then
+ PKI_ARCHITECTURE="${PKI_PLATFORM}"
+ export PKI_ARCHITECTURE
+ else
+ printf "On 'Linux', this '$0' script is ONLY executable\n"
+ printf "on either an 'i386' or 'x86_64' architecture!\n"
+ exit 255
+ fi
+elif [ "${PKI_OS}" == "SunOS" ]; then
+ PKI_PLATFORM=`uname -p`
+ export PKI_PLATFORM
+ if [ "${PKI_PLATFORM}" == "sparc" ]; then
+ PKI_ARCHITECTURE="sparcv9"
+ export PKI_ARCHITECTURE
+ else
+ printf "On 'Solaris', this '$0' script is ONLY executable\n"
+ printf "on a 'sparcv9' architecture!\n"
+ exit 255
+ fi
+fi
+
+
+###
+### Set PKI_OS_DISTRIBUTION
+###
+### CS 8.0 NOTE: "Linux Fedora 8" - "Fedora"
+### "Linux Fedora 9" - "Fedora"
+### "Linux Fedora 10" - "Fedora"
+### "Linux RHEL 5" - "Red Hat"
+### "SunOS 5.9" - "Solaris"
+###
+
+if [ "${PKI_OS}" == "Linux" ]; then
+ IS_FEDORA=`test -e /etc/fedora-release && echo 1 || echo 0`
+ if [ "${IS_FEDORA}" -eq 1 ]; then
+ PKI_DISTRIBUTION="Fedora"
+ export PKI_DISTRIBUTION
+ PKI_OS_RPM_VERSION=`rpm -qf --qf='%{VERSION}' /etc/fedora-release`
+ export PKI_OS_RPM_VERSION
+ PKI_OS_VERSION=`echo "${PKI_OS_RPM_VERSION}" | tr -d [A-Za-z]`
+ export PKI_OS_VERSION
+ else
+ IS_REDHAT=`test -e /etc/redhat-release && echo 1 || echo 0`
+ if [ "${IS_REDHAT}" -eq 1 ]; then
+ PKI_DISTRIBUTION="Red Hat"
+ export PKI_DISTRIBUTION
+ PKI_OS_RPM_VERSION=`rpm -qf --qf='%{VERSION}' /etc/redhat-release`
+ export PKI_OS_RPM_VERSION
+ PKI_OS_VERSION=`echo "${PKI_OS_RPM_VERSION}" | tr -d [A-Za-z]`
+ export PKI_OS_VERSION
+ else
+ printf "On 'Linux',this '$0' script is ONLY executable\n"
+ printf "on either a 'Fedora' or 'Red Hat' machine!\n"
+ exit 255
+ fi
+ fi
+elif [ "${PKI_OS}" == "SunOS" ]; then
+ PKI_DISTRIBUTION="Solaris"
+ export PKI_DISTRIBUTION
+ PKI_OS_VERSION=`uname -r | awk -F. '{print $2}'`
+ export PKI_OS_VERSION
+fi
+
+
+###
+### Set JAVA_HOME
+###
+### CS 8.0 NOTE: "Linux Fedora 8" - JDK 1.7.0 (IcedTea)
+### "Linux Fedora 9" - JDK 1.6.0 (OpenJDK)
+### "Linux Fedora 10" - JDK 1.6.0 (OpenJDK)
+### "Linux RHEL 5" - JDK 1.6.0 (OpenJDK)
+### "SunOS 5.9" - JDK 1.6.0 (Sun JDK)
+###
+### "Linux" - ALWAYS set specific JAVA_HOME
+### "SunOS" - ALLOW JAVA_HOME to be pre-defined
+###
+
+if [ "${PKI_OS}" == "Linux" ]; then
+ if [ "${PKI_DISTRIBUTION}" == "Fedora" ]; then
+ if [ ${PKI_OS_VERSION} -eq 8 ]; then
+ if [ "${PKI_ARCHITECTURE}" == "i386" ]; then
+ JAVA_HOME="/usr/lib/jvm/java-1.7.0-icedtea"
+ JAVA_ARCHITECTURE="i386"
+ else # "x86_64"
+ JAVA_HOME="/usr/lib/jvm/java-1.7.0-icedtea.${PKI_ARCHITECTURE}"
+ JAVA_ARCHITECTURE="amd64"
+ fi
+ if [ ! -x "${JAVA_HOME}/bin/javac" ] &&
+ [ ! -f "${JAVA_HOME}/jre/lib/rt.jar" ] &&
+ [ ! -d "${JAVA_HOME}/jre/lib/${JAVA_ARCHITECTURE}" ] &&
+ [ ! -d "${JAVA_HOME}/jre/lib/${JAVA_ARCHITECTURE}/native_threads" ]; then
+ printf "On 'Fedora 8', this '$0' script is ONLY executable\n"
+ printf "by 'JDK 1.7.0 (IcedTea)'!\n"
+ exit 255
+ fi
+ elif [ ${PKI_OS_VERSION} -gt 8 ]; then
+ if [ "${PKI_ARCHITECTURE}" == "i386" ]; then
+ JAVA_HOME="/usr/lib/jvm/java-1.6.0-openjdk"
+ JAVA_ARCHITECTURE="i386"
+ else # "x86_64"
+ JAVA_HOME="/usr/lib/jvm/java-1.6.0-openjdk.${PKI_ARCHITECTURE}"
+ JAVA_ARCHITECTURE="amd64"
+ fi
+ if [ ! -x "${JAVA_HOME}/bin/javac" ] &&
+ [ ! -f "${JAVA_HOME}/jre/lib/rt.jar" ] &&
+ [ ! -d "${JAVA_HOME}/jre/lib/${JAVA_ARCHITECTURE}" ] &&
+ [ ! -d "${JAVA_HOME}/jre/lib/${JAVA_ARCHITECTURE}/native_threads" ]; then
+ printf "On 'Fedora ${PKI_OS_VERSION}', "
+ printf "this '$0' script is ONLY executable\n"
+ printf "by 'JDK 1.6.0 (OpenJDK)'!\n"
+ exit 255
+ fi
+ else
+ printf "On 'Fedora', this '$0' script is ONLY executable\n"
+ printf "on 'Fedora 8' or later!\n"
+ exit 255
+ fi
+ elif [ "${PKI_DISTRIBUTION}" == "Red Hat" ]; then
+ if [ ${PKI_OS_VERSION} -ge 5 ]; then
+ if [ "${PKI_ARCHITECTURE}" == "i386" ]; then
+ JAVA_HOME="/usr/lib/jvm/java-1.6.0-openjdk"
+ JAVA_ARCHITECTURE="i386"
+ else # "x86_64"
+ JAVA_HOME="/usr/lib/jvm/java-1.6.0-openjdk.${PKI_ARCHITECTURE}"
+ JAVA_ARCHITECTURE="amd64"
+ fi
+ if [ ! -x "${JAVA_HOME}/bin/javac" ] &&
+ [ ! -f "${JAVA_HOME}/jre/lib/rt.jar" ] &&
+ [ ! -d "${JAVA_HOME}/jre/lib/${JAVA_ARCHITECTURE}" ] &&
+ [ ! -d "${JAVA_HOME}/jre/lib/${JAVA_ARCHITECTURE}/native_threads" ]; then
+ printf "On 'RHEL ${PKI_OS_VERSION}', "
+ printf "this '$0' script is ONLY executable\n"
+ printf "by 'JDK 1.6.0 (OpenJDK)'!\n"
+ exit 255
+ fi
+ else
+ printf "On 'Red Hat', this '$0' script is ONLY executable\n"
+ printf "on 'RHEL 5' or later!\n"
+ exit 255
+ fi
+ fi
+ JDK_EXE="${JAVA_HOME}/bin/javac"
+ export JDK_EXE
+ JDK_VERSION=`${JAVA_HOME}/bin/javac -version 2>&1 | cut -b7-11`
+ export JDK_VERSION
+elif [ "${PKI_OS}" == "SunOS" ]; then
+ if [ "${JAVA_HOME}" == "" ]; then
+ JAVA_HOME="/usr/java"
+ fi
+ JDK_EXE="${JAVA_HOME}/bin/${PKI_ARCHITECTURE}/javac"
+ export JDK_EXE
+ JDK_VERSION=`${JAVA_HOME}/bin/${PKI_ARCHITECTURE}/javac -version 2>&1 | cut -b7-11`
+ export JDK_VERSION
+ if [ ${PKI_OS_VERSION} -eq 9 ]; then
+ if [ "${JDK_VERSION}" != "1.6.0" ]; then
+ printf "On 'Solaris ${PKI_OS_VERSION}', "
+ printf "this '$0' script is ONLY executable\n"
+ printf "by 'JDK 1.6.0'!\n"
+ exit 255
+ fi
+ if [ ! -x "${JAVA_HOME}/bin/${PKI_ARCHITECTURE}/javac" ] &&
+ [ ! -f "${JAVA_HOME}/jre/lib/rt.jar" ] &&
+ [ ! -d "${JAVA_HOME}/jre/lib/${PKI_ARCHITECTURE}" ] &&
+ [ ! -d "${JAVA_HOME}/jre/lib/${PKI_ARCHITECTURE}/native_threads" ]; then
+ printf "On 'Solaris ${PKI_OS_VERSION}', "
+ printf "this '$0' script is ONLY executable\n"
+ printf "by 'JDK 1.6.0 (Sun JDK)'!\n"
+ exit 255
+ fi
+ else
+ printf "On 'Solaris', this '$0' script is ONLY executable\n"
+ printf "on 'Solaris 9'!\n"
+ exit 255
+ fi
+fi
+
+
+###
+### Setup the appropriate CLASSPATH and LD_LIBRARY_PATH
+### environment variables based upon the platform
+###
+
+if [ ! -f "/usr/share/java/pki/cmscore.jar" ] &&
+ [ ! -f "/usr/share/java/pki/certsrv.jar" ]; then
+ printf "This '$0' script must be COMPILED against\n"
+ printf "the 'pki-common' package!\n"
+ exit 255
+fi
+if [ ! -f "/usr/share/java/pki/nsutil.jar" ]; then
+ printf "This '$0' script must be COMPILED against\n"
+ printf "the 'pki-util' package!\n"
+ exit 255
+fi
+
+if [ ${PKI_OS} = "Linux" ] ; then
+ if [ ! -f "/usr/lib/java/jss4.jar" ]; then
+ printf "This '$0' script must be COMPILED against\n"
+ printf "the 'jss' package!\n"
+ exit 255
+ fi
+ CLASSPATH=${JAVA_HOME}/jre/lib/rt.jar
+ CLASSPATH=/usr/lib/java/jss4.jar:${CLASSPATH}
+ CLASSPATH=/usr/share/java/pki/nsutil.jar:${CLASSPATH}
+ CLASSPATH=/usr/share/java/pki/cmscore.jar:${CLASSPATH}
+ CLASSPATH=/usr/share/java/pki/certsrv.jar:${CLASSPATH}
+ export CLASSPATH
+ if [ ${PKI_ARCHITECTURE} = "i386" ] ; then
+ LD_LIBRARY_PATH=${JAVA_HOME}/jre/lib/${JAVA_ARCHITECTURE}/native_threads
+ LD_LIBRARY_PATH=${JAVA_HOME}/jre/lib/${JAVA_ARCHITECTURE}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ else # "x86_64"
+ LD_LIBRARY_PATH=${JAVA_HOME}/jre/lib/${JAVA_ARCHITECTURE}/native_threads
+ LD_LIBRARY_PATH=${JAVA_HOME}/jre/lib/${JAVA_ARCHITECTURE}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib64:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ fi
+else # "SunOS"
+ if [ ! -f "/usr/lib/java/dirsec/jss4.jar" ]; then
+ printf "This '$0' script must be COMPILED against\n"
+ printf "the 'dirsec-jss' package!\n"
+ exit 255
+ fi
+ CLASSPATH=${JAVA_HOME}/jre/lib/rt.jar
+ CLASSPATH=/usr/lib/java/dirsec/jss4.jar:${CLASSPATH}
+ CLASSPATH=/usr/share/java/pki/nsutil.jar:${CLASSPATH}
+ CLASSPATH=/usr/share/java/pki/cmscore.jar:${CLASSPATH}
+ CLASSPATH=/usr/share/java/pki/certsrv.jar:${CLASSPATH}
+ export CLASSPATH
+ LD_LIBRARY_PATH=${JAVA_HOME}/jre/lib/${PKI_ARCHITECTURE}/native_threads
+ LD_LIBRARY_PATH=${JAVA_HOME}/jre/lib/${PKI_ARCHITECTURE}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/${PKI_ARCHITECTURE}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/${PKI_ARCHITECTURE}/dirsec:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+fi
+
+
+###
+### Set TARGET - identify the complete path to the new classes target directory
+###
+
+TARGET=../classes
+export TARGET
+
+
+###
+### Create the new classes target directory (if it does not already exist)
+###
+
+if [ ! -d ${TARGET} ]; then
+ mkdir -p ${TARGET}
+fi
+
+
+###
+### Compile TxtTo80 - create "CS80LdifParser.class", "DummyAuthManager.class",
+### and "Main.class"
+###
+
+printf "================================================================\n"
+printf "PKI_OS='${PKI_OS}'\n"
+printf "PKI_DISTRIBUTION='${PKI_DISTRIBUTION}'\n"
+printf "PKI_OS_VERSION='${PKI_OS_VERSION}'\n"
+printf "PKI_ARCHITECTURE='${PKI_ARCHITECTURE}'\n"
+printf "JAVA_HOME='${JAVA_HOME}'\n"
+printf "JDK_EXE='${JDK_EXE}'\n"
+printf "JDK_VERSION='${JDK_VERSION}'\n"
+printf "================================================================\n\n"
+
+${JDK_EXE} -d ${TARGET} -classpath ${CLASSPATH} Main.java
+
diff --git a/base/migrate/kra/RecoverKey.class b/base/migrate/kra/RecoverKey.class
new file mode 100755
index 000000000..756380e8d
--- /dev/null
+++ b/base/migrate/kra/RecoverKey.class
Binary files differ
diff --git a/base/migrate/kra/RecoverKey.java b/base/migrate/kra/RecoverKey.java
new file mode 100755
index 000000000..06e5fc55f
--- /dev/null
+++ b/base/migrate/kra/RecoverKey.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.cmstools;
+
+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 org.mozilla.jss.pkcs10.*;
+import org.mozilla.jss.crypto.*;
+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.crypto.X509Certificate;
+import org.mozilla.jss.util.*;
+import org.mozilla.jss.*;
+
+import sun.misc.BASE64Encoder;
+import sun.misc.*;
+
+import java.io.*;
+import java.util.*;
+
+import com.netscape.cmscore.shares.*;
+
+public class RecoverKey {
+
+ public static void main(String args[]) throws Exception
+ {
+ if (args.length != 6) {
+ System.out.println("Usage: RecoverKey <alias directory> <prefix> <password> <pin> <nickname> <kra-key.db path>");
+ System.exit(0);
+ }
+
+ String alias = args[0];
+ String prefix = args[1];
+ String password = args[2];
+ String pin = args[3];
+ String nickname = args[4];
+ String db_path = args[5];
+
+ CryptoManager.InitializationValues vals =
+ new CryptoManager.InitializationValues(alias,
+ prefix, prefix, "secmod.db");
+
+ CryptoManager.initialize(vals);
+ CryptoManager cm = CryptoManager.getInstance();
+
+ CryptoToken token = cm.getInternalKeyStorageToken();
+ token.login(new Password(password.toCharArray()));
+
+ // retrieve public key
+ X509Certificate cert = cm.findCertByNickname(nickname);
+
+ // retrieve encrypted private key material
+ File priFile = new File(db_path);
+ byte priData[] = new byte[(new Long(priFile.length())).intValue()];
+ FileInputStream fi = new FileInputStream(priFile);
+ fi.read(priData);
+ fi.close();
+
+ // recover private key
+ Password pass = new Password(pin.toCharArray());
+ KeyGenerator kg = token.getKeyGenerator(
+ PBEAlgorithm.PBE_SHA1_DES3_CBC);
+ byte iv[] = {0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01};
+ PBEKeyGenParams kgp = new PBEKeyGenParams(pass,
+ iv, 5);
+
+ pass.clear();
+ kg.initialize(kgp);
+ SymmetricKey sk = kg.generate();
+
+ KeyWrapper wrapper = token.getKeyWrapper(KeyWrapAlgorithm.DES3_CBC_PAD);
+ wrapper.initUnwrap(sk, new IVParameterSpec(iv));
+ PrivateKey pk = wrapper.unwrapPrivate(priData,
+ PrivateKey.RSA, cert.getPublicKey());
+
+ System.out.println("=> Private is '" + pk + "'");
+ }
+}
diff --git a/base/migrate/kra/RecoverPin.class b/base/migrate/kra/RecoverPin.class
new file mode 100755
index 000000000..75db9d5f9
--- /dev/null
+++ b/base/migrate/kra/RecoverPin.class
Binary files differ
diff --git a/base/migrate/kra/RecoverPin.java b/base/migrate/kra/RecoverPin.java
new file mode 100755
index 000000000..2ad268c37
--- /dev/null
+++ b/base/migrate/kra/RecoverPin.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.cmstools;
+
+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 org.mozilla.jss.pkcs10.*;
+import org.mozilla.jss.crypto.*;
+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.crypto.X509Certificate;
+import org.mozilla.jss.util.*;
+import org.mozilla.jss.*;
+
+import sun.misc.BASE64Encoder;
+import sun.misc.*;
+
+import java.io.*;
+import java.util.*;
+
+import com.netscape.cmscore.shares.*;
+
+public class RecoverPin {
+
+ public static String getPassword(Hashtable shares) throws Exception
+ {
+ System.out.println("Share size '" + shares.size() + "'");
+ JoinShares j = new JoinShares(shares.size());
+
+ Enumeration e = shares.keys();
+ while (e.hasMoreElements()) {
+ String next = (String) e.nextElement();
+System.out.println("Add share " + (int)(Integer.parseInt(next) + 1));
+ j.addShare(Integer.parseInt(next) + 1,
+ (byte[]) shares.get(next));
+ }
+ byte secret[] = j.recoverSecret();
+ String pwd = new String(secret);
+ return pwd;
+ }
+
+ public static byte[] resizeShare(byte share[]) {
+ byte data[] = new byte[share.length - 2];
+
+ for (int i = 2; i < share.length; i++) {
+ data[i - 2] = share[i];
+ }
+ return data;
+ }
+
+ public static Hashtable getShares(CryptoToken token,
+ Properties kra_mn_p) throws Exception
+ {
+ BufferedReader br = new BufferedReader( new InputStreamReader(System.in));
+ Hashtable v = new Hashtable();
+ Enumeration e = kra_mn_p.keys();
+ int n = Integer.parseInt((String)kra_mn_p.get("n"));
+ for (int i = 0; i < n; i++) {
+ String uid = (String)kra_mn_p.get("uid"+i);
+ System.out.println("Got uid '" + uid + "'");
+
+ String encrypted = (String)kra_mn_p.get("share"+i);
+ System.out.println("Got share '" + encrypted + "'");
+
+ BASE64Decoder decoder = new BASE64Decoder();
+ byte share[] = decoder.decodeBuffer(encrypted);
+ System.out.println("Got encrypted share length '" +
+ share.length + "'");
+
+ System.out.println("Please input password for " + uid + ":");
+ String pwd = br.readLine();
+ System.out.println("Got password '" + pwd + "'");
+
+ Cipher cipher = token.getCipherContext(
+ EncryptionAlgorithm.DES3_CBC_PAD);
+ byte iv[] = {0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01};
+ Password pass = new Password(pwd.toCharArray());
+ KeyGenerator kg = token.getKeyGenerator(
+ PBEAlgorithm.PBE_SHA1_DES3_CBC);
+ PBEKeyGenParams kgp = new PBEKeyGenParams(pass,
+ iv, 5);
+ kg.initialize(kgp);
+ SymmetricKey sk = kg.generate();
+ cipher.initDecrypt(sk, new IVParameterSpec(iv));
+ byte dec[] = cipher.doFinal(share);
+ System.out.println("Got decrypted share length '" + dec.length + "'");
+ System.out.println("Got share[0] '" + dec[0] + "'");
+ System.out.println("Got share[1] '" + dec[1] + "'");
+ byte res[] = resizeShare(dec);
+ v.put(Integer.toString(i), res);
+ }
+ return v;
+ }
+
+ public static void main(String args[]) throws Exception
+ {
+ if (args.length != 4) {
+ System.out.println("Usage: RecoverPin <alias directory> <prefix> <password> <kra-mn.conf path>");
+ System.exit(0);
+ }
+
+ String alias = args[0];
+ String prefix = args[1];
+ String password = args[2];
+ String path_kra_mn = args[3];
+
+ CryptoManager.InitializationValues vals =
+ new CryptoManager.InitializationValues(alias,
+ prefix, prefix, "secmod.db");
+
+ CryptoManager.initialize(vals);
+ CryptoManager cm = CryptoManager.getInstance();
+
+ // load files into properties
+ Properties kra_mn_p = new Properties();
+ kra_mn_p.load(new FileInputStream(path_kra_mn));
+
+ CryptoToken token = cm.getInternalKeyStorageToken();
+ token.login(new Password(password.toCharArray()));
+
+ Hashtable shares = getShares(token, kra_mn_p);
+
+ String pwd = getPassword(shares);
+ System.out.println("=> Pin is '" + pwd + "'");
+ }
+}
diff --git a/base/migrate/kra/readme.txt b/base/migrate/kra/readme.txt
new file mode 100755
index 000000000..8b7b69b49
--- /dev/null
+++ b/base/migrate/kra/readme.txt
@@ -0,0 +1,130 @@
+Date
+
+ Tue Oct 17 16:11:07 PDT 2006
+
+Version
+
+ CMS 6.1
+
+Overview
+
+ In CMS6.1 Data Recovery Manager (DRM), it has deployed a
+ complicated key splitting scheme where software token and
+ hardware token are treated differently.
+
+ Both software and hardware token requires a group of N recovery agents
+ to be present during the configuration. A Pin is randomly generated
+ and splitted into N pieces called shares. Each share is encrypted with
+ a password provided by the individual recovery agent. This is to
+ ensure no single recovery agent to access the pin.
+
+ For software token, during configuration, a storage key pair is
+ generated, and the private key portion is then encrypted by the
+ Pin mentioned above. The encrypted key is stored in a file called
+ kra-key.db in the conf directory. The configuration deletes
+ the private key from the software token. For each recovery
+ operation, the private key is then reconstructed and imported
+ into the software token.
+
+ For hardware token, during configuration, a storage key pair is
+ generated on the selected token, then the configuration changes the
+ hardware token's pin to the randomly generated pin mentioned above.
+ For each recovery operation, the token's pin is reconstructed and
+ private key is accessed.
+
+ To provide migration on the user keys that were encrypted with the
+ storage keys of CS6.1, we need to be able to migrate the public and
+ private keys to the new system. To access the private key, we need
+ to have a way to reconstruct the pin.
+
+ This support package provides 2 utilities that can assist the
+ migration.
+
+Programs
+
+ RecoverPin - This command is to reconstruct the pin. It reads
+ the shares from conf/kra-mn.conf, and prompts for
+ agent passwords. It then reconstructs and prints the
+ pin to the screen.
+
+ RecoverKey - For software token deployment, the encrypted private
+ key is stored in the file conf/kra-key.db. To recover
+ the private key, the user needs to use the pin obtained
+ from RecoverPin. Once the private key is recovered into
+ the security database. The user can use pk12util to
+ migrate key to the new installation. For hardware token
+ deployment, this command is not necessary.
+
+Examples
+
+ Here is an example of RecoverPin usage
+
+ java -classpath <server-root>/bin/cert/jars/cmscore.jar:<server-root>/bin/cert/jars/nsutil.jar:<server-root>/bin/cert/jars/jss3.jar:. RecoverPin <path to alias directory> <prefix> <password> <key splitting scheme file>
+
+ For example,
+
+ java -classpath /home/user/cs61/servers/bin/cert/jars/cmscore.jar:/export/home/user/cs61/servers/bin/cert/jars/nsutil.jar:/export/home/user/cs61/servers/bin/cert/jars/jss3.jar:. RecoverPin /export/home/user/cs61/servers/alias "cert-drm-sunburst-" netscape /export/home/user/cs61/servers/cert-drm/config/kra-mn.conf
+
+ The output is:
+
+ Got uid 'agent1'
+ Got share 'A23UO/q9f40='
+ Got encrypted share length '8'
+ Please input password for agent1:
+ netscape1
+ Got password 'netscape1'
+ Got decrypted share length '2'
+ Got share[0] '0'
+ Got share[1] '0'
+ Got uid 'agent2'
+ Got share 'R+zGVd5zczI='
+ Got encrypted share length '8'
+ Please input password for agent2:
+ netscape2
+ Got password 'netscape2'
+ Got decrypted share length '2'
+ Got share[0] '0'
+ Got share[1] '0'
+ Got uid 'agent3'
+ Got share 'lsipE7cM8jg='
+ Got encrypted share length '8'
+ Please input password for agent3:
+ netscape3
+ Got password 'netscape3'
+ Got decrypted share length '2'
+ Got share[0] '0'
+ Got share[1] '0'
+ Share size '3'
+ Add share 3
+ Add share 2
+ Add share 1
+ => Pin is ''
+
+ Here is an example of RecoverKey usage
+
+ java -classpath <server-root>/bin/cert/jars/cmscore.jar:<server-root>/bin/cert/jars/nsutil.jar:<server-root>/bin/cert/jars/jss3.jar:. RecoverKey <alias path> <prefix> <db password> <pin from RecoverPin> <nickname> <key db path>
+
+ For example,
+
+ java -classpath /export/home/user/cs61/servers/bin/cert/jars/cmscore.jar:/export/home/user/cs61/servers/bin/cert/jars/nsutil.jar:/export/home/user/cs61/servers/bin/cert/jars/jss3.jar:. RecoverKey /export/home/user/cs61/servers/alias cert-drm-sunburst- "netscape" "" "kraStorageCert 1161121005622" /export/home/user/cs61/servers/cert-drm/config/kra-key.db
+
+ The output is:
+
+ => Private is 'org.mozilla.jss.pkcs11.PK11RSAPrivateKey@1ab8f9e'
+
+To make the private and public key exportable via pk12util. You need to first
+backup the storage certificate, delete it, and then import it
+again. For example,
+
+ certutil -d . -P cert-drm-sunburst- \
+ -n "kraStorageCert 1161121005622" -a > storageCert.txt
+
+ certutil -d . -P cert-drm-sunburst- -D -n "kraStorageCert 1161121005622"
+
+ certutil -d . -P cert-drm-sunburst- -A -t "u,u,u" \
+ -n "kraStorageCert 1161121005622" -i storageCert.txt
+
+Finally, you can export the private and public key using pk12util
+
+ pk12util -o storage.p12 -d . -P cert-drm-sunburst- \
+ -n "kraStorageCert 1161121005622"
diff --git a/base/native-tools/CMakeLists.txt b/base/native-tools/CMakeLists.txt
new file mode 100644
index 000000000..0ccebe578
--- /dev/null
+++ b/base/native-tools/CMakeLists.txt
@@ -0,0 +1,3 @@
+project(native-tools)
+
+add_subdirectory(src)
diff --git a/base/native-tools/LICENSE b/base/native-tools/LICENSE
new file mode 100644
index 000000000..e281f4362
--- /dev/null
+++ b/base/native-tools/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/base/native-tools/doc/README b/base/native-tools/doc/README
new file mode 100644
index 000000000..01b11a7a3
--- /dev/null
+++ b/base/native-tools/doc/README
@@ -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.
+#
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+ Certificate System
+ Native Command Line Utilities
+
+
+Command Line Utility Purpose
+==============================================================================
+bulkissuance A command line utility utilized
+ to send either a KEYGEN or CRMF
+ enrollment request to the bulk
+ issuance interface for the
+ automatic creation of
+ certificates.
+
+bulkissuance.data An example data file for use
+ with the bulkissuance tool.
+
+revoker A command line tool which may be
+ conveniently utilized to
+ automate user management scripts
+ used to revoke certificates.
+
+setpin A command line tool utilized
+ to enable Certificate
+ System to utilize PIN-based
+ authentication.
+
+setpin.conf The configuration file utilized
+ by the setpin command line
+ utility.
+
+tkstool A command line tool utilized
+ to construct DES 2 symmetric
+ keys utilized in conjunction
+ with the Certificate
+ System Token Key Service
+ subsystem.
+
diff --git a/base/native-tools/src/CMakeLists.txt b/base/native-tools/src/CMakeLists.txt
new file mode 100644
index 000000000..c727a9a49
--- /dev/null
+++ b/base/native-tools/src/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_subdirectory(p7tool)
+add_subdirectory(revoker)
+add_subdirectory(setpin)
+add_subdirectory(sslget)
+add_subdirectory(tkstool)
diff --git a/base/native-tools/src/bulkissuance/CMakeLists.txt b/base/native-tools/src/bulkissuance/CMakeLists.txt
new file mode 100644
index 000000000..31df27306
--- /dev/null
+++ b/base/native-tools/src/bulkissuance/CMakeLists.txt
@@ -0,0 +1,37 @@
+project(bulkissuance C)
+
+set(BULKISSUANCE_PRIVATE_INCLUDE_DIRS
+ ${CMAKE_BINARY_DIR}
+ ${NSPR_INCLUDE_DIRS}
+ ${NSS_INCLUDE_DIRS}
+)
+
+set(BULKISSUANCE_LINK_LIBRARIES
+ ${NSPR_LIBRARIES}
+ ${NSS_LIBRARIES}
+)
+
+set(bulkissuance_SRCS
+ bulkissuance.c
+ getopt.c
+)
+
+include_directories(${BULKISSUANCE_PRIVATE_INCLUDE_DIRS})
+
+add_executable(bulkissuance ${bulkissuance_SRCS})
+
+target_link_libraries(bulkissuance ${BULKISSUANCE_LINK_LIBRARIES})
+
+install(
+ TARGETS bulkissuance
+ RUNTIME DESTINATION ${BIN_INSTALL_DIR}
+ LIBRARY DESTINATION ${LIB_INSTALL_DIR}
+ ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
+)
+
+install(
+ FILES
+ bulkissuance.data
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/pki/native-tools/
+)
diff --git a/base/native-tools/src/bulkissuance/bulkissuance.c b/base/native-tools/src/bulkissuance/bulkissuance.c
new file mode 100644
index 000000000..ec33e8a7a
--- /dev/null
+++ b/base/native-tools/src/bulkissuance/bulkissuance.c
@@ -0,0 +1,807 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 ---
+ */
+
+/* vi: set ts=4 sw=4 : */
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#if defined(XP_UNIX)
+#include <unistd.h>
+#endif
+
+#include "ssl.h"
+
+#include "prerror.h"
+
+#include "pk11func.h"
+#include "secitem.h"
+
+
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+
+#include "nspr.h"
+#include "prio.h"
+#include "prnetdb.h"
+#include "nss.h"
+
+/*from nss2.8.4 secopt.h*/
+#ifdef XP_PC
+
+/*
+** This comes from the AT&T public-domain getopt published in mod.sources
+** (i.e., comp.sources.unix before the great Usenet renaming).
+*/
+
+extern int opterr;
+extern int optind;
+extern int optopt;
+extern char *optarg;
+
+#ifdef _WIN32
+static void do_opterr(const char *s, int c, char * const av[]);
+#define ERR(s, c) do_opterr(s, c, av)
+#else
+#define ERR(s, c) /* Win16 doesn't do stderr */
+#endif
+
+/*
+** Return options and their values from the command line.
+*/
+int getopt(int ac, char * const av[], const char * opts);
+#else
+#if defined(LINUX)
+#include <getopt.h>
+#endif
+#endif /* XP_PC */
+/*end secopt.h*/
+
+#define VERSIONSTRING "$Revision$ ($Date$)"
+#define MAXLEN 50000
+
+#ifndef PORT_Sprintf
+#define PORT_Sprintf sprintf
+#endif
+
+#ifndef PORT_Strstr
+#define PORT_Strstr strstr
+#endif
+
+#ifndef PORT_Malloc
+#define PORT_Malloc PR_Malloc
+#endif
+
+#define RD_BUF_SIZE (60 * 1024)
+
+#define PRINTF if (verbose) printf
+#define FPRINTF if (verbose) fprintf
+#define FPUTS if (verbose) fputs
+
+#define MAX_SERIAL_LEN 8192
+
+int MakeCertOK=1;
+
+int verbose;
+SECItem bigBuf;
+
+
+static char *ownPasswd( PK11SlotInfo *slot, PRBool retry, void *arg)
+{
+ char *passwd = NULL;
+
+ if ( (!retry) && arg ) {
+ passwd = PL_strdup((char *)arg);
+ }
+
+ return passwd;
+}
+
+static void
+Usage(const char *progName)
+{
+ fprintf( stderr,
+ "\n" );
+ fprintf( stderr,
+ "Description: A command-line utility used to send either a KEYGEN or a\n"
+ " Certificate Request Message Format (CRMF) enrollment\n"
+ " request to the bulk issuance interface of a\n"
+ " Certificate Authority (CA) for the automatic\n"
+ " creation of certificates.\n\n\n" );
+ fprintf( stderr,
+ "Usage:\n\n"
+ " %s -n rsa_nickname [-p password | -w pwfile ]\n"
+ " [-d dbdir] [-v] [-V] [-f inputFile] hostname[:port]\n\n"
+ " where:\n\n"
+ " -n rsa_nickname nickname of the Agent Certificate\n"
+ " [-p password | -w pwfile] password OR file containing password\n"
+ " [-d dbdir] database directory\n"
+ " [-v] verbose mode\n"
+ " [-V] version of %s\n"
+ " [-f inputFile] file containing an http request\n"
+ " which gets sent to the hostname[:port]\n"
+ " hostname[:port] machine name with optional port address\n\n\n",
+ progName, progName );
+ fprintf( stderr,
+ "Example (using the example inputFile called \"bulkissuance.data\"):\n\n" );
+ fprintf( stderr,
+ " (1) cd <server-root>/bin/cert/tools\n" );
+ fprintf( stderr,
+ " (2) cp <client-database>/cert8.db .\n" );
+ fprintf( stderr,
+ " (3) cp <client-database>/key3.db .\n" );
+ fprintf( stderr,
+ " (4) Ensure that the agent certificate is\n"
+ " inside these cert8.db/key3.db databases.\n"
+ " (for this example, call it \"CS Agent\'s CS ID\")\n" );
+ fprintf( stderr,
+ " (5) ./bulkissuance.sh -n \"CS Agent\'s CS ID\" -p password\n"
+ " -d . -f bulkissuance.data example.com:8100\n\n" );
+ exit( 1 );
+}
+
+
+static void
+errWarn(const char * funcString)
+{
+ PRErrorCode perr = PR_GetError();
+
+ FPRINTF(stderr, "exit after %s with error %d:\n", funcString,perr );
+}
+
+static void
+errExit(const char * funcString)
+{
+ errWarn(funcString);
+ exit(1);
+}
+
+/* This invokes the "default" AuthCert handler in libssl.
+** The only reason to use this one is that it prints out info as it goes.
+*/
+static SECStatus
+mySSLAuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig,
+ PRBool isServer)
+{
+ SECStatus rv;
+ CERTCertificate * peerCert;
+
+ peerCert = SSL_PeerCertificate(fd);
+
+ PRINTF("Subject: %s\nIssuer : %s\n",
+ peerCert->subjectName, peerCert->issuerName);
+ /* invoke the "default" AuthCert handler. */
+ rv = SSL_AuthCertificate(arg, fd, checkSig, isServer);
+
+ if (rv == SECSuccess) {
+ FPUTS("-- SSL3: Server Certificate Validated.\n", stderr);
+ }
+ /* error, if any, will be displayed by the Bad Cert Handler. */
+ return rv;
+}
+
+static SECStatus
+myBadCertHandler( void *arg, PRFileDesc *fd)
+{
+ /* int err = PR_GetError(); */
+ /* fprintf(stderr, "-- SSL: Server Certificate Invalid, err %d.\n%s\n",
+ err, SECU_Strerror(err)); */
+ return (MakeCertOK ? SECSuccess : SECFailure);
+}
+
+
+static SECStatus
+my_GetClientAuthData(void * arg,
+ PRFileDesc * sock,
+ struct CERTDistNamesStr * caNames,
+ struct CERTCertificateStr ** pRetCert,
+ struct SECKEYPrivateKeyStr **pRetKey)
+{
+ CERTCertificate * cert = NULL;
+ SECKEYPrivateKey * privkey = NULL;
+ char * chosenNickName = (char *)arg; /* CONST */
+ void * proto_win = NULL;
+ SECStatus rv = SECFailure;
+
+ FPRINTF(stderr,"Called mygetclientauthdata - nickname = %s\n",chosenNickName);
+
+ proto_win = SSL_RevealPinArg(sock);
+
+ if (chosenNickName) {
+ cert = PK11_FindCertFromNickname(chosenNickName, proto_win);
+ FPRINTF(stderr," mygetclientauthdata - cert = %p\n", cert);
+ if ( cert ) {
+ privkey = PK11_FindKeyByAnyCert(cert, proto_win);
+ FPRINTF(stderr," mygetclientauthdata - privkey = %p\n", privkey);
+ if ( privkey ) {
+ rv = SECSuccess;
+ } else {
+ CERT_DestroyCertificate(cert);
+ }
+ }
+ } else { /* no name given, automatically find the right cert. */
+ CERTCertNicknames * names;
+ int i;
+
+ names = CERT_GetCertNicknames(CERT_GetDefaultCertDB(),
+ SEC_CERT_NICKNAMES_USER, proto_win);
+ if (names != NULL) {
+ for (i = 0; i < names->numnicknames; i++) {
+ cert = PK11_FindCertFromNickname(names->nicknames[i],proto_win);
+ if ( !cert )
+ continue;
+ /* Only check unexpired certs */
+ if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_TRUE) !=
+ secCertTimeValid ) {
+ CERT_DestroyCertificate(cert);
+ continue;
+ }
+ rv = NSS_CmpCertChainWCANames(cert, caNames);
+ if ( rv == SECSuccess ) {
+ privkey = PK11_FindKeyByAnyCert(cert, proto_win);
+ if ( privkey )
+ break;
+ }
+ rv = SECFailure;
+ CERT_DestroyCertificate(cert);
+ }
+ CERT_FreeNicknames(names);
+ }
+ }
+ if (rv == SECSuccess) {
+ *pRetCert = cert;
+ *pRetKey = privkey;
+ }
+ return rv;
+}
+
+
+
+
+static void
+printSecurityInfo(PRFileDesc *fd)
+{
+ char * cp; /* bulk cipher name */
+ char * ip; /* cert issuer DN */
+ char * sp; /* cert subject DN */
+ int op; /* High, Low, Off */
+ int kp0; /* total key bits */
+ int kp1; /* secret key bits */
+ int result;
+
+ static int only_once;
+
+ if (! only_once++ && fd) {
+ result = SSL_SecurityStatus(fd, &op, &cp, &kp0, &kp1, &ip, &sp);
+ if (result != SECSuccess)
+ return;
+#if 0
+ PRINTF("bulk cipher %s, %d secret key bits, %d key bits, status: %d\n"
+ "subject DN: %s\n"
+ "issuer DN: %s\n", cp, kp1, kp0, op, sp, ip);
+#else
+ PRINTF("bulk cipher %s, %d secret key bits, %d key bits, status: %d\n",
+ cp, kp1, kp0, op);
+#endif
+ PR_Free(cp);
+ PR_Free(ip);
+ PR_Free(sp);
+ }
+
+}
+
+
+PRBool useModelSocket = PR_TRUE;
+
+static const char outHeader[] = {
+ "HTTP/1.0 200 OK\r\n"
+ "Server: Netscape-Enterprise/2.0a\r\n"
+ "Date: Tue, 26 Aug 1997 22:10:05 GMT\r\n"
+ "Content-type: text/plain\r\n"
+ "\r\n"
+};
+
+
+static PRInt32
+do_writes(
+ void * a
+)
+{
+ PRFileDesc * ssl_sock = (PRFileDesc *)a;
+ PRUint32 sent = 0;
+ PRInt32 count = 0;
+
+ while (sent < bigBuf.len) {
+
+ count = PR_Write(ssl_sock, bigBuf.data + sent, bigBuf.len - sent);
+ if (count < 0) {
+ errWarn("PR_Write bigBuf");
+ exit(4);
+ break;
+ }
+ FPRINTF(stderr, "PR_Write wrote %d bytes from bigBuf\n", count );
+ FPRINTF(stderr, "bytes: [%*s]\n",count,bigBuf.data);
+
+ sent += (PRUint32)count;
+ }
+ if (count >= 0) { /* last write didn't fail. */
+ FPRINTF(stderr, "do_writes shutting down send socket\n");
+ /* PR_Shutdown(ssl_sock, PR_SHUTDOWN_SEND); */
+ }
+
+ FPRINTF(stderr, "do_writes exiting with (failure = %d)\n",
+ (sent < bigBuf.len) == SECFailure);
+ return (sent < bigBuf.len) ? SECFailure : SECSuccess;
+}
+
+
+
+
+static SECStatus
+do_io( PRFileDesc *ssl_sock, int connection)
+{
+ int countRead = 0;
+ PRInt32 rv;
+ char *buf;
+ int first=1;
+
+ buf = PR_Malloc(RD_BUF_SIZE);
+ if (!buf) exit(5);
+
+
+ /* send the http request here. */
+
+ rv = do_writes(ssl_sock);
+
+ if (rv == SECFailure) {
+ errWarn("returning from after calling do_writes");
+ PR_Free(buf);
+ buf = 0;
+ exit(6);
+ }
+ printSecurityInfo(ssl_sock);
+
+ /* read until EOF */
+ while (1) {
+ rv = PR_Read(ssl_sock, buf, RD_BUF_SIZE);
+ if (rv == 0) {
+ break; /* EOF */
+ }
+ if (rv < 0) {
+ errWarn("PR_Read");
+ exit(1);
+ }
+
+ countRead += rv;
+ FPRINTF(stderr, "connection %d read %d bytes (%d total).\n",
+ connection, rv, countRead );
+ FPRINTF(stderr, "these bytes read: ");
+ if (verbose) {
+ PR_Write(PR_STDERR,buf,rv);
+ }
+
+ if (first) {
+ first=0;
+ if (rv < 13) {
+ errWarn("not enough bytes read in first read");
+ exit(2);
+ } else {
+ if ( ! PL_strnstr(buf,"200",13)) {
+ exit(3);
+ }
+ }
+ }
+ }
+ PR_Free(buf);
+ buf = 0;
+
+ /* Caller closes the socket. */
+
+ FPRINTF(stderr,
+ "connection %d read %d bytes total. -----------------------------\n",
+ connection, countRead);
+
+ return SECSuccess; /* success */
+}
+
+static int
+do_connect(
+ PRNetAddr *addr,
+ PRFileDesc *model_sock,
+ int connection)
+{
+ PRFileDesc * ssl_sock;
+ PRFileDesc * tcp_sock;
+ PRStatus prStatus;
+ SECStatus result;
+ int rv = SECSuccess;
+ PRSocketOptionData opt;
+
+ int family = PR_NetAddrFamily( addr );
+
+ tcp_sock = PR_OpenTCPSocket( family );
+ if (tcp_sock == NULL) {
+ errExit("PR_OpenTCPSocket on tcp socket");
+ }
+
+ opt.option = PR_SockOpt_Nonblocking;
+ opt.value.non_blocking = PR_FALSE;
+ prStatus = PR_SetSocketOption(tcp_sock, &opt);
+ if (prStatus != PR_SUCCESS) {
+ if( tcp_sock != NULL ) {
+ PR_Close(tcp_sock);
+ tcp_sock = NULL;
+ }
+ /* Don't return SECFailure? */
+ return SECSuccess;
+ }
+
+ prStatus = PR_Connect(tcp_sock, addr, PR_SecondsToInterval(3));
+ if (prStatus != PR_SUCCESS) {
+ errWarn("PR_Connect");
+ if( tcp_sock != NULL ) {
+ PR_Close(tcp_sock);
+ tcp_sock = NULL;
+ }
+ exit(6);
+ }
+
+ ssl_sock = SSL_ImportFD(model_sock, tcp_sock);
+ /* XXX if this import fails, close tcp_sock and return. */
+ if (!ssl_sock) {
+ if( tcp_sock != NULL ) {
+ PR_Close(tcp_sock);
+ tcp_sock = NULL;
+ }
+ exit(7);
+ }
+
+ rv = SSL_ResetHandshake(ssl_sock, /* asServer */ 0);
+ if (rv != SECSuccess) {
+ errWarn("SSL_ResetHandshake");
+ exit(8);
+ }
+
+ result = do_io( ssl_sock, connection);
+
+ if( ssl_sock != NULL ) {
+ PR_Close(ssl_sock);
+ ssl_sock = NULL;
+ }
+ return SECSuccess;
+}
+
+#if 0
+/* Returns IP address for hostname as PRUint32 in Host Byte Order.
+** Since the value returned is an integer (not a string of bytes),
+** it is inherently in Host Byte Order.
+*/
+static PRUint32
+getIPAddress(const char * hostName)
+{
+ const unsigned char *p;
+ PRStatus prStatus;
+ PRUint32 rv;
+ PRHostEnt prHostEnt;
+ char scratch[PR_NETDB_BUF_SIZE];
+
+ prStatus = PR_GetHostByName(hostName, scratch, sizeof scratch, &prHostEnt);
+ if (prStatus != PR_SUCCESS)
+ errExit("PR_GetHostByName");
+
+#undef h_addr
+#define h_addr h_addr_list[0] /* address, for backward compatibility */
+
+ p = (const unsigned char *)(prHostEnt.h_addr); /* in Network Byte order */
+ FPRINTF(stderr, "%s -> %d.%d.%d.%d\n", hostName, p[0], p[1], p[2], p[3]);
+ rv = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+ return rv;
+}
+#endif
+
+static void
+client_main(
+ unsigned short port,
+ int connections,
+ SECKEYPrivateKey ** privKey,
+ CERTCertificate ** cert,
+ const char * hostName,
+ char * nickName)
+{
+ PRFileDesc *model_sock = NULL;
+ int rv;
+ PRAddrInfo *ai;
+ void *iter;
+ PRNetAddr addr;
+ int family = PR_AF_INET;
+
+
+
+ FPRINTF(stderr, "port: %d\n", port);
+
+ /* all suites except RSA_NULL_MD5 are enabled by Domestic Policy */
+ NSS_SetDomesticPolicy();
+
+ /* all the SSL2 and SSL3 cipher suites are enabled by default. */
+ /* SSL_CipherPrefSetDefault(0xC005 */
+ /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA */
+ /*, PR_TRUE); */
+
+ /*
+ * Rifle through the values for the host
+ */
+
+ ai = PR_GetAddrInfoByName(hostName, PR_AF_UNSPEC, PR_AI_ADDRCONFIG);
+ if (ai) {
+ FPRINTF( stderr, "addr='%s'\n", PR_GetCanonNameFromAddrInfo( ai ) );
+ iter = NULL;
+ while ((iter = PR_EnumerateAddrInfo(iter, ai, 0, &addr)) != NULL) {
+ family = PR_NetAddrFamily(&addr);
+ FPRINTF( stderr, "family='%d'\n", family );
+ break;
+ }
+ PR_FreeAddrInfo(ai);
+ }
+
+ PR_SetNetAddr( PR_IpAddrNull, family, port, &addr );
+
+ model_sock = PR_OpenTCPSocket( family );
+ if (model_sock == NULL) {
+ errExit("PR_OpenTCPSocket on tcp socket");
+ }
+
+ /* Should we really be re-using the same socket? */
+ model_sock = SSL_ImportFD(NULL, model_sock);
+
+
+ /* check on success of call to SSL_ImportFD() */
+ if (model_sock == NULL) {
+ errExit("SSL_ImportFD");
+ }
+
+ /* enable ECC cipher also */
+
+ /* do SSL configuration. */
+
+ rv = SSL_OptionSet(model_sock, SSL_SECURITY, 1);
+ if (rv < 0) {
+ if( model_sock != NULL ) {
+ PR_Close( model_sock );
+ model_sock = NULL;
+ }
+ errExit("SSL_OptionSet SSL_SECURITY");
+ }
+
+ SSL_SetURL(model_sock, hostName);
+
+ SSL_AuthCertificateHook(model_sock, mySSLAuthCertificate,
+ (void *)CERT_GetDefaultCertDB());
+
+ SSL_BadCertHook(model_sock, myBadCertHandler, NULL);
+
+ SSL_GetClientAuthDataHook(model_sock,
+ (SSLGetClientAuthData)my_GetClientAuthData,
+ nickName);
+
+ /* I'm not going to set the HandshakeCallback function. */
+
+ /* end of ssl configuration. */
+
+ rv = do_connect(&addr, model_sock, 1);
+
+ if( model_sock != NULL ) {
+ PR_Close( model_sock );
+ model_sock = NULL;
+ }
+}
+
+
+static SECStatus
+createRequest(char *progName, char *path)
+{
+ char *temp;
+ char * newstr;
+ FILE *fp;
+
+ temp = (char *)malloc(MAXLEN);
+ fp = fopen(path, "r");
+ if (fp == NULL) {
+ fputs("Input file must be provided on command line in this version"
+ " of bulk issuance client.\n", stderr);
+ Usage(progName);
+ } else {
+ temp = fgets(temp, MAXLEN, fp);
+ if (temp == NULL) {
+ fclose(fp);
+ fputs("File is empty\n", stderr);
+ exit(1);
+ }
+
+ fclose(fp);
+ }
+
+ newstr = PR_smprintf("%s\r\n\r\n", temp);
+/*
+ "GET /ca/bulkissuance?csrRequestorName=++&CN=a&UID=a&E=a&OU=&O=&C=US&email=true&ssl_client=true&digital_signature=true&non_repudiation=true&key_encipherment=true&challengePassword=&confirmChallengePassword=&csrRequestorEmail=a&csrRequestorPhone=&csrRequestorComments=&CRMFRequest=MIICTDCB%2BzCB8wICJ4EwgbWAAQKlQDA%2BMQswCQYDVQQGEwJVUzERMA8GCgmSJomT%0D%0A8ixkAQETAWExCjAIBgNVBAMTAWExEDAOBgkqhkiG9w0BCQEWAWGmXDANBgkqhkiG%0D%0A9w0BAQEFAANLADBIAkEA3R3vkvw3%2F4f5eDJZszB2%2B8BhWtNgwX97KV%2FydZ1kPlei%0D%0AcJwIcHfLbp6tRYs2iKAxbTuw01H1P9gdUIx1nY7R0QIDAQABqRAwDgYDVR0PAQH%2F%0D%0ABAQDAgUgMDUwGwYJKwYBBQUHBQECDA5hdXRoZW50aWNhdG9yADAWBgkrBgEFBQcF%0D%0AAQEMCXJlZ1Rva2VuAKIDgQEBMIIBSjCB8wICRGswgbWAAQKlQDA%2BMQswCQYDVQQG%0D%0AEwJVUzERMA8GCgmSJomT8ixkAQETAWExCjAIBgNVBAMTAWExEDAOBgkqhkiG9w0B%0D%0ACQEWAWGmXDANBgkqhkiG9w0BAQEFAANLADBIAkEAuf9KVCouLB6rKI290XpSghLe%0D%0APtYxSBdGv5gnzYVyokz9DPSSTeRBCUQDGWCVMIgMrUMABK0tkXPlVrD8lylVWQID%0D%0AAQABqRAwDgYDVR0PAQH%2FBAQDAgeAMDUwGwYJKwYBBQUHBQECDA5hdXRoZW50aWNh%0D%0AdG9yADAWBgkrBgEFBQcFAQEMCXJlZ1Rva2VuAKFSMA0GCSqGSIb3DQEBBQUAA0EA%0D%0Aq0tNDOzqcDI%2BwQ6gZMsCbYLh7MBBAzJo8Z67ddx%2BOS%2FZjCAtAbdabeazQnu0UOfN%0D%0A0HwLPDcNuurcvw4y604ang%3D%3D&cmmfResponse=true&certNickname=E%3Da%2C+CN%3Da%2C+UID%3Da%2C+C%3DUS&subject=E%3Da%2C+CN%3Da%2C+UID%3Da%2C+C%3DUS&requestFormat=keygen&certType=client HTTP/1.0\r\n"
+ "Content-Type: application/x-www-form-urlencoded\r\n"
+ "\r\n");
+*/
+
+ bigBuf.data = (unsigned char *)newstr;
+
+ FPUTS((char *)bigBuf.data, stderr);
+
+ bigBuf.len = PORT_Strlen((char *)bigBuf.data);
+
+ free(temp);
+
+ return SECSuccess;
+}
+
+int
+main(int argc, char **argv)
+{
+ const char * dir = ".";
+ char * hostName = NULL;
+ char * nickName = NULL;
+ char * progName = NULL;
+ char * tmp = NULL;
+ CERTCertificate * cert [kt_kea_size] = { NULL };
+ SECKEYPrivateKey * privKey[kt_kea_size] = { NULL };
+ int optchar;
+ int connections = 1;
+ int tmpI;
+ unsigned short port = 443;
+ SECStatus rv;
+ char * passwd = NULL;
+ char * passwdfile = NULL;
+ char path[1000];
+ FILE *fp;
+ char pwbuf[256];
+ int co;
+ char *crlf;
+
+ /* Call the NSPR initialization routines */
+ PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
+
+ tmp = strrchr(argv[0], '/');
+ tmp = tmp ? tmp + 1 : argv[0];
+ progName = strrchr(tmp, '\\');
+ progName = progName ? progName + 1 : tmp;
+
+
+ while ((optchar = getopt(argc, argv, "Vd:n:p:f:v")) != -1) {
+ switch(optchar) {
+
+ case 'V':
+ PRINTF("%s\n",VERSIONSTRING);
+ break;
+
+ case 'd':
+ dir = optarg;
+ break;
+
+ case 'n':
+ nickName = optarg;
+ break;
+
+ case 'p':
+ passwd = optarg;
+ break;
+
+ case 'w':
+ passwdfile = optarg;
+ break;
+
+ case 'v':
+ verbose++;
+ break;
+
+ case 'f':
+ strcpy(path, optarg);
+ break;
+
+ default:
+ case '?':
+ Usage(progName);
+ break;
+
+ }
+ }
+ if (optind != argc - 1)
+ Usage(progName);
+
+ hostName = argv[optind];
+ tmp = strchr(hostName, ':');
+ if (tmp) {
+ *tmp++ = 0;
+ tmpI = atoi(tmp);
+ if (tmpI <= 0)
+ Usage(progName);
+ port = (unsigned short)tmpI;
+ }
+
+ if (!nickName)
+ Usage(progName);
+
+ createRequest(progName, path);
+
+ if (passwdfile) {
+ fp = fopen(passwdfile,"r");
+ if (!fp) { fprintf(stderr, "Couldn't open password file\n"); exit(7); }
+ co = fread(pwbuf,1,256,fp);
+ pwbuf[co] = '\0';
+ crlf = PL_strchr(pwbuf,'\n');
+ if (crlf) {
+ *crlf = '\0';
+ }
+ passwd = pwbuf;
+ }
+
+ /* set our password function */
+ if (passwd == NULL) {
+ PRINTF("Password must be provided on command line in this version of revoker.\n");
+ Usage(progName);
+ }
+ PK11_SetPasswordFunc(ownPasswd);
+
+ /* Call the libsec initialization routines */
+ rv = NSS_Init(dir);
+ if (rv != SECSuccess) {
+ fputs("NSS_Init failed.\n", stderr);
+ exit(1);
+ }
+
+ cert[kt_rsa] = PK11_FindCertFromNickname(nickName, passwd);
+ if (cert[kt_rsa] == NULL) {
+ fprintf(stderr, "Can't find certificate %s\n", nickName);
+ exit(1);
+ }
+
+ privKey[kt_rsa] = PK11_FindKeyByAnyCert(cert[kt_rsa], passwd);
+ if (privKey[kt_rsa] == NULL) {
+ fprintf(stderr, "Can't find Private Key for cert %s (possibly incorrect password)\n", nickName);
+ exit(1);
+ }
+
+
+ client_main(port, connections, privKey, cert, hostName, nickName);
+
+ NSS_Shutdown();
+ PR_Cleanup();
+ return 0;
+}
+
diff --git a/base/native-tools/src/bulkissuance/bulkissuance.data b/base/native-tools/src/bulkissuance/bulkissuance.data
new file mode 100644
index 000000000..1d68c26a1
--- /dev/null
+++ b/base/native-tools/src/bulkissuance/bulkissuance.data
@@ -0,0 +1 @@
+GET /ca/agent/ca/bulkissuance?csrRequestorName=++&CN=a&UID=a&E=a&OU=&O=&C=US&email=true&ssl_client=true&digital_signature=true&non_repudiation=true&key_encipherment=true&challengePassword=&confirmChallengePassword=&csrRequestorEmail=a&csrRequestorPhone=&csrRequestorComments=&CRMFRequest=MIICTDCB%2BzCB8wICJ4EwgbWAAQKlQDA%2BMQswCQYDVQQGEwJVUzERMA8GCgmSJomT%0D%0A8ixkAQETAWExCjAIBgNVBAMTAWExEDAOBgkqhkiG9w0BCQEWAWGmXDANBgkqhkiG%0D%0A9w0BAQEFAANLADBIAkEA3R3vkvw3%2F4f5eDJZszB2%2B8BhWtNgwX97KV%2FydZ1kPlei%0D%0AcJwIcHfLbp6tRYs2iKAxbTuw01H1P9gdUIx1nY7R0QIDAQABqRAwDgYDVR0PAQH%2F%0D%0ABAQDAgUgMDUwGwYJKwYBBQUHBQECDA5hdXRoZW50aWNhdG9yADAWBgkrBgEFBQcF%0D%0AAQEMCXJlZ1Rva2VuAKIDgQEBMIIBSjCB8wICRGswgbWAAQKlQDA%2BMQswCQYDVQQG%0D%0AEwJVUzERMA8GCgmSJomT8ixkAQETAWExCjAIBgNVBAMTAWExEDAOBgkqhkiG9w0B%0D%0ACQEWAWGmXDANBgkqhkiG9w0BAQEFAANLADBIAkEAuf9KVCouLB6rKI290XpSghLe%0D%0APtYxSBdGv5gnzYVyokz9DPSSTeRBCUQDGWCVMIgMrUMABK0tkXPlVrD8lylVWQID%0D%0AAQABqRAwDgYDVR0PAQH%2FBAQDAgeAMDUwGwYJKwYBBQUHBQECDA5hdXRoZW50aWNh%0D%0AdG9yADAWBgkrBgEFBQcFAQEMCXJlZ1Rva2VuAKFSMA0GCSqGSIb3DQEBBQUAA0EA%0D%0Aq0tNDOzqcDI%2BwQ6gZMsCbYLh7MBBAzJo8Z67ddx%2BOS%2FZjCAtAbdabeazQnu0UOfN%0D%0A0HwLPDcNuurcvw4y604ang%3D%3D&cmmfResponse=true&certNickname=E%3Da%2C+CN%3Da%2C+UID%3Da%2C+C%3DUS&subject=E%3Da%2C+CN%3Da%2C+UID%3Da%2C+C%3DUS&requestFormat=CRMF&certType=client HTTP/1.0
diff --git a/base/native-tools/src/bulkissuance/getopt.c b/base/native-tools/src/bulkissuance/getopt.c
new file mode 100644
index 000000000..7554e1a14
--- /dev/null
+++ b/base/native-tools/src/bulkissuance/getopt.c
@@ -0,0 +1,126 @@
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ *
+ * END COPYRIGHT BLOCK **/
+#ifdef XP_PC
+
+/*
+** This comes from the AT&T public-domain getopt published in mod.sources
+** (i.e., comp.sources.unix before the great Usenet renaming).
+*/
+
+#include <stdio.h>
+#include <string.h> /* for str*() */
+#include <io.h> /* for write() */
+
+int opterr = 1; /* boolean flag, says "report error on stderr." */
+int optind = 1; /* index to element of argv from which options are
+ ** being parsed. */
+int optopt = 0; /* option character */
+char *optarg; /* ptr to option's parameter arg. */
+
+#ifdef _WIN32
+static void
+do_opterr(const char *s, int c, char * const av[])
+{
+ if (opterr) {
+ char buff[2];
+ int fd = _fileno(stderr);
+
+ buff[0] = (char)c;
+ buff[1] = '\n';
+ (void)write(fd, av[0], strlen(av[0]));
+ (void)write(fd, s, strlen(s));
+ (void)write(fd, buff, 2);
+ }
+}
+#define ERR(s, c) do_opterr(s, c, av)
+#else
+#define ERR(s, c) /* Win16 doesn't do stderr */
+#endif
+
+/*
+** Return options and their values from the command line.
+*/
+int
+getopt(int ac, char * const av[], const char * opts)
+{
+ static int i = 1; /* offset of current option char in current arg. */
+ char *p; /* opt char in opts that matched. */
+
+ /* Move to next value from argv? */
+ if (i == 1) {
+ if (optind >= ac || av[optind][0] != '-' || av[optind][1] == '\0')
+ return EOF;
+ if (strcmp(av[optind], "--") == 0) {
+ optind++;
+ return EOF;
+ }
+ }
+
+ /* Get next option character. */
+ if ((optopt = av[optind][i]) == ':' ||
+ (p = strchr(opts, optopt)) == NULL) {
+ ERR(": illegal option -- ", optopt);
+ if (av[optind][++i] == '\0') {
+ optind++;
+ i = 1;
+ }
+ return '?';
+ }
+
+ /* Snarf argument? */
+ if (*++p == ':') {
+ if (av[optind][i + 1] != '\0')
+ optarg = &av[optind++][i + 1];
+ else {
+ if (++optind >= ac) {
+ ERR(": option requires an argument -- ", optopt);
+ i = 1;
+ return '?';
+ }
+ optarg = av[optind++];
+ }
+ i = 1;
+ } else {
+ if (av[optind][++i] == '\0') {
+ i = 1;
+ optind++;
+ }
+ optarg = NULL;
+ }
+
+ return optopt;
+}
+
+#endif /* XP_PC */
diff --git a/base/native-tools/src/p7tool/CMakeLists.txt b/base/native-tools/src/p7tool/CMakeLists.txt
new file mode 100644
index 000000000..6adfbedb7
--- /dev/null
+++ b/base/native-tools/src/p7tool/CMakeLists.txt
@@ -0,0 +1,33 @@
+project(p7tool C)
+
+set(P7TOOL_PRIVATE_INCLUDE_DIRS
+ ${CMAKE_BINARY_DIR}
+ ${NSPR_INCLUDE_DIRS}
+ ${NSS_INCLUDE_DIRS}
+)
+
+set(P7TOOL_LINK_LIBRARIES
+ ${NSPR_LIBRARIES}
+ ${NSS_LIBRARIES}
+)
+
+set(p7tool_SRCS
+ secerror.c
+ secpwd.c
+ secutil.c
+ pppolicy.c
+ p7tool.c
+)
+
+include_directories(${P7TOOL_PRIVATE_INCLUDE_DIRS})
+
+add_executable(p7tool ${p7tool_SRCS})
+
+target_link_libraries(p7tool ${P7TOOL_LINK_LIBRARIES})
+
+install(
+ TARGETS p7tool
+ RUNTIME DESTINATION ${BIN_INSTALL_DIR}
+ LIBRARY DESTINATION ${LIB_INSTALL_DIR}
+ ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
+)
diff --git a/base/native-tools/src/p7tool/NSPRerrs.h b/base/native-tools/src/p7tool/NSPRerrs.h
new file mode 100644
index 000000000..f0bc8b77e
--- /dev/null
+++ b/base/native-tools/src/p7tool/NSPRerrs.h
@@ -0,0 +1,161 @@
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/NSPRerrs.h
+ */
+
+/* General NSPR 2.0 errors */
+/* Caller must #include "prerror.h" */
+
+ER2( PR_OUT_OF_MEMORY_ERROR, "Memory allocation attempt failed." )
+ER2( PR_BAD_DESCRIPTOR_ERROR, "Invalid file descriptor." )
+ER2( PR_WOULD_BLOCK_ERROR, "The operation would have blocked." )
+ER2( PR_ACCESS_FAULT_ERROR, "Invalid memory address argument." )
+ER2( PR_INVALID_METHOD_ERROR, "Invalid function for file type." )
+ER2( PR_ILLEGAL_ACCESS_ERROR, "Invalid memory address argument." )
+ER2( PR_UNKNOWN_ERROR, "Some unknown error has occurred." )
+ER2( PR_PENDING_INTERRUPT_ERROR,"Operation interrupted by another thread." )
+ER2( PR_NOT_IMPLEMENTED_ERROR, "function not implemented." )
+ER2( PR_IO_ERROR, "I/O function error." )
+ER2( PR_IO_TIMEOUT_ERROR, "I/O operation timed out." )
+ER2( PR_IO_PENDING_ERROR, "I/O operation on busy file descriptor." )
+ER2( PR_DIRECTORY_OPEN_ERROR, "The directory could not be opened." )
+ER2( PR_INVALID_ARGUMENT_ERROR, "Invalid function argument." )
+ER2( PR_ADDRESS_NOT_AVAILABLE_ERROR, "Network address not available (in use?)." )
+ER2( PR_ADDRESS_NOT_SUPPORTED_ERROR, "Network address type not supported." )
+ER2( PR_IS_CONNECTED_ERROR, "Already connected." )
+ER2( PR_BAD_ADDRESS_ERROR, "Network address is invalid." )
+ER2( PR_ADDRESS_IN_USE_ERROR, "Local Network address is in use." )
+ER2( PR_CONNECT_REFUSED_ERROR, "Connection refused by peer." )
+ER2( PR_NETWORK_UNREACHABLE_ERROR, "Network address is presently unreachable." )
+ER2( PR_CONNECT_TIMEOUT_ERROR, "Connection attempt timed out." )
+ER2( PR_NOT_CONNECTED_ERROR, "Network file descriptor is not connected." )
+ER2( PR_LOAD_LIBRARY_ERROR, "Failure to load dynamic library." )
+ER2( PR_UNLOAD_LIBRARY_ERROR, "Failure to unload dynamic library." )
+ER2( PR_FIND_SYMBOL_ERROR,
+"Symbol not found in any of the loaded dynamic libraries." )
+ER2( PR_INSUFFICIENT_RESOURCES_ERROR, "Insufficient system resources." )
+ER2( PR_DIRECTORY_LOOKUP_ERROR,
+"A directory lookup on a network address has failed." )
+ER2( PR_TPD_RANGE_ERROR,
+"Attempt to access a TPD key that is out of range." )
+ER2( PR_PROC_DESC_TABLE_FULL_ERROR, "Process open FD table is full." )
+ER2( PR_SYS_DESC_TABLE_FULL_ERROR, "System open FD table is full." )
+ER2( PR_NOT_SOCKET_ERROR,
+"Network operation attempted on non-network file descriptor." )
+ER2( PR_NOT_TCP_SOCKET_ERROR,
+"TCP-specific function attempted on a non-TCP file descriptor." )
+ER2( PR_SOCKET_ADDRESS_IS_BOUND_ERROR, "TCP file descriptor is already bound." )
+ER2( PR_NO_ACCESS_RIGHTS_ERROR, "Access Denied." )
+ER2( PR_OPERATION_NOT_SUPPORTED_ERROR,
+"The requested operation is not supported by the platform." )
+ER2( PR_PROTOCOL_NOT_SUPPORTED_ERROR,
+"The host operating system does not support the protocol requested." )
+ER2( PR_REMOTE_FILE_ERROR, "Access to the remote file has been severed." )
+ER2( PR_BUFFER_OVERFLOW_ERROR,
+"The value requested is too large to be stored in the data buffer provided." )
+ER2( PR_CONNECT_RESET_ERROR, "TCP connection reset by peer." )
+ER2( PR_RANGE_ERROR, "Unused." )
+ER2( PR_DEADLOCK_ERROR, "The operation would have deadlocked." )
+ER2( PR_FILE_IS_LOCKED_ERROR, "The file is already locked." )
+ER2( PR_FILE_TOO_BIG_ERROR,
+"Write would result in file larger than the system allows." )
+ER2( PR_NO_DEVICE_SPACE_ERROR, "The device for storing the file is full." )
+ER2( PR_PIPE_ERROR, "Unused." )
+ER2( PR_NO_SEEK_DEVICE_ERROR, "Unused." )
+ER2( PR_IS_DIRECTORY_ERROR,
+"Cannot perform a normal file operation on a directory." )
+ER2( PR_LOOP_ERROR, "Symbolic link loop." )
+ER2( PR_NAME_TOO_LONG_ERROR, "File name is too long." )
+ER2( PR_FILE_NOT_FOUND_ERROR, "File not found." )
+ER2( PR_NOT_DIRECTORY_ERROR,
+"Cannot perform directory operation on a normal file." )
+ER2( PR_READ_ONLY_FILESYSTEM_ERROR,
+"Cannot write to a read-only file system." )
+ER2( PR_DIRECTORY_NOT_EMPTY_ERROR,
+"Cannot delete a directory that is not empty." )
+ER2( PR_FILESYSTEM_MOUNTED_ERROR,
+"Cannot delete or rename a file object while the file system is busy." )
+ER2( PR_NOT_SAME_DEVICE_ERROR,
+"Cannot rename a file to a file system on another device." )
+ER2( PR_DIRECTORY_CORRUPTED_ERROR,
+"The directory object in the file system is corrupted." )
+ER2( PR_FILE_EXISTS_ERROR,
+"Cannot create or rename a filename that already exists." )
+ER2( PR_MAX_DIRECTORY_ENTRIES_ERROR,
+"Directory is full. No additional filenames may be added." )
+ER2( PR_INVALID_DEVICE_STATE_ERROR,
+"The required device was in an invalid state." )
+ER2( PR_DEVICE_IS_LOCKED_ERROR, "The device is locked." )
+ER2( PR_NO_MORE_FILES_ERROR, "No more entries in the directory." )
+ER2( PR_END_OF_FILE_ERROR, "Encountered end of file." )
+ER2( PR_FILE_SEEK_ERROR, "Seek error." )
+ER2( PR_FILE_IS_BUSY_ERROR, "The file is busy." )
+ER2( PR_IN_PROGRESS_ERROR,
+"Operation is still in progress (probably a non-blocking connect)." )
+ER2( PR_ALREADY_INITIATED_ERROR,
+"Operation has already been initiated (probably a non-blocking connect)." )
+
+#ifdef PR_GROUP_EMPTY_ERROR
+ER2( PR_GROUP_EMPTY_ERROR, "The wait group is empty." )
+#endif
+
+#ifdef PR_INVALID_STATE_ERROR
+ER2( PR_INVALID_STATE_ERROR, "Object state improper for request." )
+#endif
+
+#ifdef PR_NETWORK_DOWN_ERROR
+ER2( PR_NETWORK_DOWN_ERROR, "Network is down." )
+#endif
+
+#ifdef PR_SOCKET_SHUTDOWN_ERROR
+ER2( PR_SOCKET_SHUTDOWN_ERROR, "The socket was previously shut down." )
+#endif
+
+#ifdef PR_CONNECT_ABORTED_ERROR
+ER2( PR_CONNECT_ABORTED_ERROR, "TCP Connection aborted." )
+#endif
+
+#ifdef PR_HOST_UNREACHABLE_ERROR
+ER2( PR_HOST_UNREACHABLE_ERROR, "Host is unreachable." )
+#endif
+
+/* always last */
+ER2( PR_MAX_ERROR, "Placeholder for the end of the list" )
diff --git a/base/native-tools/src/p7tool/SECerrs.h b/base/native-tools/src/p7tool/SECerrs.h
new file mode 100644
index 000000000..55858b98f
--- /dev/null
+++ b/base/native-tools/src/p7tool/SECerrs.h
@@ -0,0 +1,523 @@
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/SECerrs.h
+ */
+
+/* General security error codes */
+/* Caller must #include "secerr.h" */
+
+ER3(SEC_ERROR_IO, SEC_ERROR_BASE + 0,
+"An I/O error occurred during security authorization.")
+
+ER3(SEC_ERROR_LIBRARY_FAILURE, SEC_ERROR_BASE + 1,
+"security library failure.")
+
+ER3(SEC_ERROR_BAD_DATA, SEC_ERROR_BASE + 2,
+"security library: received bad data.")
+
+ER3(SEC_ERROR_OUTPUT_LEN, SEC_ERROR_BASE + 3,
+"security library: output length error.")
+
+ER3(SEC_ERROR_INPUT_LEN, SEC_ERROR_BASE + 4,
+"security library has experienced an input length error.")
+
+ER3(SEC_ERROR_INVALID_ARGS, SEC_ERROR_BASE + 5,
+"security library: invalid arguments.")
+
+ER3(SEC_ERROR_INVALID_ALGORITHM, SEC_ERROR_BASE + 6,
+"security library: invalid algorithm.")
+
+ER3(SEC_ERROR_INVALID_AVA, SEC_ERROR_BASE + 7,
+"security library: invalid AVA.")
+
+ER3(SEC_ERROR_INVALID_TIME, SEC_ERROR_BASE + 8,
+"Improperly formatted time string.")
+
+ER3(SEC_ERROR_BAD_DER, SEC_ERROR_BASE + 9,
+"security library: improperly formatted DER-encoded message.")
+
+ER3(SEC_ERROR_BAD_SIGNATURE, SEC_ERROR_BASE + 10,
+"Peer's certificate has an invalid signature.")
+
+ER3(SEC_ERROR_EXPIRED_CERTIFICATE, SEC_ERROR_BASE + 11,
+"Peer's Certificate has expired.")
+
+ER3(SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_BASE + 12,
+"Peer's Certificate has been revoked.")
+
+ER3(SEC_ERROR_UNKNOWN_ISSUER, SEC_ERROR_BASE + 13,
+"Peer's Certificate issuer is not recognized.")
+
+ER3(SEC_ERROR_BAD_KEY, SEC_ERROR_BASE + 14,
+"Peer's public key is invalid.")
+
+ER3(SEC_ERROR_BAD_PASSWORD, SEC_ERROR_BASE + 15,
+"The security password entered is incorrect.")
+
+ER3(SEC_ERROR_RETRY_PASSWORD, SEC_ERROR_BASE + 16,
+"New password entered incorrectly. Please try again.")
+
+ER3(SEC_ERROR_NO_NODELOCK, SEC_ERROR_BASE + 17,
+"security library: no nodelock.")
+
+ER3(SEC_ERROR_BAD_DATABASE, SEC_ERROR_BASE + 18,
+"security library: bad database.")
+
+ER3(SEC_ERROR_NO_MEMORY, SEC_ERROR_BASE + 19,
+"security library: memory allocation failure.")
+
+ER3(SEC_ERROR_UNTRUSTED_ISSUER, SEC_ERROR_BASE + 20,
+"Peer's certificate issuer has been marked as not trusted by the user.")
+
+ER3(SEC_ERROR_UNTRUSTED_CERT, SEC_ERROR_BASE + 21,
+"Peer's certificate has been marked as not trusted by the user.")
+
+ER3(SEC_ERROR_DUPLICATE_CERT, (SEC_ERROR_BASE + 22),
+"Certificate already exists in your database.")
+
+ER3(SEC_ERROR_DUPLICATE_CERT_NAME, (SEC_ERROR_BASE + 23),
+"Downloaded certificate's name duplicates one already in your database.")
+
+ER3(SEC_ERROR_ADDING_CERT, (SEC_ERROR_BASE + 24),
+"Error adding certificate to database.")
+
+ER3(SEC_ERROR_FILING_KEY, (SEC_ERROR_BASE + 25),
+"Error refiling the key for this certificate.")
+
+ER3(SEC_ERROR_NO_KEY, (SEC_ERROR_BASE + 26),
+"The private key for this certificate cannot be found in key database")
+
+ER3(SEC_ERROR_CERT_VALID, (SEC_ERROR_BASE + 27),
+"This certificate is valid.")
+
+ER3(SEC_ERROR_CERT_NOT_VALID, (SEC_ERROR_BASE + 28),
+"This certificate is not valid.")
+
+ER3(SEC_ERROR_CERT_NO_RESPONSE, (SEC_ERROR_BASE + 29),
+"Cert Library: No Response")
+
+ER3(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE, (SEC_ERROR_BASE + 30),
+"The certificate issuer's certificate has expired. Check your system date and time.")
+
+ER3(SEC_ERROR_CRL_EXPIRED, (SEC_ERROR_BASE + 31),
+"The CRL for the certificate's issuer has expired. Update it or check your system data and time.")
+
+ER3(SEC_ERROR_CRL_BAD_SIGNATURE, (SEC_ERROR_BASE + 32),
+"The CRL for the certificate's issuer has an invalid signature.")
+
+ER3(SEC_ERROR_CRL_INVALID, (SEC_ERROR_BASE + 33),
+"New CRL has an invalid format.")
+
+ER3(SEC_ERROR_EXTENSION_VALUE_INVALID, (SEC_ERROR_BASE + 34),
+"Certificate extension value is invalid.")
+
+ER3(SEC_ERROR_EXTENSION_NOT_FOUND, (SEC_ERROR_BASE + 35),
+"Certificate extension not found.")
+
+ER3(SEC_ERROR_CA_CERT_INVALID, (SEC_ERROR_BASE + 36),
+"Issuer certificate is invalid.")
+
+ER3(SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID, (SEC_ERROR_BASE + 37),
+"Certificate path length constraint is invalid.")
+
+ER3(SEC_ERROR_CERT_USAGES_INVALID, (SEC_ERROR_BASE + 38),
+"Certificate usages field is invalid.")
+
+ER3(SEC_INTERNAL_ONLY, (SEC_ERROR_BASE + 39),
+"**Internal ONLY module**")
+
+ER3(SEC_ERROR_INVALID_KEY, (SEC_ERROR_BASE + 40),
+"The key does not support the requested operation.")
+
+ER3(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 41),
+"Certificate contains unknown critical extension.")
+
+ER3(SEC_ERROR_OLD_CRL, (SEC_ERROR_BASE + 42),
+"New CRL is not later than the current one.")
+
+ER3(SEC_ERROR_NO_EMAIL_CERT, (SEC_ERROR_BASE + 43),
+"Not encrypted or signed: you do not yet have an email certificate.")
+
+ER3(SEC_ERROR_NO_RECIPIENT_CERTS_QUERY, (SEC_ERROR_BASE + 44),
+"Not encrypted: you do not have certificates for each of the recipients.")
+
+ER3(SEC_ERROR_NOT_A_RECIPIENT, (SEC_ERROR_BASE + 45),
+"Cannot decrypt: you are not a recipient, or matching certificate and \
+private key not found.")
+
+ER3(SEC_ERROR_PKCS7_KEYALG_MISMATCH, (SEC_ERROR_BASE + 46),
+"Cannot decrypt: key encryption algorithm does not match your certificate.")
+
+ER3(SEC_ERROR_PKCS7_BAD_SIGNATURE, (SEC_ERROR_BASE + 47),
+"Signature verification failed: no signer found, too many signers found, \
+or improper or corrupted data.")
+
+ER3(SEC_ERROR_UNSUPPORTED_KEYALG, (SEC_ERROR_BASE + 48),
+"Unsupported or unknown key algorithm.")
+
+ER3(SEC_ERROR_DECRYPTION_DISALLOWED, (SEC_ERROR_BASE + 49),
+"Cannot decrypt: encrypted using a disallowed algorithm or key size.")
+
+
+/* Fortezza Alerts */
+ER3(XP_SEC_FORTEZZA_BAD_CARD, (SEC_ERROR_BASE + 50),
+"Fortezza card has not been properly initialized. \
+Please remove it and return it to your issuer.")
+
+ER3(XP_SEC_FORTEZZA_NO_CARD, (SEC_ERROR_BASE + 51),
+"No Fortezza cards Found")
+
+ER3(XP_SEC_FORTEZZA_NONE_SELECTED, (SEC_ERROR_BASE + 52),
+"No Fortezza card selected")
+
+ER3(XP_SEC_FORTEZZA_MORE_INFO, (SEC_ERROR_BASE + 53),
+"Please select a personality to get more info on")
+
+ER3(XP_SEC_FORTEZZA_PERSON_NOT_FOUND, (SEC_ERROR_BASE + 54),
+"Personality not found")
+
+ER3(XP_SEC_FORTEZZA_NO_MORE_INFO, (SEC_ERROR_BASE + 55),
+"No more information on that Personality")
+
+ER3(XP_SEC_FORTEZZA_BAD_PIN, (SEC_ERROR_BASE + 56),
+"Invalid Pin")
+
+ER3(XP_SEC_FORTEZZA_PERSON_ERROR, (SEC_ERROR_BASE + 57),
+"Couldn't initialize Fortezza personalities.")
+/* end fortezza alerts. */
+
+ER3(SEC_ERROR_NO_KRL, (SEC_ERROR_BASE + 58),
+"No KRL for this site's certificate has been found.")
+
+ER3(SEC_ERROR_KRL_EXPIRED, (SEC_ERROR_BASE + 59),
+"The KRL for this site's certificate has expired.")
+
+ER3(SEC_ERROR_KRL_BAD_SIGNATURE, (SEC_ERROR_BASE + 60),
+"The KRL for this site's certificate has an invalid signature.")
+
+ER3(SEC_ERROR_REVOKED_KEY, (SEC_ERROR_BASE + 61),
+"The key for this site's certificate has been revoked.")
+
+ER3(SEC_ERROR_KRL_INVALID, (SEC_ERROR_BASE + 62),
+"New KRL has an invalid format.")
+
+ER3(SEC_ERROR_NEED_RANDOM, (SEC_ERROR_BASE + 63),
+"security library: need random data.")
+
+ER3(SEC_ERROR_NO_MODULE, (SEC_ERROR_BASE + 64),
+"security library: no security module can perform the requested operation.")
+
+ER3(SEC_ERROR_NO_TOKEN, (SEC_ERROR_BASE + 65),
+"The security card or token does not exist, needs to be initialized, or has been removed.")
+
+ER3(SEC_ERROR_READ_ONLY, (SEC_ERROR_BASE + 66),
+"security library: read-only database.")
+
+ER3(SEC_ERROR_NO_SLOT_SELECTED, (SEC_ERROR_BASE + 67),
+"No slot or token was selected.")
+
+ER3(SEC_ERROR_CERT_NICKNAME_COLLISION, (SEC_ERROR_BASE + 68),
+"A certificate with the same nickname already exists.")
+
+ER3(SEC_ERROR_KEY_NICKNAME_COLLISION, (SEC_ERROR_BASE + 69),
+"A key with the same nickname already exists.")
+
+ER3(SEC_ERROR_SAFE_NOT_CREATED, (SEC_ERROR_BASE + 70),
+"error while creating safe object")
+
+ER3(SEC_ERROR_BAGGAGE_NOT_CREATED, (SEC_ERROR_BASE + 71),
+"error while creating baggage object")
+
+ER3(XP_JAVA_REMOVE_PRINCIPAL_ERROR, (SEC_ERROR_BASE + 72),
+"Couldn't remove the principal")
+
+ER3(XP_JAVA_DELETE_PRIVILEGE_ERROR, (SEC_ERROR_BASE + 73),
+"Couldn't delete the privilege")
+
+ER3(XP_JAVA_CERT_NOT_EXISTS_ERROR, (SEC_ERROR_BASE + 74),
+"This principal doesn't have a certificate")
+
+ER3(SEC_ERROR_BAD_EXPORT_ALGORITHM, (SEC_ERROR_BASE + 75),
+"Required algorithm is not allowed.")
+
+ER3(SEC_ERROR_EXPORTING_CERTIFICATES, (SEC_ERROR_BASE + 76),
+"Error attempting to export certificates.")
+
+ER3(SEC_ERROR_IMPORTING_CERTIFICATES, (SEC_ERROR_BASE + 77),
+"Error attempting to import certificates.")
+
+ER3(SEC_ERROR_PKCS12_DECODING_PFX, (SEC_ERROR_BASE + 78),
+"Unable to import. Decoding error. File not valid.")
+
+ER3(SEC_ERROR_PKCS12_INVALID_MAC, (SEC_ERROR_BASE + 79),
+"Unable to import. Invalid MAC. Incorrect password or corrupt file.")
+
+ER3(SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM, (SEC_ERROR_BASE + 80),
+"Unable to import. MAC algorithm not supported.")
+
+ER3(SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE,(SEC_ERROR_BASE + 81),
+"Unable to import. Only password integrity and privacy modes supported.")
+
+ER3(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE, (SEC_ERROR_BASE + 82),
+"Unable to import. File structure is corrupt.")
+
+ER3(SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM, (SEC_ERROR_BASE + 83),
+"Unable to import. Encryption algorithm not supported.")
+
+ER3(SEC_ERROR_PKCS12_UNSUPPORTED_VERSION, (SEC_ERROR_BASE + 84),
+"Unable to import. File version not supported.")
+
+ER3(SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT,(SEC_ERROR_BASE + 85),
+"Unable to import. Incorrect privacy password.")
+
+ER3(SEC_ERROR_PKCS12_CERT_COLLISION, (SEC_ERROR_BASE + 86),
+"Unable to import. Same nickname already exists in database.")
+
+ER3(SEC_ERROR_USER_CANCELLED, (SEC_ERROR_BASE + 87),
+"The user pressed cancel.")
+
+ER3(SEC_ERROR_PKCS12_DUPLICATE_DATA, (SEC_ERROR_BASE + 88),
+"Not imported, already in database.")
+
+ER3(SEC_ERROR_MESSAGE_SEND_ABORTED, (SEC_ERROR_BASE + 89),
+"Message not sent.")
+
+ER3(SEC_ERROR_INADEQUATE_KEY_USAGE, (SEC_ERROR_BASE + 90),
+"Certificate key usage inadequate for attempted operation.")
+
+ER3(SEC_ERROR_INADEQUATE_CERT_TYPE, (SEC_ERROR_BASE + 91),
+"Certificate type not approved for application.")
+
+ER3(SEC_ERROR_CERT_ADDR_MISMATCH, (SEC_ERROR_BASE + 92),
+"Address in signing certificate does not match address in message headers.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY, (SEC_ERROR_BASE + 93),
+"Unable to import. Error attempting to import private key.")
+
+ER3(SEC_ERROR_PKCS12_IMPORTING_CERT_CHAIN, (SEC_ERROR_BASE + 94),
+"Unable to import. Error attempting to import certificate chain.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME, (SEC_ERROR_BASE + 95),
+"Unable to export. Unable to locate certificate or key by nickname.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY, (SEC_ERROR_BASE + 96),
+"Unable to export. Private Key could not be located and exported.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_WRITE, (SEC_ERROR_BASE + 97),
+"Unable to export. Unable to write the export file.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_READ, (SEC_ERROR_BASE + 98),
+"Unable to import. Unable to read the import file.")
+
+ER3(SEC_ERROR_PKCS12_KEY_DATABASE_NOT_INITIALIZED, (SEC_ERROR_BASE + 99),
+"Unable to export. Key database corrupt or deleted.")
+
+ER3(SEC_ERROR_KEYGEN_FAIL, (SEC_ERROR_BASE + 100),
+"Unable to generate public/private key pair.")
+
+ER3(SEC_ERROR_INVALID_PASSWORD, (SEC_ERROR_BASE + 101),
+"Password entered is invalid. Please pick a different one.")
+
+ER3(SEC_ERROR_RETRY_OLD_PASSWORD, (SEC_ERROR_BASE + 102),
+"Old password entered incorrectly. Please try again.")
+
+ER3(SEC_ERROR_BAD_NICKNAME, (SEC_ERROR_BASE + 103),
+"Certificate nickname already in use.")
+
+ER3(SEC_ERROR_NOT_FORTEZZA_ISSUER, (SEC_ERROR_BASE + 104),
+"Peer FORTEZZA chain has a non-FORTEZZA Certificate.")
+
+ER3(SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY, (SEC_ERROR_BASE + 105),
+"A sensitive key cannot be moved to the slot where it is needed.")
+
+ER3(SEC_ERROR_JS_INVALID_MODULE_NAME, (SEC_ERROR_BASE + 106),
+"Invalid module name.")
+
+ER3(SEC_ERROR_JS_INVALID_DLL, (SEC_ERROR_BASE + 107),
+"Invalid module path/filename")
+
+ER3(SEC_ERROR_JS_ADD_MOD_FAILURE, (SEC_ERROR_BASE + 108),
+"Unable to add module")
+
+ER3(SEC_ERROR_JS_DEL_MOD_FAILURE, (SEC_ERROR_BASE + 109),
+"Unable to delete module")
+
+ER3(SEC_ERROR_OLD_KRL, (SEC_ERROR_BASE + 110),
+"New KRL is not later than the current one.")
+
+ER3(SEC_ERROR_CKL_CONFLICT, (SEC_ERROR_BASE + 111),
+"New CKL has different issuer than current CKL. Delete current CKL.")
+
+ER3(SEC_ERROR_CERT_NOT_IN_NAME_SPACE, (SEC_ERROR_BASE + 112),
+"The Certifying Authority for this certificate is not permitted to issue a \
+certificate with this name.")
+
+ER3(SEC_ERROR_KRL_NOT_YET_VALID, (SEC_ERROR_BASE + 113),
+"The key revocation list for this certificate is not yet valid.")
+
+ER3(SEC_ERROR_CRL_NOT_YET_VALID, (SEC_ERROR_BASE + 114),
+"The certificate revocation list for this certificate is not yet valid.")
+
+ER3(SEC_ERROR_UNKNOWN_CERT, (SEC_ERROR_BASE + 115),
+"The requested certificate could not be found.")
+
+ER3(SEC_ERROR_UNKNOWN_SIGNER, (SEC_ERROR_BASE + 116),
+"The signer's certificate could not be found.")
+
+ER3(SEC_ERROR_CERT_BAD_ACCESS_LOCATION, (SEC_ERROR_BASE + 117),
+"The location for the certificate status server has invalid format.")
+
+ER3(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE, (SEC_ERROR_BASE + 118),
+"The OCSP response cannot be fully decoded; it is of an unknown type.")
+
+ER3(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE, (SEC_ERROR_BASE + 119),
+"The OCSP server returned unexpected/invalid HTTP data.")
+
+ER3(SEC_ERROR_OCSP_MALFORMED_REQUEST, (SEC_ERROR_BASE + 120),
+"The OCSP server found the request to be corrupted or improperly formed.")
+
+ER3(SEC_ERROR_OCSP_SERVER_ERROR, (SEC_ERROR_BASE + 121),
+"The OCSP server experienced an internal error.")
+
+ER3(SEC_ERROR_OCSP_TRY_SERVER_LATER, (SEC_ERROR_BASE + 122),
+"The OCSP server suggests trying again later.")
+
+ER3(SEC_ERROR_OCSP_REQUEST_NEEDS_SIG, (SEC_ERROR_BASE + 123),
+"The OCSP server requires a signature on this request.")
+
+ER3(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST, (SEC_ERROR_BASE + 124),
+"The OCSP server has refused this request as unauthorized.")
+
+ER3(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS, (SEC_ERROR_BASE + 125),
+"The OCSP server returned an unrecognizable status.")
+
+ER3(SEC_ERROR_OCSP_UNKNOWN_CERT, (SEC_ERROR_BASE + 126),
+"The OCSP server has no status for the certificate.")
+
+ER3(SEC_ERROR_OCSP_NOT_ENABLED, (SEC_ERROR_BASE + 127),
+"You must enable OCSP before performing this operation.")
+
+ER3(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER, (SEC_ERROR_BASE + 128),
+"You must set the OCSP default responder before performing this operation.")
+
+ER3(SEC_ERROR_OCSP_MALFORMED_RESPONSE, (SEC_ERROR_BASE + 129),
+"The response from the OCSP server was corrupted or improperly formed.")
+
+ER3(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE, (SEC_ERROR_BASE + 130),
+"The signer of the OCSP response is not authorized to give status for \
+this certificate.")
+
+ER3(SEC_ERROR_OCSP_FUTURE_RESPONSE, (SEC_ERROR_BASE + 131),
+"The OCSP response is not yet valid (contains a date in the future).")
+
+ER3(SEC_ERROR_OCSP_OLD_RESPONSE, (SEC_ERROR_BASE + 132),
+"The OCSP response contains out-of-date information.")
+
+ER3(SEC_ERROR_DIGEST_NOT_FOUND, (SEC_ERROR_BASE + 133),
+"The CMS or PKCS #7 Digest was not found in signed message.")
+
+ER3(SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE, (SEC_ERROR_BASE + 134),
+"The CMS or PKCS #7 Message type is unsupported.")
+
+ER3(SEC_ERROR_MODULE_STUCK, (SEC_ERROR_BASE + 135),
+"PKCS #11 module could not be removed because it is still in use.")
+
+ER3(SEC_ERROR_BAD_TEMPLATE, (SEC_ERROR_BASE + 136),
+"Could not decode ASN.1 data. Specified template was invalid.")
+
+ER3(SEC_ERROR_CRL_NOT_FOUND, (SEC_ERROR_BASE + 137),
+"No matching CRL was found.")
+
+ER3(SEC_ERROR_REUSED_ISSUER_AND_SERIAL, (SEC_ERROR_BASE + 138),
+"You are attempting to import a cert with the same issuer/serial as \
+an existing cert, but that is not the same cert.")
+
+ER3(SEC_ERROR_BUSY, (SEC_ERROR_BASE + 139),
+"NSS could not shutdown. Objects are still in use.")
+
+ER3(SEC_ERROR_EXTRA_INPUT, (SEC_ERROR_BASE + 140),
+"DER-encoded message contained extra unused data.")
+
+ER3(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE, (SEC_ERROR_BASE + 141),
+"Unsupported elliptic curve.")
+
+ER3(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM, (SEC_ERROR_BASE + 142),
+"Unsupported elliptic curve point form.")
+
+ER3(SEC_ERROR_UNRECOGNIZED_OID, (SEC_ERROR_BASE + 143),
+"Unrecognized Object IDentifier.")
+
+ER3(SEC_ERROR_OCSP_INVALID_SIGNING_CERT, (SEC_ERROR_BASE + 144),
+"Invalid OCSP signing certificate in OCSP response.")
+
+ER3(SEC_ERROR_REVOKED_CERTIFICATE_CRL, (SEC_ERROR_BASE + 145),
+"Certificate is revoked in issuer's certificate revocation list.")
+
+ER3(SEC_ERROR_REVOKED_CERTIFICATE_OCSP, (SEC_ERROR_BASE + 146),
+"Issuer's OCSP responder reports certificate is revoked.")
+
+ER3(SEC_ERROR_CRL_INVALID_VERSION, (SEC_ERROR_BASE + 147),
+"Issuer's Certificate Revocation List has an unknown version number.")
+
+ER3(SEC_ERROR_CRL_V1_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 148),
+"Issuer's V1 Certificate Revocation List has a critical extension.")
+
+ER3(SEC_ERROR_CRL_UNKNOWN_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 149),
+"Issuer's V2 Certificate Revocation List has an unknown critical extension.")
+
+ER3(SEC_ERROR_UNKNOWN_OBJECT_TYPE, (SEC_ERROR_BASE + 150),
+"Unknown object type specified.")
+
+ER3(SEC_ERROR_INCOMPATIBLE_PKCS11, (SEC_ERROR_BASE + 151),
+"PKCS #11 driver violates the spec in an incompatible way.")
+
+ER3(SEC_ERROR_NO_EVENT, (SEC_ERROR_BASE + 152),
+"No new slot event is available at this time.")
+
+ER3(SEC_ERROR_CRL_ALREADY_EXISTS, (SEC_ERROR_BASE + 153),
+"CRL already exists.")
+
+ER3(SEC_ERROR_NOT_INITIALIZED, (SEC_ERROR_BASE + 154),
+"NSS is not initialized.")
+
+ER3(SEC_ERROR_TOKEN_NOT_LOGGED_IN, (SEC_ERROR_BASE + 155),
+"The operation failed because the PKCS#11 token is not logged in.")
+
diff --git a/base/native-tools/src/p7tool/SSLerrs.h b/base/native-tools/src/p7tool/SSLerrs.h
new file mode 100644
index 000000000..d6ec13b47
--- /dev/null
+++ b/base/native-tools/src/p7tool/SSLerrs.h
@@ -0,0 +1,393 @@
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/SSLerrs.h
+ */
+
+/* SSL-specific security error codes */
+/* caller must include "sslerr.h" */
+
+ER3(SSL_ERROR_EXPORT_ONLY_SERVER, SSL_ERROR_BASE + 0,
+"Unable to communicate securely. Peer does not support high-grade encryption.")
+
+ER3(SSL_ERROR_US_ONLY_SERVER, SSL_ERROR_BASE + 1,
+"Unable to communicate securely. Peer requires high-grade encryption which is not supported.")
+
+ER3(SSL_ERROR_NO_CYPHER_OVERLAP, SSL_ERROR_BASE + 2,
+"Cannot communicate securely with peer: no common encryption algorithm(s).")
+
+ER3(SSL_ERROR_NO_CERTIFICATE, SSL_ERROR_BASE + 3,
+"Unable to find the certificate or key necessary for authentication.")
+
+ER3(SSL_ERROR_BAD_CERTIFICATE, SSL_ERROR_BASE + 4,
+"Unable to communicate securely with peer: peers's certificate was rejected.")
+
+/* unused (SSL_ERROR_BASE + 5),*/
+
+ER3(SSL_ERROR_BAD_CLIENT, SSL_ERROR_BASE + 6,
+"The server has encountered bad data from the client.")
+
+ER3(SSL_ERROR_BAD_SERVER, SSL_ERROR_BASE + 7,
+"The client has encountered bad data from the server.")
+
+ER3(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE, SSL_ERROR_BASE + 8,
+"Unsupported certificate type.")
+
+ER3(SSL_ERROR_UNSUPPORTED_VERSION, SSL_ERROR_BASE + 9,
+"Peer using unsupported version of security protocol.")
+
+/* unused (SSL_ERROR_BASE + 10),*/
+
+ER3(SSL_ERROR_WRONG_CERTIFICATE, SSL_ERROR_BASE + 11,
+"Client authentication failed: private key in key database does not match public key in certificate database.")
+
+ER3(SSL_ERROR_BAD_CERT_DOMAIN, SSL_ERROR_BASE + 12,
+"Unable to communicate securely with peer: requested domain name does not match the server's certificate.")
+
+/* SSL_ERROR_POST_WARNING (SSL_ERROR_BASE + 13),
+ defined in sslerr.h
+*/
+
+ER3(SSL_ERROR_SSL2_DISABLED, (SSL_ERROR_BASE + 14),
+"Peer only supports SSL version 2, which is locally disabled.")
+
+
+ER3(SSL_ERROR_BAD_MAC_READ, (SSL_ERROR_BASE + 15),
+"SSL received a record with an incorrect Message Authentication Code.")
+
+ER3(SSL_ERROR_BAD_MAC_ALERT, (SSL_ERROR_BASE + 16),
+"SSL peer reports incorrect Message Authentication Code.")
+
+ER3(SSL_ERROR_BAD_CERT_ALERT, (SSL_ERROR_BASE + 17),
+"SSL peer cannot verify your certificate.")
+
+ER3(SSL_ERROR_REVOKED_CERT_ALERT, (SSL_ERROR_BASE + 18),
+"SSL peer rejected your certificate as revoked.")
+
+ER3(SSL_ERROR_EXPIRED_CERT_ALERT, (SSL_ERROR_BASE + 19),
+"SSL peer rejected your certificate as expired.")
+
+ER3(SSL_ERROR_SSL_DISABLED, (SSL_ERROR_BASE + 20),
+"Cannot connect: SSL is disabled.")
+
+ER3(SSL_ERROR_FORTEZZA_PQG, (SSL_ERROR_BASE + 21),
+"Cannot connect: SSL peer is in another FORTEZZA domain.")
+
+
+ER3(SSL_ERROR_UNKNOWN_CIPHER_SUITE , (SSL_ERROR_BASE + 22),
+"An unknown SSL cipher suite has been requested.")
+
+ER3(SSL_ERROR_NO_CIPHERS_SUPPORTED , (SSL_ERROR_BASE + 23),
+"No cipher suites are present and enabled in this program.")
+
+ER3(SSL_ERROR_BAD_BLOCK_PADDING , (SSL_ERROR_BASE + 24),
+"SSL received a record with bad block padding.")
+
+ER3(SSL_ERROR_RX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 25),
+"SSL received a record that exceeded the maximum permissible length.")
+
+ER3(SSL_ERROR_TX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 26),
+"SSL attempted to send a record that exceeded the maximum permissible length.")
+
+/*
+ * Received a malformed (too long or short or invalid content) SSL handshake.
+ */
+ER3(SSL_ERROR_RX_MALFORMED_HELLO_REQUEST , (SSL_ERROR_BASE + 27),
+"SSL received a malformed Hello Request handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO , (SSL_ERROR_BASE + 28),
+"SSL received a malformed Client Hello handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_SERVER_HELLO , (SSL_ERROR_BASE + 29),
+"SSL received a malformed Server Hello handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CERTIFICATE , (SSL_ERROR_BASE + 30),
+"SSL received a malformed Certificate handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 31),
+"SSL received a malformed Server Key Exchange handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CERT_REQUEST , (SSL_ERROR_BASE + 32),
+"SSL received a malformed Certificate Request handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_HELLO_DONE , (SSL_ERROR_BASE + 33),
+"SSL received a malformed Server Hello Done handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CERT_VERIFY , (SSL_ERROR_BASE + 34),
+"SSL received a malformed Certificate Verify handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 35),
+"SSL received a malformed Client Key Exchange handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_FINISHED , (SSL_ERROR_BASE + 36),
+"SSL received a malformed Finished handshake message.")
+
+/*
+ * Received a malformed (too long or short) SSL record.
+ */
+ER3(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER , (SSL_ERROR_BASE + 37),
+"SSL received a malformed Change Cipher Spec record.")
+
+ER3(SSL_ERROR_RX_MALFORMED_ALERT , (SSL_ERROR_BASE + 38),
+"SSL received a malformed Alert record.")
+
+ER3(SSL_ERROR_RX_MALFORMED_HANDSHAKE , (SSL_ERROR_BASE + 39),
+"SSL received a malformed Handshake record.")
+
+ER3(SSL_ERROR_RX_MALFORMED_APPLICATION_DATA , (SSL_ERROR_BASE + 40),
+"SSL received a malformed Application Data record.")
+
+/*
+ * Received an SSL handshake that was inappropriate for the state we're in.
+ * E.g. Server received message from server, or wrong state in state machine.
+ */
+ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST , (SSL_ERROR_BASE + 41),
+"SSL received an unexpected Hello Request handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO , (SSL_ERROR_BASE + 42),
+"SSL received an unexpected Client Hello handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO , (SSL_ERROR_BASE + 43),
+"SSL received an unexpected Server Hello handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CERTIFICATE , (SSL_ERROR_BASE + 44),
+"SSL received an unexpected Certificate handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 45),
+"SSL received an unexpected Server Key Exchange handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST , (SSL_ERROR_BASE + 46),
+"SSL received an unexpected Certificate Request handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE , (SSL_ERROR_BASE + 47),
+"SSL received an unexpected Server Hello Done handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY , (SSL_ERROR_BASE + 48),
+"SSL received an unexpected Certificate Verify handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 49),
+"SSL received an unexpected Cllient Key Exchange handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_FINISHED , (SSL_ERROR_BASE + 50),
+"SSL received an unexpected Finished handshake message.")
+
+/*
+ * Received an SSL record that was inappropriate for the state we're in.
+ */
+ER3(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER , (SSL_ERROR_BASE + 51),
+"SSL received an unexpected Change Cipher Spec record.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 52),
+"SSL received an unexpected Alert record.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE , (SSL_ERROR_BASE + 53),
+"SSL received an unexpected Handshake record.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA, (SSL_ERROR_BASE + 54),
+"SSL received an unexpected Application Data record.")
+
+/*
+ * Received record/message with unknown discriminant.
+ */
+ER3(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE , (SSL_ERROR_BASE + 55),
+"SSL received a record with an unknown content type.")
+
+ER3(SSL_ERROR_RX_UNKNOWN_HANDSHAKE , (SSL_ERROR_BASE + 56),
+"SSL received a handshake message with an unknown message type.")
+
+ER3(SSL_ERROR_RX_UNKNOWN_ALERT , (SSL_ERROR_BASE + 57),
+"SSL received an alert record with an unknown alert description.")
+
+/*
+ * Received an alert reporting what we did wrong. (more alerts above)
+ */
+ER3(SSL_ERROR_CLOSE_NOTIFY_ALERT , (SSL_ERROR_BASE + 58),
+"SSL peer has closed this connection.")
+
+ER3(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 59),
+"SSL peer was not expecting a handshake message it received.")
+
+ER3(SSL_ERROR_DECOMPRESSION_FAILURE_ALERT , (SSL_ERROR_BASE + 60),
+"SSL peer was unable to succesfully decompress an SSL record it received.")
+
+ER3(SSL_ERROR_HANDSHAKE_FAILURE_ALERT , (SSL_ERROR_BASE + 61),
+"SSL peer was unable to negotiate an acceptable set of security parameters.")
+
+ER3(SSL_ERROR_ILLEGAL_PARAMETER_ALERT , (SSL_ERROR_BASE + 62),
+"SSL peer rejected a handshake message for unacceptable content.")
+
+ER3(SSL_ERROR_UNSUPPORTED_CERT_ALERT , (SSL_ERROR_BASE + 63),
+"SSL peer does not support certificates of the type it received.")
+
+ER3(SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT , (SSL_ERROR_BASE + 64),
+"SSL peer had some unspecified issue with the certificate it received.")
+
+
+ER3(SSL_ERROR_GENERATE_RANDOM_FAILURE , (SSL_ERROR_BASE + 65),
+"SSL experienced a failure of its random number generator.")
+
+ER3(SSL_ERROR_SIGN_HASHES_FAILURE , (SSL_ERROR_BASE + 66),
+"Unable to digitally sign data required to verify your certificate.")
+
+ER3(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE , (SSL_ERROR_BASE + 67),
+"SSL was unable to extract the public key from the peer's certificate.")
+
+ER3(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 68),
+"Unspecified failure while processing SSL Server Key Exchange handshake.")
+
+ER3(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 69),
+"Unspecified failure while processing SSL Client Key Exchange handshake.")
+
+ER3(SSL_ERROR_ENCRYPTION_FAILURE , (SSL_ERROR_BASE + 70),
+"Bulk data encryption algorithm failed in selected cipher suite.")
+
+ER3(SSL_ERROR_DECRYPTION_FAILURE , (SSL_ERROR_BASE + 71),
+"Bulk data decryption algorithm failed in selected cipher suite.")
+
+ER3(SSL_ERROR_SOCKET_WRITE_FAILURE , (SSL_ERROR_BASE + 72),
+"Attempt to write encrypted data to underlying socket failed.")
+
+ER3(SSL_ERROR_MD5_DIGEST_FAILURE , (SSL_ERROR_BASE + 73),
+"MD5 digest function failed.")
+
+ER3(SSL_ERROR_SHA_DIGEST_FAILURE , (SSL_ERROR_BASE + 74),
+"SHA-1 digest function failed.")
+
+ER3(SSL_ERROR_MAC_COMPUTATION_FAILURE , (SSL_ERROR_BASE + 75),
+"MAC computation failed.")
+
+ER3(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE , (SSL_ERROR_BASE + 76),
+"Failure to create Symmetric Key context.")
+
+ER3(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE , (SSL_ERROR_BASE + 77),
+"Failure to unwrap the Symmetric key in Client Key Exchange message.")
+
+ER3(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED , (SSL_ERROR_BASE + 78),
+"SSL Server attempted to use domestic-grade public key with export cipher suite.")
+
+ER3(SSL_ERROR_IV_PARAM_FAILURE , (SSL_ERROR_BASE + 79),
+"PKCS11 code failed to translate an IV into a param.")
+
+ER3(SSL_ERROR_INIT_CIPHER_SUITE_FAILURE , (SSL_ERROR_BASE + 80),
+"Failed to initialize the selected cipher suite.")
+
+ER3(SSL_ERROR_SESSION_KEY_GEN_FAILURE , (SSL_ERROR_BASE + 81),
+"Client failed to generate session keys for SSL session.")
+
+ER3(SSL_ERROR_NO_SERVER_KEY_FOR_ALG , (SSL_ERROR_BASE + 82),
+"Server has no key for the attempted key exchange algorithm.")
+
+ER3(SSL_ERROR_TOKEN_INSERTION_REMOVAL , (SSL_ERROR_BASE + 83),
+"PKCS#11 token was inserted or removed while operation was in progress.")
+
+ER3(SSL_ERROR_TOKEN_SLOT_NOT_FOUND , (SSL_ERROR_BASE + 84),
+"No PKCS#11 token could be found to do a required operation.")
+
+ER3(SSL_ERROR_NO_COMPRESSION_OVERLAP , (SSL_ERROR_BASE + 85),
+"Cannot communicate securely with peer: no common compression algorithm(s).")
+
+ER3(SSL_ERROR_HANDSHAKE_NOT_COMPLETED , (SSL_ERROR_BASE + 86),
+"Cannot initiate another SSL handshake until current handshake is complete.")
+
+ER3(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE , (SSL_ERROR_BASE + 87),
+"Received incorrect handshakes hash values from peer.")
+
+ER3(SSL_ERROR_CERT_KEA_MISMATCH , (SSL_ERROR_BASE + 88),
+"The certificate provided cannot be used with the selected key exchange algorithm.")
+
+ER3(SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA , (SSL_ERROR_BASE + 89),
+"No certificate authority is trusted for SSL client authentication.")
+
+ER3(SSL_ERROR_SESSION_NOT_FOUND , (SSL_ERROR_BASE + 90),
+"Client's SSL session ID not found in server's session cache.")
+
+ER3(SSL_ERROR_DECRYPTION_FAILED_ALERT , (SSL_ERROR_BASE + 91),
+"Peer was unable to decrypt an SSL record it received.")
+
+ER3(SSL_ERROR_RECORD_OVERFLOW_ALERT , (SSL_ERROR_BASE + 92),
+"Peer received an SSL record that was longer than is permitted.")
+
+ER3(SSL_ERROR_UNKNOWN_CA_ALERT , (SSL_ERROR_BASE + 93),
+"Peer does not recognize and trust the CA that issued your certificate.")
+
+ER3(SSL_ERROR_ACCESS_DENIED_ALERT , (SSL_ERROR_BASE + 94),
+"Peer received a valid certificate, but access was denied.")
+
+ER3(SSL_ERROR_DECODE_ERROR_ALERT , (SSL_ERROR_BASE + 95),
+"Peer could not decode an SSL handshake message.")
+
+ER3(SSL_ERROR_DECRYPT_ERROR_ALERT , (SSL_ERROR_BASE + 96),
+"Peer reports failure of signature verification or key exchange.")
+
+ER3(SSL_ERROR_EXPORT_RESTRICTION_ALERT , (SSL_ERROR_BASE + 97),
+"Peer reports negotiation not in compliance with export regulations.")
+
+ER3(SSL_ERROR_PROTOCOL_VERSION_ALERT , (SSL_ERROR_BASE + 98),
+"Peer reports incompatible or unsupported protocol version.")
+
+ER3(SSL_ERROR_INSUFFICIENT_SECURITY_ALERT , (SSL_ERROR_BASE + 99),
+"Server requires ciphers more secure than those supported by client.")
+
+ER3(SSL_ERROR_INTERNAL_ERROR_ALERT , (SSL_ERROR_BASE + 100),
+"Peer reports it experienced an internal error.")
+
+ER3(SSL_ERROR_USER_CANCELED_ALERT , (SSL_ERROR_BASE + 101),
+"Peer user canceled handshake.")
+
+ER3(SSL_ERROR_NO_RENEGOTIATION_ALERT , (SSL_ERROR_BASE + 102),
+"Peer does not permit renegotiation of SSL security parameters.")
+
+ER3(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED , (SSL_ERROR_BASE + 103),
+"SSL server cache not configured and not disabled for this socket.")
+
+ER3(SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT , (SSL_ERROR_BASE + 104),
+"SSL peer does not support requested TLS hello extension.")
+
+ER3(SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT , (SSL_ERROR_BASE + 105),
+"SSL peer could not obtain your certificate from the supplied URL.")
+
+ER3(SSL_ERROR_UNRECOGNIZED_NAME_ALERT , (SSL_ERROR_BASE + 106),
+"SSL peer has no certificate for the requested DNS name.")
+
+ER3(SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT , (SSL_ERROR_BASE + 107),
+"SSL peer was unable to get an OCSP response for its certificate.")
+
+ER3(SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT , (SSL_ERROR_BASE + 108),
+"SSL peer reported bad certificate hash value.")
diff --git a/base/native-tools/src/p7tool/p7tool.c b/base/native-tools/src/p7tool/p7tool.c
new file mode 100644
index 000000000..9ab6023ff
--- /dev/null
+++ b/base/native-tools/src/p7tool/p7tool.c
@@ -0,0 +1,375 @@
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+/* This file is based upon the file originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N
+ * mozilla/security/nss/cmd/p7content/p7content.c
+ */
+
+/*
+ * p7tool -- A command to display/process pkcs7 content.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "nspr.h"
+#include "secutil.h"
+#include "plgetopt.h"
+#include "secpkcs7.h"
+#include "cert.h"
+#include "certdb.h"
+#include "nss.h"
+
+#if defined(XP_UNIX)
+#include <unistd.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#if (defined(XP_WIN) && !defined(WIN32)) || (defined(__sun) && !defined(SVR4))
+extern int fwrite(char *, size_t, size_t, FILE*);
+extern int fprintf(FILE *, char *, ...);
+#endif
+
+
+static void
+Usage(char *progName)
+{
+ fprintf(stderr,
+ "Usage: %s [-d dbdir] [-p chainFilePrefix] [-a] [-i input] [-o output]\n",
+ progName);
+ fprintf(stderr,
+ "%-20s Key/Cert database directory (default is ~/.netscape)\n",
+ "-d dbdir");
+ fprintf(stderr, "%-20s Define the cert chain file name prefix(default is chaincert)\n",
+ "-p chainFilePrefix");
+ fprintf(stderr, "%-20s Input is in ascii encoded form (RFC1113)\n",
+ "-a");
+ fprintf(stderr, "%-20s Define an input file to use (default is stdin)\n",
+ "-i input");
+ fprintf(stderr, "%-20s Define an output file to use (default is stdout)\n",
+ "-o output");
+ exit(-1);
+}
+
+static PRBool saw_content;
+
+static void
+PrintBytes(void *arg, const char *buf, unsigned long len)
+{
+ FILE *out;
+
+ out = arg;
+ fwrite (buf, len, 1, out);
+
+ saw_content = PR_TRUE;
+}
+
+/*
+ * XXX Someday we may want to do real policy stuff here. This allows
+ * anything to be decrypted, which is okay for a test program but does
+ * not set an example of how a real client with a real policy would
+ * need to do it.
+ */
+static PRBool
+decryption_allowed(SECAlgorithmID *algid, PK11SymKey *key)
+{
+ return PR_TRUE;
+}
+
+int
+DecodeAndPrintFile(FILE *out, PRFileDesc *in, char *progName, int ascii,
+ char *prefix)
+{
+ SECItem derdata;
+ SEC_PKCS7ContentInfo *cinfo = NULL;
+ SEC_PKCS7DecoderContext *dcx;
+ int rv;
+
+ if (SECU_ReadDERFromFile(&derdata, in, ascii)) {
+ SECU_PrintError(progName, "error converting der");
+ return -1;
+ }
+
+ fprintf(out, "Pretty Print of PKCS#7 content:\n");
+ rv = SECU_PrintPKCS7ContentInfo(out, &derdata,
+ "PKCS #7 Content Info", 0);
+/*
+ fprintf(out,
+ "Content printed between bars (newline added before second bar):");
+ fprintf(out, "\n---------------------------------------------\n");
+*/
+ if (rv) {
+ fprintf(stderr, "%s: problem converting data (%s)\n",
+ progName, SECU_Strerror(PORT_GetError()));
+ return -1;
+ }
+
+ saw_content = PR_FALSE;
+ dcx = SEC_PKCS7DecoderStart(PrintBytes, out, NULL, NULL,
+ NULL, NULL, decryption_allowed);
+ if (dcx != NULL) {
+#if 0 /* Test that decoder works when data is really streaming in. */
+ {
+ unsigned long i;
+ for (i = 0; i < derdata.len; i++)
+ SEC_PKCS7DecoderUpdate(dcx, derdata.data + i, 1);
+ }
+#else
+ SEC_PKCS7DecoderUpdate(dcx, (char *)derdata.data, derdata.len);
+#endif
+ cinfo = SEC_PKCS7DecoderFinish(dcx);
+ }
+/*
+ fprintf(out, "\n---------------------------------------------\n");
+*/
+ if (cinfo == NULL)
+ return -1;
+/*
+ fprintf(out, "Content was%s encrypted.\n",
+ SEC_PKCS7ContentIsEncrypted(cinfo) ? "" : " not");
+*/
+
+ if (SEC_PKCS7ContentIsSigned(cinfo)) {
+ char *signer_cname, *signer_ename;
+ SECItem *signing_time;
+
+ if (saw_content) {
+ fprintf(out, "Signature is ");
+ PORT_SetError(0);
+ if (SEC_PKCS7VerifySignature(cinfo, certUsageEmailSigner, PR_FALSE))
+ fprintf(out, "valid.\n");
+ else
+ fprintf(out, "invalid (Reason: %s).\n",
+ SECU_Strerror(PORT_GetError()));
+ } else {
+ fprintf(out,
+ "Content is detached; signature cannot be verified.\n");
+ }
+
+ signer_cname = SEC_PKCS7GetSignerCommonName(cinfo);
+ if (signer_cname != NULL) {
+ fprintf(out, "The signer's common name is %s\n", signer_cname);
+ PORT_Free(signer_cname);
+ } else {
+ fprintf(out, "No signer common name.\n");
+ }
+
+ signer_ename = SEC_PKCS7GetSignerEmailAddress(cinfo);
+ if (signer_ename != NULL) {
+ fprintf(out, "The signer's email address is %s\n", signer_ename);
+ PORT_Free(signer_ename);
+ } else {
+ fprintf(out, "No signer email address.\n");
+ }
+
+ signing_time = SEC_PKCS7GetSigningTime(cinfo);
+ if (signing_time != NULL) {
+ SECU_PrintTimeChoice(out, signing_time, "Signing time", 0);
+ } else {
+ fprintf(out, "No signing time included.\n");
+ }
+ } else {
+/* fprintf(out, "Content was not signed.\n");*/
+ }
+/*
+ fprintf(out, "There were%s certs or crls included.\n",
+ SEC_PKCS7ContainsCertsOrCrls(cinfo) ? "" : " no");
+*/
+
+ /* write out certs */
+ SECItem **items = NULL;
+ SECOidTag kind;
+
+ kind = SEC_PKCS7ContentType (cinfo);
+ if (kind == SEC_OID_PKCS7_SIGNED_DATA) {
+/* fprintf(out, "content is SEC_OID_PKCS7_SIGNED_DATA\n");*/
+ SEC_PKCS7SignedData *sdp;
+
+ sdp = cinfo->content.signedData;
+ if (sdp != NULL) {
+ items = sdp->rawCerts;
+ }
+ } else {
+/* fprintf(out, "content is not SEC_OID_PKCS7_SIGNED_DATA\n");*/
+
+ }
+
+ int i= 0;
+ if (items != NULL) {
+ CERTCertificate *cert;
+ if (prefix == NULL) {
+ prefix = "chaincert";
+ }
+ while ((items[i]) != NULL) {
+ cert = (CERTCertificate*) items[i]->data;
+ FILE *outFile;
+ char filename[256];
+ int nb = 0;
+
+ sprintf(filename, "%s%d.der", prefix, i);
+
+ outFile = fopen(filename, "wb");
+ if (outFile == NULL) {
+ fprintf(out, "Couldn't open '%s' file for writing\n", filename);
+ i = -1;
+ break;
+ }
+ nb = fwrite((char *) cert, 1, items[i]->len, outFile);
+ fclose(outFile);
+
+ i++;
+ }
+ } else {
+ fprintf(out, "certs is NULL\n");
+ }
+
+ SEC_PKCS7DestroyContentInfo(cinfo);
+ return i;
+}
+
+
+/*
+ * Print the contents of a PKCS7 message, indicating signatures, etc.
+ */
+
+int
+main(int argc, char **argv)
+{
+ char *progName;
+ FILE *outFile;
+ PRFileDesc *inFile;
+ PLOptState *optstate;
+ PLOptStatus status;
+ SECStatus rv;
+ int ascii = 0;
+ char *prefix = NULL;
+ int exitStatus = 0;
+
+ progName = strrchr(argv[0], '/');
+ progName = progName ? progName+1 : argv[0];
+
+ inFile = NULL;
+ outFile = NULL;
+
+ /*
+ * Parse command line arguments
+ */
+ optstate = PL_CreateOptState(argc, argv, "ad:i:o:p:");
+ while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
+ switch (optstate->option) {
+ case 'd':
+ SECU_ConfigDirectory(optstate->value);
+ break;
+
+ case 'a':
+ ascii = 1;
+ break;
+
+ case 'i':
+ inFile = PR_Open(optstate->value, PR_RDONLY, 0);
+ if (!inFile) {
+ fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
+ progName, optstate->value);
+ return -1;
+ }
+ break;
+
+ case 'o':
+ outFile = fopen(optstate->value, "w");
+ if (!outFile) {
+ fprintf(stderr, "%s: unable to open \"%s\" for writing\n",
+ progName, optstate->value);
+ return -1;
+ }
+ break;
+
+ case 'p':
+ prefix = optstate->value;
+ break;
+
+ default:
+ Usage(progName);
+ break;
+ }
+ }
+ if (status == PL_OPT_BAD)
+ Usage(progName);
+
+ if (!inFile) inFile = PR_STDIN;
+ if (!outFile) outFile = stdout;
+
+ /* Call the initialization routines */
+ PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
+ rv = NSS_Init(SECU_ConfigDirectory(NULL));
+ if (rv != SECSuccess) {
+ SECU_PrintPRandOSError(progName);
+ return -1;
+ }
+
+ exitStatus = DecodeAndPrintFile(outFile, inFile, progName, ascii, prefix);
+ if (exitStatus < 0) {
+ SECU_PrintError(progName, "problem decoding data");
+ return -1;
+ }
+
+ if (NSS_Shutdown() != SECSuccess) {
+ exit(1);
+ }
+
+ return exitStatus;
+/* return 0;*/
+}
diff --git a/base/native-tools/src/p7tool/pppolicy.c b/base/native-tools/src/p7tool/pppolicy.c
new file mode 100644
index 000000000..76ec6e8c6
--- /dev/null
+++ b/base/native-tools/src/p7tool/pppolicy.c
@@ -0,0 +1,309 @@
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/pppolicy.c
+ */
+
+/*
+ * Support for various policy related extensions
+ *
+ * $Id$
+ */
+
+#include "seccomon.h"
+#include "secport.h"
+#include "secder.h"
+#include "cert.h"
+#include "secoid.h"
+#include "secasn1.h"
+#include "secerr.h"
+#include "nspr.h"
+#include "secutil.h"
+
+/* This implementation is derived from the one in nss/lib/certdb/policyxtn.c .
+** The chief difference is the addition of the OPTIONAL flag to many
+** parts. The idea is to be able to parse and print as much of the
+** policy extension as possible, even if some parts are invalid.
+**
+** If this approach still is unable to decode policy extensions that
+** contain invalid parts, then the next approach will be to parse
+** the PolicyInfos as a SEQUENCE of ANYs, and then parse each of them
+** as PolicyInfos, with the PolicyQualifiers being ANYs, and finally
+** parse each of the PolicyQualifiers.
+*/
+
+static const SEC_ASN1Template secu_PolicyQualifierTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(CERTPolicyQualifier) },
+ { SEC_ASN1_OBJECT_ID,
+ offsetof(CERTPolicyQualifier, qualifierID),
+ NULL, 0},
+ { SEC_ASN1_ANY | SEC_ASN1_OPTIONAL,
+ offsetof(CERTPolicyQualifier, qualifierValue),
+ NULL, 0},
+ { 0, 0, NULL, 0 }
+};
+
+static const SEC_ASN1Template secu_PolicyInfoTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(CERTPolicyInfo) },
+ { SEC_ASN1_OBJECT_ID,
+ offsetof(CERTPolicyInfo, policyID),
+ NULL, 0},
+ { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_OPTIONAL,
+ offsetof(CERTPolicyInfo, policyQualifiers),
+ secu_PolicyQualifierTemplate, 0 },
+ { 0, 0, NULL, 0 }
+};
+
+static const SEC_ASN1Template secu_CertificatePoliciesTemplate[] = {
+ { SEC_ASN1_SEQUENCE_OF,
+ offsetof(CERTCertificatePolicies, policyInfos),
+ secu_PolicyInfoTemplate, sizeof(CERTCertificatePolicies) }
+};
+
+
+static CERTCertificatePolicies *
+secu_DecodeCertificatePoliciesExtension(SECItem *extnValue)
+{
+ PRArenaPool *arena = NULL;
+ SECStatus rv;
+ CERTCertificatePolicies *policies;
+ CERTPolicyInfo **policyInfos, *policyInfo;
+ CERTPolicyQualifier **policyQualifiers, *policyQualifier;
+ SECItem newExtnValue;
+
+ /* make a new arena */
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if ( !arena ) {
+ goto loser;
+ }
+
+ /* allocate the certifiate policies structure */
+ policies = PORT_ArenaZNew(arena, CERTCertificatePolicies);
+ if ( policies == NULL ) {
+ goto loser;
+ }
+
+ policies->arena = arena;
+
+ /* copy the DER into the arena, since Quick DER returns data that points
+ into the DER input, which may get freed by the caller */
+ rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ /* decode the policy info */
+ rv = SEC_QuickDERDecodeItem(arena, policies,
+ secu_CertificatePoliciesTemplate,
+ &newExtnValue);
+
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ /* initialize the oid tags */
+ policyInfos = policies->policyInfos;
+ while (policyInfos != NULL && *policyInfos != NULL ) {
+ policyInfo = *policyInfos;
+ policyInfo->oid = SECOID_FindOIDTag(&policyInfo->policyID);
+ policyQualifiers = policyInfo->policyQualifiers;
+ while ( policyQualifiers && *policyQualifiers != NULL ) {
+ policyQualifier = *policyQualifiers;
+ policyQualifier->oid =
+ SECOID_FindOIDTag(&policyQualifier->qualifierID);
+ policyQualifiers++;
+ }
+ policyInfos++;
+ }
+
+ return(policies);
+
+loser:
+ if ( arena != NULL ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return(NULL);
+}
+
+
+static char *
+itemToString(SECItem *item)
+{
+ char *string;
+
+ string = PORT_ZAlloc(item->len+1);
+ if (string == NULL) return NULL;
+ PORT_Memcpy(string,item->data,item->len);
+ string[item->len] = 0;
+ return string;
+}
+
+static SECStatus
+secu_PrintUserNoticeQualifier(FILE *out, SECItem * qualifierValue,
+ const char *msg, int level)
+{
+ CERTUserNotice *userNotice = NULL;
+ if (qualifierValue)
+ userNotice = CERT_DecodeUserNotice(qualifierValue);
+ if (userNotice) {
+ if (userNotice->noticeReference.organization.len != 0) {
+ char *string =
+ itemToString(&userNotice->noticeReference.organization);
+ SECItem **itemList = userNotice->noticeReference.noticeNumbers;
+
+ while (itemList && *itemList) {
+ SECU_PrintInteger(out,*itemList,string,level+1);
+ itemList++;
+ }
+ PORT_Free(string);
+ }
+ if (userNotice->displayText.len != 0) {
+ SECU_PrintString(out,&userNotice->displayText,
+ "Display Text", level+1);
+ }
+ CERT_DestroyUserNotice(userNotice);
+ return SECSuccess;
+ }
+ return SECFailure; /* caller will print this value */
+}
+
+static SECStatus
+secu_PrintPolicyQualifier(FILE *out,CERTPolicyQualifier *policyQualifier,
+ const char *msg, int level)
+{
+ SECStatus rv;
+ SECItem * qualifierValue = &policyQualifier->qualifierValue;
+
+ SECU_PrintObjectID(out, &policyQualifier->qualifierID ,
+ "Policy Qualifier Name", level);
+ if (!qualifierValue->data) {
+ SECU_Indent(out, level);
+ fprintf(out,"Error: missing qualifier\n");
+ } else
+ switch (policyQualifier->oid) {
+ case SEC_OID_PKIX_USER_NOTICE_QUALIFIER:
+ rv = secu_PrintUserNoticeQualifier(out, qualifierValue, msg, level);
+ if (SECSuccess == rv)
+ break;
+ /* fall through on error */
+ case SEC_OID_PKIX_CPS_POINTER_QUALIFIER:
+ default:
+ SECU_PrintAny(out, qualifierValue, "Policy Qualifier Data", level);
+ break;
+ }
+ return SECSuccess;
+}
+
+static SECStatus
+secu_PrintPolicyInfo(FILE *out, CERTPolicyInfo *policyInfo, const char *msg, int level)
+{
+ CERTPolicyQualifier **policyQualifiers;
+
+ policyQualifiers = policyInfo->policyQualifiers;
+ SECU_PrintObjectID(out, &policyInfo->policyID , "Policy Name", level);
+
+ while (policyQualifiers && *policyQualifiers != NULL) {
+ secu_PrintPolicyQualifier(out,*policyQualifiers,"",level+1);
+ policyQualifiers++;
+ }
+ return SECSuccess;
+}
+
+void
+SECU_PrintPolicy(FILE *out, SECItem *value, const char *msg, int level)
+{
+ CERTCertificatePolicies *policies = NULL;
+ CERTPolicyInfo **policyInfos;
+
+ if (msg) {
+ SECU_Indent(out, level);
+ fprintf(out,"%s: \n",msg);
+ level++;
+ }
+ policies = secu_DecodeCertificatePoliciesExtension(value);
+ if (policies == NULL) {
+ SECU_PrintAny(out, value, "Invalid Policy Data", level);
+ return;
+ }
+
+ policyInfos = policies->policyInfos;
+ while (policyInfos && *policyInfos != NULL) {
+ secu_PrintPolicyInfo(out,*policyInfos,"",level);
+ policyInfos++;
+ }
+
+ CERT_DestroyCertificatePoliciesExtension(policies);
+}
+
+
+void
+SECU_PrintPrivKeyUsagePeriodExtension(FILE *out, SECItem *value,
+ const char *msg, int level)
+{
+ CERTPrivKeyUsagePeriod * prd;
+ PLArenaPool * arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if ( !arena ) {
+ goto loser;
+ }
+ prd = CERT_DecodePrivKeyUsagePeriodExtension(arena, value);
+ if (!prd) {
+ goto loser;
+ }
+ if (prd->notBefore.data) {
+ SECU_PrintGeneralizedTime(out, &prd->notBefore, "Not Before", level);
+ }
+ if (prd->notAfter.data) {
+ SECU_PrintGeneralizedTime(out, &prd->notAfter, "Not After ", level);
+ }
+ if (!prd->notBefore.data && !prd->notAfter.data) {
+ SECU_Indent(out, level);
+ fprintf(out, "Error: notBefore or notAfter MUST be present.\n");
+loser:
+ SECU_PrintAny(out, value, msg, level);
+ }
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+}
diff --git a/base/native-tools/src/p7tool/secerror.c b/base/native-tools/src/p7tool/secerror.c
new file mode 100644
index 000000000..07e6bac8e
--- /dev/null
+++ b/base/native-tools/src/p7tool/secerror.c
@@ -0,0 +1,119 @@
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/secerror.c
+ */
+
+#include "nspr.h"
+#include "secerror.h"
+
+struct tuple_str {
+ PRErrorCode errNum;
+ const char * errString;
+};
+
+typedef struct tuple_str tuple_str;
+
+#define ER2(a,b) {a, b},
+#define ER3(a,b,c) {a, c},
+
+#include "secerr.h"
+#include "sslerr.h"
+
+const tuple_str errStrings[] = {
+
+/* keep this list in asceding order of error numbers */
+#include "SSLerrs.h"
+#include "SECerrs.h"
+#include "NSPRerrs.h"
+
+};
+
+const PRInt32 numStrings = sizeof(errStrings) / sizeof(tuple_str);
+
+/* Returns a UTF-8 encoded constant error string for "errNum".
+ * Returns NULL of errNum is unknown.
+ */
+const char *
+SECU_Strerror(PRErrorCode errNum) {
+ PRInt32 low = 0;
+ PRInt32 high = numStrings - 1;
+ PRInt32 i;
+ PRErrorCode num;
+ static int initDone;
+
+ /* make sure table is in ascending order.
+ * binary search depends on it.
+ */
+ if (!initDone) {
+ PRErrorCode lastNum = ((PRInt32)0x80000000);
+ for (i = low; i <= high; ++i) {
+ num = errStrings[i].errNum;
+ if (num <= lastNum) {
+ fprintf(stderr,
+"sequence error in error strings at item %d\n"
+"error %d (%s)\n"
+"should come after \n"
+"error %d (%s)\n",
+ i, lastNum, errStrings[i-1].errString,
+ num, errStrings[i].errString);
+ }
+ lastNum = num;
+ }
+ initDone = 1;
+ }
+
+ /* Do binary search of table. */
+ while (low + 1 < high) {
+ i = (low + high) / 2;
+ num = errStrings[i].errNum;
+ if (errNum == num)
+ return errStrings[i].errString;
+ if (errNum < num)
+ high = i;
+ else
+ low = i;
+ }
+ if (errNum == errStrings[low].errNum)
+ return errStrings[low].errString;
+ if (errNum == errStrings[high].errNum)
+ return errStrings[high].errString;
+ return NULL;
+}
diff --git a/base/native-tools/src/p7tool/secerror.h b/base/native-tools/src/p7tool/secerror.h
new file mode 100644
index 000000000..dce63728f
--- /dev/null
+++ b/base/native-tools/src/p7tool/secerror.h
@@ -0,0 +1,44 @@
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+#ifndef _SEC_ERROR_H_
+#define _SEC_ERROR_H_
+
+const char *
+SECU_Strerror(PRErrorCode errNum);
+
+#endif /* _SEC_ERROR_H_ */
diff --git a/base/native-tools/src/p7tool/secpwd.c b/base/native-tools/src/p7tool/secpwd.c
new file mode 100644
index 000000000..c0cb9b3d5
--- /dev/null
+++ b/base/native-tools/src/p7tool/secpwd.c
@@ -0,0 +1,213 @@
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/secpwd.c
+ */
+
+#include "secutil.h"
+
+/*
+ * NOTE: The contents of this file are NOT used by the client.
+ * (They are part of the security library as a whole, but they are
+ * NOT USED BY THE CLIENT.) Do not change things on behalf of the
+ * client (like localizing strings), or add things that are only
+ * for the client (put them elsewhere).
+ */
+
+
+#ifdef XP_UNIX
+#include <termios.h>
+#endif
+
+#if defined(XP_UNIX) || defined(XP_BEOS)
+#include <unistd.h> /* for isatty() */
+#endif
+
+#if( defined(_WINDOWS) && !defined(_WIN32_WCE)) || defined(XP_OS2_VACPP)
+#include <conio.h>
+#include <io.h>
+#define QUIET_FGETS quiet_fgets
+static char * quiet_fgets (char *buf, int length, FILE *input);
+#else
+#define QUIET_FGETS fgets
+#endif
+
+static void echoOff(int fd)
+{
+#if defined(XP_UNIX) && !defined(VMS)
+ if (isatty(fd)) {
+ struct termios tio;
+ tcgetattr(fd, &tio);
+ tio.c_lflag &= ~ECHO;
+ tcsetattr(fd, TCSAFLUSH, &tio);
+ }
+#endif
+}
+
+static void echoOn(int fd)
+{
+#if defined(XP_UNIX) && !defined(VMS)
+ if (isatty(fd)) {
+ struct termios tio;
+ tcgetattr(fd, &tio);
+ tio.c_lflag |= ECHO;
+ tcsetattr(fd, TCSAFLUSH, &tio);
+ }
+#endif
+}
+
+char *SEC_GetPassword(FILE *input, FILE *output, const char *prompt,
+ PRBool (*ok)(char *))
+{
+#if defined(_WINDOWS)
+ int isTTY = (input == stdin);
+#define echoOn(x)
+#define echoOff(x)
+#else
+ int infd = fileno(input);
+ int isTTY = isatty(infd);
+#endif
+ char phrase[200] = {'\0'}; /* ensure EOF doesn't return junk */
+
+ for (;;) {
+ /* Prompt for password */
+ if (isTTY) {
+ fprintf(output, "%s", prompt);
+ fflush (output);
+ echoOff(infd);
+ }
+
+ QUIET_FGETS ( phrase, sizeof(phrase), input);
+
+ if (isTTY) {
+ fprintf(output, "\n");
+ echoOn(infd);
+ }
+
+ /* stomp on newline */
+ phrase[PORT_Strlen(phrase)-1] = 0;
+
+ /* Validate password */
+ if (!(*ok)(phrase)) {
+ /* Not weird enough */
+ if (!isTTY) return 0;
+ fprintf(output, "Password must be at least 8 characters long with one or more\n");
+ fprintf(output, "non-alphabetic characters\n");
+ continue;
+ }
+ return (char*) PORT_Strdup(phrase);
+ }
+}
+
+
+
+PRBool SEC_CheckPassword(char *cp)
+{
+ int len;
+ char *end;
+
+ len = PORT_Strlen(cp);
+ if (len < 8) {
+ return PR_FALSE;
+ }
+ end = cp + len;
+ while (cp < end) {
+ unsigned char ch = *cp++;
+ if (!((ch >= 'A') && (ch <= 'Z')) &&
+ !((ch >= 'a') && (ch <= 'z'))) {
+ /* pass phrase has at least one non alphabetic in it */
+ return PR_TRUE;
+ }
+ }
+ return PR_FALSE;
+}
+
+PRBool SEC_BlindCheckPassword(char *cp)
+{
+ if (cp != NULL) {
+ return PR_TRUE;
+ }
+ return PR_FALSE;
+}
+
+/* Get a password from the input terminal, without echoing */
+
+#if defined(_WINDOWS) || defined(XP_OS2_VACPP)
+static char * quiet_fgets (char *buf, int length, FILE *input)
+ {
+ int c;
+ char *end = buf;
+
+ /* fflush (input); */
+ memset (buf, 0, length);
+
+#ifndef XP_OS2_VACPP
+ if (input != stdin) {
+ return fgets(buf,length,input);
+ }
+#else
+ if (!isatty(fileno(input))) {
+ return fgets(buf,length,input);
+ }
+#endif
+
+ while (1)
+ {
+#if defined (_WIN32_WCE)
+ c = getchar(); /* gets a character from stdin */
+#else
+ c = getch(); /* getch gets a character from the console */
+#endif
+ if (c == '\b')
+ {
+ if (end > buf)
+ end--;
+ }
+
+ else if (--length > 0)
+ *end++ = c;
+
+ if (!c || c == '\n' || c == '\r')
+ break;
+ }
+
+ return buf;
+ }
+#endif
diff --git a/base/native-tools/src/p7tool/secutil.c b/base/native-tools/src/p7tool/secutil.c
new file mode 100644
index 000000000..abdfd216f
--- /dev/null
+++ b/base/native-tools/src/p7tool/secutil.c
@@ -0,0 +1,3665 @@
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/secutil.c
+ */
+
+/*
+** secutil.c - various functions used by security stuff
+**
+*/
+
+#include "prtypes.h"
+#include "prtime.h"
+#include "prlong.h"
+#include "prerror.h"
+#include "prprf.h"
+#include "plgetopt.h"
+#include "prenv.h"
+#include "prnetdb.h"
+
+#include "cryptohi.h"
+#include "secerror.h"
+#include "secutil.h"
+#include "secpkcs7.h"
+#include <stdarg.h>
+#if !defined(_WIN32_WCE)
+#include <sys/stat.h>
+#include <errno.h>
+#endif
+
+#ifdef XP_UNIX
+#include <unistd.h>
+#endif
+
+/* for SEC_TraverseNames */
+#include "cert.h"
+#include "certt.h"
+#include "certdb.h"
+
+/* #include "secmod.h" */
+#include "pk11func.h"
+#include "secoid.h"
+
+static char consoleName[] = {
+#ifdef XP_UNIX
+#ifdef VMS
+ "TT"
+#else
+ "/dev/tty"
+#endif
+#else
+#ifdef XP_OS2
+ "\\DEV\\CON"
+#else
+ "CON:"
+#endif
+#endif
+};
+
+
+static char *
+SECU_GetString(int16 error_number)
+{
+
+ static char errString[80];
+ sprintf(errString, "Unknown error string (%d)", error_number);
+ return errString;
+}
+
+static void
+SECU_PrintErrMsg(FILE *out, int level, const char *progName, const char *msg, ...)
+{
+ va_list args;
+ PRErrorCode err = PORT_GetError();
+ const char * errString = SECU_Strerror(err);
+
+ va_start(args, msg);
+
+ SECU_Indent(out, level);
+ fprintf(out, "%s: ", progName);
+ vfprintf(out, msg, args);
+ if (errString != NULL && PORT_Strlen(errString) > 0)
+ fprintf(out, ": %s\n", errString);
+ else
+ fprintf(out, ": error %d\n", (int)err);
+
+ va_end(args);
+}
+
+void
+SECU_PrintError(const char *progName, const char *msg, ...)
+{
+ va_list args;
+ PRErrorCode err = PORT_GetError();
+ const char * errString = SECU_Strerror(err);
+
+ va_start(args, msg);
+
+ fprintf(stderr, "%s: ", progName);
+ vfprintf(stderr, msg, args);
+ if (errString != NULL && PORT_Strlen(errString) > 0)
+ fprintf(stderr, ": %s\n", errString);
+ else
+ fprintf(stderr, ": error %d\n", (int)err);
+
+ va_end(args);
+}
+
+void
+SECU_PrintSystemError(const char *progName, const char *msg, ...)
+{
+ va_list args;
+
+ va_start(args, msg);
+ fprintf(stderr, "%s: ", progName);
+ vfprintf(stderr, msg, args);
+#if defined(_WIN32_WCE)
+ fprintf(stderr, ": %d\n", PR_GetOSError());
+#else
+ fprintf(stderr, ": %s\n", strerror(errno));
+#endif
+ va_end(args);
+}
+
+static void
+secu_ClearPassword(char *p)
+{
+ if (p) {
+ PORT_Memset(p, 0, PORT_Strlen(p));
+ PORT_Free(p);
+ }
+}
+
+char *
+SECU_GetPasswordString(void *arg, char *prompt)
+{
+#ifndef _WINDOWS
+ char *p = NULL;
+ FILE *input, *output;
+
+ /* open terminal */
+ input = fopen(consoleName, "r");
+ if (input == NULL) {
+ fprintf(stderr, "Error opening input terminal for read\n");
+ return NULL;
+ }
+
+ output = fopen(consoleName, "w");
+ if (output == NULL) {
+ fprintf(stderr, "Error opening output terminal for write\n");
+ fclose(input);
+ return NULL;
+ }
+
+ p = SEC_GetPassword (input, output, prompt, SEC_BlindCheckPassword);
+
+
+ fclose(input);
+ fclose(output);
+
+ return p;
+
+#else
+ /* Win32 version of above. opening the console may fail
+ on windows95, and certainly isn't necessary.. */
+
+ char *p = NULL;
+
+ p = SEC_GetPassword (stdin, stdout, prompt, SEC_BlindCheckPassword);
+ return p;
+
+#endif
+}
+
+
+/*
+ * p a s s w o r d _ h a r d c o d e
+ *
+ * A function to use the password passed in the -f(pwfile) argument
+ * of the command line.
+ * After use once, null it out otherwise PKCS11 calls us forever.?
+ *
+ */
+char *
+SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg)
+{
+ unsigned char phrase[200];
+ PRFileDesc *fd;
+ PRInt32 nb;
+ char *pwFile = arg;
+ int i;
+
+ if (!pwFile)
+ return 0;
+
+ if (retry) {
+ return 0; /* no good retrying - the files contents will be the same */
+ }
+
+ fd = PR_Open(pwFile, PR_RDONLY, 0);
+ if (!fd) {
+ fprintf(stderr, "No password file \"%s\" exists.\n", pwFile);
+ return NULL;
+ }
+
+ nb = PR_Read(fd, phrase, sizeof(phrase));
+
+ PR_Close(fd);
+ /* handle the Windows EOL case */
+ i = 0;
+ while (phrase[i] != '\r' && phrase[i] != '\n' && i < nb) i++;
+ phrase[i] = '\0';
+ if (nb == 0) {
+ fprintf(stderr,"password file contains no data\n");
+ return NULL;
+ }
+ return (char*) PORT_Strdup((char*)phrase);
+}
+
+char *
+SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg)
+{
+ char prompt[255];
+ char external[] = "external";
+ secuPWData *pwdata = (secuPWData *)arg;
+ secuPWData pwnull = { PW_NONE, 0 };
+ secuPWData pwxtrn = { PW_EXTERNAL, external };
+ char *pw;
+
+ if (pwdata == NULL)
+ pwdata = &pwnull;
+
+ if (PK11_ProtectedAuthenticationPath(slot)) {
+ pwdata = &pwxtrn;
+ }
+ if (retry && pwdata->source != PW_NONE) {
+ PR_fprintf(PR_STDERR, "Incorrect password/PIN entered.\n");
+ return NULL;
+ }
+
+ switch (pwdata->source) {
+ case PW_NONE:
+ sprintf(prompt, "Enter Password or Pin for \"%s\":",
+ PK11_GetTokenName(slot));
+ return SECU_GetPasswordString(NULL, prompt);
+ case PW_FROMFILE:
+ /* Instead of opening and closing the file every time, get the pw
+ * once, then keep it in memory (duh).
+ */
+ pw = SECU_FilePasswd(slot, retry, pwdata->data);
+ pwdata->source = PW_PLAINTEXT;
+ pwdata->data = PL_strdup(pw);
+ /* it's already been dup'ed */
+ return pw;
+ case PW_EXTERNAL:
+ sprintf(prompt,
+ "Press Enter, then enter PIN for \"%s\" on external device.\n",
+ PK11_GetTokenName(slot));
+ (void) SECU_GetPasswordString(NULL, prompt);
+ /* Fall Through */
+ case PW_PLAINTEXT:
+ return PL_strdup(pwdata->data);
+ default:
+ break;
+ }
+
+ PR_fprintf(PR_STDERR, "Password check failed: No password found.\n");
+ return NULL;
+}
+
+static char *
+secu_InitSlotPassword(PK11SlotInfo *slot, PRBool retry, void *arg)
+{
+ char *p0 = NULL;
+ char *p1 = NULL;
+ FILE *input, *output;
+ secuPWData *pwdata = arg;
+
+ if (pwdata->source == PW_FROMFILE) {
+ return SECU_FilePasswd(slot, retry, pwdata->data);
+ }
+ if (pwdata->source == PW_PLAINTEXT) {
+ return PL_strdup(pwdata->data);
+ }
+
+ /* PW_NONE - get it from tty */
+ /* open terminal */
+#ifdef _WINDOWS
+ input = stdin;
+#else
+ input = fopen(consoleName, "r");
+#endif
+ if (input == NULL) {
+ PR_fprintf(PR_STDERR, "Error opening input terminal for read\n");
+ return NULL;
+ }
+
+ /* we have no password, so initialize database with one */
+ PR_fprintf(PR_STDERR,
+ "Enter a password which will be used to encrypt your keys.\n"
+ "The password should be at least 8 characters long,\n"
+ "and should contain at least one non-alphabetic character.\n\n");
+
+ output = fopen(consoleName, "w");
+ if (output == NULL) {
+ PR_fprintf(PR_STDERR, "Error opening output terminal for write\n");
+ fclose(input);
+ return NULL;
+ }
+
+
+ for (;;) {
+ if (p0)
+ PORT_Free(p0);
+ p0 = SEC_GetPassword(input, output, "Enter new password: ",
+ SEC_BlindCheckPassword);
+
+ if (p1)
+ PORT_Free(p1);
+ p1 = SEC_GetPassword(input, output, "Re-enter password: ",
+ SEC_BlindCheckPassword);
+ if (p0 && p1 && !PORT_Strcmp(p0, p1)) {
+ break;
+ }
+ PR_fprintf(PR_STDERR, "Passwords do not match. Try again.\n");
+ }
+
+ /* clear out the duplicate password string */
+ secu_ClearPassword(p1);
+
+ fclose(input);
+ fclose(output);
+
+ return p0;
+}
+
+SECStatus
+SECU_ChangePW(PK11SlotInfo *slot, char *passwd, char *pwFile)
+{
+ SECStatus rv;
+ secuPWData pwdata, newpwdata;
+ char *oldpw = NULL, *newpw = NULL;
+
+ if (passwd) {
+ pwdata.source = PW_PLAINTEXT;
+ pwdata.data = passwd;
+ } else if (pwFile) {
+ pwdata.source = PW_FROMFILE;
+ pwdata.data = pwFile;
+ } else {
+ pwdata.source = PW_NONE;
+ pwdata.data = NULL;
+ }
+
+ if (PK11_NeedUserInit(slot)) {
+ newpw = secu_InitSlotPassword(slot, PR_FALSE, &pwdata);
+ rv = PK11_InitPin(slot, (char*)NULL, newpw);
+ goto done;
+ }
+
+ for (;;) {
+ oldpw = SECU_GetModulePassword(slot, PR_FALSE, &pwdata);
+
+ if (PK11_CheckUserPassword(slot, oldpw) != SECSuccess) {
+ if (pwdata.source == PW_NONE) {
+ PR_fprintf(PR_STDERR, "Invalid password. Try again.\n");
+ } else {
+ PR_fprintf(PR_STDERR, "Invalid password.\n");
+ PORT_Memset(oldpw, 0, PL_strlen(oldpw));
+ PORT_Free(oldpw);
+ return SECFailure;
+ }
+ } else
+ break;
+
+ PORT_Free(oldpw);
+ }
+
+ newpwdata.source = PW_NONE;
+ newpwdata.data = NULL;
+
+ newpw = secu_InitSlotPassword(slot, PR_FALSE, &newpwdata);
+
+ if (PK11_ChangePW(slot, oldpw, newpw) != SECSuccess) {
+ PR_fprintf(PR_STDERR, "Failed to change password.\n");
+ return SECFailure;
+ }
+
+ PORT_Memset(oldpw, 0, PL_strlen(oldpw));
+ PORT_Free(oldpw);
+
+ PR_fprintf(PR_STDOUT, "Password changed successfully.\n");
+
+done:
+ PORT_Memset(newpw, 0, PL_strlen(newpw));
+ PORT_Free(newpw);
+ return SECSuccess;
+}
+
+struct matchobj {
+ SECItem index;
+ char *nname;
+ PRBool found;
+};
+
+char *
+SECU_DefaultSSLDir(void)
+{
+ char *dir;
+ static char sslDir[1000];
+
+ dir = PR_GetEnv("SSL_DIR");
+ if (!dir)
+ return NULL;
+
+ sprintf(sslDir, "%s", dir);
+
+ if (sslDir[strlen(sslDir)-1] == '/')
+ sslDir[strlen(sslDir)-1] = 0;
+
+ return sslDir;
+}
+
+char *
+SECU_AppendFilenameToDir(char *dir, char *filename)
+{
+ static char path[1000];
+
+ if (dir[strlen(dir)-1] == '/')
+ sprintf(path, "%s%s", dir, filename);
+ else
+ sprintf(path, "%s/%s", dir, filename);
+ return path;
+}
+
+char *
+SECU_ConfigDirectory(const char* base)
+{
+ static PRBool initted = PR_FALSE;
+ const char *dir = ".netscape";
+ const char *home;
+ static char buf[1000];
+
+ if (initted) return buf;
+
+
+ if (base == NULL || *base == 0) {
+ home = PR_GetEnv("HOME");
+ if (!home) home = "";
+
+ if (*home && home[strlen(home) - 1] == '/')
+ sprintf (buf, "%.900s%s", home, dir);
+ else
+ sprintf (buf, "%.900s/%s", home, dir);
+ } else {
+ sprintf(buf, "%.900s", base);
+ if (buf[strlen(buf) - 1] == '/')
+ buf[strlen(buf) - 1] = 0;
+ }
+
+
+ initted = PR_TRUE;
+ return buf;
+}
+
+/*Turn off SSL for now */
+/* This gets called by SSL when server wants our cert & key */
+int
+SECU_GetClientAuthData(void *arg, PRFileDesc *fd,
+ struct CERTDistNamesStr *caNames,
+ struct CERTCertificateStr **pRetCert,
+ struct SECKEYPrivateKeyStr **pRetKey)
+{
+ SECKEYPrivateKey *key;
+ CERTCertificate *cert;
+ int errsave;
+
+ if (arg == NULL) {
+ fprintf(stderr, "no key/cert name specified for client auth\n");
+ return -1;
+ }
+ cert = PK11_FindCertFromNickname(arg, NULL);
+ errsave = PORT_GetError();
+ if (!cert) {
+ if (errsave == SEC_ERROR_BAD_PASSWORD)
+ fprintf(stderr, "Bad password\n");
+ else if (errsave > 0)
+ fprintf(stderr, "Unable to read cert (error %d)\n", errsave);
+ else if (errsave == SEC_ERROR_BAD_DATABASE)
+ fprintf(stderr, "Unable to get cert from database (%d)\n", errsave);
+ else
+ fprintf(stderr, "SECKEY_FindKeyByName: internal error %d\n", errsave);
+ return -1;
+ }
+
+ key = PK11_FindKeyByAnyCert(arg,NULL);
+ if (!key) {
+ fprintf(stderr, "Unable to get key (%d)\n", PORT_GetError());
+ return -1;
+ }
+
+
+ *pRetCert = cert;
+ *pRetKey = key;
+
+ return 0;
+}
+
+static SECStatus
+secu_StdinToItem(SECItem *dst)
+{
+ unsigned char buf[1000];
+ PRInt32 numBytes;
+ PRBool notDone = PR_TRUE;
+
+ dst->len = 0;
+ dst->data = NULL;
+
+ while (notDone) {
+ numBytes = PR_Read(PR_STDIN, buf, sizeof(buf));
+
+ if (numBytes < 0) {
+ return SECFailure;
+ }
+
+ if (numBytes == 0)
+ break;
+
+ if (dst->data) {
+ unsigned char * p = dst->data;
+ dst->data = (unsigned char*)PORT_Realloc(p, dst->len + numBytes);
+ if (!dst->data) {
+ PORT_Free(p);
+ }
+ } else {
+ dst->data = (unsigned char*)PORT_Alloc(numBytes);
+ }
+ if (!dst->data) {
+ return SECFailure;
+ }
+ PORT_Memcpy(dst->data + dst->len, buf, numBytes);
+ dst->len += numBytes;
+ }
+
+ return SECSuccess;
+}
+
+SECStatus
+SECU_FileToItem(SECItem *dst, PRFileDesc *src)
+{
+ PRFileInfo info;
+ PRInt32 numBytes;
+ PRStatus prStatus;
+
+ if (src == PR_STDIN)
+ return secu_StdinToItem(dst);
+
+ prStatus = PR_GetOpenFileInfo(src, &info);
+
+ if (prStatus != PR_SUCCESS) {
+ PORT_SetError(SEC_ERROR_IO);
+ return SECFailure;
+ }
+
+ /* XXX workaround for 3.1, not all utils zero dst before sending */
+ dst->data = 0;
+ if (!SECITEM_AllocItem(NULL, dst, info.size))
+ goto loser;
+
+ numBytes = PR_Read(src, dst->data, info.size);
+ if (numBytes != info.size) {
+ PORT_SetError(SEC_ERROR_IO);
+ goto loser;
+ }
+
+ return SECSuccess;
+loser:
+ SECITEM_FreeItem(dst, PR_FALSE);
+ return SECFailure;
+}
+
+SECStatus
+SECU_TextFileToItem(SECItem *dst, PRFileDesc *src)
+{
+ PRFileInfo info;
+ PRInt32 numBytes;
+ PRStatus prStatus;
+ unsigned char *buf;
+
+ if (src == PR_STDIN)
+ return secu_StdinToItem(dst);
+
+ prStatus = PR_GetOpenFileInfo(src, &info);
+
+ if (prStatus != PR_SUCCESS) {
+ PORT_SetError(SEC_ERROR_IO);
+ return SECFailure;
+ }
+
+ buf = (unsigned char*)PORT_Alloc(info.size);
+ if (!buf)
+ return SECFailure;
+
+ numBytes = PR_Read(src, buf, info.size);
+ if (numBytes != info.size) {
+ PORT_SetError(SEC_ERROR_IO);
+ goto loser;
+ }
+
+ if (buf[numBytes-1] == '\n') numBytes--;
+#ifdef _WINDOWS
+ if (buf[numBytes-1] == '\r') numBytes--;
+#endif
+
+ /* XXX workaround for 3.1, not all utils zero dst before sending */
+ dst->data = 0;
+ if (!SECITEM_AllocItem(NULL, dst, numBytes))
+ goto loser;
+
+ memcpy(dst->data, buf, numBytes);
+
+ PORT_Free(buf);
+ return SECSuccess;
+loser:
+ PORT_Free(buf);
+ return SECFailure;
+}
+
+SECStatus
+SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii)
+{
+ SECStatus rv;
+ if (ascii) {
+ /* First convert ascii to binary */
+ SECItem filedata;
+ char *asc, *body;
+
+ /* Read in ascii data */
+ rv = SECU_FileToItem(&filedata, inFile);
+ asc = (char *)filedata.data;
+ if (!asc) {
+ fprintf(stderr, "unable to read data from input file\n");
+ return SECFailure;
+ }
+
+ /* check for headers and trailers and remove them */
+ if ((body = strstr(asc, "-----BEGIN")) != NULL) {
+ char *trailer = NULL;
+ asc = body;
+ body = PORT_Strchr(body, '\n');
+ if (!body)
+ body = PORT_Strchr(asc, '\r'); /* maybe this is a MAC file */
+ if (body)
+ trailer = strstr(++body, "-----END");
+ if (trailer != NULL) {
+ *trailer = '\0';
+ } else {
+ fprintf(stderr, "input has header but no trailer\n");
+ PORT_Free(filedata.data);
+ return SECFailure;
+ }
+ } else {
+ body = asc;
+ }
+
+ /* Convert to binary */
+ rv = ATOB_ConvertAsciiToItem(der, body);
+ if (rv) {
+ fprintf(stderr, "error converting ascii to binary (%s)\n",
+ SECU_Strerror(PORT_GetError()));
+ PORT_Free(filedata.data);
+ return SECFailure;
+ }
+
+ PORT_Free(filedata.data);
+ } else {
+ /* Read in binary der */
+ rv = SECU_FileToItem(der, inFile);
+ if (rv) {
+ fprintf(stderr, "error converting der (%s)\n",
+ SECU_Strerror(PORT_GetError()));
+ return SECFailure;
+ }
+ }
+ return SECSuccess;
+}
+
+#define INDENT_MULT 4
+void
+SECU_Indent(FILE *out, int level)
+{
+ int i;
+
+ for (i = 0; i < level; i++) {
+ fprintf(out, " ");
+ }
+}
+
+static void secu_Newline(FILE *out)
+{
+ fprintf(out, "\n");
+}
+
+void
+SECU_PrintAsHex(FILE *out, SECItem *data, const char *m, int level)
+{
+ unsigned i;
+ int column;
+ PRBool isString = PR_TRUE;
+ PRBool isWhiteSpace = PR_TRUE;
+ PRBool printedHex = PR_FALSE;
+ unsigned int limit = 15;
+
+ if ( m ) {
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ level++;
+ }
+
+ SECU_Indent(out, level); column = level*INDENT_MULT;
+ if (!data->len) {
+ fprintf(out, "(empty)\n");
+ return;
+ }
+ /* take a pass to see if it's all printable. */
+ for (i = 0; i < data->len; i++) {
+ unsigned char val = data->data[i];
+ if (!val || !isprint(val)) {
+ isString = PR_FALSE;
+ break;
+ }
+ if (isWhiteSpace && !isspace(val)) {
+ isWhiteSpace = PR_FALSE;
+ }
+ }
+
+ /* Short values, such as bit strings (which are printed with this
+ ** function) often look like strings, but we want to see the bits.
+ ** so this test assures that short values will be printed in hex,
+ ** perhaps in addition to being printed as strings.
+ ** The threshold size (4 bytes) is arbitrary.
+ */
+ if (!isString || data->len <= 4) {
+ for (i = 0; i < data->len; i++) {
+ if (i != data->len - 1) {
+ fprintf(out, "%02x:", data->data[i]);
+ column += 3;
+ } else {
+ fprintf(out, "%02x", data->data[i]);
+ column += 2;
+ break;
+ }
+ if (column > 76 || (i % 16 == limit)) {
+ secu_Newline(out);
+ SECU_Indent(out, level);
+ column = level*INDENT_MULT;
+ limit = i % 16;
+ }
+ }
+ printedHex = PR_TRUE;
+ }
+ if (isString && !isWhiteSpace) {
+ if (printedHex != PR_FALSE) {
+ secu_Newline(out);
+ SECU_Indent(out, level); column = level*INDENT_MULT;
+ }
+ for (i = 0; i < data->len; i++) {
+ unsigned char val = data->data[i];
+
+ if (val) {
+ fprintf(out,"%c",val);
+ column++;
+ } else {
+ column = 77;
+ }
+ if (column > 76) {
+ secu_Newline(out);
+ SECU_Indent(out, level); column = level*INDENT_MULT;
+ }
+ }
+ }
+
+ if (column != level*INDENT_MULT) {
+ secu_Newline(out);
+ }
+}
+
+static const char *hex = "0123456789abcdef";
+
+static const char printable[257] = {
+ "................" /* 0x */
+ "................" /* 1x */
+ " !\"#$%&'()*+,-./" /* 2x */
+ "0123456789:;<=>?" /* 3x */
+ "@ABCDEFGHIJKLMNO" /* 4x */
+ "PQRSTUVWXYZ[\\]^_" /* 5x */
+ "`abcdefghijklmno" /* 6x */
+ "pqrstuvwxyz{|}~." /* 7x */
+ "................" /* 8x */
+ "................" /* 9x */
+ "................" /* ax */
+ "................" /* bx */
+ "................" /* cx */
+ "................" /* dx */
+ "................" /* ex */
+ "................" /* fx */
+};
+
+void
+SECU_PrintBuf(FILE *out, const char *msg, const void *vp, int len)
+{
+ const unsigned char *cp = (const unsigned char *)vp;
+ char buf[80];
+ char *bp;
+ char *ap;
+
+ fprintf(out, "%s [Len: %d]\n", msg, len);
+ memset(buf, ' ', sizeof buf);
+ bp = buf;
+ ap = buf + 50;
+ while (--len >= 0) {
+ unsigned char ch = *cp++;
+ *bp++ = hex[(ch >> 4) & 0xf];
+ *bp++ = hex[ch & 0xf];
+ *bp++ = ' ';
+ *ap++ = printable[ch];
+ if (ap - buf >= 66) {
+ *ap = 0;
+ fprintf(out, " %s\n", buf);
+ memset(buf, ' ', sizeof buf);
+ bp = buf;
+ ap = buf + 50;
+ }
+ }
+ if (bp > buf) {
+ *ap = 0;
+ fprintf(out, " %s\n", buf);
+ }
+}
+
+static SECStatus
+SECU_StripTagAndLength(SECItem *i)
+{
+ unsigned int start;
+
+ if (!i || !i->data || i->len < 2) { /* must be at least tag and length */
+ return SECFailure;
+ }
+ start = ((i->data[1] & 0x80) ? (i->data[1] & 0x7f) + 2 : 2);
+ if (i->len < start) {
+ return SECFailure;
+ }
+ i->data += start;
+ i->len -= start;
+ return SECSuccess;
+}
+
+
+/* This expents i->data[0] to be the MSB of the integer.
+** if you want to print a DER-encoded integer (with the tag and length)
+** call SECU_PrintEncodedInteger();
+*/
+void
+SECU_PrintInteger(FILE *out, SECItem *i, const char *m, int level)
+{
+ int iv;
+
+ if (!i || !i->len || !i->data) {
+ SECU_Indent(out, level);
+ if (m) {
+ fprintf(out, "%s: (null)\n", m);
+ } else {
+ fprintf(out, "(null)\n");
+ }
+ } else if (i->len > 4) {
+ SECU_PrintAsHex(out, i, m, level);
+ } else {
+ iv = DER_GetInteger(i);
+ SECU_Indent(out, level);
+ if (m) {
+ fprintf(out, "%s: %d (0x%x)\n", m, iv, iv);
+ } else {
+ fprintf(out, "%d (0x%x)\n", iv, iv);
+ }
+ }
+}
+
+static void
+secu_PrintRawString(FILE *out, SECItem *si, const char *m, int level)
+{
+ int column;
+ unsigned int i;
+
+ if ( m ) {
+ SECU_Indent(out, level); fprintf(out, "%s: ", m);
+ column = (level * INDENT_MULT) + strlen(m) + 2;
+ level++;
+ } else {
+ SECU_Indent(out, level);
+ column = level*INDENT_MULT;
+ }
+ fprintf(out, "\""); column++;
+
+ for (i = 0; i < si->len; i++) {
+ unsigned char val = si->data[i];
+ if (column > 76) {
+ secu_Newline(out);
+ SECU_Indent(out, level); column = level*INDENT_MULT;
+ }
+
+ fprintf(out,"%c", printable[val]); column++;
+ }
+
+ fprintf(out, "\""); column++;
+ if (column != level*INDENT_MULT || column > 76) {
+ secu_Newline(out);
+ }
+}
+
+void
+SECU_PrintString(FILE *out, SECItem *si, const char *m, int level)
+{
+ SECItem my = *si;
+
+ if (SECSuccess != SECU_StripTagAndLength(&my) || !my.len)
+ return;
+ secu_PrintRawString(out, &my, m, level);
+}
+
+/* print an unencoded boolean */
+static void
+secu_PrintBoolean(FILE *out, SECItem *i, const char *m, int level)
+{
+ int val = 0;
+
+ if ( i->data && i->len ) {
+ val = i->data[0];
+ }
+
+ if (!m) {
+ m = "Boolean";
+ }
+ SECU_Indent(out, level);
+ fprintf(out, "%s: %s\n", m, (val ? "True" : "False"));
+}
+
+/*
+ * Format and print "time_val". If the tag message "m" is not NULL,
+ * do indent formatting based on "level" and add a newline afterward;
+ * otherwise just print the formatted time string only.
+ */
+static void
+secu_PrintTime(FILE *out, int64 time_val, const char *m, int level)
+{
+ PRExplodedTime printableTime;
+ char *timeString;
+
+ /* Convert to local time */
+ PR_ExplodeTime(time_val, PR_GMTParameters, &printableTime);
+
+ timeString = PORT_Alloc(100);
+ if (timeString == NULL)
+ return;
+
+ if (m != NULL) {
+ SECU_Indent(out, level);
+ fprintf(out, "%s: ", m);
+ }
+
+ PR_FormatTime(timeString, 100, "%a %b %d %H:%M:%S %Y", &printableTime);
+ fprintf(out, "%s", timeString);
+
+ if (m != NULL)
+ fprintf(out, "\n");
+
+ PORT_Free(timeString);
+}
+
+/*
+ * Format and print the UTC Time "t". If the tag message "m" is not NULL,
+ * do indent formatting based on "level" and add a newline afterward;
+ * otherwise just print the formatted time string only.
+ */
+void
+SECU_PrintUTCTime(FILE *out, SECItem *t, const char *m, int level)
+{
+ int64 time_val;
+ SECStatus rv;
+
+ rv = DER_UTCTimeToTime(&time_val, t);
+ if (rv != SECSuccess)
+ return;
+
+ secu_PrintTime(out, time_val, m, level);
+}
+
+/*
+ * Format and print the Generalized Time "t". If the tag message "m"
+ * is not NULL, * do indent formatting based on "level" and add a newline
+ * afterward; otherwise just print the formatted time string only.
+ */
+void
+SECU_PrintGeneralizedTime(FILE *out, SECItem *t, const char *m, int level)
+{
+ int64 time_val;
+ SECStatus rv;
+
+
+ rv = DER_GeneralizedTimeToTime(&time_val, t);
+ if (rv != SECSuccess)
+ return;
+
+ secu_PrintTime(out, time_val, m, level);
+}
+
+/*
+ * Format and print the UTC or Generalized Time "t". If the tag message
+ * "m" is not NULL, do indent formatting based on "level" and add a newline
+ * afterward; otherwise just print the formatted time string only.
+ */
+void
+SECU_PrintTimeChoice(FILE *out, SECItem *t, const char *m, int level)
+{
+ switch (t->type) {
+ case siUTCTime:
+ SECU_PrintUTCTime(out, t, m, level);
+ break;
+
+ case siGeneralizedTime:
+ SECU_PrintGeneralizedTime(out, t, m, level);
+ break;
+
+ default:
+ PORT_Assert(0);
+ break;
+ }
+}
+
+
+/* This prints a SET or SEQUENCE */
+static void
+SECU_PrintSet(FILE *out, SECItem *t, const char *m, int level)
+{
+ int type = t->data[0] & SEC_ASN1_TAGNUM_MASK;
+ int constructed = t->data[0] & SEC_ASN1_CONSTRUCTED;
+ const char * label;
+ SECItem my = *t;
+
+ if (!constructed) {
+ SECU_PrintAsHex(out, t, m, level);
+ return;
+ }
+ if (SECSuccess != SECU_StripTagAndLength(&my))
+ return;
+
+ SECU_Indent(out, level);
+ if (m) {
+ fprintf(out, "%s: ", m);
+ }
+
+ if (type == SEC_ASN1_SET)
+ label = "Set ";
+ else if (type == SEC_ASN1_SEQUENCE)
+ label = "Sequence ";
+ else
+ label = "";
+ fprintf(out,"%s{\n", label); /* } */
+
+ while (my.len >= 2) {
+ SECItem tmp = my;
+
+ if (tmp.data[1] & 0x80) {
+ unsigned int i;
+ unsigned int lenlen = tmp.data[1] & 0x7f;
+ if (lenlen > sizeof tmp.len)
+ break;
+ tmp.len = 0;
+ for (i=0; i < lenlen; i++) {
+ tmp.len = (tmp.len << 8) | tmp.data[2+i];
+ }
+ tmp.len += lenlen + 2;
+ } else {
+ tmp.len = tmp.data[1] + 2;
+ }
+ if (tmp.len > my.len) {
+ tmp.len = my.len;
+ }
+ my.data += tmp.len;
+ my.len -= tmp.len;
+ SECU_PrintAny(out, &tmp, NULL, level + 1);
+ }
+ SECU_Indent(out, level); fprintf(out, /* { */ "}\n");
+}
+
+static void
+secu_PrintContextSpecific(FILE *out, SECItem *i, const char *m, int level)
+{
+ int type = i->data[0] & SEC_ASN1_TAGNUM_MASK;
+ int constructed = i->data[0] & SEC_ASN1_CONSTRUCTED;
+ SECItem tmp;
+
+ if (constructed) {
+ char * m2;
+ if (!m)
+ m2 = PR_smprintf("[%d]", type);
+ else
+ m2 = PR_smprintf("%s: [%d]", m, type);
+ if (m2) {
+ SECU_PrintSet(out, i, m2, level);
+ PR_smprintf_free(m2);
+ }
+ return;
+ }
+
+ SECU_Indent(out, level);
+ if (m) {
+ fprintf(out, "%s: ", m);
+ }
+ fprintf(out,"[%d]\n", type);
+
+ tmp = *i;
+ if (SECSuccess == SECU_StripTagAndLength(&tmp))
+ SECU_PrintAsHex(out, &tmp, m, level+1);
+}
+
+static void
+secu_PrintOctetString(FILE *out, SECItem *i, const char *m, int level)
+{
+ SECItem tmp = *i;
+ if (SECSuccess == SECU_StripTagAndLength(&tmp))
+ SECU_PrintAsHex(out, &tmp, m, level);
+}
+
+static void
+secu_PrintBitString(FILE *out, SECItem *i, const char *m, int level)
+{
+ int unused_bits;
+ SECItem tmp = *i;
+
+ if (SECSuccess != SECU_StripTagAndLength(&tmp) || tmp.len < 2)
+ return;
+
+ unused_bits = *tmp.data++;
+ tmp.len--;
+
+ SECU_PrintAsHex(out, &tmp, m, level);
+ if (unused_bits) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "(%d least significant bits unused)\n", unused_bits);
+ }
+}
+
+/* in a decoded bit string, the len member is a bit length. */
+static void
+secu_PrintDecodedBitString(FILE *out, SECItem *i, const char *m, int level)
+{
+ int unused_bits;
+ SECItem tmp = *i;
+
+
+ unused_bits = (tmp.len & 0x7) ? 8 - (tmp.len & 7) : 0;
+ DER_ConvertBitString(&tmp); /* convert length to byte length */
+
+ SECU_PrintAsHex(out, &tmp, m, level);
+ if (unused_bits) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "(%d least significant bits unused)\n", unused_bits);
+ }
+}
+
+
+/* Print a DER encoded Boolean */
+static void
+SECU_PrintEncodedBoolean(FILE *out, SECItem *i, const char *m, int level)
+{
+ SECItem my = *i;
+ if (SECSuccess == SECU_StripTagAndLength(&my))
+ secu_PrintBoolean(out, &my, m, level);
+}
+
+/* Print a DER encoded integer */
+static void
+SECU_PrintEncodedInteger(FILE *out, SECItem *i, const char *m, int level)
+{
+ SECItem my = *i;
+ if (SECSuccess == SECU_StripTagAndLength(&my))
+ SECU_PrintInteger(out, &my, m, level);
+}
+
+/* Print a DER encoded OID */
+static void
+SECU_PrintEncodedObjectID(FILE *out, SECItem *i, const char *m, int level)
+{
+ SECItem my = *i;
+ if (SECSuccess == SECU_StripTagAndLength(&my))
+ SECU_PrintObjectID(out, &my, m, level);
+}
+
+static void
+secu_PrintBMPString(FILE *out, SECItem *i, const char *m, int level)
+{
+ unsigned char * s;
+ unsigned char * d;
+ int len;
+ SECItem tmp = {0, 0, 0};
+ SECItem my = *i;
+
+ if (SECSuccess != SECU_StripTagAndLength(&my))
+ goto loser;
+ if (my.len % 2)
+ goto loser;
+ len = (int)(my.len / 2);
+ tmp.data = (unsigned char *)PORT_Alloc(len);
+ if (!tmp.data)
+ goto loser;
+ tmp.len = len;
+ for (s = my.data, d = tmp.data ; len > 0; len--) {
+ PRUint32 bmpChar = (s[0] << 8) | s[1]; s += 2;
+ if (!isprint(bmpChar))
+ goto loser;
+ *d++ = (unsigned char)bmpChar;
+ }
+ secu_PrintRawString(out, &tmp, m, level);
+ PORT_Free(tmp.data);
+ return;
+
+loser:
+ SECU_PrintAsHex(out, i, m, level);
+ if (tmp.data)
+ PORT_Free(tmp.data);
+}
+
+static void
+secu_PrintUniversalString(FILE *out, SECItem *i, const char *m, int level)
+{
+ unsigned char * s;
+ unsigned char * d;
+ int len;
+ SECItem tmp = {0, 0, 0};
+ SECItem my = *i;
+
+ if (SECSuccess != SECU_StripTagAndLength(&my))
+ goto loser;
+ if (my.len % 4)
+ goto loser;
+ len = (int)(my.len / 4);
+ tmp.data = (unsigned char *)PORT_Alloc(len);
+ if (!tmp.data)
+ goto loser;
+ tmp.len = len;
+ for (s = my.data, d = tmp.data ; len > 0; len--) {
+ PRUint32 bmpChar = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
+ s += 4;
+ if (!isprint(bmpChar))
+ goto loser;
+ *d++ = (unsigned char)bmpChar;
+ }
+ secu_PrintRawString(out, &tmp, m, level);
+ PORT_Free(tmp.data);
+ return;
+
+loser:
+ SECU_PrintAsHex(out, i, m, level);
+ if (tmp.data)
+ PORT_Free(tmp.data);
+}
+
+static void
+secu_PrintUniversal(FILE *out, SECItem *i, const char *m, int level)
+{
+ switch (i->data[0] & SEC_ASN1_TAGNUM_MASK) {
+ case SEC_ASN1_ENUMERATED:
+ case SEC_ASN1_INTEGER:
+ SECU_PrintEncodedInteger(out, i, m, level);
+ break;
+ case SEC_ASN1_OBJECT_ID:
+ SECU_PrintEncodedObjectID(out, i, m, level);
+ break;
+ case SEC_ASN1_BOOLEAN:
+ SECU_PrintEncodedBoolean(out, i, m, level);
+ break;
+ case SEC_ASN1_UTF8_STRING:
+ case SEC_ASN1_PRINTABLE_STRING:
+ case SEC_ASN1_VISIBLE_STRING:
+ case SEC_ASN1_IA5_STRING:
+ case SEC_ASN1_T61_STRING:
+ SECU_PrintString(out, i, m, level);
+ break;
+ case SEC_ASN1_GENERALIZED_TIME:
+ SECU_PrintGeneralizedTime(out, i, m, level);
+ break;
+ case SEC_ASN1_UTC_TIME:
+ SECU_PrintUTCTime(out, i, m, level);
+ break;
+ case SEC_ASN1_NULL:
+ SECU_Indent(out, level);
+ if (m && m[0])
+ fprintf(out, "%s: NULL\n", m);
+ else
+ fprintf(out, "NULL\n");
+ break;
+ case SEC_ASN1_SET:
+ case SEC_ASN1_SEQUENCE:
+ SECU_PrintSet(out, i, m, level);
+ break;
+ case SEC_ASN1_OCTET_STRING:
+ secu_PrintOctetString(out, i, m, level);
+ break;
+ case SEC_ASN1_BIT_STRING:
+ secu_PrintBitString(out, i, m, level);
+ break;
+ case SEC_ASN1_BMP_STRING:
+ secu_PrintBMPString(out, i, m, level);
+ break;
+ case SEC_ASN1_UNIVERSAL_STRING:
+ secu_PrintUniversalString(out, i, m, level);
+ break;
+ default:
+ SECU_PrintAsHex(out, i, m, level);
+ break;
+ }
+}
+
+void
+SECU_PrintAny(FILE *out, SECItem *i, const char *m, int level)
+{
+ if ( i && i->len && i->data ) {
+ switch (i->data[0] & SEC_ASN1_CLASS_MASK) {
+ case SEC_ASN1_CONTEXT_SPECIFIC:
+ secu_PrintContextSpecific(out, i, m, level);
+ break;
+ case SEC_ASN1_UNIVERSAL:
+ secu_PrintUniversal(out, i, m, level);
+ break;
+ default:
+ SECU_PrintAsHex(out, i, m, level);
+ break;
+ }
+ }
+}
+
+static int
+secu_PrintValidity(FILE *out, CERTValidity *v, const char *m, int level)
+{
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintTimeChoice(out, &v->notBefore, "Not Before", level+1);
+ SECU_PrintTimeChoice(out, &v->notAfter, "Not After ", level+1);
+ return 0;
+}
+
+/* This function does NOT expect a DER type and length. */
+SECOidTag
+SECU_PrintObjectID(FILE *out, SECItem *oid, const char *m, int level)
+{
+ SECOidData *oiddata;
+ char * oidString = NULL;
+
+ oiddata = SECOID_FindOID(oid);
+ if (oiddata != NULL) {
+ const char *name = oiddata->desc;
+ SECU_Indent(out, level);
+ if (m != NULL)
+ fprintf(out, "%s: ", m);
+ fprintf(out, "%s\n", name);
+ return oiddata->offset;
+ }
+ oidString = CERT_GetOidString(oid);
+ if (oidString) {
+ SECU_Indent(out, level);
+ if (m != NULL)
+ fprintf(out, "%s: ", m);
+ fprintf(out, "%s\n", oidString);
+ PR_smprintf_free(oidString);
+ return SEC_OID_UNKNOWN;
+ }
+ SECU_PrintAsHex(out, oid, m, level);
+ return SEC_OID_UNKNOWN;
+}
+
+
+/* This function does NOT expect a DER type and length. */
+void
+SECU_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, const char *m, int level)
+{
+ SECU_PrintObjectID(out, &a->algorithm, m, level);
+
+ if (a->parameters.len == 0
+ || (a->parameters.len == 2
+ && PORT_Memcmp(a->parameters.data, "\005\000", 2) == 0)) {
+ /* No arguments or NULL argument */
+ } else {
+ /* Print args to algorithm */
+ SECU_PrintAsHex(out, &a->parameters, "Args", level+1);
+ }
+}
+
+static void
+secu_PrintAttribute(FILE *out, SEC_PKCS7Attribute *attr, const char *m, int level)
+{
+ SECItem *value;
+ int i;
+ char om[100];
+
+ if (m) {
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ }
+
+ /*
+ * Should make this smarter; look at the type field and then decode
+ * and print the value(s) appropriately!
+ */
+ SECU_PrintObjectID(out, &(attr->type), "Type", level+1);
+ if (attr->values != NULL) {
+ i = 0;
+ while ((value = attr->values[i++]) != NULL) {
+ sprintf(om, "Value (%d)%s", i, attr->encoded ? " (encoded)" : "");
+ if (attr->encoded || attr->typeTag == NULL) {
+ SECU_PrintAny(out, value, om, level+1);
+ } else {
+ switch (attr->typeTag->offset) {
+ default:
+ SECU_PrintAsHex(out, value, om, level+1);
+ break;
+ case SEC_OID_PKCS9_CONTENT_TYPE:
+ SECU_PrintObjectID(out, value, om, level+1);
+ break;
+ case SEC_OID_PKCS9_SIGNING_TIME:
+ SECU_PrintTimeChoice(out, value, om, level+1);
+ break;
+ }
+ }
+ }
+ }
+}
+
+static void
+secu_PrintRSAPublicKey(FILE *out, SECKEYPublicKey *pk, const char *m, int level)
+{
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &pk->u.rsa.modulus, "Modulus", level+1);
+ SECU_PrintInteger(out, &pk->u.rsa.publicExponent, "Exponent", level+1);
+ if (pk->u.rsa.publicExponent.len == 1 &&
+ pk->u.rsa.publicExponent.data[0] == 1) {
+ SECU_Indent(out, level +1); fprintf(out, "Error: INVALID RSA KEY!\n");
+ }
+}
+
+static void
+secu_PrintDSAPublicKey(FILE *out, SECKEYPublicKey *pk, const char *m, int level)
+{
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &pk->u.dsa.params.prime, "Prime", level+1);
+ SECU_PrintInteger(out, &pk->u.dsa.params.subPrime, "Subprime", level+1);
+ SECU_PrintInteger(out, &pk->u.dsa.params.base, "Base", level+1);
+ SECU_PrintInteger(out, &pk->u.dsa.publicValue, "PublicValue", level+1);
+}
+
+#ifdef NSS_ENABLE_ECC
+static void
+secu_PrintECPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level)
+{
+ SECItem curveOID = { siBuffer, NULL, 0};
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &pk->u.ec.publicValue, "PublicValue", level+1);
+ /* For named curves, the DEREncodedParams field contains an
+ * ASN Object ID (0x06 is SEC_ASN1_OBJECT_ID).
+ */
+ if ((pk->u.ec.DEREncodedParams.len > 2) &&
+ (pk->u.ec.DEREncodedParams.data[0] == 0x06)) {
+ curveOID.len = pk->u.ec.DEREncodedParams.data[1];
+ curveOID.data = pk->u.ec.DEREncodedParams.data + 2;
+ SECU_PrintObjectID(out, &curveOID, "Curve", level +1);
+ }
+}
+#endif /* NSS_ENABLE_ECC */
+
+static void
+secu_PrintSubjectPublicKeyInfo(FILE *out, PRArenaPool *arena,
+ CERTSubjectPublicKeyInfo *i, const char *msg, int level)
+{
+ SECKEYPublicKey *pk;
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", msg);
+ SECU_PrintAlgorithmID(out, &i->algorithm, "Public Key Algorithm", level+1);
+
+ pk = SECKEY_ExtractPublicKey(i);
+ if (pk) {
+ switch (pk->keyType) {
+ case rsaKey:
+ secu_PrintRSAPublicKey(out, pk, "RSA Public Key", level +1);
+ break;
+
+ case dsaKey:
+ secu_PrintDSAPublicKey(out, pk, "DSA Public Key", level +1);
+ break;
+
+#ifdef NSS_ENABLE_ECC
+ case ecKey:
+ secu_PrintECPublicKey(out, pk, "EC Public Key", level +1);
+ break;
+#endif
+
+ case dhKey:
+ case fortezzaKey:
+ case keaKey:
+ SECU_Indent(out, level);
+ fprintf(out, "unable to format this SPKI algorithm type\n");
+ goto loser;
+ default:
+ SECU_Indent(out, level);
+ fprintf(out, "unknown SPKI algorithm type\n");
+ goto loser;
+ }
+ PORT_FreeArena(pk->arena, PR_FALSE);
+ } else {
+ SECU_PrintErrMsg(out, level, "Error", "Parsing public key");
+loser:
+ if (i->subjectPublicKey.data) {
+ SECU_PrintAny(out, &i->subjectPublicKey, "Raw", level);
+ }
+ }
+}
+
+static SECStatus
+secu_PrintX509InvalidDate(FILE *out, SECItem *value, const char *msg, int level)
+{
+ SECItem decodedValue;
+ SECStatus rv;
+ int64 invalidTime;
+ char *formattedTime = NULL;
+
+ decodedValue.data = NULL;
+ rv = SEC_ASN1DecodeItem (NULL, &decodedValue,
+ SEC_ASN1_GET(SEC_GeneralizedTimeTemplate),
+ value);
+ if (rv == SECSuccess) {
+ rv = DER_GeneralizedTimeToTime(&invalidTime, &decodedValue);
+ if (rv == SECSuccess) {
+ formattedTime = CERT_GenTime2FormattedAscii
+ (invalidTime, (char *) "%a %b %d %H:%M:%S %Y");
+ SECU_Indent(out, level +1);
+ fprintf (out, "%s: %s\n", msg, formattedTime);
+ PORT_Free (formattedTime);
+ }
+ }
+ PORT_Free (decodedValue.data);
+ return (rv);
+}
+
+static SECStatus
+PrintExtKeyUsageExtension (FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTOidSequence *os;
+ SECItem **op;
+
+ os = CERT_DecodeOidSequence(value);
+ if( (CERTOidSequence *)NULL == os ) {
+ return SECFailure;
+ }
+
+ for( op = os->oids; *op; op++ ) {
+ SECU_PrintObjectID(out, *op, msg, level + 1);
+ }
+ CERT_DestroyOidSequence(os);
+ return SECSuccess;
+}
+
+static SECStatus
+secu_PrintBasicConstraints(FILE *out, SECItem *value, const char *msg, int level) {
+ CERTBasicConstraints constraints;
+ SECStatus rv;
+
+ SECU_Indent(out, level);
+ if (msg) {
+ fprintf(out,"%s: ",msg);
+ }
+ rv = CERT_DecodeBasicConstraintValue(&constraints,value);
+ if (rv == SECSuccess && constraints.isCA) {
+ if (constraints.pathLenConstraint >= 0) {
+ fprintf(out,"Is a CA with a maximum path length of %d.\n",
+ constraints.pathLenConstraint);
+ } else {
+ fprintf(out,"Is a CA with no maximum path length.\n");
+ }
+ } else {
+ fprintf(out,"Is not a CA.\n");
+ }
+ return SECSuccess;
+}
+
+static const char * const nsTypeBits[] = {
+ "SSL Client",
+ "SSL Server",
+ "S/MIME",
+ "Object Signing",
+ "Reserved",
+ "SSL CA",
+ "S/MIME CA",
+ "ObjectSigning CA"
+};
+
+/* NSCertType is merely a bit string whose bits are displayed symbolically */
+static SECStatus
+secu_PrintNSCertType(FILE *out, SECItem *value, const char *msg, int level)
+{
+ int unused;
+ int NS_Type;
+ int i;
+ int found = 0;
+ SECItem my = *value;
+
+ if ((my.data[0] != SEC_ASN1_BIT_STRING) ||
+ SECSuccess != SECU_StripTagAndLength(&my)) {
+ SECU_PrintAny(out, value, "Data", level);
+ return SECSuccess;
+ }
+
+ unused = (my.len == 2) ? (my.data[0] & 0x0f) : 0;
+ NS_Type = my.data[1] & (0xff << unused);
+
+
+ SECU_Indent(out, level);
+ if (msg) {
+ fprintf(out,"%s: ",msg);
+ } else {
+ fprintf(out,"Netscape Certificate Type: ");
+ }
+ for (i=0; i < 8; i++) {
+ if ( (0x80 >> i) & NS_Type) {
+ fprintf(out, "%c%s", (found ? ',' : '<'), nsTypeBits[i]);
+ found = 1;
+ }
+ }
+ fprintf(out, (found ? ">\n" : "none\n"));
+ return SECSuccess;
+}
+
+static const char * const usageBits[] = {
+ "Digital Signature", /* 0x80 */
+ "Non-Repudiation", /* 0x40 */
+ "Key Encipherment", /* 0x20 */
+ "Data Encipherment", /* 0x10 */
+ "Key Agreement", /* 0x08 */
+ "Certificate Signing", /* 0x04 */
+ "CRL Signing", /* 0x02 */
+ "Encipher Only", /* 0x01 */
+ "Decipher Only", /* 0x0080 */
+ NULL
+};
+
+/* X509KeyUsage is merely a bit string whose bits are displayed symbolically */
+static void
+secu_PrintX509KeyUsage(FILE *out, SECItem *value, char *msg, int level)
+{
+ int unused;
+ int usage;
+ int i;
+ int found = 0;
+ SECItem my = *value;
+
+ if ((my.data[0] != SEC_ASN1_BIT_STRING) ||
+ SECSuccess != SECU_StripTagAndLength(&my)) {
+ SECU_PrintAny(out, value, "Data", level);
+ return;
+ }
+
+ unused = (my.len >= 2) ? (my.data[0] & 0x0f) : 0;
+ usage = (my.len == 2) ? (my.data[1] & (0xff << unused)) << 8
+ : (my.data[1] << 8) |
+ (my.data[2] & (0xff << unused));
+
+ SECU_Indent(out, level);
+ fprintf(out, "Usages: ");
+ for (i=0; usageBits[i]; i++) {
+ if ( (0x8000 >> i) & usage) {
+ if (found)
+ SECU_Indent(out, level + 2);
+ fprintf(out, "%s\n", usageBits[i]);
+ found = 1;
+ }
+ }
+ if (!found) {
+ fprintf(out, "(none)\n");
+ }
+}
+
+static void
+secu_PrintIPAddress(FILE *out, SECItem *value, const char *msg, int level)
+{
+ PRStatus st;
+ PRNetAddr addr;
+ char addrBuf[80];
+
+ memset(&addr, 0, sizeof addr);
+ if (value->len == 4) {
+ addr.inet.family = PR_AF_INET;
+ memcpy(&addr.inet.ip, value->data, value->len);
+ } else if (value->len == 16) {
+ addr.ipv6.family = PR_AF_INET6;
+ memcpy(addr.ipv6.ip.pr_s6_addr, value->data, value->len);
+ if (PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped)) {
+ /* convert to IPv4. */
+ addr.inet.family = PR_AF_INET;
+ memcpy(&addr.inet.ip, &addr.ipv6.ip.pr_s6_addr[12], 4);
+ memset(&addr.inet.pad[0], 0, sizeof addr.inet.pad);
+ }
+ } else {
+ goto loser;
+ }
+
+ st = PR_NetAddrToString(&addr, addrBuf, sizeof addrBuf);
+ if (st == PR_SUCCESS) {
+ SECU_Indent(out, level);
+ fprintf(out, "%s: %s\n", msg, addrBuf);
+ } else {
+loser:
+ SECU_PrintAsHex(out, value, msg, level);
+ }
+}
+
+
+static void
+secu_PrintGeneralName(FILE *out, CERTGeneralName *gname, const char *msg, int level)
+{
+ char label[40];
+ if (msg && msg[0]) {
+ SECU_Indent(out, level++); fprintf(out, "%s: \n", msg);
+ }
+ switch (gname->type) {
+ case certOtherName :
+ SECU_PrintAny( out, &gname->name.OthName.name, "Other Name", level);
+ SECU_PrintObjectID(out, &gname->name.OthName.oid, "OID", level+1);
+ break;
+ case certDirectoryName :
+ SECU_PrintName(out, &gname->name.directoryName, "Directory Name", level);
+ break;
+ case certRFC822Name :
+ secu_PrintRawString( out, &gname->name.other, "RFC822 Name", level);
+ break;
+ case certDNSName :
+ secu_PrintRawString( out, &gname->name.other, "DNS name", level);
+ break;
+ case certURI :
+ secu_PrintRawString( out, &gname->name.other, "URI", level);
+ break;
+ case certIPAddress :
+ secu_PrintIPAddress(out, &gname->name.other, "IP Address", level);
+ break;
+ case certRegisterID :
+ SECU_PrintObjectID( out, &gname->name.other, "Registered ID", level);
+ break;
+ case certX400Address :
+ SECU_PrintAny( out, &gname->name.other, "X400 Address", level);
+ break;
+ case certEDIPartyName :
+ SECU_PrintAny( out, &gname->name.other, "EDI Party", level);
+ break;
+ default:
+ PR_snprintf(label, sizeof label, "unknown type [%d]",
+ (int)gname->type - 1);
+ SECU_PrintAsHex(out, &gname->name.other, label, level);
+ break;
+ }
+}
+
+static void
+secu_PrintAuthKeyIDExtension(FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTAuthKeyID *kid = NULL;
+ PLArenaPool *pool = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if (!pool) {
+ SECU_PrintError("Error", "Allocating new ArenaPool");
+ return;
+ }
+ kid = CERT_DecodeAuthKeyID(pool, value);
+ if (!kid) {
+ SECU_PrintErrMsg(out, level, "Error", "Parsing extension");
+ SECU_PrintAny(out, value, "Data", level);
+ } else {
+ int keyIDPresent = (kid->keyID.data && kid->keyID.len);
+ int issuerPresent = kid->authCertIssuer != NULL;
+ int snPresent = (kid->authCertSerialNumber.data &&
+ kid->authCertSerialNumber.len);
+
+ if ((keyIDPresent && !issuerPresent && !snPresent) ||
+ (!keyIDPresent && issuerPresent && snPresent)) {
+ /* all is well */
+ } else {
+ SECU_Indent(out, level);
+ fprintf(out,
+ "Error: KeyID OR (Issuer AND Serial) must be present, not both.\n");
+ }
+ if (keyIDPresent)
+ SECU_PrintAsHex(out, &kid->keyID, "Key ID", level);
+ if (issuerPresent)
+ secu_PrintGeneralName(out, kid->authCertIssuer, "Issuer", level);
+ if (snPresent)
+ SECU_PrintInteger(out, &kid->authCertSerialNumber,
+ "Serial Number", level);
+ }
+ PORT_FreeArena(pool, PR_FALSE);
+}
+
+
+static void
+secu_PrintAltNameExtension(FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTGeneralName * nameList;
+ CERTGeneralName * current;
+ PLArenaPool * pool = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if (!pool) {
+ SECU_PrintError("Error", "Allocating new ArenaPool");
+ return;
+ }
+ nameList = current = CERT_DecodeAltNameExtension(pool, value);
+ if (!current) {
+ if (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) {
+ /* Decoder found empty sequence, which is invalid. */
+ PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
+ }
+ SECU_PrintErrMsg(out, level, "Error", "Parsing extension");
+ SECU_PrintAny(out, value, "Data", level);
+ } else {
+ do {
+ secu_PrintGeneralName(out, current, msg, level);
+ current = CERT_GetNextGeneralName(current);
+ } while (current != nameList);
+ }
+ PORT_FreeArena(pool, PR_FALSE);
+}
+
+static void
+secu_PrintCRLDistPtsExtension(FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTCrlDistributionPoints * dPoints;
+ PLArenaPool * pool = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if (!pool) {
+ SECU_PrintError("Error", "Allocating new ArenaPool");
+ return;
+ }
+ dPoints = CERT_DecodeCRLDistributionPoints(pool, value);
+ if (dPoints && dPoints->distPoints && dPoints->distPoints[0]) {
+ CRLDistributionPoint ** pPoints = dPoints->distPoints;
+ CRLDistributionPoint * pPoint;
+ while (NULL != (pPoint = *pPoints++)) {
+ if (pPoint->distPointType == generalName &&
+ pPoint->distPoint.fullName != NULL) {
+ secu_PrintGeneralName(out, pPoint->distPoint.fullName, NULL,
+ level);
+#if defined(LATER)
+ } else if (pPoint->distPointType == relativeDistinguishedName) {
+ /* print the relative name */
+#endif
+ } else if (pPoint->derDistPoint.data) {
+ SECU_PrintAny(out, &pPoint->derDistPoint, "Point", level);
+ }
+ if (pPoint->reasons.data) {
+ secu_PrintDecodedBitString(out, &pPoint->reasons, "Reasons",
+ level);
+ }
+ if (pPoint->crlIssuer) {
+ secu_PrintGeneralName(out, pPoint->crlIssuer, "Issuer", level);
+ }
+ }
+ } else {
+ SECU_PrintErrMsg(out, level, "Error", "Parsing extension");
+ SECU_PrintAny(out, value, "Data", level);
+ }
+ PORT_FreeArena(pool, PR_FALSE);
+}
+
+
+static void
+secu_PrintNameConstraintSubtree(FILE *out, CERTNameConstraint *value,
+ const char *msg, int level)
+{
+ CERTNameConstraint *head = value;
+ SECU_Indent(out, level); fprintf(out, "%s Subtree:\n", msg);
+ level++;
+ do {
+ secu_PrintGeneralName(out, &value->name, NULL, level);
+ if (value->min.data)
+ SECU_PrintInteger(out, &value->min, "Minimum", level+1);
+ if (value->max.data)
+ SECU_PrintInteger(out, &value->max, "Maximum", level+1);
+ value = CERT_GetNextNameConstraint(value);
+ } while (value != head);
+}
+
+static void
+secu_PrintNameConstraintsExtension(FILE *out, SECItem *value, const char *msg, int level)
+{
+ CERTNameConstraints * cnstrnts;
+ PLArenaPool * pool = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if (!pool) {
+ SECU_PrintError("Error", "Allocating new ArenaPool");
+ return;
+ }
+ cnstrnts = CERT_DecodeNameConstraintsExtension(pool, value);
+ if (!cnstrnts) {
+ SECU_PrintErrMsg(out, level, "Error", "Parsing extension");
+ SECU_PrintAny(out, value, "Raw", level);
+ } else {
+ if (cnstrnts->permited)
+ secu_PrintNameConstraintSubtree(out, cnstrnts->permited,
+ "Permitted", level);
+ if (cnstrnts->excluded)
+ secu_PrintNameConstraintSubtree(out, cnstrnts->excluded,
+ "Excluded", level);
+ }
+ PORT_FreeArena(pool, PR_FALSE);
+}
+
+
+static void
+secu_PrintAuthorityInfoAcess(FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTAuthInfoAccess **infos = NULL;
+ PLArenaPool * pool = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if (!pool) {
+ SECU_PrintError("Error", "Allocating new ArenaPool");
+ return;
+ }
+ infos = CERT_DecodeAuthInfoAccessExtension(pool, value);
+ if (!infos) {
+ SECU_PrintErrMsg(out, level, "Error", "Parsing extension");
+ SECU_PrintAny(out, value, "Raw", level);
+ } else {
+ CERTAuthInfoAccess *info;
+ while (NULL != (info = *infos++)) {
+ if (info->method.data) {
+ SECU_PrintObjectID(out, &info->method, "Method", level);
+ } else {
+ SECU_Indent(out,level);
+ fprintf(out, "Error: missing method\n");
+ }
+ if (info->location) {
+ secu_PrintGeneralName(out, info->location, "Location", level);
+ } else {
+ SECU_PrintAny(out, &info->derLocation, "Location", level);
+ }
+ }
+ }
+ PORT_FreeArena(pool, PR_FALSE);
+}
+
+
+void
+SECU_PrintExtensions(FILE *out, CERTCertExtension **extensions,
+ const char *msg, int level)
+{
+ SECOidTag oidTag;
+
+ if ( extensions ) {
+ if (msg && *msg) {
+ SECU_Indent(out, level++); fprintf(out, "%s:\n", msg);
+ }
+
+ while ( *extensions ) {
+ SECItem *tmpitem;
+
+ tmpitem = &(*extensions)->id;
+ SECU_PrintObjectID(out, tmpitem, "Name", level);
+
+ tmpitem = &(*extensions)->critical;
+ if ( tmpitem->len ) {
+ secu_PrintBoolean(out, tmpitem, "Critical", level);
+ }
+
+ oidTag = SECOID_FindOIDTag (&((*extensions)->id));
+ tmpitem = &((*extensions)->value);
+
+ switch (oidTag) {
+ case SEC_OID_X509_INVALID_DATE:
+ case SEC_OID_NS_CERT_EXT_CERT_RENEWAL_TIME:
+ secu_PrintX509InvalidDate(out, tmpitem, "Date", level );
+ break;
+ case SEC_OID_X509_CERTIFICATE_POLICIES:
+ SECU_PrintPolicy(out, tmpitem, "Data", level );
+ break;
+ case SEC_OID_NS_CERT_EXT_BASE_URL:
+ case SEC_OID_NS_CERT_EXT_REVOCATION_URL:
+ case SEC_OID_NS_CERT_EXT_CA_REVOCATION_URL:
+ case SEC_OID_NS_CERT_EXT_CA_CRL_URL:
+ case SEC_OID_NS_CERT_EXT_CA_CERT_URL:
+ case SEC_OID_NS_CERT_EXT_CERT_RENEWAL_URL:
+ case SEC_OID_NS_CERT_EXT_CA_POLICY_URL:
+ case SEC_OID_NS_CERT_EXT_HOMEPAGE_URL:
+ case SEC_OID_NS_CERT_EXT_LOST_PASSWORD_URL:
+ case SEC_OID_OCSP_RESPONDER:
+ SECU_PrintString(out,tmpitem, "URL", level);
+ break;
+ case SEC_OID_NS_CERT_EXT_COMMENT:
+ SECU_PrintString(out,tmpitem, "Comment", level);
+ break;
+ case SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME:
+ SECU_PrintString(out,tmpitem, "ServerName", level);
+ break;
+ case SEC_OID_NS_CERT_EXT_CERT_TYPE:
+ secu_PrintNSCertType(out,tmpitem,"Data",level);
+ break;
+ case SEC_OID_X509_BASIC_CONSTRAINTS:
+ secu_PrintBasicConstraints(out,tmpitem,"Data",level);
+ break;
+ case SEC_OID_X509_EXT_KEY_USAGE:
+ PrintExtKeyUsageExtension(out, tmpitem, NULL, level);
+ break;
+ case SEC_OID_X509_KEY_USAGE:
+ secu_PrintX509KeyUsage(out, tmpitem, NULL, level );
+ break;
+ case SEC_OID_X509_AUTH_KEY_ID:
+ secu_PrintAuthKeyIDExtension(out, tmpitem, NULL, level );
+ break;
+ case SEC_OID_X509_SUBJECT_ALT_NAME:
+ case SEC_OID_X509_ISSUER_ALT_NAME:
+ secu_PrintAltNameExtension(out, tmpitem, NULL, level );
+ break;
+ case SEC_OID_X509_CRL_DIST_POINTS:
+ secu_PrintCRLDistPtsExtension(out, tmpitem, NULL, level );
+ break;
+ case SEC_OID_X509_PRIVATE_KEY_USAGE_PERIOD:
+ SECU_PrintPrivKeyUsagePeriodExtension(out, tmpitem, NULL,
+ level );
+ break;
+ case SEC_OID_X509_NAME_CONSTRAINTS:
+ secu_PrintNameConstraintsExtension(out, tmpitem, NULL, level);
+ break;
+ case SEC_OID_X509_AUTH_INFO_ACCESS:
+ secu_PrintAuthorityInfoAcess(out, tmpitem, NULL, level);
+ break;
+
+ case SEC_OID_X509_CRL_NUMBER:
+ case SEC_OID_X509_REASON_CODE:
+
+ /* PKIX OIDs */
+ case SEC_OID_PKIX_OCSP:
+ case SEC_OID_PKIX_OCSP_BASIC_RESPONSE:
+ case SEC_OID_PKIX_OCSP_NONCE:
+ case SEC_OID_PKIX_OCSP_CRL:
+ case SEC_OID_PKIX_OCSP_RESPONSE:
+ case SEC_OID_PKIX_OCSP_NO_CHECK:
+ case SEC_OID_PKIX_OCSP_ARCHIVE_CUTOFF:
+ case SEC_OID_PKIX_OCSP_SERVICE_LOCATOR:
+ case SEC_OID_PKIX_REGCTRL_REGTOKEN:
+ case SEC_OID_PKIX_REGCTRL_AUTHENTICATOR:
+ case SEC_OID_PKIX_REGCTRL_PKIPUBINFO:
+ case SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS:
+ case SEC_OID_PKIX_REGCTRL_OLD_CERT_ID:
+ case SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY:
+ case SEC_OID_PKIX_REGINFO_UTF8_PAIRS:
+ case SEC_OID_PKIX_REGINFO_CERT_REQUEST:
+
+ /* Netscape extension OIDs. */
+ case SEC_OID_NS_CERT_EXT_NETSCAPE_OK:
+ case SEC_OID_NS_CERT_EXT_ISSUER_LOGO:
+ case SEC_OID_NS_CERT_EXT_SUBJECT_LOGO:
+ case SEC_OID_NS_CERT_EXT_ENTITY_LOGO:
+ case SEC_OID_NS_CERT_EXT_USER_PICTURE:
+
+ /* x.509 v3 Extensions */
+ case SEC_OID_X509_SUBJECT_DIRECTORY_ATTR:
+ case SEC_OID_X509_SUBJECT_KEY_ID:
+ case SEC_OID_X509_POLICY_MAPPINGS:
+ case SEC_OID_X509_POLICY_CONSTRAINTS:
+
+
+ default:
+ SECU_PrintAny(out, tmpitem, "Data", level);
+ break;
+ }
+
+ secu_Newline(out);
+ extensions++;
+ }
+ }
+}
+
+
+void
+SECU_PrintName(FILE *out, CERTName *name, const char *msg, int level)
+{
+ char *nameStr;
+ const char *str;
+ SECItem my;
+
+ str = nameStr = CERT_NameToAscii(name);
+ if (!str) {
+ str = "!Invalid AVA!";
+ }
+ my.data = (unsigned char *)str;
+ my.len = PORT_Strlen(str);
+#if 1
+ secu_PrintRawString(out, &my, msg, level);
+#else
+ SECU_Indent(out, level); fprintf(out, "%s: ", msg);
+ fprintf(out, str);
+ secu_Newline(out);
+#endif
+ PORT_Free(nameStr);
+}
+
+void
+printflags(char *trusts, unsigned int flags)
+{
+ if (flags & CERTDB_VALID_CA)
+ if (!(flags & CERTDB_TRUSTED_CA) &&
+ !(flags & CERTDB_TRUSTED_CLIENT_CA))
+ PORT_Strcat(trusts, "c");
+ if (flags & CERTDB_VALID_PEER)
+ if (!(flags & CERTDB_TRUSTED))
+ PORT_Strcat(trusts, "p");
+ if (flags & CERTDB_TRUSTED_CA)
+ PORT_Strcat(trusts, "C");
+ if (flags & CERTDB_TRUSTED_CLIENT_CA)
+ PORT_Strcat(trusts, "T");
+ if (flags & CERTDB_TRUSTED)
+ PORT_Strcat(trusts, "P");
+ if (flags & CERTDB_USER)
+ PORT_Strcat(trusts, "u");
+ if (flags & CERTDB_SEND_WARN)
+ PORT_Strcat(trusts, "w");
+ if (flags & CERTDB_INVISIBLE_CA)
+ PORT_Strcat(trusts, "I");
+ if (flags & CERTDB_GOVT_APPROVED_CA)
+ PORT_Strcat(trusts, "G");
+ return;
+}
+
+/* callback for listing certs through pkcs11 */
+SECStatus
+SECU_PrintCertNickname(CERTCertListNode *node, void *data)
+{
+ CERTCertTrust *trust;
+ CERTCertificate* cert;
+ FILE *out;
+ char trusts[30];
+ const char *name;
+
+ cert = node->cert;
+
+ PORT_Memset (trusts, 0, sizeof (trusts));
+ out = (FILE *)data;
+
+ name = node->appData;
+ if (!name || !name[0]) {
+ name = cert->nickname;
+ }
+ if (!name || !name[0]) {
+ name = cert->emailAddr;
+ }
+ if (!name || !name[0]) {
+ name = "(NULL)";
+ }
+
+ trust = cert->trust;
+ if (trust) {
+ printflags(trusts, trust->sslFlags);
+ PORT_Strcat(trusts, ",");
+ printflags(trusts, trust->emailFlags);
+ PORT_Strcat(trusts, ",");
+ printflags(trusts, trust->objectSigningFlags);
+ } else {
+ PORT_Memcpy(trusts,",,",3);
+ }
+ fprintf(out, "%-60s %-5s\n", name, trusts);
+
+ return (SECSuccess);
+}
+
+static int
+SECU_DecodeAndPrintExtensions(FILE *out, SECItem *any, const char *m, int level)
+{
+ CERTCertExtension **extensions = NULL;
+ PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ int rv = 0;
+
+ if (!arena)
+ return SEC_ERROR_NO_MEMORY;
+
+ rv = SEC_QuickDERDecodeItem(arena, &extensions,
+ SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate), any);
+ if (!rv)
+ SECU_PrintExtensions(out, extensions, m, level);
+ else
+ SECU_PrintAny(out, any, m, level);
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+/* print a decoded SET OF or SEQUENCE OF Extensions */
+static int
+SECU_PrintSetOfExtensions(FILE *out, SECItem **any, const char *m, int level)
+{
+ int rv = 0;
+ if (m && *m) {
+ SECU_Indent(out, level++); fprintf(out, "%s:\n", m);
+ }
+ while (any && any[0]) {
+ rv |= SECU_DecodeAndPrintExtensions(out, any[0], "", level);
+ any++;
+ }
+ return rv;
+}
+
+/* print a decoded SET OF or SEQUENCE OF "ANY" */
+static int
+SECU_PrintSetOfAny(FILE *out, SECItem **any, const char *m, int level)
+{
+ int rv = 0;
+ if (m && *m) {
+ SECU_Indent(out, level++); fprintf(out, "%s:\n", m);
+ }
+ while (any && any[0]) {
+ SECU_PrintAny(out, any[0], "", level);
+ any++;
+ }
+ return rv;
+}
+
+static int
+SECU_PrintCertAttribute(FILE *out, CERTAttribute *attr, const char *m, int level)
+{
+ int rv = 0;
+ SECOidTag tag;
+ tag = SECU_PrintObjectID(out, &attr->attrType, "Attribute Type", level);
+ if (tag == SEC_OID_PKCS9_EXTENSION_REQUEST) {
+ rv = SECU_PrintSetOfExtensions(out, attr->attrValue, "Extensions", level);
+ } else {
+ rv = SECU_PrintSetOfAny(out, attr->attrValue, "Attribute Values", level);
+ }
+ return rv;
+}
+
+static int
+SECU_PrintCertAttributes(FILE *out, CERTAttribute **attrs, const char *m, int level)
+{
+ int rv = 0;
+ while (attrs[0]) {
+ rv |= SECU_PrintCertAttribute(out, attrs[0], m, level+1);
+ attrs++;
+ }
+ return rv;
+}
+
+int /* sometimes a PRErrorCode, other times a SECStatus. Sigh. */
+SECU_PrintCertificateRequest(FILE *out, SECItem *der, const char *m, int level)
+{
+ PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ CERTCertificateRequest *cr;
+ int rv = SEC_ERROR_NO_MEMORY;
+
+ if (!arena)
+ return rv;
+
+ /* Decode certificate request */
+ cr = PORT_ArenaZNew(arena, CERTCertificateRequest);
+ if (!cr)
+ goto loser;
+ cr->arena = arena;
+ rv = SEC_QuickDERDecodeItem(arena, cr,
+ SEC_ASN1_GET(CERT_CertificateRequestTemplate), der);
+ if (rv)
+ goto loser;
+
+ /* Pretty print it out */
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &cr->version, "Version", level+1);
+ SECU_PrintName(out, &cr->subject, "Subject", level+1);
+ secu_PrintSubjectPublicKeyInfo(out, arena, &cr->subjectPublicKeyInfo,
+ "Subject Public Key Info", level+1);
+ if (cr->attributes)
+ SECU_PrintCertAttributes(out, cr->attributes, "Attributes", level+1);
+ rv = 0;
+loser:
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+int
+SECU_PrintCertificate(FILE *out, SECItem *der, const char *m, int level)
+{
+ PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ CERTCertificate *c;
+ int rv = SEC_ERROR_NO_MEMORY;
+ int iv;
+
+ if (!arena)
+ return rv;
+
+ /* Decode certificate */
+ c = PORT_ArenaZNew(arena, CERTCertificate);
+ if (!c)
+ goto loser;
+ c->arena = arena;
+ rv = SEC_ASN1DecodeItem(arena, c,
+ SEC_ASN1_GET(CERT_CertificateTemplate), der);
+ if (rv) {
+ SECU_Indent(out, level);
+ SECU_PrintErrMsg(out, level, "Error", "Parsing extension");
+ SECU_PrintAny(out, der, "Raw", level);
+ goto loser;
+ }
+ /* Pretty print it out */
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ iv = c->version.len ? DER_GetInteger(&c->version) : 0; /* version is optional */
+ SECU_Indent(out, level+1); fprintf(out, "%s: %d (0x%x)\n", "Version", iv + 1, iv);
+
+ SECU_PrintInteger(out, &c->serialNumber, "Serial Number", level+1);
+ SECU_PrintAlgorithmID(out, &c->signature, "Signature Algorithm", level+1);
+ SECU_PrintName(out, &c->issuer, "Issuer", level+1);
+ secu_PrintValidity(out, &c->validity, "Validity", level+1);
+ SECU_PrintName(out, &c->subject, "Subject", level+1);
+ secu_PrintSubjectPublicKeyInfo(out, arena, &c->subjectPublicKeyInfo,
+ "Subject Public Key Info", level+1);
+ if (c->issuerID.data)
+ secu_PrintDecodedBitString(out, &c->issuerID, "Issuer Unique ID", level+1);
+ if (c->subjectID.data)
+ secu_PrintDecodedBitString(out, &c->subjectID, "Subject Unique ID", level+1);
+ SECU_PrintExtensions(out, c->extensions, "Signed Extensions", level+1);
+loser:
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+int
+SECU_PrintPublicKey(FILE *out, SECItem *der, const char *m, int level)
+{
+ PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ SECKEYPublicKey key;
+ int rv = SEC_ERROR_NO_MEMORY;
+
+ if (!arena)
+ return rv;
+
+ PORT_Memset(&key, 0, sizeof(key));
+ rv = SEC_ASN1DecodeItem(arena, &key,
+ SEC_ASN1_GET(SECKEY_RSAPublicKeyTemplate), der);
+ if (!rv) {
+ /* Pretty print it out */
+ secu_PrintRSAPublicKey(out, &key, m, level);
+ }
+
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+#ifdef HAVE_EPV_TEMPLATE
+int
+SECU_PrintPrivateKey(FILE *out, SECItem *der, char *m, int level)
+{
+ PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ SECKEYEncryptedPrivateKeyInfo key;
+ int rv = SEC_ERROR_NO_MEMORY;
+
+ if (!arena)
+ return rv;
+
+ PORT_Memset(&key, 0, sizeof(key));
+ rv = SEC_ASN1DecodeItem(arena, &key,
+ SEC_ASN1_GET(SECKEY_EncryptedPrivateKeyInfoTemplate), der);
+ if (rv)
+ goto loser;
+
+ /* Pretty print it out */
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintAlgorithmID(out, &key.algorithm, "Encryption Algorithm",
+ level+1);
+ SECU_PrintAsHex(out, &key.encryptedData, "Encrypted Data", level+1);
+loser:
+ PORT_FreeArena(arena, PR_TRUE);
+ return rv;
+}
+#endif
+
+int
+SECU_PrintFingerprints(FILE *out, SECItem *derCert, const char *m, int level)
+{
+ unsigned char fingerprint[20];
+ char *fpStr = NULL;
+ int err = PORT_GetError();
+ SECStatus rv;
+ SECItem fpItem;
+
+ /* print MD5 fingerprint */
+ memset(fingerprint, 0, sizeof fingerprint);
+ rv = PK11_HashBuf(SEC_OID_MD5,fingerprint, derCert->data, derCert->len);
+ fpItem.data = fingerprint;
+ fpItem.len = MD5_LENGTH;
+ fpStr = CERT_Hexify(&fpItem, 1);
+ SECU_Indent(out, level); fprintf(out, "%s (MD5):\n", m);
+ SECU_Indent(out, level+1); fprintf(out, "%s\n", fpStr);
+ PORT_Free(fpStr);
+ fpStr = NULL;
+ if (rv != SECSuccess && !err)
+ err = PORT_GetError();
+
+ /* print SHA1 fingerprint */
+ memset(fingerprint, 0, sizeof fingerprint);
+ rv = PK11_HashBuf(SEC_OID_SHA1,fingerprint, derCert->data, derCert->len);
+ fpItem.data = fingerprint;
+ fpItem.len = SHA1_LENGTH;
+ fpStr = CERT_Hexify(&fpItem, 1);
+ SECU_Indent(out, level); fprintf(out, "%s (SHA1):\n", m);
+ SECU_Indent(out, level+1); fprintf(out, "%s\n", fpStr);
+ PORT_Free(fpStr);
+ fprintf(out, "\n");
+
+ if (err)
+ PORT_SetError(err);
+ if (err || rv != SECSuccess)
+ return SECFailure;
+
+ return 0;
+}
+
+/*
+** PKCS7 Support
+*/
+
+/* forward declaration */
+static int
+secu_PrintPKCS7ContentInfo(FILE *, SEC_PKCS7ContentInfo *, const char *, int);
+
+/*
+** secu_PrintPKCS7EncContent
+** Prints a SEC_PKCS7EncryptedContentInfo (without decrypting it)
+*/
+static void
+secu_PrintPKCS7EncContent(FILE *out, SEC_PKCS7EncryptedContentInfo *src,
+ const char *m, int level)
+{
+ if (src->contentTypeTag == NULL)
+ src->contentTypeTag = SECOID_FindOID(&(src->contentType));
+
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Content Type: %s\n",
+ (src->contentTypeTag != NULL) ? src->contentTypeTag->desc
+ : "Unknown");
+ SECU_PrintAlgorithmID(out, &(src->contentEncAlg),
+ "Content Encryption Algorithm", level+1);
+ SECU_PrintAsHex(out, &(src->encContent),
+ "Encrypted Content", level+1);
+}
+
+/*
+** secu_PrintRecipientInfo
+** Prints a PKCS7RecipientInfo type
+*/
+static void
+secu_PrintRecipientInfo(FILE *out, SEC_PKCS7RecipientInfo *info, char *m,
+ int level)
+{
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(info->version), "Version", level + 1);
+
+ SECU_PrintName(out, &(info->issuerAndSN->issuer), "Issuer",
+ level + 1);
+ SECU_PrintInteger(out, &(info->issuerAndSN->serialNumber),
+ "Serial Number", level + 1);
+
+ /* Parse and display encrypted key */
+ SECU_PrintAlgorithmID(out, &(info->keyEncAlg),
+ "Key Encryption Algorithm", level + 1);
+ SECU_PrintAsHex(out, &(info->encKey), "Encrypted Key", level + 1);
+}
+
+/*
+** secu_PrintSignerInfo
+** Prints a PKCS7SingerInfo type
+*/
+static void
+secu_PrintSignerInfo(FILE *out, SEC_PKCS7SignerInfo *info, char *m, int level)
+{
+ SEC_PKCS7Attribute *attr;
+ int iv;
+ char om[100];
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(info->version), "Version", level + 1);
+
+ SECU_PrintName(out, &(info->issuerAndSN->issuer), "Issuer",
+ level + 1);
+ SECU_PrintInteger(out, &(info->issuerAndSN->serialNumber),
+ "Serial Number", level + 1);
+
+ SECU_PrintAlgorithmID(out, &(info->digestAlg), "Digest Algorithm",
+ level + 1);
+
+ if (info->authAttr != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Authenticated Attributes:\n");
+ iv = 0;
+ while ((attr = info->authAttr[iv++]) != NULL) {
+ sprintf(om, "Attribute (%d)", iv);
+ secu_PrintAttribute(out, attr, om, level + 2);
+ }
+ }
+
+ /* Parse and display signature */
+ SECU_PrintAlgorithmID(out, &(info->digestEncAlg),
+ "Digest Encryption Algorithm", level + 1);
+ SECU_PrintAsHex(out, &(info->encDigest), "Encrypted Digest", level + 1);
+
+ if (info->unAuthAttr != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Unauthenticated Attributes:\n");
+ iv = 0;
+ while ((attr = info->unAuthAttr[iv++]) != NULL) {
+ sprintf(om, "Attribute (%x)", iv);
+ secu_PrintAttribute(out, attr, om, level + 2);
+ }
+ }
+}
+
+/* callers of this function must make sure that the CERTSignedCrl
+ from which they are extracting the CERTCrl has been fully-decoded.
+ Otherwise it will not have the entries even though the CRL may have
+ some */
+
+void
+SECU_PrintCRLInfo(FILE *out, CERTCrl *crl, const char *m, int level)
+{
+ CERTCrlEntry *entry;
+ int iv;
+ char om[100];
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ /* version is optional */
+ iv = crl->version.len ? DER_GetInteger(&crl->version) : 0;
+ SECU_Indent(out, level+1);
+ fprintf(out, "%s: %d (0x%x)\n", "Version", iv + 1, iv);
+ SECU_PrintAlgorithmID(out, &(crl->signatureAlg), "Signature Algorithm",
+ level + 1);
+ SECU_PrintName(out, &(crl->name), "Issuer", level + 1);
+ SECU_PrintTimeChoice(out, &(crl->lastUpdate), "This Update", level + 1);
+ if (crl->nextUpdate.data && crl->nextUpdate.len) /* is optional */
+ SECU_PrintTimeChoice(out, &(crl->nextUpdate), "Next Update", level + 1);
+
+ if (crl->entries != NULL) {
+ iv = 0;
+ while ((entry = crl->entries[iv++]) != NULL) {
+ sprintf(om, "Entry (%x):\n", iv);
+ SECU_Indent(out, level + 1);
+ fprintf(out, "%s", om);
+ SECU_PrintInteger(out, &(entry->serialNumber), "Serial Number",
+ level + 2);
+ SECU_PrintTimeChoice(out, &(entry->revocationDate),
+ "Revocation Date", level + 2);
+ SECU_PrintExtensions(out, entry->extensions,
+ "Entry Extensions", level + 2);
+ }
+ }
+ SECU_PrintExtensions(out, crl->extensions, "CRL Extensions", level + 1);
+}
+
+/*
+** secu_PrintPKCS7Signed
+** Pretty print a PKCS7 signed data type (up to version 1).
+*/
+static int
+secu_PrintPKCS7Signed(FILE *out, SEC_PKCS7SignedData *src,
+ const char *m, int level)
+{
+ SECAlgorithmID *digAlg; /* digest algorithms */
+ SECItem *aCert; /* certificate */
+ CERTSignedCrl *aCrl; /* certificate revocation list */
+ SEC_PKCS7SignerInfo *sigInfo; /* signer information */
+ int rv, iv;
+ char om[100];
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(src->version), "Version", level + 1);
+
+ /* Parse and list digest algorithms (if any) */
+ if (src->digestAlgorithms != NULL) {
+ SECU_Indent(out, level + 1); fprintf(out, "Digest Algorithm List:\n");
+ iv = 0;
+ while ((digAlg = src->digestAlgorithms[iv++]) != NULL) {
+ sprintf(om, "Digest Algorithm (%x)", iv);
+ SECU_PrintAlgorithmID(out, digAlg, om, level + 2);
+ }
+ }
+
+ /* Now for the content */
+ rv = secu_PrintPKCS7ContentInfo(out, &(src->contentInfo),
+ "Content Information", level + 1);
+ if (rv != 0)
+ return rv;
+
+ /* Parse and list certificates (if any) */
+ if (src->rawCerts != NULL) {
+ SECU_Indent(out, level + 1); fprintf(out, "Certificate List:\n");
+ iv = 0;
+ while ((aCert = src->rawCerts[iv++]) != NULL) {
+ sprintf(om, "Certificate (%x)", iv);
+ rv = SECU_PrintSignedData(out, aCert, om, level + 2,
+ SECU_PrintCertificate);
+ if (rv)
+ return rv;
+ }
+ }
+
+ /* Parse and list CRL's (if any) */
+ if (src->crls != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Signed Revocation Lists:\n");
+ iv = 0;
+ while ((aCrl = src->crls[iv++]) != NULL) {
+ sprintf(om, "Signed Revocation List (%x)", iv);
+ SECU_Indent(out, level + 2); fprintf(out, "%s:\n", om);
+ SECU_PrintAlgorithmID(out, &aCrl->signatureWrap.signatureAlgorithm,
+ "Signature Algorithm", level+3);
+ DER_ConvertBitString(&aCrl->signatureWrap.signature);
+ SECU_PrintAsHex(out, &aCrl->signatureWrap.signature, "Signature",
+ level+3);
+ SECU_PrintCRLInfo(out, &aCrl->crl, "Certificate Revocation List",
+ level + 3);
+ }
+ }
+
+ /* Parse and list signatures (if any) */
+ if (src->signerInfos != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Signer Information List:\n");
+ iv = 0;
+ while ((sigInfo = src->signerInfos[iv++]) != NULL) {
+ sprintf(om, "Signer Information (%x)", iv);
+ secu_PrintSignerInfo(out, sigInfo, om, level + 2);
+ }
+ }
+
+ return 0;
+}
+
+/*
+** secu_PrintPKCS7Enveloped
+** Pretty print a PKCS7 enveloped data type (up to version 1).
+*/
+static void
+secu_PrintPKCS7Enveloped(FILE *out, SEC_PKCS7EnvelopedData *src,
+ const char *m, int level)
+{
+ SEC_PKCS7RecipientInfo *recInfo; /* pointer for signer information */
+ int iv;
+ char om[100];
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(src->version), "Version", level + 1);
+
+ /* Parse and list recipients (this is not optional) */
+ if (src->recipientInfos != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Recipient Information List:\n");
+ iv = 0;
+ while ((recInfo = src->recipientInfos[iv++]) != NULL) {
+ sprintf(om, "Recipient Information (%x)", iv);
+ secu_PrintRecipientInfo(out, recInfo, om, level + 2);
+ }
+ }
+
+ secu_PrintPKCS7EncContent(out, &src->encContentInfo,
+ "Encrypted Content Information", level + 1);
+}
+
+/*
+** secu_PrintPKCS7SignedEnveloped
+** Pretty print a PKCS7 singed and enveloped data type (up to version 1).
+*/
+static int
+secu_PrintPKCS7SignedAndEnveloped(FILE *out,
+ SEC_PKCS7SignedAndEnvelopedData *src,
+ const char *m, int level)
+{
+ SECAlgorithmID *digAlg; /* pointer for digest algorithms */
+ SECItem *aCert; /* pointer for certificate */
+ CERTSignedCrl *aCrl; /* pointer for certificate revocation list */
+ SEC_PKCS7SignerInfo *sigInfo; /* pointer for signer information */
+ SEC_PKCS7RecipientInfo *recInfo; /* pointer for recipient information */
+ int rv, iv;
+ char om[100];
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(src->version), "Version", level + 1);
+
+ /* Parse and list recipients (this is not optional) */
+ if (src->recipientInfos != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Recipient Information List:\n");
+ iv = 0;
+ while ((recInfo = src->recipientInfos[iv++]) != NULL) {
+ sprintf(om, "Recipient Information (%x)", iv);
+ secu_PrintRecipientInfo(out, recInfo, om, level + 2);
+ }
+ }
+
+ /* Parse and list digest algorithms (if any) */
+ if (src->digestAlgorithms != NULL) {
+ SECU_Indent(out, level + 1); fprintf(out, "Digest Algorithm List:\n");
+ iv = 0;
+ while ((digAlg = src->digestAlgorithms[iv++]) != NULL) {
+ sprintf(om, "Digest Algorithm (%x)", iv);
+ SECU_PrintAlgorithmID(out, digAlg, om, level + 2);
+ }
+ }
+
+ secu_PrintPKCS7EncContent(out, &src->encContentInfo,
+ "Encrypted Content Information", level + 1);
+
+ /* Parse and list certificates (if any) */
+ if (src->rawCerts != NULL) {
+ SECU_Indent(out, level + 1); fprintf(out, "Certificate List:\n");
+ iv = 0;
+ while ((aCert = src->rawCerts[iv++]) != NULL) {
+ sprintf(om, "Certificate (%x)", iv);
+ rv = SECU_PrintSignedData(out, aCert, om, level + 2,
+ SECU_PrintCertificate);
+ if (rv)
+ return rv;
+ }
+ }
+
+ /* Parse and list CRL's (if any) */
+ if (src->crls != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Signed Revocation Lists:\n");
+ iv = 0;
+ while ((aCrl = src->crls[iv++]) != NULL) {
+ sprintf(om, "Signed Revocation List (%x)", iv);
+ SECU_Indent(out, level + 2); fprintf(out, "%s:\n", om);
+ SECU_PrintAlgorithmID(out, &aCrl->signatureWrap.signatureAlgorithm,
+ "Signature Algorithm", level+3);
+ DER_ConvertBitString(&aCrl->signatureWrap.signature);
+ SECU_PrintAsHex(out, &aCrl->signatureWrap.signature, "Signature",
+ level+3);
+ SECU_PrintCRLInfo(out, &aCrl->crl, "Certificate Revocation List",
+ level + 3);
+ }
+ }
+
+ /* Parse and list signatures (if any) */
+ if (src->signerInfos != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Signer Information List:\n");
+ iv = 0;
+ while ((sigInfo = src->signerInfos[iv++]) != NULL) {
+ sprintf(om, "Signer Information (%x)", iv);
+ secu_PrintSignerInfo(out, sigInfo, om, level + 2);
+ }
+ }
+
+ return 0;
+}
+
+int
+SECU_PrintCrl(FILE *out, SECItem *der, const char *m, int level)
+{
+ PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ CERTCrl *c = NULL;
+ int rv = SEC_ERROR_NO_MEMORY;
+
+ if (!arena)
+ return rv;
+ do {
+ /* Decode CRL */
+ c = PORT_ArenaZNew(arena, CERTCrl);
+ if (!c)
+ break;
+
+ rv = SEC_QuickDERDecodeItem(arena, c, SEC_ASN1_GET(CERT_CrlTemplate), der);
+ if (rv != SECSuccess)
+ break;
+ SECU_PrintCRLInfo (out, c, m, level);
+ } while (0);
+ PORT_FreeArena (arena, PR_FALSE);
+ return rv;
+}
+
+
+/*
+** secu_PrintPKCS7Encrypted
+** Pretty print a PKCS7 encrypted data type (up to version 1).
+*/
+static void
+secu_PrintPKCS7Encrypted(FILE *out, SEC_PKCS7EncryptedData *src,
+ const char *m, int level)
+{
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(src->version), "Version", level + 1);
+
+ secu_PrintPKCS7EncContent(out, &src->encContentInfo,
+ "Encrypted Content Information", level + 1);
+}
+
+/*
+** secu_PrintPKCS7Digested
+** Pretty print a PKCS7 digested data type (up to version 1).
+*/
+static void
+secu_PrintPKCS7Digested(FILE *out, SEC_PKCS7DigestedData *src,
+ const char *m, int level)
+{
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(src->version), "Version", level + 1);
+
+ SECU_PrintAlgorithmID(out, &src->digestAlg, "Digest Algorithm",
+ level + 1);
+ secu_PrintPKCS7ContentInfo(out, &src->contentInfo, "Content Information",
+ level + 1);
+ SECU_PrintAsHex(out, &src->digest, "Digest", level + 1);
+}
+
+/*
+** secu_PrintPKCS7ContentInfo
+** Takes a SEC_PKCS7ContentInfo type and sends the contents to the
+** appropriate function
+*/
+static int
+secu_PrintPKCS7ContentInfo(FILE *out, SEC_PKCS7ContentInfo *src,
+ const char *m, int level)
+{
+ const char *desc;
+ SECOidTag kind;
+ int rv;
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ level++;
+
+ if (src->contentTypeTag == NULL)
+ src->contentTypeTag = SECOID_FindOID(&(src->contentType));
+
+ if (src->contentTypeTag == NULL) {
+ desc = "Unknown";
+ kind = SEC_OID_PKCS7_DATA;
+ } else {
+ desc = src->contentTypeTag->desc;
+ kind = src->contentTypeTag->offset;
+ }
+
+ if (src->content.data == NULL) {
+ SECU_Indent(out, level); fprintf(out, "%s:\n", desc);
+ level++;
+ SECU_Indent(out, level); fprintf(out, "<no content>\n");
+ return 0;
+ }
+
+ rv = 0;
+ switch (kind) {
+ case SEC_OID_PKCS7_SIGNED_DATA: /* Signed Data */
+ rv = secu_PrintPKCS7Signed(out, src->content.signedData, desc, level);
+ break;
+
+ case SEC_OID_PKCS7_ENVELOPED_DATA: /* Enveloped Data */
+ secu_PrintPKCS7Enveloped(out, src->content.envelopedData, desc, level);
+ break;
+
+ case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: /* Signed and Enveloped */
+ rv = secu_PrintPKCS7SignedAndEnveloped(out,
+ src->content.signedAndEnvelopedData,
+ desc, level);
+ break;
+
+ case SEC_OID_PKCS7_DIGESTED_DATA: /* Digested Data */
+ secu_PrintPKCS7Digested(out, src->content.digestedData, desc, level);
+ break;
+
+ case SEC_OID_PKCS7_ENCRYPTED_DATA: /* Encrypted Data */
+ secu_PrintPKCS7Encrypted(out, src->content.encryptedData, desc, level);
+ break;
+
+ default:
+ SECU_PrintAsHex(out, src->content.data, desc, level);
+ break;
+ }
+
+ return rv;
+}
+
+/*
+** SECU_PrintPKCS7ContentInfo
+** Decode and print any major PKCS7 data type (up to version 1).
+*/
+int
+SECU_PrintPKCS7ContentInfo(FILE *out, SECItem *der, const char *m, int level)
+{
+ SEC_PKCS7ContentInfo *cinfo;
+ int rv;
+
+ cinfo = SEC_PKCS7DecodeItem(der, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ if (cinfo != NULL) {
+ /* Send it to recursive parsing and printing module */
+ rv = secu_PrintPKCS7ContentInfo(out, cinfo, m, level);
+ SEC_PKCS7DestroyContentInfo(cinfo);
+ } else {
+ rv = -1;
+ }
+
+ return rv;
+}
+
+/*
+** End of PKCS7 functions
+*/
+
+static void
+printFlags(FILE *out, unsigned int flags, int level)
+{
+ if ( flags & CERTDB_VALID_PEER ) {
+ SECU_Indent(out, level); fprintf(out, "Valid Peer\n");
+ }
+ if ( flags & CERTDB_TRUSTED ) {
+ SECU_Indent(out, level); fprintf(out, "Trusted\n");
+ }
+ if ( flags & CERTDB_SEND_WARN ) {
+ SECU_Indent(out, level); fprintf(out, "Warn When Sending\n");
+ }
+ if ( flags & CERTDB_VALID_CA ) {
+ SECU_Indent(out, level); fprintf(out, "Valid CA\n");
+ }
+ if ( flags & CERTDB_TRUSTED_CA ) {
+ SECU_Indent(out, level); fprintf(out, "Trusted CA\n");
+ }
+ if ( flags & CERTDB_NS_TRUSTED_CA ) {
+ SECU_Indent(out, level); fprintf(out, "Netscape Trusted CA\n");
+ }
+ if ( flags & CERTDB_USER ) {
+ SECU_Indent(out, level); fprintf(out, "User\n");
+ }
+ if ( flags & CERTDB_TRUSTED_CLIENT_CA ) {
+ SECU_Indent(out, level); fprintf(out, "Trusted Client CA\n");
+ }
+ if ( flags & CERTDB_GOVT_APPROVED_CA ) {
+ SECU_Indent(out, level); fprintf(out, "Step-up\n");
+ }
+}
+
+void
+SECU_PrintTrustFlags(FILE *out, CERTCertTrust *trust, const char *m, int level)
+{
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_Indent(out, level+1); fprintf(out, "SSL Flags:\n");
+ printFlags(out, trust->sslFlags, level+2);
+ SECU_Indent(out, level+1); fprintf(out, "Email Flags:\n");
+ printFlags(out, trust->emailFlags, level+2);
+ SECU_Indent(out, level+1); fprintf(out, "Object Signing Flags:\n");
+ printFlags(out, trust->objectSigningFlags, level+2);
+}
+
+int SECU_PrintSignedData(FILE *out, SECItem *der, const char *m,
+ int level, SECU_PPFunc inner)
+{
+ PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ CERTSignedData *sd;
+ int rv = SEC_ERROR_NO_MEMORY;
+
+ if (!arena)
+ return rv;
+
+ /* Strip off the signature */
+ sd = PORT_ArenaZNew(arena, CERTSignedData);
+ if (!sd)
+ goto loser;
+
+ rv = SEC_ASN1DecodeItem(arena, sd, SEC_ASN1_GET(CERT_SignedDataTemplate),
+ der);
+ if (rv)
+ goto loser;
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ rv = (*inner)(out, &sd->data, "Data", level+1);
+
+ SECU_PrintAlgorithmID(out, &sd->signatureAlgorithm, "Signature Algorithm",
+ level+1);
+ DER_ConvertBitString(&sd->signature);
+ SECU_PrintAsHex(out, &sd->signature, "Signature", level+1);
+ SECU_PrintFingerprints(out, der, "Fingerprint", level+1);
+loser:
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+
+}
+
+SECStatus
+SECU_ParseCommandLine(int argc, char **argv, char *progName, secuCommand *cmd)
+{
+ PRBool found;
+ PLOptState *optstate;
+ PLOptStatus status;
+ char *optstring;
+ int i, j;
+
+ optstring = (char *)malloc(cmd->numCommands + 2*cmd->numOptions);
+ j = 0;
+
+ for (i=0; i<cmd->numCommands; i++) {
+ optstring[j++] = cmd->commands[i].flag;
+ }
+ for (i=0; i<cmd->numOptions; i++) {
+ optstring[j++] = cmd->options[i].flag;
+ if (cmd->options[i].needsArg)
+ optstring[j++] = ':';
+ }
+ optstring[j] = '\0';
+ optstate = PL_CreateOptState(argc, argv, optstring);
+
+ /* Parse command line arguments */
+ while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
+
+ /* Wasn't really an option, just standalone arg. */
+ if (optstate->option == '\0')
+ continue;
+
+ found = PR_FALSE;
+
+ for (i=0; i<cmd->numCommands; i++) {
+ if (cmd->commands[i].flag == optstate->option) {
+ cmd->commands[i].activated = PR_TRUE;
+ if (optstate->value) {
+ cmd->commands[i].arg = (char *)optstate->value;
+ }
+ found = PR_TRUE;
+ break;
+ }
+ }
+
+ if (found)
+ continue;
+
+ for (i=0; i<cmd->numOptions; i++) {
+ if (cmd->options[i].flag == optstate->option) {
+ cmd->options[i].activated = PR_TRUE;
+ if (optstate->value) {
+ cmd->options[i].arg = (char *)optstate->value;
+ } else if (cmd->options[i].needsArg) {
+ return SECFailure;
+ }
+ found = PR_TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ return SECFailure;
+ }
+ if (status == PL_OPT_BAD)
+ return SECFailure;
+ return SECSuccess;
+}
+
+char *
+SECU_GetOptionArg(secuCommand *cmd, int optionNum)
+{
+ if (optionNum < 0 || optionNum >= cmd->numOptions)
+ return NULL;
+ if (cmd->options[optionNum].activated)
+ return PL_strdup(cmd->options[optionNum].arg);
+ else
+ return NULL;
+}
+
+static char SECUErrorBuf[64];
+
+char *
+SECU_ErrorStringRaw(int16 err)
+{
+ if (err == 0)
+ SECUErrorBuf[0] = '\0';
+ else if (err == SEC_ERROR_BAD_DATA)
+ sprintf(SECUErrorBuf, "Bad data");
+ else if (err == SEC_ERROR_BAD_DATABASE)
+ sprintf(SECUErrorBuf, "Problem with database");
+ else if (err == SEC_ERROR_BAD_DER)
+ sprintf(SECUErrorBuf, "Problem with DER");
+ else if (err == SEC_ERROR_BAD_KEY)
+ sprintf(SECUErrorBuf, "Problem with key");
+ else if (err == SEC_ERROR_BAD_PASSWORD)
+ sprintf(SECUErrorBuf, "Incorrect password");
+ else if (err == SEC_ERROR_BAD_SIGNATURE)
+ sprintf(SECUErrorBuf, "Bad signature");
+ else if (err == SEC_ERROR_EXPIRED_CERTIFICATE)
+ sprintf(SECUErrorBuf, "Expired certificate");
+ else if (err == SEC_ERROR_EXTENSION_VALUE_INVALID)
+ sprintf(SECUErrorBuf, "Invalid extension value");
+ else if (err == SEC_ERROR_INPUT_LEN)
+ sprintf(SECUErrorBuf, "Problem with input length");
+ else if (err == SEC_ERROR_INVALID_ALGORITHM)
+ sprintf(SECUErrorBuf, "Invalid algorithm");
+ else if (err == SEC_ERROR_INVALID_ARGS)
+ sprintf(SECUErrorBuf, "Invalid arguments");
+ else if (err == SEC_ERROR_INVALID_AVA)
+ sprintf(SECUErrorBuf, "Invalid AVA");
+ else if (err == SEC_ERROR_INVALID_TIME)
+ sprintf(SECUErrorBuf, "Invalid time");
+ else if (err == SEC_ERROR_IO)
+ sprintf(SECUErrorBuf, "Security I/O error");
+ else if (err == SEC_ERROR_LIBRARY_FAILURE)
+ sprintf(SECUErrorBuf, "Library failure");
+ else if (err == SEC_ERROR_NO_MEMORY)
+ sprintf(SECUErrorBuf, "Out of memory");
+ else if (err == SEC_ERROR_OLD_CRL)
+ sprintf(SECUErrorBuf, "CRL is older than the current one");
+ else if (err == SEC_ERROR_OUTPUT_LEN)
+ sprintf(SECUErrorBuf, "Problem with output length");
+ else if (err == SEC_ERROR_UNKNOWN_ISSUER)
+ sprintf(SECUErrorBuf, "Unknown issuer");
+ else if (err == SEC_ERROR_UNTRUSTED_CERT)
+ sprintf(SECUErrorBuf, "Untrusted certificate");
+ else if (err == SEC_ERROR_UNTRUSTED_ISSUER)
+ sprintf(SECUErrorBuf, "Untrusted issuer");
+ else if (err == SSL_ERROR_BAD_CERTIFICATE)
+ sprintf(SECUErrorBuf, "Bad certificate");
+ else if (err == SSL_ERROR_BAD_CLIENT)
+ sprintf(SECUErrorBuf, "Bad client");
+ else if (err == SSL_ERROR_BAD_SERVER)
+ sprintf(SECUErrorBuf, "Bad server");
+ else if (err == SSL_ERROR_EXPORT_ONLY_SERVER)
+ sprintf(SECUErrorBuf, "Export only server");
+ else if (err == SSL_ERROR_NO_CERTIFICATE)
+ sprintf(SECUErrorBuf, "No certificate");
+ else if (err == SSL_ERROR_NO_CYPHER_OVERLAP)
+ sprintf(SECUErrorBuf, "No cypher overlap");
+ else if (err == SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE)
+ sprintf(SECUErrorBuf, "Unsupported certificate type");
+ else if (err == SSL_ERROR_UNSUPPORTED_VERSION)
+ sprintf(SECUErrorBuf, "Unsupported version");
+ else if (err == SSL_ERROR_US_ONLY_SERVER)
+ sprintf(SECUErrorBuf, "U.S. only server");
+ else if (err == PR_IO_ERROR)
+ sprintf(SECUErrorBuf, "I/O error");
+
+ else if (err == SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE)
+ sprintf (SECUErrorBuf, "Expired Issuer Certificate");
+ else if (err == SEC_ERROR_REVOKED_CERTIFICATE)
+ sprintf (SECUErrorBuf, "Revoked certificate");
+ else if (err == SEC_ERROR_NO_KEY)
+ sprintf (SECUErrorBuf, "No private key in database for this cert");
+ else if (err == SEC_ERROR_CERT_NOT_VALID)
+ sprintf (SECUErrorBuf, "Certificate is not valid");
+ else if (err == SEC_ERROR_EXTENSION_NOT_FOUND)
+ sprintf (SECUErrorBuf, "Certificate extension was not found");
+ else if (err == SEC_ERROR_CA_CERT_INVALID)
+ sprintf (SECUErrorBuf, "Issuer certificate is invalid");
+ else if (err == SEC_ERROR_CERT_USAGES_INVALID)
+ sprintf (SECUErrorBuf, "Certificate usages is invalid");
+ else if (err == SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION)
+ sprintf (SECUErrorBuf, "Certificate has unknown critical extension");
+ else if (err == SEC_ERROR_PKCS7_BAD_SIGNATURE)
+ sprintf (SECUErrorBuf, "Bad PKCS7 signature");
+ else if (err == SEC_ERROR_INADEQUATE_KEY_USAGE)
+ sprintf (SECUErrorBuf, "Certificate not approved for this operation");
+ else if (err == SEC_ERROR_INADEQUATE_CERT_TYPE)
+ sprintf (SECUErrorBuf, "Certificate not approved for this operation");
+
+ return SECUErrorBuf;
+}
+
+char *
+SECU_ErrorString(int16 err)
+{
+ char *error_string;
+
+ *SECUErrorBuf = 0;
+ SECU_ErrorStringRaw (err);
+
+ if (*SECUErrorBuf == 0) {
+ error_string = SECU_GetString(err);
+ if (error_string == NULL || *error_string == '\0')
+ sprintf(SECUErrorBuf, "No error string found for %d.", err);
+ else
+ return error_string;
+ }
+
+ return SECUErrorBuf;
+}
+
+
+void
+SECU_PrintPRandOSError(const char *progName)
+{
+ char buffer[513];
+ PRInt32 errLen = PR_GetErrorTextLength();
+ if ((errLen > 0) && ((size_t) errLen < sizeof(buffer))) {
+ PR_GetErrorText(buffer);
+ }
+ SECU_PrintError(progName, "function failed");
+ if ((errLen > 0) && ((size_t) errLen < sizeof(buffer))) {
+ PR_fprintf(PR_STDERR, "\t%s\n", buffer);
+ }
+}
+
+
+static char *
+bestCertName(CERTCertificate *cert) {
+ if (cert->nickname) {
+ return cert->nickname;
+ }
+ if (cert->emailAddr && cert->emailAddr[0]) {
+ return cert->emailAddr;
+ }
+ return cert->subjectName;
+}
+
+void
+SECU_printCertProblems(FILE *outfile, CERTCertDBHandle *handle,
+ CERTCertificate *cert, PRBool checksig,
+ SECCertificateUsage certUsage, void *pinArg, PRBool verbose)
+{
+ CERTVerifyLog log;
+ CERTVerifyLogNode *node = NULL;
+ unsigned int depth = (unsigned int)-1;
+ unsigned int flags = 0;
+ const char * errstr = NULL;
+ PRErrorCode err = PORT_GetError();
+
+ log.arena = PORT_NewArena(512);
+ log.head = log.tail = NULL;
+ log.count = 0;
+ CERT_VerifyCertificate(handle, cert, checksig, certUsage, PR_Now(), pinArg, &log, NULL);
+
+ if (log.count > 0) {
+ fprintf(outfile,"PROBLEM WITH THE CERT CHAIN:\n");
+ for (node = log.head; node; node = node->next) {
+ if (depth != node->depth) {
+ depth = node->depth;
+ fprintf(outfile,"CERT %d. %s %s:\n", depth,
+ bestCertName(node->cert),
+ depth ? "[Certificate Authority]": "");
+ if (verbose) {
+ const char * emailAddr;
+ emailAddr = CERT_GetFirstEmailAddress(node->cert);
+ if (emailAddr) {
+ fprintf(outfile,"Email Address(es): ");
+ do {
+ fprintf(outfile, "%s\n", emailAddr);
+ emailAddr = CERT_GetNextEmailAddress(node->cert,
+ emailAddr);
+ } while (emailAddr);
+ }
+ }
+ }
+ fprintf(outfile," ERROR %ld: %s\n", node->error,
+ SECU_Strerror(node->error));
+ errstr = NULL;
+ switch (node->error) {
+ case SEC_ERROR_INADEQUATE_KEY_USAGE:
+ flags = (unsigned int)node->arg;
+ switch (flags) {
+ case KU_DIGITAL_SIGNATURE:
+ errstr = "Cert cannot sign.";
+ break;
+ case KU_KEY_ENCIPHERMENT:
+ errstr = "Cert cannot encrypt.";
+ break;
+ case KU_KEY_CERT_SIGN:
+ errstr = "Cert cannot sign other certs.";
+ break;
+ default:
+ errstr = "[unknown usage].";
+ break;
+ }
+ case SEC_ERROR_INADEQUATE_CERT_TYPE:
+ flags = (unsigned int)node->arg;
+ switch (flags) {
+ case NS_CERT_TYPE_SSL_CLIENT:
+ case NS_CERT_TYPE_SSL_SERVER:
+ errstr = "Cert cannot be used for SSL.";
+ break;
+ case NS_CERT_TYPE_SSL_CA:
+ errstr = "Cert cannot be used as an SSL CA.";
+ break;
+ case NS_CERT_TYPE_EMAIL:
+ errstr = "Cert cannot be used for SMIME.";
+ break;
+ case NS_CERT_TYPE_EMAIL_CA:
+ errstr = "Cert cannot be used as an SMIME CA.";
+ break;
+ case NS_CERT_TYPE_OBJECT_SIGNING:
+ errstr = "Cert cannot be used for object signing.";
+ break;
+ case NS_CERT_TYPE_OBJECT_SIGNING_CA:
+ errstr = "Cert cannot be used as an object signing CA.";
+ break;
+ default:
+ errstr = "[unknown usage].";
+ break;
+ }
+ case SEC_ERROR_UNKNOWN_ISSUER:
+ case SEC_ERROR_UNTRUSTED_ISSUER:
+ case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
+ errstr = node->cert->issuerName;
+ break;
+ default:
+ break;
+ }
+ if (errstr) {
+ fprintf(stderr," %s\n",errstr);
+ }
+ CERT_DestroyCertificate(node->cert);
+ }
+ }
+ PORT_SetError(err); /* restore original error code */
+}
+
+SECOidTag
+SECU_StringToSignatureAlgTag(const char *alg)
+{
+ SECOidTag hashAlgTag = SEC_OID_UNKNOWN;
+
+ if (alg) {
+ if (!PL_strcmp(alg, "MD2")) {
+ hashAlgTag = SEC_OID_MD2;
+ } else if (!PL_strcmp(alg, "MD4")) {
+ hashAlgTag = SEC_OID_MD4;
+ } else if (!PL_strcmp(alg, "MD5")) {
+ hashAlgTag = SEC_OID_MD5;
+ } else if (!PL_strcmp(alg, "SHA1")) {
+ hashAlgTag = SEC_OID_SHA1;
+ } else if (!PL_strcmp(alg, "SHA256")) {
+ hashAlgTag = SEC_OID_SHA256;
+ } else if (!PL_strcmp(alg, "SHA384")) {
+ hashAlgTag = SEC_OID_SHA384;
+ } else if (!PL_strcmp(alg, "SHA512")) {
+ hashAlgTag = SEC_OID_SHA512;
+ }
+ }
+ return hashAlgTag;
+}
+
+
+SECStatus
+SECU_StoreCRL(PK11SlotInfo *slot, SECItem *derCrl, PRFileDesc *outFile,
+ const PRBool ascii, char *url)
+{
+ PORT_Assert(derCrl != NULL);
+ if (!derCrl) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ if (outFile != NULL) {
+ if (ascii) {
+ PR_fprintf(outFile, "%s\n%s\n%s\n", NS_CRL_HEADER,
+ BTOA_DataToAscii(derCrl->data, derCrl->len),
+ NS_CRL_TRAILER);
+ } else {
+ if (PR_Write(outFile, derCrl->data, derCrl->len) != derCrl->len) {
+ return SECFailure;
+ }
+ }
+ }
+ if (slot) {
+ CERTSignedCrl *newCrl = PK11_ImportCRL(slot, derCrl, url,
+ SEC_CRL_TYPE, NULL, 0, NULL, 0);
+ if (newCrl != NULL) {
+ SEC_DestroyCrl(newCrl);
+ return SECSuccess;
+ }
+ return SECFailure;
+ }
+ if (!outFile && !slot) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+SECStatus
+SECU_SignAndEncodeCRL(CERTCertificate *issuer, CERTSignedCrl *signCrl,
+ SECOidTag hashAlgTag, SignAndEncodeFuncExitStat *resCode)
+{
+ SECItem der;
+ SECKEYPrivateKey *caPrivateKey = NULL;
+ SECStatus rv;
+ PRArenaPool *arena;
+ SECOidTag algID;
+ void *dummy;
+
+ PORT_Assert(issuer != NULL && signCrl != NULL);
+ if (!issuer || !signCrl) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ arena = signCrl->arena;
+
+ caPrivateKey = PK11_FindKeyByAnyCert(issuer, NULL);
+ if (caPrivateKey == NULL) {
+ *resCode = noKeyFound;
+ return SECFailure;
+ }
+
+ algID = SEC_GetSignatureAlgorithmOidTag(caPrivateKey->keyType, hashAlgTag);
+ if (algID == SEC_OID_UNKNOWN) {
+ *resCode = noSignatureMatch;
+ rv = SECFailure;
+ goto done;
+ }
+
+ if (!signCrl->crl.signatureAlg.parameters.data) {
+ rv = SECOID_SetAlgorithmID(arena, &signCrl->crl.signatureAlg, algID, 0);
+ if (rv != SECSuccess) {
+ *resCode = failToEncode;
+ goto done;
+ }
+ }
+
+ der.len = 0;
+ der.data = NULL;
+ dummy = SEC_ASN1EncodeItem(arena, &der, &signCrl->crl,
+ SEC_ASN1_GET(CERT_CrlTemplate));
+ if (!dummy) {
+ *resCode = failToEncode;
+ rv = SECFailure;
+ goto done;
+ }
+
+ rv = SECU_DerSignDataCRL(arena, &signCrl->signatureWrap,
+ der.data, der.len, caPrivateKey, algID);
+ if (rv != SECSuccess) {
+ *resCode = failToSign;
+ goto done;
+ }
+
+ signCrl->derCrl = PORT_ArenaZNew(arena, SECItem);
+ if (signCrl->derCrl == NULL) {
+ *resCode = noMem;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ rv = SECFailure;
+ goto done;
+ }
+
+ signCrl->derCrl->len = 0;
+ signCrl->derCrl->data = NULL;
+ dummy = SEC_ASN1EncodeItem (arena, signCrl->derCrl, signCrl,
+ SEC_ASN1_GET(CERT_SignedCrlTemplate));
+ if (!dummy) {
+ *resCode = failToEncode;
+ rv = SECFailure;
+ goto done;
+ }
+
+done:
+ if (caPrivateKey) {
+ SECKEY_DestroyPrivateKey(caPrivateKey);
+ }
+ return rv;
+}
+
+
+
+SECStatus
+SECU_CopyCRL(PRArenaPool *destArena, CERTCrl *destCrl, CERTCrl *srcCrl)
+{
+ void *dummy;
+ SECStatus rv = SECSuccess;
+ SECItem der;
+
+ PORT_Assert(destArena && srcCrl && destCrl);
+ if (!destArena || !srcCrl || !destCrl) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ der.len = 0;
+ der.data = NULL;
+ dummy = SEC_ASN1EncodeItem (destArena, &der, srcCrl,
+ SEC_ASN1_GET(CERT_CrlTemplate));
+ if (!dummy) {
+ return SECFailure;
+ }
+
+ rv = SEC_QuickDERDecodeItem(destArena, destCrl,
+ SEC_ASN1_GET(CERT_CrlTemplate), &der);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ destCrl->arena = destArena;
+
+ return rv;
+}
+
+SECStatus
+SECU_DerSignDataCRL(PRArenaPool *arena, CERTSignedData *sd,
+ unsigned char *buf, int len, SECKEYPrivateKey *pk,
+ SECOidTag algID)
+{
+ SECItem it;
+ SECStatus rv;
+
+ it.data = 0;
+
+ /* XXX We should probably have some asserts here to make sure the key type
+ * and algID match
+ */
+
+ /* Sign input buffer */
+ rv = SEC_SignData(&it, buf, len, pk, algID);
+ if (rv) goto loser;
+
+ /* Fill out SignedData object */
+ PORT_Memset(sd, 0, sizeof(*sd));
+ sd->data.data = buf;
+ sd->data.len = len;
+ sd->signature.data = it.data;
+ sd->signature.len = it.len << 3; /* convert to bit string */
+ rv = SECOID_SetAlgorithmID(arena, &sd->signatureAlgorithm, algID, 0);
+ if (rv) goto loser;
+
+ return rv;
+
+ loser:
+ PORT_Free(it.data);
+ return rv;
+}
+
+#if 0
+
+/* we need access to the private function cert_FindExtension for this code to work */
+
+CERTAuthKeyID *
+SECU_FindCRLAuthKeyIDExten (PRArenaPool *arena, CERTSignedCrl *scrl)
+{
+ SECItem encodedExtenValue;
+ SECStatus rv;
+ CERTAuthKeyID *ret;
+ CERTCrl* crl;
+
+ if (!scrl) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
+ }
+
+ crl = &scrl->crl;
+
+ encodedExtenValue.data = NULL;
+ encodedExtenValue.len = 0;
+
+ rv = cert_FindExtension(crl->extensions, SEC_OID_X509_AUTH_KEY_ID,
+ &encodedExtenValue);
+ if ( rv != SECSuccess ) {
+ return (NULL);
+ }
+
+ ret = CERT_DecodeAuthKeyID (arena, &encodedExtenValue);
+
+ PORT_Free(encodedExtenValue.data);
+ encodedExtenValue.data = NULL;
+
+ return(ret);
+}
+
+#endif
+
+/*
+ * Find the issuer of a Crl. Use the authorityKeyID if it exists.
+ */
+CERTCertificate *
+SECU_FindCrlIssuer(CERTCertDBHandle *dbhandle, SECItem* subject,
+ CERTAuthKeyID* authorityKeyID, PRTime validTime)
+{
+ CERTCertificate *issuerCert = NULL;
+ CERTCertList *certList = NULL;
+
+ if (!subject) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
+ }
+
+ certList =
+ CERT_CreateSubjectCertList(NULL, dbhandle, subject,
+ validTime, PR_TRUE);
+ if (certList) {
+ CERTCertListNode *node = CERT_LIST_HEAD(certList);
+
+ /* XXX and authoritykeyid in the future */
+ while ( ! CERT_LIST_END(node, certList) ) {
+ CERTCertificate *cert = node->cert;
+ /* check cert CERTCertTrust data is allocated, check cert
+ usage extension, check that cert has pkey in db. Select
+ the first (newest) user cert */
+ if (cert->trust &&
+ CERT_CheckCertUsage(cert, KU_CRL_SIGN) == SECSuccess &&
+ CERT_IsUserCert(cert)) {
+
+ issuerCert = CERT_DupCertificate(cert);
+ break;
+ }
+ node = CERT_LIST_NEXT(node);
+ }
+ CERT_DestroyCertList(certList);
+ }
+ return(issuerCert);
+}
+
+
+/* Encodes and adds extensions to the CRL or CRL entries. */
+SECStatus
+SECU_EncodeAndAddExtensionValue(PRArenaPool *arena, void *extHandle,
+ void *value, PRBool criticality, int extenType,
+ EXTEN_EXT_VALUE_ENCODER EncodeValueFn)
+{
+ SECItem encodedValue;
+ SECStatus rv;
+
+ encodedValue.data = NULL;
+ encodedValue.len = 0;
+ do {
+ rv = (*EncodeValueFn)(arena, value, &encodedValue);
+ if (rv != SECSuccess)
+ break;
+
+ rv = CERT_AddExtension(extHandle, extenType, &encodedValue,
+ criticality, PR_TRUE);
+ if (rv != SECSuccess)
+ break;
+ } while (0);
+
+ return (rv);
+}
diff --git a/base/native-tools/src/p7tool/secutil.h b/base/native-tools/src/p7tool/secutil.h
new file mode 100644
index 000000000..10c8f9ae6
--- /dev/null
+++ b/base/native-tools/src/p7tool/secutil.h
@@ -0,0 +1,430 @@
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/secutil.h
+ */
+
+#ifndef _SEC_UTIL_H_
+#define _SEC_UTIL_H_
+
+#include "seccomon.h"
+#include "secitem.h"
+#include "prerror.h"
+#include "base64.h"
+#include "key.h"
+#include "secpkcs7.h"
+#include "secasn1.h"
+#include "secder.h"
+#include <stdio.h>
+
+#define SEC_CT_PRIVATE_KEY "private-key"
+#define SEC_CT_PUBLIC_KEY "public-key"
+#define SEC_CT_CERTIFICATE "certificate"
+#define SEC_CT_CERTIFICATE_REQUEST "certificate-request"
+#define SEC_CT_PKCS7 "pkcs7"
+#define SEC_CT_CRL "crl"
+
+#define NS_CERTREQ_HEADER "-----BEGIN NEW CERTIFICATE REQUEST-----"
+#define NS_CERTREQ_TRAILER "-----END NEW CERTIFICATE REQUEST-----"
+
+#define NS_CERT_HEADER "-----BEGIN CERTIFICATE-----"
+#define NS_CERT_TRAILER "-----END CERTIFICATE-----"
+
+#define NS_CRL_HEADER "-----BEGIN CRL-----"
+#define NS_CRL_TRAILER "-----END CRL-----"
+
+/* From libsec/pcertdb.c --- it's not declared in sec.h */
+extern SECStatus SEC_AddPermCertificate(CERTCertDBHandle *handle,
+ SECItem *derCert, char *nickname, CERTCertTrust *trust);
+
+
+#ifdef SECUTIL_NEW
+typedef int (*SECU_PPFunc)(PRFileDesc *out, SECItem *item,
+ const char *msg, int level);
+#else
+typedef int (*SECU_PPFunc)(FILE *out, SECItem *item, const char *msg, int level);
+#endif
+
+typedef struct {
+ enum {
+ PW_NONE = 0,
+ PW_FROMFILE = 1,
+ PW_PLAINTEXT = 2,
+ PW_EXTERNAL = 3
+ } source;
+ char *data;
+} secuPWData;
+
+/*
+** Change a password on a token, or initialize a token with a password
+** if it does not already have one.
+** Use passwd to send the password in plaintext, pwFile to specify a
+** file containing the password, or NULL for both to prompt the user.
+*/
+SECStatus SECU_ChangePW(PK11SlotInfo *slot, char *passwd, char *pwFile);
+
+/* These were stolen from the old sec.h... */
+/*
+** Check a password for legitimacy. Passwords must be at least 8
+** characters long and contain one non-alphabetic. Return DSTrue if the
+** password is ok, DSFalse otherwise.
+*/
+extern PRBool SEC_CheckPassword(char *password);
+
+/*
+** Blind check of a password. Complement to SEC_CheckPassword which
+** ignores length and content type, just retuning DSTrue is the password
+** exists, DSFalse if NULL
+*/
+extern PRBool SEC_BlindCheckPassword(char *password);
+
+/*
+** Get a password.
+** First prompt with "msg" on "out", then read the password from "in".
+** The password is then checked using "chkpw".
+*/
+extern char *SEC_GetPassword(FILE *in, FILE *out, const char *msg,
+ PRBool (*chkpw)(char *));
+
+char *SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg);
+
+char *SECU_GetPasswordString(void *arg, char *prompt);
+
+/*
+** Write a dongle password.
+** Uses MD5 to hash constant system data (hostname, etc.), and then
+** creates RC4 key to encrypt a password "pw" into a file "fd".
+*/
+extern SECStatus SEC_WriteDongleFile(int fd, char *pw);
+
+/*
+** Get a dongle password.
+** Uses MD5 to hash constant system data (hostname, etc.), and then
+** creates RC4 key to decrypt and return a password from file "fd".
+*/
+extern char *SEC_ReadDongleFile(int fd);
+
+
+/* End stolen headers */
+
+/* Just sticks the two strings together with a / if needed */
+char *SECU_AppendFilenameToDir(char *dir, char *filename);
+
+/* Returns result of getenv("SSL_DIR") or NULL */
+extern char *SECU_DefaultSSLDir(void);
+
+/*
+** Should be called once during initialization to set the default
+** directory for looking for cert.db, key.db, and cert-nameidx.db files
+** Removes trailing '/' in 'base'
+** If 'base' is NULL, defaults to set to .netscape in home directory.
+*/
+extern char *SECU_ConfigDirectory(const char* base);
+
+/*
+** Basic callback function for SSL_GetClientAuthDataHook
+*/
+extern int
+SECU_GetClientAuthData(void *arg, PRFileDesc *fd,
+ struct CERTDistNamesStr *caNames,
+ struct CERTCertificateStr **pRetCert,
+ struct SECKEYPrivateKeyStr **pRetKey);
+
+/* print out an error message */
+extern void SECU_PrintError(const char *progName, const char *msg, ...);
+
+/* print out a system error message */
+extern void SECU_PrintSystemError(const char *progName, const char *msg, ...);
+
+/* Return informative error string */
+extern const char * SECU_Strerror(PRErrorCode errNum);
+
+/* print information about cert verification failure */
+extern void
+SECU_printCertProblems(FILE *outfile, CERTCertDBHandle *handle,
+ CERTCertificate *cert, PRBool checksig,
+ SECCertificateUsage certUsage, void *pinArg, PRBool verbose);
+
+/* Read the contents of a file into a SECItem */
+extern SECStatus SECU_FileToItem(SECItem *dst, PRFileDesc *src);
+extern SECStatus SECU_TextFileToItem(SECItem *dst, PRFileDesc *src);
+
+/* Read in a DER from a file, may be ascii */
+extern SECStatus
+SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii);
+
+/* Indent based on "level" */
+extern void SECU_Indent(FILE *out, int level);
+
+/* Print integer value and hex */
+extern void SECU_PrintInteger(FILE *out, SECItem *i, const char *m, int level);
+
+/* Print ObjectIdentifier symbolically */
+extern SECOidTag SECU_PrintObjectID(FILE *out, SECItem *oid, const char *m, int level);
+
+/* Print AlgorithmIdentifier symbolically */
+extern void SECU_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, const char *m,
+ int level);
+
+/* Print SECItem as hex */
+extern void SECU_PrintAsHex(FILE *out, SECItem *i, const const char *m, int level);
+
+/* dump a buffer in hex and ASCII */
+extern void SECU_PrintBuf(FILE *out, const char *msg, const void *vp, int len);
+
+/*
+ * Format and print the UTC Time "t". If the tag message "m" is not NULL,
+ * do indent formatting based on "level" and add a newline afterward;
+ * otherwise just print the formatted time string only.
+ */
+extern void SECU_PrintUTCTime(FILE *out, SECItem *t, const char *m, int level);
+
+/*
+ * Format and print the Generalized Time "t". If the tag message "m"
+ * is not NULL, * do indent formatting based on "level" and add a newline
+ * afterward; otherwise just print the formatted time string only.
+ */
+extern void SECU_PrintGeneralizedTime(FILE *out, SECItem *t, const char *m,
+ int level);
+
+/*
+ * Format and print the UTC or Generalized Time "t". If the tag message
+ * "m" is not NULL, do indent formatting based on "level" and add a newline
+ * afterward; otherwise just print the formatted time string only.
+ */
+extern void SECU_PrintTimeChoice(FILE *out, SECItem *t, const char *m, int level);
+
+/* callback for listing certs through pkcs11 */
+extern SECStatus SECU_PrintCertNickname(CERTCertListNode* cert, void *data);
+
+/* Dump all certificate nicknames in a database */
+extern SECStatus
+SECU_PrintCertificateNames(CERTCertDBHandle *handle, PRFileDesc* out,
+ PRBool sortByName, PRBool sortByTrust);
+
+/* See if nickname already in database. Return 1 true, 0 false, -1 error */
+int SECU_CheckCertNameExists(CERTCertDBHandle *handle, char *nickname);
+
+/* Dump contents of cert req */
+extern int SECU_PrintCertificateRequest(FILE *out, SECItem *der, const char *m,
+ int level);
+
+/* Dump contents of certificate */
+extern int SECU_PrintCertificate(FILE *out, SECItem *der, const char *m, int level);
+
+/* print trust flags on a cert */
+extern void SECU_PrintTrustFlags(FILE *out, CERTCertTrust *trust, const char *m, int level);
+
+/* Dump contents of public key */
+extern int SECU_PrintPublicKey(FILE *out, SECItem *der, const char *m, int level);
+
+#ifdef HAVE_EPV_TEMPLATE
+/* Dump contents of private key */
+extern int SECU_PrintPrivateKey(FILE *out, SECItem *der, char *m, int level);
+#endif
+
+/* Print the MD5 and SHA1 fingerprints of a cert */
+extern int SECU_PrintFingerprints(FILE *out, SECItem *derCert, const char *m,
+ int level);
+
+/* Pretty-print any PKCS7 thing */
+extern int SECU_PrintPKCS7ContentInfo(FILE *out, SECItem *der, const char *m,
+ int level);
+
+/* Init PKCS11 stuff */
+extern SECStatus SECU_PKCS11Init(PRBool readOnly);
+
+/* Dump contents of signed data */
+extern int SECU_PrintSignedData(FILE *out, SECItem *der, const char *m, int level,
+ SECU_PPFunc inner);
+
+extern int SECU_PrintCrl(FILE *out, SECItem *der, const char *m, int level);
+
+extern void
+SECU_PrintCRLInfo(FILE *out, CERTCrl *crl, const char *m, int level);
+
+extern void SECU_PrintString(FILE *out, SECItem *si, const char *m, int level);
+extern void SECU_PrintAny(FILE *out, SECItem *i, const char *m, int level);
+
+extern void SECU_PrintPolicy(FILE *out, SECItem *value, const char *msg, int level);
+extern void SECU_PrintPrivKeyUsagePeriodExtension(FILE *out, SECItem *value,
+ const char *msg, int level);
+
+extern void SECU_PrintExtensions(FILE *out, CERTCertExtension **extensions,
+ const char *msg, int level);
+
+extern void SECU_PrintName(FILE *out, CERTName *name, const char *msg, int level);
+
+#ifdef SECU_GetPassword
+/* Convert a High public Key to a Low public Key */
+extern SECKEYLowPublicKey *SECU_ConvHighToLow(SECKEYPublicKey *pubHighKey);
+#endif
+
+extern char *SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg);
+
+extern SECStatus DER_PrettyPrint(FILE *out, SECItem *it, PRBool raw);
+extern void SEC_Init(void);
+
+extern char *SECU_SECModDBName(void);
+
+extern void SECU_PrintPRandOSError(const char *progName);
+
+extern SECStatus SECU_RegisterDynamicOids(void);
+
+/* Identifies hash algorithm tag by its string representation. */
+extern SECOidTag SECU_StringToSignatureAlgTag(const char *alg);
+
+/* Store CRL in output file or pk11 db. Also
+ * encodes with base64 and exports to file if ascii flag is set
+ * and file is not NULL. */
+extern SECStatus SECU_StoreCRL(PK11SlotInfo *slot, SECItem *derCrl,
+ PRFileDesc *outFile, int ascii, char *url);
+
+
+/*
+** DER sign a single block of data using private key encryption and the
+** MD5 hashing algorithm. This routine first computes a digital signature
+** using SEC_SignData, then wraps it with an CERTSignedData and then der
+** encodes the result.
+** "arena" is the memory arena to use to allocate data from
+** "sd" returned CERTSignedData
+** "result" the final der encoded data (memory is allocated)
+** "buf" the input data to sign
+** "len" the amount of data to sign
+** "pk" the private key to encrypt with
+*/
+extern SECStatus SECU_DerSignDataCRL(PRArenaPool *arena, CERTSignedData *sd,
+ unsigned char *buf, int len,
+ SECKEYPrivateKey *pk, SECOidTag algID);
+
+typedef enum {
+ noKeyFound = 1,
+ noSignatureMatch = 2,
+ failToEncode = 3,
+ failToSign = 4,
+ noMem = 5
+} SignAndEncodeFuncExitStat;
+
+extern SECStatus
+SECU_SignAndEncodeCRL(CERTCertificate *issuer, CERTSignedCrl *signCrl,
+ SECOidTag hashAlgTag, SignAndEncodeFuncExitStat *resCode);
+
+extern SECStatus
+SECU_CopyCRL(PRArenaPool *destArena, CERTCrl *destCrl, CERTCrl *srcCrl);
+
+/*
+** Finds the crl Authority Key Id extension. Returns NULL if no such extension
+** was found.
+*/
+CERTAuthKeyID *
+SECU_FindCRLAuthKeyIDExten (PRArenaPool *arena, CERTSignedCrl *crl);
+
+/*
+ * Find the issuer of a crl. Cert usage should be checked before signing a crl.
+ */
+CERTCertificate *
+SECU_FindCrlIssuer(CERTCertDBHandle *dbHandle, SECItem* subject,
+ CERTAuthKeyID* id, PRTime validTime);
+
+
+/* call back function used in encoding of an extension. Called from
+ * SECU_EncodeAndAddExtensionValue */
+typedef SECStatus (* EXTEN_EXT_VALUE_ENCODER) (PRArenaPool *extHandleArena,
+ void *value, SECItem *encodedValue);
+
+/* Encodes and adds extensions to the CRL or CRL entries. */
+SECStatus
+SECU_EncodeAndAddExtensionValue(PRArenaPool *arena, void *extHandle,
+ void *value, PRBool criticality, int extenType,
+ EXTEN_EXT_VALUE_ENCODER EncodeValueFn);
+
+
+/*
+ *
+ * Utilities for parsing security tools command lines
+ *
+ */
+
+/* A single command flag */
+typedef struct {
+ char flag;
+ PRBool needsArg;
+ char *arg;
+ PRBool activated;
+} secuCommandFlag;
+
+/* A full array of command/option flags */
+typedef struct
+{
+ int numCommands;
+ int numOptions;
+
+ secuCommandFlag *commands;
+ secuCommandFlag *options;
+} secuCommand;
+
+/* fill the "arg" and "activated" fields for each flag */
+SECStatus
+SECU_ParseCommandLine(int argc, char **argv, char *progName, secuCommand *cmd);
+char *
+SECU_GetOptionArg(secuCommand *cmd, int optionNum);
+
+/*
+ *
+ * Error messaging
+ *
+ */
+
+/* Return informative error string */
+char *SECU_ErrorString(int16 err);
+
+/* Return informative error string. Does not call XP_GetString */
+char *SECU_ErrorStringRaw(int16 err);
+
+void printflags(char *trusts, unsigned int flags);
+
+#ifndef XP_UNIX
+extern int ffs(unsigned int i);
+#endif
+
+#include "secerr.h"
+#include "sslerr.h"
+
+#endif /* _SEC_UTIL_H_ */
diff --git a/base/native-tools/src/revoker/CMakeLists.txt b/base/native-tools/src/revoker/CMakeLists.txt
new file mode 100644
index 000000000..5aa5ddff3
--- /dev/null
+++ b/base/native-tools/src/revoker/CMakeLists.txt
@@ -0,0 +1,30 @@
+project(revoker C)
+
+set(REVOKER_PRIVATE_INCLUDE_DIRS
+ ${CMAKE_BINARY_DIR}
+ ${NSPR_INCLUDE_DIRS}
+ ${NSS_INCLUDE_DIRS}
+)
+
+set(REVOKER_LINK_LIBRARIES
+ ${NSPR_LIBRARIES}
+ ${NSS_LIBRARIES}
+)
+
+set(revoker_SRCS
+ revoker.c
+ getopt.c
+)
+
+include_directories(${REVOKER_PRIVATE_INCLUDE_DIRS})
+
+add_executable(revoker ${revoker_SRCS})
+
+target_link_libraries(revoker ${REVOKER_LINK_LIBRARIES})
+
+install(
+ TARGETS revoker
+ RUNTIME DESTINATION ${BIN_INSTALL_DIR}
+ LIBRARY DESTINATION ${LIB_INSTALL_DIR}
+ ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
+)
diff --git a/base/native-tools/src/revoker/getopt.c b/base/native-tools/src/revoker/getopt.c
new file mode 100644
index 000000000..7554e1a14
--- /dev/null
+++ b/base/native-tools/src/revoker/getopt.c
@@ -0,0 +1,126 @@
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ *
+ * END COPYRIGHT BLOCK **/
+#ifdef XP_PC
+
+/*
+** This comes from the AT&T public-domain getopt published in mod.sources
+** (i.e., comp.sources.unix before the great Usenet renaming).
+*/
+
+#include <stdio.h>
+#include <string.h> /* for str*() */
+#include <io.h> /* for write() */
+
+int opterr = 1; /* boolean flag, says "report error on stderr." */
+int optind = 1; /* index to element of argv from which options are
+ ** being parsed. */
+int optopt = 0; /* option character */
+char *optarg; /* ptr to option's parameter arg. */
+
+#ifdef _WIN32
+static void
+do_opterr(const char *s, int c, char * const av[])
+{
+ if (opterr) {
+ char buff[2];
+ int fd = _fileno(stderr);
+
+ buff[0] = (char)c;
+ buff[1] = '\n';
+ (void)write(fd, av[0], strlen(av[0]));
+ (void)write(fd, s, strlen(s));
+ (void)write(fd, buff, 2);
+ }
+}
+#define ERR(s, c) do_opterr(s, c, av)
+#else
+#define ERR(s, c) /* Win16 doesn't do stderr */
+#endif
+
+/*
+** Return options and their values from the command line.
+*/
+int
+getopt(int ac, char * const av[], const char * opts)
+{
+ static int i = 1; /* offset of current option char in current arg. */
+ char *p; /* opt char in opts that matched. */
+
+ /* Move to next value from argv? */
+ if (i == 1) {
+ if (optind >= ac || av[optind][0] != '-' || av[optind][1] == '\0')
+ return EOF;
+ if (strcmp(av[optind], "--") == 0) {
+ optind++;
+ return EOF;
+ }
+ }
+
+ /* Get next option character. */
+ if ((optopt = av[optind][i]) == ':' ||
+ (p = strchr(opts, optopt)) == NULL) {
+ ERR(": illegal option -- ", optopt);
+ if (av[optind][++i] == '\0') {
+ optind++;
+ i = 1;
+ }
+ return '?';
+ }
+
+ /* Snarf argument? */
+ if (*++p == ':') {
+ if (av[optind][i + 1] != '\0')
+ optarg = &av[optind++][i + 1];
+ else {
+ if (++optind >= ac) {
+ ERR(": option requires an argument -- ", optopt);
+ i = 1;
+ return '?';
+ }
+ optarg = av[optind++];
+ }
+ i = 1;
+ } else {
+ if (av[optind][++i] == '\0') {
+ i = 1;
+ optind++;
+ }
+ optarg = NULL;
+ }
+
+ return optopt;
+}
+
+#endif /* XP_PC */
diff --git a/base/native-tools/src/revoker/revoker.c b/base/native-tools/src/revoker/revoker.c
new file mode 100644
index 000000000..c7fc76294
--- /dev/null
+++ b/base/native-tools/src/revoker/revoker.c
@@ -0,0 +1,882 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 ---
+ */
+
+/* vi: set ts=4 sw=4 : */
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#if defined(XP_UNIX)
+#include <unistd.h>
+#endif
+
+#include "ssl.h"
+
+#include "prerror.h"
+
+#include "pk11func.h"
+#include "secitem.h"
+
+
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+
+#include "nspr.h"
+#include "prio.h"
+#include "prnetdb.h"
+#include "nss.h"
+
+
+/* set Tabs to 8 */
+
+
+/*from nss2.8.4 secopt.h*/
+#ifdef XP_PC
+
+/*
+** This comes from the AT&T public-domain getopt published in mod.sources
+** (i.e., comp.sources.unix before the great Usenet renaming).
+*/
+
+extern int opterr;
+extern int optind;
+extern int optopt;
+extern char *optarg;
+
+#ifdef _WIN32
+static void do_opterr(const char *s, int c, char * const av[]);
+#define ERR(s, c) do_opterr(s, c, av)
+#else
+#define ERR(s, c) /* Win16 doesn't do stderr */
+#endif
+
+/*
+** Return options and their values from the command line.
+*/
+int getopt(int ac, char * const av[], const char * opts);
+#else
+#if defined(LINUX)
+#include <getopt.h>
+#endif
+#endif /* XP_PC */
+/*end secopt.h*/
+
+#define VERSIONSTRING "$Revision$ ($Date$)"
+
+#ifndef PORT_Sprintf
+#define PORT_Sprintf sprintf
+#endif
+
+#ifndef PORT_Strstr
+#define PORT_Strstr strstr
+#endif
+
+#ifndef PORT_Malloc
+#define PORT_Malloc PR_Malloc
+#endif
+
+#define RD_BUF_SIZE (60 * 1024)
+
+#define PRINTF if (verbose) printf
+#define FPRINTF if (verbose) fprintf
+#define FPUTS if (verbose) fputs
+
+#define MAX_SERIAL_LEN 8192
+
+int MakeCertOK=1;
+
+int verbose;
+SECItem bigBuf;
+
+
+char * ownPasswd( PK11SlotInfo *slot, PRBool retry, void *arg)
+{
+ char *passwd = NULL;
+
+ if ( (!retry) && arg ) {
+ passwd = PL_strdup((char *)arg);
+ }
+
+ return passwd;
+}
+
+static void
+Usage(const char *progName)
+{
+ fprintf(stderr,
+ "Usage: %s -s serialNum -n rsa_nickname [-p password | -w pwfile ] [-d dbdir] \n"
+ " [-v] [-V] [-u] [-r reasoncode] [-i numberOfHours] hostname[:port]\n"
+ " serialNum: List of serial numbers to revoke, in hex, e.g. '0x31' or '0x44,0x643,0x22'\n"
+ " reasoncode: integer from 0 to 6, as follows\n"
+ " 0 = Unspecified (default)\n"
+ " 1 = Key compromised\n"
+ " 2 = CA key compromised\n"
+ " 3 = Affiliation changed\n"
+ " 4 = Certificate superseded\n"
+ " 5 = Cessation of operation\n"
+ " 6 = Certificate is on hold\n"
+ " -u : unrevoke (take off hold)\n"
+ " -v : verbose\n"
+ " -V : report version information\n",
+ progName);
+ exit(1);
+}
+
+
+static void
+errWarn(char * funcString)
+{
+ PRErrorCode perr = PR_GetError();
+
+ FPRINTF(stderr, "exit after %s with error %d:\n", funcString,perr );
+}
+
+static void
+errExit(char * funcString)
+{
+ errWarn(funcString);
+ exit(1);
+}
+
+/* This invokes the "default" AuthCert handler in libssl.
+** The only reason to use this one is that it prints out info as it goes.
+*/
+static SECStatus
+mySSLAuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig,
+ PRBool isServer)
+{
+ SECStatus rv;
+ CERTCertificate * peerCert;
+
+ peerCert = SSL_PeerCertificate(fd);
+
+ PRINTF("Subject: %s\nIssuer : %s\n",
+ peerCert->subjectName, peerCert->issuerName);
+ /* invoke the "default" AuthCert handler. */
+ rv = SSL_AuthCertificate(arg, fd, checkSig, isServer);
+
+ if (rv == SECSuccess) {
+ FPUTS("-- SSL3: Server Certificate Validated.\n", stderr);
+ }
+ /* error, if any, will be displayed by the Bad Cert Handler. */
+ return rv;
+}
+
+static SECStatus
+myBadCertHandler( void *arg, PRFileDesc *fd)
+{
+ /* int err = PR_GetError(); */
+ /* fprintf(stderr, "-- SSL: Server Certificate Invalid, err %d.\n%s\n",
+ err, SECU_Strerror(err)); */
+ return (MakeCertOK ? SECSuccess : SECFailure);
+}
+
+
+SECStatus
+my_GetClientAuthData(void * arg,
+ PRFileDesc * socket,
+ struct CERTDistNamesStr * caNames,
+ struct CERTCertificateStr ** pRetCert,
+ struct SECKEYPrivateKeyStr **pRetKey)
+{
+ CERTCertificate * cert = NULL;
+ SECKEYPrivateKey * privkey = NULL;
+ char * chosenNickName = (char *)arg; /* CONST */
+ void * proto_win = NULL;
+ SECStatus rv = SECFailure;
+
+ FPRINTF(stderr,"Called mygetclientauthdata - nickname = %s\n",chosenNickName);
+
+ proto_win = SSL_RevealPinArg(socket);
+
+ if (chosenNickName) {
+ cert = PK11_FindCertFromNickname(chosenNickName, proto_win);
+ FPRINTF(stderr," mygetclientauthdata - cert = %x\n",(unsigned int)cert);
+ if ( cert ) {
+ privkey = PK11_FindKeyByAnyCert(cert, proto_win);
+ FPRINTF(stderr," mygetclientauthdata - privkey = %x\n",(unsigned int)privkey);
+ if ( privkey ) {
+ rv = SECSuccess;
+ } else {
+ CERT_DestroyCertificate(cert);
+ }
+ }
+ } else { /* no name given, automatically find the right cert. */
+ CERTCertNicknames * names;
+ int i;
+
+ names = CERT_GetCertNicknames(CERT_GetDefaultCertDB(),
+ SEC_CERT_NICKNAMES_USER, proto_win);
+ if (names != NULL) {
+ for (i = 0; i < names->numnicknames; i++) {
+ cert = PK11_FindCertFromNickname(names->nicknames[i],proto_win);
+ if ( !cert )
+ continue;
+ /* Only check unexpired certs */
+ if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_TRUE) !=
+ secCertTimeValid ) {
+ CERT_DestroyCertificate(cert);
+ continue;
+ }
+ rv = NSS_CmpCertChainWCANames(cert, caNames);
+ if ( rv == SECSuccess ) {
+ privkey = PK11_FindKeyByAnyCert(cert, proto_win);
+ if ( privkey )
+ break;
+ }
+ rv = SECFailure;
+ CERT_DestroyCertificate(cert);
+ }
+ CERT_FreeNicknames(names);
+ }
+ }
+ if (rv == SECSuccess) {
+ *pRetCert = cert;
+ *pRetKey = privkey;
+ }
+ return rv;
+}
+
+
+
+
+void
+printSecurityInfo(PRFileDesc *fd)
+{
+ char * cp; /* bulk cipher name */
+ char * ip; /* cert issuer DN */
+ char * sp; /* cert subject DN */
+ int op; /* High, Low, Off */
+ int kp0; /* total key bits */
+ int kp1; /* secret key bits */
+ int result;
+
+ static int only_once;
+
+ if (! only_once++ && fd) {
+ result = SSL_SecurityStatus(fd, &op, &cp, &kp0, &kp1, &ip, &sp);
+ if (result != SECSuccess)
+ return;
+#if 0
+ PRINTF("bulk cipher %s, %d secret key bits, %d key bits, status: %d\n"
+ "subject DN: %s\n"
+ "issuer DN: %s\n", cp, kp1, kp0, op, sp, ip);
+#else
+ PRINTF("bulk cipher %s, %d secret key bits, %d key bits, status: %d\n",
+ cp, kp1, kp0, op);
+#endif
+ PR_Free(cp);
+ PR_Free(ip);
+ PR_Free(sp);
+ }
+
+}
+
+
+PRBool useModelSocket = PR_TRUE;
+
+static const char outHeader[] = {
+ "HTTP/1.0 200 OK\r\n"
+ "Server: Netscape-Enterprise/2.0a\r\n"
+ "Date: Tue, 26 Aug 1997 22:10:05 GMT\r\n"
+ "Content-type: text/plain\r\n"
+ "\r\n"
+};
+
+
+PRInt32
+do_writes(
+ void * a
+)
+{
+ PRFileDesc * ssl_sock = (PRFileDesc *)a;
+ PRUint32 sent = 0;
+ PRInt32 count = 0;
+
+ while (sent < bigBuf.len) {
+
+ count = PR_Write(ssl_sock, bigBuf.data + sent, bigBuf.len - sent);
+ if (count < 0) {
+ errWarn("PR_Write bigBuf");
+ exit(4);
+ break;
+ }
+ FPRINTF(stderr, "PR_Write wrote %d bytes from bigBuf\n", count );
+ FPRINTF(stderr, "bytes: [%*s]\n",count,bigBuf.data);
+
+ sent += (PRUint32)count;
+ }
+ if (count >= 0) { /* last write didn't fail. */
+ FPRINTF(stderr, "do_writes shutting down send socket\n");
+ /* PR_Shutdown(ssl_sock, PR_SHUTDOWN_SEND); */
+ }
+
+ FPRINTF(stderr, "do_writes exiting with (failure = %d)\n",sent<bigBuf.len == SECFailure);
+ return (sent < bigBuf.len) ? SECFailure : SECSuccess;
+}
+
+
+
+
+SECStatus
+do_io( PRFileDesc *ssl_sock, int connection)
+{
+ int countRead = 0;
+ PRInt32 rv;
+ char *buf;
+ int first=1;
+
+ buf = PR_Malloc(RD_BUF_SIZE);
+ if (!buf) exit(5);
+
+
+ /* send the http request here. */
+
+ rv = do_writes(ssl_sock);
+
+ if (rv == SECFailure) {
+ errWarn("returning from after calling do_writes");
+ PR_Free(buf);
+ buf = 0;
+ exit(6);
+ }
+ printSecurityInfo(ssl_sock);
+
+ /* read until EOF */
+ while (1) {
+ rv = PR_Read(ssl_sock, buf, RD_BUF_SIZE);
+ if (rv == 0) {
+ break; /* EOF */
+ }
+ if (rv < 0) {
+ errWarn("PR_Read");
+ exit(1);
+ }
+
+ countRead += rv;
+ FPRINTF(stderr, "connection %d read %d bytes (%d total).\n",
+ connection, rv, countRead );
+ FPRINTF(stderr, "these bytes read:\n");
+ if (verbose) {
+ PR_Write(PR_STDERR,buf,rv);
+ PR_fprintf(PR_STDERR, "\n");
+ }
+
+ if (first) {
+ first=0;
+ if (rv < 13) {
+ errWarn("not enough bytes read in first read");
+ exit(2);
+ } else {
+ if ( ! PL_strnstr(buf,"200",13)) {
+ exit(3);
+ }
+ }
+ }
+ }
+ PR_Free(buf);
+ buf = 0;
+
+ /* Caller closes the socket. */
+
+ FPRINTF(stderr,
+ "connection %d read %d bytes total. -----------------------------\n",
+ connection, countRead);
+
+ return SECSuccess; /* success */
+}
+
+int
+do_connect(
+ PRNetAddr *addr,
+ PRFileDesc *model_sock,
+ int connection)
+{
+ PRFileDesc * ssl_sock;
+ PRFileDesc * tcp_sock;
+ PRStatus prStatus;
+ SECStatus result;
+ int rv = SECSuccess;
+ PRSocketOptionData opt;
+
+ int family = PR_NetAddrFamily( addr );
+
+ tcp_sock = PR_OpenTCPSocket( family );
+ if (tcp_sock == NULL) {
+ errExit("PR_OpenTCPSocket on tcp socket");
+ }
+
+ opt.option = PR_SockOpt_Nonblocking;
+ opt.value.non_blocking = PR_FALSE;
+ prStatus = PR_SetSocketOption(tcp_sock, &opt);
+ if (prStatus != PR_SUCCESS) {
+ if( tcp_sock != NULL ) {
+ PR_Close(tcp_sock);
+ tcp_sock = NULL;
+ }
+ /* Don't return SECFailure? */
+ return SECSuccess;
+ }
+
+ prStatus = PR_Connect(tcp_sock, addr, PR_SecondsToInterval(3));
+ if (prStatus != PR_SUCCESS) {
+ errWarn("PR_Connect");
+ if( tcp_sock != NULL ) {
+ PR_Close(tcp_sock);
+ tcp_sock = NULL;
+ }
+ exit(6);
+ }
+
+ ssl_sock = SSL_ImportFD(model_sock, tcp_sock);
+ /* XXX if this import fails, close tcp_sock and return. */
+ if (!ssl_sock) {
+ if( tcp_sock != NULL ) {
+ PR_Close(tcp_sock);
+ tcp_sock = NULL;
+ }
+ exit(7);
+ }
+
+ rv = SSL_ResetHandshake(ssl_sock, /* asServer */ 0);
+ if (rv != SECSuccess) {
+ errWarn("SSL_ResetHandshake");
+ exit(8);
+ }
+
+ result = do_io( ssl_sock, connection);
+
+ if( ssl_sock != NULL ) {
+ PR_Close(ssl_sock);
+ ssl_sock = NULL;
+ }
+ return SECSuccess;
+}
+
+/* Returns IP address for hostname as PRUint32 in Host Byte Order.
+** Since the value returned is an integer (not a string of bytes),
+** it is inherently in Host Byte Order.
+*/
+PRUint32
+getIPAddress(const char * hostName)
+{
+ const unsigned char *p;
+ PRStatus prStatus;
+ PRUint32 rv;
+ PRHostEnt prHostEnt;
+ char scratch[PR_NETDB_BUF_SIZE];
+
+ prStatus = PR_GetHostByName(hostName, scratch, sizeof scratch, &prHostEnt);
+ if (prStatus != PR_SUCCESS)
+ errExit("PR_GetHostByName");
+
+#undef h_addr
+#define h_addr h_addr_list[0] /* address, for backward compatibility */
+
+ p = (const unsigned char *)(prHostEnt.h_addr); /* in Network Byte order */
+ FPRINTF(stderr, "%s -> %d.%d.%d.%d\n", hostName, p[0], p[1], p[2], p[3]);
+ rv = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+ return rv;
+}
+
+void
+client_main(
+ unsigned short port,
+ int connections,
+ SECKEYPrivateKey ** privKey,
+ CERTCertificate ** cert,
+ const char * hostName,
+ char * nickName)
+{
+ PRFileDesc *model_sock = NULL;
+ int rv;
+
+
+ FPRINTF(stderr, "port: %d\n", port);
+
+ /* all suites except RSA_NULL_MD5 are enabled by Domestic Policy */
+ NSS_SetDomesticPolicy();
+
+ /* all the SSL2 and SSL3 cipher suites are enabled by default. */
+ /* SSL_CipherPrefSetDefault(0xC005 */
+ /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA */
+ /*, PR_TRUE); */
+
+ /*
+ * Rifle through the values for the host
+ */
+
+ PRAddrInfo *ai;
+ void *iter;
+ PRNetAddr addr;
+ int family = PR_AF_INET;
+
+ ai = PR_GetAddrInfoByName(hostName, PR_AF_UNSPEC, PR_AI_ADDRCONFIG);
+ if (ai) {
+ FPRINTF( stderr, "addr='%s'\n", PR_GetCanonNameFromAddrInfo( ai ) );
+ iter = NULL;
+ while ((iter = PR_EnumerateAddrInfo(iter, ai, 0, &addr)) != NULL) {
+ family = PR_NetAddrFamily(&addr);
+ FPRINTF( stderr, "family='%d'\n", family );
+ break;
+ }
+ PR_FreeAddrInfo(ai);
+ }
+
+ PR_SetNetAddr( PR_IpAddrNull, family, port, &addr );
+
+ model_sock = PR_OpenTCPSocket( family );
+ if (model_sock == NULL) {
+ errExit("PR_OpenTCPSocket on tcp socket");
+ }
+
+ /* Should we really be re-using the same socket? */
+ model_sock = SSL_ImportFD(NULL, model_sock);
+
+
+ /* check on success of call to SSL_ImportFD() */
+ if (model_sock == NULL) {
+ errExit("SSL_ImportFD");
+ }
+
+ /* enable ECC cipher also */
+
+ /* do SSL configuration. */
+
+ rv = SSL_OptionSet(model_sock, SSL_SECURITY, 1);
+ if (rv < 0) {
+ if( model_sock != NULL ) {
+ PR_Close( model_sock );
+ model_sock = NULL;
+ }
+ errExit("SSL_OptionSet SSL_SECURITY");
+ }
+
+ SSL_SetURL(model_sock, hostName);
+
+ SSL_AuthCertificateHook(model_sock, mySSLAuthCertificate,
+ (void *)CERT_GetDefaultCertDB());
+
+ SSL_BadCertHook(model_sock, myBadCertHandler, NULL);
+
+ SSL_GetClientAuthDataHook(model_sock,
+ (SSLGetClientAuthData)my_GetClientAuthData,
+ nickName);
+
+ /* I'm not going to set the HandshakeCallback function. */
+
+ /* end of ssl configuration. */
+
+ rv = do_connect(&addr, model_sock, 1);
+
+ if( model_sock != NULL ) {
+ PR_Close( model_sock );
+ model_sock = NULL;
+ }
+}
+
+
+SECStatus
+createRequest(char * serials, char *reason, char *invalidity, int take_off_hold)
+{
+ int tmpI;
+ char *s;
+ char **strs=NULL;
+ char *filter = NULL;
+ int count = 0;
+ int range = 0;
+ int i;
+ char *old;
+ char * newstr;
+ char * iDate;
+ time_t ltime;
+ time_t itime;
+ long l;
+
+ tmpI = strlen(serials);
+ if (tmpI >= MAX_SERIAL_LEN) {
+ fputs("Serial number length invalid.\n", stderr);
+ exit(1);
+ }
+
+ strs = PR_Malloc((sizeof (char*)) * strlen(serials));
+ if (strs == NULL) exit(1);
+
+ /* example serials:
+ 23-25
+ 0x34523
+ 0x1010,0x10101
+ 0x94,0x2202,0x10101,0202
+ */
+
+ s = serials;
+ s = strchr(serials,'-');
+ if (s != NULL) {
+ strs[count++] = serials;
+ *s = '\0';
+ s++;
+ strs[count++] = s;
+ range = 1;
+ } else {
+ s = serials;
+ while (1) {
+ strs[count++] = s;
+ s = strchr(s,',');
+ if (s == NULL) {break;}
+ *s = '\0';
+ s++;
+ }
+ }
+
+ if (range == 0) {
+ old = "";
+ for (i=0; i<count; i++) {
+ filter = PR_smprintf("%s(certRecordId%%3D%s)",old,strs[i]);
+ if (i>0) PR_smprintf_free(old);
+ old = filter;
+ }
+ } else {
+ filter = PR_smprintf("(%%26(certRecordId>%%3D%s)(certRecordId<%%3D%s))",strs[0],strs[1]);
+ }
+
+ iDate = "";
+ if (invalidity != NULL) {
+ time( &ltime );
+ l = atol(invalidity);
+ l *= 3600;
+ itime = (time_t)l;
+ ltime -= itime;
+ iDate = PR_smprintf("invalidityDate=%ld000&", ltime);
+ }
+
+ if (take_off_hold > 0) {
+ newstr = PR_smprintf(
+ "GET /ca/doUnrevoke?serialNumber=%s HTTP/1.0\r\n\r\n",
+ strs[0]);
+ } else {
+ newstr = PR_smprintf(
+ "GET /ca/doRevoke?op=doRevoke&"
+ "revocationReason=%s&%s"
+ "revokeAll=(|%s)&totalRecordCount=1 HTTP/1.0\r\n\r\n",
+ reason,iDate,
+ filter);
+ }
+
+ if (strlen(iDate) > 0) PR_smprintf_free(iDate);
+ if (filter != NULL) PR_smprintf_free(filter);
+ if (strs != NULL) PR_Free(strs);
+
+ bigBuf.data = (unsigned char *)newstr;
+
+ FPUTS((char *)bigBuf.data, stderr);
+
+ bigBuf.len = PORT_Strlen((char *)bigBuf.data);
+
+ return SECSuccess;
+}
+
+int
+main(int argc, char **argv)
+{
+ char * dir = ".";
+ char * hostName = NULL;
+ char * nickName = NULL;
+ char * progName = NULL;
+ char * serial = NULL;
+ char * tmp = NULL;
+ CERTCertificate * cert [kt_kea_size] = { NULL };
+ SECKEYPrivateKey * privKey[kt_kea_size] = { NULL };
+ int optchar;
+ int connections = 1;
+ int tmpI;
+ unsigned short port = 443;
+ SECStatus rv;
+ char * passwd = NULL;
+ char * passwdfile = NULL;
+ char * revocation_reason = NULL;
+ char * invalidity_date = NULL;
+ int take_off_hold = 0;
+ FILE *fp;
+ char pwbuf[256];
+ int co;
+ char *crlf;
+
+ /* Call the NSPR initialization routines */
+ PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
+
+ tmp = strrchr(argv[0], '/');
+ tmp = tmp ? tmp + 1 : argv[0];
+ progName = strrchr(tmp, '\\');
+ progName = progName ? progName + 1 : tmp;
+
+
+ while ((optchar = getopt(argc, argv, "Vd:n:p:s:r:i:w:uv")) != -1) {
+ switch(optchar) {
+
+/* Version */
+ case 'V':
+ printf("%s\n",VERSIONSTRING);
+ PR_Cleanup();
+ return 0;
+
+/* Directory which holds cert8.db and key3.db */
+ case 'd':
+ dir = optarg;
+ break;
+
+/* Nickname of certificate to use */
+ case 'n':
+ nickName = optarg;
+ break;
+
+/* password to open key3.db */
+ case 'p':
+ passwd = optarg;
+ break;
+
+/* name of file holding password for key3.db */
+ case 'w':
+ passwdfile = optarg;
+ break;
+
+/* revocation reason */
+ case 'r':
+ revocation_reason = optarg;
+ break;
+
+/* invalidity date */
+ case 'i':
+ invalidity_date = optarg;
+ break;
+
+/* unrevoke - take off hold */
+ case 'u':
+ take_off_hold++;
+ break;
+
+/* serial number */
+ case 's':
+ serial = optarg;
+ break;
+
+ case 'v':
+ verbose++;
+ break;
+
+ default:
+ case '?':
+ fprintf( stderr, "ERROR: Invalid option!\n" );
+ Usage(progName);
+ break;
+
+ }
+ }
+
+ if (optind != argc - 1) {
+ fprintf( stderr, "ERROR: Invalid number of arguments!\n" );
+ Usage(progName);
+ }
+
+ hostName = argv[optind];
+ tmp = strchr(hostName, ':');
+ if (tmp) {
+ *tmp++ = 0;
+ tmpI = atoi(tmp);
+ if (tmpI <= 0) {
+ fprintf( stderr, "ERROR: Invalid port!\n" );
+ Usage(progName);
+ }
+ port = (unsigned short)tmpI;
+ }
+
+ if (revocation_reason == NULL) {
+ revocation_reason = "0";
+ }
+
+ if (!nickName || !serial) {
+ fprintf( stderr, "ERROR: Invalid nickname or serial number!\n" );
+ Usage(progName);
+ }
+
+ createRequest(serial,revocation_reason,invalidity_date,take_off_hold);
+
+ if (passwdfile) {
+ fp = fopen(passwdfile,"r");
+ if (!fp) { fprintf(stderr, "Couldn't open password file\n"); exit(7); }
+ co = fread(pwbuf,1,256,fp);
+ pwbuf[co] = '\0';
+ crlf = PL_strchr(pwbuf,'\n');
+ if (crlf) {
+ *crlf = '\0';
+ }
+ passwd = pwbuf;
+ }
+
+ /* set our password function */
+ if (passwd == NULL) {
+ fprintf( stderr, "ERROR: Invalid password!\n" );
+ PRINTF("Password must be provided on command line in this version of revoker.\n");
+ Usage(progName);
+ }
+ PK11_SetPasswordFunc(ownPasswd);
+
+ /* Call the libsec initialization routines */
+ rv = NSS_Init(dir);
+ if (rv != SECSuccess) {
+ fputs("NSS_Init failed.\n", stderr);
+ exit(1);
+ }
+
+ cert[kt_rsa] = PK11_FindCertFromNickname(nickName, passwd);
+ if (cert[kt_rsa] == NULL) {
+ fprintf(stderr, "Can't find certificate %s\n", nickName);
+ exit(1);
+ }
+
+ privKey[kt_rsa] = PK11_FindKeyByAnyCert(cert[kt_rsa], passwd);
+ if (privKey[kt_rsa] == NULL) {
+ fprintf(stderr, "Can't find Private Key for cert %s (possibly incorrect password)\n", nickName);
+ exit(1);
+ }
+
+
+ client_main(port, connections, privKey, cert, hostName, nickName);
+
+ NSS_Shutdown();
+ PR_Cleanup();
+ return 0;
+}
+
diff --git a/base/native-tools/src/setpin/CMakeLists.txt b/base/native-tools/src/setpin/CMakeLists.txt
new file mode 100644
index 000000000..b32e12b22
--- /dev/null
+++ b/base/native-tools/src/setpin/CMakeLists.txt
@@ -0,0 +1,43 @@
+project(setpin C)
+
+find_package(Ldap REQUIRED)
+
+set(SETPIN_PRIVATE_INCLUDE_DIRS
+ ${CMAKE_BINARY_DIR}
+ ${NSPR_INCLUDE_DIRS}
+ ${NSS_INCLUDE_DIRS}
+ ${LDAP_INCLUDE_DIRS}
+)
+
+set(SETPIN_LINK_LIBRARIES
+ ${NSPR_LIBRARIES}
+ ${NSS_LIBRARIES}
+ ${LDAP_LIBRARIES}
+)
+
+set(setpin_SRCS
+ b64.c
+ options.c
+ setpin.c
+ setpin_options.c
+)
+
+include_directories(${SETPIN_PRIVATE_INCLUDE_DIRS})
+
+add_executable(setpin ${setpin_SRCS})
+
+target_link_libraries(setpin ${SETPIN_LINK_LIBRARIES})
+
+install(
+ TARGETS setpin
+ RUNTIME DESTINATION ${BIN_INSTALL_DIR}
+ LIBRARY DESTINATION ${LIB_INSTALL_DIR}
+ ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
+)
+
+install(
+ FILES
+ setpin.conf
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/pki/native-tools/
+)
diff --git a/base/native-tools/src/setpin/b64.c b/base/native-tools/src/setpin/b64.c
new file mode 100644
index 000000000..1c20f3792
--- /dev/null
+++ b/base/native-tools/src/setpin/b64.c
@@ -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.
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+
+
+
+
+
+
+static char nib2b64[0x40f] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+
+
+static int
+ldif_base64_encode_internal( unsigned char *src, char *dst, int srclen, int lenused, int wraplen )
+{
+ unsigned char *byte, *stop;
+ unsigned char buf[3];
+ char *out;
+ unsigned long bits;
+ int i, pad, len;
+
+ len = 0;
+ out = dst;
+ stop = src + srclen;
+
+ /* convert to base 64 (3 bytes => 4 base 64 digits) */
+ for ( byte = src; byte < stop - 2; byte += 3 ) {
+ bits = (byte[0] & 0xff) << 16;
+ bits |= (byte[1] & 0xff) << 8;
+ bits |= (byte[2] & 0xff);
+
+ for ( i = 0; i < 4; i++, bits <<= 6 ) {
+ if ( wraplen != -1 && lenused >= 0 && lenused++ > wraplen ) {
+ *out++ = '\n';
+ *out++ = ' ';
+ lenused = 2;
+ }
+
+ /* get b64 digit from high order 6 bits */
+ *out++ = nib2b64[ (bits & 0xfc0000L) >> 18 ];
+ }
+ }
+ /* add padding if necessary */
+ if ( byte < stop ) {
+ for ( i = 0; byte + i < stop; i++ ) {
+ buf[i] = byte[i];
+ }
+ for ( pad = 0; i < 3; i++, pad++ ) {
+ buf[i] = '\0';
+ }
+ byte = buf;
+ bits = (byte[0] & 0xff) << 16;
+ bits |= (byte[1] & 0xff) << 8;
+ bits |= (byte[2] & 0xff);
+
+ for ( i = 0; i < 4; i++, bits <<= 6 ) {
+ if ( wraplen != -1 && lenused >= 0 && lenused++ > wraplen ) {
+ *out++ = '\n';
+ *out++ = ' ';
+ lenused = 2;
+ }
+
+ if (( i == 3 && pad > 0 ) || ( i == 2 && pad == 2 )) {
+ /* Pad as appropriate */
+ *out++ = '=';
+ } else {
+ /* get b64 digit from low order 6 bits */
+ *out++ = nib2b64[ (bits & 0xfc0000L) >> 18 ];
+ }
+ }
+ }
+
+ *out = '\0';
+
+ return( out - dst );
+}
+
+
+int
+ldif_base64_encode( unsigned char *src, char *dst, int srclen, int lenused )
+{
+ return ldif_base64_encode_internal( src, dst, srclen, lenused, 200);
+}
+
diff --git a/base/native-tools/src/setpin/options.c b/base/native-tools/src/setpin/options.c
new file mode 100644
index 000000000..9e2dab129
--- /dev/null
+++ b/base/native-tools/src/setpin/options.c
@@ -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.
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+
+
+#include "options.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+/*
+ * (C) 1998 Netscape Communications Corporation
+ * All rights reserved
+ * Intellectual property rulez!
+ *
+ */
+
+
+
+/* this file maintains a static linked list of the
+ options it knows about
+*/
+
+static OPTION *option_list = NULL;
+static OPTION *last_option = NULL;
+
+static char* OPT_parseArgument(char *arg,char**valid);
+
+
+/* OPT_getValue(char *option, char** output)
+
+ returns 1 if the specified option exists,
+ - value is put into 'output'
+ returns 0 if the specified option doesn't exist
+ - output is unchanged
+
+*/
+
+
+int OPT_getValue(char *option, char **output) {
+ OPTION *opt = option_list;
+
+ while (opt) {
+ if (! strcmp(opt->name,option)) {
+ *output = opt->value;
+ return 1;
+ }
+ opt = opt->next;
+ }
+ return 0;
+}
+
+
+static char* OPT_parseOptFile(char *filename, char*validlist[])
+{
+ FILE *fp;
+ char buffer[1024];
+
+ if (filename == NULL || filename[0] == '\0') {
+ return ("Bad syntax for 'optfile'\n");
+ }
+ fp = fopen(filename,"r");
+ if (fp == NULL) {
+ return ("Options file could not be opened for reading\n");
+ }
+ while (fgets(buffer,1024,fp)) {
+ if (buffer[strlen(buffer)-1] == '\n') buffer[strlen(buffer)-1] = '\0';
+ if (buffer[strlen(buffer)-1] == '\r') buffer[strlen(buffer)-1] = '\0';
+
+ OPT_parseArgument(strdup(buffer),validlist);
+ }
+ fclose(fp);
+ return NULL;
+}
+
+
+
+static char *OPT_parseArgument(char *arg, char* validlist[]) {
+ char *error;
+ char *INV_ARG = "invalid argument: %s";
+ char *eq;
+
+ OPTION *new_opt;
+
+ if (!strncmp(arg,"optfile=",8)) {
+ return OPT_parseOptFile(&arg[8],validlist);
+ }
+
+ new_opt = (OPTION*)malloc(sizeof(OPTION));
+
+ new_opt->next = NULL;
+ new_opt->name = strdup(arg);
+ eq = strchr(new_opt->name,'=');
+ if (eq) {
+ *eq = 0;
+ }
+ new_opt->value = strchr(arg,'=');
+
+
+ if (new_opt->value != NULL) {
+ new_opt->value++;
+ }
+
+ if (option_list == NULL) {
+ option_list = new_opt;
+ last_option = new_opt;
+ }
+ else {
+ last_option->next = new_opt;
+ last_option= new_opt;
+ }
+ if (!validlist) {
+ return NULL;
+ }
+ else {
+ int i=0;
+ while (validlist[i]) {
+ if (! strcmp(validlist[i],new_opt->name)) {
+ return NULL;
+ }
+ i+=2;
+ }
+ }
+
+ error = (char *)malloc(strlen(INV_ARG)+strlen(new_opt->name)+5);
+ sprintf(error,INV_ARG,new_opt->name);
+
+ return error;
+}
+
+
+
+
+/* char *OPT_parseOptions(int ac, char **av)
+
+ constructs the linked list of options
+ ac: number of arguments
+ av: array of arguments
+ valid: array of valid arguments (can be null)
+
+ returns:
+ NULL if no error
+ char* with error text if error. caller is responsible for
+ freeing this memory
+
+*/
+
+char * OPT_parseOptions(int ac, char **av, char *valid[]) {
+ int i=0;
+ char *r=NULL;
+
+ assert(option_list == NULL);
+ assert(last_option == NULL);
+ assert(av != NULL);
+
+ if (ac == 1) return NULL;
+
+ for (i=0; i<ac-1; i++) {
+ r = OPT_parseArgument(av[1+i],valid);
+ if (r) return r;
+ }
+ return r;
+}
+
+
+
+
diff --git a/base/native-tools/src/setpin/options.h b/base/native-tools/src/setpin/options.h
new file mode 100644
index 000000000..80ccae478
--- /dev/null
+++ b/base/native-tools/src/setpin/options.h
@@ -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.
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+
+
+#ifndef OPT_INCLUDE_H
+#define OPT_INCLUDE_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+struct option {
+ struct option *next;
+ char *name;
+ char *value;
+};
+
+typedef struct option OPTION;
+
+/* OPT_getValue(char *option, char** output)
+
+ returns 1 if the specified option exists,
+ - value is put into 'output'
+ returns 0 if the specified option doesn't exist
+ - output is unchanged
+
+ 'value' will be everything after the '='
+ If no '=' is present in the argument, 'output' will be
+ set to null.
+ If '=' is present, but no value is given (e.g. "file="),
+ output will be a pointer to a string of zero length.
+
+*/
+
+extern int OPT_getValue(char *option, char **output);
+
+/* void OPT_parseOptions(int ac, char **av)
+
+ initializes the global store with the options supplied
+ in av (typically used for parsing arguments passed on the
+ command line. Arguments are of the form 'arg=value'.
+ valid: array of valid arguments (can be null)
+
+ returns:
+ NULL if no error
+ char* with error text if error. caller is responsible for
+ freeing this memory
+
+
+
+*/
+
+extern char * OPT_parseOptions(int ac, char **av, char**valid);
+
+#endif
diff --git a/base/native-tools/src/setpin/setpin.c b/base/native-tools/src/setpin/setpin.c
new file mode 100644
index 000000000..f1bf6a8c7
--- /dev/null
+++ b/base/native-tools/src/setpin/setpin.c
@@ -0,0 +1,1237 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 ---
+ */
+
+
+/* Set-pin tool */
+
+
+/* This will modify the specified attribute in the directory
+ You must add the pin objectclass to the schema
+ e.g in config/slapd.oc.conf
+
+ attribute pin bin
+ objectclass pinPerson
+ superior organizationalPerson
+ allows
+ pin
+*/
+
+/*
+ History:
+ version 1.2 - upgraded to NSS 3.3.1
+ */
+
+#define SETPIN_VERSION "1.2"
+
+#include "options.h"
+#include "setpin_options.h"
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <ldap.h>
+
+#define USE_NSS_RANDOM
+
+#ifdef USE_NSS_RANDOM
+/* removed #include <secrng.h> as of NSS 3.9 */
+/* removed from nss3_3_1 secrngt.h*/
+typedef struct RNGContextStr RNGContext;
+#endif
+
+#include <sechash.h>
+
+#include <plhash.h>
+#include <prerror.h>
+#include <ctype.h>
+
+#include <secoidt.h>
+#include <nss.h>
+
+extern int equals(char *s, char *t);
+extern SECStatus PK11_HashBuf(SECOidTag hashAlg,
+ unsigned char *out,
+ unsigned char *in,
+ int32 len);
+extern SECStatus PK11_GenerateRandom(unsigned char *data,
+ int len);
+
+/* use NSS's new generic hash api */
+#define USE_NSS_GEN_HASH
+
+void exitError(char *errstring);
+void exitLDAPError(char *errstring);
+void doLDAPBind();
+void doLDAPSearch(LDAPMessage **result);
+void doLDAPUnbind();
+void processSearchResults(LDAPMessage *r);
+char *newPassword();
+void initrandom();
+void testpingen();
+void do_setup();
+
+
+char *sha1_pw_enc( char *pwd );
+
+int errcode=0;
+
+LDAP *ld=NULL;
+char *programName = NULL;
+
+FILE *output;
+FILE *input;
+
+
+PLHashTable *pinHashTable=NULL;
+
+#ifdef USE_NSS_RANDOM
+RNGContext *rngc = NULL;
+#endif
+
+/* this tool should really be changed to use NSPR */
+#ifdef _WIN32
+#define strcasecmp stricmp
+#endif
+
+void exitError(char *errstring) {
+ char *errbuf;
+
+ errbuf = malloc(strlen(errstring)+strlen(programName)+10);
+
+ sprintf(errbuf,"%s error : %s\n",programName,errstring);
+ fputs(errbuf,stderr);
+ exit(errcode);
+}
+
+
+void exitLDAPError(char *errstring) {
+ char *ldaperr;
+ char *newerror;
+ int err;
+
+ ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &err);
+ ldaperr = ldap_err2string(err);
+ newerror = (char*) malloc((errstring?strlen(errstring):0) + (ldaperr?strlen(ldaperr):0) +5);
+ sprintf(newerror,"%s (%s)",errstring?errstring:"",ldaperr?ldaperr:"");
+ exitError(newerror);
+}
+
+
+/* This returns an allocated string, like strdup does, except that
+ the duplicate string begins with the first non-whitespace character */
+
+char * trim_strdup(char *s)
+{
+ while (*s == ' ' || *s == '\t') {
+ s++;
+ }
+ if (*s == '\0') return NULL;
+ return strdup(s);
+}
+
+void readInputFile() {
+ int more_to_read=1;
+ char *thedn = NULL;
+ char *thepin = NULL;
+ int linenum=0;
+
+ pinHashTable = PL_NewHashTable(256,
+ PL_HashString,
+ PL_CompareStrings,
+ PL_CompareValues,
+ NULL, /* allocOps */
+ NULL);
+ if (pinHashTable == NULL) {
+ errcode=9;
+ exitError("Couldn't create dn->pin hashtable");
+ }
+
+ if (o_input) {
+
+ do {
+ char line[4096];
+ char *n;
+ char *checkdn;
+
+ do {
+ n = fgets(line,4096,input);
+ linenum++;
+ if (! n) {
+ more_to_read = 0;
+ break;
+ }
+
+ /* replace newline with null byte */
+
+ line[strlen(line)-1] = 0;
+
+ if (! strncmp("dn:",line,3)) {
+ thedn = trim_strdup(&line[3]);
+ if (thedn == NULL) {
+ fprintf(stderr,"warning: empty line not allowed at line: %d\n",linenum);
+ }
+ }
+
+ if (! strncmp("pin:",line,4)) {
+ thepin = trim_strdup(&line[4]);
+ }
+
+ } while (strlen(line));
+
+ /* first check to see if that dn is already in the hashtable */
+
+ if (thepin == NULL) {
+ thepin = strdup("");
+ }
+
+ if (thedn && thepin) {
+
+ checkdn = (char*) PL_HashTableLookup(pinHashTable, thedn);
+ if (checkdn) {
+ char msg[256];
+ errcode = 10;
+ strcpy(msg,"Duplicate entry in input file for dn=");
+ strcat(msg,thedn);
+ exitError(msg);
+ }
+
+ PL_HashTableAdd(pinHashTable,
+ thedn,
+ thepin);
+ fprintf(stderr, "Reading dn/pin ( %s, %s )\n", thedn, thepin);
+ if (o_debug) {
+ fprintf(stderr, "Reading dn/pin ( %s, %s )\n", thedn, thepin);
+ }
+
+ } else {
+ if (o_debug) {
+ fprintf(stderr," ...ignoring\n");
+ }
+ }
+ if (thedn != NULL) {
+ free(thedn);
+ thedn = NULL;
+ }
+ if (thepin != NULL) {
+ free(thepin);
+ thepin = NULL;
+ }
+ } while (more_to_read);
+ }
+}
+
+
+int main(int ac, char **av) {
+ char *error;
+ LDAPMessage *search_results;
+
+ programName = av[0];
+ if (strlen(av[0]) == 0) {
+ strcpy(programName, "setpin");
+ }
+ else {
+ strcpy(programName, av[0]);
+ }
+
+ if (ac == 1) {
+ int i=0;
+ fprintf(stderr,"Setpin utility. Version " SETPIN_VERSION "\n"
+ "(C) 2005 Fedora Project.\n\n");
+ fprintf(stderr,"To set up directory for pin usage, modify setpin.conf, "
+ "then run:\n %s optfile=<svr_root>/bin/cert/tools/setpin.conf\n", programName);
+ fprintf(stderr,"\nUsage: %s option=value ... option=value\n\n", programName);
+
+ for (i = 0; i < valid_args_len; i += 2) {
+ if (valid_args[i]) {
+ fprintf(stderr,"%13s : %s\n",valid_args[i],valid_args[i+1]);
+ } else {
+ errcode=0;
+ fprintf(stderr,"\n");
+ exit(errcode);
+ }
+ }
+ }
+
+ error = OPT_parseOptions(ac, av, valid_args);
+ if (error) {
+ errcode=7;
+ exitError(error);
+ }
+
+ setDefaultOptions();
+
+ getOptions();
+ fprintf(stderr,"\n");
+ if (o_debug) {
+ fprintf(stderr,"about to validateOptions\n");
+ }
+
+ validateOptions();
+
+ /* Initialize random number generator */
+ initrandom();
+
+ if (o_debug) {
+ fprintf(stderr,"about to doLDAPBind\n");
+ }
+
+ if (! o_testpingen) {
+ doLDAPBind();
+ }
+
+ if (o_setup) {
+ do_setup();
+ }
+
+ if (o_output) {
+ output = fopen(o_output,"w");
+ if (!output) {
+ errcode=5;
+ exitError("Couldn't open output file");
+ }
+ } else {
+ output = stdout;
+ }
+
+ if (o_testpingen) {
+ testpingen();
+ exit(0);
+ }
+
+ if (o_input) {
+ input = fopen(o_input,"r");
+ if (!input) {
+ errcode=8;
+ exitError("Couldn't open input file");
+ }
+ }
+
+ readInputFile();
+
+ if (o_debug) {
+ fprintf(stderr,"about to doLDAPSearch\n");
+ }
+
+ doLDAPSearch(&search_results);
+
+ if (o_debug) {
+ fprintf(stderr,"about to processSearchResults\n");
+ }
+
+ processSearchResults(search_results);
+
+ if (output != stdout) {
+ fclose(output);
+ }
+
+ return 0;
+}
+
+
+
+/* This function implements the 'setup' procedure, invoked when the user
+ specified 'setup' as one of the arguments. The point is that in this
+ mode, schema modifications are performed to add these things to the
+ directory schema:
+ if (schemachange argument is specified)
+ - 'pin' attribute as specified by the 'attribute' argument (default 'pin')
+ - 'pinPerson' objectclass as specified by the 'objectclass argument (dfl: pinperson)
+ if ('pinmanager' argument specified)
+ - pin manager user, with permission to remove the pin for the basedn specified
+
+*/
+
+void do_setup() {
+ int i;
+
+ char *x_values[]={NULL,NULL,NULL};
+ char *a1_values[]={NULL,NULL};
+ char *a2_values[]={NULL,NULL};
+ char *a3_values[]={NULL,NULL};
+ char *a4_values[]={NULL,NULL};
+ LDAPMod x,a1,a2,a3,a4;
+ LDAPMod *mods[10];
+ char* password=NULL;
+ int err;
+
+ x_values[0] = malloc(1024);
+
+ doLDAPBind();
+
+ if (o_schemachange) {
+ sprintf(x_values[0],"( %s-oid NAME '%s' DESC 'User Defined Attribute' SYNTAX '1.3.6.1.4.1.1466.115.121.1.5' SINGLE-VALUE )",
+ o_attribute,
+ o_attribute);
+
+ fprintf(stderr,"Adding attribute: %s\n",x_values[0]);
+ x_values[1] = NULL;
+ x.mod_op = LDAP_MOD_ADD;
+ x.mod_type = "attributetypes";
+ x.mod_values = x_values;
+ mods[0] = &x;
+ mods[1] = NULL;
+
+ i = ldap_modify_ext_s(ld, "cn=schema", mods, NULL, NULL);
+
+ if (i != LDAP_SUCCESS) {
+ ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &err);
+ if (err != LDAP_TYPE_OR_VALUE_EXISTS) {
+ exitLDAPError("couldn't modify schema when creating pin attribute");
+ } else {
+ fprintf(stderr," .. successful\n\n");
+ }
+ }
+
+ sprintf(x_values[0],"( %s-oid NAME '%s' DESC 'User Defined ObjectClass' SUP 'top' MUST ( objectclass ) MAY ( aci $ %s )",
+ o_objectclass,o_objectclass,
+ o_attribute);
+
+ fprintf(stderr,"Adding objectclass: %s\n",x_values[0]);
+
+ x_values[1] = NULL;
+ x.mod_op = LDAP_MOD_ADD;
+ x.mod_type = "objectclasses";
+ x.mod_values = x_values;
+ mods[0] = &x;
+ mods[1] = NULL;
+
+
+ i = ldap_modify_ext_s(ld, "cn=schema", mods, NULL, NULL);
+
+ if (i != LDAP_SUCCESS) {
+ ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &err);
+ if (err != LDAP_TYPE_OR_VALUE_EXISTS) {
+ exitLDAPError("couldn't modify schema when creating objectclass");
+ } else {
+ fprintf(stderr," .. successful\n\n");
+ }
+ }
+ }
+
+ if (o_pinmanager) {
+
+ if (o_pinmanagerpwd == NULL) {
+ exitError("missing pinmanagerpwd argument");
+ }
+ if (o_basedn == NULL) {
+ exitError("missing basedn argument");
+ }
+
+ password = sha1_pw_enc( o_pinmanagerpwd );
+
+ fprintf(stderr,"Adding user: %s\n",o_pinmanager);
+
+ a1_values[0] = "pinmanager";
+ a1_values[1] = NULL;
+ a1.mod_op = 0;
+ a1.mod_type = "sn";
+ a1.mod_values = a1_values;
+
+ a2_values[0] = "pinmanager";
+ a2_values[1] = NULL;
+ a2.mod_op = 0;
+ a2.mod_type = "cn";
+ a2.mod_values = a2_values;
+
+ a3_values[0] = password;
+ a3_values[1] = NULL;
+ a3.mod_op = 0;
+ a3.mod_type = "userPassword";
+ a3.mod_values = a3_values;
+
+ a4_values[0] = "person";
+ a4_values[1] = NULL;
+ a4.mod_op = 0;
+ a4.mod_type = "objectclass";
+ a4.mod_values = a4_values;
+
+ mods[0] = &a1;
+ mods[1] = &a2;
+ mods[2] = &a3;
+ mods[3] = &a4;
+ mods[4] = NULL;
+
+
+ i = ldap_add_ext_s(ld, o_pinmanager, mods, NULL, NULL);
+
+ if (i != LDAP_SUCCESS) {
+ ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &err);
+ if (!( err == LDAP_TYPE_OR_VALUE_EXISTS || err == LDAP_ALREADY_EXISTS)) {
+ exitLDAPError("couldn't create new user");
+ } else {
+ fprintf(stderr," .. successful\n\n");
+ }
+ }
+
+
+ /* modify aci on basedn to allow pinmanager to modify pin attr */
+
+ fprintf(stderr,"modifying ACI for: %s\n",o_basedn);
+
+ sprintf(x_values[0],"(target=\"ldap:///%s\")"
+ "(targetattr=\"pin\")"
+ "(version 3.0; acl \"Pin attribute\"; "
+ "allow (all) userdn = \"ldap:///%s\"; "
+ "deny(proxy,selfwrite,compare,add,write,delete,search) "
+ "userdn = \"ldap:///self\"; ) ",
+ o_basedn,
+ o_pinmanager);
+
+ x_values[1] = malloc(1024);
+
+ sprintf(x_values[1],"(target=\"ldap:///%s\")"
+ "(targetattr=\"objectclass\")"
+ "(version 3.0; acl \"Pin Objectclass\"; "
+ "allow (all) userdn = \"ldap:///%s\"; "
+ " ) ",
+ o_basedn,
+ o_pinmanager);
+
+ x_values[2] = NULL;
+ x.mod_op = LDAP_MOD_ADD;
+ x.mod_type = "aci";
+ x.mod_values = x_values;
+
+ mods[0] = &x;
+ mods[1] = NULL;
+
+ i = ldap_modify_ext_s(ld, o_basedn, mods, NULL, NULL);
+
+ if (i != LDAP_SUCCESS) {
+ ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &err);
+ if (!( err == LDAP_TYPE_OR_VALUE_EXISTS || err == LDAP_ALREADY_EXISTS)) {
+ exitLDAPError("couldn't modify aci on basedn");
+ } else {
+ fprintf(stderr," .. successful\n\n");
+ }
+ }
+ }
+ exit(0);
+}
+
+int ldif_base64_encode(
+ unsigned char *src, char *dst, int srclen, int lenused );
+
+/* do password hashing */
+
+/*
+ * Number of bytes each hash algorithm produces
+ */
+#define SHA1_LENGTH 20
+
+
+char *
+sha1_pw_enc( char *pwd )
+{
+ unsigned char hash[ SHA1_LENGTH ];
+ char *enc;
+
+ /* SHA1 hash the user's key */
+ PK11_HashBuf(SEC_OID_SHA1,hash,pwd,strlen(pwd));
+ enc = malloc(256);
+
+ sprintf( enc, "{SHA}");
+
+ (void)ldif_base64_encode( hash, enc + 5,
+ SHA1_LENGTH, -1 );
+
+ return( enc );
+}
+
+/* check the first 8 characters to see if this is a string */
+
+int isstring(char *s) {
+ int i=0;
+
+ for (i=0;i<8;i++) {
+ if (*s == 0) return 1;
+ if (! isprint(*s)) return 0;
+ s++;
+ }
+ return 1;
+}
+
+
+void doLDAPBind() {
+ char errbuf[1024];
+ char ldapuri[1024];
+ int port=389;
+ int r;
+ int status;
+
+ if (o_port == NULL) {
+ if (o_ssl) {
+ port = 636;
+ /* fprintf(stderr,"o_ssl = %0x, o_certdb = %0x, o_nickname= %0x\n",o_ssl,o_certdb,o_nickname); */
+ } else {
+ port = 389;
+ }
+ } else {
+ port = atoi(o_port);
+ }
+
+ if (o_debug) {
+ fprintf(stderr,"# connecting to %s:%d\n",o_host,port);
+ }
+
+ if (o_ssl) {
+ printf("SSL not currently supported.\n");
+ exit(0);
+ /* ld = ldapssl_init(o_host,port,LDAPSSL_AUTH_CNCHECK); */
+ } else {
+ snprintf(ldapuri, 1024, "ldap://%s:%i", o_host, port);
+ status = ldap_initialize(&ld, ldapuri);
+ }
+
+ if ((status != LDAP_SUCCESS) || (ld == NULL)) {
+ errcode=4;
+ exitError("could not connect to directory server");
+ }
+
+ if (o_debug) {
+ fprintf(stderr,"# ldap_init completed\n");
+ }
+
+ struct berval credential;
+ credential.bv_val = o_bindpw;
+ credential.bv_len= strlen(o_bindpw);
+
+ r = ldap_sasl_bind_s(ld, o_binddn, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (r != LDAP_SUCCESS) {
+ sprintf(errbuf,"could not bind to %s:%d as %s",o_host,port,o_binddn);
+ if (strstr(o_binddn,"=") == NULL) {
+ strcat(errbuf,". Perhaps you missed the 'CN=' part of the bin DN?");
+ }
+ exitLDAPError(errbuf);
+ }
+
+ if (o_debug) {
+ fprintf(stderr,"# ldap_simple_bind_s completed\n");
+ }
+}
+
+
+void doLDAPSearch(LDAPMessage **result ) {
+ int r;
+ char errbuf[1024];
+
+ r = ldap_search_ext_s( ld, o_basedn, LDAP_SCOPE_SUBTREE,
+ o_filter, NULL, 0, NULL, NULL, NULL, 0, result );
+
+ if (r != LDAP_SUCCESS ) {
+ sprintf(errbuf,"could not complete search with that filter. Check filter and basedn");
+ exitLDAPError(errbuf);
+ }
+
+ if (o_debug) {
+ fprintf(stderr,"# ldap_search_s completed\n");
+ }
+}
+
+void doLDAPUnbind(){
+ ldap_unbind_ext_s(ld, NULL, NULL);
+}
+
+
+void processSearchResults(LDAPMessage *r) {
+ LDAPMessage *e;
+ char *dn;
+ char *a;
+ struct berval **vals;
+#ifdef USE_NSS_GEN_HASH
+ /* HASHContext *hcx;
+ HASH_HashType ht; */
+#else
+#endif
+ int i;
+ BerElement *ber;
+ char *objectclass_values[]={NULL,NULL};
+ int change=0;
+ int pin_objectclass_exists=0;
+ LDAPMod objectclass, pinattribute;
+ LDAPMod *mods[3];
+ SECStatus status = SECFailure;
+
+ char *saltval;
+ int action;
+ char *hashbuf_source = NULL;
+ char hashbuf_dest[256];
+ char errbuf[1024];
+ int pindatasize= 0;
+ char *pindata = NULL;
+ char *generatedPassword = NULL;
+ struct berval *bvals[2];
+ struct berval bval;
+
+ bvals[0] = &bval;
+ bvals[1] = NULL;
+
+ /* Check whether any results were found. */
+ i = ldap_count_entries( ld, r );
+
+ fprintf(stderr,"filter %s found %d matching results.\n", o_filter,i);
+
+ /* for each entry print out name + all attrs and values */
+ for ( e = ldap_first_entry( ld, r ); e != NULL;
+ e = ldap_next_entry( ld, e ) ) {
+
+ generatedPassword = NULL;
+
+ if ( (dn = ldap_get_dn( ld, e )) != NULL ) {
+ fprintf(stderr, "Processing: %s\n", dn );
+ if (o_input) {
+ generatedPassword = (char*) PL_HashTableLookup(pinHashTable,dn);
+ if (generatedPassword) {
+ fprintf(stderr, " found user from input file\n");
+ }
+ if (! generatedPassword) {
+ fprintf(stderr, " Skipping (not in input file)\n");
+ continue;
+ }
+ }
+ }
+
+
+ /* what we do here is go through all the entries looking for
+ 'objectclass'.
+ */
+
+ pin_objectclass_exists = 0;
+ change = 0;
+
+#define ACTION_NONE 0
+#define ACTION_REPLACE 1
+#define ACTION_ADD 2
+
+ action = ACTION_ADD;
+
+ saltval = NULL;
+ /* loop through the entries */
+ for ( a = ldap_first_attribute( ld, e, &ber );
+ a != NULL; a = ldap_next_attribute( ld, e, ber ) ) {
+
+ if ((vals = ldap_get_values_len( ld, e, a)) != NULL ) {
+
+ if (o_debug && (! strcasecmp(o_debug,"attrs"))) {
+ for ( i = 0; vals[i] != NULL; i++ ) {
+ char *bin;
+ bin = "<binary>";
+ if (isstring(vals[i]->bv_val)) {
+ bin = vals[i]->bv_val;
+ }
+
+ fprintf(stderr, " %s: %s\n",a,bin);
+ }
+ }
+
+ if (o_debug) {
+ fprintf(stderr," examining attribute: %s\n",a);
+ for ( i = 0; vals[i] != NULL; i++ ) {
+ fprintf(stderr," val[%d]: %s\n",i,vals[i]->bv_val);
+ }
+ }
+
+ if (o_saltattribute != NULL) {
+ if (!strcasecmp(a,o_saltattribute)) {
+ saltval = vals[0]->bv_val;
+ if (o_debug) {
+ fprintf(stderr," setting salt value to: %s\n",saltval);
+ }
+ }
+ }
+
+ if (!strcasecmp(a,"objectclass")) {
+ /* check if we have a pin objectclass already */
+ /* Cycle through all the values for this
+ entry, looking for the one which matches the
+ objectclass we specified */
+
+ /* if user specified objectclass= on the commandline,
+ without any value, then the objectclass is assumed to
+ exist already */
+ if (strlen(o_objectclass) == 0) {
+ if (o_debug) { fprintf(stderr, " user objectclass assumed to already exist\n"); }
+ pin_objectclass_exists=1;
+ } else {
+ for ( i = 0; vals[i] != NULL; i++ ) {
+ if (o_debug) {
+ fprintf(stderr, " checking vals[%d]=%s == objectclass=%s -> %d \n",
+ i,vals[i]->bv_val, o_objectclass, strcasecmp(vals[i]->bv_val,o_objectclass));
+ }
+ if (!strcasecmp(vals[i]->bv_val,o_objectclass)) {
+ if (o_debug) {
+ fprintf(stderr, " %s: %s found\n", a, vals[i]->bv_val );
+ }
+ pin_objectclass_exists = 1;
+ }
+ }
+ }
+ } else if (!strcasecmp(a,o_attribute)) {
+ if (o_clobber) {
+ action = ACTION_REPLACE;
+ } else {
+ action = ACTION_NONE;
+ }
+ }
+
+ /* use ldap_value_free_len */
+ ldap_value_free_len( vals );
+ }
+ ldap_memfree( a );
+ }
+
+ if (o_debug) { fprintf(stderr, " Did the objectclass exist? %d\n", pin_objectclass_exists); }
+
+ /* add the objectclass attribute if it doesn't already exist */
+
+ if (! pin_objectclass_exists) {
+ if (o_debug) {
+ fprintf(stderr,"objectclass: %s doesn't exist, adding\n",o_objectclass);
+ }
+ objectclass_values[0] = o_objectclass;
+ objectclass_values[1] = NULL;
+ objectclass.mod_op = LDAP_MOD_ADD;
+ objectclass.mod_type = "objectclass";
+ objectclass.mod_values = objectclass_values;
+ mods[0] = &objectclass;
+ mods[1] = NULL;
+
+ if (o_write) {
+ i = ldap_modify_ext_s(ld, dn, mods, NULL, NULL);
+
+ if (i != LDAP_SUCCESS) {
+ exitLDAPError("couldn't modify attribute");
+ }
+ }
+ }
+
+ pinattribute.mod_type = o_attribute;
+
+ /* password could have been set from input file. If not, set it now */
+ if (generatedPassword == NULL || (strlen(generatedPassword) == 0)) {
+ generatedPassword = newPassword();
+ }
+ if (generatedPassword == NULL || (strlen(generatedPassword) == 0)) {
+ errcode=13;
+ exitError("Couldn't generate password.");
+ }
+
+ /* should we hash the password? */
+ if (o_hash) {
+
+ /* we hash the DN of the user and the PIN together */
+
+ if (o_debug) {
+ fprintf(stderr,"checking salt attribute...\n");
+ }
+ if (saltval == NULL) {
+ if (o_saltattribute != NULL) {
+ errcode = 11;
+ exitError("specified salt attribute not found for this user");
+ }
+ if (o_debug) {
+ fprintf(stderr,"setting salt attribute to dn...\n");
+ }
+ saltval = dn;
+ }
+
+ hashbuf_source =
+ malloc(strlen(saltval) + strlen(generatedPassword) + 10);
+ if (hashbuf_source == NULL) {
+ errcode=12;
+ exitError("Couldn't allocate 'hashbuf_source'.");
+ }
+ strcpy(hashbuf_source,saltval);
+ strcat(hashbuf_source,generatedPassword);
+
+ if (o_debug) {
+ fprintf(stderr,"hashing this: %s\n",hashbuf_source);
+ }
+
+ saltval = NULL;
+
+ /* We leave one byte at the beginning of the hash
+ buffer, to support the hash type */
+
+#define SENTINEL_SHA1 0
+#define SENTINEL_MD5 1
+#define SENTINEL_NONE '-'
+
+ if ((!strcmp(o_hash,"SHA1")) || (!strcmp(o_hash,"sha1")) ) {
+ status = PK11_HashBuf(SEC_OID_SHA1,
+ (unsigned char *)hashbuf_dest+1,
+ (unsigned char *)hashbuf_source,
+ strlen(hashbuf_source)
+ );
+ hashbuf_dest[0] = SENTINEL_SHA1;
+ pindatasize = SHA1_LENGTH + 1;
+ } else if ((!strcmp(o_hash,"MD5")) || (!strcmp(o_hash,"md5")) ) {
+ status = PK11_HashBuf(SEC_OID_MD5,
+ (unsigned char *)hashbuf_dest+1,
+ (unsigned char *)hashbuf_source,
+ strlen(hashbuf_source)
+ );
+ hashbuf_dest[0] = SENTINEL_MD5;
+ pindatasize = MD5_LENGTH + 1;
+ } else if ((!strcmp(o_hash,"NONE")) || (!strcmp(o_hash,"none")) ) {
+ hashbuf_dest[0] = SENTINEL_NONE;
+ status = SECSuccess;
+ memcpy(hashbuf_dest+1,
+ hashbuf_source,
+ strlen(hashbuf_source)
+ );
+ } else {
+ sprintf(errbuf,"Unsupported hash type '%s'. Must be one of 'sha1', 'md5' or 'none",o_hash);
+ errcode = 7;
+ exitError(errbuf);
+ }
+
+ if (status != SECSuccess) {
+ sprintf(errbuf,"Error hashing pin (%d)",PR_GetError());
+ errcode = 9;
+ exitError(errbuf);
+ }
+
+ pindata = hashbuf_dest;
+
+ if (hashbuf_source != NULL) {
+ free(hashbuf_source);
+ hashbuf_source = NULL;
+ }
+ } else {
+ pindata = generatedPassword;
+ pindatasize = strlen(generatedPassword);
+ }
+
+ bval.bv_len = pindatasize;
+ bval.bv_val = pindata;
+
+ fprintf(stderr," Adding new %s\n",o_attribute);
+
+ if (! o_write) {
+ fprintf(stderr, " [NOTE: 'write' was not specified, so no changes will be made to the directory]\n");
+ }
+
+ pinattribute.mod_bvalues = bvals;
+ if (action == ACTION_REPLACE) {
+ pinattribute.mod_op = LDAP_MOD_REPLACE|LDAP_MOD_BVALUES;
+ if (o_debug) {
+ fprintf(stderr," %s exists, replacing\n",o_attribute);
+ }
+ } else if (action == ACTION_ADD) {
+ if (o_debug) {
+ fprintf(stderr," %s doesn't exist, adding\n",o_attribute);
+ }
+ pinattribute.mod_op = LDAP_MOD_ADD|LDAP_MOD_BVALUES;
+ } else if (action == ACTION_NONE) {
+ if (o_debug) {
+ fprintf(stderr," %s exists. not replacing\n",o_attribute);
+ }
+ goto skip_write;
+ }
+ mods[0] = &pinattribute;
+ mods[1] = NULL;
+
+ if (o_write) {
+ i = ldap_modify_ext_s(ld, dn, mods, NULL, NULL);
+
+ if (i != LDAP_SUCCESS) {
+ exitLDAPError("couldn't modify attribute");
+ }
+ }
+
+ skip_write:
+
+ fprintf(output,"dn:%s\n",dn);
+ fprintf(output,"%s:%s\n",o_attribute,generatedPassword);
+ if (o_debug) {
+ fprintf(stderr,"o_write = %0x\n",(unsigned int)o_write);
+ }
+ if (! o_write) {
+ fprintf(output,"status:notwritten\n");
+ } else {
+ if (action == ACTION_NONE) {
+ fprintf(output,"status:notreplaced\n");
+ } else {
+ if (i != LDAP_SUCCESS) {
+ fprintf(output,"status:writefailed\n");
+ } else {
+ if (action == ACTION_ADD) {
+ fprintf(output,"status:added\n");
+ } else if (action == ACTION_REPLACE) {
+ fprintf(output,"status:replaced\n");
+ }
+ }
+ }
+ }
+
+ fprintf(output,"\n");
+
+ if (dn) {
+ ldap_memfree( dn );
+ dn = NULL;
+ }
+
+ if ( ber != NULL ) {
+ ber_free( ber, 0 );
+ }
+ fprintf(stderr, "\n" );
+ }
+ ldap_msgfree( r );
+}
+
+
+/* this function uses i_minlength and i_maxlength to determine the
+ size of the password to generate */
+
+static char *UCalpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+
+static char *LCalpha = "abcdefghijklmnopqrstuvwxyz";
+static char *numbers = "0123456789";
+static char *punc = "!#$%&*+,-./:;<=>?@[]^{|}";
+
+static char *charpool = NULL; /* carpool, geddit? */
+static int charpoolsize;
+
+static char *RNG_ALPHA = "RNG-alpha";
+static char *RNG_PRINTABLEASCII = "RNG-printableascii";
+static char *RNG_ALPHANUM = "RNG-alphanum";
+
+
+/* build the pool of characters we can use for the password */
+
+void buildCharpool() {
+ char err_buf[1024];
+ charpool = (char*) malloc(256);
+
+ charpool[0] = '\0';
+
+ if ( o_case == NULL) {
+ strcat(charpool,LCalpha); /* then add the lowercase */
+ } else {
+ if (strcmp(o_case,"upperonly")) {
+ errcode = 7;
+ exitError("Illegal value for case=");
+ }
+ }
+
+
+ if ( !strcmp(o_gen,RNG_ALPHA) ||
+ !strcmp(o_gen,RNG_ALPHANUM) ||
+ !strcmp(o_gen,RNG_PRINTABLEASCII) ) {
+ strcat(charpool,UCalpha); /* add uppercase chars */
+ } else {
+ sprintf(err_buf,"invalid value '%s' for gen= option",o_gen);
+ errcode = 7;
+ exitError(err_buf);
+ }
+
+ if ( strcmp(o_gen,"RNG-alpha")) { /* not alpha-only */
+ strcat(charpool,numbers);
+ }
+ if (! strcmp(o_gen,"RNG-printableascii")) {
+ strcat(charpool, punc);
+ }
+ if (o_debug) {
+ fprintf(stderr,"Character pool: %s\n",charpool);
+ }
+ charpoolsize = strlen(charpool);
+}
+
+
+/* initialize random number generator */
+
+void initrandom() {
+ char err_buf[1024];
+#ifdef USE_NSS_RANDOM
+ if( NSS_Initialize( "",
+ "",
+ "",
+ "",
+ NSS_INIT_NOCERTDB |
+ NSS_INIT_NOMODDB |
+ NSS_INIT_FORCEOPEN ) != SECSuccess ) {
+ sprintf(err_buf,"Couldn't initialize NSS (error code %d)\n",PR_GetError());
+ errcode = 9;
+ exitError(err_buf);
+ }
+#else
+ srand(time(NULL));
+#endif
+
+}
+
+
+unsigned short getRandomShort() {
+ unsigned short r;
+#ifdef USE_NSS_RANDOM
+ PK11_GenerateRandom( ( unsigned char * ) &r, sizeof( r ) );
+ if (o_debug) {
+ /* fprintf(stderr,"Random: %d\n",r); */
+ }
+ return r;
+#else
+ return (unsigned short) rand();
+#endif
+}
+
+
+/*
+ * this function is important. It needs review.
+ *
+ * returns a random number in the range (0 .. max-1)
+ */
+
+/* We have a short, rno, and we want to convert this to a number
+ in the required range by just using (rno % max). However,
+ this may result in some of the numbers at the end of 'rno's
+ range being selected more frequently. So, if random number
+ select is in this range, we will pick another.
+
+ As an example, assume:
+ a short is 4 bits (0..15)
+ max is 6
+
+ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+ a a a a a a b b b b b b X X X X
+
+ we want to reject everything more than 11
+
+ we take 16 (that largest number which can be in a short+1)
+ divide by 'max', which is 6. This gives us 2. Multiply by
+ max, gives us 12. Subtract 1, which is 11, our highest
+ allowable range. Now we do the modulus.
+
+*/
+
+unsigned short getRandomInRange(unsigned short max) {
+ unsigned short rno;
+ unsigned short result;
+
+ unsigned short max_allowed_rno =
+ ((65536 / max) * max) -1;
+
+ do {
+ rno = getRandomShort();
+ } while (rno >max_allowed_rno);
+
+ result = rno % max;
+
+ assert(result < max);
+
+ return result;
+}
+
+
+char * newPassword() {
+ static char *pw_buf=NULL;
+ unsigned short l;
+ unsigned short r;
+ int i;
+
+ if (pw_buf == NULL) {
+ pw_buf = (char *) malloc(i_maxlength+5);
+ }
+
+ if (charpool == NULL) {
+ buildCharpool();
+ }
+
+ /* decide how long the password should be */
+ /* It must be between i_minlength and i_maxlength */
+
+ if (i_minlength == i_maxlength) {
+ l = i_minlength;
+ } else {
+ l = getRandomInRange((unsigned short)(1 + i_maxlength - i_minlength));
+ l += i_minlength;
+ }
+
+ for (i=0; i<l; i++) {
+ r = getRandomInRange((unsigned short)(charpoolsize));
+ pw_buf[i] = charpool[r];
+ }
+ pw_buf[l] = '\0';
+ return pw_buf;
+}
+
+
+void testpingen() {
+ int count=25;
+ int i,j;
+ int pwlen;
+ char *pw;
+ unsigned int index[256];
+ unsigned int *totals;
+ char c;
+
+ if (! equals(o_testpingen,"")) {
+ count = atoi(o_testpingen);
+ }
+
+ if (charpool == NULL) {
+ buildCharpool();
+ }
+
+ /* last spot is used to hold invalid chars */
+ totals = malloc(sizeof(int)*(charpoolsize+1));
+ if (totals != NULL) {
+ for (i=0;i<(charpoolsize);i++) {
+ totals[i] = 0;
+ }
+ totals[charpoolsize]=0;
+ for (i=0;i<256;i++) {
+ index[i] = 255; /* indicates->invalid */
+ }
+ for (i=0;i<charpoolsize;i++) {
+ index[(int)(charpool[i])] = i;
+ }
+
+ for (i=0;i<count;i++) {
+ pw = newPassword();
+ if (pw != NULL) {
+ if (o_debug) {
+ fprintf(output,"%d:%s\n",i+1,pw);
+ }
+ pwlen = strlen(pw);
+ for (j=0;j<pwlen;j++) {
+ c = pw[j];
+ if (index[(int)c] == 255) {
+ printf("\ninvalid char found: %02x %c\n",c,c);
+ totals[charpoolsize]++;
+ }
+ else {
+ totals[index[(int)c]]++;
+ }
+ }
+ free(pw);
+ }
+ }
+
+ for (i=0;i<charpoolsize;i++) {
+ fprintf(output,"%c: %10d\n",charpool[i],totals[i]);
+ }
+ fprintf(output,"invalid: %10d\n",totals[charpoolsize]);
+ free(totals);
+ }
+}
+
+
+
diff --git a/base/native-tools/src/setpin/setpin.conf b/base/native-tools/src/setpin/setpin.conf
new file mode 100644
index 000000000..4e5851858
--- /dev/null
+++ b/base/native-tools/src/setpin/setpin.conf
@@ -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.
+#
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+#
+# Setpin has a special setup mode which allows you to
+# automate the following two tasks.
+#
+# * To enable setpin to operate, the directory schema must be
+# changed to add the pin attribute and pinPerson objectclass.
+#
+# * To enable pin removal to work well, you can create a new
+# pin user with an ACI which lets the user remove the pin
+#
+# This configuration file is used as an input for setpin.
+# After modifying the options in this file, invoke setpin
+# with this config file:
+#
+# setpin optfile=setpin.conf
+
+
+########## GENERAL INFO ABOUT YOUR DIRECTORY #####
+
+
+#------- Enter the hostname of the LDAP server
+host=localhost
+
+#------- Enter the port number of the LDAP server
+port=389
+
+#------- Enter the DN of the Directory Manager user
+binddn=CN=Directory Manager
+
+#------- Enter the password for the Directory manager user
+bindpw=
+
+
+
+################ SCHEMA MODIFICATIONS #######
+#
+# Comment-out to turn off schema modification
+schemachange=yes
+
+# Enter the pin attribute name
+attribute=pin
+
+# Enter the pin objectclass
+objectclass=pinPerson
+
+
+############### PIN REMOVAL ##########
+#
+# To enable pin removal, it is advisable to create a new
+# user who has the power to remove pins, and nothing else.
+#
+# Enter the DN and password for the new pin manager user
+pinmanager=cn=pinmanager,o=mcom.com
+pinmanagerpwd=
+
+# Enter the base over which this user has the power
+# to remove pins
+basedn=ou=people,o=mcom.com
+
+
+
+## This line switches setpin into setup mode.
+## Please do not change it.
+setup=yes
+
diff --git a/base/native-tools/src/setpin/setpin_options.c b/base/native-tools/src/setpin/setpin_options.c
new file mode 100644
index 000000000..d8ee83a8c
--- /dev/null
+++ b/base/native-tools/src/setpin/setpin_options.c
@@ -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.
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+
+/* Set-pin tool */
+
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+extern int OPT_getValue(char *option, char **output);
+extern void exitError(char *errstring);
+extern int errcode;
+
+#define PW_DEFAULT_LENGTH 6
+#define ERR_BUF_LENGTH 512
+
+char *valid_args[] = {
+ "host", "LDAP host [required]",
+ "port", "LDAP port (default 389)",
+ "binddn", "DN to bind to directory as [required]",
+ "bindpw", "Password associated with above DN ",
+ "filter", "Ldap search filter e.g. filter=(uid=*) [required]",
+/* "ssl", "Use SSL LDAP connection?", */
+/* "certdb", "Path to SSL Client certificate database directory (not yet implemented)",
+ "nickname", "Nickname of cert to use for SSL client auth (not yet implemented)",
+ */
+ "basedn", "Base DN used for LDAP search",
+ "length", "Length of generated pins (default 6)",
+ "minlength","Minimum length of generated pins (not to be used with 'length')",
+ "maxlength","Maximum length of generated pins (not to be used with 'length')",
+ "gen", "Permitted chars for pin. Type 'setpin gen' for more info",
+ "case", "Restrict case of pins 'case=upperonly'",
+ "objectclass", "Objectclass of LDAP entry to operate on (default pinPerson)",
+ "attribute","Which LDAP attribute to write to (default pin)",
+ "hash", "Hash algorithm used to store pin: 'none', 'md5' or 'sha1' (default)",
+ "saltattribute", "Which attribute to use for salt (default: dn)",
+ "input", "File to use for restricting DN's, or providing your own pins",
+ "output", "Redirect stdout to a file",
+ "write", "Turn on writing to directory (otherwise, pins will not get written)",
+ "clobber", "Overwrite old pins in the directory",
+ "testpingen", "Test pin generation mode. testpingen=count",
+ "debug", "Turn on debugging, or use debug=attrs for even more",
+ "optfile", "Read in options (one per line) from specified file",
+ "setup", "Switch to setup mode",
+ "pinmanager","Pin Manager user to create in setup mode",
+ "pinmanagerpwd","password of pin manager user in setup mode",
+ "schemachange","make schema changes in setup mode",
+ NULL
+};
+
+int valid_args_len = sizeof(valid_args)/sizeof(char *);
+
+int i_length, i_minlength, i_maxlength;
+
+char *attribute=NULL;
+
+char *o_certdb,*o_nickname,*o_binddn,*o_bindpw,*o_filter,*o_ssl,
+ *o_basedn,*o_input,*o_host,*o_port,*o_length,*o_minlength,*o_hash,
+ *o_maxlength,*o_gen,*o_case,*o_attribute,*o_objectclass,*o_output,
+ *o_retry,*o_debug, *o_write, *o_clobber, *o_saltattribute, *o_testpingen,
+ *o_setup,*o_pinmanager,*o_pinmanagerpwd,*o_schemachange;
+
+void setDefaultOptions() {
+ o_certdb= ".";
+ o_nickname= NULL;
+ o_binddn= NULL;
+ o_bindpw= NULL;
+ o_filter= NULL;
+ o_ssl= NULL;
+ o_basedn= NULL;
+ o_input= NULL;
+ o_host= NULL;
+ o_port= NULL;
+ o_length= NULL; /* default set later */
+ o_minlength=NULL;
+ o_maxlength=NULL;
+ o_gen= "RNG-alphanum";
+ o_case= NULL;
+ o_attribute="pin";
+ o_hash= "sha1";
+ o_objectclass="pinPerson";
+ o_output= NULL;
+ o_retry= "5";
+ o_debug= NULL;
+ o_write= NULL;
+ o_clobber= NULL;
+ o_saltattribute = NULL;
+ o_testpingen = NULL;
+ o_setup= NULL;
+ o_pinmanager= NULL;
+ o_pinmanagerpwd= NULL;
+ o_schemachange= NULL;
+}
+
+void getOptions() {
+ int i;
+ char *c;
+
+ i_length = 0;
+ i_minlength =0;
+ i_maxlength =0;
+
+ OPT_getValue("certdb", &o_certdb);
+ OPT_getValue("nickname", &o_nickname);
+ OPT_getValue("binddn", &o_binddn);
+ OPT_getValue("bindpw", &o_bindpw);
+ OPT_getValue("filter", &o_filter);
+ i = OPT_getValue("ssl", &o_ssl);
+ if (i) o_ssl = "yes";
+ OPT_getValue("basedn", &o_basedn);
+ OPT_getValue("input", &o_input);
+ OPT_getValue("host", &o_host);
+ OPT_getValue("port", &o_port);
+ OPT_getValue("length", &o_length);
+ if (o_length) i_length = atoi(o_length);
+ OPT_getValue("minlength",&o_minlength);
+ if (o_minlength) i_minlength = atoi(o_minlength);
+ OPT_getValue("maxlength",&o_maxlength);
+ if (o_maxlength) i_maxlength = atoi(o_maxlength);
+ OPT_getValue("gen", &o_gen);
+ OPT_getValue("case", &o_case);
+ OPT_getValue("attribute",&o_attribute);
+ OPT_getValue("hash", &o_hash);
+ if (o_hash) {
+ c = o_hash;
+ while (*c) {
+ if (isupper(*c)) {
+ *c = *c - 'A' + 'a';
+ }
+ c++;
+ }
+ }
+
+ OPT_getValue("objectclass",&o_objectclass);
+ OPT_getValue("output", &o_output);
+ OPT_getValue("retry", &o_retry);
+ i = OPT_getValue("debug", &o_debug);
+ if (i) {
+ if (! o_debug) {
+ o_debug = "yes";
+ }
+ }
+ i = OPT_getValue("write", &o_write);
+ if (i) o_write = "yes";
+ i = OPT_getValue("clobber", &o_clobber);
+ if (i) o_clobber = "yes";
+ OPT_getValue("saltattribute", &o_saltattribute);
+ i = OPT_getValue("testpingen", &o_testpingen);
+ if (i) {
+ if (!o_testpingen) {
+ o_testpingen = "25";
+ }
+ }
+ OPT_getValue("setup", &o_setup);
+ OPT_getValue("pinmanager", &o_pinmanager);
+ OPT_getValue("pinmanagerpwd", &o_pinmanagerpwd);
+ OPT_getValue("schemachange", &o_schemachange);
+
+
+}
+
+int equals(char *s, char *t) {
+ return !(strcmp(s,t));
+}
+
+void validateOptions() {
+ char errbuf[ERR_BUF_LENGTH];
+
+ if (o_nickname && equals(o_ssl,"no")) {
+ snprintf(errbuf, ERR_BUF_LENGTH, "specifying nickname doesn't make sense with no SSL");
+ goto loser;
+ }
+
+ if (o_gen == NULL || !
+ ( equals(o_gen,"RNG-printableascii") ||
+ equals(o_gen,"RNG-alpha") ||
+ equals(o_gen,"RNG-alphanum") ||
+ equals(o_gen,"FIPS181-printable"))
+ ) {
+ printf("Permissible values for gen:\n"
+ " RNG-alpha : alpha-only characters\n"
+ " RNG-alphanum : alphanumeric characters\n"
+ " RNG-printableascii : alphanumeric and punctuation\n");
+ if (o_gen) {
+ printf("You specified: gen=%s\n",o_gen);
+ }
+ exit(0);
+ }
+
+ if (o_length && (o_minlength || o_maxlength)) {
+ strcpy(errbuf,"cannot use minlength or maxlength with length option");
+ goto loser;
+ }
+
+ if (o_minlength && !o_maxlength) {
+ strcpy(errbuf,"if you set minlength, you must also set maxlength");
+ goto loser;
+ }
+
+ if (!o_minlength && o_maxlength) {
+ strcpy(errbuf,"if you set maxlength, you must also set minlength");
+ goto loser;
+ }
+
+ if (i_minlength > i_maxlength) {
+ strcpy(errbuf,"cannot set minlength to be more than maxlength");
+ goto loser;
+ }
+
+ if (i_length > 0) {
+ i_minlength = i_length;
+ i_maxlength = i_length;
+ }
+ else {
+ if (i_minlength == 0 && i_maxlength == 0) {
+ i_minlength = PW_DEFAULT_LENGTH;
+ i_maxlength = PW_DEFAULT_LENGTH;
+ }
+ }
+
+ if (o_testpingen) {
+ return;
+ }
+
+ if (!o_host || equals(o_host,"")) {
+ strcpy(errbuf,"host missing");
+ goto loser;
+ }
+
+ if (!o_binddn || equals(o_binddn,"")) {
+ strcpy(errbuf,"binddn missing");
+ goto loser;
+ }
+
+ if (!o_bindpw || equals(o_bindpw,"")) {
+ strcpy(errbuf,"bindpw missing");
+ goto loser;
+ }
+
+ if (o_setup != NULL) {
+ return;
+ }
+
+ if (!o_basedn) {
+ fprintf(stderr,"WARNING: basedn not set. Will search from root.\n");
+ }
+
+ if (!o_filter || equals(o_filter,"")) {
+ strcpy(errbuf,"filter missing. Example filters:\n filter=(uid=*) - all users with a UID attribute\n filter=(&(uid=*)(ou=Managers)) - all users with a UID and members of the managers group\n");
+ goto loser;
+ }
+
+ if (!
+ (equals(o_hash,"sha1") ||
+ equals(o_hash,"md5") ||
+ equals(o_hash,"none"))
+ ) {
+ snprintf(errbuf, ERR_BUF_LENGTH, "invalid hash: %s",o_hash);
+ goto loser;
+ }
+ if (equals(o_hash,"none")) o_hash = NULL;
+
+ return ;
+
+ loser:
+ errcode=13;
+ exitError(errbuf);
+
+}
+
+
diff --git a/base/native-tools/src/setpin/setpin_options.h b/base/native-tools/src/setpin/setpin_options.h
new file mode 100644
index 000000000..45373f356
--- /dev/null
+++ b/base/native-tools/src/setpin/setpin_options.h
@@ -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.
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+
+#ifndef SETPIN_OPTIONS_H
+#define SETPIN_OPTIONS_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+extern char *o_certdb,*o_nickname,*o_binddn,*o_bindpw,*o_bindpwfile,*o_filter,*o_ssl,
+ *o_input,*o_basedn,*o_dnfile,*o_host,*o_port,*o_length,*o_minlength,
+ *o_maxlength,*o_gen,*o_case,*o_attribute,*o_hash,*o_objectclass,*o_output,
+ *o_retry,*o_debug,*o_write,*o_clobber,*o_saltattribute,*o_testpingen,*o_setup,
+ *o_pinmanager,*o_pinmanagerpwd,*o_schemachange;
+
+extern char *valid_args[];
+extern int valid_args_len;
+
+extern void setDefaultOptions();
+extern void getOptions();
+extern void validateOptions();
+
+extern int i_length, i_minlength, i_maxlength;
+
+extern char* attribute;
+
+#endif
diff --git a/base/native-tools/src/sslget/CMakeLists.txt b/base/native-tools/src/sslget/CMakeLists.txt
new file mode 100644
index 000000000..ec4bd85f9
--- /dev/null
+++ b/base/native-tools/src/sslget/CMakeLists.txt
@@ -0,0 +1,30 @@
+project(sslget C)
+
+set(SSLGET_PRIVATE_INCLUDE_DIRS
+ ${CMAKE_BINARY_DIR}
+ ${NSPR_INCLUDE_DIRS}
+ ${NSS_INCLUDE_DIRS}
+)
+
+set(SSLGET_LINK_LIBRARIES
+ ${NSPR_LIBRARIES}
+ ${NSS_LIBRARIES}
+)
+
+set(sslget_SRCS
+ sslget.c
+ getopt.c
+)
+
+include_directories(${SSLGET_PRIVATE_INCLUDE_DIRS})
+
+add_executable(sslget ${sslget_SRCS})
+
+target_link_libraries(sslget ${SSLGET_LINK_LIBRARIES})
+
+install(
+ TARGETS sslget
+ RUNTIME DESTINATION ${BIN_INSTALL_DIR}
+ LIBRARY DESTINATION ${LIB_INSTALL_DIR}
+ ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
+)
diff --git a/base/native-tools/src/sslget/getopt.c b/base/native-tools/src/sslget/getopt.c
new file mode 100644
index 000000000..7554e1a14
--- /dev/null
+++ b/base/native-tools/src/sslget/getopt.c
@@ -0,0 +1,126 @@
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ *
+ * END COPYRIGHT BLOCK **/
+#ifdef XP_PC
+
+/*
+** This comes from the AT&T public-domain getopt published in mod.sources
+** (i.e., comp.sources.unix before the great Usenet renaming).
+*/
+
+#include <stdio.h>
+#include <string.h> /* for str*() */
+#include <io.h> /* for write() */
+
+int opterr = 1; /* boolean flag, says "report error on stderr." */
+int optind = 1; /* index to element of argv from which options are
+ ** being parsed. */
+int optopt = 0; /* option character */
+char *optarg; /* ptr to option's parameter arg. */
+
+#ifdef _WIN32
+static void
+do_opterr(const char *s, int c, char * const av[])
+{
+ if (opterr) {
+ char buff[2];
+ int fd = _fileno(stderr);
+
+ buff[0] = (char)c;
+ buff[1] = '\n';
+ (void)write(fd, av[0], strlen(av[0]));
+ (void)write(fd, s, strlen(s));
+ (void)write(fd, buff, 2);
+ }
+}
+#define ERR(s, c) do_opterr(s, c, av)
+#else
+#define ERR(s, c) /* Win16 doesn't do stderr */
+#endif
+
+/*
+** Return options and their values from the command line.
+*/
+int
+getopt(int ac, char * const av[], const char * opts)
+{
+ static int i = 1; /* offset of current option char in current arg. */
+ char *p; /* opt char in opts that matched. */
+
+ /* Move to next value from argv? */
+ if (i == 1) {
+ if (optind >= ac || av[optind][0] != '-' || av[optind][1] == '\0')
+ return EOF;
+ if (strcmp(av[optind], "--") == 0) {
+ optind++;
+ return EOF;
+ }
+ }
+
+ /* Get next option character. */
+ if ((optopt = av[optind][i]) == ':' ||
+ (p = strchr(opts, optopt)) == NULL) {
+ ERR(": illegal option -- ", optopt);
+ if (av[optind][++i] == '\0') {
+ optind++;
+ i = 1;
+ }
+ return '?';
+ }
+
+ /* Snarf argument? */
+ if (*++p == ':') {
+ if (av[optind][i + 1] != '\0')
+ optarg = &av[optind++][i + 1];
+ else {
+ if (++optind >= ac) {
+ ERR(": option requires an argument -- ", optopt);
+ i = 1;
+ return '?';
+ }
+ optarg = av[optind++];
+ }
+ i = 1;
+ } else {
+ if (av[optind][++i] == '\0') {
+ i = 1;
+ optind++;
+ }
+ optarg = NULL;
+ }
+
+ return optopt;
+}
+
+#endif /* XP_PC */
diff --git a/base/native-tools/src/sslget/sslget.c b/base/native-tools/src/sslget/sslget.c
new file mode 100644
index 000000000..7288a1c58
--- /dev/null
+++ b/base/native-tools/src/sslget/sslget.c
@@ -0,0 +1,836 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 ---
+ */
+
+/* vi: set ts=4 sw=4 : */
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#if defined(XP_UNIX)
+#include <unistd.h>
+#endif
+
+#include "ssl.h"
+
+#include "prerror.h"
+
+#include "pk11func.h"
+#include "secitem.h"
+
+
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+
+#include "nspr.h"
+#include "prio.h"
+#include "prnetdb.h"
+#include "nss.h"
+
+
+/* set Tabs to 8 */
+
+
+/*from nss2.8.4 secopt.h*/
+#ifdef XP_PC
+
+/*
+** This comes from the AT&T public-domain getopt published in mod.sources
+** (i.e., comp.sources.unix before the great Usenet renaming).
+*/
+
+extern int opterr;
+extern int optind;
+extern int optopt;
+extern char *optarg;
+
+#ifdef _WIN32
+static void do_opterr(const char *s, int c, char * const av[]);
+#define ERR(s, c) do_opterr(s, c, av)
+#else
+#define ERR(s, c) /* Win16 doesn't do stderr */
+#endif
+
+/*
+** Return options and their values from the command line.
+*/
+int getopt(int ac, char * const av[], const char * opts);
+#else
+#if defined(LINUX)
+#include <getopt.h>
+#endif
+#endif /* XP_PC */
+/*end secopt.h*/
+
+#define VERSIONSTRING "$Revision$ ($Date$)"
+
+#ifndef PORT_Sprintf
+#define PORT_Sprintf sprintf
+#endif
+
+#ifndef PORT_Strstr
+#define PORT_Strstr strstr
+#endif
+
+#ifndef PORT_Malloc
+#define PORT_Malloc PR_Malloc
+#endif
+
+#define RD_BUF_SIZE (60 * 1024)
+
+#define PRINTF if (verbose) printf
+#define FPRINTF if (verbose) fprintf
+#define FPUTS if (verbose) fputs
+
+#define MAX_SERIAL_LEN 8192
+
+int MakeCertOK=1;
+
+int verbose;
+SECItem bigBuf;
+
+
+char * ownPasswd( PK11SlotInfo *slot, PRBool retry, void *arg)
+{
+ char *passwd = NULL;
+
+ if ( (!retry) && arg ) {
+ passwd = PL_strdup((char *)arg);
+ }
+
+ return passwd;
+}
+
+static void
+Usage(const char *progName)
+{
+ fprintf(stderr,
+ "Usage: %s [-n nickname] [-p password | -w pwfile ] [-d dbdir] \n"
+ " [-e post] [-v] [-V] -r url hostname[:port]\n"
+ " -n : nickname or hsm:nickname\n"
+ " -v : verbose\n"
+ " -V : report version information\n",
+ progName);
+ exit(1);
+}
+
+
+static void
+errWarn(char * funcString)
+{
+ PRErrorCode perr = PR_GetError();
+
+ FPRINTF(stderr, "exit after %s with error %d:\n", funcString,perr );
+}
+
+static void
+errExit(char * funcString)
+{
+ errWarn(funcString);
+ exit(1);
+}
+
+/* This invokes the "default" AuthCert handler in libssl.
+** The only reason to use this one is that it prints out info as it goes.
+*/
+static SECStatus
+mySSLAuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig,
+ PRBool isServer)
+{
+ SECStatus rv;
+ CERTCertificate * peerCert;
+
+ peerCert = SSL_PeerCertificate(fd);
+
+ PRINTF("Subject: %s\nIssuer : %s\n",
+ peerCert->subjectName, peerCert->issuerName);
+ /* invoke the "default" AuthCert handler. */
+ rv = SSL_AuthCertificate(arg, fd, checkSig, isServer);
+
+ if (rv == SECSuccess) {
+ FPUTS("-- SSL3: Server Certificate Validated.\n", stderr);
+ }
+ /* error, if any, will be displayed by the Bad Cert Handler. */
+ return rv;
+}
+
+static SECStatus
+myBadCertHandler( void *arg, PRFileDesc *fd)
+{
+ /* int err = PR_GetError(); */
+ /* fprintf(stderr, "-- SSL: Server Certificate Invalid, err %d.\n%s\n",
+ err, SECU_Strerror(err)); */
+ return (MakeCertOK ? SECSuccess : SECFailure);
+}
+
+
+SECStatus
+my_GetClientAuthData(void * arg,
+ PRFileDesc * socket,
+ struct CERTDistNamesStr * caNames,
+ struct CERTCertificateStr ** pRetCert,
+ struct SECKEYPrivateKeyStr **pRetKey)
+{
+ CERTCertificate * cert = NULL;
+ SECKEYPrivateKey * privkey = NULL;
+ char * chosenNickName = (char *)arg; /* CONST */
+ void * proto_win = NULL;
+ SECStatus rv = SECFailure;
+
+ FPRINTF(stderr,"Called mygetclientauthdata - nickname = %s\n",chosenNickName);
+
+ proto_win = SSL_RevealPinArg(socket);
+
+ if (chosenNickName) {
+ cert = PK11_FindCertFromNickname(chosenNickName, proto_win);
+ FPRINTF(stderr," mygetclientauthdata - cert = %x\n",(unsigned int)cert);
+ if ( cert ) {
+ privkey = PK11_FindKeyByAnyCert(cert, proto_win);
+ FPRINTF(stderr," mygetclientauthdata - privkey = %x\n",(unsigned int)privkey);
+ if ( privkey ) {
+ rv = SECSuccess;
+ } else {
+ CERT_DestroyCertificate(cert);
+ }
+ }
+ } else { /* no name given, automatically find the right cert. */
+ CERTCertNicknames * names;
+ int i;
+
+ names = CERT_GetCertNicknames(CERT_GetDefaultCertDB(),
+ SEC_CERT_NICKNAMES_USER, proto_win);
+ if (names != NULL) {
+ for (i = 0; i < names->numnicknames; i++) {
+ cert = PK11_FindCertFromNickname(names->nicknames[i],proto_win);
+ if ( !cert )
+ continue;
+ /* Only check unexpired certs */
+ if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_TRUE) !=
+ secCertTimeValid ) {
+ CERT_DestroyCertificate(cert);
+ continue;
+ }
+ rv = NSS_CmpCertChainWCANames(cert, caNames);
+ if ( rv == SECSuccess ) {
+ privkey = PK11_FindKeyByAnyCert(cert, proto_win);
+ if ( privkey )
+ break;
+ }
+ rv = SECFailure;
+ CERT_DestroyCertificate(cert);
+ }
+ CERT_FreeNicknames(names);
+ }
+ }
+ if (rv == SECSuccess) {
+ *pRetCert = cert;
+ *pRetKey = privkey;
+ }
+ return rv;
+}
+
+
+
+
+void
+printSecurityInfo(PRFileDesc *fd)
+{
+ char * cp; /* bulk cipher name */
+ char * ip; /* cert issuer DN */
+ char * sp; /* cert subject DN */
+ int op; /* High, Low, Off */
+ int kp0; /* total key bits */
+ int kp1; /* secret key bits */
+ int result;
+
+ static int only_once;
+
+ if (! only_once++ && fd) {
+ result = SSL_SecurityStatus(fd, &op, &cp, &kp0, &kp1, &ip, &sp);
+ if (result != SECSuccess)
+ return;
+#if 0
+ PRINTF("bulk cipher %s, %d secret key bits, %d key bits, status: %d\n"
+ "subject DN: %s\n"
+ "issuer DN: %s\n", cp, kp1, kp0, op, sp, ip);
+#else
+ PRINTF("bulk cipher %s, %d secret key bits, %d key bits, status: %d\n",
+ cp, kp1, kp0, op);
+#endif
+ PR_Free(cp);
+ PR_Free(ip);
+ PR_Free(sp);
+ }
+
+}
+
+
+PRBool useModelSocket = PR_TRUE;
+
+static const char outHeader[] = {
+ "HTTP/1.0 200 OK\r\n"
+ "Server: Netscape-Enterprise/2.0a\r\n"
+ "Date: Tue, 26 Aug 1997 22:10:05 GMT\r\n"
+ "Content-type: text/plain\r\n"
+ "\r\n"
+};
+
+
+PRInt32
+do_writes(
+ void * a
+)
+{
+ PRFileDesc * ssl_sock = (PRFileDesc *)a;
+ PRUint32 sent = 0;
+ PRInt32 count = 0;
+
+ while (sent < bigBuf.len) {
+
+ count = PR_Write(ssl_sock, bigBuf.data + sent, bigBuf.len - sent);
+ if (count < 0) {
+ errWarn("PR_Write bigBuf");
+ exit(4);
+ break;
+ }
+ FPRINTF(stderr, "PR_Write wrote %d bytes from bigBuf\n", count );
+ FPRINTF(stderr, "bytes: [%*s]\n",count,bigBuf.data);
+
+ sent += (PRUint32)count;
+ }
+ if (count >= 0) { /* last write didn't fail. */
+ FPRINTF(stderr, "do_writes shutting down send socket\n");
+ /* PR_Shutdown(ssl_sock, PR_SHUTDOWN_SEND); */
+ }
+
+ FPRINTF(stderr, "do_writes exiting with (failure = %d)\n",sent<bigBuf.len == SECFailure);
+ return (sent < bigBuf.len) ? SECFailure : SECSuccess;
+}
+
+
+
+
+SECStatus
+do_io( PRFileDesc *ssl_sock, int connection)
+{
+ int countRead = 0;
+ PRInt32 rv;
+ char *buf;
+ char *buf2;
+ int first=1;
+
+ buf = PR_Malloc(RD_BUF_SIZE);
+ if (!buf) exit(5);
+
+ /* send the http request here. */
+
+ rv = do_writes(ssl_sock);
+
+ if (rv == SECFailure) {
+ errWarn("returning from after calling do_writes");
+ PR_Free(buf);
+ buf = 0;
+ exit(6);
+ }
+ printSecurityInfo(ssl_sock);
+
+ /* read until EOF */
+ while (1) {
+ rv = PR_Read(ssl_sock, buf, RD_BUF_SIZE);
+ if (rv == 0) {
+ break; /* EOF */
+ }
+ if (rv < 0) {
+ errWarn("PR_Read");
+ PR_Free(buf);
+ buf = 0;
+ exit(1);
+ }
+
+ countRead += rv;
+ FPRINTF(stderr, "connection %d read %d bytes (%d total).\n",
+ connection, rv, countRead );
+ FPRINTF(stderr, "these bytes read:\n");
+ PR_Write(PR_STDOUT,buf,rv);
+
+ if (first) {
+ first=0;
+ if (rv < 13) {
+ int ret = 0;
+ buf2 = PR_Malloc(RD_BUF_SIZE);
+ if (!buf2) {
+ PR_Free(buf);
+ buf = 0;
+ exit(5);
+ }
+
+ for (ret=0; rv < 13 ; rv += ret) {
+ ret = PR_Read(ssl_sock, buf2, RD_BUF_SIZE - rv);
+ if (ret < 0 ) {
+ errWarn("PR_Read");
+ PR_Free(buf);
+ buf = 0;
+ PR_Free(buf2);
+ buf2 = 0;
+ exit(1);
+ }
+ if (ret == 0) {
+ errWarn("not enough bytes read in first read");
+ PR_Free(buf);
+ buf = 0;
+ PR_Free(buf2);
+ buf2 = 0;
+ exit(2);
+ }
+ countRead += ret;
+ FPRINTF(stderr, "connection %d read %d bytes (%d total).\n",
+ connection, ret, countRead );
+ FPRINTF(stderr, "these bytes read:\n");
+ PR_Write(PR_STDOUT, buf2, ret);
+
+ PR_snprintf(buf, RD_BUF_SIZE, "%s%s", buf, buf2);
+ }
+ PR_Free(buf2);
+ buf2 = 0;
+ }
+
+ if ( ! PL_strnstr(buf,"200",13)) {
+ PR_Free(buf);
+ buf = 0;
+ exit(3);
+ }
+ }
+ }
+ PR_fprintf(PR_STDOUT, "\n");
+
+ PR_Free(buf);
+ buf = 0;
+
+ /* Caller closes the socket. */
+
+ FPRINTF(stderr,
+ "connection %d read %d bytes total. -----------------------------\n",
+ connection, countRead);
+
+ return SECSuccess; /* success */
+}
+
+int
+do_connect(
+ PRNetAddr *addr,
+ PRFileDesc *model_sock,
+ int connection)
+{
+ PRFileDesc * ssl_sock;
+ PRFileDesc * tcp_sock;
+ PRStatus prStatus;
+ SECStatus result;
+ int rv = SECSuccess;
+ PRSocketOptionData opt;
+
+ int family = PR_NetAddrFamily( addr );
+
+ tcp_sock = PR_OpenTCPSocket( family );
+ if (tcp_sock == NULL) {
+ errExit("PR_OpenTCPSocket on tcp socket");
+ }
+
+ opt.option = PR_SockOpt_Nonblocking;
+ opt.value.non_blocking = PR_FALSE;
+ prStatus = PR_SetSocketOption(tcp_sock, &opt);
+ if (prStatus != PR_SUCCESS) {
+ if( tcp_sock != NULL ) {
+ PR_Close(tcp_sock);
+ tcp_sock = NULL;
+ }
+ /* Don't return SECFailure? */
+ return SECSuccess;
+ }
+
+ prStatus = PR_Connect(tcp_sock, addr, PR_SecondsToInterval(3));
+ if (prStatus != PR_SUCCESS) {
+ errWarn("PR_Connect");
+ if( tcp_sock != NULL ) {
+ PR_Close(tcp_sock);
+ tcp_sock = NULL;
+ }
+ exit(6);
+ }
+
+ ssl_sock = SSL_ImportFD(model_sock, tcp_sock);
+ /* XXX if this import fails, close tcp_sock and return. */
+ if (!ssl_sock) {
+ if( tcp_sock != NULL ) {
+ PR_Close(tcp_sock);
+ tcp_sock = NULL;
+ }
+ exit(7);
+ }
+
+ rv = SSL_ResetHandshake(ssl_sock, /* asServer */ 0);
+ if (rv != SECSuccess) {
+ errWarn("SSL_ResetHandshake");
+ exit(8);
+ }
+
+ result = do_io( ssl_sock, connection);
+
+ if( ssl_sock != NULL ) {
+ PR_Close(ssl_sock);
+ ssl_sock = NULL;
+ }
+ return SECSuccess;
+}
+
+/* Returns IP address for hostname as PRUint32 in Host Byte Order.
+** Since the value returned is an integer (not a string of bytes),
+** it is inherently in Host Byte Order.
+*/
+PRUint32
+getIPAddress(const char * hostName)
+{
+ const unsigned char *p;
+ PRStatus prStatus;
+ PRUint32 rv;
+ PRHostEnt prHostEnt;
+ char scratch[PR_NETDB_BUF_SIZE];
+
+ prStatus = PR_GetHostByName(hostName, scratch, sizeof scratch, &prHostEnt);
+ if (prStatus != PR_SUCCESS)
+ errExit("PR_GetHostByName");
+
+#undef h_addr
+#define h_addr h_addr_list[0] /* address, for backward compatibility */
+
+ p = (const unsigned char *)(prHostEnt.h_addr); /* in Network Byte order */
+ FPRINTF(stderr, "%s -> %d.%d.%d.%d\n", hostName, p[0], p[1], p[2], p[3]);
+ rv = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+ return rv;
+}
+
+void
+client_main(
+ unsigned short port,
+ int connections,
+ SECKEYPrivateKey ** privKey,
+ CERTCertificate ** cert,
+ const char * hostName,
+ char * nickName)
+{
+ PRFileDesc *model_sock = NULL;
+ int rv;
+
+
+ FPRINTF(stderr, "port: %d\n", port);
+
+ /* all suites except RSA_NULL_MD5 are enabled by Domestic Policy */
+ NSS_SetDomesticPolicy();
+
+ /* all the SSL2 and SSL3 cipher suites are enabled by default. */
+
+ /* enable FIPS ciphers */
+ SSL_CipherPrefSetDefault(0xc004 /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA */, PR_TRUE);
+ SSL_CipherPrefSetDefault(0xc003 /* TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA */, PR_TRUE);
+ SSL_CipherPrefSetDefault(0xC005 /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA */, PR_TRUE);
+ SSL_CipherPrefSetDefault(0xc00a /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA */, PR_TRUE);
+ SSL_CipherPrefSetDefault(0x2f /* TLS_RSA_WITH_AES_128_CBC_SHA */, PR_TRUE);
+ SSL_CipherPrefSetDefault(0x35 /* TLS_RSA_WITH_AES_256_CBC_SHA */, PR_TRUE);
+ SSL_CipherPrefSetDefault(0xc008 /* TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA */, PR_TRUE);
+ SSL_CipherPrefSetDefault(0xc009 /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA */, PR_TRUE);
+ SSL_CipherPrefSetDefault(0xc012 /* TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA */, PR_TRUE);
+ SSL_CipherPrefSetDefault(0xc013 /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA */, PR_TRUE);
+ SSL_CipherPrefSetDefault(0xc014 /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */, PR_TRUE);
+ SSL_CipherPrefSetDefault(0x32 /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA */, PR_TRUE);
+ SSL_CipherPrefSetDefault(0x38 /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA */, PR_TRUE);
+ SSL_CipherPrefSetDefault(0x33 /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA */, PR_TRUE);
+ SSL_CipherPrefSetDefault(0x39 /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA */, PR_TRUE);
+
+ /*
+ * Rifle through the values for the host
+ */
+
+ PRAddrInfo *ai;
+ void *iter;
+ PRNetAddr addr;
+ int family = PR_AF_INET;
+
+ ai = PR_GetAddrInfoByName(hostName, PR_AF_UNSPEC, PR_AI_ADDRCONFIG);
+ if (ai) {
+ FPRINTF( stderr, "addr='%s'\n", PR_GetCanonNameFromAddrInfo( ai ) );
+ iter = NULL;
+ while ((iter = PR_EnumerateAddrInfo(iter, ai, 0, &addr)) != NULL) {
+ family = PR_NetAddrFamily(&addr);
+ FPRINTF( stderr, "family='%d'\n", family );
+ break;
+ }
+ PR_FreeAddrInfo(ai);
+ }
+
+ PR_SetNetAddr( PR_IpAddrNull, family, port, &addr );
+
+ model_sock = PR_OpenTCPSocket( family );
+ if (model_sock == NULL) {
+ errExit("PR_OpenTCPSocket on tcp socket");
+ }
+
+ /* Should we really be re-using the same socket? */
+ model_sock = SSL_ImportFD(NULL, model_sock);
+
+
+ /* check on success of call to SSL_ImportFD() */
+ if (model_sock == NULL) {
+ errExit("SSL_ImportFD");
+ }
+
+ /* enable ECC cipher also */
+
+ /* do SSL configuration. */
+
+ rv = SSL_OptionSet(model_sock, SSL_SECURITY, 1);
+ if (rv < 0) {
+ if( model_sock != NULL ) {
+ PR_Close( model_sock );
+ model_sock = NULL;
+ }
+ errExit("SSL_OptionSet SSL_SECURITY");
+ }
+
+ SSL_SetURL(model_sock, hostName);
+
+ SSL_AuthCertificateHook(model_sock, mySSLAuthCertificate,
+ (void *)CERT_GetDefaultCertDB());
+
+ SSL_BadCertHook(model_sock, myBadCertHandler, NULL);
+
+ if( nickName) {
+ SSL_GetClientAuthDataHook(model_sock,
+ (SSLGetClientAuthData)my_GetClientAuthData,
+ nickName);
+ }
+
+ /* I'm not going to set the HandshakeCallback function. */
+
+ /* end of ssl configuration. */
+
+ rv = do_connect(&addr, model_sock, 1);
+
+ if( model_sock != NULL ) {
+ PR_Close( model_sock );
+ model_sock = NULL;
+ }
+}
+
+
+SECStatus
+createRequest(char * url, char *post)
+{
+ char * newstr;
+
+ if (post == NULL) {
+ newstr = PR_smprintf(
+ "GET %s HTTP/1.0\r\n\r\n",
+ url);
+ } else {
+ int len = strlen(post);
+ newstr = PR_smprintf(
+ "POST %s HTTP/1.0\r\nContent-Length: %d\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\n%s", url, len, post);
+ }
+
+ bigBuf.data = (unsigned char *)newstr;
+
+ FPUTS((char *)bigBuf.data, stderr);
+
+ bigBuf.len = PORT_Strlen((char *)bigBuf.data);
+
+ return SECSuccess;
+}
+
+int
+main(int argc, char **argv)
+{
+ char * dir = ".";
+ char * hostName = NULL;
+ char * nickName = NULL;
+ char * progName = NULL;
+ char * tmp = NULL;
+ char * post = NULL;
+ CERTCertificate * cert [kt_kea_size] = { NULL };
+ SECKEYPrivateKey * privKey[kt_kea_size] = { NULL };
+ int optchar;
+ int connections = 1;
+ int tmpI;
+ unsigned short port = 443;
+ SECStatus rv;
+ char * passwd = NULL;
+ char * passwdfile = NULL;
+ char * url = NULL;
+ FILE *fp;
+ char pwbuf[256];
+ int co;
+ char *crlf;
+
+ /* Call the NSPR initialization routines */
+ PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
+
+ tmp = strrchr(argv[0], '/');
+ tmp = tmp ? tmp + 1 : argv[0];
+ progName = strrchr(tmp, '\\');
+ progName = progName ? progName + 1 : tmp;
+
+
+ while ((optchar = getopt(argc, argv, "Vd:e:n:p:r:w:v")) != -1) {
+ switch(optchar) {
+
+/* Version */
+ case 'V':
+ printf("%s\n",VERSIONSTRING);
+ PR_Cleanup();
+ return 0;
+
+/* Directory which holds cert8.db and key3.db */
+ case 'd':
+ dir = optarg;
+ break;
+
+/* Nickname of certificate to use */
+ case 'n':
+ nickName = optarg;
+ break;
+
+/* password to open key3.db */
+ case 'p':
+ passwd = optarg;
+ break;
+
+/* name of file holding password for key3.db */
+ case 'w':
+ passwdfile = optarg;
+ break;
+
+/* url */
+ case 'r':
+ url = optarg;
+ break;
+
+/* post parameters */
+ case 'e':
+ post = optarg;
+ break;
+
+ case 'v':
+ verbose++;
+ break;
+
+ default:
+ case '?':
+ fprintf( stderr, "ERROR: Invalid option!\n" );
+ Usage(progName);
+ break;
+
+ }
+ }
+
+ if (optind != argc - 1) {
+ fprintf( stderr, "ERROR: Invalid number of arguments!\n" );
+ Usage(progName);
+ }
+
+ hostName = argv[optind];
+ tmp = strchr(hostName, ':');
+ if (tmp) {
+ *tmp++ = 0;
+ tmpI = atoi(tmp);
+ if (tmpI <= 0) {
+ fprintf( stderr, "ERROR: Invalid port!\n" );
+ Usage(progName);
+ }
+ port = (unsigned short)tmpI;
+ }
+
+ if ( !url) {
+ fprintf( stderr, "ERROR: Invalid url!\n" );
+ Usage(progName);
+ }
+
+ createRequest(url, post);
+
+ if (passwdfile) {
+ fp = fopen(passwdfile,"r");
+ if (!fp) { fprintf(stderr, "Couldn't open password file\n"); exit(7); }
+ co = fread(pwbuf,1,256,fp);
+ pwbuf[co] = '\0';
+ crlf = PL_strchr(pwbuf,'\n');
+ if (crlf) {
+ *crlf = '\0';
+ }
+ passwd = pwbuf;
+ }
+
+ /* set our password function */
+ if (passwd == NULL) {
+ fprintf( stderr, "ERROR: Invalid password!\n" );
+ PRINTF("Password must be provided on command line in this version of revoker.\n");
+ Usage(progName);
+ }
+ PK11_SetPasswordFunc(ownPasswd);
+
+ /* Call the libsec initialization routines */
+ rv = NSS_Init(dir);
+ if (rv != SECSuccess) {
+ fputs("NSS_Init failed.\n", stderr);
+ exit(1);
+ }
+
+ if(nickName) {
+ cert[kt_rsa] = PK11_FindCertFromNickname(nickName, passwd);
+ if (cert[kt_rsa] == NULL) {
+ fprintf(stderr, "Can't find certificate %s\n", nickName);
+ exit(1);
+ }
+
+ privKey[kt_rsa] = PK11_FindKeyByAnyCert(cert[kt_rsa], passwd);
+ if (privKey[kt_rsa] == NULL) {
+ fprintf(stderr, "Can't find Private Key for cert %s (possibly incorrect password)\n", nickName);
+ exit(1);
+ }
+ }
+
+ client_main(port, connections, privKey, cert, hostName, nickName);
+
+ NSS_Shutdown();
+ PR_Cleanup();
+ return 0;
+}
+
diff --git a/base/native-tools/src/tkstool/CMakeLists.txt b/base/native-tools/src/tkstool/CMakeLists.txt
new file mode 100644
index 000000000..8b07950eb
--- /dev/null
+++ b/base/native-tools/src/tkstool/CMakeLists.txt
@@ -0,0 +1,45 @@
+project(tkstool C)
+
+set(TKSTOOL_PRIVATE_INCLUDE_DIRS
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_BINARY_DIR}
+ ${NSPR_INCLUDE_DIRS}
+ ${NSS_INCLUDE_DIRS}
+)
+
+set(TKSTOOL_LINK_LIBRARIES
+ ${NSPR_LIBRARIES}
+ ${NSS_LIBRARIES}
+)
+
+set(tkstool_SRCS
+ delete.c
+ file.c
+ find.c
+ help.c
+ key.c
+ list.c
+ modules.c
+ pppolicy.c
+ random.c
+ retrieve.c
+ secerror.c
+ secpwd.c
+ secutil.c
+ tkstool.c
+ util.c
+ version.c
+)
+
+include_directories(${TKSTOOL_PRIVATE_INCLUDE_DIRS})
+
+add_executable(tkstool ${tkstool_SRCS})
+
+target_link_libraries(tkstool ${TKSTOOL_LINK_LIBRARIES})
+
+install(
+ TARGETS tkstool
+ RUNTIME DESTINATION ${BIN_INSTALL_DIR}
+ LIBRARY DESTINATION ${LIB_INSTALL_DIR}
+ ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
+)
diff --git a/base/native-tools/src/tkstool/NSPRerrs.h b/base/native-tools/src/tkstool/NSPRerrs.h
new file mode 100644
index 000000000..f0bc8b77e
--- /dev/null
+++ b/base/native-tools/src/tkstool/NSPRerrs.h
@@ -0,0 +1,161 @@
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/NSPRerrs.h
+ */
+
+/* General NSPR 2.0 errors */
+/* Caller must #include "prerror.h" */
+
+ER2( PR_OUT_OF_MEMORY_ERROR, "Memory allocation attempt failed." )
+ER2( PR_BAD_DESCRIPTOR_ERROR, "Invalid file descriptor." )
+ER2( PR_WOULD_BLOCK_ERROR, "The operation would have blocked." )
+ER2( PR_ACCESS_FAULT_ERROR, "Invalid memory address argument." )
+ER2( PR_INVALID_METHOD_ERROR, "Invalid function for file type." )
+ER2( PR_ILLEGAL_ACCESS_ERROR, "Invalid memory address argument." )
+ER2( PR_UNKNOWN_ERROR, "Some unknown error has occurred." )
+ER2( PR_PENDING_INTERRUPT_ERROR,"Operation interrupted by another thread." )
+ER2( PR_NOT_IMPLEMENTED_ERROR, "function not implemented." )
+ER2( PR_IO_ERROR, "I/O function error." )
+ER2( PR_IO_TIMEOUT_ERROR, "I/O operation timed out." )
+ER2( PR_IO_PENDING_ERROR, "I/O operation on busy file descriptor." )
+ER2( PR_DIRECTORY_OPEN_ERROR, "The directory could not be opened." )
+ER2( PR_INVALID_ARGUMENT_ERROR, "Invalid function argument." )
+ER2( PR_ADDRESS_NOT_AVAILABLE_ERROR, "Network address not available (in use?)." )
+ER2( PR_ADDRESS_NOT_SUPPORTED_ERROR, "Network address type not supported." )
+ER2( PR_IS_CONNECTED_ERROR, "Already connected." )
+ER2( PR_BAD_ADDRESS_ERROR, "Network address is invalid." )
+ER2( PR_ADDRESS_IN_USE_ERROR, "Local Network address is in use." )
+ER2( PR_CONNECT_REFUSED_ERROR, "Connection refused by peer." )
+ER2( PR_NETWORK_UNREACHABLE_ERROR, "Network address is presently unreachable." )
+ER2( PR_CONNECT_TIMEOUT_ERROR, "Connection attempt timed out." )
+ER2( PR_NOT_CONNECTED_ERROR, "Network file descriptor is not connected." )
+ER2( PR_LOAD_LIBRARY_ERROR, "Failure to load dynamic library." )
+ER2( PR_UNLOAD_LIBRARY_ERROR, "Failure to unload dynamic library." )
+ER2( PR_FIND_SYMBOL_ERROR,
+"Symbol not found in any of the loaded dynamic libraries." )
+ER2( PR_INSUFFICIENT_RESOURCES_ERROR, "Insufficient system resources." )
+ER2( PR_DIRECTORY_LOOKUP_ERROR,
+"A directory lookup on a network address has failed." )
+ER2( PR_TPD_RANGE_ERROR,
+"Attempt to access a TPD key that is out of range." )
+ER2( PR_PROC_DESC_TABLE_FULL_ERROR, "Process open FD table is full." )
+ER2( PR_SYS_DESC_TABLE_FULL_ERROR, "System open FD table is full." )
+ER2( PR_NOT_SOCKET_ERROR,
+"Network operation attempted on non-network file descriptor." )
+ER2( PR_NOT_TCP_SOCKET_ERROR,
+"TCP-specific function attempted on a non-TCP file descriptor." )
+ER2( PR_SOCKET_ADDRESS_IS_BOUND_ERROR, "TCP file descriptor is already bound." )
+ER2( PR_NO_ACCESS_RIGHTS_ERROR, "Access Denied." )
+ER2( PR_OPERATION_NOT_SUPPORTED_ERROR,
+"The requested operation is not supported by the platform." )
+ER2( PR_PROTOCOL_NOT_SUPPORTED_ERROR,
+"The host operating system does not support the protocol requested." )
+ER2( PR_REMOTE_FILE_ERROR, "Access to the remote file has been severed." )
+ER2( PR_BUFFER_OVERFLOW_ERROR,
+"The value requested is too large to be stored in the data buffer provided." )
+ER2( PR_CONNECT_RESET_ERROR, "TCP connection reset by peer." )
+ER2( PR_RANGE_ERROR, "Unused." )
+ER2( PR_DEADLOCK_ERROR, "The operation would have deadlocked." )
+ER2( PR_FILE_IS_LOCKED_ERROR, "The file is already locked." )
+ER2( PR_FILE_TOO_BIG_ERROR,
+"Write would result in file larger than the system allows." )
+ER2( PR_NO_DEVICE_SPACE_ERROR, "The device for storing the file is full." )
+ER2( PR_PIPE_ERROR, "Unused." )
+ER2( PR_NO_SEEK_DEVICE_ERROR, "Unused." )
+ER2( PR_IS_DIRECTORY_ERROR,
+"Cannot perform a normal file operation on a directory." )
+ER2( PR_LOOP_ERROR, "Symbolic link loop." )
+ER2( PR_NAME_TOO_LONG_ERROR, "File name is too long." )
+ER2( PR_FILE_NOT_FOUND_ERROR, "File not found." )
+ER2( PR_NOT_DIRECTORY_ERROR,
+"Cannot perform directory operation on a normal file." )
+ER2( PR_READ_ONLY_FILESYSTEM_ERROR,
+"Cannot write to a read-only file system." )
+ER2( PR_DIRECTORY_NOT_EMPTY_ERROR,
+"Cannot delete a directory that is not empty." )
+ER2( PR_FILESYSTEM_MOUNTED_ERROR,
+"Cannot delete or rename a file object while the file system is busy." )
+ER2( PR_NOT_SAME_DEVICE_ERROR,
+"Cannot rename a file to a file system on another device." )
+ER2( PR_DIRECTORY_CORRUPTED_ERROR,
+"The directory object in the file system is corrupted." )
+ER2( PR_FILE_EXISTS_ERROR,
+"Cannot create or rename a filename that already exists." )
+ER2( PR_MAX_DIRECTORY_ENTRIES_ERROR,
+"Directory is full. No additional filenames may be added." )
+ER2( PR_INVALID_DEVICE_STATE_ERROR,
+"The required device was in an invalid state." )
+ER2( PR_DEVICE_IS_LOCKED_ERROR, "The device is locked." )
+ER2( PR_NO_MORE_FILES_ERROR, "No more entries in the directory." )
+ER2( PR_END_OF_FILE_ERROR, "Encountered end of file." )
+ER2( PR_FILE_SEEK_ERROR, "Seek error." )
+ER2( PR_FILE_IS_BUSY_ERROR, "The file is busy." )
+ER2( PR_IN_PROGRESS_ERROR,
+"Operation is still in progress (probably a non-blocking connect)." )
+ER2( PR_ALREADY_INITIATED_ERROR,
+"Operation has already been initiated (probably a non-blocking connect)." )
+
+#ifdef PR_GROUP_EMPTY_ERROR
+ER2( PR_GROUP_EMPTY_ERROR, "The wait group is empty." )
+#endif
+
+#ifdef PR_INVALID_STATE_ERROR
+ER2( PR_INVALID_STATE_ERROR, "Object state improper for request." )
+#endif
+
+#ifdef PR_NETWORK_DOWN_ERROR
+ER2( PR_NETWORK_DOWN_ERROR, "Network is down." )
+#endif
+
+#ifdef PR_SOCKET_SHUTDOWN_ERROR
+ER2( PR_SOCKET_SHUTDOWN_ERROR, "The socket was previously shut down." )
+#endif
+
+#ifdef PR_CONNECT_ABORTED_ERROR
+ER2( PR_CONNECT_ABORTED_ERROR, "TCP Connection aborted." )
+#endif
+
+#ifdef PR_HOST_UNREACHABLE_ERROR
+ER2( PR_HOST_UNREACHABLE_ERROR, "Host is unreachable." )
+#endif
+
+/* always last */
+ER2( PR_MAX_ERROR, "Placeholder for the end of the list" )
diff --git a/base/native-tools/src/tkstool/SECerrs.h b/base/native-tools/src/tkstool/SECerrs.h
new file mode 100644
index 000000000..55858b98f
--- /dev/null
+++ b/base/native-tools/src/tkstool/SECerrs.h
@@ -0,0 +1,523 @@
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/SECerrs.h
+ */
+
+/* General security error codes */
+/* Caller must #include "secerr.h" */
+
+ER3(SEC_ERROR_IO, SEC_ERROR_BASE + 0,
+"An I/O error occurred during security authorization.")
+
+ER3(SEC_ERROR_LIBRARY_FAILURE, SEC_ERROR_BASE + 1,
+"security library failure.")
+
+ER3(SEC_ERROR_BAD_DATA, SEC_ERROR_BASE + 2,
+"security library: received bad data.")
+
+ER3(SEC_ERROR_OUTPUT_LEN, SEC_ERROR_BASE + 3,
+"security library: output length error.")
+
+ER3(SEC_ERROR_INPUT_LEN, SEC_ERROR_BASE + 4,
+"security library has experienced an input length error.")
+
+ER3(SEC_ERROR_INVALID_ARGS, SEC_ERROR_BASE + 5,
+"security library: invalid arguments.")
+
+ER3(SEC_ERROR_INVALID_ALGORITHM, SEC_ERROR_BASE + 6,
+"security library: invalid algorithm.")
+
+ER3(SEC_ERROR_INVALID_AVA, SEC_ERROR_BASE + 7,
+"security library: invalid AVA.")
+
+ER3(SEC_ERROR_INVALID_TIME, SEC_ERROR_BASE + 8,
+"Improperly formatted time string.")
+
+ER3(SEC_ERROR_BAD_DER, SEC_ERROR_BASE + 9,
+"security library: improperly formatted DER-encoded message.")
+
+ER3(SEC_ERROR_BAD_SIGNATURE, SEC_ERROR_BASE + 10,
+"Peer's certificate has an invalid signature.")
+
+ER3(SEC_ERROR_EXPIRED_CERTIFICATE, SEC_ERROR_BASE + 11,
+"Peer's Certificate has expired.")
+
+ER3(SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_BASE + 12,
+"Peer's Certificate has been revoked.")
+
+ER3(SEC_ERROR_UNKNOWN_ISSUER, SEC_ERROR_BASE + 13,
+"Peer's Certificate issuer is not recognized.")
+
+ER3(SEC_ERROR_BAD_KEY, SEC_ERROR_BASE + 14,
+"Peer's public key is invalid.")
+
+ER3(SEC_ERROR_BAD_PASSWORD, SEC_ERROR_BASE + 15,
+"The security password entered is incorrect.")
+
+ER3(SEC_ERROR_RETRY_PASSWORD, SEC_ERROR_BASE + 16,
+"New password entered incorrectly. Please try again.")
+
+ER3(SEC_ERROR_NO_NODELOCK, SEC_ERROR_BASE + 17,
+"security library: no nodelock.")
+
+ER3(SEC_ERROR_BAD_DATABASE, SEC_ERROR_BASE + 18,
+"security library: bad database.")
+
+ER3(SEC_ERROR_NO_MEMORY, SEC_ERROR_BASE + 19,
+"security library: memory allocation failure.")
+
+ER3(SEC_ERROR_UNTRUSTED_ISSUER, SEC_ERROR_BASE + 20,
+"Peer's certificate issuer has been marked as not trusted by the user.")
+
+ER3(SEC_ERROR_UNTRUSTED_CERT, SEC_ERROR_BASE + 21,
+"Peer's certificate has been marked as not trusted by the user.")
+
+ER3(SEC_ERROR_DUPLICATE_CERT, (SEC_ERROR_BASE + 22),
+"Certificate already exists in your database.")
+
+ER3(SEC_ERROR_DUPLICATE_CERT_NAME, (SEC_ERROR_BASE + 23),
+"Downloaded certificate's name duplicates one already in your database.")
+
+ER3(SEC_ERROR_ADDING_CERT, (SEC_ERROR_BASE + 24),
+"Error adding certificate to database.")
+
+ER3(SEC_ERROR_FILING_KEY, (SEC_ERROR_BASE + 25),
+"Error refiling the key for this certificate.")
+
+ER3(SEC_ERROR_NO_KEY, (SEC_ERROR_BASE + 26),
+"The private key for this certificate cannot be found in key database")
+
+ER3(SEC_ERROR_CERT_VALID, (SEC_ERROR_BASE + 27),
+"This certificate is valid.")
+
+ER3(SEC_ERROR_CERT_NOT_VALID, (SEC_ERROR_BASE + 28),
+"This certificate is not valid.")
+
+ER3(SEC_ERROR_CERT_NO_RESPONSE, (SEC_ERROR_BASE + 29),
+"Cert Library: No Response")
+
+ER3(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE, (SEC_ERROR_BASE + 30),
+"The certificate issuer's certificate has expired. Check your system date and time.")
+
+ER3(SEC_ERROR_CRL_EXPIRED, (SEC_ERROR_BASE + 31),
+"The CRL for the certificate's issuer has expired. Update it or check your system data and time.")
+
+ER3(SEC_ERROR_CRL_BAD_SIGNATURE, (SEC_ERROR_BASE + 32),
+"The CRL for the certificate's issuer has an invalid signature.")
+
+ER3(SEC_ERROR_CRL_INVALID, (SEC_ERROR_BASE + 33),
+"New CRL has an invalid format.")
+
+ER3(SEC_ERROR_EXTENSION_VALUE_INVALID, (SEC_ERROR_BASE + 34),
+"Certificate extension value is invalid.")
+
+ER3(SEC_ERROR_EXTENSION_NOT_FOUND, (SEC_ERROR_BASE + 35),
+"Certificate extension not found.")
+
+ER3(SEC_ERROR_CA_CERT_INVALID, (SEC_ERROR_BASE + 36),
+"Issuer certificate is invalid.")
+
+ER3(SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID, (SEC_ERROR_BASE + 37),
+"Certificate path length constraint is invalid.")
+
+ER3(SEC_ERROR_CERT_USAGES_INVALID, (SEC_ERROR_BASE + 38),
+"Certificate usages field is invalid.")
+
+ER3(SEC_INTERNAL_ONLY, (SEC_ERROR_BASE + 39),
+"**Internal ONLY module**")
+
+ER3(SEC_ERROR_INVALID_KEY, (SEC_ERROR_BASE + 40),
+"The key does not support the requested operation.")
+
+ER3(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 41),
+"Certificate contains unknown critical extension.")
+
+ER3(SEC_ERROR_OLD_CRL, (SEC_ERROR_BASE + 42),
+"New CRL is not later than the current one.")
+
+ER3(SEC_ERROR_NO_EMAIL_CERT, (SEC_ERROR_BASE + 43),
+"Not encrypted or signed: you do not yet have an email certificate.")
+
+ER3(SEC_ERROR_NO_RECIPIENT_CERTS_QUERY, (SEC_ERROR_BASE + 44),
+"Not encrypted: you do not have certificates for each of the recipients.")
+
+ER3(SEC_ERROR_NOT_A_RECIPIENT, (SEC_ERROR_BASE + 45),
+"Cannot decrypt: you are not a recipient, or matching certificate and \
+private key not found.")
+
+ER3(SEC_ERROR_PKCS7_KEYALG_MISMATCH, (SEC_ERROR_BASE + 46),
+"Cannot decrypt: key encryption algorithm does not match your certificate.")
+
+ER3(SEC_ERROR_PKCS7_BAD_SIGNATURE, (SEC_ERROR_BASE + 47),
+"Signature verification failed: no signer found, too many signers found, \
+or improper or corrupted data.")
+
+ER3(SEC_ERROR_UNSUPPORTED_KEYALG, (SEC_ERROR_BASE + 48),
+"Unsupported or unknown key algorithm.")
+
+ER3(SEC_ERROR_DECRYPTION_DISALLOWED, (SEC_ERROR_BASE + 49),
+"Cannot decrypt: encrypted using a disallowed algorithm or key size.")
+
+
+/* Fortezza Alerts */
+ER3(XP_SEC_FORTEZZA_BAD_CARD, (SEC_ERROR_BASE + 50),
+"Fortezza card has not been properly initialized. \
+Please remove it and return it to your issuer.")
+
+ER3(XP_SEC_FORTEZZA_NO_CARD, (SEC_ERROR_BASE + 51),
+"No Fortezza cards Found")
+
+ER3(XP_SEC_FORTEZZA_NONE_SELECTED, (SEC_ERROR_BASE + 52),
+"No Fortezza card selected")
+
+ER3(XP_SEC_FORTEZZA_MORE_INFO, (SEC_ERROR_BASE + 53),
+"Please select a personality to get more info on")
+
+ER3(XP_SEC_FORTEZZA_PERSON_NOT_FOUND, (SEC_ERROR_BASE + 54),
+"Personality not found")
+
+ER3(XP_SEC_FORTEZZA_NO_MORE_INFO, (SEC_ERROR_BASE + 55),
+"No more information on that Personality")
+
+ER3(XP_SEC_FORTEZZA_BAD_PIN, (SEC_ERROR_BASE + 56),
+"Invalid Pin")
+
+ER3(XP_SEC_FORTEZZA_PERSON_ERROR, (SEC_ERROR_BASE + 57),
+"Couldn't initialize Fortezza personalities.")
+/* end fortezza alerts. */
+
+ER3(SEC_ERROR_NO_KRL, (SEC_ERROR_BASE + 58),
+"No KRL for this site's certificate has been found.")
+
+ER3(SEC_ERROR_KRL_EXPIRED, (SEC_ERROR_BASE + 59),
+"The KRL for this site's certificate has expired.")
+
+ER3(SEC_ERROR_KRL_BAD_SIGNATURE, (SEC_ERROR_BASE + 60),
+"The KRL for this site's certificate has an invalid signature.")
+
+ER3(SEC_ERROR_REVOKED_KEY, (SEC_ERROR_BASE + 61),
+"The key for this site's certificate has been revoked.")
+
+ER3(SEC_ERROR_KRL_INVALID, (SEC_ERROR_BASE + 62),
+"New KRL has an invalid format.")
+
+ER3(SEC_ERROR_NEED_RANDOM, (SEC_ERROR_BASE + 63),
+"security library: need random data.")
+
+ER3(SEC_ERROR_NO_MODULE, (SEC_ERROR_BASE + 64),
+"security library: no security module can perform the requested operation.")
+
+ER3(SEC_ERROR_NO_TOKEN, (SEC_ERROR_BASE + 65),
+"The security card or token does not exist, needs to be initialized, or has been removed.")
+
+ER3(SEC_ERROR_READ_ONLY, (SEC_ERROR_BASE + 66),
+"security library: read-only database.")
+
+ER3(SEC_ERROR_NO_SLOT_SELECTED, (SEC_ERROR_BASE + 67),
+"No slot or token was selected.")
+
+ER3(SEC_ERROR_CERT_NICKNAME_COLLISION, (SEC_ERROR_BASE + 68),
+"A certificate with the same nickname already exists.")
+
+ER3(SEC_ERROR_KEY_NICKNAME_COLLISION, (SEC_ERROR_BASE + 69),
+"A key with the same nickname already exists.")
+
+ER3(SEC_ERROR_SAFE_NOT_CREATED, (SEC_ERROR_BASE + 70),
+"error while creating safe object")
+
+ER3(SEC_ERROR_BAGGAGE_NOT_CREATED, (SEC_ERROR_BASE + 71),
+"error while creating baggage object")
+
+ER3(XP_JAVA_REMOVE_PRINCIPAL_ERROR, (SEC_ERROR_BASE + 72),
+"Couldn't remove the principal")
+
+ER3(XP_JAVA_DELETE_PRIVILEGE_ERROR, (SEC_ERROR_BASE + 73),
+"Couldn't delete the privilege")
+
+ER3(XP_JAVA_CERT_NOT_EXISTS_ERROR, (SEC_ERROR_BASE + 74),
+"This principal doesn't have a certificate")
+
+ER3(SEC_ERROR_BAD_EXPORT_ALGORITHM, (SEC_ERROR_BASE + 75),
+"Required algorithm is not allowed.")
+
+ER3(SEC_ERROR_EXPORTING_CERTIFICATES, (SEC_ERROR_BASE + 76),
+"Error attempting to export certificates.")
+
+ER3(SEC_ERROR_IMPORTING_CERTIFICATES, (SEC_ERROR_BASE + 77),
+"Error attempting to import certificates.")
+
+ER3(SEC_ERROR_PKCS12_DECODING_PFX, (SEC_ERROR_BASE + 78),
+"Unable to import. Decoding error. File not valid.")
+
+ER3(SEC_ERROR_PKCS12_INVALID_MAC, (SEC_ERROR_BASE + 79),
+"Unable to import. Invalid MAC. Incorrect password or corrupt file.")
+
+ER3(SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM, (SEC_ERROR_BASE + 80),
+"Unable to import. MAC algorithm not supported.")
+
+ER3(SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE,(SEC_ERROR_BASE + 81),
+"Unable to import. Only password integrity and privacy modes supported.")
+
+ER3(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE, (SEC_ERROR_BASE + 82),
+"Unable to import. File structure is corrupt.")
+
+ER3(SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM, (SEC_ERROR_BASE + 83),
+"Unable to import. Encryption algorithm not supported.")
+
+ER3(SEC_ERROR_PKCS12_UNSUPPORTED_VERSION, (SEC_ERROR_BASE + 84),
+"Unable to import. File version not supported.")
+
+ER3(SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT,(SEC_ERROR_BASE + 85),
+"Unable to import. Incorrect privacy password.")
+
+ER3(SEC_ERROR_PKCS12_CERT_COLLISION, (SEC_ERROR_BASE + 86),
+"Unable to import. Same nickname already exists in database.")
+
+ER3(SEC_ERROR_USER_CANCELLED, (SEC_ERROR_BASE + 87),
+"The user pressed cancel.")
+
+ER3(SEC_ERROR_PKCS12_DUPLICATE_DATA, (SEC_ERROR_BASE + 88),
+"Not imported, already in database.")
+
+ER3(SEC_ERROR_MESSAGE_SEND_ABORTED, (SEC_ERROR_BASE + 89),
+"Message not sent.")
+
+ER3(SEC_ERROR_INADEQUATE_KEY_USAGE, (SEC_ERROR_BASE + 90),
+"Certificate key usage inadequate for attempted operation.")
+
+ER3(SEC_ERROR_INADEQUATE_CERT_TYPE, (SEC_ERROR_BASE + 91),
+"Certificate type not approved for application.")
+
+ER3(SEC_ERROR_CERT_ADDR_MISMATCH, (SEC_ERROR_BASE + 92),
+"Address in signing certificate does not match address in message headers.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY, (SEC_ERROR_BASE + 93),
+"Unable to import. Error attempting to import private key.")
+
+ER3(SEC_ERROR_PKCS12_IMPORTING_CERT_CHAIN, (SEC_ERROR_BASE + 94),
+"Unable to import. Error attempting to import certificate chain.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME, (SEC_ERROR_BASE + 95),
+"Unable to export. Unable to locate certificate or key by nickname.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY, (SEC_ERROR_BASE + 96),
+"Unable to export. Private Key could not be located and exported.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_WRITE, (SEC_ERROR_BASE + 97),
+"Unable to export. Unable to write the export file.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_READ, (SEC_ERROR_BASE + 98),
+"Unable to import. Unable to read the import file.")
+
+ER3(SEC_ERROR_PKCS12_KEY_DATABASE_NOT_INITIALIZED, (SEC_ERROR_BASE + 99),
+"Unable to export. Key database corrupt or deleted.")
+
+ER3(SEC_ERROR_KEYGEN_FAIL, (SEC_ERROR_BASE + 100),
+"Unable to generate public/private key pair.")
+
+ER3(SEC_ERROR_INVALID_PASSWORD, (SEC_ERROR_BASE + 101),
+"Password entered is invalid. Please pick a different one.")
+
+ER3(SEC_ERROR_RETRY_OLD_PASSWORD, (SEC_ERROR_BASE + 102),
+"Old password entered incorrectly. Please try again.")
+
+ER3(SEC_ERROR_BAD_NICKNAME, (SEC_ERROR_BASE + 103),
+"Certificate nickname already in use.")
+
+ER3(SEC_ERROR_NOT_FORTEZZA_ISSUER, (SEC_ERROR_BASE + 104),
+"Peer FORTEZZA chain has a non-FORTEZZA Certificate.")
+
+ER3(SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY, (SEC_ERROR_BASE + 105),
+"A sensitive key cannot be moved to the slot where it is needed.")
+
+ER3(SEC_ERROR_JS_INVALID_MODULE_NAME, (SEC_ERROR_BASE + 106),
+"Invalid module name.")
+
+ER3(SEC_ERROR_JS_INVALID_DLL, (SEC_ERROR_BASE + 107),
+"Invalid module path/filename")
+
+ER3(SEC_ERROR_JS_ADD_MOD_FAILURE, (SEC_ERROR_BASE + 108),
+"Unable to add module")
+
+ER3(SEC_ERROR_JS_DEL_MOD_FAILURE, (SEC_ERROR_BASE + 109),
+"Unable to delete module")
+
+ER3(SEC_ERROR_OLD_KRL, (SEC_ERROR_BASE + 110),
+"New KRL is not later than the current one.")
+
+ER3(SEC_ERROR_CKL_CONFLICT, (SEC_ERROR_BASE + 111),
+"New CKL has different issuer than current CKL. Delete current CKL.")
+
+ER3(SEC_ERROR_CERT_NOT_IN_NAME_SPACE, (SEC_ERROR_BASE + 112),
+"The Certifying Authority for this certificate is not permitted to issue a \
+certificate with this name.")
+
+ER3(SEC_ERROR_KRL_NOT_YET_VALID, (SEC_ERROR_BASE + 113),
+"The key revocation list for this certificate is not yet valid.")
+
+ER3(SEC_ERROR_CRL_NOT_YET_VALID, (SEC_ERROR_BASE + 114),
+"The certificate revocation list for this certificate is not yet valid.")
+
+ER3(SEC_ERROR_UNKNOWN_CERT, (SEC_ERROR_BASE + 115),
+"The requested certificate could not be found.")
+
+ER3(SEC_ERROR_UNKNOWN_SIGNER, (SEC_ERROR_BASE + 116),
+"The signer's certificate could not be found.")
+
+ER3(SEC_ERROR_CERT_BAD_ACCESS_LOCATION, (SEC_ERROR_BASE + 117),
+"The location for the certificate status server has invalid format.")
+
+ER3(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE, (SEC_ERROR_BASE + 118),
+"The OCSP response cannot be fully decoded; it is of an unknown type.")
+
+ER3(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE, (SEC_ERROR_BASE + 119),
+"The OCSP server returned unexpected/invalid HTTP data.")
+
+ER3(SEC_ERROR_OCSP_MALFORMED_REQUEST, (SEC_ERROR_BASE + 120),
+"The OCSP server found the request to be corrupted or improperly formed.")
+
+ER3(SEC_ERROR_OCSP_SERVER_ERROR, (SEC_ERROR_BASE + 121),
+"The OCSP server experienced an internal error.")
+
+ER3(SEC_ERROR_OCSP_TRY_SERVER_LATER, (SEC_ERROR_BASE + 122),
+"The OCSP server suggests trying again later.")
+
+ER3(SEC_ERROR_OCSP_REQUEST_NEEDS_SIG, (SEC_ERROR_BASE + 123),
+"The OCSP server requires a signature on this request.")
+
+ER3(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST, (SEC_ERROR_BASE + 124),
+"The OCSP server has refused this request as unauthorized.")
+
+ER3(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS, (SEC_ERROR_BASE + 125),
+"The OCSP server returned an unrecognizable status.")
+
+ER3(SEC_ERROR_OCSP_UNKNOWN_CERT, (SEC_ERROR_BASE + 126),
+"The OCSP server has no status for the certificate.")
+
+ER3(SEC_ERROR_OCSP_NOT_ENABLED, (SEC_ERROR_BASE + 127),
+"You must enable OCSP before performing this operation.")
+
+ER3(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER, (SEC_ERROR_BASE + 128),
+"You must set the OCSP default responder before performing this operation.")
+
+ER3(SEC_ERROR_OCSP_MALFORMED_RESPONSE, (SEC_ERROR_BASE + 129),
+"The response from the OCSP server was corrupted or improperly formed.")
+
+ER3(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE, (SEC_ERROR_BASE + 130),
+"The signer of the OCSP response is not authorized to give status for \
+this certificate.")
+
+ER3(SEC_ERROR_OCSP_FUTURE_RESPONSE, (SEC_ERROR_BASE + 131),
+"The OCSP response is not yet valid (contains a date in the future).")
+
+ER3(SEC_ERROR_OCSP_OLD_RESPONSE, (SEC_ERROR_BASE + 132),
+"The OCSP response contains out-of-date information.")
+
+ER3(SEC_ERROR_DIGEST_NOT_FOUND, (SEC_ERROR_BASE + 133),
+"The CMS or PKCS #7 Digest was not found in signed message.")
+
+ER3(SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE, (SEC_ERROR_BASE + 134),
+"The CMS or PKCS #7 Message type is unsupported.")
+
+ER3(SEC_ERROR_MODULE_STUCK, (SEC_ERROR_BASE + 135),
+"PKCS #11 module could not be removed because it is still in use.")
+
+ER3(SEC_ERROR_BAD_TEMPLATE, (SEC_ERROR_BASE + 136),
+"Could not decode ASN.1 data. Specified template was invalid.")
+
+ER3(SEC_ERROR_CRL_NOT_FOUND, (SEC_ERROR_BASE + 137),
+"No matching CRL was found.")
+
+ER3(SEC_ERROR_REUSED_ISSUER_AND_SERIAL, (SEC_ERROR_BASE + 138),
+"You are attempting to import a cert with the same issuer/serial as \
+an existing cert, but that is not the same cert.")
+
+ER3(SEC_ERROR_BUSY, (SEC_ERROR_BASE + 139),
+"NSS could not shutdown. Objects are still in use.")
+
+ER3(SEC_ERROR_EXTRA_INPUT, (SEC_ERROR_BASE + 140),
+"DER-encoded message contained extra unused data.")
+
+ER3(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE, (SEC_ERROR_BASE + 141),
+"Unsupported elliptic curve.")
+
+ER3(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM, (SEC_ERROR_BASE + 142),
+"Unsupported elliptic curve point form.")
+
+ER3(SEC_ERROR_UNRECOGNIZED_OID, (SEC_ERROR_BASE + 143),
+"Unrecognized Object IDentifier.")
+
+ER3(SEC_ERROR_OCSP_INVALID_SIGNING_CERT, (SEC_ERROR_BASE + 144),
+"Invalid OCSP signing certificate in OCSP response.")
+
+ER3(SEC_ERROR_REVOKED_CERTIFICATE_CRL, (SEC_ERROR_BASE + 145),
+"Certificate is revoked in issuer's certificate revocation list.")
+
+ER3(SEC_ERROR_REVOKED_CERTIFICATE_OCSP, (SEC_ERROR_BASE + 146),
+"Issuer's OCSP responder reports certificate is revoked.")
+
+ER3(SEC_ERROR_CRL_INVALID_VERSION, (SEC_ERROR_BASE + 147),
+"Issuer's Certificate Revocation List has an unknown version number.")
+
+ER3(SEC_ERROR_CRL_V1_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 148),
+"Issuer's V1 Certificate Revocation List has a critical extension.")
+
+ER3(SEC_ERROR_CRL_UNKNOWN_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 149),
+"Issuer's V2 Certificate Revocation List has an unknown critical extension.")
+
+ER3(SEC_ERROR_UNKNOWN_OBJECT_TYPE, (SEC_ERROR_BASE + 150),
+"Unknown object type specified.")
+
+ER3(SEC_ERROR_INCOMPATIBLE_PKCS11, (SEC_ERROR_BASE + 151),
+"PKCS #11 driver violates the spec in an incompatible way.")
+
+ER3(SEC_ERROR_NO_EVENT, (SEC_ERROR_BASE + 152),
+"No new slot event is available at this time.")
+
+ER3(SEC_ERROR_CRL_ALREADY_EXISTS, (SEC_ERROR_BASE + 153),
+"CRL already exists.")
+
+ER3(SEC_ERROR_NOT_INITIALIZED, (SEC_ERROR_BASE + 154),
+"NSS is not initialized.")
+
+ER3(SEC_ERROR_TOKEN_NOT_LOGGED_IN, (SEC_ERROR_BASE + 155),
+"The operation failed because the PKCS#11 token is not logged in.")
+
diff --git a/base/native-tools/src/tkstool/SSLerrs.h b/base/native-tools/src/tkstool/SSLerrs.h
new file mode 100644
index 000000000..d6ec13b47
--- /dev/null
+++ b/base/native-tools/src/tkstool/SSLerrs.h
@@ -0,0 +1,393 @@
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/SSLerrs.h
+ */
+
+/* SSL-specific security error codes */
+/* caller must include "sslerr.h" */
+
+ER3(SSL_ERROR_EXPORT_ONLY_SERVER, SSL_ERROR_BASE + 0,
+"Unable to communicate securely. Peer does not support high-grade encryption.")
+
+ER3(SSL_ERROR_US_ONLY_SERVER, SSL_ERROR_BASE + 1,
+"Unable to communicate securely. Peer requires high-grade encryption which is not supported.")
+
+ER3(SSL_ERROR_NO_CYPHER_OVERLAP, SSL_ERROR_BASE + 2,
+"Cannot communicate securely with peer: no common encryption algorithm(s).")
+
+ER3(SSL_ERROR_NO_CERTIFICATE, SSL_ERROR_BASE + 3,
+"Unable to find the certificate or key necessary for authentication.")
+
+ER3(SSL_ERROR_BAD_CERTIFICATE, SSL_ERROR_BASE + 4,
+"Unable to communicate securely with peer: peers's certificate was rejected.")
+
+/* unused (SSL_ERROR_BASE + 5),*/
+
+ER3(SSL_ERROR_BAD_CLIENT, SSL_ERROR_BASE + 6,
+"The server has encountered bad data from the client.")
+
+ER3(SSL_ERROR_BAD_SERVER, SSL_ERROR_BASE + 7,
+"The client has encountered bad data from the server.")
+
+ER3(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE, SSL_ERROR_BASE + 8,
+"Unsupported certificate type.")
+
+ER3(SSL_ERROR_UNSUPPORTED_VERSION, SSL_ERROR_BASE + 9,
+"Peer using unsupported version of security protocol.")
+
+/* unused (SSL_ERROR_BASE + 10),*/
+
+ER3(SSL_ERROR_WRONG_CERTIFICATE, SSL_ERROR_BASE + 11,
+"Client authentication failed: private key in key database does not match public key in certificate database.")
+
+ER3(SSL_ERROR_BAD_CERT_DOMAIN, SSL_ERROR_BASE + 12,
+"Unable to communicate securely with peer: requested domain name does not match the server's certificate.")
+
+/* SSL_ERROR_POST_WARNING (SSL_ERROR_BASE + 13),
+ defined in sslerr.h
+*/
+
+ER3(SSL_ERROR_SSL2_DISABLED, (SSL_ERROR_BASE + 14),
+"Peer only supports SSL version 2, which is locally disabled.")
+
+
+ER3(SSL_ERROR_BAD_MAC_READ, (SSL_ERROR_BASE + 15),
+"SSL received a record with an incorrect Message Authentication Code.")
+
+ER3(SSL_ERROR_BAD_MAC_ALERT, (SSL_ERROR_BASE + 16),
+"SSL peer reports incorrect Message Authentication Code.")
+
+ER3(SSL_ERROR_BAD_CERT_ALERT, (SSL_ERROR_BASE + 17),
+"SSL peer cannot verify your certificate.")
+
+ER3(SSL_ERROR_REVOKED_CERT_ALERT, (SSL_ERROR_BASE + 18),
+"SSL peer rejected your certificate as revoked.")
+
+ER3(SSL_ERROR_EXPIRED_CERT_ALERT, (SSL_ERROR_BASE + 19),
+"SSL peer rejected your certificate as expired.")
+
+ER3(SSL_ERROR_SSL_DISABLED, (SSL_ERROR_BASE + 20),
+"Cannot connect: SSL is disabled.")
+
+ER3(SSL_ERROR_FORTEZZA_PQG, (SSL_ERROR_BASE + 21),
+"Cannot connect: SSL peer is in another FORTEZZA domain.")
+
+
+ER3(SSL_ERROR_UNKNOWN_CIPHER_SUITE , (SSL_ERROR_BASE + 22),
+"An unknown SSL cipher suite has been requested.")
+
+ER3(SSL_ERROR_NO_CIPHERS_SUPPORTED , (SSL_ERROR_BASE + 23),
+"No cipher suites are present and enabled in this program.")
+
+ER3(SSL_ERROR_BAD_BLOCK_PADDING , (SSL_ERROR_BASE + 24),
+"SSL received a record with bad block padding.")
+
+ER3(SSL_ERROR_RX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 25),
+"SSL received a record that exceeded the maximum permissible length.")
+
+ER3(SSL_ERROR_TX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 26),
+"SSL attempted to send a record that exceeded the maximum permissible length.")
+
+/*
+ * Received a malformed (too long or short or invalid content) SSL handshake.
+ */
+ER3(SSL_ERROR_RX_MALFORMED_HELLO_REQUEST , (SSL_ERROR_BASE + 27),
+"SSL received a malformed Hello Request handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO , (SSL_ERROR_BASE + 28),
+"SSL received a malformed Client Hello handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_SERVER_HELLO , (SSL_ERROR_BASE + 29),
+"SSL received a malformed Server Hello handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CERTIFICATE , (SSL_ERROR_BASE + 30),
+"SSL received a malformed Certificate handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 31),
+"SSL received a malformed Server Key Exchange handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CERT_REQUEST , (SSL_ERROR_BASE + 32),
+"SSL received a malformed Certificate Request handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_HELLO_DONE , (SSL_ERROR_BASE + 33),
+"SSL received a malformed Server Hello Done handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CERT_VERIFY , (SSL_ERROR_BASE + 34),
+"SSL received a malformed Certificate Verify handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 35),
+"SSL received a malformed Client Key Exchange handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_FINISHED , (SSL_ERROR_BASE + 36),
+"SSL received a malformed Finished handshake message.")
+
+/*
+ * Received a malformed (too long or short) SSL record.
+ */
+ER3(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER , (SSL_ERROR_BASE + 37),
+"SSL received a malformed Change Cipher Spec record.")
+
+ER3(SSL_ERROR_RX_MALFORMED_ALERT , (SSL_ERROR_BASE + 38),
+"SSL received a malformed Alert record.")
+
+ER3(SSL_ERROR_RX_MALFORMED_HANDSHAKE , (SSL_ERROR_BASE + 39),
+"SSL received a malformed Handshake record.")
+
+ER3(SSL_ERROR_RX_MALFORMED_APPLICATION_DATA , (SSL_ERROR_BASE + 40),
+"SSL received a malformed Application Data record.")
+
+/*
+ * Received an SSL handshake that was inappropriate for the state we're in.
+ * E.g. Server received message from server, or wrong state in state machine.
+ */
+ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST , (SSL_ERROR_BASE + 41),
+"SSL received an unexpected Hello Request handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO , (SSL_ERROR_BASE + 42),
+"SSL received an unexpected Client Hello handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO , (SSL_ERROR_BASE + 43),
+"SSL received an unexpected Server Hello handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CERTIFICATE , (SSL_ERROR_BASE + 44),
+"SSL received an unexpected Certificate handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 45),
+"SSL received an unexpected Server Key Exchange handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST , (SSL_ERROR_BASE + 46),
+"SSL received an unexpected Certificate Request handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE , (SSL_ERROR_BASE + 47),
+"SSL received an unexpected Server Hello Done handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY , (SSL_ERROR_BASE + 48),
+"SSL received an unexpected Certificate Verify handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 49),
+"SSL received an unexpected Cllient Key Exchange handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_FINISHED , (SSL_ERROR_BASE + 50),
+"SSL received an unexpected Finished handshake message.")
+
+/*
+ * Received an SSL record that was inappropriate for the state we're in.
+ */
+ER3(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER , (SSL_ERROR_BASE + 51),
+"SSL received an unexpected Change Cipher Spec record.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 52),
+"SSL received an unexpected Alert record.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE , (SSL_ERROR_BASE + 53),
+"SSL received an unexpected Handshake record.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA, (SSL_ERROR_BASE + 54),
+"SSL received an unexpected Application Data record.")
+
+/*
+ * Received record/message with unknown discriminant.
+ */
+ER3(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE , (SSL_ERROR_BASE + 55),
+"SSL received a record with an unknown content type.")
+
+ER3(SSL_ERROR_RX_UNKNOWN_HANDSHAKE , (SSL_ERROR_BASE + 56),
+"SSL received a handshake message with an unknown message type.")
+
+ER3(SSL_ERROR_RX_UNKNOWN_ALERT , (SSL_ERROR_BASE + 57),
+"SSL received an alert record with an unknown alert description.")
+
+/*
+ * Received an alert reporting what we did wrong. (more alerts above)
+ */
+ER3(SSL_ERROR_CLOSE_NOTIFY_ALERT , (SSL_ERROR_BASE + 58),
+"SSL peer has closed this connection.")
+
+ER3(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 59),
+"SSL peer was not expecting a handshake message it received.")
+
+ER3(SSL_ERROR_DECOMPRESSION_FAILURE_ALERT , (SSL_ERROR_BASE + 60),
+"SSL peer was unable to succesfully decompress an SSL record it received.")
+
+ER3(SSL_ERROR_HANDSHAKE_FAILURE_ALERT , (SSL_ERROR_BASE + 61),
+"SSL peer was unable to negotiate an acceptable set of security parameters.")
+
+ER3(SSL_ERROR_ILLEGAL_PARAMETER_ALERT , (SSL_ERROR_BASE + 62),
+"SSL peer rejected a handshake message for unacceptable content.")
+
+ER3(SSL_ERROR_UNSUPPORTED_CERT_ALERT , (SSL_ERROR_BASE + 63),
+"SSL peer does not support certificates of the type it received.")
+
+ER3(SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT , (SSL_ERROR_BASE + 64),
+"SSL peer had some unspecified issue with the certificate it received.")
+
+
+ER3(SSL_ERROR_GENERATE_RANDOM_FAILURE , (SSL_ERROR_BASE + 65),
+"SSL experienced a failure of its random number generator.")
+
+ER3(SSL_ERROR_SIGN_HASHES_FAILURE , (SSL_ERROR_BASE + 66),
+"Unable to digitally sign data required to verify your certificate.")
+
+ER3(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE , (SSL_ERROR_BASE + 67),
+"SSL was unable to extract the public key from the peer's certificate.")
+
+ER3(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 68),
+"Unspecified failure while processing SSL Server Key Exchange handshake.")
+
+ER3(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 69),
+"Unspecified failure while processing SSL Client Key Exchange handshake.")
+
+ER3(SSL_ERROR_ENCRYPTION_FAILURE , (SSL_ERROR_BASE + 70),
+"Bulk data encryption algorithm failed in selected cipher suite.")
+
+ER3(SSL_ERROR_DECRYPTION_FAILURE , (SSL_ERROR_BASE + 71),
+"Bulk data decryption algorithm failed in selected cipher suite.")
+
+ER3(SSL_ERROR_SOCKET_WRITE_FAILURE , (SSL_ERROR_BASE + 72),
+"Attempt to write encrypted data to underlying socket failed.")
+
+ER3(SSL_ERROR_MD5_DIGEST_FAILURE , (SSL_ERROR_BASE + 73),
+"MD5 digest function failed.")
+
+ER3(SSL_ERROR_SHA_DIGEST_FAILURE , (SSL_ERROR_BASE + 74),
+"SHA-1 digest function failed.")
+
+ER3(SSL_ERROR_MAC_COMPUTATION_FAILURE , (SSL_ERROR_BASE + 75),
+"MAC computation failed.")
+
+ER3(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE , (SSL_ERROR_BASE + 76),
+"Failure to create Symmetric Key context.")
+
+ER3(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE , (SSL_ERROR_BASE + 77),
+"Failure to unwrap the Symmetric key in Client Key Exchange message.")
+
+ER3(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED , (SSL_ERROR_BASE + 78),
+"SSL Server attempted to use domestic-grade public key with export cipher suite.")
+
+ER3(SSL_ERROR_IV_PARAM_FAILURE , (SSL_ERROR_BASE + 79),
+"PKCS11 code failed to translate an IV into a param.")
+
+ER3(SSL_ERROR_INIT_CIPHER_SUITE_FAILURE , (SSL_ERROR_BASE + 80),
+"Failed to initialize the selected cipher suite.")
+
+ER3(SSL_ERROR_SESSION_KEY_GEN_FAILURE , (SSL_ERROR_BASE + 81),
+"Client failed to generate session keys for SSL session.")
+
+ER3(SSL_ERROR_NO_SERVER_KEY_FOR_ALG , (SSL_ERROR_BASE + 82),
+"Server has no key for the attempted key exchange algorithm.")
+
+ER3(SSL_ERROR_TOKEN_INSERTION_REMOVAL , (SSL_ERROR_BASE + 83),
+"PKCS#11 token was inserted or removed while operation was in progress.")
+
+ER3(SSL_ERROR_TOKEN_SLOT_NOT_FOUND , (SSL_ERROR_BASE + 84),
+"No PKCS#11 token could be found to do a required operation.")
+
+ER3(SSL_ERROR_NO_COMPRESSION_OVERLAP , (SSL_ERROR_BASE + 85),
+"Cannot communicate securely with peer: no common compression algorithm(s).")
+
+ER3(SSL_ERROR_HANDSHAKE_NOT_COMPLETED , (SSL_ERROR_BASE + 86),
+"Cannot initiate another SSL handshake until current handshake is complete.")
+
+ER3(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE , (SSL_ERROR_BASE + 87),
+"Received incorrect handshakes hash values from peer.")
+
+ER3(SSL_ERROR_CERT_KEA_MISMATCH , (SSL_ERROR_BASE + 88),
+"The certificate provided cannot be used with the selected key exchange algorithm.")
+
+ER3(SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA , (SSL_ERROR_BASE + 89),
+"No certificate authority is trusted for SSL client authentication.")
+
+ER3(SSL_ERROR_SESSION_NOT_FOUND , (SSL_ERROR_BASE + 90),
+"Client's SSL session ID not found in server's session cache.")
+
+ER3(SSL_ERROR_DECRYPTION_FAILED_ALERT , (SSL_ERROR_BASE + 91),
+"Peer was unable to decrypt an SSL record it received.")
+
+ER3(SSL_ERROR_RECORD_OVERFLOW_ALERT , (SSL_ERROR_BASE + 92),
+"Peer received an SSL record that was longer than is permitted.")
+
+ER3(SSL_ERROR_UNKNOWN_CA_ALERT , (SSL_ERROR_BASE + 93),
+"Peer does not recognize and trust the CA that issued your certificate.")
+
+ER3(SSL_ERROR_ACCESS_DENIED_ALERT , (SSL_ERROR_BASE + 94),
+"Peer received a valid certificate, but access was denied.")
+
+ER3(SSL_ERROR_DECODE_ERROR_ALERT , (SSL_ERROR_BASE + 95),
+"Peer could not decode an SSL handshake message.")
+
+ER3(SSL_ERROR_DECRYPT_ERROR_ALERT , (SSL_ERROR_BASE + 96),
+"Peer reports failure of signature verification or key exchange.")
+
+ER3(SSL_ERROR_EXPORT_RESTRICTION_ALERT , (SSL_ERROR_BASE + 97),
+"Peer reports negotiation not in compliance with export regulations.")
+
+ER3(SSL_ERROR_PROTOCOL_VERSION_ALERT , (SSL_ERROR_BASE + 98),
+"Peer reports incompatible or unsupported protocol version.")
+
+ER3(SSL_ERROR_INSUFFICIENT_SECURITY_ALERT , (SSL_ERROR_BASE + 99),
+"Server requires ciphers more secure than those supported by client.")
+
+ER3(SSL_ERROR_INTERNAL_ERROR_ALERT , (SSL_ERROR_BASE + 100),
+"Peer reports it experienced an internal error.")
+
+ER3(SSL_ERROR_USER_CANCELED_ALERT , (SSL_ERROR_BASE + 101),
+"Peer user canceled handshake.")
+
+ER3(SSL_ERROR_NO_RENEGOTIATION_ALERT , (SSL_ERROR_BASE + 102),
+"Peer does not permit renegotiation of SSL security parameters.")
+
+ER3(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED , (SSL_ERROR_BASE + 103),
+"SSL server cache not configured and not disabled for this socket.")
+
+ER3(SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT , (SSL_ERROR_BASE + 104),
+"SSL peer does not support requested TLS hello extension.")
+
+ER3(SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT , (SSL_ERROR_BASE + 105),
+"SSL peer could not obtain your certificate from the supplied URL.")
+
+ER3(SSL_ERROR_UNRECOGNIZED_NAME_ALERT , (SSL_ERROR_BASE + 106),
+"SSL peer has no certificate for the requested DNS name.")
+
+ER3(SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT , (SSL_ERROR_BASE + 107),
+"SSL peer was unable to get an OCSP response for its certificate.")
+
+ER3(SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT , (SSL_ERROR_BASE + 108),
+"SSL peer reported bad certificate hash value.")
diff --git a/base/native-tools/src/tkstool/delete.c b/base/native-tools/src/tkstool/delete.c
new file mode 100644
index 000000000..f40e66d16
--- /dev/null
+++ b/base/native-tools/src/tkstool/delete.c
@@ -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.
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#include "tkstool.h"
+
+static SECStatus
+DeleteKey( char *keyname,
+ PK11SymKey *key )
+{
+ char *name = NULL;
+ SECStatus rv = SECFailure;
+
+ name = PK11_GetSymKeyNickname( /* symmetric key */ key );
+ if( name == NULL ) {
+ name = PORT_Strdup( "< orphaned >" );
+ }
+
+ /* Delete this key ONLY if its name is the specified keyname */
+ /* */
+ /* NOTE: If duplicate keys are allowed to be added to an */
+ /* individual token, this function will delete */
+ /* EVERY key named by the specified keyname; */
+ /* therefore, MORE than ONE key may be DELETED from */
+ /* the specified token!!! */
+ if( PL_strcmp( keyname, name ) == 0 ) {
+ rv = PK11_DeleteTokenSymKey( /* symmetric key */ key );
+ }
+
+ PORT_Free( name );
+
+ return rv;
+}
+
+
+SECStatus
+TKS_DeleteKeys( char *progName,
+ PK11SlotInfo *slot,
+ char *keyname,
+ secuPWData *pwdata )
+{
+ int count = 0;
+ int keys_deleted = 0;
+ PK11SymKey *symKey = NULL;
+ PK11SymKey *nextSymKey = NULL;
+ SECStatus rvDelete = SECFailure;
+ SECStatus rv;
+
+ if( PK11_NeedLogin( /* slot */ slot ) ) {
+ PK11_Authenticate(
+ /* slot */ slot,
+ /* load certs */ PR_TRUE,
+ /* wincx */ pwdata );
+ }
+
+ /* Initialize the symmetric key list. */
+ symKey = PK11_ListFixedKeysInSlot(
+ /* slot */ slot,
+ /* nickname */ NULL,
+ /* wincx */ ( void *) pwdata );
+
+ /* Iterate through the symmetric key list. */
+ while( symKey != NULL ) {
+ rvDelete = DeleteKey( keyname,
+ symKey );
+ if( rvDelete != SECFailure ) {
+ keys_deleted++;
+ }
+
+ nextSymKey = PK11_GetNextSymKey( /* symmetric key */ symKey );
+ PK11_FreeSymKey( /* symmetric key */ symKey );
+ symKey = nextSymKey;
+
+ count++;
+ }
+
+ if( keys_deleted == 0 ) {
+ PR_fprintf( PR_STDOUT,
+ "\t%s: no key(s) called \"%s\" could be deleted\n",
+ progName,
+ keyname );
+
+ rv = SECFailure;
+ } else {
+ PR_fprintf( PR_STDOUT,
+ "%s: %d key(s) called \"%s\" were deleted\n",
+ progName,
+ keys_deleted,
+ keyname );
+
+ rv = SECSuccess;
+ }
+
+ return rv;
+}
+
diff --git a/base/native-tools/src/tkstool/file.c b/base/native-tools/src/tkstool/file.c
new file mode 100644
index 000000000..d757225fc
--- /dev/null
+++ b/base/native-tools/src/tkstool/file.c
@@ -0,0 +1,518 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 ---
+ */
+
+#include "tkstool.h"
+
+SECStatus
+TKS_ReadInputFileIntoSECItem( char *input,
+ char *hexInternalKeyKCV,
+ int hexInternalKeyKCVLength,
+ char *wrappedKeyName,
+ SECItem *wrappedKey )
+{
+ char buf[1];
+ PRFileDesc *fd = NULL;
+ PRInt32 c = 0;
+ PRInt32 k = 0;
+ PRInt32 count = 0;
+ PRIntn firstCount = 0;
+ PRIntn secondCount = 0;
+ PRIntn thirdCount = 0;
+ PRIntn i = 0;
+ SECItem hexWrappedKey = { siBuffer,
+ NULL,
+ 0 };
+ SECStatus status = SECFailure;
+
+ /* Create a clean new hex display buffer for this wrapped key */
+ hexWrappedKey.type = ( SECItemType ) siBuffer;
+ hexWrappedKey.len = ( ( wrappedKey->len * 2 ) + 1 );
+ hexWrappedKey.data = ( unsigned char * )
+ PORT_ZAlloc( hexWrappedKey.len );
+ if( hexWrappedKey.data == NULL ) {
+ status = SECFailure;
+ goto destroyHexWrappedKey;
+ }
+
+ /* open the input file read-only */
+ fd = PR_OpenFile( input, PR_RDONLY, 0666 );
+ if( !fd ) {
+ status = SECFailure;
+ goto destroyHexWrappedKey;
+ }
+
+ /* read in the wrapped key */
+ while( c < HEX_WRAPPED_KEY_LENGTH ) {
+ /* read in the next byte */
+ count = PR_Read( fd, buf, 1 );
+
+ /* check for EOF */
+ if( count > 0 ) {
+ /* save acceptable hex characters */
+ /* silently throw anything else away */
+ switch( *buf ) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ /* acceptable character; save it as typed */
+ hexWrappedKey.data[c] = buf[0];
+ break;
+ case 'A':
+ case 'a':
+ /* acceptable character; save uppercase version */
+ hexWrappedKey.data[c] = 'A';
+ break;
+ case 'B':
+ case 'b':
+ /* acceptable character; save uppercase version */
+ hexWrappedKey.data[c] = 'B';
+ break;
+ case 'C':
+ case 'c':
+ /* acceptable character; save uppercase version */
+ hexWrappedKey.data[c] = 'C';
+ break;
+ case 'D':
+ case 'd':
+ /* acceptable character; save uppercase version */
+ hexWrappedKey.data[c] = 'D';
+ break;
+ case 'E':
+ case 'e':
+ /* acceptable character; save uppercase version */
+ hexWrappedKey.data[c] = 'E';
+ break;
+ case 'F':
+ case 'f':
+ /* acceptable character; save uppercase version */
+ hexWrappedKey.data[c] = 'F';
+ break;
+ default:
+ /* unacceptable character; don't save it */
+ continue;
+ }
+
+ /* increment the number of wrapped key bytes read */
+ c++;
+ }
+ }
+
+ /* insure that the wrapped key was completely obtained */
+ if( c != HEX_WRAPPED_KEY_LENGTH ) {
+ status = SECFailure;
+ goto destroyHexWrappedKey;
+ }
+
+ /* Convert these wrapped key hex digits */
+ /* into the data portion of a SECItem */
+ TKS_ConvertStringOfHexCharactersIntoBitStream( ( char * ) hexWrappedKey.data,
+ ( hexWrappedKey.len - 1 ),
+ wrappedKey->data );
+
+ /* read in the wrapped key KCV */
+ while( k < HEX_WRAPPED_KEY_KCV_LENGTH ) {
+ count = PR_Read( fd, buf, 1 );
+
+ if( count > 0 ) {
+ /* save acceptable hex characters; silently */
+ /* throw anything else away */
+ switch( *buf ) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ /* acceptable character; save it as typed */
+ hexInternalKeyKCV[k] = buf[0];
+ break;
+ case 'A':
+ case 'a':
+ /* acceptable character; save uppercase version */
+ hexInternalKeyKCV[k] = 'A';
+ break;
+ case 'B':
+ case 'b':
+ /* acceptable character; save uppercase version */
+ hexInternalKeyKCV[k] = 'B';
+ break;
+ case 'C':
+ case 'c':
+ /* acceptable character; save uppercase version */
+ hexInternalKeyKCV[k] = 'C';
+ break;
+ case 'D':
+ case 'd':
+ /* acceptable character; save uppercase version */
+ hexInternalKeyKCV[k] = 'D';
+ break;
+ case 'E':
+ case 'e':
+ /* acceptable character; save uppercase version */
+ hexInternalKeyKCV[k] = 'E';
+ break;
+ case 'F':
+ case 'f':
+ /* acceptable character; save uppercase version */
+ hexInternalKeyKCV[k] = 'F';
+ break;
+ default:
+ /* unacceptable character; don't save it */
+ continue;
+ }
+
+ /* increment the number of key KCV bytes read */
+ k++;
+ }
+ }
+
+ /* insure that the wrapped key KCV was completely obtained */
+ if( k != HEX_WRAPPED_KEY_KCV_LENGTH ) {
+ status = SECFailure;
+ goto destroyHexWrappedKey;
+ }
+
+ /* For convenience, display the read-in wrapped key */
+ /* and its associated KCV to the user. */
+ if( hexWrappedKey.data != NULL ) {
+ /* Display this final wrapped key */
+ if( ( hexWrappedKey.len - 1 ) !=
+ HEX_WRAPPED_KEY_LENGTH ) {
+ /* invalid key length */
+ PR_fprintf( PR_STDERR,
+ "ERROR: Invalid data length of %d bytes!\n\n\n",
+ hexWrappedKey.len );
+ status = SECFailure;
+ goto destroyHexWrappedKey;
+ } else {
+ /* Print wrapped data blob */
+ PR_fprintf( PR_STDOUT,
+ "\n wrapped data: " );
+
+ /* Print first DES_LENGTH bytes */
+ if( wrappedKey->len == ( 3 * DES_LENGTH ) ) {
+ firstCount = ( ( hexWrappedKey.len - 1 ) / 3 );
+ } else {
+ firstCount = ( ( hexWrappedKey.len - 1 ) / 2 );
+ }
+ for( i = 0; i < firstCount; i += 4 ) {
+ PR_fprintf( PR_STDOUT,
+ "%c%c%c%c ",
+ hexWrappedKey.data[i],
+ hexWrappedKey.data[i + 1],
+ hexWrappedKey.data[i + 2],
+ hexWrappedKey.data[i + 3] );
+ }
+
+ /* Print appropriate padding length */
+ PR_fprintf( PR_STDOUT, "\n " );
+
+ /* Print second DES_LENGTH bytes */
+ secondCount = firstCount * 2;
+ for( i = firstCount; i < secondCount; i += 4 ) {
+ PR_fprintf( PR_STDOUT,
+ "%c%c%c%c ",
+ hexWrappedKey.data[i],
+ hexWrappedKey.data[i + 1],
+ hexWrappedKey.data[i + 2],
+ hexWrappedKey.data[i + 3] );
+ }
+
+ /* print out last 8 bytes of triple-DES keys */
+ if( wrappedKey->len == ( 3 * DES_LENGTH ) ) {
+ /* Print appropriate padding length */
+ PR_fprintf( PR_STDOUT, "\n " );
+
+ /* Print third DES_LENGTH bytes */
+ thirdCount = hexWrappedKey.len;
+ for( i = secondCount; i < thirdCount; i += 4 ) {
+ PR_fprintf( PR_STDOUT,
+ "%c%c%c%c ",
+ hexWrappedKey.data[i],
+ hexWrappedKey.data[i + 1],
+ hexWrappedKey.data[i + 2],
+ hexWrappedKey.data[i + 3] );
+ }
+ }
+
+ /* Print appropriate vertical spacing */
+ PR_fprintf( PR_STDOUT, "\n\n\n" );
+ }
+ }
+
+ if( hexInternalKeyKCV != NULL ) {
+ /* Display this final wrapped key's KCV */
+ if( ( hexInternalKeyKCVLength - 1 ) !=
+ HEX_WRAPPED_KEY_KCV_LENGTH ) {
+ /* invalid key length */
+ PR_fprintf( PR_STDERR,
+ "ERROR: Invalid key KCV length "
+ "of %d bytes!\n\n\n",
+ hexInternalKeyKCVLength );
+ status = SECFailure;
+ goto destroyHexWrappedKey;
+ } else {
+ PR_fprintf( PR_STDOUT,
+ " master key KCV: "
+ "%c%c%c%c %c%c%c%c\n (pre-computed KCV of the "
+ "master key residing inside the wrapped data)\n\n\n",
+ hexInternalKeyKCV[0],
+ hexInternalKeyKCV[1],
+ hexInternalKeyKCV[2],
+ hexInternalKeyKCV[3],
+ hexInternalKeyKCV[4],
+ hexInternalKeyKCV[5],
+ hexInternalKeyKCV[6],
+ hexInternalKeyKCV[7] );
+ }
+ }
+
+ /* close the input file */
+ PR_Close( fd );
+
+ status = SECSuccess;
+
+destroyHexWrappedKey:
+ /* Destroy the hex wrapped key */
+ if( hexWrappedKey.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ hexWrappedKey.data,
+ hexWrappedKey.len );
+ hexWrappedKey.data = NULL;
+ hexWrappedKey.len = 0;
+ }
+
+ return status;
+}
+
+
+SECStatus
+TKS_WriteSECItemIntoOutputFile( SECItem *wrappedKey,
+ char *wrappedKeyName,
+ char *hexInternalKeyKCV,
+ int hexInternalKeyKCVLength,
+ char *output )
+{
+ PRFileDesc *fd = NULL;
+ PRInt32 count = 0;
+ PRInt32 r = 0;
+ PRIntn firstCount = 0;
+ PRIntn secondCount = 0;
+ PRIntn thirdCount = 0;
+ PRIntn i = 0;
+ SECItem hexWrappedKey = { siBuffer,
+ NULL,
+ 0 };
+ SECStatus status = SECFailure;
+
+ /* Create a clean new hex display buffer for this wrapped key */
+ hexWrappedKey.type = ( SECItemType ) siBuffer;
+ hexWrappedKey.len = ( ( wrappedKey->len * 2 ) + 1 );
+ hexWrappedKey.data = ( unsigned char * )
+ PORT_ZAlloc( hexWrappedKey.len );
+ if( hexWrappedKey.data == NULL ) {
+ status = SECFailure;
+ goto destroyHexWrappedKey;
+ }
+
+ /* Convert this wrapped key into hex digits */
+ TKS_StringToHex( ( PRUint8 * ) wrappedKey->data,
+ ( PRIntn ) wrappedKey->len,
+ ( PRUint8 * ) hexWrappedKey.data,
+ ( PRIntn ) hexWrappedKey.len );
+
+ /* For convenience, display this wrapped key to the user. */
+ if( hexWrappedKey.data != NULL ) {
+ /* Display this final wrapped key */
+ if( ( hexWrappedKey.len - 1 ) !=
+ HEX_WRAPPED_KEY_LENGTH ) {
+ /* invalid key length */
+ PR_fprintf( PR_STDERR,
+ "ERROR: Invalid data length of %d bytes!\n\n\n",
+ hexWrappedKey.len );
+ status = SECFailure;
+ goto destroyHexWrappedKey;
+ } else {
+ /* Print wrapped data blob */
+ PR_fprintf( PR_STDOUT,
+ " wrapped data: " );
+
+ /* Print first DES_LENGTH bytes */
+ if( wrappedKey->len == ( 3 * DES_LENGTH ) ) {
+ firstCount = ( ( hexWrappedKey.len - 1 ) / 3 );
+ } else {
+ firstCount = ( ( hexWrappedKey.len - 1 ) / 2 );
+ }
+ for( i = 0; i < firstCount; i += 4 ) {
+ PR_fprintf( PR_STDOUT,
+ "%c%c%c%c ",
+ hexWrappedKey.data[i],
+ hexWrappedKey.data[i + 1],
+ hexWrappedKey.data[i + 2],
+ hexWrappedKey.data[i + 3] );
+ }
+
+ /* Print appropriate padding length */
+ PR_fprintf( PR_STDOUT, "\n " );
+
+ /* Print second DES_LENGTH bytes */
+ secondCount = firstCount * 2;
+ for( i = firstCount; i < secondCount; i += 4 ) {
+ PR_fprintf( PR_STDOUT,
+ "%c%c%c%c ",
+ hexWrappedKey.data[i],
+ hexWrappedKey.data[i + 1],
+ hexWrappedKey.data[i + 2],
+ hexWrappedKey.data[i + 3] );
+ }
+
+ /* print out last 8 bytes of triple-DES keys */
+ if( wrappedKey->len == ( 3 * DES_LENGTH ) ) {
+ /* Print appropriate padding length */
+ PR_fprintf( PR_STDOUT, "\n " );
+
+ /* Print third DES_LENGTH bytes */
+ thirdCount = hexWrappedKey.len;
+ for( i = secondCount; i < thirdCount; i += 4 ) {
+ PR_fprintf( PR_STDOUT,
+ "%c%c%c%c ",
+ hexWrappedKey.data[i],
+ hexWrappedKey.data[i + 1],
+ hexWrappedKey.data[i + 2],
+ hexWrappedKey.data[i + 3] );
+ }
+ }
+
+ /* Print appropriate vertical spacing */
+ PR_fprintf( PR_STDOUT, "\n\n\n" );
+ }
+ }
+
+ /* For convenience, display this wrapped key's */
+ /* master key KCV to the user. */
+ if( ( hexInternalKeyKCV != NULL ) &&
+ ( hexInternalKeyKCVLength == HEX_WRAPPED_KEY_KCV_LENGTH ) ) {
+ /* display this wrapped key's computed KCV value (in hex) */
+ PR_fprintf( PR_STDOUT,
+ " master key KCV: "
+ "%c%c%c%c %c%c%c%c\n (computed KCV of the "
+ "master key residing inside the wrapped data)\n\n\n",
+ hexInternalKeyKCV[0],
+ hexInternalKeyKCV[1],
+ hexInternalKeyKCV[2],
+ hexInternalKeyKCV[3],
+ hexInternalKeyKCV[4],
+ hexInternalKeyKCV[5],
+ hexInternalKeyKCV[6],
+ hexInternalKeyKCV[7] );
+ }
+
+ /* open the output file read-write */
+ fd = PR_OpenFile( output, ( PR_RDWR | PR_CREATE_FILE ), 0666 );
+ if( !fd ) {
+ status = SECFailure;
+ goto destroyHexWrappedKey;
+ }
+
+ /* write out the wrapped key (in hex) to the output file */
+ while( count < HEX_WRAPPED_KEY_LENGTH ) {
+ /* write out 4 bytes */
+ r = PR_Write( fd, &( hexWrappedKey.data[count] ), 4 );
+ if( r != 4 ) {
+ status = SECFailure;
+ goto destroyHexWrappedKey;
+ }
+
+ /* increment the byte count by 4 */
+ count += 4;
+
+ if( count >= HEX_WRAPPED_KEY_LENGTH ) {
+ r = PR_Write( fd, "\n", 1 );
+ if( r != 1 ) {
+ status = SECFailure;
+ goto destroyHexWrappedKey;
+ }
+ } else {
+ r = PR_Write( fd, " ", 1 );
+ if( r != 1 ) {
+ status = SECFailure;
+ goto destroyHexWrappedKey;
+ }
+ }
+ }
+
+ /* reinitialize count */
+ count = 0;
+
+ /* write out the master key KCV (in hex) to the output file */
+ while( count < HEX_WRAPPED_KEY_KCV_LENGTH ) {
+ /* write out 4 bytes */
+ r = PR_Write( fd, &( hexInternalKeyKCV[count] ), 4 );
+ if( r != 4 ) {
+ status = SECFailure;
+ goto destroyHexWrappedKey;
+ }
+
+ /* increment the byte count by 4 */
+ count += 4;
+
+ if( count >= HEX_WRAPPED_KEY_KCV_LENGTH ) {
+ r = PR_Write( fd, "\n", 1 );
+ if( r != 1 ) {
+ status = SECFailure;
+ goto destroyHexWrappedKey;
+ }
+ } else {
+ r = PR_Write( fd, " ", 1 );
+ if( r != 1 ) {
+ status = SECFailure;
+ goto destroyHexWrappedKey;
+ }
+ }
+ }
+
+ /* close the output file */
+ PR_Close( fd );
+
+ status = SECSuccess;
+
+destroyHexWrappedKey:
+ /* Destroy the hex wrapped key */
+ if( hexWrappedKey.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ hexWrappedKey.data,
+ hexWrappedKey.len );
+ hexWrappedKey.data = NULL;
+ hexWrappedKey.len = 0;
+ }
+
+ return status;
+}
+
diff --git a/base/native-tools/src/tkstool/find.c b/base/native-tools/src/tkstool/find.c
new file mode 100644
index 000000000..8926d5cbb
--- /dev/null
+++ b/base/native-tools/src/tkstool/find.c
@@ -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.
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#include "tkstool.h"
+
+SECStatus
+TKS_FindSymKey( PK11SlotInfo *slot,
+ char *keyname,
+ void *pwdata )
+{
+ char *name = NULL;
+ int count = 0;
+ int keys_found = 0;
+ PK11SymKey *symKey = NULL;
+ PK11SymKey *nextSymKey = NULL;
+ SECStatus rv = SECFailure;
+
+ if( PK11_NeedLogin( /* slot */ slot ) ) {
+ PK11_Authenticate(
+ /* slot */ slot,
+ /* load certs */ PR_TRUE,
+ /* wincx */ pwdata );
+ }
+
+ /* Initialize the symmetric key list. */
+ symKey = PK11_ListFixedKeysInSlot(
+ /* slot */ slot,
+ /* nickname */ NULL,
+ /* wincx */ ( void *) pwdata );
+
+ /* Iterate through the symmetric key list. */
+ while( symKey != NULL ) {
+ name = PK11_GetSymKeyNickname( /* symmetric key */ symKey );
+ if( name != NULL ) {
+ if( keyname != NULL ) {
+ if( PL_strcmp( keyname, name ) == 0 ) {
+ keys_found++;
+ rv = SECSuccess;
+ }
+ }
+ }
+
+ nextSymKey = PK11_GetNextSymKey( /* symmetric key */ symKey );
+ PK11_FreeSymKey( /* symmetric key */ symKey );
+ symKey = nextSymKey;
+
+ count++;
+ }
+
+ /* case 1: the token is empty */
+ if( count == 0 ) {
+ /* the specified token is empty */
+ rv = SECFailure;
+ }
+
+ /* case 2: the specified key is not on this token */
+ if( ( keyname != NULL ) &&
+ ( keys_found == 0 ) ) {
+ /* the key called "keyname" could not be found */
+ rv = SECFailure;
+ }
+
+ return rv;
+}
+
diff --git a/base/native-tools/src/tkstool/help.c b/base/native-tools/src/tkstool/help.c
new file mode 100644
index 000000000..97c724459
--- /dev/null
+++ b/base/native-tools/src/tkstool/help.c
@@ -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.
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#include "tkstool.h"
+
+void
+TKS_Usage( char *progName )
+{
+ PR_fprintf( PR_STDERR,
+ "Usage: %s -D -n keyname -d DBDir [-h token_name]\n"
+ "\t\t[-p DBPrefix] [-f pwfile]\n\n",
+ progName );
+ PR_fprintf( PR_STDERR,
+ "\t%s -H\n\n",
+ progName );
+ PR_fprintf( PR_STDERR,
+ "\t%s -I -n keyname -d DBDir [-h token_name]\n"
+ "\t\t[-p DBPrefix] [-f pwfile]\n\n",
+ progName );
+ PR_fprintf( PR_STDERR,
+ "\t%s -K -n keyname -d DBDir [-h token_name]\n"
+ "\t\t[-p DBPrefix] [-f pwfile]\n\n",
+ progName );
+ PR_fprintf( PR_STDERR,
+ "\t%s -L -d DBDir [-h all | -h token_name]\n"
+ "\t\t[-p DBPrefix] [-n keyname] [-f pwfile] [-x]\n\n",
+ progName );
+ PR_fprintf( PR_STDERR,
+ "\t%s -M -n keyname -d DBDir [-h token_name]\n"
+ "\t\t[-p DBPrefix] [-f pwfile]\n\n",
+ progName );
+ PR_fprintf( PR_STDERR,
+ "\t%s -N -d DBDir\n"
+ "\t\t[-p DBPrefix] [-f pwfile]\n\n",
+ progName );
+ PR_fprintf( PR_STDERR,
+ "\t%s -P -d DBDir\n"
+ "\t\t[-p DBPrefix] [-f pwfile]\n\n",
+ progName );
+ PR_fprintf( PR_STDERR,
+ "\t%s -R -n keyname -r new_keyname -d DBDir [-h token_name]\n"
+ "\t\t[-p DBPrefix] [-f pwfile]\n\n",
+ progName );
+ PR_fprintf( PR_STDERR,
+ "\t%s -S -d DBDir\n"
+ "\t\t[-p DBPrefix] [-x]\n\n",
+ progName );
+ PR_fprintf( PR_STDERR,
+ "\t%s -T -n keyname -d DBDir [-h token_name]\n"
+ "\t\t[-p DBPrefix] [-f pwfile] [-z noisefile]\n\n",
+ progName );
+ PR_fprintf( PR_STDERR,
+ "\t%s -U -n keyname -d DBDir -t transport_keyname -i infile\n"
+ "\t\t[-h token_name] [-p DBPrefix] [-f pwfile]\n\n",
+ progName );
+ PR_fprintf( PR_STDERR,
+ "\t%s -V\n\n",
+ progName );
+ PR_fprintf( PR_STDERR,
+ "\t%s -W -n keyname -d DBDir -t transport_keyname -o outfile\n"
+ "\t\t[-h token_name] [-p DBPrefix] [-f pwfile]\n\n",
+ progName );
+ PR_fprintf( PR_STDERR,
+ "Type \"%s -H\" for more detailed descriptions\n\n",
+ progName );
+}
+
+
+void
+TKS_PrintHelp( char *progName )
+{
+ /**********************/
+ /* -D command options */
+ /**********************/
+
+ PR_fprintf( PR_STDERR,
+ "%-15s Delete a key from the token\n",
+ "-D" );
+ PR_fprintf( PR_STDERR,
+ "%-24s The name of the key to delete\n"
+ "\t\t [required]\n",
+ " -n keyname" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Security module database directory (HSM);\n"
+ "\t\t Key database directory (software only)\n"
+ "\t\t [required]\n",
+ " -d DBDir" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Name of token from which to remove key\n"
+ "\t\t [optional]\n",
+ " -h token_name" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Security module database prefix\n"
+ "\t\t [optional]\n",
+ " -p DBPrefix" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Specify the password file\n"
+ "\t\t [optional]\n",
+ " -f pwfile" );
+ PR_fprintf( PR_STDERR,
+ "\n" );
+
+
+ /**********************/
+ /* -H command options */
+ /**********************/
+
+ PR_fprintf( PR_STDERR,
+ "%-15s Display this extended help for Usage\n",
+ "-H" );
+ PR_fprintf( PR_STDERR,
+ "\n" );
+
+
+ /**********************/
+ /* -I command options */
+ /**********************/
+
+ PR_fprintf( PR_STDERR,
+ "%-15s Input shares to generate a new transport key\n",
+ "-I" );
+ PR_fprintf( PR_STDERR,
+ "%-24s The name to assign to the generated transport key\n"
+ "\t\t [required]\n",
+ " -n keyname" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Security module database directory (HSM);\n"
+ "\t\t Key database directory (software only)\n"
+ "\t\t [required]\n",
+ " -d DBDir" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Name of token in which to generate transport key\n"
+ "\t\t [optional]\n",
+ " -h token_name" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Security module database prefix\n"
+ "\t\t [optional]\n",
+ " -p DBPrefix" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Specify the password file\n"
+ "\t\t [optional]\n",
+ " -f pwfile" );
+ PR_fprintf( PR_STDERR,
+ "\n" );
+
+
+ /**********************/
+ /* -K command options */
+ /**********************/
+
+ PR_fprintf( PR_STDERR,
+ "%-15s Display the KCV of the specified key\n",
+ "-K" );
+ PR_fprintf( PR_STDERR,
+ "%-24s The name of the key to perform a KCV on\n"
+ "\t\t [required]\n",
+ " -n keyname" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Security module database directory (HSM);\n"
+ "\t\t Key database directory (software only)\n"
+ "\t\t [required]\n",
+ " -d DBDir" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Name of token on which the named key resides\n"
+ "\t\t [optional]\n",
+ " -h token_name" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Security module database prefix\n"
+ "\t\t [optional]\n",
+ " -p DBPrefix" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Specify the password file\n"
+ "\t\t [optional]\n",
+ " -f pwfile" );
+ PR_fprintf( PR_STDERR,
+ "\n" );
+
+
+ /**********************/
+ /* -L command options */
+ /**********************/
+
+ PR_fprintf( PR_STDERR,
+ "%-15s List out a specified key, or all keys\n",
+ "-L" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Security module database directory (HSM);\n"
+ "\t\t Key database directory (software only)\n"
+ "\t\t [required]\n",
+ " -d DBDir" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Look on all tokens OR\n"
+ "%-24s Name of token in which to look for keys\n"
+ "\t\t [optional]\n",
+ " -h all |",
+ " -h token_name" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Security module database prefix\n"
+ "\t\t [optional]\n",
+ " -p DBPrefix" );
+ PR_fprintf( PR_STDERR,
+ "%-24s The name of the key to list\n"
+ "\t\t [optional]\n",
+ " -n keyname" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Specify the password file\n"
+ "\t\t [optional]\n",
+ " -f pwfile" );
+ PR_fprintf( PR_STDERR,
+ "%-24s force the database to open R/W (software only)\n"
+ "\t\t [optional]\n",
+ " -x" );
+ PR_fprintf( PR_STDERR,
+ "\n" );
+
+
+ /**********************/
+ /* -M command options */
+ /**********************/
+
+ PR_fprintf( PR_STDERR,
+ "%-15s Generate a new master key\n",
+ "-M" );
+ PR_fprintf( PR_STDERR,
+ "%-24s The name to assign to the generated master key\n"
+ "\t\t [required]\n",
+ " -n keyname" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Security module database directory (HSM);\n"
+ "\t\t Key database directory (software only)\n"
+ "\t\t [required]\n",
+ " -d DBDir" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Name of token in which to generate master key\n"
+ "\t\t [optional]\n",
+ " -h token_name" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Security module database prefix\n"
+ "\t\t [optional]\n",
+ " -p DBPrefix" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Specify the password file\n"
+ "\t\t [optional]\n",
+ " -f pwfile" );
+ PR_fprintf( PR_STDERR,
+ "\n" );
+
+
+ /**********************/
+ /* -N command options */
+ /**********************/
+
+ PR_fprintf( PR_STDERR,
+ "%-15s Create a new key database (software only)\n",
+ "-N" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Key database directory (software only)\n"
+ "\t\t [required]\n",
+ " -d DBDir" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Key database prefix (software only)\n"
+ "\t\t [optional]\n",
+ " -p DBPrefix" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Specify the password file\n"
+ "\t\t [optional]\n",
+ " -f pwfile" );
+ PR_fprintf( PR_STDERR,
+ "\n" );
+
+
+ /**********************/
+ /* -P command options */
+ /**********************/
+
+ PR_fprintf( PR_STDERR,
+ "%-15s Change the key database password (software only)\n",
+ "-P" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Key database directory (software only)\n"
+ "\t\t [required]\n",
+ " -d DBDir" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Key database prefix (software only)\n"
+ "\t\t [optional]\n",
+ " -p DBPrefix" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Specify the password file\n"
+ "\t\t [optional]\n",
+ " -f pwfile" );
+ PR_fprintf( PR_STDERR,
+ "\n" );
+
+
+ /**********************/
+ /* -R command options */
+ /**********************/
+
+ PR_fprintf( PR_STDERR,
+ "%-15s Rename a symmetric key\n",
+ "-R" );
+ PR_fprintf( PR_STDERR,
+ "%-24s The original name assigned to a pre-existing\n"
+ "\t\t symmetric key\n"
+ "\t\t [required]\n",
+ " -n keyname" );
+ PR_fprintf( PR_STDERR,
+ "%-24s The new name assigned to the original pre-existing\n"
+ "\t\t symmetric key\n"
+ "\t\t [required]\n",
+ " -r new_keyname" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Security module database directory (HSM);\n"
+ "\t\t Key database directory (software only)\n"
+ "\t\t [required]\n",
+ " -d DBDir" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Name of token in which to generate master key\n"
+ "\t\t [optional]\n",
+ " -h token_name" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Security module database prefix\n"
+ "\t\t [optional]\n",
+ " -p DBPrefix" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Specify the password file\n"
+ "\t\t [optional]\n",
+ " -f pwfile" );
+ PR_fprintf( PR_STDERR,
+ "\n" );
+
+
+ /**********************/
+ /* -S command options */
+ /**********************/
+
+ PR_fprintf( PR_STDERR,
+ "%-15s List all security modules\n",
+ /*, or print out a single named module\n",*/
+ "-S" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Security module database directory\n"
+ "\t\t [required]\n",
+ " -d DBDir" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Security module database prefix\n"
+ "\t\t [optional]\n",
+ " -p DBPrefix" );
+ PR_fprintf( PR_STDERR,
+ "%-24s force the database to open R/W (software only)\n"
+ "\t\t [optional]\n",
+ " -x" );
+ PR_fprintf( PR_STDERR,
+ "\n" );
+
+
+ /**********************/
+ /* -T command options */
+ /**********************/
+
+ PR_fprintf( PR_STDERR,
+ "%-15s Generate a new transport key\n",
+ "-T" );
+ PR_fprintf( PR_STDERR,
+ "%-24s The name to assign to the generated transport key\n"
+ "\t\t [required]\n",
+ " -n keyname" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Security module database directory (HSM);\n"
+ "\t\t Key database directory (software only)\n"
+ "\t\t [required]\n",
+ " -d DBDir" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Name of token in which to generate transport key\n"
+ "\t\t [optional]\n",
+ " -h token_name" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Security module database prefix\n"
+ "\t\t [optional]\n",
+ " -p DBPrefix" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Specify the password file\n"
+ "\t\t [optional]\n",
+ " -f pwfile" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Specify the noise file to be used\n"
+ "\t\t [optional]\n",
+ " -z noisefile" );
+ PR_fprintf( PR_STDERR,
+ "\n" );
+
+
+ /**********************/
+ /* -U command options */
+ /**********************/
+
+ PR_fprintf( PR_STDERR,
+ "%-15s Unwrap the wrapped master key\n",
+ "-U" );
+ PR_fprintf( PR_STDERR,
+ "%-24s The name to assign to the unwrapped master key\n"
+ "\t\t [required]\n",
+ " -n keyname" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Security module database directory (HSM);\n"
+ "\t\t Key database directory (software only)\n"
+ "\t\t [required]\n",
+ " -d DBDir" );
+ PR_fprintf( PR_STDERR,
+ "%-24s The name of the transport key (e. g. - unwrapping key)\n"
+ "\t\t [required]\n",
+ " -t transport_keyname" );
+ PR_fprintf( PR_STDERR,
+ "%-24s The filename from which to input the wrapped master key\n"
+ "\t\t [required]\n",
+ " -i infile" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Name of token in which to store wrapped master key\n"
+ "\t\t [optional]\n",
+ " -h token_name" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Security module database prefix\n"
+ "\t\t [optional]\n",
+ " -p DBPrefix" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Specify the password file\n"
+ "\t\t [optional]\n",
+ " -f pwfile" );
+ PR_fprintf( PR_STDERR,
+ "\n" );
+
+
+ /**********************/
+ /* -V command options */
+ /**********************/
+
+ PR_fprintf( PR_STDERR,
+ "%-15s Display the version number of this tool\n",
+ "-V" );
+ PR_fprintf( PR_STDERR,
+ "\n" );
+
+
+ /**********************/
+ /* -W command options */
+ /**********************/
+
+ PR_fprintf( PR_STDERR,
+ "%-15s Wrap a newly generated master key\n",
+ "-W" );
+ PR_fprintf( PR_STDERR,
+ "%-24s The name to assign to the generated master key\n"
+ "\t\t [required]\n",
+ " -n keyname" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Security module database directory (HSM);\n"
+ "\t\t Key database directory (software only)\n"
+ "\t\t [required]\n",
+ " -d DBDir" );
+ PR_fprintf( PR_STDERR,
+ "%-24s The name of the transport key (e. g. - wrapping key)\n"
+ "\t\t [required]\n",
+ " -t transport_keyname" );
+ PR_fprintf( PR_STDERR,
+ "%-24s The filename in which to output the wrapped master key\n"
+ "\t\t [required]\n",
+ " -o outfile" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Name of token in which to generate master key\n"
+ "\t\t [optional]\n",
+ " -h token_name" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Security module database prefix\n"
+ "\t\t [optional]\n",
+ " -p DBPrefix" );
+ PR_fprintf( PR_STDERR,
+ "%-24s Specify the password file\n"
+ "\t\t [optional]\n",
+ " -f pwfile" );
+ PR_fprintf( PR_STDERR,
+ "\n" );
+}
+
diff --git a/base/native-tools/src/tkstool/key.c b/base/native-tools/src/tkstool/key.c
new file mode 100644
index 000000000..4fd37963b
--- /dev/null
+++ b/base/native-tools/src/tkstool/key.c
@@ -0,0 +1,1350 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 ---
+ */
+
+#include "tkstool.h"
+
+/*******************************/
+/** local private functions **/
+/*******************************/
+
+/* returns 0 for success, -1 for failure (EOF encountered) */
+static int
+InputHexSessionKey( char *sessionKeyShareName,
+ SECItem *hexSessionKeyShare )
+{
+ int fd;
+ int i;
+ int count;
+ int c;
+ int rv = 0;
+#ifdef XP_UNIX
+ cc_t orig_cc_min;
+ cc_t orig_cc_time;
+ tcflag_t orig_lflag;
+ struct termios tio;
+#endif
+
+ PR_fprintf( PR_STDOUT,
+ "Type in the %s session key share (or ^C to break):\n\n",
+ sessionKeyShareName );
+ PR_fprintf( PR_STDOUT,
+ "[ ] [ ] [ ] [ ] "
+ "[ ] [ ] [ ] [ ]\r" );
+
+ /* turn off echo on stdin & return on 1 char instead of NL */
+ fd = fileno( stdin );
+
+#if defined( XP_UNIX ) && !defined( VMS )
+ tcgetattr( fd, &tio );
+ orig_lflag = tio.c_lflag;
+ orig_cc_min = tio.c_cc[VMIN];
+ orig_cc_time = tio.c_cc[VTIME];
+ tio.c_lflag &= ~ECHO;
+ tio.c_lflag &= ~ICANON;
+ tio.c_cc[VMIN] = 1;
+ tio.c_cc[VTIME] = 0;
+ tcsetattr( fd, TCSAFLUSH, &tio );
+#endif
+
+ /* Get user input from keyboard strokes */
+ count = 0;
+ while( count < HEX_SESSION_KEY_BUF_LENGTH ) {
+#ifdef VMS
+ c = GENERIC_GETCHAR_NOECHO();
+#elif XP_UNIX
+ c = getc( stdin );
+#else
+ c = getch();
+#endif
+ /* break on EOF */
+ if( c == EOF ) {
+ rv = -1;
+ break;
+ }
+
+ /* break on ^C */
+ if( c == CTRL_C ) {
+ rv = -1;
+ break;
+ }
+
+ /* save acceptable hex characters; silently throw anything else away */
+ switch( c ) {
+ case '\010': /* backspace */
+ /* acceptable character; save it as a NULL value */
+ hexSessionKeyShare->data[count] = '\0';
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ /* acceptable character; save it as typed */
+ hexSessionKeyShare->data[count] = c;
+ break;
+ case 'A':
+ case 'a':
+ /* acceptable character; save uppercase version */
+ hexSessionKeyShare->data[count] = 'A';
+ break;
+ case 'B':
+ case 'b':
+ /* acceptable character; save uppercase version */
+ hexSessionKeyShare->data[count] = 'B';
+ break;
+ case 'C':
+ case 'c':
+ /* acceptable character; save uppercase version */
+ hexSessionKeyShare->data[count] = 'C';
+ break;
+ case 'D':
+ case 'd':
+ /* acceptable character; save uppercase version */
+ hexSessionKeyShare->data[count] = 'D';
+ break;
+ case 'E':
+ case 'e':
+ /* acceptable character; save uppercase version */
+ hexSessionKeyShare->data[count] = 'E';
+ break;
+ case 'F':
+ case 'f':
+ /* acceptable character; save uppercase version */
+ hexSessionKeyShare->data[count] = 'F';
+ break;
+ default:
+ /* unacceptable character; don't save it */
+ continue;
+ }
+
+ /* adjust the character count appropriately */
+ if( c != '\010' ) {
+ /* only increment the character count if everything is OK */
+ count++;
+ } else {
+ /* only decrement the character count if a backspace was entered */
+ if( count > 0 ) {
+ count--;
+ }
+ }
+
+ /* redisplay the left bracket */
+ PR_fprintf( PR_STDOUT,
+ "\r[" );
+
+ /* display the characters input so far */
+ for( i = 0 ; i < count ; i++ ) {
+ PR_fprintf( PR_STDOUT,
+ "%c",
+ hexSessionKeyShare->data[i] );
+ if( ( i > 0 ) &&
+ ( ( ( i + 1 ) % 4 ) == 0 ) ) {
+ PR_fprintf( PR_STDOUT, "] [" );
+ }
+ }
+
+ /* display a "cursor" pointing to the next character */
+ PR_fprintf( PR_STDOUT,
+ "/" );
+
+ /* display spaces to pad the remainder */
+ for( i = ( count + 1 );
+ i < HEX_SESSION_KEY_BUF_LENGTH;
+ i++ ) {
+ if( ( i % 4 ) != 0 ) {
+ PR_fprintf( PR_STDOUT, " " );
+ } else {
+ if( ( i > 0 ) &&
+ ( ( i + 1 ) < HEX_SESSION_KEY_BUF_LENGTH ) ) {
+ PR_fprintf( PR_STDOUT, "] [" );
+ PR_fprintf( PR_STDOUT, " " );
+ }
+ }
+ }
+
+ /* redisplay the right bracket */
+ PR_fprintf( PR_STDOUT,
+ "]" );
+ }
+
+ /* Null terminate the entered character sequence */
+ hexSessionKeyShare->data[count] = '\0';
+
+
+ /**************************************/
+ /* Print the final character sequence */
+ /**************************************/
+
+ /* Clear input line by outputting 78 blank */
+ /* spaces from the beginning of this line */
+ PR_fprintf( PR_STDOUT,
+ "\r"
+ " "
+ " " );
+
+ /* Print appropriate key share name */
+ PR_fprintf( PR_STDOUT,
+ "\r %s session key share: ",
+ sessionKeyShareName );
+
+ /* Print first DES_LENGTH bytes */
+ count = ( ( hexSessionKeyShare->len - 1 ) / 2 );
+ for( i = 0; i < count; i += 4 ) {
+ PR_fprintf( PR_STDOUT,
+ "%c%c%c%c ",
+ hexSessionKeyShare->data[i],
+ hexSessionKeyShare->data[i + 1],
+ hexSessionKeyShare->data[i + 2],
+ hexSessionKeyShare->data[i + 3] );
+ }
+
+ /* Print appropriate key share padding length */
+ PR_fprintf( PR_STDOUT, "\n " );
+ for( i = 0; i < PL_strlen( sessionKeyShareName ); i++ ) {
+ PR_fprintf( PR_STDOUT, " " );
+ }
+
+ /* Print second DES_LENGTH bytes */
+ for( i = count; i < hexSessionKeyShare->len; i += 4 ) {
+ PR_fprintf( PR_STDOUT,
+ "%c%c%c%c ",
+ hexSessionKeyShare->data[i],
+ hexSessionKeyShare->data[i + 1],
+ hexSessionKeyShare->data[i + 2],
+ hexSessionKeyShare->data[i + 3] );
+ }
+
+ /* Print appropriate vertical spacing */
+ PR_fprintf( PR_STDOUT, "\n\n\n" );
+
+#if defined( XP_UNIX ) && !defined( VMS )
+ /* set back termio the way it was */
+ tio.c_lflag = orig_lflag;
+ tio.c_cc[VMIN] = orig_cc_min;
+ tio.c_cc[VTIME] = orig_cc_time;
+ tcsetattr( fd, TCSAFLUSH, &tio );
+#endif
+
+ return rv;
+}
+
+
+/* returns 0 for success, -1 for failure (EOF encountered) */
+static int
+InputHexKCV( char *sessionKeyShareName,
+ PRUint8 *hexKCV )
+{
+ int fd;
+ int i;
+ int count;
+ int c;
+ int rv = 0;
+#ifdef XP_UNIX
+ cc_t orig_cc_min;
+ cc_t orig_cc_time;
+ tcflag_t orig_lflag;
+ struct termios tio;
+#endif
+
+ PR_fprintf( PR_STDOUT,
+ "Type in the corresponding KCV for the "
+ "%s session key share (or ^C to break):\n\n",
+ sessionKeyShareName );
+ PR_fprintf( PR_STDOUT,
+ "[ ] [ ]\r" );
+
+ /* turn off echo on stdin & return on 1 char instead of NL */
+ fd = fileno( stdin );
+
+#if defined( XP_UNIX ) && !defined( VMS )
+ tcgetattr( fd, &tio );
+ orig_lflag = tio.c_lflag;
+ orig_cc_min = tio.c_cc[VMIN];
+ orig_cc_time = tio.c_cc[VTIME];
+ tio.c_lflag &= ~ECHO;
+ tio.c_lflag &= ~ICANON;
+ tio.c_cc[VMIN] = 1;
+ tio.c_cc[VTIME] = 0;
+ tcsetattr( fd, TCSAFLUSH, &tio );
+#endif
+
+ /* Get user input from keyboard strokes */
+ count = 0;
+ while( count < HEX_SESSION_KEY_KCV_BUF_LENGTH ) {
+#ifdef VMS
+ c = GENERIC_GETCHAR_NOECHO();
+#elif XP_UNIX
+ c = getc( stdin );
+#else
+ c = getch();
+#endif
+ /* break on EOF */
+ if( c == EOF ) {
+ rv = -1;
+ break;
+ }
+
+ /* break on ^C */
+ if( c == CTRL_C ) {
+ rv = -1;
+ break;
+ }
+
+ /* save acceptable hex characters; silently throw anything else away */
+ switch( c ) {
+ case '\010': /* backspace */
+ /* acceptable character; save it as a NULL value */
+ hexKCV[count] = '\0';
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ /* acceptable character; save it as typed */
+ hexKCV[count] = c;
+ break;
+ case 'A':
+ case 'a':
+ /* acceptable character; save uppercase version */
+ hexKCV[count] = 'A';
+ break;
+ case 'B':
+ case 'b':
+ /* acceptable character; save uppercase version */
+ hexKCV[count] = 'B';
+ break;
+ case 'C':
+ case 'c':
+ /* acceptable character; save uppercase version */
+ hexKCV[count] = 'C';
+ break;
+ case 'D':
+ case 'd':
+ /* acceptable character; save uppercase version */
+ hexKCV[count] = 'D';
+ break;
+ case 'E':
+ case 'e':
+ /* acceptable character; save uppercase version */
+ hexKCV[count] = 'E';
+ break;
+ case 'F':
+ case 'f':
+ /* acceptable character; save uppercase version */
+ hexKCV[count] = 'F';
+ break;
+ default:
+ /* unacceptable character; don't save it */
+ continue;
+ }
+
+ /* adjust the character count appropriately */
+ if( c != '\010' ) {
+ /* only increment the character count if everything is OK */
+ count++;
+ } else {
+ /* only decrement the character count if a backspace was entered */
+ if( count > 0 ) {
+ count--;
+ }
+ }
+
+ /* redisplay the left bracket */
+ PR_fprintf( PR_STDOUT,
+ "\r[" );
+
+ /* display the characters input so far */
+ for( i = 0 ; i < count ; i++ ) {
+ PR_fprintf( PR_STDOUT,
+ "%c",
+ hexKCV[i] );
+ if( ( i > 0 ) &&
+ ( ( ( i + 1 ) % 4 ) == 0 ) ) {
+ PR_fprintf( PR_STDOUT, "] [" );
+ }
+ }
+
+ /* display a "cursor" pointing to the next character */
+ PR_fprintf( PR_STDOUT,
+ "/" );
+
+ /* display spaces to pad the remainder */
+ for( i = ( count + 1 );
+ i < HEX_SESSION_KEY_KCV_BUF_LENGTH;
+ i++ ) {
+ if( ( i % 4 ) != 0 ) {
+ PR_fprintf( PR_STDOUT, " " );
+ } else {
+ if( ( i > 0 ) &&
+ ( ( i + 1 ) < HEX_SESSION_KEY_KCV_BUF_LENGTH ) ) {
+ PR_fprintf( PR_STDOUT, "] [" );
+ PR_fprintf( PR_STDOUT, " " );
+ }
+ }
+ }
+
+ /* redisplay the right bracket */
+ PR_fprintf( PR_STDOUT,
+ "]" );
+ }
+
+ /* Null terminate the entered character sequence */
+ hexKCV[count] = '\0';
+
+
+ /**************************************/
+ /* Print the final character sequence */
+ /**************************************/
+
+ /* Clear input line by outputting 78 blank */
+ /* spaces from the beginning of this line */
+ PR_fprintf( PR_STDOUT,
+ "\r"
+ " "
+ " " );
+
+ /* display this session key share's entered KCV value (in hex) */
+ PR_fprintf( PR_STDOUT,
+ "\r %s session key share KCV: "
+ "%c%c%c%c %c%c%c%c\n\n\n",
+ sessionKeyShareName,
+ hexKCV[0],
+ hexKCV[1],
+ hexKCV[2],
+ hexKCV[3],
+ hexKCV[4],
+ hexKCV[5],
+ hexKCV[6],
+ hexKCV[7] );
+
+#if defined( XP_UNIX ) && !defined( VMS )
+ /* set back termio the way it was */
+ tio.c_lflag = orig_lflag;
+ tio.c_cc[VMIN] = orig_cc_min;
+ tio.c_cc[VTIME] = orig_cc_time;
+ tcsetattr( fd, TCSAFLUSH, &tio );
+#endif
+
+ return rv;
+}
+
+
+/************************************/
+/** public session key functions **/
+/************************************/
+
+SECStatus
+TKS_ComputeAndDisplayKCV( PRUint8 *newKey,
+ PRIntn newKeyLen,
+ PRUint8 *KCV,
+ PRIntn KCVLen,
+ PK11SymKey *symKey,
+ char *keyName,
+ char *keyType,
+ PRBool displayKCV,
+ PRUint8 *expectedHexKCV )
+{
+ int len;
+ unsigned char value[8];
+ PK11SymKey *key = NULL;
+ PK11SlotInfo *slot = NULL;
+ PK11Context *context = NULL;
+ PRIntn hexKCVLen = ( 2 * KCVLen ) + 1;
+ PRUint8 *hexKCV = NULL;
+ PRUint8 *keyData = NULL;
+ SECItem keyItem = { siBuffer,
+ NULL,
+ 0 };
+ SECItem noParams = { siBuffer,
+ NULL,
+ 0 };
+ SECStatus s = SECFailure;
+ SECStatus status = SECFailure;
+
+ /* for all keys except keys that are resident/wrapped/unwrapped . . . */
+ if( ( PL_strcmp( keyType, RESIDENT_KEY ) != 0 ) &&
+ ( PL_strcmp( keyType, UNWRAPPED_KEY ) != 0 ) &&
+ ( PL_strcmp( keyType, WRAPPED_KEY ) != 0 ) ) {
+ slot = PK11_GetInternalKeySlot();
+
+ if( newKeyLen == ( 2 * DES_LENGTH ) ) {
+#if defined(PAD_DES2_KEY_LENGTH)
+ /* double-DES key */
+ keyData = ( PRUint8 * ) PORT_ZAlloc( newKeyLen + DES_LENGTH );
+
+ keyItem.type = ( SECItemType ) siBuffer;
+ keyItem.data = ( unsigned char * ) keyData;
+ keyItem.len = ( unsigned int ) ( newKeyLen + DES_LENGTH );
+
+ /* convert 16-byte double-DES key to 24-byte triple-DES key */
+ PORT_Memcpy( keyData, newKey, newKeyLen );
+ PORT_Memcpy( ( keyData + ( 2 * DES_LENGTH ) ),
+ newKey, DES_LENGTH );
+#else
+ /* double-DES key */
+ keyData = ( PRUint8 * ) PORT_ZAlloc( newKeyLen );
+
+ keyItem.type = ( SECItemType ) siBuffer;
+ keyItem.data = ( unsigned char * ) keyData;
+ keyItem.len = ( unsigned int ) newKeyLen;
+
+ PORT_Memcpy( keyData, newKey, newKeyLen );
+#endif
+ } else if( newKeyLen == ( 3 * DES_LENGTH ) ) {
+ /* triple-DES key */
+ keyData = ( PRUint8 * ) PORT_ZAlloc( newKeyLen );
+
+ keyItem.type = ( SECItemType ) siBuffer;
+ keyItem.data = ( unsigned char * ) keyData;
+ keyItem.len = ( unsigned int ) newKeyLen;
+
+ PORT_Memcpy( keyData, newKey, newKeyLen );
+ } else {
+ /* invalid key size */
+ PR_fprintf( PR_STDOUT,
+ "Attempting to perform KCV on invalid key length!\n\n\n" );
+ status = SECFailure;
+ goto done;
+ }
+
+ key = PK11_ImportSymKeyWithFlags(
+ /* slot */ slot,
+ /* mechanism type */ CKM_DES3_ECB,
+ /* origin */ PK11_OriginGenerated,
+ /* operation */ CKA_ENCRYPT,
+ /* key */ &keyItem,
+ /* flags */ CKF_ENCRYPT,
+ /* isPerm */ PR_FALSE,
+ /* wincx */ 0 );
+
+ if( ! key ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Failed to import %s key!\n\n\n",
+ keyType );
+ status = SECFailure;
+ goto done;
+ }
+ } else {
+ /* since resident/wrapped/unwrapped keys are already present . . . */
+ key = symKey;
+ }
+
+ PORT_Memset( value, 0, sizeof( value ) );
+
+ context = PK11_CreateContextBySymKey(
+ /* mechanism type */ CKM_DES3_ECB,
+ /* operation */ CKA_ENCRYPT,
+ /* symmetric key */ key,
+ /* param */ &noParams );
+
+ if( ! context ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Failed to create crypto context!\n\n\n" );
+ status = SECFailure;
+ goto done;
+ }
+
+ s = PK11_CipherOp(
+ /* context */ context,
+ /* output */ &value[0],
+ /* output length */ &len,
+ /* maximum output length */ DES_LENGTH,
+ /* input */ &value[0],
+ /* input length */ DES_LENGTH );
+ if( s != SECSuccess) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: CipherOp Failed!\n\n\n" );
+ status = SECFailure;
+ goto done;
+ }
+
+ KCV = ( PRUint8 * ) PORT_ZAlloc( KCVLen );
+
+ PORT_Memcpy( KCV, value, KCVLen );
+
+ /* Create a clean new display buffer for this */
+ /* symmetric key/session key share KCV */
+ hexKCV = ( PRUint8 * ) PORT_ZAlloc( hexKCVLen );
+ if( hexKCV == NULL ) {
+ status = SECFailure;
+ goto done;
+ }
+
+ /* Display the symmetric key/session key share KCV (in hex digits) */
+ TKS_StringToHex( ( PRUint8 * ) KCV,
+ ( PRIntn ) KCVLen,
+ ( PRUint8 * ) hexKCV,
+ ( PRIntn ) hexKCVLen );
+
+ if( displayKCV != PR_FALSE ) {
+ /********************************************/
+ /* The following code is ONLY relevant to: */
+ /* */
+ /* (1) resident, */
+ /* (2) session, */
+ /* (3) symmetric, and */
+ /* (4) transport keys. */
+ /* */
+ /********************************************/
+
+ if( PL_strcmp( keyType, RESIDENT_KEY ) == 0 ) {
+ /* display this resident key's computed KCV value (in hex) */
+ PR_fprintf( PR_STDOUT,
+ " %s key KCV: "
+ "%c%c%c%c %c%c%c%c\n\n\n",
+ keyName,
+ hexKCV[0],
+ hexKCV[1],
+ hexKCV[2],
+ hexKCV[3],
+ hexKCV[4],
+ hexKCV[5],
+ hexKCV[6],
+ hexKCV[7] );
+ } else if( PL_strcmp( keyType, SESSION_KEY ) == 0 ) {
+ /* display this session key share's computed KCV value (in hex) */
+ PR_fprintf( PR_STDOUT,
+ " %s session key share KCV: "
+ "%c%c%c%c %c%c%c%c\n\n\n",
+ keyName,
+ hexKCV[0],
+ hexKCV[1],
+ hexKCV[2],
+ hexKCV[3],
+ hexKCV[4],
+ hexKCV[5],
+ hexKCV[6],
+ hexKCV[7] );
+ } else if( PL_strcmp( keyType, SYMMETRIC_KEY ) == 0 ) {
+ /* display this symmetric key's computed KCV value (in hex) */
+ PR_fprintf( PR_STDOUT,
+ " %s key KCV: "
+ "%c%c%c%c %c%c%c%c\n\n\n",
+ keyName,
+ hexKCV[0],
+ hexKCV[1],
+ hexKCV[2],
+ hexKCV[3],
+ hexKCV[4],
+ hexKCV[5],
+ hexKCV[6],
+ hexKCV[7] );
+ } else if( PL_strcmp( keyType, TRANSPORT_KEY ) == 0 ) {
+ /* display this transport key's computed KCV value (in hex) */
+ PR_fprintf( PR_STDOUT,
+ " %s key KCV: "
+ "%c%c%c%c %c%c%c%c\n\n\n",
+ keyName,
+ hexKCV[0],
+ hexKCV[1],
+ hexKCV[2],
+ hexKCV[3],
+ hexKCV[4],
+ hexKCV[5],
+ hexKCV[6],
+ hexKCV[7] );
+ }
+ } else {
+ /**********************************************/
+ /* The following code is ONLY relevant to: */
+ /* */
+ /* (1) session keys, */
+ /* (2) keys that have been unwrapped, and */
+ /* (3) keys that will be wrapped. */
+ /* */
+ /**********************************************/
+
+ if( PL_strcmp( keyType, SESSION_KEY ) == 0 ) {
+ /* compare this session key share's computed KCV value (in hex) */
+ /* with the expected KCV value (in hex) */
+ if( PL_strcmp( ( const char * ) hexKCV,
+ ( const char * ) expectedHexKCV ) == 0 ) {
+ PR_fprintf( PR_STDOUT,
+ "Congratulations, the %s session key share KCV "
+ "value entered CORRESPONDS\nto the %s session key "
+ "share value entered!\n",
+ keyName,
+ keyName );
+
+ /* Wait for the user to type "proceed" to continue */
+ TKS_TypeProceedToContinue();
+ } else {
+ PR_fprintf( PR_STDOUT,
+ "Unfortunately, a MISMATCH exists between the %s "
+ "session key share entered\nand the %s session key "
+ "share KCV entered. Please try again . . .\n",
+ keyName,
+ keyName );
+
+ /* Wait for the user to type "proceed" to continue */
+ TKS_TypeProceedToContinue();
+
+ status = SECFailure;
+ goto done;
+ }
+ } else if( PL_strcmp( keyType, UNWRAPPED_KEY ) == 0 ) {
+ PR_fprintf( PR_STDOUT,
+ " master key KCV: "
+ "%c%c%c%c %c%c%c%c\n (computed KCV of the "
+ "master key residing inside the wrapped data)\n\n\n",
+ hexKCV[0],
+ hexKCV[1],
+ hexKCV[2],
+ hexKCV[3],
+ hexKCV[4],
+ hexKCV[5],
+ hexKCV[6],
+ hexKCV[7] );
+
+ PR_fprintf( PR_STDOUT,
+ " master key KCV: "
+ "%c%c%c%c %c%c%c%c\n (pre-computed KCV of the "
+ "master key residing inside the wrapped data)\n\n\n",
+ expectedHexKCV[0],
+ expectedHexKCV[1],
+ expectedHexKCV[2],
+ expectedHexKCV[3],
+ expectedHexKCV[4],
+ expectedHexKCV[5],
+ expectedHexKCV[6],
+ expectedHexKCV[7] );
+
+ /* compare this wrapped key's computed KCV value (in hex) */
+ /* with the expected KCV value (in hex) -- silently */
+ if( PL_strcmp( ( const char * ) hexKCV,
+ ( const char * ) expectedHexKCV ) != 0 ) {
+ PR_fprintf( PR_STDOUT,
+ "Unfortunately, a MISMATCH exists between the "
+ "wrapped data read in\nfrom the input file "
+ "and the master key KCV that was recomputed.\n\n",
+ keyName,
+ keyName );
+ status = SECFailure;
+ goto done;
+ }
+ } else if( PL_strcmp( keyType, WRAPPED_KEY ) == 0 ) {
+ /* store this master key's computed KCV value (in hex) */
+ expectedHexKCV[0] = hexKCV[0];
+ expectedHexKCV[1] = hexKCV[1];
+ expectedHexKCV[2] = hexKCV[2];
+ expectedHexKCV[3] = hexKCV[3];
+ expectedHexKCV[4] = hexKCV[4];
+ expectedHexKCV[5] = hexKCV[5];
+ expectedHexKCV[6] = hexKCV[6];
+ expectedHexKCV[7] = hexKCV[7];
+ }
+ }
+
+ status = SECSuccess;
+
+done:
+ if( keyItem.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ keyItem.data,
+ keyItem.len );
+ keyItem.data = NULL;
+ keyItem.len = 0;
+ }
+
+ if( hexKCV != NULL ) {
+ PORT_ZFree( ( PRUint8 * )
+ hexKCV,
+ hexKCVLen );
+ }
+
+ if( context ) {
+ PK11_DestroyContext(
+ /* context */ context,
+ /* free it */ PR_TRUE );
+ }
+
+ if( slot ) {
+ PK11_FreeSlot( /* slot */ slot );
+ }
+
+ /* for all keys except keys that are resident/wrapped/unwrapped . . . */
+ if( ( PL_strcmp( keyType, RESIDENT_KEY ) != 0 ) &&
+ ( PL_strcmp( keyType, UNWRAPPED_KEY ) != 0 ) &&
+ ( PL_strcmp( keyType, WRAPPED_KEY ) != 0 ) ) {
+ if( key ) {
+ PK11_FreeSymKey( /* symmetric key */ key );
+ }
+ }
+
+ return status;
+}
+
+
+SECStatus
+TKS_GenerateSessionKeyShare( char *sessionKeyShareName,
+ SECItem *sessionKeyShare )
+{
+ PRIntn count = 0;
+ PRIntn i = 0;
+ PRIntn KCVLen = KCV_LENGTH;
+ PRUint8 *KCV = NULL;
+ SECItem hexSessionKeyShare = { siBuffer,
+ NULL,
+ 0 };
+ SECStatus rvKCV = SECFailure;
+ SECStatus sessionKeyShareStatus = SECFailure;
+ SECStatus status = SECFailure;
+
+ /* Clear the screen */
+ TKS_ClearScreen();
+
+ /* Generate a new session key share */
+ PR_fprintf( PR_STDOUT,
+ "\nGenerating the %s session key share . . .\n\n\n",
+ sessionKeyShareName );
+
+ sessionKeyShareStatus = PK11_GenerateRandom( ( unsigned char * )
+ /* data */ sessionKeyShare->data,
+ /* length */ sessionKeyShare->len );
+ if( sessionKeyShareStatus != SECSuccess ) {
+ goto destroyHexSessionKeyShare;
+ }
+
+ /* Create a clean new display buffer for this session key share */
+ hexSessionKeyShare.type = ( SECItemType ) siBuffer;
+ hexSessionKeyShare.len = ( ( sessionKeyShare->len * 2 ) + 1 );
+ hexSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( hexSessionKeyShare.len );
+ if( hexSessionKeyShare.data == NULL ) {
+ goto destroyHexSessionKeyShare;
+ }
+
+ /* Convert this session key share into hex digits */
+ TKS_StringToHex( ( PRUint8 * ) sessionKeyShare->data,
+ ( PRIntn ) sessionKeyShare->len,
+ ( PRUint8 * ) hexSessionKeyShare.data,
+ ( PRIntn ) hexSessionKeyShare.len );
+
+ /* Adjust the first DES-sized (8-byte) chunk */
+ TKS_AdjustOddParity( ( PRUint8 * ) sessionKeyShare->data );
+
+ /* Adjust the second DES-sized (8-byte) chunk */
+ TKS_AdjustOddParity( ( PRUint8 * ) ( sessionKeyShare->data + DES_LENGTH ) );
+
+ /* Finally, display this session key share */
+ /* (adjusted for odd parity in hex digits) */
+ TKS_StringToHex( ( PRUint8 * ) sessionKeyShare->data,
+ ( PRIntn ) sessionKeyShare->len,
+ ( PRUint8 * ) hexSessionKeyShare.data,
+ ( PRIntn ) hexSessionKeyShare.len );
+
+ if( ( ( hexSessionKeyShare.len - 1 ) % 4 ) != 0 ) {
+ /* invalid key length */
+ PR_fprintf( PR_STDERR,
+ "ERROR: Invalid session key share length "
+ "of %d bytes!\n\n\n",
+ hexSessionKeyShare.len );
+ goto destroyHexSessionKeyShare;
+ } else {
+ /* Print appropriate key share name */
+ PR_fprintf( PR_STDOUT,
+ " %s session key share: ",
+ sessionKeyShareName );
+
+ /* Print first DES_LENGTH bytes */
+ count = ( ( hexSessionKeyShare.len - 1 ) / 2 );
+ for( i = 0; i < count; i += 4 ) {
+ PR_fprintf( PR_STDOUT,
+ "%c%c%c%c ",
+ hexSessionKeyShare.data[i],
+ hexSessionKeyShare.data[i + 1],
+ hexSessionKeyShare.data[i + 2],
+ hexSessionKeyShare.data[i + 3] );
+ }
+
+ /* Print appropriate key share padding length */
+ PR_fprintf( PR_STDOUT, "\n " );
+ for( i = 0; i < PL_strlen( sessionKeyShareName ); i++ ) {
+ PR_fprintf( PR_STDOUT, " " );
+ }
+
+ /* Print second DES_LENGTH bytes */
+ for( i = count; i < hexSessionKeyShare.len; i += 4 ) {
+ PR_fprintf( PR_STDOUT,
+ "%c%c%c%c ",
+ hexSessionKeyShare.data[i],
+ hexSessionKeyShare.data[i + 1],
+ hexSessionKeyShare.data[i + 2],
+ hexSessionKeyShare.data[i + 3] );
+ }
+
+ /* Print appropriate vertical spacing */
+ PR_fprintf( PR_STDOUT, "\n\n\n" );
+ }
+
+ rvKCV = TKS_ComputeAndDisplayKCV( ( PRUint8 * ) sessionKeyShare->data,
+ ( PRIntn ) sessionKeyShare->len,
+ ( PRUint8 * ) KCV,
+ ( PRIntn ) KCVLen,
+ NULL,
+ sessionKeyShareName,
+ SESSION_KEY,
+ PR_TRUE,
+ NULL );
+ if( rvKCV != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Failed to compute KCV of "
+ "this %s session key share!\n\n",
+ sessionKeyShareName );
+ goto destroyHexSessionKeyShare;
+ }
+
+ PR_fprintf( PR_STDOUT,
+ "(1) Write down and save the value "
+ "for this %s session key share.\n\n",
+ sessionKeyShareName );
+
+ PR_fprintf( PR_STDOUT,
+ "(2) Write down and save the KCV value "
+ "for this %s session key share.\n",
+ sessionKeyShareName );
+
+ /* Wait for the user to type "proceed" to continue */
+ TKS_TypeProceedToContinue();
+
+ /* Clear the screen */
+ TKS_ClearScreen();
+
+ /* Report success */
+ status = SECSuccess;
+
+destroyHexSessionKeyShare:
+ /* Destroy the hex session key share */
+ if( hexSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ hexSessionKeyShare.data,
+ hexSessionKeyShare.len );
+ hexSessionKeyShare.data = NULL;
+ hexSessionKeyShare.len = 0;
+ }
+
+ return status;
+}
+
+SECStatus
+TKS_InputSessionKeyShare( char *sessionKeyShareName,
+ SECItem *sessionKeyShare )
+{
+ int rv = 0;
+ PRIntn KCVLen = KCV_LENGTH;
+ PRUint8 *KCV = NULL;
+ SECItem hexSessionKeyShare;
+ PRIntn hexKCVLen = ( 2 * KCVLen ) + 1;
+ PRUint8 *hexKCV = NULL;
+ SECStatus rvKCV = SECFailure;
+ SECStatus status = SECFailure;
+
+ /* Clear the screen */
+ TKS_ClearScreen();
+
+ /* Enter a new session key share */
+ PR_fprintf( PR_STDOUT,
+ "\nEnter the %s session key share . . .\n\n\n",
+ sessionKeyShareName );
+
+ /* Create a clean new display buffer for this session key share */
+ hexSessionKeyShare.type = ( SECItemType ) siBuffer;
+ hexSessionKeyShare.len = ( ( sessionKeyShare->len * 2 ) + 1 );
+ hexSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( hexSessionKeyShare.len );
+ if( hexSessionKeyShare.data == NULL ) {
+ goto destroyHexSessionKeyShare;
+ }
+
+ rv = InputHexSessionKey( sessionKeyShareName,
+ &hexSessionKeyShare );
+ if( rv ) {
+ PORT_SetError( PR_END_OF_FILE_ERROR );
+ return SECFailure;
+ }
+
+ /* Convert these hex digits into a session key share */
+ TKS_ConvertStringOfHexCharactersIntoBitStream( ( char * ) hexSessionKeyShare.data,
+ ( hexSessionKeyShare.len - 1 ),
+ sessionKeyShare->data );
+
+ /* Create a clean new display buffer for this session key share KCV */
+ hexKCV = ( PRUint8 * ) PORT_ZAlloc( hexKCVLen );
+ if( hexKCV == NULL ) {
+ goto destroyHexSessionKeyShare;
+ }
+
+ rv = InputHexKCV( sessionKeyShareName,
+ hexKCV );
+ if( rv ) {
+ PORT_SetError( PR_END_OF_FILE_ERROR );
+ return SECFailure;
+ }
+
+ /* Enter the corresponding KCV */
+ PR_fprintf( PR_STDOUT,
+ "Verifying that this session key share and KCV "
+ "correspond to each other . . .\n\n\n" );
+
+ rvKCV = TKS_ComputeAndDisplayKCV( ( PRUint8 * ) sessionKeyShare->data,
+ ( PRIntn ) sessionKeyShare->len,
+ ( PRUint8 * ) KCV,
+ ( PRIntn ) KCVLen,
+ NULL,
+ sessionKeyShareName,
+ SESSION_KEY,
+ PR_FALSE,
+ hexKCV );
+ if( rvKCV != SECSuccess ) {
+ goto destroyHexSessionKeyShare;
+ }
+
+ /* Clear the screen */
+ TKS_ClearScreen();
+
+ /* Report success */
+ status = SECSuccess;
+
+destroyHexSessionKeyShare:
+ /* Destroy the hex session key share */
+ if( hexSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ hexSessionKeyShare.data,
+ hexSessionKeyShare.len );
+ hexSessionKeyShare.data = NULL;
+ hexSessionKeyShare.len = 0;
+ }
+
+ if( hexKCV != NULL ) {
+ PORT_ZFree( ( PRUint8 * )
+ hexKCV,
+ hexKCVLen );
+ }
+
+ return status;
+}
+
+
+/**************************************/
+/** public symmetric key functions **/
+/**************************************/
+
+PK11SymKey *
+TKS_ImportSymmetricKey( char *symmetricKeyName,
+ PK11SlotInfo *slot,
+ CK_MECHANISM_TYPE mechanism,
+ CK_ATTRIBUTE_TYPE operation,
+ SECItem *sessionKeyShare,
+ secuPWData *pwdata )
+{
+ PK11Origin origin = PK11_OriginGenerated;
+ PK11SymKey *symKey = NULL;
+
+ if( slot == NULL ) {
+ return NULL;
+ }
+
+ PR_fprintf( PR_STDOUT,
+ "\n" );
+ PR_fprintf( PR_STDOUT,
+ "Generating %s symmetric key . . .\n\n",
+ symmetricKeyName );
+
+ symKey = PK11_ImportSymKeyWithFlags(
+ /* slot */ slot,
+ /* mechanism type */ mechanism,
+ /* origin */ origin,
+ /* operation */ operation,
+ /* key */ sessionKeyShare,
+ /* flags */ 0,
+ /* isPerm */ PR_FALSE,
+ /* wincx */ pwdata );
+ return symKey;
+}
+
+
+PK11SymKey *
+TKS_DeriveSymmetricKey( char *symmetricKeyName,
+ PK11SymKey *symKey,
+ CK_MECHANISM_TYPE derive,
+ SECItem *sessionKeyShare,
+ CK_MECHANISM_TYPE target,
+ CK_ATTRIBUTE_TYPE operation,
+ int keysize )
+{
+ PK11SymKey *newSymKey = NULL;
+
+ if( symKey == NULL ) {
+ return NULL;
+ }
+
+ if( keysize <= 0 ) {
+ return NULL;
+ }
+
+ PR_fprintf( PR_STDOUT,
+ "Generating %s symmetric key . . .\n\n",
+ symmetricKeyName );
+
+ newSymKey = PK11_Derive(
+ /* base symmetric key */ symKey,
+ /* mechanism derive type */ derive,
+ /* param */ sessionKeyShare,
+ /* target */ target,
+ /* operation */ operation,
+ /* key size */ keysize );
+ return newSymKey;
+}
+
+
+SECStatus
+TKS_StoreSymmetricKeyAndNameIt( char *symmetricKeyName,
+ char *keyname,
+ PK11SlotInfo *slot,
+ CK_ATTRIBUTE_TYPE operation,
+ CK_FLAGS flags,
+ PK11SymKey *symKey )
+{
+ PK11SymKey *newSymKey = NULL;
+ PRIntn KCVLen = KCV_LENGTH;
+ PRUint8 *KCV = NULL;
+ SECItem *symmetricKey = NULL;
+ SECStatus rvExtractSymmetricKey = SECFailure;
+ SECStatus rvKCV = SECFailure;
+ SECStatus rvSymmetricKeyname = SECFailure;
+ SECStatus status = SECFailure;
+#if defined(DEBUG)
+ PRIntn firstCount = 0;
+ PRIntn secondCount = 0;
+ PRIntn thirdCount = 0;
+ PRIntn i = 0;
+ SECItem hexSymmetricKey;
+#endif
+
+ PR_fprintf( PR_STDOUT,
+ "Extracting %s key from operational token . . .\n\n",
+ symmetricKeyName );
+
+ rvExtractSymmetricKey = PK11_ExtractKeyValue( /* symmetric key */ symKey );
+ if( rvExtractSymmetricKey != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Failed to extract the %s key!\n\n",
+ symmetricKeyName );
+ goto destroyHexSymmetricKey;
+ }
+
+ /* If present, retrieve the raw key data */
+ symmetricKey = PK11_GetKeyData( /* symmetric key */ symKey );
+
+#if defined(DEBUG)
+ /* For convenience, display the final symmetric key and */
+ /* its associated KCV to the user in DEBUG mode ONLY!!! */
+ if( symmetricKey != NULL ) {
+
+ /* Create a clean new display buffer for this symmetric key */
+ hexSymmetricKey.type = ( SECItemType ) siBuffer;
+ hexSymmetricKey.len = ( ( symmetricKey->len * 2 ) + 1 );
+ hexSymmetricKey.data = ( unsigned char * )
+ PORT_ZAlloc( hexSymmetricKey.len );
+ if( hexSymmetricKey.data == NULL ) {
+ goto destroyHexSymmetricKey;
+ }
+
+ /* Convert this symmetric key into hex digits */
+ TKS_StringToHex( ( PRUint8 * ) symmetricKey->data,
+ ( PRIntn ) symmetricKey->len,
+ ( PRUint8 * ) hexSymmetricKey.data,
+ ( PRIntn ) hexSymmetricKey.len );
+
+ /* Display this final symmetric key */
+ if( ( ( hexSymmetricKey.len - 1 ) % 4 ) != 0 ) {
+ /* invalid key length */
+ PR_fprintf( PR_STDERR,
+ "ERROR: Invalid symmetric key length "
+ "of %d bytes!\n\n\n",
+ hexSymmetricKey.len );
+ goto destroyHexSymmetricKey;
+ } else {
+ /* Print appropriate key name */
+ PR_fprintf( PR_STDOUT,
+ "\n %s key: ",
+ symmetricKeyName );
+
+ /* Print first DES_LENGTH bytes */
+ if( symmetricKey->len == ( 3 * DES_LENGTH ) ) {
+ firstCount = ( ( hexSymmetricKey.len - 1 ) / 3 );
+ } else {
+ firstCount = ( ( hexSymmetricKey.len - 1 ) / 2 );
+ }
+ for( i = 0; i < firstCount; i += 4 ) {
+ PR_fprintf( PR_STDOUT,
+ "%c%c%c%c ",
+ hexSymmetricKey.data[i],
+ hexSymmetricKey.data[i + 1],
+ hexSymmetricKey.data[i + 2],
+ hexSymmetricKey.data[i + 3] );
+ }
+
+ /* Print appropriate key padding length */
+ PR_fprintf( PR_STDOUT, "\n " );
+ for( i = 0; i < PL_strlen( symmetricKeyName ); i++ ) {
+ PR_fprintf( PR_STDOUT, " " );
+ }
+
+ /* Print second DES_LENGTH bytes */
+ secondCount = firstCount * 2;
+ for( i = firstCount; i < secondCount; i += 4 ) {
+ PR_fprintf( PR_STDOUT,
+ "%c%c%c%c ",
+ hexSymmetricKey.data[i],
+ hexSymmetricKey.data[i + 1],
+ hexSymmetricKey.data[i + 2],
+ hexSymmetricKey.data[i + 3] );
+ }
+
+ /* print out last 8 bytes of triple-DES keys */
+ if( symmetricKey->len == ( 3 * DES_LENGTH ) ) {
+ /* Print appropriate key padding length */
+ PR_fprintf( PR_STDOUT, "\n " );
+ for( i = 0; i < PL_strlen( symmetricKeyName ); i++ ) {
+ PR_fprintf( PR_STDOUT, " " );
+ }
+
+ /* Print third DES_LENGTH bytes */
+ thirdCount = hexSymmetricKey.len;
+ for( i = secondCount; i < thirdCount; i += 4 ) {
+ PR_fprintf( PR_STDOUT,
+ "%c%c%c%c ",
+ hexSymmetricKey.data[i],
+ hexSymmetricKey.data[i + 1],
+ hexSymmetricKey.data[i + 2],
+ hexSymmetricKey.data[i + 3] );
+ }
+ }
+
+ /* Print appropriate vertical spacing */
+ PR_fprintf( PR_STDOUT, "\n\n\n" );
+ }
+
+ /* Compute and display this final symmetric key's KCV */
+ rvKCV = TKS_ComputeAndDisplayKCV( ( PRUint8 * ) symmetricKey->data,
+ ( PRIntn ) symmetricKey->len,
+ ( PRUint8 * ) KCV,
+ ( PRIntn ) KCVLen,
+ NULL,
+ symmetricKeyName,
+ SYMMETRIC_KEY,
+ PR_TRUE,
+ NULL );
+ if( rvKCV != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Failed to compute KCV of this %s key!\n\n",
+ symmetricKeyName );
+ goto destroyHexSymmetricKey;
+ }
+ }
+#else
+ /* Display the final symmetric key's associated KCV to the user . . . */
+ if( symmetricKey != NULL ) {
+ /* . . . if and only if this is the transport key!!! */
+ if( PL_strcmp( symmetricKeyName, TRANSPORT_KEY ) == 0 ) {
+ /* Compute and display this transport key's KCV */
+ rvKCV = TKS_ComputeAndDisplayKCV( ( PRUint8 * ) symmetricKey->data,
+ ( PRIntn ) symmetricKey->len,
+ ( PRUint8 * ) KCV,
+ ( PRIntn ) KCVLen,
+ NULL,
+ symmetricKeyName,
+ TRANSPORT_KEY,
+ PR_TRUE,
+ NULL );
+ if( rvKCV != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Failed to compute KCV of this %s key!\n\n",
+ symmetricKeyName );
+ goto destroyHexSymmetricKey;
+ }
+ }
+ }
+#endif
+
+ PR_fprintf( PR_STDOUT,
+ "Storing %s key on final specified token . . .\n\n",
+ symmetricKeyName );
+
+ newSymKey = PK11_MoveSymKey(
+ /* slot */ slot,
+ /* operation */ operation,
+ /* flags */ flags,
+ /* permanence */ PR_TRUE,
+ /* symmetric key */ symKey );
+ if( newSymKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Failed to store the %s key: %d!\n\n",
+ symmetricKeyName,
+ PR_GetError() );
+ goto destroyHexSymmetricKey;
+ }
+
+
+ PR_fprintf( PR_STDOUT,
+ "Naming %s key \"%s\" . . .\n\n",
+ symmetricKeyName,
+ keyname );
+
+ rvSymmetricKeyname = PK11_SetSymKeyNickname(
+ /* symmetric key */ newSymKey,
+ /* nickname */ keyname );
+ if( rvSymmetricKeyname != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Failed to name the %s key!\n\n",
+ symmetricKeyName );
+ goto destroyHexSymmetricKey;
+ }
+
+ status = SECSuccess;
+
+
+destroyHexSymmetricKey:
+
+#if defined(DEBUG)
+ /* Destroy the hex symmetric key */
+ if( hexSymmetricKey.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ hexSymmetricKey.data,
+ hexSymmetricKey.len );
+ hexSymmetricKey.data = NULL;
+ hexSymmetricKey.len = 0;
+ }
+#endif
+
+ return status;
+}
+
diff --git a/base/native-tools/src/tkstool/list.c b/base/native-tools/src/tkstool/list.c
new file mode 100644
index 000000000..44173fa36
--- /dev/null
+++ b/base/native-tools/src/tkstool/list.c
@@ -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.
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#include "tkstool.h"
+
+/* callback for listing keys through pkcs11 */
+static SECStatus
+PrintSymKey( struct PRFileDesc *out,
+ int count,
+ char *keyname,
+ PK11SymKey *key )
+{
+ char *name = NULL;
+ SECStatus rv = SECFailure;
+
+ name = PK11_GetSymKeyNickname( /* symmetric key */ key );
+ if( name == NULL ) {
+ name = PORT_Strdup( "\t< orphaned >" );
+ }
+
+ if( keyname != NULL ) {
+ /* ONLY print this name if it is the requested key */
+ if( PL_strcmp( keyname, name ) == 0 ) {
+ PR_fprintf( out,
+ "\t<%d> %s\n",
+ count,
+ name );
+
+ rv = SECSuccess;
+ }
+ } else {
+ PR_fprintf( out,
+ "\t<%d> %s\n",
+ count,
+ name );
+
+ rv = SECSuccess;
+ }
+
+ PORT_Free( name );
+
+ return rv;
+}
+
+
+static SECStatus
+listKeys( char *progName,
+ PK11SlotInfo *slot,
+ char *keyname,
+ void *pwdata )
+{
+ int count = 0;
+ int keys_found = 0;
+ PK11SymKey *symKey = NULL;
+ PK11SymKey *nextSymKey = NULL;
+ SECStatus rvPrint = SECFailure;
+
+ if( PK11_NeedLogin( /* slot */ slot ) ) {
+ PK11_Authenticate(
+ /* slot */ slot,
+ /* load certs */ PR_TRUE,
+ /* wincx */ pwdata );
+ }
+
+ /* Initialize the symmetric key list. */
+ symKey = PK11_ListFixedKeysInSlot(
+ /* slot */ slot,
+ /* nickname */ NULL,
+ /* wincx */ ( void *) pwdata );
+
+ /* Iterate through the symmetric key list. */
+ while( symKey != NULL ) {
+ rvPrint = PrintSymKey( PR_STDOUT,
+ count,
+ keyname,
+ symKey );
+ if( rvPrint != SECFailure ) {
+ keys_found++;
+ }
+
+ nextSymKey = PK11_GetNextSymKey( /* symmetric key */ symKey );
+ PK11_FreeSymKey( /* symmetric key */ symKey );
+ symKey = nextSymKey;
+
+ count++;
+ }
+
+ /* case 1: the token is empty */
+ if( count == 0 ) {
+ PR_fprintf( PR_STDOUT,
+ "\t%s: the specified token is empty\n",
+ progName );
+
+ return SECFailure;
+ }
+
+ /* case 2: the specified key is not on this token */
+ if( ( keyname != NULL ) &&
+ ( keys_found == 0 ) ) {
+ PR_fprintf( PR_STDOUT,
+ "\t%s: the key called \"%s\" could not be found\n",
+ progName,
+ keyname );
+
+ return SECFailure;
+ }
+
+ return SECSuccess;
+}
+
+
+SECStatus
+TKS_ListKeys( char *progName,
+ PK11SlotInfo *slot,
+ char *keyname,
+ int index,
+ PRBool dopriv,
+ secuPWData *pwdata )
+{
+ SECStatus rv = SECSuccess;
+
+ if( slot == NULL ) {
+ PK11SlotList *list;
+ PK11SlotListElement *le;
+
+ list = PK11_GetAllTokens(
+ /* mechanism type */ CKM_INVALID_MECHANISM,
+ /* need R/W */ PR_FALSE,
+ /* load certs */ PR_FALSE,
+ /* wincx */ pwdata );
+
+ if( list ) {
+ for( le = list->head ; le ; le = le->next ) {
+ PR_fprintf( PR_STDOUT,
+ "\n slot: %s\n",
+ PK11_GetSlotName( /* slot */ le->slot ) );
+
+ PR_fprintf( PR_STDOUT,
+ "token: %s\n\n",
+ PK11_GetTokenName( /* slot */ le->slot ) );
+
+ rv = listKeys( progName,
+ le->slot,
+ keyname,
+ pwdata );
+ }
+ }
+ } else {
+ PR_fprintf( PR_STDOUT,
+ "\n slot: %s\n",
+ PK11_GetSlotName( /* slot */ slot ) );
+
+ PR_fprintf( PR_STDOUT,
+ "token: %s\n\n",
+ PK11_GetTokenName( /* slot */ slot ) );
+
+ rv = listKeys( progName,
+ slot,
+ keyname,
+ pwdata );
+ }
+
+ return rv;
+}
+
diff --git a/base/native-tools/src/tkstool/modules.c b/base/native-tools/src/tkstool/modules.c
new file mode 100644
index 000000000..0c4297251
--- /dev/null
+++ b/base/native-tools/src/tkstool/modules.c
@@ -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.
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#include "tkstool.h"
+
+/*
+ * L i s t S e c M o d u l e s
+ *
+ * Print a list of the PKCS11 security modules that are
+ * available. This is useful for smartcard people to
+ * make sure they have the drivers loaded.
+ *
+ */
+SECStatus
+TKS_ListSecModules( void )
+{
+ PK11SlotList *list;
+ PK11SlotListElement *le;
+
+ /* get them all! */
+ list = PK11_GetAllTokens(
+ /* mechanism type */ CKM_INVALID_MECHANISM,
+ /* need R/W */ PR_FALSE,
+ /* load certs */ PR_FALSE,
+ /* wincx */ NULL );
+
+ if( list == NULL ) {
+ return SECFailure;
+ }
+
+ /* look at each slot */
+ for( le = list->head ; le ; le = le->next ) {
+ PR_fprintf ( PR_STDOUT,
+ "\n" );
+ PR_fprintf ( PR_STDOUT,
+ " slot: %s\n",
+ PK11_GetSlotName( /* slot */ le->slot ) );
+ PR_fprintf ( PR_STDOUT,
+ " token: %s\n",
+ PK11_GetTokenName( /* slot */ le->slot ) );
+ }
+
+ PK11_FreeSlotList( /* slot list */ list );
+
+ return SECSuccess;
+}
+
diff --git a/base/native-tools/src/tkstool/pppolicy.c b/base/native-tools/src/tkstool/pppolicy.c
new file mode 100644
index 000000000..8b198ca52
--- /dev/null
+++ b/base/native-tools/src/tkstool/pppolicy.c
@@ -0,0 +1,306 @@
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/pppolicy.c
+ */
+
+/*
+ * Support for various policy related extensions
+ *
+ * $Id$
+ */
+
+#include "seccomon.h"
+#include "secport.h"
+#include "secder.h"
+#include "cert.h"
+#include "secoid.h"
+#include "secasn1.h"
+#include "secerr.h"
+#include "nspr.h"
+#include "secutil.h"
+
+/* This implementation is derived from the one in nss/lib/certdb/policyxtn.c .
+** The chief difference is the addition of the OPTIONAL flag to many
+** parts. The idea is to be able to parse and print as much of the
+** policy extension as possible, even if some parts are invalid.
+**
+** If this approach still is unable to decode policy extensions that
+** contain invalid parts, then the next approach will be to parse
+** the PolicyInfos as a SEQUENCE of ANYs, and then parse each of them
+** as PolicyInfos, with the PolicyQualifiers being ANYs, and finally
+** parse each of the PolicyQualifiers.
+*/
+
+static const SEC_ASN1Template secu_PolicyQualifierTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(CERTPolicyQualifier) },
+ { SEC_ASN1_OBJECT_ID,
+ offsetof(CERTPolicyQualifier, qualifierID) },
+ { SEC_ASN1_ANY | SEC_ASN1_OPTIONAL,
+ offsetof(CERTPolicyQualifier, qualifierValue) },
+ { 0 }
+};
+
+static const SEC_ASN1Template secu_PolicyInfoTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(CERTPolicyInfo) },
+ { SEC_ASN1_OBJECT_ID,
+ offsetof(CERTPolicyInfo, policyID) },
+ { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_OPTIONAL,
+ offsetof(CERTPolicyInfo, policyQualifiers),
+ secu_PolicyQualifierTemplate },
+ { 0 }
+};
+
+static const SEC_ASN1Template secu_CertificatePoliciesTemplate[] = {
+ { SEC_ASN1_SEQUENCE_OF,
+ offsetof(CERTCertificatePolicies, policyInfos),
+ secu_PolicyInfoTemplate, sizeof(CERTCertificatePolicies) }
+};
+
+
+static CERTCertificatePolicies *
+secu_DecodeCertificatePoliciesExtension(SECItem *extnValue)
+{
+ PRArenaPool *arena = NULL;
+ SECStatus rv;
+ CERTCertificatePolicies *policies;
+ CERTPolicyInfo **policyInfos, *policyInfo;
+ CERTPolicyQualifier **policyQualifiers, *policyQualifier;
+ SECItem newExtnValue;
+
+ /* make a new arena */
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if ( !arena ) {
+ goto loser;
+ }
+
+ /* allocate the certifiate policies structure */
+ policies = PORT_ArenaZNew(arena, CERTCertificatePolicies);
+ if ( policies == NULL ) {
+ goto loser;
+ }
+
+ policies->arena = arena;
+
+ /* copy the DER into the arena, since Quick DER returns data that points
+ into the DER input, which may get freed by the caller */
+ rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ /* decode the policy info */
+ rv = SEC_QuickDERDecodeItem(arena, policies,
+ secu_CertificatePoliciesTemplate,
+ &newExtnValue);
+
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ /* initialize the oid tags */
+ policyInfos = policies->policyInfos;
+ while (policyInfos != NULL && *policyInfos != NULL ) {
+ policyInfo = *policyInfos;
+ policyInfo->oid = SECOID_FindOIDTag(&policyInfo->policyID);
+ policyQualifiers = policyInfo->policyQualifiers;
+ while ( policyQualifiers && *policyQualifiers != NULL ) {
+ policyQualifier = *policyQualifiers;
+ policyQualifier->oid =
+ SECOID_FindOIDTag(&policyQualifier->qualifierID);
+ policyQualifiers++;
+ }
+ policyInfos++;
+ }
+
+ return(policies);
+
+loser:
+ if ( arena != NULL ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return(NULL);
+}
+
+
+static char *
+itemToString(SECItem *item)
+{
+ char *string;
+
+ string = PORT_ZAlloc(item->len+1);
+ if (string == NULL) return NULL;
+ PORT_Memcpy(string,item->data,item->len);
+ string[item->len] = 0;
+ return string;
+}
+
+static SECStatus
+secu_PrintUserNoticeQualifier(FILE *out, SECItem * qualifierValue,
+ char *msg, int level)
+{
+ CERTUserNotice *userNotice = NULL;
+ if (qualifierValue)
+ userNotice = CERT_DecodeUserNotice(qualifierValue);
+ if (userNotice) {
+ if (userNotice->noticeReference.organization.len != 0) {
+ char *string =
+ itemToString(&userNotice->noticeReference.organization);
+ SECItem **itemList = userNotice->noticeReference.noticeNumbers;
+
+ while (itemList && *itemList) {
+ SECU_PrintInteger(out,*itemList,string,level+1);
+ itemList++;
+ }
+ PORT_Free(string);
+ }
+ if (userNotice->displayText.len != 0) {
+ SECU_PrintString(out,&userNotice->displayText,
+ "Display Text", level+1);
+ }
+ CERT_DestroyUserNotice(userNotice);
+ return SECSuccess;
+ }
+ return SECFailure; /* caller will print this value */
+}
+
+static SECStatus
+secu_PrintPolicyQualifier(FILE *out,CERTPolicyQualifier *policyQualifier,
+ char *msg,int level)
+{
+ SECStatus rv;
+ SECItem * qualifierValue = &policyQualifier->qualifierValue;
+
+ SECU_PrintObjectID(out, &policyQualifier->qualifierID ,
+ "Policy Qualifier Name", level);
+ if (!qualifierValue->data) {
+ SECU_Indent(out, level);
+ fprintf(out,"Error: missing qualifier\n");
+ } else
+ switch (policyQualifier->oid) {
+ case SEC_OID_PKIX_USER_NOTICE_QUALIFIER:
+ rv = secu_PrintUserNoticeQualifier(out, qualifierValue, msg, level);
+ if (SECSuccess == rv)
+ break;
+ /* fall through on error */
+ case SEC_OID_PKIX_CPS_POINTER_QUALIFIER:
+ default:
+ SECU_PrintAny(out, qualifierValue, "Policy Qualifier Data", level);
+ break;
+ }
+ return SECSuccess;
+}
+
+static SECStatus
+secu_PrintPolicyInfo(FILE *out,CERTPolicyInfo *policyInfo,char *msg,int level)
+{
+ CERTPolicyQualifier **policyQualifiers;
+
+ policyQualifiers = policyInfo->policyQualifiers;
+ SECU_PrintObjectID(out, &policyInfo->policyID , "Policy Name", level);
+
+ while (policyQualifiers && *policyQualifiers != NULL) {
+ secu_PrintPolicyQualifier(out,*policyQualifiers,"",level+1);
+ policyQualifiers++;
+ }
+ return SECSuccess;
+}
+
+void
+SECU_PrintPolicy(FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTCertificatePolicies *policies = NULL;
+ CERTPolicyInfo **policyInfos;
+
+ if (msg) {
+ SECU_Indent(out, level);
+ fprintf(out,"%s: \n",msg);
+ level++;
+ }
+ policies = secu_DecodeCertificatePoliciesExtension(value);
+ if (policies == NULL) {
+ SECU_PrintAny(out, value, "Invalid Policy Data", level);
+ return;
+ }
+
+ policyInfos = policies->policyInfos;
+ while (policyInfos && *policyInfos != NULL) {
+ secu_PrintPolicyInfo(out,*policyInfos,"",level);
+ policyInfos++;
+ }
+
+ CERT_DestroyCertificatePoliciesExtension(policies);
+}
+
+
+void
+SECU_PrintPrivKeyUsagePeriodExtension(FILE *out, SECItem *value,
+ char *msg, int level)
+{
+ CERTPrivKeyUsagePeriod * prd;
+ PLArenaPool * arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if ( !arena ) {
+ goto loser;
+ }
+ prd = CERT_DecodePrivKeyUsagePeriodExtension(arena, value);
+ if (!prd) {
+ goto loser;
+ }
+ if (prd->notBefore.data) {
+ SECU_PrintGeneralizedTime(out, &prd->notBefore, "Not Before", level);
+ }
+ if (prd->notAfter.data) {
+ SECU_PrintGeneralizedTime(out, &prd->notAfter, "Not After ", level);
+ }
+ if (!prd->notBefore.data && !prd->notAfter.data) {
+ SECU_Indent(out, level);
+ fprintf(out, "Error: notBefore or notAfter MUST be present.\n");
+loser:
+ SECU_PrintAny(out, value, msg, level);
+ }
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+}
diff --git a/base/native-tools/src/tkstool/random.c b/base/native-tools/src/tkstool/random.c
new file mode 100644
index 000000000..49dfb525e
--- /dev/null
+++ b/base/native-tools/src/tkstool/random.c
@@ -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.
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#include "tkstool.h"
+
+/* returns 0 for success, -1 for failure (EOF encountered) */
+static int
+UpdateRNG( void )
+{
+ char *randbuf;
+ int fd;
+ int i;
+ int count;
+ int c;
+ int rv = 0;
+#ifdef XP_UNIX
+ cc_t orig_cc_min;
+ cc_t orig_cc_time;
+ tcflag_t orig_lflag;
+ struct termios tio;
+#endif
+
+#define FPS PR_fprintf( PR_STDOUT,
+ FPS "\n");
+ FPS "A random seed must be generated that will be used in the\n");
+ FPS "creation of your key. One of the easiest ways to create a\n");
+ FPS "random seed is to use the timing of keystrokes on a keyboard.\n");
+ FPS "\n");
+ FPS "To begin, type keys on the keyboard until this progress meter\n");
+ FPS "is full. DO NOT USE THE AUTOREPEAT FUNCTION ON YOUR KEYBOARD!\n");
+ FPS "\n");
+ FPS "\n");
+ FPS "Continue typing until the progress meter is full:\n\n");
+ FPS "| |\r|");
+
+ /* turn off echo on stdin & return on 1 char instead of NL */
+ fd = fileno( stdin );
+
+#if defined( XP_UNIX ) && !defined( VMS )
+ tcgetattr( fd, &tio );
+ orig_lflag = tio.c_lflag;
+ orig_cc_min = tio.c_cc[VMIN];
+ orig_cc_time = tio.c_cc[VTIME];
+ tio.c_lflag &= ~ECHO;
+ tio.c_lflag &= ~ICANON;
+ tio.c_cc[VMIN] = 1;
+ tio.c_cc[VTIME] = 0;
+ tcsetattr( fd, TCSAFLUSH, &tio );
+#endif
+
+ /* Get random noise from keyboard strokes */
+ randbuf = ( char * ) PORT_Alloc( RAND_BUF_LENGTH );
+ count = 0;
+ while( randbuf != NULL && count < NUM_KEYSTROKES+1 ) {
+#ifdef VMS
+ c = GENERIC_GETCHAR_NOECHO();
+#elif XP_UNIX
+ c = getc( stdin );
+#else
+ c = getch();
+#endif
+ if( c == EOF ) {
+ rv = -1;
+ break;
+ }
+
+ PK11_RandomUpdate(
+ /* data */ randbuf,
+ /* length in bytes */ RAND_BUF_LENGTH );
+
+ if( c != randbuf[0] ) {
+ randbuf[0] = c;
+
+ FPS "\r|");
+
+ for( i = 0 ;
+ i < count / ( NUM_KEYSTROKES / RAND_BUF_LENGTH ) ;
+ i++ ) {
+ FPS "*");
+ }
+
+ if( count % ( NUM_KEYSTROKES / RAND_BUF_LENGTH ) == 1 ) {
+ FPS "/");
+ }
+
+ count++;
+ }
+ }
+
+ if (randbuf != NULL) free (randbuf);
+
+ FPS "\n\n");
+ FPS "Finished.\n");
+
+ TKS_TypeProceedToContinue();
+
+ FPS "\n");
+
+#undef FPS
+
+#if defined( XP_UNIX ) && !defined( VMS )
+ /* set back termio the way it was */
+ tio.c_lflag = orig_lflag;
+ tio.c_cc[VMIN] = orig_cc_min;
+ tio.c_cc[VTIME] = orig_cc_time;
+ tcsetattr( fd, TCSAFLUSH, &tio );
+#endif
+
+ return rv;
+}
+
+
+void
+TKS_FileForRNG( char *noise )
+{
+ char buf[2048];
+ PRFileDesc *fd;
+ PRInt32 count;
+
+ fd = PR_OpenFile( noise, PR_RDONLY, 0666 );
+ if( !fd ) {
+ return;
+ }
+
+ do {
+ count = PR_Read( fd, buf, sizeof( buf ) );
+ if (count > 0) {
+ PK11_RandomUpdate(
+ /* data */ buf,
+ /* length in bytes */ count );
+ }
+ } while( count > 0 );
+
+ PR_Close( fd );
+}
+
+
+SECStatus
+TKS_SeedRNG( char *noise )
+{
+ /* Clear the screen */
+ TKS_ClearScreen();
+
+ /* Seed the RNG */
+ if( noise ) {
+ TKS_FileForRNG( noise );
+ } else {
+ int rv = UpdateRNG();
+ if( rv ) {
+ PORT_SetError( PR_END_OF_FILE_ERROR );
+ return SECFailure;
+ }
+ }
+
+ return SECSuccess;
+}
+
diff --git a/base/native-tools/src/tkstool/retrieve.c b/base/native-tools/src/tkstool/retrieve.c
new file mode 100644
index 000000000..44cf3c069
--- /dev/null
+++ b/base/native-tools/src/tkstool/retrieve.c
@@ -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.
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#include "tkstool.h"
+
+PK11SymKey *
+TKS_RetrieveSymKey( PK11SlotInfo *slot,
+ char *keyname,
+ void *pwdata )
+{
+ char *name = NULL;
+ int count = 0;
+ int keys_found = 0;
+ PK11SymKey *symKey = NULL;
+ PK11SymKey *nextSymKey = NULL;
+ PK11SymKey *rvSymKey = NULL;
+
+ if( PK11_NeedLogin( /* slot */ slot ) ) {
+ PK11_Authenticate(
+ /* slot */ slot,
+ /* load certs */ PR_TRUE,
+ /* wincx */ pwdata );
+ }
+
+ /* Initialize the symmetric key list. */
+ symKey = PK11_ListFixedKeysInSlot(
+ /* slot */ slot,
+ /* nickname */ NULL,
+ /* wincx */ ( void *) pwdata );
+
+ /* Iterate through the symmetric key list. */
+ while( symKey != NULL ) {
+ name = PK11_GetSymKeyNickname( /* symmetric key */ symKey );
+ if( name != NULL ) {
+ if( keyname != NULL ) {
+ if( PL_strcmp( keyname, name ) == 0 ) {
+ keys_found++;
+ }
+ }
+ }
+
+ nextSymKey = PK11_GetNextSymKey( /* symmetric key */ symKey );
+ PK11_FreeSymKey( /* symmetric key */ symKey );
+ symKey = nextSymKey;
+
+ count++;
+ }
+
+ /* case 1: the token is empty */
+ if( count == 0 ) {
+ /* the specified token is empty */
+ rvSymKey = NULL;
+ goto retrievedSymKey;
+ }
+
+ /* case 2: the specified key is not on this token */
+ if( ( keyname != NULL ) &&
+ ( keys_found == 0 ) ) {
+ /* the key called "keyname" could not be found */
+ rvSymKey = NULL;
+ goto retrievedSymKey;
+ }
+
+ /* case 3: the specified key exists more than once on this token */
+ if( keys_found != 1 ) {
+ /* more than one key called "keyname" was found on this token */
+ rvSymKey = NULL;
+ goto retrievedSymKey;
+ } else {
+ /* Re-initialize the symmetric key list. */
+ symKey = PK11_ListFixedKeysInSlot(
+ /* slot */ slot,
+ /* nickname */ NULL,
+ /* wincx */ ( void *) pwdata );
+
+ /* Reiterate through the symmetric key list once more, */
+ /* this time returning an actual reference to the key. */
+ while( symKey != NULL ) {
+ name = PK11_GetSymKeyNickname( /* symmetric key */ symKey );
+ if( name != NULL ) {
+ if( keyname != NULL ) {
+ if( PL_strcmp( keyname, name ) == 0 ) {
+ rvSymKey = symKey;
+ goto retrievedSymKey;
+ }
+ }
+ }
+
+ nextSymKey = PK11_GetNextSymKey( /* symmetric key */ symKey );
+ PK11_FreeSymKey( /* symmetric key */ symKey );
+ symKey = nextSymKey;
+ }
+ }
+
+retrievedSymKey:
+ return rvSymKey;
+}
+
diff --git a/base/native-tools/src/tkstool/secerror.c b/base/native-tools/src/tkstool/secerror.c
new file mode 100644
index 000000000..6b0f40d70
--- /dev/null
+++ b/base/native-tools/src/tkstool/secerror.c
@@ -0,0 +1,118 @@
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/secerror.c
+ */
+
+#include "nspr.h"
+
+struct tuple_str {
+ PRErrorCode errNum;
+ const char * errString;
+};
+
+typedef struct tuple_str tuple_str;
+
+#define ER2(a,b) {a, b},
+#define ER3(a,b,c) {a, c},
+
+#include "secerr.h"
+#include "sslerr.h"
+
+const tuple_str errStrings[] = {
+
+/* keep this list in asceding order of error numbers */
+#include "SSLerrs.h"
+#include "SECerrs.h"
+#include "NSPRerrs.h"
+
+};
+
+const PRInt32 numStrings = sizeof(errStrings) / sizeof(tuple_str);
+
+/* Returns a UTF-8 encoded constant error string for "errNum".
+ * Returns NULL of errNum is unknown.
+ */
+const char *
+SECU_Strerror(PRErrorCode errNum) {
+ PRInt32 low = 0;
+ PRInt32 high = numStrings - 1;
+ PRInt32 i;
+ PRErrorCode num;
+ static int initDone;
+
+ /* make sure table is in ascending order.
+ * binary search depends on it.
+ */
+ if (!initDone) {
+ PRErrorCode lastNum = ((PRInt32)0x80000000);
+ for (i = low; i <= high; ++i) {
+ num = errStrings[i].errNum;
+ if (num <= lastNum) {
+ fprintf(stderr,
+"sequence error in error strings at item %d\n"
+"error %d (%s)\n"
+"should come after \n"
+"error %d (%s)\n",
+ i, lastNum, errStrings[i-1].errString,
+ num, errStrings[i].errString);
+ }
+ lastNum = num;
+ }
+ initDone = 1;
+ }
+
+ /* Do binary search of table. */
+ while (low + 1 < high) {
+ i = (low + high) / 2;
+ num = errStrings[i].errNum;
+ if (errNum == num)
+ return errStrings[i].errString;
+ if (errNum < num)
+ high = i;
+ else
+ low = i;
+ }
+ if (errNum == errStrings[low].errNum)
+ return errStrings[low].errString;
+ if (errNum == errStrings[high].errNum)
+ return errStrings[high].errString;
+ return NULL;
+}
diff --git a/base/native-tools/src/tkstool/secpwd.c b/base/native-tools/src/tkstool/secpwd.c
new file mode 100644
index 000000000..542885858
--- /dev/null
+++ b/base/native-tools/src/tkstool/secpwd.c
@@ -0,0 +1,213 @@
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/secpwd.c
+ */
+
+#include "secutil.h"
+
+/*
+ * NOTE: The contents of this file are NOT used by the client.
+ * (They are part of the security library as a whole, but they are
+ * NOT USED BY THE CLIENT.) Do not change things on behalf of the
+ * client (like localizing strings), or add things that are only
+ * for the client (put them elsewhere).
+ */
+
+
+#ifdef XP_UNIX
+#include <termios.h>
+#endif
+
+#if defined(XP_UNIX) || defined(XP_BEOS)
+#include <unistd.h> /* for isatty() */
+#endif
+
+#if( defined(_WINDOWS) && !defined(_WIN32_WCE)) || defined(XP_OS2_VACPP)
+#include <conio.h>
+#include <io.h>
+#define QUIET_FGETS quiet_fgets
+static char * quiet_fgets (char *buf, int length, FILE *input);
+#else
+#define QUIET_FGETS fgets
+#endif
+
+static void echoOff(int fd)
+{
+#if defined(XP_UNIX) && !defined(VMS)
+ if (isatty(fd)) {
+ struct termios tio;
+ tcgetattr(fd, &tio);
+ tio.c_lflag &= ~ECHO;
+ tcsetattr(fd, TCSAFLUSH, &tio);
+ }
+#endif
+}
+
+static void echoOn(int fd)
+{
+#if defined(XP_UNIX) && !defined(VMS)
+ if (isatty(fd)) {
+ struct termios tio;
+ tcgetattr(fd, &tio);
+ tio.c_lflag |= ECHO;
+ tcsetattr(fd, TCSAFLUSH, &tio);
+ }
+#endif
+}
+
+char *SEC_GetPassword(FILE *input, FILE *output, char *prompt,
+ PRBool (*ok)(char *))
+{
+#if defined(_WINDOWS)
+ int isTTY = (input == stdin);
+#define echoOn(x)
+#define echoOff(x)
+#else
+ int infd = fileno(input);
+ int isTTY = isatty(infd);
+#endif
+ char phrase[200] = {'\0'}; /* ensure EOF doesn't return junk */
+
+ for (;;) {
+ /* Prompt for password */
+ if (isTTY) {
+ fprintf(output, "%s", prompt);
+ fflush (output);
+ echoOff(infd);
+ }
+
+ QUIET_FGETS ( phrase, sizeof(phrase), input);
+
+ if (isTTY) {
+ fprintf(output, "\n");
+ echoOn(infd);
+ }
+
+ /* stomp on newline */
+ phrase[PORT_Strlen(phrase)-1] = 0;
+
+ /* Validate password */
+ if (!(*ok)(phrase)) {
+ /* Not weird enough */
+ if (!isTTY) return 0;
+ fprintf(output, "Password must be at least 8 characters long with one or more\n");
+ fprintf(output, "non-alphabetic characters\n");
+ continue;
+ }
+ return (char*) PORT_Strdup(phrase);
+ }
+}
+
+
+
+PRBool SEC_CheckPassword(char *cp)
+{
+ int len;
+ char *end;
+
+ len = PORT_Strlen(cp);
+ if (len < 8) {
+ return PR_FALSE;
+ }
+ end = cp + len;
+ while (cp < end) {
+ unsigned char ch = *cp++;
+ if (!((ch >= 'A') && (ch <= 'Z')) &&
+ !((ch >= 'a') && (ch <= 'z'))) {
+ /* pass phrase has at least one non alphabetic in it */
+ return PR_TRUE;
+ }
+ }
+ return PR_FALSE;
+}
+
+PRBool SEC_BlindCheckPassword(char *cp)
+{
+ if (cp != NULL) {
+ return PR_TRUE;
+ }
+ return PR_FALSE;
+}
+
+/* Get a password from the input terminal, without echoing */
+
+#if defined(_WINDOWS) || defined(XP_OS2_VACPP)
+static char * quiet_fgets (char *buf, int length, FILE *input)
+ {
+ int c;
+ char *end = buf;
+
+ /* fflush (input); */
+ memset (buf, 0, length);
+
+#ifndef XP_OS2_VACPP
+ if (input != stdin) {
+ return fgets(buf,length,input);
+ }
+#else
+ if (!isatty(fileno(input))) {
+ return fgets(buf,length,input);
+ }
+#endif
+
+ while (1)
+ {
+#if defined (_WIN32_WCE)
+ c = getchar(); /* gets a character from stdin */
+#else
+ c = getch(); /* getch gets a character from the console */
+#endif
+ if (c == '\b')
+ {
+ if (end > buf)
+ end--;
+ }
+
+ else if (--length > 0)
+ *end++ = c;
+
+ if (!c || c == '\n' || c == '\r')
+ break;
+ }
+
+ return buf;
+ }
+#endif
diff --git a/base/native-tools/src/tkstool/secutil.c b/base/native-tools/src/tkstool/secutil.c
new file mode 100644
index 000000000..9ece007fa
--- /dev/null
+++ b/base/native-tools/src/tkstool/secutil.c
@@ -0,0 +1,3662 @@
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/secutil.c
+ */
+
+/*
+** secutil.c - various functions used by security stuff
+**
+*/
+
+#include "prtypes.h"
+#include "prtime.h"
+#include "prlong.h"
+#include "prerror.h"
+#include "prprf.h"
+#include "plgetopt.h"
+#include "prenv.h"
+#include "prnetdb.h"
+
+#include "cryptohi.h"
+#include "secutil.h"
+#include "secpkcs7.h"
+#include <stdarg.h>
+#if !defined(_WIN32_WCE)
+#include <sys/stat.h>
+#include <errno.h>
+#endif
+
+#ifdef XP_UNIX
+#include <unistd.h>
+#endif
+
+/* for SEC_TraverseNames */
+#include "cert.h"
+#include "certt.h"
+#include "certdb.h"
+
+/* #include "secmod.h" */
+#include "pk11func.h"
+#include "secoid.h"
+
+static char consoleName[] = {
+#ifdef XP_UNIX
+#ifdef VMS
+ "TT"
+#else
+ "/dev/tty"
+#endif
+#else
+#ifdef XP_OS2
+ "\\DEV\\CON"
+#else
+ "CON:"
+#endif
+#endif
+};
+
+
+char *
+SECU_GetString(int16 error_number)
+{
+
+ static char errString[80];
+ sprintf(errString, "Unknown error string (%d)", error_number);
+ return errString;
+}
+
+void
+SECU_PrintErrMsg(FILE *out, int level, char *progName, char *msg, ...)
+{
+ va_list args;
+ PRErrorCode err = PORT_GetError();
+ const char * errString = SECU_Strerror(err);
+
+ va_start(args, msg);
+
+ SECU_Indent(out, level);
+ fprintf(out, "%s: ", progName);
+ vfprintf(out, msg, args);
+ if (errString != NULL && PORT_Strlen(errString) > 0)
+ fprintf(out, ": %s\n", errString);
+ else
+ fprintf(out, ": error %d\n", (int)err);
+
+ va_end(args);
+}
+
+void
+SECU_PrintError(char *progName, char *msg, ...)
+{
+ va_list args;
+ PRErrorCode err = PORT_GetError();
+ const char * errString = SECU_Strerror(err);
+
+ va_start(args, msg);
+
+ fprintf(stderr, "%s: ", progName);
+ vfprintf(stderr, msg, args);
+ if (errString != NULL && PORT_Strlen(errString) > 0)
+ fprintf(stderr, ": %s\n", errString);
+ else
+ fprintf(stderr, ": error %d\n", (int)err);
+
+ va_end(args);
+}
+
+void
+SECU_PrintSystemError(char *progName, char *msg, ...)
+{
+ va_list args;
+
+ va_start(args, msg);
+ fprintf(stderr, "%s: ", progName);
+ vfprintf(stderr, msg, args);
+#if defined(_WIN32_WCE)
+ fprintf(stderr, ": %d\n", PR_GetOSError());
+#else
+ fprintf(stderr, ": %s\n", strerror(errno));
+#endif
+ va_end(args);
+}
+
+static void
+secu_ClearPassword(char *p)
+{
+ if (p) {
+ PORT_Memset(p, 0, PORT_Strlen(p));
+ PORT_Free(p);
+ }
+}
+
+char *
+SECU_GetPasswordString(void *arg, char *prompt)
+{
+#ifndef _WINDOWS
+ char *p = NULL;
+ FILE *input, *output;
+
+ /* open terminal */
+ input = fopen(consoleName, "r");
+ if (input == NULL) {
+ fprintf(stderr, "Error opening input terminal for read\n");
+ return NULL;
+ }
+
+ output = fopen(consoleName, "w");
+ if (output == NULL) {
+ fprintf(stderr, "Error opening output terminal for write\n");
+ fclose(input);
+ return NULL;
+ }
+
+ p = SEC_GetPassword (input, output, prompt, SEC_BlindCheckPassword);
+
+
+ fclose(input);
+ fclose(output);
+
+ return p;
+
+#else
+ /* Win32 version of above. opening the console may fail
+ on windows95, and certainly isn't necessary.. */
+
+ char *p = NULL;
+
+ p = SEC_GetPassword (stdin, stdout, prompt, SEC_BlindCheckPassword);
+ return p;
+
+#endif
+}
+
+
+/*
+ * p a s s w o r d _ h a r d c o d e
+ *
+ * A function to use the password passed in the -f(pwfile) argument
+ * of the command line.
+ * After use once, null it out otherwise PKCS11 calls us forever.?
+ *
+ */
+char *
+SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg)
+{
+ unsigned char phrase[200];
+ PRFileDesc *fd;
+ PRInt32 nb;
+ char *pwFile = arg;
+ int i;
+
+ if (!pwFile)
+ return 0;
+
+ if (retry) {
+ return 0; /* no good retrying - the files contents will be the same */
+ }
+
+ fd = PR_Open(pwFile, PR_RDONLY, 0);
+ if (!fd) {
+ fprintf(stderr, "No password file \"%s\" exists.\n", pwFile);
+ return NULL;
+ }
+
+ nb = PR_Read(fd, phrase, sizeof(phrase));
+
+ PR_Close(fd);
+ /* handle the Windows EOL case */
+ i = 0;
+ while (phrase[i] != '\r' && phrase[i] != '\n' && i < nb) i++;
+ phrase[i] = '\0';
+ if (nb == 0) {
+ fprintf(stderr,"password file contains no data\n");
+ return NULL;
+ }
+ return (char*) PORT_Strdup((char*)phrase);
+}
+
+char *
+SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg)
+{
+ char prompt[255];
+ secuPWData *pwdata = (secuPWData *)arg;
+ secuPWData pwnull = { PW_NONE, 0 };
+ secuPWData pwxtrn = { PW_EXTERNAL, "external" };
+ char *pw;
+
+ if (pwdata == NULL)
+ pwdata = &pwnull;
+
+ if (PK11_ProtectedAuthenticationPath(slot)) {
+ pwdata = &pwxtrn;
+ }
+ if (retry && pwdata->source != PW_NONE) {
+ PR_fprintf(PR_STDERR, "Incorrect password/PIN entered.\n");
+ return NULL;
+ }
+
+ switch (pwdata->source) {
+ case PW_NONE:
+ sprintf(prompt, "Enter Password or Pin for \"%s\":",
+ PK11_GetTokenName(slot));
+ return SECU_GetPasswordString(NULL, prompt);
+ case PW_FROMFILE:
+ /* Instead of opening and closing the file every time, get the pw
+ * once, then keep it in memory (duh).
+ */
+ pw = SECU_FilePasswd(slot, retry, pwdata->data);
+ pwdata->source = PW_PLAINTEXT;
+ pwdata->data = PL_strdup(pw);
+ /* it's already been dup'ed */
+ return pw;
+ case PW_EXTERNAL:
+ sprintf(prompt,
+ "Press Enter, then enter PIN for \"%s\" on external device.\n",
+ PK11_GetTokenName(slot));
+ (void) SECU_GetPasswordString(NULL, prompt);
+ /* Fall Through */
+ case PW_PLAINTEXT:
+ return PL_strdup(pwdata->data);
+ default:
+ break;
+ }
+
+ PR_fprintf(PR_STDERR, "Password check failed: No password found.\n");
+ return NULL;
+}
+
+char *
+secu_InitSlotPassword(PK11SlotInfo *slot, PRBool retry, void *arg)
+{
+ char *p0 = NULL;
+ char *p1 = NULL;
+ FILE *input, *output;
+ secuPWData *pwdata = arg;
+
+ if (pwdata->source == PW_FROMFILE) {
+ return SECU_FilePasswd(slot, retry, pwdata->data);
+ }
+ if (pwdata->source == PW_PLAINTEXT) {
+ return PL_strdup(pwdata->data);
+ }
+
+ /* PW_NONE - get it from tty */
+ /* open terminal */
+#ifdef _WINDOWS
+ input = stdin;
+#else
+ input = fopen(consoleName, "r");
+#endif
+ if (input == NULL) {
+ PR_fprintf(PR_STDERR, "Error opening input terminal for read\n");
+ return NULL;
+ }
+
+ /* we have no password, so initialize database with one */
+ PR_fprintf(PR_STDERR,
+ "Enter a password which will be used to encrypt your keys.\n"
+ "The password should be at least 8 characters long,\n"
+ "and should contain at least one non-alphabetic character.\n\n");
+
+ output = fopen(consoleName, "w");
+ if (output == NULL) {
+ PR_fprintf(PR_STDERR, "Error opening output terminal for write\n");
+ fclose(input);
+ return NULL;
+ }
+
+
+ for (;;) {
+ if (p0)
+ PORT_Free(p0);
+ p0 = SEC_GetPassword(input, output, "Enter new password: ",
+ SEC_BlindCheckPassword);
+
+ if (p1)
+ PORT_Free(p1);
+ p1 = SEC_GetPassword(input, output, "Re-enter password: ",
+ SEC_BlindCheckPassword);
+ if (p0 && p1 && !PORT_Strcmp(p0, p1)) {
+ break;
+ }
+ PR_fprintf(PR_STDERR, "Passwords do not match. Try again.\n");
+ }
+
+ /* clear out the duplicate password string */
+ secu_ClearPassword(p1);
+
+ fclose(input);
+ fclose(output);
+
+ return p0;
+}
+
+SECStatus
+SECU_ChangePW(PK11SlotInfo *slot, char *passwd, char *pwFile)
+{
+ SECStatus rv;
+ secuPWData pwdata, newpwdata;
+ char *oldpw = NULL, *newpw = NULL;
+
+ if (passwd) {
+ pwdata.source = PW_PLAINTEXT;
+ pwdata.data = passwd;
+ } else if (pwFile) {
+ pwdata.source = PW_FROMFILE;
+ pwdata.data = pwFile;
+ } else {
+ pwdata.source = PW_NONE;
+ pwdata.data = NULL;
+ }
+
+ if (PK11_NeedUserInit(slot)) {
+ newpw = secu_InitSlotPassword(slot, PR_FALSE, &pwdata);
+ rv = PK11_InitPin(slot, (char*)NULL, newpw);
+ goto done;
+ }
+
+ for (;;) {
+ oldpw = SECU_GetModulePassword(slot, PR_FALSE, &pwdata);
+
+ if (PK11_CheckUserPassword(slot, oldpw) != SECSuccess) {
+ if (pwdata.source == PW_NONE) {
+ PR_fprintf(PR_STDERR, "Invalid password. Try again.\n");
+ } else {
+ PR_fprintf(PR_STDERR, "Invalid password.\n");
+ PORT_Memset(oldpw, 0, PL_strlen(oldpw));
+ PORT_Free(oldpw);
+ return SECFailure;
+ }
+ } else
+ break;
+
+ PORT_Free(oldpw);
+ }
+
+ newpwdata.source = PW_NONE;
+ newpwdata.data = NULL;
+
+ newpw = secu_InitSlotPassword(slot, PR_FALSE, &newpwdata);
+
+ if (PK11_ChangePW(slot, oldpw, newpw) != SECSuccess) {
+ PR_fprintf(PR_STDERR, "Failed to change password.\n");
+ return SECFailure;
+ }
+
+ PORT_Memset(oldpw, 0, PL_strlen(oldpw));
+ PORT_Free(oldpw);
+
+ PR_fprintf(PR_STDOUT, "Password changed successfully.\n");
+
+done:
+ PORT_Memset(newpw, 0, PL_strlen(newpw));
+ PORT_Free(newpw);
+ return SECSuccess;
+}
+
+struct matchobj {
+ SECItem index;
+ char *nname;
+ PRBool found;
+};
+
+char *
+SECU_DefaultSSLDir(void)
+{
+ char *dir;
+ static char sslDir[1000];
+
+ dir = PR_GetEnv("SSL_DIR");
+ if (!dir)
+ return NULL;
+
+ sprintf(sslDir, "%s", dir);
+
+ if (sslDir[strlen(sslDir)-1] == '/')
+ sslDir[strlen(sslDir)-1] = 0;
+
+ return sslDir;
+}
+
+char *
+SECU_AppendFilenameToDir(char *dir, char *filename)
+{
+ static char path[1000];
+
+ if (dir[strlen(dir)-1] == '/')
+ sprintf(path, "%s%s", dir, filename);
+ else
+ sprintf(path, "%s/%s", dir, filename);
+ return path;
+}
+
+char *
+SECU_ConfigDirectory(const char* base)
+{
+ static PRBool initted = PR_FALSE;
+ const char *dir = ".netscape";
+ char *home;
+ static char buf[1000];
+
+ if (initted) return buf;
+
+
+ if (base == NULL || *base == 0) {
+ home = PR_GetEnv("HOME");
+ if (!home) home = "";
+
+ if (*home && home[strlen(home) - 1] == '/')
+ sprintf (buf, "%.900s%s", home, dir);
+ else
+ sprintf (buf, "%.900s/%s", home, dir);
+ } else {
+ sprintf(buf, "%.900s", base);
+ if (buf[strlen(buf) - 1] == '/')
+ buf[strlen(buf) - 1] = 0;
+ }
+
+
+ initted = PR_TRUE;
+ return buf;
+}
+
+/*Turn off SSL for now */
+/* This gets called by SSL when server wants our cert & key */
+int
+SECU_GetClientAuthData(void *arg, PRFileDesc *fd,
+ struct CERTDistNamesStr *caNames,
+ struct CERTCertificateStr **pRetCert,
+ struct SECKEYPrivateKeyStr **pRetKey)
+{
+ SECKEYPrivateKey *key;
+ CERTCertificate *cert;
+ int errsave;
+
+ if (arg == NULL) {
+ fprintf(stderr, "no key/cert name specified for client auth\n");
+ return -1;
+ }
+ cert = PK11_FindCertFromNickname(arg, NULL);
+ errsave = PORT_GetError();
+ if (!cert) {
+ if (errsave == SEC_ERROR_BAD_PASSWORD)
+ fprintf(stderr, "Bad password\n");
+ else if (errsave > 0)
+ fprintf(stderr, "Unable to read cert (error %d)\n", errsave);
+ else if (errsave == SEC_ERROR_BAD_DATABASE)
+ fprintf(stderr, "Unable to get cert from database (%d)\n", errsave);
+ else
+ fprintf(stderr, "SECKEY_FindKeyByName: internal error %d\n", errsave);
+ return -1;
+ }
+
+ key = PK11_FindKeyByAnyCert(arg,NULL);
+ if (!key) {
+ fprintf(stderr, "Unable to get key (%d)\n", PORT_GetError());
+ return -1;
+ }
+
+
+ *pRetCert = cert;
+ *pRetKey = key;
+
+ return 0;
+}
+
+SECStatus
+secu_StdinToItem(SECItem *dst)
+{
+ unsigned char buf[1000];
+ PRInt32 numBytes;
+ PRBool notDone = PR_TRUE;
+
+ dst->len = 0;
+ dst->data = NULL;
+
+ while (notDone) {
+ numBytes = PR_Read(PR_STDIN, buf, sizeof(buf));
+
+ if (numBytes < 0) {
+ return SECFailure;
+ }
+
+ if (numBytes == 0)
+ break;
+
+ if (dst->data) {
+ unsigned char * p = dst->data;
+ dst->data = (unsigned char*)PORT_Realloc(p, dst->len + numBytes);
+ if (!dst->data) {
+ PORT_Free(p);
+ }
+ } else {
+ dst->data = (unsigned char*)PORT_Alloc(numBytes);
+ }
+ if (!dst->data) {
+ return SECFailure;
+ }
+ PORT_Memcpy(dst->data + dst->len, buf, numBytes);
+ dst->len += numBytes;
+ }
+
+ return SECSuccess;
+}
+
+SECStatus
+SECU_FileToItem(SECItem *dst, PRFileDesc *src)
+{
+ PRFileInfo info;
+ PRInt32 numBytes;
+ PRStatus prStatus;
+
+ if (src == PR_STDIN)
+ return secu_StdinToItem(dst);
+
+ prStatus = PR_GetOpenFileInfo(src, &info);
+
+ if (prStatus != PR_SUCCESS) {
+ PORT_SetError(SEC_ERROR_IO);
+ return SECFailure;
+ }
+
+ /* XXX workaround for 3.1, not all utils zero dst before sending */
+ dst->data = 0;
+ if (!SECITEM_AllocItem(NULL, dst, info.size))
+ goto loser;
+
+ numBytes = PR_Read(src, dst->data, info.size);
+ if (numBytes != info.size) {
+ PORT_SetError(SEC_ERROR_IO);
+ goto loser;
+ }
+
+ return SECSuccess;
+loser:
+ SECITEM_FreeItem(dst, PR_FALSE);
+ return SECFailure;
+}
+
+SECStatus
+SECU_TextFileToItem(SECItem *dst, PRFileDesc *src)
+{
+ PRFileInfo info;
+ PRInt32 numBytes;
+ PRStatus prStatus;
+ unsigned char *buf;
+
+ if (src == PR_STDIN)
+ return secu_StdinToItem(dst);
+
+ prStatus = PR_GetOpenFileInfo(src, &info);
+
+ if (prStatus != PR_SUCCESS) {
+ PORT_SetError(SEC_ERROR_IO);
+ return SECFailure;
+ }
+
+ buf = (unsigned char*)PORT_Alloc(info.size);
+ if (!buf)
+ return SECFailure;
+
+ numBytes = PR_Read(src, buf, info.size);
+ if (numBytes != info.size) {
+ PORT_SetError(SEC_ERROR_IO);
+ goto loser;
+ }
+
+ if (buf[numBytes-1] == '\n') numBytes--;
+#ifdef _WINDOWS
+ if (buf[numBytes-1] == '\r') numBytes--;
+#endif
+
+ /* XXX workaround for 3.1, not all utils zero dst before sending */
+ dst->data = 0;
+ if (!SECITEM_AllocItem(NULL, dst, numBytes))
+ goto loser;
+
+ memcpy(dst->data, buf, numBytes);
+
+ PORT_Free(buf);
+ return SECSuccess;
+loser:
+ PORT_Free(buf);
+ return SECFailure;
+}
+
+SECStatus
+SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii)
+{
+ SECStatus rv;
+ if (ascii) {
+ /* First convert ascii to binary */
+ SECItem filedata;
+ char *asc, *body;
+
+ /* Read in ascii data */
+ rv = SECU_FileToItem(&filedata, inFile);
+ asc = (char *)filedata.data;
+ if (!asc) {
+ fprintf(stderr, "unable to read data from input file\n");
+ return SECFailure;
+ }
+
+ /* check for headers and trailers and remove them */
+ if ((body = strstr(asc, "-----BEGIN")) != NULL) {
+ char *trailer = NULL;
+ asc = body;
+ body = PORT_Strchr(body, '\n');
+ if (!body)
+ body = PORT_Strchr(asc, '\r'); /* maybe this is a MAC file */
+ if (body)
+ trailer = strstr(++body, "-----END");
+ if (trailer != NULL) {
+ *trailer = '\0';
+ } else {
+ fprintf(stderr, "input has header but no trailer\n");
+ PORT_Free(filedata.data);
+ return SECFailure;
+ }
+ } else {
+ body = asc;
+ }
+
+ /* Convert to binary */
+ rv = ATOB_ConvertAsciiToItem(der, body);
+ if (rv) {
+ fprintf(stderr, "error converting ascii to binary (%s)\n",
+ SECU_Strerror(PORT_GetError()));
+ PORT_Free(filedata.data);
+ return SECFailure;
+ }
+
+ PORT_Free(filedata.data);
+ } else {
+ /* Read in binary der */
+ rv = SECU_FileToItem(der, inFile);
+ if (rv) {
+ fprintf(stderr, "error converting der (%s)\n",
+ SECU_Strerror(PORT_GetError()));
+ return SECFailure;
+ }
+ }
+ return SECSuccess;
+}
+
+#define INDENT_MULT 4
+void
+SECU_Indent(FILE *out, int level)
+{
+ int i;
+
+ for (i = 0; i < level; i++) {
+ fprintf(out, " ");
+ }
+}
+
+static void secu_Newline(FILE *out)
+{
+ fprintf(out, "\n");
+}
+
+void
+SECU_PrintAsHex(FILE *out, SECItem *data, const char *m, int level)
+{
+ unsigned i;
+ int column;
+ PRBool isString = PR_TRUE;
+ PRBool isWhiteSpace = PR_TRUE;
+ PRBool printedHex = PR_FALSE;
+ unsigned int limit = 15;
+
+ if ( m ) {
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ level++;
+ }
+
+ SECU_Indent(out, level); column = level*INDENT_MULT;
+ if (!data->len) {
+ fprintf(out, "(empty)\n");
+ return;
+ }
+ /* take a pass to see if it's all printable. */
+ for (i = 0; i < data->len; i++) {
+ unsigned char val = data->data[i];
+ if (!val || !isprint(val)) {
+ isString = PR_FALSE;
+ break;
+ }
+ if (isWhiteSpace && !isspace(val)) {
+ isWhiteSpace = PR_FALSE;
+ }
+ }
+
+ /* Short values, such as bit strings (which are printed with this
+ ** function) often look like strings, but we want to see the bits.
+ ** so this test assures that short values will be printed in hex,
+ ** perhaps in addition to being printed as strings.
+ ** The threshold size (4 bytes) is arbitrary.
+ */
+ if (!isString || data->len <= 4) {
+ for (i = 0; i < data->len; i++) {
+ if (i != data->len - 1) {
+ fprintf(out, "%02x:", data->data[i]);
+ column += 3;
+ } else {
+ fprintf(out, "%02x", data->data[i]);
+ column += 2;
+ break;
+ }
+ if (column > 76 || (i % 16 == limit)) {
+ secu_Newline(out);
+ SECU_Indent(out, level);
+ column = level*INDENT_MULT;
+ limit = i % 16;
+ }
+ }
+ printedHex = PR_TRUE;
+ }
+ if (isString && !isWhiteSpace) {
+ if (printedHex != PR_FALSE) {
+ secu_Newline(out);
+ SECU_Indent(out, level); column = level*INDENT_MULT;
+ }
+ for (i = 0; i < data->len; i++) {
+ unsigned char val = data->data[i];
+
+ if (val) {
+ fprintf(out,"%c",val);
+ column++;
+ } else {
+ column = 77;
+ }
+ if (column > 76) {
+ secu_Newline(out);
+ SECU_Indent(out, level); column = level*INDENT_MULT;
+ }
+ }
+ }
+
+ if (column != level*INDENT_MULT) {
+ secu_Newline(out);
+ }
+}
+
+static const char *hex = "0123456789abcdef";
+
+static const char printable[257] = {
+ "................" /* 0x */
+ "................" /* 1x */
+ " !\"#$%&'()*+,-./" /* 2x */
+ "0123456789:;<=>?" /* 3x */
+ "@ABCDEFGHIJKLMNO" /* 4x */
+ "PQRSTUVWXYZ[\\]^_" /* 5x */
+ "`abcdefghijklmno" /* 6x */
+ "pqrstuvwxyz{|}~." /* 7x */
+ "................" /* 8x */
+ "................" /* 9x */
+ "................" /* ax */
+ "................" /* bx */
+ "................" /* cx */
+ "................" /* dx */
+ "................" /* ex */
+ "................" /* fx */
+};
+
+void
+SECU_PrintBuf(FILE *out, const char *msg, const void *vp, int len)
+{
+ const unsigned char *cp = (const unsigned char *)vp;
+ char buf[80];
+ char *bp;
+ char *ap;
+
+ fprintf(out, "%s [Len: %d]\n", msg, len);
+ memset(buf, ' ', sizeof buf);
+ bp = buf;
+ ap = buf + 50;
+ while (--len >= 0) {
+ unsigned char ch = *cp++;
+ *bp++ = hex[(ch >> 4) & 0xf];
+ *bp++ = hex[ch & 0xf];
+ *bp++ = ' ';
+ *ap++ = printable[ch];
+ if (ap - buf >= 66) {
+ *ap = 0;
+ fprintf(out, " %s\n", buf);
+ memset(buf, ' ', sizeof buf);
+ bp = buf;
+ ap = buf + 50;
+ }
+ }
+ if (bp > buf) {
+ *ap = 0;
+ fprintf(out, " %s\n", buf);
+ }
+}
+
+SECStatus
+SECU_StripTagAndLength(SECItem *i)
+{
+ unsigned int start;
+
+ if (!i || !i->data || i->len < 2) { /* must be at least tag and length */
+ return SECFailure;
+ }
+ start = ((i->data[1] & 0x80) ? (i->data[1] & 0x7f) + 2 : 2);
+ if (i->len < start) {
+ return SECFailure;
+ }
+ i->data += start;
+ i->len -= start;
+ return SECSuccess;
+}
+
+
+/* This expents i->data[0] to be the MSB of the integer.
+** if you want to print a DER-encoded integer (with the tag and length)
+** call SECU_PrintEncodedInteger();
+*/
+void
+SECU_PrintInteger(FILE *out, SECItem *i, char *m, int level)
+{
+ int iv;
+
+ if (!i || !i->len || !i->data) {
+ SECU_Indent(out, level);
+ if (m) {
+ fprintf(out, "%s: (null)\n", m);
+ } else {
+ fprintf(out, "(null)\n");
+ }
+ } else if (i->len > 4) {
+ SECU_PrintAsHex(out, i, m, level);
+ } else {
+ iv = DER_GetInteger(i);
+ SECU_Indent(out, level);
+ if (m) {
+ fprintf(out, "%s: %d (0x%x)\n", m, iv, iv);
+ } else {
+ fprintf(out, "%d (0x%x)\n", iv, iv);
+ }
+ }
+}
+
+static void
+secu_PrintRawString(FILE *out, SECItem *si, char *m, int level)
+{
+ int column;
+ unsigned int i;
+
+ if ( m ) {
+ SECU_Indent(out, level); fprintf(out, "%s: ", m);
+ column = (level * INDENT_MULT) + strlen(m) + 2;
+ level++;
+ } else {
+ SECU_Indent(out, level);
+ column = level*INDENT_MULT;
+ }
+ fprintf(out, "\""); column++;
+
+ for (i = 0; i < si->len; i++) {
+ unsigned char val = si->data[i];
+ if (column > 76) {
+ secu_Newline(out);
+ SECU_Indent(out, level); column = level*INDENT_MULT;
+ }
+
+ fprintf(out,"%c", printable[val]); column++;
+ }
+
+ fprintf(out, "\""); column++;
+ if (column != level*INDENT_MULT || column > 76) {
+ secu_Newline(out);
+ }
+}
+
+void
+SECU_PrintString(FILE *out, SECItem *si, char *m, int level)
+{
+ SECItem my = *si;
+
+ if (SECSuccess != SECU_StripTagAndLength(&my) || !my.len)
+ return;
+ secu_PrintRawString(out, &my, m, level);
+}
+
+/* print an unencoded boolean */
+static void
+secu_PrintBoolean(FILE *out, SECItem *i, const char *m, int level)
+{
+ int val = 0;
+
+ if ( i->data && i->len ) {
+ val = i->data[0];
+ }
+
+ if (!m) {
+ m = "Boolean";
+ }
+ SECU_Indent(out, level);
+ fprintf(out, "%s: %s\n", m, (val ? "True" : "False"));
+}
+
+/*
+ * Format and print "time". If the tag message "m" is not NULL,
+ * do indent formatting based on "level" and add a newline afterward;
+ * otherwise just print the formatted time string only.
+ */
+static void
+secu_PrintTime(FILE *out, int64 time, char *m, int level)
+{
+ PRExplodedTime printableTime;
+ char *timeString;
+
+ /* Convert to local time */
+ PR_ExplodeTime(time, PR_GMTParameters, &printableTime);
+
+ timeString = PORT_Alloc(100);
+ if (timeString == NULL)
+ return;
+
+ if (m != NULL) {
+ SECU_Indent(out, level);
+ fprintf(out, "%s: ", m);
+ }
+
+ PR_FormatTime(timeString, 100, "%a %b %d %H:%M:%S %Y", &printableTime);
+ fprintf(out, timeString);
+
+ if (m != NULL)
+ fprintf(out, "\n");
+
+ PORT_Free(timeString);
+}
+
+/*
+ * Format and print the UTC Time "t". If the tag message "m" is not NULL,
+ * do indent formatting based on "level" and add a newline afterward;
+ * otherwise just print the formatted time string only.
+ */
+void
+SECU_PrintUTCTime(FILE *out, SECItem *t, char *m, int level)
+{
+ int64 time;
+ SECStatus rv;
+
+ rv = DER_UTCTimeToTime(&time, t);
+ if (rv != SECSuccess)
+ return;
+
+ secu_PrintTime(out, time, m, level);
+}
+
+/*
+ * Format and print the Generalized Time "t". If the tag message "m"
+ * is not NULL, * do indent formatting based on "level" and add a newline
+ * afterward; otherwise just print the formatted time string only.
+ */
+void
+SECU_PrintGeneralizedTime(FILE *out, SECItem *t, char *m, int level)
+{
+ int64 time;
+ SECStatus rv;
+
+
+ rv = DER_GeneralizedTimeToTime(&time, t);
+ if (rv != SECSuccess)
+ return;
+
+ secu_PrintTime(out, time, m, level);
+}
+
+/*
+ * Format and print the UTC or Generalized Time "t". If the tag message
+ * "m" is not NULL, do indent formatting based on "level" and add a newline
+ * afterward; otherwise just print the formatted time string only.
+ */
+void
+SECU_PrintTimeChoice(FILE *out, SECItem *t, char *m, int level)
+{
+ switch (t->type) {
+ case siUTCTime:
+ SECU_PrintUTCTime(out, t, m, level);
+ break;
+
+ case siGeneralizedTime:
+ SECU_PrintGeneralizedTime(out, t, m, level);
+ break;
+
+ default:
+ PORT_Assert(0);
+ break;
+ }
+}
+
+
+/* This prints a SET or SEQUENCE */
+void
+SECU_PrintSet(FILE *out, SECItem *t, char *m, int level)
+{
+ int type = t->data[0] & SEC_ASN1_TAGNUM_MASK;
+ int constructed = t->data[0] & SEC_ASN1_CONSTRUCTED;
+ const char * label;
+ SECItem my = *t;
+
+ if (!constructed) {
+ SECU_PrintAsHex(out, t, m, level);
+ return;
+ }
+ if (SECSuccess != SECU_StripTagAndLength(&my))
+ return;
+
+ SECU_Indent(out, level);
+ if (m) {
+ fprintf(out, "%s: ", m);
+ }
+
+ if (type == SEC_ASN1_SET)
+ label = "Set ";
+ else if (type == SEC_ASN1_SEQUENCE)
+ label = "Sequence ";
+ else
+ label = "";
+ fprintf(out,"%s{\n", label); /* } */
+
+ while (my.len >= 2) {
+ SECItem tmp = my;
+
+ if (tmp.data[1] & 0x80) {
+ unsigned int i;
+ unsigned int lenlen = tmp.data[1] & 0x7f;
+ if (lenlen > sizeof tmp.len)
+ break;
+ tmp.len = 0;
+ for (i=0; i < lenlen; i++) {
+ tmp.len = (tmp.len << 8) | tmp.data[2+i];
+ }
+ tmp.len += lenlen + 2;
+ } else {
+ tmp.len = tmp.data[1] + 2;
+ }
+ if (tmp.len > my.len) {
+ tmp.len = my.len;
+ }
+ my.data += tmp.len;
+ my.len -= tmp.len;
+ SECU_PrintAny(out, &tmp, NULL, level + 1);
+ }
+ SECU_Indent(out, level); fprintf(out, /* { */ "}\n");
+}
+
+static void
+secu_PrintContextSpecific(FILE *out, SECItem *i, char *m, int level)
+{
+ int type = i->data[0] & SEC_ASN1_TAGNUM_MASK;
+ int constructed = i->data[0] & SEC_ASN1_CONSTRUCTED;
+ SECItem tmp;
+
+ if (constructed) {
+ char * m2;
+ if (!m)
+ m2 = PR_smprintf("[%d]", type);
+ else
+ m2 = PR_smprintf("%s: [%d]", m, type);
+ if (m2) {
+ SECU_PrintSet(out, i, m2, level);
+ PR_smprintf_free(m2);
+ }
+ return;
+ }
+
+ SECU_Indent(out, level);
+ if (m) {
+ fprintf(out, "%s: ", m);
+ }
+ fprintf(out,"[%d]\n", type);
+
+ tmp = *i;
+ if (SECSuccess == SECU_StripTagAndLength(&tmp))
+ SECU_PrintAsHex(out, &tmp, m, level+1);
+}
+
+static void
+secu_PrintOctetString(FILE *out, SECItem *i, char *m, int level)
+{
+ SECItem tmp = *i;
+ if (SECSuccess == SECU_StripTagAndLength(&tmp))
+ SECU_PrintAsHex(out, &tmp, m, level);
+}
+
+static void
+secu_PrintBitString(FILE *out, SECItem *i, char *m, int level)
+{
+ int unused_bits;
+ SECItem tmp = *i;
+
+ if (SECSuccess != SECU_StripTagAndLength(&tmp) || tmp.len < 2)
+ return;
+
+ unused_bits = *tmp.data++;
+ tmp.len--;
+
+ SECU_PrintAsHex(out, &tmp, m, level);
+ if (unused_bits) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "(%d least significant bits unused)\n", unused_bits);
+ }
+}
+
+/* in a decoded bit string, the len member is a bit length. */
+static void
+secu_PrintDecodedBitString(FILE *out, SECItem *i, char *m, int level)
+{
+ int unused_bits;
+ SECItem tmp = *i;
+
+
+ unused_bits = (tmp.len & 0x7) ? 8 - (tmp.len & 7) : 0;
+ DER_ConvertBitString(&tmp); /* convert length to byte length */
+
+ SECU_PrintAsHex(out, &tmp, m, level);
+ if (unused_bits) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "(%d least significant bits unused)\n", unused_bits);
+ }
+}
+
+
+/* Print a DER encoded Boolean */
+void
+SECU_PrintEncodedBoolean(FILE *out, SECItem *i, char *m, int level)
+{
+ SECItem my = *i;
+ if (SECSuccess == SECU_StripTagAndLength(&my))
+ secu_PrintBoolean(out, &my, m, level);
+}
+
+/* Print a DER encoded integer */
+void
+SECU_PrintEncodedInteger(FILE *out, SECItem *i, char *m, int level)
+{
+ SECItem my = *i;
+ if (SECSuccess == SECU_StripTagAndLength(&my))
+ SECU_PrintInteger(out, &my, m, level);
+}
+
+/* Print a DER encoded OID */
+void
+SECU_PrintEncodedObjectID(FILE *out, SECItem *i, char *m, int level)
+{
+ SECItem my = *i;
+ if (SECSuccess == SECU_StripTagAndLength(&my))
+ SECU_PrintObjectID(out, &my, m, level);
+}
+
+static void
+secu_PrintBMPString(FILE *out, SECItem *i, char *m, int level)
+{
+ unsigned char * s;
+ unsigned char * d;
+ int len;
+ SECItem tmp = {0, 0, 0};
+ SECItem my = *i;
+
+ if (SECSuccess != SECU_StripTagAndLength(&my))
+ goto loser;
+ if (my.len % 2)
+ goto loser;
+ len = (int)(my.len / 2);
+ tmp.data = (unsigned char *)PORT_Alloc(len);
+ if (!tmp.data)
+ goto loser;
+ tmp.len = len;
+ for (s = my.data, d = tmp.data ; len > 0; len--) {
+ PRUint32 bmpChar = (s[0] << 8) | s[1]; s += 2;
+ if (!isprint(bmpChar))
+ goto loser;
+ *d++ = (unsigned char)bmpChar;
+ }
+ secu_PrintRawString(out, &tmp, m, level);
+ PORT_Free(tmp.data);
+ return;
+
+loser:
+ SECU_PrintAsHex(out, i, m, level);
+ if (tmp.data)
+ PORT_Free(tmp.data);
+}
+
+static void
+secu_PrintUniversalString(FILE *out, SECItem *i, char *m, int level)
+{
+ unsigned char * s;
+ unsigned char * d;
+ int len;
+ SECItem tmp = {0, 0, 0};
+ SECItem my = *i;
+
+ if (SECSuccess != SECU_StripTagAndLength(&my))
+ goto loser;
+ if (my.len % 4)
+ goto loser;
+ len = (int)(my.len / 4);
+ tmp.data = (unsigned char *)PORT_Alloc(len);
+ if (!tmp.data)
+ goto loser;
+ tmp.len = len;
+ for (s = my.data, d = tmp.data ; len > 0; len--) {
+ PRUint32 bmpChar = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
+ s += 4;
+ if (!isprint(bmpChar))
+ goto loser;
+ *d++ = (unsigned char)bmpChar;
+ }
+ secu_PrintRawString(out, &tmp, m, level);
+ PORT_Free(tmp.data);
+ return;
+
+loser:
+ SECU_PrintAsHex(out, i, m, level);
+ if (tmp.data)
+ PORT_Free(tmp.data);
+}
+
+static void
+secu_PrintUniversal(FILE *out, SECItem *i, char *m, int level)
+{
+ switch (i->data[0] & SEC_ASN1_TAGNUM_MASK) {
+ case SEC_ASN1_ENUMERATED:
+ case SEC_ASN1_INTEGER:
+ SECU_PrintEncodedInteger(out, i, m, level);
+ break;
+ case SEC_ASN1_OBJECT_ID:
+ SECU_PrintEncodedObjectID(out, i, m, level);
+ break;
+ case SEC_ASN1_BOOLEAN:
+ SECU_PrintEncodedBoolean(out, i, m, level);
+ break;
+ case SEC_ASN1_UTF8_STRING:
+ case SEC_ASN1_PRINTABLE_STRING:
+ case SEC_ASN1_VISIBLE_STRING:
+ case SEC_ASN1_IA5_STRING:
+ case SEC_ASN1_T61_STRING:
+ SECU_PrintString(out, i, m, level);
+ break;
+ case SEC_ASN1_GENERALIZED_TIME:
+ SECU_PrintGeneralizedTime(out, i, m, level);
+ break;
+ case SEC_ASN1_UTC_TIME:
+ SECU_PrintUTCTime(out, i, m, level);
+ break;
+ case SEC_ASN1_NULL:
+ SECU_Indent(out, level);
+ if (m && m[0])
+ fprintf(out, "%s: NULL\n", m);
+ else
+ fprintf(out, "NULL\n");
+ break;
+ case SEC_ASN1_SET:
+ case SEC_ASN1_SEQUENCE:
+ SECU_PrintSet(out, i, m, level);
+ break;
+ case SEC_ASN1_OCTET_STRING:
+ secu_PrintOctetString(out, i, m, level);
+ break;
+ case SEC_ASN1_BIT_STRING:
+ secu_PrintBitString(out, i, m, level);
+ break;
+ case SEC_ASN1_BMP_STRING:
+ secu_PrintBMPString(out, i, m, level);
+ break;
+ case SEC_ASN1_UNIVERSAL_STRING:
+ secu_PrintUniversalString(out, i, m, level);
+ break;
+ default:
+ SECU_PrintAsHex(out, i, m, level);
+ break;
+ }
+}
+
+void
+SECU_PrintAny(FILE *out, SECItem *i, char *m, int level)
+{
+ if ( i && i->len && i->data ) {
+ switch (i->data[0] & SEC_ASN1_CLASS_MASK) {
+ case SEC_ASN1_CONTEXT_SPECIFIC:
+ secu_PrintContextSpecific(out, i, m, level);
+ break;
+ case SEC_ASN1_UNIVERSAL:
+ secu_PrintUniversal(out, i, m, level);
+ break;
+ default:
+ SECU_PrintAsHex(out, i, m, level);
+ break;
+ }
+ }
+}
+
+static int
+secu_PrintValidity(FILE *out, CERTValidity *v, char *m, int level)
+{
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintTimeChoice(out, &v->notBefore, "Not Before", level+1);
+ SECU_PrintTimeChoice(out, &v->notAfter, "Not After ", level+1);
+ return 0;
+}
+
+/* This function does NOT expect a DER type and length. */
+SECOidTag
+SECU_PrintObjectID(FILE *out, SECItem *oid, char *m, int level)
+{
+ SECOidData *oiddata;
+ char * oidString = NULL;
+
+ oiddata = SECOID_FindOID(oid);
+ if (oiddata != NULL) {
+ const char *name = oiddata->desc;
+ SECU_Indent(out, level);
+ if (m != NULL)
+ fprintf(out, "%s: ", m);
+ fprintf(out, "%s\n", name);
+ return oiddata->offset;
+ }
+ oidString = CERT_GetOidString(oid);
+ if (oidString) {
+ SECU_Indent(out, level);
+ if (m != NULL)
+ fprintf(out, "%s: ", m);
+ fprintf(out, "%s\n", oidString);
+ PR_smprintf_free(oidString);
+ return SEC_OID_UNKNOWN;
+ }
+ SECU_PrintAsHex(out, oid, m, level);
+ return SEC_OID_UNKNOWN;
+}
+
+
+/* This function does NOT expect a DER type and length. */
+void
+SECU_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, char *m, int level)
+{
+ SECU_PrintObjectID(out, &a->algorithm, m, level);
+
+ if (a->parameters.len == 0
+ || (a->parameters.len == 2
+ && PORT_Memcmp(a->parameters.data, "\005\000", 2) == 0)) {
+ /* No arguments or NULL argument */
+ } else {
+ /* Print args to algorithm */
+ SECU_PrintAsHex(out, &a->parameters, "Args", level+1);
+ }
+}
+
+static void
+secu_PrintAttribute(FILE *out, SEC_PKCS7Attribute *attr, char *m, int level)
+{
+ SECItem *value;
+ int i;
+ char om[100];
+
+ if (m) {
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ }
+
+ /*
+ * Should make this smarter; look at the type field and then decode
+ * and print the value(s) appropriately!
+ */
+ SECU_PrintObjectID(out, &(attr->type), "Type", level+1);
+ if (attr->values != NULL) {
+ i = 0;
+ while ((value = attr->values[i++]) != NULL) {
+ sprintf(om, "Value (%d)%s", i, attr->encoded ? " (encoded)" : "");
+ if (attr->encoded || attr->typeTag == NULL) {
+ SECU_PrintAny(out, value, om, level+1);
+ } else {
+ switch (attr->typeTag->offset) {
+ default:
+ SECU_PrintAsHex(out, value, om, level+1);
+ break;
+ case SEC_OID_PKCS9_CONTENT_TYPE:
+ SECU_PrintObjectID(out, value, om, level+1);
+ break;
+ case SEC_OID_PKCS9_SIGNING_TIME:
+ SECU_PrintTimeChoice(out, value, om, level+1);
+ break;
+ }
+ }
+ }
+ }
+}
+
+static void
+secu_PrintRSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level)
+{
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &pk->u.rsa.modulus, "Modulus", level+1);
+ SECU_PrintInteger(out, &pk->u.rsa.publicExponent, "Exponent", level+1);
+ if (pk->u.rsa.publicExponent.len == 1 &&
+ pk->u.rsa.publicExponent.data[0] == 1) {
+ SECU_Indent(out, level +1); fprintf(out, "Error: INVALID RSA KEY!\n");
+ }
+}
+
+static void
+secu_PrintDSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level)
+{
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &pk->u.dsa.params.prime, "Prime", level+1);
+ SECU_PrintInteger(out, &pk->u.dsa.params.subPrime, "Subprime", level+1);
+ SECU_PrintInteger(out, &pk->u.dsa.params.base, "Base", level+1);
+ SECU_PrintInteger(out, &pk->u.dsa.publicValue, "PublicValue", level+1);
+}
+
+#ifdef NSS_ENABLE_ECC
+static void
+secu_PrintECPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level)
+{
+ SECItem curveOID = { siBuffer, NULL, 0};
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &pk->u.ec.publicValue, "PublicValue", level+1);
+ /* For named curves, the DEREncodedParams field contains an
+ * ASN Object ID (0x06 is SEC_ASN1_OBJECT_ID).
+ */
+ if ((pk->u.ec.DEREncodedParams.len > 2) &&
+ (pk->u.ec.DEREncodedParams.data[0] == 0x06)) {
+ curveOID.len = pk->u.ec.DEREncodedParams.data[1];
+ curveOID.data = pk->u.ec.DEREncodedParams.data + 2;
+ SECU_PrintObjectID(out, &curveOID, "Curve", level +1);
+ }
+}
+#endif /* NSS_ENABLE_ECC */
+
+static void
+secu_PrintSubjectPublicKeyInfo(FILE *out, PRArenaPool *arena,
+ CERTSubjectPublicKeyInfo *i, char *msg, int level)
+{
+ SECKEYPublicKey *pk;
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", msg);
+ SECU_PrintAlgorithmID(out, &i->algorithm, "Public Key Algorithm", level+1);
+
+ pk = SECKEY_ExtractPublicKey(i);
+ if (pk) {
+ switch (pk->keyType) {
+ case rsaKey:
+ secu_PrintRSAPublicKey(out, pk, "RSA Public Key", level +1);
+ break;
+
+ case dsaKey:
+ secu_PrintDSAPublicKey(out, pk, "DSA Public Key", level +1);
+ break;
+
+#ifdef NSS_ENABLE_ECC
+ case ecKey:
+ secu_PrintECPublicKey(out, pk, "EC Public Key", level +1);
+ break;
+#endif
+
+ case dhKey:
+ case fortezzaKey:
+ case keaKey:
+ SECU_Indent(out, level);
+ fprintf(out, "unable to format this SPKI algorithm type\n");
+ goto loser;
+ default:
+ SECU_Indent(out, level);
+ fprintf(out, "unknown SPKI algorithm type\n");
+ goto loser;
+ }
+ PORT_FreeArena(pk->arena, PR_FALSE);
+ } else {
+ SECU_PrintErrMsg(out, level, "Error", "Parsing public key");
+loser:
+ if (i->subjectPublicKey.data) {
+ SECU_PrintAny(out, &i->subjectPublicKey, "Raw", level);
+ }
+ }
+}
+
+static SECStatus
+secu_PrintX509InvalidDate(FILE *out, SECItem *value, char *msg, int level)
+{
+ SECItem decodedValue;
+ SECStatus rv;
+ int64 invalidTime;
+ char *formattedTime = NULL;
+
+ decodedValue.data = NULL;
+ rv = SEC_ASN1DecodeItem (NULL, &decodedValue,
+ SEC_ASN1_GET(SEC_GeneralizedTimeTemplate),
+ value);
+ if (rv == SECSuccess) {
+ rv = DER_GeneralizedTimeToTime(&invalidTime, &decodedValue);
+ if (rv == SECSuccess) {
+ formattedTime = CERT_GenTime2FormattedAscii
+ (invalidTime, "%a %b %d %H:%M:%S %Y");
+ SECU_Indent(out, level +1);
+ fprintf (out, "%s: %s\n", msg, formattedTime);
+ PORT_Free (formattedTime);
+ }
+ }
+ PORT_Free (decodedValue.data);
+ return (rv);
+}
+
+static SECStatus
+PrintExtKeyUsageExtension (FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTOidSequence *os;
+ SECItem **op;
+
+ os = CERT_DecodeOidSequence(value);
+ if( (CERTOidSequence *)NULL == os ) {
+ return SECFailure;
+ }
+
+ for( op = os->oids; *op; op++ ) {
+ SECU_PrintObjectID(out, *op, msg, level + 1);
+ }
+ CERT_DestroyOidSequence(os);
+ return SECSuccess;
+}
+
+static SECStatus
+secu_PrintBasicConstraints(FILE *out, SECItem *value, char *msg, int level) {
+ CERTBasicConstraints constraints;
+ SECStatus rv;
+
+ SECU_Indent(out, level);
+ if (msg) {
+ fprintf(out,"%s: ",msg);
+ }
+ rv = CERT_DecodeBasicConstraintValue(&constraints,value);
+ if (rv == SECSuccess && constraints.isCA) {
+ if (constraints.pathLenConstraint >= 0) {
+ fprintf(out,"Is a CA with a maximum path length of %d.\n",
+ constraints.pathLenConstraint);
+ } else {
+ fprintf(out,"Is a CA with no maximum path length.\n");
+ }
+ } else {
+ fprintf(out,"Is not a CA.\n");
+ }
+ return SECSuccess;
+}
+
+static const char * const nsTypeBits[] = {
+ "SSL Client",
+ "SSL Server",
+ "S/MIME",
+ "Object Signing",
+ "Reserved",
+ "SSL CA",
+ "S/MIME CA",
+ "ObjectSigning CA"
+};
+
+/* NSCertType is merely a bit string whose bits are displayed symbolically */
+static SECStatus
+secu_PrintNSCertType(FILE *out, SECItem *value, char *msg, int level)
+{
+ int unused;
+ int NS_Type;
+ int i;
+ int found = 0;
+ SECItem my = *value;
+
+ if ((my.data[0] != SEC_ASN1_BIT_STRING) ||
+ SECSuccess != SECU_StripTagAndLength(&my)) {
+ SECU_PrintAny(out, value, "Data", level);
+ return SECSuccess;
+ }
+
+ unused = (my.len == 2) ? (my.data[0] & 0x0f) : 0;
+ NS_Type = my.data[1] & (0xff << unused);
+
+
+ SECU_Indent(out, level);
+ if (msg) {
+ fprintf(out,"%s: ",msg);
+ } else {
+ fprintf(out,"Netscape Certificate Type: ");
+ }
+ for (i=0; i < 8; i++) {
+ if ( (0x80 >> i) & NS_Type) {
+ fprintf(out, "%c%s", (found ? ',' : '<'), nsTypeBits[i]);
+ found = 1;
+ }
+ }
+ fprintf(out, (found ? ">\n" : "none\n"));
+ return SECSuccess;
+}
+
+static const char * const usageBits[] = {
+ "Digital Signature", /* 0x80 */
+ "Non-Repudiation", /* 0x40 */
+ "Key Encipherment", /* 0x20 */
+ "Data Encipherment", /* 0x10 */
+ "Key Agreement", /* 0x08 */
+ "Certificate Signing", /* 0x04 */
+ "CRL Signing", /* 0x02 */
+ "Encipher Only", /* 0x01 */
+ "Decipher Only", /* 0x0080 */
+ NULL
+};
+
+/* X509KeyUsage is merely a bit string whose bits are displayed symbolically */
+static void
+secu_PrintX509KeyUsage(FILE *out, SECItem *value, char *msg, int level)
+{
+ int unused;
+ int usage;
+ int i;
+ int found = 0;
+ SECItem my = *value;
+
+ if ((my.data[0] != SEC_ASN1_BIT_STRING) ||
+ SECSuccess != SECU_StripTagAndLength(&my)) {
+ SECU_PrintAny(out, value, "Data", level);
+ return;
+ }
+
+ unused = (my.len >= 2) ? (my.data[0] & 0x0f) : 0;
+ usage = (my.len == 2) ? (my.data[1] & (0xff << unused)) << 8
+ : (my.data[1] << 8) |
+ (my.data[2] & (0xff << unused));
+
+ SECU_Indent(out, level);
+ fprintf(out, "Usages: ");
+ for (i=0; usageBits[i]; i++) {
+ if ( (0x8000 >> i) & usage) {
+ if (found)
+ SECU_Indent(out, level + 2);
+ fprintf(out, "%s\n", usageBits[i]);
+ found = 1;
+ }
+ }
+ if (!found) {
+ fprintf(out, "(none)\n");
+ }
+}
+
+static void
+secu_PrintIPAddress(FILE *out, SECItem *value, char *msg, int level)
+{
+ PRStatus st;
+ PRNetAddr addr;
+ char addrBuf[80];
+
+ memset(&addr, 0, sizeof addr);
+ if (value->len == 4) {
+ addr.inet.family = PR_AF_INET;
+ memcpy(&addr.inet.ip, value->data, value->len);
+ } else if (value->len == 16) {
+ addr.ipv6.family = PR_AF_INET6;
+ memcpy(addr.ipv6.ip.pr_s6_addr, value->data, value->len);
+ if (PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped)) {
+ /* convert to IPv4. */
+ addr.inet.family = PR_AF_INET;
+ memcpy(&addr.inet.ip, &addr.ipv6.ip.pr_s6_addr[12], 4);
+ memset(&addr.inet.pad[0], 0, sizeof addr.inet.pad);
+ }
+ } else {
+ goto loser;
+ }
+
+ st = PR_NetAddrToString(&addr, addrBuf, sizeof addrBuf);
+ if (st == PR_SUCCESS) {
+ SECU_Indent(out, level);
+ fprintf(out, "%s: %s\n", msg, addrBuf);
+ } else {
+loser:
+ SECU_PrintAsHex(out, value, msg, level);
+ }
+}
+
+
+static void
+secu_PrintGeneralName(FILE *out, CERTGeneralName *gname, char *msg, int level)
+{
+ char label[40];
+ if (msg && msg[0]) {
+ SECU_Indent(out, level++); fprintf(out, "%s: \n", msg);
+ }
+ switch (gname->type) {
+ case certOtherName :
+ SECU_PrintAny( out, &gname->name.OthName.name, "Other Name", level);
+ SECU_PrintObjectID(out, &gname->name.OthName.oid, "OID", level+1);
+ break;
+ case certDirectoryName :
+ SECU_PrintName(out, &gname->name.directoryName, "Directory Name", level);
+ break;
+ case certRFC822Name :
+ secu_PrintRawString( out, &gname->name.other, "RFC822 Name", level);
+ break;
+ case certDNSName :
+ secu_PrintRawString( out, &gname->name.other, "DNS name", level);
+ break;
+ case certURI :
+ secu_PrintRawString( out, &gname->name.other, "URI", level);
+ break;
+ case certIPAddress :
+ secu_PrintIPAddress(out, &gname->name.other, "IP Address", level);
+ break;
+ case certRegisterID :
+ SECU_PrintObjectID( out, &gname->name.other, "Registered ID", level);
+ break;
+ case certX400Address :
+ SECU_PrintAny( out, &gname->name.other, "X400 Address", level);
+ break;
+ case certEDIPartyName :
+ SECU_PrintAny( out, &gname->name.other, "EDI Party", level);
+ break;
+ default:
+ PR_snprintf(label, sizeof label, "unknown type [%d]",
+ (int)gname->type - 1);
+ SECU_PrintAsHex(out, &gname->name.other, label, level);
+ break;
+ }
+}
+
+static void
+secu_PrintAuthKeyIDExtension(FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTAuthKeyID *kid = NULL;
+ PLArenaPool *pool = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if (!pool) {
+ SECU_PrintError("Error", "Allocating new ArenaPool");
+ return;
+ }
+ kid = CERT_DecodeAuthKeyID(pool, value);
+ if (!kid) {
+ SECU_PrintErrMsg(out, level, "Error", "Parsing extension");
+ SECU_PrintAny(out, value, "Data", level);
+ } else {
+ int keyIDPresent = (kid->keyID.data && kid->keyID.len);
+ int issuerPresent = kid->authCertIssuer != NULL;
+ int snPresent = (kid->authCertSerialNumber.data &&
+ kid->authCertSerialNumber.len);
+
+ if ((keyIDPresent && !issuerPresent && !snPresent) ||
+ (!keyIDPresent && issuerPresent && snPresent)) {
+ /* all is well */
+ } else {
+ SECU_Indent(out, level);
+ fprintf(out,
+ "Error: KeyID OR (Issuer AND Serial) must be present, not both.\n");
+ }
+ if (keyIDPresent)
+ SECU_PrintAsHex(out, &kid->keyID, "Key ID", level);
+ if (issuerPresent)
+ secu_PrintGeneralName(out, kid->authCertIssuer, "Issuer", level);
+ if (snPresent)
+ SECU_PrintInteger(out, &kid->authCertSerialNumber,
+ "Serial Number", level);
+ }
+ PORT_FreeArena(pool, PR_FALSE);
+}
+
+
+static void
+secu_PrintAltNameExtension(FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTGeneralName * nameList;
+ CERTGeneralName * current;
+ PLArenaPool * pool = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if (!pool) {
+ SECU_PrintError("Error", "Allocating new ArenaPool");
+ return;
+ }
+ nameList = current = CERT_DecodeAltNameExtension(pool, value);
+ if (!current) {
+ if (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) {
+ /* Decoder found empty sequence, which is invalid. */
+ PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
+ }
+ SECU_PrintErrMsg(out, level, "Error", "Parsing extension");
+ SECU_PrintAny(out, value, "Data", level);
+ } else {
+ do {
+ secu_PrintGeneralName(out, current, msg, level);
+ current = CERT_GetNextGeneralName(current);
+ } while (current != nameList);
+ }
+ PORT_FreeArena(pool, PR_FALSE);
+}
+
+static void
+secu_PrintCRLDistPtsExtension(FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTCrlDistributionPoints * dPoints;
+ PLArenaPool * pool = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if (!pool) {
+ SECU_PrintError("Error", "Allocating new ArenaPool");
+ return;
+ }
+ dPoints = CERT_DecodeCRLDistributionPoints(pool, value);
+ if (dPoints && dPoints->distPoints && dPoints->distPoints[0]) {
+ CRLDistributionPoint ** pPoints = dPoints->distPoints;
+ CRLDistributionPoint * pPoint;
+ while (NULL != (pPoint = *pPoints++)) {
+ if (pPoint->distPointType == generalName &&
+ pPoint->distPoint.fullName != NULL) {
+ secu_PrintGeneralName(out, pPoint->distPoint.fullName, NULL,
+ level);
+#if defined(LATER)
+ } else if (pPoint->distPointType == relativeDistinguishedName) {
+ /* print the relative name */
+#endif
+ } else if (pPoint->derDistPoint.data) {
+ SECU_PrintAny(out, &pPoint->derDistPoint, "Point", level);
+ }
+ if (pPoint->reasons.data) {
+ secu_PrintDecodedBitString(out, &pPoint->reasons, "Reasons",
+ level);
+ }
+ if (pPoint->crlIssuer) {
+ secu_PrintGeneralName(out, pPoint->crlIssuer, "Issuer", level);
+ }
+ }
+ } else {
+ SECU_PrintErrMsg(out, level, "Error", "Parsing extension");
+ SECU_PrintAny(out, value, "Data", level);
+ }
+ PORT_FreeArena(pool, PR_FALSE);
+}
+
+
+static void
+secu_PrintNameConstraintSubtree(FILE *out, CERTNameConstraint *value,
+ char *msg, int level)
+{
+ CERTNameConstraint *head = value;
+ SECU_Indent(out, level); fprintf(out, "%s Subtree:\n", msg);
+ level++;
+ do {
+ secu_PrintGeneralName(out, &value->name, NULL, level);
+ if (value->min.data)
+ SECU_PrintInteger(out, &value->min, "Minimum", level+1);
+ if (value->max.data)
+ SECU_PrintInteger(out, &value->max, "Maximum", level+1);
+ value = CERT_GetNextNameConstraint(value);
+ } while (value != head);
+}
+
+static void
+secu_PrintNameConstraintsExtension(FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTNameConstraints * cnstrnts;
+ PLArenaPool * pool = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if (!pool) {
+ SECU_PrintError("Error", "Allocating new ArenaPool");
+ return;
+ }
+ cnstrnts = CERT_DecodeNameConstraintsExtension(pool, value);
+ if (!cnstrnts) {
+ SECU_PrintErrMsg(out, level, "Error", "Parsing extension");
+ SECU_PrintAny(out, value, "Raw", level);
+ } else {
+ if (cnstrnts->permited)
+ secu_PrintNameConstraintSubtree(out, cnstrnts->permited,
+ "Permitted", level);
+ if (cnstrnts->excluded)
+ secu_PrintNameConstraintSubtree(out, cnstrnts->excluded,
+ "Excluded", level);
+ }
+ PORT_FreeArena(pool, PR_FALSE);
+}
+
+
+static void
+secu_PrintAuthorityInfoAcess(FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTAuthInfoAccess **infos = NULL;
+ PLArenaPool * pool = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if (!pool) {
+ SECU_PrintError("Error", "Allocating new ArenaPool");
+ return;
+ }
+ infos = CERT_DecodeAuthInfoAccessExtension(pool, value);
+ if (!infos) {
+ SECU_PrintErrMsg(out, level, "Error", "Parsing extension");
+ SECU_PrintAny(out, value, "Raw", level);
+ } else {
+ CERTAuthInfoAccess *info;
+ while (NULL != (info = *infos++)) {
+ if (info->method.data) {
+ SECU_PrintObjectID(out, &info->method, "Method", level);
+ } else {
+ SECU_Indent(out,level);
+ fprintf(out, "Error: missing method\n");
+ }
+ if (info->location) {
+ secu_PrintGeneralName(out, info->location, "Location", level);
+ } else {
+ SECU_PrintAny(out, &info->derLocation, "Location", level);
+ }
+ }
+ }
+ PORT_FreeArena(pool, PR_FALSE);
+}
+
+
+void
+SECU_PrintExtensions(FILE *out, CERTCertExtension **extensions,
+ char *msg, int level)
+{
+ SECOidTag oidTag;
+
+ if ( extensions ) {
+ if (msg && *msg) {
+ SECU_Indent(out, level++); fprintf(out, "%s:\n", msg);
+ }
+
+ while ( *extensions ) {
+ SECItem *tmpitem;
+
+ tmpitem = &(*extensions)->id;
+ SECU_PrintObjectID(out, tmpitem, "Name", level);
+
+ tmpitem = &(*extensions)->critical;
+ if ( tmpitem->len ) {
+ secu_PrintBoolean(out, tmpitem, "Critical", level);
+ }
+
+ oidTag = SECOID_FindOIDTag (&((*extensions)->id));
+ tmpitem = &((*extensions)->value);
+
+ switch (oidTag) {
+ case SEC_OID_X509_INVALID_DATE:
+ case SEC_OID_NS_CERT_EXT_CERT_RENEWAL_TIME:
+ secu_PrintX509InvalidDate(out, tmpitem, "Date", level );
+ break;
+ case SEC_OID_X509_CERTIFICATE_POLICIES:
+ SECU_PrintPolicy(out, tmpitem, "Data", level );
+ break;
+ case SEC_OID_NS_CERT_EXT_BASE_URL:
+ case SEC_OID_NS_CERT_EXT_REVOCATION_URL:
+ case SEC_OID_NS_CERT_EXT_CA_REVOCATION_URL:
+ case SEC_OID_NS_CERT_EXT_CA_CRL_URL:
+ case SEC_OID_NS_CERT_EXT_CA_CERT_URL:
+ case SEC_OID_NS_CERT_EXT_CERT_RENEWAL_URL:
+ case SEC_OID_NS_CERT_EXT_CA_POLICY_URL:
+ case SEC_OID_NS_CERT_EXT_HOMEPAGE_URL:
+ case SEC_OID_NS_CERT_EXT_LOST_PASSWORD_URL:
+ case SEC_OID_OCSP_RESPONDER:
+ SECU_PrintString(out,tmpitem, "URL", level);
+ break;
+ case SEC_OID_NS_CERT_EXT_COMMENT:
+ SECU_PrintString(out,tmpitem, "Comment", level);
+ break;
+ case SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME:
+ SECU_PrintString(out,tmpitem, "ServerName", level);
+ break;
+ case SEC_OID_NS_CERT_EXT_CERT_TYPE:
+ secu_PrintNSCertType(out,tmpitem,"Data",level);
+ break;
+ case SEC_OID_X509_BASIC_CONSTRAINTS:
+ secu_PrintBasicConstraints(out,tmpitem,"Data",level);
+ break;
+ case SEC_OID_X509_EXT_KEY_USAGE:
+ PrintExtKeyUsageExtension(out, tmpitem, NULL, level);
+ break;
+ case SEC_OID_X509_KEY_USAGE:
+ secu_PrintX509KeyUsage(out, tmpitem, NULL, level );
+ break;
+ case SEC_OID_X509_AUTH_KEY_ID:
+ secu_PrintAuthKeyIDExtension(out, tmpitem, NULL, level );
+ break;
+ case SEC_OID_X509_SUBJECT_ALT_NAME:
+ case SEC_OID_X509_ISSUER_ALT_NAME:
+ secu_PrintAltNameExtension(out, tmpitem, NULL, level );
+ break;
+ case SEC_OID_X509_CRL_DIST_POINTS:
+ secu_PrintCRLDistPtsExtension(out, tmpitem, NULL, level );
+ break;
+ case SEC_OID_X509_PRIVATE_KEY_USAGE_PERIOD:
+ SECU_PrintPrivKeyUsagePeriodExtension(out, tmpitem, NULL,
+ level );
+ break;
+ case SEC_OID_X509_NAME_CONSTRAINTS:
+ secu_PrintNameConstraintsExtension(out, tmpitem, NULL, level);
+ break;
+ case SEC_OID_X509_AUTH_INFO_ACCESS:
+ secu_PrintAuthorityInfoAcess(out, tmpitem, NULL, level);
+ break;
+
+ case SEC_OID_X509_CRL_NUMBER:
+ case SEC_OID_X509_REASON_CODE:
+
+ /* PKIX OIDs */
+ case SEC_OID_PKIX_OCSP:
+ case SEC_OID_PKIX_OCSP_BASIC_RESPONSE:
+ case SEC_OID_PKIX_OCSP_NONCE:
+ case SEC_OID_PKIX_OCSP_CRL:
+ case SEC_OID_PKIX_OCSP_RESPONSE:
+ case SEC_OID_PKIX_OCSP_NO_CHECK:
+ case SEC_OID_PKIX_OCSP_ARCHIVE_CUTOFF:
+ case SEC_OID_PKIX_OCSP_SERVICE_LOCATOR:
+ case SEC_OID_PKIX_REGCTRL_REGTOKEN:
+ case SEC_OID_PKIX_REGCTRL_AUTHENTICATOR:
+ case SEC_OID_PKIX_REGCTRL_PKIPUBINFO:
+ case SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS:
+ case SEC_OID_PKIX_REGCTRL_OLD_CERT_ID:
+ case SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY:
+ case SEC_OID_PKIX_REGINFO_UTF8_PAIRS:
+ case SEC_OID_PKIX_REGINFO_CERT_REQUEST:
+
+ /* Netscape extension OIDs. */
+ case SEC_OID_NS_CERT_EXT_NETSCAPE_OK:
+ case SEC_OID_NS_CERT_EXT_ISSUER_LOGO:
+ case SEC_OID_NS_CERT_EXT_SUBJECT_LOGO:
+ case SEC_OID_NS_CERT_EXT_ENTITY_LOGO:
+ case SEC_OID_NS_CERT_EXT_USER_PICTURE:
+
+ /* x.509 v3 Extensions */
+ case SEC_OID_X509_SUBJECT_DIRECTORY_ATTR:
+ case SEC_OID_X509_SUBJECT_KEY_ID:
+ case SEC_OID_X509_POLICY_MAPPINGS:
+ case SEC_OID_X509_POLICY_CONSTRAINTS:
+
+
+ default:
+ SECU_PrintAny(out, tmpitem, "Data", level);
+ break;
+ }
+
+ secu_Newline(out);
+ extensions++;
+ }
+ }
+}
+
+
+void
+SECU_PrintName(FILE *out, CERTName *name, char *msg, int level)
+{
+ char *nameStr;
+ char *str;
+ SECItem my;
+
+ str = nameStr = CERT_NameToAscii(name);
+ if (!str) {
+ str = "!Invalid AVA!";
+ }
+ my.data = (unsigned char *)str;
+ my.len = PORT_Strlen(str);
+#if 1
+ secu_PrintRawString(out, &my, msg, level);
+#else
+ SECU_Indent(out, level); fprintf(out, "%s: ", msg);
+ fprintf(out, str);
+ secu_Newline(out);
+#endif
+ PORT_Free(nameStr);
+}
+
+void
+printflags(char *trusts, unsigned int flags)
+{
+ if (flags & CERTDB_VALID_CA)
+ if (!(flags & CERTDB_TRUSTED_CA) &&
+ !(flags & CERTDB_TRUSTED_CLIENT_CA))
+ PORT_Strcat(trusts, "c");
+ if (flags & CERTDB_VALID_PEER)
+ if (!(flags & CERTDB_TRUSTED))
+ PORT_Strcat(trusts, "p");
+ if (flags & CERTDB_TRUSTED_CA)
+ PORT_Strcat(trusts, "C");
+ if (flags & CERTDB_TRUSTED_CLIENT_CA)
+ PORT_Strcat(trusts, "T");
+ if (flags & CERTDB_TRUSTED)
+ PORT_Strcat(trusts, "P");
+ if (flags & CERTDB_USER)
+ PORT_Strcat(trusts, "u");
+ if (flags & CERTDB_SEND_WARN)
+ PORT_Strcat(trusts, "w");
+ if (flags & CERTDB_INVISIBLE_CA)
+ PORT_Strcat(trusts, "I");
+ if (flags & CERTDB_GOVT_APPROVED_CA)
+ PORT_Strcat(trusts, "G");
+ return;
+}
+
+/* callback for listing certs through pkcs11 */
+SECStatus
+SECU_PrintCertNickname(CERTCertListNode *node, void *data)
+{
+ CERTCertTrust *trust;
+ CERTCertificate* cert;
+ FILE *out;
+ char trusts[30];
+ char *name;
+
+ cert = node->cert;
+
+ PORT_Memset (trusts, 0, sizeof (trusts));
+ out = (FILE *)data;
+
+ name = node->appData;
+ if (!name || !name[0]) {
+ name = cert->nickname;
+ }
+ if (!name || !name[0]) {
+ name = cert->emailAddr;
+ }
+ if (!name || !name[0]) {
+ name = "(NULL)";
+ }
+
+ trust = cert->trust;
+ if (trust) {
+ printflags(trusts, trust->sslFlags);
+ PORT_Strcat(trusts, ",");
+ printflags(trusts, trust->emailFlags);
+ PORT_Strcat(trusts, ",");
+ printflags(trusts, trust->objectSigningFlags);
+ } else {
+ PORT_Memcpy(trusts,",,",3);
+ }
+ fprintf(out, "%-60s %-5s\n", name, trusts);
+
+ return (SECSuccess);
+}
+
+int
+SECU_DecodeAndPrintExtensions(FILE *out, SECItem *any, char *m, int level)
+{
+ CERTCertExtension **extensions = NULL;
+ PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ int rv = 0;
+
+ if (!arena)
+ return SEC_ERROR_NO_MEMORY;
+
+ rv = SEC_QuickDERDecodeItem(arena, &extensions,
+ SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate), any);
+ if (!rv)
+ SECU_PrintExtensions(out, extensions, m, level);
+ else
+ SECU_PrintAny(out, any, m, level);
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+/* print a decoded SET OF or SEQUENCE OF Extensions */
+int
+SECU_PrintSetOfExtensions(FILE *out, SECItem **any, char *m, int level)
+{
+ int rv = 0;
+ if (m && *m) {
+ SECU_Indent(out, level++); fprintf(out, "%s:\n", m);
+ }
+ while (any && any[0]) {
+ rv |= SECU_DecodeAndPrintExtensions(out, any[0], "", level);
+ any++;
+ }
+ return rv;
+}
+
+/* print a decoded SET OF or SEQUENCE OF "ANY" */
+int
+SECU_PrintSetOfAny(FILE *out, SECItem **any, char *m, int level)
+{
+ int rv = 0;
+ if (m && *m) {
+ SECU_Indent(out, level++); fprintf(out, "%s:\n", m);
+ }
+ while (any && any[0]) {
+ SECU_PrintAny(out, any[0], "", level);
+ any++;
+ }
+ return rv;
+}
+
+int
+SECU_PrintCertAttribute(FILE *out, CERTAttribute *attr, char *m, int level)
+{
+ int rv = 0;
+ SECOidTag tag;
+ tag = SECU_PrintObjectID(out, &attr->attrType, "Attribute Type", level);
+ if (tag == SEC_OID_PKCS9_EXTENSION_REQUEST) {
+ rv = SECU_PrintSetOfExtensions(out, attr->attrValue, "Extensions", level);
+ } else {
+ rv = SECU_PrintSetOfAny(out, attr->attrValue, "Attribute Values", level);
+ }
+ return rv;
+}
+
+int
+SECU_PrintCertAttributes(FILE *out, CERTAttribute **attrs, char *m, int level)
+{
+ int rv = 0;
+ while (attrs[0]) {
+ rv |= SECU_PrintCertAttribute(out, attrs[0], m, level+1);
+ attrs++;
+ }
+ return rv;
+}
+
+int /* sometimes a PRErrorCode, other times a SECStatus. Sigh. */
+SECU_PrintCertificateRequest(FILE *out, SECItem *der, char *m, int level)
+{
+ PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ CERTCertificateRequest *cr;
+ int rv = SEC_ERROR_NO_MEMORY;
+
+ if (!arena)
+ return rv;
+
+ /* Decode certificate request */
+ cr = PORT_ArenaZNew(arena, CERTCertificateRequest);
+ if (!cr)
+ goto loser;
+ cr->arena = arena;
+ rv = SEC_QuickDERDecodeItem(arena, cr,
+ SEC_ASN1_GET(CERT_CertificateRequestTemplate), der);
+ if (rv)
+ goto loser;
+
+ /* Pretty print it out */
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &cr->version, "Version", level+1);
+ SECU_PrintName(out, &cr->subject, "Subject", level+1);
+ secu_PrintSubjectPublicKeyInfo(out, arena, &cr->subjectPublicKeyInfo,
+ "Subject Public Key Info", level+1);
+ if (cr->attributes)
+ SECU_PrintCertAttributes(out, cr->attributes, "Attributes", level+1);
+ rv = 0;
+loser:
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+int
+SECU_PrintCertificate(FILE *out, SECItem *der, char *m, int level)
+{
+ PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ CERTCertificate *c;
+ int rv = SEC_ERROR_NO_MEMORY;
+ int iv;
+
+ if (!arena)
+ return rv;
+
+ /* Decode certificate */
+ c = PORT_ArenaZNew(arena, CERTCertificate);
+ if (!c)
+ goto loser;
+ c->arena = arena;
+ rv = SEC_ASN1DecodeItem(arena, c,
+ SEC_ASN1_GET(CERT_CertificateTemplate), der);
+ if (rv) {
+ SECU_Indent(out, level);
+ SECU_PrintErrMsg(out, level, "Error", "Parsing extension");
+ SECU_PrintAny(out, der, "Raw", level);
+ goto loser;
+ }
+ /* Pretty print it out */
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ iv = c->version.len ? DER_GetInteger(&c->version) : 0; /* version is optional */
+ SECU_Indent(out, level+1); fprintf(out, "%s: %d (0x%x)\n", "Version", iv + 1, iv);
+
+ SECU_PrintInteger(out, &c->serialNumber, "Serial Number", level+1);
+ SECU_PrintAlgorithmID(out, &c->signature, "Signature Algorithm", level+1);
+ SECU_PrintName(out, &c->issuer, "Issuer", level+1);
+ secu_PrintValidity(out, &c->validity, "Validity", level+1);
+ SECU_PrintName(out, &c->subject, "Subject", level+1);
+ secu_PrintSubjectPublicKeyInfo(out, arena, &c->subjectPublicKeyInfo,
+ "Subject Public Key Info", level+1);
+ if (c->issuerID.data)
+ secu_PrintDecodedBitString(out, &c->issuerID, "Issuer Unique ID", level+1);
+ if (c->subjectID.data)
+ secu_PrintDecodedBitString(out, &c->subjectID, "Subject Unique ID", level+1);
+ SECU_PrintExtensions(out, c->extensions, "Signed Extensions", level+1);
+loser:
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+int
+SECU_PrintPublicKey(FILE *out, SECItem *der, char *m, int level)
+{
+ PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ SECKEYPublicKey key;
+ int rv = SEC_ERROR_NO_MEMORY;
+
+ if (!arena)
+ return rv;
+
+ PORT_Memset(&key, 0, sizeof(key));
+ rv = SEC_ASN1DecodeItem(arena, &key,
+ SEC_ASN1_GET(SECKEY_RSAPublicKeyTemplate), der);
+ if (!rv) {
+ /* Pretty print it out */
+ secu_PrintRSAPublicKey(out, &key, m, level);
+ }
+
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+#ifdef HAVE_EPV_TEMPLATE
+int
+SECU_PrintPrivateKey(FILE *out, SECItem *der, char *m, int level)
+{
+ PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ SECKEYEncryptedPrivateKeyInfo key;
+ int rv = SEC_ERROR_NO_MEMORY;
+
+ if (!arena)
+ return rv;
+
+ PORT_Memset(&key, 0, sizeof(key));
+ rv = SEC_ASN1DecodeItem(arena, &key,
+ SEC_ASN1_GET(SECKEY_EncryptedPrivateKeyInfoTemplate), der);
+ if (rv)
+ goto loser;
+
+ /* Pretty print it out */
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintAlgorithmID(out, &key.algorithm, "Encryption Algorithm",
+ level+1);
+ SECU_PrintAsHex(out, &key.encryptedData, "Encrypted Data", level+1);
+loser:
+ PORT_FreeArena(arena, PR_TRUE);
+ return rv;
+}
+#endif
+
+int
+SECU_PrintFingerprints(FILE *out, SECItem *derCert, char *m, int level)
+{
+ unsigned char fingerprint[20];
+ char *fpStr = NULL;
+ int err = PORT_GetError();
+ SECStatus rv;
+ SECItem fpItem;
+
+ /* print MD5 fingerprint */
+ memset(fingerprint, 0, sizeof fingerprint);
+ rv = PK11_HashBuf(SEC_OID_MD5,fingerprint, derCert->data, derCert->len);
+ fpItem.data = fingerprint;
+ fpItem.len = MD5_LENGTH;
+ fpStr = CERT_Hexify(&fpItem, 1);
+ SECU_Indent(out, level); fprintf(out, "%s (MD5):\n", m);
+ SECU_Indent(out, level+1); fprintf(out, "%s\n", fpStr);
+ PORT_Free(fpStr);
+ fpStr = NULL;
+ if (rv != SECSuccess && !err)
+ err = PORT_GetError();
+
+ /* print SHA1 fingerprint */
+ memset(fingerprint, 0, sizeof fingerprint);
+ rv = PK11_HashBuf(SEC_OID_SHA1,fingerprint, derCert->data, derCert->len);
+ fpItem.data = fingerprint;
+ fpItem.len = SHA1_LENGTH;
+ fpStr = CERT_Hexify(&fpItem, 1);
+ SECU_Indent(out, level); fprintf(out, "%s (SHA1):\n", m);
+ SECU_Indent(out, level+1); fprintf(out, "%s\n", fpStr);
+ PORT_Free(fpStr);
+ fprintf(out, "\n");
+
+ if (err)
+ PORT_SetError(err);
+ if (err || rv != SECSuccess)
+ return SECFailure;
+
+ return 0;
+}
+
+/*
+** PKCS7 Support
+*/
+
+/* forward declaration */
+static int
+secu_PrintPKCS7ContentInfo(FILE *, SEC_PKCS7ContentInfo *, char *, int);
+
+/*
+** secu_PrintPKCS7EncContent
+** Prints a SEC_PKCS7EncryptedContentInfo (without decrypting it)
+*/
+static void
+secu_PrintPKCS7EncContent(FILE *out, SEC_PKCS7EncryptedContentInfo *src,
+ char *m, int level)
+{
+ if (src->contentTypeTag == NULL)
+ src->contentTypeTag = SECOID_FindOID(&(src->contentType));
+
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Content Type: %s\n",
+ (src->contentTypeTag != NULL) ? src->contentTypeTag->desc
+ : "Unknown");
+ SECU_PrintAlgorithmID(out, &(src->contentEncAlg),
+ "Content Encryption Algorithm", level+1);
+ SECU_PrintAsHex(out, &(src->encContent),
+ "Encrypted Content", level+1);
+}
+
+/*
+** secu_PrintRecipientInfo
+** Prints a PKCS7RecipientInfo type
+*/
+static void
+secu_PrintRecipientInfo(FILE *out, SEC_PKCS7RecipientInfo *info, char *m,
+ int level)
+{
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(info->version), "Version", level + 1);
+
+ SECU_PrintName(out, &(info->issuerAndSN->issuer), "Issuer",
+ level + 1);
+ SECU_PrintInteger(out, &(info->issuerAndSN->serialNumber),
+ "Serial Number", level + 1);
+
+ /* Parse and display encrypted key */
+ SECU_PrintAlgorithmID(out, &(info->keyEncAlg),
+ "Key Encryption Algorithm", level + 1);
+ SECU_PrintAsHex(out, &(info->encKey), "Encrypted Key", level + 1);
+}
+
+/*
+** secu_PrintSignerInfo
+** Prints a PKCS7SingerInfo type
+*/
+static void
+secu_PrintSignerInfo(FILE *out, SEC_PKCS7SignerInfo *info, char *m, int level)
+{
+ SEC_PKCS7Attribute *attr;
+ int iv;
+ char om[100];
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(info->version), "Version", level + 1);
+
+ SECU_PrintName(out, &(info->issuerAndSN->issuer), "Issuer",
+ level + 1);
+ SECU_PrintInteger(out, &(info->issuerAndSN->serialNumber),
+ "Serial Number", level + 1);
+
+ SECU_PrintAlgorithmID(out, &(info->digestAlg), "Digest Algorithm",
+ level + 1);
+
+ if (info->authAttr != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Authenticated Attributes:\n");
+ iv = 0;
+ while ((attr = info->authAttr[iv++]) != NULL) {
+ sprintf(om, "Attribute (%d)", iv);
+ secu_PrintAttribute(out, attr, om, level + 2);
+ }
+ }
+
+ /* Parse and display signature */
+ SECU_PrintAlgorithmID(out, &(info->digestEncAlg),
+ "Digest Encryption Algorithm", level + 1);
+ SECU_PrintAsHex(out, &(info->encDigest), "Encrypted Digest", level + 1);
+
+ if (info->unAuthAttr != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Unauthenticated Attributes:\n");
+ iv = 0;
+ while ((attr = info->unAuthAttr[iv++]) != NULL) {
+ sprintf(om, "Attribute (%x)", iv);
+ secu_PrintAttribute(out, attr, om, level + 2);
+ }
+ }
+}
+
+/* callers of this function must make sure that the CERTSignedCrl
+ from which they are extracting the CERTCrl has been fully-decoded.
+ Otherwise it will not have the entries even though the CRL may have
+ some */
+
+void
+SECU_PrintCRLInfo(FILE *out, CERTCrl *crl, char *m, int level)
+{
+ CERTCrlEntry *entry;
+ int iv;
+ char om[100];
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ /* version is optional */
+ iv = crl->version.len ? DER_GetInteger(&crl->version) : 0;
+ SECU_Indent(out, level+1);
+ fprintf(out, "%s: %d (0x%x)\n", "Version", iv + 1, iv);
+ SECU_PrintAlgorithmID(out, &(crl->signatureAlg), "Signature Algorithm",
+ level + 1);
+ SECU_PrintName(out, &(crl->name), "Issuer", level + 1);
+ SECU_PrintTimeChoice(out, &(crl->lastUpdate), "This Update", level + 1);
+ if (crl->nextUpdate.data && crl->nextUpdate.len) /* is optional */
+ SECU_PrintTimeChoice(out, &(crl->nextUpdate), "Next Update", level + 1);
+
+ if (crl->entries != NULL) {
+ iv = 0;
+ while ((entry = crl->entries[iv++]) != NULL) {
+ sprintf(om, "Entry (%x):\n", iv);
+ SECU_Indent(out, level + 1); fprintf(out, om);
+ SECU_PrintInteger(out, &(entry->serialNumber), "Serial Number",
+ level + 2);
+ SECU_PrintTimeChoice(out, &(entry->revocationDate),
+ "Revocation Date", level + 2);
+ SECU_PrintExtensions(out, entry->extensions,
+ "Entry Extensions", level + 2);
+ }
+ }
+ SECU_PrintExtensions(out, crl->extensions, "CRL Extensions", level + 1);
+}
+
+/*
+** secu_PrintPKCS7Signed
+** Pretty print a PKCS7 signed data type (up to version 1).
+*/
+static int
+secu_PrintPKCS7Signed(FILE *out, SEC_PKCS7SignedData *src,
+ const char *m, int level)
+{
+ SECAlgorithmID *digAlg; /* digest algorithms */
+ SECItem *aCert; /* certificate */
+ CERTSignedCrl *aCrl; /* certificate revocation list */
+ SEC_PKCS7SignerInfo *sigInfo; /* signer information */
+ int rv, iv;
+ char om[100];
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(src->version), "Version", level + 1);
+
+ /* Parse and list digest algorithms (if any) */
+ if (src->digestAlgorithms != NULL) {
+ SECU_Indent(out, level + 1); fprintf(out, "Digest Algorithm List:\n");
+ iv = 0;
+ while ((digAlg = src->digestAlgorithms[iv++]) != NULL) {
+ sprintf(om, "Digest Algorithm (%x)", iv);
+ SECU_PrintAlgorithmID(out, digAlg, om, level + 2);
+ }
+ }
+
+ /* Now for the content */
+ rv = secu_PrintPKCS7ContentInfo(out, &(src->contentInfo),
+ "Content Information", level + 1);
+ if (rv != 0)
+ return rv;
+
+ /* Parse and list certificates (if any) */
+ if (src->rawCerts != NULL) {
+ SECU_Indent(out, level + 1); fprintf(out, "Certificate List:\n");
+ iv = 0;
+ while ((aCert = src->rawCerts[iv++]) != NULL) {
+ sprintf(om, "Certificate (%x)", iv);
+ rv = SECU_PrintSignedData(out, aCert, om, level + 2,
+ SECU_PrintCertificate);
+ if (rv)
+ return rv;
+ }
+ }
+
+ /* Parse and list CRL's (if any) */
+ if (src->crls != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Signed Revocation Lists:\n");
+ iv = 0;
+ while ((aCrl = src->crls[iv++]) != NULL) {
+ sprintf(om, "Signed Revocation List (%x)", iv);
+ SECU_Indent(out, level + 2); fprintf(out, "%s:\n", om);
+ SECU_PrintAlgorithmID(out, &aCrl->signatureWrap.signatureAlgorithm,
+ "Signature Algorithm", level+3);
+ DER_ConvertBitString(&aCrl->signatureWrap.signature);
+ SECU_PrintAsHex(out, &aCrl->signatureWrap.signature, "Signature",
+ level+3);
+ SECU_PrintCRLInfo(out, &aCrl->crl, "Certificate Revocation List",
+ level + 3);
+ }
+ }
+
+ /* Parse and list signatures (if any) */
+ if (src->signerInfos != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Signer Information List:\n");
+ iv = 0;
+ while ((sigInfo = src->signerInfos[iv++]) != NULL) {
+ sprintf(om, "Signer Information (%x)", iv);
+ secu_PrintSignerInfo(out, sigInfo, om, level + 2);
+ }
+ }
+
+ return 0;
+}
+
+/*
+** secu_PrintPKCS7Enveloped
+** Pretty print a PKCS7 enveloped data type (up to version 1).
+*/
+static void
+secu_PrintPKCS7Enveloped(FILE *out, SEC_PKCS7EnvelopedData *src,
+ const char *m, int level)
+{
+ SEC_PKCS7RecipientInfo *recInfo; /* pointer for signer information */
+ int iv;
+ char om[100];
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(src->version), "Version", level + 1);
+
+ /* Parse and list recipients (this is not optional) */
+ if (src->recipientInfos != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Recipient Information List:\n");
+ iv = 0;
+ while ((recInfo = src->recipientInfos[iv++]) != NULL) {
+ sprintf(om, "Recipient Information (%x)", iv);
+ secu_PrintRecipientInfo(out, recInfo, om, level + 2);
+ }
+ }
+
+ secu_PrintPKCS7EncContent(out, &src->encContentInfo,
+ "Encrypted Content Information", level + 1);
+}
+
+/*
+** secu_PrintPKCS7SignedEnveloped
+** Pretty print a PKCS7 singed and enveloped data type (up to version 1).
+*/
+static int
+secu_PrintPKCS7SignedAndEnveloped(FILE *out,
+ SEC_PKCS7SignedAndEnvelopedData *src,
+ const char *m, int level)
+{
+ SECAlgorithmID *digAlg; /* pointer for digest algorithms */
+ SECItem *aCert; /* pointer for certificate */
+ CERTSignedCrl *aCrl; /* pointer for certificate revocation list */
+ SEC_PKCS7SignerInfo *sigInfo; /* pointer for signer information */
+ SEC_PKCS7RecipientInfo *recInfo; /* pointer for recipient information */
+ int rv, iv;
+ char om[100];
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(src->version), "Version", level + 1);
+
+ /* Parse and list recipients (this is not optional) */
+ if (src->recipientInfos != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Recipient Information List:\n");
+ iv = 0;
+ while ((recInfo = src->recipientInfos[iv++]) != NULL) {
+ sprintf(om, "Recipient Information (%x)", iv);
+ secu_PrintRecipientInfo(out, recInfo, om, level + 2);
+ }
+ }
+
+ /* Parse and list digest algorithms (if any) */
+ if (src->digestAlgorithms != NULL) {
+ SECU_Indent(out, level + 1); fprintf(out, "Digest Algorithm List:\n");
+ iv = 0;
+ while ((digAlg = src->digestAlgorithms[iv++]) != NULL) {
+ sprintf(om, "Digest Algorithm (%x)", iv);
+ SECU_PrintAlgorithmID(out, digAlg, om, level + 2);
+ }
+ }
+
+ secu_PrintPKCS7EncContent(out, &src->encContentInfo,
+ "Encrypted Content Information", level + 1);
+
+ /* Parse and list certificates (if any) */
+ if (src->rawCerts != NULL) {
+ SECU_Indent(out, level + 1); fprintf(out, "Certificate List:\n");
+ iv = 0;
+ while ((aCert = src->rawCerts[iv++]) != NULL) {
+ sprintf(om, "Certificate (%x)", iv);
+ rv = SECU_PrintSignedData(out, aCert, om, level + 2,
+ SECU_PrintCertificate);
+ if (rv)
+ return rv;
+ }
+ }
+
+ /* Parse and list CRL's (if any) */
+ if (src->crls != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Signed Revocation Lists:\n");
+ iv = 0;
+ while ((aCrl = src->crls[iv++]) != NULL) {
+ sprintf(om, "Signed Revocation List (%x)", iv);
+ SECU_Indent(out, level + 2); fprintf(out, "%s:\n", om);
+ SECU_PrintAlgorithmID(out, &aCrl->signatureWrap.signatureAlgorithm,
+ "Signature Algorithm", level+3);
+ DER_ConvertBitString(&aCrl->signatureWrap.signature);
+ SECU_PrintAsHex(out, &aCrl->signatureWrap.signature, "Signature",
+ level+3);
+ SECU_PrintCRLInfo(out, &aCrl->crl, "Certificate Revocation List",
+ level + 3);
+ }
+ }
+
+ /* Parse and list signatures (if any) */
+ if (src->signerInfos != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Signer Information List:\n");
+ iv = 0;
+ while ((sigInfo = src->signerInfos[iv++]) != NULL) {
+ sprintf(om, "Signer Information (%x)", iv);
+ secu_PrintSignerInfo(out, sigInfo, om, level + 2);
+ }
+ }
+
+ return 0;
+}
+
+int
+SECU_PrintCrl (FILE *out, SECItem *der, char *m, int level)
+{
+ PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ CERTCrl *c = NULL;
+ int rv = SEC_ERROR_NO_MEMORY;
+
+ if (!arena)
+ return rv;
+ do {
+ /* Decode CRL */
+ c = PORT_ArenaZNew(arena, CERTCrl);
+ if (!c)
+ break;
+
+ rv = SEC_QuickDERDecodeItem(arena, c, SEC_ASN1_GET(CERT_CrlTemplate), der);
+ if (rv != SECSuccess)
+ break;
+ SECU_PrintCRLInfo (out, c, m, level);
+ } while (0);
+ PORT_FreeArena (arena, PR_FALSE);
+ return rv;
+}
+
+
+/*
+** secu_PrintPKCS7Encrypted
+** Pretty print a PKCS7 encrypted data type (up to version 1).
+*/
+static void
+secu_PrintPKCS7Encrypted(FILE *out, SEC_PKCS7EncryptedData *src,
+ const char *m, int level)
+{
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(src->version), "Version", level + 1);
+
+ secu_PrintPKCS7EncContent(out, &src->encContentInfo,
+ "Encrypted Content Information", level + 1);
+}
+
+/*
+** secu_PrintPKCS7Digested
+** Pretty print a PKCS7 digested data type (up to version 1).
+*/
+static void
+secu_PrintPKCS7Digested(FILE *out, SEC_PKCS7DigestedData *src,
+ const char *m, int level)
+{
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(src->version), "Version", level + 1);
+
+ SECU_PrintAlgorithmID(out, &src->digestAlg, "Digest Algorithm",
+ level + 1);
+ secu_PrintPKCS7ContentInfo(out, &src->contentInfo, "Content Information",
+ level + 1);
+ SECU_PrintAsHex(out, &src->digest, "Digest", level + 1);
+}
+
+/*
+** secu_PrintPKCS7ContentInfo
+** Takes a SEC_PKCS7ContentInfo type and sends the contents to the
+** appropriate function
+*/
+static int
+secu_PrintPKCS7ContentInfo(FILE *out, SEC_PKCS7ContentInfo *src,
+ char *m, int level)
+{
+ const char *desc;
+ SECOidTag kind;
+ int rv;
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ level++;
+
+ if (src->contentTypeTag == NULL)
+ src->contentTypeTag = SECOID_FindOID(&(src->contentType));
+
+ if (src->contentTypeTag == NULL) {
+ desc = "Unknown";
+ kind = SEC_OID_PKCS7_DATA;
+ } else {
+ desc = src->contentTypeTag->desc;
+ kind = src->contentTypeTag->offset;
+ }
+
+ if (src->content.data == NULL) {
+ SECU_Indent(out, level); fprintf(out, "%s:\n", desc);
+ level++;
+ SECU_Indent(out, level); fprintf(out, "<no content>\n");
+ return 0;
+ }
+
+ rv = 0;
+ switch (kind) {
+ case SEC_OID_PKCS7_SIGNED_DATA: /* Signed Data */
+ rv = secu_PrintPKCS7Signed(out, src->content.signedData, desc, level);
+ break;
+
+ case SEC_OID_PKCS7_ENVELOPED_DATA: /* Enveloped Data */
+ secu_PrintPKCS7Enveloped(out, src->content.envelopedData, desc, level);
+ break;
+
+ case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: /* Signed and Enveloped */
+ rv = secu_PrintPKCS7SignedAndEnveloped(out,
+ src->content.signedAndEnvelopedData,
+ desc, level);
+ break;
+
+ case SEC_OID_PKCS7_DIGESTED_DATA: /* Digested Data */
+ secu_PrintPKCS7Digested(out, src->content.digestedData, desc, level);
+ break;
+
+ case SEC_OID_PKCS7_ENCRYPTED_DATA: /* Encrypted Data */
+ secu_PrintPKCS7Encrypted(out, src->content.encryptedData, desc, level);
+ break;
+
+ default:
+ SECU_PrintAsHex(out, src->content.data, desc, level);
+ break;
+ }
+
+ return rv;
+}
+
+/*
+** SECU_PrintPKCS7ContentInfo
+** Decode and print any major PKCS7 data type (up to version 1).
+*/
+int
+SECU_PrintPKCS7ContentInfo(FILE *out, SECItem *der, char *m, int level)
+{
+ SEC_PKCS7ContentInfo *cinfo;
+ int rv;
+
+ cinfo = SEC_PKCS7DecodeItem(der, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ if (cinfo != NULL) {
+ /* Send it to recursive parsing and printing module */
+ rv = secu_PrintPKCS7ContentInfo(out, cinfo, m, level);
+ SEC_PKCS7DestroyContentInfo(cinfo);
+ } else {
+ rv = -1;
+ }
+
+ return rv;
+}
+
+/*
+** End of PKCS7 functions
+*/
+
+void
+printFlags(FILE *out, unsigned int flags, int level)
+{
+ if ( flags & CERTDB_VALID_PEER ) {
+ SECU_Indent(out, level); fprintf(out, "Valid Peer\n");
+ }
+ if ( flags & CERTDB_TRUSTED ) {
+ SECU_Indent(out, level); fprintf(out, "Trusted\n");
+ }
+ if ( flags & CERTDB_SEND_WARN ) {
+ SECU_Indent(out, level); fprintf(out, "Warn When Sending\n");
+ }
+ if ( flags & CERTDB_VALID_CA ) {
+ SECU_Indent(out, level); fprintf(out, "Valid CA\n");
+ }
+ if ( flags & CERTDB_TRUSTED_CA ) {
+ SECU_Indent(out, level); fprintf(out, "Trusted CA\n");
+ }
+ if ( flags & CERTDB_NS_TRUSTED_CA ) {
+ SECU_Indent(out, level); fprintf(out, "Netscape Trusted CA\n");
+ }
+ if ( flags & CERTDB_USER ) {
+ SECU_Indent(out, level); fprintf(out, "User\n");
+ }
+ if ( flags & CERTDB_TRUSTED_CLIENT_CA ) {
+ SECU_Indent(out, level); fprintf(out, "Trusted Client CA\n");
+ }
+ if ( flags & CERTDB_GOVT_APPROVED_CA ) {
+ SECU_Indent(out, level); fprintf(out, "Step-up\n");
+ }
+}
+
+void
+SECU_PrintTrustFlags(FILE *out, CERTCertTrust *trust, char *m, int level)
+{
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ SECU_Indent(out, level+1); fprintf(out, "SSL Flags:\n");
+ printFlags(out, trust->sslFlags, level+2);
+ SECU_Indent(out, level+1); fprintf(out, "Email Flags:\n");
+ printFlags(out, trust->emailFlags, level+2);
+ SECU_Indent(out, level+1); fprintf(out, "Object Signing Flags:\n");
+ printFlags(out, trust->objectSigningFlags, level+2);
+}
+
+int SECU_PrintSignedData(FILE *out, SECItem *der, char *m,
+ int level, SECU_PPFunc inner)
+{
+ PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ CERTSignedData *sd;
+ int rv = SEC_ERROR_NO_MEMORY;
+
+ if (!arena)
+ return rv;
+
+ /* Strip off the signature */
+ sd = PORT_ArenaZNew(arena, CERTSignedData);
+ if (!sd)
+ goto loser;
+
+ rv = SEC_ASN1DecodeItem(arena, sd, SEC_ASN1_GET(CERT_SignedDataTemplate),
+ der);
+ if (rv)
+ goto loser;
+
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ rv = (*inner)(out, &sd->data, "Data", level+1);
+
+ SECU_PrintAlgorithmID(out, &sd->signatureAlgorithm, "Signature Algorithm",
+ level+1);
+ DER_ConvertBitString(&sd->signature);
+ SECU_PrintAsHex(out, &sd->signature, "Signature", level+1);
+ SECU_PrintFingerprints(out, der, "Fingerprint", level+1);
+loser:
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+
+}
+
+SECStatus
+SECU_ParseCommandLine(int argc, char **argv, char *progName, secuCommand *cmd)
+{
+ PRBool found;
+ PLOptState *optstate;
+ PLOptStatus status;
+ char *optstring;
+ int i, j;
+
+ optstring = (char *)malloc(cmd->numCommands + 2*cmd->numOptions);
+ j = 0;
+
+ for (i=0; i<cmd->numCommands; i++) {
+ optstring[j++] = cmd->commands[i].flag;
+ }
+ for (i=0; i<cmd->numOptions; i++) {
+ optstring[j++] = cmd->options[i].flag;
+ if (cmd->options[i].needsArg)
+ optstring[j++] = ':';
+ }
+ optstring[j] = '\0';
+ optstate = PL_CreateOptState(argc, argv, optstring);
+
+ /* Parse command line arguments */
+ while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
+
+ /* Wasn't really an option, just standalone arg. */
+ if (optstate->option == '\0')
+ continue;
+
+ found = PR_FALSE;
+
+ for (i=0; i<cmd->numCommands; i++) {
+ if (cmd->commands[i].flag == optstate->option) {
+ cmd->commands[i].activated = PR_TRUE;
+ if (optstate->value) {
+ cmd->commands[i].arg = (char *)optstate->value;
+ }
+ found = PR_TRUE;
+ break;
+ }
+ }
+
+ if (found)
+ continue;
+
+ for (i=0; i<cmd->numOptions; i++) {
+ if (cmd->options[i].flag == optstate->option) {
+ cmd->options[i].activated = PR_TRUE;
+ if (optstate->value) {
+ cmd->options[i].arg = (char *)optstate->value;
+ } else if (cmd->options[i].needsArg) {
+ return SECFailure;
+ }
+ found = PR_TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ return SECFailure;
+ }
+ if (status == PL_OPT_BAD)
+ return SECFailure;
+ return SECSuccess;
+}
+
+char *
+SECU_GetOptionArg(secuCommand *cmd, int optionNum)
+{
+ if (optionNum < 0 || optionNum >= cmd->numOptions)
+ return NULL;
+ if (cmd->options[optionNum].activated)
+ return PL_strdup(cmd->options[optionNum].arg);
+ else
+ return NULL;
+}
+
+static char SECUErrorBuf[64];
+
+char *
+SECU_ErrorStringRaw(int16 err)
+{
+ if (err == 0)
+ SECUErrorBuf[0] = '\0';
+ else if (err == SEC_ERROR_BAD_DATA)
+ sprintf(SECUErrorBuf, "Bad data");
+ else if (err == SEC_ERROR_BAD_DATABASE)
+ sprintf(SECUErrorBuf, "Problem with database");
+ else if (err == SEC_ERROR_BAD_DER)
+ sprintf(SECUErrorBuf, "Problem with DER");
+ else if (err == SEC_ERROR_BAD_KEY)
+ sprintf(SECUErrorBuf, "Problem with key");
+ else if (err == SEC_ERROR_BAD_PASSWORD)
+ sprintf(SECUErrorBuf, "Incorrect password");
+ else if (err == SEC_ERROR_BAD_SIGNATURE)
+ sprintf(SECUErrorBuf, "Bad signature");
+ else if (err == SEC_ERROR_EXPIRED_CERTIFICATE)
+ sprintf(SECUErrorBuf, "Expired certificate");
+ else if (err == SEC_ERROR_EXTENSION_VALUE_INVALID)
+ sprintf(SECUErrorBuf, "Invalid extension value");
+ else if (err == SEC_ERROR_INPUT_LEN)
+ sprintf(SECUErrorBuf, "Problem with input length");
+ else if (err == SEC_ERROR_INVALID_ALGORITHM)
+ sprintf(SECUErrorBuf, "Invalid algorithm");
+ else if (err == SEC_ERROR_INVALID_ARGS)
+ sprintf(SECUErrorBuf, "Invalid arguments");
+ else if (err == SEC_ERROR_INVALID_AVA)
+ sprintf(SECUErrorBuf, "Invalid AVA");
+ else if (err == SEC_ERROR_INVALID_TIME)
+ sprintf(SECUErrorBuf, "Invalid time");
+ else if (err == SEC_ERROR_IO)
+ sprintf(SECUErrorBuf, "Security I/O error");
+ else if (err == SEC_ERROR_LIBRARY_FAILURE)
+ sprintf(SECUErrorBuf, "Library failure");
+ else if (err == SEC_ERROR_NO_MEMORY)
+ sprintf(SECUErrorBuf, "Out of memory");
+ else if (err == SEC_ERROR_OLD_CRL)
+ sprintf(SECUErrorBuf, "CRL is older than the current one");
+ else if (err == SEC_ERROR_OUTPUT_LEN)
+ sprintf(SECUErrorBuf, "Problem with output length");
+ else if (err == SEC_ERROR_UNKNOWN_ISSUER)
+ sprintf(SECUErrorBuf, "Unknown issuer");
+ else if (err == SEC_ERROR_UNTRUSTED_CERT)
+ sprintf(SECUErrorBuf, "Untrusted certificate");
+ else if (err == SEC_ERROR_UNTRUSTED_ISSUER)
+ sprintf(SECUErrorBuf, "Untrusted issuer");
+ else if (err == SSL_ERROR_BAD_CERTIFICATE)
+ sprintf(SECUErrorBuf, "Bad certificate");
+ else if (err == SSL_ERROR_BAD_CLIENT)
+ sprintf(SECUErrorBuf, "Bad client");
+ else if (err == SSL_ERROR_BAD_SERVER)
+ sprintf(SECUErrorBuf, "Bad server");
+ else if (err == SSL_ERROR_EXPORT_ONLY_SERVER)
+ sprintf(SECUErrorBuf, "Export only server");
+ else if (err == SSL_ERROR_NO_CERTIFICATE)
+ sprintf(SECUErrorBuf, "No certificate");
+ else if (err == SSL_ERROR_NO_CYPHER_OVERLAP)
+ sprintf(SECUErrorBuf, "No cypher overlap");
+ else if (err == SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE)
+ sprintf(SECUErrorBuf, "Unsupported certificate type");
+ else if (err == SSL_ERROR_UNSUPPORTED_VERSION)
+ sprintf(SECUErrorBuf, "Unsupported version");
+ else if (err == SSL_ERROR_US_ONLY_SERVER)
+ sprintf(SECUErrorBuf, "U.S. only server");
+ else if (err == PR_IO_ERROR)
+ sprintf(SECUErrorBuf, "I/O error");
+
+ else if (err == SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE)
+ sprintf (SECUErrorBuf, "Expired Issuer Certificate");
+ else if (err == SEC_ERROR_REVOKED_CERTIFICATE)
+ sprintf (SECUErrorBuf, "Revoked certificate");
+ else if (err == SEC_ERROR_NO_KEY)
+ sprintf (SECUErrorBuf, "No private key in database for this cert");
+ else if (err == SEC_ERROR_CERT_NOT_VALID)
+ sprintf (SECUErrorBuf, "Certificate is not valid");
+ else if (err == SEC_ERROR_EXTENSION_NOT_FOUND)
+ sprintf (SECUErrorBuf, "Certificate extension was not found");
+ else if (err == SEC_ERROR_CA_CERT_INVALID)
+ sprintf (SECUErrorBuf, "Issuer certificate is invalid");
+ else if (err == SEC_ERROR_CERT_USAGES_INVALID)
+ sprintf (SECUErrorBuf, "Certificate usages is invalid");
+ else if (err == SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION)
+ sprintf (SECUErrorBuf, "Certificate has unknown critical extension");
+ else if (err == SEC_ERROR_PKCS7_BAD_SIGNATURE)
+ sprintf (SECUErrorBuf, "Bad PKCS7 signature");
+ else if (err == SEC_ERROR_INADEQUATE_KEY_USAGE)
+ sprintf (SECUErrorBuf, "Certificate not approved for this operation");
+ else if (err == SEC_ERROR_INADEQUATE_CERT_TYPE)
+ sprintf (SECUErrorBuf, "Certificate not approved for this operation");
+
+ return SECUErrorBuf;
+}
+
+char *
+SECU_ErrorString(int16 err)
+{
+ char *error_string;
+
+ *SECUErrorBuf = 0;
+ SECU_ErrorStringRaw (err);
+
+ if (*SECUErrorBuf == 0) {
+ error_string = SECU_GetString(err);
+ if (error_string == NULL || *error_string == '\0')
+ sprintf(SECUErrorBuf, "No error string found for %d.", err);
+ else
+ return error_string;
+ }
+
+ return SECUErrorBuf;
+}
+
+
+void
+SECU_PrintPRandOSError(char *progName)
+{
+ char buffer[513];
+ PRInt32 errLen = PR_GetErrorTextLength();
+ if (errLen > 0 && errLen < sizeof buffer) {
+ PR_GetErrorText(buffer);
+ }
+ SECU_PrintError(progName, "function failed");
+ if (errLen > 0 && errLen < sizeof buffer) {
+ PR_fprintf(PR_STDERR, "\t%s\n", buffer);
+ }
+}
+
+
+static char *
+bestCertName(CERTCertificate *cert) {
+ if (cert->nickname) {
+ return cert->nickname;
+ }
+ if (cert->emailAddr && cert->emailAddr[0]) {
+ return cert->emailAddr;
+ }
+ return cert->subjectName;
+}
+
+void
+SECU_printCertProblems(FILE *outfile, CERTCertDBHandle *handle,
+ CERTCertificate *cert, PRBool checksig,
+ SECCertificateUsage certUsage, void *pinArg, PRBool verbose)
+{
+ CERTVerifyLog log;
+ CERTVerifyLogNode *node = NULL;
+ unsigned int depth = (unsigned int)-1;
+ unsigned int flags = 0;
+ char * errstr = NULL;
+ PRErrorCode err = PORT_GetError();
+
+ log.arena = PORT_NewArena(512);
+ log.head = log.tail = NULL;
+ log.count = 0;
+ CERT_VerifyCertificate(handle, cert, checksig, certUsage, PR_Now(), pinArg, &log, NULL);
+
+ if (log.count > 0) {
+ fprintf(outfile,"PROBLEM WITH THE CERT CHAIN:\n");
+ for (node = log.head; node; node = node->next) {
+ if (depth != node->depth) {
+ depth = node->depth;
+ fprintf(outfile,"CERT %d. %s %s:\n", depth,
+ bestCertName(node->cert),
+ depth ? "[Certificate Authority]": "");
+ if (verbose) {
+ const char * emailAddr;
+ emailAddr = CERT_GetFirstEmailAddress(node->cert);
+ if (emailAddr) {
+ fprintf(outfile,"Email Address(es): ");
+ do {
+ fprintf(outfile, "%s\n", emailAddr);
+ emailAddr = CERT_GetNextEmailAddress(node->cert,
+ emailAddr);
+ } while (emailAddr);
+ }
+ }
+ }
+ fprintf(outfile," ERROR %ld: %s\n", node->error,
+ SECU_Strerror(node->error));
+ errstr = NULL;
+ switch (node->error) {
+ case SEC_ERROR_INADEQUATE_KEY_USAGE:
+ flags = (unsigned int)node->arg;
+ switch (flags) {
+ case KU_DIGITAL_SIGNATURE:
+ errstr = "Cert cannot sign.";
+ break;
+ case KU_KEY_ENCIPHERMENT:
+ errstr = "Cert cannot encrypt.";
+ break;
+ case KU_KEY_CERT_SIGN:
+ errstr = "Cert cannot sign other certs.";
+ break;
+ default:
+ errstr = "[unknown usage].";
+ break;
+ }
+ case SEC_ERROR_INADEQUATE_CERT_TYPE:
+ flags = (unsigned int)node->arg;
+ switch (flags) {
+ case NS_CERT_TYPE_SSL_CLIENT:
+ case NS_CERT_TYPE_SSL_SERVER:
+ errstr = "Cert cannot be used for SSL.";
+ break;
+ case NS_CERT_TYPE_SSL_CA:
+ errstr = "Cert cannot be used as an SSL CA.";
+ break;
+ case NS_CERT_TYPE_EMAIL:
+ errstr = "Cert cannot be used for SMIME.";
+ break;
+ case NS_CERT_TYPE_EMAIL_CA:
+ errstr = "Cert cannot be used as an SMIME CA.";
+ break;
+ case NS_CERT_TYPE_OBJECT_SIGNING:
+ errstr = "Cert cannot be used for object signing.";
+ break;
+ case NS_CERT_TYPE_OBJECT_SIGNING_CA:
+ errstr = "Cert cannot be used as an object signing CA.";
+ break;
+ default:
+ errstr = "[unknown usage].";
+ break;
+ }
+ case SEC_ERROR_UNKNOWN_ISSUER:
+ case SEC_ERROR_UNTRUSTED_ISSUER:
+ case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
+ errstr = node->cert->issuerName;
+ break;
+ default:
+ break;
+ }
+ if (errstr) {
+ fprintf(stderr," %s\n",errstr);
+ }
+ CERT_DestroyCertificate(node->cert);
+ }
+ }
+ PORT_SetError(err); /* restore original error code */
+}
+
+SECOidTag
+SECU_StringToSignatureAlgTag(const char *alg)
+{
+ SECOidTag hashAlgTag = SEC_OID_UNKNOWN;
+
+ if (alg) {
+ if (!PL_strcmp(alg, "MD2")) {
+ hashAlgTag = SEC_OID_MD2;
+ } else if (!PL_strcmp(alg, "MD4")) {
+ hashAlgTag = SEC_OID_MD4;
+ } else if (!PL_strcmp(alg, "MD5")) {
+ hashAlgTag = SEC_OID_MD5;
+ } else if (!PL_strcmp(alg, "SHA1")) {
+ hashAlgTag = SEC_OID_SHA1;
+ } else if (!PL_strcmp(alg, "SHA256")) {
+ hashAlgTag = SEC_OID_SHA256;
+ } else if (!PL_strcmp(alg, "SHA384")) {
+ hashAlgTag = SEC_OID_SHA384;
+ } else if (!PL_strcmp(alg, "SHA512")) {
+ hashAlgTag = SEC_OID_SHA512;
+ }
+ }
+ return hashAlgTag;
+}
+
+
+SECStatus
+SECU_StoreCRL(PK11SlotInfo *slot, SECItem *derCrl, PRFileDesc *outFile,
+ const PRBool ascii, char *url)
+{
+ PORT_Assert(derCrl != NULL);
+ if (!derCrl) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ if (outFile != NULL) {
+ if (ascii) {
+ PR_fprintf(outFile, "%s\n%s\n%s\n", NS_CRL_HEADER,
+ BTOA_DataToAscii(derCrl->data, derCrl->len),
+ NS_CRL_TRAILER);
+ } else {
+ if (PR_Write(outFile, derCrl->data, derCrl->len) != derCrl->len) {
+ return SECFailure;
+ }
+ }
+ }
+ if (slot) {
+ CERTSignedCrl *newCrl = PK11_ImportCRL(slot, derCrl, url,
+ SEC_CRL_TYPE, NULL, 0, NULL, 0);
+ if (newCrl != NULL) {
+ SEC_DestroyCrl(newCrl);
+ return SECSuccess;
+ }
+ return SECFailure;
+ }
+ if (!outFile && !slot) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+SECStatus
+SECU_SignAndEncodeCRL(CERTCertificate *issuer, CERTSignedCrl *signCrl,
+ SECOidTag hashAlgTag, SignAndEncodeFuncExitStat *resCode)
+{
+ SECItem der;
+ SECKEYPrivateKey *caPrivateKey = NULL;
+ SECStatus rv;
+ PRArenaPool *arena;
+ SECOidTag algID;
+ void *dummy;
+
+ PORT_Assert(issuer != NULL && signCrl != NULL);
+ if (!issuer || !signCrl) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ arena = signCrl->arena;
+
+ caPrivateKey = PK11_FindKeyByAnyCert(issuer, NULL);
+ if (caPrivateKey == NULL) {
+ *resCode = noKeyFound;
+ return SECFailure;
+ }
+
+ algID = SEC_GetSignatureAlgorithmOidTag(caPrivateKey->keyType, hashAlgTag);
+ if (algID == SEC_OID_UNKNOWN) {
+ *resCode = noSignatureMatch;
+ rv = SECFailure;
+ goto done;
+ }
+
+ if (!signCrl->crl.signatureAlg.parameters.data) {
+ rv = SECOID_SetAlgorithmID(arena, &signCrl->crl.signatureAlg, algID, 0);
+ if (rv != SECSuccess) {
+ *resCode = failToEncode;
+ goto done;
+ }
+ }
+
+ der.len = 0;
+ der.data = NULL;
+ dummy = SEC_ASN1EncodeItem(arena, &der, &signCrl->crl,
+ SEC_ASN1_GET(CERT_CrlTemplate));
+ if (!dummy) {
+ *resCode = failToEncode;
+ rv = SECFailure;
+ goto done;
+ }
+
+ rv = SECU_DerSignDataCRL(arena, &signCrl->signatureWrap,
+ der.data, der.len, caPrivateKey, algID);
+ if (rv != SECSuccess) {
+ *resCode = failToSign;
+ goto done;
+ }
+
+ signCrl->derCrl = PORT_ArenaZNew(arena, SECItem);
+ if (signCrl->derCrl == NULL) {
+ *resCode = noMem;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ rv = SECFailure;
+ goto done;
+ }
+
+ signCrl->derCrl->len = 0;
+ signCrl->derCrl->data = NULL;
+ dummy = SEC_ASN1EncodeItem (arena, signCrl->derCrl, signCrl,
+ SEC_ASN1_GET(CERT_SignedCrlTemplate));
+ if (!dummy) {
+ *resCode = failToEncode;
+ rv = SECFailure;
+ goto done;
+ }
+
+done:
+ if (caPrivateKey) {
+ SECKEY_DestroyPrivateKey(caPrivateKey);
+ }
+ return rv;
+}
+
+
+
+SECStatus
+SECU_CopyCRL(PRArenaPool *destArena, CERTCrl *destCrl, CERTCrl *srcCrl)
+{
+ void *dummy;
+ SECStatus rv = SECSuccess;
+ SECItem der;
+
+ PORT_Assert(destArena && srcCrl && destCrl);
+ if (!destArena || !srcCrl || !destCrl) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ der.len = 0;
+ der.data = NULL;
+ dummy = SEC_ASN1EncodeItem (destArena, &der, srcCrl,
+ SEC_ASN1_GET(CERT_CrlTemplate));
+ if (!dummy) {
+ return SECFailure;
+ }
+
+ rv = SEC_QuickDERDecodeItem(destArena, destCrl,
+ SEC_ASN1_GET(CERT_CrlTemplate), &der);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ destCrl->arena = destArena;
+
+ return rv;
+}
+
+SECStatus
+SECU_DerSignDataCRL(PRArenaPool *arena, CERTSignedData *sd,
+ unsigned char *buf, int len, SECKEYPrivateKey *pk,
+ SECOidTag algID)
+{
+ SECItem it;
+ SECStatus rv;
+
+ it.data = 0;
+
+ /* XXX We should probably have some asserts here to make sure the key type
+ * and algID match
+ */
+
+ /* Sign input buffer */
+ rv = SEC_SignData(&it, buf, len, pk, algID);
+ if (rv) goto loser;
+
+ /* Fill out SignedData object */
+ PORT_Memset(sd, 0, sizeof(*sd));
+ sd->data.data = buf;
+ sd->data.len = len;
+ sd->signature.data = it.data;
+ sd->signature.len = it.len << 3; /* convert to bit string */
+ rv = SECOID_SetAlgorithmID(arena, &sd->signatureAlgorithm, algID, 0);
+ if (rv) goto loser;
+
+ return rv;
+
+ loser:
+ PORT_Free(it.data);
+ return rv;
+}
+
+#if 0
+
+/* we need access to the private function cert_FindExtension for this code to work */
+
+CERTAuthKeyID *
+SECU_FindCRLAuthKeyIDExten (PRArenaPool *arena, CERTSignedCrl *scrl)
+{
+ SECItem encodedExtenValue;
+ SECStatus rv;
+ CERTAuthKeyID *ret;
+ CERTCrl* crl;
+
+ if (!scrl) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
+ }
+
+ crl = &scrl->crl;
+
+ encodedExtenValue.data = NULL;
+ encodedExtenValue.len = 0;
+
+ rv = cert_FindExtension(crl->extensions, SEC_OID_X509_AUTH_KEY_ID,
+ &encodedExtenValue);
+ if ( rv != SECSuccess ) {
+ return (NULL);
+ }
+
+ ret = CERT_DecodeAuthKeyID (arena, &encodedExtenValue);
+
+ PORT_Free(encodedExtenValue.data);
+ encodedExtenValue.data = NULL;
+
+ return(ret);
+}
+
+#endif
+
+/*
+ * Find the issuer of a Crl. Use the authorityKeyID if it exists.
+ */
+CERTCertificate *
+SECU_FindCrlIssuer(CERTCertDBHandle *dbhandle, SECItem* subject,
+ CERTAuthKeyID* authorityKeyID, PRTime validTime)
+{
+ CERTCertificate *issuerCert = NULL;
+ CERTCertList *certList = NULL;
+
+ if (!subject) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
+ }
+
+ certList =
+ CERT_CreateSubjectCertList(NULL, dbhandle, subject,
+ validTime, PR_TRUE);
+ if (certList) {
+ CERTCertListNode *node = CERT_LIST_HEAD(certList);
+
+ /* XXX and authoritykeyid in the future */
+ while ( ! CERT_LIST_END(node, certList) ) {
+ CERTCertificate *cert = node->cert;
+ /* check cert CERTCertTrust data is allocated, check cert
+ usage extension, check that cert has pkey in db. Select
+ the first (newest) user cert */
+ if (cert->trust &&
+ CERT_CheckCertUsage(cert, KU_CRL_SIGN) == SECSuccess &&
+ CERT_IsUserCert(cert)) {
+
+ issuerCert = CERT_DupCertificate(cert);
+ break;
+ }
+ node = CERT_LIST_NEXT(node);
+ }
+ CERT_DestroyCertList(certList);
+ }
+ return(issuerCert);
+}
+
+
+/* Encodes and adds extensions to the CRL or CRL entries. */
+SECStatus
+SECU_EncodeAndAddExtensionValue(PRArenaPool *arena, void *extHandle,
+ void *value, PRBool criticality, int extenType,
+ EXTEN_EXT_VALUE_ENCODER EncodeValueFn)
+{
+ SECItem encodedValue;
+ SECStatus rv;
+
+ encodedValue.data = NULL;
+ encodedValue.len = 0;
+ do {
+ rv = (*EncodeValueFn)(arena, value, &encodedValue);
+ if (rv != SECSuccess)
+ break;
+
+ rv = CERT_AddExtension(extHandle, extenType, &encodedValue,
+ criticality, PR_TRUE);
+ if (rv != SECSuccess)
+ break;
+ } while (0);
+
+ return (rv);
+}
diff --git a/base/native-tools/src/tkstool/secutil.h b/base/native-tools/src/tkstool/secutil.h
new file mode 100644
index 000000000..a2f065067
--- /dev/null
+++ b/base/native-tools/src/tkstool/secutil.h
@@ -0,0 +1,430 @@
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/secutil.h
+ */
+
+#ifndef _SEC_UTIL_H_
+#define _SEC_UTIL_H_
+
+#include "seccomon.h"
+#include "secitem.h"
+#include "prerror.h"
+#include "base64.h"
+#include "key.h"
+#include "secpkcs7.h"
+#include "secasn1.h"
+#include "secder.h"
+#include <stdio.h>
+
+#define SEC_CT_PRIVATE_KEY "private-key"
+#define SEC_CT_PUBLIC_KEY "public-key"
+#define SEC_CT_CERTIFICATE "certificate"
+#define SEC_CT_CERTIFICATE_REQUEST "certificate-request"
+#define SEC_CT_PKCS7 "pkcs7"
+#define SEC_CT_CRL "crl"
+
+#define NS_CERTREQ_HEADER "-----BEGIN NEW CERTIFICATE REQUEST-----"
+#define NS_CERTREQ_TRAILER "-----END NEW CERTIFICATE REQUEST-----"
+
+#define NS_CERT_HEADER "-----BEGIN CERTIFICATE-----"
+#define NS_CERT_TRAILER "-----END CERTIFICATE-----"
+
+#define NS_CRL_HEADER "-----BEGIN CRL-----"
+#define NS_CRL_TRAILER "-----END CRL-----"
+
+/* From libsec/pcertdb.c --- it's not declared in sec.h */
+extern SECStatus SEC_AddPermCertificate(CERTCertDBHandle *handle,
+ SECItem *derCert, char *nickname, CERTCertTrust *trust);
+
+
+#ifdef SECUTIL_NEW
+typedef int (*SECU_PPFunc)(PRFileDesc *out, SECItem *item,
+ char *msg, int level);
+#else
+typedef int (*SECU_PPFunc)(FILE *out, SECItem *item, char *msg, int level);
+#endif
+
+typedef struct {
+ enum {
+ PW_NONE = 0,
+ PW_FROMFILE = 1,
+ PW_PLAINTEXT = 2,
+ PW_EXTERNAL = 3
+ } source;
+ char *data;
+} secuPWData;
+
+/*
+** Change a password on a token, or initialize a token with a password
+** if it does not already have one.
+** Use passwd to send the password in plaintext, pwFile to specify a
+** file containing the password, or NULL for both to prompt the user.
+*/
+SECStatus SECU_ChangePW(PK11SlotInfo *slot, char *passwd, char *pwFile);
+
+/* These were stolen from the old sec.h... */
+/*
+** Check a password for legitimacy. Passwords must be at least 8
+** characters long and contain one non-alphabetic. Return DSTrue if the
+** password is ok, DSFalse otherwise.
+*/
+extern PRBool SEC_CheckPassword(char *password);
+
+/*
+** Blind check of a password. Complement to SEC_CheckPassword which
+** ignores length and content type, just retuning DSTrue is the password
+** exists, DSFalse if NULL
+*/
+extern PRBool SEC_BlindCheckPassword(char *password);
+
+/*
+** Get a password.
+** First prompt with "msg" on "out", then read the password from "in".
+** The password is then checked using "chkpw".
+*/
+extern char *SEC_GetPassword(FILE *in, FILE *out, char *msg,
+ PRBool (*chkpw)(char *));
+
+char *SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg);
+
+char *SECU_GetPasswordString(void *arg, char *prompt);
+
+/*
+** Write a dongle password.
+** Uses MD5 to hash constant system data (hostname, etc.), and then
+** creates RC4 key to encrypt a password "pw" into a file "fd".
+*/
+extern SECStatus SEC_WriteDongleFile(int fd, char *pw);
+
+/*
+** Get a dongle password.
+** Uses MD5 to hash constant system data (hostname, etc.), and then
+** creates RC4 key to decrypt and return a password from file "fd".
+*/
+extern char *SEC_ReadDongleFile(int fd);
+
+
+/* End stolen headers */
+
+/* Just sticks the two strings together with a / if needed */
+char *SECU_AppendFilenameToDir(char *dir, char *filename);
+
+/* Returns result of getenv("SSL_DIR") or NULL */
+extern char *SECU_DefaultSSLDir(void);
+
+/*
+** Should be called once during initialization to set the default
+** directory for looking for cert.db, key.db, and cert-nameidx.db files
+** Removes trailing '/' in 'base'
+** If 'base' is NULL, defaults to set to .netscape in home directory.
+*/
+extern char *SECU_ConfigDirectory(const char* base);
+
+/*
+** Basic callback function for SSL_GetClientAuthDataHook
+*/
+extern int
+SECU_GetClientAuthData(void *arg, PRFileDesc *fd,
+ struct CERTDistNamesStr *caNames,
+ struct CERTCertificateStr **pRetCert,
+ struct SECKEYPrivateKeyStr **pRetKey);
+
+/* print out an error message */
+extern void SECU_PrintError(char *progName, char *msg, ...);
+
+/* print out a system error message */
+extern void SECU_PrintSystemError(char *progName, char *msg, ...);
+
+/* Return informative error string */
+extern const char * SECU_Strerror(PRErrorCode errNum);
+
+/* print information about cert verification failure */
+extern void
+SECU_printCertProblems(FILE *outfile, CERTCertDBHandle *handle,
+ CERTCertificate *cert, PRBool checksig,
+ SECCertificateUsage certUsage, void *pinArg, PRBool verbose);
+
+/* Read the contents of a file into a SECItem */
+extern SECStatus SECU_FileToItem(SECItem *dst, PRFileDesc *src);
+extern SECStatus SECU_TextFileToItem(SECItem *dst, PRFileDesc *src);
+
+/* Read in a DER from a file, may be ascii */
+extern SECStatus
+SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii);
+
+/* Indent based on "level" */
+extern void SECU_Indent(FILE *out, int level);
+
+/* Print integer value and hex */
+extern void SECU_PrintInteger(FILE *out, SECItem *i, char *m, int level);
+
+/* Print ObjectIdentifier symbolically */
+extern SECOidTag SECU_PrintObjectID(FILE *out, SECItem *oid, char *m, int level);
+
+/* Print AlgorithmIdentifier symbolically */
+extern void SECU_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, char *m,
+ int level);
+
+/* Print SECItem as hex */
+extern void SECU_PrintAsHex(FILE *out, SECItem *i, const char *m, int level);
+
+/* dump a buffer in hex and ASCII */
+extern void SECU_PrintBuf(FILE *out, const char *msg, const void *vp, int len);
+
+/*
+ * Format and print the UTC Time "t". If the tag message "m" is not NULL,
+ * do indent formatting based on "level" and add a newline afterward;
+ * otherwise just print the formatted time string only.
+ */
+extern void SECU_PrintUTCTime(FILE *out, SECItem *t, char *m, int level);
+
+/*
+ * Format and print the Generalized Time "t". If the tag message "m"
+ * is not NULL, * do indent formatting based on "level" and add a newline
+ * afterward; otherwise just print the formatted time string only.
+ */
+extern void SECU_PrintGeneralizedTime(FILE *out, SECItem *t, char *m,
+ int level);
+
+/*
+ * Format and print the UTC or Generalized Time "t". If the tag message
+ * "m" is not NULL, do indent formatting based on "level" and add a newline
+ * afterward; otherwise just print the formatted time string only.
+ */
+extern void SECU_PrintTimeChoice(FILE *out, SECItem *t, char *m, int level);
+
+/* callback for listing certs through pkcs11 */
+extern SECStatus SECU_PrintCertNickname(CERTCertListNode* cert, void *data);
+
+/* Dump all certificate nicknames in a database */
+extern SECStatus
+SECU_PrintCertificateNames(CERTCertDBHandle *handle, PRFileDesc* out,
+ PRBool sortByName, PRBool sortByTrust);
+
+/* See if nickname already in database. Return 1 true, 0 false, -1 error */
+int SECU_CheckCertNameExists(CERTCertDBHandle *handle, char *nickname);
+
+/* Dump contents of cert req */
+extern int SECU_PrintCertificateRequest(FILE *out, SECItem *der, char *m,
+ int level);
+
+/* Dump contents of certificate */
+extern int SECU_PrintCertificate(FILE *out, SECItem *der, char *m, int level);
+
+/* print trust flags on a cert */
+extern void SECU_PrintTrustFlags(FILE *out, CERTCertTrust *trust, char *m, int level);
+
+/* Dump contents of public key */
+extern int SECU_PrintPublicKey(FILE *out, SECItem *der, char *m, int level);
+
+#ifdef HAVE_EPV_TEMPLATE
+/* Dump contents of private key */
+extern int SECU_PrintPrivateKey(FILE *out, SECItem *der, char *m, int level);
+#endif
+
+/* Print the MD5 and SHA1 fingerprints of a cert */
+extern int SECU_PrintFingerprints(FILE *out, SECItem *derCert, char *m,
+ int level);
+
+/* Pretty-print any PKCS7 thing */
+extern int SECU_PrintPKCS7ContentInfo(FILE *out, SECItem *der, char *m,
+ int level);
+
+/* Init PKCS11 stuff */
+extern SECStatus SECU_PKCS11Init(PRBool readOnly);
+
+/* Dump contents of signed data */
+extern int SECU_PrintSignedData(FILE *out, SECItem *der, char *m, int level,
+ SECU_PPFunc inner);
+
+extern int SECU_PrintCrl(FILE *out, SECItem *der, char *m, int level);
+
+extern void
+SECU_PrintCRLInfo(FILE *out, CERTCrl *crl, char *m, int level);
+
+extern void SECU_PrintString(FILE *out, SECItem *si, char *m, int level);
+extern void SECU_PrintAny(FILE *out, SECItem *i, char *m, int level);
+
+extern void SECU_PrintPolicy(FILE *out, SECItem *value, char *msg, int level);
+extern void SECU_PrintPrivKeyUsagePeriodExtension(FILE *out, SECItem *value,
+ char *msg, int level);
+
+extern void SECU_PrintExtensions(FILE *out, CERTCertExtension **extensions,
+ char *msg, int level);
+
+extern void SECU_PrintName(FILE *out, CERTName *name, char *msg, int level);
+
+#ifdef SECU_GetPassword
+/* Convert a High public Key to a Low public Key */
+extern SECKEYLowPublicKey *SECU_ConvHighToLow(SECKEYPublicKey *pubHighKey);
+#endif
+
+extern char *SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg);
+
+extern SECStatus DER_PrettyPrint(FILE *out, SECItem *it, PRBool raw);
+extern void SEC_Init(void);
+
+extern char *SECU_SECModDBName(void);
+
+extern void SECU_PrintPRandOSError(char *progName);
+
+extern SECStatus SECU_RegisterDynamicOids(void);
+
+/* Identifies hash algorithm tag by its string representation. */
+extern SECOidTag SECU_StringToSignatureAlgTag(const char *alg);
+
+/* Store CRL in output file or pk11 db. Also
+ * encodes with base64 and exports to file if ascii flag is set
+ * and file is not NULL. */
+extern SECStatus SECU_StoreCRL(PK11SlotInfo *slot, SECItem *derCrl,
+ PRFileDesc *outFile, int ascii, char *url);
+
+
+/*
+** DER sign a single block of data using private key encryption and the
+** MD5 hashing algorithm. This routine first computes a digital signature
+** using SEC_SignData, then wraps it with an CERTSignedData and then der
+** encodes the result.
+** "arena" is the memory arena to use to allocate data from
+** "sd" returned CERTSignedData
+** "result" the final der encoded data (memory is allocated)
+** "buf" the input data to sign
+** "len" the amount of data to sign
+** "pk" the private key to encrypt with
+*/
+extern SECStatus SECU_DerSignDataCRL(PRArenaPool *arena, CERTSignedData *sd,
+ unsigned char *buf, int len,
+ SECKEYPrivateKey *pk, SECOidTag algID);
+
+typedef enum {
+ noKeyFound = 1,
+ noSignatureMatch = 2,
+ failToEncode = 3,
+ failToSign = 4,
+ noMem = 5
+} SignAndEncodeFuncExitStat;
+
+extern SECStatus
+SECU_SignAndEncodeCRL(CERTCertificate *issuer, CERTSignedCrl *signCrl,
+ SECOidTag hashAlgTag, SignAndEncodeFuncExitStat *resCode);
+
+extern SECStatus
+SECU_CopyCRL(PRArenaPool *destArena, CERTCrl *destCrl, CERTCrl *srcCrl);
+
+/*
+** Finds the crl Authority Key Id extension. Returns NULL if no such extension
+** was found.
+*/
+CERTAuthKeyID *
+SECU_FindCRLAuthKeyIDExten (PRArenaPool *arena, CERTSignedCrl *crl);
+
+/*
+ * Find the issuer of a crl. Cert usage should be checked before signing a crl.
+ */
+CERTCertificate *
+SECU_FindCrlIssuer(CERTCertDBHandle *dbHandle, SECItem* subject,
+ CERTAuthKeyID* id, PRTime validTime);
+
+
+/* call back function used in encoding of an extension. Called from
+ * SECU_EncodeAndAddExtensionValue */
+typedef SECStatus (* EXTEN_EXT_VALUE_ENCODER) (PRArenaPool *extHandleArena,
+ void *value, SECItem *encodedValue);
+
+/* Encodes and adds extensions to the CRL or CRL entries. */
+SECStatus
+SECU_EncodeAndAddExtensionValue(PRArenaPool *arena, void *extHandle,
+ void *value, PRBool criticality, int extenType,
+ EXTEN_EXT_VALUE_ENCODER EncodeValueFn);
+
+
+/*
+ *
+ * Utilities for parsing security tools command lines
+ *
+ */
+
+/* A single command flag */
+typedef struct {
+ char flag;
+ PRBool needsArg;
+ char *arg;
+ PRBool activated;
+} secuCommandFlag;
+
+/* A full array of command/option flags */
+typedef struct
+{
+ int numCommands;
+ int numOptions;
+
+ secuCommandFlag *commands;
+ secuCommandFlag *options;
+} secuCommand;
+
+/* fill the "arg" and "activated" fields for each flag */
+SECStatus
+SECU_ParseCommandLine(int argc, char **argv, char *progName, secuCommand *cmd);
+char *
+SECU_GetOptionArg(secuCommand *cmd, int optionNum);
+
+/*
+ *
+ * Error messaging
+ *
+ */
+
+/* Return informative error string */
+char *SECU_ErrorString(int16 err);
+
+/* Return informative error string. Does not call XP_GetString */
+char *SECU_ErrorStringRaw(int16 err);
+
+void printflags(char *trusts, unsigned int flags);
+
+#ifndef XP_UNIX
+extern int ffs(unsigned int i);
+#endif
+
+#include "secerr.h"
+#include "sslerr.h"
+
+#endif /* _SEC_UTIL_H_ */
diff --git a/base/native-tools/src/tkstool/tkstool.c b/base/native-tools/src/tkstool/tkstool.c
new file mode 100644
index 000000000..5368b2e7b
--- /dev/null
+++ b/base/native-tools/src/tkstool/tkstool.c
@@ -0,0 +1,2660 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 ---
+ */
+
+#include "tkstool.h"
+
+
+static char *progName;
+
+
+/* tkstool commands */
+enum {
+ cmd_DeleteKey = 0,
+ cmd_PrintHelp,
+ cmd_InputGenTransportKey,
+ cmd_DisplayKCV,
+ cmd_ListKeys,
+ cmd_GenMasterKey,
+ cmd_NewDBs,
+ cmd_ChangePassword,
+ cmd_RenameKey,
+ cmd_ListSecModules,
+ cmd_GenTransportKey,
+ cmd_UnWrapMasterKey,
+ cmd_Version,
+ cmd_WrapMasterKey
+};
+
+
+/* tkstool options */
+enum {
+ opt_DBDir = 0,
+ opt_PasswordFile,
+ opt_TokenName,
+ opt_InFile,
+ opt_Keyname,
+ opt_OutFile,
+ opt_DBPrefix,
+ opt_NewKeyname,
+ opt_TransportKeyname,
+ opt_RW,
+ opt_NoiseFile
+};
+
+
+static secuCommandFlag tkstool_commands[] = {
+ { /* cmd_DeleteKey */ 'D', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_PrintHelp */ 'H', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_InputGenTransportKey */ 'I', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_DisplayKCV */ 'K', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_ListKeys */ 'L', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_GenMasterKey */ 'M', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_NewDBs */ 'N', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_ChangePassword */ 'P', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_RenameKey */ 'R', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_ListSecModules */ 'S', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_GenTransportKey */ 'T', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_UnWrapMasterKey */ 'U', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_Version */ 'V', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_WrapMasterKey */ 'W', PR_FALSE, 0, PR_FALSE }
+};
+
+
+static secuCommandFlag tkstool_options[] = {
+ { /* opt_DBDir */ 'd', PR_TRUE, 0, PR_FALSE },
+ { /* opt_PasswordFile */ 'f', PR_TRUE, 0, PR_FALSE },
+ { /* opt_TokenName */ 'h', PR_TRUE, 0, PR_FALSE },
+ { /* opt_InFile */ 'i', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Keyname */ 'n', PR_TRUE, 0, PR_FALSE },
+ { /* opt_OutFile */ 'o', PR_TRUE, 0, PR_FALSE },
+ { /* opt_DBPrefix */ 'p', PR_TRUE, 0, PR_FALSE },
+ { /* opt_NewKeyname */ 'r', PR_TRUE, 0, PR_FALSE },
+ { /* opt_TransportKeyname */ 't', PR_TRUE, 0, PR_FALSE },
+ { /* opt_RW */ 'x', PR_FALSE, 0, PR_FALSE },
+ { /* opt_NoiseFile */ 'z', PR_TRUE, 0, PR_FALSE },
+};
+
+
+int
+main( int argc, char **argv )
+{
+ CK_KEY_DERIVATION_STRING_DATA secondDerivationData = { NULL,
+ 0 };
+ CK_KEY_DERIVATION_STRING_DATA thirdDerivationData = { NULL,
+ 0 };
+ PK11SlotInfo *internalSlot = NULL;
+ PK11SlotInfo *slot = NULL;
+ PK11SymKey *symmetricKey = NULL;
+ PK11SymKey *masterKey = NULL;
+ PK11SymKey *temporaryMasterKey = NULL;
+ PK11SymKey *firstSymmetricKey = NULL;
+ PK11SymKey *secondSymmetricKey = NULL;
+ PK11SymKey *thirdSymmetricKey = NULL;
+ PK11SymKey *transportKey = NULL;
+ PRBool readOnly = PR_FALSE;
+ PRIntn KCVLen = KCV_LENGTH;
+ PRUint8 *KCV = NULL;
+ SECItem firstSessionKeyShare = { siBuffer,
+ NULL,
+ 0 };
+ SECItem secondSessionKeyShare = { siBuffer,
+ NULL,
+ 0 };
+ SECItem thirdSessionKeyShare = { siBuffer,
+ NULL,
+ 0 };
+#if defined(PAD_DES2_KEY_LENGTH)
+ SECItem paddedFirstSessionKeyShare = { siBuffer,
+ NULL,
+ 0 };
+ SECItem paddedSecondSessionKeyShare = { siBuffer,
+ NULL,
+ 0 };
+ SECItem paddedThirdSessionKeyShare = { siBuffer,
+ NULL,
+ 0 };
+#endif
+ SECItem hexInternalKeyKCV = { siBuffer,
+ NULL,
+ 0 };
+ SECItem wrappedMasterKey = { siBuffer,
+ NULL,
+ 0 };
+ SECStatus rvKCV = SECFailure;
+ SECStatus rvParse = SECSuccess;
+ SECStatus rvNSSinit = SECSuccess;
+ SECStatus rvFindSymKey = SECSuccess;
+ SECStatus rvSeedRNG = SECSuccess;
+ SECStatus rvFirstSessionKeyShare = SECFailure;
+ SECStatus rvSecondSessionKeyShare = SECFailure;
+ SECStatus rvThirdSessionKeyShare = SECFailure;
+ SECStatus rvSaveWrappedMasterKey = SECSuccess;
+ SECStatus rvSymmetricKeyname = SECSuccess;
+ SECStatus rvWrappedMasterKey = SECSuccess;
+ SECStatus rvMasterKeyname = SECSuccess;
+ SECStatus rv = SECSuccess;
+ SECStatus status = PR_FALSE;
+ char commandToRun = '\0';
+ char *DBDir = NULL;
+ char *DBPrefix = "";
+ char *input = NULL;
+ char *keyname = NULL;
+ char *new_keyname = NULL;
+ char *output = NULL;
+ char *SeedNoise = NULL;
+ char *slotname = "internal";
+ char *transport_keyname = NULL;
+ int commandsEntered = 0;
+ int i = 0;
+ int optionsEntered = 0;
+ secuPWData pwdata = { PW_NONE,
+ 0 };
+
+
+ /**************************/
+ /* Parse the command line */
+ /**************************/
+
+ secuCommand tkstool;
+ tkstool.numCommands = sizeof( tkstool_commands ) /
+ sizeof( secuCommandFlag );
+ tkstool.numOptions = sizeof( tkstool_options ) /
+ sizeof( secuCommandFlag );
+ tkstool.commands = tkstool_commands;
+ tkstool.options = tkstool_options;
+
+ /* retrieve name of command */
+ progName = strrchr( argv[0], '/' );
+ progName = progName ? ( progName + 1 ) : argv[0];
+
+ /* parse command line (command(s) and options) from command line */
+ rvParse = SECU_ParseCommandLine( argc, argv, progName, &tkstool );
+ if( rvParse != SECSuccess ) {
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+
+ /*********************************************************/
+ /* Check the number of command line "command(s)" entered */
+ /*********************************************************/
+
+ commandsEntered = 0;
+ for( i = 0 ; i < tkstool.numCommands ; i++ ) {
+ if( tkstool.commands[i].activated ) {
+ commandToRun = tkstool.commands[i].flag;
+ commandsEntered++;
+ }
+
+ if( commandsEntered > 1 ) {
+ break;
+ }
+ }
+
+ if( commandsEntered > 1 ) {
+ PR_fprintf( PR_STDERR,
+ "%s: only one command at a time!\n",
+ progName );
+
+ PR_fprintf( PR_STDERR,
+ "You entered: " );
+
+ for( i = 0 ; i < tkstool.numCommands ; i++ ) {
+ if( tkstool.commands[i].activated ) {
+ PR_fprintf( PR_STDERR,
+ " -%c",
+ tkstool.commands[i].flag );
+ }
+ }
+
+ PR_fprintf( PR_STDERR,
+ "\n" );
+ return 255;
+ }
+
+ if( commandsEntered == 0 ) {
+ PR_fprintf( PR_STDERR,
+ "%s: you must enter one of the following commands:\n\n",
+ progName );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+
+ /********************************************************/
+ /* Check the number of command line "option(s)" entered */
+ /********************************************************/
+
+ optionsEntered = 0;
+ for( i = 0 ; i < tkstool.numOptions ; i++ ) {
+ if( tkstool.options[i].activated ) {
+ optionsEntered++;
+ }
+
+ if( optionsEntered > 1 ) {
+ break;
+ }
+ }
+
+ if( optionsEntered == 0 &&
+ ! ( tkstool.commands[cmd_PrintHelp].activated ||
+ tkstool.commands[cmd_Version].activated ) ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: you must enter the following options "
+ "for this command:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+
+ /***************************************************/
+ /* Check that command line "options" correspond to */
+ /* one of their specified command line "commands" */
+ /***************************************************/
+
+ /* the "-d DBDir" command option may ONLY be used with */
+ /* the "-D", "-I", "-K", "-L", "-M", "-N", "-P", "-R", */
+ /* "-S", "-T", "-U", and "-W" commands */
+ if( tkstool.options[opt_DBDir].activated &&
+ ! ( tkstool.commands[cmd_DeleteKey].activated ||
+ tkstool.commands[cmd_InputGenTransportKey].activated ||
+ tkstool.commands[cmd_DisplayKCV].activated ||
+ tkstool.commands[cmd_ListKeys].activated ||
+ tkstool.commands[cmd_GenMasterKey].activated ||
+ tkstool.commands[cmd_NewDBs].activated ||
+ tkstool.commands[cmd_ChangePassword].activated ||
+ tkstool.commands[cmd_RenameKey].activated ||
+ tkstool.commands[cmd_ListSecModules].activated ||
+ tkstool.commands[cmd_GenTransportKey].activated ||
+ tkstool.commands[cmd_UnWrapMasterKey].activated ||
+ tkstool.commands[cmd_WrapMasterKey].activated ) ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-d DBDir\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* the "-f pwfile" command option may ONLY be used with */
+ /* the "-D", "-I", "-K", "-L", "-M", "-N", "-P", "-R", */
+ /* "-T", "-U", and "-W" commands */
+ if( tkstool.options[opt_PasswordFile].activated &&
+ ! ( tkstool.commands[cmd_DeleteKey].activated ||
+ tkstool.commands[cmd_InputGenTransportKey].activated ||
+ tkstool.commands[cmd_DisplayKCV].activated ||
+ tkstool.commands[cmd_ListKeys].activated ||
+ tkstool.commands[cmd_GenMasterKey].activated ||
+ tkstool.commands[cmd_NewDBs].activated ||
+ tkstool.commands[cmd_ChangePassword].activated ||
+ tkstool.commands[cmd_RenameKey].activated ||
+ tkstool.commands[cmd_GenTransportKey].activated ||
+ tkstool.commands[cmd_UnWrapMasterKey].activated ||
+ tkstool.commands[cmd_WrapMasterKey].activated ) ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-f pwfile\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* the "-h token_name" command option may ONLY be used with */
+ /* the "-D", "-I", "-K", "-L", "-M", "-R", "-T", "-U", and */
+ /* "-W" commands */
+ if( tkstool.options[opt_TokenName].activated &&
+ ! ( tkstool.commands[cmd_DeleteKey].activated ||
+ tkstool.commands[cmd_InputGenTransportKey].activated ||
+ tkstool.commands[cmd_DisplayKCV].activated ||
+ tkstool.commands[cmd_ListKeys].activated ||
+ tkstool.commands[cmd_GenMasterKey].activated ||
+ tkstool.commands[cmd_RenameKey].activated ||
+ tkstool.commands[cmd_GenTransportKey].activated ||
+ tkstool.commands[cmd_UnWrapMasterKey].activated ||
+ tkstool.commands[cmd_WrapMasterKey].activated ) ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-h token_name\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* the "-i infile" command option may ONLY be used with */
+ /* the "-U" command */
+ if( tkstool.options[opt_InFile].activated &&
+ !tkstool.commands[cmd_UnWrapMasterKey].activated ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-i infile\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* the "-n keyname" command option may ONLY be used with the */
+ /* "-D", "-I", "-K", "-L", "-M", "-R", "-T", "-U", and "-W" */
+ /* commands */
+ if( tkstool.options[opt_Keyname].activated &&
+ ! ( tkstool.commands[cmd_DeleteKey].activated ||
+ tkstool.commands[cmd_InputGenTransportKey].activated ||
+ tkstool.commands[cmd_DisplayKCV].activated ||
+ tkstool.commands[cmd_ListKeys].activated ||
+ tkstool.commands[cmd_GenMasterKey].activated ||
+ tkstool.commands[cmd_RenameKey].activated ||
+ tkstool.commands[cmd_GenTransportKey].activated ||
+ tkstool.commands[cmd_UnWrapMasterKey].activated ||
+ tkstool.commands[cmd_WrapMasterKey].activated ) ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-n keyname\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* the "-o outfile" command option may ONLY be used with */
+ /* the "-W" command */
+ if( tkstool.options[opt_OutFile].activated &&
+ !tkstool.commands[cmd_WrapMasterKey].activated ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-o outfile\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* the "-p DBPrefix" command option may ONLY be used with */
+ /* the "-D", "-I", "-K", "-L", "-M", "-N", "-P", "-R", */
+ /* "-S", "-T", "-U", and "-W" commands */
+ if( tkstool.options[opt_DBPrefix].activated &&
+ ! ( tkstool.commands[cmd_DeleteKey].activated ||
+ tkstool.commands[cmd_InputGenTransportKey].activated ||
+ tkstool.commands[cmd_DisplayKCV].activated ||
+ tkstool.commands[cmd_ListKeys].activated ||
+ tkstool.commands[cmd_GenMasterKey].activated ||
+ tkstool.commands[cmd_NewDBs].activated ||
+ tkstool.commands[cmd_ChangePassword].activated ||
+ tkstool.commands[cmd_RenameKey].activated ||
+ tkstool.commands[cmd_ListSecModules].activated ||
+ tkstool.commands[cmd_GenTransportKey].activated ||
+ tkstool.commands[cmd_UnWrapMasterKey].activated ||
+ tkstool.commands[cmd_WrapMasterKey].activated ) ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-p DBPrefix\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* the "-r new_keyname" command option may */
+ /* ONLY be used with the "-R" command */
+ if( tkstool.options[opt_NewKeyname].activated &&
+ ! ( tkstool.commands[cmd_RenameKey].activated ) ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-r new_keyname\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* the "-t transport_keyname" command option may ONLY be used with */
+ /* the "-U", and "-W" commands */
+ if( tkstool.options[opt_TransportKeyname].activated &&
+ !( tkstool.commands[cmd_UnWrapMasterKey].activated ||
+ tkstool.commands[cmd_WrapMasterKey].activated ) ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-t transport_keyname\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* the "-x" command option may ONLY be used with */
+ /* the "-L", and "-S" commands */
+ if( tkstool.options[opt_RW].activated &&
+ ! ( tkstool.commands[cmd_ListKeys].activated ||
+ tkstool.commands[cmd_ListSecModules].activated ) ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-x\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* the "-z noisefile" command option may ONLY be used with */
+ /* the "-T" command */
+ if( tkstool.options[opt_NoiseFile].activated &&
+ !tkstool.commands[cmd_GenTransportKey].activated ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-z noisefile\" option may only be "
+ "specified with one of the following command(s):\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+
+ /********************************************************/
+ /* Perform special processing on command line "options" */
+ /********************************************************/
+
+ /* "-d DBDir" command option */
+ if( tkstool.options[opt_DBDir].activated ) {
+ if( tkstool.options[opt_DBDir].arg ) {
+ DBDir = SECU_ConfigDirectory( tkstool.options[opt_DBDir].arg );
+ } else {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-d\" option must contain a "
+ "\"DBDir\" argument:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+ }
+
+ /* "-f pwfile" command option */
+ if( tkstool.options[opt_PasswordFile].activated ) {
+ pwdata.source = PW_FROMFILE;
+ if( tkstool.options[opt_PasswordFile].arg ) {
+ pwdata.data = tkstool.options[opt_PasswordFile].arg;
+ } else {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-f\" option must contain a "
+ "\"pwfile\" argument:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+ }
+
+ /* "-i infile" command option */
+ if( tkstool.options[opt_InFile].activated ) {
+ if( tkstool.options[opt_InFile].arg ) {
+ input = tkstool.options[opt_InFile].arg;
+ } else {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-i\" option must contain an "
+ "\"infile\" argument:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+ }
+
+ /* "-h token_name" command option */
+ if( tkstool.options[opt_TokenName].activated ) {
+ if( tkstool.options[opt_TokenName].arg ) {
+ if( PL_strcmp( tkstool.options[opt_TokenName].arg, "all" ) == 0 ) {
+ slotname = NULL;
+ } else {
+ slotname = PL_strdup( tkstool.options[opt_TokenName].arg );
+ }
+ } else {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-h\" option must contain a "
+ "\"token_name\" argument:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+ }
+
+ /* "-n keyname" command option */
+ if( tkstool.options[opt_Keyname].activated ) {
+ if( tkstool.options[opt_Keyname].arg ) {
+ keyname = SECU_GetOptionArg( &tkstool,
+ opt_Keyname );
+ } else {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-n\" option must contain a "
+ "\"keyname\" argument:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+ }
+
+ /* "-o outfile" command option */
+ if( tkstool.options[opt_OutFile].activated ) {
+ if( tkstool.options[opt_OutFile].arg ) {
+ output = tkstool.options[opt_OutFile].arg;
+ } else {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-o\" option must contain an "
+ "\"outfile\" argument:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+ }
+
+ /* "-p DBPrefix" command option */
+ if( tkstool.options[opt_DBPrefix].activated ) {
+ if( tkstool.options[opt_DBPrefix].arg ) {
+ DBPrefix = strdup( tkstool.options[opt_DBPrefix].arg );
+ } else {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-p\" option must contain a "
+ "\"DBPrefix\" argument:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+ }
+
+ /* "-r new_keyname" command option */
+ if( tkstool.options[opt_NewKeyname].activated ) {
+ if( tkstool.options[opt_NewKeyname].arg ) {
+ new_keyname = SECU_GetOptionArg( &tkstool,
+ opt_NewKeyname );
+ } else {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-r\" option must contain a "
+ "\"new_keyname\" argument:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+ }
+
+ /* "-t transport_keyname" command option */
+ if( tkstool.options[opt_TransportKeyname].activated ) {
+ if( tkstool.options[opt_TransportKeyname].arg ) {
+ transport_keyname = SECU_GetOptionArg( &tkstool,
+ opt_TransportKeyname );
+ } else {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-t\" option must contain a "
+ "\"transport_keyname\" argument:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+ }
+
+ /* "-x" command option is processed below */
+ /* ONLY based upon specific commands */
+
+ /* "-z noisefile" command option */
+ if( tkstool.options[opt_NoiseFile].activated ) {
+ if( tkstool.options[opt_NoiseFile].arg ) {
+ SeedNoise = tkstool.options[opt_NoiseFile].arg;
+ } else {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-z\" option must contain a "
+ "\"noisefile\" argument:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+ }
+
+
+ /******************************************************************/
+ /* Perform special processing on specific command line "commands" */
+ /******************************************************************/
+
+ /* "-D", "-I", "-K", "-M", "-R", "-T", "-U" and "-W" */
+ /* commands require the "-n keyname" command line */
+ /* option to be specified */
+ if( ( tkstool.commands[cmd_DeleteKey].activated ||
+ tkstool.commands[cmd_InputGenTransportKey].activated ||
+ tkstool.commands[cmd_DisplayKCV].activated ||
+ tkstool.commands[cmd_GenMasterKey].activated ||
+ tkstool.commands[cmd_RenameKey].activated ||
+ tkstool.commands[cmd_GenTransportKey].activated ||
+ tkstool.commands[cmd_UnWrapMasterKey].activated ||
+ tkstool.commands[cmd_WrapMasterKey].activated ) &&
+ !tkstool.options[opt_Keyname].activated ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-n keyname\" option is required "
+ "for this command:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* "-D", "-I", "-K", "-L", "-M", "-N", "-P", "-R", "-S", */
+ /* "-T", "-U", and "-W" commands require the "-d DBDir" */
+ /* command line option to be specified */
+ if( ( tkstool.commands[cmd_DeleteKey].activated ||
+ tkstool.commands[cmd_InputGenTransportKey].activated ||
+ tkstool.commands[cmd_DisplayKCV].activated ||
+ tkstool.commands[cmd_ListKeys].activated ||
+ tkstool.commands[cmd_GenMasterKey].activated ||
+ tkstool.commands[cmd_NewDBs].activated ||
+ tkstool.commands[cmd_ChangePassword].activated ||
+ tkstool.commands[cmd_RenameKey].activated ||
+ tkstool.commands[cmd_ListSecModules].activated ||
+ tkstool.commands[cmd_GenTransportKey].activated ||
+ tkstool.commands[cmd_UnWrapMasterKey].activated ||
+ tkstool.commands[cmd_WrapMasterKey].activated ) &&
+ !tkstool.options[opt_DBDir].activated ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-d DBDir\" option is required "
+ "for this command:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* "-H", "-L", "-S", and "-V" commands require the "-x" */
+ /* command line option to be silently turned off */
+ if( tkstool.commands[cmd_PrintHelp].activated ||
+ tkstool.commands[cmd_ListKeys].activated ||
+ tkstool.commands[cmd_ListSecModules].activated ||
+ tkstool.commands[cmd_Version].activated ) {
+ readOnly = !tkstool.options[opt_RW].activated;
+ }
+
+ /* "-L" command is the ONLY command that allows */
+ /* the "-h all" command line option to be used */
+ /* */
+ /* NOTE: ONLY use "slotname == NULL" to */
+ /* LIST keys on all slots */
+ if( !tkstool.commands[cmd_ListKeys].activated && slotname == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: cannot use \"-h all\" for this command:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* "-R" commands require the "-r new_keyname" */
+ /* command line option to be specified */
+ if( ( tkstool.commands[cmd_RenameKey].activated ) &&
+ !tkstool.options[opt_NewKeyname].activated ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-r new_keyname\" option is required "
+ "for this command:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* "-U", and "-W" commands require the "-t transport_keyname" */
+ /* command line option to be specified */
+ if( ( tkstool.commands[cmd_UnWrapMasterKey].activated ||
+ tkstool.commands[cmd_WrapMasterKey].activated ) &&
+ !tkstool.options[opt_TransportKeyname].activated ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-t transport_keyname\" option is required "
+ "for this command:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* "-U" commands require the "-i infile" */
+ /* command line option to be specified */
+ if( tkstool.commands[cmd_UnWrapMasterKey].activated &&
+ !tkstool.options[opt_InFile].activated ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-i infile\" option is required "
+ "for this command:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+ /* "-W" commands require the "-o outfile" */
+ /* command line option to be specified */
+ if( tkstool.commands[cmd_WrapMasterKey].activated &&
+ !tkstool.options[opt_OutFile].activated ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: the \"-o outfile\" option is required "
+ "for this command:\n\n",
+ progName,
+ commandToRun );
+
+ TKS_Usage( progName );
+
+ return 255;
+ }
+
+
+ /*********************************/
+ /* Execute the "-H" help command */
+ /*********************************/
+
+ if( tkstool.commands[cmd_PrintHelp].activated ) {
+ TKS_PrintHelp( progName );
+
+ return 0;
+ }
+
+
+ /************************************/
+ /* Execute the "-V" version command */
+ /************************************/
+
+ /* "-V" version command */
+ if( tkstool.commands[cmd_Version].activated ) {
+ TKS_Version( progName );
+
+ return 0;
+ }
+
+
+ /************************************************/
+ /* Initialize PKCS #11 Security Module Password */
+ /************************************************/
+
+ PK11_SetPasswordFunc( /* password callback */ SECU_GetModulePassword );
+
+
+ /*******************/
+ /* Initialize NSPR */
+ /*******************/
+
+ PR_Init( PR_SYSTEM_THREAD,
+ PR_PRIORITY_NORMAL,
+ 1 );
+
+
+ /******************/
+ /* Initialize NSS */
+ /******************/
+
+ rvNSSinit = NSS_Initialize( DBDir,
+ DBPrefix,
+ DBPrefix,
+ "secmod.db",
+ readOnly ? NSS_INIT_READONLY : 0 );
+ if( rvNSSinit != SECSuccess ) {
+ char buffer[513];
+ PRInt32 errLen = PR_GetErrorTextLength();
+
+ if( errLen > 0 && errLen < sizeof buffer ) {
+ PR_GetErrorText( buffer );
+ }
+
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s",
+ progName,
+ commandToRun,
+ "NSS_Initialize() failed" );
+
+ if( errLen > 0 && errLen < sizeof buffer ) {
+ PR_fprintf( PR_STDERR, "\t%s\n", buffer );
+ } else {
+ PR_fprintf( PR_STDERR, "\n" );
+ }
+
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*****************************************************/
+ /* Initialize internal PKCS #11 software crypto slot */
+ /* as well as any specified PKCS #11 slot */
+ /*****************************************************/
+
+ /* Always initialize the internal software crypto slot */
+ internalSlot = PK11_GetInternalSlot();
+
+ /* If "slotname != NULL", initialize the slot based upon the slotname */
+ if( PL_strcmp( slotname, "internal" ) == 0 ) {
+ slot = PK11_GetInternalKeySlot();
+ } else if( slotname != NULL ) {
+ slot = PK11_FindSlotByName( /* slot name */ slotname );
+
+ /* Fixes Bugscape Bug #55178: tkstool dumps core if -h <token> */
+ /* specifies a nonexistent token */
+ if( slot == NULL ) {
+ char buffer[513];
+ PRInt32 errLen = PR_GetErrorTextLength();
+
+ if( errLen > 0 && errLen < sizeof buffer ) {
+ PR_GetErrorText( buffer );
+ }
+
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s%s%s",
+ progName,
+ commandToRun,
+ "no token called \"",
+ slotname,
+ "\" exists!" );
+
+ if( errLen > 0 && errLen < sizeof buffer ) {
+ PR_fprintf( PR_STDERR, "\t%s\n", buffer );
+ } else {
+ PR_fprintf( PR_STDERR, "\n" );
+ }
+
+ rv = SECFailure;
+ goto shutdown;
+ }
+ }
+
+
+ /****************************************/
+ /* Execute the "-D" delete keys command */
+ /* */
+ /* NOTE: This command is mutually */
+ /* exclusive from all others. */
+ /****************************************/
+
+ if( tkstool.commands[cmd_DeleteKey].activated ) {
+ rv = TKS_DeleteKeys( progName,
+ slot,
+ keyname,
+ &pwdata );
+ goto shutdown;
+ }
+
+
+ /*******************************************************************/
+ /* Execute the "-I" input shares to generate transport key command */
+ /* */
+ /* --- OR --- */
+ /* */
+ /* Execute the "-T" generate transport key command */
+ /* */
+ /* NOTE: Each of these commands is mutually */
+ /* exclusive from all others, including */
+ /* each other. */
+ /*******************************************************************/
+
+ if( tkstool.commands[cmd_InputGenTransportKey].activated ||
+ tkstool.commands[cmd_GenTransportKey].activated ) {
+
+ /**********************************************************/
+ /* Do not allow duplicate symmetric keys to be generated */
+ /* (i. e. - disallow symmetric keys specified */
+ /* by the same keyname) */
+ /* */
+ /* NOTE: The following code snippet effectively */
+ /* prohibits this tool from generating any */
+ /* symmetric key with a keyname that already */
+ /* resides in the specified token */
+ /**********************************************************/
+
+ rvFindSymKey = TKS_FindSymKey( slot,
+ keyname,
+ &pwdata );
+ if( rvFindSymKey == SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tthe \"%s\" keyname specified by "
+ "\n\t\t\"-n %s\"\n\t\talready exists in the "
+ "specified token.\n\t\tPlease specify a "
+ "different keyname.\n\n",
+ progName,
+ commandToRun,
+ keyname,
+ keyname );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /**********************************************/
+ /* Seed the Random Number Generator (RNG). */
+ /* ("-T" generate transport key command ONLY) */
+ /**********************************************/
+
+ if( tkstool.commands[cmd_GenTransportKey].activated ) {
+ rvSeedRNG = TKS_SeedRNG( SeedNoise );
+ if( rvSeedRNG != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s",
+ progName,
+ commandToRun,
+ "unable to seed random number generator\n" );
+ rv = SECFailure;
+ goto shutdown;
+ }
+ }
+
+
+ /***********************************/
+ /* Clear screen and wait for user. */
+ /***********************************/
+
+ TKS_ClearScreen();
+
+ if( tkstool.commands[cmd_GenTransportKey].activated ) {
+ PR_fprintf( PR_STDOUT,
+ "\nThe next screen generates the "
+ "first session key share . . .\n" );
+ } else {
+ /* ( tkstool.commands[cmd_InputGenTransportKey].activated ) */
+ PR_fprintf( PR_STDOUT,
+ "\nUse the next screen to input the "
+ "first session key share . . .\n" );
+ }
+
+ TKS_TypeProceedToContinue();
+
+
+ /******************************************************************/
+ /* Input ("-I"), or Generate ("-T"), the first session key share. */
+ /******************************************************************/
+
+ firstSessionKeyShare.len = FIRST_SESSION_KEY_SHARE_LENGTH;
+ firstSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( FIRST_SESSION_KEY_SHARE_LENGTH );
+
+ if( tkstool.commands[cmd_GenTransportKey].activated ) {
+ rvFirstSessionKeyShare = TKS_GenerateSessionKeyShare(
+ FIRST_SESSION_KEY_SHARE,
+ &firstSessionKeyShare );
+
+ if( rvFirstSessionKeyShare != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s",
+ progName,
+ commandToRun,
+ "unable to generate the ",
+ FIRST_SESSION_KEY_SHARE,
+ " session key share\n" );
+ rv = SECFailure;
+ goto shutdown;
+ }
+ } else {
+ /* ( tkstool.commands[cmd_InputGenTransportKey].activated ) */
+ while( rvFirstSessionKeyShare != SECSuccess ) {
+ rvFirstSessionKeyShare = TKS_InputSessionKeyShare(
+ FIRST_SESSION_KEY_SHARE,
+ &firstSessionKeyShare );
+ }
+ }
+
+#if defined(PAD_DES2_KEY_LENGTH)
+ /****************************************************************/
+ /* Since TKS uses double-DES keys instead of triple-DES keys, */
+ /* the final 8 bytes of this session key share must be padded */
+ /* in order to use the standard PKCS #11 triple-DES operations! */
+ /* */
+ /* Therefore, in order to perform this operation, the 16 bytes */
+ /* comprising the original buffer are first copied into the new */
+ /* buffer, and then the first 8 bytes of the original buffer */
+ /* are copied into the final 8 bytes of the new buffer. */
+ /****************************************************************/
+
+ paddedFirstSessionKeyShare.len = PADDED_FIRST_SESSION_KEY_SHARE_LENGTH;
+ paddedFirstSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( PADDED_FIRST_SESSION_KEY_SHARE_LENGTH );
+
+ PORT_Memcpy( paddedFirstSessionKeyShare.data,
+ firstSessionKeyShare.data,
+ FIRST_SESSION_KEY_SHARE_LENGTH );
+ PORT_Memcpy( ( paddedFirstSessionKeyShare.data +
+ FIRST_SESSION_KEY_SHARE_LENGTH ),
+ firstSessionKeyShare.data,
+ DES_LENGTH );
+#endif
+
+
+ /***********************************/
+ /* Clear screen and wait for user. */
+ /***********************************/
+
+ TKS_ClearScreen();
+
+ if( tkstool.commands[cmd_GenTransportKey].activated ) {
+ PR_fprintf( PR_STDOUT,
+ "\nThe next screen generates the "
+ "second session key share . . .\n" );
+ } else {
+ /* ( tkstool.commands[cmd_InputGenTransportKey].activated ) */
+ PR_fprintf( PR_STDOUT,
+ "\nUse the next screen to input the "
+ "second session key share . . .\n" );
+ }
+
+ TKS_TypeProceedToContinue();
+
+
+ /*******************************************************************/
+ /* Input ("-I"), or Generate ("-T"), the second session key share. */
+ /*******************************************************************/
+
+ secondSessionKeyShare.len = SECOND_SESSION_KEY_SHARE_LENGTH;
+ secondSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( SECOND_SESSION_KEY_SHARE_LENGTH );
+
+ if( tkstool.commands[cmd_GenTransportKey].activated ) {
+ rvSecondSessionKeyShare = TKS_GenerateSessionKeyShare(
+ SECOND_SESSION_KEY_SHARE,
+ &secondSessionKeyShare );
+
+ if( rvSecondSessionKeyShare != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s",
+ progName,
+ commandToRun,
+ "unable to generate the ",
+ SECOND_SESSION_KEY_SHARE,
+ " session key share\n" );
+ rv = SECFailure;
+ goto shutdown;
+ }
+ } else {
+ /* ( tkstool.commands[cmd_InputGenTransportKey].activated ) */
+ while( rvSecondSessionKeyShare != SECSuccess ) {
+ rvSecondSessionKeyShare = TKS_InputSessionKeyShare(
+ SECOND_SESSION_KEY_SHARE,
+ &secondSessionKeyShare );
+ }
+ }
+
+#if defined(PAD_DES2_KEY_LENGTH)
+ /****************************************************************/
+ /* Since TKS uses double-DES keys instead of triple-DES keys, */
+ /* the final 8 bytes of this session key share must be padded */
+ /* in order to use the standard PKCS #11 triple-DES operations! */
+ /* */
+ /* Therefore, in order to perform this operation, the 16 bytes */
+ /* comprising the original buffer are first copied into the new */
+ /* buffer, and then the first 8 bytes of the original buffer */
+ /* are copied into the final 8 bytes of the new buffer. */
+ /****************************************************************/
+
+ paddedSecondSessionKeyShare.len = PADDED_SECOND_SESSION_KEY_SHARE_LENGTH;
+ paddedSecondSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( PADDED_SECOND_SESSION_KEY_SHARE_LENGTH );
+
+ PORT_Memcpy( paddedSecondSessionKeyShare.data,
+ secondSessionKeyShare.data,
+ SECOND_SESSION_KEY_SHARE_LENGTH );
+ PORT_Memcpy( ( paddedSecondSessionKeyShare.data +
+ SECOND_SESSION_KEY_SHARE_LENGTH ),
+ secondSessionKeyShare.data,
+ DES_LENGTH );
+
+
+ /**********************************************/
+ /* Prepare this key share to be used with the */
+ /* TKS_DeriveSymmetricKey() function . . . */
+ /**********************************************/
+
+ /* store a copy of the "original" padded second session key share */
+ secondDerivationData.ulLen = paddedSecondSessionKeyShare.len;
+ secondDerivationData.pData = ( unsigned char * )
+ PORT_ZAlloc( paddedSecondSessionKeyShare.len );
+ PORT_Memcpy( secondDerivationData.pData,
+ paddedSecondSessionKeyShare.data,
+ paddedSecondSessionKeyShare.len );
+
+ /* destroy the "original" padded second session key share */
+ if( paddedSecondSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ paddedSecondSessionKeyShare.data,
+ paddedSecondSessionKeyShare.len );
+ paddedSecondSessionKeyShare.data = NULL;
+ paddedSecondSessionKeyShare.len = 0;
+ }
+
+ /* create a "new" container for the padded second session key share */
+ paddedSecondSessionKeyShare.len = sizeof( CK_KEY_DERIVATION_STRING_DATA );
+ paddedSecondSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( paddedSecondSessionKeyShare.len );
+
+ /* copy the "original" padded second session key share */
+ /* into the "new" container */
+ PORT_Memcpy( paddedSecondSessionKeyShare.data,
+ &secondDerivationData,
+ paddedSecondSessionKeyShare.len );
+#else
+ /**********************************************/
+ /* Prepare this key share to be used with the */
+ /* TKS_DeriveSymmetricKey() function . . . */
+ /**********************************************/
+
+ /* store a copy of the "original" second session key share */
+ secondDerivationData.ulLen = secondSessionKeyShare.len;
+ secondDerivationData.pData = ( unsigned char * )
+ PORT_ZAlloc( secondSessionKeyShare.len );
+ PORT_Memcpy( secondDerivationData.pData,
+ secondSessionKeyShare.data,
+ secondSessionKeyShare.len );
+
+ /* destroy the "original" second session key share */
+ if( secondSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ secondSessionKeyShare.data,
+ secondSessionKeyShare.len );
+ secondSessionKeyShare.data = NULL;
+ secondSessionKeyShare.len = 0;
+ }
+
+ /* create a "new" container for the second session key share */
+ secondSessionKeyShare.len = sizeof( CK_KEY_DERIVATION_STRING_DATA );
+ secondSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( secondSessionKeyShare.len );
+
+ /* copy the "original" second session key share */
+ /* into the "new" container */
+ PORT_Memcpy( secondSessionKeyShare.data,
+ &secondDerivationData,
+ secondSessionKeyShare.len );
+#endif
+
+
+ /***********************************/
+ /* Clear screen and wait for user. */
+ /***********************************/
+
+ TKS_ClearScreen();
+
+ if( tkstool.commands[cmd_GenTransportKey].activated ) {
+ PR_fprintf( PR_STDOUT,
+ "\nThe next screen generates the "
+ "third session key share . . .\n" );
+ } else {
+ /* ( tkstool.commands[cmd_InputGenTransportKey].activated ) */
+ PR_fprintf( PR_STDOUT,
+ "\nUse the next screen to input the "
+ "third session key share . . .\n" );
+ }
+
+ TKS_TypeProceedToContinue();
+
+
+ /******************************************************************/
+ /* Input ("-I"), or Generate ("-T"), the third session key share. */
+ /******************************************************************/
+
+ thirdSessionKeyShare.len = THIRD_SESSION_KEY_SHARE_LENGTH;
+ thirdSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( THIRD_SESSION_KEY_SHARE_LENGTH );
+
+ if( tkstool.commands[cmd_GenTransportKey].activated ) {
+ rvThirdSessionKeyShare = TKS_GenerateSessionKeyShare(
+ THIRD_SESSION_KEY_SHARE,
+ &thirdSessionKeyShare );
+
+ if( rvThirdSessionKeyShare != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s",
+ progName,
+ commandToRun,
+ "unable to generate the ",
+ THIRD_SESSION_KEY_SHARE,
+ " session key share\n" );
+ rv = SECFailure;
+ goto shutdown;
+ }
+ } else {
+ /* ( tkstool.commands[cmd_InputGenTransportKey].activated ) */
+ while( rvThirdSessionKeyShare != SECSuccess ) {
+ rvThirdSessionKeyShare = TKS_InputSessionKeyShare(
+ THIRD_SESSION_KEY_SHARE,
+ &thirdSessionKeyShare );
+ }
+ }
+
+#if defined(PAD_DES2_KEY_LENGTH)
+ /****************************************************************/
+ /* Since TKS uses double-DES keys instead of triple-DES keys, */
+ /* the final 8 bytes of this session key share must be padded */
+ /* in order to use the standard PKCS #11 triple-DES operations! */
+ /* */
+ /* Therefore, in order to perform this operation, the 16 bytes */
+ /* comprising the original buffer are first copied into the new */
+ /* buffer, and then the first 8 bytes of the original buffer */
+ /* are copied into the final 8 bytes of the new buffer. */
+ /****************************************************************/
+
+ paddedThirdSessionKeyShare.len = PADDED_THIRD_SESSION_KEY_SHARE_LENGTH;
+ paddedThirdSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( PADDED_THIRD_SESSION_KEY_SHARE_LENGTH );
+
+ PORT_Memcpy( paddedThirdSessionKeyShare.data,
+ thirdSessionKeyShare.data,
+ THIRD_SESSION_KEY_SHARE_LENGTH );
+ PORT_Memcpy( ( paddedThirdSessionKeyShare.data +
+ THIRD_SESSION_KEY_SHARE_LENGTH ),
+ thirdSessionKeyShare.data,
+ DES_LENGTH );
+
+
+ /**********************************************/
+ /* Prepare this key share to be used with the */
+ /* TKS_DeriveSymmetricKey() function . . . */
+ /**********************************************/
+
+ /* store a copy of the "original" padded third session key share */
+ thirdDerivationData.ulLen = paddedThirdSessionKeyShare.len;
+ thirdDerivationData.pData = ( unsigned char * )
+ PORT_ZAlloc( paddedThirdSessionKeyShare.len );
+ PORT_Memcpy( thirdDerivationData.pData,
+ paddedThirdSessionKeyShare.data,
+ paddedThirdSessionKeyShare.len );
+
+ /* destroy the "original" padded third session key share */
+ if( paddedThirdSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ paddedThirdSessionKeyShare.data,
+ paddedThirdSessionKeyShare.len );
+ paddedThirdSessionKeyShare.data = NULL;
+ paddedThirdSessionKeyShare.len = 0;
+ }
+
+ /* create a "new" container for the padded third session key share */
+ paddedThirdSessionKeyShare.len = sizeof( CK_KEY_DERIVATION_STRING_DATA );
+ paddedThirdSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( paddedThirdSessionKeyShare.len );
+
+ /* copy the "original" padded third session key share */
+ /* into the "new" container */
+ PORT_Memcpy( paddedThirdSessionKeyShare.data,
+ &thirdDerivationData,
+ paddedThirdSessionKeyShare.len );
+#else
+ /**********************************************/
+ /* Prepare this key share to be used with the */
+ /* TKS_DeriveSymmetricKey() function . . . */
+ /**********************************************/
+
+ /* store a copy of the "original" third session key share */
+ thirdDerivationData.ulLen = thirdSessionKeyShare.len;
+ thirdDerivationData.pData = ( unsigned char * )
+ PORT_ZAlloc( thirdSessionKeyShare.len );
+ PORT_Memcpy( thirdDerivationData.pData,
+ thirdSessionKeyShare.data,
+ thirdSessionKeyShare.len );
+
+ /* destroy the "original" third session key share */
+ if( thirdSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ thirdSessionKeyShare.data,
+ thirdSessionKeyShare.len );
+ thirdSessionKeyShare.data = NULL;
+ thirdSessionKeyShare.len = 0;
+ }
+
+ /* create a "new" container for the third session key share */
+ thirdSessionKeyShare.len = sizeof( CK_KEY_DERIVATION_STRING_DATA );
+ thirdSessionKeyShare.data = ( unsigned char * )
+ PORT_ZAlloc( thirdSessionKeyShare.len );
+
+ /* copy the "original" third session key share */
+ /* into the "new" container */
+ PORT_Memcpy( thirdSessionKeyShare.data,
+ &thirdDerivationData,
+ thirdSessionKeyShare.len );
+#endif
+
+
+ /***********************************/
+ /* Clear screen and wait for user. */
+ /***********************************/
+
+ TKS_ClearScreen();
+
+ PR_fprintf( PR_STDOUT,
+ "\nThe next screen uses the session key shares to "
+ "generate the transport key . . .\n" );
+
+ TKS_TypeProceedToContinue();
+
+ TKS_ClearScreen();
+
+
+ /**************************************/
+ /* Generate the first symmetric key */
+ /* using the first session key share. */
+ /**************************************/
+
+
+#if defined(PAD_DES2_KEY_LENGTH)
+ firstSymmetricKey = TKS_ImportSymmetricKey( FIRST_SYMMETRIC_KEY,
+ internalSlot,
+ CKM_DES3_KEY_GEN,
+ CKA_ENCRYPT,
+ &paddedFirstSessionKeyShare,
+ &pwdata );
+#else
+ firstSymmetricKey = TKS_ImportSymmetricKey( FIRST_SYMMETRIC_KEY,
+ internalSlot,
+ CKM_DES2_KEY_GEN,
+ CKA_ENCRYPT,
+ &firstSessionKeyShare,
+ &pwdata );
+#endif
+ if( firstSymmetricKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to generate the first (or initial) "
+ "symmetric key",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*********************************************************/
+ /* Generate the second symmetric key using the */
+ /* first symmetric key and the second session key share. */
+ /*********************************************************/
+
+#if defined(PAD_DES2_KEY_LENGTH)
+ secondSymmetricKey = TKS_DeriveSymmetricKey( SECOND_SYMMETRIC_KEY,
+ firstSymmetricKey,
+ CKM_XOR_BASE_AND_DATA,
+ &paddedSecondSessionKeyShare,
+ CKM_DES3_ECB,
+ ( CKA_DERIVE |
+ CKA_ENCRYPT ),
+ PADDED_SECOND_SESSION_KEY_SHARE_LENGTH );
+#else
+ secondSymmetricKey = TKS_DeriveSymmetricKey( SECOND_SYMMETRIC_KEY,
+ firstSymmetricKey,
+ CKM_XOR_BASE_AND_DATA,
+ &secondSessionKeyShare,
+ CKM_DES3_ECB,
+ ( CKA_DERIVE |
+ CKA_ENCRYPT ),
+ SECOND_SESSION_KEY_SHARE_LENGTH );
+#endif
+ if( secondSymmetricKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to generate the second (or intermediate) "
+ "symmetric key",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*********************************************************/
+ /* Generate the third symmetric key using the */
+ /* second symmetric key and the third session key share. */
+ /*********************************************************/
+
+#if defined(PAD_DES2_KEY_LENGTH)
+ thirdSymmetricKey = TKS_DeriveSymmetricKey( THIRD_SYMMETRIC_KEY,
+ secondSymmetricKey,
+ CKM_XOR_BASE_AND_DATA,
+ &paddedThirdSessionKeyShare,
+ CKM_DES3_ECB,
+ ( CKA_DERIVE |
+ CKA_ENCRYPT ),
+ PADDED_THIRD_SESSION_KEY_SHARE_LENGTH );
+#else
+ thirdSymmetricKey = TKS_DeriveSymmetricKey( THIRD_SYMMETRIC_KEY,
+ secondSymmetricKey,
+ CKM_XOR_BASE_AND_DATA,
+ &thirdSessionKeyShare,
+ CKM_DES3_ECB,
+ ( CKA_DERIVE |
+ CKA_ENCRYPT ),
+ THIRD_SESSION_KEY_SHARE_LENGTH );
+#endif
+ if( thirdSymmetricKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to generate the third (or final) "
+ "symmetric key",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*******************************************************************/
+ /* Finally, store the third symmetric key (the transport key) into */
+ /* the specified slot, and provide a name for this transport key. */
+ /*******************************************************************/
+
+ rvSymmetricKeyname = TKS_StoreSymmetricKeyAndNameIt( TRANSPORT_KEY,
+ keyname,
+ slot,
+ ( CKA_ENCRYPT |
+ CKA_WRAP ),
+ ( CKF_ENCRYPT |
+ CKF_UNWRAP |
+ CKF_WRAP ),
+ thirdSymmetricKey );
+ if( rvSymmetricKeyname != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Failed to save/name the transport key!\n\n" );
+ rv = SECFailure;
+ goto shutdown;
+ } else {
+ PR_fprintf( PR_STDOUT,
+ "Successfully generated, stored, and named the "
+ "transport key!\n\n" );
+ }
+
+
+ /*********************************/
+ /* Cleanup and exit with success */
+ /*********************************/
+
+ rv = SECSuccess;
+ goto shutdown;
+ }
+
+
+ /****************************************/
+ /* Execute the "-K" display KCV command */
+ /* */
+ /* NOTE: This command is mutually */
+ /* exclusive from all others. */
+ /****************************************/
+
+ if( tkstool.commands[cmd_DisplayKCV].activated ) {
+
+ /*****************************************************/
+ /* Retrieve a handle to the specified symmetric key. */
+ /* This insures that the specified symmetric key */
+ /* already resides on the specified token. */
+ /*****************************************************/
+
+ symmetricKey = TKS_RetrieveSymKey( slot,
+ keyname,
+ &pwdata );
+ if( symmetricKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tthe \"%s\" symmetric keyname specified by "
+ "\n\t\t\"-n %s\" does NOT exist on the specified "
+ "token.\n\t\tPlease specify a "
+ "different symmetric keyname.\n\n",
+ progName,
+ commandToRun,
+ keyname,
+ keyname );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*************************************************/
+ /* Compute and display this symmetric key's KCV. */
+ /*************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "\nComputing and displaying KCV of the symmetric key "
+ "on the specified token . . .\n\n" );
+
+ /* Calculate this symmetric key's KCV */
+ rvKCV = TKS_ComputeAndDisplayKCV( ( PRUint8 * ) NULL,
+ ( PRIntn ) 0,
+ ( PRUint8 * ) KCV,
+ ( PRIntn ) KCVLen,
+ symmetricKey,
+ keyname,
+ RESIDENT_KEY,
+ PR_TRUE,
+ NULL );
+ if( rvKCV != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Unable to compute/display KCV of "
+ "this symmetric key!\n\n" );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*********************************/
+ /* Cleanup and exit with success */
+ /*********************************/
+
+ rv = SECSuccess;
+ goto shutdown;
+ }
+
+
+ /**************************************/
+ /* Execute the "-L" list keys command */
+ /* */
+ /* NOTE: This command is mutually */
+ /* exclusive from all others. */
+ /**************************************/
+
+ if( tkstool.commands[cmd_ListKeys].activated ) {
+ rv = TKS_ListKeys( progName,
+ slot,
+ keyname,
+ 0 /*keyindex*/,
+ PR_FALSE /*dopriv*/,
+ &pwdata );
+ goto shutdown;
+ }
+
+
+ /************************************************/
+ /* Execute the "-M" generate master key command */
+ /* */
+ /* NOTE: This command is mutually */
+ /* exclusive from all others. */
+ /************************************************/
+
+ if( tkstool.commands[cmd_GenMasterKey].activated ) {
+
+ /**********************************************************/
+ /* Do not allow duplicate symmetric keys to be generated */
+ /* (i. e. - disallow symmetric keys specified */
+ /* by the same keyname) */
+ /* */
+ /* NOTE: The following code snippet effectively */
+ /* prohibits this tool from generating any */
+ /* symmetric key with a keyname that already */
+ /* resides in the specified token */
+ /**********************************************************/
+
+ rvFindSymKey = TKS_FindSymKey( slot,
+ keyname,
+ &pwdata );
+ if( rvFindSymKey == SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tthe \"%s\" keyname specified by "
+ "\n\t\t\"-n %s\"\n\t\talready exists in the "
+ "specified token.\n\t\tPlease specify a "
+ "different keyname.\n\n",
+ progName,
+ commandToRun,
+ keyname,
+ keyname );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*****************************************************************/
+ /* Generate the master key and store it on the designated token. */
+ /*****************************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "\nGenerating and storing the master key "
+ "on the specified token . . .\n\n" );
+
+ if( MASTER_KEY_LENGTH == ( 2 * DES_LENGTH ) ) {
+ masterKey = PK11_TokenKeyGen(
+ /* slot */ slot,
+ /* mechanism */ CKM_DES2_KEY_GEN,
+ /* param */ 0,
+ /* keySize */ 0,
+ /* keyid */ 0,
+ /* isToken (i. e. - isPerm) */ PR_TRUE,
+ /* wincx */ &pwdata );
+ if( masterKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to generate/store this DES2 master key ",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+ } else if( MASTER_KEY_LENGTH == ( 3 * DES_LENGTH ) ) {
+ masterKey = PK11_TokenKeyGen(
+ /* slot */ slot,
+ /* mechanism */ CKM_DES3_KEY_GEN,
+ /* param */ 0,
+ /* keySize */ 0,
+ /* keyid */ 0,
+ /* isToken (i. e. - isPerm) */ PR_TRUE,
+ /* wincx */ &pwdata );
+ if( masterKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to generate/store this DES3 master key ",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+ } else {
+ /* invalid key size */
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s\n\n\n",
+ progName,
+ commandToRun,
+ "MASTER_KEY_LENGTH must be DES2 or DES3 length!" );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*****************************************************************/
+ /* Finally, name the master key with the specified name. */
+ /*****************************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Naming the master key \"%s\" . . .\n\n",
+ keyname );
+
+ rvMasterKeyname = PK11_SetSymKeyNickname(
+ /* symmetric key */ masterKey,
+ /* nickname */ keyname );
+ if( rvMasterKeyname != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Failed to name the master key!\n\n" );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*********************************************/
+ /* Compute and display the master key's KCV. */
+ /*********************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Computing and displaying KCV of the master key "
+ "on the specified token . . .\n\n" );
+
+ /* Calculate the master key's KCV */
+ rvKCV = TKS_ComputeAndDisplayKCV( ( PRUint8 * ) NULL,
+ ( PRIntn ) 0,
+ ( PRUint8 * ) KCV,
+ ( PRIntn ) KCVLen,
+ masterKey,
+ keyname,
+ RESIDENT_KEY,
+ PR_TRUE,
+ NULL );
+ if( rvKCV != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Unable to compute/display KCV of "
+ "the master key!\n\n" );
+ rv = SECFailure;
+ goto shutdown;
+ } else {
+ PR_fprintf( PR_STDOUT,
+ "Successfully generated, stored, and named the "
+ "master key\nincluding computing and displaying "
+ "its KCV!\n\n" );
+ }
+
+
+ /*********************************/
+ /* Cleanup and exit with success */
+ /*********************************/
+
+ rv = SECSuccess;
+ goto shutdown;
+ }
+
+
+ /**************************************************************/
+ /* Execute the "-N" new software database creation command */
+ /* */
+ /* NOTE: This command is mutually exclusive from all others. */
+ /* Always initialize the password when creating a new */
+ /* set of software databases */
+ /**************************************************************/
+
+ if( tkstool.commands[cmd_NewDBs].activated ) {
+ rv = SECU_ChangePW( slot,
+ 0,
+ pwdata.data );
+ goto shutdown;
+ }
+
+
+ /****************************************************/
+ /* Execute the "-P" change key DB password command */
+ /* */
+ /* NOTE: This command is mutually exclusive from */
+ /* all others. (future - change pw to slot?) */
+ /****************************************************/
+
+ if( tkstool.commands[cmd_ChangePassword].activated ) {
+ rv = SECU_ChangePW( slot,
+ 0,
+ pwdata.data );
+ goto shutdown;
+ }
+
+
+ /***************************************/
+ /* Execute the "-R" rename key command */
+ /* */
+ /* NOTE: This command is mutually */
+ /* exclusive from all others. */
+ /***************************************/
+
+ if( tkstool.commands[cmd_RenameKey].activated ) {
+
+ /*****************************************************/
+ /* Check that specified keynames are not identical. */
+ /*****************************************************/
+ if( PL_strcmp( keyname, new_keyname ) == 0 ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tthe two keynames specified by "
+ "\n\t\t\"-n %s\" and \"-r %s\" are identical."
+ "\n\t\tPlease provide two non-identical keynames.\n\n",
+ progName,
+ commandToRun,
+ keyname,
+ new_keyname );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+ /*****************************************************/
+ /* Retrieve a handle to the specified symmetric key. */
+ /* This insures that the specified symmetric key */
+ /* already resides on the specified token. */
+ /*****************************************************/
+
+ symmetricKey = TKS_RetrieveSymKey( slot,
+ keyname,
+ &pwdata );
+ if( symmetricKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tthe \"%s\" symmetric keyname specified by "
+ "\n\t\t\"-n %s\" does NOT exist on the specified "
+ "token.\n\t\tPlease specify a "
+ "different symmetric keyname.\n\n",
+ progName,
+ commandToRun,
+ keyname,
+ keyname );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /**********************************************************/
+ /* Do not allow the renamed key to overwrite a */
+ /* preexisting key of the same name */
+ /* */
+ /* NOTE: The following code snippet effectively */
+ /* prohibits this tool from renaming any */
+ /* symmetric key with a keyname that already */
+ /* resides in the specified token */
+ /**********************************************************/
+
+ rvFindSymKey = TKS_FindSymKey( slot,
+ new_keyname,
+ &pwdata );
+ if( rvFindSymKey == SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tthe \"%s\" keyname specified by "
+ "\n\t\t\"-r %s\"\n\t\talready exists in the "
+ "specified token.\n\t\tPlease specify a "
+ "different keyname for renaming purposes.\n\n",
+ progName,
+ commandToRun,
+ new_keyname,
+ new_keyname );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+#if defined(DEBUG)
+ /*****************************************************************/
+ /* For convenience, compute and display the symmetric key's KCV. */
+ /*****************************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Computing and displaying KCV of the symmetric key "
+ "on the specified token . . .\n\n" );
+
+ /* Calculate the symmetric key's KCV */
+ rvKCV = TKS_ComputeAndDisplayKCV( ( PRUint8 * ) NULL,
+ ( PRIntn ) 0,
+ ( PRUint8 * ) KCV,
+ ( PRIntn ) KCVLen,
+ symmetricKey,
+ keyname,
+ RESIDENT_KEY,
+ PR_TRUE,
+ NULL );
+ if( rvKCV != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Unable to compute/display KCV of "
+ "the symmetric key!\n\n" );
+ rv = SECFailure;
+ goto shutdown;
+ }
+#endif
+
+
+ /********************************************************************/
+ /* Finally, rename the symmetric key with the newly specified name. */
+ /********************************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Renaming the symmetric key named \"%s\" to \"%s\" . . .\n\n",
+ keyname,
+ new_keyname );
+
+ rvSymmetricKeyname = PK11_SetSymKeyNickname(
+ /* symmetric key */ symmetricKey,
+ /* nickname */ new_keyname );
+ if( rvSymmetricKeyname != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Failed to rename the symmetric key!\n\n" );
+ rv = SECFailure;
+ goto shutdown;
+ } else {
+ PR_fprintf( PR_STDOUT,
+ "Successfully renamed the symmetric key named \"%s\" "
+ "to \"%s\"!\n\n",
+ keyname,
+ new_keyname );
+ }
+
+
+#if defined(DEBUG)
+ /********************************************************/
+ /* For convenience, compute and display the renamed */
+ /* symmetric key's KCV. */
+ /********************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Computing and displaying KCV of the renamed symmetric key "
+ "on the specified token . . .\n\n" );
+
+ /* Calculate the renamed symmetric key's KCV */
+ rvKCV = TKS_ComputeAndDisplayKCV( ( PRUint8 * ) NULL,
+ ( PRIntn ) 0,
+ ( PRUint8 * ) KCV,
+ ( PRIntn ) KCVLen,
+ symmetricKey,
+ new_keyname,
+ RESIDENT_KEY,
+ PR_TRUE,
+ NULL );
+ if( rvKCV != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Unable to compute/display KCV of "
+ "the renamed symmetric key!\n\n" );
+ rv = SECFailure;
+ goto shutdown;
+ }
+#endif
+
+
+ /*********************************/
+ /* Cleanup and exit with success */
+ /*********************************/
+
+ rv = SECSuccess;
+ goto shutdown;
+ }
+
+
+ /**************************************************/
+ /* Execute the "-S" list security modules command */
+ /* */
+ /* NOTE: This command is mutually */
+ /* exclusive from all others. */
+ /**************************************************/
+
+ if( tkstool.commands[cmd_ListSecModules].activated ) {
+ rv = TKS_ListSecModules();
+ goto shutdown;
+ }
+
+
+ /**********************************************/
+ /* Execute the "-U" unwrap master key command */
+ /* */
+ /* NOTE: This command is mutually */
+ /* exclusive from all others. */
+ /**********************************************/
+
+ if( tkstool.commands[cmd_UnWrapMasterKey].activated ) {
+
+ /**********************************************************/
+ /* Do not allow duplicate symmetric keys to be stored */
+ /* (i. e. - disallow symmetric keys specified */
+ /* by the same keyname) */
+ /* */
+ /* NOTE: The following code snippet effectively */
+ /* prohibits this tool from storing any */
+ /* symmetric key with a keyname that already */
+ /* resides in the specified token */
+ /**********************************************************/
+
+ rvFindSymKey = TKS_FindSymKey( slot,
+ keyname,
+ &pwdata );
+ if( rvFindSymKey == SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tthe \"%s\" keyname specified by "
+ "\n\t\t\"-n %s\"\n\t\talready exists in the "
+ "specified token.\n\t\tPlease specify a "
+ "different keyname.\n\n",
+ progName,
+ commandToRun,
+ keyname,
+ keyname );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*******************************************************************/
+ /* Retrieve a handle to the specified unwrapping key. This insures */
+ /* that the specified unwrapping key (i. e. - transport key) */
+ /* already exists on the specified token. */
+ /* */
+ /* NOTE: Requiring that the transport key AND the master key */
+ /* reside on the same token is a FIPS 140-1 requirement! */
+ /*******************************************************************/
+
+ TKS_ClearScreen();
+
+ PR_fprintf( PR_STDOUT,
+ "\nRetrieving the transport key from the "
+ "specified token (for unwrapping) . . .\n\n" );
+
+ transportKey = TKS_RetrieveSymKey( slot,
+ transport_keyname,
+ &pwdata );
+ if( transportKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tthe \"%s\" transport keyname specified by "
+ "\"-t %s\"\n\t\tdoes NOT exist on the specified "
+ "token.\n\t\tPlease specify a "
+ "different transport keyname.\n\n",
+ progName,
+ commandToRun,
+ transport_keyname,
+ transport_keyname );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*****************************************************************/
+ /* Read in the wrapped master key from the specified input file. */
+ /*****************************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Reading in the wrapped data (and resident master key KCV) "
+ "from the file called\n\"%s\" . . .\n\n",
+ input );
+
+ /* Create a clean new storage buffer for this wrapped key */
+ wrappedMasterKey.len = WRAPPED_KEY_LENGTH;
+ wrappedMasterKey.data = ( unsigned char * )
+ PORT_ZAlloc( WRAPPED_KEY_LENGTH );
+
+ /* Create a clean new hex storage buffer for this master key's KCV */
+ hexInternalKeyKCV.type = ( SECItemType ) siBuffer;
+ hexInternalKeyKCV.len = ( HEX_WRAPPED_KEY_KCV_LENGTH + 1 );
+ hexInternalKeyKCV.data = ( unsigned char * )
+ PORT_ZAlloc( hexInternalKeyKCV.len );
+ if( hexInternalKeyKCV.data == NULL ) {
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+ rvWrappedMasterKey = TKS_ReadInputFileIntoSECItem( input,
+ ( char * ) hexInternalKeyKCV.data,
+ hexInternalKeyKCV.len,
+ keyname,
+ &wrappedMasterKey );
+ if( rvWrappedMasterKey != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tunable to read in wrapped master key "
+ "from file called \"%s\".\n",
+ progName,
+ commandToRun,
+ input );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*************************************************************/
+ /* Temporarily unwrap the master key to check its KCV value. */
+ /*************************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Using the transport key to temporarily unwrap "
+ "the master key to recompute\nits KCV value to "
+ "check against its pre-computed KCV value . . .\n\n" );
+
+ temporaryMasterKey = PK11_UnwrapSymKeyWithFlagsPerm(
+ /* wrapping key */ transportKey,
+ /* wraptype */ CKM_DES3_ECB,
+ /* param */ 0,
+ /* wrapped key */ &wrappedMasterKey,
+ /* target */ CKM_DES3_ECB,
+ /* operation */ CKA_ENCRYPT,
+ /* target key length */ WRAPPED_KEY_LENGTH,
+ /* flags */ 0,
+ /* isPerm */ PR_FALSE );
+ if( temporaryMasterKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to temporarily unwrap the master key ",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+ /* verify that the wrapped key and KCV read in from */
+ /* the input file correspond to each other . . . */
+ rvKCV = TKS_ComputeAndDisplayKCV( ( PRUint8 * ) NULL,
+ ( PRIntn ) 0,
+ ( PRUint8 * ) KCV,
+ ( PRIntn ) KCVLen,
+ temporaryMasterKey,
+ keyname,
+ UNWRAPPED_KEY,
+ PR_FALSE,
+ hexInternalKeyKCV.data );
+ if( rvKCV != SECSuccess ) {
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /***************************************************************/
+ /* Unwrap the master key and store it on the designated token. */
+ /***************************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Using the transport key to unwrap and store "
+ "the master key\non the specified token . . .\n\n" );
+
+ masterKey = PK11_UnwrapSymKeyWithFlagsPerm(
+ /* wrapping key */ transportKey,
+ /* wraptype */ CKM_DES3_ECB,
+ /* param */ 0,
+ /* wrapped key */ &wrappedMasterKey,
+ /* target */ CKM_DES3_ECB,
+ /* operation */ CKA_ENCRYPT,
+ /* target key length */ WRAPPED_KEY_LENGTH,
+ /* flags */ 0,
+ /* isPerm */ PR_TRUE );
+ if( masterKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to unwrap/store the master key ",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*****************************************************************/
+ /* Finally, name the master key with the specified name. */
+ /*****************************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Naming the master key \"%s\" . . .\n\n",
+ keyname );
+
+ rvMasterKeyname = PK11_SetSymKeyNickname(
+ /* symmetric key */ masterKey,
+ /* nickname */ keyname );
+ if( rvMasterKeyname != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Failed to name the master key!\n\n" );
+ rv = SECFailure;
+ goto shutdown;
+ } else {
+ PR_fprintf( PR_STDOUT,
+ "Successfully unwrapped, stored, and named the "
+ "master key!\n\n" );
+ }
+
+
+ /*********************************/
+ /* Cleanup and exit with success */
+ /*********************************/
+
+ rv = SECSuccess;
+ goto shutdown;
+ }
+
+
+ /******************************************************/
+ /* Execute the "-W" wrap generated master key command */
+ /* */
+ /* NOTE: This command is mutually */
+ /* exclusive from all others. */
+ /******************************************************/
+
+ if( tkstool.commands[cmd_WrapMasterKey].activated ) {
+
+ /**********************************************************/
+ /* Do not allow duplicate symmetric keys to be stored */
+ /* (i. e. - disallow symmetric keys specified */
+ /* by the same keyname) */
+ /* */
+ /* NOTE: The following code snippet effectively */
+ /* prohibits this tool from storing any */
+ /* symmetric key with a keyname that already */
+ /* resides in the specified token */
+ /**********************************************************/
+
+ rvFindSymKey = TKS_FindSymKey( slot,
+ keyname,
+ &pwdata );
+ if( rvFindSymKey == SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tthe \"%s\" keyname specified by "
+ "\n\t\t\"-n %s\"\n\t\talready exists in the "
+ "specified token.\n\t\tPlease specify a "
+ "different keyname.\n\n",
+ progName,
+ commandToRun,
+ keyname,
+ keyname );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*****************************************************************/
+ /* Retrieve a handle to the specified wrapping key. This insures */
+ /* that the specified wrapping key (i. e. - transport key) */
+ /* already exists on the specified token. */
+ /* */
+ /* NOTE: Requiring that the transport key AND the master key */
+ /* reside on the same token is a FIPS 140-1 requirement! */
+ /*****************************************************************/
+
+ TKS_ClearScreen();
+
+ PR_fprintf( PR_STDOUT,
+ "\nRetrieving the transport key (for wrapping) "
+ "from the specified token . . .\n\n" );
+
+ transportKey = TKS_RetrieveSymKey( slot,
+ transport_keyname,
+ &pwdata );
+ if( transportKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c:\tthe \"%s\" transport keyname specified by "
+ "\"-t %s\"\n\t\tdoes NOT exist on the specified "
+ "token.\n\t\tPlease specify a "
+ "different transport keyname.\n\n",
+ progName,
+ commandToRun,
+ transport_keyname,
+ transport_keyname );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*****************************************************************/
+ /* Generate the master key and store it on the designated token. */
+ /*****************************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Generating and storing the master key "
+ "on the specified token . . .\n\n" );
+
+ if( WRAPPED_KEY_LENGTH == ( 2 * DES_LENGTH ) ) {
+ masterKey = PK11_TokenKeyGen(
+ /* slot */ slot,
+ /* mechanism */ CKM_DES2_KEY_GEN,
+ /* param */ 0,
+ /* keySize */ 0,
+ /* keyid */ 0,
+ /* isToken (i. e. - isPerm) */ PR_TRUE,
+ /* wincx */ &pwdata );
+ if( masterKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to generate/store this DES2 master key ",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+ } else if( WRAPPED_KEY_LENGTH == ( 3 * DES_LENGTH ) ) {
+ masterKey = PK11_TokenKeyGen(
+ /* slot */ slot,
+ /* mechanism */ CKM_DES3_KEY_GEN,
+ /* param */ 0,
+ /* keySize */ 0,
+ /* keyid */ 0,
+ /* isToken (i. e. - isPerm) */ PR_TRUE,
+ /* wincx */ &pwdata );
+ if( masterKey == NULL ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to generate/store this DES3 master key ",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+ } else {
+ /* invalid key size */
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s\n\n\n",
+ progName,
+ commandToRun,
+ "WRAPPED_KEY_LENGTH must be DES2 or DES3 length!" );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /************************************************/
+ /* Name the master key with the specified name. */
+ /************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Naming the master key \"%s\" . . .\n\n",
+ keyname );
+
+ rvMasterKeyname = PK11_SetSymKeyNickname(
+ /* symmetric key */ masterKey,
+ /* nickname */ keyname );
+ if( rvMasterKeyname != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "ERROR: Failed to name the master key!\n\n" );
+ rv = SECFailure;
+ goto shutdown;
+ } else {
+ PR_fprintf( PR_STDOUT,
+ "Successfully generated, stored, and named the "
+ "master key!\n\n" );
+ }
+
+
+ /**********************************/
+ /* Compute this master key's KCV. */
+ /**********************************/
+
+ /* Create a clean new hex storage buffer for this master key's KCV */
+ hexInternalKeyKCV.type = ( SECItemType ) siBuffer;
+ hexInternalKeyKCV.len = ( HEX_WRAPPED_KEY_KCV_LENGTH + 1 );
+ hexInternalKeyKCV.data = ( unsigned char * )
+ PORT_ZAlloc( hexInternalKeyKCV.len );
+ if( hexInternalKeyKCV.data == NULL ) {
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+ /* Calculate this master key's KCV */
+ rvKCV = TKS_ComputeAndDisplayKCV( ( PRUint8 * ) NULL,
+ ( PRIntn ) 0,
+ ( PRUint8 * ) KCV,
+ ( PRIntn ) KCVLen,
+ masterKey,
+ keyname,
+ WRAPPED_KEY,
+ PR_FALSE,
+ hexInternalKeyKCV.data );
+ if( rvKCV != SECSuccess ) {
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /****************************************/
+ /* Wrap the newly generated master key. */
+ /****************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Using the transport key to wrap and store "
+ "the master key . . .\n\n" );
+
+ wrappedMasterKey.len = WRAPPED_KEY_LENGTH;
+ wrappedMasterKey.data = ( unsigned char * )
+ PORT_ZAlloc( WRAPPED_KEY_LENGTH );
+
+ rvWrappedMasterKey = PK11_WrapSymKey(
+ /* mechanism type */ CKM_DES3_ECB,
+ /* param */ 0,
+ /* wrapping key */ transportKey,
+ /* key to be wrapped */ masterKey,
+ /* wrapped key */ &wrappedMasterKey );
+ if( rvWrappedMasterKey != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to wrap the master key ",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /**************************************************************/
+ /* Write the wrapped master key to the specified output file. */
+ /**************************************************************/
+
+ PR_fprintf( PR_STDOUT,
+ "Writing the wrapped data (and resident master key KCV) "
+ "into the file called\n\"%s\" . . .\n\n",
+ output );
+
+ rvSaveWrappedMasterKey = TKS_WriteSECItemIntoOutputFile( &wrappedMasterKey,
+ keyname,
+ ( char * ) hexInternalKeyKCV.data,
+ ( hexInternalKeyKCV.len - 1 ),
+ output );
+ if( rvSaveWrappedMasterKey != SECSuccess ) {
+ PR_fprintf( PR_STDERR,
+ "%s -%c: %s:%d\n",
+ progName,
+ commandToRun,
+ "unable to save the wrapped master key ",
+ PR_GetError() );
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
+ /*********************************/
+ /* Cleanup and exit with success */
+ /*********************************/
+
+ rv = SECSuccess;
+ goto shutdown;
+ }
+
+
+shutdown:
+ /* free internal slot */
+ if( slot ) {
+ PK11_FreeSlot( /* slot */ internalSlot );
+ }
+
+
+ /* free slot */
+ if( slot ) {
+ PK11_FreeSlot( /* slot */ slot );
+ }
+
+
+ /* destroy the pwdata */
+ if( pwdata.data != NULL ) {
+ pwdata.source = PW_NONE;
+ i = 0;
+ do {
+ if( pwdata.data[i] != 0 ) {
+ pwdata.data[i] = 0;
+ i++;
+ } else {
+ status = PR_TRUE;
+ }
+ } while( status == PR_FALSE );
+ }
+
+
+ /* destroy the first session key share */
+ if( firstSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ firstSessionKeyShare.data,
+ firstSessionKeyShare.len );
+ firstSessionKeyShare.data = NULL;
+ firstSessionKeyShare.len = 0;
+ }
+
+
+#if defined(PAD_DES2_KEY_LENGTH)
+ /* destroy the first padded session key share */
+ if( paddedFirstSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ paddedFirstSessionKeyShare.data,
+ paddedFirstSessionKeyShare.len );
+ paddedFirstSessionKeyShare.data = NULL;
+ paddedFirstSessionKeyShare.len = 0;
+ }
+#endif
+
+
+ /* destroy the "original" second session key share */
+ if( secondDerivationData.pData != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ secondDerivationData.pData,
+ secondDerivationData.ulLen );
+ secondDerivationData.pData = NULL;
+ secondDerivationData.ulLen = 0;
+ }
+
+
+#if defined(PAD_DES2_KEY_LENGTH)
+ /* destroy the second padded session key share */
+ if( paddedSecondSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ paddedSecondSessionKeyShare.data,
+ paddedSecondSessionKeyShare.len );
+ paddedSecondSessionKeyShare.data = NULL;
+ paddedSecondSessionKeyShare.len = 0;
+ }
+#endif
+
+
+ /* destroy the second session key share container */
+ if( secondSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ secondSessionKeyShare.data,
+ secondSessionKeyShare.len );
+ secondSessionKeyShare.data = NULL;
+ secondSessionKeyShare.len = 0;
+ }
+
+
+ /* destroy the "original" third session key share */
+ if( thirdDerivationData.pData != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ thirdDerivationData.pData,
+ thirdDerivationData.ulLen );
+ thirdDerivationData.pData = NULL;
+ thirdDerivationData.ulLen = 0;
+ }
+
+
+#if defined(PAD_DES2_KEY_LENGTH)
+ /* destroy the third padded session key share */
+ if( paddedThirdSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ paddedThirdSessionKeyShare.data,
+ paddedThirdSessionKeyShare.len );
+ paddedThirdSessionKeyShare.data = NULL;
+ paddedThirdSessionKeyShare.len = 0;
+ }
+#endif
+
+
+ /* destroy the third session key share container */
+ if( thirdSessionKeyShare.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ thirdSessionKeyShare.data,
+ thirdSessionKeyShare.len );
+ thirdSessionKeyShare.data = NULL;
+ thirdSessionKeyShare.len = 0;
+ }
+
+
+ /* destroy the first symmetric key */
+ if( firstSymmetricKey ) {
+ PK11_FreeSymKey( /* symmetric key */ firstSymmetricKey );
+ }
+
+
+ /* destroy the second symmetric key */
+ if( secondSymmetricKey ) {
+ PK11_FreeSymKey( /* symmetric key */ secondSymmetricKey );
+ }
+
+
+ /* destroy the third symmetric key (transport key) */
+ if( thirdSymmetricKey ) {
+ PK11_FreeSymKey( /* symmetric key */ thirdSymmetricKey );
+ }
+
+
+ /* destroy the hexInternalKeyKCV */
+ if( hexInternalKeyKCV.data != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ hexInternalKeyKCV.data,
+ hexInternalKeyKCV.len );
+ hexInternalKeyKCV.data = NULL;
+ hexInternalKeyKCV.len = 0;
+ }
+
+
+ /* destroy the KCV */
+ if( KCV != NULL ) {
+ PORT_ZFree( ( unsigned char * )
+ KCV,
+ KCVLen );
+ KCV = NULL;
+ KCVLen = 0;
+ }
+
+
+ /* destroy the temporary master key */
+ if( temporaryMasterKey ) {
+ PK11_FreeSymKey( /* symmetric key */ temporaryMasterKey );
+ }
+
+
+ /* destroy the master key */
+ if( masterKey ) {
+ PK11_FreeSymKey( /* symmetric key */ masterKey );
+ }
+
+
+ /* destroy the transport key */
+ if( transportKey ) {
+ PK11_FreeSymKey( /* symmetric key */ transportKey );
+ }
+
+
+ /* shutdown NSS */
+ if( NSS_Shutdown() != SECSuccess ) {
+ return 255;
+ }
+
+
+ /* exit with an appropriate return value */
+ if( rv == SECSuccess ) {
+ return 0;
+ } else {
+ return 255;
+ }
+}
+
diff --git a/base/native-tools/src/tkstool/tkstool.h b/base/native-tools/src/tkstool/tkstool.h
new file mode 100644
index 000000000..3b0407227
--- /dev/null
+++ b/base/native-tools/src/tkstool/tkstool.h
@@ -0,0 +1,321 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 ---
+ */
+
+/************************/
+/** #include headers **/
+/************************/
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <string.h>
+
+#if defined(WIN32)
+#include "fcntl.h"
+#include "io.h"
+#endif
+
+#if defined(XP_UNIX)
+#include <unistd.h>
+#include <sys/time.h>
+#include <termios.h>
+#endif
+
+#if defined(XP_WIN) || defined (XP_PC)
+#include <time.h>
+#include <conio.h>
+#endif
+
+#include "secutil.h"
+#include "nspr.h"
+#include "prtypes.h"
+#include "prtime.h"
+#include "prlong.h"
+#include "pk11func.h"
+#include "secasn1.h"
+#include "cert.h"
+#include "cryptohi.h"
+#include "secoid.h"
+#include "certdb.h"
+#include "nss.h"
+
+
+/****************/
+/** #defines **/
+/****************/
+
+#define TKSTOOL_MAJOR_VERSION_NUMBER 1
+#define TKSTOOL_MINOR_VERSION_NUMBER 0
+#define TKSTOOL_VERSION_SUFFIX ""
+
+#define DEFAULT_KEY_BITS 1024
+#define NUM_KEYSTROKES 120
+#define RAND_BUF_LENGTH 60
+#define DES_LENGTH 8
+#define KEYSTROKES_TO_PROCEED 8
+#define KCV_LENGTH 4
+#define CTRL_C 3
+
+#define FIRST_SESSION_KEY_SHARE "first"
+#define FIRST_SESSION_KEY_SHARE_LENGTH 16
+#define SECOND_SESSION_KEY_SHARE "second"
+#define SECOND_SESSION_KEY_SHARE_LENGTH 16
+#define THIRD_SESSION_KEY_SHARE "third"
+#define THIRD_SESSION_KEY_SHARE_LENGTH 16
+#define HEX_SESSION_KEY_BUF_LENGTH 32
+#define HEX_SESSION_KEY_KCV_BUF_LENGTH 8
+
+#define MASTER_KEY_LENGTH 16
+
+#define WRAPPED_KEY_LENGTH 16
+#define HEX_WRAPPED_KEY_LENGTH 32
+#define HEX_WRAPPED_KEY_KCV_LENGTH 8
+
+#if defined(PAD_DES2_KEY_LENGTH)
+#define PADDED_FIRST_SESSION_KEY_SHARE_LENGTH 24
+#define PADDED_SECOND_SESSION_KEY_SHARE_LENGTH 24
+#define PADDED_THIRD_SESSION_KEY_SHARE_LENGTH 24
+#endif
+
+#define FIRST_SYMMETRIC_KEY "first"
+#define SECOND_SYMMETRIC_KEY "second"
+#define THIRD_SYMMETRIC_KEY "third"
+#define MASTER_KEY "master"
+#define RESIDENT_KEY "resident"
+#define SESSION_KEY "session"
+#define SYMMETRIC_KEY "symmetric"
+#define TRANSPORT_KEY "transport"
+#define UNWRAPPED_KEY "unwrapped"
+#define WRAPPED_KEY "wrapped"
+
+#define CONTINUATION_MESSAGE "Press enter to continue " \
+ "(or ^C to break): "
+
+#define PROCEED_MESSAGE "Type the word \"proceed\" " \
+ "and press enter to continue " \
+ "(or ^C to break): "
+
+
+/**************************************/
+/** external function declarations **/
+/**************************************/
+
+#if defined(__sun) && !defined(SVR4)
+extern int fclose( FILE* );
+extern int fprintf( FILE *, char *, ... );
+extern int isatty( int );
+extern char *sys_errlist[];
+#define strerror( errno ) sys_errlist[errno]
+#endif
+
+
+/***************************/
+/** function prototypes **/
+/***************************/
+
+/************/
+/* delete.c */
+/************/
+
+SECStatus
+TKS_DeleteKeys( char *progName,
+ PK11SlotInfo *slot,
+ char *keyname,
+ secuPWData *pwdata );
+
+
+/**********/
+/* file.c */
+/**********/
+
+SECStatus
+TKS_ReadInputFileIntoSECItem( char *input,
+ char *hexInternalKeyKCV,
+ int hexInternalKeyKCVLength,
+ char *keyname,
+ SECItem *wrappedKey );
+
+SECStatus
+TKS_WriteSECItemIntoOutputFile( SECItem *wrappedKey,
+ char *keyname,
+ char *hexInternalKeyKCV,
+ int hexInternalKeyKCVLength,
+ char *output );
+
+
+/**********/
+/* find.c */
+/**********/
+
+SECStatus
+TKS_FindSymKey( PK11SlotInfo *slot,
+ char *keyname,
+ void *pwdata );
+
+
+/**********/
+/* help.c */
+/**********/
+
+void
+TKS_Usage( char *progName );
+
+void
+TKS_PrintHelp( char *progName );
+
+
+/*********/
+/* key.c */
+/*********/
+
+SECStatus
+TKS_ComputeAndDisplayKCV( PRUint8 *newKey,
+ PRIntn newKeyLen,
+ PRUint8 *KCV,
+ PRIntn KCVLen,
+ PK11SymKey *symKey,
+ char *keyName,
+ char *keyType,
+ PRBool displayKCV,
+ PRUint8 *expectedHexKCV );
+
+SECStatus
+TKS_GenerateSessionKeyShare( char *sessionKeyShareName,
+ SECItem *sessionKeyShare );
+
+SECStatus
+TKS_InputSessionKeyShare( char *sessionKeyShareName,
+ SECItem *sessionKeyShare );
+
+PK11SymKey *
+TKS_ImportSymmetricKey( char *symmetricKeyName,
+ PK11SlotInfo *slot,
+ CK_MECHANISM_TYPE mechanism,
+ CK_ATTRIBUTE_TYPE operation,
+ SECItem *sessionKeyShare,
+ secuPWData *pwdata );
+
+PK11SymKey *
+TKS_DeriveSymmetricKey( char *symmetricKeyName,
+ PK11SymKey *symKey,
+ CK_MECHANISM_TYPE derive,
+ SECItem *sessionKeyShare,
+ CK_MECHANISM_TYPE target,
+ CK_ATTRIBUTE_TYPE operation,
+ int keysize );
+
+SECStatus
+TKS_StoreSymmetricKeyAndNameIt( char *symmetricKeyName,
+ char *keyname,
+ PK11SlotInfo *slot,
+ CK_ATTRIBUTE_TYPE operation,
+ CK_FLAGS flags,
+ PK11SymKey *symKey );
+
+
+/**********/
+/* list.c */
+/**********/
+
+SECStatus
+TKS_ListKeys( char *progName,
+ PK11SlotInfo *slot,
+ char *keyname,
+ int index,
+ PRBool dopriv,
+ secuPWData *pwdata );
+
+
+/*************/
+/* modules.c */
+/*************/
+
+SECStatus
+TKS_ListSecModules( void );
+
+
+/************/
+/* random.c */
+/************/
+
+void
+TKS_FileForRNG( char *noise );
+
+SECStatus
+TKS_SeedRNG( char *noise );
+
+
+/**************/
+/* retrieve.c */
+/**************/
+
+PK11SymKey *
+TKS_RetrieveSymKey( PK11SlotInfo *slot,
+ char *keyname,
+ void *pwdata );
+
+
+/**********/
+/* util.c */
+/**********/
+
+PR_IMPLEMENT( void )
+TKS_ClearScreen();
+
+PR_IMPLEMENT( void )
+TKS_WaitForUser();
+
+PR_IMPLEMENT( void )
+TKS_TypeProceedToContinue();
+
+PR_IMPLEMENT( void )
+TKS_AdjustOddParity( PRUint8 *key );
+
+PR_IMPLEMENT( void )
+TKS_StringToHex( PRUint8 *key,
+ PRIntn len,
+ PRUint8 *hex_key,
+ PRIntn hex_len );
+
+PR_IMPLEMENT( PRBool )
+TKS_ConvertStringOfHexCharactersIntoBitStream( char* input,
+ PRIntn input_bytes,
+ PRUint8* output );
+
+
+/*************/
+/* version.c */
+/*************/
+
+void
+TKS_Version( char *progName );
+
diff --git a/base/native-tools/src/tkstool/util.c b/base/native-tools/src/tkstool/util.c
new file mode 100644
index 000000000..5fda75f8e
--- /dev/null
+++ b/base/native-tools/src/tkstool/util.c
@@ -0,0 +1,640 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 ---
+ */
+
+#include "tkstool.h"
+
+static PRBool
+IsValidHexCharacter( char byte )
+{
+ switch( byte )
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case 'a':
+ case 'A':
+ case 'b':
+ case 'B':
+ case 'c':
+ case 'C':
+ case 'd':
+ case 'D':
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ {
+ /* Character may be converted into a hexadecimal number. */
+ return PR_TRUE;
+ }
+ default:
+ {
+ return PR_FALSE;
+ }
+ }
+}
+
+
+static void
+InsertUpperFourBits( char* byte, char bits )
+{
+ switch( bits )
+ {
+ case '0':
+ {
+ *byte &= ~( 1 << 7 );
+ *byte &= ~( 1 << 6 );
+ *byte &= ~( 1 << 5 );
+ *byte &= ~( 1 << 4 );
+ break;
+ }
+ case '1':
+ {
+ *byte &= ~( 1 << 7 );
+ *byte &= ~( 1 << 6 );
+ *byte &= ~( 1 << 5 );
+ *byte |= ( 1 << 4 );
+ break;
+ }
+ case '2':
+ {
+ *byte &= ~( 1 << 7 );
+ *byte &= ~( 1 << 6 );
+ *byte |= ( 1 << 5 );
+ *byte &= ~( 1 << 4 );
+ break;
+ }
+ case '3':
+ {
+ *byte &= ~( 1 << 7 );
+ *byte &= ~( 1 << 6 );
+ *byte |= ( 1 << 5 );
+ *byte |= ( 1 << 4 );
+ break;
+ }
+ case '4':
+ {
+ *byte &= ~( 1 << 7 );
+ *byte |= ( 1 << 6 );
+ *byte &= ~( 1 << 5 );
+ *byte &= ~( 1 << 4 );
+ break;
+ }
+ case '5':
+ {
+ *byte &= ~( 1 << 7 );
+ *byte |= ( 1 << 6 );
+ *byte &= ~( 1 << 5 );
+ *byte |= ( 1 << 4 );
+ break;
+ }
+ case '6':
+ {
+ *byte &= ~( 1 << 7 );
+ *byte |= ( 1 << 6 );
+ *byte |= ( 1 << 5 );
+ *byte &= ~( 1 << 4 );
+ break;
+ }
+ case '7':
+ {
+ *byte &= ~( 1 << 7 );
+ *byte |= ( 1 << 6 );
+ *byte |= ( 1 << 5 );
+ *byte |= ( 1 << 4 );
+ break;
+ }
+ case '8':
+ {
+ *byte |= ( 1 << 7 );
+ *byte &= ~( 1 << 6 );
+ *byte &= ~( 1 << 5 );
+ *byte &= ~( 1 << 4 );
+ break;
+ }
+ case '9':
+ {
+ *byte |= ( 1 << 7 );
+ *byte &= ~( 1 << 6 );
+ *byte &= ~( 1 << 5 );
+ *byte |= ( 1 << 4 );
+ break;
+ }
+ case 'a':
+ case 'A':
+ {
+ *byte |= ( 1 << 7 );
+ *byte &= ~( 1 << 6 );
+ *byte |= ( 1 << 5 );
+ *byte &= ~( 1 << 4 );
+ break;
+ }
+ case 'b':
+ case 'B':
+ {
+ *byte |= ( 1 << 7 );
+ *byte &= ~( 1 << 6 );
+ *byte |= ( 1 << 5 );
+ *byte |= ( 1 << 4 );
+ break;
+ }
+ case 'c':
+ case 'C':
+ {
+ *byte |= ( 1 << 7 );
+ *byte |= ( 1 << 6 );
+ *byte &= ~( 1 << 5 );
+ *byte &= ~( 1 << 4 );
+ break;
+ }
+ case 'd':
+ case 'D':
+ {
+ *byte |= ( 1 << 7 );
+ *byte |= ( 1 << 6 );
+ *byte &= ~( 1 << 5 );
+ *byte |= ( 1 << 4 );
+ break;
+ }
+ case 'e':
+ case 'E':
+ {
+ *byte |= ( 1 << 7 );
+ *byte |= ( 1 << 6 );
+ *byte |= ( 1 << 5 );
+ *byte &= ~( 1 << 4 );
+ break;
+ }
+ case 'f':
+ case 'F':
+ {
+ *byte |= ( 1 << 7 );
+ *byte |= ( 1 << 6 );
+ *byte |= ( 1 << 5 );
+ *byte |= ( 1 << 4 );
+ break;
+ }
+ }
+}
+
+
+static void
+InsertLowerFourBits( char* byte, char bits )
+{
+ switch( bits )
+ {
+ case '0':
+ {
+ *byte &= ~( 1 << 3 );
+ *byte &= ~( 1 << 2 );
+ *byte &= ~( 1 << 1 );
+ *byte &= ~( 1 << 0 );
+ break;
+ }
+ case '1':
+ {
+ *byte &= ~( 1 << 3 );
+ *byte &= ~( 1 << 2 );
+ *byte &= ~( 1 << 1 );
+ *byte |= ( 1 << 0 );
+ break;
+ }
+ case '2':
+ {
+ *byte &= ~( 1 << 3 );
+ *byte &= ~( 1 << 2 );
+ *byte |= ( 1 << 1 );
+ *byte &= ~( 1 << 0 );
+ break;
+ }
+ case '3':
+ {
+ *byte &= ~( 1 << 3 );
+ *byte &= ~( 1 << 2 );
+ *byte |= ( 1 << 1 );
+ *byte |= ( 1 << 0 );
+ break;
+ }
+ case '4':
+ {
+ *byte &= ~( 1 << 3 );
+ *byte |= ( 1 << 2 );
+ *byte &= ~( 1 << 1 );
+ *byte &= ~( 1 << 0 );
+ break;
+ }
+ case '5':
+ {
+ *byte &= ~( 1 << 3 );
+ *byte |= ( 1 << 2 );
+ *byte &= ~( 1 << 1 );
+ *byte |= ( 1 << 0 );
+ break;
+ }
+ case '6':
+ {
+ *byte &= ~( 1 << 3 );
+ *byte |= ( 1 << 2 );
+ *byte |= ( 1 << 1 );
+ *byte &= ~( 1 << 0 );
+ break;
+ }
+ case '7':
+ {
+ *byte &= ~( 1 << 3 );
+ *byte |= ( 1 << 2 );
+ *byte |= ( 1 << 1 );
+ *byte |= ( 1 << 0 );
+ break;
+ }
+ case '8':
+ {
+ *byte |= ( 1 << 3 );
+ *byte &= ~( 1 << 2 );
+ *byte &= ~( 1 << 1 );
+ *byte &= ~( 1 << 0 );
+ break;
+ }
+ case '9':
+ {
+ *byte |= ( 1 << 3 );
+ *byte &= ~( 1 << 2 );
+ *byte &= ~( 1 << 1 );
+ *byte |= ( 1 << 0 );
+ break;
+ }
+ case 'a':
+ case 'A':
+ {
+ *byte |= ( 1 << 3 );
+ *byte &= ~( 1 << 2 );
+ *byte |= ( 1 << 1 );
+ *byte &= ~( 1 << 0 );
+ break;
+ }
+ case 'b':
+ case 'B':
+ {
+ *byte |= ( 1 << 3 );
+ *byte &= ~( 1 << 2 );
+ *byte |= ( 1 << 1 );
+ *byte |= ( 1 << 0 );
+ break;
+ }
+ case 'c':
+ case 'C':
+ {
+ *byte |= ( 1 << 3 );
+ *byte |= ( 1 << 2 );
+ *byte &= ~( 1 << 1 );
+ *byte &= ~( 1 << 0 );
+ break;
+ }
+ case 'd':
+ case 'D':
+ {
+ *byte |= ( 1 << 3 );
+ *byte |= ( 1 << 2 );
+ *byte &= ~( 1 << 1 );
+ *byte |= ( 1 << 0 );
+ break;
+ }
+ case 'e':
+ case 'E':
+ {
+ *byte |= ( 1 << 3 );
+ *byte |= ( 1 << 2 );
+ *byte |= ( 1 << 1 );
+ *byte &= ~( 1 << 0 );
+ break;
+ }
+ case 'f':
+ case 'F':
+ {
+ *byte |= ( 1 << 3 );
+ *byte |= ( 1 << 2 );
+ *byte |= ( 1 << 1 );
+ *byte |= ( 1 << 0 );
+ break;
+ }
+ }
+}
+
+
+PR_IMPLEMENT( void )
+TKS_ClearScreen()
+{
+#if defined(XP_UNIX) && !defined(VMS)
+ system( "tput clear" );
+#else
+ system( "cls" );
+#endif
+}
+
+
+PR_IMPLEMENT( void )
+TKS_WaitForUser()
+{
+ int c;
+
+ PR_fprintf( PR_STDOUT, "\n\n" );
+ PR_fprintf( PR_STDOUT, "%s", CONTINUATION_MESSAGE );
+#if defined(VMS)
+ while((c = GENERIC_GETCHAR_NO_ECHO()) != '\r' && c != EOF && c != CTRL_C )
+ ;
+#else
+ while ((c = getc(stdin)) != '\n' && c != EOF && c != CTRL_C )
+ ;
+#endif
+ PR_fprintf( PR_STDOUT, "\n" );
+}
+
+
+PR_IMPLEMENT( void )
+TKS_TypeProceedToContinue()
+{
+ int fd;
+ int i;
+ int count;
+ int c;
+ int rv = 0;
+#ifdef XP_UNIX
+ cc_t orig_cc_min;
+ cc_t orig_cc_time;
+ tcflag_t orig_lflag;
+ struct termios tio;
+#endif
+ char keystrokes[KEYSTROKES_TO_PROCEED + 1] = "\0\0\0\0\0\0\0\0\0";
+
+ /* display the continuation message */
+ PR_fprintf( PR_STDOUT, "\n\n" );
+ PR_fprintf( PR_STDOUT, "%s", PROCEED_MESSAGE );
+
+ /* turn off echo on stdin & return on 1 char instead of NL */
+ fd = fileno( stdin );
+
+#if defined( XP_UNIX ) && !defined( VMS )
+ tcgetattr( fd, &tio );
+ orig_lflag = tio.c_lflag;
+ orig_cc_min = tio.c_cc[VMIN];
+ orig_cc_time = tio.c_cc[VTIME];
+ tio.c_lflag &= ~ECHO;
+ tio.c_lflag &= ~ICANON;
+ tio.c_cc[VMIN] = 1;
+ tio.c_cc[VTIME] = 0;
+ tcsetattr( fd, TCSAFLUSH, &tio );
+#endif
+
+ /* Get user input from keyboard strokes */
+ count = 0;
+ while( count < KEYSTROKES_TO_PROCEED ) {
+#ifdef VMS
+ c = GENERIC_GETCHAR_NOECHO();
+#elif XP_UNIX
+ c = getc( stdin );
+#else
+ c = getch();
+#endif
+ /* break on EOF */
+ if( c == EOF ) {
+ rv = -1;
+ break;
+ }
+
+ /* break on ^C */
+ if( c == CTRL_C ) {
+ rv = -1;
+ break;
+ }
+
+ /* save acceptable characters; silently throw anything else away */
+ switch( count ) {
+ case 0:
+ switch( c ) {
+ case 'P':
+ case 'p':
+ /* acceptable character; save lowercase version */
+ keystrokes[count] = 'p';
+ break;
+ default:
+ /* unacceptable character; don't save it */
+ continue;
+ }
+ break;
+ case 1:
+ switch( c ) {
+ case 'R':
+ case 'r':
+ /* acceptable character; save lowercase version */
+ keystrokes[count] = 'r';
+ break;
+ default:
+ /* unacceptable character; don't save it */
+ continue;
+ }
+ break;
+ case 2:
+ switch( c ) {
+ case 'O':
+ case 'o':
+ /* acceptable character; save lowercase version */
+ keystrokes[count] = 'o';
+ break;
+ default:
+ /* unacceptable character; don't save it */
+ continue;
+ }
+ break;
+ case 3:
+ switch( c ) {
+ case 'C':
+ case 'c':
+ /* acceptable character; save lowercase version */
+ keystrokes[count] = 'c';
+ break;
+ default:
+ /* unacceptable character; don't save it */
+ continue;
+ }
+ break;
+ case 4:
+ switch( c ) {
+ case 'E':
+ case 'e':
+ /* acceptable character; save lowercase version */
+ keystrokes[count] = 'e';
+ break;
+ default:
+ /* unacceptable character; don't save it */
+ continue;
+ }
+ break;
+ case 5:
+ switch( c ) {
+ case 'E':
+ case 'e':
+ /* acceptable character; save lowercase version */
+ keystrokes[count] = 'e';
+ break;
+ default:
+ /* unacceptable character; don't save it */
+ continue;
+ }
+ break;
+ case 6:
+ switch( c ) {
+ case 'D':
+ case 'd':
+ /* acceptable character; save lowercase version */
+ keystrokes[count] = 'd';
+ break;
+ default:
+ /* unacceptable character; don't save it */
+ continue;
+ }
+ break;
+ case 7:
+ switch( c ) {
+ case '\n':
+ case '\r':
+ /* acceptable character; save lowercase version */
+ keystrokes[count] = '\n';
+ break;
+ default:
+ /* unacceptable character; don't save it */
+ continue;
+ }
+ break;
+ default:
+ /* unacceptable character; don't save it */
+ continue;
+ }
+
+ /* adjust the character count appropriately */
+ count++;
+
+ /* redisplay the message */
+ PR_fprintf( PR_STDOUT, "\r%s", PROCEED_MESSAGE );
+
+ /* display the characters input so far */
+ for( i = 0 ; i < count ; i++ ) {
+ PR_fprintf( PR_STDOUT,
+ "%c",
+ keystrokes[i] );
+ }
+ }
+}
+
+
+PR_IMPLEMENT( void )
+TKS_AdjustOddParity( PRUint8 *key )
+{
+ PRIntn i;
+ PRIntn j;
+ PRIntn one;
+
+ /* this must be performed for each DES-sized (8-byte) chunk */
+ for( j = 0 ; j < DES_LENGTH ; j++ ) {
+ for( one = 0, i = key[j] ; i ; i >>= 1 ) {
+ if( i & 1 ) {
+ one++;
+ }
+ }
+
+ key[j] ^= !( one & 1 );
+ }
+}
+
+
+PR_IMPLEMENT( void )
+TKS_StringToHex( PRUint8 *key,
+ PRIntn len,
+ PRUint8 *hex_key,
+ PRIntn hex_len )
+{
+ PRIntn i;
+
+ for( i = 0 ; i < len ; i++ ) {
+ ( void ) PR_snprintf( ( char * ) &( hex_key[ ( 2 * i ) ] ),
+ hex_len,
+ "%X",
+ ( key[i] >> 4 ) & 0x0F );
+ ( void ) PR_snprintf( ( char * ) &( hex_key[ ( 2 * i ) + 1 ] ),
+ hex_len,
+ "%X",
+ key[i] & 0x0F );
+ }
+
+ hex_key[ ( hex_len - 1 ) ] = '\0';
+
+ return;
+}
+
+
+/* Convert a signed character string such as "de43a58f. . ." into an */
+/* unsigned character string which is one/half the size of the input */
+PR_IMPLEMENT( PRBool )
+TKS_ConvertStringOfHexCharactersIntoBitStream( char* input,
+ PRIntn input_bytes,
+ PRUint8* output )
+{
+ PRIntn i;
+ PRIntn output_bytes;
+
+ /* Check to be sure that the input string contains an */
+ /* "even" number of bytes so that it may be converted. */
+ if( input_bytes % 2 ) {
+ ( void ) PR_fprintf( PR_STDERR,
+ "ERROR: "
+ "ConvertStringOfHexCharactersIntoBitStream() "
+ "contained an illegal "
+ "input byte length of %d bytes!\r\n",
+ input_bytes );
+ return PR_FALSE;
+ }
+
+ output_bytes = ( input_bytes / 2 );
+
+ for( i = 0; i < output_bytes; i++ ) {
+ if( IsValidHexCharacter( input[ ( 2 * i ) ] ) &&
+ IsValidHexCharacter( input[ ( 2 * i ) + 1 ] ) ) {
+ InsertUpperFourBits( ( char* ) &( output[i] ), input[ ( 2 * i ) ] );
+ InsertLowerFourBits( ( char* ) &( output[i] ), input[ ( 2 * i ) + 1 ] );
+ } else {
+ ( void ) PR_fprintf( PR_STDERR,
+ "ERROR: "
+ "ConvertStringOfHexCharactersIntoBitStream() "
+ "contained a "
+ "byte in the input string which can not be "
+ "converted!\r\n" );
+ return PR_FALSE;
+ }
+ }
+
+ return PR_TRUE;
+}
+
+
diff --git a/base/native-tools/src/tkstool/version.c b/base/native-tools/src/tkstool/version.c
new file mode 100644
index 000000000..b8d4c5fbb
--- /dev/null
+++ b/base/native-tools/src/tkstool/version.c
@@ -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.
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#include "tkstool.h"
+
+void
+TKS_Version( char *progName )
+{
+#if defined(TKSTOOL_VERSION_SUFFIX)
+ if( TKSTOOL_VERSION_SUFFIX != NULL &&
+ PL_strcmp( TKSTOOL_VERSION_SUFFIX, "" ) != 0 ) {
+ PR_fprintf( PR_STDOUT,
+ "%s: Version %d.%d %s\n",
+ progName,
+ TKSTOOL_MAJOR_VERSION_NUMBER,
+ TKSTOOL_MINOR_VERSION_NUMBER,
+ TKSTOOL_VERSION_SUFFIX );
+ } else {
+ PR_fprintf( PR_STDOUT,
+ "%s: Version %d.%d\n",
+ progName,
+ TKSTOOL_MAJOR_VERSION_NUMBER,
+ TKSTOOL_MINOR_VERSION_NUMBER );
+ }
+#else
+ PR_fprintf( PR_STDOUT,
+ "%s: Version %d.%d\n",
+ progName,
+ TKSTOOL_MAJOR_VERSION_NUMBER,
+ TKSTOOL_MINOR_VERSION_NUMBER );
+#endif
+}
+
diff --git a/base/ocsp/CMakeLists.txt b/base/ocsp/CMakeLists.txt
new file mode 100644
index 000000000..c8e22ea1e
--- /dev/null
+++ b/base/ocsp/CMakeLists.txt
@@ -0,0 +1,65 @@
+project(ocsp Java)
+
+add_subdirectory(src)
+add_subdirectory(setup)
+add_subdirectory(shared/conf)
+
+# install systemd scripts
+install(
+ FILES
+ shared/lib/systemd/system/pki-ocspd.target
+ shared/lib/systemd/system/pki-ocspd@.service
+ DESTINATION
+ ${SYSTEMD_LIB_INSTALL_DIR}
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+# install init script
+install(
+ FILES
+ shared/etc/init.d/pki-ocspd
+ DESTINATION
+ ${SYSCONF_INSTALL_DIR}/rc.d/init.d
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+# install directories
+install(
+ DIRECTORY
+ shared/
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}
+ PATTERN
+ "CMakeLists.txt" EXCLUDE
+ PATTERN
+ "etc/*" EXCLUDE
+ PATTERN
+ "CS.cfg.in" EXCLUDE
+ PATTERN
+ "lib/*" EXCLUDE
+)
+
+# install empty directories
+install(
+ DIRECTORY
+ DESTINATION
+ ${VAR_INSTALL_DIR}/lock/pki/ocsp
+)
+
+install(
+ DIRECTORY
+ DESTINATION
+ ${VAR_INSTALL_DIR}/run/pki/ocsp
+)
+
+install(
+ DIRECTORY
+ DESTINATION
+ ${SYSTEMD_ETC_INSTALL_DIR}/pki-ocspd.target.wants
+)
diff --git a/base/ocsp/LICENSE b/base/ocsp/LICENSE
new file mode 100644
index 000000000..e281f4362
--- /dev/null
+++ b/base/ocsp/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/base/ocsp/setup/CMakeLists.txt b/base/ocsp/setup/CMakeLists.txt
new file mode 100644
index 000000000..f5f069cdb
--- /dev/null
+++ b/base/ocsp/setup/CMakeLists.txt
@@ -0,0 +1,8 @@
+set(VERSION ${APPLICATION_VERSION})
+
+install(
+ FILES
+ registry_instance
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/setup
+)
diff --git a/base/ocsp/setup/registry_instance b/base/ocsp/setup/registry_instance
new file mode 100644
index 000000000..3210b9131
--- /dev/null
+++ b/base/ocsp/setup/registry_instance
@@ -0,0 +1,63 @@
+# Establish PKI Variable "Slot" Substitutions
+
+PKI_FLAVOR=[PKI_FLAVOR]
+export PKI_FLAVOR
+
+PKI_SUBSYSTEM_TYPE=[PKI_SUBSYSTEM_TYPE]
+export PKI_SUBSYSTEM_TYPE
+
+PKI_USER=[PKI_USER]
+export PKI_USER
+
+PKI_GROUP=[PKI_GROUP]
+export PKI_GROUP
+
+PKI_INSTANCE_ID=[PKI_INSTANCE_ID]
+export PKI_INSTANCE_ID
+
+PKI_INSTANCE_PATH=[PKI_INSTANCE_PATH]
+export PKI_INSTANCE_PATH
+
+PKI_INSTANCE_INITSCRIPT=[PKI_INSTANCE_INITSCRIPT]
+export PKI_INSTANCE_INITSCRIPT
+
+PKI_SERVER_XML_CONF=[PKI_SERVER_XML_CONF]
+export PKI_SERVER_XML_CONF
+
+# Use CATALINA_BASE
+
+CATALINA_BASE=$PKI_INSTANCE_PATH
+export CATALINA_BASE
+
+TOMCAT_PROG=$PKI_INSTANCE_ID
+export TOMCAT_PROG
+
+TOMCAT_USER=$PKI_USER
+export TOMCAT_USER
+
+TOMCAT_GROUP=$PKI_GROUP
+export TOMCAT_GROUP
+
+PKI_LOCKDIR="/var/lock/${PKI_FLAVOR}/${PKI_SUBSYSTEM_TYPE}"
+export PKI_LOCKDIR
+
+PKI_LOCKFILE="${PKI_LOCKDIR}/${PKI_INSTANCE_ID}"
+export PKI_LOCKFILE
+
+PKI_PIDDIR="/var/run/${PKI_FLAVOR}/${PKI_SUBSYSTEM_TYPE}"
+export PKI_PIDDIR
+
+PKI_PIDFILE="${PKI_PIDDIR}/${PKI_INSTANCE_ID}.pid"
+export PKI_PIDFILE
+
+TOMCAT_LOCKFILE=/var/lock/subsys/${PKI_INSTANCE_ID}
+export TOMCAT_LOCKFILE
+
+TOMCAT_PIDFILE=[TOMCAT_PIDFILE]
+export TOMCAT_PIDFILE
+
+pki_instance_configuration_file=${PKI_INSTANCE_PATH}/conf/CS.cfg
+export pki_instance_configuration_file
+
+RESTART_SERVER=${PKI_INSTANCE_PATH}/conf/restart_server_after_configuration
+export RESTART_SERVER
diff --git a/base/ocsp/shared/conf/CMakeLists.txt b/base/ocsp/shared/conf/CMakeLists.txt
new file mode 100644
index 000000000..e3cef5915
--- /dev/null
+++ b/base/ocsp/shared/conf/CMakeLists.txt
@@ -0,0 +1,12 @@
+set(VERSION ${APPLICATION_VERSION})
+set(MAJOR_VERSION ${APPLICATION_VERSION_MAJOR})
+set(MINOR_VERSION ${APPLICATION_VERSION_MINOR})
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CS.cfg.in ${CMAKE_CURRENT_BINARY_DIR}/CS.cfg @ONLY)
+
+install(
+ FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/CS.cfg
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/conf
+)
diff --git a/base/ocsp/shared/conf/CS.cfg.in b/base/ocsp/shared/conf/CS.cfg.in
new file mode 100644
index 000000000..5be916e7c
--- /dev/null
+++ b/base/ocsp/shared/conf/CS.cfg.in
@@ -0,0 +1,333 @@
+_000=##
+_001=## Online Certificate Status Protocol (OCSP) Responder Configuration File
+_002=##
+pidDir=[PKI_PIDDIR]
+pkicreate.pki_instance_root=[PKI_INSTANCE_ROOT]
+pkicreate.pki_instance_name=[PKI_INSTANCE_ID]
+pkicreate.subsystem_type=[PKI_SUBSYSTEM_TYPE]
+pkicreate.agent_secure_port=[PKI_AGENT_SECURE_PORT]
+pkicreate.ee_secure_port=[PKI_EE_SECURE_PORT]
+pkicreate.admin_secure_port=[PKI_ADMIN_SECURE_PORT]
+pkicreate.secure_port=[PKI_SECURE_PORT]
+pkicreate.unsecure_port=[PKI_UNSECURE_PORT]
+pkicreate.tomcat_server_port=[TOMCAT_SERVER_PORT]
+pkicreate.user=[PKI_USER]
+pkicreate.group=[PKI_GROUP]
+pkicreate.systemd.servicename=[PKI_SYSTEMD_SERVICENAME]
+pkiremove.cert.subsystem.nickname=subsystemCert cert-[PKI_INSTANCE_ID]
+installDate=[INSTALL_TIME]
+cs.type=OCSP
+admin.interface.uri=ocsp/admin/console/config/wizard
+agent.interface.uri=ocsp/agent/ocsp
+preop.admin.name=Online Certificate Status Manager Administrator
+preop.admin.group=Online Certificate Status Manager Agents
+preop.admincert.profile=caAdminCert
+preop.securitydomain.admin_url=https://[PKI_MACHINE_NAME]:9445
+preop.wizard.name=OCSP Setup Wizard
+preop.product.name=CS
+preop.product.version=@VERSION@
+preop.system.name=OCSP
+preop.system.fullname=OCSP Responder
+proxy.securePort=[PKI_PROXY_SECURE_PORT]
+proxy.unsecurePort=[PKI_PROXY_UNSECURE_PORT]
+preop.configModules.module0.userFriendlyName=NSS Internal PKCS #11 Module
+preop.configModules.module0.commonName=NSS Internal PKCS #11 Module
+preop.configModules.module0.imagePath=../img/clearpixel.gif
+preop.configModules.module1.userFriendlyName=nCipher's nFast Token Hardware Module
+preop.configModules.module1.commonName=nfast
+preop.configModules.module1.imagePath=../img/clearpixel.gif
+preop.configModules.module2.userFriendlyName=SafeNet's LunaSA Token Hardware Module
+preop.configModules.module2.commonName=lunasa
+preop.configModules.module2.imagePath=../img/clearpixel.gif
+preop.configModules.count=3
+preop.module.token=Internal Key Storage Token
+ocsp.cert.list=signing,sslserver,subsystem,audit_signing
+preop.cert.list=signing,sslserver,subsystem,audit_signing
+preop.cert.rsalist=audit_signing
+ocsp.cert.signing.certusage=StatusResponder
+ocsp.cert.sslserver.certusage=SSLServer
+ocsp.cert.subsystem.certusage=SSLClient
+ocsp.cert.audit_signing.certusage=ObjectSigner
+preop.cert.ocsp_signing.enable=true
+preop.cert.sslserver.enable=true
+preop.cert.subsystem.enable=true
+preop.cert.audit_signing.enable=true
+preop.cert.audit_signing.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.audit_signing.dn=CN=OCSP Audit Signing Certificate
+preop.cert.audit_signing.keysize.custom_size=2048
+preop.cert.audit_signing.keysize.size=2048
+preop.cert.audit_signing.nickname=auditSigningCert cert-[PKI_INSTANCE_ID]
+preop.cert.audit_signing.profile=caInternalAuthAuditSigningCert
+preop.cert.audit_signing.signing.required=false
+preop.cert.audit_signing.subsystem=ocsp
+preop.cert.audit_signing.type=remote
+preop.cert.audit_signing.userfriendlyname=OCSP Audit Signing Certificate
+preop.cert.audit_signing.cncomponent.override=true
+preop.cert.signing.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.signing.dn=CN=OCSP Signing Certificate
+preop.cert.signing.keysize.custom_size=2048
+preop.cert.signing.keysize.size=2048
+preop.cert.signing.nickname=ocspSigningCert cert-[PKI_INSTANCE_ID]
+preop.cert.signing.profile=caInternalAuthOCSPCert
+preop.cert.signing.signing.required=true
+preop.cert.signing.subsystem=ocsp
+preop.cert.signing.type=remote
+preop.cert.signing.userfriendlyname=OCSP Signing Certificate
+preop.cert.signing.cncomponent.override=true
+preop.cert.sslserver.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.sslserver.dn=CN=[PKI_MACHINE_NAME]
+preop.cert.sslserver.keysize.custom_size=2048
+preop.cert.sslserver.keysize.size=2048
+preop.cert.sslserver.nickname=Server-Cert cert-[PKI_INSTANCE_ID]
+preop.cert.sslserver.profile=caInternalAuthServerCert
+preop.cert.sslserver.signing.required=false
+preop.cert.sslserver.subsystem=ocsp
+preop.cert.sslserver.type=remote
+preop.cert.sslserver.userfriendlyname=SSL Server Certificate
+preop.cert.sslserver.cncomponent.override=false
+preop.cert.subsystem.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.subsystem.dn=CN=OCSP Subsystem Certificate
+preop.cert.subsystem.keysize.custom_size=2048
+preop.cert.subsystem.keysize.size=2048
+preop.cert.subsystem.nickname=subsystemCert cert-[PKI_INSTANCE_ID]
+preop.cert.subsystem.profile=caInternalAuthSubsystemCert
+preop.cert.subsystem.signing.required=false
+preop.cert.subsystem.subsystem=ocsp
+preop.cert.subsystem.type=remote
+preop.cert.subsystem.userfriendlyname=Subsystem Certificate
+preop.cert.subsystem.cncomponent.override=true
+cs.state=0
+authType=pwd
+instanceRoot=[PKI_INSTANCE_PATH]
+machineName=[PKI_MACHINE_NAME]
+instanceId=[PKI_INSTANCE_ID]
+service.machineName=[PKI_MACHINE_NAME]
+service.instanceDir=[PKI_INSTANCE_ROOT]
+service.securePort=[PKI_AGENT_SECURE_PORT]
+service.non_clientauth_securePort=[PKI_EE_SECURE_PORT]
+service.unsecurePort=[PKI_UNSECURE_PORT]
+service.instanceID=[PKI_INSTANCE_ID]
+preop.pin=[PKI_RANDOM_NUMBER]
+passwordFile=[PKI_INSTANCE_PATH]/conf/password.conf
+passwordClass=com.netscape.cmsutil.password.PlainPasswordFile
+multiroles=true
+multiroles.false.groupEnforceList=Administrators,Auditors,Trusted Managers,Certificate Manager Agents,Registration Manager Agents,Data Recovery Manager Agents,Online Certificate Status Manager Agents,Token Key Service Manager Agents,Enterprise CA Administrators,Enterprise KRA Adminstrators,Enterprise OCSP Administrators,Enterprise RA Administrators,Enterprise TKS Administrators,Enterprise TPS Administrators,Security Domain Administrators,Subsystem Group
+CrossCertPair._000=##
+CrossCertPair._001=## CrossCertPair Import
+CrossCertPair._002=##
+CrossCertPair.ldap=internaldb
+accessEvaluator.impl.group.class=com.netscape.cms.evaluators.GroupAccessEvaluator
+accessEvaluator.impl.ipaddress.class=com.netscape.cms.evaluators.IPAddressAccessEvaluator
+accessEvaluator.impl.user.class=com.netscape.cms.evaluators.UserAccessEvaluator
+auths._000=##
+auths._001=## new authentication
+auths._002=##
+auths.impl._000=##
+auths.impl._001=## authentication manager implementations
+auths.impl._002=##
+auths.impl.AgentCertAuth.class=com.netscape.cms.authentication.AgentCertAuthentication
+auths.impl.CMCAuth.class=com.netscape.cms.authentication.CMCAuth
+auths.impl.NISAuth.class=com.netscape.cms.authentication.NISAuth
+auths.impl.PortalEnroll.class=com.netscape.cms.authentication.PortalEnroll
+auths.impl.TokenAuth.class=com.netscape.cms.authentication.TokenAuthentication
+auths.impl.UdnPwdDirAuth.class=com.netscape.cms.authentication.UdnPwdDirAuthentication
+auths.impl.UidPwdDirAuth.class=com.netscape.cms.authentication.UidPwdDirAuthentication
+auths.impl.UidPwdPinDirAuth.class=com.netscape.cms.authentication.UidPwdPinDirAuthentication
+auths.instance.AgentCertAuth.agentGroup=Certificate Manager Agents
+auths.instance.AgentCertAuth.pluginName=AgentCertAuth
+auths.instance.TokenAuth.pluginName=TokenAuth
+auths.revocationChecking.bufferSize=50
+authz._000=##
+authz._001=## new authorizatioin
+authz._002=##
+authz.evaluateOrder=deny,allow
+authz.sourceType=ldap
+authz.impl._000=##
+authz.impl._001=## authorization manager implementations
+authz.impl._002=##
+authz.impl.BasicAclAuthz.class=com.netscape.cms.authorization.BasicAclAuthz
+authz.impl.DirAclAuthz.class=com.netscape.cms.authorization.DirAclAuthz
+authz.instance.BasicAclAuthz.pluginName=BasicAclAuthz
+authz.instance.DirAclAuthz.ldap=internaldb
+authz.instance.DirAclAuthz.pluginName=DirAclAuthz
+authz.instance.DirAclAuthz.ldap._000=##
+authz.instance.DirAclAuthz.ldap._001=## Internal Database
+authz.instance.DirAclAuthz.ldap._002=##
+cmc.cert.confirmRequired=false
+cmc.lraPopWitness.verify.allow=true
+cmc.revokeCert.verify=true
+cmc.revokeCert.sharedSecret.class=com.netscape.cms.authentication.SharedSecret
+cmc.sharedSecret.class=com.netscape.cms.authentication.SharedSecret
+cms.version=@MAJOR_VERSION@.@MINOR_VERSION@
+dbs.ldap=internaldb
+dbs.newSchemaEntryAdded=true
+debug.append=true
+debug.enabled=true
+debug.filename=[PKI_INSTANCE_PATH]/logs/debug
+debug.hashkeytypes=
+debug.level=0
+debug.showcaller=false
+keys.ecc.curve.list=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
+keys.ecc.curve.display.list=nistp256 (secp256r1),nistp384 (secp384r1),nistp521 (secp521r1),nistk163 (sect163k1),sect163r1,nistb163 (sect163r2),sect193r1,sect193r2,nistk233 (sect233k1),nistb233 (sect233r1),sect239k1,nistk283 (sect283k1),nistb283 (sect283r1),nistk409 (sect409k1),nistb409 (sect409r1),nistk571 (sect571k1),nistb571 (sect571r1),secp160k1,secp160r1,secp160r2,secp192k1,nistp192 (secp192r1, prime192v1),secp224k1,nistp224 (secp224r1),secp256k1,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
+keys.ecc.curve.default=nistp256
+keys.rsa.keysize.default=2048
+internaldb._000=##
+internaldb._001=## Internal Database
+internaldb._002=##
+internaldb.maxConns=15
+internaldb.minConns=3
+internaldb.ldapauth.authtype=BasicAuth
+internaldb.ldapauth.bindDN=cn=Directory Manager
+internaldb.ldapauth.bindPWPrompt=Internal LDAP Database
+internaldb.ldapauth.clientCertNickname=
+internaldb.ldapconn.host=
+internaldb.ldapconn.port=
+internaldb.ldapconn.secureConn=false
+preop.internaldb.schema.ldif=/usr/share/[PKI_FLAVOR]/ocsp/conf/schema.ldif
+preop.internaldb.ldif=/usr/share/[PKI_FLAVOR]/ocsp/conf/database.ldif
+preop.internaldb.data_ldif=/usr/share/[PKI_FLAVOR]/ocsp/conf/db.ldif,/usr/share/[PKI_FLAVOR]/ocsp/conf/acl.ldif
+preop.internaldb.index_ldif=/usr/share/[PKI_FLAVOR]/ocsp/conf/index.ldif
+preop.internaldb.manager_ldif=/usr/share/[PKI_FLAVOR]/ca/conf/manager.ldif
+preop.internaldb.post_ldif=
+preop.internaldb.wait_dn=
+internaldb.multipleSuffix.enable=false
+jss._000=##
+jss._001=## JSS
+jss._002=##
+jss.configDir=[PKI_INSTANCE_PATH]/alias/
+jss.enable=true
+jss.secmodName=secmod.db
+jss.ocspcheck.enable=false
+jss.ssl.cipherfortezza=true
+jss.ssl.cipherpref=
+jss.ssl.cipherversion=cipherdomestic
+log._000=##
+log._001=## Logging
+log._002=##
+log.impl.file.class=com.netscape.cms.logging.RollingLogFile
+log.instance.SignedAudit._000=##
+log.instance.SignedAudit._001=## Signed Audit Logging
+log.instance.SignedAudit._002=##
+log.instance.SignedAudit._003=##
+log.instance.SignedAudit._004=## Available Audit events:
+log.instance.SignedAudit._005=## AUDIT_LOG_STARTUP,AUDIT_LOG_SHUTDOWN,ROLE_ASSUME,CONFIG_CERT_POLICY,CONFIG_CERT_PROFILE,CONFIG_CRL_PROFILE,CONFIG_OCSP_PROFILE,CONFIG_AUTH,CONFIG_ROLE,CONFIG_ACL,CONFIG_SIGNED_AUDIT,CONFIG_ENCRYPTION,CONFIG_TRUSTED_PUBLIC_KEY,CONFIG_DRM,SELFTESTS_EXECUTION,AUDIT_LOG_DELETE,LOG_PATH_CHANGE,LOG_EXPIRATION_CHANGE,PRIVATE_KEY_ARCHIVE_REQUEST,PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE,KEY_RECOVERY_REQUEST,KEY_RECOVERY_REQUEST_ASYNC,KEY_RECOVERY_AGENT_LOGIN,KEY_RECOVERY_REQUEST_PROCESSED,KEY_RECOVERY_REQUEST_PROCESSED_ASYNC,KEY_GEN_ASYMMETRIC,NON_PROFILE_CERT_REQUEST,PROFILE_CERT_REQUEST,CERT_REQUEST_PROCESSED,CERT_STATUS_CHANGE_REQUEST,CERT_STATUS_CHANGE_REQUEST_PROCESSED,AUTHZ_SUCCESS,AUTHZ_FAIL,INTER_BOUNDARY,AUTH_FAIL,AUTH_SUCCESS,CERT_PROFILE_APPROVAL,PROOF_OF_POSSESSION,CRL_RETRIEVAL,CRL_VALIDATION,CMC_SIGNED_REQUEST_SIG_VERIFY,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_FAILURE,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_SUCCESS,SERVER_SIDE_KEYGEN_REQUEST,COMPUTE_SESSION_KEY_REQUEST,COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS, COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE,DIVERSIFY_KEY_REQUEST,DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS, DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE,ENCRYPT_DATA_REQUEST,ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS,ENCRYPT_DATA_REQUEST_PROCESSED_FAILURE,OCSP_ADD_CA_REQUEST,OCSP_ADD_CA_REQUEST_PROCESSED,OCSP_REMOVE_CA_REQUEST,OCSP_REMOVE_CA_REQUEST_PROCESSED_SUCCESS,OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE,COMPUTE_RANDOM_DATA_REQUEST,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_SUCCESS,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_FAILURE,CIMC_CERT_VERIFICATION
+log.instance.SignedAudit._006=##
+log.instance.SignedAudit.bufferSize=512
+log.instance.SignedAudit.enable=true
+log.instance.SignedAudit.events=AUDIT_LOG_STARTUP,AUDIT_LOG_SHUTDOWN,ROLE_ASSUME,CONFIG_CERT_POLICY,CONFIG_CERT_PROFILE,CONFIG_CRL_PROFILE,CONFIG_OCSP_PROFILE,CONFIG_AUTH,CONFIG_ROLE,CONFIG_ACL,CONFIG_SIGNED_AUDIT,CONFIG_ENCRYPTION,CONFIG_TRUSTED_PUBLIC_KEY,CONFIG_DRM,SELFTESTS_EXECUTION,AUDIT_LOG_DELETE,LOG_PATH_CHANGE,PRIVATE_KEY_ARCHIVE_REQUEST,PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE,KEY_RECOVERY_REQUEST,KEY_RECOVERY_REQUEST_ASYNC,KEY_RECOVERY_AGENT_LOGIN,KEY_RECOVERY_REQUEST_PROCESSED,KEY_RECOVERY_REQUEST_PROCESSED_ASYNC,KEY_GEN_ASYMMETRIC,NON_PROFILE_CERT_REQUEST,PROFILE_CERT_REQUEST,CERT_REQUEST_PROCESSED,CERT_STATUS_CHANGE_REQUEST,CERT_STATUS_CHANGE_REQUEST_PROCESSED,AUTHZ_SUCCESS,AUTHZ_FAIL,INTER_BOUNDARY,AUTH_FAIL,AUTH_SUCCESS,CERT_PROFILE_APPROVAL,PROOF_OF_POSSESSION,CRL_RETRIEVAL,CRL_VALIDATION,CMC_SIGNED_REQUEST_SIG_VERIFY,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_FAILURE,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_SUCCESS,SERVER_SIDE_KEYGEN_REQUEST,,COMPUTE_SESSION_KEY_REQUEST,COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS, COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE,DIVERSIFY_KEY_REQUEST,DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS, DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE,ENCRYPT_DATA_REQUEST,ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS,ENCRYPT_DATA_REQUEST_PROCESSED_FAILURE,OCSP_ADD_CA_REQUEST,OCSP_ADD_CA_REQUEST_PROCESSED,OCSP_REMOVE_CA_REQUEST,OCSP_REMOVE_CA_REQUEST_PROCESSED_SUCCESS,OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE,COMPUTE_RANDOM_DATA_REQUEST,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_SUCCESS,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_FAILURE,CIMC_CERT_VERIFICATION
+log.instance.SignedAudit.expirationTime=0
+log.instance.SignedAudit.fileName=[PKI_INSTANCE_PATH]/logs/signedAudit/ocsp_cert-ocsp_audit
+log.instance.SignedAudit.flushInterval=5
+log.instance.SignedAudit.level=1
+log.instance.SignedAudit.logSigning=false
+log.instance.SignedAudit.maxFileSize=2000
+log.instance.SignedAudit.pluginName=file
+log.instance.SignedAudit.rolloverInterval=2592000
+log.instance.SignedAudit.signedAudit:_000=##
+log.instance.SignedAudit.signedAudit:_001=## Fill in the nickname of a trusted signing certificate to allow OCSP audit logs to be signed
+log.instance.SignedAudit.signedAudit:_002=##
+log.instance.SignedAudit.signedAuditCertNickname=auditSigningCert cert-[PKI_INSTANCE_ID]
+log.instance.SignedAudit.type=signedAudit
+log.instance.System._000=##
+log.instance.System._001=## System Logging
+log.instance.System._002=##
+log.instance.System.bufferSize=512
+log.instance.System.enable=true
+log.instance.System.expirationTime=0
+log.instance.System.fileName=[PKI_INSTANCE_PATH]/logs/system
+log.instance.System.flushInterval=5
+log.instance.System.level=3
+log.instance.System.maxFileSize=2000
+log.instance.System.pluginName=file
+log.instance.System.rolloverInterval=2592000
+log.instance.System.type=system
+log.instance.Transactions._000=##
+log.instance.Transactions._001=## Transaction Logging
+log.instance.Transactions._002=##
+log.instance.Transactions.bufferSize=512
+log.instance.Transactions.enable=true
+log.instance.Transactions.expirationTime=0
+log.instance.Transactions.fileName=[PKI_INSTANCE_PATH]/logs/transactions
+log.instance.Transactions.flushInterval=5
+log.instance.Transactions.level=1
+log.instance.Transactions.maxFileSize=2000
+log.instance.Transactions.pluginName=file
+log.instance.Transactions.rolloverInterval=2592000
+log.instance.Transactions.type=transaction
+logAudit.fileName=[PKI_INSTANCE_PATH]/logs/access
+logError.fileName=[PKI_INSTANCE_PATH]/logs/error
+ocsp.certNickname=
+ocsp.storeId=defStore
+ocsp.signing.certnickname=
+ocsp.signing.defaultSigningAlgorithm=SHA256withRSA
+ocsp.signing.tokenname=internal
+ocsp.store.defStore.class=com.netscape.cms.ocsp.DefStore
+ocsp.store.defStore.includeNextUpdate=false
+ocsp.store.defStore.notFoundAsGood=true
+ocsp.store.ldapStore.class=com.netscape.cms.ocsp.LDAPStore
+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.extended_key_usage.class=netscape.security.extensions.ExtendedKeyUsageExtension
+oidmap.extended_key_usage.oid=2.5.29.37
+oidmap.extensions_requested_pkcs9.class=com.netscape.cms.servlet.cert.scep.ExtensionsRequested
+oidmap.extensions_requested_pkcs9.oid=1.2.840.113549.1.9.14
+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.netscape_comment.class=netscape.security.x509.NSCCommentExtension
+oidmap.netscape_comment.oid=2.16.840.1.113730.1.13
+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.pse.class=netscape.security.extensions.PresenceServerExtension
+oidmap.pse.oid=2.16.840.1.113730.1.18
+oidmap.subject_info_access.class=netscape.security.extensions.SubjectInfoAccessExtension
+oidmap.subject_info_access.oid=1.3.6.1.5.5.7.1.11
+os.serverName=cert-[PKI_INSTANCE_ID]
+os.userid=nobody
+registry.file=[PKI_INSTANCE_PATH]/conf/registry.cfg
+selftests._000=##
+selftests._001=## Self Tests
+selftests._002=##
+selftests._003=## The Self-Test plugin SystemCertsVerification uses the
+selftests._004=## following parameters (where certusage is optional):
+selftests._005=## ocsp.cert.list = <list of cert tag names deliminated by ",">
+selftests._006=## ocsp.cert.<cert tag name>.nickname
+selftests._007=## ocsp.cert.<cert tag name>.certusage
+selftests._008=##
+selftests.container.instance.OCSPPresence=com.netscape.cms.selftests.ocsp.OCSPPresence
+selftests.container.instance.OCSPValidity=com.netscape.cms.selftests.ocsp.OCSPValidity
+selftests.container.instance.SystemCertsVerification=com.netscape.cms.selftests.common.SystemCertsVerification
+selftests.container.logger.bufferSize=512
+selftests.container.logger.class=com.netscape.cms.logging.RollingLogFile
+selftests.container.logger.enable=true
+selftests.container.logger.expirationTime=0
+selftests.container.logger.fileName=[PKI_INSTANCE_PATH]/logs/selftests.log
+selftests.container.logger.flushInterval=5
+selftests.container.logger.level=1
+selftests.container.logger.maxFileSize=2000
+selftests.container.logger.register=false
+selftests.container.logger.rolloverInterval=2592000
+selftests.container.logger.type=transaction
+selftests.container.order.onDemand=OCSPPresence:critical, SystemCertsVerification:critical, OCSPValidity:critical
+selftests.container.order.startup=OCSPPresence:critical, SystemCertsVerification:critical
+selftests.plugin.OCSPPresence.OcspSubId=ocsp
+selftests.plugin.OCSPValidity.OcspSubId=ocsp
+selftests.plugin.SystemCertsVerification.SubId=ocsp
+smtp.host=localhost
+smtp.port=25
+subsystem.0.class=com.netscape.ocsp.OCSPAuthority
+subsystem.0.id=ocsp
+subsystem.1.class=com.netscape.cmscore.selftests.SelfTestSubsystem
+subsystem.1.id=selftests
+subsystem.2.class=com.netscape.cmscore.util.StatsSubsystem
+subsystem.2.id=stats
+usrgrp._000=##
+usrgrp._001=## User/Group
+usrgrp._002=##
+usrgrp.ldap=internaldb
+multiroles._000=##
+multiroles._001=## multiroles
+multiroles._002=##
+multiroles.enable=true
+multiroles.false.groupEnforceList=Administrators,Auditors,Trusted Managers,Certificate Manager Agents,Registration Manager Agents,Data Recovery Manager Agents,Online Certificate Status Manager Agents,Token Key Service Manager Agents,Enterprise CA Administrators,Enterprise KRA Administrators,Enterprise OCSP Administrators,Enterprise RA Administrators,Enterprise TKS Administrators,Enterprise TPS Administrators,Security Domain Administrators,Subsystem Group,ClonedSubsystems
diff --git a/base/ocsp/shared/conf/acl.ldif b/base/ocsp/shared/conf/acl.ldif
new file mode 100644
index 000000000..94a102b48
--- /dev/null
+++ b/base/ocsp/shared/conf/acl.ldif
@@ -0,0 +1,29 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+dn: cn=aclResources,{rootSuffix}
+objectClass: top
+objectClass: CertACLS
+cn: aclResources
+resourceACLS: certServer.general.configuration:read,modify,delete:allow (read) group="Administrators" || group="Auditors" || group="Online Certificate Status Manager Agents";allow (modify,delete) group="Administrators":Administrators, auditors, and agents are allowed to read CMS general configuration but only administrators are allowed to modify and delete
+resourceACLS: certServer.acl.configuration:read,modify:allow (read) group="Administrators" || group="Online Certificate Status Manager Agents" || group="Auditors";allow (modify) group="Administrators":Administrators, agents and auditors are allowed to read ACL configuration but only administrators allowed to modify
+resourceACLS: certServer.log.configuration:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Online Certificate Status Manager Agents";allow (modify) group="Administrators":Administrators, Agents, and auditors are allowed to read the log configuration but only administrators are allowed to modify
+resourceACLS: certServer.log.configuration.fileName:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Online Certificate Status Manager Agents";deny (modify) user=anybody:Nobody is allowed to modify a fileName parameter
+#resourceACLS: certServer.log.configuration.signedAudit.expirationTime:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Online Certificate Status Manager Agents";deny (modify) user=anybody:Nobody is allowed to modify an expirationTime parameter
+resourceACLS: certServer.log.content.signedAudit:read:allow (read) group="Auditors":Only auditor is allowed to read the signed audit log
+resourceACLS: certServer.log.content.system:read:allow (read) group="Administrators" || group="Online Certificate Status Manager Agents" || group="Auditors":Administrators, auditors, and agents are allowed to read the log content
+resourceACLS: certServer.log.content.transactions:read:allow (read) group="Administrators" || group="Online Certificate Status Manager Agents" || group="Auditors":Administrators, auditors, and agents are allowed to read the log content
+resourceACLS: certServer.auth.configuration:read,modify:allow (read) group="Administrators" || group="Online Certificate Status Manager Agents" || group="Auditors";allow (modify) group="Administrators":Administrators, agents, and auditors are allowed to read authentication configuration but only administrators allowed to modify
+resourceACLS: certServer.ocsp.configuration:read,modify:allow (read) group="Administrators" || group="Online Certificate Status Manager Agents" || group="Auditors";allow (modify) group="Administrators":Administrators, Agents, and auditors are allowed to read ocsp configuration but only administrators allowed to modify
+resourceACLS: certServer.registry.configuration:read,modify:allow (read) group="Administrators" || group="Online Certificate Status Manager Agents" || group="Auditors";allow (modify) group="Administrators":this acl is shared by all admin servlets
+resourceACLS: certServer.ocsp.info:read:allow (read) group="Online Certificate Status Manager Agents":Online Certificate Status Manager agents may read ocsp information
+resourceACLS: certServer.ee.request.ocsp:submit:allow (submit) ipaddress=".*":Any clients can submit ocsp requests
+resourceACLS: certServer.ee.crl:read,add:allow (read,add) user="anybody":Anybody may add or retrieve CRL
+resourceACLS: certServer.ocsp.crl:add:allow (add) group="Online Certificate Status Manager Agents" || group="Trusted Managers":Online Certificate Status Manager agents and Trusted Managers may add CRL
+resourceACLS: certServer.ocsp.ca:add:allow (add) group="Online Certificate Status Manager Agents":Online Certificate Status Manager agents may add Certificate Authority
+resourceACLS: certServer.ocsp.cas:list:allow (list) group="Online Certificate Status Manager Agents":Online Certificate Status Manager agents may list Certificate Authorities
+resourceACLS: certServer.ocsp.certificate:validate:allow (validate) group="Online Certificate Status Manager Agents":Online Certificate Status Manager agents may validate certificate status
+resourceACLS: certServer.ocsp.group:read,modify:allow (modify,read) group="Administrators":Only administrators are allowed to read and modify groups
+resourceACLS: certServer.clone.configuration:read,modify:allow (modify,read) group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise OCSP Administrators" || group="Enterprise TKS Administrators":Only Enterprise Administrators are allowed to clone the configuration.
diff --git a/base/ocsp/shared/conf/catalina.policy b/base/ocsp/shared/conf/catalina.policy
new file mode 100644
index 000000000..cf8302cd0
--- /dev/null
+++ b/base/ocsp/shared/conf/catalina.policy
@@ -0,0 +1,184 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// Copyright (C) 2006-2010 Red Hat, Inc.
+// All rights reserved.
+// Modifications: configuration parameters
+// --- END COPYRIGHT BLOCK ---
+
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// ============================================================================
+// catalina.corepolicy - Security Policy Permissions for Tomcat 6
+//
+// This file contains a default set of security policies to be enforced (by the
+// JVM) when Catalina is executed with the "-security" option. In addition
+// to the permissions granted here, the following additional permissions are
+// granted to the codebase specific to each web application:
+//
+// * Read access to the document root directory
+//
+// $Id$
+// ============================================================================
+
+
+// ========== SYSTEM CODE PERMISSIONS =========================================
+
+
+// These permissions apply to javac
+grant codeBase "file:${java.home}/lib/-" {
+ permission java.security.AllPermission;
+};
+
+// These permissions apply to all shared system extensions
+grant codeBase "file:${java.home}/jre/lib/ext/-" {
+ permission java.security.AllPermission;
+};
+
+// These permissions apply to javac when ${java.home] points at $JAVA_HOME/jre
+grant codeBase "file:${java.home}/../lib/-" {
+ permission java.security.AllPermission;
+};
+
+// These permissions apply to all shared system extensions when
+// ${java.home} points at $JAVA_HOME/jre
+grant codeBase "file:${java.home}/lib/ext/-" {
+ permission java.security.AllPermission;
+};
+
+
+// ========== CATALINA CODE PERMISSIONS =======================================
+
+
+// These permissions apply to the daemon code
+grant codeBase "file:${catalina.home}/bin/commons-daemon.jar" {
+ permission java.security.AllPermission;
+};
+
+// These permissions apply to the logging API
+grant codeBase "file:${catalina.home}/bin/tomcat-juli.jar" {
+ permission java.util.PropertyPermission "java.util.logging.config.class", "read";
+ permission java.util.PropertyPermission "java.util.logging.config.file", "read";
+ permission java.io.FilePermission "${java.home}${file.separator}lib${file.separator}logging.properties", "read";
+ permission java.lang.RuntimePermission "shutdownHooks";
+ permission java.io.FilePermission "${catalina.base}${file.separator}conf${file.separator}logging.properties", "read";
+ permission java.util.PropertyPermission "catalina.base", "read";
+ permission java.util.logging.LoggingPermission "control";
+ permission java.io.FilePermission "${catalina.base}${file.separator}logs", "read, write";
+ permission java.io.FilePermission "${catalina.base}${file.separator}logs${file.separator}*", "read, write";
+ permission java.lang.RuntimePermission "getClassLoader";
+ // To enable per context logging configuration, permit read access to the appropriate file.
+ // Be sure that the logging configuration is secure before enabling such access
+ // eg for the examples web application:
+ // permission java.io.FilePermission "${catalina.base}${file.separator}webapps${file.separator}examples${file.separator}WEB-INF${file.separator}classes${file.separator}logging.properties", "read";
+};
+
+// These permissions apply to the server startup code
+grant codeBase "file:${catalina.home}/bin/bootstrap.jar" {
+ permission java.security.AllPermission;
+};
+
+// These permissions apply to the servlet API classes
+// and those that are shared across all class loaders
+// located in the "lib" directory
+grant codeBase "file:${catalina.home}/lib/-" {
+ permission java.security.AllPermission;
+};
+
+
+// ========== WEB APPLICATION PERMISSIONS =====================================
+
+
+// These permissions are granted by default to all web applications
+// In addition, a web application will be given a read FilePermission
+// and JndiPermission for all files and directories in its document root.
+grant {
+ // Required for JNDI lookup of named JDBC DataSource's and
+ // javamail named MimePart DataSource used to send mail
+ permission java.util.PropertyPermission "java.home", "read";
+ permission java.util.PropertyPermission "java.naming.*", "read";
+ permission java.util.PropertyPermission "javax.sql.*", "read";
+
+ // OS Specific properties to allow read access
+ permission java.util.PropertyPermission "os.name", "read";
+ permission java.util.PropertyPermission "os.version", "read";
+ permission java.util.PropertyPermission "os.arch", "read";
+ permission java.util.PropertyPermission "file.separator", "read";
+ permission java.util.PropertyPermission "path.separator", "read";
+ permission java.util.PropertyPermission "line.separator", "read";
+
+ // JVM properties to allow read access
+ permission java.util.PropertyPermission "java.version", "read";
+ permission java.util.PropertyPermission "java.vendor", "read";
+ permission java.util.PropertyPermission "java.vendor.url", "read";
+ permission java.util.PropertyPermission "java.class.version", "read";
+ permission java.util.PropertyPermission "java.specification.version", "read";
+ permission java.util.PropertyPermission "java.specification.vendor", "read";
+ permission java.util.PropertyPermission "java.specification.name", "read";
+
+ permission java.util.PropertyPermission "java.vm.specification.version", "read";
+ permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
+ permission java.util.PropertyPermission "java.vm.specification.name", "read";
+ permission java.util.PropertyPermission "java.vm.version", "read";
+ permission java.util.PropertyPermission "java.vm.vendor", "read";
+ permission java.util.PropertyPermission "java.vm.name", "read";
+
+ // Required for OpenJMX
+ permission java.lang.RuntimePermission "getAttribute";
+
+ // Allow read of JAXP compliant XML parser debug
+ permission java.util.PropertyPermission "jaxp.debug", "read";
+
+ // Precompiled JSPs need access to this package.
+ permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime";
+ permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime.*";
+
+ // Precompiled JSPs need access to this system property.
+ permission java.util.PropertyPermission "org.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER", "read";
+
+};
+
+
+// You can assign additional permissions to particular web applications by
+// adding additional "grant" entries here, based on the code base for that
+// application, /WEB-INF/classes/, or /WEB-INF/lib/ jar files.
+//
+// Different permissions can be granted to JSP pages, classes loaded from
+// the /WEB-INF/classes/ directory, all jar files in the /WEB-INF/lib/
+// directory, or even to individual jar files in the /WEB-INF/lib/ directory.
+//
+// For instance, assume that the standard "examples" application
+// included a JDBC driver that needed to establish a network connection to the
+// corresponding database and used the scrape taglib to get the weather from
+// the NOAA web server. You might create a "grant" entries like this:
+//
+// The permissions granted to the context root directory apply to JSP pages.
+// grant codeBase "file:${catalina.home}/webapps/examples/-" {
+// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
+// permission java.net.SocketPermission "*.noaa.gov:80", "connect";
+// };
+//
+// The permissions granted to the context WEB-INF/classes directory
+// grant codeBase "file:${catalina.home}/webapps/examples/WEB-INF/classes/-" {
+// };
+//
+// The permission granted to your JDBC driver
+// grant codeBase "jar:file:${catalina.home}/webapps/examples/WEB-INF/lib/driver.jar!/-" {
+// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
+// };
+// The permission granted to the scrape taglib
+// grant codeBase "jar:file:${catalina.home}/webapps/examples/WEB-INF/lib/scrape.jar!/-" {
+// permission java.net.SocketPermission "*.noaa.gov:80", "connect";
+// };
+
diff --git a/base/ocsp/shared/conf/catalina.properties b/base/ocsp/shared/conf/catalina.properties
new file mode 100644
index 000000000..70cb7c05e
--- /dev/null
+++ b/base/ocsp/shared/conf/catalina.properties
@@ -0,0 +1,87 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006-2010 Red Hat, Inc.
+# All rights reserved.
+# Modifications: configuration parameters
+# --- END COPYRIGHT BLOCK ---
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# List of comma-separated packages that start with or equal this string
+# will cause a security exception to be thrown when
+# passed to checkPackageAccess unless the
+# corresponding RuntimePermission ("accessClassInPackage."+package) has
+# been granted.
+package.access=sun.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper.,sun.beans.
+#
+# List of comma-separated packages that start with or equal this string
+# will cause a security exception to be thrown when
+# passed to checkPackageDefinition unless the
+# corresponding RuntimePermission ("defineClassInPackage."+package) has
+# been granted.
+#
+# by default, no packages are restricted for definition, and none of
+# the class loaders supplied with the JDK call checkPackageDefinition.
+#
+package.definition=sun.,java.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper.
+
+#
+#
+# List of comma-separated paths defining the contents of the "common"
+# classloader. Prefixes should be used to define what is the repository type.
+# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute.
+# If left as blank,the JVM system loader will be used as Catalina's "common"
+# loader.
+# Examples:
+# "foo": Add this folder as a class repository
+# "foo/*.jar": Add all the JARs of the specified folder as class
+# repositories
+# "foo/bar.jar": Add bar.jar as a class repository
+common.loader=${catalina.home}/lib,${catalina.home}/lib/*.jar,[TOMCAT_INSTANCE_COMMON_LIB]
+
+#
+# List of comma-separated paths defining the contents of the "server"
+# classloader. Prefixes should be used to define what is the repository type.
+# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute.
+# If left as blank, the "common" loader will be used as Catalina's "server"
+# loader.
+# Examples:
+# "foo": Add this folder as a class repository
+# "foo/*.jar": Add all the JARs of the specified folder as class
+# repositories
+# "foo/bar.jar": Add bar.jar as a class repository
+server.loader=
+
+#
+# List of comma-separated paths defining the contents of the "shared"
+# classloader. Prefixes should be used to define what is the repository type.
+# Path may be relative to the CATALINA_BASE path or absolute. If left as blank,
+# the "common" loader will be used as Catalina's "shared" loader.
+# Examples:
+# "foo": Add this folder as a class repository
+# "foo/*.jar": Add all the JARs of the specified folder as class
+# repositories
+# "foo/bar.jar": Add bar.jar as a class repository
+# Please note that for single jars, e.g. bar.jar, you need the URL form
+# starting with file:.
+shared.loader=
+
+#
+# String cache configuration.
+tomcat.util.buf.StringCache.byte.enabled=true
+#tomcat.util.buf.StringCache.char.enabled=true
+#tomcat.util.buf.StringCache.trainThreshold=500000
+#tomcat.util.buf.StringCache.cacheSize=5000
diff --git a/base/ocsp/shared/conf/context.xml b/base/ocsp/shared/conf/context.xml
new file mode 100644
index 000000000..8b6fe4905
--- /dev/null
+++ b/base/ocsp/shared/conf/context.xml
@@ -0,0 +1,40 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2006-2010 Red Hat, Inc.
+ All rights reserved.
+ Modifications: configuration parameters
+ END COPYRIGHT BLOCK -->
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- The contents of this file will be loaded for each web application -->
+<Context crossContext="true" allowLinking="true">
+
+ <!-- Default set of monitored resources -->
+ <WatchedResource>WEB-INF/web.xml</WatchedResource>
+
+ <!-- Uncomment this to disable session persistence across Tomcat restarts -->
+ <!--
+ <Manager pathname="" />
+ -->
+
+ <!-- Uncomment this to enable Comet connection tacking (provides events
+ on session expiration as well as webapp lifecycle) -->
+ <!--
+ <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
+ -->
+
+</Context>
diff --git a/base/ocsp/shared/conf/database.ldif b/base/ocsp/shared/conf/database.ldif
new file mode 100644
index 000000000..d3c5f9e68
--- /dev/null
+++ b/base/ocsp/shared/conf/database.ldif
@@ -0,0 +1,9 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+dn: cn=config
+changetype: modify
+replace: nsslapd-maxbersize
+nsslapd-maxbersize: 209715200
diff --git a/base/ocsp/shared/conf/db.ldif b/base/ocsp/shared/conf/db.ldif
new file mode 100644
index 000000000..ec159e02f
--- /dev/null
+++ b/base/ocsp/shared/conf/db.ldif
@@ -0,0 +1,67 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+dn: ou=people,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: people
+aci: (targetattr!="userPassword")(version 3.0; acl "Enable anonymous access"; allow (read, search, compare)userdn="ldap:///anyone";)
+
+dn: ou=groups,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: groups
+
+dn: cn=Online Certificate Status Manager Agents,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Online Certificate Status Manager Agents
+description: Agents for Online Certificate Status Manager
+
+dn: cn=Subsystem Group, ou=groups, {rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Subsystem Group
+description: Subsystem Group
+
+dn: cn=Trusted Managers,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Trusted Managers
+description: Managers trusted by this PKI instance
+
+dn: cn=Administrators,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Administrators
+description: People who manage the Certificate System
+
+dn: cn=Auditors,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Auditors
+description: People who can read the signed audits
+
+dn: cn=ClonedSubsystems,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: ClonedSubsystems
+description: People who can clone the master subsystem
+
+dn: ou=requests,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: requests
+
+dn: cn=crossCerts,{rootSuffix}
+cn: crossCerts
+sn: crossCerts
+objectClass: top
+objectClass: person
+objectClass: pkiCA
+cACertificate;binary:
+authorityRevocationList;binary:
+certificateRevocationList;binary:
+crossCertificatePair;binary:
diff --git a/base/ocsp/shared/conf/index.ldif b/base/ocsp/shared/conf/index.ldif
new file mode 100644
index 000000000..184187045
--- /dev/null
+++ b/base/ocsp/shared/conf/index.ldif
@@ -0,0 +1,203 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+dn: cn=revokedby,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: revokedby
+
+dn: cn=issuedby,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: issuedby
+
+dn: cn=publicKeyData,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: publicKeyData
+
+dn: cn=clientId,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: clientId
+
+dn: cn=dataType,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: dataType
+
+dn: cn=status,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: status
+
+dn: cn=description,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: description
+
+dn: cn=serialno,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: serialno
+
+dn: cn=metaInfo,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: metaInfo
+
+dn: cn=certstatus,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: certstatus
+
+dn: cn=requestid,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: requestid
+
+dn: cn=requesttype,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: requesttype
+
+dn: cn=requeststate,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: requeststate
+
+dn: cn=requestowner,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: requestowner
+
+dn: cn=notbefore,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: notbefore
+
+dn: cn=notafter,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: notafter
+
+dn: cn=duration,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: duration
+
+dn: cn=dateOfCreate,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: dateOfCreate
+
+dn: cn=revokedOn,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: revokedOn
+
+dn: cn=archivedBy,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: archivedBy
+
+dn: cn=ownername,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsIndexType: sub
+nsSystemIndex: false
+cn: ownername
+
+dn: cn=subjectname,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsIndexType: sub
+nsSystemIndex: false
+cn: subjectname
+
+dn: cn=requestsourceid,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsIndexType: sub
+nsSystemIndex: false
+cn: requestsourceid
+
+dn: cn=revInfo,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsIndexType: sub
+nsSystemIndex: false
+cn: revInfo
+
+dn: cn=extension,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsIndexType: sub
+nsSystemIndex: false
+cn: extension
diff --git a/base/ocsp/shared/conf/jk2.manifest b/base/ocsp/shared/conf/jk2.manifest
new file mode 100644
index 000000000..986d7b874
--- /dev/null
+++ b/base/ocsp/shared/conf/jk2.manifest
@@ -0,0 +1,2 @@
+Main-Class: org.apache.jk.apr.TomcatStarter
+Class-Path: ../lib/tomcat.jar log4j.jar log4j-core.jar ../lib/common/log4j.jar ../lib/common/log4j-core.jar ../lib/common/classes ../lib/common/commons-logging.jar bootstrap.jar ../server/lib/commons-logging.jar ../server/lib/jmx.jar jmx.jar commons-logging-api.jar
diff --git a/base/ocsp/shared/conf/jk2.properties b/base/ocsp/shared/conf/jk2.properties
new file mode 100644
index 000000000..4d8e357f8
--- /dev/null
+++ b/base/ocsp/shared/conf/jk2.properties
@@ -0,0 +1,31 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+## THIS FILE MAY BE OVERRIDEN AT RUNTIME. MAKE SURE TOMCAT IS STOPED
+## WHEN YOU EDIT THE FILE.
+
+## COMMENTS WILL BE _LOST_
+
+## DOCUMENTATION OF THE FORMAT IN JkMain javadoc.
+
+# Set the desired handler list
+# handler.list=apr,request,channelJni
+#
+# Override the default port for the socketChannel
+# channelSocket.port=8019
+# Default:
+# channelUnix.file=${jkHome}/work/jk2.socket
+# Just to check if the the config is working
+# shm.file=${jkHome}/work/jk2.shm
+
+# In order to enable jni use any channelJni directive
+# channelJni.disabled = 0
+# And one of the following directives:
+
+# apr.jniModeSo=/opt/apache2/modules/mod_jk2.so
+
+# If set to inprocess the mod_jk2 will Register natives itself
+# This will enable the starting of the Tomcat from mod_jk2
+# apr.jniModeSo=inprocess
diff --git a/base/ocsp/shared/conf/jkconf.ant.xml b/base/ocsp/shared/conf/jkconf.ant.xml
new file mode 100644
index 000000000..a4f498050
--- /dev/null
+++ b/base/ocsp/shared/conf/jkconf.ant.xml
@@ -0,0 +1,55 @@
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2006 Red Hat, Inc.
+ All rights reserved.
+ END COPYRIGHT BLOCK -->
+<project name="jkconf" default="main" basedir=".">
+
+ <target name="init-3x" if="33.detect">
+ <taskdef name="jkconf"
+ classname="org.apache.jk.config.WebXml2Jk" >
+ <classpath>
+ <!-- 3.3 support -->
+ <pathelement location="/ws/jtc/jk/build/classes" />
+ <pathelement location="${tomcat.home}/lib/container/tomcat-jk2.jar" />
+ <pathelement location="${tomcat.home}/lib/container/crimson.jar"/>
+ <pathelement location="${tomcat.home}/lib/common/commons-logging.jar"/>
+ </classpath>
+ </taskdef>
+ </target>
+
+ <target name="init-4x" if="4x.detect" >
+ <path id="main.classpath">
+ <!-- 3.3 support -->
+ <fileset dir="${tomcat.home}/lib" includes="*.jar" />
+ <fileset dir="${tomcat.home}/server/lib" includes="*.jar" />
+ <fileset dir="${tomcat.home}/common/lib" includes="*.jar" />
+ </path>
+
+ <taskdef name="jkconf" classpathref="main.classpath"
+ classname="org.apache.jk.config.WebXml2Jk" />
+ </target>
+
+ <target name="detect" >
+ <property file="build.properties"/>
+ <property file="${user.home}/build.properties"/>
+ <property file="${user.home}/.build.properties"/>
+
+ <!-- default locations, overrident by properties.
+ This file must be installed in conf/ -->
+ <property name="tomcat.home" location=".." />
+
+ <available property="33.detect" file="${tomcat.home}/lib/container" />
+ <available property="4x.detect" file="${tomcat.home}/server/lib" />
+ </target>
+
+ <target name="init" depends="detect,init-3x,init-4x" />
+
+ <!-- ==================== Detection and reports ==================== -->
+
+
+ <target name="main" depends="init">
+ <jkconf docBase="${tomcat.home}/webapps/examples"
+ context="/examples" />
+ </target>
+
+</project>
diff --git a/base/ocsp/shared/conf/jkconfig.manifest b/base/ocsp/shared/conf/jkconfig.manifest
new file mode 100644
index 000000000..3ba1f2e3e
--- /dev/null
+++ b/base/ocsp/shared/conf/jkconfig.manifest
@@ -0,0 +1,2 @@
+Main-Class: org.apache.jk.config.WebXml2Jk
+Class-Path: tomcat-jk2.jar commons-logging.jar crimson.jar xercesImpl.jar xmlApis.jar tomcat-util.jar log4j.jar log4j-core.jar
diff --git a/base/ocsp/shared/conf/logging.properties b/base/ocsp/shared/conf/logging.properties
new file mode 100644
index 000000000..796cfc071
--- /dev/null
+++ b/base/ocsp/shared/conf/logging.properties
@@ -0,0 +1,70 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006-2010 Red Hat, Inc.
+# All rights reserved.
+# Modifications: configuration parameters
+# --- END COPYRIGHT BLOCK ---
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+handlers = 1catalina.org.apache.juli.FileHandler, 2localhost.org.apache.juli.FileHandler, 3manager.org.apache.juli.FileHandler, 4host-manager.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+
+.handlers = 1catalina.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+
+############################################################
+# Handler specific properties.
+# Describes specific configuration info for Handlers.
+############################################################
+
+1catalina.org.apache.juli.FileHandler.level = FINE
+1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+1catalina.org.apache.juli.FileHandler.prefix = catalina.
+
+2localhost.org.apache.juli.FileHandler.level = FINE
+2localhost.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+2localhost.org.apache.juli.FileHandler.prefix = localhost.
+
+3manager.org.apache.juli.FileHandler.level = FINE
+3manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+3manager.org.apache.juli.FileHandler.prefix = manager.
+
+4host-manager.org.apache.juli.FileHandler.level = FINE
+4host-manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+4host-manager.org.apache.juli.FileHandler.prefix = host-manager.
+
+java.util.logging.ConsoleHandler.level = FINE
+java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
+
+
+############################################################
+# Facility specific properties.
+# Provides extra control for each logger.
+############################################################
+
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler
+
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler
+
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler
+
+# For example, set the com.xyz.foo logger to only log SEVERE
+# messages:
+#org.apache.catalina.startup.ContextConfig.level = FINE
+#org.apache.catalina.startup.HostConfig.level = FINE
+#org.apache.catalina.session.ManagerBase.level = FINE
+#org.apache.catalina.core.AprLifecycleListener.level=FINE
diff --git a/base/ocsp/shared/conf/manager.ldif b/base/ocsp/shared/conf/manager.ldif
new file mode 100644
index 000000000..52e486987
--- /dev/null
+++ b/base/ocsp/shared/conf/manager.ldif
@@ -0,0 +1,48 @@
+# acis for cert manager
+
+dn: ou=csusers,cn=config
+objectClass: top
+objectClass: organizationalUnit
+ou: csusers
+
+dn: {rootSuffix}
+changetype: modify
+add: aci
+aci: (targetattr=*)(version 3.0; acl "cert manager access"; allow (all) userdn = "ldap:///{dbuser}";)
+
+dn: cn=ldbm database,cn=plugins,cn=config
+changetype: modify
+add: aci
+aci: (targetattr=*)(version 3.0; acl "Cert Manager access for VLV searches"; allow (read) userdn="ldap:///{dbuser}";)
+
+dn: cn=config
+changetype: modify
+add: aci
+aci: (targetattr != aci)(version 3.0; aci "cert manager read access"; allow (read, search, compare) userdn = "ldap:///{dbuser}";)
+
+dn: ou=csusers,cn=config
+changetype: modify
+add: aci
+aci: (targetattr != aci)(version 3.0; aci "cert manager manage replication users"; allow (all) userdn = "ldap:///{dbuser}";)
+
+dn: cn="{rootSuffix}",cn=mapping tree,cn=config
+changetype: modify
+add: aci
+aci: (targetattr=*)(version 3.0;acl "cert manager: Add Replication Agreements";allow (add) userdn = "ldap:///{dbuser}";)
+
+dn: cn="{rootSuffix}",cn=mapping tree,cn=config
+changetype: modify
+add: aci
+aci: (targetattr=*)(targetfilter="(|(objectclass=nsds5Replica)(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement)(objectClass=nsMappingTree))")(version 3.0; acl "cert manager: Modify Replication Agreements"; allow (read, write, search) userdn = "ldap:///{dbuser}";)
+
+dn: cn="{rootSuffix}",cn=mapping tree,cn=config
+changetype: modify
+add: aci
+aci: (targetattr=*)(targetfilter="(|(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement))")(version 3.0;acl "cert manager: Remove Replication Agreements";allow (delete) userdn = "ldap:///{dbuser}";)
+
+dn: cn=tasks,cn=config
+changetype: modify
+add: aci
+aci: (targetattr=*)(version 3.0; acl "cert manager: Run tasks after replica re-initialization"; allow (add) userdn = "ldap:///{dbuser}";)
+
+
diff --git a/base/ocsp/shared/conf/schema.ldif b/base/ocsp/shared/conf/schema.ldif
new file mode 100644
index 000000000..70578e21c
--- /dev/null
+++ b/base/ocsp/shared/conf/schema.ldif
@@ -0,0 +1,489 @@
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( usertype-oid NAME 'usertype' DESC 'Distinguish whether the user is administrator, agent or subsystem.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( userstate-oid NAME 'userstate' DESC 'Distinguish whether the user is administrator, agent or subsystem.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( cmsuser-oid NAME 'cmsuser' DESC 'CMS User' SUP top STRUCTURAL MUST usertype MAY userstate X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( archivedBy-oid NAME 'archivedBy' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( adminMessages-oid NAME 'adminMessages' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( algorithm-oid NAME 'algorithm' DESC 'CMS defined attribute'SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( algorithmId-oid NAME 'algorithmId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( signingAlgorithmId-oid NAME 'signingAlgorithmId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( autoRenew-oid NAME 'autoRenew' DESC 'CMS defined attribute'SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( certStatus-oid NAME 'certStatus' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( crlName-oid NAME 'crlName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( crlSize-oid NAME 'crlSize' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( deltaSize-oid NAME 'deltaSize' DESC 'CMS defined attribute'SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( crlNumber-oid NAME 'crlNumber' DESC 'CMS defined attribute'SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( deltaNumber-oid NAME 'deltaNumber' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( firstUnsaved-oid NAME 'firstUnsaved' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( crlCache-oid NAME 'crlCache' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( revokedCerts-oid NAME 'revokedCerts' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( unrevokedCerts-oid NAME 'unrevokedCerts' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( expiredCerts-oid NAME 'expiredCerts' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( crlExtensions-oid NAME 'crlExtensions' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dateOfArchival-oid NAME 'dateOfArchival' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dateOfRecovery-oid NAME 'dateOfRecovery' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dateOfRevocation-oid NAME 'dateOfRevocation' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dateOfCreate-oid NAME 'dateOfCreate' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dateOfModify-oid NAME 'dateOfModify' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( duration-oid NAME 'duration' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( extension-oid NAME 'extension' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( issuedBy-oid NAME 'issuedBy' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( issueInfo-oid NAME 'issueInfo' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( issuerName-oid NAME 'issuerName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( keySize-oid NAME 'keySize' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( clientId-oid NAME 'clientId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dataType-oid NAME 'dataType' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( status-oid NAME 'status' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( keyState-oid NAME 'keyState' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( metaInfo-oid NAME 'metaInfo' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( nextUpdate-oid NAME 'nextUpdate' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( notAfter-oid NAME 'notAfter' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( notBefore-oid NAME 'notBefore' DESC 'CMS defined attribute'SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( ownerName-oid NAME 'ownerName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( password-oid NAME 'password' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( p12Expiration-oid NAME 'p12Expiration' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( proofOfArchival-oid NAME 'proofOfArchival' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( publicKeyData-oid NAME 'publicKeyData' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( publicKeyFormat-oid NAME 'publicKeyFormat' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( privateKeyData-oid NAME 'privateKeyData' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestId-oid NAME 'requestId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestInfo-oid NAME 'requestInfo' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestState-oid NAME 'requestState' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestResult-oid NAME 'requestResult' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestOwner-oid NAME 'requestOwner' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestAgentGroup-oid NAME 'requestAgentGroup' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestSourceId-oid NAME 'requestSourceId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestType-oid NAME 'requestType' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestFlag-oid NAME 'requestFlag' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestError-oid NAME 'requestError' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( resourceACLS-oid NAME 'resourceACLS' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( revInfo-oid NAME 'revInfo' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( revokedBy-oid NAME 'revokedBy' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( revokedOn-oid NAME 'revokedOn' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( serialno-oid NAME 'serialno' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( nextRange-oid NAME 'nextRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( publishingStatus-oid NAME 'publishingStatus' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( beginRange-oid NAME 'beginRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( endRange-oid NAME 'endRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( subjectName-oid NAME 'subjectName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( sessionContext-oid NAME 'sessionContext' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( thisUpdate-oid NAME 'thisUpdate' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( transId-oid NAME 'transId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( transStatus-oid NAME 'transStatus' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( transName-oid NAME 'transName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( transOps-oid NAME 'transOps' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( userDN-oid NAME 'userDN' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( userMessages-oid NAME 'userMessages' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( version-oid NAME 'version' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( Clone-oid NAME 'Clone' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( DomainManager-oid NAME 'DomainManager' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SecurePort-oid NAME 'SecurePort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SecureAgentPort-oid NAME 'SecureAgentPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SecureAdminPort-oid NAME 'SecureAdminPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SecureEEClientAuthPort-oid NAME 'SecureEEClientAuthPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( UnSecurePort-oid NAME 'UnSecurePort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SubsystemName-oid NAME 'SubsystemName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( cmsUserGroup-oid NAME 'cmsUserGroup' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( CertACLS-oid NAME 'CertACLS' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY resourceACLS X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( repository-oid NAME 'repository' DESC 'CMS defined class' SUP top STRUCTURAL MUST ou MAY ( serialno $ description $ nextRange $ publishingStatus ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( request-oid NAME 'request' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( requestId $ dateOfCreate $ dateOfModify $ requestState $ requestResult $ requestOwner $ requestAgentGroup $ requestSourceId $ requestType $ requestFlag $ requestError $ userMessages $ adminMessages ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( transaction-oid NAME 'transaction' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( transId $ description $ transName $ transStatus $ transOps ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( crlIssuingPointRecord-oid NAME 'crlIssuingPointRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( dateOfCreate $ dateOfModify $ crlNumber $ crlSize $ thisUpdate $ nextUpdate $ deltaNumber $ deltaSize $ firstUnsaved $ certificateRevocationList $ deltaRevocationList $ crlCache $ revokedCerts $ unrevokedCerts $ expiredCerts $ cACertificate ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( certificateRecord-oid NAME 'certificateRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( serialno $ dateOfCreate $ dateOfModify $ certStatus $ autoRenew $ issueInfo $ metaInfo $ revInfo $ version $ duration $ notAfter $ notBefore $ algorithmId $ subjectName $ signingAlgorithmId $ userCertificate $ issuedBy $ revokedBy $ revokedOn $ extension $ publicKeyData $ issuerName ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( userDetails-oid NAME 'userDetails' DESC 'CMS defined class' SUP top STRUCTURAL MUST userDN MAY ( dateOfCreate $ dateOfModify $ password $ p12Expiration ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( keyRecord-oid NAME 'keyRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( serialno $ dateOfCreate $ dateOfModify $ keyState $ privateKeyData $ ownerName $ keySize $ metaInfo $ dateOfArchival $ dateOfRecovery $ algorithm $ publicKeyFormat $ publicKeyData $ archivedBy $ clientId $ dataType $ status ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( pkiSecurityDomain-oid NAME 'pkiSecurityDomain' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( ou $ name ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( pkiSecurityGroup-oid NAME 'pkiSecurityGroup' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( pkiSubsystem-oid NAME 'pkiSubsystem' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ Host $ SecurePort $ SubsystemName $ Clone ) MAY ( DomainManager $ SecureAgentPort $ SecureAdminPort $SecureEEClientAuthPort $ UnSecurePort ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( pkiRange-oid NAME 'pkiRange' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ beginRange $ endRange $ Host $ SecurePort ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( securityDomainSessionEntry-oid NAME 'securityDomainSessionEntry' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ host $ uid $ cmsUserGroup $ dateOfCreate ) X-ORIGIN 'user defined' )
diff --git a/base/ocsp/shared/conf/server-minimal.xml b/base/ocsp/shared/conf/server-minimal.xml
new file mode 100644
index 000000000..0df50b528
--- /dev/null
+++ b/base/ocsp/shared/conf/server-minimal.xml
@@ -0,0 +1,29 @@
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2006 Red Hat, Inc.
+ All rights reserved.
+ END COPYRIGHT BLOCK -->
+<Server port="8005" shutdown="SHUTDOWN">
+
+ <GlobalNamingResources>
+ <!-- Used by Manager webapp -->
+ <Resource name="UserDatabase" auth="Container"
+ type="org.apache.catalina.UserDatabase"
+ description="User database that can be updated and saved"
+ factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
+ pathname="conf/tomcat-users.xml" />
+ </GlobalNamingResources>
+
+ <Service name="Catalina">
+ <Connector port="8080" />
+
+ <!-- This is here for compatibility only, not required -->
+ <Connector port="8009" protocol="AJP/1.3" />
+
+ <Engine name="Catalina" defaultHost="localhost">
+ <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+ resourceName="UserDatabase" />
+ <Host name="localhost" appBase="webapps" />
+ </Engine>
+
+ </Service>
+</Server>
diff --git a/base/ocsp/shared/conf/server.xml b/base/ocsp/shared/conf/server.xml
new file mode 100644
index 000000000..6217ce1d9
--- /dev/null
+++ b/base/ocsp/shared/conf/server.xml
@@ -0,0 +1,258 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2006-2010 Red Hat, Inc.
+ All rights reserved.
+ Modifications: configuration parameters
+ END COPYRIGHT BLOCK -->
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- Note: A "Server" is not itself a "Container", so you may not
+ define subcomponents such as "Valves" at this level.
+ Documentation at /docs/config/server.html
+ -->
+
+<!-- DO NOT REMOVE - Begin PKI Status Definitions -->
+<!--
+Unsecure Port = http://[PKI_MACHINE_NAME]:[PKI_UNSECURE_PORT]/[PKI_SUBSYSTEM_TYPE]/ee/[PKI_SUBSYSTEM_TYPE]
+Secure Agent Port = https://[PKI_MACHINE_NAME]:[PKI_AGENT_SECURE_PORT]/[PKI_SUBSYSTEM_TYPE]/agent/[PKI_SUBSYSTEM_TYPE]
+Secure EE Port = https://[PKI_MACHINE_NAME]:[PKI_EE_SECURE_PORT]/[PKI_SUBSYSTEM_TYPE]/ee/[PKI_SUBSYSTEM_TYPE]
+Secure Admin Port = https://[PKI_MACHINE_NAME]:[PKI_ADMIN_SECURE_PORT]/[PKI_SUBSYSTEM_TYPE]/services
+PKI Console Port = pkiconsole https://[PKI_MACHINE_NAME]:[PKI_ADMIN_SECURE_PORT]/[PKI_SUBSYSTEM_TYPE]
+Tomcat Port = [TOMCAT_SERVER_PORT] (for shutdown)
+-->
+<!-- DO NOT REMOVE - End PKI Status Definitions -->
+
+<Server port="[TOMCAT_SERVER_PORT]" shutdown="SHUTDOWN">
+
+ <!--APR library loader. Documentation at /docs/apr.html -->
+ <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
+ <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
+ <Listener className="org.apache.catalina.core.JasperListener" />
+ <!-- JMX Support for the Tomcat server. Documentation at /docs/non-existent.html -->
+ <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
+ <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
+
+ <!-- Global JNDI resources
+ Documentation at /docs/jndi-resources-howto.html
+ -->
+ <GlobalNamingResources>
+ <!-- Editable user database that can also be used by
+ UserDatabaseRealm to authenticate users
+ -->
+ <Resource name="UserDatabase" auth="Container"
+ type="org.apache.catalina.UserDatabase"
+ description="User database that can be updated and saved"
+ factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
+ pathname="conf/tomcat-users.xml" />
+ </GlobalNamingResources>
+
+ <!-- A "Service" is a collection of one or more "Connectors" that share
+ a single "Container" Note: A "Service" is not itself a "Container",
+ so you may not define subcomponents such as "Valves" at this level.
+ Documentation at /docs/config/service.html
+ -->
+ <Service name="Catalina">
+
+ <!--The connectors can use a shared executor, you can define one or more named thread pools-->
+ <!--
+ <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
+ maxThreads="150" minSpareThreads="4"/>
+ -->
+
+
+ <!-- A "Connector" represents an endpoint by which requests are received
+ and responses are returned. Documentation at :
+ Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
+ Java AJP Connector: /docs/config/ajp.html
+ APR (HTTP/AJP) Connector: /docs/apr.html
+ Define a non-SSL HTTP/1.1 Connector on port 8080
+ -->
+
+ [PKI_UNSECURE_PORT_SERVER_COMMENT]
+ <Connector name="[PKI_UNSECURE_PORT_CONNECTOR_NAME]" port="[PKI_UNSECURE_PORT]" protocol="HTTP/1.1" redirectPort="8443"
+ maxHttpHeaderSize="8192"
+ acceptCount="100" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+ enableLookups="false" connectionTimeout="20000" disableUploadTimeout="true"
+ />
+
+ <!-- Define a SSL HTTP/1.1 Connector on port 8443 -->
+ [PKI_SECURE_PORT_SERVER_COMMENT]
+ <!-- DO NOT REMOVE - Begin define PKI secure port
+ NOTE: The OCSP settings take effect globally, so it should only be set once.
+
+ In setup where SSL clientAuth="true", OCSP can be turned on by
+ setting enableOCSP to true like the following:
+ enableOCSP="true"
+ along with changes to related settings, especially:
+ ocspResponderURL=<see example in connector definition below>
+ ocspResponderCertNickname=<see example in connector definition below>
+ Here are the definition to all the OCSP-related settings:
+ enableOCSP - turns on/off the ocsp check
+ ocspResponderURL - sets the url where the ocsp requests are sent
+ ocspResponderCertNickname - sets the nickname of the cert that is
+ either CA's signing certificate or the OCSP server's signing
+ certificate.
+ The CA's signing certificate should already be in the db, in
+ case of the same security domain.
+ In case of an ocsp signing certificate, one must import the cert
+ into the subsystem's nss db and set trust. e.g.:
+ certutil -d . -A -n "ocspSigningCert cert-pki-ca" -t "C,," -a -i ocspCert.b64
+ ocspCacheSize - sets max cache entries
+ ocspMinCacheEntryDuration - sets minimum seconds to next fetch attempt
+ ocspMaxCacheEntryDuration - sets maximum seconds to next fetch attempt
+ ocspTimeout -sets OCSP timeout in seconds
+ -->
+ <Connector name="[PKI_SECURE_PORT_CONNECTOR_NAME]" port="[PKI_SECURE_PORT]" protocol="HTTP/1.1" SSLEnabled="true" sslProtocol="SSL" scheme="https" secure="true"
+ maxHttpHeaderSize="8192"
+ acceptCount="100" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+ enableLookups="false" disableUploadTimeout="true"
+ SSLImplementation="org.apache.tomcat.util.net.jss.JSSImplementation"
+ enableOCSP="false"
+ ocspResponderURL="http://[PKI_MACHINE_NAME]:9080/ca/ocsp"
+ ocspResponderCertNickname="ocspSigningCert cert-pki-ca"
+ ocspCacheSize="1000"
+ ocspMinCacheEntryDuration="60"
+ ocspMaxCacheEntryDuration="120"
+ ocspTimeout="10"
+ strictCiphers="false"
+ clientAuth="[PKI_AGENT_CLIENTAUTH]"
+ sslOptions="[TOMCAT_SSL_OPTIONS]"
+ ssl2Ciphers="[TOMCAT_SSL2_CIPHERS]"
+ ssl3Ciphers="[TOMCAT_SSL3_CIPHERS]"
+ tlsCiphers="[TOMCAT_TLS_CIPHERS]"
+ serverCertNickFile="[PKI_INSTANCE_PATH]/conf/serverCertNick.conf"
+ passwordFile="[PKI_INSTANCE_PATH]/conf/password.conf"
+ passwordClass="org.apache.tomcat.util.net.jss.PlainPasswordFile"
+ certdbDir="[PKI_INSTANCE_PATH]/alias"
+ />
+ <!-- DO NOT REMOVE - End define PKI secure port -->
+
+ [PKI_OPEN_SEPARATE_PORTS_SERVER_COMMENT][PKI_ADMIN_SECURE_PORT_SERVER_COMMENT]
+ <Connector name="[PKI_ADMIN_SECURE_PORT_CONNECTOR_NAME]" port="[PKI_ADMIN_SECURE_PORT]" SSLEnabled="true" sslProtocol="SSL" scheme="https" secure="true"
+ maxHttpHeaderSize="8192"
+ acceptCount="100" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+ enableLookups="false" disableUploadTimeout="true"
+ SSLImplementation="org.apache.tomcat.util.net.jss.JSSImplementation"
+ strictCiphers="false"
+ clientAuth="false"
+ sslOptions="[TOMCAT_SSL_OPTIONS]"
+ ssl2Ciphers="[TOMCAT_SSL2_CIPHERS]"
+ ssl3Ciphers="[TOMCAT_SSL3_CIPHERS]"
+ tlsCiphers="[TOMCAT_TLS_CIPHERS]"
+ serverCertNickFile="[PKI_INSTANCE_PATH]/conf/serverCertNick.conf"
+ passwordFile="[PKI_INSTANCE_PATH]/conf/password.conf"
+ passwordClass="org.apache.tomcat.util.net.jss.PlainPasswordFile"
+ certdbDir="[PKI_INSTANCE_PATH]/alias"/>
+ [PKI_CLOSE_SEPARATE_PORTS_SERVER_COMMENT]
+
+ [PKI_OPEN_SEPARATE_PORTS_SERVER_COMMENT][PKI_EE_SECURE_PORT_SERVER_COMMENT]
+ <Connector name="[PKI_EE_SECURE_PORT_CONNECTOR_NAME]" port="[PKI_EE_SECURE_PORT]" SSLEnabled="true" sslProtocol="SSL" scheme="https" secure="true"
+ maxHttpHeaderSize="8192"
+ acceptCount="100" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+ enableLookups="false" disableUploadTimeout="true"
+ SSLImplementation="org.apache.tomcat.util.net.jss.JSSImplementation"
+ strictCiphers="false"
+ clientAuth="false"
+ sslOptions="[TOMCAT_SSL_OPTIONS]"
+ ssl2Ciphers="[TOMCAT_SSL2_CIPHERS]"
+ ssl3Ciphers="[TOMCAT_SSL3_CIPHERS]"
+ tlsCiphers="[TOMCAT_TLS_CIPHERS]"
+ serverCertNickFile="[PKI_INSTANCE_PATH]/conf/serverCertNick.conf"
+ passwordFile="[PKI_INSTANCE_PATH]/conf/password.conf"
+ passwordClass="org.apache.tomcat.util.net.jss.PlainPasswordFile"
+ certdbDir="[PKI_INSTANCE_PATH]/alias"/>
+ [PKI_CLOSE_SEPARATE_PORTS_SERVER_COMMENT]
+
+ <!-- A "Connector" using the shared thread pool-->
+ <!--
+ <Connector executor="tomcatThreadPool"
+ port="8080" protocol="HTTP/1.1"
+ connectionTimeout="20000"
+ redirectPort="8443" />
+ -->
+ <!-- Define a SSL HTTP/1.1 Connector on port 8443
+ This connector uses the JSSE configuration, when using APR, the
+ connector should be using the OpenSSL style configuration
+ described in the APR documentation -->
+ <!--
+ <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
+ maxThreads="150" scheme="https" secure="true"
+ clientAuth="false" sslProtocol="TLS" />
+ -->
+
+ <!-- Define an AJP 1.3 Connector on port [PKI_AJP_PORT] -->
+[PKI_OPEN_AJP_PORT_COMMENT]
+ <Connector port="[PKI_AJP_PORT]" protocol="AJP/1.3" redirectPort="[PKI_AJP_REDIRECT_PORT]" />
+[PKI_CLOSE_AJP_PORT_COMMENT]
+
+
+ <!-- An Engine represents the entry point (within Catalina) that processes
+ every request. The Engine implementation for Tomcat stand alone
+ analyzes the HTTP headers included with the request, and passes them
+ on to the appropriate Host (virtual host).
+ Documentation at /docs/config/engine.html -->
+
+ <!-- You should set jvmRoute to support load-balancing via AJP ie :
+ <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
+ -->
+ <Engine name="Catalina" defaultHost="localhost">
+
+ <!--For clustering, please take a look at documentation at:
+ /docs/cluster-howto.html (simple how to)
+ /docs/config/cluster.html (reference documentation) -->
+ <!--
+ <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
+ -->
+
+ <!-- The request dumper valve dumps useful debugging information about
+ the request and response data received and sent by Tomcat.
+ Documentation at: /docs/config/valve.html -->
+ <!--
+ <Valve className="org.apache.catalina.valves.RequestDumperValve"/>
+ -->
+
+ <!-- This Realm uses the UserDatabase configured in the global JNDI
+ resources under the key "UserDatabase". Any edits
+ that are performed against this UserDatabase are immediately
+ available for use by the Realm. -->
+ <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+ resourceName="UserDatabase"/>
+
+ <!-- Define the default virtual host
+ Note: XML Schema validation will not work with Xerces 2.2.
+ -->
+ <Host name="localhost" appBase="webapps"
+ unpackWARs="true" autoDeploy="false"
+ xmlValidation="false" xmlNamespaceAware="false">
+
+ <!-- SingleSignOn valve, share authentication between web applications
+ Documentation at: /docs/config/valve.html -->
+ <!--
+ <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
+ -->
+
+ <!-- Access log processes all example.
+ Documentation at: /docs/config/valve.html -->
+ <!--
+ <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
+ prefix="localhost_access_log." suffix=".txt" pattern="common" resolveHosts="false"/>
+ -->
+
+ </Host>
+ </Engine>
+ </Service>
+</Server>
diff --git a/base/ocsp/shared/conf/serverCertNick.conf b/base/ocsp/shared/conf/serverCertNick.conf
new file mode 100644
index 000000000..2233ada52
--- /dev/null
+++ b/base/ocsp/shared/conf/serverCertNick.conf
@@ -0,0 +1,6 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+Server-Cert cert-[PKI_INSTANCE_ID]
diff --git a/base/ocsp/shared/conf/shm.manifest b/base/ocsp/shared/conf/shm.manifest
new file mode 100644
index 000000000..0505c085b
--- /dev/null
+++ b/base/ocsp/shared/conf/shm.manifest
@@ -0,0 +1,2 @@
+Main-Class: org.apache.jk.common.Shm
+Class-Path: tomcat-jk2.jar commons-logging.jar tomcat-util.jar log4j.jar log4j-core.jar
diff --git a/base/ocsp/shared/conf/tomcat-jk2.manifest b/base/ocsp/shared/conf/tomcat-jk2.manifest
new file mode 100644
index 000000000..acfef4a90
--- /dev/null
+++ b/base/ocsp/shared/conf/tomcat-jk2.manifest
@@ -0,0 +1,7 @@
+Manifest-version: 1.0
+Extension-Name: org.apache.jk
+Specification-Vendor: Apache Software Foundation
+Specification-Version: 2.0
+Implementation-Vendor-Id: org.apache
+Implementation-Vendor: Apache Software Foundation
+Implementation-Version: 2.1
diff --git a/base/ocsp/shared/conf/tomcat-users.xml b/base/ocsp/shared/conf/tomcat-users.xml
new file mode 100644
index 000000000..daa9260cc
--- /dev/null
+++ b/base/ocsp/shared/conf/tomcat-users.xml
@@ -0,0 +1,45 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2006-2010 Red Hat, Inc.
+ All rights reserved.
+ Modifications: configuration parameters
+ END COPYRIGHT BLOCK -->
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+ <role rolename="tomcat"/>
+ <role rolename="role1"/>
+ <user username="tomcat" password="tomcat" roles="tomcat"/>
+ <user username="both" password="tomcat" roles="tomcat,role1"/>
+ <user username="role1" password="tomcat" roles="role1"/>
+-->
+
+<!-- The host manager webapp is restricted to users with role "admin" -->
+<!--<user name="tomcat" password="password" roles="admin" />-->
+<!-- The manager webapp is restricted to users with role "manager" -->
+<!--<user name="tomcat" password="password" roles="manager" />-->
+<tomcat-users>
+ <role rolename="pkiuser"/>
+ <role rolename="tomcat"/>
+ <role rolename="manager"/>
+ <role rolename="admin"/>
+
+ <user username="pkiuser" password="pkiuser" roles="pkiuser"/>
+ <user username="tomcat" password="tomcat" roles="tomcat"/>
+ <user username="admin" password="netscape" roles="admin,manager"/>
+</tomcat-users>
diff --git a/base/ocsp/shared/conf/tomcat6.conf b/base/ocsp/shared/conf/tomcat6.conf
new file mode 100644
index 000000000..2d7def5ec
--- /dev/null
+++ b/base/ocsp/shared/conf/tomcat6.conf
@@ -0,0 +1,58 @@
+# Service-specific configuration file for tomcat6. This will be sourced by
+# the SysV init script after the global configuration file
+# /etc/tomcat6/tomcat6.conf, thus allowing values to be overridden in
+# a per-service manner.
+#
+# NEVER change the init script itself. To change values for all services make
+# your changes in /etc/tomcat6/tomcat6.conf
+#
+# To change values for a specific service make your edits here.
+# To create a new service create a link from /etc/init.d/<your new service> to
+# /etc/init.d/tomcat6 (do not copy the init script) and make a copy of the
+# /etc/sysconfig/tomcat6 file to /etc/sysconfig/<your new service> and change
+# the property values so the two services won't conflict. Register the new
+# service in the system as usual (see chkconfig and similars).
+#
+
+# Where your java installation lives
+#JAVA_HOME="/usr/lib/jvm/java"
+
+# Where your tomcat installation lives
+CATALINA_BASE="[PKI_INSTANCE_PATH]"
+#CATALINA_HOME="/usr/share/tomcat6"
+#JASPER_HOME="/usr/share/tomcat6"
+#CATALINA_TMPDIR="/var/cache/tomcat6/temp"
+
+# You can pass some parameters to java here if you wish to
+#JAVA_OPTS="-Xminf0.1 -Xmaxf0.3"
+
+# Use JAVA_OPTS to set java.library.path for libtcnative.so
+#JAVA_OPTS="-Djava.library.path=/usr/lib64"
+
+# What user should run tomcat
+TOMCAT_USER="[PKI_USER]"
+
+# You can change your tomcat locale here
+#LANG="en_US"
+
+# Run tomcat under the Java Security Manager
+#SECURITY_MANAGER="false"
+
+# Time to wait in seconds, before killing process
+#SHUTDOWN_WAIT="30"
+
+# Whether to annoy the user with "attempting to shut down" messages or not
+#SHUTDOWN_VERBOSE="false"
+
+# Set the TOMCAT_PID location
+CATALINA_PID="[TOMCAT_PIDFILE]"
+
+# Set the tomcat log file
+TOMCAT_LOG="[TOMCAT_LOG_DIR]/tomcat-initd.log"
+
+# Connector port is 8080 for this tomcat6 instance
+#CONNECTOR_PORT="8080"
+
+# If you wish to further customize your tomcat environment,
+# put your own definitions here
+# (i.e. LD_LIBRARY_PATH for some jdbc drivers)
diff --git a/base/ocsp/shared/conf/uriworkermap.properties b/base/ocsp/shared/conf/uriworkermap.properties
new file mode 100644
index 000000000..c89dd82a6
--- /dev/null
+++ b/base/ocsp/shared/conf/uriworkermap.properties
@@ -0,0 +1,18 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+# uriworkermap.properties - IIS
+#
+# This file provides sample mappings for example ajp13w
+# worker defined in workermap.properties.minimal
+# The general sytax for this file is:
+# [URL]=[Worker name]
+
+/servlet-examples/*=ajp13w
+
+# Optionally filter out all .jpeg files inside that context
+# For no mapping the url has to start with exclamation (!)
+
+!/servlet-examples/*.jpeg=ajp13w
diff --git a/base/ocsp/shared/conf/web.xml b/base/ocsp/shared/conf/web.xml
new file mode 100644
index 000000000..860a9c4af
--- /dev/null
+++ b/base/ocsp/shared/conf/web.xml
@@ -0,0 +1,993 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2006 Red Hat, Inc.
+ All rights reserved.
+ END COPYRIGHT BLOCK -->
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+ version="2.4">
+
+ <!-- ======================== Introduction ============================== -->
+ <!-- This document defines default values for *all* web applications -->
+ <!-- loaded into this instance of Tomcat. As each application is -->
+ <!-- deployed, this file is processed, followed by the -->
+ <!-- "/WEB-INF/web.xml" deployment descriptor from your own -->
+ <!-- applications. -->
+ <!-- -->
+ <!-- WARNING: Do not configure application-specific resources here! -->
+ <!-- They should go in the "/WEB-INF/web.xml" file in your application. -->
+
+
+ <!-- ================== Built In Servlet Definitions ==================== -->
+
+
+ <!-- The default servlet for all web applications, that serves static -->
+ <!-- resources. It processes all requests that are not mapped to other -->
+ <!-- servlets with servlet mappings (defined either here or in your own -->
+ <!-- web.xml file. This servlet supports the following initialization -->
+ <!-- parameters (default values are in square brackets): -->
+ <!-- -->
+ <!-- debug Debugging detail level for messages logged -->
+ <!-- by this servlet. [0] -->
+ <!-- -->
+ <!-- fileEncoding Encoding to be used to read static resources -->
+ <!-- [platform default] -->
+ <!-- -->
+ <!-- input Input buffer size (in bytes) when reading -->
+ <!-- resources to be served. [2048] -->
+ <!-- -->
+ <!-- listings Should directory listings be produced if there -->
+ <!-- is no welcome file in this directory? [true] -->
+ <!-- -->
+ <!-- output Output buffer size (in bytes) when writing -->
+ <!-- resources to be served. [2048] -->
+ <!-- -->
+ <!-- readonly Is this context "read only", so HTTP -->
+ <!-- commands like PUT and DELETE are -->
+ <!-- rejected? [true] -->
+ <!-- -->
+ <!-- readmeFile File name to display with the directory -->
+ <!-- contents. [null] -->
+ <!-- -->
+ <!-- For directory listing customization. Checks localXsltFile, then -->
+ <!-- globalXsltFile, then defaults to original behavior. -->
+ <!-- -->
+ <!-- localXsltFile Make directory listings an XML doc and -->
+ <!-- pass the result to this style sheet residing -->
+ <!-- in that directory. This overrides -->
+ <!-- globalXsltFile[null] -->
+ <!-- -->
+ <!-- globalXsltFile Site wide configuration version of -->
+ <!-- localXsltFile This argument is expected -->
+ <!-- to be a physical file. [null] -->
+ <!-- -->
+ <!-- -->
+
+ <servlet>
+ <servlet-name>default</servlet-name>
+ <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
+ <init-param>
+ <param-name>debug</param-name>
+ <param-value>0</param-value>
+ </init-param>
+ <init-param>
+ <param-name>listings</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+
+ <!-- The "invoker" servlet, which executes anonymous servlet classes -->
+ <!-- that have not been defined in a web.xml file. Traditionally, this -->
+ <!-- servlet is mapped to the URL pattern "/servlet/*", but you can map -->
+ <!-- it to other patterns as well. The extra path info portion of such a -->
+ <!-- request must be the fully qualified class name of a Java class that -->
+ <!-- implements Servlet (or extends HttpServlet), or the servlet name -->
+ <!-- of an existing servlet definition. This servlet supports the -->
+ <!-- following initialization parameters (default values are in square -->
+ <!-- brackets): -->
+ <!-- -->
+ <!-- debug Debugging detail level for messages logged -->
+ <!-- by this servlet. [0] -->
+
+<!--
+ <servlet>
+ <servlet-name>invoker</servlet-name>
+ <servlet-class>
+ org.apache.catalina.servlets.InvokerServlet
+ </servlet-class>
+ <init-param>
+ <param-name>debug</param-name>
+ <param-value>0</param-value>
+ </init-param>
+ <load-on-startup>2</load-on-startup>
+ </servlet>
+-->
+
+
+ <!-- The JSP page compiler and execution servlet, which is the mechanism -->
+ <!-- used by Tomcat to support JSP pages. Traditionally, this servlet -->
+ <!-- is mapped to the URL pattern "*.jsp". This servlet supports the -->
+ <!-- following initialization parameters (default values are in square -->
+ <!-- brackets): -->
+ <!-- -->
+ <!-- checkInterval If development is false and checkInterval is -->
+ <!-- greater than zero, background compilations are -->
+ <!-- enabled. checkInterval is the time in seconds -->
+ <!-- between checks to see if a JSP page needs to -->
+ <!-- be recompiled. [0] -->
+ <!-- -->
+ <!-- modificationTestInterval -->
+ <!-- Causes a JSP (and its dependent files) to not -->
+ <!-- be checked for modification during the -->
+ <!-- specified time interval (in seconds) from the -->
+ <!-- last time the JSP was checked for -->
+ <!-- modification. A value of 0 will cause the JSP -->
+ <!-- to be checked on every access. -->
+ <!-- Used in development mode only. [4] -->
+ <!-- -->
+ <!-- compiler Which compiler Ant should use to compile JSP -->
+ <!-- pages. See the Ant documentation for more -->
+ <!-- information. [javac] -->
+ <!-- -->
+ <!-- classdebuginfo Should the class file be compiled with -->
+ <!-- debugging information? [true] -->
+ <!-- -->
+ <!-- classpath What class path should I use while compiling -->
+ <!-- generated servlets? [Created dynamically -->
+ <!-- based on the current web application] -->
+ <!-- -->
+ <!-- development Is Jasper used in development mode? If true, -->
+ <!-- the frequency at which JSPs are checked for -->
+ <!-- modification may be specified via the -->
+ <!-- modificationTestInterval parameter. [true] -->
+ <!-- -->
+ <!-- enablePooling Determines whether tag handler pooling is -->
+ <!-- enabled [true] -->
+ <!-- -->
+ <!-- fork Tell Ant to fork compiles of JSP pages so that -->
+ <!-- a separate JVM is used for JSP page compiles -->
+ <!-- from the one Tomcat is running in. [true] -->
+ <!-- -->
+ <!-- ieClassId The class-id value to be sent to Internet -->
+ <!-- Explorer when using <jsp:plugin> tags. -->
+ <!-- [clsid:8AD9C840-044E-11D1-B3E9-00805F499D93] -->
+ <!-- -->
+ <!-- javaEncoding Java file encoding to use for generating java -->
+ <!-- source files. [UTF8] -->
+ <!-- -->
+ <!-- keepgenerated Should we keep the generated Java source code -->
+ <!-- for each page instead of deleting it? [true] -->
+ <!-- -->
+ <!-- mappedfile Should we generate static content with one -->
+ <!-- print statement per input line, to ease -->
+ <!-- debugging? [true] -->
+ <!-- -->
+ <!-- trimSpaces Should white spaces in template text between -->
+ <!-- actions or directives be trimmed? [false] -->
+ <!-- -->
+ <!-- suppressSmap Should the generation of SMAP info for JSR45 -->
+ <!-- debugging be suppressed? [false] -->
+ <!-- -->
+ <!-- dumpSmap Should the SMAP info for JSR45 debugging be -->
+ <!-- dumped to a file? [false] -->
+ <!-- False if suppressSmap is true -->
+ <!-- -->
+ <!-- genStrAsCharArray Should text strings be generated as char -->
+ <!-- arrays, to improve performance in some cases? -->
+ <!-- [false] -->
+ <!-- -->
+ <!-- errorOnUseBeanInvalidClassAttribute -->
+ <!-- Should Jasper issue an error when the value of -->
+ <!-- the class attribute in an useBean action is -->
+ <!-- not a valid bean class? [true] -->
+ <!-- -->
+ <!-- scratchdir What scratch directory should we use when -->
+ <!-- compiling JSP pages? [default work directory -->
+ <!-- for the current web application] -->
+ <!-- -->
+ <!-- xpoweredBy Determines whether X-Powered-By response -->
+ <!-- header is added by generated servlet [false] -->
+ <!-- -->
+ <!-- If you wish to use Jikes to compile JSP pages: -->
+ <!-- Please see the "Using Jikes" section of the Jasper-HowTo -->
+ <!-- page in the Tomcat documentation. -->
+
+ <servlet>
+ <servlet-name>jsp</servlet-name>
+ <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
+ <init-param>
+ <param-name>fork</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ <init-param>
+ <param-name>xpoweredBy</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ <load-on-startup>3</load-on-startup>
+ </servlet>
+
+
+ <!-- Server Side Includes processing servlet, which processes SSI -->
+ <!-- directives in HTML pages consistent with similar support in web -->
+ <!-- servers like Apache. Traditionally, this servlet is mapped to the -->
+ <!-- URL pattern "*.shtml". This servlet supports the following -->
+ <!-- initialization parameters (default values are in square brackets): -->
+ <!-- -->
+ <!-- buffered Should output from this servlet be buffered? -->
+ <!-- (0=false, 1=true) [0] -->
+ <!-- -->
+ <!-- debug Debugging detail level for messages logged -->
+ <!-- by this servlet. [0] -->
+ <!-- -->
+ <!-- expires The number of seconds before a page with SSI -->
+ <!-- directives will expire. [No default] -->
+ <!-- -->
+ <!-- isVirtualWebappRelative -->
+ <!-- Should "virtual" paths be interpreted as -->
+ <!-- relative to the context root, instead of -->
+ <!-- the server root? (0=false, 1=true) [0] -->
+ <!-- -->
+ <!-- -->
+ <!-- IMPORTANT: To use the SSI servlet, you also need to rename the -->
+ <!-- $CATALINA_HOME/server/lib/servlets-ssi.renametojar file -->
+ <!-- to $CATALINA_HOME/server/lib/servlets-ssi.jar -->
+
+<!--
+ <servlet>
+ <servlet-name>ssi</servlet-name>
+ <servlet-class>
+ org.apache.catalina.ssi.SSIServlet
+ </servlet-class>
+ <init-param>
+ <param-name>buffered</param-name>
+ <param-value>1</param-value>
+ </init-param>
+ <init-param>
+ <param-name>debug</param-name>
+ <param-value>0</param-value>
+ </init-param>
+ <init-param>
+ <param-name>expires</param-name>
+ <param-value>666</param-value>
+ </init-param>
+ <init-param>
+ <param-name>isVirtualWebappRelative</param-name>
+ <param-value>0</param-value>
+ </init-param>
+ <load-on-startup>4</load-on-startup>
+ </servlet>
+-->
+
+
+ <!-- Common Gateway Includes (CGI) processing servlet, which supports -->
+ <!-- execution of external applications that conform to the CGI spec -->
+ <!-- requirements. Typically, this servlet is mapped to the URL pattern -->
+ <!-- "/cgi-bin/*", which means that any CGI applications that are -->
+ <!-- executed must be present within the web application. This servlet -->
+ <!-- supports the following initialization parameters (default values -->
+ <!-- are in square brackets): -->
+ <!-- -->
+ <!-- cgiPathPrefix The CGI search path will start at -->
+ <!-- webAppRootDir + File.separator + this prefix. -->
+ <!-- [WEB-INF/cgi] -->
+ <!-- -->
+ <!-- debug Debugging detail level for messages logged -->
+ <!-- by this servlet. [0] -->
+ <!-- -->
+ <!-- executable Name of the exectuable used to run the -->
+ <!-- script. [perl] -->
+ <!-- -->
+ <!-- parameterEncoding Name of parameter encoding to be used with -->
+ <!-- CGI servlet. -->
+ <!-- [System.getProperty("file.encoding","UTF-8")] -->
+ <!-- -->
+ <!-- passShellEnvironment Should the shell environment variables (if -->
+ <!-- any) be passed to the CGI script? [false] -->
+ <!-- -->
+ <!-- IMPORTANT: To use the CGI servlet, you also need to rename the -->
+ <!-- $CATALINA_HOME/server/lib/servlets-cgi.renametojar file -->
+ <!-- to $CATALINA_HOME/server/lib/servlets-cgi.jar -->
+
+<!--
+ <servlet>
+ <servlet-name>cgi</servlet-name>
+ <servlet-class>org.apache.catalina.servlets.CGIServlet</servlet-class>
+ <init-param>
+ <param-name>debug</param-name>
+ <param-value>6</param-value>
+ </init-param>
+ <init-param>
+ <param-name>cgiPathPrefix</param-name>
+ <param-value>WEB-INF/cgi</param-value>
+ </init-param>
+ <load-on-startup>5</load-on-startup>
+ </servlet>
+-->
+
+
+ <!-- ================ Built In Servlet Mappings ========================= -->
+
+
+ <!-- The servlet mappings for the built in servlets defined above. Note -->
+ <!-- that, by default, the CGI and SSI servlets are *not* mapped. You -->
+ <!-- must uncomment these mappings (or add them to your application's own -->
+ <!-- web.xml deployment descriptor) to enable these services -->
+
+ <!-- The mapping for the default servlet -->
+ <servlet-mapping>
+ <servlet-name>default</servlet-name>
+ <url-pattern>/</url-pattern>
+ </servlet-mapping>
+
+ <!-- The mapping for the invoker servlet -->
+<!--
+ <servlet-mapping>
+ <servlet-name>invoker</servlet-name>
+ <url-pattern>/servlet/*</url-pattern>
+ </servlet-mapping>
+-->
+
+ <!-- The mapping for the JSP servlet -->
+ <servlet-mapping>
+ <servlet-name>jsp</servlet-name>
+ <url-pattern>*.jsp</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>jsp</servlet-name>
+ <url-pattern>*.jspx</url-pattern>
+ </servlet-mapping>
+
+ <!-- The mapping for the SSI servlet -->
+<!--
+ <servlet-mapping>
+ <servlet-name>ssi</servlet-name>
+ <url-pattern>*.shtml</url-pattern>
+ </servlet-mapping>
+-->
+
+ <!-- The mapping for the CGI Gateway servlet -->
+
+<!--
+ <servlet-mapping>
+ <servlet-name>cgi</servlet-name>
+ <url-pattern>/cgi-bin/*</url-pattern>
+ </servlet-mapping>
+-->
+
+
+ <!-- ==================== Default Session Configuration ================= -->
+ <!-- You can set the default session timeout (in minutes) for all newly -->
+ <!-- created sessions by modifying the value below. -->
+
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+
+
+ <!-- ===================== Default MIME Type Mappings =================== -->
+ <!-- When serving static resources, Tomcat will automatically generate -->
+ <!-- a "Content-Type" header based on the resource's filename extension, -->
+ <!-- based on these mappings. Additional mappings can be added here (to -->
+ <!-- apply to all web applications), or in your own application's web.xml -->
+ <!-- deployment descriptor. -->
+
+ <mime-mapping>
+ <extension>abs</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ai</extension>
+ <mime-type>application/postscript</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>aif</extension>
+ <mime-type>audio/x-aiff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>aifc</extension>
+ <mime-type>audio/x-aiff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>aiff</extension>
+ <mime-type>audio/x-aiff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>aim</extension>
+ <mime-type>application/x-aim</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>art</extension>
+ <mime-type>image/x-jg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>asf</extension>
+ <mime-type>video/x-ms-asf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>asx</extension>
+ <mime-type>video/x-ms-asf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>au</extension>
+ <mime-type>audio/basic</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>avi</extension>
+ <mime-type>video/x-msvideo</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>avx</extension>
+ <mime-type>video/x-rad-screenplay</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>bcpio</extension>
+ <mime-type>application/x-bcpio</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>bin</extension>
+ <mime-type>application/octet-stream</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>bmp</extension>
+ <mime-type>image/bmp</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>body</extension>
+ <mime-type>text/html</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>cdf</extension>
+ <mime-type>application/x-cdf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>cer</extension>
+ <mime-type>application/x-x509-ca-cert</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>class</extension>
+ <mime-type>application/java</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>cpio</extension>
+ <mime-type>application/x-cpio</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>csh</extension>
+ <mime-type>application/x-csh</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>css</extension>
+ <mime-type>text/css</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>dib</extension>
+ <mime-type>image/bmp</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>doc</extension>
+ <mime-type>application/msword</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>dtd</extension>
+ <mime-type>application/xml-dtd</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>dv</extension>
+ <mime-type>video/x-dv</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>dvi</extension>
+ <mime-type>application/x-dvi</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>eps</extension>
+ <mime-type>application/postscript</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>etx</extension>
+ <mime-type>text/x-setext</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>exe</extension>
+ <mime-type>application/octet-stream</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>gif</extension>
+ <mime-type>image/gif</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>gtar</extension>
+ <mime-type>application/x-gtar</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>gz</extension>
+ <mime-type>application/x-gzip</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>hdf</extension>
+ <mime-type>application/x-hdf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>hqx</extension>
+ <mime-type>application/mac-binhex40</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>htc</extension>
+ <mime-type>text/x-component</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>htm</extension>
+ <mime-type>text/html</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>html</extension>
+ <mime-type>text/html</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>hqx</extension>
+ <mime-type>application/mac-binhex40</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ief</extension>
+ <mime-type>image/ief</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jad</extension>
+ <mime-type>text/vnd.sun.j2me.app-descriptor</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jar</extension>
+ <mime-type>application/java-archive</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>java</extension>
+ <mime-type>text/plain</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jnlp</extension>
+ <mime-type>application/x-java-jnlp-file</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jpe</extension>
+ <mime-type>image/jpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jpeg</extension>
+ <mime-type>image/jpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jpg</extension>
+ <mime-type>image/jpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>js</extension>
+ <mime-type>text/javascript</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jsf</extension>
+ <mime-type>text/plain</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jspf</extension>
+ <mime-type>text/plain</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>kar</extension>
+ <mime-type>audio/x-midi</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>latex</extension>
+ <mime-type>application/x-latex</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>m3u</extension>
+ <mime-type>audio/x-mpegurl</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mac</extension>
+ <mime-type>image/x-macpaint</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>man</extension>
+ <mime-type>application/x-troff-man</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mathml</extension>
+ <mime-type>application/mathml+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>me</extension>
+ <mime-type>application/x-troff-me</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mid</extension>
+ <mime-type>audio/x-midi</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>midi</extension>
+ <mime-type>audio/x-midi</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mif</extension>
+ <mime-type>application/x-mif</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mov</extension>
+ <mime-type>video/quicktime</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>movie</extension>
+ <mime-type>video/x-sgi-movie</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mp1</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mp2</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mp3</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpa</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpe</extension>
+ <mime-type>video/mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpeg</extension>
+ <mime-type>video/mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpega</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpg</extension>
+ <mime-type>video/mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpv2</extension>
+ <mime-type>video/mpeg2</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ms</extension>
+ <mime-type>application/x-wais-source</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>nc</extension>
+ <mime-type>application/x-netcdf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>oda</extension>
+ <mime-type>application/oda</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ogg</extension>
+ <mime-type>application/ogg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pbm</extension>
+ <mime-type>image/x-portable-bitmap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pct</extension>
+ <mime-type>image/pict</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pdf</extension>
+ <mime-type>application/pdf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pgm</extension>
+ <mime-type>image/x-portable-graymap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pic</extension>
+ <mime-type>image/pict</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pict</extension>
+ <mime-type>image/pict</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pls</extension>
+ <mime-type>audio/x-scpls</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>png</extension>
+ <mime-type>image/png</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pnm</extension>
+ <mime-type>image/x-portable-anymap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pnt</extension>
+ <mime-type>image/x-macpaint</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ppm</extension>
+ <mime-type>image/x-portable-pixmap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ppt</extension>
+ <mime-type>application/powerpoint</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ps</extension>
+ <mime-type>application/postscript</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>psd</extension>
+ <mime-type>image/x-photoshop</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>qt</extension>
+ <mime-type>video/quicktime</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>qti</extension>
+ <mime-type>image/x-quicktime</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>qtif</extension>
+ <mime-type>image/x-quicktime</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ras</extension>
+ <mime-type>image/x-cmu-raster</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>rdf</extension>
+ <mime-type>application/rdf+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>rgb</extension>
+ <mime-type>image/x-rgb</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>rm</extension>
+ <mime-type>application/vnd.rn-realmedia</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>roff</extension>
+ <mime-type>application/x-troff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>rtf</extension>
+ <mime-type>application/rtf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>rtx</extension>
+ <mime-type>text/richtext</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>sh</extension>
+ <mime-type>application/x-sh</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>shar</extension>
+ <mime-type>application/x-shar</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>smf</extension>
+ <mime-type>audio/x-midi</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>sit</extension>
+ <mime-type>application/x-stuffit</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>snd</extension>
+ <mime-type>audio/basic</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>src</extension>
+ <mime-type>application/x-wais-source</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>sv4cpio</extension>
+ <mime-type>application/x-sv4cpio</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>sv4crc</extension>
+ <mime-type>application/x-sv4crc</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>svg</extension>
+ <mime-type>image/svg+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>swf</extension>
+ <mime-type>application/x-shockwave-flash</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>t</extension>
+ <mime-type>application/x-troff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tar</extension>
+ <mime-type>application/x-tar</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tcl</extension>
+ <mime-type>application/x-tcl</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tex</extension>
+ <mime-type>application/x-tex</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>texi</extension>
+ <mime-type>application/x-texinfo</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>texinfo</extension>
+ <mime-type>application/x-texinfo</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tif</extension>
+ <mime-type>image/tiff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tiff</extension>
+ <mime-type>image/tiff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tr</extension>
+ <mime-type>application/x-troff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tsv</extension>
+ <mime-type>text/tab-separated-values</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>txt</extension>
+ <mime-type>text/plain</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ulw</extension>
+ <mime-type>audio/basic</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ustar</extension>
+ <mime-type>application/x-ustar</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>vxml</extension>
+ <mime-type>application/voicexml+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xbm</extension>
+ <mime-type>image/x-xbitmap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xht</extension>
+ <mime-type>application/xhtml+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xhtml</extension>
+ <mime-type>application/xhtml+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xml</extension>
+ <mime-type>application/xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xpm</extension>
+ <mime-type>image/x-xpixmap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xsl</extension>
+ <mime-type>application/xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xslt</extension>
+ <mime-type>application/xslt+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xul</extension>
+ <mime-type>application/vnd.mozilla.xul+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xwd</extension>
+ <mime-type>image/x-xwindowdump</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>wav</extension>
+ <mime-type>audio/x-wav</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>svg</extension>
+ <mime-type>image/svg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>svgz</extension>
+ <mime-type>image/svg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>vsd</extension>
+ <mime-type>application/x-visio</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <!-- Wireless Bitmap -->
+ <extension>wbmp</extension>
+ <mime-type>image/vnd.wap.wbmp</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <!-- WML Source -->
+ <extension>wml</extension>
+ <mime-type>text/vnd.wap.wml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <!-- Compiled WML -->
+ <extension>wmlc</extension>
+ <mime-type>application/vnd.wap.wmlc</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <!-- WML Script Source -->
+ <extension>wmls</extension>
+ <mime-type>text/vnd.wap.wmlscript</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <!-- Compiled WML Script -->
+ <extension>wmlscriptc</extension>
+ <mime-type>application/vnd.wap.wmlscriptc</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>wrl</extension>
+ <mime-type>x-world/x-vrml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>Z</extension>
+ <mime-type>application/x-compress</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>z</extension>
+ <mime-type>application/x-compress</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>zip</extension>
+ <mime-type>application/zip</mime-type>
+ </mime-mapping>
+
+
+ <!-- ==================== Default Welcome File List ===================== -->
+ <!-- When a request URI refers to a directory, the default servlet looks -->
+ <!-- for a "welcome file" within that directory and, if present, -->
+ <!-- to the corresponding resource URI for display. If no welcome file -->
+ <!-- is present, the default servlet either serves a directory listing, -->
+ <!-- or returns a 404 status, depending on how it is configured. -->
+ <!-- -->
+ <!-- If you define welcome files in your own application's web.xml -->
+ <!-- deployment descriptor, that list *replaces* the list configured -->
+ <!-- here, so be sure that you include any of the default values that -->
+ <!-- you wish to include. -->
+
+ <welcome-file-list>
+ <welcome-file>index.html</welcome-file>
+ <welcome-file>index.htm</welcome-file>
+ <welcome-file>index.jsp</welcome-file>
+ </welcome-file-list>
+
+ <error-page>
+ <error-code>404</error-code>
+ <location>/404.html</location>
+ </error-page>
+
+ <error-page>
+ <error-code>500</error-code>
+ <location>/500.html</location>
+ </error-page>
+
+</web-app>
diff --git a/base/ocsp/shared/conf/workers.properties b/base/ocsp/shared/conf/workers.properties
new file mode 100644
index 000000000..2c39c6402
--- /dev/null
+++ b/base/ocsp/shared/conf/workers.properties
@@ -0,0 +1,211 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+# workers.properties -
+#
+# This file provides jk derived plugins with the needed information to
+# connect to the different tomcat workers. Note that the distributed
+# version of this file requires modification before it is usable by a
+# plugin.
+#
+# As a general note, the characters $( and ) are used internally to define
+# macros. Do not use them in your own configuration!!!
+#
+# Whenever you see a set of lines such as:
+# x=value
+# y=$(x)\something
+#
+# the final value for y will be value\something
+#
+# Normaly all you will need to do is un-comment and modify the first three
+# properties, i.e. workers.tomcat_home, workers.java_home and ps.
+# Most of the configuration is derived from these.
+#
+# When you are done updating workers.tomcat_home, workers.java_home and ps
+# you should have 3 workers configured:
+#
+# - An ajp12 worker that connects to localhost:8007
+# - An ajp13 worker that connects to localhost:8009
+# - A jni inprocess worker.
+# - A load balancer worker
+#
+# However by default the plugins will only use the ajp12 worker. To have
+# the plugins use other workers you should modify the worker.list property.
+#
+#
+
+# OPTIONS ( very important for jni mode )
+
+#
+# workers.tomcat_home should point to the location where you
+# installed tomcat. This is where you have your conf, webapps and lib
+# directories.
+#
+workers.tomcat_home=/var/tomcat3
+
+#
+# workers.java_home should point to your Java installation. Normally
+# you should have a bin and lib directories beneath it.
+#
+workers.java_home=/opt/IBMJava2-13
+
+#
+# You should configure your environment slash... ps=\ on NT and / on UNIX
+# and maybe something different elsewhere.
+#
+ps=/
+
+#
+#------ ADVANCED MODE ------------------------------------------------
+#---------------------------------------------------------------------
+#
+
+#
+#------ DEFAULT worket list ------------------------------------------
+#---------------------------------------------------------------------
+#
+#
+# The workers that your plugins should create and work with
+#
+# Add 'inprocess' if you want JNI connector
+worker.list=ajp12, ajp13
+# , inprocess
+
+
+#
+#------ DEFAULT ajp12 WORKER DEFINITION ------------------------------
+#---------------------------------------------------------------------
+#
+
+#
+# Defining a worker named ajp12 and of type ajp12
+# Note that the name and the type do not have to match.
+#
+worker.ajp12.port=8007
+worker.ajp12.host=localhost
+worker.ajp12.type=ajp12
+#
+# Specifies the load balance factor when used with
+# a load balancing worker.
+# Note:
+# ----> lbfactor must be > 0
+# ----> Low lbfactor means less work done by the worker.
+worker.ajp12.lbfactor=1
+
+#
+#------ DEFAULT ajp13 WORKER DEFINITION ------------------------------
+#---------------------------------------------------------------------
+#
+
+#
+# Defining a worker named ajp13 and of type ajp13
+# Note that the name and the type do not have to match.
+#
+worker.ajp13.port=8009
+worker.ajp13.host=localhost
+worker.ajp13.type=ajp13
+#
+# Specifies the load balance factor when used with
+# a load balancing worker.
+# Note:
+# ----> lbfactor must be > 0
+# ----> Low lbfactor means less work done by the worker.
+worker.ajp13.lbfactor=1
+
+#
+# Specify the size of the open connection cache.
+#worker.ajp13.cachesize
+
+#
+#------ DEFAULT LOAD BALANCER WORKER DEFINITION ----------------------
+#---------------------------------------------------------------------
+#
+
+#
+# The loadbalancer (type lb) workers perform wighted round-robin
+# load balancing with sticky sessions.
+# Note:
+# ----> If a worker dies, the load balancer will check its state
+# once in a while. Until then all work is redirected to peer
+# workers.
+worker.loadbalancer.type=lb
+worker.loadbalancer.balanced_workers=ajp12, ajp13
+
+
+#
+#------ DEFAULT JNI WORKER DEFINITION---------------------------------
+#---------------------------------------------------------------------
+#
+
+#
+# Defining a worker named inprocess and of type jni
+# Note that the name and the type do not have to match.
+#
+worker.inprocess.type=jni
+
+#
+#------ CLASSPATH DEFINITION -----------------------------------------
+#---------------------------------------------------------------------
+#
+
+#
+# Additional class path components.
+#
+worker.inprocess.class_path=$(workers.tomcat_home)$(ps)lib$(ps)tomcat.jar
+
+#
+# Setting the command line for tomcat.
+# Note: The cmd_line string may not contain spaces.
+#
+worker.inprocess.cmd_line=start
+
+# Not needed, but can be customized.
+#worker.inprocess.cmd_line=-config
+#worker.inprocess.cmd_line=$(workers.tomcat_home)$(ps)conf$(ps)server.xml
+#worker.inprocess.cmd_line=-home
+#worker.inprocess.cmd_line=$(workers.tomcat_home)
+
+#
+# The JVM that we are about to use
+#
+# This is for Java2
+#
+# Windows
+worker.inprocess.jvm_lib=$(workers.java_home)$(ps)jre$(ps)bin$(ps)classic$(ps)jvm.dll
+# IBM JDK1.3
+#worker.inprocess.jvm_lib=$(workers.java_home)$(ps)jre$(ps)bin$(ps)classic$(ps)libjvm.so
+# Unix - Sun VM or blackdown
+#worker.inprocess.jvm_lib=$(workers.java_home)$(ps)jre$(ps)lib$(ps)i386$(ps)classic$(ps)libjvm.so
+
+#
+# And this is for jdk1.1.X
+#
+#worker.inprocess.jvm_lib=$(workers.java_home)$(ps)bin$(ps)javai.dll
+
+
+#
+# Setting the place for the stdout and stderr of tomcat
+#
+worker.inprocess.stdout=$(workers.tomcat_home)$(ps)logs$(ps)inprocess.stdout
+worker.inprocess.stderr=$(workers.tomcat_home)$(ps)logs$(ps)inprocess.stderr
+
+#
+# Setting the tomcat.home Java property
+#
+#worker.inprocess.sysprops=tomcat.home=$(workers.tomcat_home)
+
+#
+# Java system properties
+#
+# worker.inprocess.sysprops=java.compiler=NONE
+# worker.inprocess.sysprops=myprop=mypropvalue
+
+#
+# Additional path components.
+#
+# worker.inprocess.ld_path=d:$(ps)SQLLIB$(ps)bin
+#
+
+
diff --git a/base/ocsp/shared/conf/workers.properties.minimal b/base/ocsp/shared/conf/workers.properties.minimal
new file mode 100644
index 000000000..51980ac49
--- /dev/null
+++ b/base/ocsp/shared/conf/workers.properties.minimal
@@ -0,0 +1,22 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+# workers.properties.minimal -
+#
+# This file provides minimal jk configuration properties needed to
+# connect to Tomcat.
+#
+# The workers that jk should create and work with
+#
+worker.list=ajp13w
+
+
+#
+# Defining a worker named ajp13w and of type ajp13
+# Note that the name and the type do not have to match.
+#
+worker.ajp13w.type=ajp13
+worker.ajp13w.host=localhost
+worker.ajp13w.port=8009
diff --git a/base/ocsp/shared/conf/workers2.properties b/base/ocsp/shared/conf/workers2.properties
new file mode 100644
index 000000000..d24abd3a9
--- /dev/null
+++ b/base/ocsp/shared/conf/workers2.properties
@@ -0,0 +1,137 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+[logger]
+level=DEBUG
+
+[config:]
+file=${serverRoot}/conf/workers2.properties
+debug=0
+debugEnv=0
+
+[uriMap:]
+info=Maps the requests. Options: debug
+debug=0
+
+# Alternate file logger
+#[logger.file:0]
+#level=DEBUG
+#file=${serverRoot}/logs/jk2.log
+
+[shm:]
+info=Scoreboard. Required for reconfiguration and status with multiprocess servers
+file=${serverRoot}/logs/jk2.shm
+size=1000000
+debug=0
+disabled=0
+
+[workerEnv:]
+info=Global server options
+timing=1
+debug=0
+# Default Native Logger (apache2 or win32 )
+# can be overriden to a file logger, useful
+# when tracing win32 related issues
+#logger=logger.file:0
+
+[lb:lb]
+info=Default load balancer.
+debug=0
+
+[lb:lb_1]
+info=A second load balancer.
+debug=0
+
+[channel.socket:localhost:8009]
+info=Ajp13 forwarding over socket
+debug=0
+tomcatId=localhost:8009
+
+[channel.socket:localhost:8019]
+info=A second tomcat instance.
+debug=0
+tomcatId=localhost:8019
+lb_factor=1
+#group=lb
+group:lb:lb
+#group=lb_1
+group:lb:lb_1
+disabled=0
+
+[channel.un:/opt/33/work/jk2.socket]
+info=A second channel connecting to localhost:8019 via unix socket
+tomcatId=localhost:8019
+lb_factor=1
+debug=0
+
+[channel.jni:jni]
+info=The jni channel, used if tomcat is started inprocess
+
+[status:]
+info=Status worker, displays runtime informations
+
+[vm:]
+info=Parameters used to load a JVM in the server process
+#JVM=C:\jdk\jre\bin\hotspot\jvm.dll
+classpath=${TOMCAT_HOME}/bin/tomcat-jni.jar
+classpath=${TOMCAT_HOME}/server/lib/commons-logging.jar
+OPT=-Dtomcat.home=${TOMCAT_HOME}
+OPT=-Dcatalina.home=${TOMCAT_HOME}
+OPT=-Xmx128M
+#OPT=-Djava.compiler=NONE
+disabled=1
+
+[worker.jni:onStartup]
+info=Command to be executed by the VM on startup. This one will start tomcat.
+class=org/apache/jk/apr/TomcatStarter
+ARG=start
+# For Tomcat 5 use the 'stard' for startup argument
+# ARG=stard
+disabled=1
+stdout=${serverRoot}/logs/stdout.log
+stderr=${serverRoot}/logs/stderr.log
+
+[worker.jni:onShutdown]
+info=Command to be executed by the VM on shutdown. This one will stop tomcat.
+class=org/apache/jk/apr/TomcatStarter
+ARG=stop
+disabled=1
+
+[uri:/jkstatus/*]
+info=Display status information and checks the config file for changes.
+group=status:
+
+[uri:127.0.0.1:8003]
+info=Example virtual host. Make sure myVirtualHost is in /etc/hosts to test it
+alias=myVirtualHost:8003
+
+[uri:127.0.0.1:8003/ex]
+info=Example webapp in the virtual host. It'll go to lb_1 ( i.e. localhost:8019 )
+context=/ex
+group=lb_1
+
+[uri:/examples]
+info=Example webapp in the default context.
+context=/examples
+debug=0
+
+[uri:/examples1/*]
+info=A second webapp, this time going to the second tomcat only.
+group=lb_1
+debug=0
+
+[uri:/examples/servlet/*]
+info=Prefix mapping
+
+[uri:/examples/*.jsp]
+info=Extension mapping
+
+[uri:/examples/*]
+info=Map the whole webapp
+
+[uri:/examples/servlet/HelloW]
+info=Example with debug enabled.
+debug=10
+
diff --git a/base/ocsp/shared/conf/workers2.properties.minimal b/base/ocsp/shared/conf/workers2.properties.minimal
new file mode 100644
index 000000000..4c440eb68
--- /dev/null
+++ b/base/ocsp/shared/conf/workers2.properties.minimal
@@ -0,0 +1,60 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+#
+# This is the minimal JK2 connector configuration file.
+#
+
+[logger]
+info=Native logger
+level=ERROR
+
+[config:]
+file=${serverRoot}/conf/workers2.properties
+debug=0
+debugEnv=0
+
+[uriMap:]
+info=Maps the requests.
+debug=0
+
+[shm:]
+info=Scoreboard. Required for reconfiguration and status with multiprocess servers
+file=anonymous
+debug=0
+
+[workerEnv:]
+info=Global server options
+timing=0
+debug=0
+
+[lb:lb]
+info=Default load balancer.
+debug=0
+
+[channel.socket:localhost:8009]
+info=Ajp13 forwarding over socket
+debug=0
+tomcatId=localhost:8009
+
+[uri:/admin]
+info=Tomcat HTML based administration web application.
+debug=0
+
+[uri:/manager]
+info=A scriptable management web application for the Tomcat Web Server.
+debug=0
+
+[uri:/jsp-examples]
+info=JSP 2.0 Examples.
+debug=0
+
+[uri:/servlets-examples]
+info=Servlet 2.4 Examples.
+debug=0
+
+[uri:/*.jsp]
+info=JSP Extension mapping.
+debug=0
diff --git a/base/ocsp/shared/etc/init.d/pki-ocspd b/base/ocsp/shared/etc/init.d/pki-ocspd
new file mode 100755
index 000000000..3d69601eb
--- /dev/null
+++ b/base/ocsp/shared/etc/init.d/pki-ocspd
@@ -0,0 +1,87 @@
+#!/bin/bash
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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-2010 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+# pki-ocspd Startup script for pki-ocsp with tomcat6
+#
+# chkconfig: - 83 17
+# description: Online Certificate Status Protocol Manager (Tomcat 6.0)
+# processname: pki-ocspd
+# piddir: /var/run/pki/ocsp
+#
+
+PROG_NAME=`basename $0`
+SERVICE_NAME="pki-ocspd"
+SERVICE_PROG="/sbin/service"
+PKI_PATH="/usr/share/pki/ocsp"
+PKI_REGISTRY="/etc/sysconfig/pki/ocsp"
+PKI_TYPE="pki-ocsp"
+PKI_TOTAL_PORTS=6
+
+# Avoid using 'systemctl' for now
+SYSTEMCTL_SKIP_REDIRECT=1
+export SYSTEMCTL_SKIP_REDIRECT
+
+# Disallow 'others' the ability to 'write' to new files
+umask 00002
+
+command="$1"
+pki_instance="$2"
+
+# Source function library.
+. /etc/init.d/functions
+
+# Source the PKI function library
+. /usr/share/pki/scripts/functions
+
+# See how we were called.
+case $command in
+ status)
+ registry_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 ${default_error}
+ ;;
+ *)
+ echo "unknown action ($command)"
+ usage
+ echo "where valid instance names include:"
+ list_instances
+ exit ${default_error}
+ ;;
+esac
+
diff --git a/base/ocsp/shared/lib/systemd/system/pki-ocspd.target b/base/ocsp/shared/lib/systemd/system/pki-ocspd.target
new file mode 100644
index 000000000..5db6bf4df
--- /dev/null
+++ b/base/ocsp/shared/lib/systemd/system/pki-ocspd.target
@@ -0,0 +1,8 @@
+[Unit]
+Description=PKI Online Certificate Status Protocol Server
+After=syslog.target network.target
+
+[Install]
+WantedBy=multi-user.target
+
+
diff --git a/base/ocsp/shared/lib/systemd/system/pki-ocspd@.service b/base/ocsp/shared/lib/systemd/system/pki-ocspd@.service
new file mode 100644
index 000000000..7b4e7855b
--- /dev/null
+++ b/base/ocsp/shared/lib/systemd/system/pki-ocspd@.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=PKI Online Certificate Status Protocol Server %i
+After=pki-ocspd.target
+BindTo=pki-ocspd.target
+
+[Service]
+Type=forking
+ExecStart=/usr/bin/pkicontrol start ocsp %i
+ExecStop=/usr/bin/pkicontrol stop ocsp %i
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/base/ocsp/shared/webapps/ROOT/WEB-INF/web.xml b/base/ocsp/shared/webapps/ROOT/WEB-INF/web.xml
new file mode 100644
index 000000000..ed274862b
--- /dev/null
+++ b/base/ocsp/shared/webapps/ROOT/WEB-INF/web.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright 2004 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ END COPYRIGHT BLOCK -->
+
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+ version="2.4">
+
+ <display-name>Welcome to Tomcat</display-name>
+ <description>
+ Welcome to Tomcat
+ </description>
+
+</web-app>
+
diff --git a/base/ocsp/shared/webapps/ROOT/index.jsp b/base/ocsp/shared/webapps/ROOT/index.jsp
new file mode 100644
index 000000000..4b2b3c60a
--- /dev/null
+++ b/base/ocsp/shared/webapps/ROOT/index.jsp
@@ -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.
+
+ Copyright (C) 2010 Red Hat, Inc.
+ All rights reserved.
+ --- END COPYRIGHT BLOCK --- -->
+<%
+ // establish acceptable schemes
+ final String HTTP_SCHEME = "http";
+ final String HTTPS_SCHEME = "https";
+
+ // establish known ports
+ final int EE_HTTP_PORT = [PKI_UNSECURE_PORT];
+ final int AGENT_HTTPS_PORT = [PKI_AGENT_SECURE_PORT];
+ final int EE_HTTPS_PORT = [PKI_EE_SECURE_PORT];
+ final int ADMIN_HTTPS_PORT = [PKI_ADMIN_SECURE_PORT];
+
+ // establish known paths
+ final String ADMIN_PATH = "/[PKI_SUBSYSTEM_TYPE]/services";
+ final String AGENT_PATH = "/[PKI_SUBSYSTEM_TYPE]/agent/[PKI_SUBSYSTEM_TYPE]";
+ final String ERROR_PATH = "/[PKI_SUBSYSTEM_TYPE]/404.html";
+
+ // retrieve scheme from request
+ String scheme = request.getScheme();
+
+ // retrieve client hostname on which the request was sent
+ String client_hostname = request.getServerName();
+
+ // retrieve client port number on which the request was sent
+ int client_port = request.getServerPort();
+
+ // retrieve server hostname on which the request was received
+ String server_hostname = request.getLocalName();
+
+ // retrieve server port number on which the request was received
+ int server_port = request.getLocalPort();
+
+ // uncomment the following lines to write to 'catalina.out'
+ //System.out.println( "scheme = '" + scheme + "'" );
+ //System.out.println( "client hostname = '" + client_hostname + "'" );
+ //System.out.println( "client port = '" + client_port + "'" );
+ //System.out.println( "server hostname = '" + server_hostname + "'" );
+ //System.out.println( "server port = '" + server_port + "'" );
+
+ // compose the appropriate URL
+ String URL = "";
+
+ if( scheme.equals( HTTP_SCHEME ) ) {
+ if( server_port == EE_HTTP_PORT ) {
+ // always redirect to secure admin 'services' port
+ scheme = HTTPS_SCHEME;
+ client_port = ADMIN_HTTPS_PORT;
+ URL = scheme + "://" + client_hostname + ":" + client_port + ADMIN_PATH;
+ } else {
+ // unknown HTTP server port: should never get here
+ URL = scheme + "://" + client_hostname + ":" + client_port + ERROR_PATH;
+
+ // uncomment the following line to write to 'catalina.out'
+ //System.out.println( "Unknown HTTP server port: '" + server_port + "'" );
+ }
+ } else if( scheme.equals( HTTPS_SCHEME ) ) {
+ if( server_port == AGENT_HTTPS_PORT ) {
+ URL = scheme + "://" + client_hostname + ":" + client_port + AGENT_PATH;
+ } else if( server_port == EE_HTTPS_PORT ) {
+ // always redirect to secure admin 'services' port
+ client_port = ADMIN_HTTPS_PORT;
+ URL = scheme + "://" + client_hostname + ":" + client_port + ADMIN_PATH;
+ } else if( server_port == ADMIN_HTTPS_PORT ) {
+ URL = scheme + "://" + client_hostname + ":" + client_port + ADMIN_PATH;
+ } else {
+ // unknown HTTPS server port: should never get here
+ URL = scheme + "://" + client_hostname + ":" + client_port + ERROR_PATH;
+
+ // uncomment the following line to write to 'catalina.out'
+ //System.out.println( "Unknown HTTPS server port: '" + server_port + "'" );
+ }
+ } else {
+ // unacceptable scheme: should never get here
+ URL = scheme + "://" + client_hostname + ":" + client_port + ERROR_PATH;
+
+ // uncomment the following line to write to 'catalina.out'
+ //System.out.println( "Unacceptable scheme: '" + scheme + "'" );
+ }
+
+ // respond (back to browser) with the appropriate redirected URL
+ response.sendRedirect( URL );
+%>
diff --git a/base/ocsp/shared/webapps/ocsp/WEB-INF/velocity.properties b/base/ocsp/shared/webapps/ocsp/WEB-INF/velocity.properties
new file mode 100644
index 000000000..5cd0454cc
--- /dev/null
+++ b/base/ocsp/shared/webapps/ocsp/WEB-INF/velocity.properties
@@ -0,0 +1,13 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+resource.loader = file
+file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
+file.resource.loader.path = [PKI_INSTANCE_PATH]/[PKI_WEBAPPS_NAME]/[PKI_SUBSYSTEM_TYPE]
+file.resource.loader.cache = true
+file.resource.loader.modificationCheckInterval = 2
+input.encoding=UTF-8
+output.encoding=UTF-8
+runtime.log.logsystem.class=org.apache.velocity.runtime.log.NullLogSystem
diff --git a/base/ocsp/shared/webapps/ocsp/WEB-INF/web.xml b/base/ocsp/shared/webapps/ocsp/WEB-INF/web.xml
new file mode 100644
index 000000000..b31bd751e
--- /dev/null
+++ b/base/ocsp/shared/webapps/ocsp/WEB-INF/web.xml
@@ -0,0 +1,647 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2006 Red Hat, Inc.
+ All rights reserved.
+ END COPYRIGHT BLOCK -->
+<!DOCTYPE web-app
+ PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "file:///usr/share/pki/setup/web-app_2_3.dtd">
+<web-app>
+
+ <filter>
+ <filter-name>AgentRequestFilter</filter-name>
+ <filter-class>com.netscape.cms.servlet.filter.AgentRequestFilter</filter-class>
+ <init-param>
+ <param-name>https_port</param-name>
+ <param-value>[PKI_AGENT_SECURE_PORT]</param-value>
+ </init-param>
+[PKI_OPEN_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>proxy_port</param-name>
+ <param-value>[PKI_PROXY_SECURE_PORT]</param-value>
+ </init-param>
+[PKI_CLOSE_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>active</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ </filter>
+
+ <filter>
+ <filter-name>AdminRequestFilter</filter-name>
+ <filter-class>com.netscape.cms.servlet.filter.AdminRequestFilter</filter-class>
+ <init-param>
+ <param-name>https_port</param-name>
+ <param-value>[PKI_ADMIN_SECURE_PORT]</param-value>
+ </init-param>
+[PKI_OPEN_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>proxy_port</param-name>
+ <param-value>[PKI_PROXY_SECURE_PORT]</param-value>
+ </init-param>
+[PKI_CLOSE_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>active</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ </filter>
+
+ <filter>
+ <filter-name>EERequestFilter</filter-name>
+ <filter-class>com.netscape.cms.servlet.filter.EERequestFilter</filter-class>
+ <init-param>
+ <param-name>http_port</param-name>
+ <param-value>[PKI_UNSECURE_PORT]</param-value>
+ </init-param>
+ <init-param>
+ <param-name>https_port</param-name>
+ <param-value>[PKI_EE_SECURE_PORT]</param-value>
+ </init-param>
+[PKI_OPEN_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>proxy_port</param-name>
+ <param-value>[PKI_PROXY_SECURE_PORT]</param-value>
+ </init-param>
+ <init-param>
+ <param-name>proxy_http_port</param-name>
+ <param-value>[PKI_PROXY_UNSECURE_PORT]</param-value>
+ </init-param>
+[PKI_CLOSE_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>active</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ </filter>
+
+ <servlet>
+ <servlet-name>csadmin-wizard</servlet-name>
+ <servlet-class>com.netscape.cms.servlet.wizard.WizardServlet</servlet-class>
+ <init-param>
+ <param-name>properties</param-name>
+ <param-value>/WEB-INF/velocity.properties</param-value>
+ </init-param>
+ <init-param>
+ <param-name>name</param-name>
+ <param-value>OCSP Setup Wizard</param-value>
+ </init-param>
+ <init-param>
+ <param-name>panels</param-name>
+ <param-value>welcome=com.netscape.cms.servlet.csadmin.WelcomePanel,module=com.netscape.cms.servlet.csadmin.ModulePanel,confighsmlogin=com.netscape.cms.servlet.csadmin.ConfigHSMLoginPanel,securitydomain=com.netscape.cms.servlet.csadmin.SecurityDomainPanel,securitydomain=com.netscape.cms.servlet.csadmin.DisplayCertChainPanel,subsystem=com.netscape.cms.servlet.csadmin.CreateSubsystemPanel,restorekeys=com.netscape.cms.servlet.csadmin.RestoreKeyCertPanel,databasepanel=com.netscape.cms.servlet.csadmin.DatabasePanel,sizepanel=com.netscape.cms.servlet.csadmin.SizePanel,namepanel=com.netscape.cms.servlet.csadmin.NamePanel,certrequestpanel=com.netscape.cms.servlet.csadmin.CertRequestPanel,backupkeys=com.netscape.cms.servlet.csadmin.BackupKeyCertPanel,savepk12=com.netscape.cms.servlet.csadmin.SavePKCS12Panel,adminpanel=com.netscape.cms.servlet.csadmin.AdminPanel,importadmincertpanel=com.netscape.cms.servlet.csadmin.ImportAdminCertPanel,donepanel=com.netscape.cms.servlet.csadmin.DonePanel</param-value>
+ </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name>csadmin-login</servlet-name>
+ <servlet-class>com.netscape.cms.servlet.csadmin.LoginServlet</servlet-class>
+ <init-param>
+ <param-name>properties</param-name>
+ <param-value>/WEB-INF/velocity.properties</param-value>
+ </init-param>
+ </servlet>
+
+
+ <servlet>
+ <servlet-name> ocspacl </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.ACLAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspacl </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+<!--
+ <servlet>
+ <servlet-name> ocspjobsScheduler </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.JobsAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspjobsScheduler </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+-->
+
+ <servlet>
+ <servlet-name> ocspug </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.UsrGrpAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspug </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+ <servlet>
+ <servlet-name> ocspserver </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.CMSAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspserver </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> ocsplog </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.LogAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocsplog </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> ocspauths </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.AuthAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspauths </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> ocspstart </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.CMSStartServlet </servlet-class>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> cfgPath </param-name>
+ <param-value> [PKI_INSTANCE_PATH]/conf/CS.cfg </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspstart </param-value> </init-param>
+ <load-on-startup> 1 </load-on-startup>
+ </servlet>
+
+ <servlet>
+ <servlet-name> ocspocsp </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.OCSPAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspocsp </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> ocspReadCheckCertPage </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.DisplayHtmlServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> htmlPath </param-name>
+ <param-value> /ocsp/CheckCert.html </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ocsp </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspReadCheckCertPage </param-value> </init-param>
+ <init-param><param-name> unauthorizedTemplate </param-name>
+ <param-value> /agent/GenUnauthorized.template </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> ocspindex </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.IndexServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspindex </param-value> </init-param>
+ <init-param><param-name> template </param-name>
+ <param-value> /agent/index.template </param-value> </init-param>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+ <servlet>
+ <servlet-name> ocspReadAddCRLPage </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.DisplayHtmlServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> htmlPath </param-name>
+ <param-value> /agent/ocsp/AddCRL.html </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ocsp </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspReadAddCRLPage </param-value> </init-param>
+ <init-param><param-name> unauthorizedTemplate </param-name>
+ <param-value> /agent/GenUnauthorized.template </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> ocspGetOCSPInfo </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.ocsp.GetOCSPInfo </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ocsp </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspGetOCSPInfo </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ocsp.info </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ocsp/getOCSPInfo.template </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> ocspListCAs </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.ocsp.ListCAServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ocsp </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspListCAs </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ocsp.cas </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ocsp/listCAs.template </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> ocspAddCRL </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.ocsp.AddCRLServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ocsp </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspAddCRL </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ocsp.crl </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ocsp/addCRL.template </param-value> </init-param>
+ </servlet>
+ <servlet>
+ <servlet-name> ocspports </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.PortsServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspports </param-value> </init-param>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> ocspGetConfigEntries </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.GetConfigEntries </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ocsp </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspGetConfigEntries </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> TokenAuth </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.clone.configuration.GetConfigEntries </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> ocspCheckCert </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.ocsp.CheckCertServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ocsp </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspCheckCert </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ocsp.certificate </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ocsp/checkCert.template </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> ocspAddCA </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.ocsp.AddCAServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ocsp </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspAddCA </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ocsp.ca </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ocsp/addCA.template </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> ocspRemoveCA </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.ocsp.RemoveCAServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ocsp </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspRemoveCA </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ocsp.ca </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /agent/ocsp/removeCA.template </param-value> </init-param>
+ </servlet>
+
+
+ <servlet>
+ <servlet-name> ocspReadAddCAPage </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.DisplayHtmlServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> agent </param-value> </init-param>
+ <init-param><param-name> htmlPath </param-name>
+ <param-value> /agent/ocsp/AddCA.html </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ocsp </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspReadAddCAPage </param-value> </init-param>
+ <init-param><param-name> unauthorizedTemplate </param-name>
+ <param-value> /agent/GenUnauthorized.template </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> ocspheader </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.IndexServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspheader </param-value> </init-param>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ <init-param><param-name> template </param-name>
+ <param-value> /agent/header.template </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> services </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.MainPageServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authorityId </param-name>
+ <param-value> ocsp </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> services </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /services.template </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> ocspOCSP </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.ocsp.OCSPServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ocsp </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspOCSP </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.ee.request.ocsp </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> ocspDownloadPKCS12 </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.DownloadPKCS12 </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ocsp </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspDownloadPKCS12 </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> TokenAuth </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> ocspGetTokenInfo </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.GetTokenInfo </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> ocsp </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> ocspGetTokenInfo </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+[PKI_OPEN_SEPARATE_PORTS_WEB_COMMENT]
+ <filter-mapping>
+ <filter-name> AgentRequestFilter </filter-name>
+ <url-pattern> /agent/* </url-pattern>
+ </filter-mapping>
+
+ <filter-mapping>
+ <filter-name> AdminRequestFilter </filter-name>
+ <url-pattern> /admin/* </url-pattern>
+ <url-pattern> /auths </url-pattern>
+ <url-pattern> /ug </url-pattern>
+ <url-pattern> /log </url-pattern>
+ <url-pattern> /acl </url-pattern>
+ <url-pattern> /server </url-pattern>
+ <url-pattern> /ocsp </url-pattern>
+ </filter-mapping>
+
+ <filter-mapping>
+ <filter-name> EERequestFilter </filter-name>
+ <url-pattern> /ee/* </url-pattern>
+ </filter-mapping>
+[PKI_CLOSE_SEPARATE_PORTS_WEB_COMMENT]
+
+ <servlet-mapping>
+ <servlet-name> ocspacl </servlet-name>
+ <url-pattern> /acl </url-pattern>
+ </servlet-mapping>
+
+<!--
+ <servlet-mapping>
+ <servlet-name> ocspjobsScheduler </servlet-name>
+ <url-pattern> /jobsScheduler </url-pattern>
+ </servlet-mapping>
+-->
+
+ <servlet-mapping>
+ <servlet-name> ocspug </servlet-name>
+ <url-pattern> /ug </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocspserver </servlet-name>
+ <url-pattern> /server </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocsplog </servlet-name>
+ <url-pattern> /log </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocspauths </servlet-name>
+ <url-pattern> /auths </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocspstart </servlet-name>
+ <url-pattern> /start </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocspocsp </servlet-name>
+ <url-pattern> /ocsp </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocspReadCheckCertPage </servlet-name>
+ <url-pattern> /agent/ocsp/checkCert.html </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocspindex </servlet-name>
+ <url-pattern> /agent/index </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocspReadAddCRLPage </servlet-name>
+ <url-pattern> /agent/ocsp/addCRL.html </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocspGetOCSPInfo </servlet-name>
+ <url-pattern> /agent/ocsp/getOCSPInfo </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocspListCAs </servlet-name>
+ <url-pattern> /agent/ocsp/listCAs </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocspAddCRL </servlet-name>
+ <url-pattern> /agent/ocsp/addCRL </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocspports </servlet-name>
+ <url-pattern> /ee/ocsp/ports </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocspCheckCert </servlet-name>
+ <url-pattern> /agent/ocsp/checkCert </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocspAddCA </servlet-name>
+ <url-pattern> /agent/ocsp/addCA </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocspRemoveCA </servlet-name>
+ <url-pattern> /agent/ocsp/removeCA </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocspReadAddCAPage </servlet-name>
+ <url-pattern> /agent/ocsp/addCA.html </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocspheader </servlet-name>
+ <url-pattern> /agent/header </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocspOCSP </servlet-name>
+ <url-pattern> /ee/ocsp </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocspOCSP </servlet-name>
+ <url-pattern> /ee/ocsp/* </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>csadmin-wizard</servlet-name>
+ <url-pattern>/admin/console/config/wizard</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>csadmin-login</servlet-name>
+ <url-pattern>/admin/console/config/login</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocspGetConfigEntries </servlet-name>
+ <url-pattern> /admin/ocsp/getConfigEntries </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> services </servlet-name>
+ <url-pattern> /services </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocspDownloadPKCS12 </servlet-name>
+ <url-pattern> /admin/console/config/savepkcs12 </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> ocspGetTokenInfo </servlet-name>
+ <url-pattern> /ee/ocsp/getTokenInfo </url-pattern>
+ </servlet-mapping>
+
+ <!-- ==================== Default Session Configuration =============== -->
+ <!-- You can set the default session timeout (in minutes) for all newly -->
+ <!-- created sessions by modifying the value below. -->
+ <!-- -->
+ <!-- To disable session timeouts for this instance, set a value of -1. -->
+
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+</web-app>
+
diff --git a/base/ocsp/src/CMakeLists.txt b/base/ocsp/src/CMakeLists.txt
new file mode 100644
index 000000000..0992eeaee
--- /dev/null
+++ b/base/ocsp/src/CMakeLists.txt
@@ -0,0 +1,99 @@
+project(pki-ocsp_java Java)
+
+# '/usr/share/java/pki' jars
+find_file(PKI_CERTSRV_JAR
+ NAMES
+ pki-certsrv.jar
+ PATHS
+ /usr/share/java/pki
+)
+
+find_file(PKI_CMS_JAR
+ NAMES
+ pki-cms.jar
+ PATHS
+ /usr/share/java/pki
+)
+
+find_file(PKI_CMSCORE_JAR
+ NAMES
+ pki-cmscore.jar
+ PATHS
+ /usr/share/java/pki
+)
+
+find_file(PKI_CMSUTIL_JAR
+ NAMES
+ pki-cmsutil.jar
+ PATHS
+ /usr/share/java/pki
+)
+
+find_file(PKI_NSUTIL_JAR
+ NAMES
+ pki-nsutil.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java/pki
+)
+
+
+# '/usr/share/java' jars
+find_file(LDAPJDK_JAR
+ NAMES
+ ldapjdk.jar
+ PATHS
+ /usr/share/java
+)
+
+
+# '${JAVA_LIB_INSTALL_DIR}' jars
+find_file(JSS_JAR
+ NAMES
+ jss4.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+)
+
+find_file(COMMONS_CODEC_JAR
+ NAMES
+ commons-codec.jar
+ PATHS
+ /usr/share/java
+)
+
+find_file(SYMKEY_JAR
+ NAMES
+ symkey.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+)
+
+
+# identify java sources
+set(pki-ocsp_java_SRCS
+ com/netscape/ocsp/OCSPResources.java
+ com/netscape/ocsp/OCSPAuthority.java
+ com/netscape/ocsp/SigningUnit.java
+ com/netscape/ocsp/EOCSPException.java
+)
+
+
+# set classpath
+set(CMAKE_JAVA_INCLUDE_PATH
+ ${PKI_CERTSRV_JAR} ${PKI_CMS_JAR} ${PKI_CMSCORE_JAR}
+ ${PKI_CMSUTIL_JAR} ${PKI_NSUTIL_JAR}
+ ${LDAPJDK_JAR}
+ ${JSS_JAR} ${COMMONS_CODEC_JAR} ${SYMKEY_JAR})
+
+
+# set version
+set(CMAKE_JAVA_TARGET_VERSION ${APPLICATION_VERSION})
+
+
+# build pki-ocsp.jar
+add_jar(pki-ocsp ${pki-ocsp_java_SRCS})
+add_dependencies(pki-ocsp symkey pki-nsutil pki-cmsutil pki-certsrv pki-cms pki-cmscore)
+install_jar(pki-ocsp ${JAVA_JAR_INSTALL_DIR}/pki)
+set(PKI_OCSP_JAR ${pki-ocsp_JAR_FILE} CACHE INTERNAL "pki-ocsp jar file")
+
diff --git a/base/ocsp/src/com/netscape/ocsp/EOCSPException.java b/base/ocsp/src/com/netscape/ocsp/EOCSPException.java
new file mode 100644
index 000000000..231ab2867
--- /dev/null
+++ b/base/ocsp/src/com/netscape/ocsp/EOCSPException.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.ocsp;
+
+import com.netscape.certsrv.base.EBaseException;
+
+/**
+ * A class represents a OCSP exception.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class EOCSPException extends EBaseException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2152152848080759882L;
+ /**
+ * CA resource class name.
+ */
+ private static final String OCSP_RESOURCES = OCSPResources.class.getName();
+
+ /**
+ * Constructs a OCSP exception.
+ * <P>
+ */
+ public EOCSPException(String msgFormat) {
+ super(msgFormat);
+ }
+
+ /**
+ * Constructs a OCSP exception.
+ * <P>
+ */
+ public EOCSPException(String msgFormat, String param) {
+ super(msgFormat, param);
+ }
+
+ /**
+ * Constructs a OCSP exception.
+ * <P>
+ */
+ public EOCSPException(String msgFormat, Exception e) {
+ super(msgFormat, e);
+ }
+
+ /**
+ * Constructs a OCSP exception.
+ * <P>
+ */
+ public EOCSPException(String msgFormat, Object params[]) {
+ super(msgFormat, params);
+ }
+
+ protected String getBundleName() {
+ return OCSP_RESOURCES;
+ }
+}
diff --git a/base/ocsp/src/com/netscape/ocsp/OCSPAuthority.java b/base/ocsp/src/com/netscape/ocsp/OCSPAuthority.java
new file mode 100644
index 000000000..f009bd56f
--- /dev/null
+++ b/base/ocsp/src/com/netscape/ocsp/OCSPAuthority.java
@@ -0,0 +1,643 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.ocsp;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateParsingException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509Key;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.pkix.primitive.Name;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+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.ocsp.IDefStore;
+import com.netscape.certsrv.ocsp.IOCSPAuthority;
+import com.netscape.certsrv.ocsp.IOCSPService;
+import com.netscape.certsrv.ocsp.IOCSPStore;
+import com.netscape.certsrv.request.IRequestListener;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.security.ISigningUnit;
+import com.netscape.cmscore.util.Debug;
+import com.netscape.cmsutil.ocsp.BasicOCSPResponse;
+import com.netscape.cmsutil.ocsp.KeyHashID;
+import com.netscape.cmsutil.ocsp.NameID;
+import com.netscape.cmsutil.ocsp.OCSPRequest;
+import com.netscape.cmsutil.ocsp.OCSPResponse;
+import com.netscape.cmsutil.ocsp.ResponderID;
+import com.netscape.cmsutil.ocsp.ResponseData;
+
+/**
+ * A class represents a Certificate Authority that is
+ * responsible for certificate specific operations.
+ * <P>
+ *
+ * @author lhsiao
+ * @version $Revision$, $Date$
+ */
+public class OCSPAuthority implements IOCSPAuthority, IOCSPService, ISubsystem, IAuthority {
+
+ private long mServedRequests = 0;
+ private long mServedTime = 0;
+
+ public final static OBJECT_IDENTIFIER OCSP_NONCE = new OBJECT_IDENTIFIER("1.3.6.1.5.5.7.48.1.2");
+
+ private Hashtable<String, IOCSPStore> mStores = new Hashtable<String, IOCSPStore>();
+ private String mId = "ocsp";
+ private IConfigStore mConfig = null;
+ private SigningUnit mSigningUnit;
+ private CertificateChain mCertChain = null;
+ private X509CertImpl mCert = null;
+ private X500Name mName = null;
+ private String mNickname = null;
+ private String[] mOCSPSigningAlgorithms = null;
+ private IOCSPStore mDefStore = null;
+
+ public long mNumOCSPRequest = 0;
+ public long mTotalTime = 0;
+ public long mTotalData = 0;
+ public long mSignTime = 0;
+ public long mLookupTime = 0;
+
+ protected ILogger mLogger = CMS.getLogger();
+
+ /**
+ * Retrieves the name of this subsystem.
+ */
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * Sets specific to this subsystem.
+ */
+ public void setId(String id) throws EBaseException {
+ mId = id;
+ }
+
+ /**
+ * 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 {
+ try {
+ mConfig = config;
+
+ initSigUnit();
+
+ // create default OCSP Store
+ try {
+ String defStoreId = mConfig.getString(PROP_DEF_STORE_ID, null);
+
+ if (defStoreId == null) {
+ throw new EBaseException("default id not found");
+ }
+
+ IConfigStore storeConfig = mConfig.getSubStore(PROP_STORE);
+ Enumeration<String> ids = storeConfig.getSubStoreNames();
+
+ while (ids.hasMoreElements()) {
+ String id = (String) ids.nextElement();
+ String className = mConfig.getString(PROP_STORE + "." + id + ".class", null);
+ IOCSPStore store = (IOCSPStore) Class.forName(className).newInstance();
+
+ store.init(this, mConfig.getSubStore(PROP_STORE + "." + id));
+ mStores.put(id, store);
+ if (id.equals(defStoreId)) {
+ mDefStore = store;
+ }
+ }
+ } catch (ClassNotFoundException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_OCSP_SIGNING_UNIT", e.toString()));
+ } catch (InstantiationException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_OCSP_SIGNING_UNIT", e.toString()));
+ } catch (IllegalAccessException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_OCSP_SIGNING_UNIT", e.toString()));
+ }
+ } catch (EBaseException ee) {
+ if (CMS.isPreOpMode())
+ return;
+ else
+ throw ee;
+ }
+ }
+
+ /**
+ * Retrieves the specificed OCSP store.
+ */
+ public IOCSPStore getOCSPStore(String id) {
+ return mStores.get(id);
+ }
+
+ public IConfigStore getOCSPStoreConfig(String id) {
+ return mConfig.getSubStore(PROP_STORE + "." + id);
+ }
+
+ public String getOCSPStoreClassPath(String id) {
+ try {
+ return mConfig.getString(PROP_STORE + "." + id + ".class", null);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_OCSP_CLASSPATH", id, e.toString()));
+ return null;
+ }
+ }
+
+ public ResponderID getResponderIDByName() {
+ try {
+ X500Name name = getName();
+ Name.Template nameTemplate = new Name.Template();
+
+ return new NameID((Name) nameTemplate.decode(
+ new ByteArrayInputStream(name.getEncoded())));
+ } catch (IOException e) {
+ return null;
+ } catch (InvalidBERException e) {
+ return null;
+ }
+ }
+
+ public ResponderID getResponderIDByHash() {
+
+ /*
+ KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key
+ --(excluding the tag and length fields)
+ */
+ PublicKey publicKey = getSigningUnit().getPublicKey();
+ MessageDigest md = null;
+
+ try {
+ md = MessageDigest.getInstance("SHA1");
+ } catch (NoSuchAlgorithmException e) {
+ return null;
+ }
+ md.update(publicKey.getEncoded());
+ byte digested[] = md.digest();
+
+ return new KeyHashID(new OCTET_STRING(digested));
+ }
+
+ /**
+ * Retrieves supported signing algorithms.
+ */
+ public String[] getOCSPSigningAlgorithms() {
+ if (mOCSPSigningAlgorithms != null) {
+ return mOCSPSigningAlgorithms;
+ }
+
+ if (mCert == null) {
+ return null; // CA not inited yet.
+ }
+
+ X509Key caPubKey = null;
+
+ try {
+ caPubKey = (X509Key) mCert.get(X509CertImpl.PUBLIC_KEY);
+ } catch (CertificateParsingException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_OCSP_RETRIEVE_KEY", e.toString()));
+ }
+ if (caPubKey == null) {
+ return null; // something seriously wrong.
+ }
+ AlgorithmId alg = caPubKey.getAlgorithmId();
+
+ if (alg == null) {
+ return null; // something seriously wrong.
+ }
+ mOCSPSigningAlgorithms = AlgorithmId.getSigningAlgorithms(alg);
+ if (mOCSPSigningAlgorithms == null) {
+ CMS.debug(
+ "OCSP - no signing algorithms for " + alg.getName());
+ } else {
+ CMS.debug("OCSP First signing algorithm ");
+ }
+ return mOCSPSigningAlgorithms;
+ }
+
+ public static final OBJECT_IDENTIFIER MD2 =
+ new OBJECT_IDENTIFIER("1.2.840.113549.2.2");
+ public static final OBJECT_IDENTIFIER MD5 =
+ new OBJECT_IDENTIFIER("1.2.840.113549.2.5");
+ public static final OBJECT_IDENTIFIER SHA1 =
+ new OBJECT_IDENTIFIER("1.3.14.3.2.26");
+
+ public String getDigestName(AlgorithmIdentifier alg) {
+ if (alg == null) {
+ return null;
+ } else if (alg.getOID().equals(MD2)) {
+ return "MD2";
+ } else if (alg.getOID().equals(MD5)) {
+ return "MD5";
+ } else if (alg.getOID().equals(SHA1)) {
+ return "SHA1"; // 1.3.14.3.2.26
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Retrieves the name of this OCSP server.
+ */
+ public X500Name getName() {
+ return mName;
+ }
+
+ public IDefStore getDefaultStore() {
+ return (IDefStore) mDefStore;
+ }
+
+ private void initSigUnit() throws EBaseException {
+ try {
+ // init signing unit
+ mSigningUnit = new SigningUnit();
+ mSigningUnit.init(this, mConfig.getSubStore(PROP_SIGNING_SUBSTORE));
+ CMS.debug("OCSP signing unit inited");
+
+ // init cert chain
+ CryptoManager manager = CryptoManager.getInstance();
+ org.mozilla.jss.crypto.X509Certificate[] chain =
+ manager.buildCertificateChain(mSigningUnit.getCert());
+ // XXX do this in case other subsyss expect a X509CertImpl
+ // until JSS implements all methods of X509Certificate
+ java.security.cert.X509Certificate[] implchain =
+ new java.security.cert.X509Certificate[chain.length];
+
+ for (int i = 0; i < chain.length; i++) {
+ implchain[i] = new X509CertImpl(chain[i].getEncoded());
+ }
+ mCertChain = new CertificateChain(implchain);
+ CMS.debug("in init - got CA chain from JSS.");
+
+ // init issuer name - take name from the cert.
+
+ mCert = new X509CertImpl(mSigningUnit.getCert().getEncoded());
+ getOCSPSigningAlgorithms();
+ mName = (X500Name) mCert.getSubjectDN();
+ mNickname = mSigningUnit.getNickname();
+ CMS.debug("in init - got CA name " + mName);
+
+ } catch (CryptoManager.NotInitializedException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_OCSP_SIGNING", e.toString()));
+ } catch (CertificateException e) {
+ if (Debug.ON)
+ e.printStackTrace();
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_OCSP_CHAIN", e.toString()));
+ } catch (TokenException e) {
+ if (Debug.ON)
+ e.printStackTrace();
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_OCSP_CHAIN", e.toString()));
+ }
+ }
+
+ /**
+ * Notifies this subsystem if owner is in running mode.
+ */
+ public void startup() throws EBaseException {
+ try {
+ if (mDefStore != null)
+ mDefStore.startup();
+ } catch (EBaseException e) {
+ if (CMS.isPreOpMode()) {
+ return;
+ } else
+ throw e;
+ } catch (Exception e) {
+ }
+ }
+
+ /**
+ * Process OCSPRequest.
+ */
+ public OCSPResponse validate(OCSPRequest request)
+ throws EBaseException {
+ long startTime = (CMS.getCurrentDate()).getTime();
+ OCSPResponse response = mDefStore.validate(request);
+ long endTime = (CMS.getCurrentDate()).getTime();
+
+ mServedRequests++;
+ mServedTime = mServedTime + (endTime - startTime);
+ return response;
+ }
+
+ public boolean arraysEqual(byte[] bytes, byte[] ints) {
+ if (bytes == null || ints == null) {
+ return false;
+ }
+
+ if (bytes.length != ints.length) {
+ return false;
+ }
+
+ for (int i = 0; i < bytes.length; i++) {
+ if (bytes[i] != ints[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * 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() {
+ return mConfig;
+ }
+
+ public String getDefaultAlgorithm() {
+ return mSigningUnit.getDefaultAlgorithm();
+ }
+
+ /**
+ * logs a message in the CA area.
+ *
+ * @param level the debug level.
+ * @param msg the message to debug.
+ */
+ public void log(int event, int level, String msg) {
+ mLogger.log(event, ILogger.S_OCSP,
+ level, msg);
+ }
+
+ public void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OCSP,
+ level, msg);
+ }
+
+ public void setDefaultAlgorithm(String algorithm)
+ throws EBaseException {
+ mSigningUnit.setDefaultAlgorithm(algorithm);
+ }
+
+ /**
+ * Signs the Response Data.
+ */
+ public BasicOCSPResponse sign(ResponseData rd)
+ throws EBaseException {
+ try {
+ DerOutputStream out = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+
+ String algname = mSigningUnit.getDefaultAlgorithm();
+
+ byte rd_data[] = ASN1Util.encode(rd);
+ if (rd_data != null) {
+ mTotalData += rd_data.length;
+ }
+ rd.encode(tmp);
+ AlgorithmId.get(algname).encode(tmp);
+ CMS.debug("adding signature");
+ byte[] signature = mSigningUnit.sign(rd_data, algname);
+
+ tmp.putBitString(signature);
+ // XXX - optional, put the certificate chains in also
+
+ DerOutputStream tmpChain = new DerOutputStream();
+ DerOutputStream tmp1 = new DerOutputStream();
+ java.security.cert.X509Certificate chains[] =
+ mCertChain.getChain();
+
+ for (int i = 0; i < chains.length; i++) {
+ tmpChain.putDerValue(new DerValue(chains[i].getEncoded()));
+ }
+ tmp1.write(DerValue.tag_Sequence, tmpChain);
+ tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0),
+ tmp1);
+
+ out.write(DerValue.tag_Sequence, tmp);
+
+ BasicOCSPResponse response = new BasicOCSPResponse(out.toByteArray());
+
+ return response;
+ } catch (Exception e) {
+ e.printStackTrace();
+ // error e
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_OCSP_SIGN_RESPONSE", e.toString()));
+ return null;
+ }
+
+ }
+
+ /**
+ * Returns default signing unit used by this CA
+ * <P>
+ *
+ * @return request identifier
+ */
+ public ISigningUnit getSigningUnit() {
+ return mSigningUnit;
+ }
+
+ /**
+ * Retrieves the request queue for the Authority.
+ * <P>
+ *
+ * @return the request queue.
+ */
+ public IRequestQueue getRequestQueue() {
+ return null;
+ }
+
+ /**
+ * Registers request completed class.
+ */
+ public void registerRequestListener(IRequestListener listener) {
+ }
+
+ /**
+ * Registers pending request class.
+ */
+ public void registerPendingListener(IRequestListener listener) {
+ }
+
+ /**
+ * nickname of signing (id) cert
+ */
+ public String getNickname() {
+ return mNickname;
+ }
+
+ public String getNewNickName() throws EBaseException {
+ return mConfig.getString(PROP_NEW_NICKNAME, "");
+ }
+
+ public void setNewNickName(String name) {
+ mConfig.putString(PROP_NEW_NICKNAME, name);
+ }
+
+ public void setNickname(String str) {
+ mConfig.putString(PROP_NICKNAME, str);
+ }
+
+ /**
+ * return official product name.
+ */
+ public String getOfficialName() {
+ return "ocsp";
+ }
+
+ /**
+ * Utility functions for processing OCSP request.
+ */
+
+ /**
+ * public OCSPResponse processOCSPRequest(OCSPRequest req, OCSPReqProcessor p)
+ * throws EBaseException
+ * {
+ * try {
+ * log(ILogger.LL_INFO, "start OCSP request");
+ * TBSRequest tbsReq = request.getTBSRequest();
+ *
+ * Vector singleResponses = new Vector();
+ * for (int i = 0; i < tbsReq.getRequestCount(); i++)
+ * {
+ * com.netscape.certsrv.ocsp.asn1.Request req =
+ * tbsReq.getRequestAt(i);
+ * CertID cid = req.getCertID();
+ * SingleResponse sr = p.process(cid);
+ * singleResponses.addElement(sr);
+ * }
+ *
+ *
+ * SingleResponse res[] = new SingleResponse[singleResponses.size()];
+ * singleResponses.copyInto(res);
+ *
+ * X500Name name = getName();
+ * Name.Template nameTemplate = new Name.Template();
+ * NameID rid = new NameID((Name)nameTemplate.decode(
+ * new ByteArrayInputStream(name.getEncoded())));
+ * ResponseData rd = new ResponseData(rid, new GeneralizedTime(
+ * CMS.getCurrentDate()), res);
+ *
+ * BasicOCSPResponse basicRes = sign(rd);
+ *
+ * OCSPResponse response = new OCSPResponse(
+ * OCSPResponseStatus.SUCCESSFUL,
+ * new ResponseBytes(ResponseBytes.OCSP_BASIC,
+ * new OCTET_STRING(ASN1Util.encode(basicRes))));
+ *
+ * log(ILogger.LL_INFO, "done OCSP request");
+ * return response;
+ * } catch (Exception e) {
+ * log(ILogger.LL_FAILURE, "request processing failure " + e);
+ * return null;
+ * }
+ * }
+ **/
+
+ /**
+ * Returns the in-memory count of the processed OCSP requests.
+ *
+ * @return number of processed OCSP requests in memory
+ */
+ public long getNumOCSPRequest() {
+ return mNumOCSPRequest;
+ }
+
+ /**
+ * Returns the in-memory time (in mini-second) of
+ * the processed time for OCSP requests.
+ *
+ * @return processed times for OCSP requests
+ */
+ public long getOCSPRequestTotalTime() {
+ return mTotalTime;
+ }
+
+ /**
+ * Returns the in-memory time (in mini-second) of
+ * the signing time for OCSP requests.
+ *
+ * @return processed times for OCSP requests
+ */
+ public long getOCSPTotalSignTime() {
+ return mSignTime;
+ }
+
+ public long getOCSPTotalLookupTime() {
+ return mLookupTime;
+ }
+
+ /**
+ * Returns the total data signed
+ * for OCSP requests.
+ *
+ * @return processed times for OCSP requests
+ */
+ public long getOCSPTotalData() {
+ return mTotalData;
+ }
+
+ public void incTotalTime(long inc) {
+ mTotalTime += inc;
+ }
+
+ public void incSignTime(long inc) {
+ mSignTime += inc;
+ }
+
+ public void incLookupTime(long inc) {
+ mLookupTime += inc;
+ }
+
+ public void incNumOCSPRequest(long inc) {
+ mNumOCSPRequest += inc;
+ }
+}
diff --git a/base/ocsp/src/com/netscape/ocsp/OCSPResources.java b/base/ocsp/src/com/netscape/ocsp/OCSPResources.java
new file mode 100644
index 000000000..7fb1e5a86
--- /dev/null
+++ b/base/ocsp/src/com/netscape/ocsp/OCSPResources.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.ocsp;
+
+import java.util.ListResourceBundle;
+
+/**
+ * A class represents a resource bundle for OCSP subsystem.
+ * <P>
+ *
+ * @version $Revision$ $Date$
+ */
+public class OCSPResources 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/base/ocsp/src/com/netscape/ocsp/SigningUnit.java b/base/ocsp/src/com/netscape/ocsp/SigningUnit.java
new file mode 100644
index 000000000..27d4e5c9b
--- /dev/null
+++ b/base/ocsp/src/com/netscape/ocsp/SigningUnit.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.ocsp;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.SignatureException;
+
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509Key;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.NoSuchTokenException;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.ObjectNotFoundException;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.crypto.Signature;
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.util.IncorrectPasswordException;
+import org.mozilla.jss.util.PasswordCallback;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.common.Constants;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.security.ISigningUnit;
+import com.netscape.cmscore.security.JssSubsystem;
+import com.netscape.cmsutil.util.Cert;
+
+/**
+ * OCSP signing unit based on JSS.
+ *
+ * $Revision$ $Date$
+ */
+
+public final class SigningUnit implements ISigningUnit {
+ public static final String PROP_DEFAULT_SIGNALG = "defaultSigningAlgorithm";
+ public static final String PROP_CERT_NICKNAME = "certnickname";
+ public static final String PROP_TOKEN_NAME = "tokenname";
+ public static final String PROP_NEW_NICKNAME = "newNickname";
+
+ private CryptoManager mManager = null;
+ private CryptoToken mToken = null;
+ private PublicKey mPubk = null;
+ private PrivateKey mPrivk = null;
+
+ protected X509Certificate mCert = null;
+ protected X509CertImpl mCertImpl = null;
+ protected String mNickname = null;
+
+ private boolean mInited = false;
+ private ILogger mLogger = CMS.getLogger();
+ private IConfigStore mConfig;
+
+ private ISubsystem mOwner = null;
+
+ private String mDefSigningAlgname = null;
+ private SignatureAlgorithm mDefSigningAlgorithm = null;
+
+ public SigningUnit() {
+ }
+
+ public X509Certificate getCert() {
+ return mCert;
+ }
+
+ public X509CertImpl getCertImpl() {
+ return mCertImpl;
+ }
+
+ public String getNickname() {
+ return mNickname;
+ }
+
+ public String getNewNickName() throws EBaseException {
+ return mConfig.getString(PROP_NEW_NICKNAME, "");
+ }
+
+ public void setNewNickName(String name) {
+ mConfig.putString(PROP_NEW_NICKNAME, name);
+ }
+
+ public PublicKey getPublicKey() {
+ return mPubk;
+ }
+
+ public PrivateKey getPrivateKey() {
+ return mPrivk;
+ }
+
+ public void updateConfig(String nickname, String tokenname) {
+ mConfig.putString(PROP_CERT_NICKNAME, nickname);
+ mConfig.putString(PROP_TOKEN_NAME, tokenname);
+ }
+
+ public String getTokenName() throws EBaseException {
+ return mConfig.getString(PROP_TOKEN_NAME);
+ }
+
+ public String getNickName() throws EBaseException {
+ return mConfig.getString(PROP_CERT_NICKNAME);
+ }
+
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mOwner = owner;
+ mConfig = config;
+
+ String tokenname = null;
+
+ try {
+ mManager = CryptoManager.getInstance();
+
+ mNickname = config.getString(PROP_CERT_NICKNAME);
+ CMS.debug("Reading nickname from " + PROP_CERT_NICKNAME);
+ CMS.debug("OCSP nickname " + mNickname);
+
+ tokenname = config.getString(PROP_TOKEN_NAME);
+ if (tokenname.equalsIgnoreCase(Constants.PR_INTERNAL_TOKEN) ||
+ tokenname.equalsIgnoreCase("Internal Key Storage Token")) {
+ mToken = mManager.getInternalKeyStorageToken();
+ } else {
+ mToken = mManager.getTokenByName(tokenname);
+ mNickname = tokenname + ":" + mNickname;
+ setNewNickName(mNickname);
+ }
+ CMS.debug(config.getName() + " Signing Unit nickname " + mNickname);
+ CMS.debug("Got token " + tokenname + " by name");
+
+ PasswordCallback cb = JssSubsystem.getInstance().getPWCB();
+
+ mToken.login(cb); // ONE_TIME by default.
+
+ mCert = mManager.findCertByNickname(mNickname);
+ CMS.debug("Found cert by nickname: '" + mNickname + "' with serial number: " + mCert.getSerialNumber());
+
+ mCertImpl = new X509CertImpl(mCert.getEncoded());
+ CMS.debug("converted to x509CertImpl");
+
+ mPrivk = mManager.findPrivKeyByCert(mCert);
+ CMS.debug("Got private key from cert");
+
+ mPubk = mCert.getPublicKey();
+ CMS.debug("Got public key from cert");
+
+ // get def alg and check if def sign alg is valid for token.
+ mDefSigningAlgname = config.getString(PROP_DEFAULT_SIGNALG);
+ mDefSigningAlgorithm =
+ checkSigningAlgorithmFromName(mDefSigningAlgname);
+ CMS.debug(
+ "got signing algorithm " + mDefSigningAlgorithm);
+ mInited = true;
+ } catch (java.security.cert.CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_OCSP_CONVERT_X509", e.getMessage()));
+ throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (CryptoManager.NotInitializedException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_OCSP_SIGNING", e.toString()));
+ throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (IncorrectPasswordException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_OCSP_INCORRECT_PWD", e.toString()));
+ throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (NoSuchTokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_OCSP_TOKEN_NOT_FOUND", tokenname, e.toString()));
+ throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (ObjectNotFoundException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_OCSP_OBJECT_NOT_FOUND", e.toString()));
+ throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (TokenException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+ }
+
+ /**
+ * Check if the signing algorithm name is supported and valid for this
+ * signing unit's token and key.
+ *
+ * @param algname a signing algorithm name from JCA.
+ * @return the mapped JSS signature algorithm object.
+ *
+ * @exception EBaseException if signing algorithm is not supported.
+ */
+ public SignatureAlgorithm checkSigningAlgorithmFromName(String algname)
+ throws EBaseException {
+ try {
+ SignatureAlgorithm sigalg = null;
+
+ sigalg = mapAlgorithmToJss(algname);
+ if (sigalg == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_OCSP_SIGN_ALG_NOT_SUPPORTED", algname));
+ throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", ""));
+ }
+ Signature signer = mToken.getSignatureContext(sigalg);
+
+ signer.initSign(mPrivk);
+ return sigalg;
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_OCSP_SIGN_ALG_NOT_SUPPORTED", algname));
+ throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (TokenException e) {
+ // from get signature context or from initSign
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_OCSP_SIGN_ALG_NOT_SUPPORTED", algname));
+ throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (InvalidKeyException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_OCSP_SIGN_ALG_NOT_SUPPORTED", algname));
+ throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+ }
+
+ /**
+ * @param algname is expected to be one of JCA's algorithm names.
+ */
+ public byte[] sign(byte[] data, String algname)
+ throws EBaseException {
+ if (!mInited) {
+ throw new EBaseException("OCSPSigningUnit not initialized!");
+ }
+ try {
+ // XXX for now do this mapping until James changes the names
+ // to match JCA names and provide a getAlgorithm method.
+ SignatureAlgorithm signAlg = mDefSigningAlgorithm;
+
+ if (algname != null) {
+ signAlg = checkSigningAlgorithmFromName(algname);
+ }
+
+ // XXX use a pool of signers based on alg ?
+ // XXX Map algor. name to id. hack: use hardcoded define for now.
+ CMS.debug(
+ "Getting algorithm context for " + algname + " " + signAlg);
+ Signature signer = mToken.getSignatureContext(signAlg);
+
+ signer.initSign(mPrivk);
+ signer.update(data);
+ CMS.debug("Signing OCSP Response");
+ return signer.sign();
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (TokenException e) {
+ // from get signature context or from initSign
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (InvalidKeyException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (SignatureException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+ }
+
+ public boolean verify(byte[] data, byte[] signature, String algname)
+ throws EBaseException {
+ if (!mInited) {
+ throw new EBaseException("OCSPSigningUnit not initialized!");
+ }
+ try {
+ SignatureAlgorithm signAlg = mapAlgorithmToJss(algname);
+
+ if (signAlg == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_OCSP_SIGN_ALG_NOT_SUPPORTED", algname));
+ throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", ""));
+ }
+ // XXX make this configurable. hack: use hardcoded for now.
+ Signature signer = mToken.getSignatureContext(signAlg);
+
+ signer.initVerify(mPubk);
+ signer.update(data);
+ return signer.verify(signature);
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (TokenException e) {
+ // from get signature context or from initSign
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (InvalidKeyException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (SignatureException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+ }
+
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_OCSP,
+ level, "OCSPSigningUnit: " + msg);
+ }
+
+ /**
+ * returns default signature algorithm
+ */
+ public SignatureAlgorithm getDefaultSignatureAlgorithm() {
+ return mDefSigningAlgorithm;
+ }
+
+ /**
+ * returns default signing algorithm name.
+ */
+ public String getDefaultAlgorithm() {
+ return mDefSigningAlgname;
+ }
+
+ public void setDefaultAlgorithm(String algorithm) throws EBaseException {
+ mConfig.putString(PROP_DEFAULT_SIGNALG, algorithm);
+ mDefSigningAlgname = algorithm;
+ log(ILogger.LL_INFO,
+ "Default signing algorithm is set to " + algorithm);
+ }
+
+ /**
+ * get all possible algorithms for the OCSP signing key type.
+ */
+ public String[] getAllAlgorithms() throws EBaseException {
+ byte[] keybytes = mPubk.getEncoded();
+ X509Key key = new X509Key();
+
+ try {
+ key.decode(keybytes);
+ } catch (java.security.InvalidKeyException e) {
+ String msg = "Invalid encoding in OCSP signing key.";
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_OCSP_INVALID_ENCODING"));
+ throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", msg));
+ }
+
+ if (key.getAlgorithmId().getOID().equals(AlgorithmId.DSA_oid)) {
+ return AlgorithmId.DSA_SIGNING_ALGORITHMS;
+ } else {
+ return AlgorithmId.ALL_SIGNING_ALGORITHMS;
+ }
+ }
+
+ public static SignatureAlgorithm mapAlgorithmToJss(String algname) {
+ return Cert.mapAlgorithmToJss(algname);
+ }
+}
diff --git a/base/ra/CMakeLists.txt b/base/ra/CMakeLists.txt
new file mode 100644
index 000000000..59910fe95
--- /dev/null
+++ b/base/ra/CMakeLists.txt
@@ -0,0 +1,76 @@
+project(ra)
+
+add_subdirectory(doc)
+add_subdirectory(setup)
+
+# install init script
+install(
+ FILES
+ etc/init.d/pki-rad
+ DESTINATION
+ ${SYSCONF_INSTALL_DIR}/rc.d/init.d
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+install(
+ DIRECTORY
+ apache/conf/
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/conf
+)
+
+install(
+ DIRECTORY
+ emails/
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/conf
+)
+
+install(
+ DIRECTORY
+ forms/
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/docroot
+)
+
+install(
+ DIRECTORY
+ lib/
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/lib
+)
+
+install(
+ FILES
+ scripts/nss_pcache
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/scripts
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+install(
+ FILES
+ scripts/schema.sql
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/scripts
+)
+
+# install empty directories
+install(
+ DIRECTORY
+ DESTINATION
+ ${VAR_INSTALL_DIR}/lock/pki/ra
+)
+
+install(
+ DIRECTORY
+ DESTINATION
+ ${VAR_INSTALL_DIR}/run/pki/ra
+)
+
diff --git a/base/ra/LICENSE b/base/ra/LICENSE
new file mode 100644
index 000000000..e281f4362
--- /dev/null
+++ b/base/ra/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/base/ra/apache/conf/httpd.conf b/base/ra/apache/conf/httpd.conf
new file mode 100644
index 000000000..9f81b646d
--- /dev/null
+++ b/base/ra/apache/conf/httpd.conf
@@ -0,0 +1,1074 @@
+#
+# Based upon the NCSA server configuration files originally by Rob McCool.
+#
+# This is the main Apache server configuration file. It contains the
+# configuration directives that give the server its instructions.
+# See <URL:http://httpd.apache.org/docs-2.0/> for detailed information about
+# the directives.
+#
+# Do NOT simply read the instructions in here without understanding
+# what they do. They're here only as hints or reminders. If you are unsure
+# consult the online docs. You have been warned.
+#
+# The configuration directives are grouped into three basic sections:
+# 1. Directives that control the operation of the Apache server process as a
+# whole (the 'global environment').
+# 2. Directives that define the parameters of the 'main' or 'default' server,
+# which responds to requests that aren't handled by a virtual host.
+# These directives also provide default values for the settings
+# of all virtual hosts.
+# 3. Settings for virtual hosts, which allow Web requests to be sent to
+# different IP addresses or hostnames and have them handled by the
+# same Apache server process.
+#
+# Configuration and logfile names: If the filenames you specify for many
+# of the server's control files begin with "/" (or "drive:/" for Win32), the
+# server will use that explicit path. If the filenames do *not* begin
+# with "/", the value of ServerRoot is prepended -- so "logs/foo.log"
+# with ServerRoot set to "/export/apache" will be interpreted by the
+# server as "/export/apache/logs/foo.log".
+#
+
+### Section 1: Global Environment
+#
+# The directives in this section affect the overall operation of Apache,
+# such as the number of concurrent requests it can handle or where it
+# can find its configuration files.
+#
+
+#
+# ServerRoot: The top of the directory tree under which the server's
+# configuration, error, and log files are kept.
+#
+# NOTE! If you intend to place this on an NFS (or otherwise network)
+# mounted filesystem then please read the LockFile documentation (available
+# at <URL:http://httpd.apache.org/docs-2.0/mod/mpm_common.html#lockfile>);
+# you will save yourself a lot of trouble.
+#
+# Do NOT add a slash at the end of the directory path.
+#
+ServerRoot "[SERVER_ROOT]"
+
+#
+# The accept serialization lock file MUST BE STORED ON A LOCAL DISK.
+#
+<IfModule !mpm_winnt.c>
+<IfModule !mpm_netware.c>
+#LockFile logs/accept.lock
+</IfModule>
+</IfModule>
+
+#
+# ScoreBoardFile: File used to store internal server process information.
+# If unspecified (the default), the scoreboard will be stored in an
+# anonymous shared memory segment, and will be unavailable to third-party
+# applications.
+# If specified, ensure that no two invocations of Apache share the same
+# scoreboard file. The scoreboard file MUST BE STORED ON A LOCAL DISK.
+#
+<IfModule !mpm_netware.c>
+<IfModule !perchild.c>
+#ScoreBoardFile logs/apache_runtime_status
+</IfModule>
+</IfModule>
+
+
+#
+# PidFile: The file in which the server should record its process
+# identification number when it starts.
+#
+<IfModule !mpm_netware.c>
+PidFile run/[PKI_INSTANCE_ID].pid
+</IfModule>
+
+#
+# Timeout: The number of seconds before receives and sends time out.
+#
+Timeout 300
+
+#
+# KeepAlive: Whether or not to allow persistent connections (more than
+# one request per connection). Set to "Off" to deactivate.
+#
+KeepAlive On
+
+#
+# MaxKeepAliveRequests: The maximum number of requests to allow
+# during a persistent connection. Set to 0 to allow an unlimited amount.
+# We recommend you leave this number high, for maximum performance.
+#
+MaxKeepAliveRequests 100
+
+#
+# KeepAliveTimeout: Number of seconds to wait for the next request from the
+# same client on the same connection.
+#
+KeepAliveTimeout 15
+
+##
+## Server-Pool Size Regulation (MPM specific)
+##
+
+# prefork MPM
+# StartServers: number of server processes to start
+# MinSpareServers: minimum number of server processes which are kept spare
+# MaxSpareServers: maximum number of server processes which are kept spare
+# MaxClients: maximum number of server processes allowed to start
+# MaxRequestsPerChild: maximum number of requests a server process serves
+<IfModule prefork.c>
+StartServers 5
+MinSpareServers 5
+MaxSpareServers 10
+MaxClients 150
+MaxRequestsPerChild 0
+</IfModule>
+
+# worker MPM
+# StartServers: initial number of server processes to start
+# MaxClients: maximum number of simultaneous client connections
+# MinSpareThreads: minimum number of worker threads which are kept spare
+# MaxSpareThreads: maximum number of worker threads which are kept spare
+# ThreadsPerChild: constant number of worker threads in each server process
+# MaxRequestsPerChild: maximum number of requests a server process serves
+<IfModule worker.c>
+ServerLimit 1
+StartServers 1
+MaxClients 64
+MinSpareThreads 1
+MaxSpareThreads 75
+ThreadsPerChild 64
+MaxRequestsPerChild 0
+</IfModule>
+
+# perchild MPM
+# NumServers: constant number of server processes
+# StartThreads: initial number of worker threads in each server process
+# MinSpareThreads: minimum number of worker threads which are kept spare
+# MaxSpareThreads: maximum number of worker threads which are kept spare
+# MaxThreadsPerChild: maximum number of worker threads in each server process
+# MaxRequestsPerChild: maximum number of connections per server process
+<IfModule perchild.c>
+NumServers 5
+StartThreads 5
+MinSpareThreads 5
+MaxSpareThreads 10
+MaxThreadsPerChild 20
+MaxRequestsPerChild 0
+</IfModule>
+
+# WinNT MPM
+# ThreadsPerChild: constant number of worker threads in the server process
+# MaxRequestsPerChild: maximum number of requests a server process serves
+<IfModule mpm_winnt.c>
+ThreadsPerChild 250
+MaxRequestsPerChild 0
+</IfModule>
+
+# BeOS MPM
+# StartThreads: how many threads do we initially spawn?
+# MaxClients: max number of threads we can have (1 thread == 1 client)
+# MaxRequestsPerThread: maximum number of requests each thread will process
+<IfModule beos.c>
+StartThreads 10
+MaxClients 50
+MaxRequestsPerThread 10000
+</IfModule>
+
+# NetWare MPM
+# ThreadStackSize: Stack size allocated for each worker thread
+# StartThreads: Number of worker threads launched at server startup
+# MinSpareThreads: Minimum number of idle threads, to handle request spikes
+# MaxSpareThreads: Maximum number of idle threads
+# MaxThreads: Maximum number of worker threads alive at the same time
+# MaxRequestsPerChild: Maximum number of requests a thread serves. It is
+# recommended that the default value of 0 be set for this
+# directive on NetWare. This will allow the thread to
+# continue to service requests indefinitely.
+<IfModule mpm_netware.c>
+ThreadStackSize 65536
+StartThreads 250
+MinSpareThreads 25
+MaxSpareThreads 250
+MaxThreads 1000
+MaxRequestsPerChild 0
+MaxMemFree 100
+</IfModule>
+
+# OS/2 MPM
+# StartServers: Number of server processes to maintain
+# MinSpareThreads: Minimum number of idle threads per process,
+# to handle request spikes
+# MaxSpareThreads: Maximum number of idle threads per process
+# MaxRequestsPerChild: Maximum number of connections per server process
+<IfModule mpmt_os2.c>
+StartServers 2
+MinSpareThreads 5
+MaxSpareThreads 10
+MaxRequestsPerChild 0
+</IfModule>
+
+#
+# Listen: Allows you to bind Apache to specific IP addresses and/or
+# ports, instead of the default. See also the <VirtualHost>
+# directive.
+#
+# Change this to Listen on specific IP addresses as shown below to
+# prevent Apache from glomming onto all bound IP addresses (0.0.0.0)
+#
+#Listen 12.34.56.78:80
+
+Listen [PORT]
+
+#
+# Dynamic Shared Object (DSO) Support
+#
+# To be able to use the functionality of a module which was built as a DSO you
+# have to place corresponding `LoadModule' lines at this location so the
+# directives contained in it are actually available _before_ they are used.
+# Statically compiled modules (those listed by `httpd -l') do not need
+# to be loaded here.
+#
+# Example:
+# LoadModule foo_module modules/mod_foo.so
+#
+
+# Required modules for command 'Order':
+[FORTITUDE_AUTH_MODULES]
+# Required module for command 'UserDir':
+LoadModule userdir_module [FORTITUDE_LIB_DIR]/modules/mod_userdir.so
+# Required module for command 'DirectoryIndex':
+LoadModule dir_module [FORTITUDE_LIB_DIR]/modules/mod_dir.so
+# Required module for command 'TypesConfig':
+LoadModule mime_module [FORTITUDE_LIB_DIR]/modules/mod_mime.so
+# Required module for command 'LogFormat':
+LoadModule log_config_module [FORTITUDE_LIB_DIR]/modules/mod_log_config.so
+# Required module for command 'Alias':
+LoadModule alias_module [FORTITUDE_LIB_DIR]/modules/mod_alias.so
+# Required module for command 'SetEnvIf':
+LoadModule setenvif_module [FORTITUDE_LIB_DIR]/modules/mod_setenvif.so
+# Required module for command 'IndexOptions':
+LoadModule autoindex_module [FORTITUDE_LIB_DIR]/modules/mod_autoindex.so
+# Required module for command 'LanguagePriority':
+LoadModule negotiation_module [FORTITUDE_LIB_DIR]/modules/mod_negotiation.so
+# Required module for command 'CGI Scripts':
+LoadModule cgi_module [FORTITUDE_LIB_DIR]/modules/mod_cgi.so
+# Required module for commands in nss.conf:
+[FORTITUDE_NSS_MODULES]
+
+<Location /nk_service>
+ SetHandler nk_service
+</Location>
+
+<Location /tus>
+ SetHandler tus
+</Location>
+
+#
+# Load config files from the config directory "/etc/[PKI_INSTANCE_ID]/conf.d".
+#
+#Include conf.d/*.conf
+Include [SERVER_ROOT]/conf/perl.conf
+
+#
+# ExtendedStatus controls whether Apache will generate "full" status
+# information (ExtendedStatus On) or just basic information (ExtendedStatus
+# Off) when the "server-status" handler is called. The default is Off.
+#
+#ExtendedStatus On
+
+### Section 2: 'Main' server configuration
+#
+# The directives in this section set up the values used by the 'main'
+# server, which responds to any requests that aren't handled by a
+# <VirtualHost> definition. These values also provide defaults for
+# any <VirtualHost> containers you may define later in the file.
+#
+# All of these directives may appear inside <VirtualHost> containers,
+# in which case these default settings will be overridden for the
+# virtual host being defined.
+#
+
+<IfModule !mpm_winnt.c>
+<IfModule !mpm_netware.c>
+#
+# If you wish [PKI_INSTANCE_ID] to run as a different user or group, you must run
+# [PKI_INSTANCE_ID] as root initially and it will switch.
+#
+# User/Group: The name (or #number) of the user/group to run [PKI_INSTANCE_ID] as.
+# . On SCO (ODT 3) use "User nouser" and "Group nogroup".
+# . On HPUX you may not be able to use shared memory as nobody, and the
+# suggested workaround is to create a user www and use that user.
+# NOTE that some kernels refuse to setgid(Group) or semctl(IPC_SET)
+# when the value of (unsigned)Group is above 60000;
+# don't use Group #-1 on these systems!
+#
+User [PKI_USER]
+Group [PKI_GROUP]
+#Group #-1
+</IfModule>
+</IfModule>
+
+#
+# ServerAdmin: Your address, where problems with the server should be
+# e-mailed. This address appears on some server-generated pages, such
+# as error documents. e.g. admin@your-domain.com
+#
+ServerAdmin you@example.com
+
+#
+# ServerName gives the name and port that the server uses to identify itself.
+# This can often be determined automatically, but we recommend you specify
+# it explicitly to prevent problems during startup.
+#
+# If this is not set to valid DNS name for your host, server-generated
+# redirections will not work. See also the UseCanonicalName directive.
+#
+# If your host doesn't have a registered DNS name, enter its IP address here.
+# You will have to access it by its address anyway, and this will make
+# redirections work in a sensible way.
+#
+#ServerName www.example.com:80
+
+#
+# UseCanonicalName: Determines how Apache constructs self-referencing
+# URLs and the SERVER_NAME and SERVER_PORT variables.
+# When set "Off", Apache will use the Hostname and Port supplied
+# by the client. When set "On", Apache will use the value of the
+# ServerName directive.
+#
+UseCanonicalName Off
+
+#
+# DocumentRoot: The directory out of which you will serve your
+# documents. By default, all requests are taken from this directory, but
+# symbolic links and aliases may be used to point to other locations.
+#
+DocumentRoot "[SERVER_ROOT]/docroot"
+
+#
+# Each directory to which Apache has access can be configured with respect
+# to which services and features are allowed and/or disabled in that
+# directory (and its subdirectories).
+#
+# First, we configure the "default" to be a very restrictive set of
+# features.
+#
+<Directory />
+ Options FollowSymLinks
+ AllowOverride None
+</Directory>
+
+#
+# Note that from this point forward you must specifically allow
+# particular features to be enabled - so if something's not working as
+# you might expect, make sure that you have specifically enabled it
+# below.
+#
+
+#
+# This should be changed to whatever you set DocumentRoot to.
+#
+<Directory "[SERVER_ROOT]/docroot">
+
+#
+# Possible values for the Options directive are "None", "All",
+# or any combination of:
+# Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
+#
+# Note that "MultiViews" must be named *explicitly* --- "Options All"
+# doesn't give it to you.
+#
+# The Options directive is both complicated and important. Please see
+# http://httpd.apache.org/docs-2.0/mod/core.html#options
+# for more information.
+#
+ Options Indexes ExecCGI FollowSymLinks
+
+#
+# AllowOverride controls what directives may be placed in .htaccess files.
+# It can be "All", "None", or any combination of the keywords:
+# Options FileInfo AuthConfig Limit
+#
+ AllowOverride None
+
+#
+# Controls who can get stuff from this server.
+#
+ Order allow,deny
+ Allow from all
+
+</Directory>
+
+#
+# UserDir: The name of the directory that is appended onto a user's home
+# directory if a ~user request is received.
+#
+UserDir public_html
+
+#
+# Control access to UserDir directories. The following is an example
+# for a site where these directories are restricted to read-only.
+#
+#<Directory /home/*/public_html>
+# AllowOverride FileInfo AuthConfig Limit Indexes
+# Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
+# <Limit GET POST OPTIONS PROPFIND>
+# Order allow,deny
+# Allow from all
+# </Limit>
+# <LimitExcept GET POST OPTIONS PROPFIND>
+# Order deny,allow
+# Deny from all
+# </LimitExcept>
+#</Directory>
+
+#
+# DirectoryIndex: sets the file that Apache will serve if a directory
+# is requested.
+#
+# The index.html.var file (a type-map) is used to deliver content-
+# negotiated documents. The MultiViews Option can be used for the
+# same purpose, but it is much slower.
+#
+DirectoryIndex index.html index.html.var index.cgi
+
+#
+# AccessFileName: The name of the file to look for in each directory
+# for additional configuration directives. See also the AllowOverride
+# directive.
+#
+AccessFileName .htaccess
+
+#
+# The following lines prevent .htaccess and .htpasswd files from being
+# viewed by Web clients.
+#
+<Files ~ "^\.ht">
+ Order allow,deny
+ Deny from all
+</Files>
+
+#
+# TypesConfig describes where the mime.types file (or equivalent) is
+# to be found.
+#
+TypesConfig conf/mime.types
+
+#
+# DefaultType is the default MIME type the server will use for a document
+# if it cannot otherwise determine one, such as from filename extensions.
+# If your server contains mostly text or HTML documents, "text/plain" is
+# a good value. If most of your content is binary, such as applications
+# or images, you may want to use "application/octet-stream" instead to
+# keep browsers from trying to display binary files as though they are
+# text.
+#
+DefaultType text/plain
+
+#
+# The mod_mime_magic module allows the server to use various hints from the
+# contents of the file itself to determine its type. The MIMEMagicFile
+# directive tells the module where the hint definitions are located.
+#
+<IfModule mod_mime_magic.c>
+ MIMEMagicFile conf/magic
+</IfModule>
+
+#
+# HostnameLookups: Log the names of clients or just their IP addresses
+# e.g., www.apache.org (on) or 204.62.129.132 (off).
+# The default is off because it'd be overall better for the net if people
+# had to knowingly turn this feature on, since enabling it means that
+# each client request will result in AT LEAST one lookup request to the
+# nameserver.
+#
+HostnameLookups Off
+
+#
+# EnableMMAP: Control whether memory-mapping is used to deliver
+# files (assuming that the underlying OS supports it).
+# The default is on; turn this off if you serve from NFS-mounted
+# filesystems. On some systems, turning it off (regardless of
+# filesystem) can improve performance; for details, please see
+# http://httpd.apache.org/docs-2.0/mod/core.html#enablemmap
+#
+#EnableMMAP off
+
+#
+# EnableSendfile: Control whether the sendfile kernel support is
+# used to deliver files (assuming that the OS supports it).
+# The default is on; turn this off if you serve from NFS-mounted
+# filesystems. Please see
+# http://httpd.apache.org/docs-2.0/mod/core.html#enablesendfile
+#
+#EnableSendfile off
+
+#
+# ErrorLog: The location of the error log file.
+# If you do not specify an ErrorLog directive within a <VirtualHost>
+# container, error messages relating to that virtual host will be
+# logged here. If you *do* define an error logfile for a <VirtualHost>
+# container, that host's errors will be logged there and not here.
+#
+ErrorLog logs/error_log
+
+#
+# LogLevel: Control the number of messages logged to the error_log.
+# Possible values include: debug, info, notice, warn, error, crit,
+# alert, emerg.
+#
+#LogLevel warn
+LogLevel debug
+
+#
+# The following directives define some format nicknames for use with
+# a CustomLog directive (see below).
+#
+LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
+LogFormat "%h %l %u %t \"%r\" %>s %b" common
+LogFormat "%{Referer}i -> %U" referer
+LogFormat "%{User-agent}i" agent
+
+# You need to enable mod_logio.c to use %I and %O
+#LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
+
+#
+# The location and format of the access logfile (Common Logfile Format).
+# If you do not define any access logfiles within a <VirtualHost>
+# container, they will be logged here. Contrariwise, if you *do*
+# define per-<VirtualHost> access logfiles, transactions will be
+# logged therein and *not* in this file.
+#
+CustomLog logs/access_log common
+
+#
+# If you would like to have agent and referer logfiles, uncomment the
+# following directives.
+#
+#CustomLog logs/referer_log referer
+#CustomLog logs/agent_log agent
+
+#
+# If you prefer a single logfile with access, agent, and referer information
+# (Combined Logfile Format) you can use the following directive.
+#
+#CustomLog logs/access_log combined
+
+#
+# ServerTokens
+# This directive configures what you return as the Server HTTP response
+# Header. The default is 'Full' which sends information about the OS-Type
+# and compiled in modules.
+# Set to one of: Full | OS | Minor | Minimal | Major | Prod
+# where Full conveys the most information, and Prod the least.
+#
+ServerTokens Prod
+
+#
+# Optionally add a line containing the server version and virtual host
+# name to server-generated pages (internal error documents, FTP directory
+# listings, mod_status and mod_info output etc., but not CGI generated
+# documents or custom error documents).
+# Set to "EMail" to also include a mailto: link to the ServerAdmin.
+# Set to one of: On | Off | EMail
+#
+ServerSignature Off
+
+#
+# Aliases: Add here as many aliases as you need (with no limit). The format is
+# Alias fakename realname
+#
+# Note that if you include a trailing / on fakename then the server will
+# require it to be present in the URL. So "/icons" isn't aliased in this
+# example, only "/icons/". If the fakename is slash-terminated, then the
+# realname must also be slash terminated, and if the fakename omits the
+# trailing slash, the realname must also omit it.
+#
+# We include the /icons/ alias for FancyIndexed directory listings. If you
+# do not use FancyIndexing, you may comment this out.
+#
+Alias /icons/ "[SERVER_ROOT]/icons/"
+
+<Directory "[SERVER_ROOT]/icons">
+ Options Indexes MultiViews
+ AllowOverride None
+ Order allow,deny
+ Allow from all
+</Directory>
+
+#
+# This should be changed to the ServerRoot/manual/. The alias provides
+# the manual, even if you choose to move your DocumentRoot. You may comment
+# this out if you do not care for the documentation.
+#
+AliasMatch ^/manual(?:/(?:de|en|es|fr|ja|ko|ru))?(/.*)?$ "[SERVER_ROOT]/manual$1"
+
+<Directory "[SERVER_ROOT]/manual">
+ Options Indexes
+ AllowOverride None
+ Order allow,deny
+ Allow from all
+
+ <Files *.html>
+ SetHandler type-map
+ </Files>
+
+ SetEnvIf Request_URI ^/manual/(de|en|es|fr|ja|ko|ru)/ prefer-language=$1
+ RedirectMatch 301 ^/manual(?:/(de|en|es|fr|ja|ko|ru)){2,}(/.*)?$ /manual/$1$2
+</Directory>
+
+#
+# ScriptAlias: This controls which directories contain server scripts.
+# ScriptAliases are essentially the same as Aliases, except that
+# documents in the realname directory are treated as applications and
+# run by the server when requested rather than as documents sent to the client.
+# The same rules about trailing "/" apply to ScriptAlias directives as to
+# Alias.
+#
+ScriptAlias /cgi-bin/ "[SERVER_ROOT]/cgi-bin/"
+
+<IfModule mod_cgid.c>
+#
+# Additional to mod_cgid.c settings, mod_cgid has Scriptsock <path>
+# for setting UNIX socket for communicating with cgid.
+#
+#Scriptsock logs/cgisock
+</IfModule>
+
+#
+# "[SERVER_ROOT]/cgi-bin" should be changed to whatever your ScriptAliased
+# CGI directory exists, if you have that configured.
+#
+<Directory "[SERVER_ROOT]/cgi-bin">
+ AllowOverride None
+ Options ExecCGI
+ Order allow,deny
+ Allow from all
+</Directory>
+
+#
+# Redirect allows you to tell clients about documents which used to exist in
+# your server's namespace, but do not anymore. This allows you to tell the
+# clients where to look for the relocated document.
+# Example:
+# Redirect permanent /foo http://www.example.com/bar
+
+#
+# Directives controlling the display of server-generated directory listings.
+#
+
+#
+# IndexOptions: Controls the appearance of server-generated directory
+# listings.
+#
+IndexOptions FancyIndexing VersionSort
+
+#
+# AddIcon* directives tell the server which icon to show for different
+# files or filename extensions. These are only displayed for
+# FancyIndexed directories.
+#
+AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip
+
+AddIconByType (TXT,/icons/text.gif) text/*
+AddIconByType (IMG,/icons/image2.gif) image/*
+AddIconByType (SND,/icons/sound2.gif) audio/*
+AddIconByType (VID,/icons/movie.gif) video/*
+
+AddIcon /icons/binary.gif .bin .exe
+AddIcon /icons/binhex.gif .hqx
+AddIcon /icons/tar.gif .tar
+AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv
+AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip
+AddIcon /icons/a.gif .ps .ai .eps
+AddIcon /icons/layout.gif .html .shtml .htm .pdf
+AddIcon /icons/text.gif .txt
+AddIcon /icons/c.gif .c
+AddIcon /icons/p.gif .pl .py
+AddIcon /icons/f.gif .for
+AddIcon /icons/dvi.gif .dvi
+AddIcon /icons/uuencoded.gif .uu
+AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
+AddIcon /icons/tex.gif .tex
+AddIcon /icons/bomb.gif core
+
+AddIcon /icons/back.gif ..
+AddIcon /icons/hand.right.gif README
+AddIcon /icons/folder.gif ^^DIRECTORY^^
+AddIcon /icons/blank.gif ^^BLANKICON^^
+
+#
+# DefaultIcon is which icon to show for files which do not have an icon
+# explicitly set.
+#
+DefaultIcon /icons/unknown.gif
+
+#
+# AddDescription allows you to place a short description after a file in
+# server-generated indexes. These are only displayed for FancyIndexed
+# directories.
+# Format: AddDescription "description" filename
+#
+#AddDescription "GZIP compressed document" .gz
+#AddDescription "tar archive" .tar
+#AddDescription "GZIP compressed tar archive" .tgz
+
+#
+# ReadmeName is the name of the README file the server will look for by
+# default, and append to directory listings.
+#
+# HeaderName is the name of a file which should be prepended to
+# directory indexes.
+ReadmeName README.html
+HeaderName HEADER.html
+
+#
+# IndexIgnore is a set of filenames which directory indexing should ignore
+# and not include in the listing. Shell-style wildcarding is permitted.
+#
+IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t
+
+#
+# DefaultLanguage and AddLanguage allows you to specify the language of
+# a document. You can then use content negotiation to give a browser a
+# file in a language the user can understand.
+#
+# Specify a default language. This means that all data
+# going out without a specific language tag (see below) will
+# be marked with this one. You probably do NOT want to set
+# this unless you are sure it is correct for all cases.
+#
+# * It is generally better to not mark a page as
+# * being a certain language than marking it with the wrong
+# * language!
+#
+# DefaultLanguage nl
+#
+# Note 1: The suffix does not have to be the same as the language
+# keyword --- those with documents in Polish (whose net-standard
+# language code is pl) may wish to use "AddLanguage pl .po" to
+# avoid the ambiguity with the common suffix for perl scripts.
+#
+# Note 2: The example entries below illustrate that in some cases
+# the two character 'Language' abbreviation is not identical to
+# the two character 'Country' code for its country,
+# E.g. 'Danmark/dk' versus 'Danish/da'.
+#
+# Note 3: In the case of 'ltz' we violate the RFC by using a three char
+# specifier. There is 'work in progress' to fix this and get
+# the reference data for rfc1766 cleaned up.
+#
+# Catalan (ca) - Croatian (hr) - Czech (cs) - Danish (da) - Dutch (nl)
+# English (en) - Esperanto (eo) - Estonian (et) - French (fr) - German (de)
+# Greek-Modern (el) - Hebrew (he) - Italian (it) - Japanese (ja)
+# Korean (ko) - Luxembourgeois* (ltz) - Norwegian Nynorsk (nn)
+# Norwegian (no) - Polish (pl) - Portugese (pt)
+# Brazilian Portuguese (pt-BR) - Russian (ru) - Swedish (sv)
+# Simplified Chinese (zh-CN) - Spanish (es) - Traditional Chinese (zh-TW)
+#
+AddLanguage ca .ca
+AddLanguage cs .cz .cs
+AddLanguage da .dk
+AddLanguage de .de
+AddLanguage el .el
+AddLanguage en .en
+AddLanguage eo .eo
+AddLanguage es .es
+AddLanguage et .et
+AddLanguage fr .fr
+AddLanguage he .he
+AddLanguage hr .hr
+AddLanguage it .it
+AddLanguage ja .ja
+AddLanguage ko .ko
+AddLanguage ltz .ltz
+AddLanguage nl .nl
+AddLanguage nn .nn
+AddLanguage no .no
+AddLanguage pl .po
+AddLanguage pt .pt
+AddLanguage pt-BR .pt-br
+AddLanguage ru .ru
+AddLanguage sv .sv
+AddLanguage zh-CN .zh-cn
+AddLanguage zh-TW .zh-tw
+
+#
+# LanguagePriority allows you to give precedence to some languages
+# in case of a tie during content negotiation.
+#
+# Just list the languages in decreasing order of preference. We have
+# more or less alphabetized them here. You probably want to change this.
+#
+LanguagePriority en ca cs da de el eo es et fr he hr it ja ko ltz nl nn no pl pt pt-BR ru sv zh-CN zh-TW
+
+#
+# ForceLanguagePriority allows you to serve a result page rather than
+# MULTIPLE CHOICES (Prefer) [in case of a tie] or NOT ACCEPTABLE (Fallback)
+# [in case no accepted languages matched the available variants]
+#
+ForceLanguagePriority Prefer Fallback
+
+#
+# Commonly used filename extensions to character sets. You probably
+# want to avoid clashes with the language extensions, unless you
+# are good at carefully testing your setup after each change.
+# See http://www.iana.org/assignments/character-sets for the
+# official list of charset names and their respective RFCs.
+#
+AddCharset ISO-8859-1 .iso8859-1 .latin1
+AddCharset ISO-8859-2 .iso8859-2 .latin2 .cen
+AddCharset ISO-8859-3 .iso8859-3 .latin3
+AddCharset ISO-8859-4 .iso8859-4 .latin4
+AddCharset ISO-8859-5 .iso8859-5 .latin5 .cyr .iso-ru
+AddCharset ISO-8859-6 .iso8859-6 .latin6 .arb
+AddCharset ISO-8859-7 .iso8859-7 .latin7 .grk
+AddCharset ISO-8859-8 .iso8859-8 .latin8 .heb
+AddCharset ISO-8859-9 .iso8859-9 .latin9 .trk
+AddCharset ISO-2022-JP .iso2022-jp .jis
+AddCharset ISO-2022-KR .iso2022-kr .kis
+AddCharset ISO-2022-CN .iso2022-cn .cis
+AddCharset Big5 .Big5 .big5
+# For russian, more than one charset is used (depends on client, mostly):
+AddCharset WINDOWS-1251 .cp-1251 .win-1251
+AddCharset CP866 .cp866
+AddCharset KOI8-r .koi8-r .koi8-ru
+AddCharset KOI8-ru .koi8-uk .ua
+AddCharset ISO-10646-UCS-2 .ucs2
+AddCharset ISO-10646-UCS-4 .ucs4
+AddCharset UTF-8 .utf8
+
+# The set below does not map to a specific (iso) standard
+# but works on a fairly wide range of browsers. Note that
+# capitalization actually matters (it should not, but it
+# does for some browsers).
+#
+# See http://www.iana.org/assignments/character-sets
+# for a list of sorts. But browsers support few.
+#
+AddCharset GB2312 .gb2312 .gb
+AddCharset utf-7 .utf7
+AddCharset utf-8 .utf8
+AddCharset big5 .big5 .b5
+AddCharset EUC-TW .euc-tw
+AddCharset EUC-JP .euc-jp
+AddCharset EUC-KR .euc-kr
+AddCharset shift_jis .sjis
+
+#
+# AddType allows you to add to or override the MIME configuration
+# file mime.types for specific file types.
+#
+#AddType application/x-tar .tgz
+#
+# AddEncoding allows you to have certain browsers uncompress
+# information on the fly. Note: Not all browsers support this.
+# Despite the name similarity, the following Add* directives have nothing
+# to do with the FancyIndexing customization directives above.
+#
+#AddEncoding x-compress .Z
+#AddEncoding x-gzip .gz .tgz
+#
+# If the AddEncoding directives above are commented-out, then you
+# probably should define those extensions to indicate media types:
+#
+AddType application/x-compress .Z
+AddType application/x-gzip .gz .tgz
+
+#
+# AddHandler allows you to map certain file extensions to "handlers":
+# actions unrelated to filetype. These can be either built into the server
+# or added with the Action directive (see below)
+#
+# To use CGI scripts outside of ScriptAliased directories:
+# (You will also need to add "ExecCGI" to the "Options" directive.)
+#
+AddHandler cgi-script .cgi
+
+#
+# For files that include their own HTTP headers:
+#
+#AddHandler send-as-is asis
+
+#
+# For server-parsed imagemap files:
+#
+#AddHandler imap-file map
+
+#
+# For type maps (negotiated resources):
+# (This is enabled by default to allow the Apache "It Worked" page
+# to be distributed in multiple languages.)
+#
+AddHandler type-map var
+
+#
+# Filters allow you to process content before it is sent to the client.
+#
+# To parse .shtml files for server-side includes (SSI):
+# (You will also need to add "Includes" to the "Options" directive.)
+#
+#AddType text/html .shtml
+#AddOutputFilter INCLUDES .shtml
+
+#
+# Action lets you define media types that will execute a script whenever
+# a matching file is called. This eliminates the need for repeated URL
+# pathnames for oft-used CGI file processors.
+# Format: Action media/type /cgi-script/location
+# Format: Action handler-name /cgi-script/location
+#
+
+#
+# Customizable error responses come in three flavors:
+# 1) plain text 2) local redirects 3) external redirects
+#
+# Some examples:
+#ErrorDocument 500 "The server made a boo boo."
+#ErrorDocument 404 /missing.html
+#ErrorDocument 404 "/cgi-bin/missing_handler.pl"
+#ErrorDocument 402 http://www.example.com/subscription_info.html
+#
+
+#
+# Putting this all together, we can internationalize error responses.
+#
+# We use Alias to redirect any /error/HTTP_<error>.html.var response to
+# our collection of by-error message multi-language collections. We use
+# includes to substitute the appropriate text.
+#
+# You can modify the messages' appearance without changing any of the
+# default HTTP_<error>.html.var files by adding the line:
+#
+# Alias /error/include/ "/your/include/path/"
+#
+# which allows you to create your own set of files by starting with the
+# /export/apache/error/include/ files and copying them to /your/include/path/,
+# even on a per-VirtualHost basis. The default include files will display
+# your Apache version number and your ServerAdmin email address regardless
+# of the setting of ServerSignature.
+#
+# The internationalized error documents require mod_alias, mod_include
+# and mod_negotiation. To activate them, uncomment the following 30 lines.
+
+# Alias /error/ "/export/apache/error/"
+#
+# <Directory "/export/apache/error">
+# AllowOverride None
+# Options IncludesNoExec
+# AddOutputFilter Includes html
+# AddHandler type-map var
+# Order allow,deny
+# Allow from all
+# LanguagePriority en cs de es fr it ja ko nl pl pt-br ro sv tr
+# ForceLanguagePriority Prefer Fallback
+# </Directory>
+#
+# ErrorDocument 400 /error/HTTP_BAD_REQUEST.html.var
+# ErrorDocument 401 /error/HTTP_UNAUTHORIZED.html.var
+# ErrorDocument 403 /error/HTTP_FORBIDDEN.html.var
+# ErrorDocument 404 /error/HTTP_NOT_FOUND.html.var
+# ErrorDocument 405 /error/HTTP_METHOD_NOT_ALLOWED.html.var
+# ErrorDocument 408 /error/HTTP_REQUEST_TIME_OUT.html.var
+# ErrorDocument 410 /error/HTTP_GONE.html.var
+# ErrorDocument 411 /error/HTTP_LENGTH_REQUIRED.html.var
+# ErrorDocument 412 /error/HTTP_PRECONDITION_FAILED.html.var
+# ErrorDocument 413 /error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.var
+# ErrorDocument 414 /error/HTTP_REQUEST_URI_TOO_LARGE.html.var
+# ErrorDocument 415 /error/HTTP_UNSUPPORTED_MEDIA_TYPE.html.var
+# ErrorDocument 500 /error/HTTP_INTERNAL_SERVER_ERROR.html.var
+# ErrorDocument 501 /error/HTTP_NOT_IMPLEMENTED.html.var
+# ErrorDocument 502 /error/HTTP_BAD_GATEWAY.html.var
+# ErrorDocument 503 /error/HTTP_SERVICE_UNAVAILABLE.html.var
+# ErrorDocument 506 /error/HTTP_VARIANT_ALSO_VARIES.html.var
+#[ErrorDocument_404]
+#[ErrorDocument_500]
+
+
+#
+# The following directives modify normal HTTP response behavior to
+# handle known problems with browser implementations.
+#
+BrowserMatch "Mozilla/2" nokeepalive
+BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
+BrowserMatch "RealPlayer 4\.0" force-response-1.0
+BrowserMatch "Java/1\.0" force-response-1.0
+BrowserMatch "JDK/1\.0" force-response-1.0
+
+#
+# The following directive disables redirects on non-GET requests for
+# a directory that does not include the trailing slash. This fixes a
+# problem with Microsoft WebFolders which does not appropriately handle
+# redirects for folders with DAV methods.
+# Same deal with Apple's DAV filesystem and Gnome VFS support for DAV.
+#
+BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully
+BrowserMatch "^WebDrive" redirect-carefully
+BrowserMatch "^WebDAVFS/1.[012]" redirect-carefully
+BrowserMatch "^gnome-vfs" redirect-carefully
+
+#
+# Allow server status reports generated by mod_status,
+# with the URL of http://servername/server-status
+# Change the ".example.com" to match your domain to enable.
+#
+#<Location /server-status>
+# SetHandler server-status
+# Order deny,allow
+# Deny from all
+# Allow from .example.com
+#</Location>
+
+#
+# Allow remote server configuration reports, with the URL of
+# http://servername/server-info (requires that mod_info.c be loaded).
+# Change the ".example.com" to match your domain to enable.
+#
+#<Location /server-info>
+# SetHandler server-info
+# Order deny,allow
+# Deny from all
+# Allow from .example.com
+#</Location>
+
+
+#
+# Bring in additional module-specific configurations
+#
+#<IfModule mod_ssl.c>
+# Include conf/ssl.conf
+#</IfModule>
+Include [SERVER_ROOT]/conf/nss.conf
+
+### Section 3: Virtual Hosts
+#
+# VirtualHost: If you want to maintain multiple domains/hostnames on your
+# machine you can setup VirtualHost containers for them. Most configurations
+# use only name-based virtual hosts so the server doesn't need to worry about
+# IP addresses. This is indicated by the asterisks in the directives below.
+#
+# Please see the documentation at
+# <URL:http://httpd.apache.org/docs-2.0/vhosts/>
+# for further details before you try to setup virtual hosts.
+#
+# You may use the command line option '-S' to verify your virtual host
+# configuration.
+
+#
+# Use name-based virtual hosting.
+#
+#NameVirtualHost *:80
+
+#
+# VirtualHost example:
+# Almost any Apache directive may go into a VirtualHost container.
+# The first VirtualHost section is used for requests without a known
+# server name.
+#
+#<VirtualHost *:80>
+# ServerAdmin webmaster@dummy-host.example.com
+# DocumentRoot /www/docs/dummy-host.example.com
+# ServerName dummy-host.example.com
+# ErrorLog logs/dummy-host.example.com-error_log
+# CustomLog logs/dummy-host.example.com-access_log common
+#</VirtualHost>
diff --git a/base/ra/apache/conf/magic b/base/ra/apache/conf/magic
new file mode 100644
index 000000000..0de73361f
--- /dev/null
+++ b/base/ra/apache/conf/magic
@@ -0,0 +1,382 @@
+# Magic data for mod_mime_magic Apache module (originally for file(1) command)
+# The module is described in /manual/mod/mod_mime_magic.html
+#
+# The format is 4-5 columns:
+# Column #1: byte number to begin checking from, ">" indicates continuation
+# Column #2: type of data to match
+# Column #3: contents of data to match
+# Column #4: MIME type of result
+# Column #5: MIME encoding of result (optional)
+
+#------------------------------------------------------------------------------
+# Localstuff: file(1) magic for locally observed files
+# Add any locally observed files here.
+
+#------------------------------------------------------------------------------
+# end local stuff
+#------------------------------------------------------------------------------
+
+#------------------------------------------------------------------------------
+# Java
+
+0 short 0xcafe
+>2 short 0xbabe application/java
+
+#------------------------------------------------------------------------------
+# audio: file(1) magic for sound formats
+#
+# from Jan Nicolai Langfeldt <janl@ifi.uio.no>,
+#
+
+# Sun/NeXT audio data
+0 string .snd
+>12 belong 1 audio/basic
+>12 belong 2 audio/basic
+>12 belong 3 audio/basic
+>12 belong 4 audio/basic
+>12 belong 5 audio/basic
+>12 belong 6 audio/basic
+>12 belong 7 audio/basic
+
+>12 belong 23 audio/x-adpcm
+
+# DEC systems (e.g. DECstation 5000) use a variant of the Sun/NeXT format
+# that uses little-endian encoding and has a different magic number
+# (0x0064732E in little-endian encoding).
+0 lelong 0x0064732E
+>12 lelong 1 audio/x-dec-basic
+>12 lelong 2 audio/x-dec-basic
+>12 lelong 3 audio/x-dec-basic
+>12 lelong 4 audio/x-dec-basic
+>12 lelong 5 audio/x-dec-basic
+>12 lelong 6 audio/x-dec-basic
+>12 lelong 7 audio/x-dec-basic
+# compressed (G.721 ADPCM)
+>12 lelong 23 audio/x-dec-adpcm
+
+# Bytes 0-3 of AIFF, AIFF-C, & 8SVX audio files are "FORM"
+# AIFF audio data
+8 string AIFF audio/x-aiff
+# AIFF-C audio data
+8 string AIFC audio/x-aiff
+# IFF/8SVX audio data
+8 string 8SVX audio/x-aiff
+
+# Creative Labs AUDIO stuff
+# Standard MIDI data
+0 string MThd audio/unknown
+#>9 byte >0 (format %d)
+#>11 byte >1 using %d channels
+# Creative Music (CMF) data
+0 string CTMF audio/unknown
+# SoundBlaster instrument data
+0 string SBI audio/unknown
+# Creative Labs voice data
+0 string Creative\ Voice\ File audio/unknown
+## is this next line right? it came this way...
+#>19 byte 0x1A
+#>23 byte >0 - version %d
+#>22 byte >0 \b.%d
+
+# [GRR 950115: is this also Creative Labs? Guessing that first line
+# should be string instead of unknown-endian long...]
+#0 long 0x4e54524b MultiTrack sound data
+#0 string NTRK MultiTrack sound data
+#>4 long x - version %ld
+
+# Microsoft WAVE format (*.wav)
+# [GRR 950115: probably all of the shorts and longs should be leshort/lelong]
+# Microsoft RIFF
+0 string RIFF audio/unknown
+# - WAVE format
+>8 string WAVE audio/x-wav
+# MPEG audio.
+0 beshort&0xfff0 0xfff0 audio/mpeg
+# C64 SID Music files, from Linus Walleij <triad@df.lth.se>
+0 string PSID audio/prs.sid
+
+#------------------------------------------------------------------------------
+# c-lang: file(1) magic for C programs or various scripts
+#
+
+# XPM icons (Greg Roelofs, newt@uchicago.edu)
+# ideally should go into "images", but entries below would tag XPM as C source
+0 string /*\ XPM image/x-xbm 7bit
+
+# this first will upset you if you're a PL/1 shop... (are there any left?)
+# in which case rm it; ascmagic will catch real C programs
+# C or REXX program text
+0 string /* text/plain
+# C++ program text
+0 string // text/plain
+
+#------------------------------------------------------------------------------
+# compress: file(1) magic for pure-compression formats (no archives)
+#
+# compress, gzip, pack, compact, huf, squeeze, crunch, freeze, yabba, whap, etc.
+#
+# Formats for various forms of compressed data
+# Formats for "compress" proper have been moved into "compress.c",
+# because it tries to uncompress it to figure out what's inside.
+
+# standard unix compress
+0 string \037\235 application/octet-stream x-compress
+
+# gzip (GNU zip, not to be confused with [Info-ZIP/PKWARE] zip archiver)
+0 string \037\213 application/octet-stream x-gzip
+
+# According to gzip.h, this is the correct byte order for packed data.
+0 string \037\036 application/octet-stream
+#
+# This magic number is byte-order-independent.
+#
+0 short 017437 application/octet-stream
+
+# XXX - why *two* entries for "compacted data", one of which is
+# byte-order independent, and one of which is byte-order dependent?
+#
+# compacted data
+0 short 0x1fff application/octet-stream
+0 string \377\037 application/octet-stream
+# huf output
+0 short 0145405 application/octet-stream
+
+# Squeeze and Crunch...
+# These numbers were gleaned from the Unix versions of the programs to
+# handle these formats. Note that I can only uncrunch, not crunch, and
+# I didn't have a crunched file handy, so the crunch number is untested.
+# Keith Waclena <keith@cerberus.uchicago.edu>
+#0 leshort 0x76FF squeezed data (CP/M, DOS)
+#0 leshort 0x76FE crunched data (CP/M, DOS)
+
+# Freeze
+#0 string \037\237 Frozen file 2.1
+#0 string \037\236 Frozen file 1.0 (or gzip 0.5)
+
+# lzh?
+#0 string \037\240 LZH compressed data
+
+#------------------------------------------------------------------------------
+# frame: file(1) magic for FrameMaker files
+#
+# This stuff came on a FrameMaker demo tape, most of which is
+# copyright, but this file is "published" as witness the following:
+#
+0 string \<MakerFile application/x-frame
+0 string \<MIFFile application/x-frame
+0 string \<MakerDictionary application/x-frame
+0 string \<MakerScreenFon application/x-frame
+0 string \<MML application/x-frame
+0 string \<Book application/x-frame
+0 string \<Maker application/x-frame
+
+#------------------------------------------------------------------------------
+# html: file(1) magic for HTML (HyperText Markup Language) docs
+#
+# from Daniel Quinlan <quinlan@yggdrasil.com>
+# and Anna Shergold <anna@inext.co.uk>
+#
+0 string \<!DOCTYPE\ HTML text/html
+0 string \<!doctype\ html text/html
+0 string \<HEAD text/html
+0 string \<head text/html
+0 string \<TITLE text/html
+0 string \<title text/html
+0 string \<html text/html
+0 string \<HTML text/html
+0 string \<!-- text/html
+0 string \<h1 text/html
+0 string \<H1 text/html
+
+# XML eXtensible Markup Language, from Linus Walleij <triad@df.lth.se>
+0 string \<?xml text/xml
+
+#------------------------------------------------------------------------------
+# images: file(1) magic for image formats (see also "c-lang" for XPM bitmaps)
+#
+# originally from jef@helios.ee.lbl.gov (Jef Poskanzer),
+# additions by janl@ifi.uio.no as well as others. Jan also suggested
+# merging several one- and two-line files into here.
+#
+# XXX - byte order for GIF and TIFF fields?
+# [GRR: TIFF allows both byte orders; GIF is probably little-endian]
+#
+
+# [GRR: what the hell is this doing in here?]
+#0 string xbtoa btoa'd file
+
+# PBMPLUS
+# PBM file
+0 string P1 image/x-portable-bitmap 7bit
+# PGM file
+0 string P2 image/x-portable-greymap 7bit
+# PPM file
+0 string P3 image/x-portable-pixmap 7bit
+# PBM "rawbits" file
+0 string P4 image/x-portable-bitmap
+# PGM "rawbits" file
+0 string P5 image/x-portable-greymap
+# PPM "rawbits" file
+0 string P6 image/x-portable-pixmap
+
+# NIFF (Navy Interchange File Format, a modification of TIFF)
+# [GRR: this *must* go before TIFF]
+0 string IIN1 image/x-niff
+
+# TIFF and friends
+# TIFF file, big-endian
+0 string MM image/tiff
+# TIFF file, little-endian
+0 string II image/tiff
+
+# possible GIF replacements; none yet released!
+# (Greg Roelofs, newt@uchicago.edu)
+#
+# GRR 950115: this was mine ("Zip GIF"):
+# ZIF image (GIF+deflate alpha)
+0 string GIF94z image/unknown
+#
+# GRR 950115: this is Jeremy Wohl's Free Graphics Format (better):
+# FGF image (GIF+deflate beta)
+0 string FGF95a image/unknown
+#
+# GRR 950115: this is Thomas Boutell's Portable Bitmap Format proposal
+# (best; not yet implemented):
+# PBF image (deflate compression)
+0 string PBF image/unknown
+
+# GIF
+0 string GIF image/gif
+
+# JPEG images
+0 beshort 0xffd8 image/jpeg
+
+# PC bitmaps (OS/2, Windoze BMP files) (Greg Roelofs, newt@uchicago.edu)
+0 string BM image/bmp
+#>14 byte 12 (OS/2 1.x format)
+#>14 byte 64 (OS/2 2.x format)
+#>14 byte 40 (Windows 3.x format)
+#0 string IC icon
+#0 string PI pointer
+#0 string CI color icon
+#0 string CP color pointer
+#0 string BA bitmap array
+
+
+#------------------------------------------------------------------------------
+# lisp: file(1) magic for lisp programs
+#
+# various lisp types, from Daniel Quinlan (quinlan@yggdrasil.com)
+0 string ;; text/plain 8bit
+# Emacs 18 - this is always correct, but not very magical.
+0 string \012( application/x-elc
+# Emacs 19
+0 string ;ELC\023\000\000\000 application/x-elc
+
+#------------------------------------------------------------------------------
+# mail.news: file(1) magic for mail and news
+#
+# There are tests to ascmagic.c to cope with mail and news.
+0 string Relay-Version: message/rfc822 7bit
+0 string #!\ rnews message/rfc822 7bit
+0 string N#!\ rnews message/rfc822 7bit
+0 string Forward\ to message/rfc822 7bit
+0 string Pipe\ to message/rfc822 7bit
+0 string Return-Path: message/rfc822 7bit
+0 string Path: message/news 8bit
+0 string Xref: message/news 8bit
+0 string From: message/rfc822 7bit
+0 string Article message/news 8bit
+#------------------------------------------------------------------------------
+# msword: file(1) magic for MS Word files
+#
+# Contributor claims:
+# Reversed-engineered MS Word magic numbers
+#
+
+0 string \376\067\0\043 application/msword
+0 string \333\245-\0\0\0 application/msword
+
+# disable this one because it applies also to other
+# Office/OLE documents for which msword is not correct. See PR#2608.
+#0 string \320\317\021\340\241\261 application/msword
+
+
+
+#------------------------------------------------------------------------------
+# printer: file(1) magic for printer-formatted files
+#
+
+# PostScript
+0 string %! application/postscript
+0 string \004%! application/postscript
+
+# Acrobat
+# (due to clamen@cs.cmu.edu)
+0 string %PDF- application/pdf
+
+#------------------------------------------------------------------------------
+# sc: file(1) magic for "sc" spreadsheet
+#
+38 string Spreadsheet application/x-sc
+
+#------------------------------------------------------------------------------
+# tex: file(1) magic for TeX files
+#
+# XXX - needs byte-endian stuff (big-endian and little-endian DVI?)
+#
+# From <conklin@talisman.kaleida.com>
+
+# Although we may know the offset of certain text fields in TeX DVI
+# and font files, we can't use them reliably because they are not
+# zero terminated. [but we do anyway, christos]
+0 string \367\002 application/x-dvi
+#0 string \367\203 TeX generic font data
+#0 string \367\131 TeX packed font data
+#0 string \367\312 TeX virtual font data
+#0 string This\ is\ TeX, TeX transcript text
+#0 string This\ is\ METAFONT, METAFONT transcript text
+
+# There is no way to detect TeX Font Metric (*.tfm) files without
+# breaking them apart and reading the data. The following patterns
+# match most *.tfm files generated by METAFONT or afm2tfm.
+#2 string \000\021 TeX font metric data
+#2 string \000\022 TeX font metric data
+#>34 string >\0 (%s)
+
+# Texinfo and GNU Info, from Daniel Quinlan (quinlan@yggdrasil.com)
+#0 string \\input\ texinfo Texinfo source text
+#0 string This\ is\ Info\ file GNU Info text
+
+# correct TeX magic for Linux (and maybe more)
+# from Peter Tobias (tobias@server.et-inf.fho-emden.de)
+#
+0 leshort 0x02f7 application/x-dvi
+
+# RTF - Rich Text Format
+0 string {\\rtf application/rtf
+
+#------------------------------------------------------------------------------
+# animation: file(1) magic for animation/movie formats
+#
+# animation formats, originally from vax@ccwf.cc.utexas.edu (VaX#n8)
+# MPEG file
+0 string \000\000\001\263 video/mpeg
+#
+# The contributor claims:
+# I couldn't find a real magic number for these, however, this
+# -appears- to work. Note that it might catch other files, too,
+# so BE CAREFUL!
+#
+# Note that title and author appear in the two 20-byte chunks
+# at decimal offsets 2 and 22, respectively, but they are XOR'ed with
+# 255 (hex FF)! DL format SUCKS BIG ROCKS.
+#
+# DL file version 1 , medium format (160x100, 4 images/screen)
+0 byte 1 video/unknown
+0 byte 2 video/unknown
+# Quicktime video, from Linus Walleij <triad@df.lth.se>
+# from Apple quicktime file format documentation.
+4 string moov video/quicktime
+4 string mdat video/quicktime
+
diff --git a/base/ra/apache/conf/mime.types b/base/ra/apache/conf/mime.types
new file mode 100644
index 000000000..3485692d1
--- /dev/null
+++ b/base/ra/apache/conf/mime.types
@@ -0,0 +1,592 @@
+# This is a comment. I love comments.
+
+# This file controls what Internet media types are sent to the client for
+# given file extension(s). Sending the correct media type to the client
+# is important so they know how to handle the content of the file.
+# Extra types can either be added here or by using an AddType directive
+# in your config files. For more information about Internet media types,
+# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type
+# registry is at <http://www.iana.org/assignments/media-types/>.
+
+# MIME type Extensions
+application/activemessage
+application/andrew-inset ez
+application/applefile
+application/atom+xml atom
+application/atomicmail
+application/batch-smtp
+application/beep+xml
+application/cals-1840
+application/cnrp+xml
+application/commonground
+application/cpl+xml
+application/cybercash
+application/dca-rft
+application/dec-dx
+application/dvcs
+application/edi-consent
+application/edifact
+application/edi-x12
+application/eshop
+application/font-tdpfr
+application/http
+application/hyperstudio
+application/iges
+application/index
+application/index.cmd
+application/index.obj
+application/index.response
+application/index.vnd
+application/iotp
+application/ipp
+application/isup
+application/mac-binhex40 hqx
+application/mac-compactpro cpt
+application/macwriteii
+application/marc
+application/mathematica
+application/mathml+xml mathml
+application/msword doc
+application/news-message-id
+application/news-transmission
+application/ocsp-request
+application/ocsp-response
+application/octet-stream bin dms lha lzh exe class so dll dmg
+application/oda oda
+application/ogg ogg
+application/parityfec
+application/pdf pdf
+application/pgp-encrypted
+application/pgp-keys
+application/pgp-signature
+application/pkcs10
+application/pkcs7-mime
+application/pkcs7-signature
+application/pkix-cert
+application/pkix-crl
+application/pkixcmp
+application/postscript ai eps ps
+application/prs.alvestrand.titrax-sheet
+application/prs.cww
+application/prs.nprend
+application/prs.plucker
+application/qsig
+application/rdf+xml rdf
+application/reginfo+xml
+application/remote-printing
+application/riscos
+application/rtf
+application/sdp
+application/set-payment
+application/set-payment-initiation
+application/set-registration
+application/set-registration-initiation
+application/sgml
+application/sgml-open-catalog
+application/sieve
+application/slate
+application/smil smi smil
+application/srgs gram
+application/srgs+xml grxml
+application/timestamp-query
+application/timestamp-reply
+application/tve-trigger
+application/vemmi
+application/vnd.3gpp.pic-bw-large
+application/vnd.3gpp.pic-bw-small
+application/vnd.3gpp.pic-bw-var
+application/vnd.3gpp.sms
+application/vnd.3m.post-it-notes
+application/vnd.accpac.simply.aso
+application/vnd.accpac.simply.imp
+application/vnd.acucobol
+application/vnd.acucorp
+application/vnd.adobe.xfdf
+application/vnd.aether.imp
+application/vnd.amiga.ami
+application/vnd.anser-web-certificate-issue-initiation
+application/vnd.anser-web-funds-transfer-initiation
+application/vnd.audiograph
+application/vnd.blueice.multipass
+application/vnd.bmi
+application/vnd.businessobjects
+application/vnd.canon-cpdl
+application/vnd.canon-lips
+application/vnd.cinderella
+application/vnd.claymore
+application/vnd.commerce-battelle
+application/vnd.commonspace
+application/vnd.contact.cmsg
+application/vnd.cosmocaller
+application/vnd.criticaltools.wbs+xml
+application/vnd.ctc-posml
+application/vnd.cups-postscript
+application/vnd.cups-raster
+application/vnd.cups-raw
+application/vnd.curl
+application/vnd.cybank
+application/vnd.data-vision.rdz
+application/vnd.dna
+application/vnd.dpgraph
+application/vnd.dreamfactory
+application/vnd.dxr
+application/vnd.ecdis-update
+application/vnd.ecowin.chart
+application/vnd.ecowin.filerequest
+application/vnd.ecowin.fileupdate
+application/vnd.ecowin.series
+application/vnd.ecowin.seriesrequest
+application/vnd.ecowin.seriesupdate
+application/vnd.enliven
+application/vnd.epson.esf
+application/vnd.epson.msf
+application/vnd.epson.quickanime
+application/vnd.epson.salt
+application/vnd.epson.ssf
+application/vnd.ericsson.quickcall
+application/vnd.eudora.data
+application/vnd.fdf
+application/vnd.ffsns
+application/vnd.fints
+application/vnd.flographit
+application/vnd.framemaker
+application/vnd.fsc.weblaunch
+application/vnd.fujitsu.oasys
+application/vnd.fujitsu.oasys2
+application/vnd.fujitsu.oasys3
+application/vnd.fujitsu.oasysgp
+application/vnd.fujitsu.oasysprs
+application/vnd.fujixerox.ddd
+application/vnd.fujixerox.docuworks
+application/vnd.fujixerox.docuworks.binder
+application/vnd.fut-misnet
+application/vnd.grafeq
+application/vnd.groove-account
+application/vnd.groove-help
+application/vnd.groove-identity-message
+application/vnd.groove-injector
+application/vnd.groove-tool-message
+application/vnd.groove-tool-template
+application/vnd.groove-vcard
+application/vnd.hbci
+application/vnd.hhe.lesson-player
+application/vnd.hp-hpgl
+application/vnd.hp-hpid
+application/vnd.hp-hps
+application/vnd.hp-pcl
+application/vnd.hp-pclxl
+application/vnd.httphone
+application/vnd.hzn-3d-crossword
+application/vnd.ibm.afplinedata
+application/vnd.ibm.electronic-media
+application/vnd.ibm.minipay
+application/vnd.ibm.modcap
+application/vnd.ibm.rights-management
+application/vnd.ibm.secure-container
+application/vnd.informix-visionary
+application/vnd.intercon.formnet
+application/vnd.intertrust.digibox
+application/vnd.intertrust.nncp
+application/vnd.intu.qbo
+application/vnd.intu.qfx
+application/vnd.irepository.package+xml
+application/vnd.is-xpr
+application/vnd.japannet-directory-service
+application/vnd.japannet-jpnstore-wakeup
+application/vnd.japannet-payment-wakeup
+application/vnd.japannet-registration
+application/vnd.japannet-registration-wakeup
+application/vnd.japannet-setstore-wakeup
+application/vnd.japannet-verification
+application/vnd.japannet-verification-wakeup
+application/vnd.jisp
+application/vnd.kde.karbon
+application/vnd.kde.kchart
+application/vnd.kde.kformula
+application/vnd.kde.kivio
+application/vnd.kde.kontour
+application/vnd.kde.kpresenter
+application/vnd.kde.kspread
+application/vnd.kde.kword
+application/vnd.kenameaapp
+application/vnd.koan
+application/vnd.liberty-request+xml
+application/vnd.llamagraphics.life-balance.desktop
+application/vnd.llamagraphics.life-balance.exchange+xml
+application/vnd.lotus-1-2-3
+application/vnd.lotus-approach
+application/vnd.lotus-freelance
+application/vnd.lotus-notes
+application/vnd.lotus-organizer
+application/vnd.lotus-screencam
+application/vnd.lotus-wordpro
+application/vnd.mcd
+application/vnd.mediastation.cdkey
+application/vnd.meridian-slingshot
+application/vnd.micrografx.flo
+application/vnd.micrografx.igx
+application/vnd.mif mif
+application/vnd.minisoft-hp3000-save
+application/vnd.mitsubishi.misty-guard.trustweb
+application/vnd.mobius.daf
+application/vnd.mobius.dis
+application/vnd.mobius.mbk
+application/vnd.mobius.mqy
+application/vnd.mobius.msl
+application/vnd.mobius.plc
+application/vnd.mobius.txf
+application/vnd.mophun.application
+application/vnd.mophun.certificate
+application/vnd.motorola.flexsuite
+application/vnd.motorola.flexsuite.adsi
+application/vnd.motorola.flexsuite.fis
+application/vnd.motorola.flexsuite.gotap
+application/vnd.motorola.flexsuite.kmr
+application/vnd.motorola.flexsuite.ttc
+application/vnd.motorola.flexsuite.wem
+application/vnd.mozilla.xul+xml xul
+application/vnd.ms-artgalry
+application/vnd.ms-asf
+application/vnd.ms-excel xls
+application/vnd.ms-lrm
+application/vnd.ms-powerpoint ppt
+application/vnd.ms-project
+application/vnd.ms-tnef
+application/vnd.ms-works
+application/vnd.ms-wpl
+application/vnd.mseq
+application/vnd.msign
+application/vnd.music-niff
+application/vnd.musician
+application/vnd.netfpx
+application/vnd.noblenet-directory
+application/vnd.noblenet-sealer
+application/vnd.noblenet-web
+application/vnd.novadigm.edm
+application/vnd.novadigm.edx
+application/vnd.novadigm.ext
+application/vnd.obn
+application/vnd.osa.netdeploy
+application/vnd.palm
+application/vnd.pg.format
+application/vnd.pg.osasli
+application/vnd.powerbuilder6
+application/vnd.powerbuilder6-s
+application/vnd.powerbuilder7
+application/vnd.powerbuilder7-s
+application/vnd.powerbuilder75
+application/vnd.powerbuilder75-s
+application/vnd.previewsystems.box
+application/vnd.publishare-delta-tree
+application/vnd.pvi.ptid1
+application/vnd.pwg-multiplexed
+application/vnd.pwg-xhtml-print+xml
+application/vnd.quark.quarkxpress
+application/vnd.rapid
+application/vnd.s3sms
+application/vnd.sealed.net
+application/vnd.seemail
+application/vnd.shana.informed.formdata
+application/vnd.shana.informed.formtemplate
+application/vnd.shana.informed.interchange
+application/vnd.shana.informed.package
+application/vnd.smaf
+application/vnd.sss-cod
+application/vnd.sss-dtf
+application/vnd.sss-ntf
+application/vnd.street-stream
+application/vnd.svd
+application/vnd.swiftview-ics
+application/vnd.triscape.mxs
+application/vnd.trueapp
+application/vnd.truedoc
+application/vnd.ufdl
+application/vnd.uplanet.alert
+application/vnd.uplanet.alert-wbxml
+application/vnd.uplanet.bearer-choice
+application/vnd.uplanet.bearer-choice-wbxml
+application/vnd.uplanet.cacheop
+application/vnd.uplanet.cacheop-wbxml
+application/vnd.uplanet.channel
+application/vnd.uplanet.channel-wbxml
+application/vnd.uplanet.list
+application/vnd.uplanet.list-wbxml
+application/vnd.uplanet.listcmd
+application/vnd.uplanet.listcmd-wbxml
+application/vnd.uplanet.signal
+application/vnd.vcx
+application/vnd.vectorworks
+application/vnd.vidsoft.vidconference
+application/vnd.visio
+application/vnd.visionary
+application/vnd.vividence.scriptfile
+application/vnd.vsf
+application/vnd.wap.sic
+application/vnd.wap.slc
+application/vnd.wap.wbxml wbxml
+application/vnd.wap.wmlc wmlc
+application/vnd.wap.wmlscriptc wmlsc
+application/vnd.webturbo
+application/vnd.wrq-hp3000-labelled
+application/vnd.wt.stf
+application/vnd.wv.csp+wbxml
+application/vnd.xara
+application/vnd.xfdl
+application/vnd.yamaha.hv-dic
+application/vnd.yamaha.hv-script
+application/vnd.yamaha.hv-voice
+application/vnd.yellowriver-custom-menu
+application/voicexml+xml vxml
+application/watcherinfo+xml
+application/whoispp-query
+application/whoispp-response
+application/wita
+application/wordperfect5.1
+application/x-bcpio bcpio
+application/x-cdlink vcd
+application/x-chess-pgn pgn
+application/x-compress
+application/x-cpio cpio
+application/x-csh csh
+application/x-director dcr dir dxr
+application/x-dvi dvi
+application/x-futuresplash spl
+application/x-gtar gtar
+application/x-gzip
+application/x-hdf hdf
+application/x-javascript js
+application/x-koan skp skd skt skm
+application/x-latex latex
+application/x-netcdf nc cdf
+application/x-sh sh
+application/x-shar shar
+application/x-shockwave-flash swf
+application/x-stuffit sit
+application/x-sv4cpio sv4cpio
+application/x-sv4crc sv4crc
+application/x-tar tar
+application/x-tcl tcl
+application/x-tex tex
+application/x-texinfo texinfo texi
+application/x-troff t tr roff
+application/x-troff-man man
+application/x-troff-me me
+application/x-troff-ms ms
+application/x-ustar ustar
+application/x-wais-source src
+application/x400-bp
+application/xhtml+xml xhtml xht
+application/xslt+xml xslt
+application/xml xml xsl
+application/xml-dtd dtd
+application/xml-external-parsed-entity
+application/zip zip
+audio/32kadpcm
+audio/amr
+audio/amr-wb
+audio/basic au snd
+audio/cn
+audio/dat12
+audio/dsr-es201108
+audio/dvi4
+audio/evrc
+audio/evrc0
+audio/g722
+audio/g.722.1
+audio/g723
+audio/g726-16
+audio/g726-24
+audio/g726-32
+audio/g726-40
+audio/g728
+audio/g729
+audio/g729D
+audio/g729E
+audio/gsm
+audio/gsm-efr
+audio/l8
+audio/l16
+audio/l20
+audio/l24
+audio/lpc
+audio/midi mid midi kar
+audio/mpa
+audio/mpa-robust
+audio/mp4a-latm
+audio/mpeg mpga mp2 mp3
+audio/parityfec
+audio/pcma
+audio/pcmu
+audio/prs.sid
+audio/qcelp
+audio/red
+audio/smv
+audio/smv0
+audio/telephone-event
+audio/tone
+audio/vdvi
+audio/vnd.3gpp.iufp
+audio/vnd.cisco.nse
+audio/vnd.cns.anp1
+audio/vnd.cns.inf1
+audio/vnd.digital-winds
+audio/vnd.everad.plj
+audio/vnd.lucent.voice
+audio/vnd.nortel.vbk
+audio/vnd.nuera.ecelp4800
+audio/vnd.nuera.ecelp7470
+audio/vnd.nuera.ecelp9600
+audio/vnd.octel.sbc
+audio/vnd.qcelp
+audio/vnd.rhetorex.32kadpcm
+audio/vnd.vmx.cvsd
+audio/x-aiff aif aiff aifc
+audio/x-alaw-basic
+audio/x-mpegurl m3u
+audio/x-pn-realaudio ram ra
+audio/x-pn-realaudio-plugin
+application/vnd.rn-realmedia rm
+audio/x-wav wav
+chemical/x-pdb pdb
+chemical/x-xyz xyz
+image/bmp bmp
+image/cgm cgm
+image/g3fax
+image/gif gif
+image/ief ief
+image/jpeg jpeg jpg jpe
+image/naplps
+image/png png
+image/prs.btif
+image/prs.pti
+image/svg+xml svg
+image/t38
+image/tiff tiff tif
+image/tiff-fx
+image/vnd.cns.inf2
+image/vnd.djvu djvu djv
+image/vnd.dwg
+image/vnd.dxf
+image/vnd.fastbidsheet
+image/vnd.fpx
+image/vnd.fst
+image/vnd.fujixerox.edmics-mmr
+image/vnd.fujixerox.edmics-rlc
+image/vnd.globalgraphics.pgb
+image/vnd.mix
+image/vnd.ms-modi
+image/vnd.net-fpx
+image/vnd.svf
+image/vnd.wap.wbmp wbmp
+image/vnd.xiff
+image/x-cmu-raster ras
+image/x-icon ico
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm
+image/x-portable-graymap pgm
+image/x-portable-pixmap ppm
+image/x-rgb rgb
+image/x-xbitmap xbm
+image/x-xpixmap xpm
+image/x-xwindowdump xwd
+message/delivery-status
+message/disposition-notification
+message/external-body
+message/http
+message/news
+message/partial
+message/rfc822
+message/s-http
+message/sip
+message/sipfrag
+model/iges igs iges
+model/mesh msh mesh silo
+model/vnd.dwf
+model/vnd.flatland.3dml
+model/vnd.gdl
+model/vnd.gs-gdl
+model/vnd.gtw
+model/vnd.mts
+model/vnd.parasolid.transmit.binary
+model/vnd.parasolid.transmit.text
+model/vnd.vtu
+model/vrml wrl vrml
+multipart/alternative
+multipart/appledouble
+multipart/byteranges
+multipart/digest
+multipart/encrypted
+multipart/form-data
+multipart/header-set
+multipart/mixed
+multipart/parallel
+multipart/related
+multipart/report
+multipart/signed
+multipart/voice-message
+text/calendar ics ifb
+text/css css
+text/directory
+text/enriched
+text/html html htm
+text/parityfec
+text/plain asc txt
+text/prs.lines.tag
+text/rfc822-headers
+text/richtext rtx
+text/rtf rtf
+text/sgml sgml sgm
+text/t140
+text/tab-separated-values tsv
+text/uri-list
+text/vnd.abc
+text/vnd.curl
+text/vnd.dmclientscript
+text/vnd.fly
+text/vnd.fmi.flexstor
+text/vnd.in3d.3dml
+text/vnd.in3d.spot
+text/vnd.iptc.nitf
+text/vnd.iptc.newsml
+text/vnd.latex-z
+text/vnd.motorola.reflex
+text/vnd.ms-mediapackage
+text/vnd.net2phone.commcenter.command
+text/vnd.sun.j2me.app-descriptor
+text/vnd.wap.si
+text/vnd.wap.sl
+text/vnd.wap.wml wml
+text/vnd.wap.wmlscript wmls
+text/x-setext etx
+text/xml
+text/xml-external-parsed-entity
+video/bmpeg
+video/bt656
+video/celb
+video/dv
+video/h261
+video/h263
+video/h263-1998
+video/h263-2000
+video/jpeg
+video/mp1s
+video/mp2p
+video/mp2t
+video/mp4v-es
+video/mpv
+video/mpeg mpeg mpg mpe
+video/nv
+video/parityfec
+video/pointer
+video/quicktime qt mov
+video/smpte292m
+video/vnd.fvt
+video/vnd.motorola.video
+video/vnd.motorola.videop
+video/vnd.mpegurl mxu m4u
+video/vnd.nokia.interleaved-multimedia
+video/vnd.objectvideo
+video/vnd.vivo
+video/x-msvideo avi
+video/x-sgi-movie movie
+x-conference/x-cooltalk ice
diff --git a/base/ra/apache/conf/nss.conf b/base/ra/apache/conf/nss.conf
new file mode 100644
index 000000000..a3e0621ab
--- /dev/null
+++ b/base/ra/apache/conf/nss.conf
@@ -0,0 +1,267 @@
+#
+# This is the Apache server configuration file providing SSL support using.
+# the mod_nss plugin. It contains the configuration directives to instruct
+# the server how to serve pages over an https connection.
+#
+# Do NOT simply read the instructions in here without understanding
+# what they do. They're here only as hints or reminders. If you are unsure
+# consult the online docs. You have been warned.
+#
+
+#
+# When we also provide SSL we have to listen to the
+# standard HTTP port (see above) and to the HTTPS port
+#
+# Note: Configurations that use IPv6 but not IPv4-mapped addresses need two
+# Listen directives: "Listen [::]:443" and "Listen 0.0.0.0:443"
+#
+Listen [SECURE_PORT]
+
+Listen [NON_CLIENTAUTH_SECURE_PORT]
+
+##
+## SSL Global Context
+##
+## All SSL configuration in this context applies both to
+## the main server and all SSL-enabled virtual hosts.
+##
+
+#
+# Some MIME-types for downloading Certificates and CRLs
+#
+AddType application/x-x509-ca-cert .crt
+AddType application/x-pkcs7-crl .crl
+
+# Pass Phrase Dialog:
+# Configure the pass phrase gathering process.
+# The filtering dialog program (`builtin' is a internal
+# terminal dialog) has to provide the pass phrase on stdout.
+#NSSPassPhraseDialog builtin
+NSSPassPhraseDialog defer:[SERVER_ROOT]/conf/password.conf
+
+
+# Pass Phrase Helper:
+# This helper program stores the token password pins between
+# restarts of Apache.
+NSSPassPhraseHelper /usr/share/pki/ra/scripts/nss_pcache
+
+# Configure the SSL Session Cache.
+# SSLSessionCacheSize is the number of entries in the cache.
+# SSLSessionCacheTimeout is the SSL2 session timeout (in seconds).
+# SSL3SessionCacheTimeout is the SSL3/TLS session timeout (in seconds).
+NSSSessionCacheSize 10000
+NSSSessionCacheTimeout 100
+NSSSession3CacheTimeout 86400
+
+##
+## SSL Virtual Host Context
+##
+
+<VirtualHost _default_:[SECURE_PORT]>
+
+# General setup for the virtual host
+#DocumentRoot "/htdocs"
+#ServerName [Server_Name]:[Secure_Port]
+#ServerAdmin you@example.com
+
+# Configure OCSP checking of client certs
+
+#NSSOCSP on
+#NSSOCSPDefaultResponder on
+
+# URL of the ocsp service
+#
+# Example of the built in ocsp service of the CS CA
+#
+#NSSOCSPDefaultURL http://localhost:9180/ca/ocsp
+
+# Nickname of ocsp signing cert
+#
+# Below is sufficient if using built in CS CA ocsp service
+# If using outboard ocsp, make sure the cert listed below
+# is imported into the local cert database.
+#
+#NSSOCSPDefaultName caCert
+
+# mod_ssl logs to separate log files, you can choose to do that if you'd like
+ErrorLog [SERVER_ROOT]/logs/error_log
+TransferLog [SERVER_ROOT]/logs/access_log
+
+# SSL Engine Switch:
+# Enable/Disable SSL for this virtual host.
+NSSEngine on
+
+# SSL Cipher Suite:
+# List the ciphers that the client is permitted to negotiate.
+# See the mod_nss documentation for a complete list.
+NSSCipherSuite -des,-desede3,-rc2,-rc2export,-rc4,-rc4export,+rsa_3des_sha,-rsa_des_56_sha,+rsa_des_sha,-rsa_null_md5,-rsa_null_sha,-rsa_rc2_40_md5,+rsa_rc4_128_md5,-rsa_rc4_128_sha,-rsa_rc4_40_md5,-rsa_rc4_56_sha,-fortezza,-fortezza_rc4_128_sha,-fortezza_null,-fips_des_sha,+fips_3des_sha,-rsa_aes_128_sha,-rsa_aes_256_sha,+ecdhe_ecdsa_aes_256_sha
+
+NSSProtocol SSLv3,TLSv1
+
+# SSL Certificate Nickname:
+# The nickname of the server certificate you are going to use.
+NSSNickname "Server-Cert cert-[PKI_INSTANCE_ID]"
+
+# Server Certificate Database:
+# The NSS security database directory that holds the certificates and
+# keys. The database consists of 3 files: cert8.db, key3.db and secmod.db.
+# Provide the directory that these files exist.
+NSSCertificateDatabase [SERVER_ROOT]/alias
+
+# Client Authentication (Type):
+# Client certificate verification type. Types are none, optional and
+# require.
+NSSVerifyClient require
+
+# Access Control:
+# With SSLRequire you can do per-directory access control based
+# on arbitrary complex boolean expressions containing server
+# variable checks and other lookup directives. The syntax is a
+# mixture between C and Perl. See the mod_nss documentation
+# for more details.
+#<Location />
+#SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \
+# and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \
+# and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \
+# and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \
+# and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \
+# or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/
+#</Location>
+
+# SSL Engine Options:
+# Set various options for the SSL engine.
+# o FakeBasicAuth:
+# Translate the client X.509 into a Basic Authorisation. This means that
+# the standard Auth/DBMAuth methods can be used for access control. The
+# user name is the `one line' version of the client's X.509 certificate.
+# Note that no password is obtained from the user. Every entry in the user
+# file needs this password: `xxj31ZMTZzkVA'.
+# o ExportCertData:
+# This exports two additional environment variables: SSL_CLIENT_CERT and
+# SSL_SERVER_CERT. These contain the PEM-encoded certificates of the
+# server (always existing) and the client (only existing when client
+# authentication is used). This can be used to import the certificates
+# into CGI scripts.
+# o StdEnvVars:
+# This exports the standard SSL/TLS related `SSL_*' environment variables.
+# Per default this exportation is switched off for performance reasons,
+# because the extraction step is an expensive operation and is usually
+# useless for serving static content. So one usually enables the
+# exportation for CGI and SSI requests only.
+# o StrictRequire:
+# This denies access when "SSLRequireSSL" or "SSLRequire" applied even
+# under a "Satisfy any" situation, i.e. when it applies access is denied
+# and no other module can change it.
+# o OptRenegotiate:
+# This enables optimized SSL connection renegotiation handling when SSL
+# directives are used in per-directory context.
+#SSLOptions +FakeBasicAuth +ExportCertData +CompatEnvVars +StrictRequire
+<Files ~ "\.(cgi|shtml|phtml|php3?)$">
+ NSSOptions +StdEnvVars +ExportCertData
+</Files>
+<Directory "/cgi-bin">
+ NSSOptions +StdEnvVars
+</Directory>
+
+# Per-Server Logging:
+# The home of a custom SSL log file. Use this when you want a
+# compact non-error SSL logfile on a virtual host basis.
+#CustomLog [SERVER_ROOT]/logs/ssl_request_log \
+# "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
+
+</VirtualHost>
+
+<VirtualHost _default_:[NON_CLIENTAUTH_SECURE_PORT]>
+
+# General setup for the virtual host
+#DocumentRoot "/htdocs"
+#ServerName [Server_Name]:[Non_Clientauth_Secure_Port]
+#ServerAdmin you@example.com
+
+# mod_ssl logs to separate log files, you can choose to do that if you'd like
+ErrorLog [SERVER_ROOT]/logs/error_log
+TransferLog [SERVER_ROOT]/logs/access_log
+
+# SSL Engine Switch:
+# Enable/Disable SSL for this virtual host.
+NSSEngine on
+
+# SSL Cipher Suite:
+# List the ciphers that the client is permitted to negotiate.
+# See the mod_nss documentation for a complete list.
+NSSCipherSuite -des,-desede3,-rc2,-rc2export,-rc4,-rc4export,+rsa_3des_sha,-rsa_des_56_sha,+rsa_des_sha,-rsa_null_md5,-rsa_null_sha,-rsa_rc2_40_md5,+rsa_rc4_128_md5,-rsa_rc4_128_sha,-rsa_rc4_40_md5,-rsa_rc4_56_sha,-fortezza,-fortezza_rc4_128_sha,-fortezza_null,-fips_des_sha,+fips_3des_sha,-rsa_aes_128_sha,-rsa_aes_256_sha,+ecdhe_ecdsa_aes_256_sha
+
+NSSProtocol SSLv3,TLSv1
+
+# SSL Certificate Nickname:
+# The nickname of the server certificate you are going to use.
+NSSNickname "Server-Cert cert-[PKI_INSTANCE_ID]"
+
+# Server Certificate Database:
+# The NSS security database directory that holds the certificates and
+# keys. The database consists of 3 files: cert8.db, key3.db and secmod.db.
+# Provide the directory that these files exist.
+NSSCertificateDatabase [SERVER_ROOT]/alias
+
+# Client Authentication (Type):
+# Client certificate verification type. Types are none, optional and
+# require.
+NSSVerifyClient none
+
+# Access Control:
+# With SSLRequire you can do per-directory access control based
+# on arbitrary complex boolean expressions containing server
+# variable checks and other lookup directives. The syntax is a
+# mixture between C and Perl. See the mod_nss documentation
+# for more details.
+#<Location />
+#SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \
+# and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \
+# and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \
+# and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \
+# and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \
+# or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/
+#</Location>
+
+# SSL Engine Options:
+# Set various options for the SSL engine.
+# o FakeBasicAuth:
+# Translate the client X.509 into a Basic Authorisation. This means that
+# the standard Auth/DBMAuth methods can be used for access control. The
+# user name is the `one line' version of the client's X.509 certificate.
+# Note that no password is obtained from the user. Every entry in the user
+# file needs this password: `xxj31ZMTZzkVA'.
+# o ExportCertData:
+# This exports two additional environment variables: SSL_CLIENT_CERT and
+# SSL_SERVER_CERT. These contain the PEM-encoded certificates of the
+# server (always existing) and the client (only existing when client
+# authentication is used). This can be used to import the certificates
+# into CGI scripts.
+# o StdEnvVars:
+# This exports the standard SSL/TLS related `SSL_*' environment variables.
+# Per default this exportation is switched off for performance reasons,
+# because the extraction step is an expensive operation and is usually
+# useless for serving static content. So one usually enables the
+# exportation for CGI and SSI requests only.
+# o StrictRequire:
+# This denies access when "SSLRequireSSL" or "SSLRequire" applied even
+# under a "Satisfy any" situation, i.e. when it applies access is denied
+# and no other module can change it.
+# o OptRenegotiate:
+# This enables optimized SSL connection renegotiation handling when SSL
+# directives are used in per-directory context.
+#SSLOptions +FakeBasicAuth +ExportCertData +CompatEnvVars +StrictRequire
+<Files ~ "\.(cgi|shtml|phtml|php3?)$">
+ NSSOptions +StdEnvVars +ExportCertData
+</Files>
+<Directory "/cgi-bin">
+ NSSOptions +StdEnvVars
+</Directory>
+
+# Per-Server Logging:
+# The home of a custom SSL log file. Use this when you want a
+# compact non-error SSL logfile on a virtual host basis.
+#CustomLog [SERVER_ROOT]/logs/ssl_request_log \
+# "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
+
+</VirtualHost>
diff --git a/base/ra/apache/conf/perl.conf b/base/ra/apache/conf/perl.conf
new file mode 100644
index 000000000..50139cdab
--- /dev/null
+++ b/base/ra/apache/conf/perl.conf
@@ -0,0 +1,102 @@
+#
+# Mod_perl incorporates a Perl interpreter into the Apache web server,
+# so that the Apache web server can directly execute Perl code.
+# Mod_perl links the Perl runtime library into the Apache web server
+# and provides an object-oriented Perl interface for Apache's C
+# language API. The end result is a quicker CGI script turnaround
+# process, since no external Perl interpreter has to be started.
+#
+
+LoadModule perl_module [FORTITUDE_LIB_DIR]/modules/mod_perl.so
+
+# Uncomment this line to globally enable warnings, which will be
+# written to the server's error log. Warnings should be enabled
+# during the development process, but should be disabled on a
+# production server as they affect performance.
+#
+#PerlWarn On
+
+# Uncomment this line to enable taint checking globally. When Perl is
+# running in taint mode various checks are performed to reduce the
+# risk of insecure data being passed to a subshell or being used to
+# modify the filesystem. Unfortunatly many Perl modules are not
+# taint-safe, so you should exercise care before enabling it on a
+# production server.
+#
+#PerlTaintCheck On
+
+# This will allow execution of mod_perl to compile your scripts to
+# subroutines which it will execute directly, avoiding the costly
+# compile process for most requests.
+#
+#Alias /perl /var/www/perl
+#<Directory /var/www/perl>
+# SetHandler perl-script
+# PerlResponseHandler ModPerl::Registry
+# PerlOptions +ParseHeaders
+# Options +ExecCGI
+#</Directory>
+
+# This will allow remote server configuration reports, with the URL of
+# http://servername/perl-status
+# Change the ".your-domain.com" to match your domain to enable.
+#
+#PerlModule Apache::compat
+#<Location /perl-status>
+# SetHandler perl-script
+# PerlResponseHandler Apache::Status
+# Order deny,allow
+# Deny from all
+# Allow from .your-domain.com
+#</Location>
+
+PerlModule ModPerl::Registry
+PerlModule [FORTITUDE_APACHE]::compat
+PerlModule PKI::RA::wizard
+PerlSetEnv PKI_DOCROOT [SERVER_ROOT]/docroot
+PerlSetEnv PKI_ROOT [SERVER_ROOT]
+<Location /ra/admin/console/config/wizard>
+ SetHandler perl-script
+ PerlHandler PKI::RA::Wizard
+ Order deny,allow
+ Allow from all
+</Location>
+
+<Location /ra/admin/console/config/login>
+ SetHandler perl-script
+ PerlHandler PKI::RA::Login
+ Order deny,allow
+ Allow from all
+</Location>
+
+PerlModule ModPerl::PerlRun
+Alias /ee/ [SERVER_ROOT]/docroot/ee/
+<Location /ee/ >
+ SetHandler perl-script
+ PerlHandler ModPerl::PerlRun
+ Options Indexes ExecCGI
+ PerlSendHeader On
+</Location>
+
+Alias /agent/ [SERVER_ROOT]/docroot/agent/
+<Location /agent/ >
+ SetHandler perl-script
+ PerlHandler ModPerl::PerlRun
+ Options Indexes ExecCGI
+ PerlSendHeader On
+</Location>
+
+Alias /admin/ [SERVER_ROOT]/docroot/admin/
+<Location /admin/ >
+ SetHandler perl-script
+ PerlHandler ModPerl::PerlRun
+ Options Indexes ExecCGI
+ PerlSendHeader On
+</Location>
+
+<Location /index.cgi >
+ SetHandler perl-script
+ PerlHandler ModPerl::PerlRun
+ Options Indexes ExecCGI
+ PerlSendHeader On
+</Location>
diff --git a/base/ra/doc/CMakeLists.txt b/base/ra/doc/CMakeLists.txt
new file mode 100644
index 000000000..4cebbe1c9
--- /dev/null
+++ b/base/ra/doc/CMakeLists.txt
@@ -0,0 +1,10 @@
+set(VERSION ${APPLICATION_VERSION})
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CS.cfg.in ${CMAKE_CURRENT_BINARY_DIR}/CS.cfg @ONLY)
+
+install(
+ FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/CS.cfg
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/conf
+)
diff --git a/base/ra/doc/CS.cfg.in b/base/ra/doc/CS.cfg.in
new file mode 100644
index 000000000..0581e3a78
--- /dev/null
+++ b/base/ra/doc/CS.cfg.in
@@ -0,0 +1,242 @@
+_000=##
+_001=## Registration Authority (RA) Configuration File
+_002=##
+pidDir=[PKI_PIDDIR]
+pkicreate.pki_instance_root=[PKI_INSTANCE_ROOT]
+pkicreate.pki_instance_name=[PKI_INSTANCE_ID]
+pkicreate.subsystem_type=[PKI_SUBSYSTEM_TYPE]
+pkicreate.secure_port=[SECURE_PORT]
+pkicreate.non_clientauth_secure_port=[NON_CLIENTAUTH_SECURE_PORT]
+pkicreate.unsecure_port=[PORT]
+pkicreate.user=[PKI_USER]
+pkicreate.group=[PKI_GROUP]
+pkiremove.cert.subsystem.nickname=subsystemCert cert-[PKI_INSTANCE_ID]
+request._000=#########################################
+request._001=# Request Queue Parameters
+request._002=#########################################
+agent.authorized_groups=administrators,agents
+admin.authorized_groups=administrators
+database.dbfile=[SERVER_ROOT]/conf/dbfile
+database.lockfile=[SERVER_ROOT]/conf/dblock
+request.renewal.approve_request.0.ca=ca1
+request.renewal.approve_request.0.plugin=PKI::Request::Plugin::RequestToCA
+request.renewal.approve_request.0.profileId=caDualRAuserCert
+request.renewal.approve_request.0.reqType=crmf
+request.renewal.approve_request.1.mailTo=$created_by
+request.renewal.approve_request.1.plugin=PKI::Request::Plugin::EmailNotification
+request.renewal.approve_request.1.templateDir=/usr/share/pki/ra/conf
+request.renewal.approve_request.1.templateFile=mail_approve_request.vm
+request.renewal.approve_request.num_plugins=2
+request.renewal.reject_request.num_plugins=0
+request.renewal.create_request.0.assignTo=agents
+request.renewal.create_request.0.plugin=PKI::Request::Plugin::AutoAssign
+request.renewal.create_request.1.mailTo=$created_by
+request.renewal.create_request.1.plugin=PKI::Request::Plugin::EmailNotification
+request.renewal.create_request.1.templateDir=/usr/share/pki/ra/conf
+request.renewal.create_request.1.templateFile=mail_create_request.vm
+request.renewal.create_request.num_plugins=2
+request.scep.profileId=caRARouterCert
+request.scep.reqType=pkcs10
+request.scep.create_request.num_plugins=2
+request.scep.create_request.0.plugin=PKI::Request::Plugin::AutoAssign
+request.scep.create_request.0.assignTo=agents
+request.scep.create_request.1.plugin=PKI::Request::Plugin::EmailNotification
+request.scep.create_request.1.mailTo=
+request.scep.create_request.1.templateDir=/usr/share/pki/ra/conf
+request.scep.create_request.1.templateFile=mail_create_request.vm
+request.scep.approve_request.num_plugins=1
+request.scep.approve_request.0.plugin=PKI::Request::Plugin::CreatePin
+request.scep.approve_request.0.pinFormat=$site_id
+request.scep.reject_request.num_plugins=0
+request.agent.profileId=caRAagentCert
+request.agent.reqType=crmf
+request.agent.create_request.num_plugins=2
+request.agent.create_request.0.plugin=PKI::Request::Plugin::AutoAssign
+request.agent.create_request.0.assignTo=agents
+request.agent.create_request.1.plugin=PKI::Request::Plugin::EmailNotification
+request.agent.create_request.1.mailTo=
+request.agent.create_request.1.templateDir=/usr/share/pki/ra/conf
+request.agent.create_request.1.templateFile=mail_create_request.vm
+request.agent.approve_request.num_plugins=1
+request.agent.approve_request.0.plugin=PKI::Request::Plugin::CreatePin
+request.agent.approve_request.0.pinFormat=$uid
+request.agent.reject_request.num_plugins=0
+request.user.create_request.num_plugins=2
+request.user.create_request.0.plugin=PKI::Request::Plugin::AutoAssign
+request.user.create_request.0.assignTo=agents
+request.user.create_request.1.plugin=PKI::Request::Plugin::EmailNotification
+request.user.create_request.1.templateDir=/usr/share/pki/ra/conf
+request.user.create_request.1.templateFile=mail_create_request.vm
+request.user.create_request.1.mailTo=
+request.user.approve_request.num_plugins=2
+request.user.approve_request.0.plugin=PKI::Request::Plugin::RequestToCA
+request.user.approve_request.0.ca=ca1
+request.user.approve_request.0.profileId=caDualRAuserCert
+request.user.approve_request.0.reqType=crmf
+request.user.approve_request.1.plugin=PKI::Request::Plugin::EmailNotification
+request.user.approve_request.1.mailTo=$created_by
+request.user.approve_request.1.templateDir=/usr/share/pki/ra/conf
+request.user.approve_request.1.templateFile=mail_approve_request.vm
+request.user.reject_request.num_plugins=0
+request.server.create_request.num_plugins=2
+request.server.create_request.0.plugin=PKI::Request::Plugin::AutoAssign
+request.server.create_request.0.assignTo=agents
+request.server.create_request.1.plugin=PKI::Request::Plugin::EmailNotification
+request.server.create_request.1.mailTo=
+request.server.create_request.1.templateDir=/usr/share/pki/ra/conf
+request.server.create_request.1.templateFile=mail_create_request.vm
+request.server.approve_request.num_plugins=2
+request.server.approve_request.0.plugin=PKI::Request::Plugin::RequestToCA
+request.server.approve_request.0.ca=ca1
+request.server.approve_request.0.profileId=caRAserverCert
+request.server.approve_request.0.reqType=pkcs10
+request.server.approve_request.1.plugin=PKI::Request::Plugin::EmailNotification
+request.server.approve_request.1.mailTo=$created_by
+request.server.approve_request.1.templateDir=/usr/share/pki/ra/conf
+request.server.approve_request.1.templateFile=mail_approve_request.vm
+request.server.reject_request.num_plugins=0
+cs.type=RA
+service.machineName=[SERVER_NAME]
+service.instanceDir=[SERVER_ROOT]
+service.securePort=[SECURE_PORT]
+service.non_clientauth_securePort=[NON_CLIENTAUTH_SECURE_PORT]
+service.unsecurePort=[PORT]
+service.instanceID=[PKI_INSTANCE_ID]
+logging._000=#########################################
+logging._001=# RA configuration File
+logging._002=#
+logging._003=# All <...> must be replaced with
+logging._004=# appropriate values.
+logging._005=#########################################
+logging._006=########################################
+logging._007=# logging
+logging._008=#
+logging._009=# logging.debug.enable:
+logging._010=# logging.audit.enable:
+logging._011=# logging.error.enable:
+logging._012=# - enable or disable the corresponding logging
+logging._013=# logging.debug.filename:
+logging._014=# logging.audit.filename:
+logging._015=# logging.error.filename:
+logging._016=# - name of the log file
+logging._017=# logging.debug.level:
+logging._018=# logging.audit.level:
+logging._019=# logging.error.level:
+logging._020=# - level of logging. (0-10)
+logging._021=# 0 - no logging,
+logging._022=# 4 - LL_PER_SERVER these messages will occur only once
+logging._023=# during the entire invocation of the
+logging._024=# server, e. g. at startup or shutdown
+logging._025=# time., reading the conf parameters.
+logging._026=# Perhaps other infrequent events
+logging._027=# relating to failing over of CA, TKS,
+logging._028=# too
+logging._029=# 6 - LL_PER_CONNECTION these messages happen once per
+logging._030=# connection - most of the log events
+logging._031=# will be at this level
+logging._032=# 8 - LL_PER_PDU these messages relate to PDU
+logging._033=# processing. If you have something that
+logging._034=# is done for every PDU, such as
+logging._035=# applying the MAC, it should be logged
+logging._036=# at this level
+logging._037=# 9 - LL_ALL_DATA_IN_PDU dump all the data in the PDU - a more
+logging._038=# chatty version of the above
+logging._039=# 10 - all logging
+logging._040=#########################################
+logging.debug.enable=true
+logging.debug.filename=[SERVER_ROOT]/logs/ra-debug.log
+logging.debug.level=7
+logging.audit.enable=true
+logging.audit.filename=[SERVER_ROOT]/logs/ra-audit.log
+logging.audit.level=10
+logging.error.enable=true
+logging.error.filename=[SERVER_ROOT]/logs/ra-error.log
+logging.error.level=10
+conn.ca1._000=#########################################
+conn.ca1._001=# CA connection
+conn.ca1._002=#
+conn.ca1._003=# conn.ca<n>.hostport:
+conn.ca1._004=# - host name and port number of your CA, format is host:port
+conn.ca1._005=# conn.ca<n>.clientNickname:
+conn.ca1._006=# - nickname of the client certificate for
+conn.ca1._007=# authentication
+conn.ca1._008=# conn.ca<n>.servlet.enrollment:
+conn.ca1._009=# - servlet to contact in CA
+conn.ca1._010=# - must be '/ca/ee/ca/profileSubmitSSLClient'
+conn.ca1._008=# conn.ca<n>.servlet.addagent:
+conn.ca1._009=# - servlet to add ra agent on CA
+conn.ca1._010=# - must be '/ca/admin/ca/registerRaUser
+conn.ca1._011=# conn.ca<n>.retryConnect:
+conn.ca1._012=# - number of reconnection attempts on failure
+conn.ca1._013=# conn.ca<n>.timeout:
+conn.ca1._014=# - connection timeout
+conn.ca1._015=# conn.ca<n>.SSLOn:
+conn.ca1._016=# - enable SSL or not
+conn.ca1._017=# conn.ca<n>.keepAlive:
+conn.ca1._018=# - enable keep alive or not
+conn.ca1._019=#
+conn.ca1._020=# where
+conn.ca1._021=# <n> - CA connection ID
+conn.ca1._022=#########################################
+failover.pod.enable=false
+conn.ca1.hostport=[CA_HOST]:[CA_PORT]
+conn.ca1.clientNickname=[HSM_LABEL][NICKNAME]
+conn.ca1.servlet.enrollment=/ca/ee/ca/profileSubmitSSLClient
+conn.ca1.servlet.addagent=/ca/admin/ca/registerRaUser
+conn.ca1.servlet.revoke=/ca/subsystem/ca/doRevoke
+conn.ca1.servlet.unrevoke=/ca/subsystem/ca/doUnrevoke
+conn.ca1.retryConnect=3
+conn.ca1.timeout=100
+conn.ca1.SSLOn=true
+conn.ca1.keepAlive=true
+preop.pin=[PKI_RANDOM_NUMBER]
+preop.product.version=@VERSION@
+preop.cert._000=#########################################
+preop.cert._001=# Installation configuration "preop" certs parameters
+preop.cert._002=#########################################
+preop.cert.list=sslserver,subsystem
+preop.cert.sslserver.enable=true
+preop.cert.subsystem.enable=true
+preop.cert.sslserver.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.sslserver.dn=CN=[SERVER_NAME], OU=[PKI_INSTANCE_ID]
+preop.cert.sslserver.keysize.customsize=2048
+preop.cert.sslserver.keysize.size=2048
+preop.cert.sslserver.keysize.select=custom
+preop.cert.sslserver.nickname=Server-Cert cert-[PKI_INSTANCE_ID]
+preop.cert.sslserver.profile=caInternalAuthServerCert
+preop.cert.sslserver.subsystem=ra
+preop.cert._003=#preop.cert.sslserver.type=local
+preop.cert.sslserver.userfriendlyname=SSL Server Certificate
+preop.cert._004=#preop.cert.sslserver.cncomponent.override=false
+preop.cert.subsystem.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.subsystem.dn=CN=RA Subsystem Certificate, OU=[PKI_INSTANCE_ID]
+preop.cert.subsystem.keysize.customsize=2048
+preop.cert.subsystem.keysize.size=2048
+preop.cert.subsystem.keysize.select=custom
+preop.cert.subsystem.nickname=subsystemCert cert-[PKI_INSTANCE_ID]
+preop.cert.subsystem.profile=caInternalAuthSubsystemCert
+preop.cert.subsystem.subsystem=ra
+preop.cert._005=#preop.cert.subsystem.type=local
+preop.cert.subsystem.userfriendlyname=Subsystem Certificate
+preop.cert._006=#preop.cert.subsystem.cncomponent.override=true
+preop.configModules._000=#########################################
+preop.configModules._001=# Installation configuration "preop" module parameters
+preop.configModules._002=#########################################
+preop.configModules.count=3
+preop.configModules.module0.commonName=NSS Internal PKCS #11 Module
+preop.configModules.module0.imagePath=../img/clearpixel.gif
+preop.configModules.module0.userFriendlyName=NSS Internal PKCS #11 Module
+preop.configModules.module1.commonName=nfast
+preop.configModules.module1.imagePath=../img/clearpixel.gif
+preop.configModules.module1.userFriendlyName=nCipher's nFast Token Hardware Module
+preop.configModules.module2.commonName=lunasa
+preop.configModules.module2.imagePath=../img/clearpixel.gif
+preop.configModules.module2.userFriendlyName=SafeNet's LunaSA Token Hardware Module
+preop.module.token=NSS Certificate DB
+preop.keysize._000=#########################################
+preop.keysize._001=# Installation configuration "preop" keysize parameters
+preop.keysize._002=#########################################
+preop.keysize.customsize=2048
+preop.keysize.select=default
+preop.keysize.size=2048
+preop.keysize.ecc.size=256
diff --git a/base/ra/emails/mail_approve_request.vm b/base/ra/emails/mail_approve_request.vm
new file mode 100644
index 000000000..461eb4d10
--- /dev/null
+++ b/base/ra/emails/mail_approve_request.vm
@@ -0,0 +1,11 @@
+Reply-to: $mail_to
+Subject: Request #$request_id approved
+To: $mail_to
+Content-type: text/plain\n\n
+Request #$request_id has been approved
+for
+Subject DN: $subject_dn
+
+Import certificate at:
+https://$machineName:$nonClientAuthSecurePort/ee/request/getcert.cgi?id=$request_id
+
diff --git a/base/ra/emails/mail_create_request.vm b/base/ra/emails/mail_create_request.vm
new file mode 100644
index 000000000..317270efa
--- /dev/null
+++ b/base/ra/emails/mail_create_request.vm
@@ -0,0 +1,8 @@
+Reply-to: $mail_to
+Subject: New request #$request_id has been created
+To: $mail_to
+Content-type: text/plain\n\n
+A new request has been created for you. You can access
+the request by going to
+
+https://$machineName:$securePort/agent/request/read.cgi?id=$request_id
diff --git a/base/ra/etc/init.d/pki-rad b/base/ra/etc/init.d/pki-rad
new file mode 100755
index 000000000..666bf6387
--- /dev/null
+++ b/base/ra/etc/init.d/pki-rad
@@ -0,0 +1,87 @@
+#!/bin/bash
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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-2010 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+# pki-rad Startup script for the Apache HTTP pki-ra Server
+#
+# chkconfig: - 86 14
+# description: Registration Authority (Apache)
+# processname: pki-rad
+# piddir: /var/run/pki/ra
+# config: ${PKI_SERVER_ROOT}/conf/httpd.conf
+
+PROG_NAME=`basename $0`
+SERVICE_NAME="pki-rad"
+SERVICE_PROG="/sbin/service"
+PKI_PATH="/usr/share/pki/ra"
+PKI_REGISTRY="/etc/sysconfig/pki/ra"
+PKI_TYPE="pki-ra"
+PKI_TOTAL_PORTS=3
+
+# Avoid using 'systemctl' for now
+SYSTEMCTL_SKIP_REDIRECT=1
+export SYSTEMCTL_SKIP_REDIRECT
+
+# Disallow 'others' the ability to 'write' to new files
+umask 00002
+
+command="$1"
+pki_instance="$2"
+
+# Source function library.
+. /etc/init.d/functions
+
+# Source the PKI function library
+. /usr/share/pki/scripts/functions
+
+# See how we were called.
+case $command in
+ status)
+ registry_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 ${default_error}
+ ;;
+ *)
+ echo "unknown action ($command)"
+ usage
+ echo "where valid instance names include:"
+ list_instances
+ exit ${default_error}
+ ;;
+esac
+
diff --git a/base/ra/forms/admin/group/add.cgi b/base/ra/forms/admin/group/add.cgi
new file mode 100755
index 000000000..212330d0d
--- /dev/null
+++ b/base/ra/forms/admin/group/add.cgi
@@ -0,0 +1,86 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use Template::Velocity;
+use PKI::RA::GlobalVar;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Request::Queue;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ if (!$self->admin_auth($cfg)) {
+ print $q->redirect("/admin/error.cgi");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+
+ my %context;
+ $context{uid} = $util->html_encode($uid);
+
+ my $gid = $util->get_val($q->param('gid'));
+ my $name = $util->get_val($q->param('name'));
+
+ my $store = PKI::Base::UserStore->new();
+ $store->open($cfg);
+ my $ref = $store->read_group($gid);
+ if (defined($ref)) {
+ # gid used
+ print $q->redirect("/admin/group/add_new.cgi?error=exist");
+ return;
+ }
+ my $ref = $store->add_group($gid, $name);
+ $store->close();
+
+ print $q->redirect("/admin/group/index.cgi");
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/admin/group/add_member.cgi b/base/ra/forms/admin/group/add_member.cgi
new file mode 100755
index 000000000..d60fe965e
--- /dev/null
+++ b/base/ra/forms/admin/group/add_member.cgi
@@ -0,0 +1,80 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use Template::Velocity;
+use PKI::RA::GlobalVar;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Base::Registry;
+use PKI::Request::Queue;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ if (!$self->admin_auth($cfg)) {
+ print $q->redirect("/admin/error.cgi");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+
+ my %context;
+ $context{uid} = $util->html_encode($uid);
+
+ my $gid = $util->get_val($q->param('gid'));
+ my $userid = $util->get_val($q->param('uid'));
+
+ my $store = PKI::Base::UserStore->new();
+ $store->open($cfg);
+ $store->add_user_to_group($gid, $userid);
+ $store->close();
+
+ print $q->redirect("/admin/group/read.cgi?gid=" . $gid);
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/admin/group/add_new.cgi b/base/ra/forms/admin/group/add_new.cgi
new file mode 100755
index 000000000..5a1ca7eda
--- /dev/null
+++ b/base/ra/forms/admin/group/add_new.cgi
@@ -0,0 +1,86 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use Template::Velocity;
+use PKI::RA::GlobalVar;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Request::Queue;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ if (!$self->admin_auth($cfg)) {
+ print $q->redirect("/admin/error.cgi");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+
+ my %context;
+ $context{uid} = $util->html_encode($uid);
+ my $error = $q->param('error');
+ $context{error} = $util->html_encode($error);
+
+ my $result = $parser->execute_file_with_context("admin/group/add_new.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/admin/group/delete.cgi b/base/ra/forms/admin/group/delete.cgi
new file mode 100755
index 000000000..5fb1f22ce
--- /dev/null
+++ b/base/ra/forms/admin/group/delete.cgi
@@ -0,0 +1,79 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use Template::Velocity;
+use PKI::RA::GlobalVar;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Request::Queue;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ if (!$self->admin_auth($cfg)) {
+ print $q->redirect("/admin/error.cgi");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+
+ my %context;
+ $context{uid} = $util->html_encode($uid);
+
+ my $gid = $util->get_val($q->param('gid'));
+
+ my $store = PKI::Base::UserStore->new();
+ $store->open($cfg);
+ $store->delete_group($gid);
+ $store->close();
+
+ print $q->redirect("/admin/group/index.cgi");
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/admin/group/delete_member.cgi b/base/ra/forms/admin/group/delete_member.cgi
new file mode 100755
index 000000000..2e516eeee
--- /dev/null
+++ b/base/ra/forms/admin/group/delete_member.cgi
@@ -0,0 +1,79 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use Template::Velocity;
+use PKI::RA::GlobalVar;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Request::Queue;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ if (!$self->admin_auth($cfg)) {
+ print $q->redirect("/admin/error.cgi");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+
+ my %context;
+ $context{uid} = $util->html_encode($uid);
+
+ my $gid = $util->get_val($q->param('gid'));
+ my $userid = $util->get_val($q->param('uid'));
+
+ my $store = PKI::Base::UserStore->new();
+ $store->open($cfg);
+ $store->delete_user_from_group($gid, $userid);
+ $store->close();
+
+ print $q->redirect("/admin/group/read.cgi?gid=" . $gid);
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/admin/group/index.cgi b/base/ra/forms/admin/group/index.cgi
new file mode 100755
index 000000000..07dc653e6
--- /dev/null
+++ b/base/ra/forms/admin/group/index.cgi
@@ -0,0 +1,115 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use Template::Velocity;
+use PKI::RA::GlobalVar;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Request::Queue;
+use PKI::Base::Registry;
+use Encode;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+
+ my $util = PKI::Base::Util->new();
+
+ $self->debug_params($cfg, $q);
+
+ if (!$self->admin_auth($cfg)) {
+ print $q->redirect("/admin/error.cgi");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+
+ my %context;
+ $context{uid} = $util->html_encode($uid);
+
+ my $sp = $util->get_alphanum_val($q->param('sp'));
+ if ($sp eq "") {
+ $sp = "0";
+ }
+ $context{sp} = $sp;
+ my $mc = $util->get_alphanum_val($q->param('mc'));
+ if ($mc eq "") {
+ $mc = "20";
+ }
+ $context{mc} = $mc;
+ $context{pp} = $sp - $mc; # previous pos (for paging)
+ $context{np} = $sp + $mc; # next pos (for paging)
+
+ my $store = PKI::Base::UserStore->new();
+ $store->open($cfg);
+ my @groups = $store->list_groups($sp, $mc);
+ $store->close();
+
+ my @r;
+ my $i = 0;
+ foreach my $group (@groups) {
+ $r[$i] = new PKI::RA::GlobalVar(
+ getGID => sub { return $util->html_encode(Encode::decode('UTF-8', $group->{'gid'})) },
+ getName => sub { return $util->html_encode(Encode::decode('UTF-8', $group->{'name'})) },
+ );
+ $i++;
+ }
+ $context{rows} = \@r;
+
+ my $result = $parser->execute_file_with_context("admin/group/index.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/admin/group/read.cgi b/base/ra/forms/admin/group/read.cgi
new file mode 100755
index 000000000..9ede3aa53
--- /dev/null
+++ b/base/ra/forms/admin/group/read.cgi
@@ -0,0 +1,125 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use Template::Velocity;
+use PKI::RA::GlobalVar;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Request::Queue;
+use PKI::Base::Registry;
+use Encode;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ if (!$self->admin_auth($cfg)) {
+ print $q->redirect("/admin/error.cgi");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+
+ my %context;
+ $context{uid} = $util->html_encode($uid);
+
+ my $gid = $util->get_val($q->param('gid'));
+
+ my $store = PKI::Base::UserStore->new();
+ $store->open($cfg);
+ my $ref = $store->read_group($gid);
+
+ $context{gid} = $util->html_encode(Encode::decode('UTF-8', $ref->{'gid'}));
+ $context{name} = $util->html_encode(Encode::decode('UTF-8', $ref->{'name'}));
+
+ my @members = $store->list_all_members($gid);
+ my @users = $store->list_all_non_members($gid);
+ $store->close();
+
+ # new member in the group
+ my @r;
+ my $i = 0;
+ foreach my $member (@members) {
+ $r[$i] = new PKI::RA::GlobalVar(
+ getUID => sub { return $util->html_encode($member->{'uid'}) },
+ );
+ $i++;
+ }
+ $context{members} = \@r;
+
+ # read users
+ my @u;
+ $i = 0;
+ foreach my $user (@users) {
+ $u[$i] = new PKI::RA::GlobalVar(
+ getUID => sub { return $util->html_encode($user->{'uid'}) },
+ );
+ $i++;
+ }
+ if ($i == 0) {
+ $context{non_member_exists} = 0;
+ } else {
+ $context{non_member_exists} = 1;
+ }
+ $context{users} = \@u;
+
+ my $result = $parser->execute_file_with_context("admin/group/read.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/admin/index.cgi b/base/ra/forms/admin/index.cgi
new file mode 100755
index 000000000..2db7b2500
--- /dev/null
+++ b/base/ra/forms/admin/index.cgi
@@ -0,0 +1,80 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use Template::Velocity;
+use PKI::Base::Conf;
+use PKI::Base::UserStore;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+
+ my $q = CGI->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ if (!$self->admin_auth($cfg)) {
+ print $q->redirect("/agent/error.cgi?error=Authentication%20Error");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+
+ my %context;
+ $context{uid} = $uid;
+
+ my $result = $parser->execute_file_with_context("admin/index.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/admin/user/add.cgi b/base/ra/forms/admin/user/add.cgi
new file mode 100755
index 000000000..94c4bae81
--- /dev/null
+++ b/base/ra/forms/admin/user/add.cgi
@@ -0,0 +1,99 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use Template::Velocity;
+use PKI::RA::GlobalVar;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Request::Queue;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ if (!$self->admin_auth($cfg)) {
+ print $q->redirect("/admin/error.cgi");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+
+ my %context;
+ $context{uid} = $uid;
+
+ my $userid = $util->get_val($q->param('uid'));
+ my $name = $util->get_val($q->param('name'));
+ my $email = $util->get_val($q->param('email'));
+ my $certificate = $util->get_val($q->param('certificate'));
+
+ if ($certificate =~ /BEGIN CERTIFICATE/ ||
+ $certificate =~ /END CERTIFICATE/) {
+ # do nothing
+ } else {
+ print $q->redirect("/admin/user/add_new.cgi?error=cert_header");
+ return;
+ }
+ $certificate =~ s/-----BEGIN CERTIFICATE-----//g;
+ $certificate =~ s/-----END CERTIFICATE-----//g;
+ $certificate =~ s/[\r\n]//g;
+
+ my $store = PKI::Base::UserStore->new();
+ $store->open($cfg);
+ my $ref = $store->read_user($userid);
+ if (defined($ref)) {
+ # uid used
+ print $q->redirect("/admin/user/add_new.cgi?error=exist");
+ return;
+ }
+ my $ref = $store->add_user($userid, $name, $email, $certificate);
+ $store->close();
+
+ print $q->redirect("/admin/user/index.cgi");
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/admin/user/add_new.cgi b/base/ra/forms/admin/user/add_new.cgi
new file mode 100755
index 000000000..8bfbd0e9e
--- /dev/null
+++ b/base/ra/forms/admin/user/add_new.cgi
@@ -0,0 +1,87 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use Template::Velocity;
+use PKI::RA::GlobalVar;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Request::Queue;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ if (!$self->admin_auth($cfg)) {
+ print $q->redirect("/admin/error.cgi");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+
+ my %context;
+ $context{uid} = $uid;
+
+ my $error = $util->get_val($q->param('error'));
+ $context{error} = $error;
+
+ my $result = $parser->execute_file_with_context("admin/user/add_new.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/admin/user/delete.cgi b/base/ra/forms/admin/user/delete.cgi
new file mode 100755
index 000000000..707035edb
--- /dev/null
+++ b/base/ra/forms/admin/user/delete.cgi
@@ -0,0 +1,79 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use Template::Velocity;
+use PKI::RA::GlobalVar;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Request::Queue;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $cfg = PKI::Base::Registry->get_config();
+
+ my $util = PKI::Base::Util->new();
+
+ $self->debug_params($cfg, $q);
+
+ if (!$self->admin_auth($cfg)) {
+ print $q->redirect("/admin/error.cgi");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+
+ my %context;
+ $context{uid} = $uid;
+
+ my $userid = $util->get_val($q->param('uid'));
+
+ my $store = PKI::Base::UserStore->new();
+ $store->open($cfg);
+ $store->delete_user($userid);
+ $store->close();
+
+ print $q->redirect("/admin/user/index.cgi");
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/admin/user/index.cgi b/base/ra/forms/admin/user/index.cgi
new file mode 100755
index 000000000..c845ae1dc
--- /dev/null
+++ b/base/ra/forms/admin/user/index.cgi
@@ -0,0 +1,118 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use Template::Velocity;
+use PKI::RA::GlobalVar;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Request::Queue;
+use PKI::Base::Registry;
+use Encode;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ my $util = PKI::Base::Util->new();
+
+ $self->debug_params($cfg, $q);
+
+ if (!$self->admin_auth($cfg)) {
+ print $q->redirect("/admin/error.cgi");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+
+ my %context;
+ $context{uid} = $uid;
+
+ my $status = $util->get_alphanum_val($q->param('status'));
+ $context{status} = $status;
+
+ my $sp = $util->get_alphanum_val($q->param('sp'));
+ if ($sp eq "") {
+ $sp = "0";
+ }
+ $context{sp} = $sp;
+ my $mc = $util->get_alphanum_val($q->param('mc'));
+ if ($mc eq "") {
+ $mc = "20";
+ }
+ $context{mc} = $mc;
+ $context{pp} = $sp - $mc; # previous pos (for paging)
+ $context{np} = $sp + $mc; # next pos (for paging)
+
+ my $store = PKI::Base::UserStore->new();
+ $store->open($cfg);
+ my @users = $store->list_users($sp, $mc);
+ $store->close();
+
+ my @r;
+ my $i = 0;
+ foreach my $user (@users) {
+ $r[$i] = new PKI::RA::GlobalVar(
+ getUID => sub { return $util->html_encode($user->{'uid'}) },
+ getName => sub { return $util->html_encode(Encode::decode('UTF-8',$user->{'name'})) },
+ getEmail => sub { return $util->html_encode($user->{'email'}) },
+ );
+ $i++;
+ }
+ $context{rows} = \@r;
+
+ my $result = $parser->execute_file_with_context("admin/user/index.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/admin/user/read.cgi b/base/ra/forms/admin/user/read.cgi
new file mode 100755
index 000000000..08d2fd3f7
--- /dev/null
+++ b/base/ra/forms/admin/user/read.cgi
@@ -0,0 +1,97 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use Template::Velocity;
+use PKI::RA::GlobalVar;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Base::Registry;
+use PKI::Request::Queue;
+use Encode;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ if (!$self->admin_auth($cfg)) {
+ print $q->redirect("/admin/error.cgi");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+
+ my %context;
+ $context{uid} = $uid;
+
+ my $userid = $util->get_val($q->param('uid'));
+
+ my $store = PKI::Base::UserStore->new();
+ $store->open($cfg);
+ my $ref = $store->read_user($userid);
+ $store->close();
+
+ $context{userid} = $util->html_encode($ref->{'uid'});
+ $context{name} = $util->html_encode(Encode::decode('UTF-8', $ref->{'name'}));
+ $context{email} = $util->html_encode($ref->{'email'});
+ $context{certificate} = $util->breakline($util->html_encode($ref->{'certificate'}),40);
+
+ my $result = $parser->execute_file_with_context("admin/user/read.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/agent/cert/index.cgi b/base/ra/forms/agent/cert/index.cgi
new file mode 100755
index 000000000..46e5b8c2c
--- /dev/null
+++ b/base/ra/forms/agent/cert/index.cgi
@@ -0,0 +1,119 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use Template::Velocity;
+use PKI::RA::GlobalVar;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Base::Registry;
+use PKI::Base::CertStore;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ if (!$self->agent_auth($cfg)) {
+ print $q->redirect("/agent/error.cgi");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+
+ my %context;
+ $context{uid} = $util->html_encode($uid);
+
+ my @roles = $self->get_current_roles($cfg);
+ my $r = join(",",@roles);
+
+ my $sp = $util->get_alphanum_val($q->param('sp'));
+ if ($sp eq "") {
+ $sp = "0";
+ }
+ $context{sp} = $sp;
+ my $mc = $util->get_alphanum_val($q->param('mc'));
+ if ($mc eq "") {
+ $mc = "20";
+ }
+ $context{mc} = $mc;
+ $context{pp} = $sp - $mc; # previous pos (for paging)
+ $context{np} = $sp + $mc; # next pos (for paging)
+
+ my $cs = PKI::Base::CertStore->new();
+ $cs->open($cfg);
+ my @certs = $cs->list_certs_by_approver($uid, $sp, $mc);
+ $cs->close();
+
+ my @r;
+ my $i = 0;
+ foreach my $cert (@certs) {
+ $r[$i] = new PKI::RA::GlobalVar(
+ getReqId => sub { return $util->html_encode($cert->{'rid'}) },
+ getSerialno => sub { return $util->html_encode($cert->{'serialno'}) },
+ getSubjectDN => sub { return $util->html_encode($cert->{'subject_dn'}) },
+ getCertificate => sub { return $util->html_encode($cert->{'certificate'}) },
+ getApprovedBy => sub { return $util->html_encode($cert->{'approved_by'}) },
+ getCreatedAt => sub { return $util->html_encode($cert->{'created_at'}); },
+ );
+ $i++;
+ }
+ $context{rows} = \@r;
+
+ my $result = $parser->execute_file_with_context("agent/cert/index.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/agent/cert/read.cgi b/base/ra/forms/agent/cert/read.cgi
new file mode 100755
index 000000000..f434baedb
--- /dev/null
+++ b/base/ra/forms/agent/cert/read.cgi
@@ -0,0 +1,104 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use Template::Velocity;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Base::Registry;
+use PKI::Conn::CA;
+use Encode;
+use vars qw (@ISA);
+use PKI::Service::Op;
+
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+ $self->debug_params($cfg, $q);
+
+ if (!$self->agent_auth($cfg)) {
+ print $q->redirect("/agent/error.cgi");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+
+ my %context;
+ $context{uid} = $util->html_encode($uid);
+
+ my $serialno = $util->get_alphanum_val($q->param('serialno'));
+
+ my $cs = PKI::Base::CertStore->new();
+ $cs->open($cfg);
+ my $ref = $cs->read_certificate_by_approver($uid, $serialno);
+ $cs->close();
+
+ my $ca = PKI::Conn::CA->new();
+ $ca->open($cfg);
+ my $certStatus = $ca->getCertStatus("ca1", $serialno);
+ $ca->close();
+
+
+ $context{certificate} = $util->breakline($util->html_encode($ref->{'certificate'}), 40);
+
+ $context{serialno} = $util->html_encode($ref->{'serialno'});
+ $context{subject_dn} = $util->html_encode(Encode::decode('UTF-8', $ref->{'subject_dn'}));
+ $context{created_at} = $util->html_encode($ref->{'created_at'});
+ $context{approved_by} = $util->html_encode($ref->{'approved_by'});
+ $context{rid} = $util->html_encode($ref->{'rid'});
+ $context{certStatus} = $util->html_encode($certStatus);
+
+ my $result = $parser->execute_file_with_context("agent/cert/read.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/agent/cert/revoke.cgi b/base/ra/forms/agent/cert/revoke.cgi
new file mode 100755
index 000000000..1e483aea0
--- /dev/null
+++ b/base/ra/forms/agent/cert/revoke.cgi
@@ -0,0 +1,89 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use Template::Velocity;
+use PKI::Base::Conf;
+use PKI::Base::Registry;
+use PKI::Base::Util;
+use Encode;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+ $self->debug_params($cfg, $q);
+
+ if (!$self->agent_auth($cfg)) {
+ print $q->redirect("/agent/error.cgi");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+
+ my %context;
+ $context{uid} = $util->html_encode($uid);
+
+ my $serialno = $util->get_alphanum_val($q->param('serialno'));
+ my $subject_dn = $util->get_val($q->param('subject_dn'));
+ my $rid = $util->get_alphanum_val($q->param('rid'));
+
+ $context{serialno} = $util->html_encode($serialno);
+ $context{subject_dn} = $util->html_encode(Encode::decode('UTF-8',$subject_dn));
+ $context{rid} = $util->html_encode($rid);
+
+ my $result = $parser->execute_file_with_context("agent/cert/revoke.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/agent/cert/submit.cgi b/base/ra/forms/agent/cert/submit.cgi
new file mode 100755
index 000000000..571385f3a
--- /dev/null
+++ b/base/ra/forms/agent/cert/submit.cgi
@@ -0,0 +1,104 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use Template::Velocity;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Base::Registry;
+use PKI::Conn::CA;
+use Encode;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ if (!$self->agent_auth($cfg)) {
+ print $q->redirect("/agent/error.cgi");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+
+ my %context;
+ $context{uid} = $util->html_encode($uid);
+
+ my $serialno = $util->get_alphanum_val($q->param('serialno'));
+ my $subject_dn = $util->get_val($q->param('subject_dn'));
+ my $reason = $util->get_alphanum_val($q->param('reason'));
+ my $rid = $util->get_alphanum_val($q->param('rid'));
+
+ my $ca = PKI::Conn::CA->new();
+ $ca->open($cfg);
+ $ca->revoke($rid, "ca1", $serialno, $reason);
+ $ca->close();
+
+ my $queue = PKI::Request::Queue->new();
+ $queue->open($cfg);
+
+ my $ref = $queue->read_request($rid);
+ $context{errorString} = $util->html_encode($ref->{'errorString'});
+ $queue->close();
+
+ $context{rid} = $util->html_encode($rid);
+ $context{serialno} = $util->html_encode($serialno);
+ $context{subject_dn} = $util->html_encode(Encode::decode('UTF-8', $subject_dn));
+
+ my $result = $parser->execute_file_with_context("agent/cert/submit.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/agent/error.cgi b/base/ra/forms/agent/error.cgi
new file mode 100755
index 000000000..fa13365a7
--- /dev/null
+++ b/base/ra/forms/agent/error.cgi
@@ -0,0 +1,81 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use Template::Velocity;
+use PKI::Base::Conf;
+use PKI::Base::UserStore;
+use PKI::Base::Util;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+
+ my $q = CGI->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ my $util = PKI::Base::Util->new();
+
+ my $error = $util->get_val($q->param('error'));
+
+ my %context;
+ if ($error ne "") {
+ $context{has_error} = 1;
+ $context{'error'} = $util->html_encode($error);
+ }
+
+ my $result = $parser->execute_file_with_context("agent/error.vm", \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/agent/index.cgi b/base/ra/forms/agent/index.cgi
new file mode 100755
index 000000000..c8f2040fe
--- /dev/null
+++ b/base/ra/forms/agent/index.cgi
@@ -0,0 +1,83 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use Template::Velocity;
+use PKI::Base::Conf;
+use PKI::Base::UserStore;
+use PKI::Base::Registry;
+use PKI::Base::Util;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ if (!$self->agent_auth($cfg)) {
+ print $q->redirect("/agent/error.cgi?error=Authentication%20Error");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+
+ my %context;
+ $context{uid} = $util->html_encode($uid);
+
+ my $result = $parser->execute_file_with_context("agent/index.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/agent/request/add_note.cgi b/base/ra/forms/agent/request/add_note.cgi
new file mode 100755
index 000000000..0ffac91c7
--- /dev/null
+++ b/base/ra/forms/agent/request/add_note.cgi
@@ -0,0 +1,93 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use Template::Velocity;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Base::Registry;
+use PKI::Request::Queue;
+use PKI::Base::TimeTool;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ if (!$self->agent_auth($cfg)) {
+ print $q->redirect("/agent/error.cgi");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+
+ my %context;
+ $context{uid} = $util->html_encode($uid);
+
+ my $id = $util->get_alphanum_val($q->param('id'));
+ my $note = $util->get_val($q->param('note'));
+
+ if ($note eq "") {
+ # dont add anything
+ print $q->redirect("/agent/request/read.cgi?id=" . $id);
+ return;
+ }
+
+ my $timet = PKI::Base::TimeTool->new();
+ my $now = $timet->get_time();
+ my $new_note = "==== Note created by $uid at $now ====\n" .
+ $note . "\n";
+
+ my $queue = PKI::Request::Queue->new();
+ $queue->open($cfg);
+ my $ref = $queue->read_request($id);
+ $queue->set_request($id, "note", $ref->{'note'} . $new_note);
+ $queue->close();
+
+ print $q->redirect("/agent/request/read.cgi?id=" . $id);
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/agent/request/index.cgi b/base/ra/forms/agent/request/index.cgi
new file mode 100755
index 000000000..81b25977a
--- /dev/null
+++ b/base/ra/forms/agent/request/index.cgi
@@ -0,0 +1,146 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use Template::Velocity;
+use PKI::RA::GlobalVar;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Base::Registry;
+use PKI::Request::Queue;
+use PKI::Service::Op;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ if (!$self->agent_auth($cfg)) {
+ print $q->redirect("/agent/error.cgi");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+ $self->debug_log( $cfg, "in request/index.cgi, uid == $uid");
+
+ my %context;
+ $context{uid} = $util->html_encode($uid);
+
+ my @roles = $self->get_current_roles($cfg);
+# my $r = join(",",@roles);
+
+ my $status = $util->get_alphanum_val($q->param('status'));
+ if ($status eq "") {
+ $context{status} = "";
+ } else {
+ $context{status} = $util->html_encode($status);
+ }
+
+ my $sp = $util->get_alphanum_val($q->param('sp'));
+ if ($sp eq "") {
+ $sp = "0";
+ }
+ $context{sp} = $sp;
+ my $mc = $util->get_alphanum_val($q->param('mc'));
+ if ($mc eq "") {
+ $mc = "20";
+ }
+ $context{mc} = $mc;
+ $context{pp} = $sp - $mc; # previous pos (for paging)
+ $context{np} = $sp + $mc; # next pos (for paging)
+
+ my $queue = PKI::Request::Queue->new();
+ $queue->open($cfg);
+ my $total = $queue->count_requests_by_roles(\@roles, $status);
+ $context{total} = $util->html_encode($total);
+
+ my @reqs = $queue->list_requests_by_roles(\@roles, $status, $sp, $mc);
+# my @reqs = $queue->list_requests_by_roles($r, $status, $sp, $mc);
+ $queue->close();
+
+ my @r;
+ my $i = 0;
+ foreach my $req (@reqs) {
+ $r[$i] = new PKI::RA::GlobalVar(
+ getId => sub { return $util->html_encode($req->{'rowid'}) },
+ getType => sub { return $util->html_encode($req->{'type'}) },
+ getStatus => sub { return $util->html_encode($req->{'status'}) },
+ getError => sub { return $util->html_encode($req->{'errorString'}) },
+ getAssignedTo => sub { return $util->html_encode($req->{'assigned_to'}) },
+ getData => sub { return $util->html_encode($req->{'data'}); },
+ getCreatedBy => sub { return $util->html_encode($req->{'created_by'}); },
+ getCreatedAt => sub { return $util->html_encode($req->{'created_at'}); },
+ );
+ $i++;
+ }
+ $context{rows} = \@r;
+
+ if ($sp - $mc < 0) {
+ $context{show_previous} = "no";
+ } else {
+ $context{show_previous} = "yes";
+ }
+
+ if ($i < 20) {
+ $context{show_next} = "no";
+ } else {
+ $context{show_next} = "yes";
+ }
+
+ my $result = $parser->execute_file_with_context("agent/request/index.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/agent/request/op.cgi b/base/ra/forms/agent/request/op.cgi
new file mode 100755
index 000000000..363d7121b
--- /dev/null
+++ b/base/ra/forms/agent/request/op.cgi
@@ -0,0 +1,153 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use Benchmark;
+use CGI;
+use Template::Velocity;
+use PKI::Base::Conf;
+use PKI::Base::Registry;
+use PKI::Request::Queue;
+use PKI::Base::Util;
+use Encode;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+
+ my $q = CGI->new();
+
+ my $st = new Benchmark;
+
+ my $util = PKI::Base::Util->new();
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ if (!$self->agent_auth($cfg)) {
+ print $q->redirect("/agent/error.cgi");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+
+ my %context;
+ $context{uid} = $util->html_encode($uid);
+
+ my $type = $util->get_alphanum_val($q->param('type'));
+ my $id = $util->get_alphanum_val($q->param('id'));
+
+ my $db_st = new Benchmark;
+ my $queue = PKI::Request::Queue->new();
+ $queue->open($cfg);
+
+ my $ref;
+
+ my @roles = $self->get_current_roles($cfg);
+ my $pref = $queue->read_request_by_roles(\@roles, $id);
+
+ if (! defined $pref) {
+ $queue->close();
+ $self->debug_log($cfg, "Invalid attempt to process request id= " . $id .
+ " by userid= " . $uid);
+ print $q->redirect("/agent/error.cgi");
+ return;
+ }
+
+ my $curr_status = $pref->{'status'};
+ if ($type eq "approve") {
+ if (($curr_status ne "OPEN") && ($curr_status ne "ERROR")) {
+ $queue->close();
+ print $q->redirect("/agent/request/read.cgi?id=$id");
+ return;
+ }
+
+ $ref = $queue->approve_request($id, $uid);
+ } elsif ($type eq "reject") {
+ if (($curr_status ne "OPEN") && ($curr_status ne "ERROR")) {
+ $queue->close();
+ print $q->redirect("/agent/request/read.cgi?id=$id");
+ return;
+ }
+
+ $ref = $queue->reject_request($id, $uid);
+ }
+ $queue->close();
+ my $db_et = new Benchmark;
+
+ $context{data} = $util->breakline($util->html_encode(Encode::decode('UTF-8', $ref->{'data'})), 40);
+ $context{output} = $util->breakline($util->html_encode($ref->{'output'}), 40);
+ $context{serialno} = $util->html_encode($ref->{'serialno'});
+ $context{type} = $util->html_encode($ref->{'type'});
+ $context{ip} = $util->html_encode($ref->{'ip'});
+ $context{note} = $util->html_encode($ref->{'note'});
+ $context{note} =~ s/\n/<br\/>/g;
+ $context{created_at} = $util->html_encode($ref->{'created_at'});
+ $context{updated_at} = $util->html_encode($ref->{'updated_at'});
+ $context{assigned_to} = $util->html_encode($ref->{'assigned_to'});
+ $context{processed_by} = $util->html_encode($ref->{'processed_by'});
+ $context{created_by} = $util->html_encode($ref->{'created_by'});
+ $context{status} = $util->html_encode($ref->{'status'});
+ $context{errorString} = $util->html_encode($ref->{'errorString'});
+ $context{id} = $util->html_encode($ref->{'rowid'});
+
+ my $t_st = new Benchmark;
+ my $result = $parser->execute_file_with_context("agent/request/op.vm",
+ \%context);
+ my $t_et = new Benchmark;
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+
+ my $et = new Benchmark;
+
+ $self->debug_log($cfg, "benchmark " .
+ "total=" . timestr(timediff($et, $st)) . " " .
+ "db total=" . timestr(timediff($db_et, $db_st)) . " " .
+ "template total=" . timestr(timediff($t_et, $t_st)) . " "
+ );
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/agent/request/read.cgi b/base/ra/forms/agent/request/read.cgi
new file mode 100755
index 000000000..d1633c164
--- /dev/null
+++ b/base/ra/forms/agent/request/read.cgi
@@ -0,0 +1,119 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use Template::Velocity;
+use PKI::Base::Conf;
+use PKI::Base::Registry;
+use PKI::Base::Util;
+use PKI::Request::Queue;
+use Encode;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ if (!$self->agent_auth($cfg)) {
+ print $q->redirect("/agent/error.cgi");
+ return;
+ }
+ my $uid = $self->get_current_uid($cfg);
+
+ my %context;
+ $context{uid} = $util->html_encode($uid);
+
+
+ my @roles = $self->get_current_roles($cfg);
+# my $r = join(",",@roles);
+
+ my $id = $util->get_alphanum_val($q->param('id'));
+
+ my $queue = PKI::Request::Queue->new();
+ $queue->open($cfg);
+ my $ref = $queue->read_request_by_roles(\@roles, $id);
+ $queue->close();
+
+ $context{data} = $util->breakline($util->html_encode(Encode::decode('UTF-8',$ref->{'data'})), 40);
+ $context{output} = $util->breakline($util->html_encode($ref->{'output'}), 40);
+ $context{meta_info} = $util->breakline($util->html_encode($ref->{'meta_info'}), 40);
+
+ $context{serialno} = $util->html_encode($ref->{'serialno'});
+ $context{subject_dn} = $util->html_encode($ref->{'subject_dn'});
+ $context{type} = $util->html_encode($ref->{'type'});
+ $context{created_at} = $util->html_encode($ref->{'created_at'});
+ $context{created_by} = $util->html_encode($ref->{'created_by'});
+ $context{updated_at} = $util->html_encode($ref->{'updated_at'});
+ $context{ip} = $util->html_encode($ref->{'ip'});
+ $context{processed_by} = $util->html_encode($ref->{'processed_by'});
+ $context{note} = $util->html_encode($ref->{'note'});
+ $context{note} =~ s/\n/<br\/>/g;
+ $context{assigned_to} = $util->html_encode($ref->{'assigned_to'});
+ $context{status} = $util->html_encode($ref->{'status'});
+ if ($ref->{'status'} eq "OPEN") {
+ $context{is_open} = 1;
+ }
+ if ($ref->{'status'} eq "ERROR") {
+ $context{is_error} = 1;
+ }
+ $context{errorString} = $util->html_encode($ref->{'errorString'});
+ $context{id} = $util->html_encode($ref->{'rowid'});
+
+ my $result = $parser->execute_file_with_context("agent/request/read.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/agent/enroll.cgi b/base/ra/forms/ee/agent/enroll.cgi
new file mode 100755
index 000000000..4f1af8f16
--- /dev/null
+++ b/base/ra/forms/ee/agent/enroll.cgi
@@ -0,0 +1,127 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use MIME::Base64;
+use CGI;
+use PKI::Service::Op;
+use Template::Velocity;
+use PKI::Base::Conf;
+use PKI::Base::Registry;
+use PKI::Request::Queue;
+use PKI::Conn::CA;
+use PKI::Base::PinStore;
+use PKI::Base::Util;
+
+use vars qw (@ISA);
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ my $uid = $util->get_val($q->param('uid'));
+ my $pin = $util->get_alphanum_val($q->param('pin'));
+ my $csr = $util->get_val($q->param('csr'));
+ $csr = $util->normalize_csr($csr);
+
+ my $key = $uid;
+
+ my $pin_store = PKI::Base::PinStore->new();
+ $pin_store->open($cfg);
+ my $pinref = $pin_store->read_pin($key);
+ if (defined($pinref) && $pinref->{'pin'} eq $pin) {
+ $pin_store->delete($key);
+ } else {
+ $pin_store->close();
+ print $q->redirect("/ee/error.cgi?error=Invalid Pin");
+ return;
+ }
+ my $rid = $pinref->{'rid'};
+ $pin_store->close();
+
+ my $profile_id = $cfg->get("request.agent.profileId");
+ my $cert_request_type = $cfg->get("request.agent.reqType");
+
+ my $queue = PKI::Request::Queue->new();
+ $queue->open($cfg);
+ my $req = $queue->read_request($rid);
+ $queue->set_request($rid, "subject_dn", "uid=$uid, e=$req->{'created_by'}");
+
+ my $ca = PKI::Conn::CA->new();
+ $ca->open($cfg);
+ my $cert = $ca->enroll($rid, "ca1", $profile_id, $cert_request_type, $csr);
+ $ca->close();
+ $queue->set_request($rid, "output", $cert);
+
+ $req = $queue->read_request($rid);
+ if ($cert eq "") {
+ my $error = $req->{'errorString'};
+ $queue->close();
+ print $q->redirect("/ee/error.cgi?error=$error");
+ return;
+ }
+
+ my $decoded = decode_base64($cert);
+ my $encoded = encode_base64($decoded);
+
+ my %context;
+ $context{cert} = $encoded;
+ $context{rid} = $util->html_encode($rid);
+ $context{subject_dn} = $util->html_encode($req->{'subject_dn'});
+ $queue->close();
+
+ my $result = $parser->execute_file_with_context("ee/agent/enroll.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/agent/index.cgi b/base/ra/forms/ee/agent/index.cgi
new file mode 100755
index 000000000..66fceb8ff
--- /dev/null
+++ b/base/ra/forms/ee/agent/index.cgi
@@ -0,0 +1,68 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use PKI::Service::Op;
+use PKI::Base::Registry;
+use Template::Velocity;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ my %context;
+ my $result = $parser->execute_file_with_context("ee/agent/index.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/agent/new.cgi b/base/ra/forms/ee/agent/new.cgi
new file mode 100755
index 000000000..c209f5e74
--- /dev/null
+++ b/base/ra/forms/ee/agent/new.cgi
@@ -0,0 +1,68 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use PKI::Service::Op;
+use PKI::Base::Registry;
+use Template::Velocity;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ my %context;
+ my $result = $parser->execute_file_with_context("ee/agent/new.vm", \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/agent/start.cgi b/base/ra/forms/ee/agent/start.cgi
new file mode 100755
index 000000000..27aedb546
--- /dev/null
+++ b/base/ra/forms/ee/agent/start.cgi
@@ -0,0 +1,69 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use PKI::Service::Op;
+use PKI::Base::Registry;
+use Template::Velocity;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ my %context;
+
+ my $result = $parser->execute_file_with_context("ee/agent/start.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/agent/submit.cgi b/base/ra/forms/ee/agent/submit.cgi
new file mode 100755
index 000000000..a68242114
--- /dev/null
+++ b/base/ra/forms/ee/agent/submit.cgi
@@ -0,0 +1,88 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use PKI::Service::Op;
+use Template::Velocity;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Base::Registry;
+use PKI::Request::Queue;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ my $uid = $util->get_val($q->param('uid'));
+ my $email = $util->get_val($q->param('email'));
+
+ $self->debug_params($cfg, $q);
+
+ my $queue = PKI::Request::Queue->new();
+ $queue->open($cfg);
+ my $request_id = $queue->create_request("agent",
+ "uid=" . $uid,
+ "0",
+ $email);
+ my %context;
+ $context{request_id} = $util->html_encode($request_id);
+ $self->debug_log($cfg, "request $request_id created");
+ $queue->close();
+
+ my $result = $parser->execute_file_with_context("ee/agent/submit.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/error.cgi b/base/ra/forms/ee/error.cgi
new file mode 100755
index 000000000..1417d4b61
--- /dev/null
+++ b/base/ra/forms/ee/error.cgi
@@ -0,0 +1,81 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use Template::Velocity;
+use PKI::Base::Conf;
+use PKI::Base::UserStore;
+use PKI::Base::Util;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+
+ my $q = CGI->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ my $util = PKI::Base::Util->new();
+
+ my %context;
+
+ my $error = $util->get_val($q->param('error'));
+ if ($error ne "") {
+ $context{has_error} = 1;
+ $context{'error'} = $util->html_encode($error);
+ }
+
+ my $result = $parser->execute_file_with_context("ee/error.vm", \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/index.cgi b/base/ra/forms/ee/index.cgi
new file mode 100755
index 000000000..453b2873b
--- /dev/null
+++ b/base/ra/forms/ee/index.cgi
@@ -0,0 +1,68 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use PKI::Service::Op;
+use Template::Velocity;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+
+ my $q = CGI->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ my %context;
+ my $result = $parser->execute_file_with_context("ee/index.vm", \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/request/getcert.cgi b/base/ra/forms/ee/request/getcert.cgi
new file mode 100755
index 000000000..b22444dc1
--- /dev/null
+++ b/base/ra/forms/ee/request/getcert.cgi
@@ -0,0 +1,93 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use PKI::Service::Op;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Base::Registry;
+use PKI::Request::Queue;
+use Template::Velocity;
+use MIME::Base64;
+use Encode;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+
+ my $id = $util->get_alphanum_val($q->param('id'));
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ my $queue = PKI::Request::Queue->new();
+ $queue->open($cfg);
+ my $req = $queue->read_request($id);
+ $queue->close();
+
+ my %context;
+ $context{id} = $util->html_encode($req->{'rowid'});
+ $context{serialno} = $util->html_encode($req->{'serialno'});
+ $context{subject_dn} = $util->html_encode(Encode::decode('UTF-8', $req->{'subject_dn'}));
+ if ($req->{'serialno'} eq "unavailable") {
+ $context{output} = "";
+ } else {
+ $context{output} = "-----BEGIN CERTIFICATE-----\n".$util->breakline($util->html_encode($req->{'output'}), 40)."\n-----END CERTIFICATE-----";
+ }
+ my $result = $parser->execute_file_with_context("ee/request/getcert.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/request/importcert.cgi b/base/ra/forms/ee/request/importcert.cgi
new file mode 100755
index 000000000..fdc309746
--- /dev/null
+++ b/base/ra/forms/ee/request/importcert.cgi
@@ -0,0 +1,82 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use PKI::Service::Op;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Base::Registry;
+use PKI::Request::Queue;
+use Template::Velocity;
+use MIME::Base64;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+
+ my $id = $util->get_alphanum_val($q->param('id'));
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ my $queue = PKI::Request::Queue->new();
+ $queue->open($cfg);
+ my $req = $queue->read_request($id);
+ $queue->close();
+
+ my %context;
+# $::symbol{id} = $req->{'rowid'};
+# $::symbol{status} = $req->{'status'};
+
+# my $result = $parser->execute_file("ee/request/status.vm");
+
+ my $cert = MIME::Base64::decode($req->{'output'});
+
+ print "Content-Type: application/x-x509-user-cert\n\n";
+ print $cert;
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/request/index.cgi b/base/ra/forms/ee/request/index.cgi
new file mode 100755
index 000000000..ef2a68b23
--- /dev/null
+++ b/base/ra/forms/ee/request/index.cgi
@@ -0,0 +1,68 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use PKI::Service::Op;
+use Template::Velocity;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ my %context;
+ my $result = $parser->execute_file_with_context("ee/request/index.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/request/status.cgi b/base/ra/forms/ee/request/status.cgi
new file mode 100755
index 000000000..6a3154716
--- /dev/null
+++ b/base/ra/forms/ee/request/status.cgi
@@ -0,0 +1,94 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use PKI::Service::Op;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Base::Registry;
+use PKI::Request::Queue;
+use Template::Velocity;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+
+ my $util = PKI::Base::Util->new();
+
+ my $id = $util->get_alphanum_val($q->param('id'));
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ my $queue = PKI::Request::Queue->new();
+ $queue->open($cfg);
+ my $req = $queue->read_request($id);
+ $queue->close();
+ if ($req == "") {
+ print $q->redirect("/ee/error.cgi?error=request%20not%20found");
+ return;
+ }
+
+ my %context;
+ $context{id} = $util->html_encode($req->{'rowid'});
+ $context{type} =$util->html_encode($req->{'type'});
+ $context{status} = $util->html_encode($req->{'status'});
+ $context{serialno} = $util->html_encode($req->{'serialno'});
+ $context{errorString} = $util->html_encode($req->{'errorString'});
+
+ my $result = $parser->execute_file_with_context("ee/request/status.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/scep/enroll.cgi b/base/ra/forms/ee/scep/enroll.cgi
new file mode 100755
index 000000000..53291636a
--- /dev/null
+++ b/base/ra/forms/ee/scep/enroll.cgi
@@ -0,0 +1,112 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use MIME::Base64;
+use URI::URL;
+use URI::Escape;
+use XML::Simple;
+use CGI;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Base::Registry;
+use PKI::Service::Op;
+use Template::Velocity;
+use PKI::Conn::CA;
+use PKI::Base::PinStore;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ my $client_id = $util->get_val($q->param('client_id'));
+ my $site_id = $util->get_val($q->param('site_id'));
+ my $pin = $util->get_alphanum_val($q->param('pin'));
+ my $csr = $util->get_val($q->param('csr'));
+
+ my $key = $client_id . "/" . $site_id;
+
+ my $pin_store = PKI::Base::PinStore->new();
+ $pin_store->open($cfg);
+ my $pinref = $pin_store->read_pin($key);
+ if (defined($pinref) && $pinref->{'pin'} eq $pin) {
+ $pin_store->delete($key);
+ } else {
+ $pin_store->close();
+ # error, redirect user back to the original enrollment page
+ print $q->redirect("/ee/scep/installer.cgi");
+ return;
+ }
+ $pin_store->close();
+
+ my $profile_id = $cfg->get("request.scep.profileId");
+ my $cert_request_type = $cfg->get("request.scep.reqType");
+
+ my $ca = PKI::Conn::CA->new();
+ $ca->open($cfg);
+ my $cert = $ca->enroll($pinref->{'rid'}, "ca1", $profile_id, $cert_request_type, $csr);
+ $ca->close();
+ my $decoded = decode_base64($cert);
+ my $encoded = encode_base64($decoded);
+
+ my %context;
+ $context{cert} = $encoded;
+
+ my $result = $parser->execute_file_with_context("ee/scep/enroll.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/scep/index.cgi b/base/ra/forms/ee/scep/index.cgi
new file mode 100755
index 000000000..c73fc379a
--- /dev/null
+++ b/base/ra/forms/ee/scep/index.cgi
@@ -0,0 +1,68 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use PKI::Service::Op;
+use Template::Velocity;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ my %context;
+ my $result = $parser->execute_file_with_context("ee/scep/index.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/scep/installer.cgi b/base/ra/forms/ee/scep/installer.cgi
new file mode 100755
index 000000000..8453c2cc4
--- /dev/null
+++ b/base/ra/forms/ee/scep/installer.cgi
@@ -0,0 +1,74 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use PKI::Service::Op;
+use Template::Velocity;
+use PKI::Base::Conf;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ my %context;
+ $context{machine} = $cfg->get("service.machineName");
+ $context{port} = $cfg->get("service.unsecurePort");
+
+ my $result = $parser->execute_file_with_context("ee/scep/installer.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/scep/manager.cgi b/base/ra/forms/ee/scep/manager.cgi
new file mode 100755
index 000000000..8b547a928
--- /dev/null
+++ b/base/ra/forms/ee/scep/manager.cgi
@@ -0,0 +1,68 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use PKI::Service::Op;
+use Template::Velocity;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ my %context;
+ my $result = $parser->execute_file_with_context("ee/scep/manager.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/scep/pkiclient.cgi b/base/ra/forms/ee/scep/pkiclient.cgi
new file mode 100755
index 000000000..a54558f37
--- /dev/null
+++ b/base/ra/forms/ee/scep/pkiclient.cgi
@@ -0,0 +1,113 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use MIME::Base64;
+use URI::URL;
+use URI::Escape;
+use XML::Simple;
+use CGI;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Service::Op;
+use Template::Velocity;
+use PKI::Conn::CA;
+use PKI::Base::PinStore;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ my $operation = $util->get_alphanum_val($q->param('operation'));
+ my $message = $util->get_val($q->param('message'));
+ $message = uri_escape($message);
+
+ my $ca = PKI::Conn::CA->new();
+ $ca->open($cfg);
+ if ($operation eq "GetCACert") {
+ my $content = $ca->scep_get_ca_cert("ca1", $operation, $message);
+
+ print "Content-Type: application/x-x509-ca-cert\n\n";
+ print $content;
+ } elsif ($operation eq "PKIOperation") {
+ my $decoded = $ca->scep_decode("ca1", $operation, $message);
+ $decoded =~ /(\<XMLResponse\>.*\<\/XMLResponse\>)/;
+ $decoded = $1;
+ my $parser = XML::Simple->new();
+ my $response = $parser->XMLin($decoded);
+
+ # one time pin
+ my $pin = $response->{'PKCS10'}->{'ChallengePassword'}->{'Password'} ;
+ # IP Address
+ my $key = $ENV{'REMOTE_ADDR'};
+
+ # check PIN
+ if (1) {
+ my $pin_store = PKI::Base::PinStore->new();
+ $pin_store->open($cfg);
+ my $pinref = $pin_store->read_pin($key);
+ if (defined($pinref) && $pinref->{'pin'} eq $pin) {
+ $pin_store->delete($key);
+ } else {
+ $pin_store->close();
+ # XXX - return SCEP error
+ print $q->redirect("/ee/scep/installer.cgi");
+ return;
+ }
+ $pin_store->close();
+ }
+
+ my $content = $ca->scep_pki_message("ca1", $operation, $message);
+
+ print "Content-Type: application/x-pki-message\n\n";
+ print $content;
+ }
+ $ca->close();
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/scep/submit.cgi b/base/ra/forms/ee/scep/submit.cgi
new file mode 100755
index 000000000..b3dfd7a5d
--- /dev/null
+++ b/base/ra/forms/ee/scep/submit.cgi
@@ -0,0 +1,91 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use DBI;
+use CGI;
+use PKI::Service::Op;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Request::Queue;
+use Template::Velocity;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+
+ my $client_id = $util->get_val($q->param('client_id'));
+ my $site_id = $util->get_val($q->param('site_id'));
+ my $email = $util->get_val($q->param('email'));
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ my $queue = PKI::Request::Queue->new();
+ $queue->open($cfg);
+ my $request_id = $queue->create_request("scep",
+ "client_id=" . $client_id . ";" .
+ "site_id=" . $site_id,
+ "0",
+ $email);
+ my %context;
+ $context{request_id} = $util->html_encode($request_id);
+ $self->debug_log($cfg, "request $request_id created");
+ $queue->close();
+
+ my $result = $parser->execute_file_with_context("ee/scep/submit.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/server/admin.cgi b/base/ra/forms/ee/server/admin.cgi
new file mode 100755
index 000000000..18945da02
--- /dev/null
+++ b/base/ra/forms/ee/server/admin.cgi
@@ -0,0 +1,68 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use PKI::Service::Op;
+use Template::Velocity;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ my %context;
+ my $result = $parser->execute_file_with_context("ee/server/admin.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/server/index.cgi b/base/ra/forms/ee/server/index.cgi
new file mode 100755
index 000000000..830409a8b
--- /dev/null
+++ b/base/ra/forms/ee/server/index.cgi
@@ -0,0 +1,68 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use PKI::Service::Op;
+use Template::Velocity;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ my %context;
+ my $result = $parser->execute_file_with_context("ee/server/index.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/server/submit.cgi b/base/ra/forms/ee/server/submit.cgi
new file mode 100755
index 000000000..4916033ee
--- /dev/null
+++ b/base/ra/forms/ee/server/submit.cgi
@@ -0,0 +1,93 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use PKI::Service::Op;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Request::Queue;
+use Template::Velocity;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $util = PKI::Base::Util->new();
+
+ my $server_id = $util->get_val($q->param('server_id'));
+ my $site_id = $util->get_val($q->param('site_id'));
+ my $email = $util->get_val($q->param('email'));
+ my $csr = $util->get_val($q->param('csr'));
+
+ $csr = $util->normalize_csr($csr);
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ my $queue = PKI::Request::Queue->new();
+ $queue->open($cfg);
+ my $request_id = $queue->create_request("server",
+ "server_id=" . $server_id . ";" .
+ "site_id=" . $site_id . ";" .
+ "csr=" . $csr,
+ "0",
+ $email);
+ my %context;
+ $context{request_id} = $util->html_encode($request_id);
+ $self->debug_log($cfg, "request $request_id created");
+ $queue->close();
+
+ my $result = $parser->execute_file_with_context("ee/server/submit.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/user/index.cgi b/base/ra/forms/ee/user/index.cgi
new file mode 100755
index 000000000..ef6b3aa47
--- /dev/null
+++ b/base/ra/forms/ee/user/index.cgi
@@ -0,0 +1,68 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use PKI::Service::Op;
+use Template::Velocity;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ my %context;
+ my $result = $parser->execute_file_with_context("ee/user/index.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/user/renew.cgi b/base/ra/forms/ee/user/renew.cgi
new file mode 100755
index 000000000..63d646ec9
--- /dev/null
+++ b/base/ra/forms/ee/user/renew.cgi
@@ -0,0 +1,165 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use PKI::Base::Conf;
+use PKI::Request::Queue;
+use Template::Velocity;
+use PKI::Service::Op;
+use PKI::Base::Util;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ my $util = PKI::Base::Util->new();
+ my $error = "";
+
+ my $host = $cfg->get("service.machineName");
+ my $port = $cfg->get("service.non_clientauth_securePort");
+
+ $self->debug_params($cfg, $q);
+
+ my $cert = $self->get_cert_record($cfg);
+ $self->debug_log( $cfg, "after get_cert_record");
+ if (!defined($cert) || ($cert eq "")) {
+ $self->debug_log( $cfg, "cert not defined");
+ $error = "certificate not found in database";
+ print $q->redirect("/ee/error.cgi?error=$error");
+ return;
+ }
+ $self->debug_log( $cfg, "got cert");
+
+ my $csr = $cert->{'csr'};
+ if ($csr eq "") {
+ $error = "csr not found in database";
+ print $q->redirect("/ee/error.cgi?error=$error");
+ return;
+ }
+ $self->debug_log( $cfg, "got csr");
+
+ my $req_id = $cert->{'rid'};
+ if ($req_id eq "") {
+ $error = "reqid not found in database";
+ print $q->redirect("/ee/error.cgi?error=$error");
+ return;
+ }
+ $self->debug_log( $cfg, "got req_id = $req_id");
+ $self->debug_log( $cfg, "before renewl read/create request");
+ my $queue = PKI::Request::Queue->new();
+ $queue->open($cfg);
+ my $o_req = $queue->read_request($req_id);
+ if ($o_req eq "") {
+ $self->debug_log( $cfg, "got null o_req");
+ print $q->redirect("/ee/error.cgi?error=$error");
+ return;
+ }
+
+ my $uid = "";
+ my $site_id = "";
+ my $org_csr = "";
+ my $csr_type = "";
+
+ my $data = $o_req->{'data'};
+ foreach $nv (split(/;/, $data)) {
+ my ($n, $v) = split(/=/, $nv);
+ if ($n eq "uid") {
+ $uid = $v;
+ }
+ if ($n eq "site_id") {
+ $site_id = $v;
+ }
+ if ($n eq "csr") {
+ $org_csr = $v;
+ }
+ if ($n eq "csr_type") {
+ $csr_type = $v;
+ }
+ }
+
+ my $new_request = $queue->create_request("renewal",
+ "uid=" . $uid . ";" .
+ "site_id=" . $site_id . ";" .
+ "csr_type=" . $csr_type . ";" .
+ "csr=" . $csr,
+ "orig_reqid=" . $o_req->{'rowid'},
+ $o_req->{'created_by'});
+
+ #self-renewal is created and processed by the same user
+ $ref = $queue->approve_request($new_request, $o_req->{'created_by'});
+ my $nreq = $queue->read_request($new_request);
+ $error = $nreq->{'errorString'};
+ if ($error ne "0") {
+ $self->debug_log( $cfg, "after approve request, got error=$error");
+ print $q->redirect("/ee/error.cgi?error=$error");
+ return;
+ }
+
+ my %context;
+ $context{request_id} = $util->html_encode($new_request);
+ $self->debug_log($cfg, "request $new_request created");
+ $queue->close();
+ $self->debug_log( $cfg, "after renewl read/create request $new_request");
+
+ $context{data} = $util->breakline($util->html_encode($ref->{'data'}), 40);
+ $context{output} = $util->breakline($util->html_encode($ref->{'output'}), 40);
+ $context{serialno} = $util->html_encode($ref->{'serialno'});
+ $context{host} = $util->html_encode($host);
+ $context{port} = $util->html_encode($port);
+
+ #print $q->redirect("/ee/request/getcert.cgi?id=$new_request");
+ my $result = $parser->execute_file_with_context("ee/user/renew.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/user/renewal.cgi b/base/ra/forms/ee/user/renewal.cgi
new file mode 100755
index 000000000..63a211eff
--- /dev/null
+++ b/base/ra/forms/ee/user/renewal.cgi
@@ -0,0 +1,74 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use PKI::Service::Op;
+use Template::Velocity;
+use PKI::Base::Conf;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ my $host = $cfg->get("service.machineName");
+ my $port = $cfg->get("service.securePort");
+
+ my %context;
+ $context{url} = "https://$host:$port/ee/user/renew.cgi";
+ my $result = $parser->execute_file_with_context("ee/user/renewal.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/user/submit.cgi b/base/ra/forms/ee/user/submit.cgi
new file mode 100755
index 000000000..26c900e00
--- /dev/null
+++ b/base/ra/forms/ee/user/submit.cgi
@@ -0,0 +1,112 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use Benchmark;
+use CGI;
+use PKI::Service::Op;
+use Template::Velocity;
+use PKI::Base::Conf;
+use PKI::Base::Util;
+use PKI::Base::Registry;
+use PKI::Request::Queue;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $st = new Benchmark;
+
+ my $util = PKI::Base::Util->new();
+
+ my $userid = $util->get_val($q->param('uid'));
+ my $fullname = $util->get_val($q->param('cn'));
+ my $site_id = $util->get_val($q->param('site_id'));
+ my $email = $util->get_val($q->param('email'));
+ my $csr_type = $util->get_alphanum_val($q->param('csr_type'));
+ my $csr = $util->get_val($q->param('csr'));
+
+ $csr = $util->normalize_csr($csr);
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ my $db_st = new Benchmark;
+ my $queue = PKI::Request::Queue->new();
+ $queue->open($cfg);
+ my $request_id = $queue->create_request("user",
+ "uid=" . $userid . ";" .
+ "cn=" . $fullname . ";" .
+ "site_id=" . $site_id . ";" .
+ "csr_type=" . $csr_type . ";" .
+ "csr=" . $csr,
+ "0",
+ $email);
+ my %context;
+ $context{request_id} = $util->html_encode($request_id);
+ $self->debug_log($cfg, "request $request_id created");
+ $queue->close();
+ my $db_et = new Benchmark;
+
+ my $t_st = new Benchmark;
+ my $result = $parser->execute_file_with_context("ee/user/submit.vm",
+ \%context);
+ my $t_et = new Benchmark;
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+
+ my $et = new Benchmark;
+ $self->debug_log($cfg, "benchmark " .
+ "total=" . timestr(timediff($et, $st)) . " " .
+ "db total=" . timestr(timediff($db_et, $db_st)) . " " .
+ "template total=" . timestr(timediff($t_et, $t_st)) . " "
+ );
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/ee/user/user.cgi b/base/ra/forms/ee/user/user.cgi
new file mode 100755
index 000000000..2d58a532b
--- /dev/null
+++ b/base/ra/forms/ee/user/user.cgi
@@ -0,0 +1,68 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use PKI::Service::Op;
+use Template::Velocity;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+ my $q = CGI->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ my %context;
+ my $result = $parser->execute_file_with_context("ee/user/user.vm",
+ \%context);
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%context);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/forms/index.cgi b/base/ra/forms/index.cgi
new file mode 100755
index 000000000..0e643166b
--- /dev/null
+++ b/base/ra/forms/index.cgi
@@ -0,0 +1,76 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use PKI::Service::Op;
+use Template::Velocity;
+use PKI::Base::Conf;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+
+ my $q = CGI->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ $::symbol{machineName} = $cfg->get("service.machineName");
+ $::symbol{non_clientauth_securePort} = $cfg->get("service.non_clientauth_securePort");
+ $::symbol{securePort} = $cfg->get("service.securePort");
+ $::symbol{unsecurePort} = $cfg->get("service.unsecurePort");
+
+ my $result = $parser->execute_file("index.vm");
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%::symbol);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+
+my $op = op->new();
+$op->execute();
diff --git a/base/ra/lib/perl/PKI/Base/CertStore.pm b/base/ra/lib/perl/PKI/Base/CertStore.pm
new file mode 100644
index 000000000..1a31ff971
--- /dev/null
+++ b/base/ra/lib/perl/PKI/Base/CertStore.pm
@@ -0,0 +1,151 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+package PKI::Base::CertStore;
+
+use DBI;
+use PKI::Base::TimeTool;
+
+#######################################
+# Constructs a cert store
+#######################################
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+#######################################
+# Opens this store
+#######################################
+sub open {
+ my ($self, $cfg) = @_;
+ $self->{cfg} = $cfg;
+ my $dbfile = $cfg->get("database.dbfile");
+ $self->{dbh} = DBI->connect("dbi:SQLite:dbname=$dbfile","","");
+}
+
+sub read_certificate {
+ my ($self, $serialno) = @_;
+ my $dbh = $self->{dbh};
+ my $select = "select * from certificates " .
+ "where serialno=" . $dbh->quote($serialno);
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my $ref = $sth->fetchrow_hashref();
+ $sth->finish();
+ return $ref;
+}
+
+sub map_certificate {
+ my ($self, $certificate) = @_;
+ my $dbh = $self->{dbh};
+ my $select = "select * from certificates " .
+ "where " .
+ "certificate=" . $dbh->quote($certificate);
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my $ref = $sth->fetchrow_hashref();
+ $sth->finish();
+ return $ref;
+}
+
+sub read_certificate_by_approver {
+ my ($self, $uid, $serialno) = @_;
+ my $dbh = $self->{dbh};
+ my $select = "select * from certificates " .
+ "where approved_by=". $dbh->quote($uid).
+ "AND serialno=" . $dbh->quote($serialno);
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my $ref = $sth->fetchrow_hashref();
+ $sth->finish();
+ return $ref;
+}
+
+sub list_certs_by_approver {
+ my ($self, $uid, $startpos, $maxcount) = @_;
+ my $dbh = $self->{dbh};
+ my $select = "select *,approved_by from certificates " .
+ "where " .
+ "approved_by=". $dbh->quote($uid).
+ " limit $startpos, $maxcount";
+
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my @certs;
+ while (my $ref = $sth->fetchrow_hashref()) {
+ push(@certs, $ref);
+ }
+ $sth->finish();
+ return @certs;
+
+
+}
+
+sub add_certificate {
+ my ($self, $serialno, $csr, $subject_dn, $certificate, $reqid, $approved_by) = @_;
+ my $dbh = $self->{dbh};
+
+ my $timet = PKI::Base::TimeTool->new();
+ my $now = $timet->get_time();
+
+ # sqlite is not thread safe, do our own lock here
+ my $cmd = "insert into certificates (" .
+ "subject_dn" . "," .
+ "certificate" . "," .
+ "csr" . "," .
+ "serialno" . "," .
+ "rid" . "," .
+ "approved_by" . "," .
+ "created_at" .
+ ") values (" .
+ $dbh->quote($subject_dn) . "," .
+ $dbh->quote($certificate) . "," .
+ $dbh->quote($csr) . "," .
+ $dbh->quote($serialno) . "," .
+ $dbh->quote($reqid) . "," .
+ $dbh->quote($approved_by) . "," .
+ $dbh->quote($now) .
+ ")";
+REDO_ADD_CERT:
+ eval {
+ $dbh->do($cmd);
+ };
+ if ($dbh->err == 5) {
+ sleep(1);
+ goto REDO_ADD_CERT;
+ }
+
+}
+
+#######################################
+# Closes this store
+#######################################
+sub close {
+ my ($self) = @_;
+ my $dbh = $self->{dbh};
+ $dbh->disconnect();
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/Base/Conf.pm b/base/ra/lib/perl/PKI/Base/Conf.pm
new file mode 100755
index 000000000..895ab28a3
--- /dev/null
+++ b/base/ra/lib/perl/PKI/Base/Conf.pm
@@ -0,0 +1,130 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package PKI::Base::Conf;
+
+use strict;
+use warnings;
+use Exporter;
+
+$PKI::Base::Conf::VERSION = '1.00';
+
+#######################################################
+# Configuration Store
+#######################################################
+sub new {
+ my $class = shift;
+ my $self = {};
+ my %hash = ();
+ $self->{filename} = "";
+ $self->{hash} = \%hash;
+ bless $self,$class;
+ return $self;
+}
+
+sub load_file
+{
+ my ($self, $filename) = @_;
+
+ $self->{filename} = $filename;
+ if (-e $filename) {
+ open(CF, "<$filename");
+ if (defined fileno CF) {
+ while (<CF>) {
+ if (/^#/) {
+ # comments
+ } elsif (/([^=]+)=(.*)$/) {
+ # print "$1 = $2\n";
+ $self->{hash}{$1} = $2;
+ } else {
+ # preserve comments
+ }
+ }
+ }
+ close(CF);
+ }
+}
+
+sub get_filename
+{
+ my ($self) = @_;
+ return $self->{filename};
+}
+
+sub get
+{
+ my ($self, $n) = @_;
+ return $self->{hash}{$n};
+}
+
+sub put
+{
+ my ($self, $n, $v) = @_;
+ $self->{hash}{$n} = $v;
+}
+
+sub commit
+{
+ my ($self) = @_;
+
+ # write stuff back to the file
+# print $self->{filename} . "\n";
+ my $hash = $self->{hash};
+ my $suffix = time();
+
+ if (-e $self->{filename}) {
+ system("mv \"" . $self->{filename} . "\" \"" .
+ $self->{filename} . "." . $suffix . "\"");
+ }
+
+ open(F, ">" . $self->{filename});
+ foreach my $k (sort keys %{$hash}) {
+ print F "$k=$self->{hash}{$k}\n";
+ }
+ close(F);
+
+ if (-e $self->{filename} . "." . $suffix) {
+ system("rm \"" . $self->{filename} . "." . $suffix . "\"");
+ }
+}
+
+sub commit_with_backup
+{
+ my ($self) = @_;
+
+ # write stuff back to the file
+# print $self->{filename} . "\n";
+ my $hash = $self->{hash};
+ my $suffix = time();
+ system("mv \"" . $self->{filename} . "\" \"" .
+ $self->{filename} . "." . $suffix . "\"");
+
+ open(F, ">" . $self->{filename});
+ foreach my $k (sort keys %{$hash}) {
+ print F "$k=$self->{hash}{$k}\n";
+ }
+ close(F);
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/Base/PinStore.pm b/base/ra/lib/perl/PKI/Base/PinStore.pm
new file mode 100644
index 000000000..437d259ff
--- /dev/null
+++ b/base/ra/lib/perl/PKI/Base/PinStore.pm
@@ -0,0 +1,180 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+package PKI::Base::PinStore;
+
+use DBI;
+use PKI::Base::TimeTool;
+
+#######################################
+# Constructs a request queue
+#######################################
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+#######################################
+# Opens request queue
+#######################################
+sub open {
+ my ($self, $cfg) = @_;
+ $self->{cfg} = $cfg;
+ my $dbfile = $cfg->get("database.dbfile");
+ $self->{dbh} = DBI->connect("dbi:SQLite:dbname=$dbfile","","");
+}
+
+#######################################
+# Creates a new request
+#######################################
+sub generate_random
+{
+ my $low = $_[0];
+ my $high = $_[1];
+
+ my $number = 0;
+
+ if( $low >= $high || $low < 0 || $high < 0 ) {
+ return -1;
+ }
+
+ $number = int( rand( $high -$low +1 ) ) + $low;
+
+ return $number;
+}
+
+
+# arg0 length of string
+# return random string
+sub generate_random_string()
+{
+ my $length_of_randomstring=shift; # the length of the string
+
+ my @chars=( 'a'..'z','A'..'Z','0'..'9' );
+ my $random_string;
+
+ foreach( 1..$length_of_randomstring ) {
+ $random_string .= $chars[rand @chars];
+ }
+
+ return $random_string;
+}
+
+sub create_pin {
+ my ($self, $key, $rid, $created_by) = @_;
+ my $dbh = $self->{dbh};
+
+ my $pin = &generate_random_string(10);
+ my $timet = PKI::Base::TimeTool->new();
+ my $now = $timet->get_time();
+
+ # delete previous pin
+ my $delete = "delete from pins where key=" . $dbh->quote($key);
+ $dbh->do($delete);
+
+ my $insert = "insert into pins (" .
+ "key" . "," .
+ "pin" . "," .
+ "rid" . "," .
+ "created_by" . "," .
+ "created_at" .
+ ") values (" .
+ $dbh->quote($key) . "," .
+ $dbh->quote($pin) . "," .
+ $dbh->quote($rid) . "," .
+ $dbh->quote($created_by) . "," .
+ $dbh->quote($now) .
+ ")";
+REDO_CREATE_PIN:
+ eval {
+ $dbh->do($insert);
+ };
+ if ($dbh->err == 5) {
+ sleep(1);
+ goto REDO_CREATE_PIN;
+ }
+
+ my $rid = $dbh->func('last_insert_rowid');
+
+# my $ref = $self->read_pin($rid);
+
+ return $pin;
+}
+
+#######################################
+# Matches pin
+#######################################
+sub match {
+ my ($self, $key, $pin) = @_;
+ my $dbh = $self->{dbh};
+ my $select = "select * from pins " .
+ "where " .
+ "key=" . $dbh->quote($key) . " AND " .
+ "pin=" . $dbh->quote($pin);
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my $ref = $sth->fetchrow_hashref();
+ $sth->finish();
+ if (defined($ref)) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+sub read_pin {
+ my ($self, $key) = @_;
+ my $dbh = $self->{dbh};
+ my $select = "select * from pins " .
+ "where " .
+ "key=" . $dbh->quote($key);
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my $ref = $sth->fetchrow_hashref();
+ $sth->finish();
+ return $ref;
+}
+
+#######################################
+# Deletes pin
+#######################################
+sub delete {
+ my ($self, $key) = @_;
+ my $dbh = $self->{dbh};
+ my $cmd = "delete from pins " .
+ "where " .
+ "key=" . $dbh->quote($key);
+ $dbh->do($cmd);
+}
+
+#######################################
+# Closes request queue
+#######################################
+sub close {
+ my ($self) = @_;
+ my $dbh = $self->{dbh};
+ $dbh->disconnect();
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/Base/Registry.pm b/base/ra/lib/perl/PKI/Base/Registry.pm
new file mode 100644
index 000000000..a4fb83f28
--- /dev/null
+++ b/base/ra/lib/perl/PKI/Base/Registry.pm
@@ -0,0 +1,55 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+package PKI::Base::Registry;
+
+use PKI::Base::Conf;
+
+my $docroot;
+my $cfg;
+my $parser;
+
+BEGIN {
+ $docroot = $ENV{DOCUMENT_ROOT};
+ $cfg = PKI::Base::Conf->new();
+ $cfg->load_file("$docroot/../conf/CS.cfg");
+ $parser = new Template::Velocity($docroot);
+
+}
+
+sub get_docroot {
+ my ($self) = @_;
+ return $docroot;
+}
+
+sub get_parser {
+ my ($self) = @_;
+ return $parser;
+}
+
+sub get_config {
+ my ($self) = @_;
+ return $cfg;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/Base/TimeTool.pm b/base/ra/lib/perl/PKI/Base/TimeTool.pm
new file mode 100755
index 000000000..11f4be208
--- /dev/null
+++ b/base/ra/lib/perl/PKI/Base/TimeTool.pm
@@ -0,0 +1,54 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+package PKI::Base::TimeTool;
+
+use Time::Local;
+
+use DBI;
+use PKI::Base::TimeTool;
+
+#######################################
+# Constructs a request queue
+#######################################
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub get_time()
+{
+ my ($self) = @_;
+ my ($sec, $min, $hr, $mday, $mnth, $y, $wd, $yd, $ds) = localtime();
+ my $r_year = 1900 + $y;
+ my $r_mnth;
+ my $r_day;
+ $r_day = $mday;
+ $mnth = $mnth + 1;
+ $r_mnth = $mnth;
+ return "$r_year-$r_mnth-$r_day $hr:$min:$sec";
+}
+
+
+1;
diff --git a/base/ra/lib/perl/PKI/Base/UserStore.pm b/base/ra/lib/perl/PKI/Base/UserStore.pm
new file mode 100644
index 000000000..c05683792
--- /dev/null
+++ b/base/ra/lib/perl/PKI/Base/UserStore.pm
@@ -0,0 +1,343 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+package PKI::Base::UserStore;
+
+use DBI;
+use PKI::Base::TimeTool;
+
+#######################################
+# Constructs a request queue
+#######################################
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+#######################################
+# Opens this store
+#######################################
+sub open {
+ my ($self, $cfg) = @_;
+ $self->{cfg} = $cfg;
+ my $dbfile = $cfg->get("database.dbfile");
+ $self->{dbh} = DBI->connect("dbi:SQLite:dbname=$dbfile","","");
+ my $timeout = $self->{dbh}->func("busy_timeout");
+ $self->{dbh}->func($timeout * 10, "busy_timeout");
+}
+
+#######################################
+# Maps user
+#######################################
+sub map_user {
+ my ($self, $certificate) = @_;
+ my $dbh = $self->{dbh};
+ my $select = "select * from users " .
+ "where " .
+ "certificate=" . $dbh->quote($certificate);
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my $ref = $sth->fetchrow_hashref();
+ $sth->finish();
+ return $ref;
+}
+
+#######################################
+# Gets roles of the given user
+#######################################
+sub get_roles {
+ my ($self, $uid) = @_;
+ my $dbh = $self->{dbh};
+ my $select = "select * from roles " .
+ "where " .
+ "uid=" . $dbh->quote($uid);
+ my @roles;
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ while (my $ref = $sth->fetchrow_hashref()) {
+ push(@roles, $ref->{'gid'});
+ }
+ $sth->finish();
+ return @roles;
+}
+
+
+#######################################
+# Reads a user
+#######################################
+sub read_group {
+ my ($self, $gid) = @_;
+ my $dbh = $self->{dbh};
+ my $select = "select * from groups " .
+ "where gid=" . $dbh->quote($gid);
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my $ref = $sth->fetchrow_hashref();
+ $sth->finish();
+ return $ref;
+}
+
+sub read_user {
+ my ($self, $uid) = @_;
+ my $dbh = $self->{dbh};
+ my $select = "select * from users " .
+ "where uid=" . $dbh->quote($uid);
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my $ref = $sth->fetchrow_hashref();
+ $sth->finish();
+ return $ref;
+}
+
+sub set_user {
+ my ($self, $uid, $name, $value) = @_;
+ my $dbh = $self->{dbh};
+
+ my $timet = PKI::Base::TimeTool->new();
+ my $now = $timet->get_time();
+ my $update = "update users set " .
+ $name . "=" . $dbh->quote($value) . "," .
+ "updated_at=" . $dbh->quote($now) . " " .
+ "where uid=" . $dbh->quote($uid);
+ $dbh->do($update);
+
+ my $select = "select * from users " .
+ "where uid=" . $dbh->quote($uid);
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my $ref = $sth->fetchrow_hashref();
+ $sth->finish();
+
+ return $ref;
+}
+
+#######################################
+# Lists all members in the given group
+#######################################
+sub list_all_members {
+ my ($self, $gid) = @_;
+ my $dbh = $self->{dbh};
+ my $select = "select * from roles where " .
+ "gid=" . $dbh->quote($gid) . " " .
+ "order by uid desc ";
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my @reqs;
+ while (my $ref = $sth->fetchrow_hashref()) {
+ push(@reqs, $ref);
+ }
+ $sth->finish();
+ return @reqs;
+}
+
+#######################################
+# Lists
+#######################################
+sub list_all_non_members {
+ my ($self, $gid) = @_;
+ my $dbh = $self->{dbh};
+ # find members of the given group
+ my $select1 = "select * from roles where " .
+ "gid=" . $dbh->quote($gid);
+ my $sth1 = $dbh->prepare($select1);
+ $sth1->execute();
+ my $filter = "";
+ while (my $ref1 = $sth1->fetchrow_hashref()) {
+ if ($filter eq "") {
+ $filter = "uid<>" . $dbh->quote($ref1->{'uid'});
+ } else {
+ $filter = $filter . " AND " . "uid<>" . $dbh->quote($ref1->{'uid'});
+ }
+ }
+ $sth1->finish();
+
+ my $select;
+ if ($filter eq "") {
+ $select = "select * from users " .
+ "order by uid desc ";
+ } else {
+ $select = "select * from users where (" .
+ $filter . ") " .
+ "order by uid desc ";
+ }
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my @reqs;
+ while (my $ref = $sth->fetchrow_hashref()) {
+ push(@reqs, $ref);
+ }
+ $sth->finish();
+ return @reqs;
+}
+
+sub delete_user {
+ my ($self, $userid) = @_;
+ my $dbh = $self->{dbh};
+
+ my $cmd = "delete from roles where uid=" . $dbh->quote($userid);
+ $dbh->do($cmd);
+ $cmd = "delete from users where uid=" . $dbh->quote($userid);
+ $dbh->do($cmd);
+}
+
+sub add_user_to_group {
+ my ($self, $gid, $userid) = @_;
+ my $dbh = $self->{dbh};
+
+ my $timet = PKI::Base::TimeTool->new();
+ my $now = $timet->get_time();
+
+ my $cmd = "insert into roles (" .
+ "gid" . "," .
+ "uid" .
+ ") values (" .
+ $dbh->quote($gid) . "," .
+ $dbh->quote($userid) .
+ ")";
+ $dbh->do($cmd);
+}
+
+sub delete_user_from_group {
+ my ($self, $gid, $userid) = @_;
+ my $dbh = $self->{dbh};
+
+ my $timet = PKI::Base::TimeTool->new();
+ my $now = $timet->get_time();
+
+ my $cmd = "delete from roles where " .
+ "gid=" . $dbh->quote($gid) . " AND " .
+ "uid=" . $dbh->quote($userid);
+ $dbh->do($cmd);
+}
+
+sub add_user {
+ my ($self, $userid, $name, $email, $certificate) = @_;
+ my $dbh = $self->{dbh};
+
+ my $timet = PKI::Base::TimeTool->new();
+ my $now = $timet->get_time();
+
+ my $cmd = "insert into users (" .
+ "uid" . "," .
+ "name" . "," .
+ "email" . "," .
+ "certificate" . "," .
+ "created_at" .
+ ") values (" .
+ $dbh->quote($userid) . "," .
+ $dbh->quote($name) . "," .
+ $dbh->quote($email) . "," .
+ $dbh->quote($certificate) . "," .
+ $dbh->quote($now) .
+ ")";
+REDO_ADD_USER:
+ eval {
+ $dbh->do($cmd);
+ };
+ if ($dbh->err == 5) {
+ sleep(1);
+ goto REDO_ADD_USER;
+ }
+}
+
+sub add_group {
+ my ($self, $gid, $name) = @_;
+ my $dbh = $self->{dbh};
+
+ my $timet = PKI::Base::TimeTool->new();
+ my $now = $timet->get_time();
+
+ my $cmd = "insert into groups (" .
+ "gid" . "," .
+ "name" . "," .
+ "created_at" .
+ ") values (" .
+ $dbh->quote($gid) . "," .
+ $dbh->quote($name) . "," .
+ $dbh->quote($now) .
+ ")";
+REDO_ADD_GROUP:
+ eval {
+ $dbh->do($cmd);
+ };
+ if ($dbh->err == 5) {
+ sleep(1);
+ goto REDO_ADD_GROUP;
+ }
+}
+
+sub delete_group {
+ my ($self, $gid) = @_;
+ my $dbh = $self->{dbh};
+
+ my $timet = PKI::Base::TimeTool->new();
+ my $now = $timet->get_time();
+
+ my $cmd = "delete from roles where gid=" . $dbh->quote($gid);
+ $dbh->do($cmd);
+ $cmd = "delete from groups where gid=" . $dbh->quote($gid);
+ $dbh->do($cmd);
+}
+
+sub list_users {
+ my ($self, $startpos, $maxcount) = @_;
+ my $dbh = $self->{dbh};
+ my $select = "select * from users " .
+ "order by uid desc " .
+ "limit $startpos, $maxcount";
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my @reqs;
+ while (my $ref = $sth->fetchrow_hashref()) {
+ push(@reqs, $ref);
+ }
+ $sth->finish();
+ return @reqs;
+}
+
+sub list_groups {
+ my ($self, $startpos, $maxcount) = @_;
+ my $dbh = $self->{dbh};
+ my $select = "select * from groups " .
+ "order by gid desc " .
+ "limit $startpos, $maxcount";
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my @reqs;
+ while (my $ref = $sth->fetchrow_hashref()) {
+ push(@reqs, $ref);
+ }
+ $sth->finish();
+ return @reqs;
+}
+#######################################
+# Closes this store
+#######################################
+sub close {
+ my ($self) = @_;
+ my $dbh = $self->{dbh};
+ $dbh->disconnect();
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/Base/Util.pm b/base/ra/lib/perl/PKI/Base/Util.pm
new file mode 100755
index 000000000..f01062e42
--- /dev/null
+++ b/base/ra/lib/perl/PKI/Base/Util.pm
@@ -0,0 +1,155 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+package PKI::Base::Util;
+
+use Time::Local;
+
+use DBI;
+use HTML::Entities;
+
+#######################################
+# Constructs a util
+#######################################
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub get_val()
+{
+ my ($self, $s) = @_;
+ return $s;
+}
+
+sub get_integer_val()
+{
+ my ($self, $s) = @_;
+ return $s;
+}
+
+sub get_string_val()
+{
+ my ($self, $s) = @_;
+ return $s;
+}
+
+sub get_alphanum_val()
+{
+ my ($self, $s) = @_;
+ $s =~ s/[^A-Za-z0-9 ]*//g;
+ return $s;
+}
+
+sub normalize_csr()
+{
+ my ($self, $s) = @_;
+ $s =~ s/-----BEGIN CERTIFICATE REQUEST-----//g;
+ $s =~ s/-----END CERTIFICATE REQUEST-----//g;
+ $s =~ s/-----BEGIN NEW CERTIFICATE REQUEST-----//g;
+ $s =~ s/-----END NEW CERTIFICATE REQUEST-----//g;
+ $s =~ s/\s//g;
+ return $s;
+}
+
+sub breakline()
+{
+ my ($self, $s, $maxlen) = @_;
+
+ my $new_s;
+ my $i = 0;
+ foreach my $c (split(//, $s)) {
+ if ($i == $maxlen) {
+ $i = 0;
+ $new_s = $new_s . "<br/>";
+ }
+ $new_s = $new_s . $c;
+ $i++;
+ }
+ return $new_s;
+}
+
+sub nv_to_hash()
+{
+ my ($self, $s) = @_;
+ my %hash;
+ my @pairs = split(/;/, $s);
+ foreach $pair (@pairs) {
+ my $i = index('=', $pair);
+ my $n = substr($pair, 0, $i-1);
+ my $v = substr($pair, $i);
+ $hash{$n} = $v;
+ }
+ return \%hash;
+}
+
+sub nv_to_str()
+{
+ my ($self, $hash) = @_;
+ my $s = "";
+ foreach $k (keys %$hash) {
+ if ($s eq "") {
+ $s = $k . "=" . $$hash{$k};
+ } else {
+ $s = $s . ";" . $k . "=" . $$hash{$k};
+ }
+ }
+ return $s;
+}
+
+sub test()
+{
+ my %h;
+ $h{'x'} = 'y';
+ $h{'z'} = 'y';
+ my $o = PKI::Base::NameValueUtil->new();
+ print $o->to_str(\%h) . "\n";
+ print $o->to_str($o->to_hash("5=1;c=2")) . "\n";
+}
+
+sub html_encode()
+{
+ my ($self, $s) = @_;
+ return HTML::Entities::encode($s);
+}
+
+sub html_encode_and_break()
+{
+ my ($self, $s, $maxlen) = @_;
+ my $new_s = '';
+ my $i = 0;
+ foreach my $c (split(//, $s)) {
+ if ($i == $maxlen) {
+ $i = 0;
+ $new_s = $new_s . '***';
+ }
+ $new_s = $new_s . $c;
+ $i++;
+ }
+ $s = HTML::Entities::encode($new_s);
+ $s =~ s/\*\*\*/<br\/>/g;
+ return $s;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/Conn/CA.pm b/base/ra/lib/perl/PKI/Conn/CA.pm
new file mode 100644
index 000000000..f3c8834ed
--- /dev/null
+++ b/base/ra/lib/perl/PKI/Conn/CA.pm
@@ -0,0 +1,390 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+package PKI::Conn::CA;
+
+use URI::URL;
+use URI::Escape;
+use XML::Simple;
+use Data::Dumper;
+use DBI;
+use PKI::Base::TimeTool;
+use PKI::Base::CertStore;
+use PKI::Base::Util;
+use PKI::Request::Queue;
+
+#######################################
+# Constructs a request queue
+#######################################
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+#######################################
+# Opens request queue
+#######################################
+sub open {
+ my ($self, $cfg) = @_;
+ $self->{cfg} = $cfg;
+ my $certstore = PKI::Base::CertStore->new();
+ $certstore->open($cfg);
+ $self->{certstore} = $certstore;
+}
+
+#######################################
+# Enrolls
+#######################################
+sub enroll {
+ my ($self, $rid, $con_id, $profile_id, $cert_request_type, $cert_request) = @_;
+
+ my $cfg = $self->{cfg};
+ my $instdir = $cfg->get("service.instanceDir");
+ my $db_password;
+
+ my $nickname = $cfg->get("conn." . $con_id . ".clientNickname");
+ my $cahostport = $cfg->get("conn." . $con_id . ".hostport");
+ my ($host, $port) = split(/:/, $cahostport);
+
+ if ($nickname =~ /(.*):(.*)/) {
+ $db_password = `grep \"$1:\" \"$instdir/conf/password.conf\" | awk -F: '{print \$2}'`;
+ } else {
+ $db_password = `grep \"internal:\" \"$instdir/conf/password.conf\" | cut -c10-`;
+ }
+ $db_password =~ s/\n$//g;
+
+ my $queue = PKI::Request::Queue->new();
+ $queue->open($cfg);
+ my $req = $queue->read_request($rid);
+ if ($req->{'subject_dn'} ne "unavailable") {
+ $subject = $req->{'subject_dn'};
+ }
+
+ my $tmpfile = "/tmp/tmp-$rid-$$";
+ my $params = "profileId=" . $profile_id . "&" .
+ "requestor_name=" .
+ URI::Escape::uri_escape("$requestor_name") . "&" .
+ "cert_request_type=" . $cert_request_type . "&" .
+ "subject=" .
+ URI::Escape::uri_escape("$subject") . "&" .
+ "cert_request=" .
+ URI::Escape::uri_escape("$cert_request") . "&" .
+ "xmlOutput=true";
+
+ system("/usr/bin/sslget -e \"$params\" -d \"$instdir/alias\" -p \"$db_password\" -v -n \"$nickname\" -r \"/ca/ee/ca/profileSubmit\" $host:$port > $tmpfile");
+
+ my $content = `cat $tmpfile`;
+ if ($content eq "") {
+ $queue->set_request($rid, "errorString", "CA Connection Error");
+ $queue->set_request($rid, "status", "ERROR");
+ $queue->close();
+
+ $queue->close();
+ return "";
+ }
+
+ $content =~ /(\<XMLResponse\>.*\<\/XMLResponse\>)/;
+ $content = $1;
+ $content =~ s/\n//g;
+
+ my $xmlparser = XML::Simple->new();
+ my $response = $xmlparser->XMLin($content);
+
+ my $status = $response->{Status};
+ if ($status ne "0") {
+ my $errorString = $response->{Error};
+
+ $queue->set_request($rid, "errorString", "CA: ".$errorString);
+ $queue->set_request($rid, "status", "ERROR");
+
+ $queue->close();
+ return "";
+ }
+
+ #reset to 0 in case of re-approval
+ $queue->set_request($rid, "errorString", "0");
+ my $req = $queue->read_request($rid);
+ my $approved_by = $req->{'processed_by'};
+ my $serialno = $response->{Requests}->{Request}->{serialno};
+ $queue->set_request($rid, "serialno", $serialno);
+ my $subject_dn = $response->{Requests}->{Request}->{SubjectDN};
+ $queue->set_request($rid, "subject_dn", $subject_dn);
+ my $cert = $response->{Requests}->{Request}->{b64};
+ $queue->close();
+
+ my $util = PKI::Base::Util->new();
+ my $csr = $cert_request;
+ $csr = $util->normalize_csr($csr);
+
+ $self->{certstore}->add_certificate($serialno, $csr, $subject_dn, $cert, $rid, $approved_by);
+
+ system("rm $tmpfile");
+
+ return $cert;
+}
+
+sub get_http_content
+{
+ my ($self, $filename) = @_;
+ my $data = "";
+ my $count = `grep -a Content-Length $filename | cut -d' ' -f2`;
+ chomp($count);
+ my $file_size = -s $filename;
+ my $offset = $file_size - $count;
+
+ open(FP, "<$filename");
+ binmode(FP);
+ seek(FP, $offset-1, 0);
+ read(FP, $data, $count);
+ close(FP);
+ return $data;
+}
+
+#######################################
+# Revoke
+#######################################
+sub revoke {
+ my ($self, $rid, $con_id, $serialno, $reason) = @_;
+
+ my $cfg = $self->{cfg};
+ my $instdir = $cfg->get("service.instanceDir");
+ my $db_password;
+
+ my $nickname = $cfg->get("conn." . $con_id . ".clientNickname");
+ my $cahostport = $cfg->get("conn." . $con_id . ".hostagentport");
+
+ if ($nickname =~ /(.*):(.*)/) {
+ $db_password = `grep \"$1:\" \"$instdir/conf/password.conf\" | awk -F: '{print \$2}'`;
+ } else {
+ $db_password = `grep \"internal:\" \"$instdir/conf/password.conf\" | cut -c10-`;
+ }
+ $db_password =~ s/\n$//g;
+
+ my $tmpfile = "/tmp/tmp-revoke-$serialno-$$";
+ my ($host, $port) = split(/:/, $cahostport);
+ my $params = "op=" . "revoke" . "&" .
+ "revocationReason=" .$reason . "&" .
+ "revokeAll=(certRecordId=" ."0x".$serialno . ")&" .
+ "totalRecordCount=" ."1" . "&" .
+ "xml=true";
+ system("/usr/bin/sslget -e \"$params\" -d \"$instdir/alias\" -p \"$db_password\" -v -n \"$nickname\" -r \"/ca/agent/ca/doRevoke\" $host:$port > $tmpfile");
+
+ my $content = `cat $tmpfile`;
+ my $queue = PKI::Request::Queue->new();
+ $queue->open($cfg);
+ if ($content eq "") {
+ $queue->set_request($rid, "errorString", "CA Connection Error");
+# $queue->set_request($rid, "status", "ERROR");
+ $queue->close();
+
+ $queue->close();
+ return "";
+ }
+ $content =~ s/\000//;
+ $content =~ /(\<xml\>.*\<\/xml\>)/s;
+ $content = $1;
+ $content =~ s/\n//g;
+
+ my $req = $queue->read_request($rid);
+
+ my $xmlparser = XML::Simple->new(NormalizeSpace => 2);
+ my $response = $xmlparser->XMLin($content);
+
+ my $errorString = $response->{fixed}->{errorDetails};
+ my $revoked = $response->{header}->{revoked};
+
+ if ($revoked ne "yes") {
+ $queue->set_request($rid, "errorString", "CA:".$errorString);
+ } else {
+ $queue->set_request($rid, "errorString", "0");
+ }
+ system("rm $tmpfile");
+
+ $queue->close();
+ return;
+}
+
+#######################################
+# Get Certificate Status
+#######################################
+sub getCertStatus {
+ my ($self, $con_id, $serialno) = @_;
+
+ my $cfg = $self->{cfg};
+ my $instdir = $cfg->get("service.instanceDir");
+ my $db_password;
+
+ my $nickname = $cfg->get("conn." . $con_id . ".clientNickname");
+ my $cahostport = $cfg->get("conn." . $con_id . ".hostport");
+ my ($host, $port) = split(/:/, $cahostport);
+
+ if ($nickname =~ /(.*):(.*)/) {
+ $db_password = `grep \"$1:\" \"$instdir/conf/password.conf\" | awk -F: '{print \$2}'`;
+ } else {
+ $db_password = `grep \"internal:\" \"$instdir/conf/password.conf\" | cut -c10-`;
+ }
+ $db_password =~ s/\n$//g;
+
+
+ my $tmpfile = "/tmp/tmp-$serialno-$$";
+ my $params = "serialNumber=" . "0x".$serialno . "&" .
+ "xml=true";
+ system("/usr/bin/sslget -e \"$params\" -d \"$instdir/alias\" -p \"$db_password\" -v -n \"$nickname\" -r \"/ca/ee/ca/displayBySerial\" $host:$port > $tmpfile");
+
+ my $content = `cat $tmpfile`;
+ system("rm $tmpfile");
+ if ($content eq "") {
+ return "CA: Connection Error";
+ system("rm $tmpfile");
+ }
+
+ $content =~ /(\<xml\>.*\<\/xml\>)/s;
+ $content = $1;
+ $content =~ s/\n//g;
+
+ my $xmlparser = XML::Simple->new(NormalizeSpace => 2);
+ my $response = $xmlparser->XMLin($content);
+
+ my $errorString = $response->{fixed}->{errorDetails};
+ my $revokeReason = $response->{header}->{revocationReason};
+
+ if ($revokeReason eq "") {
+ if ($errorString eq "") {
+ return "not revoked";
+ } else {
+ return "CA:".$errorString;
+ }
+ } else {
+ return "revoked:".$revokeReason;
+ }
+}
+
+#######################################
+# SCEP
+#######################################
+sub scep_get_ca_cert {
+ my ($self, $con_id, $operation, $message) = @_;
+
+ my $cfg = $self->{cfg};
+ my $instdir = $cfg->get("service.instanceDir");
+ my $db_password;
+
+ my $nickname = $cfg->get("conn." . $con_id . ".clientNickname");
+ my $cahostport = $cfg->get("conn." . $con_id . ".hostport");
+ my ($host, $port) = split(/:/, $cahostport);
+
+ if ($nickname =~ /(.*):(.*)/) {
+ $db_password = `grep \"$1:\" \"$instdir/conf/password.conf\" | awk -F: '{print \$2}'`;
+ } else {
+ $db_password = `grep \"internal:\" \"$instdir/conf/password.conf\" | cut -c10-`;
+ }
+ $db_password =~ s/\n$//g;
+
+ my $tmpfile = "/tmp/tmp-$$";
+ my $params = "operation=" . $operation . "&" .
+ "message=" . $message;
+ system("/usr/bin/sslget -e \"$params\" -d \"$instdir/alias\" -p \"$db_password\" -n \"$nickname\" -r \"/ca/ee/ca/pkiclient\" $host:$port > $tmpfile");
+
+
+ my $content = $self->get_http_content($tmpfile);
+
+ system("rm $tmpfile");
+
+ return $content;
+}
+
+# decode PKI Message
+sub scep_decode {
+ my ($self, $con_id, $operation, $message) = @_;
+
+ my $cfg = $self->{cfg};
+ my $instdir = $cfg->get("service.instanceDir");
+ my $db_password;
+
+ my $nickname = $cfg->get("conn." . $con_id . ".clientNickname");
+ my $cahostport = $cfg->get("conn." . $con_id . ".hostport");
+ my ($host, $port) = split(/:/, $cahostport);
+
+ if ($nickname =~ /(.*):(.*)/) {
+ $db_password = `grep \"$1:\" \"$instdir/conf/password.conf\" | awk -F: '{print \$2}'`;
+ } else {
+ $db_password = `grep \"internal:\" \"$instdir/conf/password.conf\" | cut -c10-`;
+ }
+ $db_password =~ s/\n$//g;
+
+ my $tmpfile = "/tmp/tmp-$$";
+ my $params = "operation=" . $operation . "&" .
+ "message=" . $message . "&" .
+ "decode=true";
+ system("/usr/bin/sslget -e \"$params\" -d \"$instdir/alias\" -p \"$db_password\" -n \"$nickname\" -r \"/ca/ee/ca/pkiclient\" $host:$port > $tmpfile");
+
+
+ my $content = $self->get_http_content($tmpfile);
+
+ system("rm $tmpfile");
+
+ return $content;
+}
+
+sub scep_pki_message {
+ my ($self, $con_id, $operation, $message) = @_;
+
+ my $cfg = $self->{cfg};
+ my $instdir = $cfg->get("service.instanceDir");
+ my $db_password;
+
+ my $nickname = $cfg->get("conn." . $con_id . ".clientNickname");
+ my $cahostport = $cfg->get("conn." . $con_id . ".hostport");
+ my ($host, $port) = split(/:/, $cahostport);
+
+ if ($nickname =~ /(.*):(.*)/) {
+ $db_password = `grep \"$1:\" \"$instdir/conf/password.conf\" | awk -F: '{print \$2}'`;
+ } else {
+ $db_password = `grep \"internal:\" \"$instdir/conf/password.conf\" | cut -c10-`;
+ }
+ $db_password =~ s/\n$//g;
+
+ my $tmpfile = "/tmp/tmp-$$";
+ my $params = "operation=" . $operation . "&" .
+ "message=" . $message;
+ system("/usr/bin/sslget -e \"$params\" -d \"$instdir/alias\" -p \"$db_password\" -n \"$nickname\" -r \"/ca/ee/ca/pkiclient\" $host:$port > $tmpfile");
+
+
+ my $content = $self->get_http_content($tmpfile);
+
+ system("rm $tmpfile");
+
+ return $content;
+}
+
+
+#######################################
+# Closes connection
+#######################################
+sub close {
+ my ($self) = @_;
+ $self->{certstore}->close();
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/AdminAuthPanel.pm b/base/ra/lib/perl/PKI/RA/AdminAuthPanel.pm
new file mode 100755
index 000000000..656dc2d5e
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/AdminAuthPanel.pm
@@ -0,0 +1,86 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+
+package PKI::RA::AdminAuthPanel;
+$PKI::RA::AdminAuthPanel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(8);
+ $self->{"getName"} = &PKI::RA::Common::r("Admin Authentication");
+ $self->{"vmfile"} = "adminauthenticatepanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("AdminAuthPanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("AdminAuthPanel: update");
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("AdminAuthPanel: display");
+ return 1;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/AdminPanel.pm b/base/ra/lib/perl/PKI/RA/AdminPanel.pm
new file mode 100755
index 000000000..a5538ef54
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/AdminPanel.pm
@@ -0,0 +1,227 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+use URI::URL;
+use URI::Escape;
+use DBI;
+
+package PKI::RA::AdminPanel;
+$PKI::RA::AdminPanel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(14);
+ $self->{"getName"} = &PKI::RA::Common::r("Administrator");
+ $self->{"vmfile"} = "adminpanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("AdminPanel: validate");
+ return 1;
+}
+
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("AdminPanel: update");
+
+ my $uid = $q->param("uid");
+ my $name = $q->param("name");
+ my $email = $q->param("email");
+ my $password = $q->param("__pwd");
+ my $password_again = $q->param("__admin_password_again");
+
+ my $cert_request = $q->param("cert_request");
+ my $subject = $q->param("subject");
+ my $profile_id = $q->param("profileId");
+ my $cert_request_type = $q->param("cert_request_type");
+
+ $cert_request =~ s/%0D%0A//g; # remove carraige return
+
+ # submit request to CA
+
+ # Admin Certificate should be obtained from the ca selected in the
+ # name panel. If name panel use External CA, the admin certificate
+ # will be issued by the security domain CA.
+ my $cainfo = $::config->get("preop.ca.url");
+ &PKI::RA::Wizard::debug_log("AdminPanel: preop.ca.url=$cainfo");
+ if ($cainfo eq "" || $cainfo =~ /:$/) {
+ $cainfo = $::config->get("config.sdomainEEURL");
+ &PKI::RA::Wizard::debug_log("AdminPanel: config.sdomainEEURL=$cainfo");
+ }
+ &PKI::RA::Wizard::debug_log("AdminPanel: Connecting to CA: $cainfo");
+ my $cainfo_url = new URI::URL($cainfo);
+ my $sdom = $::config->get("config.sdomainEEURL");
+ my $sdom_url = new URI::URL($sdom);
+
+ my $machineName = $::config->get("service.machineName");
+ my $securePort = $::config->get("service.securePort");
+ my $session_id = $::config->get("preop.sessionID");
+
+ my $tokenname = $::config->get("preop.module.token");
+ my $token_pwd = $::pwdconf->get($tokenname);
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+ my $instanceID = $::config->get("service.instanceID");
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $db_password =~ s/\n$//g;
+
+ my $requestor_name = "RA-" . $machineName . "-" . $securePort;
+
+ my $params = "profileId=" . $profile_id . "&" .
+ "requestor_name=" . $requestor_name . "&" .
+ "cert_request_type=" . $cert_request_type . "&" .
+ "subject=" . $subject . "&" .
+ "cert_request=" .
+ URI::Escape::uri_escape("$cert_request") . "&" .
+ "xmlOutput=true" . "&" .
+ "sessionID=" . $session_id . "&" .
+ "auth_hostname=" . $sdom_url->host . "&" .
+ "auth_port=" . $sdom_url->port;
+
+ my $ca_host = $cainfo_url->host;
+ my $https_ee_port = $cainfo_url->port;
+ my $content = "";
+ my $tmpfile = "/tmp/admin-$$";
+ if (($tokenname eq "") || ($tokenname eq "NSS Certificate DB")) {
+ system("/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"$db_password\" -v -n \"$nickname\" -r \"/ca/ee/ca/profileSubmit\" $ca_host:$https_ee_port > $tmpfile");
+ $content = `cat $tmpfile`;
+ } else {
+ system("/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"$token_pwd\" -v -n \"$nickname\" -r \"/ca/ee/ca/profileSubmit\" $ca_host:$https_ee_port > $tmpfile");
+ $content = `cat $tmpfile`;
+ }
+ system("rm $tmpfile");
+ &PKI::RA::Wizard::debug_log("req = " . $content);
+
+ $content =~ /(\<XMLResponse\>.*\<\/XMLResponse\>)/;
+ $content = $1;
+
+ # create user in internal database
+ &PKI::RA::Wizard::debug_log("AdminPanel: Creating user in internal database");
+ # use scripts/addAgents.ldif
+
+ my $parser = XML::Simple->new();
+ my $response = $parser->XMLin($content);
+ my $admincert = $response->{Requests}->{Request}->{b64};
+ &PKI::RA::Wizard::debug_log("AdminPanel: admincert " . $admincert);
+
+ # create local database
+ my $dbh = DBI->connect(
+ "dbi:SQLite:dbname=$instanceDir/conf/dbfile","","");
+ my $insert = "insert into users (" .
+ "uid" . "," .
+ "name" . "," .
+ "password" . "," .
+ "email" . "," .
+ "certificate" .
+ ") values (" .
+ $dbh->quote($uid) . "," .
+ $dbh->quote($name) . "," .
+ $dbh->quote($password) . "," .
+ $dbh->quote($email) . "," .
+ $dbh->quote($admincert) .
+ ")";
+ $dbh->do($insert);
+ $insert = "insert into roles (" .
+ "uid" . "," .
+ "gid" .
+ ") values (" .
+ $dbh->quote($uid) . "," .
+ $dbh->quote("administrators") .
+ ")";
+ $dbh->do($insert);
+ $insert = "insert into roles (" .
+ "uid" . "," .
+ "gid" .
+ ") values (" .
+ $dbh->quote($uid) . "," .
+ $dbh->quote("agents") .
+ ")";
+ $dbh->do($insert);
+ $dbh->disconnect();
+
+ my $reqid = $response->{Requests}->{Request}->{Id};
+ $::config->put("preop.admincert.requestId.0", $reqid);
+ my $sn = $response->{Requests}->{Request}->{serialno};
+ $::config->put("preop.admincert.serialno.0", $sn);
+
+ # update email address
+ $::config->put("request.agent.create_request.1.mailTo", $email);
+ $::config->put("request.scep.create_request.1.mailTo", $email);
+ $::config->put("request.server.create_request.1.mailTo", $email);
+ $::config->put("request.user.create_request.1.mailTo", $email);
+
+ $::config->commit();
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("AdminPanel: display");
+ $::symbol{admin_uid} = "admin";
+ $::symbol{admin_name} = "RA Administrator";
+ $::symbol{admin_email} = "";
+ $::symbol{admin_pwd} = "";
+ $::symbol{admin_pwd_again} = "";
+ $::symbol{import} = "true";
+ my $domain_name = $::config->get("preop.securitydomain.name");
+ $::symbol{securityDomain} = $domain_name;
+
+ return 1;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/AgentAuthPanel.pm b/base/ra/lib/perl/PKI/RA/AgentAuthPanel.pm
new file mode 100755
index 000000000..1ada5ad54
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/AgentAuthPanel.pm
@@ -0,0 +1,86 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+
+package PKI::RA::AgentAuthPanel;
+$PKI::RA::AgentAuthPanel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(7);
+ $self->{"getName"} = &PKI::RA::Common::r("Agent Authentication");
+ $self->{"vmfile"} = "agentauthenticatepanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("AgentAuthPanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("AgentAuthPanel: update");
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("AgentAuthPanel: display");
+ return 1;
+}
+
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/BasePanel.pm b/base/ra/lib/perl/PKI/RA/BasePanel.pm
new file mode 100755
index 000000000..5cb4d7697
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/BasePanel.pm
@@ -0,0 +1,40 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+
+package PKI::RA::BasePanel;
+$PKI::RA::BasePanel::VERSION = '1.00';
+
+sub new {
+ my ($class) = @_;
+ my $self = {};
+ bless $self, $class;
+ return $self;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/CAInfoPanel.pm b/base/ra/lib/perl/PKI/RA/CAInfoPanel.pm
new file mode 100755
index 000000000..4cc65e5cf
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/CAInfoPanel.pm
@@ -0,0 +1,289 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+use URI::URL;
+
+package PKI::RA::CAInfoPanel;
+$PKI::RA::CAInfoPanel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+
+our $cert_header="-----BEGIN CERTIFICATE-----";
+our $cert_footer="-----END CERTIFICATE-----";
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(4);
+ $self->{"getName"} = &PKI::RA::Common::r("CA Information");
+ $self->{"vmfile"} = "cainfopanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("CAInfoPanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("CAInfoPanel: update");
+
+ my $count = $q->param('urls');
+ &PKI::RA::Wizard::debug_log("CAInfoPanel: update - got urls = $count");
+
+ &PKI::RA::Wizard::debug_log("CAInfoPanel: update - selected ca= $count");
+
+ my $instanceID = $::config->get("service.instanceID");
+ my $host = "";
+ my $https_ee_port = "";
+ my $https_agent_port = "";
+ my $https_admin_port = "";
+ my $domain_xml = "";
+
+ if ($count =~ /http/) {
+ my $info = new URI::URL($count);
+ $host = $info->host;
+ $https_ee_port = $info->port;
+ $domain_xml = get_domain_xml($host, $https_ee_port);
+ if ($domain_xml eq "") {
+ $::symbol{errorString} = "missing security domain. CA must be installed prior to RA installation";
+ return 0;
+ }
+
+ $https_agent_port = get_secure_agent_port_from_domain_xml($domain_xml, $host, $https_ee_port);
+ $https_admin_port = get_secure_admin_port_from_domain_xml($domain_xml, $host, $https_ee_port);
+
+ if(($https_admin_port eq "") || ($https_agent_port eq "")) {
+ $::symbol{errorString} = "missing secure CA admin or agent port. CA must be installed prior to RA installation";
+ return 0;
+ }
+ } else {
+ $host = $::config->get("preop.securitydomain.ca$count.host");
+ $https_ee_port = $::config->get("preop.securitydomain.ca$count.secureport");
+ $https_agent_port = $::config->get("preop.securitydomain.ca$count.secureagentport");
+ $https_admin_port = $::config->get("preop.securitydomain.ca$count.secureadminport");
+ }
+
+ if (($host eq "") || ($https_ee_port eq "") || ($https_admin_port eq "") || ($https_agent_port eq "")) {
+ $::symbol{errorString} = "no CA found. CA must be installed prior to RA installation";
+ return 0;
+ }
+
+ &PKI::RA::Wizard::debug_log("CAInfoPanel: update - host= $host, https_ee_port= $https_ee_port");
+
+ $::config->put("preop.cainfo.select", "https://$host:$https_admin_port");
+ my $serverCertNickName = $::config->get("preop.cert.sslserver.nickname");
+
+ my $subsystemCertNickName = $::config->get("preop.cert.subsystem.nickname");
+ $::config->put("conn.ca1.clientNickname", $subsystemCertNickName);
+ $::config->put("conn.ca1.hostport", $host . ":" . $https_ee_port);
+ $::config->put("conn.ca1.hostagentport", $host . ":" . $https_agent_port);
+ $::config->put("conn.ca1.hostadminport", $host . ":" . $https_admin_port);
+
+ $::config->commit();
+
+ # connect to the CA, and retrieve the CA certificate
+ &PKI::RA::Wizard::debug_log("CAInfoPanel: update connecting to CA and retrieve cert chain");
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $db_password =~ s/\n$//g;
+ my $tmpfile = "/tmp/ca-$$";
+ system("/usr/bin/sslget -d \"$instanceDir/alias\" -p \"$db_password\" -v -n \"$serverCertNickName\" -r \"/ca/ee/ca/getCertChain\" $host:$https_ee_port > $tmpfile");
+ my $cmd = `cat $tmpfile`;
+ system("rm $tmpfile");
+ my $caCert;
+ if ($cmd =~ /\<ChainBase64\>(.*)\<\/ChainBase64\>/) {
+ $caCert = $1;
+ &PKI::RA::Wizard::debug_log("CAInfoPanel: ca= $caCert");
+ }
+ if ($caCert eq "") {
+ &PKI::RA::Wizard::debug_log("CAInfoPanel: update no cert chain found");
+ return 0;
+ }
+ open(F, ">$instanceDir/conf/caCertChain2.txt");
+ print F $cert_header."\n".$caCert."\n".$cert_footer;
+ close(F);
+
+ &PKI::RA::Wizard::debug_log("CAInfoPanel: update retrieve cert chain done");
+
+ #import cert chain
+ system("p7tool -d $instanceDir/alias -p $instanceDir/conf/chain2cert -a -i $instanceDir/conf/caCertChain2.txt -o $instanceDir/conf/CAchain2_pp.txt");
+ my $r = $? >> 8;
+ my $failed = $? & 127;
+ if (($r > 0) && ($r < 10) && !$failed) {
+ my $i = 0;
+ while ($i ne $r) {
+ my $tmp = `certutil -d $instanceDir/alias -D -n "Trusted CA c2cert$i"`;
+ $tmp = `certutil -d $instanceDir/alias -A -f $instanceDir/conf/.pwfile -n "Trusted CA c2cert$i" -t "CT,C,C" -i $instanceDir/conf/chain2cert$i.der`;
+ $i++;
+ }
+ }
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("CAInfoPanel: display");
+
+ $::symbol{urls} = [];
+# unshift(@{$::symbol{urls}}, "External CA");
+ my $count = 0;
+ my $first = 1;
+ my $list = "";
+ while (1) {
+ my $host = $::config->get("preop.securitydomain.ca$count.host");
+ if ($host eq "") {
+ goto DONE;
+ }
+ my $https_ee_port = $::config->get("preop.securitydomain.ca$count.secureport");
+ my $name = $::config->get("preop.securitydomain.ca$count.subsystemname");
+ my $item = $name . " - https://" . $host . ":" . $https_ee_port;
+# my $item = "https://" . $host . ":" . $https_ee_port;
+# unshift(@{$::symbol{urls}}, $item);
+ $::symbol{urls}[$count++] = $item;
+ if ($first eq 1) {
+ $list = $item;
+ $first = 0;
+ } else {
+ $list = $list.",".$item;
+ }
+ }
+DONE:
+# $list = $list.",External CA";
+ $::config->put("preop.ca.list", $list);
+
+ $::symbol{urls_size} = $count;
+ if ($count eq 0) {
+ $::symbol{errorString} = "no CA found. CA, TKS, and optionally DRM must be installed prior to RA installation";
+ return 0;
+ }
+ return 1;
+}
+
+sub get_domain_xml
+{
+ my $host = $1;
+ my $https_ee_port = $2;
+
+ # get the domain xml
+ # e. g. - https://water.sfbay.redhat.com:9445/ca/admin/ca/getDomainXML
+
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+ my $instanceID = $::config->get("service.instanceID");
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $db_password =~ s/\n$//g;
+
+ my $sd_host = $::config->get("securitydomain.host");
+ my $sd_admin_port = $::config->get("securitydomain.httpsadminport");
+ my $content = `/usr/bin/sslget -d \"$instanceDir/alias\" -p \"$db_password\" -v -r \"/ca/admin/ca/getDomainXML\" $sd_host:$sd_admin_port`;
+
+ $content =~ /(\<XMLResponse\>.*\<\/XMLResponse\>)/;
+ $content = $1;
+ return $content;
+}
+
+sub get_secure_admin_port_from_domain_xml
+{
+ my $content = $1;
+ my $host = $2;
+ my $https_ee_port = $3;
+
+ # Retrieve the secure admin port corresponding
+ # to the selected host and secure ee port.
+ my $parser = XML::Simple->new();
+ my $response = $parser->XMLin($content);
+ my $xml = $parser->XMLin( $response->{'DomainInfo'},
+ ForceArray => 1 );
+ my $https_admin_port = "";
+ my $count = 0;
+ foreach my $c (@{$xml->{'CAList'}[0]->{'CA'}}) {
+ if( ( $host eq $c->{'Host'}[0] ) &&
+ ( $https_ee_port eq $c->{'SecurePort'}[0] ) ) {
+ $https_admin_port = https_$c->{'SecureAdminPort'}[0];
+ }
+
+ $count++;
+ }
+
+ return $https_admin_port;
+}
+
+sub get_secure_agent_port_from_domain_xml
+{
+ my $content = $1;
+ my $host = $2;
+ my $https_ee_port = $3;
+
+ # Retrieve the secure agent port corresponding
+ # to the selected host and secure ee port.
+ my $parser = XML::Simple->new();
+ my $response = $parser->XMLin($content);
+ my $xml = $parser->XMLin( $response->{'DomainInfo'},
+ ForceArray => 1 );
+ my $https_agent_port = "";
+ my $count = 0;
+ foreach my $c (@{$xml->{'CAList'}[0]->{'CA'}}) {
+ if( ( $host eq $c->{'Host'}[0] ) &&
+ ( $https_ee_port eq $c->{'SecurePort'}[0] ) ) {
+ $https_agent_port = https_$c->{'SecureAgentPort'}[0];
+ }
+
+ $count++;
+ }
+
+ return $https_agent_port;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/CertInfo.pm b/base/ra/lib/perl/PKI/RA/CertInfo.pm
new file mode 100755
index 000000000..d1a8c3817
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/CertInfo.pm
@@ -0,0 +1,133 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+
+package PKI::RA::CertInfo;
+$PKI::RA::CertInfo::VERSION = '1.00';
+
+sub new {
+ my ($class, $name, $dn, $tag) = @_;
+ my $self = {};
+
+ &PKI::RA::Wizard::debug_log("CertInfo: start new");
+ $self->{"getUserFriendlyName"} = \&get_user_friendly_name;
+ $self->{"getCertTag"} = \&get_cert_tag;
+ $self->{"getDN"} = \&get_dn;
+ $self->{"getNickname"} = \&get_nickname;
+ $self->{"useDefaultKey"} = \&use_default_key;
+ $self->{"getCustomKeysize"} = \&get_custom_keysize;
+ $self->{"keyOption"} = \&get_key_option;
+ &PKI::RA::Wizard::debug_log("CertInfo: end new");
+
+ $self->{name} = $name;
+ $self->{dn} = $dn;
+ $self->{tag} = $tag;
+
+ bless $self, $class;
+ return $self;
+}
+
+sub get_user_friendly_name
+{
+ my ($self) = @_;
+ &PKI::RA::Wizard::debug_log("CertInfo: get_user_friendly_name");
+ return $self->{name};
+}
+
+sub get_cert_tag
+{
+ my ($self) = @_;
+ &PKI::RA::Wizard::debug_log("CertInfo: get_cert_tag");
+ return $self->{tag};
+}
+
+sub get_dn
+{
+ my ($self) = @_;
+ &PKI::RA::Wizard::debug_log("CertInfo: get_cert_dn");
+ return $self->{dn};
+}
+
+sub use_default_key
+{
+ my ($self) = @_;
+ &PKI::RA::Wizard::debug_log("CertInfo: use_default_key");
+ my $option = $::config->get("preop.cert.$self->{tag}.keysize.select");
+ if (($option ne "") && ($option ne "default")) {
+ return 0;
+ }
+ return 1;
+}
+
+sub get_nickname
+{
+ my ($self) = @_;
+ &PKI::RA::Wizard::debug_log("CertInfo: get_nickname");
+ my $nickname = $::config->get("preop.cert.$self->{tag}.nickname");
+
+ my $flavor = "pki";
+ $flavor =~ s/\n//g;
+
+ if ($nickname ne "") {
+ return $nickname;
+ } else {
+ return $self->{tag}."cert cert-$flavor-ra";
+ }
+}
+
+sub get_key_option
+{
+ my ($self) = @_;
+ &PKI::RA::Wizard::debug_log("CertInfo: get_key_option");
+ my $option = $::config->get("preop.cert.$self->{tag}.keysize.select");
+
+ if ($option ne "") {
+ &PKI::RA::Wizard::debug_log("CertInfo: get_key_option from config = $option");
+ return $option;
+ } else {
+ &PKI::RA::Wizard::debug_log("CertInfo: get_key_option not from config");
+ return "default";
+ }
+}
+
+sub get_custom_keysize
+{
+ my ($self) = @_;
+ &PKI::RA::Wizard::debug_log("CertInfo: get_custom_keysize");
+ my $size = $::config->get("preop.cert.$self->{tag}.keysize.customsize");
+ &PKI::RA::Wizard::debug_log("CertInfo: get_custom_keysize for preop.cert.$self->{tag}.keysize.customsize is $size");
+ if ($size ne "") {
+ &PKI::RA::Wizard::debug_log("CertInfo: get_custom_keysize from config is $size");
+ return $size;
+ } else {
+ &PKI::RA::Wizard::debug_log("CertInfo: get_custom_keysize not from config");
+ return 2048;
+ }
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/CertPrettyPrintPanel.pm b/base/ra/lib/perl/PKI/RA/CertPrettyPrintPanel.pm
new file mode 100755
index 000000000..cf58d2327
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/CertPrettyPrintPanel.pm
@@ -0,0 +1,85 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+
+package PKI::RA::CertPrettyPrintPanel;
+$PKI::RA::CertPrettyPrintPanel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(13);
+ $self->{"getName"} = &PKI::RA::Common::r("Certificates");
+ $self->{"vmfile"} = "certprettyprintpanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("CertPrettyPrintPanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("CertPrettyPrintPanel: update");
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("CertPrettyPrintPanel: display");
+ return 1;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/CertRequestPanel.pm b/base/ra/lib/perl/PKI/RA/CertRequestPanel.pm
new file mode 100755
index 000000000..51eb1d400
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/CertRequestPanel.pm
@@ -0,0 +1,301 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+use PKI::RA::ReqCertInfo;
+use FileHandle;
+
+package PKI::RA::CertRequestPanel;
+$PKI::RA::CertRequestPanel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+
+our $cert_req_header="-----BEGIN NEW CERTIFICATE REQUEST-----";
+our $cert_req_footer="-----END NEW CERTIFICATE REQUEST-----";
+our $cert_header="-----BEGIN CERTIFICATE-----";
+our $cert_footer="-----END CERTIFICATE-----";
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(13);
+ $self->{"getName"} = &PKI::RA::Common::r("Certificate Requests");
+ $self->{"vmfile"} = "certrequestpanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: update");
+
+ my $i = 0;
+
+ my $instanceDir = $::config->get("service.instanceDir");
+
+ my $useExternalCA = $::config->get("preop.certenroll.useExternalCA");
+ if ($useExternalCA eq "on") {
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: update: useExternalCA is on");
+ } else {
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: update: useExternalCA is off");
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: update auto enrollment should have been done, no more action needed");
+ return 1;
+ }
+
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: update External CA selected, retrieve/process user input");
+
+ my $tokenname = $::config->get("preop.module.token");
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: update got token name = $tokenname");
+ my $token_pwd = $::pwdconf->get($tokenname);
+ $token_pwd =~ s/\n//g;
+ open FILE, ">$instanceDir/conf/.pwfile";
+ system( "chmod 00660 $instanceDir/conf/.pwfile" );
+ print FILE $token_pwd;
+ close FILE;
+
+ my $hw;
+ my $tk;
+
+ if (($tokenname eq "") || ($tokenname eq "NSS Certificate DB")) {
+ $hw = "";
+ $tk = "";
+ } else {
+ $hw = "-h $tokenname";
+ $tk = $tokenname.":";
+ }
+
+ foreach my $certtag (@PKI::RA::Wizard::certtags) {
+ if ($certtag eq "subsystem") {
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: update: subsystem cert is pre-generated by the security domain");
+ return 1;
+ }
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: update: for certag= $certtag");
+ my $ccert = $::config->get("preop.cert.$certtag.cert");
+ if ($ccert ne "") {
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: update: cert already exists in CS.cfg, go to next");
+ next;
+ }
+ my $certchain = $q->param($certtag.'_cc');
+ if ($certchain ne "") {
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: update: $certtag certchain is $certchain");
+ my $cc_fn = "$instanceDir/conf/caCertChain.txt";
+ my $tmp = `echo "$certchain" > $cc_fn`;
+ # remove existing one
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: update: try to delete existing certchain, if any....ok if it fails");
+# XXX remove should not be done lightly...
+ $tmp = `p7tool -d $instanceDir/alias -p $instanceDir/conf/chain1cert -a -i $cc_fn -o $instanceDir/conf/CAchain_pp.txt`;
+ my $r = $? >> 8;
+ my $failed = $? & 127;
+ if (($r > 0) && ($r < 10) && !$failed) {
+ my $i = 0;
+ while ($i ne $r) {
+ $tmp = `certutil -d $instanceDir/alias -D -n "Trusted CA $certtag cert$i"`;
+ $tmp = `certutil -d $instanceDir/alias -A -f $instanceDir/conf/.pwfile -n "Trusted CA $certtag cert$i" -t "CT,C,C" -i $instanceDir/conf/chain1cert$i.der`;
+# $tmp = `rm $cc_fn`;
+ $i++
+ }
+ }
+ } else {
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: update: no certchain included for certtag $certtag");
+ }
+
+ my $cert = $q->param($certtag);
+ if ($cert ne "") {
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: update: $certtag cert is $cert");
+ my $nickname = $::config->get("preop.cert.$certtag.nickname");
+ if ($nickname eq "") {
+ $nickname = "RA ".$certtag." cert";
+ $::config->put("preop.cert.$certtag.nickname", $nickname);
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: update: $certtag cert nickname not found in CS.cfg, generating one= $nickname");
+ }
+ #remove existing one
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: update: try to delete existing cert $nickname, if any....ok if it fails");
+#XXX remove should not be done lightly...
+ my $tmp = `certutil -d $instanceDir/alias -D -n "$nickname"`;
+ $tmp = `certutil -d $instanceDir/alias -D $hw -f $instanceDir/conf/.pwfile -n "$tk$nickname"`;
+ #now import the cert
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: update: try to import cert");
+ my $cert_fn = "$instanceDir/conf/$certtag"."_cert.txt";
+ $tmp = `echo "$cert" > $cert_fn`;
+
+# $cert = extract_cert_from_file_sans_header_and_footer($cert_fn);
+ my $certa ="";
+ my $save_line = 0;
+ my @cert_a = split "\n", $cert;
+ foreach my $line (@cert_a) {
+ chomp( $line );
+ $line =~ s/\r//g;
+ if ($line eq $cert_header) {
+ $save_line = 1;
+ } elsif( $line eq $cert_footer ) {
+ $save_line = 0;
+ last;
+ } elsif( $save_line == 1 ) {
+ $certa .= "$line";
+ }
+ }
+
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: update putting cert in CS.cfg: $certa");
+
+ $::config->put("preop.cert.$certtag.cert", $certa);
+
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: update: about to certutil -d $instanceDir/alias $hw -A -f $instanceDir/conf/.pwfile -n $nickname -t u,u,u -a -i $cert_fn");
+ $tmp = `certutil -d $instanceDir/alias $hw -A -f $instanceDir/conf/.pwfile -n "$nickname" -t "u,u,u" -a -i $cert_fn`;
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: update: done certutil: $tmp");
+ $tmp = `rm $cert_fn`;
+
+ # changed the cert, need to change nickname too, if necessary
+ if ($hw ne "") {
+ $::config->put("preop.cert.$certtag.nickname", "$tk$nickname");
+ if ($certtag eq "subsystem") {
+ $::config->put("conn.ca1.clientNickname","$tk$nickname");
+ $::config->put("conn.drm1.clientNickname","$tk$nickname");
+ $::config->put("conn.tks1.clientNickname","$tk$nickname");
+ }
+ }
+
+ } else {
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: update: no cert");
+ }
+ }
+
+DONE:
+ $::config->commit();
+ my $tmp = `rm $instanceDir/conf/.pwfile`;
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("CertRequestPanel: display");
+
+ my $domain_name = $::config->get("preop.securitydomain.name");
+ if ($domain_name eq "") {
+ $domain_name = "RA Domain";
+ }
+ my $machine_name = $::config->get("service.machineName");
+ my $instance_id = $::config->get("service.instanceID");
+
+ my $i = 0;
+ foreach my $certtag (@PKI::RA::Wizard::certtags) {
+ my $cert_dn = $::config->get("preop.cert.".$certtag.".dn");
+ if ($cert_dn eq "") {
+ if ($certtag eq "subsystem") {
+ $cert_dn = "CN=RA Subsystem, " .
+ "OU=" . $instance_id . ", " .
+ "O=" . $domain_name;
+ } elsif ($certtag eq "sslserver") {
+ $cert_dn ="CN=" . $machine_name . ", " .
+ "OU=" . $instance_id . ", " .
+ "O=" . $domain_name;
+ } else {
+ $cert_dn = $certtag;
+ }
+ }
+
+ my $name = $::config->get("preop.cert.".$certtag.".userfriendlyname");
+ if ($name eq "") {
+ $name = $certtag."Cert ".$instance_id;
+ }
+
+ my $reqcert = new PKI::RA::ReqCertInfo($name,
+ $cert_dn, $certtag);
+ $::symbol{reqscerts}[$i++] = $reqcert;
+ }
+
+ $::symbol{errorString} = "";
+ $::symbol{showApplyButton} = "true";
+
+ return 1;
+}
+
+# arg0 message containing certificate
+# return certificate sans header and footer
+# -- all in a one-liner
+sub extract_cert_from_file_sans_header_and_footer
+{
+ my $filename = $_[0];
+ my $save_line = 0;
+
+ my $fd = new FileHandle;
+
+ my $cert = "";
+
+ $fd->open( "<$filename" ) or die "Could not open '$filename'!\n";
+
+ while( <$fd> )
+ {
+ my $line = $_;
+ chomp( $line );
+ $line =~ s/^M//g;
+
+ if( $line eq $cert_header ) {
+ $save_line = 1;
+ } elsif( $line eq $cert_footer ) {
+ $save_line = 0;
+ last;
+ } elsif( $save_line == 1 ) {
+ $cert .= "$line";
+ }
+ }
+
+ $fd->close();
+
+ return $cert;
+}
+
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/Common.pm b/base/ra/lib/perl/PKI/RA/Common.pm
new file mode 100755
index 000000000..8deab8c6c
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/Common.pm
@@ -0,0 +1,50 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package PKI::RA::Common;
+
+use strict;
+use warnings;
+use Exporter;
+
+use vars qw(@ISA @EXPORT @EXPORT_OK);
+@ISA = qw(Exporter Autoloader);
+@EXPORT = qw(r yes no);
+
+$PKI::RA::Common::VERSION = '1.00';
+
+sub yes {
+ return sub {1};
+}
+
+sub no {
+ return sub {0};
+}
+
+sub r {
+ my $a = shift;
+ return sub { $a; }
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/Config.pm b/base/ra/lib/perl/PKI/RA/Config.pm
new file mode 100755
index 000000000..f1ace5b03
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/Config.pm
@@ -0,0 +1,170 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package PKI::RA::Config;
+
+use strict;
+use warnings;
+use Exporter;
+
+$PKI::RA::Config::VERSION = '1.00';
+
+#######################################################
+# Configuration Store
+#######################################################
+sub new {
+ my $class = shift;
+ my $self = {};
+ my %hash = ();
+ $self->{filename} = "";
+ $self->{hash} = \%hash;
+ bless $self,$class;
+ return $self;
+}
+
+sub load_file
+{
+ my ($self, $filename) = @_;
+
+ $self->{filename} = $filename;
+ if (-e $filename) {
+ open(CF, "<$filename");
+ if (defined fileno CF) {
+ while (<CF>) {
+ if (/^#/) {
+ # comments
+ } elsif (/([^=]+)=(.*)$/) {
+ # print "$1 = $2\n";
+ $self->{hash}{$1} = $2;
+ } else {
+ # preserve comments
+ }
+ }
+ }
+ close(CF);
+ }
+}
+
+sub get_filename
+{
+ my ($self) = @_;
+ return $self->{filename};
+}
+
+sub get
+{
+ my ($self, $n) = @_;
+ return $self->{hash}{$n};
+}
+
+sub put
+{
+ my ($self, $n, $v) = @_;
+ $self->{hash}{$n} = $v;
+}
+
+sub deleteSubstore
+{
+ my ($self, $n) = @_;
+ foreach my $xkey (keys %{$self->{hash}}) {
+ if ($xkey =~ /^\Q$n\E/) {
+ delete $self->{hash}{$xkey};
+ }
+ }
+}
+
+sub commit
+{
+ my ($self) = @_;
+
+ # write stuff back to the file
+# print $self->{filename} . "\n";
+ my $hash = $self->{hash};
+ my $suffix = time();
+
+ if (-e $self->{filename}) {
+ # Create a copy of the original file which
+ # preserves the original file permissions
+ system("cp -p \"" . $self->{filename} . "\" \"" .
+ $self->{filename} . "." . $suffix . "\"");
+ }
+
+ # Overwrite the contents of the original file
+ # to preserve the original file permissions
+ open(F, ">" . $self->{filename});
+ foreach my $k (sort keys %{$hash}) {
+ print F "$k=$self->{hash}{$k}\n";
+ }
+ close(F);
+
+ if (-e $self->{filename} . "." . $suffix) {
+ system("rm \"" . $self->{filename} . "." . $suffix . "\"");
+ }
+}
+
+sub commit_with_backup
+{
+ my ($self) = @_;
+
+ # write stuff back to the file
+# print $self->{filename} . "\n";
+ my $hash = $self->{hash};
+ my $suffix = time();
+ # Create a copy of the original file which
+ # preserves the original file permissions
+ system("cp -p \"" . $self->{filename} . "\" \"" .
+ $self->{filename} . "." . $suffix . "\"");
+
+ # Overwrite the contents of the original file
+ # to preserve the original file permissions
+ open(F, ">" . $self->{filename});
+ foreach my $k (sort keys %{$hash}) {
+ print F "$k=$self->{hash}{$k}\n";
+ }
+ close(F);
+}
+
+1;
+
+#######################################################
+# Test Program
+#######################################################
+#my $config = PKI::RA::Config->new();
+#$config->load_file("/tmp/CS.cfg");
+#print $config->get("tokendb.indexAdminTemplate") . "\n";
+#$config->put("tokendb.indexAdminTemplate", "Testing");
+#print $config->get("tokendb.indexAdminTemplate") . "\n";
+#$config->commit();
+
+1;
+
+#######################################################
+# Test Program
+#######################################################
+#my $config = PKI::RA::Config->new();
+#$config->load_file("/tmp/CS.cfg");
+#print $config->get("tokendb.indexAdminTemplate") . "\n";
+#$config->put("tokendb.indexAdminTemplate", "Testing");
+#print $config->get("tokendb.indexAdminTemplate") . "\n";
+#$config->commit();
diff --git a/base/ra/lib/perl/PKI/RA/ConfigHSMLoginPanel.pm b/base/ra/lib/perl/PKI/RA/ConfigHSMLoginPanel.pm
new file mode 100755
index 000000000..bf74890cc
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/ConfigHSMLoginPanel.pm
@@ -0,0 +1,104 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+
+package PKI::RA::ConfigHSMLoginPanel;
+$PKI::RA::ConfigHSMLoginPanel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(9);
+ $self->{"getName"} = &PKI::RA::Common::r("Security Modules Login");
+ $self->{"vmfile"} = "config_hsmloginpanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 1;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("ConfigHSMLoginPanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("ConfigHSMLoginPanel: update");
+ my $uTokName = $q->param('uTokName');
+ my $uPasswd = $q->param('__uPasswd');
+
+# &PKI::RA::Wizard::debug_log("ConfigHSMLoginPanel: update tokname= $uTokName pwd =$uPasswd");
+
+ $::pwdconf->put($uTokName, $uPasswd);
+ $::pwdconf->commit();
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ use Data::Dumper;
+ $Data::Dumper::Indent = 1;
+# &PKI::RA::Wizard::debug_log("ConfigHSMLoginPanel -> dump of q= ". Dumper($q));
+ $::symbol{SecToken} = $q->param('SecToken');
+# &PKI::RA::Wizard::debug_log("ConfigHSMLoginPanel -> display has ".$q->param('SecToken'));
+
+ &PKI::RA::Wizard::debug_log("ConfigHSMLoginPanel -> display retrieving $q->param('SecToken') ");
+ my $pwd = $::pwdconf->get( $q->param('SecToken'));
+ if ($pwd ne "") {
+ &PKI::RA::Wizard::debug_log("ConfigHSMLoginPanel -> display retrieved pwd from pwdconf");
+ }
+
+ return 1;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/ConfigHSMPanel.pm b/base/ra/lib/perl/PKI/RA/ConfigHSMPanel.pm
new file mode 100755
index 000000000..095ed5879
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/ConfigHSMPanel.pm
@@ -0,0 +1,72 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+
+package PKI::RA::ConfigHSMPanel;
+$PKI::RA::ConfigHSMPanel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&PKI::RA::Common::no;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(12);
+ $self->{"getName"} = &PKI::RA::Common::r("ConfigHSMLogin");
+ $self->{"vmfile"} = "config_hsm.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("ConfigHSMPanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("ConfigHSMPanel: update");
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("ConfigHSMPanel: display");
+ return 1;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/DRMInfoPanel.pm b/base/ra/lib/perl/PKI/RA/DRMInfoPanel.pm
new file mode 100755
index 000000000..fadd7727c
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/DRMInfoPanel.pm
@@ -0,0 +1,140 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+use URI::URL;
+
+package PKI::RA::DRMInfoPanel;
+$PKI::RA::DRMInfoPanel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(6);
+ $self->{"getName"} = &PKI::RA::Common::r("DRM Information");
+ $self->{"vmfile"} = "drminfopanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("DRMInfoPanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("DRMInfoPanel: update");
+
+ my $choice = $q->param('choice');
+ $::config->put("preop.krainfo.keygen", $choice);
+
+ if ($choice eq "keygen") {
+ my $count = $q->param('urls');
+ my $instanceID = $::config->get("service.instanceID");
+ my $host = "";
+ my $https_agent_port = "";
+ if ($count =~ /http/) {
+ my $info = new URI::URL($count);
+ $host = $info->host;
+ $https_agent_port = $info->port;
+ } else {
+ $host = $::config->get("preop.securitydomain.kra$count.host");
+ $https_agent_port = $::config->get("preop.securitydomain.kra$count.secureagentport");
+ }
+ if (($host eq "") || ($https_agent_port eq "")) {
+ $::symbol{errorString} = "no DRM found. CA, TKS and DRM must be installed prior to RA installation";
+ return 0;
+ }
+
+ $::config->put("preop.krainfo.select", "https://$host:$https_agent_port");
+ my $subsystemCertNickName = $::config->get("preop.cert.subsystem.nickname");
+ $::config->put("conn.drm1.clientNickname", $subsystemCertNickName);
+ $::config->put("conn.drm1.hostport", $host . ":" . $https_agent_port);
+ $::config->put("conn.tks1.serverKeygen", "true");
+ $::config->put("op.enroll.userKey.keyGen.encryption.serverKeygen.enable", "true");
+ $::config->put("op.enroll.userKeyTemporary.keyGen.encryption.serverKeygen.enable", "true");
+ } else {
+ # no keygen
+ $::config->put("conn.tks1.serverKeygen", "false");
+ $::config->put("op.enroll.userKey.keyGen.encryption.serverKeygen.enable", "false");
+ $::config->put("op.enroll.userKeyTemporary.keyGen.encryption.serverKeygen.enable", "false");
+ $::config->put("conn.drm1.clientNickname", "");
+ $::config->put("conn.drm1.hostport", "");
+ }
+ $::config->commit();
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("DRMInfoPanel: display");
+
+ $::symbol{urls} = [];
+ my $count = 0;
+ while (1) {
+ my $host = $::config->get("preop.securitydomain.kra$count.host");
+ if ($host eq "") {
+ goto DONE;
+ }
+ my $https_agent_port = $::config->get("preop.securitydomain.kra$count.secureagentport");
+ my $name = $::config->get("preop.securitydomain.kra$count.subsystemname");
+ $::symbol{urls}[$count++] = $name . " - https://" . $host . ":" . $https_agent_port;
+ }
+DONE:
+ $::symbol{urls_size} = $count;
+
+ return 1;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/DatabasePanel.pm b/base/ra/lib/perl/PKI/RA/DatabasePanel.pm
new file mode 100755
index 000000000..e469e51f8
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/DatabasePanel.pm
@@ -0,0 +1,109 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+
+use DBI;
+package PKI::RA::DatabasePanel;
+$PKI::RA::DatabasePanel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(8);
+ $self->{"getName"} = &PKI::RA::Common::r("Internal Database");
+ $self->{"vmfile"} = "databasepanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("DatabasePanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("DatabasePanel: update");
+ my $instDir = $::config->get("service.instanceDir");
+
+ # create local database
+ my $dbh = DBI->connect(
+ "dbi:SQLite:dbname=$instDir/conf/dbfile","","");
+
+ # create database lockfile
+ system("touch $instDir/conf/dblock");
+
+ open(F, "/usr/share/pki/ra/scripts/schema.sql");
+ while (<F>) {
+ if (!($_ =~ /^#/)) {
+ $dbh->do($_);
+ }
+ }
+ close(F);
+
+ $dbh->disconnect();
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("DatabasePanel: display");
+
+ my $machineName = $::config->get("service.machineName");
+ my $instanceId = $::config->get("service.instanceID");
+
+ return 1;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/DisplayCertChain2Panel.pm b/base/ra/lib/perl/PKI/RA/DisplayCertChain2Panel.pm
new file mode 100755
index 000000000..46c8a2902
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/DisplayCertChain2Panel.pm
@@ -0,0 +1,179 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+use FileHandle;
+
+package PKI::RA::DisplayCertChain2Panel;
+$PKI::RA::DisplayCertChain2Panel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+
+our $cert_header="-----BEGIN CERTIFICATE-----";
+our $cert_footer="-----END CERTIFICATE-----";
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(7);
+ $self->{"getName"} = &PKI::RA::Common::r("Display Certificate Chain");
+ $self->{"vmfile"} = "displaycertchain2panel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub readFile
+{
+ my $fn = $_[0];
+ open FILE, "< $fn" or return "";
+ my $content = join "",<FILE>;
+ close FILE;
+
+ return $content;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("DisplayCertChain2Panel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("DisplayCertChain2Panel: update");
+
+ my $instanceDir = $::config->get("service.instanceDir");
+
+# my $caCert = readFile("$instanceDir/conf/caCertChain2.txt");
+ my $caCert = extract_cert_from_file_sans_header_and_footer("$instanceDir/conf/caCertChain2.txt");
+
+ #store in config
+ $::config->put("preop.ca.certchain", $caCert);
+ $::config->commit();
+ # import it into the security database
+ my $tmp = `p7tool -d $instanceDir/alias -p $instanceDir/conf/chain2cert -a -i $instanceDir/conf/caCertChain2.txt -o $instanceDir/conf/CAchain2_pp.txt`;
+ my $r = $? >> 8;
+ my $failed = $? & 127;
+ if (($r > 0) && ($r < 10) && !$failed) {
+ my $i = 0;
+ while ($i ne $r) {
+ $tmp = `certutil -d $instanceDir/alias -D -n "Trusted CA c2cert$i"`;
+ $tmp = `certutil -d $instanceDir/alias -A -f $instanceDir/conf/.pwfile -n "Trusted CA c2cert$i" -t "CT,C,C" -i $instanceDir/conf/chain2cert$i.der`;
+ $i++
+ }
+ }
+
+ # clean up
+# my $tmp = `rm $instanceDir/conf/caCertChain2.txt`;
+# $tmp = `rm $instanceDir/conf/CAchain2_pp.txt`;
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("DisplayCertChain2Panel: display");
+ my $instanceDir = $::config->get("service.instanceDir");
+
+ my $found = -e "$instanceDir/conf/caCertChain2.txt";
+ my $certpp = "";
+ if ($found) {
+ &PKI::RA::Wizard::debug_log("DisplayCertChain2Panel: display found caCertChain2.txt");
+ my $tmp = `p7tool -d $instanceDir/alias -p $instanceDir/conf/chain2cert -a -i $instanceDir/conf/caCertChain2.txt -o $instanceDir/conf/CAchain2_pp.txt`;
+
+ $certpp = readFile("$instanceDir/conf/CAchain2_pp.txt");
+ &PKI::RA::Wizard::debug_log("DisplayCertChain2Panel: display read CAchain2_pp.txt");
+ $certpp =~ s/"//g;
+ &PKI::RA::Wizard::debug_log("DisplayCertChain2Panel: certpp2= $certpp");
+ }
+
+# $symbol{certchain} = [ "cert1", "cert2" ];
+# $symbol{certchain_size} = 2;
+ $::symbol{certchain} = "$certpp";
+ $::symbol{certchain_size} = 1;
+
+ &PKI::RA::Wizard::debug_log("DisplayCertChain2Panel: display done");
+ return 1;
+}
+
+# return certificate sans header and footer
+# -- all in a one-liner
+sub extract_cert_from_file_sans_header_and_footer
+{
+ my $filename = $_[0];
+ my $save_line = 0;
+
+ my $fd = new FileHandle;
+
+ my $cert = "";
+
+ $fd->open( "<$filename" ) or die "Could not open '$filename'!\n";
+
+ while( <$fd> )
+ {
+ my $line = $_;
+ chomp( $line );
+ $line =~ s/^M//g;
+
+ if( $line eq $cert_header ) {
+ $save_line = 1;
+ } elsif( $line eq $cert_footer ) {
+ $save_line = 0;
+ last;
+ } elsif( $save_line == 1 ) {
+ $cert .= "$line";
+ }
+ }
+
+ $fd->close();
+
+ return $cert;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/DisplayCertChainPanel.pm b/base/ra/lib/perl/PKI/RA/DisplayCertChainPanel.pm
new file mode 100755
index 000000000..dd991a917
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/DisplayCertChainPanel.pm
@@ -0,0 +1,348 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+use URI::URL;
+use MIME::Base64;
+
+package PKI::RA::DisplayCertChainPanel;
+$PKI::RA::DisplayCertChainPanel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(2);
+ $self->{"getName"} = &PKI::RA::Common::r("Display Certificate Chain");
+ $self->{"vmfile"} = "displaycertchainpanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 1;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("DisplayCertChainPanel: validate");
+ return 1;
+}
+
+sub readFile
+{
+ my $fn = $_[0];
+ open FILE, "< $fn" or return "";
+ my $content = join "",<FILE>;
+ close FILE;
+
+ return $content;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("DisplayCertChainPanel: update");
+
+ my $instanceDir = $::config->get("service.instanceDir");
+
+ my $caCert = readFile("$instanceDir/conf/caCert.txt");
+
+ #store in config
+ $::config->put("preop.ca.certchain", $caCert);
+ $::config->commit();
+
+ # import it into the security database
+# my $cmd1 = `/usr/bin/AtoB $instanceDir/conf/caCert.txt $instanceDir/conf/caCert.der`;
+ my $cmd2 = `/usr/bin/certutil -A -d \"$instanceDir/alias\" -t \"CT,CT,CT\" -n \"caCert\" -i $instanceDir/conf/caCert.der`;
+
+ # clean up
+ my $tmp = `rm $instanceDir/conf/caCert.txt`;
+ $tmp = `rm $instanceDir/conf/caCert.der`;
+ $tmp = `rm $instanceDir/conf/caCert_pp.txt`;
+
+ # complete the SecurityDomain task
+ my $sdomainAdminURL = $::config->get("config.sdomainAdminURL");
+ if ($sdomainAdminURL eq "") {
+ return 2;
+ }
+
+ my $machineName = $::config->get("service.machineName");
+ my $non_clientauth_securePort = $::config->get("service.non_clientauth_securePort");
+ my $unsecurePort = $::config->get("service.unsecurePort");
+
+ # check if url is accessible
+ # redirect to the security domain authentication
+ if ($ENV{'SERVER_PORT'} eq $unsecurePort) {
+ $::symbol{redirect} = $sdomainAdminURL . "/ca/admin/ca/securityDomainLogin?url=http%3A%2F%2F" . $machineName . "%3A" . $unsecurePort . "%2Fra%2Fadmin%2Fconsole%2Fconfig%2Fwizard%3Fp%3D3%26subsystem%3DRA";
+ } else {
+ $::symbol{redirect} = $sdomainAdminURL . "/ca/admin/ca/securityDomainLogin?url=https%3A%2F%2F" . $machineName . "%3A" . $non_clientauth_securePort . "%2Fra%2Fadmin%2Fconsole%2Fconfig%2Fwizard%3Fp%3D3%26subsystem%3DRA";
+ }
+
+ get_domain_xml($sdomainAdminURL);
+
+
+ return 3;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("DisplayCertChainPanel: display");
+
+ # connect to the CA, and retrieve the CA certificate
+ &PKI::RA::Wizard::debug_log("DisplayCertChainPanel: update connecting to CA and retrieve cert chain");
+ my $instanceID = $::config->get("service.instanceID");
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $sdomainAdminURL = $::config->get("config.sdomainAdminURL");
+ if ($sdomainAdminURL eq "") {
+ return 2;
+ }
+
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $db_password =~ s/\n$//g;
+
+ my $url_info = new URI::URL($sdomainAdminURL);
+ my $sd_host = $url_info->host;
+ my $sd_admin_port = $url_info->port;
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+ my $cmd = `/usr/bin/sslget -d \"$instanceDir/alias\" -p \"$db_password\" -v -r \"/ca/admin/ca/getCertChain\" $sd_host:$sd_admin_port`;
+
+ my $caCert = "";
+ if ($cmd =~ /\<ChainBase64\>(.*)\<\/ChainBase64\>/) {
+ $caCert = $1;
+ &PKI::RA::Wizard::debug_log("DisplayCertChainPanel: ca= $caCert");
+ }
+
+ my $certpp = "";
+ if ($caCert ne "") {
+ open(F, ">$instanceDir/conf/caCert.txt");
+ print F $caCert;
+ close(F);
+
+ # test to see if tmp directory exists, if not, create
+ my $found = -e "$instanceDir/conf/tmp";
+ if (! $found) {
+ my $tmp = `mkdir $instanceDir/conf/tmp`;
+ }
+
+ # import it into a temporary security database
+# my $cmd1 = `/usr/bin/AtoB $instanceDir/conf/caCert.txt $instanceDir/conf/caCert.der`;
+ # my $cmd1 = `/usr/bin/openssl base64 -d -A -in $instanceDir/conf/caCert.txt -out $instanceDir/conf/caCert.der`;
+
+ my $txt = `cat $instanceDir/conf/caCert.txt`;
+ open(OUT, ">$instanceDir/conf/caCert.der");
+ print OUT MIME::Base64::decode($txt);
+ close(OUT);
+
+ my $cmd2 = `/usr/bin/certutil -A -d \"$instanceDir/conf/tmp\" -t \"CT,CT,CT\" -n \"caCert\" -i $instanceDir/conf/caCert.der`;
+
+ # get pretty print from temp db
+ my $tmp = `certutil -d $instanceDir/conf/tmp -n "caCert" -L > $instanceDir/conf/caCert_pp.txt`;
+ $certpp = readFile("$instanceDir/conf/caCert_pp.txt");
+ $certpp =~ s/"//g;
+ &PKI::RA::Wizard::debug_log("DisplayCertChainPanel: certpp= $certpp");
+ # clean up temp db
+ $tmp = `certutil -d $instanceDir/alias/tmp -D -n "caCert"`;
+ } else {
+ &PKI::RA::Wizard::debug_log("DisplayCertChainPanel: update no certchain found");
+ }
+
+ &PKI::RA::Wizard::debug_log("DisplayCertChainPanel: display certchain=$caCert");
+
+# $symbol{certchain} = [ "cert1", "cert2" ];
+# $symbol{certchain_size} = 2;
+ $::symbol{certchain} = "$certpp";
+# This certchain_size does not matter
+ $::symbol{certchain_size} = 1;
+
+ return 1;
+}
+
+sub get_domain_xml
+{
+ my ($sdomainAdminURL) = @_;
+
+ my $sdom_info = new URI::URL($sdomainAdminURL);
+ # get the domain xml
+ # e. g. - https://water.sfbay.redhat.com:9445/ca/admin/ca/getDomainXML
+
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+ my $instanceID = $::config->get("service.instanceID");
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $db_password =~ s/\n$//g;
+
+ my $sd_host = $sdom_info->host;
+ my $sd_admin_port = $sdom_info->port;
+ my $content = `/usr/bin/sslget -d \"$instanceDir/alias\" -p \"$db_password\" -v -r \"/ca/admin/ca/getDomainXML\" $sd_host:$sd_admin_port`;
+
+ $content =~ /(\<XMLResponse\>.*\<\/XMLResponse\>)/;
+ $content = $1;
+
+ &PKI::RA::Wizard::debug_log("content = " . $content);
+
+ my $parser = XML::Simple->new();
+ my $response = $parser->XMLin($content);
+ my $xml = $parser->XMLin($response->{'DomainInfo'},
+ ForceArray => 1);
+
+ &PKI::RA::Wizard::debug_log("DisplayCertChainPanel: security domain '" .
+ $xml->{'Name'}[0] . "'");
+ $::config->put("preop.securitydomain.name", $xml->{'Name'}[0]);
+ $::config->put("securitydomain.name", $xml->{'Name'}[0]);
+
+ # parse xml and store information in CS.cfg
+ my $count = 0;
+ $count = 0;
+ foreach my $c (@{$xml->{'CAList'}[0]->{'CA'}}) {
+ &PKI::RA::Wizard::debug_log("DisplayCertChainPanel: Found CA '" .
+ $c->{'SubsystemName'}[0] . "'");
+ $::config->put("preop.securitydomain.ca" . $count . ".subsystemname",
+ $c->{'SubsystemName'}[0]);
+ $::config->put("preop.securitydomain.ca" . $count . ".secureport",
+ $c->{'SecurePort'}[0]);
+ $::config->put("preop.securitydomain.ca" . $count . ".secureagentport",
+ $c->{'SecureAgentPort'}[0]);
+ $::config->put("preop.securitydomain.ca" . $count . ".secureadminport",
+ $c->{'SecureAdminPort'}[0]);
+ $::config->put("preop.securitydomain.ca" . $count . ".unsecureport",
+ $c->{'UnSecurePort'}[0]);
+ $::config->put("preop.securitydomain.ca" . $count . ".host",
+ $c->{'Host'}[0]);
+
+ # The user previously specified the CA Security Domain's
+ # SSL Admin URL in the "Security Domain Panel";
+ # now retrieve this specified CA Security Domain's
+ # non-SSL EE, SSL Agent, and SSL EE URLs:
+ if( $sd_admin_port eq $c->{'SecureAdminPort'}[0] ) {
+ # Build the URLs
+ my $http_ee_port = "https://"
+ . $c->{'Host'}[0]
+ . ":"
+ . $c->{'UnSecurePort'}[0];
+ my $https_agent_port = "https://"
+ . $c->{'Host'}[0]
+ . ":"
+ . $c->{'SecureAgentPort'}[0];
+ my $https_ee_port = "https://"
+ . $c->{'Host'}[0]
+ . ":"
+ . $c->{'SecurePort'}[0];
+
+ # Store the URLs
+ $::config->put( "config.sdomainHttpURL", $http_ee_port );
+ $::config->put( "config.sdomainAgentURL", $https_agent_port );
+ $::config->put( "config.sdomainEEURL", $https_ee_port );
+
+ # Store additional values necessary for 'pkiremove' . . .
+ $::config->put( "securitydomain.httpport",
+ $c->{'UnSecurePort'}[0] );
+ $::config->put( "securitydomain.httpsagentport",
+ $c->{'SecureAgentPort'}[0] );
+ $::config->put( "securitydomain.httpseeport",
+ $c->{'SecurePort'}[0] );
+ }
+
+ $count++;
+ }
+
+ $count = 0;
+ foreach my $c (@{$xml->{'TKSList'}[0]->{'TKS'}}) {
+ &PKI::RA::Wizard::debug_log("DisplayCertChainPanel: Found TKS '" .
+ $c->{'SubsystemName'}[0] . "'");
+ $::config->put("preop.securitydomain.tks" . $count . ".subsystemname",
+ $c->{'SubsystemName'}[0]);
+ $::config->put("preop.securitydomain.tks" . $count . ".secureport",
+ $c->{'SecurePort'}[0]);
+ $::config->put("preop.securitydomain.tks" . $count . ".secureagentport",
+ $c->{'SecureAgentPort'}[0]);
+ $::config->put("preop.securitydomain.tks" . $count . ".secureadminport",
+ $c->{'SecureAdminPort'}[0]);
+ $::config->put("preop.securitydomain.tks" . $count . ".unsecureport",
+ $c->{'UnSecurePort'}[0]);
+ $::config->put("preop.securitydomain.tks" . $count . ".host",
+ $c->{'Host'}[0]);
+ $count++;
+ }
+
+ $count = 0;
+ foreach my $c (@{$xml->{'KRAList'}[0]->{'KRA'}}) {
+ &PKI::RA::Wizard::debug_log("DisplayCertChainPanel: Found KRA '" .
+ $c->{'SubsystemName'}[0] . "'");
+ $::config->put("preop.securitydomain.kra" . $count . ".subsystemname",
+ $c->{'SubsystemName'}[0]);
+ $::config->put("preop.securitydomain.kra" . $count . ".secureport",
+ $c->{'SecurePort'}[0]);
+ $::config->put("preop.securitydomain.kra" . $count . ".secureagentport",
+ $c->{'SecureAgentPort'}[0]);
+ $::config->put("preop.securitydomain.kra" . $count . ".secureadminport",
+ $c->{'SecureAdminPort'}[0]);
+ $::config->put("preop.securitydomain.kra" . $count . ".unsecureport",
+ $c->{'UnSecurePort'}[0]);
+ $::config->put("preop.securitydomain.kra" . $count . ".host",
+ $c->{'Host'}[0]);
+ $count++;
+ }
+
+ $count = 0;
+ foreach my $c (@{$xml->{'RAList'}[0]->{'RA'}}) {
+ &PKI::RA::Wizard::debug_log("DisplayCertChainPanel: Found RA '" .
+ $c->{'SubsystemName'}[0] . "'");
+ $::config->put("preop.securitydomain.ra" . $count . ".subsystemname",
+ $c->{'SubsystemName'}[0]);
+ $::config->put("preop.securitydomain.ra" . $count . ".secureport",
+ $c->{'SecureAgentPort'}[0]);
+ $::config->put("preop.securitydomain.ra" . $count . ".non_clientauth_secure_port",
+ $c->{'SecurePort'}[0]);
+ $::config->put("preop.securitydomain.ra" . $count . ".unsecureport",
+ $c->{'UnSecurePort'}[0]);
+ $::config->put("preop.securitydomain.ra" . $count . ".host",
+ $c->{'Host'}[0]);
+ $count++;
+ }
+ $::config->commit();
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/DonePanel.pm b/base/ra/lib/perl/PKI/RA/DonePanel.pm
new file mode 100755
index 000000000..4a32a8270
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/DonePanel.pm
@@ -0,0 +1,399 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+use URI::URL;
+use XML::Simple;
+
+package PKI::RA::DonePanel;
+$PKI::RA::DonePanel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(16);
+ $self->{"getName"} = &PKI::RA::Common::r("Done");
+ $self->{"vmfile"} = "donepanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("DonePanel: validate");
+ return 1;
+}
+sub update
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("DonePanel: update");
+ return 1;
+}
+
+sub register_ra
+{
+ my ($sdom, $url, $uri, $xname) = @_;
+
+ &PKI::RA::Wizard::debug_log("DonePanel: register_ra at $url");
+ &PKI::RA::Wizard::debug_log("DonePanel: subsystem $xname uri=$uri");
+
+ my $url_info = new URI::URL($url);
+ my $sdom_info = new URI::URL($sdom);
+
+ # register RA to Security Domain
+ # submit request to CA
+ &PKI::RA::Wizard::debug_log("DonePanel: Connecting to Security Domain");
+
+ my $machineName = $::config->get("service.machineName");
+ my $unsecurePort = $::config->get("service.unsecurePort");
+ my $securePort = $::config->get("service.securePort");
+ my $non_clientauth_securePort = $::config->get("service.non_clientauth_securePort");
+ my $session_id = $::config->get("preop.sessionID");
+
+ &PKI::RA::Wizard::debug_log("DonePanel: Security Domain Info " . $url);
+
+ # add service.securityDomainPort to the config file in case pkiremove
+ # needs to remove system reference from the security domain
+ $::config->put("service.securityDomainPort", $securePort);
+ $::config->commit();
+
+ my $uid = "RA-" . $machineName . "-" . $securePort;
+ my $name = "Registration Authority Subsystem";
+
+ my $instDir = $::config->get("service.instanceDir");
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+
+ my $hw;
+ my $tk;
+ my $tokenname = $::config->get("preop.module.token");
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: update got token name = $tokenname");
+
+ if (($tokenname eq "") || ($tokenname eq "NSS Certificate DB")) {
+ $hw = "";
+ $tk = "";
+ } else {
+ $hw = "-h $tokenname";
+ $tk = $tokenname.":";
+ }
+
+ my $token_pwd = $::pwdconf->get($tokenname);
+ open FILE, ">$instDir/conf/.pwfile";
+ system( "chmod 00660 $instDir/conf/.pwfile" );
+ $token_pwd =~ s/\n//g;
+ print FILE $token_pwd;
+ close FILE;
+
+ my $subsystemNickname = $::config->get("preop.cert.subsystem.nickname");
+ my $certificate = `/usr/bin/certutil -d "$instDir/alias" -L $hw -f "$instDir/conf/.pwfile" -n "$subsystemNickname" -a`;
+ $certificate =~ s/-----BEGIN CERTIFICATE-----//g;
+ $certificate =~ s/-----END CERTIFICATE-----//g;
+ $certificate =~ s/\n$//g;
+
+
+ &PKI::RA::Wizard::debug_log("DonePanel: Connecting");
+
+ my $instanceID = $::config->get("service.instanceID");
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $db_password =~ s/\n$//g;
+
+ my $params = "uid=" . $uid . "&" .
+ "name=" . $name . "&" .
+ "certificate=" .
+ URI::Escape::uri_escape("$certificate") . "&" .
+ "xmlOutput=true" . "&" .
+ "sessionID=" . $session_id . "&" .
+ "auth_hostname=" . $sdom_info->host . "&" .
+ "auth_port=" . $sdom_info->port;
+
+ my $host = $url_info->host;
+ my $port = $url_info->port;
+ my $tmpfile = "/tmp/donepanel-$$";
+ if (($tokenname eq "") || ($tokenname eq "NSS Certificate DB")) {
+ system("/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"$db_password\" -v -n \"$nickname\" -r \"$uri\" $host:$port > $tmpfile");
+ } else {
+ system("/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"$token_pwd\" -v -n \"$nickname\" -r \"$uri\" $host:$port > $tmpfile");
+ }
+ my $content = `cat $tmpfile`;
+ system("rm $tmpfile");
+
+ &PKI::RA::Wizard::debug_log("req = " . $content);
+ $content =~ /(\<XMLResponse\>.*\<\/XMLResponse\>)/;
+ $content = $1;
+
+ &PKI::RA::Wizard::debug_log("DonePanel: result " . $content);
+ my $tmp = `rm $instDir/conf/.pwfile`;
+}
+
+sub get_kra_transport_cert
+{
+ my ($sdom) = @_;
+
+ my $sdom_info = new URI::URL($sdom);
+
+ # register RA to Security Domain
+ # submit request to CA
+ &PKI::RA::Wizard::debug_log("DonePanel: Connecting to KRA");
+
+ my $krainfo = $::config->get("preop.krainfo.select");
+ my $krainfo_url = new URI::URL($krainfo);
+
+ my $machineName = $::config->get("service.machineName");
+ my $unsecurePort = $::config->get("service.unsecurePort");
+ my $securePort = $::config->get("service.securePort");
+ my $non_clientauth_securePort = $::config->get("service.non_clientauth_securePort");
+ my $session_id = $::config->get("preop.sessionID");
+
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+ my $tokenname = $::config->get("preop.module.token");
+ my $token_pwd = $::pwdconf->get($tokenname);
+ my $instanceID = $::config->get("service.instanceID");
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $db_password =~ s/\n$//g;
+
+ my $params = "sessionID=" . $session_id . "&" .
+ "auth_hostname=" . $sdom_info->host . "&" .
+ "auth_port=" . $sdom_info->port;
+
+ my $host = $krainfo_url->host;
+ my $port = $krainfo_url->port;
+ my $tmpfile = "/tmp/donepanel-$$";
+ if (($tokenname eq "") || ($tokenname eq "NSS Certificate DB")) {
+ system("/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"$db_password\" -v -r \"/kra/admin/kra/getTransportCert\" $host:$port > $tmpfile");
+ } else {
+ system("/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"$token_pwd\" -v -r \"/kra/admin/kra/getTransportCert\" $host:$port > $tmpfile");
+ }
+ my $content = `cat $tmpfile`;
+ system("rm $tmpfile");
+
+ $content =~ /(\<XMLResponse\>.*\<\/XMLResponse\>)/;
+ $content = $1;
+
+ my $parser = XML::Simple->new();
+ my $response = $parser->XMLin($content);
+ my $transportCert = $response->{TransportCert};
+
+ &PKI::RA::Wizard::debug_log("DonePanel: TransportCert " . $transportCert);
+
+ return $transportCert;
+}
+
+sub send_kra_transport_cert
+{
+ my ($sdom, $certificate) = @_;
+
+ my $sdom_info = new URI::URL($sdom);
+
+ # register RA to Security Domain
+ # submit request to CA
+ &PKI::RA::Wizard::debug_log("DonePanel: Connecting to TKS");
+ my $tksinfo = $::config->get("preop.tksinfo.select");
+ my $tksinfo_url = new URI::URL($tksinfo);
+
+ my $machineName = $::config->get("service.machineName");
+ my $unsecurePort = $::config->get("service.unsecurePort");
+ my $securePort = $::config->get("service.securePort");
+ my $non_clientauth_securePort = $::config->get("service.non_clientauth_securePort");
+ my $session_id = $::config->get("preop.sessionID");
+
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+ my $tokenname = $::config->get("preop.module.token");
+ my $token_pwd = $::pwdconf->get($tokenname);
+ my $instanceID = $::config->get("service.instanceID");
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $db_password =~ s/\n$//g;
+
+ my $name = "transportCert-" . $machineName . "-" . $securePort;
+ my $params = "name=" . $name . "&" .
+ "certificate=" .
+ URI::Escape::uri_escape("$certificate") . "&" .
+ "xmlOutput=true" . "&" .
+ "sessionID=" . $session_id . "&" .
+ "auth_hostname=" . $sdom_info->host . "&" .
+ "auth_port=" . $sdom_info->port;
+
+ my $host = $tksinfo_url->host;
+ my $port = $tksinfo_url->port;
+ my $tmpfile = "/tmp/donepanel-$$";
+ if (($tokenname eq "") || ($tokenname eq "NSS Certificate DB")) {
+ system("/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"$db_password\" -v -r \"/tks/admin/tks/importTransportCert\" $host:$port > $tmpfile");
+ } else {
+ system("/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"$token_pwd\" -v -r \"/tks/admin/tks/importTransportCert\" $host:$port > $tmpfile");
+ }
+
+ my $content = `cat $tmpfile`;
+ system("rm $tmpfile");
+
+ $content =~ /(\<XMLResponse\>.*\<\/XMLResponse\>)/;
+ $content = $1;
+
+ &PKI::RA::Wizard::debug_log("DonePanel: Response from TKS " . $content);
+}
+
+sub display
+{
+ my ($q) = @_;
+ # $symbol{systemType} = "ra";
+ # $symbol{host} = "chico";
+ # $symbol{port} = "443";
+ &PKI::RA::Wizard::debug_log("DonePanel: display");
+
+ my $status = $::config->get("preop.done.status");
+ if ($status eq "done") {
+ return 1;
+ }
+
+ my $instDir = $::config->get("service.instanceDir");
+ my $tokenname = $::config->get("preop.module.token");
+ my $token_pwd = $::pwdconf->get($tokenname);
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+ if (($tokenname ne "") && ($tokenname ne "NSS Certificate DB")) {
+ open(PWD_CONF, ">>$instDir/conf/password.conf");
+ print PWD_CONF "$tokenname:$token_pwd\n";
+ close (PWD_CONF);
+ }
+
+ # Add this RA's server certificate to the subsystems
+ my $sdom = $::config->get("config.sdomainEEURL");
+ my $cainfo = $::config->get("preop.cainfo.select");
+ $cainfo =~ s/.* - //g;
+ &register_ra($sdom, $cainfo, $::config->get("conn.ca1.servlet.addagent"), "CA");
+
+ $::config->put("preop.done.status", "done");
+ $::config->commit();
+
+ # update httpd.conf
+ open(TMP_HTTPD_CONF, ">$instDir/conf/httpd.conf.tmp");
+ system( "chmod 00660 $instDir/conf/httpd.conf.tmp" );
+ open(HTTPD_CONF, "<$instDir/conf/httpd.conf");
+ while (<HTTPD_CONF>) {
+ if (/^#\[ErrorDocument_404\]/) {
+ print TMP_HTTPD_CONF "ErrorDocument 404 /404.html\n";
+ } elsif (/^#\[ErrorDocument_500\]/) {
+ print TMP_HTTPD_CONF "ErrorDocument 500 /500.html\n";
+ } else {
+ print TMP_HTTPD_CONF $_;
+ }
+ }
+ close(HTTPD_CONF);
+ close(TMP_HTTPD_CONF);
+
+ # Create a copy of the original file which
+ # preserves the original file permissions
+ system( "cp -p $instDir/conf/httpd.conf.tmp $instDir/conf/httpd.conf" );
+
+ # Remove the original file only if the backup copy was successful
+ if( -e "$instDir/conf/httpd.conf" ) {
+ system( "rm $instDir/conf/httpd.conf.tmp" );
+ }
+
+ # update nss.conf
+ open(TMP_NSS_CONF, ">$instDir/conf/nss.conf.tmp");
+ system( "chmod 00660 $instDir/conf/nss.conf.tmp" );
+ open(NSS_CONF, "<$instDir/conf/nss.conf");
+ while (<NSS_CONF>) {
+ if (/^NSSNickname/) {
+ print TMP_NSS_CONF "NSSNickname \"$nickname\"\n";
+ } else {
+ print TMP_NSS_CONF $_;
+ }
+ }
+ close(NSS_CONF);
+ close(TMP_NSS_CONF);
+
+ # Create a copy of the original file which
+ # preserves the original file permissions
+ system( "cp -p $instDir/conf/nss.conf.tmp $instDir/conf/nss.conf" );
+
+ # Remove the original file only if the backup copy was successful
+ if( -e "$instDir/conf/nss.conf" ) {
+ system( "rm $instDir/conf/nss.conf.tmp" );
+ }
+
+ &PKI::RA::Wizard::debug_log("DonePanel: Connecting to Security Domain");
+
+ my $machineName = $::config->get("service.machineName");
+ my $unsecurePort = $::config->get("service.unsecurePort");
+ my $securePort = $::config->get("service.securePort");
+ my $non_clientauth_securePort = $::config->get("service.non_clientauth_securePort");
+ my $instanceID = $::config->get("service.instanceID");
+
+ my $initDaemon = "pki-rad";
+ my $initCommand = "";
+ if( $^O eq "linux" ) {
+ $initCommand = "/sbin/service $initDaemon";
+ } else {
+ ## default case: e. g. - ( $^O eq "solaris" )
+ $initCommand = "/etc/init.d/$initDaemon";
+ }
+
+ $::symbol{host} = $machineName;
+ $::symbol{unsecurePort} = $unsecurePort;
+ $::symbol{port} = $securePort;
+ $::symbol{non_clientauth_port} = $non_clientauth_securePort;
+ $::symbol{initCommand} = $initCommand;
+ $::symbol{instanceID} = $instanceID;
+
+ $::config->deleteSubstore("preop.");
+ $::config->commit();
+
+ ## Create an empty file that designates the fact that although
+ ## this server instance has been configured, it has NOT yet
+ ## been restarted!
+ my $restart_server = "$instDir/conf/restart_server_after_configuration";
+ system( "touch $restart_server" );
+ system( "chmod 00660 $restart_server" );
+
+ system("rm $instDir/conf/*.txt $instDir/conf/*.der");
+ return 1;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/GlobalVar.pm b/base/ra/lib/perl/PKI/RA/GlobalVar.pm
new file mode 100755
index 000000000..388a41349
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/GlobalVar.pm
@@ -0,0 +1,42 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+
+package PKI::RA::GlobalVar;
+$PKI::RA::GlobalVar::VERSION = '1.00';
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ my %args = (@_);
+ foreach my $q (keys %args) {
+ $self->{$q} = $args{$q};
+ }
+ bless $self,$class;
+ return $self;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/ImportAdminCertPanel.pm b/base/ra/lib/perl/PKI/RA/ImportAdminCertPanel.pm
new file mode 100755
index 000000000..9f9bef94a
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/ImportAdminCertPanel.pm
@@ -0,0 +1,142 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+use URI::URL;
+
+package PKI::RA::ImportAdminCertPanel;
+$PKI::RA::ImportAdminCertPanel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(15);
+ $self->{"getName"} = &PKI::RA::Common::r("Import Administrator Certificate");
+ $self->{"vmfile"} = "importadmincertpanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("ImportAdminCertPanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("ImportAdminCertPanel: update");
+
+ # register to Security Domain
+ my $sdom = $::config->get("config.sdomainAgentURL");
+ my $sdom_url = new URI::URL($sdom);
+
+ #
+ # we need to authenticate to the security domain with the subsystem
+ # certificate
+ #
+ my $machineName = $::config->get("service.machineName");
+ my $instanceID = $::config->get("service.instanceID");
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $securePort = $::config->get("service.securePort");
+ my $subsystemName = $::config->get("preop.subsystem.name");
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ my $name = $subsystemName;
+ my $subCertNickName = $::config->get("preop.cert.subsystem.nickname");
+
+ $db_password =~ s/\n$//g;
+
+ my $params = "list=" . "RAList" . "&" .
+ "type=" . "RA" . "&" .
+ "host=" . $machineName . "&" .
+ "name=" . $name . "&" .
+ "sport=" . $securePort . "&" .
+ "dm=false"; # domain manager or not
+
+ my $cmd = `/usr/bin/sslget -d \"$instanceDir/alias\" -p \"$db_password\" -v -n \"$subCertNickName\" -r \"/ca/agent/ca/updateDomainXML?$params\" $sdom_url->host:$sdom_url->port`;
+
+ # Fetch the "updated" security domain and display it
+ &PKI::RA::Wizard::debug_log("ImportAdminCertPanel: Dump contents of updated Security Domain . . .");
+ my $sdomainAdminURL = $::config->get("config.sdomainAdminURL");
+ my $sdom_info = new URI::URL($sdomainAdminURL);
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+ my $sd_host = $sdom_info->host;
+ my $sd_admin_port = $sdom_info->port;
+ my $content = `/usr/bin/sslget -d \"$instanceDir/alias\" -p \"$db_password\" -v -r \"/ca/admin/ca/getDomainXML\" $sd_host:$sd_admin_port`;
+ $content =~ /(\<XMLResponse\>.*\<\/XMLResponse\>)/;
+ $content = $1;
+ &PKI::RA::Wizard::debug_log($content);
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("ImportAdminCertPanel: display");
+
+ my $cainfo = $::config->get("preop.cainfo.select");
+
+ my $cainfo_url = new URI::URL($cainfo);
+ my $serialNumber = $::config->get("preop.admincert.serialno.0");
+
+ $::symbol{info} = "";
+ $::symbol{errorString} = "";
+ $::symbol{import} = "true";
+ $::symbol{ca} = "false";
+ $::symbol{caType} = "ca";
+ $::symbol{caHost} = $cainfo_url->host;
+ $::symbol{caPort} = $cainfo_url->port;
+ $::symbol{serialNumber} = $serialNumber;
+
+ return 1;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/Login.pm b/base/ra/lib/perl/PKI/RA/Login.pm
new file mode 100755
index 000000000..d248e5481
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/Login.pm
@@ -0,0 +1,466 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+# wizard -
+# Fedora Certificate System - Registration Authority System configuration wizard
+
+
+# This script is run as a 'mod_perl' CGI. Configure mod_perl by adding
+# the following to /etc/httpd/conf.d/perl.conf
+#
+# PerlModule ModPerl::Registry
+# PerlModule Apache::compat
+# PerlModule PKI::RA::Wizard
+# PerlSetEnv PKI_DOCROOT /u/sparkins/t/cs_tip/certsystem/prj/common/ui
+# <Location /wizard>
+# SetHandler perl-script
+# PerlHandler PKI::RA::Wizard
+# Order deny,allow
+# Allow from all
+# </Location>
+
+
+# Note: The Velocity parser is not very helpful when it comes to
+# errors right now. Here are some common errors, and what they mean:
+#
+# ERROR:
+# [Mon Apr 03 13:57:33 2006] [error] [client 172.16.24.26]
+# Can't use string ("0") as an ARRAY ref while "strict refs"
+# in use at /usr/lib/perl5/site_perl/5.8.5/Template/Velocity.pm
+# line 423.\n, referer: http://chico/wizard?p=2
+# MEANING
+# This probably means that your *.vm file refers to an array
+# variable in a foreach statement that is not defined
+# Check your foreach array variables.
+
+use warnings;
+use ModPerl::Registry;
+use Template::Velocity;
+use Getopt::Std;
+use Data::Dumper;
+use CGI::Carp qw(fatalsToBrowser);
+use CGI;
+use APR::Const -compile => qw(:error SUCCESS);
+use PKI::RA::GlobalVar;
+use PKI::RA::WelcomePanel;
+use PKI::RA::SecurityDomainPanel;
+use PKI::RA::DisplayCertChainPanel;
+use PKI::RA::SubsystemTypePanel;
+use PKI::RA::CAInfoPanel;
+use PKI::RA::TKSInfoPanel;
+use PKI::RA::DRMInfoPanel;
+use PKI::RA::DisplayCertChain2Panel;
+use PKI::RA::AdminAuthPanel;
+use PKI::RA::AgentAuthPanel;
+use PKI::RA::DatabasePanel;
+use PKI::RA::ModulePanel;
+use PKI::RA::SizePanel;
+use PKI::RA::NamePanel;
+use PKI::RA::ConfigHSMLoginPanel;
+use PKI::RA::CertRequestPanel;
+use PKI::RA::AdminPanel;
+use PKI::RA::ImportAdminCertPanel;
+use PKI::RA::LoginPanel;
+use PKI::RA::DonePanel;
+use PKI::RA::Config;
+
+use PKI::RA::Common qw(yes no r);
+
+package PKI::RA::Login;
+$PKI::RA::Login::VERSION = '1.00';
+
+# read configuration file
+my $flavor = "pki";
+$flavor =~ s/\n//g;
+
+my $pkiroot = $ENV{PKI_ROOT};
+
+my $config = PKI::RA::Config->new();
+$config->load_file("$pkiroot/conf/CS.cfg");
+# read password cache file
+my $pwdconf = PKI::RA::Config->new();
+$pwdconf->load_file("$pkiroot/conf/pwcache.conf");
+# SELinux disallows performing a "chmod" on this file
+if( $^O ne "linux" ) {
+ system( "chmod 00660 $pkiroot/conf/pwcache.conf" );
+}
+
+# create cfg debug log
+my $logfile = $config->get("service.instanceDir") . "/logs/debug";
+open( DEBUG, ">>" . $logfile ) ||
+warn( "Could not open '" . $logfile . "': $!" );
+
+# apache server
+
+our $debug;
+
+my $STATUS_OK = 1;
+my $STATUS_ERROR = 2;
+my $STATUS_REDIRECT = 3;
+
+&debug_log("RA wizard: starting up");
+
+my $docroot = $ENV{PKI_DOCROOT};
+
+if (! $docroot) {
+ &debug_log("RA wizard: ERROR: PKI_DOCROOT is null");
+ return 0;
+}
+
+our $parser = new Template::Velocity($docroot);
+our $symbol;
+our @certtags;
+
+makepanels();
+
+&debug_log("RA wizard: start up complete");
+
+1;
+
+sub debug_log
+{
+ my ($msg) = @_;
+ my $date = `date`;
+ chomp($date);
+ if( -w $logfile ) {
+ print DEBUG "$date - $msg\n";
+ }
+}
+
+ # initializes entries in parser's global symbol table for panels
+sub makepanels
+{
+ #REAL PANELS BELOW
+ my $login = new PKI::RA::LoginPanel();
+
+ $symbol{panels} = [
+ $login, # com.netscape.cms.servlet.csadmin.WelcomePanel
+ ];
+};
+
+sub render_panel
+{
+ my ($panelnum, $q) = @_;
+
+ $symbol{errorString} = "";
+
+ my $currentpanel;
+
+ if ($q->param('op') && $q->param('op') eq "next") {
+ $currentpanel = $symbol{panels}[$panelnum];
+ # validate variables for panel
+ if ($currentpanel->{validate}) {
+ $currentpanel->{validate}($q);
+ }
+ # execute current panel
+ my $status = "0";
+
+ if ($currentpanel->{update}) {
+ $status = $currentpanel->{update}($q);
+ &debug_log("RA wizard: update returns status '" .
+ $status . "'");
+ if ($status == $STATUS_REDIRECT) {
+ return $STATUS_REDIRECT;
+ }
+
+ }
+
+ &debug_log("RA wizard: about to find out about sub panel");
+ if ($status eq "1") {
+ if ($currentpanel->{hasSubPanel} && &{$currentpanel->{hasSubPanel}}($q)) {
+ &debug_log("RA wizard: has sub panel");
+ $panelnum = $panelnum + 2;
+ } elsif ($currentpanel->{isSubPanel} && &{$currentpanel->{isSubPanel}}($q)) {
+ &debug_log("RA wizard: is sub panel");
+ $panelnum = $panelnum - 1;
+ } else {
+ &debug_log("RA wizard: no sub panel and is not subpanel");
+ $panelnum = $panelnum + 1;
+ }
+ }
+ } elsif ($q->param('op') && $q->param('op') eq "back") {
+ $panelnum = $panelnum - 1;
+ #check if this a subpanel, if so, go back to it's parent.
+ #only handles one-deep at this point
+ my $panel = $symbol{panels}[$panelnum];
+ if (&{$panel->{isSubPanel}}($q)) {
+ $panelnum = $panelnum - 1;
+ }
+ } elsif ($q->param('op') && $q->param('op') eq "apply") {
+ &debug_log("RA wizard: update : apply button pressed");
+ $currentpanel = $symbol{panels}[$panelnum];
+ # validate variables for panel
+ if ($currentpanel->{validate}) {
+ $currentpanel->{validate}($q);
+ }
+ # execute current panel
+ if ($currentpanel->{update}) {
+ my $status = $currentpanel->{update}($q);
+ &debug_log("RA wizard: update returns status '" .
+ $status . "'");
+ if ($status == $STATUS_REDIRECT) {
+ return $STATUS_REDIRECT;
+ }
+
+ }
+ }
+
+ &debug_log("RA wizard: after looking into about sub panel");
+
+ # advance to next panel
+ $currentpanel = $symbol{panels}[$panelnum];
+
+ # initialize symbol table values
+ $symbol{showApplyButton} = "false";
+
+ # fill in variables for new panel
+ if ($currentpanel->{panelvars}) {
+ $Data::Dumper::Indent = 1;
+ # The '&debug_log("q=".Dumper($q));' call must be commented out to fix
+ # Bugzilla Bug #249923: Incorrect file permissions on
+ # various files and/or directories
+ # &debug_log("q=".Dumper($q));
+ $currentpanel->{panelvars}($q);
+ }
+
+ $symbol{panel} = "ra/admin/console/config/".$currentpanel->{vmfile};
+
+ #wizard.vm:
+ $symbol{name} = "Registration Authority System";
+ $symbol{title} = $currentpanel->{getName}();
+ if ($panelnum == 0) {
+ $symbol{firstpanel} = "1";
+ } else {
+ $symbol{firstpanel} = "0";
+ }
+ if ($panelnum == 17) {
+ $symbol{lastpanel} = "1";
+ } else {
+ $symbol{lastpanel} = "0";
+ }
+ $symbol{p} = $panelnum;
+ $symbol{subpanelno} = $panelnum+1;
+ $symbol{csstate} = "1";
+
+# $symbol{urls} = [ "cert1", "cert2" ]; #createsubsystem
+# $symbol{urls_size} = 2;
+# $symbol{instanceId} = "ra";
+# $symbol{errorString} = "";
+
+ #modulepanel
+# $symbol{certs} = [ ];
+# $symbol{reqscerts} = [ ];
+ $symbol{ppcerts} = [ ];
+
+ return $STATUS_OK;
+}
+
+
+
+sub dbg {
+ my $msg = shift;
+ $::symbol{dbg} .= "$msg\n";
+}
+
+sub handler {
+ my $r = shift;
+
+ *::symbol = \%symbol;
+ *::s = \$s;
+ *::config = \$config;
+ *::pwdconf = \$pwdconf;
+
+ &debug_log("RA wizard: in handler");
+ if ($#ARGV == -1) {
+ $r->send_http_header('text/html');
+ }
+
+ my $q = new CGI;
+
+ # check cookie
+ my $pin = $q->param('pin');
+ if (defined($pin)) {
+ my $cookie = $q->cookie(
+ -name=>'pin',
+ -value=> $pin,
+ -expires=>'+1y',
+ -path=>'/');
+ print $q->redirect(-location => "wizard", -cookie => $cookie);
+ return;
+ }
+
+ # output http parameters
+ &debug_log("RA wizard: uri='" . $ENV{REQUEST_URI} . "'");
+ my @pnames = $q->param();
+ foreach $pn (@pnames) {
+ # 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 =~ /^__/ ||
+ $pn =~ /password$/ ||
+ $pn =~ /passwd$/ ||
+ $pn =~ /pwd$/ ||
+ $pn =~ /admin_password_again/i ||
+ $pn =~ /directoryManagerPwd/i ||
+ $pn =~ /bindpassword/i ||
+ $pn =~ /bindpwd/i ||
+ $pn =~ /passwd/i ||
+ $pn =~ /password/i ||
+ $pn =~ /pin/i ||
+ $pn =~ /pwd/i ||
+ $pn =~ /pwdagain/i ||
+ $pn =~ /uPasswd/i ) {
+ &debug_log("RA wizard: http parameter name='" . $pn . "' value='(sensitive)'");
+ } else {
+ &debug_log("RA wizard: http parameter name='" . $pn . "' value='" . $q->param($pn) . "'");
+ }
+ }
+
+ my $panelnum = $q->param('p');
+ if (!defined($panelnum) || $panelnum eq "") {
+ # Apache fails to pick up the p parameter after
+ # redirecting from the security domain. This is
+ # a quick hack to solve the issue.
+ if ($ENV{'QUERY_STRING'} ne "") {
+ $ENV{'QUERY_STRING'} =~ /p=([0-9]+)&/;
+ $panelnum = $1;
+ }
+ }
+
+ use subs qw(debug);
+ *debug = \&Template::Velocity::Executor::debug;
+
+ $::symbol{dbg} = "";
+
+ &debug_log("RA wizard: before argparsing");
+ if ($#ARGV == -1) {
+ $Data::Dumper::Maxdepth = 7;
+ $startfile = "ra/admin/console/config/login.vm";
+ }
+
+ &debug_log("RA wizard: setting up test objects");
+
+ #initialize from config file
+ my $certlist = $::config->get("preop.cert.list");
+ if ($certlist eq "") {
+ $certlist = "sslserver,subsystem";
+ }
+ @certtags = split(/,/, $certlist);
+ $numtags = @certtags;
+ if ($numtags eq 0) {
+ @certtags = ("sslserver", "subsystem");
+ }
+ &debug_log("RA wizard: found $numtags certtags");
+
+ if (! $panelnum) {
+ $panelnum = 0;
+ }
+
+ my $status = render_panel($panelnum, $q);
+ if ($status == 3) {
+ $r->header_out(Location => $symbol{redirect});
+ $r->status(301);
+ $r->send_http_header();
+ return;
+ }
+
+ use Data::Dumper;
+ &debug_log("RA wizard: executing file $startfile");
+ foreach $q (sort keys %symbol) {
+ &debug_log("RA wizard:/config/wizard?p=9&SecToken=NSS%20Generic%20Crypto%20Services sym{$q}=".$symbol{$q});
+ }
+
+ my $result;
+ if ($q->param("xml") eq "true") {
+ $r->send_http_header('text/xml');
+ $result = "<xml>";
+ foreach $s (sort keys %symbol) {
+ if ($s =~ /^__/) {
+ next;
+ }
+ $result .= "<" . $s . ">";
+ my $v = $symbol{$s};
+ $result .= &get_xml($s, $v);
+ $result .= "</" . $s . ">";
+ }
+ $result .= "</xml>";
+ } else {
+ $result = $parser->execute_file($startfile);
+ if (!defined $result) {
+ die("Couldn't execute template file: $docroot/$startfile");
+ }
+ }
+
+ print "$result\n";
+ return $STATUS_OK;
+}
+
+sub get_xml
+{
+ my ($s, $v) = @_;
+
+ my $result;
+ if (ref($v) eq "HASH") {
+ foreach my $xkey (keys %$v) {
+ $result .= "<" . $xkey . ">";
+ $result .= &get_xml($xkey, $v{$xkey});
+ # $result .= "-" . ref($xkey);
+ $result .= "</" . $xkey . ">";
+ }
+ } elsif (ref($v) eq "PKI::RA::CertInfo") {
+ my $certinfo = $v;
+ $result .= "<certinfo>";
+ $result .= "<dn>" . $certinfo->get_dn() ."</dn>";
+ $result .= "<tag>" . $certinfo->get_cert_tag() . "</tag>";
+ $result .= "<friendly>" . $certinfo->get_user_friendly_name() .
+ "</friendly>";
+ $result .= "</certinfo>";
+ } elsif (ref($v) eq "PKI::RA::ReqCertInfo") {
+ my $reqcertinfo = $v;
+ $result .= "<reqcertinfo>";
+ $result .= "<name>" . $reqcertinfo->get_user_friendly_name() ."</name>";
+ $result .= "<req>" . $reqcertinfo->get_request() ."</req>";
+ $result .= "<cert>" . $reqcertinfo->get_cert() ."</cert>";
+ $result .= "<certpp>" . $reqcertinfo->get_cert_pp() ."</certpp>";
+ $result .= "<tag>" . $reqcertinfo->get_cert_tag() ."</tag>";
+ $result .= "<dn>" . $reqcertinfo->get_cert_tag() ."</dn>";
+ $result .= "</reqcertinfo>";
+ } elsif (ref($v) eq "ARRAY") {
+ my $pos = 0;
+ foreach my $item (@$v) {
+ $result .= "<element>";
+ $result .= &get_xml("p" . $pos, $item);
+ # $result .= "-" . ref($item);
+ $result .= "</element>";
+ $pos++;
+ }
+ } else {
+ $result .= $v;
+ }
+ return $result;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/LoginPanel.pm b/base/ra/lib/perl/PKI/RA/LoginPanel.pm
new file mode 100755
index 000000000..66f40acfe
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/LoginPanel.pm
@@ -0,0 +1,91 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+
+package PKI::RA::LoginPanel;
+$PKI::RA::LoginPanel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(0);
+ $self->{"getName"} = &PKI::RA::Common::r("Welcome");
+ $self->{"vmfile"} = "login.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("WelcomePanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("WelcomePanel: update");
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log($ENV{'SERVER_PORT'});
+ &PKI::RA::Wizard::debug_log("Debug=" . $::config->get("logging.debug.enable"));
+ &PKI::RA::Wizard::debug_log("WelcomePanel: display");
+ $::symbol{wizardname} = "RA Configuration Wizard";
+ $::symbol{systemname} = "RA";
+ $::symbol{fullsystemname} = "Registration Authority";
+
+ return 1;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/ModulePanel.pm b/base/ra/lib/perl/PKI/RA/ModulePanel.pm
new file mode 100755
index 000000000..87ce056bc
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/ModulePanel.pm
@@ -0,0 +1,273 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+use PKI::RA::Modutil;
+
+package PKI::RA::ModulePanel;
+$PKI::RA::ModulePanel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+
+our $modutil;
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(9);
+ $self->{"getName"} = &PKI::RA::Common::r("Security Modules");
+ $self->{"vmfile"} = "modulepanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+
+ my $flavor = "pki";
+ $flavor =~ s/\n//g;
+
+ my $pkiroot = $ENV{PKI_ROOT};
+ $modutil = new PKI::RA::Modutil("$pkiroot/alias");
+
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 1;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ my $defTok = $::config->get("preop.module.token");
+ my $select = $q->param('choice');
+ if ($select eq "") {
+ &PKI::RA::Wizard::debug_log("ModulePanel -> update no selection found");
+ $::symbol{errorString} = "No selection found";
+ return 0;
+ } elsif ($defTok ne $select) {
+ &PKI::RA::Wizard::debug_log("ModulePanel -> update changing defTok to $select");
+ $::config->put("preop.module.token", $select);
+ $::config->put("preop.ModulePanel.done", "true");
+ } else {
+ # this is not an error...just information
+ &PKI::RA::Wizard::debug_log("ModulePanel -> update defTok not changed");
+ }
+
+ $::config->commit();
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("ModulePanel -> display");
+ getModules();
+ my $defTok = $::config->get("preop.module.token");
+
+ $::symbol{defTok} = $defTok;
+
+ return 1;
+}
+
+use Data::Dumper;
+sub getTokens {
+ my $modulename = shift;
+
+ &PKI::RA::Wizard::debug_log("ModulePanel -> getTokens");
+
+#$Data::Dumper::Indent = 0;
+#PKI::RA::Wizard::dbg("in gettokens. modutil = ".Dumper($modutil));
+ my @tokens;
+ my $mod = $modutil->getmodule($modulename);
+ foreach my $tokenname (keys %{$mod->{tokens}}) {
+ #PKI::RA::Wizard::dbg("found token $tokenname");
+ if ($tokenname ne "NSS Generic Crypto Services") {
+ my $token = $modutil->gettoken($tokenname);
+ my $t = new PKI::RA::GlobalVar(
+ getNickName => sub { return $tokenname; },
+ isLoggedIn => sub { return isLoggedIn($tokenname); },
+ isPresent => sub { return 1; },
+ );
+ push @tokens, $t;
+ } else {
+ &PKI::RA::Wizard::debug_log("ModulePanel -> getTokens token NSS Generic Crypto Services not available for key generation");
+
+ }
+ }
+
+ return \@tokens;
+}
+
+# if password is found, then it's considered "logged in"
+# otherwise it is "not logged in"
+sub Login {
+ my $tokenname = $_[0];
+ my $pwd = $::pwdconf->get($tokenname);
+ if ($pwd ne "") {
+ &PKI::RA::Wizard::debug_log("ModulePanel -> isLoggedIn retrieved pwd from pwdconf");
+ return 1;
+ }
+ &PKI::RA::Wizard::debug_log("ModulePanel -> isLoggedIn pwd not found from pwdconf for token: $tokenname");
+
+ if ($tokenname eq "NSS Certificate DB") {
+ my $instanceDir = $::config->get("service.instanceDir");
+ &PKI::RA::Wizard::debug_log("ModulePanel -> isLoggedIn get internal password for $tokenname");
+ # these are referred as "internal" in password.conf
+ $pwd = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $pwd =~ s/\n//g;
+ $::pwdconf->put($tokenname, $pwd);
+ $::pwdconf->commit();
+
+ return 1;
+ }
+ return 0;
+}
+
+sub isLoggedIn {
+ my $tokenname = $_[0];
+ return &Login($tokenname);
+}
+
+sub getModules {
+ my $count;
+ my $i;
+ my @supportedModules;
+
+ &PKI::RA::Wizard::debug_log("ModulePanel -> getModules");
+ $count = $::config->get("preop.configModules.count");
+ &PKI::RA::Wizard::debug_log("ModulePanel -> getModules count =$count");
+
+ my @modules = $modutil->getmodules();
+ # $::symbol{steve} = join ",Module:", @modules;
+ # $::symbol{steve}.= "\n";
+
+ my $x = "
+ preop.configModules.count=3
+ preop.configModules.module0.commonName=NSS Internal PKCS #11 Module
+ preop.configModules.module0.imagePath=../img/mozilla.png
+ preop.configModules.module0.userFriendlyName=NSS Internal PKCS #11 Module
+ preop.configModules.module1.commonName=nfast
+ preop.configModules.module1.imagePath=../img/ncipher.png
+ preop.configModules.module1.userFriendlyName=nCipher's nFast Token Hardware Module
+ preop.configModules.module2.commonName=lunasa
+ preop.configModules.module2.imagePath=../img/safenet.png
+ preop.configModules.module2.userFriendlyName=SafeNet's LunaSA Token Hardware Module
+ ";
+
+ my %supmodules;
+ for ($i=0; $i <$count; $i++) {
+ my $cn;
+ my $pn;
+ my $img;
+# &PKI::RA::Wizard::debug_log("ModulePanel -> getModules look for cn=","preop.configModules.module" , $i , ".commonName");
+ $cn = $::config->get("preop.configModules.module$i.commonName");
+ $supmodules{$cn} = 1;
+
+ $pn = $::config->get("preop.configModules.module$i.userFriendlyName");
+ $img = $::config->get("preop.configModules.module$i.imagePath");
+ &PKI::RA::Wizard::debug_log("ModulePanel -> getModules: got module $cn from config");
+
+ my $module = $modutil->getmodule($cn);
+ my $file = $module->{detail}->{"Library file"};
+ &PKI::RA::Wizard::debug_log("ModulePanel -> getModules Library file = $file");
+ my $found = 0;
+ if ($file) {
+ $found = ($file =~ /Internal ONLY module/) || -e $file;
+ }
+
+ my $name = $module->{detail}->{Name};
+# PKI::RA::Wizard::dbg("name: $name");
+
+ $supportedModules[$i] = new PKI::RA::GlobalVar(
+ getImagePath => sub { return $img; },
+ getUserFriendlyName => sub { return $pn; },
+ isFound => sub { return $found; },
+ getTokens => sub { return getTokens($name); },
+ );
+
+ # login to tokens
+ &PKI::RA::Wizard::debug_log("Ready to login to tokens for $name");
+ my $mod = $modutil->getmodule($name);
+ foreach my $tokenname (keys %{$mod->{tokens}}) {
+ &PKI::RA::Wizard::debug_log("Logging in Module $name Token " . $tokenname);
+ &Login($tokenname);
+ }
+
+ }
+
+ my @otherModules;
+ #compile the "others" modules
+
+ foreach my $modname (@modules) {
+ #is this modname in the supported modules list?
+ if ($supmodules{$modname}) {
+ &PKI::RA::Wizard::debug_log("ModulePanel -> getModules: found module $modname supported");
+ # does not belong to "others"
+ } else {
+ &PKI::RA::Wizard::debug_log("ModulePanel -> getModules: found module $modname unsupported");
+ #add the module to "others" list
+ my $m = $modutil->getmodule($modname);
+ my $mod = new PKI::RA::GlobalVar(
+ getImagePath => sub { return ""; },
+ getUserFriendlyName => sub { return $m->{modulename}; },
+ isFound => sub { return 1; },
+ getTokens => sub { return getTokens($m->{detail}->{Name});}
+ );
+
+ push @otherModules, $mod;
+
+ &PKI::RA::Wizard::debug_log("ModulePanel -> getModules: module $modname added to otherModules list");
+ }
+ }
+
+ $::symbol{sms} = \@supportedModules;
+ $::symbol{oms} = \@otherModules;
+# PKI::RA::Wizard::dbg("oms: ". Dumper([@otherModules]));
+# PKI::RA::Wizard::dbg("sms: ". Dumper([@supportedModules]));
+
+ &PKI::RA::Wizard::debug_log("ModulePanel -> set sms, oms");
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/Modutil.pm b/base/ra/lib/perl/PKI/RA/Modutil.pm
new file mode 100755
index 000000000..82c66e87d
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/Modutil.pm
@@ -0,0 +1,262 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package PKI::RA::Modutil;
+
+
+sub new {
+ my $class = shift;
+ my ($dir) = @_;
+
+ if (! $dir) { die "no module directory provided\n"; }
+
+ my $self = {};
+
+ $self->{dir} = $dir;
+ $self->{modules} = makemodules($self);
+
+ bless $self, $class;
+ return $self;
+}
+
+sub exists {
+ my $self = shift;
+
+ return -e "$self->{dir}/secmod.db";
+}
+
+sub create {
+ my $self = shift;
+
+ my $mods = `modutil -force -dbdir '$self->{dir}' -nocertdb -create`;
+ return $mods;
+}
+
+use Data::Dumper;
+
+sub makemodules {
+ my $self = shift;
+ my $modules = {};
+
+ my $mods = `modutil -force -dbdir '$self->{dir}' -nocertdb -list`;
+ #my $mods = join "",<::DATA>;
+
+ #print "raw mods = $mods";
+
+ my (@modules) = (
+ $mods =~ /
+ ^ #beginning of a line
+ \s+ #some spaces
+ \d+\.\s* #some digits
+ (.*?) #lots of text
+ ((?=^\s*\d+)|(?=------)) #if we would next match some spaces and digits
+ /msxg );
+
+ @modules = grep /.+/ms, @modules;
+
+ foreach $module (@modules) {
+ #print "Module #$i:$module --\n";
+ $module = "modulename:$module";
+ my ($moduleheader, $rest) = (
+ $module =~ /
+ (.*status: .*?\n) # moduleheader
+ (\s*slot:.*) # slot
+ (?=\n(\n|$)) #empty line
+ /msxg );
+ #print "moduleheader: $moduleheader\n";
+ my $m = makehash($moduleheader);
+ $modules->{$m->{modulename}} = $m;
+ $m->{tokens} = {};
+
+ my @tokens = split "\n\n", $rest;
+
+
+
+# get summary slot info with: -list
+ foreach my $token (@tokens) {
+ #print "slottext: $slot\n";
+ my $slh = makehash($token);
+ $m->{tokens}->{$slh->{token}} = $slh;
+ }
+
+# get detailed slot info with: -list "modulename"
+
+ my $moduledetail = `modutil -force -dbdir '$self->{dir}' -nocertdb -list "$m->{modulename}" 2> /dev/null`;
+ my @details= split "\n\n", $moduledetail;
+ while ($details[0] !~ /.*Name:.*/) {
+ shift @details;
+ };
+ $m->{detail} = makehash(shift @details);
+ foreach $d (@details) {
+ my $sdh = makehash($d);
+ my $tokenname = $sdh->{"Token Name"};
+ $tokenname =~ s/\s+$//; # remove trailing spaces
+ if ($tokenname) {
+ $m->{tokens}->{$tokenname}->{detail} = $sdh;
+ }
+ }
+ $i++;
+
+ }
+ return $modules;
+}
+
+# input: a multi-list string with nv/pairs
+# return a hashtable reference
+sub makehash {
+ my $str = shift;
+ my $ht = { };
+ my @lines = split "\n", $str;
+ my $line;
+LINE:
+ foreach $line (@lines) {
+ if ($line =~ /Using database directory/) { next LINE; }
+ if ($line =~ /--------------/) { next LINE; }
+ my ($name, $value) = ($line =~ /^\s*(.*?):\s*(.*?)\s*$/);
+ if ($name) {
+ #print "name:$name\n";
+ #print "value:$value\n";
+ $ht->{$name} = $value;
+ }
+ }
+ return $ht;
+}
+
+sub getmodules {
+ my $self = shift;
+ #print "modules: ".$self->{modules}. "\n";
+ #print "keys: ".(join ",",keys %{$self->{modules}})."\n";
+ return keys %{$self->{modules}};
+}
+
+sub getmodule {
+ my $self = shift;
+ my $modulename = shift;
+
+ #print Dumper($self->{modules});
+ return $self->{modules}->{$modulename};
+}
+
+
+sub gettokens {
+ my $self = shift;
+ my $module = shift;
+
+ return keys %{$module->{tokens}};
+}
+
+sub gettoken {
+ my $self = shift;
+ my $token= shift;
+ foreach my $m (values %{$self->{modules}}) {
+ foreach $t (values %{$m->{tokens}}) {
+ #print join ",", keys %{$t};
+ #print Dumper($t->{detail});
+ if ($t->{detail}->{"Token Name"} eq $token) {
+ return $t;
+ }
+ }
+ }
+}
+
+
+
+package main;
+
+sub ::test {
+
+# initialize
+ my $modutil = new PKI::RA::Modutil(".");
+
+#make database if it doesn't exist
+ if (! $modutil->exists()) {
+ $modutil->create();
+ }
+
+#get an array of module names
+ my @mods = $modutil->getmodules();
+
+ print "Found ".@mods." pkcs#11 modules\n";
+
+#for each module...
+ foreach my $modname (@mods) {
+ my $module = $modutil->getmodule($modname);
+
+ print "Module: $modname\n";
+ print "Library: ".$module->{detail}->{"Library file"}."\n";
+ print "Other keys: ".(join ",", keys %{$module->{detail}})."\n";
+
+#find all the tokens in a module, e.g. each partition for a lunasa
+ foreach my $tokenname ($modutil->gettokens($module)) {
+ print " token: $tokenname\n";
+ my $token = $modutil->gettoken($tokenname);
+
+#dump out the information we have on the token
+ foreach my $key (keys %{$token}) {
+ print " token keys/values: $key: ".$token->{$key}."\n";
+ }
+ my @detailkeys = (keys %{$token->{detail}}) ;
+ print " token detail keys:". (join ",", @detailkeys)."\n";
+ print " token detail Manufacturer:". $token->{detail}->{Manufacturer}."\n";
+ print "\n";
+ }
+ print "\n";
+ }
+
+}
+
+# this is where 'main' starts
+
+if ($ARGV[0] eq "--test") {
+ ::test();
+}
+
+1;
+
+__DATA__
+Listing of PKCS #11 Modules
+-----------------------------------------------------------
+ 1. NSS Internal PKCS #11 Module
+ slots: 2 slots attached
+ status: loaded
+
+ slot: NSS Internal Cryptographic Services
+ token: NSS Generic Crypto Services
+
+ slot: NSS User Private Key and Certificate Services
+ token: NSS Certificate DB
+
+ 2. lunasa
+ library name: /usr/lunasa/lib/libCryptoki2.so
+ slots: 2 slots attached
+ status: loaded
+
+ slot: LunaNet Slot
+ token: lunasa1-ca
+
+ slot: LunaNet Slot
+ token: lunasa2-ca
+-----------------------------------------------------------
+
+
diff --git a/base/ra/lib/perl/PKI/RA/NamePanel.pm b/base/ra/lib/perl/PKI/RA/NamePanel.pm
new file mode 100755
index 000000000..c30715aa2
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/NamePanel.pm
@@ -0,0 +1,570 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use FileHandle;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+use PKI::RA::CertInfo;
+use URI::URL;
+use URI::Escape;
+
+package PKI::RA::NamePanel;
+$PKI::RA::NamePanel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+our $cert_req_header="-----BEGIN NEW CERTIFICATE REQUEST-----";
+our $cert_req_footer="-----END NEW CERTIFICATE REQUEST-----";
+our $cert_header="-----BEGIN CERTIFICATE-----";
+our $cert_footer="-----END CERTIFICATE-----";
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(12);
+ $self->{"getName"} = &PKI::RA::Common::r("Subject Names");
+ $self->{"vmfile"} = "namepanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("NamePanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("NamePanel: update");
+ my $instanceDir = $::config->get("service.instanceDir");
+
+ my $count = $q->param('urls');
+
+ &PKI::RA::Wizard::debug_log("NamePanel: update - selected ca= $count");
+
+ my $host = "";
+ my $https_ee_port = "";
+
+ my $useExternalCA = "off";
+ if ($count =~ /http/) {
+ my $info = new URI::URL($count);
+ $host = $info->host;
+ $https_ee_port = $info->port;
+ } else {
+ $host = $::config->get("preop.securitydomain.ca$count.host");
+ if ($host eq "") {
+ $useExternalCA = "on";
+ } else {
+ $https_ee_port = $::config->get("preop.securitydomain.ca$count.secureport");
+ &PKI::RA::Wizard::debug_log("NamePanel: update - host= $host, https_ee_port= $https_ee_port");
+ }
+ }
+ $::config->put("preop.certenroll.useExternalCA", $useExternalCA);
+
+ $::config->put("preop.ca.url", "https://" . $host . ":" . $https_ee_port);
+
+ my $tokenname = $::config->get("preop.module.token");
+ &PKI::RA::Wizard::debug_log("NamePanel: update got token name = $tokenname");
+ my $hw;
+ my $tk;
+
+ if (($tokenname eq "") || ($tokenname eq "NSS Certificate DB")) {
+ $hw = "";
+ $tk = "";
+ } else {
+ $hw = "-h $tokenname";
+ $tk = $tokenname.":";
+ }
+
+ # is nickname changed because of token (hardware) selection?
+ my $changed = "false";
+ foreach my $certtag (@PKI::RA::Wizard::certtags) {
+ &PKI::RA::Wizard::debug_log("NamePanel: update begins for certag= $certtag");
+ my $cert_dn = $q->param($certtag);
+ $::config->put("preop.cert.".$certtag.".dn", $cert_dn);
+ $::config->commit();
+
+ my $sslnickname = $::config->get("preop.cert.sslserver.nickname");
+ my $nickname = $q->param($certtag . "_nick");
+ if ($nickname ne "") {
+ &PKI::RA::Wizard::debug_log("NamePanel: update nickname for $certtag set to $nickname");
+ &PKI::RA::Wizard::debug_log("NamePanel: update nickname for $certtag being updated in config file");
+ $::config->put("preop.cert.".$certtag.".nickname", $nickname);
+ $::config->commit();
+ } else {
+ $nickname = $::config->get("preop.cert.$certtag.nickname");
+ if ($nickname eq "") {
+ $nickname = "RA ".$certtag." cert";
+ &PKI::RA::Wizard::debug_log("NamePanel: update nickname not found for $certtag -- try $nickname");
+ }
+ }
+
+ my $cert_request = $::config->get("preop.cert.$certtag.certreq");
+ if ($cert_request ne "") {
+ &PKI::RA::Wizard::debug_log("NamePanel: update do not generate new keys");
+ goto GEN_CERT;
+ }
+ &PKI::RA::Wizard::debug_log("NamePanel: update generate new keys");
+
+ # =====generate requests========
+ # getting new request should void old cert
+
+ my $file= "$instanceDir/conf/".$certtag."_cert.txt";
+ my $tmp = `rm $file`;
+
+ &PKI::RA::Wizard::debug_log("NamePanel: retrieving $tokenname from pwdconf");
+ my $token_pwd = $::pwdconf->get($tokenname);
+ &PKI::RA::Wizard::debug_log("NamePanel: creating pwfile");
+ open FILE, ">$instanceDir/conf/.pwfile";
+ system( "chmod 00660 $instanceDir/conf/.pwfile" );
+ $token_pwd =~ s/\n//g;
+ print FILE $token_pwd;
+ close FILE;
+
+ my $keytype = $::config->get("preop.cert.$certtag.keytype");
+ if ($keytype eq "") {
+ $keytype = "rsa";
+ }
+
+ my $select = $::config->get("preop.cert.$certtag.keysize.select");
+
+ my $keysize;
+
+ if ($keytype eq "rsa") {
+ $keysize = 2048;
+ } elsif ($keytype eq "ecc") {
+ $keysize = 256;
+ }
+
+ if (($select eq "") || ($select eq "default")) {
+ my $size = $::config->get("preop.cert.$certtag.keysize.size");
+ if ($size ne "") {
+ $keysize = $size;
+ }
+ } else {
+ my $size = $::config->get("preop.cert.$certtag.keysize.customsize");
+ if ($size ne "") {
+ $keysize = $size;
+ }
+ if (($keytype eq "ecc") && ($keysize ne 256)) {
+ &PKI::RA::Wizard::debug_log("NamePanel: update got keysize from config= $keysize changing to 256, the only supported ECC strength");
+ $keysize = 256;
+ }
+ }
+
+ &PKI::RA::Wizard::debug_log("NamePanel: update got key type $keytype");
+ my $req;
+ my $debug_req;
+ my $filename = "/tmp/random.$$";
+ `dd if\=/dev/urandom of\=\"$filename\" count\=256 bs\=1`;
+ if ($keytype eq "rsa") {
+ #XXX temporary
+ &PKI::RA::Wizard::debug_log("NamePanel: update "."certutil -R -s $cert_dn -k $keytype -g $keysize -d $instanceDir/alias $hw -f $instanceDir/conf/.pwfile -a -z $filename");
+ my $tmpfile = "/tmp/req$$";
+ system("certutil -R -s \"$cert_dn\" -k $keytype -g $keysize -d $instanceDir/alias $hw -f $instanceDir/conf/.pwfile -a -z $filename > $tmpfile");
+ $req = `cat $tmpfile`;
+ system("rm $tmpfile");
+ } elsif ($keytype eq "ecc") {
+ #only support curve nistp256 for now
+ my $tmpfile = "/tmp/req$$";
+ system("certutil -d $instanceDir/alias $hw -f $instanceDir/conf/.pwfile -R -s \"$cert_dn\" -k ec -q nistp256 -a -z $filename> $tmpfile");
+ $req = `cat $tmpfile`;
+ system("rm $tmpfile");
+ } else {
+ &PKI::RA::Wizard::debug_log("NamePanel: update unsupported keytype $keytype");
+ }
+ system("rm $filename");
+
+ my $save_line = 0;
+ my @req_a = split "\n", $req;
+ foreach my $line (@req_a) {
+ chomp( $line );
+ $line =~ s/ //g;
+ if ($line eq $cert_req_header) {
+ $save_line = 1;
+ } elsif( $line eq $cert_req_footer ) {
+ $save_line = 0;
+ last;
+ } elsif( $save_line == 1 ) {
+ $cert_request .= "$line";
+ }
+ }
+ &PKI::RA::Wizard::debug_log("NamePanel: update putting cert_request in CS.cfg: $cert_request");
+ $::config->put("preop.cert.$certtag.certreq", $cert_request);
+ $::config->commit();
+
+GEN_CERT:
+# =====request for certs========
+# see if there is an existing cert
+
+ my $cert = $::config->get("preop.cert.$certtag.cert");
+ my $sdom = $::config->get("config.sdomainEEURL");
+ my $sdom_url = new URI::URL($sdom);
+
+ if (($useExternalCA eq "on") && ($certtag ne "subsystem")) {
+ &PKI::RA::Wizard::debug_log("NamePanel: update External CA selected");
+ if ($cert eq "") {
+ &PKI::RA::Wizard::debug_log("NamePanel: update no cert found...need manual enrollment");
+ }
+ } else {
+ if ($cert eq "") {
+ &PKI::RA::Wizard::debug_log("NamePanel: update External CA not selected...need automatic enrollment");
+
+ my $machineName = $::config->get("service.machineName");
+ my $securePort = $::config->get("service.securePort");
+ my $session_id = $::config->get("preop.sessionID");
+
+ if ($cert_request ne "") {
+ &PKI::RA::Wizard::debug_log("NamePanel: update found existing request: $cert_request");
+ } else {
+ &PKI::RA::Wizard::debug_log("NamePanel: update existing request not found");
+ #something is wrong...no request, no cert
+ goto DONE;
+ return $cert;
+ }
+
+ my $instanceID = $::config->get("service.instanceID");
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $db_password = "";
+ &PKI::RA::Wizard::debug_log("NamePanel: greping password");
+
+ my $tmpfile = "/tmp/grep$$";
+ system ("grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10- > $tmpfile");
+ $db_password = `cat $tmpfile`;
+ $db_password =~ s/\n$//g;
+ system("rm $tmpfile");
+
+ my $profile_id = $::config->get("preop.cert.$certtag.profile");
+ &PKI::RA::Wizard::debug_log("NamePanel: profileId=" . $profile_id);
+ my $requestor_name = "RA-" . $machineName . "-" . $securePort;
+ my $params = "profileId=" . $profile_id . "&" .
+ "cert_request_type=" . "pkcs10" . "&" .
+ "requestor_name=" . $requestor_name . "&" .
+ "cert_request=" .
+ URI::Escape::uri_escape("$cert_request") . "&" .
+ "xmlOutput=true" . "&" .
+ "sessionID=" . $session_id . "&" .
+ "auth_hostname=" . $sdom_url->host . "&" .
+ "auth_port=" . $sdom_url->port;
+
+ if ($certtag eq "subsystem") {
+ $host = $sdom_url->host;
+ $https_ee_port = $sdom_url->port;
+ }
+ if ($changed eq "true") {
+$req = "/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"$token_pwd\" -v -n \"$sslnickname\" -r \"/ca/ee/ca/profileSubmit\" $host:$https_ee_port";
+$debug_req = "/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"(sensitive)\" -v -n \"$sslnickname\" -r \"/ca/ee/ca/profileSubmit\" $host:$https_ee_port";
+ } else {
+$req = "/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"$db_password\" -v -n \"$sslnickname\" -r \"/ca/ee/ca/profileSubmit\" $host:$https_ee_port";
+$debug_req = "/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"(sensitive)\" -v -n \"$sslnickname\" -r \"/ca/ee/ca/profileSubmit\" $host:$https_ee_port";
+ }
+
+ &PKI::RA::Wizard::debug_log("debug_req = " . $debug_req);
+ my $content = `$req`;
+ &PKI::RA::Wizard::debug_log("content = " . $content);
+
+ $content =~ /(\<XMLResponse\>.*\<\/XMLResponse\>)/;
+ $content = $1;
+
+ if ($content eq "") {
+ $::symbol{errorString} = "CA returned no response. Please check that the CA is available and also check the host's firewall settings.";
+ return 0;
+ }
+
+ my $parser = XML::Simple->new();
+ &PKI::RA::Wizard::debug_log("NamePanel: response content= " . $content);
+ my $response = $parser->XMLin($content);
+ my $status = $response->{Status};
+ if ($status ne "0") {
+ my $error = $response->{Error};
+ &PKI::RA::Wizard::debug_log("NamePanel: Error = $error");
+ $::symbol{errorString} = "CA response: $error. Please check previous related panels." . " Please check that the CA is available and also check the host's firewall settings.";
+ return 0;
+ }
+ $cert = $response->{Requests}->{Request}->{b64};
+ &PKI::RA::Wizard::debug_log("NamePanel: new cert generated= " . $cert);
+
+# my $reqid = $response->{Requests}->{Request}->{Id};
+# $::config->put("preop.admincert.requestId.0", $reqid);
+# my $sn = $response->{Requests}->{Request}->{serialno};
+# $::config->put("preop.admincert.serialno.0", $sn);
+# $::config->commit();
+
+ &PKI::RA::Wizard::debug_log("NamePanel: update putting cert in CS.cfg: $cert");
+ $::config->put("preop.cert.$certtag.cert", $cert);
+ $::config->commit();
+
+ } else {
+ # cert is not null
+ &PKI::RA::Wizard::debug_log("NamePanel: update External CA not selected. Cert found...no need for enrollment");
+ }
+
+# write cert to file so certutil can import
+ my $cert_fn = "$instanceDir/conf/".$certtag."_cert.txt";
+ open FILE, "> $cert_fn";
+ print FILE $cert_header."\n".$cert."\n".$cert_footer;
+ close FILE;
+
+ # import cert, whether it was imported before or not
+ my $nickname = $::config->get("preop.cert.$certtag.nickname");
+ if ($nickname eq "") {
+ #XXX
+ $nickname = "RA ".$certtag." cert";
+ &PKI::RA::Wizard::debug_log("NamePanel: update nickname not found for $certtag -- try $nickname");
+ }
+
+ if ($certtag ne "sslserver") {
+ &PKI::RA::Wizard::debug_log("NamePanel: update: try to delete existing cert $nickname, if any....ok if it fails");
+ $tmp = `certutil -d $instanceDir/alias -D -n "$nickname"`;
+ $tmp = `certutil -d $instanceDir/alias -D $hw -f $instanceDir/conf/.pwfile -n "$tk$nickname"`;
+ } else {
+ &PKI::RA::Wizard::debug_log("NamePanel: update: try to delete existing cert $sslnickname, if any....ok if it fails");
+ $tmp = `certutil -d $instanceDir/alias -D -n "$sslnickname"`;
+ $tmp = `certutil -d $instanceDir/alias -D $hw -f $instanceDir/conf/.pwfile -n "$tk$sslnickname"`;
+ }
+
+ &PKI::RA::Wizard::debug_log("NamePanel: update: try to import cert from $cert_fn");
+ $tmp = `certutil -d $instanceDir/alias $hw -f $instanceDir/conf/.pwfile -A -n "$nickname" -t "u,u,u" -a -i $cert_fn`;
+ # changed the cert, need to change nickname too, if necessary
+ if ($hw ne "") {
+ if ($certtag eq "sslserver") {
+ if ($changed eq "false") {
+ $::config->put("preop.cert.$certtag.nickname", "$tk$nickname");
+ }
+ $changed = "true";
+ } elsif ($certtag eq "subsystem") {
+ &PKI::RA::Wizard::debug_log("NamePanel: update: subsystem nickname changed");
+ $::config->put("preop.cert.$certtag.nickname", "$tk$nickname");
+ $::config->put("conn.ca1.clientNickname", "$tk$nickname");
+ $::config->put("conn.drm1.clientNickname", "$tk$nickname");
+ $::config->put("conn.tks1.clientNickname", "$tk$nickname");
+ $::config->put( "ra.cert.subsystem.nickname", "$tk$nickname");
+ } else {
+ &PKI::RA::Wizard::debug_log("NamePanel: update: $certtag nickname changed");
+ $::config->put("preop.cert.$certtag.nickname", "$tk$nickname");
+ }
+ $::config->commit();
+ } else {
+ if ($certtag eq "subsystem") {
+ # setting these just in case the subsystem nickname changed.
+ &PKI::RA::Wizard::debug_log("NamePanel: update: setting in case the subsystem nickname changed");
+ $::config->put("conn.ca1.clientNickname", "$nickname");
+ $::config->put("conn.drm1.clientNickname", "$nickname");
+ $::config->put("conn.tks1.clientNickname", "$nickname");
+ $::config->put("ra.cert.subsystem.nickname", "$nickname");
+ }
+ $::config->commit();
+ }
+
+ &PKI::RA::Wizard::debug_log("NamePanel: update: done importing cert: $tk$nickname");
+ $tmp = `rm $cert_fn`;
+ }
+ }
+
+DONE:
+ &PKI::RA::Wizard::debug_log("NamePanel: removing pwfile");
+ my $tmp = `rm $instanceDir/conf/.pwfile`;
+ return 1;
+}
+
+sub readFile
+{
+ my $fn = $_[0];
+ open FILE, "< $fn" or return "";
+ my $content = join "",<FILE>;
+ close FILE;
+
+ return $content;
+}
+
+use Data::Dumper;
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("NamePanel: display");
+
+ my $domain_name = $::config->get("preop.securitydomain.name");
+ if ($domain_name eq "") {
+ $domain_name = "RA Domain";
+ }
+ my $machine_name = $::config->get("service.machineName");
+ my $instance_id = $::config->get("service.instanceID");
+
+ my $i = 0;
+ foreach my $certtag (@PKI::RA::Wizard::certtags) {
+ &PKI::RA::Wizard::debug_log("NamePanel: display certtag=$certtag");
+ my $cert_dn = $::config->get("preop.cert.".$certtag.".dn");
+ if ($cert_dn eq "") {
+ if ($certtag eq "subsystem") {
+ $cert_dn = "CN=RA Subsystem, " .
+ "OU=" . $instance_id . ", " .
+ "O=" . $domain_name;
+ } elsif ($certtag eq "sslserver") {
+ $cert_dn ="CN=" . $machine_name . ", " .
+ "OU=" . $instance_id . ", " .
+ "O=" . $domain_name;
+ } else {
+ &PKI::RA::Wizard::debug_log("NamePanel: display other certtag=$certtag");
+ $cert_dn = $certtag;
+ }
+ $::config->put("preop.cert.".$certtag.".dn", $cert_dn);
+ $::config->commit();
+ } else {
+ if (!($cert_dn =~ /O=/)) {
+ $cert_dn .= ", O=" . $domain_name;
+ $::config->put("preop.cert.".$certtag.".dn", $cert_dn);
+ $::config->commit();
+ }
+ }
+
+ my $name = $::config->get("preop.cert.".$certtag.".userfriendlyname");
+ if ($name eq "") {
+ $name = $certtag."Cert ".$instance_id;
+ $::config->put("preop.cert.".$certtag.".userfriendlyname", $name);
+ $::config->commit();
+ }
+
+ my $cert = new PKI::RA::CertInfo($name,
+ $cert_dn, $certtag);
+ $::symbol{certs}[$i++] = $cert;
+ }
+
+ &PKI::RA::Wizard::debug_log("NamePanel: getting CA info");
+ $::symbol{urls} = [];
+ my $count = 0;
+
+ while (1) {
+ my $host = $::config->get("preop.securitydomain.ca$count.host");
+ if ($host eq "") {
+ goto DONE;
+ }
+ my $https_ee_port = $::config->get("preop.securitydomain.ca$count.secureport");
+ my $name = $::config->get("preop.securitydomain.ca$count.subsystemname");
+ my $item = $name . " - https://" . $host . ":" . $https_ee_port;
+ $::symbol{urls}[$count++] = $item;
+
+ }
+DONE:
+
+ $::symbol{urls}[$count++] = "External CA";
+ $::symbol{urls_size} = $count+1;
+
+ return 1;
+}
+
+
+# arg0 filename containing certificate request
+# return certificate request plus header and footer
+sub extract_cert_req_from_file
+{
+ my $save_line = 0;
+
+ my $filename = $_[0];
+
+ my $fd = new FileHandle;
+
+ my $cert_request = "";
+
+ $fd->open( "<$filename" ) or die "Could not open '$filename'!\n";
+
+ while( <$fd> )
+ {
+ my $line = $_;
+ chomp( $line );
+
+ if( $line eq $cert_req_header ) {
+ $save_line = 1;
+ $cert_request .= "$line\n";
+ } elsif( $line eq $cert_req_footer ) {
+ $cert_request .= "$line\n";
+ $save_line = 0;
+ last;
+ } elsif( $save_line == 1 ) {
+ $cert_request .= "$line\n";
+ }
+ }
+
+ $fd->close();
+
+ return $cert_request;
+}
+
+# arg0 message containing certificate request
+# return certificate request sans header and footer
+sub extract_cert_req_from_file_sans_header_and_footer
+{
+ my $filename = $_[0];
+ my $save_line = 0;
+
+ my $fd = new FileHandle;
+
+ my $cert_request = "";
+
+ $fd->open( "<$filename" ) or die "Could not open '$filename'!\n";
+
+ while( <$fd> )
+ {
+ my $line = $_;
+ chomp( $line );
+
+ if( $line eq $cert_req_header ) {
+ $save_line = 1;
+ } elsif( $line eq $cert_req_footer ) {
+ $save_line = 0;
+ last;
+ } elsif( $save_line == 1 ) {
+ $cert_request .= "$line\n";
+ }
+ }
+
+ $fd->close();
+
+ return $cert_request;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/ReqCertInfo.pm b/base/ra/lib/perl/PKI/RA/ReqCertInfo.pm
new file mode 100755
index 000000000..51c22cd24
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/ReqCertInfo.pm
@@ -0,0 +1,235 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+
+package PKI::RA::ReqCertInfo;
+$PKI::RA::ReqCertInfo::VERSION = '1.00';
+
+our $cert_req_header="-----BEGIN NEW CERTIFICATE REQUEST-----";
+our $cert_req_footer="-----END NEW CERTIFICATE REQUEST-----";
+our $cert_header="-----BEGIN CERTIFICATE-----";
+our $cert_footer="-----END CERTIFICATE-----";
+
+sub new {
+ my ($class, $name, $dn, $tag) = @_;
+ my $self = {};
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: start new");
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: creating name: $name, dn: $dn, tag: $tag");
+
+ $self->{"getUserFriendlyName"} = \&get_user_friendly_name;
+ $self->{"getCertTag"} = \&get_cert_tag;
+ $self->{"getCert"} = \&get_cert;
+ $self->{"getCertpp"} = \&get_cert_pp;
+ $self->{"getRequest"} = \&get_request;
+ $self->{"getDN"} = \&get_dn;
+ $self->{"useDefaultKey"} = \&use_default_key;
+ $self->{"getCustomKeysize"} = \&get_custom_keysize;
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: end new");
+
+ $self->{name} = $name;
+ $self->{dn} = $dn;
+ $self->{tag} = $tag;
+
+ bless $self, $class;
+ return $self;
+}
+
+sub get_user_friendly_name
+{
+ my ($self) = @_;
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: get_user_friendly_name");
+ return $self->{name};
+}
+
+sub readFile
+{
+ my $fn = $_[0];
+ open FILE, "< $fn" or return "";
+ my $content = join "",<FILE>;
+ close FILE;
+
+ return $content;
+}
+
+sub wrap_lines
+{
+ my $lines = shift;
+ my $temp ;
+ foreach my $line (split "\n", $lines) {
+ if (length $line > 59) {
+ $line =~ s/(.{0,60})/$1\n/g;
+ }
+ # get rid of a line that is just an empty newline
+ $line =~ s/^\n$//gms;
+ $temp .= $line;
+ }
+ # collapse multiple newlines into one
+ $temp =~ s/\n+/\n/gms;
+ $temp =~ s/\n$//gms;
+ $temp;
+
+}
+
+sub get_request
+{
+ my ($self) = @_;
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: get_request");
+ # first, try to see if request has been made before
+# my $req = readFile( "/var/lib/pki-ra/conf/$self->{tag}_cert_request.txt");
+
+ my $req = $::config->get("preop.cert.$self->{tag}.certreq");
+
+ $req = wrap_lines($req);
+
+ if ($req ne "") {
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: get_request found existing request");
+ return $cert_req_header."\n".$req."\n".$cert_req_footer;;
+ } else {
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: get_request existing request not found");
+ }
+
+ return $req;
+}
+
+sub get_cert
+{
+ my ($self) = @_;
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: get_cert");
+# see if there is an existing cert
+# my $cert = readFile("/var/lib/pki-ra/conf/".$self->{tag}."_cert.txt");
+ my $cert = $::config->get("preop.cert.$self->{tag}.cert");
+
+ $cert = wrap_lines($cert);
+ if ($cert ne "") {
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: get_cert found existing cert");
+ return $cert_header."\n".$cert."\n".$cert_footer;;
+ } else {
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: get_cert existing cert not found");
+ }
+ if ($cert eq "") {
+ $cert = "...paste certificate here...";
+ }
+
+
+ return $cert;
+}
+
+sub get_cert_pp
+{
+ my ($self) = @_;
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: get_cert_pp");
+ my $instanceDir = $::config->get("service.instanceDir");
+
+ my $hw;
+ my $tokenname = $::config->get("preop.module.token");
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: update got token name = $tokenname");
+
+ if (($tokenname eq "") || ($tokenname eq "NSS Certificate DB")) {
+ $hw = "";
+ } else {
+ $hw = "-h $tokenname";
+ }
+
+ my $token_pwd = $::pwdconf->get($tokenname);
+ open FILE, ">$instanceDir/conf/.pwfile";
+ system( "chmod 00660 $instanceDir/conf/.pwfile" );
+ $token_pwd =~ s/\n//g;
+ print FILE $token_pwd;
+ close FILE;
+
+ my $nickname = $::config->get("preop.cert.$self->{tag}.nickname");
+ if ($nickname eq "") {
+#XXX
+ $nickname = "RA ".$self->{tag}." cert";
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: get_cert_pp nickname not found for $self->{tag} -- try $nickname");
+ }
+ my $certpp="";
+# my $found = -e "/var/lib/pki-ra/conf/$self->{tag}_cert.txt";
+ my $cert = $::config->get("preop.cert.$self->{tag}.cert");
+
+ if ($cert ne "") {
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: get_cert_pp found request, ready to get prettyprint");
+ my $tmp = `certutil -d $instanceDir/alias $hw -f $instanceDir/conf/.pwfile -n "$nickname" -L > $instanceDir/conf/$self->{tag}_cert_pp.txt`;
+ $certpp = readFile("$instanceDir/conf/$self->{tag}_cert_pp.txt");
+ $certpp =~ s/"//g;
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: get_cert_pp pp=$certpp");
+ $tmp =`rm $instanceDir/conf/$self->{tag}_cert_pp.txt`;
+ } else {
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: get_cert_pp cert not found, will not get prettyprint");
+ }
+ my $tmp = `rm $instanceDir/conf/.pwfile`;
+
+ return $certpp;
+}
+
+sub get_cert_tag
+{
+ my ($self) = @_;
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: get_cert_tag");
+ return $self->{tag};
+}
+
+sub get_dn
+{
+ my ($self) = @_;
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: get_cert_dn");
+ return $self->{dn};
+}
+
+sub use_default_key
+{
+ my ($self) = @_;
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: use_default_key");
+ my $select = $::config->get("preop.cert.$self->{tag}.keysize.select");
+ if ($select ne "") {
+ if ($select eq "custom") {
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: use_default_key from config = $select returning 0");
+ return 0;
+ }
+ }
+
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: use_default_key returning 1");
+ return 1;
+}
+
+sub get_custom_keysize
+{
+ my ($self) = @_;
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: get_custom_keysize");
+ my $keysize = $::config->get("preop.cert.$self->{tag}.keysize.customsize");
+ if ($keysize ne "") {
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: get_custom_keysize from config = $keysize");
+ return $keysize;
+ } else {
+ &PKI::RA::Wizard::debug_log("ReqCertInfo: get_custom_keysize not from config");
+ }
+ return 2048;
+}
+
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/SecurityDomainPanel.pm b/base/ra/lib/perl/PKI/RA/SecurityDomainPanel.pm
new file mode 100755
index 000000000..114b19ef0
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/SecurityDomainPanel.pm
@@ -0,0 +1,199 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+use URI::URL;
+use XML::Simple;
+use Data::Dumper;
+
+package PKI::RA::SecurityDomainPanel;
+$PKI::RA::SecurityDomainPanel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(1);
+ $self->{"getName"} = &PKI::RA::Common::r("Security Domain");
+ $self->{"vmfile"} = "securitydomainpanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("SecurityPanel: validate");
+
+ return 1;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub pingCS
+{
+ my( $instanceDir ) = $_[0];
+ my( $db_password ) = $_[1];
+ my( $nickname ) = $_[2];
+ my( $hostname ) = $_[3];
+ my( $port ) = $_[4];
+
+ my $content = `/usr/bin/sslget -d $instanceDir/alias -p $db_password -v -r "/ca/admin/ca/getStatus" $hostname:$port`;
+ if( "$content" eq "" ) {
+ return 0;
+ } else {
+ $content =~ /(\<XMLResponse\>.*\<\/XMLResponse\>)/;
+ $content = $1;
+
+ my $parser = XML::Simple->new();
+ my $response = $parser->XMLin($content);
+ my $state = $response->{State};
+
+ if( "$state" eq "1" ) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("SecurityPanel: display");
+ $::symbol{panelname} = "Security Domain";
+ $::symbol{sdomainName} = "Security Domain";
+
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $db_password =~ s/\n$//g;
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+ my $hostname = $::config->get("service.machineName");
+ my $default_https_admin_port = 9445;
+
+ # check to see if "default" security domain exists on local machine
+ my $status = pingCS( $instanceDir,
+ $db_password,
+ $nickname,
+ $hostname,
+ $default_https_admin_port );
+ if( "$status" eq "1" ) {
+ # "default" security domain exists on local machine;
+ # fill "sdomainURL" in with "default" security domain
+ # as an initial "guess"
+ $::symbol{sdomainURL} = "https://" . $hostname . ":"
+ . $default_https_admin_port;
+ } else {
+ # "default" security domain does NOT exist on local machine;
+ # leave "sdomainURL" blank
+ $::symbol{sdomainURL} = "";
+ }
+
+ $::symbol{sdomainAdminURL} = "https://" . $hostname . ":"
+ . $default_https_admin_port;
+
+ my $initDaemon = "pki-cad";
+ my $initCommand = "";
+ my $instanceID ="&lt;security_domain_instance_name&gt; ";
+ if( $^O eq "linux" ) {
+ $initCommand = "/sbin/service $initDaemon";
+ } else {
+ ## default case: e. g. - ( $^O eq "solaris" )
+ $initCommand = "/etc/init.d/$initDaemon";
+ }
+ $::symbol{initCommand} = $initCommand;
+ $::symbol{instanceID} = $instanceID;
+ return 1;
+}
+
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("SecurityPanel: update");
+ my $sdomainURL = $q->param("sdomainURL");
+
+ if ($sdomainURL eq "") {
+ &PKI::RA::Wizard::debug_log("SecurityPanel: sdomainURL has not been specified!");
+ $::symbol{errorString} = "Security Domain HTTPS has not been specified!";
+ return 0;
+ }
+
+ my $sdomainURL_info = new URI::URL($sdomainURL);
+
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $db_password =~ s/\n$//g;
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+ my $hostname = $sdomainURL_info->host;
+ my $https_admin_port = $sdomainURL_info->port;
+
+ # check to see if "default" security domain exists on local machine
+ my $status = pingCS( $instanceDir,
+ $db_password,
+ $nickname,
+ $hostname,
+ $https_admin_port );
+ if( "$status" ne "1" ) {
+ # invalid security domain specified
+ &PKI::RA::Wizard::debug_log("SecurityPanel: sdomainURL not found");
+ $::symbol{errorString} = "Security Domain HTTPS Admin URL not found";
+ return 0;
+ }
+
+ # save urls in CS.cfg
+ &PKI::RA::Wizard::debug_log("SecurityPanel: sdomainURL=" . $sdomainURL);
+ $::config->put("config.sdomainAdminURL", $sdomainURL);
+
+ # Add values necessary for 'pkiremove' . . .
+ $::config->put("securitydomain.select", "existing");
+ $::config->put("securitydomain.host", $sdomainURL_info->host);
+ $::config->put("securitydomain.httpsadminport", $sdomainURL_info->port);
+ $::config->commit();
+
+ return 1;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/SizePanel.pm b/base/ra/lib/perl/PKI/RA/SizePanel.pm
new file mode 100755
index 000000000..f55dc41e9
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/SizePanel.pm
@@ -0,0 +1,245 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+use PKI::RA::CertInfo;
+
+package PKI::RA::SizePanel;
+$PKI::RA::SizePanel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(11);
+ $self->{"getName"} = &PKI::RA::Common::r("Key Pairs");
+ $self->{"vmfile"} = "sizepanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("SizePanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("SizePanel: update");
+
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $done = $::config->get("preop.SizePanel.done");
+ my $genKeyPair = $q->param('generateKeyPair');
+ &PKI::RA::Wizard::debug_log("SizePanel: update generateKeyPair value=$genKeyPair");
+ if ($done eq "true") {
+ if ($genKeyPair eq "") {
+ &PKI::RA::Wizard::debug_log("SizePanel: update generateKeyPair value not found, turn to off");
+ $genKeyPair = "off";
+ }
+ } else {
+ # firstime should always generate keys
+ $genKeyPair = "on";
+ }
+
+ foreach my $certtag (@PKI::RA::Wizard::certtags) {
+ my $select = $q->param($certtag.'_choice');
+ my $keytype = $q->param($certtag.'_keytype');
+ my $size = $q->param($certtag.'_custom_size');
+
+ &PKI::RA::Wizard::debug_log("SizePanel: update $certtag _choice=$select $certtag _keytype=$keytype customsize= $size");
+
+ $::config->put("preop.keysize.select", $select);
+ $::config->put("preop.cert.".$certtag.".keysize.select", $select);
+
+ if (! isSupportedSize($keytype, $size)) {
+ &PKI::RA::Wizard::debug_log("SizePanel: update size $size not supported");
+ return 0;
+ }
+ $::config->put("preop.cert.".$certtag.".keysize.customsize", $size);
+ $::config->put("preop.cert.".$certtag.".keytype", $keytype);
+
+ if ($select eq "default") {
+ my $defaultSize = getDefaultSize($keytype);
+ &PKI::RA::Wizard::debug_log("SizePanel: update in default, defaultsize = $defaultSize");
+ $::config->put("preop.keysize.customsize", $defaultSize);
+ $::config->put("preop.keysize.size", $defaultSize);
+ $::config->put("preop.cert.".$certtag.".keysize.size", $defaultSize);
+
+ } elsif ($select eq "custom") {
+ &PKI::RA::Wizard::debug_log("SizePanel: update in custom, customsize = $size");
+ $::config->put("preop.keysize.size", $size);
+ $::config->put("preop.cert.".$certtag.".keysize.size", $size);
+ }
+
+ if ($genKeyPair eq "on") {
+ $::config->put("preop.cert.".$certtag.".certreq", "");
+ $::config->put("preop.cert.".$certtag.".cert", "");
+ }
+ }
+#XXX should have better error checking to work better
+ $done = $::config->put("preop.SizePanel.done", "true");
+ $::config->commit();
+
+ return 1;
+}
+
+sub getDefaultSize {
+ my $keytype = $_[0];
+
+ if ($keytype eq "ecc") {
+ return 256;
+ } elsif ($keytype eq "rsa") {
+ return 2048;
+ }
+
+ $::symbol{errorString} = "Unsupported keytype $keytype";
+ return 0;
+}
+
+sub isSupportedSize {
+ my $keytype = $_[0];
+ my $size = $_[1];
+
+ if (($keytype eq "ecc") && ($size ne "256")) {
+ &PKI::RA::Wizard::debug_log("SizePanel: isSupportedSize ECC only supports size 256");
+ $::symbol{errorString} = "Unsupported Size $size. ECC only supports size 256";
+ return 0;
+ }
+
+ if (($size eq "256") || ($size eq "512") || ($size eq "1024") ||
+ ($size eq "2048") || ($size eq "4096")) {
+ return 1;
+ }
+ # wrong size
+ $::symbol{errorString} = "Unsupported Size $size. RSA only supports sizes 256, 512, 1024, 2048, and 4096";
+ return 0;
+}
+
+sub display
+{
+ my ($q) = @_;
+
+ &PKI::RA::Wizard::debug_log("SizePanel: display");
+
+ my $done = $::config->get("preop.SizePanel.done");
+ &PKI::RA::Wizard::debug_log("SizePanel: display is panel done? $done");
+ if ($done eq "true") {
+ $::symbol{firsttime} = "false";
+ } else {
+ $::symbol{firsttime} = "true";
+ }
+
+ my $domain_name = $::config->get("preop.securitydomain.name");
+ if ($domain_name eq "") {
+ $domain_name = "RA Domain";
+ }
+
+ my $machine_name = $::config->get("service.machineName");
+ my $instance_id = $::config->get("service.instanceID");
+
+ my $i = 0;
+ foreach my $certtag (@PKI::RA::Wizard::certtags) {
+ my $cert_dn = $::config->get("preop.cert.".$certtag.".dn");
+ if ($cert_dn eq "") {
+ if ($certtag eq "subsystem") {
+ $cert_dn = "CN=RA Subsystem, " .
+ "OU=" . $instance_id . ", " .
+ "O=" . $domain_name;
+ } elsif ($certtag eq "sslserver") {
+ $cert_dn ="CN=" . $machine_name . ", " .
+ "OU=" . $instance_id . ", " .
+ "O=" . $domain_name;
+ } else {
+ $cert_dn = $certtag;
+ }
+ }
+ my $name = $::config->get("preop.cert.".$certtag.".userfriendlyname");
+ if ($name eq "") {
+ $name = $certtag."Cert ".$instance_id;
+ }
+ my $cert = new PKI::RA::CertInfo($name,
+ $cert_dn, $certtag);
+ $::symbol{certs}[$i++] = $cert;
+ }
+
+ #for "common key settings"
+ my $select = $::config->get("preop.keysize.select");
+ if (($select eq "") || ($select eq "default")) {
+ $::symbol{select} = "default";
+ } else {
+ &PKI::RA::Wizard::debug_log("SizePanel: display keysize select= $select");
+ $::symbol{select} = $select;
+ }
+ my $default_size = $::config->get("preop.keysize.size");
+ if ($default_size eq "") {
+ $::symbol{default_keysize} = 2048;
+ } else {
+ $::symbol{default_keysize} = $default_size;
+ }
+
+ my $default_ecc_size = $::config->get("preop.keysize.ecc.size");
+ if ($default_ecc_size eq "") {
+ $::symbol{default_ecc_keysize} = 256;
+ } else {
+ $::symbol{default_ecc_keysize} = $default_ecc_size;
+ }
+
+ my $custom_size = $::config->get("preop.keysize.customsize");
+ if ($custom_size eq "") {
+ $::symbol{custom_size} = 2048;
+ } else {
+ $::symbol{custom_size} = $default_size;
+ }
+
+
+ return 1;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/SubsystemTypePanel.pm b/base/ra/lib/perl/PKI/RA/SubsystemTypePanel.pm
new file mode 100755
index 000000000..3d946bca0
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/SubsystemTypePanel.pm
@@ -0,0 +1,142 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+
+package PKI::RA::SubsystemTypePanel;
+$PKI::RA::SubsystemTypePanel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(3);
+ $self->{"getName"} = &PKI::RA::Common::r("Subsystem Type");
+ $self->{"vmfile"} = "createsubsystempanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("SubsystemTypePanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("SubsystemTypePanel: update");
+ $::symbol{systemname} = "Registration Authority ";
+ $::symbol{subsystemName} = "Registration Authority";
+ $::symbol{fullsystemname} = "Registration Authority";
+ $::symbol{machineName} = "localhost";
+ $::symbol{http_port} = "12888";
+ $::symbol{https_port} = "12889";
+ $::symbol{non_clientauth_https_port} = "12890";
+ $::symbol{check_clonesubsystem} = " ";
+ $::symbol{check_newsubsystem} = " ";
+ $::symbol{disableClone} = 1;
+
+ my $subsystemName = $q->param('subsystemName');
+ $::config->put("preop.subsystem.name", $subsystemName);
+ $::config->commit();
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("SubsystemTypePanel: display");
+ $::symbol{systemname} = "Registration Authority ";
+ $::symbol{subsystemName} = "Registration Authority";
+ $::symbol{fullsystemname} = "Registration Authority ";
+
+ my $machineName = $::config->get("service.machineName");
+ my $unsecurePort = $::config->get("service.unsecurePort");
+ my $securePort = $::config->get("service.securePort");
+ my $non_clientauth_securePort = $::config->get("service.non_clientauth_securePort");
+
+
+ $::symbol{machineName} = $machineName;
+ $::symbol{http_port} = $unsecurePort;
+ $::symbol{https_port} = $securePort;
+ $::symbol{non_clientauth_https_port} = $non_clientauth_securePort;
+ $::symbol{check_clonesubsystem} = "";
+ $::symbol{check_newsubsystem} = "checked ";
+
+ my $session_id = $q->param("session_id");
+ $::config->put("preop.sessionID", $session_id);
+ $::config->commit();
+
+ $::symbol{urls} = [];
+ my $count = 0;
+ while (1) {
+ my $host = $::config->get("preop.securitydomain.ra$count.host");
+ if ($host eq "") {
+ goto DONE;
+ }
+ my $port = $::config->get("preop.securitydomain.ra$count.non_clientauth_secure_port");
+ my $name = $::config->get("preop.securitydomain.ra$count.subsystemname");
+ unshift(@{$::symbol{urls}}, "https://" . $host . ":" . $port);
+ $count++;
+ }
+DONE:
+ $::symbol{urls_size} = $count;
+
+# if ($count == 0) {
+ $::symbol{disableClone} = 1;
+# }
+
+ # XXX - how to deal with urls
+ return 1;
+}
+
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/TKSInfoPanel.pm b/base/ra/lib/perl/PKI/RA/TKSInfoPanel.pm
new file mode 100755
index 000000000..ddf1124a9
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/TKSInfoPanel.pm
@@ -0,0 +1,134 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+use URI::URL;
+
+package PKI::RA::TKSInfoPanel;
+$PKI::RA::TKSInfoPanel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(5);
+ $self->{"getName"} = &PKI::RA::Common::r("TKS Information");
+ $self->{"vmfile"} = "tksinfopanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("TKSInfoPanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("TKSInfoPanel: update");
+
+ my $count = $q->param('urls');
+
+ my $instanceID = $::config->get("service.instanceID");
+
+ my $host = "";
+ my $https_agent_port = "";
+ if ($count =~ /http/) {
+ my $info = new URI::URL($count);
+ $host = $info->host;
+ $https_agent_port = $info->port;
+ if (($host eq "") || ($https_agent_port eq "")) {
+ $::symbol{errorString} = "no TKS found. CA, TKS and optionally DRM must be installed prior to RA installation";
+ return 0;
+ }
+ $::config->put("preop.tksinfo.select", $count);
+ } else {
+ $host = $::config->get("preop.securitydomain.tks$count.host");
+ $https_agent_port = $::config->get("preop.securitydomain.tks$count.secureagentport");
+ if (($host eq "") || ($https_agent_port eq "")) {
+ $::symbol{errorString} = "no TKS found. CA, TKS and optionally DRM must be installed prior to RA installation";
+ return 0;
+ }
+ $::config->put("preop.tksinfo.select", "https://$host:$https_agent_port");
+ }
+ my $subsystemCertNickName = $::config->get("preop.cert.subsystem.nickname");
+ $::config->put("conn.tks1.clientNickname", $subsystemCertNickName);
+ $::config->put("conn.tks1.hostport", $host . ":" . $https_agent_port);
+ $::config->commit();
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("TKSInfoPanel: display");
+ $::symbol{urls} = [];
+ my $count = 0;
+ while (1) {
+ my $host = $::config->get("preop.securitydomain.tks$count.host");
+ if ($host eq "") {
+ goto DONE;
+ }
+ my $https_agent_port = $::config->get("preop.securitydomain.tks$count.secureagentport");
+ my $name = $::config->get("preop.securitydomain.tks$count.subsystemname");
+ $::symbol{urls}[$count++] = $name . " - https://" . $host . ":" . $https_agent_port;
+ }
+DONE:
+ $::symbol{urls_size} = $count;
+ if ($count eq 0) {
+ $::symbol{errorString} = "no TKS found. CA, TKS and optionally DRM must be installed prior to RA installation";
+ return 0;
+ }
+
+ return 1;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/WelcomePanel.pm b/base/ra/lib/perl/PKI/RA/WelcomePanel.pm
new file mode 100755
index 000000000..c88c138be
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/WelcomePanel.pm
@@ -0,0 +1,90 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+use warnings;
+use PKI::RA::GlobalVar;
+use PKI::RA::Common;
+
+package PKI::RA::WelcomePanel;
+$PKI::RA::WelcomePanel::VERSION = '1.00';
+
+use PKI::RA::BasePanel;
+our @ISA = qw(PKI::RA::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&PKI::RA::Common::no;
+ $self->{"getPanelNo"} = &PKI::RA::Common::r(0);
+ $self->{"getName"} = &PKI::RA::Common::r("Welcome");
+ $self->{"vmfile"} = "welcomepanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("WelcomePanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("WelcomePanel: update");
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::RA::Wizard::debug_log("XXX " . $::config->get("logging.debug.enable"));
+ &PKI::RA::Wizard::debug_log("WelcomePanel: display");
+ $::symbol{wizardname} = "RA Configuration Wizard";
+ $::symbol{systemname} = "RA";
+ $::symbol{fullsystemname} = "Registration Authority";
+
+ return 1;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/RA/wizard.pm b/base/ra/lib/perl/PKI/RA/wizard.pm
new file mode 100755
index 000000000..5fe1e7536
--- /dev/null
+++ b/base/ra/lib/perl/PKI/RA/wizard.pm
@@ -0,0 +1,502 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+# wizard -
+# Fedora Certificate System - Registration Authority System configuration wizard
+
+
+# This script is run as a 'mod_perl' CGI. Configure mod_perl by adding
+# the following to /etc/httpd/conf.d/perl.conf
+#
+# PerlModule ModPerl::Registry
+# PerlModule Apache::compat
+# PerlModule PKI::RA::Wizard
+# PerlSetEnv PKI_DOCROOT /u/sparkins/t/cs_tip/certsystem/prj/common/ui
+# <Location /wizard>
+# SetHandler perl-script
+# PerlHandler PKI::RA::Wizard
+# Order deny,allow
+# Allow from all
+# </Location>
+
+
+# Note: The Velocity parser is not very helpful when it comes to
+# errors right now. Here are some common errors, and what they mean:
+#
+# ERROR:
+# [Mon Apr 03 13:57:33 2006] [error] [client 172.16.24.26]
+# Can't use string ("0") as an ARRAY ref while "strict refs"
+# in use at /usr/lib/perl5/site_perl/5.8.5/Template/Velocity.pm
+# line 423.\n, referer: http://chico/wizard?p=2
+# MEANING
+# This probably means that your *.vm file refers to an array
+# variable in a foreach statement that is not defined
+# Check your foreach array variables.
+
+use warnings;
+use ModPerl::Registry;
+use Template::Velocity;
+use Getopt::Std;
+use Data::Dumper;
+use CGI::Carp qw(fatalsToBrowser);
+use CGI;
+use APR::Const -compile => qw(:error SUCCESS);
+use PKI::RA::GlobalVar;
+use PKI::RA::WelcomePanel;
+use PKI::RA::SecurityDomainPanel;
+use PKI::RA::DisplayCertChainPanel;
+use PKI::RA::SubsystemTypePanel;
+use PKI::RA::CAInfoPanel;
+use PKI::RA::DisplayCertChain2Panel;
+use PKI::RA::AdminAuthPanel;
+use PKI::RA::AgentAuthPanel;
+use PKI::RA::DatabasePanel;
+use PKI::RA::ModulePanel;
+use PKI::RA::SizePanel;
+use PKI::RA::NamePanel;
+use PKI::RA::ConfigHSMLoginPanel;
+use PKI::RA::CertRequestPanel;
+use PKI::RA::AdminPanel;
+use PKI::RA::ImportAdminCertPanel;
+use PKI::RA::DonePanel;
+use PKI::RA::Config;
+
+use PKI::RA::Common qw(yes no r);
+
+package PKI::RA::Wizard;
+$PKI::RA::Wizard::VERSION = '1.00';
+
+# read configuration file
+my $flavor = "pki";
+$flavor =~ s/\n//g;
+
+my $pkiroot = $ENV{PKI_ROOT};
+
+my $config = PKI::RA::Config->new();
+$config->load_file("$pkiroot/conf/CS.cfg");
+# read password cache file
+my $pwdconf = PKI::RA::Config->new();
+$pwdconf->load_file("$pkiroot/conf/pwcache.conf");
+# SELinux disallows performing a "chmod" on this file
+if( $^O ne "linux" ) {
+ system( "chmod 00660 $pkiroot/conf/pwcache.conf" );
+}
+
+# create cfg debug log
+my $logfile = $config->get("service.instanceDir") . "/logs/debug";
+system( "touch $logfile" );
+system( "chmod 00640 $logfile" );
+open( DEBUG, ">>" . $logfile ) ||
+warn( "Could not open '" . $logfile . "': $!" );
+
+# apache server
+
+our $debug;
+
+my $HTTP_OK = 0;
+
+my $STATUS_OK = 0; # Apache 2 needs this to be zero
+my $STATUS_ERROR = 2;
+my $STATUS_REDIRECT = 3;
+
+&debug_log("RA wizard: starting up");
+
+my $docroot = $ENV{PKI_DOCROOT};
+
+if (! $docroot) {
+ &debug_log("RA wizard: ERROR: PKI_DOCROOT is null");
+ return 0;
+}
+
+our $parser = new Template::Velocity($docroot);
+our $symbol;
+our @certtags;
+
+makepanels();
+
+&debug_log("RA wizard: start up complete");
+
+1;
+
+sub debug_log
+{
+ my ($msg) = @_;
+ my $date = `date`;
+ chomp($date);
+ if( -w $logfile ) {
+ print DEBUG "$date - $msg\n";
+ }
+}
+
+ # initializes entries in parser's global symbol table for panels
+sub makepanels
+{
+ #REAL PANELS BELOW
+ my $welcome = new PKI::RA::WelcomePanel();
+ my $securitydomain = new PKI::RA::SecurityDomainPanel();
+ my $displaycertchain = new PKI::RA::DisplayCertChainPanel();
+ my $subsystem = new PKI::RA::SubsystemTypePanel();
+ my $cainfopanel = new PKI::RA::CAInfoPanel();
+# my $displaycertchain2 = new PKI::RA::DisplayCertChain2Panel();
+ my $databasepanel = new PKI::RA::DatabasePanel();
+ my $modulepanel = new PKI::RA::ModulePanel();
+ my $confighsmloginpanel = new PKI::RA::ConfigHSMLoginPanel();
+ my $sizepanel = new PKI::RA::SizePanel();
+ my $namepanel = new PKI::RA::NamePanel();
+ my $certrequestpanel = new PKI::RA::CertRequestPanel();
+ my $adminpanel = new PKI::RA::AdminPanel();
+ my $importadmincertpanel = new PKI::RA::ImportAdminCertPanel();
+ my $donepanel = new PKI::RA::DonePanel();
+
+ $symbol{panels} = [
+ $welcome, # com.netscape.cms.servlet.csadmin.WelcomePanel
+ $securitydomain, # com.netscape.cms.servlet.csadmin.SecurityDomainPanel
+ $displaycertchain, # com.netscape.cms.servlet.csadmin.DisplayCertChainPanel
+ $subsystem, # com.netscape.cms.servlet.csadmin.CreateSubsystemPanel
+ $cainfopanel, # com.netscape.cms.servlet.csadmin.CAInfoPanel
+# $displaycertchain2, # com.netscape.cms.servlet.csadmin.DisplayCertChain2Panel
+ $databasepanel, # com.netscape.cms.servlet.csadmin.DatabasePanel
+ $modulepanel, # com.netscape.cms.servlet.csadmin.ModulePanel
+ $confighsmloginpanel, # com.netscape.cms.servlet.csadmin.ConfigHSMLoginPanel
+ $sizepanel, # com.netscape.cms.servlet.csadmin.SizePanel
+ $namepanel, # com.netscape.cms.servlet.csadmin.NamePanel
+ $certrequestpanel, # com.netscape.cms.servlet.csadmin.CertRequestPanel
+ $adminpanel, # com.netscape.cms.servlet.csadmin.AdminPanel
+ $importadmincertpanel, # com.netscape.cms.servlet.csadmin.ImportAdminCertPanel
+ $donepanel, # com.netscape.cms.servlet.csadmin.DonePanel</param-value>
+ ];
+};
+
+sub render_panel
+{
+ my ($panelnum, $q) = @_;
+
+ $symbol{errorString} = "";
+
+ my $currentpanel;
+
+ if ($q->param('op') && $q->param('op') eq "next") {
+ $currentpanel = $symbol{panels}[$panelnum];
+ # validate variables for panel
+ if ($currentpanel->{validate}) {
+ $currentpanel->{validate}($q);
+ }
+ # execute current panel
+ my $status = "0";
+
+ if ($currentpanel->{update}) {
+ $status = $currentpanel->{update}($q);
+ &debug_log("RA wizard: update returns status '" .
+ $status . "'");
+ if ($status == $STATUS_REDIRECT) {
+ return $STATUS_REDIRECT;
+ }
+
+ }
+
+ &debug_log("RA wizard: about to find out about sub panel");
+ if ($status eq "1") {
+ if ($currentpanel->{hasSubPanel} && &{$currentpanel->{hasSubPanel}}($q)) {
+ &debug_log("RA wizard: has sub panel");
+ $panelnum = $panelnum + 2;
+ } elsif ($currentpanel->{isSubPanel} && &{$currentpanel->{isSubPanel}}($q)) {
+ &debug_log("RA wizard: is sub panel");
+ $panelnum = $panelnum - 1;
+ } else {
+ &debug_log("RA wizard: no sub panel and is not subpanel");
+ $panelnum = $panelnum + 1;
+ }
+ }
+ } elsif ($q->param('op') && $q->param('op') eq "back") {
+ $panelnum = $panelnum - 1;
+ #check if this a subpanel, if so, go back to it's parent.
+ #only handles one-deep at this point
+ my $panel = $symbol{panels}[$panelnum];
+ if (&{$panel->{isSubPanel}}($q)) {
+ $panelnum = $panelnum - 1;
+ }
+ } elsif ($q->param('op') && $q->param('op') eq "apply") {
+ &debug_log("RA wizard: update : apply button pressed");
+ $currentpanel = $symbol{panels}[$panelnum];
+ # validate variables for panel
+ if ($currentpanel->{validate}) {
+ $currentpanel->{validate}($q);
+ }
+ # execute current panel
+ if ($currentpanel->{update}) {
+ my $status = $currentpanel->{update}($q);
+ &debug_log("RA wizard: update returns status '" .
+ $status . "'");
+ if ($status == $STATUS_REDIRECT) {
+ return $STATUS_REDIRECT;
+ }
+
+ }
+ }
+
+ &debug_log("RA wizard: after looking into about sub panel");
+
+ # advance to next panel
+ $currentpanel = $symbol{panels}[$panelnum];
+
+ # initialize symbol table values
+ $symbol{showApplyButton} = "false";
+
+ # fill in variables for new panel
+ if ($currentpanel->{panelvars}) {
+ $Data::Dumper::Indent = 1;
+ # The '&debug_log("q=".Dumper($q));' call must be commented out to fix
+ # Bugzilla Bug #249923: Incorrect file permissions on
+ # various files and/or directories
+ # &debug_log("q=".Dumper($q));
+ $currentpanel->{panelvars}($q);
+ }
+
+ $symbol{panel} = "ra/admin/console/config/".$currentpanel->{vmfile};
+
+ #wizard.vm:
+ $symbol{name} = "Registration Authority";
+ $symbol{title} = $currentpanel->{getName}();
+ if ($panelnum == 0) {
+ $symbol{firstpanel} = "1";
+ } else {
+ $symbol{firstpanel} = "0";
+ }
+ if ($panelnum == 13) {
+ $symbol{lastpanel} = "1";
+ } else {
+ $symbol{lastpanel} = "0";
+ }
+ $symbol{p} = $panelnum;
+ $symbol{subpanelno} = $panelnum+1;
+ $symbol{productversion} = $::config->get("preop.product.version");
+ $symbol{csstate} = "1";
+
+# $symbol{urls} = [ "cert1", "cert2" ]; #createsubsystem
+# $symbol{urls_size} = 2;
+# $symbol{instanceId} = "ra";
+# $symbol{errorString} = "";
+
+ #modulepanel
+# $symbol{certs} = [ ];
+# $symbol{reqscerts} = [ ];
+ $symbol{ppcerts} = [ ];
+
+ return $STATUS_OK;
+}
+
+
+
+sub dbg {
+ my $msg = shift;
+ $::symbol{dbg} .= "$msg\n";
+}
+
+sub handler {
+ my $r = shift;
+
+ *::symbol = \%symbol;
+ *::s = \$s;
+ *::config = \$config;
+ *::pwdconf = \$pwdconf;
+
+ &debug_log("RA wizard: in handler");
+
+ my $q = new CGI;
+
+ # check cookie
+ my $cookie = $q->cookie('pin');
+ my $pin = $::config->get("preop.pin");
+ if ($cookie ne $pin) {
+ print $q->redirect("login");
+ return;
+ }
+
+ # output http parameters
+ &debug_log("RA wizard: uri='" . $ENV{REQUEST_URI} . "'");
+ my @pnames = $q->param();
+ foreach $pn (@pnames) {
+ # 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 =~ /^__/ ||
+ $pn =~ /password$/ ||
+ $pn =~ /passwd$/ ||
+ $pn =~ /pwd$/ ||
+ $pn =~ /admin_password_again/i ||
+ $pn =~ /directoryManagerPwd/i ||
+ $pn =~ /bindpassword/i ||
+ $pn =~ /bindpwd/i ||
+ $pn =~ /passwd/i ||
+ $pn =~ /password/i ||
+ $pn =~ /pin/i ||
+ $pn =~ /pwd/i ||
+ $pn =~ /pwdagain/i ||
+ $pn =~ /uPasswd/i ) {
+ &debug_log("RA wizard: http parameter name='" . $pn . "' value='(sensitive)'");
+ } else {
+ &debug_log("RA wizard: http parameter name='" . $pn . "' value='" . $q->param($pn) . "'");
+ }
+ }
+
+ my $panelnum = $q->param('p');
+ if (!defined($panelnum) || $panelnum eq "") {
+ # Apache fails to pick up the p parameter after
+ # redirecting from the security domain. This is
+ # a quick hack to solve the issue.
+ if ($ENV{'QUERY_STRING'} ne "") {
+ $ENV{'QUERY_STRING'} =~ /p=([0-9]+)&/;
+ $panelnum = $1;
+ }
+ }
+
+ use subs qw(debug);
+ *debug = \&Template::Velocity::Executor::debug;
+
+ $::symbol{dbg} = "";
+
+ &debug_log("RA wizard: before argparsing");
+ if ($#ARGV == -1) {
+ $Data::Dumper::Maxdepth = 7;
+ $startfile = "ra/admin/console/config/wizard.vm";
+ }
+
+ &debug_log("RA wizard: setting up test objects");
+
+ #initialize from config file
+ my $certlist = $::config->get("preop.cert.list");
+ if ($certlist eq "") {
+ $certlist = "sslserver,subsystem";
+ }
+ @certtags = split(/,/, $certlist);
+ $numtags = @certtags;
+ if ($numtags eq 0) {
+ @certtags = ("sslserver", "subsystem");
+ }
+ &debug_log("RA wizard: found $numtags certtags");
+
+ if (! $panelnum) {
+ $panelnum = 0;
+ }
+
+ my $status = render_panel($panelnum, $q);
+ if ($status == 3) {
+ $r->header_out(Location => $symbol{redirect});
+ $r->status(301);
+ $r->send_http_header();
+ return;
+ }
+
+ use Data::Dumper;
+ &debug_log("RA wizard: executing file $startfile");
+ foreach $q (sort keys %symbol) {
+ &debug_log("RA wizard:/config/wizard?p=9&SecToken=NSS%20Generic%20Crypto%20Services sym{$q}=".$symbol{$q});
+ }
+
+ my $result;
+ if ($q->param('xml') && $q->param('xml') eq "true") {
+ $r->send_http_header('text/xml');
+ $result = "<xml>";
+ foreach $s (sort keys %symbol) {
+ if ($s =~ /^__/) {
+ next;
+ }
+ $result .= "<" . $s . ">";
+ my $v = $symbol{$s};
+ $result .= &get_xml($s, $v);
+ $result .= "</" . $s . ">";
+ }
+ $result .= "</xml>";
+ } else {
+ $result = $parser->execute_file($startfile);
+ if (!defined $result) {
+ die("Couldn't execute template file: $docroot/$startfile");
+ }
+ }
+
+ $r->send_http_header('text/html');
+ print "$result\n";
+
+ return $HTTP_OK;
+}
+
+sub escape_xml
+{
+ my ($v) = @_;
+ $v =~ s/\"/&quot;/g;
+ $v =~ s/\'/&apos;/g;
+ $v =~ s/\&/&amp;/g;
+ $v =~ s/</&lt;/g;
+ $v =~ s/>/&gt;/g;
+ return $v;
+}
+
+sub get_xml
+{
+ my ($s, $v) = @_;
+
+ my $result;
+ if (ref($v) eq "HASH") {
+ foreach my $xkey (keys %$v) {
+ $result .= "<" . $xkey . ">";
+ $result .= &get_xml($xkey, $v{$xkey});
+ # $result .= "-" . ref($xkey);
+ $result .= "</" . $xkey . ">";
+ }
+ } elsif (ref($v) eq "PKI::RA::CertInfo") {
+ my $certinfo = $v;
+ $result .= "<certinfo>";
+ $result .= "<dn>" . $certinfo->get_dn() ."</dn>";
+ $result .= "<tag>" . $certinfo->get_cert_tag() . "</tag>";
+ $result .= "<friendly>" . $certinfo->get_user_friendly_name() .
+ "</friendly>";
+ $result .= "</certinfo>";
+ } elsif (ref($v) eq "PKI::RA::ReqCertInfo") {
+ my $reqcertinfo = $v;
+ $result .= "<reqcertinfo>";
+ $result .= "<name>" . $reqcertinfo->get_user_friendly_name() ."</name>";
+ $result .= "<req>" . $reqcertinfo->get_request() ."</req>";
+ $result .= "<cert>" . $reqcertinfo->get_cert() ."</cert>";
+ $result .= "<certpp>" . &escape_xml($reqcertinfo->get_cert_pp()) ."</certpp>";
+ $result .= "<tag>" . $reqcertinfo->get_cert_tag() ."</tag>";
+ $result .= "<dn>" . $reqcertinfo->get_cert_tag() ."</dn>";
+ $result .= "</reqcertinfo>";
+ } elsif (ref($v) eq "ARRAY") {
+ my $pos = 0;
+ foreach my $item (@$v) {
+ $result .= "<element>";
+ $result .= &get_xml("p" . $pos, $item);
+ # $result .= "-" . ref($item);
+ $result .= "</element>";
+ $pos++;
+ }
+ } else {
+ $result .= &escape_xml($v);
+ }
+ return $result;
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/Request/Plugin/AutoAssign.pm b/base/ra/lib/perl/PKI/Request/Plugin/AutoAssign.pm
new file mode 100644
index 000000000..671f2418d
--- /dev/null
+++ b/base/ra/lib/perl/PKI/Request/Plugin/AutoAssign.pm
@@ -0,0 +1,52 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+#######################################
+# This plugins assigns a request to a group.
+#######################################
+package PKI::Request::Plugin::AutoAssign;
+
+use DBI;
+use PKI::Base::TimeTool;
+
+#######################################
+# Instantiate this plugin
+#######################################
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+#######################################
+# Processes plugin
+#######################################
+sub process {
+ my ($self, $cfg, $queue, $prefix, $req) = @_;
+
+ my $assignTo = $cfg->get($prefix . ".assignTo");
+ $queue->set_request($req->{'rowid'}, "assigned_to", $assignTo);
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/Request/Plugin/CreatePin.pm b/base/ra/lib/perl/PKI/Request/Plugin/CreatePin.pm
new file mode 100644
index 000000000..b90096664
--- /dev/null
+++ b/base/ra/lib/perl/PKI/Request/Plugin/CreatePin.pm
@@ -0,0 +1,75 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+#######################################
+# This plugins creates a one time pin.
+#######################################
+package PKI::Request::Plugin::CreatePin;
+
+use DBI;
+use PKI::Base::TimeTool;
+use PKI::Base::PinStore;
+
+#######################################
+# Instantiates this plugin
+#######################################
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+#######################################
+# Processes plugin
+#######################################
+sub process {
+ my ($self, $cfg, $queue, $prefix, $req) = @_;
+
+ my $pin_store = PKI::Base::PinStore->new();
+ $pin_store->open($cfg);
+
+
+ my $pin_format = $cfg->get($prefix . ".pinFormat");
+
+ my $client_id = "";
+ my $site_id = "";
+
+ my $data = $req->{'data'};
+ foreach $nv (split(/;/, $data)) {
+ my ($n, $v) = split(/=/, $nv);
+ $pin_format =~ s/\$$n/$v/g;
+ }
+ my $created_by = "admin";
+ my $pin = $pin_store->create_pin($pin_format, $req->{'rowid'}, $created_by);
+
+ # save pin to output
+ $output = "pin=" . $pin;
+ $queue->set_request_output($req->{'rowid'}, $output);
+
+ $req->{'output'} = $output;
+
+ $pin_store->close();
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/Request/Plugin/EmailNotification.pm b/base/ra/lib/perl/PKI/Request/Plugin/EmailNotification.pm
new file mode 100644
index 000000000..95274bfa7
--- /dev/null
+++ b/base/ra/lib/perl/PKI/Request/Plugin/EmailNotification.pm
@@ -0,0 +1,100 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+#######################################
+# This plugins mails a notification
+# to an email specified in the request.
+#######################################
+package PKI::Request::Plugin::EmailNotification;
+
+use DBI;
+use PKI::Base::TimeTool;
+
+#######################################
+# Instantiate this plugin
+#######################################
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub substitute {
+ my ($self, $cfg, $queue, $prefix, $req, $line) = @_;
+
+ my $mail_to = $cfg->get($prefix . ".mailTo");
+
+ # if mail_to starts with $, retrieve value from request
+ if ($mail_to =~ /^\$/) {
+ $mail_to =~ s/\$//g;
+ $mail_to = $req->{$mail_to};
+ }
+ my $machineName = $cfg->get("service.machineName");
+ my $securePort = $cfg->get("service.securePort");
+ my $unsecurePort = $cfg->get("service.unsecurePort");
+ my $nonClientAuthSecurePort = $cfg->get("service.non_clientauth_securePort");
+ my $subject_dn = $req->{'subject_dn'};
+
+ $line =~ s/\$mail_to/$mail_to/g;
+ $line =~ s/\$request_id/$req->{'rowid'}/g;
+ $line =~ s/\$machineName/$machineName/g;
+ $line =~ s/\$securePort/$securePort/g;
+ $line =~ s/\$unsecurePort/$unsecurePort/g;
+ $line =~ s/\$subject_dn/$subject_dn/g;
+ $line =~ s/\$nonClientAuthSecurePort/$nonClientAuthSecurePort/g;
+ return $line;
+}
+
+#######################################
+# Processes plugin
+#######################################
+sub process {
+ my ($self, $cfg, $queue, $prefix, $req) = @_;
+ my $queue = PKI::Request::Queue->new();
+ $queue->open($cfg);
+ my $ref = $queue->read_request($req->{rowid});
+
+ my $req_err = $ref->{errorString};
+ if ($req_err ne "0") {
+ return;
+ }
+
+ my $mail_to = $cfg->get($prefix . ".mailTo");
+ if ($mail_to eq "") {
+ return;
+ }
+
+ my $template_dir = $cfg->get($prefix . ".templateDir");
+ my $template_file = $cfg->get($prefix . ".templateFile");
+
+ open(SENDMAIL, "|/usr/sbin/sendmail -t");
+ open(F,"$template_dir/$template_file");
+ while (<F>) {
+ print SENDMAIL $self->substitute($cfg, $queue, $prefix, $ref, $_);
+ }
+ close(F);
+ close(SENDMAIL);
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/Request/Plugin/RequestToCA.pm b/base/ra/lib/perl/PKI/Request/Plugin/RequestToCA.pm
new file mode 100644
index 000000000..1c5b7d6b2
--- /dev/null
+++ b/base/ra/lib/perl/PKI/Request/Plugin/RequestToCA.pm
@@ -0,0 +1,89 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+#######################################
+# This plugins mails a notification
+# to an email specified in the request.
+#######################################
+package PKI::Request::Plugin::RequestToCA;
+
+use DBI;
+use PKI::Base::TimeTool;
+use PKI::Conn::CA;
+
+#######################################
+# Instantiate this plugin
+#######################################
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+#######################################
+# Processes plugin
+#######################################
+sub process {
+ my ($self, $cfg, $queue, $prefix, $req) = @_;
+
+ my $ca = $cfg->get($prefix . ".ca");
+ my $profile_id = $cfg->get($prefix . ".profileId");
+ my $req_type = $cfg->get($prefix . ".reqType");
+
+ my $server_id = "";
+ my $site_id = "";
+ my $csr = "";
+ my $csr_type = "";
+
+ my $data = $req->{'data'};
+ foreach $nv (split(/;/, $data)) {
+ my ($n, $v) = split(/=/, $nv);
+ if ($n eq "server_id") {
+ $server_id = $v;
+ }
+ if ($n eq "site_id") {
+ $site_id = $v;
+ }
+ if ($n eq "csr") {
+ $csr = $v;
+ }
+ if ($n eq "csr_type") {
+ $csr_type = $v;
+ }
+ }
+
+ if ($csr_type ne "") {
+ $req_type = $csr_type;
+ }
+
+ my $ca_conn = PKI::Conn::CA->new();
+ $ca_conn->open($cfg);
+ my $cert = $ca_conn->enroll($req->{'rowid'}, $ca, $profile_id, $req_type, $csr);
+ $queue->set_request($req->{'rowid'}, "output", $cert);
+ $req->{'output'} = $cert;
+ $ca_conn->close();
+
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/Request/Queue.pm b/base/ra/lib/perl/PKI/Request/Queue.pm
new file mode 100644
index 000000000..dc8418d22
--- /dev/null
+++ b/base/ra/lib/perl/PKI/Request/Queue.pm
@@ -0,0 +1,387 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+package PKI::Request::Queue;
+
+use DBI;
+use PKI::Base::TimeTool;
+
+#######################################
+# Constructs a request queue
+#######################################
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+#######################################
+# Opens request queue
+#######################################
+sub open {
+ my ($self, $cfg) = @_;
+ $self->{cfg} = $cfg;
+ my $dbfile = $cfg->get("database.dbfile");
+ $self->{dbh} = DBI->connect("dbi:SQLite:dbname=$dbfile","","");
+ my $timeout = $self->{dbh}->func("busy_timeout");
+ $self->{dbh}->func($timeout * 10, "busy_timeout");
+}
+
+#######################################
+# Creates a new request
+#######################################
+sub invoke_plugins {
+ my ($self, $prefix, $type, $ref) = @_;
+
+ my $num_plugins = $self->{cfg}->get($prefix . ".num_plugins");
+ for (my $i = 0; $i < $num_plugins; $i++) {
+ my $plugin = $self->{cfg}->get($prefix . "." . $i . ".plugin");
+ eval("require $plugin");
+ my $p = $plugin->new();
+ $p->process($self->{cfg}, $self, $prefix . "." . $i, $ref);
+ }
+}
+
+#######################################
+# Creates a new request
+#######################################
+sub create_request {
+ my ($self, $type, $data, $meta_info, $created_by) = @_;
+ my $dbh = $self->{dbh};
+
+ my $timet = PKI::Base::TimeTool->new();
+ my $now = $timet->get_time();
+
+ my $insert = "insert into requests (" .
+ "type" . "," .
+ "status" . "," .
+ "errorString" . "," .
+ "ip" . "," .
+ "data" . "," .
+ "serialno" . "," .
+ "subject_dn" . "," .
+ "meta_info" . "," .
+ "created_by" . "," .
+ "updated_at" . "," .
+ "created_at" .
+ ") values (" .
+ $dbh->quote($type) . "," .
+ $dbh->quote("OPEN") . "," .
+ $dbh->quote("0") . "," .
+ $dbh->quote($ENV{REMOTE_ADDR}) . "," .
+ $dbh->quote($data) . "," .
+ $dbh->quote("unavailable") . "," .
+ $dbh->quote("unavailable") . "," .
+ $dbh->quote($meta_info) . "," .
+ $dbh->quote($created_by) . "," .
+ $dbh->quote($now) . "," .
+ $dbh->quote($now) .
+ ")";
+REDO_CREATE_REQUEST:
+ eval {
+ $dbh->do($insert);
+ };
+ if ($dbh->err == 5) {
+ sleep(1);
+ goto REDO_CREATE_REQUEST;
+ }
+ my $rid = $dbh->func('last_insert_rowid');
+
+ my $ref = $self->read_request($rid);
+
+ # call plugins
+ my $prefix = "request." . $type . ".create_request";
+ $self->invoke_plugins($prefix, $type, $ref);
+
+ return $rid;
+}
+
+#######################################
+# Reads a request
+#######################################
+sub read_request {
+ my ($self, $reqid) = @_;
+ my $dbh = $self->{dbh};
+ my $select = "select *,rowid from requests " .
+ "where rowid=" . $dbh->quote($reqid);
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my $ref = $sth->fetchrow_hashref();
+ $sth->finish();
+ return $ref;
+}
+
+sub read_request_by_roles {
+ my ($self, $roles, $reqid) = @_;
+ my $dbh = $self->{dbh};
+
+ my $select;
+ if (grep /^administrators/, @$roles) {
+ # administrator see all requests
+ $select = "select *,rowid from requests " .
+ "where rowid=" . $dbh->quote($reqid);
+ } else {
+ my $filter = $self->get_role_filter($roles);
+ $select = "select *,rowid from requests where " .
+ "(" . $filter . ")" . " AND " .
+ "rowid=" . $dbh->quote($reqid);
+ }
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my $ref = $sth->fetchrow_hashref();
+ $sth->finish();
+ return $ref;
+}
+
+#######################################
+# Sets request attributes
+#######################################
+sub set_request {
+ my ($self, $reqid, $name, $value) = @_;
+ my $dbh = $self->{dbh};
+
+ my $timet = PKI::Base::TimeTool->new();
+ my $now = $timet->get_time();
+ my $update = "update requests set " .
+ $name . "=" . $dbh->quote($value) . "," .
+ "updated_at=" . $dbh->quote($now) . " " .
+ "where rowid=" . $dbh->quote($reqid);
+REDO_SET_REQUEST:
+ eval {
+ $dbh->do($update);
+ };
+ if ($dbh->err == 5) {
+ sleep(1);
+ goto REDO_SET_REQUEST;
+ }
+
+ my $select = "select *,rowid from requests " .
+ "where rowid=" . $dbh->quote($reqid);
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my $ref = $sth->fetchrow_hashref();
+ $sth->finish();
+
+ return $ref;
+}
+
+#######################################
+# Sets output
+#######################################
+sub set_request_output {
+ my ($self, $reqid, $output) = @_;
+
+ return $self->set_request($reqid, "output", $output);
+}
+
+#######################################
+# Approves a request
+#######################################
+sub approve_request {
+ my ($self, $reqid, $processed_by) = @_;
+ my $dbh = $self->{dbh};
+
+ # XXX - check assigned_to
+
+ my $timet = PKI::Base::TimeTool->new();
+ my $now = $timet->get_time();
+ my $update = "update requests set " .
+ "processed_by=" . $dbh->quote($processed_by) . "," .
+ "status='APPROVED' " . "," .
+ "errorString='0' " . "," .
+ "updated_at=" . $dbh->quote($now) . " " .
+ "where rowid=" . $dbh->quote($reqid);
+REDO_APPROVE_REQUEST:
+ eval {
+ $dbh->do($update);
+ };
+ if ($dbh->err == 5) {
+ sleep(1);
+ goto REDO_APPROVE_REQUEST;
+ }
+
+ my $select = "select *,rowid from requests " .
+ "where rowid=" . $dbh->quote($reqid);
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my $ref = $sth->fetchrow_hashref();
+ $sth->finish();
+
+ # call plugins
+ my $prefix = "request." . $ref->{'type'} . ".approve_request";
+ $self->invoke_plugins($prefix, $ref->{'type'}, $ref);
+
+ my $select = "select *,rowid from requests " .
+ "where rowid=" . $dbh->quote($reqid);
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my $ref = $sth->fetchrow_hashref();
+ $sth->finish();
+
+ return $ref;
+}
+
+#######################################
+# Rejects a request
+#######################################
+sub reject_request {
+ my ($self, $reqid, $processed_by) = @_;
+ my $dbh = $self->{dbh};
+
+ my $timet = PKI::Base::TimeTool->new();
+ my $now = $timet->get_time();
+ my $update = "update requests set " .
+ "processed_by=" . $dbh->quote($processed_by) . "," .
+ "status='REJECTED' " . "," .
+ "updated_at=" . $dbh->quote($now) . " " .
+ "where rowid=" . $dbh->quote($reqid);
+REDO_REJECT_REQUEST:
+ eval {
+ $dbh->do($update);
+ };
+ if ($dbh->err == 5) {
+ sleep(1);
+ goto REDO_REJECT_REQUEST;
+ }
+
+ my $select = "select *,rowid from requests " .
+ "where rowid=" . $dbh->quote($reqid);
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my $ref = $sth->fetchrow_hashref();
+ $sth->finish();
+
+ # call plugins
+ my $prefix = "request." . $ref->{'type'} . ".reject_request";
+ $self->invoke_plugins($prefix, $ref->{'type'}, $ref);
+
+ my $select = "select *,rowid from requests " .
+ "where rowid=" . $dbh->quote($reqid);
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my $ref = $sth->fetchrow_hashref();
+ $sth->finish();
+
+ return $ref;
+}
+
+sub get_role_filter {
+ my ($self, $roles) = @_;
+ my $dbh = $self->{dbh};
+
+ my $filter = "";
+ foreach $rr (@$roles) {
+ if ($filter eq "") {
+ $filter = "assigned_to=" . $dbh->quote($rr);
+ } else {
+ $filter = $filter . " OR " . "assigned_to=" . $dbh->quote($rr);
+ }
+ }
+ return $filter;
+}
+
+#######################################
+# Lists requests
+#######################################
+sub list_requests {
+ my ($self, $startpos, $maxcount) = @_;
+ my $dbh = $self->{dbh};
+ my $select = "select *,rowid from requests " .
+ "order by rowid desc " .
+ "limit $startpos, $maxcount";
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my @reqs;
+ while (my $ref = $sth->fetchrow_hashref()) {
+ push(@reqs, $ref);
+ }
+ $sth->finish();
+ return @reqs;
+}
+
+sub count_requests_by_roles {
+ my ($self, $roles, $status) = @_;
+ my $dbh = $self->{dbh};
+
+ my $select;
+
+ if (grep /^administrators$/, @$roles) {
+ # administrator sees everything
+ $select = "select count(*) from requests where " .
+ "status like '$status%' ";
+ } else {
+ # shows requests that are owned by the groups
+ my $filter = $self->get_role_filter($roles);
+ $select = "select count(*) from requests where " .
+ "status like '$status%' AND " .
+ "(" . $filter . ") ";
+ }
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my $ref = $sth->fetchrow_hashref();
+ $sth->finish();
+ return $ref->{'count(*)'};
+}
+
+sub list_requests_by_roles {
+ my ($self, $roles, $status, $startpos, $maxcount) = @_;
+ my $dbh = $self->{dbh};
+
+ my $select;
+
+# if ($roles =~ /administrators/) {
+ if (grep /^administrators$/, @$roles) {
+ # administrator sees everything
+ $select = "select *,rowid from requests where " .
+ "status like '$status%' " .
+ "order by rowid desc " .
+ "limit $startpos, $maxcount";
+ } else {
+ # shows requests that are owned by the groups
+ my $filter = $self->get_role_filter($roles);
+ $select = "select *,rowid from requests where " .
+ "status like '$status%' AND " .
+ "(" . $filter . ") " .
+ "order by rowid desc " .
+ "limit $startpos, $maxcount";
+ }
+ my $sth = $dbh->prepare($select);
+ $sth->execute();
+ my @reqs;
+ while (my $ref = $sth->fetchrow_hashref()) {
+ push(@reqs, $ref);
+ }
+ $sth->finish();
+ return @reqs;
+}
+
+#######################################
+# Closes request queue
+#######################################
+sub close {
+ my ($self) = @_;
+ my $dbh = $self->{dbh};
+ $dbh->disconnect();
+}
+
+1;
diff --git a/base/ra/lib/perl/PKI/Service/Op.pm b/base/ra/lib/perl/PKI/Service/Op.pm
new file mode 100644
index 000000000..602f1a29f
--- /dev/null
+++ b/base/ra/lib/perl/PKI/Service/Op.pm
@@ -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.
+#
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+#
+#
+#
+
+package PKI::Service::Op;
+
+use PKI::Base::UserStore;
+use PKI::Base::CertStore;
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub debug_log()
+{
+ my ($self, $cfg, $msg) = @_;
+
+ my $date = `date`;
+ chomp($date);
+ open(DEBUG, ">>" . $cfg->get("logging.debug.filename"));
+ print DEBUG "$date - $msg\n";
+ close(DEBUG);
+}
+
+sub debug_params()
+{
+ my ($self, $cfg, $q) = @_;
+
+ my $date = `date`;
+ chomp($date);
+ $self->debug_log($cfg, "$date - URL '" . $ENV{REQUEST_URI} . "'");
+ my @names = $q->param();
+ foreach my $k (@names) {
+ $self->debug_log($cfg, "$date - Param $k='" . $q->param($k) . "'");
+ }
+}
+
+sub get_client_certificate()
+{
+ my ($self) = @_;
+
+ my $user_cert = $ENV{"SSL_CLIENT_CERT"};
+ $user_cert =~ s/-----BEGIN CERTIFICATE-----//g;
+ $user_cert =~ s/-----END CERTIFICATE-----//g;
+ $user_cert =~ s/\n//g;
+
+ return $user_cert;
+}
+
+sub get_current_uid()
+{
+ my ($self, $cfg) = @_;
+
+ my $user_cert = $self->get_client_certificate();
+
+ my $us = PKI::Base::UserStore->new();
+ $us->open($cfg);
+ my $ref = $us->map_user($user_cert);
+ if (!defined($ref)) {
+ return "";
+ }
+ $us->close();
+
+ return $ref->{'uid'};
+}
+
+sub get_csr_by_cert()
+{
+ my ($self, $cfg) = @_;
+
+ my $user_cert = $self->get_client_certificate();
+ my $cs = PKI::Base::CertStore->new();
+ $cs->open($cfg);
+ my $ref = $cs->map_certificate($user_cert);
+ if (!defined($ref)) {
+ return "";
+ }
+ $us->close();
+
+ return $ref->{'csr'};
+}
+
+sub get_cert_record()
+{
+ my ($self, $cfg) = @_;
+
+$self->debug_log( $cfg, "in get_cert_record");
+ my $user_cert = $self->get_client_certificate();
+ my $cs = PKI::Base::CertStore->new();
+ $cs->open($cfg);
+ my $ref = $cs->map_certificate($user_cert);
+ if (!defined($ref)) {
+$self->debug_log( $cfg, "in get_cert_record: map_certificate ref none");
+ return "";
+ }
+$self->debug_log( $cfg, "in get_cert_record: got map_certificate ref");
+ $cs->close();
+
+ return $ref;
+}
+
+sub get_current_roles()
+{
+ my ($self, $cfg) = @_;
+
+ my $uid = $self->get_current_uid($cfg);
+ my $us = PKI::Base::UserStore->new();
+ $us->open($cfg);
+ my @roles = $us->get_roles($uid);
+ $us->close();
+
+ return @roles;
+}
+
+sub get_roles_of()
+{
+ my ($self, $cfg, $uid) = @_;
+
+ my $us = PKI::Base::UserStore->new();
+ $us->open($cfg);
+ my @roles = $us->get_roles($uid);
+ $us->close();
+
+ return @roles;
+}
+
+sub admin_auth()
+{
+ my ($self, $cfg) = @_;
+
+ my $user_cert = $self->get_client_certificate();
+
+ # authentication
+ my $us = PKI::Base::UserStore->new();
+ $us->open($cfg);
+ my $ref = $us->map_user($user_cert);
+ if (!defined($ref)) {
+ return 0;
+ }
+ my @roles = $us->get_roles($ref->{'uid'});
+ $us->close();
+
+ # authorization
+ my $authorized_groups = $cfg->get("admin.authorized_groups");
+ $self->debug_log( $cfg, "in admin_auth: authorized groups are: $authorized_groups");
+ my @authorizedGroups = split(/,/, $authorized_groups);
+ my $authorized = 0;
+ foreach my $role (@roles) {
+ $self->debug_log( $cfg, "in admin_auth: user has group $role");
+ if (grep /^$role$/, @authorizedGroups) {
+ $self->debug_log( $cfg, "in admin_auth: group matched");
+ $authorized = 1;
+ }
+ }
+ if (!$authorized) {
+ $self->debug_log( $cfg, "in admin_auth: no group matched");
+ return 0;
+ }
+ return 1;
+}
+
+sub agent_auth()
+{
+ my ($self, $cfg) = @_;
+
+ my $user_cert = $self->get_client_certificate();
+
+ # authentication
+ my $us = PKI::Base::UserStore->new();
+ $us->open($cfg);
+ my $ref = $us->map_user($user_cert);
+ if (!defined($ref)) {
+ return 0;
+ }
+ my @roles = $us->get_roles($ref->{'uid'});
+ my $j = join(",", @roles);
+ $self->debug_log( $cfg, "in agent_auth: $ref->{'uid'} has roles: $j");
+ $us->close();
+
+ # authorization
+ my $authorized_groups = $cfg->get("agent.authorized_groups");
+ $self->debug_log( $cfg, "in agent_auth: authorized groups are: $authorized_groups");
+ my @authorizedGroups = split(/,/, $authorized_groups);
+ my $authorized = 0;
+ foreach $role (@roles) {
+ if (grep /^$role$/, @authorizedGroups) {
+ $self->debug_log( $cfg, "in agent_auth: group matched");
+ $authorized = 1;
+ }
+ }
+ if (!$authorized) {
+ $self->debug_log( $cfg, "in agent_auth: no group matched");
+ return 0;
+ }
+ return 1;
+}
+
+sub process {
+ my ($self) = @_;
+}
+
+sub escape_xml
+{
+ my ($v) = @_;
+ $v =~ s/\"/&quot;/g;
+ $v =~ s/\'/&apos;/g;
+ $v =~ s/\&/&amp;/g;
+ $v =~ s/</&lt;/g;
+ $v =~ s/>/&gt;/g;
+ return $v;
+}
+
+sub get_xml
+{
+ my ($s, $v) = @_;
+
+ my $result;
+ if (ref($v) eq "HASH") {
+ foreach my $xkey (keys %$v) {
+ $result .= "<" . $xkey . ">";
+ $result .= &get_xml($xkey, $v{$xkey});
+ # $result .= "-" . ref($xkey);
+ $result .= "</" . $xkey . ">";
+ }
+ } elsif (ref($v) eq "PKI::RA::GlobalVar") {
+ foreach my $xkey (keys %$v) {
+ $result .= "<" . $xkey . ">";
+ $result .= &get_xml($xkey, $$v{$xkey}->());
+ # $result .= "-" . ref($xkey);
+ $result .= "</" . $xkey . ">";
+ }
+ } elsif (ref($v) eq "ARRAY") {
+ my $pos = 0;
+ foreach my $item (@$v) {
+ $result .= "<element>";
+ $result .= &get_xml("p" . $pos, $item);
+ # $result .= "-" . ref($item);
+ $result .= "</element>";
+ $pos++;
+ }
+ } else {
+ $result .= &escape_xml($v);
+ }
+ return $result;
+}
+
+sub xml_output {
+ my ($self, $c) = @_;
+
+ my $result = "<xml>";
+ foreach $s (sort keys %$c) {
+ if ($s =~ /^__/) {
+ next;
+ }
+ $result .= "<" . $s . ">";
+ my $v = $$c{$s};
+ $result .= &get_xml($s, $v);
+ $result .= "</" . $s . ">";
+ }
+ $result .= "</xml>";
+ return "$result\n";
+}
+
+sub execute {
+ my ($self) = @_;
+ $self->process();
+}
+
+1;
diff --git a/base/ra/lib/perl/Template/Velocity.pm b/base/ra/lib/perl/Template/Velocity.pm
new file mode 100755
index 000000000..848de65fd
--- /dev/null
+++ b/base/ra/lib/perl/Template/Velocity.pm
@@ -0,0 +1,1099 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+use strict;
+
+package Template::Velocity::Executor;
+sub new;
+
+package Template::Velocity;
+
+
+# The Template::Velocity package implements a Template execution
+# engine similar to the Java Velocity package.
+
+use Parse::RecDescent;
+use Data::Dumper;
+use Thread::Semaphore;
+
+
+$Template::Velocity::parser;
+
+our $docroot="docroot";
+our $parser;
+my %parsetrees = ();
+my $debugflag = 0;
+my $semaphore;
+
+
+#GRAMMAR defined here
+
+my $vmgrammar = q{
+
+ {
+ use Data::Dumper;
+ sub Dumper
+ {
+ $::debugdumper = undef;
+ if ($::debugflag && $::debugdumper ) { return Data::Dumper(@_); }
+ else {""};
+ }
+
+ }
+
+
+# Template is the top-level object
+ template: <skip:'[ \t]*'> section(s) /\Z/
+
+ section: blockdirective
+ | nonblockdirective
+ | plainline
+
+ blockdirective: ifblock
+ | foreachblock
+
+ plainline : <skip:''> /[ \t]*/ ...!'#' linecomp(s?) /\n*/
+
+ HASH: '#'
+
+# HMM - this doesn't handle multiple variables on one line?
+ linecomp: variable
+ | <skip:'[ \t]*'> /[^\$\n]*/
+
+ nonblockdirective: '#' 'include' <commit> includeargs /\n*/ { $item[4] ; }
+ | '#' 'parse' <commit> parseargs /\n*/ { $item[4] ; }
+ | '#' 'set' <commit> setargs /\n*/ { $item[4] ; }
+ | <error:unknown command $text>
+
+
+ ifblock: ifdirective section(s) elseclause(?) enddirective
+
+
+# this bubbles up the result of the expression inside the if()
+# which is from the 'ifargs' rule
+ ifdirective: '#' 'if' <skip:'[ \t]*'> ifargs /\n/
+
+ enddirective: <skip:'[ \t]*'> '#' 'end' "\n"
+
+ elseclause: elsedirective section(s)
+
+ elsedirective: '#' 'else' "\n"
+
+ foreachblock: foreachdirective section(s) enddirective
+
+ foreachdirective: '#' 'foreach' foreachargs "\n"
+
+ ifargs: '(' expression ')'
+ | <error:Argument to if must be an expression: $text>
+
+ foreachargs: '(' variablename 'in' variable ')'
+ | <error:Arguments to 'foreach' must be of form \$a in \$b: $text>
+
+ includeargs: '(' string ')'
+ | <error:invalid argument to include: $text>
+
+ parseargs: '(' expression ')'
+ | <error:invalid argument to parsearges: $text>
+
+
+ setargs: <skip:'[ \t]*'> '(' assignment ')'
+ | <error:Argument to set must be an assignment : $text>
+
+
+# expression evaluation
+
+# this goes roughly in order of precendence:
+# ==
+# &&, ||
+# +, -
+# *
+# !
+
+# does not properly distinguish between lvalues and rvalues
+
+
+ expression: boolean
+ | <error>
+
+
+ assignment: variablename '=' boolean
+
+ boolean: equality (boolean_operator equality)(?)
+
+ boolean_operator: ( '&&' | '||' )
+
+ equality: summation (equality_operator summation)(?)
+
+
+ equality_operator: ( '==' | '!=' )
+
+ summation: product (summation_operator summation)(?)
+
+ summation_operator: ( '+' | '-' )
+
+
+# must parenthesize operator '*' to get it to appear in the $item array
+
+ product: negation ('*' product)(?)
+
+#XXX need to implement
+ negation: notoperator(?) factor
+
+ notoperator: "!"
+
+ factor: number
+ | string
+ | variable
+
+
+
+# These rules deal with variables
+# handles $process
+# $file.executablename
+# $process.getpid()
+# $person.getparent().getbrother().slap()
+# $fred.getchildren()
+
+# You'd make a dependency on the 'variable' rule if you want the value
+# of the variable.
+# You'd make a dependency on the 'variablename' rule if you want the
+# name of the variable.
+# (There's no real difference here - the expression evaluation is
+# in the variable() subroutine)
+
+ variable: variablename { ["variable", $item[1][1] ]; }
+
+ variablename: '$' identifier subfield(s?)
+ {
+ my $variableinfo = {
+ top => $item{identifier},
+ fields => $item{'subfield(s?)'}
+ };
+ $return = [ "variablename", \$variableinfo ];
+ }
+
+ subfield: '.' identifier arglist(?)
+ {
+ my $d;
+ my $a = $item{"arglist(?)"};
+ my $args;
+
+ #::debug "arglist = ".Dumper($a)."\n";
+ if ($a) {
+
+ my ($argcount, $al, $alpresent);
+
+ #$args = @{$a}->[2];
+ $args = $a->[0][2];
+ #::debug "arglist args=".Dumper($args)."\n";
+ $alpresent = $args;
+ $argcount = $#$args;
+ if ($alpresent && $argcount == -1) {
+ $args->[0] = [ ];
+ }
+ }
+
+ #::debug "arglist identifier=".$item{identifier}."\n";
+ $return = [ "subfield", {
+ fieldname => $item{identifier},
+ arglist => $args->[0],
+ } ];
+ }
+
+ arglist: '(' list(?) ')'
+
+ list: expression (',' list)(s?)
+
+
+# Basic data types
+# identifiers, numbers and strings
+
+ identifier: /[A-Za-z0-9_]+/ { $item[1]; }
+
+ number: /\d+/ {$item[1]; }
+
+ #XXX skip is all wrong here... should be in []
+ string: <skip:'[ \t]'> '"' <skip:""> /[^"]*/ '"' { $return = ["string",$item[4]]; }
+ | <skip:'[ \t]'> "'" <skip:""> /[^']*/ "'" { $return = ["string",$item[4]]; }
+
+
+# other literals
+ whitespace: /\s*/
+
+
+};
+
+
+# Get a parser object (transforming the built-in text grammar into RecDescent
+# data structure). This object can be reused for parsing multiple velocity files
+sub new
+{
+ #$::debugflag = 0;
+ my $class = shift;
+ $docroot = shift;
+ undef $::RD_HINT;
+ undef $::RD_WARN;
+ #$::RD_TRACE = 1;
+ $parser = new Parse::RecDescent($vmgrammar) or die "Bad Grammar\n";
+ $semaphore = new Thread::Semaphore;
+ $Data::Dumper::Maxdepth = 1;;
+ my $self = {};
+ $self->{parser} = $parser;
+ # ugly - :-(
+ $Template::Velocity::parser = $parser;
+ bless $self, $class;
+ return $self;
+}
+
+
+# Execute a template. Given a text string and a parser object, will return
+# a parse tree, useful for feeding into the executor.
+sub execute_string
+{
+ my $self = shift;
+ my $string = shift;
+ my $rule = shift;
+ if (! $rule ) { $rule = "template"; }
+ #print Dumper($self);
+
+ my $parser = $self->{parser};
+ my $parsetree = $parser->$rule($string);
+ my $executor = new Template::Velocity::Executor($parsetree, $parser );
+
+ my @value = $executor->run();
+ #my @value = Template::Velocity::Executor::execute($parsetree, $parser);
+ my $value = shift @value;
+ return $value;
+}
+
+sub execute_file_with_context
+{
+
+ my $self = shift;
+ my $filename = shift;
+ my $hash = shift;
+
+ # This perl Velocity implementation uses global variable to
+ # store values that go to the template. This is not thread
+ # safe and should be fixed in near future.
+ #
+ # For this release, we just a lock to prevent the global
+ # variable (i.e. symbol) being changed by multiple threads
+ # at the same time.
+
+ $semaphore->down;
+ my %c = %$hash;
+ foreach my $h (keys %c) {
+ $::symbol{$h} = $c{$h};
+ }
+
+ my $rule;
+ my $tree = $parsetrees{$filename};
+
+ if (! $tree) {
+ $rule = "template";
+ open my $fh, "<$docroot/$filename" or return undef;
+ my $string = join "",<$fh>;
+ close $fh;
+ $tree = $parser->$rule($string);
+ $parsetrees{$filename} = $tree;
+ }
+
+ my $executor = new Template::Velocity::Executor($tree, $parser );
+
+ my @value = $executor->run();
+ my $value = shift @value;
+
+ $semaphore->up;
+
+ return $value;
+
+
+}
+
+sub execute_file
+{
+
+ my $self = shift;
+ my $filename = shift;
+
+ my $rule;
+ my $tree = $parsetrees{$filename};
+
+ if (! $tree) {
+ $rule = "template";
+ open my $fh, "<$docroot/$filename" or return undef;
+ my $string = join "",<$fh>;
+ close $fh;
+ $tree = $parser->$rule($string);
+ $parsetrees{$filename} = $tree;
+ }
+
+ my $executor = new Template::Velocity::Executor($tree, $parser );
+
+ my @value = $executor->run();
+ my $value = shift @value;
+ return $value;
+
+
+}
+
+
+
+
+
+
+
+
+sub Dumper
+{
+ return "";
+ if ($::debugflag && $::debugdumper) {
+ return Data::Dumper->Dump([@_]);
+ }
+ else {""};
+}
+
+
+
+
+# This autoaction returns an array of each parse element
+# The net result is a parse tree
+# I couldn't use <autotree> because I wanted to preserve
+# the order of the elements, and <autotree> returns a
+# hashtable, not an array
+
+$::RD_AUTOACTION = q{
+ [@item];
+};
+
+# debug flags set here
+
+
+
+
+
+
+######### EXECUTE FUNCTIONS
+
+
+# These functions deal with executing the velocity parse tree
+{
+ package Template::Velocity::Executor::Rules;
+ use Data::Dumper;
+
+ # this imports symbols from these other packages, so
+ # we don't have to always use the fully-qualified names
+ *exe_all = \&Template::Velocity::Executor::exe_all;
+ *exe_optional = \&Template::Velocity::Executor::exe_optional;
+ *execute = \&Template::Velocity::Executor::execute;
+ *debug = \&Template::Velocity::Executor::debug;
+ *indent = \&Template::Velocity::Executor::indent;
+ *deindent = \&Template::Velocity::Executor::deindent;
+#XXX probably should be $, not &
+ *docroot = \&Template::Velocity::docroot;
+
+ sub Dumper
+ {
+ return "";
+ if ($::debugflag && $::debugdumper) { return Dumper(@_); }
+ else {""};
+ }
+
+ #template: <skip:'[ \t]*'> section(s) /\Z/
+ sub template {
+ my $f = "template";
+ my @item = exe_all(@_);
+ debug ("$::level $f - sections should be an array of text: .".Dumper($item[2])."\n");
+ my $sections = $item[2];
+ debug ("sections is a: ".(ref $sections)." - it should be an array\n");
+ my $r= ( join "", @{$item[2]});
+ return $r;
+ }
+
+
+ #linecomp: variable
+ # | <skip:'[ \t]*'> /[^\$\n]*/
+ sub linecomp {
+ my $item;
+ debug ("linecomp: _[2] = '".$_[2]."'\n");
+ if ($_[2]) {
+ debug ("linecomp: inside if\n");
+ $item = $_[1].$_[2];
+ } else {
+ debug ("linecomp: inside else{\n");
+ ($item) = exe_all($_[1]);
+ debug ("linecomp: end of else}\n");
+ debug ("linecomp: item =\n".Dumper($item)."\n");
+ }
+ debug ("linecomp: returning $item\n");
+ return $item;
+ }
+
+ # plainline : <skip:''> /[ \t]*/ ...!'#' linecomp(s?) /\n+/
+ sub plainline {
+ my @item = exe_all(@_);
+ debug ("$::level in plainline - linecomps should be an array of text: .".Dumper($item[4])."\n");
+ my $r = join "", @{$item[4]};
+ debug ("$::level in plainline - joined as: $r\n");
+ $r = $item[2] . $r. $item[5];
+ debug ("$::level in plainline - returning : $r\n");
+ return $r;
+ }
+
+ sub expression {
+ debug ("$::level expression = ".Dumper($_[1])."\n");
+ my ($item) = exe_all($_[1]);
+ debug ("$::level expression returning $item\n");
+ return $item;
+ }
+
+ #foreachblock: foreachdirective section(s) enddirective
+ sub foreachblock {
+ my $f = "foreachblock";
+ debug ("$::level $f started!\n");
+ my ($directive) = exe_all($_[1]);
+ debug ("$::level $f directive = \n".Dumper($directive)."\n");
+ my ($variable, $list) = @{$directive};
+ my $variablename = $$variable->{top};
+ debug ("$::level $f variable = $variablename\n");
+ debug ("$::level $f list = \n".Dumper($list)."\n");
+
+ my $result = "";
+ foreach my $q (@{$list}) {
+ debug ("$::level $f q=$q\n");
+ $::symbol{$variablename} = $q;
+ debug ("$::level $f setting variable $variablename = $q\n");
+
+ my ($sections) = exe_all($_[2]);
+ debug ("$::level $f sections was: ".Dumper($sections)."\n");
+ $result .= join "",@{$sections};
+ }
+ return $result;
+ }
+
+ #foreachdirective: '#' 'foreach' foreachargs "\n"
+ sub foreachdirective {
+ my ($item) = exe_all($_[3]);
+ return $item;
+ }
+
+ #foreachargs: '(' variablename 'in' expression ')'
+ sub foreachargs {
+ my $f = "foreachargs";
+ my ($variable, $list) = exe_all($_[2], $_[4]);
+ debug ("$::level $f variable = \n".Dumper($variable)."\n");
+ debug ("$::level $f list = \n".Dumper($list)."\n");
+ return [$variable, $list];
+ }
+
+ # XXX if block should only execute section(s) if if arg is positve)
+ # likewise for else
+ #ifblock: ifdirective section(s) elseclause(?) enddirective
+ sub ifblock {
+ my $f = "ifblock";
+ my @item = exe_all(@_);
+ debug ("$::level $f - sections should be an array of text: .".Dumper($item[2])."\n");
+ my $sections = $item[2];
+ my $else = $item[3];
+ debug ("$::level $f sections is a: ".(ref $sections)." - it should be an array\n");
+ debug ("$::level item1: if expression = ".$item[1]."\n");
+ debug ("$::level $f elseclause is a: ".(ref $else)." - it should be an scalar\n");
+ my $r= (
+ $item[1]>0 ? # if expression
+ (join "", @{$item[2]}) :
+ ($item[3] ? join "",@{$item[3]} : "")
+ );
+ # this is not quite right ... elseclause returns a scalar (it joins the sections)
+ # so why do I have to join again here? possibly because it's a '?'
+ return $r;
+ }
+
+ #elseclause: elsedirective section(s)
+ sub elseclause {
+ my $f = "elseclause";
+ my ($sections) = exe_all($_[2]);
+ debug ("$::level $f sections is a: ".(ref $sections)." - it should be an array\n");
+ my $return = join "", @{$sections};
+ debug ("$::level $f returning: $return\n");
+ return $return;
+ }
+
+ sub ifargs {
+ debug ("$::level ifargs [2] = ".Dumper($_[2])."\n");
+ my ($item) = exe_all($_[2]);
+ debug ("$::level item = ".Dumper($item)."\n");
+ my $r = $item>0 ? 1 : 0;
+ debug ("$::level ifargs returning $r\n");
+ return $r;
+ }
+
+ #ifdirective: '#' 'if' <skip:'[ \t]*'> ifargs /\n/
+ sub ifdirective {
+ my ($item) = exe_all($_[4]);
+ my $r = $item>0 ? 1 : 0;
+ debug ("$::level ifdirective returning $r\n");
+ return $r;
+ }
+
+ #boolean: equality (boolean_operator equality)(?)
+ sub boolean {
+ my $f = "boolean";
+ my ($equality, $alt) = ( execute($_[1]), $_[2]);
+ my $r = $equality;
+ if (scalar @$alt) {
+ my ($op, $equality2) = exe_optional($alt, 1,2);
+
+ if ($op eq '&&') {
+ $r = $equality && $equality2;
+ }
+ if ($op eq '||') {
+ $r = $equality || $equality2;
+ }
+ }
+
+ return $r;
+ }
+
+
+ #summation: product (summation_operator summation)(?)
+ sub summation {
+ #my @item = exe_all(@_);
+ my $f = "summation";
+ my ($product, $alt) = ( execute($_[1]), $_[2]);
+ debug("$::level $f - product = $product, alternation = $alt\n");
+ debug("$::level $f - alternation = \n".Dumper($alt)."\n");
+
+ if (scalar @$alt) {
+ if (0) {
+ debug("$::level $f - alt1= \n".Dumper($alt->[0][1])."\n");
+ debug("$::level $f - alt2= \n".Dumper($alt->[0][2])."\n");
+ my ($operator, $summation) = ( execute($alt->[0][1]), execute($alt->[0][2]),);
+ }
+ my ($operator, $summation) = exe_optional($alt, 1,2);
+
+ if ($operator eq '+') { return $product + $summation;
+ } else { return $product - $summation; }
+ } else {
+ return $product;
+ }
+ }
+
+
+
+ #equality: summation (equality_operator summation)(?)
+ sub equality {
+ my $f = "equality";
+ my ($summation, $alt) = ( execute($_[1]), $_[2] );
+
+ if (scalar @$alt) {
+ my ($operator, $summation2) = exe_optional($alt, 1,2);
+
+ # string comparison used, so (0.0) is NOT equal to (0)
+ if ($operator eq '==') { return ($summation eq $summation2) ? 1:0; }
+ else { return ($summation eq $summation2) ? 0:1; }
+ } else {
+ return $summation;
+ }
+ }
+
+
+ sub product {
+ my $f = "product";
+ my ($negation, $alt) = ( execute($_[1]), $_[2]);
+ debug("$::level $f negation = $negation, alternation = $alt\n");
+ debug("$::level $f - alternation = ".Dumper($alt)."\n");
+
+ if (scalar @$alt) {
+ if (0) {
+ debug("$::level $f - alt1= \n".Dumper($alt->[0][1])."\n");
+ debug("$::level $f - alt2= \n".Dumper($alt->[0][2])."\n");
+ my ($operator, $product) = ( execute($alt->[0][1]), execute($alt->[0][2]),);
+ }
+ my ($operator, $product) = exe_optional($alt,1,2);
+ return ($negation * $product);
+ } else {
+ return $negation;
+ }
+ }
+
+ sub factor {
+ my ($value) = exe_all($_[1]);
+ return $value;
+ }
+
+ #negation: notoperator(?) factor
+ sub negation {
+ debug ("$::level in negation... input = ".(join ",",@_)."\n");
+ #my @item = exe_all(@_);
+ my ($alt, $value) = ( $_[1], execute($_[2]) );
+ debug ("$::level negation: alternation= $alt\n");
+ debug ("$::level negation: value = $value\n");
+ my $operator = execute($alt->[0][1]);
+
+ my $r;
+ if ($operator && $operator eq '!') {
+ if ($value ) { $r = 0; }
+ else { $r = 1; }
+ debug ("$::level negation: inverting\n");
+ } else {
+ debug ("$::level negation: not inverting\n");
+ $r = $value;
+ }
+ debug ("$::level negation: returning $r\n");
+ return $r;
+ }
+
+ #setargs: <skip:'[ \t]*'> '(' assignment ')'
+ sub setargs {
+ my $f = "setargs";
+ my ($args) = exe_all($_[3]);
+ debug("$::level $f args = \n".Dumper($args)."\n");
+ my ($variable, $value) = @{$args};
+ debug("$::level $f variable type =".(ref $variable)."\n");
+ debug("$::level $f variable = \n".Dumper($variable)."\n");
+ my $symbolname = $$variable->{top};
+ debug("$::level $f setting variable '$symbolname' = $value\n");
+ $::symbol{$symbolname} = $value;
+ return "";
+ }
+
+ #assignment: variablename '=' boolean
+ sub assignment {
+ my $f = "assignment";
+ my ($variable, $value) = exe_all($_[1],$_[3]);
+ debug("$::level $f variable = \n".Dumper($variable)."\n");
+ my $r = [ $variable, $value ];
+ debug("$::level $f returning: \n".Dumper($r)."\n");
+ return $r;
+ }
+
+ #includeargs: '(' string ')'
+ sub includeargs {
+ my $f = "includeargs";
+ my ($filename ) = execute($_[2]);
+
+ debug("including file: $filename\n");
+ open my $fh, "<$docroot/$filename" or return "filenotfound $docroot/$filename!\n";
+ my $file = join "", <$fh>;
+ close FILE;
+
+ return $file;
+ }
+
+ sub parseargs {
+ my $f = "parseargs";
+ my ($filename ) = execute($_[2]);
+
+ debug("parsing file: $filename\n");
+
+ #open my $fh, "<$docroot/$filename" or return "filenotfound $docroot/$filename!\n";
+ #my $file = join "", <$fh>;
+ #close FILE;
+
+ #my $parsetree = $Template::Velocity::parser->template($file);
+ #my @value = execute($parsetree);
+ #my $value = shift @value;
+
+ my @value = Template::Velocity::execute_file(undef,$filename);
+ my $value = shift @value;
+
+ return $value;
+ }
+
+# variables
+
+# variables
+# this rule converts a variable name/identifier into its value
+# $main.subfield(argument1,argument2).subfield2(arg1,arg2)
+# There are two data structures at work here.
+# 1. the data structure specifying the variable name to be queried
+# this represents $a.b.c(100,9,5,4)
+#{
+# 'top' => 'a'
+# 'fields' => [
+# { 'fieldname' => 'b', 'arglist' => undef },
+# { 'fieldname' => 'c', 'arglist' => [ '100', 9, 5, '4', ], }
+# ],
+#}
+# 2. Data structure specifying the symbol table
+
+# return value could be:
+# a scalar: either a string/number value or reference to an array of values
+# an array
+
+ sub variable {
+# look up the root object in the symbol table
+ my $f = "variable";
+ debug("$::level $f: input\n".Dumper(\@_)."\n");
+ my $var = $_[1];
+ debug("$::level $f var=\n".Dumper($var)."\n");
+# $$var works with # 27: '#set (\$a=1+3)\n\$a\n'
+#0 REF(0x8fa0510)
+# -> HASH(0x8fa1454)
+# 'fields' => ARRAY(0x8fa8c08)
+# empty array
+# 'top' => 'a'
+
+# $var works with # 25: '$employee.add(100,4+5,2+3,4,4,5,6)'
+#DB<2> x $var
+#0 HASH(0x9c7a340)
+# 'fields' => ARRAY(0xa06e7d8)
+# 0 ARRAY(0xa06e9ac)
+# 0 'subfield'
+# 1 HASH(0xa06e880)
+# 'arglist' => ARRAY(0xa074184)
+
+ my $top = $$var->{top}; # name of the root object
+ debug("$::level $f top=\n".Dumper($top)."\n");
+ my $fields = $$var->{fields}; # array of the subidentifiers
+ my $val = "";
+
+ debug("$::level $f - top_id = $top\n");
+ debug("$::level $f : var: \n".Dumper($var)."\n");
+ debug("$::level $f - fields = \n".Dumper($fields)."\n");
+
+
+ debug("$::level $f : top = ".$top."\n");
+ if (! defined $::symbol{$top} ) {
+# XXX
+ debug ("symbol table = ",(join ",",sort keys %::symbol)."\n");
+ debug ("undefined variable: $top\n");
+ return 0;
+ }
+ debug("$::level $f symbol table: \n".Dumper(\%::symbol)."\n");
+ $val = $::symbol{$top};
+ debug("$::level $f val before: \n".Dumper($val)."\n");
+
+ debug("$::level $f - fields = \n".Dumper($fields)."\n");
+ my $pass = 1;
+ foreach my $field (@$fields) {
+ my $args;
+
+ my ($fieldname, $values);
+ {
+ debug("$::level $f pass $pass \@_=\n".Dumper(\@_)."\n");
+ debug("$::level $f before strip field = \n".Dumper($field)."\n");
+#shift @$fn; # 'subfield' string
+#$fn = $fn->[0];
+#$fn = [ (@{$fn}) ];
+#shift @$fn;
+ debug("$::level $f after strip fn = \n".Dumper($field)."\n");
+
+ $fieldname = $field->[1]->{fieldname};
+ debug("$::level $f processing field: $fieldname\n");
+ $args= $field->[1]->{arglist};
+
+
+# convert the argument list (which could be expressions, other
+# variables, etc) into raw values
+ if ($args) {
+ debug("$::level $f executing $fieldname with args:\n".Dumper($args)."\n");
+ ($values) = execute($args);
+ debug("$::level $f returned values:\n".Dumper($values)."\n");
+ }
+ }
+
+ debug("$::level $f after execute, \@_=\n".Dumper(\@_)."\n");
+
+#call the function
+ if (ref $val) {
+ debug("$::level $f : inside loop(before) {\n".Dumper($val)."\n");
+ debug("$::level $f : inside loop(before) {\n".Dumper($val)."\n");
+ if ($args) {
+ debug("$::level $f: function call\n");
+#$val = $$val->$fieldname ($args); # method call
+ my $func = $val->{$fieldname}; # method call
+ debug("$::level $f: $fieldname func=\n ".Dumper($func)."\n");
+ no strict;
+ $val = &$func($val, @$values);
+ debug("$::level $f: $fieldname result=$val\n");
+ debug("$::level $f: $fieldname result=\n".Dumper($val)."\n");
+
+ } else {
+ &::debug("$::level $f: plain field access\n");
+ if (ref $val eq "REF") {
+ $val = $$val->{$fieldname}; # field access
+ } else {
+ $val = $val->{$fieldname}; # field access
+ }
+ }
+ debug("$::level $f } inside loop(after val retrieval) val=\n".Dumper($val)."\n");
+ }
+ $pass++;
+
+ }
+
+ return $val;
+ }
+
+ #$return = [ "variablename", \$variableinfo ];
+ sub variablename {
+ my $f = "variablename";
+ debug("$::level $f: input\n".Dumper(\@_)."\n");
+ my $var = $_[1];
+ return $var;
+ }
+
+ #arglist: '(' list(?) ')'
+ sub arglist {
+ my ($list) = exe_all($_[2]);
+ debug("$::level list: ".Dumper($list)."\n");
+ if ($list) {
+ my $ll = $list->[0];
+ debug("$::level ll \n".Dumper($ll)."\n");
+ debug("$::level \$\$list: \n");
+ return $ll;
+ }
+ return undef;
+ }
+
+ #list: expression (',' list)(s?)
+ sub list {
+ my ($expr, $alt) = ( execute($_[1]), $_[2] );
+
+ if (scalar @$alt) {
+ my ($list) = exe_optional($alt, 2);
+
+ debug("$::level list: expr: $expr\n");
+ debug("$::level list: list: $list\n:");
+ debug("$::level list ".Dumper($list)."\n");
+ my $r = [ $expr, (@$list) ];
+ return $r;
+ }
+ debug("$::level returning simple expression: $expr\n:");
+ return [$expr];
+ }
+
+
+
+ sub _default {
+ debug ("$::level default rule {\n");
+ indent();
+ debug ("$::level parsing parameters\n");
+ my @item = exe_all(@_);
+ debug ("$::level default rule - last item in array is: ".$item[$#item]."\n");
+ my $r = join "",@item[1..$#item];
+ debug ("$::level default rule - returning: $r\n");
+ deindent();
+ debug ("$::level }\n");
+ return $r;
+
+ }
+
+
+}
+
+
+package Template::Velocity::Executor;
+
+use Data::Dumper;
+
+
+
+sub new
+{
+ my $class = shift;
+
+ my $parsetree = shift;
+ my $parser = shift;
+
+ my $self = {};
+ $self->{parser} = $parser;
+ $self->{parsetree} = $parsetree;
+ bless $self, $class;
+ return $self;
+}
+
+
+sub run {
+ my $self = shift;
+
+ return (execute($self->{parsetree}));
+}
+
+
+
+my $level = " ";
+
+sub debug {
+ if ($::debugflag) {
+ print @_;
+ }
+}
+
+# This basically all works calling execute($parsetree).
+# Execute will look the Parsetree, which is built by a special autoaction
+#
+# It will call top-down, into functions called 'Executor::XXX', (where XXX is
+# the name of the production)
+#
+# Additional trees, representing child productions, will be passed in
+# as arguments to the Executor::XXX function. These arguments be processed
+# before the Executor::XXX function can proceed.
+#
+# If no such function is present, Executor:_default will be run
+#
+# To process the arguments, use this in the Executor function:
+# my @item = exe(@_);
+# Which will give you an @item array similar to that in the RD rules, one
+# exception being that productions which return arrays are flattened into
+# the @item array. (bad idea?)
+#
+
+
+
+# executes a parsetree (gotten as a result of calling recdescent $parser->rule()
+# and returns the string value of the result.
+
+sub Dumper {
+ "";
+}
+
+sub execute {
+ my $result;
+ my $tree = shift; # a reference to a tree is passed in
+ debug "$level execute: {\n";
+ indent();
+ debug ("$level tree = \n".Dumper($tree)."\n");
+
+# there are 3 possible things this tree could be:
+
+# 1 a scalar .. in which case this rule represents a literal, and the
+# the literal is just returned
+#
+# 2 an array of the form (array, ...) - in which case this is the result of a production
+# which returned an array of trees. This happens
+# if you specify (s), (?), etc, in a production.
+# 3 an array of the form (scalar, ...) - in which case this refers to a subrule
+#
+
+# case 1...
+ my $type = ref $tree;
+ if ($type) {
+ debug "\n$level tree type: ".(ref $tree)." \n";
+ } else {
+ debug "\n$level tree type: scalar \n";
+ }
+ if ($type ne "ARRAY") {
+ debug "$level returning literal: '$tree'\n";
+ deindent();
+ debug "$level }\n\n";
+ return $tree;
+ }
+
+ my @result;
+
+# if this tree is the result of a auto-generated rule (e.g. alternation)
+# then tree[0] is not a name.. it is an array. just call the default action with
+# the arguments
+
+ my $rule = @{$tree}->[0]; # rule name is first
+
+ if ($rule && ref $rule eq "ARRAY") { # case 2
+ debug "$level element[0] is an array (case 2) \n";
+ debug "$level contents of input: \n".Dumper(\@{$tree})."\n";
+ #@result = exe(@{$rule});
+ debug "$level running exe on the array..\n";
+ # not sure about this...
+ @result = (exe_all(@{$tree}));
+ debug "$level contents of output: \n".Dumper(\@result)."\n";
+ #shift @result; # get rid of function name
+ $result = \@result;
+
+ } else { # case 3
+ my @args = @{$tree};
+
+ debug "$level rule is a function to execute (case 3): '$rule'\n";
+ indent();
+ my $qr = "Template::Velocity::Executor::Rules::$rule";
+ if (defined &$qr) {
+ no strict ;
+ $result = (&$qr(@args));
+ } else {
+ debug "$level no function defined for: '$rule' - calling default action\n";
+ $result = Template::Velocity::Executor::Rules::_default(@args);
+ }
+ }
+ deindent();
+ debug "$level function: $rule returned=\n".Dumper($result)."\n";
+
+ debug "$level }\n";
+ return $result;
+
+ }
+
+# these hold and set the current indent level. It's only used for nested debug messages
+sub indent {
+ if (!$debugflag) { return; }
+ $level .= " ";
+ $Data::Dumper::Pad = $level." ";
+}
+sub deindent {
+ if (!$debugflag) { return; }
+ $level = substr ($level,0,-2);
+ $Data::Dumper::Pad = $level." ";
+}
+
+
+sub exe_optional {
+ my @r;
+ my $f = shift;
+ foreach my $q (@_) {
+ debug("$level: getting arg# $q\n");
+ push @r, execute($f->[0][$q]);
+ }
+ return @r;
+}
+
+# exe: for each argument, run the 'execute' function
+#
+
+sub exe_all {
+ my $d = $Data::Dumper::Maxdepth;
+ $Data::Dumper::Maxdepth = 9;
+ debug "\n$level exe_all (".$_[0].") arguments: {\n".Dumper(\@_)." \n";
+ my @r;
+ indent();
+
+ foreach my $i (@_) {
+ push @r, execute($i);
+ }
+ deindent();
+ debug "$level exe_all: returning: \n".Dumper(\@r)."$level}\n\n";
+ $Data::Dumper::Maxdepth = $d;
+ return @r;
+}
+
+
+
+
+
+#package PKI::RA::GlobalVar;
+
+#sub new { my $self = {}; bless $self; return $self; }
+
+
+1;
+
diff --git a/base/ra/scripts/nss_pcache b/base/ra/scripts/nss_pcache
new file mode 100755
index 000000000..bf978b48b
--- /dev/null
+++ b/base/ra/scripts/nss_pcache
@@ -0,0 +1,66 @@
+#!/bin/bash
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+# 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 '$0' from non-existent directory!"
+ exit 255
+fi
+
+OS=`uname -s`
+
+if [ $OS = "Linux" ]; then
+ PLATFORM=`uname -i`
+ if [ $PLATFORM = "i386" ]; then
+ # 32-bit Linux
+ LD_LIBRARY_PATH=/usr/lib/dirsec:/usr/lib:$LD_LIBRARY_PATH
+ elif [ $PLATFORM = "x86_64" ]; then
+ # 64-bit Linux
+ LD_LIBRARY_PATH=/usr/lib64/dirsec:/usr/lib64:/usr/lib:$LD_LIBRARY_PATH
+ fi
+ export LD_LIBRARY_PATH
+elif [ $OS = "SunOS" ]; then
+ PLATFORM=`uname -p`
+ if [ "${PLATFORM}" = "sparc" ] &&
+ [ -d "/usr/lib/sparcv9/" ] ; then
+ PLATFORM="sparcv9"
+ fi
+ if [ $PLATFORM = "sparc" ]; then
+ # 32-bit Solaris
+ LD_LIBRARY_PATH=/usr/lib/dirsec:/usr/lib:$LD_LIBRARY_PATH
+ elif [ $PLATFORM = "sparcv9" ]; then
+ # 64-bit Solaris
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/dirsec:/usr/lib/sparcv9:/usr/lib/dirsec:/usr/lib:$LD_LIBRARY_PATH
+ fi
+ export LD_LIBRARY_PATH
+fi
+
+FORTITUDE_DIR=/usr/sbin
+if [ $OS = "SunOS" ]; then
+ FORTITUDE_DIR=/opt/fortitude/bin
+fi
+
+$FORTITUDE_DIR/nss_pcache $@
diff --git a/base/ra/scripts/schema.sql b/base/ra/scripts/schema.sql
new file mode 100644
index 000000000..18fd8a39c
--- /dev/null
+++ b/base/ra/scripts/schema.sql
@@ -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.
+#
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+#
+# sql schema
+#
+CREATE TABLE requests ( type TEXT, ip TEXT, note TEXT, data TEXT, output TEXT, serialno TEXT, subject_dn TEXT, meta_info TEXT, status TEXT, errorString TEXT, processed_by TEXT, assigned_to TEXT, updated_at TEXT, created_at TEXT, created_by TEXT )
+CREATE TABLE users ( uid TEXT, name TEXT, password TEXT, email TEXT, certificate TEXT, created_at TEXT, created_by TEXT )
+CREATE TABLE groups ( gid TEXT, name TEXT, created_at TEXT, created_by TEXT )
+CREATE TABLE roles ( uid TEXT, gid TEXT )
+CREATE TABLE pins ( key TEXT, pin TEXT, rid TEXT, created_at TEXT, created_by TEXT )
+CREATE TABLE certificates ( rid TEXT, csr TEXT, subject_dn TEXT, certificate TEXT, serialno TEXT, approved_by TEXT, created_at TEXT )
+#
+# add defaults
+#
+INSERT INTO groups (gid, name) values ('administrators','Administrators');
+INSERT INTO groups (gid, name) values ('agents','Agents');
diff --git a/base/ra/setup/CMakeLists.txt b/base/ra/setup/CMakeLists.txt
new file mode 100644
index 000000000..f5f069cdb
--- /dev/null
+++ b/base/ra/setup/CMakeLists.txt
@@ -0,0 +1,8 @@
+set(VERSION ${APPLICATION_VERSION})
+
+install(
+ FILES
+ registry_instance
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/setup
+)
diff --git a/base/ra/setup/registry_instance b/base/ra/setup/registry_instance
new file mode 100644
index 000000000..64a73197f
--- /dev/null
+++ b/base/ra/setup/registry_instance
@@ -0,0 +1,116 @@
+# Establish PKI Variable "Slot" Substitutions
+
+PKI_FLAVOR=[PKI_FLAVOR]
+export PKI_FLAVOR
+
+PKI_SUBSYSTEM_TYPE=[PKI_SUBSYSTEM_TYPE]
+export PKI_SUBSYSTEM_TYPE
+
+PKI_USER=[PKI_USER]
+export PKI_USER
+
+PKI_GROUP=[PKI_GROUP]
+export PKI_GROUP
+
+PKI_INSTANCE_ID=[PKI_INSTANCE_ID]
+export PKI_INSTANCE_ID
+
+PKI_INSTANCE_INITSCRIPT=[PKI_INSTANCE_INITSCRIPT]
+export PKI_INSTANCE_INITSCRIPT
+
+PKI_HTTPD_CONF=[HTTPD_CONF]
+export PKI_HTTPD_CONF
+
+PKI_SERVER_ROOT=[SERVER_ROOT]
+export PKI_SERVER_ROOT
+
+PKI_SYSTEM_USER_LIBRARIES=[SYSTEM_USER_LIBRARIES]
+export PKI_SYSTEM_USER_LIBRARIES
+
+PKI_FORTITUDE_DIR=[FORTITUDE_DIR]
+export PKI_FORTITUDE_DIR
+
+PKI_NSS_CONF=[NSS_CONF]
+export PKI_NSS_CONF
+
+PKI_SERVER_NAME=[SERVER_NAME]
+export PKI_SERVER_NAME
+
+PKI_LOCK_FILE="[PKI_LOCKDIR]/${PKI_INSTANCE_ID}.pid"
+export PKI_LOCK_FILE
+
+PKI_PID_FILE="[PKI_PIDDIR]/${PKI_INSTANCE_ID}.pid"
+export PKI_PID_FILE
+
+PKI_SELINUX_TYPE="pki_ra_t"
+export PKI_SELINUX_TYPE
+
+pki_instance_configuration_file=${PKI_SERVER_ROOT}/conf/CS.cfg
+export pki_instance_configuration_file
+
+RESTART_SERVER=${PKI_SERVER_ROOT}/conf/restart_server_after_configuration
+export RESTART_SERVER
+
+########################################################################
+# This section contains modified content of "/etc/sysconfig/httpd" #
+########################################################################
+# Configuration file for the ${PKI_INSTANCE_ID} service.
+
+#
+# The default processing model (MPM) is the process-based
+# 'prefork' model. A thread-based model, 'worker', is also
+# available, but does not work with some modules (such as PHP).
+# The service must be stopped before changing this variable.
+#
+PKI_HTTPD=${PKI_FORTITUDE_DIR}/sbin/httpd.worker
+export PKI_HTTPD
+
+#
+# To pass additional options (for instance, -D definitions) to the
+# httpd binary at startup, set PKI_OPTIONS here.
+#
+PKI_OPTIONS="-f ${PKI_HTTPD_CONF}"
+export PKI_OPTIONS
+
+#
+# By default, the httpd process is started in the C locale; to
+# change the locale in which the server runs, the PKI_HTTPD_LANG
+# variable can be set.
+#
+PKI_HTTPD_LANG=C
+export PKI_HTTPD_LANG
+########################################################################
+# #
+########################################################################
+
+# This will prevent initlog from swallowing up a pass-phrase prompt if
+# mod_ssl needs a pass-phrase from the user.
+PKI_INITLOG_ARGS=""
+export PKI_INITLOG_ARGS
+
+# Set PKI_HTTPD=/usr/sbin/httpd.worker in /etc/sysconfig/httpd to use a server
+# with the thread-based "worker" MPM; BE WARNED that some modules may not
+# work correctly with a thread-based MPM; notably PHP will refuse to start.
+
+# Path to the server binary and short-form for messages.
+httpd=${PKI_HTTPD}
+export httpd
+
+pki_logs_directory=${PKI_SERVER_ROOT}/logs
+export pki_logs_directory
+
+# see if httpd is linked with the openldap libraries - we need to override
+# their use of OpenSSL
+if [ ${OS} = "Linux" ]; then
+ hasopenldap=0
+
+ /usr/bin/ldd ${httpd} 2>&1 | grep libldap- > /dev/null 2>&1 && hasopenldap=1
+
+ if [ ${hasopenldap} -eq 1 ] ; then
+ LD_PRELOAD="${PKI_SYSTEM_USER_LIBRARIES}/libssl3.so:${LD_PRELOAD}"
+ export LD_PRELOAD
+ fi
+elif [ ${OS} = "SunOS" ]; then
+ LD_PRELOAD_64="${PKI_SYSTEM_USER_LIBRARIES}/dirsec/libssl3.so:${LD_PRELOAD_64}"
+ export LD_PRELOAD_64
+fi
diff --git a/base/scripts/enable_cvs_keywords_in_svn b/base/scripts/enable_cvs_keywords_in_svn
new file mode 100755
index 000000000..fd14a885f
--- /dev/null
+++ b/base/scripts/enable_cvs_keywords_in_svn
@@ -0,0 +1,97 @@
+#!/bin/bash
+# BEGIN COPYRIGHT BLOCK
+# (C) 2010 Red Hat, Inc.
+# All rights reserved.
+# END COPYRIGHT BLOCK
+
+# Always switch into this base directory
+# prior to script execution so that all
+# of its output is written to this directory
+cd `dirname $0`
+
+# Retrieve the name of this base directory
+PKI_PWD=`pwd`
+
+# Retrieve the base name of this script
+PKI_SCRIPT=`basename $0`
+
+# Print pre-script instructions
+printf "REMINDER: ALWAYS remember to execute 'svn update' on 'pki/base'\n"
+printf " PRIOR to executing '${PKI_SCRIPT}'!\n\n"
+while :
+do
+ printf "Have you executed 'svn update' at the 'pki/base' level? [yn] "
+ read ANSWER
+ printf "\n"
+ if [ "${ANSWER}" = "N" ] ||
+ [ "${ANSWER}" = "n" ] ; then
+ printf "\n"
+ printf "Please execute 'svn update'\n"
+ printf "PRIOR to executing '${PKI_SCRIPT}'!\n\n"
+ exit 255
+ elif [ "${ANSWER}" = "Y" ] ||
+ [ "${ANSWER}" = "y" ] ; then
+ printf "\n"
+ break
+ else
+ continue
+ fi
+done
+
+# Set equivalent "SVN" keyword properties to enable
+# legacy "CVS" keywords in pre-existing PKI files
+SVN_KEYWORDS="Author Date Header Id Revision URL"
+
+# Generate timestamp
+PKI_TIMESTAMP=`date +%Y%m%d%H%M%S`
+
+# Create the name of the list
+PKI_LIST=list.${PKI_TIMESTAMP}
+
+# Switch into the 'pki/base' directory
+cd ${PKI_PWD}/..
+
+# Fill the list with the name of each ".c", ".cpp", and ".java" file
+find . -type f | grep -v '/\.svn/' | egrep "\.(c|cpp|h|pm|java)$" > ${PKI_LIST}
+
+# Complete the list with miscellaneous files containing legacy "CVS" keywords
+echo "./ca/shared/conf/catalina.policy" >> ${PKI_LIST}
+echo "./ca/shared/conf/dtomcat5" >> ${PKI_LIST}
+echo "./ocsp/shared/conf/catalina.policy" >> ${PKI_LIST}
+echo "./ocsp/shared/conf/dtomcat5" >> ${PKI_LIST}
+echo "./tks/shared/conf/catalina.policy" >> ${PKI_LIST}
+echo "./tks/shared/conf/dtomcat5" >> ${PKI_LIST}
+echo "./kra/shared/conf/catalina.policy" >> ${PKI_LIST}
+echo "./kra/shared/conf/dtomcat5" >> ${PKI_LIST}
+echo "./setup/pkicommon" >> ${PKI_LIST}
+echo "./setup/pkicreate" >> ${PKI_LIST}
+echo "./setup/pkihost" >> ${PKI_LIST}
+echo "./setup/pkiremove" >> ${PKI_LIST}
+
+# Add 'svn:keywords' properties to ALL files in the list that
+# do NOT already contain the SPECIFIED 'svn:keywords' properties
+printf "BEGIN: Processing 'svn:keywords' to ALL files in list . . .\n"
+for FILE in `cat ${PKI_LIST}`
+do
+ # retrieve the current 'svn:keywords' properties set for this file
+ KEYWORDS=`svn propget svn:keywords ${FILE}`
+ if [ "${KEYWORDS}" = "" ] ; then
+ # set the SPECIFIED 'svn:keywords' properties on this file
+ svn propset svn:keywords "${SVN_KEYWORDS}" ${FILE}
+ elif [ "${KEYWORDS}" != "${SVN_KEYWORDS}" ] ; then
+ # Warn the script user if a file in the list contains
+ # 'svn:keywords' properties that are DIFFERENT than
+ # the SPECIFIED 'svn:keywords' properties
+ printf "WARNING: '${FILE}' ONLY contains the keywords '${KEYWORDS}'!\n"
+ fi
+done
+printf "END: Finished processing 'svn:keywords' to ALL files in list.\n\n"
+
+# Always remove this list
+rm -rf ${PKI_LIST}
+
+# Print post-script instructions
+printf "\n"
+printf "REMINDER: ALWAYS remember to execute 'svn commit' on 'pki/base'\n"
+printf " AFTER executing '${PKI_SCRIPT}'!\n\n"
+
diff --git a/base/scripts/pkicheck b/base/scripts/pkicheck
new file mode 100755
index 000000000..3ff548d3d
--- /dev/null
+++ b/base/scripts/pkicheck
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+# This script may ONLY be run on Linux!
+PKI_OS=`uname`
+if [ "${PKI_OS}" != "Linux" ]; then
+ printf "The '$0' script is ONLY executable\n"
+ printf "on a 'Linux' machine!\n"
+ exit 255
+fi
+
+# For now, check for symkey (legacy package)
+rpm -qa | egrep -i pki-\|symkey | sort | cat -n
+
diff --git a/base/scripts/pkimanifest b/base/scripts/pkimanifest
new file mode 100755
index 000000000..31d443cfc
--- /dev/null
+++ b/base/scripts/pkimanifest
@@ -0,0 +1,100 @@
+#!/bin/bash
+# BEGIN COPYRIGHT BLOCK
+# (C) 2010 Red Hat, Inc.
+# All rights reserved.
+# END COPYRIGHT BLOCK
+
+# Define global constants
+FOOTER="TIMING - ======== Finished Processing PKI Manifest ========"
+HEADER="TIMING - ======== Started Processing PKI Manifest ========"
+MANIFEST="manifest"
+PKI="pki"
+SCRIPTS="scripts"
+SVN=".svn"
+
+# Define global variables
+pki_date=`date +%Y%m%d%H%M%S`
+pki_dir=""
+pki_manifest=""
+
+# Define functions
+Usage()
+{
+ printf "Usage 1: `basename ${0}`\n"
+ printf "Usage 2: `basename ${0}` source_path manifest_file\n\n"
+ printf " where 'Usage 1' must be explicitly executed\n"
+ printf " from one of the following subdirectories:\n\n"
+ printf " pki/base/scripts,\n"
+ printf " pki/dogtag/scripts, or\n"
+ printf " pki/redhat/scripts\n\n"
+}
+
+# Check for valid number of arguments to shell script
+if [ $# -eq 2 ] ; then
+ # Check that source path is a directory
+ if [ ! -d ${1} ] ; then
+ printf "The source path '${1}' does not exist!\n\n"
+ Usage
+ exit 255
+ fi
+
+ # Initialize variables
+ pki_dir=${1}
+ pki_manifest=${2}.${pki_date}
+elif [ $# -eq 0 ] ; then
+ # Remember current location
+ pki_pwd=`pwd`
+
+ # Check that this script is being run from an appropriate directory
+ if [ "`basename ${pki_pwd}`" != "${SCRIPTS}" ] ; then
+ printf "The '`basename ${0}`' script is NOT being executed "
+ printf "from a valid subdirectory!\n\n"
+ Usage
+ exit 255
+ fi
+
+ # Obtain the source directory related to this PKI manifest
+ pki_src_dir=`cd .. ; pwd | xargs basename ; cd ./${SCRIPTS}`
+
+ # Always switch into the base directory three levels
+ # above this shell script prior to executing it so
+ # that all of its output is written to this directory
+ cd ${pki_pwd}/../../..
+
+ # Initialize variables
+ pki_dir="${PKI}/${pki_src_dir}"
+ pki_manifest="`pwd`/${PKI}.${pki_src_dir}.${MANIFEST}.${pki_date}"
+else
+ Usage
+ exit 255
+fi
+
+# Compose alphabetical list of specified source files
+pki_now=`date`
+echo "TIMING - ======== Started Generating Source File List ========"
+echo "${pki_now}"
+process_pki_tree=`find ${pki_dir} -name ${SVN} -prune -o -type f -print | sort`
+echo "${pki_now}"
+echo "TIMING - ======== Finished Generating Source File List ========"
+echo
+
+# Generate PKI Manifest
+pki_now=`date`
+echo "${HEADER}"
+echo "${pki_now}"
+
+printf "${HEADER}\n" > ${pki_manifest}
+printf "${pki_now}\n\n" >> ${pki_manifest}
+for f in "${process_pki_tree}"
+do
+ echo "Processing ${f} . . ."
+ svn info ${f} >> ${pki_manifest}
+done
+pki_now=`date`
+printf "${pki_now}\n" >> ${pki_manifest}
+printf "${FOOTER}\n" >> ${pki_manifest}
+
+echo "${pki_now}"
+echo "${FOOTER}"
+echo
+
diff --git a/base/selinux/CMakeLists.txt b/base/selinux/CMakeLists.txt
new file mode 100644
index 000000000..a9ef0707f
--- /dev/null
+++ b/base/selinux/CMakeLists.txt
@@ -0,0 +1,11 @@
+project(selinux)
+
+add_subdirectory(src)
+
+# install empty directories
+install(
+ DIRECTORY
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/selinux/modules
+)
+
diff --git a/base/selinux/LICENSE b/base/selinux/LICENSE
new file mode 100644
index 000000000..e281f4362
--- /dev/null
+++ b/base/selinux/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/base/selinux/src/CMakeLists.txt b/base/selinux/src/CMakeLists.txt
new file mode 100644
index 000000000..146ab1348
--- /dev/null
+++ b/base/selinux/src/CMakeLists.txt
@@ -0,0 +1,28 @@
+set(POLICY_MAKEFILE /usr/share/selinux/devel/Makefile)
+
+set(policy_SRCS
+ pki.fc
+ pki.if
+ pki.te
+)
+
+if (LINUX)
+ if (EXISTS ${POLICY_MAKEFILE})
+ foreach(_POLICY ${policy_SRCS})
+ macro_copy_file(${CMAKE_CURRENT_SOURCE_DIR}/${_POLICY} ${CMAKE_CURRENT_BINARY_DIR}/${_POLICY})
+ endforeach(_POLICY ${policy_SRCS})
+
+ # FIXME This should be done by cmake
+ add_custom_target(selinux ALL
+ COMMAND ${CMAKE_BUILD_TOOL} -f ${POLICY_MAKEFILE}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ )
+
+ install(
+ FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/pki.pp
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/selinux/modules
+ )
+ endif (EXISTS ${POLICY_MAKEFILE})
+endif (LINUX)
diff --git a/base/selinux/src/Makefile b/base/selinux/src/Makefile
new file mode 100644
index 000000000..201a448a9
--- /dev/null
+++ b/base/selinux/src/Makefile
@@ -0,0 +1,18 @@
+POLICY_MAKEFILE = /usr/share/selinux/devel/Makefile
+POLICY_DIR = $(DESTDIR)/usr/share/selinux/targeted
+
+all:
+ if [ ! -e $(POLICY_MAKEFILE) ]; then echo "You need to install the SELinux development tools (selinux-policy-devel)" && exit 1; fi
+ $(MAKE) -f $(POLICY_MAKEFILE) || exit 1;
+
+clean:
+ rm -rf tmp
+ rm pki.pp
+
+install: all
+ install -d $(POLICY_DIR)
+ install -m 644 pki.pp $(POLICY_DIR)
+
+load:
+ /usr/sbin/semodule -i pki.pp
+
diff --git a/base/selinux/src/pki.fc b/base/selinux/src/pki.fc
new file mode 100644
index 000000000..3a22d86a4
--- /dev/null
+++ b/base/selinux/src/pki.fc
@@ -0,0 +1,91 @@
+
+/usr/bin/dtomcat5-pki-ca -- gen_context(system_u:object_r:pki_ca_exec_t,s0)
+
+/etc/pki-ca(/.*)? gen_context(system_u:object_r:pki_ca_etc_rw_t,s0)
+/etc/pki-ca/tomcat5.conf -- gen_context(system_u:object_r:pki_ca_tomcat_exec_t,s0)
+
+/var/lib/pki-ca(/.*)? gen_context(system_u:object_r:pki_ca_var_lib_t,s0)
+
+/var/run/pki-ca.pid gen_context(system_u:object_r:pki_ca_var_run_t,s0)
+
+/var/log/pki-ca(/.*)? gen_context(system_u:object_r:pki_ca_log_t,s0)
+
+/usr/bin/dtomcat5-pki-kra -- gen_context(system_u:object_r:pki_kra_exec_t,s0)
+
+/etc/pki-kra(/.*)? gen_context(system_u:object_r:pki_kra_etc_rw_t,s0)
+/etc/pki-kra/tomcat5.conf -- gen_context(system_u:object_r:pki_kra_tomcat_exec_t,s0)
+
+/var/lib/pki-kra(/.*)? gen_context(system_u:object_r:pki_kra_var_lib_t,s0)
+
+/var/run/pki-kra.pid gen_context(system_u:object_r:pki_kra_var_run_t,s0)
+
+/var/log/pki-kra(/.*)? gen_context(system_u:object_r:pki_kra_log_t,s0)
+
+/usr/bin/dtomcat5-pki-ocsp -- gen_context(system_u:object_r:pki_ocsp_exec_t,s0)
+
+/etc/pki-ocsp(/.*)? gen_context(system_u:object_r:pki_ocsp_etc_rw_t,s0)
+/etc/pki-ocsp/tomcat5.conf -- gen_context(system_u:object_r:pki_ocsp_tomcat_exec_t,s0)
+
+/var/lib/pki-ocsp(/.*)? gen_context(system_u:object_r:pki_ocsp_var_lib_t,s0)
+
+/var/run/pki-ocsp.pid gen_context(system_u:object_r:pki_ocsp_var_run_t,s0)
+
+/var/log/pki-ocsp(/.*)? gen_context(system_u:object_r:pki_ocsp_log_t,s0)
+
+/usr/sbin/httpd.worker -- gen_context(system_u:object_r:pki_ra_exec_t,s0)
+/etc/pki-ra(/.*)? gen_context(system_u:object_r:pki_ra_etc_rw_t,s0)
+/var/lib/pki-ra(/.*)? gen_context(system_u:object_r:pki_ra_var_lib_t,s0)
+/var/log/pki-ra(/.*)? gen_context(system_u:object_r:pki_ra_log_t,s0)
+
+
+/usr/bin/dtomcat5-pki-tks -- gen_context(system_u:object_r:pki_tks_exec_t,s0)
+
+/etc/pki-tks(/.*)? gen_context(system_u:object_r:pki_tks_etc_rw_t,s0)
+/etc/pki-tks/tomcat5.conf -- gen_context(system_u:object_r:pki_tks_tomcat_exec_t,s0)
+
+/var/lib/pki-tks(/.*)? gen_context(system_u:object_r:pki_tks_var_lib_t,s0)
+
+/var/run/pki-tks.pid gen_context(system_u:object_r:pki_tks_var_run_t,s0)
+
+/var/log/pki-tks(/.*)? gen_context(system_u:object_r:pki_tks_log_t,s0)
+
+/etc/pki-tps(/.*)? gen_context(system_u:object_r:pki_tps_etc_rw_t,s0)
+/var/lib/pki-tps(/.*)? gen_context(system_u:object_r:pki_tps_var_lib_t,s0)
+/var/log/pki-tps(/.*)? gen_context(system_u:object_r:pki_tps_log_t,s0)
+
+# default labeling for nCipher
+/opt/nfast/scripts/init.d/(.*) gen_context(system_u:object_r:initrc_exec_t, s0)
+/opt/nfast/sbin/init.d-ncipher gen_context(system_u:object_r:initrc_exec_t, s0)
+/opt/nfast(/.*)? gen_context(system_u:object_r:pki_common_t, s0)
+/dev/nfast(/.*)? gen_context(system_u:object_r:pki_common_dev_t, s0)
+
+# labeling for new CA under pki-cad
+
+/var/run/pki/ca(/.*)? gen_context(system_u:object_r:pki_ca_var_run_t,s0)
+/etc/sysconfig/pki/ca(/.*)? gen_context(system_u:object_r:pki_ca_etc_rw_t,s0)
+
+# labeling for new KRA under pki-krad
+
+/var/run/pki/kra(/.*)? gen_context(system_u:object_r:pki_kra_var_run_t,s0)
+/etc/sysconfig/pki/kra(/.*)? gen_context(system_u:object_r:pki_kra_etc_rw_t,s0)
+
+# labeling for new OCSP under pki-ocspd
+
+/var/run/pki/ocsp(/.*)? gen_context(system_u:object_r:pki_ocsp_var_run_t,s0)
+/etc/sysconfig/pki/ocsp(/.*)? gen_context(system_u:object_r:pki_ocsp_etc_rw_t,s0)
+
+# labeling for new TKS under pki-tksd
+
+/var/run/pki/tks(/.*)? gen_context(system_u:object_r:pki_tks_var_run_t,s0)
+/etc/sysconfig/pki/tks(/.*)? gen_context(system_u:object_r:pki_tks_etc_rw_t,s0)
+
+# labeling for new RA under pki-rad
+
+/var/run/pki/ra(/.*)? gen_context(system_u:object_r:pki_ra_var_run_t,s0)
+/etc/sysconfig/pki/ra(/.*)? gen_context(system_u:object_r:pki_ra_etc_rw_t,s0)
+
+# labeling for new TPS under pki-tpsd
+
+/var/run/pki/tps(/.*)? gen_context(system_u:object_r:pki_tps_var_run_t,s0)
+/etc/sysconfig/pki/tps(/.*)? gen_context(system_u:object_r:pki_tps_etc_rw_t,s0)
+
diff --git a/base/selinux/src/pki.if b/base/selinux/src/pki.if
new file mode 100644
index 000000000..0709176ea
--- /dev/null
+++ b/base/selinux/src/pki.if
@@ -0,0 +1,745 @@
+
+## <summary>policy for pki</summary>
+
+########################################
+## <summary>
+## Create a set of derived types for apache
+## web content.
+## </summary>
+## <param name="prefix">
+## <summary>
+## The prefix to be used for deriving type names.
+## </summary>
+## </param>
+#
+template(`pki_ca_template',`
+ gen_require(`
+ attribute pki_ca_process;
+ attribute pki_ca_config, pki_ca_var_lib, pki_ca_var_run;
+ attribute pki_ca_executable, pki_ca_script, pki_ca_var_log;
+ type pki_ca_tomcat_exec_t;
+ type $1_port_t;
+ type rpm_var_lib_t;
+ type rpm_exec_t;
+ type setfiles_t;
+ ')
+ ########################################
+ #
+ # Declarations
+ #
+
+ type $1_t, pki_ca_process;
+ type $1_exec_t, pki_ca_executable;
+ domain_type($1_t)
+ init_daemon_domain($1_t, $1_exec_t)
+
+ type $1_script_t;
+ domain_type($1_script_t)
+ gen_require(`
+ type java_exec_t;
+ type initrc_t;
+ ')
+ domtrans_pattern($1_script_t, java_exec_t, $1_t)
+
+ role system_r types $1_script_t;
+ allow $1_t java_exec_t:file entrypoint;
+ allow initrc_t $1_script_t:process transition;
+
+ type $1_etc_rw_t, pki_ca_config;
+ files_type($1_etc_rw_t)
+
+ type $1_var_run_t, pki_ca_var_run;
+ files_pid_file($1_var_run_t)
+
+ type $1_var_lib_t, pki_ca_var_lib;
+ files_type($1_var_lib_t)
+
+ type $1_log_t, pki_ca_var_log;
+ logging_log_file($1_log_t)
+
+ ########################################
+ #
+ # $1 local policy
+ #
+
+ # Execstack/execmem caused by java app.
+ allow $1_t self:process { execstack execmem getsched setsched signal};
+ allow initrc_t self:process execstack;
+
+ ## internal communication is often done using fifo and unix sockets.
+ allow $1_t self:fifo_file rw_file_perms;
+ allow $1_t self:unix_stream_socket create_stream_socket_perms;
+ allow $1_t self:tcp_socket create_stream_socket_perms;
+ allow $1_t self:process signull;
+
+ allow $1_t $1_port_t:tcp_socket {name_bind name_connect};
+
+ # use rpm to look at velocity version in dtomcat-foo
+ allow $1_t rpm_exec_t:file exec_file_perms;
+
+ corenet_all_recvfrom_unlabeled($1_t)
+ corenet_tcp_sendrecv_all_if($1_t)
+ corenet_tcp_sendrecv_all_nodes($1_t)
+ corenet_tcp_sendrecv_all_ports($1_t)
+
+ corenet_tcp_bind_all_nodes($1_t)
+ corenet_tcp_bind_ocsp_port($1_t)
+ corenet_tcp_connect_ocsp_port($1_t)
+ corenet_tcp_connect_generic_port($1_t)
+
+ # for file signing
+ corenet_tcp_connect_http_port($1_t)
+
+ # This is for /etc/$1/tomcat.conf:
+ can_exec($1_t, $1_tomcat_exec_t)
+ allow $1_t $1_tomcat_exec_t:file {getattr read};
+
+ #installation requires this for access to /var/lib/tomcat5/common/lib/jdtcore.jar
+ rpm_read_db($1_t)
+
+ # Init script handling
+ domain_use_interactive_fds($1_t)
+
+ files_read_etc_files($1_t)
+
+ manage_dirs_pattern($1_t, $1_etc_rw_t, $1_etc_rw_t)
+ manage_files_pattern($1_t, $1_etc_rw_t, $1_etc_rw_t)
+ files_etc_filetrans($1_t,$1_etc_rw_t, { file dir })
+
+ # start/stop using pki-cad, pki-krad, pki-ocspd, or pki-tksd
+ allow setfiles_t $1_etc_rw_t:file read;
+
+ manage_dirs_pattern($1_t, $1_var_run_t, $1_var_run_t)
+ manage_files_pattern($1_t, $1_var_run_t, $1_var_run_t)
+ files_pid_filetrans($1_t,$1_var_run_t, { file dir })
+
+ manage_dirs_pattern($1_t, $1_var_lib_t, $1_var_lib_t)
+ manage_files_pattern($1_t, $1_var_lib_t, $1_var_lib_t)
+ read_lnk_files_pattern($1_t, $1_var_lib_t, $1_var_lib_t)
+ files_var_lib_filetrans($1_t, $1_var_lib_t, { file dir } )
+ allow $1_t rpm_var_lib_t:lnk_file { read getattr };
+
+ manage_dirs_pattern($1_t, $1_log_t, $1_log_t)
+ manage_files_pattern($1_t, $1_log_t, $1_log_t)
+ logging_log_filetrans($1_t, $1_log_t, { file dir } )
+
+ corecmd_exec_bin($1_t)
+ corecmd_read_bin_symlinks($1_t)
+ corecmd_exec_shell($1_t)
+ corecmd_search_bin($1_t)
+
+ dev_list_sysfs($1_t)
+ dev_read_sysfs($1_t)
+ dev_read_rand($1_t)
+ dev_read_urand($1_t)
+
+ # Java is looking in /tmp for some reason...:
+ files_manage_generic_tmp_dirs($1_t)
+ files_manage_generic_tmp_files($1_t)
+ files_read_usr_files($1_t)
+ files_read_usr_symlinks($1_t)
+ # These are used to read tomcat class files in /var/lib/tomcat
+ files_read_var_lib_files($1_t)
+ files_read_var_lib_symlinks($1_t)
+
+ #needed in tps key archival in kra
+ files_list_var($1_t)
+
+ kernel_read_network_state($1_t)
+ kernel_read_system_state($1_t)
+ kernel_search_network_state($1_t)
+ # audit2allow
+ kernel_signull_unlabeled($1_t)
+
+ auth_use_nsswitch($1_t)
+
+ init_dontaudit_write_utmp($1_t)
+
+ libs_use_ld_so($1_t)
+ libs_use_shared_libs($1_t)
+
+ miscfiles_read_localization($1_t)
+
+ logging_send_syslog_msg($1_t)
+
+ ifdef(`targeted_policy',`
+ term_dontaudit_use_unallocated_ttys($1_t)
+ term_dontaudit_use_generic_ptys($1_t)
+ ')
+
+ # allow java subsystems to talk to the ncipher hsm
+ allow $1_t pki_common_dev_t:sock_file write;
+ allow $1_t pki_common_dev_t:dir search;
+ allow $1_t pki_common_t:dir create_dir_perms;
+ manage_files_pattern($1_t, pki_common_t, pki_common_t)
+ can_exec($1_t, pki_common_t)
+ init_stream_connect_script($1_t)
+
+ #allow java subsystems to talk to lunasa hsm
+
+ #allow sending mail
+ corenet_tcp_connect_smtp_port($1_t)
+
+ # allow rpm -q in init scripts
+ rpm_exec($1_t)
+
+ # allow writing to the kernel keyring
+ allow $1_t self:key { write read };
+
+ #reverse proxy
+ corenet_tcp_connect_dogtag_port($1_t)
+
+ #connect to ldap
+ corenet_tcp_connect_ldap_port($1_t)
+
+ # tomcat connects to ephemeral ports on shutdown
+ corenet_tcp_connect_all_unreserved_ports($1_t)
+
+ optional_policy(`
+ #This is broken in selinux-policy we need java_exec defined, Will add to policy
+ gen_require(`
+ type java_exec_t;
+ ')
+ can_exec($1_t, java_exec_t)
+ ')
+
+ optional_policy(`
+ unconfined_domain($1_script_t)
+ ')
+')
+
+########################################
+## <summary>
+## All of the rules required to administrate
+## an pki_ca environment
+## </summary>
+## <param name="domain">
+## <summary>
+## Domain allowed access.
+## </summary>
+## </param>
+## <param name="role">
+## <summary>
+## The role to be allowed to manage the syslog domain.
+## </summary>
+## </param>
+## <param name="terminal">
+## <summary>
+## The type of the user terminal.
+## </summary>
+## </param>
+## <rolecap/>
+#
+interface(`pki_ca_admin',`
+ gen_require(`
+ type pki_ca_tomcat_exec_t;
+ attribute pki_ca_process;
+ attribute pki_ca_config;
+ attribute pki_ca_executable;
+ attribute pki_ca_var_lib;
+ attribute pki_ca_var_log;
+ attribute pki_ca_var_run;
+ attribute pki_ca_pidfiles;
+ attribute pki_ca_script;
+ ')
+
+ allow $1 pki_ca_process:process { ptrace signal_perms };
+ ps_process_pattern($1, pki_ca_t)
+
+ # Allow pki_ca_t to restart the service
+ pki_ca_script_domtrans($1)
+ domain_system_change_exemption($1)
+ role_transition $2 pki_ca_script system_r;
+ allow $2 system_r;
+
+ manage_all_pattern($1, pki_ca_config)
+ manage_all_pattern($1, pki_ca_var_run)
+ manage_all_pattern($1, pki_ca_var_lib)
+ manage_all_pattern($1, pki_ca_var_log)
+ manage_all_pattern($1, pki_ca_config)
+ manage_all_pattern($1, pki_ca_tomcat_exec_t)
+')
+
+########################################
+## <summary>
+## All of the rules required to administrate
+## an pki_kra environment
+## </summary>
+## <param name="domain">
+## <summary>
+## Domain allowed access.
+## </summary>
+## </param>
+## <param name="role">
+## <summary>
+## The role to be allowed to manage the syslog domain.
+## </summary>
+## </param>
+## <param name="terminal">
+## <summary>
+## The type of the user terminal.
+## </summary>
+## </param>
+## <rolecap/>
+#
+interface(`pki_kra_admin',`
+ gen_require(`
+ type pki_kra_tomcat_exec_t;
+ attribute pki_kra_process;
+ attribute pki_kra_config;
+ attribute pki_kra_executable;
+ attribute pki_kra_var_lib;
+ attribute pki_kra_var_log;
+ attribute pki_kra_var_run;
+ attribute pki_kra_pidfiles;
+ attribute pki_kra_script;
+ ')
+
+ allow $1 pki_kra_process:process { ptrace signal_perms };
+ ps_process_pattern($1, pki_kra_t)
+
+ # Allow pki_kra_t to restart the service
+ pki_kra_script_domtrans($1)
+ domain_system_change_exemption($1)
+ role_transition $2 pki_kra_script system_r;
+ allow $2 system_r;
+
+ manage_all_pattern($1, pki_kra_config)
+ manage_all_pattern($1, pki_kra_var_run)
+ manage_all_pattern($1, pki_kra_var_lib)
+ manage_all_pattern($1, pki_kra_var_log)
+ manage_all_pattern($1, pki_kra_config)
+ manage_all_pattern($1, pki_kra_tomcat_exec_t)
+')
+
+########################################
+## <summary>
+## All of the rules required to administrate
+## an pki_ocsp environment
+## </summary>
+## <param name="domain">
+## <summary>
+## Domain allowed access.
+## </summary>
+## </param>
+## <param name="role">
+## <summary>
+## The role to be allowed to manage the syslog domain.
+## </summary>
+## </param>
+## <param name="terminal">
+## <summary>
+## The type of the user terminal.
+## </summary>
+## </param>
+## <rolecap/>
+#
+interface(`pki_ocsp_admin',`
+ gen_require(`
+ type pki_ocsp_tomcat_exec_t;
+ attribute pki_ocsp_process;
+ attribute pki_ocsp_config;
+ attribute pki_ocsp_executable;
+ attribute pki_ocsp_var_lib;
+ attribute pki_ocsp_var_log;
+ attribute pki_ocsp_var_run;
+ attribute pki_ocsp_pidfiles;
+ attribute pki_ocsp_script;
+ ')
+
+ allow $1 pki_ocsp_process:process { ptrace signal_perms };
+ ps_process_pattern($1, pki_ocsp_t)
+
+ # Allow pki_ocsp_t to restart the service
+ pki_ocsp_script_domtrans($1)
+ domain_system_change_exemption($1)
+ role_transition $2 pki_ocsp_script system_r;
+ allow $2 system_r;
+
+ manage_all_pattern($1, pki_ocsp_config)
+ manage_all_pattern($1, pki_ocsp_var_run)
+ manage_all_pattern($1, pki_ocsp_var_lib)
+ manage_all_pattern($1, pki_ocsp_var_log)
+ manage_all_pattern($1, pki_ocsp_config)
+ manage_all_pattern($1, pki_ocsp_tomcat_exec_t)
+')
+
+########################################
+## <summary>
+## Execute pki_ra server in the pki_ra domain.
+## </summary>
+## <param name="domain">
+## <summary>
+## The type of the process performing this action.
+## </summary>
+## </param>
+#
+interface(`pki_ra_script_domtrans',`
+ gen_require(`
+ attribute pki_ra_script;
+ ')
+
+ init_script_domtrans_spec($1,pki_ra_script)
+')
+
+########################################
+## <summary>
+## Create a set of derived types for apache
+## web content.
+## </summary>
+## <param name="prefix">
+## <summary>
+## The prefix to be used for deriving type names.
+## </summary>
+## </param>
+#
+template(`pki_tps_template',`
+ gen_require(`
+ attribute pki_tps_process;
+ attribute pki_tps_config, pki_tps_var_lib, pki_tps_var_run;
+ attribute pki_tps_executable, pki_tps_script, pki_tps_var_log;
+ ')
+ ########################################
+ #
+ # Declarations
+ #
+
+ type $1_t, pki_tps_process;
+ type $1_exec_t, pki_tps_executable;
+ domain_type($1_t)
+ init_daemon_domain($1_t, $1_exec_t)
+
+ type $1_script_exec_t, pki_tps_script;
+ init_script_file($1_script_exec_t)
+
+ type $1_etc_rw_t, pki_tps_config;
+ files_type($1_etc_rw_t)
+
+ type $1_var_run_t, pki_tps_var_run;
+ files_pid_file($1_var_run_t)
+
+ type $1_var_lib_t, pki_tps_var_lib;
+ files_type($1_var_lib_t)
+
+ type $1_log_t, pki_tps_var_log;
+ logging_log_file($1_log_t)
+
+ ########################################
+ #
+ # $1 local policy
+ #
+
+ ## internal communication is often done using fifo and unix sockets.
+ allow $1_t self:fifo_file rw_file_perms;
+ allow $1_t self:unix_stream_socket create_stream_socket_perms;
+
+ # Init script handling
+ domain_use_interactive_fds($1_t)
+
+ files_read_etc_files($1_t)
+ allow pki_tps_t pki_tps_etc_rw_t:lnk_file read;
+
+ manage_dirs_pattern($1_t, $1_etc_rw_t, $1_etc_rw_t)
+ manage_files_pattern($1_t, $1_etc_rw_t, $1_etc_rw_t)
+ files_etc_filetrans($1_t,$1_etc_rw_t, { file dir })
+
+ manage_dirs_pattern($1_t, $1_var_run_t, $1_var_run_t)
+ manage_files_pattern($1_t, $1_var_run_t, $1_var_run_t)
+ files_pid_filetrans($1_t,$1_var_run_t, { file dir })
+
+ manage_dirs_pattern($1_t, $1_var_lib_t, $1_var_lib_t)
+ manage_files_pattern($1_t, $1_var_lib_t, $1_var_lib_t)
+ read_lnk_files_pattern($1_t, $1_var_lib_t, $1_var_lib_t)
+ files_var_lib_filetrans($1_t, $1_var_lib_t, { file dir } )
+
+ manage_dirs_pattern($1_t, $1_log_t, $1_log_t)
+ manage_files_pattern($1_t, $1_log_t, $1_log_t)
+ logging_log_filetrans($1_t, $1_log_t, { file dir } )
+
+ init_dontaudit_write_utmp($1_t)
+
+ libs_use_ld_so($1_t)
+ libs_use_shared_libs($1_t)
+
+ miscfiles_read_localization($1_t)
+
+ ifdef(`targeted_policy',`
+ term_dontaudit_use_unallocated_ttys($1_t)
+ term_dontaudit_use_generic_ptys($1_t)
+ ')
+
+ gen_require(`
+ type httpd_t;
+ type httpd_exec_t;
+ type httpd_suexec_exec_t;
+ ')
+
+ #============= httpd_t ==============
+ allow httpd_t $1_var_run_t:dir search;
+ allow httpd_t $1_var_run_t:file read_file_perms;
+
+')
+
+template(`pki_ra_template',`
+ gen_require(`
+ attribute pki_ra_process;
+ attribute pki_ra_config, pki_ra_var_lib, pki_ra_var_run;
+ attribute pki_ra_executable, pki_ra_script, pki_ra_var_log;
+ ')
+ ########################################
+ #
+ # Declarations
+ #
+
+ type $1_t, pki_ra_process;
+ type $1_exec_t, pki_ra_executable;
+ domain_type($1_t)
+ init_daemon_domain($1_t, $1_exec_t)
+
+ type $1_script_exec_t, pki_ra_script;
+ init_script_file($1_script_exec_t)
+
+ type $1_etc_rw_t, pki_ra_config;
+ files_type($1_etc_rw_t)
+
+ type $1_var_run_t, pki_ra_var_run;
+ files_pid_file($1_var_run_t)
+
+ type $1_var_lib_t, pki_ra_var_lib;
+ files_type($1_var_lib_t)
+
+ type $1_log_t, pki_ra_var_log;
+ logging_log_file($1_log_t)
+
+ ########################################
+ #
+ # $1 local policy
+ #
+
+ ## internal communication is often done using fifo and unix sockets.
+ allow $1_t self:fifo_file rw_file_perms;
+ allow $1_t self:unix_stream_socket create_stream_socket_perms;
+
+ # Init script handling
+ domain_use_interactive_fds($1_t)
+
+ files_read_etc_files($1_t)
+
+ manage_dirs_pattern($1_t, $1_etc_rw_t, $1_etc_rw_t)
+ manage_files_pattern($1_t, $1_etc_rw_t, $1_etc_rw_t)
+ files_etc_filetrans($1_t,$1_etc_rw_t, { file dir })
+
+ manage_dirs_pattern($1_t, $1_var_run_t, $1_var_run_t)
+ manage_files_pattern($1_t, $1_var_run_t, $1_var_run_t)
+ files_pid_filetrans($1_t,$1_var_run_t, { file dir })
+
+ manage_dirs_pattern($1_t, $1_var_lib_t, $1_var_lib_t)
+ manage_files_pattern($1_t, $1_var_lib_t, $1_var_lib_t)
+ read_lnk_files_pattern($1_t, $1_var_lib_t, $1_var_lib_t)
+ files_var_lib_filetrans($1_t, $1_var_lib_t, { file dir } )
+
+ manage_dirs_pattern($1_t, $1_log_t, $1_log_t)
+ manage_files_pattern($1_t, $1_log_t, $1_log_t)
+ logging_log_filetrans($1_t, $1_log_t, { file dir } )
+
+ init_dontaudit_write_utmp($1_t)
+
+ libs_use_ld_so($1_t)
+ libs_use_shared_libs($1_t)
+
+ miscfiles_read_localization($1_t)
+
+ ifdef(`targeted_policy',`
+ term_dontaudit_use_unallocated_ttys($1_t)
+ term_dontaudit_use_generic_ptys($1_t)
+ ')
+
+ gen_require(`
+ type httpd_t;
+ type devlog_t;
+ type syslogd_t;
+ type httpd_exec_t;
+ type httpd_suexec_exec_t;
+ ')
+
+ #============= httpd_t ==============
+ allow httpd_t $1_var_run_t:dir search;
+ allow httpd_t $1_var_run_t:file read_file_perms;
+')
+
+########################################
+## <summary>
+## All of the rules required to administrate
+## an pki_ra environment
+## </summary>
+## <param name="domain">
+## <summary>
+## Domain allowed access.
+########################################
+## <summary>
+## All of the rules required to administrate
+## an pki_ra environment
+## </summary>
+## <param name="domain">
+## <summary>
+## Domain allowed access.
+## </summary>
+## </param>
+## <param name="role">
+## <summary>
+## The role to be allowed to manage the syslog domain.
+## </summary>
+## </param>
+## <param name="terminal">
+## <summary>
+## The type of the user terminal.
+## </summary>
+## </param>
+## <rolecap/>
+#
+interface(`pki_ra_admin',`
+ gen_require(`
+ attribute pki_ra_process;
+ attribute pki_ra_config;
+ attribute pki_ra_executable;
+ attribute pki_ra_var_lib;
+ attribute pki_ra_var_log;
+ attribute pki_ra_var_run;
+ attribute pki_ra_script;
+ ')
+
+ allow $1 pki_ra_process:process { ptrace signal_perms };
+ ps_process_pattern($1, pki_ra_t)
+
+ # Allow pki_ra_t to restart the service
+ pki_ra_script_domtrans($1)
+ domain_system_change_exemption($1)
+ role_transition $2 pki_ra_script system_r;
+ allow $2 system_r;
+
+ manage_all_pattern($1, pki_ra_config)
+ manage_all_pattern($1, pki_ra_var_run)
+ manage_all_pattern($1, pki_ra_var_lib)
+ manage_all_pattern($1, pki_ra_var_log)
+ manage_all_pattern($1, pki_ra_config)
+')
+
+########################################
+## <summary>
+## All of the rules required to administrate
+## an pki_tks environment
+## </summary>
+## <param name="domain">
+## <summary>
+## Domain allowed access.
+## </summary>
+## </param>
+## <param name="role">
+## <summary>
+## The role to be allowed to manage the syslog domain.
+## </summary>
+## </param>
+## <param name="terminal">
+## <summary>
+## The type of the user terminal.
+## </summary>
+## </param>
+## <rolecap/>
+#
+interface(`pki_tks_admin',`
+ gen_require(`
+ type pki_tks_tomcat_exec_t;
+ attribute pki_tks_process;
+ attribute pki_tks_config;
+ attribute pki_tks_executable;
+ attribute pki_tks_var_lib;
+ attribute pki_tks_var_log;
+ attribute pki_tks_var_run;
+ attribute pki_tks_pidfiles;
+ attribute pki_tks_script;
+ ')
+
+ allow $1 pki_tks_process:process { ptrace signal_perms };
+ ps_process_pattern($1, pki_tks_t)
+
+ # Allow pki_tks_t to restart the service
+ pki_tks_script_domtrans($1)
+ domain_system_change_exemption($1)
+ role_transition $2 pki_tks_script system_r;
+ allow $2 system_r;
+
+ manage_all_pattern($1, pki_tks_config)
+ manage_all_pattern($1, pki_tks_var_run)
+ manage_all_pattern($1, pki_tks_var_lib)
+ manage_all_pattern($1, pki_tks_var_log)
+ manage_all_pattern($1, pki_tks_config)
+ manage_all_pattern($1, pki_tks_tomcat_exec_t)
+')
+
+########################################
+## <summary>
+## Execute pki_tps server in the pki_tps domain.
+## </summary>
+## <param name="domain">
+## <summary>
+## The type of the process performing this action.
+## </summary>
+## </param>
+#
+interface(`pki_tps_script_domtrans',`
+ gen_require(`
+ attribute pki_tps_script;
+ ')
+
+ init_script_domtrans_spec($1,pki_tps_script)
+')
+
+
+########################################
+## <summary>
+## All of the rules required to administrate
+## an pki_tps environment
+## </summary>
+## <param name="domain">
+## <summary>
+## Domain allowed access.
+## </summary>
+## </param>
+## <param name="role">
+## <summary>
+## The role to be allowed to manage the syslog domain.
+## </summary>
+## </param>
+## <param name="terminal">
+## <summary>
+## The type of the user terminal.
+## </summary>
+## </param>
+## <rolecap/>
+#
+interface(`pki_tps_admin',`
+ gen_require(`
+ attribute pki_tps_process;
+ attribute pki_tps_config;
+ attribute pki_tps_executable;
+ attribute pki_tps_var_lib;
+ attribute pki_tps_var_log;
+ attribute pki_tps_var_run;
+ attribute pki_tps_script;
+ ')
+
+ allow $1 pki_tps_process:process { ptrace signal_perms };
+ ps_process_pattern($1, pki_tps_t)
+
+ # Allow pki_tps_t to restart the service
+ pki_tps_script_domtrans($1)
+ domain_system_change_exemption($1)
+ role_transition $2 pki_tps_script system_r;
+ allow $2 system_r;
+
+ manage_all_pattern($1, pki_tps_config)
+ manage_all_pattern($1, pki_tps_var_run)
+ manage_all_pattern($1, pki_tps_var_lib)
+ manage_all_pattern($1, pki_tps_var_log)
+ manage_all_pattern($1, pki_tps_config)
+')
diff --git a/base/selinux/src/pki.sh b/base/selinux/src/pki.sh
new file mode 100755
index 000000000..bf95ba98c
--- /dev/null
+++ b/base/selinux/src/pki.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+USAGE="$0 [ --update ]"
+
+if [ ! -f /usr/share/selinux/devel/Makefile ]; then
+echo 'selinux-policy-devel not installed, package required for building policy'
+echo '# yum install selinux-policy-devel'
+exit 1
+fi
+
+if [ $# -eq 1 ]; then
+ if [ "$1" = "--update" ] ; then
+ time=`ls -l --time-style="+%x %X" pki_ca.te | awk '{ printf "%s %s", $6, $7 }'`
+ rules=`ausearch --start $time -m avc --raw -se pki_ca`
+ if [ x"$rules" != "x" ] ; then
+ echo "Found avc's to update policy with"
+ echo -e "$rules" | audit2allow -R
+ echo "Do you want these changes added to policy [y/n]?"
+ read ANS
+ if [ "$ANS" = "y" -o "$ANS" = "Y" ] ; then
+ echo "Updating policy"
+ echo -e "$rules" | audit2allow -R >> pki_ca.te
+ # Fall though and rebuild policy
+ else
+ exit 0
+ fi
+ else
+ echo "No new avcs found"
+ exit 0
+ fi
+ else
+ echo -e $USAGE
+ exit 1
+ fi
+elif [ $# -ge 2 ] ; then
+ echo -e $USAGE
+ exit 1
+fi
+
+echo "Building and Loading Policy"
+make -f /usr/share/selinux/devel/Makefile
diff --git a/base/selinux/src/pki.te b/base/selinux/src/pki.te
new file mode 100644
index 000000000..7f6e65738
--- /dev/null
+++ b/base/selinux/src/pki.te
@@ -0,0 +1,332 @@
+policy_module(pki,10.0.2)
+
+attribute pki_ca_config;
+attribute pki_ca_executable;
+attribute pki_ca_var_lib;
+attribute pki_ca_var_log;
+attribute pki_ca_var_run;
+attribute pki_ca_pidfiles;
+attribute pki_ca_script;
+attribute pki_ca_process;
+
+type pki_common_t;
+files_type(pki_common_t)
+
+type pki_common_dev_t;
+files_type(pki_common_dev_t)
+
+type pki_ca_tomcat_exec_t;
+files_type(pki_ca_tomcat_exec_t)
+
+pki_ca_template(pki_ca)
+corenet_tcp_connect_pki_kra_port(pki_ca_t)
+corenet_tcp_connect_pki_ocsp_port(pki_ca_t)
+
+# forward proxy
+corenet_tcp_connect_pki_ca_port(httpd_t)
+
+# for crl publishing
+allow pki_ca_t pki_ca_var_lib_t:lnk_file { rename create unlink };
+
+# for ECC
+auth_getattr_shadow(pki_ca_t)
+
+attribute pki_kra_config;
+attribute pki_kra_executable;
+attribute pki_kra_var_lib;
+attribute pki_kra_var_log;
+attribute pki_kra_var_run;
+attribute pki_kra_pidfiles;
+attribute pki_kra_script;
+attribute pki_kra_process;
+
+type pki_kra_tomcat_exec_t;
+files_type(pki_kra_tomcat_exec_t)
+
+pki_ca_template(pki_kra)
+corenet_tcp_connect_pki_ca_port(pki_kra_t)
+
+# forward proxy
+corenet_tcp_connect_pki_kra_port(httpd_t)
+
+attribute pki_ocsp_config;
+attribute pki_ocsp_executable;
+attribute pki_ocsp_var_lib;
+attribute pki_ocsp_var_log;
+attribute pki_ocsp_var_run;
+attribute pki_ocsp_pidfiles;
+attribute pki_ocsp_script;
+attribute pki_ocsp_process;
+
+type pki_ocsp_tomcat_exec_t;
+files_type(pki_ocsp_tomcat_exec_t)
+
+pki_ca_template(pki_ocsp)
+corenet_tcp_connect_pki_ca_port(pki_ocsp_t)
+
+# forward proxy
+corenet_tcp_connect_pki_ocsp_port(httpd_t)
+
+attribute pki_ra_config;
+attribute pki_ra_executable;
+attribute pki_ra_var_lib;
+attribute pki_ra_var_log;
+attribute pki_ra_var_run;
+attribute pki_ra_pidfiles;
+attribute pki_ra_script;
+attribute pki_ra_process;
+
+type pki_ra_tomcat_exec_t;
+files_type(pki_ra_tomcat_exec_t)
+
+pki_ra_template(pki_ra)
+
+attribute pki_tks_config;
+attribute pki_tks_executable;
+attribute pki_tks_var_lib;
+attribute pki_tks_var_log;
+attribute pki_tks_var_run;
+attribute pki_tks_pidfiles;
+attribute pki_tks_script;
+attribute pki_tks_process;
+
+type pki_tks_tomcat_exec_t;
+files_type(pki_tks_tomcat_exec_t)
+
+pki_ca_template(pki_tks)
+corenet_tcp_connect_pki_ca_port(pki_tks_t)
+
+# forward proxy
+corenet_tcp_connect_pki_tks_port(httpd_t)
+
+# needed for token enrollment, list /var/cache/tomcat5/temp
+files_list_var(pki_tks_t)
+
+attribute pki_tps_config;
+attribute pki_tps_executable;
+attribute pki_tps_var_lib;
+attribute pki_tps_var_log;
+attribute pki_tps_var_run;
+attribute pki_tps_pidfiles;
+attribute pki_tps_script;
+attribute pki_tps_process;
+
+type pki_tps_tomcat_exec_t;
+files_type(pki_tps_tomcat_exec_t)
+
+pki_tps_template(pki_tps)
+
+#interprocess communication on process shutdown
+allow pki_ca_t pki_kra_t:process signull;
+allow pki_ca_t pki_ocsp_t:process signull;
+allow pki_ca_t pki_tks_t:process signull;
+
+allow pki_kra_t pki_ca_t:process signull;
+allow pki_kra_t pki_ocsp_t:process signull;
+allow pki_kra_t pki_tks_t:process signull;
+
+allow pki_ocsp_t pki_ca_t:process signull;
+allow pki_ocsp_t pki_kra_t:process signull;
+allow pki_ocsp_t pki_tks_t:process signull;
+
+allow pki_tks_t pki_ca_t:process signull;
+allow pki_tks_t pki_kra_t:process signull;
+allow pki_tks_t pki_ocsp_t:process signull;
+
+#allow httpd_t pki_tks_tomcat_exec_t:process signull;
+#allow httpd_t pki_tks_var_lib_t:process signull;
+
+# start up httpd in pki_tps_t mode
+can_exec(pki_tps_t, httpd_config_t)
+allow pki_tps_t httpd_exec_t:file entrypoint;
+allow pki_tps_t httpd_modules_t:lnk_file read;
+can_exec(pki_tps_t, httpd_suexec_exec_t)
+
+# apache permissions
+apache_exec_modules(pki_tps_t)
+apache_list_modules(pki_tps_t)
+apache_read_config(pki_tps_t)
+
+allow pki_tps_t lib_t:file execute_no_trans;
+
+#fowner needed for chmod
+allow pki_tps_t self:capability { setuid sys_nice setgid dac_override fowner fsetid kill};
+allow pki_tps_t self:process { setsched signal getsched signull execstack execmem sigkill};
+allow pki_tps_t self:sem all_sem_perms;
+allow pki_tps_t self:tcp_socket create_stream_socket_perms;
+
+# used to serve cgi web pages under /var/lib/pki-tps, formatting, enrollment
+allow pki_tps_t pki_tps_var_lib_t:file {execute execute_no_trans};
+
+ #netlink needed?
+allow pki_tps_t self:netlink_route_socket { write getattr read bind create nlmsg_read };
+
+corecmd_exec_bin(pki_tps_t)
+corecmd_exec_shell(pki_tps_t)
+corecmd_read_bin_symlinks(pki_tps_t)
+corecmd_search_bin(pki_tps_t)
+
+corenet_sendrecv_unlabeled_packets(pki_tps_t)
+corenet_tcp_bind_all_nodes(pki_tps_t)
+corenet_tcp_bind_pki_tps_port(pki_tps_t)
+corenet_tcp_connect_generic_port(pki_tps_t)
+
+# customer may run an ldap server on 389
+corenet_tcp_connect_ldap_port(pki_tps_t)
+
+# connect to other subsystems
+corenet_tcp_connect_pki_ca_port(pki_tps_t)
+corenet_tcp_connect_pki_kra_port(pki_tps_t)
+corenet_tcp_connect_pki_tks_port(pki_tps_t)
+
+corenet_tcp_sendrecv_all_if(pki_tps_t)
+corenet_tcp_sendrecv_all_nodes(pki_tps_t)
+corenet_tcp_sendrecv_all_ports(pki_tps_t)
+corenet_all_recvfrom_unlabeled(pki_tps_t)
+
+dev_read_urand(pki_tps_t)
+files_exec_usr_files(pki_tps_t)
+files_read_usr_symlinks(pki_tps_t)
+files_read_usr_files(pki_tps_t)
+
+#installation and debug uses /tmp
+files_manage_generic_tmp_dirs(pki_tps_t)
+files_manage_generic_tmp_files(pki_tps_t)
+
+kernel_read_kernel_sysctls(pki_tps_t)
+kernel_read_system_state(pki_tps_t)
+
+# need to resolve addresses?
+auth_use_nsswitch(pki_tps_t)
+
+sysnet_read_config(pki_tps_t)
+
+allow httpd_t pki_tps_etc_rw_t:dir search;
+allow httpd_t pki_tps_etc_rw_t:file rw_file_perms;
+allow httpd_t pki_tps_log_t:dir rw_dir_perms;
+allow httpd_t pki_tps_log_t:file manage_file_perms;
+allow httpd_t pki_tps_t:process { signal signull };
+allow httpd_t pki_tps_var_lib_t:dir { getattr search };
+allow httpd_t pki_tps_var_lib_t:lnk_file read;
+allow httpd_t pki_tps_var_lib_t:file read_file_perms;
+
+# why do I need to add this?
+allow httpd_t httpd_config_t:file execute;
+files_exec_usr_files(httpd_t)
+
+# talk to the hsm
+allow pki_tps_t pki_common_dev_t:sock_file write;
+allow pki_tps_t pki_common_dev_t:dir search;
+allow pki_tps_t pki_common_t:dir create_dir_perms;
+manage_files_pattern(pki_tps_t, pki_common_t, pki_common_t)
+can_exec(pki_tps_t, pki_common_t)
+init_stream_connect_script(pki_tps_t)
+
+#allow tps to talk to lunasa hsm
+logging_send_syslog_msg(pki_tps_t)
+
+# allow rpm -q in init scripts
+rpm_exec(pki_tps_t)
+
+# allow writing to the kernel keyring
+allow pki_tps_t self:key { write read };
+
+# new for f14
+apache_exec(pki_tps_t)
+
+ # start up httpd in pki_ra_t mode
+allow pki_ra_t httpd_config_t:file { read getattr execute };
+allow pki_ra_t httpd_exec_t:file entrypoint;
+allow pki_ra_t httpd_modules_t:lnk_file read;
+allow pki_ra_t httpd_suexec_exec_t:file { getattr read execute };
+
+#apache permissions
+apache_read_config(pki_ra_t)
+apache_exec_modules(pki_ra_t)
+apache_list_modules(pki_ra_t)
+
+allow pki_ra_t lib_t:file execute_no_trans;
+
+allow pki_ra_t self:capability { setuid sys_nice setgid dac_override fowner fsetid};
+allow pki_ra_t self:process { setsched getsched signal signull execstack execmem};
+allow pki_ra_t self:sem all_sem_perms;
+allow pki_ra_t self:tcp_socket create_stream_socket_perms;
+
+#RA specific? talking to mysql?
+allow pki_ra_t self:udp_socket { write read create connect };
+allow pki_ra_t self:unix_dgram_socket { write create connect };
+
+# netlink needed?
+allow pki_ra_t self:netlink_route_socket { write getattr read bind create nlmsg_read };
+
+corecmd_exec_bin(pki_ra_t)
+corecmd_exec_shell(pki_ra_t)
+corecmd_read_bin_symlinks(pki_ra_t)
+corecmd_search_bin(pki_ra_t)
+
+corenet_sendrecv_unlabeled_packets(pki_ra_t)
+corenet_tcp_bind_all_nodes(pki_ra_t)
+corenet_tcp_bind_pki_ra_port(pki_ra_t)
+
+corenet_tcp_sendrecv_all_if(pki_ra_t)
+corenet_tcp_sendrecv_all_nodes(pki_ra_t)
+corenet_tcp_sendrecv_all_ports(pki_ra_t)
+corenet_all_recvfrom_unlabeled(pki_ra_t)
+corenet_tcp_connect_generic_port(pki_ra_t)
+
+# talk to other subsystems
+corenet_tcp_connect_pki_ca_port(pki_ra_t)
+
+dev_read_urand(pki_ra_t)
+files_exec_usr_files(pki_ra_t)
+fs_getattr_xattr_fs(pki_ra_t)
+
+# ra writes files to /tmp
+files_manage_generic_tmp_files(pki_ra_t)
+
+kernel_read_kernel_sysctls(pki_ra_t)
+kernel_read_system_state(pki_ra_t)
+
+logging_send_syslog_msg(pki_ra_t)
+
+corenet_tcp_connect_smtp_port(pki_ra_t)
+files_search_spool(pki_ra_t)
+
+#
+# Should be changed to mta_send_mail
+#
+mta_manage_spool(pki_ra_t)
+mta_manage_queue(pki_ra_t)
+mta_read_config(pki_ra_t)
+mta_sendmail_exec(pki_ra_t)
+
+#resolve names?
+auth_use_nsswitch(pki_ra_t)
+
+sysnet_read_config(pki_ra_t)
+
+allow httpd_t pki_ra_etc_rw_t:dir search;
+allow httpd_t pki_ra_etc_rw_t:file rw_file_perms;
+allow httpd_t pki_ra_log_t:dir rw_dir_perms;
+allow httpd_t pki_ra_log_t:file manage_file_perms;
+allow httpd_t pki_ra_t:process { signal signull };
+allow httpd_t pki_ra_var_lib_t:dir { getattr search };
+allow httpd_t pki_ra_var_lib_t:lnk_file read;
+allow httpd_t pki_ra_var_lib_t:file read_file_perms;
+
+# talk to the hsm
+allow pki_ra_t pki_common_dev_t:sock_file write;
+allow pki_ra_t pki_common_dev_t:dir search;
+allow pki_ra_t pki_common_t:dir create_dir_perms;
+manage_files_pattern(pki_ra_t, pki_common_t, pki_common_t)
+can_exec(pki_ra_t, pki_common_t)
+init_stream_connect_script(pki_ra_t)
+
+# allow rpm -q in init scripts
+rpm_exec(pki_ra_t)
+
+# allow writing to the kernel keyring
+allow pki_ra_t self:key { write read };
+
+# new for f14
+apache_exec(pki_ra_t)
diff --git a/base/setup/CMakeLists.txt b/base/setup/CMakeLists.txt
new file mode 100644
index 000000000..2ed50ee62
--- /dev/null
+++ b/base/setup/CMakeLists.txt
@@ -0,0 +1,43 @@
+project(setup)
+
+install(
+ FILES
+ pkicreate
+ pkiremove
+ pki-setup-proxy
+ scripts/pkicontrol
+ DESTINATION
+ ${BIN_INSTALL_DIR}
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+install(
+ FILES
+ pkicommon.pm
+ 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
+ jars/resteasy-jettison-provider-2.3-RC1.jar
+ DESTINATION
+ ${JAVA_JAR_INSTALL_DIR}
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+# install empty directories
+install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${VAR_INSTALL_DIR}/lock/pki)")
+install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${VAR_INSTALL_DIR}/run/pki)")
diff --git a/base/setup/LICENSE b/base/setup/LICENSE
new file mode 100644
index 000000000..e281f4362
--- /dev/null
+++ b/base/setup/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/base/setup/jars/resteasy-jettison-provider-2.3-RC1.jar b/base/setup/jars/resteasy-jettison-provider-2.3-RC1.jar
new file mode 100644
index 000000000..da7106ddd
--- /dev/null
+++ b/base/setup/jars/resteasy-jettison-provider-2.3-RC1.jar
Binary files differ
diff --git a/base/setup/pki-setup-proxy b/base/setup/pki-setup-proxy
new file mode 100755
index 000000000..0222eab46
--- /dev/null
+++ b/base/setup/pki-setup-proxy
@@ -0,0 +1,499 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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) 2011 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+use strict;
+use warnings;
+
+use File::Copy;
+use Sys::Hostname;
+use Getopt::Long qw(GetOptions);
+use File::Slurp qw(read_file write_file);
+
+use lib "/usr/share/pki/scripts";
+use pkicommon;
+
+##############################################################
+# This script is used to convert an existing instance from a
+# non-proxy port configuration to a proxy port configuration.
+#
+# Sample Invocation (for CA):
+#
+# ./pki-setup-proxy -pki_instance_root=/var/lib
+# -pki_instance_name=pki-ca
+# -subsystem_type=ca
+# -ajp_redirect_port=9444
+# -ajp_port=9447
+# -proxy_secure_port=443
+# -proxy_unsecure_port=80
+# -unsecure_port=9080
+# -user=pkiuser
+# -group=pkiuser
+# -verbose
+#
+##############################################################
+
+##############################################################
+# Command-Line Variables
+##############################################################
+
+my $ARGS = ($#ARGV + 1);
+
+##############################################################
+# Local Variables
+##############################################################
+
+# Command-line variables (mandatory)
+my $pki_instance_root = undef;
+my $pki_instance_name = undef;
+my $subsystem_type = undef;
+
+# Command-line variables (optional)
+my $ajp_port = -1;
+my $ajp_redirect_port = -1;
+my $proxy_secure_port = -1;
+my $proxy_unsecure_port = -1;
+my $unsecure_port = -1;
+my $pki_user = $PKI_USER;
+my $pki_group = $PKI_GROUP;
+
+# Base subsystem directory paths
+my $pki_subsystem_conf_path = undef;
+
+# Base instance directory paths
+my $pki_instance_path = undef;
+my $pki_instance_conf_path = undef;
+my $pki_instance_webxml_path = undef;
+my $pki_instance_profile_select_path = undef;
+
+#proxy defaults
+my $PROXY_SECURE_PORT_DEFAULT = "443";
+my $PROXY_UNSECURE_PORT_DEFAULT = "80";
+my $UNSECURE_PORT_DEFAULT = "9080";
+my $AJP_PORT_DEFAULT = "9447";
+my $AJP_REDIRECT_PORT_DEFAULT = "9444";
+
+sub usage
+{
+ print STDOUT <<'EOF';
+###############################################################################
+### USAGE: CA, KRA, OCSP, or TKS subsystem proxy setup ###
+###############################################################################
+
+pki-proxy-setup \
+ -pki_instance_root=<pki_instance_root> # Instance root directory
+ # destination
+
+ -pki_instance_name=<pki_instance_id> # Unique PKI subsystem
+ # instance name
+
+ -subsystem_type=<subsystem_type> # Subsystem type
+ # [ca | kra | ocsp | tks]
+
+ [-ajp_port=<ajp_port>] # AJP port, default 9447
+
+ [-ajp_redirect_port=<ajp_redirect_port>] # AJP redirect port,
+ # default 9444
+
+ [-proxy_secure_port=<proxy_secure_port>] # Proxy secure port,
+ # default 443
+
+ [-proxy_unsecure_port=<unsecure_port>] # Proxy unsecure port,
+ # default 80
+
+ [-unsecure_port=<unsecure_port>] # UnSecure port,
+ # default 9080
+
+ [-user=<username>] # User ownership,
+ # default pkiuser
+
+ [-group=<groupname>] # Group ownership
+ # default pkiuser
+
+ [-verbose] # Print out liberal info
+ # Specify multiple times
+ # to increase verbosity.
+
+ [-help] # Print out this screen
+EOF
+
+}
+
+sub pki_instance_already_exists
+{
+ my ($name) = @_;
+ my $result = 0;
+ my $instance = "";
+
+ $instance = "/etc/sysconfig/pki"
+ . "/" . $subsystem_type
+ . "/" . $name;
+
+ if (-e $instance) {
+ $result = 1;
+ }
+
+ return $result;
+}
+
+# no args
+# return 1 - success, or
+# return 0 - failure
+sub parse_arguments
+{
+ my $l_proxy_secure_port = -1;
+ my $l_proxy_unsecure_port = -1;
+ my $l_unsecure_port = -1;
+ my $l_ajp_port = -1;
+ my $l_ajp_redirect_port = -1;
+ my $show_help = 0;
+ my $username = undef;
+ my $groupname = undef;
+
+ my $result = GetOptions("help" => \$show_help,
+ "pki_instance_root=s" => \$pki_instance_root,
+ "pki_instance_name=s" => \$pki_instance_name,
+ "subsystem_type=s" => \$subsystem_type,
+ "ajp_port:i" => \$l_ajp_port,
+ "ajp_redirect_port:i" => \$l_ajp_redirect_port,
+ "proxy_secure_port:i" => \$l_proxy_secure_port,
+ "proxy_unsecure_port:i" => \$l_proxy_unsecure_port,
+ "unsecure_port:i" => \$l_unsecure_port,
+ "user=s" => \$username,
+ "group=s" => \$groupname,
+ "verbose+" => \$verbose);
+
+ ## Optional "-help" option - no "mandatory" options are required
+ if ($show_help) {
+ usage();
+ return 0;
+ }
+
+ ## Mandatory "-pki_instance_root=s" option
+ if (!$pki_instance_root) {
+ usage();
+ emit("Must have value for -pki_instance_root!\n", "error");
+ return 0;
+ }
+
+ # Remove all trailing directory separators ('/')
+ $pki_instance_root =~ s/\/+$//;
+
+ ## Mandatory "-subsystem_type=s" option
+ if ($subsystem_type ne $CA &&
+ $subsystem_type ne $KRA &&
+ $subsystem_type ne $OCSP &&
+ $subsystem_type ne $TKS &&
+ $subsystem_type ne $RA &&
+ $subsystem_type ne $TPS) {
+ usage();
+ emit("Illegal value => $subsystem_type : for -subsystem_type!\n",
+ "error");
+ return 0;
+ }
+
+ if ($subsystem_type eq $RA ||
+ $subsystem_type eq $TPS) {
+ usage();
+ emit("Illegal value => $subsystem_type : for -subsystem_type!\n" .
+ "Proxy configuration is not yet supported for TPS and RA subsystems",
+ "error");
+ return 0;
+ }
+
+ ## Mandatory "-pki_instance_name=s" option
+ if (!$pki_instance_name) {
+ usage();
+ emit("Must have value for -pki_instance_name!\n", "error");
+ return 0;
+ }
+
+ if (! pki_instance_already_exists($pki_instance_name)) {
+ usage();
+ emit("An instance named $pki_instance_name "
+ . "does not exist; please try again.\n", "error");
+ return 0;
+ }
+
+ $pki_instance_path = "${pki_instance_root}/${pki_instance_name}";
+
+ # Capture installation information in a log file, always overwrite this file.
+ # When modifying an instance it's a fatal error if the logfile
+ # cannot be created.
+ my $logfile = "/var/log/${pki_instance_name}-proxy-setup.log";
+ if (!open_logfile($logfile, $default_file_permissions)) {
+ emit("can not create logfile ($logfile)", "error");
+ return 0;
+ }
+
+ printf(STDOUT "Capturing configuration information in %s\n", $logfile);
+
+ emit("Parsing setup_proxy arguments ...\n");
+ if ($verbose) {
+ emit(" verbose mode ENABLED (level=$verbose)\n");
+ }
+
+ if ($username) {
+ $pki_user = $username;
+ }
+ emit(" user $pki_user\n");
+
+ if ($groupname) {
+ $pki_group = $groupname;
+ }
+ emit(" group $pki_group\n");
+
+ $proxy_secure_port = ($l_proxy_secure_port >= 0) ? $l_proxy_secure_port :
+ $PROXY_SECURE_PORT_DEFAULT;
+ emit(" proxy_secure_port $proxy_secure_port\n");
+
+ $proxy_unsecure_port = ($l_proxy_unsecure_port >= 0) ? $l_proxy_unsecure_port :
+ $PROXY_UNSECURE_PORT_DEFAULT;
+ emit(" proxy_unsecure_port $proxy_unsecure_port\n");
+
+ $unsecure_port = ($l_unsecure_port >= 0) ? $l_unsecure_port :
+ $UNSECURE_PORT_DEFAULT;
+ emit(" unsecure_port $unsecure_port\n");
+
+ $ajp_port = ($l_ajp_port >= 0) ? $l_ajp_port : $AJP_PORT_DEFAULT;
+ emit(" ajp_port $ajp_port\n");
+
+ $ajp_redirect_port = ($l_ajp_redirect_port >= 0) ? $l_ajp_redirect_port :
+ $AJP_REDIRECT_PORT_DEFAULT;
+ emit(" ajp_redirect_port $ajp_redirect_port\n");
+
+ return 1;
+}
+
+# no args
+# no return
+sub initialize_paths
+{
+ $pki_instance_conf_path = "${pki_instance_path}/conf";
+ $pki_subsystem_conf_path = "/usr/share/pki/${subsystem_type}/conf";
+ $pki_instance_webxml_path = "${pki_instance_path}/webapps/${subsystem_type}" .
+ "/WEB-INF/web.xml";
+ $pki_instance_profile_select_path = "${pki_instance_path}/webapps/" .
+ "${subsystem_type}/ee/${subsystem_type}/" .
+ "ProfileSelect.template";
+}
+
+# no args
+# no return
+sub update_server_xml
+{
+ my $server_xml = "${pki_instance_conf_path}/server.xml";
+
+ my $new_match = <<EOF;
+ <!-- Define an AJP 1.3 Connector on port \\[PKI_AJP_PORT\\] -->
+<!--
+ <Connector port="\\[PKI_AJP_PORT\\]" protocol="AJP/1.3" redirectPort="\\[PKI_AJP_REDIRECT_PORT\\]" />
+-->
+EOF
+ my $old_match = <<EOF;
+ <!-- Define an AJP 1.3 Connector on port 8009 -->
+<!--
+ <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
+-->
+EOF
+ my $new_ajp = <<EOF;
+ <!-- Define an AJP 1.3 Connector on port $ajp_port -->
+ <Connector port="$ajp_port" protocol="AJP/1.3" redirectPort="$ajp_redirect_port" />
+EOF
+
+ my $data = read_file $server_xml;
+ $data =~ s/$old_match/$new_ajp/;
+ $data =~ s/$new_match/$new_ajp/;
+
+ # back up existing server.xml
+ copy_file($server_xml, $server_xml . ".pre-proxy.$$",
+ $default_file_permissions, $pki_user, $pki_group);
+ write_file($server_xml, $data);
+ set_file_props($server_xml, $default_file_permissions,
+ $pki_user, $pki_group);
+
+}
+
+# no args
+# no return
+sub update_proxy_conf
+{
+ my $template_file = "${pki_subsystem_conf_path}/proxy.conf";
+ my $server_file = "${pki_instance_conf_path}/proxy.conf";
+
+ #backup, just in case there already was a file
+ copy_file($server_file, $server_file . ".pre-proxy.$$",
+ $default_file_permissions, $pki_user, $pki_group);
+
+ my $data = read_file $template_file;
+ my $host = hostname;
+ $data =~ s/\[PKI_MACHINE_NAME\]/$host/g;
+ $data =~ s/\[PKI_AJP_PORT\]/$ajp_port/g;
+
+ write_file($server_file, $data);
+ set_file_props($server_file, $default_file_permissions,
+ $pki_user, $pki_group);
+
+}
+
+# no args
+# no return
+sub update_web_xml
+{
+ my $data = read_file $pki_instance_webxml_path;
+
+ my $commented_proxy_stanza = <<EOF;
+<!--
+ <init-param>
+ <param-name>proxy_port</param-name>
+ <param-value></param-value>
+ </init-param>
+-->
+EOF
+ my $proxy_stanza = <<EOF;
+ <init-param>
+ <param-name>proxy_port</param-name>
+ <param-value>$proxy_secure_port</param-value>
+ </init-param>
+EOF
+
+ my $commented_proxy_stanza_2 = <<EOF;
+<!--
+ <init-param>
+ <param-name>proxy_port</param-name>
+ <param-value></param-value>
+ </init-param>
+ <init-param>
+ <param-name>proxy_http_port</param-name>
+ <param-value></param-value>
+ </init-param>
+-->
+EOF
+ my $proxy_stanza_2 = <<EOF;
+ <init-param>
+ <param-name>proxy_port</param-name>
+ <param-value>$proxy_secure_port</param-value>
+ </init-param>
+ <init-param>
+ <param-name>proxy_http_port</param-name>
+ <param-value>$proxy_unsecure_port</param-value>
+ </init-param>
+EOF
+
+ my $ee_filter_head = <<EOF;
+ <filter>
+ <filter-name>EERequestFilter</filter-name>
+ <filter-class>com.netscape.cms.servlet.filter.EERequestFilter</filter-class>
+ <init-param>
+ <param-name>http_port</param-name>
+ <param-value>$unsecure_port</param-value>
+ </init-param>
+ <init-param>
+ <param-name>https_port</param-name>
+ <param-value>$proxy_secure_port</param-value>
+ </init-param>
+EOF
+
+ my $active_stanza = <<EOF;
+ <init-param>
+ <param-name>active</param-name>
+EOF
+
+ if ($data =~ /$commented_proxy_stanza/) {
+ $data =~ s/$commented_proxy_stanza/$proxy_stanza/g;
+ $data =~ s/$commented_proxy_stanza_2/$proxy_stanza_2/g;
+ } else {
+ $data =~ s/$active_stanza/${proxy_stanza}${active_stanza}/g;
+ $data =~ s/${ee_filter_head}${proxy_stanza}${active_stanza}/${ee_filter_head}${proxy_stanza_2}${active_stanza}/;
+ }
+
+ # backup old file
+ copy_file($pki_instance_webxml_path, $pki_instance_webxml_path . ".pre_proxy",
+ $default_file_permissions, $pki_user, $pki_group);
+
+ write_file($pki_instance_webxml_path, $data);
+ set_file_props($pki_instance_webxml_path, $default_file_permissions,
+ $pki_user, $pki_group);
+}
+
+# no args
+# no return
+sub update_cs_cfg
+{
+ my $cs_cfg = "${pki_instance_conf_path}/CS.cfg";
+ my $data = read_file $cs_cfg;
+
+ $data =~ s/proxy.securePort=[\d]*\n//g;
+ $data =~ s/proxy.unsecurePort=[\d]*\n//g;
+ chomp($data);
+ $data .= "\nproxy.securePort=$proxy_secure_port" .
+ "\nproxy.unsecurePort=$proxy_unsecure_port\n";
+
+ # backup old file
+ copy_file($cs_cfg, $cs_cfg . ".pre-proxy.$$",
+ $default_file_permissions, $pki_user, $pki_group);
+
+ write_file($cs_cfg, $data);
+ set_file_props($cs_cfg, $default_file_permissions,
+ $pki_user, $pki_group);
+}
+
+# no args
+# no return
+sub update_profile_select_template
+{
+ my $template_file = $pki_instance_profile_select_path;
+ my $data = read_file $template_file;
+
+ my $host = hostname;
+ $data =~ s/https:\/\/$host:\d*\/ca\/eeca/https:\/\/$host:$proxy_secure_port\/ca\/eeca/;
+
+ # backup old file
+ copy_file($template_file, $template_file . ".pre-proxy.$$",
+ $default_file_permissions, $pki_user, $pki_group);
+
+ write_file($template_file, $data);
+ set_file_props($template_file, $default_file_permissions,
+ $pki_user, $pki_group);
+}
+
+######################################
+# Main program
+#####################################
+
+sub main
+{
+ my $parse_result = parse_arguments();
+ if (!$parse_result) {
+ close_logfile();
+ exit 255;
+ }
+
+ initialize_paths();
+ update_server_xml();
+ update_proxy_conf();
+ update_web_xml();
+ update_cs_cfg();
+ update_profile_select_template();
+ parse_selinux_ports();
+ add_selinux_port("pki_${subsystem_type}_port_t", $ajp_port);
+}
+
+main();
+exit 0;
diff --git a/base/setup/pkicommon.pm b/base/setup/pkicommon.pm
new file mode 100755
index 000000000..6ce255303
--- /dev/null
+++ b/base/setup/pkicommon.pm
@@ -0,0 +1,3580 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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-2010 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+
+package pkicommon;
+use strict;
+use warnings;
+
+use Exporter;
+our @ISA = qw(Exporter);
+our @EXPORT = qw(
+ $lib_prefix $obj_ext $path_sep $tmp_dir
+ $pki_flavor $pki_registry_path
+ $verbose $dry_run $hostname $default_hardware_platform
+ $default_system_binaries $default_lockdir $default_system_libraries $default_system_user_binaries
+ $default_system_user_libraries
+ $default_java_path $default_pki_java_path $default_x86_64_jni_java_path $default_system_jni_java_path @default_jar_path
+ $default_security_libraries $default_certutil_command
+ $default_ldapmodify_command $default_modutil_command
+ $default_dir_permissions $default_exe_permissions $default_file_permissions
+ $default_initscripts_path $default_registry_path
+ $ROOTUID $MAX_WELL_KNOWN_PORT $MAX_RESERVED_PORT $MAX_REGISTERED_PORT $MAX_DYNAMIC_PORT
+ $FILE_PREFIX $FTP_PREFIX $HTTP_PREFIX $HTTPS_PREFIX $LDAP_PREFIX $LDAPS_PREFIX
+ $PKI_USER $PKI_GROUP $PKI_UID $PKI_GID
+ $CA $KRA $OCSP $TKS $RA $TPS
+ $CA_INITSCRIPT $KRA_INITSCRIPT $OCSP_INITSCRIPT
+ $TKS_INITSCRIPT $RA_INITSCRIPT $TPS_INITSCRIPT
+ $install_info_basename $cleanup_basename %installation_info
+ $semanage $restorecon $SELINUX_PORT_UNDEFINED $SELINUX_PORT_DEFINED $SELINUX_PORT_WRONGLY_DEFINED
+
+ add_install_info remove_install_info get_install_description
+ format_install_info get_install_info_description
+ parse_install_info parse_old_cleanup read_old_cleanup
+ read_install_info read_install_info_from_dir write_install_info_to_dir uninstall
+ is_Windows is_Linux is_Fedora is_RHEL is_RHEL4 setup_platform_dependent_parameters
+ set_library_path get_library_path fedora_release
+ check_for_root_UID user_disallows_shell
+ user_exists create_user
+ group_exists create_group user_is_a_member_of_group add_user_as_a_member_of_group
+ get_UID_from_username
+ get_FQDN check_for_valid_url_prefix
+ AreConnectorPortsValid IsLocalPortAvailable IsServerReachable
+ get_time_stamp generate_random generate_random_string password_quality_checker
+ LDAP_add LDAP_modify
+ certutil_create_databases certutil_delete_cert certutil_generate_CSR
+ certutil_generate_self_signed_cert certutil_import_cert
+ certutil_print_cert certutil_list_certs modutil_add_token
+ open_logfile get_logfile_path close_logfile
+ prompt printFile emit
+ is_path_valid is_name_valid entity_type entity_exists
+ file_exists is_file_empty create_empty_file create_file copy_file remove_file
+ set_permissions set_owner_group set_file_props
+ get_directory_files normalize_path
+ directory_exists is_directory_empty create_directory copy_directory remove_directory
+ set_owner_group_on_directory_contents
+ symlink_exists create_symlink remove_symlink set_owner_group_on_symlink
+ run_command get_cs_cfg get_registry_initscript_name
+ register_pki_instance_with_chkconfig deregister_pki_instance_with_chkconfig
+ find_jar
+ check_selinux_port parse_selinux_ports add_selinux_port add_selinux_file_context
+ );
+
+
+use File::Slurp qw(read_file write_file);
+
+##############################################################
+# This file contains shared data and subroutines for
+# the "pkicreate" and "pkiremove" Perl scripts.
+##############################################################
+
+
+##############################################################
+# Perl Version
+##############################################################
+
+my $MINIMUM_PERL_VERSION = "5.006001";
+
+my $perl_version_error_message = "ERROR: Using Perl version $] ...\n"
+ . " Must use Perl version "
+ . "$MINIMUM_PERL_VERSION or later to "
+ . "run this script!\n";
+
+die $perl_version_error_message if $] < $MINIMUM_PERL_VERSION;
+
+
+##############################################################
+# Execution Check
+##############################################################
+
+# Check to insure that this script's original
+# invocation directory has not been deleted!
+my $cwd = `/bin/pwd`;
+chomp $cwd;
+if (!$cwd) {
+ emit("Cannot invoke '$0' from non-existent directory!\n", "error");
+ exit 255;
+}
+
+
+##############################################################
+# Environment Variables
+##############################################################
+
+# untaint called subroutines
+if (($^O ne 'Windows_NT') && ($^O ne 'MSWin32')) {
+ $> = $<; # set effective user ID to real UID
+ $) = $(; # set effective group ID to real GID
+ $ENV{'PATH'} = '/bin:/usr/bin';
+ $ENV{'ENV'} = '' if !defined($ENV{'ENV'});
+}
+
+
+##############################################################
+# Perl Modules
+##############################################################
+
+use Sys::Hostname;
+use FileHandle;
+use Socket;
+use File::Copy;
+use File::Basename;
+use File::Path qw(make_path remove_tree);
+
+##############################################################
+# Global Variables
+##############################################################
+
+# Platform-dependent parameters
+our $lib_prefix = undef;
+our $obj_ext = undef;
+our $path_sep = undef;
+our $tmp_dir = undef;
+
+# Whether or not to do verbose mode
+our $verbose = 0;
+
+# Controls whether actions are executed (dry_run == false)
+# or if actions are only reported (dry_run == true).
+our $dry_run = 0;
+
+our $hostname = undef;
+
+# selinux structures
+our %selinux_ports = ();
+
+##############################################################
+# Shared Default Values
+##############################################################
+
+our $pki_flavor = undef;
+our $pki_registry_path = undef;
+
+our $default_hardware_platform = undef;
+our $default_system_binaries = undef;
+our $default_lockdir = undef;
+our $default_system_libraries = undef;
+our $default_system_user_binaries = undef;
+our $default_system_user_libraries = undef;
+our $default_java_path = undef;
+our $default_pki_java_path = undef;
+our $default_x86_64_jni_java_path = undef;
+our $default_system_jni_java_path = undef;
+our @default_jar_path = undef;
+our $default_security_libraries = undef;
+our $default_certutil_command = undef;
+our $default_ldapmodify_command = undef;
+our $default_modutil_command = undef;
+our $default_initscripts_path = undef;
+our $default_registry_path = undef;
+my $candlepin_java_path = "/usr/share/candlepin/lib";
+
+our $default_dir_permissions = 00770;
+our $default_exe_permissions = 00770;
+our $default_file_permissions = 00660;
+
+our $semanage = "/usr/sbin/semanage";
+our $restorecon = "/sbin/restorecon";
+our $SELINUX_PORT_UNDEFINED = 0;
+our $SELINUX_PORT_DEFINED = 1;
+our $SELINUX_PORT_WRONGLY_DEFINED = 2;
+
+
+
+# Use a local variable to denote IPv6
+my $is_IPv6 = 0;
+
+# Compute "hardware platform" of Operating System
+if ($^O eq "linux") {
+ $pki_flavor = "pki";
+ $default_registry_path = "/etc/sysconfig";
+ $pki_registry_path = "$default_registry_path/$pki_flavor";
+ $default_initscripts_path = "/etc/rc.d/init.d";
+ $default_lockdir = "/var/lock/$pki_flavor";
+ $default_hardware_platform = `uname -i`;
+ $default_hardware_platform =~ s/\s+$//g;
+ chomp($default_hardware_platform);
+ if ($default_hardware_platform eq "i386") {
+ # 32-bit Linux
+ $default_system_binaries = "/bin";
+ $default_system_libraries = "/lib";
+ $default_system_user_binaries = "/usr/bin";
+ $default_system_user_libraries = "/usr/lib";
+ $default_java_path = "/usr/share/java";
+ $default_pki_java_path = "/usr/share/java/pki";
+ $default_system_jni_java_path = "/usr/lib/java";
+ @default_jar_path = ($default_pki_java_path, $default_java_path, $default_system_jni_java_path, $candlepin_java_path);
+ } elsif ($default_hardware_platform eq "x86_64") {
+ # 64-bit Linux
+ $default_system_binaries = "/bin";
+ $default_system_libraries = "/lib64";
+ $default_system_user_binaries = "/usr/bin";
+ $default_system_user_libraries = "/usr/lib64";
+ $default_java_path = "/usr/share/java";
+ $default_pki_java_path = "/usr/share/java/pki";
+ $default_x86_64_jni_java_path = "/usr/lib64/java";
+ $default_system_jni_java_path = "/usr/lib/java";
+ @default_jar_path = ($default_pki_java_path, $default_java_path, $default_x86_64_jni_java_path,
+ $default_system_jni_java_path, $candlepin_java_path);
+ } else {
+ emit("Unsupported '$^O' hardware platform '$default_hardware_platform'!", "error");
+ exit 255;
+ }
+
+ # Retrieve hostname
+ if (defined($ENV{'PKI_HOSTNAME'})) {
+ # IPv6: Retrieve hostname from environment variable
+ $hostname = $ENV{'PKI_HOSTNAME'};
+ $is_IPv6 = 1;
+ } else {
+ # IPv4: Retrieve hostname using Sys::Hostname
+ $hostname = hostname;
+ }
+} else {
+ emit("Unsupported platform '$^O'!\n", "error");
+ exit 255;
+}
+
+
+$default_security_libraries = "$default_system_user_libraries/dirsec";
+
+$default_certutil_command = "$default_system_user_binaries/certutil";
+$default_ldapmodify_command = "$default_system_user_binaries/ldapmodify";
+$default_modutil_command = "$default_system_user_binaries/modutil";
+
+
+##############################################################
+# Global Constants
+##############################################################
+
+our $ROOTUID = 0;
+
+our $MAX_WELL_KNOWN_PORT = 511; # well-known ports = 0 through 511
+our $MAX_RESERVED_PORT = 1023; # reserved ports = 512 through 1023
+our $MAX_REGISTERED_PORT = 49151; # registered ports = 1024 through 49151
+our $MAX_DYNAMIC_PORT = 65535; # dynamic/private ports = 49152 through 65535
+
+our $FILE_PREFIX = "file://";
+our $FTP_PREFIX = "ftp://";
+our $HTTP_PREFIX = "http://";
+our $HTTPS_PREFIX = "https://";
+our $LDAP_PREFIX = "ldap://";
+our $LDAPS_PREFIX = "ldaps://";
+
+# Identity values
+our $PKI_USER = "pkiuser";
+our $PKI_GROUP = "pkiuser";
+our $PKI_UID = 17;
+our $PKI_GID = 17;
+
+# Subsystem names
+our $CA = "ca";
+our $KRA = "kra";
+our $OCSP = "ocsp";
+our $TKS = "tks";
+our $RA = "ra";
+our $TPS = "tps";
+
+# Subsystem init scripts
+our $CA_INITSCRIPT = "pki-cad";
+our $KRA_INITSCRIPT = "pki-krad";
+our $OCSP_INITSCRIPT = "pki-ocspd";
+our $TKS_INITSCRIPT = "pki-tksd";
+our $RA_INITSCRIPT = "pki-rad";
+our $TPS_INITSCRIPT = "pki-tpsd";
+
+
+##############################################################
+# Local Variables
+##############################################################
+
+# "identity" parameters
+my $fqdn = undef;
+
+# "logging" parameters
+my $logfd = undef;
+my $logfile_path = undef;
+
+
+
+##############################################################
+# Routines & data structures used to track &
+# manage installation information
+##############################################################
+
+# Basename of the installation info file.
+our $install_info_basename = "install_info";
+
+# Basename of the old clean up file.
+our $cleanup_basename = ".cleanup.dat";
+
+# Global hash table of installation actions
+# Each filesystem path which is modified during installation
+# is entered into this table as a key. The value associated
+# with the key is an anonymous hash table of key/value pairs,
+# e.g. the installation metadata associated with the path.
+# This table should not be directly modified, rather use
+# the utility subroutines which know how to operate on
+# on an installation info table. The utility routines can
+# operate on any installation table, but default to using
+# this single global table.
+our %installation_info = ();
+
+# Table to validate an installation type
+my %valid_install_types = ('file' => 1,
+ 'symlink' => 1,
+ 'dir' => 1);
+
+# Table to validate a install action
+my %valid_install_action = ('create' => 1,
+ 'move' => 1,
+ 'remove' => 1);
+
+# Table to validate an uninstall action
+my %valid_uninstall_action = ('remove' => 1,
+ 'preserve' => 1);
+
+# Capture information about items modified during installation
+#
+# add_install_info(path, [type='file'], [uninstall_action='remove],
+# [install_action='create])
+#
+# path the path name of the object
+# type what kind of object
+# (file, symlink, dir)
+# uninstall_action - during uninstall what should be done
+# (remove, preserve)
+# install_action what was done during install
+# (create, move, remove)
+#
+# The data structure used to capture the information is a hash
+# table whose keys are path names and whose value is a hash
+# table of key/value attributes belonging to the path object.
+sub add_install_info {
+ my ($path, $type, $uninstall_action, $install_action) = @_;
+ my ($install_info) = \%installation_info;
+ $type = 'file' unless defined($type);
+ $uninstall_action = 'remove' unless defined($uninstall_action);
+ $install_action = 'create' unless defined($install_action);
+ my $info;
+
+ die "invalid install type ($type) for path ($path)"
+ if (!exists($valid_install_types{$type}));
+
+ die "invalid uninstall action ($uninstall_action) for path ($path)"
+ if (!exists($valid_uninstall_action{$uninstall_action}));
+
+ die "invalid install action ($install_action) for path ($path)"
+ if (!exists($valid_install_action{$install_action}));
+
+ if (exists($install_info->{$path})) {
+ $info = $install_info->{$path};
+ } else {
+ $install_info->{$path} = $info = {};
+ }
+
+ $info->{'type'} = $type;
+ $info->{'install_action'} = $install_action;
+ $info->{'uninstall_action'} = $uninstall_action;
+}
+
+# Removes the install info for the given path.
+# Used primarily after an error occurs.
+sub remove_install_info {
+ my ($path) = @_;
+ my ($install_info) = \%installation_info;
+
+ delete $install_info->{$path};
+}
+
+# return text description of installed files and directories
+sub get_install_description
+{
+ my ($install_info) = \%installation_info;
+
+ return get_install_info_description($install_info);
+}
+
+# Given a hash of installation information format it into text.
+# Each path name is in brackets at the beginning of a line
+# followed by the path's attributes, which is an indented line of
+# key = value, for each attribute
+#
+# The formatted text is referred to as a "Installation Manifest".
+#
+# returns formatted text
+#
+# Example:
+#
+# [/etc/pki-ca]
+# install_action = create
+# type = dir
+# uninstall_action = remove
+# [/etc/pki-ca/CS.cfg]
+# install_action = create
+# type = file
+# uninstall_action = remove
+#
+sub format_install_info
+{
+ my ($install_info) = @_;
+ my ($text, @paths, $path, $info, @key_names, $key, $value);
+
+ $text = "";
+ @paths = sort(keys %$install_info);
+ foreach $path (@paths) {
+ $info = $install_info->{$path};
+ $text .= sprintf("[%s]\n", $path);
+ @key_names = sort(keys %$info);
+ foreach $key (@key_names) {
+ $value = $info->{$key};
+ $text .= sprintf(" %s = %s\n", $key, $value);
+ }
+ }
+ return $text;
+}
+
+# Given a hash of installation information format it into
+# into friendly description of what was installed.
+#
+# Brief Example:
+#
+# Installed Files:
+# /etc/pki-ca/CS.cfg
+# /var/log/pki-ca-install.log
+# Installed Directories:
+# /etc/pki-ca
+# /var/log/pki-ca
+# Installed Symbolic Links:
+# /var/lib/pki-ca/logs
+# Removed Items:
+# /etc/pki-ca/noise
+#
+sub get_install_info_description
+{
+ my ($install_info) = @_;
+ my ($text, @paths, @filtered_paths, $path);
+
+ $text = '';
+ @paths = sort(keys %$install_info);
+
+ @filtered_paths = grep {my ($info) = $install_info->{$_};
+ $info->{'type'} eq 'file' &&
+ $info->{'install_action'} ne 'remove'} @paths;
+ if (@filtered_paths) {
+ $text .= "Installed Files:\n";
+ foreach $path (@filtered_paths) {
+ $text .= " ${path}\n";
+ }
+ }
+
+ @filtered_paths = grep {my ($info) = $install_info->{$_};
+ $info->{'type'} eq 'dir' &&
+ $info->{'install_action'} ne 'remove'} @paths;
+ if (@filtered_paths) {
+ $text .= "Installed Directories:\n";
+ foreach $path (@filtered_paths) {
+ $text .= " ${path}\n";
+ }
+ }
+
+ @filtered_paths = grep {my ($info) = $install_info->{$_};
+ $info->{'type'} eq 'symlink' &&
+ $info->{'install_action'} ne 'remove'} @paths;
+ if (@filtered_paths) {
+ $text .= "Installed Symbolic Links:\n";
+ foreach $path (@filtered_paths) {
+ $text .= " ${path}\n";
+ }
+ }
+
+ @filtered_paths = grep {my ($info) = $install_info->{$_};
+ $info->{'install_action'} eq 'remove'} @paths;
+ if (@filtered_paths) {
+ $text .= "Removed Items:\n";
+ foreach $path (@filtered_paths) {
+ $text .= " ${path}\n";
+ }
+ }
+
+ return $text;
+
+}
+
+# Given text as formatted by format_install_info() parse it into
+# a install info hash table where each key is a path name and whose
+# value is a hash table of key/value pairs.
+#
+# E.g. this routine parses an "Installation Manifest".
+#
+# Returns pointer to an install info hash table
+sub parse_install_info
+{
+ my ($text) = @_;
+ my ($install_info, @lines, $line, $line_num, $path, $info, $key, $value);
+
+ $install_info = {};
+ @lines = split(/\n/, $text);
+ $line_num = 0;
+ $path = undef;
+ $info = undef;
+
+ foreach $line (@lines) {
+ $line_num++;
+ $line =~ s/#.*//; # nuke comments
+ $line =~ s/\s+$//; # strip trailing whitespace
+ next if !$line; # skip blank lines
+
+ # Look for quoted path at beginning of line
+ if ($line =~ /^\s*\[(.+)\]\s*$/) {
+ $path = $1;
+ $info = {};
+ $install_info->{$path} = $info;
+ next;
+ }
+
+ if (defined($path)) {
+ # Look for key = value in section, must be preceded by whitespace
+ undef($key);
+ if ($line =~ /^\s+(\w+)\s*=\s*(.*)/) {
+ # quoted name followed by a colon followed by an action
+ $key = $1;
+ $value = $2;
+ $info->{$key} = $value;
+ }
+ }
+ }
+ return $install_info;
+}
+
+# Formerly the installation info was written as an ini style
+# file, a section for files and a section for directories.
+# Everything in the file was meant to be removed upon uninstall.
+#
+# Returns an install info style hash table (see parse_install_info)
+sub parse_old_cleanup
+{
+ my ($text) = @_;
+ my ($install_info, @lines, $line, $section, $info, $path);
+
+ $install_info = {};
+ @lines = split(/\n/, $text);
+
+ foreach $line (@lines) {
+ $line =~ s/#.*//; # nuke comments
+ $line =~ s/^\s+//; # strip leading whitespace
+ $line =~ s/\s+$//; # strip trailing whitespace
+ next if !$line; # skip blank lines
+
+ # Look for section markers
+ if ($line =~ /^\s*\[\s*(\w+)\s*\]\s*$/) {
+ $section = $1;
+ next;
+ }
+
+ # Must be path name
+ $path = $line;
+ $info = {};
+ $install_info->{$path} = $info;
+ $info->{'uninstall_action'} = 'remove';
+ if ($section eq 'files') {
+ $info->{'type'} = 'file';
+ } elsif ($section eq 'directories') {
+ $info->{'type'} = 'dir';
+ } else {
+ die "unknown cleanup section = \"$section\"\n";
+ }
+ }
+ return $install_info;
+}
+
+# Get the contents of the old cleanup file
+sub read_old_cleanup
+{
+ my ($path) = @_;
+ my ($text);
+
+ $text = read_file($path);
+ return parse_old_cleanup($text);
+}
+
+# Get the contents of an install info file
+sub read_install_info
+{
+ my ($path) = @_;
+ my ($text);
+
+ $text = read_file($path);
+ return parse_install_info($text);
+}
+
+# Get the contents of installation info from a directory.
+# Supports both the new install info format and the older
+# cleanup format. First checks for the presence of the newer
+# install info format file, if that's absent reads the older
+# cleanup format but returns it as the new install info hash table.
+sub read_install_info_from_dir
+{
+ my ($dir) = @_;
+ my ($path);
+
+ $path = "${dir}/${install_info_basename}";
+ if (-e $path) {
+ return read_install_info($path);
+ }
+
+ $path = "${dir}/${cleanup_basename}";
+ if (-e $path) {
+ return read_old_cleanup($path);
+ }
+
+ return undef;
+}
+
+# Give an install info hash table writes it formated as a
+# "Installation Manifest" into specified directory under
+# the name $install_info_basename
+#
+# Returns pathname of manifest if successful, undef otherwise.
+sub write_install_info_to_dir
+{
+ my ($dir, $install_info) = @_;
+ my ($path, $formatted);
+
+ if (! defined($dir)) {
+ emit("Cannot write installation manifest, directory unspecified", "error");
+ return undef;
+ }
+
+ if (! defined($install_info_basename)) {
+ emit("Cannot write installation manifest, file basename unspecified", "error");
+ return undef;
+ }
+
+ if (! -e $dir) {
+ emit("Cannot write installation manifest, directory ($dir) does not exist", "error");
+ return undef;
+ }
+
+ if (! -d $dir) {
+ emit("Cannot write installation manifest, directory ($dir) is not a directory", "error");
+ return undef;
+ }
+
+ if (! -w $dir) {
+ emit("Cannot write installation manifest, directory ($dir) is not writable", "error");
+ return undef;
+ }
+
+ $path = "${dir}/${install_info_basename}";
+ $formatted = format_install_info($install_info);
+ write_file($path, \$formatted);
+
+ return $path;
+}
+
+# Given an Installation Manifest (e.g. install_info) remove the items in
+# the manifest marked for removal.
+#
+# 1) Remove all files and symlinks we created.
+#
+# 2) Attempt to remove all directories we created, even if they are non-empty.
+#
+sub uninstall
+{
+ my ($install_info) = @_;
+ my ($result, @paths, @filtered_paths, $path, @dirs);
+
+ $result = 1;
+
+ @paths = sort(keys %$install_info);
+
+ # Get a list of files marked for removal.
+ @filtered_paths = grep {my ($info) = $install_info->{$_};
+ ($info->{'type'} eq 'file' || $info->{'type'} eq 'symlink') &&
+ $info->{'install_action'} ne 'remove' &&
+ $info->{'uninstall_action'} eq 'remove'} @paths;
+ # Remove the files
+ if (@filtered_paths) {
+ foreach $path (@filtered_paths) {
+ $result = 0 if !remove_file($path);
+ }
+ }
+
+ # Get a list of directories marked for removal.
+ @filtered_paths = grep {my ($info) = $install_info->{$_};
+ $info->{'type'} eq 'dir' &&
+ $info->{'uninstall_action'} eq 'remove'} @paths;
+
+ # We need to removed directories starting at the deepest level
+ # and progressively work upward, otherwise the directory might
+ # not be empty. To accomplish this we sort the directory array
+ # based on the number of path components.
+
+ # Primary sort by number of path components, longest first.
+ # When the number of path components is the same the secondary sort
+ # is lexical string comparision.
+ @dirs = sort {my ($r, @a, @b);
+ @a = split("/", $a);
+ @b = split("/", $b);
+ $r = @b <=> @a;
+ $r == 0 ? $a cmp $b : $r} @filtered_paths;
+
+ foreach $path (@dirs) {
+ $result = 0 if !remove_directory($path, 1);
+ }
+
+ return $result;
+}
+
+##############################################################
+# Generic "platform" Subroutines
+##############################################################
+
+# no args
+# return 1 - true, or
+# return 0 - false
+sub is_Windows
+{
+ if (($^O eq "Windows_NT") || ($^O eq "MSWin32")) {
+ return 1;
+ }
+
+ return 0;
+}
+
+
+# no args
+# return 1 - true, or
+# return 0 - false
+sub is_Linux
+{
+ if ($^O eq "linux") {
+ return 1;
+ }
+
+ return 0;
+}
+
+
+# no args
+# return 1 - true, or
+# return 0 - false
+sub is_Fedora
+{
+ if (is_Linux() && (-e "/etc/fedora-release")) {
+ return 1;
+ }
+
+ return 0;
+}
+
+
+# no args
+# return 1 - true, or
+# return 0 - false
+sub is_RHEL {
+ if ((! is_Fedora()) && (-e "/etc/redhat-release")) {
+ return 1;
+ }
+
+ return 0;
+}
+
+
+# no args
+# return 1 - true, or
+# return 0 - false
+sub is_RHEL4 {
+ if (is_RHEL()) {
+ my $releasefd = new FileHandle;
+ if ($releasefd->open("< /etc/redhat-release")) {
+ while (defined(my $line = <$releasefd>)) {
+ if ($line =~ /Nahant/i) {
+ return 1;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+# no args
+# return release_number
+# return 0 if not found
+sub fedora_release {
+ my $releasefd = new FileHandle;
+ if ($releasefd->open("< /etc/fedora-release")) {
+ while (defined(my $line = <$releasefd>)) {
+ if ($line =~ /Fedora release (\d*)/) {
+ return $1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+# no args
+# no return value
+sub setup_platform_dependent_parameters
+{
+ # Setup path separators, et. al., based upon platform
+ if (is_Windows()) {
+ $lib_prefix = "";
+ $obj_ext = ".dll";
+ $path_sep = ";";
+ $tmp_dir = "c:\\temp";
+ } elsif ($^O eq "hpux") {
+ $lib_prefix = "lib";
+ $obj_ext = ".sl";
+ $path_sep = ":";
+ $tmp_dir = "/tmp";
+ } else {
+ $lib_prefix = "lib";
+ $obj_ext = ".so";
+ $path_sep = ":";
+ $tmp_dir = "/tmp";
+ }
+
+ return;
+}
+
+
+# Takes an array reference containing a list of paths.
+# Any item in the list which is undefined will be ignored.
+# no return value
+sub set_library_path
+{
+ my ($paths) = @_;
+ my ($path);
+
+ $path = join($path_sep, grep(defined($_), @$paths));
+
+ if (is_Windows()) {
+ $ENV{'PATH'} = $path;
+ } elsif ($^O eq "hpux") {
+ $ENV{'SHLIB_PATH'} = $path;
+ } else {
+ $ENV{'LD_LIBRARY_PATH'} = $path;
+ }
+
+ return;
+}
+
+
+# no args
+# return Library Path Environment variable
+sub get_library_path
+{
+ if (is_Windows()) {
+ return $ENV{'PATH'};
+ } elsif ($^O eq "hpux") {
+ return $ENV{'SHLIB_PATH'};
+ } else {
+ return $ENV{'LD_LIBRARY_PATH'};
+ }
+}
+
+
+##############################################################
+# Generic "identity" Subroutines
+##############################################################
+
+# no args
+# return 1 - success, or
+# return 0 - failure
+sub check_for_root_UID
+{
+ my $result = 0;
+
+ # On Linux/UNIX, insure that this script is being run as "root";
+ # First check the "Real" UID, and then check the "Effective" UID.
+ if (!is_Windows()) {
+ if (($< != $ROOTUID) &&
+ ($> != $ROOTUID)) {
+ emit("This script must be run as root!\n", "error");
+ $result = 0;
+ } else {
+ # Success -- running script as root
+ $result = 1;
+ }
+ } else {
+ emit("Root UID makes no sense on Windows machines!\n", "error");
+ $result = 0;
+ }
+
+ return $result;
+}
+
+
+# return 1 - exists, or
+# return 0 - DOES NOT exist
+sub user_exists
+{
+ my ($username) = @_;
+
+ return defined(getpwnam($username));
+}
+
+
+# Return 1 if success, 0 if failure
+sub create_user
+{
+ my ($username, $groupname) = @_;
+ my $command;
+
+ emit(sprintf("create_user(%s)\n", join(", ", @_)), "debug");
+
+ return 1 if $dry_run;
+
+ if (($username eq $PKI_USER) &&
+ ($groupname eq $PKI_GROUP)) {
+ # Attempt to create $PKI_USER with $PKI_UID
+ emit("create_user(): Adding default PKI user '$username' "
+ . "(uid=$PKI_UID) to '/etc/passwd'.\n", "debug");
+ if ($^O eq "linux") {
+ $command = "/usr/sbin/useradd "
+ . "-g $groupname "
+ . "-d /usr/share/pki "
+ . "-s /sbin/nologin "
+ . "-c 'Certificate System' "
+ . "-u $PKI_UID "
+ . "-r "
+ . $username;
+ } elsif ($^O eq "solaris") {
+ $command = "/usr/sbin/useradd "
+ . "-g $groupname "
+ . "-d /usr/share/pki "
+ . "-s /bin/false "
+ . "-c 'Certificate System' "
+ . "-u $PKI_UID "
+ . $username;
+ } else {
+ $command = "/usr/sbin/useradd "
+ . "-g $groupname "
+ . "-d /usr/share/pki "
+ . "-s '' "
+ . "-c 'Certificate System' "
+ . "-u $PKI_UID "
+ . $username;
+ }
+ } else {
+ # Attempt to create $username with random UID
+ emit("create_user(): Adding default PKI user '$username' "
+ . "(uid=random) to '/etc/passwd'.\n", "debug");
+ if ($^O eq "linux") {
+ $command = "/usr/sbin/useradd "
+ . "-g $groupname "
+ . "-d /usr/share/pki "
+ . "-s /sbin/nologin "
+ . "-c 'Certificate System' "
+ . $username;
+ } elsif ($^O eq "solaris") {
+ $command = "/usr/sbin/useradd "
+ . "-g $groupname "
+ . "-d /usr/share/pki "
+ . "-s /bin/false "
+ . "-c 'Certificate System' "
+ . $username;
+ } else {
+ $command = "/usr/sbin/useradd "
+ . "-g $groupname "
+ . "-d /usr/share/pki "
+ . "-s '' "
+ . "-c 'Certificate System' "
+ . $username;
+ }
+ }
+
+ return 0 if !run_command($command);
+ return user_exists($username);
+}
+
+
+# return 1 - exists, or
+# return 0 - DOES NOT exist
+sub group_exists
+{
+ my ($groupname) = @_;
+
+ return defined(getgrnam($groupname));
+}
+
+
+# Return 1 if success, 0 if failure
+sub create_group
+{
+ my ($groupname) = @_;
+ my $command;
+
+ emit(sprintf("create_group(%s)\n", join(", ", @_)), "debug");
+
+ return 1 if $dry_run;
+
+ if ($groupname eq $PKI_GROUP) {
+ # Attempt to create $PKI_GROUP with $PKI_GID
+ emit("Adding default PKI group '$groupname' "
+ . "(gid=$PKI_GID) to '/etc/group'.\n", "debug");
+ if ($^O eq "linux") {
+ $command = "/usr/sbin/groupadd "
+ . "-g $PKI_GID "
+ . "-r "
+ . $groupname;
+ } elsif ($^O eq "solaris") {
+ $command = "/usr/sbin/groupadd "
+ . "-g $PKI_GID "
+ . $groupname;
+ } else {
+ $command = "/usr/sbin/groupadd "
+ . "-g $PKI_GID "
+ . $groupname;
+ }
+ } else {
+ # Attempt to create $groupname with random GID
+ emit("Adding default PKI group '$groupname' "
+ . "(gid=random) to '/etc/group'.\n", "debug");
+ if ($^O eq "linux") {
+ $command = "/usr/sbin/groupadd "
+ . $groupname;
+ } elsif ($^O eq "solaris") {
+ $command = "/usr/sbin/groupadd "
+ . $groupname;
+ } else {
+ $command = "/usr/sbin/groupadd "
+ . $groupname;
+ }
+ }
+
+ return 0 if !run_command($command);
+ return group_exists($groupname);
+}
+
+
+# return 1 - disallows shell, or
+# return 0 - allows shell
+sub user_disallows_shell
+{
+ my ($username) = @_;
+
+ my $result = 0;
+ my $sans_shell = "";
+
+ if ($^O eq "linux") {
+ $sans_shell="/sbin/nologin";
+ $result = 0;
+ } elsif ($^O eq "solaris") {
+ $sans_shell="/bin/false";
+ $result = 0;
+ } else {
+ $sans_shell="";
+ return 1;
+ }
+
+ if (!user_exists($username)) {
+ return $result;
+ }
+
+ my ($name, $passwd, $uid, $gid, $quota,
+ $comment, $gcos, $dir, $shell, $expire) = getpwnam($username);
+
+ if (!$shell) {
+ $result = 1;
+ } elsif ($shell eq $sans_shell) {
+ $result = 1;
+ } else {
+ # issue a warning and continue
+ emit("WARNING: Potential security hole - user '$username' is\n"
+ . " using '$shell' instead of '$sans_shell'!\n", "warning");
+ }
+
+ return $result;
+}
+
+
+# return 1 - is a member, or
+# return 0 - is NOT a member
+sub user_is_a_member_of_group
+{
+ my ($username, $groupname) = @_;
+
+ return 0 if !user_exists($username);
+ return 0 if !group_exists($groupname);
+
+ # The members list returned by getgrname may not contain the user's primary group.
+ # This is OS dependent and is typically the case when the primary gid is a
+ # "user private group". Therefore testing the group member list is insufficient,
+ # we must also test the primary group.
+ my ($pw_name, $pw_passwd, $pw_uid, $pw_gid) = getpwnam($username);
+ if (defined $pw_gid) {
+ my $primary_groupname = getgrgid($pw_gid);
+
+ return 1 if $primary_groupname eq $groupname;
+ }
+
+ # Now get the list of users in the specified group
+ # and test to see if the specified user is in that list.
+ my ($gr_name, $gr_passwd, $gr_gid, $gr_members) = getgrnam($groupname);
+ for my $member (split(' ', $gr_members)) {
+ return 1 if $member eq $username;
+ }
+
+ return 0;
+}
+
+
+# return 1 - success, or
+# return 0 - failure
+sub add_user_as_a_member_of_group
+{
+ my ($username, $groupname) = @_;
+
+ my $command = "";
+ my $result = 0;
+
+ emit(sprintf("add_user_as_a_member_of_group(%s)\n", join(", ", @_)), "debug");
+
+ return 1 if $dry_run;
+
+ return 0 if !user_exists($username);
+ return 0 if !group_exists($groupname);
+ return 1 if user_is_a_member_of_group($username, $groupname);
+
+ # Attempt to add user to be a member of group
+ emit("Adding user '$username' to be a member of group "
+ . "'$groupname'.\n", "debug");
+ if ($^O eq "linux") {
+ $command = "/usr/sbin/usermod "
+ . "-G $groupname "
+ . $username;
+ } elsif ($^O eq "solaris") {
+ $command = "/usr/sbin/usermod "
+ . "-G $groupname "
+ . $username;
+ } else {
+ $command = "/usr/sbin/usermod "
+ . "-G $groupname "
+ . $username;
+ }
+
+ return 0 if !run_command($command);
+ return user_is_a_member_of_group($username, $groupname);
+}
+
+
+# return UID, or
+# return (-1) - user is not in password file
+sub get_UID_from_username
+{
+ my ($username) = @_;
+
+ my ($name, $passwd, $uid) = getpwnam($username);
+
+ return $uid if defined($uid);
+ return (-1);
+ }
+
+
+# Return fully-qualified domain name (FQDN) given
+# either a hostname or an IP address
+sub get_FQDN
+{
+ my ($addr) = @_;
+
+ if (!$is_IPv6) {
+ if ($addr !~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) {
+ # Retrieve FQDN via a "mnemonic" hostname
+ ($fqdn) = gethostbyname($addr);
+ } else {
+ # Retrieve FQDN via a "4-tuple" IP address
+ $fqdn = gethostbyaddr(pack('C4', $1, $2, $3, $4), 2);
+ }
+ } else {
+ # IPv6: Don't rely upon "Socket6.pm" being present!
+ $fqdn = $addr;
+ }
+
+ return($fqdn);
+}
+
+
+##############################################################
+# Generic "availability" Subroutines
+##############################################################
+
+# return 1 - URL prefix is known (success)
+# return 0 - URL prefix is unknown (failure)
+sub check_for_valid_url_prefix
+{
+ my ($url_prefix) = @_;
+
+ if (($url_prefix eq $FILE_PREFIX) ||
+ ($url_prefix eq $FTP_PREFIX) ||
+ ($url_prefix eq $HTTP_PREFIX) ||
+ ($url_prefix eq $HTTPS_PREFIX) ||
+ ($url_prefix eq $LDAP_PREFIX) ||
+ ($url_prefix eq $LDAPS_PREFIX)) {
+ return 1;
+ }
+
+ return 0;
+}
+
+# return 1 - ports are valid (success)
+# return 0 - ports have a conflict (failure)
+sub AreConnectorPortsValid
+{
+ # parse parameters
+ my ($secure_port, $unsecure_port, $agent_secure_port,
+ $ee_secure_port, $admin_secure_port, $proxy_secure_port,
+ $proxy_unsecure_port, $ajp_port) = @_;
+
+
+ if ($secure_port == -1 && $agent_secure_port == -1)
+ {
+ return 0;
+ }
+
+ if ($secure_port >= 0 && $agent_secure_port >= 0)
+ {
+ return 0;
+ }
+
+ if ($secure_port >= 0)
+ {
+ if ($secure_port == $unsecure_port)
+ {
+ return 0;
+ }
+ return 1;
+ }
+
+ if (!portsUnique($agent_secure_port,$ee_secure_port, $admin_secure_port, $proxy_secure_port,
+ $proxy_unsecure_port, $ajp_port)) {
+ return 0;
+ }
+
+ return 1;
+
+}
+
+#return 1 - if non-negative ports are uique
+#return 0 - otherwise (failure)
+sub portsUnique
+{
+ my @ports = sort @_;
+ my $last_port = -1;
+ for my $port (@ports) {
+ next if ($port < 0);
+ if ($port == $last_port) {
+ return 0;
+ }
+ $last_port = $port;
+ }
+ return 1;
+}
+
+# return 1 - port is available (success)
+# return 0 - port is unavailable; report an error (failure)
+sub IsLocalPortAvailable
+{
+ # parse parameters
+ my ($user, $port) = @_;
+
+ # On Linux/UNIX, check well-known/reserved ports
+ if (!is_Windows()) {
+ my $uid = -1;
+
+ # retrieve the UID given the username
+ $uid = get_UID_from_username($user);
+ if ($uid == -1) {
+ emit("User '$user' is NOT in the password file!\n", "error");
+ return 0;
+ }
+
+ # insure that well-known ports cannot be used by a non-root user
+ if (($port <= $MAX_WELL_KNOWN_PORT) && ($uid != $ROOTUID)) {
+ emit("User '$user' is not allowed to bind to well-known "
+ . "port $port!\n", "error");
+ return 0;
+ }
+
+ # insure that reserved ports cannot be used by a non-root user
+ if (($port <= $MAX_RESERVED_PORT) && ($uid != $ROOTUID)) {
+ emit("User '$user' is not allowed to bind to reserved "
+ . "port $port!\n", "error");
+ return 0;
+ }
+
+ # insure that the user has not specified a port greater than
+ # the number of dynamic/private ports
+ if ($port > $MAX_DYNAMIC_PORT) {
+ emit("User '$user' is not allowed to bind to a "
+ . "port greater than $MAX_DYNAMIC_PORT!\n", "error");
+ return 0;
+ }
+
+ # if the user has specified a port greater than the number
+ # of registered ports, issue a warning and continue
+ if ($port > $MAX_REGISTERED_PORT) {
+ emit("WARNING: User '$user' is binding to port $port; use of "
+ . "a dynamic/private port is discouraged!\n", "warning");
+ }
+ }
+
+ # initialize local variables
+ my $rv = 0;
+ my $status = "AVAILABLE";
+
+ # make a local TCP server socket
+ my $proto = getprotobyname('tcp');
+ socket(SERVER, PF_INET, SOCK_STREAM, $proto);
+
+ # create a local server socket address
+ my $server_address = sockaddr_in($port, INADDR_ANY);
+
+ # attempt to bind this local server socket
+ # to this local server socket address
+ bind(SERVER, $server_address) or $status = $!;
+
+ # identify the status of this attempt to bind
+ if ($status eq "AVAILABLE") {
+ # this port is inactive
+ $rv = 1;
+ } elsif ($status eq "Address already in use") {
+ emit("Unable to bind to local port $port : $status\n", "error");
+ $rv = 0;
+ } else {
+ emit("Unable to bind to local port $port : $status\n", "error");
+ $rv = 0;
+ }
+
+ # close local server socket
+ close(SERVER);
+
+ # return result
+ return $rv;
+}
+
+
+# return 2 - warn that server is unreachable (continue)
+# return 1 - server is reachable (success)
+# return 0 - server is unreachable; report an error (failure)
+sub IsServerReachable
+{
+ # parse parameters
+ my ($prefix, $host, $port) = @_;
+
+ # check the validity of the prefix
+ my $result = 0;
+
+ $result = check_for_valid_url_prefix($prefix);
+ if (!$result) {
+ emit("Specified unknown url prefix '$prefix'!\n", "error");
+ return $result;
+ }
+
+ # create a URL from the passed-in parameters
+ my $url = $prefix . $host . ":" . $port;
+
+ # initialize the state of the Server referred to by this URL
+ my $rv = 0;
+ my $status = "ACTIVE";
+
+ # retrieve the remote host IP address
+ my $iaddr = inet_aton($host) or $status = $!;
+ if ($status ne "ACTIVE") {
+ emit("Unable to contact the Server at '$url' ($status)", "error");
+ return $rv;
+ }
+
+ # create a remote server socket address
+ my $server_address = sockaddr_in($port, $iaddr);
+
+ # make a local TCP client socket
+ my $proto = getprotobyname('tcp');
+ socket(CLIENT, PF_INET, SOCK_STREAM, $proto);
+
+ # attempt to connect this local client socket
+ # to the remote server socket address
+ connect(CLIENT, $server_address) or $status = $!;
+
+ # identify the status of this connection
+ if ($status eq "ACTIVE") {
+ # this '$host:$port' is reachable
+ $rv = 1;
+ } else {
+ emit("WARNING: Unable to contact the Server at '$url' ($status)", "warning");
+ }
+
+ # close local client socket
+ close(CLIENT);
+
+ # return result
+ return $rv;
+}
+
+
+##############################################################
+# Generic "time" Subroutines
+##############################################################
+
+# no args
+# return time stamp
+sub get_time_stamp
+{
+ my ($sec, $min, $hour, $mday,
+ $mon, $year, $wday, $yday, $isdst) = localtime(time);
+
+ my $stamp = sprintf "%4d-%02d-%02d %02d:%02d:%02d",
+ $year+1900, $mon+1, $mday, $hour, $min, $sec;
+
+ return $stamp;
+}
+
+
+##############################################################
+# Generic "random" Subroutines
+##############################################################
+
+# return random number between low & high
+sub generate_random
+{
+ my ($low, $high) = @_;
+
+ my $number = 0;
+
+ if ($low >= $high || $low < 0 || $high < 0) {
+ return -1;
+ }
+
+ $number = int(rand($high -$low +1)) + $low;
+
+ return $number;
+}
+
+
+# return random string of specified length
+sub generate_random_string
+{
+ my ($length_of_randomstring) = @_;
+
+ my @chars=('a'..'z','A'..'Z','0'..'9');
+ my $random_string;
+
+ foreach (1..$length_of_randomstring) {
+ $random_string .= $chars[rand @chars];
+ }
+
+ return $random_string;
+}
+
+
+##############################################################
+# Generic "password" Subroutines
+##############################################################
+
+# return 1 - success
+# return 0 - failure; report an error
+sub password_quality_checker
+{
+ my ($password) = @_;
+ my ($i, $letter);
+
+ # Test #1: $password MUST be > 8 characters
+ if (length($password) < 8) {
+ print("\n");
+ print("Password entered is less than 8 characters. Try again.\n");
+ return 0;
+ }
+
+
+ # Test #2: $password MUST contain at least one non-alphabetic character
+ my @alphabet = ("A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
+ "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
+ "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d",
+ "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
+ "o", "p", "q", "r", "s", "t", "u", "v", "w", "x",
+ "y", "z");
+
+ my $non_alphabetic_characters = 0;
+ for ($i = 0; $i < length($password); $i++) {
+ # always reset character type
+ my $found_alphabetic_character = 0;
+
+ # extract the next character from the $password
+ my $character = substr($password, $i, 1);
+
+ # check to see if this character is "alphabetic"
+ for $letter (@alphabet) {
+ if ($character eq $letter) {
+ $found_alphabetic_character = 1;
+ last;
+ }
+ }
+
+ # keep a count of "non-alphabetic" characters
+ if ($found_alphabetic_character == 0) {
+ $non_alphabetic_characters++;
+ }
+ }
+
+ # pass Test #2 if the $password contains any "non-alphabetic" characters
+ if ($non_alphabetic_characters > 0) {
+ return 1;
+ } else {
+ print("\n");
+ print("Password entered contains 0 non-alphabetic characters. "
+ . "Try again.\n");
+ return 0;
+ }
+}
+
+
+##############################################################
+# Generic "LDAP" Subroutines
+##############################################################
+
+# hostname - LDAP server name or IP address (default: localhost)
+# port - LDAP server TCP port number (default: 389)
+# password - bind passwd (for simple authentication)
+# file - read modifications from file (default: standard input)
+# no return value
+sub LDAP_add
+{
+ my ($tokendb_hostname, $tokendb_port, $tokendb_password, $file) = @_;
+
+ my $command = "";
+
+ my $original_library_path = get_library_path();
+
+ emit(sprintf("LDAP_add(%s)\n", join(", ", @_)), "debug");
+
+ return if $dry_run;
+
+ set_library_path([$default_security_libraries,
+ $default_system_user_libraries,
+ $default_system_libraries,
+ $original_library_path]);
+
+ $command = "$default_ldapmodify_command "
+ . "-h '$tokendb_hostname' "
+ . "-p '$tokendb_port' "
+ . "-D 'cn=directory manager' "
+ . "-w '$tokendb_password' "
+ . "-a "
+ . "-f '$file'";
+
+ system($command);
+
+ set_library_path([$original_library_path]);
+
+ return;
+}
+
+
+# hostname - LDAP server name or IP address (default: localhost)
+# port - LDAP server TCP port number (default: 389)
+# password - bind passwd (for simple authentication)
+# file - read modifications from file (default: standard input)
+# no return value
+sub LDAP_modify
+{
+ my ($tokendb_hostname, $tokendb_port, $tokendb_password, $file) = @_;
+
+ my $command = "";
+
+ my $original_library_path = get_library_path();
+
+ emit(sprintf("LDAP_modify(%s)\n", join(", ", @_)), "debug");
+
+ return if $dry_run;
+
+ set_library_path([$default_security_libraries,
+ $default_system_user_libraries,
+ $default_system_libraries,
+ $original_library_path]);
+
+ $command = "$default_ldapmodify_command "
+ . "-h '$tokendb_hostname' "
+ . "-p '$tokendb_port' "
+ . "-D 'cn=directory manager' "
+ . "-w '$tokendb_password' "
+ . "-f '$file'";
+
+ system($command);
+
+ set_library_path([$original_library_path]);
+
+ return;
+}
+
+
+##############################################################
+# Generic "Security Databases" Subroutines
+##############################################################
+
+# instance path - Security databases directory (default is ~/.netscape)
+# password file - Specify the password file
+# no return value
+sub certutil_create_databases
+{
+ my ($instance_path, $pwdfile) = @_;
+
+ my $command = "";
+
+ my $original_library_path = get_library_path();
+
+ emit(sprintf("certutil_create_databases(%s)\n", join(", ", @_)), "debug");
+
+ return if $dry_run;
+
+ set_library_path([$default_security_libraries,
+ $default_system_user_libraries,
+ $default_system_libraries,
+ $original_library_path]);
+
+ if (!$pwdfile) {
+ $command = "$default_certutil_command "
+ . "-N "
+ . "-d $instance_path";
+ } else {
+ $command = "$default_certutil_command "
+ . "-N "
+ . "-d $instance_path "
+ . "-f $pwdfile";
+ }
+
+ system($command);
+
+ set_library_path([$original_library_path]);
+
+ return;
+}
+
+
+# instance path - Security databases directory (default is ~/.netscape)
+# token - Name of token in which to look for cert (default is internal,
+# use "all" to look for cert on all tokens)
+# nickname - The nickname of the cert to delete
+# no return value
+sub certutil_delete_cert
+{
+ my ($instance_path, $token, $nickname) = @_;
+
+ my $command = "";
+
+ my $original_library_path = get_library_path();
+
+ emit(sprintf("certutil_delete_cert(%s)\n", join(", ", @_)), "debug");
+
+ return if $dry_run;
+
+ set_library_path([$default_security_libraries,
+ $default_system_user_libraries,
+ $default_system_libraries,
+ $original_library_path]);
+
+ $command = "$default_certutil_command "
+ . "-D "
+ . "-d $instance_path "
+ . "-h '$token' "
+ . "-n '$nickname'";
+
+ system($command);
+
+ set_library_path([$original_library_path]);
+
+ return;
+}
+
+
+# instance path - Security databases directory (default is ~/.netscape)
+# token - Name of token in which to generate key (default is internal)
+# subject - Specify the subject name (using RFC1485)
+# password file - Specify the password file
+# no return value
+sub certutil_generate_CSR
+{
+ my ($instance_path, $token, $subject, $pwdfile) = @_;
+
+ my $command = "";
+
+ my $original_library_path = get_library_path();
+
+ emit(sprintf("certutil_generate_CSR(%s)\n", join(", ", @_)), "debug");
+
+ return if $dry_run;
+
+ set_library_path([$default_security_libraries,
+ $default_system_user_libraries,
+ $default_system_libraries,
+ $original_library_path]);
+
+ if (!$pwdfile) {
+ $command = "$default_certutil_command "
+ . "-R "
+ . "-d $instance_path "
+ . "-h '$token' "
+ . "-s '$subject' "
+ . "-a";
+ } else {
+ $command = "$default_certutil_command "
+ . "-R "
+ . "-d $instance_path "
+ . "-h '$token' "
+ . "-s '$subject' "
+ . "-a "
+ . "-f $pwdfile";
+ }
+
+ system($command);
+
+ set_library_path([$original_library_path]);
+
+ return;
+}
+
+
+# instance path - Security databases directory (default is ~/.netscape)
+# token - Name of token in which to store the certificate
+# (default is internal)
+# serial number - Cert serial number
+# validity period - Months valid (default is 3)
+# subject - Specify the subject name (using RFC1485)
+# issuer name - The nickname of the issuer cert
+# nickname - Specify the nickname of the server certificate
+# trust args - Set the certificate trust attributes:
+# p valid peer
+# P trusted peer (implies p)
+# c valid CA
+# T trusted CA to issue client certs (implies c)
+# C trusted CA to issue server certs (implies c)
+# u user cert
+# w send warning
+# g make step-up cert
+# noise file - Specify the noise file to be used
+# (to introduce randomness during key generation)
+# password file - Specify the password file
+# no return value
+sub certutil_generate_self_signed_cert
+{
+ my ($instance_path, $token, $serial_number, $validity_period,
+ $subject, $issuer_name, $nickname, $trustargs, $noise_file,
+ $pwdfile) = @_;
+
+ my $command = "";
+
+ my $original_library_path = get_library_path();
+
+ emit(sprintf("certutil_generate_self_signed_cert(%s)\n", join(", ", @_)), "debug");
+
+ return if $dry_run;
+
+ set_library_path([$default_security_libraries,
+ $default_system_user_libraries,
+ $default_system_libraries,
+ $original_library_path]);
+
+ if (!$pwdfile) {
+ $command = "$default_certutil_command "
+ . "-S "
+ . "-d $instance_path "
+ . "-h '$token' "
+ . "-m $serial_number "
+ . "-v $validity_period "
+ . "-x "
+ . "-s '$subject' "
+ . "-c '$issuer_name' "
+ . "-n '$nickname' "
+ . "-t '$trustargs' "
+ . "-z $noise_file "
+ . "> /dev/null "
+ . "2>&1";
+ } else {
+ $command = "$default_certutil_command "
+ . "-S "
+ . "-d $instance_path "
+ . "-h '$token' "
+ . "-f $pwdfile "
+ . "-m $serial_number "
+ . "-v $validity_period "
+ . "-x "
+ . "-s '$subject' "
+ . "-c '$issuer_name' "
+ . "-n '$nickname' "
+ . "-t '$trustargs' "
+ . "-z $noise_file "
+ . "> /dev/null "
+ . "2>&1";
+ }
+
+ system($command);
+
+ set_library_path([$original_library_path]);
+
+ return;
+}
+
+
+# instance path - Security databases directory (default is ~/.netscape)
+# token - Name of token in which to store the certificate
+# (default is internal)
+# nickname - Specify the nickname of the server certificate
+# trust args - Set the certificate trust attributes:
+# p valid peer
+# P trusted peer (implies p)
+# c valid CA
+# T trusted CA to issue client certs (implies c)
+# C trusted CA to issue server certs (implies c)
+# u user cert
+# w send warning
+# g make step-up cert
+# (e. g. - Server Cert 'u,u,u', CA Cert 'CT,CT,CT')
+# cert - The certificate encoded in ASCII (RFC1113)
+# no return value
+sub certutil_import_cert
+{
+ my ($instance_path, $token, $nickname, $trustargs, $cert) = @_;
+
+ my $original_library_path = get_library_path();
+
+ emit(sprintf("certutil_import_cert(%s)\n", join(", ", @_)), "debug");
+
+ return if $dry_run;
+
+ set_library_path([$default_security_libraries,
+ $default_system_user_libraries,
+ $default_system_libraries,
+ $original_library_path]);
+
+ open(F,
+ "|$default_certutil_command "
+ . "-A "
+ . "-d $instance_path "
+ . "-h '$token' "
+ . "-n '$nickname' "
+ . "-t '$trustargs' "
+ . "-a");
+ print(F $cert);
+ close(F);
+
+ set_library_path([$original_library_path]);
+
+ return;
+}
+
+
+# instance path - Security databases directory (default is ~/.netscape)
+# token - Name of token in which to look for cert (default is internal,
+# use "all" to look for cert on all tokens)
+# nickname - Pretty print named cert (list all if unspecified)
+# no return value
+sub certutil_print_cert
+{
+ my ($instance_path, $token, $nickname) = @_;
+
+ my $command = "";
+
+ my $original_library_path = get_library_path();
+
+ emit(sprintf("certutil_print_cert(%s)\n", join(", ", @_)), "debug");
+
+ return if $dry_run;
+
+ set_library_path([$default_security_libraries,
+ $default_system_user_libraries,
+ $default_system_libraries,
+ $original_library_path]);
+
+ if ($token) {
+ # Raidzilla Bug #57616 - certutil is not being consistent, nickname
+ # requires token name for no reason.
+ $command = "$default_certutil_command "
+ . "-L "
+ . "-d $instance_path "
+ . "-h '$token' "
+ . "-n '$token:$nickname'";
+ } else {
+ $command = "$default_certutil_command "
+ . "-L "
+ . "-d $instance_path "
+ . "-h '$token' "
+ . "-n '$nickname'";
+ }
+
+ system($command);
+
+ set_library_path([$original_library_path]);
+
+ return;
+}
+
+
+# no return value
+# instance path - Security databases directory (default is ~/.netscape)
+# token - Name of token in which to look for certs (default is internal,
+# use "all" to list certs on all tokens)
+sub certutil_list_certs
+{
+ my ($instance_path, $token) = @_;
+
+ my $command = "";
+
+ my $original_library_path = get_library_path();
+
+ emit(sprintf("certutil_list_certs(%s)\n", join(", ", @_)), "debug");
+
+ return if $dry_run;
+
+ set_library_path([$default_security_libraries,
+ $default_system_user_libraries,
+ $default_system_libraries,
+ $original_library_path]);
+
+ $command = "$default_certutil_command "
+ . "-L "
+ . "-d $instance_path "
+ . "-h '$token'";
+
+ system($command);
+
+ set_library_path([$original_library_path]);
+
+ return;
+}
+
+
+# instance path - Security databases directory (default is ~/.netscape)
+# token - Add the named token to the module database
+# library - The name of the file (.so or .dll) containing the
+# implementation of PKCS #11
+# no return value
+sub modutil_add_token
+{
+ my ($instance_path, $token, $library) = @_;
+
+ my $command = "";
+
+ my $original_library_path = get_library_path();
+
+ emit(sprintf("modutil_add_token(%s)\n", join(", ", @_)), "debug");
+
+ return if $dry_run;
+
+ set_library_path([$default_security_libraries,
+ $default_system_user_libraries,
+ $default_system_libraries,
+ $original_library_path]);
+
+ $command = "$default_modutil_command "
+ . "-force "
+ . "-dbdir $instance_path "
+ . "-add $token "
+ . "-libfile $library "
+ . "-nocertdb";
+
+ system("$command > /dev/null 2>&1");
+
+ set_library_path([$original_library_path]);
+
+ return;
+}
+
+
+##############################################################
+# Generic "logging" Subroutines
+##############################################################
+
+# Return 1 if success, 0 if failure
+sub open_logfile
+{
+ my ($path, $permissions, $owner, $group) = @_;
+
+
+ $logfd = FileHandle->new("> $path");
+
+ if (defined($logfd)) {
+ $logfile_path = $path;
+ } else {
+ return 0;
+ }
+
+ if (defined($permissions)) {
+ return 0 if !set_permissions($logfile_path, $permissions);
+ }
+
+ if (defined($owner) && defined($group)) {
+ return 0 if !set_owner_group($logfile_path, $owner, $group);
+ }
+
+ return 1;
+}
+
+# no return value
+sub get_logfile_path
+{
+ return $logfile_path;
+}
+
+# no return value
+sub close_logfile
+{
+ if (defined($logfd)) {
+ $logfd->close();
+ }
+
+ $logfd = undef;
+ return;
+}
+
+
+##############################################################
+# Generic "response" Subroutines
+##############################################################
+
+# return answer
+sub prompt
+{
+ my ($promptStr) = @_;
+
+ my $answer = "";
+
+ print(STDOUT "$promptStr ");
+
+ $| = 1;
+ $answer = <STDIN>;
+
+ chomp $answer;
+
+ print(STDOUT "\n");
+
+ return $answer;
+}
+
+
+##############################################################
+# Generic "reply" Subroutines
+##############################################################
+
+# no return value
+sub printFile
+{
+ my ($fileHandle) = @_;
+
+ while (<$fileHandle>) {
+ my $line = $_;
+ chomp($line);
+ print(STDOUT "$line\n");
+ }
+
+ return;
+}
+
+
+# no return value
+sub emit
+{
+ my ($string, $type) = @_;
+
+ my $force_emit = 0;
+ my $log_entry = "";
+
+ $type = "debug" if !defined($type);
+
+ if ($type eq "error" || $type eq "warning" || $type eq "info") {
+ $force_emit = 1;
+ }
+
+ return if !$string;
+
+ chomp($string);
+ my $stamp = get_time_stamp();
+
+ if ($verbose || $force_emit) {
+ # print to stdout
+ if ($type ne "log") {
+ print(STDERR "[$type] $string\n");
+ }
+ }
+
+ # If a log file exists, write all types
+ # ("debug", "error", "info", or "log")
+ # to this specified log file
+ if (defined($logfd)) {
+ $log_entry = "[$stamp] [$type] $string\n";
+ $logfd->print($log_entry);
+ }
+
+ return;
+}
+
+
+##############################################################
+# Generic "validity" Subroutines
+##############################################################
+
+# return 1 - valid, or
+# return 0 - invalid
+sub is_path_valid
+{
+ my ($path) = @_;
+
+ my @pathname = split("/", $path);
+
+ shift @pathname unless $pathname[0];
+
+ my $valid = 0;
+ my $split_path;
+
+ foreach $split_path (@pathname) {
+ chomp($split_path);
+
+ if (!($split_path !~ /^[-_.a-zA-Z0-9\[\]\@]+$/)) {
+ $valid = 1;
+ } else {
+ $valid = 0;
+ last;
+ }
+ }
+
+ return $valid;
+}
+
+
+# return 1 - valid, or
+# return 0 - invalid
+sub is_name_valid
+{
+ my ($name) = @_;
+
+ my $result = 0;
+
+ if (!($name !~ /^[-_.a-zA-Z0-9]+$/)) {
+ $result = 1;
+ }
+
+ return $result;
+}
+
+
+##############################################################
+# Generic "entity" Subroutines
+##############################################################
+
+# return type of entity
+sub entity_type
+{
+ my ($entity) = @_;
+
+ if (-b $entity) {
+ return "block special file";
+ } elsif (-c $entity) {
+ return "character special file";
+ } elsif (-d $entity) {
+ return "directory";
+ } elsif (-f $entity) {
+ if (-B $entity) {
+ return "binary file";
+ } elsif (-T $entity) {
+ return "text file";
+ } else {
+ return "plain file";
+ }
+ } elsif (-l $entity) {
+ return "symbolic link";
+ } elsif (-p $entity) {
+ return "named pipe";
+ } elsif (-S $entity) {
+ return "socket";
+ }
+
+ return "UNKNOWN";
+}
+
+
+# return 1 - exists, or
+# return 0 - DOES NOT exist
+sub entity_exists
+{
+ my ($entity) = @_;
+
+ my $result = 0;
+
+ if (-e $entity) {
+ my $type = entity_type($entity);
+ $result = 1;
+ }
+
+ return $result;
+}
+
+
+##############################################################
+# Generic "file" Subroutines
+##############################################################
+
+# return 1 - exists, or
+# return 0 - DOES NOT exist
+sub file_exists
+{
+ my ($file) = @_;
+
+ my $result = 0;
+
+ if (-f $file) {
+ $result = 1;
+ } elsif (-e $file) {
+ my $type = entity_type($file);
+ emit("File $file DOES NOT exist because $file is a $type!\n",
+ "error");
+ $result = 0;
+ }
+
+
+ return $result;
+}
+
+
+# return 1 - empty, or
+# return 0 - NOT empty
+sub is_file_empty
+{
+ my ($file) = @_;
+
+ my $result = 0;
+
+ if (-z $file) {
+ $result = 1;
+ }
+
+ return $result;
+}
+
+
+# Return 1 if success, 0 if failure
+sub create_empty_file
+{
+ my ($path, $permissions, $owner, $group, $uninstall_action) = @_;
+
+ $uninstall_action = 'remove' unless defined($uninstall_action);
+
+ emit(sprintf("create_empty_file(%s, %s, %s, %s, %s)\n",
+ $path,
+ defined($permissions) ? sprintf("%o", $permissions) : "",
+ $owner, $group, $uninstall_action), "debug");
+
+ add_install_info($path, 'file', $uninstall_action);
+
+ if (!$dry_run) {
+ if (!open(FILE, "> $path")) {
+ emit("Cannot create empty file \"$path\" ($!)", 'error');
+ return 0;
+ }
+ close(FILE);
+ }
+
+ if (defined($permissions)) {
+ return 0 if !set_permissions($path, $permissions);
+ }
+
+ if (defined($owner) && defined($group)) {
+ return 0 if !set_owner_group($path, $owner, $group);
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub create_file
+{
+ my ($path, $contents, $permissions, $owner, $group, $uninstall_action) = @_;
+
+ $uninstall_action = 'remove' unless defined($uninstall_action);
+
+ emit(sprintf("create_file(%s, %s, %s, %s, %s)\n",
+ $path,
+ defined($permissions) ? sprintf("%o", $permissions) : "",
+ $owner, $group, $uninstall_action), "debug");
+
+ add_install_info($path, 'file', $uninstall_action);
+
+ if (!$dry_run) {
+ if (!open(FILE, "> $path")) {
+ emit("could not create file \"$path\" ($!)\n", 'error');
+ return 0;
+ }
+ print(FILE $contents);
+ close(FILE);
+ }
+
+ if (defined($permissions)) {
+ return 0 if !set_permissions($path, $permissions);
+ }
+
+ if (defined($owner) && defined($group)) {
+ return 0 if !set_owner_group($path, $owner, $group);
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub copy_file
+{
+ my ($src_path, $dst_path, $permissions, $owner, $group, $uninstall_action) = @_;
+
+ $uninstall_action = 'remove' unless defined($uninstall_action);
+
+ emit(sprintf("copy_file(%s, %s, %s, %s, %s, %s)\n",
+ $src_path, $dst_path,
+ defined($permissions) ? sprintf("%o", $permissions) : "",
+ $owner, $group, $uninstall_action), "debug");
+
+ add_install_info($dst_path, 'file', $uninstall_action);
+
+ if (!is_path_valid($src_path)) {
+ emit("copy_file(): illegal src path => \"$src_path\".\n",
+ "error");
+ remove_install_info($dst_path);
+ return 0;
+ }
+
+ if (!is_path_valid($dst_path)) {
+ emit("copy_file(): illegal dst path => \"$dst_path\".\n",
+ "error");
+ remove_install_info($dst_path);
+ return 0;
+ }
+
+ if (!$dry_run) {
+ if (!copy($src_path, $dst_path)) {
+ emit("copy_file(): \"$src_path\" => \"$dst_path\" ($!)\n", "error");
+ remove_install_info($dst_path);
+ return 0;
+ }
+ }
+
+ if (defined($permissions)) {
+ return 0 if !set_permissions($dst_path, $permissions);
+ }
+
+ if (defined($owner) && defined($group)) {
+ return 0 if !set_owner_group($dst_path, $owner, $group);
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub remove_file
+{
+ my ($path) = @_;
+ my $result = 0;
+
+ emit(sprintf("remove_file(%s)\n", join(", ", @_)), "debug");
+
+ add_install_info($path, 'file', 'remove', 'remove');
+
+ return 1 if $dry_run;
+
+ if (!unlink($path)) {
+ emit("remove_file(): failed to remove file \"$path\" ($!)\n", "error");
+ return 0;
+ }
+
+ return 1;
+ }
+
+# set_permissions(path_glob, permissions)
+# Return 1 if success, 0 if failure
+sub set_permissions
+{
+ my ($path_glob, $permissions) = @_;
+ my (@paths, $errstr, $result, $count);
+
+ $errstr = undef;
+ $count = 0;
+ $result = 1;
+
+ emit(sprintf("set_permissions(%s, %s)\n",
+ $path_glob,
+ defined($permissions) ? sprintf("%o", $permissions) : ""), "debug");
+
+ return 1 if $dry_run;
+
+ @paths = glob($path_glob);
+
+ if (($count = chmod($permissions, @paths)) != @paths) {
+ $errstr = "$!";
+ $result = 0;
+ emit(sprintf("failed to set permission (%o) on \"%s\" => (%s), %d out of %d failed, \"%s\"\n",
+ $permissions, $path_glob, "@paths", @paths - $count, @paths+0, $errstr), 'error');
+ }
+ return $result;
+ }
+
+# set_owner_group(path_glob, owner, group)
+# Return 1 if success, 0 if failure
+sub set_owner_group
+{
+ my ($path_glob, $owner, $group) = @_;
+ my (@paths, $errstr, $result, $count);
+ my ($uid, $gid);
+
+ $errstr = undef;
+ $count = 0;
+ $result = 1;
+
+ emit(sprintf("set_owner_group(%s)\n", join(", ", @_)), "debug");
+
+ return 1 if $dry_run;
+
+ $uid = getpwnam($owner);
+ $gid = getgrnam($group);
+ @paths = glob($path_glob);
+
+ if (($count = chown($uid, $gid, @paths)) != @paths) {
+ $errstr = "$!";
+ $result = 0;
+ emit(sprintf("failed to set ownership (%s) on \"%s\" => (%s), %d out of %d failed, \"%s\"\n",
+ "${owner}:${group}", $path_glob, "@paths", @paths - $count, @paths+0, $errstr), 'error');
+ }
+ return $result;
+}
+
+# set_file_props(path_glob, permissions, owner, group)
+# Return 1 if success, 0 if failure
+sub set_file_props
+{
+ my ($path_glob, $permissions, $owner, $group) = @_;
+ my (@paths, $tmp_result, $result);
+
+ $result = 1;
+
+ emit(sprintf("set_file_props(%s %s %s %s)\n",
+ $path_glob,
+ defined($permissions) ? sprintf("%o", $permissions) : "",
+ $owner, $group), "debug");
+
+ return 1 if $dry_run;
+
+ $tmp_result = set_permissions($path_glob, $permissions);
+ $result = 0 if !$tmp_result;
+
+ $tmp_result = set_owner_group($path_glob, $owner, $group);
+ $result = 0 if !$tmp_result;
+
+ return $result;
+ }
+
+
+
+##############################################################
+# Generic "directory" Subroutines
+##############################################################
+
+# Callback for walk_dir(), see walk_dir() for documentation
+sub walk_callback {
+ my ($dir, $basename, $is_dir, $prune, $opts) = @_;
+
+ if ($is_dir) {
+ my ($include_dirs, $mark_dir, $add_to_list, $regexp, $regexps);
+
+ # Don't descend into directories unless recursive.
+ $$prune = ! $opts->{'recursive'};
+
+ # If include filter is provided, basename must match
+ # at least one regexp in filter list.
+ if (defined($regexps = $opts->{'dir_includes'})) {
+ $add_to_list = 0;
+ for $regexp (@$regexps) {
+ if ($basename =~ /$regexp/) {
+ $add_to_list = 1;
+ last;
+ }
+ }
+ } else {
+ $add_to_list = 1;
+ }
+
+ if (!$add_to_list) {
+ $$prune = 1;
+ return;
+ }
+
+ # If exclude filter is provided, basename cannot match
+ # any regexp in filter list.
+ if (defined($regexps = $opts->{'dir_excludes'})) {
+ for $regexp (@$regexps) {
+ if ($basename =~ /$regexp/) {
+ $add_to_list = 0;
+ last;
+ }
+ }
+ }
+
+ if (!$add_to_list) {
+ $$prune = 1;
+ return;
+ }
+
+ # Are we collecting directories?
+ $include_dirs = $opts->{'include_dirs'} // 0;
+ return if ! $include_dirs;
+
+ if ($opts->{'mark_dir'}) {
+ push(@{$opts->{'file_list'}}, "${dir}/${basename}/");
+ } else {
+ push(@{$opts->{'file_list'}}, "${dir}/${basename}");
+ }
+ }
+ else {
+ my ($include_files, $add_to_list, $regexp, $regexps);
+
+ # If include filter is provided, basename must match
+ # at least one regexp in filter list.
+ if (defined($regexps = $opts->{'file_includes'})) {
+ $add_to_list = 0;
+ for $regexp (@$regexps) {
+ if ($basename =~ /$regexp/) {
+ $add_to_list = 1;
+ last;
+ }
+ }
+ } else {
+ $add_to_list = 1;
+ }
+
+ return if !$add_to_list;
+
+ # If exclude filter is provided, basename cannot match
+ # any regexp in filter list.
+ if (defined($regexps = $opts->{'file_excludes'})) {
+ for $regexp (@$regexps) {
+ if ($basename =~ /$regexp/) {
+ $add_to_list = 0;
+ last;
+ }
+ }
+ }
+
+ return if !$add_to_list;
+
+ # Are we collecting files?
+ $include_files = $opts->{'include_files'} // 0;
+ return if ! $include_files;
+
+ push(@{$opts->{'file_list'}}, "${dir}/${basename}");
+ }
+}
+
+# Walk directory structure invoking a callback on each
+# item found. Optionally prune traversal.
+#
+# walk_dir($dir, $callback, $prune, $user_data)
+#
+# dir Path of directory to examine.
+# callback Pointer to callback function.
+# prune Pointer to boolean variable.
+# Callback can set to avoid descending into a directory.
+# Ignored for non-directory callback invocations.
+# opts Hash table of key/value pairs which controls execution and
+# can be used to pass user values to the walk callback.
+# See get_directory_files() for definitions.
+#
+# The signature of the callback is:
+#
+# callback($dir, $basename, $is_dir, $prune, $user_data)
+#
+# dir Current directory path.
+# basename Entry in directory.
+# is_dir Boolean, true if basename is a directory
+# prune Pointer to boolean variable.
+# Callback can set to avoid descending into a directory.
+# Ignored for non-directory callback invocations.
+# opts Hash table of key/value pairs which controls execution and
+# can be used to pass user values to the walk callback.
+# See get_directory_files() for definitions.
+#
+sub walk_dir {
+ my ($dir, $callback, $prune, $opts) = @_;
+ my ($basename);
+
+ # Get the list of files in the current directory.
+ opendir(DIR, $dir) || (warn "Can't open $dir: $!\n", return);
+ my (@entries) = sort readdir(DIR);
+ closedir(DIR);
+
+ foreach $basename (@entries) {
+ next if $basename eq '.';
+ next if $basename eq '..';
+ $$prune = 0;
+
+ my $path = "${dir}/${basename}";
+ if ((-d $path) &&
+ ((! $opts->{'preserve_links'}) || (! -l $path))) { # yes it is a directory
+ &$callback($dir, $basename, 1, $prune, $opts);
+ if (!$$prune) {
+ walk_dir($path, $callback, $prune, $opts);
+ }
+ }
+ else { # not a directory
+ &$callback($dir, $basename, 0, $prune, $opts);
+ last if $$prune;
+ }
+ }
+}
+
+# Given a directory path return a sorted array of it's contents.
+# The opts parameter is a hash of key/value pairs which controls
+# execution and can be used to pass user values to the walk callback.
+#
+# The options are:
+#
+# strip_dir (default = false)
+# If true strip the leading $dir from returned paths,
+# otherwise preserve $dir in each returned path.
+# recursive (default = true)
+# If true then recusively descend into each directory,
+# otherwise just examine the starting directory
+# preserve_links (default = true)
+# If true symbolic links are preserved.
+# If false symbolic links are traversed.
+# include_dirs (default = false)
+# If true include directories in the returned array,
+# otherwise directories are omitted.
+# include_files (default = true)
+# If true include files in the returned array,
+# otherwise files are omitted.
+# mark_dir (default = false)
+# If true paths which are directories (include_dirs must be true)
+# are indicated by a trailing slash, otherwise the basename of
+# the directory is left bare.
+#
+# Filtering
+#
+# You may specify a set of include/exclude filters on both directories and
+# files. An entry will be added to the returned list if it's in the include
+# list and not in the exclude list. If either the include or exclude list
+# is undefined it has no effect. Each filter is an array of regular
+# expressions. The basename (directory entry) is tested against the regular
+# expression. For the include filter the basename must match at least one
+# of the regular expressions. For the exclude filter if the basename
+# matches any of the regular expressions it will be excluded.
+#
+# In addition if the traversal is recursive and a directory is excluded via
+# filtering then that directory is not descended into during the recursive
+# traversal.
+#
+# dir_includes (default = undef)
+# Array of regular expressions. If defined a directory must match at
+# least one regular expression in the array to be included.
+# dir_excludes (default = undef)
+# Array of regular expressions. If defined a directory will be excluded
+# if it matches any regular expression in the array.
+# file_includes (default = undef)
+# Array of regular expressions. If defined a file must match at
+# least one regular expression in the array to be included.
+# file_excludes (default = undef)
+# Array of regular expressions. If defined a file will be excluded
+# if it matches any regular expression in the array.
+#
+sub get_directory_files
+{
+ my ($dir, $opts) = @_;
+ my ($strip_dir, $mark_dir, $recursive, $preserve_links, $include_dirs, $include_files);
+ my ($dir_includes, $dir_excludes, $file_includes, $file_excludes);
+ my ($files, $prune, $pat);
+
+ $strip_dir = $opts->{'strip_dir'} // 0;
+ $mark_dir = $opts->{'mark_dir'} // 0;
+ $recursive = $opts->{'recursive'} // 1;
+ $preserve_links = $opts->{'preserve_links'} // 1;
+ $include_dirs = $opts->{'include_dirs'} // 0;
+ $include_files = $opts->{'include_files'} // 1;
+ $dir_includes = $opts->{'dir_includes'} // undef;
+ $dir_excludes = $opts->{'dir_excludes'} // undef;
+ $file_includes = $opts->{'file_includes'} // undef;
+ $file_excludes = $opts->{'file_excludes'} // undef;
+
+ $files = [];
+ $prune = 0;
+
+ walk_dir($dir, \&walk_callback, \$prune,
+ {'file_list' => $files,
+ 'mark_dir' => $mark_dir,
+ 'recursive' => $recursive,
+ 'preserve_links' => $preserve_links,
+ 'include_dirs' => $include_dirs,
+ 'include_files' => $include_files,
+ 'dir_includes' => $dir_includes,
+ 'dir_excludes' => $dir_excludes,
+ 'file_includes' => $file_includes,
+ 'file_excludes' => $file_excludes,
+ });
+
+ if ($strip_dir) {
+ $pat = "^${dir}/";
+ map {s/$pat//; $_} @$files;
+ }
+
+ return $files;
+}
+
+# Normalize paths such that:
+# Multiple slashes are collapsed into one slash
+# Trailing slash is stripped.
+# Strip "." path components.
+# Strip previous path component for ".."
+# Returns normalized path.
+sub normalize_path
+{
+ my ($path) = @_;
+ my (@src_components, @dst_components, $component, $leading_slash, $new_path);
+
+ $leading_slash = $path =~ m!^/! ? "/" : "";
+
+ @src_components = split("/", $path);
+
+ foreach $component (@src_components) {
+ next if !$component;
+ next if $component eq ".";
+ if ($component eq "..") {
+ die "no directory component to pop \"..\" for in \"$path\"" if !@dst_components;
+ pop @dst_components;
+ next;
+ }
+ push @dst_components, $component;
+ }
+
+ $new_path = join("/", @dst_components);
+
+ return $leading_slash . $new_path;
+}
+
+# return 1 - exists, or
+# return 0 - DOES NOT exist
+sub directory_exists
+{
+ my ($dir) = @_;
+
+ my $result = 0;
+
+ if (-d $dir) {
+ $result = 1;
+ } elsif (-e $dir) {
+ my $type = entity_type($dir);
+ emit("Directory $dir DOES NOT exist because $dir is a $type!\n",
+ "error");
+ $result = 0;
+ }
+
+ return $result;
+}
+
+
+# return 1 - empty, or
+# return 0 - NOT empty
+sub is_directory_empty
+{
+ my ($dir) = @_;
+
+ my $empty = 1;
+ my $entity = "";
+
+ if (!directory_exists($dir)) {
+ return 1;
+ }
+
+ opendir(DIR, $dir);
+ while (defined($entity = readdir(DIR)) && ($empty == 1)) {
+ if ($entity ne "." && $entity ne "..") {
+ # NOTE: This is not necessarily an error!
+ #
+ # my $type = entity_type("$dir/$entity");
+ # emit(" Found $type $entity in directory $dir.\n",
+ # "debug");
+
+ $empty = 0;
+ }
+ }
+ closedir(DIR);
+
+ return $empty;
+}
+
+
+# Return 1 if success, 0 if failure
+sub create_directory
+{
+ my ($dir, $permissions, $owner, $group, $uninstall_action) = @_;
+ my $result = 1;
+ my $errors;
+
+ $uninstall_action = 'remove' unless defined($uninstall_action);
+
+ emit(sprintf("create_directory(%s, %s, %s, %s, %s)\n",
+ $dir,
+ defined($permissions) ? sprintf("%o", $permissions) : "",
+ $owner, $group, $uninstall_action), "debug");
+
+ add_install_info($dir, 'dir', $uninstall_action);
+
+ return 1 if $dry_run;
+
+ if (!directory_exists($dir)) {
+ make_path($dir, {error => \$errors});
+ if (@$errors) {
+ my ($error, $path, $errstr);
+ $result = 0;
+ for $error (@$errors) {
+ ($path, $errstr) = %$error;
+ if ($path eq '') {
+ emit("create_directory(): dir=\"$dir\" \"$errstr\"\n", "error");
+}
+ else {
+ remove_install_info($path);
+ emit("create_directory(): dir=\"$dir\" path=\"$path\" \"$errstr\"\n", "error");
+ }
+ }
+ }
+ }
+
+ if ($result) {
+ if (defined($permissions)) {
+ return 0 if !set_permissions($dir, $permissions);
+ }
+
+ if (defined($owner) && defined($group)) {
+ return 0 if !set_owner_group($dir, $owner, $group);
+ }
+ }
+
+ return $result;
+}
+
+# Return 1 if success, 0 if failure
+sub copy_directory
+{
+ my ($src_dir_path, $dst_dir_path,
+ $dir_permissions, $file_permissions,
+ $owner, $group, $uninstall_action) = @_;
+ my($result);
+ my ($files, $sub_dirs, $path, $src_path, $dst_path);
+
+ $uninstall_action = 'remove' unless defined($uninstall_action);
+ $result = 1;
+
+ $src_dir_path = normalize_path($src_dir_path);
+ $dst_dir_path = normalize_path($dst_dir_path);
+
+ emit(sprintf("copy_directory(%s, %s, %s, %s, %s, %s, %s)\n",
+ $src_dir_path, $dst_dir_path,
+ defined($dir_permissions) ? sprintf("%o", $dir_permissions) : "",
+ defined($dir_permissions) ? sprintf("%o", $dir_permissions) : "",
+ $owner, $group, $uninstall_action), "debug");
+
+ if (!is_path_valid($src_dir_path)) {
+ emit("copy_directory(): illegal src path => $src_dir_path.\n",
+ "error");
+ return 0;
+ }
+
+ if (!is_path_valid($dst_dir_path)) {
+ emit("copy_directory(): illegal dst path ($dst_dir_path)\n", "error");
+ return 0;
+ }
+
+ if (!directory_exists($src_dir_path)) {
+ # Take the case where this directory does not exist
+ # Just return true
+ emit("copy_directory(): non-existent src path ($src_dir_path)\n", "error");
+ return 1;
+ }
+
+ # Get list of directories under the src dir
+ $sub_dirs = get_directory_files($src_dir_path,
+ {'strip_dir' => 1, 'include_dirs' => 1, 'include_files' => 0});
+
+ # Get list of files under the src dir
+ $files = get_directory_files($src_dir_path,
+ {'strip_dir' => 1, 'include_dirs' => 0, 'include_files' => 1});
+
+ # Assure each destination directory exists
+ return 0 if !create_directory($dst_dir_path,
+ $dir_permissions, $owner, $group, $uninstall_action);
+ for $path (@$sub_dirs) {
+ $dst_path = "${dst_dir_path}/${path}";
+ return 0 if !create_directory($dst_path, $dir_permissions,
+ $owner, $group, $uninstall_action);
+ }
+
+ # Copy each file
+ for $path (@$files) {
+ $src_path = "${src_dir_path}/${path}";
+ $dst_path = "${dst_dir_path}/${path}";
+
+ # Emulate cp's behavior with respect to symbolic links,
+ # symbolic links are NOT followed when copying recursively.
+ # During recursive copies symbolic links are recreated.
+ if (-l $src_path) { # src is a symbolic link
+ if (!copy_symlink($src_path, $dst_path,
+ $owner, $group, $uninstall_action)) {
+ $result = 0;
+ }
+ } else { # src is not a symbolic link
+ if (!copy_file($src_path, $dst_path,
+ $file_permissions, $owner, $group, $uninstall_action)) {
+ $result = 0;
+ }
+ }
+ }
+
+ if (!$result) {
+ emit("copy_directory(): failed $src_dir_path => $dst_dir_path.\n",
+ "error");
+ }
+
+ return $result;
+}
+
+
+# Removes given directory. By default only the directory is removed and
+# only if it is empty. To remove the directory and all of it's contents
+# you must provide the $remove_contents parameter and set it to true,
+# it defaults to false.
+#
+# Return 1 if success, 0 if failure
+sub remove_directory
+{
+ my($dir, $remove_contents) = @_;
+ my($errors, $result);
+
+ emit(sprintf("remove_directory(%s)\n", join(", ", @_)), "debug");
+
+ $remove_contents = 0 unless defined($remove_contents);
+ $result = 1;
+
+ add_install_info($dir, 'dir', 'remove', 'remove');
+
+ return 1 if $dry_run;
+
+ if (!is_path_valid($dir)) {
+ emit("remove_directory(): specified invalid directory $dir.\n",
+ "error");
+ return 0;
+ }
+
+ if ($dir eq "/") {
+ emit("remove_directory(): don't even think about removing root!.\n",
+ "error");
+ return 0;
+ }
+
+ if (!directory_exists($dir)) {
+ return 1;
+ }
+
+ if ($remove_contents) {
+ remove_tree($dir, {error => \$errors});
+ if (@$errors) {
+ my($error, $path, $errstr);
+ $result = 0;
+ for $error (@$errors) {
+ ($path, $errstr) = %$error;
+ if ($path eq '') {
+ emit("remove_directory(): tree=\"$dir\" ($errstr)\n", "error");
+ }
+ else {
+ emit("remove_directory(): tree=\"$dir\" path=\"$path\" ($errstr)\n", "error");
+ }
+ }
+ }
+ } else {
+ if (!rmdir($dir)) {
+ $result = 0;
+ emit("remove_directory(): dir=\"$dir\" ($!) \n", "error");
+ }
+ }
+
+ return $result;
+}
+
+
+# Return 1 if success, 0 if failure
+sub set_owner_group_on_directory_contents
+{
+ my ($dir, $owner, $group, $recursive) = @_;
+ my ($result, $paths, $path);
+
+ $recursive = $recursive // 1;
+ $result = 1;
+
+ emit(sprintf("set_owner_group_on_directory_contents(%s)\n", join(", ", @_)), "debug");
+
+ return 1 if $dry_run;
+
+ if (!$dir || !directory_exists($dir)) {
+ emit("set_owner_group_on_directory_contents(): invalid directory specified.\n",
+ "error");
+ return 0;
+ }
+
+ if (!$owner || !$group) {
+ emit("set_owner_group_on_directory_contents(): directory $dir needs a user and group!\n",
+ "error");
+ return 0;
+ }
+
+ $paths = get_directory_files($dir, {'recursive' => $recursive,
+ 'include_dirs' => 1});
+
+ for $path (@$paths) {
+ $result = 0 if !set_owner_group($path, $owner, $group);
+ }
+
+ return $result;
+}
+
+
+##############################################################
+# Generic "symbolic link" Subroutines
+##############################################################
+
+# return 1 - exists, or
+# return 0 - DOES NOT exist
+sub symlink_exists
+{
+ my ($symlink) = @_;
+
+ my $result = 0;
+
+ if (-l $symlink) {
+ $result = 1;
+ } elsif (-e $symlink) {
+ my $type = entity_type($symlink);
+ emit("Symbolic link $symlink DOES NOT exist because $symlink "
+ . "is a $type!\n",
+ "error");
+ $result = 0;
+ }
+
+
+ return $result;
+}
+
+
+# Return 1 if success, 0 if failure
+sub create_symlink
+{
+ my ($symlink, $dst_path, $owner, $group, $uninstall_action) = @_;
+
+ $uninstall_action = 'remove' unless defined($uninstall_action);
+
+ emit(sprintf("create_symlink(%s)\n", join(", ", @_)), "debug");
+
+ add_install_info($symlink, 'symlink', $uninstall_action);
+
+ return 1 if $dry_run;
+
+ if (symlink_exists($symlink)) {
+ # delete symbolic link so that we can recreate link for upgrades
+ if (unlink($symlink) != 1) {
+ emit("create_symlink(): could not remove existing link \"$symlink\"\n", 'error');
+ remove_install_info($symlink);
+ return 0;
+ }
+ }
+
+ if (!is_path_valid($symlink)) {
+ emit("create_symlink(): invalid path \"$symlink\"\n", "error");
+ remove_install_info($symlink);
+ return 0;
+ }
+
+ if (!is_path_valid($dst_path) || !entity_exists($dst_path)) {
+ emit("create_symlink(): illegal dst path \"$dst_path\"\n", "error");
+ remove_install_info($symlink);
+ return 0;
+ }
+
+ if (!symlink($dst_path, $symlink)) {
+ emit("create_symlink(): failed \"$symlink\" => \"$dst_path\" ($!)\n", "error");
+ remove_install_info($symlink);
+ return 0;
+ }
+
+ if (defined($owner) && defined($group)) {
+ # The Perl Lchown package implements lchown, but it's not currently available
+ # as an RPM so use a system command instead. :-(
+ return 0 if !set_owner_group_on_symlink($symlink, $owner, $group);
+ }
+ return 1;
+}
+
+# Return 1 if success, 0 if failure
+sub copy_symlink
+{
+ my ($src_path, $dst_path, $owner, $group, $uninstall_action) = @_;
+ my ($target);
+
+ $uninstall_action = 'remove' unless defined($uninstall_action);
+
+ emit(sprintf("copy_symlink(%s)\n", join(", ", @_)), "debug");
+
+ add_install_info($dst_path, 'symlink', $uninstall_action);
+
+ if (!is_path_valid($src_path)) {
+ emit("copy_symlink(): illegal src path => \"$src_path\".\n",
+ "error");
+ remove_install_info($dst_path);
+ return 0;
+ }
+
+ if (!is_path_valid($dst_path)) {
+ emit("copy_symlink(): illegal dst path => \"$dst_path\".\n",
+ "error");
+ remove_install_info($dst_path);
+ return 0;
+ }
+
+ if (! -l $src_path) {
+ emit("copy_symlink(): $src_path is not a symbolic link\n");
+ return 0;
+ }
+
+ return 1 if $dry_run;
+
+ $target = readlink($src_path);
+
+ if (!symlink($target, $dst_path)) {
+ emit("could not symbolically link $target dst_path", "error");
+ remove_install_info($dst_path);
+ return 0;
+ }
+
+ if (defined($owner) && defined($group)) {
+ return 0 if !set_owner_group_on_symlink($dst_path, $owner, $group);
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub remove_symlink
+{
+ my ($symlink) = @_;
+ my $result = 0;
+
+ emit(sprintf("remove_symlink(%s)\n", join(", ", @_)), "debug");
+
+ add_install_info($symlink, 'symlink', 'remove', 'remove');
+
+ return 1 if $dry_run;
+
+ if (!$symlink) {
+ # symlink is NULL
+ return 1;
+ }
+
+ if (!symlink_exists($symlink)) {
+ return 1;
+ }
+
+ if (unlink($symlink) != 1) {
+ emit("remove_symlink(): failed \"$symlink\" ($!)\n", "error");
+ return 0;
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub set_owner_group_on_symlink
+{
+ my ($symlink, $owner, $group) = @_;
+
+ emit(sprintf("set_owner_group_on_symlink(%s)\n", join(", ", @_)), "debug");
+
+ return 1 if $dry_run;
+
+ if (!$symlink || !symlink_exists($symlink)) {
+ emit("set_owner_group_on_symlink(): invalid symbolic link specified \"$symlink\"\n",
+ "error");
+ return 1;
+ }
+
+ if (!$owner || !$group) {
+ emit("set_owner_group_on_symlink(): symbolic link \"$symlink\" needs a user and group!\n",
+ "error");
+ return 0;
+ }
+
+ # The Perl Lchown package implements lchown, but it's not currently available
+ # as an RPM so use a system command instead. :-(
+ return run_command("chown --no-dereference ${owner}:${group} $symlink");
+}
+
+
+##############################################################
+# Generic "chkconfig" Subroutines (Linux ONLY)
+##############################################################
+
+if ($^O eq "linux") {
+ # Return 1 if success, 0 if failure
+ sub register_pki_instance_with_chkconfig
+ {
+ my ($pki_instance_name) = @_;
+ my ($command, $exit_status, $result);
+
+ $result = 1;
+ $command = "/sbin/chkconfig --add $pki_instance_name";
+ if (run_command($command)) {
+ emit("Registered '$pki_instance_name' with '/sbin/chkconfig'.\n");
+ } else {
+ $result = 0;
+ emit("Failed to register '$pki_instance_name' with '/sbin/chkconfig'.\n", 'error');
+ }
+ return $result;
+ }
+
+ # Return 1 if success, 0 if failure
+ sub deregister_pki_instance_with_chkconfig
+ {
+ my ($pki_instance_name) = @_;
+ my ($command, $exit_status, $result);
+
+ $result = 1;
+ $command = "/sbin/chkconfig --del $pki_instance_name";
+ if (run_command($command)) {
+ emit("Registered '$pki_instance_name' with '/sbin/chkconfig'.\n");
+ } else {
+ $result = 0;
+ emit("Failed to deregister '$pki_instance_name' with '/sbin/chkconfig'.\n", 'error');
+ }
+ return $result;
+ }
+}
+
+##############################################################
+# Generic Subprocess Subroutines
+##############################################################
+
+# Runs the supplied command in a sub-shell. The command is subject
+# to shell interpretation.
+#
+# WARNING: Do not supply shell IO redirection in the command.
+#
+# Return 1 if success, 0 if failure
+#
+# The critical aspect of running a command is determining if the
+# command succeeded or failed. The proper way to determine this is by
+# checking exit status of command. Perl's subprocess mechansims are
+# less than ideal. In simplicity you would want to run the subprocess,
+# indpendently capture stdout & stderr, wait for termination and then
+# get the exit status. However most of the mechanisms discard
+# stderr. The advantages & disadvantages of each approach is nicely
+# documented here:
+#
+# http://blog.0x1fff.com/2009/09/howto-execute-system-commands-in-perl.html
+#
+# Ideally we would like to capture stdout and stderr
+# independently. The best way to do this is with Perl's IPC::Cmd
+# package which is part of the standard Perl distribution (whose
+# installation may be optional on a given system. RPM can detect our
+# use of this package and force it's installation as a
+# dependency). One disadvantage of IPC::Cmd is that it does not return
+# the actual exit status, just an indication if it was non-zero or not
+# (e.g. success). If we chose to use IPC::Cmd at a future date the
+# implementation would look like this:
+#
+# # Note: IPC::Cmd is in the perl-IPC-Cmd RPM
+# use IPC::Cmd qw[run];
+#
+# my ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf) =
+# run(command => $cmd, verbose => 0);
+#
+# if (!$success) {
+# my ($err_msg);
+#
+# $err_msg = join("", @$stderr_buf);
+# chomp($err_msg);
+#
+# emit(sprintf("FAILED run_command(\"%s\"), output=\"%s\"\n",
+# $cmd, $err_msg), "error");
+#
+# return 0;
+# }
+#
+sub run_command
+{
+ my ($cmd) = @_;
+ my ($output, $wait_status, $exit_status);
+
+ emit(sprintf("run_command(%s)\n", join(", ", @_)), "debug");
+
+ return 1 if $dry_run;
+
+ # Perl backtick only captures stdout.
+ # stderr goes to the existing stderr file descriptor, probably the console.
+ # Capture stderr along with stdout via shell redirection (e.g. 2>&1)
+
+ $output = `$cmd 2>&1`;
+ $wait_status = $?;
+
+ # The low order 8 bits of the status is the terminating signal
+ # for the process, the actual exit status is obtained by
+ # shifting the low order 8 bits out.
+ $exit_status = $wait_status >> 8;
+
+ if ($exit_status != 0) {
+ chomp($output);
+ emit(sprintf("FAILED run_command(\"%s\"), exit status=%d output=\"%s\"\n",
+ $cmd, $exit_status, $output), "error");
+ return 0;
+ }
+
+ return 1;
+}
+
+##############################################################
+# Generic Java Subroutines
+##############################################################
+
+# Given a jar's base name locate it in the file system
+# using standard Java jar path for this system.
+# Return the path to the jar if found, undef otherwise.
+sub find_jar
+{
+ my($jar_name) = @_;
+ my($jar_dir, $jar_path);
+
+ for $jar_dir (@default_jar_path) {
+ $jar_path = "$jar_dir/$jar_name";
+ if (-e $jar_path) {
+ return $jar_path;
+ }
+ }
+ return undef;
+}
+
+##############################################################
+# Generic PKI Subroutines
+##############################################################
+
+# Get parameter value(s) from CS.cfg file
+#
+# get_cs_cfg(config_path, search)
+#
+# There are 3 ways the parameters can be returned, as a string, as a
+# set of variables, or as a hash table depending on the search
+# parameter type.
+#
+# If search is string then the parameter value is returned as a string
+# if it was found, otherwise if it wasn't found then undef is
+# returned.
+#
+# If search is a reference to a hash then each key in the hash will be
+# searched for and the key's value will be used as a reference to
+# assign the value of the parameter to. If the key was not found then
+# the reference will be assigned the value of undef.
+#
+# If search is reference to an array then every parameter in the
+# array will be searched for and a hash will be returned with a key
+# for every parameter found, the key's value is the parameter value.
+#
+# Examples:
+#
+# my ($subsystem_type, $uri, $table);
+#
+# # Get a single string: $subsystem_type is assigned the string "CA"
+# $subsystem_type = get_cs_cfg("/etc/pki-ca/CS.cfg", "cs.type");
+#
+# # Assign a set of variables: $subsystem_type and $uri are assigned
+# get_cs_cfg($config_path, {"cs.type" => \$subsystem_type,
+# "ee.interface.uri" => \$uri});
+#
+# # Get a lookup table:
+# $table = get_cs_cfg("/etc/pki-ca/CS.cfg", ["cs.type", "ee.interface.uri"]);
+# # returns the hash:
+# # {"cs.type" => "CA",
+# # "ee.interface.uri" => "ca/ee/ca"}
+#
+sub get_cs_cfg
+{
+ my ($config_path, $search) = @_;
+ my ($text, $key, $value, $num_found);
+
+ $text = read_file($config_path);
+
+ if (ref($search) eq "HASH") {
+ my $num_found = 0;
+ while (my ($key, $ref) = each(%$search)) {
+ if ($text =~ /^\s*\Q$key\E\s*=\s*(.*)/m) {
+ $value = $1;
+ $$ref = $value;
+ $num_found += 1;
+ } else {
+ $$ref = undef;
+ }
+ }
+ return $num_found;
+ } elsif (ref($search) eq "ARRAY") {
+ my $result = {};
+ my $keys = $search;
+
+ foreach $key (@$keys) {
+ if ($text =~ /^\s*\Q$key\E\s*=\s*(.*)/m) {
+ $value = $1;
+ $result->{$key} = $value;
+ }
+ }
+
+ return $result;
+
+ } else {
+ my $result = undef;
+ $key = $search;
+
+ if ($text =~ /^\s*\Q$key\E\s*=\s*(.*)/m) {
+ $value = $1;
+ $result = $value;
+ }
+
+ return $result;
+
+ }
+}
+
+sub get_registry_initscript_name
+{
+ my ($subsystem_type) = @_;
+ my ($pki_initscript);
+
+ if ($subsystem_type eq $CA) {
+ $pki_initscript = $CA_INITSCRIPT;
+ } elsif($subsystem_type eq $KRA) {
+ $pki_initscript = $KRA_INITSCRIPT;
+ } elsif($subsystem_type eq $OCSP) {
+ $pki_initscript = $OCSP_INITSCRIPT;
+ } elsif($subsystem_type eq $RA) {
+ $pki_initscript = $RA_INITSCRIPT;
+ } elsif($subsystem_type eq $TKS) {
+ $pki_initscript = $TKS_INITSCRIPT;
+ } elsif($subsystem_type eq $TPS) {
+ $pki_initscript = $TPS_INITSCRIPT;
+ } else {
+ die "unknown subsystem type \"$subsystem_type\"";
+ }
+
+}
+
+#######################################
+# Generic selinux routines
+#######################################
+
+sub check_selinux_port
+{
+ my ($setype, $seport) = @_;
+
+ return $SELINUX_PORT_UNDEFINED if $dry_run;
+
+ if (defined $selinux_ports{$seport}) {
+ if ($selinux_ports{$seport} eq $setype) {
+ return $SELINUX_PORT_DEFINED;
+ } else {
+ return $SELINUX_PORT_WRONGLY_DEFINED;
+ }
+ } else {
+ return $SELINUX_PORT_UNDEFINED;
+ }
+}
+
+sub parse_selinux_ports
+{
+ open SM, '/usr/sbin/semanage port -l |grep tcp |sed \'s/tcp/___/g\'|sed \'s/\s//g\'|';
+ while (<SM>) {
+ chomp($_);
+ my ($type, $portstr) = split /___/, $_;
+ my @ports = split /,/, $portstr;
+ foreach my $port (@ports) {
+ if ($port =~ /(.*)-(.*)/) {
+ for (my $count = $1; $count <= $2; $count++) {
+ $selinux_ports{$count} = $type;
+ }
+ } else {
+ $selinux_ports{$port} = $type;
+ }
+ }
+ }
+ close(SM);
+}
+
+sub add_selinux_port
+{
+ my ($setype, $seport, $cmds_ref) = @_;
+ my $status = check_selinux_port($setype, $seport);
+
+ if ($status == $SELINUX_PORT_UNDEFINED) {
+ if ($cmds_ref) {
+ $$cmds_ref .= "port -a -t $setype -p tcp $seport\n";
+ } else {
+ my $cmd = "$semanage port -a -t $setype -p tcp $seport\n";
+ if (! run_command($cmd)) {
+ emit("Failed to set selinux context for $seport", "error");
+ }
+ }
+
+ } elsif ($status == $SELINUX_PORT_WRONGLY_DEFINED) {
+ emit("Failed setting selinux context $setype for $seport. " .
+ "Port already defined otherwise.\n", "error");
+ }
+}
+
+sub add_selinux_file_context
+{
+ my ($fcontext, $fname, $ftype, $cmds_ref) = @_;
+ my ($result);
+
+ emit(sprintf("add_selinux_file_context(%s)\n", join(", ", @_)), "debug");
+
+ #check if fcontext has already been set
+ my $tmp = `$semanage fcontext -l -n |grep $fname |grep ":$fcontext:" | wc -l`;
+ chomp $tmp;
+ if ($tmp ne "0") {
+ emit("selinux fcontext for $fname already defined\n", "debug");
+ return;
+ }
+
+ if ($ftype eq "f") {
+ $$cmds_ref .= "fcontext -a -t $fcontext -f -- $fname\n";
+ } else {
+ $$cmds_ref .= "fcontext -a -t $fcontext $fname\n";
+ }
+}
+
+1;
diff --git a/base/setup/pkicreate b/base/setup/pkicreate
new file mode 100755
index 000000000..edde86ecc
--- /dev/null
+++ b/base/setup/pkicreate
@@ -0,0 +1,3479 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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-2010 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+
+use strict;
+use warnings;
+
+use File::Slurp qw(read_file write_file);
+use Getopt::Long qw(GetOptions);
+
+##############################################################
+# This script is used to create a new instance of a
+# subsystem within a PKI installation.
+#
+# Sample Invocation (for CA):
+#
+# ./pkicreate -pki_instance_root=/var/lib
+# -pki_instance_name=pki-ca
+# -subsystem_type=ca
+# -agent_secure_port=9443
+# -ee_secure_port=9444
+# -ee_secure_client_auth_port=9446
+# -admin_secure_port=9445
+# -unsecure_port=9180
+# -tomcat_server_port=9701
+# -user=pkiuser
+# -group=pkiuser
+# -redirect conf=/etc/pki-ca
+# -redirect logs=/var/log/pki-ca
+# -verbose
+#
+##############################################################
+
+
+##############################################################
+# Execution Check
+##############################################################
+
+# Disallow 'others' the ability to 'write' to new files
+umask 00002;
+
+# Check to insure that this script's original
+# invocation directory has not been deleted!
+my $cwd = `/bin/pwd`;
+chomp $cwd;
+if (!$cwd) {
+ emit("Cannot invoke '$0' from non-existent directory!\n", "error");
+ exit 255;
+}
+
+
+##############################################################
+# Environment Variables
+##############################################################
+
+# option to not run this script.
+if (defined($ENV{'DONT_RUN_PKICREATE'})) {
+ if ($ENV{'DONT_RUN_PKICREATE'} == 1) {
+ emit("Env. variable DONT_RUN_PKICREATE is set. Exiting.\n", "error");
+ exit 0;
+ }
+}
+
+# untaint called subroutines
+if (($^O ne 'Windows_NT') && ($^O ne 'MSWin32')) {
+ $> = $<; # set effective user ID to real UID
+ $) = $(; # set effective group ID to real GID
+ $ENV{'PATH'} = '/bin:/usr/bin';
+ $ENV{'ENV'} = '' if !defined($ENV{'ENV'});
+}
+
+
+##############################################################
+# Command-Line Variables
+##############################################################
+
+my $ARGS = ($#ARGV + 1);
+
+
+##############################################################
+# Shared Common Perl Data and Subroutines
+##############################################################
+
+use lib "/usr/share/pki/scripts";
+use pkicommon;
+
+# Establish path to scripts
+my $pki_subsystem_common_area = "/usr/share/$pki_flavor";
+
+# make -w happy by suppressing warnings of Global variables used only once
+my $suppress = "";
+$suppress = $hostname;
+$suppress = $obj_ext;
+$suppress = $tmp_dir;
+$suppress = $default_security_libraries;
+$suppress = $default_system_libraries;
+$suppress = $lib_prefix;
+$suppress = $PKI_USER;
+$suppress = $PKI_GROUP;
+$suppress = $install_info_basename;
+
+##############################################################
+# Local Constants
+##############################################################
+
+# Base subsystem directory names
+my $applets_base_subsystem_dir = "applets"; # TPS
+my $cgibin_base_subsystem_dir = "cgi-bin"; # TPS (Apache)
+my $conf_base_subsystem_dir = "conf"; # CA, KRA, OCSP, TKS, RA, TPS
+my $docroot_base_subsystem_dir = "docroot"; # RA, TPS (Apache)
+my $emails_base_subsystem_dir = "emails"; # CA
+my $lib_base_subsystem_dir = "lib"; # RA, TPS
+my $profiles_base_subsystem_dir = "profiles"; # CA, KRA, OCSP, TKS
+my $samples_base_subsystem_dir = "samples"; # TPS
+my $scripts_base_subsystem_dir = "scripts"; # RA, TPS
+my $webapps_base_subsystem_dir = "webapps"; # CA, KRA, OCSP, TKS
+
+# Base instance directory names
+my $alias_base_instance_dir = "alias"; # CA, KRA, OCSP, TKS, RA, TPS
+my $bin_base_instance_dir = "bin"; # TPS
+my $cgibin_base_instance_dir = "cgi-bin"; # TPS (Apache)
+my $conf_base_instance_dir = "conf"; # CA, KRA, OCSP, TKS, RA, TPS
+my $docroot_base_instance_dir = "docroot"; # RA, TPS (Apache)
+my $emails_base_instance_dir = "emails"; # CA
+my $lib_base_instance_dir = "lib"; # RA, TPS
+my $logs_base_instance_dir = "logs"; # CA, KRA, OCSP, TKS, RA, TPS
+my $profiles_base_instance_dir = "profiles"; # CA, KRA, OCSP, TKS
+my $scripts_base_instance_dir = "scripts"; # RA, TPS
+my $tomcat_instance_common_lib_dir = "common/lib"; # CA, KRA, OCSP, TKS (Tomcat)
+my $shared_base_instance_dir = "shared"; # CA, KRA, OCSP, TKS (Tomcat)
+my $temp_base_instance_dir = "temp"; # CA, KRA, OCSP, TKS (Tomcat)
+my $webapps_base_instance_dir = "webapps"; # CA, KRA, OCSP, TKS
+my $work_base_instance_dir = "work"; # CA, KRA, OCSP, TKS (Tomcat)
+
+# Base instance symbolic link names
+my $common_base_instance_symlink = "common"; # CA, KRA, OCSP, TKS
+my $conf_base_instance_symlink = "conf"; # CA, KRA, OCSP, TKS, RA, TPS
+my $logs_base_instance_symlink = "logs"; # CA, KRA, OCSP, TKS, RA, TPS
+my $run_base_instance_symlink = "run"; # RA, TPS
+
+# Base names
+my $cgi_home_base_name = "home/index.cgi"; # TPS
+my $cgi_demo_base_name = "demo/index.cgi"; # TPS
+my $cgi_so_base_name = "so/index.cgi"; # TPS
+my $cgi_so_enroll_name = "so/enroll.cgi"; # TPS
+my $cgi_sow_dir_name = "sow"; # TPS
+my $cgi_sow_cfg_pl_name = "sow/cfg.pl"; # TPS
+my $addAgents_ldif_base_name = "addAgents.ldif"; # TPS
+my $addIndexes_ldif_base_name = "addIndexes.ldif"; # TPS
+my $addTokens_ldif_base_name = "addTokens.ldif"; # TPS
+my $addVLVIndexes_ldif_base_name = "addVLVIndexes.ldif"; # TPS
+my $nss_pcache_base_name = "nss_pcache"; # RA, TPS
+my $pki_subsystem_jar_base_name = undef; # CA, KRA, OCSP, TKS
+
+my $pki_certsrv_jar_base_name = "pki-certsrv.jar"; # CA, KRA, OCSP, TKS
+my $pki_cms_jar_base_name = "pki-cms.jar"; # CA, KRA, OCSP, TKS
+my $pki_cmsbundle_jar_base_name = "pki-cmsbundle.jar"; # CA, KRA, OCSP, TKS
+my $pki_cmscore_jar_base_name = "pki-cmscore.jar"; # CA, KRA, OCSP, TKS
+my $pki_cmsutil_jar_base_name = "pki-cmsutil.jar"; # CA, KRA, OCSP, TKS
+my $commons_collections_jar_base_name = undef; # CA, KRA, OCSP, TKS
+my $commons_lang_jar_base_name = undef; # CA, KRA, OCSP, TKS
+my $commons_logging_jar_base_name = undef; # CA, KRA, OCSP, TKS
+my $jss_jar_base_name = "jss4.jar"; # CA, KRA, OCSP, TKS
+my $ldapjdk_jar_base_name = "ldapjdk.jar"; # CA, KRA, OCSP, TKS
+my $pki_nsutil_jar_base_name = "pki-nsutil.jar"; # CA, KRA, OCSP, TKS
+my $commons_codec_jar_base_name = "commons-codec.jar"; # CA, KRA, OCSP, TKS
+my $symkey_jar_base_name = "symkey.jar"; # CA, KRA, OCSP, TKS
+my $tomcatjss_jar_base_name = "tomcatjss.jar"; # CA, KRA, OCSP, TKS
+my $velocity_jar_base_name = "velocity.jar"; # CA, KRA, OCSP, TKS
+my $xerces_jar_base_name = "xerces-j2.jar"; # CA, KRA, OCSP, TKS
+
+# resteasy jars
+my $javassist_jar_base_name = "javassist-3.9.0.GA.jar"; # CA, KRA, OCSP, TKS
+my $jaxrs_api_jar_base_name = "jaxrs-api-2.2.1.GA.jar"; # CA, KRA, OCSP, TKS
+my $resteasy_jaxb_provider_jar_base_name = "resteasy-jaxb-provider-2.2.1.GA.jar"; # CA, KRA, OCSP, TKS
+my $resteasy_jaxrs_jar_base_name = "resteasy-jaxrs-2.2.1.GA.jar"; # CA, KRA, OCSP, TKS
+my $scannotation_jar_base_name = "scannotation-1.0.2.jar"; # CA, KRA, OCSP, TKS
+my $jettison_jar_base_name = "jettison.jar"; # CA, KRA, OCSP, TKS
+my $resteasy_jettison_provider_jar_base_name = "resteasy-jettison-provider-2.3-RC1.jar"; # CA, KRA, OCSP, TKS
+
+my $apache_commons_collections_jar_base_name = "apache-commons-collections.jar";
+my $jakarta_commons_collections_jar_base_name = "jakarta-commons-collections.jar";
+my $apache_commons_logging_jar_base_name = "apache-commons-logging.jar";
+my $jakarta_commons_logging_jar_base_name = "jakarta-commons-logging.jar";
+my $apache_commons_lang_jar_base_name = "apache-commons-lang.jar";
+my $jakarta_commons_lang_jar_base_name = "jakarta-commons-lang.jar";
+my $xml_commons_apis_jar_base_name = "xml-commons-apis.jar";
+my $xml_commons_resolver_jar_base_name = "xml-commons-resolver.jar";
+
+my $conf_base_name = "conf"; # CA, KRA, OCSP, TKS,
+my $catalina_properties_base_name = "catalina.properties"; # CA, KRA, OCSP, TKS
+
+my $httpd_conf_base_name = "httpd.conf"; # RA, TPS
+my $index_jsp_base_name = "index.jsp"; # CA, KRA, OCSP, TKS
+ # RA, TPS
+my $magic_base_name = "magic"; # RA, TPS
+my $mime_types_base_name = "mime.types"; # RA, TPS
+my $noise_base_name = "noise"; # CA, KRA, OCSP, TKS,
+ # RA, TPS
+my $nss_conf_base_name = "nss.conf"; # RA, TPS
+my $perl_conf_base_name = "perl.conf"; # RA, TPS
+my $password_conf_base_name = "password.conf"; # CA, KRA, OCSP, TKS,
+ # RA, TPS
+my $pfile_base_name = "pfile"; # CA, KRA, OCSP, TKS,
+ # RA, TPS
+my $pwcache_conf_base_name = "pwcache.conf"; # RA, TPS
+my $pki_cfg_base_name = "CS.cfg"; # CA, KRA, OCSP, TKS,
+ # RA, TPS
+my $schemaMods_ldif_base_name = "schemaMods.ldif"; # RA, TPS
+my $server_xml_base_name = "server.xml"; # CA, KRA, OCSP, TKS
+my $servercertnick_conf_base_name = "serverCertNick.conf"; # CA, KRA, OCSP, TKS
+my $tomcat6_conf_base_name = "tomcat6.conf"; # CA, KRA, OCSP, TKS
+my $velocity_prop_base_name = "velocity.properties"; # CA, KRA, OCSP, TKS
+my $web_xml_base_name = "web.xml"; # CA, KRA, OCSP, TKS
+my $profile_select_base_name = "ProfileSelect.template"; # CA
+my $proxy_conf_base_name = "proxy.conf"; # CA
+
+my $registry_template_base_name = "registry_instance"; # CA, KRA, OCSP, TKS, RA, TPS
+my $pki_apache_initscript_base_name = "pki_apache_initscript"; # RA, TPS
+
+# Subdirectory names
+my $perl_base_instance_symlink = "perl"; # RA, TPS
+my $perl_base_subsystem_dir = "perl"; # RA, TPS
+my $signed_audit_base_instance_dir = "signedAudit"; # CA, KRA, OCSP, TKS, TPS
+my $webapps_root_base_instance_dir = "ROOT"; # CA, KRA, OCSP, TKS
+my $webapps_root_base_subsystem_dir = "ROOT"; # CA, KRA, OCSP, TKS
+my $webinf_base_instance_dir = "WEB-INF"; # CA, KRA, OCSP, TKS
+
+# Defaults
+my $default_apache_pids_path = "/var/run/pki";
+my $default_tomcat_pids_path = "/var/run";
+my $default_tomcat_lib_path = "/usr/share/tomcat6/lib";
+my $default_security_token = "internal";
+my $default_nfast_group = "nfast";
+
+# Default PKI user and group to give to PKI installed files
+my $pki_user = $PKI_USER;
+my $pki_group = $PKI_GROUP;
+
+# PKI creation constants
+my $db_password_low = 100000000000;
+my $db_password_high = 999999999999;
+
+# Template slot constants (RA, TPS)
+my $HTTPD_CONF = "HTTPD_CONF";
+my $LIB_PREFIX = "LIB_PREFIX";
+my $NSS_CONF = "NSS_CONF";
+my $OBJ_EXT = "OBJ_EXT";
+my $PORT = "PORT";
+my $PROCESS_ID = "PROCESS_ID";
+my $SECURE_PORT = "SECURE_PORT";
+my $NON_CLIENTAUTH_SECURE_PORT = "NON_CLIENTAUTH_SECURE_PORT";
+my $SECURITY_LIBRARIES = "SECURITY_LIBRARIES";
+my $SERVER_NAME = "SERVER_NAME";
+my $SERVER_ROOT = "SERVER_ROOT";
+my $SYSTEM_LIBRARIES = "SYSTEM_LIBRARIES";
+my $SYSTEM_USER_LIBRARIES = "SYSTEM_USER_LIBRARIES";
+my $TMP_DIR = "TMP_DIR";
+my $TPS_DIR = "TPS_DIR";
+my $FORTITUDE_APACHE = "FORTITUDE_APACHE";
+my $FORTITUDE_DIR = "FORTITUDE_DIR";
+my $FORTITUDE_MODULE = "FORTITUDE_MODULE";
+my $FORTITUDE_LIB_DIR = "FORTITUDE_LIB_DIR";
+my $FORTITUDE_AUTH_MODULES = "FORTITUDE_AUTH_MODULES";
+my $FORTITUDE_NSS_MODULES = "FORTITUDE_NSS_MODULES";
+my $REQUIRE_CFG_PL = "REQUIRE_CFG_PL";
+my $PKI_PIDDIR = "PKI_PIDDIR";
+my $PKI_LOCKDIR = "PKI_LOCKDIR";
+
+# Template slot constants (CA, KRA, OCSP, TKS, RA, TPS)
+my $PKI_INSTANCE_ID_SLOT = "PKI_INSTANCE_ID";
+my $PKI_REGISTRY_FILE_SLOT = "PKI_REGISTRY_FILE";
+
+# Template slot constants (CA, KRA, OCSP, TKS)
+my $INSTALL_TIME = "INSTALL_TIME";
+my $PKI_AGENT_CLIENTAUTH_SLOT = "PKI_AGENT_CLIENTAUTH";
+my $PKI_CERT_DB_PASSWORD_SLOT = "PKI_CERT_DB_PASSWORD";
+my $PKI_CFG_PATH_NAME_SLOT = "PKI_CFG_PATH_NAME";
+my $PKI_GROUP_SLOT = "PKI_GROUP";
+my $PKI_INSTANCE_PATH_SLOT = "PKI_INSTANCE_PATH";
+my $PKI_INSTANCE_ROOT_SLOT = "PKI_INSTANCE_ROOT";
+my $PKI_MACHINE_NAME_SLOT = "PKI_MACHINE_NAME";
+my $PKI_RANDOM_NUMBER_SLOT = "PKI_RANDOM_NUMBER";
+my $PKI_SECURE_PORT_SLOT = "PKI_SECURE_PORT";
+my $PKI_EE_SECURE_PORT_SLOT = "PKI_EE_SECURE_PORT";
+my $PKI_EE_SECURE_CLIENT_AUTH_PORT_SLOT = "PKI_EE_SECURE_CLIENT_AUTH_PORT";
+my $PKI_EE_SECURE_CLIENT_AUTH_PORT_UI_SLOT = "PKI_EE_SECURE_CLIENT_AUTH_PORT_UI";
+my $PKI_AGENT_SECURE_PORT_SLOT = "PKI_AGENT_SECURE_PORT";
+my $PKI_ADMIN_SECURE_PORT_SLOT = "PKI_ADMIN_SECURE_PORT";
+my $PKI_SERVER_XML_CONF = "PKI_SERVER_XML_CONF";
+my $PKI_SUBSYSTEM_TYPE_SLOT = "PKI_SUBSYSTEM_TYPE";
+my $PKI_UNSECURE_PORT_SLOT = "PKI_UNSECURE_PORT";
+my $PKI_USER_SLOT = "PKI_USER";
+my $TOMCAT_SERVER_PORT_SLOT = "TOMCAT_SERVER_PORT";
+my $TOMCAT_PIDFILE = "TOMCAT_PIDFILE";
+my $TOMCAT_CFG = "TOMCAT_CFG";
+my $TOMCAT_SSL_OPTIONS = "TOMCAT_SSL_OPTIONS";
+my $TOMCAT_SSL2_CIPHERS = "TOMCAT_SSL2_CIPHERS";
+my $TOMCAT_SSL3_CIPHERS = "TOMCAT_SSL3_CIPHERS";
+my $TOMCAT_TLS_CIPHERS = "TOMCAT_TLS_CIPHERS";
+my $TOMCAT_INSTANCE_COMMON_LIB = "TOMCAT_INSTANCE_COMMON_LIB";
+my $TOMCAT_LOG_DIR = "TOMCAT_LOG_DIR";
+my $PKI_INSTANCE_INITSCRIPT = "PKI_INSTANCE_INITSCRIPT";
+my $PKI_FLAVOR_SLOT = "PKI_FLAVOR";
+my $PKI_UNSECURE_PORT_CONNECTOR_NAME_SLOT = "PKI_UNSECURE_PORT_CONNECTOR_NAME";
+my $PKI_SECURE_PORT_CONNECTOR_NAME_SLOT = "PKI_SECURE_PORT_CONNECTOR_NAME";
+my $PKI_ADMIN_SECURE_PORT_CONNECTOR_NAME_SLOT = "PKI_ADMIN_SECURE_PORT_CONNECTOR_NAME";
+my $PKI_EE_SECURE_PORT_CONNECTOR_NAME_SLOT = "PKI_EE_SECURE_PORT_CONNECTOR_NAME";
+my $PKI_EE_SECURE_CLIENT_AUTH_PORT_CONNECTOR_NAME_SLOT = "PKI_EE_SECURE_CLIENT_AUTH_PORT_CONNECTOR_NAME";
+my $PKI_UNSECURE_PORT_COMMENT_SERVER_SLOT = "PKI_UNSECURE_PORT_SERVER_COMMENT";
+my $PKI_SECURE_PORT_COMMENT_SERVER_SLOT = "PKI_SECURE_PORT_SERVER_COMMENT";
+my $PKI_ADMIN_SECURE_PORT_COMMENT_SERVER_SLOT = "PKI_ADMIN_SECURE_PORT_SERVER_COMMENT";
+my $PKI_EE_SECURE_PORT_COMMENT_SERVER_SLOT = "PKI_EE_SECURE_PORT_SERVER_COMMENT";
+my $PKI_EE_SECURE_CLIENT_AUTH_PORT_COMMENT_SERVER_SLOT = "PKI_EE_SECURE_CLIENT_AUTH_PORT_SERVER_COMMENT";
+my $PKI_OPEN_SEPARATE_PORTS_COMMENT_SERVER_SLOT = "PKI_OPEN_SEPARATE_PORTS_SERVER_COMMENT";
+my $PKI_CLOSE_SEPARATE_PORTS_COMMENT_SERVER_SLOT = "PKI_CLOSE_SEPARATE_PORTS_SERVER_COMMENT";
+my $PKI_OPEN_SEPARATE_PORTS_COMMENT_WEB_SLOT = "PKI_OPEN_SEPARATE_PORTS_WEB_COMMENT";
+my $PKI_CLOSE_SEPARATE_PORTS_COMMENT_WEB_SLOT = "PKI_CLOSE_SEPARATE_PORTS_WEB_COMMENT";
+my $PKI_OPEN_AJP_PORT_COMMENT_SLOT = "PKI_OPEN_AJP_PORT_COMMENT";
+my $PKI_CLOSE_AJP_PORT_COMMENT_SLOT = "PKI_CLOSE_AJP_PORT_COMMENT";
+my $PKI_OPEN_ENABLE_PROXY_COMMENT_SLOT = "PKI_OPEN_ENABLE_PROXY_COMMENT";
+my $PKI_CLOSE_ENABLE_PROXY_COMMENT_SLOT = "PKI_CLOSE_ENABLE_PROXY_COMMENT";
+my $PKI_AJP_REDIRECT_PORT_SLOT = "PKI_AJP_REDIRECT_PORT";
+my $PKI_AJP_PORT_SLOT = "PKI_AJP_PORT";
+my $PROXY_SECURE_PORT_SLOT = "PKI_PROXY_SECURE_PORT";
+my $PROXY_UNSECURE_PORT_SLOT = "PKI_PROXY_UNSECURE_PORT";
+my $PKI_SYSTEMD_SERVICENAME_SLOT = "PKI_SYSTEMD_SERVICENAME";
+my $PKI_UNSECURE_PORT_NAME = "Unsecure";
+my $PKI_AGENT_SECURE_PORT_NAME = "Agent";
+my $PKI_ADMIN_SECURE_PORT_NAME = "Admin";
+my $PKI_EE_SECURE_PORT_NAME = "EE";
+my $PKI_EE_SECURE_CLIENT_AUTH_PORT_NAME = "EEClientAuth";
+my $PKI_SECURE_PORT_NAME = "Secure";
+my $PKI_UNUSED_SECURE_PORT_NAME = "Unused";
+my $PKI_UNSECURE_SEPARATE_PORTS_COMMENT = "<!-- Port Separation: Unsecure Port Connector -->";
+my $PKI_AGENT_SECURE_SEPARATE_PORTS_COMMENT = "<!-- Port Separation: Agent Secure Port Connector -->";
+my $PKI_ADMIN_SECURE_SEPARATE_PORTS_COMMENT = "<!-- Port Separation: Admin Secure Port Connector -->";
+my $PKI_EE_SECURE_SEPARATE_PORTS_COMMENT = "<!-- Port Separation: EE Secure Port Connector -->";
+my $PKI_EE_SECURE_CLIENT_AUTH_SEPARATE_PORTS_COMMENT = "<!-- Port Separation: EE Secure Client Auth Port Connector -->";
+my $PKI_UNSECURE_SHARED_PORTS_COMMENT = "<!-- Shared Ports: Unsecure Port Connector -->";
+my $PKI_SECURE_SHARED_PORTS_COMMENT = "<!-- Shared Ports: Agent, EE, and Admin Secure Port Connector -->";
+my $PKI_OPEN_COMMENT = "<!--";
+my $PKI_CLOSE_COMMENT = "-->";
+my $PKI_WEBAPPS_NAME = "PKI_WEBAPPS_NAME";
+
+#proxy defaults
+my $PROXY_SECURE_PORT_DEFAULT = "443";
+my $PROXY_UNSECURE_PORT_DEFAULT = "80";
+my $AJP_PORT_DEFAULT = "9447";
+
+##############################################################
+# Local Data Structures
+##############################################################
+
+# Useful pki references
+my %redirects = ();
+my %supported_sec_modules_hash = ();
+
+##############################################################
+# Local Variables
+##############################################################
+
+# Command-line variables (mandatory)
+my $pki_instance_root = undef;
+my $pki_instance_name = undef;
+my $subsystem_type = undef;
+my $secure_port = -1;
+my $non_clientauth_secure_port = -1;
+my $unsecure_port = -1;
+my $tomcat_server_port = -1;
+
+# Command-line variables (optional)
+my $agent_secure_port = -1;
+my $ee_secure_port = -1;
+my $ee_secure_client_auth_port = -1;
+my $admin_secure_port = -1;
+my $proxy_secure_port = -1;
+my $proxy_unsecure_port = -1;
+my $ajp_port = -1;
+my $enable_proxy = undef;
+my $username = undef;
+my $groupname = undef;
+my $redirected_conf_path = undef;
+my $redirected_logs_path = undef;
+
+# Base subsystem directory paths
+my $pki_subsystem_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $applets_subsystem_path = undef; # TPS
+my $bin_subsystem_path = undef; # TPS
+my $cgibin_subsystem_path = undef; # TPS (Apache)
+my $conf_subsystem_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $docroot_subsystem_path = undef; # RA, TPS (Apache)
+my $emails_subsystem_path = undef; # CA
+my $lib_subsystem_path = undef; # RA, TPS
+my $profiles_subsystem_path = undef; # CA, KRA, OCSP, TKS
+my $samples_subsystem_path = undef; # TPS
+my $scripts_subsystem_path = undef; # RA, TPS
+my $webapps_subsystem_path = undef; # CA, KRA, OCSP, TKS
+my $common_ui_subsystem_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $ui_subsystem_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+
+# Base instance directory paths
+my $pki_instance_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $alias_instance_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $bin_instance_path = undef; # TPS
+my $cgibin_instance_path = undef; # TPS (Apache)
+my $conf_instance_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $docroot_instance_path = undef; # RA, TPS (Apache)
+my $emails_instance_path = undef; # CA
+my $lib_instance_path = undef; # RA, TPS
+my $logs_instance_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $profiles_instance_path = undef; # CA, KRA, OCSP, TKS
+my $scripts_instance_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $tomcat_instance_common_lib_path = undef; # CA, KRA, OCSP, TKS (Tomcat)
+my $shared_instance_path = undef; # CA, KRA, OCSP, TKS (Tomcat)
+my $temp_instance_path = undef; # CA, KRA, OCSP, TKS (Tomcat)
+my $webapps_instance_path = undef; # CA, KRA, OCSP, TKS
+my $webapps_subsystem_instance_path = undef; # CA, KRA, OCSP, TKS
+my $work_instance_path = undef; # CA, KRA, OCSP, TKS (Tomcat)
+my $pki_piddir_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $pki_lockdir_path = undef; # RA, TPS
+
+# Base instance symbolic link paths
+my $conf_instance_symlink_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $logs_instance_symlink_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $run_instance_symlink_path = undef; # RA, TPS
+
+# Subdirectory paths
+my $cgi_home_instance_file_path = undef; # TPS
+my $cgi_home_subsystem_file_path = undef; # TPS
+my $cgi_demo_instance_file_path = undef; # TPS
+my $cgi_demo_subsystem_file_path = undef; # TPS
+my $cgi_so_instance_file_path = undef; # TPS
+my $cgi_so_subsystem_file_path = undef; # TPS
+my $cgi_so_instance_enroll_file_path = undef; # TPS
+my $cgi_so_subsystem_enroll_file_path = undef; # TPS
+my $cgi_sow_instance_file_path = undef; # TPS
+my $cgi_sow_subsystem_file_path = undef; # TPS
+my $cgi_sow_instance_cgi_file_path = undef; # TPS
+my $cgi_sow_subsystem_cgi_file_path = undef; # TPS
+my $cgi_sow_instance_cfg_pl_path = undef; # TPS
+my $addAgents_ldif_instance_file_path = undef; # TPS
+my $addAgents_ldif_subsystem_file_path = undef; # TPS
+my $addIndexes_ldif_instance_file_path = undef; # TPS
+my $addIndexes_ldif_subsystem_file_path = undef; # TPS
+my $addTokens_ldif_instance_file_path = undef; # TPS
+my $addTokens_ldif_subsystem_file_path = undef; # TPS
+my $addVLVIndexes_ldif_instance_file_path = undef; # TPS
+my $addVLVIndexes_ldif_subsystem_file_path = undef; # TPS
+my $pki_certsrv_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $pki_certsrv_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $pki_cms_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $pki_cms_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $pki_cmsbundle_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $pki_cmsbundle_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $pki_cmscore_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $pki_cmscore_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $pki_cmsutil_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $pki_cmsutil_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $javassist_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $javassist_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $jaxrs_api_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $jaxrs_api_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $resteasy_jaxb_provider_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $resteasy_jaxb_provider_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $resteasy_jaxrs_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $resteasy_jaxrs_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $scannotation_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $scannotation_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $jettison_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $jettison_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $resteasy_jettison_provider_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $resteasy_jettison_provider_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $commons_collections_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $commons_collections_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $commons_lang_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $commons_lang_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $commons_logging_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $commons_logging_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $jss_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $jss_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $ldapjdk_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $ldapjdk_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $pki_nsutil_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $pki_nsutil_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $commons_codec_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $commons_codec_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $symkey_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $symkey_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $tomcatjss_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $tomcatjss_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $velocity_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $velocity_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $xerces_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $xerces_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $xml_commons_apis_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $xml_commons_apis_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $xml_commons_resolver_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $xml_commons_resolver_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $httpd_conf_instance_file_path = undef; # RA, TPS
+my $httpd_conf_subsystem_file_path = undef; # RA, TPS
+my $index_jsp_instance_file_path = undef; # CA, KRA, OCSP, TKS
+my $index_jsp_subsystem_file_path = undef; # CA, KRA, OCSP, TKS
+my $magic_instance_file_path = undef; # RA, TPS
+my $magic_subsystem_file_path = undef; # RA, TPS
+my $mime_types_instance_file_path = undef; # RA, TPS
+my $mime_types_subsystem_file_path = undef; # RA, TPS
+my $noise_instance_file_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $nss_conf_instance_file_path = undef; # RA, TPS
+my $nss_conf_subsystem_file_path = undef; # RA, TPS
+my $nss_pcache_instance_file_path = undef; # RA, TPS
+my $nss_pcache_subsystem_file_path = undef; # RA, TPS
+my $perl_conf_instance_file_path = undef; # RA, TPS
+my $perl_conf_subsystem_file_path = undef; # RA, TPS
+my $password_conf_instance_file_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $perl_instance_symlink_path = undef; # RA, TPS
+my $perl_subsystem_path = undef; # RA, TPS
+my $pfile_instance_file_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $pwcache_conf_instance_file_path = undef; # RA, TPS
+my $pki_cfg_subsystem_file_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $pki_cfg_instance_file_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $pki_apache_initscript_file_path = undef; # RA, TPS
+my $schemaMods_ldif_instance_file_path = undef; # RA, TPS
+my $schemaMods_ldif_subsystem_file_path = undef; # RA, TPS
+my $server_xml_instance_file_path = undef; # CA, KRA, OCSP, TKS
+my $server_xml_subsystem_file_path = undef; # CA, KRA, OCSP, TKS
+my $servercertnick_conf_instance_file_path = undef; # CA, KRA, OCSP, TKS
+my $servercertnick_conf_subsystem_file_path = undef; # CA, KRA, OCSP, TKS
+my $pki_subsystem_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $pki_subsystem_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $tomcat6_conf_subsystem_file_path = undef; # CA, KRA, OCSP, TKS
+my $tomcat6_conf_instance_file_path = undef; # CA, KRA, OCSP, TKS
+my $tomcat6_instance_pid_file_path = undef; # CA, KRA, OCSP, TKS
+my $velocity_prop_instance_file_path = undef; # CA, KRA, OCSP, TKS
+my $velocity_prop_subsystem_file_path = undef; # CA, KRA, OCSP, TKS
+my $web_xml_instance_file_path = undef; # CA, KRA, OCSP, TKS
+my $web_xml_subsystem_file_path = undef; # CA, KRA, OCSP, TKS
+my $catalina_properties_instance_file_path = undef; # CA, KRA, OCSP, TKS
+my $catalina_properties_subsystem_file_path = undef; # CA, KRA, OCSP, TKS
+my $webapps_root_instance_path = undef; # CA, KRA, OCSP, TKS
+my $webapps_root_subsystem_path = undef; # CA, KRA, OCSP, TKS
+my $webinf_instance_path = undef; # CA, KRA, OCSP, TKS
+my $webinf_lib_instance_path = undef; # CA, KRA, OCSP, TKS
+my $webinf_subsystem_path = undef; # CA, KRA, OCSP, TKS
+my $profile_select_template_subsystem_file_path = undef; #CA
+my $profile_select_template_instance_file_path = undef; #CA
+my $proxy_conf_subsystem_file_path = undef; #CA
+my $proxy_conf_instance_file_path = undef; #CA
+
+# PKI init script variables
+my $pki_registry_initscript = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $pki_registry_initscript_command = undef; # CA, KRA, OCSP, TKS, RA, TPS
+
+# PKI registry variables
+my $pki_registry_subsystem_path = undef; # CA, KRA, OCSP, TKS RA, TPS
+my $pki_registry_subsystem_file_path = undef; # CA, KRA, OCSP, TKS RA, TPS
+my $pki_registry_instance_file_path = undef; # CA, KRA, OCSP, TKS RA, TPS
+
+# PKI creation variables
+my $host = undef;
+my $db_password = undef;
+my $random = undef;
+
+# Linux specific variables
+my $setup_base_subsystem_dir = "setup";
+my $setup_subsystem_path = undef;
+my $tomcat6_initscript_path = undef;
+my $tomcat6_instance_config_path = undef;
+my $root_user = undef;
+my $root_group = undef;
+my $pki_instance_initscript_path = undef;
+
+#systemd specific variables
+my $use_systemd = 0;
+my $pki_subsystem_systemd_wants_path = undef;
+my $pki_subsystem_systemd_service_path = undef;
+my $pki_instance_systemd_service_name = undef;
+
+
+##############################################################
+# Platform-Dependent Data Initialization
+##############################################################
+
+if ($^O eq "linux") {
+ if (is_Fedora() && (fedora_release() >= 16)) {
+ $use_systemd = 1;
+ }
+
+ # Linux init scripts
+ if ($use_systemd) {
+ $tomcat6_initscript_path = "/usr/sbin/tomcat6-sysd";
+ } else {
+ $tomcat6_initscript_path = "${default_initscripts_path}/tomcat6";
+ }
+
+ # Tomcat instance config directory
+ $tomcat6_instance_config_path = "/etc/sysconfig";
+
+ # Superuser and group to give to PKI installed files
+ $root_user = "root";
+ $root_group = "root";
+} else {
+ emit("Unsupported platform '$^O'!\n", "error");
+ exit 255;
+}
+
+
+##############################################################
+# Local Data Initialization
+##############################################################
+
+# Initialize Java-specific variables
+if ($^O eq "linux") {
+ if ($default_hardware_platform eq "i386") {
+ # 32-bit Linux
+
+ # Supported hardware token PKCS #11 modules
+ %supported_sec_modules_hash = ("lunasa" => "/usr/lunasa/lib/libCryptoki2.so",
+ "nfast" => "/opt/nfast/toolkits/pkcs11/libcknfast.so");
+ } elsif ($default_hardware_platform eq "x86_64") {
+ # 64-bit Linux
+
+ # Supported hardware token PKCS #11 modules
+ %supported_sec_modules_hash = ("lunasa" => "/usr/lunasa/lib/libCryptoki2_64.so",
+ "nfast" => "/opt/nfast/toolkits/pkcs11/libcknfast.so");
+ } else {
+ emit("Unsupported '$^O' hardware platform '$default_hardware_platform'!\n", "error");
+ exit 255;
+ }
+} else {
+ emit("Unsupported platform '$^O'!\n", "error");
+ exit 255;
+}
+
+##############################################################
+# PKI Instance Creation Subroutines
+##############################################################
+
+# no args
+# no return value
+sub usage
+{
+ print STDOUT <<'EOF';
+###############################################################################
+### USAGE: CA, KRA, OCSP, or TKS subsystem instance creation (Tomcat) ###
+###############################################################################
+
+pkicreate -pki_instance_root=<pki_instance_root> # Instance root directory
+ # destination
+
+ -pki_instance_name=<pki_instance_id> # Unique PKI subsystem
+ # instance name
+
+ -subsystem_type=<subsystem_type> # Subsystem type
+ # [ca | kra | ocsp | tks]
+
+ #####################################################################
+ ### SELECT separate secure ports for AGENT, EE, and ADMIN: ###
+ #####################################################################
+
+ -agent_secure_port=<agent_secure_port> # Agent secure port
+
+ -ee_secure_port=<ee_secure_port> # EE secure port
+
+ -admin_secure_port=<admin_secure_port> # Admin secure port
+
+ #####################################################################
+ ### ... and a client auth EE port, required for CAs only ###
+ #####################################################################
+
+ -ee_secure_client_auth_port=<ee_secure_client_auth_port>
+ # EE secure client authentication port
+
+ #####################################################################
+ ### OR SELECT a single secure port shared by AGENT,EE and ADMIN ###
+ ### ###
+ ### WARNING: Use of a single shared secure port has been ###
+ ### DEPRECATED! Use 'port separation' in conjunction ###
+ ### with 'port forwarding' to emulate this behavior. ###
+ #####################################################################
+
+ -secure_port=<secure_port> # Secure port
+ # (shared by Agent,
+ # EE, and Admin)
+
+ #####################################################################
+ ### END secure port SELECTION ###
+ #####################################################################
+
+ -unsecure_port=<unsecure_port> # Unsecure port
+
+ -tomcat_server_port=<tomcat_server_port> # Unique port for each
+ # Tomcat instance
+
+ #####################################################################
+ ### proxy configuration ###
+ ### if -enable_proxy is set, ajp_port, proxy_secure_port, and ###
+ ### proxy_unsecure_port are also set. ###
+ #####################################################################
+
+ [-enable_proxy] #enable proxy configuration
+ [-ajp_port=<ajp_port>] #AJP port, default 9447
+
+ [-proxy_secure_port=<proxy_secure_port>] # Proxy secure port,
+ # default 443
+
+ [-proxy_unsecure_port=<unsecure_port>] # Proxy unsecure port,
+ # default 80
+
+ #####################################################################
+ ### END proxy configuration ###
+ #####################################################################
+
+ [-user=<username>] # User ownership
+ # (must ALSO specify
+ # group ownership)
+ #
+ # [Default=pkiuser]
+
+ [-group=<groupname>] # Group ownership
+ # (must ALSO specify
+ # user ownership)
+ #
+ # [Default=pkiuser]
+
+ [-redirect conf=<real conf dir path>] # Redirection of
+ # 'conf' directory
+
+ [-redirect logs=<real logs dir path>] # Redirection of
+ # 'logs' directory
+
+ [-verbose] # Print out liberal info
+ # during 'pkicreate'.
+ # Specify multiple times
+ # to increase verbosity.
+
+ [-dry_run] # Do not perform any actions.
+ # Just report what would have
+ # been done.
+
+ [-help] # Print out this screen
+
+
+###############################################################################
+### USAGE: RA or TPS subsystem instance creation (Apache) ###
+###############################################################################
+
+pkicreate -pki_instance_root=<pki_instance_root> # Instance root directory
+ # destination
+
+ -pki_instance_name=<pki_instance_id> # Unique PKI subsystem
+ # instance name
+
+ -subsystem_type=<subsystem_type> # Subsystem type
+ # [ra | tps]
+
+ -secure_port=<secure_port> # Secure port
+ # (clientauth)
+ # for each
+ # Apache instance
+
+ -non_clientauth_secure_port=<non_clientauth_secure_port>
+
+ # Secure port
+ # (non-clientauth)
+ # for each
+ # Apache instance
+
+ -unsecure_port=<unsecure_port> # Unsecure port
+
+ [-user=<username>] # User ownership
+ # (must ALSO specify
+ # group ownership)
+ #
+ # [Default=pkiuser]
+
+ [-group=<groupname>] # Group ownership
+ # (must ALSO specify
+ # user ownership)
+ #
+ # [Default=pkiuser]
+
+ [-redirect conf=<real conf dir path>] # Redirection of
+ # 'conf' directory
+
+ [-redirect logs=<real logs dir path>] # Redirection of
+ # 'logs' directory
+
+ [-verbose] # Print out liberal info
+ # during 'pkicreate'.
+ # Specify multiple times
+ # to increase verbosity.
+
+ [-dry_run] # Do not perform any actions.
+ # Just report what would have
+ # been done.
+
+ [-help] # Print out this screen
+
+
+###############################################################################
+### EXAMPLES: ###
+### PKI (Tomcat) subsystem instance creation of a CA ###
+### PKI (Tomcat) subsystem instance creation of a Subordinate CA ###
+### PKI (Tomcat) subsystem instance creation of a KRA ###
+### PKI (Tomcat) subsystem instance creation of an OCSP ###
+### PKI (Tomcat) subsystem instance creation of a TKS ###
+### PKI (Apache) subsystem instance creation of an RA ###
+### PKI (Apache) subsystem instance creation of a TPS ###
+### PKI (Apache) subsystem instance creation of a second TPS ###
+###############################################################################
+
+pkicreate -pki_instance_root=/var/lib \
+ -pki_instance_name=pki-ca \
+ -subsystem_type=ca \
+ -agent_secure_port=9443 \
+ -ee_secure_port=9444 \
+ -ee_secure_client_auth_port=9446 \
+ -admin_secure_port=9445 \
+ -unsecure_port=9180 \
+ -tomcat_server_port=9701 \
+ -user=pkiuser \
+ -group=pkiuser \
+ -redirect conf=/etc/pki-ca \
+ -redirect logs=/var/log/pki-ca \
+ -verbose
+
+pkicreate -pki_instance_root=/var/lib \
+ -pki_instance_name=pki-subca \
+ -subsystem_type=ca \
+ -agent_secure_port=9543 \
+ -ee_secure_port=9544 \
+ -ee_secure_client_auth_port=9546 \
+ -admin_secure_port=9545 \
+ -unsecure_port=9580 \
+ -tomcat_server_port=9801 \
+ -user=pkiuser \
+ -group=pkiuser \
+ -redirect conf=/etc/pki-subca \
+ -redirect logs=/var/log/pki-subca \
+ -verbose
+
+pkicreate -pki_instance_root=/var/lib \
+ -pki_instance_name=pki-kra \
+ -subsystem_type=kra \
+ -agent_secure_port=10443 \
+ -ee_secure_port=10444 \
+ -admin_secure_port=10445 \
+ -unsecure_port=10180 \
+ -tomcat_server_port=10701 \
+ -user=pkiuser \
+ -group=pkiuser \
+ -redirect conf=/etc/pki-kra \
+ -redirect logs=/var/log/pki-kra \
+ -verbose
+
+pkicreate -pki_instance_root=/var/lib \
+ -pki_instance_name=pki-ocsp \
+ -subsystem_type=ocsp \
+ -agent_secure_port=11443 \
+ -ee_secure_port=11444 \
+ -admin_secure_port=11445 \
+ -unsecure_port=11180 \
+ -tomcat_server_port=11701 \
+ -user=pkiuser \
+ -group=pkiuser \
+ -redirect conf=/etc/pki-ocsp \
+ -redirect logs=/var/log/pki-ocsp \
+ -verbose
+
+pkicreate -pki_instance_root=/var/lib \
+ -pki_instance_name=pki-tks \
+ -subsystem_type=tks \
+ -agent_secure_port=13443 \
+ -ee_secure_port=13444 \
+ -admin_secure_port=13445 \
+ -unsecure_port=13180 \
+ -tomcat_server_port=13701 \
+ -user=pkiuser \
+ -group=pkiuser \
+ -redirect conf=/etc/pki-tks \
+ -redirect logs=/var/log/pki-tks \
+ -verbose
+
+pkicreate -pki_instance_root=/var/lib \
+ -pki_instance_name=pki-ra \
+ -subsystem_type=ra \
+ -secure_port=12889 \
+ -non_clientauth_secure_port=12890 \
+ -unsecure_port=12888 \
+ -user=pkiuser \
+ -group=pkiuser \
+ -redirect conf=/etc/pki-ra \
+ -redirect logs=/var/log/pki-ra \
+ -verbose
+
+pkicreate -pki_instance_root=/var/lib \
+ -pki_instance_name=pki-tps \
+ -subsystem_type=tps \
+ -secure_port=7889 \
+ -non_clientauth_secure_port=7890 \
+ -unsecure_port=7888 \
+ -user=pkiuser \
+ -group=pkiuser \
+ -redirect conf=/etc/pki-tps \
+ -redirect logs=/var/log/pki-tps \
+ -verbose
+
+pkicreate -pki_instance_root=/var/lib \
+ -pki_instance_name=pki-tps1 \
+ -subsystem_type=tps \
+ -secure_port=7989 \
+ -non_clientauth_secure_port=7990 \
+ -unsecure_port=7988 \
+ -user=pkiuser \
+ -group=pkiuser \
+ -redirect conf=/etc/pki-tps1 \
+ -redirect logs=/var/log/pki-tps1 \
+ -verbose
+
+IMPORTANT: Must be run as root!
+EOF
+
+ return;
+}
+
+
+# arg0 instance name
+# return 1 - exists, or
+# return 0 - DOES NOT exist
+sub pki_instance_already_exists
+{
+ my ($name) = @_;
+ my $result = 0;
+ my $instance = "";
+
+ $instance = $pki_registry_path
+ . "/" . $subsystem_type
+ . "/" . $name;
+
+ if (-e $instance) {
+ $result = 1;
+ }
+
+ return $result;
+}
+
+
+# no args
+# return 1 - success, or
+# return 0 - failure
+sub parse_arguments
+{
+ my $l_secure_port = -1;
+ my $l_non_clientauth_secure_port = -1;
+ my $l_unsecure_port = -1;
+ my $l_tomcat_server_port = -1;
+ my $l_agent_secure_port = -1;
+ my $l_ee_secure_port = -1;
+ my $l_ee_secure_client_auth_port = -1;
+ my $l_admin_secure_port = -1;
+ my $l_proxy_secure_port = -1;
+ my $l_proxy_unsecure_port = -1;
+ my $l_ajp_port = -1;
+ my $show_help = 0;
+
+ my $result = GetOptions("help" => \$show_help,
+ "pki_instance_root=s" => \$pki_instance_root,
+ "pki_instance_name=s" => \$pki_instance_name,
+ "subsystem_type=s" => \$subsystem_type,
+ "secure_port:i" => \$l_secure_port,
+ "non_clientauth_secure_port:i" => \$l_non_clientauth_secure_port,
+ "unsecure_port:i" => \$l_unsecure_port,
+ "agent_secure_port:i" => \$l_agent_secure_port,
+ "ee_secure_port:i" => \$l_ee_secure_port,
+ "ee_secure_client_auth_port:i" => \$l_ee_secure_client_auth_port,
+ "admin_secure_port:i" => \$l_admin_secure_port,
+ "tomcat_server_port:i" => \$l_tomcat_server_port,
+ "proxy_secure_port:i" => \$l_proxy_secure_port,
+ "proxy_unsecure_port:i" => \$l_proxy_unsecure_port,
+ "ajp_port:i" => \$l_ajp_port,
+ "enable_proxy" => \$enable_proxy,
+ "user=s" => \$username,
+ "group=s" => \$groupname,
+ "verbose+" => \$verbose,
+ "dry_run" => \$dry_run,
+ "redirect=s" => \%redirects);
+
+
+ ## Optional "-help" option - no "mandatory" options are required
+ if ($show_help) {
+ usage();
+ return 0;
+ }
+
+
+ ## Mandatory "-pki_instance_root=s" option
+ if (!$pki_instance_root) {
+ usage();
+ emit("Must have value for -pki_instance_root!\n", "error");
+ return 0;
+ }
+
+ if ($pki_instance_root eq "/") {
+ usage();
+ emit("Don't even think about making root the pki_instance_root! "
+ . "Try again.\n", "error");
+ return 0;
+ }
+
+ # Remove all trailing directory separators ('/')
+ $pki_instance_root =~ s/\/+$//;
+
+ if (!is_path_valid($pki_instance_root)) {
+ usage();
+ emit("Target directory $pki_instance_root is not a "
+ . "legal directory try again.\n",
+ "error");
+ return 0;
+ }
+
+ ## Mandatory "-subsystem_type=s" option
+ if ($subsystem_type ne $CA &&
+ $subsystem_type ne $KRA &&
+ $subsystem_type ne $OCSP &&
+ $subsystem_type ne $TKS &&
+ $subsystem_type ne $RA &&
+ $subsystem_type ne $TPS) {
+ usage();
+ emit("Illegal value => $subsystem_type : for -subsystem_type!\n",
+ "error");
+ return 0;
+ }
+
+ $pki_subsystem_path = $pki_subsystem_common_area
+ . "/" . $subsystem_type;
+
+ if (!(-d $pki_subsystem_path)) {
+ usage();
+ emit("$pki_subsystem_path not present. "
+ . "Please install the corresponding subsystem RPM first!\n",
+ "error");
+ return 0;
+ } else {
+ emit(" subsystem_type $subsystem_type\n");
+ }
+
+
+ ## Mandatory "-pki_instance_name=s" option
+ if (!$pki_instance_name) {
+ usage();
+ emit("Must have value for -pki_instance_name!\n", "error");
+ return 0;
+ }
+
+ if (!is_name_valid($pki_instance_name)) {
+ usage();
+ emit("Illegal Value => $pki_instance_name for -pki_instance_name!\n",
+ "error");
+ return 0;
+ }
+
+ if (pki_instance_already_exists($pki_instance_name) && !$dry_run) {
+ usage();
+ emit("An instance named $pki_instance_name "
+ . "already exists; please try again.\n", "error");
+ return 0;
+ }
+
+ $pki_instance_path = "${pki_instance_root}/${pki_instance_name}";
+
+ if (directory_exists($pki_instance_path) && !$dry_run) {
+ usage();
+ emit("Target directory $pki_instance_path "
+ . "already exists; clean up and "
+ . "try again.\n", "error");
+ return 0;
+ }
+
+ # Capture installation information in a log file, always overwrite this file.
+ # When creating an instance it's a fatal error if the logfile
+ # cannot be created.
+ my $logfile = "/var/log/${pki_instance_name}-install.log";
+ if (!open_logfile($logfile, $default_file_permissions)) {
+ emit("can not create logfile ($logfile)", "error");
+ return 0;
+ }
+
+ add_install_info($logfile, 'file', 'preserve');
+
+ printf(STDOUT "Capturing installation information in %s\n", $logfile);
+
+ emit("Parsing PKI creation arguments ...\n");
+
+ if ($verbose) {
+ emit(" verbose mode ENABLED (level=$verbose)\n");
+ }
+
+ if ($dry_run) {
+ emit(" dry run mode ENABLED, system will not be modified\n");
+ print STDOUT "dry run mode ENABLED, system will not be modified\n";
+ }
+
+ emit(" pki_instance_root $pki_instance_root\n");
+ emit(" pki_instance_name $pki_instance_name\n");
+
+ ## Mandatory "-secure_port=<secure_port>" option
+ if ($l_secure_port >= 0) {
+ $secure_port = $l_secure_port;
+
+ emit(" secure_port $secure_port\n");
+ } else {
+ if ($l_agent_secure_port == -1)
+ {
+ usage();
+ emit("Must include value for secure_port!\n", "error");
+ return 0;
+ }
+ }
+
+ ## Mandatory "-non_clientauth_secure_port=<non_clientauth_secure_port>"
+ ## option/exclusion
+ if (($subsystem_type eq $RA || $subsystem_type eq $TPS)) {
+ if ($l_non_clientauth_secure_port >= 0) {
+ $non_clientauth_secure_port = $l_non_clientauth_secure_port;
+
+ emit(" non_clientauth_secure_port "
+ . "$non_clientauth_secure_port\n");
+ } else {
+ if ($l_non_clientauth_secure_port == -1)
+ {
+ usage();
+ emit("Must include value for non_clientauth_secure_port!\n",
+ "error");
+ return 0;
+ }
+ }
+
+ if ($l_agent_secure_port > 0 ||
+ $l_ee_secure_port > 0 ||
+ $l_ee_secure_client_auth_port > 0 ||
+ $l_admin_secure_port > 0) {
+ usage();
+ emit("Must NOT include values for any agent|admin|ee ports!\n",
+ "error");
+ return 0;
+ }
+ } else {
+ ## Mandatory EXCLUSION for CA, KRA, OCSP, and TKS subsystems
+ if ($l_non_clientauth_secure_port != -1) {
+ usage();
+ emit("Must NOT include value for non_clientauth_secure_port!\n",
+ "error");
+ return 0;
+ }
+ }
+
+ ## Mandatory "-unsecure_port=<unsecure_port>" option
+ if ($l_unsecure_port >= 0) {
+ $unsecure_port = $l_unsecure_port;
+
+ emit(" unsecure_port $unsecure_port\n");
+ } else {
+ usage();
+ emit("Must include value for unsecure_port!\n", "error");
+ return 0;
+ }
+
+ ## Mandatory "-tomcat_server_port=<tomcat_server_port>" option/exclusion
+ if (!($subsystem_type eq $RA || $subsystem_type eq $TPS)) {
+ ## Mandatory OPTION for CA, KRA, OCSP, and TKS subsystems
+ if ($l_tomcat_server_port < 0) {
+ usage();
+ emit("Must include value for tomcat_server_port!\n", "error");
+ return 0;
+ }
+
+ $tomcat_server_port = $l_tomcat_server_port;
+
+ emit(" tomcat_server_port $tomcat_server_port\n");
+ } else {
+ ## Mandatory EXCLUSION for RA and TPS subsystems
+ if ($l_tomcat_server_port != -1) {
+ usage();
+ emit("Must NOT include value for tomcat_server_port!\n",
+ "error");
+ return 0;
+ }
+ }
+
+ if ($l_agent_secure_port >= 0) {
+ $agent_secure_port = $l_agent_secure_port;
+
+ emit(" agent_secure_port $agent_secure_port\n");
+
+ }
+
+ ## Mandatory ee_secure_port if "-agent_secure_port" is given
+
+ if ($l_ee_secure_port >= 0) {
+ $ee_secure_port = $l_ee_secure_port;
+
+ emit(" ee_secure_port $ee_secure_port\n");
+
+ } else {
+ if ($agent_secure_port >= 0) {
+ emit("Must include value for ee_secure_port if agent_secure_port is given!\n");
+ }
+ }
+
+ ## Mandatory ee_secure_client_auth_port if "-agent_secure_port" is given, and CA subsystem
+
+ if ($l_ee_secure_client_auth_port >= 0) {
+ $ee_secure_client_auth_port = $l_ee_secure_client_auth_port;
+
+ emit(" ee_secure_client_auth_port $ee_secure_client_auth_port\n");
+
+ } else {
+ if (($agent_secure_port >= 0) && ($subsystem_type eq $CA)) {
+ usage();
+ emit("For CAs, must include value for ee_secure_client_auth_port if agent_secure_port is given!\n");
+ return 0;
+ }
+ }
+
+ ## Mandatory admin_secure_port if "-agent_secure_port" is given
+
+ if ($l_admin_secure_port >= 0) {
+ $admin_secure_port = $l_admin_secure_port;
+
+ emit(" admin_secure_port $admin_secure_port\n");
+
+ } else {
+ if ($agent_secure_port >= 0) {
+ emit("Must include value for admin_secure_port if agent_secure_port is given!\n");
+ }
+ }
+
+ if ($enable_proxy) {
+
+ $proxy_secure_port = ($l_proxy_secure_port >= 0) ? $l_proxy_secure_port :
+ $PROXY_SECURE_PORT_DEFAULT;
+ emit(" proxy_secure_port $proxy_secure_port\n");
+
+ $proxy_unsecure_port = ($l_proxy_unsecure_port >= 0) ? $l_proxy_unsecure_port :
+ $PROXY_UNSECURE_PORT_DEFAULT;
+ emit(" proxy_unsecure_port $proxy_unsecure_port\n");
+
+ $ajp_port = ($l_ajp_port >= 0) ? $l_ajp_port : $AJP_PORT_DEFAULT;
+ emit(" ajp_port $ajp_port\n");
+ }
+
+ if (!AreConnectorPortsValid($secure_port,$unsecure_port,$agent_secure_port,
+ $ee_secure_port,$ee_secure_client_auth_port, $admin_secure_port,
+ $proxy_secure_port, $proxy_unsecure_port))
+ {
+ usage();
+ emit("Invalid port numbers submitted!\n","error");
+ return 0;
+ }
+
+
+ ## Optional "-group=<groupname>" option
+ if ($groupname) {
+ if (!$username) {
+ usage();
+ emit("Must ALSO specify user ownership using -user!\n",
+ "error");
+ return 0;
+ }
+
+ if (!group_exists($groupname)) {
+ if (!create_group($groupname)) {
+ usage();
+ emit("Unable to create group '$groupname' on this machine!\n",
+ "error");
+ return 0;
+ }
+ }
+
+ # Overwrite default value of $pki_group with user-specified $groupname
+ $pki_group = $groupname;
+ }
+
+
+ # At this point in time, ALWAYS check that $pki_group exists!
+ if (!group_exists($pki_group)) {
+ if (!create_group($pki_group)) {
+ usage();
+ emit("Unable to create group '$pki_group' on this machine!\n",
+ "error");
+ return 0;
+ }
+ }
+
+
+ ## Optional "-user=<username>" option
+ if ($username) {
+ if (!$groupname) {
+ usage();
+ emit("Must ALSO specify group ownership using -group!\n",
+ "error");
+ return 0;
+ }
+
+ if (!user_exists($username)) {
+ if (!create_user($username, $groupname)) {
+ usage();
+ emit("Unable to create user '$username' on this machine!\n",
+ "error");
+ return 0;
+ }
+ }
+
+ # Overwrite default value of $pki_user with user-specified $username
+ $pki_user = $username;
+ }
+
+
+ # At this point in time, ALWAYS check that $pki_user exists!
+ if (!user_exists($pki_user)) {
+ if (!create_user($pki_user, $pki_group)) {
+ usage();
+ emit("Unable to create user '$pki_user' on this machine!\n",
+ "error");
+ return 0;
+ }
+ }
+
+
+ # At this point in time, ALWAYS check that shell access for $pki_user is
+ # disallowed; for now, simply notify the user performing the installation
+ # and continue
+ if (!user_disallows_shell($pki_user)) {
+ emit("Please contact your system administrator "
+ . "to disallow shell access for '$pki_user'!\n");
+ }
+
+
+ # At this point in time, ALWAYS check that $pki_user
+ # is a valid member of $pki_group
+ #
+ # NOTE: Uncomment the following code to enforce a strict policy of
+ # requiring $pki_user to be a member of $pki_group . . .
+ #
+ # if (!user_is_a_member_of_group($pki_user, $pki_group)) {
+ # usage();
+ # emit("The user '$pki_user' is NOT a member of group '$pki_group'!\n",
+ # "error");
+ # return 0;
+ # }
+
+
+ # At this point in time, ALWAYS attempt to add $pki_user as a
+ # valid member of $default_nfast_group (presuming one exists)
+ if (group_exists($default_nfast_group)) {
+ # Ignore failures as this should be considered a 'benign' error
+ if (add_user_as_a_member_of_group($pki_user,
+ $default_nfast_group)) {
+ emit("User '$pki_user' is a member of group "
+ . "'$default_nfast_group'.\n");
+ }
+ }
+
+
+ ## Optional "-redirect <dir_name>=<real dir path> ..." option
+ while (my ($key, $value) = each(%redirects)) {
+ if (!is_path_valid($value)) {
+ usage();
+ emit("Illegal redirect directory value: key=$key value="
+ . "$value\n", "error");
+ return 0;
+ }
+
+ if ($key eq "conf") {
+ $redirected_conf_path = $value;
+ emit("setting conf_path $redirected_conf_path\n");
+ } elsif ($key eq "logs") {
+ $redirected_logs_path = $value;
+ emit("setting logs_path $redirected_logs_path\n");
+ } else {
+ usage();
+ emit("Illegal redirect directory key: key=$key value="
+ . "$value\n", "error");
+ return 0;
+ }
+
+ emit("redirect $key => $value\n");
+ }
+
+ ## selinux warning
+ if (($pki_instance_root ne "/var/lib") && ($^O eq "linux")) {
+ print STDOUT <<"EOF";
+WARNING: This utility will attempt to relabel the selinux context of the
+$pki_instance_path directory and the files within it
+as pki_$subsystem_type _var_lib_t
+
+Depending on the location of pki_instance_root and the selinux rules
+currently in place on the system, this may not succeed. In that case, the
+directory may have to be manually relabeled, or selinux will have to be run
+in permissive mode.
+
+It is therefore recommended that the default setting of /var/lib be used
+for pki_instance_root.
+EOF
+
+ASK_CONTINUE_NONSTD_INSTANCE_ROOT:
+
+ my $confirm = prompt("You have chosen the following value for pki_instance_root instead: "
+ . $pki_instance_root
+ . "\nDo you wish to proceed with this value (Y/N)?");
+
+ if ($confirm eq "N" || $confirm eq "n") {
+ return 0;
+ } elsif ($confirm ne "Y" && $confirm ne "y") {
+ goto ASK_CONTINUE_NONSTD_INSTANCE_ROOT;
+ }
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub initialize_subsystem_paths
+{
+ ## Initialize subsystem directory paths (subsystem independent)
+ $conf_subsystem_path = $pki_subsystem_path
+ . "/" . $conf_base_subsystem_dir;
+ $setup_subsystem_path = $pki_subsystem_path
+ . "/" . $setup_base_subsystem_dir;
+
+ $pki_registry_subsystem_path = $pki_registry_path
+ . "/" . $subsystem_type;
+ $pki_registry_subsystem_file_path = $setup_subsystem_path
+ . "/" . $registry_template_base_name;
+
+ $pki_registry_initscript = get_registry_initscript_name($subsystem_type);
+
+ ## systemd subsystem variables
+ $pki_subsystem_systemd_wants_path =
+ "/etc/systemd/system/${pki_registry_initscript}.target.wants";
+ $pki_subsystem_systemd_service_path =
+ "/lib/systemd/system/${pki_registry_initscript}\@.service";
+
+ ## Initialize subsystem directory paths (CA subsystems)
+ if ($subsystem_type eq $CA) {
+ $emails_subsystem_path = $pki_subsystem_path
+ . "/" . $emails_base_subsystem_dir;
+ }
+
+
+ $common_ui_subsystem_path = $pki_subsystem_common_area . "/" .
+ "common-ui";
+ $ui_subsystem_path = $pki_subsystem_path . "-ui";
+
+ ## Initialize subsystem directory paths (RA, TPS subsystems)
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+ if ($subsystem_type eq $TPS) {
+ $applets_subsystem_path = $pki_subsystem_path
+ . "/" . $applets_base_subsystem_dir;
+ $bin_subsystem_path = $default_system_user_libraries
+ . "/" . $pki_flavor
+ . "/" . $subsystem_type;
+ $samples_subsystem_path = $pki_subsystem_path
+ . "/" . $samples_base_subsystem_dir;
+ }
+
+ $lib_subsystem_path = $pki_subsystem_path
+ . "/" . $lib_base_subsystem_dir;
+ $scripts_subsystem_path = $pki_subsystem_path
+ . "/" . $scripts_base_subsystem_dir;
+
+ # Apache Specific
+ if ($subsystem_type eq $TPS) {
+ $cgibin_subsystem_path = $pki_subsystem_path
+ . "/" . $cgibin_base_subsystem_dir;
+ }
+
+ # Apache Specific
+ $docroot_subsystem_path = $pki_subsystem_path
+ . "/" . $docroot_base_subsystem_dir;
+ } else {
+
+ ## Initialize subsystem directory paths (CA, KRA, OCSP, TKS subsystems)
+
+ $profiles_subsystem_path = $pki_subsystem_path
+ . "/" . $profiles_base_subsystem_dir;
+ $webapps_subsystem_path = $pki_subsystem_path
+ . "/" . $webapps_base_subsystem_dir;
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub initialize_instance_paths
+{
+ ## Initialize instance directory paths (instance independent)
+ $alias_instance_path = $pki_instance_path
+ . "/" . $alias_base_instance_dir;
+ $conf_instance_path = $pki_instance_path
+ . "/" . $conf_base_instance_dir;
+ $logs_instance_path = $pki_instance_path
+ . "/" . $logs_base_instance_dir;
+
+
+ ## Initialize the pki registry instance
+ $pki_registry_instance_file_path = $pki_registry_subsystem_path
+ . "/" . $pki_instance_name;
+
+ ## Initialize path to per instance init script
+ $pki_instance_initscript_path = $pki_instance_path
+ . "/" . $pki_instance_name;
+
+ ## Initialize tomcat6 instance conf
+ $tomcat6_conf_instance_file_path = $tomcat6_instance_config_path
+ . "/" . $pki_instance_name;
+ ## Initialize tomcat6 pid file
+ $tomcat6_instance_pid_file_path = $default_tomcat_pids_path
+ . "/" . $pki_instance_name
+ . ".pid";
+
+ ## systemd instance service name
+ $pki_instance_systemd_service_name =
+ "${pki_registry_initscript}\@${pki_instance_name}.service";
+
+ ## Initialize instance directory paths (RA, TPS instances)
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+ if ($subsystem_type eq $TPS) {
+ $bin_instance_path = $pki_instance_path
+ . "/" . $bin_base_instance_dir;
+ }
+
+ $lib_instance_path = $pki_instance_path
+ . "/" . $lib_base_instance_dir;
+ $scripts_instance_path = $pki_instance_path
+ . "/" . $scripts_base_instance_dir;
+
+ # Apache Specific
+ if ($subsystem_type eq $TPS) {
+ $cgibin_instance_path = $pki_instance_path
+ . "/" . $cgibin_base_instance_dir;
+ }
+
+ # Apache Specific
+ $docroot_instance_path = $pki_instance_path
+ . "/" . $docroot_base_instance_dir;
+ } else {
+ ## Initialize instance directory paths (CA, KRA, OCSP, TKS instances)
+ $emails_instance_path = $pki_instance_path
+ . "/" . $emails_base_instance_dir;
+ $profiles_instance_path = $pki_instance_path
+ . "/" . $profiles_base_instance_dir;
+ $webapps_instance_path = $pki_instance_path
+ . "/" . $webapps_base_instance_dir;
+ $webapps_subsystem_instance_path = $webapps_instance_path . "/"
+ . $subsystem_type;
+
+ # Tomcat Specific
+ $shared_instance_path = $pki_instance_path
+ . "/" . $shared_base_instance_dir;
+ $tomcat_instance_common_lib_path = $pki_instance_path
+ . "/" . $tomcat_instance_common_lib_dir;
+ $temp_instance_path = $pki_instance_path
+ . "/" . $temp_base_instance_dir;
+ $work_instance_path = $pki_instance_path
+ . "/" . $work_base_instance_dir;
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub initialize_instance_symlink_paths
+{
+ ## Initialize instance symlinks (instance independent)
+ $conf_instance_symlink_path = $pki_instance_path
+ . "/" . $conf_base_instance_symlink;
+ $logs_instance_symlink_path = $pki_instance_path
+ . "/" . $logs_base_instance_symlink;
+
+
+ ## Initialize instance symlinks (CA instances)
+ # if ($subsystem_type eq $CA) {
+ # }
+
+
+ ## Initialize instance symlinks (RA, TPS instances)
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+ # Apache Specific
+ $run_instance_symlink_path = $pki_instance_path
+ . "/" . $run_base_instance_symlink;
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub initialize_subdirectory_paths
+{
+ ## Initialize subdirectory paths (subsystem independent)
+ $pki_cfg_subsystem_file_path = $conf_subsystem_path
+ . "/" . $pki_cfg_base_name;
+ $pki_piddir_path = $default_apache_pids_path
+ . "/" . $subsystem_type;
+
+ ## Initialize subdirectory paths (CA subsystems)
+ if ($subsystem_type eq $CA) {
+ $profile_select_template_subsystem_file_path = $ui_subsystem_path
+ . "/" . $webapps_base_subsystem_dir
+ . "/" . $subsystem_type
+ . "/ee/" . $subsystem_type
+ . "/" . $profile_select_base_name;
+ $profile_select_template_instance_file_path = $webapps_subsystem_instance_path
+ . "/ee/". $subsystem_type
+ . "/" . $profile_select_base_name;
+
+ $proxy_conf_subsystem_file_path = $conf_subsystem_path
+ . "/" . $proxy_conf_base_name;
+ }
+
+ ## Initialize subdirectory paths (RA, TPS subsystems)
+ if ($subsystem_type eq $TPS) {
+ $cgi_sow_subsystem_file_path = $cgibin_subsystem_path
+ . "/"
+ . $cgi_sow_dir_name;
+ $cgi_sow_instance_cfg_pl_path = $cgibin_instance_path
+ . "/"
+ . $cgi_sow_cfg_pl_name;
+ }
+
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+
+ if ($subsystem_type eq $TPS) {
+
+ $cgi_home_instance_file_path = $cgibin_instance_path
+ . "/"
+ . $cgi_home_base_name;
+ $cgi_home_subsystem_file_path = $cgibin_subsystem_path
+ . "/"
+ . $cgi_home_base_name;
+ $cgi_demo_instance_file_path = $cgibin_instance_path
+ . "/"
+ . $cgi_demo_base_name;
+ $cgi_demo_subsystem_file_path = $cgibin_subsystem_path
+ . "/"
+ . $cgi_demo_base_name;
+ $cgi_so_instance_file_path = $cgibin_instance_path
+ . "/"
+ . $cgi_so_base_name;
+ $cgi_so_subsystem_file_path = $cgibin_subsystem_path
+ . "/"
+ . $cgi_so_base_name;
+ $cgi_so_instance_enroll_file_path = $cgibin_instance_path
+ . "/"
+ . $cgi_so_enroll_name;
+ $cgi_so_subsystem_enroll_file_path = $cgibin_subsystem_path
+ . "/"
+ . $cgi_so_enroll_name;
+ $cgi_sow_instance_file_path = $cgibin_instance_path
+ . "/"
+ . $cgi_sow_dir_name;
+ $addAgents_ldif_instance_file_path = $scripts_instance_path
+ . "/"
+ . $addAgents_ldif_base_name;
+ $addAgents_ldif_subsystem_file_path = $scripts_subsystem_path
+ . "/"
+ . $addAgents_ldif_base_name;
+ $addIndexes_ldif_instance_file_path = $scripts_instance_path
+ . "/"
+ . $addIndexes_ldif_base_name;
+ $addIndexes_ldif_subsystem_file_path = $scripts_subsystem_path
+ . "/"
+ . $addIndexes_ldif_base_name;
+ $addTokens_ldif_instance_file_path = $scripts_instance_path
+ . "/"
+ . $addTokens_ldif_base_name;
+ $addTokens_ldif_subsystem_file_path = $scripts_subsystem_path
+ . "/"
+ . $addTokens_ldif_base_name;
+ $addVLVIndexes_ldif_instance_file_path = $scripts_instance_path
+ . "/"
+ . $addVLVIndexes_ldif_base_name;
+ $addVLVIndexes_ldif_subsystem_file_path = $scripts_subsystem_path
+ . "/"
+ . $addVLVIndexes_ldif_base_name;
+ $schemaMods_ldif_instance_file_path = $scripts_instance_path
+ . "/"
+ . $schemaMods_ldif_base_name;
+ $schemaMods_ldif_subsystem_file_path = $scripts_subsystem_path
+ . "/"
+ . $schemaMods_ldif_base_name;
+ }
+
+ $pki_lockdir_path = $default_lockdir
+ . "/" . $subsystem_type;
+ $pki_apache_initscript_file_path = $pki_subsystem_common_area
+ . "/" . $scripts_base_subsystem_dir
+ . "/" . $pki_apache_initscript_base_name;
+ $nss_pcache_instance_file_path = $scripts_instance_path
+ . "/"
+ . $nss_pcache_base_name;
+ $nss_pcache_subsystem_file_path = $scripts_subsystem_path
+ . "/"
+ . $nss_pcache_base_name;
+ $httpd_conf_subsystem_file_path = $conf_subsystem_path
+ . "/" . $httpd_conf_base_name;
+ $magic_subsystem_file_path = $conf_subsystem_path
+ . "/" . $magic_base_name;
+ $mime_types_subsystem_file_path = $conf_subsystem_path
+ . "/" . $mime_types_base_name;
+ $nss_conf_subsystem_file_path = $conf_subsystem_path
+ . "/" . $nss_conf_base_name;
+ $perl_conf_subsystem_file_path = $conf_subsystem_path
+ . "/" . $perl_conf_base_name;
+ $perl_instance_symlink_path = $lib_instance_path
+ . "/"
+ . $perl_base_instance_symlink;
+ $perl_subsystem_path = $lib_subsystem_path
+ . "/"
+ . $perl_base_subsystem_dir;
+ } else {
+ ## Initialize subdirectory paths (CA, KRA, OCSP, TKS subsystems)
+
+ $pki_subsystem_jar_base_name = "pki-${subsystem_type}.jar";
+
+ if (!defined($pki_certsrv_jar_file_path = find_jar($pki_certsrv_jar_base_name))) {
+ emit("could not find jar: $pki_certsrv_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($pki_cms_jar_file_path = find_jar($pki_cms_jar_base_name))) {
+ emit("could not find jar: $pki_cms_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($pki_cmsbundle_jar_file_path = find_jar($pki_cmsbundle_jar_base_name))) {
+ emit("could not find jar: $pki_cmsbundle_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($pki_cmscore_jar_file_path = find_jar($pki_cmscore_jar_base_name))) {
+ emit("could not find jar: $pki_cmscore_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($pki_cmsutil_jar_file_path = find_jar($pki_cmsutil_jar_base_name))) {
+ emit("could not find jar: $pki_cmsutil_jar_base_name", "error");
+ return 0;
+ }
+
+ # jakarta-commons-* has been renamed to apache-commons-* on some
+ # systems, search which one is available, preferring apache-commons
+ if (defined($commons_collections_jar_file_path = find_jar($apache_commons_collections_jar_base_name))) {
+ $commons_collections_jar_base_name = $apache_commons_collections_jar_base_name;
+ } else {
+ if (defined($commons_collections_jar_file_path = find_jar($jakarta_commons_collections_jar_base_name))) {
+ $commons_collections_jar_base_name = $jakarta_commons_collections_jar_base_name;
+ } else {
+ emit("could not find jar: $apache_commons_collections_jar_base_name or $jakarta_commons_collections_jar_base_name", "error");
+ return 0;
+ }
+ }
+
+ if (defined($commons_lang_jar_file_path = find_jar($apache_commons_lang_jar_base_name))) {
+ $commons_lang_jar_base_name = $apache_commons_lang_jar_base_name;
+ } else {
+ if (defined($commons_lang_jar_file_path = find_jar($jakarta_commons_lang_jar_base_name))) {
+ $commons_lang_jar_base_name = $jakarta_commons_lang_jar_base_name;
+ } else {
+ emit("could not find jar: $apache_commons_lang_jar_base_name or $jakarta_commons_lang_jar_base_name", "error");
+ return 0;
+ }
+ }
+
+ if (defined($commons_logging_jar_file_path = find_jar($apache_commons_logging_jar_base_name))) {
+ $commons_logging_jar_base_name = $apache_commons_logging_jar_base_name;
+ } else {
+ if (defined($commons_logging_jar_file_path = find_jar($jakarta_commons_logging_jar_base_name))) {
+ $commons_logging_jar_base_name = $jakarta_commons_logging_jar_base_name;
+ } else {
+ emit("could not find jar: $apache_commons_logging_jar_base_name or $jakarta_commons_logging_jar_base_name", "error");
+ return 0;
+ }
+ }
+
+ if (!defined($jss_jar_file_path = find_jar($jss_jar_base_name))) {
+ emit("could not find jar: $jss_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($ldapjdk_jar_file_path = find_jar($ldapjdk_jar_base_name))) {
+ emit("could not find jar: $ldapjdk_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($pki_nsutil_jar_file_path = find_jar($pki_nsutil_jar_base_name))) {
+ emit("could not find jar: $pki_nsutil_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($commons_codec_jar_file_path = find_jar($commons_codec_jar_base_name))) {
+ emit("could not find jar: $commons_codec_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($pki_subsystem_jar_file_path = find_jar($pki_subsystem_jar_base_name))) {
+ emit("could not find jar: $pki_subsystem_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($symkey_jar_file_path = find_jar($symkey_jar_base_name))) {
+ emit("could not find jar: $symkey_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($tomcatjss_jar_file_path = find_jar($tomcatjss_jar_base_name))) {
+ emit("could not find jar: $tomcatjss_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($velocity_jar_file_path = find_jar($velocity_jar_base_name))) {
+ emit("could not find jar: $velocity_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($xerces_jar_file_path = find_jar($xerces_jar_base_name))) {
+ emit("could not find jar: $xerces_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($xml_commons_apis_jar_file_path = find_jar($xml_commons_apis_jar_base_name))) {
+ emit("could not find jar: $xml_commons_apis_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($xml_commons_resolver_jar_file_path = find_jar($xml_commons_resolver_jar_base_name))) {
+ emit("could not find jar: $xml_commons_resolver_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($javassist_jar_file_path = find_jar($javassist_jar_base_name))) {
+ emit("could not find jar: $javassist_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($jaxrs_api_jar_file_path = find_jar($jaxrs_api_jar_base_name))) {
+ emit("could not find jar: $jaxrs_api_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($resteasy_jaxb_provider_jar_file_path = find_jar($resteasy_jaxb_provider_jar_base_name))) {
+ emit("could not find jar: $resteasy_jaxb_provider_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($resteasy_jaxrs_jar_file_path = find_jar($resteasy_jaxrs_jar_base_name))) {
+ emit("could not find jar: $resteasy_jaxrs_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($scannotation_jar_file_path = find_jar($scannotation_jar_base_name))) {
+ emit("could not find jar: $scannotation_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($resteasy_jettison_provider_jar_file_path = find_jar($resteasy_jettison_provider_jar_base_name))) {
+ emit("could not find jar: $resteasy_jettison_provider_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($jettison_jar_file_path = find_jar($jettison_jar_base_name))) {
+ emit("could not find jar: $jettison_jar_base_name", "error");
+ return 0;
+ }
+
+ $webinf_instance_path = $webapps_instance_path
+ . "/" . $subsystem_type
+ . "/" . $webinf_base_instance_dir;
+ $webinf_subsystem_path = $webapps_subsystem_path
+ . "/" . $subsystem_type
+ . "/" . $webinf_base_instance_dir;
+ $webinf_lib_instance_path = $webinf_instance_path
+ . "/" . $lib_base_instance_dir;
+ $webapps_root_subsystem_path = $webapps_subsystem_path
+ . "/"
+ . $webapps_root_base_subsystem_dir;
+ $webapps_subsystem_instance_path = $webapps_instance_path
+ . "/" . $subsystem_type;
+
+ $pki_certsrv_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $pki_certsrv_jar_base_name;
+ $pki_cms_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $pki_cms_jar_base_name;
+ $pki_cmsbundle_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $pki_cmsbundle_jar_base_name;
+ $pki_cmscore_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $pki_cmscore_jar_base_name;
+ $pki_cmsutil_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $pki_cmsutil_jar_base_name;
+ $commons_collections_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $commons_collections_jar_base_name;
+ $commons_lang_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $commons_lang_jar_base_name;
+ $commons_logging_jar_symlink_path = $tomcat_instance_common_lib_path
+ . "/" . $commons_logging_jar_base_name;
+ $jss_jar_symlink_path = $tomcat_instance_common_lib_path
+ . "/" . $jss_jar_base_name;
+ $ldapjdk_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $ldapjdk_jar_base_name;
+ $pki_nsutil_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $pki_nsutil_jar_base_name;
+ $commons_codec_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $commons_codec_jar_base_name;
+ $symkey_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $symkey_jar_base_name;
+ $pki_subsystem_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $pki_subsystem_jar_base_name;
+ $tomcatjss_jar_symlink_path = $tomcat_instance_common_lib_path
+ . "/" . $tomcatjss_jar_base_name;
+ $velocity_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $velocity_jar_base_name;
+ $xerces_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $xerces_jar_base_name;
+ $xml_commons_apis_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $xml_commons_apis_jar_base_name;
+ $xml_commons_resolver_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $xml_commons_resolver_jar_base_name;
+
+ #resteasy
+ $javassist_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $javassist_jar_base_name;
+ $jaxrs_api_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $jaxrs_api_jar_base_name;
+ $resteasy_jaxb_provider_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $resteasy_jaxb_provider_jar_base_name;
+ $resteasy_jaxrs_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $resteasy_jaxrs_jar_base_name;
+ $scannotation_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $scannotation_jar_base_name;
+ $resteasy_jettison_provider_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $resteasy_jettison_provider_jar_base_name;
+ $jettison_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $jettison_jar_base_name;
+
+
+ $webapps_root_instance_path = $webapps_instance_path
+ . "/"
+ . $webapps_root_base_instance_dir;
+ $index_jsp_instance_file_path = $webapps_root_instance_path
+ . "/" . $index_jsp_base_name;
+ $index_jsp_subsystem_file_path = $webapps_root_subsystem_path
+ . "/" . $index_jsp_base_name;
+ $server_xml_subsystem_file_path = $conf_subsystem_path
+ . "/" . $server_xml_base_name;
+ $servercertnick_conf_subsystem_file_path = $conf_subsystem_path
+ . "/" . $servercertnick_conf_base_name;
+ $tomcat6_conf_subsystem_file_path = $conf_subsystem_path
+ . "/" . $tomcat6_conf_base_name;
+ $velocity_prop_instance_file_path = $webinf_instance_path
+ . "/" . $velocity_prop_base_name;
+ $velocity_prop_subsystem_file_path = $webinf_subsystem_path
+ . "/" . $velocity_prop_base_name;
+ $web_xml_instance_file_path = $webinf_instance_path
+ . "/" . $web_xml_base_name;
+ $web_xml_subsystem_file_path = $webinf_subsystem_path
+ . "/" . $web_xml_base_name;
+ $catalina_properties_subsystem_file_path = $conf_subsystem_path
+ . "/" . $catalina_properties_base_name;
+ }
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub initialize_paths
+{
+ return 0 if !initialize_subsystem_paths();
+ return 0 if !initialize_instance_paths();
+ return 0 if !initialize_instance_symlink_paths();
+ return 0 if !initialize_subdirectory_paths();
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub initialize_pki_creation_values
+{
+ # obtain the fully-qualified domain name of this host
+ $host = get_FQDN($hostname);
+
+ # we need the certdb password generated now ...
+ $db_password = generate_random($db_password_low, $db_password_high);
+
+ # generate a random value for a pin ...
+ $random = generate_random_string(20);
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub process_pki_directories
+{
+ my $remove_dir="";
+
+ emit("Processing PKI directories for '$pki_instance_path' ...\n");
+
+ ## Populate instance directory paths (instance independent)
+ return 0 if !create_directory($alias_instance_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ # Check for an optionally redirected "conf" directory path ...
+ if (!$redirected_conf_path) {
+ $noise_instance_file_path = $conf_instance_path
+ . "/" . $noise_base_name;
+ $password_conf_instance_file_path = $conf_instance_path
+ . "/" . $password_conf_base_name;
+ $pfile_instance_file_path = $conf_instance_path
+ . "/" . $pfile_base_name;
+ $pki_cfg_instance_file_path = $conf_instance_path
+ . "/" . $pki_cfg_base_name;
+ $proxy_conf_instance_file_path = $conf_instance_path
+ . "/" . $proxy_conf_base_name;
+ $catalina_properties_instance_file_path = $conf_instance_path
+ . "/" . $catalina_properties_base_name;
+
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+ $httpd_conf_instance_file_path = $conf_instance_path
+ . "/" . $httpd_conf_base_name;
+ $magic_instance_file_path = $conf_instance_path
+ . "/" . $magic_base_name;
+ $mime_types_instance_file_path = $conf_instance_path
+ . "/" . $mime_types_base_name;
+ $nss_conf_instance_file_path = $conf_instance_path
+ . "/" . $nss_conf_base_name;
+ $perl_conf_instance_file_path = $conf_instance_path
+ . "/" . $perl_conf_base_name;
+ $pwcache_conf_instance_file_path = $conf_instance_path
+ . "/" . $pwcache_conf_base_name;
+
+ # create instance directory
+ return 0 if !create_directory($conf_instance_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ # only copy selected files
+ return 0 if !copy_file($magic_subsystem_file_path, $magic_instance_file_path,
+ $default_file_permissions, $pki_user, $pki_group);
+
+ return 0 if !copy_file($mime_types_subsystem_file_path, $mime_types_instance_file_path,
+ $default_file_permissions, $pki_user, $pki_group);
+
+ } else {
+ $server_xml_instance_file_path = $conf_instance_path
+ . "/" . $server_xml_base_name;
+ $servercertnick_conf_instance_file_path = $conf_instance_path
+ . "/" . $servercertnick_conf_base_name;
+
+ return 0 if !copy_directory($conf_subsystem_path, $conf_instance_path,
+ $default_dir_permissions, $default_file_permissions,
+ $pki_user, $pki_group);
+ }
+ } else {
+ $noise_instance_file_path = $redirected_conf_path
+ . "/" . $noise_base_name;
+ $password_conf_instance_file_path = $redirected_conf_path
+ . "/" . $password_conf_base_name;
+ $pfile_instance_file_path = $redirected_conf_path
+ . "/" . $pfile_base_name;
+ $pki_cfg_instance_file_path = $redirected_conf_path
+ . "/" . $pki_cfg_base_name;
+ $proxy_conf_instance_file_path = $redirected_conf_path
+ . "/" . $proxy_conf_base_name;
+ $catalina_properties_instance_file_path = $redirected_conf_path
+ . "/" . $catalina_properties_base_name;
+
+ # Populate optionally redirected instance directory path
+ # and setup a symlink in the standard area
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+ $httpd_conf_instance_file_path = $redirected_conf_path
+ . "/" . $httpd_conf_base_name;
+ $magic_instance_file_path = $redirected_conf_path
+ . "/" . $magic_base_name;
+ $mime_types_instance_file_path = $redirected_conf_path
+ . "/" . $mime_types_base_name;
+ $nss_conf_instance_file_path = $redirected_conf_path
+ . "/" . $nss_conf_base_name;
+ $perl_conf_instance_file_path = $redirected_conf_path
+ . "/" . $perl_conf_base_name;
+ $pwcache_conf_instance_file_path = $redirected_conf_path
+ . "/" . $pwcache_conf_base_name;
+
+ # create redirected instance directory
+ return 0 if !create_directory($redirected_conf_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ # only copy selected files
+ return 0 if !copy_file($magic_subsystem_file_path, $magic_instance_file_path,
+ $default_file_permissions, $pki_user, $pki_group);
+
+ return 0 if !copy_file($mime_types_subsystem_file_path, $mime_types_instance_file_path,
+ $default_file_permissions, $pki_user, $pki_group);
+
+ } else {
+ $server_xml_instance_file_path = $redirected_conf_path
+ . "/" . $server_xml_base_name;
+ $servercertnick_conf_instance_file_path = $redirected_conf_path
+ . "/" . $servercertnick_conf_base_name;
+
+ return 0 if !copy_directory($conf_subsystem_path, $redirected_conf_path,
+ $default_dir_permissions, $default_file_permissions,
+ $pki_user, $pki_group);
+ }
+
+ return 0 if !create_symlink($conf_instance_symlink_path, $redirected_conf_path,
+ $pki_user, $pki_group);
+
+ }
+
+
+ # Check for an optionally redirected "logs" directory path ...
+ if (!$redirected_logs_path) {
+ # create instance directory
+ return 0 if !create_directory(${logs_instance_path},
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ ## (CA, KRA, OCSP, TKS, TPS instances)
+ if ($subsystem_type ne $RA) {
+ ## Create a "signedAudit" directory
+ return 0 if !create_directory("${logs_instance_path}/${signed_audit_base_instance_dir}",
+ $default_dir_permissions, $pki_user, $pki_group);
+ }
+ } else {
+ # create redirected instance directory
+ # and setup a symlink in the standard area
+ return 0 if !create_directory($redirected_logs_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ ## (CA, KRA, OCSP, TKS, TPS instances)
+ if ($subsystem_type ne $RA) {
+ ## Create a "signedAudit" directory
+ return 0 if !create_directory("${redirected_logs_path}/${signed_audit_base_instance_dir}",
+ $default_dir_permissions, $pki_user, $pki_group);
+ }
+
+ return 0 if !create_symlink($logs_instance_symlink_path, $redirected_logs_path,
+ $pki_user, $pki_group);
+
+ return 0 if !set_owner_group_on_directory_contents($redirected_logs_path, $pki_user, $pki_group);
+ }
+
+
+ ## Populate pki instance registry
+ # create pki registry for this subsystem
+ return 0 if !create_directory($pki_registry_subsystem_path,
+ $default_dir_permissions, $pki_user, $pki_group, 'preserve');
+
+
+ ## Populate instance directory paths (CA instances)
+ if ($subsystem_type eq $CA) {
+ return 0 if !copy_directory($emails_subsystem_path, $emails_instance_path,
+ $default_dir_permissions, $default_file_permissions,
+ $pki_user, $pki_group);
+
+ return 0 if !copy_directory($profiles_subsystem_path, $profiles_instance_path,
+ $default_dir_permissions, $default_file_permissions,
+ $pki_user, $pki_group);
+ }
+
+
+ ## Populate instance directory paths (RA, TPS instances)
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+
+ if ($subsystem_type eq $TPS) {
+ return 0 if !create_directory($bin_instance_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+ }
+
+ return 0 if !create_directory($lib_instance_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ return 0 if !create_directory($scripts_instance_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ # Apache Specific
+ if ($subsystem_type eq $TPS) {
+ return 0 if !copy_directory($cgibin_subsystem_path, $cgibin_instance_path,
+ $default_dir_permissions, $default_file_permissions,
+ $pki_user, $pki_group);
+ }
+
+ # Apache Specific
+ return 0 if !copy_directory($docroot_subsystem_path, $docroot_instance_path,
+ $default_dir_permissions, $default_file_permissions,
+ $pki_user, $pki_group);
+
+
+ return 0 if !copy_directory($ui_subsystem_path, $pki_instance_path,
+ $default_dir_permissions, $default_file_permissions,
+ $pki_user, $pki_group);
+
+ # fix permissions
+ if (!is_Windows()) {
+ # Apache Specific
+ if ($subsystem_type eq $TPS) {
+ set_permissions("${cgibin_instance_path}/demo", $default_dir_permissions);
+ set_permissions("${cgibin_instance_path}/demo/*.cgi", $default_exe_permissions);
+ set_permissions("${cgibin_instance_path}/demo/*.html", $default_file_permissions);
+ set_permissions("${cgibin_instance_path}/home", $default_dir_permissions);
+ set_permissions("${cgibin_instance_path}/home/*.cgi", $default_exe_permissions);
+ set_permissions("${cgibin_instance_path}/home/*.html", $default_file_permissions);
+ set_permissions("${cgibin_instance_path}/so", $default_dir_permissions);
+ set_permissions("${cgibin_instance_path}/so/*.cgi", $default_exe_permissions);
+ set_permissions("${cgibin_instance_path}/so/*.html", $default_file_permissions);
+ set_permissions("${cgibin_instance_path}/sow", $default_dir_permissions);
+ set_permissions("${cgibin_instance_path}/sow/*.cgi", $default_exe_permissions);
+ set_permissions("${cgibin_instance_path}/sow/*.html", $default_file_permissions);
+ set_permissions("${cgibin_instance_path}/sow/*.pl", $default_exe_permissions);
+ set_permissions("${docroot_instance_path}/", $default_dir_permissions);
+ set_permissions("${docroot_instance_path}/*.cgi", $default_exe_permissions);
+ }
+ }
+ } else {
+ ## Populate instance directory paths (CA, KRA, OCSP, TKS instances)
+ return 0 if !copy_directory($webapps_subsystem_path, $webapps_instance_path,
+ $default_dir_permissions, $default_file_permissions,
+ $pki_user, $pki_group);
+
+ return 0 if !copy_directory($common_ui_subsystem_path, $webapps_subsystem_instance_path,
+ $default_dir_permissions, $default_file_permissions,
+ $pki_user, $pki_group);
+
+ return 0 if !copy_directory($ui_subsystem_path, $pki_instance_path,
+ $default_dir_permissions, $default_file_permissions,
+ $pki_user, $pki_group);
+
+ ## Tomcat Specific
+ return 0 if !create_directory($shared_instance_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ return 0 if !create_directory("$shared_instance_path/classes",
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ return 0 if !create_directory("$shared_instance_path/lib",
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ return 0 if !create_directory($tomcat_instance_common_lib_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ return 0 if !create_directory($temp_instance_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ return 0 if !create_directory($work_instance_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+ }
+
+ ## Set appropriate permissions
+ return 0 if !set_owner_group_on_directory_contents($pki_instance_path, $pki_user, $pki_group);
+
+ return 1;
+}
+
+
+# process_file_template
+#
+# template_name
+# Used to identify the template.
+# src_path
+# The file pathname of the template.
+# dst_path
+# The file pathname the processed template will be written to.
+# substitutions
+# Pointer to a hash. Each key is a substitution name, the key's
+# value is the string to substitute.
+#
+# Given a template file, read it's contents in. Then perform text
+# replacements on any string of the form "[name]". name will be used
+# as a key in the substitutions hash, if the key exists in the hash then
+# it's value will replace the string "[name]".
+#
+# Example, if the src template contained this line:
+#
+# Open port [PORT] on your firewall.
+#
+# And the substitutions hash was this {'PORT' => '1234'}
+#
+# Then the dst file contents will look like this:
+#
+# Open port 1234 on your firewall.
+#
+# Return 1 if success, 0 if failure
+
+sub process_file_template
+{
+ my ($template_name, $src_path, $dst_path, $substitutions) = @_;
+
+ my $buf = "";
+ my $num_subs = 0;
+ my $total_subs = 0;
+ my @keys;
+ my $key;
+ my $value;
+ emit(" Template ($template_name) \"${src_path}\" ==> \"${dst_path}\" ...\n");
+
+ # Check for a valid source file
+ if (!is_path_valid($src_path)) {
+ emit("process_file_template(): invalid source path ${src_path}!\n", "error");
+ return 0;
+ }
+
+ # Check for a valid destination file
+ if (!is_path_valid($dst_path)) {
+ emit("process_file_template(): invalid destination path ${dst_path}!\n", "error");
+ return 0;
+ }
+
+ # Read in contents of source file
+ $buf = read_file($src_path);
+
+ # Process each line substituting each [KEY]
+ # with its corresponding slot hash value
+ @keys = sort(keys %$substitutions);
+ foreach $key (@keys) {
+ $value = $substitutions->{$key};
+ # Perform global substitution on buffer and
+ # get count of how many substitutions were actually performed.
+ $num_subs = $buf =~ s/\[$key\]/$value/g;
+ $total_subs += $num_subs;
+
+ # If any substitutions were performed then log what was done.
+ if ($num_subs > 0) {
+ # Hide sensitive information by emitting the word "(sensitive)"
+ # rather rather than the substituted value.
+ if ($key eq $PKI_CERT_DB_PASSWORD_SLOT) {
+ emit(sprintf(" %3d substitutions: %s ==> (sensitive)\n", $num_subs, $key));
+ } else {
+ emit(sprintf(" %3d substitutions: %s ==> \"%s\"\n", $num_subs, $key, $value));
+ }
+ }
+ }
+
+ emit(" $total_subs substitutions were made in '$dst_path'\n");
+
+ # Sanity check, are there any strings left in the buffer which look
+ # like a substitution.
+ foreach my $match ($buf =~ /\[[A-Z_]+\]/g) {
+ emit("WARNING: Possible missed substitution \"$match\" in $src_path");
+ }
+
+ # Record that we've installed this file.
+ add_install_info($dst_path, 'file');
+
+ if ($verbose >= 2) {
+ # For debugging, emit the contents after substitution.
+ emit(sprintf(">> $dst_path\n%s<< $dst_path\n", $buf));
+ }
+
+ if (!$dry_run) {
+ # Write out these modified contents to the destination file.
+ write_file($dst_path, \$buf);
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub process_pki_templates
+{
+ my $use_port_separation = 0;
+ if ($agent_secure_port >= 0 &&
+ ($subsystem_type ne $RA) &&
+ ($subsystem_type ne $TPS)) {
+ $use_port_separation = 1;
+ }
+
+ my %slot_hash = ();
+
+ emit("Processing PKI templates for '$pki_instance_path' ...\n");
+
+ $slot_hash{$PKI_SUBSYSTEM_TYPE_SLOT} = $subsystem_type;
+ $slot_hash{$PKI_INSTANCE_ID_SLOT} = $pki_instance_name;
+ $slot_hash{$PKI_INSTANCE_ROOT_SLOT} = $pki_instance_root;
+ $slot_hash{$PKI_INSTANCE_INITSCRIPT} = $pki_instance_initscript_path;
+ $slot_hash{$PKI_REGISTRY_FILE_SLOT} = $pki_registry_instance_file_path;
+ $slot_hash{$PKI_USER_SLOT} = $pki_user;
+ $slot_hash{$PKI_GROUP_SLOT} = $pki_group;
+ $slot_hash{$PKI_PIDDIR} = $pki_piddir_path;
+
+ if ($subsystem_type eq $TPS) {
+ $slot_hash{$REQUIRE_CFG_PL} = "require \"${cgi_sow_instance_cfg_pl_path}\";";
+ }
+
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+ # Setup templates (RA, TPS)
+ $slot_hash{$HTTPD_CONF} = $httpd_conf_instance_file_path;
+ $slot_hash{$LIB_PREFIX} = $lib_prefix;
+ $slot_hash{$NSS_CONF} = $nss_conf_instance_file_path;
+ $slot_hash{$OBJ_EXT} = $obj_ext;
+ $slot_hash{$PORT} = $unsecure_port;
+ $slot_hash{$PROCESS_ID} = $$;
+ $slot_hash{$SECURE_PORT} = $secure_port;
+ $slot_hash{$NON_CLIENTAUTH_SECURE_PORT} = $non_clientauth_secure_port;
+ $slot_hash{$SECURITY_LIBRARIES} = $default_security_libraries;
+ $slot_hash{$SERVER_NAME} = $host;
+ $slot_hash{$SERVER_ROOT} = $pki_instance_path;
+ $slot_hash{$SYSTEM_LIBRARIES} = $default_system_libraries;
+ $slot_hash{$SYSTEM_USER_LIBRARIES} = $default_system_user_libraries;
+ $slot_hash{$TMP_DIR} = $tmp_dir;
+ $slot_hash{$TPS_DIR} = $pki_subsystem_path;
+ $slot_hash{$PKI_FLAVOR_SLOT} = $pki_flavor;
+ $slot_hash{$PKI_RANDOM_NUMBER_SLOT} = $random;
+ $slot_hash{$PKI_LOCKDIR} = $pki_lockdir_path;
+ if (is_Fedora() || (is_RHEL() && (! is_RHEL4()))) {
+ $slot_hash{$FORTITUDE_APACHE} = "Apache2";
+ $slot_hash{$FORTITUDE_DIR} = "/usr";
+ $slot_hash{$FORTITUDE_LIB_DIR} = "/etc/httpd";
+ $slot_hash{$FORTITUDE_MODULE} = "/etc/httpd/modules";
+ $slot_hash{$FORTITUDE_AUTH_MODULES} =
+"
+LoadModule auth_basic_module /etc/httpd/modules/mod_auth_basic.so
+LoadModule authn_file_module /etc/httpd/modules/mod_authn_file.so
+LoadModule authz_user_module /etc/httpd/modules/mod_authz_user.so
+LoadModule authz_groupfile_module /etc/httpd/modules/mod_authz_groupfile.so
+LoadModule authz_host_module /etc/httpd/modules/mod_authz_host.so
+";
+ $slot_hash{$FORTITUDE_NSS_MODULES} =
+"
+LoadModule nss_module /etc/httpd/modules/libmodnss.so
+";
+ }
+ else {
+ $slot_hash{$FORTITUDE_APACHE} = "Apache";
+ $slot_hash{$FORTITUDE_DIR} = "/opt/fortitude";
+ $slot_hash{$FORTITUDE_LIB_DIR} = "/opt/fortitude";
+ $slot_hash{$FORTITUDE_MODULE} = "/opt/fortitude/modules.local";
+ $slot_hash{$FORTITUDE_AUTH_MODULES} =
+"
+LoadModule auth_module /opt/fortitude/modules/mod_auth.so
+LoadModule access_module /opt/fortitude/modules/mod_access.so
+";
+ $slot_hash{$FORTITUDE_NSS_MODULES} =
+"
+LoadModule nss_module /opt/fortitude/modules.local/libmodnss.so
+";
+ }
+ } else {
+ # Setup templates (CA, KRA, OCSP, TKS)
+ $slot_hash{$INSTALL_TIME} = localtime;
+ $slot_hash{$PKI_CERT_DB_PASSWORD_SLOT} = $db_password;
+ $slot_hash{$PKI_CFG_PATH_NAME_SLOT} = $pki_cfg_instance_file_path;
+ $slot_hash{$PKI_INSTANCE_PATH_SLOT} = $pki_instance_path;
+ $slot_hash{$PKI_MACHINE_NAME_SLOT} = $host;
+ $slot_hash{$PKI_RANDOM_NUMBER_SLOT} = $random;
+ $slot_hash{$PKI_SERVER_XML_CONF} = $server_xml_instance_file_path;
+ $slot_hash{$PKI_UNSECURE_PORT_SLOT} = $unsecure_port;
+
+ if ($use_systemd) {
+ $slot_hash{$PKI_SYSTEMD_SERVICENAME_SLOT} = $pki_instance_systemd_service_name;
+ } else {
+ $slot_hash{$PKI_SYSTEMD_SERVICENAME_SLOT} = "";
+ }
+
+ # Define "Port Separation" (default) versus "Shared Ports" (legacy)
+ if ($use_port_separation) {
+ # Establish "Port Separation" Connector Names
+ $slot_hash{$PKI_UNSECURE_PORT_CONNECTOR_NAME_SLOT} = $PKI_UNSECURE_PORT_NAME;
+ $slot_hash{$PKI_SECURE_PORT_CONNECTOR_NAME_SLOT} = $PKI_AGENT_SECURE_PORT_NAME;
+ $slot_hash{$PKI_ADMIN_SECURE_PORT_CONNECTOR_NAME_SLOT} = $PKI_ADMIN_SECURE_PORT_NAME;
+ $slot_hash{$PKI_EE_SECURE_PORT_CONNECTOR_NAME_SLOT} = $PKI_EE_SECURE_PORT_NAME;
+ $slot_hash{$PKI_EE_SECURE_CLIENT_AUTH_PORT_CONNECTOR_NAME_SLOT} = $PKI_EE_SECURE_CLIENT_AUTH_PORT_NAME;
+
+ # Establish "Port Separation" Connector Ports
+ $slot_hash{$PKI_SECURE_PORT_SLOT} = $agent_secure_port;
+ $slot_hash{$PKI_AGENT_SECURE_PORT_SLOT} = $agent_secure_port;
+ $slot_hash{$PKI_EE_SECURE_PORT_SLOT} = $ee_secure_port;
+ $slot_hash{$PKI_EE_SECURE_CLIENT_AUTH_PORT_SLOT} = $ee_secure_client_auth_port;
+ $slot_hash{$PKI_EE_SECURE_CLIENT_AUTH_PORT_UI_SLOT} = $ee_secure_client_auth_port;
+ $slot_hash{$PKI_ADMIN_SECURE_PORT_SLOT} = $admin_secure_port;
+
+ # Comment "Port Separation" appropriately
+ $slot_hash{$PKI_UNSECURE_PORT_COMMENT_SERVER_SLOT} = $PKI_UNSECURE_SEPARATE_PORTS_COMMENT;
+ $slot_hash{$PKI_SECURE_PORT_COMMENT_SERVER_SLOT} = $PKI_AGENT_SECURE_SEPARATE_PORTS_COMMENT;
+ $slot_hash{$PKI_ADMIN_SECURE_PORT_COMMENT_SERVER_SLOT} = $PKI_ADMIN_SECURE_SEPARATE_PORTS_COMMENT;
+ $slot_hash{$PKI_EE_SECURE_PORT_COMMENT_SERVER_SLOT} = $PKI_EE_SECURE_SEPARATE_PORTS_COMMENT;
+ $slot_hash{$PKI_EE_SECURE_CLIENT_AUTH_PORT_COMMENT_SERVER_SLOT} = $PKI_EE_SECURE_CLIENT_AUTH_SEPARATE_PORTS_COMMENT;
+
+ # Set appropriate "clientAuth" parameter for "Port Separation"
+ $slot_hash{$PKI_AGENT_CLIENTAUTH_SLOT} = "true";
+
+ # Do NOT comment out the "Admin/EE" Ports
+ $slot_hash{$PKI_OPEN_SEPARATE_PORTS_COMMENT_SERVER_SLOT} = "";
+ $slot_hash{$PKI_CLOSE_SEPARATE_PORTS_COMMENT_SERVER_SLOT} = "";
+
+ # Do NOT comment out the "Admin/Agent/EE" Filters
+ # used by Port Separation
+ $slot_hash{$PKI_OPEN_SEPARATE_PORTS_COMMENT_WEB_SLOT} = "";
+ $slot_hash{$PKI_CLOSE_SEPARATE_PORTS_COMMENT_WEB_SLOT} = "";
+ } else {
+ # Establish "Shared Ports" Connector Names
+ $slot_hash{$PKI_UNSECURE_PORT_CONNECTOR_NAME_SLOT} = $PKI_UNSECURE_PORT_NAME;
+ $slot_hash{$PKI_SECURE_PORT_CONNECTOR_NAME_SLOT} = $PKI_SECURE_PORT_NAME;
+ $slot_hash{$PKI_ADMIN_SECURE_PORT_CONNECTOR_NAME_SLOT} = $PKI_UNUSED_SECURE_PORT_NAME;
+ $slot_hash{$PKI_EE_SECURE_PORT_CONNECTOR_NAME_SLOT} = $PKI_UNUSED_SECURE_PORT_NAME;
+ $slot_hash{$PKI_EE_SECURE_CLIENT_AUTH_PORT_CONNECTOR_NAME_SLOT} = $PKI_UNUSED_SECURE_PORT_NAME;
+
+ # Establish "Shared Ports" Connector Ports
+ $slot_hash{$PKI_SECURE_PORT_SLOT} = $secure_port;
+ $slot_hash{$PKI_AGENT_SECURE_PORT_SLOT} = $secure_port;
+ $slot_hash{$PKI_EE_SECURE_PORT_SLOT} = $secure_port;
+ $slot_hash{$PKI_EE_SECURE_CLIENT_AUTH_PORT_SLOT} = $secure_port;
+ $slot_hash{$PKI_EE_SECURE_CLIENT_AUTH_PORT_UI_SLOT} = $secure_port;
+ $slot_hash{$PKI_ADMIN_SECURE_PORT_SLOT} = $secure_port;
+
+ # Comment "Shared Ports" appropriately
+ $slot_hash{$PKI_UNSECURE_PORT_COMMENT_SERVER_SLOT} = $PKI_UNSECURE_SHARED_PORTS_COMMENT;
+ $slot_hash{$PKI_SECURE_PORT_COMMENT_SERVER_SLOT} = $PKI_SECURE_SHARED_PORTS_COMMENT;
+ $slot_hash{$PKI_ADMIN_SECURE_PORT_COMMENT_SERVER_SLOT} = "";
+ $slot_hash{$PKI_EE_SECURE_PORT_COMMENT_SERVER_SLOT} = "";
+ $slot_hash{$PKI_EE_SECURE_CLIENT_AUTH_PORT_COMMENT_SERVER_SLOT} = "";
+
+ # Set appropriate "clientAuth" parameter for "Shared Ports"
+ $slot_hash{$PKI_AGENT_CLIENTAUTH_SLOT} = "agent";
+
+ # Comment out the "Admin/EE" Ports
+ $slot_hash{$PKI_OPEN_SEPARATE_PORTS_COMMENT_SERVER_SLOT} = $PKI_OPEN_COMMENT;
+ $slot_hash{$PKI_CLOSE_SEPARATE_PORTS_COMMENT_SERVER_SLOT} = $PKI_CLOSE_COMMENT;;
+
+ # Comment out the "Admin/Agent/EE" Filters
+ $slot_hash{$PKI_OPEN_SEPARATE_PORTS_COMMENT_WEB_SLOT} = $PKI_OPEN_COMMENT;
+ $slot_hash{$PKI_CLOSE_SEPARATE_PORTS_COMMENT_WEB_SLOT} = $PKI_CLOSE_COMMENT;
+ }
+
+ if ($enable_proxy) {
+ if ($use_port_separation) {
+ $slot_hash{$PKI_AJP_REDIRECT_PORT_SLOT} = $ee_secure_port;
+ } else {
+ $slot_hash{$PKI_AJP_REDIRECT_PORT_SLOT} = $secure_port;
+ }
+ $slot_hash{$PKI_EE_SECURE_CLIENT_AUTH_PORT_UI_SLOT} = $proxy_secure_port;
+ $slot_hash{$PKI_AJP_PORT_SLOT} = $ajp_port;
+ $slot_hash{$PKI_OPEN_AJP_PORT_COMMENT_SLOT} = "";
+ $slot_hash{$PKI_CLOSE_AJP_PORT_COMMENT_SLOT} = "";
+ $slot_hash{$PKI_OPEN_ENABLE_PROXY_COMMENT_SLOT} = "";
+ $slot_hash{$PKI_CLOSE_ENABLE_PROXY_COMMENT_SLOT} = "";
+ } else {
+ $slot_hash{$PKI_OPEN_AJP_PORT_COMMENT_SLOT} = $PKI_OPEN_COMMENT;
+ $slot_hash{$PKI_CLOSE_AJP_PORT_COMMENT_SLOT} = $PKI_CLOSE_COMMENT;
+ $slot_hash{$PKI_OPEN_ENABLE_PROXY_COMMENT_SLOT} = $PKI_OPEN_COMMENT;
+ $slot_hash{$PKI_CLOSE_ENABLE_PROXY_COMMENT_SLOT} = $PKI_CLOSE_COMMENT;
+ }
+
+ $slot_hash{$PROXY_SECURE_PORT_SLOT} = ($proxy_secure_port >=0) ?
+ $proxy_secure_port : "";
+ $slot_hash{$PROXY_UNSECURE_PORT_SLOT} = ($proxy_unsecure_port>=0) ?
+ $proxy_unsecure_port : "";
+
+ $slot_hash{$PKI_WEBAPPS_NAME} = $webapps_base_subsystem_dir;
+ $slot_hash{$PKI_FLAVOR_SLOT} = $pki_flavor;
+ $slot_hash{$TOMCAT_SERVER_PORT_SLOT} = $tomcat_server_port;
+ $slot_hash{$TOMCAT_PIDFILE} = $tomcat6_instance_pid_file_path;
+ $slot_hash{$TOMCAT_CFG} = $tomcat6_conf_instance_file_path;
+ $slot_hash{$TOMCAT_SSL_OPTIONS} = "ssl2=true,ssl3=true,tls=true";
+ $slot_hash{$TOMCAT_SSL2_CIPHERS} = "-SSL2_RC4_128_WITH_MD5,-SSL2_RC4_128_EXPORT40_WITH_MD5,"
+ . "-SSL2_RC2_128_CBC_WITH_MD5,-SSL2_RC2_128_CBC_EXPORT40_WITH_MD5,"
+ . "-SSL2_DES_64_CBC_WITH_MD5,-SSL2_DES_192_EDE3_CBC_WITH_MD5";
+ $slot_hash{$TOMCAT_SSL3_CIPHERS} = "-SSL3_FORTEZZA_DMS_WITH_NULL_SHA,-SSL3_FORTEZZA_DMS_WITH_RC4_128_SHA,"
+ . "+SSL3_RSA_WITH_RC4_128_SHA,-SSL3_RSA_EXPORT_WITH_RC4_40_MD5,"
+ . "+SSL3_RSA_WITH_3DES_EDE_CBC_SHA,+SSL3_RSA_WITH_DES_CBC_SHA,"
+ . "-SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5,-SSL3_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA,"
+ . "-SSL_RSA_FIPS_WITH_DES_CBC_SHA,+SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,"
+ . "-SSL3_RSA_WITH_NULL_MD5,-TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,"
+ . "-TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,+TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
+ $slot_hash{$TOMCAT_TLS_CIPHERS} = "-TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,-TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,"
+ . "+TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,+TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,"
+ . "+TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,-TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,"
+ . "+TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,+TLS_RSA_WITH_3DES_EDE_CBC_SHA,"
+ . "+TLS_RSA_WITH_AES_128_CBC_SHA,+TLS_RSA_WITH_AES_256_CBC_SHA,"
+ . "+TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,+TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,"
+ . "-TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,-TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,"
+ . "-TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,+TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,"
+ . "+TLS_DHE_DSS_WITH_AES_128_CBC_SHA,+TLS_DHE_DSS_WITH_AES_256_CBC_SHA,"
+ . "+TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,+TLS_DHE_RSA_WITH_AES_128_CBC_SHA,"
+ . "+TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
+ $slot_hash{$TOMCAT_INSTANCE_COMMON_LIB} = "$tomcat_instance_common_lib_path/*.jar";
+ if (!$redirected_logs_path) {
+ $slot_hash{$TOMCAT_LOG_DIR} = $logs_instance_path;
+ }
+ else {
+ $slot_hash{$TOMCAT_LOG_DIR} = $redirected_logs_path;
+ }
+
+ }
+
+ ## Process templates (instance independent)
+ #
+ # NOTE: The values substituted may differ across subsystems.
+ #
+
+ # process "CS.cfg" template
+ return 0 if !process_file_template("pki_cfg",
+ $pki_cfg_subsystem_file_path,
+ $pki_cfg_instance_file_path,
+ \%slot_hash);
+ return 0 if !set_file_props($pki_cfg_instance_file_path,
+ $default_file_permissions, $pki_user, $pki_group);
+
+ ## Process registry instance template
+ return 0 if !process_file_template("pki_registry_template",
+ $pki_registry_subsystem_file_path,
+ $pki_registry_instance_file_path,
+ \%slot_hash);
+ return 0 if !set_file_props($pki_registry_instance_file_path,
+ $default_file_permissions, $root_user, $root_group);
+
+ ## Process templates (CA instances)
+ if ($subsystem_type eq $CA) {
+ # process ProfileSelect.template
+ return 0 if !process_file_template("profile_select_template",
+ $profile_select_template_subsystem_file_path,
+ $profile_select_template_instance_file_path,
+ \%slot_hash);
+ # process proxy.conf file
+ return 0 if !process_file_template("proxy_conf",
+ $proxy_conf_subsystem_file_path,
+ $proxy_conf_instance_file_path,
+ \%slot_hash);
+ }
+
+
+ ## Process templates (RA, TPS instances)
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+
+ if ($subsystem_type eq $TPS) {
+
+ # process "cgi" template
+ return 0 if !process_file_template("cgi_home",
+ $cgi_home_subsystem_file_path,
+ $cgi_home_instance_file_path,
+ \%slot_hash);
+
+ return 0 if !process_file_template("cgi_demo",
+ $cgi_demo_subsystem_file_path,
+ $cgi_demo_instance_file_path,
+ \%slot_hash);
+
+ return 0 if !process_file_template("cgi_so",
+ $cgi_so_subsystem_file_path,
+ $cgi_so_instance_file_path,
+ \%slot_hash);
+
+ return 0 if !process_file_template("cgi_so_enroll",
+ $cgi_so_subsystem_enroll_file_path,
+ $cgi_so_instance_enroll_file_path,
+ \%slot_hash);
+
+ # process each "*.cgi" file in subsystem "sow" directory
+ opendir(SUBSYSTEM_DIR, $cgi_sow_subsystem_file_path);
+ while (defined(my $entity = readdir(SUBSYSTEM_DIR))) {
+ if ($entity =~ m/.cgi$/) {
+ # build complete "sow" subystem ".cgi" file name
+ $cgi_sow_subsystem_cgi_file_path = "${cgi_sow_subsystem_file_path}/${entity}";
+ # build complete "sow" instance ".cgi" file name
+ $cgi_sow_instance_cgi_file_path = "${cgi_sow_instance_file_path}/${entity}";
+ # process complete "sow" instance ".cgi" file name
+ return 0 if !process_file_template("cgi_sow",
+ $cgi_sow_subsystem_cgi_file_path,
+ $cgi_sow_instance_cgi_file_path,
+ \%slot_hash);
+ }
+ }
+ closedir(SUBSYSTEM_DIR);
+
+ # process "addAgents.ldif" template
+ return 0 if !process_file_template("addAgents_ldif",
+ $addAgents_ldif_subsystem_file_path,
+ $addAgents_ldif_instance_file_path,
+ \%slot_hash);
+
+ # process "addIndexes.ldif" template
+ return 0 if !process_file_template("addIndexes_ldif",
+ $addIndexes_ldif_subsystem_file_path,
+ $addIndexes_ldif_instance_file_path,
+ \%slot_hash);
+
+ # process "addTokens.ldif" template
+ return 0 if !process_file_template("addTokens_ldif",
+ $addTokens_ldif_subsystem_file_path,
+ $addTokens_ldif_instance_file_path,
+ \%slot_hash);
+
+ # process "addVLVIndexes.ldif" template
+ return 0 if !process_file_template("addVLVIndexes_ldif",
+ $addVLVIndexes_ldif_subsystem_file_path,
+ $addVLVIndexes_ldif_instance_file_path,
+ \%slot_hash);
+
+ # process "schemaMods.ldif" template
+ return 0 if !process_file_template("schemaMods_ldif",
+ $schemaMods_ldif_subsystem_file_path,
+ $schemaMods_ldif_instance_file_path,
+ \%slot_hash);
+ }
+
+
+ # process "httpd.conf" template
+ return 0 if !process_file_template("httpd_conf",
+ $httpd_conf_subsystem_file_path,
+ $httpd_conf_instance_file_path,
+ \%slot_hash);
+ return 0 if !set_file_props($httpd_conf_instance_file_path,
+ $default_file_permissions, $pki_user, $pki_group);
+
+
+ # process "nss.conf" template
+ return 0 if !process_file_template("nss_conf",
+ $nss_conf_subsystem_file_path,
+ $nss_conf_instance_file_path,
+ \%slot_hash);
+ return 0 if !set_file_props($nss_conf_instance_file_path,
+ $default_file_permissions, $pki_user, $pki_group);
+
+ # process "perl.conf" template
+ return 0 if !process_file_template("perl_conf",
+ $perl_conf_subsystem_file_path,
+ $perl_conf_instance_file_path,
+ \%slot_hash);
+
+ return 0 if !set_file_props($perl_conf_instance_file_path,
+ $default_file_permissions, $pki_user, $pki_group);
+
+
+ # process "nss_pcache" template
+ return 0 if !process_file_template("nss_pcache",
+ $nss_pcache_subsystem_file_path,
+ $nss_pcache_instance_file_path,
+ \%slot_hash);
+
+ return 0 if !set_permissions($nss_pcache_instance_file_path,
+ $default_exe_permissions);
+
+ # process "pki_apache_initscript" template
+ return 0 if !process_file_template("pki_apache_initscript",
+ $pki_apache_initscript_file_path,
+ $pki_instance_initscript_path,
+ \%slot_hash);
+
+ return 0 if !set_permissions($pki_instance_initscript_path,
+ $default_exe_permissions);
+
+
+ } else {
+ ## Process templates (CA, KRA, OCSP, TKS instances)
+ # process "index.jsp" template
+ return 0 if !process_file_template("index_jsp",
+ $index_jsp_subsystem_file_path,
+ $index_jsp_instance_file_path,
+ \%slot_hash);
+
+ # process "server.xml" template
+ return 0 if !process_file_template("server_xml",
+ $server_xml_subsystem_file_path,
+ $server_xml_instance_file_path,
+ \%slot_hash);
+
+ # process "serverCertNick.conf" template
+ return 0 if !process_file_template("servercertnick_conf",
+ $servercertnick_conf_subsystem_file_path,
+ $servercertnick_conf_instance_file_path,
+ \%slot_hash);
+
+ # process "tomcat6.conf" template
+ return 0 if !process_file_template("tomcat6_conf",
+ $tomcat6_conf_subsystem_file_path,
+ $tomcat6_conf_instance_file_path,
+ \%slot_hash);
+
+ # process "velocity.properties" template
+ return 0 if !process_file_template("velocity_prop",
+ $velocity_prop_subsystem_file_path,
+ $velocity_prop_instance_file_path,
+ \%slot_hash);
+
+ # process "web.xml" template
+ return 0 if !process_file_template("web_xml",
+ $web_xml_subsystem_file_path,
+ $web_xml_instance_file_path,
+ \%slot_hash);
+
+ # process "catalina.properties" template
+ return 0 if !process_file_template("catalina_properties",
+ $catalina_properties_subsystem_file_path,
+ $catalina_properties_instance_file_path,
+ \%slot_hash);
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub process_pki_files_and_symlinks
+{
+ emit("Processing PKI files and symbolic links for '$pki_instance_path' ...\n");
+
+ ## Populate instances (instance independent)
+
+ # create a filled in temporary "noise"
+ # file for this instance
+ my $noise = generate_random_string(1024);
+
+ return 0 if !create_file($noise_instance_file_path,
+ $noise,
+ $default_file_permissions, $pki_user, $pki_group);
+
+ # create a filled in empty "password.conf"
+ # password file for this instance
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+ return 0 if !create_file($password_conf_instance_file_path,
+ "${default_security_token}:${db_password}\n",
+ $default_file_permissions, $pki_user, $pki_group);
+ } else {
+ return 0 if !create_file($password_conf_instance_file_path,
+ "${default_security_token}=${db_password}\n",
+ $default_file_permissions, $pki_user, $pki_group);
+ }
+
+ # create a filled in empty temporary "pfile"
+ # password file for this instance
+ return 0 if !create_file($pfile_instance_file_path,
+ "${db_password}\n",
+ $default_file_permissions, $pki_user, $pki_group);
+
+ ## Populate instances (RA, TPS instances)
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+ # create an empty file called "pwcache.conf" for this
+ return 0 if !create_empty_file($pwcache_conf_instance_file_path,
+ $default_file_permissions, $pki_user, $pki_group);
+
+ # create instance symlink to subsystem "perl" subdirectory
+ return 0 if !create_symlink($perl_instance_symlink_path, $perl_subsystem_path,
+ $pki_user, $pki_group);
+
+ return 0 if !create_symlink($run_instance_symlink_path,
+ "${default_apache_pids_path}/${subsystem_type}",
+ $pki_user, $pki_group);
+
+ } else {
+ ## Populate instances (CA, KRA, OCSP, TKS instances)
+ # create instance "webapps/$subsystem_type/WEB-INF/lib" subdirectory
+
+ # Create symlink of pki_instance_name pointing to tomcat6 init script.
+ # This is our per instance init script, tomcat6 will use the basename
+ # to find our tomcat6 configuration file in /etc/sysconfig
+ return 0 if !create_symlink($pki_instance_initscript_path, $tomcat6_initscript_path,
+ $root_user, $root_group);
+ if ($use_systemd) {
+ return 0 if !create_symlink(
+ "${pki_subsystem_systemd_wants_path}/${pki_instance_systemd_service_name}",
+ "$pki_subsystem_systemd_service_path",
+ $root_user, $root_group);
+
+ # reload systemd configuration
+ run_command("/bin/systemctl --system daemon-reload");
+
+ }
+
+ return 0 if !create_directory($webinf_lib_instance_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ # create instance symlink to "pki-certsrv.jar"
+ return 0 if !create_symlink($pki_certsrv_jar_symlink_path, $pki_certsrv_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "pki-cms.jar"
+ return 0 if !create_symlink($pki_cms_jar_symlink_path, $pki_cms_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "pki-cmsbundle.jar"
+ return 0 if !create_symlink($pki_cmsbundle_jar_symlink_path, $pki_cmsbundle_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "pki-cmscore.jar"
+ return 0 if !create_symlink($pki_cmscore_jar_symlink_path, $pki_cmscore_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "pki-cmsutil.jar"
+ return 0 if !create_symlink($pki_cmsutil_jar_symlink_path, $pki_cmsutil_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create symlink to either "apache-commons-collections.jar" or "jakarta-commons-collections.jar"
+ # needed by velocity
+ return 0 if !create_symlink($commons_collections_jar_symlink_path,
+ $commons_collections_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create symlink to either "apache-commons-lang.jar" or "jakarta-commons-lang.jar"
+ # needed by velocity
+ return 0 if !create_symlink($commons_lang_jar_symlink_path,
+ $commons_lang_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create symlink to "apache-commons-logging.jar or jakarta-commons-logging.jar"
+ # this is needed by tomcatjss
+ return 0 if !create_symlink($commons_logging_jar_symlink_path,
+ $commons_logging_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create symlink to "jss.jar"
+ return 0 if !create_symlink($jss_jar_symlink_path, $jss_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create symlink to "ldapjdk.jar"
+ return 0 if !create_symlink($ldapjdk_jar_symlink_path, $ldapjdk_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "pki-nsutil.jar"
+ return 0 if !create_symlink($pki_nsutil_jar_symlink_path, $pki_nsutil_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "commons_codec.jar"
+ return 0 if !create_symlink($commons_codec_jar_symlink_path, $commons_codec_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "${subsystem_type}.jar"
+ return 0 if !create_symlink($pki_subsystem_jar_symlink_path, $pki_subsystem_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "symkey.jar"
+ return 0 if !create_symlink($symkey_jar_symlink_path, $symkey_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create symlink to "tomcatjss.jar"
+ return 0 if !create_symlink($tomcatjss_jar_symlink_path, $tomcatjss_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "velocity.jar"
+ return 0 if !create_symlink($velocity_jar_symlink_path, $velocity_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "xerces.jar"
+ return 0 if !create_symlink($xerces_jar_symlink_path, $xerces_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "xml_commons_apis.jar"
+ return 0 if !create_symlink($xml_commons_apis_jar_symlink_path, $xml_commons_apis_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "xml_commons_resolver.jar"
+ return 0 if !create_symlink($xml_commons_resolver_jar_symlink_path, $xml_commons_resolver_jar_file_path,
+ $pki_user, $pki_group);
+
+ #resteasy
+ # create instance symlink to "javassist.jar"
+ return 0 if !create_symlink($javassist_jar_symlink_path, $javassist_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "jaxrs-api.jar"
+ return 0 if !create_symlink($jaxrs_api_jar_symlink_path, $jaxrs_api_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "pki-resteasy_jaxb_provider.jar"
+ return 0 if !create_symlink($resteasy_jaxb_provider_jar_symlink_path, $resteasy_jaxb_provider_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "resteasy_jaxrs.jar"
+ return 0 if !create_symlink($resteasy_jaxrs_jar_symlink_path, $resteasy_jaxrs_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "scannotation.jar"
+ return 0 if !create_symlink($scannotation_jar_symlink_path, $scannotation_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "pki-resteasy_jettison_provider.jar"
+ return 0 if !create_symlink($resteasy_jettison_provider_jar_symlink_path, $resteasy_jettison_provider_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "jettison.jar"
+ return 0 if !create_symlink($jettison_jar_symlink_path, $jettison_jar_file_path,
+ $pki_user, $pki_group);
+
+
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub process_pki_security_databases
+{
+ my $result = 0;
+ my $serial_number = 0;
+ my $validity_period = 12;
+ my $time_stamp = get_time_stamp();
+ my $subject = "CN=$host,O=$time_stamp";
+ my $issuer_name = "CN=$host,O=$time_stamp";
+ my $nickname = "Server-Cert cert-$pki_instance_name";
+ my $trustargs = "CTu,CTu,CTu";
+
+ emit("Processing PKI security databases for '$pki_instance_path' ...\n");
+
+ # now create and configure pki security databases,
+ # cert3.db, key3.db, secmod.db ...
+ if (!file_exists($default_certutil_command) && !$dry_run) {
+ emit("process_pki_security_databases(): $default_certutil_command does not exist!\n", "error");
+ return $result;
+
+ }
+
+ if (!file_exists($noise_instance_file_path) && !$dry_run) {
+ emit("process_pki_security_databases(): Can't find temp noise file!\n", "error");
+ return $result;
+ }
+
+ if (!file_exists($pfile_instance_file_path) && !$dry_run) {
+ emit("process_pki_security_databases(): Can't find temp file with password!\n", "error");
+ return $result;
+ }
+
+ certutil_create_databases($alias_instance_path,
+ $pfile_instance_file_path);
+
+ certutil_generate_self_signed_cert($alias_instance_path,
+ $default_security_token,
+ $serial_number,
+ $validity_period,
+ $subject,
+ $issuer_name,
+ $nickname,
+ $trustargs,
+ $noise_instance_file_path,
+ $pfile_instance_file_path);
+
+ remove_file($noise_instance_file_path);
+
+ remove_file($pfile_instance_file_path);
+
+ set_owner_group_on_directory_contents($alias_instance_path,
+ $pki_user, $pki_group);
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub process_pki_security_modules
+{
+ my $result = 0;
+
+ emit("Processing PKI security modules for '$pki_instance_path' ...\n");
+
+ if (!file_exists($default_modutil_command) && !$dry_run) {
+ emit("process_pki_security_modules(): $default_modutil_command must be installed on system!\n", "error");
+ return $result;
+ }
+
+ emit(" Attempting to add hardware security modules to system if applicable ...\n");
+
+ while (my ($key, $value) = each(%supported_sec_modules_hash)) {
+ if (!file_exists($value)) {
+ emit(" module name: $key lib: $value DOES NOT EXIST!\n");
+ next;
+ } else {
+ modutil_add_token($alias_instance_path, $key, $value);
+ emit(" Added module name: $key lib: $value\n");
+ }
+ }
+
+ return 1;
+}
+
+sub process_pki_selinux_setup
+{
+ my $setype = "pki_" . $subsystem_type;
+ my $setype_p = $setype . "_port_t";
+ my $default_instance_name = "pki-" . $subsystem_type;
+ my $default_instance_root = "/var/lib";
+ my $default_log_path = "/var/log/" . $default_instance_name;
+ my $default_conf_path = "/etc/" . $default_instance_name;
+ my $status = 0;
+
+ my $conf_path;
+ my $log_path;
+ my $ftype;
+ my $java_component = 0;
+ my $semanage_cmds = "";
+ my @restorecon_cmds;
+
+ emit("configuring SELinux ...\n");
+
+ if (!$redirected_logs_path) {
+ $log_path = $logs_instance_path;
+ }
+ else {
+ $log_path =$redirected_logs_path;
+ }
+
+ if (!$redirected_conf_path) {
+ $conf_path = $conf_instance_path;
+ }
+ else {
+ $conf_path =$redirected_conf_path;
+ }
+
+ if ($subsystem_type eq $CA ||
+ $subsystem_type eq $KRA ||
+ $subsystem_type eq $OCSP ||
+ $subsystem_type eq $TKS) {
+ $java_component =1;
+ }
+
+ # set file contexts
+ if ($java_component) {
+ push (@restorecon_cmds, "$restorecon -F -R /usr/share/java/pki");
+ }
+ push (@restorecon_cmds, "$restorecon -F -R /usr/share/pki");
+
+ # set file context for $pki_instance_root/$pki_instance_name
+ if (($pki_instance_name ne $default_instance_name) || ($pki_instance_root ne $default_instance_root)) {
+ add_selinux_file_context($setype . "_var_lib_t",
+ "\"${pki_instance_root}/${pki_instance_name}(/.*)?\"",
+ "a", \$semanage_cmds);
+ }
+ push(@restorecon_cmds, "$restorecon -F -R $pki_instance_root/$pki_instance_name");
+
+
+ if ($java_component) {
+ # set file context for instance pid file
+ my $pidfile = $tomcat6_instance_pid_file_path;
+ if ($pki_instance_name ne $default_instance_name) {
+ add_selinux_file_context($setype . "_var_run_t",
+ $pidfile, "f", \$semanage_cmds);
+ }
+ if (-e $pidfile) {
+ push(@restorecon_cmds, "$restorecon -F $pidfile");
+ }
+
+ my $pidpath = $default_apache_pids_path;
+ if (-e $pidpath) {
+ push(@restorecon_cmds, "$restorecon -F -R $pidpath");
+ }
+ }
+
+ # set file context for $log_path
+ $log_path =~ s/\/+$//;
+ if (!$log_path) {
+ emit("Error: Cannot set selinux context $setype" . "_log_t for directory /");
+ } else {
+ if ($log_path ne $default_log_path) {
+ add_selinux_file_context($setype . "_log_t",
+ "\"$log_path(/.*)?\"", "a", \$semanage_cmds);
+ }
+ push(@restorecon_cmds, "$restorecon -F -R $log_path");
+ }
+
+ # set file context for $conf_path
+ $conf_path =~ s/\/+$//;
+ if (!$conf_path) {
+ emit("Error: Cannot set selinux context $setype" . "_etc_rw_t for directory /");
+ } else {
+ if ($conf_path ne $default_conf_path) {
+ add_selinux_file_context($setype . "_etc_rw_t",
+ "\"$conf_path(/.*)?\"", "a", \$semanage_cmds);
+ }
+ push(@restorecon_cmds, "$restorecon -F -R $conf_path");
+ }
+
+ if (! $java_component) {
+ push(@restorecon_cmds, "$restorecon -F -R /usr/sbin/httpd.worker");
+ }
+
+ # add ports
+ parse_selinux_ports();
+ if ($secure_port != -1) {
+ add_selinux_port($setype_p, $secure_port, \$semanage_cmds);
+ }
+ if ($non_clientauth_secure_port != -1) {
+ add_selinux_port($setype_p, $non_clientauth_secure_port, \$semanage_cmds);
+ }
+ if ($unsecure_port != -1) {
+ add_selinux_port($setype_p, $unsecure_port, \$semanage_cmds);
+ }
+ if ($tomcat_server_port != -1) {
+ add_selinux_port($setype_p, $tomcat_server_port, \$semanage_cmds);
+ }
+ if ($agent_secure_port != -1) {
+ add_selinux_port($setype_p, $agent_secure_port, \$semanage_cmds);
+ }
+ if ($ee_secure_port != -1) {
+ add_selinux_port($setype_p, $ee_secure_port, \$semanage_cmds);
+ }
+ if ($ee_secure_client_auth_port != -1) {
+ add_selinux_port($setype_p, $ee_secure_client_auth_port, \$semanage_cmds);
+ }
+ if ($admin_secure_port != -1) {
+ add_selinux_port($setype_p, $admin_secure_port, \$semanage_cmds);
+ }
+ if ($ajp_port != -1) {
+ add_selinux_port($setype_p, $ajp_port, \$semanage_cmds);
+ }
+
+ # now run the selinux commands in batch mode
+ if ($semanage_cmds ne "") {
+ emit("Running the semanage commands in batch mode\n", "debug");
+ if (! $dry_run) {
+ if(! run_command("$semanage -S targeted -i - " . ' << _EOF' . "\n$semanage_cmds\n" . '_EOF' . "\n")) {
+ emit("Failed executing semanage batch command \n", "error");
+ }
+ }
+ } else {
+ emit("Selinux contexts already set. No need to run semanage.\n", "debug");
+ }
+
+ #now run the restorecons
+ emit("Running restorecon commands\n", "debug");
+ foreach my $cmd (@restorecon_cmds) {
+ emit("$cmd\n", "debug");
+ if (! $dry_run) {
+ if (!run_command($cmd)) {
+ emit("Failed executing restorecon command; $cmd\n", "error");
+ }
+ }
+ }
+
+ return 1;
+}
+
+# no args
+# return 1 - success, or
+# return 0 - failure
+sub install_pki_instance
+{
+ emit("Installing PKI instance ...\n");
+
+ return 0 if !create_directory($pki_instance_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ return 0 if !process_pki_directories();
+ return 0 if !process_pki_templates();
+ return 0 if !process_pki_files_and_symlinks();
+ return 0 if !process_pki_security_databases();
+ return 0 if !process_pki_security_modules();
+
+ if (($^O eq "linux") && (is_Fedora() || (is_RHEL() && (! is_RHEL4())))){
+ return 0 if !process_pki_selinux_setup();
+ }
+
+ return 1;
+}
+
+
+##############################################################
+# PKI Instance Removal Subroutines
+##############################################################
+
+
+# Return 1 if success, 0 if failure
+sub cleanup
+{
+ my $result = 0;
+
+ emit(sprintf("cleanup(%s)\n", join(", ", @_)), "debug");
+
+ emit("PKI instance creation Cleanup Utility cleaning up on error ...", "info");
+
+ $result = uninstall(\%installation_info);
+
+ return $result;
+}
+
+# Return 1 if success, 0 if failure
+sub write_install_info
+{
+ if ($dry_run) {
+ return 1;
+ } else {
+ if (!defined($pki_instance_path)) {
+ return 0;
+ }
+ my $install_info_file_path = write_install_info_to_dir($pki_instance_path,
+ \%installation_info);
+ if (defined($install_info_file_path)) {
+ emit(sprintf("Installation manifest: %s", $install_info_file_path));
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+}
+
+##############################################################
+# Signal Handlers
+##############################################################
+
+sub die_handler
+{
+ my ($msg) = @_;
+
+ # If we abort write the installation manifest
+ # so cleanup can still be performed later.
+ write_install_info();
+}
+
+$SIG{'__DIE__'} = \&die_handler;
+
+##############################################################
+# Main Program
+##############################################################
+
+# no args
+# no return value
+sub main
+{
+ my $result = 0;
+ my $parse_result = 0;
+ my $command = "";
+
+ chdir("/tmp");
+
+ print(STDOUT "PKI instance creation Utility ...\n\n");
+
+ # On Linux/UNIX, insure that this script is being run as "root".
+ $result = check_for_root_UID();
+ if (!$result) {
+ usage();
+ exit 255;
+ }
+
+ # Setup platform-dependent parameters
+ setup_platform_dependent_parameters();
+
+ $parse_result = parse_arguments();
+ if (!$parse_result || $parse_result == -1) {
+ close_logfile();
+ exit 255;
+ }
+
+ exit 255 if !initialize_paths();
+
+ exit 255 if !initialize_pki_creation_values();
+
+ $result = install_pki_instance();
+ if (!$result) {
+ print(STDOUT "\n");
+
+ my $install_description = get_install_description();
+ emit(sprintf("The following was performed\n%s\n\n", $install_description));
+
+ASK_AGAIN:
+ my $confirm = prompt("Error detected would you like to clean up ${pki_instance_path} (Y/N)? ");
+
+ if ($confirm eq "Y" || $confirm eq "y") {
+ cleanup();
+ } elsif ($confirm ne "N" && $confirm ne "n") {
+ goto ASK_AGAIN;
+ }
+
+ close_logfile();
+
+ exit 255;
+ }
+
+ print(STDOUT "\n");
+ print(STDOUT "PKI instance creation completed ...\n\n");
+
+ # Write the installation manifest.
+ write_install_info();
+
+ my $install_description = get_install_description();
+ emit(sprintf("The following was performed:\n%s\n", $install_description));
+
+ printf(STDOUT "Installation information recorded in %s.\n", get_logfile_path());
+
+ if ($use_systemd) {
+ $pki_registry_initscript_command =
+ "/bin/systemctl restart $pki_instance_systemd_service_name";
+ } else {
+ $pki_registry_initscript_command =
+ "/sbin/service $pki_registry_initscript restart $pki_instance_name";
+ }
+
+ $command = "${pki_registry_initscript_command}";
+ run_command($command);
+
+ if ($dry_run) {
+ print STDOUT "dry run mode ENABLED, system was not modified\n";
+ } else {
+
+ # Notify user to check firewall settings . . .
+ print(STDOUT
+ "Before proceeding with the configuration, make sure \n"
+ . "the firewall settings of this machine permit proper \n"
+ . "access to this subsystem. \n\n");
+
+ # EXCEPTION: To enable a user to easily configure their PKI subsystem,
+ # this is the ONLY instance in which we print out the actual
+ # value of the the one-time random PIN, as well as store this
+ # message at the end of the initialization log.
+ if ($subsystem_type eq $CA ||
+ $subsystem_type eq $KRA ||
+ $subsystem_type eq $OCSP ||
+ $subsystem_type eq $TKS) {
+ if ($admin_secure_port > 0) {
+ # Port Separation: CA, KRA, OCSP, TKS
+ print(STDOUT
+ "Please start the configuration by accessing:\n\n"
+ . "https://$host:$admin_secure_port/$subsystem_type/admin/"
+ . "console/config/login?pin=$random\n\n");
+ emit("Configuration Wizard listening on\n"
+ . "https://$host:$admin_secure_port/$subsystem_type/admin/"
+ . "console/config/login?pin=$random\n",
+ "log");
+ } else {
+ # Shared Ports: CA, KRA, OCSP, TKS
+ print(STDOUT
+ "Please start the configuration by accessing:\n\n"
+ . "https://$host:$secure_port/$subsystem_type/admin/"
+ . "console/config/login?pin=$random\n\n");
+ emit("Configuration Wizard listening on\n"
+ . "https://$host:$secure_port/$subsystem_type/admin/"
+ . "console/config/login?pin=$random\n",
+ "log");
+ }
+ } else {
+ # Port Separation: RA, TPS
+ print(STDOUT
+ "Please start the configuration by accessing:\n\n"
+ . "https://$host:$non_clientauth_secure_port/$subsystem_type/"
+ . "admin/console/config/login?pin=$random\n\n");
+ emit("Configuration Wizard listening on\n"
+ . "https://$host:$non_clientauth_secure_port/$subsystem_type/"
+ . "admin/console/config/login?pin=$random\n",
+ "log");
+ }
+
+ print(STDOUT
+ "After configuration, the server can be operated by the command:\n\n"
+ . " $pki_registry_initscript_command\n\n");
+ emit("After configuration, the server can be operated by the command:\n"
+ . "${pki_registry_initscript_command}\n",
+ "log");
+ }
+
+ close_logfile();
+
+ return;
+}
+
+
+##############################################################
+# PKI Instance Creation
+##############################################################
+
+main();
+
+exit 0;
+
diff --git a/base/setup/pkiremove b/base/setup/pkiremove
new file mode 100755
index 000000000..dd9fbc7f9
--- /dev/null
+++ b/base/setup/pkiremove
@@ -0,0 +1,680 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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-2010 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+
+use strict;
+use warnings;
+
+use Getopt::Long qw(GetOptions);
+
+##############################################################
+# This script is used to remove an existing PKI instance.
+#
+# To execute:
+#
+# ./pkiremove -pki_instance_root=<pki_instance_root> # Instance root
+# # directory destination
+#
+# -pki_instance_name=<pki_instance_id> # Unique PKI subsystem
+# # instance name
+# # (e. g. - pki-pki1)
+#
+# [-token_pwd=<token pw>] # Password of token containing
+# # subsystem certificate
+#
+# [-force] # Don't ask any
+# # questions
+#
+##############################################################
+
+
+##############################################################
+# Execution Check
+##############################################################
+
+# Check to insure that this script's original
+# invocation directory has not been deleted!
+my $cwd = `/bin/pwd`;
+chomp $cwd;
+if (!$cwd) {
+ emit("Cannot invoke '$0' from non-existent directory!\n", "error");
+ exit 255;
+}
+
+##############################################################
+# Environment Variables
+##############################################################
+
+# untaint called subroutines
+if (($^O ne 'Windows_NT') && ($^O ne 'MSWin32')) {
+ $> = $<; # set effective user ID to real UID
+ $) = $(; # set effective group ID to real GID
+ $ENV{'PATH'} = '/bin:/usr/bin';
+ $ENV{'ENV'} = '' if !defined($ENV{'ENV'});
+}
+
+
+##############################################################
+# Command-Line Variables
+##############################################################
+
+my $ARGS = ($#ARGV + 1);
+
+
+##############################################################
+# Shared Common Perl Data and Subroutines
+##############################################################
+
+use lib "/usr/share/pki/scripts";
+use pkicommon;
+
+# make -w happy by suppressing warnings of Global variables used only once
+my $suppress = "";
+$suppress = $default_file_permissions;
+
+##############################################################
+# Local Constants
+##############################################################
+
+my $semanage = "/usr/sbin/semanage";
+
+##############################################################
+# Local Data Structures
+##############################################################
+
+
+##############################################################
+# Local Variables
+##############################################################
+
+my $pki_instance_root = undef;
+my $pki_instance_name = undef;
+my $force = 0;
+my $token_pwd = "";
+
+my $conf_file = undef;
+my $pki_instance_path = undef;
+my $subsystem_type = undef;
+
+# PKI init script variables
+my $pki_registry_initscript = undef;
+my $pki_registry_initscript_command = undef;
+
+# PKI registry variables
+my $pki_registry_subsystem_path = undef;
+
+#systemd specific variables
+my $use_systemd = 0;
+my $pki_instance_systemd_service_name = undef;
+
+##############################################################
+# Platform-Dependent Data Initialization
+##############################################################
+
+if ($^O eq "linux") {
+ if (is_Fedora() && (fedora_release() >= 16)) {
+ $use_systemd = 1;
+ }
+} else {
+ emit("Unsupported platform '$^O'!\n", "error");
+ exit 255;
+}
+
+##############################################################
+# Local Data Initialization
+##############################################################
+
+##############################################################
+# PKI Instance Removal Subroutines
+##############################################################
+
+# no args
+# no return value
+sub usage
+{
+ print STDOUT <<'EOF';
+Usage: pkiremove -pki_instance_root=<pki_instance_root> # Instance root
+ # directory
+ # destination
+ -pki_instance_name=<pki_instance_id> # Unique PKI
+ # subsystem
+ # instance name
+ # (e. g. - pki-pki1)
+ #
+[-token_pwd=<token password>] # Password for token containing subsystem cert.
+
+[-force] # Don't ask any questions
+
+[-verbose] # Display detailed information. May be specified multiple times,
+ # each time increasing the verbosity level.
+
+[-dry_run] # Do not perform any actions.
+ # Just report what would have been done.
+
+Example: pkiremove -pki_instance_root=/var/lib -pki_instance_name=pki-ca
+
+IMPORTANT: Must be run as root!
+EOF
+ return;
+}
+
+sub update_domain
+{
+ my $sport;
+ my $ncsport;
+ my $sechost;
+ my $httpport;
+ my $seceeport;
+ my $secagentport;
+ my $secadminport;
+ my $adminsport;
+ my $agentsport;
+ my $secselect;
+ my $subsystemnick;
+ my $machinename;
+ my $typeval;
+ my $url;
+
+ get_cs_cfg($conf_file, {"service.machineName" => \$machinename,
+ "service.securityDomainPort" => \$sport,
+ "service.non_clientauth_securePort" => \$ncsport,
+ "securitydomain.host" => \$sechost,
+ "securitydomain.httpport" => \$httpport,
+ "securitydomain.httpseeport" => \$seceeport,
+ "securitydomain.httpsagentport" => \$secagentport,
+ "securitydomain.httpsadminport" => \$secadminport,
+ "securitydomain.select" => \$secselect,
+ "pkicreate.admin_secure_port" => \$adminsport,
+ "cs.type" => \$typeval,
+ "pkicreate.agent_secure_port" => \$agentsport});
+
+ my $subsystemnick_param = lc($typeval) . ".cert.subsystem.nickname";
+ get_cs_cfg($conf_file, {$subsystemnick_param => \$subsystemnick});
+
+ # NOTE: Don't check for the existence of $httpport, as this will
+ # be undefined for a Security Domain that has been migrated!
+ if ((!defined($sechost)) ||
+ (!defined($seceeport)) ||
+ (!defined($secagentport)) ||
+ (!defined($secadminport))) {
+ print(STDOUT "No security domain defined.\nIf this is an unconfigured instance, then that is OK.\n" .
+ "Otherwise, manually delete the entry from the security domain master.\n");
+ return;
+ }
+
+ die "Subsystem nickname not defined" if (!defined($subsystemnick));
+ if (!defined($adminsport)) {
+ $adminsport = "";
+ }
+
+ if (!defined($agentsport)) {
+ $agentsport = "";
+ }
+
+ if (!defined($ncsport)) {
+ $ncsport = "";
+ }
+
+ (my $token_name, my $nick) = split(/:/, $subsystemnick, 2);
+ if ((!defined($nick)) || ($nick eq "")) {
+ $token_name = "internal";
+ }
+
+ if ($secselect ne "new") {
+ # This is not a domain master, so we need to update the master
+ print(STDOUT "Contacting the security domain master to update the security domain\n");
+ my $listval = $subsystem_type . "List";
+ my $urlheader = "https://" . $sechost . ":" . $seceeport;
+ my $urlagentheader = "https://" . $sechost . ":" . $secagentport;
+ my $urladminheader = "https://" . $sechost . ":" . $secadminport;
+ my $updateURL = "/ca/agent/ca/updateDomainXML";
+
+ if ($token_pwd eq "") {
+ my $pwfile = $pki_instance_path . "/conf/password.conf";
+ if (-r $pwfile) {
+ open(DAT, $pwfile) or die "Could not open password.conf file to read token password.";
+ my @pw_data=<DAT>;
+ foreach my $line (@pw_data) {
+ chomp($line);
+ if (($typeval eq "CA") ||
+ ($typeval eq "KRA") ||
+ ($typeval eq "OCSP") ||
+ ($typeval eq "TKS")) {
+ (my $varname, my $valname) = split(/=/, $line);
+ if ($varname eq "hardware-$token_name") { $token_pwd = $valname; }
+ if ($varname eq "$token_name") { $token_pwd = $valname; }
+ } else { # TPS, RA
+ (my $varname, my $valname) = split(/:/, $line);
+ if ($varname eq $token_name) { $token_pwd = $valname; }
+ if ($varname eq "hardware-$token_name") { $token_pwd = $valname; }
+ }
+ }
+ close($pwfile);
+ }
+ }
+
+ while ($token_pwd eq "") {
+ $token_pwd = prompt( "No password found for $token_name. What is the password for this token?");
+ }
+
+ my $params = "name=$pki_instance_name" .
+ "&type=$typeval" .
+ "&list=$listval" .
+ "&host=$machinename" .
+ "&sport=$sport" .
+ "&ncsport=$ncsport" .
+ "&adminsport=$adminsport" .
+ "&agentsport=$agentsport" .
+ "&operation=remove";
+
+ #update domainXML
+ my $cmd = `/usr/bin/sslget -d \"$pki_instance_path/alias\" -p \"$token_pwd\" -v -n \"$subsystemnick\" -r \"$updateURL\" -e \"$params\" $sechost:$secagentport 2>&1`;
+ $cmd =~ /\<Status\>(.*?)\<\/Status\>/;
+ $cmd = $1;
+
+ die ("Security Domain returns non-zero status for updateDomainXML.") if ($cmd ne "0");
+ }
+}
+
+sub remove_fcontext
+{
+ my ($fcontext, $fname, $ftype, $cmd_ref) = @_;
+ emit(sprintf("remove_fcontext(%s)\n", join(", ", @_)), "debug");
+
+ my $tmp = `$semanage fcontext -l -C |grep $fcontext |grep $fname |wc -l`;
+ chomp $tmp;
+ if ($tmp eq "0" ) {
+ emit("File context $fcontext for $fname defined in policy, not deleted", "debug");
+ return 0;
+ }
+
+ if ($ftype eq "f") {
+ $$cmd_ref .= "fcontext -d -t $fcontext -f -- $fname\n";
+ } else {
+ $$cmd_ref .= "fcontext -d -t $fcontext $fname\n";
+ }
+}
+
+sub get_selinux_fcontexts
+{
+ my ($cmd_ref) = @_;
+ my $setype = "pki_" . $subsystem_type;
+ my $default_instance_name = "pki-" . $subsystem_type;
+ my $default_instance_root = "/var/lib";
+ my $default_log_path = "/var/log/" . $default_instance_name;
+ my $default_conf_path = "/etc/" . $default_instance_name;
+
+ my $log_path = "$pki_instance_path/logs";
+ my $conf_path = "$pki_instance_path/conf";
+ my $ftype;
+ my $java_component = 0;
+
+ if (($subsystem_type eq $CA) ||
+ ($subsystem_type eq $KRA) ||
+ ($subsystem_type eq $OCSP) ||
+ ($subsystem_type eq $TKS)) {
+ $java_component=1;
+ }
+
+ if (-l $log_path) {
+ $log_path = readlink $log_path;
+ };
+
+ if (-l $conf_path) {
+ $conf_path = readlink $conf_path;
+ };
+
+ # For backwards compatibility, support removal of instances
+ # which use the legacy start/stop implementation
+ if (entity_exists("$default_initscripts_path/$pki_instance_name")) {
+ # remove context for "$default_initscripts_path/$pki_instance_name"
+ if ($pki_instance_name ne $default_instance_name) {
+ remove_fcontext($setype . "_script_exec_t",
+ "/etc/rc\\.d/init\\.d/$pki_instance_name", "f", $cmd_ref);
+ }
+ }
+
+ # remove context for $pki_instance_root/$pki_instance_name
+ if (($pki_instance_name ne $default_instance_name) || ($pki_instance_root ne $default_instance_root)) {
+ remove_fcontext($setype . "_var_lib_t",
+ "\"$pki_instance_root/$pki_instance_name(/.*)?\"", "a", $cmd_ref);
+ }
+
+ # remove context for /var/run/$pki_instance_name.pid
+ if (($java_component) && ($pki_instance_name ne $default_instance_name)) {
+ remove_fcontext($setype . "_var_run_t",
+ "/var/run/$pki_instance_name" . '.pid', "f", $cmd_ref);
+ }
+
+ # remove context for $log_path
+ if ($log_path ne $default_log_path) {
+ remove_fcontext($setype . "_log_t",
+ "\"$log_path(/.*)?\"", "a", $cmd_ref);
+ }
+
+ # remove context for $conf_path
+ if ($conf_path ne $default_conf_path) {
+ remove_fcontext($setype . "_etc_rw_t",
+ "\"$conf_path(/.*)?\"", "a", $cmd_ref);
+ }
+
+}
+
+
+sub get_selinux_ports
+{
+ my ($cmd_ref) = @_;
+ my $status;
+ my $semanage = "/usr/sbin/semanage";
+ my $secure_port;
+ my $non_clientauth_secure_port;
+ my $unsecure_port;
+ my @ports = ();
+
+ get_cs_cfg($conf_file, {"service.securePort" => \$secure_port,
+ "service.non_clientauth_securePort" => \$non_clientauth_secure_port,
+ "service.unsecurePort" => \$unsecure_port});
+
+ if (($subsystem_type eq $CA) ||
+ ($subsystem_type eq $KRA) ||
+ ($subsystem_type eq $OCSP) ||
+ ($subsystem_type eq $TKS)) {
+ use XML::LibXML;
+ my $parser = XML::LibXML->new();
+ my $config = $parser->parse_file($pki_instance_path . "/conf/server.xml")
+ or die "Could not read XML from server.xml to determine ports.";
+
+ my $root = $config->getDocumentElement;
+
+ my $i = 0;
+ foreach my $port ($root->findnodes('//@port')) {
+ $ports[$i] = $port->getValue();
+ $i++;
+ }
+ } else { # TPS, RA
+ my $i =0;
+ if (defined $secure_port) {
+ $ports[$i] = $secure_port;
+ $i++;
+ }
+ if (defined $non_clientauth_secure_port) {
+ $ports[$i] = $non_clientauth_secure_port;
+ $i++;
+ }
+ if (defined $unsecure_port) {
+ $ports[$i] = $unsecure_port;
+ $i++;
+ }
+ }
+
+ print(STDOUT "\n");
+ foreach my $port (@ports) {
+ my $setype = "pki_" . $subsystem_type . "_port_t";
+ my $tmp = `$semanage port -l -C |grep $setype |grep $port | wc -l`;
+ chomp $tmp;
+ if ($tmp eq "0") {
+ emit("Port context $setype for $port defined in policy, not deleting", "debug");
+ } else {
+ $$cmd_ref .= "port -d -t $setype -ptcp $port\n";
+ }
+ }
+}
+
+
+# Return 1 if success, 0 if failure
+sub remove_instance
+{
+ my ($result, $confirm, $install_info);
+ $confirm = "Y";
+ $result = 1;
+
+ print(STDOUT "PKI instance Deletion Utility cleaning up instance ...\n\n");
+
+ASK_AGAIN:
+ if (!$force) {
+ $confirm = prompt("You have elected to remove the instance "
+ . "installed in $pki_instance_path.\n"
+ . "Are you sure (Y/N)? ");
+ }
+
+ if ($confirm eq "N" || $confirm eq "n") {
+ return 1;
+ } elsif ($confirm ne "Y" && $confirm ne "y") {
+ goto ASK_AGAIN;
+ }
+
+ $install_info = read_install_info_from_dir($pki_instance_path);
+ if (!defined($install_info)) {
+ emit("Can't remove instance, installation manifest does not exist!", "error");
+ return $result;
+ }
+
+ eval { update_domain(); } if !$dry_run; # FIXME so update_domain shows what it would do
+ warn "Error updating security domain: " . $@ if $@;
+
+ if (($^O eq "linux") && (is_Fedora() || (is_RHEL() && (! is_RHEL4())))) {
+ my $semanage_cmds = "";
+
+ eval { get_selinux_ports(\$semanage_cmds); };
+ warn "Error getting selinux ports: " . $@ if $@;
+
+ eval { get_selinux_fcontexts(\$semanage_cmds); };
+ warn "Error getting selinux file contexts: " . $@ if $@;
+
+ print STDOUT "Removing selinux contexts\n";
+ if ($semanage_cmds ne "") {
+ emit("Executing selinux commands in batch mode.\n", "debug");
+ if (! $dry_run) {
+ if (! run_command("$semanage -S targeted -i - " . '<< _EOF' . "\n$semanage_cmds\n" . '_EOF' . "\n")) {
+ emit("Error executing selinux batch commands\n", "error");
+ }
+ }
+ } else {
+ emit("No selinux contexts need to be removed. No need to run semanage. \n");
+ }
+ }
+
+ $pki_registry_initscript = get_registry_initscript_name($subsystem_type);
+
+ # Shutdown this instance
+ if ($^O eq "linux") {
+ if ($use_systemd) {
+ $pki_instance_systemd_service_name =
+ "${pki_registry_initscript}\@${pki_instance_name}.service";
+ $pki_registry_initscript_command =
+ "/bin/systemctl stop $pki_instance_systemd_service_name";
+ } else {
+ if (entity_exists("$default_initscripts_path/$pki_instance_name")) {
+ $pki_registry_initscript_command = "/sbin/service $pki_instance_name stop";
+ } else {
+ $pki_registry_initscript_command =
+ "/sbin/service $pki_registry_initscript stop $pki_instance_name";
+ }
+ }
+ } else {
+ emit("Unsupported platform '$^O'!\n", "error");
+ exit 255;
+ }
+ run_command($pki_registry_initscript_command);
+
+ if (!$use_systemd) {
+ # De-register this instance with "chkconfig"
+ if ($^O eq "linux") {
+ if (entity_exists("$default_initscripts_path/$pki_instance_name")) {
+ # De-register this instance with '/sbin/chkconfig'
+ print(STDOUT "Removing '$pki_instance_name' from chkconfig.\n");
+ deregister_pki_instance_with_chkconfig($pki_instance_name);
+ }
+ }
+ }
+
+ print(STDOUT "\n");
+
+ # Remove all installed files and directories.
+ $result = 0 if !uninstall($install_info);
+
+ if ($use_systemd) {
+ run_command("/bin/systemctl --system daemon-reload");
+ }
+
+ print(STDOUT "\n");
+
+ return $result;
+}
+
+
+##############################################################
+# Main Program
+##############################################################
+
+# no args
+# return 1 - success, or
+# return 0 - failure
+sub main
+{
+ chdir("/tmp");
+
+ my $result = 0;
+
+ print(STDOUT "PKI instance Deletion Utility ...\n\n");
+
+ # On Linux/UNIX, insure that this script is being run as "root".
+ $result = check_for_root_UID();
+ if (!$result) {
+ usage();
+ exit 255;
+ }
+
+ # Check for a valid number of command-line arguments.
+ if ($ARGS < 2) {
+ emit("$0: Insufficient arguments!", "error");
+ usage();
+ exit 255;
+ }
+
+ # Parse command-line arguments.
+ $result = GetOptions("pki_instance_root=s" => \$pki_instance_root,
+ "pki_instance_name=s" => \$pki_instance_name,
+ "token_pwd=s" => \$token_pwd,
+ "verbose+" => \$verbose,
+ "dry_run" => \$dry_run,
+ "force" => \$force);
+
+ # Always disallow root to be the pki_instance_root.
+ if ($pki_instance_root eq "/") {
+ emit("$0: Don't even think about making root "
+ . "the pki_instance_root!", "error");
+ usage();
+ exit 255;
+ }
+
+ $pki_instance_root = normalize_path($pki_instance_root);
+
+ # Check for valid content of command-line arguments.
+ if (!$pki_instance_root) {
+ emit("$0: Must have value for -pki_instance_root!", "error");
+ usage();
+ exit 255;
+ }
+
+ if (!$pki_instance_name) {
+ emit("$0: The instance ID of the PKI instance "
+ . "to be removed is required!", "error");
+ usage();
+ exit 255;
+ }
+
+ $pki_instance_path = "${pki_instance_root}/${pki_instance_name}";
+
+ if (!directory_exists($pki_instance_path)) {
+ emit("$0: Target directory $pki_instance_path "
+ . "is not a legal directory.", "error");
+ usage();
+ exit 255;
+ }
+
+ # Capture uninstall information in a log file, always overwrite this file.
+ # When removing an instance it's never a fatal error if the logfile
+ # cannot be created.
+ my $logfile = "/var/log/${pki_instance_name}-uninstall.log";
+ open_logfile($logfile, $default_file_permissions);
+
+ emit("Capturing installation information in $logfile.\n");
+
+ if ($verbose) {
+ emit(" verbose mode ENABLED (level=$verbose)\n");
+ }
+
+ if ($dry_run) {
+ emit(" dry run mode ENABLED, system will not be modified, log to $logfile\n");
+ print STDOUT "dry run mode ENABLED, system will not be modified\n";
+ }
+
+ emit(" pki_instance_root $pki_instance_root\n");
+ emit(" pki_instance_name $pki_instance_name\n");
+ emit(" pki_instance_path $pki_instance_path\n");
+
+ $conf_file = $pki_instance_path . "/conf/CS.cfg";
+ $subsystem_type = get_cs_cfg($conf_file, "cs.type");
+ if (!defined($subsystem_type)) {
+ emit("Could not determine the subsystem type from the file \"$conf_file\"\n", "error");
+ exit 1;
+ }
+ $subsystem_type = lc($subsystem_type);
+
+ # Remove the specified instance
+ $result = remove_instance();
+ if ($result != 1) {
+ exit 255;
+ }
+
+ # Establish PKI subsystem-level registry
+ $pki_registry_subsystem_path = "$pki_registry_path/$subsystem_type";
+
+ # If empty, remove the PKI subsystem-level registry
+ if (directory_exists($pki_registry_subsystem_path)) {
+ if (is_directory_empty($pki_registry_subsystem_path)) {
+ remove_directory($pki_registry_subsystem_path);
+ }
+ }
+
+ # If empty, remove the PKI-level registry
+ if (directory_exists($pki_registry_path)) {
+ if (is_directory_empty($pki_registry_path)) {
+ remove_directory($pki_registry_path);
+ }
+ }
+
+ if ($dry_run) {
+ print STDOUT "dry run mode ENABLED, system was not modified\n";
+ }
+
+ return $result;
+}
+
+
+##############################################################
+# PKI Instance Removal
+##############################################################
+
+main();
+
+exit 0;
+
diff --git a/base/setup/scripts/functions b/base/setup/scripts/functions
new file mode 100644
index 000000000..516bf32e2
--- /dev/null
+++ b/base/setup/scripts/functions
@@ -0,0 +1,1121 @@
+#!/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
+}
+
+usage_systemd()
+{
+ echo -n "Usage: /usr/bin/pkicontrol "
+ 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 "subsytem-type "
+ 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 [ $SYSTEMD ]; then
+ if [ $# -lt 2 ] ; then
+ # [insufficient arguments]
+ echo "$PROG_NAME: Insufficient arguments!"
+ echo
+ usage_systemd
+ 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_systemd
+ echo "where valid instance names include:"
+ list_instances
+ exit 2
+ elif [ $# -gt 3 ] ; then
+ echo "$PROG_NAME: Excess arguments!"
+ echo
+ usage_systemd
+ 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
+else
+ 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
+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"
+ if [ ! $SYSTEMD ]; then
+ echo_failure
+ fi
+ 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
+
+ return 0;
+}
+
+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
+
+ return 0;
+}
+
+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
+
+ return 0;
+}
+
+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_systemd()
+{
+ echo -n "Status for ${PKI_INSTANCE_ID}: "
+ systemctl status "$PKI_SYSTEMD_TARGET@$PKI_INSTANCE_ID.service" > /dev/null 2>&1
+ rv=$?
+
+ if [ $rv -eq 0 ] ; then
+ echo "$PKI_INSTANCE_ID is running .."
+ display_configuration_information
+ else
+ echo "$PKI_INSTANCE_ID is stopped"
+ fi
+
+ return $rv
+}
+
+display_instance_status()
+{
+ # 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)
+
+ # We must export the service name so that the systemd version
+ # of the tomcat6 init script knows which instance specific
+ # configuration file to source.
+ export SERVICE_NAME=$PKI_INSTANCE_ID
+
+ 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
+
+ export SERVICE_NAME=$PKI_INSTANCE_ID
+ # 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
+
+ case $PKI_SUBSYSTEM_TYPE in
+ ca|kra|ocsp|tks)
+ if [ $SYSTEMD ]; then
+ display_instance_status_systemd
+ else
+ display_instance_status
+ fi
+ rv=$?
+ ;;
+ tps|ra)
+ display_instance_status
+ rv=$?
+ ;;
+ esac
+ 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/base/setup/scripts/pki_apache_initscript b/base/setup/scripts/pki_apache_initscript
new file mode 100755
index 000000000..e51231065
--- /dev/null
+++ b/base/setup/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/base/setup/scripts/pkicontrol b/base/setup/scripts/pkicontrol
new file mode 100755
index 000000000..f9a279b07
--- /dev/null
+++ b/base/setup/scripts/pkicontrol
@@ -0,0 +1,73 @@
+#!/bin/bash
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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-2010 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+
+PROG_NAME=`basename $0`
+SERVICE_NAME="pkicontrol"
+SERVICE_PROG="/bin/systemctl"
+
+command="$1"
+pki_subsystem_type="$2"
+pki_instance="$3"
+
+PKI_PATH="/usr/share/pki/${pki_subsystem_type}"
+PKI_REGISTRY="/etc/sysconfig/pki/${pki_subsystem_type}"
+PKI_TYPE="pki-${pki_subsystem_type}"
+PKI_SYSTEMD_TARGET="pki-${pki_subsystem_type}d"
+SYSTEMD=1
+
+# Source the PKI function library
+. /usr/share/pki/scripts/functions
+
+# See how we were called.
+case $command in
+ status)
+ registry_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 ${default_error}
+ ;;
+ *)
+ echo "unknown action ($command)"
+ usage
+ echo "where valid instance names include:"
+ list_instances
+ exit ${default_error}
+ ;;
+esac
+
diff --git a/base/silent/CMakeLists.txt b/base/silent/CMakeLists.txt
new file mode 100644
index 000000000..8f71375dc
--- /dev/null
+++ b/base/silent/CMakeLists.txt
@@ -0,0 +1,17 @@
+project(silent Java)
+
+add_subdirectory(src)
+add_subdirectory(scripts)
+
+install(
+ FILES
+ templates/pki_silent.template
+ templates/subca_silent.template
+ DESTINATION
+ ${DATA_INSTALL_DIR}/silent/
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
diff --git a/base/silent/LICENSE b/base/silent/LICENSE
new file mode 100644
index 000000000..e281f4362
--- /dev/null
+++ b/base/silent/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/base/silent/scripts/CMakeLists.txt b/base/silent/scripts/CMakeLists.txt
new file mode 100644
index 000000000..df4dfc469
--- /dev/null
+++ b/base/silent/scripts/CMakeLists.txt
@@ -0,0 +1,10 @@
+install(
+ FILES
+ pkisilent
+ DESTINATION
+ ${BIN_INSTALL_DIR}
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
diff --git a/base/silent/scripts/pkisilent b/base/silent/scripts/pkisilent
new file mode 100755
index 000000000..c5be67855
--- /dev/null
+++ b/base/silent/scripts/pkisilent
@@ -0,0 +1,117 @@
+#!/usr/bin/perl
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+
+###############################################################################
+## (1) Specify variables used by this script. ##
+###############################################################################
+
+my $PRODUCT="pki";
+my $libpath="";
+
+
+###############################################################################
+## (2) Define helper functions. ##
+###############################################################################
+
+sub invalid_architecture()
+{
+ print "\n";
+ print "ERROR: pkisilent does not execute on this architecture\n";
+ print "ERROR: check to make sure pki-native-tools package is installed!\n";
+ print "\n";
+}
+
+
+###############################################################################
+## (3) Set the LD_LIBRARY_PATH environment variable ##
+## (as well as the ${libpath} java property) to determine the ##
+## search order this command uses to find shared libraries. ##
+###############################################################################
+
+my $ARCHITECTURE=`uname -i`;
+chop( $ARCHITECTURE );
+
+if( $ARCHITECTURE eq "i386" ) {
+ $libpath="/usr/lib";
+
+ $ENV{LD_LIBRARY_PATH} = "/usr/lib/jss:"
+ . "/usr/lib:/lib";
+} elsif($ARCHITECTURE eq "x86_64") {
+ $libpath="/usr/lib64";
+
+ $ENV{LD_LIBRARY_PATH} = "/usr/lib64/jss:"
+ . "/usr/lib64:/lib64:"
+ . "/usr/lib/jss:"
+ . "/usr/lib:/lib";
+} else {
+ invalid_architecture();
+ exit(255);
+}
+
+
+###############################################################################
+## (4) Set the CP environment variable to determine the search ##
+## order this command wrapper uses to find jar files. ##
+###############################################################################
+
+print "libpath=$libpath\n";
+
+$ENV{CLASSPATH} = "/usr/share/java/${PRODUCT}/pki-silent.jar:"
+ . "/usr/share/java/${PRODUCT}/pki-certsrv.jar:"
+ . "/usr/share/java/${PRODUCT}/pki-cmscore.jar:"
+ . "/usr/share/java/${PRODUCT}/pki-nsutil.jar:"
+ . "/usr/share/java/${PRODUCT}/pki-cmsutil.jar:"
+ . "/usr/share/java/${PRODUCT}/pki-tools.jar:"
+ . "/usr/share/java/ldapjdk.jar:"
+ . "/usr/share/java/commons-codec.jar:"
+ . "/usr/share/java/xerces-j2.jar:"
+ . "/usr/share/java/xml-commons-apis.jar:"
+ . "/usr/share/java/xml-commons-resolver.jar:";
+if( $ARCHITECTURE eq "x86_64" ) {
+ $ENV{CLASSPATH} = $ENV{CLASSPATH}
+ . "/usr/lib64/java/jss4.jar:"
+ . "/usr/lib/java/jss4.jar:";
+} else {
+ $ENV{CLASSPATH} = $ENV{CLASSPATH}
+ . "/usr/lib/java/jss4.jar:";
+}
+
+
+###############################################################################
+## (5) Execute the java command specified by this java command wrapper ##
+## based upon the preset LD_LIBRARY_PATH and CP environment variables. ##
+###############################################################################
+
+my @args = ();
+foreach (@ARGV) {
+ push(@args, quotemeta($_));
+}
+my $output = `java -cp $ENV{CLASSPATH} com.netscape.pkisilent.PKISilent @args`;
+my $status = $?;
+
+print "#######################################################################\n";
+print "$output\n";
+print "#######################################################################\n";
+
+if ($status != 0) {
+ exit(255);
+} else {
+ exit(0);
+}
diff --git a/base/silent/src/CMakeLists.txt b/base/silent/src/CMakeLists.txt
new file mode 100644
index 000000000..a3e6034f8
--- /dev/null
+++ b/base/silent/src/CMakeLists.txt
@@ -0,0 +1,82 @@
+project(pki-silent_java Java)
+
+find_file(JSS_JAR
+ NAMES
+ jss4.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(LDAPJDK_JAR
+ NAMES
+ ldapjdk.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(XERCES_JAR
+ NAMES
+ xerces-j2.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+set(pki-silent_java_SRCS
+ com/netscape/pkisilent/ConfigureTKS.java
+ com/netscape/pkisilent/ConfigureCA.java
+ com/netscape/pkisilent/argparser/CharHolder.java
+ com/netscape/pkisilent/argparser/ArgParseException.java
+ com/netscape/pkisilent/argparser/StringHolder.java
+ com/netscape/pkisilent/argparser/SimpleExample.java
+ com/netscape/pkisilent/argparser/ArgParser.java
+ com/netscape/pkisilent/argparser/DoubleHolder.java
+ com/netscape/pkisilent/argparser/ObjectHolder.java
+ com/netscape/pkisilent/argparser/FloatHolder.java
+ com/netscape/pkisilent/argparser/BooleanHolder.java
+ com/netscape/pkisilent/argparser/StringScanException.java
+ com/netscape/pkisilent/argparser/StringScanner.java
+ com/netscape/pkisilent/argparser/LongHolder.java
+ com/netscape/pkisilent/argparser/IntHolder.java
+ com/netscape/pkisilent/ConfigureTPS.java
+ com/netscape/pkisilent/http/HTTPClient.java
+ com/netscape/pkisilent/http/HTMLDocument.java
+ com/netscape/pkisilent/http/HTTPResponse.java
+ com/netscape/pkisilent/http/CertSelection.java
+ com/netscape/pkisilent/common/Request.java
+ com/netscape/pkisilent/common/CertificateRecord.java
+ com/netscape/pkisilent/common/Utilities.java
+ com/netscape/pkisilent/common/ComCrypto.java
+ com/netscape/pkisilent/common/BaseState.java
+ com/netscape/pkisilent/common/CMSLDAP.java
+ com/netscape/pkisilent/common/CMSConfig.java
+ com/netscape/pkisilent/common/PostQuery.java
+ com/netscape/pkisilent/common/ServerInfo.java
+ com/netscape/pkisilent/common/UserEnroll.java
+ com/netscape/pkisilent/common/ParseXML.java
+ com/netscape/pkisilent/common/CMSProperties.java
+ com/netscape/pkisilent/common/DirEnroll.java
+ com/netscape/pkisilent/common/Con2Agent.java
+ com/netscape/pkisilent/common/TestClient.java
+ com/netscape/pkisilent/common/CMSTask.java
+ com/netscape/pkisilent/ConfigureOCSP.java
+ com/netscape/pkisilent/ConfigureRA.java
+ com/netscape/pkisilent/ConfigureSubCA.java
+ com/netscape/pkisilent/ConfigureDRM.java
+ com/netscape/pkisilent/PKISilent.java
+)
+
+set(CMAKE_JAVA_INCLUDE_PATH
+ ${PKI_CERTSRV_JAR} ${PKI_CMS_JAR}
+ ${PKI_CMSUTIL_JAR} ${PKI_NSUTIL_JAR}
+ ${LDAPJDK_JAR} ${XERCES_JAR}
+ ${JSS_JAR} ${COMMONS_CODEC_JAR} ${SYMKEY_JAR})
+
+set(CMAKE_JAVA_TARGET_VERSION ${APPLICATION_VERSION})
+
+add_jar(pki-silent ${pki-silent_java_SRCS})
+add_dependencies(pki-silent symkey pki-cmsutil pki-nsutil pki-certsrv pki-cms)
+install_jar(pki-silent ${JAVA_JAR_INSTALL_DIR}/pki)
+set(PKI_SILENT_JAR ${pki-silent_JAR_FILE} CACHE INTERNAL "pki-silent jar file")
diff --git a/base/silent/src/com/netscape/pkisilent/ConfigureCA.java b/base/silent/src/com/netscape/pkisilent/ConfigureCA.java
new file mode 100644
index 000000000..3c498febe
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/ConfigureCA.java
@@ -0,0 +1,1698 @@
+package com.netscape.pkisilent;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.pkcs12.AuthenticatedSafes;
+import org.mozilla.jss.pkcs12.PFX;
+
+import com.netscape.pkisilent.argparser.ArgParser;
+import com.netscape.pkisilent.argparser.StringHolder;
+import com.netscape.pkisilent.common.ComCrypto;
+import com.netscape.pkisilent.common.ParseXML;
+import com.netscape.pkisilent.http.HTTPClient;
+import com.netscape.pkisilent.http.HTTPResponse;
+import com.netscape.cmsutil.util.Utils;
+
+public class ConfigureCA {
+
+ // global constants
+ public static final String DEFAULT_KEY_TYPE = "RSA";
+ public static final String DEFAULT_KEY_SIZE = "2048";
+ public static final String DEFAULT_KEY_CURVENAME = "nistp256";
+ public static final String DEFAULT_KEY_ALGORITHM_RSA = "SHA256withRSA";
+ public static final String DEFAULT_KEY_ALGORITHM_ECC = "SHA256withEC";
+ public static final String SUCCESS = "success";
+ public static final String FAILURE = "failure";
+
+ // define global variables
+
+ public static HTTPClient hc = null;
+
+ public static String login_uri = "/ca/admin/console/config/login";
+ public static String wizard_uri = "/ca/admin/console/config/wizard";
+ public static String admin_uri = "/ca/admin/ca/getBySerial";
+ public static String pkcs12_uri = "/ca/admin/console/config/savepkcs12";
+ public static String sd_login_uri = "/ca/admin/ca/securityDomainLogin";
+ public static String sd_get_cookie_uri = "/ca/admin/ca/getCookie";
+
+ public static String cs_hostname = null;
+ public static String cs_port = null;
+ public static String client_certdb_dir = null;
+ public static String client_certdb_pwd = null;
+
+ public static String sd_hostname = null;
+ public static String sd_ssl_port = null;
+ public static String sd_agent_port = null;
+ public static String sd_admin_port = null;
+ public static String sd_admin_name = null;
+ public static String sd_admin_password = null;
+
+ // Login Panel
+ public static String pin = null;
+
+ public static String domain_name = null;
+
+ public static String admin_user = null;
+ public static String admin_email = null;
+ public static String admin_password = null;
+ public static String admin_serial_number = null;
+ public static String agent_name = null;
+
+ public static String ldap_host = null;
+ public static String ldap_port = null;
+ public static String bind_dn = null;
+ public static String bind_password = null;
+ public static String base_dn = null;
+ public static String db_name = null;
+ public static String secure_conn = null;
+ public static String remove_data = null;
+
+ public static String key_type = null;
+ public static String key_size = null;
+ public static String key_curvename = null;
+ public static String key_algorithm = null;
+ public static String signing_algorithm = null;
+
+ public static String signing_key_type = null;
+ public static String signing_key_size = null;
+ public static String signing_key_curvename = null;
+ public static String signing_signingalgorithm = null;
+
+ public static String ocsp_signing_key_type = null;
+ public static String ocsp_signing_key_size = null;
+ public static String ocsp_signing_key_curvename = null;
+ public static String ocsp_signing_signingalgorithm = null;
+
+ public static String subsystem_key_type = null;
+ public static String subsystem_key_size = null;
+ public static String subsystem_key_curvename = null;
+
+ public static String audit_signing_key_type = null;
+ public static String audit_signing_key_size = null;
+ public static String audit_signing_key_curvename = null;
+
+ public static String sslserver_key_type = null;
+ public static String sslserver_key_size = null;
+ public static String sslserver_key_curvename = null;
+
+ public static String token_name = null;
+ public static String token_pwd = null;
+
+ public static String agent_key_size = null;
+ public static String agent_key_type = null;
+ public static String agent_cert_subject = null;
+
+ public static String save_p12 = null;
+ public static String backup_pwd = null;
+ public static String backup_fname = null;
+
+ public static String ca_cert_name = null;
+ public static String ca_cert_req = null;
+ public static String ca_cert_pp = null;
+ public static String ca_cert_cert = null;
+
+ public static String ocsp_cert_name = null;
+ public static String ocsp_cert_req = null;
+ public static String ocsp_cert_pp = null;
+ public static String ocsp_cert_cert = null;
+
+ public static String server_cert_name = null;
+ public static String server_cert_req = null;
+ public static String server_cert_pp = null;
+ public static String server_cert_cert = null;
+
+ public static String ca_subsystem_cert_name = null;
+ public static String ca_subsystem_cert_req = null;
+ public static String ca_subsystem_cert_pp = null;
+ public static String ca_subsystem_cert_cert = null;
+
+ public static String ca_audit_signing_cert_name = null;
+ public static String ca_audit_signing_cert_req = null;
+ public static String ca_audit_signing_cert_pp = null;
+ public static String ca_audit_signing_cert_cert = null;
+
+ // names
+ public static String ca_sign_cert_subject_name = null;
+ public static String ca_subsystem_cert_subject_name = null;
+ public static String ca_ocsp_cert_subject_name = null;
+ public static String ca_server_cert_subject_name = null;
+ public static String ca_audit_signing_cert_subject_name = null;
+
+ public static String subsystem_name = null;
+
+ public static String external_ca = null;
+ public static String ext_ca_cert_file = null;
+ public static String ext_ca_cert_chain_file = null;
+ public static String ext_csr_file = null;
+ public static String signing_cc = null;
+
+ public static boolean clone = false;
+ public static String clone_uri = null;
+ public static String clone_p12_passwd = null;
+ public static String clone_p12_file = null;
+ public static String clone_master_port = null;
+ public static String clone_replica_port = null;
+ public static String clone_replication_security = null;
+
+ //for correct selection of CA to be cloned
+ public static String urls;
+
+ public ConfigureCA() {// do nothing :)
+ }
+
+ public String getStatus(HTTPResponse hr, String name) {
+ ByteArrayInputStream bais = null;
+ String status = null;
+ try {
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ ParseXML px = new ParseXML();
+ px.parse(bais);
+ px.prettyprintxml();
+ status = px.getvalue(name);
+ } catch (Exception e) {
+ System.out.println("Exception in getStatus(): " + e.toString());
+ }
+ return status;
+ }
+
+ public boolean checkStatus(HTTPResponse hr, String name,
+ String expected, String location) {
+ return checkStatus(hr, name, new String[] { expected }, location);
+ }
+
+ public boolean checkStatus(HTTPResponse hr, String name,
+ String[] expected, String location) {
+ String status = getStatus(hr, name);
+ if (status == null) {
+ System.out.println("Error in " + location + ": " + name +
+ " value is null");
+ return false;
+ }
+ for (int i = 0; i < expected.length; i++) {
+ if (status.equals(expected[i])) {
+ return true;
+ }
+ }
+ System.out.println("Error in " + location + ": " + name +
+ " returns " + status);
+ return false;
+ }
+
+ public boolean LoginPanel() {
+ try {
+ boolean st = false;
+ HTTPResponse hr = null;
+
+ String query_string = "pin=" + pin + "&xml=true";
+ hr = hc.sslConnect(cs_hostname, cs_port, login_uri, query_string);
+ System.out.println("xml returned: " + hr.getHTML());
+
+ // parse xml here - nothing to parse
+
+ // get cookie
+ String temp = hr.getCookieValue("JSESSIONID");
+ if (temp != null) {
+ int index = temp.indexOf(";");
+
+ HTTPClient.j_session_id = temp.substring(0, index);
+ st = true;
+ }
+
+ hr = null;
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri,
+ "p=0&op=next&xml=true");
+ if (!checkStatus(hr, "status", "display", "LoginPanel()")) {
+ return false;
+ }
+
+ return st;
+ } catch (Exception e) {
+ System.out.println("Exception in LoginPanel(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public boolean TokenChoicePanel() {
+ try {
+ HTTPResponse hr = null;
+ String query_string = null;
+
+ // Software Token
+ if (token_name.equalsIgnoreCase("internal")) {
+ query_string = "p=1" + "&op=next" + "&xml=true" + "&choice="
+ + URLEncoder.encode("Internal Key Storage Token", "UTF-8") + "";
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ if (!checkStatus(hr, "updateStatus", SUCCESS, "TokenChoicePanel()")) {
+ return false;
+ }
+ } // HSM
+ else {
+ // login to hsm first
+ query_string = "p=2" + "&op=next" + "&xml=true" + "&uTokName="
+ + URLEncoder.encode(token_name, "UTF-8") + "&__uPasswd="
+ + URLEncoder.encode(token_pwd, "UTF-8") + "";
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ if (!checkStatus(hr, "updateStatus", SUCCESS, "TokenChoicePanel()")) {
+ return false;
+ }
+
+ // choice with token name now
+ query_string = "p=1" + "&op=next" + "&xml=true" + "&choice="
+ + URLEncoder.encode(token_name, "UTF-8") + "";
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ if (!checkStatus(hr, "updateStatus", SUCCESS, "TokenChoicePanel()")) {
+ return false;
+ }
+ }
+ return true;
+ } catch (Exception e) {
+ System.out.println("Exception in TokenChoicePanel(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public boolean DomainPanel() {
+ try {
+ HTTPResponse hr = null;
+ String domain_url = "https://" + cs_hostname + ":" + cs_port;
+ String query_string = null;
+
+ if (!clone) {
+ query_string = "sdomainURL=" + URLEncoder.encode(domain_url, "UTF-8")
+ + "&sdomainName=" + URLEncoder.encode(domain_name, "UTF-8")
+ + "&choice=newdomain" + "&p=3" + "&op=next" + "&xml=true";
+ } else {
+ domain_url = "https://" + sd_hostname + ":" + sd_admin_port;
+ query_string = "sdomainURL=" + URLEncoder.encode(domain_url, "UTF-8")
+ + "&sdomainName="
+ + "&choice=existingdomain" + "&p=3" + "&op=next" + "&xml=true";
+ }
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ if (!checkStatus(hr, "updateStatus", SUCCESS, "DomainPanel()")) {
+ return false;
+ }
+
+ return true;
+ } catch (Exception e) {
+ System.out.println("Exception in DomainPanel(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public boolean DisplayCertChainPanel() {
+ try {
+ String query_string = "p=4" + "&op=next" + "&xml=true";
+ hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ return true;
+ } catch (Exception e) {
+ System.out.println("Exception in DisplayCertChainPanel(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public boolean SecurityDomainLoginPanel() {
+ try {
+ HTTPResponse hr = null;
+
+ String subca_url = "https://" + cs_hostname + ":" + cs_port +
+ "/ca/admin/console/config/wizard" + "?p=5&subsystem=CA";
+
+ String query_string = "url=" + URLEncoder.encode(subca_url, "UTF-8");
+
+ hr = hc.sslConnect(sd_hostname, sd_admin_port, sd_login_uri, query_string);
+
+ String query_string_1 = "uid=" + sd_admin_name + "&pwd=" + URLEncoder.encode(sd_admin_password, "UTF-8") +
+ "&url=" + URLEncoder.encode(subca_url, "UTF-8");
+
+ hr = hc.sslConnect(sd_hostname, sd_admin_port, sd_get_cookie_uri,
+ query_string_1);
+
+ // get session id from security domain
+
+ String subca_session_id = hr.getContentValue("header.session_id");
+ String subca_url_1 = hr.getContentValue("header.url");
+
+ System.out.println("SUBCA_SESSION_ID=" + subca_session_id);
+ System.out.println("SUBCA_URL=" + subca_url_1);
+
+ // use session id to connect back to subCA
+
+ String query_string_2 = "p=5" + "&subsystem=CA" +
+ "&session_id=" + subca_session_id + "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string_2);
+ urls = hr.getHTML();
+ int indx = urls.indexOf(clone_uri);
+ if (indx < 0) {
+ throw new Exception("Invalid clone_uri");
+ }
+ urls = urls.substring(urls.lastIndexOf("<option", indx), indx);
+ urls = urls.split("\"")[1];
+
+ System.out.println("urls =" + urls);
+ return true;
+ } catch (Exception e) {
+ System.out.println("Exception in SecurityDomainLoginPanel(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public boolean CreateCAPanel() {
+ try {
+ HTTPResponse hr = null;
+ String query_string = null;
+
+ if (!clone) {
+ query_string = "p=5" + "&op=next" + "&xml=true"
+ + "&choice=newsubsystem" + "&subsystemName="
+ + URLEncoder.encode(subsystem_name, "UTF-8");
+ } else {
+ query_string = "p=5" + "&op=next" + "&xml=true"
+ + "&choice=clonesubsystem" + "&subsystemName="
+ + URLEncoder.encode(subsystem_name, "UTF-8")
+ + "&urls=" + urls + "";
+ }
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ if (!checkStatus(hr, "updateStatus", SUCCESS, "CreateCAPanel()")) {
+ return false;
+ }
+
+ if (clone) {
+
+ hr = null;
+ query_string = "p=6" + "&op=next" + "&xml=true";
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ if (!checkStatus(hr, "updateStatus", SUCCESS, "CreateCAPanel(2)")) {
+ return false;
+ }
+ }
+
+ return true;
+ } catch (Exception e) {
+ System.out.println("Exception in CreateCAPanel(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public boolean RestoreKeyCertPanel() {
+ try {
+ HTTPResponse hr = null;
+
+ String query_string = "p=7" + "&op=next" + "&xml=true"
+ + "&__password=" + URLEncoder.encode(clone_p12_passwd, "UTF-8")
+ + "&path=" + URLEncoder.encode(clone_p12_file, "UTF-8") + "";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ if (!checkStatus(hr, "updateStatus", SUCCESS, "RestoreKeyCertPanel()")) {
+ return false;
+ }
+ return true;
+ } catch (Exception e) {
+ System.out.println("Exception in RestoreKeyCertPanel(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public boolean HierarchyPanel() {
+ try {
+ HTTPResponse hr = null;
+
+ String query_string = "p=8" + "&op=next" + "&xml=true";
+ if (external_ca.equalsIgnoreCase("true"))
+ query_string += "&choice=join";
+ else
+ query_string += "&choice=root";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ if (!checkStatus(hr, "updateStatus", SUCCESS, "HierarchyPanel()")) {
+ return false;
+ }
+
+ return true;
+ } catch (Exception e) {
+ System.out.println("Exception in HierarchyPanel(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+
+ }
+
+ public boolean LdapConnectionPanel() {
+ try {
+ HTTPResponse hr = null;
+
+ String query_string = "p=9" + "&op=next" + "&xml=true" + "&host="
+ + URLEncoder.encode(ldap_host,"UTF-8") + "&port="
+ + URLEncoder.encode(ldap_port,"UTF-8") + "&binddn="
+ + URLEncoder.encode(bind_dn, "UTF-8") + "&__bindpwd="
+ + URLEncoder.encode(bind_password, "UTF-8") + "&basedn="
+ + URLEncoder.encode(base_dn, "UTF-8") + "&database="
+ + URLEncoder.encode(db_name, "UTF-8") + "&display="
+ + URLEncoder.encode("$displayStr", "UTF-8")
+ + (secure_conn.equals("true") ? "&secureConn=on" : "")
+ + "&masterReplicationPort=" + URLEncoder.encode(clone_master_port, "UTF-8")
+ + "&cloneReplicationPort=" + URLEncoder.encode(clone_replica_port, "UTF-8")
+ + "&replicationSecurity=" + URLEncoder.encode(clone_replication_security, "UTF-8")
+ + (remove_data.equals("true") ? "&removeData=true" : "");
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ if (!checkStatus(hr, "updateStatus", SUCCESS, "LdapConnectionPanel()")) {
+ return false;
+ }
+
+ return true;
+ } catch (Exception e) {
+ System.out.println("Exception in LdapConnectionPanel(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public boolean KeyPanel() {
+ try {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+ ArrayList<String> al = null;
+ String query_string = null;
+ if (clone) {
+ query_string = "p=10" + "&op=next" + "&xml=true"
+ + "&sslserver_custom_size=" + sslserver_key_size
+ + "&sslserver_custom_curvename=" + sslserver_key_curvename
+ + "&sslserver_choice=custom"
+ + "&sslserver_keytype=" + sslserver_key_type
+ + "&choice=custom" + "&keytype=" + key_type
+ + "&custom_size=" + key_size;
+ } else {
+ query_string = "p=10" + "&op=next" + "&xml=true"
+ + "&subsystem_custom_size=" + subsystem_key_size
+ + "&subsystem_custom_curvename=" + subsystem_key_curvename
+ + "&subsystem_keytype=" + subsystem_key_type
+ + "&subsystem_choice=custom"
+ + "&sslserver_custom_size=" + sslserver_key_size
+ + "&sslserver_custom_curvename=" + sslserver_key_curvename
+ + "&sslserver_keytype=" + sslserver_key_type
+ + "&sslserver_choice=custom"
+ + "&signing_custom_size=" + signing_key_size
+ + "&signing_custom_curvename=" + signing_key_curvename
+ + "&signing_keytype=" + signing_key_type
+ + "&signing_choice=custom"
+ + "&signing_keyalgorithm=" + key_algorithm
+ + "&signing_signingalgorithm=" + signing_signingalgorithm
+ + "&ocsp_signing_custom_size=" + ocsp_signing_key_size
+ + "&ocsp_signing_custom_curvename=" + ocsp_signing_key_curvename
+ + "&ocsp_signing_keytype=" + ocsp_signing_key_type
+ + "&ocsp_signing_choice=custom"
+ + "&ocsp_signing_signingalgorithm=" + ocsp_signing_signingalgorithm
+ + "&audit_signing_custom_size=" + audit_signing_key_size
+ + "&audit_signing_custom_curvename=" + audit_signing_key_curvename
+ + "&audit_signing_keytype=" + audit_signing_key_type
+ + "&audit_signing_choice=custom"
+ + "&custom_size=" + key_size
+ + "&custom_curvename=" + key_curvename
+ + "&keytype=" + key_type
+ + "&choice=custom"
+ + "&signingalgorithm=" + signing_algorithm
+ + "&keyalgorithm=" + key_algorithm;
+ }
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ if (!checkStatus(hr, "updateStatus", SUCCESS, "KeyPanel()")) {
+ return false;
+ }
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+
+ al = px.constructValueList("CertReqPair", "DN");
+ // get ca cert subject name
+ if (al != null) {
+ for (int i = 0; i < al.size(); i++) {
+ String temp = al.get(i);
+
+ if (temp.indexOf("Certificate Authority") > 0) {
+ ca_cert_name = temp;
+ } else if (temp.indexOf("OCSP Signing Certificate") > 0) {
+ ocsp_cert_name = temp;
+ } else if (temp.indexOf("Subsystem Certificate") > 0) {
+ ca_subsystem_cert_name = temp;
+ } else if (temp.indexOf("Audit Signing Certificate") > 0) {
+ ca_audit_signing_cert_name = temp;
+ } else {
+ server_cert_name = temp;
+ }
+ }
+ }
+
+ System.out.println("default: ca_cert_name=" + ca_cert_name);
+ System.out.println("default: ocsp_cert_name=" + ocsp_cert_name);
+ System.out.println(
+ "default: ca_subsystem_cert_name=" + ca_subsystem_cert_name);
+ System.out.println(
+ "default: ca_audit_signing_cert_name=" + ca_audit_signing_cert_name);
+ System.out.println("default: server_cert_name=" + server_cert_name);
+ return true;
+ } catch (Exception e) {
+ System.out.println("Exception in KeyPanel(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public boolean CertSubjectPanel() {
+ try {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+ ArrayList<String> req_list = null;
+ ArrayList<String> cert_list = null;
+ ArrayList<String> dn_list = null;
+ String query_string = null;
+
+ // use subject names provided as input
+
+ if (!clone) {
+ query_string = "p=11" + "&op=next" + "&xml=true" + "&subsystem="
+ + URLEncoder.encode(ca_subsystem_cert_subject_name, "UTF-8")
+ + "&ocsp_signing="
+ + URLEncoder.encode(ca_ocsp_cert_subject_name, "UTF-8") + "&signing="
+ + URLEncoder.encode(ca_sign_cert_subject_name, "UTF-8") + "&sslserver="
+ + URLEncoder.encode(ca_server_cert_subject_name, "UTF-8") + "&audit_signing="
+ + URLEncoder.encode(ca_audit_signing_cert_subject_name, "UTF-8") + "&urls=0"
+ + "";
+ } else {
+ query_string = "p=11" + "&op=next" + "&xml=true" + "&sslserver="
+ + URLEncoder.encode(ca_server_cert_subject_name, "UTF-8") + "&urls=0"
+ + "";
+ }
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ if (!checkStatus(hr, "updateStatus", SUCCESS, "CertSubjectPanel()")) {
+ return false;
+ }
+
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+
+ req_list = px.constructValueList("CertReqPair", "Request");
+ cert_list = px.constructValueList("CertReqPair", "Certificate");
+ dn_list = px.constructValueList("CertReqPair", "Nickname");
+
+ System.out.println("req_list_size=" + req_list.size());
+ System.out.println("cert_list_size=" + cert_list.size());
+ System.out.println("dn_list_size=" + dn_list.size());
+
+ if (external_ca.equalsIgnoreCase("true")) {
+ if ((req_list != null) && (dn_list != null)) {
+ for (int i = 0; i < dn_list.size(); i++) {
+ String temp = dn_list.get(i);
+ if (temp.indexOf("caSigningCert") >= 0) {
+ ca_cert_req = req_list.get(i);
+ }
+ }
+ }
+
+ if (ext_ca_cert_file == null) {
+ try {
+ FileOutputStream fos = new FileOutputStream(ext_csr_file);
+ PrintStream p = new PrintStream(fos);
+ p.println(ca_cert_req);
+ p.close();
+ return true;
+ } catch (Exception e) {
+ System.out.println("CertSubjectPanel: Unable to write CSR for external CA to " + ext_csr_file);
+ System.out.println(e.toString());
+ return false;
+ }
+ } else {
+ try {
+ ca_cert_cert = "";
+ FileInputStream fis = new FileInputStream(ext_ca_cert_file);
+ DataInputStream in = new DataInputStream(fis);
+ while (in.available() != 0) {
+ ca_cert_cert += in.readLine();
+ }
+ in.close();
+
+ signing_cc = "";
+ fis = new FileInputStream(ext_ca_cert_chain_file);
+ in = new DataInputStream(fis);
+ while (in.available() != 0) {
+ signing_cc += in.readLine();
+ }
+ in.close();
+ return true;
+ } catch (Exception e) {
+ System.out.println(
+ "CertSubjectPanel: Unable to read in external approved CA cert or certificate chain.");
+ System.out.println(e.toString());
+ return false;
+ }
+ }
+ }
+
+ if (req_list != null && cert_list != null && dn_list != null) {
+ for (int i = 0; i < dn_list.size(); i++) {
+ String temp = dn_list.get(i);
+
+ if (temp.indexOf("caSigningCert") >= 0) {
+ ca_cert_req = req_list.get(i);
+ ca_cert_cert = cert_list.get(i);
+ } else if (temp.indexOf("ocspSigningCert") >= 0) {
+ ocsp_cert_req = req_list.get(i);
+ ocsp_cert_cert = cert_list.get(i);
+ } else if (temp.indexOf("subsystemCert") >= 0) {
+ ca_subsystem_cert_req = req_list.get(i);
+ ca_subsystem_cert_cert = cert_list.get(i);
+ } else if (temp.indexOf("auditSigningCert") >= 0) {
+ ca_audit_signing_cert_req = req_list.get(i);
+ ca_audit_signing_cert_cert = cert_list.get(i);
+ } else {
+ server_cert_req = req_list.get(i);
+ server_cert_cert = cert_list.get(i);
+ }
+ }
+ }
+
+ // print out subject names
+ System.out.println("ca_cert_name=" + ca_sign_cert_subject_name);
+ System.out.println("ocsp_cert_name=" + ca_ocsp_cert_subject_name);
+ System.out.println(
+ "ca_subsystem_cert_name=" + ca_subsystem_cert_subject_name);
+ System.out.println("server_cert_name=" + ca_server_cert_subject_name);
+ System.out.println("audit_signing_cert_name=" + ca_audit_signing_cert_subject_name);
+
+ // print out requests
+ System.out.println("ca_cert_req=" + ca_cert_req);
+ System.out.println("ocsp_cert_req=" + ocsp_cert_req);
+ System.out.println("ca_subsystem_cert_req=" + ca_subsystem_cert_req);
+ System.out.println("server_cert_req=" + server_cert_req);
+ System.out.println("ca_audit_siging_cert_req=" + ca_audit_signing_cert_req);
+
+ // print out certs
+ System.out.println("ca_cert_cert=" + ca_cert_cert);
+ System.out.println("ocsp_cert_cert=" + ocsp_cert_cert);
+ System.out.println("ca_subsystem_cert_cert=" + ca_subsystem_cert_cert);
+ System.out.println("server_cert_cert=" + server_cert_cert);
+ System.out.println("ca_audit_signing_cert_cert=" + ca_audit_signing_cert_cert);
+
+ return true;
+ } catch (Exception e) {
+ System.out.println("Exception in CertSubjectPanel(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+
+ }
+
+ public boolean CertificatePanel() {
+ try {
+ HTTPResponse hr = null;
+
+ String query_string = "p=12" + "&op=next" + "&xml=true" + "&subsystem="
+ + URLEncoder.encode(ca_subsystem_cert_cert, "UTF-8") + "&subsystem_cc="
+ + "&ocsp_signing=" + URLEncoder.encode(ocsp_cert_cert, "UTF-8")
+ + "&ocsp_signing_cc=" + "&signing="
+ + URLEncoder.encode(ca_cert_cert, "UTF-8") + "&signing_cc="
+ + "&audit_signing=" + URLEncoder.encode(ca_audit_signing_cert_cert, "UTF-8")
+ + "&audit_signing_cc="
+ + "&sslserver=" + URLEncoder.encode(server_cert_cert, "UTF-8")
+ + "&sslserver_cc=" + "";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ if (!checkStatus(hr, "updateStatus", SUCCESS, "CertificatePanel()")) {
+ return false;
+ }
+
+ return true;
+ } catch (Exception e) {
+ System.out.println("Exception in CertificatePanel(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+
+ }
+
+ public boolean CertificatePanelExternal() {
+ try {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+ ArrayList<String> req_list = null;
+ ArrayList<String> cert_list = null;
+ ArrayList<String> dn_list = null;
+ String genString = "...certificate be generated internally...";
+
+ String query_string = "p=12" + "&op=apply" + "&xml=true" + "&subsystem="
+ + URLEncoder.encode(genString, "UTF-8") + "&subsystem_cc="
+ + "&ocsp_signing=" + URLEncoder.encode(genString, "UTF-8")
+ + "&ocsp_signing_cc=" + "&signing="
+ + URLEncoder.encode(ca_cert_cert, "UTF-8") + "&signing_cc="
+ + URLEncoder.encode(signing_cc, "UTF-8")
+ + "&audit_signing=" + URLEncoder.encode(genString, "UTF-8")
+ + "&audit_signing_cc="
+ + "&sslserver=" + URLEncoder.encode(genString, "UTF-8")
+ + "&sslserver_cc=" + "";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ if (!checkStatus(hr, "updateStatus", SUCCESS, "CertificatePanelExternal()")) {
+ return false;
+ }
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+
+ req_list = px.constructValueList("CertReqPair", "Request");
+ cert_list = px.constructValueList("CertReqPair", "Certificate");
+ dn_list = px.constructValueList("CertReqPair", "Nickname");
+
+ System.out.println("req_list_size=" + req_list.size());
+ System.out.println("cert_list_size=" + cert_list.size());
+ System.out.println("dn_list_size=" + dn_list.size());
+
+ if (req_list != null && cert_list != null && dn_list != null) {
+ for (int i = 0; i < dn_list.size(); i++) {
+ String temp = dn_list.get(i);
+
+ if (temp.indexOf("caSigningCert") >= 0) {
+ ca_cert_req = req_list.get(i);
+ ca_cert_cert = cert_list.get(i);
+ } else if (temp.indexOf("ocspSigningCert") >= 0) {
+ ocsp_cert_req = req_list.get(i);
+ ocsp_cert_cert = cert_list.get(i);
+ } else if (temp.indexOf("subsystemCert") >= 0) {
+ ca_subsystem_cert_req = req_list.get(i);
+ ca_subsystem_cert_cert = cert_list.get(i);
+ } else if (temp.indexOf("auditSigningCert") >= 0) {
+ ca_audit_signing_cert_req = req_list.get(i);
+ ca_audit_signing_cert_cert = cert_list.get(i);
+ } else {
+ server_cert_req = req_list.get(i);
+ server_cert_cert = cert_list.get(i);
+ }
+ }
+ }
+
+ // print out subject name
+ System.out.println("ca_cert_name=" + ca_sign_cert_subject_name);
+ System.out.println("ocsp_cert_name=" + ca_ocsp_cert_subject_name);
+ System.out.println(
+ "ca_subsystem_cert_name=" + ca_subsystem_cert_subject_name);
+ System.out.println("server_cert_name=" + ca_server_cert_subject_name);
+ System.out.println(
+ "ca_audit_signing_cert_name=" + ca_audit_signing_cert_subject_name);
+
+ // print out requests
+ System.out.println("ca_cert_req=" + ca_cert_req);
+ System.out.println("ocsp_cert_req=" + ocsp_cert_req);
+ System.out.println("ca_subsystem_cert_req=" + ca_subsystem_cert_req);
+ System.out.println("server_cert_req=" + server_cert_req);
+ System.out.println("ca_audit_signing_cert_req=" + ca_audit_signing_cert_req);
+
+ // print out certs
+ System.out.println("ca_cert_cert=" + ca_cert_cert);
+ System.out.println("ocsp_cert_cert=" + ocsp_cert_cert);
+ System.out.println("ca_subsystem_cert_cert=" + ca_subsystem_cert_cert);
+ System.out.println("server_cert_cert=" + server_cert_cert);
+ System.out.println("ca_audit_signing_cert_cert=" + ca_audit_signing_cert_cert);
+
+ return true;
+ } catch (Exception e) {
+ System.out.println("Exception in CertificatePanelExternal(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+
+ }
+
+ public boolean BackupPanel() {
+ try {
+ HTTPResponse hr = null;
+
+ if (save_p12.equalsIgnoreCase("true")) {
+ String query_string = "p=13" + "&op=next" + "&xml=true"
+ + "&choice=backupkey" + "&__pwd=" + URLEncoder.encode(backup_pwd, "UTF-8")
+ + "&__pwdagain=" + URLEncoder.encode(backup_pwd, "UTF-8");
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ if (!checkStatus(hr, "updateStatus", SUCCESS, "BackupPanel()")) {
+ return false;
+ }
+
+ query_string = "";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, pkcs12_uri, query_string);
+
+ // dump hr.getResponseData() to file
+
+ try {
+ FileOutputStream fos = new FileOutputStream(backup_fname);
+
+ fos.write(hr.getResponseData());
+ fos.close();
+
+ // set file to permissions 600
+ String rtParams[] = { "chmod", "600", backup_fname };
+ Process proc = Runtime.getRuntime().exec(rtParams);
+
+ BufferedReader br = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
+ String line = null;
+ while ((line = br.readLine()) != null)
+ System.out.println("Error: " + line);
+ proc.waitFor();
+
+ // verify p12 file
+ // Decode the P12 file
+ FileInputStream fis = new FileInputStream(backup_fname);
+ PFX.Template pfxt = new PFX.Template();
+ PFX pfx = (PFX) pfxt.decode(new BufferedInputStream(fis, 2048));
+
+ System.out.println("Decoded PFX");
+
+ // now peruse it for interesting info
+ System.out.println("Version: " + pfx.getVersion());
+ AuthenticatedSafes authSafes = pfx.getAuthSafes();
+ SEQUENCE asSeq = authSafes.getSequence();
+
+ System.out.println(
+ "AuthSafes has " + asSeq.size() + " SafeContents");
+
+ fis.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ return true;
+ } catch (Exception e) {
+ System.out.println("Exception in BackupPanel(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public boolean BackupContinuePanel() {
+ try {
+ HTTPResponse hr = null;
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri,
+ "p=14&op=next&xml=true");
+ if (!checkStatus(hr, "updateStatus", SUCCESS, "BackupContinuePanel()")) {
+ return false;
+ }
+
+ return true;
+ } catch (Exception e) {
+ System.out.println("Exception in BackupContinuePanel(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public boolean ImportCACertPanel() {
+ try {
+ HTTPResponse hr = null;
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri,
+ "p=15&op=next&xml=true");
+ if (!checkStatus(hr, "updateStatus", SUCCESS, "ImportCACertPanel()")) {
+ return false;
+ }
+
+ return true;
+ } catch (Exception e) {
+ System.out.println("Exception in ImportCACertPanel(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public boolean AdminCertReqPanel() {
+ try {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+ String admin_cert_request = null;
+
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir, client_certdb_pwd,
+ agent_cert_subject, agent_key_size, agent_key_type);
+
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(true);
+ cCrypt.setTransportCert(null);
+ cCrypt.setDualKey(false);
+ cCrypt.loginDB();
+
+ String crmf_request = cCrypt.generateCRMFrequest();
+
+ if (crmf_request == null) {
+ System.out.println("ERROR: AdminCertReqPanel() cert req gen failed");
+ return false;
+ }
+
+ admin_cert_request = crmf_request;
+
+ String query_string = "p=16" + "&op=next" + "&xml=true"
+ + "&cert_request_type=" + "crmf" + "&uid=" + admin_user
+ + "&name=" + admin_user + "&__pwd=" + URLEncoder.encode(admin_password, "UTF-8")
+ + "&__admin_password_again=" + URLEncoder.encode(admin_password, "UTF-8") + "&profileId="
+ + "caAdminCert" + "&email=" + URLEncoder.encode(admin_email, "UTF-8")
+ + "&cert_request=" + URLEncoder.encode(admin_cert_request, "UTF-8")
+ + "&subject=" + URLEncoder.encode(agent_cert_subject, "UTF-8")
+ + "&clone=new"
+ + "&import=true" + "&securitydomain="
+ + URLEncoder.encode(domain_name, "UTF-8") + "";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ if (!checkStatus(hr, "updateStatus", SUCCESS, "AdminCertReqPanel()")) {
+ return false;
+ }
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+
+ admin_serial_number = px.getvalue("serialNumber");
+
+ return true;
+ } catch (Exception e) {
+ System.out.println("Exception in AdminCertReqPanel(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+
+ }
+
+ public boolean AdminCertImportPanel() {
+ try {
+ boolean st = false;
+ HTTPResponse hr = null;
+ String cert_to_import = null;
+
+ String query_string = "&serialNumber=" + admin_serial_number
+ + "&importCert=true" + "";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, admin_uri, query_string);
+
+ try {
+ // get response data
+ // Convert a byte array to base64 string
+ // cert_to_import = new sun.misc.BASE64Encoder().encode(
+ // hr.getResponseData());
+ cert_to_import = Utils.base64encode(hr.getResponseData());
+
+ // Convert base64 string to a byte array
+ // buf = new sun.misc.BASE64Decoder().decodeBuffer(s);
+
+ System.out.println("Cert to Import =" + cert_to_import);
+ } catch (Exception e) {
+ System.out.println("ERROR: failed to retrieve cert");
+ }
+
+ System.out.println("Cert to Import =" + cert_to_import);
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir, client_certdb_pwd,
+ null, null, null);
+
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(true);
+ cCrypt.loginDB();
+
+ String start = "-----BEGIN CERTIFICATE-----\r\n";
+ String end = "\r\n-----END CERTIFICATE-----";
+
+ st = cCrypt.importCert(start + cert_to_import + end, agent_name);
+ if (!st) {
+ System.out.println(
+ "ERROR: AdminCertImportPanel() during cert import");
+ return false;
+ }
+
+ System.out.println("SUCCESS: imported admin user cert");
+ return true;
+ } catch (Exception e) {
+ System.out.println("Exception in AdminCertImportPanel(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public boolean UpdateDomainPanel() {
+ try {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=17" + "&op=next" + "&xml=true" + "&caHost="
+ + URLEncoder.encode("/", "UTF-8") + "&caPort=" + URLEncoder.encode("/", "UTF-8")
+ + "";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ if (!checkStatus(hr, "updateStatus", SUCCESS, "UpdateDomainPanel()")) {
+ return false;
+ }
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+
+ String caHost = px.getvalue("host");
+ String caPort = px.getvalue("port");
+ String systemType = px.getvalue("systemType");
+
+ System.out.println("caHost=" + caHost);
+ System.out.println("caPort=" + caPort);
+ System.out.println("systemType=" + systemType);
+
+ return true;
+ } catch (Exception e) {
+ System.out.println("Exception in UpdateDomainPanel(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+
+ }
+
+ public boolean ConfigureCAInstance() {
+ // 0. login to cert db
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir, client_certdb_pwd,
+ null, null, null);
+
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(true);
+ cCrypt.loginDB();
+
+ // instantiate http client
+ // enable ecc if need be
+
+ if (key_type.equalsIgnoreCase("ecc")) {
+ hc = new HTTPClient(true);
+ } else {
+ hc = new HTTPClient(false);
+ }
+
+ // 1. Login panel
+ boolean log_st = LoginPanel();
+
+ if (!log_st) {
+ System.out.println("ERROR: ConfigureCA: LoginPanel() failure");
+ return false;
+ }
+
+ // 2. Token Choice Panel
+ boolean disp_token = TokenChoicePanel();
+
+ if (!disp_token) {
+ System.out.println("ERROR: ConfigureCA: TokenChoicePanel() failure");
+ return false;
+ }
+
+ // 3. domain panel
+ boolean dom_st = DomainPanel();
+
+ if (!dom_st) {
+ System.out.println("ERROR: ConfigureCA: DomainPanel() failure");
+ return false;
+ }
+
+ // 4. display cert chain panel and security domain login
+ if (clone) {
+ boolean disp_st = DisplayCertChainPanel();
+ if (!disp_st) {
+ System.out.println("ERROR: ConfigureCA: DisplayCertChainPanel() failure");
+ return false;
+ }
+
+ boolean sd_st = SecurityDomainLoginPanel();
+ if (!sd_st) {
+ System.out.println("ERROR: ConfigureSubCA: SecurityDomainLoginPanel() failure");
+ return false;
+ }
+
+ }
+
+ // 5. display create CA panel
+ boolean disp_cert = CreateCAPanel();
+
+ if (!disp_cert) {
+ System.out.println("ERROR: ConfigureCA: CreateCAPanel() failure");
+ return false;
+ }
+
+ // 6. display restore key cert panel
+ if (clone) {
+ boolean restore_st = RestoreKeyCertPanel();
+ if (!restore_st) {
+ System.out.println("ERROR: ConfigureCA: RestoreKeyCertPanel() failure");
+ return false;
+ }
+ }
+
+ // 7. hierarchy panel
+ if (!clone) {
+ boolean disp_h = HierarchyPanel();
+
+ if (!disp_h) {
+ System.out.println("ERROR: ConfigureCA: HierarchyPanel() failure");
+ return false;
+ }
+ }
+
+ // 8. ldap connection panel
+ boolean disp_ldap = LdapConnectionPanel();
+
+ if (!disp_ldap) {
+ System.out.println(
+ "ERROR: ConfigureCA: LdapConnectionPanel() failure");
+ return false;
+ }
+
+ // 9. Key Panel
+ boolean disp_key = KeyPanel();
+
+ if (!disp_key) {
+ System.out.println("ERROR: ConfigureCA: KeyPanel() failure");
+ return false;
+ }
+
+ // 10. Cert Subject Panel
+ boolean disp_csubj = CertSubjectPanel();
+
+ if (!disp_csubj) {
+ System.out.println("ERROR: ConfigureCA: CertSubjectPanel() failure");
+ return false;
+ }
+
+ // 11. Certificate Panel
+ boolean disp_cp;
+
+ if (external_ca.equalsIgnoreCase("true")) {
+ if (ext_ca_cert_file != null) {
+ // second pass - cacert file defined
+ disp_cp = CertificatePanelExternal();
+
+ if (!disp_cp) {
+ System.out.println("ERROR: ConfigureCA: CertificatePanelExternal() failure");
+ return false;
+ }
+ } else {
+ // first pass - cacert file not defined
+ System.out.println("A Certificate Request has been generated and stored in " + ext_csr_file);
+ System.out.println(
+ "Please submit this CSR to your external CA and obtain the CA Cert and CA Cert Chain");
+ return true;
+ }
+ }
+
+ disp_cp = CertificatePanel();
+
+ if (!disp_cp) {
+ System.out.println("ERROR: ConfigureCA: CertificatePanel() failure");
+ return false;
+ }
+
+ // 13. Backup Panel
+ boolean disp_back = BackupPanel();
+
+ if (!disp_back) {
+ System.out.println("ERROR: ConfigureCA: BackupPanel() failure");
+ return false;
+ }
+
+ // 14. Backup Continue Panel
+ boolean disp_back_cont = BackupContinuePanel();
+
+ if (!disp_back_cont) {
+ System.out.println("ERROR: ConfigureCA: BackupContinuePanel() failure");
+ return false;
+ }
+
+ // 15. Import CA Cert panel
+ boolean disp_import_cacert = ImportCACertPanel();
+
+ if (!disp_import_cacert) {
+ System.out.println("ERROR: ConfigureCA: ImportCACertPanel() failure");
+ return false;
+ }
+
+ if (clone) {
+ // no other panels required for clone
+ return true;
+ }
+
+ // 16. Admin Cert Req Panel
+ boolean disp_adm = AdminCertReqPanel();
+
+ if (!disp_adm) {
+ System.out.println("ERROR: ConfigureCA: AdminCertReqPanel() failure");
+ return false;
+ }
+
+ // 14. Admin Cert import Panel
+ boolean disp_im = AdminCertImportPanel();
+
+ if (!disp_im) {
+ System.out.println(
+ "ERROR: ConfigureCA: AdminCertImportPanel() failure");
+ return false;
+ }
+
+ // 15. Update Domain Panel
+ boolean disp_ud = UpdateDomainPanel();
+
+ if (!disp_ud) {
+ System.out.println("ERROR: ConfigureCA: UpdateDomainPanel() failure");
+ return false;
+ }
+
+ return true;
+ }
+
+ private static String set_default(String val, String def) {
+ if ((val == null) || (val.equals(""))) {
+ return def;
+ } else {
+ return val;
+ }
+ }
+
+ public static void main(String args[]) {
+ ConfigureCA ca = new ConfigureCA();
+
+ // set variables
+ StringHolder x_cs_hostname = new StringHolder();
+ StringHolder x_cs_port = new StringHolder();
+ StringHolder x_client_certdb_dir = new StringHolder();
+ StringHolder x_client_certdb_pwd = new StringHolder();
+ StringHolder x_preop_pin = new StringHolder();
+
+ StringHolder x_domain_name = new StringHolder();
+
+ StringHolder x_admin_user = new StringHolder();
+ StringHolder x_admin_email = new StringHolder();
+ StringHolder x_admin_password = new StringHolder();
+
+ // ldap
+ StringHolder x_ldap_host = new StringHolder();
+ StringHolder x_ldap_port = new StringHolder();
+ StringHolder x_bind_dn = new StringHolder();
+ StringHolder x_bind_password = new StringHolder();
+ StringHolder x_base_dn = new StringHolder();
+ StringHolder x_db_name = new StringHolder();
+ StringHolder x_secure_conn = new StringHolder();
+ StringHolder x_remove_data = new StringHolder();
+
+ // key properties (defaults)
+ StringHolder x_key_size = new StringHolder();
+ StringHolder x_key_type = new StringHolder();
+ StringHolder x_key_curvename = new StringHolder();
+ StringHolder x_key_algorithm = new StringHolder();
+ StringHolder x_signing_algorithm = new StringHolder();
+
+ // key properties (custom - signing)
+ StringHolder x_signing_key_size = new StringHolder();
+ StringHolder x_signing_key_type = new StringHolder();
+ StringHolder x_signing_key_curvename = new StringHolder();
+ StringHolder x_signing_signingalgorithm = new StringHolder();
+
+ // key properties (custom - ocsp_signing)
+ StringHolder x_ocsp_signing_key_size = new StringHolder();
+ StringHolder x_ocsp_signing_key_type = new StringHolder();
+ StringHolder x_ocsp_signing_key_curvename = new StringHolder();
+ StringHolder x_ocsp_signing_signingalgorithm = new StringHolder();
+
+ // key properties (custom - audit_signing)
+ StringHolder x_audit_signing_key_size = new StringHolder();
+ StringHolder x_audit_signing_key_type = new StringHolder();
+ StringHolder x_audit_signing_key_curvename = new StringHolder();
+
+ // key properties (custom - subsystem)
+ StringHolder x_subsystem_key_size = new StringHolder();
+ StringHolder x_subsystem_key_type = new StringHolder();
+ StringHolder x_subsystem_key_curvename = new StringHolder();
+
+ // key properties (custom - sslserver)
+ StringHolder x_sslserver_key_size = new StringHolder();
+ StringHolder x_sslserver_key_type = new StringHolder();
+ StringHolder x_sslserver_key_curvename = new StringHolder();
+
+ StringHolder x_token_name = new StringHolder();
+ StringHolder x_token_pwd = new StringHolder();
+
+ StringHolder x_agent_name = new StringHolder();
+ StringHolder x_save_p12 = new StringHolder();
+ StringHolder x_backup_pwd = new StringHolder();
+ StringHolder x_backup_fname = new StringHolder();
+
+ // separate key size for agent cert
+ StringHolder x_agent_key_size = new StringHolder();
+ StringHolder x_agent_key_type = new StringHolder();
+ StringHolder x_agent_cert_subject = new StringHolder();
+
+ // ca cert subject name params
+ StringHolder x_ca_sign_cert_subject_name = new StringHolder();
+ StringHolder x_ca_subsystem_cert_subject_name = new StringHolder();
+ StringHolder x_ca_ocsp_cert_subject_name = new StringHolder();
+ StringHolder x_ca_server_cert_subject_name = new StringHolder();
+ StringHolder x_ca_audit_signing_cert_subject_name = new StringHolder();
+
+ // subsystemName
+ StringHolder x_subsystem_name = new StringHolder();
+
+ // external CA cert
+ StringHolder x_external_ca = new StringHolder();
+ StringHolder x_ext_ca_cert_file = new StringHolder();
+ StringHolder x_ext_ca_cert_chain_file = new StringHolder();
+ StringHolder x_ext_csr_file = new StringHolder();
+
+ //clone parameters
+ StringHolder x_clone = new StringHolder();
+ StringHolder x_clone_uri = new StringHolder();
+ StringHolder x_clone_p12_file = new StringHolder();
+ StringHolder x_clone_p12_passwd = new StringHolder();
+ StringHolder x_clone_master_port = new StringHolder();
+ StringHolder x_clone_replica_port = new StringHolder();
+ StringHolder x_clone_replication_security = new StringHolder();
+
+ //security domain
+ StringHolder x_sd_hostname = new StringHolder();
+ StringHolder x_sd_ssl_port = new StringHolder();
+ StringHolder x_sd_agent_port = new StringHolder();
+ StringHolder x_sd_admin_port = new StringHolder();
+ StringHolder x_sd_admin_name = new StringHolder();
+ StringHolder x_sd_admin_password = new StringHolder();
+
+ // parse the args
+ ArgParser parser = new ArgParser("ConfigureCA");
+
+ parser.addOption("-cs_hostname %s #CS Hostname", x_cs_hostname);
+ parser.addOption("-cs_port %s #CS SSL Admin port", x_cs_port);
+ parser.addOption("-client_certdb_dir %s #Client CertDB dir",
+ x_client_certdb_dir);
+ parser.addOption("-client_certdb_pwd %s #client certdb password",
+ x_client_certdb_pwd);
+ parser.addOption("-preop_pin %s #pre op pin", x_preop_pin);
+ parser.addOption("-domain_name %s #domain name", x_domain_name);
+ parser.addOption("-admin_user %s #Admin User Name", x_admin_user);
+ parser.addOption("-admin_email %s #Admin email", x_admin_email);
+ parser.addOption("-admin_password %s #Admin password", x_admin_password);
+ parser.addOption("-agent_name %s #Agent Cert Nickname", x_agent_name);
+ parser.addOption("-agent_key_size %s #Agent Cert Key size",
+ x_agent_key_size);
+ parser.addOption("-agent_key_type %s #Agent Cert Key type [rsa]",
+ x_agent_key_type);
+ parser.addOption("-agent_cert_subject %s #Agent Certificate Subject",
+ x_agent_cert_subject);
+
+ parser.addOption("-ldap_host %s #ldap host", x_ldap_host);
+ parser.addOption("-ldap_port %s #ldap port", x_ldap_port);
+ parser.addOption("-bind_dn %s #ldap bind dn", x_bind_dn);
+ parser.addOption("-bind_password %s #ldap bind password",
+ x_bind_password);
+ parser.addOption("-base_dn %s #base dn", x_base_dn);
+ parser.addOption("-db_name %s #db name", x_db_name);
+ parser.addOption("-secure_conn %s #use ldaps port (optional, default is false)", x_secure_conn);
+ parser.addOption("-remove_data %s #remove existing data under base_dn (optional, default is false) ",
+ x_remove_data);
+
+ // key and algorithm options (default)
+ parser.addOption("-key_type %s #Key type [RSA,ECC] (optional, default is RSA)", x_key_type);
+ parser.addOption("-key_size %s #Key Size (optional, for RSA default is 2048)", x_key_size);
+ parser.addOption("-key_curvename %s #Key Curve Name (optional, for ECC default is nistp256)", x_key_curvename);
+ parser.addOption(
+ "-key_algorithm %s #Key algorithm of the CA certificate (optional, default is SHA256withRSA for RSA and SHA256withEC for ECC)",
+ x_key_algorithm);
+ parser.addOption("-signing_algorithm %s #Signing algorithm (optional, default is key_algorithm)",
+ x_signing_algorithm);
+
+ // key and algorithm options for signing certificate (overrides default)
+ parser.addOption("-signing_key_type %s #Key type [RSA,ECC] (optional, default is key_type)", x_signing_key_type);
+ parser.addOption("-signing_key_size %s #Key Size (optional, for RSA default is key_size)", x_signing_key_size);
+ parser.addOption("-signing_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_signing_key_curvename);
+ parser.addOption(
+ "-signing_signingalgorithm %s #Algorithm used be CA cert to sign objects (optional, default is signing_algorithm)",
+ x_signing_signingalgorithm);
+
+ // key and algorithm options for ocsp_signing certificate (overrides default)
+ parser.addOption("-ocsp_signing_key_type %s #Key type [RSA,ECC] (optional, default is key_type)",
+ x_ocsp_signing_key_type);
+ parser.addOption("-ocsp_signing_key_size %s #Key Size (optional, for RSA default is key_size)",
+ x_ocsp_signing_key_size);
+ parser.addOption("-ocsp_signing_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_ocsp_signing_key_curvename);
+ parser.addOption(
+ "-ocsp_signing_signingalgorithm %s #Algorithm used by the OCSP signing cert to sign objects (optional, default is signing_algorithm)",
+ x_ocsp_signing_signingalgorithm);
+
+ // key and algorithm options for audit_signing certificate (overrides default)
+ parser.addOption("-audit_signing_key_type %s #Key type [RSA,ECC] (optional, default is key_type)",
+ x_audit_signing_key_type);
+ parser.addOption("-audit_signing_key_size %s #Key Size (optional, for RSA default is key_size)",
+ x_audit_signing_key_size);
+ parser.addOption(
+ "-audit_signing_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_audit_signing_key_curvename);
+
+ // key and algorithm options for subsystem certificate (overrides default)
+ parser.addOption("-subsystem_key_type %s #Key type [RSA,ECC] (optional, default is key_type)",
+ x_subsystem_key_type);
+ parser.addOption("-subsystem_key_size %s #Key Size (optional, for RSA default is key_size)",
+ x_subsystem_key_size);
+ parser.addOption("-subsystem_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_subsystem_key_curvename);
+
+ // key and algorithm options for sslserver certificate (overrides default)
+ parser.addOption("-sslserver_key_type %s #Key type [RSA,ECC] (optional, default is key_type)",
+ x_sslserver_key_type);
+ parser.addOption("-sslserver_key_size %s #Key Size (optional, for RSA default is key_size)",
+ x_sslserver_key_size);
+ parser.addOption("-sslserver_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_sslserver_key_curvename);
+
+ parser.addOption("-token_name %s #HSM/Software Token name", x_token_name);
+ parser.addOption("-token_pwd %s #HSM/Software Token password (optional - only required for HSM)",
+ x_token_pwd);
+
+ parser.addOption("-save_p12 %s #Enable/Disable p12 Export[true,false]",
+ x_save_p12);
+ parser.addOption("-backup_pwd %s #Backup Password for p12 (optional, only required if -save_p12 = true)",
+ x_backup_pwd);
+ parser.addOption("-backup_fname %s #Backup File for p12, (optional, default is /root/tmp-ca.p12)",
+ x_backup_fname);
+
+ parser.addOption("-ca_sign_cert_subject_name %s #CA cert subject name",
+ x_ca_sign_cert_subject_name);
+ parser.addOption(
+ "-ca_subsystem_cert_subject_name %s #CA subsystem cert subject name",
+ x_ca_subsystem_cert_subject_name);
+ parser.addOption(
+ "-ca_ocsp_cert_subject_name %s #CA ocsp cert subject name",
+ x_ca_ocsp_cert_subject_name);
+ parser.addOption(
+ "-ca_server_cert_subject_name %s #CA server cert subject name",
+ x_ca_server_cert_subject_name);
+ parser.addOption(
+ "-ca_audit_signing_cert_subject_name %s #CA audit signing cert subject name",
+ x_ca_audit_signing_cert_subject_name);
+
+ parser.addOption("-subsystem_name %s #CA subsystem name",
+ x_subsystem_name);
+
+ parser.addOption("-external %s #Subordinate to external CA [true,false] (optional, default false)",
+ x_external_ca);
+ parser.addOption("-ext_ca_cert_file %s #File with CA cert from external CA (optional)",
+ x_ext_ca_cert_file);
+ parser.addOption("-ext_ca_cert_chain_file %s #File with CA cert from external CA (optional)",
+ x_ext_ca_cert_chain_file);
+ parser.addOption("-ext_csr_file %s #File to save the CSR for submission to an external CA (optional)",
+ x_ext_csr_file);
+
+ parser.addOption("-clone %s #Clone of another CA [true, false] (optional, default false)", x_clone);
+ parser.addOption(
+ "-clone_uri %s #URL of Master CA to clone. It must have the form https://<hostname>:<EE port> (optional, required if -clone=true)",
+ x_clone_uri);
+ parser.addOption(
+ "-clone_p12_file %s #File containing pk12 keys of Master CA (optional, required if -clone=true)",
+ x_clone_p12_file);
+ parser.addOption("-clone_p12_password %s #Password for pk12 file (optional, required if -clone=true)",
+ x_clone_p12_passwd);
+
+ // replication agreement options
+ parser.addOption("-clone_master_port %s #Master Port to be used in replication agreement (optional)",
+ x_clone_master_port);
+ parser.addOption("-clone_replica_port %s #Replica Port to be used in replication agreement (optional)",
+ x_clone_replica_port);
+ parser.addOption("-clone_replication_security %s #Type of security in replication agreement (optional)",
+ x_clone_replication_security);
+
+ parser.addOption("-sd_hostname %s #Security Domain Hostname (optional, required if -clone=true)", x_sd_hostname);
+ parser.addOption("-sd_ssl_port %s #Security Domain SSL EE port (optional, required if -clone=true)",
+ x_sd_ssl_port);
+ parser.addOption("-sd_agent_port %s #Security Domain SSL Agent port (optional, required if -clone=true)",
+ x_sd_agent_port);
+ parser.addOption("-sd_admin_port %s #Security Domain SSL Admin port (optional, required if -clone=true)",
+ x_sd_admin_port);
+ parser.addOption("-sd_admin_name %s #Security Domain admin name (optional, required if -clone=true)",
+ x_sd_admin_name);
+ parser.addOption("-sd_admin_password %s #Security Domain admin password (optional, required if -clone=true)",
+ x_sd_admin_password);
+
+ // and then match the arguments
+ String[] unmatched = null;
+
+ unmatched = parser.matchAllArgs(args, 0, ArgParser.EXIT_ON_UNMATCHED);
+
+ if (unmatched != null) {
+ System.out.println("ERROR: Argument Mismatch");
+ System.exit(-1);
+ }
+
+ parser.checkRequiredArgs();
+
+ // set variables
+ cs_hostname = x_cs_hostname.value;
+ cs_port = x_cs_port.value;
+ client_certdb_dir = x_client_certdb_dir.value;
+ client_certdb_pwd = x_client_certdb_pwd.value;
+ pin = x_preop_pin.value;
+ domain_name = x_domain_name.value;
+ admin_user = x_admin_user.value;
+ admin_email = x_admin_email.value;
+ admin_password = x_admin_password.value;
+ agent_name = x_agent_name.value;
+
+ ldap_host = x_ldap_host.value;
+ ldap_port = x_ldap_port.value;
+ bind_dn = x_bind_dn.value;
+ bind_password = x_bind_password.value;
+ base_dn = x_base_dn.value;
+ db_name = x_db_name.value;
+ secure_conn = set_default(x_secure_conn.value, "false");
+ remove_data = set_default(x_remove_data.value, "false");
+
+ key_type = set_default(x_key_type.value, DEFAULT_KEY_TYPE);
+ signing_key_type = set_default(x_signing_key_type.value, key_type);
+ ocsp_signing_key_type = set_default(x_ocsp_signing_key_type.value, key_type);
+ audit_signing_key_type = set_default(x_audit_signing_key_type.value, key_type);
+ subsystem_key_type = set_default(x_subsystem_key_type.value, key_type);
+ sslserver_key_type = set_default(x_sslserver_key_type.value, key_type);
+
+ key_size = set_default(x_key_size.value, DEFAULT_KEY_SIZE);
+ signing_key_size = set_default(x_signing_key_size.value, key_size);
+ ocsp_signing_key_size = set_default(x_ocsp_signing_key_size.value, key_size);
+ audit_signing_key_size = set_default(x_audit_signing_key_size.value, key_size);
+ subsystem_key_size = set_default(x_subsystem_key_size.value, key_size);
+ sslserver_key_size = set_default(x_sslserver_key_size.value, key_size);
+
+ key_curvename = set_default(x_key_curvename.value, DEFAULT_KEY_CURVENAME);
+ signing_key_curvename = set_default(x_signing_key_curvename.value, key_curvename);
+ ocsp_signing_key_curvename = set_default(x_ocsp_signing_key_curvename.value, key_curvename);
+ audit_signing_key_curvename = set_default(x_audit_signing_key_curvename.value, key_curvename);
+ subsystem_key_curvename = set_default(x_subsystem_key_curvename.value, key_curvename);
+ sslserver_key_curvename = set_default(x_sslserver_key_curvename.value, key_curvename);
+
+ if (signing_key_type.equalsIgnoreCase("RSA")) {
+ key_algorithm = set_default(x_key_algorithm.value, DEFAULT_KEY_ALGORITHM_RSA);
+ } else {
+ key_algorithm = set_default(x_key_algorithm.value, DEFAULT_KEY_ALGORITHM_ECC);
+ }
+
+ signing_algorithm = set_default(x_signing_algorithm.value, key_algorithm);
+ signing_signingalgorithm = set_default(x_signing_signingalgorithm.value, signing_algorithm);
+ ocsp_signing_signingalgorithm = set_default(x_ocsp_signing_signingalgorithm.value, signing_algorithm);
+
+ token_name = x_token_name.value;
+ token_pwd = x_token_pwd.value;
+ save_p12 = x_save_p12.value;
+ backup_pwd = x_backup_pwd.value;
+ backup_fname = set_default(x_backup_fname.value, "/root/tmp-ca.p12");
+
+ agent_key_size = x_agent_key_size.value;
+ agent_key_type = x_agent_key_type.value;
+ agent_cert_subject = x_agent_cert_subject.value;
+
+ ca_sign_cert_subject_name = x_ca_sign_cert_subject_name.value;
+ ca_subsystem_cert_subject_name = x_ca_subsystem_cert_subject_name.value;
+ ca_ocsp_cert_subject_name = x_ca_ocsp_cert_subject_name.value;
+ ca_server_cert_subject_name = x_ca_server_cert_subject_name.value;
+ ca_audit_signing_cert_subject_name = x_ca_audit_signing_cert_subject_name.value;
+
+ subsystem_name = x_subsystem_name.value;
+
+ external_ca = set_default(x_external_ca.value, "false");
+ ext_ca_cert_file = x_ext_ca_cert_file.value;
+ ext_ca_cert_chain_file = x_ext_ca_cert_chain_file.value;
+ ext_csr_file = set_default(x_ext_csr_file.value, "/tmp/ext_ca.csr");
+
+ if ((x_clone.value != null) && (x_clone.value.equalsIgnoreCase("true"))) {
+ clone = true;
+ } else {
+ clone = false;
+ }
+ clone_uri = x_clone_uri.value;
+ clone_p12_file = x_clone_p12_file.value;
+ clone_p12_passwd = x_clone_p12_passwd.value;
+ clone_master_port = set_default(x_clone_master_port.value, "");
+ clone_replica_port = set_default(x_clone_replica_port.value, "");
+ clone_replication_security = set_default(x_clone_replication_security.value, "None");
+
+ sd_hostname = x_sd_hostname.value;
+ sd_ssl_port = x_sd_ssl_port.value;
+ sd_agent_port = x_sd_agent_port.value;
+ sd_admin_port = x_sd_admin_port.value;
+ sd_admin_name = x_sd_admin_name.value;
+ sd_admin_password = x_sd_admin_password.value;
+
+ boolean st = ca.ConfigureCAInstance();
+
+ if (!st) {
+ System.out.println("ERROR: unable to create CA");
+ System.exit(-1);
+ }
+
+ System.out.println("Certificate System - CA Instance Configured.");
+ System.exit(0);
+
+ }
+
+};
diff --git a/base/silent/src/com/netscape/pkisilent/ConfigureDRM.java b/base/silent/src/com/netscape/pkisilent/ConfigureDRM.java
new file mode 100644
index 000000000..7d548ddf3
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/ConfigureDRM.java
@@ -0,0 +1,1374 @@
+package com.netscape.pkisilent;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.pkcs12.AuthenticatedSafes;
+import org.mozilla.jss.pkcs12.PFX;
+
+import com.netscape.pkisilent.argparser.ArgParser;
+import com.netscape.pkisilent.argparser.StringHolder;
+import com.netscape.pkisilent.common.ComCrypto;
+import com.netscape.pkisilent.common.ParseXML;
+import com.netscape.pkisilent.http.HTTPClient;
+import com.netscape.pkisilent.http.HTTPResponse;
+import com.netscape.cmsutil.util.Utils;
+
+public class ConfigureDRM {
+
+ // global constants
+ public static final String DEFAULT_KEY_TYPE = "RSA";
+ public static final String DEFAULT_KEY_SIZE = "2048";
+ public static final String DEFAULT_KEY_CURVENAME = "nistp256";
+ public static final String DEFAULT_KEY_ALGORITHM_RSA = "SHA256withRSA";
+ public static final String DEFAULT_KEY_ALGORITHM_ECC = "SHA256withEC";
+
+ // define global variables
+
+ public static HTTPClient hc = null;
+
+ public static String login_uri = "/kra/admin/console/config/login";
+ public static String wizard_uri = "/kra/admin/console/config/wizard";
+ public static String admin_uri = "/ca/admin/ca/getBySerial";
+
+ public static String sd_login_uri = "/ca/admin/ca/securityDomainLogin";
+ public static String sd_get_cookie_uri = "/ca/admin/ca/getCookie";
+ public static String pkcs12_uri = "/kra/admin/console/config/savepkcs12";
+
+ public static String cs_hostname = null;
+ public static String cs_port = null;
+
+ public static String sd_hostname = null;
+ public static String sd_ssl_port = null;
+ public static String sd_agent_port = null;
+ public static String sd_admin_port = null;
+ public static String sd_admin_name = null;
+ public static String sd_admin_password = null;
+
+ public static String ca_hostname = null;
+ public static String ca_port = null;
+ public static String ca_ssl_port = null;
+
+ public static String client_certdb_dir = null;
+ public static String client_certdb_pwd = null;
+
+ // Login Panel
+ public static String pin = null;
+
+ public static String domain_name = null;
+
+ public static String admin_user = null;
+ public static String admin_email = null;
+ public static String admin_password = null;
+ public static String admin_serial_number = null;
+ public static String agent_name = null;
+
+ public static String ldap_host = null;
+ public static String ldap_port = null;
+ public static String bind_dn = null;
+ public static String bind_password = null;
+ public static String base_dn = null;
+ public static String db_name = null;
+ public static String secure_conn = null;
+ public static String remove_data = null;
+
+ public static String key_type = null;
+ public static String key_size = null;
+ public static String key_curvename = null;
+ public static String signing_algorithm = null;
+
+ public static String transport_key_type = null;
+ public static String transport_key_size = null;
+ public static String transport_key_curvename = null;
+ public static String transport_signingalgorithm = null;
+
+ public static String storage_key_type = null;
+ public static String storage_key_size = null;
+ public static String storage_key_curvename = null;
+
+ public static String subsystem_key_type = null;
+ public static String subsystem_key_size = null;
+ public static String subsystem_key_curvename = null;
+
+ public static String audit_signing_key_type = null;
+ public static String audit_signing_key_size = null;
+ public static String audit_signing_key_curvename = null;
+
+ public static String sslserver_key_type = null;
+ public static String sslserver_key_size = null;
+ public static String sslserver_key_curvename = null;
+
+ public static String token_name = null;
+ public static String token_pwd = null;
+
+ public static String agent_key_size = null;
+ public static String agent_key_type = null;
+ public static String agent_cert_subject = null;
+
+ public static String drm_transport_cert_name = null;
+ public static String drm_transport_cert_req = null;
+ public static String drm_transport_cert_pp = null;
+ public static String drm_transport_cert_cert = null;
+
+ public static String drm_storage_cert_name = null;
+ public static String drm_storage_cert_req = null;
+ public static String drm_storage_cert_pp = null;
+ public static String drm_storage_cert_cert = null;
+
+ public static String server_cert_name = null;
+ public static String server_cert_req = null;
+ public static String server_cert_pp = null;
+ public static String server_cert_cert = null;
+
+ public static String drm_subsystem_cert_name = null;
+ public static String drm_subsystem_cert_req = null;
+ public static String drm_subsystem_cert_pp = null;
+ public static String drm_subsystem_cert_cert = null;
+
+ public static String drm_audit_signing_cert_name = null;
+ public static String drm_audit_signing_cert_req = null;
+ public static String drm_audit_signing_cert_pp = null;
+ public static String drm_audit_signing_cert_cert = null;
+
+ public static String backup_pwd = null;
+ public static String backup_fname = null;
+
+ // cert subject names
+ public static String drm_transport_cert_subject_name = null;
+ public static String drm_subsystem_cert_subject_name = null;
+ public static String drm_storage_cert_subject_name = null;
+ public static String drm_server_cert_subject_name = null;
+ public static String drm_audit_signing_cert_subject_name = null;
+
+ public static String subsystem_name = null;
+
+ // cloning
+ public static boolean clone = false;
+ public static String clone_uri = null;
+ public static String clone_p12_passwd = null;
+ public static String clone_p12_file = null;
+ public static String clone_master_port = null;
+ public static String clone_replica_port = null;
+ public static String clone_replication_security = null;
+
+ //for correct selection of CA to be cloned
+ public static String urls;
+
+ public ConfigureDRM() {
+ // do nothing :)
+ }
+
+ public void sleep_time() {
+ try {
+ System.out.println("Sleeping for 5 secs..");
+ Thread.sleep(5000);
+ } catch (Exception e) {
+ System.out.println("ERROR: sleep problem");
+ }
+
+ }
+
+ public boolean LoginPanel() {
+ boolean st = false;
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "pin=" + pin + "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, login_uri, query_string);
+ System.out.println("xml returned: " + hr.getHTML());
+
+ // parse xml here - nothing to parse
+
+ // get cookie
+ String temp = hr.getCookieValue("JSESSIONID");
+
+ if (temp != null) {
+ int index = temp.indexOf(";");
+ HTTPClient.j_session_id = temp.substring(0, index);
+ st = true;
+ }
+
+ hr = null;
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, "p=0&op=next&xml=true");
+
+ // parse xml here
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return st;
+ }
+
+ public boolean TokenChoicePanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = null;
+
+ // Software Token
+ if (token_name.equalsIgnoreCase("internal")) {
+ query_string = "p=1" + "&op=next" + "&xml=true" +
+ "&choice=" +
+ URLEncoder.encode("Internal Key Storage Token", "UTF-8");
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+ } else {
+ // login to hsm first
+ query_string = "p=2" + "&op=next" + "&xml=true" +
+ "&uTokName=" +
+ URLEncoder.encode(token_name, "UTF-8") +
+ "&__uPasswd=" +
+ URLEncoder.encode(token_pwd, "UTF-8");
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ // choice with token name now
+ query_string = "p=1" + "&op=next" + "&xml=true" +
+ "&choice=" +
+ URLEncoder.encode(token_name, "UTF-8");
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+ }
+
+ return true;
+ }
+
+ public boolean DomainPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String domain_url = "https://" + sd_hostname + ":" + sd_admin_port;
+
+ String query_string = "sdomainURL=" +
+ URLEncoder.encode(domain_url, "UTF-8") +
+ "&choice=existingdomain" +
+ "&p=3" +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+
+ }
+
+ public boolean DisplayChainPanel() {
+ String query_string = "p=4" + "&op=next" + "&xml=true";
+ hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ return true;
+
+ }
+
+ public boolean SecurityDomainLoginPanel() {
+ try {
+ HTTPResponse hr = null;
+
+ String kra_url = "https://" + cs_hostname + ":" + cs_port +
+ "/kra/admin/console/config/wizard" +
+ "?p=5&subsystem=KRA";
+
+ String query_string = "url=" + URLEncoder.encode(kra_url, "UTF-8");
+
+ hr = hc.sslConnect(sd_hostname, sd_admin_port, sd_login_uri, query_string);
+
+ String query_string_1 = "uid=" + sd_admin_name +
+ "&pwd=" + URLEncoder.encode(sd_admin_password, "UTF-8") +
+ "&url=" + URLEncoder.encode(kra_url, "UTF-8");
+
+ hr = hc.sslConnect(sd_hostname, sd_admin_port, sd_get_cookie_uri,
+ query_string_1);
+
+ // get session id from security domain
+
+ String kra_session_id = hr.getContentValue("header.session_id");
+ String kra_url_1 = hr.getContentValue("header.url");
+
+ System.out.println("KRA_SESSION_ID=" + kra_session_id);
+ System.out.println("KRA_URL=" + kra_url_1);
+
+ // use session id to connect back to KRA
+
+ String query_string_2 = "p=5" +
+ "&subsystem=KRA" +
+ "&session_id=" + kra_session_id +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri,
+ query_string_2);
+
+ if (clone) {
+ // parse urls
+ urls = hr.getHTML();
+ int indx = urls.indexOf(clone_uri);
+ if (indx < 0) {
+ throw new Exception("Invalid clone_uri");
+ }
+ urls = urls.substring(urls.lastIndexOf("<option", indx), indx);
+ urls = urls.split("\"")[1];
+
+ System.out.println("urls =" + urls);
+ }
+
+ return true;
+ } catch (Exception e) {
+ System.out.println("Exception in SecurityDomainLoginPanel(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public boolean SubsystemPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+ String query_string = null;
+ if (!clone) {
+ query_string = "p=5" + "&op=next" + "&xml=true"
+ + "&choice=newsubsystem" + "&subsystemName="
+ + URLEncoder.encode(subsystem_name, "UTF-8");
+ } else {
+ query_string = "p=5" + "&op=next" + "&xml=true"
+ + "&choice=clonesubsystem" + "&subsystemName="
+ + URLEncoder.encode(subsystem_name, "UTF-8")
+ + "&urls=" + urls;
+ }
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean RestoreKeyCertPanel() {
+ try {
+ ByteArrayInputStream bais = null;
+ HTTPResponse hr = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=6" + "&op=next" + "&xml=true"
+ + "&__password=" + URLEncoder.encode(clone_p12_passwd, "UTF-8")
+ + "&path=" + URLEncoder.encode(clone_p12_file, "UTF-8") + "";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+ return true;
+ } catch (Exception e) {
+ System.out.println("Exception in RestoreKeyCertPanel(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public boolean LdapConnectionPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=7" + "&op=next" + "&xml=true" +
+ "&host=" + URLEncoder.encode(ldap_host, "UTF-8") +
+ "&port=" + URLEncoder.encode(ldap_port, "UTF-8") +
+ "&binddn=" + URLEncoder.encode(bind_dn, "UTF-8") +
+ "&__bindpwd=" + URLEncoder.encode(bind_password, "UTF-8") +
+ "&basedn=" + URLEncoder.encode(base_dn, "UTF-8") +
+ "&database=" + URLEncoder.encode(db_name, "UTF-8") +
+ "&display=" + URLEncoder.encode("$displayStr", "UTF-8") +
+ (secure_conn.equals("true") ? "&secureConn=on" : "") +
+ "&masterReplicationPort=" + URLEncoder.encode(clone_master_port, "UTF-8") +
+ "&cloneReplicationPort=" + URLEncoder.encode(clone_replica_port, "UTF-8") +
+ "&replicationSecurity=" + URLEncoder.encode(clone_replication_security, "UTF-8") +
+ (remove_data.equals("true") ? "&removeData=true" : "");
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean KeyPanel() {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+ ArrayList<String> al = null;
+
+ String query_string = null;
+
+ if (!clone) {
+ query_string = "p=8" + "&op=next" + "&xml=true" +
+ "&transport_custom_size=" + transport_key_size +
+ "&storage_custom_size=" + storage_key_size +
+ "&subsystem_custom_size=" + subsystem_key_size +
+ "&sslserver_custom_size=" + sslserver_key_size +
+ "&audit_signing_custom_size=" + key_size +
+ "&custom_size=" + key_size +
+ "&transport_custom_curvename=" + transport_key_curvename +
+ "&storage_custom_curvename=" + storage_key_curvename +
+ "&subsystem_custom_curvename=" + subsystem_key_curvename +
+ "&sslserver_custom_curvename=" + sslserver_key_curvename +
+ "&audit_signing_custom_curvename=" + audit_signing_key_curvename +
+ "&custom_curvename=" + key_curvename +
+ "&transport_keytype=" + transport_key_type +
+ "&storage_keytype=" + storage_key_type +
+ "&subsystem_keytype=" + subsystem_key_type +
+ "&sslserver_keytype=" + sslserver_key_type +
+ "&audit_signing_keytype=" + audit_signing_key_type +
+ "&keytype=" + key_type +
+ "&transport_choice=custom" +
+ "&storage_choice=custom" +
+ "&subsystem_choice=custom" +
+ "&sslserver_choice=custom" +
+ "&choice=custom" +
+ "&audit_signing_choice=custom" +
+ "&signingalgorithm=" + signing_algorithm +
+ "&transport_signingalgorithm=" + transport_signingalgorithm;
+
+ } else {
+ query_string = "p=8" + "&op=next" + "&xml=true" +
+ "&sslserver_custom_size=" + sslserver_key_size +
+ "&sslserver_keytype=" + sslserver_key_type +
+ "&sslserver_choice=custom" +
+ "&custom_size=" + key_size +
+ "&keytype=" + key_type +
+ "&choice=custom";
+ }
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ al = px.constructValueList("CertReqPair", "DN");
+ // get ca cert subject name
+ if (al != null) {
+ for (int i = 0; i < al.size(); i++) {
+ String temp = al.get(i);
+ if (temp.indexOf("DRM Transport") > 0) {
+ drm_transport_cert_name = temp;
+ } else if (temp.indexOf("DRM Storage") > 0) {
+ drm_storage_cert_name = temp;
+ } else if (temp.indexOf("DRM Subsystem") > 0) {
+ drm_subsystem_cert_name = temp;
+ } else if (temp.indexOf("DRM Audit Signing Certificate") > 0) {
+ drm_audit_signing_cert_name = temp;
+ } else {
+ server_cert_name = temp;
+ }
+ }
+ }
+
+ System.out.println("default: drm_transport_cert_name=" +
+ drm_transport_cert_name);
+ System.out.println("default: drm_storage_cert_name=" +
+ drm_storage_cert_name);
+ System.out.println("default: drm_subsystem_cert_name=" +
+ drm_subsystem_cert_name);
+ System.out.println("default: drm_audit_signing_cert_name=" +
+ drm_audit_signing_cert_name);
+
+ System.out.println("default: server_cert_name=" +
+ server_cert_name);
+ return true;
+ }
+
+ public boolean CertSubjectPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+ ArrayList<String> req_list = null;
+ ArrayList<String> cert_list = null;
+ ArrayList<String> dn_list = null;
+ String query_string = null;
+
+ String domain_url = "https://" + ca_hostname + ":" + ca_ssl_port;
+
+ if (!clone) {
+ query_string = "p=9" + "&op=next" + "&xml=true" +
+ "&subsystem=" +
+ URLEncoder.encode(drm_subsystem_cert_subject_name, "UTF-8") +
+ "&transport=" +
+ URLEncoder.encode(drm_transport_cert_subject_name, "UTF-8") +
+ "&storage=" +
+ URLEncoder.encode(drm_storage_cert_subject_name, "UTF-8") +
+ "&sslserver=" +
+ URLEncoder.encode(drm_server_cert_subject_name, "UTF-8") +
+ "&audit_signing=" +
+ URLEncoder.encode(drm_audit_signing_cert_subject_name, "UTF-8") +
+ "&urls=" +
+ URLEncoder.encode(domain_url, "UTF-8");
+ } else {
+ query_string = "p=9" + "&op=next" + "&xml=true" +
+ "&sslserver=" +
+ URLEncoder.encode(drm_server_cert_subject_name, "UTF-8") +
+ "&urls=" +
+ URLEncoder.encode(domain_url, "UTF-8");
+ }
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ req_list = px.constructValueList("CertReqPair", "Request");
+ cert_list = px.constructValueList("CertReqPair", "Certificate");
+ dn_list = px.constructValueList("CertReqPair", "Nickname");
+
+ if (req_list != null && cert_list != null && dn_list != null) {
+ for (int i = 0; i < dn_list.size(); i++) {
+ String temp = dn_list.get(i);
+
+ if (temp.indexOf("transportCert") >= 0) {
+ drm_transport_cert_req = req_list.get(i);
+ drm_transport_cert_cert = cert_list.get(i);
+ } else if (temp.indexOf("storageCert") >= 0) {
+ drm_storage_cert_req = req_list.get(i);
+ drm_storage_cert_cert = cert_list.get(i);
+ } else if (temp.indexOf("subsystemCert") >= 0) {
+ drm_subsystem_cert_req = req_list.get(i);
+ drm_subsystem_cert_cert = cert_list.get(i);
+ } else if (temp.indexOf("auditSigningCert") >= 0) {
+ drm_audit_signing_cert_req = req_list.get(i);
+ drm_audit_signing_cert_cert = cert_list.get(i);
+ } else {
+ server_cert_req = req_list.get(i);
+ server_cert_cert = cert_list.get(i);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ public boolean CertificatePanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=10" + "&op=next" + "&xml=true" +
+ "&subsystem=" +
+ URLEncoder.encode(drm_subsystem_cert_cert, "UTF-8") +
+ "&subsystem_cc=" +
+ "&transport=" +
+ URLEncoder.encode(drm_transport_cert_cert, "UTF-8") +
+ "&transport_cc=" +
+ "&storage=" +
+ URLEncoder.encode(drm_storage_cert_cert, "UTF-8") +
+ "&storage_cc=" +
+ "&sslserver=" +
+ URLEncoder.encode(server_cert_cert, "UTF-8") +
+ "&sslserver_cc=" +
+ "&audit_signing=" +
+ URLEncoder.encode(drm_audit_signing_cert_cert, "UTF-8") +
+ "&audit_signing_cc=";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean BackupPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=11" + "&op=next" + "&xml=true" +
+ "&choice=backupkey" +
+ "&__pwd=" + URLEncoder.encode(backup_pwd, "UTF-8") +
+ "&__pwdagain=" + URLEncoder.encode(backup_pwd, "UTF-8");
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean SavePKCS12Panel() {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, pkcs12_uri, query_string);
+
+ // dump hr.getResponseData() to file
+ try {
+ FileOutputStream fos = new FileOutputStream(backup_fname);
+ fos.write(hr.getResponseData());
+ fos.close();
+
+ // set file to permissions 600
+ String rtParams[] = { "chmod", "600", backup_fname };
+ Process proc = Runtime.getRuntime().exec(rtParams);
+
+ BufferedReader br = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
+ String line = null;
+ while ((line = br.readLine()) != null)
+ System.out.println("Error: " + line);
+ proc.waitFor();
+
+ // verify p12 file
+
+ // Decode the P12 file
+ FileInputStream fis = new FileInputStream(backup_fname);
+ PFX.Template pfxt = new PFX.Template();
+ PFX pfx = (PFX) pfxt.decode(new BufferedInputStream(fis, 2048));
+ System.out.println("Decoded PFX");
+
+ // now peruse it for interesting info
+ System.out.println("Version: " + pfx.getVersion());
+ AuthenticatedSafes authSafes = pfx.getAuthSafes();
+ SEQUENCE asSeq = authSafes.getSequence();
+ System.out.println("AuthSafes has " +
+ asSeq.size() + " SafeContents");
+
+ fis.close();
+
+ if (clone) {
+ query_string = "p=12" + "&op=next" + "&xml=true";
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+ }
+ } catch (Exception e) {
+ System.out.println("ERROR: Exception=" + e.getMessage());
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean AdminCertReqPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+ String admin_cert_request = null;
+
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir,
+ client_certdb_pwd,
+ agent_cert_subject,
+ agent_key_size,
+ agent_key_type);
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(true);
+ cCrypt.setTransportCert(null);
+ cCrypt.setDualKey(false);
+ cCrypt.loginDB();
+
+ String crmf_request = cCrypt.generateCRMFrequest();
+
+ if (crmf_request == null) {
+ System.out.println("ERROR: AdminCertReqPanel() cert req gen failed");
+ return false;
+ }
+
+ admin_cert_request = crmf_request;
+
+ String query_string = "p=13" + "&op=next" + "&xml=true" +
+ "&cert_request_type=" + "crmf" +
+ "&uid=" + admin_user +
+ "&name=" + admin_user +
+ "&__pwd=" + URLEncoder.encode(admin_password, "UTF-8") +
+ "&__admin_password_again=" + URLEncoder.encode(admin_password, "UTF-8") +
+ "&profileId=" + "caAdminCert" +
+ "&email=" +
+ URLEncoder.encode(admin_email, "UTF-8") +
+ "&cert_request=" +
+ URLEncoder.encode(admin_cert_request, "UTF-8") +
+ "&subject=" +
+ URLEncoder.encode(agent_cert_subject, "UTF-8") +
+ "&clone=new" +
+ "&import=true" +
+ "&securitydomain=" +
+ URLEncoder.encode(domain_name, "UTF-8");
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ admin_serial_number = px.getvalue("serialNumber");
+
+ return true;
+ }
+
+ public boolean AdminCertImportPanel() {
+ boolean st = false;
+ HTTPResponse hr = null;
+
+ String query_string = "serialNumber=" + admin_serial_number +
+ "&importCert=" + "true";
+
+ hr = hc.sslConnect(sd_hostname, sd_admin_port, admin_uri, query_string);
+
+ // get response data
+ // String cert_to_import =
+ // new sun.misc.BASE64Encoder().encode(hr.getResponseData());
+ String cert_to_import =
+ Utils.base64encode(hr.getResponseData());
+ System.out.println("Imported Cert=" + cert_to_import);
+
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir,
+ client_certdb_pwd,
+ null,
+ null,
+ null);
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(true);
+ cCrypt.loginDB();
+
+ String start = "-----BEGIN CERTIFICATE-----\r\n";
+ String end = "\r\n-----END CERTIFICATE-----";
+
+ st = cCrypt.importCert(start + cert_to_import + end, agent_name);
+ if (!st) {
+ System.out.println("ERROR: AdminCertImportPanel() during cert import");
+ return false;
+ }
+
+ System.out.println("SUCCESS: imported admin user cert");
+ return true;
+ }
+
+ public boolean UpdateDomainPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=14" + "&op=next" + "&xml=true" +
+ "&caHost=" + URLEncoder.encode(sd_hostname, "UTF-8") +
+ "&caPort=" + URLEncoder.encode(sd_agent_port, "UTF-8");
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean ConfigureDRMInstance() throws UnsupportedEncodingException {
+ // 0. login to cert db
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir,
+ client_certdb_pwd,
+ null,
+ null,
+ null);
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(true);
+ cCrypt.loginDB();
+
+ // instantiate http client
+ hc = new HTTPClient();
+
+ // 1. Login panel
+ boolean log_st = LoginPanel();
+ if (!log_st) {
+ System.out.println("ERROR: ConfigureDRM: LoginPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 2. Token Choice Panel
+ boolean disp_token = TokenChoicePanel();
+ if (!disp_token) {
+ System.out.println("ERROR: ConfigureDRM: TokenChoicePanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 3. domain panel
+ boolean dom_st = DomainPanel();
+ if (!dom_st) {
+ System.out.println("ERROR: ConfigureDRM: DomainPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 4. display cert chain panel
+ boolean disp_st = DisplayChainPanel();
+ if (!disp_st) {
+ System.out.println("ERROR: ConfigureDRM: DisplayChainPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // security domain login panel
+ boolean disp_sd = SecurityDomainLoginPanel();
+ if (!disp_sd) {
+ System.out.println("ERROR: ConfigureDRM: SecurityDomainLoginPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // subsystem panel
+ boolean disp_ss = SubsystemPanel();
+ if (!disp_ss) {
+ System.out.println("ERROR: ConfigureDRM: SubsystemPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 6. display restore key cert panel
+ if (clone) {
+ boolean restore_st = RestoreKeyCertPanel();
+ if (!restore_st) {
+ System.out.println("ERROR: ConfigureCA: RestoreKeyCertPanel() failure");
+ return false;
+ }
+ }
+
+ sleep_time();
+ // 7. ldap connection panel
+ boolean disp_ldap = LdapConnectionPanel();
+ if (!disp_ldap) {
+ System.out.println("ERROR: ConfigureDRM: LdapConnectionPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ sleep_time();
+ // 9. Key Panel
+ boolean disp_key = KeyPanel();
+ if (!disp_key) {
+ System.out.println("ERROR: ConfigureDRM: KeyPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 10. Cert Subject Panel
+ boolean disp_csubj = CertSubjectPanel();
+ if (!disp_csubj) {
+ System.out.println("ERROR: ConfigureDRM: CertSubjectPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 11. Certificate Panel
+ boolean disp_cp = CertificatePanel();
+ if (!disp_cp) {
+ System.out.println("ERROR: ConfigureDRM: CertificatePanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // backup panel
+ boolean disp_back = BackupPanel();
+ if (!disp_back) {
+ System.out.println("ERROR: ConfigureDRM: BackupPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // save panel
+ boolean disp_save = SavePKCS12Panel();
+ if (!disp_save) {
+ System.out.println("ERROR: ConfigureDRM: SavePKCS12Panel() failure");
+ return false;
+ }
+
+ if (clone) {
+ // no other panels required for clone
+ return true;
+ }
+
+ sleep_time();
+ // 13. Admin Cert Req Panel
+ boolean disp_adm = AdminCertReqPanel();
+ if (!disp_adm) {
+ System.out.println("ERROR: ConfigureDRM: AdminCertReqPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 14. Admin Cert import Panel
+ boolean disp_im = AdminCertImportPanel();
+ if (!disp_im) {
+ System.out.println("ERROR: ConfigureDRM: AdminCertImportPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 15. Update Domain Panel
+ boolean disp_ud = UpdateDomainPanel();
+ if (!disp_ud) {
+ System.out.println("ERROR: ConfigureDRM: UpdateDomainPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ return true;
+ }
+
+ private static String set_default(String val, String def) {
+ if ((val == null) || (val.equals(""))) {
+ return def;
+ } else {
+ return val;
+ }
+ }
+
+ public static void main(String args[]) throws UnsupportedEncodingException {
+ ConfigureDRM ca = new ConfigureDRM();
+
+ // set variables
+ StringHolder x_cs_hostname = new StringHolder();
+ StringHolder x_cs_port = new StringHolder();
+
+ StringHolder x_sd_hostname = new StringHolder();
+ StringHolder x_sd_ssl_port = new StringHolder();
+ StringHolder x_sd_agent_port = new StringHolder();
+ StringHolder x_sd_admin_port = new StringHolder();
+ StringHolder x_sd_admin_name = new StringHolder();
+ StringHolder x_sd_admin_password = new StringHolder();
+
+ StringHolder x_ca_hostname = new StringHolder();
+ StringHolder x_ca_port = new StringHolder();
+ StringHolder x_ca_ssl_port = new StringHolder();
+
+ StringHolder x_client_certdb_dir = new StringHolder();
+ StringHolder x_client_certdb_pwd = new StringHolder();
+ StringHolder x_preop_pin = new StringHolder();
+
+ StringHolder x_domain_name = new StringHolder();
+
+ StringHolder x_admin_user = new StringHolder();
+ StringHolder x_admin_email = new StringHolder();
+ StringHolder x_admin_password = new StringHolder();
+
+ // ldap
+ StringHolder x_ldap_host = new StringHolder();
+ StringHolder x_ldap_port = new StringHolder();
+ StringHolder x_bind_dn = new StringHolder();
+ StringHolder x_bind_password = new StringHolder();
+ StringHolder x_base_dn = new StringHolder();
+ StringHolder x_db_name = new StringHolder();
+ StringHolder x_secure_conn = new StringHolder();
+ StringHolder x_remove_data = new StringHolder();
+
+ // key properties (defaults)
+ StringHolder x_key_size = new StringHolder();
+ StringHolder x_key_type = new StringHolder();
+ StringHolder x_key_curvename = new StringHolder();
+ StringHolder x_signing_algorithm = new StringHolder();
+
+ // key properties (custom - transport)
+ StringHolder x_transport_key_size = new StringHolder();
+ StringHolder x_transport_key_type = new StringHolder();
+ StringHolder x_transport_key_curvename = new StringHolder();
+ StringHolder x_transport_signingalgorithm = new StringHolder();
+
+ // key properties (custom - storage)
+ StringHolder x_storage_key_size = new StringHolder();
+ StringHolder x_storage_key_type = new StringHolder();
+ StringHolder x_storage_key_curvename = new StringHolder();
+
+ // key properties (custom - audit_signing)
+ StringHolder x_audit_signing_key_size = new StringHolder();
+ StringHolder x_audit_signing_key_type = new StringHolder();
+ StringHolder x_audit_signing_key_curvename = new StringHolder();
+
+ // key properties (custom - subsystem)
+ StringHolder x_subsystem_key_size = new StringHolder();
+ StringHolder x_subsystem_key_type = new StringHolder();
+ StringHolder x_subsystem_key_curvename = new StringHolder();
+
+ // key properties (custom - sslserver)
+ StringHolder x_sslserver_key_size = new StringHolder();
+ StringHolder x_sslserver_key_type = new StringHolder();
+ StringHolder x_sslserver_key_curvename = new StringHolder();
+
+ StringHolder x_token_name = new StringHolder();
+ StringHolder x_token_pwd = new StringHolder();
+
+ StringHolder x_agent_key_size = new StringHolder();
+ StringHolder x_agent_key_type = new StringHolder();
+ StringHolder x_agent_cert_subject = new StringHolder();
+
+ StringHolder x_agent_name = new StringHolder();
+ StringHolder x_backup_pwd = new StringHolder();
+ StringHolder x_backup_fname = new StringHolder();
+
+ // drm cert subject name params
+ StringHolder x_drm_subsystem_cert_subject_name = new StringHolder();
+ StringHolder x_drm_server_cert_subject_name = new StringHolder();
+ StringHolder x_drm_transport_cert_subject_name = new StringHolder();
+ StringHolder x_drm_storage_cert_subject_name = new StringHolder();
+ StringHolder x_drm_audit_signing_cert_subject_name = new StringHolder();
+
+ // subsystemName
+ StringHolder x_subsystem_name = new StringHolder();
+
+ //clone parameters
+ StringHolder x_clone = new StringHolder();
+ StringHolder x_clone_uri = new StringHolder();
+ StringHolder x_clone_p12_file = new StringHolder();
+ StringHolder x_clone_p12_passwd = new StringHolder();
+ StringHolder x_clone_master_port = new StringHolder();
+ StringHolder x_clone_replica_port = new StringHolder();
+ StringHolder x_clone_replication_security = new StringHolder();
+
+ // parse the args
+ ArgParser parser = new ArgParser("ConfigureDRM");
+
+ parser.addOption("-cs_hostname %s #CS Hostname",
+ x_cs_hostname);
+ parser.addOption("-cs_port %s #CS SSL Admin port",
+ x_cs_port);
+
+ parser.addOption("-sd_hostname %s #Security Domain Hostname",
+ x_sd_hostname);
+ parser.addOption("-sd_ssl_port %s #Security Domain SSL EE port",
+ x_sd_ssl_port);
+ parser.addOption("-sd_agent_port %s #Security Domain SSL Agent port",
+ x_sd_agent_port);
+ parser.addOption("-sd_admin_port %s #Security Domain SSL Admin port",
+ x_sd_admin_port);
+ parser.addOption("-sd_admin_name %s #Security Domain username",
+ x_sd_admin_name);
+ parser.addOption("-sd_admin_password %s #Security Domain password",
+ x_sd_admin_password);
+
+ parser.addOption("-ca_hostname %s #CA Hostname",
+ x_ca_hostname);
+ parser.addOption("-ca_port %s #CA non-SSL EE port",
+ x_ca_port);
+ parser.addOption("-ca_ssl_port %s #CA SSL EE port",
+ x_ca_ssl_port);
+
+ parser.addOption("-client_certdb_dir %s #Client CertDB dir",
+ x_client_certdb_dir);
+ parser.addOption("-client_certdb_pwd %s #client certdb password",
+ x_client_certdb_pwd);
+ parser.addOption("-preop_pin %s #pre op pin",
+ x_preop_pin);
+ parser.addOption("-domain_name %s #domain name",
+ x_domain_name);
+ parser.addOption("-admin_user %s #Admin User Name",
+ x_admin_user);
+ parser.addOption("-admin_email %s #Admin email",
+ x_admin_email);
+ parser.addOption("-admin_password %s #Admin password",
+ x_admin_password);
+ parser.addOption("-agent_name %s #Agent Cert Nickname",
+ x_agent_name);
+
+ parser.addOption("-ldap_host %s #ldap host",
+ x_ldap_host);
+ parser.addOption("-ldap_port %s #ldap port",
+ x_ldap_port);
+ parser.addOption("-bind_dn %s #ldap bind dn",
+ x_bind_dn);
+ parser.addOption("-bind_password %s #ldap bind password",
+ x_bind_password);
+ parser.addOption("-base_dn %s #base dn",
+ x_base_dn);
+ parser.addOption("-db_name %s #db name",
+ x_db_name);
+ parser.addOption("-secure_conn %s #use ldaps port (optional, default is false)", x_secure_conn);
+ parser.addOption("-remove_data %s #remove existing data under base_dn (optional, default is false) ",
+ x_remove_data);
+
+ // key and algorithm options (default)
+ parser.addOption("-key_type %s #Key type [RSA,ECC] (optional, default is RSA)", x_key_type);
+ parser.addOption("-key_size %s #Key Size (optional, for RSA default is 2048)", x_key_size);
+ parser.addOption("-key_curvename %s #Key Curve Name (optional, for ECC default is nistp256)", x_key_curvename);
+ parser.addOption(
+ "-signing_algorithm %s #Signing algorithm (optional, default is SHA256withRSA for RSA and SHA256withEC for ECC)",
+ x_signing_algorithm);
+
+ // key and algorithm options for transport certificate (overrides default)
+ parser.addOption("-transport_key_type %s #Key type [RSA,ECC] (optional, default is key_type)",
+ x_transport_key_type);
+ parser.addOption("-transport_key_size %s #Key Size (optional, for RSA default is key_size)",
+ x_transport_key_size);
+ parser.addOption("-transport_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_transport_key_curvename);
+ parser.addOption(
+ "-transport_signingalgorithm %s #Algorithm used by the transport cert to sign objects (optional, default is signing_algorithm)",
+ x_transport_signingalgorithm);
+
+ // key and algorithm options for storage certificate (overrides default)
+ parser.addOption("-storage_key_type %s #Key type [RSA,ECC] (optional, default is key_type)", x_storage_key_type);
+ parser.addOption("-storage_key_size %s #Key Size (optional, for RSA default is key_size)", x_storage_key_size);
+ parser.addOption("-storage_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_storage_key_curvename);
+
+ // key and algorithm options for audit_signing certificate (overrides default)
+ parser.addOption("-audit_signing_key_type %s #Key type [RSA,ECC] (optional, default is key_type)",
+ x_audit_signing_key_type);
+ parser.addOption("-audit_signing_key_size %s #Key Size (optional, for RSA default is key_size)",
+ x_audit_signing_key_size);
+ parser.addOption(
+ "-audit_signing_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_audit_signing_key_curvename);
+
+ // key and algorithm options for subsystem certificate (overrides default)
+ parser.addOption("-subsystem_key_type %s #Key type [RSA,ECC] (optional, default is key_type)",
+ x_subsystem_key_type);
+ parser.addOption("-subsystem_key_size %s #Key Size (optional, for RSA default is key_size)",
+ x_subsystem_key_size);
+ parser.addOption("-subsystem_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_subsystem_key_curvename);
+
+ // key and algorithm options for sslserver certificate (overrides default)
+ parser.addOption("-sslserver_key_type %s #Key type [RSA,ECC] (optional, default is key_type)",
+ x_sslserver_key_type);
+ parser.addOption("-sslserver_key_size %s #Key Size (optional, for RSA default is key_size)",
+ x_sslserver_key_size);
+ parser.addOption("-sslserver_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_sslserver_key_curvename);
+
+ parser.addOption("-token_name %s #HSM/Software Token name",
+ x_token_name);
+ parser.addOption("-token_pwd %s #HSM/Software Token password (optional, required for HSM)",
+ x_token_pwd);
+
+ parser.addOption("-agent_key_size %s #Agent Cert Key Size",
+ x_agent_key_size);
+ parser.addOption("-agent_key_type %s #Agent Cert Key type [rsa]",
+ x_agent_key_type);
+ parser.addOption("-agent_cert_subject %s #Agent Cert Subject ",
+ x_agent_cert_subject);
+
+ parser.addOption("-backup_pwd %s #PKCS12 password",
+ x_backup_pwd);
+
+ parser.addOption("-backup_fname %s #Backup File for p12, (optional, default /root/tmp-kra.p12)",
+ x_backup_fname);
+
+ parser.addOption(
+ "-drm_transport_cert_subject_name %s #DRM transport cert subject name",
+ x_drm_transport_cert_subject_name);
+ parser.addOption(
+ "-drm_subsystem_cert_subject_name %s #DRM subsystem cert subject name",
+ x_drm_subsystem_cert_subject_name);
+ parser.addOption(
+ "-drm_storage_cert_subject_name %s #DRM storage cert subject name",
+ x_drm_storage_cert_subject_name);
+ parser.addOption(
+ "-drm_server_cert_subject_name %s #DRM server cert subject name",
+ x_drm_server_cert_subject_name);
+
+ parser.addOption(
+ "-subsystem_name %s #CA subsystem name",
+ x_subsystem_name);
+
+ parser.addOption(
+ "-drm_audit_signing_cert_subject_name %s #DRM audit signing cert subject name",
+ x_drm_audit_signing_cert_subject_name);
+
+ parser.addOption("-clone %s #Clone of another KRA [true, false] (optional, default false)", x_clone);
+ parser.addOption(
+ "-clone_uri %s #URL of Master KRA to clone. It must have the form https://<hostname>:<EE port> (optional, required if -clone=true)",
+ x_clone_uri);
+ parser.addOption(
+ "-clone_p12_file %s #File containing pk12 keys of Master KRA (optional, required if -clone=true)",
+ x_clone_p12_file);
+ parser.addOption("-clone_p12_password %s #Password for pk12 file (optional, required if -clone=true)",
+ x_clone_p12_passwd);
+
+ // replication agreement options
+ parser.addOption("-clone_master_port %s #Master Port to be used in replication agreement (optional)",
+ x_clone_master_port);
+ parser.addOption("-clone_replica_port %s #Replica Port to be used in replication agreement (optional)",
+ x_clone_replica_port);
+ parser.addOption("-clone_replication_security %s #Type of security in replication agreement (optional)",
+ x_clone_replication_security);
+
+
+ // and then match the arguments
+ String[] unmatched = null;
+ unmatched = parser.matchAllArgs(args, 0, ArgParser.EXIT_ON_UNMATCHED);
+
+ if (unmatched != null) {
+ System.out.println("ERROR: Argument Mismatch");
+ System.exit(-1);
+ }
+
+ parser.checkRequiredArgs();
+
+ // set variables
+ cs_hostname = x_cs_hostname.value;
+ cs_port = x_cs_port.value;
+
+ sd_hostname = x_sd_hostname.value;
+ sd_ssl_port = x_sd_ssl_port.value;
+ sd_agent_port = x_sd_agent_port.value;
+ sd_admin_port = x_sd_admin_port.value;
+ sd_admin_name = x_sd_admin_name.value;
+ sd_admin_password = x_sd_admin_password.value;
+
+ ca_hostname = x_ca_hostname.value;
+ ca_port = x_ca_port.value;
+ ca_ssl_port = x_ca_ssl_port.value;
+
+ client_certdb_dir = x_client_certdb_dir.value;
+ client_certdb_pwd = x_client_certdb_pwd.value;
+ pin = x_preop_pin.value;
+ domain_name = x_domain_name.value;
+
+ admin_user = x_admin_user.value;
+ admin_email = x_admin_email.value;
+ admin_password = x_admin_password.value;
+ agent_name = x_agent_name.value;
+
+ ldap_host = x_ldap_host.value;
+ ldap_port = x_ldap_port.value;
+ bind_dn = x_bind_dn.value;
+ bind_password = x_bind_password.value;
+ base_dn = x_base_dn.value;
+ db_name = x_db_name.value;
+ secure_conn = set_default(x_secure_conn.value, "false");
+ remove_data = set_default(x_remove_data.value, "false");
+
+ key_type = set_default(x_key_type.value, DEFAULT_KEY_TYPE);
+ transport_key_type = set_default(x_transport_key_type.value, key_type);
+ storage_key_type = set_default(x_storage_key_type.value, key_type);
+ audit_signing_key_type = set_default(x_audit_signing_key_type.value, key_type);
+ subsystem_key_type = set_default(x_subsystem_key_type.value, key_type);
+ sslserver_key_type = set_default(x_sslserver_key_type.value, key_type);
+
+ key_size = set_default(x_key_size.value, DEFAULT_KEY_SIZE);
+ transport_key_size = set_default(x_transport_key_size.value, key_size);
+ storage_key_size = set_default(x_storage_key_size.value, key_size);
+ audit_signing_key_size = set_default(x_audit_signing_key_size.value, key_size);
+ subsystem_key_size = set_default(x_subsystem_key_size.value, key_size);
+ sslserver_key_size = set_default(x_sslserver_key_size.value, key_size);
+
+ key_curvename = set_default(x_key_curvename.value, DEFAULT_KEY_CURVENAME);
+ transport_key_curvename = set_default(x_transport_key_curvename.value, key_curvename);
+ storage_key_curvename = set_default(x_storage_key_curvename.value, key_curvename);
+ audit_signing_key_curvename = set_default(x_audit_signing_key_curvename.value, key_curvename);
+ subsystem_key_curvename = set_default(x_subsystem_key_curvename.value, key_curvename);
+ sslserver_key_curvename = set_default(x_sslserver_key_curvename.value, key_curvename);
+
+ if (transport_key_type.equalsIgnoreCase("RSA")) {
+ signing_algorithm = set_default(x_signing_algorithm.value, DEFAULT_KEY_ALGORITHM_RSA);
+ } else {
+ signing_algorithm = set_default(x_signing_algorithm.value, DEFAULT_KEY_ALGORITHM_ECC);
+ }
+
+ transport_signingalgorithm = set_default(x_transport_signingalgorithm.value, signing_algorithm);
+
+ token_name = x_token_name.value;
+ token_pwd = x_token_pwd.value;
+
+ agent_key_size = x_agent_key_size.value;
+ agent_key_type = x_agent_key_type.value;
+ agent_cert_subject = x_agent_cert_subject.value;
+
+ backup_pwd = x_backup_pwd.value;
+ backup_fname = set_default(x_backup_fname.value, "/root/tmp-kra.p12");
+
+ drm_transport_cert_subject_name =
+ x_drm_transport_cert_subject_name.value;
+ drm_subsystem_cert_subject_name =
+ x_drm_subsystem_cert_subject_name.value;
+ drm_storage_cert_subject_name = x_drm_storage_cert_subject_name.value;
+ drm_server_cert_subject_name = x_drm_server_cert_subject_name.value;
+ drm_audit_signing_cert_subject_name = x_drm_audit_signing_cert_subject_name.value;
+
+ subsystem_name = x_subsystem_name.value;
+
+ if ((x_clone.value != null) && (x_clone.value.equalsIgnoreCase("true"))) {
+ clone = true;
+ } else {
+ clone = false;
+ }
+ clone_uri = x_clone_uri.value;
+ clone_p12_file = x_clone_p12_file.value;
+ clone_p12_passwd = x_clone_p12_passwd.value;
+ clone_master_port = set_default(x_clone_master_port.value, "");
+ clone_replica_port = set_default(x_clone_replica_port.value, "");
+ clone_replication_security = set_default(x_clone_replication_security.value, "None");
+
+ boolean st = ca.ConfigureDRMInstance();
+
+ if (!st) {
+ System.out.println("ERROR: unable to create DRM");
+ System.exit(-1);
+ }
+
+ System.out.println("Certificate System - DRM Instance Configured");
+ System.exit(0);
+ }
+
+};
diff --git a/base/silent/src/com/netscape/pkisilent/ConfigureOCSP.java b/base/silent/src/com/netscape/pkisilent/ConfigureOCSP.java
new file mode 100644
index 000000000..53c014b74
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/ConfigureOCSP.java
@@ -0,0 +1,1181 @@
+package com.netscape.pkisilent;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.pkcs12.AuthenticatedSafes;
+import org.mozilla.jss.pkcs12.PFX;
+
+import com.netscape.pkisilent.argparser.ArgParser;
+import com.netscape.pkisilent.argparser.StringHolder;
+import com.netscape.pkisilent.common.ComCrypto;
+import com.netscape.pkisilent.common.ParseXML;
+import com.netscape.pkisilent.http.HTTPClient;
+import com.netscape.pkisilent.http.HTTPResponse;
+import com.netscape.cmsutil.util.Utils;
+
+public class ConfigureOCSP {
+ public static final String DEFAULT_KEY_TYPE = "RSA";
+ public static final String DEFAULT_KEY_SIZE = "2048";
+ public static final String DEFAULT_KEY_CURVENAME = "nistp256";
+ public static final String DEFAULT_KEY_ALGORITHM_RSA = "SHA256withRSA";
+ public static final String DEFAULT_KEY_ALGORITHM_ECC = "SHA256withEC";
+
+ // define global variables
+
+ public static HTTPClient hc = null;
+
+ public static String login_uri = "/ocsp/admin/console/config/login";
+ public static String wizard_uri = "/ocsp/admin/console/config/wizard";
+ public static String admin_uri = "/ca/admin/ca/getBySerial";
+
+ public static String sd_login_uri = "/ca/admin/ca/securityDomainLogin";
+ public static String sd_get_cookie_uri = "/ca/admin/ca/getCookie";
+ public static String pkcs12_uri = "/ocsp/admin/console/config/savepkcs12";
+
+ public static String cs_hostname = null;
+ public static String cs_port = null;
+
+ public static String sd_hostname = null;
+ public static String sd_ssl_port = null;
+ public static String sd_agent_port = null;
+ public static String sd_admin_port = null;
+ public static String sd_admin_name = null;
+ public static String sd_admin_password = null;
+
+ public static String ca_hostname = null;
+ public static String ca_port = null;
+ public static String ca_ssl_port = null;
+
+ public static String client_certdb_dir = null;
+ public static String client_certdb_pwd = null;
+
+ // Login Panel
+ public static String pin = null;
+
+ public static String domain_name = null;
+
+ public static String admin_user = null;
+ public static String admin_email = null;
+ public static String admin_password = null;
+ public static String admin_serial_number = null;
+ public static String agent_name = null;
+
+ public static String ldap_host = null;
+ public static String ldap_port = null;
+ public static String bind_dn = null;
+ public static String bind_password = null;
+ public static String base_dn = null;
+ public static String db_name = null;
+ public static String secure_conn = null;
+ public static String remove_data = null;
+
+ public static String key_type = null;
+ public static String key_size = null;
+ public static String key_curvename = null;
+ public static String signing_algorithm = null;
+
+ public static String signing_key_type = null;
+ public static String signing_key_size = null;
+ public static String signing_key_curvename = null;
+ public static String signing_signingalgorithm = null;
+
+ public static String subsystem_key_type = null;
+ public static String subsystem_key_size = null;
+ public static String subsystem_key_curvename = null;
+
+ public static String audit_signing_key_type = null;
+ public static String audit_signing_key_size = null;
+ public static String audit_signing_key_curvename = null;
+
+ public static String sslserver_key_type = null;
+ public static String sslserver_key_size = null;
+ public static String sslserver_key_curvename = null;
+
+ public static String token_name = null;
+ public static String token_pwd = null;
+
+ public static String agent_key_size = null;
+ public static String agent_key_type = null;
+ public static String agent_cert_subject = null;
+
+ public static String ocsp_signing_cert_name = null;
+ public static String ocsp_signing_cert_req = null;
+ public static String ocsp_signing_cert_pp = null;
+ public static String ocsp_signing_cert_cert = null;
+
+ public static String server_cert_name = null;
+ public static String server_cert_req = null;
+ public static String server_cert_pp = null;
+ public static String server_cert_cert = null;
+
+ public static String ocsp_subsystem_cert_name = null;
+ public static String ocsp_subsystem_cert_req = null;
+ public static String ocsp_subsystem_cert_pp = null;
+ public static String ocsp_subsystem_cert_cert = null;
+
+ public static String ocsp_audit_signing_cert_name = null;
+ public static String ocsp_audit_signing_cert_req = null;
+ public static String ocsp_audit_signing_cert_pp = null;
+ public static String ocsp_audit_signing_cert_cert = null;
+
+ public static String backup_pwd = null;
+ public static String backup_fname = null;
+
+ // cert subject names
+ public static String ocsp_sign_cert_subject_name = null;
+ public static String ocsp_subsystem_cert_subject_name = null;
+ public static String ocsp_server_cert_subject_name = null;
+ public static String ocsp_audit_signing_cert_subject_name = null;
+
+ public static String subsystem_name = null;
+
+ public ConfigureOCSP() {
+ // do nothing :)
+ }
+
+ public void sleep_time() {
+ try {
+ System.out.println("Sleeping for 5 secs..");
+ Thread.sleep(5000);
+ } catch (Exception e) {
+ System.out.println("ERROR: sleep problem");
+ }
+
+ }
+
+ public boolean LoginPanel() {
+ boolean st = false;
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "pin=" + pin + "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, login_uri, query_string);
+ System.out.println("xml returned: " + hr.getHTML());
+
+ // parse xml here - nothing to parse
+
+ // get cookie
+ String temp = hr.getCookieValue("JSESSIONID");
+
+ if (temp != null) {
+ int index = temp.indexOf(";");
+ HTTPClient.j_session_id = temp.substring(0, index);
+ st = true;
+ }
+
+ hr = null;
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri,
+ "p=0&op=next&xml=true");
+
+ // parse xml here
+
+ bais = new ByteArrayInputStream(
+ hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return st;
+ }
+
+ public boolean TokenChoicePanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = null;
+
+ // Software Token
+ if (token_name.equalsIgnoreCase("internal")) {
+ query_string = "p=1" + "&op=next" + "&xml=true" +
+ "&choice=" + URLEncoder.encode("Internal Key Storage Token", "UTF-8");
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+ }
+ // HSM
+ else {
+ // login to hsm first
+ query_string = "p=2" + "&op=next" + "&xml=true" +
+ "&uTokName=" +
+ URLEncoder.encode(token_name, "UTF-8") +
+ "&__uPasswd=" +
+ URLEncoder.encode(token_pwd, "UTF-8");
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ // choice with token name now
+ query_string = "p=1" + "&op=next" + "&xml=true" +
+ "&choice=" +
+ URLEncoder.encode(token_name, "UTF-8");
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ }
+ return true;
+ }
+
+ public boolean DomainPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String domain_url = "https://" + sd_hostname + ":" + sd_admin_port;
+
+ String query_string = "sdomainURL=" +
+ URLEncoder.encode(domain_url, "UTF-8") +
+ "&choice=existingdomain" +
+ "&p=3" +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+
+ }
+
+ public boolean DisplayChainPanel() {
+ String query_string = null;
+
+ query_string = "p=4" + "&op=next" + "&xml=true";
+ hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ // bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ // px.parse(bais);
+ // px.prettyprintxml();
+
+ return true;
+
+ }
+
+ public boolean SecurityDomainLoginPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+
+ String ocsp_url = "https://" + cs_hostname + ":" + cs_port +
+ "/ocsp/admin/console/config/wizard" +
+ "?p=5&subsystem=OCSP";
+
+ String query_string = "url=" + URLEncoder.encode(ocsp_url, "UTF-8");
+
+ hr = hc.sslConnect(sd_hostname, sd_admin_port, sd_login_uri, query_string);
+
+ String query_string_1 = "uid=" + sd_admin_name +
+ "&pwd=" + URLEncoder.encode(sd_admin_password, "UTF-8") +
+ "&url=" + URLEncoder.encode(ocsp_url, "UTF-8");
+
+ hr = hc.sslConnect(sd_hostname, sd_admin_port, sd_get_cookie_uri,
+ query_string_1);
+
+ // get session id from security domain
+
+ String ocsp_session_id = hr.getContentValue("header.session_id");
+ String ocsp_url_1 = hr.getContentValue("header.url");
+
+ System.out.println("OCSP_SESSION_ID=" + ocsp_session_id);
+ System.out.println("OCSP_URL=" + ocsp_url_1);
+
+ // use session id to connect back to OCSP
+
+ String query_string_2 = "p=5" +
+ "&subsystem=OCSP" +
+ "&session_id=" + ocsp_session_id +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri,
+ query_string_2);
+
+ return true;
+
+ }
+
+ public boolean SubsystemPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=5" + "&op=next" + "&xml=true" +
+ "&subsystemName=" +
+ URLEncoder.encode(subsystem_name, "UTF-8") +
+ "&choice=newsubsystem";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean LdapConnectionPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=7" + "&op=next" + "&xml=true" +
+ "&host=" + URLEncoder.encode(ldap_host, "UTF-8") +
+ "&port=" + URLEncoder.encode(ldap_port, "UTF-8") +
+ "&binddn=" + URLEncoder.encode(bind_dn, "UTF-8") +
+ "&__bindpwd=" + URLEncoder.encode(bind_password, "UTF-8") +
+ "&basedn=" + URLEncoder.encode(base_dn, "UTF-8") +
+ "&database=" + URLEncoder.encode(db_name, "UTF-8") +
+ "&display=" + URLEncoder.encode("$displayStr", "UTF-8") +
+ (secure_conn.equals("true") ? "&secureConn=on" : "") +
+ (remove_data.equals("true") ? "&removeData=true" : "");
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean KeyPanel() {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+ ArrayList<String> al = null;
+
+ String query_string = "p=8" + "&op=next" + "&xml=true" +
+ "&signing_custom_size=" + signing_key_size +
+ "&subsystem_custom_size=" + subsystem_key_size +
+ "&sslserver_custom_size=" + sslserver_key_size +
+ "&audit_signing_custom_size=" + audit_signing_key_size +
+ "&custom_size=" + key_size +
+ "&signing_custom_curvename=" + signing_key_curvename +
+ "&subsystem_custom_curvename=" + subsystem_key_curvename +
+ "&sslserver_custom_curvename=" + sslserver_key_curvename +
+ "&audit_signing_custom_curvename=" + audit_signing_key_curvename +
+ "&custom_curvename=" + key_curvename +
+ "&signing_keytype=" + signing_key_type +
+ "&subsystem_keytype=" + subsystem_key_type +
+ "&sslserver_keytype=" + sslserver_key_type +
+ "&audit_signing_keytype=" + audit_signing_key_type +
+ "&keytype=" + key_type +
+ "&signing_choice=custom" +
+ "&subsystem_choice=custom" +
+ "&sslserver_choice=custom" +
+ "&audit_signing_choice=custom" +
+ "&signingalgorithm=" + signing_algorithm +
+ "&signing_signingalgorithm=" + signing_signingalgorithm +
+ "&choice=custom";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ al = px.constructValueList("CertReqPair", "DN");
+ // get ca cert subject name
+ if (al != null) {
+ for (int i = 0; i < al.size(); i++) {
+ String temp = al.get(i);
+ if (temp.indexOf("OCSP Signing") > 0) {
+ ocsp_signing_cert_name = temp;
+ } else if (temp.indexOf("OCSP Subsystem") > 0) {
+ ocsp_subsystem_cert_name = temp;
+ } else if (temp.indexOf("Audit Signing Certificate") > 0) {
+ ocsp_audit_signing_cert_name = temp;
+ } else {
+ server_cert_name = temp;
+ }
+ }
+ }
+
+ System.out.println("default: ocsp_signing_cert_name=" + ocsp_signing_cert_name);
+ System.out.println("default: ocsp_subsystem_cert_name=" + ocsp_subsystem_cert_name);
+ System.out.println("default: server_cert_name=" + server_cert_name);
+ System.out.println("default: oscp_audit_signing_cert_name=" + ocsp_audit_signing_cert_name);
+
+ return true;
+ }
+
+ public boolean CertSubjectPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+ ArrayList<String> req_list = null;
+ ArrayList<String> cert_list = null;
+ ArrayList<String> dn_list = null;
+
+ String domain_url = "https://" + ca_hostname + ":" + ca_ssl_port;
+
+ String query_string = "p=9" + "&op=next" + "&xml=true" +
+ "&subsystem=" +
+ URLEncoder.encode(ocsp_subsystem_cert_subject_name, "UTF-8") +
+ "&signing=" +
+ URLEncoder.encode(ocsp_sign_cert_subject_name, "UTF-8") +
+ "&sslserver=" +
+ URLEncoder.encode(ocsp_server_cert_subject_name, "UTF-8") +
+ "&audit_signing=" +
+ URLEncoder.encode(ocsp_audit_signing_cert_subject_name, "UTF-8") +
+ "&urls=" +
+ URLEncoder.encode(domain_url, "UTF-8") +
+ "";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ req_list = px.constructValueList("CertReqPair", "Request");
+ cert_list = px.constructValueList("CertReqPair", "Certificate");
+ dn_list = px.constructValueList("CertReqPair", "Nickname");
+
+ if (req_list != null && cert_list != null && dn_list != null) {
+ for (int i = 0; i < dn_list.size(); i++) {
+ String temp = dn_list.get(i);
+
+ if (temp.indexOf("ocspSigningCert") >= 0) {
+ ocsp_signing_cert_req = req_list.get(i);
+ ocsp_signing_cert_cert = cert_list.get(i);
+ } else if (temp.indexOf("subsystemCert") >= 0) {
+ ocsp_subsystem_cert_req = req_list.get(i);
+ ocsp_subsystem_cert_cert = cert_list.get(i);
+ } else if (temp.indexOf("auditSigningCert") >= 0) {
+ ocsp_audit_signing_cert_req = req_list.get(i);
+ ocsp_audit_signing_cert_cert = cert_list.get(i);
+ } else {
+ server_cert_req = req_list.get(i);
+ server_cert_cert = cert_list.get(i);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ public boolean CertificatePanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=10" + "&op=next" + "&xml=true" +
+ "&subsystem=" +
+ URLEncoder.encode(ocsp_subsystem_cert_cert, "UTF-8") +
+ "&subsystem_cc=" +
+ "&signing=" +
+ URLEncoder.encode(ocsp_signing_cert_cert, "UTF-8") +
+ "&signing_cc=" +
+ "&sslserver=" +
+ URLEncoder.encode(server_cert_cert, "UTF-8") +
+ "&sslserver_cc=" +
+ "&audit_signing=" +
+ URLEncoder.encode(ocsp_audit_signing_cert_cert, "UTF-8") +
+ "&audit_signing_cc=";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+
+ System.out.println("html returned=" + hr.getHTML());
+
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean BackupPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=11" + "&op=next" + "&xml=true" +
+ "&choice=backupkey" +
+ "&__pwd=" + URLEncoder.encode(backup_pwd, "UTF-8") +
+ "&__pwdagain=" + URLEncoder.encode(backup_pwd, "UTF-8");
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean SavePKCS12Panel() {
+ HTTPResponse hr = null;
+
+ String query_string = "";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, pkcs12_uri, query_string);
+
+ // dump hr.getResponseData() to file
+
+ try {
+ FileOutputStream fos = new FileOutputStream(backup_fname);
+ fos.write(hr.getResponseData());
+ fos.close();
+
+ // set file to permissions 600
+ String rtParams[] = { "chmod", "600", backup_fname };
+ Process proc = Runtime.getRuntime().exec(rtParams);
+
+ BufferedReader br = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
+ String line = null;
+ while ((line = br.readLine()) != null)
+ System.out.println("Error: " + line);
+ proc.waitFor();
+
+ // verify p12 file
+
+ // Decode the P12 file
+ FileInputStream fis = new FileInputStream(backup_fname);
+ PFX.Template pfxt = new PFX.Template();
+ PFX pfx = (PFX) pfxt.decode(new BufferedInputStream(fis, 2048));
+ System.out.println("Decoded PFX");
+
+ // now peruse it for interesting info
+ System.out.println("Version: " + pfx.getVersion());
+ AuthenticatedSafes authSafes = pfx.getAuthSafes();
+ SEQUENCE asSeq = authSafes.getSequence();
+ System.out.println("AuthSafes has " +
+ asSeq.size() + " SafeContents");
+
+ fis.close();
+ } catch (Exception e) {
+ System.out.println("ERROR: Exception=" + e.getMessage());
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean AdminCertReqPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+ String admin_cert_request = null;
+
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir,
+ client_certdb_pwd,
+ agent_cert_subject,
+ agent_key_size,
+ agent_key_type);
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(true);
+ cCrypt.setTransportCert(null);
+ cCrypt.setDualKey(false);
+ cCrypt.loginDB();
+
+ String crmf_request = cCrypt.generateCRMFrequest();
+
+ if (crmf_request == null) {
+ System.out.println("ERROR: AdminCertReqPanel() cert req gen failed");
+ return false;
+ }
+
+ admin_cert_request = crmf_request;
+
+ String query_string = "p=13" + "&op=next" + "&xml=true" +
+ "&cert_request_type=" + "crmf" +
+ "&uid=" + admin_user +
+ "&name=" + admin_user +
+ "&__pwd=" + URLEncoder.encode(admin_password, "UTF-8") +
+ "&__admin_password_again=" + URLEncoder.encode(admin_password, "UTF-8") +
+ "&profileId=" + "caAdminCert" +
+ "&email=" +
+ URLEncoder.encode(admin_email, "UTF-8") +
+ "&cert_request=" +
+ URLEncoder.encode(admin_cert_request, "UTF-8") +
+ "&subject=" +
+ URLEncoder.encode(agent_cert_subject, "UTF-8") +
+ "&clone=new" +
+ "&import=true" +
+ "&securitydomain=" +
+ URLEncoder.encode(domain_name, "UTF-8");
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ admin_serial_number = px.getvalue("serialNumber");
+
+ return true;
+ }
+
+ public boolean AdminCertImportPanel() {
+ boolean st = false;
+ HTTPResponse hr = null;
+
+ String query_string = "serialNumber=" + admin_serial_number +
+ "&importCert=" + "true" +
+ "";
+
+ hr = hc.sslConnect(sd_hostname, sd_admin_port, admin_uri, query_string);
+
+ // get response data
+ // String cert_to_import =
+ // new sun.misc.BASE64Encoder().encode(hr.getResponseData());
+ String cert_to_import =
+ Utils.base64encode(hr.getResponseData());
+ System.out.println("Imported Cert=" + cert_to_import);
+
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir,
+ client_certdb_pwd,
+ null,
+ null,
+ null);
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(true);
+ cCrypt.loginDB();
+
+ String start = "-----BEGIN CERTIFICATE-----\r\n";
+ String end = "\r\n-----END CERTIFICATE-----";
+
+ st = cCrypt.importCert(start + cert_to_import + end, agent_name);
+ if (!st) {
+ System.out.println("ERROR: AdminCertImportPanel() during cert import");
+ return false;
+ }
+
+ System.out.println("SUCCESS: imported admin user cert");
+ return true;
+ }
+
+ public boolean UpdateDomainPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=14" + "&op=next" + "&xml=true" +
+ "&caHost=" + URLEncoder.encode(sd_hostname, "UTF-8") +
+ "&caPort=" + URLEncoder.encode(sd_agent_port, "UTF-8");
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean ConfigureOCSPInstance() throws UnsupportedEncodingException {
+ // 0. login to cert db
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir,
+ client_certdb_pwd,
+ null,
+ null,
+ null);
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(true);
+ cCrypt.loginDB();
+
+ // instantiate http client
+ hc = new HTTPClient();
+
+ // 1. Login panel
+ boolean log_st = LoginPanel();
+ if (!log_st) {
+ System.out.println("ERROR: ConfigureOCSP: LoginPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 2. Token Choice Panel
+ boolean disp_token = TokenChoicePanel();
+ if (!disp_token) {
+ System.out.println("ERROR: ConfigureOCSP: TokenChoicePanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 3. domain panel
+ boolean dom_st = DomainPanel();
+ if (!dom_st) {
+ System.out.println("ERROR: ConfigureOCSP: DomainPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 4. display cert chain panel
+ boolean disp_st = DisplayChainPanel();
+ if (!disp_st) {
+ System.out.println("ERROR: ConfigureOCSP: DisplayChainPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // security domain login panel
+ boolean disp_sd = SecurityDomainLoginPanel();
+ if (!disp_sd) {
+ System.out.println("ERROR: ConfigureOCSP: SecurityDomainLoginPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // subsystem panel
+ boolean disp_ss = SubsystemPanel();
+ if (!disp_ss) {
+ System.out.println("ERROR: ConfigureOCSP: SubsystemPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 7. ldap connection panel
+ boolean disp_ldap = LdapConnectionPanel();
+ if (!disp_ldap) {
+ System.out.println("ERROR: ConfigureOCSP: LdapConnectionPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ sleep_time();
+ // 9. Key Panel
+ boolean disp_key = KeyPanel();
+ if (!disp_key) {
+ System.out.println("ERROR: ConfigureOCSP: KeyPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 10. Cert Subject Panel
+ boolean disp_csubj = CertSubjectPanel();
+ if (!disp_csubj) {
+ System.out.println("ERROR: ConfigureOCSP: CertSubjectPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 11. Certificate Panel
+ boolean disp_cp = CertificatePanel();
+ if (!disp_cp) {
+ System.out.println("ERROR: ConfigureOCSP: CertificatePanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // backup panel
+ boolean disp_back = BackupPanel();
+ if (!disp_back) {
+ System.out.println("ERROR: ConfigureOCSP: BackupPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // save panel
+ boolean disp_save = SavePKCS12Panel();
+ if (!disp_save) {
+ System.out.println("ERROR: ConfigureOCSP: SavePKCS12Panel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 13. Admin Cert Req Panel
+ boolean disp_adm = AdminCertReqPanel();
+ if (!disp_adm) {
+ System.out.println("ERROR: ConfigureOCSP: AdminCertReqPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 14. Admin Cert import Panel
+ boolean disp_im = AdminCertImportPanel();
+ if (!disp_im) {
+ System.out.println("ERROR: ConfigureOCSP: AdminCertImportPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 15. Update Domain Panel
+ boolean disp_ud = UpdateDomainPanel();
+ if (!disp_ud) {
+ System.out.println("ERROR: ConfigureOCSP: UpdateDomainPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ return true;
+ }
+
+ private static String set_default(String val, String def) {
+ if ((val == null) || (val.equals(""))) {
+ return def;
+ } else {
+ return val;
+ }
+ }
+
+ public static void main(String args[]) throws UnsupportedEncodingException {
+ ConfigureOCSP ca = new ConfigureOCSP();
+
+ // set variables
+ StringHolder x_cs_hostname = new StringHolder();
+ StringHolder x_cs_port = new StringHolder();
+
+ StringHolder x_sd_hostname = new StringHolder();
+ StringHolder x_sd_ssl_port = new StringHolder();
+ StringHolder x_sd_agent_port = new StringHolder();
+ StringHolder x_sd_admin_port = new StringHolder();
+ StringHolder x_sd_admin_name = new StringHolder();
+ StringHolder x_sd_admin_password = new StringHolder();
+
+ StringHolder x_ca_hostname = new StringHolder();
+ StringHolder x_ca_port = new StringHolder();
+ StringHolder x_ca_ssl_port = new StringHolder();
+
+ StringHolder x_client_certdb_dir = new StringHolder();
+ StringHolder x_client_certdb_pwd = new StringHolder();
+ StringHolder x_preop_pin = new StringHolder();
+
+ StringHolder x_domain_name = new StringHolder();
+
+ StringHolder x_admin_user = new StringHolder();
+ StringHolder x_admin_email = new StringHolder();
+ StringHolder x_admin_password = new StringHolder();
+
+ // ldap
+ StringHolder x_ldap_host = new StringHolder();
+ StringHolder x_ldap_port = new StringHolder();
+ StringHolder x_bind_dn = new StringHolder();
+ StringHolder x_bind_password = new StringHolder();
+ StringHolder x_base_dn = new StringHolder();
+ StringHolder x_db_name = new StringHolder();
+ StringHolder x_secure_conn = new StringHolder();
+ StringHolder x_remove_data = new StringHolder();
+
+ // key properties (defaults)
+ StringHolder x_key_size = new StringHolder();
+ StringHolder x_key_type = new StringHolder();
+ StringHolder x_key_curvename = new StringHolder();
+ StringHolder x_signing_algorithm = new StringHolder();
+
+ // key properties (custom - signing)
+ StringHolder x_signing_key_size = new StringHolder();
+ StringHolder x_signing_key_type = new StringHolder();
+ StringHolder x_signing_key_curvename = new StringHolder();
+ StringHolder x_signing_signingalgorithm = new StringHolder();
+
+ // key properties (custom - audit_signing)
+ StringHolder x_audit_signing_key_size = new StringHolder();
+ StringHolder x_audit_signing_key_type = new StringHolder();
+ StringHolder x_audit_signing_key_curvename = new StringHolder();
+
+ // key properties (custom - subsystem)
+ StringHolder x_subsystem_key_size = new StringHolder();
+ StringHolder x_subsystem_key_type = new StringHolder();
+ StringHolder x_subsystem_key_curvename = new StringHolder();
+
+ // key properties (custom - sslserver)
+ StringHolder x_sslserver_key_size = new StringHolder();
+ StringHolder x_sslserver_key_type = new StringHolder();
+ StringHolder x_sslserver_key_curvename = new StringHolder();
+
+ StringHolder x_token_name = new StringHolder();
+ StringHolder x_token_pwd = new StringHolder();
+
+ StringHolder x_agent_key_size = new StringHolder();
+ StringHolder x_agent_key_type = new StringHolder();
+ StringHolder x_agent_cert_subject = new StringHolder();
+
+ StringHolder x_agent_name = new StringHolder();
+ StringHolder x_backup_pwd = new StringHolder();
+ StringHolder x_backup_fname = new StringHolder();
+
+ // ca cert subject name params
+ StringHolder x_ocsp_sign_cert_subject_name = new StringHolder();
+ StringHolder x_ocsp_subsystem_cert_subject_name = new StringHolder();
+ StringHolder x_ocsp_server_cert_subject_name = new StringHolder();
+ StringHolder x_ocsp_audit_signing_cert_subject_name = new StringHolder();
+
+ // subsystemName
+ StringHolder x_subsystem_name = new StringHolder();
+
+ // parse the args
+ ArgParser parser = new ArgParser("ConfigureOCSP");
+
+ parser.addOption("-cs_hostname %s #CS Hostname",
+ x_cs_hostname);
+ parser.addOption("-cs_port %s #CS SSL Admin port",
+ x_cs_port);
+
+ parser.addOption("-sd_hostname %s #Security Domain Hostname",
+ x_sd_hostname);
+ parser.addOption("-sd_ssl_port %s #Security Domain SSL EE port",
+ x_sd_ssl_port);
+ parser.addOption("-sd_agent_port %s #Security Domain SSL Agent port",
+ x_sd_agent_port);
+ parser.addOption("-sd_admin_port %s #Security Domain SSL Admin port",
+ x_sd_admin_port);
+ parser.addOption("-sd_admin_name %s #Security Domain Admin Name",
+ x_sd_admin_name);
+ parser.addOption("-sd_admin_password %s #Security Domain Admin password",
+ x_sd_admin_password);
+
+ parser.addOption("-ca_hostname %s #CA Hostname",
+ x_ca_hostname);
+ parser.addOption("-ca_port %s #CA non-SSL EE port",
+ x_ca_port);
+ parser.addOption("-ca_ssl_port %s #CA SSL EE port",
+ x_ca_ssl_port);
+
+ parser.addOption("-client_certdb_dir %s #Client CertDB dir",
+ x_client_certdb_dir);
+ parser.addOption("-client_certdb_pwd %s #client certdb password",
+ x_client_certdb_pwd);
+ parser.addOption("-preop_pin %s #pre op pin",
+ x_preop_pin);
+ parser.addOption("-domain_name %s #domain name",
+ x_domain_name);
+ parser.addOption("-admin_user %s #Admin User Name",
+ x_admin_user);
+ parser.addOption("-admin_email %s #Admin email",
+ x_admin_email);
+ parser.addOption("-admin_password %s #Admin password",
+ x_admin_password);
+ parser.addOption("-agent_name %s #Agent Cert Nickname",
+ x_agent_name);
+
+ parser.addOption("-ldap_host %s #ldap host",
+ x_ldap_host);
+ parser.addOption("-ldap_port %s #ldap port",
+ x_ldap_port);
+ parser.addOption("-bind_dn %s #ldap bind dn",
+ x_bind_dn);
+ parser.addOption("-bind_password %s #ldap bind password",
+ x_bind_password);
+ parser.addOption("-base_dn %s #base dn",
+ x_base_dn);
+ parser.addOption("-db_name %s #db name",
+ x_db_name);
+ parser.addOption("-secure_conn %s #use ldaps port (optional, default is false)", x_secure_conn);
+ parser.addOption("-remove_data %s #remove existing data under base_dn (optional, default is false) ",
+ x_remove_data);
+
+ // key and algorithm options (default)
+ parser.addOption("-key_type %s #Key type [RSA,ECC] (optional, default is RSA)", x_key_type);
+ parser.addOption("-key_size %s #Key Size (optional, for RSA default is 2048)", x_key_size);
+ parser.addOption("-key_curvename %s #Key Curve Name (optional, for ECC default is nistp256)", x_key_curvename);
+ parser.addOption(
+ "-signing_algorithm %s #Signing algorithm (optional, default is SHA256withRSA for RSA and SHA256withEC for ECC)",
+ x_signing_algorithm);
+
+ // key and algorithm options for signing certificate (overrides default)
+ parser.addOption("-signing_key_type %s #Key type [RSA,ECC] (optional, default is key_type)", x_signing_key_type);
+ parser.addOption("-signing_key_size %s #Key Size (optional, for RSA default is key_size)", x_signing_key_size);
+ parser.addOption("-signing_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_signing_key_curvename);
+ parser.addOption(
+ "-signing_signingalgorithm %s #Algorithm used be ocsp signing cert to sign objects (optional, default is signing_algorithm)",
+ x_signing_signingalgorithm);
+
+ // key and algorithm options for audit_signing certificate (overrides default)
+ parser.addOption("-audit_signing_key_type %s #Key type [RSA,ECC] (optional, default is key_type)",
+ x_audit_signing_key_type);
+ parser.addOption("-audit_signing_key_size %s #Key Size (optional, for RSA default is key_size)",
+ x_audit_signing_key_size);
+ parser.addOption(
+ "-audit_signing_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_audit_signing_key_curvename);
+
+ // key and algorithm options for subsystem certificate (overrides default)
+ parser.addOption("-subsystem_key_type %s #Key type [RSA,ECC] (optional, default is key_type)",
+ x_subsystem_key_type);
+ parser.addOption("-subsystem_key_size %s #Key Size (optional, for RSA default is key_size)",
+ x_subsystem_key_size);
+ parser.addOption("-subsystem_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_subsystem_key_curvename);
+
+ // key and algorithm options for sslserver certificate (overrides default)
+ parser.addOption("-sslserver_key_type %s #Key type [RSA,ECC] (optional, default is key_type)",
+ x_sslserver_key_type);
+ parser.addOption("-sslserver_key_size %s #Key Size (optional, for RSA default is key_size)",
+ x_sslserver_key_size);
+ parser.addOption("-sslserver_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_sslserver_key_curvename);
+
+ parser.addOption("-token_name %s #HSM/Software Token name",
+ x_token_name);
+ parser.addOption("-token_pwd %s #HSM/Software Token password (optional, required for HSM)",
+ x_token_pwd);
+
+ parser.addOption("-agent_key_size %s #Agent Cert Key Size",
+ x_agent_key_size);
+ parser.addOption("-agent_key_type %s #Agent Cert Key type [rsa]",
+ x_agent_key_type);
+ parser.addOption("-agent_cert_subject %s #Agent Cert Subject",
+ x_agent_cert_subject);
+
+ parser.addOption("-backup_pwd %s #PKCS12 password",
+ x_backup_pwd);
+
+ parser.addOption(
+ "-ocsp_sign_cert_subject_name %s #OCSP cert subject name",
+ x_ocsp_sign_cert_subject_name);
+ parser.addOption(
+ "-ocsp_subsystem_cert_subject_name %s #OCSP subsystem cert subject name",
+ x_ocsp_subsystem_cert_subject_name);
+ parser.addOption(
+ "-ocsp_server_cert_subject_name %s #OCSP server cert subject name",
+ x_ocsp_server_cert_subject_name);
+
+ parser.addOption("-backup_fname %s #Backup File for p12, (optional, default /root/tmp-ocsp.p12",
+ x_backup_fname);
+
+ parser.addOption(
+ "-subsystem_name %s #OCSP subsystem name",
+ x_subsystem_name);
+
+ parser.addOption(
+ "-ocsp_audit_signing_cert_subject_name %s #OCSP audit signing cert subject name",
+ x_ocsp_audit_signing_cert_subject_name);
+
+ // and then match the arguments
+ String[] unmatched = null;
+ unmatched = parser.matchAllArgs(args, 0, ArgParser.EXIT_ON_UNMATCHED);
+
+ if (unmatched != null) {
+ System.out.println("ERROR: Argument Mismatch");
+ System.exit(-1);
+ }
+
+ parser.checkRequiredArgs();
+
+ // set variables
+ cs_hostname = x_cs_hostname.value;
+ cs_port = x_cs_port.value;
+
+ sd_hostname = x_sd_hostname.value;
+ sd_ssl_port = x_sd_ssl_port.value;
+ sd_agent_port = x_sd_agent_port.value;
+ sd_admin_port = x_sd_admin_port.value;
+ sd_admin_name = x_sd_admin_name.value;
+ sd_admin_password = x_sd_admin_password.value;
+
+ ca_hostname = x_ca_hostname.value;
+ ca_port = x_ca_port.value;
+ ca_ssl_port = x_ca_ssl_port.value;
+
+ client_certdb_dir = x_client_certdb_dir.value;
+ client_certdb_pwd = x_client_certdb_pwd.value;
+ pin = x_preop_pin.value;
+ domain_name = x_domain_name.value;
+
+ admin_user = x_admin_user.value;
+ admin_email = x_admin_email.value;
+ admin_password = x_admin_password.value;
+ agent_name = x_agent_name.value;
+
+ ldap_host = x_ldap_host.value;
+ ldap_port = x_ldap_port.value;
+ bind_dn = x_bind_dn.value;
+ bind_password = x_bind_password.value;
+ base_dn = x_base_dn.value;
+ db_name = x_db_name.value;
+ secure_conn = set_default(x_secure_conn.value, "false");
+ remove_data = set_default(x_remove_data.value, "false");
+
+ key_type = set_default(x_key_type.value, DEFAULT_KEY_TYPE);
+ signing_key_type = set_default(x_signing_key_type.value, key_type);
+ audit_signing_key_type = set_default(x_audit_signing_key_type.value, key_type);
+ subsystem_key_type = set_default(x_subsystem_key_type.value, key_type);
+ sslserver_key_type = set_default(x_sslserver_key_type.value, key_type);
+
+ key_size = set_default(x_key_size.value, DEFAULT_KEY_SIZE);
+ signing_key_size = set_default(x_signing_key_size.value, key_size);
+ audit_signing_key_size = set_default(x_audit_signing_key_size.value, key_size);
+ subsystem_key_size = set_default(x_subsystem_key_size.value, key_size);
+ sslserver_key_size = set_default(x_sslserver_key_size.value, key_size);
+
+ key_curvename = set_default(x_key_curvename.value, DEFAULT_KEY_CURVENAME);
+ signing_key_curvename = set_default(x_signing_key_curvename.value, key_curvename);
+ audit_signing_key_curvename = set_default(x_audit_signing_key_curvename.value, key_curvename);
+ subsystem_key_curvename = set_default(x_subsystem_key_curvename.value, key_curvename);
+ sslserver_key_curvename = set_default(x_sslserver_key_curvename.value, key_curvename);
+
+ if (signing_key_type.equalsIgnoreCase("RSA")) {
+ signing_algorithm = set_default(x_signing_algorithm.value, DEFAULT_KEY_ALGORITHM_RSA);
+ } else {
+ signing_algorithm = set_default(x_signing_algorithm.value, DEFAULT_KEY_ALGORITHM_ECC);
+ }
+ signing_signingalgorithm = set_default(x_signing_signingalgorithm.value, signing_algorithm);
+
+ token_name = x_token_name.value;
+ token_pwd = x_token_pwd.value;
+
+ agent_key_size = x_agent_key_size.value;
+ agent_key_type = x_agent_key_type.value;
+ agent_cert_subject = x_agent_cert_subject.value;
+
+ backup_pwd = x_backup_pwd.value;
+ backup_fname = set_default(x_backup_fname.value, "/root/tmp-ocsp.p12");
+
+ ocsp_sign_cert_subject_name = x_ocsp_sign_cert_subject_name.value;
+ ocsp_subsystem_cert_subject_name =
+ x_ocsp_subsystem_cert_subject_name.value;
+ ocsp_server_cert_subject_name = x_ocsp_server_cert_subject_name.value;
+ ocsp_audit_signing_cert_subject_name = x_ocsp_audit_signing_cert_subject_name.value;
+
+ subsystem_name = x_subsystem_name.value;
+
+ boolean st = ca.ConfigureOCSPInstance();
+
+ if (!st) {
+ System.out.println("ERROR: unable to create OCSP");
+ System.exit(-1);
+ }
+
+ System.out.println("Certificate System - OCSP Instance Configured");
+ System.exit(0);
+
+ }
+
+};
diff --git a/base/silent/src/com/netscape/pkisilent/ConfigureRA.java b/base/silent/src/com/netscape/pkisilent/ConfigureRA.java
new file mode 100644
index 000000000..3de70a067
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/ConfigureRA.java
@@ -0,0 +1,881 @@
+package com.netscape.pkisilent;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.ByteArrayInputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+import com.netscape.pkisilent.argparser.ArgParser;
+import com.netscape.pkisilent.argparser.StringHolder;
+import com.netscape.pkisilent.common.ComCrypto;
+import com.netscape.pkisilent.common.ParseXML;
+import com.netscape.pkisilent.http.HTTPClient;
+import com.netscape.pkisilent.http.HTTPResponse;
+import com.netscape.cmsutil.util.Utils;
+
+public class ConfigureRA {
+
+ // define global variables
+
+ public static HTTPClient hc = null;
+
+ public static String login_uri = "/ra/admin/console/config/login";
+ public static String wizard_uri = "/ra/admin/console/config/wizard";
+ public static String admin_uri = "/ca/admin/ca/getBySerial";
+
+ public static String sd_login_uri = "/ca/admin/ca/securityDomainLogin";
+ public static String sd_get_cookie_uri = "/ca/admin/ca/getCookie";
+ public static String sd_update_domain_uri = "/ca/agent/ca/updateDomainXML";
+ public static String pkcs12_uri = "/ra/admin/console/config/savepkcs12";
+
+ public static String cs_hostname = null;
+ public static String cs_port = null;
+ public static String cs_clientauth_port = null;
+
+ public static String sd_hostname = null;
+ public static String sd_ssl_port = null;
+ public static String sd_agent_port = null;
+ public static String sd_admin_port = null;
+ public static String sd_admin_name = null;
+ public static String sd_admin_password = null;
+
+ public static String ca_hostname = null;
+ public static String ca_port = null;
+ public static String ca_ssl_port = null;
+ public static String ca_admin_port = null;
+
+ public static String client_certdb_dir = null;
+ public static String client_certdb_pwd = null;
+
+ // Login Panel
+ public static String pin = null;
+
+ public static String domain_name = null;
+
+ public static String admin_user = null;
+ public static String admin_email = null;
+ public static String admin_password = null;
+ public static String admin_serial_number = null;
+ public static String agent_name = null;
+
+ public static String key_size = null;
+ public static String key_type = null;
+ public static String token_name = null;
+ public static String token_pwd = null;
+
+ public static String agent_key_size = null;
+ public static String agent_key_type = null;
+ public static String agent_cert_subject = null;
+
+ public static String server_cert_name = null;
+ public static String server_cert_req = null;
+ public static String server_cert_pp = null;
+ public static String server_cert_cert = null;
+
+ public static String ra_subsystem_cert_name = null;
+ public static String ra_subsystem_cert_req = null;
+ public static String ra_subsystem_cert_pp = null;
+ public static String ra_subsystem_cert_cert = null;
+
+ // names
+ public static String ra_server_cert_subject_name = null;
+ public static String ra_server_cert_nickname = null;
+ public static String ra_subsystem_cert_subject_name = null;
+ public static String ra_subsystem_cert_nickname = null;
+ public static String subsystem_name = null;
+
+ // Security Domain Login Panel
+ public static String ra_session_id = null;
+
+ // Admin Certificate Request Panel
+ public static String requestor_name = null;
+
+ public ConfigureRA() {
+ // do nothing :)
+ }
+
+ public void sleep_time() {
+ try {
+ System.out.println("Sleeping for 5 secs..");
+ Thread.sleep(5000);
+ } catch (Exception e) {
+ System.out.println("ERROR: sleep problem");
+ }
+
+ }
+
+ public boolean LoginPanel() {
+ boolean st = false;
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "pin=" + pin + "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, login_uri, query_string);
+ System.out.println("xml returned: " + hr.getHTML());
+
+ // parse xml here - nothing to parse
+
+ // no cookie for ra
+ // get cookie
+ String temp = hr.getCookieValue("pin");
+
+ if (temp != null) {
+ int index = temp.indexOf(";");
+ HTTPClient.j_session_id = temp.substring(0, index);
+ st = true;
+ }
+
+ hr = null;
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri,
+ "p=0&op=next&xml=true");
+
+ // parse xml here
+
+ bais = new ByteArrayInputStream(
+ hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ st = true;
+ return st;
+ }
+
+ public boolean DomainPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String domain_url = "https://" + sd_hostname + ":" + sd_admin_port;
+
+ String query_string = "p=1" +
+ "&choice=existingdomain" +
+ "&sdomainURL=" +
+ URLEncoder.encode(domain_url, "UTF-8") +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+
+ }
+
+ public boolean DisplayChainPanel() {
+ String query_string = "p=2" + "&op=next" + "&xml=true";
+ hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ return true;
+
+ }
+
+ public boolean SecurityDomainLoginPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+
+ String ra_url = "https://" + cs_hostname + ":" + cs_port +
+ "/ra/admin/console/config/wizard" +
+ "?p=3&subsystem=RA";
+
+ String query_string = "url=" + URLEncoder.encode(ra_url, "UTF-8") + "";
+
+ hr = hc.sslConnect(sd_hostname, sd_admin_port, sd_login_uri, query_string);
+
+ String query_string_1 = "uid=" + sd_admin_name +
+ "&pwd=" + URLEncoder.encode(sd_admin_password, "UTF-8") +
+ "&url=" + URLEncoder.encode(ra_url, "UTF-8") +
+ "";
+
+ hr = hc.sslConnect(sd_hostname, sd_admin_port, sd_get_cookie_uri,
+ query_string_1);
+
+ // get session id from security domain
+ sleep_time();
+
+ ra_session_id = hr.getContentValue("header.session_id");
+ String ra_url_1 = hr.getContentValue("header.url");
+
+ System.out.println("RA_SESSION_ID=" + ra_session_id);
+ System.out.println("RA_URL=" + ra_url_1);
+
+ // use session id to connect back to RA
+
+ String query_string_2 = "p=3" +
+ "&subsystem=RA" +
+ "&session_id=" + ra_session_id +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri,
+ query_string_2);
+
+ // parse xml - no parsing
+
+ return true;
+
+ }
+
+ public boolean SubsystemPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ sleep_time();
+ String query_string = "p=3" +
+ "&choice=newsubsystem" +
+ "&subsystemName=" +
+ URLEncoder.encode(subsystem_name, "UTF-8") +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ sleep_time();
+
+ // CA choice panel
+ query_string = "p=4" +
+ "&urls=0" +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean DBPanel() {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ // SQL LITE PANEL
+
+ String query_string = "p=5" + "&op=next" + "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean TokenChoicePanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ ////////////////////////////////////////////////////////
+ String query_string = null;
+
+ // Software Token
+ if (token_name.equalsIgnoreCase("internal")) {
+ query_string = "p=6" +
+ "&choice=" +
+ URLEncoder.encode("NSS Certificate DB", "UTF-8") +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+ }
+ // HSM
+ else {
+ // login to hsm first
+ query_string = "p=7" +
+ "&uTokName=" +
+ URLEncoder.encode(token_name, "UTF-8") +
+ "&__uPasswd=" +
+ URLEncoder.encode(token_pwd, "UTF-8") +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ // choice with token name now
+ query_string = "p=6" +
+ "&choice=" +
+ URLEncoder.encode(token_name, "UTF-8") +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ }
+
+ return true;
+ }
+
+ public boolean KeyPanel() {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=8" +
+ "&keytype=" + key_type +
+ "&choice=default" +
+ "&custom_size=" + key_size +
+ "&sslserver_keytype=" + key_type +
+ "&sslserver_choice=custom" +
+ "&sslserver_custom_size=" + key_size +
+ "&subsystem_keytype=" + key_type +
+ "&subsystem_choice=custom" +
+ "&subsystem_custom_size=" + key_size +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean CertSubjectPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=9" +
+ "&sslserver=" +
+ URLEncoder.encode(ra_server_cert_subject_name, "UTF-8") +
+ "&sslserver_nick=" +
+ URLEncoder.encode(ra_server_cert_nickname, "UTF-8") +
+ "&subsystem=" +
+ URLEncoder.encode(ra_subsystem_cert_subject_name, "UTF-8") +
+ "&subsystem_nick=" +
+ URLEncoder.encode(ra_subsystem_cert_nickname, "UTF-8") +
+ "&urls=0" +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean CertificatePanel() {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=10" +
+ "&sslserver=" +
+ "&sslserver_cc=" +
+ "&subsystem=" +
+ "&subsystem_cc=" +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean AdminCertReqPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+ String admin_cert_request = null;
+
+ requestor_name = "RA-" + cs_hostname + "-" + cs_clientauth_port;
+
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir,
+ client_certdb_pwd,
+ agent_cert_subject,
+ agent_key_size,
+ agent_key_type);
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(true);
+ cCrypt.setTransportCert(null);
+ cCrypt.setDualKey(false);
+ cCrypt.loginDB();
+
+ String crmf_request = cCrypt.generateCRMFrequest();
+
+ if (crmf_request == null) {
+ System.out.println("ERROR: AdminCertReqPanel() cert req gen failed");
+ return false;
+ }
+
+ admin_cert_request = crmf_request;
+
+ String query_string = "p=11" +
+ "&uid=" + admin_user +
+ "&name=" +
+ URLEncoder.encode("RA Administrator", "UTF-8") +
+ "&email=" +
+ URLEncoder.encode(admin_email, "UTF-8") +
+ "&__pwd=" + URLEncoder.encode(admin_password, "UTF-8") +
+ "&__admin_password_again=" + URLEncoder.encode(admin_password, "UTF-8") +
+ "&cert_request=" +
+ URLEncoder.encode(admin_cert_request, "UTF-8") +
+ "&display=0" +
+ "&profileId=" + "caAdminCert" +
+ "&cert_request_type=" + "crmf" +
+ "&import=true" +
+ "&uid=" + admin_user +
+ "&clone=0" +
+ "&securitydomain=" +
+ URLEncoder.encode(domain_name, "UTF-8") +
+ "&subject=" +
+ URLEncoder.encode(agent_cert_subject, "UTF-8") +
+ "&requestor_name=" +
+ URLEncoder.encode(requestor_name, "UTF-8") +
+ "&sessionID=" + ra_session_id +
+ "&auth_hostname=" + ca_hostname +
+ "&auth_port=" + ca_ssl_port +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ admin_serial_number = px.getvalue("serialNumber");
+
+ return true;
+ }
+
+ public boolean AdminCertImportPanel() throws UnsupportedEncodingException {
+ boolean st = false;
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+ String cert_to_import = null;
+
+ String query_string = "serialNumber=" + admin_serial_number +
+ "&importCert=" + "true" +
+ "";
+
+ // NOTE: CA, DRM, OCSP, and TKS use the Security Domain Admin Port;
+ // whereas RA and TPS use the CA Admin Port associated with
+ // the 'CA choice panel' as invoked from the SubsystemPanel()
+ // which MAY or MAY NOT be the same CA as the CA specified
+ // by the Security Domain.
+ hr = hc.sslConnect(ca_hostname, ca_admin_port, admin_uri, query_string);
+
+ try {
+ // cert_to_import =
+ // new sun.misc.BASE64Encoder().encode(hr.getResponseData());
+ cert_to_import =
+ Utils.base64encode(hr.getResponseData());
+
+ } catch (Exception e) {
+ System.out.println("ERROR: failed to retrieve cert");
+ }
+
+ System.out.println("Imported Cert=" + cert_to_import);
+
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir,
+ client_certdb_pwd,
+ null,
+ null,
+ null);
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(true);
+ cCrypt.loginDB();
+
+ String start = "-----BEGIN CERTIFICATE-----\r\n";
+ String end = "\r\n-----END CERTIFICATE-----";
+
+ st = cCrypt.importCert(start + cert_to_import + end, agent_name);
+ if (!st) {
+ System.out.println("ERROR: AdminCertImportPanel() during cert import");
+ return false;
+ }
+
+ System.out.println("SUCCESS: imported admin user cert");
+
+ String query_string_1 = "p=12" +
+ "&serialNumber=" + admin_serial_number +
+ "&caHost=" +
+ URLEncoder.encode(ca_hostname, "UTF-8") +
+ "&caPort=" + ca_admin_port +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string_1);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean ConfigureRAInstance() throws UnsupportedEncodingException {
+ // 0. login to cert db
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir,
+ client_certdb_pwd,
+ null,
+ null,
+ null);
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(true);
+ cCrypt.loginDB();
+
+ // instantiate http client
+ hc = new HTTPClient();
+
+ sleep_time();
+ // 1. Login panel
+ boolean log_st = LoginPanel();
+ if (!log_st) {
+ System.out.println("ERROR: JSESSIONID not found.");
+ System.out.println("ERROR: ConfigureRA: LoginPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 2. domain panel
+ boolean dom_st = DomainPanel();
+ if (!dom_st) {
+ System.out.println("ERROR: ConfigureRA: DomainPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 3. display cert chain panel
+ boolean disp_st = DisplayChainPanel();
+ if (!disp_st) {
+ System.out.println("ERROR: ConfigureRA: DisplayChainPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // security domain login panel
+ boolean disp_sd = SecurityDomainLoginPanel();
+ if (!disp_sd) {
+ System.out.println("ERROR: ConfigureRA: SecurityDomainLoginPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 4. subsystem panel
+ boolean disp_ss = SubsystemPanel();
+ if (!disp_ss) {
+ System.out.println("ERROR: ConfigureRA: SubsystemPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 5. ldap connection panel
+ boolean disp_ldap = DBPanel();
+ if (!disp_ldap) {
+ System.out.println("ERROR: ConfigureRA: DBPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 6. Token Choice Panel
+ boolean disp_token = TokenChoicePanel();
+ if (!disp_token) {
+ System.out.println("ERROR: ConfigureRA: TokenChoicePanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 8. Key Panel
+ boolean disp_key = KeyPanel();
+ if (!disp_key) {
+ System.out.println("ERROR: ConfigureRA: KeyPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 9. Cert Subject Panel
+ boolean disp_csubj = CertSubjectPanel();
+ if (!disp_csubj) {
+ System.out.println("ERROR: ConfigureRA: CertSubjectPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 10. Certificate Panel
+ boolean disp_cp = CertificatePanel();
+ if (!disp_cp) {
+ System.out.println("ERROR: ConfigureRA: CertificatePanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 11. Admin Cert Req Panel
+ boolean disp_adm = AdminCertReqPanel();
+ if (!disp_adm) {
+ System.out.println("ERROR: ConfigureRA: AdminCertReqPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 12. Admin Cert import Panel
+ boolean disp_im = AdminCertImportPanel();
+ if (!disp_im) {
+ System.out.println("ERROR: ConfigureRA: AdminCertImportPanel() failure");
+ return false;
+ }
+
+ return true;
+ }
+
+ public static void main(String args[]) throws UnsupportedEncodingException {
+ ConfigureRA ca = new ConfigureRA();
+
+ // set variables
+ StringHolder x_cs_hostname = new StringHolder();
+ StringHolder x_cs_port = new StringHolder();
+ StringHolder x_cs_clientauth_port = new StringHolder();
+
+ StringHolder x_sd_hostname = new StringHolder();
+ StringHolder x_sd_ssl_port = new StringHolder();
+ StringHolder x_sd_agent_port = new StringHolder();
+ StringHolder x_sd_admin_port = new StringHolder();
+ StringHolder x_sd_admin_name = new StringHolder();
+ StringHolder x_sd_admin_password = new StringHolder();
+
+ StringHolder x_ca_hostname = new StringHolder();
+ StringHolder x_ca_port = new StringHolder();
+ StringHolder x_ca_ssl_port = new StringHolder();
+ StringHolder x_ca_admin_port = new StringHolder();
+
+ StringHolder x_client_certdb_dir = new StringHolder();
+ StringHolder x_client_certdb_pwd = new StringHolder();
+ StringHolder x_preop_pin = new StringHolder();
+
+ StringHolder x_domain_name = new StringHolder();
+
+ StringHolder x_admin_user = new StringHolder();
+ StringHolder x_admin_email = new StringHolder();
+ StringHolder x_admin_password = new StringHolder();
+
+ // key size
+ StringHolder x_token_name = new StringHolder();
+ StringHolder x_token_pwd = new StringHolder();
+ StringHolder x_key_size = new StringHolder();
+ StringHolder x_key_type = new StringHolder();
+
+ StringHolder x_agent_key_size = new StringHolder();
+ StringHolder x_agent_key_type = new StringHolder();
+ StringHolder x_agent_cert_subject = new StringHolder();
+
+ StringHolder x_agent_name = new StringHolder();
+
+ // ra cert subject name params
+ StringHolder x_ra_server_cert_subject_name = new StringHolder();
+ StringHolder x_ra_server_cert_nickname = new StringHolder();
+ StringHolder x_ra_subsystem_cert_subject_name = new StringHolder();
+ StringHolder x_ra_subsystem_cert_nickname = new StringHolder();
+
+ // subsystemName
+ StringHolder x_subsystem_name = new StringHolder();
+
+ // parse the args
+ ArgParser parser = new ArgParser("ConfigureRA");
+
+ parser.addOption("-cs_hostname %s #CS Hostname",
+ x_cs_hostname);
+ parser.addOption("-cs_port %s #CS SSL port",
+ x_cs_port);
+ parser.addOption("-cs_clientauth_port %s #CS SSL port",
+ x_cs_clientauth_port);
+
+ parser.addOption("-sd_hostname %s #Security Domain Hostname",
+ x_sd_hostname);
+ parser.addOption("-sd_ssl_port %s #Security Domain SSL EE port",
+ x_sd_ssl_port);
+ parser.addOption("-sd_agent_port %s #Security Domain SSL Agent port",
+ x_sd_agent_port);
+ parser.addOption("-sd_admin_port %s #Security Domain SSL Admin port",
+ x_sd_admin_port);
+ parser.addOption("-sd_admin_name %s #Security Domain username",
+ x_sd_admin_name);
+ parser.addOption("-sd_admin_password %s #Security Domain password",
+ x_sd_admin_password);
+
+ parser.addOption("-ca_hostname %s #CA Hostname",
+ x_ca_hostname);
+ parser.addOption("-ca_port %s #CA non-SSL port",
+ x_ca_port);
+ parser.addOption("-ca_ssl_port %s #CA SSL port",
+ x_ca_ssl_port);
+ parser.addOption("-ca_admin_port %s #CA SSL Admin port",
+ x_ca_admin_port);
+
+ parser.addOption("-client_certdb_dir %s #Client CertDB dir",
+ x_client_certdb_dir);
+ parser.addOption("-client_certdb_pwd %s #client certdb password",
+ x_client_certdb_pwd);
+ parser.addOption("-preop_pin %s #pre op pin",
+ x_preop_pin);
+ parser.addOption("-domain_name %s #domain name",
+ x_domain_name);
+ parser.addOption("-admin_user %s #Admin User Name",
+ x_admin_user);
+ parser.addOption("-admin_email %s #Admin email",
+ x_admin_email);
+ parser.addOption("-admin_password %s #Admin password",
+ x_admin_password);
+ parser.addOption("-agent_name %s #Agent Cert Nickname",
+ x_agent_name);
+
+ parser.addOption("-token_name %s #HSM/Software Token name",
+ x_token_name);
+ parser.addOption("-token_pwd %s #HSM/Software Token password",
+ x_token_pwd);
+ parser.addOption("-key_size %s #Key Size",
+ x_key_size);
+ parser.addOption("-key_type %s #Key type [rsa,ecc]",
+ x_key_type);
+
+ parser.addOption("-agent_key_size %s #Agent Cert Key Size",
+ x_agent_key_size);
+ parser.addOption("-agent_key_type %s #Agent cert Key type [rsa]",
+ x_agent_key_type);
+ parser.addOption("-agent_cert_subject %s #Agent cert Subject",
+ x_agent_cert_subject);
+
+ parser.addOption(
+ "-ra_server_cert_subject_name %s #RA server cert subject name",
+ x_ra_server_cert_subject_name);
+ parser.addOption(
+ "-ra_server_cert_nickname %s #RA server cert nickname",
+ x_ra_server_cert_nickname);
+ parser.addOption(
+ "-ra_subsystem_cert_subject_name %s #RA subsystem cert subject name",
+ x_ra_subsystem_cert_subject_name);
+ parser.addOption(
+ "-ra_subsystem_cert_nickname %s #RA subsystem cert nickname",
+ x_ra_subsystem_cert_nickname);
+
+ parser.addOption(
+ "-subsystem_name %s #RA subsystem name",
+ x_subsystem_name);
+
+ // and then match the arguments
+ String[] unmatched = null;
+ unmatched = parser.matchAllArgs(args, 0, ArgParser.EXIT_ON_UNMATCHED);
+
+ if (unmatched != null) {
+ System.out.println("ERROR: Argument Mismatch");
+ System.exit(-1);
+ }
+
+ // set variables
+ cs_hostname = x_cs_hostname.value;
+ cs_port = x_cs_port.value;
+ cs_clientauth_port = x_cs_clientauth_port.value;
+
+ sd_hostname = x_sd_hostname.value;
+ sd_ssl_port = x_sd_ssl_port.value;
+ sd_agent_port = x_sd_agent_port.value;
+ sd_admin_port = x_sd_admin_port.value;
+ sd_admin_name = x_sd_admin_name.value;
+ sd_admin_password = x_sd_admin_password.value;
+
+ ca_hostname = x_ca_hostname.value;
+ ca_port = x_ca_port.value;
+ ca_ssl_port = x_ca_ssl_port.value;
+ ca_admin_port = x_ca_admin_port.value;
+
+ client_certdb_dir = x_client_certdb_dir.value;
+ client_certdb_pwd = x_client_certdb_pwd.value;
+ pin = x_preop_pin.value;
+ domain_name = x_domain_name.value;
+
+ admin_user = x_admin_user.value;
+ admin_email = x_admin_email.value;
+ admin_password = x_admin_password.value;
+ agent_name = x_agent_name.value;
+
+ key_size = x_key_size.value;
+ key_type = x_key_type.value;
+ token_name = x_token_name.value;
+ token_pwd = x_token_pwd.value;
+
+ agent_key_size = x_agent_key_size.value;
+ agent_key_type = x_agent_key_type.value;
+ agent_cert_subject = x_agent_cert_subject.value;
+
+ ra_server_cert_subject_name =
+ x_ra_server_cert_subject_name.value;
+ ra_server_cert_nickname =
+ x_ra_server_cert_nickname.value;
+ ra_subsystem_cert_subject_name =
+ x_ra_subsystem_cert_subject_name.value;
+ ra_subsystem_cert_nickname =
+ x_ra_subsystem_cert_nickname.value;
+
+ subsystem_name = x_subsystem_name.value;
+
+ boolean st = ca.ConfigureRAInstance();
+
+ if (!st) {
+ System.out.println("ERROR: unable to create RA");
+ System.exit(-1);
+ }
+
+ System.out.println("Certificate System - RA Instance Configured");
+ System.exit(0);
+
+ }
+
+};
diff --git a/base/silent/src/com/netscape/pkisilent/ConfigureSubCA.java b/base/silent/src/com/netscape/pkisilent/ConfigureSubCA.java
new file mode 100644
index 000000000..706827c74
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/ConfigureSubCA.java
@@ -0,0 +1,1249 @@
+package com.netscape.pkisilent;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.ByteArrayInputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+
+import com.netscape.pkisilent.argparser.ArgParser;
+import com.netscape.pkisilent.argparser.StringHolder;
+import com.netscape.pkisilent.common.ComCrypto;
+import com.netscape.pkisilent.common.ParseXML;
+import com.netscape.pkisilent.http.HTTPClient;
+import com.netscape.pkisilent.http.HTTPResponse;
+import com.netscape.cmsutil.util.Utils;
+
+public class ConfigureSubCA {
+
+ // global constants
+ public static final String DEFAULT_KEY_TYPE = "RSA";
+ public static final String DEFAULT_KEY_SIZE = "2048";
+ public static final String DEFAULT_KEY_CURVENAME = "nistp256";
+ public static final String DEFAULT_KEY_ALGORITHM_RSA = "SHA256withRSA";
+ public static final String DEFAULT_KEY_ALGORITHM_ECC = "SHA256withEC";
+
+ // define global variables
+
+ public static HTTPClient hc = null;
+
+ public static String login_uri = "/ca/admin/console/config/login";
+ public static String wizard_uri = "/ca/admin/console/config/wizard";
+ public static String admin_uri = "/ca/admin/ca/getBySerial";
+
+ public static String sd_login_uri = "/ca/admin/ca/securityDomainLogin";
+ public static String sd_get_cookie_uri = "/ca/admin/ca/getCookie";
+ public static String pkcs12_uri = "/ca/admin/console/config/savepkcs12";
+
+ public static String cs_hostname = null;
+ public static String cs_port = null;
+
+ public static String sd_hostname = null;
+ public static String sd_ssl_port = null;
+ public static String sd_agent_port = null;
+ public static String sd_admin_port = null;
+ public static String sd_admin_name = null;
+ public static String sd_admin_password = null;
+
+ public static String ca_hostname = null;
+ public static String ca_port = null;
+ public static String ca_ssl_port = null;
+
+ public static String client_certdb_dir = null;
+ public static String client_certdb_pwd = null;
+
+ // Login Panel
+ public static String pin = null;
+
+ public static String domain_name = null;
+
+ public static String admin_user = null;
+ public static String admin_email = null;
+ public static String admin_password = null;
+ public static String admin_serial_number = null;
+ public static String agent_name = null;
+
+ public static String ldap_host = null;
+ public static String ldap_port = null;
+ public static String bind_dn = null;
+ public static String bind_password = null;
+ public static String base_dn = null;
+ public static String db_name = null;
+ public static String secure_conn = null;
+ public static String remove_data = null;
+
+ public static String key_type = null;
+ public static String key_size = null;
+ public static String key_curvename = null;
+ public static String key_algorithm = null;
+ public static String signing_algorithm = null;
+
+ public static String signing_key_type = null;
+ public static String signing_key_size = null;
+ public static String signing_key_curvename = null;
+ public static String signing_signingalgorithm = null;
+
+ public static String ocsp_signing_key_type = null;
+ public static String ocsp_signing_key_size = null;
+ public static String ocsp_signing_key_curvename = null;
+ public static String ocsp_signing_signingalgorithm = null;
+
+ public static String subsystem_key_type = null;
+ public static String subsystem_key_size = null;
+ public static String subsystem_key_curvename = null;
+
+ public static String audit_signing_key_type = null;
+ public static String audit_signing_key_size = null;
+ public static String audit_signing_key_curvename = null;
+
+ public static String sslserver_key_type = null;
+ public static String sslserver_key_size = null;
+ public static String sslserver_key_curvename = null;
+
+ public static String token_name = null;
+ public static String token_pwd = null;
+
+ public static String agent_key_size = null;
+ public static String agent_key_type = null;
+ public static String agent_cert_subject = null;
+
+ public static String ca_cert_name = null;
+ public static String ca_cert_req = null;
+ public static String ca_cert_pp = null;
+ public static String ca_cert_cert = null;
+
+ public static String ocsp_cert_name = null;
+ public static String ocsp_cert_req = null;
+ public static String ocsp_cert_pp = null;
+ public static String ocsp_cert_cert = null;
+
+ public static String server_cert_name = null;
+ public static String server_cert_req = null;
+ public static String server_cert_pp = null;
+ public static String server_cert_cert = null;
+
+ public static String ca_subsystem_cert_name = null;
+ public static String ca_subsystem_cert_req = null;
+ public static String ca_subsystem_cert_pp = null;
+ public static String ca_subsystem_cert_cert = null;
+
+ public static String ca_audit_signing_cert_name = null;
+ public static String ca_audit_signing_cert_req = null;
+ public static String ca_audit_signing_cert_pp = null;
+ public static String ca_audit_signing_cert_cert = null;
+
+ public static String backup_pwd = null;
+
+ public static String subsystem_name = null;
+
+ // names
+ public static String subca_sign_cert_subject_name = null;
+ public static String subca_subsystem_cert_subject_name = null;
+ public static String subca_ocsp_cert_subject_name = null;
+ public static String subca_server_cert_subject_name = null;
+ public static String subca_audit_signing_cert_subject_name = null;
+
+ public ConfigureSubCA() {
+ // do nothing :)
+ }
+
+ public void sleep_time() {
+ try {
+ System.out.println("Sleeping for 5 secs..");
+ Thread.sleep(5000);
+ } catch (Exception e) {
+ System.out.println("ERROR: sleep problem");
+ }
+
+ }
+
+ public boolean LoginPanel() {
+ boolean st = false;
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "pin=" + pin + "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, login_uri, query_string);
+ System.out.println("xml returned: " + hr.getHTML());
+
+ // parse xml here - nothing to parse
+
+ // get cookie
+ String temp = hr.getCookieValue("JSESSIONID");
+
+ if (temp != null) {
+ int index = temp.indexOf(";");
+ HTTPClient.j_session_id = temp.substring(0, index);
+ st = true;
+ }
+
+ hr = null;
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri,
+ "p=0&op=next&xml=true");
+
+ // parse xml here
+
+ bais = new ByteArrayInputStream(
+ hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return st;
+ }
+
+ public boolean TokenChoicePanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ ///////////////////////////////////////////////////////
+ String query_string = null;
+
+ // Software Token
+ if (token_name.equalsIgnoreCase("internal")) {
+ query_string = "p=1" + "&op=next" + "&xml=true" +
+ "&choice=" +
+ URLEncoder.encode("Internal Key Storage Token", "UTF-8") +
+ "";
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+ }
+ // HSM
+ else {
+ // login to hsm first
+ query_string = "p=2" + "&op=next" + "&xml=true" +
+ "&uTokName=" +
+ URLEncoder.encode(token_name, "UTF-8") +
+ "&__uPasswd=" +
+ URLEncoder.encode(token_pwd, "UTF-8") +
+ "";
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ // choice with token name now
+ query_string = "p=1" + "&op=next" + "&xml=true" +
+ "&choice=" +
+ URLEncoder.encode(token_name, "UTF-8") +
+ "";
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ }
+
+ return true;
+ }
+
+ public boolean DomainPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String domain_url = "https://" + sd_hostname + ":" + sd_admin_port;
+
+ String query_string = "sdomainURL=" +
+ URLEncoder.encode(domain_url, "UTF-8") +
+ "&sdomainName=" +
+ URLEncoder.encode(domain_name, "UTF-8") +
+ "&choice=existingdomain" +
+ "&p=3" +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ String query_string_1 = "p=4" +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string_1);
+
+ return true;
+
+ }
+
+ public boolean SecurityDomainLoginPanel() throws UnsupportedEncodingException {
+ String subca_url = "https://" + cs_hostname + ":" + cs_port +
+ "/ca/admin/console/config/wizard" +
+ "?p=5&subsystem=CA";
+
+ String query_string = "url=" + URLEncoder.encode(subca_url, "UTF-8");
+
+ HTTPResponse hr = hc.sslConnect(sd_hostname, sd_admin_port, sd_login_uri, query_string);
+
+ String query_string_1 = "uid=" + sd_admin_name +
+ "&pwd=" + URLEncoder.encode(sd_admin_password, "UTF-8") +
+ "&url=" + URLEncoder.encode(subca_url, "UTF-8");
+
+ hr = hc.sslConnect(sd_hostname, sd_admin_port, sd_get_cookie_uri,
+ query_string_1);
+
+ // get session id from security domain
+
+ String subca_session_id = hr.getContentValue("header.session_id");
+ String subca_url_1 = hr.getContentValue("header.url");
+
+ System.out.println("SUBCA_SESSION_ID=" + subca_session_id);
+ System.out.println("SUBCA_URL=" + subca_url_1);
+
+ // use session id to connect back to subCA
+
+ String query_string_2 = "p=5" +
+ "&subsystem=CA" +
+ "&session_id=" + subca_session_id +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri,
+ query_string_2);
+
+ return true;
+
+ }
+
+ public boolean DisplayChainPanel() throws UnsupportedEncodingException {
+ String query_string = "p=5" + "&op=next" + "&xml=true" +
+ "&choice=newsubsystem" +
+ "&subsystemName=" +
+ URLEncoder.encode(subsystem_name, "UTF-8") +
+ "&subsystemName=" +
+ URLEncoder.encode(subsystem_name, "UTF-8") +
+ "&urls=0";
+ hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ // bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ // px.parse(bais);
+ // px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean HierarchyPanel() {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=8" + "&op=next" + "&xml=true" +
+ "&choice=join";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+
+ }
+
+ public boolean LdapConnectionPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=9" + "&op=next" + "&xml=true" +
+ "&host=" + URLEncoder.encode(ldap_host, "UTF-8") +
+ "&port=" + URLEncoder.encode(ldap_port, "UTF-8") +
+ "&basedn=" + URLEncoder.encode(base_dn, "UTF-8") +
+ "&database=" + URLEncoder.encode(db_name, "UTF-8") +
+ "&binddn=" + URLEncoder.encode(bind_dn, "UTF-8") +
+ "&__bindpwd=" + URLEncoder.encode(bind_password, "UTF-8") +
+ "&display=" + URLEncoder.encode("$displayStr", "UTF-8") +
+ (secure_conn.equals("true") ? "&secureConn=on" : "") +
+ (remove_data.equals("true") ? "&removeData=true" : "");
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean KeyPanel() {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+ ArrayList<String> al = null;
+
+ String query_string = "p=10" + "&op=next" + "&xml=true"
+ + "&subsystem_custom_size=" + subsystem_key_size
+ + "&subsystem_custom_curvename=" + subsystem_key_curvename
+ + "&subsystem_keytype=" + subsystem_key_type
+ + "&subsystem_choice=custom"
+ + "&sslserver_custom_size=" + sslserver_key_size
+ + "&sslserver_custom_curvename=" + sslserver_key_curvename
+ + "&sslserver_keytype=" + sslserver_key_type
+ + "&sslserver_choice=custom"
+ + "&signing_custom_size=" + signing_key_size
+ + "&signing_custom_curvename=" + signing_key_curvename
+ + "&signing_keytype=" + signing_key_type
+ + "&signing_choice=custom"
+ + "&signing_keyalgorithm=" + key_algorithm
+ + "&signing_signingalgorithm=" + signing_signingalgorithm
+ + "&ocsp_signing_custom_size=" + ocsp_signing_key_size
+ + "&ocsp_signing_custom_curvename=" + ocsp_signing_key_curvename
+ + "&ocsp_signing_keytype=" + ocsp_signing_key_type
+ + "&ocsp_signing_choice=custom"
+ + "&ocsp_signing_signingalgorithm=" + ocsp_signing_signingalgorithm
+ + "&audit_signing_custom_size=" + audit_signing_key_size
+ + "&audit_signing_custom_curvename=" + audit_signing_key_curvename
+ + "&audit_signing_keytype=" + audit_signing_key_type
+ + "&audit_signing_choice=custom"
+ + "&custom_size=" + key_size
+ + "&custom_curvename=" + key_curvename
+ + "&keytype=" + key_type
+ + "&choice=custom"
+ + "&signingalgorithm=" + signing_algorithm
+ + "&keyalgorithm=" + key_algorithm;
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ al = px.constructValueList("CertReqPair", "DN");
+ // get ca cert subject name
+ if (al != null) {
+ for (int i = 0; i < al.size(); i++) {
+ String temp = al.get(i);
+ if (temp.indexOf("Certificate Authority") > 0) {
+ ca_cert_name = temp;
+ } else if (temp.indexOf("OCSP Signing Certificate") > 0) {
+ ocsp_cert_name = temp;
+ } else if (temp.indexOf("Subsystem Certificate") > 0) {
+ ca_subsystem_cert_name = temp;
+ } else if (temp.indexOf("Audit Signing Certificate") > 0) {
+ ca_audit_signing_cert_name = temp;
+ } else {
+ server_cert_name = temp;
+ }
+ }
+ }
+
+ System.out.println("default: ca_cert_name=" + ca_cert_name);
+ System.out.println("default: ocsp_cert_name=" + ocsp_cert_name);
+ System.out.println("default: ca_subsystem_cert_name=" +
+ ca_subsystem_cert_name);
+ System.out.println("default: server_cert_name=" + server_cert_name);
+ System.out.println("default: ca_audit_signing_cert_name=" +
+ ca_audit_signing_cert_name);
+ return true;
+ }
+
+ public boolean CertSubjectPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+ ArrayList<String> req_list = null;
+ ArrayList<String> cert_list = null;
+ ArrayList<String> dn_list = null;
+
+ String query_string = "p=11" + "&op=next" + "&xml=true" +
+ "&signing=" +
+ URLEncoder.encode(subca_sign_cert_subject_name, "UTF-8") +
+ "&ocsp_signing=" +
+ URLEncoder.encode(subca_ocsp_cert_subject_name, "UTF-8") +
+ "&sslserver=" +
+ URLEncoder.encode(subca_server_cert_subject_name, "UTF-8") +
+ "&subsystem=" +
+ URLEncoder.encode(subca_subsystem_cert_subject_name, "UTF-8") +
+ "&audit_signing=" +
+ URLEncoder.encode(subca_audit_signing_cert_subject_name, "UTF-8") +
+ "&urls=0" +
+ "";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ req_list = px.constructValueList("CertReqPair", "Request");
+ cert_list = px.constructValueList("CertReqPair", "Certificate");
+ dn_list = px.constructValueList("CertReqPair", "Nickname");
+
+ System.out.println("req_list_size=" + req_list.size());
+ System.out.println("cert_list_size=" + cert_list.size());
+ System.out.println("dn_list_size=" + dn_list.size());
+
+ if (req_list != null && cert_list != null && dn_list != null) {
+ for (int i = 0; i < dn_list.size(); i++) {
+ String temp = dn_list.get(i);
+
+ if (temp.indexOf("caSigningCert") >= 0) {
+ ca_cert_req = req_list.get(i);
+ ca_cert_cert = cert_list.get(i);
+ } else if (temp.indexOf("ocspSigningCert") >= 0) {
+ ocsp_cert_req = req_list.get(i);
+ ocsp_cert_cert = cert_list.get(i);
+ } else if (temp.indexOf("subsystemCert") >= 0) {
+ ca_subsystem_cert_req = req_list.get(i);
+ ca_subsystem_cert_cert = cert_list.get(i);
+ } else if (temp.indexOf("auditSigningCert") >= 0) {
+ ca_audit_signing_cert_req = req_list.get(i);
+ ca_audit_signing_cert_cert = cert_list.get(i);
+ } else {
+ server_cert_req = req_list.get(i);
+ server_cert_cert = cert_list.get(i);
+ }
+ }
+ }
+
+ System.out.println("ca_cert_name=" + subca_sign_cert_subject_name);
+ System.out.println("ocsp_cert_name=" + subca_ocsp_cert_subject_name);
+ System.out.println("ca_subsystem_cert_name=" +
+ subca_subsystem_cert_subject_name);
+ System.out.println("server_cert_name=" +
+ subca_server_cert_subject_name);
+ System.out.println("audit_signing_cert_name=" +
+ subca_audit_signing_cert_subject_name);
+
+ System.out.println("ca_cert_req=" + ca_cert_req);
+ System.out.println("ocsp_cert_req=" + ocsp_cert_req);
+ System.out.println("ca_subsystem_cert_req=" + ca_subsystem_cert_req);
+ System.out.println("server_cert_req=" + server_cert_req);
+ System.out.println("ca_audit_siging_cert_req=" +
+ ca_audit_signing_cert_req);
+
+ System.out.println("ca_cert_cert=" + ca_cert_cert);
+ System.out.println("ocsp_cert_cert=" + ocsp_cert_cert);
+ System.out.println("ca_subsystem_cert_cert=" + ca_subsystem_cert_cert);
+ System.out.println("server_cert_cert=" + server_cert_cert);
+ System.out.println("ca_audit_signing_cert_cert=" +
+ ca_audit_signing_cert_cert);
+
+ return true;
+ }
+
+ public boolean CertificatePanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=12" + "&op=next" + "&xml=true" +
+ "&signing=" +
+ URLEncoder.encode(ca_cert_cert, "UTF-8") +
+ "&signing_cc=" +
+ "&ocsp_signing=" +
+ URLEncoder.encode(ocsp_cert_cert, "UTF-8") +
+ "&ocsp_signing_cc=" +
+ "&sslserver=" +
+ URLEncoder.encode(server_cert_cert, "UTF-8") +
+ "&sslserver_cc=" +
+ "&subsystem=" +
+ URLEncoder.encode(ca_subsystem_cert_cert, "UTF-8") +
+ "&subsystem_cc=" +
+ "&audit_signing=" +
+ URLEncoder.encode(ca_audit_signing_cert_cert, "UTF-8") +
+ "&audit_signing_cc=" +
+ "";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean BackupPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=13" + "&op=next" + "&xml=true" +
+ "&choice=backupkey" +
+ "&__pwd=" + URLEncoder.encode(backup_pwd, "UTF-8") +
+ "&__pwdagain=" + URLEncoder.encode(backup_pwd, "UTF-8");
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean ImportCACertPanel() {
+ try {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri,
+ "p=15&op=next&xml=true");
+
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ } catch (Exception e) {
+ System.out.println("Exception in ImportCACertPanel(): " + e.toString());
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public boolean AdminCertReqPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+ String admin_cert_request = null;
+
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir,
+ client_certdb_pwd,
+ agent_cert_subject,
+ agent_key_size,
+ agent_key_type);
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(true);
+ cCrypt.setTransportCert(null);
+ cCrypt.setDualKey(false);
+ cCrypt.loginDB();
+
+ String crmf_request = cCrypt.generateCRMFrequest();
+
+ if (crmf_request == null) {
+ System.out.println("ERROR: AdminCertReqPanel() cert req gen failed");
+ return false;
+ }
+
+ admin_cert_request = crmf_request;
+
+ String query_string = "p=16" + "&op=next" + "&xml=true" +
+ "&uid=" + admin_user +
+ "&name=" + URLEncoder.encode(agent_name, "UTF-8") +
+ "&email=" +
+ URLEncoder.encode(admin_email, "UTF-8") +
+ "&__pwd=" + URLEncoder.encode(admin_password, "UTF-8") +
+ "&__admin_password_again=" + URLEncoder.encode(admin_password, "UTF-8") +
+ "&cert_request=" +
+ URLEncoder.encode(admin_cert_request, "UTF-8") +
+ "&display=" + URLEncoder.encode("$displayStr", "UTF-8") +
+ "&profileId=" + "caAdminCert" +
+ "&cert_request_type=" + "crmf" +
+ "&import=true" +
+ "&uid=" + admin_user +
+ "&securitydomain=" +
+ URLEncoder.encode(domain_name, "UTF-8") +
+ "&subject=" +
+ URLEncoder.encode(agent_cert_subject, "UTF-8") +
+ "";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ admin_serial_number = px.getvalue("serialNumber");
+
+ return true;
+ }
+
+ public boolean AdminCertImportPanel() {
+ boolean st = false;
+
+ String query_string = "serialNumber=" + admin_serial_number +
+ "&importCert=" + "true" +
+ "";
+
+ HTTPResponse hr = hc.sslConnect(cs_hostname, cs_port, admin_uri, query_string);
+
+ // get response data
+ // String cert_to_import =
+ // new sun.misc.BASE64Encoder().encode(hr.getResponseData());
+ String cert_to_import =
+ Utils.base64encode(hr.getResponseData());
+ System.out.println("Imported Cert=" + cert_to_import);
+
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir,
+ client_certdb_pwd,
+ null,
+ null,
+ null);
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(true);
+ cCrypt.loginDB();
+
+ String start = "-----BEGIN CERTIFICATE-----\r\n";
+ String end = "\r\n-----END CERTIFICATE-----";
+
+ st = cCrypt.importCert(start + cert_to_import + end, agent_name);
+ if (!st) {
+ System.out.println("ERROR: AdminCertImportPanel() during cert import");
+ return false;
+ }
+
+ System.out.println("SUCCESS: imported admin user cert: " + agent_name);
+
+ return true;
+ }
+
+ public boolean UpdateDomainPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=17" +
+ "&serialNumber=" + admin_serial_number +
+ "&caHost=" + URLEncoder.encode(sd_hostname, "UTF-8") +
+ "&caPort=" + URLEncoder.encode(sd_admin_port, "UTF-8") +
+ "&importCert=" + "true" +
+ "&op=next" + "&xml=true" +
+ "";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ String caHost = px.getvalue("host");
+ String caPort = px.getvalue("port");
+ String systemType = px.getvalue("systemType");
+
+ System.out.println("caHost=" + caHost);
+ System.out.println("caPort=" + caPort);
+ System.out.println("systemType=" + systemType);
+
+ return true;
+ }
+
+ public boolean ConfigureSubCAInstance() throws UnsupportedEncodingException {
+ // 0. login to cert db
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir,
+ client_certdb_pwd,
+ null,
+ null,
+ null);
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(true);
+ cCrypt.loginDB();
+
+ // instantiate http client
+ hc = new HTTPClient();
+
+ sleep_time();
+ // 0. Login panel
+ boolean log_st = LoginPanel();
+ if (!log_st) {
+ System.out.println("ERROR: ConfigureSubCA: LoginPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 1. Token Choice Panel
+ boolean disp_token = TokenChoicePanel();
+ if (!disp_token) {
+ System.out.println("ERROR: ConfigureSubCA: TokenChoicePanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 2. domain panel
+ boolean dom_st = DomainPanel();
+ if (!dom_st) {
+ System.out.println("ERROR: ConfigureSubCA: DomainPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 3. domain panel
+ boolean sd_st = SecurityDomainLoginPanel();
+ if (!sd_st) {
+ System.out.println("ERROR: ConfigureSubCA: SecurityDomainLoginPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 4. display cert chain panel
+ boolean disp_st = DisplayChainPanel();
+ if (!disp_st) {
+ System.out.println("ERROR: ConfigureSubCA: DisplayChainPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 6. hierarchy panel
+ boolean disp_h = HierarchyPanel();
+ if (!disp_h) {
+ System.out.println("ERROR: ConfigureSubCA: HierarchyPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 7. ldap connection panel
+ boolean disp_ldap = LdapConnectionPanel();
+ if (!disp_ldap) {
+ System.out.println("ERROR: ConfigureSubCA: LdapConnectionPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ sleep_time();
+ // 10. Key Panel
+ boolean disp_key = KeyPanel();
+ if (!disp_key) {
+ System.out.println("ERROR: ConfigureSubCA: KeyPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 11. Cert Subject Panel
+ boolean disp_csubj = CertSubjectPanel();
+ if (!disp_csubj) {
+ System.out.println("ERROR: ConfigureSubCA: CertSubjectPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 12. Certificate Panel
+ boolean disp_cp = CertificatePanel();
+ if (!disp_cp) {
+ System.out.println("ERROR: ConfigureSubCA: CertificatePanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 13. Backup Panel
+ boolean disp_back = BackupPanel();
+ if (!disp_back) {
+ System.out.println("ERROR: ConfigureSubCA: BackupPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 15. Import CA Certificate Panel
+ boolean disp_cert = ImportCACertPanel();
+ if (!disp_cert) {
+ System.out.println("ERROR: ConfigureSubCA: ImportCACertPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 16. Admin Cert Req Panel
+ boolean disp_adm = AdminCertReqPanel();
+ if (!disp_adm) {
+ System.out.println("ERROR: ConfigureSubCA: AdminCertReqPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ boolean disp_im = AdminCertImportPanel();
+ if (!disp_im) {
+ System.out.println("ERROR: ConfigureSubCA: AdminCertImportPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 17. Update Domain Panel
+ boolean disp_ud = UpdateDomainPanel();
+ if (!disp_ud) {
+ System.out.println("ERROR: ConfigureSubCA: UpdateDomainPanel() failure");
+ return false;
+ }
+
+ return true;
+ }
+
+ private static String set_default(String val, String def) {
+ if ((val == null) || (val.equals(""))) {
+ return def;
+ } else {
+ return val;
+ }
+ }
+
+ public static void main(String args[]) throws UnsupportedEncodingException {
+ ConfigureSubCA ca = new ConfigureSubCA();
+
+ // set variables
+ StringHolder x_cs_hostname = new StringHolder();
+ StringHolder x_cs_port = new StringHolder();
+
+ StringHolder x_sd_hostname = new StringHolder();
+ StringHolder x_sd_ssl_port = new StringHolder();
+ StringHolder x_sd_agent_port = new StringHolder();
+ StringHolder x_sd_admin_port = new StringHolder();
+ StringHolder x_sd_admin_name = new StringHolder();
+ StringHolder x_sd_admin_password = new StringHolder();
+
+ StringHolder x_ca_hostname = new StringHolder();
+ StringHolder x_ca_port = new StringHolder();
+ StringHolder x_ca_ssl_port = new StringHolder();
+
+ StringHolder x_client_certdb_dir = new StringHolder();
+ StringHolder x_client_certdb_pwd = new StringHolder();
+ StringHolder x_preop_pin = new StringHolder();
+
+ StringHolder x_domain_name = new StringHolder();
+
+ StringHolder x_admin_user = new StringHolder();
+ StringHolder x_admin_email = new StringHolder();
+ StringHolder x_admin_password = new StringHolder();
+
+ // ldap
+ StringHolder x_ldap_host = new StringHolder();
+ StringHolder x_ldap_port = new StringHolder();
+ StringHolder x_bind_dn = new StringHolder();
+ StringHolder x_bind_password = new StringHolder();
+ StringHolder x_base_dn = new StringHolder();
+ StringHolder x_db_name = new StringHolder();
+ StringHolder x_secure_conn = new StringHolder();
+ StringHolder x_remove_data = new StringHolder();
+
+ // key properties (defaults)
+ StringHolder x_key_size = new StringHolder();
+ StringHolder x_key_type = new StringHolder();
+ StringHolder x_key_curvename = new StringHolder();
+ StringHolder x_key_algorithm = new StringHolder();
+ StringHolder x_signing_algorithm = new StringHolder();
+
+ // key properties (custom - signing)
+ StringHolder x_signing_key_size = new StringHolder();
+ StringHolder x_signing_key_type = new StringHolder();
+ StringHolder x_signing_key_curvename = new StringHolder();
+ StringHolder x_signing_signingalgorithm = new StringHolder();
+
+ // key properties (custom - ocsp_signing)
+ StringHolder x_ocsp_signing_key_size = new StringHolder();
+ StringHolder x_ocsp_signing_key_type = new StringHolder();
+ StringHolder x_ocsp_signing_key_curvename = new StringHolder();
+ StringHolder x_ocsp_signing_signingalgorithm = new StringHolder();
+
+ // key properties (custom - audit_signing)
+ StringHolder x_audit_signing_key_size = new StringHolder();
+ StringHolder x_audit_signing_key_type = new StringHolder();
+ StringHolder x_audit_signing_key_curvename = new StringHolder();
+
+ // key properties (custom - subsystem)
+ StringHolder x_subsystem_key_size = new StringHolder();
+ StringHolder x_subsystem_key_type = new StringHolder();
+ StringHolder x_subsystem_key_curvename = new StringHolder();
+
+ // key properties (custom - sslserver)
+ StringHolder x_sslserver_key_size = new StringHolder();
+ StringHolder x_sslserver_key_type = new StringHolder();
+ StringHolder x_sslserver_key_curvename = new StringHolder();
+
+ StringHolder x_token_name = new StringHolder();
+ StringHolder x_token_pwd = new StringHolder();
+
+ StringHolder x_agent_key_size = new StringHolder();
+ StringHolder x_agent_key_type = new StringHolder();
+ StringHolder x_agent_cert_subject = new StringHolder();
+
+ StringHolder x_agent_name = new StringHolder();
+ StringHolder x_backup_pwd = new StringHolder();
+
+ // subsystem name
+ StringHolder x_subsystem_name = new StringHolder();
+
+ // subject names
+ StringHolder x_subca_sign_cert_subject_name = new StringHolder();
+ StringHolder x_subca_subsystem_cert_subject_name = new StringHolder();
+ StringHolder x_subca_ocsp_cert_subject_name = new StringHolder();
+ StringHolder x_subca_server_cert_subject_name = new StringHolder();
+ StringHolder x_subca_audit_signing_cert_subject_name = new StringHolder();
+
+ // parse the args
+ ArgParser parser = new ArgParser("ConfigureSubCA");
+
+ parser.addOption("-cs_hostname %s #CS Hostname",
+ x_cs_hostname);
+ parser.addOption("-cs_port %s #CS SSL port",
+ x_cs_port);
+
+ parser.addOption("-sd_hostname %s #Security Domain Hostname",
+ x_sd_hostname);
+ parser.addOption("-sd_ssl_port %s #Security Domain SSL EE port",
+ x_sd_ssl_port);
+ parser.addOption("-sd_agent_port %s #Security Domain SSL Agent port",
+ x_sd_agent_port);
+ parser.addOption("-sd_admin_port %s #Security Domain SSL Admin port",
+ x_sd_admin_port);
+ parser.addOption("-sd_admin_name %s #Security Domain admin name",
+ x_sd_admin_name);
+ parser.addOption("-sd_admin_password %s #Security Domain admin password",
+ x_sd_admin_password);
+
+ parser.addOption("-ca_hostname %s #CA Hostname",
+ x_ca_hostname);
+ parser.addOption("-ca_port %s #CA non-SSL port",
+ x_ca_port);
+ parser.addOption("-ca_ssl_port %s #CA SSL port",
+ x_ca_ssl_port);
+
+ parser.addOption("-client_certdb_dir %s #Client CertDB dir",
+ x_client_certdb_dir);
+ parser.addOption("-client_certdb_pwd %s #client certdb password",
+ x_client_certdb_pwd);
+ parser.addOption("-preop_pin %s #pre op pin",
+ x_preop_pin);
+ parser.addOption("-domain_name %s #domain name",
+ x_domain_name);
+ parser.addOption("-admin_user %s #Admin User Name",
+ x_admin_user);
+ parser.addOption("-admin_email %s #Admin email",
+ x_admin_email);
+ parser.addOption("-admin_password %s #Admin password",
+ x_admin_password);
+ parser.addOption("-agent_name %s #Agent Cert Nickname",
+ x_agent_name);
+
+ parser.addOption("-ldap_host %s #ldap host",
+ x_ldap_host);
+ parser.addOption("-ldap_port %s #ldap port",
+ x_ldap_port);
+ parser.addOption("-bind_dn %s #ldap bind dn",
+ x_bind_dn);
+ parser.addOption("-bind_password %s #ldap bind password",
+ x_bind_password);
+ parser.addOption("-base_dn %s #base dn",
+ x_base_dn);
+ parser.addOption("-db_name %s #db name",
+ x_db_name);
+ parser.addOption("-secure_conn %s #use ldaps port (optional, default is false)", x_secure_conn);
+ parser.addOption("-remove_data %s #remove existing data under base_dn (optional, default is false) ",
+ x_remove_data);
+
+ // key and algorithm options (default)
+ parser.addOption("-key_type %s #Key type [RSA,ECC] (optional, default is RSA)", x_key_type);
+ parser.addOption("-key_size %s #Key Size (optional, for RSA default is 2048)", x_key_size);
+ parser.addOption("-key_curvename %s #Key Curve Name (optional, for ECC default is nistp256)", x_key_curvename);
+ parser.addOption(
+ "-key_algorithm %s #Key algorithm of the CA certificate (optional, default is SHA256withRSA for RSA and SHA256withEC for ECC)",
+ x_key_algorithm);
+ parser.addOption("-signing_algorithm %s #Signing algorithm (optional, default is key_algorithm)",
+ x_signing_algorithm);
+
+ // key and algorithm options for signing certificate (overrides default)
+ parser.addOption("-signing_key_type %s #Key type [RSA,ECC] (optional, default is key_type)", x_signing_key_type);
+ parser.addOption("-signing_key_size %s #Key Size (optional, for RSA default is key_size)", x_signing_key_size);
+ parser.addOption("-signing_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_signing_key_curvename);
+ parser.addOption(
+ "-signing_signingalgorithm %s #Algorithm used be CA cert to sign objects (optional, default is signing_algorithm)",
+ x_signing_signingalgorithm);
+
+ // key and algorithm options for ocsp_signing certificate (overrides default)
+ parser.addOption("-ocsp_signing_key_type %s #Key type [RSA,ECC] (optional, default is key_type)",
+ x_ocsp_signing_key_type);
+ parser.addOption("-ocsp_signing_key_size %s #Key Size (optional, for RSA default is key_size)",
+ x_ocsp_signing_key_size);
+ parser.addOption("-ocsp_signing_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_ocsp_signing_key_curvename);
+ parser.addOption(
+ "-ocsp_signing_signingalgorithm %s #Algorithm used by the OCSP signing cert to sign objects (optional, default is signing_algorithm)",
+ x_ocsp_signing_signingalgorithm);
+
+ // key and algorithm options for audit_signing certificate (overrides default)
+ parser.addOption("-audit_signing_key_type %s #Key type [RSA,ECC] (optional, default is key_type)",
+ x_audit_signing_key_type);
+ parser.addOption("-audit_signing_key_size %s #Key Size (optional, for RSA default is key_size)",
+ x_audit_signing_key_size);
+ parser.addOption(
+ "-audit_signing_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_audit_signing_key_curvename);
+
+ // key and algorithm options for subsystem certificate (overrides default)
+ parser.addOption("-subsystem_key_type %s #Key type [RSA,ECC] (optional, default is key_type)",
+ x_subsystem_key_type);
+ parser.addOption("-subsystem_key_size %s #Key Size (optional, for RSA default is key_size)",
+ x_subsystem_key_size);
+ parser.addOption("-subsystem_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_subsystem_key_curvename);
+
+ // key and algorithm options for sslserver certificate (overrides default)
+ parser.addOption("-sslserver_key_type %s #Key type [RSA,ECC] (optional, default is key_type)",
+ x_sslserver_key_type);
+ parser.addOption("-sslserver_key_size %s #Key Size (optional, for RSA default is key_size)",
+ x_sslserver_key_size);
+ parser.addOption("-sslserver_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_sslserver_key_curvename);
+
+ parser.addOption("-token_name %s #HSM/Software Token name",
+ x_token_name);
+ parser.addOption("-token_pwd %s #HSM/Software Token password (optional - required for HSM)",
+ x_token_pwd);
+
+ parser.addOption("-agent_key_size %s #Agent Cert Key Size",
+ x_agent_key_size);
+ parser.addOption("-agent_key_type %s #Agent Cert Key type [rsa]",
+ x_agent_key_type);
+ parser.addOption("-agent_cert_subject %s #Agent Cert Subject",
+ x_agent_cert_subject);
+
+ parser.addOption("-backup_pwd %s #PKCS12 backup password",
+ x_backup_pwd);
+
+ parser.addOption("-subsystem_name %s #Subsystem name",
+ x_subsystem_name);
+
+ parser.addOption(
+ "-subca_sign_cert_subject_name %s #subCA cert subject name",
+ x_subca_sign_cert_subject_name);
+ parser.addOption(
+ "-subca_subsystem_cert_subject_name %s #subCA subsystem cert subject name",
+ x_subca_subsystem_cert_subject_name);
+ parser.addOption(
+ "-subca_ocsp_cert_subject_name %s #subCA ocsp cert subject name",
+ x_subca_ocsp_cert_subject_name);
+ parser.addOption(
+ "-subca_server_cert_subject_name %s #subCA server cert subject name",
+ x_subca_server_cert_subject_name);
+ parser.addOption(
+ "-subca_audit_signing_cert_subject_name %s #CA audit signing cert subject name",
+ x_subca_audit_signing_cert_subject_name);
+
+ // and then match the arguments
+ String[] unmatched = null;
+ unmatched = parser.matchAllArgs(args, 0, ArgParser.EXIT_ON_UNMATCHED);
+
+ if (unmatched != null) {
+ System.out.println("ERROR: Argument Mismatch");
+ System.exit(-1);
+ }
+
+ parser.checkRequiredArgs();
+
+ // set variables
+ cs_hostname = x_cs_hostname.value;
+ cs_port = x_cs_port.value;
+
+ sd_hostname = x_sd_hostname.value;
+ sd_ssl_port = x_sd_ssl_port.value;
+ sd_agent_port = x_sd_agent_port.value;
+ sd_admin_port = x_sd_admin_port.value;
+ sd_admin_name = x_sd_admin_name.value;
+ sd_admin_password = x_sd_admin_password.value;
+
+ ca_hostname = x_ca_hostname.value;
+ ca_port = x_ca_port.value;
+ ca_ssl_port = x_ca_ssl_port.value;
+
+ client_certdb_dir = x_client_certdb_dir.value;
+ client_certdb_pwd = x_client_certdb_pwd.value;
+ pin = x_preop_pin.value;
+ domain_name = x_domain_name.value;
+ admin_user = x_admin_user.value;
+ admin_email = x_admin_email.value;
+ admin_password = x_admin_password.value;
+ agent_name = x_agent_name.value;
+
+ ldap_host = x_ldap_host.value;
+ ldap_port = x_ldap_port.value;
+ bind_dn = x_bind_dn.value;
+ bind_password = x_bind_password.value;
+ base_dn = x_base_dn.value;
+ db_name = x_db_name.value;
+ secure_conn = set_default(x_secure_conn.value, "false");
+ remove_data = set_default(x_remove_data.value, "false");
+
+ key_type = set_default(x_key_type.value, DEFAULT_KEY_TYPE);
+ signing_key_type = set_default(x_signing_key_type.value, key_type);
+ ocsp_signing_key_type = set_default(x_ocsp_signing_key_type.value, key_type);
+ audit_signing_key_type = set_default(x_audit_signing_key_type.value, key_type);
+ subsystem_key_type = set_default(x_subsystem_key_type.value, key_type);
+ sslserver_key_type = set_default(x_sslserver_key_type.value, key_type);
+
+ key_size = set_default(x_key_size.value, DEFAULT_KEY_SIZE);
+ signing_key_size = set_default(x_signing_key_size.value, key_size);
+ ocsp_signing_key_size = set_default(x_ocsp_signing_key_size.value, key_size);
+ audit_signing_key_size = set_default(x_audit_signing_key_size.value, key_size);
+ subsystem_key_size = set_default(x_subsystem_key_size.value, key_size);
+ sslserver_key_size = set_default(x_sslserver_key_size.value, key_size);
+
+ key_curvename = set_default(x_key_curvename.value, DEFAULT_KEY_CURVENAME);
+ signing_key_curvename = set_default(x_signing_key_curvename.value, key_curvename);
+ ocsp_signing_key_curvename = set_default(x_ocsp_signing_key_curvename.value, key_curvename);
+ audit_signing_key_curvename = set_default(x_audit_signing_key_curvename.value, key_curvename);
+ subsystem_key_curvename = set_default(x_subsystem_key_curvename.value, key_curvename);
+ sslserver_key_curvename = set_default(x_sslserver_key_curvename.value, key_curvename);
+
+ if (signing_key_type.equalsIgnoreCase("RSA")) {
+ key_algorithm = set_default(x_key_algorithm.value, DEFAULT_KEY_ALGORITHM_RSA);
+ } else {
+ key_algorithm = set_default(x_key_algorithm.value, DEFAULT_KEY_ALGORITHM_ECC);
+ }
+
+ signing_algorithm = set_default(x_signing_algorithm.value, key_algorithm);
+ signing_signingalgorithm = set_default(x_signing_signingalgorithm.value, signing_algorithm);
+ ocsp_signing_signingalgorithm = set_default(x_ocsp_signing_signingalgorithm.value, signing_algorithm);
+
+ token_name = x_token_name.value;
+ token_pwd = x_token_pwd.value;
+
+ agent_key_size = x_agent_key_size.value;
+ agent_key_type = x_agent_key_type.value;
+ agent_cert_subject = x_agent_cert_subject.value;
+
+ backup_pwd = x_backup_pwd.value;
+ subsystem_name = x_subsystem_name.value;
+
+ subca_sign_cert_subject_name = x_subca_sign_cert_subject_name.value;
+ subca_subsystem_cert_subject_name =
+ x_subca_subsystem_cert_subject_name.value;
+ subca_ocsp_cert_subject_name = x_subca_ocsp_cert_subject_name.value;
+ subca_server_cert_subject_name = x_subca_server_cert_subject_name.value;
+ subca_audit_signing_cert_subject_name = x_subca_audit_signing_cert_subject_name.value;
+
+ boolean st = ca.ConfigureSubCAInstance();
+
+ if (!st) {
+ System.out.println("ERROR: unable to create Subordinate CA");
+ System.exit(-1);
+ }
+
+ System.out.println("Certificate System - Subordinate CA Instance Configured.");
+ System.exit(0);
+
+ }
+
+};
diff --git a/base/silent/src/com/netscape/pkisilent/ConfigureTKS.java b/base/silent/src/com/netscape/pkisilent/ConfigureTKS.java
new file mode 100644
index 000000000..760690888
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/ConfigureTKS.java
@@ -0,0 +1,1121 @@
+package com.netscape.pkisilent;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.pkcs12.AuthenticatedSafes;
+import org.mozilla.jss.pkcs12.PFX;
+
+import com.netscape.pkisilent.argparser.ArgParser;
+import com.netscape.pkisilent.argparser.StringHolder;
+import com.netscape.pkisilent.common.ComCrypto;
+import com.netscape.pkisilent.common.ParseXML;
+import com.netscape.pkisilent.http.HTTPClient;
+import com.netscape.pkisilent.http.HTTPResponse;
+import com.netscape.cmsutil.util.Utils;
+
+public class ConfigureTKS {
+
+ public static final String DEFAULT_KEY_TYPE = "RSA";
+ public static final String DEFAULT_KEY_SIZE = "2048";
+ public static final String DEFAULT_KEY_CURVENAME = "nistp256";
+
+ // define global variables
+
+ public static HTTPClient hc = null;
+
+ public static String login_uri = "/tks/admin/console/config/login";
+ public static String wizard_uri = "/tks/admin/console/config/wizard";
+ public static String admin_uri = "/ca/admin/ca/getBySerial";
+
+ public static String sd_login_uri = "/ca/admin/ca/securityDomainLogin";
+ public static String sd_get_cookie_uri = "/ca/admin/ca/getCookie";
+ public static String pkcs12_uri = "/tks/admin/console/config/savepkcs12";
+
+ public static String cs_hostname = null;
+ public static String cs_port = null;
+
+ public static String sd_hostname = null;
+ public static String sd_ssl_port = null;
+ public static String sd_agent_port = null;
+ public static String sd_admin_port = null;
+ public static String sd_admin_name = null;
+ public static String sd_admin_password = null;
+
+ public static String ca_hostname = null;
+ public static String ca_port = null;
+ public static String ca_ssl_port = null;
+
+ public static String client_certdb_dir = null;
+ public static String client_certdb_pwd = null;
+
+ // Login Panel
+ public static String pin = null;
+
+ public static String domain_name = null;
+
+ public static String admin_user = null;
+ public static String admin_email = null;
+ public static String admin_password = null;
+ public static String admin_serial_number = null;
+ public static String agent_name = null;
+
+ public static String ldap_host = null;
+ public static String ldap_port = null;
+ public static String bind_dn = null;
+ public static String bind_password = null;
+ public static String base_dn = null;
+ public static String db_name = null;
+ public static String secure_conn = null;
+ public static String remove_data = null;
+
+ public static String key_type = null;
+ public static String key_size = null;
+ public static String key_curvename = null;
+
+ public static String subsystem_key_type = null;
+ public static String subsystem_key_size = null;
+ public static String subsystem_key_curvename = null;
+
+ public static String audit_signing_key_type = null;
+ public static String audit_signing_key_size = null;
+ public static String audit_signing_key_curvename = null;
+
+ public static String sslserver_key_type = null;
+ public static String sslserver_key_size = null;
+ public static String sslserver_key_curvename = null;
+
+ public static String token_name = null;
+ public static String token_pwd = null;
+
+ public static String agent_key_size = null;
+ public static String agent_key_type = null;
+ public static String agent_cert_subject = null;
+
+ public static String server_cert_name = null;
+ public static String server_cert_req = null;
+ public static String server_cert_pp = null;
+ public static String server_cert_cert = null;
+
+ public static String tks_subsystem_cert_name = null;
+ public static String tks_subsystem_cert_req = null;
+ public static String tks_subsystem_cert_pp = null;
+ public static String tks_subsystem_cert_cert = null;
+
+ public static String tks_audit_signing_cert_name = null;
+ public static String tks_audit_signing_cert_req = null;
+ public static String tks_audit_signing_cert_pp = null;
+ public static String tks_audit_signing_cert_cert = null;
+
+ public static String backup_pwd = null;
+ public static String backup_fname = null;
+
+ // names
+ public static String tks_subsystem_cert_subject_name = null;
+ public static String tks_server_cert_subject_name = null;
+ public static String subsystem_name = null;
+ public static String tks_audit_signing_cert_subject_name = null;
+
+ public ConfigureTKS() {
+ // do nothing :)
+ }
+
+ public void sleep_time() {
+ try {
+ System.out.println("Sleeping for 5 secs..");
+ Thread.sleep(5000);
+ } catch (Exception e) {
+ System.out.println("ERROR: sleep problem");
+ }
+ }
+
+ public boolean LoginPanel() {
+ boolean st = false;
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "pin=" + pin + "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, login_uri, query_string);
+ System.out.println("xml returned: " + hr.getHTML());
+
+ // parse xml here - nothing to parse
+
+ // get cookie
+ String temp = hr.getCookieValue("JSESSIONID");
+
+ if (temp != null) {
+ int index = temp.indexOf(";");
+ HTTPClient.j_session_id = temp.substring(0, index);
+ st = true;
+ }
+
+ hr = null;
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri,
+ "p=0&op=next&xml=true");
+
+ // parse xml here
+
+ bais = new ByteArrayInputStream(
+ hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return st;
+ }
+
+ public boolean TokenChoicePanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = null;
+
+ // Software Token
+ if (token_name.equalsIgnoreCase("internal")) {
+ query_string = "p=1" + "&op=next" + "&xml=true" +
+ "&choice=" +
+ URLEncoder.encode("Internal Key Storage Token", "UTF-8") +
+ "";
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+ }
+ // HSM
+ else {
+ // login to hsm first
+ query_string = "p=2" + "&op=next" + "&xml=true" +
+ "&uTokName=" +
+ URLEncoder.encode(token_name, "UTF-8") +
+ "&__uPasswd=" +
+ URLEncoder.encode(token_pwd, "UTF-8") +
+ "";
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ // choice with token name now
+ query_string = "p=1" + "&op=next" + "&xml=true" +
+ "&choice=" +
+ URLEncoder.encode(token_name, "UTF-8") +
+ "";
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+ }
+
+ return true;
+ }
+
+ public boolean DomainPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String domain_url = "https://" + sd_hostname + ":" + sd_admin_port;
+
+ String query_string = "sdomainURL=" +
+ URLEncoder.encode(domain_url, "UTF-8") +
+ "&choice=existingdomain" +
+ "&p=3" +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+
+ }
+
+ public boolean DisplayChainPanel() {
+ String query_string = "p=4" + "&op=next" + "&xml=true";
+ hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ // bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ // px.parse(bais);
+ // px.prettyprintxml();
+
+ return true;
+
+ }
+
+ public boolean SecurityDomainLoginPanel() throws UnsupportedEncodingException {
+ String tks_url = "https://" + cs_hostname + ":" + cs_port +
+ "/tks/admin/console/config/wizard" +
+ "?p=5&subsystem=TKS";
+
+ String query_string = "url=" + URLEncoder.encode(tks_url, "UTF-8");
+
+ HTTPResponse hr = hc.sslConnect(sd_hostname, sd_admin_port, sd_login_uri, query_string);
+
+ String query_string_1 = "uid=" + sd_admin_name +
+ "&pwd=" + URLEncoder.encode(sd_admin_password, "UTF-8") +
+ "&url=" + URLEncoder.encode(tks_url, "UTF-8");
+
+ hr = hc.sslConnect(sd_hostname, sd_admin_port, sd_get_cookie_uri,
+ query_string_1);
+
+ // get session id from security domain
+
+ String tks_session_id = hr.getContentValue("header.session_id");
+ String tks_url_1 = hr.getContentValue("header.url");
+
+ System.out.println("TKS_SESSION_ID=" + tks_session_id);
+ System.out.println("TKS_URL=" + tks_url_1);
+
+ // use session id to connect back to TKS
+
+ String query_string_2 = "p=5" +
+ "&subsystem=TKS" +
+ "&session_id=" + tks_session_id +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri,
+ query_string_2);
+
+ // parse xml
+ // bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ // px.parse(bais);
+ // px.prettyprintxml();
+
+ return true;
+
+ }
+
+ public boolean SubsystemPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=5" + "&op=next" + "&xml=true" +
+ "&subsystemName=" +
+ URLEncoder.encode(subsystem_name, "UTF-8") +
+ "&choice=newsubsystem";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean LdapConnectionPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=7" + "&op=next" + "&xml=true" +
+ "&host=" + URLEncoder.encode(ldap_host, "UTF-8") +
+ "&port=" + URLEncoder.encode(ldap_port, "UTF-8") +
+ "&binddn=" + URLEncoder.encode(bind_dn, "UTF-8") +
+ "&__bindpwd=" + URLEncoder.encode(bind_password, "UTF-8") +
+ "&basedn=" + URLEncoder.encode(base_dn, "UTF-8") +
+ "&database=" + URLEncoder.encode(db_name, "UTF-8") +
+ "&display=" + URLEncoder.encode("$displayStr", "UTF-8") +
+ (secure_conn.equals("true") ? "&secureConn=on" : "") +
+ (remove_data.equals("true") ? "&removeData=true" : "");
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean KeyPanel() {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+ ArrayList<String> al = null;
+
+ String query_string = "p=8" + "&op=next" + "&xml=true" +
+ "&subsystem_custom_size=" + subsystem_key_size +
+ "&sslserver_custom_size=" + sslserver_key_size +
+ "&audit_signing_custom_size=" + audit_signing_key_size +
+ "&custom_size=" + key_size +
+ "&subsystem_custom_curvename=" + subsystem_key_curvename +
+ "&sslserver_custom_curvename=" + sslserver_key_curvename +
+ "&audit_signing_custom_curvename=" + audit_signing_key_curvename +
+ "&custom_curvename=" + key_curvename +
+ "&subsystem_keytype=" + subsystem_key_type +
+ "&sslserver_keytype=" + sslserver_key_type +
+ "&audit_signing_keytype=" + audit_signing_key_type +
+ "&keytype=" + key_type +
+ "&subsystem_choice=custom" +
+ "&sslserver_choice=custom" +
+ "&audit_signing_choice=custom" +
+ "&choice=custom";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ al = px.constructValueList("CertReqPair", "DN");
+ // get ca cert subject name
+ if (al != null) {
+ for (int i = 0; i < al.size(); i++) {
+ String temp = al.get(i);
+ if (temp.indexOf("TKS Subsystem") > 0) {
+ tks_subsystem_cert_name = temp;
+ } else if (temp.indexOf("Audit Signing Certificate") > 0) {
+ tks_audit_signing_cert_name = temp;
+ } else {
+ server_cert_name = temp;
+ }
+ }
+ }
+
+ System.out.println("default: tks_subsystem_cert_name=" +
+ tks_subsystem_cert_name);
+ System.out.println("default: server_cert_name=" +
+ server_cert_name);
+ System.out.println("default: tks_audit_signing_cert_name=" + tks_audit_signing_cert_name);
+ return true;
+ }
+
+ public boolean CertSubjectPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+ ArrayList<String> req_list = null;
+ ArrayList<String> cert_list = null;
+ ArrayList<String> dn_list = null;
+
+ String domain_url = "https://" + ca_hostname + ":" + ca_ssl_port;
+
+ String query_string = "p=9" + "&op=next" + "&xml=true" +
+ "&subsystem=" +
+ URLEncoder.encode(tks_subsystem_cert_subject_name, "UTF-8") +
+ "&sslserver=" +
+ URLEncoder.encode(tks_server_cert_subject_name, "UTF-8") +
+ "&audit_signing=" +
+ URLEncoder.encode(tks_audit_signing_cert_subject_name, "UTF-8") +
+ "&urls=" +
+ URLEncoder.encode(domain_url, "UTF-8") +
+ "";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ req_list = px.constructValueList("CertReqPair", "Request");
+ cert_list = px.constructValueList("CertReqPair", "Certificate");
+ dn_list = px.constructValueList("CertReqPair", "Nickname");
+
+ if (req_list != null && cert_list != null && dn_list != null) {
+ for (int i = 0; i < dn_list.size(); i++) {
+ String temp = dn_list.get(i);
+
+ if (temp.indexOf("subsystemCert") >= 0) {
+ tks_subsystem_cert_req = req_list.get(i);
+ tks_subsystem_cert_cert = cert_list.get(i);
+ } else if (temp.indexOf("auditSigningCert") >= 0) {
+ tks_audit_signing_cert_req = req_list.get(i);
+ tks_audit_signing_cert_cert = cert_list.get(i);
+ } else {
+ server_cert_req = req_list.get(i);
+ server_cert_cert = cert_list.get(i);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ public boolean CertificatePanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=10" + "&op=next" + "&xml=true" +
+ "&subsystem=" +
+ URLEncoder.encode(tks_subsystem_cert_cert, "UTF-8") +
+ "&subsystem_cc=" +
+ "&sslserver=" +
+ URLEncoder.encode(server_cert_cert, "UTF-8") +
+ "&sslserver_cc=" +
+ "&audit_signing=" +
+ URLEncoder.encode(tks_audit_signing_cert_cert, "UTF-8") +
+ "&audit_signing_cc=" +
+ "";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean BackupPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=11" + "&op=next" + "&xml=true" +
+ "&choice=backupkey" +
+ "&__pwd=" + URLEncoder.encode(backup_pwd, "UTF-8") +
+ "&__pwdagain=" + URLEncoder.encode(backup_pwd, "UTF-8");
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean SavePKCS12Panel() {
+ String query_string = "";
+
+ HTTPResponse hr = hc.sslConnect(cs_hostname, cs_port, pkcs12_uri, query_string);
+
+ // dump hr.getResponseData() to file
+
+ try {
+ FileOutputStream fos = new FileOutputStream(backup_fname);
+ fos.write(hr.getResponseData());
+ fos.close();
+
+ // set file to permissions 600
+ String rtParams[] = { "chmod", "600", backup_fname };
+ Process proc = Runtime.getRuntime().exec(rtParams);
+
+ BufferedReader br = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
+ String line = null;
+ while ((line = br.readLine()) != null)
+ System.out.println("Error: " + line);
+ proc.waitFor();
+
+ // verify p12 file
+
+ // Decode the P12 file
+ FileInputStream fis = new FileInputStream(backup_fname);
+ PFX.Template pfxt = new PFX.Template();
+ PFX pfx = (PFX) pfxt.decode(new BufferedInputStream(fis, 2048));
+ System.out.println("Decoded PFX");
+
+ // now peruse it for interesting info
+ System.out.println("Version: " + pfx.getVersion());
+ AuthenticatedSafes authSafes = pfx.getAuthSafes();
+ SEQUENCE asSeq = authSafes.getSequence();
+ System.out.println("AuthSafes has " +
+ asSeq.size() + " SafeContents");
+
+ fis.close();
+ } catch (Exception e) {
+ System.out.println("ERROR: Exception=" + e.getMessage());
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean AdminCertReqPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+ String admin_cert_request = null;
+
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir,
+ client_certdb_pwd,
+ agent_cert_subject,
+ agent_key_size,
+ agent_key_type);
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(true);
+ cCrypt.setTransportCert(null);
+ cCrypt.setDualKey(false);
+ cCrypt.loginDB();
+
+ String crmf_request = cCrypt.generateCRMFrequest();
+
+ if (crmf_request == null) {
+ System.out.println("ERROR: AdminCertReqPanel() cert req gen failed");
+ return false;
+ }
+
+ admin_cert_request = crmf_request;
+
+ String query_string = "p=13" + "&op=next" + "&xml=true" +
+ "&cert_request_type=" + "crmf" +
+ "&uid=" + admin_user +
+ "&name=" + admin_user +
+ "&__pwd=" + URLEncoder.encode(admin_password, "UTF-8") +
+ "&__admin_password_again=" + URLEncoder.encode(admin_password, "UTF-8") +
+ "&profileId=" + "caAdminCert" +
+ "&email=" +
+ URLEncoder.encode(admin_email, "UTF-8") +
+ "&cert_request=" +
+ URLEncoder.encode(admin_cert_request, "UTF-8") +
+ "&subject=" +
+ URLEncoder.encode(agent_cert_subject, "UTF-8") +
+ "&clone=new" +
+ "&import=true" +
+ "&securitydomain=" +
+ URLEncoder.encode(domain_name, "UTF-8") +
+ "";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ admin_serial_number = px.getvalue("serialNumber");
+
+ return true;
+ }
+
+ public boolean AdminCertImportPanel() {
+ boolean st = false;
+
+ String query_string = "serialNumber=" + admin_serial_number +
+ "&importCert=" + "true" +
+ "";
+
+ HTTPResponse hr = hc.sslConnect(sd_hostname, sd_admin_port, admin_uri, query_string);
+
+ // get response data
+ // String cert_to_import =
+ // new sun.misc.BASE64Encoder().encode(hr.getResponseData());
+ String cert_to_import =
+ Utils.base64encode(hr.getResponseData());
+ System.out.println("Imported Cert=" + cert_to_import);
+
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir,
+ client_certdb_pwd,
+ null,
+ null,
+ null);
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(true);
+ cCrypt.loginDB();
+
+ String start = "-----BEGIN CERTIFICATE-----\r\n";
+ String end = "\r\n-----END CERTIFICATE-----";
+
+ st = cCrypt.importCert(start + cert_to_import + end, agent_name);
+ if (!st) {
+ System.out.println("ERROR: AdminCertImportPanel() during cert import");
+ return false;
+ }
+
+ System.out.println("SUCCESS: imported admin user cert");
+ return true;
+ }
+
+ public boolean UpdateDomainPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=14" + "&op=next" + "&xml=true" +
+ "&caHost=" + URLEncoder.encode(sd_hostname, "UTF-8") +
+ "&caPort=" + URLEncoder.encode(sd_agent_port, "UTF-8") +
+ "";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean ConfigureTKSInstance() throws UnsupportedEncodingException {
+ // 0. login to cert db
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir,
+ client_certdb_pwd,
+ null,
+ null,
+ null);
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(true);
+ cCrypt.loginDB();
+
+ // instantiate http client
+ hc = new HTTPClient();
+
+ sleep_time();
+ // 1. Login panel
+ boolean log_st = LoginPanel();
+ if (!log_st) {
+ System.out.println("ERROR: ConfigureTKS: LoginPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 2. Token Choice Panel
+ boolean disp_token = TokenChoicePanel();
+ if (!disp_token) {
+ System.out.println("ERROR: ConfigureTKS: TokenChoicePanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 3. domain panel
+ boolean dom_st = DomainPanel();
+ if (!dom_st) {
+ System.out.println("ERROR: ConfigureTKS: DomainPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 4. display cert chain panel
+ boolean disp_st = DisplayChainPanel();
+ if (!disp_st) {
+ System.out.println("ERROR: ConfigureTKS: DisplayChainPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // security domain login panel
+ boolean disp_sd = SecurityDomainLoginPanel();
+ if (!disp_sd) {
+ System.out.println("ERROR: ConfigureTKS: SecurityDomainLoginPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // subsystem panel
+ boolean disp_ss = SubsystemPanel();
+ if (!disp_ss) {
+ System.out.println("ERROR: ConfigureTKS: SubsystemPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 7. ldap connection panel
+ boolean disp_ldap = LdapConnectionPanel();
+ if (!disp_ldap) {
+ System.out.println("ERROR: ConfigureTKS: LdapConnectionPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ sleep_time();
+ // 9. Key Panel
+ boolean disp_key = KeyPanel();
+ if (!disp_key) {
+ System.out.println("ERROR: ConfigureTKS: KeyPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 10. Cert Subject Panel
+ boolean disp_csubj = CertSubjectPanel();
+ if (!disp_csubj) {
+ System.out.println("ERROR: ConfigureTKS: CertSubjectPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 11. Certificate Panel
+ boolean disp_cp = CertificatePanel();
+ if (!disp_cp) {
+ System.out.println("ERROR: ConfigureTKS: CertificatePanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // backup panel
+ boolean disp_back = BackupPanel();
+ if (!disp_back) {
+ System.out.println("ERROR: ConfigureTKS: BackupPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // save panel
+ boolean disp_save = SavePKCS12Panel();
+ if (!disp_save) {
+ System.out.println("ERROR: ConfigureTKS: SavePKCS12Panel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 13. Admin Cert Req Panel
+ boolean disp_adm = AdminCertReqPanel();
+ if (!disp_adm) {
+ System.out.println("ERROR: ConfigureTKS: AdminCertReqPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 14. Admin Cert import Panel
+ boolean disp_im = AdminCertImportPanel();
+ if (!disp_im) {
+ System.out.println("ERROR: ConfigureTKS: AdminCertImportPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 15. Update Domain Panel
+ boolean disp_ud = UpdateDomainPanel();
+ if (!disp_ud) {
+ System.out.println("ERROR: ConfigureTKS: UpdateDomainPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ return true;
+ }
+
+ private static String set_default(String val, String def) {
+ if ((val == null) || (val.equals(""))) {
+ return def;
+ } else {
+ return val;
+ }
+ }
+
+ public static void main(String args[]) throws UnsupportedEncodingException {
+ ConfigureTKS ca = new ConfigureTKS();
+
+ // set variables
+ StringHolder x_cs_hostname = new StringHolder();
+ StringHolder x_cs_port = new StringHolder();
+
+ StringHolder x_sd_hostname = new StringHolder();
+ StringHolder x_sd_ssl_port = new StringHolder();
+ StringHolder x_sd_agent_port = new StringHolder();
+ StringHolder x_sd_admin_port = new StringHolder();
+ StringHolder x_sd_admin_name = new StringHolder();
+ StringHolder x_sd_admin_password = new StringHolder();
+
+ StringHolder x_ca_hostname = new StringHolder();
+ StringHolder x_ca_port = new StringHolder();
+ StringHolder x_ca_ssl_port = new StringHolder();
+
+ StringHolder x_client_certdb_dir = new StringHolder();
+ StringHolder x_client_certdb_pwd = new StringHolder();
+ StringHolder x_preop_pin = new StringHolder();
+
+ StringHolder x_domain_name = new StringHolder();
+
+ StringHolder x_admin_user = new StringHolder();
+ StringHolder x_admin_email = new StringHolder();
+ StringHolder x_admin_password = new StringHolder();
+
+ // ldap
+ StringHolder x_ldap_host = new StringHolder();
+ StringHolder x_ldap_port = new StringHolder();
+ StringHolder x_bind_dn = new StringHolder();
+ StringHolder x_bind_password = new StringHolder();
+ StringHolder x_base_dn = new StringHolder();
+ StringHolder x_db_name = new StringHolder();
+ StringHolder x_secure_conn = new StringHolder();
+ StringHolder x_remove_data = new StringHolder();
+
+ // key properties (defaults)
+ StringHolder x_key_size = new StringHolder();
+ StringHolder x_key_type = new StringHolder();
+ StringHolder x_key_curvename = new StringHolder();
+
+ // key properties (custom - audit_signing)
+ StringHolder x_audit_signing_key_size = new StringHolder();
+ StringHolder x_audit_signing_key_type = new StringHolder();
+ StringHolder x_audit_signing_key_curvename = new StringHolder();
+
+ // key properties (custom - subsystem)
+ StringHolder x_subsystem_key_size = new StringHolder();
+ StringHolder x_subsystem_key_type = new StringHolder();
+ StringHolder x_subsystem_key_curvename = new StringHolder();
+
+ // key properties (custom - sslserver)
+ StringHolder x_sslserver_key_size = new StringHolder();
+ StringHolder x_sslserver_key_type = new StringHolder();
+ StringHolder x_sslserver_key_curvename = new StringHolder();
+
+ StringHolder x_token_name = new StringHolder();
+ StringHolder x_token_pwd = new StringHolder();
+
+ StringHolder x_agent_key_size = new StringHolder();
+ StringHolder x_agent_key_type = new StringHolder();
+ StringHolder x_agent_cert_subject = new StringHolder();
+
+ StringHolder x_agent_name = new StringHolder();
+ StringHolder x_backup_pwd = new StringHolder();
+ StringHolder x_backup_fname = new StringHolder();
+
+ // tks cert subject name params
+ StringHolder x_tks_subsystem_cert_subject_name = new StringHolder();
+ StringHolder x_tks_server_cert_subject_name = new StringHolder();
+ StringHolder x_tks_audit_signing_cert_subject_name = new StringHolder();
+
+ // subsystemName
+ StringHolder x_subsystem_name = new StringHolder();
+
+ // parse the args
+ ArgParser parser = new ArgParser("ConfigureTKS");
+
+ parser.addOption("-cs_hostname %s #CS Hostname",
+ x_cs_hostname);
+ parser.addOption("-cs_port %s #CS SSL Admin port",
+ x_cs_port);
+
+ parser.addOption("-sd_hostname %s #Security Domain Hostname",
+ x_sd_hostname);
+ parser.addOption("-sd_ssl_port %s #Security Domain SSL EE port",
+ x_sd_ssl_port);
+ parser.addOption("-sd_agent_port %s #Security Domain SSL Agent port",
+ x_sd_agent_port);
+ parser.addOption("-sd_admin_port %s #Security Domain SSL Admin port",
+ x_sd_admin_port);
+ parser.addOption("-sd_admin_name %s #Security Domain Admin Name",
+ x_sd_admin_name);
+ parser.addOption("-sd_admin_password %s #Security Domain Admin password",
+ x_sd_admin_password);
+
+ parser.addOption("-ca_hostname %s #CA Hostname",
+ x_ca_hostname);
+ parser.addOption("-ca_port %s #CA non-SSL EE port",
+ x_ca_port);
+ parser.addOption("-ca_ssl_port %s #CA SSL EE port",
+ x_ca_ssl_port);
+
+ parser.addOption("-client_certdb_dir %s #Client CertDB dir",
+ x_client_certdb_dir);
+ parser.addOption("-client_certdb_pwd %s #client certdb password",
+ x_client_certdb_pwd);
+ parser.addOption("-preop_pin %s #pre op pin",
+ x_preop_pin);
+ parser.addOption("-domain_name %s #domain name",
+ x_domain_name);
+ parser.addOption("-admin_user %s #Admin User Name",
+ x_admin_user);
+ parser.addOption("-admin_email %s #Admin email",
+ x_admin_email);
+ parser.addOption("-admin_password %s #Admin password",
+ x_admin_password);
+ parser.addOption("-agent_name %s #Agent Cert Nickname",
+ x_agent_name);
+
+ parser.addOption("-ldap_host %s #ldap host",
+ x_ldap_host);
+ parser.addOption("-ldap_port %s #ldap port",
+ x_ldap_port);
+ parser.addOption("-bind_dn %s #ldap bind dn",
+ x_bind_dn);
+ parser.addOption("-bind_password %s #ldap bind password",
+ x_bind_password);
+ parser.addOption("-base_dn %s #base dn",
+ x_base_dn);
+ parser.addOption("-db_name %s #db name",
+ x_db_name);
+ parser.addOption("-secure_conn %s #use ldaps port (optional, default is false)", x_secure_conn);
+ parser.addOption("-remove_data %s #remove existing data under base_dn (optional, default is false) ",
+ x_remove_data);
+
+ // key and algorithm options (default)
+ parser.addOption("-key_type %s #Key type [RSA,ECC] (optional, default is RSA)", x_key_type);
+ parser.addOption("-key_size %s #Key Size (optional, for RSA default is 2048)", x_key_size);
+ parser.addOption("-key_curvename %s #Key Curve Name (optional, for ECC default is nistp256)", x_key_curvename);
+
+ // key and algorithm options for audit_signing certificate (overrides default)
+ parser.addOption("-audit_signing_key_type %s #Key type [RSA,ECC] (optional, default is key_type)",
+ x_audit_signing_key_type);
+ parser.addOption("-audit_signing_key_size %s #Key Size (optional, for RSA default is key_size)",
+ x_audit_signing_key_size);
+ parser.addOption(
+ "-audit_signing_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_audit_signing_key_curvename);
+
+ // key and algorithm options for subsystem certificate (overrides default)
+ parser.addOption("-subsystem_key_type %s #Key type [RSA,ECC] (optional, default is key_type)",
+ x_subsystem_key_type);
+ parser.addOption("-subsystem_key_size %s #Key Size (optional, for RSA default is key_size)",
+ x_subsystem_key_size);
+ parser.addOption("-subsystem_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_subsystem_key_curvename);
+
+ // key and algorithm options for sslserver certificate (overrides default)
+ parser.addOption("-sslserver_key_type %s #Key type [RSA,ECC] (optional, default is key_type)",
+ x_sslserver_key_type);
+ parser.addOption("-sslserver_key_size %s #Key Size (optional, for RSA default is key_size)",
+ x_sslserver_key_size);
+ parser.addOption("-sslserver_key_curvename %s #Key Curve Name (optional, for ECC default is key_curvename)",
+ x_sslserver_key_curvename);
+
+ parser.addOption("-token_name %s #HSM/Software Token name",
+ x_token_name);
+ parser.addOption("-token_pwd %s #HSM/Software Token password (optional, required for HSM)",
+ x_token_pwd);
+
+ parser.addOption("-agent_key_size %s #Agent Cert Key Size",
+ x_agent_key_size);
+ parser.addOption("-agent_key_type %s #Agent Cert Key type [rsa]",
+ x_agent_key_type);
+ parser.addOption("-agent_cert_subject %s #Agent Cert Subject",
+ x_agent_cert_subject);
+
+ parser.addOption("-backup_pwd %s #PKCS12 password",
+ x_backup_pwd);
+
+ parser.addOption(
+ "-tks_subsystem_cert_subject_name %s #TKS subsystem cert subject name",
+ x_tks_subsystem_cert_subject_name);
+ parser.addOption(
+ "-tks_server_cert_subject_name %s #TKS server cert subject name",
+ x_tks_server_cert_subject_name);
+
+ parser.addOption("-backup_fname %s #Backup File for p12, (optional, default /root/tmp-tks.p12",
+ x_backup_fname);
+
+ parser.addOption(
+ "-subsystem_name %s #CA subsystem name",
+ x_subsystem_name);
+
+ parser.addOption(
+ "-tks_audit_signing_cert_subject_name %s #TKS audit signing cert subject name",
+ x_tks_audit_signing_cert_subject_name);
+
+ // and then match the arguments
+ String[] unmatched = null;
+ unmatched = parser.matchAllArgs(args, 0, ArgParser.EXIT_ON_UNMATCHED);
+
+ if (unmatched != null) {
+ System.out.println("ERROR: Argument Mismatch");
+ System.exit(-1);
+ }
+
+ parser.checkRequiredArgs();
+
+ // set variables
+ cs_hostname = x_cs_hostname.value;
+ cs_port = x_cs_port.value;
+
+ sd_hostname = x_sd_hostname.value;
+ sd_ssl_port = x_sd_ssl_port.value;
+ sd_agent_port = x_sd_agent_port.value;
+ sd_admin_port = x_sd_admin_port.value;
+ sd_admin_name = x_sd_admin_name.value;
+ sd_admin_password = x_sd_admin_password.value;
+
+ ca_hostname = x_ca_hostname.value;
+ ca_port = x_ca_port.value;
+ ca_ssl_port = x_ca_ssl_port.value;
+
+ client_certdb_dir = x_client_certdb_dir.value;
+ client_certdb_pwd = x_client_certdb_pwd.value;
+ pin = x_preop_pin.value;
+ domain_name = x_domain_name.value;
+
+ admin_user = x_admin_user.value;
+ admin_email = x_admin_email.value;
+ admin_password = x_admin_password.value;
+ agent_name = x_agent_name.value;
+
+ ldap_host = x_ldap_host.value;
+ ldap_port = x_ldap_port.value;
+ bind_dn = x_bind_dn.value;
+ bind_password = x_bind_password.value;
+ base_dn = x_base_dn.value;
+ db_name = x_db_name.value;
+ secure_conn = set_default(x_secure_conn.value, "false");
+ remove_data = set_default(x_remove_data.value, "false");
+
+ key_type = set_default(x_key_type.value, DEFAULT_KEY_TYPE);
+ audit_signing_key_type = set_default(x_audit_signing_key_type.value, key_type);
+ subsystem_key_type = set_default(x_subsystem_key_type.value, key_type);
+ sslserver_key_type = set_default(x_sslserver_key_type.value, key_type);
+
+ key_size = set_default(x_key_size.value, DEFAULT_KEY_SIZE);
+ audit_signing_key_size = set_default(x_audit_signing_key_size.value, key_size);
+ subsystem_key_size = set_default(x_subsystem_key_size.value, key_size);
+ sslserver_key_size = set_default(x_sslserver_key_size.value, key_size);
+
+ key_curvename = set_default(x_key_curvename.value, DEFAULT_KEY_CURVENAME);
+ audit_signing_key_curvename = set_default(x_audit_signing_key_curvename.value, key_curvename);
+ subsystem_key_curvename = set_default(x_subsystem_key_curvename.value, key_curvename);
+ sslserver_key_curvename = set_default(x_sslserver_key_curvename.value, key_curvename);
+
+ token_name = x_token_name.value;
+ token_pwd = x_token_pwd.value;
+
+ agent_key_size = x_agent_key_size.value;
+ agent_key_type = x_agent_key_type.value;
+ agent_cert_subject = x_agent_cert_subject.value;
+
+ backup_pwd = x_backup_pwd.value;
+ backup_fname = set_default(x_backup_fname.value, "/root/tmp-tks.p12");
+
+ tks_subsystem_cert_subject_name =
+ x_tks_subsystem_cert_subject_name.value;
+ tks_server_cert_subject_name =
+ x_tks_server_cert_subject_name.value;
+
+ subsystem_name = x_subsystem_name.value;
+ tks_audit_signing_cert_subject_name = x_tks_audit_signing_cert_subject_name.value;
+
+ boolean st = ca.ConfigureTKSInstance();
+
+ if (!st) {
+ System.out.println("ERROR: unable to create TKS");
+ System.exit(-1);
+ }
+
+ System.out.println("Certificate System - TKS Instance Configured.");
+ System.exit(0);
+
+ }
+
+};
diff --git a/base/silent/src/com/netscape/pkisilent/ConfigureTPS.java b/base/silent/src/com/netscape/pkisilent/ConfigureTPS.java
new file mode 100644
index 000000000..366fb57b6
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/ConfigureTPS.java
@@ -0,0 +1,1088 @@
+package com.netscape.pkisilent;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.ByteArrayInputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+import com.netscape.pkisilent.argparser.ArgParser;
+import com.netscape.pkisilent.argparser.StringHolder;
+import com.netscape.pkisilent.common.ComCrypto;
+import com.netscape.pkisilent.common.ParseXML;
+import com.netscape.pkisilent.http.HTTPClient;
+import com.netscape.pkisilent.http.HTTPResponse;
+import com.netscape.cmsutil.util.Utils;
+
+public class ConfigureTPS {
+ // define global variables
+
+ public static HTTPClient hc = null;
+
+ public static String login_uri = "/tps/admin/console/config/login";
+ public static String wizard_uri = "/tps/admin/console/config/wizard";
+ public static String admin_uri = "/ca/admin/ca/getBySerial";
+
+ public static String sd_login_uri = "/ca/admin/ca/securityDomainLogin";
+ public static String sd_get_cookie_uri = "/ca/admin/ca/getCookie";
+ public static String sd_update_domain_uri = "/ca/agent/ca/updateDomainXML";
+ public static String pkcs12_uri = "/tps/admin/console/config/savepkcs12";
+
+ public static String cs_hostname = null;
+ public static String cs_port = null;
+ public static String cs_clientauth_port = null;
+
+ public static String sd_hostname = null;
+ public static String sd_ssl_port = null;
+ public static String sd_agent_port = null;
+ public static String sd_admin_port = null;
+ public static String sd_admin_name = null;
+ public static String sd_admin_password = null;
+
+ public static String ca_hostname = null;
+ public static String ca_port = null;
+ public static String ca_ssl_port = null;
+ public static String ca_admin_port = null;
+
+ public static String drm_hostname = null;
+ public static String drm_ssl_port = null;
+
+ public static String tks_hostname = null;
+ public static String tks_ssl_port = null;
+
+ public static String client_certdb_dir = null;
+ public static String client_certdb_pwd = null;
+
+ // Login Panel
+ public static String pin = null;
+
+ public static String domain_name = null;
+
+ public static String admin_user = null;
+ public static String admin_email = null;
+ public static String admin_password = null;
+ public static String admin_serial_number = null;
+ public static String agent_name = null;
+
+ public static String ldap_auth_host = null;
+ public static String ldap_auth_port = null;
+ public static String ldap_auth_base_dn = null;
+
+ public static String ldap_host = null;
+ public static String ldap_port = null;
+ public static String bind_dn = null;
+ public static String bind_password = null;
+ public static String base_dn = null;
+ public static String db_name = null;
+
+ public static String key_size = null;
+ public static String key_type = null;
+ public static String token_name = null;
+ public static String token_pwd = null;
+
+ public static String agent_key_size = null;
+ public static String agent_key_type = null;
+ public static String agent_cert_subject = null;
+
+ public static String tps_transport_cert_name = null;
+ public static String tps_transport_cert_req = null;
+ public static String tps_transport_cert_pp = null;
+ public static String tps_transport_cert_cert = null;
+
+ public static String tps_storage_cert_name = null;
+ public static String tps_storage_cert_req = null;
+ public static String tps_storage_cert_pp = null;
+ public static String tps_storage_cert_cert = null;
+
+ public static String server_cert_name = null;
+ public static String server_cert_req = null;
+ public static String server_cert_pp = null;
+ public static String server_cert_cert = null;
+
+ public static String tps_subsystem_cert_name = null;
+ public static String tps_subsystem_cert_req = null;
+ public static String tps_subsystem_cert_pp = null;
+ public static String tps_subsystem_cert_cert = null;
+
+ public static String tps_audit_signing_cert_name = null;
+ public static String tps_audit_signing_cert_req = null;
+ public static String tps_audit_signing_cert_pp = null;
+ public static String tps_audit_signing_cert_cert = null;
+
+ public static String ss_keygen = null;
+
+ // names
+ public static String tps_server_cert_subject_name = null;
+ public static String tps_server_cert_nickname = null;
+ public static String tps_subsystem_cert_subject_name = null;
+ public static String tps_subsystem_cert_nickname = null;
+ public static String tps_audit_signing_cert_subject_name = null;
+ public static String tps_audit_signing_cert_nickname = null;
+ public static String subsystem_name = null;
+
+ // Security Domain Login Panel
+ public static String tps_session_id = null;
+
+ // Admin Certificate Request Panel
+ public static String requestor_name = null;
+
+ public ConfigureTPS() {
+ // do nothing :)
+ }
+
+ public void sleep_time() {
+ try {
+ System.out.println("Sleeping for 5 secs..");
+ Thread.sleep(5000);
+ } catch (Exception e) {
+ System.out.println("ERROR: sleep problem");
+ }
+
+ }
+
+ public boolean LoginPanel() {
+ boolean st = false;
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "pin=" + pin + "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, login_uri, query_string);
+ System.out.println("xml returned: " + hr.getHTML());
+
+ // parse xml here - nothing to parse
+
+ // no cookie for tps
+ // get cookie
+ String temp = hr.getCookieValue("pin");
+
+ if (temp != null) {
+ int index = temp.indexOf(";");
+ HTTPClient.j_session_id = temp.substring(0, index);
+ st = true;
+ }
+
+ hr = null;
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri,
+ "p=0&op=next&xml=true");
+
+ // parse xml here
+
+ bais = new ByteArrayInputStream(
+ hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ st = true;
+ return st;
+ }
+
+ public boolean DomainPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String domain_url = "https://" + sd_hostname + ":" + sd_admin_port;
+
+ String query_string = "p=3" +
+ "&choice=existingdomain" +
+ "&sdomainURL=" +
+ URLEncoder.encode(domain_url, "UTF-8") +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+
+ }
+
+ public boolean DisplayChainPanel() {
+ String query_string = "p=4" + "&op=next" + "&xml=true";
+ hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ return true;
+
+ }
+
+ public boolean SecurityDomainLoginPanel() throws UnsupportedEncodingException {
+ String tps_url = "https://" + cs_hostname + ":" + cs_port +
+ "/tps/admin/console/config/wizard" +
+ "?p=3&subsystem=TPS";
+
+ String query_string = "url=" + URLEncoder.encode(tps_url, "UTF-8") + "";
+
+ HTTPResponse hr = hc.sslConnect(sd_hostname, sd_admin_port, sd_login_uri, query_string);
+
+ String query_string_1 = "uid=" + sd_admin_name +
+ "&pwd=" + URLEncoder.encode(sd_admin_password, "UTF-8") +
+ "&url=" + URLEncoder.encode(tps_url, "UTF-8") +
+ "";
+
+ hr = hc.sslConnect(sd_hostname, sd_admin_port, sd_get_cookie_uri,
+ query_string_1);
+
+ // get session id from security domain
+ sleep_time();
+
+ tps_session_id = hr.getContentValue("header.session_id");
+ String tps_url_1 = hr.getContentValue("header.url");
+
+ System.out.println("TPS_SESSION_ID=" + tps_session_id);
+ System.out.println("TPS_URL=" + tps_url_1);
+
+ // use session id to connect back to TPS
+
+ String query_string_2 = "p=5" +
+ "&subsystem=TPS" +
+ "&session_id=" + tps_session_id +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri,
+ query_string_2);
+
+ // parse xml - no parsing
+
+ return true;
+
+ }
+
+ public boolean SubsystemPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ sleep_time();
+ String query_string = "p=5" +
+ "&choice=newsubsystem" +
+ "&subsystemName=" +
+ URLEncoder.encode(subsystem_name, "UTF-8") +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ sleep_time();
+
+ // CA choice panel
+ query_string = "p=6" +
+ "&urls=0" +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ sleep_time();
+ query_string = "p=7" +
+ "&urls=0" +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ // DRM / server side keygen panel
+
+ sleep_time();
+ if (ss_keygen.equalsIgnoreCase("true")) {
+ ss_keygen = "keygen";
+ }
+
+ query_string = "p=8" +
+ "&choice=" + ss_keygen +
+ "&urls=0" +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean LdapAuthConnectionPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=9" +
+ "&host=" +
+ URLEncoder.encode(ldap_auth_host, "UTF-8") +
+ "&port=" +
+ URLEncoder.encode(ldap_auth_port, "UTF-8") +
+ "&basedn=" +
+ URLEncoder.encode(ldap_auth_base_dn, "UTF-8") +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean LdapConnectionPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=10" +
+ "&host=" +
+ URLEncoder.encode(ldap_host, "UTF-8") +
+ "&port=" +
+ URLEncoder.encode(ldap_port, "UTF-8") +
+ "&binddn=" +
+ URLEncoder.encode(bind_dn, "UTF-8") +
+ "&__bindpwd=" +
+ URLEncoder.encode(bind_password, "UTF-8") +
+ "&basedn=" +
+ URLEncoder.encode(base_dn, "UTF-8") +
+ "&database=" +
+ URLEncoder.encode(db_name, "UTF-8") +
+ "&display=" +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean TokenChoicePanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ ////////////////////////////////////////////////////////
+ String query_string = null;
+
+ // Software Token
+ if (token_name.equalsIgnoreCase("internal")) {
+ query_string = "p=1" +
+ "&choice=" +
+ URLEncoder.encode("NSS Certificate DB", "UTF-8") +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+ }
+ // HSM
+ else {
+ // login to hsm first
+ query_string = "p=2" +
+ "&uTokName=" +
+ URLEncoder.encode(token_name, "UTF-8") +
+ "&__uPasswd=" +
+ URLEncoder.encode(token_pwd, "UTF-8") +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ // choice with token name now
+ query_string = "p=1" +
+ "&choice=" +
+ URLEncoder.encode(token_name, "UTF-8") +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ }
+
+ return true;
+ }
+
+ public boolean KeyPanel() {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=11" +
+ "&keytype=" + key_type +
+ "&choice=default" +
+ "&custom_size=" + key_size +
+ "&sslserver_keytype=" + key_type +
+ "&sslserver_choice=custom" +
+ "&sslserver_custom_size=" + key_size +
+ "&subsystem_keytype=" + key_type +
+ "&subsystem_choice=custom" +
+ "&subsystem_custom_size=" + key_size +
+ "&audit_signing_keytype=" + key_type +
+ "&audit_signing_choice=default" +
+ "&audit_signing_custom_size=" + key_size +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean CertSubjectPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=12" +
+ "&sslserver=" +
+ URLEncoder.encode(tps_server_cert_subject_name, "UTF-8") +
+ "&sslserver_nick=" +
+ URLEncoder.encode(tps_server_cert_nickname, "UTF-8") +
+ "&subsystem=" +
+ URLEncoder.encode(tps_subsystem_cert_subject_name, "UTF-8") +
+ "&subsystem_nick=" +
+ URLEncoder.encode(tps_subsystem_cert_nickname, "UTF-8") +
+ "&audit_signing=" +
+ URLEncoder.encode(tps_audit_signing_cert_subject_name, "UTF-8") +
+ "&audit_signing_nick=" +
+ URLEncoder.encode(tps_audit_signing_cert_nickname, "UTF-8") +
+ "&urls=0" +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ // parse the certs if needed
+
+ return true;
+ }
+
+ public boolean CertificatePanel() {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+
+ String query_string = "p=13" +
+ "&sslserver=" +
+ "&sslserver_cc=" +
+ "&subsystem=" +
+ "&subsystem_cc=" +
+ "&audit_signing=" +
+ "&audit_signing_cc=" +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean AdminCertReqPanel() throws UnsupportedEncodingException {
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+ String admin_cert_request = null;
+
+ requestor_name = "TPS-" + cs_hostname + "-" + cs_clientauth_port;
+
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir,
+ client_certdb_pwd,
+ agent_cert_subject,
+ agent_key_size,
+ agent_key_type);
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(true);
+ cCrypt.setTransportCert(null);
+ cCrypt.setDualKey(false);
+ cCrypt.loginDB();
+
+ String crmf_request = cCrypt.generateCRMFrequest();
+
+ if (crmf_request == null) {
+ System.out.println("ERROR: AdminCertReqPanel() cert req gen failed");
+ return false;
+ }
+
+ admin_cert_request = crmf_request;
+
+ String query_string = "p=14" +
+ "&uid=" + admin_user +
+ "&name=" +
+ URLEncoder.encode("TPS Administrator", "UTF-8") +
+ "&email=" +
+ URLEncoder.encode(admin_email, "UTF-8") +
+ "&__pwd=" + URLEncoder.encode(admin_password, "UTF-8") +
+ "&__admin_password_again=" + URLEncoder.encode(admin_password, "UTF-8") +
+ "&cert_request=" +
+ URLEncoder.encode(admin_cert_request, "UTF-8") +
+ "&display=0" +
+ "&profileId=" + "caAdminCert" +
+ "&cert_request_type=" + "crmf" +
+ "&import=true" +
+ "&uid=" + admin_user +
+ "&clone=0" +
+ "&securitydomain=" +
+ URLEncoder.encode(domain_name, "UTF-8") +
+ "&subject=" +
+ URLEncoder.encode(agent_cert_subject, "UTF-8") +
+ "&requestor_name=" +
+ URLEncoder.encode(requestor_name, "UTF-8") +
+ "&sessionID=" + tps_session_id +
+ "&auth_hostname=" + ca_hostname +
+ "&auth_port=" + ca_ssl_port +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ admin_serial_number = px.getvalue("serialNumber");
+
+ return true;
+ }
+
+ public boolean AdminCertImportPanel() throws UnsupportedEncodingException {
+ boolean st = false;
+ HTTPResponse hr = null;
+ ByteArrayInputStream bais = null;
+ ParseXML px = new ParseXML();
+ String cert_to_import = null;
+
+ String query_string = "serialNumber=" + admin_serial_number +
+ "&importCert=" + "true" +
+ "";
+
+ // NOTE: CA, DRM, OCSP, and TKS use the Security Domain Admin Port;
+ // whereas RA and TPS use the CA Admin Port associated with
+ // the 'CA choice panel' as invoked from the SubsystemPanel()
+ // which MAY or MAY NOT be the same CA as the CA specified
+ // by the Security Domain.
+ hr = hc.sslConnect(ca_hostname, ca_admin_port, admin_uri, query_string);
+
+ try {
+ // cert_to_import =
+ // new sun.misc.BASE64Encoder().encode(hr.getResponseData());
+ cert_to_import =
+ Utils.base64encode(hr.getResponseData());
+
+ } catch (Exception e) {
+ System.out.println("ERROR: failed to retrieve cert");
+ }
+
+ System.out.println("Imported Cert=" + cert_to_import);
+
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir,
+ client_certdb_pwd,
+ null,
+ null,
+ null);
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(true);
+ cCrypt.loginDB();
+
+ String start = "-----BEGIN CERTIFICATE-----\r\n";
+ String end = "\r\n-----END CERTIFICATE-----";
+
+ st = cCrypt.importCert(start + cert_to_import + end, agent_name);
+ if (!st) {
+ System.out.println("ERROR: AdminCertImportPanel() during cert import");
+ return false;
+ }
+
+ System.out.println("SUCCESS: imported admin user cert");
+
+ String query_string_1 = "p=15" +
+ "&serialNumber=" + admin_serial_number +
+ "&caHost=" +
+ URLEncoder.encode(ca_hostname, "UTF-8") +
+ "&caPort=" + ca_admin_port +
+ "&op=next" +
+ "&xml=true";
+
+ hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string_1);
+
+ // parse xml
+ bais = new ByteArrayInputStream(hr.getHTML().getBytes());
+ px.parse(bais);
+ px.prettyprintxml();
+
+ return true;
+ }
+
+ public boolean ConfigureTPSInstance() throws UnsupportedEncodingException {
+ // 0. login to cert db
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir,
+ client_certdb_pwd,
+ null,
+ null,
+ null);
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(true);
+ cCrypt.loginDB();
+
+ // instantiate http client
+ hc = new HTTPClient();
+
+ sleep_time();
+ // 1. Login panel
+ boolean log_st = LoginPanel();
+ if (!log_st) {
+ System.out.println("ERROR: JSESSIONID not found.");
+ System.out.println("ERROR: ConfigureTPS: LoginPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 2. Token Choice Panel
+ boolean disp_token = TokenChoicePanel();
+ if (!disp_token) {
+ System.out.println("ERROR: ConfigureTPS: TokenChoicePanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 3. domain panel
+ boolean dom_st = DomainPanel();
+ if (!dom_st) {
+ System.out.println("ERROR: ConfigureTPS: DomainPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 4. display cert chain panel
+ boolean disp_st = DisplayChainPanel();
+ if (!disp_st) {
+ System.out.println("ERROR: ConfigureTPS: DisplayChainPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 5. security domain login panel
+ boolean disp_sd = SecurityDomainLoginPanel();
+ if (!disp_sd) {
+ System.out.println("ERROR: ConfigureTPS: SecurityDomainLoginPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 6. subsystem panel
+ boolean disp_ss = SubsystemPanel();
+ if (!disp_ss) {
+ System.out.println("ERROR: ConfigureTPS: SubsystemPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 7. ldap auth connection panel
+ boolean disp_ldap_auth = LdapAuthConnectionPanel();
+ if (!disp_ldap_auth) {
+ System.out.println("ERROR: ConfigureTPS: LdapAuthConnectionPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 8. ldap connection panel
+ boolean disp_ldap = LdapConnectionPanel();
+ if (!disp_ldap) {
+ System.out.println("ERROR: ConfigureTPS: LdapConnectionPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 11. Key Panel
+ boolean disp_key = KeyPanel();
+ if (!disp_key) {
+ System.out.println("ERROR: ConfigureTPS: KeyPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 12. Cert Subject Panel
+ boolean disp_csubj = CertSubjectPanel();
+ if (!disp_csubj) {
+ System.out.println("ERROR: ConfigureTPS: CertSubjectPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 13. Certificate Panel
+ boolean disp_cp = CertificatePanel();
+ if (!disp_cp) {
+ System.out.println("ERROR: ConfigureTPS: CertificatePanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 14. Admin Cert Req Panel
+ boolean disp_adm = AdminCertReqPanel();
+ if (!disp_adm) {
+ System.out.println("ERROR: ConfigureTPS: AdminCertReqPanel() failure");
+ return false;
+ }
+
+ sleep_time();
+ // 15. Admin Cert import Panel
+ boolean disp_im = AdminCertImportPanel();
+ if (!disp_im) {
+ System.out.println("ERROR: ConfigureTPS: AdminCertImportPanel() failure");
+ return false;
+ }
+
+ return true;
+ }
+
+ public static void main(String args[]) throws UnsupportedEncodingException {
+ ConfigureTPS ca = new ConfigureTPS();
+
+ // set variables
+ StringHolder x_cs_hostname = new StringHolder();
+ StringHolder x_cs_port = new StringHolder();
+ StringHolder x_cs_clientauth_port = new StringHolder();
+
+ StringHolder x_sd_hostname = new StringHolder();
+ StringHolder x_sd_ssl_port = new StringHolder();
+ StringHolder x_sd_agent_port = new StringHolder();
+ StringHolder x_sd_admin_port = new StringHolder();
+ StringHolder x_sd_admin_name = new StringHolder();
+ StringHolder x_sd_admin_password = new StringHolder();
+
+ StringHolder x_ca_hostname = new StringHolder();
+ StringHolder x_ca_port = new StringHolder();
+ StringHolder x_ca_ssl_port = new StringHolder();
+ StringHolder x_ca_admin_port = new StringHolder();
+
+ StringHolder x_drm_hostname = new StringHolder();
+ StringHolder x_drm_ssl_port = new StringHolder();
+
+ StringHolder x_tks_hostname = new StringHolder();
+ StringHolder x_tks_ssl_port = new StringHolder();
+
+ StringHolder x_client_certdb_dir = new StringHolder();
+ StringHolder x_client_certdb_pwd = new StringHolder();
+ StringHolder x_preop_pin = new StringHolder();
+
+ StringHolder x_domain_name = new StringHolder();
+
+ StringHolder x_admin_user = new StringHolder();
+ StringHolder x_admin_email = new StringHolder();
+ StringHolder x_admin_password = new StringHolder();
+
+ // ldap
+
+ StringHolder x_ldap_host = new StringHolder();
+ StringHolder x_ldap_port = new StringHolder();
+ StringHolder x_bind_dn = new StringHolder();
+ StringHolder x_bind_password = new StringHolder();
+ StringHolder x_base_dn = new StringHolder();
+ StringHolder x_db_name = new StringHolder();
+
+ StringHolder x_ldap_auth_host = new StringHolder();
+ StringHolder x_ldap_auth_port = new StringHolder();
+ StringHolder x_ldap_auth_base_dn = new StringHolder();
+
+ // key size
+ StringHolder x_token_name = new StringHolder();
+ StringHolder x_token_pwd = new StringHolder();
+ StringHolder x_key_size = new StringHolder();
+ StringHolder x_key_type = new StringHolder();
+
+ StringHolder x_agent_key_size = new StringHolder();
+ StringHolder x_agent_key_type = new StringHolder();
+ StringHolder x_agent_cert_subject = new StringHolder();
+
+ StringHolder x_agent_name = new StringHolder();
+
+ StringHolder x_ss_keygen = new StringHolder();
+
+ // tps cert subject name params
+ StringHolder x_tps_server_cert_subject_name = new StringHolder();
+ StringHolder x_tps_server_cert_nickname = new StringHolder();
+ StringHolder x_tps_subsystem_cert_subject_name = new StringHolder();
+ StringHolder x_tps_subsystem_cert_nickname = new StringHolder();
+ StringHolder x_tps_audit_signing_cert_subject_name = new StringHolder();
+ StringHolder x_tps_audit_signing_cert_nickname = new StringHolder();
+
+ // subsystemName
+ StringHolder x_subsystem_name = new StringHolder();
+
+ // parse the args
+ ArgParser parser = new ArgParser("ConfigureTPS");
+
+ parser.addOption("-cs_hostname %s #CS Hostname",
+ x_cs_hostname);
+ parser.addOption("-cs_port %s #CS SSL port",
+ x_cs_port);
+ parser.addOption("-cs_clientauth_port %s #CS SSL port",
+ x_cs_clientauth_port);
+
+ parser.addOption("-sd_hostname %s #Security Domain Hostname",
+ x_sd_hostname);
+ parser.addOption("-sd_ssl_port %s #Security Domain SSL EE port",
+ x_sd_ssl_port);
+ parser.addOption("-sd_agent_port %s #Security Domain SSL Agent port",
+ x_sd_agent_port);
+ parser.addOption("-sd_admin_port %s #Security Domain SSL Admin port",
+ x_sd_admin_port);
+ parser.addOption("-sd_admin_name %s #Security Domain username",
+ x_sd_admin_name);
+ parser.addOption("-sd_admin_password %s #Security Domain password",
+ x_sd_admin_password);
+
+ parser.addOption("-ca_hostname %s #CA Hostname",
+ x_ca_hostname);
+ parser.addOption("-ca_port %s #CA non-SSL port",
+ x_ca_port);
+ parser.addOption("-ca_ssl_port %s #CA SSL port",
+ x_ca_ssl_port);
+ parser.addOption("-ca_admin_port %s #CA SSL Admin port",
+ x_ca_admin_port);
+
+ parser.addOption("-drm_hostname %s #DRM Hostname",
+ x_drm_hostname);
+ parser.addOption("-drm_ssl_port %s #DRM SSL port",
+ x_drm_ssl_port);
+ parser.addOption("-ss_keygen %s #Enable Server Side Keygen [true,false]",
+ x_ss_keygen);
+
+ parser.addOption("-tks_hostname %s #TKS Hostname",
+ x_tks_hostname);
+ parser.addOption("-tks_ssl_port %s #TKS SSL port",
+ x_tks_ssl_port);
+
+ parser.addOption("-client_certdb_dir %s #Client CertDB dir",
+ x_client_certdb_dir);
+ parser.addOption("-client_certdb_pwd %s #client certdb password",
+ x_client_certdb_pwd);
+ parser.addOption("-preop_pin %s #pre op pin",
+ x_preop_pin);
+ parser.addOption("-domain_name %s #domain name",
+ x_domain_name);
+ parser.addOption("-admin_user %s #Admin User Name",
+ x_admin_user);
+ parser.addOption("-admin_email %s #Admin email",
+ x_admin_email);
+ parser.addOption("-admin_password %s #Admin password",
+ x_admin_password);
+ parser.addOption("-agent_name %s #Agent Cert Nickname",
+ x_agent_name);
+
+ parser.addOption("-ldap_host %s #ldap host",
+ x_ldap_host);
+ parser.addOption("-ldap_port %s #ldap port",
+ x_ldap_port);
+ parser.addOption("-bind_dn %s #ldap bind dn",
+ x_bind_dn);
+ parser.addOption("-bind_password %s #ldap bind password",
+ x_bind_password);
+ parser.addOption("-base_dn %s #base dn",
+ x_base_dn);
+ parser.addOption("-db_name %s #db name",
+ x_db_name);
+
+ parser.addOption("-token_name %s #HSM/Software Token name",
+ x_token_name);
+ parser.addOption("-token_pwd %s #HSM/Software Token password (optional, required for HSM)",
+ x_token_pwd);
+ parser.addOption("-key_size %s #Key Size",
+ x_key_size);
+ parser.addOption("-key_type %s #Key type [rsa,ecc]",
+ x_key_type);
+
+ parser.addOption("-agent_key_size %s #Agent Cert Key Size",
+ x_agent_key_size);
+ parser.addOption("-agent_key_type %s #Agent cert Key type [rsa]",
+ x_agent_key_type);
+ parser.addOption("-agent_cert_subject %s #Agent cert Subject",
+ x_agent_cert_subject);
+
+ parser.addOption("-ldap_auth_host %s #ldap auth host",
+ x_ldap_auth_host);
+ parser.addOption("-ldap_auth_port %s #ldap auth port",
+ x_ldap_auth_port);
+ parser.addOption("-ldap_auth_base_dn %s #ldap auth base dn",
+ x_ldap_auth_base_dn);
+
+ parser.addOption(
+ "-tps_server_cert_subject_name %s #TPS server cert subject name",
+ x_tps_server_cert_subject_name);
+ parser.addOption(
+ "-tps_server_cert_nickname %s #TPS server cert nickname",
+ x_tps_server_cert_nickname);
+ parser.addOption(
+ "-tps_subsystem_cert_subject_name %s #TPS subsystem cert subject name",
+ x_tps_subsystem_cert_subject_name);
+ parser.addOption(
+ "-tps_subsystem_cert_nickname %s #TPS subsystem cert nickname",
+ x_tps_subsystem_cert_nickname);
+ parser.addOption(
+ "-tps_audit_signing_cert_subject_name %s #TPS audit signing cert subject name",
+ x_tps_audit_signing_cert_subject_name);
+ parser.addOption(
+ "-tps_audit_signing_cert_nickname %s #TPS audit signing cert nickname",
+ x_tps_audit_signing_cert_nickname);
+
+ parser.addOption(
+ "-subsystem_name %s #CA subsystem name",
+ x_subsystem_name);
+
+ // and then match the arguments
+ String[] unmatched = null;
+ unmatched = parser.matchAllArgs(args, 0, ArgParser.EXIT_ON_UNMATCHED);
+
+ if (unmatched != null) {
+ System.out.println("ERROR: Argument Mismatch");
+ System.exit(-1);
+ }
+
+ parser.checkRequiredArgs();
+
+ // set variables
+ cs_hostname = x_cs_hostname.value;
+ cs_port = x_cs_port.value;
+ cs_clientauth_port = x_cs_clientauth_port.value;
+
+ sd_hostname = x_sd_hostname.value;
+ sd_ssl_port = x_sd_ssl_port.value;
+ sd_agent_port = x_sd_agent_port.value;
+ sd_admin_port = x_sd_admin_port.value;
+ sd_admin_name = x_sd_admin_name.value;
+ sd_admin_password = x_sd_admin_password.value;
+
+ ca_hostname = x_ca_hostname.value;
+ ca_port = x_ca_port.value;
+ ca_ssl_port = x_ca_ssl_port.value;
+ ca_admin_port = x_ca_admin_port.value;
+
+ tks_hostname = x_tks_hostname.value;
+ tks_ssl_port = x_tks_ssl_port.value;
+
+ drm_hostname = x_drm_hostname.value;
+ drm_ssl_port = x_drm_ssl_port.value;
+
+ client_certdb_dir = x_client_certdb_dir.value;
+ client_certdb_pwd = x_client_certdb_pwd.value;
+ pin = x_preop_pin.value;
+ domain_name = x_domain_name.value;
+
+ admin_user = x_admin_user.value;
+ admin_email = x_admin_email.value;
+ admin_password = x_admin_password.value;
+ agent_name = x_agent_name.value;
+
+ ldap_host = x_ldap_host.value;
+ ldap_port = x_ldap_port.value;
+ bind_dn = x_bind_dn.value;
+ bind_password = x_bind_password.value;
+ base_dn = x_base_dn.value;
+ db_name = x_db_name.value;
+
+ ldap_auth_host = x_ldap_auth_host.value;
+ ldap_auth_port = x_ldap_auth_port.value;
+ ldap_auth_base_dn = x_ldap_auth_base_dn.value;
+
+ key_size = x_key_size.value;
+ key_type = x_key_type.value;
+ token_name = x_token_name.value;
+ token_pwd = x_token_pwd.value;
+
+ agent_key_size = x_agent_key_size.value;
+ agent_key_type = x_agent_key_type.value;
+ agent_cert_subject = x_agent_cert_subject.value;
+
+ ss_keygen = x_ss_keygen.value;
+
+ tps_server_cert_subject_name =
+ x_tps_server_cert_subject_name.value;
+ tps_server_cert_nickname =
+ x_tps_server_cert_nickname.value;
+ tps_subsystem_cert_subject_name =
+ x_tps_subsystem_cert_subject_name.value;
+ tps_subsystem_cert_nickname =
+ x_tps_subsystem_cert_nickname.value;
+ tps_audit_signing_cert_subject_name =
+ x_tps_audit_signing_cert_subject_name.value;
+ tps_audit_signing_cert_nickname =
+ x_tps_audit_signing_cert_nickname.value;
+
+ subsystem_name = x_subsystem_name.value;
+
+ boolean st = ca.ConfigureTPSInstance();
+
+ if (!st) {
+ System.out.println("ERROR: unable to create TPS");
+ System.exit(-1);
+ }
+
+ System.out.println("Certificate System - TPS Instance Configured");
+ System.exit(0);
+
+ }
+
+};
diff --git a/base/silent/src/com/netscape/pkisilent/PKISilent.java b/base/silent/src/com/netscape/pkisilent/PKISilent.java
new file mode 100644
index 000000000..f90832481
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/PKISilent.java
@@ -0,0 +1,59 @@
+package com.netscape.pkisilent;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.HashMap;
+
+public class PKISilent {
+ private static void usage() {
+ System.out.print("usage: java " + PKISilent.class.getCanonicalName());
+ boolean first = true;
+ for (Class<?> c : classes) {
+ if (first) {
+ System.out.println(" [ ");
+ } else {
+ System.out.println(" | ");
+ }
+ first = false;
+ System.out.print(" " + c.getSimpleName());
+ }
+ System.out.println(" ] ");
+ }
+
+ static Class<?>[] classes = { ConfigureCA.class, ConfigureDRM.class,
+ ConfigureOCSP.class, ConfigureRA.class, ConfigureSubCA.class,
+ ConfigureTKS.class, ConfigureTPS.class, };
+
+ public static final void main(String[] args) {
+ HashMap<String, Method> classMap = new HashMap<String, Method>();
+ for (Class<?> c : classes) {
+ try {
+ classMap.put(c.getSimpleName(),
+ c.getMethod("main", String[].class));
+ } catch (Exception e) {
+ // The set of classes listed above is guaranteed to have a
+ // method 'main'
+ e.printStackTrace();
+ }
+ }
+ if (args.length == 0) {
+ usage();
+ System.exit(-1);
+ }
+ Method mainMethod = classMap.get(args[0]);
+ if (mainMethod == null) {
+ usage();
+ System.exit(-1);
+ }
+ String[] innerArgs = {};
+ if (args.length > 1) {
+ innerArgs = Arrays.copyOfRange(args, 1, args.length);
+ }
+
+ try {
+ mainMethod.invoke(null, (Object) innerArgs);
+ } catch (Exception e) {
+ // exception is guaranteed to have the static main method
+ }
+ }
+}
diff --git a/base/silent/src/com/netscape/pkisilent/argparser/ArgParseException.java b/base/silent/src/com/netscape/pkisilent/argparser/ArgParseException.java
new file mode 100644
index 000000000..de3c58bd4
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/argparser/ArgParseException.java
@@ -0,0 +1,54 @@
+package com.netscape.pkisilent.argparser;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+import java.io.IOException;
+
+/**
+ * Exception class used by <code>ArgParser</code> when
+ * command line arguments contain an error.
+ *
+ * @author John E. Lloyd, Fall 2004
+ * @see ArgParser
+ */
+public class ArgParseException extends IOException {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -604960834535589460L;
+
+ /**
+ * Creates a new ArgParseException with the given message.
+ *
+ * @param msg Exception message
+ */
+ public ArgParseException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * Creates a new ArgParseException from the given
+ * argument and message.
+ *
+ * @param arg Offending argument
+ * @param msg Error message
+ */
+ public ArgParseException(String arg, String msg) {
+ super(arg + ": " + msg);
+ }
+}
diff --git a/base/silent/src/com/netscape/pkisilent/argparser/ArgParser.java b/base/silent/src/com/netscape/pkisilent/argparser/ArgParser.java
new file mode 100755
index 000000000..ed5f98b1d
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/argparser/ArgParser.java
@@ -0,0 +1,2085 @@
+package com.netscape.pkisilent.argparser;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ * Copyright John E. Lloyd, 2004. All rights reserved. Permission to use,
+ * copy, modify and redistribute is granted, provided that this copyright
+ * notice is retained and the author is given credit whenever appropriate.
+ *
+ * This software is distributed "as is", without any warranty, including
+ * any implied warranty of merchantability or fitness for a particular
+ * use. The author assumes no responsibility for, and shall not be liable
+ * for, any special, indirect, or consequential damages, or any damages
+ * whatsoever, arising out of or in connection with the use of this
+ * software.
+ */
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.io.PrintStream;
+import java.io.Reader;
+import java.lang.reflect.Array;
+import java.util.Vector;
+
+/**
+ * ArgParser is used to parse the command line arguments for a java
+ * application program. It provides a compact way to specify options and match
+ * them against command line arguments, with support for
+ * <a href=#rangespec>range checking</a>,
+ * <a href=#multipleOptionNames>multiple option names</a> (aliases),
+ * <a href=#singleWordOptions>single word options</a>,
+ * <a href=#multipleOptionValues>multiple values associated with an option</a>,
+ * <a href=#multipleOptionInvocation>multiple option invocation</a>,
+ * <a href=#helpInfo>generating help information</a>,
+ * <a href=#customArgParsing>custom argument parsing</a>, and
+ * <a href=#argsFromAFile>reading arguments from a file</a>. The
+ * last feature is particularly useful and makes it
+ * easy to create ad-hoc configuration files for an application.
+ *
+ * <h3><a name="example">Basic Example</a></h3>
+ *
+ * <p>
+ * Here is a simple example in which an application has three command line options: <code>-theta</code> (followed by a
+ * floating point value), <code>-file</code> (followed by a string value), and <code>-debug</code>, which causes a
+ * boolean value to be set.
+ *
+ * <pre>
+ *
+ * static public void main(String[] args) {
+ * // create holder objects for storing results ...
+ *
+ * DoubleHolder theta = new DoubleHolder();
+ * StringHolder fileName = new StringHolder();
+ * BooleanHolder debug = new BooleanHolder();
+ *
+ * // create the parser and specify the allowed options ...
+ *
+ * ArgParser parser = new ArgParser(&quot;java argparser.SimpleExample&quot;);
+ * parser.addOption(&quot;-theta %f #theta value (in degrees)&quot;, theta);
+ * parser.addOption(&quot;-file %s #name of the operating file&quot;, fileName);
+ * parser.addOption(&quot;-debug %v #enables display of debugging info&quot;, debug);
+ *
+ * // match the arguments ...
+ *
+ * parser.matchAllArgs(args);
+ *
+ * // and print out the values
+ *
+ * System.out.println(&quot;theta=&quot; + theta.value);
+ * System.out.println(&quot;fileName=&quot; + fileName.value);
+ * System.out.println(&quot;debug=&quot; + debug.value);
+ * }
+ * </pre>
+ * <p>
+ * A command line specifying all three options might look like this:
+ *
+ * <pre>
+ * java argparser.SimpleExample -theta 7.8 -debug -file /ai/lloyd/bar
+ * </pre>
+ *
+ * <p>
+ * The application creates an instance of ArgParser and then adds descriptions of the allowed options using
+ * {@link #addOption addOption}. The method {@link #matchAllArgs(String[]) matchAllArgs} is then used to match these
+ * options against the command line arguments. Values associated with each option are returned in the <code>value</code>
+ * field of special ``holder'' classes (e.g., {@link argparser.DoubleHolder DoubleHolder},
+ * {@link argparser.StringHolder StringHolder}, etc.).
+ *
+ * <p>
+ * The first argument to {@link #addOption addOption} is a string that specifies (1) the option's name, (2) a conversion
+ * code for its associated value (e.g., <code>%f</code> for floating point, <code>%s</code> for a string,
+ * <code>%v</code> for a boolean flag), and (3) an optional description (following the <code>#</code> character) which
+ * is used for generating help messages. The second argument is the holder object through which the value is returned.
+ * This may be either a type-specific object (such as {@link argparser.DoubleHolder DoubleHolder} or
+ * {@link argparser.StringHolder
+ * StringHolder}), an array of the appropriate type, or <a href=#multipleOptionInvocation> an instance of
+ * <code>java.util.Vector</code></a>.
+ *
+ * <p>
+ * By default, arguments that don't match the specified options, are <a href=#rangespec>out of range</a>, or are
+ * otherwise formatted incorrectly, will cause <code>matchAllArgs</code> to print a message and exit the program.
+ * Alternatively, an application can use {@link #matchAllArgs(String[],int,int) matchAllArgs(args,idx,exitFlags)} to
+ * obtain an array of unmatched arguments which can then be <a href=#customArgParsing>processed separately</a>
+ *
+ * <h3><a name="rangespec">Range Specification</a></h3>
+ *
+ * The values associated with options can also be given range specifications. A range specification appears in curly
+ * braces immediately following the conversion code. In the code fragment below, we show how to specify an option
+ * <code>-name</code> that expects to be provided with one of three string values (<code>john</code>, <code>mary</code>,
+ * or <code>jane</code>), an option <code>-index</code> that expects to be supplied with a integer value in the range 1
+ * to 256, an option <code>-size</code> that expects to be supplied with integer values of either 1, 2, 4, 8, or 16, and
+ * an option <code>-foo</code> that expects to be supplied with floating point values in the ranges -99 < foo <= -50, or
+ * 50 <= foo < 99.
+ *
+ * <pre>
+ * StringHolder name = new StringHolder();
+ * IntHolder index = new IntHolder();
+ * IntHolder size = new IntHolder();
+ * DoubleHolder foo = new DoubleHolder();
+ *
+ * parser.addOption(&quot;-name %s {john,mary,jane}&quot;, name);
+ * parser.addOption(&quot;-index %d {[1,256]}&quot;, index);
+ * parser.addOption(&quot;-size %d {1,2,4,8,16}&quot;, size);
+ * parser.addOption(&quot;-foo %f {(-99,-50],[50,99)}&quot;, foo);
+ * </pre>
+ *
+ * If an argument value does not lie within a specified range, an error is generated.
+ *
+ * <h3><a name="multipleOptionNames">Multiple Option Names</a></h3>
+ *
+ * An option may be given several names, or aliases, in the form of a comma seperated list:
+ *
+ * <pre>
+ * parser.addOption(&quot;-v,--verbose %v #print lots of info&quot;);
+ * parser.addOption(&quot;-of,-outfile,-outputFile %s #output file&quot;);
+ * </pre>
+ *
+ * <h3><a name="singleWordOptions">Single Word Options</a></h3>
+ *
+ * Normally, options are assumed to be "multi-word", meaning that any associated value must follow the option as a
+ * separate argument string. For example,
+ *
+ * <pre>
+ * parser.addOption(&quot;-file %s #file name&quot;);
+ * </pre>
+ *
+ * will cause the parser to look for two strings in the argument list of the form
+ *
+ * <pre>
+ * -file someFileName
+ * </pre>
+ *
+ * However, if there is no white space separting the option's name from it's conversion code, then values associated
+ * with that option will be assumed to be part of the same argument string as the option itself. For example,
+ *
+ * <pre>
+ * parser.addOption(&quot;-file=%s #file name&quot;);
+ * </pre>
+ *
+ * will cause the parser to look for a single string in the argument list of the form
+ *
+ * <pre>
+ * -file=someFileName
+ * </pre>
+ *
+ * Such an option is called a "single word" option.
+ *
+ * <p>
+ * In cases where an option has multiple names, then this single word behavior is invoked if there is no white space
+ * between the last indicated name and the conversion code. However, previous names in the list will still be given
+ * multi-word behavior if there is white space between the name and the following comma. For example,
+ *
+ * <pre>
+ * parser.addOption(&quot;-nb=,-number ,-n%d #number of blocks&quot;);
+ * </pre>
+ *
+ * will cause the parser to look for one, two, and one word constructions of the forms
+ *
+ * <pre>
+ * -nb=N
+ * -number N
+ * -nN
+ * </pre>
+ *
+ * <h3><a name="multipleOptionValues">Multiple Option Values</a></h3>
+ *
+ * If may be useful for an option to be followed by several values. For instance, we might have an option
+ * <code>-velocity</code> which should be followed by three numbers denoting the x, y, and z components of a velocity
+ * vector. We can require multiple values for an option by placing a <i>multiplier</i> specification, of the form
+ * <code>X</code>N, where N is an integer, after the conversion code (or range specification, if present). For example,
+ *
+ * <pre>
+ * double[] pos = new double[3];
+ *
+ * addOption(&quot;-position %fX3 #position of the object&quot;, pos);
+ * </pre>
+ *
+ * will cause the parser to look for
+ *
+ * <pre>
+ * -position xx yy zz
+ * </pre>
+ *
+ * in the argument list, where <code>xx</code>, <code>yy</code>, and <code>zz</code> are numbers. The values are stored
+ * in the array <code>pos</code>.
+ *
+ * Options requiring multiple values must use arrays to return their values, and cannot be used in single word format.
+ *
+ * <h3><a name="multipleOptionInvocation">Multiple Option Invocation</a></h3>
+ *
+ * Normally, if an option appears twice in the command list, the value associated with the second instance simply
+ * overwrites the value associated with the first instance.
+ *
+ * However, the application can instead arrange for the storage of <i>all</i> values associated with multiple option
+ * invocation, by supplying a instance of <code>java.util.Vector</code> to serve as the value holder. Then every time
+ * the option appears in the argument list, the parser will create a value holder of appropriate type, set it to the
+ * current value, and store the holder in the vector. For example, the construction
+ *
+ * <pre>
+ * Vector vec = new Vector(10);
+ *
+ * parser.addOption(&quot;-foo %f&quot;, vec);
+ * parser.matchAllArgs(args);
+ * </pre>
+ *
+ * when supplied with an argument list that contains
+ *
+ * <pre>
+ * -foo 1.2 -foo 1000 -foo -78
+ * </pre>
+ *
+ * will create three instances of {@link argparser.DoubleHolder DoubleHolder}, initialized to <code>1.2</code>,
+ * <code>1000</code>, and <code>-78</code>, and store them in <code>vec</code>.
+ *
+ * <h3><a name="helpInfo">Generating help information</a></h3>
+ *
+ * ArgParser automatically generates help information for the options, and this information may be printed in response
+ * to a <i>help</i> option, or may be queried by the application using {@link #getHelpMessage getHelpMessage}. The
+ * information for each option consists of the option's name(s), it's required value(s), and an application-supplied
+ * description. Value information is generated automaticlly from the conversion code, range, and multiplier
+ * specifications (although this can be overriden, as <a href=#valueInfo>described below</a>). The application-supplied
+ * description is whatever appears in the specification string after the optional <code>#</code> character. The string
+ * returned by {@link #getHelpMessage getHelpMessage} for the <a href=#example>first example above</a> would be
+ *
+ * <pre>
+ * Usage: java argparser.SimpleExample
+ * Options include:
+ *
+ * -help,-? displays help information
+ * -theta &lt;float&gt; theta value (in degrees)
+ * -file &lt;string&gt; name of the operating file
+ * -debug enables display of debugging info
+ * </pre>
+ *
+ * The options <code>-help</code> and <code>-?</code> are including in the parser by default as help options, and they
+ * automatically cause the help message to be printed. To exclude these options, one should use the constructor
+ * {@link #ArgParser(String,boolean)
+ * ArgParser(synopsis,false)}. Help options can also be specified by the application using {@link #addOption addOption}
+ * and the conversion code <code>%h</code>. Help options can be disabled using {@link #setHelpOptionsEnabled
+ * setHelpOptionsEnabled(false)}.
+ *
+ * <p>
+ * <a name=valueInfo> A description of the required values for an option can be specified explicitly by placing a second
+ * <code>#</code> character in the specification string. Everything between the first and second <code>#</code>
+ * characters then becomes the value description, and everything after the second <code>#</code> character becomes the
+ * option description. For example, if the <code>-theta</code> option above was specified with
+ *
+ * <pre>
+ * parser.addOption(&quot;-theta %f #NUMBER#theta value (in degrees)&quot;, theta);
+ * </pre>
+ *
+ * instead of
+ *
+ * <pre>
+ * parser.addOption(&quot;-theta %f #theta value (in degrees)&quot;, theta);
+ * </pre>
+ *
+ * then the corresponding entry in the help message would look like
+ *
+ * <pre>
+ * -theta NUMBER theta value (in degrees)
+ * </pre>
+ *
+ * <h3><a name="customArgParsing">Custom Argument Parsing</a></h3>
+ *
+ * An application may find it necessary to handle arguments that don't fit into the framework of this class. There are a
+ * couple of ways to do this.
+ *
+ * <p>
+ * First, the method {@link #matchAllArgs(String[],int,int)
+ * matchAllArgs(args,idx,exitFlags)} returns an array of all unmatched arguments, which can then be handled specially:
+ *
+ * <pre>
+ * String[] unmatched =
+ * parser.matchAllArgs (args, 0, parser.EXIT_ON_ERROR);
+ * for (int i = 0; i < unmatched.length; i++)
+ * { ... handle unmatched arguments ...
+ * }
+ * </pre>
+ *
+ * For instance, this would be useful for an applicatoon that accepts an arbitrary number of input file names. The
+ * options can be parsed using <code>matchAllArgs</code>, and the remaining unmatched arguments give the file names.
+ *
+ * <p>
+ * If we need more control over the parsing, we can parse arguments one at a time using {@link #matchArg matchArg}:
+ *
+ * <pre>
+ * int idx = 0;
+ * while (idx < args.length)
+ * { try
+ * { idx = parser.matchArg (args, idx);
+ * if (parser.getUnmatchedArgument() != null)
+ * {
+ * ... handle this unmatched argument ourselves ...
+ * }
+ * }
+ * catch (ArgParserException e)
+ * { // malformed or erroneous argument
+ * parser.printErrorAndExit (e.getMessage());
+ * }
+ * }
+ * </pre>
+ *
+ * {@link #matchArg matchArg(args,idx)} matches one option at location <code>idx</code> in the argument list, and then
+ * returns the location value that should be used for the next match. If an argument does not match any option,
+ * {@link #getUnmatchedArgument getUnmatchedArgument} will return a copy of the unmatched argument.
+ *
+ * <h3><a name="argsFromAFile">Reading Arguments From a File</a></h3>
+ *
+ * The method {@link #prependArgs prependArgs} can be used to automatically read in a set of arguments from a file and
+ * prepend them onto an existing argument list. Argument words correspond to white-space-delimited strings, and the file
+ * may contain the comment character <code>#</code> (which comments out everything to the end of the current line). A
+ * typical usage looks like this:
+ *
+ * <pre>
+ * ... create parser and add options ...
+ *
+ * args = parser.prependArgs (new File(".configFile"), args);
+ *
+ * parser.matchAllArgs (args);
+ * </pre>
+ *
+ * This makes it easy to generate simple configuration files for an application.
+ *
+ * @author John E. Lloyd, Fall 2004
+ */
+public class ArgParser {
+ Vector<Record> matchList;
+ // int tabSpacing = 8;
+ String synopsisString;
+ boolean helpOptionsEnabled = true;
+ Record defaultHelpOption = null;
+ Record firstHelpOption = null;
+ PrintStream printStream = System.out;
+ int helpIndent = 24;
+ String errMsg = null;
+ String unmatchedArg = null;
+
+ static String validConversionCodes = "iodxcbfsvh";
+
+ /**
+ * Indicates that the program should exit with an appropriate message
+ * in the event of an erroneous or malformed argument.
+ */
+ public static int EXIT_ON_ERROR = 1;
+
+ /**
+ * Indicates that the program should exit with an appropriate message
+ * in the event of an unmatched argument.
+ */
+ public static int EXIT_ON_UNMATCHED = 2;
+
+ /**
+ * Returns a string containing the valid conversion codes. These
+ * are the characters which may follow the <code>%</code> character in
+ * the specification string of {@link #addOption addOption}.
+ *
+ * @return Valid conversion codes
+ * @see #addOption
+ */
+ public static String getValidConversionCodes() {
+ return validConversionCodes;
+ }
+
+ static class NameDesc {
+ String name;
+ // oneWord implies that any value associated with
+ // option is concatenated onto the argument string itself
+ boolean oneWord;
+ NameDesc next = null;
+ }
+
+ static class RangePnt {
+ double dval = 0;
+ long lval = 0;
+ String sval = null;
+ boolean bval = true;
+ boolean closed = true;
+
+ RangePnt(String s, boolean closed) {
+ sval = s;
+ this.closed = closed;
+ }
+
+ RangePnt(double d, boolean closed) {
+ dval = d;
+ this.closed = closed;
+ }
+
+ RangePnt(long l, boolean closed) {
+ lval = l;
+ this.closed = closed;
+ }
+
+ RangePnt(boolean b, boolean closed) {
+ bval = b;
+ this.closed = closed;
+ }
+
+ RangePnt(StringScanner scanner, int type)
+ throws IllegalArgumentException {
+ String typeName = null;
+ try {
+ switch (type) {
+ case Record.CHAR: {
+ typeName = "character";
+ lval = scanner.scanChar();
+ break;
+ }
+ case Record.INT:
+ case Record.LONG: {
+ typeName = "integer";
+ lval = scanner.scanInt();
+ break;
+ }
+ case Record.FLOAT:
+ case Record.DOUBLE: {
+ typeName = "float";
+ dval = scanner.scanDouble();
+ break;
+ }
+ case Record.STRING: {
+ typeName = "string";
+ sval = scanner.scanString();
+ break;
+ }
+ case Record.BOOLEAN: {
+ typeName = "boolean";
+ bval = scanner.scanBoolean();
+ break;
+ }
+ }
+ } catch (StringScanException e) {
+ throw new IllegalArgumentException(
+ "Malformed " + typeName + " '" +
+ scanner.substring(scanner.getIndex(),
+ e.getFailIndex() + 1) +
+ "' in range spec");
+ }
+ // this.closed = closed;
+ }
+
+ void setClosed(boolean closed) {
+ this.closed = closed;
+ }
+
+ boolean getClosed() {
+ return closed;
+ }
+
+ int compareTo(double d) {
+ if (dval < d) {
+ return -1;
+ } else if (d == dval) {
+ return 0;
+ } else {
+ return 1;
+ }
+ }
+
+ int compareTo(long l) {
+ if (lval < l) {
+ return -1;
+ } else if (l == lval) {
+ return 0;
+ } else {
+ return 1;
+ }
+ }
+
+ int compareTo(String s) {
+ return sval.compareTo(s);
+ }
+
+ int compareTo(boolean b) {
+ if (b == bval) {
+ return 0;
+ } else {
+ return 1;
+ }
+ }
+
+ public String toString() {
+ return "{ dval=" + dval + ", lval=" + lval +
+ ", sval=" + sval + ", bval=" + bval +
+ ", closed=" + closed + "}";
+ }
+ }
+
+ class RangeAtom {
+ RangePnt low = null;
+ RangePnt high = null;
+ RangeAtom next = null;
+
+ RangeAtom(RangePnt p0, RangePnt p1, int type)
+ throws IllegalArgumentException {
+ int cmp = 0;
+ switch (type) {
+ case Record.CHAR:
+ case Record.INT:
+ case Record.LONG: {
+ cmp = p0.compareTo(p1.lval);
+ break;
+ }
+ case Record.FLOAT:
+ case Record.DOUBLE: {
+ cmp = p0.compareTo(p1.dval);
+ break;
+ }
+ case Record.STRING: {
+ cmp = p0.compareTo(p1.sval);
+ break;
+ }
+ }
+ if (cmp > 0) { // then switch high and low
+ low = p1;
+ high = p0;
+ } else {
+ low = p0;
+ high = p1;
+ }
+ }
+
+ RangeAtom(RangePnt p0)
+ throws IllegalArgumentException {
+ low = p0;
+ }
+
+ boolean match(double d) {
+ int lc = low.compareTo(d);
+ if (high != null) {
+ int hc = high.compareTo(d);
+ return (lc * hc < 0 ||
+ (low.closed && lc == 0) || (high.closed && hc == 0));
+ } else {
+ return lc == 0;
+ }
+ }
+
+ boolean match(long l) {
+ int lc = low.compareTo(l);
+ if (high != null) {
+ int hc = high.compareTo(l);
+ return (lc * hc < 0 ||
+ (low.closed && lc == 0) || (high.closed && hc == 0));
+ } else {
+ return lc == 0;
+ }
+ }
+
+ boolean match(String s) {
+ int lc = low.compareTo(s);
+ if (high != null) {
+ int hc = high.compareTo(s);
+ return (lc * hc < 0 ||
+ (low.closed && lc == 0) || (high.closed && hc == 0));
+ } else {
+ return lc == 0;
+ }
+ }
+
+ boolean match(boolean b) {
+ return low.compareTo(b) == 0;
+ }
+
+ public String toString() {
+ return "low=" + (low == null ? "null" : low.toString()) +
+ ", high=" + (high == null ? "null" : high.toString());
+ }
+ }
+
+ class Record {
+ NameDesc nameList;
+ static final int NOTYPE = 0;
+ static final int BOOLEAN = 1;
+ static final int CHAR = 2;
+ static final int INT = 3;
+ static final int LONG = 4;
+ static final int FLOAT = 5;
+ static final int DOUBLE = 6;
+ static final int STRING = 7;
+ int type;
+ int numValues;
+ boolean vectorResult = false;
+ boolean required = true;
+
+ String helpMsg = null;
+ String valueDesc = null;
+ String rangeDesc = null;
+ Object resHolder = null;
+ RangeAtom rangeList = null;
+ RangeAtom rangeTail = null;
+ char convertCode;
+ boolean vval = true; // default value for now
+
+ NameDesc firstNameDesc() {
+ return nameList;
+ }
+
+ RangeAtom firstRangeAtom() {
+ return rangeList;
+ }
+
+ int numRangeAtoms() {
+ int cnt = 0;
+ for (RangeAtom ra = rangeList; ra != null; ra = ra.next) {
+ cnt++;
+ }
+ return cnt;
+ }
+
+ void addRangeAtom(RangeAtom ra) {
+ if (rangeList == null) {
+ rangeList = ra;
+ } else {
+ rangeTail.next = ra;
+ }
+ rangeTail = ra;
+ }
+
+ boolean withinRange(double d) {
+ if (rangeList == null) {
+ return true;
+ }
+ for (RangeAtom ra = rangeList; ra != null; ra = ra.next) {
+ if (ra.match(d)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ boolean withinRange(long l) {
+ if (rangeList == null) {
+ return true;
+ }
+ for (RangeAtom ra = rangeList; ra != null; ra = ra.next) {
+ if (ra.match(l)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ boolean withinRange(String s) {
+ if (rangeList == null) {
+ return true;
+ }
+ for (RangeAtom ra = rangeList; ra != null; ra = ra.next) {
+ if (ra.match(s)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ boolean withinRange(boolean b) {
+ if (rangeList == null) {
+ return true;
+ }
+ for (RangeAtom ra = rangeList; ra != null; ra = ra.next) {
+ if (ra.match(b)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ String valTypeName() {
+ switch (convertCode) {
+ case 'i': {
+ return ("integer");
+ }
+ case 'o': {
+ return ("octal integer");
+ }
+ case 'd': {
+ return ("decimal integer");
+ }
+ case 'x': {
+ return ("hex integer");
+ }
+ case 'c': {
+ return ("char");
+ }
+ case 'b': {
+ return ("boolean");
+ }
+ case 'f': {
+ return ("float");
+ }
+ case 's': {
+ return ("string");
+ }
+ }
+ return ("unknown");
+ }
+
+ void scanValue(Object result, String name, String s, int resultIdx)
+ throws ArgParseException {
+ double dval = 0;
+ String sval = null;
+ long lval = 0;
+ boolean bval = false;
+
+ if (s.length() == 0) {
+ throw new ArgParseException(name, "requires a contiguous value");
+ }
+ StringScanner scanner = new StringScanner(s);
+ try {
+ switch (convertCode) {
+ case 'i': {
+ lval = scanner.scanInt();
+ break;
+ }
+ case 'o': {
+ lval = scanner.scanInt(8, false);
+ break;
+ }
+ case 'd': {
+ lval = scanner.scanInt(10, false);
+ break;
+ }
+ case 'x': {
+ lval = scanner.scanInt(16, false);
+ break;
+ }
+ case 'c': {
+ lval = scanner.scanChar();
+ break;
+ }
+ case 'b': {
+ bval = scanner.scanBoolean();
+ break;
+ }
+ case 'f': {
+ dval = scanner.scanDouble();
+ break;
+ }
+ case 's': {
+ sval = scanner.getString();
+ break;
+ }
+ }
+ } catch (StringScanException e) {
+ throw new ArgParseException(
+ name, "malformed " + valTypeName() + " '" + s + "'");
+ }
+ scanner.skipWhiteSpace();
+ if (!scanner.atEnd()) {
+ throw new ArgParseException(
+ name, "malformed " + valTypeName() + " '" + s + "'");
+ }
+ boolean outOfRange = false;
+ switch (type) {
+ case CHAR:
+ case INT:
+ case LONG: {
+ outOfRange = !withinRange(lval);
+ break;
+ }
+ case FLOAT:
+ case DOUBLE: {
+ outOfRange = !withinRange(dval);
+ break;
+ }
+ case STRING: {
+ outOfRange = !withinRange(sval);
+ break;
+ }
+ case BOOLEAN: {
+ outOfRange = !withinRange(bval);
+ break;
+ }
+ }
+ if (outOfRange) {
+ throw new ArgParseException(
+ name, "value '" + s + "' not in range " + rangeDesc);
+ }
+ if (result.getClass().isArray()) {
+ switch (type) {
+ case BOOLEAN: {
+ ((boolean[]) result)[resultIdx] = bval;
+ break;
+ }
+ case CHAR: {
+ ((char[]) result)[resultIdx] = (char) lval;
+ break;
+ }
+ case INT: {
+ ((int[]) result)[resultIdx] = (int) lval;
+ break;
+ }
+ case LONG: {
+ ((long[]) result)[resultIdx] = lval;
+ break;
+ }
+ case FLOAT: {
+ ((float[]) result)[resultIdx] = (float) dval;
+ break;
+ }
+ case DOUBLE: {
+ ((double[]) result)[resultIdx] = dval;
+ break;
+ }
+ case STRING: {
+ ((String[]) result)[resultIdx] = sval;
+ break;
+ }
+ }
+ } else {
+ switch (type) {
+ case BOOLEAN: {
+ ((BooleanHolder) result).value = bval;
+ break;
+ }
+ case CHAR: {
+ ((CharHolder) result).value = (char) lval;
+ break;
+ }
+ case INT: {
+ ((IntHolder) result).value = (int) lval;
+ break;
+ }
+ case LONG: {
+ ((LongHolder) result).value = lval;
+ break;
+ }
+ case FLOAT: {
+ ((FloatHolder) result).value = (float) dval;
+ break;
+ }
+ case DOUBLE: {
+ ((DoubleHolder) result).value = dval;
+ break;
+ }
+ case STRING: {
+ ((StringHolder) result).value = sval;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ private String firstHelpOptionName() {
+ if (firstHelpOption != null) {
+ return firstHelpOption.nameList.name;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Creates an <code>ArgParser</code> with a synopsis
+ * string, and the default help options <code>-help</code> and <code>-&#063;</code>.
+ *
+ * @param synopsisString string that briefly describes program usage,
+ * for use by {@link #getHelpMessage getHelpMessage}.
+ * @see ArgParser#getSynopsisString
+ * @see ArgParser#getHelpMessage
+ */
+ public ArgParser(String synopsisString) {
+ this(synopsisString, true);
+ }
+
+ /**
+ * Creates an <code>ArgParser</code> with a synopsis
+ * string. The help options <code>-help</code> and <code>-?</code> are added if <code>defaultHelp</code> is true.
+ *
+ * @param synopsisString string that briefly describes program usage,
+ * for use by {@link #getHelpMessage getHelpMessage}.
+ * @param defaultHelp if true, adds the default help options
+ * @see ArgParser#getSynopsisString
+ * @see ArgParser#getHelpMessage
+ */
+ public ArgParser(String synopsisString, boolean defaultHelp) {
+ matchList = new Vector<Record>(128);
+ this.synopsisString = synopsisString;
+ if (defaultHelp) {
+ addOption("-help,-? %h #displays help information", null);
+ defaultHelpOption = firstHelpOption = matchList.get(0);
+ }
+ }
+
+ /**
+ * Returns the synopsis string used by the parser.
+ * The synopsis string is a short description of how to invoke
+ * the program, and usually looks something like
+ * <p>
+ * <prec> "java somepackage.SomeClass [options] files ..." </prec>
+ *
+ * <p>
+ * It is used in help and error messages.
+ *
+ * @return synopsis string
+ * @see ArgParser#setSynopsisString
+ * @see ArgParser#getHelpMessage
+ */
+ public String getSynopsisString() {
+ return synopsisString;
+ }
+
+ /**
+ * Sets the synopsis string used by the parser.
+ *
+ * @param s new synopsis string
+ * @see ArgParser#getSynopsisString
+ * @see ArgParser#getHelpMessage
+ */
+ public void setSynopsisString(String s) {
+ synopsisString = s;
+ }
+
+ /**
+ * Indicates whether or not help options are enabled.
+ *
+ * @return true if help options are enabled
+ * @see ArgParser#setHelpOptionsEnabled
+ * @see ArgParser#addOption
+ */
+ public boolean getHelpOptionsEnabled() {
+ return helpOptionsEnabled;
+ }
+
+ /**
+ * Enables or disables help options. Help options are those
+ * associated with a conversion code of <code>%h</code>. If
+ * help options are enabled, and a help option is matched,
+ * then the string produced by {@link #getHelpMessage getHelpMessage} is printed to the default print stream and the
+ * program
+ * exits with code 0. Otherwise, arguments which match help
+ * options are ignored.
+ *
+ * @param enable enables help options if <code>true</code>.
+ * @see ArgParser#getHelpOptionsEnabled
+ * @see ArgParser#addOption
+ * @see ArgParser#setDefaultPrintStream
+ */
+ public void setHelpOptionsEnabled(boolean enable) {
+ helpOptionsEnabled = enable;
+ }
+
+ /**
+ * Returns the default print stream used for outputting help
+ * and error information.
+ *
+ * @return default print stream
+ * @see ArgParser#setDefaultPrintStream
+ */
+ public PrintStream getDefaultPrintStream() {
+ return printStream;
+ }
+
+ /**
+ * Sets the default print stream used for outputting help
+ * and error information.
+ *
+ * @param stream new default print stream
+ * @see ArgParser#getDefaultPrintStream
+ */
+ public void setDefaultPrintStream(PrintStream stream) {
+ printStream = stream;
+ }
+
+ /**
+ * Gets the indentation used by {@link #getHelpMessage
+ * getHelpMessage}.
+ *
+ * @return number of indentation columns
+ * @see ArgParser#setHelpIndentation
+ * @see ArgParser#getHelpMessage
+ */
+ public int getHelpIndentation() {
+ return helpIndent;
+ }
+
+ /**
+ * Sets the indentation used by {@link #getHelpMessage
+ * getHelpMessage}. This is the number of columns that an option's help
+ * information is indented. If the option's name and value information
+ * can fit within this number of columns, then all information about
+ * the option is placed on one line. Otherwise, the indented help
+ * information is placed on a separate line.
+ *
+ * @param indent number of indentation columns
+ * @see ArgParser#getHelpIndentation
+ * @see ArgParser#getHelpMessage
+ */
+ public void setHelpIndentation(int indent) {
+ helpIndent = indent;
+ }
+
+ // public void setTabSpacing (int n)
+ // { tabSpacing = n;
+ // }
+
+ // public int getTabSpacing ()
+ // { return tabSpacing;
+ // }
+
+ private void scanRangeSpec(Record rec, String s)
+ throws IllegalArgumentException {
+ StringScanner scanner = new StringScanner(s);
+ char c, c0, c1;
+
+ scanner.setStringDelimiters(")],}");
+ c = scanner.getc(); // swallow the first '{'
+ scanner.skipWhiteSpace();
+ while ((c = scanner.peekc()) != '}') {
+ RangePnt p0, p1;
+
+ if (c == '[' || c == '(') {
+ if (rec.convertCode == 'v' || rec.convertCode == 'b') {
+ throw new IllegalArgumentException("Sub ranges not supported for %b or %v");
+ }
+ c0 = scanner.getc(); // record & swallow character
+ scanner.skipWhiteSpace();
+ p0 = new RangePnt(scanner, rec.type);
+ scanner.skipWhiteSpace();
+ if (scanner.getc() != ',') {
+ throw new IllegalArgumentException("Missing ',' in subrange specification");
+ }
+ p1 = new RangePnt(scanner, rec.type);
+ scanner.skipWhiteSpace();
+ if ((c1 = scanner.getc()) != ']' && c1 != ')') {
+ throw new IllegalArgumentException("Unterminated subrange");
+ }
+ if (c0 == '(') {
+ p0.setClosed(false);
+ }
+ if (c1 == ')') {
+ p1.setClosed(false);
+ }
+ rec.addRangeAtom(new RangeAtom(p0, p1, rec.type));
+ } else {
+ scanner.skipWhiteSpace();
+ p0 = new RangePnt(scanner, rec.type);
+ rec.addRangeAtom(new RangeAtom(p0));
+ }
+ scanner.skipWhiteSpace();
+ if ((c = scanner.peekc()) == ',') {
+ scanner.getc();
+ scanner.skipWhiteSpace();
+ } else if (c != '}') {
+ throw new IllegalArgumentException("Range spec: ',' or '}' expected");
+ }
+ }
+ if (rec.numRangeAtoms() == 1) {
+ rec.rangeDesc = s.substring(1, s.length() - 1);
+ } else {
+ rec.rangeDesc = s;
+ }
+ }
+
+ private int defaultResultType(char convertCode) {
+ switch (convertCode) {
+ case 'i':
+ case 'o':
+ case 'd':
+ case 'x': {
+ return Record.LONG;
+ }
+ case 'c': {
+ return Record.CHAR;
+ }
+ case 'v':
+ case 'b': {
+ return Record.BOOLEAN;
+ }
+ case 'f': {
+ return Record.DOUBLE;
+ }
+ case 's': {
+ return Record.STRING;
+ }
+ }
+ return Record.NOTYPE;
+ }
+
+ /**
+ * Adds a new option description to the parser. The method takes two
+ * arguments: a specification string, and a result holder in which to
+ * store the associated value.
+ *
+ * <p>
+ * The specification string has the general form
+ *
+ * <p>
+ * <var>optionNames</var> <code>%</code><var>conversionCode</var> [<code>{</code><var>rangeSpec</var><code>}</code>]
+ * [<code>X</code><var>multiplier</var>] [<code>#</code><var>valueDescription</var>] [<code>#</code>
+ * <var>optionDescription</var>] </code>
+ *
+ * <p>
+ * where
+ * <ul>
+ * <p>
+ * <li><var>optionNames</var> is a comma-separated list of names for the option (such as <code>-f, --file</code>).
+ *
+ * <p>
+ * <li><var>conversionCode</var> is a single letter, following a <code>%</code> character, specifying information
+ * about what value the option requires:
+ *
+ * <table>
+ * <tr>
+ * <td><code>%f</code></td>
+ * <td>a floating point number</td>
+ * <tr>
+ * <td><code>%i</code></td>
+ * <td>an integer, in either decimal, hex (if preceeded by <code>0x</code>), or octal (if preceeded by
+ * <code>0</code>)</td>
+ * <tr valign=top>
+ * <td><code>%d</code></td>
+ * <td>a decimal integer</td>
+ * <tr valign=top>
+ * <td><code>%o</code></td>
+ * <td>an octal integer</td>
+ * <tr valign=top>
+ * <td><code>%h</code></td>
+ * <td>a hex integer (without the preceeding <code>0x</code>)</td>
+ * <tr valign=top>
+ * <td><code>%c</code></td>
+ * <td>a single character, including escape sequences (such as <code>\n</code> or <code>\007</code>), and optionally
+ * enclosed in single quotes
+ * <tr valign=top>
+ * <td><code>%b</code></td>
+ * <td>a boolean value (<code>true</code> or <code>false</code>)</td>
+ * <tr valign=top>
+ * <td><code>%s</code></td>
+ * <td>a string. This will be the argument string itself (or its remainder, in the case of a single word option)</td>
+ * <tr valign=top>
+ * <td><code>%v</code></td>
+ * <td>no explicit value is expected, but a boolean value of <code>true</code> (by default) will be stored into the
+ * associated result holder if this option is matched. If one wishes to have a value of <code>false</code> stored
+ * instead, then the <code>%v</code> should be followed by a "range spec" containing <code>false</code>, as in
+ * <code>%v{false}</code>.
+ * </table>
+ *
+ * <p>
+ * <li><var>rangeSpec</var> is an optional range specification, placed inside curly braces, consisting of a
+ * comma-separated list of range items each specifying permissible values for the option. A range item may be an
+ * individual value, or it may itself be a subrange, consisting of two individual values, separated by a comma, and
+ * enclosed in square or round brackets. Square and round brackets denote closed and open endpoints of a subrange,
+ * indicating that the associated endpoint value is included or excluded from the subrange. The values specified in
+ * the range spec need to be consistent with the type of value expected by the option.
+ *
+ * <p>
+ * <b>Examples:</b>
+ *
+ * <p>
+ * A range spec of <code>{2,4,8,16}</code> for an integer value will allow the integers 2, 4, 8, or 16.
+ *
+ * <p>
+ * A range spec of <code>{[-1.0,1.0]}</code> for a floating point value will allow any floating point number in the
+ * range -1.0 to 1.0.
+ *
+ * <p>
+ * A range spec of <code>{(-88,100],1000}</code> for an integer value will allow values > -88 and <= 100, as well as
+ * 1000.
+ *
+ * <p>
+ * A range spec of <code>{"foo", "bar", ["aaa","zzz")} </code> for a string value will allow strings equal to
+ * <code>"foo"</code> or <code>"bar"</code>, plus any string lexically greater than or equal to <code>"aaa"</code>
+ * but less then <code>"zzz"</code>.
+ *
+ * <p>
+ * <li><var>multiplier</var> is an optional integer, following a <code>X</code> character, indicating the number of
+ * values which the option expects. If the multiplier is not specified, it is assumed to be 1. If the multiplier
+ * value is greater than 1, then the result holder should be either an array (of appropriate type) with a length
+ * greater than or equal to the multiplier value, or a <code>java.util.Vector</code> <a href=#vectorHolder>as
+ * discussed below</a>.
+ *
+ * <p>
+ * <li><var>valueDescription</var> is an optional description of the option's value requirements, and consists of
+ * all characters between two <code>#</code> characters. The final <code>#</code> character initiates the <i>option
+ * description</i>, which may be empty. The value description is used in <a href=#helpInfo>generating help
+ * messages</a>.
+ *
+ * <p>
+ * <li><var>optionDescription</var> is an optional description of the option itself, consisting of all characters
+ * between a <code>#</code> character and the end of the specification string. The option description is used in <a
+ * href=#helpInfo>generating help messages</a>.
+ * </ul>
+ *
+ * <p>
+ * The result holder must be an object capable of holding a value compatible with the conversion code, or it must be
+ * a <code>java.util.Vector</code>. When the option is matched, its associated value is placed in the result holder.
+ * If the same option is matched repeatedly, the result holder value will be overwritten, unless the result holder
+ * is a <code>java.util.Vector</code>, in which case new holder objects for each match will be allocated and added
+ * to the vector. Thus if multiple instances of an option are desired by the program, the result holder should be a
+ * <code>java.util.Vector</code>.
+ *
+ * <p>
+ * If the result holder is not a <code>Vector</code>, then it must correspond as follows to the conversion code:
+ *
+ * <table>
+ * <tr valign=top>
+ * <td><code>%i</code>, <code>%d</code>, <code>%x</code>, <code>%o</code></td>
+ * <td>{@link argparser.IntHolder IntHolder}, {@link argparser.LongHolder LongHolder}, <code>int[]</code>, or
+ * <code>long[]</code></td>
+ * </tr>
+ *
+ * <tr valign=top>
+ * <td><code>%f</code></td>
+ * <td>{@link argparser.FloatHolder FloatHolder}, {@link argparser.DoubleHolder DoubleHolder}, <code>float[]</code>,
+ * or <code>double[]</code></td>
+ * </tr>
+ *
+ * <tr valign=top>
+ * <td><code>%b</code>, <code>%v</code></td>
+ * <td>{@link argparser.BooleanHolder BooleanHolder} or <code>boolean[]</code></td>
+ * </tr>
+ *
+ * <tr valign=top>
+ * <td><code>%s</code></td>
+ * <td>{@link argparser.StringHolder StringHolder} or <code>String[]</code></td>
+ * </tr>
+ *
+ * <tr valign=top>
+ * <td><code>%c</code></td>
+ * <td>{@link argparser.CharHolder CharHolder} or <code>char[]</code></td>
+ * </tr>
+ * </table>
+ *
+ * <p>
+ * In addition, if the multiplier is greater than 1, then only the array type indicated above may be used, and the
+ * array must be at least as long as the multiplier.
+ *
+ * <p>
+ * <a name=vectorHolder>If the result holder is a <code>Vector</code>, then the system will create an appropriate
+ * result holder object and add it to the vector. Multiple occurances of the option will cause multiple results to
+ * be added to the vector.
+ *
+ * <p>
+ * The object allocated by the system to store the result will correspond to the conversion code as follows:
+ *
+ * <table>
+ * <tr valign=top>
+ * <td><code>%i</code>, <code>%d</code>, <code>%x</code>, <code>%o</code></td>
+ * <td>{@link argparser.LongHolder LongHolder}, or <code>long[]</code> if the multiplier value exceeds 1</td>
+ * </tr>
+ *
+ * <tr valign=top>
+ * <td><code>%f</code></td>
+ * <td>{@link argparser.DoubleHolder DoubleHolder}, or <code>double[]</code> if the multiplier value exceeds 1</td>
+ * </tr>
+ *
+ * <tr valign=top>
+ * <td><code>%b</code>, <code>%v</code></td>
+ * <td>{@link argparser.BooleanHolder BooleanHolder}, or <code>boolean[]</code> if the multiplier value exceeds 1</td>
+ * </tr>
+ *
+ * <tr valign=top>
+ * <td><code>%s</code></td>
+ * <td>{@link argparser.StringHolder StringHolder}, or <code>String[]</code> if the multiplier value exceeds 1</td>
+ * </tr>
+ *
+ * <tr valign=top>
+ * <td><code>%c</code></td>
+ * <td>{@link argparser.CharHolder CharHolder}, or <code>char[]</code> if the multiplier value exceeds 1</td>
+ * </tr>
+ * </table>
+ *
+ * @param spec the specification string
+ * @param resHolder object in which to store the associated
+ * value
+ * @throws IllegalArgumentException if there is an error in
+ * the specification or if the result holder is of an invalid
+ * type.
+ */
+ public void addOption(String spec, Object resHolder)
+ throws IllegalArgumentException {
+ // null terminated string is easier to parse
+ StringScanner scanner = new StringScanner(spec);
+ Record rec = null;
+ NameDesc nameTail = null;
+ NameDesc ndesc;
+ int i0, i1;
+ char c;
+
+ do {
+ ndesc = new NameDesc();
+ boolean nameEndsInWhiteSpace = false;
+
+ scanner.skipWhiteSpace();
+ i0 = scanner.getIndex();
+ while (!Character.isWhitespace(c = scanner.getc()) &&
+ c != ',' && c != '%' && c != '\000')
+ ;
+ i1 = scanner.getIndex();
+ if (c != '\000') {
+ i1--;
+ }
+ if (i0 == i1) { // then c is one of ',' '%' or '\000'
+ throw new IllegalArgumentException("Null option name given");
+ }
+ if (Character.isWhitespace(c)) {
+ nameEndsInWhiteSpace = true;
+ scanner.skipWhiteSpace();
+ c = scanner.getc();
+ }
+ if (c == '\000') {
+ throw new IllegalArgumentException("No conversion character given");
+ }
+ if (c != ',' && c != '%') {
+ throw new IllegalArgumentException("Names not separated by ','");
+ }
+ ndesc.name = scanner.substring(i0, i1);
+ if (rec == null) {
+ rec = new Record();
+ rec.nameList = ndesc;
+ } else {
+ nameTail.next = ndesc;
+ }
+ nameTail = ndesc;
+ ndesc.oneWord = !nameEndsInWhiteSpace;
+ } while (c != '%');
+
+ if (!nameTail.oneWord) {
+ for (ndesc = rec.nameList; ndesc != null; ndesc = ndesc.next) {
+ ndesc.oneWord = false;
+ }
+ }
+ c = scanner.getc();
+ if (c == '\000') {
+ throw new IllegalArgumentException("No conversion character given");
+ }
+ if (validConversionCodes.indexOf(c) == -1) {
+ throw new IllegalArgumentException("Conversion code '" + c + "' not one of '" +
+ validConversionCodes + "'");
+ }
+ rec.convertCode = c;
+
+ if (resHolder instanceof Vector) {
+ rec.vectorResult = true;
+ rec.type = defaultResultType(rec.convertCode);
+ } else {
+ switch (rec.convertCode) {
+ case 'i':
+ case 'o':
+ case 'd':
+ case 'x': {
+ if (resHolder instanceof LongHolder ||
+ resHolder instanceof long[]) {
+ rec.type = Record.LONG;
+ } else if (resHolder instanceof IntHolder ||
+ resHolder instanceof int[]) {
+ rec.type = Record.INT;
+ } else {
+ throw new IllegalArgumentException(
+ "Invalid result holder for %" + c);
+ }
+ break;
+ }
+ case 'c': {
+ if (!(resHolder instanceof CharHolder) &&
+ !(resHolder instanceof char[])) {
+ throw new IllegalArgumentException(
+ "Invalid result holder for %c");
+ }
+ rec.type = Record.CHAR;
+ break;
+ }
+ case 'v':
+ case 'b': {
+ if (!(resHolder instanceof BooleanHolder) &&
+ !(resHolder instanceof boolean[])) {
+ throw new IllegalArgumentException(
+ "Invalid result holder for %" + c);
+ }
+ rec.type = Record.BOOLEAN;
+ break;
+ }
+ case 'f': {
+ if (resHolder instanceof DoubleHolder ||
+ resHolder instanceof double[]) {
+ rec.type = Record.DOUBLE;
+ } else if (resHolder instanceof FloatHolder ||
+ resHolder instanceof float[]) {
+ rec.type = Record.FLOAT;
+ } else {
+ throw new IllegalArgumentException(
+ "Invalid result holder for %f");
+ }
+ break;
+ }
+ case 's': {
+ if (!(resHolder instanceof StringHolder) &&
+ !(resHolder instanceof String[])) {
+ throw new IllegalArgumentException(
+ "Invalid result holder for %s");
+ }
+ rec.type = Record.STRING;
+ break;
+ }
+ case 'h': { // resHolder is ignored for this type
+ break;
+ }
+ }
+ }
+ if (rec.convertCode == 'h') {
+ rec.resHolder = null;
+ } else {
+ rec.resHolder = resHolder;
+ }
+
+ scanner.skipWhiteSpace();
+ // get the range specification, if any
+ if (scanner.peekc() == '{') {
+ if (rec.convertCode == 'h') {
+ throw new IllegalArgumentException("Ranges not supported for %h");
+ }
+ // int bcnt = 0;
+ i0 = scanner.getIndex(); // beginning of range spec
+ do {
+ c = scanner.getc();
+ if (c == '\000') {
+ throw new IllegalArgumentException("Unterminated range specification");
+ }
+ // else if (c=='[' || c=='(')
+ // { bcnt++;
+ // }
+ // else if (c==']' || c==')')
+ // { bcnt--;
+ // }
+ // if ((rec.convertCode=='v'||rec.convertCode=='b') && bcnt>1)
+ // { throw new IllegalArgumentException
+ // ("Sub ranges not supported for %b or %v");
+ // }
+ } while (c != '}');
+ // if (c != ']')
+ // { throw new IllegalArgumentException
+ // ("Range specification must end with ']'");
+ // }
+ i1 = scanner.getIndex(); // end of range spec
+ scanRangeSpec(rec, scanner.substring(i0, i1));
+ if (rec.convertCode == 'v' && rec.rangeList != null) {
+ rec.vval = rec.rangeList.low.bval;
+ }
+ }
+ // check for value multiplicity information, if any
+ if (scanner.peekc() == 'X') {
+ if (rec.convertCode == 'h') {
+ throw new IllegalArgumentException("Multipliers not supported for %h");
+ }
+ scanner.getc();
+ try {
+ rec.numValues = (int) scanner.scanInt();
+ } catch (StringScanException e) {
+ throw new IllegalArgumentException("Malformed value multiplier");
+ }
+ if (rec.numValues <= 0) {
+ throw new IllegalArgumentException("Value multiplier number must be > 0");
+ }
+ } else {
+ rec.numValues = 1;
+ }
+ if (rec.numValues > 1) {
+ for (ndesc = rec.nameList; ndesc != null; ndesc = ndesc.next) {
+ if (ndesc.oneWord) {
+ throw new IllegalArgumentException(
+ "Multiplier value incompatible with one word option " + ndesc.name);
+ }
+ }
+ }
+ if (resHolder != null && resHolder.getClass().isArray()) {
+ if (Array.getLength(resHolder) < rec.numValues) {
+ throw new IllegalArgumentException(
+ "Result holder array must have a length >= " + rec.numValues);
+ }
+ } else {
+ if (rec.numValues > 1 && !(resHolder instanceof Vector)) {
+ throw new IllegalArgumentException(
+ "Multiplier requires result holder to be an array of length >= "
+ + rec.numValues);
+ }
+ }
+
+ // skip white space following conversion information
+ scanner.skipWhiteSpace();
+
+ // get the help message, if any
+
+ if (!scanner.atEnd()) {
+ if (scanner.getc() != '#') {
+ throw new IllegalArgumentException("Illegal character(s), expecting '#'");
+ }
+ String helpInfo = scanner.substring(scanner.getIndex());
+ // look for second '#'. If there is one, then info
+ // between the first and second '#' is the value descriptor.
+ int k = helpInfo.indexOf("#");
+ if (k != -1) {
+ rec.valueDesc = helpInfo.substring(0, k);
+ rec.helpMsg = helpInfo.substring(k + 1);
+ } else {
+ rec.helpMsg = helpInfo;
+ }
+ } else {
+ rec.helpMsg = "";
+ }
+
+ // parse helpMsg for required/optional information if present
+ // default to required
+ if (rec.helpMsg.indexOf("(optional") != -1) {
+ rec.required = false;
+ }
+
+ // add option information to match list
+ if (rec.convertCode == 'h' && firstHelpOption == defaultHelpOption) {
+ matchList.remove(defaultHelpOption);
+ firstHelpOption = rec;
+ }
+ matchList.add(rec);
+ }
+
+ Record lastMatchRecord() {
+ return (Record) matchList.lastElement();
+ }
+
+ private Record getRecord(String arg, ObjectHolder ndescHolder) {
+ NameDesc ndesc;
+ for (int i = 0; i < matchList.size(); i++) {
+ Record rec = (Record) matchList.get(i);
+ for (ndesc = rec.nameList; ndesc != null; ndesc = ndesc.next) {
+ if (rec.convertCode != 'v' && ndesc.oneWord) {
+ if (arg.startsWith(ndesc.name)) {
+ if (ndescHolder != null) {
+ ndescHolder.value = ndesc;
+ }
+ return rec;
+ }
+ } else {
+ if (arg.equals(ndesc.name)) {
+ if (ndescHolder != null) {
+ ndescHolder.value = ndesc;
+ }
+ return rec;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ public void checkRequiredArgs() {
+ for (int i = 1; i < matchList.size(); i++) {
+ Record rec = (Record) matchList.get(i);
+ StringHolder myString = (StringHolder) rec.resHolder;
+ if (((myString.value == null) || (myString.value.equals(""))) && (rec.required)) {
+ printErrorAndExit("Required parameter " + rec.nameList.name + " is not specified.");
+ }
+ }
+ }
+
+ Object getResultHolder(String arg) {
+ Record rec = getRecord(arg, null);
+ return (rec != null) ? rec.resHolder : null;
+ }
+
+ String getOptionName(String arg) {
+ ObjectHolder ndescHolder = new ObjectHolder();
+ Record rec = getRecord(arg, ndescHolder);
+ return (rec != null) ? ((NameDesc) ndescHolder.value).name : null;
+ }
+
+ String getOptionRangeDesc(String arg) {
+ Record rec = getRecord(arg, null);
+ return (rec != null) ? rec.rangeDesc : null;
+ }
+
+ String getOptionTypeName(String arg) {
+ Record rec = getRecord(arg, null);
+ return (rec != null) ? rec.valTypeName() : null;
+ }
+
+ private Object createResultHolder(Record rec) {
+ if (rec.numValues == 1) {
+ switch (rec.type) {
+ case Record.LONG: {
+ return new LongHolder();
+ }
+ case Record.CHAR: {
+ return new CharHolder();
+ }
+ case Record.BOOLEAN: {
+ return new BooleanHolder();
+ }
+ case Record.DOUBLE: {
+ return new DoubleHolder();
+ }
+ case Record.STRING: {
+ return new StringHolder();
+ }
+ }
+ } else {
+ switch (rec.type) {
+ case Record.LONG: {
+ return new long[rec.numValues];
+ }
+ case Record.CHAR: {
+ return new char[rec.numValues];
+ }
+ case Record.BOOLEAN: {
+ return new boolean[rec.numValues];
+ }
+ case Record.DOUBLE: {
+ return new double[rec.numValues];
+ }
+ case Record.STRING: {
+ return new String[rec.numValues];
+ }
+ }
+ }
+ return null; // can't happen
+ }
+
+ static void stringToArgs(Vector<String> vec, String s,
+ boolean allowQuotedStrings)
+ throws StringScanException {
+ StringScanner scanner = new StringScanner(s);
+ scanner.skipWhiteSpace();
+ while (!scanner.atEnd()) {
+ if (allowQuotedStrings) {
+ vec.add(scanner.scanString());
+ } else {
+ vec.add(scanner.scanNonWhiteSpaceString());
+ }
+ scanner.skipWhiteSpace();
+ }
+ }
+
+ /**
+ * Reads in a set of strings from a reader and prepends them to an
+ * argument list. Strings are delimited by either whitespace or
+ * double quotes <code>"</code>. The character <code>#</code> acts as
+ * a comment character, causing input to the end of the current line to
+ * be ignored.
+ *
+ * @param reader Reader from which to read the strings
+ * @param args Initial set of argument values. Can be
+ * specified as <code>null</code>.
+ * @throws IOException if an error occured while reading.
+ */
+ public static String[] prependArgs(Reader reader, String[] args)
+ throws IOException {
+ if (args == null) {
+ args = new String[0];
+ }
+ LineNumberReader lineReader = new LineNumberReader(reader);
+ Vector<String> vec = new Vector<String>(100, 100);
+ String line;
+ int i, k;
+
+ while ((line = lineReader.readLine()) != null) {
+ int commentIdx = line.indexOf("#");
+ if (commentIdx != -1) {
+ line = line.substring(0, commentIdx);
+ }
+ try {
+ stringToArgs(vec, line, /*allowQuotedStings=*/true);
+ } catch (StringScanException e) {
+ throw new IOException(
+ "malformed string, line " + lineReader.getLineNumber());
+ }
+ }
+ String[] result = new String[vec.size() + args.length];
+ for (i = 0; i < vec.size(); i++) {
+ result[i] = (String) vec.get(i);
+ }
+ for (k = 0; k < args.length; k++) {
+ result[i++] = args[k];
+ }
+ return result;
+ }
+
+ /**
+ * Reads in a set of strings from a file and prepends them to an
+ * argument list. Strings are delimited by either whitespace or double
+ * quotes <code>"</code>. The character <code>#</code> acts as a
+ * comment character, causing input to the end of the current line to
+ * be ignored.
+ *
+ * @param file File to be read
+ * @param args Initial set of argument values. Can be
+ * specified as <code>null</code>.
+ * @throws IOException if an error occured while reading the file.
+ */
+ public static String[] prependArgs(File file, String[] args)
+ throws IOException {
+ if (args == null) {
+ args = new String[0];
+ }
+ if (!file.canRead()) {
+ return args;
+ }
+ try {
+ return prependArgs(new FileReader(file), args);
+ } catch (IOException e) {
+ throw new IOException(
+ "File " + file.getName() + ": " + e.getMessage());
+ }
+ }
+
+ /**
+ * Sets the parser's error message.
+ *
+ * @param s Error message
+ */
+ protected void setError(String msg) {
+ errMsg = msg;
+ }
+
+ /**
+ * Prints an error message, along with a pointer to help options,
+ * if available, and causes the program to exit with code 1.
+ */
+ public void printErrorAndExit(String msg) {
+ if (helpOptionsEnabled && firstHelpOptionName() != null) {
+ msg += "\nUse " + firstHelpOptionName() + " for help information";
+ }
+ if (printStream != null) {
+ printStream.println(msg);
+ }
+ System.exit(1);
+ }
+
+ /**
+ * Matches arguments within an argument list.
+ *
+ * <p>
+ * In the event of an erroneous or unmatched argument, the method prints a message and exits the program with code
+ * 1.
+ *
+ * <p>
+ * If help options are enabled and one of the arguments matches a help option, then the result of
+ * {@link #getHelpMessage
+ * getHelpMessage} is printed to the default print stream and the program exits with code 0. If help options are not
+ * enabled, they are ignored.
+ *
+ * @param args argument list
+ * @see ArgParser#getDefaultPrintStream
+ */
+ public void matchAllArgs(String[] args) {
+ matchAllArgs(args, 0, EXIT_ON_UNMATCHED | EXIT_ON_ERROR);
+ }
+
+ /**
+ * Matches arguments within an argument list and returns
+ * those which were not matched. The matching starts at a location
+ * in <code>args</code> specified by <code>idx</code>, and
+ * unmatched arguments are returned in a String array.
+ *
+ * <p>
+ * In the event of an erroneous argument, the method either prints a message and exits the program (if
+ * {@link #EXIT_ON_ERROR} is set in <code>exitFlags</code>) or terminates the matching and creates a error message
+ * that can be retrieved by {@link #getErrorMessage}.
+ *
+ * <p>
+ * In the event of an umatched argument, the method will print a message and exit if {@link #EXIT_ON_UNMATCHED} is
+ * set in <code>errorFlags</code>. Otherwise, the unmatched argument will be appended to the returned array of
+ * unmatched values, and the matching will continue at the next location.
+ *
+ * <p>
+ * If help options are enabled and one of the arguments matches a help option, then the result of
+ * {@link #getHelpMessage
+ * getHelpMessage} is printed to the the default print stream and the program exits with code 0. If help options are
+ * not enabled, then they will not be matched.
+ *
+ * @param args argument list
+ * @param idx starting location in list
+ * @param exitFlags conditions causing the program to exit. Should be
+ * an or-ed combintion of {@link #EXIT_ON_ERROR} or {@link #EXIT_ON_UNMATCHED}.
+ * @return array of arguments that were not matched, or <code>null</code> if all arguments were successfully matched
+ * @see ArgParser#getErrorMessage
+ * @see ArgParser#getDefaultPrintStream
+ */
+ public String[] matchAllArgs(String[] args, int idx, int exitFlags) {
+ Vector<String> unmatched = new Vector<String>(10);
+
+ while (idx < args.length) {
+ try {
+ idx = matchArg(args, idx);
+ if (unmatchedArg != null) {
+ if ((exitFlags & EXIT_ON_UNMATCHED) != 0) {
+ printErrorAndExit("Unrecognized argument: " + unmatchedArg);
+ } else {
+ unmatched.add(unmatchedArg);
+ }
+ }
+ } catch (ArgParseException e) {
+ if ((exitFlags & EXIT_ON_ERROR) != 0) {
+ printErrorAndExit(e.getMessage());
+ }
+ break;
+ }
+ }
+ if (unmatched.size() == 0) {
+ return null;
+ } else {
+ return (String[]) unmatched.toArray(new String[0]);
+ }
+ }
+
+ /**
+ * Matches one option starting at a specified location in an argument
+ * list. The method returns the location in the list where the next
+ * match should begin.
+ *
+ * <p>
+ * In the event of an erroneous argument, the method throws an {@link argparser.ArgParseException ArgParseException}
+ * with an appropriate error message. This error message can also be retrieved using {@link #getErrorMessage
+ * getErrorMessage}.
+ *
+ * <p>
+ * In the event of an umatched argument, the method will return idx + 1, and {@link #getUnmatchedArgument
+ * getUnmatchedArgument} will return a copy of the unmatched argument. If an argument is matched,
+ * {@link #getUnmatchedArgument getUnmatchedArgument} will return <code>null</code>.
+ *
+ * <p>
+ * If help options are enabled and the argument matches a help option, then the result of {@link #getHelpMessage
+ * getHelpMessage} is printed to the the default print stream and the program exits with code 0. If help options are
+ * not enabled, then they are ignored.
+ *
+ * @param args argument list
+ * @param idx location in list where match should start
+ * @return location in list where next match should start
+ * @throws ArgParseException if there was an error performing
+ * the match (such as improper or insufficient values).
+ * @see ArgParser#setDefaultPrintStream
+ * @see ArgParser#getHelpOptionsEnabled
+ * @see ArgParser#getErrorMessage
+ * @see ArgParser#getUnmatchedArgument
+ */
+ @SuppressWarnings("unchecked")
+ public int matchArg(String[] args, int idx)
+ throws ArgParseException {
+ unmatchedArg = null;
+ setError(null);
+ try {
+ ObjectHolder ndescHolder = new ObjectHolder();
+ Record rec = getRecord(args[idx], ndescHolder);
+ if (rec == null || (rec.convertCode == 'h' && !helpOptionsEnabled)) { // didn't match
+ unmatchedArg = new String(args[idx]);
+ return idx + 1;
+ }
+ NameDesc ndesc = (NameDesc) ndescHolder.value;
+ Object result;
+ if (rec.resHolder instanceof Vector) {
+ result = createResultHolder(rec);
+ } else {
+ result = rec.resHolder;
+ }
+ if (rec.convertCode == 'h') {
+ if (helpOptionsEnabled) {
+ printStream.println(getHelpMessage());
+ System.exit(0);
+ } else {
+ return idx + 1;
+ }
+ } else if (rec.convertCode != 'v') {
+ if (ndesc.oneWord) {
+ rec.scanValue(
+ result, ndesc.name,
+ args[idx].substring(ndesc.name.length()), 0);
+ } else {
+ if (idx + rec.numValues >= args.length) {
+ throw new ArgParseException(
+ ndesc.name, "requires " + rec.numValues + " value" +
+ (rec.numValues > 1 ? "s" : ""));
+ }
+ for (int k = 0; k < rec.numValues; k++) {
+ rec.scanValue(result, ndesc.name, args[++idx], k);
+ }
+ }
+ } else {
+ if (rec.resHolder instanceof BooleanHolder) {
+ ((BooleanHolder) result).value = rec.vval;
+ } else {
+ for (int k = 0; k < rec.numValues; k++) {
+ ((boolean[]) result)[k] = rec.vval;
+ }
+ }
+ }
+ if (rec.resHolder instanceof Vector) {
+ ((Vector<Object>) rec.resHolder).add(result);
+ }
+ } catch (ArgParseException e) {
+ setError(e.getMessage());
+ throw e;
+ }
+ return idx + 1;
+ }
+
+ private String spaceString(int n) {
+ StringBuffer sbuf = new StringBuffer(n);
+ for (int i = 0; i < n; i++) {
+ sbuf.append(' ');
+ }
+ return sbuf.toString();
+ }
+
+ // public String getShortHelpMessage ()
+ // {
+ // String s;
+ // Record rec;
+ // NameDesc ndesc;
+ // int initialIndent = 8;
+ // int col = initialIndent;
+
+ // if (maxcols <= 0)
+ // { maxcols = 80;
+ // }
+ // if (matchList.size() > 0)
+ // { ps.print (spaceString(initialIndent));
+ // }
+ // for (int i=0; i<matchList.size(); i++)
+ // { rec = (Record)matchList.get(i);
+ // s = "[";
+ // for (ndesc=rec.nameList; ndesc!=null; ndesc=ndesc.next)
+ // { s = s + ndesc.name;
+ // if (ndesc.oneWord == false)
+ // { s = s + " ";
+ // }
+ // if (ndesc.next != null)
+ // { s = s + ",";
+ // }
+ // }
+ // if (rec.convertCode != 'v' && rec.convertCode != 'h')
+ // { if (rec.valueDesc != null)
+ // { s += rec.valueDesc;
+ // }
+ // else
+ // { s = s + "<" + rec.valTypeName() + ">";
+ // if (rec.numValues > 1)
+ // { s += "X" + rec.numValues;
+ // }
+ // }
+ // }
+ // s = s + "]";
+ // /*
+ // (col+=s.length()) > (maxcols-1) => we will spill over edge.
+ // we use (maxcols-1) because if we go right to the edge
+ // (maxcols), we get wrap new line inserted "for us".
+ // i != 0 means we print the first entry, no matter
+ // how long it is. Subsequent entries are printed
+ // full length anyway. */
+
+ // if ((col+=s.length()) > (maxcols-1) && i != 0)
+ // { col = initialIndent+s.length();
+ // ps.print ("\n" + spaceString(initialIndent));
+ // }
+ // ps.print (s);
+ // }
+ // if (matchList.size() > 0)
+ // { ps.print ('\n');
+ // ps.flush();
+ // }
+ // }
+
+ /**
+ * Returns a string describing the allowed options
+ * in detail.
+ *
+ * @return help information string.
+ */
+ public String getHelpMessage() {
+ Record rec;
+ NameDesc ndesc;
+ boolean hasOneWordAlias = false;
+ String s;
+
+ s = "Usage: " + synopsisString + "\n";
+ s += "Options include:\n\n";
+ for (int i = 0; i < matchList.size(); i++) {
+ String optionInfo = "";
+ rec = (Record) matchList.get(i);
+ if (rec.convertCode == 'h' && !helpOptionsEnabled) {
+ continue;
+ }
+ for (ndesc = rec.nameList; ndesc != null; ndesc = ndesc.next) {
+ if (ndesc.oneWord) {
+ hasOneWordAlias = true;
+ break;
+ }
+ }
+ for (ndesc = rec.nameList; ndesc != null; ndesc = ndesc.next) {
+ optionInfo += ndesc.name;
+ if (hasOneWordAlias && !ndesc.oneWord) {
+ optionInfo += " ";
+ }
+ if (ndesc.next != null) {
+ optionInfo += ",";
+ }
+ }
+ if (!hasOneWordAlias) {
+ optionInfo += " ";
+ }
+ if (rec.convertCode != 'v' && rec.convertCode != 'h') {
+ if (rec.valueDesc != null) {
+ optionInfo += rec.valueDesc;
+ } else {
+ if (rec.rangeDesc != null) {
+ optionInfo += "<" + rec.valTypeName() + " "
+ + rec.rangeDesc + ">";
+ } else {
+ optionInfo += "<" + rec.valTypeName() + ">";
+ }
+ }
+ }
+ if (rec.numValues > 1) {
+ optionInfo += "X" + rec.numValues;
+ }
+ s += optionInfo;
+ if (rec.helpMsg.length() > 0) {
+ int pad = helpIndent - optionInfo.length();
+ if (pad < 2) { //s += '\n';
+ pad = helpIndent;
+ }
+ // s += spaceString(pad) + rec.helpMsg;
+ s += spaceString(4) + rec.helpMsg;
+ }
+ s += '\n';
+ }
+ return s;
+ }
+
+ /**
+ * Returns the parser's error message. This is automatically
+ * set whenever an error is encountered in <code>matchArg</code> or <code>matchAllArgs</code>, and is automatically
+ * set to <code>null</code> at the beginning of these methods.
+ *
+ * @return error message
+ */
+ public String getErrorMessage() {
+ return errMsg;
+ }
+
+ /**
+ * Returns the value of an unmatched argument discovered {@link #matchArg matchArg} or
+ * {@link #matchAllArgs(String[],int,int)
+ * matchAllArgs}. If there was no unmatched argument, <code>null</code> is returned.
+ *
+ * @return unmatched argument
+ */
+ public String getUnmatchedArgument() {
+ return unmatchedArg;
+ }
+}
diff --git a/base/silent/src/com/netscape/pkisilent/argparser/ArgParserTest.java b/base/silent/src/com/netscape/pkisilent/argparser/ArgParserTest.java
new file mode 100644
index 000000000..9ddb80778
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/argparser/ArgParserTest.java
@@ -0,0 +1,1514 @@
+package com.netscape.pkisilent.argparser;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ * Copyright John E. Lloyd, 2004. All rights reserved. Permission to use,
+ * copy, modify and redistribute is granted, provided that this copyright
+ * notice is retained and the author is given credit whenever appropriate.
+ *
+ * This software is distributed "as is", without any warranty, including
+ * any implied warranty of merchantability or fitness for a particular
+ * use. The author assumes no responsibility for, and shall not be liable
+ * for, any special, indirect, or consequential damages, or any damages
+ * whatsoever, arising out of or in connection with the use of this
+ * software.
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.lang.reflect.Array;
+import java.util.Vector;
+
+/**
+ * Testing class for the class ArgParser. Executing the <code>main</code> method of this class will perform a suite of
+ * tests to help verify correct
+ * operation of the parser class.
+ *
+ * @author John E. Lloyd, Fall 2004
+ * @see ArgParser
+ */
+public class ArgParserTest {
+ ArgParser parser;
+
+ static final boolean CLOSED = true;
+ static final boolean OPEN = false;
+
+ static final boolean ONE_WORD = true;
+ static final boolean MULTI_WORD = false;
+
+ private static void verify(boolean ok, String msg) {
+ if (!ok) {
+ Throwable e = new Throwable();
+ System.out.println("Verification failed:" + msg);
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ private static String[] argsFromString(String s) {
+ Vector<String> vec = new Vector<String>(100);
+ try {
+ ArgParser.stringToArgs(vec, s, /*allowQuotedStings=*/false);
+ } catch (StringScanException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ String[] result = new String[vec.size()];
+ for (int i = 0; i < vec.size(); i++) {
+ result[i] = (String) vec.get(i);
+ }
+ return result;
+ }
+
+ static class RngCheck {
+ ArgParser.RangePnt low = null;
+ ArgParser.RangePnt high = null;
+ int type;
+
+ RngCheck(String s) {
+ low = new ArgParser.RangePnt(s, CLOSED);
+ type = 's';
+ }
+
+ RngCheck(double d) {
+ low = new ArgParser.RangePnt(d, CLOSED);
+ type = 'd';
+ }
+
+ RngCheck(long l) {
+ low = new ArgParser.RangePnt(l, CLOSED);
+ type = 'l';
+ }
+
+ RngCheck(boolean b) {
+ low = new ArgParser.RangePnt(b, CLOSED);
+ type = 'b';
+ }
+
+ RngCheck(String s1, boolean c1, String s2, boolean c2) {
+ low = new ArgParser.RangePnt(s1, c1);
+ high = new ArgParser.RangePnt(s2, c2);
+ type = 's';
+ }
+
+ RngCheck(double d1, boolean c1, double d2, boolean c2) {
+ low = new ArgParser.RangePnt(d1, c1);
+ high = new ArgParser.RangePnt(d2, c2);
+ type = 'd';
+ }
+
+ RngCheck(long l1, boolean c1, long l2, boolean c2) {
+ low = new ArgParser.RangePnt(l1, c1);
+ high = new ArgParser.RangePnt(l2, c2);
+ type = 'l';
+ }
+
+ void check(ArgParser.RangeAtom ra) {
+ verify((ra.low == null) == (low == null),
+ "(ra.low==null)=" + (ra.low == null) +
+ "(low==null)=" + (low == null));
+ verify((ra.high == null) == (high == null),
+ "(ra.high==null)=" + (ra.high == null) +
+ "(high==null)=" + (high == null));
+
+ if (ra.low != null) {
+ switch (type) {
+ case 'l': {
+ verify(ra.low.lval == low.lval,
+ "ra.low=" + ra.low + " low=" + low);
+ break;
+ }
+ case 'd': {
+ verify(ra.low.dval == low.dval,
+ "ra.low=" + ra.low + " low=" + low);
+ break;
+ }
+ case 's': {
+ verify(ra.low.sval.equals(low.sval),
+ "ra.low=" + ra.low + " low=" + low);
+ break;
+ }
+ case 'b': {
+ verify(ra.low.bval == low.bval,
+ "ra.low=" + ra.low + " low=" + low);
+ break;
+ }
+ }
+ verify(ra.low.closed == low.closed,
+ "ra.low=" + ra.low + " low=" + low);
+ }
+ if (ra.high != null) {
+ switch (type) {
+ case 'l': {
+ verify(ra.high.lval == high.lval,
+ "ra.high=" + ra.high + " high=" + high);
+ break;
+ }
+ case 'd': {
+ verify(ra.high.dval == high.dval,
+ "ra.high=" + ra.high + " high=" + high);
+ break;
+ }
+ case 's': {
+ verify(ra.high.sval.equals(high.sval),
+ "ra.high=" + ra.high + " high=" + high);
+ break;
+ }
+ case 'b': {
+ verify(ra.high.bval == high.bval,
+ "ra.high=" + ra.high + " high=" + high);
+ break;
+ }
+ }
+ verify(ra.high.closed == high.closed,
+ "ra.high=" + ra.high + " high=" + high);
+ }
+ }
+ }
+
+ ArgParserTest() {
+ parser = new ArgParser("fubar");
+ }
+
+ static void checkException(Exception e, String errmsg) {
+ if (errmsg != null) {
+ if (!e.getMessage().equals(errmsg)) {
+ System.out.println(
+ "Expecting exception '" + errmsg + "' but got '" +
+ e.getMessage() + "'");
+ e.printStackTrace();
+ (new Throwable()).printStackTrace();
+ System.exit(1);
+ }
+ } else {
+ System.out.println(
+ "Unexpected exception '" + e.getMessage() + "'");
+ e.printStackTrace();
+ (new Throwable()).printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ void checkPrintHelp(String msg) {
+ ByteArrayOutputStream buf = new ByteArrayOutputStream(0x10000);
+ PrintStream ps = new PrintStream(buf);
+ ps.println(parser.getHelpMessage());
+ System.out.print(buf.toString());
+ }
+
+ // void checkGetSynopsis (String msg)
+ // {
+ // ByteArrayOutputStream buf = new ByteArrayOutputStream(0x10000);
+ // PrintStream ps = new PrintStream(buf);
+ // parser.printSynopsis (ps, 80);
+ // System.out.print (buf.toString());
+ // }
+
+ void checkAdd(String s, Object resHolder, String errmsg) {
+ checkAdd(s, resHolder, 0, 0, null, null, null, errmsg);
+ }
+
+ void add(String s, Object resHolder) {
+ try {
+ parser.addOption(s, resHolder);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ void checkStringArray(String msg, String[] strs, String[] check) {
+ boolean dontMatch = false;
+ if (strs.length != check.length) {
+ dontMatch = true;
+ } else {
+ for (int i = 0; i < strs.length; i++) {
+ if (!strs[i].equals(check[i])) {
+ dontMatch = true;
+ break;
+ }
+ }
+ }
+ if (dontMatch) {
+ System.out.println(msg);
+ System.out.print("Expected: ");
+ for (int i = 0; i < check.length; i++) {
+ System.out.print("'" + check[i] + "'");
+ if (i < check.length - 1) {
+ System.out.print(" ");
+ }
+ }
+ System.out.println("");
+ System.out.print("Got: ");
+ for (int i = 0; i < strs.length; i++) {
+ System.out.print("'" + strs[i] + "'");
+ if (i < strs.length - 1) {
+ System.out.print(" ");
+ }
+ }
+ System.out.println("");
+ System.exit(1);
+ }
+ }
+
+ void checkAdd(String s, Object resHolder, int code, int numValues,
+ Object names, RngCheck[] rngCheck,
+ String helpMsg, String errmsg) {
+ boolean exceptionThrown = false;
+ String[] namelist = null;
+ try {
+ parser.addOption(s, resHolder);
+ } catch (Exception e) {
+ exceptionThrown = true;
+ checkException(e, errmsg);
+ }
+ if (names instanceof String) {
+ namelist = new String[] { (String) names };
+ } else {
+ namelist = (String[]) names;
+ }
+ if (!exceptionThrown) {
+ verify(errmsg == null,
+ "Expecting exception " + errmsg);
+ ArgParser.Record rec = parser.lastMatchRecord();
+ verify(rec.convertCode == code,
+ "code=" + rec.convertCode + ", expecting " + code);
+ ArgParser.NameDesc nd;
+ int i = 0;
+ for (nd = rec.firstNameDesc(); nd != null; nd = nd.next) {
+ i++;
+ }
+ verify(i == namelist.length,
+ "numNames=" + i + ", expecting " + namelist.length);
+ i = 0;
+ for (nd = rec.firstNameDesc(); nd != null; nd = nd.next) {
+ String ss;
+ if (!nd.oneWord) {
+ ss = new String(nd.name) + ' ';
+ } else {
+ ss = nd.name;
+ }
+ verify(ss.equals(namelist[i]),
+ "have name '" + ss + "', expecting '" + namelist[i] + "'");
+ i++;
+ }
+ ArgParser.RangeAtom ra;
+ i = 0;
+ for (ra = rec.firstRangeAtom(); ra != null; ra = ra.next) {
+ i++;
+ }
+ int expectedRangeNum = 0;
+ if (rngCheck != null) {
+ expectedRangeNum = rngCheck.length;
+ }
+ verify(i == expectedRangeNum,
+ "numRangeAtoms=" + i + ", expecting " + expectedRangeNum);
+ i = 0;
+ for (ra = rec.firstRangeAtom(); ra != null; ra = ra.next) {
+ rngCheck[i++].check(ra);
+ }
+ verify(rec.helpMsg.equals(helpMsg),
+ "helpMsg=" + rec.helpMsg + ", expecting " + helpMsg);
+ verify(rec.numValues == numValues,
+ "numValues=" + rec.numValues + ", expecting " + numValues);
+ }
+ }
+
+ double getDoubleValue(Object obj, int k) {
+ if (obj instanceof DoubleHolder) {
+ return ((DoubleHolder) obj).value;
+ } else if (obj instanceof FloatHolder) {
+ return ((FloatHolder) obj).value;
+ } else if (obj instanceof double[]) {
+ return ((double[]) obj)[k];
+ } else if (obj instanceof float[]) {
+ return ((float[]) obj)[k];
+ } else {
+ verify(false, "object doesn't contain double values");
+ return 0;
+ }
+ }
+
+ long getLongValue(Object obj, int k) {
+ if (obj instanceof LongHolder) {
+ return ((LongHolder) obj).value;
+ } else if (obj instanceof IntHolder) {
+ return ((IntHolder) obj).value;
+ } else if (obj instanceof long[]) {
+ return ((long[]) obj)[k];
+ } else if (obj instanceof int[]) {
+ return ((int[]) obj)[k];
+ } else {
+ verify(false, "object doesn't contain long values");
+ return 0;
+ }
+ }
+
+ String getStringValue(Object obj, int k) {
+ if (obj instanceof StringHolder) {
+ return ((StringHolder) obj).value;
+ } else if (obj instanceof String[]) {
+ return ((String[]) obj)[k];
+ } else {
+ verify(false, "object doesn't contain String values");
+ return null;
+ }
+ }
+
+ boolean getBooleanValue(Object obj, int k) {
+ if (obj instanceof BooleanHolder) {
+ return ((BooleanHolder) obj).value;
+ } else if (obj instanceof boolean[]) {
+ return ((boolean[]) obj)[k];
+ } else {
+ verify(false, "object doesn't contain boolean values");
+ return false;
+ }
+ }
+
+ char getCharValue(Object obj, int k) {
+ if (obj instanceof CharHolder) {
+ return ((CharHolder) obj).value;
+ } else if (obj instanceof char[]) {
+ return ((char[]) obj)[k];
+ } else {
+ verify(false, "object doesn't contain char values");
+ return 0;
+ }
+ }
+
+ static class MErr {
+ int code;
+ String valStr;
+
+ MErr(int code, String valStr) {
+ this.code = code;
+ this.valStr = valStr;
+ }
+ }
+
+ static class MTest {
+ String args;
+ Object result;
+ int resultIdx;
+
+ MTest(String args, Object result) {
+ this(args, result, -1);
+ }
+
+ MTest(String args, Object result, int resultIdx) {
+ this.args = args;
+ this.result = result;
+ this.resultIdx = resultIdx;
+ }
+ };
+
+ void checkMatch(String args[], int idx, String errMsg) {
+ getMatchResult(args, idx, -1, errMsg, -1);
+ }
+
+ void checkMatch(String args[], int idx, int cnt,
+ long check, int resultIdx) {
+ Object rholder = getMatchResult(args, idx, cnt, null, resultIdx);
+ long result = getLongValue(rholder, 0);
+ verify(result == check, "result " + result + " vs. " + check);
+ }
+
+ void checkMatch(String args[], int idx, int cnt,
+ double check, int resultIdx) {
+ Object rholder = getMatchResult(args, idx, cnt, null, resultIdx);
+ double result = getDoubleValue(rholder, 0);
+ verify(result == check, "result " + result + " vs. " + check);
+ }
+
+ void checkMatch(String args[], int idx, int cnt,
+ String check, int resultIdx) {
+ Object rholder = getMatchResult(args, idx, cnt, null, resultIdx);
+ String result = getStringValue(rholder, 0);
+ verify(result.equals(check), "result " + result + " vs. " + check);
+ }
+
+ void checkMatch(String args[], int idx, int cnt,
+ boolean check, int resultIdx) {
+ Object rholder = getMatchResult(args, idx, cnt, null, resultIdx);
+ boolean result = getBooleanValue(rholder, 0);
+ verify(result == check, "result " + result + " vs. " + check);
+ }
+
+ void checkMatch(String args[], int idx, int cnt,
+ char check, int resultIdx) {
+ Object rholder = getMatchResult(args, idx, cnt, null, resultIdx);
+ char result = getCharValue(rholder, 0);
+ verify(result == check, "result " + result + " vs. " + check);
+ }
+
+ void checkMatch(String args[], int idx, int cnt,
+ Object checkArray, int resultIdx) {
+ Object rholder = getMatchResult(args, idx, cnt, null, resultIdx);
+ if (!checkArray.getClass().isArray()) {
+ verify(false, "check is not an array");
+ }
+ for (int i = 0; i < Array.getLength(checkArray); i++) {
+ if (checkArray instanceof long[]) {
+ long result = getLongValue(rholder, i);
+ long check = ((long[]) checkArray)[i];
+ verify(result == check,
+ "result [" + i + "] " + result + " vs. " + check);
+ } else if (checkArray instanceof double[]) {
+ double result = getDoubleValue(rholder, i);
+ double check = ((double[]) checkArray)[i];
+ verify(result == check,
+ "result [" + i + "] " + result + " vs. " + check);
+ } else if (checkArray instanceof String[]) {
+ String result = getStringValue(rholder, i);
+ String check = ((String[]) checkArray)[i];
+ verify(result.equals(check),
+ "result [" + i + "] " + result + " vs. " + check);
+ } else if (checkArray instanceof boolean[]) {
+ boolean result = getBooleanValue(rholder, i);
+ boolean check = ((boolean[]) checkArray)[i];
+ verify(result == check,
+ "result [" + i + "] " + result + " vs. " + check);
+ } else if (checkArray instanceof char[]) {
+ char result = getCharValue(rholder, i);
+ char check = ((char[]) checkArray)[i];
+ verify(result == check,
+ "result [" + i + "] " + result + " vs. " + check);
+ } else {
+ verify(false, "unknown type for checkArray");
+ }
+ }
+ }
+
+ void checkMatch(MTest test, boolean oneWord) {
+ String[] argv;
+ if (oneWord) {
+ argv = new String[1];
+ argv[0] = test.args;
+ } else {
+ argv = argsFromString(test.args);
+ }
+ if (test.result instanceof Long) {
+ checkMatch(argv, 0, argv.length,
+ ((Long) test.result).longValue(),
+ test.resultIdx);
+ } else if (test.result instanceof Double) {
+ checkMatch(argv, 0, argv.length,
+ ((Double) test.result).doubleValue(),
+ test.resultIdx);
+ } else if (test.result instanceof String) {
+ checkMatch(argv, 0, argv.length,
+ (String) test.result,
+ test.resultIdx);
+ } else if (test.result instanceof Boolean) {
+ checkMatch(argv, 0, argv.length,
+ ((Boolean) test.result).booleanValue(),
+ test.resultIdx);
+ } else if (test.result instanceof Character) {
+ checkMatch(argv, 0, argv.length,
+ ((Character) test.result).charValue(),
+ test.resultIdx);
+ } else if (test.result.getClass().isArray()) {
+ checkMatch(argv, 0, argv.length, test.result,
+ test.resultIdx);
+ } else if (test.result instanceof MErr) {
+ MErr err = (MErr) test.result;
+ String argname = parser.getOptionName(argv[0]);
+ String msg = "";
+
+ switch (err.code) {
+ case 'c': {
+ msg = "requires a contiguous value";
+ break;
+ }
+ case 'm': {
+ msg = "malformed " + parser.getOptionTypeName(argv[0]) +
+ " '" + err.valStr + "'";
+ break;
+ }
+ case 'r': {
+ msg = "value '" + err.valStr + "' not in range " +
+ parser.getOptionRangeDesc(argv[0]);
+ break;
+ }
+ case 'v': {
+ msg = "requires " + err.valStr + " values";
+ break;
+ }
+ }
+ checkMatch(argv, 0, argname + ": " + msg);
+ } else {
+ verify(false, "Unknown result type");
+ }
+ }
+
+ void checkMatches(MTest[] tests, boolean oneWord) {
+ for (int i = 0; i < tests.length; i++) {
+ checkMatch(tests[i], oneWord);
+ }
+ }
+
+ Object getMatchResult(String args[], int idx, int cnt,
+ String errMsg, int resultIdx) {
+ boolean exceptionThrown = false;
+ int k = 0;
+ try {
+ k = parser.matchArg(args, idx);
+ } catch (Exception e) {
+ exceptionThrown = true;
+ checkException(e, errMsg);
+ }
+ if (!exceptionThrown) {
+ verify(k == idx + cnt,
+ "Expecting result index " + (idx + cnt) + ", got " + k);
+ Object result = parser.getResultHolder(args[0]);
+ if (resultIdx >= 0) {
+ verify(result instanceof Vector,
+ "Expecting result to be stored in a vector");
+ Vector<?> vec = (Vector<?>) result;
+ verify(vec.size() == resultIdx + 1,
+ "Expecting result vector size " + (resultIdx + 1));
+ return vec.get(resultIdx);
+ } else {
+ return result;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Runs a set of tests to verify correct operation of the
+ * ArgParser class. If all the tests run correctly, the
+ * program prints the message <code>Passed</code> and terminates.
+ * Otherwise, diagnostic information is printed at the first
+ * point of failure.
+ */
+ public static void main(String[] args) {
+ ArgParserTest test = new ArgParserTest();
+
+ BooleanHolder bh = new BooleanHolder();
+ boolean[] b3 = new boolean[3];
+ CharHolder ch = new CharHolder();
+ char[] c3 = new char[3];
+ IntHolder ih = new IntHolder();
+ int[] i3 = new int[3];
+ LongHolder lh = new LongHolder();
+ long[] l3 = new long[3];
+ FloatHolder fh = new FloatHolder();
+ float[] f3 = new float[3];
+ DoubleHolder dh = new DoubleHolder();
+ double[] d3 = new double[3];
+ StringHolder sh = new StringHolder();
+ String[] s3 = new String[3];
+
+ test.checkAdd("-foo %i{[0,10)}X3 #sets the value of foo",
+ // 0123456789012345
+ i3, 'i', 3, new String[] { "-foo " },
+ new RngCheck[] {
+ new RngCheck(0, CLOSED, 10, OPEN) },
+ "sets the value of foo", null);
+
+ test.checkAdd("-arg1,,", null, "Null option name given");
+ test.checkAdd("-arg1,,goo %f ", null, "Null option name given");
+ test.checkAdd(" ", null, "Null option name given");
+ test.checkAdd("", null, "Null option name given");
+ test.checkAdd(" %v", null, "Null option name given");
+ test.checkAdd("-foo ", null, "No conversion character given");
+ test.checkAdd("-foo %", null, "No conversion character given");
+ test.checkAdd("foo, aaa bbb ", null, "Names not separated by ','");
+ test.checkAdd(" foo aaa %d", null, "Names not separated by ','");
+ test.checkAdd("-arg1,-b,", null, "Null option name given");
+ test.checkAdd("-arg1,-b", null, "No conversion character given");
+ test.checkAdd("-arg1 ", null, "No conversion character given");
+ test.checkAdd("-arg1, %v", null, "Null option name given");
+ test.checkAdd("-arg1,%v", null, "Null option name given");
+ test.checkAdd("-foo %V", null,
+ "Conversion code 'V' not one of 'iodxcbfsvh'");
+ test.checkAdd("-h %hX5", null, "Multipliers not supported for %h");
+ test.checkAdd("-h %h{}", null, "Ranges not supported for %h");
+ test.checkAdd("-help, -h %h #here is how we help you",
+ null, 'h', 1, new String[] { "-help ", "-h " },
+ null, "here is how we help you", null);
+
+ test.checkAdd(
+ "-arg1 ,-arg2=%d{0,3,(7,16]}X1 #x3 test",
+ l3, 'd', 1, new String[] { "-arg1 ", "-arg2=" },
+ new RngCheck[]
+ { new RngCheck(0),
+ new RngCheck(3),
+ new RngCheck(7, OPEN, 16, CLOSED),
+ },
+ "x3 test", null);
+
+ test.checkAdd(
+ "bbb,ccc%x{[1,2]} #X3 x3 test",
+ l3, 'x', 1, new String[] { "bbb", "ccc" },
+ new RngCheck[]
+ { new RngCheck(1, CLOSED, 2, CLOSED),
+ },
+ "X3 x3 test", null);
+
+ test.checkAdd(
+ " bbb ,ccc, ddd ,e , f=%bX1 #x3 test",
+ b3, 'b', 1, new String[] { "bbb ", "ccc", "ddd ", "e ", "f=" },
+ null,
+ "x3 test", null);
+
+ test.checkAdd(
+ " bbb ,ccc, ddd ,e , f= %bX3 #x3 test",
+ b3, 'b', 3, new String[] { "bbb ", "ccc ", "ddd ", "e ", "f= " },
+ null,
+ "x3 test", null);
+
+ test.checkAdd(
+ "-b,--bar %s{[\"john\",\"jerry\"),fred,\"harry\"} #sets bar",
+ sh, 's', 1, new String[] { "-b ", "--bar " },
+ new RngCheck[] {
+ new RngCheck("jerry", OPEN, "john", CLOSED),
+ new RngCheck("fred"),
+ new RngCheck("harry") },
+ "sets bar", null);
+
+ test.checkAdd(
+ "-c ,coven%f{0.0,9.0,(6,5],[-9.1,10.2]} ",
+ dh, 'f', 1, new String[] { "-c ", "coven" },
+ new RngCheck[] {
+ new RngCheck(0.0),
+ new RngCheck(9.0),
+ new RngCheck(5.0, CLOSED, 6.0, OPEN),
+ new RngCheck(-9.1, CLOSED, 10.2, CLOSED) },
+ "", null);
+
+ test.checkAdd(
+ "-b %b #a boolean value ",
+ bh, 'b', 1, new String[] { "-b " },
+ new RngCheck[] {},
+ "a boolean value ", null);
+
+ test.checkAdd("-a %i", ih, 'i', 1, "-a ", null, "", null);
+ test.checkAdd("-a %o", lh, 'o', 1, "-a ", null, "", null);
+ test.checkAdd("-a %d", i3, 'd', 1, "-a ", null, "", null);
+ test.checkAdd("-a %x", l3, 'x', 1, "-a ", null, "", null);
+ test.checkAdd("-a %c", ch, 'c', 1, "-a ", null, "", null);
+ test.checkAdd("-a %c", c3, 'c', 1, "-a ", null, "", null);
+ test.checkAdd("-a %v", bh, 'v', 1, "-a ", null, "", null);
+ test.checkAdd("-a %b", b3, 'b', 1, "-a ", null, "", null);
+ test.checkAdd("-a %f", fh, 'f', 1, "-a ", null, "", null);
+ test.checkAdd("-a %f", f3, 'f', 1, "-a ", null, "", null);
+ test.checkAdd("-a %f", dh, 'f', 1, "-a ", null, "", null);
+ test.checkAdd("-a %f", d3, 'f', 1, "-a ", null, "", null);
+
+ test.checkAdd("-a %i", fh, 'i', 1, "-a ", null, "",
+ "Invalid result holder for %i");
+ test.checkAdd("-a %c", i3, 'c', 1, "-a ", null, "",
+ "Invalid result holder for %c");
+ test.checkAdd("-a %v", d3, 'v', 1, "-a ", null, "",
+ "Invalid result holder for %v");
+ test.checkAdd("-a %f", sh, 'f', 1, "-a ", null, "",
+ "Invalid result holder for %f");
+ test.checkAdd("-a %s", l3, 's', 1, "-a ", null, "",
+ "Invalid result holder for %s");
+
+ test.checkAdd("-foo %i{} ", ih, 'i', 1, "-foo ", null, "", null);
+ test.checkAdd("-foo%i{}", ih, 'i', 1, "-foo", null, "", null);
+ test.checkAdd("-foo%i{ }", ih, 'i', 1, "-foo", null, "", null);
+ test.checkAdd("-foo%i{ }}", ih,
+ "Illegal character(s), expecting '#'");
+ test.checkAdd("-foo%i{ ", ih, "Unterminated range specification");
+ test.checkAdd("-foo%i{", ih, "Unterminated range specification");
+ test.checkAdd("-foo%i{0,9", ih, "Unterminated range specification");
+ test.checkAdd("-foo%i{1,2,3)", ih,
+ "Unterminated range specification");
+
+ test.checkAdd("-b %f{0.9}", fh, 'f', 1, "-b ",
+ new RngCheck[] { new RngCheck(0.9) },
+ "", null);
+ test.checkAdd("-b %f{ 0.9 ,7, -0.5,-4 ,6 }", fh, 'f', 1, "-b ",
+ new RngCheck[] { new RngCheck(0.9),
+ new RngCheck(7.0),
+ new RngCheck(-0.5),
+ new RngCheck(-4.0),
+ new RngCheck(6.0) },
+ "", null);
+ test.checkAdd("-b %f{ [0.9,7), (-0.5,-4),[9,6] , (10,13.4] }",
+ fh, 'f', 1, "-b ",
+ new RngCheck[] { new RngCheck(0.9, CLOSED, 7.0, OPEN),
+ new RngCheck(-4.0, OPEN, -.5, OPEN),
+ new RngCheck(6.0, CLOSED, 9.0, CLOSED),
+ new RngCheck(10.0, OPEN, 13.4, CLOSED),
+ },
+ "", null);
+ test.checkAdd("-b %f{(8 9]}", fh,
+ "Missing ',' in subrange specification");
+ test.checkAdd("-b %f{(8,9,]}", fh,
+ "Unterminated subrange");
+ test.checkAdd("-b %f{(8,9 ,]}", fh,
+ "Unterminated subrange");
+ test.checkAdd("-b %f{(8,9 8]}", fh,
+ "Unterminated subrange");
+ test.checkAdd("-b %f{8 9}", fh,
+ "Range spec: ',' or '}' expected");
+ test.checkAdd("-b %f{8 *}", fh,
+ "Range spec: ',' or '}' expected");
+
+ test.checkAdd("-b %f{8y}", fh,
+ "Range spec: ',' or '}' expected");
+ test.checkAdd("-b %f{.}", fh,
+ "Malformed float '.}' in range spec");
+ test.checkAdd("-b %f{1.0e}", fh,
+ "Malformed float '1.0e}' in range spec");
+ test.checkAdd("-b %f{[*]}", fh,
+ "Malformed float '*' in range spec");
+ test.checkAdd("-b %f{1.2e5t}", fh,
+ "Range spec: ',' or '}' expected");
+
+ test.checkAdd("-b %i{8}", ih, 'i', 1, "-b ",
+ new RngCheck[] { new RngCheck(8) },
+ "", null);
+ test.checkAdd("-b %i{8, 9,10 }", ih, 'i', 1, "-b ",
+ new RngCheck[] { new RngCheck(8),
+ new RngCheck(9),
+ new RngCheck(10) },
+ "", null);
+ test.checkAdd("-b %i{8, [-9,10),[-17,15],(2,-33),(8,9] }",
+ ih, 'i', 1, "-b ",
+ new RngCheck[] { new RngCheck(8),
+ new RngCheck(-9, CLOSED, 10, OPEN),
+ new RngCheck(-17, CLOSED, 15, CLOSED),
+ new RngCheck(-33, OPEN, 2, OPEN),
+ new RngCheck(8, OPEN, 9, CLOSED),
+ },
+ "", null);
+ test.checkAdd("-b %i{8.7}", ih,
+ "Range spec: ',' or '}' expected");
+ test.checkAdd("-b %i{6,[*]}", ih,
+ "Malformed integer '*' in range spec");
+ test.checkAdd("-b %i{g76}", ih,
+ "Malformed integer 'g' in range spec");
+
+ test.checkAdd("-b %s{foobar}", sh, 's', 1, "-b ",
+ new RngCheck[] { new RngCheck("foobar") },
+ "", null);
+ test.checkAdd("-b %s{foobar, 0x233,\" \"}", sh, 's', 1, "-b ",
+ new RngCheck[] { new RngCheck("foobar"),
+ new RngCheck("0x233"),
+ new RngCheck(" ") },
+ "", null);
+ test.checkAdd("-b %s{foobar,(bb,aa], [\"01\",02]}",
+ sh, 's', 1, "-b ",
+ new RngCheck[]
+ { new RngCheck("foobar"),
+ new RngCheck("aa", CLOSED, "bb", OPEN),
+ new RngCheck("01", CLOSED, "02", CLOSED),
+ },
+ "", null);
+
+ test.checkAdd("-b %c{'a'}", ch, 'c', 1, "-b ",
+ new RngCheck[] { new RngCheck('a') },
+ "", null);
+ test.checkAdd("-b %c{'\\n', '\\002', 'B'}", ch, 'c', 1, "-b ",
+ new RngCheck[] { new RngCheck('\n'),
+ new RngCheck('\002'),
+ new RngCheck('B') },
+ "", null);
+ test.checkAdd("-b %c{'q',('g','a'], ['\t','\\003']}",
+ ch, 'c', 1, "-b ",
+ new RngCheck[]
+ { new RngCheck('q'),
+ new RngCheck('a', CLOSED, 'g', OPEN),
+ new RngCheck('\003', CLOSED, '\t', CLOSED),
+ },
+ "", null);
+
+ test.checkAdd("-b %b{true}X2", b3, 'b', 2, "-b ",
+ new RngCheck[] { new RngCheck(true) },
+ "", null);
+ test.checkAdd("-b %b{ true , false, true }", bh, 'b', 1, "-b ",
+ new RngCheck[] { new RngCheck(true),
+ new RngCheck(false),
+ new RngCheck(true) },
+ "", null);
+ test.checkAdd("-b %v{true,[true,false)}", bh,
+ "Sub ranges not supported for %b or %v");
+ test.checkAdd("-b %v{true,[]}", bh,
+ "Sub ranges not supported for %b or %v");
+ test.checkAdd("-b %b{tru}", bh,
+ "Malformed boolean 'tru}' in range spec");
+
+ test.checkAdd("-b %iX2", i3, 'i', 2, "-b ", null, "", null);
+ test.checkAdd("-b %vX3", b3, 'v', 3, "-b ", null, "", null);
+ test.checkAdd("-b %v{ }X3", b3, 'v', 3, "-b ", null, "", null);
+
+ test.checkAdd("-b=%iX2", i3, 'i', 2, "-b", null, "",
+ "Multiplier value incompatible with one word option -b=");
+ test.checkAdd("-b %iX0", i3, 'i', 0, "-b ", null, "",
+ "Value multiplier number must be > 0");
+ test.checkAdd("-b %iX-6", i3, 'i', 0, "-b ", null, "",
+ "Value multiplier number must be > 0");
+ test.checkAdd("-b %iXy", i3, 'i', 0, "-b ", null, "",
+ "Malformed value multiplier");
+ test.checkAdd("-b %iX4", i3, 'i', 4, "-b ", null, "",
+ "Result holder array must have a length >= 4");
+ test.checkAdd("-b %iX4", ih, 'i', 4, "-b ", null, "",
+ "Multiplier requires result holder to be an array of length >= 4");
+
+ test.checkAdd("-b %i #X4", ih, 'i', 1, "-b ", null, "X4", null);
+ test.checkAdd("-b %i #[}X4", ih, 'i', 1, "-b ", null, "[}X4", null);
+
+ // test.checkPrintHelp("");
+ // test.checkPrintUsage("");
+
+ test = new ArgParserTest();
+
+ test.checkAdd(
+ "-intarg %i{1,2,(9,18],[22,27],[33,38),(45,48)} #test int arg",
+ ih, 'i', 1, "-intarg ",
+ new RngCheck[]
+ { new RngCheck(1),
+ new RngCheck(2),
+ new RngCheck(9, OPEN, 18, CLOSED),
+ new RngCheck(22, CLOSED, 27, CLOSED),
+ new RngCheck(33, CLOSED, 38, OPEN),
+ new RngCheck(45, OPEN, 48, OPEN),
+ },
+ "test int arg", null);
+
+ MTest[] tests;
+
+ tests = new MTest[]
+ {
+ new MTest("-intarg 1", new Long(1)),
+ new MTest("-intarg 3", new MErr('r', "3")),
+ new MTest("-intarg 9", new MErr('r', "9")),
+ new MTest("-intarg 11", new Long(11)),
+ new MTest("-intarg 18", new Long(18)),
+ new MTest("-intarg 22", new Long(22)),
+ new MTest("-intarg 25", new Long(25)),
+ new MTest("-intarg 27", new Long(27)),
+ new MTest("-intarg 33", new Long(33)),
+ new MTest("-intarg 35", new Long(35)),
+ new MTest("-intarg 38", new MErr('r', "38")),
+ new MTest("-intarg 45", new MErr('r', "45")),
+ new MTest("-intarg 46", new Long(46)),
+ new MTest("-intarg 48", new MErr('r', "48")),
+ new MTest("-intarg 100", new MErr('r', "100")),
+ new MTest("-intarg 0xbeef", new MErr('r', "0xbeef")),
+ new MTest("-intarg 0x2f", new Long(0x2f)),
+ new MTest("-intarg 041", new Long(041)),
+ };
+ test.checkMatches(tests, MULTI_WORD);
+
+ test.checkAdd(
+ "-farg %f{1,2,(9,18],[22,27],[33,38),(45,48)} #test float arg",
+ dh, 'f', 1, "-farg ",
+ new RngCheck[]
+ {
+ new RngCheck(1.0),
+ new RngCheck(2.0),
+ new RngCheck(9.0, OPEN, 18.0, CLOSED),
+ new RngCheck(22.0, CLOSED, 27.0, CLOSED),
+ new RngCheck(33.0, CLOSED, 38.0, OPEN),
+ new RngCheck(45.0, OPEN, 48.0, OPEN),
+ },
+ "test float arg", null);
+
+ tests = new MTest[]
+ {
+ new MTest("-farg 1", new Double(1)),
+ new MTest("-farg 3", new MErr('r', "3")),
+ new MTest("-farg 9", new MErr('r', "9")),
+ new MTest("-farg 9.0001", new Double(9.0001)),
+ new MTest("-farg 11", new Double(11)),
+ new MTest("-farg 18", new Double(18)),
+ new MTest("-farg 22", new Double(22)),
+ new MTest("-farg 25", new Double(25)),
+ new MTest("-farg 27", new Double(27)),
+ new MTest("-farg 33", new Double(33)),
+ new MTest("-farg 35", new Double(35)),
+ new MTest("-farg 37.9999", new Double(37.9999)),
+ new MTest("-farg 38", new MErr('r', "38")),
+ new MTest("-farg 45", new MErr('r', "45")),
+ new MTest("-farg 45.0001", new Double(45.0001)),
+ new MTest("-farg 46", new Double(46)),
+ new MTest("-farg 47.9999", new Double(47.9999)),
+ new MTest("-farg 48", new MErr('r', "48")),
+ new MTest("-farg 100", new MErr('r', "100")),
+ new MTest("-farg 0", new MErr('r', "0")),
+ };
+ test.checkMatches(tests, MULTI_WORD);
+
+ test.checkAdd(
+ "-sarg %s{1,2,(AA,AZ],[BB,BX],[C3,C8),(d5,d8)} #test string arg",
+ s3, 's', 1, "-sarg ",
+ new RngCheck[]
+ { new RngCheck("1"),
+ new RngCheck("2"),
+ new RngCheck("AA", OPEN, "AZ", CLOSED),
+ new RngCheck("BB", CLOSED, "BX", CLOSED),
+ new RngCheck("C3", CLOSED, "C8", OPEN),
+ new RngCheck("d5", OPEN, "d8", OPEN),
+ },
+ "test string arg", null);
+
+ tests = new MTest[]
+ {
+ new MTest("-sarg 1", "1"),
+ new MTest("-sarg 3", new MErr('r', "3")),
+ new MTest("-sarg AA", new MErr('r', "AA")),
+ new MTest("-sarg AM", "AM"),
+ new MTest("-sarg AZ", "AZ"),
+ new MTest("-sarg BB", "BB"),
+ new MTest("-sarg BL", "BL"),
+ new MTest("-sarg BX", "BX"),
+ new MTest("-sarg C3", "C3"),
+ new MTest("-sarg C6", "C6"),
+ new MTest("-sarg C8", new MErr('r', "C8")),
+ new MTest("-sarg d5", new MErr('r', "d5")),
+ new MTest("-sarg d6", "d6"),
+ new MTest("-sarg d8", new MErr('r', "d8")),
+ new MTest("-sarg zzz", new MErr('r', "zzz")),
+ new MTest("-sarg 0", new MErr('r', "0")),
+ };
+ test.checkMatches(tests, MULTI_WORD);
+
+ test = new ArgParserTest();
+
+ test.checkAdd(
+ "-carg %c{1,2,(a,z],['A','Z'],['\\001',\\007),(4,8)}",
+ c3, 'c', 1, "-carg ",
+ new RngCheck[]
+ { new RngCheck('1'),
+ new RngCheck('2'),
+ new RngCheck('a', OPEN, 'z', CLOSED),
+ new RngCheck('A', CLOSED, 'Z', CLOSED),
+ new RngCheck('\001', CLOSED, '\007', OPEN),
+ new RngCheck('4', OPEN, '8', OPEN),
+ },
+ "", null);
+
+ tests = new MTest[]
+ {
+ new MTest("-carg 1", new Character('1')),
+ new MTest("-carg 3", new MErr('r', "3")),
+ new MTest("-carg a", new MErr('r', "a")),
+ new MTest("-carg m", new Character('m')),
+ new MTest("-carg z", new Character('z')),
+ new MTest("-carg A", new Character('A')),
+ new MTest("-carg 'L'", new Character('L')),
+ new MTest("-carg 'Z'", new Character('Z')),
+ new MTest("-carg \\001", new Character('\001')),
+ new MTest("-carg \\005", new Character('\005')),
+ new MTest("-carg '\\007'", new MErr('r', "'\\007'")),
+ new MTest("-carg '4'", new MErr('r', "'4'")),
+ new MTest("-carg 6", new Character('6')),
+ new MTest("-carg 8", new MErr('r', "8")),
+ new MTest("-carg '\\012'", new MErr('r', "'\\012'")),
+ new MTest("-carg 0", new MErr('r', "0")),
+ };
+ test.checkMatches(tests, MULTI_WORD);
+
+ test.checkAdd(
+ "-foo=%i{[-50,100]}", ih, 'i', 1, "-foo=",
+ new RngCheck[]
+ { new RngCheck(-50, CLOSED, 100, CLOSED),
+ },
+ "", null);
+
+ tests = new MTest[]
+ {
+ new MTest("-foo=-51", new MErr('r', "-51")),
+ new MTest("-foo=-0x32", new Long(-0x32)),
+ new MTest("-foo=-0x33", new MErr('r', "-0x33")),
+ new MTest("-foo=-0777", new MErr('r', "-0777")),
+ new MTest("-foo=-07", new Long(-07)),
+ new MTest("-foo=0", new Long(0)),
+ new MTest("-foo=100", new Long(100)),
+ new MTest("-foo=0x5e", new Long(0x5e)),
+ new MTest("-foo=066", new Long(066)),
+ new MTest("-foo=06677", new MErr('r', "06677")),
+ new MTest("-foo=0xbeef", new MErr('r', "0xbeef")),
+ new MTest("-foo=foo", new MErr('m', "foo")),
+ new MTest("-foo=-51d", new MErr('m', "-51d")),
+ };
+ test.checkMatches(tests, ONE_WORD);
+
+ test.checkAdd("-foo2=%i", ih, 'i', 1, "-foo2=", null, "", null);
+ tests = new MTest[]
+ {
+ new MTest("-foo2=-51", new Long(-51)),
+ new MTest("-foo2=-0x33", new Long(-0x33)),
+ new MTest("-foo2=-0777", new Long(-0777)),
+ new MTest("-foo2=06677", new Long(06677)),
+ new MTest("-foo2=0xbeef", new Long(0xbeef)),
+ new MTest("-foo2=foo", new MErr('m', "foo")),
+ new MTest("-foo2=-51d", new MErr('m', "-51d")),
+ new MTest("-foo2=-51", new Long(-51)),
+ };
+ test.checkMatches(tests, ONE_WORD);
+
+ test.checkAdd("-foo3 %iX3", i3, 'i', 3, "-foo3 ", null, "", null);
+ tests = new MTest[]
+ {
+ new MTest("-foo3 -51 678 0x45",
+ new long[] { -51, 678, 0x45 }),
+ new MTest("-foo3 55 16f 55", new MErr('m', "16f")),
+ new MTest("-foo3 55 16", new MErr('v', "3")),
+ };
+ test.checkMatches(tests, MULTI_WORD);
+
+ Vector<String> vec = new Vector<String>(100);
+
+ test.checkAdd("-foov3 %iX3", vec, 'i', 3, "-foov3 ", null, "", null);
+ tests = new MTest[]
+ { new MTest("-foov3 -1 2 4", new long[] { -1, 2, 4 }, 0),
+ new MTest("-foov3 10 3 9", new long[] { 10, 3, 9 }, 1),
+ new MTest("-foov3 123 1 0", new long[] { 123, 1, 0 }, 2),
+ };
+ vec.clear();
+ test.checkMatches(tests, MULTI_WORD);
+ test.checkAdd("-foov %i", vec, 'i', 1, "-foov ", null, "", null);
+ tests = new MTest[]
+ { new MTest("-foov 11", new Long(11), 0),
+ new MTest("-foov 12", new Long(12), 1),
+ new MTest("-foov 13", new Long(13), 2),
+ };
+ vec.clear();
+ test.checkMatches(tests, MULTI_WORD);
+
+ test.checkAdd(
+ "-foo4 %i{[-50,100]}X2", i3, 'i', 2, "-foo4 ",
+ new RngCheck[]
+ { new RngCheck(-50, CLOSED, 100, CLOSED),
+ },
+ "", null);
+ tests = new MTest[]
+ {
+ new MTest("-foo4 -49 78",
+ new long[] { -49, 78 }),
+ new MTest("-foo4 -48 102", new MErr('r', "102")),
+ };
+ test.checkMatches(tests, MULTI_WORD);
+
+ test.checkAdd(
+ "-oct=%o{[-062,0144]}", ih, 'o', 1, "-oct=",
+ new RngCheck[]
+ { new RngCheck(-50, CLOSED, 100, CLOSED),
+ },
+ "", null);
+
+ tests = new MTest[]
+ {
+ new MTest("-oct=-063", new MErr('r', "-063")),
+ new MTest("-oct=-0x32", new MErr('m', "-0x32")),
+ new MTest("-oct=-0777", new MErr('r', "-0777")),
+ new MTest("-oct=-07", new Long(-07)),
+ new MTest("-oct=0", new Long(0)),
+ new MTest("-oct=100", new Long(64)),
+ new MTest("-oct=0xae", new MErr('m', "0xae")),
+ new MTest("-oct=66", new Long(066)),
+ new MTest("-oct=06677", new MErr('r', "06677")),
+ new MTest("-oct=0xbeef", new MErr('m', "0xbeef")),
+ new MTest("-oct=foo", new MErr('m', "foo")),
+ new MTest("-oct=-51d", new MErr('m', "-51d")),
+ new MTest("-oct=78", new MErr('m', "78")),
+ };
+ test.checkMatches(tests, ONE_WORD);
+
+ test.checkAdd("-oct2=%o", ih, 'o', 1, "-oct2=", null, "", null);
+ tests = new MTest[]
+ {
+ new MTest("-oct2=-063", new Long(-063)),
+ new MTest("-oct2=-0777", new Long(-0777)),
+ new MTest("-oct2=06677", new Long(06677)),
+ };
+ test.checkMatches(tests, ONE_WORD);
+
+ test.checkAdd(
+ "-dec=%d{[-0x32,0x64]}", ih, 'd', 1, "-dec=",
+ new RngCheck[]
+ { new RngCheck(-50, CLOSED, 100, CLOSED),
+ },
+ "", null);
+
+ tests = new MTest[]
+ {
+ new MTest("-dec=-063", new MErr('r', "-063")),
+ new MTest("-dec=-0x32", new MErr('m', "-0x32")),
+ new MTest("-dec=-0777", new MErr('r', "-0777")),
+ new MTest("-dec=-07", new Long(-07)),
+ new MTest("-dec=0", new Long(0)),
+ new MTest("-dec=100", new Long(100)),
+ new MTest("-dec=0xae", new MErr('m', "0xae")),
+ new MTest("-dec=66", new Long(66)),
+ new MTest("-dec=06677", new MErr('r', "06677")),
+ new MTest("-dec=0xbeef", new MErr('m', "0xbeef")),
+ new MTest("-dec=foo", new MErr('m', "foo")),
+ new MTest("-dec=-51d", new MErr('m', "-51d")),
+ };
+ test.checkMatches(tests, ONE_WORD);
+
+ test.checkAdd("-dec2=%d", ih, 'd', 1, "-dec2=", null, "", null);
+ tests = new MTest[]
+ {
+ new MTest("-dec2=-063", new Long(-63)),
+ new MTest("-dec2=-0777", new Long(-777)),
+ new MTest("-dec2=06677", new Long(6677)),
+ };
+ test.checkMatches(tests, ONE_WORD);
+
+ test.checkAdd(
+ "-hex=%x{[-0x32,0x64]}", ih, 'x', 1, "-hex=",
+ new RngCheck[]
+ { new RngCheck(-50, CLOSED, 100, CLOSED),
+ },
+ "", null);
+
+ tests = new MTest[]
+ {
+ new MTest("-hex=-06", new Long(-0x6)),
+ new MTest("-hex=-0x3g2", new MErr('m', "-0x3g2")),
+ new MTest("-hex=-0777", new MErr('r', "-0777")),
+ new MTest("-hex=-017", new Long(-0x17)),
+ new MTest("-hex=0", new Long(0)),
+ new MTest("-hex=64", new Long(0x64)),
+ new MTest("-hex=5e", new Long(0x5e)),
+ new MTest("-hex=66", new MErr('r', "66")),
+ new MTest("-hex=06677", new MErr('r', "06677")),
+ new MTest("-hex=0xbeef", new MErr('m', "0xbeef")),
+ new MTest("-hex=foo", new MErr('m', "foo")),
+ new MTest("-hex=-51d", new MErr('r', "-51d")),
+ new MTest("-hex=-51g", new MErr('m', "-51g")),
+ new MTest("-hex=", new MErr('c', "")),
+ };
+ test.checkMatches(tests, ONE_WORD);
+
+ test.checkAdd("-hex2=%x", ih, 'x', 1, "-hex2=", null, "", null);
+ tests = new MTest[]
+ {
+ new MTest("-hex2=-0777", new Long(-0x777)),
+ new MTest("-hex2=66", new Long(0x66)),
+ new MTest("-hex2=06677", new Long(0x6677)),
+ new MTest("-hex2=-51d", new Long(-0x51d)),
+ };
+ test.checkMatches(tests, ONE_WORD);
+
+ test.checkAdd(
+ "-char=%c{['b','m']}", ch, 'c', 1, "-char=",
+ new RngCheck[]
+ { new RngCheck('b', CLOSED, 'm', CLOSED),
+ },
+ "", null);
+
+ tests = new MTest[]
+ {
+ new MTest("-char=a", new MErr('r', "a")),
+ new MTest("-char=b", new Character('b')),
+ new MTest("-char='b'", new Character('b')),
+ new MTest("-char='\142'", new Character('b')),
+ new MTest("-char='\141'", new MErr('r', "'\141'")),
+ new MTest("-char=\142", new Character('b')),
+ new MTest("-char=\141", new MErr('r', "\141")),
+ new MTest("-char=m", new Character('m')),
+ new MTest("-char=z", new MErr('r', "z")),
+ new MTest("-char=bb", new MErr('m', "bb")),
+ new MTest("-char='b", new MErr('m', "'b")),
+ new MTest("-char='", new MErr('m', "'")),
+ new MTest("-char=a'", new MErr('m', "a'")),
+ };
+ test.checkMatches(tests, ONE_WORD);
+
+ test.checkAdd("-char2=%c", ch, 'c', 1, "-char2=", null, "", null);
+ tests = new MTest[]
+ {
+ new MTest("-char2=a", new Character('a')),
+ new MTest("-char2='\141'", new Character('\141')),
+ new MTest("-char2=\141", new Character('\141')),
+ new MTest("-char2=z", new Character('z')),
+ };
+ test.checkMatches(tests, ONE_WORD);
+
+ test.checkAdd("-charv3 %cX3", vec, 'c', 3, "-charv3 ", null, "", null);
+ tests = new MTest[]
+ { new MTest("-charv3 a b c", new char[] { 'a', 'b', 'c' }, 0),
+ new MTest("-charv3 'g' f '\\n'", new char[] { 'g', 'f', '\n' }, 1),
+ new MTest("-charv3 1 \001 3", new char[] { '1', '\001', '3' }, 2),
+ };
+ vec.clear();
+ test.checkMatches(tests, MULTI_WORD);
+ test.checkAdd("-charv=%c", vec, 'c', 1, "-charv=", null, "", null);
+ tests = new MTest[]
+ { new MTest("-charv=d", new Character('d'), 0),
+ new MTest("-charv='g'", new Character('g'), 1),
+ new MTest("-charv=\111", new Character('\111'), 2),
+ };
+ vec.clear();
+ test.checkMatches(tests, ONE_WORD);
+
+ test.checkAdd(
+ "-bool=%b{true}", bh, 'b', 1, "-bool=",
+ new RngCheck[]
+ { new RngCheck(true),
+ },
+ "", null);
+
+ tests = new MTest[]
+ {
+ new MTest("-bool=true", new Boolean(true)),
+ new MTest("-bool=false", new MErr('r', "false")),
+ new MTest("-bool=fals", new MErr('m', "fals")),
+ new MTest("-bool=falsem", new MErr('m', "falsem")),
+ new MTest("-bool=truex", new MErr('m', "truex")),
+ new MTest("-bool=foo", new MErr('m', "foo")),
+ new MTest("-bool=1", new MErr('m', "1")),
+ };
+ test.checkMatches(tests, ONE_WORD);
+
+ test.checkAdd(
+ "-boo2=%b{true,false}", bh, 'b', 1, "-boo2=",
+ new RngCheck[]
+ { new RngCheck(true),
+ new RngCheck(false),
+ },
+ "", null);
+
+ tests = new MTest[]
+ {
+ new MTest("-boo2=true", new Boolean(true)),
+ new MTest("-boo2=false", new Boolean(false)),
+ };
+ test.checkMatches(tests, ONE_WORD);
+
+ test.checkAdd("-boo3=%b", bh, 'b', 1, "-boo3=", null, "", null);
+ tests = new MTest[]
+ {
+ new MTest("-boo3=true", new Boolean(true)),
+ new MTest("-boo3=false", new Boolean(false)),
+ };
+ test.checkMatches(tests, ONE_WORD);
+
+ test.checkAdd("-boo3 %bX3", b3, 'b', 3, "-boo3 ", null, "", null);
+ tests = new MTest[]
+ {
+ new MTest("-boo3 true false true",
+ new boolean[] { true, false, true }),
+ new MTest("-boo3 true fals true", new MErr('m', "fals")),
+ };
+ test.checkMatches(tests, MULTI_WORD);
+
+ test.checkAdd("-boov3 %bX3", vec, 'b', 3, "-boov3 ", null, "", null);
+ tests = new MTest[]
+ { new MTest("-boov3 true true false",
+ new boolean[] { true, true, false }, 0),
+ new MTest("-boov3 false false true",
+ new boolean[] { false, false, true }, 1),
+ };
+ vec.clear();
+ test.checkMatches(tests, MULTI_WORD);
+ test.checkAdd("-boov %b", vec, 'b', 1, "-boov ", null, "", null);
+ tests = new MTest[]
+ { new MTest("-boov true", new Boolean(true), 0),
+ new MTest("-boov false", new Boolean(false), 1),
+ new MTest("-boov true", new Boolean(true), 2),
+ };
+ vec.clear();
+ test.checkMatches(tests, MULTI_WORD);
+
+ test.checkAdd("-v3 %vX2", b3, 'v', 2, "-v3 ", null, "", null);
+ tests = new MTest[]
+ { new MTest("-v3", new boolean[] { true, true }),
+ };
+ test.checkMatches(tests, MULTI_WORD);
+
+ test.checkAdd(
+ "-vf %v{false,true}X2", b3, 'v', 2, "-vf ",
+ new RngCheck[]
+ { new RngCheck(false),
+ new RngCheck(true),
+ },
+ "", null);
+ tests = new MTest[]
+ { new MTest("-vf", new boolean[] { false, false }),
+ };
+ test.checkMatches(tests, MULTI_WORD);
+
+ test.checkAdd(
+ "-str=%s{(john,zzzz]}", sh, 's', 1, "-str=",
+ new RngCheck[]
+ { new RngCheck("john", OPEN, "zzzz", CLOSED),
+ },
+ "", null);
+
+ tests = new MTest[]
+ {
+ new MTest("-str=john", new MErr('r', "john")),
+ new MTest("-str=joho ", "joho "),
+ new MTest("-str=joho ", "joho "),
+ new MTest("-str=zzzz", "zzzz"),
+ new MTest("-str= joho", new MErr('r', " joho")),
+ new MTest("-str=jnhn ", new MErr('r', "jnhn ")),
+ new MTest("-str=zzzzz", new MErr('r', "zzzzz")),
+ new MTest("-str=\"joho\"", new MErr('r', "\"joho\"")),
+ new MTest("-str=\"joho", new MErr('r', "\"joho")),
+ new MTest("-str=joho j", "joho j"), // new MErr('m', "joho j")),
+ };
+ test.checkMatches(tests, ONE_WORD);
+
+ test.checkAdd("-str2=%s", sh, 's', 1, "-str2=", null, "", null);
+ tests = new MTest[]
+ {
+ new MTest("-str2= jnhn", " jnhn"),
+ new MTest("-str2=zzzzz", "zzzzz"),
+ };
+ test.checkMatches(tests, ONE_WORD);
+
+ test.checkAdd("-str3 %sX3", s3, 's', 3, "-str3 ", null, "", null);
+ tests = new MTest[]
+ {
+ new MTest("-str3 foo bar johnny",
+ new String[] { "foo", "bar", "johnny" }),
+ new MTest("-str3 zzzzz \"bad foo",
+ new String[] { "zzzzz", "\"bad", "foo"
+ }), // new MErr('m', "\"bad")),
+ };
+ test.checkMatches(tests, MULTI_WORD);
+
+ test.checkAdd("-strv3 %sX3", vec, 's', 3, "-strv3 ", null, "", null);
+ tests = new MTest[]
+ { new MTest("-strv3 foo bar \"hihi\"",
+ new String[] { "foo", "bar", "\"hihi\"" }, 0),
+ new MTest("-strv3 a 123 gg",
+ new String[] { "a", "123", "gg" }, 1),
+ };
+ vec.clear();
+ test.checkMatches(tests, MULTI_WORD);
+ test.checkAdd("-strv=%s", vec, 's', 1, "-strv=", null, "", null);
+ tests = new MTest[]
+ { new MTest("-strv=d", "d", 0),
+ new MTest("-strv='g'", "'g'", 1),
+ new MTest("-strv=\\111", "\\111", 2),
+ };
+ vec.clear();
+ test.checkMatches(tests, ONE_WORD);
+
+ test.checkAdd(
+ "-float=%f{(-0.001,1000.0]}", dh, 'f', 1, "-float=",
+ new RngCheck[]
+ { new RngCheck(-0.001, OPEN, 1000.0, CLOSED),
+ },
+ "", null);
+
+ tests = new MTest[]
+ {
+ new MTest("-float=-0.000999", new Double(-0.000999)),
+ new MTest("-float=1e-3", new Double(0.001)),
+ new MTest("-float=12.33e1", new Double(123.3)),
+ new MTest("-float=1e3", new Double(1e3)),
+ new MTest("-float=1000.000", new Double(1000.0)),
+ new MTest("-float=-0.001", new MErr('r', "-0.001")),
+ new MTest("-float=-1e-3", new MErr('r', "-1e-3")),
+ new MTest("-float=1000.001", new MErr('r', "1000.001")),
+ new MTest("-float=.", new MErr('m', ".")),
+ new MTest("-float= 124.5 ", new Double(124.5)),
+ new MTest("-float=124.5x", new MErr('m', "124.5x")),
+ new MTest("-float= foo ", new MErr('m', " foo ")),
+ new MTest("-float=1e1", new Double(10)),
+ new MTest("-float=1e ", new MErr('m', "1e ")),
+ };
+ test.checkMatches(tests, ONE_WORD);
+
+ test.checkAdd("-float2=%f", dh, 'f', 1, "-float2=", null, "", null);
+ tests = new MTest[]
+ {
+ new MTest("-float2=-0.001", new Double(-0.001)),
+ new MTest("-float2=-1e-3", new Double(-1e-3)),
+ new MTest("-float2=1000.001", new Double(1000.001)),
+ };
+ test.checkMatches(tests, ONE_WORD);
+
+ test.checkAdd("-f3 %fX3", d3, 'f', 3, "-f3 ", null, "", null);
+ tests = new MTest[]
+ {
+ new MTest("-f3 -0.001 1.23e5 -9.88e-4",
+ new double[] { -0.001, 1.23e5, -9.88e-4 }),
+ new MTest("-f3 7.88 foo 9.0", new MErr('m', "foo")),
+ new MTest("-f3 7.88 . 9.0", new MErr('m', ".")),
+ new MTest("-f3 7.88 3.0 9.0x", new MErr('m', "9.0x")),
+ };
+ test.checkMatches(tests, MULTI_WORD);
+
+ test.checkAdd("-fv3 %fX3", vec, 'f', 3, "-fv3 ", null, "", null);
+ tests = new MTest[]
+ { new MTest("-fv3 1.0 3.444 6.7",
+ new double[] { 1.0, 3.444, 6.7 }, 0),
+ new MTest("-fv3 13e-5 145.678 0.0001e45",
+ new double[] { 13e-5, 145.678, 0.0001e45 }, 1),
+ new MTest("-fv3 11.11 3.1245 -1e-4",
+ new double[] { 11.11, 3.1245, -1e-4 }, 2),
+ new MTest("-fv3 1.0 2 3",
+ new double[] { 1.0, 2.0, 3.0 }, 3),
+ };
+ vec.clear();
+ test.checkMatches(tests, MULTI_WORD);
+ test.checkAdd("-fv %f", vec, 'f', 1, "-fv ", null, "", null);
+ tests = new MTest[]
+ { new MTest("-fv -15.1234", new Double(-15.1234), 0),
+ new MTest("-fv -1.234e-7", new Double(-1.234e-7), 1),
+ new MTest("-fv 0.001111", new Double(0.001111), 2),
+ };
+ vec.clear();
+ test.checkMatches(tests, MULTI_WORD);
+
+ IntHolder intHolder = new IntHolder();
+ StringHolder strHolder = new StringHolder();
+
+ ArgParser parser = new ArgParser("test");
+ parser.addOption("-foo %d #an int", intHolder);
+ parser.addOption("-bar %s #a string", strHolder);
+ args = new String[]
+ { "zzz", "-cat", "-foo", "123", "yyy", "-bar", "xxxx", "xxx"
+ };
+
+ String[] unmatchedCheck = new String[]
+ { "zzz", "-cat", "yyy", "xxx"
+ };
+
+ String[] unmatched = parser.matchAllArgs(args, 0, 0);
+ test.checkStringArray(
+ "Unmatched args:", unmatched, unmatchedCheck);
+
+ vec.clear();
+ for (int i = 0; i < args.length;) {
+ try {
+ i = parser.matchArg(args, i);
+ if (parser.getUnmatchedArgument() != null) {
+ vec.add(parser.getUnmatchedArgument());
+ }
+ } catch (Exception e) {
+ }
+ }
+ unmatched = (String[]) vec.toArray(new String[0]);
+ test.checkStringArray(
+ "My unmatched args:", unmatched, unmatchedCheck);
+
+ System.out.println("\nPassed\n");
+
+ }
+}
diff --git a/base/silent/src/com/netscape/pkisilent/argparser/BooleanHolder.java b/base/silent/src/com/netscape/pkisilent/argparser/BooleanHolder.java
new file mode 100644
index 000000000..ba10022b5
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/argparser/BooleanHolder.java
@@ -0,0 +1,54 @@
+package com.netscape.pkisilent.argparser;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ * Wrapper class which ``holds'' a boolean value,
+ * enabling methods to return boolean values through
+ * arguments.
+ */
+public class BooleanHolder implements java.io.Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2863748864787121510L;
+ /**
+ * Value of the boolean, set and examined
+ * by the application as needed.
+ */
+ public boolean value;
+
+ /**
+ * Constructs a new <code>BooleanHolder</code> with an initial
+ * value of <code>false</code>.
+ */
+ public BooleanHolder() {
+ value = false;
+ }
+
+ /**
+ * Constructs a new <code>BooleanHolder</code> with a
+ * specific initial value.
+ *
+ * @param b Initial boolean value.
+ */
+ public BooleanHolder(boolean b) {
+ value = b;
+ }
+}
diff --git a/base/silent/src/com/netscape/pkisilent/argparser/CharHolder.java b/base/silent/src/com/netscape/pkisilent/argparser/CharHolder.java
new file mode 100644
index 000000000..453cac8b2
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/argparser/CharHolder.java
@@ -0,0 +1,54 @@
+package com.netscape.pkisilent.argparser;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ * Wrapper class which ``holds'' a character value,
+ * enabling methods to return character values through
+ * arguments.
+ */
+public class CharHolder implements java.io.Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7340010668929015745L;
+ /**
+ * Value of the character, set and examined
+ * by the application as needed.
+ */
+ public char value;
+
+ /**
+ * Constructs a new <code>CharHolder</code> with an initial
+ * value of 0.
+ */
+ public CharHolder() {
+ value = 0;
+ }
+
+ /**
+ * Constructs a new <code>CharHolder</code> with a
+ * specific initial value.
+ *
+ * @param c Initial character value.
+ */
+ public CharHolder(char c) {
+ value = c;
+ }
+}
diff --git a/base/silent/src/com/netscape/pkisilent/argparser/DoubleHolder.java b/base/silent/src/com/netscape/pkisilent/argparser/DoubleHolder.java
new file mode 100644
index 000000000..13012a641
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/argparser/DoubleHolder.java
@@ -0,0 +1,54 @@
+package com.netscape.pkisilent.argparser;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ * Wrapper class which ``holds'' a double value,
+ * enabling methods to return double values through
+ * arguments.
+ */
+public class DoubleHolder implements java.io.Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5461991811517552431L;
+ /**
+ * Value of the double, set and examined
+ * by the application as needed.
+ */
+ public double value;
+
+ /**
+ * Constructs a new <code>DoubleHolder</code> with an initial
+ * value of 0.
+ */
+ public DoubleHolder() {
+ value = 0;
+ }
+
+ /**
+ * Constructs a new <code>DoubleHolder</code> with a
+ * specific initial value.
+ *
+ * @param d Initial double value.
+ */
+ public DoubleHolder(double d) {
+ value = d;
+ }
+}
diff --git a/base/silent/src/com/netscape/pkisilent/argparser/FloatHolder.java b/base/silent/src/com/netscape/pkisilent/argparser/FloatHolder.java
new file mode 100644
index 000000000..b8474b535
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/argparser/FloatHolder.java
@@ -0,0 +1,54 @@
+package com.netscape.pkisilent.argparser;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ * Wrapper class which ``holds'' a float value,
+ * enabling methods to return float values through
+ * arguments.
+ */
+public class FloatHolder implements java.io.Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7962968109874934361L;
+ /**
+ * Value of the float, set and examined
+ * by the application as needed.
+ */
+ public float value;
+
+ /**
+ * Constructs a new <code>FloatHolder</code> with an initial
+ * value of 0.
+ */
+ public FloatHolder() {
+ value = 0;
+ }
+
+ /**
+ * Constructs a new <code>FloatHolder</code> with a
+ * specific initial value.
+ *
+ * @param f Initial float value.
+ */
+ public FloatHolder(float f) {
+ value = f;
+ }
+}
diff --git a/base/silent/src/com/netscape/pkisilent/argparser/IntHolder.java b/base/silent/src/com/netscape/pkisilent/argparser/IntHolder.java
new file mode 100644
index 000000000..a94ceea1e
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/argparser/IntHolder.java
@@ -0,0 +1,54 @@
+package com.netscape.pkisilent.argparser;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ * Wrapper class which ``holds'' an integer value,
+ * enabling methods to return integer values through
+ * arguments.
+ */
+public class IntHolder implements java.io.Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5303361328570056819L;
+ /**
+ * Value of the integer, set and examined
+ * by the application as needed.
+ */
+ public int value;
+
+ /**
+ * Constructs a new <code>IntHolder</code> with an initial
+ * value of 0.
+ */
+ public IntHolder() {
+ value = 0;
+ }
+
+ /**
+ * Constructs a new <code>IntHolder</code> with a
+ * specific initial value.
+ *
+ * @param i Initial integer value.
+ */
+ public IntHolder(int i) {
+ value = i;
+ }
+}
diff --git a/base/silent/src/com/netscape/pkisilent/argparser/LongHolder.java b/base/silent/src/com/netscape/pkisilent/argparser/LongHolder.java
new file mode 100644
index 000000000..5656d8b86
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/argparser/LongHolder.java
@@ -0,0 +1,54 @@
+package com.netscape.pkisilent.argparser;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ * Wrapper class which ``holds'' a long value,
+ * enabling methods to return long values through
+ * arguments.
+ */
+public class LongHolder implements java.io.Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1559599139421340971L;
+ /**
+ * Value of the long, set and examined
+ * by the application as needed.
+ */
+ public long value;
+
+ /**
+ * Constructs a new <code>LongHolder</code> with an initial
+ * value of 0.
+ */
+ public LongHolder() {
+ value = 0;
+ }
+
+ /**
+ * Constructs a new <code>LongHolder</code> with a
+ * specific initial value.
+ *
+ * @param l Initial long value.
+ */
+ public LongHolder(long l) {
+ value = l;
+ }
+}
diff --git a/base/silent/src/com/netscape/pkisilent/argparser/ObjectHolder.java b/base/silent/src/com/netscape/pkisilent/argparser/ObjectHolder.java
new file mode 100644
index 000000000..70e050fde
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/argparser/ObjectHolder.java
@@ -0,0 +1,54 @@
+package com.netscape.pkisilent.argparser;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ * Wrapper class which ``holds'' an Object reference,
+ * enabling methods to return Object references through
+ * arguments.
+ */
+public class ObjectHolder implements java.io.Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1825881254530066307L;
+ /**
+ * Value of the Object reference, set and examined
+ * by the application as needed.
+ */
+ public Object value;
+
+ /**
+ * Constructs a new <code>ObjectHolder</code> with an initial
+ * value of <code>null</code>.
+ */
+ public ObjectHolder() {
+ value = null;
+ }
+
+ /**
+ * Constructs a new <code>ObjectHolder</code> with a
+ * specific initial value.
+ *
+ * @param o Initial Object reference.
+ */
+ public ObjectHolder(Object o) {
+ value = o;
+ }
+}
diff --git a/base/silent/src/com/netscape/pkisilent/argparser/SimpleExample.java b/base/silent/src/com/netscape/pkisilent/argparser/SimpleExample.java
new file mode 100644
index 000000000..6970d318d
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/argparser/SimpleExample.java
@@ -0,0 +1,53 @@
+package com.netscape.pkisilent.argparser;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ * Gives a very simple example of the use of {@link argparser.ArgParser ArgParser}.
+ */
+public class SimpleExample {
+ /**
+ * Run this to invoke command line parsing.
+ */
+ public static void main(String[] args) {
+ // create holder objects for storing results ...
+
+ DoubleHolder theta = new DoubleHolder();
+ StringHolder fileName = new StringHolder();
+ BooleanHolder debug = new BooleanHolder();
+
+ // create the parser and specify the allowed options ...
+
+ ArgParser parser = new ArgParser("java argparser.SimpleExample");
+ parser.addOption("-theta %f #theta value (in degrees)", theta);
+ parser.addOption("-file %s #name of the operating file", fileName);
+ parser.addOption("-debug %v #enables display of debugging info",
+ debug);
+
+ // and then match the arguments
+
+ parser.matchAllArgs(args);
+
+ // now print out the values
+
+ System.out.println("theta=" + theta.value);
+ System.out.println("fileName=" + fileName.value);
+ System.out.println("debug=" + debug.value);
+ }
+}
diff --git a/base/silent/src/com/netscape/pkisilent/argparser/StringHolder.java b/base/silent/src/com/netscape/pkisilent/argparser/StringHolder.java
new file mode 100644
index 000000000..937360346
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/argparser/StringHolder.java
@@ -0,0 +1,54 @@
+package com.netscape.pkisilent.argparser;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ * Wrapper class which ``holds'' a String reference,
+ * enabling methods to return String references through
+ * arguments.
+ */
+public class StringHolder implements java.io.Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3184348746223759310L;
+ /**
+ * Value of the String reference, set and examined
+ * by the application as needed.
+ */
+ public String value;
+
+ /**
+ * Constructs a new <code>StringHolder</code> with an
+ * initial value of <code>null</code>.
+ */
+ public StringHolder() {
+ value = null;
+ }
+
+ /**
+ * Constructs a new <code>StringHolder</code> with a
+ * specific initial value.
+ *
+ * @param s Initial String reference.
+ */
+ public StringHolder(String s) {
+ value = s;
+ }
+}
diff --git a/base/silent/src/com/netscape/pkisilent/argparser/StringScanException.java b/base/silent/src/com/netscape/pkisilent/argparser/StringScanException.java
new file mode 100644
index 000000000..bf3ea6dc3
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/argparser/StringScanException.java
@@ -0,0 +1,56 @@
+package com.netscape.pkisilent.argparser;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.IOException;
+
+/**
+ * Exception class used by <code>StringScanner</code> when
+ * command line arguments do not parse correctly.
+ *
+ * @author John E. Lloyd, Winter 2001
+ * @see StringScanner
+ */
+class StringScanException extends IOException {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4923445904507805754L;
+ int failIdx;
+
+ /**
+ * Creates a new StringScanException with the given message.
+ *
+ * @param msg Error message
+ * @see StringScanner
+ */
+
+ public StringScanException(String msg) {
+ super(msg);
+ }
+
+ public StringScanException(int idx, String msg) {
+ super(msg);
+ failIdx = idx;
+ }
+
+ public int getFailIndex() {
+ return failIdx;
+ }
+}
diff --git a/base/silent/src/com/netscape/pkisilent/argparser/StringScanner.java b/base/silent/src/com/netscape/pkisilent/argparser/StringScanner.java
new file mode 100644
index 000000000..271dd0c62
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/argparser/StringScanner.java
@@ -0,0 +1,567 @@
+package com.netscape.pkisilent.argparser;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ * Copyright John E. Lloyd, 2004. All rights reserved. Permission to use,
+ * copy, modify and redistribute is granted, provided that this copyright
+ * notice is retained and the author is given credit whenever appropriate.
+ *
+ * This software is distributed "as is", without any warranty, including
+ * any implied warranty of merchantability or fitness for a particular
+ * use. The author assumes no responsibility for, and shall not be liable
+ * for, any special, indirect, or consequential damages, or any damages
+ * whatsoever, arising out of or in connection with the use of this
+ * software.
+ */
+
+class StringScanner {
+ private char[] buf;
+ private int idx;
+ private int len;
+ private String stringDelimiters = "";
+
+ public StringScanner(String s) {
+ buf = new char[s.length() + 1];
+ s.getChars(0, s.length(), buf, 0);
+ len = s.length();
+ buf[len] = 0;
+ idx = 0;
+ }
+
+ public int getIndex() {
+ return idx;
+ }
+
+ public void setIndex(int i) {
+ if (i < 0) {
+ idx = 0;
+ } else if (i > len) {
+ idx = len;
+ } else {
+ idx = i;
+ }
+ }
+
+ public void setStringDelimiters(String s) {
+ stringDelimiters = s;
+ }
+
+ public String getStringDelimiters() {
+ return stringDelimiters;
+ }
+
+ public char scanChar()
+ throws StringScanException {
+ int idxSave = idx;
+ skipWhiteSpace();
+ try {
+ if (buf[idx] == '\'') {
+ return scanQuotedChar();
+ } else {
+ return scanUnquotedChar();
+ }
+ } catch (StringScanException e) {
+ idx = idxSave;
+ throw e;
+ }
+ }
+
+ public char scanQuotedChar()
+ throws StringScanException {
+ StringScanException exception = null;
+ char retval = 0;
+ int idxSave = idx;
+
+ skipWhiteSpace();
+ if (idx == len) {
+ exception = new StringScanException(idx, "end of input");
+ } else if (buf[idx++] == '\'') {
+ try {
+ retval = scanUnquotedChar();
+ } catch (StringScanException e) {
+ exception = e;
+ }
+ if (exception == null) {
+ if (idx == len) {
+ exception = new StringScanException
+ (idx, "end of input");
+ } else if (buf[idx++] != '\'') {
+ exception = new StringScanException
+ (idx - 1, "unclosed quoted character");
+ }
+ }
+ } else {
+ exception = new StringScanException
+ (idx - 1, "uninitialized quoted character");
+ }
+ if (exception != null) {
+ idx = idxSave;
+ throw exception;
+ }
+ return retval;
+ }
+
+ public char scanUnquotedChar()
+ throws StringScanException {
+ StringScanException exception = null;
+ char c, retval = 0;
+ int idxSave = idx;
+
+ if (idx == len) {
+ exception = new StringScanException(idx, "end of input");
+ } else if ((c = buf[idx++]) == '\\') {
+ if (idx == len) {
+ exception = new StringScanException(idx, "end of input");
+ } else {
+ c = buf[idx++];
+ if (c == '"') {
+ retval = '"';
+ } else if (c == '\'') {
+ retval = '\'';
+ } else if (c == '\\') {
+ retval = '\\';
+ } else if (c == 'n') {
+ retval = '\n';
+ } else if (c == 't') {
+ retval = '\t';
+ } else if (c == 'b') {
+ retval = '\b';
+ } else if (c == 'r') {
+ retval = '\r';
+ } else if (c == 'f') {
+ retval = '\f';
+ } else if ('0' <= c && c < '8') {
+ int v = c - '0';
+ for (int j = 0; j < 2; j++) {
+ if (idx == len) {
+ break;
+ }
+ c = buf[idx];
+ if ('0' <= c && c < '8' && (v * 8 + (c - '0')) <= 255) {
+ v = v * 8 + (c - '0');
+ idx++;
+ } else {
+ break;
+ }
+ }
+ retval = (char) v;
+ } else {
+ exception = new StringScanException
+ (idx - 1, "illegal escape character '" + c + "'");
+ }
+ }
+ } else {
+ retval = c;
+ }
+ if (exception != null) {
+ idx = idxSave;
+ throw exception;
+ }
+ return retval;
+ }
+
+ public String scanQuotedString()
+ throws StringScanException {
+ StringScanException exception = null;
+ StringBuffer sbuf = new StringBuffer(len);
+ char c;
+ int idxSave = idx;
+
+ skipWhiteSpace();
+ if (idx == len) {
+ exception = new StringScanException(idx, "end of input");
+ } else if ((c = buf[idx++]) == '"') {
+ while (idx < len && (c = buf[idx]) != '"' && c != '\n') {
+ if (c == '\\') {
+ try {
+ c = scanUnquotedChar();
+ } catch (StringScanException e) {
+ exception = e;
+ break;
+ }
+ } else {
+ idx++;
+ }
+ sbuf.append(c);
+ }
+ if (exception == null && idx >= len) {
+ exception = new StringScanException(len, "end of input");
+ } else if (exception == null && c == '\n') {
+ exception = new StringScanException
+ (idx, "unclosed quoted string");
+ } else {
+ idx++;
+ }
+ } else {
+ exception = new StringScanException(idx - 1,
+ "quoted string must start with \"");
+ }
+ if (exception != null) {
+ idx = idxSave;
+ throw exception;
+ }
+ return sbuf.toString();
+ }
+
+ public String scanNonWhiteSpaceString()
+ throws StringScanException {
+ StringBuffer sbuf = new StringBuffer(len);
+ int idxSave = idx;
+ char c;
+
+ skipWhiteSpace();
+ if (idx == len) {
+ StringScanException e = new StringScanException(
+ idx, "end of input");
+ idx = idxSave;
+ throw e;
+ } else {
+ c = buf[idx++];
+ while (idx < len && !Character.isWhitespace(c)
+ && stringDelimiters.indexOf(c) == -1) {
+ sbuf.append(c);
+ c = buf[idx++];
+ }
+ if (Character.isWhitespace(c) ||
+ stringDelimiters.indexOf(c) != -1) {
+ idx--;
+ } else {
+ sbuf.append(c);
+ }
+ }
+ return sbuf.toString();
+ }
+
+ public String scanString()
+ throws StringScanException {
+ int idxSave = idx;
+ skipWhiteSpace();
+ try {
+ if (buf[idx] == '"') {
+ return scanQuotedString();
+ } else {
+ return scanNonWhiteSpaceString();
+ }
+ } catch (StringScanException e) {
+ idx = idxSave;
+ throw e;
+ }
+ }
+
+ public String getString()
+ throws StringScanException {
+ StringBuffer sbuf = new StringBuffer(len);
+ while (idx < len) {
+ sbuf.append(buf[idx++]);
+ }
+ return sbuf.toString();
+ }
+
+ public long scanInt()
+ throws StringScanException {
+ int idxSave = idx;
+ char c;
+ int sign = 1;
+
+ skipWhiteSpace();
+ if ((c = buf[idx]) == '-' || c == '+') {
+ sign = (c == '-' ? -1 : 1);
+ idx++;
+ }
+ try {
+ if (idx == len) {
+ throw new StringScanException(len, "end of input");
+ } else if ((c = buf[idx]) == '0') {
+ if ((c = buf[idx + 1]) == 'x' || c == 'X') {
+ idx += 2;
+ return sign * scanInt(16, false);
+ } else {
+ return sign * scanInt(8, false);
+ }
+ } else {
+ return sign * scanInt(10, false);
+ }
+ } catch (StringScanException e) {
+ idx = idxSave;
+ throw e;
+ }
+ }
+
+ public long scanInt(int radix)
+ throws StringScanException {
+ return scanInt(radix, /*skipWhite=*/true);
+ }
+
+ private String baseDesc(int radix) {
+ switch (radix) {
+ case 10: {
+ return "decimal";
+ }
+ case 8: {
+ return "octal";
+ }
+ case 16: {
+ return "hex";
+ }
+ default: {
+ return "base " + radix;
+ }
+ }
+ }
+
+ public long scanInt(int radix, boolean skipWhite)
+ throws StringScanException {
+ StringScanException exception = null;
+ int charval, idxSave = idx;
+ char c;
+ long val = 0;
+ boolean negate = false;
+
+ if (skipWhite) {
+ skipWhiteSpace();
+ }
+ if ((c = buf[idx]) == '-' || c == '+') {
+ negate = (c == '-');
+ idx++;
+ }
+ if (idx >= len) {
+ exception = new StringScanException(len, "end of input");
+ } else if ((charval = Character.digit(buf[idx++], radix)) == -1) {
+ exception = new StringScanException
+ (idx - 1, "malformed " + baseDesc(radix) + " integer");
+ } else {
+ val = charval;
+ while ((charval = Character.digit(buf[idx], radix)) != -1) {
+ val = val * radix + charval;
+ idx++;
+ }
+ if (Character.isLetter(c = buf[idx]) ||
+ Character.isDigit(c) || c == '_') {
+ exception = new StringScanException
+ (idx, "malformed " + baseDesc(radix) + " integer");
+ }
+ }
+ if (exception != null) {
+ idx = idxSave;
+ throw exception;
+ }
+ return negate ? -val : val;
+ }
+
+ public double scanDouble()
+ throws StringScanException {
+ StringScanException exception = null;
+ int idxSave = idx;
+ char c;
+ // parse [-][0-9]*[.][0-9]*[eE][-][0-9]*
+ boolean hasDigits = false;
+ double value = 0;
+
+ skipWhiteSpace();
+ if (idx == len) {
+ exception = new StringScanException("end of input");
+ } else {
+ if ((c = buf[idx]) == '-' || c == '+') {
+ // signed
+ idx++;
+ }
+ if (matchDigits()) {
+ hasDigits = true;
+ }
+ if (buf[idx] == '.') {
+ idx++;
+ }
+ if (!hasDigits && (buf[idx] < '0' || buf[idx] > '9')) {
+ if (idx == len) {
+ exception = new StringScanException(idx, "end of input");
+ } else {
+ exception = new StringScanException(
+ idx, "malformed floating number: no digits");
+ }
+ } else {
+ matchDigits();
+
+ if ((c = buf[idx]) == 'e' || c == 'E') {
+ idx++;
+ if ((c = buf[idx]) == '-' || c == '+') {
+ // signed
+ idx++;
+ }
+ if (buf[idx] < '0' || buf[idx] > '9') {
+ if (idx == len) {
+ exception = new StringScanException(
+ idx, "end of input");
+ } else {
+ exception = new StringScanException(idx,
+ "malformed floating number: no digits in exponent");
+ }
+ } else {
+ matchDigits();
+ }
+ }
+ }
+ }
+ if (exception == null) {
+ // if (Character.isLetterOrDigit(c=buf[idx]) || c == '_')
+ // { exception = new StringScanException (idx,
+ //"malformed floating number");
+ // }
+ // else
+ {
+ try {
+ value = Double.parseDouble(new String(buf, idxSave,
+ idx - idxSave));
+ } catch (NumberFormatException e) {
+ exception = new StringScanException(
+ idx, "malformed floating number");
+ }
+ }
+ }
+ if (exception != null) {
+ idx = idxSave;
+ throw exception;
+ }
+ return value;
+ }
+
+ public boolean scanBoolean()
+ throws StringScanException {
+ StringScanException exception = null;
+ int idxSave = idx;
+ String testStr = "false";
+ boolean testval = false;
+ char c;
+
+ skipWhiteSpace();
+ if (buf[idx] == 't') {
+ testStr = "true";
+ testval = true;
+ } else {
+ testval = false;
+ }
+ int i = 0;
+ for (i = 0; i < testStr.length(); i++) {
+ if (testStr.charAt(i) != buf[idx]) {
+ if (idx == len) {
+ exception = new StringScanException(idx, "end of input");
+ }
+ break;
+ }
+ idx++;
+ }
+ if (exception == null) {
+ if (i < testStr.length() ||
+ Character.isLetterOrDigit(c = buf[idx]) || c == '_') {
+ exception = new StringScanException(idx, "illegal boolean");
+ }
+ }
+ if (exception != null) {
+ idx = idxSave;
+ throw exception;
+ }
+ return testval;
+ }
+
+ public boolean matchString(String s) {
+ int k = idx;
+ for (int i = 0; i < s.length(); i++) {
+ if (k >= len || s.charAt(i) != buf[k++]) {
+ return false;
+ }
+ }
+ idx = k;
+ return true;
+ }
+
+ public boolean matchDigits() {
+ int k = idx;
+ char c;
+
+ while ((c = buf[k]) >= '0' && c <= '9') {
+ k++;
+ }
+ if (k > idx) {
+ idx = k;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public void skipWhiteSpace() {
+ while (Character.isWhitespace(buf[idx])) {
+ idx++;
+ }
+ }
+
+ public boolean atEnd() {
+ return idx == len;
+ }
+
+ public boolean atBeginning() {
+ return idx == 0;
+ }
+
+ public void ungetc() {
+ if (idx > 0) {
+ idx--;
+ }
+ }
+
+ public char getc() {
+ char c = buf[idx];
+ if (idx < len) {
+ idx++;
+ }
+ return c;
+ }
+
+ public char peekc() {
+ return buf[idx];
+ }
+
+ public String substring(int i0, int i1) {
+ if (i0 < 0) {
+ i0 = 0;
+ } else if (i0 >= len) {
+ i0 = len - 1;
+ }
+ if (i1 < 0) {
+ i1 = 0;
+ } else if (i1 > len) {
+ i1 = len;
+ }
+ if (i1 <= i0) {
+ return "";
+ }
+ return new String(buf, i0, i1 - i0);
+ }
+
+ public String substring(int i0) {
+ if (i0 < 0) {
+ i0 = 0;
+ }
+ if (i0 >= len) {
+ return "";
+ } else {
+ return new String(buf, i0, len - i0);
+ }
+ }
+}
diff --git a/base/silent/src/com/netscape/pkisilent/common/BaseState.java b/base/silent/src/com/netscape/pkisilent/common/BaseState.java
new file mode 100644
index 000000000..0d5e9cfc6
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/common/BaseState.java
@@ -0,0 +1,118 @@
+package com.netscape.pkisilent.common;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ * CMS Test framework .
+ * This class reads and sets the values for a CMS subsytems Config file (CS.cfg)
+ * Using this class you can set the server to a base state.
+ */
+
+public class BaseState {
+
+ private String CMSConfigFile;
+ private CMSConfig cmscfg = null;
+ private String ldapbase, ldaphost, ldapport, ldapdn, ldapdnpw;
+ private boolean ldapsecConn = false;
+
+ // Constructor
+
+ public BaseState() {
+ }
+
+ /**
+ * Constructor . Takes the parameter CMSConfigfilename ( with fullpath)
+ *
+ * @param CMSConfigfile.
+ */
+
+ public BaseState(String cmscfilename) {
+ CMSConfigFile = cmscfilename;
+
+ }
+
+ /**
+ * Set the publishing directory information . Takes the paramters ldaphost,ldapport,ldapDN, ldapDN password, BaseDN
+ * , Secure coonection (true/false)
+ */
+ public void setLDAPInfo(String h, String p, String dn, String pw, String base, boolean sc) {
+ ldaphost = h;
+ ldapport = p;
+ ldapdn = dn;
+ ldapdnpw = pw;
+ ldapbase = base;
+ ldapsecConn = sc;
+
+ }
+
+ /**
+ * Enable SSL Client authentication for Directory enrollment and publishing
+ */
+
+ public void EnableSSLClientAuth() {
+ ldapsecConn = true;
+ cmscfg = new CMSConfig(CMSConfigFile);
+ // Enable DirBaseEnrollment
+ cmscfg.EnableDirEnrollment(ldapsecConn, ldapbase, ldaphost, ldapport);
+ // Enable Publishing
+ cmscfg.EnablePublishing(ldapsecConn, ldapdn, ldapdnpw, ldaphost,
+ ldapport);
+ cmscfg.saveCMSConfig();
+
+ }
+
+ /**
+ * Set to CA 's base state . Enables Directory based enrollment , publishing and Portal enrollment
+ */
+
+ public void CABaseState() {
+ cmscfg = new CMSConfig(CMSConfigFile);
+ cmscfg.EnableAdminEnrollment();
+ // Enable DirBaseEnrollment
+ cmscfg.EnableDirEnrollment(ldapsecConn, ldapbase, ldaphost, ldapport);
+ // Enable Publishing
+ cmscfg.DisablePublishing(ldapsecConn, ldapdn, ldapdnpw, ldaphost,
+ ldapport, ldapbase);
+ // Enable Portalbased enrollment
+ cmscfg.EnablePortalAuth(ldapsecConn, ldapdn, ldapdnpw, ldaphost,
+ ldapport, ldapbase);
+ cmscfg.saveCMSConfig();
+
+ }
+
+ /**
+ * Set to RA 's base state . Enables Directory based enrollment and Portal enrollment
+ */
+
+ public void RABaseState() {
+ cmscfg = new CMSConfig(CMSConfigFile);
+ cmscfg.EnableAdminEnrollment();
+ // Enable DirBaseEnrollment
+ cmscfg.EnableDirEnrollment(ldapsecConn, ldapbase, ldaphost, ldapport);
+ // Enable Portalbased enrollment
+ cmscfg.EnablePortalAuth(ldapsecConn, ldapdn, ldapdnpw, ldaphost,
+ ldapport, ldapbase);
+ cmscfg.saveCMSConfig();
+
+ }
+
+ public static void main(String args[]) {
+ }// end of function main
+
+}
diff --git a/base/silent/src/com/netscape/pkisilent/common/CMSConfig.java b/base/silent/src/com/netscape/pkisilent/common/CMSConfig.java
new file mode 100644
index 000000000..3e4f0bfa2
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/common/CMSConfig.java
@@ -0,0 +1,569 @@
+package com.netscape.pkisilent.common;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+/**
+ * CMS Test framework .
+ * This class reads,modifies and saves CS.cfg file
+ */
+
+public class CMSConfig extends ServerInfo {
+
+ /**
+ * Constructor . Reads the CS.cfg file .Takes the parameter for Configfile ( Provide fullpath)
+ */
+
+ public CMSConfig(String confFile) {
+ CMSConfigFile = confFile;
+ System.out.println(CMSConfigFile);
+ readCMSConfig();
+ }
+
+ private void readCMSConfig() {
+
+ try {
+ FileInputStream fiscfg = new FileInputStream(CMSConfigFile);
+
+ CMSprops = new CMSProperties();
+ CMSprops.load(fiscfg);
+ System.out.println("Reading CMS Config file successful");
+ fiscfg.close();
+ System.out.println("Number in size " + CMSprops.size());
+ } catch (Exception e) {
+ System.out.println("exception " + e.getMessage());
+ }
+
+ }
+
+ /**
+ * Saves the config file
+ **/
+
+ public void saveCMSConfig() {
+ try {
+ // Properties s = new Properties(CMSprops);
+ FileOutputStream fos = new FileOutputStream(CMSConfigFile);
+
+ System.out.println("Number in size " + CMSprops.size());
+ // CMSprops.list(System.out);
+ CMSprops.store(fos, null);
+ System.out.println("Writing to CMS Config file successful");
+ fos.close();
+ } catch (Exception e) {
+ System.out.println("exception " + e.getMessage());
+ }
+
+ }
+
+ // AdminEnrollment
+
+ public void EnableAdminEnrollment() {
+ CMSprops.setProperty("cmsgateway.enableAdminEnroll", "true");
+
+ }
+
+ // Authentication
+
+ // Enable DirectoryBased Authentication
+ /**
+ * Takes parameters : secureConnection( true/false), basedn, ldaphostname, lapdaportnumber ( in case of secured
+ * connection give ldap secured port)
+ */
+
+ public void EnableDirEnrollment(boolean secureConn, String ldapbase, String lhost, String lport) {
+ CMSprops.setProperty("auths.instance.UserDirEnrollment.dnpattern",
+ "UID=$attr.uid,E=$attr.mail.1,CN=$attr.cn,OU=$dn.ou.2,O=$dn.o,C=US");
+ CMSprops.setProperty("auths.instance.UserDirEnrollment.ldap.basedn",
+ ldapbase);
+ CMSprops.setProperty(
+ "auths.instance.UserDirEnrollment.ldap.ldapconn.host", lhost);
+ CMSprops.setProperty(
+ "auths.instance.UserDirEnrollment.ldap.ldapconn.version", "3");
+ CMSprops.setProperty("auths.instance.UserDirEnrollment.ldap.maxConns",
+ "8");
+ CMSprops.setProperty("auths.instance.UserDirEnrollment.ldap.minConns",
+ "2");
+ // CMSprops.setProperty("auths.instance.UserDirEnrollment.ldapByteAttributes=","");
+ CMSprops.setProperty(
+ "auths.instance.UserDirEnrollment.ldapStringAttributes", "mail");
+ CMSprops.setProperty("auths.instance.UserDirEnrollment.pluginName",
+ "UidPwdDirAuth");
+ if (secureConn) {
+ CMSprops.setProperty(
+ "auths.instance.UserDirEnrollment.ldap.ldapconn.secureConn",
+ "true");
+ CMSprops.setProperty(
+ "auths.instance.UserDirEnrollment.ldap.ldapconn.port", lport);
+
+ } else {
+ CMSprops.setProperty(
+ "auths.instance.UserDirEnrollment.ldap.ldapconn.secureConn",
+ "false");
+ CMSprops.setProperty(
+ "auths.instance.UserDirEnrollment.ldap.ldapconn.port", lport);
+
+ }
+ }
+
+ public void DisableDirEnrollment() {
+ CMSprops.remove("auths.instance.UserDirEnrollment.dnpattern");
+ CMSprops.remove("auths.instance.UserDirEnrollment.ldap.basedn");
+ CMSprops.remove("auths.instance.UserDirEnrollment.ldap.ldapconn.host");
+ CMSprops.remove("auths.instance.UserDirEnrollment.ldap.ldapconn.port");
+ CMSprops.remove(
+ "auths.instance.UserDirEnrollment.ldap.ldapconn.secureConn");
+ CMSprops.remove("auths.instance.UserDirEnrollment.ldap.ldapconn.version");
+ CMSprops.remove("auths.instance.UserDirEnrollment.ldap.maxConns");
+ CMSprops.remove("auths.instance.UserDirEnrollment.ldap.minConns");
+ CMSprops.remove("auths.instance.UserDirEnrollment.ldapByteAttributes=");
+ CMSprops.remove("auths.instance.UserDirEnrollment.ldapStringAttributes");
+ CMSprops.remove("auths.instance.UserDirEnrollment.pluginName");
+
+ }
+
+ public void EnableCMCAuth() {
+
+ CMSprops.setProperty("auths.instance.testcmc.pluginName",
+ "CMCAuthentication");
+ }
+
+ /**
+ * Takes parameters : secureConnection( true/false), ldapbinddn, ldapbindnpassword,ldaphostname, lapdaportnumber (
+ * in case of secured connection give ldap secured port), basedn (e.g ou=people,o=mcom.com)
+ */
+
+ void EnablePortalAuth(boolean secureConn, String ldaprootDN, String ldaprootDNPW, String lhost, String lport,
+ String lbsuffix) {
+ String certnickname = null;
+
+ CMSprops.setProperty("auths.instance.PortalEnrollment.pluginName",
+ "PortalEnroll");
+ CMSprops.setProperty("auths.instance.PortalEnrollment.dnpattern",
+ "uid=$attr.uid,cn=$attr.cn,O=$dn.co,C=$dn.c");
+ CMSprops.setProperty("auths.instance.PortalEnrollment.ldap.basedn",
+ lbsuffix);
+ CMSprops.setProperty("auths.instance.PortalEnrollment.ldap.maxConns",
+ "3");
+ CMSprops.setProperty("auths.instance.PortalEnrollment.ldap.minConns",
+ "2");
+ CMSprops.setProperty("auths.instance.PortalEnrollment.ldap.objectclass",
+ "inetOrgPerson");
+ CMSprops.setProperty(
+ "auths.instance.PortalEnrollment.ldap.ldapauth.bindDN",
+ ldaprootDN);
+ CMSprops.setProperty(
+ "auths.instance.PortalEnrollment.ldap.ldapauth.bindPassword",
+ ldaprootDNPW);
+ CMSprops.setProperty(
+ "auths.instance.PortalEnrollment.ldap.ldapauth.bindPWPrompt",
+ "Rule PortalEnrollment");
+ CMSprops.setProperty(
+ "auths.instance.PortalEnrollment.ldap.ldapconn.host", lhost);
+ if (secureConn) {
+ CMSprops.setProperty(
+ "auths.instance.PortalEnrollment.ldap.ldapconn.secureConn",
+ "true");
+ CMSprops.setProperty(
+ "auths.instance.PortalEnrollment.ldap.ldapauth.clientCertNickname",
+ certnickname);
+ CMSprops.setProperty(
+ "auths.instance.PortalEnrollment.ldap.ldapauth.authtype",
+ "SslClientAuth");
+ CMSprops.setProperty(
+ "auths.instance.PortalEnrollment.ldap.ldapconn.port", lport);
+
+ } else {
+ CMSprops.setProperty(
+ "auths.instance.PortalEnrollment.ldap.ldapconn.secureConn",
+ "false");
+ CMSprops.setProperty(
+ "auths.instance.PortalEnrollment.ldap.ldapconn.port", lport);
+ CMSprops.setProperty(
+ "auths.instance.PortalEnrollment.ldap.ldapauth.authtype",
+ "BasicAuth");
+ }
+
+ CMSprops.setProperty(
+ "auths.instance.PortalEnrollment.ldap.ldapconn.version", "3");
+
+ }
+
+ // Publishing
+ /**
+ * Takes parameters : secureConnection( true/false), ldapbinddn, ldapbindnpassword,ldaphostname, lapdaportnumber (
+ * in case of secured connection give ldap secured port)
+ */
+
+ public void EnablePublishing(boolean secureConn, String ldaprootDN, String ldaprootDNPW, String lhost, String lport) {
+
+ CMSprops.setProperty("ca.publish.enable", "true");
+ CMSprops.setProperty("ca.publish.ldappublish.enable", "true");
+ if (secureConn) {
+ CMSprops.setProperty(
+ "ca.publish.ldappublish.ldap.ldapconn.secureConn", "true");
+ CMSprops.setProperty("ca.publish.ldappublish.ldap.ldapconn.port",
+ lport);
+
+ CMSprops.setProperty("ca.publish.ldappublish.ldap.ldapauth.authtype",
+ "SslClientAuth");
+ } else {
+ CMSprops.setProperty(
+ "ca.publish.ldappublish.ldap.ldapconn.secureConn", "false");
+ CMSprops.setProperty("ca.publish.ldappublish.ldap.ldapconn.port",
+ lport);
+ CMSprops.setProperty("ca.publish.ldappublish.ldap.ldapauth.authtype",
+ "BasicAuth");
+ }
+
+ CMSprops.setProperty("ca.publish.ldappublish.ldap.ldapauth.bindDN",
+ ldaprootDN);
+ CMSprops.setProperty("ca.publish.ldappublish.ldap.ldapauth.bindPassword",
+ ldaprootDNPW);
+ CMSprops.setProperty("ca.publish.ldappublish.ldap.ldapauth.bindPWPrompt",
+ "CA LDAP Publishing");
+
+ // set the hostname with fully qulified name if you are using SSL
+ CMSprops.setProperty("ca.publish.ldappublish.ldap.ldapconn.host", lhost);
+ CMSprops.setProperty("ca.publish.ldappublish.ldap.ldapconn.version", "3");
+ CMSprops.setProperty("ca.publish.mapper.impl.LdapCaSimpleMap.class",
+ "com.netscape.cms.publish.mappers.LdapCaSimpleMap");
+ CMSprops.setProperty("ca.publish.mapper.impl.LdapDNCompsMap.class",
+ "com.netscape.cms.publish.mappers.Lda pCertCompsMap");
+ CMSprops.setProperty("ca.publish.mapper.impl.LdapDNExactMap.class",
+ "com.netscape.cms.publish.mappers.LdapCertExactMap");
+ CMSprops.setProperty("ca.publish.mapper.impl.LdapEnhancedMap.class",
+ "com.netscape.cms.publish.mappers.LdapEnhancedMap");
+ CMSprops.setProperty("ca.publish.mapper.impl.LdapSimpleMap.class",
+ "com.netscape.cms.publish.mappers.LdapSimpleMap");
+ CMSprops.setProperty("ca.publish.mapper.impl.LdapSubjAttrMap.class",
+ "com.netscape.cms.publish.mappers.LdapCertSubjMap");
+ CMSprops.setProperty(
+ "ca.publish.mapper.instance.LdapCaCertMap.createCAEntry", "true");
+ CMSprops.setProperty(
+ "ca.publish.mapper.instance.LdapCaCertMap.dnPattern",
+ "UID=CManager,OU=people,O=mcom.com");
+ CMSprops.setProperty(
+ "ca.publish.mapper.instance.LdapCaCertMap.pluginName",
+ "LdapCaSimpleMap");
+ CMSprops.setProperty(
+ "ca.publish.mapper.instance.LdapCrlMap.createCAEntry", "true");
+ CMSprops.setProperty("ca.publish.mapper.instance.LdapCrlMap.dnPattern",
+ "UID=CManager,OU=people,O=mcom.com");
+ CMSprops.setProperty("ca.publish.mapper.instance.LdapCrlMap.pluginName",
+ "LdapCaSimpleMap");
+ CMSprops.setProperty(
+ "ca.publish.mapper.instance.LdapUserCertMap.dnPattern",
+ "UID=$subj.UID,OU=people,O=mcom.com");
+ CMSprops.setProperty(
+ "ca.publish.mapper.instance.LdapUserCertMap.pluginName",
+ "LdapSimpleMap");
+ CMSprops.setProperty(
+ "ca.publish.publisher.impl.FileBasedPublisher.class",
+ "com.netscape.cms.publish.publishers.FileBasedPublisher");
+ CMSprops.setProperty(
+ "ca.publish.publisher.impl.LdapCaCertPublisher.class",
+ "com.netscape.cms.publish.publishers.LdapCaCertPublisher");
+ CMSprops.setProperty("ca.publish.publisher.impl.LdapCrlPublisher.class",
+ "com.netscape.cms.publish.publishers.LdapCrlPublisher");
+ CMSprops.setProperty(
+ "ca.publish.publisher.impl.LdapUserCertPublisher.class",
+ "com.netscape.cms.publish.publishers.LdapUserCertPublisher");
+ CMSprops.setProperty("ca.publish.publisher.impl.OCSPPublisher.class",
+ "com.netscape.cms.publish.publishers.OCSPPublisher");
+ CMSprops.setProperty(
+ "ca.publish.publisher.instance.LdapCaCertPublisher.caCertAttr",
+ "caCertificate;binary");
+ CMSprops.setProperty(
+ "ca.publish.publisher.instance.LdapCaCertPublisher.caObjectClass",
+ "certificationAuthority");
+ CMSprops.setProperty(
+ "ca.publish.publisher.instance.LdapCaCertPublisher.pluginName",
+ "LdapCaCertPublisher");
+ CMSprops.setProperty(
+ "ca.publish.publisher.instance.LdapCrlPublisher.crlAttr",
+ "certificateRevocationList;binary");
+ CMSprops.setProperty(
+ "ca.publish.publisher.instance.LdapCrlPublisher.pluginName",
+ "LdapCrlPublisher");
+ CMSprops.setProperty(
+ "ca.publish.publisher.instance.LdapUserCertPublisher.certAttr",
+ "userCertificate;binary");
+ CMSprops.setProperty(
+ "ca.publish.publisher.instance.LdapUserCertPublisher.pluginName",
+ "LdapUserCertPublisher");
+ }
+
+ public void DisablePublishing(boolean secureConn, String ldaprootDN, String ldaprootDNPW, String lhost,
+ String lport, String base) {
+
+ CMSprops.setProperty("ca.publish.enable", "false");
+ CMSprops.setProperty("ca.publish.ldappublish.enable", "false");
+ if (secureConn) {
+ CMSprops.setProperty(
+ "ca.publish.ldappublish.ldap.ldapconn.secureConn", "false");
+ CMSprops.setProperty("ca.publish.ldappublish.ldap.ldapconn.port",
+ lport);
+
+ CMSprops.setProperty("ca.publish.ldappublish.ldap.ldapauth.authtype",
+ "SslClientAuth");
+ } else {
+ CMSprops.setProperty(
+ "ca.publish.ldappublish.ldap.ldapconn.secureConn", "false");
+ CMSprops.setProperty("ca.publish.ldappublish.ldap.ldapconn.port",
+ lport);
+ CMSprops.setProperty("ca.publish.ldappublish.ldap.ldapauth.authtype",
+ "BasicAuth");
+ }
+
+ CMSprops.setProperty("ca.publish.ldappublish.ldap.ldapauth.bindDN",
+ ldaprootDN);
+ CMSprops.setProperty("ca.publish.ldappublish.ldap.ldapauth.bindPassword",
+ ldaprootDNPW);
+ CMSprops.setProperty("ca.publish.ldappublish.ldap.ldapauth.bindPWPrompt",
+ "CA LDAP Publishing");
+
+ // set the hostname with fully qulified name if you are using SSL
+ CMSprops.setProperty("ca.publish.ldappublish.ldap.ldapconn.host", lhost);
+ CMSprops.setProperty("ca.publish.ldappublish.ldap.ldapconn.version", "3");
+ CMSprops.setProperty("ca.publish.mapper.impl.LdapCaSimpleMap.class",
+ "com.netscape.cms.publish.mappers.LdapCaSimpleMap");
+ CMSprops.setProperty("ca.publish.mapper.impl.LdapDNCompsMap.class",
+ "com.netscape.cms.publish.mappers.Lda pCertCompsMap");
+ CMSprops.setProperty("ca.publish.mapper.impl.LdapDNExactMap.class",
+ "com.netscape.cms.publish.mappers.LdapCertExactMap");
+ CMSprops.setProperty("ca.publish.mapper.impl.LdapEnhancedMap.class",
+ "com.netscape.cms.publish.mappers.LdapEnhancedMap");
+ CMSprops.setProperty("ca.publish.mapper.impl.LdapSimpleMap.class",
+ "com.netscape.cms.publish.mappers.LdapSimpleMap");
+ CMSprops.setProperty("ca.publish.mapper.impl.LdapSubjAttrMap.class",
+ "com.netscape.cms.publish.mappers.LdapCertSubjMap");
+ CMSprops.setProperty(
+ "ca.publish.mapper.instance.LdapCaCertMap.createCAEntry",
+ "false");
+ CMSprops.setProperty(
+ "ca.publish.mapper.instance.LdapCaCertMap.dnPattern",
+ "UID=CManager,OU=people," + base);
+ CMSprops.setProperty(
+ "ca.publish.mapper.instance.LdapCaCertMap.pluginName",
+ "LdapCaSimpleMap");
+ CMSprops.setProperty(
+ "ca.publish.mapper.instance.LdapCrlMap.createCAEntry", "false");
+ CMSprops.setProperty("ca.publish.mapper.instance.LdapCrlMap.dnPattern",
+ "UID=CManager,OU=people," + base);
+ CMSprops.setProperty("ca.publish.mapper.instance.LdapCrlMap.pluginName",
+ "LdapCaSimpleMap");
+ CMSprops.setProperty(
+ "ca.publish.mapper.instance.LdapUserCertMap.dnPattern",
+ "UID=$subj.UID,OU=people," + base);
+ CMSprops.setProperty(
+ "ca.publish.mapper.instance.LdapUserCertMap.pluginName",
+ "LdapSimpleMap");
+ CMSprops.setProperty(
+ "ca.publish.publisher.impl.FileBasedPublisher.class",
+ "com.netscape.cms.publish.publishers.FileBasedPublisher");
+ CMSprops.setProperty(
+ "ca.publish.publisher.impl.LdapCaCertPublisher.class",
+ "com.netscape.cms.publish.publishers.LdapCaCertPublisher");
+ CMSprops.setProperty("ca.publish.publisher.impl.LdapCrlPublisher.class",
+ "com.netscape.cms.publish.publishers.LdapCrlPublisher");
+ CMSprops.setProperty(
+ "ca.publish.publisher.impl.LdapUserCertPublisher.class",
+ "com.netscape.cms.publish.publishers.LdapUserCertPublisher");
+ CMSprops.setProperty("ca.publish.publisher.impl.OCSPPublisher.class",
+ "com.netscape.cms.publish.publishers.OCSPPublisher");
+ CMSprops.setProperty(
+ "ca.publish.publisher.instance.LdapCaCertPublisher.caCertAttr",
+ "caCertificate;binary");
+ CMSprops.setProperty(
+ "ca.publish.publisher.instance.LdapCaCertPublisher.caObjectClass",
+ "certificationAuthority");
+ CMSprops.setProperty(
+ "ca.publish.publisher.instance.LdapCaCertPublisher.pluginName",
+ "LdapCaCertPublisher");
+ CMSprops.setProperty(
+ "ca.publish.publisher.instance.LdapCrlPublisher.crlAttr",
+ "certificateRevocationList;binary");
+ CMSprops.setProperty(
+ "ca.publish.publisher.instance.LdapCrlPublisher.pluginName",
+ "LdapCrlPublisher");
+ CMSprops.setProperty(
+ "ca.publish.publisher.instance.LdapUserCertPublisher.certAttr",
+ "userCertificate;binary");
+ CMSprops.setProperty(
+ "ca.publish.publisher.instance.LdapUserCertPublisher.pluginName",
+ "LdapUserCertPublisher");
+ }
+
+ public void CreateOCSPPublisher(String OCSPHost, String OCSPPort, String OCSPEEPort) {
+ // Set host nmae with fully qualified hostname
+ String location = "http://" + OCSPHost + ":" + OCSPEEPort + "/ocsp";
+
+ CMSprops.setProperty("ca.crl.MasterCRL.alwaysUpdate", "true");
+ CMSprops.setProperty(
+ "ca.publish.publisher.instance.CAOCSPPublisher.host", OCSPHost);
+ CMSprops.setProperty(
+ "ca.publish.publisher.instance.CAOCSPPublisher.path",
+ "/ocsp/addCRL");
+ CMSprops.setProperty(
+ "ca.publish.publisher.instance.CAOCSPPublisher.pluginName",
+ "OCSPPublisher");
+ CMSprops.setProperty(
+ "ca.publish.publisher.instance.CAOCSPPublisher.port", OCSPPort);
+ CMSprops.setProperty(
+ "ca.publish.rule.instance.OCSPPublishingRule.enable", "true");
+ CMSprops.setProperty(
+ "ca.publish.rule.instance.OCSPPublishingRule.mapper", "");
+ CMSprops.setProperty(
+ "ca.publish.rule.instance.OCSPPublishingRule.pluginName", "Rule");
+ CMSprops.setProperty(
+ "ca.publish.rule.instance.OCSPPublishingRule.predicate", "");
+ CMSprops.setProperty(
+ "ca.publish.rule.instance.OCSPPublishingRule.publisher",
+ "CAOCSPPublisher");
+ CMSprops.setProperty("ca.publish.rule.instance.OCSPPublishingRule.type",
+ "crl");
+ CMSprops.setProperty("ca.Policy.rule.AuthInfoAccessExt.ad0_location",
+ location);
+ CMSprops.setProperty(
+ "ca.Policy.rule.AuthInfoAccessExt.ad0_location_type", "URL");
+ CMSprops.setProperty("ca.Policy.rule.AuthInfoAccessExt.ad0_method",
+ "ocsp");
+ CMSprops.setProperty("ca.Policy.rule.AuthInfoAccessExt.critical",
+ "false");
+ CMSprops.setProperty("ca.Policy.rule.AuthInfoAccessExt.enable", "true");
+ CMSprops.setProperty("ca.Policy.rule.AuthInfoAccessExt.implName",
+ "AuthInfoAccessExt");
+ CMSprops.setProperty("ca.Policy.rule.AuthInfoAccessExt.numADs", "1");
+ CMSprops.setProperty("ca.Policy.rule.AuthInfoAccessExt.predicate",
+ "HTTP_PARAMS.certType == client");
+
+ }
+
+ public void EnableOCSPLDAPStore(String certInstanceID) {
+ String certNickName = "ocspSigningCert cert-" + certInstanceID;
+
+ CMSprops.setProperty("ocsp.storeId", "ldapStore");
+ CMSprops.setProperty("ocsp.store.defStore.byName", "true");
+ CMSprops.setProperty("ocsp.store.defStore.class",
+ "com.netscape.cms.ocsp.DefStore");
+ CMSprops.setProperty("ocsp.store.defStore.includeNextUpdate", "true");
+ CMSprops.setProperty("ocsp.store.defStore.notFoundAsGood", "true");
+ CMSprops.setProperty("ocsp.store.ldapStore.baseDN0", ldapBaseSuffix);
+ CMSprops.setProperty("ocsp.store.ldapStore.byName", "true");
+ CMSprops.setProperty("ocsp.store.ldapStore.caCertAttr",
+ "cACertificate;binary");
+ CMSprops.setProperty("ocsp.store.ldapStore.class",
+ "com.netscape.cms.ocsp.LDAPStore");
+ CMSprops.setProperty("ocsp.store.ldapStore.crlAttr",
+ "certificateRevocationList;binary");
+ CMSprops.setProperty("ocsp.store.ldapStore.host0", ldapHost);
+ CMSprops.setProperty("ocsp.store.ldapStore.includeNextUpdate", "true");
+ CMSprops.setProperty("ocsp.store.ldapStore.notFoundAsGood", "true");
+ CMSprops.setProperty("ocsp.store.ldapStore.numConns", "1");
+ CMSprops.setProperty("ocsp.store.ldapStore.port0", ldapPort);
+ CMSprops.setProperty("ocsp.store.ldapStore.refreshInSec0", "864");
+ CMSprops.setProperty("ocsp.signing.certnickname", certNickName);
+ CMSprops.setProperty("ocsp.signing.defaultSigningAlgorithm",
+ "MD5withRSA");
+ CMSprops.setProperty("ocsp.signing.tokenname", "internal");
+
+ }
+
+ public void SetupKRAConnectorInCA(String certInstanceID, String KRAHost, String KRAPort) {
+ String certNickName = "Server-Cert " + certInstanceID;
+
+ CMSprops.setProperty("ca.connector.KRA.enable", "true");
+ CMSprops.setProperty("ca.connector.KRA.host", KRAHost);
+ CMSprops.setProperty("ca.connector.KRA.local", "false");
+ CMSprops.setProperty("ca.connector.KRA.nickName", certNickName);
+ CMSprops.setProperty("ca.connector.KRA.port", KRAPort);
+ CMSprops.setProperty("ca.connector.KRA.timeout", "30");
+ CMSprops.setProperty("ca.connector.KRA.uri", "/kra/connector");
+
+ }
+
+ public void DisableCardCryptoValidationinTKS() {
+ CMSprops.setProperty("cardcryptogram.validate.enable", "false");
+ }
+
+ // Policies
+ public void DefaultValidityRule(String SubsystemType, String lagtime, String leadtime, String maxValidity) {
+ if (SubsystemType.equals("ca")) {
+ CMSprops.setProperty("ca.Policy.rule.DefaultValidityRule.enable",
+ "true");
+ CMSprops.setProperty("ca.Policy.rule.DefaultValidityRule.implName",
+ "ValidityConstraints");
+ CMSprops.setProperty("ca.Policy.rule.DefaultValidityRule.lagTime",
+ lagtime);
+ CMSprops.setProperty("ca.Policy.rule.DefaultValidityRule.leadTime",
+ leadtime);
+ CMSprops.setProperty(
+ "ca.Policy.rule.DefaultValidityRule.maxValidity",
+ maxValidity);
+ CMSprops.setProperty(
+ "ca.Policy.rule.DefaultValidityRule.minValidity", "1");
+ CMSprops.setProperty(
+ "ca.Policy.rule.DefaultValidityRule.notBeforeSkew", "5");
+ CMSprops.setProperty("ca.Policy.rule.DefaultValidityRule.predicate",
+ null);
+ } else {
+
+ CMSprops.setProperty("ra.Policy.rule.DefaultValidityRule.enable",
+ "true");
+ CMSprops.setProperty("ra.Policy.rule.DefaultValidityRule.implName",
+ "ValidityConstraints");
+ CMSprops.setProperty("ra.Policy.rule.DefaultValidityRule.lagTime",
+ lagtime);
+ CMSprops.setProperty("ra.Policy.rule.DefaultValidityRule.leadTime",
+ leadtime);
+ CMSprops.setProperty(
+ "ra.Policy.rule.DefaultValidityRule.maxValidity",
+ maxValidity);
+ CMSprops.setProperty(
+ "ra.Policy.rule.DefaultValidityRule.minValidity", "1");
+ CMSprops.setProperty(
+ "ra.Policy.rule.DefaultValidityRule.notBeforeSkew", "5");
+ CMSprops.setProperty("ra.Policy.rule.DefaultValidityRule.predicate",
+ null);
+ }
+
+ }
+
+ // Main Function
+ public static void main(String args[]) {
+ System.out.println(args.length);
+
+ if (args.length < 1) {
+ System.out.println("Usage : ConfigFilePath");
+ System.exit(-1);
+ }
+
+ CMSConfig s = new CMSConfig(args[0]);
+
+ // boolean secureC = false;
+ // s.EnableDirEnrollment(secureC);
+ s.saveCMSConfig();
+
+ }// end of function main
+
+} // end of class
+
diff --git a/base/silent/src/com/netscape/pkisilent/common/CMSLDAP.java b/base/silent/src/com/netscape/pkisilent/common/CMSLDAP.java
new file mode 100644
index 000000000..91a273df6
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/common/CMSLDAP.java
@@ -0,0 +1,609 @@
+package com.netscape.pkisilent.common;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.ByteArrayInputStream;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPModification;
+import netscape.ldap.LDAPModificationSet;
+import netscape.ldap.LDAPSearchResults;
+import netscape.ldap.LDAPv2;
+
+/**
+ * CMS Test framework .
+ * Using this class you can add a user and user certificate to LDAP server.
+ * You can also check if a certificate / CRL is published in LDAP server
+ * USe this class to turn of SSL and turn on SSL in a LDAP server.
+ */
+
+public class CMSLDAP {
+
+ private String HOST, DN, BASEDN, PASSWORD;
+ private int PORT;
+
+ private LDAPConnection conn = new LDAPConnection();
+
+ public CMSLDAP() {
+ }
+
+ /**
+ * Constructor. Takes parametes ldaphost, ldapport
+ */
+ public CMSLDAP(String h, String p) {
+ HOST = h;
+ PORT = Integer.parseInt(p);
+ }
+
+ /**
+ * Cosntructor. Takes parameters ldaphost,ldapport,ldapbinddn, ldapbindnpassword.
+ */
+ public CMSLDAP(String h, String p, String dn, String pwd) {
+ HOST = h;
+ PORT = Integer.parseInt(p);
+ DN = dn;
+ PASSWORD = pwd;
+ }
+
+ /**
+ * Connect to ldap server
+ */
+
+ public boolean connect() {
+ try {
+ conn.connect(HOST, PORT, DN, PASSWORD);
+ return true;
+ } catch (Exception e) {
+ System.out.println("ERROR: " + e.toString());
+ return false;
+ }
+ }
+
+ /**
+ * Disconnect form ldap server
+ */
+
+ public void disconnect() {
+
+ if ((conn != null) && conn.isConnected()) {
+ try {
+ conn.disconnect();
+ } catch (Exception e) {
+ System.out.println("ERROR: " + e.toString());
+ }
+
+ }
+
+ }
+
+ /**
+ * Search for certificaterevocationList attribute. Takes basedn and filter as parameters
+ */
+
+ public boolean searchCRL(String basedn, String filter) throws LDAPException {
+ int searchScope = LDAPv2.SCOPE_SUB;
+ String getAttrs[] = { "certificateRevocationList;binary" };
+ LDAPSearchResults results = conn.search(basedn, searchScope, filter,
+ getAttrs, false);
+
+ if (results == null) {
+ System.out.println("Could not search");
+ return false;
+ }
+ while (results.hasMoreElements()) {
+ LDAPEntry entry = (LDAPEntry) results.nextElement();
+
+ System.out.println(entry.getDN());
+ LDAPAttribute anAttr = entry.getAttribute(
+ "certificateRevocationList;binary");
+
+ if (anAttr == null) {
+ System.out.println("Attribute not found ");
+ return false;
+ } else {
+ System.out.println(anAttr.getName());
+ System.out.println(anAttr.getByteValueArray());
+ return true;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Search for attriburte usercertificate. Takes parameters basedn and filter
+ */
+
+ public boolean searchUserCert(String basedn, String filter) throws LDAPException {
+ int searchScope = LDAPv2.SCOPE_SUB;
+ String getAttrs[] = { "usercertificate;binary" };
+ LDAPSearchResults results = conn.search(basedn, searchScope, filter,
+ getAttrs, false);
+
+ if (results == null) {
+ System.out.println("Could not search");
+ return false;
+ }
+ while (results.hasMoreElements()) {
+ LDAPEntry entry = (LDAPEntry) results.nextElement();
+
+ System.out.println(entry.getDN());
+ LDAPAttribute anAttr = entry.getAttribute("usercertificate;binary");
+
+ if (anAttr == null) {
+ System.out.println("Attribute not found ");
+ return false;
+ } else {
+ System.out.println(anAttr.getName());
+ System.out.println(anAttr.getByteValueArray());
+ return true;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Adds a user to direcrtory server . Takes parameters basedn, cn,sn,uid and passwd
+ */
+
+ public boolean userAdd(String basedn, String cn, String sn, String uid, String pwd) {
+ try {
+ LDAPAttributeSet attrSet = new LDAPAttributeSet();
+
+ attrSet.add(
+ new LDAPAttribute("objectclass",
+ new String[] {
+ "top", "person", "organizationalPerson",
+ "inetorgperson" }));
+ attrSet.add(new LDAPAttribute("cn", cn));
+ attrSet.add(new LDAPAttribute("mail", uid + "@netscape.com"));
+ attrSet.add(new LDAPAttribute("userpassword", pwd));
+ attrSet.add(new LDAPAttribute("sn", sn));
+ attrSet.add(new LDAPAttribute("givenName", cn + sn));
+ String name = "uid=" + uid + "," + basedn;
+
+ System.out.println("Basedn " + name);
+ LDAPEntry entry = new LDAPEntry(name, attrSet);
+
+ conn.add(entry);
+ System.out.println("ADDED: " + name);
+ return true;
+ } catch (Exception e) {
+ System.out.println("ERROR: " + e.toString());
+ return false;
+ }
+
+ }
+
+ private X509Certificate getXCertificate(byte[] cpack) {
+
+ try {
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ ByteArrayInputStream s = new ByteArrayInputStream(cpack);
+
+ System.out.println("Building certificate :" + cpack);
+ java.security.cert.X509Certificate the_cert = (
+ java.security.cert.X509Certificate) cf.generateCertificate(s);
+
+ return the_cert;
+ } catch (Exception e) {
+ System.out.println("ERROR: getXCertificate " + e.toString());
+ return null;
+ }
+
+ }
+
+ private String buildDNString(String s) {
+
+ String val = "";
+
+ for (int i = 0; i < s.length(); i++) {
+ if ((s.charAt(i) == ',') && (s.charAt(i + 1) == ' ')) {
+ val += ',';
+ i++;
+ continue;
+ } else {
+ val += s.charAt(i);
+ }
+ }
+ return val;
+ }
+
+ /**
+ * Returns the SerialNumber;issuerDN;SubjectDN string.
+ * Takes certificate as parameter
+ */
+
+ public String getCertificateString(X509Certificate cert) {
+ if (cert == null) {
+ return null;
+ }
+ String idn = ((cert.getIssuerDN()).toString()).trim();
+
+ idn = buildDNString(idn);
+ String sdn = ((cert.getSubjectDN()).toString()).trim();
+
+ sdn = buildDNString(sdn);
+
+ System.out.println("GetCertificateString : " + idn + ";" + sdn);
+
+ // note that it did not represent a certificate fully
+ // return cert.getVersion() + ";" + cert.getSerialNumber().toString() +
+ // ";" + cert.getIssuerDN() + ";" + cert.getSubjectDN();
+ return "2;" + cert.getSerialNumber().toString() + ";" + idn + ";" + sdn;
+
+ }
+
+ /**
+ * Adds a user of objectclass cmsuser . Takes cn,sn,uid,password,certificate as parameters.
+ */
+ public boolean CMSuserAdd(String cn, String sn, String uid, String pwd, byte[] certpack) {
+ try {
+ X509Certificate cert = getXCertificate(certpack);
+
+ LDAPAttributeSet attrSet = new LDAPAttributeSet();
+
+ attrSet.add(
+ new LDAPAttribute("objectclass",
+ new String[] {
+ "top", "person", "organizationalPerson",
+ "inetorgperson", "cmsuser" }));
+ attrSet.add(new LDAPAttribute("cn", cn));
+ attrSet.add(new LDAPAttribute("mail", uid + "@netscape.com"));
+ attrSet.add(new LDAPAttribute("userpassword", pwd));
+ attrSet.add(new LDAPAttribute("sn", sn));
+ attrSet.add(new LDAPAttribute("givenName", cn + sn));
+ attrSet.add(new LDAPAttribute("usertype", "sub"));
+ attrSet.add(new LDAPAttribute("userstate", "1"));
+
+ attrSet.add(
+ new LDAPAttribute("description", getCertificateString(cert)));
+ LDAPAttribute attrCertBin = new LDAPAttribute("usercertificate");
+
+ attrCertBin.addValue(cert.getEncoded());
+ attrSet.add(attrCertBin);
+
+ String name = "uid=" + uid + ","
+ + "ou=People,o=netscapecertificateServer";
+ LDAPEntry entry = new LDAPEntry(name, attrSet);
+
+ conn.add(entry);
+ System.out.println("ADDED: " + name);
+ return true;
+ } catch (Exception e) {
+ System.out.println("ERROR: " + e.toString());
+ return false;
+ }
+
+ }
+
+ /**
+ * Adds a user of objectclass cmsuser . Takes cn,sn,uid,password,certificate as parameters.
+ */
+
+ public boolean CMSuserAdd(String cn, String sn, String uid, String pwd, X509Certificate cert) {
+
+ try {
+ LDAPAttributeSet attrSet = new LDAPAttributeSet();
+
+ attrSet.add(
+ new LDAPAttribute("objectclass",
+ new String[] {
+ "top", "person", "organizationalPerson",
+ "inetorgperson", "cmsuser" }));
+ attrSet.add(new LDAPAttribute("cn", cn));
+ attrSet.add(new LDAPAttribute("mail", uid + "@netscape.com"));
+ attrSet.add(new LDAPAttribute("userpassword", pwd));
+ attrSet.add(new LDAPAttribute("sn", sn));
+ attrSet.add(new LDAPAttribute("givenName", cn + sn));
+ attrSet.add(new LDAPAttribute("usertype", "sub"));
+ attrSet.add(new LDAPAttribute("userstate", "1"));
+
+ attrSet.add(
+ new LDAPAttribute("description", getCertificateString(cert)));
+
+ LDAPAttribute attrCertBin = new LDAPAttribute("usercertificate");
+
+ attrCertBin.addValue(cert.getEncoded());
+ attrSet.add(attrCertBin);
+
+ String name = "uid=" + uid + ","
+ + "ou=People,o=netscapecertificateServer";
+ LDAPEntry entry = new LDAPEntry(name, attrSet);
+
+ conn.add(entry);
+ System.out.println("ADDED: " + name);
+ } catch (Exception e) {
+ System.out.println("ERROR: " + e.toString());
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * adds a cms user to Trusted Manager Group. Takes uid as parameter.
+ */
+
+ public boolean addCMSUserToTMGroup(String uid) {
+ try {
+ LDAPAttributeSet attrSet = new LDAPAttributeSet();
+ LDAPAttribute um = new LDAPAttribute("uniquemember",
+ "uid=" + uid + ",ou=People,o=NetscapeCertificateServer");
+
+ attrSet.add(um);
+ LDAPModification gr = new LDAPModification(LDAPModification.ADD, um);
+
+ String dn = "cn=Trusted Managers,ou=groups,o=netscapeCertificateServer";
+
+ conn.modify(dn, gr);
+ return true;
+
+ } catch (Exception e) {
+ System.out.println("ERROR: " + e.toString());
+ return false;
+ }
+
+ }
+
+ /**
+ * adds a cms user to Agent Group. Takes subsytem (ca/ra/ocsp/kra) and uid as parameters .
+ */
+
+ public boolean addCMSUserToAgentGroup(String subsystem, String uid) {
+ try {
+ String dn = null;
+
+ if (subsystem.equals("ocsp")) {
+ dn = "cn=Online Certificate Status Manager Agents,ou=groups,o=netscapeCertificateServer";
+ }
+ if (subsystem.equals("kra")) {
+ dn = "cn=Data Recovery Manager Agents,ou=groups,o=netscapeCertificateServer";
+ }
+ if (subsystem.equals("ra")) {
+ dn = "cn=Registration Manager Agents,ou=groups,o=netscapeCertificateServer";
+ }
+ if (subsystem.equals("ca")) {
+ dn = "cn=Certificate Manager Agents,ou=groups,o=netscapeCertificateServer";
+ }
+ if (subsystem.equals("tks")) {
+ dn = "cn=Token Key Service Manager Agents,ou=groups,o=netscapeCertificateServer";
+ }
+
+ LDAPAttributeSet attrSet = new LDAPAttributeSet();
+ LDAPAttribute um = new LDAPAttribute("uniquemember",
+ "uid=" + uid + ",ou=People,o=NetscapeCertificateServer");
+
+ System.out.println(
+ "uid=" + uid + ",ou=People,o=NetscapeCertificateServer");
+
+ attrSet.add(um);
+ LDAPModification gr = new LDAPModification(LDAPModification.ADD, um);
+
+ conn.modify(dn, gr);
+
+ return true;
+
+ } catch (Exception e) {
+ System.out.println("ERROR: " + e.toString());
+ return false;
+ }
+
+ }
+
+ /**
+ * Will trun of SSL in LDAP server
+ **/
+
+ public boolean TurnOffSSL() {
+ try {
+
+ LDAPModificationSet mods = new LDAPModificationSet();
+ LDAPAttribute ssl3 = new LDAPAttribute("nsssl3", "off");
+ LDAPAttribute ssl3ciphers = new LDAPAttribute("nsssl3ciphers", "");
+ LDAPAttribute kfile = new LDAPAttribute("nskeyfile", "alias/");
+ LDAPAttribute cfile = new LDAPAttribute("nscertfile", "alias/");
+ LDAPAttribute cauth = new LDAPAttribute("nssslclientauth", "allowed");
+
+ // conn.delete("cn=RSA,cn=encryption,cn=config");
+
+ mods.add(LDAPModification.REPLACE, ssl3);
+ mods.add(LDAPModification.DELETE, ssl3ciphers);
+ mods.add(LDAPModification.DELETE, kfile);
+ mods.add(LDAPModification.DELETE, cfile);
+ mods.add(LDAPModification.DELETE, cauth);
+ System.out.println("going to mod");
+ // conn.modify("cn=encryption,cn=config",mods);
+ System.out.println("mod en=encryption");
+ int i = 4;
+
+ while (i >= 0) {
+ mods.removeElementAt(i);
+ i--;
+ }
+
+ LDAPAttribute sec = new LDAPAttribute("nsslapd-security", "off");
+
+ mods.add(LDAPModification.REPLACE, sec);
+ conn.modify("cn=config", mods);
+ System.out.println("mod cn=config");
+
+ return true;
+
+ } catch (Exception e) {
+ System.out.println("ERROR: " + e.toString());
+ return false;
+ }
+
+ }
+
+ /**
+ * Will Turn ON SSL in LDAP server . Takes certPrefix, certificatenickanme and sslport as parameters.
+ **/
+
+ public boolean TurnOnSSL(String certPrefix, String certName, String sslport) {
+ String CIPHERS =
+ "-rsa_null_md5,+rsa_fips_3des_sha,+rsa_fips_des_sha,+rsa_3des_sha,+rsa_rc4_128_md5,+rsa_des_sha,+rsa_rc2_40_md5,+rsa_rc4_40_md5";
+
+ try {
+ int searchScope = LDAPv2.SCOPE_SUB;
+ String getAttrs[] = { "nssslactivation" };
+
+ LDAPModificationSet mods = new LDAPModificationSet();
+ LDAPAttribute sec = new LDAPAttribute("nsslapd-security", "on");
+ LDAPAttribute sp = new LDAPAttribute("nsslapd-securePort", sslport);
+
+ mods.add(LDAPModification.REPLACE, sec);
+ mods.add(LDAPModification.REPLACE, sp);
+ conn.modify("cn=config", mods);
+ mods.removeElementAt(1);
+ mods.removeElementAt(0);
+
+ LDAPAttribute ssl3 = new LDAPAttribute("nsssl3", "on");
+ LDAPAttribute ssl3ciphers = new LDAPAttribute("nsssl3ciphers",
+ CIPHERS);
+ LDAPAttribute kfile = new LDAPAttribute("nskeyfile",
+ "alias/" + certPrefix + "-key3.db");
+ LDAPAttribute cfile = new LDAPAttribute("nscertfile",
+ "alias/" + certPrefix + "-cert7.db");
+ LDAPAttribute cauth = new LDAPAttribute("nssslclientauth", "allowed");
+
+ mods.add(LDAPModification.REPLACE, ssl3);
+ mods.add(LDAPModification.REPLACE, ssl3ciphers);
+ mods.add(LDAPModification.REPLACE, kfile);
+ mods.add(LDAPModification.REPLACE, cfile);
+ mods.add(LDAPModification.REPLACE, cauth);
+
+ conn.modify("cn=encryption,cn=config", mods);
+ int i = 4;
+
+ while (i >= 0) {
+ mods.removeElementAt(i);
+ i--;
+ }
+
+ // conn.delete("cn=RSA,cn=encryption,cn=config");
+ try {
+ conn.search(
+ "cn=RSA,cn=encryption,cn=config", searchScope, null,
+ getAttrs, false); // check for errors
+
+ LDAPAttribute cn = new LDAPAttribute("cn", "RSA");
+ LDAPAttribute ssltoken = new LDAPAttribute("nsssltoken",
+ "internal (software)");
+ LDAPAttribute activation = new LDAPAttribute("nssslactivation",
+ "on");
+ LDAPAttribute cname = new LDAPAttribute("nssslpersonalityssl",
+ certName);
+
+ mods.add(LDAPModification.REPLACE, cn);
+ mods.add(LDAPModification.REPLACE, ssltoken);
+ mods.add(LDAPModification.REPLACE, activation);
+ mods.add(LDAPModification.REPLACE, cname);
+
+ conn.modify("cn=RSA,cn=encryption,cn=config", mods);
+
+ } catch (Exception e1) {
+ LDAPAttributeSet attrSet = new LDAPAttributeSet();
+
+ attrSet.add(
+ new LDAPAttribute("objectclass",
+ new String[] { "top", "nsEncryptionModule" }));
+ attrSet.add(new LDAPAttribute("cn", "RSA"));
+ attrSet.add(
+ new LDAPAttribute("nsssltoken", "internal (software)"));
+ attrSet.add(new LDAPAttribute("nssslactivation", "on"));
+ attrSet.add(new LDAPAttribute("nssslpersonalityssl", certName));
+ LDAPEntry entry = new LDAPEntry("cn=RSA,cn=encryption,cn=config",
+ attrSet);
+
+ conn.add(entry);
+ }
+
+ return true;
+
+ } catch (Exception e) {
+ System.out.println("ERROR: " + e.toString());
+ return false;
+ }
+
+ }
+
+ public static void main(String args[]) {
+ String HOST = args[0];
+ // int PORT = Integer.parseInt(args[1]);
+ String PORT = args[1];
+ String DN = args[2];
+ String PASSWORD = args[3];
+ String BASEDN = args[4];
+
+ String s =
+ "MIICFzCCAYCgAwIBAgIBBjANBgkqhkiG9w0BAQQFADBDMRswGQYDVQQKExJhY2NlcHRhY25ldGVz\ndDEwMjQxFzAVBgNVBAsTDmFjY2VwdGFuY2V0ZXN0MQswCQYDVQQDEwJjYTAeFw0wMzA0MTEyMTUx\nMzZaFw0wNDA0MTAwOTQ2NTVaMFwxCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNTU0wxHTAbBgNVBAsT\nFHNzbHRlc3QxMDUwMDk3ODkzNzQ1MSAwHgYDVQQDExdqdXBpdGVyMi5uc2NwLmFvbHR3Lm5ldDBc\nMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDCsCTIIQ+bJMfPHi6kwa7HF+/xSTVHcpZ5zsodXsNWjPlD\noRu/5KAO8NotfwGnYmALWdYnqXCF0q0gkaJQalQTAgMBAAGjRjBEMA4GA1UdDwEB/wQEAwIFoDAR\nBglghkgBhvhCAQEEBAMCBkAwHwYDVR0jBBgwFoAUzxZkSySZT/Y3SxGMEiNyHnLUOPAwDQYJKoZI\nhvcNAQEEBQADgYEALtpqMOtZt6j5KlghDFgdg/dvf36nWiZwC1ap6+ka22shLkA/RjmOix97btzT\nQ+8LcmdkAW5iap4YbtrCu0wdN6IbIEXoQI1QGZBoKO2o02utssXANmTnRCyH/GX2KefQlp1NSRj9\nZNZ+GRT2Qk/8G5Ds9vVjm1I5+/AkzI9jS14=";
+
+ s = "-----BEGIN CERTIFICATE-----" + "\n" + s + "\n"
+ + "-----END CERTIFICATE-----\n";
+
+ try {
+
+ System.out.println(HOST + PORT + DN + PASSWORD + BASEDN);
+ CMSLDAP caIdb = new CMSLDAP(HOST, PORT, DN, PASSWORD);
+
+ /* FileInputStream fis = new FileInputStream("t1");
+ DataInputStream dis = new DataInputStream(fis);
+
+ byte[] bytes = new byte[dis.available()];
+ dis.readFully(bytes);
+
+ // bytes=s.getBytes();
+ */
+
+ if (!caIdb.connect()) {
+ System.out.println("Could not connect to CA internal DB port");
+ }
+
+ if (!caIdb.searchCRL("o=mcom.com", "uid=CManager")) {
+ System.out.println("CRL is not published");
+ }
+
+ // if(!caIdb.searchUserCert("o=mcom.com","uid=test"))
+ // System.out.println("USer cert is not published");
+
+ // if (!caIdb.CMSuserAdd("ra-trust" ,"ra-trust","ra-trust","netscape",bytes))
+ // {System.out.println("Trusted MAnager user Could not be add ");}
+
+ // if(!caIdb.addCMSUserToTMGroup("ra-trust"))
+ // {System.out.println("CMS user Could not be added to Trusted manager group "); }
+
+ // if(!caIdb.addCMSUserToAgentGroup("ra","ra-agent"))
+ // {System.out.println("CMS user Could not be added to Trusted manager group "); }
+ /* if(!caIdb.userAdd(BASEDN,"raeetest1","raeetest1","raeetest1","netscape"))
+ {System.out.println("CMS user Could not be added to Trusted manager group "); }
+ */
+
+ } catch (Exception e) {
+ System.out.println("ERROR: " + e.toString());
+ }
+
+ }
+}
diff --git a/base/silent/src/com/netscape/pkisilent/common/CMSProperties.java b/base/silent/src/com/netscape/pkisilent/common/CMSProperties.java
new file mode 100644
index 000000000..a4ba55d29
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/common/CMSProperties.java
@@ -0,0 +1,679 @@
+package com.netscape.pkisilent.common;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/*
+ * @(#)Properties.java 1.60 00/02/02
+ *
+ * Copyright 1995-2000 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * This software is the proprietary information of Sun Microsystems, Inc.
+ * Use is subject to license terms.
+ *
+ */
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.Date;
+import java.util.Enumeration;
+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.
+ * <p>
+ * 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.
+ * <p>
+ * <a name="encoding"></a> When saving properties to a stream or loading them from a stream, the ISO 8859-1 character
+ * encoding is used. For characters that cannot be directly represented in this encoding, <a
+ * href="http://java.sun.com/docs/books/jls/html/3.doc.html#100850">Unicode escapes</a> are used; however, only a single
+ * 'u' character is allowed in an escape sequence. The native2ascii tool can be used to convert property files to and
+ * from other character encodings.
+ *
+ * @see <a href="../../../tooldocs/solaris/native2ascii.html">native2ascii tool for Solaris</a>
+ * @see <a href="../../../tooldocs/win32/native2ascii.html">native2ascii tool for Windows</a>
+ *
+ * @author Arthur van Hoff
+ * @author Michael McCloskey
+ * @version 1.60, 02/02/00
+ * @since JDK1.0
+ */
+
+class CMSProperties extends Hashtable<String, String> {
+
+ /**
+ * use serialVersionUID from JDK 1.1.X for interoperability
+ */
+ private static final long serialVersionUID = 4112578634029874840L;
+
+ /**
+ * A property list that contains default values for any keys not
+ * found in this property list.
+ *
+ * @serial
+ */
+ protected CMSProperties defaults;
+
+ /**
+ * Creates an empty property list with no default values.
+ */
+ public CMSProperties() {
+ this(null);
+ }
+
+ /**
+ * Creates an empty property list with the specified defaults.
+ *
+ * @param defaults the defaults.
+ */
+ public CMSProperties(CMSProperties defaults) {
+ this.defaults = defaults;
+ }
+
+ /**
+ * Calls the hashtable method <code>put</code>. Provided for
+ * parallelism with the <tt>getProperty</tt> method. Enforces use of
+ * strings for property keys and values.
+ *
+ * @param key the key to be placed into this property list.
+ * @param value the value corresponding to <tt>key</tt>.
+ * @see #getProperty
+ * @since 1.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.
+ * The stream is assumed to be using the ISO 8859-1 character encoding.
+ * <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>&#92;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>
+ * &quot;apple, banana, pear, cantaloupe, watermelon,kiwi, mango&quot;
+ * </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 inStream 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 = new String("");
+ }
+ 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;
+ }
+ }
+
+ // Blank lines are ignored
+ if (keyStart == len) {
+ continue;
+ }
+
+ // 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
+ 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 &#92;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 &#92;uxxxx
+ * and writes out any of the characters in specialSaveChars
+ * with a preceding slash
+ */
+ private String saveConvert(String theString, boolean escapeSpace) {
+ int len = theString.length();
+ StringBuffer outBuffer = new StringBuffer(len * 2);
+
+ for (int x = 0; x < len; x++) {
+ char aChar = theString.charAt(x);
+
+ switch (aChar) {
+ case ' ':
+ if (x == 0 || escapeSpace) {
+ outBuffer.append('\\');
+ }
+
+ outBuffer.append(' ');
+ break;
+
+ case '\\':
+ outBuffer.append('\\');
+ outBuffer.append('\\');
+ break;
+
+ case '\t':
+ outBuffer.append('\\');
+ outBuffer.append('t');
+ break;
+
+ case '\n':
+ outBuffer.append('\\');
+ outBuffer.append('n');
+ break;
+
+ case '\r':
+ outBuffer.append('\\');
+ outBuffer.append('r');
+ break;
+
+ case '\f':
+ outBuffer.append('\\');
+ outBuffer.append('f');
+ break;
+
+ default:
+ if ((aChar < 0x0020) || (aChar > 0x007e)) {
+ 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 & 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 the Java 2 platform v1.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.
+ * The stream is written using the ISO 8859-1 character encoding.
+ * <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>&#92;u0020</code> and characters
+ * greater than <code>&#92;u007E</code> are written as <code>&#92;u</code><i>xxxx</i> for the appropriate
+ * hexadecimal value <i>xxxx</i>. Leading 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 IOException if writing this property list to the specified
+ * output stream throws an <tt>IOException</tt>.
+ * @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<String> e = keys(); e.hasMoreElements();) {
+ String key = e.nextElement();
+ String val = get(key);
+
+ key = saveConvert(key, true);
+
+ /* No need to escape embedded and trailing spaces for value, hence
+ * pass false to flag.
+ */
+ val = saveConvert(val, false);
+ 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 #setProperty
+ * @see #defaults
+ */
+ public String getProperty(String key) {
+ String oval = super.get(key);
+ String sval = (oval instanceof 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 #setProperty
+ * @see #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<String> propertyNames() {
+ Hashtable<String, String> h = new Hashtable<String, String>();
+
+ 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<String, String> h = new Hashtable<String, String>();
+
+ enumerate(h);
+ for (Enumeration<String> e = h.keys(); e.hasMoreElements();) {
+ String key = e.nextElement();
+ String val = 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<String, String> h = new Hashtable<String, String>();
+
+ enumerate(h);
+ for (Enumeration<String> e = h.keys(); e.hasMoreElements();) {
+ String key = e.nextElement();
+ String val = 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<String, String> h) {
+ if (defaults != null) {
+ defaults.enumerate(h);
+ }
+ for (Enumeration<String> e = keys(); e.hasMoreElements();) {
+ String key = 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/base/silent/src/com/netscape/pkisilent/common/CMSTask.java b/base/silent/src/com/netscape/pkisilent/common/CMSTask.java
new file mode 100644
index 000000000..4b6c75ba3
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/common/CMSTask.java
@@ -0,0 +1,190 @@
+package com.netscape.pkisilent.common;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import com.netscape.pkisilent.argparser.ArgParser;
+import com.netscape.pkisilent.argparser.StringHolder;
+
+/**
+ * CS Test framework .
+ * This class starts and stops CS server from command line
+ */
+
+public class CMSTask {
+
+ private static String operation;
+ private static String debug;
+ private static String serverRoot;
+ private Process p = null;
+
+ /**
+ * Constructor . Takes CMS server root as parameter
+ * for example (/export/qa/cert-jupiter2)
+ **/
+
+ public CMSTask() {// do nothing
+ }
+
+ public CMSTask(String sroot) {
+ serverRoot = sroot;
+ }
+
+ public boolean CMSStart() {
+
+ try {
+ System.out.println("Starting Certificate System:");
+ Runtime r = Runtime.getRuntime();
+
+ p = r.exec(serverRoot + "/start-cert");
+
+ InputStreamReader isr = new InputStreamReader(p.getInputStream());
+ BufferedReader br = new BufferedReader(isr);
+ String s = null;
+
+ try {
+ while ((s = br.readLine()) != null) {
+ if (s.indexOf("started") > 0) {
+ return true;
+ }
+ // do something
+ }
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+
+ return false;
+
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+
+ return false;
+ }
+
+ public boolean CMSStop() {
+ try {
+ Runtime r = Runtime.getRuntime();
+
+ System.out.println("Stopping Certificate System:");
+ p = r.exec(serverRoot + "/stop-cert");
+ BufferedReader br = new BufferedReader(
+ new InputStreamReader(p.getInputStream()));
+ String line;
+
+ while ((line = br.readLine()) != null) {
+ System.out.println(" " + line);
+ if (line.indexOf("server shut down") > -1) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ public boolean CMSRestart() {
+ try {
+ System.out.println("Restarting Certificate System:");
+ Runtime r = Runtime.getRuntime();
+
+ p = r.exec(serverRoot + "/restart-cert");
+ BufferedReader br = new BufferedReader(
+ new InputStreamReader(p.getInputStream()));
+ String line;
+
+ while ((line = br.readLine()) != null) {
+ System.out.println(" " + line);
+ if (line.indexOf("started") > -1) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ public boolean task() {
+ if (operation.equalsIgnoreCase("stop")) {
+ CMSStop();
+ return true;
+ }
+
+ if (operation.equalsIgnoreCase("start")) {
+ CMSStart();
+ return true;
+ }
+
+ if (operation.equalsIgnoreCase("restart")) {
+ CMSRestart();
+ return true;
+ }
+
+ return false;
+ }
+
+ public static void main(String args[]) {
+ CMSTask prof = new CMSTask();
+ // parse args
+ StringHolder x_instance_root = new StringHolder();
+ StringHolder x_operation = new StringHolder();
+
+ // parse the args
+ ArgParser parser = new ArgParser("CMSTask");
+
+ parser.addOption("-instance_root %s #CA Server Root", x_instance_root);
+ parser.addOption("-operation %s #CA operation [stop,start,restart]",
+ x_operation);
+
+ // and then match the arguments
+ String[] unmatched = null;
+
+ unmatched = parser.matchAllArgs(args, 0, ArgParser.EXIT_ON_UNMATCHED);
+
+ if (unmatched != null) {
+ System.out.println("ERROR: Argument Mismatch");
+ System.exit(-1);
+ }
+
+ // set variables
+ serverRoot = x_instance_root.value;
+ operation = x_operation.value;
+
+ boolean st = prof.task();
+
+ if (!st) {
+ System.out.println("ERROR");
+ }
+
+ System.out.println("SUCCESS");
+
+ } // end of function main
+
+} // end of class
+
diff --git a/base/silent/src/com/netscape/pkisilent/common/CertificateRecord.java b/base/silent/src/com/netscape/pkisilent/common/CertificateRecord.java
new file mode 100644
index 000000000..9599eb6dd
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/common/CertificateRecord.java
@@ -0,0 +1,44 @@
+package com.netscape.pkisilent.common;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+public class CertificateRecord {
+
+ public String revokedOn = null;
+ public String revokedBy = null;
+ public String revocation_info = null;
+ public String signatureAlgorithm = null;
+ public String serialNumber = null;
+ public String subjectPublicKeyLength = null;
+ public String type = null;
+ public String subject = null;
+ public String issuedOn = null;
+ public String validNotBefore = null;
+ public String validNotAfter = null;
+ public String issuedBy = null;
+ public String subjectPublicKeyAlgorithm = null;
+ public String certChainBase64 = null;
+ public String certFingerprint = null;
+ public String pkcs7ChainBase64 = null;
+ public String certPrettyPrint = null;
+
+ public CertificateRecord() {// Do nothing
+ }
+
+};
diff --git a/base/silent/src/com/netscape/pkisilent/common/ComCrypto.java b/base/silent/src/com/netscape/pkisilent/common/ComCrypto.java
new file mode 100644
index 000000000..d629030f2
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/common/ComCrypto.java
@@ -0,0 +1,767 @@
+package com.netscape.pkisilent.common;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.ByteArrayInputStream;
+import java.security.KeyPair;
+
+import netscape.security.x509.X500Name;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.BIT_STRING;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.crypto.AlreadyInitializedException;
+import org.mozilla.jss.crypto.CryptoStore;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.IVParameterSpec;
+import org.mozilla.jss.crypto.InternalCertificate;
+import org.mozilla.jss.crypto.KeyGenAlgorithm;
+import org.mozilla.jss.crypto.KeyGenerator;
+import org.mozilla.jss.crypto.KeyPairAlgorithm;
+import org.mozilla.jss.crypto.KeyPairGenerator;
+import org.mozilla.jss.crypto.KeyWrapAlgorithm;
+import org.mozilla.jss.crypto.KeyWrapper;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.crypto.SymmetricKey;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.pkcs11.PK11Token;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.crmf.CertTemplate;
+import org.mozilla.jss.pkix.crmf.EncryptedKey;
+import org.mozilla.jss.pkix.crmf.EncryptedValue;
+import org.mozilla.jss.pkix.crmf.PKIArchiveOptions;
+import org.mozilla.jss.pkix.crmf.POPOPrivKey;
+import org.mozilla.jss.pkix.crmf.ProofOfPossession;
+import org.mozilla.jss.pkix.primitive.AVA;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.pkix.primitive.Name;
+import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
+import org.mozilla.jss.util.Password;
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * CMS Test framework .
+ * Use this class to initalize,add a certificate ,generate a certificate request from certificate database.
+ */
+
+public class ComCrypto {
+
+ private String cdir, certnickname, keysize, keytype, tokenpwd;
+ private String certpackage, pkcs10request;
+ private boolean debug = true;
+ private boolean DBlogin = false;
+ private boolean generaterequest = false;
+
+ private String transportcert = null;
+ private boolean dualkey = false;
+ public String CRMF_REQUEST = null;
+ int START = 1;
+ int END = START + 1;
+ Password password = null;
+
+ public static CryptoManager manager;
+ public static CryptoToken token;
+ private CryptoStore store;
+ private Password pass1 = null, pass2 = null;
+
+ private String bstr = "-----BEGIN NEW CERTIFICATE REQUEST-----";
+ private String blob, Blob1 = null;
+ private String Blob2 = null;
+ private String estr = "-----END NEW CERTIFICATE REQUEST-----";
+
+ private String certprefix = null;
+
+ public ComCrypto() {
+ };
+
+ /**
+ * Constructor . Takes the parameter certificatedbdirectory , passwordfor cert database,
+ * certificatenickname,keysize, keytype(RSA/DSA)
+ *
+ * @param certdbdirectory.
+ * @param certdbpassword
+ * @param certnickname
+ * @param keysize (1024/2048/4096)
+ * @param keytype (RSA/DSA)
+ */
+
+ public ComCrypto(String cd, String tpwd, String cn, String ks, String kt) {
+ cdir = cd;
+ tokenpwd = tpwd;
+ certnickname = cn;
+ keysize = ks;
+ keytype = kt;
+ }
+
+ // Set and Get functions
+
+ public void setCertDir(String cd) {
+ cdir = cd;
+ }
+
+ public void setCertnickname(String cd) {
+ certnickname = cd;
+ }
+
+ public void setKeySize(String cd) {
+ keysize = cd;
+ }
+
+ public void setKeyType(String cd) {
+ keytype = cd;
+ }
+
+ public void setTokenPWD(String cd) {
+ tokenpwd = cd;
+ }
+
+ public void setCertPackage(String cd) {
+ certpackage = cd;
+ }
+
+ public void setGenerateRequest(boolean c) {
+ generaterequest = c;
+ }
+
+ public void setDebug(boolean t) {
+ debug = t;
+ }
+
+ public void setCertPrefix(String prefix) {
+ certprefix = prefix;
+ }
+
+ /*
+ * setTransportCert() should only be called when the calling profile
+ * needs to do key archivals with the DRM and make sure the function
+ * generateCRMFtransport() is called for the CRMF request generation
+ * part.
+ */
+ public void setTransportCert(String tcert) {
+ transportcert = tcert;
+ }
+
+ public void setDualKey(boolean dkey) {
+ dualkey = dkey;
+ }
+
+ public String getPkcs10Request() {
+ return pkcs10request;
+ }
+
+ /**
+ * Parses the Certificate and returns SubjectDN . Takes certificate as parameter
+ */
+
+ 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();
+ }
+
+ /**
+ * Finds and returns Certificate . Takes certificatenickname as parameter.
+ */
+
+ public X509Certificate findCert(String certname) {
+ try {
+
+ X509Certificate cert2 = manager.findCertByNickname(certname);
+
+ return cert2;
+
+ } catch (Exception e) {
+ System.out.println("exception importing cert " + e.getMessage());
+ return null;
+ }
+
+ }
+
+ /**
+ * Imports a certificate to Certificate Database. Takes certificate and nickname as parameters.
+ */
+
+ public boolean importCert(X509Certificate xcert, String nickname) {
+ try {
+
+ System.out.println(
+ "importCert x509 : importing with nickname: " + nickname);
+
+ InternalCertificate cert2 = manager.importCertToPerm(xcert, nickname);
+
+ cert2.setSSLTrust(2);
+ return true;
+
+ } catch (Exception e) {
+ System.out.println("exception importing cert " + e.getMessage());
+ return false;
+ }
+
+ }
+
+ /**
+ * Imports a certificate to Certificate Database. Takes certificate and nickname as parameters.
+ */
+
+ public boolean importCert(String cpack, String cn) {
+
+ System.out.println("importCert string: importing with nickname: " + cn);
+ try {
+
+ String tmp = normalize(cpack);
+
+ if (DBlogin) {
+ System.out.println("Already logged into to DB");
+ }
+
+ if (manager == null) {
+ System.out.println("Manager object is null");
+ }
+
+ manager.importCertPackage(tmp.getBytes(), cn);
+
+ return true;
+
+ } catch (Exception e) {
+ System.out.println(
+ "ERROR:exception importing cert " + e.getMessage());
+ e.printStackTrace();
+ return false;
+ }
+
+ }
+
+ /* imports CA certificate
+ */
+
+ public boolean importCACert(String cpack) {
+
+ try {
+ String tmp = normalize(cpack);
+
+ if (DBlogin) {
+ System.out.println("Already logged into to DB");
+ }
+
+ if (manager == null) {
+ System.out.println("Manager object is null");
+ }
+
+ manager.importCACertPackage(tmp.getBytes());
+
+ return true;
+
+ } catch (Exception e) {
+ System.out.println(
+ "ERROR:exception importing cert " + e.getMessage());
+ return false;
+ }
+
+ }
+
+ /**
+ * Normalizes a given certificate string . Removes the extra \\ in the certificate returned by CMS server.
+ */
+
+ public String normalize(String s) {
+
+ String val = "";
+
+ for (int i = 0; i < s.length(); i++) {
+ if ((s.charAt(i) == '\\') && (s.charAt(i + 1) == 'n')) {
+ val += '\n';
+ i++;
+ continue;
+ } else if ((s.charAt(i) == '\\') && (s.charAt(i + 1) == 'r')) {
+ i++;
+ continue;
+ } else if (s.charAt(i) == '"') {
+ continue;
+ }
+ val += s.charAt(i);
+ }
+ return val;
+ }
+
+ /**
+ * Normalizes a given certificate string . Removes the extra \\ in the certificate returned by CMS server.
+ */
+
+ public String normalizeForLDAP(String s) {
+
+ String val = "";
+
+ for (int i = 0; i < s.length(); i++) {
+ if ((s.charAt(i) == '\\') && (s.charAt(i + 1) == 'n')) {
+ val += '\n' + " ";
+ i++;
+ continue;
+ } else if ((s.charAt(i) == '\\') && (s.charAt(i + 1) == 'r')) {
+ i++;
+ continue;
+ } else if (s.charAt(i) == '"') {
+ continue;
+ }
+ val += s.charAt(i);
+ }
+ return val;
+ }
+
+ /**
+ * Convert to pkcs7 format
+ */
+
+ public String pkcs7Convertcert(String s) {
+
+ String val = "";
+
+ int len = s.length();
+
+ for (int i = 0; i < len; i = i + 64) {
+
+ if (i + 64 < len) {
+ val = val + s.substring(i, i + 64) + "\n";
+ } else {
+ val = val + s.substring(i, len);
+ }
+
+ }
+ return val;
+ }
+
+ /**
+ * Delete all keys frim key3.db
+ **/
+
+ public void deleteKeys() {
+ try {
+ int i = 0;
+
+ store = token.getCryptoStore();
+ PrivateKey[] keys = store.getPrivateKeys();
+
+ if (debug) {
+ System.out.println("Now we shall delete all the keys!");
+ }
+
+ keys = store.getPrivateKeys();
+ for (i = 0; i < keys.length; i++) {
+ PrivateKey key = (PrivateKey) keys[i];
+
+ store.deletePrivateKey(key);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Creates a new certificate database
+ **/
+
+ public boolean CreateCertDB() {
+ return loginDB();
+
+ }
+
+ /**
+ * Login to cert database
+ **/
+
+ public boolean loginDB() {
+ Password pass1 = null;
+
+ try {
+ if (debug) {
+ System.out.println("CRYPTO INIT WITH CERTDB:" + cdir);
+ }
+
+ // this piece of code is to create db's with certain prefix
+ if (certprefix != null) {
+ CryptoManager.InitializationValues vals;
+
+ vals = new CryptoManager.InitializationValues(cdir, certprefix,
+ certprefix, "secmod.db");
+ CryptoManager.initialize(vals);
+ } else {
+ CryptoManager.initialize(cdir);
+ }
+
+ manager = CryptoManager.getInstance();
+ token = (PK11Token) manager.getInternalKeyStorageToken();
+ pass1 = new Password(tokenpwd.toCharArray());
+ if (token.isLoggedIn() && debug) {
+ System.out.println("Already Logged in ");
+ }
+
+ if (debug) {
+ System.out.println("tokenpwd:" + tokenpwd);
+ }
+
+ token.login(pass1);
+ pass1.clear();
+
+ } catch (AlreadyInitializedException e) {
+ if (debug) {
+ System.out.println("Crypto manager already initialized");
+ }
+ } catch (Exception e) {
+ try {
+ if (!token.isLoggedIn()) {
+ token.initPassword(pass1, pass1);
+ }
+ return true;
+ } catch (Exception er) {
+ System.err.println("some exception:" + e);
+ return false;
+ }
+ }
+ DBlogin = true;
+ return true;
+ }
+
+ /**
+ * Generate Certificate Request
+ **/
+
+ public synchronized boolean generateRequest() {
+
+ System.out.println("generating pkcs10 Request");
+ loginDB();
+
+ try {
+ debug = true;
+ System.out.println("Generating request : keysize :" + keysize);
+ System.out.println("Generating request : subject :" + certnickname);
+ System.out.println("Generating request : keytype :" + keytype);
+
+ Integer n = new Integer(keysize);
+
+ if (generaterequest) {
+ blob = token.generateCertRequest(certnickname, n.intValue(),
+ keytype, (byte[]) null, (byte[]) null, (byte[]) null);
+
+ System.out.println("Cert Request Generated.");
+
+ bstr = "-----BEGIN NEW CERTIFICATE REQUEST-----";
+ Blob1 = blob.substring(bstr.length() + 1);
+ Blob2 = Blob1.substring(0, Blob1.indexOf(estr));
+
+ System.out.println(Blob2);
+ pkcs10request = Blob2;
+ }
+
+ return true;
+
+ } catch (Exception e) {
+ System.out.println("Exception: Unable to generate request: " + e);
+ }
+
+ return false;
+ }
+
+ public String generateCRMFrequest() {
+ KeyPair pair = null;
+
+ System.out.println("Debug : initialize crypto Manager");
+ try {
+
+ // Step 1. initialize crypto Manager
+ try {
+ CryptoManager.initialize(cdir);
+ } catch (Exception e) {
+ // it is ok if it is already initialized
+ System.out.println("INITIALIZATION ERROR: " + e.toString());
+ System.out.println("cdir = " + cdir);
+ }
+
+ // Step 2 log into database
+ try {
+
+ System.out.println("Debug : before getInstance");
+
+ manager = CryptoManager.getInstance();
+ String token_pwd = tokenpwd;
+
+ System.out.println("Debug : before get token");
+
+ token = manager.getInternalKeyStorageToken();
+ password = new Password(token_pwd.toCharArray());
+
+ System.out.println("Debug : before login password");
+
+ token.login(password);
+
+ System.out.println("Debug : after login password");
+ } catch (Exception e) {
+ System.out.println("INITIALIZATION ERROR: " + e.toString());
+
+ if (!token.isLoggedIn()) {
+ token.initPassword(password, password);
+ }
+ }
+
+ // Generating CRMF request
+
+ KeyPairGenerator kg = token.getKeyPairGenerator(KeyPairAlgorithm.RSA);
+
+ Integer x = new Integer(keysize);
+ int key_len = x.intValue();
+
+ kg.initialize(key_len);
+
+ // 1st key pair
+ pair = kg.genKeyPair();
+
+ // create CRMF
+ CertTemplate certTemplate = new CertTemplate();
+
+ certTemplate.setVersion(new INTEGER(2));
+
+ if (certnickname != null) {
+ X500Name name = new X500Name(certnickname);
+ ByteArrayInputStream cs = new ByteArrayInputStream(name.getEncoded());
+ Name n = (Name) Name.getTemplate().decode(cs);
+ certTemplate.setSubject(n);
+ }
+
+ certTemplate.setPublicKey(new SubjectPublicKeyInfo(pair.getPublic()));
+
+ SEQUENCE seq = new SEQUENCE();
+ CertRequest certReq = new CertRequest(new INTEGER(1), certTemplate,
+ seq);
+ byte popdata[] = { 0x0, 0x3, 0x0 };
+
+ ProofOfPossession pop = ProofOfPossession.createKeyEncipherment(
+ POPOPrivKey.createThisMessage(new BIT_STRING(popdata, 3)));
+
+ CertReqMsg crmfMsg = new CertReqMsg(certReq, pop, null);
+
+ SEQUENCE s1 = new SEQUENCE();
+
+ // 1st : Encryption key
+
+ s1.addElement(crmfMsg);
+
+ // 2nd : Signing Key
+
+ if (dualkey) {
+ System.out.println("dualkey = true");
+ SEQUENCE seq1 = new SEQUENCE();
+ CertRequest certReqSigning = new CertRequest(new INTEGER(1),
+ certTemplate, seq1);
+ CertReqMsg signingMsg = new CertReqMsg(certReqSigning, pop, null);
+
+ s1.addElement(signingMsg);
+ }
+
+ byte encoded[] = ASN1Util.encode(s1);
+
+ // BASE64Encoder encoder = new BASE64Encoder();
+ // String Req1 = encoder.encodeBuffer(encoded);
+ String Req1 = Utils.base64encode(encoded);
+
+ // Set CRMF_REQUEST variable
+ CRMF_REQUEST = Req1;
+
+ System.out.println("CRMF_REQUEST = " + CRMF_REQUEST);
+
+ } catch (Exception e) {
+ System.out.println("ERROR: " + e.toString());
+ e.printStackTrace();
+ return null;
+ }
+
+ return CRMF_REQUEST;
+ }
+
+ /*
+ * This function is used to Generated CRMF requests wrapped with the
+ * transport cert so that we can do key archival with the drm.
+ * This function expects transportcert variable to be set in this class.
+ * Use setTransportCert() to do the same.
+ */
+
+ public String generateCRMFtransport() {
+
+ KeyPair pair = null;
+
+ try {
+ // Step 1. initialize crypto Manager
+ try {
+ CryptoManager.initialize(cdir);
+ } catch (Exception e) {
+ // it is ok if it is already initialized
+ System.out.println("INITIALIZATION ERROR: " + e.toString());
+ System.out.println("cdir = " + cdir);
+ }
+
+ // Step 2 log into database
+ try {
+
+ System.out.println("Debug : before getInstance");
+
+ manager = CryptoManager.getInstance();
+ String token_pwd = tokenpwd;
+
+ System.out.println("Debug : before get token");
+
+ token = manager.getInternalKeyStorageToken();
+ password = new Password(token_pwd.toCharArray());
+
+ System.out.println("Debug : before login password");
+
+ token.login(password);
+
+ System.out.println("Debug : after login password");
+ } catch (Exception e) {
+ System.out.println("INITIALIZATION ERROR: " + e.toString());
+
+ if (!token.isLoggedIn()) {
+ token.initPassword(password, password);
+ }
+ }
+
+ // Key Pair Generation
+ KeyPairGenerator kg = token.getKeyPairGenerator(KeyPairAlgorithm.RSA);
+ Integer x = new Integer(keysize);
+ int key_len = x.intValue();
+
+ kg.initialize(key_len);
+
+ pair = kg.genKeyPair();
+
+ // wrap private key
+ // BASE64Decoder decoder = new BASE64Decoder();
+ // byte transport[] = decoder.decodeBuffer(transportcert);
+ byte transport[] = Utils.base64decode(transportcert);
+
+ X509Certificate tcert = manager.importCACertPackage(transport);
+
+ byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
+
+ KeyGenerator kg1 = token.getKeyGenerator(KeyGenAlgorithm.DES3);
+ SymmetricKey sk = kg1.generate();
+
+ // wrap private key using session
+ KeyWrapper wrapper1 = token.getKeyWrapper(
+ KeyWrapAlgorithm.DES3_CBC_PAD);
+
+ wrapper1.initWrap(sk, new IVParameterSpec(iv));
+
+ byte key_data[] = wrapper1.wrap((
+ org.mozilla.jss.crypto.PrivateKey) pair.getPrivate());
+
+ // wrap session using transport
+ KeyWrapper rsaWrap = token.getKeyWrapper(KeyWrapAlgorithm.RSA);
+
+ rsaWrap.initWrap(tcert.getPublicKey(), null);
+
+ byte session_data[] = rsaWrap.wrap(sk);
+
+ // create CRMF
+ CertTemplate certTemplate = new CertTemplate();
+
+ certTemplate.setVersion(new INTEGER(2));
+
+ if (certnickname != null) {
+ X500Name name = new X500Name(certnickname);
+ ByteArrayInputStream cs = new ByteArrayInputStream(name.getEncoded());
+ Name n = (Name) Name.getTemplate().decode(cs);
+ certTemplate.setSubject(n);
+ }
+
+ certTemplate.setPublicKey(new SubjectPublicKeyInfo(pair.getPublic()));
+
+ // set extension
+ AlgorithmIdentifier algS = new AlgorithmIdentifier(
+ new OBJECT_IDENTIFIER("1.2.840.113549.3.7"),
+ new OCTET_STRING(iv));
+
+ EncryptedValue encValue = new EncryptedValue(null, algS,
+ new BIT_STRING(session_data, 0), null, null,
+ new BIT_STRING(key_data, 0));
+
+ EncryptedKey key = new EncryptedKey(encValue);
+ PKIArchiveOptions opt = new PKIArchiveOptions(key);
+
+ SEQUENCE seq = new SEQUENCE();
+
+ seq.addElement(
+ new AVA(new OBJECT_IDENTIFIER("1.3.6.1.5.5.7.5.1.4"), opt));
+
+ CertRequest certReq = new CertRequest(new INTEGER(1), certTemplate,
+ seq);
+
+ // Adding proof of possesion data
+ byte popdata[] = { 0x0, 0x3, 0x0 };
+ ProofOfPossession pop = ProofOfPossession.createKeyEncipherment(
+ POPOPrivKey.createThisMessage(new BIT_STRING(popdata, 3)));
+
+ CertReqMsg crmfMsg = new CertReqMsg(certReq, pop, null);
+
+ SEQUENCE s1 = new SEQUENCE();
+
+ // 1st : Encryption key
+ s1.addElement(crmfMsg);
+
+ // 2nd : Signing Key
+
+ if (dualkey) {
+ System.out.println("dualkey = true");
+ SEQUENCE seq1 = new SEQUENCE();
+ CertRequest certReqSigning = new CertRequest(new INTEGER(1),
+ certTemplate, seq1);
+ CertReqMsg signingMsg = new CertReqMsg(certReqSigning, pop, null);
+
+ s1.addElement(signingMsg);
+ }
+
+ byte encoded[] = ASN1Util.encode(s1);
+
+ // BASE64Encoder encoder = new BASE64Encoder();
+
+ // CRMF_REQUEST = encoder.encodeBuffer(encoded);
+ CRMF_REQUEST = Utils.base64encode(encoded);
+
+ System.out.println("Generated crmf request: ...... ");
+ System.out.println("");
+
+ System.out.println(CRMF_REQUEST);
+ System.out.println("");
+ System.out.println("End crmf Request:");
+ } catch (Exception e) {
+ System.out.println("Exception: " + e.getMessage());
+ }
+
+ return CRMF_REQUEST;
+ }
+
+} // end of class
+
diff --git a/base/silent/src/com/netscape/pkisilent/common/Con2Agent.java b/base/silent/src/com/netscape/pkisilent/common/Con2Agent.java
new file mode 100644
index 000000000..61305305e
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/common/Con2Agent.java
@@ -0,0 +1,318 @@
+package com.netscape.pkisilent.common;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.Vector;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.AlreadyInitializedException;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.pkcs11.PK11Token;
+import org.mozilla.jss.ssl.SSLCertificateApprovalCallback;
+import org.mozilla.jss.ssl.SSLClientCertificateSelectionCallback;
+import org.mozilla.jss.ssl.SSLSocket;
+import org.mozilla.jss.util.Password;
+
+/**
+ * CMS Test framework .
+ * Submits a requests to agent port with sslclient authentication.
+ */
+
+public class Con2Agent implements SSLClientCertificateSelectionCallback,
+ SSLCertificateApprovalCallback {
+
+ private int i, port;
+ private String host, certdir, certnickname, tokenpwd, certname, query;
+ private String ACTIONURL;
+
+ private BufferedReader stdin = null;
+ private StringBuffer stdout = new StringBuffer();
+
+ public Con2Agent() {
+ }
+
+ /**
+ * Constructor. Takes hostname , portnumber , certificate nickname, token password ,client certdb directory
+ *
+ * @param hostname
+ * @param portnumber
+ * @param agent cert nickname
+ * @param token password
+ * @param certdb directory
+ */
+
+ public Con2Agent(String hs, int p, String cname, String tpwd, String cdir) {
+ host = hs;
+ port = p;
+ certnickname = cname;
+ tokenpwd = tpwd;
+ certdir = cdir;
+ }
+
+ public boolean approve(X509Certificate x509, SSLCertificateApprovalCallback.ValidityStatus status) {
+ return true;
+ }
+
+ public String select(@SuppressWarnings("rawtypes") Vector nicknames) {
+
+ System.out.println("nicknames size = " + nicknames.size());
+ int i = nicknames.size();
+
+ if (i > 0) {
+ return (String) nicknames.elementAt(0);
+ } else {
+ return null;
+ }
+
+ }
+
+ // Get and Set methods
+
+ /*
+ * Get the page returned by the server
+ */
+
+ public StringBuffer getPage() {
+ return stdout;
+ }
+
+ /*
+ * Set the query string to be submitted to the server
+ */
+
+ public void setQueryString(String qu) {
+ query = qu;
+ }
+
+ /*
+ *Set token password
+ */
+
+ public void setTokenPassword(String pwd) {
+ tokenpwd = pwd;
+ }
+
+ /*
+ * Set Client cert database
+ */
+
+ public void setCertDBDir(String cdir) {
+ certdir = cdir;
+ }
+
+ /*
+ * Set host name
+ */
+
+ public void setHost(String hs) {
+ host = hs;
+ }
+
+ /*
+ * set Agent port number
+ */
+
+ public void setPort(int p) {
+ port = p;
+ }
+
+ /*
+ * Set Agent cert nickname
+ */
+
+ public void setCertNickName(String cname) {
+ certnickname = cname;
+ }
+
+ /*
+ * Set action URL
+ */
+
+ public void setActionURL(String url) {
+ ACTIONURL = url;
+ }
+
+ // Submit requests
+
+ public boolean Send() {
+ try {
+
+ if (!loginCertDB()) {
+ return false;
+ }
+
+ SSLSocket socket = new SSLSocket(host, port, null, 0, this, null);
+
+ System.out.println("Con2Agent.java: host = " + host);
+ System.out.println("Con2Agent.java: port = " + port);
+ System.out.println("Con2Agent.java: certnickname = " + certnickname);
+
+ socket.setClientCertNickname(certnickname);
+ System.out.println("Connected to the socket");
+
+ OutputStream rawos = socket.getOutputStream();
+ BufferedOutputStream os = new BufferedOutputStream(rawos);
+ PrintStream ps = new PrintStream(os);
+
+ System.out.println(ACTIONURL);
+ System.out.println("Query :" + query);
+ ps.println("POST " + ACTIONURL + " HTTP/1.0");
+ ps.println("Connection: Keep-Alive");
+ ps.println("Content-type: application/x-www-form-urlencoded");
+ ps.println("Content-length: " + query.length());
+ ps.println("");
+ ps.println(query);
+ ps.println("\r");
+ ps.flush();
+ os.flush();
+ BufferedReader stdin1 = new BufferedReader(
+ new InputStreamReader(socket.getInputStream()));
+ String line;
+
+ while ((line = stdin1.readLine()) != null) {
+ stdout.append(line + "\n");
+ System.out.println(line);
+ }
+
+ // Send Connection: close to let the server close the connection.
+ // Else the socket on the server side continues to remain in TIME_WAIT state
+
+ ps.println("Connection: close");
+ ps.flush();
+ os.flush();
+ os.close();
+ rawos.close();
+ ps.close();
+ stdin1.close();
+ socket.close();
+
+ if (socket.isClosed()) {
+ System.out.println("Con2Agent.java : Socket is Closed");
+ } else {
+ System.out.println("Con2Agent.java : Socket not Closed");
+ }
+
+ } catch (Exception e) {
+ System.out.println("some exception: in Send routine" + e);
+ return false;
+ }
+
+ return true;
+
+ }
+
+ private boolean loginCertDB() {
+ CryptoManager manager;
+ Password pass1 = null;
+
+ try {
+ System.out.println("Step 1: Initializing CryptoManager");
+ CryptoManager.initialize(certdir);
+
+ System.out.println("Step 2: Login to Cert Database");
+ manager = CryptoManager.getInstance();
+ CryptoToken token = (PK11Token) manager.getInternalKeyStorageToken();
+
+ if (token.isLoggedIn()) {
+ System.out.println("Con2Agent: Logged in incorrect");
+ }
+
+ System.out.println("tokenpwd:" + tokenpwd);
+ char[] passchar1 = new char[tokenpwd.length()];
+
+ tokenpwd.getChars(0, tokenpwd.length(), passchar1, 0);
+
+ pass1 = new Password((char[]) passchar1.clone());
+ token.login(pass1);
+
+ X509Certificate cert2 = manager.findCertByNickname(certnickname);
+
+ certname = cert2.getNickname();
+ return true;
+
+ } catch (AlreadyInitializedException e) {
+ System.out.println("Crypto manager already initialized");
+ return true;
+ } catch (NumberFormatException e) {
+ System.err.println("Invalid key size: " + e);
+ return false;
+ } catch (java.security.InvalidParameterException e) {
+ System.err.println("Invalid key size: " + e);
+ return false;
+
+ } catch (Exception e) {
+ System.err.println("some exception:" + e);
+ e.printStackTrace();
+ return false;
+ }
+
+ }
+
+ public boolean Send_withGET() {
+
+ try {
+
+ if (!loginCertDB()) {
+ return false;
+ }
+
+ SSLSocket socket = new SSLSocket(host, port, null, 0, this, null);
+
+ socket.setClientCertNickname(certnickname);
+ System.out.println("Connected to the socket");
+
+ OutputStream rawos = socket.getOutputStream();
+ BufferedOutputStream os = new BufferedOutputStream(rawos);
+ PrintStream ps = new PrintStream(os);
+
+ System.out.println("Query in con2agent :" + query);
+ System.out.println("ACTIONURL in con2agent : " + ACTIONURL);
+
+ ps.println("GET " + ACTIONURL + query + " HTTP/1.0");
+ ps.println("");
+ ps.println("\r");
+ ps.flush();
+ os.flush();
+ BufferedReader stdin2 = new BufferedReader(
+ new InputStreamReader(socket.getInputStream()));
+ String line;
+
+ while ((line = stdin2.readLine()) != null) {
+ stdout.append(line + "\n");
+ }
+ stdin2.close();
+
+ socket.close();
+
+ } catch (Exception e) {
+ System.err.println("some exception: in Send routine" + e);
+ return false;
+ }
+
+ return true;
+
+ }
+
+} // end of class
diff --git a/base/silent/src/com/netscape/pkisilent/common/DirEnroll.java b/base/silent/src/com/netscape/pkisilent/common/DirEnroll.java
new file mode 100644
index 000000000..019b75825
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/common/DirEnroll.java
@@ -0,0 +1,470 @@
+package com.netscape.pkisilent.common;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import org.mozilla.jss.ssl.SSLSocket;
+
+/**
+ * CMS Test framework - Legacyenrollment forms for Directory based enrollmnet and Portal based enrollment .
+ * Certificate issuance through Legacy Directory based enrollment and Portal based enrollment form.
+ * <P>
+ */
+
+public class DirEnroll extends TestClient {
+
+ private int i;
+ private String Authenticator = "UserDir";
+ private int port;
+ private long elapsedTime;
+
+ private String importcert = "false";
+ private boolean impStatus = false;
+
+ // Constructors
+
+ /**
+ * Constructor . Takes the parameter for Properties file name
+ * <p>
+ *
+ * @param propfilename name of the parameter file
+ */
+
+ public DirEnroll(String pfile) {
+ propfileName = pfile;
+ }
+
+ /**
+ * Constructor. Takes hostname , EESSLportnumber as parameter
+ * <p>
+ *
+ * @param hostname
+ * @param portnumber
+ */
+
+ public DirEnroll(String h, String p) {
+ host = h;
+ ports = p;
+ }
+
+ /**
+ * Constructor. Takes
+ * hostname,EESSLportnumber,uid,password,certdbdirectorypath,certdbpassword,certificatenickname,keysize,teytype
+ * <p>
+ *
+ * @param hostname
+ * @param portnumber
+ * @param subjectdn
+ * @param admuserid
+ * @param adminpassword
+ */
+
+ public DirEnroll(String hs, String p, String uid, String pw, String certdir, String certtokenpwd, String nickname,
+ String ksz, String kt) {
+
+ host = hs;
+ ports = p;
+ UID = uid;
+ PWD = pw;
+ cdir = certdir;
+ tokenpwd = certtokenpwd;
+ certnickname = nickname;
+ keysize = "1024";
+ keytype = "RSA";
+ }
+
+ // Set and Get functions
+
+ /**
+ * Use this method to set User Info
+ */
+ public void setUIDInfo(String uid, String pw) {
+ UID = uid;
+ PWD = pw;
+ }
+
+ /**
+ * Returns a string "UserDir" / "Portal"
+ */
+
+ public String getAuthenticator() {
+ return Authenticator;
+ }
+
+ /**
+ * Valid values for s - UserDir for Directory based Authntication
+ * Portal for Portal based Authentication
+ */
+ public void setAuthenticator(String s) {
+ Authenticator = s;
+ }
+
+ public boolean enroll_load() throws UnsupportedEncodingException {
+ buildquery();
+ return (Send());
+ }
+
+ private boolean pkcs10() {
+ System.out.println(" In pkcs10 Keysize , key type " + keysize + keytype);
+ cCrypt.setCertDir(cdir);
+ cCrypt.setCertnickname("cn=test");
+ cCrypt.setKeySize(keysize);
+ cCrypt.setKeyType(keytype);
+ cCrypt.setTokenPWD(tokenpwd);
+
+ cCrypt.setDebug(debug);
+ cCrypt.setGenerateRequest(true);
+ if (!cCrypt.generateRequest()) {
+ System.out.println("Request could not be generated ");
+ return false;
+ }
+ pkcs10request = cCrypt.getPkcs10Request();
+
+ try {
+ buildquery();
+ System.out.println(query);
+ setStatusString("Congratulations, your certificate has been issued.");
+ return (Send());
+ } catch (Exception e) {
+ System.err.println("some exception:" + e);
+ }
+
+ return false;
+
+ }
+
+ /**
+ * Enroll for certificate . Before calling this mentod SetAuthenticator and setUIDInfo
+ */
+ public boolean enroll() {
+ return (pkcs10());
+ }
+
+ private boolean readProperties() {
+
+ // Read the properties file and assign values to variables .
+ try {
+ getProperties(propfileName);
+ } catch (Exception e) {
+ System.out.println(
+ "exception reading Properties File " + e.getMessage());
+ return false;
+ }
+
+ System.out.println("Reading");
+ host = props.getProperty("enroll.host");
+ ports = props.getProperty("enroll.port");
+ UID = props.getProperty("enroll.UID");
+ PWD = props.getProperty("enroll.pwd");
+ cdir = props.getProperty("enroll.certdir");
+ tokenpwd = props.getProperty("enroll.certtokenpwd");
+ certnickname = props.getProperty("enroll.nickname");
+ keysize = props.getProperty("enroll.keysize");
+ keytype = props.getProperty("enroll.keytype");
+ Authenticator = props.getProperty("enroll.authenticator");
+ GN = props.getProperty("enroll.GN");
+ SN = props.getProperty("enroll.SN");
+ CN = props.getProperty("enroll.CN");
+ OU = props.getProperty("enroll.OU");
+ O = props.getProperty("enroll.O");
+ MAIL = props.getProperty("enroll.mail");
+ L = props.getProperty("enroll.l");
+
+ importcert = props.getProperty("enroll.importCert");
+ if (importcert == null) {
+ importcert = "false";
+ }
+ String de = props.getProperty("enroll.debug");
+
+ if (de == null) {
+ debug = false;
+ } else if (de.equals("true")) {
+ debug = true;
+ } else {
+ debug = false;
+ }
+
+ System.out.println("Reading done");
+ // Enroll using a pkscks10 request
+ return true;
+ }
+
+ // Private functions
+
+ private boolean importCert(String certpack) {
+
+ if (importcert.equals("false")) {
+ return true;
+ }
+
+ try {
+ if (certpack == null) {
+ return false;
+ }
+
+ if (debug) {
+ System.out.println(
+ "importing cert" + certpack + "certnick" + certnickname);
+ }
+
+ cCrypt.importCert(certpack, certnickname);
+
+ return true;
+
+ } catch (Exception e) {
+ System.out.println("exception importing cert " + e.getMessage());
+ return false;
+ }
+
+ }
+
+ private void setElapsedTime(long dif) {
+ elapsedTime = dif;
+ }
+
+ private long calculateElapsedTime(GregorianCalendar b, GregorianCalendar e) {
+
+ Date d1 = b.getTime();
+ Date d2 = e.getTime();
+ long l1 = d1.getTime();
+ long l2 = d2.getTime();
+ long difference = l2 - l1;
+
+ return difference;
+
+ }
+
+ private boolean Send() {
+ boolean st = false;
+
+ try {
+ if (debug) {
+ System.out.println("Step 3 : Socket initialize");
+ }
+
+ Integer x = new Integer(ports);
+
+ port = x.intValue();
+ ErrorDetail = null;
+ GregorianCalendar begin = new GregorianCalendar();
+
+ // SSLSocket socket = new SSLSocket(host,port);
+ SSLSocket socket = new SSLSocket(host, port, null, 0, this, null);
+
+ socket.setUseClientMode(true);
+
+ OutputStream rawos = socket.getOutputStream();
+ BufferedOutputStream os = new BufferedOutputStream(rawos);
+ PrintStream ps = new PrintStream(os);
+
+ ps.println("POST /enrollment HTTP/1.0");
+ ps.println("Connection: Keep-Alive");
+ ps.println("Content-type: application/x-www-form-urlencoded");
+ ps.println("Content-length: " + query.length());
+ ps.println("");
+ ps.println(query);
+ ps.println("\r");
+ ps.flush();
+ os.flush();
+ BufferedReader stdin = new BufferedReader(
+ new InputStreamReader(socket.getInputStream()));
+
+ if (debug) {
+ System.out.println("Step 4: Received the page");
+ }
+ st = false;
+ String line;
+
+ while ((line = stdin.readLine()) != null) {
+ if (debug) {
+ System.out.println(line);
+ }
+ if (line.indexOf(STATUS) != -1) {
+ st = true;
+ }
+ if (getError(line)) {
+ st = true;
+ }
+
+ if (line.indexOf("record.base64Cert=") > -1) {
+ String baseCert = line;
+
+ System.out.println("BaseCert : " + baseCert);
+ if (importcert.equals("true")) {
+ String strbase = "record.base64Cert=";
+
+ int n = strbase.length() + 1;
+
+ baseCert = baseCert.substring(n);
+ String tmp = baseCert.substring(0, baseCert.length() - 2);
+
+ if (importCert(tmp)) {
+ impStatus = true;
+ }
+ } else {
+ impStatus = true;
+ }
+ }
+
+ }
+ stdin.close();
+ socket.close();
+ os.close();
+ rawos.close();
+ ps.close();
+ os = null;
+ rawos = null;
+ stdin = null;
+ ps = null;
+ line = null;
+
+ GregorianCalendar end = new GregorianCalendar();
+ long diff = calculateElapsedTime(begin, end);
+
+ setElapsedTime(diff);
+
+ } catch (Exception e) {
+ System.err.println("some exception: in Send routine" + e);
+ return false;
+ }
+
+ return st;
+
+ }
+
+ private void buildquery() throws UnsupportedEncodingException {
+
+ StringBuffer queryStrBuf = new StringBuffer();
+
+ queryStrBuf.append("certType=client");
+ queryStrBuf.append("&importCert=off");
+ queryStrBuf.append("&non_repudiation=true");
+ queryStrBuf.append("&submit=Submit");
+ queryStrBuf.append("&key_encipherment=true");
+ queryStrBuf.append("&digital_signature=true");
+ queryStrBuf.append("&ssl_client=true");
+
+ System.out.println("Authenticator : " + Authenticator);
+
+ if (Authenticator.equals("UserDir")) {
+ queryStrBuf.append("&authenticator=UserDirEnrollment");
+ queryStrBuf.append("&requestFormat=keygen");
+ queryStrBuf.append("&uid=");
+ queryStrBuf.append(URLEncoder.encode(UID, "UTF-8"));
+ queryStrBuf.append("&pwd=");
+ queryStrBuf.append(URLEncoder.encode(PWD, "UTF-8"));
+ queryStrBuf.append("&email=true");
+ queryStrBuf.append("&cryptprovider=1");
+
+ }
+
+ if (Authenticator.equals("Portal")) {
+ queryStrBuf.append("&authenticator=PortalEnrollment");
+ queryStrBuf.append("&requestFormat=keygen");
+ queryStrBuf.append("&uid=");
+ queryStrBuf.append(URLEncoder.encode(UID, "UTF-8"));
+ queryStrBuf.append("&userPassword=");
+ queryStrBuf.append(URLEncoder.encode(PWD, "UTF-8"));
+ GN = "test";
+ SN = "test";
+ CN = "test";
+ MAIL = "test@netscape.com";
+ OU = "aol";
+ O = "aol";
+ L = "MV";
+ queryStrBuf.append("&givenname=");
+ queryStrBuf.append(URLEncoder.encode(GN, "UTF-8"));
+
+ queryStrBuf.append("&sn=");
+ queryStrBuf.append(URLEncoder.encode(SN, "UTF-8"));
+ queryStrBuf.append("&cn=");
+ queryStrBuf.append(URLEncoder.encode(CN, "UTF-8"));
+
+ queryStrBuf.append("&mail=");
+ queryStrBuf.append(URLEncoder.encode(MAIL, "UTF-8"));
+ queryStrBuf.append("&ou=");
+ queryStrBuf.append(URLEncoder.encode(OU, "UTF-8"));
+ queryStrBuf.append("&o=");
+ queryStrBuf.append(URLEncoder.encode(O, "UTF-8"));
+ queryStrBuf.append("&l=");
+ queryStrBuf.append(URLEncoder.encode(L, "UTF-8"));
+
+ queryStrBuf.append("&email=true");
+
+ }
+
+ if (Authenticator.equals("NIS")) {
+ queryStrBuf.append("&authenticator=NISAuth");
+ queryStrBuf.append("&requestFormat=keygen");
+ queryStrBuf.append("&uid=");
+ queryStrBuf.append(URLEncoder.encode(UID, "UTF-8"));
+ queryStrBuf.append("&pwd=");
+ queryStrBuf.append(URLEncoder.encode(PWD, "UTF-8"));
+ queryStrBuf.append("&email=true");
+
+ }
+
+ queryStrBuf.append("&pkcs10Request=");
+ queryStrBuf.append(URLEncoder.encode(pkcs10request, "UTF-8"));
+ query = queryStrBuf.toString();
+
+ System.out.println(query);
+
+ }
+
+ public static void main(String args[]) {
+ // Exit Status - (0) for error/Fail
+ // - requestId Pass
+ boolean st;
+
+ System.out.println(args.length);
+ if (args.length < 1) {
+ System.out.println("Usage : propertiesfile");
+ System.exit(0);
+ }
+
+ DirEnroll t = new DirEnroll(args[0]);
+
+ t.readProperties();
+ st = t.enroll();
+ if (st) {
+ System.out.println(
+ t.getAuthenticator() + " based enrollment successfull. ");
+ System.exit(1);
+ } else {
+
+ System.out.println(
+ t.getAuthenticator()
+ + " based enrollment was not successful."
+ + "Error: " + t.getErrorDetail());
+ System.exit(0);
+ }
+ }// end of function main
+
+} // end of class
+
diff --git a/base/silent/src/com/netscape/pkisilent/common/ParseXML.java b/base/silent/src/com/netscape/pkisilent/common/ParseXML.java
new file mode 100644
index 000000000..de1b38172
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/common/ParseXML.java
@@ -0,0 +1,170 @@
+package com.netscape.pkisilent.common;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.xml.serialize.OutputFormat;
+import org.apache.xml.serialize.XMLSerializer;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+public class ParseXML {
+ Document dom = null;
+
+ public ParseXML() {// nothing
+ }
+
+ public void parse(java.io.InputStream is) {
+ try {
+ // get the factory
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+
+ // Using factory get an instance of document builder
+ DocumentBuilder db = dbf.newDocumentBuilder();
+
+ // parse using builder to get DOM representation of the XML file
+ dom = db.parse(is);
+ } catch (Exception se) {
+ System.out.println("ERROR: unable to parse xml");
+ se.printStackTrace();
+
+ try {
+ BufferedReader br = new BufferedReader(new InputStreamReader(is));
+ StringBuilder sb = new StringBuilder();
+ String line = null;
+
+ while ((line = br.readLine()) != null) {
+ sb.append(line + "\n");
+ }
+
+ br.close();
+ System.out.println("ERROR XML = " + sb.toString());
+ } catch (Exception se1) {
+ System.out.println("ERROR: unable to print xml");
+ se1.printStackTrace();
+ }
+ }
+ }
+
+ public String getvalue(String tag) {
+ String temp = null;
+
+ try {
+
+ // get the root elememt
+ Element docEle = dom.getDocumentElement();
+
+ // get a nodelist of <employee> elements
+ NodeList nl = docEle.getElementsByTagName(tag);
+
+ if (nl != null && nl.getLength() > 0) {
+ Element el = (Element) nl.item(0);
+
+ if (el != null) {
+ temp = el.getFirstChild().getNodeValue();
+ }
+ }
+ } catch (Exception e) {
+ System.out.println("ERROR: Tag=" + tag + "has no values");
+ return null;
+ }
+
+ return temp;
+ }
+
+ public void prettyprintxml() {
+ try {
+ // Serialize the document
+ OutputFormat format = new OutputFormat(dom);
+
+ format.setLineWidth(65);
+ format.setIndenting(true);
+ format.setIndent(2);
+ XMLSerializer serializer = new XMLSerializer(System.out, format);
+
+ serializer.serialize(dom);
+ } catch (Exception e) {
+ }
+ }
+
+ private String getTextValue(Element ele, String tagName) {
+ String textVal = null;
+ NodeList nl = ele.getElementsByTagName(tagName);
+
+ if (nl != null && nl.getLength() > 0) {
+ Element el = (Element) nl.item(0);
+
+ textVal = el.getFirstChild().getNodeValue();
+ }
+
+ return textVal;
+ }
+
+ // returns an arraylist of values for the corresponding tag
+
+ public ArrayList<String> constructValueList(String first, String second) {
+ ArrayList<String> al = new ArrayList<String>();
+
+ try {
+ // get the root elememt
+ Element docEle = dom.getDocumentElement();
+
+ // get a nodelist of <employee> elements
+ NodeList nl = docEle.getElementsByTagName(first);
+
+ if (nl != null && nl.getLength() > 0) {
+ for (int i = 0; i < nl.getLength(); i++) {
+ Element el = (Element) nl.item(i);
+ String value = getTextValue(el, second);
+
+ System.out.println("tag=" + second + " value=" + value);
+ if (value != null) {
+ al.add(value);
+ }
+ }
+ }
+ } catch (Exception e) {
+ System.out.println("ERROR: Tag=" + first + " has no values");
+ }
+
+ return al;
+ }
+
+ public static void main(String args[]) {
+ try {
+
+ ParseXML px = new ParseXML();
+ FileInputStream fiscfg = new FileInputStream("/tmp/test.xml");
+
+ px.parse(fiscfg);
+ px.prettyprintxml();
+
+ } catch (Exception e) {
+ }
+ }
+
+}; // end class
diff --git a/base/silent/src/com/netscape/pkisilent/common/PostQuery.java b/base/silent/src/com/netscape/pkisilent/common/PostQuery.java
new file mode 100644
index 000000000..31fb07b3e
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/common/PostQuery.java
@@ -0,0 +1,141 @@
+package com.netscape.pkisilent.common;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * CMS Test framework .
+ * This class submits request to admin server after authenticating with UID and Password. You can get back the response
+ * by calling the method. getPage().
+ */
+
+public class PostQuery {
+
+ private boolean st;
+ private String NmcStatus = "NMC_STATUS: 0";
+ private String postQuery = null;
+ private String adminID, adminPWD, URLString;
+
+ private StringBuffer stdout = new StringBuffer();
+
+ /**
+ * Constructor . Takes the parameters urlstring("http://hostname:<portnumber> , Id for authenticating to the server,
+ * password for authentication to the server and query which needs to be submitted to the server
+ */
+
+ public PostQuery(String urlstr, String authid, String authpwd, String querystring) {
+
+ URLString = urlstr;
+ adminID = authid;
+ adminPWD = authpwd;
+ postQuery = querystring;
+
+ }
+
+ public void setNMCStatus(String m) {
+ NmcStatus = m;
+ }
+
+ public void setPostQueryString(String querystring) {
+ postQuery = querystring;
+ }
+
+ public void setAuth(String ID, String Pwd) {
+ adminID = ID;
+ adminPWD = Pwd;
+ }
+
+ public StringBuffer getPage() {
+ return stdout;
+ }
+
+ public boolean Send() {
+ // / This functions connects to the URL and POST HTTP Request .
+ // It compares with NMC_STATUS and return the status.
+ System.out.println(URLString);
+ st = false;
+
+ try {
+
+ URL myUrl = new URL(URLString);
+ String userPassword = adminID + ":" + adminPWD;
+
+ System.out.println("adminid=" + adminID);
+ System.out.println("adminpwd=" + adminPWD);
+ // String encoding = new sun.misc.BASE64Encoder().encode(
+ // userPassword.getBytes());
+ String encoding = Utils.base64encode(
+ userPassword.getBytes());
+ HttpURLConnection URLCon = (HttpURLConnection) myUrl.openConnection();
+
+ URLCon.setRequestProperty("Authorization", "Basic " + encoding);
+ URLCon.setDoOutput(true);
+ URLCon.setDoInput(true);
+ URLCon.setUseCaches(false);
+ URLCon.setRequestProperty("Content-type",
+ "application/x-www-form-urlencoded");
+ // URLCon.setRequestMethod("POST");
+ System.out.println("After post");
+
+ DataOutputStream os = new DataOutputStream(URLCon.getOutputStream());
+
+ System.out.println("Query: " + postQuery);
+
+ os.writeBytes(postQuery);
+ os.flush();
+ os.close();
+
+ InputStream Content = (InputStream) URLCon.getInputStream();
+
+ System.out.println("Configuring Cert Instance : Return Response");
+ BufferedReader in = new BufferedReader(
+ new InputStreamReader(Content));
+ String line;
+
+ while ((line = in.readLine()) != null) {
+ System.out.println(line);
+ stdout.append(line + "\n");
+ st = line.startsWith(NmcStatus);
+ if (st) {
+ break;
+ }
+ }
+ URLCon.disconnect();
+ } // try
+ catch (MalformedURLException e) {
+ System.out.println(URLString + " is not a valid URL.");
+
+ } catch (IOException e) {
+ System.out.println("exception : " + e.getMessage());
+ }
+ System.out.println(st);
+ return st;
+ }
+
+}
diff --git a/base/silent/src/com/netscape/pkisilent/common/Request.java b/base/silent/src/com/netscape/pkisilent/common/Request.java
new file mode 100644
index 000000000..3dffc929c
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/common/Request.java
@@ -0,0 +1,1138 @@
+package com.netscape.pkisilent.common;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Vector;
+
+/**
+ * CMS Test framework .
+ * Submits List,Approve,Reject,cancel requests to agent port
+ */
+
+public class Request extends TestClient {
+
+ private String validityperiod;
+ private String approveseqnum, type, reqType, reqState, agenttype;
+ private int i;
+
+ // Program variables
+ private String ACTION_PROCESS_CERT_REQUEST = null;
+ private String ACTION_LISTREQUEST = "/queryReq";
+ private int reqtype = 1;
+ private int seqNumFrom = 1;
+ private int maxCount = 50;
+ private int validperiod = 180;
+ private String cadualcert_name = null;
+
+ private String approveseqnumFrom, approveseqnumTo;
+ // Request variables
+ private Vector<String> seqNum = new Vector<String>();
+ private String AUTH_ID = null;
+
+ // Cert Detail variables
+
+ private String csrRequestorName, csrRequestorPhone, csrRequestorEmail, subject, subjectdn, reqStatus, certType;
+ private String requestType, requestID, sslclient, clientcert, servercert, emailcert, objectsigningcert, sslcacert,
+ objectsigningcacert, emailcacert, sigAlgo, totalRecord, validitylength, trustedManager;
+
+ private int totalNumApproved = 0;
+
+ // Constructors
+
+ /**
+ * Constructor . Takes the parameter for Properties file name
+ *
+ * @param propfileName name of the parameter file.
+ */
+
+ public Request(String pfile) {
+ propfileName = pfile;
+ }
+
+ /**
+ * Constructor . Takes the parameter host , port and "angent type - ca/ra"
+ *
+ * @param hostname.
+ * @param port
+ * @param agenttype Whether ca or ra agent
+ */
+
+ public Request(String h, String p, String at) {
+ host = h;
+ ports = p;
+ agenttype = at;
+ }
+
+ /**
+ * Constructor . Takes the following parmaters
+ *
+ * @param hostName .
+ * @param port
+ * @param adminuid
+ * @param adminpwd
+ * @param agentcertnickname
+ * @param certdb
+ * @param tokenpwd
+ * @param approveSequncenumber
+ * @param ApproveSequenceNumberFrom
+ * @param ApproveSequnceNumberTo
+ * @param type
+ * @param reqtype enrollment/revoked
+ * @param requestState complete/pending
+ * @param agentType ra/ca
+ * @param trustedManager true/false
+ */
+
+ public Request(String h, String p, String aid, String apwd, String cname, String cd, String ctpwd, String snum,
+ String sfrom, String sto, String ty, String rty, String rstate, String aty, String tm) {
+ host = h;
+ ports = p;
+ adminid = aid;
+ adminpwd = apwd;
+ certnickname = cname;
+ cdir = cd;
+ tokenpwd = ctpwd;
+ approveseqnum = snum;
+ approveseqnumFrom = sfrom;
+ if (approveseqnumFrom == null) {
+ approveseqnumFrom = "1";
+ }
+
+ approveseqnumTo = sto;
+ if (approveseqnumTo == null) {
+ approveseqnumTo = "100";
+ }
+
+ type = ty;
+ reqType = rty;
+ reqState = rstate;
+ agenttype = aty;
+ if (agenttype == null) {
+ agenttype = "ca";
+ }
+
+ trustedManager = tm;
+ if (trustedManager.equals("true")) {
+ trustedManager = "true";
+ } else {
+ trustedManager = "false";
+ }
+ debug = false;
+
+ }
+
+ /**
+ * Set Agent Cert nick name
+ */
+ public void setAgentCertName(String s) {
+ certnickname = s;
+ }
+
+ /**
+ * List all pending enrollment request. Takes parameters fromRequestNumber,toRequestNumber
+ *
+ * @param fromrequest number
+ * @param endrequestnumber.
+ * @throws UnsupportedEncodingException
+ */
+
+ public Vector<String> ListPendingRequests(String fromRequestNumber, String toRequestNumber) throws UnsupportedEncodingException {
+ reqState = "showWaiting";
+ reqType = "enrollment";
+ approveseqnumFrom = fromRequestNumber;
+ approveseqnumTo = toRequestNumber;
+ listRequest(approveseqnumFrom, approveseqnumTo);
+ return seqNum;
+ }
+
+ /**
+ * List all pending request. Takes parameters fromRequestNumber,toRequestNumber
+ *
+ * @param fromrequest number
+ * @param endrequestnumber.
+ * @throws UnsupportedEncodingException
+ */
+
+ public Vector<String> ListAllRequests(String fromRequestNumber, String toRequestNumber) throws UnsupportedEncodingException {
+ reqState = "showAll";
+ reqType = "enrollment";
+ approveseqnumFrom = fromRequestNumber;
+ approveseqnumTo = toRequestNumber;
+ listRequest(approveseqnumFrom, approveseqnumTo);
+ return seqNum;
+ }
+
+ /**
+ * Approve pending enrollment request. Takes parameters RequestNumber
+ *
+ * @param request number
+ * @throws UnsupportedEncodingException
+ */
+
+ public int ApproveRequests(String requestNumber) throws UnsupportedEncodingException {
+ reqState = "showWaiting";
+ reqType = "enrollment";
+ approveseqnum = requestNumber;
+ approveseqnumFrom = requestNumber;
+ approveseqnumTo = requestNumber;
+ if (approveRequest()) {
+ System.out.println("Approve Request :" + totalNumApproved);
+ return totalNumApproved;
+ } else {
+ return -1;
+ }
+
+ }
+
+ /**
+ * Approve profile based pending enrollment request. Takes parameters RequestNumber
+ *
+ * @param request number
+ * @throws UnsupportedEncodingException
+ */
+
+ public int ApproveProfileRequests(String RequestNumber) throws UnsupportedEncodingException {
+
+ approveseqnum = RequestNumber;
+ approveseqnumFrom = RequestNumber;
+ approveseqnumTo = RequestNumber;
+
+ reqtype = 4;
+ buildquery();
+ if (!Send()) {
+ System.out.println("Error: Approving request " + approveseqnum);
+ return 0;
+ }
+ return 1;
+
+ }
+
+ public boolean Approve_cadualcert_Profile_Request(String RequestNumber, String name) throws UnsupportedEncodingException {
+
+ approveseqnum = RequestNumber;
+ approveseqnumFrom = RequestNumber;
+ approveseqnumTo = RequestNumber;
+
+ cadualcert_name = name;
+
+ // reqtype = 7 means cadualcert profile request
+ // this is just a convention that we follow within this file to distinguish
+ // bet'n the different requests
+
+ reqtype = 7;
+
+ buildquery();
+
+ if (!Send()) {
+ System.out.println("Error: Approving request " + approveseqnum);
+ return false;
+ }
+
+ return true;
+
+ }
+
+ /**
+ * Reject profile based pending enrollment request. Takes parameters RequestNumber
+ *
+ * @param request number
+ * @throws UnsupportedEncodingException
+ */
+
+ public int RejectProfileRequests(String RequestNumber) throws UnsupportedEncodingException {
+
+ approveseqnum = RequestNumber;
+ approveseqnumFrom = RequestNumber;
+ approveseqnumTo = RequestNumber;
+
+ reqtype = 5;
+ buildquery();
+ if (!Send()) {
+ System.out.println("Error: Rejecting request " + approveseqnum);
+ return 0;
+ }
+ return 1;
+
+ }
+
+ /**
+ * Cancel profile based pending enrollment request. Takes parameters RequestNumber
+ *
+ * @param request number
+ * @throws UnsupportedEncodingException
+ */
+
+ public int CancelProfileRequests(String RequestNumber) throws UnsupportedEncodingException {
+
+ approveseqnum = RequestNumber;
+ approveseqnumFrom = RequestNumber;
+ approveseqnumTo = RequestNumber;
+
+ reqtype = 6;
+ buildquery();
+ if (!Send()) {
+ System.out.println("Error: canceling request " + approveseqnum);
+ return 0;
+ }
+ return 1;
+
+ }
+
+ // private methods
+ private boolean RetrieveProfileCancel(StringBuffer s) {
+ String res = s.toString();
+ int ret = 0;
+
+ ret = res.indexOf("requestStatus=");
+ String status = res.substring(ret + "requestStatus=".length() + 1,
+ res.indexOf(";", ret) - 1);
+
+ if (!status.equals("canceled")) {
+ ErrorDetail = res.substring(ret + "errorReason=".length() + 1,
+ res.indexOf(";", ret) - 1);
+ return false;
+ }
+
+ return true;
+ }
+
+ private boolean RetrieveProfileReject(StringBuffer s) {
+ String res = s.toString();
+ int ret = 0;
+
+ ret = res.indexOf("requestStatus=");
+ String status = res.substring(ret + "requestStatus=".length() + 1,
+ res.indexOf(";", ret) - 1);
+
+ if (!status.equals("rejected")) {
+ ErrorDetail = res.substring(ret + "errorReason=".length() + 1,
+ res.indexOf(";", ret) - 1);
+ return false;
+ }
+
+ return true;
+ }
+
+ private boolean RetrieveProfileApproval(StringBuffer s) {
+ String res = s.toString();
+ int ret = 0;
+
+ ret = res.indexOf("requestStatus=");
+ String status = res.substring(ret + "requestStatus=".length() + 1,
+ res.indexOf(";", ret) - 1);
+
+ if (!status.equals("complete")) {
+ ErrorDetail = res.substring(ret + "errorReason=".length() + 1,
+ res.indexOf(";", ret) - 1);
+ return false;
+ }
+
+ return true;
+
+ }
+
+ private boolean RetrieveReq(StringBuffer s) {
+ String AUTHID = "header.authorityid = ";
+ String seqnum = "record.seqNum";
+
+ String res = s.toString();
+ int ret = 0;
+
+ if ((ret = res.indexOf(AUTHID)) > -1) {
+ AUTH_ID = res.substring(ret + AUTHID.length() + 1,
+ res.indexOf(";", ret) - 1);
+ while (ret > 0) {
+ if ((ret = res.indexOf(seqnum, ret)) > -1) {
+ int bi = ret + seqnum.length() + 2;
+ int be = res.indexOf(";", ret) - 1;
+
+ seqNum.addElement(res.substring(bi, be));
+ ret++;
+ }
+
+ }
+
+ }
+
+ ret = res.indexOf("header.totalRecordCount =");
+ totalRecord = res.substring(ret + "header.totalRecordCount = ".length(),
+ res.indexOf(";", ret));
+
+ return true;
+
+ }
+
+ private boolean RetrieveCertDetails(StringBuffer s) {
+
+ // System.out.println("Debug : Retrieving cert details ");
+ String res = s.toString();
+
+ if (debug) {
+ System.out.println(res);
+ }
+ int ret = 0;
+
+ boolean st = false;
+
+ for (int t = 0; t < 25; t++) {
+ String cmp = "header.SERVER_ATTRS[" + t + "].name=";
+
+ ret = res.indexOf(cmp);
+ if ((res.substring(ret + cmp.length() + 1, res.indexOf(";", ret) - 1)).equals(
+ "requestId")) {
+ ret = res.indexOf("header.SERVER_ATTRS[" + t + "].value=");
+ requestID = res.substring(
+ ret + "header.SERVER_ATTRS[t].value=".length() + 1,
+ res.indexOf(";", ret) - 1);
+ }
+ if ((res.substring(ret + cmp.length() + 1, res.indexOf(";", ret) - 1)).equals(
+ "requestStatus")) {
+ ret = res.indexOf("header.SERVER_ATTRS[" + t + "].value=");
+ reqStatus = res.substring(
+ ret + "header.SERVER_ATTRS[t].value=".length() + 1,
+ res.indexOf(";", ret) - 1);
+ }
+
+ if ((res.substring(ret + cmp.length() + 1, res.indexOf(";", ret) - 1)).equals(
+ "requestType")) {
+ ret = res.indexOf("header.SERVER_ATTRS[" + t + "].value=");
+ requestType = res.substring(
+ ret + "header.SERVER_ATTRS[t].value=".length() + 1,
+ res.indexOf(";", ret) - 1);
+ }
+
+ } // end of for loop
+
+ // System.out.println("Debug : Retrieving cert details Serverattributes ");
+
+ if (requestID.equals(approveseqnum)) {
+ st = true;
+ }
+
+ if (!st) {
+ System.out.println("Error in retrieving the record " + approveseqnum);
+ return false;
+ }
+
+ // System.out.println("Debug : Retrieving cert details HTTP parmas ");
+
+ for (int t = 0; t < 25; t++) {
+ String cmp = "header.HTTP_PARAMS[" + t + "].name=";
+
+ ret = res.indexOf(cmp);
+ if ((res.substring(ret + cmp.length() + 1, res.indexOf(";", ret) - 1)).equals(
+ "csrRequestorEmail")) {
+ ret = res.indexOf("header.HTTP_PARAMS[" + t + "].value=");
+ csrRequestorEmail = res.substring(
+ ret + "header.HTTP_PARAMS[t].value=".length() + 1,
+ res.indexOf(";", ret) - 1);
+ }
+ if ((res.substring(ret + cmp.length() + 1, res.indexOf(";", ret) - 1)).equals(
+ "csrRequestorPhone")) {
+ ret = res.indexOf("header.HTTP_PARAMS[" + t + "].value=");
+ csrRequestorPhone = res.substring(
+ ret + "header.HTTP_PARAMS[t].value=".length() + 1,
+ res.indexOf(";", ret) - 1);
+ }
+ if ((res.substring(ret + cmp.length() + 1, res.indexOf(";", ret) - 1)).equals(
+ "csrRequestorName")) {
+ ret = res.indexOf("header.HTTP_PARAMS[" + t + "].value=");
+ csrRequestorName = res.substring(
+ ret + "header.HTTP_PARAMS[t].value=".length() + 1,
+ res.indexOf(";", ret) - 1);
+ }
+
+ if ((res.substring(ret + cmp.length() + 1, res.indexOf(";", ret) - 1)).equals(
+ "subject")) {
+ ret = res.indexOf("header.HTTP_PARAMS[" + t + "].value=");
+ subjectdn = res.substring(
+ ret + "header.HTTP_PARAMS[t].value=".length() + 1,
+ res.indexOf(";", ret) - 1);
+ }
+
+ } // end of for loop
+
+ // System.out.println("Debug : Retrieving cert details");
+
+ ret = res.indexOf("header.subject =");
+ if (ret > 0) {
+ subject = res.substring(ret + "header.subject = ".length() + 1,
+ res.indexOf(";", ret) - 1);
+ }
+ // System.out.println("Debug : Retrieving cert details ");
+
+ sslclient =
+ clientcert =
+ servercert =
+ emailcert = objectsigningcert = sslcacert = objectsigningcacert = emailcacert = "false";
+ ret = res.indexOf("header.sslclient =");
+ if (ret > 0) {
+ sslclient = res.substring(ret + "header.sslclient = ".length() + 1,
+ res.indexOf(";", ret) - 1);
+ }
+ // System.out.println("Debug : Retrieving cert details ");
+
+ ret = res.indexOf("header.ext_ssl_client =");
+ if (ret > 0) {
+ clientcert = res.substring(
+ ret + "header.ext_ssl_client = ".length() + 1,
+ res.indexOf(";", ret) - 1);
+ }
+ // System.out.println("Debug : Retrieving cert details ");
+
+ ret = res.indexOf("header.ext_email =");
+ if (ret > 0) {
+ emailcert = res.substring(ret + "header.ext_email = ".length() + 1,
+ res.indexOf(";", ret) - 1);
+ }
+ // System.out.println("Debug : Retrieving cert details ");
+
+ ret = res.indexOf("header.ext_ssl_server =");
+ if (ret > 0) {
+ servercert = res.substring(
+ ret + "header.ext_ssl_server = ".length() + 1,
+ res.indexOf(";", ret) - 1);
+ }
+
+ // System.out.println("Debug : Retrieving cert details ");
+
+ ret = res.indexOf("header.ext_object_signing =");
+ if (ret > 0) {
+ objectsigningcert = res.substring(
+ ret + "header.ext_object_signing = ".length() + 1,
+ res.indexOf(";", ret) - 1);
+ }
+
+ // System.out.println("Debug : Retrieving cert details ");
+
+ ret = res.indexOf("header.ext_ssl_ca =");
+ if (ret > 0) {
+ sslcacert = res.substring(ret + "header.ext_ssl_ca = ".length() + 1,
+ res.indexOf(";", ret) - 1);
+ }
+
+ // System.out.println("Debug : Retrieving cert details ");
+
+ if (ret > 0) {
+ ret = res.indexOf("header.ext_object_signing_ca=");
+ }
+ objectsigningcacert = res.substring(
+ ret + "header.ext_object_signing_ca = ".length() + 1,
+ res.indexOf(";", ret) - 1);
+
+ // System.out.println("Debug : Retrieving cert details ");
+
+ ret = res.indexOf("header.ext_email_ca =");
+ if (ret > 0) {
+ emailcacert = res.substring(
+ ret + "header.ext_email_ca = ".length() + 1,
+ res.indexOf(";", ret) - 1);
+ }
+
+ // System.out.println("Debug : Retrieving cert details ");
+
+ ret = res.indexOf("header.certType =");
+ if (ret > 0) {
+ certType = res.substring(ret + "header.certType = ".length() + 1,
+ res.indexOf(";", ret) - 1);
+ }
+ // System.out.println("Debug : Retrieving cert details ");
+
+ ret = res.indexOf("header.signatureAlgorithmName =");
+ if (ret > 0) {
+ sigAlgo = res.substring(
+ ret + "header.signatureAlgorithmName = ".length() + 1,
+ res.indexOf(";", ret) - 1);
+ }
+
+ ret = res.indexOf("header.validityLength =");
+ if (ret > 0) {
+ validitylength = res.substring(
+ ret + "header.validityLength = ".length() + 1,
+ res.indexOf(";", ret) - 1);
+ }
+
+ return true;
+
+ }
+
+ private boolean approveRequestStatus(StringBuffer s) {
+
+ String res = s.toString();
+
+ if (debug) {
+ System.out.println(res);
+ }
+
+ // Find th Server_ATTRS paramteter value of reqStatus
+
+ int i = 1;
+ int ret;
+
+ for (int t = 0; t < 25; t++) {
+ String cmp = "header.SERVER_ATTRS[" + t + "].name=";
+
+ ret = res.indexOf(cmp);
+ if ((res.substring(ret + cmp.length() + 1, res.indexOf(";", ret) - 1)).equals(
+ "requestStatus")) {
+ i = t;
+ break;
+ }
+
+ }
+
+ String req = "header.SERVER_ATTRS[" + i + "].value=";
+
+ ret = res.indexOf(req);
+ reqStatus = res.substring(ret + req.length() + 1,
+ res.indexOf(";", ret) - 1);
+
+ if (reqStatus != null) {
+ reqStatus.toLowerCase();
+ if (reqStatus.equals("complete")) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ return false;
+
+ }
+
+ private boolean Send() {
+ debug = true;
+ boolean st = false;
+
+ try {
+ // Covert the string port to int port
+
+ Integer x = new Integer(ports);
+
+ port = x.intValue();
+
+ Con2Agent con = new Con2Agent(host, port, certnickname, tokenpwd,
+ cdir);
+
+ con.setQueryString(query);
+ con.setActionURL(ACTION_STRING);
+ con.Send();
+ StringBuffer s = new StringBuffer();
+
+ s = con.getPage();
+
+ if (debug) {
+ System.out.println(s.toString());
+ }
+ switch (reqtype) {
+ case 1:
+ st = RetrieveReq(s);
+ break;
+
+ case 2:
+ st = RetrieveCertDetails(s);
+ break;
+
+ case 3:
+ st = approveRequestStatus(s);
+ break;
+
+ case 4:
+ st = RetrieveProfileApproval(s);
+ break;
+
+ case 5:
+ st = RetrieveProfileReject(s);
+ break;
+
+ case 6:
+ st = RetrieveProfileCancel(s);
+ break;
+
+ case 7:
+ st = RetrieveProfileApproval(s);
+ break;
+
+ default:
+ System.out.println("reqtype not recognized");
+ }
+ } catch (Exception e) {
+ System.err.println("exception: in Send routine" + e);
+ return false;
+ }
+
+ return st;
+ }
+
+ private void buildquery() throws UnsupportedEncodingException {
+
+ if (reqtype == 1) { // req type = list
+ ACTION_STRING = "/" + agenttype + ACTION_LISTREQUEST;
+ query = "seqNumFrom=" + seqNumFrom;
+ query += "&maxCount=" + maxCount;
+ query += "&reqType=" + reqType;
+ query += "&reqState=" + reqState;
+
+ }
+
+ if (reqtype == 2) { // get cert details
+ ACTION_PROCESS_CERT_REQUEST = "/" + AUTH_ID + "/processCertReq";
+ ACTION_STRING = ACTION_PROCESS_CERT_REQUEST;
+ query = "seqNum=" + approveseqnum;
+
+ }
+
+ if (reqtype == 3) { // aaprove cert
+
+ if (validityperiod != null) {
+ Integer x = new Integer(validityperiod);
+
+ validperiod = x.intValue();
+ } else {
+ validperiod = 180;
+ }
+
+ ACTION_PROCESS_CERT_REQUEST = "/" + AUTH_ID + "/processCertReq";
+ ACTION_STRING = ACTION_PROCESS_CERT_REQUEST;
+ query = "seqNum=" + approveseqnum;
+ query += "&toDo=accept";
+ if (subjectdn != null) {
+ query += "&subject=" + URLEncoder.encode(subjectdn, "UTF-8");
+ } else if (subject != null) {
+ query += "&subject=" + URLEncoder.encode(subject, "UTF-8");
+ }
+
+ if (csrRequestorName != null) {
+ query += "&csrRequestorName=" + csrRequestorName;
+ }
+ if (csrRequestorPhone != null) {
+ query += "&csrRequestorPhone=" + csrRequestorPhone;
+ }
+
+ if (csrRequestorEmail != null) {
+ query += "&csrRequestorEmail=" + csrRequestorEmail;
+ }
+ if (sigAlgo != null) {
+ query += "&signatureAlgorithm=" + sigAlgo;
+ }
+ query += "&grantUID=u" + approveseqnum;
+
+ GregorianCalendar begin = new GregorianCalendar();
+ GregorianCalendar end = new GregorianCalendar();
+
+ end.add(GregorianCalendar.DATE, validperiod);
+ Date begindate = begin.getTime();
+ Date enddate = end.getTime();
+
+ query += "&notValidBefore=" + begindate.getTime() / 1000;
+ query += "&notValidAfter=" + enddate.getTime() / 1000;
+
+ if (clientcert.equals("true")) {
+ query += "&certTypeSSLClient=" + clientcert;
+ }
+
+ if (servercert.equals("true")) {
+ query += "&certTypeSSLServer=" + servercert;
+ }
+
+ if (emailcert.equals("true")) {
+ query += "&certTypeEmail=" + emailcert;
+ }
+
+ if (objectsigningcert.equals("true")) {
+ query += "&certTypeObjSigning=" + objectsigningcert;
+ }
+
+ query += "&grantTrustedManagerPrivilege=" + trustedManager;
+
+ }
+
+ if ((reqtype == 4) || (reqtype == 5) || (reqtype == 6)) { // profile based cert request
+
+ if (validityperiod != null) {
+ Integer x = new Integer(validityperiod);
+
+ validperiod = x.intValue();
+ } else {
+ validperiod = 180;
+ }
+
+ ACTION_PROCESS_CERT_REQUEST = "/" + agenttype + "/profileProcess";
+ ACTION_STRING = ACTION_PROCESS_CERT_REQUEST;
+ query = "requestId=" + approveseqnum;
+ query += "&name="
+ + URLEncoder.encode(
+ "UID=test,E=test,CN=test,OU=netscape,O=aol", "UTF-8");
+ query += "&keyUsageCritical=true";
+ query += "&keyUsageDigitalSignature=true";
+ query += "&keyUsageNonRepudiation=true";
+ query += "&keyUsageKeyEncipherment=true";
+ query += "&keyUsageDataEncipherment=false";
+ query += "&keyUsageKeyAgreement=false";
+ query += "&keyUsageKeyCertSign=false";
+ query += "&keyUsageCrlSign=false";
+ query += "&keyUsageEncipherOnly=false";
+ query += "&keyUsageDecipherOnly=false";
+
+ query += "&nsCertCritical=false";
+ query += "&nsCertSSLClient=true";
+
+ query += "&nsCertSSLServer=false";
+ query += "&nsCertEmail=true";
+ query += "&nsCertObjectSigning=false";
+ query += "&nsCertSSLCA=false";
+ query += "&nsCertEmailCA=false";
+ query += "&nsCertObjectSigningCA=false";
+
+ query += "&subAltNameExtCritical=false";
+ query += "&subjAltNames=RFC822Name:"
+ + URLEncoder.encode(" thomasknscp@aol.com", "UTF-8");
+ query += "&signingAlg=MD5withRSA";
+
+ query += "&submit=submit";
+
+ GregorianCalendar begin = new GregorianCalendar();
+ GregorianCalendar end = new GregorianCalendar();
+
+ end.add(GregorianCalendar.DATE, validperiod);
+ // Date begindate = begin.getTime();
+ // Date enddate = end.getTime();
+ String nb = begin.get(Calendar.YEAR) + "-"
+ + begin.get(Calendar.MONTH) + "-" + begin.get(Calendar.DATE)
+ + " " + begin.get(Calendar.HOUR) + ":"
+ + begin.get(Calendar.MINUTE) + ":"
+ + begin.get(Calendar.SECOND);
+
+ String nat = end.get(Calendar.YEAR) + "-" + end.get(Calendar.MONTH)
+ + "-" + end.get(Calendar.DATE) + " "
+ + end.get(Calendar.HOUR) + ":" + end.get(Calendar.MINUTE)
+ + ":" + end.get(Calendar.SECOND);
+
+ query += "&notBefore=" + nb;
+ query += "&notAfter=" + nat;
+
+ query += "&authInfoAccessCritical=false";
+ query += "&authInfoAccessGeneralNames=";
+ query += "&exKeyUsageOIDs=" + "1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4";
+
+ }
+
+ if (reqtype == 4) {
+ query += "&op=approve";
+ }
+
+ if (reqtype == 5) {
+ query += "&op=reject";
+ }
+
+ if (reqtype == 6) {
+ query += "&op=cancel";
+ }
+
+ if (reqtype == 7) {
+ // cadualcert profile approval
+ ACTION_STRING = "/" + "ca" + "/profileProcess";
+
+ GregorianCalendar begin = new GregorianCalendar();
+ GregorianCalendar end = new GregorianCalendar();
+
+ end.add(GregorianCalendar.DATE, validperiod);
+
+ String nb = begin.get(Calendar.YEAR) + "-"
+ + begin.get(Calendar.MONTH) + "-" + begin.get(Calendar.DATE)
+ + " " + begin.get(Calendar.HOUR) + ":"
+ + begin.get(Calendar.MINUTE) + ":"
+ + begin.get(Calendar.SECOND);
+
+ String nat = end.get(Calendar.YEAR) + "-" + end.get(Calendar.MONTH)
+ + "-" + end.get(Calendar.DATE) + " "
+ + end.get(Calendar.HOUR) + ":" + end.get(Calendar.MINUTE)
+ + ":" + end.get(Calendar.SECOND);
+
+ query = "requestId=" + approveseqnum + "&name="
+ + URLEncoder.encode(cadualcert_name, "UTF-8") + "&notBefore=" + nb
+ + "&notAfter=" + nat + "&authInfoAccessCritical=false"
+ + "&authInfoAccessGeneralNames=" + "&keyUsageCritical=true"
+ + "&keyUsageDigitalSignature=false"
+ + "&keyUsageNonRepudiation=false"
+ + "&keyUsageKeyEncipherment=true"
+ + "&keyUsageDataEncipherment=false"
+ + "&keyUsageKeyAgreement=false"
+ + "&keyUsageKeyCertSign=false" + "&keyUsageCrlSign=false"
+ + "&keyUsageEncipherOnly=false"
+ + "&keyUsageDecipherOnly=false" + /* -- For Older CMS 6.x servers use these
+ "&nsCertCritical=false" +
+ "&nsCertSSLClient=true" +
+ "&nsCertSSLServer=false" +
+ "&nsCertEmail=true" +
+ "&nsCertObjectSigning=false" +
+ "&nsCertSSLCA=false" +
+ "&nsCertEmailCA=false" +
+ "&nsCertObjectSigningCA=false" +
+ "&subjAltNameExtCritical=false" +
+ "&subjAltNames=RFC822Name: null" +
+ "&signingAlg=MD5withRSA" +
+ */// For newer CS 7.x servers use these
+ "&exKeyUsageCritical=false"
+ + "&exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4"
+ + "&subjAltNameExtCritical=false"
+ + "&subjAltNames=RFC822Name: null"
+ + "&signingAlg=SHA1withRSA" + "&requestNotes="
+ + "&op=approve" + "&submit=submit";
+
+ }
+
+ }
+
+ private void readProperties() {
+
+ // Read the properties file and assign values to variables .
+ try {
+ getProperties(propfileName);
+ } catch (Exception e) {
+ System.out.println(
+ "exception reading Properties File " + e.getMessage());
+ }
+
+ // Read the properties file
+ host = props.getProperty("enroll.host");
+ ports = props.getProperty("enroll.port");
+ adminid = props.getProperty("enroll.adminid");
+ adminpwd = props.getProperty("enroll.adminpwd");
+ certnickname = props.getProperty("enroll.nickname");
+ cdir = props.getProperty("enroll.certdir");
+ tokenpwd = props.getProperty("enroll.certtokenpwd");
+ approveseqnum = props.getProperty("enroll.seqnum");
+ if (approveseqnum == null) {
+ System.out.println("Seq num is null");
+ }
+
+ approveseqnumFrom = props.getProperty("enroll.seqnumFrom");
+ if (approveseqnumFrom == null) {
+ approveseqnumFrom = "1";
+ }
+
+ approveseqnumTo = props.getProperty("enroll.seqnumTo");
+ if (approveseqnumTo == null) {
+ approveseqnumTo = "100";
+ }
+ validityperiod = props.getProperty("enroll.validperiod");
+ type = props.getProperty("enroll.type");
+ reqType = props.getProperty("enroll.reqtype");
+ reqState = props.getProperty("enroll.reqstate");
+ agenttype = props.getProperty("enroll.agenttype");
+ if (agenttype == null) {
+ agenttype = "ca";
+ }
+
+ trustedManager = props.getProperty("enroll.trust");
+ if (trustedManager.equals("true")) {
+ trustedManager = "true";
+ } else {
+ trustedManager = "false";
+ }
+
+ String de = props.getProperty("enroll.debug");
+
+ if (de == null) {
+ debug = false;
+ } else if (de.equals("true")) {
+ debug = true;
+ } else {
+ debug = false;
+ }
+
+ }
+
+ private boolean listRequest(String from, String To) throws UnsupportedEncodingException {
+
+ Integer x = new Integer(from);
+
+ seqNumFrom = x.intValue();
+
+ Integer y = new Integer(To);
+
+ if ((y.intValue() - seqNumFrom) > 50) {
+ maxCount = 50;
+ } else {
+ maxCount = y.intValue() - x.intValue();
+ }
+ if (maxCount == 0) {
+ maxCount = 1;
+ }
+
+ reqtype = 1;
+ buildquery();
+ return (Send());
+ }
+
+ private boolean approveRequest() throws UnsupportedEncodingException {
+
+ boolean st = true;
+
+ listRequest(approveseqnumFrom, approveseqnumTo);
+
+ if (seqNum.isEmpty()) {
+ System.out.println("No Requests for approval");
+ return false;
+ }
+
+ if (approveseqnum.length() > 0) {
+ if (seqNum.contains(approveseqnum)) {
+ seqNum.removeAllElements();
+ seqNum.addElement(approveseqnum);
+ } else {
+ System.out.println(
+ " Seq num " + approveseqnum + " already approved ");
+ return false;
+ }
+ } else {
+ System.out.println(
+ " Seq num not specified . Approving all pending request From : "
+ + approveseqnumFrom + " To : " + approveseqnumTo);
+ }
+
+ boolean flag = true;
+
+ Integer y = new Integer(approveseqnumTo);
+ int torequest = y.intValue();
+
+ while (flag) {
+
+ i = 0;
+ while (i < seqNum.size()) {
+
+ approveseqnum = (seqNum.elementAt(i)).toString();
+ // Get request details
+ reqtype = 2;
+ buildquery();
+ if (!Send()) {
+ System.out.println("Error : Getting Request details ");
+ i++;
+ continue;
+ }
+
+ if (debug) {
+ System.out.println(
+ csrRequestorName + " " + csrRequestorPhone + " "
+ + csrRequestorEmail + " " + requestID + " "
+ + subject);
+ }
+ // Now for pending status - approve the request
+ reqtype = 3;
+ buildquery();
+ if (!Send()) {
+ System.out.println(
+ "Error: Approving request " + approveseqnum);
+ i++;
+ continue;
+ }
+ System.out.println("Request " + approveseqnum + " is approved ");
+ totalNumApproved++;
+ i++;
+ }
+ Integer x = new Integer(approveseqnum);
+
+ if (x.intValue() >= torequest) {
+ flag = false;
+ } else {
+ listRequest(approveseqnum, approveseqnumTo);
+ }
+
+ }
+ return st;
+ }
+
+ /**
+ * Use this method when you need to use properties file.
+ * @throws UnsupportedEncodingException
+ */
+
+ public int processRequest() throws UnsupportedEncodingException {
+ if (propfileName != null) {
+ readProperties();
+ }
+
+ if (approveseqnum.length() > 0) {
+ approveseqnumFrom = approveseqnum;
+ approveseqnumTo = approveseqnum;
+ }
+
+ type = type.toLowerCase();
+ if (type.equals("approve")) {
+ if (approveRequest()) {
+ System.out.println("Approve Request :" + totalNumApproved);
+ return totalNumApproved;
+ } else {
+ return -1;
+ }
+
+ }
+
+ if (type.equals("list")) {
+
+ if (listRequest(approveseqnumFrom, approveseqnumTo)) {
+ System.out.println("List Request : " + seqNum.size());
+ if (seqNum.size() > 0) {
+ return seqNum.size();
+ } else {
+ return 0;
+ }
+ } else {
+ return -1;
+ }
+
+ }
+
+ return -1;
+ }
+
+ public static void main(String args[]) {
+ // Exit Status - (0) for error
+ // - any number > 0 Pass
+ int st = 0;
+
+ if (args.length < 1) {
+ System.out.println("Usage : propertiesfile");
+ System.exit(0);
+ }
+
+ Request t = new Request(args[0]);
+
+ try {
+ st = t.processRequest();
+ } catch (UnsupportedEncodingException e) {
+ System.out.println(e);
+ e.printStackTrace();
+ }
+ if (st == -1) {
+ System.exit(0);
+ } else {
+ System.exit(st);
+ }
+
+ }// end of function main
+
+} // end of class
+
diff --git a/base/silent/src/com/netscape/pkisilent/common/ServerInfo.java b/base/silent/src/com/netscape/pkisilent/common/ServerInfo.java
new file mode 100644
index 000000000..f63456b4d
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/common/ServerInfo.java
@@ -0,0 +1,355 @@
+package com.netscape.pkisilent.common;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.net.InetAddress;
+import java.util.StringTokenizer;
+
+/**
+ * CMS Test framework .
+ * This class fetches all the necssary ServerInformation to run the test . For example AdminServer information linke
+ * port , hsotname, Config LDAP server port, CMS servers Agentport,AdminPort, EESSL port, EE port etc..
+ */
+
+public class ServerInfo {
+
+ public String serverRoot, instanceRoot, instanceID;
+ public String ldapPort, ldapHost, ldapSSLPort, ldapBaseSuffix, adminPort, admDN, admDNPW, singleSignOnPWD, domain;
+ public String caSigningCertNickName, raSigningCertNickName, ocspSigningCertNickName, kraTransportCertNickName;
+ public String ServerCertNickName, CertAuthority;
+ public String CMSAgentPort, CMSEESSLPort, CMSEEPort, CMSAdminPort, IDBPort;
+
+ public static CMSProperties props = null;
+ public static CMSProperties CMSprops = null;
+
+ // Private variables
+ private int i;
+ public String CMSConfigFile, AdminConfigFile;
+
+ public ServerInfo() {
+ }
+
+ /**
+ * Constructor. Takes Server root as parameter for example ( /export/qa). Reads and collects information about
+ * adminserver and Config LDAP server.
+ */
+ public ServerInfo(String sroot) {
+ serverRoot = sroot;
+ AdminConfigFile = serverRoot + "/admin-serv/config/adm.conf";
+ readAdminConfig();
+ SystemInfo();
+ }
+
+ /**
+ * Constructor. Takes Serverroot ( /export/qa) and instanceRoot (/export/qa/cert-jupiter2) as parameters . Reads and
+ * collects information about Admin Server , Config LDAP server and CMS server .
+ */
+
+ public ServerInfo(String sroot, String instRoot) {
+ serverRoot = sroot;
+ instanceRoot = instRoot;
+ CMSConfigFile = instanceRoot + "/config/CS.cfg";
+ AdminConfigFile = serverRoot + "/admin-serv/config/adm.conf";
+ instanceID = instanceRoot.substring(instanceRoot.indexOf("cert-") + 5);
+ readAdminConfig();
+ SystemInfo();
+ parseServerXML();
+ readCMSConfig();
+ }
+
+ public String GetAdminPort() {
+ return adminPort;
+ }
+
+ public String GetConfigLDAPPort() {
+ return ldapPort;
+ }
+
+ public String GetHostName() {
+ if (domain.indexOf(".") > 0) {
+ return domain.substring(0, domain.indexOf("."));
+ } else {
+ return domain;
+ }
+ }
+
+ public String GetInstanceID() {
+ return instanceID;
+ }
+
+ public String GetCMSConfigFileName() {
+ return CMSConfigFile;
+ }
+
+ public String GetDomainName() {
+ return ldapHost.substring(ldapHost.indexOf(".") + 1);
+ }
+
+ public String GetAgentPort() {
+ return CMSAgentPort;
+ }
+
+ public String GetEESSLPort() {
+ return CMSEESSLPort;
+ }
+
+ public String GetEEPort() {
+ return CMSEEPort;
+ }
+
+ public String GetCMSAdminPort() {
+ return CMSAdminPort;
+ }
+
+ public String GetInternalDBPort() {
+ return IDBPort;
+ }
+
+ public String GetCertAuthority() {
+ return CertAuthority;
+ }
+
+ public String GetCASigningCert() {
+ return caSigningCertNickName;
+ }
+
+ public String GetRASigningCert() {
+ return raSigningCertNickName;
+ }
+
+ public String GetServerCertNickName() {
+ return ServerCertNickName;
+ }
+
+ public void setInstanceRoot(String instRoot) {
+ instanceRoot = instRoot;
+ CMSConfigFile = instanceRoot + "/config/CS.cfg";
+ AdminConfigFile = serverRoot + "/admin-serv/config/adm.conf";
+ instanceID = instanceRoot.substring(instanceRoot.indexOf("cert-") + 5);
+ SystemInfo();
+ parseServerXML();
+ readCMSConfig();
+ }
+
+ // Private functions
+ private void SystemInfo() {
+ try {
+ domain = InetAddress.getLocalHost().getHostName();
+ System.out.println("Debu:SystemInfo " + domain);
+ } catch (Exception e) {
+ System.out.println("Exception InetAddress : " + e.getMessage());
+ }
+
+ }
+
+ private void parseServerXML() {
+ int AGENT = 1;
+ int ADMIN = 2;
+ int EE_SSL = 3;
+ int EE_NON_SSL = 4;
+ int IP = 5;
+ int PORT = 6;
+ BufferedReader in = null;
+
+ try {
+ String xmlFilePath = instanceRoot + "/config/server.xml";
+
+ in = new BufferedReader(new FileReader(xmlFilePath));
+ String s = in.readLine();
+
+ while (s != null) {
+ // <LS id="agent" ip="0.0.0.0" port="8101" security="on"
+ // acceptorthreads="1" blocking="no">
+ if (s.startsWith("<LS id=")) {
+ StringTokenizer st = new StringTokenizer(s, "\"");
+ int index1 = 5, index2 = 3;
+
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+
+ if (token.equalsIgnoreCase("agent")) {
+ index1 = AGENT;
+ } else if (token.equalsIgnoreCase("admin")) {
+ index1 = ADMIN;
+ } else if (token.equalsIgnoreCase("eeSSL")) {
+ index1 = EE_SSL;
+ } else if (token.equalsIgnoreCase("ee_nonSSL")) {
+ index1 = EE_NON_SSL;
+ } else if (token.equals(" ip=")) {
+ index2 = IP;
+ } else if (token.equals(" port=")) {
+ index2 = PORT;
+ }
+
+ if (index1 != 5 && index2 == IP && !token.equals(" ip=")) {
+ // token contains the ip value
+ } else if (index2 == PORT && !token.equals(" port=")) {
+
+ switch (index1) {
+ case 1:
+ CMSAgentPort = token;
+ break;
+
+ case 2:
+ CMSAdminPort = token;
+ break;
+
+ case 3:
+ CMSEESSLPort = token;
+ break;
+
+ case 4:
+ CMSEEPort = token;
+ break;
+
+ default:
+ break;
+
+ }
+
+ break;
+ }
+ } // while token
+ } // if LS
+ s = in.readLine();
+ } // while file no end
+ in.close();
+ } catch (Exception e) {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (Exception ex) {
+ }
+ }
+ }
+ }
+
+ private String stripSpace(String s) {
+
+ String val = "";
+
+ for (int i = 0; i < s.length(); i++) {
+ if ((s.charAt(i) == ' ')) {
+ i++;
+ continue;
+ } else {
+ val += s.charAt(i);
+ }
+ }
+ return val;
+ }
+
+ private void readAdminConfig() {
+ String ldapHostStr = "ldapHost:";
+ String ldapPortStr = "ldapPort:";
+ String adminPortStr = "port:";
+
+ try {
+ FileInputStream fis = new FileInputStream(AdminConfigFile);
+ int size = fis.available();
+ byte b[] = new byte[size];
+
+ if (fis.read(b) != b.length) {
+ System.out.println("Could not read ");
+
+ } else {
+ String tmpstr = new String(b, 0, b.length);
+ int ret;
+
+ if ((ret = tmpstr.indexOf(ldapHostStr)) > -1) {
+ ldapHost = tmpstr.substring(ret + ldapHostStr.length() + 1,
+ tmpstr.indexOf("ldapPort", ret) - 1);
+ ldapHost = stripSpace(ldapHost);
+ // System.out.println(ldapPort);
+ }
+
+ if ((ret = tmpstr.indexOf(ldapPortStr)) > -1) {
+ ldapPort = tmpstr.substring(ret + ldapPortStr.length() + 1,
+ tmpstr.indexOf("sie", ret) - 1);
+ ldapPort = stripSpace(ldapPort);
+ // System.out.println(ldapPort);
+ }
+ if ((ret = tmpstr.indexOf(adminPortStr)) > -1) {
+ adminPort = tmpstr.substring(ret + adminPortStr.length() + 1,
+ tmpstr.indexOf("ldapStart", ret) - 1);
+ adminPort = stripSpace(adminPort);
+ // System.out.println(adminPort);
+ }
+
+ }
+
+ fis.close();
+ } catch (Exception e) {
+ System.out.println("exception " + e.getMessage());
+ }
+
+ }
+
+ private void readCMSConfig() {
+
+ try {
+ FileInputStream fis = new FileInputStream(CMSConfigFile);
+
+ CMSprops = new CMSProperties();
+ CMSprops.load(fis);
+ System.out.println("Reading CMS Config file successful");
+ CertAuthority = CMSprops.getProperty("subsystem.0.id");
+ if (CertAuthority.equals("ca")) {
+ caSigningCertNickName = CMSprops.getProperty(
+ "ca.signing.cacertnickname");
+ ServerCertNickName = "Server-Cert cert-" + instanceID;
+ }
+ if (CertAuthority.equals("ra")) {
+ raSigningCertNickName = CMSprops.getProperty(
+ "ra.signing.cacertnickname");
+ ServerCertNickName = "Server-Cert cert-" + instanceID;
+ }
+ IDBPort = CMSprops.getProperty("internaldb.ldapconn.port");
+
+ fis.close();
+ } catch (Exception e) {
+ System.out.println("exception " + e.getMessage());
+ }
+
+ }
+
+ public static void main(String args[]) {
+ ServerInfo s = new ServerInfo("Test", "Test");
+
+ System.out.println(" Admin Port : " + s.GetAdminPort());
+ System.out.println(" LDAP Port : " + s.GetConfigLDAPPort());
+ System.out.println("Hostname " + s.GetHostName());
+ System.out.println("InstanceID" + s.GetInstanceID());
+ System.out.println(" doamin name : " + s.GetDomainName());
+ System.out.println("AgentPort " + s.GetAgentPort());
+ System.out.println("EESSLPort " + s.GetEESSLPort());
+ System.out.println("EEPort " + s.GetEEPort());
+ System.out.println("CMSAdminPort :" + s.GetCMSAdminPort());
+ System.out.println("CAAuthority : " + s.GetCertAuthority());
+ System.out.println("CASigningCert:" + s.GetCASigningCert());
+ System.out.println("RASigningCert:" + s.GetRASigningCert());
+ System.out.println("ServerCert" + s.GetServerCertNickName());
+
+ }// end of function main
+
+} // end of class
+
diff --git a/base/silent/src/com/netscape/pkisilent/common/TestClient.java b/base/silent/src/com/netscape/pkisilent/common/TestClient.java
new file mode 100644
index 000000000..0e4ed9cdd
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/common/TestClient.java
@@ -0,0 +1,941 @@
+package com.netscape.pkisilent.common;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.net.ServerSocket;
+import java.util.Properties;
+
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.ssl.SSLCertificateApprovalCallback;
+
+/**
+ * CMS Test framework .
+ * Before createing an instance of this class make sure you havae set an environment variable TEST_CONFIG_FILE.
+ */
+
+public class TestClient implements SSLCertificateApprovalCallback {
+
+ public int port;
+
+ // properties file parameters
+ public static String host, ports, adminid, adminpwd, propfileName, cdir;
+ public static String certnickname, keysize, keytype, tokenpwd;
+ public static String serverRoot, instanceRoot, ldaprootDN, ldaprootDNPW, caInstanceRoot, dataDirectory;
+
+ // Program variables
+ public String STATUS;
+ public Properties props = null;
+ public String ACTION_STRING;
+ public String query;
+ public boolean debug = false;
+ // Certificate nicknames to be used by Test Clients
+ private int i;
+ private String testConfigFile;
+
+ public String caAgentCertName = "ca-agent";
+ public String raAgentCertName = "ra-agent";
+ public String ocspAgentCertName = "ocsp-agent";
+ public String kraAgentCertName = "kra-agent";
+ public String tksAgentCertName = "tks-agent";
+ public String singleSignOnPWD = "secret12";
+ public String adminCertName = "cn=admin";
+ private String ldapBaseSuffix = "dc=netscape,dc=com";
+ private String admDN = "admin";
+ private String admDNPW = "admin";
+ private String TmpDir;
+ private String TestLogFile;
+ private String startupTests, cleanupTests;
+
+ private X509Certificate SSLServerCert = null;
+
+ // Cert Sub vart
+ public String UID, OU, O, DN, E, CN, C, GN, SN, L, MAIL;
+ // Enroll
+ protected String PWD;
+ // CRypto
+ public ComCrypto cCrypt = new ComCrypto();
+ public String pkcs10request = null;
+
+ // Error
+
+ public String ErrorDetail;
+
+ private String serverKeyType, serverKeySize, serverKeyAlgo;
+
+ private String unauth[] = {
+ "Unauthorized Access", "Server Error",
+ "Not Found", "Generic Unauthorized" };
+
+ public boolean approve(X509Certificate x509, SSLCertificateApprovalCallback.ValidityStatus status) {
+ SSLServerCert = x509;
+ return true;
+ }
+
+ // Constructor
+
+ public TestClient() {
+ keysize = "1024";
+ keytype = "RSA";
+ }
+
+ /**
+ * Constructor . Takes the parameter for keysize and keytype .
+ * Before creating a new instance of this class make sure you have set TEST_CONFIG_FILE variable in your
+ * environnemt.
+ * Reads the TEST_CONFIG_FILE . Initializes the certificate database. See engage.cfg file for example.
+ *
+ * @param keysize
+ * @param keytype
+ */
+
+ public TestClient(String ks, String kt) {
+
+ testConfigFile = ReadEnv("TEST_CONFIG_FILE");
+
+ System.out.println(testConfigFile);
+ readConfigFile();
+ keysize = ks;
+ keytype = kt;
+ cCrypt.setCertDir(cdir);
+ cCrypt.setCertnickname(adminCertName);
+ cCrypt.setKeySize(keysize);
+ cCrypt.setKeyType(keytype);
+ cCrypt.setTokenPWD(tokenpwd);
+ cCrypt.setDebug(true);
+ cCrypt.CreateCertDB();
+
+ }
+
+ /**
+ * Gets the SSLServer Certificate of the server
+ */
+
+ public X509Certificate getSSLServerCert() {
+ return SSLServerCert;
+ }
+
+ /**
+ * finds the cert with nickname cname in the clients cert database
+ */
+
+ public X509Certificate findCertByNickname(String cname) {
+
+ return cCrypt.findCert(cname);
+
+ }
+
+ /**
+ * Imports certificate to cert database.Takes parameters Certpackage and certnickname
+ */
+ boolean importCert(String cp, String nickname) {
+
+ return cCrypt.importCert(cp, nickname);
+
+ }
+
+ /**
+ * This function returns true if you choose to executeStartupTests
+ */
+
+ public boolean executeStartupTests() {
+
+ if (startupTests == null) {
+ return false;
+ } else if (startupTests.equals("y")) {
+ return true;
+ } else {
+ return false;
+ }
+
+ }
+
+ /**
+ * This function returns true if you choose to executeCleanupTests
+ */
+
+ public boolean executeCleanupTests() {
+
+ if (cleanupTests == null) {
+ return false;
+ } else if (cleanupTests.equals("y")) {
+ return true;
+ } else {
+ return false;
+ }
+
+ }
+
+ public String GetServerRoot() {
+ return serverRoot;
+ }
+
+ public String GetInstanceRoot() {
+ return instanceRoot;
+ }
+
+ public String getErrorDetail() {
+ return ErrorDetail;
+ }
+
+ public String GetAdminDN() {
+ return admDN;
+ }
+
+ public String GetAdminDNPWD() {
+ return admDNPW;
+ }
+
+ public String GetLDAPDN() {
+ return ldaprootDN;
+ }
+
+ public String GetLDAPDNPW() {
+ return ldaprootDNPW;
+ }
+
+ public String GetLDAPBASE() {
+ return ldapBaseSuffix;
+ }
+
+ public String GetAdminCertName() {
+ return adminCertName;
+ }
+
+ public String GetRAAgentCertName() {
+ return raAgentCertName;
+ }
+
+ public String GetKRAAgentCertName() {
+ return kraAgentCertName;
+ }
+
+ public String GetOCSPAgentCertName() {
+ return ocspAgentCertName;
+ }
+
+ public String GetTKSAgentCertName() {
+ return tksAgentCertName;
+ }
+
+ public String GetDataDirectory() {
+ return dataDirectory;
+ }
+
+ public String GetClientCertDB() {
+ return cdir;
+ }
+
+ public String GetClientCertDBPW() {
+ return tokenpwd;
+ }
+
+ public String GetSingleSignOnPW() {
+ return singleSignOnPWD;
+ }
+
+ public String GetCARoot() {
+ return caInstanceRoot;
+ }
+
+ public String GetTmpDir() {
+ return TmpDir;
+ }
+
+ public String GetServerKeySize() {
+ return serverKeySize;
+ }
+
+ public String GetServerKeyType() {
+ return serverKeyType;
+ }
+
+ public String GetServerKeyAlgorithm() {
+ return serverKeyAlgo;
+ }
+
+ public void setStatusString(String ststr) {
+ STATUS = ststr;
+ }
+
+ public void setDebug(boolean t) {
+ debug = t;
+ }
+
+ public void setpkcs10Request(String t) {
+ pkcs10request = t;
+ }
+
+ public void setHostName(String s) {
+ host = s;
+ }
+
+ public void setCARoot(String s) {
+ caInstanceRoot = s;
+ }
+
+ public void setTestLogFile(String s) {
+ TestLogFile = s;
+ }
+
+ /**
+ * parses a http page and returns true if any error is returned by server
+ **/
+
+ public boolean getError(String line) {
+
+ int ret;
+
+ ret = line.indexOf("fixed.errorDetails");
+
+ if (line.indexOf("fixed.errorDetails") == 0) {
+ ErrorDetail = line.substring(
+ ret + ("fixed.errorDetails = ").length());
+ return true;
+ }
+
+ if (line.indexOf("fixed.errorDetails") >= 0) {
+ ErrorDetail = line.substring(
+ ret + ("fixed.errorDetails = ").length());
+ return true;
+ }
+
+ ret = line.indexOf("fixed.unexpectedError");
+
+ if (line.indexOf("fixed.unexpectedError") == 0) {
+ System.out.println("Processing unexpectedError");
+ ErrorDetail = line.substring(
+ ret + ("fixed.unexpectedError = ").length());
+ return true;
+ }
+
+ if (line.indexOf(unauth[0]) > 0) {
+ ErrorDetail = unauth[0];
+ return true;
+ }
+ if (line.indexOf(unauth[1]) > -1) {
+ ErrorDetail = unauth[1];
+ return true;
+ }
+ if (line.indexOf(unauth[2]) > -1) {
+ ErrorDetail = unauth[2];
+ return true;
+ }
+ if (line.indexOf(unauth[3]) > -1) {
+ ErrorDetail = unauth[3];
+ return true;
+ }
+
+ if (line.indexOf("errorReason") >= 0) {
+ ErrorDetail = line.substring(ret + ("errorReason=").length());
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Reads a properties file . Takes filename as input parameter.
+ */
+
+ public void getProperties(String fileName) throws Exception {
+ try {
+ FileInputStream fis = new FileInputStream(fileName);
+
+ props = new Properties();
+ props.load(fis);
+ } catch (Exception e) {
+ System.out.println("exception " + e.getMessage());
+ }
+
+ }
+
+ public String ReadEnv(String str) {
+ try {
+ Process p = null;
+ Runtime r = Runtime.getRuntime();
+ String OS = System.getProperty("os.name").toLowerCase();
+
+ if (OS.indexOf("windows") > 1) {
+ p = r.exec("cmd.exe /c set");
+ } else {
+ p = r.exec("env");
+ }
+
+ BufferedReader br = new BufferedReader(
+ new InputStreamReader(p.getInputStream()));
+ String line;
+
+ while ((line = br.readLine()) != null) {
+ int idx = line.indexOf('=');
+ String key = line.substring(0, idx);
+ String value = line.substring(idx + 1);
+
+ // System.out.println(key + "=" + value);
+ if (key.startsWith(str)) {
+ return value;
+ }
+ }
+ return null;
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ private void readConfigFile() {
+ try {
+ getProperties(testConfigFile);
+ } catch (Exception e) {
+ System.out.println(
+ "exception reading TestConfigFile " + e.getMessage());
+ }
+
+ serverRoot = props.getProperty("SROOT");
+ instanceRoot = props.getProperty("IROOT");
+ dataDirectory = props.getProperty("DATA_DIR");
+ ldapBaseSuffix = props.getProperty("LDAPBASESUFFIX");
+
+ if (ldapBaseSuffix.indexOf("\"") > -1) {
+ ldapBaseSuffix = ldapBaseSuffix.substring(1,
+ ldapBaseSuffix.length() - 1);
+ }
+
+ ldaprootDN = props.getProperty("LDAPROOTDN");
+ // Strip of th e quotes "cn=directory manager" string
+ if (ldaprootDN.indexOf("\"") > -1) {
+ ldaprootDN = ldaprootDN.substring(1, ldaprootDN.length() - 1);
+ }
+ System.out.println("ldaprootDN : " + ldaprootDN);
+
+ ldaprootDNPW = props.getProperty("LDAPROOTDNPW");
+ cdir = props.getProperty("CERTDB");
+ tokenpwd = props.getProperty("CERTDBPW");
+ caInstanceRoot = props.getProperty("CAIROOT");
+ admDN = props.getProperty("ADMINDN");
+ admDNPW = props.getProperty("ADMINDNPW");
+ singleSignOnPWD = props.getProperty("SINGLESIGNONPW");
+ serverKeySize = props.getProperty("KEYSIZE");
+ serverKeyType = props.getProperty("KEYTYPE");
+ serverKeyAlgo = props.getProperty("KEYALGORITHM");
+
+ TmpDir = props.getProperty("TMP_DIR");
+ TestLogFile = props.getProperty("TEST_LOG_FILE");
+
+ String de = props.getProperty("DEBUG");
+
+ if (de == null) {
+ debug = false;
+ } else if (de.equals("true")) {
+ debug = true;
+ } else {
+ debug = false;
+ }
+
+ }
+
+ /**
+ * returns a String representation of an interger
+ */
+ public String getString(int m) {
+ Integer x = new Integer(m);
+ String s = x.toString();
+
+ return s;
+ }
+
+ /**
+ * returns FreePort in this machine . Takes a parmater portnumber. For example getFreePort("4026").
+ */
+ public String getFreePort(String s) {
+ Integer x = new Integer(s);
+ int p = x.intValue();
+
+ // if p = 0, then the serversocket constructor get a free port by itself
+ p = 0;
+ try {
+ ServerSocket ss1 = new ServerSocket(p);
+
+ p = ss1.getLocalPort();
+ System.out.println("Obtained Free Port = " + p);
+ ss1.close();
+ return (getString(p));
+ } catch (Exception e) {
+ System.out.println("Unable to get Free Port");
+ e.printStackTrace();
+ p = 0;
+ return (getString(p));
+ }
+
+ // This following method doesn't Always get a free port.
+ // while (st) {
+ // if(isSocketUnused(host,p) )
+ // st=false;
+ // p++;
+ // }
+ // return (getString(p));
+
+ }
+
+ /**
+ * Reads a file and returns the cert request as string
+ **/
+
+ public String readRequest(String filename) {
+ try {
+ FileInputStream f1 = new FileInputStream(filename);
+ int size = f1.available();
+ byte b[] = new byte[size];
+
+ if (f1.read(b) != b.length) {
+ return null;
+ }
+
+ f1.close();
+ String s = new String(b);
+
+ return s;
+ } catch (Exception e) {
+ System.out.println("exception " + e.getMessage());
+ return null;
+ }
+ }
+
+ public static void main(String args[]) {
+ TestClient t = new TestClient("1024", "RSA");
+
+ /*
+ *******************************************************************
+ * Sample programs to initialze calsses
+ *******************************************************************
+ */
+
+ /*
+ ********************************************************************
+ * To Test AutoInstaller
+ *******************************************************************
+ */
+
+ /*
+ AutoInstaller a = new AutoInstaller(t.GetServerRoot());
+
+ ServerInfo s = new ServerInfo(t.GetServerRoot());
+ System.out.println (" Admin Port : " + s.GetAdminPort());
+ System.out.println (" LDAP Port : "+ s.GetConfigLDAPPort());
+ System.out.println( "Hostname " + s.GetHostName());
+ System.out.println(" doamin name : " + s.GetDomainName());
+
+ t.setHostName(s.GetHostName());
+ // Set adminServer Info
+ a.setAdminInfo(s.GetHostName(),s.GetAdminPort(),s.GetDomainName(),"admin","admin");
+ a.setAdminInfo(s.GetHostName(),s.GetAdminPort(),"mcom.com","admin","admin");
+
+ // setCAInfo
+ a.setCAInfo(s.GetHostName(),"1027","8100","admin","secret12");
+ //setInternalDB info
+ String dp = t.getFreePort("38900");
+ a.setInternalDBInfo(s.GetHostName(),"38907","ca-db","cn=directory manager","secret12" );
+
+ // set tokenInfo
+
+ a.setTokenInfo("Internal","secret12");
+
+ // set Subsystem info
+ String agp = t.getFreePort("8100");
+ String adp = t.getFreePort("8200");
+ String eesp = t.getFreePort("1027");
+ String eep = t.getFreePort("1100");
+
+ System.out.println(agp);
+
+ a.setSubSystemInfo("testra",t.GetServerRoot(),"RSA","1024","MD5","365","cn=certificate manager,ou=test,o=test",adp,agp,eesp,eep);
+
+ a.setClientDBInfo(t.GetClientCertDB(),"secret12",t.GetAdminCertName());
+
+ a.ConfigureCA("admin","admin","secret12","secret12");
+
+ // a.ConfigureRA("admin","admin","secret12","secret12");
+
+ */
+
+ /*
+ ******************************************************
+ * Example to Get Server Details
+ ******************************************************
+ */
+
+ ServerInfo s = new ServerInfo(t.GetServerRoot(), t.GetInstanceRoot());
+
+ t.setHostName(s.GetHostName());
+
+ System.out.println("AgentPort " + s.GetAgentPort());
+ System.out.println("EESSLPort " + s.GetEESSLPort());
+ System.out.println("EEPort " + s.GetEEPort());
+ System.out.println("CMSAdminPort :" + s.GetCMSAdminPort());
+ System.out.println("IDBPort : " + s.GetInternalDBPort());
+ System.out.println("CAAuthority : " + s.GetCertAuthority());
+ System.out.println("CASigningCert:" + s.GetCASigningCert());
+ System.out.println("RASigningCert:" + s.GetRASigningCert());
+ System.out.println("ServerCert" + s.GetServerCertNickName());
+ System.out.println("------------------------------------------");
+ System.out.println(" Internal Database Test:");
+ System.out.println(" LDAP Port : " + s.GetConfigLDAPPort());
+ System.out.println("Hostname " + s.GetHostName());
+
+ DirEnroll de = new DirEnroll(s.GetHostName(), s.GetEESSLPort());
+
+ de.setAuthenticator("Portal");
+ de.setUIDInfo("caeetest110", "secret12");
+ de.enroll();
+
+ /* ****************************************************************
+ * CMC Enroll
+ ***************************************************************
+ */
+
+ /* CMSUtils cmsutils = new CMSUtils(t.GetServerRoot());
+ String requestfile="/u/lgopal/work/tetCMS/ns/tetframework/testcases/CMS/6.0/acceptance/data/basic/cmcreq/cmctest1.req";
+ cmsutils.runCMCEnroll(t.GetClientCertDB(),"cn=admin",t.GetClientCertDBPW(),requestfile);
+ Profiles pr = new Profiles(s.GetHostName(),s.GetEESSLPort());
+ pr.setProfileType("caCMCUserCert");
+ pr.setCertAuthority("ca");
+
+ String request = t.readRequest(requestfile+".out");
+ String bstr = "-----BEGIN NEW CERTIFICATE REQUEST-----";
+ String estr="-----END NEW CERTIFICATE REQUEST-----";
+ String Blob1 = request.substring(bstr.length() + 1);
+ String Blob2 = Blob1.substring(0,Blob1.indexOf(estr));
+ request=Blob2;
+
+
+ pr.setRequest(request);
+
+ pr.setUserInfo("UID=test1,Ou=netscape,o=aol","test","test","test","netscape","aol");
+ pr.clientCertEnroll();
+ */
+
+ /* ****************************************************************
+ * OCSP Client stuff
+ ************************************************************
+ */
+
+ /*
+ String ip= "10.169.25.26";
+ OCSPClient ocspclient= new OCSPClient(s.GetHostName(),ip,s.GetEEPort(),t.GetClientCertDB(),t.GetClientCertDBPW(),"cn=admin" ,"/tmp/ocsp.out","4");
+ ocspclient.setCert(t.findCertByNickname("ocsp-agent"));
+
+ ocspclient.SendOCSPRequest();
+ */
+
+ /*
+ *****************************************************
+ * Test CRMFcleint and KRA REcovery and Archival
+ *****************************************************
+ */
+
+ /*
+ *********************************************************
+ * OCSP Agent stuff
+ *********************************************************
+ */
+
+ /* Retrieval rtr = new Retrieval(s.GetHostName(),s.GetEESSLPort());
+ rtr.getCACert();
+ System.out.println("CA Cert chain" + rtr.getCert());
+
+ OcspAgent ocspAgent= new OcspAgent(s.GetHostName(),"8111");
+ ocspAgent.setAgentCertName(t.GetOCSPAgentCertName());
+
+ String cert = "-----BEGIN CERTIFICATE-----"+"\n"+rtr.getCert()+"\n"+"-----END CERTIFICATE-----\n";
+
+ ocspAgent.setCACert(cert);
+ ocspAgent.addCA();
+ */
+
+ /*
+ ***************************************************************
+ Submit Profile based request
+ *********************************************************
+ */
+
+ /*
+ Profiles pr = new Profiles(s.GetHostName(),s.GetEESSLPort());
+ pr.setProfileType("caUserCert");
+ // pr.setProfileType("caDirUserCert");
+
+ pr.setCertAuthority("ca");
+ pr.setUserInfo("UID=test1,Ou=netscape,o=aol","test","test","test","netscape","aol");
+ //pr.setDirUserInfo("test","netscape");
+ pr.clientCertEnroll();
+ System.out.println("Request ID is " + pr.getRequestID());
+
+
+ Request re = new Request (s.GetHostName(),s.GetAgentPort(),"ca");
+ re.setAgentCertName(t.GetAdminCertName());
+ re.ApproveProfileRequests(pr.getRequestID());
+ */
+
+ /*
+ String TransportCert="MIICJTCCAY6gAwIBAgIBBTANBgkqhkiG9w0BAQQFADBDMRswGQYDVQQKExJhY2NlcHRhY25ldGVzdDEwMjQxFzAVBgNVBAsTDmFjY2VwdGFuY2V0ZXN0MQswCQYDVQQDEwJjYTAeFw0wMzA0MjMyMTM3NTFaFw0wNDA0MjIwOTMzMzFaMDkxETAPBgNVBAoTCHRlc3QxMDI0MRcwFQYDVQQLEw5hY2NlcHRhbmNldGVzdDELMAkGA1UEAxMCcmEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANVW81T7GatHIB25kF0jdY4h4hOF1NAlAHE2YdN/UEyXuU22CfwrIltA3x/6sKFHhbbFysn6nGJlgKipPJqJDwyYTIv07hgoXqgcUu8fSYQg4BDHYhpHJxsUt3BSfADTjxAUHize7C2F8TVhBIcWW043FSkwvAiUjJb7uqQRKn7lAgMBAAGjMzAxMA4GA1UdDwEB/wQEAwIFIDAfBgNVHSMEGDAWgBTqvc3UPGDSWq+21DZGSUABNGIUbDANBgkqhkiG9w0BAQQFAAOBgQCNLJivNDHTTmCb2vDefUwLMxXNjuHwrbjVqymHPFqUjredTq2Yp+Ed1zxj+mxRovzegd65Tbnx+MV84j8K3Qc1kWOC+kbohAY9svSPsN3o5Q5BB19+5nUPC5Gk/mxkWJWWJLOnpKJGiAHMZIr58TH7hF8KQWXWMN9ikSFkPj0a/g==";
+
+
+ CRMFClient CrmfClient = new CRMFClient(s.GetHostName(),s.GetEEPort());
+ CrmfClient.setDBInfo(t.GetClientCertDB(),t.GetClientCertDBPW());
+ CrmfClient.setTransportCert(TransportCert);
+ CrmfClient.setUserInfo("user","netscape");
+ CrmfClient.setLDAPInfo(t.GetLDAPDN(),t.GetLDAPDNPW());
+ CrmfClient.setDualKey(true);
+
+ if(!CrmfClient.Enroll())
+ {System.out.println("CRMFClient : could not submit request");}
+
+
+ checkRequest cr = new checkRequest(s.GetHostName(),s.GetEESSLPort(),t.getString(CrmfClient.getRequestId()),"false");
+ cr.checkRequestStatus();
+ System.out.println("Serial num " + cr.getSerialNumber());
+ System.out.println("cert pack " + cr.getCert());
+
+ KraAgent kraAgent = new KraAgent(s.GetHostName(),"8111");
+ kraAgent.setAgentCertName("cn=admin");
+ System.out.println("KRAAgent List archival");
+
+ Vector aReq= kraAgent.ListArchivalRequests();
+ int i=0;
+ while(i < aReq.size() )
+ {
+ System.out.print(aReq.elementAt(i) + " ");
+ i++;
+ }
+
+ kraAgent.setCertificate(cr.getCert());
+ kraAgent.setLocalAgent(false);
+ kraAgent.recoverKeys();
+ */
+
+ /*
+ *************************************************************
+ * Example to Connect oto Config Directory port
+ *************************************************************
+ */
+
+ /*
+ CMSLDAP cmsldap = new CMSLDAP(s.GetHostName(),s.GetConfigLDAPPort(),t.GetLDAPDN(),t.GetLDAPDNPW());
+ if(cmsldap.connect())
+ System.out.println("LDAP Connection successful");
+ else
+ System.out.println("Error Connecting to LDAPSERVER");
+
+ // Add user to config directoory
+ if (cmsldap.userAdd("ou=people,"+t.GetLDAPBASE(),"t2","t2","t2","netscape"))
+ System.out.println("Added user to Config directory");
+
+ */
+
+ /*
+ *************************************************************
+ * Example to Submit a CRMFCleint request to CA
+ *************************************************************
+ */
+
+ /*
+ String TransportCert =
+ "MIICJTCCAY6gAwIBAgIBBTANBgkqhkiG9w0BAQQFADBDMRswGQYDVQQKExJhY2NlcHRhY25ldGVzdDEwMjQxFzAVBgNVBAsTDmFjY2VwdGFuY2V0ZXN0MQswCQYDVQQDEwJjYTAeFw0wMzA0MTgyMjMwMDhaFw0wNDA0MTcxMDI2MDhaMDkxETAPBgNVBAoTCHRlc3QxMDI0MRcwFQYDVQQLEw5hY2NlcHRhbmNldGVzdDELMAkGA1UEAxMCcmEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAN6sQ3mSU8mL6i6gTZIXDLzOZPhYOkQLpnJjit5hcPZ0JMn0CQVXo4QjKN1xvuZv8qVlZoQw9czmzp/knTa0sCDgFKd0r+u0TnLeZkJMSimgFnma9CnChlaDHnBd8Beu4vyaHmo7rJ0xA4etn7HjhmKbaQZOcv/aP0SW9JXRga7ZAgMBAAGjMzAxMA4GA1UdDwEB/wQEAwIFIDAfBgNVHSMEGDAWgBSC3fsQHb7fddr2vL0UdkM2dAmUWzANBgkqhkiG9w0BAQQFAAOBgQBkAGbgd9HIqwoLKAr+V6bj9oWesDmDH80gPPxj10qyWSQYIs8PofOs/75yGS9nxhydtgSMFoBgCPdroUI31kZQQlFzxtudGoKD+5MWSXho79XzPwpjheOBYgpX6ch+L4tMLFDpqeraB1yZESO5EEeKm20DGVBOKVWxHhddO1BenA==";
+
+ CRMFClient CrmfClient = new CRMFClient(s.GetHostName(),s.GetEEPort());
+ CrmfClient.setDBInfo(t.GetClientCertDB(),t.GetClientCertDBPW());
+ CrmfClient.setTransportCert(TransportCert);
+ CrmfClient.setUserInfo("user","netscape");
+ CrmfClient.setLDAPInfo(t.GetLDAPDN(),t.GetLDAPDNPW());
+ CrmfClient.setDualKey(true);
+
+ if(!CrmfClient.Enroll())
+ {System.out.println("CRMFClient : could not submit request");}
+ */
+
+ /* KRA Agent list archived request */
+
+ /* ServerInfo KRAsvrInfo = new ServerInfo(t.GetServerRoot());
+ String KRAinstanceRoot=t.GetServerRoot() + "/cert-" + "KRARSA1024" ;
+ KRAsvrInfo.setInstanceRoot(KRAinstanceRoot);*/
+
+ /* System.out.println("KRAAgent ");
+ KraAgent kraAgent = new KraAgent(s.GetHostName(),s.GetAgentPort());
+ kraAgent.setAgentCertName(t.GetKRAAgentCertName());
+ System.out.println("KRAAgent List archival");
+
+ Vector aReq= kraAgent.ListArchivalRequests();
+ int i=0;
+ while(i < aReq.size() )
+ {
+ System.out.print(aReq.elementAt(i) + " ");
+ i++;
+ }
+
+ */
+
+ // cmsldap.disconnect();
+
+ /*
+ *************************************************************
+ * Example to submit manual user enrollment request
+ *************************************************************
+ /*
+
+
+ /*
+ UserEnroll ue = new UserEnroll(s.GetHostName(),"1029");
+ ue.setUserInfo("E=testman,CN=testman,OU=netscape,O=aol,UID=testman1,C=US","testman", "testman", "testman1", "netscape","t");
+
+ boolean flag = ue.clientCertEnroll();
+ if(flag)
+ System.out.println("Success submitted request");
+ */
+
+ /*
+ *************************************************************
+ * Example to submit Directory based enroolemt request
+ *************************************************************
+ /*
+
+ /*
+ // Add user to config directoory
+ if (cmsldap.userAdd("dc=netscape,dc=com","t2","t2","t2","netscape"))
+ System.out.println("Success ");
+
+ if(cmsldap.TurnOnSSL("slapd-jupiter2","Server-Cert cert-jupiter2","7000"))
+ System.out.println("Turned on ssl");
+ else
+ return;
+
+ cmsldap.TurnOffSSL();
+
+ cmsldap.disconnect();
+
+ DirEnroll de = new DirEnroll(s.GetHostName(),s.GetEESSLPort());
+ de.setUIDInfo("t2","netscape");
+ de.enroll();
+
+ */
+
+ /*
+ *************************************************************
+ * Example to submit Admin Enrollment request
+ *************************************************************
+ /*
+
+ /*
+
+ AdminEnroll ade = new AdminEnroll("jupiter2","8200","cn=CMS Administrator,UID=admin,C=US","admin", "secret12");
+ flag = ade.Enroll();
+ if (flag)
+ System.out.println("adminEnrolled Successfully");
+ */
+
+ /*
+ *************************************************************
+ * Example gent List Pending request
+ *************************************************************
+ /*
+
+ /*
+
+ // Agent List and Approve Request
+ Request re = new Request (s.GetHostName(),s.GetAgentPort(),s.GetCertAuthority());
+ re.setAgentCertName(t.GetAdminCertName());
+ re.ListPendingRequests("2","70");
+ re.ApproveRequests(t.getString(ue.getRequestId()));
+ */
+
+ /*
+ *************************************************************
+ * Example for CheckRequest Status and add the certificate to internal db
+ *************************************************************
+ /*
+
+ /*
+ // check request status and Revoke cert
+ checkRequest cr = new checkRequest(s.GetHostName(),s.GetEESSLPort(),t.getString(ue.getRequestId()),"false");
+ checkRequest cr = new checkRequest(s.GetHostName(),s.GetEESSLPort(),"1","false");
+
+ cr.checkRequestStatus();
+ System.out.println("Serial num " + cr.getSerialNumber());
+ System.out.println("cert pack " + cr.getCert());
+
+ String st= "-----BEGIN CERTIFICATE-----"+"\n"+cr.getCert()+"\n"+"-----END CERTIFICATE-----\n";
+ System.out.println("cert pack " + st);
+
+ cmsldap.getXCertificate(st.getBytes());
+
+ */
+
+ /*
+ *************************************************************
+ * Example agent ro revoke request
+ *************************************************************
+ /*
+
+ /*
+ Revoke rr = new Revoke (s.GetHostName(),s.GetAgentPort(),s.GetCertAuthority(),t.getString(cr.getSerialNumber()));
+ rr.revokeCerts();
+ */
+
+ /*
+ *************************************************************
+ * Example Agent update CRL
+ *************************************************************
+ /*
+
+ /*
+ // Update CRLand DISPLAY it
+
+ System.out.println("Displayin CRL");
+ CRL crl = new CRL (s.GetHostName(),s.GetAgentPort(),"/tmp/crlfile");
+ crl.setAgentCertName(t.GetAdminCertName());
+ crl.updateCRL();
+ crl.displayCRL();
+ crl.getRevokedCerts();
+ */
+
+ // Update CRL in Directory
+ /* UpdateDir dcrl = new UpdateDir(s.GetHostName(),s.GetEESSLPort());
+ dcrl.updateDir();*/
+
+ /*
+ *************************************************************
+ * Example for stopping and starting servers
+ *************************************************************
+ */
+
+ /*
+ DSTask idb = new DSTask(t.GetServerRoot()+"/slapd-jupiter2-db");
+ if (idb.ldapStop()) System.out.println("IDB stopped");
+ if(idb.ldapStart()) System.out.println("IDB Started");
+
+ System.out.println("------------------------------------------");
+ System.out.println(" CMS Test:");
+ CMSTask task = new CMSTask(t.GetInstanceRoot());
+ task.CMSStop();
+ task.CMSStart();
+ */
+
+ }// end of function main
+
+}
diff --git a/base/silent/src/com/netscape/pkisilent/common/UserEnroll.java b/base/silent/src/com/netscape/pkisilent/common/UserEnroll.java
new file mode 100644
index 000000000..c55088bc6
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/common/UserEnroll.java
@@ -0,0 +1,536 @@
+package com.netscape.pkisilent.common;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import org.mozilla.jss.ssl.SSLSocket;
+
+/**
+ * CMS Test framework .
+ * Submits Legacy Manual User Enrollment request from EESSL port. Parses the response from server and return RequestID.
+ * <P>
+ */
+
+public class UserEnroll extends TestClient {
+
+ private int i;
+ private String requestorName, requestorEmail, requestorPhone, requestorComments, requestId, certType, ssl_client;
+ private int port;
+ private long elapsedTime;
+
+ // Constructor
+ public UserEnroll() {
+ }
+
+ /**
+ * Constructor . Takes the parameter hostname and EESSLport
+ * <p>
+ */
+
+ public UserEnroll(String h, String p) {
+ host = h;
+ ports = p;
+ }
+
+ /**
+ * Constructor . Takes the parameter for Properties file name
+ * <p>
+ *
+ * @param propfilename name of the parameter file
+ */
+
+ public UserEnroll(String pfile) {
+ propfileName = pfile;
+ }
+
+ /**
+ * Constructor . Takes the parameter for hostname, EESSLportnumber, subjectdn, E, CN,UID,OU,O,
+ * CertdbDirecrory(fullpath) , certdbPassword, keysize, keytype, requestorName,requestorEmail and Certtype.
+ * valid values for Certtype - "ca","ra","ocsp"
+ * <p>
+ *
+ * @param propfilename name of the parameter file
+ */
+
+ public UserEnroll(String h, String p, String dn, String e, String cn, String uid, String ou, String o, String cd,
+ String tpwd, String sslcl, String ksize, String keyty, String reqname, String reqemail, String ctype) {
+
+ host = h;
+ ports = p;
+ DN = dn;
+ E = e;
+ CN = cn;
+ UID = uid;
+ OU = ou;
+ O = o;
+ C = "US";
+ cdir = cd;
+ tokenpwd = tpwd;
+ ssl_client = sslcl;
+ keysize = ksize;
+ keytype = keyty;
+ requestorName = reqname;
+ requestorPhone = "650";
+ requestorEmail = "lg";
+ requestorComments = "load Test";
+ certnickname = "cn=test";
+ keytype = "RSA";
+ keysize = "1024";
+ certType = ctype;
+ if (certType.equals("caSigningCert")) {
+ certType = "ca";
+ }
+ if (certType.equals("raSigningCert")) {
+ certType = "ra";
+ }
+ if (certType.equals("ocspSigningCert")) {
+ certType = "ocsp";
+ }
+ }
+
+ /**
+ * Set Certificate Request information. Takes parameters - subjectdn,E,CN,UID,OU,O
+ */
+
+ public void setUserInfo(String dn, String e, String cn, String uid, String ou, String o) {
+ DN = dn;
+ E = e;
+ CN = cn;
+ UID = uid;
+ OU = ou;
+ O = o;
+ requestorName = "test";
+ requestorPhone = "650";
+ requestorEmail = "lg";
+ requestorComments = "Test";
+ certnickname = "cn=test";
+
+ }
+
+ public void setUserInfo(String dn, String e, String cn, String uid, String ou, String o, String nickname) {
+ DN = dn;
+ E = e;
+ CN = cn;
+ UID = uid;
+ OU = ou;
+ O = o;
+ requestorName = "test";
+ requestorPhone = "650";
+ requestorEmail = "lg";
+ requestorComments = "Test";
+ certnickname = nickname;
+
+ }
+
+ /**
+ * Set Certificat Type for which you want to submit a request . Valid values - "ca"/"ra"/"ocsp"
+ */
+ public void setCertType(String ct) {
+ certType = ct;
+ }
+
+ public boolean enroll_load() throws UnsupportedEncodingException {
+ buildquery();
+ setStatusString("");
+ return (Send());
+ }
+
+ private boolean pkcs10() {
+
+ System.out.println(" In pkcs10 Keysize , key type " + keysize + keytype);
+ // ComCrypto cCrypt = new ComCrypto(cdir,tokenpwd,certnickname,keysize,keytype);
+ cCrypt.setCertDir(cdir);
+ cCrypt.setCertnickname(adminCertName);
+ cCrypt.setKeySize(keysize);
+ cCrypt.setKeyType(keytype);
+ cCrypt.setTokenPWD(tokenpwd);
+ cCrypt.setDebug(true);
+ if (pkcs10request != null) {
+ cCrypt.setGenerateRequest(false);
+ cCrypt.loginDB();
+ } else {
+ cCrypt.setGenerateRequest(true);
+ if (!cCrypt.generateRequest()) {
+ System.out.println("Request could not be generated ");
+ return false;
+ }
+ pkcs10request = cCrypt.getPkcs10Request();
+ }
+
+ try {
+ System.out.println("Debug: building query ");
+ buildquery();
+ if (debug) {
+ System.out.println(query);
+ }
+ setStatusString("");
+ return (Send());
+ } catch (Exception e) {
+ System.err.println("some exception:" + e);
+ }
+
+ return (false);
+
+ }
+
+ // Private methods
+
+ private void setElapsedTime(long dif) {
+ elapsedTime = dif;
+ }
+
+ private long calculateElapsedTime(GregorianCalendar b, GregorianCalendar e) {
+
+ Date d1 = b.getTime();
+ Date d2 = e.getTime();
+ long l1 = d1.getTime();
+ long l2 = d2.getTime();
+ long difference = l2 - l1;
+
+ return difference;
+
+ }
+
+ private boolean Send() {
+ boolean st = false;
+
+ try {
+
+ if (debug) {
+ System.out.println("Step 3 : Socket initialize");
+ }
+
+ Integer x = new Integer(ports);
+
+ port = x.intValue();
+
+ GregorianCalendar begin = new GregorianCalendar();
+
+ // SSLSocket socket = new SSLSocket(host,port);
+ SSLSocket socket = new SSLSocket(host, port, null, 0, this, null);
+
+ socket.setUseClientMode(true);
+ OutputStream rawos = socket.getOutputStream();
+ BufferedOutputStream os = new BufferedOutputStream(rawos);
+ PrintStream ps = new PrintStream(os);
+
+ ps.println("POST /enrollment HTTP/1.0");
+ ps.println("Connection: Keep-Alive");
+ ps.println("Content-type: application/x-www-form-urlencoded");
+ ps.println("Content-length: " + query.length());
+ ps.println("");
+ ps.println(query);
+ ps.println("\r");
+ ps.flush();
+ os.flush();
+ BufferedReader stdin = new BufferedReader(
+ new InputStreamReader(socket.getInputStream()));
+
+ if (debug) {
+ System.out.println("Step 4: Received the page");
+ }
+ st = false;
+ String line;
+
+ while ((line = stdin.readLine()) != null) {
+ if (debug) {
+ System.out.println(line);
+ }
+ if (line.indexOf(STATUS) != -1) {
+ st = true;
+ }
+ if (line.indexOf("fixed.requestId = ") != -1) {
+ requestId = line.substring("fixed.requestId = ".length() + 1,
+ line.indexOf(";") - 1);
+ }
+
+ if (getError(line)) {
+ st = false;
+ }
+
+ }
+ stdin.close();
+ socket.close();
+ os.close();
+ rawos.close();
+ ps.close();
+ os = null;
+ rawos = null;
+ stdin = null;
+ ps = null;
+ line = null;
+ GregorianCalendar end = new GregorianCalendar();
+ long diff = calculateElapsedTime(begin, end);
+
+ setElapsedTime(diff);
+
+ } catch (Exception e) {
+ System.err.println("some exception: in Send routine" + e);
+ return false;
+ }
+
+ return st;
+
+ }
+
+ private void buildquery() throws UnsupportedEncodingException {
+
+ StringBuffer queryStrBuf = new StringBuffer();
+
+ if (certType.equals("client")) {
+ queryStrBuf.append("certType=");
+ queryStrBuf.append(certType);
+ queryStrBuf.append("&Send=submit");
+
+ queryStrBuf.append("&key_encipherment=true");
+
+ queryStrBuf.append("&digital_signature=true");
+
+ queryStrBuf.append("&requestFormat=keygen");
+
+ queryStrBuf.append("&cryptprovider=1");
+ if (ssl_client.equals("true")) {
+ queryStrBuf.append("&ssl_client=true");
+ } else {
+ queryStrBuf.append("&ssl_server=true");
+ }
+
+ queryStrBuf.append("&non_repudiation=true");
+
+ if (requestorName.length() > 0) {
+ queryStrBuf.append("&csrRequestorName=");
+ }
+ queryStrBuf.append(URLEncoder.encode(requestorName, "UTF-8"));
+ if (requestorEmail.length() > 0) {
+ queryStrBuf.append("&csrRequestorEmail=");
+ queryStrBuf.append(URLEncoder.encode(requestorEmail, "UTF-8"));
+ queryStrBuf.append("&email=true");
+
+ } else {
+ queryStrBuf.append("&email=false");
+ }
+
+ if (requestorPhone.length() > 0) {
+ queryStrBuf.append("&csrRequestorPhone=");
+ queryStrBuf.append(URLEncoder.encode(requestorPhone, "UTF-8"));
+ }
+ if (requestorComments.length() > 0) {
+ queryStrBuf.append("&csrRequestorComments=");
+ queryStrBuf.append(URLEncoder.encode(requestorComments, "UTF-8"));
+ }
+ System.out.println("buidlquery client E ");
+ if (E.length() > 0) {
+ queryStrBuf.append("&E=");
+ queryStrBuf.append(E);
+ }
+ if (CN.length() > 0) {
+ queryStrBuf.append("&CN=");
+ queryStrBuf.append(CN);
+ }
+
+ if (UID.length() > 0) {
+ queryStrBuf.append("&UID=");
+ queryStrBuf.append(UID);
+ }
+ if (OU.length() > 0) {
+ queryStrBuf.append("&OU=");
+ queryStrBuf.append(OU);
+ }
+ // if(O.length() > 0) { queryStrBuf.append("&O=");queryStrBuf.append(O);}
+ // if(C.length() >0) { queryStrBuf.append("&C=");queryStrBuf.append(C);}
+ System.out.println("buidlquery client dn ");
+ queryStrBuf.append("&subject=");
+ queryStrBuf.append(URLEncoder.encode(DN, "UTF-8"));
+ }
+
+ if (certType.equals("ra")) {
+ queryStrBuf.append("certType=" + certType);
+ queryStrBuf.append("&digital_signature=true");
+ queryStrBuf.append("&non_repudiation=true");
+ queryStrBuf.append("&ssl_client=true");
+ }
+
+ if (certType.equals("server")) {
+ queryStrBuf.append("certType=" + certType);
+ queryStrBuf.append("&digital_signature=true");
+ queryStrBuf.append("&non_repudiation=true");
+ queryStrBuf.append("&ssl_server=true");
+ queryStrBuf.append("&key_encipherment=true");
+ queryStrBuf.append("&data_encipherment=true");
+
+ }
+
+ if (certType.equals("ocsp")) {
+ queryStrBuf.append("certType=ocspResponder");
+ queryStrBuf.append("&digital_signature=true");
+ queryStrBuf.append("&non_repudiation=true");
+ queryStrBuf.append("&ssl_client=true");
+ }
+
+ if (certType.equals("ca")) {
+ queryStrBuf.append("certType=" + certType);
+ queryStrBuf.append("&digital_signature=true");
+ queryStrBuf.append("&non_repudiation=true");
+ queryStrBuf.append("&ssl_client=true");
+ queryStrBuf.append("&object_signing_ca=true");
+ queryStrBuf.append("&crl_sign=true");
+ queryStrBuf.append("&ssl_ca=true");
+ queryStrBuf.append("&key_certsign=true");
+ queryStrBuf.append("&email_ca=true");
+
+ }
+
+ queryStrBuf.append("&pkcs10Request=");
+ queryStrBuf.append(URLEncoder.encode(pkcs10request, "UTF-8"));
+ System.out.println("before converting bug to string ");
+ query = queryStrBuf.toString();
+
+ System.out.println(query);
+ queryStrBuf = null;
+ }
+
+ public int getRequestId() {
+ Integer m = new Integer(requestId);
+
+ return m.intValue();
+
+ }
+
+ /**
+ * Submit enrollment request
+ */
+
+ public boolean clientCertEnroll() {
+ certType = "client";
+ ssl_client = "true";
+ debug = true;
+ return (pkcs10());
+ }
+
+ public boolean Enroll() {
+ debug = true;
+ return (pkcs10());
+ }
+
+ /**
+ * Read the properties file
+ **/
+
+ public boolean readProperties() {
+
+ // Read the properties file and assign values to variables .
+ try {
+ getProperties(propfileName);
+ } catch (Exception e) {
+ System.out.println(
+ "exception reading Properties File " + e.getMessage());
+ return false;
+ }
+
+ host = props.getProperty("enroll.host");
+ ports = props.getProperty("enroll.port");
+ DN = props.getProperty("enroll.DN");
+ requestorName = props.getProperty("enroll.name");
+ requestorEmail = props.getProperty("enroll.email");
+ requestorPhone = props.getProperty("enroll.phone");
+ requestorComments = props.getProperty("enroll.comments");
+ E = props.getProperty("enroll.E");
+ CN = props.getProperty("enroll.CN");
+ UID = props.getProperty("enroll.UID");
+ OU = props.getProperty("enroll.OU");
+ O = props.getProperty("enroll.O");
+ C = props.getProperty("enroll.C");
+ cdir = props.getProperty("enroll.certdir");
+ tokenpwd = props.getProperty("enroll.certtokenpwd");
+ certnickname = props.getProperty("enroll.nickname");
+ keysize = props.getProperty("enroll.keysize");
+ keytype = props.getProperty("enroll.keytype");
+ certType = props.getProperty("enroll.certtype");
+ if (certType == null) {
+ certType = "client";
+ }
+ if (certType.equals("raSigningCert")) {
+ certType = "ra";
+ }
+ if (certType.equals("ocspSigningCert")) {
+ certType = "ocsp";
+ }
+ pkcs10request = props.getProperty("enroll.pkcs10");
+ ssl_client = props.getProperty("enroll.sslclient");
+ if (ssl_client == null) {
+ ssl_client = "true";
+ }
+
+ String de = props.getProperty("enroll.debug");
+
+ if (de == null) {
+ debug = false;
+ } else if (de.equals("true")) {
+ debug = true;
+ } else {
+ debug = false;
+ }
+
+ // Enroll using a pkscks10 request
+ return (pkcs10());
+ }
+
+ public static void main(String args[]) {
+ // Exit Status - (0) for error/Fail
+ // - requestId Pass
+
+ UserEnroll e = new UserEnroll("jupiter2", "1027",
+ "E=test,cn=test,uid=test", "test", "test", "test", "t1", "t",
+ "/u/lgopal/work/tetCMS/ns/tetframework/testcases/CMS/6.0/acceptanceJava/data/certdb",
+ "secret12", "true", "1024", "RSA", "rn", "re", "client");
+
+ e.clientCertEnroll();
+
+ /* if ( args.length < 1)
+ {
+ System.out.println("Usage : propertiesfile");
+ System.exit(0);
+ }
+
+
+ UserEnroll t = new UserEnroll(args[0]);
+ st=t.enroll();
+ if (st){
+ System.out.println("User Enrolled successfully . RequestId is "+t.getrequestId());
+ System.exit(t.getRequestId());
+ }
+ else{
+
+ System.out.println("Error: " + t.getErrorDetail());
+ System.exit(0);
+ }
+ */
+ }// end of function main
+
+} // end of class
+
diff --git a/base/silent/src/com/netscape/pkisilent/common/Utilities.java b/base/silent/src/com/netscape/pkisilent/common/Utilities.java
new file mode 100644
index 000000000..3e5d6fb4c
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/common/Utilities.java
@@ -0,0 +1,347 @@
+package com.netscape.pkisilent.common;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.DataInputStream;
+import java.io.FileInputStream;
+
+import netscape.security.x509.CertificateSerialNumber;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.RDN;
+import netscape.security.x509.SerialNumber;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.cmsutil.util.Utils;
+
+public class Utilities {
+
+ public Utilities() {// Do nothing
+ }
+
+ public String cleanupQuotes(String token) {
+
+ StringBuffer buf = new StringBuffer();
+ int length = token.length();
+ int curIndex = 0;
+
+ if (token.startsWith("\"") && token.endsWith("\"")) {
+ curIndex = 1;
+ length--;
+ }
+
+ boolean oneQuoteFound = false;
+ boolean twoQuotesFound = false;
+
+ while (curIndex < length) {
+ char curChar = token.charAt(curIndex);
+
+ if (curChar == '"') {
+ twoQuotesFound = (oneQuoteFound) ? true : false;
+ oneQuoteFound = true;
+ } else {
+ oneQuoteFound = false;
+ twoQuotesFound = false;
+ }
+
+ if (twoQuotesFound) {
+ twoQuotesFound = false;
+ oneQuoteFound = false;
+ curIndex++;
+ continue;
+ }
+
+ buf.append(curChar);
+ curIndex++;
+ }
+
+ return buf.toString();
+ }
+
+ public String removechar(String token) {
+
+ StringBuffer buf = new StringBuffer();
+ int end = token.length();
+ int begin = 0;
+
+ if (token.endsWith(";")) {
+ end--;
+ }
+
+ while (begin < end) {
+ char curChar = token.charAt(begin);
+
+ buf.append(curChar);
+ begin++;
+ }
+ return buf.toString();
+
+ }
+
+ public String parse_httpresponse(String line) {
+ // look for name=value pair
+ // remove trailing white spaces
+ // remove trailing ;
+ // remove double quotes
+
+ String temp = line.substring(line.indexOf("=") + 1);
+
+ return cleanupQuotes(removechar(temp.trim()));
+
+ }
+
+ public String remove_newline(String s) {
+ if (s == null) {
+ return null;
+ }
+
+ String val = "";
+
+ for (int i = 0; i < s.length(); i++) {
+ if ((s.charAt(i) == '\\') && (s.charAt(i + 1) == 'n')) {
+ i++;
+ continue;
+ } else if ((s.charAt(i) == '\\') && (s.charAt(i + 1) == 'r')) {
+ i++;
+ continue;
+ } else if (s.charAt(i) == '"') {
+ continue;
+ }
+ val += s.charAt(i);
+ }
+ return val;
+
+ }
+
+ public String normalize(String s) {
+
+ if (s == null) {
+ return null;
+ }
+
+ String val = "";
+
+ for (int i = 0; i < s.length(); i++) {
+ if ((s.charAt(i) == '\\') && (s.charAt(i + 1) == 'n')) {
+ val += '\n';
+ i++;
+ continue;
+ } else if ((s.charAt(i) == '\\') && (s.charAt(i + 1) == 'r')) {
+ i++;
+ continue;
+ } else if (s.charAt(i) == '"') {
+ continue;
+ }
+ val += s.charAt(i);
+ }
+ return val;
+ }
+
+ /*
+ * format of the file should be like this:
+ * -----BEGIN CERTIFICATE-----
+ * base64 encoded certificate
+ * -----END CERTIFICATE-----
+ */
+ public String getcertfromfile(String filename) {
+ StringBuffer tempBuffer = new StringBuffer();
+
+ try {
+ FileInputStream fis = new FileInputStream(filename);
+ DataInputStream in = new DataInputStream(fis);
+
+ while (in.available() != 0) {
+ String temp = in.readLine();
+
+ if (temp.equalsIgnoreCase("-----BEGIN CERTIFICATE-----")
+ || temp.equalsIgnoreCase("-----END CERTIFICATE-----")) {
+ continue;
+ }
+ tempBuffer.append(temp);
+ }
+
+ return tempBuffer.toString();
+ } catch (Exception e) {
+ System.out.println("ERROR: getcertfromfile" + e.toString());
+ return null;
+ }
+
+ }
+
+ public String getcertfromfile_withheaders(String filename) {
+ StringBuffer tempBuffer = new StringBuffer();
+
+ try {
+ FileInputStream fis = new FileInputStream(filename);
+ DataInputStream in = new DataInputStream(fis);
+
+ while (in.available() != 0) {
+ String temp = in.readLine();
+
+ tempBuffer.append(temp);
+ }
+ return tempBuffer.toString();
+ } catch (Exception e) {
+ System.out.println(
+ "ERROR: getcertfromfile_withheaders" + e.toString());
+ return null;
+ }
+ }
+
+ /*
+ * format of the file should be like this:
+ * -----BEGIN CERTIFICATE REVOCATION LIST-----
+ * base64 encoded CRL
+ * -----END CERTIFICATE REVOCATION LIST-----
+ */
+ public String getcrlfromfile(String filename) {
+ StringBuffer tempBuffer = new StringBuffer();
+
+ try {
+ FileInputStream fis = new FileInputStream(filename);
+ DataInputStream in = new DataInputStream(fis);
+
+ while (in.available() != 0) {
+ String temp = in.readLine();
+
+ tempBuffer.append(temp);
+ }
+
+ return tempBuffer.toString();
+ } catch (Exception e) {
+ System.out.println("ERROR: getcrlfromfile" + e.toString());
+ return null;
+ }
+
+ }
+
+ /*
+ * format of the file should be like this:
+ * -----BEGIN CERTIFICATE-----
+ * base64 encoded certificate
+ * -----END CERTIFICATE-----
+ */
+ public String getcafromfile(String filename) {
+ StringBuffer tempBuffer = new StringBuffer();
+
+ try {
+ FileInputStream fis = new FileInputStream(filename);
+ DataInputStream in = new DataInputStream(fis);
+
+ while (in.available() != 0) {
+ String temp = in.readLine();
+
+ tempBuffer.append(temp);
+ }
+
+ return tempBuffer.toString();
+ } catch (Exception e) {
+ System.out.println("ERROR: getcafromfile" + e.toString());
+ return null;
+ }
+
+ }
+
+ /*
+ * function for RFC 2254. converts a x509 certificate given as
+ * a binary array[] to a Ldap filter string
+ */
+ public static String escapeBinaryData(byte data[]) {
+ String result = "";
+
+ for (int i = 0; i < data.length; i++) {
+ String s = Integer.toHexString((int) (0xff & data[i]));
+
+ if (s.length() == 1) {
+ s = "0" + s;
+ }
+ result = result + "\\" + s;
+ }
+
+ System.out.println("LDAP_FILTER=" + result);
+ return result;
+ }
+
+ /*
+ * function to decode base64 encoded certificate
+ */
+ public CertificateRecord decode_cert(String cert) {
+
+ String head = "-----BEGIN CERTIFICATE-----";
+ String tail = "-----END CERTIFICATE-----";
+
+ CertificateRecord cr = new CertificateRecord();
+
+ int head_pos = cert.indexOf(head);
+ int tail_pos = cert.indexOf(tail);
+
+ // String not found
+ if (head_pos == -1 || tail_pos == -1) {
+ return null;
+ }
+
+ String temp = cert.substring(head_pos + head.length(), tail_pos);
+
+ temp = temp.replaceAll("\\r", "");
+ temp = temp.replaceAll("\\n", "");
+
+ try {
+ // BASE64Decoder base64 = new BASE64Decoder();
+ // byte decodedBASE64Cert[] = base64.decodeBuffer(temp);
+ byte decodedBASE64Cert[] = Utils.base64decode(temp);
+ X509CertImpl x509_cert = new X509CertImpl(decodedBASE64Cert);
+ X509CertInfo certinfo = (X509CertInfo) x509_cert.get("x509.INFO");
+
+ /* Get Serial Number */
+ CertificateSerialNumber csn = (CertificateSerialNumber)
+ certinfo.get(X509CertInfo.SERIAL_NUMBER);
+ SerialNumber sn = (SerialNumber) csn.get("NUMBER");
+
+ // just adding serialnumber for add.
+ // we can add mode here like subject name, extensions,issuer to this record.
+ cr.serialNumber = sn.getNumber().toString().trim();
+
+ /* Get Subject Name */
+
+ CertificateSubjectName csn1 = (CertificateSubjectName)
+ certinfo.get(X509CertInfo.SUBJECT);
+
+ X500Name dname = (X500Name) csn1.get(CertificateSubjectName.DN_NAME);
+
+ String pp = "";
+ RDN[] rdns = dname.getNames();
+
+ for (int i = rdns.length - 1; i >= 0; i--) {
+ pp = pp + rdns[i] + "\n";
+ }
+
+ cr.subject = pp;
+
+ } catch (Exception e) {
+ System.out.println("ERROR: Exception when decoding certificate=" + e);
+ e.printStackTrace();
+ return null;
+ }
+
+ return cr;
+
+ }
+
+}; // end class
diff --git a/base/silent/src/com/netscape/pkisilent/common/checkRequest.java b/base/silent/src/com/netscape/pkisilent/common/checkRequest.java
new file mode 100644
index 000000000..c4599ffde
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/common/checkRequest.java
@@ -0,0 +1,617 @@
+package com.netscape.pkisilent.common;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import org.mozilla.jss.ssl.SSLSocket;
+
+/**
+ * CMS Test framework .
+ * Submits a checkRequestStatus request to the server. parses the response from server and can import cert to the
+ * specified client database.
+ * <P>
+ */
+
+public class checkRequest extends TestClient {
+
+ private int i;
+ private String certfile, importcert = "false", certnickname, serialNumber, ldapformat;
+
+ private String requestId;
+ private String reqStatus = "false";
+ private String pkcsCert, baseCert, ACTION_STRING, issuer, subject, AUTH = "ca";
+ private int port;
+ private boolean impStatus = false;
+ private int type = 1;
+
+ private long elapsedTime;
+
+ private String host;
+ private String ports;
+ private String tokenpwd;
+ private String cdir;
+
+ // public methods
+
+ /**
+ * Constructor . Takes the parameter for Properties file name
+ * <p>
+ *
+ * @param propfilename name of the parameter file
+ */
+
+ public checkRequest(String pfile) {
+ propfileName = pfile;
+ }
+
+ /**
+ * Constructor . Takes the parameter for hostname and EESSLportnumber
+ * <p>
+ */
+
+ public checkRequest(String h, String p) {
+ host = h;
+ ports = p;
+ };
+
+ /**
+ * Constructor . Takes the parameter for hostname , EESSLportnumber , Requestnumber and ImportCert ( true/false)
+ * <p>
+ */
+
+ public checkRequest(String h, String p, String snum, String impc) {
+ host = h;
+ ports = p;
+ requestId = snum;
+ importcert = impc;
+ }
+
+ /**
+ * Constructor . Takes the parameter for hostname , EESSLportnumber , certdbdir, certdbpassword, Requestnumber
+ * ,certnickname and ImportCert ( true/false)
+ * <p>
+ */
+
+ public checkRequest(String hs, String pt, String certdir, String certtokenpwd, String seqnum, String nickname,
+ String impc) {
+ host = hs;
+ ports = pt;
+ cdir = certdir;
+ tokenpwd = certtokenpwd;
+ requestId = seqnum;
+ if (impc == null) {
+ importcert = "false";
+ } else {
+ importcert = impc;
+ }
+ certnickname = nickname;
+
+ }
+
+ public void setDebug(boolean t) {
+ debug = t;
+ }
+
+ public void setreqId(String seqnum) {
+ requestId = seqnum;
+ }
+
+ public void setCertNickname(String cname) {
+ certnickname = cname;
+ }
+
+ /**
+ * takes values - true/false
+ **/
+ public void setImportCert(String impc) {
+ importcert = impc;
+ }
+
+ public String getpkcs7ChainCert() {
+ return pkcsCert;
+ }
+
+ /**
+ * returns Certificate
+ **/
+
+ public String getCert() {
+ return cCrypt.normalize(baseCert);
+ }
+
+ /**
+ * returns Request status - "complete","pending"
+ **/
+
+ public String getRequestStatus() {
+ return reqStatus;
+ }
+
+ /**
+ * returns the hex serial number of the certificate
+ **/
+
+ public String getSerialNumberHex() {
+ return serialNumber;
+ }
+
+ /**
+ * returns the serial number as interger
+ **/
+
+ public int getSerialNumber() {
+ if (serialNumber != null) {
+ Integer y = new Integer(Integer.parseInt(serialNumber, 16));
+
+ return y.intValue();
+ }
+ return 0;
+ }
+
+ /**
+ * Submits a checkRequestStatus request to the server
+ **/
+
+ public boolean checkRequestStatus() {
+
+ // Login to dB and genertae request
+ cCrypt.setCertDir(cdir);
+ cCrypt.setCertnickname(certnickname);
+ cCrypt.setKeySize(keysize);
+ cCrypt.setKeyType(keytype);
+ cCrypt.setTokenPWD(tokenpwd);
+ cCrypt.setDebug(debug);
+
+ if (!cCrypt.loginDB()) {
+ System.out.println("Error : Login certdb failed ");
+ System.err.println("FAIL : Login certdb failed ");
+ return false;
+ }
+
+ try {
+
+ type = 1;
+ buildquery();
+ if (debug) {
+ System.out.println(query);
+ }
+ setStatusString("Congratulations, your certificate has been issued.");
+ if (Send()) {
+ if (debug) {
+ System.out.println("Request Status :" + reqStatus);
+ }
+ if (reqStatus.equals("complete")) {
+ type = 2;
+ buildquery();
+ if (debug) {
+ System.out.println(query);
+ }
+ if (Send()) {
+ return true;
+ }
+ } else {
+ return true;
+ }
+
+ }
+ if (debug) {
+ System.out.println("Request Status :" + reqStatus);
+ }
+
+ System.err.println("FAIL: reached end of checkRequestStatus()");
+
+ return false;
+ } catch (Exception e) {
+ System.err.println("some exception:" + e);
+ }
+
+ return false;
+ }
+
+ // Private functions
+
+ private void setElapsedTime(long dif) {
+ elapsedTime = dif;
+ }
+
+ private long calculateElapsedTime(GregorianCalendar b, GregorianCalendar e) {
+
+ Date d1 = b.getTime();
+ Date d2 = e.getTime();
+ long l1 = d1.getTime();
+ long l2 = d2.getTime();
+ long difference = l2 - l1;
+
+ return difference;
+
+ }
+
+ private boolean writeCert2File() {
+ if (serialNumber != null) {
+
+ try {
+ FileOutputStream fos = new FileOutputStream(certfile);
+
+ if (ldapformat.equals("true")) {
+ String tmp = "description: 2;"
+ + Integer.parseInt(serialNumber, 16) + ";" + issuer
+ + ";" + subject + "\n";
+
+ fos.write(tmp.getBytes());
+ tmp = cCrypt.normalizeForLDAP(getCert());
+ if (debug) {
+ System.out.println(tmp);
+ }
+ fos.write(("usercertificate:: ").getBytes());
+ fos.write(tmp.getBytes());
+ fos.close();
+ } else {
+ String tmp = cCrypt.normalize(getCert());
+
+ if (debug) {
+ System.out.println(tmp);
+ }
+ fos.write(tmp.getBytes());
+ fos.close();
+
+ }
+
+ } catch (Exception e) {
+ System.out.println(
+ "exception in writeCert2File: " + e.getMessage());
+ return false;
+ }
+
+ }
+
+ return true;
+ }
+
+ private boolean importCert(String certpack) {
+
+ if (importcert.equals("false")) {
+ return true;
+ }
+
+ try {
+ if (certpack == null) {
+ return false;
+ }
+
+ String s = cCrypt.normalize(certpack);
+
+ if (AUTH.equals("ca")) {
+ String tmp = "-----BEGIN CERTIFICATE-----\n" + s + "\n"
+ + "-----END CERTIFICATE-----";
+
+ if (debug) {
+ System.out.println(
+ "importing cert" + tmp + "certnick" + certnickname);
+ }
+ s = tmp;
+ }
+
+ if (cCrypt.importCert(s, certnickname)) {
+ System.out.println("successfully imported cert");
+ return true;
+ }
+
+ return false;
+
+ } catch (Exception e) {
+ System.out.println(
+ "exception importing cert crequest" + e.getMessage());
+ return false;
+ }
+
+ }
+
+ private boolean RetrieveRequestDetail(String line) {
+ String stat = "header.status = ";
+ boolean st = true;
+
+ if (debug) {
+ System.out.println(line);
+ }
+
+ if (line.indexOf(stat) != -1) {
+ String tm = line.substring(stat.length() + 1,
+ line.indexOf(";", 10) - 1);
+
+ reqStatus = tm;
+ }
+ if (line.indexOf("header.pkcs7ChainBase64 = ") != -1) {
+ // if status is complete retrieve cert
+ pkcsCert = line.substring("header.pkcs7ChainBase64 = ".length() + 1,
+ line.indexOf(";", 10) - 1);
+ }
+ if (line.indexOf("record.serialNumber=") != -1) {
+ serialNumber = line.substring("record.serialNumber=".length() + 1,
+ line.indexOf(";", 1) - 1);
+ }
+ if (line.indexOf("header.authority =") == 0) {
+ AUTH = line.substring("header.authority =".length() + 2,
+ line.indexOf(";", 1) - 1);
+ }
+
+ if (getError(line)) {
+ st = false;
+ }
+
+ return st;
+
+ }
+
+ private boolean RetrieveCertDetails(String line) {
+ if (debug) {
+ System.out.println(line);
+ }
+
+ boolean st = true;
+
+ String retriveStr[] = {
+ "record.base64Cert=", "record.certPrettyPrint=",
+ "header.certChainBase64 = ", "header.certPrettyPrint = " };
+ String baseCertStr, certPrettyprintStr;
+
+ if (AUTH.equals("ra")) {
+ baseCertStr = retriveStr[0];
+ certPrettyprintStr = retriveStr[1];
+ } else {
+ baseCertStr = retriveStr[2];
+ certPrettyprintStr = retriveStr[3];
+ }
+
+ if (line.indexOf(baseCertStr) != -1) {
+
+ // if status is complete retrieve cert
+ baseCert = line.substring(baseCertStr.length() + 1,
+ line.indexOf(";", 10) - 1);
+ if (importcert.equals("true")) {
+ if (importCert(baseCert)) {
+ st = true;
+ }
+ } else {
+ st = true;
+ }
+ }
+
+ if (line.indexOf(certPrettyprintStr) != -1) {
+
+ System.out.println("Found certPrettyPrint");
+ int ret = line.indexOf("Issuer: ");
+
+ issuer = line.substring(("Issuer: ").length() + ret,
+ line.indexOf("Validi", ret) - 14);
+ ret = line.indexOf("Subject:");
+ subject = line.substring(("Subject: ").length() + ret,
+ line.indexOf("Subject Public", ret) - 14);
+
+ System.out.println(" HEADER : " + issuer);
+
+ }
+
+ // System.out.println("Debug :get Error detail " + line);
+ if (getError(line)) {
+ st = false;
+ }
+
+ return st;
+
+ }
+
+ private synchronized boolean Send() {
+ boolean st = false;
+
+ try {
+ if (debug) {
+ System.out.println("Step 3 : Socket initialize");
+ }
+
+ Integer x = new Integer(ports);
+
+ port = x.intValue();
+
+ GregorianCalendar begin = new GregorianCalendar();
+
+ impStatus = false;
+
+ // SSLSocket socket = new SSLSocket(host,port);
+ SSLSocket socket = new SSLSocket(host, port, null, 0, this, null);
+
+ socket.setUseClientMode(true);
+
+ OutputStream rawos = socket.getOutputStream();
+ BufferedOutputStream os = new BufferedOutputStream(rawos);
+ PrintStream ps = new PrintStream(os);
+
+ ps.println("POST " + ACTION_STRING + " HTTP/1.0");
+ ps.println("Connection: Keep-Alive");
+ ps.println("Content-type: application/x-www-form-urlencoded");
+ ps.println("Content-length: " + query.length());
+ ps.println("");
+ ps.println(query);
+ ps.println("\r");
+ ps.flush();
+ os.flush();
+ BufferedReader stdin = new BufferedReader(
+ new InputStreamReader(socket.getInputStream()));
+
+ if (debug) {
+ System.out.println("Step 4: Received the page");
+ }
+ st = false;
+ String line;
+
+ while ((line = stdin.readLine()) != null) {
+ switch (type) {
+ case 1:
+ RetrieveRequestDetail(line);
+ st = true;
+ break;
+
+ case 2:
+ st = RetrieveCertDetails(line);
+ break;
+
+ default:
+ System.out.println("invalid format");
+
+ }
+
+ }
+ stdin.close();
+ socket.close();
+ os.close();
+ rawos.close();
+ ps.close();
+ os = null;
+ rawos = null;
+ stdin = null;
+ ps = null;
+ line = null;
+
+ GregorianCalendar end = new GregorianCalendar();
+ long diff = calculateElapsedTime(begin, end);
+
+ setElapsedTime(diff);
+
+ } catch (Exception e) {
+ System.err.println("some exception: in Send routine" + e);
+ return false;
+ }
+ if ((certfile != null) && (type == 2)) {
+ st = writeCert2File();
+ }
+
+ if (debug) {
+ System.out.println(serialNumber);
+ }
+
+ return st;
+
+ }
+
+ private void buildquery() {
+
+ StringBuffer queryStrBuf = new StringBuffer();
+
+ if (type == 1) {
+ ACTION_STRING = "/checkRequest";
+ queryStrBuf.append("requestId=");
+ queryStrBuf.append(requestId);
+ queryStrBuf.append("&importCert=true");
+ }
+
+ if (type == 2) {
+ ACTION_STRING = "/" + AUTH + "/displayBySerial";
+ if (AUTH.equals("ra")) {
+ ACTION_STRING = "/displayCertFromRequest";
+ queryStrBuf.append("requestId=");
+ queryStrBuf.append(requestId);
+
+ } else {
+ ACTION_STRING = "/displayBySerial";
+ queryStrBuf.append("op=displayBySerial");
+ queryStrBuf.append("&serialNumber=0x");
+ queryStrBuf.append(serialNumber);
+ }
+ }
+
+ query = queryStrBuf.toString();
+
+ queryStrBuf = null;
+
+ }
+
+ private boolean readProperties() {
+
+ // Read the properties file and assign values to variables .
+ try {
+ getProperties(propfileName);
+ } catch (Exception e) {
+ System.out.println(
+ "exception reading Properties File " + e.getMessage());
+ return false;
+ }
+
+ host = props.getProperty("enroll.host");
+ ports = props.getProperty("enroll.port");
+ cdir = props.getProperty("enroll.certdir");
+ tokenpwd = props.getProperty("enroll.certtokenpwd");
+ requestId = props.getProperty("enroll.seqnum");
+ certfile = props.getProperty("enroll.certfile");
+ importcert = props.getProperty("enroll.importCert");
+ if (importcert == null) {
+ importcert = "false";
+ }
+ ldapformat = props.getProperty("enroll.ldapformat");
+ if (ldapformat == null) {
+ ldapformat = "true";
+ }
+ System.out.println(ldapformat);
+ certnickname = props.getProperty("enroll.nickname");
+ String de = props.getProperty("enroll.debug");
+
+ if (de == null) {
+ debug = false;
+ } else if (de.equals("true")) {
+ debug = true;
+ } else {
+ debug = false;
+ }
+
+ // Enroll using a pkscks10 request
+ return (checkRequestStatus());
+ }
+
+ public static void main(String args[]) {
+ // Exit Status - (0) for error/Fail
+ // - requestId Pass
+ boolean st;
+
+ if (args.length < 1) {
+ System.out.println("Usage : propertiesfile");
+ System.exit(0);
+ }
+
+ checkRequest t = new checkRequest(args[0]);
+
+ st = t.readProperties();
+ if (st) {
+ System.exit(t.getSerialNumber());
+ } else {
+
+ System.out.println("Request Status :" + t.getRequestStatus());
+ System.out.println("Error: " + t.getErrorDetail());
+
+ System.exit(0);
+ }
+ }// end of function main
+
+} // end of class
+
diff --git a/base/silent/src/com/netscape/pkisilent/http/CertSelection.java b/base/silent/src/com/netscape/pkisilent/http/CertSelection.java
new file mode 100644
index 000000000..ff541b6c6
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/http/CertSelection.java
@@ -0,0 +1,45 @@
+package com.netscape.pkisilent.http;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.util.Vector;
+
+import org.mozilla.jss.ssl.SSLClientCertificateSelectionCallback;
+
+public class CertSelection implements SSLClientCertificateSelectionCallback {
+
+ // make the select() call to use this client cert
+ public static String client_cert = null;
+
+ public void setClientCert(String nickname) {
+ client_cert = nickname;
+ }
+
+ public String select(@SuppressWarnings("rawtypes") Vector nicknames) {
+
+ // when this method is called by SSLSocket we get a vector
+ // of nicknames to select similar to the way the browser presents
+ // the list.
+
+ // We will just use the one thats set by setClientCert()
+
+ return client_cert;
+ }
+
+}; // end class
diff --git a/base/silent/src/com/netscape/pkisilent/http/HTMLDocument.java b/base/silent/src/com/netscape/pkisilent/http/HTMLDocument.java
new file mode 100644
index 000000000..e8de29081
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/http/HTMLDocument.java
@@ -0,0 +1,595 @@
+package com.netscape.pkisilent.http;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.LinkedHashSet;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class HTMLDocument {
+ // Indicates whether this HTML document has been parsed.
+ boolean parsed;
+
+ // A list of URLs of files that should be retrieved along with the main
+ // contents of the document. This may include any images contained in the
+ // document, and possibly any external stylesheets.
+ LinkedHashSet<String> associatedFiles;
+
+ // A list of URLs of frames that are contained in the document.
+ LinkedHashSet<String> documentFrames;
+
+ // A list of URLs of links that are contained in the document.
+ LinkedHashSet<String> documentLinks;
+
+ // A list of URLs of images that are contained in the document.
+ LinkedHashSet<String> documentImages;
+
+ // A regular expression pattern that can be used to extract a URI from an HREF
+ // tag.
+ Pattern hrefPattern;
+
+ // A regular expression pattern that can be used to extract a URI from a SRC
+ // tag.
+ Pattern srcPattern;
+
+ // The base URL for relative links in this document.
+ String baseURL;
+
+ // The URL that may be used to access this document.
+ String documentURL;
+
+ // The actual contents of the page.
+ String htmlData;
+
+ // The contents of the page converted to lowercase for easier matching.
+ String lowerData;
+
+ // The URL for this document with only protocol, host, and port (i.e., no
+ // file).
+ String protocolHostPort;
+
+ // A string buffer containing the contents of the page with tags removed.
+ StringBuffer textData;
+
+ // A set of private variables used for internal processing.
+ private boolean lastElementIsAssociatedFile;
+ private boolean lastElementIsChunk;
+ private boolean lastElementIsComment;
+ private boolean lastElementIsFrame;
+ private boolean lastElementIsImage;
+ private boolean lastElementIsLink;
+ private boolean lastElementIsText;
+ private int lastElementEndPos;
+ private int lastElementStartPos;
+ private String lastURL;
+
+ // constructor that helps to parse without url stuff
+ public HTMLDocument(String htmlData) {
+ this.documentURL = null;
+ this.htmlData = htmlData;
+ lowerData = htmlData.toLowerCase();
+ associatedFiles = null;
+ documentLinks = null;
+ documentImages = null;
+ textData = null;
+ parsed = false;
+
+ // Create the regex patterns that we will use for extracting URIs from tags.
+ hrefPattern = Pattern.compile(".*?[hH][rR][eE][fF][\\s=\\\"\\']+" +
+ "([^\\s\\\"\\'\\>]+).*", Pattern.DOTALL);
+ srcPattern = Pattern.compile(".*?[sS][rR][cC][\\s=\\\"\\']+" +
+ "([^\\s\\\"\\'\\>]+).*", Pattern.DOTALL);
+ }
+
+ /**
+ * Creates a new HTML document using the provided data.
+ *
+ * @param documentURL The URL for this document.
+ * @param htmlData The actual data contained in the HTML document.
+ */
+ public HTMLDocument(String documentURL, String htmlData)
+ throws MalformedURLException {
+ this.documentURL = documentURL;
+ this.htmlData = htmlData;
+ lowerData = htmlData.toLowerCase();
+ associatedFiles = null;
+ documentLinks = null;
+ documentImages = null;
+ textData = null;
+ parsed = false;
+
+ // Create the regex patterns that we will use for extracting URIs from tags.
+ hrefPattern = Pattern.compile(".*?[hH][rR][eE][fF][\\s=\\\"\\']+" +
+ "([^\\s\\\"\\'\\>]+).*", Pattern.DOTALL);
+ srcPattern = Pattern.compile(".*?[sS][rR][cC][\\s=\\\"\\']+" +
+ "([^\\s\\\"\\'\\>]+).*", Pattern.DOTALL);
+
+ URL url = new URL(documentURL);
+ String urlPath = url.getPath();
+ if ((urlPath == null) || (urlPath.length() == 0)) {
+ baseURL = documentURL;
+ protocolHostPort = documentURL;
+ } else if (urlPath.equals("/")) {
+ baseURL = documentURL;
+ protocolHostPort = documentURL.substring(0, documentURL.length() - 1);
+ } else if (urlPath.endsWith("/")) {
+ baseURL = documentURL;
+
+ int port = url.getPort();
+ if (port > 0) {
+ protocolHostPort = url.getProtocol() + "://" + url.getHost() + ":" +
+ port;
+ } else {
+ protocolHostPort = url.getProtocol() + "://" + url.getHost();
+ }
+ } else {
+ int port = url.getPort();
+ if (port > 0) {
+ protocolHostPort = url.getProtocol() + "://" + url.getHost() + ":" +
+ port;
+ } else {
+ protocolHostPort = url.getProtocol() + "://" + url.getHost();
+ }
+
+ File urlFile = new File(urlPath);
+ String parentDirectory = urlFile.getParent();
+ if ((parentDirectory == null) || (parentDirectory.length() == 0)) {
+ parentDirectory = "/";
+ } else if (!parentDirectory.startsWith("/")) {
+ parentDirectory = "/" + parentDirectory;
+ }
+
+ baseURL = protocolHostPort + parentDirectory;
+ }
+
+ if (!baseURL.endsWith("/")) {
+ baseURL = baseURL + "/";
+ }
+ }
+
+ /**
+ * Actually parses the HTML document and extracts useful elements from it.
+ *
+ * @return <CODE>true</CODE> if the page could be parsed successfully, or <CODE>false</CODE> if not.
+ */
+ public boolean parse() {
+ if (parsed) {
+ return true;
+ }
+
+ try {
+ associatedFiles = new LinkedHashSet<String>();
+ documentFrames = new LinkedHashSet<String>();
+ documentLinks = new LinkedHashSet<String>();
+ documentImages = new LinkedHashSet<String>();
+ textData = new StringBuffer();
+
+ lastElementStartPos = 0;
+ lastElementEndPos = -1;
+ String element;
+ while ((element = nextDocumentElement()) != null) {
+ if (element.length() == 0) {
+ continue;
+ }
+
+ if (lastElementIsText) {
+ char lastChar;
+ if (textData.length() == 0) {
+ lastChar = ' ';
+ } else {
+ lastChar = textData.charAt(textData.length() - 1);
+ }
+ char firstChar = element.charAt(0);
+ if (!((lastChar == ' ') || (lastChar == '\t') ||
+ (lastChar == '\r') || (lastChar == '\n')) ||
+ (firstChar == ' ') || (firstChar == '\t') ||
+ (firstChar == '\r') || (firstChar == '\n')) {
+ textData.append(" ");
+ }
+
+ textData.append(element);
+ } else if (lastElementIsImage) {
+ if (lastURL != null) {
+ documentImages.add(lastURL);
+ associatedFiles.add(lastURL);
+ }
+ } else if (lastElementIsFrame) {
+ if (lastURL != null) {
+ documentFrames.add(lastURL);
+ associatedFiles.add(lastURL);
+ }
+ } else if (lastElementIsLink) {
+ if (lastURL != null) {
+ documentLinks.add(lastURL);
+ }
+ } else if (lastElementIsAssociatedFile) {
+ if (lastURL != null) {
+ associatedFiles.add(lastURL);
+ }
+ } else if (lastElementIsChunk || lastElementIsComment) {
+ // Don't need to do anything with this.
+ } else {
+ // Also don't need anything here.
+ }
+ }
+
+ parsed = true;
+ } catch (Exception e) {
+ associatedFiles = null;
+ documentLinks = null;
+ documentImages = null;
+ textData = null;
+ parsed = false;
+ }
+
+ return parsed;
+ }
+
+ /**
+ * Retrieves the next element from the HTML document. An HTML element can
+ * include a string of plain text, a single HTML tag, or a larger chunk of
+ * HTML including a start and end tag, all of which should be considered a
+ * single element.
+ */
+ private String nextDocumentElement() {
+ // If we're at the end of the HTML, then return null.
+ if (lastElementEndPos >= htmlData.length()) {
+ return null;
+ }
+
+ // Initialize the variables we will use for the search.
+ lastElementStartPos = lastElementEndPos + 1;
+ lastElementIsAssociatedFile = false;
+ lastElementIsChunk = false;
+ lastElementIsComment = false;
+ lastElementIsFrame = false;
+ lastElementIsImage = false;
+ lastElementIsLink = false;
+ lastElementIsText = false;
+ lastURL = null;
+
+ // Find the location of the next open angle bracket. If there is none, then
+ // the rest of the document must be plain text.
+ int openPos = lowerData.indexOf('<', lastElementStartPos);
+ if (openPos < 0) {
+ lastElementEndPos = htmlData.length();
+ lastElementIsText = true;
+ return htmlData.substring(lastElementStartPos);
+ }
+
+ // If the location of the next open tag is not we started looking, then read
+ // everything up to that tag as text.
+ if (openPos > lastElementStartPos) {
+ lastElementEndPos = openPos - 1;
+ lastElementIsText = true;
+ return htmlData.substring(lastElementStartPos, openPos);
+ }
+
+ // The start position is an open tag. See if the tag is actually "<!--",
+ // which indicates an HTML comment. If that's the case, then find the
+ // closing "-->".
+ if (openPos == lowerData.indexOf("<!--", lastElementStartPos)) {
+ int closePos = lowerData.indexOf("-->", openPos + 1);
+ if (closePos < 0) {
+ // This looks like an unterminated comment. We can't do much else
+ // here, so just stop parsing.
+ return null;
+ } else {
+ lastElementEndPos = closePos + 2;
+ lastElementIsComment = true;
+ return htmlData.substring(lastElementStartPos, lastElementEndPos + 1);
+ }
+ }
+
+ // Find the location of the next close angle bracket. If there is none,
+ // then we have an unmatched open tag. What to do here? I guess just treat
+ // the rest of the document as text.
+ int closePos = lowerData.indexOf('>', openPos + 1);
+ if (closePos < 0) {
+ lastElementEndPos = htmlData.length();
+ lastElementIsText = true;
+ return htmlData.substring(lastElementStartPos);
+ }
+
+ // Grab the contents of the tag in both normal and lowercase.
+ String tag = htmlData.substring(openPos, closePos + 1);
+ String strippedTag = htmlData.substring(openPos + 1, closePos).trim();
+ StringTokenizer tokenizer = new StringTokenizer(strippedTag, " \t\r\n=\"'");
+ lastElementEndPos = closePos;
+
+ if (!tokenizer.hasMoreTokens()) {
+ return tag;
+ }
+
+ String token = tokenizer.nextToken();
+ String lowerToken = token.toLowerCase();
+
+ if (lowerToken.equals("a") || lowerToken.equals("area")) {
+ while (tokenizer.hasMoreTokens()) {
+ token = tokenizer.nextToken();
+ if (token.equalsIgnoreCase("href")) {
+ try {
+ Matcher matcher = hrefPattern.matcher(tag);
+ lastURL = uriToURL(matcher.replaceAll("$1"));
+ if (lastURL != null) {
+ lastElementIsLink = true;
+ }
+ } catch (Exception e) {
+ }
+ break;
+ }
+ }
+ } else if (lowerToken.equals("base")) {
+ while (tokenizer.hasMoreTokens()) {
+ token = tokenizer.nextToken();
+ if (token.equalsIgnoreCase("href")) {
+ try {
+ Matcher matcher = hrefPattern.matcher(tag);
+ String uri = matcher.replaceAll("$1");
+ if (!uri.endsWith("/")) {
+ uri = uri + "/";
+ }
+
+ baseURL = uri;
+ } catch (Exception e) {
+ }
+ break;
+ }
+ }
+ } else if (lowerToken.equals("frame") || lowerToken.equals("iframe") ||
+ lowerToken.equals("input")) {
+ while (tokenizer.hasMoreTokens()) {
+ token = tokenizer.nextToken();
+ if (token.equalsIgnoreCase("src")) {
+ try {
+ Matcher matcher = srcPattern.matcher(tag);
+ String uri = matcher.replaceAll("$1");
+ lastURL = uriToURL(uri);
+ if (lastURL != null) {
+ lastElementIsFrame = true;
+ lastElementIsAssociatedFile = true;
+ }
+ } catch (Exception e) {
+ }
+ break;
+ }
+ }
+ } else if (lowerToken.equals("img")) {
+ while (tokenizer.hasMoreTokens()) {
+ token = tokenizer.nextToken();
+ if (token.equalsIgnoreCase("src")) {
+ try {
+ Matcher matcher = srcPattern.matcher(tag);
+ String uri = matcher.replaceAll("$1");
+ lastURL = uriToURL(uri);
+ if (lastURL != null) {
+ lastElementIsImage = true;
+ }
+ } catch (Exception e) {
+ }
+ break;
+ }
+ }
+ } else if (lowerToken.equals("link")) {
+ boolean isStyleSheet = false;
+
+ while (tokenizer.hasMoreTokens()) {
+ token = tokenizer.nextToken();
+ if (token.equalsIgnoreCase("href")) {
+ try {
+ Matcher matcher = hrefPattern.matcher(tag);
+ String uri = matcher.replaceAll("$1");
+ lastURL = uriToURL(uri);
+ if (lastURL != null) {
+ lastElementIsLink = true;
+ }
+ } catch (Exception e) {
+ }
+ break;
+ } else if (token.equalsIgnoreCase("rel")) {
+ if (tokenizer.hasMoreTokens()) {
+ String relType = tokenizer.nextToken();
+ if (relType.equalsIgnoreCase("stylesheet")) {
+ isStyleSheet = true;
+ }
+ }
+ }
+ }
+
+ if (lastURL != null) {
+ if (isStyleSheet) {
+ lastElementIsAssociatedFile = true;
+ } else {
+ lastElementIsLink = true;
+ }
+ }
+ } else if (lowerToken.equals("script")) {
+ while (tokenizer.hasMoreTokens()) {
+ token = tokenizer.nextToken();
+ if (token.equalsIgnoreCase("src")) {
+ try {
+ Matcher matcher = srcPattern.matcher(tag);
+ String uri = matcher.replaceAll("$1");
+ lastURL = uriToURL(uri);
+ } catch (Exception e) {
+ }
+ break;
+ }
+ }
+
+ if (lastURL == null) {
+ int endScriptPos = lowerData.indexOf("</script>", lastElementEndPos + 1);
+ if (endScriptPos > 0) {
+ lastElementEndPos = endScriptPos + 8;
+ tag = htmlData.substring(lastElementStartPos, lastElementEndPos + 1);
+ lastElementIsChunk = true;
+ }
+ } else {
+ lastElementIsAssociatedFile = true;
+ }
+ }
+
+ return tag;
+ }
+
+ /**
+ * Converts the provided URI to a URL. The provided URI may be a URL already,
+ * or it may also be an absolute path on the server or a path relative to the
+ * base URL.
+ *
+ * @param uri The URI to convert to a URL.
+ *
+ * @return The URL based on the provided URI.
+ */
+ private String uriToURL(String uri) {
+ String url = null;
+
+ if (uri.indexOf("://") > 0) {
+ if (uri.startsWith("http")) {
+ url = uri;
+ }
+ } else if (uri.startsWith("/")) {
+ url = protocolHostPort + uri;
+ } else {
+ url = baseURL + uri;
+ }
+
+ return url;
+ }
+
+ /**
+ * Retrieves the URL of this HTML document.
+ *
+ * @return The URL of this HTML document.
+ */
+ public String getDocumentURL() {
+ return documentURL;
+ }
+
+ /**
+ * Retrieves the original HTML data used to create this document.
+ *
+ * @return The orginal HTML data used to create this document.
+ */
+ public String getHTMLData() {
+ return htmlData;
+ }
+
+ /**
+ * Retrieves the contents of the HTML document with all tags removed.
+ *
+ * @return The contents of the HTML document with all tags removed, or <CODE>null</CODE> if a problem occurs while
+ * trying to parse the
+ * HTML.
+ */
+ public String getTextData() {
+ if (!parsed) {
+ if (!parse()) {
+ return null;
+ }
+ }
+
+ return textData.toString();
+ }
+
+ /**
+ * Retrieves an array containing a set of URLs parsed from the HTML document
+ * that reference files that would normally be downloaded as part of
+ * retrieving a page in a browser. This includes images and external style
+ * sheets.
+ *
+ * @return An array containing a set of URLs to files associated with the
+ * HTML document, or <CODE>null</CODE> if a problem occurs while
+ * trying to parse the HTML.
+ */
+ public String[] getAssociatedFiles() {
+ if (!parsed) {
+ if (!parse()) {
+ return null;
+ }
+ }
+
+ String[] urlArray = new String[associatedFiles.size()];
+ associatedFiles.toArray(urlArray);
+ return urlArray;
+ }
+
+ /**
+ * Retrieves an array containing a set of URLs parsed from the HTML document
+ * that are in the form of links to other content.
+ *
+ * @return An array containing a set of URLs parsed from the HTML document
+ * that are in the form of links to other content, or <CODE>null</CODE> if a problem occurs while trying to
+ * parse the
+ * HTML.
+ */
+ public String[] getDocumentLinks() {
+ if (!parsed) {
+ if (!parse()) {
+ return null;
+ }
+ }
+
+ String[] urlArray = new String[documentLinks.size()];
+ documentLinks.toArray(urlArray);
+ return urlArray;
+ }
+
+ /**
+ * Retrieves an array containing a set of URLs parsed from the HTML document
+ * that reference images used in the document.
+ *
+ * @return An array containing a set of URLs parsed from the HTML document
+ * that reference images used in the document.
+ */
+ public String[] getDocumentImages() {
+ if (!parsed) {
+ if (!parse()) {
+ return null;
+ }
+ }
+
+ String[] urlArray = new String[documentImages.size()];
+ documentImages.toArray(urlArray);
+ return urlArray;
+ }
+
+ /**
+ * Retrieves an array containing a set of URLs parsed from the HTML document
+ * that reference frames used in the document.
+ *
+ * @return An array containing a set of URLs parsed from the HTML document
+ * that reference frames used in the document.
+ */
+ public String[] getDocumentFrames() {
+ if (!parsed) {
+ if (!parse()) {
+ return null;
+ }
+ }
+
+ String[] urlArray = new String[documentFrames.size()];
+ documentFrames.toArray(urlArray);
+ return urlArray;
+ }
+}
diff --git a/base/silent/src/com/netscape/pkisilent/http/HTTPClient.java b/base/silent/src/com/netscape/pkisilent/http/HTTPClient.java
new file mode 100644
index 000000000..f3980c0ed
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/http/HTTPClient.java
@@ -0,0 +1,1231 @@
+package com.netscape.pkisilent.http;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.io.BufferedOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.URLDecoder;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.ssl.SSLCertificateApprovalCallback;
+import org.mozilla.jss.ssl.SSLClientCertificateSelectionCallback;
+import org.mozilla.jss.ssl.SSLSocket;
+import org.mozilla.jss.ssl.TestCertApprovalCallback;
+import org.mozilla.jss.ssl.TestClientCertificateSelectionCallback;
+
+import com.netscape.pkisilent.argparser.ArgParser;
+import com.netscape.pkisilent.argparser.StringHolder;
+import com.netscape.pkisilent.common.ComCrypto;
+import com.netscape.cmsutil.util.Utils;
+
+public class HTTPClient implements SSLCertificateApprovalCallback {
+
+ public static final int BUFFER_SIZE = 4096;
+ public boolean debugMode = true;
+
+ public static String basic_auth_header_value = null;
+
+ public static String cs_hostname = null;
+ public static String cs_port = null;
+ public static String ssl = null;
+ public static String client_certdb_dir = null;
+ public static String client_certdb_pwd = null;
+ public static String client_cert_nickname = null;
+ public static String uri = null;
+ public static String query = null;
+ public static String request_type = null;
+ public static String user_id = null;
+ public static String user_password = null;
+ public static String auth_type = null;
+ public static String debug = null;
+
+ public static boolean parse_xml = false;
+
+ public static X509Certificate server_cert = null;
+
+ // cookie variable for CS install UI
+ public static String j_session_id = null;
+ public static boolean ecc_support = false;
+
+ public HTTPClient() {
+ // constructor
+ // turn off ecc by default
+ ecc_support = true;
+ }
+
+ public HTTPClient(boolean ecc) {
+ ecc_support = ecc;
+ }
+
+ public boolean setCipherPref(SSLSocket socket) {
+
+ if (ecc_support) {
+ int ecc_Ciphers[] = {
+ SSLSocket.TLS_ECDH_ECDSA_WITH_NULL_SHA, SSLSocket.TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
+ SSLSocket.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, SSLSocket.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
+ SSLSocket.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, SSLSocket.TLS_ECDHE_ECDSA_WITH_NULL_SHA,
+ SSLSocket.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, SSLSocket.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
+ SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+ SSLSocket.TLS_ECDH_RSA_WITH_NULL_SHA, SSLSocket.TLS_ECDH_RSA_WITH_RC4_128_SHA,
+ SSLSocket.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, SSLSocket.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
+ SSLSocket.TLS_ECDHE_RSA_WITH_NULL_SHA, SSLSocket.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
+ SSLSocket.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSLSocket.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+ SSLSocket.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+ 0 };
+
+ try {
+ for (int i = 0; i < ecc_Ciphers.length; i++) {
+ if (ecc_Ciphers[i] > 0)
+ socket.setCipherPreference(
+ ecc_Ciphers[i], true);
+ }
+ } catch (Exception e) {
+ System.out.println("ERROR: unable to set ECC Cipher List");
+ System.out.println("ERROR: Exception = " + e.getMessage());
+ }
+
+ }
+ return true;
+ }
+
+ public boolean disableSSL2(SSLSocket socket) {
+ try {
+ SSLSocket.enableSSL3Default(true);
+ socket.enableSSL3(true);
+ socket.enableSSL2(false);
+ SSLSocket.enableSSL2Default(false);
+ socket.enableV2CompatibleHello(false);
+ } catch (Exception e) {
+ System.out.println("ERROR: Exception = " + e.getMessage());
+ }
+ return true;
+ }
+
+ public X509Certificate getServerCert() {
+ return server_cert;
+ }
+
+ public void set_parse_xml(boolean b) {
+ parse_xml = b;
+ }
+
+ public boolean approve(X509Certificate cert,
+ SSLCertificateApprovalCallback.ValidityStatus status) {
+
+ // when this method is called by SSLSocket we get the server cert
+ // we can capture this for future use.
+ server_cert = cert;
+ return true;
+ }
+
+ public boolean testsslConnect(String hostname, String portnumber) {
+ boolean st = true;
+
+ try {
+
+ System.out.println("#############################################");
+ System.out.println("Attempting to connect to: " + hostname + ":" +
+ portnumber);
+
+ Integer x = new Integer(portnumber);
+ int port = x.intValue();
+
+ SSLClientCertificateSelectionCallback certSelectionCallback =
+ new TestClientCertificateSelectionCallback();
+
+ Socket js = new Socket(InetAddress.getByName(hostname), port);
+ SSLSocket socket = new SSLSocket(js, hostname, this,
+ certSelectionCallback);
+ setCipherPref(socket);
+ disableSSL2(socket);
+ socket.forceHandshake();
+ System.out.println("Connected.");
+ socket.setUseClientMode(true);
+
+ // test connection to obtain server cert. close it.
+ socket.close();
+
+ }
+
+ catch (Exception e) {
+ System.err.println("Exception: Unable to Send Request:" + e);
+ e.printStackTrace();
+ st = false;
+ }
+
+ if (!st)
+ return false;
+ else
+ return true;
+ }
+
+ // performs ssl connect to given host/port requiring client auth
+ // posts the given query data
+ // returns HTTPResponse
+ public HTTPResponse sslConnectClientAuth(String hostname, String portnumber,
+ String client_cert, String url, String query) {
+
+ boolean st = true;
+ HTTPResponse hr = null;
+
+ try {
+
+ System.out.println("#############################################");
+ System.out.println("Attempting to connect to: " + hostname + ":" +
+ portnumber);
+
+ Integer x = new Integer(portnumber);
+ int port = x.intValue();
+
+ SSLCertificateApprovalCallback approvalCallback =
+ new TestCertApprovalCallback();
+ CertSelection certSelectionCallback =
+ new CertSelection();
+
+ // Client Cert for Auth is set here
+ certSelectionCallback.setClientCert(client_cert);
+
+ Socket js = new Socket(InetAddress.getByName(hostname), port);
+ SSLSocket socket = new SSLSocket(js, hostname, approvalCallback,
+ certSelectionCallback);
+ disableSSL2(socket);
+ setCipherPref(socket);
+ socket.forceHandshake();
+ System.out.println("Connected.");
+ socket.setUseClientMode(true);
+
+ System.out.println("Posting Query = " +
+ "https://" + hostname +
+ ":" + portnumber +
+ "/" + url +
+ "?" + query);
+
+ OutputStream rawos = socket.getOutputStream();
+ BufferedOutputStream os = new BufferedOutputStream(rawos);
+ PrintStream ps = new PrintStream(os);
+
+ ps.println("POST " + url + " HTTP/1.0");
+ ps.println("Connection: Keep-Alive");
+ ps.println("Content-type: application/x-www-form-urlencoded");
+ ps.println("Content-length: " + query.length());
+ ps.println("");
+ ps.print(query);
+ ps.flush();
+ os.flush();
+
+ try {
+ hr = readResponse(socket.getInputStream());
+ hr.parseContent();
+
+ } catch (Exception e) {
+ System.out.println("Exception");
+ e.printStackTrace();
+ st = false;
+ }
+
+ socket.close();
+ os.close();
+ rawos.close();
+ ps.close();
+
+ os = null;
+ rawos = null;
+ ps = null;
+
+ }
+
+ catch (Exception e) {
+ System.err.println("Exception: Unable to Send Request:" + e);
+ e.printStackTrace();
+ st = false;
+ }
+
+ if (!st)
+ return null;
+ else
+ return hr;
+ }
+
+ // performs ssl connect to given host/port
+ // posts the given query data
+ // returns HTTPResponse
+ public HTTPResponse sslConnect(String hostname, String portnumber,
+ String url, String query) {
+
+ boolean st = true;
+ HTTPResponse hr = null;
+
+ try {
+
+ System.out.println("#############################################");
+ System.out.println("Attempting to connect to: " + hostname + ":" +
+ portnumber);
+
+ Integer x = new Integer(portnumber);
+ int port = x.intValue();
+
+ SSLCertificateApprovalCallback approvalCallback =
+ new TestCertApprovalCallback();
+ SSLClientCertificateSelectionCallback certSelectionCallback =
+ new TestClientCertificateSelectionCallback();
+
+ Socket js = new Socket(InetAddress.getByName(hostname), port);
+ SSLSocket socket = new SSLSocket(js, hostname, approvalCallback,
+ certSelectionCallback);
+ setCipherPref(socket);
+ disableSSL2(socket);
+ socket.forceHandshake();
+ System.out.println("Connected.");
+ socket.setUseClientMode(true);
+
+ System.out.println("Posting Query = " +
+ "https://" + hostname +
+ ":" + portnumber +
+ "/" + url +
+ "?" + query);
+
+ OutputStream rawos = socket.getOutputStream();
+ BufferedOutputStream os = new BufferedOutputStream(rawos);
+ PrintStream ps = new PrintStream(os);
+
+ ps.println("POST " + url + " HTTP/1.0");
+
+ // check to see if we have a cookie to send
+ if (j_session_id != null)
+ ps.println("Cookie: " + j_session_id);
+
+ ps.println("Content-type: application/x-www-form-urlencoded");
+ ps.println("Content-length: " + query.length());
+ ps.println("Connection: Keep-Alive");
+
+ // special header posting if available
+ if (basic_auth_header_value != null) {
+ System.out.println("basic_auth = " + basic_auth_header_value);
+ ps.println("Authorization: Basic " + basic_auth_header_value);
+ }
+
+ ps.println("");
+ ps.println(query);
+ ps.println("\r");
+ ps.flush();
+ os.flush();
+
+ try {
+ hr = readResponse(socket.getInputStream());
+ hr.parseContent();
+
+ } catch (Exception e) {
+ System.out.println("Exception");
+ e.printStackTrace();
+ st = false;
+ }
+
+ socket.close();
+ os.close();
+ rawos.close();
+ ps.close();
+
+ os = null;
+ rawos = null;
+ ps = null;
+
+ }
+
+ catch (Exception e) {
+ System.err.println("Exception: Unable to Send Request:" + e);
+ e.printStackTrace();
+ st = false;
+ }
+
+ if (!st)
+ return null;
+ else
+ return hr;
+ }
+
+ // performs non ssl connect to given host/port
+ // posts the given query data
+ // returns HTTPResponse
+ public HTTPResponse nonsslConnect(String hostname, String portnumber,
+ String url, String query) {
+
+ boolean st = true;
+ HTTPResponse hr = null;
+
+ try {
+
+ System.out.println("#############################################");
+ System.out.println("Attempting to connect to: " + hostname + ":" +
+ portnumber);
+
+ Integer x = new Integer(portnumber);
+ int port = x.intValue();
+
+ Socket socket = new Socket(hostname, port);
+
+ System.out.println("Posting Query = " +
+ "http://" + hostname +
+ ":" + portnumber +
+ "/" + url +
+ "?" + query);
+
+ OutputStream rawos = socket.getOutputStream();
+ BufferedOutputStream os = new BufferedOutputStream(rawos);
+ PrintStream ps = new PrintStream(os);
+
+ System.out.println("Connected.");
+
+ ps.println("POST " + url + " HTTP/1.0");
+
+ // check to see if we have a cookie to send
+ if (j_session_id != null)
+ ps.println("Cookie: " + j_session_id);
+
+ ps.println("Content-type: application/x-www-form-urlencoded");
+ ps.println("Content-length: " + query.length());
+ ps.println("Connection: Keep-Alive");
+
+ // special header posting if available
+ if (basic_auth_header_value != null) {
+ System.out.println("basic_auth = " + basic_auth_header_value);
+ ps.println("Authorization: Basic " + basic_auth_header_value);
+ }
+
+ ps.println("");
+ ps.println(query);
+ ps.println("\r");
+ ps.flush();
+ os.flush();
+
+ try {
+ hr = readResponse(socket.getInputStream());
+ hr.parseContent();
+
+ } catch (Exception e) {
+ System.out.println("Exception");
+ e.printStackTrace();
+ st = false;
+ }
+
+ socket.close();
+ os.close();
+ rawos.close();
+ ps.close();
+
+ os = null;
+ rawos = null;
+ ps = null;
+
+ }
+
+ catch (Exception e) {
+ System.err.println("Exception: Unable to Send Request:" + e);
+ e.printStackTrace();
+ st = false;
+ }
+
+ if (!st)
+ return null;
+ else
+ return hr;
+ }
+
+ public HTTPResponse readResponse(InputStream inputStream)
+ throws Exception {
+ // read response from http input stream and return HTTPResponse
+ byte[] buffer = new byte[BUFFER_SIZE];
+ HTTPResponse response = null;
+ int statusCode = 0;
+
+ // Read an initial chunk of the response from the server.
+ int bytesRead = inputStream.read(buffer);
+ if (bytesRead < 0) {
+ throw new IOException("Unexpected end of input stream from server");
+ }
+
+ // Hopefully, this initial chunk will contain the entire header, so look for
+ // it. Technically, HTTP is supposed to use CRLF as the end-of-line
+ // character, so look for that first, but also check for LF by itself just
+ // in case.
+ int headerEndPos = -1;
+ int dataStartPos = -1;
+ for (int i = 0; i < (bytesRead - 3); i++) {
+ if ((buffer[i] == '\r') && (buffer[i + 1] == '\n') &&
+ (buffer[i + 2] == '\r') && (buffer[i + 3] == '\n')) {
+ headerEndPos = i;
+ dataStartPos = i + 4;
+ break;
+ }
+ }
+
+ if (headerEndPos < 0) {
+ for (int i = 0; i < (bytesRead - 1); i++) {
+ if ((buffer[i] == '\n') && (buffer[i + 1] == '\n')) {
+ headerEndPos = i;
+ dataStartPos = i + 2;
+ break;
+ }
+ }
+ }
+
+ // In the event that we didn't get the entire header in the first pass, keep
+ // reading until we do have enough.
+ if (headerEndPos < 0) {
+ byte[] buffer2 = new byte[BUFFER_SIZE];
+ while (headerEndPos < 0) {
+ int startPos = bytesRead;
+ int moreBytesRead = inputStream.read(buffer2);
+ if (moreBytesRead < 0) {
+ throw new IOException("Unexpected end of input stream from server " +
+ "when reading more data from response");
+ }
+
+ byte[] newBuffer = new byte[bytesRead + moreBytesRead];
+ System.arraycopy(buffer, 0, newBuffer, 0, bytesRead);
+ System.arraycopy(buffer2, 0, newBuffer, bytesRead, moreBytesRead);
+ buffer = newBuffer;
+ bytesRead += moreBytesRead;
+
+ for (int i = startPos; i < (bytesRead - 3); i++) {
+ if ((buffer[i] == '\r') && (buffer[i + 1] == '\n') &&
+ (buffer[i + 2] == '\r') && (buffer[i + 3] == '\n')) {
+ headerEndPos = i;
+ dataStartPos = i + 4;
+ break;
+ }
+ }
+
+ if (headerEndPos < 0) {
+ for (int i = startPos; i < (bytesRead - 1); i++) {
+ if ((buffer[i] == '\n') && (buffer[i + 1] == '\n')) {
+ headerEndPos = i;
+ dataStartPos = i + 2;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // At this point, we should have the entire header, so read and analyze it.
+ String headerStr = new String(buffer, 0, headerEndPos);
+ StringTokenizer tokenizer = new StringTokenizer(headerStr, "\r\n");
+ if (tokenizer.hasMoreTokens()) {
+ String statusLine = tokenizer.nextToken();
+ if (debugMode) {
+ System.out.println("RESPONSE STATUS: " + statusLine);
+ }
+
+ int spacePos = statusLine.indexOf(' ');
+ if (spacePos < 0) {
+ System.out.println("ERROR: Unable to parse response header -- could " +
+ "not find protocol/version delimiter");
+ return null;
+
+ }
+
+ String protocolVersion = statusLine.substring(0, spacePos);
+ int spacePos2 = statusLine.indexOf(' ', spacePos + 1);
+ if (spacePos2 < 0) {
+ System.out.println("ERROR: Unable to parse response header -- could " +
+ "not find response code delimiter");
+ return null;
+ }
+
+ try {
+ statusCode = Integer.parseInt(statusLine.substring(spacePos + 1,
+ spacePos2));
+ } catch (NumberFormatException nfe) {
+ System.out.println("Unable to parse response header -- could " +
+ "not interpret status code as an integer");
+ return null;
+ }
+
+ String responseMessage = statusLine.substring(spacePos2 + 1);
+ response = new HTTPResponse(statusCode, protocolVersion,
+ responseMessage);
+
+ while (tokenizer.hasMoreTokens()) {
+ String headerLine = tokenizer.nextToken();
+ if (debugMode) {
+ System.out.println("RESPONSE HEADER: " + headerLine);
+ }
+
+ int colonPos = headerLine.indexOf(':');
+ if (colonPos < 0) {
+ if (headerLine.toLowerCase().startsWith("http/")) {
+ // This is a direct violation of RFC 2616, but certain HTTP servers
+ // seem to immediately follow a 100 continue with a 200 ok without
+ // the required CRLF in between.
+ System.out.println("ERROR: Found illegal status line '" + headerLine +
+ "'in the middle of a response -- attempting " +
+ "to deal with it as the start of a new " +
+ "response.");
+ statusLine = headerLine;
+ spacePos = statusLine.indexOf(' ');
+ if (spacePos < 0) {
+ System.out.println("ERROR: Unable to parse response header -- " +
+ "could not find protocol/version " +
+ "delimiter");
+ return null;
+ }
+
+ protocolVersion = statusLine.substring(0, spacePos);
+ spacePos2 = statusLine.indexOf(' ', spacePos + 1);
+ if (spacePos2 < 0) {
+ System.out.println("ERROR: Unable to parse response header -- " +
+ "could not find response code delimiter");
+ return null;
+ }
+
+ try {
+ statusCode = Integer.parseInt(statusLine.substring(spacePos + 1,
+ spacePos2));
+ } catch (NumberFormatException nfe) {
+ System.out.println("ERROR: Unable to parse response header -- " +
+ "could not interpret status code as an " +
+ "integer");
+ return null;
+ }
+
+ responseMessage = statusLine.substring(spacePos2 + 1);
+ response = new HTTPResponse(statusCode, protocolVersion,
+ responseMessage);
+ continue;
+ } else {
+ System.out.println("ERROR: Unable to parse response header -- no " +
+ "colon found on header line \"" +
+ headerLine + "\"");
+ }
+ }
+
+ String headerName = headerLine.substring(0, colonPos);
+ String headerValue = headerLine.substring(colonPos + 1).trim();
+ response.addHeader(headerName, headerValue);
+ }
+ } else {
+ // This should never happen -- an empty response
+ System.out.println("Unable to parse response header -- empty " +
+ "header");
+ }
+
+ // If the status code was 100 (continue), then it was an intermediate header
+ // and we need to keep reading until we get the real response header.
+ while (response.getStatusCode() == 100) {
+ if (dataStartPos < bytesRead) {
+ byte[] newBuffer = new byte[bytesRead - dataStartPos];
+ System.arraycopy(buffer, dataStartPos, newBuffer, 0, newBuffer.length);
+ buffer = newBuffer;
+ bytesRead = buffer.length;
+
+ headerEndPos = -1;
+ for (int i = 0; i < (bytesRead - 3); i++) {
+ if ((buffer[i] == '\r') && (buffer[i + 1] == '\n') &&
+ (buffer[i + 2] == '\r') && (buffer[i + 3] == '\n')) {
+ headerEndPos = i;
+ dataStartPos = i + 4;
+ break;
+ }
+ }
+
+ if (headerEndPos < 0) {
+ for (int i = 0; i < (bytesRead - 1); i++) {
+ if ((buffer[i] == '\n') && (buffer[i + 1] == '\n')) {
+ headerEndPos = i;
+ dataStartPos = i + 2;
+ break;
+ }
+ }
+ }
+ } else {
+ buffer = new byte[0];
+ bytesRead = 0;
+ headerEndPos = -1;
+ }
+
+ byte[] buffer2 = new byte[BUFFER_SIZE];
+ while (headerEndPos < 0) {
+ int startPos = bytesRead;
+ int moreBytesRead = inputStream.read(buffer2);
+
+ if (moreBytesRead < 0) {
+ throw new IOException("Unexpected end of input stream from server " +
+ "when reading more data from response");
+ }
+
+ byte[] newBuffer = new byte[bytesRead + moreBytesRead];
+ System.arraycopy(buffer, 0, newBuffer, 0, bytesRead);
+ System.arraycopy(buffer2, 0, newBuffer, bytesRead, moreBytesRead);
+ buffer = newBuffer;
+ bytesRead += moreBytesRead;
+
+ for (int i = startPos; i < (bytesRead - 3); i++) {
+ if ((buffer[i] == '\r') && (buffer[i + 1] == '\n') &&
+ (buffer[i + 2] == '\r') && (buffer[i + 3] == '\n')) {
+ headerEndPos = i;
+ dataStartPos = i + 4;
+ break;
+ }
+ }
+
+ if (headerEndPos < 0) {
+ for (int i = startPos; i < (bytesRead - 1); i++) {
+ if ((buffer[i] == '\n') && (buffer[i + 1] == '\n')) {
+ headerEndPos = i;
+ dataStartPos = i + 2;
+ break;
+ }
+ }
+ }
+ }
+
+ // We should now have the next header, so examine it.
+ headerStr = new String(buffer, 0, headerEndPos);
+ tokenizer = new StringTokenizer(headerStr, "\r\n");
+ if (tokenizer.hasMoreTokens()) {
+ String statusLine = tokenizer.nextToken();
+ if (debugMode) {
+ System.out.println("RESPONSE STATUS: " + statusLine);
+ }
+
+ int spacePos = statusLine.indexOf(' ');
+ if (spacePos < 0) {
+ System.out.println("Unable to parse response header -- could " +
+ "not find protocol/version delimiter");
+ }
+
+ String protocolVersion = statusLine.substring(0, spacePos);
+ int spacePos2 = statusLine.indexOf(' ', spacePos + 1);
+ if (spacePos2 < 0) {
+ System.out.println("Unable to parse response header -- could " +
+ "not find response code delimiter");
+ }
+
+ try {
+ statusCode = Integer.parseInt(statusLine.substring(spacePos + 1,
+ spacePos2));
+ } catch (NumberFormatException nfe) {
+ System.out.println("Unable to parse response header -- could " +
+ "not interpret status code as an integer");
+ }
+
+ String responseMessage = statusLine.substring(spacePos2 + 1);
+ response = new HTTPResponse(statusCode, protocolVersion,
+ responseMessage);
+
+ while (tokenizer.hasMoreTokens()) {
+ String headerLine = tokenizer.nextToken();
+ if (debugMode) {
+ System.out.println("RESPONSE HEADER: " + headerLine);
+ }
+
+ int colonPos = headerLine.indexOf(':');
+ if (colonPos < 0) {
+ System.out.println("Unable to parse response header -- no " +
+ "colon found on header line \"" +
+ headerLine + "\"");
+ }
+
+ String headerName = headerLine.substring(0, colonPos);
+ String headerValue = headerLine.substring(colonPos + 1).trim();
+ response.addHeader(headerName, headerValue);
+ }
+ } else {
+ // This should never happen -- an empty response
+ System.out.println("Unable to parse response header -- empty " +
+ "header");
+ }
+ }
+
+ // Now that we have parsed the header, use it to determine how much data
+ // there is. If we're lucky, the server will have told us using the
+ // "Content-Length" header.
+ int contentLength = response.getContentLength();
+
+ if (contentLength >= 0) {
+ readContentDataUsingLength(response, inputStream, contentLength, buffer,
+ dataStartPos, bytesRead);
+ } else {
+ // It's not chunked encoding, so our last hope is that the connection
+ // will be closed when all the data has been sent.
+ String connectionStr = response.getHeader("connection");
+ if ((connectionStr != null) &&
+ (!connectionStr.equalsIgnoreCase("close"))) {
+ System.out.println("ERROR:Unable to determine how to find when the " +
+ "end of the data has been reached (no " +
+ "content length, not chunked encoding, " +
+ "connection string is \"" + connectionStr +
+ "\" rather than \"close\")");
+ } else {
+ readContentDataUsingConnectionClose(response, inputStream, buffer,
+ dataStartPos, bytesRead);
+ }
+ }
+ // Finally, return the response to the caller.
+ return response;
+ }
+
+ /**
+ * Reads the actual data of the response based on the content length provided
+ * by the server in the response header.
+ *
+ * @param response The response with which the data is associated.
+ * @param inputStream The input stream from which to read the response.
+ * @param contentLength The number of bytes that the server said are in the
+ * response.
+ * @param dataRead The data that we have already read. This includes
+ * the header data, but may also include some or all of
+ * the content data as well.
+ * @param dataStartPos The position in the provided array at which the
+ * content data starts.
+ * @param dataBytesRead The total number of valid bytes in the provided
+ * array that should be considered part of the
+ * response (the number of header bytes is included in
+ * this count).
+ *
+ * @throws IOException If a problem occurs while reading data from the
+ * server.
+ */
+ private void readContentDataUsingLength(HTTPResponse response,
+ InputStream inputStream,
+ int contentLength, byte[] dataRead,
+ int dataStartPos, int dataBytesRead)
+ throws IOException {
+ if (contentLength <= 0) {
+ response.setResponseData(new byte[0]);
+ return;
+ }
+
+ byte[] contentBytes = new byte[contentLength];
+ int startPos = 0;
+ if (dataBytesRead > dataStartPos) {
+ // We've already got some data to include in the header, so copy that into
+ // the content array. Make sure the server didn't do something stupid
+ // like return more data than it told us was in the response.
+ int bytesToCopy = Math.min(contentBytes.length,
+ (dataBytesRead - dataStartPos));
+ System.arraycopy(dataRead, dataStartPos, contentBytes, 0, bytesToCopy);
+ startPos = bytesToCopy;
+ }
+
+ byte[] buffer = new byte[BUFFER_SIZE];
+ while (startPos < contentBytes.length) {
+ int bytesRead = inputStream.read(buffer);
+ if (bytesRead < 0) {
+ throw new IOException("Unexpected end of input stream reached when " +
+ "reading data from the server");
+ }
+
+ System.arraycopy(buffer, 0, contentBytes, startPos, bytesRead);
+ startPos += bytesRead;
+ }
+
+ response.setResponseData(contentBytes);
+ }
+
+ /**
+ * Reads the actual data of the response using chunked encoding, which is a
+ * way for the server to provide the data in several chunks rather than all at
+ * once.
+ *
+ * @param response The response with which the data is associated.
+ * @param inputStream The input stream from which to read the response.
+ * @param dataRead The data that we have already read. This includes
+ * the header data, but may also include some or all of
+ * the content data as well.
+ * @param dataStartPos The position in the provided array at which the
+ * content data starts.
+ * @param dataBytesRead The total number of valid bytes in the provided
+ * array that should be considered part of the
+ * response (the number of header bytes is included in
+ * this count).
+ *
+ * @throws IOException If a problem occurs while reading data from the
+ * server.
+ */
+ private void readContentDataUsingConnectionClose(HTTPResponse response,
+ InputStream inputStream,
+ byte[] dataRead,
+ int dataStartPos,
+ int dataBytesRead)
+ throws IOException {
+ // Create an array list that we will use to hold the chunks of information
+ // read from the server.
+ ArrayList<ByteBuffer> bufferList = new ArrayList<ByteBuffer>();
+
+ // Create a variable to hold the total number of bytes in the data.
+ int totalBytes = 0;
+
+ // See if we have unread data in the array already provided.
+ int existingBytes = dataBytesRead - dataStartPos;
+ if (existingBytes > 0) {
+ ByteBuffer byteBuffer = ByteBuffer.allocate(existingBytes);
+ byteBuffer.put(dataRead, dataStartPos, existingBytes);
+ bufferList.add(byteBuffer);
+ totalBytes += existingBytes;
+ }
+
+ // Keep reading until we hit the end of the input stream.
+ byte[] buffer = new byte[BUFFER_SIZE];
+ while (true) {
+ try {
+ int bytesRead = inputStream.read(buffer);
+ if (bytesRead < 0) {
+ // We've hit the end of the stream and therefore the end of the
+ // document.
+ break;
+ } else if (bytesRead > 0) {
+ ByteBuffer byteBuffer = ByteBuffer.allocate(bytesRead);
+ byteBuffer.put(buffer, 0, bytesRead);
+ bufferList.add(byteBuffer);
+ totalBytes += bytesRead;
+ }
+ } catch (IOException ioe) {
+ // In this case we'll assume that the end of the stream has been
+ // reached. It's possible that there was some other error, but we can't
+ // do anything about it so try to process what we've got so far.
+ System.out.println("ERROR: unable to read until end of stream");
+ System.out.println("ERROR: " + ioe.getMessage());
+ break;
+ }
+ }
+
+ // Assemble the contents of all the buffers into a big array and store that
+ // array in the response.
+ int startPos = 0;
+ byte[] contentData = new byte[totalBytes];
+ for (int i = 0; i < bufferList.size(); i++) {
+ ByteBuffer byteBuffer = (ByteBuffer) bufferList.get(i);
+ byteBuffer.flip();
+ byteBuffer.get(contentData, startPos, byteBuffer.limit());
+ startPos += byteBuffer.limit();
+ }
+ response.setResponseData(contentData);
+ }
+
+ // performs ssl connect to given host/port
+ // posts the given query data - format - a byte array
+ // returns HTTPResponse
+
+ public HTTPResponse sslConnect(String hostname, String portnumber,
+ String url, byte[] data) {
+
+ boolean st = true;
+ HTTPResponse hr = null;
+
+ try {
+
+ System.out.println("#############################################");
+ System.out.println("Attempting to connect to: " + hostname + ":" +
+ portnumber);
+
+ Integer x = new Integer(portnumber);
+ int port = x.intValue();
+
+ SSLCertificateApprovalCallback approvalCallback =
+ new TestCertApprovalCallback();
+ SSLClientCertificateSelectionCallback certSelectionCallback =
+ new TestClientCertificateSelectionCallback();
+
+ Socket js = new Socket(InetAddress.getByName(hostname), port);
+ SSLSocket socket = new SSLSocket(js, hostname, approvalCallback,
+ certSelectionCallback);
+ setCipherPref(socket);
+ disableSSL2(socket);
+ socket.forceHandshake();
+ System.out.println("Connected.");
+ socket.setUseClientMode(true);
+
+ DataOutputStream dos =
+ new DataOutputStream(socket.getOutputStream());
+ dos.writeBytes("POST /ocsp HTTP/1.0\r\n");
+ dos.writeBytes("Content-length: " + data.length + "\r\n");
+ dos.writeBytes("\r\n");
+ dos.write(data);
+ dos.writeBytes("\r\n");
+ dos.flush();
+
+ try {
+ hr = readResponse(socket.getInputStream());
+ hr.parseContent();
+ } catch (Exception e) {
+ System.out.println("Exception");
+ e.printStackTrace();
+ st = false;
+ }
+
+ socket.close();
+ dos.close();
+
+ }
+
+ catch (Exception e) {
+ System.err.println("Exception: Unable to Send Request:" + e);
+ e.printStackTrace();
+ st = false;
+ }
+
+ if (!st)
+ return null;
+ else
+ return hr;
+ }
+
+ // performs non ssl connect to given host/port
+ // posts the given query data
+ // returns HTTPResponse
+ public HTTPResponse nonsslConnect(String hostname, String portnumber,
+ String url, byte[] data) {
+
+ boolean st = true;
+ HTTPResponse hr = null;
+
+ try {
+
+ System.out.println("#############################################");
+ System.out.println("Attempting to connect to: " + hostname + ":" +
+ portnumber);
+
+ Integer x = new Integer(portnumber);
+ int port = x.intValue();
+
+ Socket socket = new Socket(hostname, port);
+
+ System.out.println("Posting Query = " +
+ "http://" + hostname +
+ ":" + portnumber +
+ "/" + url);
+
+ System.out.println("Connected.");
+
+ DataOutputStream dos =
+ new DataOutputStream(socket.getOutputStream());
+ dos.writeBytes("POST " + url + " HTTP/1.0\r\n");
+ dos.writeBytes("Content-length: " + data.length + "\r\n");
+ dos.writeBytes("\r\n");
+ dos.write(data);
+ dos.writeBytes("\r\n");
+ dos.flush();
+
+ try {
+ hr = readResponse(socket.getInputStream());
+ hr.parseContent();
+ } catch (Exception e) {
+ System.out.println("Exception");
+ e.printStackTrace();
+ st = false;
+ }
+
+ socket.close();
+ dos.close();
+
+ }
+
+ catch (Exception e) {
+ System.err.println("Exception: Unable to Send Request:" + e);
+ e.printStackTrace();
+ st = false;
+ }
+
+ if (!st)
+ return null;
+ else
+ return hr;
+ }
+
+ public static boolean init_nss() {
+ try {
+
+ ComCrypto cCrypt = new ComCrypto(client_certdb_dir,
+ client_certdb_pwd,
+ null,
+ null,
+ null);
+ cCrypt.setDebug(true);
+ cCrypt.setGenerateRequest(false);
+ cCrypt.loginDB();
+ } catch (Exception e) {
+ System.out.println("ERROR: unable to login to : " +
+ client_certdb_dir);
+ return false;
+ }
+
+ return true;
+ }
+
+ public static void main(String args[]) throws UnsupportedEncodingException {
+ HTTPClient hc = new HTTPClient();
+ HTTPResponse hr = null;
+
+ // parse args
+ StringHolder x_hostname = new StringHolder();
+ StringHolder x_port = new StringHolder();
+ StringHolder x_ssl = new StringHolder();
+ StringHolder x_client_certdb_dir = new StringHolder();
+ StringHolder x_client_certdb_pwd = new StringHolder();
+ StringHolder x_client_cert_nickname = new StringHolder();
+ StringHolder x_uri = new StringHolder();
+ StringHolder x_query = new StringHolder();
+ StringHolder x_request_type = new StringHolder();
+ StringHolder x_auth_type = new StringHolder();
+ StringHolder x_user_id = new StringHolder();
+ StringHolder x_user_password = new StringHolder();
+ StringHolder x_debug = new StringHolder();
+ StringHolder x_decode = new StringHolder();
+
+ // parse the args
+ ArgParser parser = new ArgParser("HTTPClient");
+
+ parser.addOption("-hostname %s #Hostname",
+ x_hostname);
+ parser.addOption("-port %s #port number",
+ x_port);
+ parser.addOption("-ssl %s #HTTP or HTTPS[true or false]",
+ x_ssl);
+ parser.addOption("-client_certdb_dir %s #CertDB dir",
+ x_client_certdb_dir);
+ parser.addOption("-client_certdb_pwd %s #CertDB password",
+ x_client_certdb_pwd);
+ parser.addOption("-client_cert_nickname %s #client cert nickname",
+ x_client_cert_nickname);
+ parser.addOption("-uri %s #URI",
+ x_uri);
+ parser.addOption("-query %s #URL encoded query string[note: url encode value part only for CS operations]",
+ x_query);
+ parser.addOption("-request_type %s #Request Type [ post ]",
+ x_request_type);
+ parser.addOption("-user_id %s #user id for authorization",
+ x_user_id);
+ parser.addOption("-user_password %s #password for authorization",
+ x_user_password);
+ parser.addOption("-auth_type %s #type of authorization [ BASIC ]",
+ x_auth_type);
+ parser.addOption("-debug %s #enables display of debugging info",
+ x_debug);
+ parser.addOption("-decode %s #URL Decode the resulting output",
+ x_decode);
+
+ // and then match the arguments
+ String[] unmatched = null;
+ unmatched = parser.matchAllArgs(args, 0, ArgParser.EXIT_ON_UNMATCHED);
+
+ if (unmatched != null) {
+ System.out.println("ERROR: Argument Mismatch");
+ System.exit(-1);
+ }
+
+ // set variables
+ cs_hostname = x_hostname.value;
+ cs_port = x_port.value;
+ ssl = x_ssl.value;
+ client_certdb_dir = x_client_certdb_dir.value;
+ client_certdb_pwd = x_client_certdb_pwd.value;
+ client_cert_nickname = x_client_cert_nickname.value;
+ uri = x_uri.value;
+ query = x_query.value;
+ request_type = x_request_type.value;
+ user_id = x_user_id.value;
+ user_password = x_user_password.value;
+ auth_type = x_auth_type.value;
+ debug = x_debug.value;
+
+ String decode = x_decode.value;
+
+ // init_nss if needed
+ boolean st = init_nss();
+ if (!st)
+ System.exit(-1);
+
+ // set basic auth if needed
+ if (auth_type != null && auth_type.equalsIgnoreCase("BASIC")) {
+ // BASE64Encoder encoder = new BASE64Encoder();
+
+ // String temp = encoder.encodeBuffer((user_id +
+ // ":" + user_password).getBytes());
+ String temp = Utils.base64encode((user_id +
+ ":" + user_password).getBytes());
+
+ // note: temp already contains \r and \n.
+ // remove \r and \n from the base64 encoded string.
+ // causes problems when sending http post requests
+ // using PrintStream.println()
+
+ temp = temp.replaceAll("\\r", "");
+ temp = temp.replaceAll("\\n", "");
+
+ basic_auth_header_value = temp;
+ }
+
+ // route to proper function
+
+ if (ssl != null && ssl.equalsIgnoreCase("true")) {
+ if (client_cert_nickname != null &&
+ !client_cert_nickname.equalsIgnoreCase("null")) {
+ // ssl client auth call
+
+ hr = hc.sslConnectClientAuth(cs_hostname, cs_port,
+ client_cert_nickname,
+ uri, query);
+ }
+
+ else {
+ // ssl client call
+ hr = hc.sslConnect(cs_hostname, cs_port, uri, query);
+ }
+ } else if (ssl != null && ssl.equalsIgnoreCase("false")) {
+ // non ssl connect
+ hr = hc.nonsslConnect(cs_hostname, cs_port, uri, query);
+ } else {
+ System.out.println("ERROR: ssl parameter is null");
+ System.exit(-1);
+ }
+
+ // collect and print response
+
+ if (hr.getStatusCode() == 200)
+ System.out.println("Response from Host:" + cs_hostname + " OK");
+ else {
+ System.out.println("ERROR: unable to get response from host:" +
+ cs_hostname);
+ System.exit(-1);
+ }
+
+ String responseValue = null;
+ if (decode.equalsIgnoreCase("true"))
+ responseValue = URLDecoder.decode(hr.getHTML(), "UTF-8");
+ else
+ responseValue = hr.getHTML();
+
+ System.out.println("###############################");
+ System.out.println("RESULT=" + responseValue);
+ System.out.println("###############################");
+
+ }
+
+};
diff --git a/base/silent/src/com/netscape/pkisilent/http/HTTPResponse.java b/base/silent/src/com/netscape/pkisilent/http/HTTPResponse.java
new file mode 100644
index 000000000..9ade1c133
--- /dev/null
+++ b/base/silent/src/com/netscape/pkisilent/http/HTTPResponse.java
@@ -0,0 +1,314 @@
+package com.netscape.pkisilent.http;
+
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+
+import com.netscape.pkisilent.common.Utilities;
+
+public class HTTPResponse {
+ // The set of cookie values included in this response.
+ ArrayList<String> cookieValueList;
+
+ // The names of the headers included in this response.
+ ArrayList<String> headerNameList;
+
+ // The values of the headers included in this response.
+ ArrayList<String> headerValueList;
+
+ // The actual data associated with this response.
+ byte[] responseData;
+
+ // The HTML document included in the response, if appropriate.
+ HTMLDocument htmlDocument;
+
+ // The number of bytes contained in the content of the response.
+ int contentLength;
+
+ // The HTTP status code for the response.
+ int statusCode;
+
+ // The MIME type of the response.
+ String contentType;
+
+ // The protocol version string for this response.
+ String protolVersion;
+
+ // The response message for this response.
+ String responseMessage;
+
+ // Parsed Content Name/Value pair info
+ ArrayList<String> contentName;
+ ArrayList<String> contentValue;
+
+ /**
+ * Creates a new HTTP response with the provided status code.
+ *
+ * @param statusCode The HTTP status code for this response.
+ * @param protocolVersion The protocol and version for this response.
+ * @param responseMessage The message associated with this response.
+ */
+ public HTTPResponse(int statusCode, String protocolVersion,
+ String responseMessage) {
+ this.statusCode = statusCode;
+ this.protolVersion = protocolVersion;
+ this.responseMessage = responseMessage;
+
+ htmlDocument = null;
+ contentType = null;
+ contentLength = -1;
+ responseData = new byte[0];
+ cookieValueList = new ArrayList<String>();
+ headerNameList = new ArrayList<String>();
+ headerValueList = new ArrayList<String>();
+ contentName = new ArrayList<String>();
+ contentValue = new ArrayList<String>();
+ }
+
+ /**
+ * Retrieves the status code for this HTTP response.
+ *
+ * @return The status code for this HTTP response.
+ */
+ public int getStatusCode() {
+ return statusCode;
+ }
+
+ /**
+ * Retrieves the protocol version for this HTTP response.
+ *
+ * @return The protocol version for this HTTP response.
+ */
+ public String getProtocolVersion() {
+ return protolVersion;
+ }
+
+ /**
+ * Retrieves the response message for this HTTP response.
+ *
+ * @return The response message for this HTTP response.
+ */
+ public String getResponseMessage() {
+ return responseMessage;
+ }
+
+ /**
+ * Retrieves the value of the header with the specified name. If the
+ * specified header has more than one value, then only the first will be
+ * retrieved.
+ *
+ * @return The value of the header with the specified name, or <CODE>null</CODE> if no such header is available.
+ */
+ public String getHeader(String headerName) {
+ String lowerName = headerName.toLowerCase();
+
+ for (int i = 0; i < headerNameList.size(); i++) {
+ if (lowerName.equals(headerNameList.get(i))) {
+ return headerValueList.get(i);
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Retrieves the set of values for the specified header.
+ *
+ * @return The set of values for the specified header.
+ */
+ public String[] getHeaderValues(String headerName) {
+ ArrayList<String> valueList = new ArrayList<String>();
+ String lowerName = headerName.toLowerCase();
+
+ for (int i = 0; i < headerNameList.size(); i++) {
+ if (lowerName.equals(headerNameList.get(i))) {
+ valueList.add(headerValueList.get(i));
+ }
+ }
+
+ String[] values = new String[valueList.size()];
+ valueList.toArray(values);
+ return values;
+ }
+
+ /**
+ * Adds a header with the given name and value to this response.
+ *
+ * @param headerName The name of the header to add to this response.
+ * @param headerValue The value of the header to add to this response.
+ */
+ public void addHeader(String headerName, String headerValue) {
+ String lowerName = headerName.toLowerCase();
+ headerNameList.add(lowerName);
+ headerValueList.add(headerValue);
+
+ if (lowerName.equals("content-length")) {
+ try {
+ contentLength = Integer.parseInt(headerValue);
+ } catch (NumberFormatException nfe) {
+ }
+ } else if (lowerName.equals("content-type")) {
+ contentType = headerValue;
+ } else if (lowerName.equals("set-cookie")) {
+ cookieValueList.add(headerValue);
+ }
+ }
+
+ /**
+ * Retrieves a two-dimensional array containing the header data for this
+ * response, with each element being an array containing a name/value pair.
+ *
+ * @return A two-dimensional array containing the header data for this
+ * response.
+ */
+ public String[][] getHeaderElements() {
+ String[][] headerElements = new String[headerNameList.size()][2];
+ for (int i = 0; i < headerNameList.size(); i++) {
+ headerElements[i][0] = headerNameList.get(i);
+ headerElements[i][1] = headerValueList.get(i);
+ }
+
+ return headerElements;
+ }
+
+ /**
+ * Retrieves the raw data included in this HTTP response. If the response did
+ * not include any data, an empty array will be returned.
+ *
+ * @return The raw data included in this HTTP response.
+ */
+ public byte[] getResponseData() {
+ return responseData;
+ }
+
+ public String getHTML() {
+ String htmlString = new String(responseData);
+ return htmlString;
+ }
+
+ public String getHTMLwithoutTags() {
+ String htmlString = new String(responseData);
+ HTMLDocument htmldocument = new HTMLDocument(htmlString);
+ return htmldocument.getTextData();
+ }
+
+ public void parseContent() {
+ // parse the responseData byte[] buffer and split content into name
+ // value pair
+ String htmlString = new String(responseData);
+ StringTokenizer st = new StringTokenizer(htmlString, "\n");
+ Utilities ut = new Utilities();
+
+ while (st.hasMoreTokens()) {
+ String line = st.nextToken();
+ // format for line assumed to be name="value"; format
+
+ int eqPos = line.indexOf('=');
+ if (eqPos != -1) {
+ String name = line.substring(0, eqPos);
+ String tempval = line.substring(eqPos + 1).trim();
+ String value = ut.cleanupQuotes(ut.removechar(tempval));
+
+ // add to array
+ this.contentName.add(name.trim());
+ this.contentValue.add(value);
+ }
+
+ }
+
+ }
+
+ public String getContentValue(String headerName) {
+ for (int i = 0; i < contentName.size(); i++) {
+ if (headerName.equals(contentName.get(i))) {
+ return contentValue.get(i);
+ }
+ }
+
+ return null;
+ }
+
+ public ArrayList<String> getContentNames() {
+ return contentName;
+ }
+
+ public ArrayList<String> getContentValues() {
+ return contentValue;
+ }
+
+ /**
+ * Sets the actual data associated with this response.
+ *
+ * @param responseData The actual data associated with this response.
+ */
+ public void setResponseData(byte[] responseData) {
+ if (responseData == null) {
+ this.responseData = new byte[0];
+ } else {
+ this.responseData = responseData;
+ }
+ }
+
+ /**
+ * Retrieves the content length associated with this response.
+ *
+ * @return The content length associated with this response, or -1 if no
+ * content length is available.
+ */
+ public int getContentLength() {
+ return contentLength;
+ }
+
+ /**
+ * Retrieves the content type associated with this response.
+ *
+ * @return The content type associated with this response, or <CODE>null</CODE> if no content type is available.
+ */
+ public String getContentType() {
+ return contentType;
+ }
+
+ /**
+ * Retrieves an array containing the values of the cookies that should be set
+ * based on the information in this response.
+ *
+ * @return An array containing the values of the cookies that should be set
+ * based on the information in this response.
+ */
+ public String[] getCookieValues() {
+ String[] cookieValues = new String[cookieValueList.size()];
+ cookieValueList.toArray(cookieValues);
+ return cookieValues;
+ }
+
+ public String getCookieValue(String headerName) {
+ for (int i = 0; i < cookieValueList.size(); i++) {
+ System.out.println("cookie list: " + cookieValueList.get(i));
+
+ String temp = cookieValueList.get(i);
+ if (temp.startsWith(headerName)) {
+ return cookieValueList.get(i);
+ }
+ }
+
+ return null;
+ }
+
+}
diff --git a/base/silent/templates/pki_silent.template b/base/silent/templates/pki_silent.template
new file mode 100755
index 000000000..93ff5849a
--- /dev/null
+++ b/base/silent/templates/pki_silent.template
@@ -0,0 +1,1732 @@
+#!/bin/bash
+## BEGIN COPYRIGHT BLOCK
+## (C) 2009 Red Hat, Inc.
+## All rights reserved.
+## END COPYRIGHT BLOCK
+
+
+## Always switch into this base directory
+## prior to script execution so that all
+## of its output is written to this directory
+
+cd `dirname $0`
+
+
+## Disallow script to be run as the name of this template
+pki_silent_script=`basename $0`
+if [ "${pki_silent_script}" = "pki_silent.template" ] ; then
+ printf "\n"
+ printf "Usage: (1) Install AND configure a directory server instance.\n\n"
+ printf " (2) Install, but do NOT configure ALL six\n"
+ printf " 'default' PKI subsystem instances.\n\n"
+ printf " (3) Install the 'pki-silent' package.\n\n"
+ printf " (4) Copy '$0' to a new script name\n"
+ printf " without the '.template' extension.\n"
+ printf " (e .g. - 'configure_default_pki_instances')\n\n"
+ printf " (5) Fill in all MANDATORY user-defined variables\n"
+ printf " in the new script.\n\n"
+ printf " (6) Change any OPTIONAL user-defined variables\n"
+ printf " in the new script as desired.\n\n"
+ printf " (7) Become the 'root' user, and execute the new script to\n"
+ printf " configure ALL six 'default' PKI subsystem instances.\n\n"
+ exit 255
+fi
+
+
+##
+## This script MUST be run as root!
+##
+
+ROOTUID=0
+
+OS=`uname`
+if [ "${OS}" = "Linux" ] ; then
+ MY_EUID=`/usr/bin/id -u`
+ MY_UID=`/usr/bin/id -ur`
+ USERNAME=`/usr/bin/id -un`
+else
+ printf "ERROR: Unsupported operating system '${OS}'!\n"
+ exit 255
+fi
+
+if [ "${MY_UID}" != "${ROOTUID}" ] &&
+ [ "${MY_EUID}" != "${ROOTUID}" ] ; then
+ printf "ERROR: The '$0' script must be run as root!\n"
+ exit 255
+fi
+
+
+
+##############################################################################
+##############################################################################
+## ##
+## P K I S I L E N T - V A R I A B L E D E C L A R A T I O N ##
+## ##
+##############################################################################
+##############################################################################
+
+##############################################################################
+## U S E R - D E F I N E D V A R I A B L E S ( M A N D A T O R Y ) ##
+##############################################################################
+
+##
+## IMPORTANT: 'Escape' ALL spaces in EACH variable specified below!
+##
+## For Example:
+##
+## pki_security_domain_name="My\ Security\ Domain"
+##
+
+## PKI Silent Security Database Variables
+## (e. g. - PKI Silent "browser" database)
+pki_silent_security_database_repository="/tmp"
+pki_silent_security_database_password=
+
+## PKI Security Domain Variables
+## (e. g. - Security Domain Login Panel)
+pki_security_domain_name=
+pki_security_domain_host=`hostname`
+pki_security_domain_admin_name=admin
+pki_security_domain_admin_password=
+
+## PKI Internal LDAP Database Variables
+## (e. g. - Database Panel)
+pki_ldap_host=localhost
+pki_ldap_port=389
+pki_bind_dn="cn=Directory\ Manager"
+pki_bind_password=
+
+## PKI Instance-Specific Token Variables
+## (e. g. - Module Panel)
+ca_token_name=internal
+ca_token_password=
+
+kra_token_name=internal
+kra_token_password=
+
+ocsp_token_name=internal
+ocsp_token_password=
+
+tks_token_name=internal
+tks_token_password=
+
+ra_token_name=internal
+ra_token_password=
+
+tps_token_name=internal
+tps_token_password=
+
+## PKI Instance-Specific Backup Variables
+## (e. g. - Backup Key and Certificates Panel)
+ca_backup_password=
+kra_backup_password=
+ocsp_backup_password=
+tks_backup_password=
+
+## PKI Email Variables
+##
+## For example, to specify 'pkitest@example.com':
+##
+## pki_email_name=pkitest
+## pki_email_company=example
+## pki_email_domain=com
+##
+pki_email_name=
+pki_email_company=
+pki_email_domain=
+
+## PKI Silent Admin Variables
+## (e. g. - Import Admin Certificate into PKI Silent "browser" database)
+pki_silent_admin_user=admin
+pki_silent_admin_password=
+pki_silent_admin_email="${pki_email_name}\@${pki_email_company}\.${pki_email_domain}"
+
+
+
+##############################################################################
+## P R E - D E F I N E D " D E F A U L T " V A R I A B L E S ##
+##############################################################################
+
+## PKI Subsystem Host (computed by default)
+pki_host=`hostname`
+
+## PKI Subsystem Names
+ca_subsystem_name="Certificate\ Authority"
+kra_subsystem_name="Data\ Recovery\ Manager"
+ocsp_subsystem_name="OCSP\ Responder"
+tks_subsystem_name="Token\ Key\ Service"
+ra_subsystem_name="Registration\ Authority"
+tps_subsystem_name="Token\ Processing\ System"
+
+## PKI Subsystem Instance Names
+ca_instance_name="pki-ca"
+kra_instance_name="pki-kra"
+ocsp_instance_name="pki-ocsp"
+tks_instance_name="pki-tks"
+ra_instance_name="pki-ra"
+tps_instance_name="pki-tps"
+
+## PKI Subsystem Init Script Names
+ca_init_script="pki-cad"
+kra_init_script="pki-krad"
+ocsp_init_script="pki-ocspd"
+tks_init_script="pki-tksd"
+ra_init_script="pki-rad"
+tps_init_script="pki-tpsd"
+
+##
+## NOTE: Default PKI Instance Ports
+##
+## CA, DRM, OCSP, TKS:
+##
+## *180 - non-secure port (not role specific)
+## *701 - non-secure Tomcat port
+## *443 - secure EE port
+## *444 - secure Agent port
+## *445 - secure Admin port
+##
+## RA, TPS:
+##
+## *888 - non-secure port
+## *889 - secure port (clientauth)
+## *890 - secure port (non-clientauth)
+##
+##
+## For Example:
+##
+## semanage port -l | grep pki
+##
+## pki_ca_port_t tcp 9180, 9701, 9443, 9444, 9445
+## pki_kra_port_t tcp 10180, 10701, 10443, 10444, 10445
+## pki_ocsp_port_t tcp 11180, 11701, 11443, 11444, 11445
+## pki_ra_port_t tcp 12890, 12888, 12889
+## pki_tks_port_t tcp 13180, 13701, 13443, 13444, 13445
+## pki_tps_port_t tcp 7890, 7888, 7889
+##
+
+## CA ports
+ca_nonssl_port=9180
+ca_agent_port=9443
+ca_ee_port=9444
+ca_admin_port=9445
+
+## DRM ports
+kra_nonssl_port=10180
+kra_agent_port=10443
+kra_ee_port=10444
+kra_admin_port=10445
+
+## OCSP ports
+ocsp_nonssl_port=11180
+ocsp_agent_port=11443
+ocsp_ee_port=11444
+ocsp_admin_port=11445
+
+## TKS ports
+tks_nonssl_port=13180
+tks_agent_port=13443
+tks_ee_port=13444
+tks_admin_port=13445
+
+## RA ports
+ra_nonssl_port=12888
+ra_clientauth_port=12889
+ra_nonclientauth_port=12890
+
+## TPS ports
+tps_nonssl_port=7888
+tps_clientauth_port=7889
+tps_nonclientauth_port=7890
+
+
+
+##############################################################################
+## U S E R - D E F I N E D V A R I A B L E S ( O P T I O N A L ) ##
+##############################################################################
+
+## PKI Silent Log Files
+pki_silent_ca_log=/tmp/ca.log
+pki_silent_kra_log=/tmp/kra.log
+pki_silent_ocsp_log=/tmp/ocsp.log
+pki_silent_ra_log=/tmp/ra.log
+pki_silent_tks_log=/tmp/tks.log
+pki_silent_tps_log=/tmp/tps.log
+
+
+##
+## NOTE: For comparison's sake, if the default instances were manually
+## configured using a Firefox browser, the content of the corresponding
+## Firefox browser's security libraries would be something similar
+## to this:
+##
+## Certificate Nickname Trust Attributes
+## SSL,S/MIME,JAR/XPI
+##
+## Certificate Authority - ${pki_security_domain_name} CT,C,C
+## CA Administrator of Instance ${ca_instance_name}'s
+## ${pki_security_domain_name} ID u,u,u
+## KRA Administrator of Instance ${kra_instance_name}'s
+## ${pki_security_domain_name} ID u,u,u
+## OCSP Administrator of Instance ${ocsp_instance_name}'s
+## ${pki_security_domain_name} ID u,u,u
+## TKS Administrator of Instance ${tks_instance_name}'s
+## ${pki_security_domain_name} ID u,u,u
+## RA Administrator's ${pki_security_domain_name} ID u,u,u
+## TPS Administrator's ${pki_security_domain_name} ID u,u,u
+##
+## where:
+##
+## Nickname: "Certificate Authority - "
+## + "${pki_security_domain_name}"
+## Subject Name: "cn=Certificate Authority,"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "CA Administrator of Instance "
+## + "${ca_instance_name}'s "
+## + "${pki_security_domain_name} ID"
+## Subject Name: "cn=CA Administrator of Instance "
+## + "${ca_instance_name},"
+## + "uid=admin,"
+## + "e=${pki_silent_admin_email},"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "KRA Administrator of Instance "
+## + "${kra_instance_name}'s "
+## + "${pki_security_domain_name} ID"
+## Subject Name: "cn=KRA Administrator of Instance "
+## + "${kra_instance_name},"
+## + "uid=admin,"
+## + "e=${pki_silent_admin_email},"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "OCSP Administrator of Instance "
+## + "${ocsp_instance_name}'s "
+## + "${pki_security_domain_name} ID"
+## Subject Name: "cn=OCSP Administrator of Instance "
+## + "${ocsp_instance_name},"
+## + "uid=admin,"
+## + "e=${pki_silent_admin_email},"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "TKS Administrator of Instance "
+## + "${tks_instance_name}'s "
+## + "${pki_security_domain_name} ID"
+## Subject Name: "cn=TKS Administrator of Instance "
+## + "${tks_instance_name},"
+## + "uid=admin,"
+## + "e=${pki_silent_admin_email},"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "RA Administrator's "
+## + "${pki_security_domain_name} ID"
+## Subject Name: "cn=RA Administrator,"
+## + "uid=admin,"
+## + "e=${pki_silent_admin_email},"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "TPS Administrator's "
+## + "${pki_security_domain_name} ID"
+## Subject Name: "cn=TPS Administrator,"
+## + "uid=admin,"
+## + "e=${pki_silent_admin_email},"
+## + "o=${pki_security_domain_name}"
+##
+
+
+## Miscellaneous CA Variables
+##
+## REMINDER: 'Escape' ALL spaces in EACH variable specified below!
+##
+## NOTE: For comparison's sake, if the default instances were manually
+## configured using a Firefox browser, the content of the corresponding
+## "/var/lib/${ca_instance_name}/alias/" security libraries would be
+## something similar to this:
+##
+## Certificate Nickname Trust Attributes
+## SSL,S/MIME,JAR/XPI
+##
+## ocspSigningCert cert-${ca_instance_name} u,u,u
+## subsystemCert cert-${ca_instance_name} u,u,u
+## caSigningCert cert-${ca_instance_name} CTu,Cu,Cu
+## Server-Cert cert-${ca_instance_name} u,u,u
+## auditSigningCert cert-${ca_instance_name} u,u,u
+##
+## where:
+##
+## Nickname: "caSigningCert cert-${ca_instance_name}"
+## Subject Name: "cn=Certificate Authority,"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "subsystemCert cert-${ca_instance_name}"
+## Subject Name: "cn=CA Subsystem Certificate,"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "ocspSigningCert cert-${ca_instance_name}"
+## Subject Name: "cn=OCSP Signing Certificate,"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "Server-Cert cert-${ca_instance_name}"
+## Subject Name: "cn=${pki_host},"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "auditSigningCert cert-${ca_instance_name}"
+## Subject Name: "cn=CA Audit Signing Certificate,"
+## + "o=${pki_security_domain_name}"
+##
+## NOTE: The parameters for the signing and key algorithms have the following meaning:
+## ca_key_algorithm - signature algorithm used to sign the CA certificate
+## ca_signing_algorithm - signature algorithm used by the CA and OCSP signing certs to sign objects.
+## ca_signing_signingalgorithm - optionally specify the algorithm used by the CA signing cert to sign objects
+## ca_ocsp_signing_signingalgorithm - optionally specify the algorithm used by the CA ocsp signing cert to sign objects
+##
+## NOTE: Additional variables to specify the LDAP connection are as follows:
+## remove_data - set to true/false. Remove any existing data found under the baseDN
+## secure_conn - use the ldaps port
+ca_agent_name="CA\ Administrator\ of\ Instance\ ${ca_instance_name}\'s\ ${pki_security_domain_name}\ ID"
+ca_agent_key_size=2048
+ca_agent_key_type=rsa
+ca_agent_cert_subject="cn=CA\ Administrator\ of\ Instance\ ${ca_instance_name},uid=admin,e=${pki_silent_admin_email},o=${pki_security_domain_name}"
+ca_base_dn="dc=${pki_host}-${ca_instance_name}"
+ca_db_name="${pki_host}-${ca_instance_name}"
+ca_key_size=2048
+ca_key_type=rsa
+ca_key_algorithm=SHA256withRSA
+ca_signing_algorithm=SHA256withRSA
+ca_signing_signingalgorithm=SHA256withRSA
+ca_ocsp_signing_signingalgorithm=SHA256withRSA
+ca_save_p12=false
+ca_sign_cert_subject_name="cn=Certificate\ Authority,o=${pki_security_domain_name}"
+ca_subsystem_cert_subject_name="cn=CA\ Subsystem\ Certificate,o=${pki_security_domain_name}"
+ca_ocsp_cert_subject_name="cn=OCSP\ Signing\ Certificate,o=${pki_security_domain_name}"
+ca_server_cert_subject_name="cn=${pki_host},o=${pki_security_domain_name}"
+ca_audit_signing_cert_subject_name="cn=CA\ Audit\ Signing\ Certificate,o=${pki_security_domain_name}"
+
+## Optional CA Variables for creating a clone CA
+##
+## It is possible for pkisilent to create a CA that is a clone of a previously
+## installed CA (the master CA). To do so, the keys of the master CA must
+## first be backed up in a pk12 file, and this file should be copied to the
+## alias directory of the clone CA. This file should have read permission for
+## the PKI user (pkisuer).
+##
+## An example file would be /var/lib/ca-clone/alias/ca-master.p12.
+##
+## The following variables should then be uncommented and defined for the clone CA.
+## ca_clone=true
+## ca_clone_p12_file=
+## ca_clone_p12_password=
+## clone_uri=
+## sd_hostname=
+## sd_admin_port=
+## sd_admin_name=
+## sd_admin_password=
+## clone_start_tls=false
+##
+## NOTES:
+## 1. ca_clone_p12_file must be just the filename relative to the alias directory.
+## So in the example above, ca_clone_p12_file="ca-master.p12"
+## 2. sd_* refer to the CA where the security domain is hosted.
+## 3. clone_uri has the following format: https://<hostname>:<EE port> fo the CA to be cloned
+## 4. clone_start_tls can be set to true if we require replication between the master and clone databases
+## to be encrypted using startTLS on the standard (non-ldaps) port. The databases must
+## be ssl enabled first or the replication will fail.
+##
+## ADDITIONAL NOTES:
+## 1. The clone CA and master CA cannot share the same database instance. A new
+## instance should be created for the clone CA.
+## 2. The variables ca_base_dn and ca_db_name defined above MUST be identical to the
+## ca_base_dn and ca_db_name of the master CA. The following assignments attempt
+## to ensure this is correct.
+##
+## ca_master_instance_name=
+## ca_base_dn="dc=${pki_host}-${ca_master_instance_name}"
+## ca_db_name="${pki_host}-${ca_master_instance_name}"
+
+## Optional CA variables for creating a CA using an external CA
+##
+## It is possible to configure a CA that has its certificates signed by an external CA.
+## This is a two step process.
+##
+## In the first step, pkisilent will create a CSR to be signed by the external CA
+## and write it to the file specified. If this file is not specified, the default
+## location /tmp/ext_ca.csr is used.
+##
+## The following parameters are required:
+## ca_external=true
+## ca_ext_csr_file=
+##
+## Once the CSR is approved by the external CA, the resulting certificate and CA
+## cert chain are copied into files on the system.
+##
+## pkisilent is then rerun for the second step, providing the cert and cert chain files as
+## parameters. For the second step, the following parameters are then required:
+##
+## ca_external=true
+## ca_ext_cert_file=
+## ca_ext_cert_chain_file=
+
+## Miscellaneous DRM Variables
+##
+## REMINDER: 'Escape' ALL spaces in EACH variable specified below!
+##
+## NOTE: For comparison's sake, if the default instances were manually
+## configured using a Firefox browser, the content of the corresponding
+## "/var/lib/${kra_instance_name}/alias/" security libraries would be
+## something similar to this:
+##
+## Certificate Nickname Trust Attributes
+## SSL,S/MIME,JAR/XPI
+##
+## transportCert cert-${kra_instance_name} u,u,u
+## Server-Cert cert-${kra_instance_name} u,u,u
+## auditSigningCert cert-${kra_instance_name} u,u,u
+## Certificate Authority - ${pki_security_domain_name} CT,c,
+## storageCert cert-${kra_instance_name} u,u,u
+## subsystemCert cert-${kra_instance_name} u,u,u
+##
+## where:
+##
+## Nickname: "transportCert cert-${kra_instance_name}"
+## Subject Name: "cn=DRM Transport Certificate,"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "Server-Cert cert-${kra_instance_name}"
+## Subject Name: "cn=${pki_host},"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "auditSigningCert cert-${kra_instance_name}"
+## Subject Name: "cn=DRM Audit Signing Certificate,"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "Certificate Authority - "
+## + "${pki_security_domain_name}"
+## Subject Name: "cn=Certificate Authority,"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "storageCert cert-${kra_instance_name}"
+## Subject Name: "cn=DRM Storage Certificate,"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "subsystemCert cert-${kra_instance_name}"
+## Subject Name: "cn=DRM Subsystem Certificate,"
+## + "o=${pki_security_domain_name}"
+##
+
+## Optional CA Variables for creating a clone DRM
+##
+## It is possible for pkisilent to create a DRM that is a clone of a previously
+## installed DRM (the master DRM). To do so, the keys of the master DRM must
+## first be backed up in a pk12 file, and this file should be copied to the
+## alias directory of the clone DRM. This file should have read permission for
+## the PKI user (pkiuser).
+##
+## An example file would be /var/lib/drm-clone/alias/drm-master.p12.
+##
+## The following variables should then be uncommented and defined for the clone CA.
+## kra_clone=true
+## kra_clone_p12_file=
+## kra_clone_p12_password=
+## kra_clone_uri=
+## clone_start_tls=false
+##
+## NOTES:
+## 1. drm_clone_p12_file must be just the filename relative to the alias directory.
+## So in the example above, drm_clone_p12_file="drm-master.p12"
+## 2. drm_clone_uri has the following format: https://<hostname>:<EE port> of the DRM to be cloned
+## 3. clone_start_tls can be set to true if we require replication between the master and clone databases
+## to be encrypted using startTLS on the standard (non-ldaps) port. The databases must
+## be ssl enabled first or the replication will fail.
+##
+## ADDITIONAL NOTES:
+## 1. The clone DRM and master DRM cannot share the same database instance. A new
+## instance should be created for the clone DRM.
+## 2. The variables kra_base_dn and kra_db_name defined above MUST be identical to the
+## kra_base_dn and kra_name of the master CA. The following assignments attempt
+## to ensure this is correct.
+##
+## kra_master_instance_name=
+## kra_base_dn="dc=${pki_host}-${kra_master_instance_name}"
+## kra_db_name="${pki_host}-${kra_master_instance_name}"
+
+kra_agent_name="KRA\ Administrator\ of\ Instance\ ${kra_instance_name}\'s\ ${pki_security_domain_name}\ ID"
+kra_agent_key_size=2048
+kra_agent_key_type=rsa
+kra_agent_cert_subject="cn=KRA\ Administrator\ of\ Instance\ ${kra_instance_name},uid=admin,e=${pki_silent_admin_email},o=${pki_security_domain_name}"
+kra_base_dn="dc=${pki_host}-${kra_instance_name}"
+kra_db_name="${pki_host}-${kra_instance_name}"
+kra_key_size=2048
+kra_key_type=rsa
+kra_transport_cert_subject_name="cn=DRM\ Transport\ Certificate,o=${pki_security_domain_name}"
+kra_subsystem_cert_subject_name="cn=DRM\ Subsystem\ Certificate,o=${pki_security_domain_name}"
+kra_storage_cert_subject_name="cn=DRM\ Storage\ Certificate,o=${pki_security_domain_name}"
+kra_server_cert_subject_name="cn=${pki_host},o=${pki_security_domain_name}"
+kra_audit_signing_cert_subject_name="cn=DRM\ Audit\ Signing\ Certificate,o=${pki_security_domain_name}"
+
+
+## Miscellaneous OCSP Variables
+##
+## REMINDER: 'Escape' ALL spaces in EACH variable specified below!
+##
+## NOTE: For comparison's sake, if the default instances were manually
+## configured using a Firefox browser, the content of the corresponding
+## "/var/lib/${ocsp_instance_name}/alias/" security libraries would be
+## something similar to this:
+##
+## Certificate Nickname Trust Attributes
+## SSL,S/MIME,JAR/XPI
+##
+## ocspSigningCert cert-${ocsp_instance_name} CTu,Cu,Cu
+## subsystemCert cert-${ocsp_instance_name} u,u,u
+## Certificate Authority - ${pki_security_domain_name} CT,c,
+## Server-Cert cert-${ocsp_instance_name} u,u,u
+## auditSigningCert cert-${ocsp_instance_name} u,u,u
+##
+## where:
+##
+## Nickname: "ocspSigningCert cert-${ocsp_instance_name}"
+## Subject Name: "cn=OCSP Signing Certificate,"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "subsystemCert cert-${ocsp_instance_name}"
+## Subject Name: "cn=OCSP Subsystem Certificate,"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "Certificate Authority - "
+## + "${pki_security_domain_name}"
+## Subject Name: "cn=Certificate Authority,"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "Server-Cert cert-${ocsp_instance_name}"
+## Subject Name: "cn=${pki_host},"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "auditSigningCert cert-${ocsp_instance_name}"
+## Subject Name: "cn=OCSP Audit Signing Certificate,"
+## + "o=${pki_security_domain_name}"
+##
+
+ocsp_agent_name="OCSP\ Administrator\ of\ Instance\ ${ocsp_instance_name}\'s\ ${pki_security_domain_name}\ ID"
+ocsp_agent_key_size=2048
+ocsp_agent_key_type=rsa
+ocsp_agent_cert_subject="cn=OCSP\ Administrator\ of\ Instance\ ${ocsp_instance_name},uid=admin,e=${pki_silent_admin_email},o=${pki_security_domain_name}"
+ocsp_base_dn="dc=${pki_host}-${ocsp_instance_name}"
+ocsp_db_name="${pki_host}-${ocsp_instance_name}"
+ocsp_key_size=2048
+ocsp_key_type=rsa
+ocsp_sign_cert_subject_name="cn=OCSP\ Signing\ Certificate,o=${pki_security_domain_name}"
+ocsp_subsystem_cert_subject_name="cn=OCSP\ Subsystem\ Certificate,o=${pki_security_domain_name}"
+ocsp_server_cert_subject_name="cn=${pki_host},o=${pki_security_domain_name}"
+ocsp_audit_signing_cert_subject_name="cn=OCSP\ Audit\ Signing\ Certificate,o=${pki_security_domain_name}"
+
+
+## Miscellaneous TKS Variables
+##
+## REMINDER: 'Escape' ALL spaces in EACH variable specified below!
+##
+## NOTE: For comparison's sake, if the default instances were manually
+## configured using a Firefox browser, the content of the corresponding
+## "/var/lib/${tks_instance_name}/alias/" security libraries would be
+## something similar to this:
+##
+## Certificate Nickname Trust Attributes
+## SSL,S/MIME,JAR/XPI
+##
+## subsystemCert cert-${tks_instance_name} u,u,u
+## DRM Transport Certificate - ${pki_security_domain_name} c,c,c
+## Certificate Authority - ${pki_security_domain_name} CT,c,
+## Server-Cert cert-${tks_instance_name} u,u,u
+## auditSigningCert cert-${tks_instance_name} u,u,u
+##
+## where:
+##
+## Nickname: "subsystemCert cert-${tks_instance_name}"
+## Subject Name: "cn=TKS Subsystem Certificate,"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "DRM Transport Certificate - "
+## + "${pki_security_domain_name}"
+## Subject Name: "cn=DRM Transport Certificate,"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "Certificate Authority - "
+## + "${pki_security_domain_name}"
+## Subject Name: "cn=Certificate Authority,"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "Server-Cert cert-${tks_instance_name}"
+## Subject Name: "cn=${pki_host},"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "auditSigningCert cert-${tks_instance_name}"
+## Subject Name: "cn=TKS Audit Signing Certificate,"
+## + "o=${pki_security_domain_name}"
+##
+
+tks_agent_name="TKS\ Administrator\ of\ Instance\ ${tks_instance_name}\'s\ ${pki_security_domain_name}\ ID"
+tks_agent_key_size=2048
+tks_agent_key_type=rsa
+tks_agent_cert_subject="cn=TKS\ Administrator\ of\ Instance\ ${tks_instance_name},uid=admin,e=${pki_silent_admin_email},o=${pki_security_domain_name}"
+tks_base_dn="dc=${pki_host}-${tks_instance_name}"
+tks_db_name="${pki_host}-${tks_instance_name}"
+tks_key_size=2048
+tks_key_type=rsa
+tks_subsystem_cert_subject_name="cn=TKS\ Subsystem\ Certificate,o=${pki_security_domain_name}"
+tks_server_cert_subject_name="cn=${pki_host},o=${pki_security_domain_name}"
+tks_audit_signing_cert_subject_name="cn=TKS\ Audit\ Signing\ Certificate,o=${pki_security_domain_name}"
+
+
+## Miscellaneous RA Variables
+##
+## REMINDER: 'Escape' ALL spaces in EACH variable specified below!
+##
+## NOTE: For comparison's sake, if the default instances were manually
+## configured using a Firefox browser, the content of the corresponding
+## "/var/lib/${ra_instance_name}/alias/" security libraries would be
+## something similar to this:
+##
+## Certificate Nickname Trust Attributes
+## SSL,S/MIME,JAR/XPI
+##
+## subsystemCert cert-${ra_instance_name} u,u,u
+## caCert CT,C,C
+## Server-Cert cert-${ra_instance_name} u,u,u
+##
+## where:
+##
+## Nickname: "subsystemCert cert-${ra_instance_name}"
+## Subject Name: "cn=RA Subsystem Certificate,"
+## + "ou=${ra_instance_name},"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "caCert"
+## Subject Name: "cn=Certificate Authority,"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "Server-Cert cert-${ra_instance_name}"
+## Subject Name: "cn=${pki_host},"
+## + "ou=${ra_instance_name},"
+## + "o=${pki_security_domain_name}"
+##
+
+ra_chosen_ca_hostname=${pki_security_domain_host}
+ra_chosen_ca_nonssl_port=${ca_nonssl_port}
+ra_chosen_ca_ssl_port=${ca_ee_port}
+ra_chosen_ca_admin_port=${ca_admin_port}
+ra_agent_name="RA\ Administrator\'s\ ${pki_security_domain_name}\ ID"
+ra_agent_key_size=2048
+ra_agent_key_type=rsa
+ra_agent_cert_subject="cn=RA\ Administrator,uid=admin,e=${pki_silent_admin_email},o=${pki_security_domain_name}"
+ra_key_size=2048
+ra_key_type=rsa
+ra_server_cert_nickname="Server-Cert\ cert-${ra_instance_name}"
+ra_server_cert_subject_name="cn=${pki_host},ou=${ra_instance_name},o=${pki_security_domain_name}"
+ra_subsystem_cert_nickname="subsystemCert\ cert-${ra_instance_name}"
+ra_subsystem_cert_subject_name="cn=RA\ Subsystem\ Certificate,ou=${ra_instance_name},o=${pki_security_domain_name}"
+
+
+## Miscellaneous TPS Variables
+##
+## REMINDER: 'Escape' ALL spaces in EACH variable specified below!
+##
+## NOTE: For comparison's sake, if the default instances were manually
+## configured using a Firefox browser, the content of the corresponding
+## "/var/lib/${tps_instance_name}/alias/" security libraries would be
+## something similar to this:
+##
+## Certificate Nickname Trust Attributes
+## SSL,S/MIME,JAR/XPI
+##
+## subsystemCert cert-${tps_instance_name} u,u,u
+## caCert CT,C,C
+## Server-Cert cert-${tps_instance_name} u,u,u
+## auditSigningCert cert-${tps_instance_name} u,u,u
+##
+## where:
+##
+## Nickname: "subsystemCert cert-${tps_instance_name}"
+## Subject Name: "cn=TPS Subsystem Certificate,"
+## + "ou=${tps_instance_name},"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "caCert"
+## Subject Name: "cn=Certificate Authority,"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "Server-Cert cert-${tps_instance_name}"
+## Subject Name: "cn=${pki_host},"
+## + "ou=${tps_instance_name},"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "auditSigningCert cert-${tps_instance_name}"
+## Subject Name: "cn=TPS Audit Signing Certificate,"
+## + "ou=${tps_instance_name},"
+## + "o=${pki_security_domain_name}"
+##
+
+tps_chosen_ca_hostname=${pki_security_domain_host}
+tps_chosen_ca_nonssl_port=${ca_nonssl_port}
+tps_chosen_ca_ssl_port=${ca_ee_port}
+tps_chosen_ca_admin_port=${ca_admin_port}
+tps_chosen_tks_hostname=${pki_host}
+tps_chosen_tks_ssl_port=${tks_ee_port}
+tps_chosen_drm_hostname=${pki_host}
+tps_chosen_drm_ssl_port=${kra_ee_port}
+tps_agent_name="TPS\ Administrator\'s\ ${pki_security_domain_name}\ ID"
+tps_agent_key_size=2048
+tps_agent_key_type=rsa
+tps_agent_cert_subject="cn=TPS\ Administrator,uid=admin,e=${pki_silent_admin_email},o=${pki_security_domain_name}"
+tps_ldap_auth_host=localhost
+tps_ldap_auth_port=389
+tps_ldap_auth_base_dn="dc=${pki_email_company},dc=${pki_email_domain}"
+tps_base_dn="dc=${pki_host}-${tps_instance_name}"
+tps_db_name="${pki_host}-${tps_instance_name}"
+tps_key_size=2048
+tps_key_type=rsa
+tps_ss_keygen=true
+tps_server_cert_subject_name="cn=${pki_host},ou=${tps_instance_name},o=${pki_security_domain_name}"
+tps_server_cert_nickname="Server-Cert\ cert-${tps_instance_name}"
+tps_subsystem_cert_subject_name="cn=TPS\ Subsystem\ Certificate,ou=${tps_instance_name},o=${pki_security_domain_name}"
+tps_subsystem_cert_nickname="subsystemCert\ cert-${tps_instance_name}"
+tps_audit_signing_cert_subject_name="cn=TPS\ Audit\ Signing\ Certificate,ou=${tps_instance_name},o=${pki_security_domain_name}"
+tps_audit_signing_cert_nickname="auditSigningCert\ cert-${tps_instance_name}"
+
+
+
+##############################################################################
+##############################################################################
+## ##
+## P K I S I L E N T - S U B S Y S T E M C O N F I G U R A T I O N ##
+## ##
+##############################################################################
+##############################################################################
+
+##############################################################################
+## P K I S I L E N T I N I T I A L I Z A T I O N ##
+##############################################################################
+
+## (1) Make certain that user has defined all MANDATORY user-defined variables!
+usage_errors=0
+usage_error_preamble="ERROR: User MUST define a value for"
+
+if [ "${pki_silent_security_database_password}" = "" ] ; then
+ printf "${usage_error_preamble} 'pki_silent_security_database_password'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${pki_security_domain_name}" = "" ] ; then
+ printf "${usage_error_preamble} 'pki_security_domain_name'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${pki_security_domain_admin_password}" = "" ] ; then
+ printf "${usage_error_preamble} 'pki_security_domain_admin_password'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${pki_bind_password}" = "" ] ; then
+ printf "${usage_error_preamble} 'pki_bind_password'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${ca_token_password}" = "" ] ; then
+ printf "${usage_error_preamble} 'ca_token_password'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${kra_token_password}" = "" ] ; then
+ printf "${usage_error_preamble} 'kra_token_password'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${ocsp_token_password}" = "" ] ; then
+ printf "${usage_error_preamble} 'ocsp_token_password'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${tks_token_password}" = "" ] ; then
+ printf "${usage_error_preamble} 'tks_token_password'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${ra_token_password}" = "" ] ; then
+ printf "${usage_error_preamble} 'ra_token_password'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${tps_token_password}" = "" ] ; then
+ printf "${usage_error_preamble} 'tps_token_password'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${ca_backup_password}" = "" ] ; then
+ printf "${usage_error_preamble} 'ca_backup_password'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${kra_backup_password}" = "" ] ; then
+ printf "${usage_error_preamble} 'kra_backup_password'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${ocsp_backup_password}" = "" ] ; then
+ printf "${usage_error_preamble} 'ocsp_backup_password'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${tks_backup_password}" = "" ] ; then
+ printf "${usage_error_preamble} 'tks_backup_password'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${pki_email_name}" = "" ] ; then
+ printf "${usage_error_preamble} 'pki_email_name'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${pki_email_company}" = "" ] ; then
+ printf "${usage_error_preamble} 'pki_email_company'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${pki_email_domain}" = "" ] ; then
+ printf "${usage_error_preamble} 'pki_email_domain'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${pki_silent_admin_password}" = "" ] ; then
+ printf "${usage_error_preamble} 'pki_silent_admin_password'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+
+
+## (2) Make certain that a PKI instance of the specified name EXISTS,
+## but has NOT been previously CONFIGURED!
+existence_errors=0
+existence_error_preamble="ERROR: No PKI Instance named"
+configuration_errors=0
+configuration_error_preamble="ERROR: A PKI Instance named"
+configuration_error_postamble="EXISTS,\n but has PREVIOUSLY been CONFIGURED!"
+
+if [ ! -f "/var/lib/${ca_instance_name}/conf/CS.cfg" ] ; then
+ printf "${existence_error_preamble} '${ca_instance_name}' EXISTS!\n"
+ existence_errors=`expr ${existence_errors} + 1`
+else
+ ca_configuration_check=`grep -c preop /var/lib/${ca_instance_name}/conf/CS.cfg`
+ if [ ${ca_configuration_check} -eq 0 ] ; then
+ printf "${configuration_error_preamble} '${ca_instance_name}' "
+ printf "${configuration_error_postamble}\n"
+ configuration_errors=`expr ${configuration_errors} + 1`
+ fi
+fi
+if [ ! -f "/var/lib/${kra_instance_name}/conf/CS.cfg" ] ; then
+ printf "${existence_error_preamble} '${kra_instance_name}' EXISTS!\n"
+ existence_errors=`expr ${existence_errors} + 1`
+else
+ kra_configuration_check=`grep -c preop /var/lib/${kra_instance_name}/conf/CS.cfg`
+ if [ ${kra_configuration_check} -eq 0 ] ; then
+ printf "${configuration_error_preamble} '${kra_instance_name}' "
+ printf "${configuration_error_postamble}\n"
+ configuration_errors=`expr ${configuration_errors} + 1`
+ fi
+fi
+if [ ! -f "/var/lib/${ocsp_instance_name}/conf/CS.cfg" ] ; then
+ printf "${existence_error_preamble} '${ocsp_instance_name}' EXISTS!\n"
+ existence_errors=`expr ${existence_errors} + 1`
+else
+ ocsp_configuration_check=`grep -c preop /var/lib/${ocsp_instance_name}/conf/CS.cfg`
+ if [ ${ocsp_configuration_check} -eq 0 ] ; then
+ printf "${configuration_error_preamble} '${ocsp_instance_name}' "
+ printf "${configuration_error_postamble}\n"
+ configuration_errors=`expr ${configuration_errors} + 1`
+ fi
+fi
+if [ ! -f "/var/lib/${tks_instance_name}/conf/CS.cfg" ] ; then
+ printf "${existence_error_preamble} '${tks_instance_name}' EXISTS!\n"
+ existence_errors=`expr ${existence_errors} + 1`
+else
+ tks_configuration_check=`grep -c preop /var/lib/${tks_instance_name}/conf/CS.cfg`
+ if [ ${tks_configuration_check} -eq 0 ] ; then
+ printf "${configuration_error_preamble} '${tks_instance_name}' "
+ printf "${configuration_error_postamble}\n"
+ configuration_errors=`expr ${configuration_errors} + 1`
+ fi
+fi
+if [ ! -f "/var/lib/${ra_instance_name}/conf/CS.cfg" ] ; then
+ printf "${existence_error_preamble} '${ra_instance_name}' EXISTS!\n"
+ existence_errors=`expr ${existence_errors} + 1`
+else
+ ra_configuration_check=`grep -c preop /var/lib/${ra_instance_name}/conf/CS.cfg`
+ if [ ${ra_configuration_check} -eq 0 ] ; then
+ printf "${configuration_error_preamble} '${ra_instance_name}' "
+ printf "${configuration_error_postamble}\n"
+ configuration_errors=`expr ${configuration_errors} + 1`
+ fi
+fi
+if [ ! -f "/var/lib/${tps_instance_name}/conf/CS.cfg" ] ; then
+ printf "${existence_error_preamble} '${tps_instance_name}' EXISTS!\n"
+ existence_errors=`expr ${existence_errors} + 1`
+else
+ tps_configuration_check=`grep -c preop /var/lib/${tps_instance_name}/conf/CS.cfg`
+ if [ ${tps_configuration_check} -eq 0 ] ; then
+ printf "${configuration_error_preamble} '${tps_instance_name}' "
+ printf "${configuration_error_postamble}\n"
+ configuration_errors=`expr ${configuration_errors} + 1`
+ fi
+fi
+
+
+if [ ${usage_errors} -ne 0 ] ||
+ [ ${existence_errors} -ne 0 ] ||
+ [ ${configuration_errors} -ne 0 ] ; then
+ printf "\n"
+ printf "Please correct ALL errors listed above and re-run\n"
+ printf "the '$0' script!\n\n"
+ exit 255
+fi
+
+
+## (3) Make certain that 'pkisilent' exists and is executable on this system.
+if [ ! -x "/usr/bin/pkisilent" ] ; then
+ printf "\n"
+ printf "ERROR: Please install the 'pki-silent' package and re-run\n"
+ printf "the '$0' script!\n\n"
+ exit 255
+fi
+
+
+## (4) Check for old PKI Silent Security Databases, but DO NOT remove them!
+## Instead, inform the user and exit this script.
+if [ -f "${pki_silent_security_database_repository}/cert8.db" ] ||
+ [ -f "${pki_silent_security_database_repository}/key3.db" ] ||
+ [ -f "${pki_silent_security_database_repository}/secmod.db" ] ; then
+ printf "\n"
+ printf "WARNING: At least one of the security databases\n"
+ printf " (i. e. - 'cert8.db', 'key3.db', and/or 'secmod.db')\n"
+ printf " required by '${pki_silent_script}' exists at the\n"
+ printf " specified location '${pki_silent_security_database_repository}'.\n"
+ printf "\n"
+ printf " Please MANUALLY move or erase these security database(s),\n"
+ printf " or specify a different location before re-running this script.\n\n"
+ exit 255
+fi
+
+
+## (5) Remove ALL old PKI Silent log files
+printf "Removing old PKI Silent log files:\n"
+if [ -f ${pki_silent_ca_log} ] ; then
+ printf " Removing old '${pki_silent_ca_log}' . . . "
+ rm ${pki_silent_ca_log}
+ printf "done.\n"
+fi
+if [ -f ${pki_silent_kra_log} ] ; then
+ printf " Removing old '${pki_silent_kra_log}' . . . "
+ rm ${pki_silent_kra_log}
+ printf "done.\n"
+fi
+if [ -f ${pki_silent_ocsp_log} ] ; then
+ printf " Removing old '${pki_silent_ocsp_log}' . . . "
+ rm ${pki_silent_ocsp_log}
+ printf "done.\n"
+fi
+if [ -f ${pki_silent_tks_log} ] ; then
+ printf " Removing old '${pki_silent_tks_log}' . . . "
+ rm ${pki_silent_tks_log}
+ printf "done.\n"
+fi
+if [ -f ${pki_silent_ra_log} ] ; then
+ printf " Removing old '${pki_silent_ra_log}' . . . "
+ rm ${pki_silent_ra_log}
+ printf "done.\n"
+fi
+if [ -f ${pki_silent_tps_log} ] ; then
+ printf " Removing old '${pki_silent_tps_log}' . . . "
+ rm ${pki_silent_tps_log}
+ printf "done.\n"
+fi
+printf "Done.\n\n"
+
+
+
+##############################################################################
+## C A L C U L A T E P K I I N S T A N C E P I N S ##
+##############################################################################
+
+## PKI Subsystem Instance PINS
+ca_preop_pin=`cat /var/lib/${ca_instance_name}/conf/CS.cfg \
+ | grep preop.pin | grep -v grep | awk -F= '{print $2}'`
+kra_preop_pin=`cat /var/lib/${kra_instance_name}/conf/CS.cfg \
+ | grep preop.pin | grep -v grep | awk -F= '{print $2}'`
+ocsp_preop_pin=`cat /var/lib/${ocsp_instance_name}/conf/CS.cfg \
+ | grep preop.pin | grep -v grep | awk -F= '{print $2}'`
+tks_preop_pin=`cat /var/lib/${tks_instance_name}/conf/CS.cfg \
+ | grep preop.pin | grep -v grep | awk -F= '{print $2}'`
+ra_preop_pin=`cat /var/lib/${ra_instance_name}/conf/CS.cfg \
+ | grep preop.pin | grep -v grep | awk -F= '{print $2}'`
+tps_preop_pin=`cat /var/lib/${tps_instance_name}/conf/CS.cfg \
+ | grep preop.pin | grep -v grep | awk -F= '{print $2}'`
+
+
+
+##############################################################################
+## C E R T I F I C A T E A U T H O R I T Y ##
+##############################################################################
+##
+## For example, upon completion,
+## execute '/sbin/service ${ca_init_script} status ${ca_instance_name}':
+##
+## ${ca_instance_name} (pid 7843) is running ...
+##
+## Unsecure Port = http://${pki_host}:9180/ca/ee/ca
+## Secure Agent Port = https://${pki_host}:9443/ca/agent/ca
+## Secure EE Port = https://${pki_host}:9444/ca/ee/ca
+## Secure Admin Port = https://${pki_host}:9445/ca/services
+## PKI Console Port = pkiconsole https://${pki_host}:9445/ca
+## Tomcat Port = 9701 (for shutdown)
+##
+##
+## Security Domain URL:
+## ==================================================================
+## https://${pki_host}:9445
+## ==================================================================
+##
+
+## Configure CA
+printf "'${pki_silent_script}': Configuring '${ca_instance_name}' . . .\n"
+pkisilent ConfigureCA \
+ -cs_hostname "${pki_host}" \
+ -cs_port ${ca_admin_port} \
+ -client_certdb_dir ${pki_silent_security_database_repository} \
+ -client_certdb_pwd ${pki_silent_security_database_password} \
+ -preop_pin ${ca_preop_pin} \
+ -domain_name "${pki_security_domain_name}" \
+ -admin_user ${pki_silent_admin_user} \
+ -admin_password ${pki_silent_admin_password} \
+ -admin_email "${pki_silent_admin_email}" \
+ -agent_name ${ca_agent_name} \
+ -agent_key_size ${ca_agent_key_size} \
+ -agent_key_type ${ca_agent_key_type} \
+ -agent_cert_subject "${ca_agent_cert_subject}" \
+ -ldap_host ${pki_ldap_host} \
+ -ldap_port ${pki_ldap_port} \
+ -bind_dn "${pki_bind_dn}" \
+ -bind_password ${pki_bind_password} \
+ -base_dn "${ca_base_dn}" \
+ -db_name "${ca_db_name}" \
+ -key_size ${ca_key_size} \
+ -key_type ${ca_key_type} \
+ -key_algorithm ${ca_key_algorithm} \
+ -signing_algorithm ${ca_signing_algorithm} \
+ -signing_signingalgorithm ${ca_signing_signingalgorithm} \
+ -ocsp_signing_signingalgorithm ${ca_ocsp_signing_signingalgorithm} \
+ -save_p12 ${ca_save_p12} \
+ -subsystem_name ${ca_subsystem_name} \
+ -token_name ${ca_token_name} \
+ -token_pwd ${ca_token_password} \
+ -ca_sign_cert_subject_name "${ca_sign_cert_subject_name}" \
+ -ca_subsystem_cert_subject_name "${ca_subsystem_cert_subject_name}" \
+ -ca_ocsp_cert_subject_name "${ca_ocsp_cert_subject_name}" \
+ -ca_server_cert_subject_name "${ca_server_cert_subject_name}" \
+ -ca_audit_signing_cert_subject_name \
+ "${ca_audit_signing_cert_subject_name}" \
+ | tee ${pki_silent_ca_log}
+
+## Restart CA
+/sbin/service ${ca_init_script} restart ${ca_instance_name}
+
+
+##############################################################################
+## C E R T I F I C A T E A U T H O R I T Y (Clone) ##
+##############################################################################
+##
+## Use this to create a clone CA ..
+##
+## For example, upon completion,
+## execute '/sbin/service ${ca_init_script} status ${ca_instance_name}':
+##
+## ${ca_instance_name} (pid 7843) is running ...
+##
+## Unsecure Port = http://${pki_host}:9180/ca/ee/ca
+## Secure Agent Port = https://${pki_host}:9443/ca/agent/ca
+## Secure EE Port = https://${pki_host}:9444/ca/ee/ca
+## Secure Admin Port = https://${pki_host}:9445/ca/services
+## PKI Console Port = pkiconsole https://${pki_host}:9445/ca
+## Tomcat Port = 9701 (for shutdown)
+##
+##
+## Security Domain URL:
+## ==================================================================
+## https://${pki_host}:9445
+## ==================================================================
+##
+
+## Configure clone CA
+# printf "'${pki_silent_script}': Configuring '${ca_instance_name}' . . .\n"
+# pkisilent ConfigureCA \
+# -cs_hostname "${pki_host}" \
+# -cs_port ${ca_admin_port} \
+# -client_certdb_dir ${pki_silent_security_database_repository} \
+# -client_certdb_pwd ${pki_silent_security_database_password} \
+# -preop_pin ${ca_preop_pin} \
+# -domain_name "${pki_security_domain_name}" \
+# -admin_user ${pki_silent_admin_user} \
+# -admin_password ${pki_silent_admin_password} \
+# -admin_email "${pki_silent_admin_email}" \
+# -agent_name ${ca_agent_name} \
+# -agent_key_size ${ca_agent_key_size} \
+# -agent_key_type ${ca_agent_key_type} \
+# -agent_cert_subject "${ca_agent_cert_subject}" \
+# -ldap_host ${pki_ldap_host} \
+# -ldap_port ${pki_ldap_port} \
+# -bind_dn "${pki_bind_dn}" \
+# -bind_password ${pki_bind_password} \
+# -base_dn "${ca_base_dn}" \
+# -db_name "${ca_db_name}" \
+# -key_size ${ca_key_size} \
+# -key_type ${ca_key_type} \
+# -key_algorithm ${ca_key_algorithm} \
+# -save_p12 ${ca_save_p12} \
+# -subsystem_name ${ca_subsystem_name} \
+# -token_name ${ca_token_name} \
+# -token_pwd ${ca_token_password} \
+# -ca_sign_cert_subject_name "${ca_sign_cert_subject_name}" \
+# -ca_subsystem_cert_subject_name "${ca_subsystem_cert_subject_name}" \
+# -ca_ocsp_cert_subject_name "${ca_ocsp_cert_subject_name}" \
+# -ca_server_cert_subject_name "${ca_server_cert_subject_name}" \
+# -ca_audit_signing_cert_subject_name \
+# "${ca_audit_signing_cert_subject_name}" \
+# -clone ${ca_clone} \
+# -clone_p12_file ${ca_clone_p12_file} \
+# -clone_p12_password ${ca_clone_p12_password} \
+# -clone_uri ${clone_uri} \
+# -sd_hostname ${sd_hostname} \
+# -sd_admin_port ${sd_admin_port} \
+# -sd_admin_name ${sd_admin_name} \
+# -sd_admin_password ${sd_admin_password} \
+# -clone_start_tls ${clone_start_tls} \
+# | tee ${pki_silent_ca_log}
+
+## Restart CA
+#/sbin/service ${ca_init_script} restart ${ca_instance_name}
+
+##############################################################################
+## C E R T I F I C A T E A U T H O R I T Y (External CA - step 1) ##
+##############################################################################
+##
+## Use this invocation for the first step in creating a CA signed by
+## and external CA ..
+##
+## For example, upon completion,
+##
+## A Certificate Request has been generated and stored in /tmp/ext_ca_csr.csr
+## Please submit this CSR to your external CA and obtain the CA Cert and CA Cert Chain"
+
+## Configure CA signed by external CA (step 1)
+# printf "'${pki_silent_script}': First step in configuring '${ca_instance_name}' . . .\n"
+# pkisilent ConfigureCA \
+# -cs_hostname "${pki_host}" \
+# -cs_port ${ca_admin_port} \
+# -client_certdb_dir ${pki_silent_security_database_repository} \
+# -client_certdb_pwd ${pki_silent_security_database_password} \
+# -preop_pin ${ca_preop_pin} \
+# -domain_name "${pki_security_domain_name}" \
+# -admin_user ${pki_silent_admin_user} \
+# -admin_password ${pki_silent_admin_password} \
+# -admin_email "${pki_silent_admin_email}" \
+# -agent_name ${ca_agent_name} \
+# -agent_key_size ${ca_agent_key_size} \
+# -agent_key_type ${ca_agent_key_type} \
+# -agent_cert_subject "${ca_agent_cert_subject}" \
+# -ldap_host ${pki_ldap_host} \
+# -ldap_port ${pki_ldap_port} \
+# -bind_dn "${pki_bind_dn}" \
+# -bind_password ${pki_bind_password} \
+# -base_dn "${ca_base_dn}" \
+# -db_name "${ca_db_name}" \
+# -key_size ${ca_key_size} \
+# -key_type ${ca_key_type} \
+# -key_algorithm ${ca_key_algorithm} \
+# -signing_algorithm ${ca_signing_algorithm} \
+# -signing_signingalgorithm ${ca_signing_signingalgorithm} \
+# -ocsp_signing_signingalgorithm ${ca_ocsp_signing_signingalgorithm} \
+# -save_p12 ${ca_save_p12} \
+# -subsystem_name ${ca_subsystem_name} \
+# -token_name ${ca_token_name} \
+# -token_pwd ${ca_token_password} \
+# -ca_sign_cert_subject_name "${ca_sign_cert_subject_name}" \
+# -ca_subsystem_cert_subject_name "${ca_subsystem_cert_subject_name}" \
+# -ca_ocsp_cert_subject_name "${ca_ocsp_cert_subject_name}" \
+# -ca_server_cert_subject_name "${ca_server_cert_subject_name}" \
+# -ca_audit_signing_cert_subject_name \
+# "${ca_audit_signing_cert_subject_name}" \
+# -external ${ca_external} \
+# -ext_csr_file ${ca_ext_csr_file} \
+# | tee ${pki_silent_ca_log}
+
+## Restart CA
+#/sbin/service ${ca_init_script} restart ${ca_instance_name}
+
+##############################################################################
+## C E R T I F I C A T E A U T H O R I T Y (External CA step 2) ##
+##############################################################################
+##
+## Use this to create a CA signed by an external CA (step 2)
+##
+## For example, upon completion,
+## execute '/sbin/service ${ca_init_script} status ${ca_instance_name}':
+##
+## ${ca_instance_name} (pid 7843) is running ...
+##
+## Unsecure Port = http://${pki_host}:9180/ca/ee/ca
+## Secure Agent Port = https://${pki_host}:9443/ca/agent/ca
+## Secure EE Port = https://${pki_host}:9444/ca/ee/ca
+## Secure Admin Port = https://${pki_host}:9445/ca/services
+## PKI Console Port = pkiconsole https://${pki_host}:9445/ca
+## Tomcat Port = 9701 (for shutdown)
+##
+##
+## Security Domain URL:
+## ==================================================================
+## https://${pki_host}:9445
+## ==================================================================
+##
+
+## Configure an externally signed CA (step 2)
+# printf "'${pki_silent_script}': Step 2 in configuring external signed '${ca_instance_name}' . . .\n"
+# pkisilent ConfigureCA \
+# -cs_hostname "${pki_host}" \
+# -cs_port ${ca_admin_port} \
+# -client_certdb_dir ${pki_silent_security_database_repository} \
+# -client_certdb_pwd ${pki_silent_security_database_password} \
+# -preop_pin ${ca_preop_pin} \
+# -domain_name "${pki_security_domain_name}" \
+# -admin_user ${pki_silent_admin_user} \
+# -admin_password ${pki_silent_admin_password} \
+# -admin_email "${pki_silent_admin_email}" \
+# -agent_name ${ca_agent_name} \
+# -agent_key_size ${ca_agent_key_size} \
+# -agent_key_type ${ca_agent_key_type} \
+# -agent_cert_subject "${ca_agent_cert_subject}" \
+# -ldap_host ${pki_ldap_host} \
+# -ldap_port ${pki_ldap_port} \
+# -bind_dn "${pki_bind_dn}" \
+# -bind_password ${pki_bind_password} \
+# -base_dn "${ca_base_dn}" \
+# -db_name "${ca_db_name}" \
+# -key_size ${ca_key_size} \
+# -key_type ${ca_key_type} \
+# -key_algorithm ${ca_key_algorithm} \
+# -signing_algorithm ${ca_signing_algorithm} \
+# -signing_signingalgorithm ${ca_signing_signingalgorithm} \
+# -ocsp_signing_signingalgorithm ${ca_ocsp_signing_signingalgorithm} \
+# -save_p12 ${ca_save_p12} \
+# -subsystem_name ${ca_subsystem_name} \
+# -token_name ${ca_token_name} \
+# -token_pwd ${ca_token_password} \
+# -ca_sign_cert_subject_name "${ca_sign_cert_subject_name}" \
+# -ca_subsystem_cert_subject_name "${ca_subsystem_cert_subject_name}" \
+# -ca_ocsp_cert_subject_name "${ca_ocsp_cert_subject_name}" \
+# -ca_server_cert_subject_name "${ca_server_cert_subject_name}" \
+# -ca_audit_signing_cert_subject_name \
+# "${ca_audit_signing_cert_subject_name}" \
+# -external ${ca_external} \
+# -ext_ca_cert_file ${ca_ext_cert_file} \
+# -ext_ca_cert_chain_file ${ca_ext_cert_chain_file} \
+# | tee ${pki_silent_ca_log}
+
+## Restart CA
+#/sbin/service ${ca_init_script} restart ${ca_instance_name}
+
+##############################################################################
+## D A T A R E C O V E R Y M A N A G E R ##
+##############################################################################
+##
+## For example, upon completion,
+## execute '/sbin/service ${kra_init_script} status ${kra_instance_name}':
+##
+## ${kra_instance_name} (pid 11723) is running ...
+##
+## Unsecure Port = http://${pki_host}:10180/kra/ee/kra
+## Secure Agent Port = https://${pki_host}:10443/kra/agent/kra
+## Secure EE Port = https://${pki_host}:10444/kra/ee/kra
+## Secure Admin Port = https://${pki_host}:10445/kra/services
+## PKI Console Port = pkiconsole https://${pki_host}:10445/kra
+## Tomcat Port = 10701 (for shutdown)
+##
+
+## Configure DRM
+printf "'${pki_silent_script}': Configuring '${kra_instance_name}' . . .\n"
+pkisilent ConfigureDRM \
+ -cs_hostname "${pki_host}" \
+ -cs_port ${kra_admin_port} \
+ -sd_hostname "${pki_security_domain_host}" \
+ -sd_ssl_port ${ca_ee_port} \
+ -sd_agent_port ${ca_agent_port} \
+ -sd_admin_port ${ca_admin_port} \
+ -sd_admin_name "${pki_security_domain_admin_name}" \
+ -sd_admin_password ${pki_security_domain_admin_password} \
+ -ca_hostname ${pki_security_domain_host} \
+ -ca_port ${ca_nonssl_port} \
+ -ca_ssl_port ${ca_ee_port} \
+ -client_certdb_dir ${pki_silent_security_database_repository} \
+ -client_certdb_pwd ${pki_silent_security_database_password} \
+ -preop_pin ${kra_preop_pin} \
+ -domain_name "${pki_security_domain_name}" \
+ -admin_user ${pki_silent_admin_user} \
+ -admin_password ${pki_silent_admin_password} \
+ -admin_email "${pki_silent_admin_email}" \
+ -agent_name ${kra_agent_name} \
+ -ldap_host ${pki_ldap_host} \
+ -ldap_port ${pki_ldap_port} \
+ -bind_dn "${pki_bind_dn}" \
+ -bind_password ${pki_bind_password} \
+ -base_dn "${kra_base_dn}" \
+ -db_name "${kra_db_name}" \
+ -key_size ${kra_key_size} \
+ -key_type ${kra_key_type} \
+ -token_name ${kra_token_name} \
+ -token_pwd ${kra_token_password} \
+ -agent_key_size ${kra_agent_key_size} \
+ -agent_key_type ${kra_agent_key_type} \
+ -agent_cert_subject "${kra_agent_cert_subject}" \
+ -subsystem_name ${kra_subsystem_name} \
+ -backup_pwd ${kra_backup_password} \
+ -drm_transport_cert_subject_name "${kra_transport_cert_subject_name}" \
+ -drm_subsystem_cert_subject_name "${kra_subsystem_cert_subject_name}" \
+ -drm_storage_cert_subject_name "${kra_storage_cert_subject_name}" \
+ -drm_server_cert_subject_name "${kra_server_cert_subject_name}" \
+ -drm_audit_signing_cert_subject_name \
+ "${kra_audit_signing_cert_subject_name}" \
+ | tee ${pki_silent_kra_log}
+
+## Restart drm
+/sbin/service ${kra_init_script} restart ${kra_instance_name}
+
+
+##############################################################################
+## D A T A R E C O V E R Y M A N A G E R (clone) ##
+##############################################################################
+##
+## Use this to configure a DRM clone.
+##
+## For example, upon completion,
+## execute '/sbin/service ${kra_init_script} status ${kra_instance_name}':
+##
+## ${kra_instance_name} (pid 11723) is running ...
+##
+## Unsecure Port = http://${pki_host}:10180/kra/ee/kra
+## Secure Agent Port = https://${pki_host}:10443/kra/agent/kra
+## Secure EE Port = https://${pki_host}:10444/kra/ee/kra
+## Secure Admin Port = https://${pki_host}:10445/kra/services
+## PKI Console Port = pkiconsole https://${pki_host}:10445/kra
+## Tomcat Port = 10701 (for shutdown)
+##
+
+## Configure DRM
+# printf "'${pki_silent_script}': Configuring '${kra_instance_name}' . . .\n"
+# pkisilent ConfigureDRM \
+# -cs_hostname "${pki_host}" \
+# -cs_port ${kra_admin_port} \
+# -sd_hostname "${pki_security_domain_host}" \
+# -sd_ssl_port ${ca_ee_port} \
+# -sd_agent_port ${ca_agent_port} \
+# -sd_admin_port ${ca_admin_port} \
+# -sd_admin_name "${pki_security_domain_admin_name}" \
+# -sd_admin_password ${pki_security_domain_admin_password} \
+# -ca_hostname ${pki_security_domain_host} \
+# -ca_port ${ca_nonssl_port} \
+# -ca_ssl_port ${ca_ee_port} \
+# -client_certdb_dir ${pki_silent_security_database_repository} \
+# -client_certdb_pwd ${pki_silent_security_database_password} \
+# -preop_pin ${kra_preop_pin} \
+# -domain_name "${pki_security_domain_name}" \
+# -admin_user ${pki_silent_admin_user} \
+# -admin_password ${pki_silent_admin_password} \
+# -admin_email "${pki_silent_admin_email}" \
+# -agent_name ${kra_agent_name} \
+# -ldap_host ${pki_ldap_host} \
+# -ldap_port ${pki_ldap_port} \
+# -bind_dn "${pki_bind_dn}" \
+# -bind_password ${pki_bind_password} \
+# -base_dn "${kra_base_dn}" \
+# -db_name "${kra_db_name}" \
+# -key_size ${kra_key_size} \
+# -key_type ${kra_key_type} \
+# -token_name ${kra_token_name} \
+# -token_pwd ${kra_token_password} \
+# -agent_key_size ${kra_agent_key_size} \
+# -agent_key_type ${kra_agent_key_type} \
+# -agent_cert_subject "${kra_agent_cert_subject}" \
+# -subsystem_name ${kra_subsystem_name} \
+# -backup_pwd ${kra_backup_password} \
+# -drm_transport_cert_subject_name "${kra_transport_cert_subject_name}" \
+# -drm_subsystem_cert_subject_name "${kra_subsystem_cert_subject_name}" \
+# -drm_storage_cert_subject_name "${kra_storage_cert_subject_name}" \
+# -drm_server_cert_subject_name "${kra_server_cert_subject_name}" \
+# -drm_audit_signing_cert_subject_name \
+# "${kra_audit_signing_cert_subject_name}" \
+# -clone ${kra_clone} \
+# -clone_p12_file ${kra_clone_p12_file} \
+# -clone_p12_password ${kra_clone_p12_password} \
+# -clone_uri ${kra_uri} \
+# -clone_start_tls ${clone_start_tls} \
+# | tee ${pki_silent_kra_log}
+
+## Restart drm
+#/sbin/service ${kra_init_script} restart ${kra_instance_name}
+
+
+##############################################################################
+## O N L I N E S T A T U S C E R T I F I C A T E P R O T O C O L ##
+###############################################################################
+##
+## For example, upon completion,
+## execute '/sbin/service ${ocsp_init_script} status ${ocsp_instance_name}':
+##
+## ${ocsp_instance_name} (pid 13058) is running ...
+##
+## Unsecure Port = http://${pki_host}:11180/ocsp/ee/ocsp
+## Secure Agent Port = https://${pki_host}:11443/ocsp/agent/ocsp
+## Secure EE Port = https://${pki_host}:11444/ocsp/ee/ocsp
+## Secure Admin Port = https://${pki_host}:11445/ocsp/services
+## PKI Console Port = pkiconsole https://${pki_host}:11445/ocsp
+## Tomcat Port = 11701 (for shutdown)
+##
+
+## Configure OCSP
+printf "'${pki_silent_script}': Configuring '${ocsp_instance_name}' . . .\n"
+pkisilent ConfigureOCSP \
+ -cs_hostname "${pki_host}" \
+ -cs_port ${ocsp_admin_port} \
+ -sd_hostname "${pki_security_domain_host}" \
+ -sd_ssl_port ${ca_ee_port} \
+ -sd_agent_port ${ca_agent_port} \
+ -sd_admin_port ${ca_admin_port} \
+ -sd_admin_name "${pki_security_domain_admin_name}" \
+ -sd_admin_password ${pki_security_domain_admin_password} \
+ -ca_hostname ${pki_security_domain_host} \
+ -ca_port ${ca_nonssl_port} \
+ -ca_ssl_port ${ca_ee_port} \
+ -client_certdb_dir ${pki_silent_security_database_repository} \
+ -client_certdb_pwd ${pki_silent_security_database_password} \
+ -preop_pin ${ocsp_preop_pin} \
+ -domain_name "${pki_security_domain_name}" \
+ -admin_user ${pki_silent_admin_user} \
+ -admin_password ${pki_silent_admin_password} \
+ -admin_email "${pki_silent_admin_email}" \
+ -agent_name ${ocsp_agent_name} \
+ -ldap_host ${pki_ldap_host} \
+ -ldap_port ${pki_ldap_port} \
+ -bind_dn "${pki_bind_dn}" \
+ -bind_password ${pki_bind_password} \
+ -base_dn "${ocsp_base_dn}" \
+ -db_name "${ocsp_db_name}" \
+ -key_size ${ocsp_key_size} \
+ -key_type ${ocsp_key_type} \
+ -token_name ${ocsp_token_name} \
+ -token_pwd ${ocsp_token_password} \
+ -agent_key_size ${ocsp_agent_key_size} \
+ -agent_key_type ${ocsp_agent_key_type} \
+ -agent_cert_subject "${ocsp_agent_cert_subject}" \
+ -subsystem_name ${ocsp_subsystem_name} \
+ -backup_pwd ${ocsp_backup_password} \
+ -ocsp_sign_cert_subject_name "${ocsp_sign_cert_subject_name}" \
+ -ocsp_subsystem_cert_subject_name "${ocsp_subsystem_cert_subject_name}" \
+ -ocsp_server_cert_subject_name "${ocsp_server_cert_subject_name}" \
+ -ocsp_audit_signing_cert_subject_name \
+ "${ocsp_audit_signing_cert_subject_name}" \
+ | tee ${pki_silent_ocsp_log}
+
+## Restart OCSP
+/sbin/service ${ocsp_init_script} restart ${ocsp_instance_name}
+
+
+
+##############################################################################
+## T O K E N K E Y S E R V I C E ##
+##############################################################################
+##
+## For example, upon completion,
+## execute '/sbin/service ${tks_init_script} status ${tks_instance_name}':
+##
+## ${tks_instance_name} (pid 14129) is running ...
+##
+## Unsecure Port = http://${pki_host}:13180/tks/ee/tks
+## Secure Agent Port = https://${pki_host}:13443/tks/agent/tks
+## Secure EE Port = https://${pki_host}:13444/tks/ee/tks
+## Secure Admin Port = https://${pki_host}:13445/tks/services
+## PKI Console Port = pkiconsole https://${pki_host}:13445/tks
+## Tomcat Port = 13701 (for shutdown)
+##
+
+## Configure TKS
+printf "'${pki_silent_script}': Configuring '${tks_instance_name}' . . .\n"
+pkisilent ConfigureTKS \
+ -cs_hostname "${pki_host}" \
+ -cs_port ${tks_admin_port} \
+ -sd_hostname "${pki_security_domain_host}" \
+ -sd_ssl_port ${ca_ee_port} \
+ -sd_agent_port ${ca_agent_port} \
+ -sd_admin_port ${ca_admin_port} \
+ -sd_admin_name "${pki_security_domain_admin_name}" \
+ -sd_admin_password ${pki_security_domain_admin_password} \
+ -ca_hostname ${pki_security_domain_host} \
+ -ca_port ${ca_nonssl_port} \
+ -ca_ssl_port ${ca_ee_port} \
+ -client_certdb_dir ${pki_silent_security_database_repository} \
+ -client_certdb_pwd ${pki_silent_security_database_password} \
+ -preop_pin ${tks_preop_pin} \
+ -domain_name "${pki_security_domain_name}" \
+ -admin_user ${pki_silent_admin_user} \
+ -admin_password ${pki_silent_admin_password} \
+ -admin_email "${pki_silent_admin_email}" \
+ -agent_name ${tks_agent_name} \
+ -ldap_host ${pki_ldap_host} \
+ -ldap_port ${pki_ldap_port} \
+ -bind_dn "${pki_bind_dn}" \
+ -bind_password ${pki_bind_password} \
+ -base_dn "${tks_base_dn}" \
+ -db_name "${tks_db_name}" \
+ -key_size ${tks_key_size} \
+ -key_type ${tks_key_type} \
+ -token_name ${tks_token_name} \
+ -token_pwd ${tks_token_password} \
+ -agent_key_size ${tks_agent_key_size} \
+ -agent_key_type ${tks_agent_key_type} \
+ -agent_cert_subject "${tks_agent_cert_subject}" \
+ -subsystem_name ${tks_subsystem_name} \
+ -backup_pwd ${tks_backup_password} \
+ -tks_subsystem_cert_subject_name "${tks_subsystem_cert_subject_name}" \
+ -tks_server_cert_subject_name "${tks_server_cert_subject_name}" \
+ -tks_audit_signing_cert_subject_name \
+ "${tks_audit_signing_cert_subject_name}" \
+ | tee ${pki_silent_tks_log}
+
+## restart tks
+/sbin/service ${tks_init_script} restart ${tks_instance_name}
+
+
+
+##############################################################################
+## R E G I S T R A T I O N A U T H O R I T Y ##
+##############################################################################
+##
+## For example, upon completion,
+## execute '/sbin/service ${ra_init_script} status ${ra_instance_name}':
+##
+## ${ra_instance_name} (pid 15769) is running ...
+##
+## Unsecure Port = http://${pki_host}:12888
+## Secure Clientauth Port = https://${pki_host}:12889
+## Secure Non-Clientauth Port = https://${pki_host}:12890
+##
+
+## Configure RA
+printf "'${pki_silent_script}': Configuring '${ra_instance_name}' . . .\n"
+pkisilent ConfigureRA \
+ -cs_hostname "${pki_host}" \
+ -cs_port ${ra_nonclientauth_port} \
+ -cs_clientauth_port ${ra_clientauth_port} \
+ -sd_hostname "${pki_security_domain_host}" \
+ -sd_ssl_port ${ca_ee_port} \
+ -sd_agent_port ${ca_agent_port} \
+ -sd_admin_port ${ca_admin_port} \
+ -sd_admin_name "${pki_security_domain_admin_name}" \
+ -sd_admin_password ${pki_security_domain_admin_password} \
+ -ca_hostname ${ra_chosen_ca_hostname} \
+ -ca_port ${ra_chosen_ca_nonssl_port} \
+ -ca_ssl_port ${ra_chosen_ca_ssl_port} \
+ -ca_admin_port ${ra_chosen_ca_admin_port} \
+ -client_certdb_dir ${pki_silent_security_database_repository} \
+ -client_certdb_pwd ${pki_silent_security_database_password} \
+ -preop_pin ${ra_preop_pin} \
+ -domain_name "${pki_security_domain_name}" \
+ -admin_user ${pki_silent_admin_user} \
+ -admin_password ${pki_silent_admin_password} \
+ -admin_email "${pki_silent_admin_email}" \
+ -agent_name ${ra_agent_name} \
+ -key_size ${ra_key_size} \
+ -key_type ${ra_key_type} \
+ -token_name ${ra_token_name} \
+ -token_pwd ${ra_token_password} \
+ -agent_key_size ${ra_agent_key_size} \
+ -agent_key_type ${ra_agent_key_type} \
+ -agent_cert_subject "${ra_agent_cert_subject}" \
+ -subsystem_name ${ra_subsystem_name} \
+ -ra_server_cert_nickname "${ra_server_cert_nickname}" \
+ -ra_server_cert_subject_name "${ra_server_cert_subject_name}" \
+ -ra_subsystem_cert_nickname "${ra_subsystem_cert_nickname}" \
+ -ra_subsystem_cert_subject_name "${ra_subsystem_cert_subject_name}" \
+ | tee ${pki_silent_ra_log}
+
+## Restart RA
+/sbin/service ${ra_init_script} restart ${ra_instance_name}
+
+
+##############################################################################
+## T O K E N P R O C E S S I N G S Y S T E M ##
+##############################################################################
+##
+## For example, upon completion,
+## execute '/sbin/service ${tps_init_script} status ${tps_instance_name}':
+##
+##
+## ${tps_instance_name} (pid 16241) is running ...
+##
+## Unsecure Port = http://${pki_host}:7888/cgi-bin/so/enroll.cgi
+## (ESC Security Officer Enrollment)
+## Unsecure Port = http://${pki_host}:7888/cgi-bin/home/index.cgi
+## (ESC Phone Home)
+## Secure Clientauth Port = https://${pki_host}:7889/cgi-bin/sow/welcome.cgi
+## (ESC Security Officer Workstation)
+## Secure Clientauth Port = https://${pki_host}:7889/tus
+## (TPS Roles - Operator/Administrator/Agent)
+## Secure Non-Clientauth Port = https://${pki_host}:7890/cgi-bin/so/enroll.cgi
+## (ESC Security Officer Enrollment)
+## Secure Non-Clientauth Port = https://${pki_host}:7890/cgi-bin/home/index.cgi
+## (ESC Phone Home)
+##
+
+## Configure TPS
+printf "'${pki_silent_script}': Configuring '${tps_instance_name}' . . .\n"
+pkisilent ConfigureTPS \
+ -cs_hostname "${pki_host}" \
+ -cs_port ${tps_nonclientauth_port} \
+ -cs_clientauth_port ${tps_clientauth_port} \
+ -sd_hostname "${pki_security_domain_host}" \
+ -sd_ssl_port ${ca_ee_port} \
+ -sd_agent_port ${ca_agent_port} \
+ -sd_admin_port ${ca_admin_port} \
+ -sd_admin_name "${pki_security_domain_admin_name}" \
+ -sd_admin_password ${pki_security_domain_admin_password} \
+ -ca_hostname ${tps_chosen_ca_hostname} \
+ -ca_port ${tps_chosen_ca_nonssl_port} \
+ -ca_ssl_port ${tps_chosen_ca_ssl_port} \
+ -ca_admin_port ${tps_chosen_ca_admin_port} \
+ -drm_hostname ${tps_chosen_drm_hostname} \
+ -drm_ssl_port ${tps_chosen_drm_ssl_port} \
+ -ss_keygen ${tps_ss_keygen} \
+ -tks_hostname ${tps_chosen_tks_hostname} \
+ -tks_ssl_port ${tps_chosen_tks_ssl_port} \
+ -client_certdb_dir ${pki_silent_security_database_repository} \
+ -client_certdb_pwd ${pki_silent_security_database_password} \
+ -preop_pin ${tps_preop_pin} \
+ -domain_name "${pki_security_domain_name}" \
+ -admin_user ${pki_silent_admin_user} \
+ -admin_password ${pki_silent_admin_password} \
+ -admin_email "${pki_silent_admin_email}" \
+ -agent_name ${tps_agent_name} \
+ -ldap_host ${pki_ldap_host} \
+ -ldap_port ${pki_ldap_port} \
+ -bind_dn "${pki_bind_dn}" \
+ -bind_password ${pki_bind_password} \
+ -base_dn "${tps_base_dn}" \
+ -db_name "${tps_db_name}" \
+ -key_size ${tps_key_size} \
+ -key_type ${tps_key_type} \
+ -token_name ${tps_token_name} \
+ -token_pwd ${tps_token_password} \
+ -agent_key_size ${tps_agent_key_size} \
+ -agent_key_type ${tps_agent_key_type} \
+ -agent_cert_subject "${tps_agent_cert_subject}" \
+ -subsystem_name ${tps_subsystem_name} \
+ -ldap_auth_host ${tps_ldap_auth_host} \
+ -ldap_auth_port ${tps_ldap_auth_port} \
+ -ldap_auth_base_dn ${tps_ldap_auth_base_dn} \
+ -tps_server_cert_subject_name "${tps_server_cert_subject_name}" \
+ -tps_server_cert_nickname "${tps_server_cert_nickname}" \
+ -tps_subsystem_cert_subject_name "${tps_subsystem_cert_subject_name}" \
+ -tps_subsystem_cert_nickname "${tps_subsystem_cert_nickname}" \
+ -tps_audit_signing_cert_subject_name \
+ "${tps_audit_signing_cert_subject_name}" \
+ -tps_audit_signing_cert_nickname \
+ "${tps_audit_signing_cert_nickname}" \
+ | tee ${pki_silent_tps_log}
+
+## Restart TPS
+/sbin/service ${tps_init_script} restart ${tps_instance_name}
+
+exit 0
+
diff --git a/base/silent/templates/subca_silent.template b/base/silent/templates/subca_silent.template
new file mode 100755
index 000000000..1475996d1
--- /dev/null
+++ b/base/silent/templates/subca_silent.template
@@ -0,0 +1,513 @@
+#!/bin/bash
+## BEGIN COPYRIGHT BLOCK
+## (C) 2009 Red Hat, Inc.
+## All rights reserved.
+## END COPYRIGHT BLOCK
+
+
+## Always switch into this base directory
+## prior to script execution so that all
+## of its output is written to this directory
+
+cd `dirname $0`
+
+
+## Disallow script to be run as the name of this template
+subca_silent_script=`basename $0`
+if [ "${subca_silent_script}" = "subca_silent.template" ] ; then
+ printf "\n"
+ printf "Usage: (1) Install AND configure a directory server instance.\n\n"
+ printf " (2) Install AND configure a Root CA subsystem instance\n"
+ printf " that is its own security domain.\n\n"
+ printf " (3) Use 'pkicreate' to install a second CA subsystem\n"
+ printf " instance (this will become a Subordinate CA).\n"
+ printf " [Do NOT configure this CA subsystem instance!]\n\n"
+ printf " (4) Install the 'pki-silent' package.\n\n"
+ printf " (5) Copy '$0' to a new script name\n"
+ printf " without the '.template' extension.\n"
+ printf " (e .g. - 'configure_subca_instance')\n\n"
+ printf " (6) Fill in all MANDATORY user-defined variables\n"
+ printf " in the new script.\n\n"
+ printf " (7) Change any OPTIONAL user-defined variables\n"
+ printf " in the new script as desired.\n\n"
+ printf " (8) Become the 'root' user, and execute the new script to\n"
+ printf " configure a Subordinate CA subsystem instance.\n\n"
+ exit 255
+fi
+
+
+##
+## This script MUST be run as root!
+##
+
+ROOTUID=0
+
+OS=`uname`
+if [ "${OS}" = "Linux" ] ; then
+ MY_EUID=`/usr/bin/id -u`
+ MY_UID=`/usr/bin/id -ur`
+ USERNAME=`/usr/bin/id -un`
+else
+ printf "ERROR: Unsupported operating system '${OS}'!\n"
+ exit 255
+fi
+
+if [ "${MY_UID}" != "${ROOTUID}" ] &&
+ [ "${MY_EUID}" != "${ROOTUID}" ] ; then
+ printf "ERROR: The '$0' script must be run as root!\n"
+ exit 255
+fi
+
+
+
+##############################################################################
+##############################################################################
+## ##
+## P K I S I L E N T - V A R I A B L E D E C L A R A T I O N ##
+## ##
+##############################################################################
+##############################################################################
+
+##############################################################################
+## U S E R - D E F I N E D V A R I A B L E S ( M A N D A T O R Y ) ##
+##############################################################################
+
+##
+## IMPORTANT: 'Escape' ALL spaces in EACH variable specified below!
+##
+## For Example:
+##
+## pki_security_domain_name="My\ Security\ Domain"
+##
+
+## PKI Silent Security Database Variables
+## (e. g. - PKI Silent "browser" database)
+pki_silent_security_database_repository="/tmp"
+pki_silent_security_database_password=
+
+## PKI Security Domain Variables
+## (e. g. - Security Domain Login Panel)
+pki_security_domain_name=
+pki_security_domain_host=`hostname`
+pki_security_domain_admin_name=admin
+pki_security_domain_admin_password=
+
+## PKI Internal LDAP Database Variables
+## (e. g. - Database Panel)
+pki_ldap_host=localhost
+pki_ldap_port=389
+pki_bind_dn="cn=Directory\ Manager"
+pki_bind_password=
+
+## PKI Instance-Specific Token Variables
+## (e. g. - Module Panel)
+subca_token_name=internal
+subca_token_password=
+
+## PKI Instance-Specific Backup Variables
+## (e. g. - Backup Key and Certificates Panel)
+subca_backup_password=
+
+## PKI Email Variables
+##
+## For example, to specify 'pkitest@example.com':
+##
+## pki_email_name=pkitest
+## pki_email_company=example
+## pki_email_domain=com
+##
+pki_email_name=
+pki_email_company=
+pki_email_domain=
+
+## PKI Silent Admin Variables
+## (e. g. - Import Admin Certificate into PKI Silent "browser" database)
+pki_silent_admin_user=admin
+pki_silent_admin_password=
+pki_silent_admin_email="${pki_email_name}\@${pki_email_company}\.${pki_email_domain}"
+
+
+
+##############################################################################
+## P R E - D E F I N E D " D E F A U L T " V A R I A B L E S ##
+##############################################################################
+
+## PKI Subsystem Host (computed by default)
+pki_host=`hostname`
+
+## PKI Subsystem Names
+ca_subsystem_name="Certificate\ Authority"
+
+## PKI Subsystem Instance Names
+subca_instance_name="pki-subca"
+
+## PKI Subsystem Init Script Names
+subca_init_script="pki-cad"
+
+##
+## NOTE: Default PKI Instance Ports
+##
+## CA:
+##
+## *180 - non-secure port (not role specific)
+## *701 - non-secure Tomcat port
+## *443 - secure EE port
+## *444 - secure Agent port
+## *445 - secure Admin port
+##
+##
+## For Example:
+##
+## semanage port -l | grep pki
+##
+## pki_ca_port_t tcp 9180, 9701, 9443, 9444, 9445
+## pki_subca_port_t tcp 9580, 9801, 9543, 9544, 9545
+##
+
+## CA ports
+ca_nonssl_port=9180
+ca_agent_port=9443
+ca_ee_port=9444
+ca_admin_port=9445
+
+## Subordinate CA ports
+subca_nonssl_port=9580
+subca_agent_port=9543
+subca_ee_port=9544
+subca_admin_port=9545
+
+
+
+##############################################################################
+## U S E R - D E F I N E D V A R I A B L E S ( O P T I O N A L ) ##
+##############################################################################
+
+## PKI Silent Log Files
+pki_silent_subca_log=/tmp/subca.log
+
+
+##
+## NOTE: For comparison's sake, if the default instances were manually
+## configured using a Firefox browser, the content of the corresponding
+## Firefox browser's security libraries would be something similar
+## to this:
+##
+## Certificate Nickname Trust Attributes
+## SSL,S/MIME,JAR/XPI
+##
+## Certificate Authority 2 - ${pki_security_domain_name} ,,
+## CA Administrator of Instance ${subca_instance_name}'s
+## ${pki_security_domain_name} ID u,u,u
+## ${pki_host} P,,
+## Certificate Authority - ${pki_security_domain_name} CT,C,C
+##
+## where:
+##
+## Nickname: "Certificate Authority 2 - "
+## + "${pki_security_domain_name}"
+## Subject Name: "cn=Certificate Authority 2,"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "CA Administrator of Instance "
+## + "${subca_instance_name}'s "
+## + "${pki_security_domain_name} ID"
+## Subject Name: "cn=CA Administrator of Instance "
+## + "${subca_instance_name},"
+## + "uid=admin,"
+## + "e=${pki_silent_admin_email},"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "${pki_host}"
+## Subject Name: "cn=${pki_host},"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "Certificate Authority - "
+## + "${pki_security_domain_name}"
+## Subject Name: "cn=Certificate Authority,"
+## + "o=${pki_security_domain_name}"
+##
+
+
+## Miscellaneous CA Variables
+##
+## REMINDER: 'Escape' ALL spaces in EACH variable specified below!
+##
+## NOTE: For comparison's sake, if the default instances were manually
+## configured using a Firefox browser, the content of the corresponding
+## "/var/lib/${subca_instance_name}/alias/" security libraries would be
+## something similar to this:
+##
+## Certificate Nickname Trust Attributes
+## SSL,S/MIME,JAR/XPI
+##
+## caSigningCert cert-${subca_instance_name} CTu,Cu,Cu
+## Server-Cert cert-${subca_instance_name} u,u,u
+## Certificate Authority - ${pki_security_domain_name} CT,c,
+## ocspSigningCert cert-${subca_instance_name} u,u,u
+## auditSigningCert cert-${subca_instance_name} u,u,u
+## subsystemCert cert-${subca_instance_name} u,u,u
+##
+## where:
+##
+## Nickname: "caSigningCert cert-${subca_instance_name}"
+## Subject Name: "cn=Certificate Authority 2,"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "Server-Cert cert-${subca_instance_name}"
+## Subject Name: "cn=${pki_host},"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "Certificate Authority - "
+## + "${pki_security_domain_name}"
+## Subject Name: "cn=Certificate Authority,"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "ocspSigningCert cert-${subca_instance_name}"
+## Subject Name: "cn=OCSP Signing Certificate 2,"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "auditSigningCert cert-${subca_instance_name}"
+## Subject Name: "cn=CA Audit Signing Certificate 2,"
+## + "o=${pki_security_domain_name}"
+##
+## Nickname: "subsystemCert cert-${subca_instance_name}"
+## Subject Name: "cn=CA Subsystem Certificate 2,"
+## + "o=${pki_security_domain_name}"
+##
+## NOTE: The parameters for the signing algorithms have the following meaning:
+## subca_signing_algorithm - signature algorithm used by the CA and OCSP signing certs to sign objects.
+## subca_signing_signingalgorithm - optionally specify the algorithm used by the CA signing cert to sign objects
+## subca_ocsp_signing_signingalgorithm - optionally specify the algorithm used by the CA ocsp signing cert to sign objects
+##
+
+subca_agent_name="CA\ Administrator\ of\ Instance\ ${subca_instance_name}\'s\ ${pki_security_domain_name}\ ID"
+subca_agent_key_size=2048
+subca_agent_key_type=rsa
+subca_agent_cert_subject="cn=CA\ Administrator\ of\ Instance\ ${subca_instance_name},uid=admin,e=${pki_silent_admin_email},o=${pki_security_domain_name}"
+subca_base_dn="dc=${pki_host}-${subca_instance_name}"
+subca_db_name="${pki_host}-${subca_instance_name}"
+subca_key_size=2048
+subca_key_type=rsa
+subca_signing_algorithm=SHA256withRSA
+subca_signing_signingalgorithm=SHA256withRSA
+subca_ocsp_signing_signingalgorithm=SHA256withRSA
+subca_sign_cert_subject_name="cn=Certificate\ Authority\ 2,o=${pki_security_domain_name}"
+subca_subsystem_cert_subject_name="cn=CA\ Subsystem\ Certificate\ 2,o=${pki_security_domain_name}"
+subca_ocsp_cert_subject_name="cn=OCSP\ Signing\ Certificate\ 2,o=${pki_security_domain_name}"
+subca_server_cert_subject_name="cn=${pki_host},o=${pki_security_domain_name}"
+subca_audit_signing_cert_subject_name="cn=CA\ Audit\ Signing\ Certificate\ 2,o=${pki_security_domain_name}"
+
+
+
+##############################################################################
+##############################################################################
+## ##
+## P K I S I L E N T - S U B S Y S T E M C O N F I G U R A T I O N ##
+## ##
+##############################################################################
+##############################################################################
+
+##############################################################################
+## P K I S I L E N T I N I T I A L I Z A T I O N ##
+##############################################################################
+
+## (1) Make certain that user has defined all MANDATORY user-defined variables!
+usage_errors=0
+usage_error_preamble="ERROR: User MUST define a value for"
+
+if [ "${pki_silent_security_database_password}" = "" ] ; then
+ printf "${usage_error_preamble} 'pki_silent_security_database_password'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${pki_security_domain_name}" = "" ] ; then
+ printf "${usage_error_preamble} 'pki_security_domain_name'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${pki_security_domain_admin_password}" = "" ] ; then
+ printf "${usage_error_preamble} 'pki_security_domain_admin_password'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${pki_bind_password}" = "" ] ; then
+ printf "${usage_error_preamble} 'pki_bind_password'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${subca_token_password}" = "" ] ; then
+ printf "${usage_error_preamble} 'subca_token_password'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${subca_backup_password}" = "" ] ; then
+ printf "${usage_error_preamble} 'subca_backup_password'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${pki_email_name}" = "" ] ; then
+ printf "${usage_error_preamble} 'pki_email_name'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${pki_email_company}" = "" ] ; then
+ printf "${usage_error_preamble} 'pki_email_company'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${pki_email_domain}" = "" ] ; then
+ printf "${usage_error_preamble} 'pki_email_domain'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+if [ "${pki_silent_admin_password}" = "" ] ; then
+ printf "${usage_error_preamble} 'pki_silent_admin_password'!\n"
+ usage_errors=`expr ${usage_errors} + 1`
+fi
+
+
+## (2) Make certain that a PKI instance of the specified name EXISTS,
+## but has NOT been previously CONFIGURED!
+existence_errors=0
+existence_error_preamble="ERROR: No PKI Instance named"
+configuration_errors=0
+configuration_error_preamble="ERROR: A PKI Instance named"
+configuration_error_postamble="EXISTS,\n but has PREVIOUSLY been CONFIGURED!"
+
+if [ ! -f "/var/lib/${subca_instance_name}/conf/CS.cfg" ] ; then
+ printf "${existence_error_preamble} '${subca_instance_name}' EXISTS!\n"
+ existence_errors=`expr ${existence_errors} + 1`
+else
+ subca_configuration_check=`grep -c preop /var/lib/${subca_instance_name}/conf/CS.cfg`
+ if [ ${subca_configuration_check} -eq 0 ] ; then
+ printf "${configuration_error_preamble} '${subca_instance_name}' "
+ printf "${configuration_error_postamble}\n"
+ configuration_errors=`expr ${configuration_errors} + 1`
+ fi
+fi
+
+
+if [ ${usage_errors} -ne 0 ] ||
+ [ ${existence_errors} -ne 0 ] ||
+ [ ${configuration_errors} -ne 0 ] ; then
+ printf "\n"
+ printf "Please correct ALL errors listed above and re-run\n"
+ printf "the '$0' script!\n\n"
+ exit 255
+fi
+
+
+## (3) Make certain that 'pkisilent' exists and is executable on this system.
+if [ ! -x "/usr/bin/pkisilent" ] ; then
+ printf "\n"
+ printf "ERROR: Please install the 'pki-silent' package and re-run\n"
+ printf "the '$0' script!\n\n"
+ exit 255
+fi
+
+
+## (4) Check for old PKI Silent Security Databases, but DO NOT remove them!
+## Instead, inform the user and exit this script.
+if [ -f "${pki_silent_security_database_repository}/cert8.db" ] ||
+ [ -f "${pki_silent_security_database_repository}/key3.db" ] ||
+ [ -f "${pki_silent_security_database_repository}/secmod.db" ] ; then
+ printf "\n"
+ printf "WARNING: At least one of the security databases\n"
+ printf " (i. e. - 'cert8.db', 'key3.db', and/or 'secmod.db')\n"
+ printf " required by '${subca_silent_script}' exists at the\n"
+ printf " specified location '${pki_silent_security_database_repository}'.\n"
+ printf "\n"
+ printf " Please MANUALLY move or erase these security database(s),\n"
+ printf " or specify a different location before re-running this script.\n\n"
+ exit 255
+fi
+
+
+## (5) Remove ALL old PKI Silent log files
+printf "Removing old PKI Silent log files:\n"
+if [ -f ${pki_silent_subca_log} ] ; then
+ printf " Removing old '${pki_silent_subca_log}' . . . "
+ rm ${pki_silent_subca_log}
+ printf "done.\n"
+fi
+printf "Done.\n\n"
+
+
+
+##############################################################################
+## C A L C U L A T E P K I I N S T A N C E P I N S ##
+##############################################################################
+
+## PKI Subsystem Instance PINS
+subca_preop_pin=`cat /var/lib/${subca_instance_name}/conf/CS.cfg \
+ | grep preop.pin | grep -v grep | awk -F= '{print $2}'`
+
+
+
+##############################################################################
+## C E R T I F I C A T E A U T H O R I T Y ##
+##############################################################################
+##
+## For example, upon completion,
+## execute '/sbin/service ${subca_init_script} status ${subca_instance_name}':
+##
+## ${subca_instance_name} (pid 7843) is running ...
+##
+## Unsecure Port = http://${pki_host}:9180/ca/ee/ca
+## Secure Agent Port = https://${pki_host}:9443/ca/agent/ca
+## Secure EE Port = https://${pki_host}:9444/ca/ee/ca
+## Secure Admin Port = https://${pki_host}:9445/ca/services
+## PKI Console Port = pkiconsole https://${pki_host}:9445/ca
+## Tomcat Port = 9701 (for shutdown)
+##
+##
+## Security Domain URL:
+## ==================================================================
+## https://${pki_host}:9445
+## ==================================================================
+##
+
+## Configure Subordinate CA
+printf "'${subca_silent_script}': Configuring '${subca_instance_name}' . . .\n"
+pkisilent ConfigureSubCA \
+ -cs_hostname "${pki_host}" \
+ -cs_port ${subca_admin_port} \
+ -sd_hostname "${pki_security_domain_host}" \
+ -sd_ssl_port ${ca_ee_port} \
+ -sd_agent_port ${ca_agent_port} \
+ -sd_admin_port ${ca_admin_port} \
+ -sd_admin_name "${pki_security_domain_admin_name}" \
+ -sd_admin_password ${pki_security_domain_admin_password} \
+ -ca_hostname ${pki_security_domain_host} \
+ -ca_port ${ca_nonssl_port} \
+ -ca_ssl_port ${ca_ee_port} \
+ -client_certdb_dir ${pki_silent_security_database_repository} \
+ -client_certdb_pwd ${pki_silent_security_database_password} \
+ -preop_pin ${subca_preop_pin} \
+ -domain_name "${pki_security_domain_name}" \
+ -admin_user ${pki_silent_admin_user} \
+ -admin_email "${pki_silent_admin_email}" \
+ -admin_password ${pki_silent_admin_password} \
+ -agent_name ${subca_agent_name} \
+ -ldap_host ${pki_ldap_host} \
+ -ldap_port ${pki_ldap_port} \
+ -bind_dn "${pki_bind_dn}" \
+ -bind_password ${pki_bind_password} \
+ -base_dn "${subca_base_dn}" \
+ -db_name "${subca_db_name}" \
+ -key_size ${subca_key_size} \
+ -key_type ${subca_key_type} \
+ -signing_algorithm ${subca_signing_algorithm} \
+ -signing_signingalgorithm ${subca_signing_signingalgorithm} \
+ -ocsp_signing_signingalgorithm ${subca_ocsp_signing_signingalgorithm} \
+ -token_name ${subca_token_name} \
+ -token_pwd ${subca_token_password} \
+ -agent_key_size ${subca_agent_key_size} \
+ -agent_key_type ${subca_agent_key_type} \
+ -agent_cert_subject "${subca_agent_cert_subject}" \
+ -backup_pwd ${subca_backup_password} \
+ -subsystem_name "${ca_subsystem_name}" \
+ -subca_sign_cert_subject_name "${subca_sign_cert_subject_name}" \
+ -subca_subsystem_cert_subject_name "${subca_subsystem_cert_subject_name}" \
+ -subca_ocsp_cert_subject_name "${subca_ocsp_cert_subject_name}" \
+ -subca_server_cert_subject_name "${subca_server_cert_subject_name}" \
+ -subca_audit_signing_cert_subject_name \
+ "${subca_audit_signing_cert_subject_name}" \
+ | tee ${pki_silent_subca_log}
+
+## Restart Subordinate CA
+/sbin/service ${subca_init_script} restart ${subca_instance_name}
+
+exit 0
+
diff --git a/base/symkey/CMakeLists.txt b/base/symkey/CMakeLists.txt
new file mode 100644
index 000000000..e994c0721
--- /dev/null
+++ b/base/symkey/CMakeLists.txt
@@ -0,0 +1,4 @@
+project(symkey)
+
+add_subdirectory(src)
+add_subdirectory(src/com/netscape/symkey)
diff --git a/base/symkey/LICENSE b/base/symkey/LICENSE
new file mode 100644
index 000000000..fbd2b7ff4
--- /dev/null
+++ b/base/symkey/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/base/symkey/src/CMakeLists.txt b/base/symkey/src/CMakeLists.txt
new file mode 100644
index 000000000..599a7cb5a
--- /dev/null
+++ b/base/symkey/src/CMakeLists.txt
@@ -0,0 +1,24 @@
+project(symkey Java)
+
+find_file(JSS_JAR
+ NAMES
+ jss4.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+set(symkey_java_SRCS
+ com/netscape/symkey/SessionKey.java
+)
+
+set(CMAKE_JNI_TARGET TRUE)
+set(CMAKE_JAVA_INCLUDE_PATH ${JSS_JAR})
+set(CMAKE_JAVA_TARGET_VERSION ${APPLICATION_VERSION})
+
+add_jar(symkey ${symkey_java_SRCS})
+install_jar(symkey ${LIB_INSTALL_DIR}/symkey)
+install_jni_symlink(symkey ${JAVA_LIB_INSTALL_DIR})
+
+set(SYMKEY_JAVA_OBJECT_DIR ${symkey_CLASS_DIR} PARENT_SCOPE)
+set(SYMKEY_JAR ${symkey_JAR_FILE} CACHE INTERNAL "symkey jar file")
diff --git a/base/symkey/src/com/netscape/symkey/Base.h b/base/symkey/src/com/netscape/symkey/Base.h
new file mode 100644
index 000000000..cdcf72bcf
--- /dev/null
+++ b/base/symkey/src/com/netscape/symkey/Base.h
@@ -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 ---
+
+#ifndef BASE_H
+#define BASE_H
+#include <nspr.h>
+
+typedef unsigned char BYTE;
+
+enum nsNKeyMsgEnum {
+ VRFY_FAILURE,
+ VRFY_SUCCESS,
+ ENCODE_DER_PUBKEY_FAILURE,
+ B64ENCODE_FAILURE,
+ VFY_BEGIN_FAILURE,
+ VFY_UPDATE_FAILURE,
+ HTTP_REQ_EXE_FAILURE,
+ HTTP_ERROR_RCVD,
+ BASE64_DECODE_FAILURE,
+ REQ_TO_CA_SUCCESS,
+ MSG_INVALID
+};
+
+struct ReturnStatus {
+ PRStatus status;
+ nsNKeyMsgEnum statusNum;
+};
+
+#endif /* BASE_H */
diff --git a/base/symkey/src/com/netscape/symkey/Buffer.cpp b/base/symkey/src/com/netscape/symkey/Buffer.cpp
new file mode 100644
index 000000000..5c687c5f5
--- /dev/null
+++ b/base/symkey/src/com/netscape/symkey/Buffer.cpp
@@ -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 ---
+
+#include <memory.h>
+#include <assert.h>
+#include <stdio.h>
+#include <cstdarg>
+#include <string>
+
+#include "Buffer.h"
+
+Buffer::Buffer(const BYTE *buf_, unsigned int len_) : len(len_), res(len_)
+{
+ buf = new BYTE[len];
+ memcpy(buf, buf_, len);
+}
+
+Buffer::Buffer(const Buffer& cpy)
+{
+ buf = 0;
+ *this = cpy;
+}
+
+Buffer::Buffer(unsigned int len_) : len(len_), res(len_)
+{
+ buf = new BYTE[res];
+ memset(buf, 0, len_);
+}
+
+Buffer::Buffer(unsigned int len_, BYTE b) : len(len_), res(len_)
+{
+ buf = new BYTE[res];
+ memset(buf, b, len);
+}
+
+Buffer::~Buffer()
+{
+ delete [] buf;
+}
+
+bool
+Buffer::operator==(const Buffer& cmp) const
+{
+ if( len != cmp.len ) return false;
+ for( unsigned int i=0; i < len; ++i ) {
+ if( buf[i] != cmp.buf[i] ) {
+ return false;
+ }
+ }
+ return true;
+}
+
+Buffer&
+Buffer::operator=(const Buffer& cpy)
+{
+ if( this == &cpy ) return *this;
+ len = cpy.len;
+ delete [] buf;
+ buf = new BYTE[len];
+ memcpy(buf, cpy.buf, len);
+ res = len;
+
+ return *this;
+}
+
+void
+Buffer::zeroize()
+{
+ if( len > 0 ) {
+ memset( buf, 0, len );
+ }
+}
+
+Buffer
+Buffer::operator+(const Buffer& addend) const
+{
+ Buffer result(len + addend.len);
+ memcpy(result.buf, buf, len);
+ memcpy(result.buf+len, addend.buf, addend.len);
+ return result;
+}
+
+Buffer&
+Buffer::operator+=(const Buffer& addend)
+{
+ unsigned int oldLen = len;
+ resize(len + addend.len);
+ memcpy(buf+oldLen, addend.buf, addend.len);
+ return *this;
+}
+
+Buffer&
+Buffer::operator+=(BYTE b)
+{
+ resize(len+1);
+ buf[len-1] = b;
+ return *this;
+}
+
+void
+Buffer::reserve(unsigned int n)
+{
+ if( n > res ) {
+ BYTE *newBuf = new BYTE[n];
+ memcpy(newBuf, buf, len);
+ delete [] buf;
+ buf = newBuf;
+ res = n;
+ }
+}
+
+void
+Buffer::resize(unsigned int newLen)
+{
+ if( newLen == len ) {
+ return;
+ } else if( newLen < len ) {
+ len = newLen;
+ } else if( newLen <= res ) {
+ assert( newLen > len );
+ memset(buf+len, 0, newLen-len);
+ len = newLen;
+ } else {
+ assert( newLen > len && newLen > res );
+ BYTE *newBuf = new BYTE[newLen];
+ memcpy(newBuf, buf, len);
+ memset(newBuf+len, 0, newLen-len);
+ delete [] buf;
+ buf = newBuf;
+ len = newLen;
+ res = newLen;
+ }
+}
+
+Buffer
+Buffer::substr(unsigned int i, unsigned int n) const
+{
+ assert( i < len && (i+n) <= len );
+ return Buffer( buf+i, n );
+}
+
+void
+Buffer::replace(unsigned int i, const BYTE* cpy, unsigned int n)
+{
+ if (len > i+n) {
+ resize( len);
+ }else {
+ resize( i+n );
+ }
+ memcpy(buf+i, cpy, n);
+}
+
+void
+Buffer::dump() const
+{
+ unsigned int i;
+
+ for( i=0; i < len; ++i ) {
+ printf("%02x ", buf[i]);
+ if( i % 16 == 15 ) printf("\n");
+ }
+ printf("\n");
+}
+
+static const char hextbl[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+};
diff --git a/base/symkey/src/com/netscape/symkey/Buffer.h b/base/symkey/src/com/netscape/symkey/Buffer.h
new file mode 100644
index 000000000..2e0256d87
--- /dev/null
+++ b/base/symkey/src/com/netscape/symkey/Buffer.h
@@ -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 ---
+
+#ifndef BUFFER_H
+#define BUFFER_H
+
+#include <stdio.h>
+#include "Base.h"
+
+/**
+ * This class represents a byte array.
+ */
+class Buffer {
+
+ private:
+ BYTE *buf;
+ unsigned int len;
+ unsigned int res;
+
+ public:
+ /**
+ * Creates an empty Buffer.
+ */
+ Buffer() : buf(0), len(0), res(0) { }
+
+ /**
+ * Creates a Buffer of length 'len', with each byte initialized to 'b'.
+ */
+ Buffer(unsigned int len, BYTE b);
+
+ /**
+ * Creates a Buffer of length 'len', initialized to zeroes.
+ */
+ explicit Buffer(unsigned int len);
+
+ /**
+ * Creates a Buffer of length 'len', initialized from 'buf'. 'buf' must
+ * contain at least 'len' bytes.
+ */
+ Buffer(const BYTE* buf, unsigned int len);
+
+ /**
+ * Copy constructor.
+ */
+ Buffer(const Buffer& cpy);
+
+ /**
+ * Destructor.
+ */
+ ~Buffer();
+
+ /**
+ * Assignment operator.
+ */
+ Buffer& operator=(const Buffer& cpy);
+
+ /**
+ * Returns true if the two buffers are the same length and contain
+ * the same byte at each offset.
+ */
+ bool operator==(const Buffer& cmp) const;
+
+ /**
+ * Returns ! operator==(cmp).
+ */
+ bool operator!=(const Buffer& cmp) const { return ! (*this == cmp); }
+
+ /**
+ * Concatenation operator.
+ */
+ Buffer operator+(const Buffer&addend) const;
+
+ /**
+ * Append operators.
+ */
+ Buffer& operator+=(const Buffer&addend);
+ Buffer& operator+=(BYTE b);
+
+ /**
+ * Returns a pointer into the Buffer. This also enables the subscript
+ * operator, so you can say, for example, 'buf[4] = b' or 'b = buf[4]'.
+ */
+ operator BYTE*() { return buf; }
+ operator const BYTE*() const { return buf; }
+
+ /**
+ * The length of buffer. The actual amount of space allocated may be
+ * higher--see capacity().
+ */
+ unsigned int size() const { return len; }
+
+ /**
+ * The amount of memory allocated for the buffer. This is the maximum
+ * size the buffer can grow before it needs to allocate more memory.
+ */
+ unsigned int capacity() const { return res; }
+
+ /**
+ * Sets all bytes in the buffer to 0.
+ */
+ void zeroize();
+
+ /**
+ * Changes the length of the Buffer. If 'newLen' is shorter than the
+ * current length, the Buffer is truncated. If 'newLen' is longer, the
+ * new bytes are initialized to 0. If 'newLen' is the same as size(),
+ * this is a no-op.
+ */
+ void resize(unsigned int newLen);
+
+ /**
+ * Ensures that capacity() is at least 'reserve'. Allocates more memory
+ * if necessary. If 'reserve' is <= capacity(), this is a no-op.
+ * Does not affect size().
+ */
+ void reserve(unsigned int reserve);
+
+ /**
+ * Returns a new Buffer that is a substring of this Buffer, starting
+ * from offset 'start' and continuing for 'len' bytes. This Buffer
+ * must have size() >= (start + len).
+ */
+ Buffer substr(unsigned int start, unsigned int len) const;
+
+ /**
+ * Replaces bytes i through i+n in this Buffer using the values in 'cpy'.
+ * This Buffer is resized if necessary. The 'cpy' argument can be a
+ * Buffer.
+ */
+ void replace(unsigned int i, const BYTE* cpy, unsigned int n);
+
+ /**
+ * returns a hex version of the buffer
+ */
+ char *toHex();
+
+ /**
+ * Dumps this Buffer to the given file as formatted hex: 16 bytes per
+ * line, separated by spaces.
+ */
+ void dump(FILE* file) const;
+
+ /**
+ * returns a null-terminated string of the buf.
+ * should be called only by callers that are certain that buf
+ * is entirely representable by printable characters and wants
+ * a string instead.
+ */
+ char *string();
+
+ /**
+ * dump()s this Buffer to stdout.
+ */
+ void dump() const;
+
+};
+
+#endif
diff --git a/base/symkey/src/com/netscape/symkey/CMakeLists.txt b/base/symkey/src/com/netscape/symkey/CMakeLists.txt
new file mode 100644
index 000000000..47d40a3f1
--- /dev/null
+++ b/base/symkey/src/com/netscape/symkey/CMakeLists.txt
@@ -0,0 +1,63 @@
+project(symkey_library CXX)
+
+set(SYMKEY_PUBLIC_INCLUDE_DIRS
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ CACHE INTERNAL "symkey public include directories"
+)
+
+set(SYMKEY_PRIVATE_INCLUDE_DIRS
+ ${CMAKE_BINARY_DIR}
+ ${JNI_INCLUDE_DIRS}
+ ${NSPR_INCLUDE_DIRS}
+ ${NSS_INCLUDE_DIRS}
+)
+
+set(SYMKEY_SHARED_LIBRARY
+ symkey_library
+ CACHE INTERNAL "symkey shared library"
+)
+
+set(SYMKEY_LINK_LIBRARIES
+ ${NSPR_LIBRARIES}
+ ${NSS_LIBRARIES}
+)
+
+set(symkey_library_HDRS
+ SessionKey.h
+)
+
+set(symkey_library_SRCS
+ Buffer.cpp
+ EncryptData.cpp
+ SessionKey.cpp
+ SymKey.cpp
+)
+
+include_directories(${SYMKEY_PRIVATE_INCLUDE_DIRS})
+
+add_custom_command(
+ OUTPUT
+ ${symkey_library_HDRS}
+ COMMAND
+ ${JAVA_HEADER}
+ -classpath ${SYMKEY_JAVA_OBJECT_DIR}:${JAVA_LIB_INSTALL_DIR}/jss4.jar
+ -jni -d ${CMAKE_CURRENT_BINARY_DIR}
+ com.netscape.symkey.SessionKey
+)
+
+add_library(${SYMKEY_SHARED_LIBRARY} SHARED ${symkey_library_HDRS} ${symkey_library_SRCS})
+target_link_libraries(${SYMKEY_SHARED_LIBRARY} ${SYMKEY_LINK_LIBRARIES})
+add_dependencies(${SYMKEY_SHARED_LIBRARY} symkey)
+
+set_target_properties(${SYMKEY_SHARED_LIBRARY}
+ PROPERTIES
+ OUTPUT_NAME
+ symkey
+)
+
+install(
+ TARGETS
+ ${SYMKEY_SHARED_LIBRARY}
+ LIBRARY DESTINATION ${LIB_INSTALL_DIR}/symkey
+)
diff --git a/base/symkey/src/com/netscape/symkey/EncryptData.cpp b/base/symkey/src/com/netscape/symkey/EncryptData.cpp
new file mode 100644
index 000000000..ccb817f7c
--- /dev/null
+++ b/base/symkey/src/com/netscape/symkey/EncryptData.cpp
@@ -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 ---
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include "pk11func.h"
+#include "nspr.h"
+#ifdef __cplusplus
+#include <jni.h>
+#include <assert.h>
+#include <string.h>
+
+}
+#endif
+#include <memory.h>
+#include <assert.h>
+#include <stdio.h>
+#include <cstdarg>
+#include <string>
+#include <stdlib.h>
+#include "Buffer.h"
+#include "SymKey.h"
+#define DES2_WORKAROUND
+
+PRFileDesc *d = NULL;
+
+void GetKeyName(jbyte *keyVersion, char *keyname)
+{
+ int index=0;
+
+ if( !keyname || !keyVersion ||
+ (strlen(keyname) < KEYNAMELENGTH)) {
+ return;
+ }
+
+ if(strlen(masterKeyPrefix)!=0)
+ {
+ index= strlen(masterKeyPrefix);
+ strcpy(keyname,masterKeyPrefix);
+ }
+
+ if( (index + 3) >= KEYNAMELENGTH) {
+ return;
+ }
+
+ keyname[index+0]='#';
+ sprintf(keyname+index+1,"%.2d", keyVersion[0]);
+ keyname[index+3]='#';
+ sprintf(keyname+index+4,"%.2d", keyVersion[1]);
+}
+
+
+extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_EncryptData
+(JNIEnv *, jclass, jstring, jstring, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jstring, jstring);
+
+extern "C" JNIEXPORT jbyteArray JNICALL
+Java_com_netscape_symkey_SessionKey_EncryptData(JNIEnv * env, jclass this2, jstring j_tokenName, jstring j_keyName, jbyteArray j_in, jbyteArray keyInfo, jbyteArray CUID, jbyteArray kekKeyArray, jstring useSoftToken_s,jstring keySet)
+{
+ jbyte * kek_key = NULL;
+
+ PK11SymKey *masterKey = NULL;
+ PK11SymKey *kekKey = NULL;
+
+ Buffer out = Buffer(KEYLENGTH, (BYTE)0);
+ BYTE kekData[KEYLENGTH];
+ char keyname[KEYNAMELENGTH];
+
+ int status = PR_FAILURE;
+
+ jbyte *cc = NULL;
+ int cc_len = 0;
+ jbyte * cuidValue = NULL;
+
+ if( kekKeyArray != NULL) {
+ kek_key = (jbyte*)(env)->GetByteArrayElements(kekKeyArray, NULL);
+ } else {
+ return NULL;
+ }
+
+ PK11SlotInfo *slot = NULL;
+ PK11SlotInfo *internal = PK11_GetInternalKeySlot();
+
+ Buffer kek_buffer = Buffer((BYTE*)kek_key, KEYLENGTH);
+ char *keySetStringChars = NULL;
+ if( keySet != NULL) {
+ keySetStringChars = (char *) (env)->GetStringUTFChars( keySet, NULL);
+ }
+
+ char *keySetString = keySetStringChars;
+
+ if ( keySetString == NULL ) {
+ keySetString = (char *) DEFKEYSET_NAME;
+ }
+
+ jbyte * keyVersion = NULL;
+ int keyVersion_len = 0;
+ if( keyInfo != NULL) {
+ keyVersion = (jbyte*)(env)->GetByteArrayElements( keyInfo, NULL);
+ if( keyVersion) {
+ keyVersion_len = (env)->GetArrayLength(keyInfo);
+ }
+ }
+
+ if( !keyVersion || (keyVersion_len < 2) ) {
+ goto done;
+ }
+
+ if( CUID != NULL) {
+ cuidValue = (jbyte*)(env)->GetByteArrayElements( CUID, NULL);
+ }
+
+ if( cuidValue == NULL) {
+ goto done;
+ }
+
+ if( j_in != NULL) {
+ cc = (jbyte*)(env)->GetByteArrayElements( j_in, NULL);
+ cc_len = (env)->GetArrayLength(j_in);
+ }
+
+ if( cc == NULL) {
+ goto done;
+ }
+
+ GetDiversificationData(cuidValue,kekData,kek);
+
+ PR_fprintf(PR_STDOUT,"In SessionKey: EncryptData! \n");
+
+ if(j_tokenName != NULL) {
+ char *tokenNameChars = (char *)(env)->GetStringUTFChars(j_tokenName, NULL);
+ slot = ReturnSlot(tokenNameChars);
+ (env)->ReleaseStringUTFChars(j_tokenName, (const char *)tokenNameChars);
+ tokenNameChars = NULL;
+ }
+
+ if(j_keyName != NULL) {
+ char *keyNameChars= (char *)(env)->GetStringUTFChars(j_keyName, NULL);
+ strcpy(keyname,keyNameChars);
+ env->ReleaseStringUTFChars(j_keyName, (const char *)keyNameChars);
+ keyNameChars = NULL;
+ }
+ else {
+ GetKeyName(keyVersion,keyname);
+ }
+
+ if ( (keyVersion[0] == 0x1 && keyVersion[1]== 0x1 && strcmp( keyname, "#01#01") == 0) ||
+ (keyVersion[0] == -1 && strstr(keyname, "#FF") ))
+ {
+ /* default development keyset */
+ Buffer devInput = Buffer((BYTE*)cc, cc_len);
+ Buffer empty = Buffer();
+
+ kekKey = ReturnDeveloperSymKey( internal, (char *) "kek", keySetString, empty);
+
+ if ( kekKey ) {
+ status = EncryptData(Buffer(),kekKey,devInput, out);
+ } else {
+ status = EncryptData(kek_buffer, NULL, devInput, out);
+ }
+ }
+ else
+ {
+ if (slot!=NULL)
+ {
+ masterKey = ReturnSymKey( slot,keyname);
+
+ /* We need to use internal so that the key
+ * can be exported by using PK11_GetKeyData()
+ */
+ if (masterKey != NULL)
+ {
+ kekKey = ComputeCardKeyOnToken(masterKey,kekData);
+ if (kekKey != NULL)
+ {
+ Buffer input = Buffer((BYTE*)cc, cc_len);
+ status = EncryptData(Buffer(), kekKey, input, out);
+ }
+ }
+ }
+ }
+
+done:
+
+ if (masterKey != NULL) {
+ PK11_FreeSymKey( masterKey);
+ masterKey = NULL;
+ }
+
+ if( slot != NULL ) {
+ PK11_FreeSlot( slot);
+ slot = NULL;
+ }
+
+ if( internal != NULL) {
+ PK11_FreeSlot( internal);
+ internal = NULL;
+ }
+
+ if ( kekKey != NULL) {
+ PK11_FreeSymKey( kekKey);
+ kekKey = NULL;
+ }
+
+ if( keySetStringChars ) {
+ (env)->ReleaseStringUTFChars(keySet, (const char *)keySetStringChars);
+ keySetStringChars = NULL;
+ }
+
+ jbyteArray handleBA=NULL;
+ if (status != PR_FAILURE && (out.size()>0) ) {
+ jbyte *handleBytes=NULL;
+ handleBA = (env)->NewByteArray( out.size());
+ handleBytes = (env)->GetByteArrayElements(handleBA, NULL);
+ BYTE* outp = (BYTE*)out;
+ memcpy(handleBytes, outp,out.size());
+ env->ReleaseByteArrayElements( handleBA, handleBytes, 0);
+ handleBytes=NULL;
+ }
+
+ if( cc != NULL) {
+ env->ReleaseByteArrayElements(j_in, cc, JNI_ABORT);
+ }
+
+ if( keyVersion != NULL) {
+ env->ReleaseByteArrayElements(keyInfo, keyVersion, JNI_ABORT);
+ }
+
+ if( cuidValue != NULL) {
+ env->ReleaseByteArrayElements(CUID, cuidValue, JNI_ABORT);
+ }
+
+ return handleBA;
+}
diff --git a/base/symkey/src/com/netscape/symkey/SessionKey.cpp b/base/symkey/src/com/netscape/symkey/SessionKey.cpp
new file mode 100644
index 000000000..eb412f01a
--- /dev/null
+++ b/base/symkey/src/com/netscape/symkey/SessionKey.cpp
@@ -0,0 +1,2005 @@
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include "pk11func.h"
+#include "seccomon.h"
+#include "nspr.h"
+#ifdef __cplusplus
+#include <jni.h>
+#include <assert.h>
+#include <string.h>
+#include "secerr.h"
+
+/*
+#include <jss_exceptions.h>
+#include <jssutil.h>
+*/
+
+}
+#endif
+#include <memory.h>
+#include <assert.h>
+#include <stdio.h>
+#include <cstdarg>
+#include <string>
+
+// DRM_PROTO begins
+#define PK11SYMKEY_CLASS_NAME "org/mozilla/jss/pkcs11/PK11SymKey"
+#define PK11SYMKEY_CONSTRUCTOR_SIG "([B)V"
+#define ALL_SYMKEY_OPS (CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP)
+// DRM_PROTO ends
+
+#include "Buffer.h"
+#include "SymKey.h"
+
+#define STEAL_JSS
+#ifdef STEAL_JSS
+// stealing code from JSS to handle DRM support
+/*
+ * NativeProxy
+ */
+#define NATIVE_PROXY_CLASS_NAME "org/mozilla/jss/util/NativeProxy"
+#define NATIVE_PROXY_POINTER_FIELD "mPointer"
+#define NATIVE_PROXY_POINTER_SIG "[B"
+
+/*
+ * SymKeyProxy
+ */
+#define SYM_KEY_PROXY_FIELD "keyProxy"
+#define SYM_KEY_PROXY_SIG "Lorg/mozilla/jss/pkcs11/SymKeyProxy;"
+
+
+/***********************************************************************
+ **
+ ** J S S _ p t r T o B y t e A r r a y
+ **
+ ** Turn a C pointer into a Java byte array. The byte array can be passed
+ ** into a NativeProxy constructor.
+ **
+ ** Returns a byte array containing the pointer, or NULL if an exception
+ ** was thrown.
+ */
+jbyteArray
+JSS_ptrToByteArray(JNIEnv *env, void *ptr)
+{
+ jbyteArray byteArray;
+
+ /* Construct byte array from the pointer */
+ byteArray = (env)->NewByteArray(sizeof(ptr));
+ if(byteArray==NULL)
+ {
+ PR_ASSERT( (env)->ExceptionOccurred() != NULL);
+ return NULL;
+ }
+ (env)->SetByteArrayRegion(byteArray, 0, sizeof(ptr), (jbyte*)&ptr);
+ if((env)->ExceptionOccurred() != NULL)
+ {
+ PR_ASSERT(PR_FALSE);
+ return NULL;
+ }
+ return byteArray;
+}
+
+
+/***********************************************************************
+ *
+ * J S S _ P K 1 1 _ w r a p S y m K e y
+
+ * Puts a Symmetric Key into a Java object.
+ * (Does NOT perform a cryptographic "wrap" operation.)
+ * symKey: will be stored in a Java wrapper.
+ * Returns: a new PK11SymKey, or NULL if an exception occurred.
+ */
+jobject
+JSS_PK11_wrapSymKey(JNIEnv *env, PK11SymKey **symKey)
+{
+// return JSS_PK11_wrapSymKey(env, symKey, NULL);
+// hmmm, looks like I may not need to steal code after all
+ return JSS_PK11_wrapSymKey(env, symKey);
+}
+
+
+jobject
+JSS_PK11_wrapSymKey(JNIEnv *env, PK11SymKey **symKey, PRFileDesc *debug_fd)
+{
+ jclass keyClass;
+ jmethodID constructor;
+ jbyteArray ptrArray;
+ jobject Key=NULL;
+
+ if (debug_fd)
+ PR_fprintf(debug_fd, "DRMproto in JSS_PK11_wrapSymKey\n");
+
+ PR_ASSERT(env!=NULL && symKey!=NULL && *symKey!=NULL);
+
+ /* find the class */
+ keyClass = (env)->FindClass(PK11SYMKEY_CLASS_NAME);
+ if (debug_fd)
+ PR_fprintf(debug_fd, "DRMproto in JSS_PK11_wrapSymKey called FindClass\n");
+ if( keyClass == NULL )
+ {
+ if (debug_fd)
+ PR_fprintf(debug_fd, "DRMproto in JSS_PK11_wrapSymKey FindClass NULL\n");
+// ASSERT_OUTOFMEM(env);
+ goto finish;
+ }
+
+ /* find the constructor */
+ constructor = (env)->GetMethodID(keyClass,
+ "<init>"/*PLAIN_CONSTRUCTOR*/,
+ PK11SYMKEY_CONSTRUCTOR_SIG);
+ if (debug_fd)
+ PR_fprintf(debug_fd, "DRMproto in JSS_PK11_wrapSymKey called GetMethodID\n");
+ if(constructor == NULL)
+ {
+// ASSERT_OUTOFMEM(env);
+ if (debug_fd)
+ PR_fprintf(debug_fd, "DRMproto in JSS_PK11_wrapSymKey GetMethodID returns NULL\n");
+ goto finish;
+ }
+
+ /* convert the pointer to a byte array */
+ ptrArray = JSS_ptrToByteArray(env, (void*)*symKey);
+ if (debug_fd)
+ PR_fprintf(debug_fd, "DRMproto in JSS_PK11_wrapSymKey called JSS_ptrToByteArray\n");
+ if( ptrArray == NULL )
+ {
+ if (debug_fd)
+ PR_fprintf(debug_fd, "DRMproto in JSS_PK11_wrapSymKey JSS_ptrToByteArray returns NULL\n");
+ goto finish;
+ }
+
+ /* call the constructor */
+ Key = (env)->NewObject( keyClass, constructor, ptrArray);
+ if (debug_fd)
+ PR_fprintf(debug_fd, "DRMproto in JSS_PK11_wrapSymKey called NewObject\n");
+
+finish:
+ if(Key == NULL)
+ {
+ if (debug_fd)
+ PR_fprintf(debug_fd, "DRMproto in JSS_PK11_wrapSymKey NewObject returns NULL\n");
+ PK11_FreeSymKey(*symKey);
+ }
+ *symKey = NULL;
+ return Key;
+}
+
+
+/***********************************************************************
+ **
+ ** J S S _ g e t P t r F r o m P r o x y
+ **
+ ** Given a NativeProxy, extract the pointer and store it at the given
+ ** address.
+ **
+ ** nativeProxy: a JNI reference to a NativeProxy.
+ ** ptr: address of a void* that will receive the pointer extracted from
+ ** the NativeProxy.
+ ** Returns: PR_SUCCESS on success, PR_FAILURE if an exception was thrown.
+ **
+ ** Example:
+ ** DataStructure *recovered;
+ ** jobject proxy;
+ ** JNIEnv *env;
+ ** [...]
+ ** if(JSS_getPtrFromProxy(env, proxy, (void**)&recovered) != PR_SUCCESS) {
+ ** return; // exception was thrown!
+ ** }
+ */
+PRStatus
+JSS_getPtrFromProxy(JNIEnv *env, jobject nativeProxy, void **ptr)
+{
+#ifdef DEBUG
+ jclass nativeProxyClass;
+#endif
+ jclass proxyClass;
+ jfieldID byteArrayField;
+ jbyteArray byteArray;
+ int size;
+
+ PR_ASSERT(env!=NULL && nativeProxy != NULL && ptr != NULL);
+ if( nativeProxy == NULL )
+ {
+// JSS_throw(env, NULL_POINTER_EXCEPTION);
+ return PR_FAILURE;
+ }
+
+ proxyClass = (env)->GetObjectClass(nativeProxy);
+ PR_ASSERT(proxyClass != NULL);
+
+#ifdef DEBUG
+ nativeProxyClass = (env)->FindClass(
+ NATIVE_PROXY_CLASS_NAME);
+ if(nativeProxyClass == NULL)
+ {
+// ASSERT_OUTOFMEM(env);
+ return PR_FAILURE;
+ }
+
+ /* make sure what we got was really a NativeProxy object */
+ PR_ASSERT( (env)->IsInstanceOf(nativeProxy, nativeProxyClass) );
+#endif
+
+ byteArrayField = (env)->GetFieldID(
+ proxyClass,
+ NATIVE_PROXY_POINTER_FIELD,
+ NATIVE_PROXY_POINTER_SIG);
+ if(byteArrayField==NULL)
+ {
+// ASSERT_OUTOFMEM(env);
+ return PR_FAILURE;
+ }
+
+ byteArray = (jbyteArray) (env)->GetObjectField(nativeProxy,
+ byteArrayField);
+ PR_ASSERT(byteArray != NULL);
+
+ size = sizeof(*ptr);
+ PR_ASSERT((env)->GetArrayLength( byteArray) == size);
+ (env)->GetByteArrayRegion(byteArray, 0, size, (jbyte*)ptr);
+ if( (env)->ExceptionOccurred() )
+ {
+ PR_ASSERT(PR_FALSE);
+ return PR_FAILURE;
+ }
+ else
+ {
+ return PR_SUCCESS;
+ }
+}
+
+
+/***********************************************************************
+ **
+ ** J S S _ g e t P t r F r o m P r o x y O w n e r
+ **
+ ** Given an object which contains a NativeProxy, extract the pointer
+ ** from the NativeProxy and store it at the given address.
+ **
+ ** proxyOwner: an object which contains a NativeProxy member.
+ ** proxyFieldName: the name of the NativeProxy member.
+ ** proxyFieldSig: the signature of the NativeProxy member.
+ ** ptr: address of a void* that will receive the extract pointer.
+ ** Returns: PR_SUCCESS for success, PR_FAILURE if an exception was thrown.
+ **
+ ** Example:
+ ** <Java>
+ ** public class Owner {
+ ** protected MyProxy myProxy;
+ ** [...]
+ ** }
+ **
+ ** <C>
+ ** DataStructure *recovered;
+ ** jobject owner;
+ ** JNIEnv *env;
+ ** [...]
+ ** if(JSS_getPtrFromProxyOwner(env, owner, "myProxy", (void**)&recovered)
+ ** != PR_SUCCESS) {
+ ** return; // exception was thrown!
+ ** }
+ */
+PRStatus
+JSS_getPtrFromProxyOwner(JNIEnv *env, jobject proxyOwner, char* proxyFieldName,
+char *proxyFieldSig, void **ptr)
+{
+ jclass ownerClass;
+ jfieldID proxyField;
+ jobject proxyObject;
+
+ PR_ASSERT(env!=NULL && proxyOwner!=NULL && proxyFieldName!=NULL &&
+ ptr!=NULL);
+
+ /*
+ * Get proxy object
+ */
+ ownerClass = (env)->GetObjectClass(proxyOwner);
+ proxyField = (env)->GetFieldID(ownerClass, proxyFieldName,
+ proxyFieldSig);
+ if(proxyField == NULL)
+ {
+ return PR_FAILURE;
+ }
+ proxyObject = (env)->GetObjectField(proxyOwner, proxyField);
+ PR_ASSERT(proxyObject != NULL);
+
+ /*
+ * Get the pointer from the Native Reference object
+ */
+ return JSS_getPtrFromProxy(env, proxyObject, ptr);
+}
+
+
+/***********************************************************************
+ *
+ * J S S _ P K 1 1 _ g e t S y m K e y P t r
+ *
+ */
+PRStatus
+JSS_PK11_getSymKeyPtr(JNIEnv *env, jobject symKeyObject, PK11SymKey **ptr)
+{
+ PR_ASSERT(env!=NULL && symKeyObject!=NULL);
+
+ /* Get the pointer from the key proxy */
+ return JSS_getPtrFromProxyOwner(env, symKeyObject, SYM_KEY_PROXY_FIELD,
+ SYM_KEY_PROXY_SIG, (void**)ptr);
+}
+#endif //STEAL_JSS
+// Function takes wither a symkey OR a keybuffer (for the default keyset case)
+// To derive a new key.
+PK11SymKey *DeriveKey(PK11SymKey *cardKey, const Buffer& hostChallenge, const Buffer& cardChallenge)
+{
+ PK11SymKey *key = NULL, *master = NULL;
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+ PK11Context *context = NULL;
+ unsigned char derivationData[KEYLENGTH];
+#ifdef DES2_WORKAROUND
+ unsigned char keyData[DES3_LENGTH];
+#else
+ unsigned char keyData[KEYLENGTH];
+#endif
+ int i = 0;
+ SECStatus s = SECSuccess;
+ int len = 0;;
+ static SECItem noParams = { siBuffer, NULL, 0 };
+
+ /* vars for PK11_Derive section */
+ SECItem param = { siBuffer, NULL, 0 };
+ CK_KEY_DERIVATION_STRING_DATA string;
+ PK11SymKey *tmp1 = NULL;
+ PK11SymKey *tmp2 = NULL;
+ PRBool invalid_mechanism = PR_FALSE;
+ CK_OBJECT_HANDLE keyhandle = 0;
+
+ PR_fprintf(PR_STDOUT,"In DeriveKey! \n");
+ master = cardKey;
+
+ if( ! master ) goto done;
+
+ for(i = 0;i < 4;i++)
+ {
+ derivationData[i] = cardChallenge[i+4];
+ derivationData[i+4] = hostChallenge[i];
+ derivationData[i+8] = cardChallenge[i];
+ derivationData[i+12] = hostChallenge[i+4];
+ }
+
+ string.pData = &derivationData[0];
+ string.ulLen = EIGHT_BYTES;
+ param.data = (unsigned char*)&string;
+ param.len = sizeof(string);
+
+ invalid_mechanism = PR_FALSE;
+
+ tmp1 = PK11_Derive( master , CKM_DES_ECB_ENCRYPT_DATA , &param , CKM_CONCATENATE_BASE_AND_KEY , CKA_DERIVE, 0);
+
+ if ( tmp1 == NULL) {
+ if ( PR_GetError() == SEC_ERROR_NO_TOKEN)
+ invalid_mechanism = PR_TRUE;
+
+ PR_fprintf(PR_STDERR,"DeriveKey: Can't create key, using encrypt and derive method ! error %d \n", PR_GetError());
+ } else {
+ PR_fprintf(PR_STDOUT,"DeriveKey: Successfully created key using encrypt and derive method! \n");
+ }
+
+ if ( invalid_mechanism == PR_FALSE) {
+
+ string.pData = &derivationData[EIGHT_BYTES];
+ string.ulLen = EIGHT_BYTES;
+
+ tmp2 = PK11_Derive( master , CKM_DES_ECB_ENCRYPT_DATA , &param , CKM_CONCATENATE_BASE_AND_KEY , CKA_DERIVE , 0);
+
+ if ( tmp2 == NULL) {
+ PR_fprintf(PR_STDERR,"DeriveKey: Can't derive key using CONCATENATE method! \n");
+ goto done;
+ } else {
+ PR_fprintf(PR_STDOUT,"DeriveKey: Successfully created key using CONCATENATE method! \n");
+ }
+
+ keyhandle = PK11_GetSymKeyHandle(tmp2);
+
+ param.data=(unsigned char *) &keyhandle;
+ param.len=sizeof(keyhandle);
+
+ key = PK11_Derive ( tmp1 , CKM_CONCATENATE_BASE_AND_KEY , &param ,CKM_DES3_ECB , CKA_DERIVE , 16);
+
+ if ( key == NULL) {
+ PR_fprintf(PR_STDERR,"DeriveKey: Can't create final derived key! \n");
+ goto done;
+ } else {
+ PR_fprintf(PR_STDOUT,"DeriveKey: Successfully created final derived key! \n");
+ }
+
+ } else { /* We don't have access to the proper derive mechanism, use primitive mechanisms now */
+
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, master,
+ &noParams);
+
+ if (!context) goto done;
+
+ s = PK11_CipherOp(context, &keyData[0], &len, EIGHT_BYTES, &derivationData[0], EIGHT_BYTES);
+ if (s != SECSuccess) goto done;
+
+ s = PK11_CipherOp(context, &keyData[EIGHT_BYTES], &len, 8, &derivationData[EIGHT_BYTES], EIGHT_BYTES);
+ if (s != SECSuccess) goto done;
+
+ for(i = 0;i < EIGHT_BYTES ;i++)
+ {
+ keyData[i+KEYLENGTH] = keyData[i];
+ }
+
+ key = CreateUnWrappedSymKeyOnToken( slot, master, &keyData[0] , DES3_LENGTH, PR_FALSE );
+
+ if ( key == NULL ) {
+ PR_fprintf(PR_STDERR,"DeriveKey: CreateUnWrappedSymKey failed! %d \n", PR_GetError());
+ } else {
+ PR_fprintf(PR_STDOUT,"DeriveKey: CreateUnWrappedSymKey succeeded! \n");
+ }
+ }
+
+ done:
+ memset(keyData, 0, sizeof keyData);
+ if ( context != NULL) {
+ PK11_DestroyContext(context, PR_TRUE);
+ context = NULL;
+ }
+
+ if (slot) {
+ PK11_FreeSlot(slot);
+ slot = NULL;
+ }
+
+ if (tmp1) {
+ PK11_FreeSymKey(tmp1);
+ tmp1 = NULL;
+ }
+
+ if (tmp2) {
+ PK11_FreeSymKey(tmp2);
+ tmp2 = NULL;
+ }
+
+ return key;
+}
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+ JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeKeyCheck
+ (JNIEnv *, jclass, jobject deskeyObj);
+#ifdef __cplusplus
+}
+#endif
+extern "C" JNIEXPORT jbyteArray JNICALL
+Java_com_netscape_symkey_SessionKey_ComputeKeyCheck
+(JNIEnv* env, jclass this2, jobject deskeyObj)
+{
+ jbyteArray handleBA=NULL;
+ jbyte *handleBytes=NULL;
+
+ PK11SymKey *key = NULL;
+// PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+ PK11Context *context = NULL;
+ SECStatus s = SECFailure;
+ PRStatus r = PR_FAILURE;
+ int lenx = 0;
+ static SECItem noParams = { siBuffer, NULL, 0 };
+
+ unsigned char value[EIGHT_BYTES];
+
+ memset(value, 0, sizeof value);
+
+ r = JSS_PK11_getSymKeyPtr(env, deskeyObj, &key);
+
+ if (r != PR_SUCCESS) {
+ goto finish;
+ }
+
+ if ( ! key ) {
+ goto finish;
+ }
+
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, key,
+ &noParams);
+ if (!context) {
+ goto finish;
+ }
+
+ s = PK11_CipherOp(context, &value[0], &lenx, EIGHT_BYTES, &value[0], EIGHT_BYTES);
+ if (s != SECSuccess)
+ {
+ goto finish;
+ }
+ handleBA = (env)->NewByteArray(3);
+ if(handleBA == NULL ) {
+ goto finish;
+ }
+ handleBytes = (env)->GetByteArrayElements(handleBA, NULL);
+ if(handleBytes==NULL) {
+ goto finish;
+ }
+ memcpy(handleBytes, value, 3);
+
+ if( handleBytes != NULL) {
+ (env)->ReleaseByteArrayElements(handleBA, handleBytes, 0);
+ }
+
+finish:
+
+ if ( context != NULL) {
+ PK11_DestroyContext(context, PR_TRUE);
+ context = NULL;
+ }
+
+// if ( slot != NULL) {
+// PK11_FreeSlot(slot);
+// slot = NULL;
+// }
+
+ return handleBA;
+}
+
+
+//=================================================================================
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/*
+ * Class: com_netscape_cms_servlet_tks_RASessionKey
+ * Method: ComputeSessionKey
+ * Signature: ([B[B[B[B)[B
+ */
+ JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeSessionKey
+ (JNIEnv *, jclass, jstring, jstring, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jstring, jstring, jstring);
+#ifdef __cplusplus
+}
+#endif
+#define KEYLENGTH 16
+extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeSessionKey(JNIEnv * env, jclass this2, jstring tokenName, jstring keyName, jbyteArray card_challenge, jbyteArray host_challenge, jbyteArray keyInfo, jbyteArray CUID, jbyteArray macKeyArray, jstring useSoftToken_s, jstring keySet, jstring sharedSecretKeyName)
+{
+ /* hardcore permanent mac key */
+ jbyte *mac_key = NULL;
+ if (macKeyArray != NULL) {
+ mac_key = (jbyte*)(env)->GetByteArrayElements(macKeyArray, NULL);
+ } else {
+ return NULL;
+ }
+
+ char input[KEYLENGTH];
+ int i = 0;
+
+ SECItem wrappedKeyItem = { siBuffer, NULL , 0};
+ SECItem noParams = { siBuffer, NULL, 0 };
+ SECStatus wrapStatus = SECFailure;
+
+
+ char *keyNameChars=NULL;
+ char *tokenNameChars=NULL;
+ PK11SlotInfo *slot = NULL;
+ PK11SlotInfo *internal = PK11_GetInternalKeySlot();
+
+ PK11SymKey *symkey = NULL;
+ PK11SymKey *transportKey = NULL;
+ PK11SymKey *masterKey = NULL;
+
+ PK11SymKey *macSymKey = NULL;
+ PK11SymKey *symkey16 = NULL;
+ PK11SymKey *macKey = NULL;
+
+
+ BYTE macData[KEYLENGTH];
+ char keyname[KEYNAMELENGTH];
+
+
+ /* Derive vars */
+
+ CK_ULONG bitPosition = 0;
+ SECItem paramsItem = { siBuffer, NULL, 0 };
+
+ /* Java object return vars */
+
+ jbyteArray handleBA=NULL;
+ jbyte *handleBytes=NULL;
+
+ jbyte * cuidValue = NULL;
+
+ jbyte *cc = NULL;
+ int cc_len = 0;
+
+ int hc_len = 0;
+ jbyte *hc = NULL;
+
+ jbyte * keyVersion = NULL;
+ int keyVersion_len = 0;
+
+ Buffer macBuff( ( BYTE *) mac_key , KEYLENGTH );
+
+ char *keySetStringChars = NULL;
+ if( keySet != NULL ) {
+ keySetStringChars = (char *) (env)->GetStringUTFChars( keySet, NULL);
+ }
+
+ char *keySetString = keySetStringChars;
+
+ if ( keySetString == NULL ) {
+ keySetString = (char *) DEFKEYSET_NAME;
+ }
+
+ char *sharedSecretKeyNameChars = NULL;
+
+ if( sharedSecretKeyName != NULL ) {
+ sharedSecretKeyNameChars = (char *) (env)->GetStringUTFChars( sharedSecretKeyName, NULL);
+ }
+
+ char *sharedSecretKeyNameString = sharedSecretKeyNameChars;
+
+ if ( sharedSecretKeyNameString == NULL ) {
+ sharedSecretKeyNameString = (char *) TRANSPORT_KEY_NAME;
+ }
+
+ GetSharedSecretKeyName(sharedSecretKeyNameString);
+
+ if( card_challenge != NULL) {
+ cc = (jbyte*)(env)->GetByteArrayElements( card_challenge, NULL);
+ cc_len = (env)->GetArrayLength(card_challenge);
+ }
+
+ if( cc == NULL) {
+ goto done;
+ }
+
+ if( host_challenge != NULL) {
+ hc = (jbyte*)(env)->GetByteArrayElements( host_challenge, NULL);
+ hc_len = (env)->GetArrayLength( host_challenge);
+ }
+
+ if( hc == NULL) {
+ goto done;
+ }
+
+ if( keyInfo != NULL) {
+ keyVersion = (jbyte*)(env)->GetByteArrayElements( keyInfo, NULL);
+
+ if( keyVersion) {
+ keyVersion_len = (env)->GetArrayLength(keyInfo);
+ }
+ }
+
+ if( !keyVersion || (keyVersion_len < 2) ){
+ goto done;
+ }
+
+ if ( CUID != NULL ) {
+ cuidValue = (jbyte*)(env)->GetByteArrayElements( CUID, NULL);
+ }
+
+ if( cuidValue == NULL) {
+ goto done;
+ }
+
+ /* copy card and host challenge into input buffer */
+ for (i = 0; i < 8; i++)
+ {
+ input[i] = cc[i];
+ }
+ for (i = 0; i < 8; i++)
+ {
+ input[8+i] = hc[i];
+ }
+
+ GetDiversificationData(cuidValue,macData,mac);//keytype is mac
+
+ if(tokenName)
+ {
+ tokenNameChars = (char *)(env)->GetStringUTFChars(tokenName, NULL);
+ slot = ReturnSlot(tokenNameChars);
+ (env)->ReleaseStringUTFChars(tokenName, (const char *)tokenNameChars);
+ }
+
+ if(keyName)
+ {
+ keyNameChars = (char *)(env)->GetStringUTFChars(keyName, NULL);
+ strncpy(keyname,keyNameChars,KEYNAMELENGTH);
+ (env)->ReleaseStringUTFChars(keyName, (const char *)keyNameChars);
+ }else
+ GetKeyName(keyVersion,keyname);
+
+ PR_fprintf(PR_STDOUT,"In SessionKey.ComputeSessionKey! \n");
+
+ if ( (keyVersion[0] == 0x1 && keyVersion[1]== 0x1 && strcmp( keyname, "#01#01") == 0) ||
+ (keyVersion[0] == -1 && strstr(keyname, "#FF")))
+
+ {
+ /* default manufacturers key */
+
+ macSymKey = ReturnDeveloperSymKey(slot, (char *) "mac" , keySetString, macBuff);
+
+ if( macSymKey == NULL ) {
+ goto done;
+ }
+
+ symkey = DeriveKey( //Util::DeriveKey(
+ macSymKey, Buffer((BYTE*)hc, hc_len), Buffer((BYTE*)cc, cc_len));
+
+ }else
+ {
+ masterKey = ReturnSymKey( slot,keyname);
+ if(masterKey == NULL)
+ {
+ goto done;
+ }
+
+ macKey =ComputeCardKeyOnToken(masterKey,macData);
+ if(macKey == NULL)
+ {
+ goto done;
+ }
+
+ symkey = DeriveKey(macKey, Buffer((BYTE*)hc, hc_len), Buffer((BYTE*)cc, cc_len));
+
+ if(symkey == NULL)
+ {
+ goto done;
+ }
+ }
+ //Now wrap the key for the trip back to TPS with shared secret transport key
+
+ symkey16 = NULL;
+ transportKey = ReturnSymKey( internal, GetSharedSecretKeyName(NULL));
+ if ( transportKey == NULL ) {
+ PR_fprintf(PR_STDERR, "Can't find shared secret transport key! \n");
+ goto done;
+ }
+
+ handleBA = (env)->NewByteArray( KEYLENGTH);
+ handleBytes = (env)->GetByteArrayElements(handleBA, NULL);
+
+ paramsItem.data = (CK_BYTE *) &bitPosition;
+ paramsItem.len = sizeof bitPosition;
+
+ symkey16 = PK11_Derive(symkey, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT,
+ CKA_DERIVE, 16);
+ if ( !symkey16 ) {
+ PR_fprintf(PR_STDERR,"Can't derive 16 byte key from 24 byte symkey! \n");
+ goto done;
+ }
+
+ wrappedKeyItem.data = (unsigned char *) handleBytes;
+ wrappedKeyItem.len = KEYLENGTH;
+ wrapStatus = PK11_WrapSymKey(CKM_DES3_ECB,&noParams, transportKey, symkey16, &wrappedKeyItem);
+
+ if(wrapStatus == SECFailure )
+ {
+ PR_fprintf(PR_STDERR, "Can't wrap session key! Error: %d \n", PR_GetError());
+ }
+
+done:
+
+ if( slot) {
+ PK11_FreeSlot(slot);
+ slot = NULL;
+ }
+
+ if( internal ) {
+ PK11_FreeSlot(internal);
+ internal = NULL;
+ }
+
+ if ( symkey ) {
+ PK11_FreeSymKey( symkey);
+ symkey = NULL;
+ }
+
+ if ( transportKey ) {
+ PK11_FreeSymKey( transportKey );
+ transportKey = NULL;
+ }
+
+ if ( symkey16 ) {
+ PK11_FreeSymKey( symkey16 );
+ symkey16 = NULL;
+ }
+
+ if( masterKey ) {
+ PK11_FreeSymKey( masterKey);
+ masterKey = NULL;
+ }
+
+ if( macKey ) {
+ PK11_FreeSymKey( macKey);
+ macKey = NULL;
+ }
+
+ if( macSymKey ) {
+ PK11_FreeSymKey( macSymKey );
+ macSymKey = NULL;
+ }
+
+ if( keySetStringChars ) {
+ (env)->ReleaseStringUTFChars(keySet, (const char *)keySetStringChars);
+ keySetStringChars = NULL;
+ }
+
+ if( sharedSecretKeyNameChars ) {
+ (env)->ReleaseStringUTFChars(sharedSecretKeyName, (const char *)sharedSecretKeyNameChars);
+ sharedSecretKeyNameChars = NULL;
+ }
+
+ if ( handleBA != NULL) {
+ (env)->ReleaseByteArrayElements( handleBA, handleBytes, 0);
+ }
+
+ if ( cc != NULL) {
+ (env)->ReleaseByteArrayElements(card_challenge, cc, JNI_ABORT);
+ }
+
+ if ( hc != NULL) {
+ (env)->ReleaseByteArrayElements(host_challenge, hc, JNI_ABORT);
+ }
+
+ if( keyVersion != NULL) {
+ (env)->ReleaseByteArrayElements(keyInfo, keyVersion, JNI_ABORT);
+ }
+
+ if ( cuidValue != NULL) {
+ (env)->ReleaseByteArrayElements(CUID, cuidValue, JNI_ABORT);
+ }
+
+ if( mac_key != NULL) {
+ (env)->ReleaseByteArrayElements(macKeyArray, mac_key, JNI_ABORT);
+ }
+
+ return handleBA;
+}
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/*
+ * Class: com_netscape_cms_servlet_tks_RASessionKey
+ * Method: ComputeEncSessionKey
+ * Signature: ([B[B[B[B)[B
+ */
+ JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeEncSessionKey
+ (JNIEnv *, jclass, jstring, jstring, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jstring, jstring);
+#ifdef __cplusplus
+}
+#endif
+#define KEYLENGTH 16
+extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeEncSessionKey(JNIEnv * env, jclass this2, jstring tokenName, jstring keyName, jbyteArray card_challenge, jbyteArray host_challenge, jbyteArray keyInfo, jbyteArray CUID, jbyteArray encKeyArray, jstring useSoftToken_s, jstring keySet)
+{
+ /* hardcoded permanent enc key */
+ jbyte *enc_key = NULL;
+ if(encKeyArray != NULL ) {
+ enc_key = (jbyte*)(env)->GetByteArrayElements(encKeyArray, NULL);
+ } else {
+ return NULL;
+ }
+
+ char input[KEYLENGTH];
+ int i = 0;
+
+ SECItem wrappedKeyItem = { siBuffer, NULL , 0};
+ SECItem noParams = { siBuffer, NULL, 0 };
+ SECStatus wrapStatus = SECFailure;
+
+ char *keyNameChars = NULL;
+ char *tokenNameChars = NULL;
+ PK11SlotInfo *slot = NULL;
+ PK11SlotInfo *internal = PK11_GetInternalKeySlot();
+
+ PK11SymKey *symkey = NULL;
+ PK11SymKey * transportKey = NULL;
+ PK11SymKey *masterKey = NULL;
+
+ PK11SymKey *encSymKey = NULL;
+ PK11SymKey *encKey = NULL;
+ PK11SymKey *symkey16 = NULL;
+
+ BYTE encData[KEYLENGTH];
+ char keyname[KEYNAMELENGTH];
+
+ /* Derive vars */
+ CK_ULONG bitPosition = 0;
+ SECItem paramsItem = { siBuffer, NULL, 0 };
+
+ /* Java object return vars */
+
+ jbyteArray handleBA=NULL;
+ jbyte *handleBytes=NULL;
+
+ jbyte * cuidValue = NULL;
+
+ jbyte *cc = NULL;
+ int cc_len = 0;
+
+ int hc_len = 0;
+ jbyte *hc = NULL;
+
+ jbyte * keyVersion = NULL;
+ int keyVersion_len = 0;
+
+ Buffer encBuff( ( BYTE *) enc_key , KEYLENGTH );
+
+ char *keySetStringChars = NULL;
+
+ if( keySet != NULL ) {
+ keySetStringChars = (char *) (env)->GetStringUTFChars( keySet, NULL);
+ }
+
+ char *keySetString = keySetStringChars;
+
+ if ( keySetString == NULL ) {
+ keySetString = (char *) DEFKEYSET_NAME;
+ }
+
+ if( card_challenge != NULL) {
+ cc = (jbyte*)(env)->GetByteArrayElements( card_challenge, NULL);
+ cc_len = (env)->GetArrayLength(card_challenge);
+ }
+
+ if( cc == NULL) {
+ goto done;
+ }
+
+ if( host_challenge != NULL) {
+ hc = (jbyte*)(env)->GetByteArrayElements( host_challenge, NULL);
+ hc_len = (env)->GetArrayLength( host_challenge);
+ }
+
+ if( hc == NULL) {
+ goto done;
+ }
+
+ if( keyInfo != NULL) {
+ keyVersion = (jbyte*)(env)->GetByteArrayElements( keyInfo, NULL);
+
+ if( keyVersion) {
+ keyVersion_len = (env)->GetArrayLength(keyInfo);
+ }
+ }
+
+ if( !keyVersion || (keyVersion_len < 2) ){
+ goto done;
+ }
+
+ if( CUID != NULL) {
+ cuidValue = (jbyte*)(env)->GetByteArrayElements( CUID, NULL);
+ }
+
+ if( cuidValue == NULL) {
+ goto done;
+ }
+
+ /* copy card and host challenge into input buffer */
+ for (i = 0; i < 8; i++)
+ {
+ input[i] = cc[i];
+ }
+ for (i = 0; i < 8; i++)
+ {
+ input[8+i] = hc[i];
+ }
+
+ GetDiversificationData(cuidValue,encData,enc);
+
+ if(tokenName)
+ {
+ tokenNameChars = (char *)(env)->GetStringUTFChars(tokenName, NULL);
+ slot = ReturnSlot(tokenNameChars);
+ (env)->ReleaseStringUTFChars(tokenName, (const char *)tokenNameChars);
+ }
+
+ if(keyName)
+ {
+ keyNameChars = (char *)(env)->GetStringUTFChars(keyName, NULL);
+ strncpy(keyname,keyNameChars,KEYNAMELENGTH);
+ (env)->ReleaseStringUTFChars(keyName, (const char *)keyNameChars);
+ }
+ else {
+ GetKeyName(keyVersion,keyname);
+ }
+
+ if ( (keyVersion[0] == 0x1 && keyVersion[1]== 0x1 &&strcmp( keyname, "#01#01") == 0) ||
+ (keyVersion[0] == -1 && strstr(keyname, "#FF")))
+ {
+ /* default manufacturers key */
+
+ encSymKey = ReturnDeveloperSymKey(slot, (char *) "auth" , keySetString, encBuff);
+
+ if( encSymKey == NULL ) {
+ goto done;
+ }
+
+ symkey = DeriveKey( //Util::DeriveKey(
+ encSymKey, Buffer((BYTE*)hc, hc_len), Buffer((BYTE*)cc, cc_len));
+
+ }else
+ {
+ masterKey = ReturnSymKey( slot,keyname);
+
+ /* We need to use internal so that the key
+ * can be exported by using PK11_GetKeyData()
+ */
+ if(masterKey == NULL) {
+ goto done;
+ }
+
+ encKey =ComputeCardKeyOnToken(masterKey,encData);
+ if(encKey == NULL) {
+ goto done;
+ }
+ symkey = DeriveKey(encKey, Buffer((BYTE*)hc, hc_len), Buffer((BYTE*)cc, cc_len));
+ }
+
+ if(symkey == NULL) {
+ goto done;
+ }
+
+ //Now wrap the key for the trip back to TPS with shared secret transport key
+ transportKey = ReturnSymKey( internal, GetSharedSecretKeyName(NULL));
+ if ( transportKey == NULL ) {
+ goto done;
+ }
+
+ handleBA = (env)->NewByteArray( KEYLENGTH);
+ handleBytes = (env)->GetByteArrayElements(handleBA, NULL);
+
+ paramsItem.data = (CK_BYTE *) &bitPosition;
+ paramsItem.len = sizeof bitPosition;
+
+ symkey16 = PK11_Derive(symkey, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT,
+ CKA_DERIVE, KEYLENGTH);
+
+ if ( !symkey16 ) {
+ PR_fprintf(PR_STDERR,"SessionKey: ComputeEncSessionKey - Can't derive 16 byte key from 24 byte symkey! \n");
+ goto done;
+ }
+
+ wrappedKeyItem.data = (unsigned char *) handleBytes;
+ wrappedKeyItem.len = KEYLENGTH;
+ wrapStatus = PK11_WrapSymKey(CKM_DES3_ECB,&noParams, transportKey, symkey16, &wrappedKeyItem);
+
+ if ( wrapStatus == SECFailure ) {
+ PR_fprintf(PR_STDERR,"SessionKey: ComputeEncSessionKey - Can't wrap encSessionKey ! Error: %d \n", PR_GetError());
+ }
+
+done:
+
+ if ( slot ) {
+ PK11_FreeSlot ( slot );
+ slot = NULL;
+ }
+
+ if ( internal) {
+ PK11_FreeSlot( internal);
+ internal = NULL;
+ }
+
+ if( symkey) {
+ PK11_FreeSymKey( symkey);
+ symkey = NULL;
+ }
+
+ if( transportKey) {
+ PK11_FreeSymKey( transportKey );
+ transportKey = NULL;
+ }
+
+ if( masterKey) {
+ PK11_FreeSymKey( masterKey);
+ masterKey = NULL;
+ }
+
+ if( symkey16) {
+ PK11_FreeSymKey( symkey16);
+ symkey16 = NULL;
+ }
+
+ if ( encSymKey ) {
+ PK11_FreeSymKey( encSymKey);
+ encSymKey = NULL;
+ }
+
+ if( encKey) {
+ PK11_FreeSymKey( encKey);
+ encKey = NULL;
+ }
+
+ if( keySetStringChars ) {
+ (env)->ReleaseStringUTFChars(keySet, (const char *)keySetStringChars);
+ keySetStringChars = NULL;
+ }
+
+ if ( handleBytes != NULL ) {
+ (env)->ReleaseByteArrayElements( handleBA, handleBytes, 0);
+ }
+
+ if( cc != NULL ) {
+ (env)->ReleaseByteArrayElements(card_challenge, cc, JNI_ABORT);
+ }
+
+ if( hc != NULL ) {
+ (env)->ReleaseByteArrayElements(host_challenge, hc, JNI_ABORT);
+ }
+ if(keyVersion != NULL ) {
+ (env)->ReleaseByteArrayElements(keyInfo, keyVersion, JNI_ABORT);
+ }
+
+ if(cuidValue != NULL) {
+ (env)->ReleaseByteArrayElements(CUID, cuidValue, JNI_ABORT);
+ }
+
+ if( enc_key != NULL) {
+ (env)->ReleaseByteArrayElements(encKeyArray, enc_key, JNI_ABORT);
+ }
+
+ return handleBA;
+}
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/*
+ * Class: com_netscape_cms_servlet_tks_RASessionKey
+ * Method: ComputeKekKey
+ * Signature: ([B[B[B[B)[B
+ */
+ JNIEXPORT jobject JNICALL Java_com_netscape_symkey_SessionKey_ComputeKekKey
+ (JNIEnv *, jclass, jstring, jstring, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jstring, jstring);
+#ifdef __cplusplus
+}
+#endif
+#define KEYLENGTH 16
+
+extern "C" JNIEXPORT jobject JNICALL Java_com_netscape_symkey_SessionKey_ComputeKekKey(JNIEnv * env, jclass this2, jstring tokenName, jstring keyName, jbyteArray card_challenge, jbyteArray host_challenge, jbyteArray keyInfo, jbyteArray CUID, jbyteArray kekKeyArray, jstring useSoftToken_s, jstring keySet)
+{
+ /* hardcoded permanent kek key */
+ jbyte *kek_key = NULL;
+ if( kekKeyArray != NULL) {
+ kek_key = (jbyte*)(env)->GetByteArrayElements(kekKeyArray, NULL);
+ } else {
+ return NULL;
+ }
+
+ Buffer kekBuff( ( BYTE *) kek_key , KEYLENGTH );
+
+ char *keySetStringChars = NULL;
+ if( keySet != NULL ) {
+ keySetStringChars = (char *) (env)->GetStringUTFChars( keySet, NULL);
+ }
+
+ char *keySetString = keySetStringChars;
+
+ if ( keySetString == NULL ) {
+ keySetString = (char *) DEFKEYSET_NAME;
+ }
+
+ char input[KEYLENGTH];
+ int i;
+ jobject keyObj = NULL;
+
+ jbyte *cc = NULL;
+ jbyte *hc = NULL;
+ jbyte * keyVersion = NULL;
+ int keyVersion_len = 0;
+ jbyte * cuidValue = NULL;
+
+ char *keyNameChars=NULL;
+ char *tokenNameChars = NULL;
+ PK11SlotInfo *slot = NULL;
+
+ PK11SymKey *kekKey = NULL;
+ PK11SymKey *masterKey = NULL;
+
+ BYTE kekData[KEYLENGTH];
+ char keyname[KEYNAMELENGTH];
+
+ if( card_challenge != NULL) {
+ cc = (jbyte*)(env)->GetByteArrayElements( card_challenge, NULL);
+ }
+
+ if( cc == NULL) {
+ goto done;
+ }
+
+ if( host_challenge != NULL) {
+ hc = (jbyte*)(env)->GetByteArrayElements( host_challenge, NULL);
+ }
+
+ if( hc == NULL) {
+ goto done;
+ }
+
+ if( keyInfo != NULL) {
+ keyVersion = (jbyte*)(env)->GetByteArrayElements( keyInfo, NULL);
+ if( keyVersion) {
+ keyVersion_len = (env)->GetArrayLength(keyInfo);
+ }
+ }
+
+ if( !keyVersion || (keyVersion_len < 2) ){
+ goto done;
+ }
+
+ if( CUID != NULL) {
+ cuidValue = (jbyte*)(env)->GetByteArrayElements( CUID, NULL);
+ }
+
+ if( cuidValue == NULL) {
+ goto done;
+ }
+
+ /* copy card and host challenge into input buffer */
+ for (i = 0; i < 8; i++)
+ {
+ input[i] = cc[i];
+ }
+ for (i = 0; i < 8; i++)
+ {
+ input[8+i] = hc[i];
+ }
+
+ GetDiversificationData(cuidValue,kekData,kek);//keytype is kek
+
+ if (tokenName)
+ {
+ tokenNameChars = (char *)(env)->GetStringUTFChars(tokenName, NULL);
+ slot = ReturnSlot(tokenNameChars);
+ (env)->ReleaseStringUTFChars(tokenName, (const char *)tokenNameChars);
+ }
+
+ if (keyName)
+ {
+ keyNameChars = (char *)(env)->GetStringUTFChars(keyName, NULL);
+ strcpy(keyname,keyNameChars);
+ (env)->ReleaseStringUTFChars(keyName, (const char *)keyNameChars);
+ }else
+ GetKeyName(keyVersion,keyname);
+
+ PR_fprintf(PR_STDOUT,"In SessionKey.ComputeKekKey! \n");
+
+ if (( keyVersion[0] == 0x1 && keyVersion[1]== 0x1 &&strcmp( keyname, "#01#01") == 0 ) ||
+ (keyVersion[0] == -1 && strcmp(keyname, "#FF")))
+ {
+ /* default manufacturers key */
+
+ kekKey = ReturnDeveloperSymKey(slot, (char *) "kek" , keySetString, kekBuff);
+
+ } else {
+ masterKey = ReturnSymKey( slot,keyname);
+
+ if(masterKey == NULL)
+ {
+ goto done;
+ }
+
+ kekKey =ComputeCardKeyOnToken(masterKey,kekData);
+
+ }
+
+ if(kekKey == NULL) {
+ goto done;
+ }
+
+ keyObj = JSS_PK11_wrapSymKey(env, &kekKey, NULL);
+
+done:
+
+ if( keySetStringChars ) {
+ (env)->ReleaseStringUTFChars(keySet, (const char *)keySetStringChars);
+ keySetStringChars = NULL;
+ }
+
+ if(masterKey) {
+ PK11_FreeSymKey( masterKey);
+ masterKey = NULL;
+ }
+
+ if(kekKey) {
+ PK11_FreeSymKey( kekKey);
+ kekKey = NULL;
+ }
+
+ if(slot) {
+ PK11_FreeSlot(slot);
+ slot = NULL;
+ }
+
+ if (cc != NULL) {
+ (env)->ReleaseByteArrayElements(card_challenge, cc, JNI_ABORT);
+ }
+
+ if (hc != NULL) {
+ (env)->ReleaseByteArrayElements(host_challenge, hc, JNI_ABORT);
+ }
+
+ if( keyVersion != NULL ) {
+ (env)->ReleaseByteArrayElements(keyInfo, keyVersion, JNI_ABORT);
+ }
+
+ if (cuidValue != NULL ) {
+ (env)->ReleaseByteArrayElements(CUID, cuidValue, JNI_ABORT);
+ }
+
+ return keyObj;
+}
+
+PRStatus ComputeMAC(PK11SymKey *key, Buffer &x_input,
+const Buffer &icv, Buffer &output)
+{
+ PRStatus rv = PR_SUCCESS;
+ PK11Context *context = NULL;
+// NetkeyICV temp;
+ unsigned char result[8];
+ int i;
+ SECStatus s;
+ int len;
+#ifdef USE_DESMAC
+ CK_ULONG macLen = sizeof result;
+ SECItem params = { siBuffer, (unsigned char *)&macLen, sizeof macLen };
+#endif
+ static SECItem noParams = { siBuffer, NULL, 0 };
+ static unsigned char macPad[] =
+ {
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ BYTE *input = (BYTE *) x_input;
+ int inputLen = x_input.size();
+
+ if(key == NULL)
+ {
+ rv = PR_FAILURE; goto done;
+ }
+
+#ifdef USE_DESMAC
+ context = PK11_CreateContextBySymKey(CKM_DES3_MAC_GENERAL, CKA_SIGN,
+ key, &params);
+ if (!context) { rv = PR_FAILURE; goto done; }
+
+ s = PK11_DigestBegin(context);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+
+ s = PK11_DigestOp(context, icv, 8);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+
+ while(inputLen >= 8)
+ {
+ s = PK11_DigestOp(context, input, 8);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+
+ input += 8;
+ inputLen -= 8;
+ }
+
+ for (i = 0;i < inputLen;i++)
+ {
+ result[i] = input[i];
+ }
+
+ input = macPad;
+ for(;i < 8;i++)
+ {
+ result[i] = *input++;
+ }
+
+ s = PK11_DigestOp(context, result, sizeof result);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+
+ s = PK11_DigestFinal(context, output, (unsigned int *)&len, sizeof output);
+ if (1 != SECSuccess) { rv = PR_FAILURE; goto done; }
+
+#else
+
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, key, &noParams);
+ if (!context) { rv = PR_FAILURE; goto done; }
+
+ memcpy(result, icv, sizeof result);
+
+ /* Process whole blocks */
+ while (inputLen >= 8)
+ {
+ for(i = 0;i < 8;i++)
+ {
+ result[i] ^= input[i];
+ }
+
+ s = PK11_CipherOp(context, result, &len, sizeof result, result, sizeof result);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+ if (len != sizeof result) /* assert? */
+ {
+//PR_SetError(PR_UNKNOWN_ERROR, 0);
+ rv = PR_FAILURE;
+ goto done;
+ }
+
+ input += 8;
+ inputLen -= 8;
+ }
+
+/*
+ * Fold in remaining data (if any)
+ * Set i to number of bytes processed
+ */
+ for(i = 0;i < inputLen;i++)
+ {
+ result[i] ^= input[i];
+ }
+
+ /*
+ * Fill remainder of last block. There
+ * will be at least one byte handled here.
+ */
+ input = macPad;
+ while(i < 8)
+ {
+ result[i] ^= *input++;
+ i++;
+ }
+
+ s = PK11_CipherOp(context, result, &len, sizeof result, result, sizeof result);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+ if (len != sizeof result)
+ {
+//PR_SetError(PR_UNKNOWN_ERROR, 0);
+ rv = PR_FAILURE;
+ goto done;
+ }
+
+ output.replace(0, result, sizeof result);
+#endif
+
+ done:
+ if (context)
+ {
+ PK11_Finalize(context);
+ PK11_DestroyContext(context, PR_TRUE);
+ }
+ memset(result, 0, sizeof result);
+
+ return rv;
+} /* ComputeMAC */
+
+
+//=================================================================================
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/*
+ * Class: com_netscape_cms_servlet_tks_RASessionKey
+ * Method: ComputeCryptogram
+ * Signature: ([B[B[B[B)[B
+ */
+ JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeCryptogram
+ (JNIEnv *, jclass, jstring, jstring, jbyteArray, jbyteArray, jbyteArray, jbyteArray, int, jbyteArray, jstring, jstring);
+#ifdef __cplusplus
+}
+#endif
+#define KEYLENGTH 16
+extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeCryptogram(JNIEnv * env, jclass this2, jstring tokenName, jstring keyName, jbyteArray card_challenge, jbyteArray host_challenge, jbyteArray keyInfo, jbyteArray CUID, int type, jbyteArray authKeyArray, jstring useSoftToken_s, jstring keySet)
+{
+/* hardcore permanent mac key */
+ jbyte *auth_key = NULL;
+ if( authKeyArray != NULL) {
+ auth_key = (jbyte*)(env)->GetByteArrayElements(authKeyArray, NULL);
+ } else {
+ return NULL;
+ }
+
+ Buffer authBuff( ( BYTE *) auth_key , KEYLENGTH );
+ Buffer icv = Buffer(EIGHT_BYTES, (BYTE)0);
+ Buffer output = Buffer(EIGHT_BYTES, (BYTE)0);
+
+ char *keySetStringChars = NULL;
+ if( keySet != NULL ) {
+ keySetStringChars = (char *) (env)->GetStringUTFChars( keySet, NULL);
+ }
+
+ char *keySetString = keySetStringChars;
+
+ if ( keySetString == NULL ) {
+ keySetString = (char *) DEFKEYSET_NAME;
+ }
+
+ char input[KEYLENGTH];
+ int i;
+
+ PR_fprintf(PR_STDOUT,"In SessionKey: ComputeCryptogram! \n");
+ jbyteArray handleBA=NULL;
+ jbyte *handleBytes=NULL;
+
+ jbyte *cc = NULL;
+ jbyte *hc = NULL;
+ int cc_len = 0;
+ int hc_len = 0;
+ jbyte * keyVersion = NULL;
+ int keyVersion_len = 0;
+ jbyte * cuidValue = NULL;
+
+ char *tokenNameChars = NULL;
+ char *keyNameChars=NULL;
+ PK11SlotInfo *slot = NULL;
+
+ jbyte * session_key = NULL;
+ PK11SymKey *symkey = NULL;
+ PK11SymKey *masterKey = NULL;
+ PK11SymKey *authKey = NULL;
+ PK11SymKey *authSymKey = NULL;
+
+ BYTE authData[KEYLENGTH];
+ char keyname[KEYNAMELENGTH];
+ Buffer input_x = Buffer(KEYLENGTH);
+
+ if( card_challenge != NULL ) {
+ cc = (jbyte*)(env)->GetByteArrayElements( card_challenge, NULL);
+ cc_len = (env)->GetArrayLength(card_challenge);
+ }
+
+ if( cc == NULL) {
+ goto done;
+ }
+
+ if( host_challenge != NULL ) {
+ hc = (jbyte*)(env)->GetByteArrayElements( host_challenge, NULL);
+ hc_len = (env)->GetArrayLength( host_challenge);
+ }
+
+ if( hc == NULL) {
+ goto done;
+ }
+
+ if( keyInfo != NULL) {
+ keyVersion = (jbyte*)(env)->GetByteArrayElements( keyInfo, NULL);
+ if( keyVersion) {
+ keyVersion_len = (env)->GetArrayLength(keyInfo);
+ }
+ }
+
+ if( !keyVersion || (keyVersion_len < 2) ){
+ goto done;
+ }
+
+ if( CUID != NULL) {
+ cuidValue = (jbyte*)(env)->GetByteArrayElements( CUID, NULL);
+ }
+
+ if( cuidValue == NULL) {
+ goto done;
+ }
+
+ if (type == 0) // compute host cryptogram
+ {
+ /* copy card and host challenge into input buffer */
+ for (i = 0; i < EIGHT_BYTES; i++)
+ {
+ input[i] = cc[i];
+ }
+ for (i = 0; i < EIGHT_BYTES; i++)
+ {
+ input[EIGHT_BYTES +i] = hc[i];
+ }
+ } // compute card cryptogram
+ else if (type == 1)
+ {
+ for (i = 0; i < EIGHT_BYTES; i++)
+ {
+ input[i] = hc[i];
+ }
+ for (i = 0; i < EIGHT_BYTES; i++)
+ {
+ input[EIGHT_BYTES+i] = cc[i];
+ }
+ }
+
+ input_x.replace(0, (BYTE*) input, KEYLENGTH);
+
+ GetDiversificationData(cuidValue,authData,enc);
+
+ if (tokenName)
+ {
+ tokenNameChars = (char *)(env)->GetStringUTFChars(tokenName, NULL);
+ slot = ReturnSlot(tokenNameChars);
+ (env)->ReleaseStringUTFChars(tokenName, (const char *)tokenNameChars);
+ }
+
+ if (keyName)
+ {
+ keyNameChars = (char *)(env)->GetStringUTFChars(keyName, NULL);
+ strcpy(keyname,keyNameChars);
+ (env)->ReleaseStringUTFChars(keyName, (const char *)keyNameChars);
+ }else
+ GetKeyName(keyVersion,keyname);
+
+ if ( (keyVersion[0] == 0x1 && keyVersion[1]== 0x1 &&strcmp( keyname, "#01#01") == 0 ) ||
+ (keyVersion[0] == -1 && strstr(keyname, "#FF")))
+ {
+
+ /* default manufacturers key */
+
+ authSymKey = ReturnDeveloperSymKey(slot, (char *) "auth" , keySetString, authBuff);
+ if( authSymKey == NULL ) {
+ goto done;
+ }
+
+ symkey = DeriveKey(
+ authSymKey, Buffer((BYTE*)hc, hc_len), Buffer((BYTE*)cc, cc_len));
+ }
+ else
+ {
+ masterKey = ReturnSymKey( slot,keyname);
+ if (masterKey == NULL)
+ {
+ goto done;
+ }
+
+ authKey = ComputeCardKeyOnToken(masterKey,authData);
+ if (authKey == NULL)
+ {
+ goto done;
+ }
+
+ symkey = DeriveKey(authKey,
+ Buffer((BYTE*)hc, hc_len), Buffer((BYTE*)cc, cc_len));
+
+ }
+
+ ComputeMAC(symkey, input_x, icv, output);
+ session_key = (jbyte *) (BYTE*)output;
+
+ handleBA = (env)->NewByteArray( EIGHT_BYTES);
+ handleBytes = (env)->GetByteArrayElements(handleBA, NULL);
+ if( handleBytes ) {
+ memcpy(handleBytes, session_key, EIGHT_BYTES);
+ }
+
+done:
+
+ if( slot ) {
+ PK11_FreeSlot( slot );
+ slot = NULL;
+ }
+
+ if( symkey ) {
+ PK11_FreeSymKey( symkey );
+ symkey = NULL;
+ }
+
+ if( authSymKey ) {
+ PK11_FreeSymKey( authSymKey );
+ authSymKey = NULL;
+ }
+
+ if( authKey) {
+ PK11_FreeSymKey( authKey);
+ authKey = NULL;
+ }
+
+ if( masterKey) {
+ PK11_FreeSymKey( masterKey);
+ masterKey = NULL;
+ }
+
+ if( keySetStringChars ) {
+ (env)->ReleaseStringUTFChars(keySet, (const char *)keySetStringChars);
+ keySetStringChars = NULL;
+ }
+
+ if( handleBytes != NULL) {
+ (env)->ReleaseByteArrayElements( handleBA, handleBytes, 0);
+ }
+
+ if( cc != NULL) {
+ (env)->ReleaseByteArrayElements(card_challenge, cc, JNI_ABORT);
+ }
+
+ if( hc != NULL) {
+ (env)->ReleaseByteArrayElements(host_challenge, hc, JNI_ABORT);
+ }
+
+ if( keyVersion != NULL) {
+ (env)->ReleaseByteArrayElements(keyInfo, keyVersion, JNI_ABORT);
+ }
+
+ if( cuidValue != NULL) {
+ (env)->ReleaseByteArrayElements(CUID, cuidValue, JNI_ABORT);
+ }
+
+ return handleBA;
+}
+
+
+//=================================================================================
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/*
+ * Class: com_netscape_cms_servlet_tks_ECBencrypt
+ * Method: ECBencrypt
+ * Signature: ([B[B[B[B)[B
+ */
+ JNIEXPORT jbyteArray JNICALL
+ Java_com_netscape_symkey_SessionKey_ECBencrypt
+ (JNIEnv*, jclass, jobject, jobject);
+#ifdef __cplusplus
+}
+#endif
+extern "C" JNIEXPORT jbyteArray JNICALL
+Java_com_netscape_symkey_SessionKey_ECBencrypt
+(JNIEnv* env, jclass this2, jobject symkeyObj, jobject deskeyObj )
+{
+ jbyteArray handleBA=NULL;
+ jint dlen=KEYLENGTH; // applet only supports 16 bytes
+ jbyte *handleBytes=NULL;
+
+ PK11SymKey *symkey = NULL;
+ PK11SymKey *deskey = NULL;
+ PK11SymKey *newdeskey = NULL;
+ PRStatus r = PR_FAILURE;
+ static SECItem noParams = { siBuffer, NULL, 0 };
+ SECItem wrappedKeyItem = { siBuffer, NULL, 0 };
+ SECStatus wrapStatus = SECFailure;
+
+ /* PK11_Derive vars. */
+
+ SECItem paramsItem = { siBuffer, NULL, 0 };
+ CK_ULONG bitPosition = 0;
+
+ PR_fprintf(PR_STDOUT,"In SessionKey: ECBencrypt! \n");
+
+ if( !symkeyObj || !deskeyObj) {
+ goto finish;
+ }
+
+ r = JSS_PK11_getSymKeyPtr(env, symkeyObj, &symkey);
+ if (r != PR_SUCCESS) {
+ goto finish;
+ }
+
+ r = JSS_PK11_getSymKeyPtr(env, deskeyObj, &deskey);
+ if (r != PR_SUCCESS) {
+ goto finish;
+ }
+ // Instead of playing with raw keys, let's derive the 16 byte des2 key from
+ // the 24 byte des2 key.
+
+ bitPosition = 0;
+ paramsItem.data = (CK_BYTE *) &bitPosition;
+ paramsItem.len = sizeof bitPosition;
+
+ newdeskey = PK11_Derive(deskey, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT,
+ CKA_DERIVE, 16);
+
+ if ( ! newdeskey ) {
+ goto finish;
+ }
+
+ dlen = KEYLENGTH; // applet suports only 16 bytes
+
+ handleBA = (env)->NewByteArray(dlen);
+ if(handleBA == NULL )
+ {
+ goto finish;
+ }
+ handleBytes = (jbyte *)(env)->GetByteArrayElements(handleBA, NULL);
+
+ if(handleBytes==NULL)
+ {
+ goto finish;
+ }
+
+ //Wrap the new 16 bit key with the input symkey.
+
+ wrappedKeyItem.data = (unsigned char *) handleBytes;
+ wrappedKeyItem.len = dlen;
+ wrapStatus = PK11_WrapSymKey(CKM_DES3_ECB,&noParams, symkey, newdeskey, &wrappedKeyItem);
+
+ if( wrapStatus == SECSuccess) {
+ PR_fprintf(PR_STDERR, "ECBencrypt wrapStatus %d wrappedKeySize %d \n", wrapStatus, wrappedKeyItem.len);
+ } else {
+ PR_fprintf(PR_STDERR, "ECBecrypt wrap failed! Error %d \n", PR_GetError());
+ }
+
+finish:
+
+ if( handleBytes != NULL) {
+ (env)->ReleaseByteArrayElements( handleBA, handleBytes, 0);
+ }
+
+ if ( newdeskey ) {
+ PK11_FreeSymKey( newdeskey );
+ newdeskey = NULL;
+ }
+
+ return handleBA;
+}
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/*
+ * Class: com_netscape_cms_servlet_tks_GenerateSymkey
+ * Method: GenerateSymkey
+ * Signature: ([B[B[B[B)[B
+ */
+ JNIEXPORT jobject JNICALL
+ Java_com_netscape_symkey_SessionKey_GenerateSymkey
+ (JNIEnv*, jclass, jstring);
+#ifdef __cplusplus
+}
+#endif
+extern "C" JNIEXPORT jobject JNICALL
+Java_com_netscape_symkey_SessionKey_GenerateSymkey
+(JNIEnv* env, jclass this2, jstring tokenName)
+{
+ jobject keyObj = NULL;
+ PK11SymKey *okey = NULL;
+ PK11SymKey *okeyFirstEight = NULL;
+ PK11SymKey *concatKey = NULL;
+ PK11SymKey *finalKey = NULL;
+
+ char *tokenNameChars = NULL;
+ PK11SlotInfo *slot = NULL;
+ CK_ULONG bitPosition = 0;
+ SECItem paramsItem = { siBuffer, NULL, 0 };
+ CK_OBJECT_HANDLE keyhandle = 0;
+
+ PR_fprintf(PR_STDOUT,"In SessionKey GenerateSymkey!\n");
+ if (tokenName)
+ {
+ tokenNameChars = (char *)(env)->GetStringUTFChars(tokenName, NULL);
+ if ( tokenNameChars && !strcmp(tokenNameChars, "internal")) {
+ slot = PK11_GetInternalSlot();
+ } else {
+ slot = ReturnSlot(tokenNameChars);
+ }
+
+ PR_fprintf(PR_STDOUT,"SessinKey: GenerateSymkey slot %p name %s tokenName %s \n",slot, PK11_GetSlotName(slot), PK11_GetTokenName(slot));
+ (env)->ReleaseStringUTFChars(tokenName, (const char *)tokenNameChars);
+ }
+
+ //Generate original 16 byte DES2 key
+ okey = PK11_TokenKeyGen(slot, CKM_DES2_KEY_GEN,0, 0, 0, PR_FALSE, NULL);
+
+ if (okey == NULL) {
+ goto finish;
+ }
+
+ // Extract first eight bytes from generated key into another key.
+ bitPosition = 0;
+ paramsItem.data = (CK_BYTE *) &bitPosition;
+ paramsItem.len = sizeof bitPosition;
+
+ okeyFirstEight = PK11_Derive(okey, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT , CKA_DERIVE, 8);
+ if (okeyFirstEight == NULL ) {
+ goto finish;
+ }
+
+ //Concatenate 8 byte key to the end of the original key, giving new 24 byte key
+ keyhandle = PK11_GetSymKeyHandle(okeyFirstEight);
+ paramsItem.data=(unsigned char *) &keyhandle;
+ paramsItem.len=sizeof(keyhandle);
+
+ concatKey = PK11_Derive ( okey , CKM_CONCATENATE_BASE_AND_KEY , &paramsItem ,CKM_DES3_ECB , CKA_DERIVE , 0);
+ if ( concatKey == NULL ) {
+ goto finish;
+ }
+
+ //Make sure we move this to the orig token, in case it got moved by NSS
+ //during the derive phase.
+
+ finalKey = PK11_MoveSymKey ( slot, CKA_ENCRYPT, 0, PR_FALSE, concatKey);
+
+ /* wrap the symkey in java object. This sets symkey to NULL. */
+ keyObj = JSS_PK11_wrapSymKey(env, &finalKey, NULL);
+
+finish:
+ if ( slot != NULL) {
+ PK11_FreeSlot(slot);
+ slot = NULL;
+ }
+
+ if ( okey != NULL) {
+ PK11_FreeSymKey(okey);
+ okey = NULL;
+ }
+
+ if ( okeyFirstEight != NULL) {
+ PK11_FreeSymKey(okeyFirstEight);
+ okeyFirstEight = NULL;
+ }
+
+ if ( concatKey != NULL) {
+ PK11_FreeSymKey(concatKey);
+ concatKey = NULL;
+ }
+
+ if ( finalKey != NULL) {
+ PK11_FreeSymKey(finalKey);
+ finalKey = NULL;
+ }
+
+ return keyObj;
+}
+
+// begin DRM proto
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/*
+ * Class: com_netscape_cms_servlet_tks_RASessionKey
+ * Method: bytes2PK11SymKey
+ * Signature:
+ */
+ JNIEXPORT jobject JNICALL Java_com_netscape_symkey_SessionKey_bytes2PK11SymKey
+ (JNIEnv *, jclass, jbyteArray);
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef DRM_SUPPORT_DEBUG
+extern "C" JNIEXPORT jobject JNICALL Java_com_netscape_symkey_SessionKey_bytes2PK11SymKey(JNIEnv * env, jclass this2, jbyteArray symKeyBytes)
+{
+ PK11SlotInfo *slot=NULL;
+ jobject keyObj = NULL;
+ PK11SymKey *symKey=NULL;
+
+// how about do unwrap (decrypt of the symkey in here??
+
+// DRM proto just use internal slot
+ slot = PK11_GetInternalKeySlot();
+
+ BYTE masterKeyData[24];
+ SECItem masterKeyItem = {siBuffer, masterKeyData, sizeof(masterKeyData)};
+
+ memcpy(masterKeyData, (char*)symKeyBytes, 16);
+ memcpy(masterKeyData+16, (char*)symKeyBytes, 8);
+
+ // ToDo: possibly get rid of whole function, not used
+ // For now , no need to get rid of PK11_ImportSymKeyWithFlags call.
+
+ symKey = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
+ PK11_OriginUnwrap, CKA_ENCRYPT, &masterKeyItem,
+ ALL_SYMKEY_OPS /*CKF_ENCRYPT*/, PR_FALSE, 0);
+
+ /* wrap the symkey in java object. This sets symkey to NULL. */
+ keyObj = JSS_PK11_wrapSymKey(env, &symKey, debug_fd);
+
+finish:
+ return keyObj;
+}
+
+
+// end DRM proto
+#endif // DRM_SUPPORT_DEBUG
diff --git a/base/symkey/src/com/netscape/symkey/SessionKey.java b/base/symkey/src/com/netscape/symkey/SessionKey.java
new file mode 100644
index 000000000..47f9385f7
--- /dev/null
+++ b/base/symkey/src/com/netscape/symkey/SessionKey.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.symkey;
+
+import org.mozilla.jss.pkcs11.PK11SymKey;
+
+/**
+ * This object contains the OS independent interfaces.
+ */
+public class SessionKey {
+ static boolean tryLoad(String filename) {
+ try {
+ System.load(filename);
+ } catch (Exception e) {
+ return false;
+ } catch (UnsatisfiedLinkError e) {
+ return false;
+ }
+
+ return true;
+ }
+
+ // Load native library
+ static {
+ boolean mNativeLibrariesLoaded = false;
+ String os = System.getProperty("os.name");
+ if ((os.equals("Linux"))) {
+ // Check for 64-bit library availability
+ // prior to 32-bit library availability.
+ mNativeLibrariesLoaded =
+ tryLoad("/usr/lib64/symkey/libsymkey.so");
+ if (mNativeLibrariesLoaded) {
+ System.out.println("64-bit symkey library loaded");
+ } else {
+ // REMINDER: May be trying to run a 32-bit app
+ // on 64-bit platform.
+ mNativeLibrariesLoaded =
+ tryLoad("/usr/lib/symkey/libsymkey.so");
+ if (mNativeLibrariesLoaded) {
+ System.out.println("32-bit symkey library loaded");
+ } else {
+ System.out.println("FAILED loading symkey library!");
+ System.exit(-1);
+ }
+ }
+ } else {
+ try {
+ System.loadLibrary("symkey");
+ System.out.println("symkey library loaded");
+ mNativeLibrariesLoaded = true;
+ } catch (Throwable t) {
+ // This is bad news, the program is doomed at this point
+ t.printStackTrace();
+ }
+ }
+ }
+
+ // external calls from RA
+ public static native byte[] ComputeKeyCheck(PK11SymKey desKey); /* byte data[] ); */
+
+ public static native byte[] ComputeSessionKey(String tokenName,
+ String keyName,
+ byte[] card_challenge,
+ byte[] host_challenge,
+ byte[] keyInfo,
+ byte[] CUID,
+ byte[] macKeyArray,
+ String useSoftToken,
+ String keySet,
+ String sharedSecretKeyName);
+
+ public static native byte[] ComputeEncSessionKey(String tokenName,
+ String keyName,
+ byte[] card_challenge,
+ byte[] host_challenge,
+ byte[] keyInfo,
+ byte[] CUID,
+ byte[] encKeyArray,
+ String useSoftToken,
+ String keySet);
+
+ public static native PK11SymKey ComputeKekSessionKey(String tokenName,
+ String keyName,
+ byte[] card_challenge,
+ byte[] host_challenge,
+ byte[] keyInfo,
+ byte[] CUID,
+ byte[] kekKeyArray,
+ String useSoftToken,
+ String keySet);
+
+ public static native PK11SymKey ComputeKekKey(String tokenName,
+ String keyName,
+ byte[] card_challenge,
+ byte[] host_challenge,
+ byte[] keyInfo,
+ byte[] CUID,
+ byte[] kekKeyArray,
+ String useSoftToken, String keySet);
+
+ public static native byte[] ECBencrypt(PK11SymKey key,
+ PK11SymKey desKey); //byte[] data );
+
+ public static native PK11SymKey GenerateSymkey(String tokenName);
+
+ /*
+ * DRM_SUPPORT_DEBUG
+ */
+
+ // public static native PK11SymKey bytes2PK11SymKey( byte[] symKeyBytes );
+
+ public static native byte[] ComputeCryptogram(String tokenName,
+ String keyName,
+ byte[] card_challenge,
+ byte[] host_challenge,
+ byte[] keyInfo,
+ byte[] CUID,
+ int type,
+ byte[] authKeyArray,
+ String useSoftToken, String keySet);
+
+ public static native byte[] EncryptData(String tokenName,
+ String keyName,
+ byte[] in,
+ byte[] keyInfo,
+ byte[] CUID,
+ byte[] kekKeyArray,
+ String useSoftToken, String keySet);
+
+ public static native byte[] DiversifyKey(String tokenName,
+ String newTokenName,
+ String oldMasterKeyName,
+ String newMasterKeyName,
+ String keyInfo,
+ byte[] CUIDValue,
+ byte[] kekKeyArray,
+ String useSoftToken, String keySet);
+
+ // internal calls from config TKS keys tab
+ public static native String GenMasterKey(String token,
+ String keyName);
+
+ public static native String DeleteSymmetricKey(String token,
+ String keyName);
+
+ public static native String ListSymmetricKeys(String token);
+
+ // set when called from the config TKS tab to create master key
+ // get when called from the RA to create session key
+ public static native void SetDefaultPrefix(String masterPrefix);
+}
diff --git a/base/symkey/src/com/netscape/symkey/SymKey.cpp b/base/symkey/src/com/netscape/symkey/SymKey.cpp
new file mode 100644
index 000000000..c300d1ada
--- /dev/null
+++ b/base/symkey/src/com/netscape/symkey/SymKey.cpp
@@ -0,0 +1,1407 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#if defined(WIN32)
+#include "fcntl.h"
+#include "io.h"
+#endif
+
+#if defined(XP_UNIX)
+#include <unistd.h>
+#include <sys/time.h>
+#include <termios.h>
+#endif
+
+#if defined(XP_WIN) || defined (XP_PC)
+#include <time.h>
+#include <conio.h>
+#endif
+
+#include "nspr.h"
+#include "prtypes.h"
+#include "prtime.h"
+#include "prlong.h"
+#include "pk11func.h"
+#include "secasn1.h"
+#include "cert.h"
+#include "cryptohi.h"
+#include "secoid.h"
+#include "certdb.h"
+#include "nss.h"
+
+#include "nspr.h"
+#ifdef __cplusplus
+#include <jni.h>
+#include <assert.h>
+#include <string.h>
+
+}
+#endif
+#include <memory.h>
+#include <assert.h>
+#include <stdio.h>
+#include <cstdarg>
+#include <string>
+
+#include "Buffer.h"
+#include "SymKey.h"
+
+typedef unsigned char BYTE;
+
+typedef struct
+{
+ enum
+ {
+ PW_NONE = 0,
+ PW_FROMFILE = 1,
+ PW_PLAINTEXT = 2,
+ PW_EXTERNAL = 3
+ } source;
+ char *data;
+} secuPWData;
+
+char masterKeyPrefix[PREFIXLENGHT];
+char masterKeyNickName[KEYNAMELENGTH];
+char masterNewKeyNickName[KEYNAMELENGTH];
+char sharedSecretSymKeyName[KEYNAMELENGTH] = { 0 };
+
+//=================================================================================
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/*
+ * Class: com_netscape_cms_servlet_tks_RASessionKey
+ * Method: ListSymmetricKeys
+ * Signature: (Ljava/lang/String;)Ljava/lang/String;
+ */
+ JNIEXPORT jstring JNICALL Java_com_netscape_symkey_SessionKey_ListSymmetricKeys
+ (JNIEnv *, jclass, jstring);
+
+#ifdef __cplusplus
+}
+#endif
+
+PK11SlotInfo *ReturnSlot(char *tokenNameChars)
+{
+ if( tokenNameChars == NULL)
+ {
+ return NULL;
+ }
+ PK11SlotInfo *slot=NULL;
+
+ if(!strcmp( tokenNameChars, "internal" ) || !strcmp( tokenNameChars, "Internal Key Storage Token"))
+ {
+ slot = PK11_GetInternalKeySlot();
+ }
+ else
+ {
+ slot = PK11_FindSlotByName( tokenNameChars );
+ }
+ return slot;
+}
+
+
+/* Find the Symmetric key with the given nickname
+ Returns null if the key could not be found
+ Steve wrote this code to replace the old impl */
+
+PK11SymKey * ReturnSymKey( PK11SlotInfo *slot, char *keyname)
+{
+ char *name = NULL;
+ PK11SymKey *foundSymKey= NULL;
+ PK11SymKey *firstSymKey= NULL;
+ PK11SymKey *sk = NULL;
+ PK11SymKey *nextSymKey = NULL;
+ secuPWData pwdata;
+
+ pwdata.source = secuPWData::PW_NONE;
+ pwdata.data = (char *) NULL;
+ PR_fprintf(PR_STDOUT,"In ReturnSymKey name %s \n",keyname);
+ if (keyname == NULL)
+ {
+ goto cleanup;
+ }
+ if (slot== NULL)
+ {
+ goto cleanup;
+ }
+ /* Initialize the symmetric key list. */
+ firstSymKey = PK11_ListFixedKeysInSlot( slot , NULL, ( void *) &pwdata );
+ /* scan through the symmetric key list for a key matching our nickname */
+ sk = firstSymKey;
+ while( sk != NULL )
+ {
+ /* get the nickname of this symkey */
+ name = PK11_GetSymKeyNickname( sk );
+
+ /* if the name matches, make a 'copy' of it */
+ if ( name != NULL && !strcmp( keyname, name ))
+ {
+ if (foundSymKey == NULL)
+ {
+ foundSymKey = PK11_ReferenceSymKey(sk);
+ }
+ PORT_Free(name);
+ }
+
+ sk = PK11_GetNextSymKey( sk );
+ }
+
+ /* We're done with the list now, let's free all the keys in it
+ It's okay to free our key, because we made a copy of it */
+
+ sk = firstSymKey;
+ while( sk != NULL )
+ {
+ nextSymKey = PK11_GetNextSymKey(sk);
+ PK11_FreeSymKey(sk);
+ sk = nextSymKey;
+ }
+
+ cleanup:
+ return foundSymKey;
+}
+
+
+extern "C" JNIEXPORT jstring
+JNICALL Java_com_netscape_symkey_SessionKey_DeleteKey(JNIEnv * env, jclass this2, jstring tokenName, jstring keyName)
+
+{
+ char *tokenNameChars;
+ char *keyNameChars;
+ int count = 0;
+ int keys_deleted = 0;
+ PK11SymKey *symKey = NULL;
+ PK11SymKey *nextSymKey = NULL;
+ PK11SlotInfo *slot = NULL;
+ SECStatus rv;
+ secuPWData pwdata;
+ pwdata.source = secuPWData::PW_NONE;
+ pwdata.data = (char *) NULL;
+ jstring retval = NULL;
+
+ tokenNameChars = (char *)(env)->GetStringUTFChars(tokenName, NULL);
+ keyNameChars = (char *)(env)->GetStringUTFChars(keyName, NULL);
+ char *result= (char *)malloc(1);
+
+ result[0] = '\0';
+ if( tokenNameChars == NULL || keyNameChars==NULL)
+ {
+ goto finish;
+ }
+ if(strcmp( tokenNameChars, "internal" ) == 0 )
+ {
+ slot = PK11_GetInternalKeySlot();
+ }
+ else if( tokenNameChars != NULL )
+ {
+ slot = PK11_FindSlotByName( tokenNameChars );
+ }
+ /* Initialize the symmetric key list. */
+ symKey = PK11_ListFixedKeysInSlot( slot , NULL, ( void *) &pwdata );
+
+ /* Iterate through the symmetric key list. */
+ while( symKey != NULL )
+ {
+ char *name = NULL;
+ rv = SECFailure;
+ name = PK11_GetSymKeyNickname( symKey );
+
+ if( strcmp( keyNameChars, name ) == 0 )
+ {
+ rv = PK11_DeleteTokenSymKey( symKey );
+ }
+ PORT_Free(name);
+
+ if( rv != SECFailure )
+ {
+ keys_deleted++;
+ }
+
+ nextSymKey = PK11_GetNextSymKey( symKey );
+ PK11_FreeSymKey( symKey );
+ symKey = nextSymKey;
+
+ count++;
+ }
+
+ if( keys_deleted == 0 )
+ {
+
+ rv = SECFailure;
+ }
+ else
+ {
+
+ rv = SECSuccess;
+ }
+
+ finish:
+ if (slot)
+ {
+ PK11_FreeSlot(slot);
+ }
+ if(tokenNameChars)
+ {
+ (env)->ReleaseStringUTFChars(tokenName, (const char *)tokenNameChars);
+ }
+ if(keyNameChars)
+ {
+ (env)->ReleaseStringUTFChars(keyName, (const char *)keyNameChars);
+ }
+ retval = (env)->NewStringUTF( result);
+ free(result);
+ return retval;
+}
+
+
+#define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
+(x)->pValue=(v); (x)->ulValueLen = (l);
+
+extern "C" JNIEXPORT jstring
+JNICALL Java_com_netscape_symkey_SessionKey_ListSymmetricKeys(JNIEnv * env, jclass this2, jstring tokenName)
+{
+ char *tokenNameChars;
+ jstring retval = NULL;
+ PK11SymKey *symKey = NULL;
+ PK11SymKey *nextSymKey = NULL;
+ secuPWData pwdata;
+ pwdata.source = secuPWData::PW_NONE;
+ pwdata.data = (char *) NULL;
+ PK11SlotInfo *slot = NULL;
+
+ tokenNameChars = (char *)(env)->GetStringUTFChars(tokenName, NULL);
+ char *result= (char *)malloc(1);
+ result[0] = '\0';
+ if( tokenNameChars == NULL )
+ {
+ goto finish;
+ }
+ if(strcmp( tokenNameChars, "internal" ) == 0 )
+ {
+ slot = PK11_GetInternalKeySlot();
+ }
+ else if( tokenNameChars != NULL )
+ {
+ slot = PK11_FindSlotByName( tokenNameChars );
+ }
+
+ /* Initialize the symmetric key list. */
+ symKey = PK11_ListFixedKeysInSlot( slot , NULL, (void *)&pwdata );
+
+ /* Iterate through the symmetric key list. */
+ while (symKey != NULL)
+ {
+ int count = 0;
+ char *name = NULL;
+ char *temp = NULL;
+ name = PK11_GetSymKeyNickname( symKey );
+ temp = result;
+ result = (char*)malloc( strlen(name) + strlen(temp) + 2 );
+ result[0]='\0';
+ strcat(result, temp);
+ strcat(result, ",");
+ strcat(result, name);
+ free(temp);
+
+ PORT_Free(name);
+
+ nextSymKey = PK11_GetNextSymKey( symKey );
+ PK11_FreeSymKey( symKey );
+ symKey = nextSymKey;
+
+ count++;
+ }
+
+ finish:
+ if (slot)
+ {
+ PK11_FreeSlot(slot);
+ }
+ if(tokenNameChars)
+ {
+ (env)->ReleaseStringUTFChars(tokenName, (const char *)tokenNameChars);
+ }
+ retval = (env)->NewStringUTF(result);
+ free(result);
+ return retval;
+}
+
+
+/* DES KEY Parity conversion table. Takes each byte/2 as an index, returns
+ * that byte with the proper parity bit set */
+static const unsigned char parityTable[256] =
+{
+/* Even...0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e */
+ /* E */ 0x01,0x02,0x04,0x07,0x08,0x0b,0x0d,0x0e,
+/* Odd....0x10,0x12,0x14,0x16,0x18,0x1a,0x1c,0x1e */
+ /* O */ 0x10,0x13,0x15,0x16,0x19,0x1a,0x1c,0x1f,
+/* Odd....0x20,0x22,0x24,0x26,0x28,0x2a,0x2c,0x2e */
+ /* O */ 0x20,0x23,0x25,0x26,0x29,0x2a,0x2c,0x2f,
+/* Even...0x30,0x32,0x34,0x36,0x38,0x3a,0x3c,0x3e */
+ /* E */ 0x31,0x32,0x34,0x37,0x38,0x3b,0x3d,0x3e,
+/* Odd....0x40,0x42,0x44,0x46,0x48,0x4a,0x4c,0x4e */
+ /* O */ 0x40,0x43,0x45,0x46,0x49,0x4a,0x4c,0x4f,
+/* Even...0x50,0x52,0x54,0x56,0x58,0x5a,0x5c,0x5e */
+ /* E */ 0x51,0x52,0x54,0x57,0x58,0x5b,0x5d,0x5e,
+/* Even...0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6e */
+ /* E */ 0x61,0x62,0x64,0x67,0x68,0x6b,0x6d,0x6e,
+/* Odd....0x70,0x72,0x74,0x76,0x78,0x7a,0x7c,0x7e */
+ /* O */ 0x70,0x73,0x75,0x76,0x79,0x7a,0x7c,0x7f,
+/* Odd....0x80,0x82,0x84,0x86,0x88,0x8a,0x8c,0x8e */
+ /* O */ 0x80,0x83,0x85,0x86,0x89,0x8a,0x8c,0x8f,
+/* Even...0x90,0x92,0x94,0x96,0x98,0x9a,0x9c,0x9e */
+ /* E */ 0x91,0x92,0x94,0x97,0x98,0x9b,0x9d,0x9e,
+/* Even...0xa0,0xa2,0xa4,0xa6,0xa8,0xaa,0xac,0xae */
+ /* E */ 0xa1,0xa2,0xa4,0xa7,0xa8,0xab,0xad,0xae,
+/* Odd....0xb0,0xb2,0xb4,0xb6,0xb8,0xba,0xbc,0xbe */
+ /* O */ 0xb0,0xb3,0xb5,0xb6,0xb9,0xba,0xbc,0xbf,
+/* Even...0xc0,0xc2,0xc4,0xc6,0xc8,0xca,0xcc,0xce */
+ /* E */ 0xc1,0xc2,0xc4,0xc7,0xc8,0xcb,0xcd,0xce,
+/* Odd....0xd0,0xd2,0xd4,0xd6,0xd8,0xda,0xdc,0xde */
+ /* O */ 0xd0,0xd3,0xd5,0xd6,0xd9,0xda,0xdc,0xdf,
+/* Odd....0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xee */
+ /* O */ 0xe0,0xe3,0xe5,0xe6,0xe9,0xea,0xec,0xef,
+/* Even...0xf0,0xf2,0xf4,0xf6,0xf8,0xfa,0xfc,0xfe */
+ /* E */ 0xf1,0xf2,0xf4,0xf7,0xf8,0xfb,0xfd,0xfe,
+};
+
+void
+pk11_FormatDESKey(unsigned char *key, int length)
+{
+ int i;
+
+ /* format the des key */
+ for (i=0; i < length; i++)
+ {
+ key[i] = parityTable[key[i]>>1];
+ }
+}
+
+
+static secuPWData pwdata = { secuPWData::PW_NONE, 0 };
+
+/**
+ * Internal token is required when we are doing key diversification
+ * where raw key material needs to be accessed
+ */
+PK11SymKey *ComputeCardKeyOnSoftToken(PK11SymKey *masterKey, unsigned char *data)
+{
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+ PK11SymKey *key = ComputeCardKey(masterKey, data, slot);
+ if( slot != NULL) {
+ PK11_FreeSlot(slot);
+ slot = NULL;
+ }
+
+ return key;
+}
+
+PK11SymKey *ComputeCardKey(PK11SymKey *masterKey, unsigned char *data, PK11SlotInfo *slot)
+{
+ PK11SymKey *key = NULL;
+ PK11Context *context = NULL;
+ int keysize = DES3_LENGTH;
+ unsigned char *keyData = NULL;
+ SECStatus s = SECSuccess;
+ int i = 0;
+ int len = 0;
+ static SECItem noParams = { siBuffer, NULL, 0 };
+ unsigned char *in = data;
+ PK11SymKey *tmpkey = NULL;
+ unsigned char wrappedkey[DES3_LENGTH];
+ SECItem wrappeditem = { siBuffer, NULL, 0 };
+
+ keyData = (unsigned char*)malloc(keysize);
+
+ for (i = 0;i < keysize; i++)
+ {
+ keyData[i] = 0x0;
+ }
+
+ if (masterKey == NULL) {
+ PR_fprintf(PR_STDERR,"ComputeCardKey: master key is null.\n");
+ goto done;
+ }
+
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT,
+ masterKey,
+ &noParams);
+
+ if (context == NULL) {
+ PR_fprintf(PR_STDERR,"ComputeCardKey: failed to create context.\n");
+ goto done;
+ }
+
+ /* Part 1 */
+ s = PK11_CipherOp(context, &keyData[0], &len, 8, in, 8);
+ if (s != SECSuccess) {
+ PR_fprintf(PR_STDERR,"ComputeCardKey: failed to encrypt #1\n");
+ goto done;
+ }
+ pk11_FormatDESKey(&keyData[0], EIGHT_BYTES); /* set parity */
+
+ /* Part 2 */
+ s = PK11_CipherOp(context, &keyData[EIGHT_BYTES], &len, EIGHT_BYTES, in+EIGHT_BYTES, EIGHT_BYTES);
+ if (s != SECSuccess) {
+ PR_fprintf(PR_STDERR,"ComputeCardKey: failed to encryp #2.\n");
+ goto done;
+ }
+ pk11_FormatDESKey(&keyData[EIGHT_BYTES], EIGHT_BYTES);
+
+ /* Part 3 */
+ for(i = 0;i < EIGHT_BYTES;i++)
+ {
+ keyData[i+KEYLENGTH] = keyData[i];
+ }
+
+#define CKF_KEY_OPERATION_FLAGS 0x000e7b00UL
+
+ /* generate a tmp key to import the sym key */
+ tmpkey = PK11_TokenKeyGenWithFlags(slot,
+ CKM_DES3_KEY_GEN, 0, 0, 0,
+ (CKF_WRAP | CKF_UNWRAP | CKF_ENCRYPT | CKF_DECRYPT) & CKF_KEY_OPERATION_FLAGS,
+ PR_FALSE, &pwdata);
+
+ if (tmpkey == NULL) {
+ PR_fprintf(PR_STDERR,"ComputeCardKey: failed to keygen. \n");
+ goto done;
+ }
+
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT,
+ tmpkey,
+ &noParams);
+
+ if (context == NULL) {
+ PR_fprintf(PR_STDERR,"ComputeCardKey: failed to set context. \n");
+ goto done;
+ }
+
+ /* encrypt the key with the master key */
+ s = PK11_CipherOp(context, wrappedkey, &len, 24, keyData, 24);
+ if (s != SECSuccess)
+ {
+ PR_fprintf(PR_STDERR,"ComputeCardKey: failed to encrypt #3.\n");
+ goto done;
+ }
+
+ wrappeditem.data = wrappedkey;
+ wrappeditem.len = len;
+
+ key = PK11_UnwrapSymKeyWithFlags(tmpkey, CKM_DES3_ECB, &noParams,
+ &wrappeditem, CKM_DES3_KEY_GEN, CKA_DECRYPT, 24,
+ (CKA_ENCRYPT | CKA_DECRYPT) & CKF_KEY_OPERATION_FLAGS );
+
+done:
+ if (keyData != NULL)
+ {
+ free(keyData);
+ }
+ if (context != NULL)
+ {
+ PK11_DestroyContext(context, PR_TRUE);
+ context = NULL;
+ }
+ if (tmpkey != NULL)
+ {
+ PK11_FreeSymKey(tmpkey);
+ tmpkey = NULL;
+ }
+
+ return key;
+}
+
+PK11SymKey * ComputeCardKeyOnToken(PK11SymKey *masterKey, BYTE* data)
+{
+ PK11SlotInfo *slot = PK11_GetSlotFromKey(masterKey);
+ PK11SymKey *key = ComputeCardKey(masterKey, data, slot);
+
+ if( slot) {
+ PK11_FreeSlot(slot);
+ slot = NULL;
+ }
+
+ return key;
+}
+
+// Either encrypt data with a provided SymKey OR a key buffer array (for the Default keyset case).
+PRStatus EncryptData(const Buffer &kek_key,PK11SymKey *cardKey, Buffer &input, Buffer &output)
+{
+ PRStatus rv = PR_FAILURE;
+
+ PK11SymKey *master = NULL;
+ PK11SymKey *transportKey = NULL;
+ PK11SlotInfo *slot = NULL;
+ PK11Context *context = NULL;
+ int i = 0;
+ SECStatus s = SECFailure;
+ int len = 0;
+ static SECItem noParams = { siBuffer, NULL, 0 };
+#ifdef DES2_WORKAROUND
+ unsigned char masterKeyData[DES3_LENGTH];
+#else
+ unsigned char masterKeyData[KEYLENGTH];
+#endif
+ unsigned char result[EIGHT_BYTES];
+
+ slot = PK11_GetInternalKeySlot();
+
+ if (slot == NULL) {
+ goto done;
+ }
+
+ if ( cardKey == NULL ) { /* Developer key set mode.*/
+ transportKey = ReturnSymKey( slot, GetSharedSecretKeyName(NULL));
+
+ /* convert 16-byte to 24-byte triple-DES key */
+ memcpy(masterKeyData, kek_key, 16);
+ memcpy(masterKeyData+16, kek_key, 8);
+
+ master = CreateUnWrappedSymKeyOnToken( slot, transportKey, masterKeyData, sizeof(masterKeyData), PR_FALSE);
+
+ } else {
+ master = cardKey;
+ }
+
+ if( master == NULL) {
+ goto done;
+ }
+
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, master,
+ &noParams);
+
+ if (context == NULL) {
+ goto done;
+ }
+
+ for(i = 0;i < (int)input.size();i += EIGHT_BYTES)
+ {
+ s = PK11_CipherOp(context, result, &len, EIGHT_BYTES,
+ (unsigned char *)(((BYTE*)input)+i), EIGHT_BYTES);
+
+ if (s != SECSuccess) {
+ goto done;
+ }
+ output.replace(i, result, EIGHT_BYTES);
+ }
+
+ rv = PR_SUCCESS;
+
+done:
+
+ memset(masterKeyData, 0, sizeof masterKeyData);
+ if (context)
+ {
+ PK11_DestroyContext(context, PR_TRUE);
+ context = NULL;
+ }
+ if (slot)
+ {
+ PK11_FreeSlot(slot);
+ slot = NULL;
+ }
+ if (master && cardKey == NULL)
+ {
+ PK11_FreeSymKey(master);
+ master = NULL;
+ }
+
+ return rv;
+}
+
+PRStatus ComputeKeyCheckWithSymKey(PK11SymKey * newKey, Buffer& output)
+{
+ PK11SymKey *key = NULL;
+ PRStatus status = PR_FAILURE ;
+ PK11SlotInfo *slot = NULL;
+ PK11Context *context = NULL;
+ SECStatus s = SECFailure;
+ int len = 0;
+ static SECItem noParams = { siBuffer, NULL, 0 };
+ unsigned char value[EIGHT_BYTES];
+
+ if ( newKey == NULL ) {
+ return status;
+ }
+
+ memset(value, 0, sizeof value);
+
+ slot = PK11_GetInternalKeySlot();
+ if (slot != NULL)
+ {
+ key = newKey ;
+ if( key != NULL )
+ {
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, key,
+ &noParams);
+ if (context != NULL)
+ {
+ s = PK11_CipherOp(context, &value[0], &len, 8, &value[0], 8);
+
+ if (s == SECSuccess)
+ {
+ output.resize(3);
+ output.replace(0, value, 3);
+ status = PR_SUCCESS;
+ }
+ PK11_DestroyContext(context, PR_TRUE);
+ context = NULL;
+ }
+ //PK11_FreeSymKey(key);
+ //key = NULL;
+
+ }
+ if( slot != NULL) {
+ PK11_FreeSlot(slot);
+ slot = NULL;
+ }
+ }
+
+ return status;
+}
+
+// Create key set data with the help of either a provided old_keyk_ke2_sym key or key buffer (for the Default keyset case).
+PRStatus CreateKeySetDataWithSymKeys( Buffer &newMasterVer,const Buffer &old_kek_key2, PK11SymKey *old_kek_key2_sym, PK11SymKey *new_auth_key, PK11SymKey *new_mac_key, PK11SymKey *new_kek_key, Buffer &output)
+{
+ PRStatus rv = PR_FAILURE;
+ static SECItem noParams = { siBuffer, NULL, 0 };
+ PK11SymKey *transportKey = NULL;
+ PK11SymKey *wrappingKey = NULL;
+ BYTE masterKeyData[DES3_LENGTH];
+
+ /* Wrapping vars */
+ SECItem wrappedKeyItem = { siBuffer, NULL , 0 };
+ SECStatus wrapStatus = SECFailure;
+ PK11SlotInfo *slot = NULL;
+ /* Extracting vars */
+
+ CK_ULONG bitPosition = 0;
+ SECItem paramsItem = { siBuffer, NULL, 0 };
+ paramsItem.data = (CK_BYTE *) &bitPosition;
+ paramsItem.len = sizeof bitPosition;
+
+ PK11SymKey *macKey16 = NULL;
+ PK11SymKey *authKey16 = NULL;
+ PK11SymKey *kekKey16 = NULL;
+
+ Buffer encrypted_auth_key(KEYLENGTH);
+ Buffer encrypted_mac_key(KEYLENGTH);
+ Buffer encrypted_kek_key(KEYLENGTH);
+
+ Buffer kc_auth_key(3);
+ Buffer kc_mac_key(3);
+ Buffer kc_kek_key(3);
+ Buffer result;
+
+ PR_fprintf(PR_STDOUT,"In CreateKeySetDataWithSymKeys!\n");
+
+ if ( new_auth_key == NULL || new_mac_key == NULL || new_kek_key == NULL) {
+ return rv;
+ }
+
+ slot = PK11_GetSlotFromKey(new_auth_key);
+ if ( old_kek_key2_sym == NULL ) { /* perm key mode */
+ /* Find transport key, shared secret */
+ transportKey = ReturnSymKey( slot, GetSharedSecretKeyName(NULL));
+ if ( transportKey == NULL ) {
+ goto done;
+ }
+
+ /* convert 16-byte to 24-byte triple-DES key */
+ memcpy(masterKeyData, old_kek_key2, KEYLENGTH);
+ memcpy(masterKeyData+16, old_kek_key2, EIGHT_BYTES);
+
+ wrappingKey = CreateUnWrappedSymKeyOnToken( slot, transportKey, masterKeyData, sizeof(masterKeyData), PR_FALSE);
+
+ } else { /* card key mode */
+ wrappingKey = old_kek_key2_sym;
+ }
+
+ //Now derive 16 byte versions of the provided symkeys
+ authKey16 = PK11_Derive(new_auth_key, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT,
+ CKA_DERIVE, 16);
+
+ if ( authKey16 == NULL ) {
+ PR_fprintf(PR_STDERR,"Error deriving authKey16. Error %d \n", PR_GetError());
+ goto done;
+ }
+
+ wrappedKeyItem.data = (unsigned char *) encrypted_auth_key;
+ wrappedKeyItem.len = encrypted_auth_key.size();
+ wrapStatus = PK11_WrapSymKey(CKM_DES3_ECB,&noParams, wrappingKey, authKey16, &wrappedKeyItem);
+ if ( wrapStatus == SECFailure ) {
+ PR_fprintf(PR_STDERR,"Error wrapping authKey16. Error %d \n", PR_GetError());
+ goto done;
+ }
+
+ macKey16 = PK11_Derive(new_mac_key, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT, CKA_DERIVE, 16);
+
+ if ( macKey16 == NULL ) {
+ PR_fprintf(PR_STDERR,"Error deriving macKey16. Error %d \n", PR_GetError());
+ goto done;
+ }
+
+ wrappedKeyItem.data = (unsigned char *) encrypted_mac_key;
+ wrappedKeyItem.len = encrypted_mac_key.size();
+ wrapStatus = PK11_WrapSymKey(CKM_DES3_ECB,&noParams, wrappingKey, macKey16, &wrappedKeyItem);
+ if ( wrapStatus == SECFailure) {
+ PR_fprintf(PR_STDERR,"Error wrapping macKey16. Error %d \n", PR_GetError());
+ goto done;
+ }
+
+ kekKey16 = PK11_Derive(new_kek_key, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT,
+ CKA_DERIVE, 16);
+
+ if ( kekKey16 == NULL ) {
+ goto done;
+ PR_fprintf(PR_STDERR,"Error deriving kekKey16. Error %d \n", PR_GetError());
+ }
+
+ wrappedKeyItem.data = (unsigned char *) encrypted_kek_key;
+ wrappedKeyItem.len = encrypted_mac_key.size();
+ wrapStatus = PK11_WrapSymKey(CKM_DES3_ECB,&noParams, wrappingKey, kekKey16, &wrappedKeyItem);
+ if ( wrapStatus == SECFailure) {
+ PR_fprintf(PR_STDERR,"Error wrapping kekKey16. Error %d \n", PR_GetError());
+ goto done;
+ }
+
+ ComputeKeyCheckWithSymKey(new_auth_key, kc_auth_key);
+
+ ComputeKeyCheckWithSymKey(new_mac_key, kc_mac_key);
+
+ ComputeKeyCheckWithSymKey(new_kek_key, kc_kek_key);
+
+ result = newMasterVer +
+ Buffer(1, (BYTE)0x81) +
+ Buffer(1, (BYTE)0x10) +
+ encrypted_auth_key +
+ Buffer(1, (BYTE)0x03) +
+ kc_auth_key +
+ Buffer(1, (BYTE)0x81) +
+ Buffer(1, (BYTE)0x10) +
+ encrypted_mac_key +
+ Buffer(1, (BYTE)0x03) +
+ kc_mac_key +
+ Buffer(1, (BYTE)0x81) +
+ Buffer(1, (BYTE)0x10) +
+ encrypted_kek_key +
+ Buffer(1, (BYTE)0x03) +
+ kc_kek_key;
+ output = result;
+
+ rv = PR_SUCCESS;
+
+done:
+
+ if ( kekKey16 != NULL) {
+ PK11_FreeSymKey( kekKey16);
+ kekKey16 = NULL;
+ }
+
+ if ( authKey16 != NULL) {
+ PK11_FreeSymKey( authKey16);
+ authKey16 = NULL;
+ }
+
+ if ( macKey16 != NULL) {
+ PK11_FreeSymKey( macKey16);
+ macKey16 = NULL;
+ }
+
+ if ( slot != NULL ) {
+ PK11_FreeSlot( slot);
+ slot = NULL;
+ }
+
+ if ( transportKey != NULL ) {
+ PK11_FreeSymKey( transportKey);
+ transportKey = NULL;
+ }
+
+ return rv;
+}
+
+void GetDiversificationData(jbyte *cuidValue,BYTE *KDC,keyType keytype)
+{
+ if( ( cuidValue == NULL) || ( KDC == NULL)) {
+ return;
+ }
+
+ BYTE *lastTwoBytesOfAID = (BYTE *)cuidValue;
+// BYTE *ICFabricationDate = (BYTE *)cuidValue + 2;
+ BYTE *ICSerialNumber = (BYTE *)cuidValue + 4;
+// BYTE *ICBatchIdentifier = (BYTE *)cuidValue + 8;
+
+// Last 2 bytes of AID
+ KDC[0]= (BYTE)lastTwoBytesOfAID[0];
+ KDC[1]= (BYTE)lastTwoBytesOfAID[1];
+ KDC[2]= (BYTE)ICSerialNumber[0];
+ KDC[3]= (BYTE)ICSerialNumber[1];
+ KDC[4]= (BYTE)ICSerialNumber[2];
+ KDC[5]= (BYTE)ICSerialNumber[3];
+ KDC[6]= 0xF0;
+ KDC[7]= 0x01;
+ KDC[8]= (BYTE)lastTwoBytesOfAID[0];
+ KDC[9]= (BYTE)lastTwoBytesOfAID[1];
+ KDC[10]= (BYTE)ICSerialNumber[0];
+ KDC[11]= (BYTE)ICSerialNumber[1];
+ KDC[12]= (BYTE)ICSerialNumber[2];
+ KDC[13]= (BYTE)ICSerialNumber[3];
+ KDC[14]= 0x0F;
+ KDC[15]= 0x01;
+ if(keytype == enc)
+ return;
+
+ KDC[6]= 0xF0;
+ KDC[7]= 0x02;
+ KDC[14]= 0x0F;
+ KDC[15]= 0x02;
+ if(keytype == mac)
+ return;
+
+ KDC[6]= 0xF0;
+ KDC[7]= 0x03;
+ KDC[14]= 0x0F;
+ KDC[15]= 0x03;
+ if(keytype == kek)
+ return;
+
+}
+
+static int getMasterKeyVersion(char *newMasterKeyNameChars)
+{
+ if( newMasterKeyNameChars == NULL ||
+ strlen( newMasterKeyNameChars) < 3) {
+ return 0;
+ }
+
+ char masterKeyVersionNumber[3];
+ masterKeyVersionNumber[0]=newMasterKeyNameChars[1];
+ masterKeyVersionNumber[1]=newMasterKeyNameChars[2];
+ masterKeyVersionNumber[2]=0;
+ int newMasterKeyVesion = atoi(masterKeyVersionNumber);
+ return newMasterKeyVesion;
+}
+
+char *GetSharedSecretKeyName(char *newKeyName) {
+ if ( newKeyName && strlen( newKeyName ) > 0 ) {
+ if( strlen( sharedSecretSymKeyName) == 0) {
+ strncpy( sharedSecretSymKeyName, newKeyName, KEYNAMELENGTH);
+ }
+ }
+
+ return (char *) sharedSecretSymKeyName ;
+}
+
+void getFullName(char * fullMasterKeyName, char * masterKeyNameChars )
+{
+ if( fullMasterKeyName == NULL || masterKeyNameChars == NULL
+ || ( strlen(fullMasterKeyName) + strlen(masterKeyNameChars)) > KEYNAMELENGTH) {
+ return;
+ }
+ fullMasterKeyName[0]='\0';
+ if(strlen(masterKeyPrefix)>0)
+ strncpy(fullMasterKeyName,masterKeyPrefix, KEYNAMELENGTH);
+ strcat(fullMasterKeyName,masterKeyNameChars);
+}
+
+
+/*
+ * Class: com_netscape_cms_servlet_tks_RASessionKey
+ * Method: DiversifyKey
+ * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[B)[B
+ */
+extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_DiversifyKey
+(JNIEnv *, jclass, jstring, jstring, jstring, jstring, jstring, jbyteArray, jbyteArray, jstring, jstring);
+
+extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_DiversifyKey( JNIEnv * env, jclass this2, jstring tokenName,jstring newTokenName, jstring oldMasterKeyName, jstring newMasterKeyName, jstring keyInfo, jbyteArray CUIDValue, jbyteArray kekKeyArray, jstring useSoftToken_s, jstring keySet)
+{
+ PK11SymKey *encKey = NULL;
+ PK11SymKey *macKey = NULL;
+ PK11SymKey *kekKey = NULL;
+ Buffer encKeyBuff;
+ Buffer macKeyBuff;
+ Buffer kekKeyBuff;
+ char * oldMasterKeyNameChars=NULL;
+ Buffer old_kek_key_buff;
+ Buffer newMasterKeyBuffer;
+ char fullMasterKeyName[KEYNAMELENGTH];
+ char fullNewMasterKeyName[KEYNAMELENGTH];
+ PRBool specified_key_is_present = PR_TRUE;
+ PK11SymKey *old_kek_sym_key = NULL;
+
+ char *keySetStringChars = NULL;
+ if ( keySet != NULL ) {
+ keySetStringChars = (char *) (env)->GetStringUTFChars( keySet, NULL);
+ }
+
+ char *keySetString = keySetStringChars;
+
+ if ( keySetString == NULL ) {
+ keySetString = (char *) DEFKEYSET_NAME;
+ }
+
+ jbyteArray handleBA=NULL;
+ jbyte *handleBytes=NULL;
+ int newMasterKeyVesion = 1;
+
+ /* find slot */
+ char *tokenNameChars = NULL;
+ char * newMasterKeyNameChars = NULL;
+ PK11SlotInfo *slot = NULL;
+ PK11SlotInfo *internal = PK11_GetInternalKeySlot();
+
+ Buffer output;
+ PK11SlotInfo *newSlot =NULL;
+ char * newTokenNameChars = NULL;
+ char *keyInfoChars = NULL;
+
+ jbyte * cuidValue = NULL;
+ jbyte * old_kek_key = NULL;
+
+ PK11SymKey * masterKey = NULL;
+ PK11SymKey * oldMasterKey = NULL;
+
+ BYTE KDCenc[KEYLENGTH];
+ BYTE KDCmac[KEYLENGTH];
+ BYTE KDCkek[KEYLENGTH];
+
+ if( CUIDValue != NULL) {
+ cuidValue = (jbyte*)(env)->GetByteArrayElements( CUIDValue, NULL);
+ }
+
+ if( cuidValue == NULL) {
+ goto done;
+ }
+
+ if( kekKeyArray != NULL) {
+ old_kek_key = (jbyte*)(env)->GetByteArrayElements(kekKeyArray, NULL);
+ }
+
+ if( old_kek_key == NULL) {
+ goto done;
+ }
+
+ PR_fprintf(PR_STDOUT,"In SessionKey.DiversifyKey! \n");
+
+ GetDiversificationData(cuidValue,KDCenc,enc);
+ GetDiversificationData(cuidValue,KDCmac,mac);
+ GetDiversificationData(cuidValue,KDCkek,kek);
+
+ if(tokenName)
+ {
+ tokenNameChars = (char *)(env)->GetStringUTFChars(tokenName, NULL);
+ slot = ReturnSlot(tokenNameChars);
+ PR_fprintf(PR_STDOUT,"DiversifyKey: tokenNameChars %s slot %p \n", tokenNameChars,slot);
+ if( tokenNameChars != NULL) {
+ (env)->ReleaseStringUTFChars(tokenName, (const char *)tokenNameChars);
+ }
+ }
+
+ if(newMasterKeyName)
+ {
+ /* newMasterKeyNameChars #02#01 */
+ newMasterKeyNameChars= (char *)(env)->GetStringUTFChars(newMasterKeyName, NULL);
+ }
+ /* fullNewMasterKeyName - no prefix #02#01 */
+ getFullName(fullNewMasterKeyName,newMasterKeyNameChars);
+ PR_fprintf(PR_STDOUT,"DiversifyKey: fullNewMasterKeyName %s . \n", fullNewMasterKeyName);
+
+ if(newTokenName)
+ {
+ newTokenNameChars = (char *)(env)->GetStringUTFChars(newTokenName, NULL);
+ newSlot = ReturnSlot(newTokenNameChars);
+ PR_fprintf(PR_STDOUT,"DiversifyKey: newTokenNameChars %s newSlot %p . \n", newTokenNameChars,newSlot);
+ if( newTokenNameChars != NULL) {
+ (env)->ReleaseStringUTFChars(newTokenName, (const char *)newTokenNameChars);
+ }
+ }
+
+ masterKey = ReturnSymKey(newSlot,fullNewMasterKeyName);
+
+ if(newMasterKeyNameChars) {
+ (env)->ReleaseStringUTFChars(newMasterKeyName, (const char *)newMasterKeyNameChars);
+ }
+
+ /* packing return */
+ if( keyInfo != NULL) {
+ keyInfoChars = (char *)(env)->GetStringUTFChars(keyInfo, NULL);
+ }
+
+ newMasterKeyVesion = getMasterKeyVersion(keyInfoChars);
+
+ if(keyInfoChars)
+ {
+ (env)->ReleaseStringUTFChars(keyInfo, (const char *)keyInfoChars);
+ }
+
+ /* NEW MASTER KEY VERSION */
+ newMasterKeyBuffer = Buffer((unsigned int) 1, (BYTE)newMasterKeyVesion);
+ if(oldMasterKeyName)
+ {
+ oldMasterKeyNameChars = (char *)(env)->GetStringUTFChars(oldMasterKeyName, NULL);
+ PR_fprintf(PR_STDOUT,"DiversifyKey oldMasterKeyNameChars %s \n", oldMasterKeyNameChars);
+ }
+ getFullName(fullMasterKeyName,oldMasterKeyNameChars);
+ PR_fprintf(PR_STDOUT,"DiversifyKey fullMasterKeyName %s \n", fullMasterKeyName);
+ if(newSlot == NULL) {
+ newSlot = slot;
+ }
+ if(strcmp( oldMasterKeyNameChars, "#01#01") == 0 || strcmp( oldMasterKeyNameChars, "#FF#01") == 0)
+ {
+ old_kek_key_buff = Buffer((BYTE*)old_kek_key, KEYLENGTH);
+ }else if(strcmp( oldMasterKeyNameChars, "#00#00") == 0)
+ {
+ /* print Debug message - do not create real keysetdata */
+ old_kek_key_buff = Buffer((BYTE*)"#00#00", 6);
+ output = Buffer((BYTE*)old_kek_key, KEYLENGTH);
+ }
+ else
+ {
+ oldMasterKey = ReturnSymKey(slot,fullMasterKeyName);
+ old_kek_sym_key = ComputeCardKeyOnToken(oldMasterKey,KDCkek);
+ if (oldMasterKey) {
+ PK11_FreeSymKey( oldMasterKey );
+ oldMasterKey = NULL;
+ }
+ }
+ if(oldMasterKeyNameChars) {
+ (env)->ReleaseStringUTFChars(oldMasterKeyName, (const char *)oldMasterKeyNameChars);
+ }
+
+ /* special case #01#01 */
+ if (fullNewMasterKeyName != NULL && strcmp(fullNewMasterKeyName, "#01#01") == 0)
+ {
+ Buffer empty = Buffer();
+
+ encKey = ReturnDeveloperSymKey(internal,(char *) "auth", keySetString, empty);
+
+ if ( encKey == NULL ) {
+ goto done;
+ }
+ PR_fprintf(PR_STDOUT, "Special case dev key set for DiversifyKey!\n");
+
+ macKey = ReturnDeveloperSymKey(internal, (char *) "mac", keySetString, empty);
+ if ( macKey == NULL ) {
+ goto done;
+ }
+
+ kekKey = ReturnDeveloperSymKey(internal, (char *) "kek", keySetString, empty);
+
+ if ( kekKey == NULL ) {
+ goto done;
+ }
+
+ } else {
+ PR_fprintf(PR_STDOUT,"DiversifyKey: Compute card key on token case ! \n");
+ /* compute card key */
+ encKey = ComputeCardKeyOnSoftToken(masterKey, KDCenc);
+ macKey = ComputeCardKeyOnSoftToken(masterKey, KDCmac);
+ kekKey = ComputeCardKeyOnSoftToken(masterKey, KDCkek);
+
+ /* Fixes Bugscape Bug #55855: TKS crashes if specified key
+ * is not present -- for each portion of the key, check if
+ * the PK11SymKey is NULL before sending it to PK11_GetKeyData()!
+ */
+ if( encKey == NULL) {
+ PR_fprintf(PR_STDERR,"Can't create encKey in DiversifyKey! \n");
+ specified_key_is_present = PR_FALSE;
+ goto done;
+ }
+ if( macKey == NULL) {
+ PR_fprintf(PR_STDERR,"Can't create macKey in DiversifyKey! \n");
+ specified_key_is_present = PR_FALSE;
+ goto done;
+ }
+ if( kekKey == NULL) {
+ PR_fprintf(PR_STDERR,"Can't create kekKey in DiversifyKey! \n");
+ specified_key_is_present = PR_FALSE;
+ goto done;
+ }
+ }
+
+ if (old_kek_sym_key != NULL) {
+ CreateKeySetDataWithSymKeys(newMasterKeyBuffer, Buffer(),
+ old_kek_sym_key,
+ encKey,
+ macKey,
+ kekKey,
+ output); }
+ else {
+ old_kek_sym_key = ReturnDeveloperSymKey(slot, (char *) "kek", keySetString, old_kek_key_buff);
+ CreateKeySetDataWithSymKeys(newMasterKeyBuffer, Buffer(),
+ old_kek_sym_key,
+ encKey,
+ macKey,
+ kekKey,
+ output);
+ }
+
+done:
+ if (masterKey != NULL) {
+ PK11_FreeSymKey( masterKey);
+ masterKey = NULL;
+ }
+
+ if (encKey != NULL) {
+ PK11_FreeSymKey( encKey );
+ encKey = NULL;
+ }
+
+ if (macKey != NULL) {
+ PK11_FreeSymKey( macKey );
+ macKey = NULL;
+ }
+
+ if (kekKey != NULL) {
+ PK11_FreeSymKey( kekKey );
+ kekKey = NULL;
+ }
+
+ if( keySetStringChars ) {
+ (env)->ReleaseStringUTFChars(keySet, (const char *)keySetStringChars);
+ keySetStringChars = NULL;
+ }
+
+ if( specified_key_is_present )
+ {
+ if(output.size()>0)
+ handleBA = (env)->NewByteArray( output.size());
+ else
+ handleBA = (env)->NewByteArray(1);
+ handleBytes = (env)->GetByteArrayElements(handleBA, NULL);
+ memcpy(handleBytes, (BYTE*)output,output.size());
+
+ if( handleBytes != NULL) {
+ (env)->ReleaseByteArrayElements( handleBA, handleBytes, 0);
+ }
+ }
+
+ if( cuidValue != NULL) {
+ (env)->ReleaseByteArrayElements(CUIDValue, cuidValue, JNI_ABORT);
+ }
+
+ if( kekKeyArray != NULL) {
+ (env)->ReleaseByteArrayElements(kekKeyArray, old_kek_key, JNI_ABORT);
+ }
+
+ if((newSlot != slot) && newSlot) {
+ PK11_FreeSlot( newSlot);
+ newSlot = NULL;
+ }
+
+ if( slot ) {
+ PK11_FreeSlot( slot);
+ slot = NULL;
+ }
+
+ if( internal) {
+ PK11_FreeSlot( internal);
+ internal = NULL;
+ }
+
+ return handleBA;
+}
+
+PK11SymKey *CreateUnWrappedSymKeyOnToken( PK11SlotInfo *slot, PK11SymKey * unWrappingKey, BYTE *keyToBeUnWrapped, int sizeOfKeyToBeUnWrapped, PRBool isPerm)
+{
+ PK11SymKey * unWrappedSymKey = NULL;
+ int bufSize = 48;
+ unsigned char outbuf[bufSize];
+ int final_len = 0;
+ SECStatus s = SECSuccess;
+ PK11Context * EncContext = NULL;
+ SECItem unWrappedKeyItem = { siBuffer, NULL, 0};
+ PK11SymKey *unwrapper = NULL;
+
+ PR_fprintf( PR_STDOUT,
+ "Creating UnWrappedSymKey on token. \n");
+
+ if ( (slot == NULL) || (unWrappingKey == NULL) ||
+ (keyToBeUnWrapped == NULL) ||
+ (sizeOfKeyToBeUnWrapped != DES3_LENGTH)
+ ) {
+ return NULL;
+ }
+
+ PK11SlotInfo *unwrapKeySlot = PK11_GetSlotFromKey( unWrappingKey );
+
+ if ( unwrapKeySlot != slot ) {
+ unwrapper = PK11_MoveSymKey ( slot, CKA_ENCRYPT, 0, PR_FALSE, unWrappingKey);
+ }
+
+ SECItem *SecParam = PK11_ParamFromIV(CKM_DES3_ECB, NULL);
+ if ( SecParam == NULL) {
+ goto done;
+ }
+
+ EncContext = PK11_CreateContextBySymKey(CKM_DES3_ECB,
+ CKA_ENCRYPT,
+ unWrappingKey, SecParam);
+
+ if ( EncContext == NULL) {
+ goto done;
+ }
+
+ s = PK11_CipherOp(EncContext, outbuf, &final_len, sizeof( outbuf), keyToBeUnWrapped,
+ sizeOfKeyToBeUnWrapped);
+
+ if ( s != SECSuccess) {
+ goto done;
+ }
+
+ if ( final_len != DES3_LENGTH ) {
+ goto done;
+ }
+
+ unWrappedKeyItem.data = outbuf;
+ unWrappedKeyItem.len = final_len;
+
+
+ /* Now try to unwrap our key into the token */
+ unWrappedSymKey = PK11_UnwrapSymKeyWithFlagsPerm(unwrapper ? unwrapper : unWrappingKey,
+ CKM_DES3_ECB,SecParam, &unWrappedKeyItem,
+ CKM_DES3_ECB,
+ CKA_UNWRAP,
+ sizeOfKeyToBeUnWrapped, 0, isPerm );
+
+done:
+
+ if( SecParam != NULL ) {
+ SECITEM_FreeItem(SecParam, PR_TRUE);
+ SecParam = NULL;
+ }
+
+ if( EncContext != NULL ) {
+ PK11_DestroyContext(EncContext, PR_TRUE);
+ EncContext = NULL;
+ }
+
+ if( unwrapper != NULL ) {
+ PK11_FreeSymKey( unwrapper );
+ unwrapper = NULL;
+ }
+
+ if( unwrapKeySlot != NULL) {
+ PK11_FreeSlot( unwrapKeySlot);
+ unwrapKeySlot = NULL;
+ }
+
+ PR_fprintf( PR_STDOUT,
+ "UnWrappedSymKey on token result: %p \n",unWrappedSymKey);
+
+ return unWrappedSymKey;
+}
+//Return default keyset developer key. Either auth, mac, or kek
+PK11SymKey *ReturnDeveloperSymKey(PK11SlotInfo *slot, char *keyType, char *keySet, Buffer &inputKey)
+{
+ const int maxKeyNameSize = 56;
+ PK11SymKey *devSymKey = NULL;
+ PK11SymKey *transportKey = NULL;
+ char devKeyName[maxKeyNameSize];
+
+ SECStatus rv = SECSuccess;
+
+ BYTE sessionKey[DES3_LENGTH];
+
+ if( slot == NULL || keyType == NULL || keySet == NULL) {
+ return NULL;
+ }
+
+ snprintf(devKeyName,maxKeyNameSize,"%s-%sKey", keySet, keyType);
+
+ devSymKey = ReturnSymKey( slot, devKeyName );
+
+ // Try to create the key once and leave it there.
+ if( devSymKey == NULL ) {
+ PR_fprintf(PR_STDOUT, "Can't find devSymKey, try to create it on token. \n");
+ if ( inputKey.size() == DES2_LENGTH ) { //Any other size ignored
+ transportKey = ReturnSymKey( slot, GetSharedSecretKeyName(NULL));
+
+ if( transportKey == NULL) {
+ PR_fprintf(PR_STDERR,"Can't get transport key in ReturnDeveloperSymKey! \n");
+ goto done;
+ }
+
+ /* convert 16-byte to 24-byte triple-DES key */
+ memcpy(sessionKey, inputKey, DES2_LENGTH);
+ memcpy(sessionKey+ DES2_LENGTH, inputKey, EIGHT_BYTES);
+
+ //Unwrap this thing on there as permanent, so we don't have to create it again for a given keySet.
+ if( transportKey) {
+ devSymKey = CreateUnWrappedSymKeyOnToken( slot, transportKey, sessionKey, sizeof(sessionKey), PR_TRUE);
+ }
+
+ PR_fprintf(PR_STDERR,"Tried to create devSymKey %p \n",devSymKey);
+
+ rv = SECSuccess;
+ if( devSymKey ) {
+ rv = PK11_SetSymKeyNickname( devSymKey, devKeyName );
+
+ if ( rv != SECSuccess ) {
+ PR_fprintf(PR_STDERR, "Can't set the nickname of just written devKey! \n");
+ }
+ }
+ }
+ }
+
+done:
+ if( transportKey ) {
+ PK11_FreeSymKey( transportKey );
+ transportKey = NULL;
+ }
+
+ // Dont' free slot , let the caller.
+ return devSymKey;
+}
+
+/*
+ * Class: com_netscape_cms_servlet_tks_RASessionKey
+ * Method: SetDefaultPrefix
+ * Signature: (Ljava/lang/String;)V
+ */
+extern "C" JNIEXPORT void JNICALL Java_com_netscape_symkey_SessionKey_SetDefaultPrefix
+(JNIEnv *, jclass, jstring);
+extern "C" JNIEXPORT void
+JNICALL Java_com_netscape_symkey_SessionKey_SetDefaultPrefix(JNIEnv * env, jclass this2, jstring masterPrefix)
+{
+ char *masterPrefixChars;
+
+ masterPrefixChars = (char *)(env)->GetStringUTFChars(masterPrefix, NULL);
+
+ if(masterPrefixChars)
+ strcpy(masterKeyPrefix,masterPrefixChars);
+ else
+ masterKeyPrefix[0] = '\0';
+
+ if(masterPrefixChars)
+ {
+ (env)->ReleaseStringUTFChars(masterPrefix, (const char *)masterPrefixChars);
+ }
+
+ return;
+}
diff --git a/base/symkey/src/com/netscape/symkey/SymKey.h b/base/symkey/src/com/netscape/symkey/SymKey.h
new file mode 100644
index 000000000..5a53d48c9
--- /dev/null
+++ b/base/symkey/src/com/netscape/symkey/SymKey.h
@@ -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 ---
+
+#ifndef _TKSSYMKEY_H_
+#define _TKSSYMKEY_H_
+
+extern PK11SlotInfo *defaultSlot;
+
+typedef enum {
+ enc,
+ mac,
+ kek
+ } keyType;
+#define KEYLENGTH 16
+#define PREFIXLENGHT 128
+#define DES2_LENGTH 16
+#define DES3_LENGTH 24
+#define EIGHT_BYTES 8
+#define KEYNAMELENGTH PREFIXLENGHT+7
+#define TRANSPORT_KEY_NAME "sharedSecret"
+#define DEFKEYSET_NAME "defKeySet"
+
+extern char masterKeyPrefix[PREFIXLENGHT];
+extern char sharedSecretSymKeyName[KEYNAMELENGTH];
+
+void GetDiversificationData(jbyte *cuidValue,BYTE *KDC,keyType keytype);
+PK11SymKey * ReturnSymKey( PK11SlotInfo *slot, char *keyname);
+void GetKeyName(jbyte *keyVersion,char *keyname);
+PK11SymKey * ComputeCardKeyOnToken(PK11SymKey *masterKey, BYTE* data);
+PRStatus EncryptData(const Buffer &kek_key, PK11SymKey *card_key, Buffer &input, Buffer &output);
+PK11SlotInfo *ReturnSlot(char *tokenNameChars);
+PK11SymKey *ComputeCardKey(PK11SymKey *masterKey, unsigned char *data, PK11SlotInfo *slot);
+PK11SymKey *CreateUnWrappedSymKeyOnToken( PK11SlotInfo *slot, PK11SymKey * unWrappingKey, BYTE *keyToBeUnWrapped, int sizeOfKeyToBeUnWrapped, PRBool isPerm);
+PK11SymKey *ReturnDeveloperSymKey(PK11SlotInfo *slot, char *keyType, char *keySet, Buffer &inputKey);
+
+char *GetSharedSecretKeyName(char *newKeyName);
+
+#define DES2_WORKAROUND
+#endif /* _TKSSYMKEY_H_ */
+
diff --git a/base/test/CMakeLists.txt b/base/test/CMakeLists.txt
new file mode 100644
index 000000000..9a4acceef
--- /dev/null
+++ b/base/test/CMakeLists.txt
@@ -0,0 +1,3 @@
+project(test Java)
+
+add_subdirectory(src)
diff --git a/base/test/src/CMakeLists.txt b/base/test/src/CMakeLists.txt
new file mode 100644
index 000000000..3631baa73
--- /dev/null
+++ b/base/test/src/CMakeLists.txt
@@ -0,0 +1,20 @@
+project(pki-test_java Java)
+
+# TODO: create CMake function to find all Java files
+set(pki-test_java_SRCS
+ com/netscape/test/TestListener.java
+ com/netscape/test/TestRunner.java
+)
+
+set(CMAKE_JAVA_INCLUDE_PATH
+ ${XALAN_JAR} ${XERCES_JAR} ${JUNIT_JAR}
+)
+
+set(CMAKE_JAVA_TARGET_VERSION ${APPLICATION_VERSION})
+
+# build test jar file
+# TODO: create CMake function to compile without building jar file
+# TODO: build test only when the test is invoked
+set(CMAKE_JAR_CLASSES_PREFIX com/netscape)
+add_jar(pki-test ${pki-test_java_SRCS})
+set(PKI_TEST_JAR ${pki-test_JAR_FILE} CACHE INTERNAL "pki-test jar file") \ No newline at end of file
diff --git a/base/test/src/com/netscape/test/TestListener.java b/base/test/src/com/netscape/test/TestListener.java
new file mode 100644
index 000000000..96c4c9068
--- /dev/null
+++ b/base/test/src/com/netscape/test/TestListener.java
@@ -0,0 +1,249 @@
+package com.netscape.test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.PrintStream;
+import java.net.InetAddress;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.junit.runner.Description;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+
+public class TestListener extends RunListener {
+
+ DateFormat dateFormat;
+
+ DocumentBuilderFactory docBuilderFactory;
+ DocumentBuilder docBuilder;
+ Document document;
+
+ TransformerFactory transFactory;
+ Transformer trans;
+
+ String reportsDir;
+
+ Element testSuiteElement;
+ long testSuiteStartTime;
+
+ Element testCaseElement;
+ long testCaseStartTime;
+
+ String currentTestSuiteName;
+
+ long testCount;
+ long successCount;
+ long failureCount;
+
+ PrintStream stdOut;
+ PrintStream stdErr;
+
+ ByteArrayOutputStream out;
+ ByteArrayOutputStream err;
+
+ public TestListener() throws Exception {
+
+ dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+ dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
+
+ docBuilderFactory = DocumentBuilderFactory.newInstance();
+ docBuilder = docBuilderFactory.newDocumentBuilder();
+
+ transFactory = TransformerFactory.newInstance();
+ trans = transFactory.newTransformer();
+ trans.setOutputProperty(OutputKeys.INDENT, "yes");
+
+ reportsDir = System.getProperty("junit.reports.dir");
+ }
+
+ public void testRunFinished(Result result) throws Exception {
+ if (currentTestSuiteName != null) {
+ finishTestSuite(); // finish last suite
+ }
+ }
+
+ public void testStarted(Description description) throws Exception {
+
+ String testSuiteName = description.getClassName();
+
+ if (currentTestSuiteName == null) {
+ startTestSuite(testSuiteName); // start first suite
+
+ } else if (!currentTestSuiteName.equals(testSuiteName)) {
+ finishTestSuite(); // finish old suite
+ startTestSuite(testSuiteName); // start new suite
+ }
+
+ currentTestSuiteName = testSuiteName;
+
+ startTestCase(description);
+ }
+
+ public void testFinished(Description description) throws Exception {
+ finishTestCase();
+ recordTestCaseSuccess();
+ }
+
+ public void testFailure(Failure failure) throws Exception {
+ finishTestCase();
+ recordTestCaseFailure(failure);
+ }
+
+ public void startTestSuite(String testSuiteName) throws Exception {
+
+ testSuiteStartTime = System.currentTimeMillis();
+
+ document = docBuilder.newDocument();
+
+ // test suite
+ testSuiteElement = document.createElement("testsuite");
+ document.appendChild(testSuiteElement);
+
+ testSuiteElement.setAttribute("name", testSuiteName);
+ testSuiteElement.setAttribute("timestamp",
+ dateFormat.format(new Date(testSuiteStartTime)));
+ testSuiteElement.setAttribute("hostname",
+ InetAddress.getLocalHost().getHostName());
+
+ // system properties
+ Element propertiesElement = document.createElement("properties");
+ testSuiteElement.appendChild(propertiesElement);
+
+ for (String name : System.getProperties().stringPropertyNames()) {
+ Element propertyElement = document.createElement("property");
+ propertyElement.setAttribute("name", name);
+ propertyElement.setAttribute("value", System.getProperty(name));
+ propertiesElement.appendChild(propertyElement);
+ }
+
+ // reset counters
+ testCount = 0;
+ successCount = 0;
+ failureCount = 0;
+
+ // redirect outputs
+ stdOut = System.out;
+ out = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(out, true));
+
+ stdErr = System.err;
+ err = new ByteArrayOutputStream();
+ System.setErr(new PrintStream(err, true));
+ }
+
+ public void finishTestSuite() throws Exception {
+
+ double time = (System.currentTimeMillis() - testSuiteStartTime) / 1000.0;
+ testSuiteElement.setAttribute("time", "" + time);
+
+ // save counters
+ long errorCount = testCount - successCount - failureCount;
+
+ testSuiteElement.setAttribute("tests", "" + testCount);
+ testSuiteElement.setAttribute("failures", "" + failureCount);
+ testSuiteElement.setAttribute("errors", "" + errorCount);
+
+ // save outputs
+ System.setOut(stdOut);
+ System.setErr(stdErr);
+
+ Element systemOutElement = document.createElement("system-out");
+ testSuiteElement.appendChild(systemOutElement);
+
+ systemOutElement.appendChild(
+ document.createCDATASection(out.toString())
+ );
+
+ Element systemErrElement = document.createElement("system-err");
+ testSuiteElement.appendChild(systemErrElement);
+
+ systemErrElement.appendChild(
+ document.createCDATASection(err.toString())
+ );
+
+ // write to file
+ FileWriter fw = new FileWriter(
+ reportsDir + File.separator + "TEST-" + currentTestSuiteName + ".xml"
+ );
+ StreamResult sr = new StreamResult(fw);
+ DOMSource source = new DOMSource(document);
+ trans.transform(source, sr);
+ fw.close();
+ }
+
+ public void startTestCase(Description description) throws Exception {
+
+ testCaseStartTime = System.currentTimeMillis();
+
+ testCaseElement = document.createElement("testcase");
+ testSuiteElement.appendChild(testCaseElement);
+
+ testCaseElement.setAttribute("classname", description.getClassName());
+ testCaseElement.setAttribute("name", description.getMethodName());
+
+ testCount++;
+ }
+
+ public void finishTestCase() throws Exception {
+ double time = (System.currentTimeMillis() - testCaseStartTime) / 1000.0;
+ testCaseElement.setAttribute("time", "" + time);
+ }
+
+ public void recordTestCaseSuccess() throws Exception {
+ successCount++;
+ }
+
+ public void recordTestCaseFailure(Failure failure) throws Exception {
+
+ Element failureElement = document.createElement("failure");
+ testCaseElement.appendChild(failureElement);
+
+ Description description = failure.getDescription();
+ Throwable exception = failure.getException();
+ String exceptionName = exception.getClass().getName();
+
+ failureElement.setAttribute("message", failure.getMessage());
+ failureElement.setAttribute("type", exceptionName);
+
+ Text messageElement = document.createTextNode(
+ exceptionName + ": " + failure.getMessage() + "\n"
+ );
+
+ // print stack trace
+ for (StackTraceElement element : exception.getStackTrace()) {
+ if (!element.getClassName().equals(description.getClassName()))
+ continue;
+
+ String source = "Unknown Source";
+ if (element.getFileName() != null && element.getLineNumber() >= 0) {
+ source = element.getFileName() + ":" + element.getLineNumber();
+ }
+
+ messageElement.appendData("\tat " +
+ element.getClassName() + "." + element.getMethodName() +
+ "(" + source + ")\n"
+ );
+ }
+
+ failureElement.appendChild(messageElement);
+
+ failureCount++;
+ }
+}
diff --git a/base/test/src/com/netscape/test/TestRunner.java b/base/test/src/com/netscape/test/TestRunner.java
new file mode 100644
index 000000000..7eb4bfd3e
--- /dev/null
+++ b/base/test/src/com/netscape/test/TestRunner.java
@@ -0,0 +1,23 @@
+package com.netscape.test;
+
+import org.junit.internal.RealSystem;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+
+public class TestRunner {
+
+ public Result run(String... args) throws Exception {
+
+ JUnitCore core = new JUnitCore();
+ core.addListener(new TestListener());
+
+ return core.runMain(new RealSystem(), args);
+ }
+
+ public static void main(String... args) throws Exception {
+
+ TestRunner runner = new TestRunner();
+ Result result = runner.run(args);
+ System.exit(result.wasSuccessful() ? 0 : 1);
+ }
+}
diff --git a/base/tks/CMakeLists.txt b/base/tks/CMakeLists.txt
new file mode 100644
index 000000000..fd9246948
--- /dev/null
+++ b/base/tks/CMakeLists.txt
@@ -0,0 +1,65 @@
+project(tks Java)
+
+add_subdirectory(src)
+add_subdirectory(setup)
+add_subdirectory(shared/conf)
+
+# install systemd scripts
+install(
+ FILES
+ shared/lib/systemd/system/pki-tksd.target
+ shared/lib/systemd/system/pki-tksd@.service
+ DESTINATION
+ ${SYSTEMD_LIB_INSTALL_DIR}
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+# install init script
+install(
+ FILES
+ shared/etc/init.d/pki-tksd
+ DESTINATION
+ ${SYSCONF_INSTALL_DIR}/rc.d/init.d
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+# install directories
+install(
+ DIRECTORY
+ shared/
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}
+ PATTERN
+ "CMakeLists.txt" EXCLUDE
+ PATTERN
+ "etc/*" EXCLUDE
+ PATTERN
+ "CS.cfg.in" EXCLUDE
+ PATTERN
+ "lib/*" EXCLUDE
+)
+
+# install empty directories
+install(
+ DIRECTORY
+ DESTINATION
+ ${VAR_INSTALL_DIR}/lock/pki/tks
+)
+
+install(
+ DIRECTORY
+ DESTINATION
+ ${VAR_INSTALL_DIR}/run/pki/tks
+)
+
+install(
+ DIRECTORY
+ DESTINATION
+ ${SYSTEMD_ETC_INSTALL_DIR}/pki-tksd.target.wants
+)
diff --git a/base/tks/LICENSE b/base/tks/LICENSE
new file mode 100644
index 000000000..e281f4362
--- /dev/null
+++ b/base/tks/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/base/tks/setup/CMakeLists.txt b/base/tks/setup/CMakeLists.txt
new file mode 100644
index 000000000..f5f069cdb
--- /dev/null
+++ b/base/tks/setup/CMakeLists.txt
@@ -0,0 +1,8 @@
+set(VERSION ${APPLICATION_VERSION})
+
+install(
+ FILES
+ registry_instance
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/setup
+)
diff --git a/base/tks/setup/registry_instance b/base/tks/setup/registry_instance
new file mode 100644
index 000000000..3210b9131
--- /dev/null
+++ b/base/tks/setup/registry_instance
@@ -0,0 +1,63 @@
+# Establish PKI Variable "Slot" Substitutions
+
+PKI_FLAVOR=[PKI_FLAVOR]
+export PKI_FLAVOR
+
+PKI_SUBSYSTEM_TYPE=[PKI_SUBSYSTEM_TYPE]
+export PKI_SUBSYSTEM_TYPE
+
+PKI_USER=[PKI_USER]
+export PKI_USER
+
+PKI_GROUP=[PKI_GROUP]
+export PKI_GROUP
+
+PKI_INSTANCE_ID=[PKI_INSTANCE_ID]
+export PKI_INSTANCE_ID
+
+PKI_INSTANCE_PATH=[PKI_INSTANCE_PATH]
+export PKI_INSTANCE_PATH
+
+PKI_INSTANCE_INITSCRIPT=[PKI_INSTANCE_INITSCRIPT]
+export PKI_INSTANCE_INITSCRIPT
+
+PKI_SERVER_XML_CONF=[PKI_SERVER_XML_CONF]
+export PKI_SERVER_XML_CONF
+
+# Use CATALINA_BASE
+
+CATALINA_BASE=$PKI_INSTANCE_PATH
+export CATALINA_BASE
+
+TOMCAT_PROG=$PKI_INSTANCE_ID
+export TOMCAT_PROG
+
+TOMCAT_USER=$PKI_USER
+export TOMCAT_USER
+
+TOMCAT_GROUP=$PKI_GROUP
+export TOMCAT_GROUP
+
+PKI_LOCKDIR="/var/lock/${PKI_FLAVOR}/${PKI_SUBSYSTEM_TYPE}"
+export PKI_LOCKDIR
+
+PKI_LOCKFILE="${PKI_LOCKDIR}/${PKI_INSTANCE_ID}"
+export PKI_LOCKFILE
+
+PKI_PIDDIR="/var/run/${PKI_FLAVOR}/${PKI_SUBSYSTEM_TYPE}"
+export PKI_PIDDIR
+
+PKI_PIDFILE="${PKI_PIDDIR}/${PKI_INSTANCE_ID}.pid"
+export PKI_PIDFILE
+
+TOMCAT_LOCKFILE=/var/lock/subsys/${PKI_INSTANCE_ID}
+export TOMCAT_LOCKFILE
+
+TOMCAT_PIDFILE=[TOMCAT_PIDFILE]
+export TOMCAT_PIDFILE
+
+pki_instance_configuration_file=${PKI_INSTANCE_PATH}/conf/CS.cfg
+export pki_instance_configuration_file
+
+RESTART_SERVER=${PKI_INSTANCE_PATH}/conf/restart_server_after_configuration
+export RESTART_SERVER
diff --git a/base/tks/shared/conf/CMakeLists.txt b/base/tks/shared/conf/CMakeLists.txt
new file mode 100644
index 000000000..e3cef5915
--- /dev/null
+++ b/base/tks/shared/conf/CMakeLists.txt
@@ -0,0 +1,12 @@
+set(VERSION ${APPLICATION_VERSION})
+set(MAJOR_VERSION ${APPLICATION_VERSION_MAJOR})
+set(MINOR_VERSION ${APPLICATION_VERSION_MINOR})
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CS.cfg.in ${CMAKE_CURRENT_BINARY_DIR}/CS.cfg @ONLY)
+
+install(
+ FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/CS.cfg
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/conf
+)
diff --git a/base/tks/shared/conf/CS.cfg.in b/base/tks/shared/conf/CS.cfg.in
new file mode 100644
index 000000000..195201e4d
--- /dev/null
+++ b/base/tks/shared/conf/CS.cfg.in
@@ -0,0 +1,350 @@
+_000=##
+_001=## Token Key Service (TKS) Configuration File
+_002=##
+pidDir=[PKI_PIDDIR]
+pkicreate.pki_instance_root=[PKI_INSTANCE_ROOT]
+pkicreate.pki_instance_name=[PKI_INSTANCE_ID]
+pkicreate.subsystem_type=[PKI_SUBSYSTEM_TYPE]
+pkicreate.agent_secure_port=[PKI_AGENT_SECURE_PORT]
+pkicreate.ee_secure_port=[PKI_EE_SECURE_PORT]
+pkicreate.admin_secure_port=[PKI_ADMIN_SECURE_PORT]
+pkicreate.secure_port=[PKI_SECURE_PORT]
+pkicreate.unsecure_port=[PKI_UNSECURE_PORT]
+pkicreate.tomcat_server_port=[TOMCAT_SERVER_PORT]
+pkicreate.user=[PKI_USER]
+pkicreate.group=[PKI_GROUP]
+pkicreate.systemd.servicename=[PKI_SYSTEMD_SERVICENAME]
+pkiremove.cert.subsystem.nickname=subsystemCert cert-[PKI_INSTANCE_ID]
+installDate=[INSTALL_TIME]
+cs.type=TKS
+admin.interface.uri=tks/admin/console/config/wizard
+preop.admin.name=Token Key Service Manager Administrator
+preop.admin.group=Token Key Service Manager Agents
+preop.admincert.profile=caAdminCert
+preop.securitydomain.admin_url=https://[PKI_MACHINE_NAME]:9445
+preop.wizard.name=TKS Setup Wizard
+preop.system.name=TKS
+preop.product.name=CS
+preop.product.version=@VERSION@
+preop.system.fullname=Token Key Service
+proxy.securePort=[PKI_PROXY_SECURE_PORT]
+proxy.unsecurePort=[PKI_PROXY_UNSECURE_PORT]
+tks.cert.list=sslserver,subsystem,audit_signing
+tks.cert.sslserver.certusage=SSLServer
+tks.cert.subsystem.certusage=SSLClient
+tks.cert.audit_signing.certusage=ObjectSigner
+preop.cert.list=sslserver,subsystem,audit_signing
+preop.cert.rsalist=audit_signing
+preop.cert.sslserver.enable=true
+preop.cert.subsystem.enable=true
+preop.cert.audit_signing.enable=true
+preop.cert.audit_signing.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.audit_signing.dn=CN=TKS Audit Signing Certificate
+preop.cert.audit_signing.keysize.custom_size=2048
+preop.cert.audit_signing.keysize.size=2048
+preop.cert.audit_signing.nickname=auditSigningCert cert-[PKI_INSTANCE_ID]
+preop.cert.audit_signing.profile=caInternalAuthAuditSigningCert
+preop.cert.audit_signing.signing.required=false
+preop.cert.audit_signing.subsystem=tks
+preop.cert.audit_signing.type=remote
+preop.cert.audit_signing.userfriendlyname=TKS Audit Signing Certificate
+preop.cert.audit_signing.cncomponent.override=true
+preop.cert.sslserver.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.sslserver.dn=CN=[PKI_MACHINE_NAME]
+preop.cert.sslserver.keysize.custom_size=2048
+preop.cert.sslserver.keysize.size=2048
+preop.cert.sslserver.nickname=Server-Cert cert-[PKI_INSTANCE_ID]
+preop.cert.sslserver.profile=caInternalAuthServerCert
+preop.cert.sslserver.signing.required=false
+preop.cert.sslserver.subsystem=tks
+preop.cert.sslserver.type=remote
+preop.cert.sslserver.userfriendlyname=SSL Server Certificate
+preop.cert.sslserver.cncomponent.override=false
+preop.cert.subsystem.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.subsystem.dn=CN=TKS Subsystem Certificate
+preop.cert.subsystem.keysize.custom_size=2048
+preop.cert.subsystem.keysize.size=2048
+preop.cert.subsystem.nickname=subsystemCert cert-[PKI_INSTANCE_ID]
+preop.cert.subsystem.profile=caInternalAuthSubsystemCert
+preop.cert.subsystem.signing.required=false
+preop.cert.subsystem.subsystem=tks
+preop.cert.subsystem.type=remote
+preop.cert.subsystem.userfriendlyname=Subsystem Certificate
+preop.cert.subsystem.cncomponent.override=true
+preop.cert.admin.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.admin.dn=uid=admin,cn=admin
+preop.cert.admin.keysize.custom_size=2048
+preop.cert.admin.keysize.size=2048
+preop.cert.admin.profile=adminCert.profile
+preop.hierarchy.profile=caCert.profile
+preop.configModules.module0.userFriendlyName=NSS Internal PKCS #11 Module
+preop.configModules.module0.commonName=NSS Internal PKCS #11 Module
+preop.configModules.module0.imagePath=../img/clearpixel.gif
+preop.configModules.module1.userFriendlyName=nCipher's nFast Token Hardware Module
+preop.configModules.module1.commonName=nfast
+preop.configModules.module1.imagePath=../img/clearpixel.gif
+preop.configModules.module2.userFriendlyName=SafeNet's LunaSA Token Hardware Module
+preop.configModules.module2.commonName=lunasa
+preop.configModules.module2.imagePath=../img/clearpixel.gif
+preop.configModules.count=3
+preop.module.token=Internal Key Storage Token
+cs.state=0
+authType=pwd
+instanceRoot=[PKI_INSTANCE_PATH]
+machineName=[PKI_MACHINE_NAME]
+instanceId=[PKI_INSTANCE_ID]
+preop.pin=[PKI_RANDOM_NUMBER]
+service.machineName=[PKI_MACHINE_NAME]
+service.instanceDir=[PKI_INSTANCE_ROOT]
+service.securePort=[PKI_AGENT_SECURE_PORT]
+service.non_clientauth_securePort=[PKI_EE_SECURE_PORT]
+service.unsecurePort=[PKI_UNSECURE_PORT]
+service.instanceID=[PKI_INSTANCE_ID]
+passwordFile=[PKI_INSTANCE_PATH]/conf/password.conf
+passwordClass=com.netscape.cmsutil.password.PlainPasswordFile
+multiroles=true
+multiroles.false.groupEnforceList=Administrators,Auditors,Trusted Managers,Certificate Manager Agents,Registration Manager Agents,Data Recovery Manager Agents,Online Certificate Status Manager Agents,Token Key Service Manager Agents,Enterprise CA Administrators,Enterprise KRA Adminstrators,Enterprise OCSP Administrators,Enterprise RA Administrators,Enterprise TKS Administrators,Enterprise TPS Administrators,Security Domain Administrators,Subsystem Group
+CrossCertPair._000=##
+CrossCertPair._001=## CrossCertPair Import
+CrossCertPair._002=##
+CrossCertPair.ldap=internaldb
+accessEvaluator.impl.group.class=com.netscape.cms.evaluators.GroupAccessEvaluator
+accessEvaluator.impl.ipaddress.class=com.netscape.cms.evaluators.IPAddressAccessEvaluator
+accessEvaluator.impl.user.class=com.netscape.cms.evaluators.UserAccessEvaluator
+auths._000=##
+auths._001=## new authentication
+auths._002=##
+auths.impl._000=##
+auths.impl._001=## authentication manager implementations
+auths.impl._002=##
+auths.impl.AgentCertAuth.class=com.netscape.cms.authentication.AgentCertAuthentication
+auths.impl.CMCAuth.class=com.netscape.cms.authentication.CMCAuth
+auths.impl.NISAuth.class=com.netscape.cms.authentication.NISAuth
+auths.impl.PortalEnroll.class=com.netscape.cms.authentication.PortalEnroll
+auths.impl.TokenAuth.class=com.netscape.cms.authentication.TokenAuthentication
+auths.impl.UdnPwdDirAuth.class=com.netscape.cms.authentication.UdnPwdDirAuthentication
+auths.impl.UidPwdDirAuth.class=com.netscape.cms.authentication.UidPwdDirAuthentication
+auths.impl.UidPwdPinDirAuth.class=com.netscape.cms.authentication.UidPwdPinDirAuthentication
+auths.instance.AgentCertAuth.agentGroup=Certificate Manager Agents
+auths.instance.AgentCertAuth.pluginName=AgentCertAuth
+auths.instance.TokenAuth.pluginName=TokenAuth
+auths.revocationChecking.bufferSize=50
+authz._000=##
+authz._001=## new authorizatioin
+authz._002=##
+authz.evaluateOrder=deny,allow
+authz.sourceType=ldap
+authz.impl._000=##
+authz.impl._001=## authorization manager implementations
+authz.impl._002=##
+authz.impl.BasicAclAuthz.class=com.netscape.cms.authorization.BasicAclAuthz
+authz.impl.DirAclAuthz.class=com.netscape.cms.authorization.DirAclAuthz
+authz.instance.BasicAclAuthz.pluginName=BasicAclAuthz
+authz.instance.DirAclAuthz.ldap=internaldb
+authz.instance.DirAclAuthz.pluginName=DirAclAuthz
+authz.instance.DirAclAuthz.ldap._000=##
+authz.instance.DirAclAuthz.ldap._001=## Internal Database
+authz.instance.DirAclAuthz.ldap._002=##
+cardcryptogram.validate.enable=true
+cmc.cert.confirmRequired=false
+cmc.lraPopWitness.verify.allow=true
+cmc.revokeCert.verify=true
+cmc.revokeCert.sharedSecret.class=com.netscape.cms.authentication.SharedSecret
+cmc.sharedSecret.class=com.netscape.cms.authentication.SharedSecret
+cms.version=@MAJOR_VERSION@.@MINOR_VERSION@
+dbs.ldap=internaldb
+dbs.newSchemaEntryAdded=true
+debug.append=true
+debug.enabled=true
+debug.filename=[PKI_INSTANCE_PATH]/logs/debug
+debug.hashkeytypes=
+debug.level=0
+debug.showcaller=false
+keys.ecc.curve.list=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
+keys.ecc.curve.display.list=nistp256 (secp256r1),nistp384 (secp384r1),nistp521 (secp521r1),nistk163 (sect163k1),sect163r1,nistb163 (sect163r2),sect193r1,sect193r2,nistk233 (sect233k1),nistb233 (sect233r1),sect239k1,nistk283 (sect283k1),nistb283 (sect283r1),nistk409 (sect409k1),nistb409 (sect409r1),nistk571 (sect571k1),nistb571 (sect571r1),secp160k1,secp160r1,secp160r2,secp192k1,nistp192 (secp192r1, prime192v1),secp224k1,nistp224 (secp224r1),secp256k1,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
+keys.ecc.curve.default=nistp256
+keys.rsa.keysize.default=2048
+internaldb._000=##
+internaldb._001=## Internal Database
+internaldb._002=##
+internaldb.maxConns=15
+internaldb.minConns=3
+internaldb.ldapauth.authtype=BasicAuth
+internaldb.ldapauth.bindDN=cn=Directory Manager
+internaldb.ldapauth.bindPWPrompt=Internal LDAP Database
+internaldb.ldapauth.clientCertNickname=
+internaldb.ldapconn.host=
+internaldb.ldapconn.port=
+internaldb.ldapconn.secureConn=false
+preop.internaldb.schema.ldif=/usr/share/[PKI_FLAVOR]/tks/conf/schema.ldif
+preop.internaldb.ldif=/usr/share/[PKI_FLAVOR]/tks/conf/database.ldif
+preop.internaldb.data_ldif=/usr/share/[PKI_FLAVOR]/tks/conf/db.ldif,/usr/share/[PKI_FLAVOR]/tks/conf/acl.ldif
+preop.internaldb.index_ldif=/usr/share/[PKI_FLAVOR]/tks/conf/index.ldif
+preop.internaldb.manager_ldif=/usr/share/[PKI_FLAVOR]/ca/conf/manager.ldif
+preop.internaldb.post_ldif=
+preop.internaldb.wait_dn=
+internaldb.multipleSuffix.enable=false
+jss._000=##
+jss._001=## JSS
+jss._002=##
+jss.configDir=[PKI_INSTANCE_PATH]/alias/
+jss.enable=true
+jss.secmodName=secmod.db
+jss.ocspcheck.enable=false
+jss.ssl.cipherfortezza=true
+jss.ssl.cipherpref=
+jss.ssl.cipherversion=cipherdomestic
+log._000=##
+log._001=## Logging
+log._002=##
+log.impl.file.class=com.netscape.cms.logging.RollingLogFile
+log.instance.SignedAudit._000=##
+log.instance.SignedAudit._001=## Signed Audit Logging
+log.instance.SignedAudit._002=##
+log.instance.SignedAudit._003=##
+log.instance.SignedAudit._004=## Available Audit events:
+log.instance.SignedAudit._005=## AUDIT_LOG_STARTUP,AUDIT_LOG_SHUTDOWN,ROLE_ASSUME,CONFIG_CERT_POLICY,CONFIG_CERT_PROFILE,CONFIG_CRL_PROFILE,CONFIG_OCSP_PROFILE,CONFIG_AUTH,CONFIG_ROLE,CONFIG_ACL,CONFIG_SIGNED_AUDIT,CONFIG_ENCRYPTION,CONFIG_TRUSTED_PUBLIC_KEY,CONFIG_DRM,SELFTESTS_EXECUTION,AUDIT_LOG_DELETE,LOG_PATH_CHANGE,LOG_EXPIRATION_CHANGE,PRIVATE_KEY_ARCHIVE_REQUEST,PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE,KEY_RECOVERY_REQUEST,KEY_RECOVERY_REQUEST_ASYNC,KEY_RECOVERY_AGENT_LOGIN,KEY_RECOVERY_REQUEST_PROCESSED,KEY_RECOVERY_REQUEST_PROCESSED_ASYNC,KEY_GEN_ASYMMETRIC,NON_PROFILE_CERT_REQUEST,PROFILE_CERT_REQUEST,CERT_REQUEST_PROCESSED,CERT_STATUS_CHANGE_REQUEST,CERT_STATUS_CHANGE_REQUEST_PROCESSED,AUTHZ_SUCCESS,AUTHZ_FAIL,INTER_BOUNDARY,AUTH_FAIL,AUTH_SUCCESS,CERT_PROFILE_APPROVAL,PROOF_OF_POSSESSION,CRL_RETRIEVAL,CRL_VALIDATION,CMC_SIGNED_REQUEST_SIG_VERIFY,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_FAILURE,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_SUCCESS,SERVER_SIDE_KEYGEN_REQUEST,COMPUTE_SESSION_KEY_REQUEST,COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS, COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE,DIVERSIFY_KEY_REQUEST,DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS, DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE,ENCRYPT_DATA_REQUEST,ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS,ENCRYPT_DATA_REQUEST_PROCESSED_FAILURE,OCSP_ADD_CA_REQUEST,OCSP_ADD_CA_REQUEST_PROCESSED,OCSP_REMOVE_CA_REQUEST,OCSP_REMOVE_CA_REQUEST_PROCESSED_SUCCESS,OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE,COMPUTE_RANDOM_DATA_REQUEST,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_SUCCESS,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_FAILURE,CIMC_CERT_VERIFICATION
+log.instance.SignedAudit._006=##
+log.instance.SignedAudit.bufferSize=512
+log.instance.SignedAudit.enable=true
+log.instance.SignedAudit.events=AUDIT_LOG_STARTUP,AUDIT_LOG_SHUTDOWN,ROLE_ASSUME,CONFIG_CERT_POLICY,CONFIG_CERT_PROFILE,CONFIG_CRL_PROFILE,CONFIG_OCSP_PROFILE,CONFIG_AUTH,CONFIG_ROLE,CONFIG_ACL,CONFIG_SIGNED_AUDIT,CONFIG_ENCRYPTION,CONFIG_TRUSTED_PUBLIC_KEY,CONFIG_DRM,SELFTESTS_EXECUTION,AUDIT_LOG_DELETE,LOG_PATH_CHANGE,PRIVATE_KEY_ARCHIVE_REQUEST,PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE,KEY_RECOVERY_REQUEST,KEY_RECOVERY_REQUEST_ASYNC,KEY_RECOVERY_AGENT_LOGIN,KEY_RECOVERY_REQUEST_PROCESSED,KEY_RECOVERY_REQUEST_PROCESSED_ASYNC,KEY_GEN_ASYMMETRIC,NON_PROFILE_CERT_REQUEST,PROFILE_CERT_REQUEST,CERT_REQUEST_PROCESSED,CERT_STATUS_CHANGE_REQUEST,CERT_STATUS_CHANGE_REQUEST_PROCESSED,AUTHZ_SUCCESS,AUTHZ_FAIL,INTER_BOUNDARY,AUTH_FAIL,AUTH_SUCCESS,CERT_PROFILE_APPROVAL,PROOF_OF_POSSESSION,CRL_RETRIEVAL,CRL_VALIDATION,CMC_SIGNED_REQUEST_SIG_VERIFY,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_FAILURE,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_SUCCESS,SERVER_SIDE_KEYGEN_REQUEST,COMPUTE_SESSION_KEY_REQUEST,COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS, COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE,DIVERSIFY_KEY_REQUEST,DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS, DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE,ENCRYPT_DATA_REQUEST,ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS,ENCRYPT_DATA_REQUEST_PROCESSED_FAILURE,OCSP_ADD_CA_REQUEST,OCSP_ADD_CA_REQUEST_PROCESSED,OCSP_REMOVE_CA_REQUEST,OCSP_REMOVE_CA_REQUEST_PROCESSED_SUCCESS,OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE,COMPUTE_RANDOM_DATA_REQUEST,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_SUCCESS,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_FAILURE,CIMC_CERT_VERIFICATION
+log.instance.SignedAudit.expirationTime=0
+log.instance.SignedAudit.fileName=[PKI_INSTANCE_PATH]/logs/signedAudit/tks_cert-tks_audit
+log.instance.SignedAudit.flushInterval=5
+log.instance.SignedAudit.level=1
+log.instance.SignedAudit.logSigning=false
+log.instance.SignedAudit.maxFileSize=2000
+log.instance.SignedAudit.pluginName=file
+log.instance.SignedAudit.rolloverInterval=2592000
+log.instance.SignedAudit.signedAudit:_000=##
+log.instance.SignedAudit.signedAudit:_001=## Fill in the nickname of a trusted signing certificate to allow TKS audit logs to be signed
+log.instance.SignedAudit.signedAudit:_002=##
+log.instance.SignedAudit.signedAuditCertNickname=auditSigningCert cert-[PKI_INSTANCE_ID]
+log.instance.SignedAudit.type=signedAudit
+log.instance.System._000=##
+log.instance.System._001=## System Logging
+log.instance.System._002=##
+log.instance.System.bufferSize=512
+log.instance.System.enable=true
+log.instance.System.expirationTime=0
+log.instance.System.fileName=[PKI_INSTANCE_PATH]/logs/system
+log.instance.System.flushInterval=5
+log.instance.System.level=3
+log.instance.System.maxFileSize=2000
+log.instance.System.pluginName=file
+log.instance.System.rolloverInterval=2592000
+log.instance.System.type=system
+log.instance.Transactions._000=##
+log.instance.Transactions._001=## Transaction Logging
+log.instance.Transactions._002=##
+log.instance.Transactions.bufferSize=512
+log.instance.Transactions.enable=true
+log.instance.Transactions.expirationTime=0
+log.instance.Transactions.fileName=[PKI_INSTANCE_PATH]/logs/transactions
+log.instance.Transactions.flushInterval=5
+log.instance.Transactions.level=1
+log.instance.Transactions.maxFileSize=2000
+log.instance.Transactions.pluginName=file
+log.instance.Transactions.rolloverInterval=2592000
+log.instance.Transactions.type=transaction
+logAudit.fileName=[PKI_INSTANCE_PATH]/logs/access
+logError.fileName=[PKI_INSTANCE_PATH]/logs/error
+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.extended_key_usage.class=netscape.security.extensions.ExtendedKeyUsageExtension
+oidmap.extended_key_usage.oid=2.5.29.37
+oidmap.extensions_requested_pkcs9.class=com.netscape.cms.servlet.cert.scep.ExtensionsRequested
+oidmap.extensions_requested_pkcs9.oid=1.2.840.113549.1.9.14
+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.netscape_comment.class=netscape.security.x509.NSCCommentExtension
+oidmap.netscape_comment.oid=2.16.840.1.113730.1.13
+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.pse.class=netscape.security.extensions.PresenceServerExtension
+oidmap.pse.oid=2.16.840.1.113730.1.18
+oidmap.subject_info_access.class=netscape.security.extensions.SubjectInfoAccessExtension
+oidmap.subject_info_access.oid=1.3.6.1.5.5.7.1.11
+os.serverName=cert-[PKI_INSTANCE_ID]
+os.userid=nobody
+registry.file=[PKI_INSTANCE_PATH]/conf/registry.cfg
+selftests._000=##
+selftests._001=## Self Tests
+selftests._002=##
+selftests._003=## The Self-Test plugin SystemCertsVerification uses the
+selftests._004=## following parameters (where certusage is optional):
+selftests._005=## tks.cert.list = <list of cert tag names deliminated by ",">
+selftests._006=## tks.cert.<cert tag name>.nickname
+selftests._007=## tks.cert.<cert tag name>.certusage
+selftests._008=##
+selftests.container.instance.TKSKnownSessionKey=com.netscape.cms.selftests.tks.TKSKnownSessionKey
+selftests.container.instance.SystemCertsVerification=com.netscape.cms.selftests.common.SystemCertsVerification
+selftests.container.logger.bufferSize=512
+selftests.container.logger.class=com.netscape.cms.logging.RollingLogFile
+selftests.container.logger.enable=true
+selftests.container.logger.expirationTime=0
+selftests.container.logger.fileName=[PKI_INSTANCE_PATH]/logs/selftests.log
+selftests.container.logger.flushInterval=5
+selftests.container.logger.level=1
+selftests.container.logger.maxFileSize=2000
+selftests.container.logger.register=false
+selftests.container.logger.rolloverInterval=2592000
+selftests.container.logger.type=transaction
+selftests.container.order.onDemand=TKSKnownSessionKey:critical, SystemCertsVerification:critical
+selftests.container.order.startup=TKSKnownSessionKey:critical, SystemCertsVerification:critical
+selftests.plugin.TKSKnownSessionKey.CUID=#a0#01#92#03#04#05#06#07#08#c9
+selftests.plugin.TKSKnownSessionKey.TksSubId=tks
+selftests.plugin.TKSKnownSessionKey.cardChallenge=#bd#6d#19#85#6e#54#0f#cd
+selftests.plugin.TKSKnownSessionKey.hostChallenge=#77#57#62#e4#5e#23#66#7d
+selftests.plugin.TKSKnownSessionKey.keyName=#01#01
+selftests.plugin.TKSKnownSessionKey.macKey=#40#41#42#43#44#45#46#47#48#49#4a#4b#4c#4d#4e#4f
+selftests.plugin.TKSKnownSessionKey.sessionKey=#d1#be#b8#26#dc#56#20#25#8c#93#e7#de#f0#ab#4f#5b
+selftests.plugin.TKSKnownSessionKey.token=Internal Key Storage Token
+selftests.plugin.TKSKnownSessionKey.useSoftToken=true
+selftests.plugin.SystemCertsVerification.SubId=tks
+smtp.host=localhost
+smtp.port=25
+subsystem.0.class=com.netscape.tks.TKSAuthority
+subsystem.0.id=tks
+subsystem.1.class=com.netscape.cmscore.selftests.SelfTestSubsystem
+subsystem.1.id=selftests
+subsystem.2.class=com.netscape.cmscore.util.StatsSubsystem
+subsystem.2.id=stats
+tks._000=##
+tks._001=## TKS
+tks._002=##
+tks._003=##
+tks._004=##
+tks.debug=false
+tks.defaultSlot=Internal Key Storage Token
+tks.drm_transport_cert_nickname=
+tks.master_key_prefix=
+tks.tksSharedSymKeyName=sharedSecret
+tks.useDefaultSlot=true
+usrgrp._000=##
+usrgrp._001=## User/Group
+usrgrp._002=##
+usrgrp.ldap=internaldb
+tks.defKeySet._000=##
+tks.defKeySet._001=## Axalto default key set:
+tks.defKeySet._002=##
+tks.defKeySet._003=## tks.defKeySet.mk_mappings.#02#01=<tokenname>:<nickname>
+tks.defKeySet._004=##
+tks.defKeySet.auth_key=#40#41#42#43#44#45#46#47#48#49#4a#4b#4c#4d#4e#4f
+tks.defKeySet.mac_key=#40#41#42#43#44#45#46#47#48#49#4a#4b#4c#4d#4e#4f
+tks.defKeySet.kek_key=#40#41#42#43#44#45#46#47#48#49#4a#4b#4c#4d#4e#4f
+tks.jForte._000=##
+tks.jForte._001=## SAFLink's jForte default key set:
+tks.jForte._002=##
+tks.jForte._003=## tks.jForte.mk_mappings.#02#01=<tokenname>:<nickname>
+tks.jForte._004=##
+tks.jForte.auth_key=#30#31#32#33#34#35#36#37#38#39#3a#3b#3c#3d#3e#3f
+tks.jForte.mac_key=#40#41#42#43#44#45#46#47#48#49#4a#4b#4c#4d#4e#4f
+tks.jForte.kek_key=#50#51#52#53#54#55#56#57#58#59#5a#5b#5c#5d#5e#5f
+multiroles._000=##
+multiroles._001=## multiroles
+multiroles._002=##
+multiroles.enable=true
+multiroles.false.groupEnforceList=Administrators,Auditors,Trusted Managers,Certificate Manager Agents,Registration Manager Agents,Data Recovery Manager Agents,Online Certificate Status Manager Agents,Token Key Service Manager Agents,Enterprise CA Administrators,Enterprise KRA Administrators,Enterprise OCSP Administrators,Enterprise RA Administrators,Enterprise TKS Administrators,Enterprise TPS Administrators,Security Domain Administrators,Subsystem Group,ClonedSubsystems
diff --git a/base/tks/shared/conf/acl.ldif b/base/tks/shared/conf/acl.ldif
new file mode 100644
index 000000000..b38b5963f
--- /dev/null
+++ b/base/tks/shared/conf/acl.ldif
@@ -0,0 +1,30 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+dn: cn=aclResources,{rootSuffix}
+objectClass: top
+objectClass: CertACLS
+cn: aclResources
+resourceACLS: certServer.general.configuration:read,modify,delete:allow (read) group="Administrators" || group="Auditors" || group="Token Key Service Manager Agents";allow (modify,delete) group="Administrators":Administrators, auditors, and agents are allowed to read CMS general configuration but only administrators are allowed to modify and delete
+resourceACLS: certServer.acl.configuration:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Token Key Service Manager Agents";allow (modify) group="Administrators":Administrators, agents and auditors are allowed to read ACL configuration but only administrators allowed to modify
+resourceACLS: certServer.log.configuration:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Token Key Service Manager Agents";allow (modify) group="Administrators":Administrators, Agents, and auditors are allowed to read the log configuration but only administrators are allowed to modify
+resourceACLS: certServer.log.configuration.fileName:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Token Key Service Manager Agents";deny (modify) user=anybody:Nobody is allowed to modify a fileName parameter
+#resourceACLS: certServer.log.configuration.signedAudit.expirationTime:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Token Key Service Manager Agents";deny (modify) user=anybody:Nobody is allowed to modify an expirationTime parameter
+resourceACLS: certServer.log.content.signedAudit:read:allow (read) group="Auditors":Only auditor is allowed to read the signed audit log
+resourceACLS: certServer.log.content.system:read:allow (read) group="Administrators" || group="Auditors" || group="Token Key Service Manager Agents":Administrators, auditors, and agents are allowed to read the log content
+resourceACLS: certServer.log.content.transactions:read:allow (read) group="Administrators" || group="Auditors" || group="Token Key Service Manager Agents":Administrators, auditors, and agents are allowed to read the log content
+resourceACLS: certServer.auth.configuration:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Token Key Service Manager Agents";allow (modify) group="Administrators":Administrators, agents, and auditors are allowed to read authentication configuration but only administrators allowed to modify
+resourceACLS: certServer.registry.configuration:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Token Key Service Manager Agents";allow (modify) group="Administrators":this acl is shared by all admin servlets
+resourceACLS: certServer.admin.certificate:import:allow (import) user="anybody":Any user may import a certificate
+resourceACLS: certServer.admin.request.enrollment:submit,read,execute:allow (submit) user="anybody":Anybody may submit an enrollment request
+resourceACLS: certServer.tks.systemstatus:read:allow (read) group="Token Key Service Manager Agents":Token Key Service Manager agents may view statistics
+resourceACLS: certServer.tks.group:read,modify:allow (modify,read) group="Administrators";allow (read) group="Token Key Service Manager Agents":Only administrators are allowed to modify groups
+resourceACLS: certServer.tks.encrypteddata:execute:allow (execute) group="Token Key Service Manager Agents":Token Key Service Manager agents may execute encrypted data information servlet
+resourceACLS: certServer.tks.keysetdata:execute:allow (execute) group="Token Key Service Manager Agents":Token Key Service Manager agents may execute key set data information servlet
+resourceACLS: certServer.tks.sessionkey:execute:allow (execute) group="Token Key Service Manager Agents":Token Key Service Manager agents may execute session key servlet
+resourceACLS: certServer.tks.randomdata:execute:allow (execute) group="Token Key Service Manager Agents":Token Key Service Manager agents may execute random data servlet
+resourceACLS: certServer.tks.registerUser:read,modify:allow (modify,read) group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise OCSP Administrators" || group="Enterprise TKS Administrators" || group="Enterprise TPS Administrators":Only Enterprise Administrators are allowed to register a new agent
+resourceACLS: certServer.tks.importTransportCert:read,modify:allow (modify,read) group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise OCSP Administrators" || group="Enterprise TKS Administrators" || group="Enterprise TPS Administrators":Only Enterprise Administrators are allowed to import transport certificate
+resourceACLS: certServer.clone.configuration:read,modify:allow (modify,read) group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise OCSP Administrators" || group="Enterprise TKS Administrators":Only Enterprise Administrators are allowed to clone the configuration.
diff --git a/base/tks/shared/conf/catalina.policy b/base/tks/shared/conf/catalina.policy
new file mode 100644
index 000000000..cf8302cd0
--- /dev/null
+++ b/base/tks/shared/conf/catalina.policy
@@ -0,0 +1,184 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// Copyright (C) 2006-2010 Red Hat, Inc.
+// All rights reserved.
+// Modifications: configuration parameters
+// --- END COPYRIGHT BLOCK ---
+
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// ============================================================================
+// catalina.corepolicy - Security Policy Permissions for Tomcat 6
+//
+// This file contains a default set of security policies to be enforced (by the
+// JVM) when Catalina is executed with the "-security" option. In addition
+// to the permissions granted here, the following additional permissions are
+// granted to the codebase specific to each web application:
+//
+// * Read access to the document root directory
+//
+// $Id$
+// ============================================================================
+
+
+// ========== SYSTEM CODE PERMISSIONS =========================================
+
+
+// These permissions apply to javac
+grant codeBase "file:${java.home}/lib/-" {
+ permission java.security.AllPermission;
+};
+
+// These permissions apply to all shared system extensions
+grant codeBase "file:${java.home}/jre/lib/ext/-" {
+ permission java.security.AllPermission;
+};
+
+// These permissions apply to javac when ${java.home] points at $JAVA_HOME/jre
+grant codeBase "file:${java.home}/../lib/-" {
+ permission java.security.AllPermission;
+};
+
+// These permissions apply to all shared system extensions when
+// ${java.home} points at $JAVA_HOME/jre
+grant codeBase "file:${java.home}/lib/ext/-" {
+ permission java.security.AllPermission;
+};
+
+
+// ========== CATALINA CODE PERMISSIONS =======================================
+
+
+// These permissions apply to the daemon code
+grant codeBase "file:${catalina.home}/bin/commons-daemon.jar" {
+ permission java.security.AllPermission;
+};
+
+// These permissions apply to the logging API
+grant codeBase "file:${catalina.home}/bin/tomcat-juli.jar" {
+ permission java.util.PropertyPermission "java.util.logging.config.class", "read";
+ permission java.util.PropertyPermission "java.util.logging.config.file", "read";
+ permission java.io.FilePermission "${java.home}${file.separator}lib${file.separator}logging.properties", "read";
+ permission java.lang.RuntimePermission "shutdownHooks";
+ permission java.io.FilePermission "${catalina.base}${file.separator}conf${file.separator}logging.properties", "read";
+ permission java.util.PropertyPermission "catalina.base", "read";
+ permission java.util.logging.LoggingPermission "control";
+ permission java.io.FilePermission "${catalina.base}${file.separator}logs", "read, write";
+ permission java.io.FilePermission "${catalina.base}${file.separator}logs${file.separator}*", "read, write";
+ permission java.lang.RuntimePermission "getClassLoader";
+ // To enable per context logging configuration, permit read access to the appropriate file.
+ // Be sure that the logging configuration is secure before enabling such access
+ // eg for the examples web application:
+ // permission java.io.FilePermission "${catalina.base}${file.separator}webapps${file.separator}examples${file.separator}WEB-INF${file.separator}classes${file.separator}logging.properties", "read";
+};
+
+// These permissions apply to the server startup code
+grant codeBase "file:${catalina.home}/bin/bootstrap.jar" {
+ permission java.security.AllPermission;
+};
+
+// These permissions apply to the servlet API classes
+// and those that are shared across all class loaders
+// located in the "lib" directory
+grant codeBase "file:${catalina.home}/lib/-" {
+ permission java.security.AllPermission;
+};
+
+
+// ========== WEB APPLICATION PERMISSIONS =====================================
+
+
+// These permissions are granted by default to all web applications
+// In addition, a web application will be given a read FilePermission
+// and JndiPermission for all files and directories in its document root.
+grant {
+ // Required for JNDI lookup of named JDBC DataSource's and
+ // javamail named MimePart DataSource used to send mail
+ permission java.util.PropertyPermission "java.home", "read";
+ permission java.util.PropertyPermission "java.naming.*", "read";
+ permission java.util.PropertyPermission "javax.sql.*", "read";
+
+ // OS Specific properties to allow read access
+ permission java.util.PropertyPermission "os.name", "read";
+ permission java.util.PropertyPermission "os.version", "read";
+ permission java.util.PropertyPermission "os.arch", "read";
+ permission java.util.PropertyPermission "file.separator", "read";
+ permission java.util.PropertyPermission "path.separator", "read";
+ permission java.util.PropertyPermission "line.separator", "read";
+
+ // JVM properties to allow read access
+ permission java.util.PropertyPermission "java.version", "read";
+ permission java.util.PropertyPermission "java.vendor", "read";
+ permission java.util.PropertyPermission "java.vendor.url", "read";
+ permission java.util.PropertyPermission "java.class.version", "read";
+ permission java.util.PropertyPermission "java.specification.version", "read";
+ permission java.util.PropertyPermission "java.specification.vendor", "read";
+ permission java.util.PropertyPermission "java.specification.name", "read";
+
+ permission java.util.PropertyPermission "java.vm.specification.version", "read";
+ permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
+ permission java.util.PropertyPermission "java.vm.specification.name", "read";
+ permission java.util.PropertyPermission "java.vm.version", "read";
+ permission java.util.PropertyPermission "java.vm.vendor", "read";
+ permission java.util.PropertyPermission "java.vm.name", "read";
+
+ // Required for OpenJMX
+ permission java.lang.RuntimePermission "getAttribute";
+
+ // Allow read of JAXP compliant XML parser debug
+ permission java.util.PropertyPermission "jaxp.debug", "read";
+
+ // Precompiled JSPs need access to this package.
+ permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime";
+ permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime.*";
+
+ // Precompiled JSPs need access to this system property.
+ permission java.util.PropertyPermission "org.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER", "read";
+
+};
+
+
+// You can assign additional permissions to particular web applications by
+// adding additional "grant" entries here, based on the code base for that
+// application, /WEB-INF/classes/, or /WEB-INF/lib/ jar files.
+//
+// Different permissions can be granted to JSP pages, classes loaded from
+// the /WEB-INF/classes/ directory, all jar files in the /WEB-INF/lib/
+// directory, or even to individual jar files in the /WEB-INF/lib/ directory.
+//
+// For instance, assume that the standard "examples" application
+// included a JDBC driver that needed to establish a network connection to the
+// corresponding database and used the scrape taglib to get the weather from
+// the NOAA web server. You might create a "grant" entries like this:
+//
+// The permissions granted to the context root directory apply to JSP pages.
+// grant codeBase "file:${catalina.home}/webapps/examples/-" {
+// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
+// permission java.net.SocketPermission "*.noaa.gov:80", "connect";
+// };
+//
+// The permissions granted to the context WEB-INF/classes directory
+// grant codeBase "file:${catalina.home}/webapps/examples/WEB-INF/classes/-" {
+// };
+//
+// The permission granted to your JDBC driver
+// grant codeBase "jar:file:${catalina.home}/webapps/examples/WEB-INF/lib/driver.jar!/-" {
+// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
+// };
+// The permission granted to the scrape taglib
+// grant codeBase "jar:file:${catalina.home}/webapps/examples/WEB-INF/lib/scrape.jar!/-" {
+// permission java.net.SocketPermission "*.noaa.gov:80", "connect";
+// };
+
diff --git a/base/tks/shared/conf/catalina.properties b/base/tks/shared/conf/catalina.properties
new file mode 100644
index 000000000..70cb7c05e
--- /dev/null
+++ b/base/tks/shared/conf/catalina.properties
@@ -0,0 +1,87 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006-2010 Red Hat, Inc.
+# All rights reserved.
+# Modifications: configuration parameters
+# --- END COPYRIGHT BLOCK ---
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# List of comma-separated packages that start with or equal this string
+# will cause a security exception to be thrown when
+# passed to checkPackageAccess unless the
+# corresponding RuntimePermission ("accessClassInPackage."+package) has
+# been granted.
+package.access=sun.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper.,sun.beans.
+#
+# List of comma-separated packages that start with or equal this string
+# will cause a security exception to be thrown when
+# passed to checkPackageDefinition unless the
+# corresponding RuntimePermission ("defineClassInPackage."+package) has
+# been granted.
+#
+# by default, no packages are restricted for definition, and none of
+# the class loaders supplied with the JDK call checkPackageDefinition.
+#
+package.definition=sun.,java.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper.
+
+#
+#
+# List of comma-separated paths defining the contents of the "common"
+# classloader. Prefixes should be used to define what is the repository type.
+# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute.
+# If left as blank,the JVM system loader will be used as Catalina's "common"
+# loader.
+# Examples:
+# "foo": Add this folder as a class repository
+# "foo/*.jar": Add all the JARs of the specified folder as class
+# repositories
+# "foo/bar.jar": Add bar.jar as a class repository
+common.loader=${catalina.home}/lib,${catalina.home}/lib/*.jar,[TOMCAT_INSTANCE_COMMON_LIB]
+
+#
+# List of comma-separated paths defining the contents of the "server"
+# classloader. Prefixes should be used to define what is the repository type.
+# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute.
+# If left as blank, the "common" loader will be used as Catalina's "server"
+# loader.
+# Examples:
+# "foo": Add this folder as a class repository
+# "foo/*.jar": Add all the JARs of the specified folder as class
+# repositories
+# "foo/bar.jar": Add bar.jar as a class repository
+server.loader=
+
+#
+# List of comma-separated paths defining the contents of the "shared"
+# classloader. Prefixes should be used to define what is the repository type.
+# Path may be relative to the CATALINA_BASE path or absolute. If left as blank,
+# the "common" loader will be used as Catalina's "shared" loader.
+# Examples:
+# "foo": Add this folder as a class repository
+# "foo/*.jar": Add all the JARs of the specified folder as class
+# repositories
+# "foo/bar.jar": Add bar.jar as a class repository
+# Please note that for single jars, e.g. bar.jar, you need the URL form
+# starting with file:.
+shared.loader=
+
+#
+# String cache configuration.
+tomcat.util.buf.StringCache.byte.enabled=true
+#tomcat.util.buf.StringCache.char.enabled=true
+#tomcat.util.buf.StringCache.trainThreshold=500000
+#tomcat.util.buf.StringCache.cacheSize=5000
diff --git a/base/tks/shared/conf/context.xml b/base/tks/shared/conf/context.xml
new file mode 100644
index 000000000..8b6fe4905
--- /dev/null
+++ b/base/tks/shared/conf/context.xml
@@ -0,0 +1,40 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2006-2010 Red Hat, Inc.
+ All rights reserved.
+ Modifications: configuration parameters
+ END COPYRIGHT BLOCK -->
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- The contents of this file will be loaded for each web application -->
+<Context crossContext="true" allowLinking="true">
+
+ <!-- Default set of monitored resources -->
+ <WatchedResource>WEB-INF/web.xml</WatchedResource>
+
+ <!-- Uncomment this to disable session persistence across Tomcat restarts -->
+ <!--
+ <Manager pathname="" />
+ -->
+
+ <!-- Uncomment this to enable Comet connection tacking (provides events
+ on session expiration as well as webapp lifecycle) -->
+ <!--
+ <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
+ -->
+
+</Context>
diff --git a/base/tks/shared/conf/database.ldif b/base/tks/shared/conf/database.ldif
new file mode 100644
index 000000000..d3c5f9e68
--- /dev/null
+++ b/base/tks/shared/conf/database.ldif
@@ -0,0 +1,9 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+dn: cn=config
+changetype: modify
+replace: nsslapd-maxbersize
+nsslapd-maxbersize: 209715200
diff --git a/base/tks/shared/conf/db.ldif b/base/tks/shared/conf/db.ldif
new file mode 100644
index 000000000..6aaa310a9
--- /dev/null
+++ b/base/tks/shared/conf/db.ldif
@@ -0,0 +1,66 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+dn: ou=people,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: people
+aci: (targetattr!="userPassword")(version 3.0; acl "Enable anonymous access"; allow (read, search, compare)userdn="ldap:///anyone";)
+
+dn: ou=groups,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: groups
+
+dn: cn=Token Key Service Manager Agents,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Token Key Service Manager Agents
+description: Agents for Token Key Service Manager
+
+dn: cn=Subsystem Group, ou=groups, {rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Subsystem Group
+description: Subsystem Group
+
+dn: cn=Trusted Managers,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Trusted Managers
+description: Managers trusted by this PKI instance
+
+dn: cn=Administrators,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Administrators
+description: People who manage the Certificate System
+
+dn: cn=Auditors,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: Auditors
+description: People who can read the signed audits
+
+dn: cn=ClonedSubsystems,ou=groups,{rootSuffix}
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: ClonedSubsystems
+description: People who can clone the master subsystem
+
+dn: ou=requests,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: requests
+
+dn: cn=crossCerts,{rootSuffix}
+cn: crossCerts
+sn: crossCerts
+objectClass: top
+objectClass: person
+objectClass: pkiCA
+cACertificate;binary:
+authorityRevocationList;binary:
+certificateRevocationList;binary:
diff --git a/base/tks/shared/conf/index.ldif b/base/tks/shared/conf/index.ldif
new file mode 100644
index 000000000..184187045
--- /dev/null
+++ b/base/tks/shared/conf/index.ldif
@@ -0,0 +1,203 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+dn: cn=revokedby,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: revokedby
+
+dn: cn=issuedby,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: issuedby
+
+dn: cn=publicKeyData,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: publicKeyData
+
+dn: cn=clientId,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: clientId
+
+dn: cn=dataType,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: dataType
+
+dn: cn=status,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsSystemIndex: false
+cn: status
+
+dn: cn=description,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: description
+
+dn: cn=serialno,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: serialno
+
+dn: cn=metaInfo,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: metaInfo
+
+dn: cn=certstatus,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: certstatus
+
+dn: cn=requestid,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: requestid
+
+dn: cn=requesttype,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: requesttype
+
+dn: cn=requeststate,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: requeststate
+
+dn: cn=requestowner,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: requestowner
+
+dn: cn=notbefore,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: notbefore
+
+dn: cn=notafter,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: notafter
+
+dn: cn=duration,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: duration
+
+dn: cn=dateOfCreate,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: dateOfCreate
+
+dn: cn=revokedOn,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: revokedOn
+
+dn: cn=archivedBy,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsSystemIndex: false
+cn: archivedBy
+
+dn: cn=ownername,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsIndexType: sub
+nsSystemIndex: false
+cn: ownername
+
+dn: cn=subjectname,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsIndexType: sub
+nsSystemIndex: false
+cn: subjectname
+
+dn: cn=requestsourceid,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsIndexType: sub
+nsSystemIndex: false
+cn: requestsourceid
+
+dn: cn=revInfo,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsIndexType: sub
+nsSystemIndex: false
+cn: revInfo
+
+dn: cn=extension,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: nsIndex
+nsIndexType: eq
+nsIndexType: pres
+nsIndexType: sub
+nsSystemIndex: false
+cn: extension
diff --git a/base/tks/shared/conf/jk2.manifest b/base/tks/shared/conf/jk2.manifest
new file mode 100644
index 000000000..986d7b874
--- /dev/null
+++ b/base/tks/shared/conf/jk2.manifest
@@ -0,0 +1,2 @@
+Main-Class: org.apache.jk.apr.TomcatStarter
+Class-Path: ../lib/tomcat.jar log4j.jar log4j-core.jar ../lib/common/log4j.jar ../lib/common/log4j-core.jar ../lib/common/classes ../lib/common/commons-logging.jar bootstrap.jar ../server/lib/commons-logging.jar ../server/lib/jmx.jar jmx.jar commons-logging-api.jar
diff --git a/base/tks/shared/conf/jk2.properties b/base/tks/shared/conf/jk2.properties
new file mode 100644
index 000000000..4d8e357f8
--- /dev/null
+++ b/base/tks/shared/conf/jk2.properties
@@ -0,0 +1,31 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+## THIS FILE MAY BE OVERRIDEN AT RUNTIME. MAKE SURE TOMCAT IS STOPED
+## WHEN YOU EDIT THE FILE.
+
+## COMMENTS WILL BE _LOST_
+
+## DOCUMENTATION OF THE FORMAT IN JkMain javadoc.
+
+# Set the desired handler list
+# handler.list=apr,request,channelJni
+#
+# Override the default port for the socketChannel
+# channelSocket.port=8019
+# Default:
+# channelUnix.file=${jkHome}/work/jk2.socket
+# Just to check if the the config is working
+# shm.file=${jkHome}/work/jk2.shm
+
+# In order to enable jni use any channelJni directive
+# channelJni.disabled = 0
+# And one of the following directives:
+
+# apr.jniModeSo=/opt/apache2/modules/mod_jk2.so
+
+# If set to inprocess the mod_jk2 will Register natives itself
+# This will enable the starting of the Tomcat from mod_jk2
+# apr.jniModeSo=inprocess
diff --git a/base/tks/shared/conf/jkconf.ant.xml b/base/tks/shared/conf/jkconf.ant.xml
new file mode 100644
index 000000000..a4f498050
--- /dev/null
+++ b/base/tks/shared/conf/jkconf.ant.xml
@@ -0,0 +1,55 @@
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2006 Red Hat, Inc.
+ All rights reserved.
+ END COPYRIGHT BLOCK -->
+<project name="jkconf" default="main" basedir=".">
+
+ <target name="init-3x" if="33.detect">
+ <taskdef name="jkconf"
+ classname="org.apache.jk.config.WebXml2Jk" >
+ <classpath>
+ <!-- 3.3 support -->
+ <pathelement location="/ws/jtc/jk/build/classes" />
+ <pathelement location="${tomcat.home}/lib/container/tomcat-jk2.jar" />
+ <pathelement location="${tomcat.home}/lib/container/crimson.jar"/>
+ <pathelement location="${tomcat.home}/lib/common/commons-logging.jar"/>
+ </classpath>
+ </taskdef>
+ </target>
+
+ <target name="init-4x" if="4x.detect" >
+ <path id="main.classpath">
+ <!-- 3.3 support -->
+ <fileset dir="${tomcat.home}/lib" includes="*.jar" />
+ <fileset dir="${tomcat.home}/server/lib" includes="*.jar" />
+ <fileset dir="${tomcat.home}/common/lib" includes="*.jar" />
+ </path>
+
+ <taskdef name="jkconf" classpathref="main.classpath"
+ classname="org.apache.jk.config.WebXml2Jk" />
+ </target>
+
+ <target name="detect" >
+ <property file="build.properties"/>
+ <property file="${user.home}/build.properties"/>
+ <property file="${user.home}/.build.properties"/>
+
+ <!-- default locations, overrident by properties.
+ This file must be installed in conf/ -->
+ <property name="tomcat.home" location=".." />
+
+ <available property="33.detect" file="${tomcat.home}/lib/container" />
+ <available property="4x.detect" file="${tomcat.home}/server/lib" />
+ </target>
+
+ <target name="init" depends="detect,init-3x,init-4x" />
+
+ <!-- ==================== Detection and reports ==================== -->
+
+
+ <target name="main" depends="init">
+ <jkconf docBase="${tomcat.home}/webapps/examples"
+ context="/examples" />
+ </target>
+
+</project>
diff --git a/base/tks/shared/conf/jkconfig.manifest b/base/tks/shared/conf/jkconfig.manifest
new file mode 100644
index 000000000..3ba1f2e3e
--- /dev/null
+++ b/base/tks/shared/conf/jkconfig.manifest
@@ -0,0 +1,2 @@
+Main-Class: org.apache.jk.config.WebXml2Jk
+Class-Path: tomcat-jk2.jar commons-logging.jar crimson.jar xercesImpl.jar xmlApis.jar tomcat-util.jar log4j.jar log4j-core.jar
diff --git a/base/tks/shared/conf/logging.properties b/base/tks/shared/conf/logging.properties
new file mode 100644
index 000000000..796cfc071
--- /dev/null
+++ b/base/tks/shared/conf/logging.properties
@@ -0,0 +1,70 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006-2010 Red Hat, Inc.
+# All rights reserved.
+# Modifications: configuration parameters
+# --- END COPYRIGHT BLOCK ---
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+handlers = 1catalina.org.apache.juli.FileHandler, 2localhost.org.apache.juli.FileHandler, 3manager.org.apache.juli.FileHandler, 4host-manager.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+
+.handlers = 1catalina.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+
+############################################################
+# Handler specific properties.
+# Describes specific configuration info for Handlers.
+############################################################
+
+1catalina.org.apache.juli.FileHandler.level = FINE
+1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+1catalina.org.apache.juli.FileHandler.prefix = catalina.
+
+2localhost.org.apache.juli.FileHandler.level = FINE
+2localhost.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+2localhost.org.apache.juli.FileHandler.prefix = localhost.
+
+3manager.org.apache.juli.FileHandler.level = FINE
+3manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+3manager.org.apache.juli.FileHandler.prefix = manager.
+
+4host-manager.org.apache.juli.FileHandler.level = FINE
+4host-manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+4host-manager.org.apache.juli.FileHandler.prefix = host-manager.
+
+java.util.logging.ConsoleHandler.level = FINE
+java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
+
+
+############################################################
+# Facility specific properties.
+# Provides extra control for each logger.
+############################################################
+
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler
+
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler
+
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler
+
+# For example, set the com.xyz.foo logger to only log SEVERE
+# messages:
+#org.apache.catalina.startup.ContextConfig.level = FINE
+#org.apache.catalina.startup.HostConfig.level = FINE
+#org.apache.catalina.session.ManagerBase.level = FINE
+#org.apache.catalina.core.AprLifecycleListener.level=FINE
diff --git a/base/tks/shared/conf/manager.ldif b/base/tks/shared/conf/manager.ldif
new file mode 100644
index 000000000..52e486987
--- /dev/null
+++ b/base/tks/shared/conf/manager.ldif
@@ -0,0 +1,48 @@
+# acis for cert manager
+
+dn: ou=csusers,cn=config
+objectClass: top
+objectClass: organizationalUnit
+ou: csusers
+
+dn: {rootSuffix}
+changetype: modify
+add: aci
+aci: (targetattr=*)(version 3.0; acl "cert manager access"; allow (all) userdn = "ldap:///{dbuser}";)
+
+dn: cn=ldbm database,cn=plugins,cn=config
+changetype: modify
+add: aci
+aci: (targetattr=*)(version 3.0; acl "Cert Manager access for VLV searches"; allow (read) userdn="ldap:///{dbuser}";)
+
+dn: cn=config
+changetype: modify
+add: aci
+aci: (targetattr != aci)(version 3.0; aci "cert manager read access"; allow (read, search, compare) userdn = "ldap:///{dbuser}";)
+
+dn: ou=csusers,cn=config
+changetype: modify
+add: aci
+aci: (targetattr != aci)(version 3.0; aci "cert manager manage replication users"; allow (all) userdn = "ldap:///{dbuser}";)
+
+dn: cn="{rootSuffix}",cn=mapping tree,cn=config
+changetype: modify
+add: aci
+aci: (targetattr=*)(version 3.0;acl "cert manager: Add Replication Agreements";allow (add) userdn = "ldap:///{dbuser}";)
+
+dn: cn="{rootSuffix}",cn=mapping tree,cn=config
+changetype: modify
+add: aci
+aci: (targetattr=*)(targetfilter="(|(objectclass=nsds5Replica)(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement)(objectClass=nsMappingTree))")(version 3.0; acl "cert manager: Modify Replication Agreements"; allow (read, write, search) userdn = "ldap:///{dbuser}";)
+
+dn: cn="{rootSuffix}",cn=mapping tree,cn=config
+changetype: modify
+add: aci
+aci: (targetattr=*)(targetfilter="(|(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement))")(version 3.0;acl "cert manager: Remove Replication Agreements";allow (delete) userdn = "ldap:///{dbuser}";)
+
+dn: cn=tasks,cn=config
+changetype: modify
+add: aci
+aci: (targetattr=*)(version 3.0; acl "cert manager: Run tasks after replica re-initialization"; allow (add) userdn = "ldap:///{dbuser}";)
+
+
diff --git a/base/tks/shared/conf/schema.ldif b/base/tks/shared/conf/schema.ldif
new file mode 100644
index 000000000..70578e21c
--- /dev/null
+++ b/base/tks/shared/conf/schema.ldif
@@ -0,0 +1,489 @@
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( usertype-oid NAME 'usertype' DESC 'Distinguish whether the user is administrator, agent or subsystem.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( userstate-oid NAME 'userstate' DESC 'Distinguish whether the user is administrator, agent or subsystem.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( cmsuser-oid NAME 'cmsuser' DESC 'CMS User' SUP top STRUCTURAL MUST usertype MAY userstate X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( archivedBy-oid NAME 'archivedBy' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( adminMessages-oid NAME 'adminMessages' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( algorithm-oid NAME 'algorithm' DESC 'CMS defined attribute'SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( algorithmId-oid NAME 'algorithmId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( signingAlgorithmId-oid NAME 'signingAlgorithmId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( autoRenew-oid NAME 'autoRenew' DESC 'CMS defined attribute'SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( certStatus-oid NAME 'certStatus' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( crlName-oid NAME 'crlName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( crlSize-oid NAME 'crlSize' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( deltaSize-oid NAME 'deltaSize' DESC 'CMS defined attribute'SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( crlNumber-oid NAME 'crlNumber' DESC 'CMS defined attribute'SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( deltaNumber-oid NAME 'deltaNumber' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( firstUnsaved-oid NAME 'firstUnsaved' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( crlCache-oid NAME 'crlCache' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( revokedCerts-oid NAME 'revokedCerts' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( unrevokedCerts-oid NAME 'unrevokedCerts' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( expiredCerts-oid NAME 'expiredCerts' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( crlExtensions-oid NAME 'crlExtensions' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dateOfArchival-oid NAME 'dateOfArchival' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dateOfRecovery-oid NAME 'dateOfRecovery' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dateOfRevocation-oid NAME 'dateOfRevocation' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dateOfCreate-oid NAME 'dateOfCreate' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dateOfModify-oid NAME 'dateOfModify' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( duration-oid NAME 'duration' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( extension-oid NAME 'extension' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( issuedBy-oid NAME 'issuedBy' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( issueInfo-oid NAME 'issueInfo' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( issuerName-oid NAME 'issuerName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( keySize-oid NAME 'keySize' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( clientId-oid NAME 'clientId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dataType-oid NAME 'dataType' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( status-oid NAME 'status' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( keyState-oid NAME 'keyState' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( metaInfo-oid NAME 'metaInfo' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( nextUpdate-oid NAME 'nextUpdate' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( notAfter-oid NAME 'notAfter' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( notBefore-oid NAME 'notBefore' DESC 'CMS defined attribute'SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( ownerName-oid NAME 'ownerName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( password-oid NAME 'password' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( p12Expiration-oid NAME 'p12Expiration' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( proofOfArchival-oid NAME 'proofOfArchival' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( publicKeyData-oid NAME 'publicKeyData' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( publicKeyFormat-oid NAME 'publicKeyFormat' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( privateKeyData-oid NAME 'privateKeyData' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestId-oid NAME 'requestId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestInfo-oid NAME 'requestInfo' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestState-oid NAME 'requestState' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestResult-oid NAME 'requestResult' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestOwner-oid NAME 'requestOwner' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestAgentGroup-oid NAME 'requestAgentGroup' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestSourceId-oid NAME 'requestSourceId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestType-oid NAME 'requestType' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestFlag-oid NAME 'requestFlag' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( requestError-oid NAME 'requestError' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( resourceACLS-oid NAME 'resourceACLS' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( revInfo-oid NAME 'revInfo' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( revokedBy-oid NAME 'revokedBy' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( revokedOn-oid NAME 'revokedOn' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( serialno-oid NAME 'serialno' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( nextRange-oid NAME 'nextRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( publishingStatus-oid NAME 'publishingStatus' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( beginRange-oid NAME 'beginRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( endRange-oid NAME 'endRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( subjectName-oid NAME 'subjectName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( sessionContext-oid NAME 'sessionContext' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( thisUpdate-oid NAME 'thisUpdate' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( transId-oid NAME 'transId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( transStatus-oid NAME 'transStatus' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( transName-oid NAME 'transName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( transOps-oid NAME 'transOps' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( userDN-oid NAME 'userDN' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( userMessages-oid NAME 'userMessages' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( version-oid NAME 'version' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( Clone-oid NAME 'Clone' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( DomainManager-oid NAME 'DomainManager' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SecurePort-oid NAME 'SecurePort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SecureAgentPort-oid NAME 'SecureAgentPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SecureAdminPort-oid NAME 'SecureAdminPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SecureEEClientAuthPort-oid NAME 'SecureEEClientAuthPort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( UnSecurePort-oid NAME 'UnSecurePort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( SubsystemName-oid NAME 'SubsystemName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( cmsUserGroup-oid NAME 'cmsUserGroup' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( CertACLS-oid NAME 'CertACLS' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY resourceACLS X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( repository-oid NAME 'repository' DESC 'CMS defined class' SUP top STRUCTURAL MUST ou MAY ( serialno $ description $ nextRange $ publishingStatus ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( request-oid NAME 'request' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( requestId $ dateOfCreate $ dateOfModify $ requestState $ requestResult $ requestOwner $ requestAgentGroup $ requestSourceId $ requestType $ requestFlag $ requestError $ userMessages $ adminMessages ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( transaction-oid NAME 'transaction' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( transId $ description $ transName $ transStatus $ transOps ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( crlIssuingPointRecord-oid NAME 'crlIssuingPointRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( dateOfCreate $ dateOfModify $ crlNumber $ crlSize $ thisUpdate $ nextUpdate $ deltaNumber $ deltaSize $ firstUnsaved $ certificateRevocationList $ deltaRevocationList $ crlCache $ revokedCerts $ unrevokedCerts $ expiredCerts $ cACertificate ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( certificateRecord-oid NAME 'certificateRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( serialno $ dateOfCreate $ dateOfModify $ certStatus $ autoRenew $ issueInfo $ metaInfo $ revInfo $ version $ duration $ notAfter $ notBefore $ algorithmId $ subjectName $ signingAlgorithmId $ userCertificate $ issuedBy $ revokedBy $ revokedOn $ extension $ publicKeyData $ issuerName ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( userDetails-oid NAME 'userDetails' DESC 'CMS defined class' SUP top STRUCTURAL MUST userDN MAY ( dateOfCreate $ dateOfModify $ password $ p12Expiration ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( keyRecord-oid NAME 'keyRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( serialno $ dateOfCreate $ dateOfModify $ keyState $ privateKeyData $ ownerName $ keySize $ metaInfo $ dateOfArchival $ dateOfRecovery $ algorithm $ publicKeyFormat $ publicKeyData $ archivedBy $ clientId $ dataType $ status ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( pkiSecurityDomain-oid NAME 'pkiSecurityDomain' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( ou $ name ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( pkiSecurityGroup-oid NAME 'pkiSecurityGroup' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( pkiSubsystem-oid NAME 'pkiSubsystem' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ Host $ SecurePort $ SubsystemName $ Clone ) MAY ( DomainManager $ SecureAgentPort $ SecureAdminPort $SecureEEClientAuthPort $ UnSecurePort ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( pkiRange-oid NAME 'pkiRange' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ beginRange $ endRange $ Host $ SecurePort ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( securityDomainSessionEntry-oid NAME 'securityDomainSessionEntry' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ host $ uid $ cmsUserGroup $ dateOfCreate ) X-ORIGIN 'user defined' )
diff --git a/base/tks/shared/conf/server-minimal.xml b/base/tks/shared/conf/server-minimal.xml
new file mode 100644
index 000000000..0df50b528
--- /dev/null
+++ b/base/tks/shared/conf/server-minimal.xml
@@ -0,0 +1,29 @@
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2006 Red Hat, Inc.
+ All rights reserved.
+ END COPYRIGHT BLOCK -->
+<Server port="8005" shutdown="SHUTDOWN">
+
+ <GlobalNamingResources>
+ <!-- Used by Manager webapp -->
+ <Resource name="UserDatabase" auth="Container"
+ type="org.apache.catalina.UserDatabase"
+ description="User database that can be updated and saved"
+ factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
+ pathname="conf/tomcat-users.xml" />
+ </GlobalNamingResources>
+
+ <Service name="Catalina">
+ <Connector port="8080" />
+
+ <!-- This is here for compatibility only, not required -->
+ <Connector port="8009" protocol="AJP/1.3" />
+
+ <Engine name="Catalina" defaultHost="localhost">
+ <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+ resourceName="UserDatabase" />
+ <Host name="localhost" appBase="webapps" />
+ </Engine>
+
+ </Service>
+</Server>
diff --git a/base/tks/shared/conf/server.xml b/base/tks/shared/conf/server.xml
new file mode 100644
index 000000000..6217ce1d9
--- /dev/null
+++ b/base/tks/shared/conf/server.xml
@@ -0,0 +1,258 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2006-2010 Red Hat, Inc.
+ All rights reserved.
+ Modifications: configuration parameters
+ END COPYRIGHT BLOCK -->
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- Note: A "Server" is not itself a "Container", so you may not
+ define subcomponents such as "Valves" at this level.
+ Documentation at /docs/config/server.html
+ -->
+
+<!-- DO NOT REMOVE - Begin PKI Status Definitions -->
+<!--
+Unsecure Port = http://[PKI_MACHINE_NAME]:[PKI_UNSECURE_PORT]/[PKI_SUBSYSTEM_TYPE]/ee/[PKI_SUBSYSTEM_TYPE]
+Secure Agent Port = https://[PKI_MACHINE_NAME]:[PKI_AGENT_SECURE_PORT]/[PKI_SUBSYSTEM_TYPE]/agent/[PKI_SUBSYSTEM_TYPE]
+Secure EE Port = https://[PKI_MACHINE_NAME]:[PKI_EE_SECURE_PORT]/[PKI_SUBSYSTEM_TYPE]/ee/[PKI_SUBSYSTEM_TYPE]
+Secure Admin Port = https://[PKI_MACHINE_NAME]:[PKI_ADMIN_SECURE_PORT]/[PKI_SUBSYSTEM_TYPE]/services
+PKI Console Port = pkiconsole https://[PKI_MACHINE_NAME]:[PKI_ADMIN_SECURE_PORT]/[PKI_SUBSYSTEM_TYPE]
+Tomcat Port = [TOMCAT_SERVER_PORT] (for shutdown)
+-->
+<!-- DO NOT REMOVE - End PKI Status Definitions -->
+
+<Server port="[TOMCAT_SERVER_PORT]" shutdown="SHUTDOWN">
+
+ <!--APR library loader. Documentation at /docs/apr.html -->
+ <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
+ <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
+ <Listener className="org.apache.catalina.core.JasperListener" />
+ <!-- JMX Support for the Tomcat server. Documentation at /docs/non-existent.html -->
+ <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
+ <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
+
+ <!-- Global JNDI resources
+ Documentation at /docs/jndi-resources-howto.html
+ -->
+ <GlobalNamingResources>
+ <!-- Editable user database that can also be used by
+ UserDatabaseRealm to authenticate users
+ -->
+ <Resource name="UserDatabase" auth="Container"
+ type="org.apache.catalina.UserDatabase"
+ description="User database that can be updated and saved"
+ factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
+ pathname="conf/tomcat-users.xml" />
+ </GlobalNamingResources>
+
+ <!-- A "Service" is a collection of one or more "Connectors" that share
+ a single "Container" Note: A "Service" is not itself a "Container",
+ so you may not define subcomponents such as "Valves" at this level.
+ Documentation at /docs/config/service.html
+ -->
+ <Service name="Catalina">
+
+ <!--The connectors can use a shared executor, you can define one or more named thread pools-->
+ <!--
+ <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
+ maxThreads="150" minSpareThreads="4"/>
+ -->
+
+
+ <!-- A "Connector" represents an endpoint by which requests are received
+ and responses are returned. Documentation at :
+ Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
+ Java AJP Connector: /docs/config/ajp.html
+ APR (HTTP/AJP) Connector: /docs/apr.html
+ Define a non-SSL HTTP/1.1 Connector on port 8080
+ -->
+
+ [PKI_UNSECURE_PORT_SERVER_COMMENT]
+ <Connector name="[PKI_UNSECURE_PORT_CONNECTOR_NAME]" port="[PKI_UNSECURE_PORT]" protocol="HTTP/1.1" redirectPort="8443"
+ maxHttpHeaderSize="8192"
+ acceptCount="100" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+ enableLookups="false" connectionTimeout="20000" disableUploadTimeout="true"
+ />
+
+ <!-- Define a SSL HTTP/1.1 Connector on port 8443 -->
+ [PKI_SECURE_PORT_SERVER_COMMENT]
+ <!-- DO NOT REMOVE - Begin define PKI secure port
+ NOTE: The OCSP settings take effect globally, so it should only be set once.
+
+ In setup where SSL clientAuth="true", OCSP can be turned on by
+ setting enableOCSP to true like the following:
+ enableOCSP="true"
+ along with changes to related settings, especially:
+ ocspResponderURL=<see example in connector definition below>
+ ocspResponderCertNickname=<see example in connector definition below>
+ Here are the definition to all the OCSP-related settings:
+ enableOCSP - turns on/off the ocsp check
+ ocspResponderURL - sets the url where the ocsp requests are sent
+ ocspResponderCertNickname - sets the nickname of the cert that is
+ either CA's signing certificate or the OCSP server's signing
+ certificate.
+ The CA's signing certificate should already be in the db, in
+ case of the same security domain.
+ In case of an ocsp signing certificate, one must import the cert
+ into the subsystem's nss db and set trust. e.g.:
+ certutil -d . -A -n "ocspSigningCert cert-pki-ca" -t "C,," -a -i ocspCert.b64
+ ocspCacheSize - sets max cache entries
+ ocspMinCacheEntryDuration - sets minimum seconds to next fetch attempt
+ ocspMaxCacheEntryDuration - sets maximum seconds to next fetch attempt
+ ocspTimeout -sets OCSP timeout in seconds
+ -->
+ <Connector name="[PKI_SECURE_PORT_CONNECTOR_NAME]" port="[PKI_SECURE_PORT]" protocol="HTTP/1.1" SSLEnabled="true" sslProtocol="SSL" scheme="https" secure="true"
+ maxHttpHeaderSize="8192"
+ acceptCount="100" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+ enableLookups="false" disableUploadTimeout="true"
+ SSLImplementation="org.apache.tomcat.util.net.jss.JSSImplementation"
+ enableOCSP="false"
+ ocspResponderURL="http://[PKI_MACHINE_NAME]:9080/ca/ocsp"
+ ocspResponderCertNickname="ocspSigningCert cert-pki-ca"
+ ocspCacheSize="1000"
+ ocspMinCacheEntryDuration="60"
+ ocspMaxCacheEntryDuration="120"
+ ocspTimeout="10"
+ strictCiphers="false"
+ clientAuth="[PKI_AGENT_CLIENTAUTH]"
+ sslOptions="[TOMCAT_SSL_OPTIONS]"
+ ssl2Ciphers="[TOMCAT_SSL2_CIPHERS]"
+ ssl3Ciphers="[TOMCAT_SSL3_CIPHERS]"
+ tlsCiphers="[TOMCAT_TLS_CIPHERS]"
+ serverCertNickFile="[PKI_INSTANCE_PATH]/conf/serverCertNick.conf"
+ passwordFile="[PKI_INSTANCE_PATH]/conf/password.conf"
+ passwordClass="org.apache.tomcat.util.net.jss.PlainPasswordFile"
+ certdbDir="[PKI_INSTANCE_PATH]/alias"
+ />
+ <!-- DO NOT REMOVE - End define PKI secure port -->
+
+ [PKI_OPEN_SEPARATE_PORTS_SERVER_COMMENT][PKI_ADMIN_SECURE_PORT_SERVER_COMMENT]
+ <Connector name="[PKI_ADMIN_SECURE_PORT_CONNECTOR_NAME]" port="[PKI_ADMIN_SECURE_PORT]" SSLEnabled="true" sslProtocol="SSL" scheme="https" secure="true"
+ maxHttpHeaderSize="8192"
+ acceptCount="100" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+ enableLookups="false" disableUploadTimeout="true"
+ SSLImplementation="org.apache.tomcat.util.net.jss.JSSImplementation"
+ strictCiphers="false"
+ clientAuth="false"
+ sslOptions="[TOMCAT_SSL_OPTIONS]"
+ ssl2Ciphers="[TOMCAT_SSL2_CIPHERS]"
+ ssl3Ciphers="[TOMCAT_SSL3_CIPHERS]"
+ tlsCiphers="[TOMCAT_TLS_CIPHERS]"
+ serverCertNickFile="[PKI_INSTANCE_PATH]/conf/serverCertNick.conf"
+ passwordFile="[PKI_INSTANCE_PATH]/conf/password.conf"
+ passwordClass="org.apache.tomcat.util.net.jss.PlainPasswordFile"
+ certdbDir="[PKI_INSTANCE_PATH]/alias"/>
+ [PKI_CLOSE_SEPARATE_PORTS_SERVER_COMMENT]
+
+ [PKI_OPEN_SEPARATE_PORTS_SERVER_COMMENT][PKI_EE_SECURE_PORT_SERVER_COMMENT]
+ <Connector name="[PKI_EE_SECURE_PORT_CONNECTOR_NAME]" port="[PKI_EE_SECURE_PORT]" SSLEnabled="true" sslProtocol="SSL" scheme="https" secure="true"
+ maxHttpHeaderSize="8192"
+ acceptCount="100" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+ enableLookups="false" disableUploadTimeout="true"
+ SSLImplementation="org.apache.tomcat.util.net.jss.JSSImplementation"
+ strictCiphers="false"
+ clientAuth="false"
+ sslOptions="[TOMCAT_SSL_OPTIONS]"
+ ssl2Ciphers="[TOMCAT_SSL2_CIPHERS]"
+ ssl3Ciphers="[TOMCAT_SSL3_CIPHERS]"
+ tlsCiphers="[TOMCAT_TLS_CIPHERS]"
+ serverCertNickFile="[PKI_INSTANCE_PATH]/conf/serverCertNick.conf"
+ passwordFile="[PKI_INSTANCE_PATH]/conf/password.conf"
+ passwordClass="org.apache.tomcat.util.net.jss.PlainPasswordFile"
+ certdbDir="[PKI_INSTANCE_PATH]/alias"/>
+ [PKI_CLOSE_SEPARATE_PORTS_SERVER_COMMENT]
+
+ <!-- A "Connector" using the shared thread pool-->
+ <!--
+ <Connector executor="tomcatThreadPool"
+ port="8080" protocol="HTTP/1.1"
+ connectionTimeout="20000"
+ redirectPort="8443" />
+ -->
+ <!-- Define a SSL HTTP/1.1 Connector on port 8443
+ This connector uses the JSSE configuration, when using APR, the
+ connector should be using the OpenSSL style configuration
+ described in the APR documentation -->
+ <!--
+ <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
+ maxThreads="150" scheme="https" secure="true"
+ clientAuth="false" sslProtocol="TLS" />
+ -->
+
+ <!-- Define an AJP 1.3 Connector on port [PKI_AJP_PORT] -->
+[PKI_OPEN_AJP_PORT_COMMENT]
+ <Connector port="[PKI_AJP_PORT]" protocol="AJP/1.3" redirectPort="[PKI_AJP_REDIRECT_PORT]" />
+[PKI_CLOSE_AJP_PORT_COMMENT]
+
+
+ <!-- An Engine represents the entry point (within Catalina) that processes
+ every request. The Engine implementation for Tomcat stand alone
+ analyzes the HTTP headers included with the request, and passes them
+ on to the appropriate Host (virtual host).
+ Documentation at /docs/config/engine.html -->
+
+ <!-- You should set jvmRoute to support load-balancing via AJP ie :
+ <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
+ -->
+ <Engine name="Catalina" defaultHost="localhost">
+
+ <!--For clustering, please take a look at documentation at:
+ /docs/cluster-howto.html (simple how to)
+ /docs/config/cluster.html (reference documentation) -->
+ <!--
+ <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
+ -->
+
+ <!-- The request dumper valve dumps useful debugging information about
+ the request and response data received and sent by Tomcat.
+ Documentation at: /docs/config/valve.html -->
+ <!--
+ <Valve className="org.apache.catalina.valves.RequestDumperValve"/>
+ -->
+
+ <!-- This Realm uses the UserDatabase configured in the global JNDI
+ resources under the key "UserDatabase". Any edits
+ that are performed against this UserDatabase are immediately
+ available for use by the Realm. -->
+ <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+ resourceName="UserDatabase"/>
+
+ <!-- Define the default virtual host
+ Note: XML Schema validation will not work with Xerces 2.2.
+ -->
+ <Host name="localhost" appBase="webapps"
+ unpackWARs="true" autoDeploy="false"
+ xmlValidation="false" xmlNamespaceAware="false">
+
+ <!-- SingleSignOn valve, share authentication between web applications
+ Documentation at: /docs/config/valve.html -->
+ <!--
+ <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
+ -->
+
+ <!-- Access log processes all example.
+ Documentation at: /docs/config/valve.html -->
+ <!--
+ <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
+ prefix="localhost_access_log." suffix=".txt" pattern="common" resolveHosts="false"/>
+ -->
+
+ </Host>
+ </Engine>
+ </Service>
+</Server>
diff --git a/base/tks/shared/conf/serverCertNick.conf b/base/tks/shared/conf/serverCertNick.conf
new file mode 100644
index 000000000..2233ada52
--- /dev/null
+++ b/base/tks/shared/conf/serverCertNick.conf
@@ -0,0 +1,6 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+Server-Cert cert-[PKI_INSTANCE_ID]
diff --git a/base/tks/shared/conf/shm.manifest b/base/tks/shared/conf/shm.manifest
new file mode 100644
index 000000000..0505c085b
--- /dev/null
+++ b/base/tks/shared/conf/shm.manifest
@@ -0,0 +1,2 @@
+Main-Class: org.apache.jk.common.Shm
+Class-Path: tomcat-jk2.jar commons-logging.jar tomcat-util.jar log4j.jar log4j-core.jar
diff --git a/base/tks/shared/conf/tomcat-jk2.manifest b/base/tks/shared/conf/tomcat-jk2.manifest
new file mode 100644
index 000000000..acfef4a90
--- /dev/null
+++ b/base/tks/shared/conf/tomcat-jk2.manifest
@@ -0,0 +1,7 @@
+Manifest-version: 1.0
+Extension-Name: org.apache.jk
+Specification-Vendor: Apache Software Foundation
+Specification-Version: 2.0
+Implementation-Vendor-Id: org.apache
+Implementation-Vendor: Apache Software Foundation
+Implementation-Version: 2.1
diff --git a/base/tks/shared/conf/tomcat-users.xml b/base/tks/shared/conf/tomcat-users.xml
new file mode 100644
index 000000000..daa9260cc
--- /dev/null
+++ b/base/tks/shared/conf/tomcat-users.xml
@@ -0,0 +1,45 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2006-2010 Red Hat, Inc.
+ All rights reserved.
+ Modifications: configuration parameters
+ END COPYRIGHT BLOCK -->
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+ <role rolename="tomcat"/>
+ <role rolename="role1"/>
+ <user username="tomcat" password="tomcat" roles="tomcat"/>
+ <user username="both" password="tomcat" roles="tomcat,role1"/>
+ <user username="role1" password="tomcat" roles="role1"/>
+-->
+
+<!-- The host manager webapp is restricted to users with role "admin" -->
+<!--<user name="tomcat" password="password" roles="admin" />-->
+<!-- The manager webapp is restricted to users with role "manager" -->
+<!--<user name="tomcat" password="password" roles="manager" />-->
+<tomcat-users>
+ <role rolename="pkiuser"/>
+ <role rolename="tomcat"/>
+ <role rolename="manager"/>
+ <role rolename="admin"/>
+
+ <user username="pkiuser" password="pkiuser" roles="pkiuser"/>
+ <user username="tomcat" password="tomcat" roles="tomcat"/>
+ <user username="admin" password="netscape" roles="admin,manager"/>
+</tomcat-users>
diff --git a/base/tks/shared/conf/tomcat6.conf b/base/tks/shared/conf/tomcat6.conf
new file mode 100644
index 000000000..2d7def5ec
--- /dev/null
+++ b/base/tks/shared/conf/tomcat6.conf
@@ -0,0 +1,58 @@
+# Service-specific configuration file for tomcat6. This will be sourced by
+# the SysV init script after the global configuration file
+# /etc/tomcat6/tomcat6.conf, thus allowing values to be overridden in
+# a per-service manner.
+#
+# NEVER change the init script itself. To change values for all services make
+# your changes in /etc/tomcat6/tomcat6.conf
+#
+# To change values for a specific service make your edits here.
+# To create a new service create a link from /etc/init.d/<your new service> to
+# /etc/init.d/tomcat6 (do not copy the init script) and make a copy of the
+# /etc/sysconfig/tomcat6 file to /etc/sysconfig/<your new service> and change
+# the property values so the two services won't conflict. Register the new
+# service in the system as usual (see chkconfig and similars).
+#
+
+# Where your java installation lives
+#JAVA_HOME="/usr/lib/jvm/java"
+
+# Where your tomcat installation lives
+CATALINA_BASE="[PKI_INSTANCE_PATH]"
+#CATALINA_HOME="/usr/share/tomcat6"
+#JASPER_HOME="/usr/share/tomcat6"
+#CATALINA_TMPDIR="/var/cache/tomcat6/temp"
+
+# You can pass some parameters to java here if you wish to
+#JAVA_OPTS="-Xminf0.1 -Xmaxf0.3"
+
+# Use JAVA_OPTS to set java.library.path for libtcnative.so
+#JAVA_OPTS="-Djava.library.path=/usr/lib64"
+
+# What user should run tomcat
+TOMCAT_USER="[PKI_USER]"
+
+# You can change your tomcat locale here
+#LANG="en_US"
+
+# Run tomcat under the Java Security Manager
+#SECURITY_MANAGER="false"
+
+# Time to wait in seconds, before killing process
+#SHUTDOWN_WAIT="30"
+
+# Whether to annoy the user with "attempting to shut down" messages or not
+#SHUTDOWN_VERBOSE="false"
+
+# Set the TOMCAT_PID location
+CATALINA_PID="[TOMCAT_PIDFILE]"
+
+# Set the tomcat log file
+TOMCAT_LOG="[TOMCAT_LOG_DIR]/tomcat-initd.log"
+
+# Connector port is 8080 for this tomcat6 instance
+#CONNECTOR_PORT="8080"
+
+# If you wish to further customize your tomcat environment,
+# put your own definitions here
+# (i.e. LD_LIBRARY_PATH for some jdbc drivers)
diff --git a/base/tks/shared/conf/uriworkermap.properties b/base/tks/shared/conf/uriworkermap.properties
new file mode 100644
index 000000000..c89dd82a6
--- /dev/null
+++ b/base/tks/shared/conf/uriworkermap.properties
@@ -0,0 +1,18 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+# uriworkermap.properties - IIS
+#
+# This file provides sample mappings for example ajp13w
+# worker defined in workermap.properties.minimal
+# The general sytax for this file is:
+# [URL]=[Worker name]
+
+/servlet-examples/*=ajp13w
+
+# Optionally filter out all .jpeg files inside that context
+# For no mapping the url has to start with exclamation (!)
+
+!/servlet-examples/*.jpeg=ajp13w
diff --git a/base/tks/shared/conf/web.xml b/base/tks/shared/conf/web.xml
new file mode 100644
index 000000000..860a9c4af
--- /dev/null
+++ b/base/tks/shared/conf/web.xml
@@ -0,0 +1,993 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2006 Red Hat, Inc.
+ All rights reserved.
+ END COPYRIGHT BLOCK -->
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+ version="2.4">
+
+ <!-- ======================== Introduction ============================== -->
+ <!-- This document defines default values for *all* web applications -->
+ <!-- loaded into this instance of Tomcat. As each application is -->
+ <!-- deployed, this file is processed, followed by the -->
+ <!-- "/WEB-INF/web.xml" deployment descriptor from your own -->
+ <!-- applications. -->
+ <!-- -->
+ <!-- WARNING: Do not configure application-specific resources here! -->
+ <!-- They should go in the "/WEB-INF/web.xml" file in your application. -->
+
+
+ <!-- ================== Built In Servlet Definitions ==================== -->
+
+
+ <!-- The default servlet for all web applications, that serves static -->
+ <!-- resources. It processes all requests that are not mapped to other -->
+ <!-- servlets with servlet mappings (defined either here or in your own -->
+ <!-- web.xml file. This servlet supports the following initialization -->
+ <!-- parameters (default values are in square brackets): -->
+ <!-- -->
+ <!-- debug Debugging detail level for messages logged -->
+ <!-- by this servlet. [0] -->
+ <!-- -->
+ <!-- fileEncoding Encoding to be used to read static resources -->
+ <!-- [platform default] -->
+ <!-- -->
+ <!-- input Input buffer size (in bytes) when reading -->
+ <!-- resources to be served. [2048] -->
+ <!-- -->
+ <!-- listings Should directory listings be produced if there -->
+ <!-- is no welcome file in this directory? [true] -->
+ <!-- -->
+ <!-- output Output buffer size (in bytes) when writing -->
+ <!-- resources to be served. [2048] -->
+ <!-- -->
+ <!-- readonly Is this context "read only", so HTTP -->
+ <!-- commands like PUT and DELETE are -->
+ <!-- rejected? [true] -->
+ <!-- -->
+ <!-- readmeFile File name to display with the directory -->
+ <!-- contents. [null] -->
+ <!-- -->
+ <!-- For directory listing customization. Checks localXsltFile, then -->
+ <!-- globalXsltFile, then defaults to original behavior. -->
+ <!-- -->
+ <!-- localXsltFile Make directory listings an XML doc and -->
+ <!-- pass the result to this style sheet residing -->
+ <!-- in that directory. This overrides -->
+ <!-- globalXsltFile[null] -->
+ <!-- -->
+ <!-- globalXsltFile Site wide configuration version of -->
+ <!-- localXsltFile This argument is expected -->
+ <!-- to be a physical file. [null] -->
+ <!-- -->
+ <!-- -->
+
+ <servlet>
+ <servlet-name>default</servlet-name>
+ <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
+ <init-param>
+ <param-name>debug</param-name>
+ <param-value>0</param-value>
+ </init-param>
+ <init-param>
+ <param-name>listings</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+
+ <!-- The "invoker" servlet, which executes anonymous servlet classes -->
+ <!-- that have not been defined in a web.xml file. Traditionally, this -->
+ <!-- servlet is mapped to the URL pattern "/servlet/*", but you can map -->
+ <!-- it to other patterns as well. The extra path info portion of such a -->
+ <!-- request must be the fully qualified class name of a Java class that -->
+ <!-- implements Servlet (or extends HttpServlet), or the servlet name -->
+ <!-- of an existing servlet definition. This servlet supports the -->
+ <!-- following initialization parameters (default values are in square -->
+ <!-- brackets): -->
+ <!-- -->
+ <!-- debug Debugging detail level for messages logged -->
+ <!-- by this servlet. [0] -->
+
+<!--
+ <servlet>
+ <servlet-name>invoker</servlet-name>
+ <servlet-class>
+ org.apache.catalina.servlets.InvokerServlet
+ </servlet-class>
+ <init-param>
+ <param-name>debug</param-name>
+ <param-value>0</param-value>
+ </init-param>
+ <load-on-startup>2</load-on-startup>
+ </servlet>
+-->
+
+
+ <!-- The JSP page compiler and execution servlet, which is the mechanism -->
+ <!-- used by Tomcat to support JSP pages. Traditionally, this servlet -->
+ <!-- is mapped to the URL pattern "*.jsp". This servlet supports the -->
+ <!-- following initialization parameters (default values are in square -->
+ <!-- brackets): -->
+ <!-- -->
+ <!-- checkInterval If development is false and checkInterval is -->
+ <!-- greater than zero, background compilations are -->
+ <!-- enabled. checkInterval is the time in seconds -->
+ <!-- between checks to see if a JSP page needs to -->
+ <!-- be recompiled. [0] -->
+ <!-- -->
+ <!-- modificationTestInterval -->
+ <!-- Causes a JSP (and its dependent files) to not -->
+ <!-- be checked for modification during the -->
+ <!-- specified time interval (in seconds) from the -->
+ <!-- last time the JSP was checked for -->
+ <!-- modification. A value of 0 will cause the JSP -->
+ <!-- to be checked on every access. -->
+ <!-- Used in development mode only. [4] -->
+ <!-- -->
+ <!-- compiler Which compiler Ant should use to compile JSP -->
+ <!-- pages. See the Ant documentation for more -->
+ <!-- information. [javac] -->
+ <!-- -->
+ <!-- classdebuginfo Should the class file be compiled with -->
+ <!-- debugging information? [true] -->
+ <!-- -->
+ <!-- classpath What class path should I use while compiling -->
+ <!-- generated servlets? [Created dynamically -->
+ <!-- based on the current web application] -->
+ <!-- -->
+ <!-- development Is Jasper used in development mode? If true, -->
+ <!-- the frequency at which JSPs are checked for -->
+ <!-- modification may be specified via the -->
+ <!-- modificationTestInterval parameter. [true] -->
+ <!-- -->
+ <!-- enablePooling Determines whether tag handler pooling is -->
+ <!-- enabled [true] -->
+ <!-- -->
+ <!-- fork Tell Ant to fork compiles of JSP pages so that -->
+ <!-- a separate JVM is used for JSP page compiles -->
+ <!-- from the one Tomcat is running in. [true] -->
+ <!-- -->
+ <!-- ieClassId The class-id value to be sent to Internet -->
+ <!-- Explorer when using <jsp:plugin> tags. -->
+ <!-- [clsid:8AD9C840-044E-11D1-B3E9-00805F499D93] -->
+ <!-- -->
+ <!-- javaEncoding Java file encoding to use for generating java -->
+ <!-- source files. [UTF8] -->
+ <!-- -->
+ <!-- keepgenerated Should we keep the generated Java source code -->
+ <!-- for each page instead of deleting it? [true] -->
+ <!-- -->
+ <!-- mappedfile Should we generate static content with one -->
+ <!-- print statement per input line, to ease -->
+ <!-- debugging? [true] -->
+ <!-- -->
+ <!-- trimSpaces Should white spaces in template text between -->
+ <!-- actions or directives be trimmed? [false] -->
+ <!-- -->
+ <!-- suppressSmap Should the generation of SMAP info for JSR45 -->
+ <!-- debugging be suppressed? [false] -->
+ <!-- -->
+ <!-- dumpSmap Should the SMAP info for JSR45 debugging be -->
+ <!-- dumped to a file? [false] -->
+ <!-- False if suppressSmap is true -->
+ <!-- -->
+ <!-- genStrAsCharArray Should text strings be generated as char -->
+ <!-- arrays, to improve performance in some cases? -->
+ <!-- [false] -->
+ <!-- -->
+ <!-- errorOnUseBeanInvalidClassAttribute -->
+ <!-- Should Jasper issue an error when the value of -->
+ <!-- the class attribute in an useBean action is -->
+ <!-- not a valid bean class? [true] -->
+ <!-- -->
+ <!-- scratchdir What scratch directory should we use when -->
+ <!-- compiling JSP pages? [default work directory -->
+ <!-- for the current web application] -->
+ <!-- -->
+ <!-- xpoweredBy Determines whether X-Powered-By response -->
+ <!-- header is added by generated servlet [false] -->
+ <!-- -->
+ <!-- If you wish to use Jikes to compile JSP pages: -->
+ <!-- Please see the "Using Jikes" section of the Jasper-HowTo -->
+ <!-- page in the Tomcat documentation. -->
+
+ <servlet>
+ <servlet-name>jsp</servlet-name>
+ <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
+ <init-param>
+ <param-name>fork</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ <init-param>
+ <param-name>xpoweredBy</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ <load-on-startup>3</load-on-startup>
+ </servlet>
+
+
+ <!-- Server Side Includes processing servlet, which processes SSI -->
+ <!-- directives in HTML pages consistent with similar support in web -->
+ <!-- servers like Apache. Traditionally, this servlet is mapped to the -->
+ <!-- URL pattern "*.shtml". This servlet supports the following -->
+ <!-- initialization parameters (default values are in square brackets): -->
+ <!-- -->
+ <!-- buffered Should output from this servlet be buffered? -->
+ <!-- (0=false, 1=true) [0] -->
+ <!-- -->
+ <!-- debug Debugging detail level for messages logged -->
+ <!-- by this servlet. [0] -->
+ <!-- -->
+ <!-- expires The number of seconds before a page with SSI -->
+ <!-- directives will expire. [No default] -->
+ <!-- -->
+ <!-- isVirtualWebappRelative -->
+ <!-- Should "virtual" paths be interpreted as -->
+ <!-- relative to the context root, instead of -->
+ <!-- the server root? (0=false, 1=true) [0] -->
+ <!-- -->
+ <!-- -->
+ <!-- IMPORTANT: To use the SSI servlet, you also need to rename the -->
+ <!-- $CATALINA_HOME/server/lib/servlets-ssi.renametojar file -->
+ <!-- to $CATALINA_HOME/server/lib/servlets-ssi.jar -->
+
+<!--
+ <servlet>
+ <servlet-name>ssi</servlet-name>
+ <servlet-class>
+ org.apache.catalina.ssi.SSIServlet
+ </servlet-class>
+ <init-param>
+ <param-name>buffered</param-name>
+ <param-value>1</param-value>
+ </init-param>
+ <init-param>
+ <param-name>debug</param-name>
+ <param-value>0</param-value>
+ </init-param>
+ <init-param>
+ <param-name>expires</param-name>
+ <param-value>666</param-value>
+ </init-param>
+ <init-param>
+ <param-name>isVirtualWebappRelative</param-name>
+ <param-value>0</param-value>
+ </init-param>
+ <load-on-startup>4</load-on-startup>
+ </servlet>
+-->
+
+
+ <!-- Common Gateway Includes (CGI) processing servlet, which supports -->
+ <!-- execution of external applications that conform to the CGI spec -->
+ <!-- requirements. Typically, this servlet is mapped to the URL pattern -->
+ <!-- "/cgi-bin/*", which means that any CGI applications that are -->
+ <!-- executed must be present within the web application. This servlet -->
+ <!-- supports the following initialization parameters (default values -->
+ <!-- are in square brackets): -->
+ <!-- -->
+ <!-- cgiPathPrefix The CGI search path will start at -->
+ <!-- webAppRootDir + File.separator + this prefix. -->
+ <!-- [WEB-INF/cgi] -->
+ <!-- -->
+ <!-- debug Debugging detail level for messages logged -->
+ <!-- by this servlet. [0] -->
+ <!-- -->
+ <!-- executable Name of the exectuable used to run the -->
+ <!-- script. [perl] -->
+ <!-- -->
+ <!-- parameterEncoding Name of parameter encoding to be used with -->
+ <!-- CGI servlet. -->
+ <!-- [System.getProperty("file.encoding","UTF-8")] -->
+ <!-- -->
+ <!-- passShellEnvironment Should the shell environment variables (if -->
+ <!-- any) be passed to the CGI script? [false] -->
+ <!-- -->
+ <!-- IMPORTANT: To use the CGI servlet, you also need to rename the -->
+ <!-- $CATALINA_HOME/server/lib/servlets-cgi.renametojar file -->
+ <!-- to $CATALINA_HOME/server/lib/servlets-cgi.jar -->
+
+<!--
+ <servlet>
+ <servlet-name>cgi</servlet-name>
+ <servlet-class>org.apache.catalina.servlets.CGIServlet</servlet-class>
+ <init-param>
+ <param-name>debug</param-name>
+ <param-value>6</param-value>
+ </init-param>
+ <init-param>
+ <param-name>cgiPathPrefix</param-name>
+ <param-value>WEB-INF/cgi</param-value>
+ </init-param>
+ <load-on-startup>5</load-on-startup>
+ </servlet>
+-->
+
+
+ <!-- ================ Built In Servlet Mappings ========================= -->
+
+
+ <!-- The servlet mappings for the built in servlets defined above. Note -->
+ <!-- that, by default, the CGI and SSI servlets are *not* mapped. You -->
+ <!-- must uncomment these mappings (or add them to your application's own -->
+ <!-- web.xml deployment descriptor) to enable these services -->
+
+ <!-- The mapping for the default servlet -->
+ <servlet-mapping>
+ <servlet-name>default</servlet-name>
+ <url-pattern>/</url-pattern>
+ </servlet-mapping>
+
+ <!-- The mapping for the invoker servlet -->
+<!--
+ <servlet-mapping>
+ <servlet-name>invoker</servlet-name>
+ <url-pattern>/servlet/*</url-pattern>
+ </servlet-mapping>
+-->
+
+ <!-- The mapping for the JSP servlet -->
+ <servlet-mapping>
+ <servlet-name>jsp</servlet-name>
+ <url-pattern>*.jsp</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>jsp</servlet-name>
+ <url-pattern>*.jspx</url-pattern>
+ </servlet-mapping>
+
+ <!-- The mapping for the SSI servlet -->
+<!--
+ <servlet-mapping>
+ <servlet-name>ssi</servlet-name>
+ <url-pattern>*.shtml</url-pattern>
+ </servlet-mapping>
+-->
+
+ <!-- The mapping for the CGI Gateway servlet -->
+
+<!--
+ <servlet-mapping>
+ <servlet-name>cgi</servlet-name>
+ <url-pattern>/cgi-bin/*</url-pattern>
+ </servlet-mapping>
+-->
+
+
+ <!-- ==================== Default Session Configuration ================= -->
+ <!-- You can set the default session timeout (in minutes) for all newly -->
+ <!-- created sessions by modifying the value below. -->
+
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+
+
+ <!-- ===================== Default MIME Type Mappings =================== -->
+ <!-- When serving static resources, Tomcat will automatically generate -->
+ <!-- a "Content-Type" header based on the resource's filename extension, -->
+ <!-- based on these mappings. Additional mappings can be added here (to -->
+ <!-- apply to all web applications), or in your own application's web.xml -->
+ <!-- deployment descriptor. -->
+
+ <mime-mapping>
+ <extension>abs</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ai</extension>
+ <mime-type>application/postscript</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>aif</extension>
+ <mime-type>audio/x-aiff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>aifc</extension>
+ <mime-type>audio/x-aiff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>aiff</extension>
+ <mime-type>audio/x-aiff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>aim</extension>
+ <mime-type>application/x-aim</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>art</extension>
+ <mime-type>image/x-jg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>asf</extension>
+ <mime-type>video/x-ms-asf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>asx</extension>
+ <mime-type>video/x-ms-asf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>au</extension>
+ <mime-type>audio/basic</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>avi</extension>
+ <mime-type>video/x-msvideo</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>avx</extension>
+ <mime-type>video/x-rad-screenplay</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>bcpio</extension>
+ <mime-type>application/x-bcpio</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>bin</extension>
+ <mime-type>application/octet-stream</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>bmp</extension>
+ <mime-type>image/bmp</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>body</extension>
+ <mime-type>text/html</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>cdf</extension>
+ <mime-type>application/x-cdf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>cer</extension>
+ <mime-type>application/x-x509-ca-cert</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>class</extension>
+ <mime-type>application/java</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>cpio</extension>
+ <mime-type>application/x-cpio</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>csh</extension>
+ <mime-type>application/x-csh</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>css</extension>
+ <mime-type>text/css</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>dib</extension>
+ <mime-type>image/bmp</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>doc</extension>
+ <mime-type>application/msword</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>dtd</extension>
+ <mime-type>application/xml-dtd</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>dv</extension>
+ <mime-type>video/x-dv</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>dvi</extension>
+ <mime-type>application/x-dvi</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>eps</extension>
+ <mime-type>application/postscript</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>etx</extension>
+ <mime-type>text/x-setext</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>exe</extension>
+ <mime-type>application/octet-stream</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>gif</extension>
+ <mime-type>image/gif</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>gtar</extension>
+ <mime-type>application/x-gtar</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>gz</extension>
+ <mime-type>application/x-gzip</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>hdf</extension>
+ <mime-type>application/x-hdf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>hqx</extension>
+ <mime-type>application/mac-binhex40</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>htc</extension>
+ <mime-type>text/x-component</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>htm</extension>
+ <mime-type>text/html</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>html</extension>
+ <mime-type>text/html</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>hqx</extension>
+ <mime-type>application/mac-binhex40</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ief</extension>
+ <mime-type>image/ief</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jad</extension>
+ <mime-type>text/vnd.sun.j2me.app-descriptor</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jar</extension>
+ <mime-type>application/java-archive</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>java</extension>
+ <mime-type>text/plain</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jnlp</extension>
+ <mime-type>application/x-java-jnlp-file</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jpe</extension>
+ <mime-type>image/jpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jpeg</extension>
+ <mime-type>image/jpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jpg</extension>
+ <mime-type>image/jpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>js</extension>
+ <mime-type>text/javascript</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jsf</extension>
+ <mime-type>text/plain</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>jspf</extension>
+ <mime-type>text/plain</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>kar</extension>
+ <mime-type>audio/x-midi</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>latex</extension>
+ <mime-type>application/x-latex</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>m3u</extension>
+ <mime-type>audio/x-mpegurl</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mac</extension>
+ <mime-type>image/x-macpaint</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>man</extension>
+ <mime-type>application/x-troff-man</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mathml</extension>
+ <mime-type>application/mathml+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>me</extension>
+ <mime-type>application/x-troff-me</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mid</extension>
+ <mime-type>audio/x-midi</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>midi</extension>
+ <mime-type>audio/x-midi</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mif</extension>
+ <mime-type>application/x-mif</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mov</extension>
+ <mime-type>video/quicktime</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>movie</extension>
+ <mime-type>video/x-sgi-movie</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mp1</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mp2</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mp3</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpa</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpe</extension>
+ <mime-type>video/mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpeg</extension>
+ <mime-type>video/mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpega</extension>
+ <mime-type>audio/x-mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpg</extension>
+ <mime-type>video/mpeg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>mpv2</extension>
+ <mime-type>video/mpeg2</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ms</extension>
+ <mime-type>application/x-wais-source</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>nc</extension>
+ <mime-type>application/x-netcdf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>oda</extension>
+ <mime-type>application/oda</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ogg</extension>
+ <mime-type>application/ogg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pbm</extension>
+ <mime-type>image/x-portable-bitmap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pct</extension>
+ <mime-type>image/pict</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pdf</extension>
+ <mime-type>application/pdf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pgm</extension>
+ <mime-type>image/x-portable-graymap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pic</extension>
+ <mime-type>image/pict</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pict</extension>
+ <mime-type>image/pict</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pls</extension>
+ <mime-type>audio/x-scpls</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>png</extension>
+ <mime-type>image/png</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pnm</extension>
+ <mime-type>image/x-portable-anymap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>pnt</extension>
+ <mime-type>image/x-macpaint</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ppm</extension>
+ <mime-type>image/x-portable-pixmap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ppt</extension>
+ <mime-type>application/powerpoint</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ps</extension>
+ <mime-type>application/postscript</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>psd</extension>
+ <mime-type>image/x-photoshop</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>qt</extension>
+ <mime-type>video/quicktime</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>qti</extension>
+ <mime-type>image/x-quicktime</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>qtif</extension>
+ <mime-type>image/x-quicktime</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ras</extension>
+ <mime-type>image/x-cmu-raster</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>rdf</extension>
+ <mime-type>application/rdf+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>rgb</extension>
+ <mime-type>image/x-rgb</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>rm</extension>
+ <mime-type>application/vnd.rn-realmedia</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>roff</extension>
+ <mime-type>application/x-troff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>rtf</extension>
+ <mime-type>application/rtf</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>rtx</extension>
+ <mime-type>text/richtext</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>sh</extension>
+ <mime-type>application/x-sh</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>shar</extension>
+ <mime-type>application/x-shar</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>smf</extension>
+ <mime-type>audio/x-midi</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>sit</extension>
+ <mime-type>application/x-stuffit</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>snd</extension>
+ <mime-type>audio/basic</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>src</extension>
+ <mime-type>application/x-wais-source</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>sv4cpio</extension>
+ <mime-type>application/x-sv4cpio</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>sv4crc</extension>
+ <mime-type>application/x-sv4crc</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>svg</extension>
+ <mime-type>image/svg+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>swf</extension>
+ <mime-type>application/x-shockwave-flash</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>t</extension>
+ <mime-type>application/x-troff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tar</extension>
+ <mime-type>application/x-tar</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tcl</extension>
+ <mime-type>application/x-tcl</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tex</extension>
+ <mime-type>application/x-tex</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>texi</extension>
+ <mime-type>application/x-texinfo</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>texinfo</extension>
+ <mime-type>application/x-texinfo</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tif</extension>
+ <mime-type>image/tiff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tiff</extension>
+ <mime-type>image/tiff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tr</extension>
+ <mime-type>application/x-troff</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>tsv</extension>
+ <mime-type>text/tab-separated-values</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>txt</extension>
+ <mime-type>text/plain</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ulw</extension>
+ <mime-type>audio/basic</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>ustar</extension>
+ <mime-type>application/x-ustar</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>vxml</extension>
+ <mime-type>application/voicexml+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xbm</extension>
+ <mime-type>image/x-xbitmap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xht</extension>
+ <mime-type>application/xhtml+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xhtml</extension>
+ <mime-type>application/xhtml+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xml</extension>
+ <mime-type>application/xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xpm</extension>
+ <mime-type>image/x-xpixmap</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xsl</extension>
+ <mime-type>application/xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xslt</extension>
+ <mime-type>application/xslt+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xul</extension>
+ <mime-type>application/vnd.mozilla.xul+xml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>xwd</extension>
+ <mime-type>image/x-xwindowdump</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>wav</extension>
+ <mime-type>audio/x-wav</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>svg</extension>
+ <mime-type>image/svg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>svgz</extension>
+ <mime-type>image/svg</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>vsd</extension>
+ <mime-type>application/x-visio</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <!-- Wireless Bitmap -->
+ <extension>wbmp</extension>
+ <mime-type>image/vnd.wap.wbmp</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <!-- WML Source -->
+ <extension>wml</extension>
+ <mime-type>text/vnd.wap.wml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <!-- Compiled WML -->
+ <extension>wmlc</extension>
+ <mime-type>application/vnd.wap.wmlc</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <!-- WML Script Source -->
+ <extension>wmls</extension>
+ <mime-type>text/vnd.wap.wmlscript</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <!-- Compiled WML Script -->
+ <extension>wmlscriptc</extension>
+ <mime-type>application/vnd.wap.wmlscriptc</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>wrl</extension>
+ <mime-type>x-world/x-vrml</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>Z</extension>
+ <mime-type>application/x-compress</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>z</extension>
+ <mime-type>application/x-compress</mime-type>
+ </mime-mapping>
+ <mime-mapping>
+ <extension>zip</extension>
+ <mime-type>application/zip</mime-type>
+ </mime-mapping>
+
+
+ <!-- ==================== Default Welcome File List ===================== -->
+ <!-- When a request URI refers to a directory, the default servlet looks -->
+ <!-- for a "welcome file" within that directory and, if present, -->
+ <!-- to the corresponding resource URI for display. If no welcome file -->
+ <!-- is present, the default servlet either serves a directory listing, -->
+ <!-- or returns a 404 status, depending on how it is configured. -->
+ <!-- -->
+ <!-- If you define welcome files in your own application's web.xml -->
+ <!-- deployment descriptor, that list *replaces* the list configured -->
+ <!-- here, so be sure that you include any of the default values that -->
+ <!-- you wish to include. -->
+
+ <welcome-file-list>
+ <welcome-file>index.html</welcome-file>
+ <welcome-file>index.htm</welcome-file>
+ <welcome-file>index.jsp</welcome-file>
+ </welcome-file-list>
+
+ <error-page>
+ <error-code>404</error-code>
+ <location>/404.html</location>
+ </error-page>
+
+ <error-page>
+ <error-code>500</error-code>
+ <location>/500.html</location>
+ </error-page>
+
+</web-app>
diff --git a/base/tks/shared/conf/workers.properties b/base/tks/shared/conf/workers.properties
new file mode 100644
index 000000000..2c39c6402
--- /dev/null
+++ b/base/tks/shared/conf/workers.properties
@@ -0,0 +1,211 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+# workers.properties -
+#
+# This file provides jk derived plugins with the needed information to
+# connect to the different tomcat workers. Note that the distributed
+# version of this file requires modification before it is usable by a
+# plugin.
+#
+# As a general note, the characters $( and ) are used internally to define
+# macros. Do not use them in your own configuration!!!
+#
+# Whenever you see a set of lines such as:
+# x=value
+# y=$(x)\something
+#
+# the final value for y will be value\something
+#
+# Normaly all you will need to do is un-comment and modify the first three
+# properties, i.e. workers.tomcat_home, workers.java_home and ps.
+# Most of the configuration is derived from these.
+#
+# When you are done updating workers.tomcat_home, workers.java_home and ps
+# you should have 3 workers configured:
+#
+# - An ajp12 worker that connects to localhost:8007
+# - An ajp13 worker that connects to localhost:8009
+# - A jni inprocess worker.
+# - A load balancer worker
+#
+# However by default the plugins will only use the ajp12 worker. To have
+# the plugins use other workers you should modify the worker.list property.
+#
+#
+
+# OPTIONS ( very important for jni mode )
+
+#
+# workers.tomcat_home should point to the location where you
+# installed tomcat. This is where you have your conf, webapps and lib
+# directories.
+#
+workers.tomcat_home=/var/tomcat3
+
+#
+# workers.java_home should point to your Java installation. Normally
+# you should have a bin and lib directories beneath it.
+#
+workers.java_home=/opt/IBMJava2-13
+
+#
+# You should configure your environment slash... ps=\ on NT and / on UNIX
+# and maybe something different elsewhere.
+#
+ps=/
+
+#
+#------ ADVANCED MODE ------------------------------------------------
+#---------------------------------------------------------------------
+#
+
+#
+#------ DEFAULT worket list ------------------------------------------
+#---------------------------------------------------------------------
+#
+#
+# The workers that your plugins should create and work with
+#
+# Add 'inprocess' if you want JNI connector
+worker.list=ajp12, ajp13
+# , inprocess
+
+
+#
+#------ DEFAULT ajp12 WORKER DEFINITION ------------------------------
+#---------------------------------------------------------------------
+#
+
+#
+# Defining a worker named ajp12 and of type ajp12
+# Note that the name and the type do not have to match.
+#
+worker.ajp12.port=8007
+worker.ajp12.host=localhost
+worker.ajp12.type=ajp12
+#
+# Specifies the load balance factor when used with
+# a load balancing worker.
+# Note:
+# ----> lbfactor must be > 0
+# ----> Low lbfactor means less work done by the worker.
+worker.ajp12.lbfactor=1
+
+#
+#------ DEFAULT ajp13 WORKER DEFINITION ------------------------------
+#---------------------------------------------------------------------
+#
+
+#
+# Defining a worker named ajp13 and of type ajp13
+# Note that the name and the type do not have to match.
+#
+worker.ajp13.port=8009
+worker.ajp13.host=localhost
+worker.ajp13.type=ajp13
+#
+# Specifies the load balance factor when used with
+# a load balancing worker.
+# Note:
+# ----> lbfactor must be > 0
+# ----> Low lbfactor means less work done by the worker.
+worker.ajp13.lbfactor=1
+
+#
+# Specify the size of the open connection cache.
+#worker.ajp13.cachesize
+
+#
+#------ DEFAULT LOAD BALANCER WORKER DEFINITION ----------------------
+#---------------------------------------------------------------------
+#
+
+#
+# The loadbalancer (type lb) workers perform wighted round-robin
+# load balancing with sticky sessions.
+# Note:
+# ----> If a worker dies, the load balancer will check its state
+# once in a while. Until then all work is redirected to peer
+# workers.
+worker.loadbalancer.type=lb
+worker.loadbalancer.balanced_workers=ajp12, ajp13
+
+
+#
+#------ DEFAULT JNI WORKER DEFINITION---------------------------------
+#---------------------------------------------------------------------
+#
+
+#
+# Defining a worker named inprocess and of type jni
+# Note that the name and the type do not have to match.
+#
+worker.inprocess.type=jni
+
+#
+#------ CLASSPATH DEFINITION -----------------------------------------
+#---------------------------------------------------------------------
+#
+
+#
+# Additional class path components.
+#
+worker.inprocess.class_path=$(workers.tomcat_home)$(ps)lib$(ps)tomcat.jar
+
+#
+# Setting the command line for tomcat.
+# Note: The cmd_line string may not contain spaces.
+#
+worker.inprocess.cmd_line=start
+
+# Not needed, but can be customized.
+#worker.inprocess.cmd_line=-config
+#worker.inprocess.cmd_line=$(workers.tomcat_home)$(ps)conf$(ps)server.xml
+#worker.inprocess.cmd_line=-home
+#worker.inprocess.cmd_line=$(workers.tomcat_home)
+
+#
+# The JVM that we are about to use
+#
+# This is for Java2
+#
+# Windows
+worker.inprocess.jvm_lib=$(workers.java_home)$(ps)jre$(ps)bin$(ps)classic$(ps)jvm.dll
+# IBM JDK1.3
+#worker.inprocess.jvm_lib=$(workers.java_home)$(ps)jre$(ps)bin$(ps)classic$(ps)libjvm.so
+# Unix - Sun VM or blackdown
+#worker.inprocess.jvm_lib=$(workers.java_home)$(ps)jre$(ps)lib$(ps)i386$(ps)classic$(ps)libjvm.so
+
+#
+# And this is for jdk1.1.X
+#
+#worker.inprocess.jvm_lib=$(workers.java_home)$(ps)bin$(ps)javai.dll
+
+
+#
+# Setting the place for the stdout and stderr of tomcat
+#
+worker.inprocess.stdout=$(workers.tomcat_home)$(ps)logs$(ps)inprocess.stdout
+worker.inprocess.stderr=$(workers.tomcat_home)$(ps)logs$(ps)inprocess.stderr
+
+#
+# Setting the tomcat.home Java property
+#
+#worker.inprocess.sysprops=tomcat.home=$(workers.tomcat_home)
+
+#
+# Java system properties
+#
+# worker.inprocess.sysprops=java.compiler=NONE
+# worker.inprocess.sysprops=myprop=mypropvalue
+
+#
+# Additional path components.
+#
+# worker.inprocess.ld_path=d:$(ps)SQLLIB$(ps)bin
+#
+
+
diff --git a/base/tks/shared/conf/workers.properties.minimal b/base/tks/shared/conf/workers.properties.minimal
new file mode 100644
index 000000000..51980ac49
--- /dev/null
+++ b/base/tks/shared/conf/workers.properties.minimal
@@ -0,0 +1,22 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+# workers.properties.minimal -
+#
+# This file provides minimal jk configuration properties needed to
+# connect to Tomcat.
+#
+# The workers that jk should create and work with
+#
+worker.list=ajp13w
+
+
+#
+# Defining a worker named ajp13w and of type ajp13
+# Note that the name and the type do not have to match.
+#
+worker.ajp13w.type=ajp13
+worker.ajp13w.host=localhost
+worker.ajp13w.port=8009
diff --git a/base/tks/shared/conf/workers2.properties b/base/tks/shared/conf/workers2.properties
new file mode 100644
index 000000000..d24abd3a9
--- /dev/null
+++ b/base/tks/shared/conf/workers2.properties
@@ -0,0 +1,137 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+[logger]
+level=DEBUG
+
+[config:]
+file=${serverRoot}/conf/workers2.properties
+debug=0
+debugEnv=0
+
+[uriMap:]
+info=Maps the requests. Options: debug
+debug=0
+
+# Alternate file logger
+#[logger.file:0]
+#level=DEBUG
+#file=${serverRoot}/logs/jk2.log
+
+[shm:]
+info=Scoreboard. Required for reconfiguration and status with multiprocess servers
+file=${serverRoot}/logs/jk2.shm
+size=1000000
+debug=0
+disabled=0
+
+[workerEnv:]
+info=Global server options
+timing=1
+debug=0
+# Default Native Logger (apache2 or win32 )
+# can be overriden to a file logger, useful
+# when tracing win32 related issues
+#logger=logger.file:0
+
+[lb:lb]
+info=Default load balancer.
+debug=0
+
+[lb:lb_1]
+info=A second load balancer.
+debug=0
+
+[channel.socket:localhost:8009]
+info=Ajp13 forwarding over socket
+debug=0
+tomcatId=localhost:8009
+
+[channel.socket:localhost:8019]
+info=A second tomcat instance.
+debug=0
+tomcatId=localhost:8019
+lb_factor=1
+#group=lb
+group:lb:lb
+#group=lb_1
+group:lb:lb_1
+disabled=0
+
+[channel.un:/opt/33/work/jk2.socket]
+info=A second channel connecting to localhost:8019 via unix socket
+tomcatId=localhost:8019
+lb_factor=1
+debug=0
+
+[channel.jni:jni]
+info=The jni channel, used if tomcat is started inprocess
+
+[status:]
+info=Status worker, displays runtime informations
+
+[vm:]
+info=Parameters used to load a JVM in the server process
+#JVM=C:\jdk\jre\bin\hotspot\jvm.dll
+classpath=${TOMCAT_HOME}/bin/tomcat-jni.jar
+classpath=${TOMCAT_HOME}/server/lib/commons-logging.jar
+OPT=-Dtomcat.home=${TOMCAT_HOME}
+OPT=-Dcatalina.home=${TOMCAT_HOME}
+OPT=-Xmx128M
+#OPT=-Djava.compiler=NONE
+disabled=1
+
+[worker.jni:onStartup]
+info=Command to be executed by the VM on startup. This one will start tomcat.
+class=org/apache/jk/apr/TomcatStarter
+ARG=start
+# For Tomcat 5 use the 'stard' for startup argument
+# ARG=stard
+disabled=1
+stdout=${serverRoot}/logs/stdout.log
+stderr=${serverRoot}/logs/stderr.log
+
+[worker.jni:onShutdown]
+info=Command to be executed by the VM on shutdown. This one will stop tomcat.
+class=org/apache/jk/apr/TomcatStarter
+ARG=stop
+disabled=1
+
+[uri:/jkstatus/*]
+info=Display status information and checks the config file for changes.
+group=status:
+
+[uri:127.0.0.1:8003]
+info=Example virtual host. Make sure myVirtualHost is in /etc/hosts to test it
+alias=myVirtualHost:8003
+
+[uri:127.0.0.1:8003/ex]
+info=Example webapp in the virtual host. It'll go to lb_1 ( i.e. localhost:8019 )
+context=/ex
+group=lb_1
+
+[uri:/examples]
+info=Example webapp in the default context.
+context=/examples
+debug=0
+
+[uri:/examples1/*]
+info=A second webapp, this time going to the second tomcat only.
+group=lb_1
+debug=0
+
+[uri:/examples/servlet/*]
+info=Prefix mapping
+
+[uri:/examples/*.jsp]
+info=Extension mapping
+
+[uri:/examples/*]
+info=Map the whole webapp
+
+[uri:/examples/servlet/HelloW]
+info=Example with debug enabled.
+debug=10
+
diff --git a/base/tks/shared/conf/workers2.properties.minimal b/base/tks/shared/conf/workers2.properties.minimal
new file mode 100644
index 000000000..4c440eb68
--- /dev/null
+++ b/base/tks/shared/conf/workers2.properties.minimal
@@ -0,0 +1,60 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+#
+# This is the minimal JK2 connector configuration file.
+#
+
+[logger]
+info=Native logger
+level=ERROR
+
+[config:]
+file=${serverRoot}/conf/workers2.properties
+debug=0
+debugEnv=0
+
+[uriMap:]
+info=Maps the requests.
+debug=0
+
+[shm:]
+info=Scoreboard. Required for reconfiguration and status with multiprocess servers
+file=anonymous
+debug=0
+
+[workerEnv:]
+info=Global server options
+timing=0
+debug=0
+
+[lb:lb]
+info=Default load balancer.
+debug=0
+
+[channel.socket:localhost:8009]
+info=Ajp13 forwarding over socket
+debug=0
+tomcatId=localhost:8009
+
+[uri:/admin]
+info=Tomcat HTML based administration web application.
+debug=0
+
+[uri:/manager]
+info=A scriptable management web application for the Tomcat Web Server.
+debug=0
+
+[uri:/jsp-examples]
+info=JSP 2.0 Examples.
+debug=0
+
+[uri:/servlets-examples]
+info=Servlet 2.4 Examples.
+debug=0
+
+[uri:/*.jsp]
+info=JSP Extension mapping.
+debug=0
diff --git a/base/tks/shared/etc/init.d/pki-tksd b/base/tks/shared/etc/init.d/pki-tksd
new file mode 100755
index 000000000..2b2fc4e82
--- /dev/null
+++ b/base/tks/shared/etc/init.d/pki-tksd
@@ -0,0 +1,87 @@
+#!/bin/bash
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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-2010 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+# pki-tksd Startup script for pki-tks with tomcat6
+#
+# chkconfig: - 84 16
+# description: Token Key Service (Tomcat 6.0)
+# processname: pki-tksd
+# piddir: /var/run/pki/tks
+#
+
+PROG_NAME=`basename $0`
+SERVICE_NAME="pki-tksd"
+SERVICE_PROG="/sbin/service"
+PKI_PATH="/usr/share/pki/tks"
+PKI_REGISTRY="/etc/sysconfig/pki/tks"
+PKI_TYPE="pki-tks"
+PKI_TOTAL_PORTS=6
+
+# Avoid using 'systemctl' for now
+SYSTEMCTL_SKIP_REDIRECT=1
+export SYSTEMCTL_SKIP_REDIRECT
+
+# Disallow 'others' the ability to 'write' to new files
+umask 00002
+
+command="$1"
+pki_instance="$2"
+
+# Source function library.
+. /etc/init.d/functions
+
+# Source the PKI function library
+. /usr/share/pki/scripts/functions
+
+# See how we were called.
+case $command in
+ status)
+ registry_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 ${default_error}
+ ;;
+ *)
+ echo "unknown action ($command)"
+ usage
+ echo "where valid instance names include:"
+ list_instances
+ exit ${default_error}
+ ;;
+esac
+
diff --git a/base/tks/shared/lib/systemd/system/pki-tksd.target b/base/tks/shared/lib/systemd/system/pki-tksd.target
new file mode 100644
index 000000000..3e2b89edd
--- /dev/null
+++ b/base/tks/shared/lib/systemd/system/pki-tksd.target
@@ -0,0 +1,8 @@
+[Unit]
+Description=PKI Token Key Service
+After=syslog.target network.target
+
+[Install]
+WantedBy=multi-user.target
+
+
diff --git a/base/tks/shared/lib/systemd/system/pki-tksd@.service b/base/tks/shared/lib/systemd/system/pki-tksd@.service
new file mode 100644
index 000000000..d624eece4
--- /dev/null
+++ b/base/tks/shared/lib/systemd/system/pki-tksd@.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=PKI Token Key Service %i
+After=pki-tksd.target
+BindTo=pki-tksd.target
+
+[Service]
+Type=forking
+ExecStart=/usr/bin/pkicontrol start tks %i
+ExecStop=/usr/bin/pkicontrol stop tks %i
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/base/tks/shared/webapps/ROOT/WEB-INF/web.xml b/base/tks/shared/webapps/ROOT/WEB-INF/web.xml
new file mode 100644
index 000000000..3ac8408f7
--- /dev/null
+++ b/base/tks/shared/webapps/ROOT/WEB-INF/web.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright 2004 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ END COPYRIGHT BLOCK -->
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+ version="2.4">
+
+ <display-name>Welcome to Tomcat</display-name>
+ <description>
+ Welcome to Tomcat
+ </description>
+
+</web-app>
+
diff --git a/base/tks/shared/webapps/ROOT/index.jsp b/base/tks/shared/webapps/ROOT/index.jsp
new file mode 100644
index 000000000..4b2b3c60a
--- /dev/null
+++ b/base/tks/shared/webapps/ROOT/index.jsp
@@ -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.
+
+ Copyright (C) 2010 Red Hat, Inc.
+ All rights reserved.
+ --- END COPYRIGHT BLOCK --- -->
+<%
+ // establish acceptable schemes
+ final String HTTP_SCHEME = "http";
+ final String HTTPS_SCHEME = "https";
+
+ // establish known ports
+ final int EE_HTTP_PORT = [PKI_UNSECURE_PORT];
+ final int AGENT_HTTPS_PORT = [PKI_AGENT_SECURE_PORT];
+ final int EE_HTTPS_PORT = [PKI_EE_SECURE_PORT];
+ final int ADMIN_HTTPS_PORT = [PKI_ADMIN_SECURE_PORT];
+
+ // establish known paths
+ final String ADMIN_PATH = "/[PKI_SUBSYSTEM_TYPE]/services";
+ final String AGENT_PATH = "/[PKI_SUBSYSTEM_TYPE]/agent/[PKI_SUBSYSTEM_TYPE]";
+ final String ERROR_PATH = "/[PKI_SUBSYSTEM_TYPE]/404.html";
+
+ // retrieve scheme from request
+ String scheme = request.getScheme();
+
+ // retrieve client hostname on which the request was sent
+ String client_hostname = request.getServerName();
+
+ // retrieve client port number on which the request was sent
+ int client_port = request.getServerPort();
+
+ // retrieve server hostname on which the request was received
+ String server_hostname = request.getLocalName();
+
+ // retrieve server port number on which the request was received
+ int server_port = request.getLocalPort();
+
+ // uncomment the following lines to write to 'catalina.out'
+ //System.out.println( "scheme = '" + scheme + "'" );
+ //System.out.println( "client hostname = '" + client_hostname + "'" );
+ //System.out.println( "client port = '" + client_port + "'" );
+ //System.out.println( "server hostname = '" + server_hostname + "'" );
+ //System.out.println( "server port = '" + server_port + "'" );
+
+ // compose the appropriate URL
+ String URL = "";
+
+ if( scheme.equals( HTTP_SCHEME ) ) {
+ if( server_port == EE_HTTP_PORT ) {
+ // always redirect to secure admin 'services' port
+ scheme = HTTPS_SCHEME;
+ client_port = ADMIN_HTTPS_PORT;
+ URL = scheme + "://" + client_hostname + ":" + client_port + ADMIN_PATH;
+ } else {
+ // unknown HTTP server port: should never get here
+ URL = scheme + "://" + client_hostname + ":" + client_port + ERROR_PATH;
+
+ // uncomment the following line to write to 'catalina.out'
+ //System.out.println( "Unknown HTTP server port: '" + server_port + "'" );
+ }
+ } else if( scheme.equals( HTTPS_SCHEME ) ) {
+ if( server_port == AGENT_HTTPS_PORT ) {
+ URL = scheme + "://" + client_hostname + ":" + client_port + AGENT_PATH;
+ } else if( server_port == EE_HTTPS_PORT ) {
+ // always redirect to secure admin 'services' port
+ client_port = ADMIN_HTTPS_PORT;
+ URL = scheme + "://" + client_hostname + ":" + client_port + ADMIN_PATH;
+ } else if( server_port == ADMIN_HTTPS_PORT ) {
+ URL = scheme + "://" + client_hostname + ":" + client_port + ADMIN_PATH;
+ } else {
+ // unknown HTTPS server port: should never get here
+ URL = scheme + "://" + client_hostname + ":" + client_port + ERROR_PATH;
+
+ // uncomment the following line to write to 'catalina.out'
+ //System.out.println( "Unknown HTTPS server port: '" + server_port + "'" );
+ }
+ } else {
+ // unacceptable scheme: should never get here
+ URL = scheme + "://" + client_hostname + ":" + client_port + ERROR_PATH;
+
+ // uncomment the following line to write to 'catalina.out'
+ //System.out.println( "Unacceptable scheme: '" + scheme + "'" );
+ }
+
+ // respond (back to browser) with the appropriate redirected URL
+ response.sendRedirect( URL );
+%>
diff --git a/base/tks/shared/webapps/tks/WEB-INF/velocity.properties b/base/tks/shared/webapps/tks/WEB-INF/velocity.properties
new file mode 100644
index 000000000..5cd0454cc
--- /dev/null
+++ b/base/tks/shared/webapps/tks/WEB-INF/velocity.properties
@@ -0,0 +1,13 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2006 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+resource.loader = file
+file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
+file.resource.loader.path = [PKI_INSTANCE_PATH]/[PKI_WEBAPPS_NAME]/[PKI_SUBSYSTEM_TYPE]
+file.resource.loader.cache = true
+file.resource.loader.modificationCheckInterval = 2
+input.encoding=UTF-8
+output.encoding=UTF-8
+runtime.log.logsystem.class=org.apache.velocity.runtime.log.NullLogSystem
diff --git a/base/tks/shared/webapps/tks/WEB-INF/web.xml b/base/tks/shared/webapps/tks/WEB-INF/web.xml
new file mode 100644
index 000000000..28276fda0
--- /dev/null
+++ b/base/tks/shared/webapps/tks/WEB-INF/web.xml
@@ -0,0 +1,476 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- BEGIN COPYRIGHT BLOCK
+ Copyright (C) 2006 Red Hat, Inc.
+ All rights reserved.
+ END COPYRIGHT BLOCK -->
+<!DOCTYPE web-app
+ PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "file:///usr/share/pki/setup/web-app_2_3.dtd">
+<web-app>
+
+ <filter>
+ <filter-name>AgentRequestFilter</filter-name>
+ <filter-class>com.netscape.cms.servlet.filter.AgentRequestFilter</filter-class>
+ <init-param>
+ <param-name>https_port</param-name>
+ <param-value>[PKI_AGENT_SECURE_PORT]</param-value>
+ </init-param>
+[PKI_OPEN_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>proxy_port</param-name>
+ <param-value>[PKI_PROXY_SECURE_PORT]</param-value>
+ </init-param>
+[PKI_CLOSE_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>active</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ </filter>
+
+ <filter>
+ <filter-name>AdminRequestFilter</filter-name>
+ <filter-class>com.netscape.cms.servlet.filter.AdminRequestFilter</filter-class>
+ <init-param>
+ <param-name>https_port</param-name>
+ <param-value>[PKI_ADMIN_SECURE_PORT]</param-value>
+ </init-param>
+[PKI_OPEN_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>proxy_port</param-name>
+ <param-value>[PKI_PROXY_SECURE_PORT]</param-value>
+ </init-param>
+[PKI_CLOSE_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>active</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ </filter>
+
+ <filter>
+ <filter-name>EERequestFilter</filter-name>
+ <filter-class>com.netscape.cms.servlet.filter.EERequestFilter</filter-class>
+ <init-param>
+ <param-name>http_port</param-name>
+ <param-value>[PKI_UNSECURE_PORT]</param-value>
+ </init-param>
+ <init-param>
+ <param-name>https_port</param-name>
+ <param-value>[PKI_EE_SECURE_PORT]</param-value>
+ </init-param>
+[PKI_OPEN_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>proxy_port</param-name>
+ <param-value>[PKI_PROXY_SECURE_PORT]</param-value>
+ </init-param>
+ <init-param>
+ <param-name>proxy_http_port</param-name>
+ <param-value>[PKI_PROXY_UNSECURE_PORT]</param-value>
+ </init-param>
+[PKI_CLOSE_ENABLE_PROXY_COMMENT]
+ <init-param>
+ <param-name>active</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ </filter>
+
+ <servlet>
+ <servlet-name>csadmin-wizard</servlet-name>
+ <servlet-class>com.netscape.cms.servlet.wizard.WizardServlet</servlet-class>
+ <init-param>
+ <param-name>properties</param-name>
+ <param-value>/WEB-INF/velocity.properties</param-value>
+ </init-param>
+ <init-param>
+ <param-name>name</param-name>
+ <param-value>TKS Setup Wizard</param-value>
+ </init-param>
+ <init-param>
+ <param-name>panels</param-name>
+ <param-value>welcome=com.netscape.cms.servlet.csadmin.WelcomePanel,module=com.netscape.cms.servlet.csadmin.ModulePanel,confighsmlogin=com.netscape.cms.servlet.csadmin.ConfigHSMLoginPanel,securitydomain=com.netscape.cms.servlet.csadmin.SecurityDomainPanel,securitydomain=com.netscape.cms.servlet.csadmin.DisplayCertChainPanel,subsystem=com.netscape.cms.servlet.csadmin.CreateSubsystemPanel,restorekeys=com.netscape.cms.servlet.csadmin.RestoreKeyCertPanel,databasepanel=com.netscape.cms.servlet.csadmin.DatabasePanel,sizepanel=com.netscape.cms.servlet.csadmin.SizePanel,namepanel=com.netscape.cms.servlet.csadmin.NamePanel,certrequestpanel=com.netscape.cms.servlet.csadmin.CertRequestPanel,backupkeys=com.netscape.cms.servlet.csadmin.BackupKeyCertPanel,savepk12=com.netscape.cms.servlet.csadmin.SavePKCS12Panel,adminpanel=com.netscape.cms.servlet.csadmin.AdminPanel,importadmincertpanel=com.netscape.cms.servlet.csadmin.ImportAdminCertPanel,donepanel=com.netscape.cms.servlet.csadmin.DonePanel</param-value>
+ </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name>csadmin-login</servlet-name>
+ <servlet-class>com.netscape.cms.servlet.csadmin.LoginServlet</servlet-class>
+ <init-param>
+ <param-name>properties</param-name>
+ <param-value>/WEB-INF/velocity.properties</param-value>
+ </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> tksstart </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.CMSStartServlet </servlet-class>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> cfgPath </param-name>
+ <param-value> [PKI_INSTANCE_PATH]/conf/CS.cfg </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> tksstart </param-value> </init-param>
+ <load-on-startup> 1 </load-on-startup>
+ </servlet>
+
+ <servlet>
+ <servlet-name> tksug </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.UsrGrpAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> tksug </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> tkslog </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.LogAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> tkslog </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> tksauths </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.AuthAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> tksauths </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+<!--
+ <servlet>
+ <servlet-name> tksjobsScheduler </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.JobsAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> tksjobsScheduler </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+-->
+
+ <servlet>
+ <servlet-name> tksacl </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.ACLAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> tksacl </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> tksserver </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.admin.CMSAdminServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> tksserver </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> tksRegisterUser </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.RegisterUser </servlet-class>
+ <init-param><param-name> GetClientCert </param-name> <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> tks </param-value> </init-param> <init-param><param-name> ID </param-name>
+ <param-value> tksRegisterUser </param-value> </init-param>
+ <init-param><param-name> GroupName </param-name>
+ <param-value> Token Key Service Manager Agents </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name> <param-value> TokenAuth </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.tks.registerUser </param-value> </init-param>
+ </servlet>
+
+ <servlet> <servlet-name> tksImportTransportCert </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.ImportTransportCert </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> tks </param-value> </init-param> <init-param><param-name> ID </param-name>
+ <param-value> tksImportTransportCert </param-value> </init-param> <init-param><param-name> AuthMgr </param-name>
+ <param-value> TokenAuth </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.tks.importTransportCert </param-value> </init-param>
+ </servlet>
+
+
+ <servlet>
+ <servlet-name> tksEncryptData </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.tks.TokenServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> tksEncryptData </param-value> </init-param>
+ <init-param><param-name> template </param-name>
+ <param-value> index.template </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.tks.encrypteddata </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> tksCreateKeySetData </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.tks.TokenServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> tksCreateKeySetData </param-value> </init-param>
+ <init-param><param-name> template </param-name>
+ <param-value> index.template </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.tks.keysetdata </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> tksSessionKey </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.tks.TokenServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> tksSessionKey </param-value> </init-param>
+ <init-param><param-name> template </param-name>
+ <param-value> index.template </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.tks.sessionkey </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> tksRandomData </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.tks.TokenServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> true </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> tksRandomData </param-value> </init-param>
+ <init-param><param-name> template </param-name>
+ <param-value> index.template </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.tks.randomdata </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> certUserDBAuthMgr </param-value> </init-param>
+ </servlet>
+
+
+ <servlet>
+ <servlet-name> tksports </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.base.PortsServlet </servlet-class>
+ <init-param><param-name> ID </param-name>
+ <param-value> tksports </param-value> </init-param>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> services </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.MainPageServlet </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authorityId </param-name>
+ <param-value> tks </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> services </param-value> </init-param>
+ <init-param><param-name> templatePath </param-name>
+ <param-value> /services.template </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> tksDownloadPKCS12 </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.DownloadPKCS12 </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> tks </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> tksDownloadPKCS12 </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> TokenAuth </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.clone.configuration </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> tksGetConfigEntries </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.GetConfigEntries </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> tks </param-value> </init-param>
+ <init-param><param-name> ID </param-name>
+ <param-value> tksGetConfigEntries </param-value> </init-param>
+ <init-param><param-name> AuthzMgr </param-name>
+ <param-value> BasicAclAuthz </param-value> </init-param>
+ <init-param><param-name> AuthMgr </param-name>
+ <param-value> TokenAuth </param-value> </init-param>
+ <init-param><param-name> resourceID </param-name>
+ <param-value> certServer.clone.configuration.GetConfigEntries </param-value> </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name> tksGetTokenInfo </servlet-name>
+ <servlet-class> com.netscape.cms.servlet.csadmin.GetTokenInfo </servlet-class>
+ <init-param><param-name> GetClientCert </param-name>
+ <param-value> false </param-value> </init-param>
+ <init-param><param-name> authority </param-name>
+ <param-value> tks </param-value> </init-param> <init-param><param-name> ID </param-name>
+ <param-value> tksGetTokenInfo </param-value> </init-param>
+ <init-param><param-name> interface </param-name>
+ <param-value> ee </param-value> </init-param>
+ </servlet>
+
+[PKI_OPEN_SEPARATE_PORTS_WEB_COMMENT]
+ <filter-mapping>
+ <filter-name> AgentRequestFilter </filter-name>
+ <url-pattern> /agent/* </url-pattern>
+ </filter-mapping>
+
+ <filter-mapping>
+ <filter-name> AdminRequestFilter </filter-name>
+ <url-pattern> /admin/* </url-pattern>
+ <url-pattern> /auths </url-pattern>
+ <url-pattern> /ug </url-pattern>
+ <url-pattern> /log </url-pattern>
+ <url-pattern> /acl </url-pattern>
+ <url-pattern> /server </url-pattern>
+ </filter-mapping>
+
+ <filter-mapping>
+ <filter-name> EERequestFilter </filter-name>
+ <url-pattern> /ee/* </url-pattern>
+ </filter-mapping>
+[PKI_CLOSE_SEPARATE_PORTS_WEB_COMMENT]
+
+ <servlet-mapping>
+ <servlet-name> tksstart </servlet-name>
+ <url-pattern> /start </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> tksug </servlet-name>
+ <url-pattern> /ug </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> tkslog </servlet-name>
+ <url-pattern> /log </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> tksauths </servlet-name>
+ <url-pattern> /auths </url-pattern>
+ </servlet-mapping>
+
+<!--
+ <servlet-mapping>
+ <servlet-name> tksjobsScheduler </servlet-name>
+ <url-pattern> /jobsScheduler </url-pattern>
+ </servlet-mapping>
+-->
+
+ <servlet-mapping>
+ <servlet-name> tksacl </servlet-name>
+ <url-pattern> /acl </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> tksserver </servlet-name>
+ <url-pattern> /server </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> tksEncryptData </servlet-name>
+ <url-pattern> /agent/tks/encryptData </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> tksCreateKeySetData </servlet-name>
+ <url-pattern> /agent/tks/createKeySetData </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> tksSessionKey </servlet-name>
+ <url-pattern> /agent/tks/computeSessionKey </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> tksRandomData </servlet-name>
+ <url-pattern> /agent/tks/computeRandomData </url-pattern>
+ </servlet-mapping>
+
+
+ <servlet-mapping>
+ <servlet-name>csadmin-wizard</servlet-name>
+ <url-pattern>/admin/console/config/wizard</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>csadmin-login</servlet-name>
+ <url-pattern>/admin/console/config/login</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> tksGetConfigEntries </servlet-name>
+ <url-pattern> /admin/tks/getConfigEntries </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> tksports </servlet-name>
+ <url-pattern> /ee/tks/ports </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> tksRegisterUser </servlet-name>
+ <url-pattern> /admin/tks/registerUser </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> tksImportTransportCert </servlet-name>
+ <url-pattern> /admin/tks/importTransportCert </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> services </servlet-name>
+ <url-pattern> /services </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> tksDownloadPKCS12 </servlet-name>
+ <url-pattern> /admin/console/config/savepkcs12 </url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name> tksGetTokenInfo </servlet-name>
+ <url-pattern> /ee/tks/getTokenInfo </url-pattern>
+ </servlet-mapping>
+
+ <!-- ==================== Default Session Configuration =============== -->
+ <!-- You can set the default session timeout (in minutes) for all newly -->
+ <!-- created sessions by modifying the value below. -->
+ <!-- -->
+ <!-- To disable session timeouts for this instance, set a value of -1. -->
+
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+</web-app>
+
diff --git a/base/tks/src/CMakeLists.txt b/base/tks/src/CMakeLists.txt
new file mode 100644
index 000000000..852ad7bf4
--- /dev/null
+++ b/base/tks/src/CMakeLists.txt
@@ -0,0 +1,96 @@
+project(pki-tks_java Java)
+
+# '/usr/share/java/pki' jars
+find_file(PKI_CERTSRV_JAR
+ NAMES
+ pki-certsrv.jar
+ PATHS
+ /usr/share/java/pki
+)
+
+find_file(PKI_CMS_JAR
+ NAMES
+ pki-cms.jar
+ PATHS
+ /usr/share/java/pki
+)
+
+find_file(PKI_CMSCORE_JAR
+ NAMES
+ pki-cmscore.jar
+ PATHS
+ /usr/share/java/pki
+)
+
+find_file(PKI_CMSUTIL_JAR
+ NAMES
+ pki-cmsutil.jar
+ PATHS
+ /usr/share/java/pki
+)
+
+find_file(PKI_NSUTIL_JAR
+ NAMES
+ pki-nsutil.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java/pki
+)
+
+
+# '/usr/share/java' jars
+find_file(LDAPJDK_JAR
+ NAMES
+ ldapjdk.jar
+ PATHS
+ /usr/share/java
+)
+
+
+# '${JAVA_LIB_INSTALL_DIR}' jars
+find_file(JSS_JAR
+ NAMES
+ jss4.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+)
+
+find_file(COMMONS_CODEC_JAR
+ NAMES
+ commons-codec.jar
+ PATHS
+ /usr/share/java
+)
+
+find_file(SYMKEY_JAR
+ NAMES
+ symkey.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+)
+
+
+# identify java sources
+set(pki-tks_java_SRCS
+ com/netscape/tks/TKSAuthority.java
+)
+
+
+# set classpath
+set(CMAKE_JAVA_INCLUDE_PATH
+ ${PKI_CERTSRV_JAR} ${PKI_CMS_JAR} ${PKI_CMSCORE_JAR}
+ ${PKI_CMSUTIL_JAR} ${PKI_NSUTIL_JAR}
+ ${LDAPJDK_JAR}
+ ${JSS_JAR} ${COMMONS_CODEC_JAR} ${SYMKEY_JAR})
+
+
+# set version
+set(CMAKE_JAVA_TARGET_VERSION ${APPLICATION_VERSION})
+
+
+# build pki-tks.jar
+add_jar(pki-tks ${pki-tks_java_SRCS})
+add_dependencies(pki-tks symkey pki-nsutil pki-cmsutil pki-certsrv pki-cms pki-cmscore)
+install_jar(pki-tks ${JAVA_JAR_INSTALL_DIR}/pki)
+set(PKI_TKS_JAR ${pki-tks_JAR_FILE} CACHE INTERNAL "pki-tks jar file")
+
diff --git a/base/tks/src/com/netscape/tks/TKSAuthority.java b/base/tks/src/com/netscape/tks/TKSAuthority.java
new file mode 100644
index 000000000..1987659c4
--- /dev/null
+++ b/base/tks/src/com/netscape/tks/TKSAuthority.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.tks;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+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.request.IRequestListener;
+import com.netscape.certsrv.request.IRequestQueue;
+
+public class TKSAuthority implements IAuthority, ISubsystem {
+ protected ILogger mLogger = CMS.getLogger();
+ private String mNickname = null;
+ private ISubsystem mOwner;
+ private IConfigStore mConfig = null;
+ protected String mId = null;
+ public static final String PROP_NICKNAME = "nickName";
+
+ /**
+ * Retrieves the request queue for the Authority.
+ * <P>
+ *
+ * @return the request queue.
+ */
+ public IRequestQueue getRequestQueue() {
+ return null;
+ }
+
+ /**
+ * 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) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_TKS,
+ level, msg);
+ }
+
+ /**
+ * nickname of signing (id) cert
+ */
+ public void setNickname(String nickname) {
+ mNickname = nickname;
+ }
+
+ public String getNickname() {
+ CMS.debug("Error: TKSAuthority::getNickname - nickname of signing (id) cert");
+ return mNickname;
+ }
+
+ public String getOfficialName() {
+ return "tks";
+ }
+
+ /**
+ * Initializes this subsystem.
+ * <P>
+ *
+ * @param owner owner of this subsystem
+ * @param config configuration of this subsystem
+ * @exception EBaseException failed to initialize this RA
+ */
+ public void init(ISubsystem owner, IConfigStore config) throws
+ EBaseException {
+ mOwner = owner;
+
+ mConfig = config;
+ //mNickname = mConfig.getString(PROP_NICKNAME);
+ CMS.debug("TKS Authority (" +
+ getId() + "): " + "Initialized Request Processor.");
+
+ }
+
+ /**
+ * Notifies this subsystem if owner is in running mode.
+ *
+ * @exception EBaseException failed to start up
+ */
+ public void startup() throws EBaseException {
+
+ // Note that we use our instance id for registration.
+ // This helps us to support multiple instances
+ // of a subsystem within server.
+
+ }
+
+ /**
+ * Stops this system. The owner may call shutdown
+ * anytime after initialization.
+ * <P>
+ */
+ public void shutdown() {
+
+ getLogger().log(ILogger.EV_SYSTEM, ILogger.S_TKS,
+ ILogger.LL_INFO, "TKSAuthority is stopped");
+
+ }
+
+ /**
+ * Returns the root configuration storage of this system.
+ * <P>
+ *
+ * @return configuration store of this subsystem
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * Sets subsystem identifier.
+ *
+ * @param id subsystem id
+ * @exception EBaseException failed to set id
+ */
+ public void setId(String id) throws EBaseException {
+ mId = id;
+ }
+
+ /**
+ * Retrieves logger from escrow authority.
+ *
+ * @return logger
+ */
+ public ILogger getLogger() {
+ return CMS.getLogger();
+ }
+
+}
diff --git a/base/tps/CMakeLists.txt b/base/tps/CMakeLists.txt
new file mode 100644
index 000000000..96d23fefa
--- /dev/null
+++ b/base/tps/CMakeLists.txt
@@ -0,0 +1,208 @@
+project(tps CXX)
+
+# NOTE: TPS utilizes internal libraries located under '%{_libdir}/tps'.
+#
+# One method of resolving this issue is the use of RPATH as
+# described in 'http://www.cmake.org/Wiki/CMake_RPATH_handling'.
+#
+# While Fedora allows the use of RPATH for this purpose as documented
+# in the section entitled 'Rpath_for_Internal_Libraries' in the URL
+# called 'http://fedoraproject.org/wiki/Packaging/Guidelines',
+# the RPM '%cmake' macro overrides use of RPATH on Fedora and RHEL.
+#
+# To resolve this issue on Fedora and RHEL, one of the following
+# methods may be utilized:
+#
+# (1) Uncomment the 'SET(CMAKE_SKIP_RPATH FALSE)' line below, or
+# (2) Implement the files described in the section entitled
+# 'Alternatives to Rpath' in the URL called
+# 'http://fedoraproject.org/wiki/Packaging/Guidelines'.
+
+# use, i.e. don't skip the full RPATH
+# (overrides '%cmake' macro setting of true)
+#SET(CMAKE_SKIP_RPATH FALSE)
+
+# use, i.e. don't skip the full RPATH for the build tree
+SET(CMAKE_SKIP_BUILD_RPATH FALSE)
+
+# when building, don't use the install RPATH already
+# (but later on when installing)
+SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
+
+# the RPATH to be used when installing
+SET(CMAKE_INSTALL_RPATH "${LIB_INSTALL_DIR}/tps")
+
+# add the automatically determined parts of the RPATH
+# which point to directories outside the build tree to the install RPATH
+SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+
+add_subdirectory(src)
+add_subdirectory(tools)
+
+# install files
+add_subdirectory(doc)
+add_subdirectory(setup)
+
+# install init script
+install(
+ FILES
+ etc/init.d/pki-tpsd
+ DESTINATION
+ ${SYSCONF_INSTALL_DIR}/rc.d/init.d
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+install(
+ FILES
+ applets/1.3.44724DDE.ijc
+ applets/1.4.499dc06c.ijc
+ applets/1.4.4d40a449.ijc
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/applets
+)
+
+install(
+ DIRECTORY
+ forms/esc/cgi-bin
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}
+)
+
+install(
+ DIRECTORY
+ apache/conf
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}
+)
+
+install(
+ FILES
+ forms/index.html
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/docroot
+)
+
+install(
+ FILES
+ forms/index.cgi
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/docroot
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+install(
+ DIRECTORY
+ lib
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}
+)
+
+install(
+ FILES
+ scripts/nss_pcache
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/scripts
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+install(
+ FILES
+ scripts/addAgents.ldif
+ scripts/addIndexes.ldif
+ scripts/addTokens.ldif
+ scripts/addVLVIndexes.ldif
+ scripts/database.ldif
+ scripts/schemaMods.ldif
+ scripts/vlvtasks.ldif
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/scripts
+)
+
+# install empty directories
+install(
+ DIRECTORY
+ DESTINATION
+ ${VAR_INSTALL_DIR}/lock/pki/tps
+)
+
+install(
+ DIRECTORY
+ DESTINATION
+ ${VAR_INSTALL_DIR}/run/pki/tps
+)
+
+install(
+ DIRECTORY
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/docroot/demo
+)
+
+install(
+ DIRECTORY
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/docroot/home
+)
+
+install(
+ DIRECTORY
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/docroot/so
+)
+
+install(
+ DIRECTORY
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/docroot/sow
+)
+
+install(
+ DIRECTORY
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/docroot/tokendb
+)
+
+install(
+ DIRECTORY
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/docroot/tps
+)
+
+install(
+ DIRECTORY
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/docroot/tps/admin
+)
+
+install(
+ DIRECTORY
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/docroot/tps/admin/console
+)
+
+install(
+ DIRECTORY
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/docroot/tps/admin/console/config
+)
+
+install(
+ DIRECTORY
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/docroot/tps/admin/console/img
+)
+
+install(
+ DIRECTORY
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/docroot/tps/admin/console/js
+)
+
diff --git a/base/tps/LICENSE b/base/tps/LICENSE
new file mode 100644
index 000000000..e2391a711
--- /dev/null
+++ b/base/tps/LICENSE
@@ -0,0 +1,469 @@
+This Program is free software; you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; version 2.1 of the License.
+
+This Program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+for more details.
+
+You should have received a copy of the GNU Lesser 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 LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 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.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+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 and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, 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 library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete 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 distribute a copy of this License along with the
+Library.
+
+ 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 Library or any portion
+of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+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 Library, 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 Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you 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.
+
+ If distribution of 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 satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be 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.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library 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.
+
+ 9. 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 Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+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 with
+this License.
+
+ 11. 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 Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library 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 Library.
+
+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.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library 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.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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 Library
+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 Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+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
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. 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 LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
diff --git a/base/tps/apache/LICENSE-2.0 b/base/tps/apache/LICENSE-2.0
new file mode 100644
index 000000000..7b69c6227
--- /dev/null
+++ b/base/tps/apache/LICENSE-2.0
@@ -0,0 +1,678 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+
+APACHE HTTP SERVER SUBCOMPONENTS:
+
+The Apache HTTP Server includes a number of subcomponents with
+separate copyright notices and license terms. Your use of the source
+code for the these subcomponents is subject to the terms and
+conditions of the following licenses.
+
+For the mod_mime_magic component:
+
+/*
+ * mod_mime_magic: MIME type lookup via file magic numbers
+ * Copyright (c) 1996-1997 Cisco Systems, Inc.
+ *
+ * This software was submitted by Cisco Systems to the Apache Group in July
+ * 1997. Future revisions and derivatives of this source code must
+ * acknowledge Cisco Systems as the original contributor of this module.
+ * All other licensing and usage conditions are those of the Apache Group.
+ *
+ * Some of this code is derived from the free version of the file command
+ * originally posted to comp.sources.unix. Copyright info for that program
+ * is included below as required.
+ * ---------------------------------------------------------------------------
+ * - Copyright (c) Ian F. Darwin, 1987. Written by Ian F. Darwin.
+ *
+ * This software is not subject to any license of the American Telephone and
+ * Telegraph Company or of the Regents of the University of California.
+ *
+ * Permission is granted to anyone to use this software for any purpose on any
+ * computer system, and to alter it and redistribute it freely, subject to
+ * the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of this
+ * software, no matter how awful, even if they arise from flaws in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either by
+ * explicit claim or by omission. Since few users ever read sources, credits
+ * must appear in the documentation.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software. Since few users ever read
+ * sources, credits must appear in the documentation.
+ *
+ * 4. This notice may not be removed or altered.
+ * -------------------------------------------------------------------------
+ *
+ */
+
+
+For the modules\mappers\mod_imap.c component:
+
+ "macmartinized" polygon code copyright 1992 by Eric Haines, erich@eye.com
+
+For the server\util_md5.c component:
+
+/************************************************************************
+ * NCSA HTTPd Server
+ * Software Development Group
+ * National Center for Supercomputing Applications
+ * University of Illinois at Urbana-Champaign
+ * 605 E. Springfield, Champaign, IL 61820
+ * httpd@ncsa.uiuc.edu
+ *
+ * Copyright (C) 1995, Board of Trustees of the University of Illinois
+ *
+ ************************************************************************
+ *
+ * md5.c: NCSA HTTPd code which uses the md5c.c RSA Code
+ *
+ * Original Code Copyright (C) 1994, Jeff Hostetler, Spyglass, Inc.
+ * Portions of Content-MD5 code Copyright (C) 1993, 1994 by Carnegie Mellon
+ * University (see Copyright below).
+ * Portions of Content-MD5 code Copyright (C) 1991 Bell Communications
+ * Research, Inc. (Bellcore) (see Copyright below).
+ * Portions extracted from mpack, John G. Myers - jgm+@cmu.edu
+ * Content-MD5 Code contributed by Martin Hamilton (martin@net.lut.ac.uk)
+ *
+ */
+
+
+/* these portions extracted from mpack, John G. Myers - jgm+@cmu.edu */
+/* (C) Copyright 1993,1994 by Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Carnegie
+ * Mellon University not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission. Carnegie Mellon University makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore)
+ *
+ * Permission to use, copy, modify, and distribute this material
+ * for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice and this permission notice
+ * appear in all copies, and that the name of Bellcore not be
+ * used in advertising or publicity pertaining to this
+ * material without the specific, prior written permission
+ * of an authorized representative of Bellcore. BELLCORE
+ * MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY
+ * OF THIS MATERIAL FOR ANY PURPOSE. IT IS PROVIDED "AS IS",
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
+ */
+
+For the srclib\apr\include\apr_md5.h component:
+/*
+ * This is work is derived from material Copyright RSA Data Security, Inc.
+ *
+ * The RSA copyright statement and Licence for that original material is
+ * included below. This is followed by the Apache copyright statement and
+ * licence for the modifications made to that material.
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ rights reserved.
+
+ License to copy and use this software is granted provided that it
+ is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+ Algorithm" in all material mentioning or referencing this software
+ or this function.
+
+ License is also granted to make and use derivative works provided
+ that such works are identified as "derived from the RSA Data
+ Security, Inc. MD5 Message-Digest Algorithm" in all material
+ mentioning or referencing the derived work.
+
+ RSA Data Security, Inc. makes no representations concerning either
+ the merchantability of this software or the suitability of this
+ software for any particular purpose. It is provided "as is"
+ without express or implied warranty of any kind.
+
+ These notices must be retained in any copies of any part of this
+ documentation and/or software.
+ */
+
+For the srclib\apr\passwd\apr_md5.c component:
+
+/*
+ * This is work is derived from material Copyright RSA Data Security, Inc.
+ *
+ * The RSA copyright statement and Licence for that original material is
+ * included below. This is followed by the Apache copyright statement and
+ * licence for the modifications made to that material.
+ */
+
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ rights reserved.
+
+ License to copy and use this software is granted provided that it
+ is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+ Algorithm" in all material mentioning or referencing this software
+ or this function.
+
+ License is also granted to make and use derivative works provided
+ that such works are identified as "derived from the RSA Data
+ Security, Inc. MD5 Message-Digest Algorithm" in all material
+ mentioning or referencing the derived work.
+
+ RSA Data Security, Inc. makes no representations concerning either
+ the merchantability of this software or the suitability of this
+ software for any particular purpose. It is provided "as is"
+ without express or implied warranty of any kind.
+
+ These notices must be retained in any copies of any part of this
+ documentation and/or software.
+ */
+/*
+ * The apr_md5_encode() routine uses much code obtained from the FreeBSD 3.0
+ * MD5 crypt() function, which is licenced as follows:
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ */
+
+For the srclib\apr-util\crypto\apr_md4.c component:
+
+ * This is derived from material copyright RSA Data Security, Inc.
+ * Their notice is reproduced below in its entirety.
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD4 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+For the srclib\apr-util\include\apr_md4.h component:
+
+ *
+ * This is derived from material copyright RSA Data Security, Inc.
+ * Their notice is reproduced below in its entirety.
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD4 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+
+For the srclib\apr-util\test\testdbm.c component:
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000-2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ * not be used to endorse or promote products derived from this
+ * software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * This file came from the SDBM package (written by oz@nexus.yorku.ca).
+ * That package was under public domain. This file has been ported to
+ * APR, updated to ANSI C and other, newer idioms, and added to the Apache
+ * codebase under the above copyright and license.
+ */
+
+
+For the srclib\apr-util\test\testmd4.c component:
+
+ *
+ * This is derived from material copyright RSA Data Security, Inc.
+ * Their notice is reproduced below in its entirety.
+ *
+ * Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
+ * rights reserved.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+For the srclib\apr-util\xml\expat\conftools\install-sh component:
+
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. M.I.T. makes no representations about the
+# suitability of this software for any purpose. It is provided "as is"
+# without express or implied warranty.
+#
+
+For the srclib\pcre\install-sh component:
+
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. M.I.T. makes no representations about the
+# suitability of this software for any purpose. It is provided "as is"
+# without express or implied warranty.
+
+For the pcre component:
+
+PCRE LICENCE
+------------
+
+PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+Written by: Philip Hazel <ph10@cam.ac.uk>
+
+University of Cambridge Computing Service,
+Cambridge, England. Phone: +44 1223 334714.
+
+Copyright (c) 1997-2001 University of Cambridge
+
+Permission is granted to anyone to use this software for any purpose on any
+computer system, and to redistribute it freely, subject to the following
+restrictions:
+
+1. This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+2. The origin of this software must not be misrepresented, either by
+ explicit claim or by omission. In practice, this means that if you use
+ PCRE in software which you distribute to others, commercially or
+ otherwise, you must put a sentence like this
+
+ Regular expression support is provided by the PCRE library package,
+ which is open source software, written by Philip Hazel, and copyright
+ by the University of Cambridge, England.
+
+ somewhere reasonably visible in your documentation and in any relevant
+ files or online help data or similar. A reference to the ftp site for
+ the source, that is, to
+
+ ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
+
+ should also be given in the documentation.
+
+3. Altered versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+4. If PCRE is embedded in any software that is released under the GNU
+ General Purpose Licence (GPL), or Lesser General Purpose Licence (LGPL),
+ then the terms of that licence shall supersede any condition above with
+ which it is incompatible.
+
+The documentation for PCRE, supplied in the "doc" directory, is distributed
+under the same terms as the software itself.
+
+End PCRE LICENCE
+
+
+For the test\zb.c component:
+
+/* ZeusBench V1.01
+ ===============
+
+This program is Copyright (C) Zeus Technology Limited 1996.
+
+This program may be used and copied freely providing this copyright notice
+is not removed.
+
+This software is provided "as is" and any express or implied waranties,
+including but not limited to, the implied warranties of merchantability and
+fitness for a particular purpose are disclaimed. In no event shall
+Zeus Technology Ltd. be liable for any direct, indirect, incidental, special,
+exemplary, or consequential damaged (including, but not limited to,
+procurement of substitute good or services; loss of use, data, or profits;
+or business interruption) however caused and on theory of liability. Whether
+in contract, strict liability or tort (including negligence or otherwise)
+arising in any way out of the use of this software, even if advised of the
+possibility of such damage.
+
+ Written by Adam Twiss (adam@zeus.co.uk). March 1996
+
+Thanks to the following people for their input:
+ Mike Belshe (mbelshe@netscape.com)
+ Michael Campanella (campanella@stevms.enet.dec.com)
+
+*/
+
+For the expat xml parser component:
+
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+ and Clark Cooper
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+====================================================================
diff --git a/base/tps/apache/conf/httpd.conf b/base/tps/apache/conf/httpd.conf
new file mode 100644
index 000000000..878a4e655
--- /dev/null
+++ b/base/tps/apache/conf/httpd.conf
@@ -0,0 +1,1085 @@
+#
+# Based upon the NCSA server configuration files originally by Rob McCool.
+#
+# This is the main Apache server configuration file. It contains the
+# configuration directives that give the server its instructions.
+# See <URL:http://httpd.apache.org/docs-2.0/> for detailed information about
+# the directives.
+#
+# Do NOT simply read the instructions in here without understanding
+# what they do. They're here only as hints or reminders. If you are unsure
+# consult the online docs. You have been warned.
+#
+# The configuration directives are grouped into three basic sections:
+# 1. Directives that control the operation of the Apache server process as a
+# whole (the 'global environment').
+# 2. Directives that define the parameters of the 'main' or 'default' server,
+# which responds to requests that aren't handled by a virtual host.
+# These directives also provide default values for the settings
+# of all virtual hosts.
+# 3. Settings for virtual hosts, which allow Web requests to be sent to
+# different IP addresses or hostnames and have them handled by the
+# same Apache server process.
+#
+# Configuration and logfile names: If the filenames you specify for many
+# of the server's control files begin with "/" (or "drive:/" for Win32), the
+# server will use that explicit path. If the filenames do *not* begin
+# with "/", the value of ServerRoot is prepended -- so "logs/foo.log"
+# with ServerRoot set to "/export/apache" will be interpreted by the
+# server as "/export/apache/logs/foo.log".
+#
+
+### Section 1: Global Environment
+#
+# The directives in this section affect the overall operation of Apache,
+# such as the number of concurrent requests it can handle or where it
+# can find its configuration files.
+#
+
+#
+# ServerRoot: The top of the directory tree under which the server's
+# configuration, error, and log files are kept.
+#
+# NOTE! If you intend to place this on an NFS (or otherwise network)
+# mounted filesystem then please read the LockFile documentation (available
+# at <URL:http://httpd.apache.org/docs-2.0/mod/mpm_common.html#lockfile>);
+# you will save yourself a lot of trouble.
+#
+# Do NOT add a slash at the end of the directory path.
+#
+ServerRoot "[SERVER_ROOT]"
+
+#
+# The accept serialization lock file MUST BE STORED ON A LOCAL DISK.
+#
+<IfModule !mpm_winnt.c>
+<IfModule !mpm_netware.c>
+#LockFile logs/accept.lock
+</IfModule>
+</IfModule>
+
+#
+# ScoreBoardFile: File used to store internal server process information.
+# If unspecified (the default), the scoreboard will be stored in an
+# anonymous shared memory segment, and will be unavailable to third-party
+# applications.
+# If specified, ensure that no two invocations of Apache share the same
+# scoreboard file. The scoreboard file MUST BE STORED ON A LOCAL DISK.
+#
+<IfModule !mpm_netware.c>
+<IfModule !perchild.c>
+#ScoreBoardFile logs/apache_runtime_status
+</IfModule>
+</IfModule>
+
+
+#
+# PidFile: The file in which the server should record its process
+# identification number when it starts.
+#
+<IfModule !mpm_netware.c>
+PidFile run/[PKI_INSTANCE_ID].pid
+</IfModule>
+
+#
+# Timeout: The number of seconds before receives and sends time out.
+#
+Timeout 300
+
+#
+# KeepAlive: Whether or not to allow persistent connections (more than
+# one request per connection). Set to "Off" to deactivate.
+#
+KeepAlive On
+
+#
+# MaxKeepAliveRequests: The maximum number of requests to allow
+# during a persistent connection. Set to 0 to allow an unlimited amount.
+# We recommend you leave this number high, for maximum performance.
+#
+MaxKeepAliveRequests 100
+
+#
+# KeepAliveTimeout: Number of seconds to wait for the next request from the
+# same client on the same connection.
+#
+KeepAliveTimeout 15
+
+##
+## Server-Pool Size Regulation (MPM specific)
+##
+
+# prefork MPM
+# StartServers: number of server processes to start
+# MinSpareServers: minimum number of server processes which are kept spare
+# MaxSpareServers: maximum number of server processes which are kept spare
+# MaxClients: maximum number of server processes allowed to start
+# MaxRequestsPerChild: maximum number of requests a server process serves
+<IfModule prefork.c>
+StartServers 5
+MinSpareServers 5
+MaxSpareServers 10
+MaxClients 150
+MaxRequestsPerChild 0
+</IfModule>
+
+# worker MPM
+# StartServers: initial number of server processes to start
+# MaxClients: maximum number of simultaneous client connections
+# MinSpareThreads: minimum number of worker threads which are kept spare
+# MaxSpareThreads: maximum number of worker threads which are kept spare
+# ThreadsPerChild: constant number of worker threads in each server process
+# MaxRequestsPerChild: maximum number of requests a server process serves
+<IfModule worker.c>
+ServerLimit 1
+StartServers 1
+MaxClients 64
+MinSpareThreads 1
+MaxSpareThreads 75
+ThreadsPerChild 64
+MaxRequestsPerChild 0
+</IfModule>
+
+# perchild MPM
+# NumServers: constant number of server processes
+# StartThreads: initial number of worker threads in each server process
+# MinSpareThreads: minimum number of worker threads which are kept spare
+# MaxSpareThreads: maximum number of worker threads which are kept spare
+# MaxThreadsPerChild: maximum number of worker threads in each server process
+# MaxRequestsPerChild: maximum number of connections per server process
+<IfModule perchild.c>
+NumServers 5
+StartThreads 5
+MinSpareThreads 5
+MaxSpareThreads 10
+MaxThreadsPerChild 20
+MaxRequestsPerChild 0
+</IfModule>
+
+# WinNT MPM
+# ThreadsPerChild: constant number of worker threads in the server process
+# MaxRequestsPerChild: maximum number of requests a server process serves
+<IfModule mpm_winnt.c>
+ThreadsPerChild 250
+MaxRequestsPerChild 0
+</IfModule>
+
+# BeOS MPM
+# StartThreads: how many threads do we initially spawn?
+# MaxClients: max number of threads we can have (1 thread == 1 client)
+# MaxRequestsPerThread: maximum number of requests each thread will process
+<IfModule beos.c>
+StartThreads 10
+MaxClients 50
+MaxRequestsPerThread 10000
+</IfModule>
+
+# NetWare MPM
+# ThreadStackSize: Stack size allocated for each worker thread
+# StartThreads: Number of worker threads launched at server startup
+# MinSpareThreads: Minimum number of idle threads, to handle request spikes
+# MaxSpareThreads: Maximum number of idle threads
+# MaxThreads: Maximum number of worker threads alive at the same time
+# MaxRequestsPerChild: Maximum number of requests a thread serves. It is
+# recommended that the default value of 0 be set for this
+# directive on NetWare. This will allow the thread to
+# continue to service requests indefinitely.
+<IfModule mpm_netware.c>
+ThreadStackSize 65536
+StartThreads 250
+MinSpareThreads 25
+MaxSpareThreads 250
+MaxThreads 1000
+MaxRequestsPerChild 0
+MaxMemFree 100
+</IfModule>
+
+# OS/2 MPM
+# StartServers: Number of server processes to maintain
+# MinSpareThreads: Minimum number of idle threads per process,
+# to handle request spikes
+# MaxSpareThreads: Maximum number of idle threads per process
+# MaxRequestsPerChild: Maximum number of connections per server process
+<IfModule mpmt_os2.c>
+StartServers 2
+MinSpareThreads 5
+MaxSpareThreads 10
+MaxRequestsPerChild 0
+</IfModule>
+
+#
+# Listen: Allows you to bind Apache to specific IP addresses and/or
+# ports, instead of the default. See also the <VirtualHost>
+# directive.
+#
+# Change this to Listen on specific IP addresses as shown below to
+# prevent Apache from glomming onto all bound IP addresses (0.0.0.0)
+#
+#Listen 12.34.56.78:80
+
+Listen [PORT]
+
+#
+# Dynamic Shared Object (DSO) Support
+#
+# To be able to use the functionality of a module which was built as a DSO you
+# have to place corresponding `LoadModule' lines at this location so the
+# directives contained in it are actually available _before_ they are used.
+# Statically compiled modules (those listed by `httpd -l') do not need
+# to be loaded here.
+#
+# Example:
+# LoadModule foo_module modules/mod_foo.so
+#
+
+# Required modules for command 'Order':
+[FORTITUDE_AUTH_MODULES]
+# Required module for command 'UserDir':
+LoadModule userdir_module [FORTITUDE_LIB_DIR]/modules/mod_userdir.so
+# Required module for command 'DirectoryIndex':
+LoadModule dir_module [FORTITUDE_LIB_DIR]/modules/mod_dir.so
+# Required module for command 'TypesConfig':
+LoadModule mime_module [FORTITUDE_LIB_DIR]/modules/mod_mime.so
+# Required module for command 'LogFormat':
+LoadModule log_config_module [FORTITUDE_LIB_DIR]/modules/mod_log_config.so
+# Required module for command 'Alias':
+LoadModule alias_module [FORTITUDE_LIB_DIR]/modules/mod_alias.so
+# Required module for command 'SetEnvIf':
+LoadModule setenvif_module [FORTITUDE_LIB_DIR]/modules/mod_setenvif.so
+# Required module for command 'IndexOptions':
+LoadModule autoindex_module [FORTITUDE_LIB_DIR]/modules/mod_autoindex.so
+# Required module for command 'LanguagePriority':
+LoadModule negotiation_module [FORTITUDE_LIB_DIR]/modules/mod_negotiation.so
+# Required module for command 'CGI Scripts':
+LoadModule cgi_module [FORTITUDE_LIB_DIR]/modules/mod_cgi.so
+# Required module for commands in nss.conf:
+[FORTITUDE_NSS_MODULES]
+# Required module for command 'TPSConfigPathFile':
+LoadModule tps_module [FORTITUDE_MODULE]/mod_tps.so
+# Required module for command 'TokendbConfigPathFile':
+LoadModule tokendb_module [FORTITUDE_MODULE]/mod_tokendb.so
+
+<Location /nk_service>
+ SetHandler nk_service
+</Location>
+
+<Location /tus>
+ SetHandler tus
+</Location>
+
+#
+# Load config files from the config directory "/etc/[PKI_INSTANCE_ID]/conf.d".
+#
+#Include conf.d/*.conf
+Include [SERVER_ROOT]/conf/perl.conf
+
+#
+# ExtendedStatus controls whether Apache will generate "full" status
+# information (ExtendedStatus On) or just basic information (ExtendedStatus
+# Off) when the "server-status" handler is called. The default is Off.
+#
+#ExtendedStatus On
+
+### Section 2: 'Main' server configuration
+#
+# The directives in this section set up the values used by the 'main'
+# server, which responds to any requests that aren't handled by a
+# <VirtualHost> definition. These values also provide defaults for
+# any <VirtualHost> containers you may define later in the file.
+#
+# All of these directives may appear inside <VirtualHost> containers,
+# in which case these default settings will be overridden for the
+# virtual host being defined.
+#
+
+<IfModule !mpm_winnt.c>
+<IfModule !mpm_netware.c>
+#
+# If you wish [PKI_INSTANCE_ID] to run as a different user or group, you must run
+# [PKI_INSTANCE_ID] as root initially and it will switch.
+#
+# User/Group: The name (or #number) of the user/group to run [PKI_INSTANCE_ID] as.
+# . On SCO (ODT 3) use "User nouser" and "Group nogroup".
+# . On HPUX you may not be able to use shared memory as nobody, and the
+# suggested workaround is to create a user www and use that user.
+# NOTE that some kernels refuse to setgid(Group) or semctl(IPC_SET)
+# when the value of (unsigned)Group is above 60000;
+# don't use Group #-1 on these systems!
+#
+User [PKI_USER]
+Group [PKI_GROUP]
+#Group #-1
+</IfModule>
+</IfModule>
+
+#
+# ServerAdmin: Your address, where problems with the server should be
+# e-mailed. This address appears on some server-generated pages, such
+# as error documents. e.g. admin@your-domain.com
+#
+ServerAdmin you@example.com
+
+#
+# ServerName gives the name and port that the server uses to identify itself.
+# This can often be determined automatically, but we recommend you specify
+# it explicitly to prevent problems during startup.
+#
+# If this is not set to valid DNS name for your host, server-generated
+# redirections will not work. See also the UseCanonicalName directive.
+#
+# If your host doesn't have a registered DNS name, enter its IP address here.
+# You will have to access it by its address anyway, and this will make
+# redirections work in a sensible way.
+#
+#ServerName www.example.com:80
+
+#
+# UseCanonicalName: Determines how Apache constructs self-referencing
+# URLs and the SERVER_NAME and SERVER_PORT variables.
+# When set "Off", Apache will use the Hostname and Port supplied
+# by the client. When set "On", Apache will use the value of the
+# ServerName directive.
+#
+UseCanonicalName Off
+
+#
+# DocumentRoot: The directory out of which you will serve your
+# documents. By default, all requests are taken from this directory, but
+# symbolic links and aliases may be used to point to other locations.
+#
+DocumentRoot "[SERVER_ROOT]/docroot"
+
+#
+# Each directory to which Apache has access can be configured with respect
+# to which services and features are allowed and/or disabled in that
+# directory (and its subdirectories).
+#
+# First, we configure the "default" to be a very restrictive set of
+# features.
+#
+<Directory />
+ Options FollowSymLinks
+ AllowOverride None
+</Directory>
+
+#
+# Note that from this point forward you must specifically allow
+# particular features to be enabled - so if something's not working as
+# you might expect, make sure that you have specifically enabled it
+# below.
+#
+
+#
+# This should be changed to whatever you set DocumentRoot to.
+#
+<Directory "[SERVER_ROOT]/docroot">
+
+#
+# Possible values for the Options directive are "None", "All",
+# or any combination of:
+# Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
+#
+# Note that "MultiViews" must be named *explicitly* --- "Options All"
+# doesn't give it to you.
+#
+# The Options directive is both complicated and important. Please see
+# http://httpd.apache.org/docs-2.0/mod/core.html#options
+# for more information.
+#
+ Options Indexes ExecCGI FollowSymLinks
+
+#
+# AllowOverride controls what directives may be placed in .htaccess files.
+# It can be "All", "None", or any combination of the keywords:
+# Options FileInfo AuthConfig Limit
+#
+ AllowOverride None
+
+#
+# Controls who can get stuff from this server.
+#
+ Order allow,deny
+ Allow from all
+
+</Directory>
+
+#
+# UserDir: The name of the directory that is appended onto a user's home
+# directory if a ~user request is received.
+#
+UserDir public_html
+
+#
+# Control access to UserDir directories. The following is an example
+# for a site where these directories are restricted to read-only.
+#
+#<Directory /home/*/public_html>
+# AllowOverride FileInfo AuthConfig Limit Indexes
+# Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
+# <Limit GET POST OPTIONS PROPFIND>
+# Order allow,deny
+# Allow from all
+# </Limit>
+# <LimitExcept GET POST OPTIONS PROPFIND>
+# Order deny,allow
+# Deny from all
+# </LimitExcept>
+#</Directory>
+
+#
+# DirectoryIndex: sets the file that Apache will serve if a directory
+# is requested.
+#
+# The index.html.var file (a type-map) is used to deliver content-
+# negotiated documents. The MultiViews Option can be used for the
+# same purpose, but it is much slower.
+#
+DirectoryIndex index.html index.html.var
+
+#
+# AccessFileName: The name of the file to look for in each directory
+# for additional configuration directives. See also the AllowOverride
+# directive.
+#
+AccessFileName .htaccess
+
+#
+# The following lines prevent .htaccess and .htpasswd files from being
+# viewed by Web clients.
+#
+<Files ~ "^\.ht">
+ Order allow,deny
+ Deny from all
+</Files>
+
+#
+# TypesConfig describes where the mime.types file (or equivalent) is
+# to be found.
+#
+TypesConfig conf/mime.types
+
+#
+# DefaultType is the default MIME type the server will use for a document
+# if it cannot otherwise determine one, such as from filename extensions.
+# If your server contains mostly text or HTML documents, "text/plain" is
+# a good value. If most of your content is binary, such as applications
+# or images, you may want to use "application/octet-stream" instead to
+# keep browsers from trying to display binary files as though they are
+# text.
+#
+DefaultType text/plain
+
+#
+# The mod_mime_magic module allows the server to use various hints from the
+# contents of the file itself to determine its type. The MIMEMagicFile
+# directive tells the module where the hint definitions are located.
+#
+<IfModule mod_mime_magic.c>
+ MIMEMagicFile conf/magic
+</IfModule>
+
+#
+# HostnameLookups: Log the names of clients or just their IP addresses
+# e.g., www.apache.org (on) or 204.62.129.132 (off).
+# The default is off because it'd be overall better for the net if people
+# had to knowingly turn this feature on, since enabling it means that
+# each client request will result in AT LEAST one lookup request to the
+# nameserver.
+#
+HostnameLookups Off
+
+#
+# EnableMMAP: Control whether memory-mapping is used to deliver
+# files (assuming that the underlying OS supports it).
+# The default is on; turn this off if you serve from NFS-mounted
+# filesystems. On some systems, turning it off (regardless of
+# filesystem) can improve performance; for details, please see
+# http://httpd.apache.org/docs-2.0/mod/core.html#enablemmap
+#
+#EnableMMAP off
+
+#
+# EnableSendfile: Control whether the sendfile kernel support is
+# used to deliver files (assuming that the OS supports it).
+# The default is on; turn this off if you serve from NFS-mounted
+# filesystems. Please see
+# http://httpd.apache.org/docs-2.0/mod/core.html#enablesendfile
+#
+#EnableSendfile off
+
+#
+# ErrorLog: The location of the error log file.
+# If you do not specify an ErrorLog directive within a <VirtualHost>
+# container, error messages relating to that virtual host will be
+# logged here. If you *do* define an error logfile for a <VirtualHost>
+# container, that host's errors will be logged there and not here.
+#
+ErrorLog logs/error_log
+
+#
+# LogLevel: Control the number of messages logged to the error_log.
+# Possible values include: debug, info, notice, warn, error, crit,
+# alert, emerg.
+#
+#LogLevel warn
+LogLevel debug
+
+#
+# The following directives define some format nicknames for use with
+# a CustomLog directive (see below).
+#
+LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
+LogFormat "%h %l %u %t \"%r\" %>s %b" common
+LogFormat "%{Referer}i -> %U" referer
+LogFormat "%{User-agent}i" agent
+
+# You need to enable mod_logio.c to use %I and %O
+#LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
+
+#
+# The location and format of the access logfile (Common Logfile Format).
+# If you do not define any access logfiles within a <VirtualHost>
+# container, they will be logged here. Contrariwise, if you *do*
+# define per-<VirtualHost> access logfiles, transactions will be
+# logged therein and *not* in this file.
+#
+CustomLog logs/access_log common
+
+#
+# If you would like to have agent and referer logfiles, uncomment the
+# following directives.
+#
+#CustomLog logs/referer_log referer
+#CustomLog logs/agent_log agent
+
+#
+# If you prefer a single logfile with access, agent, and referer information
+# (Combined Logfile Format) you can use the following directive.
+#
+#CustomLog logs/access_log combined
+
+#
+# ServerTokens
+# This directive configures what you return as the Server HTTP response
+# Header. The default is 'Full' which sends information about the OS-Type
+# and compiled in modules.
+# Set to one of: Full | OS | Minor | Minimal | Major | Prod
+# where Full conveys the most information, and Prod the least.
+#
+ServerTokens Prod
+
+#
+# Optionally add a line containing the server version and virtual host
+# name to server-generated pages (internal error documents, FTP directory
+# listings, mod_status and mod_info output etc., but not CGI generated
+# documents or custom error documents).
+# Set to "EMail" to also include a mailto: link to the ServerAdmin.
+# Set to one of: On | Off | EMail
+#
+ServerSignature Off
+
+#
+# Aliases: Add here as many aliases as you need (with no limit). The format is
+# Alias fakename realname
+#
+# Note that if you include a trailing / on fakename then the server will
+# require it to be present in the URL. So "/icons" isn't aliased in this
+# example, only "/icons/". If the fakename is slash-terminated, then the
+# realname must also be slash terminated, and if the fakename omits the
+# trailing slash, the realname must also omit it.
+#
+# We include the /icons/ alias for FancyIndexed directory listings. If you
+# do not use FancyIndexing, you may comment this out.
+#
+Alias /icons/ "[SERVER_ROOT]/icons/"
+
+<Directory "[SERVER_ROOT]/icons">
+ Options Indexes MultiViews
+ AllowOverride None
+ Order allow,deny
+ Allow from all
+</Directory>
+
+#
+# This should be changed to the ServerRoot/manual/. The alias provides
+# the manual, even if you choose to move your DocumentRoot. You may comment
+# this out if you do not care for the documentation.
+#
+AliasMatch ^/manual(?:/(?:de|en|es|fr|ja|ko|ru))?(/.*)?$ "[SERVER_ROOT]/manual$1"
+
+<Directory "[SERVER_ROOT]/manual">
+ Options Indexes
+ AllowOverride None
+ Order allow,deny
+ Allow from all
+
+ <Files *.html>
+ SetHandler type-map
+ </Files>
+
+ SetEnvIf Request_URI ^/manual/(de|en|es|fr|ja|ko|ru)/ prefer-language=$1
+ RedirectMatch 301 ^/manual(?:/(de|en|es|fr|ja|ko|ru)){2,}(/.*)?$ /manual/$1$2
+</Directory>
+
+#
+# ScriptAlias: This controls which directories contain server scripts.
+# ScriptAliases are essentially the same as Aliases, except that
+# documents in the realname directory are treated as applications and
+# run by the server when requested rather than as documents sent to the client.
+# The same rules about trailing "/" apply to ScriptAlias directives as to
+# Alias.
+#
+ScriptAlias /cgi-bin/ "[SERVER_ROOT]/cgi-bin/"
+
+<IfModule mod_cgid.c>
+#
+# Additional to mod_cgid.c settings, mod_cgid has Scriptsock <path>
+# for setting UNIX socket for communicating with cgid.
+#
+#Scriptsock logs/cgisock
+</IfModule>
+
+#
+# "[SERVER_ROOT]/cgi-bin" should be changed to whatever your ScriptAliased
+# CGI directory exists, if you have that configured.
+#
+<Directory "[SERVER_ROOT]/cgi-bin">
+ AllowOverride None
+ Options ExecCGI
+ Order allow,deny
+ Allow from all
+</Directory>
+
+#
+# Redirect allows you to tell clients about documents which used to exist in
+# your server's namespace, but do not anymore. This allows you to tell the
+# clients where to look for the relocated document.
+# Example:
+# Redirect permanent /foo http://www.example.com/bar
+
+#
+# Directives controlling the display of server-generated directory listings.
+#
+
+#
+# IndexOptions: Controls the appearance of server-generated directory
+# listings.
+#
+IndexOptions FancyIndexing VersionSort
+
+#
+# AddIcon* directives tell the server which icon to show for different
+# files or filename extensions. These are only displayed for
+# FancyIndexed directories.
+#
+AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip
+
+AddIconByType (TXT,/icons/text.gif) text/*
+AddIconByType (IMG,/icons/image2.gif) image/*
+AddIconByType (SND,/icons/sound2.gif) audio/*
+AddIconByType (VID,/icons/movie.gif) video/*
+
+AddIcon /icons/binary.gif .bin .exe
+AddIcon /icons/binhex.gif .hqx
+AddIcon /icons/tar.gif .tar
+AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv
+AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip
+AddIcon /icons/a.gif .ps .ai .eps
+AddIcon /icons/layout.gif .html .shtml .htm .pdf
+AddIcon /icons/text.gif .txt
+AddIcon /icons/c.gif .c
+AddIcon /icons/p.gif .pl .py
+AddIcon /icons/f.gif .for
+AddIcon /icons/dvi.gif .dvi
+AddIcon /icons/uuencoded.gif .uu
+AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
+AddIcon /icons/tex.gif .tex
+AddIcon /icons/bomb.gif core
+
+AddIcon /icons/back.gif ..
+AddIcon /icons/hand.right.gif README
+AddIcon /icons/folder.gif ^^DIRECTORY^^
+AddIcon /icons/blank.gif ^^BLANKICON^^
+
+#
+# DefaultIcon is which icon to show for files which do not have an icon
+# explicitly set.
+#
+DefaultIcon /icons/unknown.gif
+
+#
+# AddDescription allows you to place a short description after a file in
+# server-generated indexes. These are only displayed for FancyIndexed
+# directories.
+# Format: AddDescription "description" filename
+#
+#AddDescription "GZIP compressed document" .gz
+#AddDescription "tar archive" .tar
+#AddDescription "GZIP compressed tar archive" .tgz
+
+#
+# ReadmeName is the name of the README file the server will look for by
+# default, and append to directory listings.
+#
+# HeaderName is the name of a file which should be prepended to
+# directory indexes.
+ReadmeName README.html
+HeaderName HEADER.html
+
+#
+# IndexIgnore is a set of filenames which directory indexing should ignore
+# and not include in the listing. Shell-style wildcarding is permitted.
+#
+IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t
+
+#
+# DefaultLanguage and AddLanguage allows you to specify the language of
+# a document. You can then use content negotiation to give a browser a
+# file in a language the user can understand.
+#
+# Specify a default language. This means that all data
+# going out without a specific language tag (see below) will
+# be marked with this one. You probably do NOT want to set
+# this unless you are sure it is correct for all cases.
+#
+# * It is generally better to not mark a page as
+# * being a certain language than marking it with the wrong
+# * language!
+#
+# DefaultLanguage nl
+#
+# Note 1: The suffix does not have to be the same as the language
+# keyword --- those with documents in Polish (whose net-standard
+# language code is pl) may wish to use "AddLanguage pl .po" to
+# avoid the ambiguity with the common suffix for perl scripts.
+#
+# Note 2: The example entries below illustrate that in some cases
+# the two character 'Language' abbreviation is not identical to
+# the two character 'Country' code for its country,
+# E.g. 'Danmark/dk' versus 'Danish/da'.
+#
+# Note 3: In the case of 'ltz' we violate the RFC by using a three char
+# specifier. There is 'work in progress' to fix this and get
+# the reference data for rfc1766 cleaned up.
+#
+# Catalan (ca) - Croatian (hr) - Czech (cs) - Danish (da) - Dutch (nl)
+# English (en) - Esperanto (eo) - Estonian (et) - French (fr) - German (de)
+# Greek-Modern (el) - Hebrew (he) - Italian (it) - Japanese (ja)
+# Korean (ko) - Luxembourgeois* (ltz) - Norwegian Nynorsk (nn)
+# Norwegian (no) - Polish (pl) - Portugese (pt)
+# Brazilian Portuguese (pt-BR) - Russian (ru) - Swedish (sv)
+# Simplified Chinese (zh-CN) - Spanish (es) - Traditional Chinese (zh-TW)
+#
+AddLanguage ca .ca
+AddLanguage cs .cz .cs
+AddLanguage da .dk
+AddLanguage de .de
+AddLanguage el .el
+AddLanguage en .en
+AddLanguage eo .eo
+AddLanguage es .es
+AddLanguage et .et
+AddLanguage fr .fr
+AddLanguage he .he
+AddLanguage hr .hr
+AddLanguage it .it
+AddLanguage ja .ja
+AddLanguage ko .ko
+AddLanguage ltz .ltz
+AddLanguage nl .nl
+AddLanguage nn .nn
+AddLanguage no .no
+AddLanguage pl .po
+AddLanguage pt .pt
+AddLanguage pt-BR .pt-br
+AddLanguage ru .ru
+AddLanguage sv .sv
+AddLanguage zh-CN .zh-cn
+AddLanguage zh-TW .zh-tw
+
+#
+# LanguagePriority allows you to give precedence to some languages
+# in case of a tie during content negotiation.
+#
+# Just list the languages in decreasing order of preference. We have
+# more or less alphabetized them here. You probably want to change this.
+#
+LanguagePriority en ca cs da de el eo es et fr he hr it ja ko ltz nl nn no pl pt pt-BR ru sv zh-CN zh-TW
+
+#
+# ForceLanguagePriority allows you to serve a result page rather than
+# MULTIPLE CHOICES (Prefer) [in case of a tie] or NOT ACCEPTABLE (Fallback)
+# [in case no accepted languages matched the available variants]
+#
+ForceLanguagePriority Prefer Fallback
+
+#
+# Commonly used filename extensions to character sets. You probably
+# want to avoid clashes with the language extensions, unless you
+# are good at carefully testing your setup after each change.
+# See http://www.iana.org/assignments/character-sets for the
+# official list of charset names and their respective RFCs.
+#
+AddCharset ISO-8859-1 .iso8859-1 .latin1
+AddCharset ISO-8859-2 .iso8859-2 .latin2 .cen
+AddCharset ISO-8859-3 .iso8859-3 .latin3
+AddCharset ISO-8859-4 .iso8859-4 .latin4
+AddCharset ISO-8859-5 .iso8859-5 .latin5 .cyr .iso-ru
+AddCharset ISO-8859-6 .iso8859-6 .latin6 .arb
+AddCharset ISO-8859-7 .iso8859-7 .latin7 .grk
+AddCharset ISO-8859-8 .iso8859-8 .latin8 .heb
+AddCharset ISO-8859-9 .iso8859-9 .latin9 .trk
+AddCharset ISO-2022-JP .iso2022-jp .jis
+AddCharset ISO-2022-KR .iso2022-kr .kis
+AddCharset ISO-2022-CN .iso2022-cn .cis
+AddCharset Big5 .Big5 .big5
+# For russian, more than one charset is used (depends on client, mostly):
+AddCharset WINDOWS-1251 .cp-1251 .win-1251
+AddCharset CP866 .cp866
+AddCharset KOI8-r .koi8-r .koi8-ru
+AddCharset KOI8-ru .koi8-uk .ua
+AddCharset ISO-10646-UCS-2 .ucs2
+AddCharset ISO-10646-UCS-4 .ucs4
+AddCharset UTF-8 .utf8
+
+# The set below does not map to a specific (iso) standard
+# but works on a fairly wide range of browsers. Note that
+# capitalization actually matters (it should not, but it
+# does for some browsers).
+#
+# See http://www.iana.org/assignments/character-sets
+# for a list of sorts. But browsers support few.
+#
+AddCharset GB2312 .gb2312 .gb
+AddCharset utf-7 .utf7
+AddCharset utf-8 .utf8
+AddCharset big5 .big5 .b5
+AddCharset EUC-TW .euc-tw
+AddCharset EUC-JP .euc-jp
+AddCharset EUC-KR .euc-kr
+AddCharset shift_jis .sjis
+
+#
+# AddType allows you to add to or override the MIME configuration
+# file mime.types for specific file types.
+#
+#AddType application/x-tar .tgz
+#
+# AddEncoding allows you to have certain browsers uncompress
+# information on the fly. Note: Not all browsers support this.
+# Despite the name similarity, the following Add* directives have nothing
+# to do with the FancyIndexing customization directives above.
+#
+#AddEncoding x-compress .Z
+#AddEncoding x-gzip .gz .tgz
+#
+# If the AddEncoding directives above are commented-out, then you
+# probably should define those extensions to indicate media types:
+#
+AddType application/x-compress .Z
+AddType application/x-gzip .gz .tgz
+
+#
+# AddHandler allows you to map certain file extensions to "handlers":
+# actions unrelated to filetype. These can be either built into the server
+# or added with the Action directive (see below)
+#
+# To use CGI scripts outside of ScriptAliased directories:
+# (You will also need to add "ExecCGI" to the "Options" directive.)
+#
+AddHandler cgi-script .cgi
+
+#
+# For files that include their own HTTP headers:
+#
+#AddHandler send-as-is asis
+
+#
+# For server-parsed imagemap files:
+#
+#AddHandler imap-file map
+
+#
+# For type maps (negotiated resources):
+# (This is enabled by default to allow the Apache "It Worked" page
+# to be distributed in multiple languages.)
+#
+AddHandler type-map var
+
+#
+# Filters allow you to process content before it is sent to the client.
+#
+# To parse .shtml files for server-side includes (SSI):
+# (You will also need to add "Includes" to the "Options" directive.)
+#
+#AddType text/html .shtml
+#AddOutputFilter INCLUDES .shtml
+
+#
+# Action lets you define media types that will execute a script whenever
+# a matching file is called. This eliminates the need for repeated URL
+# pathnames for oft-used CGI file processors.
+# Format: Action media/type /cgi-script/location
+# Format: Action handler-name /cgi-script/location
+#
+
+#
+# Customizable error responses come in three flavors:
+# 1) plain text 2) local redirects 3) external redirects
+#
+# Some examples:
+#ErrorDocument 500 "The server made a boo boo."
+#ErrorDocument 404 /missing.html
+#ErrorDocument 404 "/cgi-bin/missing_handler.pl"
+#ErrorDocument 402 http://www.example.com/subscription_info.html
+#
+
+#
+# Putting this all together, we can internationalize error responses.
+#
+# We use Alias to redirect any /error/HTTP_<error>.html.var response to
+# our collection of by-error message multi-language collections. We use
+# includes to substitute the appropriate text.
+#
+# You can modify the messages' appearance without changing any of the
+# default HTTP_<error>.html.var files by adding the line:
+#
+# Alias /error/include/ "/your/include/path/"
+#
+# which allows you to create your own set of files by starting with the
+# /export/apache/error/include/ files and copying them to /your/include/path/,
+# even on a per-VirtualHost basis. The default include files will display
+# your Apache version number and your ServerAdmin email address regardless
+# of the setting of ServerSignature.
+#
+# The internationalized error documents require mod_alias, mod_include
+# and mod_negotiation. To activate them, uncomment the following 30 lines.
+
+# Alias /error/ "/export/apache/error/"
+#
+# <Directory "/export/apache/error">
+# AllowOverride None
+# Options IncludesNoExec
+# AddOutputFilter Includes html
+# AddHandler type-map var
+# Order allow,deny
+# Allow from all
+# LanguagePriority en cs de es fr it ja ko nl pl pt-br ro sv tr
+# ForceLanguagePriority Prefer Fallback
+# </Directory>
+#
+# ErrorDocument 400 /error/HTTP_BAD_REQUEST.html.var
+# ErrorDocument 401 /error/HTTP_UNAUTHORIZED.html.var
+# ErrorDocument 403 /error/HTTP_FORBIDDEN.html.var
+# ErrorDocument 404 /error/HTTP_NOT_FOUND.html.var
+# ErrorDocument 405 /error/HTTP_METHOD_NOT_ALLOWED.html.var
+# ErrorDocument 408 /error/HTTP_REQUEST_TIME_OUT.html.var
+# ErrorDocument 410 /error/HTTP_GONE.html.var
+# ErrorDocument 411 /error/HTTP_LENGTH_REQUIRED.html.var
+# ErrorDocument 412 /error/HTTP_PRECONDITION_FAILED.html.var
+# ErrorDocument 413 /error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.var
+# ErrorDocument 414 /error/HTTP_REQUEST_URI_TOO_LARGE.html.var
+# ErrorDocument 415 /error/HTTP_UNSUPPORTED_MEDIA_TYPE.html.var
+# ErrorDocument 500 /error/HTTP_INTERNAL_SERVER_ERROR.html.var
+# ErrorDocument 501 /error/HTTP_NOT_IMPLEMENTED.html.var
+# ErrorDocument 502 /error/HTTP_BAD_GATEWAY.html.var
+# ErrorDocument 503 /error/HTTP_SERVICE_UNAVAILABLE.html.var
+# ErrorDocument 506 /error/HTTP_VARIANT_ALSO_VARIES.html.var
+#[ErrorDocument_404]
+#[ErrorDocument_500]
+
+
+#
+# The following directives modify normal HTTP response behavior to
+# handle known problems with browser implementations.
+#
+BrowserMatch "Mozilla/2" nokeepalive
+BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
+BrowserMatch "RealPlayer 4\.0" force-response-1.0
+BrowserMatch "Java/1\.0" force-response-1.0
+BrowserMatch "JDK/1\.0" force-response-1.0
+
+#
+# The following directive disables redirects on non-GET requests for
+# a directory that does not include the trailing slash. This fixes a
+# problem with Microsoft WebFolders which does not appropriately handle
+# redirects for folders with DAV methods.
+# Same deal with Apple's DAV filesystem and Gnome VFS support for DAV.
+#
+BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully
+BrowserMatch "^WebDrive" redirect-carefully
+BrowserMatch "^WebDAVFS/1.[012]" redirect-carefully
+BrowserMatch "^gnome-vfs" redirect-carefully
+
+#
+# Allow server status reports generated by mod_status,
+# with the URL of http://servername/server-status
+# Change the ".example.com" to match your domain to enable.
+#
+#<Location /server-status>
+# SetHandler server-status
+# Order deny,allow
+# Deny from all
+# Allow from .example.com
+#</Location>
+
+#
+# Allow remote server configuration reports, with the URL of
+# http://servername/server-info (requires that mod_info.c be loaded).
+# Change the ".example.com" to match your domain to enable.
+#
+#<Location /server-info>
+# SetHandler server-info
+# Order deny,allow
+# Deny from all
+# Allow from .example.com
+#</Location>
+
+
+#
+# Bring in additional module-specific configurations
+#
+#<IfModule mod_ssl.c>
+# Include conf/ssl.conf
+#</IfModule>
+Include [SERVER_ROOT]/conf/nss.conf
+
+TPSConfigPathFile [SERVER_ROOT]/conf/CS.cfg
+
+TokendbConfigPathFile [SERVER_ROOT]/conf/CS.cfg
+
+### Section 3: Virtual Hosts
+#
+# VirtualHost: If you want to maintain multiple domains/hostnames on your
+# machine you can setup VirtualHost containers for them. Most configurations
+# use only name-based virtual hosts so the server doesn't need to worry about
+# IP addresses. This is indicated by the asterisks in the directives below.
+#
+# Please see the documentation at
+# <URL:http://httpd.apache.org/docs-2.0/vhosts/>
+# for further details before you try to setup virtual hosts.
+#
+# You may use the command line option '-S' to verify your virtual host
+# configuration.
+
+#
+# Use name-based virtual hosting.
+#
+#NameVirtualHost *:80
+
+#
+# VirtualHost example:
+# Almost any Apache directive may go into a VirtualHost container.
+# The first VirtualHost section is used for requests without a known
+# server name.
+#
+#<VirtualHost *:80>
+# ServerAdmin webmaster@dummy-host.example.com
+# DocumentRoot /www/docs/dummy-host.example.com
+# ServerName dummy-host.example.com
+# ErrorLog logs/dummy-host.example.com-error_log
+# CustomLog logs/dummy-host.example.com-access_log common
+#</VirtualHost>
+
+#turn off TRACE by default
+TraceEnable Off
diff --git a/base/tps/apache/conf/magic b/base/tps/apache/conf/magic
new file mode 100644
index 000000000..0de73361f
--- /dev/null
+++ b/base/tps/apache/conf/magic
@@ -0,0 +1,382 @@
+# Magic data for mod_mime_magic Apache module (originally for file(1) command)
+# The module is described in /manual/mod/mod_mime_magic.html
+#
+# The format is 4-5 columns:
+# Column #1: byte number to begin checking from, ">" indicates continuation
+# Column #2: type of data to match
+# Column #3: contents of data to match
+# Column #4: MIME type of result
+# Column #5: MIME encoding of result (optional)
+
+#------------------------------------------------------------------------------
+# Localstuff: file(1) magic for locally observed files
+# Add any locally observed files here.
+
+#------------------------------------------------------------------------------
+# end local stuff
+#------------------------------------------------------------------------------
+
+#------------------------------------------------------------------------------
+# Java
+
+0 short 0xcafe
+>2 short 0xbabe application/java
+
+#------------------------------------------------------------------------------
+# audio: file(1) magic for sound formats
+#
+# from Jan Nicolai Langfeldt <janl@ifi.uio.no>,
+#
+
+# Sun/NeXT audio data
+0 string .snd
+>12 belong 1 audio/basic
+>12 belong 2 audio/basic
+>12 belong 3 audio/basic
+>12 belong 4 audio/basic
+>12 belong 5 audio/basic
+>12 belong 6 audio/basic
+>12 belong 7 audio/basic
+
+>12 belong 23 audio/x-adpcm
+
+# DEC systems (e.g. DECstation 5000) use a variant of the Sun/NeXT format
+# that uses little-endian encoding and has a different magic number
+# (0x0064732E in little-endian encoding).
+0 lelong 0x0064732E
+>12 lelong 1 audio/x-dec-basic
+>12 lelong 2 audio/x-dec-basic
+>12 lelong 3 audio/x-dec-basic
+>12 lelong 4 audio/x-dec-basic
+>12 lelong 5 audio/x-dec-basic
+>12 lelong 6 audio/x-dec-basic
+>12 lelong 7 audio/x-dec-basic
+# compressed (G.721 ADPCM)
+>12 lelong 23 audio/x-dec-adpcm
+
+# Bytes 0-3 of AIFF, AIFF-C, & 8SVX audio files are "FORM"
+# AIFF audio data
+8 string AIFF audio/x-aiff
+# AIFF-C audio data
+8 string AIFC audio/x-aiff
+# IFF/8SVX audio data
+8 string 8SVX audio/x-aiff
+
+# Creative Labs AUDIO stuff
+# Standard MIDI data
+0 string MThd audio/unknown
+#>9 byte >0 (format %d)
+#>11 byte >1 using %d channels
+# Creative Music (CMF) data
+0 string CTMF audio/unknown
+# SoundBlaster instrument data
+0 string SBI audio/unknown
+# Creative Labs voice data
+0 string Creative\ Voice\ File audio/unknown
+## is this next line right? it came this way...
+#>19 byte 0x1A
+#>23 byte >0 - version %d
+#>22 byte >0 \b.%d
+
+# [GRR 950115: is this also Creative Labs? Guessing that first line
+# should be string instead of unknown-endian long...]
+#0 long 0x4e54524b MultiTrack sound data
+#0 string NTRK MultiTrack sound data
+#>4 long x - version %ld
+
+# Microsoft WAVE format (*.wav)
+# [GRR 950115: probably all of the shorts and longs should be leshort/lelong]
+# Microsoft RIFF
+0 string RIFF audio/unknown
+# - WAVE format
+>8 string WAVE audio/x-wav
+# MPEG audio.
+0 beshort&0xfff0 0xfff0 audio/mpeg
+# C64 SID Music files, from Linus Walleij <triad@df.lth.se>
+0 string PSID audio/prs.sid
+
+#------------------------------------------------------------------------------
+# c-lang: file(1) magic for C programs or various scripts
+#
+
+# XPM icons (Greg Roelofs, newt@uchicago.edu)
+# ideally should go into "images", but entries below would tag XPM as C source
+0 string /*\ XPM image/x-xbm 7bit
+
+# this first will upset you if you're a PL/1 shop... (are there any left?)
+# in which case rm it; ascmagic will catch real C programs
+# C or REXX program text
+0 string /* text/plain
+# C++ program text
+0 string // text/plain
+
+#------------------------------------------------------------------------------
+# compress: file(1) magic for pure-compression formats (no archives)
+#
+# compress, gzip, pack, compact, huf, squeeze, crunch, freeze, yabba, whap, etc.
+#
+# Formats for various forms of compressed data
+# Formats for "compress" proper have been moved into "compress.c",
+# because it tries to uncompress it to figure out what's inside.
+
+# standard unix compress
+0 string \037\235 application/octet-stream x-compress
+
+# gzip (GNU zip, not to be confused with [Info-ZIP/PKWARE] zip archiver)
+0 string \037\213 application/octet-stream x-gzip
+
+# According to gzip.h, this is the correct byte order for packed data.
+0 string \037\036 application/octet-stream
+#
+# This magic number is byte-order-independent.
+#
+0 short 017437 application/octet-stream
+
+# XXX - why *two* entries for "compacted data", one of which is
+# byte-order independent, and one of which is byte-order dependent?
+#
+# compacted data
+0 short 0x1fff application/octet-stream
+0 string \377\037 application/octet-stream
+# huf output
+0 short 0145405 application/octet-stream
+
+# Squeeze and Crunch...
+# These numbers were gleaned from the Unix versions of the programs to
+# handle these formats. Note that I can only uncrunch, not crunch, and
+# I didn't have a crunched file handy, so the crunch number is untested.
+# Keith Waclena <keith@cerberus.uchicago.edu>
+#0 leshort 0x76FF squeezed data (CP/M, DOS)
+#0 leshort 0x76FE crunched data (CP/M, DOS)
+
+# Freeze
+#0 string \037\237 Frozen file 2.1
+#0 string \037\236 Frozen file 1.0 (or gzip 0.5)
+
+# lzh?
+#0 string \037\240 LZH compressed data
+
+#------------------------------------------------------------------------------
+# frame: file(1) magic for FrameMaker files
+#
+# This stuff came on a FrameMaker demo tape, most of which is
+# copyright, but this file is "published" as witness the following:
+#
+0 string \<MakerFile application/x-frame
+0 string \<MIFFile application/x-frame
+0 string \<MakerDictionary application/x-frame
+0 string \<MakerScreenFon application/x-frame
+0 string \<MML application/x-frame
+0 string \<Book application/x-frame
+0 string \<Maker application/x-frame
+
+#------------------------------------------------------------------------------
+# html: file(1) magic for HTML (HyperText Markup Language) docs
+#
+# from Daniel Quinlan <quinlan@yggdrasil.com>
+# and Anna Shergold <anna@inext.co.uk>
+#
+0 string \<!DOCTYPE\ HTML text/html
+0 string \<!doctype\ html text/html
+0 string \<HEAD text/html
+0 string \<head text/html
+0 string \<TITLE text/html
+0 string \<title text/html
+0 string \<html text/html
+0 string \<HTML text/html
+0 string \<!-- text/html
+0 string \<h1 text/html
+0 string \<H1 text/html
+
+# XML eXtensible Markup Language, from Linus Walleij <triad@df.lth.se>
+0 string \<?xml text/xml
+
+#------------------------------------------------------------------------------
+# images: file(1) magic for image formats (see also "c-lang" for XPM bitmaps)
+#
+# originally from jef@helios.ee.lbl.gov (Jef Poskanzer),
+# additions by janl@ifi.uio.no as well as others. Jan also suggested
+# merging several one- and two-line files into here.
+#
+# XXX - byte order for GIF and TIFF fields?
+# [GRR: TIFF allows both byte orders; GIF is probably little-endian]
+#
+
+# [GRR: what the hell is this doing in here?]
+#0 string xbtoa btoa'd file
+
+# PBMPLUS
+# PBM file
+0 string P1 image/x-portable-bitmap 7bit
+# PGM file
+0 string P2 image/x-portable-greymap 7bit
+# PPM file
+0 string P3 image/x-portable-pixmap 7bit
+# PBM "rawbits" file
+0 string P4 image/x-portable-bitmap
+# PGM "rawbits" file
+0 string P5 image/x-portable-greymap
+# PPM "rawbits" file
+0 string P6 image/x-portable-pixmap
+
+# NIFF (Navy Interchange File Format, a modification of TIFF)
+# [GRR: this *must* go before TIFF]
+0 string IIN1 image/x-niff
+
+# TIFF and friends
+# TIFF file, big-endian
+0 string MM image/tiff
+# TIFF file, little-endian
+0 string II image/tiff
+
+# possible GIF replacements; none yet released!
+# (Greg Roelofs, newt@uchicago.edu)
+#
+# GRR 950115: this was mine ("Zip GIF"):
+# ZIF image (GIF+deflate alpha)
+0 string GIF94z image/unknown
+#
+# GRR 950115: this is Jeremy Wohl's Free Graphics Format (better):
+# FGF image (GIF+deflate beta)
+0 string FGF95a image/unknown
+#
+# GRR 950115: this is Thomas Boutell's Portable Bitmap Format proposal
+# (best; not yet implemented):
+# PBF image (deflate compression)
+0 string PBF image/unknown
+
+# GIF
+0 string GIF image/gif
+
+# JPEG images
+0 beshort 0xffd8 image/jpeg
+
+# PC bitmaps (OS/2, Windoze BMP files) (Greg Roelofs, newt@uchicago.edu)
+0 string BM image/bmp
+#>14 byte 12 (OS/2 1.x format)
+#>14 byte 64 (OS/2 2.x format)
+#>14 byte 40 (Windows 3.x format)
+#0 string IC icon
+#0 string PI pointer
+#0 string CI color icon
+#0 string CP color pointer
+#0 string BA bitmap array
+
+
+#------------------------------------------------------------------------------
+# lisp: file(1) magic for lisp programs
+#
+# various lisp types, from Daniel Quinlan (quinlan@yggdrasil.com)
+0 string ;; text/plain 8bit
+# Emacs 18 - this is always correct, but not very magical.
+0 string \012( application/x-elc
+# Emacs 19
+0 string ;ELC\023\000\000\000 application/x-elc
+
+#------------------------------------------------------------------------------
+# mail.news: file(1) magic for mail and news
+#
+# There are tests to ascmagic.c to cope with mail and news.
+0 string Relay-Version: message/rfc822 7bit
+0 string #!\ rnews message/rfc822 7bit
+0 string N#!\ rnews message/rfc822 7bit
+0 string Forward\ to message/rfc822 7bit
+0 string Pipe\ to message/rfc822 7bit
+0 string Return-Path: message/rfc822 7bit
+0 string Path: message/news 8bit
+0 string Xref: message/news 8bit
+0 string From: message/rfc822 7bit
+0 string Article message/news 8bit
+#------------------------------------------------------------------------------
+# msword: file(1) magic for MS Word files
+#
+# Contributor claims:
+# Reversed-engineered MS Word magic numbers
+#
+
+0 string \376\067\0\043 application/msword
+0 string \333\245-\0\0\0 application/msword
+
+# disable this one because it applies also to other
+# Office/OLE documents for which msword is not correct. See PR#2608.
+#0 string \320\317\021\340\241\261 application/msword
+
+
+
+#------------------------------------------------------------------------------
+# printer: file(1) magic for printer-formatted files
+#
+
+# PostScript
+0 string %! application/postscript
+0 string \004%! application/postscript
+
+# Acrobat
+# (due to clamen@cs.cmu.edu)
+0 string %PDF- application/pdf
+
+#------------------------------------------------------------------------------
+# sc: file(1) magic for "sc" spreadsheet
+#
+38 string Spreadsheet application/x-sc
+
+#------------------------------------------------------------------------------
+# tex: file(1) magic for TeX files
+#
+# XXX - needs byte-endian stuff (big-endian and little-endian DVI?)
+#
+# From <conklin@talisman.kaleida.com>
+
+# Although we may know the offset of certain text fields in TeX DVI
+# and font files, we can't use them reliably because they are not
+# zero terminated. [but we do anyway, christos]
+0 string \367\002 application/x-dvi
+#0 string \367\203 TeX generic font data
+#0 string \367\131 TeX packed font data
+#0 string \367\312 TeX virtual font data
+#0 string This\ is\ TeX, TeX transcript text
+#0 string This\ is\ METAFONT, METAFONT transcript text
+
+# There is no way to detect TeX Font Metric (*.tfm) files without
+# breaking them apart and reading the data. The following patterns
+# match most *.tfm files generated by METAFONT or afm2tfm.
+#2 string \000\021 TeX font metric data
+#2 string \000\022 TeX font metric data
+#>34 string >\0 (%s)
+
+# Texinfo and GNU Info, from Daniel Quinlan (quinlan@yggdrasil.com)
+#0 string \\input\ texinfo Texinfo source text
+#0 string This\ is\ Info\ file GNU Info text
+
+# correct TeX magic for Linux (and maybe more)
+# from Peter Tobias (tobias@server.et-inf.fho-emden.de)
+#
+0 leshort 0x02f7 application/x-dvi
+
+# RTF - Rich Text Format
+0 string {\\rtf application/rtf
+
+#------------------------------------------------------------------------------
+# animation: file(1) magic for animation/movie formats
+#
+# animation formats, originally from vax@ccwf.cc.utexas.edu (VaX#n8)
+# MPEG file
+0 string \000\000\001\263 video/mpeg
+#
+# The contributor claims:
+# I couldn't find a real magic number for these, however, this
+# -appears- to work. Note that it might catch other files, too,
+# so BE CAREFUL!
+#
+# Note that title and author appear in the two 20-byte chunks
+# at decimal offsets 2 and 22, respectively, but they are XOR'ed with
+# 255 (hex FF)! DL format SUCKS BIG ROCKS.
+#
+# DL file version 1 , medium format (160x100, 4 images/screen)
+0 byte 1 video/unknown
+0 byte 2 video/unknown
+# Quicktime video, from Linus Walleij <triad@df.lth.se>
+# from Apple quicktime file format documentation.
+4 string moov video/quicktime
+4 string mdat video/quicktime
+
diff --git a/base/tps/apache/conf/mime.types b/base/tps/apache/conf/mime.types
new file mode 100644
index 000000000..3485692d1
--- /dev/null
+++ b/base/tps/apache/conf/mime.types
@@ -0,0 +1,592 @@
+# This is a comment. I love comments.
+
+# This file controls what Internet media types are sent to the client for
+# given file extension(s). Sending the correct media type to the client
+# is important so they know how to handle the content of the file.
+# Extra types can either be added here or by using an AddType directive
+# in your config files. For more information about Internet media types,
+# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type
+# registry is at <http://www.iana.org/assignments/media-types/>.
+
+# MIME type Extensions
+application/activemessage
+application/andrew-inset ez
+application/applefile
+application/atom+xml atom
+application/atomicmail
+application/batch-smtp
+application/beep+xml
+application/cals-1840
+application/cnrp+xml
+application/commonground
+application/cpl+xml
+application/cybercash
+application/dca-rft
+application/dec-dx
+application/dvcs
+application/edi-consent
+application/edifact
+application/edi-x12
+application/eshop
+application/font-tdpfr
+application/http
+application/hyperstudio
+application/iges
+application/index
+application/index.cmd
+application/index.obj
+application/index.response
+application/index.vnd
+application/iotp
+application/ipp
+application/isup
+application/mac-binhex40 hqx
+application/mac-compactpro cpt
+application/macwriteii
+application/marc
+application/mathematica
+application/mathml+xml mathml
+application/msword doc
+application/news-message-id
+application/news-transmission
+application/ocsp-request
+application/ocsp-response
+application/octet-stream bin dms lha lzh exe class so dll dmg
+application/oda oda
+application/ogg ogg
+application/parityfec
+application/pdf pdf
+application/pgp-encrypted
+application/pgp-keys
+application/pgp-signature
+application/pkcs10
+application/pkcs7-mime
+application/pkcs7-signature
+application/pkix-cert
+application/pkix-crl
+application/pkixcmp
+application/postscript ai eps ps
+application/prs.alvestrand.titrax-sheet
+application/prs.cww
+application/prs.nprend
+application/prs.plucker
+application/qsig
+application/rdf+xml rdf
+application/reginfo+xml
+application/remote-printing
+application/riscos
+application/rtf
+application/sdp
+application/set-payment
+application/set-payment-initiation
+application/set-registration
+application/set-registration-initiation
+application/sgml
+application/sgml-open-catalog
+application/sieve
+application/slate
+application/smil smi smil
+application/srgs gram
+application/srgs+xml grxml
+application/timestamp-query
+application/timestamp-reply
+application/tve-trigger
+application/vemmi
+application/vnd.3gpp.pic-bw-large
+application/vnd.3gpp.pic-bw-small
+application/vnd.3gpp.pic-bw-var
+application/vnd.3gpp.sms
+application/vnd.3m.post-it-notes
+application/vnd.accpac.simply.aso
+application/vnd.accpac.simply.imp
+application/vnd.acucobol
+application/vnd.acucorp
+application/vnd.adobe.xfdf
+application/vnd.aether.imp
+application/vnd.amiga.ami
+application/vnd.anser-web-certificate-issue-initiation
+application/vnd.anser-web-funds-transfer-initiation
+application/vnd.audiograph
+application/vnd.blueice.multipass
+application/vnd.bmi
+application/vnd.businessobjects
+application/vnd.canon-cpdl
+application/vnd.canon-lips
+application/vnd.cinderella
+application/vnd.claymore
+application/vnd.commerce-battelle
+application/vnd.commonspace
+application/vnd.contact.cmsg
+application/vnd.cosmocaller
+application/vnd.criticaltools.wbs+xml
+application/vnd.ctc-posml
+application/vnd.cups-postscript
+application/vnd.cups-raster
+application/vnd.cups-raw
+application/vnd.curl
+application/vnd.cybank
+application/vnd.data-vision.rdz
+application/vnd.dna
+application/vnd.dpgraph
+application/vnd.dreamfactory
+application/vnd.dxr
+application/vnd.ecdis-update
+application/vnd.ecowin.chart
+application/vnd.ecowin.filerequest
+application/vnd.ecowin.fileupdate
+application/vnd.ecowin.series
+application/vnd.ecowin.seriesrequest
+application/vnd.ecowin.seriesupdate
+application/vnd.enliven
+application/vnd.epson.esf
+application/vnd.epson.msf
+application/vnd.epson.quickanime
+application/vnd.epson.salt
+application/vnd.epson.ssf
+application/vnd.ericsson.quickcall
+application/vnd.eudora.data
+application/vnd.fdf
+application/vnd.ffsns
+application/vnd.fints
+application/vnd.flographit
+application/vnd.framemaker
+application/vnd.fsc.weblaunch
+application/vnd.fujitsu.oasys
+application/vnd.fujitsu.oasys2
+application/vnd.fujitsu.oasys3
+application/vnd.fujitsu.oasysgp
+application/vnd.fujitsu.oasysprs
+application/vnd.fujixerox.ddd
+application/vnd.fujixerox.docuworks
+application/vnd.fujixerox.docuworks.binder
+application/vnd.fut-misnet
+application/vnd.grafeq
+application/vnd.groove-account
+application/vnd.groove-help
+application/vnd.groove-identity-message
+application/vnd.groove-injector
+application/vnd.groove-tool-message
+application/vnd.groove-tool-template
+application/vnd.groove-vcard
+application/vnd.hbci
+application/vnd.hhe.lesson-player
+application/vnd.hp-hpgl
+application/vnd.hp-hpid
+application/vnd.hp-hps
+application/vnd.hp-pcl
+application/vnd.hp-pclxl
+application/vnd.httphone
+application/vnd.hzn-3d-crossword
+application/vnd.ibm.afplinedata
+application/vnd.ibm.electronic-media
+application/vnd.ibm.minipay
+application/vnd.ibm.modcap
+application/vnd.ibm.rights-management
+application/vnd.ibm.secure-container
+application/vnd.informix-visionary
+application/vnd.intercon.formnet
+application/vnd.intertrust.digibox
+application/vnd.intertrust.nncp
+application/vnd.intu.qbo
+application/vnd.intu.qfx
+application/vnd.irepository.package+xml
+application/vnd.is-xpr
+application/vnd.japannet-directory-service
+application/vnd.japannet-jpnstore-wakeup
+application/vnd.japannet-payment-wakeup
+application/vnd.japannet-registration
+application/vnd.japannet-registration-wakeup
+application/vnd.japannet-setstore-wakeup
+application/vnd.japannet-verification
+application/vnd.japannet-verification-wakeup
+application/vnd.jisp
+application/vnd.kde.karbon
+application/vnd.kde.kchart
+application/vnd.kde.kformula
+application/vnd.kde.kivio
+application/vnd.kde.kontour
+application/vnd.kde.kpresenter
+application/vnd.kde.kspread
+application/vnd.kde.kword
+application/vnd.kenameaapp
+application/vnd.koan
+application/vnd.liberty-request+xml
+application/vnd.llamagraphics.life-balance.desktop
+application/vnd.llamagraphics.life-balance.exchange+xml
+application/vnd.lotus-1-2-3
+application/vnd.lotus-approach
+application/vnd.lotus-freelance
+application/vnd.lotus-notes
+application/vnd.lotus-organizer
+application/vnd.lotus-screencam
+application/vnd.lotus-wordpro
+application/vnd.mcd
+application/vnd.mediastation.cdkey
+application/vnd.meridian-slingshot
+application/vnd.micrografx.flo
+application/vnd.micrografx.igx
+application/vnd.mif mif
+application/vnd.minisoft-hp3000-save
+application/vnd.mitsubishi.misty-guard.trustweb
+application/vnd.mobius.daf
+application/vnd.mobius.dis
+application/vnd.mobius.mbk
+application/vnd.mobius.mqy
+application/vnd.mobius.msl
+application/vnd.mobius.plc
+application/vnd.mobius.txf
+application/vnd.mophun.application
+application/vnd.mophun.certificate
+application/vnd.motorola.flexsuite
+application/vnd.motorola.flexsuite.adsi
+application/vnd.motorola.flexsuite.fis
+application/vnd.motorola.flexsuite.gotap
+application/vnd.motorola.flexsuite.kmr
+application/vnd.motorola.flexsuite.ttc
+application/vnd.motorola.flexsuite.wem
+application/vnd.mozilla.xul+xml xul
+application/vnd.ms-artgalry
+application/vnd.ms-asf
+application/vnd.ms-excel xls
+application/vnd.ms-lrm
+application/vnd.ms-powerpoint ppt
+application/vnd.ms-project
+application/vnd.ms-tnef
+application/vnd.ms-works
+application/vnd.ms-wpl
+application/vnd.mseq
+application/vnd.msign
+application/vnd.music-niff
+application/vnd.musician
+application/vnd.netfpx
+application/vnd.noblenet-directory
+application/vnd.noblenet-sealer
+application/vnd.noblenet-web
+application/vnd.novadigm.edm
+application/vnd.novadigm.edx
+application/vnd.novadigm.ext
+application/vnd.obn
+application/vnd.osa.netdeploy
+application/vnd.palm
+application/vnd.pg.format
+application/vnd.pg.osasli
+application/vnd.powerbuilder6
+application/vnd.powerbuilder6-s
+application/vnd.powerbuilder7
+application/vnd.powerbuilder7-s
+application/vnd.powerbuilder75
+application/vnd.powerbuilder75-s
+application/vnd.previewsystems.box
+application/vnd.publishare-delta-tree
+application/vnd.pvi.ptid1
+application/vnd.pwg-multiplexed
+application/vnd.pwg-xhtml-print+xml
+application/vnd.quark.quarkxpress
+application/vnd.rapid
+application/vnd.s3sms
+application/vnd.sealed.net
+application/vnd.seemail
+application/vnd.shana.informed.formdata
+application/vnd.shana.informed.formtemplate
+application/vnd.shana.informed.interchange
+application/vnd.shana.informed.package
+application/vnd.smaf
+application/vnd.sss-cod
+application/vnd.sss-dtf
+application/vnd.sss-ntf
+application/vnd.street-stream
+application/vnd.svd
+application/vnd.swiftview-ics
+application/vnd.triscape.mxs
+application/vnd.trueapp
+application/vnd.truedoc
+application/vnd.ufdl
+application/vnd.uplanet.alert
+application/vnd.uplanet.alert-wbxml
+application/vnd.uplanet.bearer-choice
+application/vnd.uplanet.bearer-choice-wbxml
+application/vnd.uplanet.cacheop
+application/vnd.uplanet.cacheop-wbxml
+application/vnd.uplanet.channel
+application/vnd.uplanet.channel-wbxml
+application/vnd.uplanet.list
+application/vnd.uplanet.list-wbxml
+application/vnd.uplanet.listcmd
+application/vnd.uplanet.listcmd-wbxml
+application/vnd.uplanet.signal
+application/vnd.vcx
+application/vnd.vectorworks
+application/vnd.vidsoft.vidconference
+application/vnd.visio
+application/vnd.visionary
+application/vnd.vividence.scriptfile
+application/vnd.vsf
+application/vnd.wap.sic
+application/vnd.wap.slc
+application/vnd.wap.wbxml wbxml
+application/vnd.wap.wmlc wmlc
+application/vnd.wap.wmlscriptc wmlsc
+application/vnd.webturbo
+application/vnd.wrq-hp3000-labelled
+application/vnd.wt.stf
+application/vnd.wv.csp+wbxml
+application/vnd.xara
+application/vnd.xfdl
+application/vnd.yamaha.hv-dic
+application/vnd.yamaha.hv-script
+application/vnd.yamaha.hv-voice
+application/vnd.yellowriver-custom-menu
+application/voicexml+xml vxml
+application/watcherinfo+xml
+application/whoispp-query
+application/whoispp-response
+application/wita
+application/wordperfect5.1
+application/x-bcpio bcpio
+application/x-cdlink vcd
+application/x-chess-pgn pgn
+application/x-compress
+application/x-cpio cpio
+application/x-csh csh
+application/x-director dcr dir dxr
+application/x-dvi dvi
+application/x-futuresplash spl
+application/x-gtar gtar
+application/x-gzip
+application/x-hdf hdf
+application/x-javascript js
+application/x-koan skp skd skt skm
+application/x-latex latex
+application/x-netcdf nc cdf
+application/x-sh sh
+application/x-shar shar
+application/x-shockwave-flash swf
+application/x-stuffit sit
+application/x-sv4cpio sv4cpio
+application/x-sv4crc sv4crc
+application/x-tar tar
+application/x-tcl tcl
+application/x-tex tex
+application/x-texinfo texinfo texi
+application/x-troff t tr roff
+application/x-troff-man man
+application/x-troff-me me
+application/x-troff-ms ms
+application/x-ustar ustar
+application/x-wais-source src
+application/x400-bp
+application/xhtml+xml xhtml xht
+application/xslt+xml xslt
+application/xml xml xsl
+application/xml-dtd dtd
+application/xml-external-parsed-entity
+application/zip zip
+audio/32kadpcm
+audio/amr
+audio/amr-wb
+audio/basic au snd
+audio/cn
+audio/dat12
+audio/dsr-es201108
+audio/dvi4
+audio/evrc
+audio/evrc0
+audio/g722
+audio/g.722.1
+audio/g723
+audio/g726-16
+audio/g726-24
+audio/g726-32
+audio/g726-40
+audio/g728
+audio/g729
+audio/g729D
+audio/g729E
+audio/gsm
+audio/gsm-efr
+audio/l8
+audio/l16
+audio/l20
+audio/l24
+audio/lpc
+audio/midi mid midi kar
+audio/mpa
+audio/mpa-robust
+audio/mp4a-latm
+audio/mpeg mpga mp2 mp3
+audio/parityfec
+audio/pcma
+audio/pcmu
+audio/prs.sid
+audio/qcelp
+audio/red
+audio/smv
+audio/smv0
+audio/telephone-event
+audio/tone
+audio/vdvi
+audio/vnd.3gpp.iufp
+audio/vnd.cisco.nse
+audio/vnd.cns.anp1
+audio/vnd.cns.inf1
+audio/vnd.digital-winds
+audio/vnd.everad.plj
+audio/vnd.lucent.voice
+audio/vnd.nortel.vbk
+audio/vnd.nuera.ecelp4800
+audio/vnd.nuera.ecelp7470
+audio/vnd.nuera.ecelp9600
+audio/vnd.octel.sbc
+audio/vnd.qcelp
+audio/vnd.rhetorex.32kadpcm
+audio/vnd.vmx.cvsd
+audio/x-aiff aif aiff aifc
+audio/x-alaw-basic
+audio/x-mpegurl m3u
+audio/x-pn-realaudio ram ra
+audio/x-pn-realaudio-plugin
+application/vnd.rn-realmedia rm
+audio/x-wav wav
+chemical/x-pdb pdb
+chemical/x-xyz xyz
+image/bmp bmp
+image/cgm cgm
+image/g3fax
+image/gif gif
+image/ief ief
+image/jpeg jpeg jpg jpe
+image/naplps
+image/png png
+image/prs.btif
+image/prs.pti
+image/svg+xml svg
+image/t38
+image/tiff tiff tif
+image/tiff-fx
+image/vnd.cns.inf2
+image/vnd.djvu djvu djv
+image/vnd.dwg
+image/vnd.dxf
+image/vnd.fastbidsheet
+image/vnd.fpx
+image/vnd.fst
+image/vnd.fujixerox.edmics-mmr
+image/vnd.fujixerox.edmics-rlc
+image/vnd.globalgraphics.pgb
+image/vnd.mix
+image/vnd.ms-modi
+image/vnd.net-fpx
+image/vnd.svf
+image/vnd.wap.wbmp wbmp
+image/vnd.xiff
+image/x-cmu-raster ras
+image/x-icon ico
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm
+image/x-portable-graymap pgm
+image/x-portable-pixmap ppm
+image/x-rgb rgb
+image/x-xbitmap xbm
+image/x-xpixmap xpm
+image/x-xwindowdump xwd
+message/delivery-status
+message/disposition-notification
+message/external-body
+message/http
+message/news
+message/partial
+message/rfc822
+message/s-http
+message/sip
+message/sipfrag
+model/iges igs iges
+model/mesh msh mesh silo
+model/vnd.dwf
+model/vnd.flatland.3dml
+model/vnd.gdl
+model/vnd.gs-gdl
+model/vnd.gtw
+model/vnd.mts
+model/vnd.parasolid.transmit.binary
+model/vnd.parasolid.transmit.text
+model/vnd.vtu
+model/vrml wrl vrml
+multipart/alternative
+multipart/appledouble
+multipart/byteranges
+multipart/digest
+multipart/encrypted
+multipart/form-data
+multipart/header-set
+multipart/mixed
+multipart/parallel
+multipart/related
+multipart/report
+multipart/signed
+multipart/voice-message
+text/calendar ics ifb
+text/css css
+text/directory
+text/enriched
+text/html html htm
+text/parityfec
+text/plain asc txt
+text/prs.lines.tag
+text/rfc822-headers
+text/richtext rtx
+text/rtf rtf
+text/sgml sgml sgm
+text/t140
+text/tab-separated-values tsv
+text/uri-list
+text/vnd.abc
+text/vnd.curl
+text/vnd.dmclientscript
+text/vnd.fly
+text/vnd.fmi.flexstor
+text/vnd.in3d.3dml
+text/vnd.in3d.spot
+text/vnd.iptc.nitf
+text/vnd.iptc.newsml
+text/vnd.latex-z
+text/vnd.motorola.reflex
+text/vnd.ms-mediapackage
+text/vnd.net2phone.commcenter.command
+text/vnd.sun.j2me.app-descriptor
+text/vnd.wap.si
+text/vnd.wap.sl
+text/vnd.wap.wml wml
+text/vnd.wap.wmlscript wmls
+text/x-setext etx
+text/xml
+text/xml-external-parsed-entity
+video/bmpeg
+video/bt656
+video/celb
+video/dv
+video/h261
+video/h263
+video/h263-1998
+video/h263-2000
+video/jpeg
+video/mp1s
+video/mp2p
+video/mp2t
+video/mp4v-es
+video/mpv
+video/mpeg mpeg mpg mpe
+video/nv
+video/parityfec
+video/pointer
+video/quicktime qt mov
+video/smpte292m
+video/vnd.fvt
+video/vnd.motorola.video
+video/vnd.motorola.videop
+video/vnd.mpegurl mxu m4u
+video/vnd.nokia.interleaved-multimedia
+video/vnd.objectvideo
+video/vnd.vivo
+video/x-msvideo avi
+video/x-sgi-movie movie
+x-conference/x-cooltalk ice
diff --git a/base/tps/apache/conf/nss.conf b/base/tps/apache/conf/nss.conf
new file mode 100644
index 000000000..314df040d
--- /dev/null
+++ b/base/tps/apache/conf/nss.conf
@@ -0,0 +1,280 @@
+#
+# This is the Apache server configuration file providing SSL support using.
+# the mod_nss plugin. It contains the configuration directives to instruct
+# the server how to serve pages over an https connection.
+#
+# Do NOT simply read the instructions in here without understanding
+# what they do. They're here only as hints or reminders. If you are unsure
+# consult the online docs. You have been warned.
+#
+
+#
+# When we also provide SSL we have to listen to the
+# standard HTTP port (see above) and to the HTTPS port
+#
+# Note: Configurations that use IPv6 but not IPv4-mapped addresses need two
+# Listen directives: "Listen [::]:443" and "Listen 0.0.0.0:443"
+#
+Listen [SECURE_PORT]
+
+Listen [NON_CLIENTAUTH_SECURE_PORT]
+
+##
+## SSL Global Context
+##
+## All SSL configuration in this context applies both to
+## the main server and all SSL-enabled virtual hosts.
+##
+
+#
+# Some MIME-types for downloading Certificates and CRLs
+#
+AddType application/x-x509-ca-cert .crt
+AddType application/x-pkcs7-crl .crl
+
+# Pass Phrase Dialog:
+# Configure the pass phrase gathering process.
+# The filtering dialog program (`builtin' is a internal
+# terminal dialog) has to provide the pass phrase on stdout.
+#NSSPassPhraseDialog builtin
+NSSPassPhraseDialog defer:[SERVER_ROOT]/conf/password.conf
+
+
+# Pass Phrase Helper:
+# This helper program stores the token password pins between
+# restarts of Apache.
+NSSPassPhraseHelper /usr/share/pki/tps/scripts/nss_pcache
+
+# Configure the SSL Session Cache.
+# SSLSessionCacheSize is the number of entries in the cache.
+# SSLSessionCacheTimeout is the SSL2 session timeout (in seconds).
+# SSL3SessionCacheTimeout is the SSL3/TLS session timeout (in seconds).
+NSSSessionCacheSize 10000
+NSSSessionCacheTimeout 100
+NSSSession3CacheTimeout 86400
+
+##
+## SSL Virtual Host Context
+##
+
+<VirtualHost _default_:[SECURE_PORT]>
+
+# General setup for the virtual host
+#DocumentRoot "/htdocs"
+#ServerName [Server_Name]:[Secure_Port]
+#ServerAdmin you@example.com
+
+# Configure OCSP checking of client certs
+
+#NSSOCSP on
+#NSSOCSPDefaultResponder on
+
+# URL of the ocsp service
+#
+# Example of the built in ocsp service of the CS CA
+
+#NSSOCSPDefaultURL http://localhost:9180/ca/ocsp
+
+# Nickname of ocsp signing cert
+#
+# Below is sufficient if using built in CS CA ocsp service
+# If using outboard ocsp, make sure the cert listed below
+# is imported into the local cert database.
+
+#NSSOCSPDefaultName caCert
+
+
+# mod_ssl logs to separate log files, you can choose to do that if you'd like
+ErrorLog [SERVER_ROOT]/logs/error_log
+TransferLog [SERVER_ROOT]/logs/access_log
+
+# SSL Engine Switch:
+# Enable/Disable SSL for this virtual host.
+NSSEngine on
+
+# FIPS Switch:
+# Enable/Disable FIPS mode
+# NSSFIPS on
+
+# SSL Cipher Suite:
+# List the ciphers that the client is permitted to negotiate.
+# See the mod_nss documentation for a complete list.
+NSSCipherSuite -des,-desede3,-rc2,-rc2export,-rc4,-rc4export,+rsa_3des_sha,-rsa_des_56_sha,+rsa_des_sha,-rsa_null_md5,-rsa_null_sha,-rsa_rc2_40_md5,+rsa_rc4_128_md5,-rsa_rc4_128_sha,-rsa_rc4_40_md5,-rsa_rc4_56_sha,-fortezza,-fortezza_rc4_128_sha,-fortezza_null,-fips_des_sha,+fips_3des_sha,-rsa_aes_128_sha,-rsa_aes_256_sha,+ecdhe_ecdsa_aes_256_sha
+# SSL cipher suite in FIPS mode:
+# NSSCipherSuite +rsa_3des_sha,-rsa_des_sha,-rsa_rc4_40_md5,-rsa_rc2_40_md5,-rsa_null_md5,-rsa_null_sha,+fips_3des_sha,-fips_des_sha,-fortezza,-fortezza_rc4_128_sha,-fortezza_null,-rsa_des_56_sha,-rsa_rc4_56_sha,+rsa_aes_128_sha,+rsa_aes_256_sha
+
+NSSProtocol SSLv3,TLSv1
+
+# SSL Certificate Nickname:
+# The nickname of the server certificate you are going to use.
+NSSNickname "Server-Cert cert-[PKI_INSTANCE_ID]"
+
+# Server Certificate Database:
+# The NSS security database directory that holds the certificates and
+# keys. The database consists of 3 files: cert8.db, key3.db and secmod.db.
+# Provide the directory that these files exist.
+NSSCertificateDatabase [SERVER_ROOT]/alias
+
+# Client Authentication (Type):
+# Client certificate verification type. Types are none, optional and
+# require.
+NSSVerifyClient require
+
+# Access Control:
+# With SSLRequire you can do per-directory access control based
+# on arbitrary complex boolean expressions containing server
+# variable checks and other lookup directives. The syntax is a
+# mixture between C and Perl. See the mod_nss documentation
+# for more details.
+#<Location />
+#SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \
+# and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \
+# and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \
+# and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \
+# and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \
+# or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/
+#</Location>
+
+# SSL Engine Options:
+# Set various options for the SSL engine.
+# o FakeBasicAuth:
+# Translate the client X.509 into a Basic Authorisation. This means that
+# the standard Auth/DBMAuth methods can be used for access control. The
+# user name is the `one line' version of the client's X.509 certificate.
+# Note that no password is obtained from the user. Every entry in the user
+# file needs this password: `xxj31ZMTZzkVA'.
+# o ExportCertData:
+# This exports two additional environment variables: SSL_CLIENT_CERT and
+# SSL_SERVER_CERT. These contain the PEM-encoded certificates of the
+# server (always existing) and the client (only existing when client
+# authentication is used). This can be used to import the certificates
+# into CGI scripts.
+# o StdEnvVars:
+# This exports the standard SSL/TLS related `SSL_*' environment variables.
+# Per default this exportation is switched off for performance reasons,
+# because the extraction step is an expensive operation and is usually
+# useless for serving static content. So one usually enables the
+# exportation for CGI and SSI requests only.
+# o StrictRequire:
+# This denies access when "SSLRequireSSL" or "SSLRequire" applied even
+# under a "Satisfy any" situation, i.e. when it applies access is denied
+# and no other module can change it.
+# o OptRenegotiate:
+# This enables optimized SSL connection renegotiation handling when SSL
+# directives are used in per-directory context.
+#SSLOptions +FakeBasicAuth +ExportCertData +CompatEnvVars +StrictRequire
+<Files ~ "\.(cgi|shtml|phtml|php3?)$">
+ NSSOptions +StdEnvVars
+</Files>
+<Directory "/cgi-bin">
+ NSSOptions +StdEnvVars
+</Directory>
+
+# Per-Server Logging:
+# The home of a custom SSL log file. Use this when you want a
+# compact non-error SSL logfile on a virtual host basis.
+#CustomLog [SERVER_ROOT]/logs/ssl_request_log \
+# "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
+
+</VirtualHost>
+
+<VirtualHost _default_:[NON_CLIENTAUTH_SECURE_PORT]>
+
+# General setup for the virtual host
+#DocumentRoot "/htdocs"
+#ServerName [Server_Name]:[Non_Clientauth_Secure_Port]
+#ServerAdmin you@example.com
+
+# mod_ssl logs to separate log files, you can choose to do that if you'd like
+ErrorLog [SERVER_ROOT]/logs/error_log
+TransferLog [SERVER_ROOT]/logs/access_log
+
+# SSL Engine Switch:
+# Enable/Disable SSL for this virtual host.
+NSSEngine on
+
+# FIPS Switch:
+# Enable/Disable FIPS mode
+# NSSFIPS on
+
+# SSL Cipher Suite:
+# List the ciphers that the client is permitted to negotiate.
+# See the mod_nss documentation for a complete list.
+NSSCipherSuite -des,-desede3,-rc2,-rc2export,-rc4,-rc4export,+rsa_3des_sha,-rsa_des_56_sha,+rsa_des_sha,-rsa_null_md5,-rsa_null_sha,-rsa_rc2_40_md5,+rsa_rc4_128_md5,-rsa_rc4_128_sha,-rsa_rc4_40_md5,-rsa_rc4_56_sha,-fortezza,-fortezza_rc4_128_sha,-fortezza_null,-fips_des_sha,+fips_3des_sha,-rsa_aes_128_sha,-rsa_aes_256_sha,+ecdhe_ecdsa_aes_256_sha
+# SSL cipher suite in FIPS mode:
+# NSSCipherSuite +rsa_3des_sha,-rsa_des_sha,-rsa_rc4_40_md5,-rsa_rc2_40_md5,-rsa_null_md5,-rsa_null_sha,+fips_3des_sha,-fips_des_sha,-fortezza,-fortezza_rc4_128_sha,-fortezza_null,-rsa_des_56_sha,-rsa_rc4_56_sha,+rsa_aes_128_sha,+rsa_aes_256_sha
+
+NSSProtocol SSLv3,TLSv1
+
+# SSL Certificate Nickname:
+# The nickname of the server certificate you are going to use.
+NSSNickname "Server-Cert cert-[PKI_INSTANCE_ID]"
+
+# Server Certificate Database:
+# The NSS security database directory that holds the certificates and
+# keys. The database consists of 3 files: cert8.db, key3.db and secmod.db.
+# Provide the directory that these files exist.
+NSSCertificateDatabase [SERVER_ROOT]/alias
+
+# Client Authentication (Type):
+# Client certificate verification type. Types are none, optional and
+# require.
+NSSVerifyClient none
+
+# Access Control:
+# With SSLRequire you can do per-directory access control based
+# on arbitrary complex boolean expressions containing server
+# variable checks and other lookup directives. The syntax is a
+# mixture between C and Perl. See the mod_nss documentation
+# for more details.
+#<Location />
+#SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \
+# and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \
+# and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \
+# and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \
+# and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \
+# or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/
+#</Location>
+
+# SSL Engine Options:
+# Set various options for the SSL engine.
+# o FakeBasicAuth:
+# Translate the client X.509 into a Basic Authorisation. This means that
+# the standard Auth/DBMAuth methods can be used for access control. The
+# user name is the `one line' version of the client's X.509 certificate.
+# Note that no password is obtained from the user. Every entry in the user
+# file needs this password: `xxj31ZMTZzkVA'.
+# o ExportCertData:
+# This exports two additional environment variables: SSL_CLIENT_CERT and
+# SSL_SERVER_CERT. These contain the PEM-encoded certificates of the
+# server (always existing) and the client (only existing when client
+# authentication is used). This can be used to import the certificates
+# into CGI scripts.
+# o StdEnvVars:
+# This exports the standard SSL/TLS related `SSL_*' environment variables.
+# Per default this exportation is switched off for performance reasons,
+# because the extraction step is an expensive operation and is usually
+# useless for serving static content. So one usually enables the
+# exportation for CGI and SSI requests only.
+# o StrictRequire:
+# This denies access when "SSLRequireSSL" or "SSLRequire" applied even
+# under a "Satisfy any" situation, i.e. when it applies access is denied
+# and no other module can change it.
+# o OptRenegotiate:
+# This enables optimized SSL connection renegotiation handling when SSL
+# directives are used in per-directory context.
+#SSLOptions +FakeBasicAuth +ExportCertData +CompatEnvVars +StrictRequire
+<Files ~ "\.(cgi|shtml|phtml|php3?)$">
+ NSSOptions +StdEnvVars
+</Files>
+<Directory "/cgi-bin">
+ NSSOptions +StdEnvVars
+</Directory>
+
+# Per-Server Logging:
+# The home of a custom SSL log file. Use this when you want a
+# compact non-error SSL logfile on a virtual host basis.
+#CustomLog [SERVER_ROOT]/logs/ssl_request_log \
+# "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
+
+</VirtualHost>
diff --git a/base/tps/apache/conf/perl.conf b/base/tps/apache/conf/perl.conf
new file mode 100644
index 000000000..feb51e860
--- /dev/null
+++ b/base/tps/apache/conf/perl.conf
@@ -0,0 +1,70 @@
+#
+# Mod_perl incorporates a Perl interpreter into the Apache web server,
+# so that the Apache web server can directly execute Perl code.
+# Mod_perl links the Perl runtime library into the Apache web server
+# and provides an object-oriented Perl interface for Apache's C
+# language API. The end result is a quicker CGI script turnaround
+# process, since no external Perl interpreter has to be started.
+#
+
+LoadModule perl_module [FORTITUDE_LIB_DIR]/modules/mod_perl.so
+
+# Uncomment this line to globally enable warnings, which will be
+# written to the server's error log. Warnings should be enabled
+# during the development process, but should be disabled on a
+# production server as they affect performance.
+#
+#PerlWarn On
+
+# Uncomment this line to enable taint checking globally. When Perl is
+# running in taint mode various checks are performed to reduce the
+# risk of insecure data being passed to a subshell or being used to
+# modify the filesystem. Unfortunatly many Perl modules are not
+# taint-safe, so you should exercise care before enabling it on a
+# production server.
+#
+#PerlTaintCheck On
+
+# This will allow execution of mod_perl to compile your scripts to
+# subroutines which it will execute directly, avoiding the costly
+# compile process for most requests.
+#
+#Alias /perl /var/www/perl
+#<Directory /var/www/perl>
+# SetHandler perl-script
+# PerlResponseHandler ModPerl::Registry
+# PerlOptions +ParseHeaders
+# Options +ExecCGI
+#</Directory>
+
+# This will allow remote server configuration reports, with the URL of
+# http://servername/perl-status
+# Change the ".your-domain.com" to match your domain to enable.
+#
+#PerlModule Apache::compat
+#<Location /perl-status>
+# SetHandler perl-script
+# PerlResponseHandler Apache::Status
+# Order deny,allow
+# Deny from all
+# Allow from .your-domain.com
+#</Location>
+
+PerlModule ModPerl::Registry
+PerlModule [FORTITUDE_APACHE]::compat
+PerlModule PKI::TPS::wizard
+PerlSetEnv PKI_DOCROOT [SERVER_ROOT]/docroot
+PerlSetEnv PKI_ROOT [SERVER_ROOT]
+<Location /tps/admin/console/config/wizard>
+ SetHandler perl-script
+ PerlHandler PKI::TPS::Wizard
+ Order deny,allow
+ Allow from all
+</Location>
+
+<Location /tps/admin/console/config/login>
+ SetHandler perl-script
+ PerlHandler PKI::TPS::Login
+ Order deny,allow
+ Allow from all
+</Location>
diff --git a/base/tps/apache/pki_instance_command_wrapper b/base/tps/apache/pki_instance_command_wrapper
new file mode 100644
index 000000000..913b37e4a
--- /dev/null
+++ b/base/tps/apache/pki_instance_command_wrapper
@@ -0,0 +1,192 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+
+# 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 '$0' from non-existent directory!"
+ exit 255
+fi
+
+
+###############################################################################
+## (1) Specify variables used by this script. ##
+###############################################################################
+
+PRODUCT=[PKI_PRODUCT]
+SUBSYSTEM=[PKI_SUBSYSTEM]
+INSTANCE=[PKI_INSTANCE]
+COMMAND=[PKI_COMMAND]
+
+
+###############################################################################
+## (2) Define helper functions. ##
+###############################################################################
+
+invalid_operating_system() {
+ echo
+ echo "ERROR: '$0' does not execute on the '$1' operating system!"
+ echo
+}
+
+invalid_architecture() {
+ echo
+ echo "ERROR: '$0' does not execute on the '$1' architecture!"
+ echo
+}
+
+
+###############################################################################
+## (3) Set environment variables. ##
+## ##
+## Set the LD_LIBRARY_PATH environment variable to determine the ##
+## search order this command wrapper uses to find shared libraries. ##
+## ##
+## Set the PATH environment variable to determine the search ##
+## order this command wrapper uses to find binary executables. ##
+## ##
+## NOTE: Since the wrappers themselves are ALWAYS located in ##
+## "/usr/bin" on 32-bit and 64-bit Linux as well as both ##
+## 32-bit Solaris and 64-bit Solaris, this directory ##
+## will always be excluded from the search path. ##
+## ##
+## Additionally, since "/bin" is nothing more than a symbolic ##
+## link to "/usr/bin" on Solaris, this directory will also ##
+## always be excluded from the search path on this platform. ##
+## ##
+###############################################################################
+
+OS=`uname -s`
+ARCHITECTURE=""
+
+if [ "${OS}" = "Linux" ] ; then
+ ARCHITECTURE=`uname -i`
+ if [ "${ARCHITECTURE}" = "i386" ] ; then
+ LD_LIBRARY_PATH=/usr/lib/java:/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}/${SUBSYSTEM}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/var/lib/${INSTANCE}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/java/dirsec:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+
+ PATH=/usr/lib/${PRODUCT}:/bin
+ PATH=/usr/lib/${PRODUCT}/${SUBSYSTEM}:${PATH}
+ PATH=/var/lib/${INSTANCE}:${PATH}
+ export PATH
+ elif [ "${ARCHITECTURE}" = "x86_64" ] ; then
+ LD_LIBRARY_PATH=/usr/lib/java:/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}/${SUBSYSTEM}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/var/lib/${INSTANCE}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/java/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib64/java:/usr/lib64:/lib64:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib64/${PRODUCT}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib64/${PRODUCT}/${SUBSYSTEM}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib64/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib64/java/dirsec:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+
+ PATH=/usr/lib/${PRODUCT}
+ PATH=/usr/lib/${PRODUCT}/${SUBSYSTEM}:${PATH}
+ PATH=/var/lib/${INSTANCE}:${PATH}
+ PATH=/usr/lib64/${PRODUCT}:/bin:${PATH}
+ PATH=/usr/lib64/${PRODUCT}/${SUBSYSTEM}:${PATH}
+ export PATH
+ else
+ invalid_architecture "${ARCHITECTURE}"
+ exit 255
+ fi
+elif [ "${OS}" = "SunOS" ] ; then
+ ARCHITECTURE=`uname -p`
+ if [ "${ARCHITECTURE}" = "sparc" ] &&
+ [ -d "/usr/lib/sparcv9/" ] ; then
+ ARCHITECTURE="sparcv9"
+ fi
+ if [ "${ARCHITECTURE}" = "sparc" ] ; then
+ LD_LIBRARY_PATH=/usr/lib/java:/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}/${SUBSYSTEM}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/var/lib/${INSTANCE}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/java/dirsec:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+
+ PATH=/usr/lib/${PRODUCT}
+ PATH=/usr/lib/${PRODUCT}/${SUBSYSTEM}:${PATH}
+ PATH=/var/lib/${INSTANCE}:${PATH}
+ export PATH
+ elif [ "${ARCHITECTURE}" = "sparcv9" ] ; then
+ LD_LIBRARY_PATH=/usr/lib/java:/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}/${SUBSYSTEM}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/var/lib/${INSTANCE}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/java/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9:/lib/sparcv9:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/java:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/${PRODUCT}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/${PRODUCT}/${SUBSYSTEM}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/java/dirsec:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+
+ PATH=/usr/bin/sparcv9
+ PATH=/usr/lib/${PRODUCT}:${PATH}
+ PATH=/usr/lib/${PRODUCT}/${SUBSYSTEM}:${PATH}
+ PATH=/var/lib/${INSTANCE}:${PATH}
+ PATH=/usr/lib/sparcv9/${PRODUCT}:${PATH}
+ PATH=/usr/lib/sparcv9/${PRODUCT}/${SUBSYSTEM}:${PATH}
+ export PATH
+ else
+ invalid_architecture "${ARCHITECTURE}"
+ exit 255
+ fi
+else
+ invalid_operating_system "${OS}"
+ exit 255
+fi
+
+
+###############################################################################
+## (4) Execute the binary executable specified by this command wrapper ##
+## based upon the preset LD_LIBRARY_PATH and PATH environment variables.##
+###############################################################################
+
+ORIGINAL_IFS=${IFS}
+IFS=:
+
+for dir in ${PATH}
+do
+ if [ -x ${dir}/${COMMAND} ]
+ then
+ IFS=${ORIGINAL_IFS}
+ ${dir}/${COMMAND} "$@"
+ exit $?
+ fi
+done
+
+echo "Unable to find \"${COMMAND}\" in \"${PATH}\"!"
+
+exit 255
+
diff --git a/base/tps/apache/pki_subsystem_command_wrapper b/base/tps/apache/pki_subsystem_command_wrapper
new file mode 100644
index 000000000..19cbf9dd9
--- /dev/null
+++ b/base/tps/apache/pki_subsystem_command_wrapper
@@ -0,0 +1,182 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+
+# 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 '$0' from non-existent directory!"
+ exit 255
+fi
+
+
+###############################################################################
+## (1) Specify variables used by this script. ##
+###############################################################################
+
+PRODUCT=[PKI_PRODUCT]
+SUBSYSTEM=[PKI_SUBSYSTEM]
+COMMAND=[PKI_COMMAND]
+
+
+###############################################################################
+## (2) Define helper functions. ##
+###############################################################################
+
+invalid_operating_system() {
+ echo
+ echo "ERROR: '$0' does not execute on the '$1' operating system!"
+ echo
+}
+
+invalid_architecture() {
+ echo
+ echo "ERROR: '$0' does not execute on the '$1' architecture!"
+ echo
+}
+
+
+###############################################################################
+## (3) Set environment variables. ##
+## ##
+## Set the LD_LIBRARY_PATH environment variable to determine the ##
+## search order this command wrapper uses to find shared libraries. ##
+## ##
+## Set the PATH environment variable to determine the search ##
+## order this command wrapper uses to find binary executables. ##
+## ##
+## NOTE: Since the wrappers themselves are ALWAYS located in ##
+## "/usr/bin" on 32-bit and 64-bit Linux as well as both ##
+## 32-bit Solaris and 64-bit Solaris, this directory ##
+## will always be excluded from the search path. ##
+## ##
+## Additionally, since "/bin" is nothing more than a symbolic ##
+## link to "/usr/bin" on Solaris, this directory will also ##
+## always be excluded from the search path on this platform. ##
+## ##
+###############################################################################
+
+OS=`uname -s`
+ARCHITECTURE=""
+
+if [ "${OS}" = "Linux" ] ; then
+ ARCHITECTURE=`uname -i`
+ if [ "${ARCHITECTURE}" = "i386" ] ; then
+ LD_LIBRARY_PATH=/usr/lib/java:/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}/${SUBSYSTEM}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/java/dirsec:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+
+ PATH=/usr/lib/${PRODUCT}:/bin
+ PATH=/usr/lib/${PRODUCT}/${SUBSYSTEM}:${PATH}
+ export PATH
+ elif [ "${ARCHITECTURE}" = "x86_64" ] ; then
+ LD_LIBRARY_PATH=/usr/lib/java:/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}/${SUBSYSTEM}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/java/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib64/java:/usr/lib64:/lib64:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib64/${PRODUCT}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib64/${PRODUCT}/${SUBSYSTEM}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib64/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib64/java/dirsec:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+
+ PATH=/usr/lib/${PRODUCT}
+ PATH=/usr/lib/${PRODUCT}/${SUBSYSTEM}:${PATH}
+ PATH=/usr/lib64/${PRODUCT}:/bin:${PATH}
+ PATH=/usr/lib64/${PRODUCT}/${SUBSYSTEM}:${PATH}
+ export PATH
+ else
+ invalid_architecture "${ARCHITECTURE}"
+ exit 255
+ fi
+elif [ "${OS}" = "SunOS" ] ; then
+ ARCHITECTURE=`uname -p`
+ if [ "${ARCHITECTURE}" = "sparc" ] &&
+ [ -d "/usr/lib/sparcv9/" ] ; then
+ ARCHITECTURE="sparcv9"
+ fi
+ if [ "${ARCHITECTURE}" = "sparc" ] ; then
+ LD_LIBRARY_PATH=/usr/lib/java:/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}/${SUBSYSTEM}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/java/dirsec:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+
+ PATH=/usr/lib/${PRODUCT}
+ PATH=/usr/lib/${PRODUCT}/${SUBSYSTEM}:${PATH}
+ export PATH
+ elif [ "${ARCHITECTURE}" = "sparcv9" ] ; then
+ LD_LIBRARY_PATH=/usr/lib/java:/usr/lib:/lib
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/${PRODUCT}/${SUBSYSTEM}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/java/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9:/lib/sparcv9:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/java:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/${PRODUCT}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/${PRODUCT}/${SUBSYSTEM}:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/dirsec:${LD_LIBRARY_PATH}
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/java/dirsec:${LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+
+ PATH=/usr/lib/${PRODUCT}
+ PATH=/usr/lib/${PRODUCT}/${SUBSYSTEM}:${PATH}
+ PATH=/usr/lib/sparcv9/${PRODUCT}:${PATH}
+ PATH=/usr/lib/sparcv9/${PRODUCT}/${SUBSYSTEM}:${PATH}
+ export PATH
+ else
+ invalid_architecture "${ARCHITECTURE}"
+ exit 255
+ fi
+else
+ invalid_operating_system "${OS}"
+ exit 255
+fi
+
+
+###############################################################################
+## (4) Execute the binary executable specified by this command wrapper ##
+## based upon the preset LD_LIBRARY_PATH and PATH environment variables.##
+###############################################################################
+
+ORIGINAL_IFS=${IFS}
+IFS=:
+
+for dir in ${PATH}
+do
+ if [ -x ${dir}/${COMMAND} ]
+ then
+ IFS=${ORIGINAL_IFS}
+ ${dir}/${COMMAND} "$@"
+ exit $?
+ fi
+done
+
+echo "Unable to find \"${COMMAND}\" in \"${PATH}\"!"
+
+exit 255
+
diff --git a/base/tps/apache/readme.html b/base/tps/apache/readme.html
new file mode 100644
index 000000000..3b741e6ae
--- /dev/null
+++ b/base/tps/apache/readme.html
@@ -0,0 +1,1222 @@
+<!-- --- BEGIN COPYRIGHT BLOCK ---
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation;
+ version 2.1 of the License.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; 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 --- -->
+<html>
+<body>
+<h1>
+<center><b>
+How to Setup and Configure "mod_tps" and "mod_tokendb" on Apache
+</b></center>
+<hr>
+<h2>Overview</h2>
+<ul>
+<p>This document describes how to install and configure the "mod_tps" and
+"mod_tokendb" modules required by CoolKey.
+</ul>
+<h2>Dependencies</h2>
+<ul>
+<p>"mod_tps" is dependent upon the following components:
+<ul>
+<li>Fedora Certificate System (FCS) 1.0.0 Certificate Authority (CA)
+<li>FCS 1.0.0 Token Key Service (TKS)
+<li>FCS 1.0.0 Data Recovery Manager (DRM) [optional]
+<li>FCS 1.0.0 Token Processing System (TPS)
+<li>Fedora Directory Server (FDS) 1.0 (TPS internaldb instance)
+<li>Apache 2.0.52
+<li>"mod_nss" module installed and available from this Apache 2.0.52 (Fortitude)
+</ul>
+<p>"mod_tokendb" is dependent upon the following components:
+<ul>
+<li>FCS 1.0.0 TPS
+<li>FDS 1.0 TPS internaldb instance
+<li>Apache 2.0.52
+<li>"mod_nss" module installed and available from this Apache 2.0.52 (Fortitude)
+<li>"mod_tps" module installed and available from this Apache 2.0.52 (Fortitude)
+</ul>
+</ul>
+<h2>Supported Platforms</h2>
+<ul>
+<li>Fedora Core 6 (32-bit),
+<li>Fedora Core 6 (64-bit), and
+<li>Solaris 9 (64-bit)
+</ul>
+<h2>Installing and Configuring "mod_tps" and "mod_tokendb"</h2>
+<ol>
+<li>Insure that a pre-installed version 1.0.0 of the FCS common subsystems area
+exists on the desired machine running on the desired platform<br>
+(e. g. - &lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;)
+<li>Insure that a pre-installed version 1.0.0 of the FCS CA exists on the
+desired machine running on the desired platform<br>
+(e. g. - &lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_ca_subsystems&gt; and &lt;pki_server_root&gt;/&lt;ca_instance&gt;)
+<li>Insure that a pre-installed version 1.0.0 of the FCS TKS exists on the
+desired machine running on the desired platform<br>
+(e. g. - &lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tks_subsystems&gt; and &lt;pki_server_root&gt;/&lt;tks_instance&gt;)
+<li>Optionally, insure that a pre-installed version 1.0.0 of the FCS DRM exists
+on the desired machine running on the desired platform<br>
+(e. g. - &lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_drm_subsystems&gt; and &lt;pki_server_root&gt;/&lt;drm_instance&gt;)
+<li>Insure that a pre-installed version 1.0 of the FDS exists on the desired
+machine running on the desired platform.<br>
+This is needed to create a TPS internaldb instance<br>
+(e. g. - &lt;rhds_server_root&gt;/&lt;tps_internaldb&gt;)
+<li>Insure that a pre-installed threaded version 2.0.52 of the Apache server
+exists on the desired machine running on the desired platform<br>
+(e. g. - &lt;apache_server_root&gt;)
+<li>Insure that this Apache server has "mod_nss" (Fortitude) installed and
+available from its &lt;apache_server_root&gt;
+<li>Download and unpack the entire contents of the TPS package into the
+&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;, the
+&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;, and the
+&lt;pki_server_root&gt;/&lt;tps_instance&gt;
+<li>Change directory to &lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/bin
+<li>Execute &lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/bin/setup_tps:
+<ol type="a">
+<li>Creates a wrapper script called
+&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/bin/tpsclient for
+&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/bin/tpsclient
+<li>Creates an empty
+&lt;pki_server_root&gt;/&lt;tps_instance&gt;/bin directory
+(instance-specific binaries)
+<li>Creates an empty
+&lt;pki_server_root&gt;/&lt;tps_instance&gt;/cgi-bin directory
+(user customization)
+<li>Creates an empty
+&lt;pki_server_root&gt;/&lt;tps_instance&gt;/docroot directory
+(user customization)
+<li>Creates an empty
+&lt;pki_server_root&gt;/&lt;tps_instance&gt;/lib directory
+(instance-specific libraries)
+<li>Creates an empty
+&lt;pki_server_root&gt;/&lt;tps_instance&gt;/logs directory
+(instance-specific logs)
+<li>Sets up the CA connector in
+&lt;pki_server_root&gt;/&lt;tps_instance&gt;/config/CS.cfg
+<li>Optionally, sets up the DRM connector in
+&lt;pki_server_root&gt;/&lt;tps_instance&gt;/config/CS.cfg
+<li>Creates a cert8.db in
+&lt;pki_server_root&gt;/&lt;tps_instance&gt;/config/cert8.db
+<li>Creates a key3.db in
+&lt;pki_server_root&gt;/&lt;tps_instance&gt;/config/key3.db
+<li>Populates the cert8.db and key3.db security databases located in the
+&lt;pki_server_root&gt;/&lt;tps_instance&gt;/config directory with the
+ServerCert
+<li>Populates the TPS internaldb located in the
+&lt;rhds_server_root&gt;/&lt;tps_internaldb&gt; directory by executing the
+LDIF scripts located in the
+&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/setup directory
+<li>Generates the
+&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/config/httpd.conf
+Apache Configuration file:
+<pre>
+#
+# Dynamic Shared Object (DSO) Support
+#
+# To be able to use the functionality of a module which was built as a DSO you
+# have to place corresponding `LoadModule' lines at this location so the
+# directives contained in it are actually available _before_ they are used.
+# Statically compiled modules (those listed by `httpd -l') do not need
+# to be loaded here.
+#
+# Example:
+# LoadModule foo_module modules/mod_foo.so
+#
+LoadModule nss_module &lt;apache_server_root&gt;/modules/libmodnss.so
+
+#
+# Bring in additional module-specific configurations
+#
+Include &lt;apache_server_root&gt;/conf/nss.conf
+Include &lt;pki_server_root&gt;/&lt;tps_instance&gt;/config/tps.conf
+</pre>
+<li>Generates the
+&lt;pki_server_root&gt;/&lt;tps_instance&gt;/config/tps.conf
+Apache TPS Module Configuration file:
+<pre>
+#
+# Dynamic Shared Object (DSO) Support
+#
+# To be able to use the functionality of a module which was built as a DSO you
+# have to place corresponding `LoadModule' lines at this location so the
+# directives contained in it are actually available _before_ they are used.
+# Statically compiled modules (those listed by `httpd -l') do not need
+# to be loaded here.
+#
+# Example:
+# LoadModule foo_module modules/mod_foo.so
+#
+LoadModule tps_module &lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/lib/mod_tps.so
+LoadModule tokendb_module &lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/lib/mod_tokendb.so
+
+&lt;Location /nk_service&gt;
+ SetHandler nk_service
+&lt;/Location&gt;
+
+&lt;Location /tus&gt;
+ SetHandler tus
+&lt;/Location&gt;
+
+#
+# DocumentRoot: The directory out of which you will serve your
+# documents. By default, all requests are taken from this directory, but
+# symbolic links and aliases may be used to point to other locations.
+#
+DocumentRoot "&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot"
+
+#
+# ScriptAlias: This controls which directories contain server scripts.
+# ScriptAliases are essentially the same as Aliases, except that
+# documents in the realname directory are treated as applications and
+# run by the server when requested rather than as documents sent to the client.
+# The same rules about trailing "/" apply to ScriptAlias directives as to
+# Alias.
+#
+ScriptAlias /cgi-bin/ "&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/cgi-bin/"
+
+#
+# Bring in additional module-specific configurations
+#
+TPSConfigPathFile &lt;pki_server_root&gt;/&lt;tps_instance&gt;/config/CS.cfg
+</ol>
+<li>Assume "root" privilege
+<li>Execute &lt;apache_server_root&gt;/bin/apachectl -f
+&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/config/httpd.conf
+start
+</ol>
+
+<h2>Inventory of cs-tps-{version} Package</h2>
+<ul>
+<table border=1>
+<tr>
+<th>Packaged File</th>
+<th>Unpackaged File</th>
+</tr>
+<tr>
+<td>applets/</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/applets/</td>
+</tr>
+<tr>
+<td>applets/1.3.427BDDB8.ijc</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/applets/1.3.427BDDB8.ijc</td>
+</tr>
+<tr>
+<td>bin/</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/bin/</td>
+</tr>
+<tr>
+<td>bin/setup_tps</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/bin/setup_tps</td>
+</tr>
+<tr>
+<td>bin/setup_tps</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/bin/uninstall_tps</td>
+</tr>
+<tr>
+<td>bin/</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/bin/</td>
+</tr>
+<tr>
+<td>bin/tpsclient</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/bin/tpsclient</td>
+</tr>
+<tr>
+<td>cgi-bin/</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/cgi-bin/</td>
+</tr>
+<tr>
+<td>cgi-bin/AdminEsc.html</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/cgi-bin/AdminEsc.html</td>
+</tr>
+<tr>
+<td>cgi-bin/AdvancePopup.html</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/cgi-bin/AdvancePopup.html</td>
+</tr>
+<tr>
+<td>cgi-bin/EnrollPopup.html</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/cgi-bin/EnrollPopup.html</td>
+</tr>
+<tr>
+<td>cgi-bin/SettingsEsc.html</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/cgi-bin/SettingsEsc.html</td>
+</tr>
+<tr>
+<td>cgi-bin/TokenManager.html</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/cgi-bin/TokenManager.html</td>
+</tr>
+<tr>
+<td>cgi-bin/TokenPin.html</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/cgi-bin/TokenPin.html</td>
+</tr>
+<tr>
+<td>cgi-bin/esc.cgi</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/cgi-bin/esc.cgi</td>
+</tr>
+<tr>
+<td>cgi-bin/style.css</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/cgi-bin/style.css</td>
+</tr>
+<tr>
+<td>config/</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/config/</td>
+</tr>
+<tr>
+<td>config/CS.cfg</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/config/CS.cfg</td>
+</tr>
+<tr>
+<td>config/enroll.test</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/config/enroll.test</td>
+</tr>
+<tr>
+<td>config/format.test</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/config/format.test</td>
+</tr>
+<tr>
+<td>config/reset_pin.test</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/config/reset_pin.test</td>
+</tr>
+<tr>
+<td>docroot/</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/</td>
+</tr>
+<tr>
+<td>docroot/GenericAuth.html</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/GenericAuth.html</td>
+</tr>
+<tr>
+<td>docroot/images/</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/</td>
+</tr>
+<tr>
+<td>docroot/images/BannerBackground.gif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/BannerBackground.gif</td>
+</tr>
+<tr>
+<td>docroot/images/BindSettingsPrototype.jpg</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/BindSettingsPrototype.jpg</td>
+</tr>
+<tr>
+<td>docroot/images/CancelButton.gif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/CancelButton.gif</td>
+</tr>
+<tr>
+<td>docroot/images/CloseButton.gif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/CloseButton.gif</td>
+</tr>
+<tr>
+<td>docroot/images/ContinueButton.gif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/ContinueButton.gif</td>
+</tr>
+<tr>
+<td>docroot/images/HelpButton.gif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/HelpButton.gif</td>
+</tr>
+<tr>
+<td>docroot/images/NetKey-Small.gif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/NetKey-Small.gif</td>
+</tr>
+<tr>
+<td>docroot/images/NetKeyInsert.gif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/NetKeyInsert.gif</td>
+</tr>
+<tr>
+<td>docroot/images/NetKeyLogo.gif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/NetKeyLogo.gif</td>
+</tr>
+<tr>
+<td>docroot/images/NetKeyPair.gif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/NetKeyPair.gif</td>
+</tr>
+<tr>
+<td>docroot/images/NetKeyProgress.gif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/NetKeyProgress.gif</td>
+</tr>
+<tr>
+<td>docroot/images/NetKeyQuestionMark.gif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/NetKeyQuestionMark.gif</td>
+</tr>
+<tr>
+<td>docroot/images/OKButton.gif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/OKButton.gif</td>
+</tr>
+<tr>
+<td>docroot/images/PadLock.gif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/PadLock.gif</td>
+</tr>
+<tr>
+<td>docroot/images/PurchaseButton.gif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/PurchaseButton.gif</td>
+</tr>
+<tr>
+<td>docroot/images/ReactivateButton.gif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/ReactivateButton.gif</td>
+</tr>
+<tr>
+<td>docroot/images/ReleaseButton.gif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/ReleaseButton.gif</td>
+</tr>
+<tr>
+<td>docroot/images/SecureButton.gif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/SecureButton.gif</td>
+</tr>
+<tr>
+<td>docroot/images/SuspendButton.gif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/SuspendButton.gif</td>
+</tr>
+<tr>
+<td>docroot/images/TryAgainButton.gif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/TryAgainButton.gif</td>
+</tr>
+<tr>
+<td>docroot/images/bg.jpg</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/bg.jpg</td>
+</tr>
+<tr>
+<td>docroot/images/logo.gif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/images/logo.gif</td>
+</tr>
+<tr>
+<td>docroot/style.css</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/style.css</td>
+</tr>
+<tr>
+<td>docroot/tus/</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/</td>
+</tr>
+<tr>
+<td>docroot/tus/addResults.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/addResults.template</td>
+</tr>
+<tr>
+<td>docroot/tus/delete.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/delete.template</td>
+</tr>
+<tr>
+<td>docroot/tus/deleteResults.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/deleteResults.template</td>
+</tr>
+<tr>
+<td>docroot/tus/doToken.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/doToken.template</td>
+</tr>
+<tr>
+<td>docroot/tus/doTokenConfirm.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/doTokenConfirm.template</td>
+</tr>
+<tr>
+<td>docroot/tus/edit.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/edit.template</td>
+</tr>
+<tr>
+<td>docroot/tus/editAdmin.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/editAdmin.template</td>
+</tr>
+<tr>
+<td>docroot/tus/editAdminResults.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/editAdminResults.template</td>
+</tr>
+<tr>
+<td>docroot/tus/editResults.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/editResults.template</td>
+</tr>
+<tr>
+<td>docroot/tus/error.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/error.template</td>
+</tr>
+<tr>
+<td>docroot/tus/index.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/index.template</td>
+</tr>
+<tr>
+<td>docroot/tus/indexAdmin.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/indexAdmin.template</td>
+</tr>
+<tr>
+<td>docroot/tus/new.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/new.template</td>
+</tr>
+<tr>
+<td>docroot/tus/revoke.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/revoke.template</td>
+</tr>
+<tr>
+<td>docroot/tus/search.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/search.template</td>
+</tr>
+<tr>
+<td>docroot/tus/searchActivity.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/searchActivity.template</td>
+</tr>
+<tr>
+<td>docroot/tus/searchActivityResults.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/searchActivityResults.template</td>
+</tr>
+<tr>
+<td>docroot/tus/searchAdmin.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/searchAdmin.template</td>
+</tr>
+<tr>
+<td>docroot/tus/searchAdminResults.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/searchAdminResults.template</td>
+</tr>
+<tr>
+<td>docroot/tus/searchCertificateResults.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/searchCertificateResults.template</td>
+</tr>
+<tr>
+<td>docroot/tus/searchResults.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/searchResults.template</td>
+</tr>
+<tr>
+<td>docroot/tus/show.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/show.template</td>
+</tr>
+<tr>
+<td>docroot/tus/showAdmin.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/showAdmin.template</td>
+</tr>
+<tr>
+<td>docroot/tus/showCert.template</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/docroot/tus/showCert.template</td>
+</tr>
+<tr>
+<td>lib/</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/lib/</td>
+</tr>
+<tr>
+<td>lib/libldapauth.so</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/lib/libldapauth.so</td>
+</tr>
+<tr>
+<td>lib/libtokendb.so</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/lib/libtokendb.so</td>
+</tr>
+<tr>
+<td>lib/libtps.so</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/lib/libtps.so</td>
+</tr>
+<tr>
+<td>lib/mod_tokendb.so</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/lib/mod_tokendb.so</td>
+</tr>
+<tr>
+<td>lib/mod_tps.so</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/lib/mod_tps.so</td>
+</tr>
+<tr>
+<td>setup/</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/setup/</td>
+</tr>
+<tr>
+<td>setup/addAgents.ldif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/setup/addAgents.ldif</td>
+</tr>
+<tr>
+<td>setup/addIndexes.ldif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/setup/addIndexes.ldif</td>
+</tr>
+<tr>
+<td>setup/addTokens.ldif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/setup/addTokens.ldif</td>
+</tr>
+<tr>
+<td>setup/addVLVIndexes.ldif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/setup/addVLVIndexes.ldif</td>
+</tr>
+<tr>
+<td>setup/schemaMods.ldif</td>
+<td>&lt;pki_server_root&gt;/&lt;common_subsystems_area&gt;/&lt;common_tps_subsystems&gt;/setup/schemaMods.ldif</td>
+</tr>
+</table>
+</ul>
+
+<h2>Inventory of cs-tps-devel-{version} Package</h2>
+<ul>
+<table border=1>
+<tr>
+<th>Packaged File</th>
+<th>Unpackaged File</th>
+</tr>
+<tr>
+<td>include/</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/APDU_Response.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Create_Object_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Create_Pin_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Delete_File_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/External_Authenticate_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Format_Muscle_Applet_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Generate_Key_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Get_Data_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Get_Status_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Get_Version_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Import_Key_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Import_Key_Enc_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Initialize_Update_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Install_Applet_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Install_Load_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Lifecycle_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/List_Objects_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/List_Pins_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Load_File_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Put_Key_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Read_Buffer_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Read_Object_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Select_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Set_Pin_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Unblock_Pin_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/apdu/Write_Object_APDU.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/authentication/</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/authentication/AuthParams.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/authentication/Authentication.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/authentication/LDAP_Authentication.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/channel/</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/channel/Channel.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/channel/Secure_Channel.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/cms/</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/cms/CertEnroll.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/cms/ConnectionInfo.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/cms/HttpConnection.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/engine/</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/engine/RA.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/AccessLogger.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/Auth.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/ByteBuffer.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/CERTUtil.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/Cache.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/Connection.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/ConnectionListener.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/DebugLogger.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/Defines.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/ErrorLogger.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/Iterator.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/LogRotationTask.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/Logger.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/NSPRerrs.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSBuddy.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSBuddyCache.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSBuddyList.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSBuddyListener.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSBuddyService.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSCertExtension.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSCommonLib.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSConfig.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSConfigManager.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSConfigReader.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSCrypt.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSDataSourceListener.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSDataSourceManager.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSGroup.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSGroupCache.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSHelper.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSListener.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSPRUtil.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSPlugin.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSPluginManager.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSServer.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSServerLib.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSServerListener.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSServerManager.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSServiceListener.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSServiceManager.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSUser.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PSWaspLib.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/Pool.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PresenceManager.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PresenceServer.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/PresenceServerImpl.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/SECerrs.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/SSLServerSocket.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/SSLSocket.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/SSLerrs.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/ScheduledTask.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/Scheduler.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/SecurityHeaders.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/ServerConnection.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/ServerHeaderProcessor.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/ServerSocket.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/Socket.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/SocketINC.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/SocketLib.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/StringList.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/StringUtil.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/TaskList.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/ThreadPool.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/URLUtil.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/engine.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/http.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/request.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/httpClient/httpc/response.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/main/</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/main/RA_pblock.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/main/AttributeSpec.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/main/AuthenticationEntry.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/main/Base.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/main/Buffer.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/main/ConfigStore.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/main/Login.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/main/Memory.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/main/MemoryMgr.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/main/NameValueSet.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/main/ObjectSpec.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/main/PKCS11Obj.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/main/PublishEntry.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/main/RA_Context.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/main/RA_Msg.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/main/RA_Session.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/main/SecureId.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/main/Util.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/modules/</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/modules/tps/</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/modules/tps/AP_Context.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/modules/tps/AP_Session.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/msg/</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/msg/RA_ASQ_Request_Msg.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/msg/RA_ASQ_Response_Msg.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/msg/RA_Begin_Op_Msg.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/msg/RA_End_Op_Msg.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/msg/RA_Extended_Login_Request_Msg.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/msg/RA_Extended_Login_Response_Msg.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/msg/RA_Login_Request_Msg.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/msg/RA_Login_Response_Msg.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/msg/RA_New_Pin_Request_Msg.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/msg/RA_New_Pin_Response_Msg.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/msg/RA_SecureId_Request_Msg.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/msg/RA_SecureId_Response_Msg.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/msg/RA_Status_Update_Request_Msg.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/msg/RA_Status_Update_Response_Msg.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/msg/RA_Token_PDU_Request_Msg.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/msg/RA_Token_PDU_Response_Msg.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/processor/</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/processor/RA_Enroll_Processor.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/processor/RA_Format_Processor.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/processor/RA_Pin_Reset_Processor.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/processor/RA_Processor.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/processor/RA_Renew_Processor.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/processor/RA_Unblock_Processor.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/publisher/</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/publisher/IConnector.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/publisher/IPublish_Data.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/publisher/IPublisher.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/publisher/NetkeyPublisher.h</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/tus/</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>include/tus/tus_db.h</td>
+<td>&nbsp;</td>
+</tr>
+</table>
+</ul>
+</body>
+</html>
+
diff --git a/base/tps/applets/1.2.4122DFB4.ijc b/base/tps/applets/1.2.4122DFB4.ijc
new file mode 100644
index 000000000..2a8ea0733
--- /dev/null
+++ b/base/tps/applets/1.2.4122DFB4.ijc
Binary files differ
diff --git a/base/tps/applets/1.2.416DA155.ijc b/base/tps/applets/1.2.416DA155.ijc
new file mode 100755
index 000000000..21b0312a8
--- /dev/null
+++ b/base/tps/applets/1.2.416DA155.ijc
Binary files differ
diff --git a/base/tps/applets/1.3.42260AFA.ijc b/base/tps/applets/1.3.42260AFA.ijc
new file mode 100755
index 000000000..f17f98281
--- /dev/null
+++ b/base/tps/applets/1.3.42260AFA.ijc
Binary files differ
diff --git a/base/tps/applets/1.3.4255CC01.ijc b/base/tps/applets/1.3.4255CC01.ijc
new file mode 100644
index 000000000..322fe86e2
--- /dev/null
+++ b/base/tps/applets/1.3.4255CC01.ijc
Binary files differ
diff --git a/base/tps/applets/1.3.42659461.ijc b/base/tps/applets/1.3.42659461.ijc
new file mode 100755
index 000000000..ccf8ba451
--- /dev/null
+++ b/base/tps/applets/1.3.42659461.ijc
Binary files differ
diff --git a/base/tps/applets/1.3.427BDDB8.ijc b/base/tps/applets/1.3.427BDDB8.ijc
new file mode 100644
index 000000000..4a633e8d3
--- /dev/null
+++ b/base/tps/applets/1.3.427BDDB8.ijc
Binary files differ
diff --git a/base/tps/applets/1.3.44724DDE.ijc b/base/tps/applets/1.3.44724DDE.ijc
new file mode 100755
index 000000000..e56705dff
--- /dev/null
+++ b/base/tps/applets/1.3.44724DDE.ijc
Binary files differ
diff --git a/base/tps/applets/1.3.45787308.ijc b/base/tps/applets/1.3.45787308.ijc
new file mode 100755
index 000000000..164c7e0cd
--- /dev/null
+++ b/base/tps/applets/1.3.45787308.ijc
Binary files differ
diff --git a/base/tps/applets/1.4.499dc06c.ijc b/base/tps/applets/1.4.499dc06c.ijc
new file mode 100644
index 000000000..388482123
--- /dev/null
+++ b/base/tps/applets/1.4.499dc06c.ijc
Binary files differ
diff --git a/base/tps/applets/1.4.4d40a449.ijc b/base/tps/applets/1.4.4d40a449.ijc
new file mode 100644
index 000000000..bd716adb0
--- /dev/null
+++ b/base/tps/applets/1.4.4d40a449.ijc
Binary files differ
diff --git a/base/tps/applets/3FD00877.ijc b/base/tps/applets/3FD00877.ijc
new file mode 100644
index 000000000..5e6624d5a
--- /dev/null
+++ b/base/tps/applets/3FD00877.ijc
Binary files differ
diff --git a/base/tps/applets/4003196C.ijc b/base/tps/applets/4003196C.ijc
new file mode 100644
index 000000000..bed8a7900
--- /dev/null
+++ b/base/tps/applets/4003196C.ijc
Binary files differ
diff --git a/base/tps/applets/402428AD.ijc b/base/tps/applets/402428AD.ijc
new file mode 100644
index 000000000..b91a64334
--- /dev/null
+++ b/base/tps/applets/402428AD.ijc
Binary files differ
diff --git a/base/tps/applets/404E4697.ijc b/base/tps/applets/404E4697.ijc
new file mode 100644
index 000000000..9c927c0f0
--- /dev/null
+++ b/base/tps/applets/404E4697.ijc
Binary files differ
diff --git a/base/tps/applets/4122DFB4.ijc b/base/tps/applets/4122DFB4.ijc
new file mode 100644
index 000000000..2a8ea0733
--- /dev/null
+++ b/base/tps/applets/4122DFB4.ijc
Binary files differ
diff --git a/base/tps/applets/listappletdates b/base/tps/applets/listappletdates
new file mode 100755
index 000000000..a9e5c49ca
--- /dev/null
+++ b/base/tps/applets/listappletdates
@@ -0,0 +1,42 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+
+$f = `/bin/ls *.ijc`;
+
+@filenames = split /\n/ms, $f;
+
+foreach $file (@filenames) {
+ $timestamp = $file;
+ $timestamp =~ s/1\.\d\.//;
+
+ ($root) = ($timestamp =~ /(.*).ijc/);
+
+ ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(hex($root));
+
+ printf " %16s %4d/%02d/%02d %02d:%02d\n", $file,
+ $year+1900, $mon+1, $mday,
+ $hour, $min;
+
+}
+
diff --git a/base/tps/applets/readme.txt b/base/tps/applets/readme.txt
new file mode 100644
index 000000000..9dd2a87ef
--- /dev/null
+++ b/base/tps/applets/readme.txt
@@ -0,0 +1,52 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+This directory contains a list of CoolKey applets
+that can be used by the TPS for applet upgrade.
+
+
+Applet Information:
+------------------
+
+File Name Creation Date Applet Ver Major Ver Minor Ver Remark
+============ ================ ========== ========= ========= ==========
+427BDDB8.ijc 2005/05/06 14:12 427BDDB8 1 3 Official Applet
+
+Token Information:
+-----------------
+
+Type CUID (Token ID) ATR Remark
+======================== ==================== ======= ==================
+Old "E" and ealier cards 40900062ff00ssssssss
+(Acquired From WebSite)
+"F" cards 40900062ff00ssssssss
+(Acquired From WebSite)
+"G" & later (Oct/Nov) 409000620103ssssssss
+(Acquired From WebSite)
+Fortezza cards 409000620103ssssssss
+(Acquired From WebSite)
+Developement Keyed cards 409000620101ssssssss 3B76940000FF6276010000
+
+where ssssssss is the serial number.
+
+
+Remark
+======
+1.3.45787308.ijc - this is the unofficial jForte applet with hacks
diff --git a/base/tps/doc/CMakeLists.txt b/base/tps/doc/CMakeLists.txt
new file mode 100644
index 000000000..4cebbe1c9
--- /dev/null
+++ b/base/tps/doc/CMakeLists.txt
@@ -0,0 +1,10 @@
+set(VERSION ${APPLICATION_VERSION})
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CS.cfg.in ${CMAKE_CURRENT_BINARY_DIR}/CS.cfg @ONLY)
+
+install(
+ FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/CS.cfg
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/conf
+)
diff --git a/base/tps/doc/CS.cfg.in b/base/tps/doc/CS.cfg.in
new file mode 100644
index 000000000..e712934c9
--- /dev/null
+++ b/base/tps/doc/CS.cfg.in
@@ -0,0 +1,1589 @@
+_000=##
+_001=## Token Processing System (TPS) Configuration File
+_002=##
+pidDir=[PKI_PIDDIR]
+pkicreate.pki_instance_root=[PKI_INSTANCE_ROOT]
+pkicreate.pki_instance_name=[PKI_INSTANCE_ID]
+pkicreate.subsystem_type=[PKI_SUBSYSTEM_TYPE]
+pkicreate.secure_port=[SECURE_PORT]
+pkicreate.non_clientauth_secure_port=[NON_CLIENTAUTH_SECURE_PORT]
+pkicreate.unsecure_port=[PORT]
+pkicreate.user=[PKI_USER]
+pkicreate.group=[PKI_GROUP]
+pkiremove.cert.subsystem.nickname=subsystemCert cert-[PKI_INSTANCE_ID]
+cs.type=TPS
+selftests._000=##
+selftests._001=## Self Tests
+selftests._002=##
+selftests._003=## The Self-Test plugin TPSSystemCertsVerification uses the
+selftests._004=## following parameters (where certusage is optional):
+selftests._005=## tps.cert.list = <list of cert tag names deliminated by ",">
+selftests._006=## tps.cert.<cert tag name>.nickname
+selftests._007=## tps.cert.<cert tag name>.certusage
+selftests._008=##
+selftests.container.logger.enable=true
+selftests.container.logger.expirationTime=0
+selftests.container.logger.file.type=RollingLogFile
+selftests.container.logger.fileName=[SERVER_ROOT]/logs/selftests.log
+selftests.container.logger.level=10
+selftests.container.logger.maxFileSize=2000
+selftests.container.logger.rolloverInterval=2592000
+selftests.container.order.startup=TPSPresence:critical, TPSSystemCertsVerification:critical
+selftests.container.order.onDemand=TPSPresence:critical, TPSValidity:critical, TPSSystemCertsVerification:critical
+selftests.plugin.TPSPresence.nickname=[HSM_LABEL][NICKNAME]
+selftests.plugin.TPSValidity.nickname=[HSM_LABEL][NICKNAME]
+service.machineName=[SERVER_NAME]
+service.instanceDir=[SERVER_ROOT]
+service.securePort=[SECURE_PORT]
+service.non_clientauth_securePort=[NON_CLIENTAUTH_SECURE_PORT]
+service.unsecurePort=[PORT]
+service.instanceID=[PKI_INSTANCE_ID]
+logging._000=#########################################
+logging._001=# RA configuration File
+logging._002=#
+logging._003=# All <...> must be replaced with
+logging._004=# appropriate values.
+logging._005=#########################################
+logging._006=########################################
+logging._007=# logging
+logging._008=#
+logging._009=# logging.debug.enable:
+logging._010=# logging.audit.enable:
+logging._011=# logging.error.enable:
+logging._012=# - enable or disable the corresponding logging
+logging._013=# logging.debug.filename:
+logging._014=# logging.audit.filename:
+logging._015=# logging.error.filename:
+logging._016=# - name of the log file
+logging._017=# logging.debug.level:
+logging._018=# logging.audit.level:
+logging._019=# logging.error.level:
+logging._020=# - level of logging. (0-10)
+logging._021=# 0 - no logging,
+logging._022=# 4 - LL_PER_SERVER these messages will occur only once
+logging._023=# during the entire invocation of the
+logging._024=# server, e. g. at startup or shutdown
+logging._025=# time., reading the conf parameters.
+logging._026=# Perhaps other infrequent events
+logging._027=# relating to failing over of CA, TKS,
+logging._028=# too
+logging._029=# 6 - LL_PER_CONNECTION these messages happen once per
+logging._030=# connection - most of the log events
+logging._031=# will be at this level
+logging._032=# 8 - LL_PER_PDU these messages relate to PDU
+logging._033=# processing. If you have something that
+logging._034=# is done for every PDU, such as
+logging._035=# applying the MAC, it should be logged
+logging._036=# at this level
+logging._037=# 9 - LL_ALL_DATA_IN_PDU dump all the data in the PDU - a more
+logging._038=# chatty version of the above
+logging._039=# 10 - all logging
+logging._040=# logging.audit.buffer.size: # in bytes
+logging._041=# logging.audit.flush.interval: # in seconds, 0 disables flush thread
+logging._042=# logging.*.file.type:
+logging._043=# - file type: RollingLogFile or LogFile
+logging._044=# logging.*.rolloverInterval:
+logging._045=# - interval to roll over logs (seconds), 0 to disable rollover
+logging._046=# logging.*.maxFileSize:
+logging._047=# - size at which file rollover occurs, in kB
+logging._048=# logging.*.expirationTime:
+logging._049=# - maximum age of log, older unmodified logs are deleted( in seconds, 0 to disable)
+logging._050=#########################################
+logging.debug.enable=true
+logging.debug.filename=[SERVER_ROOT]/logs/tps-debug.log
+logging.debug.level=10
+logging.debug.file.type=RollingLogFile
+logging.debug.maxFileSize=2000
+logging.debug.rolloverInterval=2592000
+logging.debug.expirationTime=0
+logging.audit.enable=true
+logging.audit.filename=[SERVER_ROOT]/logs/tps-audit.log
+logging.audit.signedAuditFilename=[SERVER_ROOT]/logs/signedAudit/tps_audit
+logging.audit.level=10
+logging.audit.logSigning=false
+logging.audit.signedAuditCertNickname=auditSigningCert cert-[PKI_INSTANCE_ID]
+logging.audit.selected.events=AUTHZ_SUCCESS,AUTHZ_FAIL,AUTH_FAIL,AUTH_SUCCESS,ROLE_ASSUME,ENROLLMENT,PIN_RESET,FORMAT,CONFIG,CONFIG_ROLE,CONFIG_TOKEN,CONFIG_PROFILE,CONFIG_AUDIT,APPLET_UPGRADE,KEY_CHANGEOVER,RENEWAL,CIMC_CERT_VERIFICATION
+logging.audit.selectable.events=AUTHZ_SUCCESS,AUTHZ_FAIL,AUTH_FAIL,AUTH_SUCCESS,ROLE_ASSUME,ENROLLMENT,PIN_RESET,FORMAT,CONFIG,CONFIG_ROLE,CONFIG_TOKEN,CONFIG_PROFILE,CONFIG_AUDIT,APPLET_UPGRADE,KEY_CHANGEOVER,RENEWAL,CIMC_CERT_VERIFICATION
+logging.audit.nonselectable.events=AUDIT_LOG_STARTUP,AUDIT_LOG_SHUTDOWN,LOGGING_SIGNED_AUDIT_SIGNING
+logging.audit.buffer.size=512
+logging.audit.flush.interval=5
+logging.audit.file.type=RollingLogFile
+logging.audit.maxFileSize=2000
+logging.audit.rolloverInterval=2592000
+logging.audit.expirationTime=0
+logging.error.enable=true
+logging.error.filename=[SERVER_ROOT]/logs/tps-error.log
+logging.error.level=10
+logging.error.file.type=RollingLogFile
+logging.error.maxFileSize=2000
+logging.error.rolloverInterval=2592000
+logging.error.expirationTime=0
+conn.ca1._000=#########################################
+conn.ca1._001=# CA connection
+conn.ca1._002=#
+conn.ca1._003=# conn.ca<n>.hostport:
+conn.ca1._004=# - host name and port number of your CA, format is host:port
+conn.ca1._005=# conn.ca<n>.clientNickname:
+conn.ca1._006=# - nickname of the client certificate for
+conn.ca1._007=# authentication
+conn.ca1._008=# conn.ca<n>.servlet.enrollment:
+conn.ca1._009=# - servlet to contact in CA
+conn.ca1._010=# - must be '/ca/profileSubmitSSLClient'
+conn.ca1._011=# conn.ca<n>.retryConnect:
+conn.ca1._012=# - number of reconnection attempts on failure
+conn.ca1._013=# conn.ca<n>.timeout:
+conn.ca1._014=# - connection timeout
+conn.ca1._015=# conn.ca<n>.SSLOn:
+conn.ca1._016=# - enable SSL or not
+conn.ca1._017=# conn.ca<n>.keepAlive:
+conn.ca1._018=# - enable keep alive or not
+conn.ca1._019=#
+conn.ca1._020=# where
+conn.ca1._021=# <n> - CA connection ID
+conn.ca1._022=#########################################
+failover.pod.enable=false
+conn.ca1.hostport=[CA_HOST]:[CA_PORT]
+conn.ca1.clientNickname=[HSM_LABEL][NICKNAME]
+conn.ca1.servlet.enrollment=/ca/ee/ca/profileSubmitSSLClient
+conn.ca1.servlet.renewal=/ca/ee/ca/profileSubmitSSLClient
+conn.ca1.servlet.revoke=/ca/ee/subsystem/ca/doRevoke
+conn.ca1.servlet.unrevoke=/ca/ee/subsystem/ca/doUnrevoke
+conn.ca1.retryConnect=3
+conn.ca1.timeout=100
+conn.ca1.SSLOn=true
+conn.ca1.keepAlive=true
+conn.tks1._000=#########################################
+conn.tks1._001=# TKS connection
+conn.tks1._002=#
+conn.tks1._003=# conn.tks<n>.hostport:
+conn.tks1._004=# - host name and port number of your TKS, the format is host:port
+conn.tks1._005=# conn.tks<n>.clientNickname:
+conn.tks1._006=# - nickname of the client certificate for
+conn.tks1._007=# authentication
+conn.tks1._008=# conn.tks<n>.servlet.computeSessionKey:
+conn.tks1._009=# - servlet to compute session key
+conn.tks1._010=# - must be '/tks/computeSessionKey'
+conn.tks1._011=# conn.tks<n>.servlet.encryptData:
+conn.tks1._012=# - servlet to encrypt data
+conn.tks1._013=# - must be '/tks/encryptData'
+conn.tks1._014=# conn.tks<n>.servlet.createKeySetData:
+conn.tks1._015=# - servlet to create key set data
+conn.tks1._016=# - must be '/tks/createKeySetData'
+conn.tks1._017=# conn.tks<n>.retryConnect:
+conn.tks1._018=# - number of reconnection attempts on failure
+conn.tks1._019=# conn.tks<n>.SSLOn
+conn.tks1._020=# - enable SSL or not
+conn.tks1._021=# conn.tks<n>.keepAlive:
+conn.tks1._022=# - enable keep alive or not
+conn.tks1._023=#
+conn.tks1._024=# where
+conn.tks1._025=# <n> - TKS connection ID
+conn.tks1._026=# conn.tks<n>.tksSharedSymKeyName:
+conn.tks1._027=# - set shared secret key name
+conn.tks1._028=#########################################
+conn.tks1.hostport=[TKS_HOST]:[TKS_PORT]
+conn.tks1.clientNickname=[HSM_LABEL][NICKNAME]
+conn.tks1.servlet.computeSessionKey=/tks/agent/tks/computeSessionKey
+conn.tks1.servlet.encryptData=/tks/agent/tks/encryptData
+conn.tks1.servlet.createKeySetData=/tks/agent/tks/createKeySetData
+conn.tks1.servlet.computeRandomData=/tks/agent/tks/computeRandomData
+conn.tks1.retryConnect=3
+conn.tks1.timeout=100
+conn.tks1.generateHostChallenge=true
+conn.tks1.SSLOn=true
+conn.tks1.keepAlive=false
+conn.tks1.keySet=defKeySet
+conn.tks1.serverKeygen=[SERVER_KEYGEN]
+conn.tks1.tksSharedSymKeyName=sharedSecret
+conn.drm1._000=#########################################
+conn.drm1._001=# DRM connection
+conn.drm1._002=#
+conn.drm1._003=#conn.drm.totalConns
+conn.drm1._004=# - # of DRM connections
+conn.drm1._005=#conn.drm<n>.hostport
+conn.drm1._006=# - host name and port number of your DRM, the format is host:port
+conn.drm1._007=#conn.drm<n>.clientNickname
+conn.drm1._008=# - nickname of the client certificate for
+conn.drm1._009=# authentication
+conn.drm1._010=#conn.drm<n>.servlet.GenerateKeyPair
+conn.drm1._011=# - servlet to generate key pairs and archive keys on DRM
+conn.drm1._012=# - must be '/kra/GenerateKeyPair'
+conn.drm1._013=#conn.drm<n>.servlet.TokenKeyRecovery=/kra/TokenKeyRecovery
+conn.drm1._014=# - servlet to handle key recovery
+conn.drm1._015=# - must be '/kra/TokenKeyRecovery'
+conn.drm1._016=#conn.drm<n>.retryConnect=3
+conn.drm1._017=# - number of reconnection attempts on failure
+conn.drm1._018=#conn.drm<n>.SSLOn=true
+conn.drm1._019=# - enable SSL or not
+conn.drm1._020=#conn.drm<n>.keepAlive=false
+conn.drm1._021=# - enable keep alive or not
+conn.drm1._022=#
+conn.drm1._023=# where
+conn.drm1._024=# <n> - DRM connection ID
+conn.drm1._025=#########################################
+conn.drm.totalConns=1
+conn.drm1.hostport=[DRM_HOST]:[DRM_PORT]
+conn.drm1.clientNickname=[HSM_LABEL][NICKNAME]
+conn.drm1.servlet.GenerateKeyPair=/kra/agent/kra/GenerateKeyPair
+conn.drm1.servlet.TokenKeyRecovery=/kra/agent/kra/TokenKeyRecovery
+conn.drm1.retryConnect=3
+conn.drm1.timeout=100
+conn.drm1.SSLOn=true
+conn.drm1.keepAlive=false
+auth.instance._000=########################################
+auth.instance._001=# publishing
+auth.instance._002=#
+auth.instance._003=# publisher.instance.<n>.libraryName:
+auth.instance._004=# - name of the library specified with a fully qualified path name
+auth.instance._005=# publisher.instance.<n>.libraryFactory:
+auth.instance._006=# - the name of the function which instantiates the publisher
+auth.instance._007=# publisher.instance.<n>.publisherId:
+auth.instance._008=# - the publisher ID
+auth.instance._009=#
+auth.instance._010=# where
+auth.instance._011=# <n> - publisher connection ID
+auth.instance._012=########################################
+auth.instance._013=#########################################
+auth.instance._014=# authentication
+auth.instance._015=#
+auth.instance._016=# auth.instance.<n>.libraryName:
+auth.instance._017=# - name of the library specified with a fully qualified path name
+auth.instance._018=# auth.instance.<n>.libraryFactory:
+auth.instance._019=# - the name of the function which instantiates the authentication
+auth.instance._020=# auth.instance.<n>.authId
+auth.instance._021=# - the authentication ID
+auth.instance._022=# auth.instance.<n>.hostport
+auth.instance._023=# - parameter specific to the given authentication,
+auth.instance._024=# i. e., LDAPAuthentication (id=ldap1)
+auth.instance._025=# - host name and port number, host:port
+auth.instance._026=# - for failover, provide multiple host:port designations
+auth.instance._027=# separated by " "
+auth.instance._028=# auth.instance.<n>.SSLOn:
+auth.instance._029=# - parameter specific to the given authentication,
+auth.instance._030=# i. e., LDAPAuthentication (id=ldap1)
+auth.instance._031=# - use SSL or not for LDAP service
+auth.instance._032=# auth.instance.<n>.retries:
+auth.instance._033=# - parameter specific to the given authentication,
+auth.instance._034=# i. e., LDAPAuthentication (id=ldap1)
+auth.instance._035=# - number of authentication re-attempts when authentication failed
+auth.instance._036=# auth.instance.<n>.retryConnect:
+auth.instance._037=# - parameter specific to the given authentication,
+auth.instance._038=# i. e., LDAPAuthentication (id=ldap1)
+auth.instance._039=# - number of connection re-attempts when connection failed
+auth.instance._040=#
+auth.instance._041=# where
+auth.instance._042=# <n> - authentication connection ID
+auth.instance._043=#########################################
+auth.instance.0.type=LDAP_Authentication
+auth.instance.0.libraryName=[SYSTEM_USER_LIBRARIES]/tps/[LIB_PREFIX]ldapauth[OBJ_EXT]
+auth.instance.0.libraryFactory=GetAuthentication
+auth.instance.0.authId=ldap1
+auth.instance.0.hostport=[LDAP_HOST]:[LDAP_PORT]
+auth.instance.0.SSLOn=false
+auth.instance.0.retries=1
+auth.instance.0.retryConnect=3
+auth.instance.0.baseDN=[LDAP_ROOT]
+auth.instance.0.ssl=false
+auth.instance.0.attributes._001=##############################################
+auth.instance.0.attributes._002=# attributes will be available
+auth.instance.0.attributes._003=# as $auth.<attribute>$
+auth.instance.0.attributes._004=##############################################
+auth.instance.0.attributes=mail,cn,uid
+auth.instance.0.ui.title.en=LDAP Authentication
+auth.instance.0.ui.description.en=This authenticates user against the LDAP directory.
+auth.instance.0.ui.id.UID.name.en=LDAP User ID
+auth.instance.0.ui.id.PASSWORD.name.en=LDAP Password
+auth.instance.0.ui.id.UID.description.en=LDAP User ID
+auth.instance.0.ui.id.PASSWORD.description.en=LDAP Password
+auth.instance.1.type=LDAP_Authentication
+auth.instance.1.libraryName=[SYSTEM_USER_LIBRARIES]/tps/[LIB_PREFIX]ldapauth[OBJ_EXT]
+auth.instance.1.libraryFactory=GetAuthentication
+auth.instance.1.authId=ldap2
+auth.instance.1.bindDN=cn=Directory Manager
+auth.instance.1.bindPWD=[SERVER_ROOT]/conf/password.conf
+auth.instance.1.hostport=[TOKENDB_HOST]:[TOKENDB_PORT]
+auth.instance.1.SSLOn=false
+auth.instance.1.retries=1
+auth.instance.1.retryConnect=3
+auth.instance.1.baseDN=[TOKENDB_ROOT]
+auth.instance.1.ssl=false
+auth.instance.1.attributes._001=##############################################
+auth.instance.1.attributes._002=# attributes will be available
+auth.instance.1.attributes._003=# as $auth.<attribute>$
+auth.instance.1.attributes._004=##############################################
+auth.instance.1.attributes=mail,cn,uid
+auth.instance.1.ui.title.en=LDAP Authentication
+auth.instance.1.ui.description.en=This authenticates user against the LDAP directory.
+auth.instance.1.ui.id.UID.name.en=LDAP User ID
+auth.instance.1.ui.id.PASSWORD.name.en=LDAP Password
+auth.instance.1.ui.id.UID.description.en=LDAP User ID
+auth.instance.1.ui.id.PASSWORD.description.en=LDAP Password
+applet._000=#########################################
+applet._001=# applet information
+applet._002=# SAF Key:
+applet._003=# applet.aid.cardmgr_instance=A0000001510000
+applet._004=#########################################
+applet.aid.cardmgr_instance=A0000000030000
+applet.aid.netkey_instance=627601FF000000
+applet.aid.netkey_file=627601FF0000
+applet.aid.netkey_old_instance=A00000000101
+applet.aid.netkey_old_file=A000000001
+applet.so_pin=000000000000
+applet.delete_old=true
+general.verifyProof=1
+general.applet_ext=ijc
+general.search.sizelimit.max=2000
+general.search.sizelimit.default=100
+general.search.timelimit.max=10
+general.search.timelimit.default=10
+general.pwlength.min=16
+channel._000=#########################################
+channel._001=# channel.encryption:
+channel._002=#
+channel._003=# - enable encryption for all operation commands to token
+channel._004=# - default is true
+channel._005=# channel.blocksize=242
+channel._006=# channel.defKeyVersion=0
+channel._007=# channel.defKeyIndex=0
+channel._008=#########################################
+channel.encryption=true
+channel.blocksize=248
+channel.defKeyVersion=0
+channel.defKeyIndex=0
+# NOTE: Since the following comments will be 'scrubbed' from any TPS
+# instance's configuration file, they will ONLY be viewable in
+# the '/usr/share/pki/tps/conf/CS.cfg' TPS subsystem template!
+#
+# Config the size of memory managed memory in the applet
+# Default is 5000, try not go get close to the instanceSize
+# which defaults to 18000:
+#
+# * channel.instanceSize=18000
+# * channel.appletMemorySize=5000
+#
+preop.pin=[PKI_RANDOM_NUMBER]
+preop.product.version=@VERSION@
+preop.cert._000=#########################################
+preop.cert._001=# Installation configuration "preop" certs parameters
+preop.cert._002=#########################################
+preop.cert.list=sslserver,subsystem,audit_signing
+tps.cert.audit_signing.certusage=ObjectSigner
+tps.cert.sslserver.certusage=SSLServer
+tps.cert.subsystem.certusage=SSLClient
+preop.cert.sslserver.enable=true
+preop.cert.subsystem.enable=true
+preop.cert.audit_signing.enable=false
+preop.cert.sslserver.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.sslserver.dn=CN=[SERVER_NAME], OU=[PKI_INSTANCE_ID]
+preop.cert.sslserver.keysize.customsize=2048
+preop.cert.sslserver.keysize.size=2048
+preop.cert.sslserver.keysize.select=custom
+preop.cert.sslserver.nickname=Server-Cert cert-[PKI_INSTANCE_ID]
+preop.cert.sslserver.profile=caInternalAuthServerCert
+preop.cert.sslserver.subsystem=tps
+preop.cert._003=#preop.cert.sslserver.type=local
+preop.cert.sslserver.userfriendlyname=SSL Server Certificate
+preop.cert._004=#preop.cert.sslserver.cncomponent.override=false
+preop.cert.subsystem.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.subsystem.dn=CN=TPS Subsystem Certificate, OU=[PKI_INSTANCE_ID]
+preop.cert.subsystem.keysize.customsize=2048
+preop.cert.subsystem.keysize.size=2048
+preop.cert.subsystem.keysize.select=custom
+preop.cert.subsystem.nickname=subsystemCert cert-[PKI_INSTANCE_ID]
+preop.cert.subsystem.profile=caInternalAuthSubsystemCert
+preop.cert.subsystem.subsystem=tps
+preop.cert._005=#preop.cert.subsystem.type=local
+preop.cert.subsystem.userfriendlyname=Subsystem Certificate
+preop.cert._006=#preop.cert.subsystem.cncomponent.override=true
+preop.cert.audit_signing.defaultSigningAlgorithm=SHA256withRSA
+preop.cert.audit_signing.dn=CN=TPS Audit Signing Certificate, OU=[PKI_INSTANCE_ID]
+preop.cert.audit_signing.keysize.customsize=2048
+preop.cert.audit_signing.keysize.size=2048
+preop.cert.audit_signing.keysize.select=custom
+preop.cert.audit_signing.nickname=auditSigningCert cert-[PKI_INSTANCE_ID]
+preop.cert.audit_signing.profile=caInternalAuthAuditSigningCert
+preop.cert.audit_signing.subsystem=tps
+preop.cert._005=#preop.cert.audit_signing.type=local
+preop.cert.audit_signing.userfriendlyname=Audit Log Signing Certificate
+preop.cert._006=#preop.cert.audit_signing.cncomponent.override=true
+preop.configModules._000=#########################################
+preop.configModules._001=# Installation configuration "preop" module parameters
+preop.configModules._002=#########################################
+preop.configModules.count=3
+preop.configModules.module0.commonName=NSS Internal PKCS #11 Module
+preop.configModules.module0.imagePath=../img/clearpixel.gif
+preop.configModules.module0.userFriendlyName=NSS Internal PKCS #11 Module
+preop.configModules.module1.commonName=nfast
+preop.configModules.module1.imagePath=../img/clearpixel.gif
+preop.configModules.module1.userFriendlyName=nCipher's nFast Token Hardware Module
+preop.configModules.module2.commonName=lunasa
+preop.configModules.module2.imagePath=../img/clearpixel.gif
+preop.configModules.module2.userFriendlyName=SafeNet's LunaSA Token Hardware Module
+preop.module.token=NSS Certificate DB
+preop.keysize._000=#########################################
+preop.keysize._001=# Installation configuration "preop" keysize parameters
+preop.keysize._002=#########################################
+preop.keysize.customsize=2048
+preop.keysize.select=default
+preop.keysize.size=2048
+preop.keysize.ecc.size=256
+preop.adminauth.done=false
+preop.adminpanel.done=false
+preop.agentauth.done=false
+preop.authdb.done=false
+preop.cainfo.done=false
+preop.certprettyprint.done=false
+preop.certrequest.done=false
+preop.confighsmlogin.done=false
+preop.confighsm.done=false
+preop.database.done=false
+preop.displaycertchain2.done=false
+preop.displaycertchain.done=false
+preop.donepanel.done=false
+preop.drminfo.done=false
+preop.importadmincert.done=false
+preop.loginpanel.done=false
+preop.ModulePanel.done=false
+preop.namepanel.done=false
+preop.securitydomain.done=false
+preop.SizePanel.done=false
+preop.subsystemtype.done=false
+preop.tksinfo.done=false
+preop.welcome.done=false
+op.enroll._000=#########################################
+op.enroll._001=# Default Operations
+op.enroll._002=#
+op.enroll._003=# op.<op>.mapping.order=<n>,<n>,<n>
+op.enroll._004=# - contains at least one value or a series
+op.enroll._005=# of comma-separated mapping values which
+op.enroll._006=# are checked in sequential order
+op.enroll._007=# op.<op>.mapping.<n>.filter.tokenType=userKey
+op.enroll._008=# - can be either empty or token type
+op.enroll._009=# specified by the client
+op.enroll._010=# op.<op>.mapping.<n>.filter.tokenATR=
+op.enroll._011=# - can be either empty or token ATR
+op.enroll._012=# specified by the client
+op.enroll._013=# op.<op>.mapping.<n>.filter.appletMajorVersion=1
+op.enroll._014=# - can be either empty or applet major version
+op.enroll._015=# specified by the client
+op.enroll._016=# op.<op>.mapping.<n>.filter.appletMinorVersion=
+op.enroll._017=# - can be either empty or applet minor version
+op.enroll._018=# specified by the client
+op.enroll._019=# - if major and minor versions are both zero, this
+op.enroll._020=# indicate there is no applet on the token.
+op.enroll._021=# op.<op>.mapping.<n>.target.tokenType=userKey
+op.enroll._022=# - if tokenType, tokenATR, appletMajorVersion,
+op.enroll._023=# and appletMinorVersion are matched, value in
+op.enroll._024=# targetTokenType will be used to locate
+op.enroll._025=# the corresponding token profile to
+op.enroll._026=# process the request.
+op.enroll._027=#
+op.enroll._028=# where
+op.enroll._029=# <op> - operation; enroll,pinReset,format
+op.enroll._030=# <n> - mapping ID; order is specifiable
+op.enroll._031=#
+op.enroll._032=# Token ATR:
+op.enroll._033=# Web Store - 3B759400006202020201
+op.enroll._034=#########################################
+op.enroll.mapping.order=0,1,2
+op.enroll.mapping.0.filter.tokenType=userKey
+op.enroll.mapping.0.filter.tokenATR=
+op.enroll.mapping.0.filter.tokenCUID.start=
+op.enroll.mapping.0.filter.tokenCUID.end=
+op.enroll.mapping.0.filter.appletMajorVersion=1
+op.enroll.mapping.0.filter.appletMinorVersion=
+op.enroll.mapping.0.target.tokenType=userKey
+op.enroll.mapping.1.filter.tokenType=soKey
+op.enroll.mapping.1.filter.tokenATR=
+op.enroll.mapping.1.filter.tokenCUID.start=
+op.enroll.mapping.1.filter.tokenCUID.end=
+op.enroll.mapping.1.filter.appletMajorVersion=
+op.enroll.mapping.1.filter.appletMinorVersion=
+op.enroll.mapping.1.target.tokenType=soKey
+op.enroll.mapping.2.filter.tokenType=
+op.enroll.mapping.2.filter.tokenATR=
+op.enroll.mapping.2.filter.tokenCUID.start=
+op.enroll.mapping.2.filter.tokenCUID.end=
+op.enroll.mapping.2.filter.appletMajorVersion=
+op.enroll.mapping.2.filter.appletMinorVersion=
+op.enroll.mapping.2.target.tokenType=userKey
+op.pinReset.mapping.order=0
+op.pinReset.mapping.0.filter.tokenType=
+op.pinReset.mapping.0.filter.tokenATR=
+op.pinReset.mapping.0.filter.tokenCUID.start=
+op.pinReset.mapping.0.filter.tokenCUID.end=
+op.pinReset.mapping.0.filter.appletMajorVersion=
+op.pinReset.mapping.0.filter.appletMinorVersion=
+op.pinReset.mapping.0.target.tokenType=userKey
+op.format.mapping.order=0,1,2,3,4,5,6
+op.format.mapping.0.filter.tokenType=soCleanUserToken
+op.format.mapping.0.filter.tokenATR=
+op.format.mapping.0.filter.tokenCUID.start=
+op.format.mapping.0.filter.tokenCUID.end=
+op.format.mapping.0.filter.appletMajorVersion=
+op.format.mapping.0.filter.appletMinorVersion=
+op.format.mapping.0.target.tokenType=soCleanUserToken
+op.format.mapping.1.filter.tokenType=soUserKey
+op.format.mapping.1.filter.tokenATR=
+op.format.mapping.1.filter.tokenCUID.start=
+op.format.mapping.1.filter.tokenCUID.end=
+op.format.mapping.1.filter.appletMajorVersion=
+op.format.mapping.1.filter.appletMinorVersion=
+op.format.mapping.1.target.tokenType=soUserKey
+op.format.mapping.2.filter.tokenType=soKey
+op.format.mapping.2.filter.tokenATR=
+op.format.mapping.2.filter.tokenCUID.start=
+op.format.mapping.2.filter.tokenCUID.end=
+op.format.mapping.2.filter.appletMajorVersion=
+op.format.mapping.2.filter.appletMinorVersion=
+op.format.mapping.2.target.tokenType=soKey
+op.format.mapping.3.filter.tokenType=userKey
+op.format.mapping.3.filter.tokenATR=
+op.format.mapping.3.filter.tokenCUID.start=
+op.format.mapping.3.filter.tokenCUID.end=
+op.format.mapping.3.filter.appletMajorVersion=
+op.format.mapping.3.filter.appletMinorVersion=
+op.format.mapping.3.target.tokenType=userKey
+op.format.mapping.4.filter.tokenType=soCleanSOToken
+op.format.mapping.4.filter.tokenATR=
+op.format.mapping.4.filter.tokenCUID.start=
+op.format.mapping.4.filter.tokenCUID.end=
+op.format.mapping.4.filter.appletMajorVersion=
+op.format.mapping.4.filter.appletMinorVersion=
+op.format.mapping.5.filter.tokenType=cleanToken
+op.format.mapping.5.filter.tokenATR=
+op.format.mapping.5.filter.tokenCUID.start=
+op.format.mapping.5.filter.tokenCUID.end=
+op.format.mapping.5.filter.appletMajorVersion=
+op.format.mapping.5.filter.appletMinorVersion=
+op.format.mapping.5.target.tokenType=cleanToken
+op.format.mapping.4.target.tokenType=soCleanSOToken
+op.format.mapping.6.filter.tokenATR=
+op.format.mapping.6.filter.tokenCUID.start=
+op.format.mapping.6.filter.tokenCUID.end=
+op.format.mapping.6.filter.appletMajorVersion=
+op.format.mapping.6.filter.appletMinorVersion=
+op.format.mapping.6.target.tokenType=tokenKey
+op.enroll.userKey._000=#########################################
+op.enroll.userKey._001=# Enrollment Operation For CoolKey
+op.enroll.userKey._002=#
+op.enroll.userKey._003=# op.enroll.<tokenType>.keyGen.<keyType>.keySize=1024
+op.enroll.userKey._004=# - size of the key the token should generate
+op.enroll.userKey._005=# - max value: 1024
+op.enroll.userKey._006=#
+op.enroll.userKey._007=# op.enroll.<tokenType>.keyGen.<keyType>.keyCapabilities.encrypt=false
+op.enroll.userKey._008=# op.enroll.<tokenType>.keyGen.<keyType>.keyCapabilities.sign=true
+op.enroll.userKey._009=# op.enroll.<tokenType>.keyGen.<keyType>.keyCapabilities.signRecover=true
+op.enroll.userKey._010=# op.enroll.<tokenType>.keyGen.<keyType>.keyCapabilities.decrypt=false
+op.enroll.userKey._011=# op.enroll.<tokenType>.keyGen.<keyType>.keyCapabilities.derive=false
+op.enroll.userKey._012=# op.enroll.<tokenType>.keyGen.<keyType>.keyCapabilities.unwrap=false
+op.enroll.userKey._013=# op.enroll.<tokenType>.keyGen.<keyType>.keyCapabilities.wrap=false
+op.enroll.userKey._014=# op.enroll.<tokenType>.keyGen.<keyType>.keyCapabilities.verifyRecover=true
+op.enroll.userKey._015=# op.enroll.<tokenType>.keyGen.<keyType>.keyCapabilities.verify=true
+op.enroll.userKey._016=# op.enroll.<tokenType>.keyGen.<keyType>.keyCapabilities.sensitive=true
+op.enroll.userKey._017=# op.enroll.<tokenType>.keyGen.<keyType>.keyCapabilities.private=true
+op.enroll.userKey._018=# op.enroll.<tokenType>.keyGen.<keyType>.keyCapabilities.token=true
+op.enroll.userKey._019=# - specify the PKCS11 attributes to set on the token
+op.enroll.userKey._020=#
+op.enroll.userKey._021=# op.enroll.userKey.keyGen.signing.cuid_label
+op.enroll.userKey._022=# - specify the CUID shown in the certificate
+op.enroll.userKey._023=#
+op.enroll.userKey._024=# op.enroll.userKey.keyGen.signing.label
+op.enroll.userKey._025=# - specify the token name. all resulting labels for co-existing keys
+op.enroll.userKey._026=# on the same token must be unique
+op.enroll.userKey._027=# - $pretty_cuid$ - Pretty Print CUID (i.e. 4090-0062-FF02-0000-0B9C)
+op.enroll.userKey._028=# - $cuid$ - CUID (i.e. 40900062FF0200000B9C)
+op.enroll.userKey._029=# - $msn$ - MSN
+op.enroll.userKey._030=# - $userid$ - User ID
+op.enroll.userKey._031=# - $profileId$ - Profile ID
+op.enroll.userKey._032=#
+op.enroll.userKey._033=# op.enroll.<tokenType>.keyGen.<keyType>.overwrite=true|false
+op.enroll.userKey._034=# - if key and certificate exist, should RA overwrite them
+op.enroll.userKey._035=#
+op.enroll.userKey._036=# op.enroll.<tokenType>.keyGen.<keyType>.certId=C1
+op.enroll.userKey._037=# op.enroll.<tokenType>.keyGen.<keyType>.certAttrId=c1
+op.enroll.userKey._038=# op.enroll.<tokenType>.keyGen.<keyType>.privateKeyAttrId=k2
+op.enroll.userKey._039=# op.enroll.<tokenType>.keyGen.<keyType>.publicKeyAttrId=k3
+op.enroll.userKey._040=# op.enroll.<tokenType>.keyGen.<keyType>.privateKeyNumber=2
+op.enroll.userKey._041=# op.enroll.<tokenType>.keyGen.<keyType>.publicKeyNumber=3
+op.enroll.userKey._042=# - specify name PKCS11 object IDs
+op.enroll.userKey._043=# - Lower case letters signify objects containing PKCS11 object attributes,
+op.enroll.userKey._044=# in the format described below.
+op.enroll.userKey._045=# 'c' An object containing PKCS11 attributes for a certificate.
+op.enroll.userKey._046=# 'k' An object containing PKCS11 attributes for a public or private key
+op.enroll.userKey._047=# 'r' An object containing PKCS11 attributes for an "reader".
+op.enroll.userKey._048=# - Upper case letters signify objects containing raw data corresponding to
+op.enroll.userKey._049=# the lower case letters described above. For example, object "C0"
+op.enroll.userKey._050=# contains raw data corresponding to object "c0".
+op.enroll.userKey._051=# 'C' This object contains an entire DER cert, and nothing else.
+op.enroll.userKey._052=# 'K' This object contains a MUSCLE "key blob". TPS does not use this.
+op.enroll.userKey._053=#
+op.enroll.userKey._054=# op.enroll.<tokenType>.keyGen.<keyType>.keyUsage=0
+op.enroll.userKey._055=# op.enroll.<tokenType>.keyGen.<keyType>.keyUser=0
+op.enroll.userKey._056=# - user specifies which PIN user should be granted
+op.enroll.userKey._057=# use privilege of the generated private key, or
+op.enroll.userKey._058=# 15 if all users have use privilege for the private key
+op.enroll.userKey._059=# - Valid uage: (only specifies the usage for the private key)
+op.enroll.userKey._060=# 0 - default usage (Signing only for this APDU)
+op.enroll.userKey._061=# 1 - signing only
+op.enroll.userKey._062=# 2 - decryption only
+op.enroll.userKey._063=# 3 - signing and decryption
+op.enroll.userKey._064=#
+op.enroll.userKey._065=# op.enroll.<tokenType>.pkcs11obj.enable=true|false
+op.enroll.userKey._066=# - enable writing of PKCS11 cache object to the token
+op.enroll.userKey._067=#
+op.enroll.userKey._068=# op.enroll.<tokenType>.pkcs11obj.compress.enable=true|false
+op.enroll.userKey._069=# - enable compression for writing of PKCS11 cache object to the token
+op.enroll.userKey._070=#
+op.enroll.userKey._071=# op.enroll.<tokenType>.pinReset.pin.maxRetries=127
+op.enroll.userKey._072=# - max number of retries before blocking the token
+op.enroll.userKey._073=# - max value: 127
+op.enroll.userKey._074=#
+op.enroll.userKey._075=# There is a special case of tokenType userKeyTemporary.
+op.enroll.userKey._076=# Make sure the profile specified by the profileId to have
+op.enroll.userKey._077=# short validity period (eg, 7 days) for the certificate.
+op.enroll.userKey._078=#
+op.enroll.userKey._079=# The three recovery schemes supported are:
+op.enroll.userKey._080=#
+op.enroll.userKey._081=# * GenerateNewKey - Generate a new
+op.enroll.userKey._082=# cert for the
+op.enroll.userKey._083=# encryption cert.
+op.enroll.userKey._084=# * RecoverLast - Recover the most
+op.enroll.userKey._085=# recent cert for the
+op.enroll.userKey._086=# encryption cert.
+op.enroll.userKey._087=# * GenerateNewKeyandRecoverLast - Generate new cert AND
+op.enroll.userKey._088=# recover last for
+op.enroll.userKey._089=# encryption cert.
+op.enroll.userKey._090=#########################################
+op.enroll.allowUnknownToken=true
+op.enroll.userKey.temporaryToken.tokenType=userKeyTemporary
+op.enroll.userKey.keyGen.recovery.destroyed.keyType.num=2
+op.enroll.userKey.keyGen.recovery.destroyed.keyType.value.0=signing
+op.enroll.userKey.keyGen.recovery.destroyed.keyType.value.1=encryption
+op.enroll.userKey.keyGen.signing.recovery.destroyed.scheme=GenerateNewKey
+op.enroll.userKey.keyGen.signing.recovery.destroyed.revokeCert=true
+op.enroll.userKey.keyGen.signing.recovery.destroyed.revokeCert.reason=0
+op.enroll.userKey.keyGen.encryption.recovery.destroyed.scheme=RecoverLast
+op.enroll.userKey.keyGen.encryption.recovery.destroyed.revokeCert=false
+op.enroll.userKey.keyGen.encryption.recovery.destroyed.revokeCert.reason=0
+op.enroll.userKey.keyGen.recovery.keyCompromise.keyType.num=2
+op.enroll.userKey.keyGen.recovery.keyCompromise.keyType.value.0=signing
+op.enroll.userKey.keyGen.recovery.keyCompromise.keyType.value.1=encryption
+op.enroll.userKey.keyGen.signing.recovery.keyCompromise.scheme=GenerateNewKey
+op.enroll.userKey.keyGen.signing.recovery.keyCompromise.revokeCert=true
+op.enroll.userKey.keyGen.signing.recovery.keyCompromise.revokeCert.reason=1
+op.enroll.userKey.keyGen.encryption.recovery.keyCompromise.scheme=GenerateNewKey
+op.enroll.userKey.keyGen.encryption.recovery.keyCompromise.revokeCert=true
+op.enroll.userKey.keyGen.encryption.recovery.keyCompromise.revokeCert.reason=1
+op.enroll.userKey.keyGen.recovery.onHold.keyType.num=2
+op.enroll.userKey.keyGen.recovery.onHold.keyType.value.0=signing
+op.enroll.userKey.keyGen.recovery.onHold.keyType.value.1=encryption
+op.enroll.userKey.keyGen.signing.recovery.onHold.scheme=GenerateNewKey
+op.enroll.userKey.keyGen.signing.recovery.onHold.revokeCert=true
+op.enroll.userKey.keyGen.signing.recovery.onHold.revokeCert.reason=6
+op.enroll.userKey.keyGen.encryption.recovery.onHold.scheme=GenerateNewKey
+op.enroll.userKey.keyGen.encryption.recovery.onHold.revokeCert=true
+op.enroll.userKey.keyGen.encryption.recovery.onHold.revokeCert.reason=6
+op.enroll.userKey.keyGen.tokenName=$auth.cn$
+op.enroll.userKey.keyGen.keyType.num=2
+op.enroll.userKey.keyGen.keyType.value.0=signing
+op.enroll.userKey.keyGen.keyType.value.1=encryption
+op.enroll.userKey.keyGen.signing.keySize=1024
+op.enroll.userKey.keyGen.signing.public.keyCapabilities.encrypt=false
+op.enroll.userKey.keyGen.signing.public.keyCapabilities.sign=false
+op.enroll.userKey.keyGen.signing.public.keyCapabilities.signRecover=false
+op.enroll.userKey.keyGen.signing.public.keyCapabilities.decrypt=false
+op.enroll.userKey.keyGen.signing.public.keyCapabilities.derive=false
+op.enroll.userKey.keyGen.signing.public.keyCapabilities.unwrap=false
+op.enroll.userKey.keyGen.signing.public.keyCapabilities.wrap=false
+op.enroll.userKey.keyGen.signing.public.keyCapabilities.verifyRecover=true
+op.enroll.userKey.keyGen.signing.public.keyCapabilities.verify=true
+op.enroll.userKey.keyGen.signing.public.keyCapabilities.sensitive=false
+op.enroll.userKey.keyGen.signing.public.keyCapabilities.private=false
+op.enroll.userKey.keyGen.signing.public.keyCapabilities.token=true
+op.enroll.userKey.keyGen.signing.private.keyCapabilities.encrypt=false
+op.enroll.userKey.keyGen.signing.private.keyCapabilities.sign=true
+op.enroll.userKey.keyGen.signing.private.keyCapabilities.signRecover=true
+op.enroll.userKey.keyGen.signing.private.keyCapabilities.decrypt=false
+op.enroll.userKey.keyGen.signing.private.keyCapabilities.derive=false
+op.enroll.userKey.keyGen.signing.private.keyCapabilities.unwrap=false
+op.enroll.userKey.keyGen.signing.private.keyCapabilities.wrap=false
+op.enroll.userKey.keyGen.signing.private.keyCapabilities.verifyRecover=false
+op.enroll.userKey.keyGen.signing.private.keyCapabilities.verify=false
+op.enroll.userKey.keyGen.signing.private.keyCapabilities.sensitive=true
+op.enroll.userKey.keyGen.signing.private.keyCapabilities.private=true
+op.enroll.userKey.keyGen.signing.private.keyCapabilities.token=true
+op.enroll.userKey.keyGen.signing.label=signing key for $userid$
+op.enroll.userKey.keyGen.signing.cuid_label=$cuid$
+op.enroll.userKey.keyGen.signing.overwrite=true
+op.enroll.userKey.keyGen.signing.certId=C1
+op.enroll.userKey.keyGen.signing.certAttrId=c1
+op.enroll.userKey.keyGen.signing.privateKeyAttrId=k2
+op.enroll.userKey.keyGen.signing.publicKeyAttrId=k3
+op.enroll.userKey.keyGen.signing.keyUsage=0
+op.enroll.userKey.keyGen.signing.keyUser=0
+op.enroll.userKey.keyGen.signing.privateKeyNumber=2
+op.enroll.userKey.keyGen.signing.publicKeyNumber=3
+op.enroll.userKey.keyGen.signing.ca.profileId=caTokenUserSigningKeyEnrollment
+op.enroll.userKey.keyGen.signing.ca.conn=ca1
+op.enroll.userKey._079=#op.enroll.userKey.keyGen.signing.publisherId=fileBasedPublisher
+op.enroll.userKey.keyGen.encryption.keySize=1024
+op.enroll.userKey.keyGen.encryption.public.keyCapabilities.encrypt=true
+op.enroll.userKey.keyGen.encryption.public.keyCapabilities.sign=false
+op.enroll.userKey.keyGen.encryption.public.keyCapabilities.signRecover=false
+op.enroll.userKey.keyGen.encryption.public.keyCapabilities.decrypt=false
+op.enroll.userKey.keyGen.encryption.public.keyCapabilities.derive=false
+op.enroll.userKey.keyGen.encryption.public.keyCapabilities.unwrap=false
+op.enroll.userKey.keyGen.encryption.public.keyCapabilities.wrap=true
+op.enroll.userKey.keyGen.encryption.public.keyCapabilities.verifyRecover=false
+op.enroll.userKey.keyGen.encryption.public.keyCapabilities.verify=false
+op.enroll.userKey.keyGen.encryption.public.keyCapabilities.sensitive=false
+op.enroll.userKey.keyGen.encryption.public.keyCapabilities.private=false
+op.enroll.userKey.keyGen.encryption.public.keyCapabilities.token=true
+op.enroll.userKey.keyGen.encryption.private.keyCapabilities.encrypt=false
+op.enroll.userKey.keyGen.encryption.private.keyCapabilities.sign=false
+op.enroll.userKey.keyGen.encryption.private.keyCapabilities.signRecover=false
+op.enroll.userKey.keyGen.encryption.private.keyCapabilities.decrypt=true
+op.enroll.userKey.keyGen.encryption.private.keyCapabilities.derive=false
+op.enroll.userKey.keyGen.encryption.private.keyCapabilities.unwrap=true
+op.enroll.userKey.keyGen.encryption.private.keyCapabilities.wrap=false
+op.enroll.userKey.keyGen.encryption.private.keyCapabilities.verifyRecover=false
+op.enroll.userKey.keyGen.encryption.private.keyCapabilities.verify=false
+op.enroll.userKey.keyGen.encryption.private.keyCapabilities.sensitive=true
+op.enroll.userKey.keyGen.encryption.private.keyCapabilities.private=true
+op.enroll.userKey.keyGen.encryption.private.keyCapabilities.token=true
+op.enroll.userKey.keyGen.encryption.label=encryption key for $userid$
+op.enroll.userKey.keyGen.encryption.cuid_label=$cuid$
+op.enroll.userKey.keyGen.encryption.overwrite=true
+op.enroll.userKey.keyGen.encryption.certId=C2
+op.enroll.userKey.keyGen.encryption.certAttrId=c2
+op.enroll.userKey.keyGen.encryption.privateKeyAttrId=k4
+op.enroll.userKey.keyGen.encryption.publicKeyAttrId=k5
+op.enroll.userKey.keyGen.encryption.keyUsage=0
+op.enroll.userKey.keyGen.encryption.keyUser=0
+op.enroll.userKey.keyGen.encryption.privateKeyNumber=4
+op.enroll.userKey.keyGen.encryption.publicKeyNumber=5
+op.enroll.userKey.keyGen.encryption.ca.profileId=caTokenUserEncryptionKeyEnrollment
+op.enroll.userKey.keyGen.encryption.ca.conn=ca1
+op.enroll.userKey.pkcs11obj.enable=true
+op.enroll.userKey.pkcs11obj.compress.enable=true
+op.enroll.userKey.update.applet.emptyToken.enable=true
+op.enroll.userKey.update.applet.enable=true
+op.enroll.userKey.update.applet.requiredVersion=1.4.4d40a449
+op.enroll.userKey.update.applet.directory=[TPS_DIR]/applets
+op.enroll.userKey.update.applet.encryption=true
+op.enroll.userKey.update.symmetricKeys.enable=false
+op.enroll.userKey.update.symmetricKeys.requiredVersion=1
+op.enroll.userKey.loginRequest.enable=true
+op.enroll.userKey.pinReset.enable=true
+op.enroll.userKey.pinReset.pin.maxRetries=127
+op.enroll.userKey.pinReset.pin.minLen=4
+op.enroll.userKey.pinReset.pin.maxLen=10
+op.enroll.userKey.cardmgr_instance=A0000000030000
+op.enroll.userKey.tks.conn=tks1
+op.enroll.userKey.auth.id=ldap1
+op.enroll.userKey.auth.enable=true
+op.enroll.userKey.issuerinfo.enable=true
+op.enroll.userKey.issuerinfo.value=http://[SERVER_NAME]:[PORT]/cgi-bin/home/index.cgi
+op.enroll.userKeyTemporary.keyGen.recovery.onHold.keyType.num=2
+op.enroll.userKeyTemporary.keyGen.recovery.onHold.keyType.value.0=signing
+op.enroll.userKeyTemporary.keyGen.recovery.onHold.keyType.value.1=encryption
+op.enroll.userKeyTemporary.keyGen.signing.recovery.onHold.scheme=GenerateNewKey
+op.enroll.userKeyTemporary.keyGen.signing.recovery.onHold.revokeCert=true
+op.enroll.userKeyTemporary.keyGen.signing.recovery.onHold.revokeCert.reason=0
+op.enroll.userKeyTemporary.keyGen.encryption.recovery.onHold.scheme=RecoverLast
+op.enroll.userKeyTemporary.keyGen.encryption.recovery.onHold.revokeCert=true
+op.enroll.userKeyTemporary.keyGen.encryption.recovery.onHold.revokeCert.reason=0
+op.enroll.userKey.keyGen.encryption.serverKeygen.enable=[SERVER_KEYGEN]
+op.enroll.userKey.keyGen.encryption.serverKeygen.drm.conn=drm1
+op.enroll.userKey.keyGen.encryption.serverKeygen.archive=true
+op.enroll.userKeyTemporary.keyGen.encryption.serverKeygen.enable=true
+op.enroll.userKeyTemporary.keyGen.encryption.serverKeygen.drm.conn=drm1
+op.enroll.userKeyTemporary.keyGen.encryption.serverKeygen.archive=true
+op.enroll.userKeyTemporary.keyGen.tokenName=$auth.cn$ (Temporary)
+op.enroll.userKeyTemporary.keyGen.keyType.num=3
+op.enroll.userKeyTemporary.keyGen.keyType.value.0=auth
+op.enroll.userKeyTemporary.keyGen.keyType.value.1=signing
+op.enroll.userKeyTemporary.keyGen.keyType.value.2=encryption
+op.enroll.userKeyTemporary.keyGen.auth.keySize=1024
+op.enroll.userKeyTemporary.keyGen.auth.public.keyCapabilities.encrypt=false
+op.enroll.userKeyTemporary.keyGen.auth.public.keyCapabilities.sign=true
+op.enroll.userKeyTemporary.keyGen.auth.public.keyCapabilities.signRecover=true
+op.enroll.userKeyTemporary.keyGen.auth.public.keyCapabilities.decrypt=false
+op.enroll.userKeyTemporary.keyGen.auth.public.keyCapabilities.derive=false
+op.enroll.userKeyTemporary.keyGen.auth.public.keyCapabilities.unwrap=false
+op.enroll.userKeyTemporary.keyGen.auth.public.keyCapabilities.wrap=false
+op.enroll.userKeyTemporary.keyGen.auth.public.keyCapabilities.verifyRecover=true
+op.enroll.userKeyTemporary.keyGen.auth.public.keyCapabilities.verify=true
+op.enroll.userKeyTemporary.keyGen.auth.public.keyCapabilities.sensitive=true
+op.enroll.userKeyTemporary.keyGen.auth.public.keyCapabilities.private=false
+op.enroll.userKeyTemporary.keyGen.auth.public.keyCapabilities.token=true
+op.enroll.userKeyTemporary.keyGen.auth.private.keyCapabilities.encrypt=false
+op.enroll.userKeyTemporary.keyGen.auth.private.keyCapabilities.sign=true
+op.enroll.userKeyTemporary.keyGen.auth.private.keyCapabilities.signRecover=true
+op.enroll.userKeyTemporary.keyGen.auth.private.keyCapabilities.decrypt=false
+op.enroll.userKeyTemporary.keyGen.auth.private.keyCapabilities.derive=false
+op.enroll.userKeyTemporary.keyGen.auth.private.keyCapabilities.unwrap=false
+op.enroll.userKeyTemporary.keyGen.auth.private.keyCapabilities.wrap=false
+op.enroll.userKeyTemporary.keyGen.auth.private.keyCapabilities.verifyRecover=true
+op.enroll.userKeyTemporary.keyGen.auth.private.keyCapabilities.verify=true
+op.enroll.userKeyTemporary.keyGen.auth.private.keyCapabilities.sensitive=true
+op.enroll.userKeyTemporary.keyGen.auth.private.keyCapabilities.private=false
+op.enroll.userKeyTemporary.keyGen.auth.private.keyCapabilities.token=true
+op.enroll.userKeyTemporary.keyGen.auth.label=Temporary Key for $userid$
+op.enroll.userKeyTemporary.keyGen.auth.cuid_label=$cuid$
+op.enroll.userKeyTemporary.keyGen.auth.overwrite=false
+op.enroll.userKeyTemporary.keyGen.auth.certId=C0
+op.enroll.userKeyTemporary.keyGen.auth.certAttrId=c0
+op.enroll.userKeyTemporary.keyGen.auth.privateKeyAttrId=k0
+op.enroll.userKeyTemporary.keyGen.auth.publicKeyAttrId=k1
+op.enroll.userKeyTemporary.keyGen.auth.keyUsage=0
+op.enroll.userKeyTemporary.keyGen.auth.keyUser=15
+op.enroll.userKeyTemporary.keyGen.auth.privateKeyNumber=0
+op.enroll.userKeyTemporary.keyGen.auth.publicKeyNumber=1
+op.enroll.userKeyTemporary.keyGen.auth.ca.profileId=caTempTokenDeviceKeyEnrollment
+op.enroll.userKeyTemporary.keyGen.auth.ca.conn=ca1
+op.enroll.userKeyTemporary.keyGen.signing.keySize=1024
+op.enroll.userKeyTemporary.keyGen.signing.public.keyCapabilities.encrypt=false
+op.enroll.userKeyTemporary.keyGen.signing.public.keyCapabilities.sign=false
+op.enroll.userKeyTemporary.keyGen.signing.public.keyCapabilities.signRecover=false
+op.enroll.userKeyTemporary.keyGen.signing.public.keyCapabilities.decrypt=false
+op.enroll.userKeyTemporary.keyGen.signing.public.keyCapabilities.derive=false
+op.enroll.userKeyTemporary.keyGen.signing.public.keyCapabilities.unwrap=false
+op.enroll.userKeyTemporary.keyGen.signing.public.keyCapabilities.wrap=false
+op.enroll.userKeyTemporary.keyGen.signing.public.keyCapabilities.verifyRecover=true
+op.enroll.userKeyTemporary.keyGen.signing.public.keyCapabilities.verify=true
+op.enroll.userKeyTemporary.keyGen.signing.public.keyCapabilities.sensitive=false
+op.enroll.userKeyTemporary.keyGen.signing.public.keyCapabilities.private=false
+op.enroll.userKeyTemporary.keyGen.signing.public.keyCapabilities.token=true
+op.enroll.userKeyTemporary.keyGen.signing.private.keyCapabilities.encrypt=false
+op.enroll.userKeyTemporary.keyGen.signing.private.keyCapabilities.sign=true
+op.enroll.userKeyTemporary.keyGen.signing.private.keyCapabilities.signRecover=true
+op.enroll.userKeyTemporary.keyGen.signing.private.keyCapabilities.decrypt=false
+op.enroll.userKeyTemporary.keyGen.signing.private.keyCapabilities.derive=false
+op.enroll.userKeyTemporary.keyGen.signing.private.keyCapabilities.unwrap=false
+op.enroll.userKeyTemporary.keyGen.signing.private.keyCapabilities.wrap=false
+op.enroll.userKeyTemporary.keyGen.signing.private.keyCapabilities.verifyRecover=false
+op.enroll.userKeyTemporary.keyGen.signing.private.keyCapabilities.verify=false
+op.enroll.userKeyTemporary.keyGen.signing.private.keyCapabilities.sensitive=true
+op.enroll.userKeyTemporary.keyGen.signing.private.keyCapabilities.private=true
+op.enroll.userKeyTemporary.keyGen.signing.private.keyCapabilities.token=true
+op.enroll.userKeyTemporary.keyGen.signing.label=signing key for $userid$
+op.enroll.userKeyTemporary.keyGen.signing.cuid_label=$cuid$
+op.enroll.userKeyTemporary.keyGen.signing.overwrite=true
+op.enroll.userKeyTemporary.keyGen.signing.certId=C1
+op.enroll.userKeyTemporary.keyGen.signing.certAttrId=c1
+op.enroll.userKeyTemporary.keyGen.signing.privateKeyAttrId=k2
+op.enroll.userKeyTemporary.keyGen.signing.publicKeyAttrId=k3
+op.enroll.userKeyTemporary.keyGen.signing.keyUsage=0
+op.enroll.userKeyTemporary.keyGen.signing.keyUser=0
+op.enroll.userKeyTemporary.keyGen.signing.privateKeyNumber=2
+op.enroll.userKeyTemporary.keyGen.signing.publicKeyNumber=3
+op.enroll.userKeyTemporary.keyGen.signing.ca.profileId=caTempTokenUserSigningKeyEnrollment
+op.enroll.userKeyTemporary.keyGen.signing.ca.conn=ca1
+op.enroll.userKey._080=#op.enroll.userKeyTemporary.keyGen.signing.publisherId=fileBasedPublisher
+op.enroll.userKeyTemporary.keyGen.encryption.keySize=1024
+op.enroll.userKeyTemporary.keyGen.encryption.public.keyCapabilities.encrypt=true
+op.enroll.userKeyTemporary.keyGen.encryption.public.keyCapabilities.sign=false
+op.enroll.userKeyTemporary.keyGen.encryption.public.keyCapabilities.signRecover=false
+op.enroll.userKeyTemporary.keyGen.encryption.public.keyCapabilities.decrypt=false
+op.enroll.userKeyTemporary.keyGen.encryption.public.keyCapabilities.derive=false
+op.enroll.userKeyTemporary.keyGen.encryption.public.keyCapabilities.unwrap=false
+op.enroll.userKeyTemporary.keyGen.encryption.public.keyCapabilities.wrap=true
+op.enroll.userKeyTemporary.keyGen.encryption.public.keyCapabilities.verifyRecover=false
+op.enroll.userKeyTemporary.keyGen.encryption.public.keyCapabilities.verify=false
+op.enroll.userKeyTemporary.keyGen.encryption.public.keyCapabilities.sensitive=false
+op.enroll.userKeyTemporary.keyGen.encryption.public.keyCapabilities.private=false
+op.enroll.userKeyTemporary.keyGen.encryption.public.keyCapabilities.token=true
+op.enroll.userKeyTemporary.keyGen.encryption.private.keyCapabilities.encrypt=false
+op.enroll.userKeyTemporary.keyGen.encryption.private.keyCapabilities.sign=false
+op.enroll.userKeyTemporary.keyGen.encryption.private.keyCapabilities.signRecover=false
+op.enroll.userKeyTemporary.keyGen.encryption.private.keyCapabilities.decrypt=true
+op.enroll.userKeyTemporary.keyGen.encryption.private.keyCapabilities.derive=false
+op.enroll.userKeyTemporary.keyGen.encryption.private.keyCapabilities.unwrap=true
+op.enroll.userKeyTemporary.keyGen.encryption.private.keyCapabilities.wrap=false
+op.enroll.userKeyTemporary.keyGen.encryption.private.keyCapabilities.verifyRecover=false
+op.enroll.userKeyTemporary.keyGen.encryption.private.keyCapabilities.verify=false
+op.enroll.userKeyTemporary.keyGen.encryption.private.keyCapabilities.sensitive=true
+op.enroll.userKeyTemporary.keyGen.encryption.private.keyCapabilities.private=true
+op.enroll.userKeyTemporary.keyGen.encryption.private.keyCapabilities.token=true
+op.enroll.userKeyTemporary.keyGen.encryption.label=encryption key for $userid$
+op.enroll.userKeyTemporary.keyGen.encryption.cuid_label=$cuid$
+op.enroll.userKeyTemporary.keyGen.encryption.overwrite=true
+op.enroll.userKeyTemporary.keyGen.encryption.certId=C2
+op.enroll.userKeyTemporary.keyGen.encryption.certAttrId=c2
+op.enroll.userKeyTemporary.keyGen.encryption.privateKeyAttrId=k4
+op.enroll.userKeyTemporary.keyGen.encryption.publicKeyAttrId=k5
+op.enroll.userKeyTemporary.keyGen.encryption.keyUsage=0
+op.enroll.userKeyTemporary.keyGen.encryption.keyUser=0
+op.enroll.userKeyTemporary.keyGen.encryption.privateKeyNumber=4
+op.enroll.userKeyTemporary.keyGen.encryption.publicKeyNumber=5
+op.enroll.userKeyTemporary.keyGen.encryption.ca.profileId=caTempTokenUserEncryptionKeyEnrollment
+op.enroll.userKeyTemporary.keyGen.encryption.ca.conn=ca1
+op.enroll.userKeyTemporary.pkcs11obj.enable=true
+op.enroll.userKeyTemporary.pkcs11obj.compress.enable=true
+op.enroll.userKeyTemporary.update.applet.emptyToken.enable=true
+op.enroll.userKeyTemporary.update.applet.enable=true
+op.enroll.userKeyTemporary.update.applet.requiredVersion=1.4.4d40a449
+op.enroll.userKeyTemporary.update.applet.directory=[TPS_DIR]/applets
+op.enroll.userKeyTemporary.update.applet.encryption=true
+op.enroll.userKeyTemporary.update.symmetricKeys.enable=false
+op.enroll.userKeyTemporary.update.symmetricKeys.requiredVersion=1
+op.enroll.userKeyTemporary.loginRequest.enable=true
+op.enroll.userKeyTemporary.pinReset.enable=true
+op.enroll.userKeyTemporary.pinReset.pin.maxRetries=127
+op.enroll.userKeyTemporary.pinReset.pin.minLen=4
+op.enroll.userKeyTemporary.pinReset.pin.maxLen=10
+op.enroll.userKeyTemporary.tks.conn=tks1
+op.enroll.userKeyTemporary.cardmgr_instance=A0000000030000
+op.enroll.userKeyTemporary.auth.id=ldap1
+op.enroll.userKeyTemporary.auth.enable=true
+op.enroll.userKey.renewal._000=#########################################
+op.enroll.userKey.renewal._001=# Token Renewal.
+op.enroll.userKey.renewal._002=#
+op.enroll.userKey.renewal._003=# For each token in TPS UI, set the
+op.enroll.userKey.renewal._004=# following to trigger renewal
+op.enroll.userKey.renewal._005=# operations:
+op.enroll.userKey.renewal._006=#
+op.enroll.userKey.renewal._007=# RENEW=YES
+op.enroll.userKey.renewal._008=#
+op.enroll.userKey.renewal._009=# Optional grace period enforcement
+op.enroll.userKey.renewal._010=# must coincide exactly with what
+op.enroll.userKey.renewal._011=# the CA enforces.
+op.enroll.userKey.renewal._012=#
+op.enroll.userKey.renewal._013=# In case of renewal, encryption certId
+op.enroll.userKey.renewal._014=# values are for completeness only, server
+op.enroll.userKey.renewal._015=# code calculates actual values used.
+op.enroll.userKey.renewal._016=#
+op.enroll.userKey.renewal._017=#########################################
+op.enroll.userKey.renewal.keyType.num=2
+op.enroll.userKey.renewal.keyType.value.0=signing
+op.enroll.userKey.renewal.keyType.value.1=encryption
+op.enroll.userKey.renewal.signing.enable=true
+op.enroll.userKey.renewal.signing.gracePeriod.enable=false
+op.enroll.userKey.renewal.signing.gracePeriod.before=30
+op.enroll.userKey.renewal.signing.gracePeriod.after=30
+op.enroll.userKey.renewal.signing.certId=C1
+op.enroll.userKey.renewal.encryption.certId=C2
+op.enroll.userKey.renewal.signing.certAttrId=c1
+op.enroll.userKey.renewal.encryption.certAttrId=c2
+op.enroll.userKey.renewal.encryption.enable=true
+op.enroll.userKey.renewal.encryption.gracePeriod.enable=false
+op.enroll.userKey.renewal.encryption.gracePeriod.before=30
+op.enroll.userKey.renewal.encryption.gracePeriod.after=30
+op.enroll.userKey.renewal.signing.ca.conn=ca1
+op.enroll.userKey.renewal.encryption.ca.conn=ca1
+op.enroll.userKey.renewal.signing.ca.profileId=caTokenUserSigningKeyRenewal
+op.enroll.userKey.renewal.encryption.ca.profileId=caTokenUserEncryptionKeyRenewal
+op.enroll.soKey.temporaryToken.tokenType=soKeyTemporary
+op.enroll.soKey.keyGen.recovery.destroyed.keyType.num=2
+op.enroll.soKey.keyGen.recovery.destroyed.keyType.value.0=signing
+op.enroll.soKey.keyGen.recovery.destroyed.keyType.value.1=encryption
+op.enroll.soKey.keyGen.signing.recovery.destroyed.scheme=GenerateNewKey
+op.enroll.soKey.keyGen.signing.recovery.destroyed.revokeCert=true
+op.enroll.soKey.keyGen.signing.recovery.destroyed.revokeCert.reason=0
+op.enroll.soKey.keyGen.encryption.recovery.destroyed.scheme=RecoverLast
+op.enroll.soKey.keyGen.encryption.recovery.destroyed.revokeCert=false
+op.enroll.soKey.keyGen.encryption.recovery.destroyed.revokeCert.reason=0
+op.enroll.soKey.keyGen.recovery.keyCompromise.keyType.num=2
+op.enroll.soKey.keyGen.recovery.keyCompromise.keyType.value.0=signing
+op.enroll.soKey.keyGen.recovery.keyCompromise.keyType.value.1=encryption
+op.enroll.soKey.keyGen.signing.recovery.keyCompromise.scheme=GenerateNewKey
+op.enroll.soKey.keyGen.signing.recovery.keyCompromise.revokeCert=true
+op.enroll.soKey.keyGen.signing.recovery.keyCompromise.revokeCert.reason=1
+op.enroll.soKey.keyGen.encryption.recovery.keyCompromise.scheme=GenerateNewKey
+op.enroll.soKey.keyGen.encryption.recovery.keyCompromise.revokeCert=true
+op.enroll.soKey.keyGen.encryption.recovery.keyCompromise.revokeCert.reason=1
+op.enroll.soKey.keyGen.recovery.onHold.keyType.num=2
+op.enroll.soKey.keyGen.recovery.onHold.keyType.value.0=signing
+op.enroll.soKey.keyGen.recovery.onHold.keyType.value.1=encryption
+op.enroll.soKey.keyGen.signing.recovery.onHold.scheme=GenerateNewKey
+op.enroll.soKey.keyGen.signing.recovery.onHold.revokeCert=true
+op.enroll.soKey.keyGen.signing.recovery.onHold.revokeCert.reason=6
+op.enroll.soKey.keyGen.encryption.recovery.onHold.scheme=GenerateNewKey
+op.enroll.soKey.keyGen.encryption.recovery.onHold.revokeCert=true
+op.enroll.soKey.keyGen.encryption.recovery.onHold.revokeCert.reason=6
+op.enroll.soKey.keyGen.tokenName=$auth.cn$
+op.enroll.soKey.keyGen.keyType.num=2
+op.enroll.soKey.keyGen.keyType.value.0=signing
+op.enroll.soKey.keyGen.keyType.value.1=encryption
+op.enroll.soKey.keyGen.signing.keySize=1024
+op.enroll.soKey.keyGen.signing.public.keyCapabilities.encrypt=false
+op.enroll.soKey.keyGen.signing.public.keyCapabilities.sign=false
+op.enroll.soKey.keyGen.signing.public.keyCapabilities.signRecover=false
+op.enroll.soKey.keyGen.signing.public.keyCapabilities.decrypt=false
+op.enroll.soKey.keyGen.signing.public.keyCapabilities.derive=false
+op.enroll.soKey.keyGen.signing.public.keyCapabilities.unwrap=false
+op.enroll.soKey.keyGen.signing.public.keyCapabilities.wrap=false
+op.enroll.soKey.keyGen.signing.public.keyCapabilities.verifyRecover=true
+op.enroll.soKey.keyGen.signing.public.keyCapabilities.verify=true
+op.enroll.soKey.keyGen.signing.public.keyCapabilities.sensitive=false
+op.enroll.soKey.keyGen.signing.public.keyCapabilities.private=false
+op.enroll.soKey.keyGen.signing.public.keyCapabilities.token=true
+op.enroll.soKey.keyGen.signing.private.keyCapabilities.encrypt=false
+op.enroll.soKey.keyGen.signing.private.keyCapabilities.sign=true
+op.enroll.soKey.keyGen.signing.private.keyCapabilities.signRecover=true
+op.enroll.soKey.keyGen.signing.private.keyCapabilities.decrypt=false
+op.enroll.soKey.keyGen.signing.private.keyCapabilities.derive=false
+op.enroll.soKey.keyGen.signing.private.keyCapabilities.unwrap=false
+op.enroll.soKey.keyGen.signing.private.keyCapabilities.wrap=false
+op.enroll.soKey.keyGen.signing.private.keyCapabilities.verifyRecover=false
+op.enroll.soKey.keyGen.signing.private.keyCapabilities.verify=false
+op.enroll.soKey.keyGen.signing.private.keyCapabilities.sensitive=true
+op.enroll.soKey.keyGen.signing.private.keyCapabilities.private=true
+op.enroll.soKey.keyGen.signing.private.keyCapabilities.token=true
+op.enroll.soKey.keyGen.signing.label=signing key for $userid$
+op.enroll.soKey.keyGen.signing.cuid_label=$cuid$
+op.enroll.soKey.keyGen.signing.overwrite=true
+op.enroll.soKey.keyGen.signing.certId=C1
+op.enroll.soKey.keyGen.signing.certAttrId=c1
+op.enroll.soKey.keyGen.signing.privateKeyAttrId=k2
+op.enroll.soKey.keyGen.signing.publicKeyAttrId=k3
+op.enroll.soKey.keyGen.signing.keyUsage=0
+op.enroll.soKey.keyGen.signing.keyUser=0
+op.enroll.soKey.keyGen.signing.privateKeyNumber=2
+op.enroll.soKey.keyGen.signing.publicKeyNumber=3
+op.enroll.soKey.keyGen.signing.ca.profileId=caTokenUserSigningKeyEnrollment
+op.enroll.soKey.keyGen.signing.ca.conn=ca1
+op.enroll.soKey._079=#op.enroll.userKey.keyGen.signing.publisherId=fileBasedPublisher
+op.enroll.soKey.keyGen.encryption.keySize=1024
+op.enroll.soKey.keyGen.encryption.public.keyCapabilities.encrypt=true
+op.enroll.soKey.keyGen.encryption.public.keyCapabilities.sign=false
+op.enroll.soKey.keyGen.encryption.public.keyCapabilities.signRecover=false
+op.enroll.soKey.keyGen.encryption.public.keyCapabilities.decrypt=false
+op.enroll.soKey.keyGen.encryption.public.keyCapabilities.derive=false
+op.enroll.soKey.keyGen.encryption.public.keyCapabilities.unwrap=false
+op.enroll.soKey.keyGen.encryption.public.keyCapabilities.wrap=true
+op.enroll.soKey.keyGen.encryption.public.keyCapabilities.verifyRecover=false
+op.enroll.soKey.keyGen.encryption.public.keyCapabilities.verify=false
+op.enroll.soKey.keyGen.encryption.public.keyCapabilities.sensitive=false
+op.enroll.soKey.keyGen.encryption.public.keyCapabilities.private=false
+op.enroll.soKey.keyGen.encryption.public.keyCapabilities.token=true
+op.enroll.soKey.keyGen.encryption.private.keyCapabilities.encrypt=false
+op.enroll.soKey.keyGen.encryption.private.keyCapabilities.sign=false
+op.enroll.soKey.keyGen.encryption.private.keyCapabilities.signRecover=false
+op.enroll.soKey.keyGen.encryption.private.keyCapabilities.decrypt=true
+op.enroll.soKey.keyGen.encryption.private.keyCapabilities.derive=false
+op.enroll.soKey.keyGen.encryption.private.keyCapabilities.unwrap=true
+op.enroll.soKey.keyGen.encryption.private.keyCapabilities.wrap=false
+op.enroll.soKey.keyGen.encryption.private.keyCapabilities.verifyRecover=false
+op.enroll.soKey.keyGen.encryption.private.keyCapabilities.verify=false
+op.enroll.soKey.keyGen.encryption.private.keyCapabilities.sensitive=true
+op.enroll.soKey.keyGen.encryption.private.keyCapabilities.private=true
+op.enroll.soKey.keyGen.encryption.private.keyCapabilities.token=true
+op.enroll.soKey.keyGen.encryption.label=encryption key for $userid$
+op.enroll.soKey.keyGen.encryption.cuid_label=$cuid$
+op.enroll.soKey.keyGen.encryption.overwrite=true
+op.enroll.soKey.keyGen.encryption.certId=C2
+op.enroll.soKey.keyGen.encryption.certAttrId=c2
+op.enroll.soKey.keyGen.encryption.privateKeyAttrId=k4
+op.enroll.soKey.keyGen.encryption.publicKeyAttrId=k5
+op.enroll.soKey.keyGen.encryption.keyUsage=0
+op.enroll.soKey.keyGen.encryption.keyUser=0
+op.enroll.soKey.keyGen.encryption.privateKeyNumber=4
+op.enroll.soKey.keyGen.encryption.publicKeyNumber=5
+op.enroll.soKey.keyGen.encryption.ca.profileId=caTokenUserEncryptionKeyEnrollment
+op.enroll.soKey.keyGen.encryption.ca.conn=ca1
+op.enroll.soKey.pkcs11obj.enable=true
+op.enroll.soKey.pkcs11obj.compress.enable=true
+op.enroll.soKey.update.applet.emptyToken.enable=true
+op.enroll.soKey.update.applet.enable=true
+op.enroll.soKey.update.applet.requiredVersion=1.4.4d40a449
+op.enroll.soKey.update.applet.directory=[TPS_DIR]/applets
+op.enroll.soKey.update.applet.encryption=true
+op.enroll.soKey.update.symmetricKeys.enable=false
+op.enroll.soKey.update.symmetricKeys.requiredVersion=1
+op.enroll.soKey.loginRequest.enable=true
+op.enroll.soKey.pinReset.enable=true
+op.enroll.soKey.pinReset.pin.maxRetries=127
+op.enroll.soKey.pinReset.pin.minLen=4
+op.enroll.soKey.pinReset.pin.maxLen=10
+op.enroll.soKey.cardmgr_instance=A0000000030000
+op.enroll.soKey.tks.conn=tks1
+op.enroll.soKey.auth.id=ldap2
+op.enroll.soKey.auth.enable=true
+op.enroll.soKey.issuerinfo.enable=true
+op.enroll.soKey.issuerinfo.value=http://[SERVER_NAME]:[PORT]/cgi-bin/so/index.cgi
+op.enroll.soKeyTemporary.keyGen.recovery.onHold.keyType.num=2
+op.enroll.soKeyTemporary.keyGen.recovery.onHold.keyType.value.0=signing
+op.enroll.soKeyTemporary.keyGen.recovery.onHold.keyType.value.1=encryption
+op.enroll.soKeyTemporary.keyGen.signing.recovery.onHold.scheme=GenerateNewKey
+op.enroll.soKeyTemporary.keyGen.signing.recovery.onHold.revokeCert=true
+op.enroll.soKeyTemporary.keyGen.signing.recovery.onHold.revokeCert.reason=0
+op.enroll.soKeyTemporary.keyGen.encryption.recovery.onHold.scheme=RecoverLast
+op.enroll.soKeyTemporary.keyGen.encryption.recovery.onHold.revokeCert=true
+op.enroll.soKeyTemporary.keyGen.encryption.recovery.onHold.revokeCert.reason=0
+op.enroll.soKey.keyGen.encryption.serverKeygen.enable=[SERVER_KEYGEN]
+op.enroll.soKey.keyGen.encryption.serverKeygen.drm.conn=drm1
+op.enroll.soKey.keyGen.encryption.serverKeygen.archive=true
+op.enroll.soKeyTemporary.keyGen.encryption.serverKeygen.enable=true
+op.enroll.soKeyTemporary.keyGen.encryption.serverKeygen.drm.conn=drm1
+op.enroll.soKeyTemporary.keyGen.encryption.serverKeygen.archive=true
+op.enroll.soKeyTemporary.keyGen.tokenName=$auth.cn$ (Temporary)
+op.enroll.soKeyTemporary.keyGen.keyType.num=3
+op.enroll.soKeyTemporary.keyGen.keyType.value.0=auth
+op.enroll.soKeyTemporary.keyGen.keyType.value.1=signing
+op.enroll.soKeyTemporary.keyGen.keyType.value.2=encryption
+op.enroll.soKeyTemporary.keyGen.auth.keySize=1024
+op.enroll.soKeyTemporary.keyGen.auth.public.keyCapabilities.encrypt=false
+op.enroll.soKeyTemporary.keyGen.auth.public.keyCapabilities.sign=true
+op.enroll.soKeyTemporary.keyGen.auth.public.keyCapabilities.signRecover=true
+op.enroll.soKeyTemporary.keyGen.auth.public.keyCapabilities.decrypt=false
+op.enroll.soKeyTemporary.keyGen.auth.public.keyCapabilities.derive=false
+op.enroll.soKeyTemporary.keyGen.auth.public.keyCapabilities.unwrap=false
+op.enroll.soKeyTemporary.keyGen.auth.public.keyCapabilities.wrap=false
+op.enroll.soKeyTemporary.keyGen.auth.public.keyCapabilities.verifyRecover=true
+op.enroll.soKeyTemporary.keyGen.auth.public.keyCapabilities.verify=true
+op.enroll.soKeyTemporary.keyGen.auth.public.keyCapabilities.sensitive=true
+op.enroll.soKeyTemporary.keyGen.auth.public.keyCapabilities.private=false
+op.enroll.soKeyTemporary.keyGen.auth.public.keyCapabilities.token=true
+op.enroll.soKeyTemporary.keyGen.auth.private.keyCapabilities.encrypt=false
+op.enroll.soKeyTemporary.keyGen.auth.private.keyCapabilities.sign=true
+op.enroll.soKeyTemporary.keyGen.auth.private.keyCapabilities.signRecover=true
+op.enroll.soKeyTemporary.keyGen.auth.private.keyCapabilities.decrypt=false
+op.enroll.soKeyTemporary.keyGen.auth.private.keyCapabilities.derive=false
+op.enroll.soKeyTemporary.keyGen.auth.private.keyCapabilities.unwrap=false
+op.enroll.soKeyTemporary.keyGen.auth.private.keyCapabilities.wrap=false
+op.enroll.soKeyTemporary.keyGen.auth.private.keyCapabilities.verifyRecover=true
+op.enroll.soKeyTemporary.keyGen.auth.private.keyCapabilities.verify=true
+op.enroll.soKeyTemporary.keyGen.auth.private.keyCapabilities.sensitive=true
+op.enroll.soKeyTemporary.keyGen.auth.private.keyCapabilities.private=false
+op.enroll.soKeyTemporary.keyGen.auth.private.keyCapabilities.token=true
+op.enroll.soKeyTemporary.keyGen.auth.label=Temporary Key for $userid$
+op.enroll.soKeyTemporary.keyGen.auth.cuid_label=$cuid$
+op.enroll.soKeyTemporary.keyGen.auth.overwrite=false
+op.enroll.soKeyTemporary.keyGen.auth.certId=C0
+op.enroll.soKeyTemporary.keyGen.auth.certAttrId=c0
+op.enroll.soKeyTemporary.keyGen.auth.privateKeyAttrId=k0
+op.enroll.soKeyTemporary.keyGen.auth.publicKeyAttrId=k1
+op.enroll.soKeyTemporary.keyGen.auth.keyUsage=0
+op.enroll.soKeyTemporary.keyGen.auth.keyUser=15
+op.enroll.soKeyTemporary.keyGen.auth.privateKeyNumber=0
+op.enroll.soKeyTemporary.keyGen.auth.publicKeyNumber=1
+op.enroll.soKeyTemporary.keyGen.auth.ca.profileId=caTempTokenDeviceKeyEnrollment
+op.enroll.soKeyTemporary.keyGen.auth.ca.conn=ca1
+op.enroll.soKeyTemporary.keyGen.signing.keySize=1024
+op.enroll.soKeyTemporary.keyGen.signing.public.keyCapabilities.encrypt=false
+op.enroll.soKeyTemporary.keyGen.signing.public.keyCapabilities.sign=false
+op.enroll.soKeyTemporary.keyGen.signing.public.keyCapabilities.signRecover=false
+op.enroll.soKeyTemporary.keyGen.signing.public.keyCapabilities.decrypt=false
+op.enroll.soKeyTemporary.keyGen.signing.public.keyCapabilities.derive=false
+op.enroll.soKeyTemporary.keyGen.signing.public.keyCapabilities.unwrap=false
+op.enroll.soKeyTemporary.keyGen.signing.public.keyCapabilities.wrap=false
+op.enroll.soKeyTemporary.keyGen.signing.public.keyCapabilities.verifyRecover=true
+op.enroll.soKeyTemporary.keyGen.signing.public.keyCapabilities.verify=true
+op.enroll.soKeyTemporary.keyGen.signing.public.keyCapabilities.sensitive=false
+op.enroll.soKeyTemporary.keyGen.signing.public.keyCapabilities.private=false
+op.enroll.soKeyTemporary.keyGen.signing.public.keyCapabilities.token=true
+op.enroll.soKeyTemporary.keyGen.signing.private.keyCapabilities.encrypt=false
+op.enroll.soKeyTemporary.keyGen.signing.private.keyCapabilities.sign=true
+op.enroll.soKeyTemporary.keyGen.signing.private.keyCapabilities.signRecover=true
+op.enroll.soKeyTemporary.keyGen.signing.private.keyCapabilities.decrypt=false
+op.enroll.soKeyTemporary.keyGen.signing.private.keyCapabilities.derive=false
+op.enroll.soKeyTemporary.keyGen.signing.private.keyCapabilities.unwrap=false
+op.enroll.soKeyTemporary.keyGen.signing.private.keyCapabilities.wrap=false
+op.enroll.soKeyTemporary.keyGen.signing.private.keyCapabilities.verifyRecover=false
+op.enroll.soKeyTemporary.keyGen.signing.private.keyCapabilities.verify=false
+op.enroll.soKeyTemporary.keyGen.signing.private.keyCapabilities.sensitive=true
+op.enroll.soKeyTemporary.keyGen.signing.private.keyCapabilities.private=true
+op.enroll.soKeyTemporary.keyGen.signing.private.keyCapabilities.token=true
+op.enroll.soKeyTemporary.keyGen.signing.label=signing key for $userid$
+op.enroll.soKeyTemporary.keyGen.signing.cuid_label=$cuid$
+op.enroll.soKeyTemporary.keyGen.signing.overwrite=true
+op.enroll.soKeyTemporary.keyGen.signing.certId=C1
+op.enroll.soKeyTemporary.keyGen.signing.certAttrId=c1
+op.enroll.soKeyTemporary.keyGen.signing.privateKeyAttrId=k2
+op.enroll.soKeyTemporary.keyGen.signing.publicKeyAttrId=k3
+op.enroll.soKeyTemporary.keyGen.signing.keyUsage=0
+op.enroll.soKeyTemporary.keyGen.signing.keyUser=0
+op.enroll.soKeyTemporary.keyGen.signing.privateKeyNumber=2
+op.enroll.soKeyTemporary.keyGen.signing.publicKeyNumber=3
+op.enroll.soKeyTemporary.keyGen.signing.ca.profileId=caTempTokenUserSigningKeyEnrollment
+op.enroll.soKeyTemporary.keyGen.signing.ca.conn=ca1
+op.enroll.soKeyTemporary.keyGen.encryption.keySize=1024
+op.enroll.soKeyTemporary.keyGen.encryption.public.keyCapabilities.encrypt=true
+op.enroll.soKeyTemporary.keyGen.encryption.public.keyCapabilities.sign=false
+op.enroll.soKeyTemporary.keyGen.encryption.public.keyCapabilities.signRecover=false
+op.enroll.soKeyTemporary.keyGen.encryption.public.keyCapabilities.decrypt=false
+op.enroll.soKeyTemporary.keyGen.encryption.public.keyCapabilities.derive=false
+op.enroll.soKeyTemporary.keyGen.encryption.public.keyCapabilities.unwrap=false
+op.enroll.soKeyTemporary.keyGen.encryption.public.keyCapabilities.wrap=true
+op.enroll.soKeyTemporary.keyGen.encryption.public.keyCapabilities.verifyRecover=false
+op.enroll.soKeyTemporary.keyGen.encryption.public.keyCapabilities.verify=false
+op.enroll.soKeyTemporary.keyGen.encryption.public.keyCapabilities.sensitive=false
+op.enroll.soKeyTemporary.keyGen.encryption.public.keyCapabilities.private=false
+op.enroll.soKeyTemporary.keyGen.encryption.public.keyCapabilities.token=true
+op.enroll.soKeyTemporary.keyGen.encryption.private.keyCapabilities.encrypt=false
+op.enroll.soKeyTemporary.keyGen.encryption.private.keyCapabilities.sign=false
+op.enroll.soKeyTemporary.keyGen.encryption.private.keyCapabilities.signRecover=false
+op.enroll.soKeyTemporary.keyGen.encryption.private.keyCapabilities.decrypt=true
+op.enroll.soKeyTemporary.keyGen.encryption.private.keyCapabilities.derive=false
+op.enroll.soKeyTemporary.keyGen.encryption.private.keyCapabilities.unwrap=true
+op.enroll.soKeyTemporary.keyGen.encryption.private.keyCapabilities.wrap=false
+op.enroll.soKeyTemporary.keyGen.encryption.private.keyCapabilities.verifyRecover=false
+op.enroll.soKeyTemporary.keyGen.encryption.private.keyCapabilities.verify=false
+op.enroll.soKeyTemporary.keyGen.encryption.private.keyCapabilities.sensitive=true
+op.enroll.soKeyTemporary.keyGen.encryption.private.keyCapabilities.private=true
+op.enroll.soKeyTemporary.keyGen.encryption.private.keyCapabilities.token=true
+op.enroll.soKeyTemporary.keyGen.encryption.label=encryption key for $userid$
+op.enroll.soKeyTemporary.keyGen.encryption.cuid_label=$cuid$
+op.enroll.soKeyTemporary.keyGen.encryption.overwrite=true
+op.enroll.soKeyTemporary.keyGen.encryption.certId=C2
+op.enroll.soKeyTemporary.keyGen.encryption.certAttrId=c2
+op.enroll.soKeyTemporary.keyGen.encryption.privateKeyAttrId=k4
+op.enroll.soKeyTemporary.keyGen.encryption.publicKeyAttrId=k5
+op.enroll.soKeyTemporary.keyGen.encryption.keyUsage=0
+op.enroll.soKeyTemporary.keyGen.encryption.keyUser=0
+op.enroll.soKeyTemporary.keyGen.encryption.privateKeyNumber=4
+op.enroll.soKeyTemporary.keyGen.encryption.publicKeyNumber=5
+op.enroll.soKeyTemporary.keyGen.encryption.ca.profileId=caTempTokenUserEncryptionKeyEnrollment
+op.enroll.soKeyTemporary.keyGen.encryption.ca.conn=ca1
+op.enroll.soKeyTemporary.pkcs11obj.enable=true
+op.enroll.soKeyTemporary.pkcs11obj.compress.enable=true
+op.enroll.soKeyTemporary.update.applet.emptyToken.enable=true
+op.enroll.soKeyTemporary.update.applet.enable=true
+op.enroll.soKeyTemporary.update.applet.requiredVersion=1.4.4d40a449
+op.enroll.soKeyTemporary.update.applet.directory=[TPS_DIR]/applets
+op.enroll.soKeyTemporary.update.applet.encryption=true
+op.enroll.soKeyTemporary.update.symmetricKeys.enable=false
+op.enroll.soKeyTemporary.update.symmetricKeys.requiredVersion=1
+op.enroll.soKeyTemporary.loginRequest.enable=true
+op.enroll.soKeyTemporary.pinReset.enable=true
+op.enroll.soKeyTemporary.pinReset.pin.maxRetries=127
+op.enroll.soKeyTemporary.pinReset.pin.minLen=4
+op.enroll.soKeyTemporary.pinReset.pin.maxLen=10
+op.enroll.soKeyTemporary.cardmgr_instance=A0000000030000
+op.enroll.soKeyTemporary.tks.conn=tks1
+op.enroll.soKeyTemporary.tks.keySet=defKeyset
+op.enroll.soKeyTemporary.auth.id=ldap2
+op.enroll.soKeyTemporary.auth.enable=true
+op.pinReset._000=#########################################
+op.pinReset._001=# Certificate Chain Imports
+op.pinReset._002=#
+op.pinReset._003=# op.enroll.certificates.num=1
+op.pinReset._004=# op.enroll.certificates.value.0=caCert
+op.pinReset._005=# op.enroll.certificates.caCert.nickName=caCert0 pki-tps
+op.pinReset._006=# op.enroll.certificates.caCert.certId=C5
+op.pinReset._007=# op.enroll.certificates.caCert.certAttrId=c5
+op.pinReset._008=# op.enroll.certificates.caCert.label=caCert Label
+op.pinReset._009=#########################################
+op.pinReset._010=#########################################
+op.pinReset._011=# Pin Reset Operation For CoolKey
+op.pinReset._012=#
+op.pinReset._013=# op.pinReset.userKey.update.applet.emptyToken.enable=false
+op.pinReset._014=# - update applet or not if token is empty
+op.pinReset._015=#
+op.pinReset._016=# - N/A for HouseKey
+op.pinReset._017=# - N/A for HouseKey with Legacy Applet
+op.pinReset._018=#########################################
+op.pinReset.userKey.update.applet.emptyToken.enable=true
+op.pinReset.userKey.update.applet.enable=false
+op.pinReset.userKey.update.applet.requiredVersion=1.4.4d40a449
+op.pinReset.userKey.update.applet.directory=[TPS_DIR]/applets
+op.pinReset.userKey.update.applet.encryption=true
+op.pinReset.userKey.update.symmetricKeys.enable=false
+op.pinReset.userKey.update.symmetricKeys.requiredVersion=1
+op.pinReset.userKey.loginRequest.enable=true
+op.pinReset.userKey.pinReset.pin.minLen=4
+op.pinReset.userKey.pinReset.pin.maxLen=10
+op.pinReset.userKey.tks.conn=tks1
+op.pinReset.userKey.cardmgr_instance=A0000000030000
+op.pinReset.userKey.auth.id=ldap1
+op.pinReset.userKey.auth.enable=true
+op.format._000=#########################################
+op.format._001=# Format Operation For tokenKey
+op.format._002=#
+op.format._003=# op.format.tokenKey.update.applet.emptyToken.enable=false
+op.format._004=# - update applet or not if token is empty
+op.format._005=#
+op.format._006=# - applicable to CoolKey
+op.format._007=# - applicable to HouseKey
+op.format._008=# - applicable to HouseKey with Legacy Applet
+op.format._009=#########################################
+op.format.allowUnknownToken=true
+op.format.soCleanUserToken.update.applet.emptyToken.enable=true
+op.format.soCleanUserToken.update.applet.requiredVersion=1.4.4d40a449
+op.format.soCleanUserToken.update.applet.directory=[TPS_DIR]/applets
+op.format.soCleanUserToken.update.applet.encryption=true
+op.format.soCleanUserToken.update.symmetricKeys.enable=false
+op.format.soCleanUserToken.update.symmetricKeys.requiredVersion=1
+op.format.soCleanUserToken.revokeCert=true
+op.format.soCleanUserToken.ca.conn=ca1
+op.format.soCleanUserToken.loginRequest.enable=false
+op.format.soCleanUserToken.cardmgr_instance=A0000000030000
+op.format.soCleanUserToken.tks.conn=tks1
+op.format.soCleanUserToken.auth.id=ldap1
+op.format.soCleanUserToken.auth.enable=false
+op.format.soCleanUserToken.issuerinfo.enable=true
+op.format.soCleanUserToken.issuerinfo.value=
+op.format.soCleanSOToken.update.applet.emptyToken.enable=true
+op.format.soCleanSOToken.update.applet.requiredVersion=1.4.4d40a449
+op.format.soCleanSOToken.update.applet.directory=[TPS_DIR]/applets
+op.format.soCleanSOToken.update.applet.encryption=true
+op.format.soCleanSOToken.update.symmetricKeys.enable=false
+op.format.soCleanSOToken.update.symmetricKeys.requiredVersion=1
+op.format.soCleanSOToken.revokeCert=true
+op.format.soCleanSOToken.ca.conn=ca1
+op.format.soCleanSOToken.loginRequest.enable=false
+op.format.soCleanSOToken.cardmgr_instance=A0000000030000
+op.format.soCleanSOToken.tks.conn=tks1
+op.format.soCleanSOToken.auth.id=ldap1
+op.format.soCleanSOToken.auth.enable=false
+op.format.soCleanSOToken.issuerinfo.enable=true
+op.format.soCleanSOToken.issuerinfo.value=
+op.format.cleanToken.update.applet.emptyToken.enable=true
+op.format.cleanToken.update.applet.requiredVersion=1.4.4d40a449
+op.format.cleanToken.update.applet.directory=[TPS_DIR]/applets
+op.format.cleanToken.update.applet.encryption=true
+op.format.cleanToken.update.symmetricKeys.enable=false
+op.format.cleanToken.update.symmetricKeys.requiredVersion=1
+op.format.cleanToken.revokeCert=true
+op.format.cleanToken.ca.conn=ca1
+op.format.cleanToken.loginRequest.enable=true
+op.format.cleanToken.cardmgr_instance=A0000000030000
+op.format.cleanToken.tks.conn=tks1
+op.format.cleanToken.auth.id=ldap1
+op.format.cleanToken.auth.enable=false
+op.format.cleanToken.issuerinfo.enable=true
+op.format.cleanToken.issuerinfo.value=
+op.format.soUserKey.update.applet.emptyToken.enable=true
+op.format.soUserKey.update.applet.requiredVersion=1.4.4d40a449
+op.format.soUserKey.update.applet.directory=[TPS_DIR]/applets
+op.format.soUserKey.update.applet.encryption=true
+op.format.soUserKey.update.symmetricKeys.enable=false
+op.format.soUserKey.update.symmetricKeys.requiredVersion=1
+op.format.soUserKey.revokeCert=true
+op.format.soUserKey.ca.conn=ca1
+op.format.soUserKey.loginRequest.enable=false
+op.format.soUserKey.cardmgr_instance=A0000000030000
+op.format.soUserKey.tks.conn=tks1
+op.format.soUserKey.auth.id=ldap1
+op.format.soUserKey.auth.enable=false
+op.format.soUserKey.issuerinfo.enable=true
+op.format.soUserKey.issuerinfo.value=http://[SERVER_NAME]:[PORT]/cgi-bin/home/index.cgi
+op.format.soKey.update.applet.emptyToken.enable=true
+op.format.soKey.update.applet.requiredVersion=1.4.4d40a449
+op.format.soKey.update.applet.directory=[TPS_DIR]/applets
+op.format.soKey.update.applet.encryption=true
+op.format.soKey.update.symmetricKeys.enable=false
+op.format.soKey.update.symmetricKeys.requiredVersion=1
+op.format.soKey.revokeCert=true
+op.format.soKey.ca.conn=ca1
+op.format.soKey.loginRequest.enable=true
+op.format.soKey.cardmgr_instance=A0000000030000
+op.format.soKey.tks.conn=tks1
+op.format.soKey.auth.id=ldap2
+op.format.soKey.auth.enable=true
+op.format.soKey.issuerinfo.enable=true
+op.format.soKey.issuerinfo.value=http://[SERVER_NAME]:[PORT]/cgi-bin/so/index.cgi
+op.format.userKey.update.applet.emptyToken.enable=true
+op.format.userKey.update.applet.requiredVersion=1.4.4d40a449
+op.format.userKey.update.applet.directory=[TPS_DIR]/applets
+op.format.userKey.update.applet.encryption=true
+op.format.userKey.update.symmetricKeys.enable=false
+op.format.userKey.update.symmetricKeys.requiredVersion=1
+op.format.userKey.revokeCert=true
+op.format.userKey.ca.conn=ca1
+op.format.userKey.loginRequest.enable=true
+op.format.userKey.cardmgr_instance=A0000000030000
+op.format.userKey.tks.conn=tks1
+op.format.userKey.auth.id=ldap1
+op.format.userKey.auth.enable=true
+op.format.userKey.issuerinfo.enable=true
+op.format.userKey.issuerinfo.value=http://[SERVER_NAME]:[PORT]/cgi-bin/home/index.cgi
+op.format.tokenKey.update.applet.emptyToken.enable=true
+op.format.tokenKey.update.applet.requiredVersion=1.4.4d40a449
+op.format.tokenKey.update.applet.directory=[TPS_DIR]/applets
+op.format.tokenKey.update.applet.encryption=true
+op.format.tokenKey.update.symmetricKeys.enable=false
+op.format.tokenKey.update.symmetricKeys.requiredVersion=1
+op.format.tokenKey.revokeCert=true
+op.format.tokenKey.ca.conn=ca1
+op.format.tokenKey.loginRequest.enable=true
+op.format.tokenKey.cardmgr_instance=A0000000030000
+op.format.tokenKey.tks.conn=tks1
+op.format.tokenKey.auth.id=ldap1
+op.format.tokenKey.auth.enable=true
+op.format.tokenKey.issuerinfo.enable=true
+op.format.tokenKey.issuerinfo.value=http://[SERVER_NAME]:[PORT]/cgi-bin/home/index.cgi
+tokendb._000=#########################################
+tokendb._001=# tokendb.auditLog:
+tokendb._002=# - audit log path
+tokendb._003=# tokendb.host:
+tokendb._004=# - tokendb host name
+tokendb._005=# tokendb.port:
+tokendb._006=# - tokendb port number
+tokendb._007=# tokendb.bindDN:
+tokendb._008=# - tokendb administration DN (i.e. cn=Directory Manager)
+tokendb._009=# tokendb.bindPassPath:
+tokendb._010=# - tokendb administration password file path
+tokendb._011=# tokendb.templateDir
+tokendb._012=# - directory where all the tokendb templates are located
+tokendb._013=# tokendb.userBaseDN:
+tokendb._014=# - directory base DN for users and groups
+tokendb._015=# tokendb.baseDN:
+tokendb._016=# - directory base DN for tokens
+tokendb._017=# tokendb.activityBaseDN:
+tokendb._018=# - directory base DN for activities
+tokendb._019=# tokendb.indexTemplate=index.template
+tokendb._020=# - index template
+tokendb._021=# tokendb.newTemplate=new.template
+tokendb._022=# - add template
+tokendb._023=# tokendb.showTemplate=show.template
+tokendb._024=# - show template
+tokendb._025=# tokendb.errorTemplate=error.template
+tokendb._026=# - error template
+tokendb._027=# tokendb.searchTemplate=search.template
+tokendb._028=# - search template
+tokendb._029=# tokendb.searchResultTemplate=searchResults.template
+tokendb._030=# - search result template
+tokendb._031=# tokendb.editTemplate=edit.template
+tokendb._032=# - edit template
+tokendb._033=# tokendb.editResultTemplate=editResults.template
+tokendb._034=# - edit result template
+tokendb._035=# tokendb.addResultTemplate=addResults.template
+tokendb._036=# - add result template
+tokendb._037=# tokendb.deleteResultTemplate=deleteResults.template
+tokendb._038=# - delete result template
+tokendb._039=# tokendb.searchActivityTemplate=searchActivity.template
+tokendb._040=# - search activity template
+tokendb._041=# tokendb.searchActivityResultTemplate=searchActivityResults.template
+tokendb._042=# - search activity result template
+tokendb._043=# tokendb.showAdminTemplate=showAdmin.template
+tokendb._044=# - show admin template
+tokendb._045=# tokendb.editAdminTemplate=editAdmin.template
+tokendb._046=# - edit admin template
+tokendb._047=# tokendb.editAdminResultTemplate=editAdminResults.template
+tokendb._048=# - edit admin result template
+tokendb._049=# tokendb.searchAdminTemplate=searchAdmin.template
+tokendb._050=# - search admin template
+tokendb._051=# tokendb.searchAdminResultTemplate=searchAdminResults.template
+tokendb._052=# - search admin result template
+tokendb._053=# tokendb.defaultPolicy:
+tokendb._054=# Supported Policy (Separated by ; [Semicolon]):
+tokendb._055=# For example, PIN_RESET=YES|NO;RE_ENROLL=YES|NO
+tokendb._056=# PIN_RESET=YES|NO
+tokendb._057=# - If not present, pin reset by user is allowed.
+tokendb._058=# - If present and agent change PIN_RESET from NO
+tokendb._059=# to YES, user is allowed to do pin reset. This
+tokendb._060=# policy will be changed back to NO after pin reset.
+tokendb._061=# RE_ENROLL=YES|NO
+tokendb._062=# - If not present, re-enrollment is allowed.
+tokendb._063=# - If present, re-enrollment is allowed when RE_ENROLL
+tokendb._064=# is set to YES. Otherwise, re-enrollment is not
+tokendb._065=# allowed.
+tokendb._066=# tokendb.allowedTransitions:
+tokendb._067=# - has transitions between the following states
+tokendb._068=# TOKEN_UNINITIALIZED = 0,
+tokendb._069=# TOKEN_DAMAGED =1,
+tokendb._070=# TOKEN_PERM_LOST=2,
+tokendb._071=# TOKEN_TEMP_LOST=3,
+tokendb._072=# TOKEN_FOUND =4,
+tokendb._073=# TOKEN_TEMP_LOST_PERM_LOST =5,
+tokendb._074=# TOKEN_TERMINATED = 6
+tokendb._075=#########################################
+tokendb.auditLog=[SERVER_ROOT]/logs/tokendb-audit.log
+tokendb.hostport=[TOKENDB_HOST]:[TOKENDB_PORT]
+tokendb.ssl=false
+tokendb.bindDN=cn=Directory Manager
+tokendb.bindPassPath=[SERVER_ROOT]/conf/password.conf
+tokendb.templateDir=[SERVER_ROOT]/docroot/tus
+tokendb.userBaseDN=[TOKENDB_ROOT]
+tokendb.baseDN=ou=Tokens,[TOKENDB_ROOT]
+tokendb.activityBaseDN=ou=Activities,[TOKENDB_ROOT]
+tokendb.certBaseDN=ou=Certificates,[TOKENDB_ROOT]
+tokendb.indexTemplate=index.template
+tokendb.indexAdminTemplate=indexAdmin.template
+tokendb.newTemplate=new.template
+tokendb.showTemplate=show.template
+tokendb.showCertTemplate=showCert.template
+tokendb.errorTemplate=error.template
+tokendb.searchTemplate=search.template
+tokendb.searchResultTemplate=searchResults.template
+tokendb.searchCertificateResultTemplate=searchCertificateResults.template
+tokendb.editTemplate=edit.template
+tokendb.editResultTemplate=editResults.template
+tokendb.addResultTemplate=addResults.template
+tokendb.deleteTemplate=delete.template
+tokendb.deleteResultTemplate=deleteResults.template
+tokendb.searchActivityTemplate=searchActivity.template
+tokendb.searchCertificateTemplate=searchCertificate.template
+tokendb.searchActivityResultTemplate=searchActivityResults.template
+tokendb.searchActivityAdminTemplate=searchActivityAdmin.template
+tokendb.searchActivityAdminResultTemplate=searchActivityAdminResults.template
+tokendb.showAdminTemplate=showAdmin.template
+tokendb.doTokenTemplate=doToken.template
+tokendb.doTokenConfirmTemplate=doTokenConfirm.template
+tokendb.revokeTemplate=revoke.template
+tokendb.searchAdminTemplate=searchAdmin.template
+tokendb.searchAdminResultTemplate=searchAdminResults.template
+tokendb.defaultPolicy=RE_ENROLL=YES
+tokendb.newUserTemplate=newUser.template
+tokendb.userDeleteTemplate=userDelete.template
+tokendb.searchUserResultTemplate=searchUserResults.template
+tokendb.searchUserTemplate=searchUser.template
+tokendb.editUserTemplate=editUser.template
+tokendb.indexOperatorTemplate=indexOperator.template
+tokendb.selfTestTemplate=selfTest.template
+tokendb.selfTestResultsTemplate=selfTestResults.template
+tokendb.auditAdminTemplate=auditAdmin.template
+tokendb.selectConfigTemplate=selectConfig.template
+tokendb.agentSelectConfigTemplate=agentSelectConfig.template
+tokendb.editConfigTemplate=editConfig.template
+tokendb.agentViewConfigTemplate=agentViewConfig.template
+tokendb.addConfigTemplate=addConfig.template
+tokendb.confirmConfigChangesTemplate=confirmConfigChanges.template
+tokendb.confirmDeleteConfigTemplate=confirmDeleteConfig.template
+log.instance.SignedAudit.selected.events=ROLE_ASSUME,CONFIG_CERT_POLICY,CONFIG_CERT_PROFILE,CONFIG_CRL_PROFILE,CONFIG_OCSP_PROFILE,CONFIG_AUTH,CONFIG_ROLE,CONFIG_ACL,CONFIG_SIGNED_AUDIT,CONFIG_ENCRYPTION,CONFIG_TRUSTED_PUBLIC_KEY,CONFIG_DRM,SELFTESTS_EXECUTION,AUDIT_LOG_DELETE,LOG_PATH_CHANGE,LOG_EXPIRATION_CHANGE,CONFIG,CONFIG_ROLE,CONFIG_TOKEN,CONFIG_PROFILE,CONFIG_AUDIT,APPLET_UPGRADE,KEY_CHANGEOVER,RENEWAL
+log.instance.SignedAudit.selectable.events=ROLE_ASSUME,CONFIG_CERT_POLICY,CONFIG_CERT_PROFILE,CONFIG_CRL_PROFILE,CONFIG_OCSP_PROFILE,CONFIG_AUTH,CONFIG_ROLE,CONFIG_ACL,CONFIG_SIGNED_AUDIT,CONFIG_ENCRYPTION,CONFIG_TRUSTED_PUBLIC_KEY,CONFIG_DRM,SELFTESTS_EXECUTION,AUDIT_LOG_DELETE,LOG_PATH_CHANGE,LOG_EXPIRATION_CHANGE,PRIVATE_KEY_ARCHIVE,PRIVATE_KEY_ARCHIVE_PROCESSED,KEY_RECOVERY_REQUEST,KEY_RECOVERY_AGENT_LOGIN,KEY_RECOVERY_PROCESSED,KEY_GEN_ASYMMETRIC,NON_PROFILE_CERT_REQUEST,CONFIG,CONFIG_ROLE,CONFIG_TOKEN,CONFIG_PROFILE,CONFIG_AUDIT,APPLET_UPGRADE,KEY_CHANGEOVER,RENEWAL
+log.instance.SignedAudit.nonselectable.events=AUDIT_LOG_STARTUP,AUDIT_LOG_SHUTDOWN,CERT_REQUEST_PROCESSED,CERT_STATUS_CHANGE_REQUEST,CERT_STATUS_CHANGE_REQUEST_PROCESSED,AUTHZ_SUCCESS,AUTHZ_FAIL,INTER_BOUNDARY,AUTH_FAIL,AUTH_SUCCESS,CERT_PROFILE_APPROVAL,PROOF_OF_POSSESSION,CRL_RETRIEVAL,CRL_VALIDATION,CMC_SIGNED_REQUEST_SIG_VERIFY,SERVER_SIDE_KEYGEN_PROCESSED,SERVER_SIDE_KEYGEN_REQUEST
+tokendb.allowedTransitions=0:1,0:2,0:3,0:4,0:5,0:6,3:4,3:5,3:6,4:1,4:2,4:3,4:6
+target._000=#########################################
+target._001=# entries to enable configuration of parameter sets through the TPS UI agent and admin tabs
+target._002=#
+target._003=# target.configure.list = comma separated lists of all parameter sets that can be configured by the admin.
+target._004=# Each entry will show up (with underscore replaced by space) under Advanced Configuration on the admin tab.
+target._005=#
+target._006=# target.agent_approve.list = comma separated subset of above list. Parameter sets in this list
+target._007=# will show up in the agent tab (under advanced configuration) and will require agent involvement
+target._008=# (enable/ disable) to be edited.
+target._009=#
+target._010=# For the wording to display correctly, the values in the above list should be plurals.
+target._011=#
+target._012=# Each parameter set in the lists above requires three parameters:
+target._013=# target.<type name>.list : list of choices of this parameter set type (will display in the drop down box)
+target._014=# target.<type name>.pattern : the regular expression to select parameters in CS.cfg for this parameter set.
+target._015=# target.<type_name>.displayname: used in the UI display text. This should be the singular form of <type_name>.
+target._016=#
+target._017=# The exception is the parameter set Generals, which has only a pattern and displayname defined.
+target._018=#
+target._019=########################################
+target.configure.list=Profiles,Subsystem_Connections,Profile_Mappings,Authentication_Sources
+target.agent_approve.list=Profiles
+target.Profiles.list=userKey,soKey,soCleanUserToken,soUserKey,cleanToken,soCleanSoToken,tokenKey
+target.Profiles.pattern=op\..*\.$name\..*
+target.Profiles.displayname=Profile
+target.Subsystem_Connections.list=ca1,drm1,tks1
+target.Subsystem_Connections.pattern=conn\.$name\..*
+target.Subsystem_Connections.displayname=Subsystem Connection
+target.Profile_Mappings.list=enroll,format,pinReset
+target.Profile_Mappings.pattern=op\.$name\.mapping\..*
+target.Profile_Mappings.displayname=Profile Mapping
+target.Authentication_Sources.list=0,1
+target.Authentication_Sources.pattern=auth\.instance\.$name\..*
+target.Authentication_Sources.displayname=Authentication Source
+target.Generals.displayname=General
+target.Generals.pattern=^applet\..*\|^general\..*\|^failover.pod.enable\|^channel\..*
+config.Generals.General.state=Enabled
+config.Generals.General.timestamp=1280283607424406
+tps._000=########################################
+tps._001=# For verifying system certificates
+tps._002=# tps.cert.list=sslserver,subsystem,audit_signing
+tps._003=# tps.cert.sslserver.nickname=xxx
+tps._005=# tps.cert.subsystem.nickname=xxx
+tps._007=# tps.cert.audit_signing.nickname=xxx
+tps._009=########################################
+tps.cert.list=sslserver,subsystem,audit_signing
+tps.cert.sslserver.nickname=[HSM_LABEL][NICKNAME]
+tps.cert.subsystem.nickname=[HSM_LABEL][NICKNAME]
+tps.cert.audit_signing.nickname=[HSM_LABEL][NICKNAME]
diff --git a/base/tps/etc/init.d/pki-tpsd b/base/tps/etc/init.d/pki-tpsd
new file mode 100755
index 000000000..e5a213add
--- /dev/null
+++ b/base/tps/etc/init.d/pki-tpsd
@@ -0,0 +1,87 @@
+#!/bin/bash
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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-2010 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+# pki-tpsd Startup script for the Apache HTTP pki-tps Server
+#
+# chkconfig: - 87 13
+# description: Token Processing System (Apache)
+# processname: pki-tpsd
+# piddir: /var/run/pki/tps
+# config: ${PKI_SERVER_ROOT}/conf/httpd.conf
+
+PROG_NAME=`basename $0`
+SERVICE_NAME="pki-tpsd"
+SERVICE_PROG="/sbin/service"
+PKI_PATH="/usr/share/pki/tps"
+PKI_REGISTRY="/etc/sysconfig/pki/tps"
+PKI_TYPE="pki-tps"
+PKI_TOTAL_PORTS=3
+
+# Avoid using 'systemctl' for now
+SYSTEMCTL_SKIP_REDIRECT=1
+export SYSTEMCTL_SKIP_REDIRECT
+
+# Disallow 'others' the ability to 'write' to new files
+umask 00002
+
+command="$1"
+pki_instance="$2"
+
+# Source function library.
+. /etc/init.d/functions
+
+# Source the PKI function library
+. /usr/share/pki/scripts/functions
+
+# See how we were called.
+case $command in
+ status)
+ registry_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 ${default_error}
+ ;;
+ *)
+ echo "unknown action ($command)"
+ usage
+ echo "where valid instance names include:"
+ list_instances
+ exit ${default_error}
+ ;;
+esac
+
diff --git a/base/tps/forms/esc/cgi-bin/demo/enroll.cgi b/base/tps/forms/esc/cgi-bin/demo/enroll.cgi
new file mode 100755
index 000000000..c0f4bcabf
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/demo/enroll.cgi
@@ -0,0 +1,183 @@
+#! /usr/bin/perl -w
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+########################################################################
+#
+# Script: esc.cgi
+# Author: Kin Blas ()
+# Date: 12/19/2003
+#
+# CGI.pm Docs:
+#
+# http://stein.cshl.org/WWW/software/CGI/
+#
+########################################################################
+
+use CGI;
+
+$gQuery = new CGI;
+
+$gQueryAction = "default";
+$gQueryOverrideAction = "default";
+
+@gCookieNames = ("ascScreenName",
+ "ascSubscriptionType",
+ "ascBindings");
+
+$gQueryAction = $gQuery->param("action") if (defined $gQuery->param("action"));
+
+$gQueryOverrideAction = $gQuery->param("override_action")
+ if (defined $gQuery->param("override_action"));
+
+if ($gQueryOverrideAction ne "default")
+{
+ $gQueryAction = $gQueryOverrideAction;
+}
+
+########################################################################
+#
+# If no action was provided, we default to showing our
+# admin page!
+#
+# http://www.foo.com/esc.cgi
+#
+########################################################################
+
+if ($gQueryAction eq "default")
+{
+ GenerateEnrollmentPage();
+ exit 0;
+}
+
+
+
+sub ExitError
+{
+ my($str) = @_;
+ print $gQuery->header(), $gQuery->start_html(), $str, $gQuery->end_html();
+ exit 0;
+}
+
+sub GetScreenName
+{
+ my $sn = "";
+
+ if (defined $gQuery->param("screenname"))
+ {
+ $sn = $gQuery->param("screenname");
+ } else {
+ $sn = "default";
+ }
+
+ return $sn;
+}
+
+sub GetKeyType
+{
+ my $keyType = 0;
+
+ if (defined $gQuery->param("keytype"))
+ {
+ $keyType = $gQuery->param("keytype");
+ }
+
+ return $keyType;
+}
+
+sub GetKeyID
+{
+ my $keyID = "";
+
+ if (defined $gQuery->param("keyid"))
+ {
+ $keyID = $gQuery->param("keyid");
+ }
+
+ return $keyID;
+}
+
+sub GetKeyLabelArg
+{
+ my $keyLabel = "";
+
+ if (defined $gQuery->param("keylabel"))
+ {
+ $keyLabel = $gQuery->param("keylabel");
+ }
+
+ return $keyLabel;
+}
+
+sub HaveScreenName
+{
+ return 1 if (GetScreenName() ne "");
+ return 0;
+}
+
+sub IsSubscriber
+{
+ my $subType = $gUserObj{'SUBSCRIPTION'};
+ return 1 if ($subType eq "HouseKey" || $subType eq "NetKey");
+
+ return 0;
+}
+
+sub GetNextAction
+{
+ my($nextActn) = "default";
+
+ if (defined $gQuery->param('nextaction'))
+ {
+ $nextActn = $gQuery->param('nextaction');
+ }
+ elsif (defined $gQuery->param('action'))
+ {
+ $nextActn = $gQuery->param('action');
+ }
+
+ return $nextActn;
+}
+
+sub GenerateEnrollmentPage
+{
+ my ($l);
+
+ ExitError("Failed to load enrollment page!") if (!open(ENROLL_FILE, "< Enroll.html"));
+
+ print $gQuery->header();
+
+ while ($l = <ENROLL_FILE>)
+ {
+ if ($l =~ /<!-- *SECURECOOL_SCREENNAME *-->/)
+ {
+ my $sn = GetScreenName();
+ $l =~ s/<!-- *SECURECOOL_SCREENNAME *-->/$sn/g;
+ print $l;
+ }
+ else
+ {
+ print $l;
+ }
+ }
+
+ close(ENROLL_FILE);
+}
diff --git a/base/tps/forms/esc/cgi-bin/demo/index.cgi b/base/tps/forms/esc/cgi-bin/demo/index.cgi
new file mode 100755
index 000000000..c9a1d21dd
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/demo/index.cgi
@@ -0,0 +1,47 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+#
+#
+#
+print "Content-type: text/xml\n\n";
+print "<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>";
+print "<ServiceInfo>";
+print "<IssuerName>";
+print "Fedora Project"; # Vendor
+print "</IssuerName>\n";
+print "<Services>";
+print "<Operation>";
+print "http://[SERVER_NAME]:[PORT]/nk_service";
+print "</Operation>";
+print "<UI>";
+print "http://[SERVER_NAME]:[PORT]/cgi-bin/demo/enroll.cgi";
+print "</UI>";
+print "<EnrolledTokenBrowserURL>";
+print "</EnrolledTokenBrowserURL>";
+print "<EnrolledTokenURL>";
+print "</EnrolledTokenURL>";
+print "<TokenType>";
+print "userKey";
+print "</TokenType>";
+print "</Services>";
+print "</ServiceInfo>";
diff --git a/base/tps/forms/esc/cgi-bin/home/cachain.cgi b/base/tps/forms/esc/cgi-bin/home/cachain.cgi
new file mode 100755
index 000000000..ddbf5e6ae
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/home/cachain.cgi
@@ -0,0 +1,52 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+#
+#
+
+use LWP::UserAgent;
+
+my $cfg = "../../conf/CS.cfg";
+my $cahostport = `grep conn.ca1.hostport $cfg | cut -c19-`;
+
+chomp($cahostport);
+
+my $url = "https://$cahostport/ca/ee/ca/getCAChain?op=download&mimeType=application/x-x509-ca-cert";
+
+my $agent = LWP::UserAgent->new;
+$agent->timeout(30);
+
+my $request = HTTP::Request->new('GET', $url);
+my $response = $agent->request($request);
+
+if ($response->is_success) {
+ print "Content-type: application/x-x509-ca-cert\n\n";
+ print $response->content;
+
+} else {
+ print "Content-type: text/html\n\n";
+ print "<html>";
+ print "<link rel=stylesheet href='/esc/home/style.css' type='text/css'>";
+ print "<center><h2>Error Importing CA Chain Information!</h2></center>";
+ print "<center><h2>Please try again later.</h2></center>";
+ print "</html>"
+}
diff --git a/base/tps/forms/esc/cgi-bin/home/enroll.cgi b/base/tps/forms/esc/cgi-bin/home/enroll.cgi
new file mode 100755
index 000000000..c0f4bcabf
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/home/enroll.cgi
@@ -0,0 +1,183 @@
+#! /usr/bin/perl -w
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+########################################################################
+#
+# Script: esc.cgi
+# Author: Kin Blas ()
+# Date: 12/19/2003
+#
+# CGI.pm Docs:
+#
+# http://stein.cshl.org/WWW/software/CGI/
+#
+########################################################################
+
+use CGI;
+
+$gQuery = new CGI;
+
+$gQueryAction = "default";
+$gQueryOverrideAction = "default";
+
+@gCookieNames = ("ascScreenName",
+ "ascSubscriptionType",
+ "ascBindings");
+
+$gQueryAction = $gQuery->param("action") if (defined $gQuery->param("action"));
+
+$gQueryOverrideAction = $gQuery->param("override_action")
+ if (defined $gQuery->param("override_action"));
+
+if ($gQueryOverrideAction ne "default")
+{
+ $gQueryAction = $gQueryOverrideAction;
+}
+
+########################################################################
+#
+# If no action was provided, we default to showing our
+# admin page!
+#
+# http://www.foo.com/esc.cgi
+#
+########################################################################
+
+if ($gQueryAction eq "default")
+{
+ GenerateEnrollmentPage();
+ exit 0;
+}
+
+
+
+sub ExitError
+{
+ my($str) = @_;
+ print $gQuery->header(), $gQuery->start_html(), $str, $gQuery->end_html();
+ exit 0;
+}
+
+sub GetScreenName
+{
+ my $sn = "";
+
+ if (defined $gQuery->param("screenname"))
+ {
+ $sn = $gQuery->param("screenname");
+ } else {
+ $sn = "default";
+ }
+
+ return $sn;
+}
+
+sub GetKeyType
+{
+ my $keyType = 0;
+
+ if (defined $gQuery->param("keytype"))
+ {
+ $keyType = $gQuery->param("keytype");
+ }
+
+ return $keyType;
+}
+
+sub GetKeyID
+{
+ my $keyID = "";
+
+ if (defined $gQuery->param("keyid"))
+ {
+ $keyID = $gQuery->param("keyid");
+ }
+
+ return $keyID;
+}
+
+sub GetKeyLabelArg
+{
+ my $keyLabel = "";
+
+ if (defined $gQuery->param("keylabel"))
+ {
+ $keyLabel = $gQuery->param("keylabel");
+ }
+
+ return $keyLabel;
+}
+
+sub HaveScreenName
+{
+ return 1 if (GetScreenName() ne "");
+ return 0;
+}
+
+sub IsSubscriber
+{
+ my $subType = $gUserObj{'SUBSCRIPTION'};
+ return 1 if ($subType eq "HouseKey" || $subType eq "NetKey");
+
+ return 0;
+}
+
+sub GetNextAction
+{
+ my($nextActn) = "default";
+
+ if (defined $gQuery->param('nextaction'))
+ {
+ $nextActn = $gQuery->param('nextaction');
+ }
+ elsif (defined $gQuery->param('action'))
+ {
+ $nextActn = $gQuery->param('action');
+ }
+
+ return $nextActn;
+}
+
+sub GenerateEnrollmentPage
+{
+ my ($l);
+
+ ExitError("Failed to load enrollment page!") if (!open(ENROLL_FILE, "< Enroll.html"));
+
+ print $gQuery->header();
+
+ while ($l = <ENROLL_FILE>)
+ {
+ if ($l =~ /<!-- *SECURECOOL_SCREENNAME *-->/)
+ {
+ my $sn = GetScreenName();
+ $l =~ s/<!-- *SECURECOOL_SCREENNAME *-->/$sn/g;
+ print $l;
+ }
+ else
+ {
+ print $l;
+ }
+ }
+
+ close(ENROLL_FILE);
+}
diff --git a/base/tps/forms/esc/cgi-bin/home/index.cgi b/base/tps/forms/esc/cgi-bin/home/index.cgi
new file mode 100755
index 000000000..1e54a8354
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/home/index.cgi
@@ -0,0 +1,51 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+#
+#
+#
+print "Content-type: text/xml\n\n";
+print "<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>";
+print "<ServiceInfo>";
+print "<IssuerName>";
+print "Fedora Project"; # Vendor
+print "</IssuerName>\n";
+print "<Services>";
+print "<Operation>";
+print "http://[SERVER_NAME]:[PORT]/nk_service";
+print "</Operation>";
+print "<UI>";
+print "http://[SERVER_NAME]:[PORT]/cgi-bin/home/enroll.cgi";
+print "</UI>";
+print "<EnrolledTokenBrowserURL>";
+print "http://www.fedora.redhat.com"; # Company URL
+print "</EnrolledTokenBrowserURL>";
+print "<EnrolledTokenURL>";
+print "</EnrolledTokenURL>";
+print "<TokenType>";
+print "userKey";
+print "</TokenType>";
+#print "<CAChainUI>";
+#print "http://[SERVER_NAME]:[PORT]/cgi-bin/home/cachain.cgi";
+#print "</CAChainUI>";
+print "</Services>";
+print "</ServiceInfo>";
diff --git a/base/tps/forms/esc/cgi-bin/so/enroll.cgi b/base/tps/forms/esc/cgi-bin/so/enroll.cgi
new file mode 100755
index 000000000..148cd78c0
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/so/enroll.cgi
@@ -0,0 +1,193 @@
+#! /usr/bin/perl -w
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+########################################################################
+#
+# Script: esc.cgi
+# Author: Kin Blas ()
+# Date: 12/19/2003
+#
+# CGI.pm Docs:
+#
+# http://stein.cshl.org/WWW/software/CGI/
+#
+########################################################################
+
+[REQUIRE_CFG_PL]
+
+use CGI;
+
+my $port = get_port();
+my $host = get_host();
+my $secure_port = get_secure_port();
+
+$gQuery = new CGI;
+
+$gQueryAction = "default";
+$gQueryOverrideAction = "default";
+
+@gCookieNames = ("ascScreenName",
+ "ascSubscriptionType",
+ "ascBindings");
+
+$gQueryAction = $gQuery->param("action") if (defined $gQuery->param("action"));
+
+$gQueryOverrideAction = $gQuery->param("override_action")
+ if (defined $gQuery->param("override_action"));
+
+if ($gQueryOverrideAction ne "default")
+{
+ $gQueryAction = $gQueryOverrideAction;
+}
+
+########################################################################
+#
+# If no action was provided, we default to showing our
+# admin page!
+#
+# http://www.foo.com/esc.cgi
+#
+########################################################################
+
+if ($gQueryAction eq "default")
+{
+ GenerateEnrollmentPage();
+ exit 0;
+}
+
+
+
+sub ExitError
+{
+ my($str) = @_;
+ print $gQuery->header(), $gQuery->start_html(), $str, $gQuery->end_html();
+ exit 0;
+}
+
+sub GetScreenName
+{
+ my $sn = "";
+
+ if (defined $gQuery->param("screenname"))
+ {
+ $sn = $gQuery->param("screenname");
+ } else {
+ $sn = "default";
+ }
+
+ return $sn;
+}
+
+sub GetKeyType
+{
+ my $keyType = 0;
+
+ if (defined $gQuery->param("keytype"))
+ {
+ $keyType = $gQuery->param("keytype");
+ }
+
+ return $keyType;
+}
+
+sub GetKeyID
+{
+ my $keyID = "";
+
+ if (defined $gQuery->param("keyid"))
+ {
+ $keyID = $gQuery->param("keyid");
+ }
+
+ return $keyID;
+}
+
+sub GetKeyLabelArg
+{
+ my $keyLabel = "";
+
+ if (defined $gQuery->param("keylabel"))
+ {
+ $keyLabel = $gQuery->param("keylabel");
+ }
+
+ return $keyLabel;
+}
+
+sub HaveScreenName
+{
+ return 1 if (GetScreenName() ne "");
+ return 0;
+}
+
+sub IsSubscriber
+{
+ my $subType = $gUserObj{'SUBSCRIPTION'};
+ return 1 if ($subType eq "HouseKey" || $subType eq "NetKey");
+
+ return 0;
+}
+
+sub GetNextAction
+{
+ my($nextActn) = "default";
+
+ if (defined $gQuery->param('nextaction'))
+ {
+ $nextActn = $gQuery->param('nextaction');
+ }
+ elsif (defined $gQuery->param('action'))
+ {
+ $nextActn = $gQuery->param('action');
+ }
+
+ return $nextActn;
+}
+
+sub GenerateEnrollmentPage
+{
+ my ($l);
+
+ ExitError("Failed to load enrollment page!") if (!open(ENROLL_FILE, "< Enroll.html"));
+
+ print $gQuery->header();
+
+ while ($l = <ENROLL_FILE>)
+ {
+ if ($l =~ /<!-- *SECURECOOL_SCREENNAME *-->/)
+ {
+ my $sn = GetScreenName();
+ $l =~ s/<!-- *SECURECOOL_SCREENNAME *-->/$sn/g;
+ print $l;
+ }
+ else
+ {
+ $l =~ s/\$host/$host/g;
+ $l =~ s/\$port/$port/g;
+ $l =~ s/\$secure_port/$secure_port/g;
+
+ print $l;
+ }
+ }
+
+ close(ENROLL_FILE);
+}
diff --git a/base/tps/forms/esc/cgi-bin/so/index.cgi b/base/tps/forms/esc/cgi-bin/so/index.cgi
new file mode 100755
index 000000000..7b3f2c68d
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/so/index.cgi
@@ -0,0 +1,48 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+#
+#
+#
+print "Content-type: text/xml\n\n";
+print "<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>";
+print "<ServiceInfo>";
+print "<IssuerName>";
+print "Fedora Project"; # Vendor
+print "</IssuerName>\n";
+print "<Services>";
+print "<Operation>";
+print "http://[SERVER_NAME]:[PORT]/nk_service";
+print "</Operation>";
+print "<UI>";
+print "http://[SERVER_NAME]:[PORT]/cgi-bin/so/enroll.cgi";
+print "</UI>";
+print "<EnrolledTokenBrowserURL>";
+print "</EnrolledTokenBrowserURL>";
+print "<EnrolledTokenURL>";
+print "http://[SERVER_NAME]:[PORT]/cgi-bin/sow/welcome.cgi";
+print "</EnrolledTokenURL>";
+print "<TokenType>";
+print "soKey";
+print "</TokenType>";
+print "</Services>";
+print "</ServiceInfo>";
diff --git a/base/tps/forms/esc/cgi-bin/sow/ajax-list.cgi b/base/tps/forms/esc/cgi-bin/sow/ajax-list.cgi
new file mode 100755
index 000000000..0f4ac094f
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/sow/ajax-list.cgi
@@ -0,0 +1,79 @@
+#! /usr/bin/perl -w
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use CGI;
+use Mozilla::LDAP::Conn;
+use PKI::TPS::Common;
+
+[REQUIRE_CFG_PL]
+
+sub main()
+{
+
+ my $q = new CGI;
+
+ my $host = get_ldap_host();
+ my $port = get_ldap_port();
+ my $secureconn = get_ldap_secure();
+ my $basedn = get_base_dn();
+ my $certdir = get_ldap_certdir();
+
+ my $letters = $q->param('letters');
+ if ($letters eq "") {
+ # HACK: ajax.js posts parameters into POST URL
+ $letters = $ENV{'QUERY_STRING'};
+ $letters =~ s/.*letters=//g;
+ $letters =~ s/\+/ /g;
+ }
+
+ my $result = "";
+
+ print "Content-Type: text/html\n\n";
+
+ my $conn = PKI::TPS::Common::make_connection(
+ {host => $host, port => $port, cert => $certdir},
+ $secureconn);
+
+ return if (!$conn);
+
+ my $entry = $conn->search ( { base =>$basedn,
+ scope => "sub",
+ filter => "cn=$letters*",
+ attrsonly => 0,
+ attrs => qw(cn uid),
+ sortattrs => qw(cn)}
+ );
+
+ while ($entry) {
+ my $cn = ($entry->getValues("cn"))[0] || "";
+ my $uid = ($entry->getValues("uid"))[0] || "";
+ $result .= $uid . "###" . $cn . "|";
+ $entry $conn->nextEntry();
+ }
+
+ $conn->close();
+
+ print $result;
+}
+
+&main();
diff --git a/base/tps/forms/esc/cgi-bin/sow/cfg.pl b/base/tps/forms/esc/cgi-bin/sow/cfg.pl
new file mode 100755
index 000000000..d616fa136
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/sow/cfg.pl
@@ -0,0 +1,174 @@
+#! /usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use Mozilla::LDAP::Conn;
+use PKI::TPS::Common;
+
+#
+# Feel free to modify the following parameters:
+#
+my $ldapHost = "localhost";
+my $ldapPort = "389";
+my $basedn = "ou=People,dc=sfbay,dc=redhat,dc=com";
+my $port = "7888";
+my $secure_port = "7889";
+my $host = "localhost";
+
+my $cfg = "/var/lib/pki-tps/conf/CS.cfg";
+
+sub get_ldap_host()
+{
+ my $ldapport = `grep auth.instance.0.hostport $cfg | cut -c26-`;
+ chomp($ldapport);
+ my ($ldapHost, $p) = split(/:/, $ldapport);
+ return $ldapHost;
+}
+
+sub get_ldap_port()
+{
+ my $ldapport = `grep auth.instance.0.hostport $cfg | cut -c26-`;
+ chomp($ldapport);
+ my ($p, $ldapPort) = split(/:/, $ldapport);
+ return $ldapPort;
+}
+
+sub get_ldap_secure()
+{
+ my $ldapsecure = `grep auth.instance.0.ssl $cfg | cut -c21-`;
+ chomp($ldapsecure);
+ return $ldapsecure;
+}
+
+sub get_ldap_certdir()
+{
+ my $ldapcertdir = `grep service.instanceDir $cfg | cut -c21-`;
+ chomp($ldapcertdir);
+ return $ldapcertdir . "/alias";
+}
+
+sub get_base_dn()
+{
+ my $basedn = `grep auth.instance.0.baseDN $cfg | cut -c24-`;
+ chomp($basedn);
+ return $basedn;
+}
+
+sub get_port()
+{
+ my $port = `grep service.unsecurePort $cfg | cut -c22-`;
+ chomp($port);
+ return $port;
+}
+
+sub get_secure_port()
+{
+ my $secure_port = `grep service.securePort $cfg | cut -c20-`;
+ chomp($secure_port);
+ return $secure_port;
+}
+
+sub get_host()
+{
+ my $host = `grep service.machineName $cfg | cut -c21-`;
+ chomp($host);
+ return $host;
+}
+
+sub is_agent()
+{
+ my ($dn) = @_;
+
+ my $uid = $dn;
+ # need to map a subject dn into user DN
+ $uid =~ /uid=([^,]*)/; # retrieve the uid
+ $uid = $1;
+
+ my $x_hostport = `grep -e "^tokendb.hostport" $cfg | cut -c18-`;
+ chomp($x_hostport);
+ my ($x_host, $x_port) = split(/:/, $x_hostport);
+
+ my $x_secureconn = `grep -e "^tokendb.ssl" $cfg | cut -c13-`;
+ chomp($x_secureconn);
+ my $x_basedn = `grep -e "^tokendb.userBaseDN" $cfg | cut -c20-`;
+ chomp($x_basedn);
+ my $x_binddn = `grep -e "^tokendb.bindDN" $cfg | cut -c16-`;
+ chomp($x_binddn);
+ my $x_bindpwdpath = `grep -e "^tokendb.bindPassPath" $cfg | cut -c22-`;
+ chomp($x_bindpwdpath);
+ my $x_bindpwd = `grep -e "^tokendbBindPass" $x_bindpwdpath | cut -c17-`;
+ chomp($x_bindpwd);
+
+ my $ldap = PKI::TPS::Common::make_connection(
+ {host => $x_host, port => $x_port, pswd => $x_bindpwd, bind => $x_binddn, cert => $x_certdir},
+ $x_secureconn);
+
+ return 0 if (! $ldap);
+
+ my $entry = $ldap->search ( "cn=TUS Officers,ou=Groups,$x_basedn",
+ "sub",
+ "uid=$uid",
+ 0
+ );
+
+ $ldap->close();
+
+ if ($entry) {
+ return 1;
+ }
+ return 0;
+}
+
+sub is_user()
+{
+ my ($dn) = @_;
+
+ my $uid = $dn;
+ # need to map a subject dn into user DN
+ $uid =~ /uid=([^,]*)/; # retrieve the uid
+ $uid = $1;
+
+ my $x_host = get_ldap_host();
+ my $x_port = get_ldap_port();
+ my $x_secureconn = get_ldap_secure();
+ my $x_basedn = get_base_dn();
+ my $x_certdir = get_ldap_certdir();
+
+ my $ldap = PKI::TPS::Common::make_connection(
+ {host => $x_host, port => $x_port, cert => $x_certdir},
+ $x_secureconn);
+
+ return 0 if (! $ldap);
+
+ my $entry = $ldap->search ( "ou=people,$x_basedn",
+ "sub",
+ "uid=$uid",
+ 0
+ );
+
+ $ldap->close();
+
+ if ($entry) {
+ return 1;
+ }
+ return 0;
+}
+
diff --git a/base/tps/forms/esc/cgi-bin/sow/enroll.cgi b/base/tps/forms/esc/cgi-bin/sow/enroll.cgi
new file mode 100755
index 000000000..8a6431e52
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/sow/enroll.cgi
@@ -0,0 +1,246 @@
+#! /usr/bin/perl -w
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+########################################################################
+#
+# Script: esc.cgi
+# Author: Kin Blas ()
+# Date: 12/19/2003
+#
+# CGI.pm Docs:
+#
+# http://stein.cshl.org/WWW/software/CGI/
+#
+########################################################################
+
+[REQUIRE_CFG_PL]
+
+use CGI;
+use Mozilla::LDAP::Conn;
+use PKI::TPS::Common;
+
+$gQuery = new CGI;
+
+sub authorize
+{
+ my $client_dn = $ENV{'SSL_CLIENT_S_DN'};
+ $client_dn =~ tr/A-Z/a-z/; # all lower cases
+ $client_dn =~ s/\s+//g; # remove all spacing
+
+ if (&is_agent($client_dn)) {
+ return 1;
+ }
+ return 0;
+}
+
+sub DoPage
+{
+ if (!&authorize()) {
+ print $gQuery->redirect("/cgi-bin/sow/noaccess.cgi");
+ return;
+ }
+
+ $gQueryAction = "default";
+ $gQueryOverrideAction = "default";
+
+ @gCookieNames = ("ascScreenName",
+ "ascSubscriptionType",
+ "ascBindings");
+
+ $gQueryAction = $gQuery->param("action") if
+ (defined $gQuery->param("action"));
+
+ $gQueryOverrideAction = $gQuery->param("override_action")
+ if (defined $gQuery->param("override_action"));
+
+ if ($gQueryOverrideAction ne "default")
+ {
+ $gQueryAction = $gQueryOverrideAction;
+ }
+
+########################################################################
+#
+# If no action was provided, we default to showing our
+# admin page!
+#
+# http://www.foo.com/esc.cgi
+#
+########################################################################
+
+ if ($gQueryAction eq "default")
+ {
+ GenerateEnrollmentPage();
+ exit 0;
+ }
+}
+
+sub ExitError
+{
+ my($str) = @_;
+ print $gQuery->header(), $gQuery->start_html(), $str, $gQuery->end_html();
+ exit 0;
+}
+
+sub GetScreenName
+{
+ my $sn = "";
+
+ if (defined $gQuery->param("screenname"))
+ {
+ $sn = $gQuery->param("screenname");
+ } else {
+ $sn = "default";
+ }
+
+ return $sn;
+}
+
+sub GetKeyType
+{
+ my $keyType = 0;
+
+ if (defined $gQuery->param("keytype"))
+ {
+ $keyType = $gQuery->param("keytype");
+ }
+
+ return $keyType;
+}
+
+sub GetKeyID
+{
+ my $keyID = "";
+
+ if (defined $gQuery->param("keyid"))
+ {
+ $keyID = $gQuery->param("keyid");
+ }
+
+ return $keyID;
+}
+
+sub GetKeyLabelArg
+{
+ my $keyLabel = "";
+
+ if (defined $gQuery->param("keylabel"))
+ {
+ $keyLabel = $gQuery->param("keylabel");
+ }
+
+ return $keyLabel;
+}
+
+sub HaveScreenName
+{
+ return 1 if (GetScreenName() ne "");
+ return 0;
+}
+
+sub IsSubscriber
+{
+ my $subType = $gUserObj{'SUBSCRIPTION'};
+ return 1 if ($subType eq "HouseKey" || $subType eq "NetKey");
+
+ return 0;
+}
+
+sub GetNextAction
+{
+ my($nextActn) = "default";
+
+ if (defined $gQuery->param('nextaction'))
+ {
+ $nextActn = $gQuery->param('nextaction');
+ }
+ elsif (defined $gQuery->param('action'))
+ {
+ $nextActn = $gQuery->param('action');
+ }
+
+ return $nextActn;
+}
+
+sub GenerateEnrollmentPage
+{
+ my ($l);
+ my $ldap_host = get_ldap_host();
+ my $ldap_port = get_ldap_port();
+ my $secureconn = get_ldap_secure();
+ my $basedn = get_base_dn();
+ my $port = get_port();
+ my $host = get_host();
+ my $secure_port = get_secure_port();
+ my $certdir = get_ldap_certdir();
+
+ ExitError("Failed to load enrollment page!") if (!open(ENROLL_FILE, "< enroll.html"));
+
+ print $gQuery->header();
+
+ my $uid = $gQuery->param("uid");
+
+ my $conn = PKI::TPS::Common::make_connection(
+ {host => $ldap_host, port => $ldap_port, cert => $certdir},
+ $secureconn);
+
+ ExitError("Failed to connect to the database. $msg") if (!$conn);
+
+ my $entry = $conn->search ( $basedn,
+ "sub",
+ "uid=$uid",
+ 0
+ );
+
+ if (!$entry) {
+ $conn->close();
+ ExitError("User $uid not found");
+ }
+
+ my $givenName = ($entry->getValues("givenName"))[0] || "-";
+ my $cn = ($entry->getValues("cn"))[0] || "-";
+ my $sn = ($entry->getValues("sn"))[0] ||"-";
+ $uid = ($entry->getValues("uid"))[0] || "-";
+ my $mail = ($entry->getValues("mail"))[0] || "-";
+ my $phone = ($entry->getValues("telephoneNumber"))[0] || "-";
+ my $departmentNumber = ($entry->getValues("departmentNumber"))[0] || "";
+ my $employeeNumber = ($entry->getValues("employeeNumber"))[0] || "";
+
+ while ($l = <ENROLL_FILE>)
+ {
+ $l =~ s/\$mail/$mail/g;
+ $l =~ s/\$uid/$uid/g;
+ $l =~ s/\$givenName/$givenName/g;
+ $l =~ s/\$sn/$sn/g;
+ $l =~ s/\$cn/$cn/g;
+ $l =~ s/\$phone/$phone/g;
+ $l =~ s/\$departmentNumber/$departmentNumber/g;
+ $l =~ s/\$employeeNumber/$employeeNumber/g;
+ $l =~ s/\$host/$host/g;
+ $l =~ s/\$port/$port/g;
+ $l =~ s/\$secure_port/$secure_port/g;
+ print $l;
+ }
+
+ close(ENROLL_FILE);
+}
+
+&DoPage();
diff --git a/base/tps/forms/esc/cgi-bin/sow/enroll_temp.cgi b/base/tps/forms/esc/cgi-bin/sow/enroll_temp.cgi
new file mode 100755
index 000000000..5817039a2
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/sow/enroll_temp.cgi
@@ -0,0 +1,246 @@
+#! /usr/bin/perl -w
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+########################################################################
+#
+# Script: esc.cgi
+# Author: Kin Blas ()
+# Date: 12/19/2003
+#
+# CGI.pm Docs:
+#
+# http://stein.cshl.org/WWW/software/CGI/
+#
+########################################################################
+
+[REQUIRE_CFG_PL]
+
+use CGI;
+use Mozilla::LDAP::Conn;
+use PKI::TPS::Common;
+
+$gQuery = new CGI;
+
+sub authorize
+{
+ my $client_dn = $ENV{'SSL_CLIENT_S_DN'};
+ $client_dn =~ tr/A-Z/a-z/; # all lower cases
+ $client_dn =~ s/\s+//g; # remove all spacing
+
+ if (&is_agent($client_dn)) {
+ return 1;
+ }
+ return 0;
+}
+
+sub DoPage
+{
+ if (!&authorize()) {
+ print $gQuery->redirect("/cgi-bin/sow/noaccess.cgi");
+ return;
+ }
+
+ $gQueryAction = "default";
+ $gQueryOverrideAction = "default";
+
+ @gCookieNames = ("ascScreenName",
+ "ascSubscriptionType",
+ "ascBindings");
+
+ $gQueryAction = $gQuery->param("action") if
+ (defined $gQuery->param("action"));
+
+ $gQueryOverrideAction = $gQuery->param("override_action")
+ if (defined $gQuery->param("override_action"));
+
+ if ($gQueryOverrideAction ne "default")
+ {
+ $gQueryAction = $gQueryOverrideAction;
+ }
+
+########################################################################
+#
+# If no action was provided, we default to showing our
+# admin page!
+#
+# http://www.foo.com/esc.cgi
+#
+########################################################################
+
+ if ($gQueryAction eq "default")
+ {
+ GenerateEnrollmentPage();
+ exit 0;
+ }
+}
+
+sub ExitError
+{
+ my($str) = @_;
+ print $gQuery->header(), $gQuery->start_html(), $str, $gQuery->end_html();
+ exit 0;
+}
+
+sub GetScreenName
+{
+ my $sn = "";
+
+ if (defined $gQuery->param("screenname"))
+ {
+ $sn = $gQuery->param("screenname");
+ } else {
+ $sn = "default";
+ }
+
+ return $sn;
+}
+
+sub GetKeyType
+{
+ my $keyType = 0;
+
+ if (defined $gQuery->param("keytype"))
+ {
+ $keyType = $gQuery->param("keytype");
+ }
+
+ return $keyType;
+}
+
+sub GetKeyID
+{
+ my $keyID = "";
+
+ if (defined $gQuery->param("keyid"))
+ {
+ $keyID = $gQuery->param("keyid");
+ }
+
+ return $keyID;
+}
+
+sub GetKeyLabelArg
+{
+ my $keyLabel = "";
+
+ if (defined $gQuery->param("keylabel"))
+ {
+ $keyLabel = $gQuery->param("keylabel");
+ }
+
+ return $keyLabel;
+}
+
+sub HaveScreenName
+{
+ return 1 if (GetScreenName() ne "");
+ return 0;
+}
+
+sub IsSubscriber
+{
+ my $subType = $gUserObj{'SUBSCRIPTION'};
+ return 1 if ($subType eq "HouseKey" || $subType eq "NetKey");
+
+ return 0;
+}
+
+sub GetNextAction
+{
+ my($nextActn) = "default";
+
+ if (defined $gQuery->param('nextaction'))
+ {
+ $nextActn = $gQuery->param('nextaction');
+ }
+ elsif (defined $gQuery->param('action'))
+ {
+ $nextActn = $gQuery->param('action');
+ }
+
+ return $nextActn;
+}
+
+sub GenerateEnrollmentPage
+{
+ my ($l);
+ my $ldap_host = get_ldap_host();
+ my $ldap_port = get_ldap_port();
+ my $secureconn = get_ldap_secure();
+ my $basedn = get_base_dn();
+ my $port = get_port();
+ my $host = get_host();
+ my $secure_port = get_secure_port();
+ my $certdir = get_ldap_certdir();
+
+ ExitError("Failed to load enrollment page!") if (!open(ENROLL_FILE, "< enroll_temp.html"));
+
+ print $gQuery->header();
+
+ my $uid = $gQuery->param("uid");
+
+ my $conn = PKI::TPS::Common::make_connection(
+ {host => $ldap_host, port => $ldap_port, cert => $certdir},
+ $secureconn);
+
+ ExitError("Failed to connect to the database. $msg") if (!$conn);
+
+ my $entry = $conn->search ( $basedn,
+ "sub",
+ "uid=$uid",
+ 0
+ );
+
+ if (!$entry) {
+ $conn->close();
+ ExitError("User $uid not found");
+ }
+
+ my $givenName = ($entry->getValues("givenName"))[0] || "-";
+ my $cn = ($entry->getValues("cn"))[0] || "-";
+ my $sn = ($entry->getValues("sn"))[0] ||"-";
+ $uid = ($entry->getValues("uid"))[0] || "-";
+ my $mail = ($entry->getValues("mail"))[0] || "-";
+ my $phone = ($entry->getValues("telephoneNumber"))[0] || "-";
+ my $departmentNumber = ($entry->getValues("departmentNumber"))[0] || "";
+ my $employeeNumber = ($entry->getValues("employeeNumber"))[0] || "";
+
+ while ($l = <ENROLL_FILE>)
+ {
+ $l =~ s/\$mail/$mail/g;
+ $l =~ s/\$uid/$uid/g;
+ $l =~ s/\$givenName/$givenName/g;
+ $l =~ s/\$sn/$sn/g;
+ $l =~ s/\$cn/$cn/g;
+ $l =~ s/\$phone/$phone/g;
+ $l =~ s/\$departmentNumber/$departmentNumber/g;
+ $l =~ s/\$employeeNumber/$employeeNumber/g;
+ $l =~ s/\$host/$host/g;
+ $l =~ s/\$port/$port/g;
+ $l =~ s/\$secure_port/$secure_port/g;
+ print $l;
+ }
+
+ close(ENROLL_FILE);
+}
+
+&DoPage();
diff --git a/base/tps/forms/esc/cgi-bin/sow/format.cgi b/base/tps/forms/esc/cgi-bin/sow/format.cgi
new file mode 100755
index 000000000..9b310991d
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/sow/format.cgi
@@ -0,0 +1,207 @@
+#! /usr/bin/perl -w
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+########################################################################
+#
+# Script: esc.cgi
+# Author: Kin Blas ()
+# Date: 12/19/2003
+#
+# CGI.pm Docs:
+#
+# http://stein.cshl.org/WWW/software/CGI/
+#
+########################################################################
+
+[REQUIRE_CFG_PL]
+
+use CGI;
+
+my $ldapHost = get_ldap_host();
+my $ldapPort = get_ldap_port();
+my $basedn = get_base_dn();
+my $host = get_host();
+my $port = get_port();
+my $secure_port = get_secure_port();
+
+$gQuery = new CGI;
+
+sub authorize
+{
+ my $client_dn = $ENV{'SSL_CLIENT_S_DN'};
+ $client_dn =~ tr/A-Z/a-z/; # all lower cases
+ $client_dn =~ s/\s+//g; # remove all spacing
+
+ if (&is_agent($client_dn)) {
+ return 1;
+ }
+ return 0;
+}
+
+sub DoPage
+{
+ if (!&authorize()) {
+ print $gQuery->redirect("/cgi-bin/sow/noaccess.cgi");
+ return;
+ }
+
+ $gQueryAction = "default";
+ $gQueryOverrideAction = "default";
+
+ @gCookieNames = ("ascScreenName",
+ "ascSubscriptionType",
+ "ascBindings");
+
+ $gQueryAction = $gQuery->param("action") if
+ (defined $gQuery->param("action"));
+
+ $gQueryOverrideAction = $gQuery->param("override_action")
+ if (defined $gQuery->param("override_action"));
+
+ if ($gQueryOverrideAction ne "default")
+ {
+ $gQueryAction = $gQueryOverrideAction;
+ }
+
+########################################################################
+#
+# If no action was provided, we default to showing our
+# admin page!
+#
+# http://www.foo.com/esc.cgi
+#
+########################################################################
+
+ if ($gQueryAction eq "default")
+ {
+ GeneratePage();
+ exit 0;
+ }
+}
+
+sub ExitError
+{
+ my($str) = @_;
+ print $gQuery->header(), $gQuery->start_html(), $str, $gQuery->end_html();
+ exit 0;
+}
+
+sub GetScreenName
+{
+ my $sn = "";
+
+ if (defined $gQuery->param("screenname"))
+ {
+ $sn = $gQuery->param("screenname");
+ } else {
+ $sn = "default";
+ }
+
+ return $sn;
+}
+
+sub GetKeyType
+{
+ my $keyType = 0;
+
+ if (defined $gQuery->param("keytype"))
+ {
+ $keyType = $gQuery->param("keytype");
+ }
+
+ return $keyType;
+}
+
+sub GetKeyID
+{
+ my $keyID = "";
+
+ if (defined $gQuery->param("keyid"))
+ {
+ $keyID = $gQuery->param("keyid");
+ }
+
+ return $keyID;
+}
+
+sub GetKeyLabelArg
+{
+ my $keyLabel = "";
+
+ if (defined $gQuery->param("keylabel"))
+ {
+ $keyLabel = $gQuery->param("keylabel");
+ }
+
+ return $keyLabel;
+}
+
+sub HaveScreenName
+{
+ return 1 if (GetScreenName() ne "");
+ return 0;
+}
+
+sub IsSubscriber
+{
+ my $subType = $gUserObj{'SUBSCRIPTION'};
+ return 1 if ($subType eq "HouseKey" || $subType eq "NetKey");
+
+ return 0;
+}
+
+sub GetNextAction
+{
+ my($nextActn) = "default";
+
+ if (defined $gQuery->param('nextaction'))
+ {
+ $nextActn = $gQuery->param('nextaction');
+ }
+ elsif (defined $gQuery->param('action'))
+ {
+ $nextActn = $gQuery->param('action');
+ }
+
+ return $nextActn;
+}
+
+sub GeneratePage
+{
+ my ($l);
+
+ ExitError("Failed to load enrollment page!") if (!open(ENROLL_FILE, "< format.html"));
+
+ print $gQuery->header();
+
+ while ($l = <ENROLL_FILE>)
+ {
+ $l =~ s/\$host/$host/g;
+ $l =~ s/\$port/$port/g;
+ $l =~ s/\$secure_port/$secure_port/g;
+ print $l;
+ }
+
+ close(ENROLL_FILE);
+}
+
+&DoPage();
diff --git a/base/tps/forms/esc/cgi-bin/sow/formatso.cgi b/base/tps/forms/esc/cgi-bin/sow/formatso.cgi
new file mode 100755
index 000000000..d53129139
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/sow/formatso.cgi
@@ -0,0 +1,207 @@
+#! /usr/bin/perl -w
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+########################################################################
+#
+# Script: esc.cgi
+# Author: Kin Blas ()
+# Date: 12/19/2003
+#
+# CGI.pm Docs:
+#
+# http://stein.cshl.org/WWW/software/CGI/
+#
+########################################################################
+
+[REQUIRE_CFG_PL]
+
+use CGI;
+
+my $ldapHost = get_ldap_host();
+my $ldapPort = get_ldap_port();
+my $basedn = get_base_dn();
+my $host = get_host();
+my $port = get_port();
+my $secure_port = get_secure_port();
+
+$gQuery = new CGI;
+
+sub authorize
+{
+ my $client_dn = $ENV{'SSL_CLIENT_S_DN'};
+ $client_dn =~ tr/A-Z/a-z/; # all lower cases
+ $client_dn =~ s/\s+//g; # remove all spacing
+
+ if (&is_agent($client_dn)) {
+ return 1;
+ }
+ return 0;
+}
+
+sub DoPage
+{
+ if (!&authorize()) {
+ print $gQuery->redirect("/cgi-bin/sow/noaccess.cgi");
+ return;
+ }
+
+ $gQueryAction = "default";
+ $gQueryOverrideAction = "default";
+
+ @gCookieNames = ("ascScreenName",
+ "ascSubscriptionType",
+ "ascBindings");
+
+ $gQueryAction = $gQuery->param("action") if
+ (defined $gQuery->param("action"));
+
+ $gQueryOverrideAction = $gQuery->param("override_action")
+ if (defined $gQuery->param("override_action"));
+
+ if ($gQueryOverrideAction ne "default")
+ {
+ $gQueryAction = $gQueryOverrideAction;
+ }
+
+########################################################################
+#
+# If no action was provided, we default to showing our
+# admin page!
+#
+# http://www.foo.com/esc.cgi
+#
+########################################################################
+
+ if ($gQueryAction eq "default")
+ {
+ GeneratePage();
+ exit 0;
+ }
+}
+
+sub ExitError
+{
+ my($str) = @_;
+ print $gQuery->header(), $gQuery->start_html(), $str, $gQuery->end_html();
+ exit 0;
+}
+
+sub GetScreenName
+{
+ my $sn = "";
+
+ if (defined $gQuery->param("screenname"))
+ {
+ $sn = $gQuery->param("screenname");
+ } else {
+ $sn = "default";
+ }
+
+ return $sn;
+}
+
+sub GetKeyType
+{
+ my $keyType = 0;
+
+ if (defined $gQuery->param("keytype"))
+ {
+ $keyType = $gQuery->param("keytype");
+ }
+
+ return $keyType;
+}
+
+sub GetKeyID
+{
+ my $keyID = "";
+
+ if (defined $gQuery->param("keyid"))
+ {
+ $keyID = $gQuery->param("keyid");
+ }
+
+ return $keyID;
+}
+
+sub GetKeyLabelArg
+{
+ my $keyLabel = "";
+
+ if (defined $gQuery->param("keylabel"))
+ {
+ $keyLabel = $gQuery->param("keylabel");
+ }
+
+ return $keyLabel;
+}
+
+sub HaveScreenName
+{
+ return 1 if (GetScreenName() ne "");
+ return 0;
+}
+
+sub IsSubscriber
+{
+ my $subType = $gUserObj{'SUBSCRIPTION'};
+ return 1 if ($subType eq "HouseKey" || $subType eq "NetKey");
+
+ return 0;
+}
+
+sub GetNextAction
+{
+ my($nextActn) = "default";
+
+ if (defined $gQuery->param('nextaction'))
+ {
+ $nextActn = $gQuery->param('nextaction');
+ }
+ elsif (defined $gQuery->param('action'))
+ {
+ $nextActn = $gQuery->param('action');
+ }
+
+ return $nextActn;
+}
+
+sub GeneratePage
+{
+ my ($l);
+
+ ExitError("Failed to load enrollment page!") if (!open(ENROLL_FILE, "< formatso.html"));
+
+ print $gQuery->header();
+
+ while ($l = <ENROLL_FILE>)
+ {
+ $l =~ s/\$host/$host/g;
+ $l =~ s/\$port/$port/g;
+ $l =~ s/\$secure_port/$secure_port/g;
+ print $l;
+ }
+
+ close(ENROLL_FILE);
+}
+
+&DoPage();
diff --git a/base/tps/forms/esc/cgi-bin/sow/index.cgi b/base/tps/forms/esc/cgi-bin/sow/index.cgi
new file mode 100755
index 000000000..7f7a98869
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/sow/index.cgi
@@ -0,0 +1,42 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+#
+#
+#
+print "Content-type: text/xml\n\n";
+print "<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>";
+print "<ServiceInfo>";
+print "<IssuerName>";
+print "Fedora Project"; # Vendor
+print "</IssuerName>\n";
+print "<Services>";
+print "<Operation>";
+print "https://[SERVER_NAME]:[SECURE_PORT]/nk_service";
+print "</Operation>";
+print "<UI>";
+print "https://[SERVER_NAME]:[SECURE_PORT]/cgi-bin/sow/search.cgi";
+print "</UI>";
+print "<EnrolledTokenBrowserURL>";
+print "</EnrolledTokenBrowserURL>";
+print "</Services>";
+print "</ServiceInfo>";
diff --git a/base/tps/forms/esc/cgi-bin/sow/is_agent.cgi b/base/tps/forms/esc/cgi-bin/sow/is_agent.cgi
new file mode 100755
index 000000000..c6b6a87f7
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/sow/is_agent.cgi
@@ -0,0 +1,69 @@
+#! /usr/bin/perl -w
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use CGI;
+
+[REQUIRE_CFG_PL]
+
+
+my $ldapHost = get_ldap_host();
+my $ldapPort = get_ldap_port();
+my $basedn = get_base_dn();
+
+my $q = new CGI;
+
+sub authorize
+{
+ my $client_dn = $ENV{'SSL_CLIENT_S_DN'};
+ $client_dn =~ tr/A-Z/a-z/; # all lower cases
+ $client_dn =~ s/\s+//g; # remove all spacing
+
+ if (&is_agent($client_dn)) {
+ return 1;
+ }
+ return 0;
+}
+
+sub DoIsAgent
+{
+
+ print "Content-type: text/xml\n\n";
+
+ if (!&authorize()) {
+ return;
+ }
+
+ my $uid = $q->param('uid');
+
+ if(&is_agent("uid=$uid"))
+ {
+ print "<response>yes</response>\n";
+ }
+ else
+ {
+ print "<response>no</response>\n";
+ }
+
+}
+
+&DoIsAgent();
diff --git a/base/tps/forms/esc/cgi-bin/sow/is_user.cgi b/base/tps/forms/esc/cgi-bin/sow/is_user.cgi
new file mode 100755
index 000000000..d7a551421
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/sow/is_user.cgi
@@ -0,0 +1,71 @@
+#! /usr/bin/perl -w
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use CGI;
+
+use CGI::Carp qw(fatalsToBrowser);
+
+[REQUIRE_CFG_PL]
+
+
+my $ldapHost = get_ldap_host();
+my $ldapPort = get_ldap_port();
+my $basedn = get_base_dn();
+
+my $q = new CGI;
+
+sub authorize
+{
+ my $client_dn = $ENV{'SSL_CLIENT_S_DN'};
+ $client_dn =~ tr/A-Z/a-z/; # all lower cases
+ $client_dn =~ s/\s+//g; # remove all spacing
+
+ if (&is_agent($client_dn)) {
+ return 1;
+ }
+ return 0;
+}
+
+sub DoIsUser
+{
+
+ print "Content-type: text/xml\n\n";
+
+ if (!&authorize()) {
+ return;
+ }
+
+ my $uid = $q->param('uid');
+
+ if(&is_user("uid=$uid"))
+ {
+ print "<response>yes</response>\n";
+ }
+ else
+ {
+ print "<response>no</response>\n";
+ }
+
+}
+
+&DoIsUser();
diff --git a/base/tps/forms/esc/cgi-bin/sow/main.cgi b/base/tps/forms/esc/cgi-bin/sow/main.cgi
new file mode 100755
index 000000000..c6f65e42e
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/sow/main.cgi
@@ -0,0 +1,70 @@
+#! /usr/bin/perl -w
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use CGI;
+
+[REQUIRE_CFG_PL]
+
+
+my $ldapHost = get_ldap_host();
+my $ldapPort = get_ldap_port();
+my $basedn = get_base_dn();
+
+my $q = new CGI;
+
+sub authorize
+{
+ my $client_dn = $ENV{'SSL_CLIENT_S_DN'};
+ $client_dn =~ tr/A-Z/a-z/; # all lower cases
+ $client_dn =~ s/\s+//g; # remove all spacing
+
+ if (&is_agent($client_dn)) {
+ return 1;
+ }
+ return 0;
+}
+
+sub DoPage
+{
+ if (!&authorize()) {
+ print $q->redirect("/cgi-bin/sow/noaccess.cgi");
+ return;
+ }
+
+ my $error = $q->param('error');
+ $error = "" if !defined $error;
+
+ open(FILE, "< main.html");
+
+ print $q->header();
+
+ while ($l = <FILE>)
+ {
+ $l =~ s/\$error/$error/g;
+ print $l;
+ }
+
+ close(FILE);
+}
+
+&DoPage();
diff --git a/base/tps/forms/esc/cgi-bin/sow/noaccess.cgi b/base/tps/forms/esc/cgi-bin/sow/noaccess.cgi
new file mode 100755
index 000000000..17166bcb6
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/sow/noaccess.cgi
@@ -0,0 +1,56 @@
+#! /usr/bin/perl -w
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use CGI;
+
+[REQUIRE_CFG_PL]
+
+
+my $host = get_host();
+my $secure_port = get_secure_port();
+my $port = get_port();
+
+my $q = new CGI;
+
+sub DoPage
+{
+
+ my $error = $q->param('error');
+
+ open(FILE, "< noaccess.html");
+
+ print $q->header();
+
+ while ($l = <FILE>)
+ {
+ $l =~ s/\$error/$error/g;
+ $l =~ s/\$host/$host/g;
+ $l =~ s/\$secure_port/$secure_port/g;
+ $l =~ s/\$port/$port/g;
+ print $l;
+ }
+
+ close(FILE);
+}
+
+&DoPage();
diff --git a/base/tps/forms/esc/cgi-bin/sow/read.cgi b/base/tps/forms/esc/cgi-bin/sow/read.cgi
new file mode 100755
index 000000000..8a5793c2b
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/sow/read.cgi
@@ -0,0 +1,128 @@
+#! /usr/bin/perl -w
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use CGI;
+use Mozilla::LDAP::Conn;
+use PKI::TPS::Common;
+
+[REQUIRE_CFG_PL]
+
+sub authorize
+{
+ my $client_dn = $ENV{'SSL_CLIENT_S_DN'};
+ $client_dn =~ tr/A-Z/a-z/; # all lower cases
+ $client_dn =~ s/\s+//g; # remove all spacing
+
+ if (&is_agent($client_dn)) {
+ return 1;
+ }
+ return 0;
+}
+
+sub DoPage
+{
+ my $q = new CGI;
+ my $host = get_ldap_host();
+ my $port = get_ldap_port();
+ my $secureconn = get_ldap_secure();
+ my $basedn = get_base_dn();
+ my $certdir = get_ldap_certdir();
+
+ if (!&authorize()) {
+ print $q->redirect("/cgi-bin/sow/noaccess.cgi");
+ return;
+ }
+
+ my $name = $q->param('name');
+ my $uid = $q->param('name_ID');
+ $name = "" if !defined $name;
+
+ if ($name eq "") {
+ print $q->redirect("/cgi-bin/sow/search.cgi?error=Name cannot be empty");
+ return;
+ }
+
+ my $conn = PKI::TPS::Common::make_connection(
+ {host => $host, port => $port, cert => $certdir},
+ $secureconn);
+
+ if (!$conn) {
+ print $q->redirect("/cgi-bin/sow/search.cgi?error=Failed to connect to the database.");
+ return;
+ };
+
+ my $entry = $conn->search ( $basedn,
+ "sub",
+ "cn=$name",
+ 0
+ );
+
+ if (!$entry) {
+ $conn->close();
+ print $q->redirect("/cgi-bin/sow/search.cgi?error=User $name not found");
+ return;
+ }
+
+ my $givenName = ($entry->getValues("givenName"))[0] || "-";
+ my $cn = ($entry->getValues("cn"))[0] || "-";
+ my $sn = ($entry->getValues("sn"))[0] ||"-";
+ $uid = ($entry->getValues("uid"))[0] || "-";
+ my $mail = ($entry->getValues("mail"))[0] || "-";
+ my $phone = ($entry->getValues("telephoneNumber"))[0] || "-";
+ my $photoLarge = ($entry->getValues("photoLarge"))[0] || ""; # photo (full size)
+ my $photoSmall = ($entry->getValues("photoSmall"))[0] || ""; # photo (thumb)
+ my $height = ($entry->getValues("height"))[0] || "";
+ my $weight = ($entry->getValues("weight"))[0] || "";
+ my $eyecolor = ($entry->getValues("eyeColor"))[0] || "";
+
+ $conn->close();
+
+ if ($uid eq "-") {
+ print $q->redirect("/cgi-bin/sow/search.cgi?error=User $name not found");
+ return;
+ }
+
+ open(FILE, "< read.html");
+
+ print $q->header();
+
+ while ($l = <FILE>)
+ {
+ $l =~ s/\$mail/$mail/g;
+ $l =~ s/\$uid/$uid/g;
+ $l =~ s/\$givenName/$givenName/g;
+ $l =~ s/\$sn/$sn/g;
+ $l =~ s/\$cn/$cn/g;
+ $l =~ s/\$phone/$phone/g;
+ $l =~ s/\$photoLarge/$photoLarge/g;
+ $l =~ s/\$photoSmall/$photoSmall/g;
+ $l =~ s/\$height/$height/g;
+ $l =~ s/\$weight/$weight/g;
+ $l =~ s/\$eyecolor/$eyecolor/g;
+ print $l;
+ }
+
+ close(FILE);
+}
+
+&DoPage();
diff --git a/base/tps/forms/esc/cgi-bin/sow/read_temp.cgi b/base/tps/forms/esc/cgi-bin/sow/read_temp.cgi
new file mode 100755
index 000000000..31c6fd7e3
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/sow/read_temp.cgi
@@ -0,0 +1,125 @@
+#! /usr/bin/perl -w
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use CGI;
+use Mozilla::LDAP::Conn;
+use PKI::TPS::Common;
+
+[REQUIRE_CFG_PL]
+
+
+sub authorize
+{
+ my $client_dn = $ENV{'SSL_CLIENT_S_DN'};
+ $client_dn =~ tr/A-Z/a-z/; # all lower cases
+ $client_dn =~ s/\s+//g; # remove all spacing
+
+ if (&is_agent($client_dn)) {
+ return 1;
+ }
+ return 0;
+}
+
+sub DoPage
+{
+ my $q = new CGI;
+ my $host = get_ldap_host();
+ my $port = get_ldap_port();
+ my $secureconn = get_ldap_secure();
+ my $basedn = get_base_dn();
+ my $certdir = get_ldap_certdir();
+
+ if (!&authorize()) {
+ print $q->redirect("/cgi-bin/sow/noaccess.cgi");
+ return;
+ }
+
+ my $name = $q->param('name');
+ my $uid = $q->param('name_ID');
+ $name = "" if !defined $name;
+
+ if ($name eq "") {
+ print $q->redirect("/cgi-bin/sow/search.cgi?error=Name cannot be empty");
+ return;
+ }
+
+ my $conn = PKI::TPS::Common::make_connection(
+ {host => $host, port => $port, cert => $certdir},
+ $secureconn);
+
+
+ my $entry = $conn->search ( $basedn,
+ "sub",
+ "cn=$name",
+ 0
+ );
+
+ if (!$entry) {
+ $conn->close();
+ print $q->redirect("/cgi-bin/sow/search.cgi?error=User $name not found");
+ return;
+ }
+
+ my $givenName = ($entry->getValues("givenName"))[0] || "-";
+ my $cn = ($entry->getValues("cn"))[0] || "-";
+ my $sn = ($entry->getValues("sn"))[0] ||"-";
+ $uid = ($entry->getValues("uid"))[0] || "-";
+ my $mail = ($entry->getValues("mail"))[0] || "-";
+ my $phone = ($entry->getValues("telephoneNumber"))[0] || "-";
+ my $photoLarge = ($entry->getValues("photoLarge"))[0] || ""; # photo (full size)
+ my $photoSmall = ($entry->getValues("photoSmall"))[0] || ""; # photo (thumb)
+ my $height = ($entry->getValues("height"))[0] || "";
+ my $weight = ($entry->getValues("weight"))[0] || "";
+ my $eyecolor = ($entry->getValues("eyeColor"))[0] || "";
+
+ $conn->close();
+
+ if ($uid eq "-") {
+ print $q->redirect("/cgi-bin/sow/search.cgi?error=User $name not found");
+ return;
+ }
+
+ open(FILE, "< read_temp.html");
+
+ print $q->header();
+
+ while ($l = <FILE>)
+ {
+ $l =~ s/\$mail/$mail/g;
+ $l =~ s/\$uid/$uid/g;
+ $l =~ s/\$givenName/$givenName/g;
+ $l =~ s/\$sn/$sn/g;
+ $l =~ s/\$cn/$cn/g;
+ $l =~ s/\$phone/$phone/g;
+ $l =~ s/\$photoLarge/$photoLarge/g;
+ $l =~ s/\$photoSmall/$photoSmall/g;
+ $l =~ s/\$height/$height/g;
+ $l =~ s/\$weight/$weight/g;
+ $l =~ s/\$eyecolor/$eyecolor/g;
+ print $l;
+ }
+
+ close(FILE);
+}
+
+&DoPage();
diff --git a/base/tps/forms/esc/cgi-bin/sow/search.cgi b/base/tps/forms/esc/cgi-bin/sow/search.cgi
new file mode 100755
index 000000000..e681ed100
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/sow/search.cgi
@@ -0,0 +1,70 @@
+#! /usr/bin/perl -w
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use CGI;
+
+[REQUIRE_CFG_PL]
+
+
+my $ldapHost = get_ldap_host();
+my $ldapPort = get_ldap_port();
+my $basedn = get_base_dn();
+
+my $q = new CGI;
+
+sub authorize
+{
+ my $client_dn = $ENV{'SSL_CLIENT_S_DN'};
+ $client_dn =~ tr/A-Z/a-z/; # all lower cases
+ $client_dn =~ s/\s+//g; # remove all spacing
+
+ if (&is_agent($client_dn)) {
+ return 1;
+ }
+ return 0;
+}
+
+sub DoPage
+{
+ if (!&authorize()) {
+ print $q->redirect("/cgi-bin/sow/noaccess.cgi");
+ return;
+ }
+
+ my $error = $q->param('error');
+ $error = "" if !defined $error;
+
+ open(FILE, "< search.html");
+
+ print $q->header();
+
+ while ($l = <FILE>)
+ {
+ $l =~ s/\$error/$error/g;
+ print $l;
+ }
+
+ close(FILE);
+}
+
+&DoPage();
diff --git a/base/tps/forms/esc/cgi-bin/sow/search_temp.cgi b/base/tps/forms/esc/cgi-bin/sow/search_temp.cgi
new file mode 100755
index 000000000..5d752a49d
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/sow/search_temp.cgi
@@ -0,0 +1,70 @@
+#! /usr/bin/perl -w
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use CGI;
+
+[REQUIRE_CFG_PL]
+
+
+my $ldapHost = get_ldap_host();
+my $ldapPort = get_ldap_port();
+my $basedn = get_base_dn();
+
+my $q = new CGI;
+
+sub authorize
+{
+ my $client_dn = $ENV{'SSL_CLIENT_S_DN'};
+ $client_dn =~ tr/A-Z/a-z/; # all lower cases
+ $client_dn =~ s/\s+//g; # remove all spacing
+
+ if (&is_agent($client_dn)) {
+ return 1;
+ }
+ return 0;
+}
+
+sub DoPage
+{
+ if (!&authorize()) {
+ print $q->redirect("/cgi-bin/sow/noaccess.cgi");
+ return;
+ }
+
+ my $error = $q->param('error');
+ $error = "" if !defined $error;
+
+ open(FILE, "< search_temp.html");
+
+ print $q->header();
+
+ while ($l = <FILE>)
+ {
+ $l =~ s/\$error/$error/g;
+ print $l;
+ }
+
+ close(FILE);
+}
+
+&DoPage();
diff --git a/base/tps/forms/esc/cgi-bin/sow/seturl.cgi b/base/tps/forms/esc/cgi-bin/sow/seturl.cgi
new file mode 100755
index 000000000..dfac46d8f
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/sow/seturl.cgi
@@ -0,0 +1,207 @@
+#! /usr/bin/perl -w
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+########################################################################
+#
+# Script: esc.cgi
+# Author: Kin Blas ()
+# Date: 12/19/2003
+#
+# CGI.pm Docs:
+#
+# http://stein.cshl.org/WWW/software/CGI/
+#
+########################################################################
+
+[REQUIRE_CFG_PL]
+
+use CGI;
+
+my $ldapHost = get_ldap_host();
+my $ldapPort = get_ldap_port();
+my $basedn = get_base_dn();
+my $host = get_host();
+my $port = get_port();
+my $secure_port = get_secure_port();
+
+$gQuery = new CGI;
+
+sub authorize
+{
+ my $client_dn = $ENV{'SSL_CLIENT_S_DN'};
+ $client_dn =~ tr/A-Z/a-z/; # all lower cases
+ $client_dn =~ s/\s+//g; # remove all spacing
+
+ if (&is_agent($client_dn)) {
+ return 1;
+ }
+ return 0;
+}
+
+sub DoPage
+{
+ if (!&authorize()) {
+ print $gQuery->redirect("/cgi-bin/sow/noaccess.cgi");
+ return;
+ }
+
+ $gQueryAction = "default";
+ $gQueryOverrideAction = "default";
+
+ @gCookieNames = ("ascScreenName",
+ "ascSubscriptionType",
+ "ascBindings");
+
+ $gQueryAction = $gQuery->param("action") if
+ (defined $gQuery->param("action"));
+
+ $gQueryOverrideAction = $gQuery->param("override_action")
+ if (defined $gQuery->param("override_action"));
+
+ if ($gQueryOverrideAction ne "default")
+ {
+ $gQueryAction = $gQueryOverrideAction;
+ }
+
+########################################################################
+#
+# If no action was provided, we default to showing our
+# admin page!
+#
+# http://www.foo.com/esc.cgi
+#
+########################################################################
+
+ if ($gQueryAction eq "default")
+ {
+ GeneratePage();
+ exit 0;
+ }
+}
+
+sub ExitError
+{
+ my($str) = @_;
+ print $gQuery->header(), $gQuery->start_html(), $str, $gQuery->end_html();
+ exit 0;
+}
+
+sub GetScreenName
+{
+ my $sn = "";
+
+ if (defined $gQuery->param("screenname"))
+ {
+ $sn = $gQuery->param("screenname");
+ } else {
+ $sn = "default";
+ }
+
+ return $sn;
+}
+
+sub GetKeyType
+{
+ my $keyType = 0;
+
+ if (defined $gQuery->param("keytype"))
+ {
+ $keyType = $gQuery->param("keytype");
+ }
+
+ return $keyType;
+}
+
+sub GetKeyID
+{
+ my $keyID = "";
+
+ if (defined $gQuery->param("keyid"))
+ {
+ $keyID = $gQuery->param("keyid");
+ }
+
+ return $keyID;
+}
+
+sub GetKeyLabelArg
+{
+ my $keyLabel = "";
+
+ if (defined $gQuery->param("keylabel"))
+ {
+ $keyLabel = $gQuery->param("keylabel");
+ }
+
+ return $keyLabel;
+}
+
+sub HaveScreenName
+{
+ return 1 if (GetScreenName() ne "");
+ return 0;
+}
+
+sub IsSubscriber
+{
+ my $subType = $gUserObj{'SUBSCRIPTION'};
+ return 1 if ($subType eq "HouseKey" || $subType eq "NetKey");
+
+ return 0;
+}
+
+sub GetNextAction
+{
+ my($nextActn) = "default";
+
+ if (defined $gQuery->param('nextaction'))
+ {
+ $nextActn = $gQuery->param('nextaction');
+ }
+ elsif (defined $gQuery->param('action'))
+ {
+ $nextActn = $gQuery->param('action');
+ }
+
+ return $nextActn;
+}
+
+sub GeneratePage
+{
+ my ($l);
+
+ ExitError("Failed to load enrollment page!") if (!open(ENROLL_FILE, "< seturl.html"));
+
+ print $gQuery->header();
+
+ while ($l = <ENROLL_FILE>)
+ {
+ $l =~ s/\$host/$host/g;
+ $l =~ s/\$port/$port/g;
+ $l =~ s/\$secure_port/$secure_port/g;
+ print $l;
+ }
+
+ close(ENROLL_FILE);
+}
+
+&DoPage();
diff --git a/base/tps/forms/esc/cgi-bin/sow/welcome.cgi b/base/tps/forms/esc/cgi-bin/sow/welcome.cgi
new file mode 100755
index 000000000..bc76dd3fa
--- /dev/null
+++ b/base/tps/forms/esc/cgi-bin/sow/welcome.cgi
@@ -0,0 +1,57 @@
+#! /usr/bin/perl -w
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use CGI;
+
+[REQUIRE_CFG_PL]
+
+
+my $host = get_host();
+my $secure_port = get_secure_port();
+my $port = get_port();
+
+my $q = new CGI;
+
+sub DoPage
+{
+
+ my $error = $q->param('error');
+ $error = "" if !defined $error;
+
+ open(FILE, "< welcome.html");
+
+ print $q->header();
+
+ while ($l = <FILE>)
+ {
+ $l =~ s/\$error/$error/g;
+ $l =~ s/\$host/$host/g;
+ $l =~ s/\$secure_port/$secure_port/g;
+ $l =~ s/\$port/$port/g;
+ print $l;
+ }
+
+ close(FILE);
+}
+
+&DoPage();
diff --git a/base/tps/forms/esc/esc.cgi b/base/tps/forms/esc/esc.cgi
new file mode 100755
index 000000000..70a93c0a0
--- /dev/null
+++ b/base/tps/forms/esc/esc.cgi
@@ -0,0 +1,1239 @@
+#! /usr/bin/perl -w
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+########################################################################
+#
+# Script: esc.cgi
+# Author: Kin Blas ()
+# Date: 12/19/2003
+#
+# CGI.pm Docs:
+#
+# http://stein.cshl.org/WWW/software/CGI/
+#
+########################################################################
+
+use CGI;
+
+$gQuery = new CGI;
+
+$gQueryAction = "default";
+$gQueryOverrideAction = "default";
+
+@gCookieNames = ("ascScreenName",
+ "ascSubscriptionType",
+ "ascBindings");
+
+$gQueryAction = $gQuery->param("action") if (defined $gQuery->param("action"));
+
+$gQueryOverrideAction = $gQuery->param("override_action")
+ if (defined $gQuery->param("override_action"));
+
+if ($gQueryOverrideAction ne "default")
+{
+ $gQueryAction = $gQueryOverrideAction;
+}
+
+########################################################################
+#
+# If no action was provided, we default to showing our
+# admin page!
+#
+# http://www.foo.com/esc.cgi
+#
+########################################################################
+
+if ($gQueryAction eq "default")
+{
+ GenerateAdminPage();
+ exit 0;
+}
+
+########################################################################
+#
+# We aren't doing any admin functions, before proceeding
+# on to user specific functions, make sure we have a screen name
+# and that they are subscribed to a service.
+#
+########################################################################
+
+#if (!HaveScreenName() || $gQueryAction eq "screennamepage")
+#{
+# GenerateScreenNamePage($gQueryAction);
+# exit 0;
+#}
+
+LoadUserDatabase("default");
+
+########################################################################
+#
+# Subscribe?
+#
+# http://www.foo.com/esc.cgi?action=subscribe
+#
+########################################################################
+
+#if ($gQueryAction eq "subscribe")
+#{
+# SaveSubscription();
+# $nextAction = GetNextAction();
+# $redirectLocation = $gQuery->url(-path_info=>1)."?action=$nextAction&screenname=".GetScreenName();
+# print $gQuery->redirect(-uri=>$redirectLocation);
+# exit 0;
+#}
+
+#if (!IsSubscriber() || $gQueryAction eq "subscriptionpage")
+#{
+# GenerateTOSPage($gQueryAction);
+# exit 0;
+#}
+
+########################################################################
+#
+# Show our cookie management page?
+#
+# http://www.foo.com/esc.cgi?action=cookiepage
+#
+########################################################################
+
+#if ($gQueryAction eq "cookiepage")
+#{
+# GenerateCookiesPage();
+# exit 0;
+#}
+
+########################################################################
+#
+# Clear cookies?
+#
+# http://www.foo.com/esc.cgi?action=clearAllCookies
+#
+########################################################################
+
+#if ($gQueryAction eq "removeCookies")
+#{
+# @expCookies = ();
+# foreach $cookie (@gCookieNames)
+# {
+# if (defined $gQuery->param($cookie))
+# {
+# $expCookies[$cookieCnt++] = CreateExpiredCookie($cookie);
+# }
+# }
+# $redirectLocation = $gQuery->url(-path_info=>1)."?action=cookiepage&screenname=".GetScreenName();
+# print $gQuery->redirect(-uri=>$redirectLocation,
+# -cookie=>\@expCookies);
+# exit 0;
+#}
+
+########################################################################
+#
+# Bind?
+#
+#
+########################################################################
+
+if ($gQueryAction eq "bind")
+{
+ UpdateBindingsForBind();
+ $nextAction = GetNextAction();
+
+ $nextAction = "bindpage" if ($nextAction eq $gQueryAction);
+
+ $redirectLocation = $gQuery->url(-path_info=>1)."?action=$nextAction&prevaction=bind&screenname=".GetScreenName()."&keytype=".GetKeyType()."&keyid=".GetKeyID()."&keylabel=".GetKeyLabelArg();
+ print $gQuery->redirect(-uri=>$redirectLocation);
+ exit 0;
+}
+
+########################################################################
+#
+# Unbind?
+#
+#
+########################################################################
+
+if ($gQueryAction eq "unbind")
+{
+ UpdateBindingsForUnbind();
+
+ $nextAction = GetNextAction();
+
+ $nextAction = "bindpage" if ($nextAction eq $gQueryAction);
+
+ $redirectLocation = $gQuery->url(-path_info=>1)."?action=$nextAction&prevaction=unbind&screenname=".GetScreenName()."&keytype=".GetKeyType()."&keyid=".GetKeyID()."&keylabel=".GetKeyLabelArg();
+ print $gQuery->redirect(-uri=>$redirectLocation);
+ exit 0;
+}
+
+########################################################################
+#
+# Label?
+#
+#
+########################################################################
+
+if ($gQueryAction eq "label")
+{
+ UpdateBindingsForLabel();
+
+ $nextAction = GetNextAction();
+
+ $nextAction = "bindpage" if ($nextAction eq $gQueryAction);
+
+ $redirectLocation = $gQuery->url(-path_info=>1)."?action=$nextAction&screenname=".GetScreenName();
+ print $gQuery->redirect(-uri=>$redirectLocation);
+ exit 0;
+}
+
+########################################################################
+#
+# ScreenName?
+#
+#
+########################################################################
+
+#if ($gQueryAction eq "screenname")
+#{
+# $nextAction = GetNextAction();
+# $redirectLocation = $gQuery->url(-path_info=>1)."?action=$nextAction&screenname=".GetScreenName();
+# print $gQuery->redirect(-uri=>$redirectLocation);
+# exit 0;
+#}
+
+########################################################################
+#
+# Check if we are displaying the label page.
+#
+#
+########################################################################
+
+if ($gQueryAction eq "labelpage")
+{
+ my $nextAction = GetNextAction();
+ $nextAction = "bindpage" if ($nextAction eq $gQueryAction);
+
+ my $keyType = GetKeyType();
+ my $keyId = GetKeyID();
+
+ GenerateLabelPage($keyType, $keyId, $nextAction);
+ exit 0;
+}
+
+########################################################################
+#
+# Show our enrollment page?
+#
+# http://www.foo.com/esc.cgi?action=enrollmentpage
+#
+########################################################################
+
+if ($gQueryAction eq "enrollmentpage")
+{
+ GenerateEnrollmentPage();
+ exit 0;
+}
+
+if ($gQueryAction eq "advancepage")
+{
+ GenerateAdvancePage();
+ exit 0;
+}
+
+if ($gQueryAction eq "tokenmanagerpage")
+{
+ GenerateTokenManagerPage();
+ exit 0;
+}
+
+if($gQueryAction eq "authenticate")
+{
+
+ GenerateAuthenticationPage();
+ exit 0;
+}
+
+if ($gQueryAction eq "autoenroll")
+{
+ GenerateAutoEnrollmentPage();
+ exit 0;
+}
+
+########################################################################
+#
+# Show our ticket request page?
+#
+#
+########################################################################
+
+if ($gQueryAction eq "ticketreqpage")
+{
+ GenerateTicketRequestPage();
+ exit 0;
+}
+
+########################################################################
+#
+# Show our load external url page?
+#
+# http://www.foo.com/esc.cgi?action=loadurlpage
+#
+########################################################################
+
+
+if ($gQueryAction eq "loadurl")
+{
+ $nextAction = GetNextAction();
+ $redirectLocation = $gQuery->param('url');
+ print $gQuery->redirect(-uri=>$redirectLocation);
+ exit 0;
+}
+
+if ($gQueryAction eq "loadurlpage")
+{
+ GenerateLoadURLPage();
+ exit 0;
+}
+
+########################################################################
+#
+# User is subscribed, check if we are displaying the
+# settings page.
+#
+#
+########################################################################
+
+if ($gQueryAction eq "settingspage")
+{
+ GenerateSettingsPage();
+ exit 0;
+}
+
+########################################################################
+#
+# Check if we are displaying the set label page.
+#
+#
+########################################################################
+
+if ($gQueryAction eq "setlabelpage")
+{
+ GenerateSetLabelPage();
+ exit 0;
+}
+
+########################################################################
+#
+# Check if we are displaying the bind/unbind progress page!
+#
+#
+########################################################################
+
+if ($gQueryAction eq "bindprogresspage")
+{
+ GenerateBindProgressPage("bind");
+ exit 0;
+}
+
+if ($gQueryAction eq "unbindprogresspage")
+{
+ GenerateBindProgressPage("unbind");
+ exit 0;
+}
+
+########################################################################
+#
+# Check if we are displaying the bind/unbind success page!
+#
+#
+########################################################################
+
+if ($gQueryAction eq "bindsuccesspage")
+{
+ GenerateBindSuccessPage("bind");
+ exit 0;
+}
+
+if ($gQueryAction eq "unbindsuccesspage")
+{
+ GenerateBindSuccessPage("unbind");
+ exit 0;
+}
+
+########################################################################
+#
+# XXX: Lose this code!
+# User is subscribed, check if we are displaying the
+# binding page.
+#
+#
+########################################################################
+
+if ($gQueryAction eq "bindpage")
+{
+ GenerateBindingConfigPage();
+ exit 0;
+}
+
+print "<html><body><H1> Unknown Query Action ";
+print $qQueryAction;
+print "</H1></body></html>";
+exit 0;
+
+########################################################################
+#
+#
+########################################################################
+
+
+sub ExitError
+{
+ my($str) = @_;
+ print $gQuery->header(), $gQuery->start_html(), $str, $gQuery->end_html();
+ exit 0;
+}
+
+sub GetScreenName
+{
+ my $sn = "";
+
+ if (defined $gQuery->param("screenname"))
+ {
+ $sn = $gQuery->param("screenname");
+ } else {
+ $sn = "default";
+ }
+
+ return $sn;
+}
+
+sub GetKeyType
+{
+ my $keyType = 0;
+
+ if (defined $gQuery->param("keytype"))
+ {
+ $keyType = $gQuery->param("keytype");
+ }
+
+ return $keyType;
+}
+
+sub GetKeyID
+{
+ my $keyID = "";
+
+ if (defined $gQuery->param("keyid"))
+ {
+ $keyID = $gQuery->param("keyid");
+ }
+
+ return $keyID;
+}
+
+sub GetKeyLabelArg
+{
+ my $keyLabel = "";
+
+ if (defined $gQuery->param("keylabel"))
+ {
+ $keyLabel = $gQuery->param("keylabel");
+ }
+
+ return $keyLabel;
+}
+
+sub HaveScreenName
+{
+ return 1 if (GetScreenName() ne "");
+ return 0;
+}
+
+sub IsSubscriber
+{
+ my $subType = $gUserObj{'SUBSCRIPTION'};
+ return 1 if ($subType eq "HouseKey" || $subType eq "NetKey");
+
+ return 0;
+}
+
+sub GetNextAction
+{
+ my($nextActn) = "default";
+
+ if (defined $gQuery->param('nextaction'))
+ {
+ $nextActn = $gQuery->param('nextaction');
+ }
+ elsif (defined $gQuery->param('action'))
+ {
+ $nextActn = $gQuery->param('action');
+ }
+
+ return $nextActn;
+}
+
+sub GenerateAdminPage()
+{
+ my ($l);
+
+ ExitError("Failed to load Admin Page") if (!open(ADMIN_FILE, "< ./AdminEsc.html"));
+
+ print $gQuery->header();
+
+ while ($l = <ADMIN_FILE>)
+ {
+ if ($l =~ /<!-- *SECURECOOL_SCREENNAME *-->/)
+ {
+ my $sn = GetScreenName();
+ $l =~ s/<!-- *SECURECOOL_SCREENNAME *-->/$sn/g;
+ }
+ print $l;
+ }
+ close(ADMIN_FILE);
+}
+
+sub GenerateCookiesPage()
+{
+ my ($nextPage) = @_;
+
+ my ($l);
+
+ ExitError("Failed to load TOS Page") if (!open(COOKIE_FILE, "< Cookies.html"));
+
+ print $gQuery->header();
+
+ while ($l = <COOKIE_FILE>)
+ {
+ if ($l =~ /SECURECOOL_COOKIE_LIST/)
+ {
+ my @cookies = $gQuery->cookie();
+ if (@cookies < 1)
+ {
+ print "No ASC Cookies currently defined!<br>\n";
+ }
+ else
+ {
+ my $cookieName;
+ foreach $cookieName (@cookies)
+ {
+ #
+ # Display only ASC related cookies!
+ #
+
+ if ($cookieName =~ /^asc/)
+ {
+ print "<tr><td valign=\"center\" align=\"center\"><input type=\"checkbox\" name=\"$cookieName\"></td><td>$cookieName</td><td>", $gQuery->cookie($cookieName), "</td></tr>\n";
+ }
+ }
+ print "<br>\n";
+ }
+ }
+ elsif ($l =~ /<!-- *SECURECOOL_SCREENNAME *-->/)
+ {
+ my $sn = GetScreenName();
+ $l =~ s/<!-- *SECURECOOL_SCREENNAME *-->/$sn/g;
+ print $l;
+ }
+ else
+ {
+ print $l;
+ }
+ }
+ close(COOKIE_FILE);
+}
+
+sub GenerateScreenNamePage
+{
+ my ($nextPage) = @_;
+
+ my ($l);
+
+ ExitError("Failed to load ScreenName Page") if (!open(SN_FILE, "< ScreenName.html"));
+
+ print $gQuery->header();
+
+ my $sn = GetScreenName();
+
+ while ($l = <SN_FILE>)
+ {
+ if ($l =~ /SECURECOOL_NEXTACTION_INPUT_TAG/)
+ {
+ if ($nextPage)
+ {
+ print "<input type=\"hidden\" name=\"nextaction\" value=\"$nextPage\">\n";
+ print "<input type=\"hidden\" name=\"screenname\" value=\"$sn\">\n";
+ }
+
+ if ($sn)
+ {
+ print "<script>document.getElementById('screenname').value = \"$sn\"</script>\n";
+ }
+ }
+ elsif ($l =~ /<!-- *SECURECOOL_SCREENNAME *-->/)
+ {
+ $l =~ s/<!-- *SECURECOOL_SCREENNAME *-->/$sn/g;
+ print $l;
+ }
+ else
+ {
+ print $l;
+ }
+ }
+ close(SN_FILE);
+}
+
+sub GenerateTOSPage
+{
+ my ($nextPage) = @_;
+
+ my ($l);
+
+ ExitError("Failed to load TOS Page") if (!open(TOS_FILE, "< Subscribe.html"));
+
+ print $gQuery->header();
+
+ while ($l = <TOS_FILE>)
+ {
+ if ($l =~ /SECURECOOL_NEXTACTION_INPUT_TAG/)
+ {
+ if ($nextPage)
+ {
+ print "<input type=\"hidden\" name=\"nextaction\" value=\"$nextPage\">\n";
+ print "<input type=\"hidden\" name=\"screenname\" value=\"". GetScreenName() ."\">\n";
+ }
+ }
+ elsif ($l =~ /<!-- *SECURECOOL_SCREENNAME *-->/)
+ {
+ my $sn = GetScreenName();
+ $l =~ s/<!-- *SECURECOOL_SCREENNAME *-->/$sn/g;
+ print $l;
+ }
+ else
+ {
+ print $l;
+ }
+ }
+ close(TOS_FILE);
+}
+
+sub GenerateSettingsPage
+{
+ my ($l);
+
+ ExitError("Failed to load settings page!") if (!open(SETTINGS_FILE, "< SettingsEsc.html"));
+
+ print $gQuery->header();
+
+ while ($l = <SETTINGS_FILE>)
+ {
+ if ($l =~ /SECURECOOL_BINDINGS_ARRAY/)
+ {
+ my(@curBindings) = GetBindings();
+ my $arrSize = scalar(@curBindings);
+ my($i);
+
+ for ($i = 0; $i < $arrSize; $i++)
+ {
+ my($keyType, $keyId, $keyLabel) = split(/&/, $curBindings[$i]);
+ print " [ $keyType, \"$keyId\", \"$keyLabel\" ]";
+ print "," if ($arrSize > 1 && $i != $arrSize - 1);
+ print "\n";
+ }
+ }
+ elsif ($l =~ /<!-- *SECURECOOL_SCREENNAME *-->/)
+ {
+ my $sn = GetScreenName();
+ $l =~ s/<!-- *SECURECOOL_SCREENNAME *-->/$sn/g;
+ print $l;
+ }
+ else
+ {
+ print $l;
+ }
+ }
+ close(SETTINGS_FILE);
+}
+
+sub GenerateSetLabelPage
+{
+ my ($l);
+
+ ExitError("Failed to open label page!") if (!open(LABEL_PAGE, "< Label.html"));
+
+ my $sn = GetScreenName();
+ ExitError("Failed to get a valid screen name!") if (! $sn);
+
+ my $keyType = GetKeyType();
+ my $keyID = GetKeyID();
+ ExitError("Failed to get a valid keyID!") if (! $keyID);
+
+ $defLabel = $keyID;
+ $defLabel =~ s/^[0-9a-fA-F]{12}//;
+ $defLabel = "$sn-$defLabel";
+
+ print $gQuery->header();
+
+ while ($l = <LABEL_PAGE>)
+ {
+ if ($l =~ /<!-- *SECURECOOL_SCREENNAME *-->/)
+ {
+ $l =~ s/<!-- *SECURECOOL_SCREENNAME *-->/$sn/g;
+ }
+ if ($l =~ /<!-- *SECURECOOL_KEYTYPE *-->/)
+ {
+ $l =~ s/<!-- *SECURECOOL_KEYTYPE *-->/$keyType/g;
+ }
+ if ($l =~ /<!-- *SECURECOOL_KEYID *-->/)
+ {
+ $l =~ s/<!-- *SECURECOOL_KEYID *-->/$keyID/g;
+ }
+ if ($l =~ /<!-- *SECURECOOL_KEYLABEL *-->/)
+ {
+ $l =~ s/<!-- *SECURECOOL_KEYLABEL *-->/$defLabel/g;
+ }
+ print $l;
+ }
+ close(LABEL_FILE);
+}
+
+sub GenerateBindProgressPage
+{
+ my ($action) = @_;
+ my ($l);
+
+ ExitError("Failed to open progress page!") if (!open(PROG_PAGE, "< Progress.html"));
+
+ my $sn = GetScreenName();
+ ExitError("Failed to get a valid screen name!") if (! $sn);
+
+ my $keyType = GetKeyType();
+ my $keyID = GetKeyID();
+ ExitError("Failed to get a valid keyID!") if (! $keyID);
+
+ my $keyLabel = "";
+
+ if ($action eq "bind")
+ {
+ $keyLabel = GetKeyLabelArg();
+ ExitError("Failed to get a valid keyLabel!") if (! $keyLabel);
+ }
+
+ print $gQuery->header();
+
+ while ($l = <PROG_PAGE>)
+ {
+ if ($l =~ /<!-- *SECURECOOL_SCREENNAME *-->/)
+ {
+ $l =~ s/<!-- *SECURECOOL_SCREENNAME *-->/$sn/g;
+ }
+ if ($l =~ /<!-- *SECURECOOL_KEYTYPE *-->/)
+ {
+ $l =~ s/<!-- *SECURECOOL_KEYTYPE *-->/$keyType/g;
+ }
+ if ($l =~ /<!-- *SECURECOOL_KEYID *-->/)
+ {
+ $l =~ s/<!-- *SECURECOOL_KEYID *-->/$keyID/g;
+ }
+ if ($l =~ /<!-- *SECURECOOL_KEYLABEL *-->/)
+ {
+ $l =~ s/<!-- *SECURECOOL_KEYLABEL *-->/$keyLabel/g;
+ }
+ if ($l =~ /<!-- *SECURECOOL_ACTION *-->/)
+ {
+ $l =~ s/<!-- *SECURECOOL_ACTION *-->/$action/g;
+ }
+ if ($l =~ /<!-- *SECURECOOL_CHALLENGEDATA *-->/)
+ {
+ $challengeData = "";
+ $challengeData = "QVNDIHJvY2tzIHRoZSBwYXJ0eSE=" if ($action eq "bind");
+
+ $l =~ s/<!-- *SECURECOOL_CHALLENGEDATA *-->/$challengeData/g;
+ }
+ print $l;
+ }
+ close(PROG_PAGE);
+}
+
+sub GenerateBindSuccessPage
+{
+ my ($action) = @_;
+ my ($l);
+
+ ExitError("Failed to open progress page!") if (!open(SUCCESS_PAGE, "< BindSuccess.html"));
+
+ my $sn = GetScreenName();
+ ExitError("Failed to get a valid screen name!") if (! $sn);
+
+ my $keyType = GetKeyType();
+ my $keyID = GetKeyID();
+ ExitError("Failed to get a valid keyID!") if (! $keyID);
+
+ my $keyLabel = "";
+
+ if ($action eq "bind")
+ {
+ $keyLabel = GetKeyLabelArg();
+ ExitError("Failed to get a valid keyLabel!") if (! $keyLabel);
+ }
+
+ print $gQuery->header();
+
+ while ($l = <SUCCESS_PAGE>)
+ {
+ if ($l =~ /<!-- *SECURECOOL_SCREENNAME *-->/)
+ {
+ $l =~ s/<!-- *SECURECOOL_SCREENNAME *-->/$sn/g;
+ }
+ if ($l =~ /<!-- *SECURECOOL_KEYTYPE *-->/)
+ {
+ $l =~ s/<!-- *SECURECOOL_KEYTYPE *-->/$keyType/g;
+ }
+ if ($l =~ /<!-- *SECURECOOL_KEYID *-->/)
+ {
+ $l =~ s/<!-- *SECURECOOL_KEYID *-->/$keyID/g;
+ }
+ if ($l =~ /<!-- *SECURECOOL_KEYLABEL *-->/)
+ {
+ $l =~ s/<!-- *SECURECOOL_KEYLABEL *-->/$keyLabel/g;
+ }
+ if ($l =~ /<!-- *SECURECOOL_ACTION *-->/)
+ {
+ $l =~ s/<!-- *SECURECOOL_ACTION *-->/$action/g;
+ }
+ print $l;
+ }
+ close(SUCCESS_PAGE);
+}
+
+sub GenerateBindingConfigPage
+{
+ my ($l);
+
+ ExitError("Failed to load binding page!") if (!open(BINDING_FILE, "< Bindings.html"));
+
+ print $gQuery->header();
+
+ while ($l = <BINDING_FILE>)
+ {
+ if ($l =~ /SECURECOOL_BINDINGS_ARRAY/)
+ {
+ my(@curBindings) = GetBindings();
+ my $arrSize = scalar(@curBindings);
+ my($i);
+
+ for ($i = 0; $i < $arrSize; $i++)
+ {
+ my($keyType, $keyId, $keyLabel) = split(/&/, $curBindings[$i]);
+ print " [ $keyType, \"$keyId\", \"$keyLabel\" ]";
+ print "," if ($arrSize > 1 && $i != $arrSize - 1);
+ print "\n";
+ }
+ }
+ elsif ($l =~ /<!-- *SECURECOOL_SCREENNAME *-->/)
+ {
+ my $sn = GetScreenName();
+ $l =~ s/<!-- *SECURECOOL_SCREENNAME *-->/$sn/g;
+ print $l;
+ }
+ else
+ {
+ print $l;
+ }
+ }
+ close(BINDING_FILE);
+}
+
+sub GetKeyLabel
+{
+ my($keyType, $keyId) = @_;
+
+ my(@curBindings) = GetBindings();
+ my($numBindings) = scalar(@curBindings);
+
+ while($numBindings > 0)
+ {
+ --$numBindings;
+ if ($curBindings[$numBindings] =~ /^$keyType&$keyId&/)
+ {
+ my($ktype, $id, $lbl) = split(/&/, $curBindings[$numBindings]);
+ return $lbl;
+ }
+ }
+
+ return "";
+}
+
+sub GenerateLabelPage
+{
+ my($keyType, $keyId, $nextAction) = @_;
+ my($keyLabel) = GetKeyLabel($keyType, $keyId);
+
+ return if ($keyLabel eq "");
+
+ my ($l);
+
+ ExitError("Failed to load label page!") if (!open(EDIT_LABEL_FILE, "< EditLabel.html"));
+
+ print $gQuery->header();
+
+ while ($l = <EDIT_LABEL_FILE>)
+ {
+ if ($l =~ /SECURECOOL_NEXTACTION_INPUT_TAG/)
+ {
+ print "<input type=\"hidden\" name=\"nextaction\" value=\"$nextAction\">\n";
+ print "<input type=\"hidden\" name=\"keytype\" value=\"$keyType\">\n";
+ print "<input type=\"hidden\" name=\"keyid\" value=\"$keyId\">\n";
+ print "<input type=\"hidden\" name=\"keylabel\" value=\"$keyLabel\">\n";
+ print "<input type=\"hidden\" name=\"screenname\" value=\"".GetScreenName()."\">\n";
+ }
+ elsif ($l =~ /<!-- *SECURECOOL_SCREENNAME *-->/)
+ {
+ my $sn = GetScreenName();
+ $l =~ s/<!-- *SECURECOOL_SCREENNAME *-->/$sn/g;
+ print $l;
+ }
+ else
+ {
+ print $l;
+ }
+ }
+ close(EDIT_LABEL_FILE);
+}
+
+sub GenerateAutoEnrollmentPage
+{
+ my ($l);
+
+ ExitError("Failed to load enrollment page!") if (!open(ENROLL_FILE, "< EnrollPopup.html"));
+
+ print $gQuery->header();
+
+ while ($l = <ENROLL_FILE>)
+ {
+ print $l;
+ }
+
+ close(ENROLL_FILE);
+}
+sub GenerateAuthenticationPage
+{
+ my ($l);
+ ExitError("Failed to load enrollment page!") if (!open(AUTH_FILE, "< GenericAuth.html"));
+
+ print $gQuery->header();
+
+ while ($l = <AUTH_FILE>)
+ {
+ if ($l =~ /<!-- *SECURECOOL_SCREENNAME *-->/)
+ {
+ my $sn = GetScreenName();
+ $l =~ s/<!-- *SECURECOOL_SCREENNAME *-->/$sn/g;
+ print $l;
+ }
+ else
+ {
+ print $l;
+ }
+ }
+
+ close(AUTH_FILE);
+}
+
+sub GenerateEnrollmentPage
+{
+ my ($l);
+
+ ExitError("Failed to load enrollment page!") if (!open(ENROLL_FILE, "< EnrollPopup.html"));
+
+ print $gQuery->header();
+
+ while ($l = <ENROLL_FILE>)
+ {
+ if ($l =~ /<!-- *SECURECOOL_SCREENNAME *-->/)
+ {
+ my $sn = GetScreenName();
+ $l =~ s/<!-- *SECURECOOL_SCREENNAME *-->/$sn/g;
+ print $l;
+ }
+ else
+ {
+ print $l;
+ }
+ }
+
+ close(ENROLL_FILE);
+}
+
+sub GenerateAdvancePage
+{
+ my ($l);
+
+ ExitError("Failed to load enrollment page!") if (!open(ENROLL_FILE, "< AdvancePopup.html"));
+
+ print $gQuery->header();
+
+ while ($l = <ENROLL_FILE>)
+ {
+ if ($l =~ /<!-- *SECURECOOL_SCREENNAME *-->/)
+ {
+ my $sn = GetScreenName();
+ $l =~ s/<!-- *SECURECOOL_SCREENNAME *-->/$sn/g;
+ print $l;
+ }
+ else
+ {
+ print $l;
+ }
+ }
+
+ close(ENROLL_FILE);
+}
+
+sub GenerateTokenManagerPage
+{
+ my ($l);
+
+ ExitError("Failed to load enrollment page!") if (!open(ENROLL_FILE, "< TokenManager.html"));
+
+ print $gQuery->header();
+
+ while ($l = <ENROLL_FILE>)
+ {
+ if ($l =~ /<!-- *SECURECOOL_SCREENNAME *-->/)
+ {
+ my $sn = GetScreenName();
+ $l =~ s/<!-- *SECURECOOL_SCREENNAME *-->/$sn/g;
+ print $l;
+ }
+ else
+ {
+ print $l;
+ }
+ }
+
+ close(ENROLL_FILE);
+}
+
+sub GenerateTicketRequestPage
+{
+ my ($l);
+
+ ExitError("Failed to load ticket request page!") if (!open(TICKETREQ_FILE, "< Ticket.html"));
+
+ print $gQuery->header();
+
+ while ($l = <TICKETREQ_FILE>)
+ {
+ if ($l =~ /<!-- *SECURECOOL_SCREENNAME *-->/)
+ {
+ my $sn = GetScreenName();
+ $l =~ s/<!-- *SECURECOOL_SCREENNAME *-->/$sn/g;
+ print $l;
+ }
+ else
+ {
+ print $l;
+ }
+ }
+
+ close(TICKETREQ_FILE);
+}
+
+sub GenerateLoadURLPage
+{
+ my ($l);
+
+ ExitError("Failed to load url request page!") if (!open(LOADURL_FILE, "< LoadURL.html"));
+
+ print $gQuery->header();
+
+ while ($l = <LOADURL_FILE>)
+ {
+ if ($l =~ /<!-- *SECURECOOL_SCREENNAME *-->/)
+ {
+ my $sn = GetScreenName();
+ $l =~ s/<!-- *SECURECOOL_SCREENNAME *-->/$sn/g;
+ print $l;
+ }
+ else
+ {
+ print $l;
+ }
+ }
+
+ close(LOADURL_FILE);
+}
+
+sub CreateExpiredCookie
+{
+ my($cookieName) = @_;
+ my $cookie = $gQuery->cookie(-name=>$cookieName,
+ -value=>'',
+ -expires=>'-2d',
+ -path=>$gQuery->url(-absolute=>1),
+ -domain=>$gQuery->server_name());
+ return $cookie;
+
+}
+
+sub SaveSubscription
+{
+
+ $gUserObj{'SUBSCRIPTION'} = $gQuery->param("subscriptiontype");
+ SaveUserDatabase(GetScreenName());
+}
+
+sub GetBindings
+{
+ my $bindings = $gUserObj{'BINDINGS'};
+ return @$bindings;
+}
+
+sub BindingsArrayToString
+{
+ my(@bindings) = @_;
+ my $i;
+ my $str = "";
+
+ for ($i = 0; $i < @bindings; $i++)
+ {
+ if ($bindings[$i] ne "")
+ {
+ $str .= "&" if ($str ne "");
+ $str .= ASCUrlEncode($bindings[$i]);
+ }
+ }
+
+ return $str;
+}
+
+sub AddItemToBindings
+{
+ my($keyType, $keyId, $keyLabel) = @_;
+
+ my(@curBindings) = GetBindings();
+ my($pos) = scalar(@curBindings);
+
+ # First check to see if the key already exists in
+ # the cookie! If it does, we'll just overwrite it.
+
+ my($i) = $pos;
+ while($i > 0)
+ {
+ --$i;
+ if ($curBindings[$i] =~ /^$keyType&$keyId&/)
+ {
+ $pos = $i;
+ last;
+ }
+ }
+
+ $curBindings[$pos] = "$keyType&$keyId&$keyLabel";
+
+ $gUserObj{'BINDINGS'} = \@curBindings;
+ #SaveUserDatabase(GetScreenName());
+}
+
+sub RemoveItemFromBindings
+{
+ my($keyType, $keyId) = @_;
+
+ my(@curBindings) = GetBindings();
+ my($numBindings) = scalar(@curBindings);
+ my @newBindings;
+
+ while($numBindings > 0)
+ {
+ --$numBindings;
+ next if ($curBindings[$numBindings] =~ /^$keyType&$keyId&/);
+ push @newBindings, $curBindings[$numBindings];
+ }
+
+ $gUserObj{'BINDINGS'} = \@newBindings;
+ #SaveUserDatabase(GetScreenName());
+}
+
+sub UpdateBindingsForBind
+{
+ return if (! defined $gQuery->param("keytype"));
+ my($keyType) = $gQuery->param("keytype");
+
+ return if (! defined $gQuery->param("keyid"));
+ my($keyId) = $gQuery->param("keyid");
+
+ return if (! defined $gQuery->param("keylabel"));
+ my($keyLabel) = $gQuery->param("keylabel");
+
+ return AddItemToBindings($keyType, $keyId, $keyLabel);
+}
+
+sub UpdateBindingsForUnbind
+{
+ return if (! defined $gQuery->param("keytype"));
+ my($keyType) = $gQuery->param("keytype");
+
+ return if (! defined $gQuery->param("keyid"));
+ my($keyId) = $gQuery->param("keyid");
+
+ return RemoveItemFromBindings($keyType, $keyId,);
+}
+
+sub UpdateBindingsForLabel
+{
+ return UpdateBindingsForBind();
+}
+
+sub ASCUrlDecode
+{
+ my($qstr) = @_;
+ $qstr =~ s/\+/ /g;
+ $qstr =~ s/%([0-9A-F]{2})/pack("C", hex($1))/eig;
+ return $qstr;
+}
+
+sub ASCUrlEncode
+{
+ my($qstr) = @_;
+ $qstr =~ s/([^a-zA-Z0-9_ ])/sprintf("%%%.2X", unpack("C", $1))/eig;
+ $qstr =~ s/ /+/g;
+ return $qstr;
+}
+
+sub LoadUserDatabase
+{
+ my($sn) = @_;
+
+ $gUserObj{'SUBSCRIPTION'} = "";
+
+ $gUserObj{'BINDINGS'} = "";
+ return;
+
+}
+
+sub SaveUserDatabase
+{
+ my($sn) = @_;
+ my($snfile) = "UserDatabase/$sn";
+
+ return;
+
+}
diff --git a/base/tps/forms/esc/home.cgi b/base/tps/forms/esc/home.cgi
new file mode 100755
index 000000000..5fdf5ecf8
--- /dev/null
+++ b/base/tps/forms/esc/home.cgi
@@ -0,0 +1,40 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+#
+#
+#
+print "Content-type: text/xml\n\n";
+print "<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>";
+print "<ServiceInfo>";
+print "<IssuerName>";
+print "Fedora Project"; # Vendor
+print "</IssuerName>\n";
+print "<Services>";
+print "<Operation>";
+print "http://machine.fedora.redhat.com:7888/nk_service";
+print "</Operation>";
+print "<UI>";
+print "http://machine.fedora.redhat.com:7888/cgi-bin/esc.cgi";
+print "</UI>";
+print "</Services>";
+print "</ServiceInfo>";
diff --git a/base/tps/forms/index.cgi b/base/tps/forms/index.cgi
new file mode 100755
index 000000000..0e643166b
--- /dev/null
+++ b/base/tps/forms/index.cgi
@@ -0,0 +1,76 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package op;
+
+use lib $ENV{DOCUMENT_ROOT} . "/../lib/perl";
+
+use CGI;
+use PKI::Service::Op;
+use Template::Velocity;
+use PKI::Base::Conf;
+use PKI::Base::Registry;
+
+use vars qw (@ISA);
+use PKI::Service::Op;
+@ISA = qw(PKI::Service::Op);
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub process()
+{
+ my $self = shift;
+
+ my $q = CGI->new();
+
+ my $docroot = PKI::Base::Registry->get_docroot();
+ my $parser = PKI::Base::Registry->get_parser();
+ my $cfg = PKI::Base::Registry->get_config();
+
+ $self->debug_params($cfg, $q);
+
+ $::symbol{machineName} = $cfg->get("service.machineName");
+ $::symbol{non_clientauth_securePort} = $cfg->get("service.non_clientauth_securePort");
+ $::symbol{securePort} = $cfg->get("service.securePort");
+ $::symbol{unsecurePort} = $cfg->get("service.unsecurePort");
+
+ my $result = $parser->execute_file("index.vm");
+
+ my $xml = $q->param('xml');
+ if ($xml eq "true") {
+ print "Content-Type: text/xml\n\n";
+ print $self->xml_output(\%::symbol);
+ } else {
+ print "Content-Type: text/html\n\n";
+ print "$result";
+ }
+}
+
+
+my $op = op->new();
+$op->execute();
diff --git a/base/tps/forms/index.html b/base/tps/forms/index.html
new file mode 100644
index 000000000..b225251a1
--- /dev/null
+++ b/base/tps/forms/index.html
@@ -0,0 +1,22 @@
+<!-- --- BEGIN COPYRIGHT BLOCK ---
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation;
+ version 2.1 of the License.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; 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 --- -->
+<html>
+<META HTTP-EQUIV="Refresh" CONTENT="0; URL=/index.cgi">
+</html>
diff --git a/base/tps/lib/perl/PKI/Base/Conf.pm b/base/tps/lib/perl/PKI/Base/Conf.pm
new file mode 100755
index 000000000..895ab28a3
--- /dev/null
+++ b/base/tps/lib/perl/PKI/Base/Conf.pm
@@ -0,0 +1,130 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+
+package PKI::Base::Conf;
+
+use strict;
+use warnings;
+use Exporter;
+
+$PKI::Base::Conf::VERSION = '1.00';
+
+#######################################################
+# Configuration Store
+#######################################################
+sub new {
+ my $class = shift;
+ my $self = {};
+ my %hash = ();
+ $self->{filename} = "";
+ $self->{hash} = \%hash;
+ bless $self,$class;
+ return $self;
+}
+
+sub load_file
+{
+ my ($self, $filename) = @_;
+
+ $self->{filename} = $filename;
+ if (-e $filename) {
+ open(CF, "<$filename");
+ if (defined fileno CF) {
+ while (<CF>) {
+ if (/^#/) {
+ # comments
+ } elsif (/([^=]+)=(.*)$/) {
+ # print "$1 = $2\n";
+ $self->{hash}{$1} = $2;
+ } else {
+ # preserve comments
+ }
+ }
+ }
+ close(CF);
+ }
+}
+
+sub get_filename
+{
+ my ($self) = @_;
+ return $self->{filename};
+}
+
+sub get
+{
+ my ($self, $n) = @_;
+ return $self->{hash}{$n};
+}
+
+sub put
+{
+ my ($self, $n, $v) = @_;
+ $self->{hash}{$n} = $v;
+}
+
+sub commit
+{
+ my ($self) = @_;
+
+ # write stuff back to the file
+# print $self->{filename} . "\n";
+ my $hash = $self->{hash};
+ my $suffix = time();
+
+ if (-e $self->{filename}) {
+ system("mv \"" . $self->{filename} . "\" \"" .
+ $self->{filename} . "." . $suffix . "\"");
+ }
+
+ open(F, ">" . $self->{filename});
+ foreach my $k (sort keys %{$hash}) {
+ print F "$k=$self->{hash}{$k}\n";
+ }
+ close(F);
+
+ if (-e $self->{filename} . "." . $suffix) {
+ system("rm \"" . $self->{filename} . "." . $suffix . "\"");
+ }
+}
+
+sub commit_with_backup
+{
+ my ($self) = @_;
+
+ # write stuff back to the file
+# print $self->{filename} . "\n";
+ my $hash = $self->{hash};
+ my $suffix = time();
+ system("mv \"" . $self->{filename} . "\" \"" .
+ $self->{filename} . "." . $suffix . "\"");
+
+ open(F, ">" . $self->{filename});
+ foreach my $k (sort keys %{$hash}) {
+ print F "$k=$self->{hash}{$k}\n";
+ }
+ close(F);
+}
+
+1;
diff --git a/base/tps/lib/perl/PKI/Base/Registry.pm b/base/tps/lib/perl/PKI/Base/Registry.pm
new file mode 100755
index 000000000..a4fb83f28
--- /dev/null
+++ b/base/tps/lib/perl/PKI/Base/Registry.pm
@@ -0,0 +1,55 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public 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 ---
+#
+#
+#
+#
+package PKI::Base::Registry;
+
+use PKI::Base::Conf;
+
+my $docroot;
+my $cfg;
+my $parser;
+
+BEGIN {
+ $docroot = $ENV{DOCUMENT_ROOT};
+ $cfg = PKI::Base::Conf->new();
+ $cfg->load_file("$docroot/../conf/CS.cfg");
+ $parser = new Template::Velocity($docroot);
+
+}
+
+sub get_docroot {
+ my ($self) = @_;
+ return $docroot;
+}
+
+sub get_parser {
+ my ($self) = @_;
+ return $parser;
+}
+
+sub get_config {
+ my ($self) = @_;
+ return $cfg;
+}
+
+1;
diff --git a/base/tps/lib/perl/PKI/Service/Op.pm b/base/tps/lib/perl/PKI/Service/Op.pm
new file mode 100755
index 000000000..9e2a63d4f
--- /dev/null
+++ b/base/tps/lib/perl/PKI/Service/Op.pm
@@ -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.
+#
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+#
+#
+#
+
+package PKI::Service::Op;
+
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+sub debug_log()
+{
+ my ($self, $cfg, $msg) = @_;
+
+ my $date = `date`;
+ chomp($date);
+ open(DEBUG, ">>" . $cfg->get("logging.debug.filename"));
+ print DEBUG "$date - $msg\n";
+ close(DEBUG);
+}
+
+sub debug_params()
+{
+ my ($self, $cfg, $q) = @_;
+
+ my $date = `date`;
+ chomp($date);
+ $self->debug_log($cfg, "$date - URL '" . $ENV{REQUEST_URI} . "'");
+ my @names = $q->param();
+ foreach my $k (@names) {
+ $self->debug_log($cfg, "$date - Param $k='" . $q->param($k) . "'");
+ }
+}
+
+sub process {
+ my ($self) = @_;
+}
+
+sub escape_xml
+{
+ my ($v) = @_;
+ $v =~ s/\"/&quot;/g;
+ $v =~ s/\'/&apos;/g;
+ $v =~ s/\&/&amp;/g;
+ $v =~ s/</&lt;/g;
+ $v =~ s/>/&gt;/g;
+ return $v;
+}
+
+sub get_xml
+{
+ my ($s, $v) = @_;
+
+ my $result;
+ if (ref($v) eq "HASH") {
+ foreach my $xkey (keys %$v) {
+ $result .= "<" . $xkey . ">";
+ $result .= &get_xml($xkey, $v{$xkey});
+ # $result .= "-" . ref($xkey);
+ $result .= "</" . $xkey . ">";
+ }
+ } elsif (ref($v) eq "PKI::RA::GlobalVar") {
+ foreach my $xkey (keys %$v) {
+ $result .= "<" . $xkey . ">";
+ $result .= &get_xml($xkey, $$v{$xkey}->());
+ # $result .= "-" . ref($xkey);
+ $result .= "</" . $xkey . ">";
+ }
+ } elsif (ref($v) eq "ARRAY") {
+ my $pos = 0;
+ foreach my $item (@$v) {
+ $result .= "<element>";
+ $result .= &get_xml("p" . $pos, $item);
+ # $result .= "-" . ref($item);
+ $result .= "</element>";
+ $pos++;
+ }
+ } else {
+ $result .= &escape_xml($v);
+ }
+ return $result;
+}
+
+sub xml_output {
+ my ($self, $c) = @_;
+
+ my $result = "<xml>";
+ foreach $s (sort keys %$c) {
+ if ($s =~ /^__/) {
+ next;
+ }
+ $result .= "<" . $s . ">";
+ my $v = $$c{$s};
+ $result .= &get_xml($s, $v);
+ $result .= "</" . $s . ">";
+ }
+ $result .= "</xml>";
+ return "$result\n";
+}
+
+sub execute {
+ my ($self) = @_;
+ $self->process();
+}
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/AdminAuthPanel.pm b/base/tps/lib/perl/PKI/TPS/AdminAuthPanel.pm
new file mode 100755
index 000000000..caaf6c65f
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/AdminAuthPanel.pm
@@ -0,0 +1,93 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+
+package PKI::TPS::AdminAuthPanel;
+$PKI::TPS::AdminAuthPanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(8);
+ $self->{"getName"} = &PKI::TPS::Common::r("Admin Authentication");
+ $self->{"vmfile"} = "adminauthenticatepanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("AdminAuthPanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("AdminAuthPanel: update");
+ $::config->put("preop.adminauth.done", "true");
+ $::config->commit();
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("AdminAuthPanel: display");
+ return 1;
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.adminauth.done");
+}
+
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/AdminPanel.pm b/base/tps/lib/perl/PKI/TPS/AdminPanel.pm
new file mode 100755
index 000000000..d62d611be
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/AdminPanel.pm
@@ -0,0 +1,234 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+use URI::URL;
+use URI::Escape;
+use Mozilla::LDAP::Conn;
+
+package PKI::TPS::AdminPanel;
+$PKI::TPS::AdminPanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(14);
+ $self->{"getName"} = &PKI::TPS::Common::r("Administrator");
+ $self->{"vmfile"} = "adminpanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("AdminPanel: validate");
+ return 1;
+}
+
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("AdminPanel: update");
+
+ my $uid = $q->param("uid");
+ my $name = $q->param("name");
+ my $email = $q->param("email");
+ my $password = $q->param("__pwd");
+ my $password_again = $q->param("__admin_password_again");
+
+ my $cert_request = $q->param("cert_request");
+ my $subject = $q->param("subject");
+ my $profile_id = $q->param("profileId");
+ my $cert_request_type = $q->param("cert_request_type");
+
+ $cert_request =~ s/%0D%0A//g; # remove carraige return
+
+ # submit request to CA
+
+ # Admin Certificate should be obtained from the ca selected in the
+ # name panel. If name panel use External CA, the admin certificate
+ # will be issued by the security domain CA.
+ my $cainfo = $::config->get("preop.ca.url");
+ &PKI::TPS::Wizard::debug_log("AdminPanel: preop.ca.url=$cainfo");
+ if ($cainfo eq "" || $cainfo =~ /:$/) {
+ $cainfo = $::config->get("config.sdomainEEURL");
+ &PKI::TPS::Wizard::debug_log("AdminPanel: config.sdomainEEURL=$cainfo");
+ }
+ &PKI::TPS::Wizard::debug_log("AdminPanel: Connecting to CA: $cainfo");
+ my $cainfo_url = new URI::URL($cainfo);
+ my $sdom = $::config->get("config.sdomainEEURL");
+ my $sdom_url = new URI::URL($sdom);
+
+ my $machineName = $::config->get("service.machineName");
+ my $securePort = $::config->get("service.securePort");
+ my $session_id = $::config->get("preop.sessionID");
+
+ my $tokenname = $::config->get("preop.module.token");
+ my $token_pwd = $::pwdconf->get($tokenname);
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+ my $instanceID = $::config->get("service.instanceID");
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $certdir = "$instanceDir/alias";
+
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $db_password =~ s/\n$//g;
+
+ my $requestor_name = "TPS-" . $machineName . "-" . $securePort;
+
+ my $params = "profileId=" . $profile_id . "&" .
+ "requestor_name=" . $requestor_name . "&" .
+ "cert_request_type=" . $cert_request_type . "&" .
+ "subject=" . $subject . "&" .
+ "cert_request=" .
+ URI::Escape::uri_escape("$cert_request") . "&" .
+ "xmlOutput=true" . "&" .
+ "sessionID=" . $session_id . "&" .
+ "auth_hostname=" . $sdom_url->host . "&" .
+ "auth_port=" . $sdom_url->port;
+
+ my $ca_host = $cainfo_url->host;
+ my $https_ee_port = $cainfo_url->port;
+ my $content = "";
+ my $tmpfile = "/tmp/admin-$$";
+ if (($tokenname eq "") || ($tokenname eq "NSS Certificate DB")) {
+ system("/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"$db_password\" -v -n \"$nickname\" -r \"/ca/ee/ca/profileSubmit\" $ca_host:$https_ee_port > $tmpfile");
+ $content = `cat $tmpfile`;
+ } else {
+ system("/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"$token_pwd\" -v -n \"$nickname\" -r \"/ca/ee/ca/profileSubmit\" $ca_host:$https_ee_port > $tmpfile");
+ $content = `cat $tmpfile`;
+ }
+ system("rm $tmpfile");
+ &PKI::TPS::Wizard::debug_log("req = " . $content);
+
+ $content =~ /(\<XMLResponse\>.*\<\/XMLResponse\>)/;
+ $content = $1;
+
+ # create user in internal database
+ &PKI::TPS::Wizard::debug_log("AdminPanel: Creating user in internal database");
+ # use scripts/addAgents.ldif
+
+ my $parser = XML::Simple->new();
+ my $response = $parser->XMLin($content);
+ my $admincert = $response->{Requests}->{Request}->{b64};
+ &PKI::TPS::Wizard::debug_log("AdminPanel: admincert " . $admincert);
+
+ my $hostport = $::config->get("auth.instance.1.hostport");
+ my ($ldap_host, $ldap_port) = split(/:/, $hostport);
+ my $secureconn = $::config->get("auth.instance.1.ssl");
+ my $basedn = $::config->get("preop.database.basedn");
+ my $binddn = $::config->get("preop.database.binddn");
+# my $bindpwd = $::config->get("tokendb.bindPass");
+ my $bindpwd = `grep \"tokendbBindPass:\" \"$instanceDir/conf/password.conf\" | cut -c17-`;
+ $bindpwd =~ s/\n$//g;
+
+ my $tmp = "/tmp/addAgents-$$.ldif";
+
+ my $flavor = "pki";
+ $flavor =~ s/\n//g;
+
+ my $conn = PKI::TPS::Common::make_connection(
+ {host => $ldap_host, port => $ldap_port, pswd => $bindpwd, bind => $binddn, cert => $certdir},
+ $secureconn);
+
+ if (!$conn) {
+ &PKI::TPS::Wizard::debug_log("AdminPanel: Failed to connect to the internal database");
+ $::symbol{errorString} = "Failed to connect to the internal database";
+ return 0;
+ };
+
+ my $msg;
+ $admincert =~ s/\//\\\//g;
+ system("sed -e 's/\$TOKENDB_ROOT/$basedn/' " .
+ "-e 's/\$TOKENDB_AGENT_PWD/$password/' " .
+ "-e 's/\$TOKENDB_AGENT_CERT/$admincert/' " .
+ "/usr/share/$flavor/tps/scripts/addAgents.ldif > $tmp");
+ if (! &PKI::TPS::Common::import_ldif($conn, $tmp, \$msg)) {
+ &PKI::TPS::Wizard::debug_log("AdminPanel: $msg");
+ $::symbol{errorString} = "Failed to add agents to database";
+ $conn->close();
+ return 0;
+ };
+ if ($msg ne "") {
+ &PKI::TPS::Wizard::debug_log("AdminPanel: adding agents errors : $msg");
+ }
+ system("rm $tmp");
+
+ my $reqid = $response->{Requests}->{Request}->{Id};
+ $::config->put("preop.admincert.requestId.0", $reqid);
+ my $sn = $response->{Requests}->{Request}->{serialno};
+ $::config->put("preop.admincert.serialno.0", $sn);
+ $::config->put("preop.adminpanel.done", "true");
+ $::config->commit();
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("AdminPanel: display");
+ $::symbol{admin_uid} = "admin";
+ $::symbol{admin_name} = "TPS Administrator";
+ $::symbol{admin_email} = "";
+ $::symbol{admin_pwd} = "";
+ $::symbol{admin_pwd_again} = "";
+ $::symbol{import} = "true";
+ my $domain_name = $::config->get("preop.securitydomain.name");
+ $::symbol{securityDomain} = $domain_name;
+
+ return 1;
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.adminpanel.done");
+}
+
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/AgentAuthPanel.pm b/base/tps/lib/perl/PKI/TPS/AgentAuthPanel.pm
new file mode 100755
index 000000000..a5130caa1
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/AgentAuthPanel.pm
@@ -0,0 +1,91 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+
+package PKI::TPS::AgentAuthPanel;
+$PKI::TPS::AgentAuthPanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(7);
+ $self->{"getName"} = &PKI::TPS::Common::r("Agent Authentication");
+ $self->{"vmfile"} = "agentauthenticatepanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("AgentAuthPanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("AgentAuthPanel: update");
+ $::config->put("preop.agentauth.done", "true");
+ $::config->commit();
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("AgentAuthPanel: display");
+ return 1;
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.agentauth.done");
+}
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/AuthDBPanel.pm b/base/tps/lib/perl/PKI/TPS/AuthDBPanel.pm
new file mode 100755
index 000000000..2b189cd0c
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/AuthDBPanel.pm
@@ -0,0 +1,172 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+use Mozilla::LDAP::Conn;
+
+package PKI::TPS::AuthDBPanel;
+$PKI::TPS::AuthDBPanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(7);
+ $self->{"getName"} = &PKI::TPS::Common::r("Authentication Directory");
+ $self->{"vmfile"} = "authdbpanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("AuthDBPanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("AuthDBPanel: update");
+
+ my $host = $q->param('host');
+ my $port = $q->param('port');
+ my $basedn = $q->param('basedn');
+ my $secureconn = $q->param('secureConn') || "false";
+ my $instDir = $::config->get("service.instanceDir");
+ my $certdir = "$instDir/alias";
+
+ &PKI::TPS::Wizard::debug_log("AuthDBPanel: host=" . $host);
+ &PKI::TPS::Wizard::debug_log("AuthDBPanel: port=" . $port);
+ &PKI::TPS::Wizard::debug_log("AuthDBPanel: basedn=" . $basedn);
+ &PKI::TPS::Wizard::debug_log("AuthDBPanel: secureconn=" . $secureconn);
+
+ if (!($port =~ /^[0-9]+$/)) {
+ &PKI::TPS::Wizard::debug_log("AuthDBPanel: bad port " . $port);
+ $::symbol{errorString} = "Bad Port";
+ return 0;
+ }
+
+ # try to make a connection
+ # we need to test the ldaps connection first because testing an ldaps port with ldap:// will hang the query!
+ my $msg;
+
+ my $conn = &PKI::TPS::Common::test_and_make_connection({host => $host, port => $port, cert => $certdir}, $secureconn, \$msg);
+ if (! $conn) {
+ &PKI::TPS::Wizard::debug_log("AuthDBPanel: failed to connect to auth db: $msg");
+ $::symbol{errorString} = $msg;
+ return 0;
+ };
+
+ my $entry = $conn->search($basedn, "base", "objectclass=*", 0);
+ if (! $entry) {
+ &PKI::TPS::Wizard::debug_log("AuthDBPanel: search for basedn failed: " . $conn->getErrorString());
+ $::symbol{errorString} = "Search for base DN failed. Does the base DN exist?";
+ $conn->close();
+ return 0;
+ }
+
+ &PKI::TPS::Wizard::debug_log("AuthDBPanel: auth database looks ok");
+
+ $conn->close();
+
+ # save values to CS.cfg
+ $::config->put("auth.instance.0.baseDN", $basedn);
+ $::config->put("auth.instance.0.hostport", $host . ":" . $port);
+ $::config->put("auth.instance.0.ssl", $secureconn);
+ $::config->put("preop.authdb.done", "true");
+ $::config->commit();
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("AuthDBPanel: display");
+
+ my $machineName = $::config->get("service.machineName");
+ my $instanceId = $::config->get("service.instanceID");
+
+ my $basedn = $::config->get("auth.instance.0.baseDN");
+ if ($basedn =~ /\[/) {
+ $basedn = $machineName;
+ $basedn =~ s/^[^.]+\.//;
+ if ($basedn eq "") {
+ $basedn = "dc=" . $machineName;
+ } else {
+ $basedn =~ s/\./,dc=/g;
+ $basedn = "dc=" . $basedn;
+ }
+ }
+ my $host = "";
+ my $port = "";
+ my $hostport = $::config->get("auth.instance.0.hostport");
+ if ($hostport =~ /\[/) {
+ $host = "localhost";
+ $port = "389";
+ } else {
+ my ($hostx, $portx) = split(/:/, $hostport);
+ $host = $hostx;
+ $port = $portx;
+ }
+
+ my $secureconn = $::config->get("auth.instance.0.ssl") || "false";
+ $::symbol{hostname} = $host;
+ $::symbol{portStr} = $port;
+ $::symbol{basedn} = $basedn;
+ $::symbol{secureconn}=$secureconn;
+
+ return 1;
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.authdb.done");
+}
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/BasePanel.pm b/base/tps/lib/perl/PKI/TPS/BasePanel.pm
new file mode 100755
index 000000000..eecf99ff5
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/BasePanel.pm
@@ -0,0 +1,39 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+
+package PKI::TPS::BasePanel;
+$PKI::TPS::BasePanel::VERSION = '1.00';
+
+sub new {
+ my ($class) = @_;
+ my $self = {};
+ bless $self, $class;
+ return $self;
+}
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/CAInfoPanel.pm b/base/tps/lib/perl/PKI/TPS/CAInfoPanel.pm
new file mode 100755
index 000000000..27d0a0048
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/CAInfoPanel.pm
@@ -0,0 +1,315 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+use URI::URL;
+
+package PKI::TPS::CAInfoPanel;
+$PKI::TPS::CAInfoPanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+our $cert_header="-----BEGIN CERTIFICATE-----";
+our $cert_footer="-----END CERTIFICATE-----";
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(4);
+ $self->{"getName"} = &PKI::TPS::Common::r("CA Information");
+ $self->{"vmfile"} = "cainfopanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("CAInfoPanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("CAInfoPanel: update");
+
+ my $count = defined($q->param('urls')) ? $q->param('urls') : "";
+ if ($count eq "") {
+ $::symbol{errorString} = "No CA information provided. CA, TKS and optionally DRM must be installed prior to TPS installation";
+ return 0;
+ }
+ &PKI::TPS::Wizard::debug_log("CAInfoPanel: update - got urls = $count");
+
+ my $instanceID = $::config->get("service.instanceID");
+ my $host = "";
+ my $https_ee_port = "";
+ my $https_agent_port = "";
+ my $https_admin_port = "";
+ my $domain_xml = "";
+
+ if ($count =~ /http/) {
+ # this is for pkisilent
+ my $info = new URI::URL($count);
+ $host = defined($info->host) ? $info->host : "";
+ if ($host eq "") {
+ $::symbol{errorString} = "No CA host provided.";
+ return 0;
+ }
+
+ $https_ee_port = defined($info->port) ? $info->port : "";
+ if ($https_ee_port eq "") {
+ $::symbol{errorString} = "No CA EE port provided.";
+ return 0;
+ }
+
+ $domain_xml = get_domain_xml($host, $https_ee_port);
+ if ($domain_xml eq "") {
+ $::symbol{errorString} = "missing security domain. CA, TKS and optionally DRM must be installed prior to TPS installation";
+ return 0;
+ }
+
+ $https_agent_port = get_secure_agent_port_from_domain_xml($domain_xml, $host, $https_ee_port);
+ $https_admin_port = get_secure_admin_port_from_domain_xml($domain_xml, $host, $https_ee_port);
+
+ if(($https_admin_port eq "") || ($https_agent_port eq "")) {
+ $::symbol{errorString} = "secure CA admin or agent port information not provided by security domain.";
+ return 0;
+ }
+ } else {
+ $host = defined($::config->get("preop.securitydomain.ca$count.host")) ?
+ $::config->get("preop.securitydomain.ca$count.host") : "";
+ $https_ee_port = defined($::config->get("preop.securitydomain.ca$count.secureport")) ?
+ $::config->get("preop.securitydomain.ca$count.secureport") : "";
+ $https_agent_port = defined($::config->get("preop.securitydomain.ca$count.secureagentport")) ?
+ $::config->get("preop.securitydomain.ca$count.secureagentport") : "";
+ $https_admin_port = defined($::config->get("preop.securitydomain.ca$count.secureadminport")) ?
+ $::config->get("preop.securitydomain.ca$count.secureadminport") : "";
+ }
+
+ if (($host eq "") || ($https_ee_port eq "") || ($https_admin_port eq "") || ($https_agent_port eq "")) {
+ $::symbol{errorString} = "no CA found. CA, TKS and optionally DRM must be installed prior to TPS installation";
+ return 0;
+ }
+
+ &PKI::TPS::Wizard::debug_log("CAInfoPanel: update - host= $host, https_ee_port= $https_ee_port");
+
+ $::config->put("preop.cainfo.select", "https://$host:$https_admin_port");
+ my $serverCertNickName = $::config->get("preop.cert.sslserver.nickname");
+
+ my $subsystemCertNickName = $::config->get("preop.cert.subsystem.nickname");
+ $::config->put("conn.ca1.clientNickname", $subsystemCertNickName);
+ $::config->put("conn.ca1.hostport", $host . ":" . $https_ee_port);
+ $::config->put("conn.ca1.hostagentport", $host . ":" . $https_agent_port);
+ $::config->put("conn.ca1.hostadminport", $host . ":" . $https_admin_port);
+
+ $::config->commit();
+
+ # connect to the CA, and retrieve the CA certificate
+ &PKI::TPS::Wizard::debug_log("CAInfoPanel: update connecting to CA and retrieve cert chain");
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $db_password =~ s/\n$//g;
+ my $tmpfile = "/tmp/ca-$$";
+ system("/usr/bin/sslget -d \"$instanceDir/alias\" -p \"$db_password\" -v -n \"$serverCertNickName\" -r \"/ca/ee/ca/getCertChain\" $host:$https_ee_port > $tmpfile");
+ my $cmd = `cat $tmpfile`;
+ system("rm $tmpfile");
+ my $caCert;
+ if ($cmd =~ /\<ChainBase64\>(.*)\<\/ChainBase64\>/) {
+ $caCert = $1;
+ &PKI::TPS::Wizard::debug_log("CAInfoPanel: ca= $caCert");
+ }
+ if ($caCert eq "") {
+ &PKI::TPS::Wizard::debug_log("CAInfoPanel: update no cert chain found");
+ return 0;
+ }
+ open(F, ">$instanceDir/conf/caCertChain2.txt");
+ print F $cert_header."\n".$caCert."\n".$cert_footer;
+ close(F);
+
+ &PKI::TPS::Wizard::debug_log("CAInfoPanel: update retrieve cert chain done");
+
+ #import cert chain
+ system("p7tool -d $instanceDir/alias -p $instanceDir/conf/chain2cert -a -i $instanceDir/conf/caCertChain2.txt -o $instanceDir/conf/CAchain2_pp.txt");
+ my $r = $? >> 8;
+ my $failed = $? & 127;
+ if (($r > 0) && ($r < 10) && !$failed) {
+ my $i = 0;
+ while ($i ne $r) {
+ my $tmp = `certutil -d $instanceDir/alias -D -n "Trusted CA c2cert$i"`;
+ $tmp = `certutil -d $instanceDir/alias -A -f $instanceDir/conf/.pwfile -n "Trusted CA c2cert$i" -t "CT,C,C" -i $instanceDir/conf/chain2cert$i.der`;
+ $i++;
+ }
+ }
+
+ $::config->put("preop.cainfo.done", "true");
+ $::config->commit();
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("CAInfoPanel: display");
+
+ $::symbol{urls} = [];
+# unshift(@{$::symbol{urls}}, "External CA");
+ my $count = 0;
+ my $first = 1;
+ my $list = "";
+ while (1) {
+ my $host = "";
+ $host = $::config->get("preop.securitydomain.ca$count.host");
+ if ($host eq "") {
+ goto DONE;
+ }
+ my $https_ee_port = $::config->get("preop.securitydomain.ca$count.secureport");
+ my $name = $::config->get("preop.securitydomain.ca$count.subsystemname");
+ my $item = $name . " - https://" . $host . ":" . $https_ee_port;
+# my $item = "https://" . $host . ":" . $https_ee_port;
+# unshift(@{$::symbol{urls}}, $item);
+ $::symbol{urls}[$count++] = $item;
+ if ($first eq 1) {
+ $list = $item;
+ $first = 0;
+ } else {
+ $list = $list.",".$item;
+ }
+ }
+DONE:
+# $list = $list.",External CA";
+ $::config->put("preop.ca.list", $list);
+
+ $::symbol{urls_size} = $count;
+ if ($count eq 0) {
+ $::symbol{errorString} = "no CA found. CA, TKS, and optionally DRM must be installed prior to TPS installation";
+ return 0;
+ }
+ return 1;
+}
+
+sub get_domain_xml
+{
+ my $host = $1;
+ my $https_ee_port = $2;
+
+ # get the domain xml
+ # e. g. - https://water.sfbay.redhat.com:9445/ca/admin/ca/getDomainXML
+
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+ my $instanceID = $::config->get("service.instanceID");
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $db_password =~ s/\n$//g;
+
+ my $sd_host = $::config->get("securitydomain.host");
+ my $sd_admin_port = $::config->get("securitydomain.httpsadminport");
+ my $content = `/usr/bin/sslget -d \"$instanceDir/alias\" -p \"$db_password\" -v -r \"/ca/admin/ca/getDomainXML\" $sd_host:$sd_admin_port`;
+
+ $content =~ /(\<XMLResponse\>.*\<\/XMLResponse\>)/;
+ $content = $1;
+ return $content;
+}
+
+sub get_secure_admin_port_from_domain_xml
+{
+ my $content = $1;
+ my $host = $2;
+ my $https_ee_port = $3;
+
+ # Retrieve the secure admin port corresponding
+ # to the selected host and secure ee port.
+ my $parser = XML::Simple->new();
+ my $response = $parser->XMLin($content);
+ my $xml = $parser->XMLin( $response->{'DomainInfo'},
+ ForceArray => 1 );
+ my $https_admin_port = "";
+ my $count = 0;
+ foreach my $c (@{$xml->{'CAList'}[0]->{'CA'}}) {
+ if( ( $host eq $c->{'Host'}[0] ) &&
+ ( $https_ee_port eq $c->{'SecurePort'}[0] ) ) {
+ $https_admin_port = https_$c->{'SecureAdminPort'}[0];
+ }
+
+ $count++;
+ }
+
+ return $https_admin_port;
+}
+
+sub get_secure_agent_port_from_domain_xml
+{
+ my $content = $1;
+ my $host = $2;
+ my $https_ee_port = $3;
+
+ # Retrieve the secure agent port corresponding
+ # to the selected host and secure ee port.
+ my $parser = XML::Simple->new();
+ my $response = $parser->XMLin($content);
+ my $xml = $parser->XMLin( $response->{'DomainInfo'},
+ ForceArray => 1 );
+ my $https_agent_port = "";
+ my $count = 0;
+ foreach my $c (@{$xml->{'CAList'}[0]->{'CA'}}) {
+ if( ( $host eq $c->{'Host'}[0] ) &&
+ ( $https_ee_port eq $c->{'SecurePort'}[0] ) ) {
+ $https_agent_port = https_$c->{'SecureAgentPort'}[0];
+ }
+
+ $count++;
+ }
+
+ return $https_agent_port;
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.cainfo.done");
+}
+
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/CertInfo.pm b/base/tps/lib/perl/PKI/TPS/CertInfo.pm
new file mode 100755
index 000000000..da5377d4f
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/CertInfo.pm
@@ -0,0 +1,132 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+
+package PKI::TPS::CertInfo;
+$PKI::TPS::CertInfo::VERSION = '1.00';
+
+sub new {
+ my ($class, $name, $dn, $tag) = @_;
+ my $self = {};
+
+ &PKI::TPS::Wizard::debug_log("CertInfo: start new");
+ $self->{"getUserFriendlyName"} = \&get_user_friendly_name;
+ $self->{"getCertTag"} = \&get_cert_tag;
+ $self->{"getDN"} = \&get_dn;
+ $self->{"getNickname"} = \&get_nickname;
+ $self->{"useDefaultKey"} = \&use_default_key;
+ $self->{"getCustomKeysize"} = \&get_custom_keysize;
+ $self->{"keyOption"} = \&get_key_option;
+ &PKI::TPS::Wizard::debug_log("CertInfo: end new");
+
+ $self->{name} = $name;
+ $self->{dn} = $dn;
+ $self->{tag} = $tag;
+
+ bless $self, $class;
+ return $self;
+}
+
+sub get_user_friendly_name
+{
+ my ($self) = @_;
+ &PKI::TPS::Wizard::debug_log("CertInfo: get_user_friendly_name");
+ return $self->{name};
+}
+
+sub get_cert_tag
+{
+ my ($self) = @_;
+ &PKI::TPS::Wizard::debug_log("CertInfo: get_cert_tag");
+ return $self->{tag};
+}
+
+sub get_dn
+{
+ my ($self) = @_;
+ &PKI::TPS::Wizard::debug_log("CertInfo: get_cert_dn");
+ return $self->{dn};
+}
+
+sub use_default_key
+{
+ my ($self) = @_;
+ &PKI::TPS::Wizard::debug_log("CertInfo: use_default_key");
+ my $option = $::config->get("preop.cert.$self->{tag}.keysize.select");
+ if (($option ne "") && ($option ne "default")) {
+ return 0;
+ }
+ return 1;
+}
+
+sub get_nickname
+{
+ my ($self) = @_;
+ &PKI::TPS::Wizard::debug_log("CertInfo: get_nickname");
+ my $nickname = $::config->get("preop.cert.$self->{tag}.nickname");
+
+ my $flavor = "pki";
+ $flavor =~ s/\n//g;
+
+ if ($nickname ne "") {
+ return $nickname;
+ } else {
+ return $self->{tag}."cert cert-$flavor-tps";
+ }
+}
+
+sub get_key_option
+{
+ my ($self) = @_;
+ &PKI::TPS::Wizard::debug_log("CertInfo: get_key_option");
+ my $option = $::config->get("preop.cert.$self->{tag}.keysize.select");
+
+ if ($option ne "") {
+ &PKI::TPS::Wizard::debug_log("CertInfo: get_key_option from config = $option");
+ return $option;
+ } else {
+ &PKI::TPS::Wizard::debug_log("CertInfo: get_key_option not from config");
+ return "default";
+ }
+}
+
+sub get_custom_keysize
+{
+ my ($self) = @_;
+ &PKI::TPS::Wizard::debug_log("CertInfo: get_custom_keysize");
+ my $size = $::config->get("preop.cert.$self->{tag}.keysize.customsize");
+ &PKI::TPS::Wizard::debug_log("CertInfo: get_custom_keysize for preop.cert.$self->{tag}.keysize.customsize is $size");
+ if ($size ne "") {
+ &PKI::TPS::Wizard::debug_log("CertInfo: get_custom_keysize from config is $size");
+ return $size;
+ } else {
+ &PKI::TPS::Wizard::debug_log("CertInfo: get_custom_keysize not from config");
+ return 2048;
+ }
+}
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/CertPrettyPrintPanel.pm b/base/tps/lib/perl/PKI/TPS/CertPrettyPrintPanel.pm
new file mode 100755
index 000000000..200ef8d74
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/CertPrettyPrintPanel.pm
@@ -0,0 +1,91 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+
+package PKI::TPS::CertPrettyPrintPanel;
+$PKI::TPS::CertPrettyPrintPanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(13);
+ $self->{"getName"} = &PKI::TPS::Common::r("Certificates");
+ $self->{"vmfile"} = "certprettyprintpanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("CertPrettyPrintPanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("CertPrettyPrintPanel: update");
+ $::config->put("preop.certprettyprint.done", "true");
+ $::config->commit();
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("CertPrettyPrintPanel: display");
+ return 1;
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.certprettyprint.done");
+}
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/CertRequestPanel.pm b/base/tps/lib/perl/PKI/TPS/CertRequestPanel.pm
new file mode 100755
index 000000000..fb5d9ccda
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/CertRequestPanel.pm
@@ -0,0 +1,306 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+use PKI::TPS::ReqCertInfo;
+use FileHandle;
+
+package PKI::TPS::CertRequestPanel;
+$PKI::TPS::CertRequestPanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+our $cert_req_header="-----BEGIN NEW CERTIFICATE REQUEST-----";
+our $cert_req_footer="-----END NEW CERTIFICATE REQUEST-----";
+our $cert_header="-----BEGIN CERTIFICATE-----";
+our $cert_footer="-----END CERTIFICATE-----";
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(13);
+ $self->{"getName"} = &PKI::TPS::Common::r("Certificate Requests");
+ $self->{"vmfile"} = "certrequestpanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: update");
+
+ my $i = 0;
+
+ my $instanceDir = $::config->get("service.instanceDir");
+
+ my $useExternalCA = $::config->get("preop.certenroll.useExternalCA");
+ if ($useExternalCA eq "on") {
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: update: useExternalCA is on");
+ } else {
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: update: useExternalCA is off");
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: update auto enrollment should have been done, no more action needed");
+ return 1;
+ }
+
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: update External CA selected, retrieve/process user input");
+
+ my $tokenname = $::config->get("preop.module.token");
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: update got token name = $tokenname");
+ my $token_pwd = $::pwdconf->get($tokenname);
+ $token_pwd =~ s/\n//g;
+ open FILE, ">$instanceDir/conf/.pwfile";
+ system( "chmod 00660 $instanceDir/conf/.pwfile" );
+ print FILE $token_pwd;
+ close FILE;
+
+ my $hw;
+ my $tk;
+
+ if (($tokenname eq "") || ($tokenname eq "NSS Certificate DB")) {
+ $hw = "";
+ $tk = "";
+ } else {
+ $hw = "-h $tokenname";
+ $tk = $tokenname.":";
+ }
+
+ foreach my $certtag (@PKI::TPS::Wizard::certtags) {
+ if ($certtag eq "subsystem") {
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: update: subsystem cert is pre-generated by the security domain");
+ return 1;
+ }
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: update: for certag= $certtag");
+ my $ccert = $::config->get("preop.cert.$certtag.cert");
+ if ($ccert ne "") {
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: update: cert already exists in CS.cfg, go to next");
+ next;
+ }
+ my $certchain = $q->param($certtag.'_cc');
+ if ($certchain ne "") {
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: update: $certtag certchain is $certchain");
+ my $cc_fn = "$instanceDir/conf/caCertChain.txt";
+ my $tmp = `echo "$certchain" > $cc_fn`;
+ # remove existing one
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: update: try to delete existing certchain, if any....ok if it fails");
+# XXX remove should not be done lightly...
+ $tmp = `p7tool -d $instanceDir/alias -p $instanceDir/conf/chain1cert -a -i $cc_fn -o $instanceDir/conf/CAchain_pp.txt`;
+ my $r = $? >> 8;
+ my $failed = $? & 127;
+ if (($r > 0) && ($r < 10) && !$failed) {
+ my $i = 0;
+ while ($i ne $r) {
+ $tmp = `certutil -d $instanceDir/alias -D -n "Trusted CA $certtag cert$i"`;
+ $tmp = `certutil -d $instanceDir/alias -A -f $instanceDir/conf/.pwfile -n "Trusted CA $certtag cert$i" -t "CT,C,C" -i $instanceDir/conf/chain1cert$i.der`;
+# $tmp = `rm $cc_fn`;
+ $i++
+ }
+ }
+ } else {
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: update: no certchain included for certtag $certtag");
+ }
+
+ my $cert = $q->param($certtag);
+ if ($cert ne "") {
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: update: $certtag cert is $cert");
+ my $nickname = $::config->get("preop.cert.$certtag.nickname");
+ if ($nickname eq "") {
+ $nickname = "TPS ".$certtag." cert";
+ $::config->put("preop.cert.$certtag.nickname", $nickname);
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: update: $certtag cert nickname not found in CS.cfg, generating one= $nickname");
+ }
+ #remove existing one
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: update: try to delete existing cert $nickname, if any....ok if it fails");
+#XXX remove should not be done lightly...
+ my $tmp = `certutil -d $instanceDir/alias -D -n "$nickname"`;
+ $tmp = `certutil -d $instanceDir/alias -D $hw -f $instanceDir/conf/.pwfile -n "$tk$nickname"`;
+ #now import the cert
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: update: try to import cert");
+ my $cert_fn = "$instanceDir/conf/$certtag"."_cert.txt";
+ $tmp = `echo "$cert" > $cert_fn`;
+
+# $cert = extract_cert_from_file_sans_header_and_footer($cert_fn);
+ my $certa ="";
+ my $save_line = 0;
+ my @cert_a = split "\n", $cert;
+ foreach my $line (@cert_a) {
+ chomp( $line );
+ $line =~ s/\r//g;
+ if ($line eq $cert_header) {
+ $save_line = 1;
+ } elsif( $line eq $cert_footer ) {
+ $save_line = 0;
+ last;
+ } elsif( $save_line == 1 ) {
+ $certa .= "$line";
+ }
+ }
+
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: update putting cert in CS.cfg: $certa");
+
+ $::config->put("preop.cert.$certtag.cert", $certa);
+
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: update: about to certutil -d $instanceDir/alias $hw -A -f $instanceDir/conf/.pwfile -n $nickname -t u,u,u -a -i $cert_fn");
+ $tmp = `certutil -d $instanceDir/alias $hw -A -f $instanceDir/conf/.pwfile -n "$nickname" -t "u,u,u" -a -i $cert_fn`;
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: update: done certutil: $tmp");
+ $tmp = `rm $cert_fn`;
+
+ # changed the cert, need to change nickname too, if necessary
+ if ($hw ne "") {
+ $::config->put("preop.cert.$certtag.nickname", "$tk$nickname");
+ if ($certtag eq "subsystem") {
+ $::config->put("conn.ca1.clientNickname","$tk$nickname");
+ $::config->put("conn.drm1.clientNickname","$tk$nickname");
+ $::config->put("conn.tks1.clientNickname","$tk$nickname");
+ }
+ }
+
+ } else {
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: update: no cert");
+ }
+ }
+
+DONE:
+ $::config->put("preop.certrequest.done", "true");
+ $::config->commit();
+ my $tmp = `rm $instanceDir/conf/.pwfile`;
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("CertRequestPanel: display");
+
+ my $domain_name = $::config->get("preop.securitydomain.name");
+ if ($domain_name eq "") {
+ $domain_name = "TPS Domain";
+ }
+ my $machine_name = $::config->get("service.machineName");
+ my $instance_id = $::config->get("service.instanceID");
+
+ my $i = 0;
+ foreach my $certtag (@PKI::TPS::Wizard::certtags) {
+ my $cert_dn = $::config->get("preop.cert.".$certtag.".dn");
+ if ($cert_dn eq "") {
+ if ($certtag eq "subsystem") {
+ $cert_dn = "CN=TPS Subsystem, " .
+ "OU=" . $instance_id . ", " .
+ "O=" . $domain_name;
+ } elsif ($certtag eq "sslserver") {
+ $cert_dn ="CN=" . $machine_name . ", " .
+ "OU=" . $instance_id . ", " .
+ "O=" . $domain_name;
+ } else {
+ $cert_dn = $certtag;
+ }
+ }
+
+ my $name = $::config->get("preop.cert.".$certtag.".userfriendlyname");
+ if ($name eq "") {
+ $name = $certtag."Cert ".$instance_id;
+ }
+
+ my $reqcert = new PKI::TPS::ReqCertInfo($name,
+ $cert_dn, $certtag);
+ $::symbol{reqscerts}[$i++] = $reqcert;
+ }
+
+ $::symbol{errorString} = "";
+ $::symbol{showApplyButton} = "true";
+
+ return 1;
+}
+
+# arg0 message containing certificate
+# return certificate sans header and footer
+# -- all in a one-liner
+sub extract_cert_from_file_sans_header_and_footer
+{
+ my $filename = $_[0];
+ my $save_line = 0;
+
+ my $fd = new FileHandle;
+
+ my $cert = "";
+
+ $fd->open( "<$filename" ) or die "Could not open '$filename'!\n";
+
+ while( <$fd> )
+ {
+ my $line = $_;
+ chomp( $line );
+ $line =~ s/^M//g;
+
+ if( $line eq $cert_header ) {
+ $save_line = 1;
+ } elsif( $line eq $cert_footer ) {
+ $save_line = 0;
+ last;
+ } elsif( $save_line == 1 ) {
+ $cert .= "$line";
+ }
+ }
+
+ $fd->close();
+
+ return $cert;
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.certrequest.done");
+}
+
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/Common.pm b/base/tps/lib/perl/PKI/TPS/Common.pm
new file mode 100755
index 000000000..c66942599
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/Common.pm
@@ -0,0 +1,148 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+package PKI::TPS::Common;
+
+use strict;
+use warnings;
+use Exporter;
+use Mozilla::LDAP::Conn;
+use Mozilla::LDAP::LDIF;
+
+use vars qw(@ISA @EXPORT @EXPORT_OK);
+@ISA = qw(Exporter Autoloader);
+@EXPORT = qw(r yes no import_ldif test_and_make_connection make_connection);
+
+$PKI::TPS::Common::VERSION = '1.00';
+
+sub yes {
+ return sub {1};
+}
+
+sub no {
+ return sub {0};
+}
+
+sub r {
+ my $a = shift;
+ return sub { $a; }
+}
+
+# special function to add schema elements. This assumes the entry
+# is ldif update format with changetype "modify" and operation "add"
+#
+sub add_schema_update
+{
+ my ($conn, $aentry, $err_ref) = @_;
+
+ my $sentry = $conn->search($aentry->{dn}, "base", "(objectclass=*)", 0, ("*", "aci"));
+ if (!$sentry) {
+ $$err_ref .= "Error: trying to update entry that does not exist: " . $aentry->{dn} . "\n";
+ return 0;
+ }
+
+ my @addtypes = ("attributeTypes", "objectClasses");
+
+ foreach my $attr (@addtypes) {
+ my @vals = $aentry->getValues($attr);
+ push @vals, $vals[0]; # HACK! for some reason, first value always fails with server unwilling to perform
+
+ foreach my $val (@vals) {
+ $sentry->addValue( $attr, $val );
+ $conn->update($sentry);
+ my $rc = $conn->getErrorCode();
+ if ( $rc != 0 ) {
+ my $string = $conn->getErrorString();
+ $$err_ref .= "Error: updating entry " . $sentry->{dn} . " with value $val : $string\n";
+ } else {
+ $$err_ref .= "Updated entry ". $sentry->{dn} . " with value $val : rc = $rc\n";
+ }
+ }
+ }
+ return 1;
+}
+
+sub import_ldif
+{
+ my ($conn, $ldif_file, $msg_ref, $schema) = @_;
+
+ if (!open( MYLDIF, "$ldif_file" )) {
+ $$msg_ref = "Could not open $ldif_file: $!\n";
+ return 0;
+ }
+
+ my $in = new Mozilla::LDAP::LDIF(*MYLDIF);
+ while (my $entry = readOneEntry $in) {
+ if (defined($schema) && ($schema == 1)) {
+ add_schema_update($conn, $entry, $msg_ref);
+ } else {
+ if (!$conn->add($entry)) {
+ $$msg_ref .= "Error: could not add entry " . $entry->getDN() . ":" . $conn->getErrorString() . "\n";
+ }
+ }
+ }
+ close( MYLDIF );
+ return 1;
+}
+
+# this subroutine checks if an ldaps connection is successful first
+# and then if an ldap connection is successful.
+# This prevents a hanging condition when someone tries to connect to a ldaps
+# port using LDAP
+#
+# The arg hash is assumed to have the certdir (key == cert) defined.
+
+sub test_and_make_connection
+{
+ my ($arg_ref, $secureconn, $msg_ref) = @_;
+ my $conn = new Mozilla::LDAP::Conn($arg_ref);
+ if ($conn) { #ldaps succeeds
+ if ($secureconn eq "false") {
+ $$msg_ref = "SSL not selected, but this looks like an SSL port.";
+ return undef;
+ }
+ } else { #ldaps failed
+ if ($secureconn eq "true") {
+ $$msg_ref = "Failed to connect to LDAPS port";
+ return undef;
+ }
+ delete $arg_ref->{cert};
+ $conn = new Mozilla::LDAP::Conn($arg_ref);
+ if (!$conn) { # ldap failed
+ $$msg_ref = "Failed to connect to LDAP port:";
+ return undef;
+ }
+ }
+ return $conn;
+}
+
+sub make_connection
+{
+ my ($arg_ref, $secureconn) = @_;
+ if ($secureconn eq "false") {
+ delete $arg_ref->{cert};
+ }
+ return new Mozilla::LDAP::Conn($arg_ref);
+}
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/Config.pm b/base/tps/lib/perl/PKI/TPS/Config.pm
new file mode 100755
index 000000000..7195dccd9
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/Config.pm
@@ -0,0 +1,169 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+package PKI::TPS::Config;
+
+use strict;
+use warnings;
+use Exporter;
+
+$PKI::TPS::Config::VERSION = '1.00';
+
+#######################################################
+# Configuration Store
+#######################################################
+sub new {
+ my $class = shift;
+ my $self = {};
+ my %hash = ();
+ $self->{filename} = "";
+ $self->{hash} = \%hash;
+ bless $self,$class;
+ return $self;
+}
+
+sub load_file
+{
+ my ($self, $filename) = @_;
+
+ $self->{filename} = $filename;
+ if (-e $filename) {
+ open(CF, "<$filename");
+ if (defined fileno CF) {
+ while (<CF>) {
+ if (/^#/) {
+ # comments
+ } elsif (/([^=]+)=(.*)$/) {
+ # print "$1 = $2\n";
+ $self->{hash}{$1} = $2;
+ } else {
+ # preserve comments
+ }
+ }
+ }
+ close(CF);
+ }
+}
+
+sub get_filename
+{
+ my ($self) = @_;
+ return $self->{filename};
+}
+
+sub get
+{
+ my ($self, $n) = @_;
+ return $self->{hash}{$n};
+}
+
+sub put
+{
+ my ($self, $n, $v) = @_;
+ $self->{hash}{$n} = $v;
+}
+
+sub deleteSubstore
+{
+ my ($self, $n) = @_;
+ foreach my $xkey (keys %{$self->{hash}}) {
+ if ($xkey =~ /^\Q$n\E/) {
+ delete $self->{hash}{$xkey};
+ }
+ }
+}
+
+sub commit
+{
+ my ($self) = @_;
+
+ # write stuff back to the file
+# print $self->{filename} . "\n";
+ my $hash = $self->{hash};
+ my $suffix = time();
+
+ if (-e $self->{filename}) {
+ # Create a copy of the original file which
+ # preserves the original file permissions
+ system("cp -p \"" . $self->{filename} . "\" \"" .
+ $self->{filename} . "." . $suffix . "\"");
+ }
+
+ # Overwrite the contents of the original file
+ # to preserve the original file permissions
+ open(F, ">" . $self->{filename});
+ foreach my $k (sort keys %{$hash}) {
+ print F "$k=$self->{hash}{$k}\n";
+ }
+ close(F);
+
+ if (-e $self->{filename} . "." . $suffix) {
+ system("rm \"" . $self->{filename} . "." . $suffix . "\"");
+ }
+}
+
+sub commit_with_backup
+{
+ my ($self) = @_;
+
+ # write stuff back to the file
+# print $self->{filename} . "\n";
+ my $hash = $self->{hash};
+ my $suffix = time();
+ # Create a copy of the original file which
+ # preserves the original file permissions
+ system("cp -p \"" . $self->{filename} . "\" \"" .
+ $self->{filename} . "." . $suffix . "\"");
+
+ # Overwrite the contents of the original file
+ # to preserve the original file permissions
+ open(F, ">" . $self->{filename});
+ foreach my $k (sort keys %{$hash}) {
+ print F "$k=$self->{hash}{$k}\n";
+ }
+ close(F);
+}
+
+1;
+
+#######################################################
+# Test Program
+#######################################################
+#my $config = PKI::TPS::Config->new();
+#$config->load_file("/tmp/CS.cfg");
+#print $config->get("tokendb.indexAdminTemplate") . "\n";
+#$config->put("tokendb.indexAdminTemplate", "Testing");
+#print $config->get("tokendb.indexAdminTemplate") . "\n";
+#$config->commit();
+
+1;
+
+#######################################################
+# Test Program
+#######################################################
+#my $config = PKI::TPS::Config->new();
+#$config->load_file("/tmp/CS.cfg");
+#print $config->get("tokendb.indexAdminTemplate") . "\n";
+#$config->put("tokendb.indexAdminTemplate", "Testing");
+#print $config->get("tokendb.indexAdminTemplate") . "\n";
+#$config->commit();
diff --git a/base/tps/lib/perl/PKI/TPS/ConfigHSMLoginPanel.pm b/base/tps/lib/perl/PKI/TPS/ConfigHSMLoginPanel.pm
new file mode 100755
index 000000000..5d36d3da3
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/ConfigHSMLoginPanel.pm
@@ -0,0 +1,112 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+
+package PKI::TPS::ConfigHSMLoginPanel;
+$PKI::TPS::ConfigHSMLoginPanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(9);
+ $self->{"getName"} = &PKI::TPS::Common::r("Security Modules Login");
+ $self->{"vmfile"} = "config_hsmloginpanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 1;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("ConfigHSMLoginPanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("ConfigHSMLoginPanel: update");
+ my $uTokName = $q->param('uTokName');
+ my $uPasswd = $q->param('__uPasswd');
+
+# &PKI::TPS::Wizard::debug_log("ConfigHSMLoginPanel: update tokname= $uTokName pwd =$uPasswd");
+
+ $::pwdconf->put($uTokName, $uPasswd);
+ $::pwdconf->commit();
+
+ $::config->put("preop.confighsmlogin.done", "true");
+ $::config->commit();
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ use Data::Dumper;
+ $Data::Dumper::Indent = 1;
+# &PKI::TPS::Wizard::debug_log("ConfigHSMLoginPanel -> dump of q= ". Dumper($q));
+ $::symbol{SecToken} = $q->param('SecToken');
+# &PKI::TPS::Wizard::debug_log("ConfigHSMLoginPanel -> display has ".$q->param('SecToken'));
+
+ &PKI::TPS::Wizard::debug_log("ConfigHSMLoginPanel -> display retrieving $q->param('SecToken') ");
+ my $pwd = $::pwdconf->get( $q->param('SecToken'));
+ if ($pwd ne "") {
+ &PKI::TPS::Wizard::debug_log("ConfigHSMLoginPanel -> display retrieved pwd from pwdconf");
+ }
+
+ return 1;
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.confighsmlogin.done");
+}
+
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/ConfigHSMPanel.pm b/base/tps/lib/perl/PKI/TPS/ConfigHSMPanel.pm
new file mode 100755
index 000000000..06697a8c7
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/ConfigHSMPanel.pm
@@ -0,0 +1,78 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+
+package PKI::TPS::ConfigHSMPanel;
+$PKI::TPS::ConfigHSMPanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&PKI::TPS::Common::no;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(12);
+ $self->{"getName"} = &PKI::TPS::Common::r("ConfigHSMLogin");
+ $self->{"vmfile"} = "config_hsm.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("ConfigHSMPanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("ConfigHSMPanel: update");
+ $::config->put("preop.confighsm.done", "true");
+ $::config->commit();
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("ConfigHSMPanel: display");
+ return 1;
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.confighsm.done");
+}
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/DRMInfoPanel.pm b/base/tps/lib/perl/PKI/TPS/DRMInfoPanel.pm
new file mode 100755
index 000000000..1ccef670d
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/DRMInfoPanel.pm
@@ -0,0 +1,180 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+use URI::URL;
+
+package PKI::TPS::DRMInfoPanel;
+$PKI::TPS::DRMInfoPanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(6);
+ $self->{"getName"} = &PKI::TPS::Common::r("DRM Information");
+ $self->{"vmfile"} = "drminfopanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("DRMInfoPanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("DRMInfoPanel: update");
+
+ my $choice = $q->param('choice');
+ $::config->put("preop.krainfo.keygen", $choice);
+
+ if ($choice eq "keygen") {
+ my $count = defined($q->param('urls')) ? $q->param('urls') : "";
+ if ($count eq "") {
+ $::symbol{errorString} = "no DRM information provided. CA, TKS and DRM must be installed prior to TPS installation";
+ return 0;
+ }
+ &PKI::TPS::Wizard::debug_log("DRMInfoPanel: update - got urls = $count");
+
+ my $instanceID = $::config->get("service.instanceID");
+ my $host = "";
+ my $https_agent_port = "";
+ my $https_admin_port = "";
+
+ if ($count =~ /http/) {
+ # this is for pkisilent
+ my $info = new URI::URL($count);
+ $host = defined($info->host) ? $info->host : "";
+ $https_agent_port = defined($info->port) ? $info->port : "";
+ $https_admin_port = defined($q->param('adminport'))? $q->param('adminport') : "";
+ } else {
+ $host = defined($::config->get("preop.securitydomain.kra$count.host")) ?
+ $::config->get("preop.securitydomain.kra$count.host") : "";
+ $https_agent_port = defined($::config->get("preop.securitydomain.kra$count.secureagentport")) ?
+ $::config->get("preop.securitydomain.kra$count.secureagentport") : "";
+ $https_admin_port = defined($::config->get("preop.securitydomain.kra$count.secureadminport")) ?
+ $::config->get("preop.securitydomain.kra$count.secureadminport") : "";
+ }
+
+
+ if (($host eq "") || ($https_agent_port eq "")) {
+ $::symbol{errorString} = "no DRM found. CA, TKS and DRM must be installed prior to TPS installation";
+ return 0;
+ }
+
+ if ($https_admin_port eq "") {
+ if ($count =~ /http/) {
+ $::symbol{errorString} = "DRM admin port not provided by the security domain.";
+ } else {
+ $::symbol{errorString} = "DRM admin port not provided.";
+ }
+ return 0;
+ }
+
+ my $subsystemCertNickName = $::config->get("preop.cert.subsystem.nickname");
+ $::config->put("preop.krainfo.select", "https://$host:$https_admin_port");
+ $::config->put("conn.drm1.clientNickname", $subsystemCertNickName);
+ $::config->put("conn.drm1.hostport", $host . ":" . $https_agent_port);
+ $::config->put("conn.tks1.serverKeygen", "true");
+ $::config->put("op.enroll.userKey.keyGen.encryption.serverKeygen.enable", "true");
+ $::config->put("op.enroll.userKeyTemporary.keyGen.encryption.serverKeygen.enable", "true");
+ $::config->put("op.enroll.soKey.keyGen.encryption.serverKeygen.enable", "true");
+ $::config->put("op.enroll.soKeyTemporary.keyGen.encryption.serverKeygen.enable", "true");
+ } else {
+ # no keygen
+ $::config->put("conn.tks1.serverKeygen", "false");
+ $::config->put("op.enroll.userKey.keyGen.encryption.serverKeygen.enable", "false");
+ $::config->put("op.enroll.userKeyTemporary.keyGen.encryption.serverKeygen.enable", "false");
+ $::config->put("op.enroll.userKey.keyGen.encryption.recovery.destroyed.scheme", "GenerateNewKey");
+ $::config->put("op.enroll.userKeyTemporary.keyGen.encryption.recovery.onHold.scheme", "GenerateNewKey");
+ $::config->put("conn.drm1.clientNickname", "");
+ $::config->put("conn.drm1.hostport", "");
+ $::config->put("op.enroll.soKey.keyGen.encryption.serverKeygen.enable", "false");
+ $::config->put("op.enroll.soKeyTemporary.keyGen.encryption.serverKeygen.enable", "false");
+ $::config->put("op.enroll.soKey.keyGen.encryption.recovery.destroyed.scheme", "GenerateNewKey");
+ $::config->put("op.enroll.soKeyTemporary.keyGen.encryption.recovery.onHold.scheme", "GenerateNewKey");
+ }
+ $::config->put("preop.drminfo.done", "true");
+ $::config->commit();
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("DRMInfoPanel: display");
+
+ $::symbol{urls} = [];
+ my $count = 0;
+ while (1) {
+ my $host = "";
+ $host = $::config->get("preop.securitydomain.kra$count.host");
+ if ($host eq "") {
+ goto DONE;
+ }
+ my $https_agent_port = $::config->get("preop.securitydomain.kra$count.secureagentport");
+ my $name = $::config->get("preop.securitydomain.kra$count.subsystemname");
+ $::symbol{urls}[$count++] = $name . " - https://" . $host . ":" . $https_agent_port;
+ }
+DONE:
+ $::symbol{urls_size} = $count;
+
+ return 1;
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.drminfo.done");
+}
+
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/DatabasePanel.pm b/base/tps/lib/perl/PKI/TPS/DatabasePanel.pm
new file mode 100755
index 000000000..d8fee06e8
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/DatabasePanel.pm
@@ -0,0 +1,277 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+use Mozilla::LDAP::Conn;
+
+package PKI::TPS::DatabasePanel;
+$PKI::TPS::DatabasePanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(8);
+ $self->{"getName"} = &PKI::TPS::Common::r("Internal Database");
+ $self->{"vmfile"} = "databasepanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("DatabasePanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("DatabasePanel: update");
+ my $instDir = $::config->get("service.instanceDir");
+ my $certdir = "$instDir/alias";
+
+ my $host = $q->param('host');
+ my $port = $q->param('port');
+ my $basedn = $q->param('basedn');
+ my $database = $q->param('database');
+ my $binddn = $q->param('binddn');
+ my $bindpwd = $q->param('__bindpwd');
+ my $secureconn = $q->param('secureConn') || "false";
+
+ &PKI::TPS::Wizard::debug_log("DatabasePanel: host=$host port=$port basedn=$basedn");
+ &PKI::TPS::Wizard::debug_log("DatabasePanel: database=$database binddn=$binddn");
+ &PKI::TPS::Wizard::debug_log("DatabasePanel: secureconn=$secureconn");
+
+ # try to make a connection
+ # we need to test the ldaps connection first because testing an ldaps port with ldap:// will hang the query!
+ my $msg;
+ my $conn = &PKI::TPS::Common::test_and_make_connection(
+ {host => $host, port => $port, cert => $certdir, bind => $binddn, pswd => $bindpwd},
+ $secureconn,
+ \$msg);
+
+ if (!$conn) {
+ &PKI::TPS::Wizard::debug_log("DatabasePanel: failed to connect to internal db: $msg");
+ $::symbol{errorString} = $msg;
+ return 0;
+ }
+
+ # save values to CS.cfg
+ $::config->put("preop.database.host", $host);
+ $::config->put("preop.database.port", $port);
+ $::config->put("preop.database.basedn", $basedn);
+ $::config->put("preop.database.database", $database);
+ $::config->put("preop.database.binddn", $binddn);
+ $::config->put("tokendb.activityBaseDN", "ou=Activities," . $basedn);
+ $::config->put("tokendb.baseDN", "ou=Tokens," . $basedn);
+ $::config->put("tokendb.certBaseDN", "ou=Certificates," . $basedn);
+ $::config->put("tokendb.hostport", $host . ":" . $port);
+ $::config->put("tokendb.userBaseDN", $basedn);
+ $::config->put("tokendb.ssl", $secureconn);
+ $::config->put("auth.instance.1.hostport", $host . ":" . $port);
+ $::config->put("auth.instance.1.baseDN", $basedn);
+ $::config->put("auth.instance.1.ssl", $secureconn);
+ $::config->commit();
+
+# $::config->put("tokendb.bindPass", $bindpwd);
+ if ($bindpwd ne "") {
+ open(PWD_CONF, ">>$instDir/conf/password.conf");
+ print PWD_CONF "tokendbBindPass:$bindpwd\n";
+ close (PWD_CONF);
+ }
+
+ my $rdn = $basedn;
+ $rdn =~ s/,.*//g;
+ my ($type, $value) = split(/=/, $rdn);
+ my $objectclass = "domain";
+ if ($type eq "O" || $type eq "o") {
+ $objectclass = "organization";
+ } elsif ($type eq "OU" || $type eq "ou") {
+ $objectclass = "organizationalUnit";
+ }
+
+ my $flavor = "pki";
+ $flavor =~ s/\n//g;
+
+ # creating database
+ my $tmp = "/tmp/database-$$.ldif";
+ system("sed -e 's/\$DATABASE/$database/' " .
+ "-e 's/\$BASEDN/$basedn/' " .
+ "-e 's/\$OBJECTCLASS/$objectclass/' " .
+ "-e 's/\$TYPE/$type/' " .
+ "-e 's/\$VALUE/$value/' " .
+ "/usr/share/$flavor/tps/scripts/database.ldif > $tmp");
+ if (! &PKI::TPS::Common::import_ldif($conn, $tmp, \$msg)) {
+ &PKI::TPS::Wizard::debug_log("DatabasePanel: $msg");
+ $::symbol{errorString} = "Failed to create database";
+ $conn->close();
+ return 0;
+ };
+ if ($msg ne "") {
+ &PKI::TPS::Wizard::debug_log("DatabasePanel: database creation errors : $msg");
+ $msg="";
+ }
+ system("rm $tmp");
+
+ # add schema
+ if (! &PKI::TPS::Common::import_ldif($conn, "/usr/share/$flavor/tps/scripts/schemaMods.ldif", \$msg, 1)) {
+ &PKI::TPS::Wizard::debug_log("DatabasePanel: $msg");
+ $::symbol{errorString} = "Failed to add schema";
+ $conn->close();
+ return 0;
+ };
+ if ($msg ne "") {
+ &PKI::TPS::Wizard::debug_log("DatabasePanel: schema creation errors : $msg");
+ $msg="";
+ }
+
+ # populate database
+ $tmp = "/tmp/addTokens-$$.ldif";
+ system("sed -e 's/\$TOKENDB_ROOT/$basedn/g' " .
+ "/usr/share/$flavor/tps/scripts/addTokens.ldif > $tmp");
+ if (! &PKI::TPS::Common::import_ldif($conn, $tmp, \$msg)) {
+ &PKI::TPS::Wizard::debug_log("DatabasePanel: $msg");
+ $::symbol{errorString} = "Failed to populate database";
+ $conn->close();
+ return 0;
+ };
+ if ($msg ne "") {
+ &PKI::TPS::Wizard::debug_log("DatabasePanel: database population errors : $msg");
+ $msg="";
+ }
+ system("rm $tmp");
+
+ # add regular indexes
+ $tmp = "/tmp/addIndexes-$$.ldif";
+ system("sed -e 's/userRoot/$database/g' " .
+ "/usr/share/$flavor/tps/scripts/addIndexes.ldif > $tmp");
+ if (! &PKI::TPS::Common::import_ldif($conn, $tmp, \$msg)) {
+ &PKI::TPS::Wizard::debug_log("DatabasePanel: $msg");
+ $::symbol{errorString} = "Failed to add indexes";
+ $conn->close();
+ return 0;
+ };
+ if ($msg ne "") {
+ &PKI::TPS::Wizard::debug_log("DatabasePanel: adding index errors : $msg");
+ $msg="";
+ }
+ system("rm $tmp");
+
+ # add VLV indexes
+ $tmp = "/tmp/addVLVIndexes-$$.ldif";
+ system("sed -e 's/userRoot/$database/g;s/\$TOKENDB_ROOT/$basedn/g' " .
+ "/usr/share/$flavor/tps/scripts/addVLVIndexes.ldif > $tmp");
+ if (! &PKI::TPS::Common::import_ldif($conn, $tmp, \$msg)) {
+ &PKI::TPS::Wizard::debug_log("DatabasePanel: $msg");
+ $::symbol{errorString} = "Failed to add vlv indexes";
+ $conn->close();
+ return 0;
+ };
+ if ($msg ne "") {
+ &PKI::TPS::Wizard::debug_log("DatabasePanel: adding VLV index errors : $msg");
+ $msg="";
+ }
+ system("rm $tmp");
+
+ $conn->close();
+
+ $::config->put("preop.database.done", "true");
+ $::config->commit();
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("DatabasePanel: display");
+
+ my $machineName = $::config->get("service.machineName");
+ my $instanceId = $::config->get("service.instanceID");
+
+ my $host = $::config->get("preop.database.host") || "";
+ $::symbol{hostname} = "localhost"; # default
+ if ($host ne "") {
+ $::symbol{hostname} = $host;
+ }
+ my $port = $::config->get("preop.database.port") || "";
+ $::symbol{portStr} = "389";
+ if ($port ne "") {
+ $::symbol{portStr} = $port;
+ }
+ my $basedn = $::config->get("preop.database.basedn") || "";
+ $::symbol{basedn} = "dc=" . $machineName . "-" . $instanceId;
+ if ($basedn ne "") {
+ $::symbol{basedn} = $basedn;
+ }
+ my $database = $::config->get("preop.database.database") || "";
+ $::symbol{database} = $machineName . "-" . $instanceId;
+ if ($database ne "") {
+ $::symbol{database} = $database;
+ }
+ my $binddn = $::config->get("preop.database.binddn") || "";
+ $::symbol{binddn} = "cn=directory manager";
+ if ($binddn ne "") {
+ $::symbol{binddn} = $binddn;
+ }
+
+ my $secureconn = $::config->get("auth.instance.1.ssl") || "false";
+ $::symbol{secureconn} = $secureconn;
+
+ $::symbol{bindpwd} = "";
+
+ return 1;
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.database.done");
+}
+
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/DisplayCertChain2Panel.pm b/base/tps/lib/perl/PKI/TPS/DisplayCertChain2Panel.pm
new file mode 100755
index 000000000..3a86ab0bd
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/DisplayCertChain2Panel.pm
@@ -0,0 +1,186 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+use FileHandle;
+
+package PKI::TPS::DisplayCertChain2Panel;
+$PKI::TPS::DisplayCertChain2Panel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+our $cert_header="-----BEGIN CERTIFICATE-----";
+our $cert_footer="-----END CERTIFICATE-----";
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(7);
+ $self->{"getName"} = &PKI::TPS::Common::r("Display Certificate Chain");
+ $self->{"vmfile"} = "displaycertchain2panel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub readFile
+{
+ my $fn = $_[0];
+ open FILE, "< $fn" or return "";
+ my $content = join "",<FILE>;
+ close FILE;
+
+ return $content;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("DisplayCertChain2Panel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("DisplayCertChain2Panel: update");
+
+ my $instanceDir = $::config->get("service.instanceDir");
+
+# my $caCert = readFile("$instanceDir/conf/caCertChain2.txt");
+ my $caCert = extract_cert_from_file_sans_header_and_footer("$instanceDir/conf/caCertChain2.txt");
+
+ #store in config
+ $::config->put("preop.ca.certchain", $caCert);
+ $::config->commit();
+ # import it into the security database
+ my $tmp = `p7tool -d $instanceDir/alias -p $instanceDir/conf/chain2cert -a -i $instanceDir/conf/caCertChain2.txt -o $instanceDir/conf/CAchain2_pp.txt`;
+ my $r = $? >> 8;
+ my $failed = $? & 127;
+ if (($r > 0) && ($r < 10) && !$failed) {
+ my $i = 0;
+ while ($i ne $r) {
+ $tmp = `certutil -d $instanceDir/alias -D -n "Trusted CA c2cert$i"`;
+ $tmp = `certutil -d $instanceDir/alias -A -f $instanceDir/conf/.pwfile -n "Trusted CA c2cert$i" -t "CT,C,C" -i $instanceDir/conf/chain2cert$i.der`;
+ $i++
+ }
+ }
+
+ # clean up
+# my $tmp = `rm $instanceDir/conf/caCertChain2.txt`;
+# $tmp = `rm $instanceDir/conf/CAchain2_pp.txt`;
+
+ $::config->put("preop.displaycertchain2.done", "true");
+ $::config->commit();
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("DisplayCertChain2Panel: display");
+ my $instanceDir = $::config->get("service.instanceDir");
+
+ my $found = -e "$instanceDir/conf/caCertChain2.txt";
+ my $certpp = "";
+ if ($found) {
+ &PKI::TPS::Wizard::debug_log("DisplayCertChain2Panel: display found caCertChain2.txt");
+ my $tmp = `p7tool -d $instanceDir/alias -p $instanceDir/conf/chain2cert -a -i $instanceDir/conf/caCertChain2.txt -o $instanceDir/conf/CAchain2_pp.txt`;
+
+ $certpp = readFile("$instanceDir/conf/CAchain2_pp.txt");
+ &PKI::TPS::Wizard::debug_log("DisplayCertChain2Panel: display read CAchain2_pp.txt");
+ $certpp =~ s/"//g;
+ &PKI::TPS::Wizard::debug_log("DisplayCertChain2Panel: certpp2= $certpp");
+ }
+
+# $symbol{certchain} = [ "cert1", "cert2" ];
+# $symbol{certchain_size} = 2;
+ $::symbol{certchain} = "$certpp";
+ $::symbol{certchain_size} = 1;
+
+ &PKI::TPS::Wizard::debug_log("DisplayCertChain2Panel: display done");
+ return 1;
+}
+
+# return certificate sans header and footer
+# -- all in a one-liner
+sub extract_cert_from_file_sans_header_and_footer
+{
+ my $filename = $_[0];
+ my $save_line = 0;
+
+ my $fd = new FileHandle;
+
+ my $cert = "";
+
+ $fd->open( "<$filename" ) or die "Could not open '$filename'!\n";
+
+ while( <$fd> )
+ {
+ my $line = $_;
+ chomp( $line );
+ $line =~ s/^M//g;
+
+ if( $line eq $cert_header ) {
+ $save_line = 1;
+ } elsif( $line eq $cert_footer ) {
+ $save_line = 0;
+ last;
+ } elsif( $save_line == 1 ) {
+ $cert .= "$line";
+ }
+ }
+
+ $fd->close();
+
+ return $cert;
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.displaycertchain2.done");
+}
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/DisplayCertChainPanel.pm b/base/tps/lib/perl/PKI/TPS/DisplayCertChainPanel.pm
new file mode 100755
index 000000000..68b64a4b5
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/DisplayCertChainPanel.pm
@@ -0,0 +1,355 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+use URI::URL;
+use MIME::Base64;
+
+package PKI::TPS::DisplayCertChainPanel;
+$PKI::TPS::DisplayCertChainPanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(2);
+ $self->{"getName"} = &PKI::TPS::Common::r("Display Certificate Chain");
+ $self->{"vmfile"} = "displaycertchainpanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 1;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("DisplayCertChainPanel: validate");
+ return 1;
+}
+
+sub readFile
+{
+ my $fn = $_[0];
+ open FILE, "< $fn" or return "";
+ my $content = join "",<FILE>;
+ close FILE;
+
+ return $content;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("DisplayCertChainPanel: update");
+
+ my $instanceDir = $::config->get("service.instanceDir");
+
+ my $caCert = readFile("$instanceDir/conf/caCert.txt");
+
+ #store in config
+ $::config->put("preop.ca.certchain", $caCert);
+ $::config->commit();
+
+ # import it into the security database
+# my $cmd1 = `/usr/bin/AtoB $instanceDir/conf/caCert.txt $instanceDir/conf/caCert.der`;
+ my $cmd2 = `/usr/bin/certutil -A -d \"$instanceDir/alias\" -t \"CT,CT,CT\" -n \"caCert\" -i $instanceDir/conf/caCert.der`;
+
+ # clean up
+ my $tmp = `rm $instanceDir/conf/caCert.txt`;
+ $tmp = `rm $instanceDir/conf/caCert.der`;
+ $tmp = `rm $instanceDir/conf/caCert_pp.txt`;
+
+ # complete the SecurityDomain task
+ my $sdomainAdminURL = $::config->get("config.sdomainAdminURL");
+ if ($sdomainAdminURL eq "") {
+ return 2;
+ }
+
+ my $machineName = $::config->get("service.machineName");
+ my $non_clientauth_securePort = $::config->get("service.non_clientauth_securePort");
+ my $unsecurePort = $::config->get("service.unsecurePort");
+
+ # check if url is accessible
+ # redirect to the security domain authentication
+ if ($ENV{'SERVER_PORT'} eq $unsecurePort) {
+ $::symbol{redirect} = $sdomainAdminURL . "/ca/admin/ca/securityDomainLogin?url=http%3A%2F%2F" . $machineName . "%3A" . $unsecurePort . "%2Ftps%2Fadmin%2Fconsole%2Fconfig%2Fwizard%3Fp%3D5%26subsystem%3DTPS";
+ } else {
+ $::symbol{redirect} = $sdomainAdminURL . "/ca/admin/ca/securityDomainLogin?url=https%3A%2F%2F" . $machineName . "%3A" . $non_clientauth_securePort . "%2Ftps%2Fadmin%2Fconsole%2Fconfig%2Fwizard%3Fp%3D5%26subsystem%3DTPS";
+ }
+
+ get_domain_xml($sdomainAdminURL);
+
+ $::config->put("preop.displaycertchain.done", "true");
+ $::config->commit();
+
+ return 3;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("DisplayCertChainPanel: display");
+
+ # connect to the CA, and retrieve the CA certificate
+ &PKI::TPS::Wizard::debug_log("DisplayCertChainPanel: update connecting to CA and retrieve cert chain");
+ my $instanceID = $::config->get("service.instanceID");
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $sdomainAdminURL = $::config->get("config.sdomainAdminURL");
+ if ($sdomainAdminURL eq "") {
+ return 2;
+ }
+
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $db_password =~ s/\n$//g;
+
+ my $url_info = new URI::URL($sdomainAdminURL);
+ my $sd_host = $url_info->host;
+ my $sd_admin_port = $url_info->port;
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+ my $cmd = `/usr/bin/sslget -d \"$instanceDir/alias\" -p \"$db_password\" -v -r \"/ca/admin/ca/getCertChain\" $sd_host:$sd_admin_port`;
+
+ my $caCert = "";
+ if ($cmd =~ /\<ChainBase64\>(.*)\<\/ChainBase64\>/) {
+ $caCert = $1;
+ &PKI::TPS::Wizard::debug_log("DisplayCertChainPanel: ca= $caCert");
+ }
+
+ my $certpp = "";
+ if ($caCert ne "") {
+ open(F, ">$instanceDir/conf/caCert.txt");
+ print F $caCert;
+ close(F);
+
+ # test to see if tmp directory exists, if not, create
+ my $found = -e "$instanceDir/conf/tmp";
+ if (! $found) {
+ my $tmp = `mkdir $instanceDir/conf/tmp`;
+ }
+
+ # import it into a temporary security database
+# my $cmd1 = `/usr/bin/AtoB $instanceDir/conf/caCert.txt $instanceDir/conf/caCert.der`;
+ # my $cmd1 = `/usr/bin/openssl base64 -d -A -in $instanceDir/conf/caCert.txt -out $instanceDir/conf/caCert.der`;
+
+ my $txt = `cat $instanceDir/conf/caCert.txt`;
+ open(OUT, ">$instanceDir/conf/caCert.der");
+ print OUT MIME::Base64::decode($txt);
+ close(OUT);
+
+ my $cmd2 = `/usr/bin/certutil -A -d \"$instanceDir/conf/tmp\" -t \"CT,CT,CT\" -n \"caCert\" -i $instanceDir/conf/caCert.der`;
+
+ # get pretty print from temp db
+ my $tmp = `certutil -d $instanceDir/conf/tmp -n "caCert" -L > $instanceDir/conf/caCert_pp.txt`;
+ $certpp = readFile("$instanceDir/conf/caCert_pp.txt");
+ $certpp =~ s/"//g;
+ &PKI::TPS::Wizard::debug_log("DisplayCertChainPanel: certpp= $certpp");
+ # clean up temp db
+ $tmp = `certutil -d $instanceDir/alias/tmp -D -n "caCert"`;
+ } else {
+ &PKI::TPS::Wizard::debug_log("DisplayCertChainPanel: update no certchain found");
+ }
+
+ &PKI::TPS::Wizard::debug_log("DisplayCertChainPanel: display certchain=$caCert");
+
+# $symbol{certchain} = [ "cert1", "cert2" ];
+# $symbol{certchain_size} = 2;
+ $::symbol{certchain} = "$certpp";
+# This certchain_size does not matter
+ $::symbol{certchain_size} = 1;
+
+ return 1;
+}
+
+sub get_domain_xml
+{
+ my ($sdomainAdminURL) = @_;
+
+ my $sdom_info = new URI::URL($sdomainAdminURL);
+ # get the domain xml
+ # e. g. - https://water.sfbay.redhat.com:9445/ca/admin/ca/getDomainXML
+
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+ my $instanceID = $::config->get("service.instanceID");
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $db_password =~ s/\n$//g;
+
+ my $sd_host = $sdom_info->host;
+ my $sd_admin_port = $sdom_info->port;
+ my $content = `/usr/bin/sslget -d \"$instanceDir/alias\" -p \"$db_password\" -v -r \"/ca/admin/ca/getDomainXML\" $sd_host:$sd_admin_port`;
+
+ $content =~ /(\<XMLResponse\>.*\<\/XMLResponse\>)/;
+ $content = $1;
+
+ &PKI::TPS::Wizard::debug_log("content = " . $content);
+
+ my $parser = XML::Simple->new();
+ my $response = $parser->XMLin($content);
+ my $xml = $parser->XMLin($response->{'DomainInfo'},
+ ForceArray => 1);
+
+ &PKI::TPS::Wizard::debug_log("DisplayCertChainPanel: security domain '" .
+ $xml->{'Name'}[0] . "'");
+ $::config->put("preop.securitydomain.name", $xml->{'Name'}[0]);
+ $::config->put("securitydomain.name", $xml->{'Name'}[0]);
+
+ # parse xml and store information in CS.cfg
+ my $count = 0;
+ $count = 0;
+ foreach my $c (@{$xml->{'CAList'}[0]->{'CA'}}) {
+ &PKI::TPS::Wizard::debug_log("DisplayCertChainPanel: Found CA '" .
+ $c->{'SubsystemName'}[0] . "'");
+ $::config->put("preop.securitydomain.ca" . $count . ".subsystemname",
+ $c->{'SubsystemName'}[0]);
+ $::config->put("preop.securitydomain.ca" . $count . ".secureport",
+ $c->{'SecurePort'}[0]);
+ $::config->put("preop.securitydomain.ca" . $count . ".secureagentport",
+ $c->{'SecureAgentPort'}[0]);
+ $::config->put("preop.securitydomain.ca" . $count . ".secureadminport",
+ $c->{'SecureAdminPort'}[0]);
+ $::config->put("preop.securitydomain.ca" . $count . ".unsecureport",
+ $c->{'UnSecurePort'}[0]);
+ $::config->put("preop.securitydomain.ca" . $count . ".host",
+ $c->{'Host'}[0]);
+
+ # The user previously specified the CA Security Domain's
+ # SSL Admin URL in the "Security Domain Panel";
+ # now retrieve this specified CA Security Domain's
+ # non-SSL EE, SSL Agent, and SSL EE URLs:
+ if( $sd_admin_port eq $c->{'SecureAdminPort'}[0] ) {
+ # Build the URLs
+ my $http_ee_port = "https://"
+ . $c->{'Host'}[0]
+ . ":"
+ . $c->{'UnSecurePort'}[0];
+ my $https_agent_port = "https://"
+ . $c->{'Host'}[0]
+ . ":"
+ . $c->{'SecureAgentPort'}[0];
+ my $https_ee_port = "https://"
+ . $c->{'Host'}[0]
+ . ":"
+ . $c->{'SecurePort'}[0];
+
+ # Store the URLs
+ $::config->put( "config.sdomainHttpURL", $http_ee_port );
+ $::config->put( "config.sdomainAgentURL", $https_agent_port );
+ $::config->put( "config.sdomainEEURL", $https_ee_port );
+
+ # Store additional values necessary for 'pkiremove' . . .
+ $::config->put( "securitydomain.httpport",
+ $c->{'UnSecurePort'}[0] );
+ $::config->put( "securitydomain.httpsagentport",
+ $c->{'SecureAgentPort'}[0] );
+ $::config->put( "securitydomain.httpseeport",
+ $c->{'SecurePort'}[0] );
+ }
+
+ $count++;
+ }
+
+ $count = 0;
+ foreach my $c (@{$xml->{'TKSList'}[0]->{'TKS'}}) {
+ &PKI::TPS::Wizard::debug_log("DisplayCertChainPanel: Found TKS '" .
+ $c->{'SubsystemName'}[0] . "'");
+ $::config->put("preop.securitydomain.tks" . $count . ".subsystemname",
+ $c->{'SubsystemName'}[0]);
+ $::config->put("preop.securitydomain.tks" . $count . ".secureport",
+ $c->{'SecurePort'}[0]);
+ $::config->put("preop.securitydomain.tks" . $count . ".secureagentport",
+ $c->{'SecureAgentPort'}[0]);
+ $::config->put("preop.securitydomain.tks" . $count . ".secureadminport",
+ $c->{'SecureAdminPort'}[0]);
+ $::config->put("preop.securitydomain.tks" . $count . ".unsecureport",
+ $c->{'UnSecurePort'}[0]);
+ $::config->put("preop.securitydomain.tks" . $count . ".host",
+ $c->{'Host'}[0]);
+ $count++;
+ }
+
+ $count = 0;
+ foreach my $c (@{$xml->{'KRAList'}[0]->{'KRA'}}) {
+ &PKI::TPS::Wizard::debug_log("DisplayCertChainPanel: Found KRA '" .
+ $c->{'SubsystemName'}[0] . "'");
+ $::config->put("preop.securitydomain.kra" . $count . ".subsystemname",
+ $c->{'SubsystemName'}[0]);
+ $::config->put("preop.securitydomain.kra" . $count . ".secureport",
+ $c->{'SecurePort'}[0]);
+ $::config->put("preop.securitydomain.kra" . $count . ".secureagentport",
+ $c->{'SecureAgentPort'}[0]);
+ $::config->put("preop.securitydomain.kra" . $count . ".secureadminport",
+ $c->{'SecureAdminPort'}[0]);
+ $::config->put("preop.securitydomain.kra" . $count . ".unsecureport",
+ $c->{'UnSecurePort'}[0]);
+ $::config->put("preop.securitydomain.kra" . $count . ".host",
+ $c->{'Host'}[0]);
+ $count++;
+ }
+
+ $count = 0;
+ foreach my $c (@{$xml->{'TPSList'}[0]->{'TPS'}}) {
+ &PKI::TPS::Wizard::debug_log("DisplayCertChainPanel: Found TPS '" .
+ $c->{'SubsystemName'}[0] . "'");
+ $::config->put("preop.securitydomain.tps" . $count . ".subsystemname",
+ $c->{'SubsystemName'}[0]);
+ $::config->put("preop.securitydomain.tps" . $count . ".secureport",
+ $c->{'SecureAgentPort'}[0]);
+ $::config->put("preop.securitydomain.tps" . $count . ".non_clientauth_secure_port",
+ $c->{'SecurePort'}[0]);
+ $::config->put("preop.securitydomain.tps" . $count . ".unsecureport",
+ $c->{'UnSecurePort'}[0]);
+ $::config->put("preop.securitydomain.tps" . $count . ".host",
+ $c->{'Host'}[0]);
+ $count++;
+ }
+ $::config->commit();
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.displaycertchain.done");
+}
+
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/DonePanel.pm b/base/tps/lib/perl/PKI/TPS/DonePanel.pm
new file mode 100755
index 000000000..3d897fca9
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/DonePanel.pm
@@ -0,0 +1,437 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+use URI::URL;
+use XML::Simple;
+
+package PKI::TPS::DonePanel;
+$PKI::TPS::DonePanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(16);
+ $self->{"getName"} = &PKI::TPS::Common::r("Done");
+ $self->{"vmfile"} = "donepanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("DonePanel: validate");
+ return 1;
+}
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("DonePanel: update");
+ return 1;
+}
+
+sub register_tps
+{
+ my ($sdom, $url, $uri, $xname) = @_;
+
+ &PKI::TPS::Wizard::debug_log("DonePanel: register_tps at $url");
+ &PKI::TPS::Wizard::debug_log("DonePanel: subsystem $xname uri=$uri");
+
+ my $url_info = new URI::URL($url);
+ my $sdom_info = new URI::URL($sdom);
+
+ # register TPS to Security Domain
+ # submit request to CA
+ &PKI::TPS::Wizard::debug_log("DonePanel: Connecting to Security Domain");
+
+ my $machineName = $::config->get("service.machineName");
+ my $unsecurePort = $::config->get("service.unsecurePort");
+ my $securePort = $::config->get("service.securePort");
+ my $non_clientauth_securePort = $::config->get("service.non_clientauth_securePort");
+ my $session_id = $::config->get("preop.sessionID");
+
+ &PKI::TPS::Wizard::debug_log("DonePanel: Security Domain Info " . $url);
+
+ # add service.securityDomainPort to the config file in case pkiremove
+ # needs to remove system reference from the security domain
+ $::config->put("service.securityDomainPort", $securePort);
+ $::config->commit();
+
+ my $uid = "TPS-" . $machineName . "-" . $securePort;
+ my $name = "Token Processing Subsystem";
+
+ my $instDir = $::config->get("service.instanceDir");
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+
+ my $hw;
+ my $tk;
+ my $tokenname = $::config->get("preop.module.token");
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: update got token name = $tokenname");
+
+ my $token_pwd = $::pwdconf->get($tokenname);
+ open FILE, ">$instDir/conf/.pwfile";
+ system( "chmod 00660 $instDir/conf/.pwfile" );
+ $token_pwd =~ s/\n//g;
+ print FILE $token_pwd;
+ close FILE;
+
+ if (($tokenname eq "") || ($tokenname eq "NSS Certificate DB")) {
+ $hw = "";
+ $tk = "";
+ } else {
+ $hw = "-h $tokenname";
+ $tk = $tokenname.":";
+ }
+
+ my $subsystemNickname = $::config->get("preop.cert.subsystem.nickname");
+
+ my $certificate = `/usr/bin/certutil -d "$instDir/alias" -L $hw -f "$instDir/conf/.pwfile" -n "$subsystemNickname" -a`;
+ my $tmp = `rm $instDir/conf/.pwfile`;
+ $certificate =~ s/-----BEGIN CERTIFICATE-----//g;
+ $certificate =~ s/-----END CERTIFICATE-----//g;
+ $certificate =~ s/\n$//g;
+
+
+ &PKI::TPS::Wizard::debug_log("DonePanel: Connecting");
+
+ my $instanceID = $::config->get("service.instanceID");
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $db_password =~ s/\n$//g;
+
+ my $params = "uid=" . $uid . "&" .
+ "name=" . $name . "&" .
+ "certificate=" .
+ URI::Escape::uri_escape("$certificate") . "&" .
+ "xmlOutput=true" . "&" .
+ "sessionID=" . $session_id . "&" .
+ "auth_hostname=" . $sdom_info->host . "&" .
+ "auth_port=" . $sdom_info->port;
+
+ my $host = $url_info->host;
+ my $port = $url_info->port;
+ my $tmpfile = "/tmp/donepanel-$$";
+ if (($tokenname eq "") || ($tokenname eq "NSS Certificate DB")) {
+ system("/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"$db_password\" -v -n \"$nickname\" -r \"$uri\" $host:$port > $tmpfile");
+ } else {
+ system("/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"$token_pwd\" -v -n \"$nickname\" -r \"$uri\" $host:$port > $tmpfile");
+ }
+ my $content = `cat $tmpfile`;
+ system("rm $tmpfile");
+
+ &PKI::TPS::Wizard::debug_log("req = " . $content);
+ $content =~ /(\<XMLResponse\>.*\<\/XMLResponse\>)/;
+ $content = $1;
+
+ if (defined $content) {
+ &PKI::TPS::Wizard::debug_log("DonePanel: result " . $content);
+ } else {
+ &PKI::TPS::Wizard::debug_log("DonePanel: result undefined");
+ }
+}
+
+sub get_kra_transport_cert
+{
+ my ($sdom) = @_;
+
+ my $sdom_info = new URI::URL($sdom);
+
+ # register TPS to Security Domain
+ # submit request to CA
+ &PKI::TPS::Wizard::debug_log("DonePanel: Connecting to KRA");
+
+ my $krainfo = $::config->get("preop.krainfo.select");
+ my $krainfo_url = new URI::URL($krainfo);
+
+ my $machineName = $::config->get("service.machineName");
+ my $unsecurePort = $::config->get("service.unsecurePort");
+ my $securePort = $::config->get("service.securePort");
+ my $non_clientauth_securePort = $::config->get("service.non_clientauth_securePort");
+ my $session_id = $::config->get("preop.sessionID");
+
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+ my $tokenname = $::config->get("preop.module.token");
+ my $token_pwd = $::pwdconf->get($tokenname);
+ my $instanceID = $::config->get("service.instanceID");
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $db_password =~ s/\n$//g;
+
+ my $params = "sessionID=" . $session_id . "&" .
+ "auth_hostname=" . $sdom_info->host . "&" .
+ "auth_port=" . $sdom_info->port;
+
+ my $host = $krainfo_url->host;
+ my $port = $krainfo_url->port;
+ my $tmpfile = "/tmp/donepanel-$$";
+ if (($tokenname eq "") || ($tokenname eq "NSS Certificate DB")) {
+ system("/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"$db_password\" -v -r \"/kra/admin/kra/getTransportCert\" $host:$port > $tmpfile");
+ } else {
+ system("/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"$token_pwd\" -v -r \"/kra/admin/kra/getTransportCert\" $host:$port > $tmpfile");
+ }
+ my $content = `cat $tmpfile`;
+ system("rm $tmpfile");
+
+ $content =~ /(\<XMLResponse\>.*\<\/XMLResponse\>)/;
+ $content = $1;
+
+ my $parser = XML::Simple->new();
+ my $response = $parser->XMLin($content);
+ my $transportCert = $response->{TransportCert};
+
+ &PKI::TPS::Wizard::debug_log("DonePanel: TransportCert " . $transportCert);
+
+ return $transportCert;
+}
+
+sub send_kra_transport_cert
+{
+ my ($sdom, $certificate) = @_;
+
+ my $sdom_info = new URI::URL($sdom);
+
+ # register TPS to Security Domain
+ # submit request to CA
+ &PKI::TPS::Wizard::debug_log("DonePanel: Connecting to TKS");
+ my $tksinfo = $::config->get("preop.tksinfo.select");
+ my $tksinfo_url = new URI::URL($tksinfo);
+
+ my $machineName = $::config->get("service.machineName");
+ my $unsecurePort = $::config->get("service.unsecurePort");
+ my $securePort = $::config->get("service.securePort");
+ my $non_clientauth_securePort = $::config->get("service.non_clientauth_securePort");
+ my $session_id = $::config->get("preop.sessionID");
+
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+ my $tokenname = $::config->get("preop.module.token");
+ my $token_pwd = $::pwdconf->get($tokenname);
+ my $instanceID = $::config->get("service.instanceID");
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $db_password =~ s/\n$//g;
+
+ my $name = "transportCert-" . $machineName . "-" . $securePort;
+ my $params = "name=" . $name . "&" .
+ "certificate=" .
+ URI::Escape::uri_escape("$certificate") . "&" .
+ "xmlOutput=true" . "&" .
+ "sessionID=" . $session_id . "&" .
+ "auth_hostname=" . $sdom_info->host . "&" .
+ "auth_port=" . $sdom_info->port;
+
+ my $host = $tksinfo_url->host;
+ my $port = $tksinfo_url->port;
+ my $tmpfile = "/tmp/donepanel-$$";
+ if (($tokenname eq "") || ($tokenname eq "NSS Certificate DB")) {
+ system("/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"$db_password\" -v -r \"/tks/admin/tks/importTransportCert\" $host:$port > $tmpfile");
+ } else {
+ system("/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"$token_pwd\" -v -r \"/tks/admin/tks/importTransportCert\" $host:$port > $tmpfile");
+ }
+
+ my $content = `cat $tmpfile`;
+ system("rm $tmpfile");
+
+ $content =~ /(\<XMLResponse\>.*\<\/XMLResponse\>)/;
+ $content = $1;
+
+ &PKI::TPS::Wizard::debug_log("DonePanel: Response from TKS " . $content);
+}
+
+sub display
+{
+ my ($q) = @_;
+ # $symbol{systemType} = "tps";
+ # $symbol{host} = "chico";
+ # $symbol{port} = "443";
+ &PKI::TPS::Wizard::debug_log("DonePanel: display");
+
+ my $status = defined($::config->get("preop.done.status"))? $::config->get("preop.done.status") : "";
+ if ($status eq "done") {
+ return 1;
+ }
+
+ my $instDir = $::config->get("service.instanceDir");
+ my $tokenname = $::config->get("preop.module.token");
+ my $token_pwd = $::pwdconf->get($tokenname);
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+ if (($tokenname ne "") && ($tokenname ne "NSS Certificate DB")) {
+ open(PWD_CONF, ">>$instDir/conf/password.conf");
+ print PWD_CONF "$tokenname:$token_pwd\n";
+ close (PWD_CONF);
+ }
+
+ # Add this TPS's server certificate to the subsystems
+ my $sdom = $::config->get("config.sdomainEEURL");
+ my $cainfo = $::config->get("preop.cainfo.select");
+ $cainfo =~ s/.* - //g;
+ &register_tps($sdom, $cainfo, "/ca/admin/ca/registerUser", "CA");
+ my $tksinfo = $::config->get("preop.tksinfo.select");
+ &register_tps($sdom, $tksinfo, "/tks/admin/tks/registerUser", "TKS");
+
+ my $keygen = $::config->get("conn.tks1.serverKeygen");
+ if ($keygen ne "false") {
+ &PKI::TPS::Wizard::debug_log("DonePanel: KRA available");
+ my $krainfo = $::config->get("preop.krainfo.select");
+ &register_tps($sdom, $krainfo, "/kra/admin/kra/registerUser", "KRA");
+ my $transportCert = &get_kra_transport_cert($sdom);
+ &send_kra_transport_cert($sdom, $transportCert);
+ } else {
+ &PKI::TPS::Wizard::debug_log("DonePanel: No KRA setup");
+ }
+
+ # Give Object Signing capability to audit_signing cert
+ open FILE, ">$instDir/conf/.pwfile";
+ system( "chmod 00660 $instDir/conf/.pwfile" );
+ $token_pwd =~ s/\n//g;
+ print FILE $token_pwd;
+ close FILE;
+ my $hw;
+ if (($tokenname eq "") || ($tokenname eq "NSS Certificate DB")) {
+ $hw = "";
+ } else {
+ $hw = "-h $tokenname";
+ }
+ my $auditSigningNickname = $::config->get("preop.cert.audit_signing.nickname");
+ my $tmp = `/usr/bin/certutil -d "$instDir/alias" -M $hw -f "$instDir/conf/.pwfile" -n "$auditSigningNickname" -t "u,u,Pu"`;
+ $tmp = `rm $instDir/conf/.pwfile`;
+
+ $::config->put("preop.done.status", "done");
+ $::config->put("tps.configured", "true");
+ $::config->commit();
+
+ # update httpd.conf
+ open(TMP_HTTPD_CONF, ">$instDir/conf/httpd.conf.tmp");
+ system( "chmod 00660 $instDir/conf/httpd.conf.tmp" );
+ open(HTTPD_CONF, "<$instDir/conf/httpd.conf");
+ while (<HTTPD_CONF>) {
+ if (/^#\[ErrorDocument_404\]/) {
+ print TMP_HTTPD_CONF "ErrorDocument 404 /404.html\n";
+ } elsif (/^#\[ErrorDocument_500\]/) {
+ print TMP_HTTPD_CONF "ErrorDocument 500 /500.html\n";
+ } else {
+ print TMP_HTTPD_CONF $_;
+ }
+ }
+ close(HTTPD_CONF);
+ close(TMP_HTTPD_CONF);
+
+ # Create a copy of the original file which
+ # preserves the original file permissions
+ system( "cp -p $instDir/conf/httpd.conf.tmp $instDir/conf/httpd.conf" );
+
+ # Remove the original file only if the backup copy was successful
+ if( -e "$instDir/conf/httpd.conf" ) {
+ system( "rm $instDir/conf/httpd.conf.tmp" );
+ }
+
+ # update nss.conf
+ open(TMP_NSS_CONF, ">$instDir/conf/nss.conf.tmp");
+ system( "chmod 00660 $instDir/conf/nss.conf.tmp" );
+ open(NSS_CONF, "<$instDir/conf/nss.conf");
+ while (<NSS_CONF>) {
+ if (/^NSSNickname/) {
+ print TMP_NSS_CONF "NSSNickname \"$nickname\"\n";
+ } else {
+ print TMP_NSS_CONF $_;
+ }
+ }
+ close(NSS_CONF);
+ close(TMP_NSS_CONF);
+
+ # Create a copy of the original file which
+ # preserves the original file permissions
+ system( "cp -p $instDir/conf/nss.conf.tmp $instDir/conf/nss.conf" );
+
+ # Remove the original file only if the backup copy was successful
+ if( -e "$instDir/conf/nss.conf" ) {
+ system( "rm $instDir/conf/nss.conf.tmp" );
+ }
+
+ &PKI::TPS::Wizard::debug_log("DonePanel: Connecting to Security Domain");
+
+ my $machineName = $::config->get("service.machineName");
+ my $unsecurePort = $::config->get("service.unsecurePort");
+ my $securePort = $::config->get("service.securePort");
+ my $non_clientauth_securePort = $::config->get("service.non_clientauth_securePort");
+ my $instanceID = $::config->get("service.instanceID");
+
+ my $initDaemon = "pki-tpsd";
+ my $initCommand = "";
+ if( $^O eq "linux" ) {
+ $initCommand = "/sbin/service $initDaemon";
+ } else {
+ ## default case: e. g. - ( $^O eq "solaris" )
+ $initCommand = "/etc/init.d/$initDaemon";
+ }
+
+ $::symbol{host} = $machineName;
+ $::symbol{unsecurePort} = $unsecurePort;
+ $::symbol{port} = $securePort;
+ $::symbol{non_clientauth_port} = $non_clientauth_securePort;
+ $::symbol{initCommand} = $initCommand;
+ $::symbol{instanceID} = $instanceID;
+
+ $::config->deleteSubstore("preop.");
+ $::config->commit();
+
+ ## Create an empty file that designates the fact that although
+ ## this server instance has been configured, it has NOT yet
+ ## been restarted!
+ my $restart_server = "$instDir/conf/restart_server_after_configuration";
+ system( "touch $restart_server" );
+ system( "chmod 00660 $restart_server" );
+
+ return 1;
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.donepanel.done");
+}
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/GlobalVar.pm b/base/tps/lib/perl/PKI/TPS/GlobalVar.pm
new file mode 100755
index 000000000..73e7b831a
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/GlobalVar.pm
@@ -0,0 +1,41 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+
+package PKI::TPS::GlobalVar;
+$PKI::TPS::GlobalVar::VERSION = '1.00';
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ my %args = (@_);
+ foreach my $q (keys %args) {
+ $self->{$q} = $args{$q};
+ }
+ bless $self,$class;
+ return $self;
+}
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/ImportAdminCertPanel.pm b/base/tps/lib/perl/PKI/TPS/ImportAdminCertPanel.pm
new file mode 100755
index 000000000..dfec6ea80
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/ImportAdminCertPanel.pm
@@ -0,0 +1,163 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+use URI::URL;
+
+package PKI::TPS::ImportAdminCertPanel;
+$PKI::TPS::ImportAdminCertPanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(15);
+ $self->{"getName"} = &PKI::TPS::Common::r("Import Administrator Certificate");
+ $self->{"vmfile"} = "importadmincertpanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("ImportAdminCertPanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("ImportAdminCertPanel: update");
+
+ # register to Security Domain
+ my $sdom = $::config->get("config.sdomainAgentURL");
+ my $sdom_url = new URI::URL($sdom);
+
+ #
+ # we need to authenticate to the security domain with the subsystem
+ # certificate
+ #
+ my $machineName = $::config->get("service.machineName");
+ my $instanceID = $::config->get("service.instanceID");
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $securePort = $::config->get("service.securePort");
+ my $subsystemName = $::config->get("preop.subsystem.name");
+ my $tokenname = $::config->get("preop.module.token");
+ my $token_pwd = $::pwdconf->get($tokenname);
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ my $name = $subsystemName;
+ my $subCertNickName = $::config->get("preop.cert.subsystem.nickname");
+
+ $db_password =~ s/\n$//g;
+
+ my $params = "list=" . "TPSList" . "&" .
+ "type=" . "TPS" . "&" .
+ "host=" . $machineName . "&" .
+ "name=" . $name . "&" .
+ "sport=" . $securePort . "&" .
+ "dm=false"; # domain manager or not
+
+ my $sd_host = $sdom_url->host;
+ my $sd_agent_port = $sdom_url->port;
+ my $cmd;
+ if (($tokenname eq "") || ($tokenname eq "NSS Certificate DB")) {
+ $cmd = `/usr/bin/sslget -d \"$instanceDir/alias\" -p \"$db_password\" -v -n \"$subCertNickName\" -r \"/ca/agent/ca/updateDomainXML\" -e \"$params\" $sd_host:$sd_agent_port`;
+ } else {
+ $cmd = `/usr/bin/sslget -d \"$instanceDir/alias\" -p \"$token_pwd\" -v -n \"$subCertNickName\" -r \"/ca/agent/ca/updateDomainXML\" -e \"$params\" $sd_host:$sd_agent_port`;
+ }
+
+ # Fetch the "updated" security domain and display it
+ &PKI::TPS::Wizard::debug_log("ImportAdminCertPanel: Dump contents of updated Security Domain . . .");
+ my $sdomainAdminURL = $::config->get("config.sdomainAdminURL");
+ my $sdom_info = new URI::URL($sdomainAdminURL);
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+ $sd_host = $sdom_info->host;
+ my $sd_admin_port = $sdom_info->port;
+ my $content;
+ if (($tokenname eq "") || ($tokenname eq "NSS Certificate DB")) {
+ $content = `/usr/bin/sslget -d \"$instanceDir/alias\" -p \"$db_password\" -v -r \"/ca/admin/ca/getDomainXML\" $sd_host:$sd_admin_port`;
+ } else {
+ $content = `/usr/bin/sslget -d \"$instanceDir/alias\" -p \"$token_pwd\" -v -r \"/ca/admin/ca/getDomainXML\" $sd_host:$sd_admin_port`;
+ }
+ $content =~ /(\<XMLResponse\>.*\<\/XMLResponse\>)/;
+ $content = $1;
+ &PKI::TPS::Wizard::debug_log($content);
+
+ $::config->put("preop.importadmincert.done", "true");
+ $::config->commit();
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("ImportAdminCertPanel: display");
+
+ my $cainfo = $::config->get("preop.cainfo.select");
+
+ my $cainfo_url = new URI::URL($cainfo);
+ my $serialNumber = $::config->get("preop.admincert.serialno.0");
+
+ $::symbol{info} = "";
+ $::symbol{errorString} = "";
+ $::symbol{import} = "true";
+ $::symbol{ca} = "false";
+ $::symbol{caType} = "ca";
+ $::symbol{caHost} = $cainfo_url->host;
+ $::symbol{caPort} = $cainfo_url->port;
+ $::symbol{serialNumber} = $serialNumber;
+
+ return 1;
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.importadmincert.done");
+}
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/Login.pm b/base/tps/lib/perl/PKI/TPS/Login.pm
new file mode 100755
index 000000000..01aa01f42
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/Login.pm
@@ -0,0 +1,466 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+# wizard -
+# Fedora Certificate System - Token Processing System configuration wizard
+
+
+# This script is run as a 'mod_perl' CGI. Configure mod_perl by adding
+# the following to /etc/httpd/conf.d/perl.conf
+#
+# PerlModule ModPerl::Registry
+# PerlModule Apache::compat
+# PerlModule RHCS::TPS::Wizard
+# PerlSetEnv RHCS_DOCROOT /u/sparkins/t/cs_tip/certsystem/prj/common/ui
+# <Location /wizard>
+# SetHandler perl-script
+# PerlHandler RHCS::TPS::Wizard
+# Order deny,allow
+# Allow from all
+# </Location>
+
+
+# Note: The Velocity parser is not very helpful when it comes to
+# errors right now. Here are some common errors, and what they mean:
+#
+# ERROR:
+# [Mon Apr 03 13:57:33 2006] [error] [client 172.16.24.26]
+# Can't use string ("0") as an ARRAY ref while "strict refs"
+# in use at /usr/lib/perl5/site_perl/5.8.5/Template/Velocity.pm
+# line 423.\n, referer: http://chico/wizard?p=2
+# MEANING
+# This probably means that your *.vm file refers to an array
+# variable in a foreach statement that is not defined
+# Check your foreach array variables.
+
+use warnings;
+use ModPerl::Registry;
+use Template::Velocity;
+use Getopt::Std;
+use Data::Dumper;
+use CGI::Carp qw(fatalsToBrowser);
+use CGI;
+use APR::Const -compile => qw(:error SUCCESS);
+use PKI::TPS::GlobalVar;
+use PKI::TPS::WelcomePanel;
+use PKI::TPS::SecurityDomainPanel;
+use PKI::TPS::DisplayCertChainPanel;
+use PKI::TPS::SubsystemTypePanel;
+use PKI::TPS::CAInfoPanel;
+use PKI::TPS::TKSInfoPanel;
+use PKI::TPS::DRMInfoPanel;
+use PKI::TPS::DisplayCertChain2Panel;
+use PKI::TPS::AdminAuthPanel;
+use PKI::TPS::AgentAuthPanel;
+use PKI::TPS::AuthDBPanel;
+use PKI::TPS::DatabasePanel;
+use PKI::TPS::ModulePanel;
+use PKI::TPS::SizePanel;
+use PKI::TPS::NamePanel;
+use PKI::TPS::ConfigHSMLoginPanel;
+use PKI::TPS::CertRequestPanel;
+use PKI::TPS::AdminPanel;
+use PKI::TPS::ImportAdminCertPanel;
+use PKI::TPS::LoginPanel;
+use PKI::TPS::DonePanel;
+use PKI::TPS::Config;
+
+use PKI::TPS::Common qw(yes no r);
+
+package PKI::TPS::Login;
+$PKI::TPS::Login::VERSION = '1.00';
+
+# read configuration file
+my $flavor = "pki";
+$flavor =~ s/\n//g;
+
+my $pkiroot = $ENV{PKI_ROOT};
+
+my $config = PKI::TPS::Config->new();
+$config->load_file("$pkiroot/conf/CS.cfg");
+# read password cache file
+my $pwdconf = PKI::TPS::Config->new();
+$pwdconf->load_file("$pkiroot/conf/pwcache.conf");
+# SELinux disallows performing a "chmod" on this file
+if( $^O ne "linux" ) {
+ system( "chmod 00660 $pkiroot/conf/pwcache.conf" );
+}
+
+# create cfg debug log
+my $logfile = $config->get("service.instanceDir") . "/logs/debug";
+open( DEBUG, ">>" . $logfile ) ||
+warn( "Could not open '" . $logfile . "': $!" );
+
+# apache server
+
+our $debug;
+
+my $STATUS_OK = 1;
+my $STATUS_ERROR = 2;
+my $STATUS_REDIRECT = 3;
+
+&debug_log("TPS wizard: starting up");
+
+my $docroot = $ENV{PKI_DOCROOT};
+
+if (! $docroot) {
+ &debug_log("TPS wizard: ERROR: PKI_DOCROOT is null");
+ return 0;
+}
+
+our $parser = new Template::Velocity($docroot);
+our $symbol;
+our @certtags;
+
+makepanels();
+
+&debug_log("TPS wizard: start up complete");
+
+1;
+
+sub debug_log
+{
+ my ($msg) = @_;
+ my $date = `date`;
+ chomp($date);
+ if( -w $logfile ) {
+ print DEBUG "$date - $msg\n";
+ }
+}
+
+ # initializes entries in parser's global symbol table for panels
+sub makepanels
+{
+ #REAL PANELS BELOW
+ my $login = new PKI::TPS::LoginPanel();
+
+ $symbol{panels} = [
+ $login, # com.netscape.cms.servlet.csadmin.WelcomePanel
+ ];
+};
+
+sub render_panel
+{
+ my ($panelnum, $q) = @_;
+
+ $symbol{errorString} = "";
+
+ my $currentpanel;
+
+ if ($q->param('op') && $q->param('op') eq "next") {
+ $currentpanel = $symbol{panels}[$panelnum];
+ # validate variables for panel
+ if ($currentpanel->{validate}) {
+ $currentpanel->{validate}($q);
+ }
+ # execute current panel
+ my $status = "0";
+
+ if ($currentpanel->{update}) {
+ $status = $currentpanel->{update}($q);
+ &debug_log("TPS wizard: update returns status '" .
+ $status . "'");
+ if ($status == $STATUS_REDIRECT) {
+ return $STATUS_REDIRECT;
+ }
+
+ }
+
+ &debug_log("TPS wizard: about to find out about sub panel");
+ if ($status eq "1") {
+ if ($currentpanel->{hasSubPanel} && &{$currentpanel->{hasSubPanel}}($q)) {
+ &debug_log("TPS wizard: has sub panel");
+ $panelnum = $panelnum + 2;
+ } elsif ($currentpanel->{isSubPanel} && &{$currentpanel->{isSubPanel}}($q)) {
+ &debug_log("TPS wizard: is sub panel");
+ $panelnum = $panelnum - 1;
+ } else {
+ &debug_log("TPS wizard: no sub panel and is not subpanel");
+ $panelnum = $panelnum + 1;
+ }
+ }
+ } elsif ($q->param('op') && $q->param('op') eq "back") {
+ $panelnum = $panelnum - 1;
+ #check if this a subpanel, if so, go back to it's parent.
+ #only handles one-deep at this point
+ my $panel = $symbol{panels}[$panelnum];
+ if (&{$panel->{isSubPanel}}($q)) {
+ $panelnum = $panelnum - 1;
+ }
+ } elsif ($q->param('op') && $q->param('op') eq "apply") {
+ &debug_log("TPS wizard: update : apply button pressed");
+ $currentpanel = $symbol{panels}[$panelnum];
+ # validate variables for panel
+ if ($currentpanel->{validate}) {
+ $currentpanel->{validate}($q);
+ }
+ # execute current panel
+ if ($currentpanel->{update}) {
+ my $status = $currentpanel->{update}($q);
+ &debug_log("TPS wizard: update returns status '" .
+ $status . "'");
+ if ($status == $STATUS_REDIRECT) {
+ return $STATUS_REDIRECT;
+ }
+
+ }
+ }
+
+ &debug_log("TPS wizard: after looking into about sub panel");
+
+ # advance to next panel
+ $currentpanel = $symbol{panels}[$panelnum];
+
+ # initialize symbol table values
+ $symbol{showApplyButton} = "false";
+
+ # fill in variables for new panel
+ if ($currentpanel->{panelvars}) {
+ $Data::Dumper::Indent = 1;
+ # The '&debug_log("q=".Dumper($q));' call must be commented out to fix
+ # Bugzilla Bug #249923: Incorrect file permissions on
+ # various files and/or directories
+ # &debug_log("q=".Dumper($q));
+ $currentpanel->{panelvars}($q);
+ }
+
+ $symbol{panel} = "tps/admin/console/config/".$currentpanel->{vmfile};
+
+ #wizard.vm:
+ $symbol{name} = "Token Processing System";
+ $symbol{title} = $currentpanel->{getName}();
+ if ($panelnum == 0) {
+ $symbol{firstpanel} = "1";
+ } else {
+ $symbol{firstpanel} = "0";
+ }
+ if ($panelnum == 17) {
+ $symbol{lastpanel} = "1";
+ } else {
+ $symbol{lastpanel} = "0";
+ }
+ $symbol{p} = $panelnum;
+ $symbol{subpanelno} = $panelnum+1;
+ $symbol{csstate} = "1";
+
+# $symbol{urls} = [ "cert1", "cert2" ]; #createsubsystem
+# $symbol{urls_size} = 2;
+# $symbol{instanceId} = "tps";
+# $symbol{errorString} = "";
+
+ #modulepanel
+# $symbol{certs} = [ ];
+# $symbol{reqscerts} = [ ];
+ $symbol{ppcerts} = [ ];
+
+ return $STATUS_OK;
+}
+
+
+
+sub dbg {
+ my $msg = shift;
+ $::symbol{dbg} .= "$msg\n";
+}
+
+sub handler {
+ my $r = shift;
+
+ *::symbol = \%symbol;
+ *::s = \$s;
+ *::config = \$config;
+ *::pwdconf = \$pwdconf;
+
+ &debug_log("TPS wizard: in handler");
+ if ($#ARGV == -1) {
+ $r->send_http_header('text/html');
+ }
+
+ my $q = new CGI;
+
+ # check cookie
+ my $pin = $q->param('pin');
+ if (defined($pin)) {
+ my $cookie = $q->cookie(
+ -name=>'pin',
+ -value=> $pin,
+ -expires=>'+1y',
+ -path=>'/');
+ print $q->redirect(-location => "wizard", -cookie => $cookie);
+ return;
+ }
+
+ # output http parameters
+ &debug_log("TPS wizard: uri='" . $ENV{REQUEST_URI} . "'");
+ my @pnames = $q->param();
+ foreach $pn (@pnames) {
+ # 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 =~ /^__/ ||
+ $pn =~ /password$/ ||
+ $pn =~ /passwd$/ ||
+ $pn =~ /pwd$/ ||
+ $pn =~ /admin_password_again/i ||
+ $pn =~ /directoryManagerPwd/i ||
+ $pn =~ /bindpassword/i ||
+ $pn =~ /bindpwd/i ||
+ $pn =~ /passwd/i ||
+ $pn =~ /password/i ||
+ $pn =~ /pin/i ||
+ $pn =~ /pwd/i ||
+ $pn =~ /pwdagain/i ||
+ $pn =~ /uPasswd/i ) {
+ &debug_log("TPS wizard: http parameter name='" . $pn . "' value='(sensitive)'");
+ } else {
+ &debug_log("TPS wizard: http parameter name='" . $pn . "' value='" . $q->param($pn) . "'");
+ }
+ }
+
+ my $panelnum = $q->param('p');
+ if (!defined($panelnum) || $panelnum eq "") {
+ # Apache fails to pick up the p parameter after
+ # redirecting from the security domain. This is
+ # a quick hack to solve the issue.
+ if ($ENV{'QUERY_STRING'} ne "") {
+ $ENV{'QUERY_STRING'} =~ /p=([0-9]+)&/;
+ $panelnum = $1;
+ }
+ }
+
+ use subs qw(debug);
+ *debug = \&Template::Velocity::Executor::debug;
+
+ $::symbol{dbg} = "";
+
+ &debug_log("TPS wizard: before argparsing");
+ if ($#ARGV == -1) {
+ $Data::Dumper::Maxdepth = 7;
+ $startfile = "tps/admin/console/config/login.vm";
+ }
+
+ &debug_log("TPS wizard: setting up test objects");
+
+ #initialize from config file
+ my $certlist = $::config->get("preop.cert.list");
+ if ($certlist eq "") {
+ $certlist = "sslserver,subsystem";
+ }
+ @certtags = split(/,/, $certlist);
+ $numtags = @certtags;
+ if ($numtags eq 0) {
+ @certtags = ("sslserver", "subsystem");
+ }
+ &debug_log("TPS wizard: found $numtags certtags");
+
+ if (! $panelnum) {
+ $panelnum = 0;
+ }
+
+ my $status = render_panel($panelnum, $q);
+ if ($status == 3) {
+ $r->header_out(Location => $symbol{redirect});
+ $r->status(301);
+ $r->send_http_header();
+ return;
+ }
+
+ use Data::Dumper;
+ &debug_log("TPS wizard: executing file $startfile");
+ foreach $q (sort keys %symbol) {
+ &debug_log("TPS wizard:/config/wizard?p=9&SecToken=NSS%20Generic%20Crypto%20Services sym{$q}=".$symbol{$q});
+ }
+
+ my $result;
+ if ($q->param("xml") eq "true") {
+ $r->send_http_header('text/xml');
+ $result = "<xml>";
+ foreach $s (sort keys %symbol) {
+ if ($s =~ /^__/) {
+ next;
+ }
+ $result .= "<" . $s . ">";
+ my $v = $symbol{$s};
+ $result .= &get_xml($s, $v);
+ $result .= "</" . $s . ">";
+ }
+ $result .= "</xml>";
+ } else {
+ $result = $parser->execute_file($startfile);
+ if (!defined $result) {
+ die("Couldn't execute template file: $docroot/$startfile");
+ }
+ }
+
+ print "$result\n";
+ return $STATUS_OK;
+}
+
+sub get_xml
+{
+ my ($s, $v) = @_;
+
+ my $result;
+ if (ref($v) eq "HASH") {
+ foreach my $xkey (keys %$v) {
+ $result .= "<" . $xkey . ">";
+ $result .= &get_xml($xkey, $v{$xkey});
+ # $result .= "-" . ref($xkey);
+ $result .= "</" . $xkey . ">";
+ }
+ } elsif (ref($v) eq "PKI::TPS::CertInfo") {
+ my $certinfo = $v;
+ $result .= "<certinfo>";
+ $result .= "<dn>" . $certinfo->get_dn() ."</dn>";
+ $result .= "<tag>" . $certinfo->get_cert_tag() . "</tag>";
+ $result .= "<friendly>" . $certinfo->get_user_friendly_name() .
+ "</friendly>";
+ $result .= "</certinfo>";
+ } elsif (ref($v) eq "PKI::TPS::ReqCertInfo") {
+ my $reqcertinfo = $v;
+ $result .= "<reqcertinfo>";
+ $result .= "<name>" . $reqcertinfo->get_user_friendly_name() ."</name>";
+ $result .= "<req>" . $reqcertinfo->get_request() ."</req>";
+ $result .= "<cert>" . $reqcertinfo->get_cert() ."</cert>";
+ $result .= "<certpp>" . $reqcertinfo->get_cert_pp() ."</certpp>";
+ $result .= "<tag>" . $reqcertinfo->get_cert_tag() ."</tag>";
+ $result .= "<dn>" . $reqcertinfo->get_cert_tag() ."</dn>";
+ $result .= "</reqcertinfo>";
+ } elsif (ref($v) eq "ARRAY") {
+ my $pos = 0;
+ foreach my $item (@$v) {
+ $result .= "<element>";
+ $result .= &get_xml("p" . $pos, $item);
+ # $result .= "-" . ref($item);
+ $result .= "</element>";
+ $pos++;
+ }
+ } else {
+ $result .= $v;
+ }
+ return $result;
+}
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/LoginPanel.pm b/base/tps/lib/perl/PKI/TPS/LoginPanel.pm
new file mode 100755
index 000000000..d6592d46e
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/LoginPanel.pm
@@ -0,0 +1,98 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+
+package PKI::TPS::LoginPanel;
+$PKI::TPS::LoginPanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(0);
+ $self->{"getName"} = &PKI::TPS::Common::r("Welcome");
+ $self->{"vmfile"} = "login.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("WelcomePanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("WelcomePanel: update");
+ $::config->put("preop.loginpanel.done", "true");
+ $::config->commit();
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log($ENV{'SERVER_PORT'});
+ &PKI::TPS::Wizard::debug_log("Debug=" . $::config->get("logging.debug.enable"));
+ &PKI::TPS::Wizard::debug_log("WelcomePanel: display");
+ $::symbol{wizardname} = "TPS Configuration Wizard";
+ $::symbol{systemname} = "TPS";
+ $::symbol{fullsystemname} = "Token Processing System";
+
+ return 1;
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.loginpanel.done");
+}
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/ModulePanel.pm b/base/tps/lib/perl/PKI/TPS/ModulePanel.pm
new file mode 100755
index 000000000..5e7089812
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/ModulePanel.pm
@@ -0,0 +1,278 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+use PKI::TPS::Modutil;
+
+package PKI::TPS::ModulePanel;
+$PKI::TPS::ModulePanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+our $modutil;
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(9);
+ $self->{"getName"} = &PKI::TPS::Common::r("Security Modules");
+ $self->{"vmfile"} = "modulepanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+
+ my $flavor = "pki";
+ $flavor =~ s/\n//g;
+
+ my $pkiroot = $ENV{PKI_ROOT};
+ $modutil = new PKI::TPS::Modutil("$pkiroot/alias");
+
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 1;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ my $defTok = $::config->get("preop.module.token");
+ my $select = $q->param('choice');
+ if ($select eq "") {
+ &PKI::TPS::Wizard::debug_log("ModulePanel -> update no selection found");
+ $::symbol{errorString} = "No selection found";
+ return 0;
+ } elsif ($defTok ne $select) {
+ &PKI::TPS::Wizard::debug_log("ModulePanel -> update changing defTok to $select");
+ $::config->put("preop.module.token", $select);
+ } else {
+ # this is not an error...just information
+ &PKI::TPS::Wizard::debug_log("ModulePanel -> update defTok not changed");
+ }
+
+ $::config->put("preop.ModulePanel.done", "true");
+
+ $::config->commit();
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("ModulePanel -> display");
+ getModules();
+ my $defTok = $::config->get("preop.module.token");
+
+ $::symbol{defTok} = $defTok;
+
+ return 1;
+}
+
+use Data::Dumper;
+sub getTokens {
+ my $modulename = shift;
+
+ &PKI::TPS::Wizard::debug_log("ModulePanel -> getTokens");
+
+#$Data::Dumper::Indent = 0;
+#PKI::TPS::Wizard::dbg("in gettokens. modutil = ".Dumper($modutil));
+ my @tokens;
+ my $mod = $modutil->getmodule($modulename);
+ foreach my $tokenname (keys %{$mod->{tokens}}) {
+ #PKI::TPS::Wizard::dbg("found token $tokenname");
+ if ($tokenname ne "NSS Generic Crypto Services") {
+ my $token = $modutil->gettoken($tokenname);
+ my $t = new PKI::TPS::GlobalVar(
+ getNickName => sub { return $tokenname; },
+ isLoggedIn => sub { return isLoggedIn($tokenname); },
+ isPresent => sub { return 1; },
+ );
+ push @tokens, $t;
+ } else {
+ &PKI::TPS::Wizard::debug_log("ModulePanel -> getTokens token NSS Generic Crypto Services not available for key generation");
+
+ }
+ }
+
+ return \@tokens;
+}
+
+# if password is found, then it's considered "logged in"
+# otherwise it is "not logged in"
+sub Login {
+ my $tokenname = $_[0];
+ my $pwd = defined($::pwdconf->get($tokenname)) ? $::pwdconf->get($tokenname) : "";
+ if ($pwd ne "") {
+ &PKI::TPS::Wizard::debug_log("ModulePanel -> isLoggedIn retrieved pwd from pwdconf");
+ return 1;
+ }
+ &PKI::TPS::Wizard::debug_log("ModulePanel -> isLoggedIn pwd not found from pwdconf for token: $tokenname");
+
+ if ($tokenname eq "NSS Certificate DB") {
+ my $instanceDir = $::config->get("service.instanceDir");
+ &PKI::TPS::Wizard::debug_log("ModulePanel -> isLoggedIn get internal password for $tokenname");
+ # these are referred as "internal" in password.conf
+ $pwd = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $pwd =~ s/\n//g;
+ $::pwdconf->put($tokenname, $pwd);
+ $::pwdconf->commit();
+
+ return 1;
+ }
+ return 0;
+}
+
+sub isLoggedIn {
+ my $tokenname = $_[0];
+ return &Login($tokenname);
+}
+
+sub getModules {
+ my $count;
+ my $i;
+ my @supportedModules;
+
+ &PKI::TPS::Wizard::debug_log("ModulePanel -> getModules");
+ $count = $::config->get("preop.configModules.count");
+ &PKI::TPS::Wizard::debug_log("ModulePanel -> getModules count =$count");
+
+ my @modules = $modutil->getmodules();
+ # $::symbol{steve} = join ",Module:", @modules;
+ # $::symbol{steve}.= "\n";
+
+ my $x = "
+ preop.configModules.count=3
+ preop.configModules.module0.commonName=NSS Internal PKCS #11 Module
+ preop.configModules.module0.imagePath=../img/mozilla.png
+ preop.configModules.module0.userFriendlyName=NSS Internal PKCS #11 Module
+ preop.configModules.module1.commonName=nfast
+ preop.configModules.module1.imagePath=../img/ncipher.png
+ preop.configModules.module1.userFriendlyName=nCipher's nFast Token Hardware Module
+ preop.configModules.module2.commonName=lunasa
+ preop.configModules.module2.imagePath=../img/safenet.png
+ preop.configModules.module2.userFriendlyName=SafeNet's LunaSA Token Hardware Module
+ ";
+
+ my %supmodules;
+ for ($i=0; $i <$count; $i++) {
+ my $cn;
+ my $pn;
+ my $img;
+# &PKI::TPS::Wizard::debug_log("ModulePanel -> getModules look for cn=","preop.configModules.module" , $i , ".commonName");
+ $cn = $::config->get("preop.configModules.module$i.commonName");
+ $supmodules{$cn} = 1;
+
+ $pn = $::config->get("preop.configModules.module$i.userFriendlyName");
+ $img = $::config->get("preop.configModules.module$i.imagePath");
+ &PKI::TPS::Wizard::debug_log("ModulePanel -> getModules: got module $cn from config");
+
+ my $module = $modutil->getmodule($cn);
+ my $file = $module->{detail}->{"Library file"};
+ &PKI::TPS::Wizard::debug_log("ModulePanel -> getModules Library file = $file");
+ my $found = 0;
+ if (defined $file) {
+ $found = ($file =~ /Internal ONLY module/) || -e $file;
+ }
+
+ my $name = $module->{detail}->{Name};
+# PKI::TPS::Wizard::dbg("name: $name");
+
+ $supportedModules[$i] = new PKI::TPS::GlobalVar(
+ getImagePath => sub { return $img; },
+ getUserFriendlyName => sub { return $pn; },
+ isFound => sub { return $found; },
+ getTokens => sub { return getTokens($name); },
+ );
+
+ # login to tokens
+ &PKI::TPS::Wizard::debug_log("Ready to login to tokens for $name");
+ my $mod = $modutil->getmodule($name);
+ foreach my $tokenname (keys %{$mod->{tokens}}) {
+ &PKI::TPS::Wizard::debug_log("Logging in Module $name Token " . $tokenname);
+ &Login($tokenname);
+ }
+
+ }
+
+ my @otherModules;
+ #compile the "others" modules
+
+ foreach my $modname (@modules) {
+ #is this modname in the supported modules list?
+ if ($supmodules{$modname}) {
+ &PKI::TPS::Wizard::debug_log("ModulePanel -> getModules: found module $modname supported");
+ # does not belong to "others"
+ } else {
+ &PKI::TPS::Wizard::debug_log("ModulePanel -> getModules: found module $modname unsupported");
+ #add the module to "others" list
+ my $m = $modutil->getmodule($modname);
+ my $mod = new PKI::TPS::GlobalVar(
+ getImagePath => sub { return ""; },
+ getUserFriendlyName => sub { return $m->{modulename}; },
+ isFound => sub { return 1; },
+ getTokens => sub { return getTokens($m->{detail}->{Name});}
+ );
+
+ push @otherModules, $mod;
+
+ &PKI::TPS::Wizard::debug_log("ModulePanel -> getModules: module $modname added to otherModules list");
+ }
+ }
+
+ $::symbol{sms} = \@supportedModules;
+ $::symbol{oms} = \@otherModules;
+# PKI::TPS::Wizard::dbg("oms: ". Dumper([@otherModules]));
+# PKI::TPS::Wizard::dbg("sms: ". Dumper([@supportedModules]));
+
+ &PKI::TPS::Wizard::debug_log("ModulePanel -> set sms, oms");
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.ModulePanel.done");
+}
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/Modutil.pm b/base/tps/lib/perl/PKI/TPS/Modutil.pm
new file mode 100755
index 000000000..49c248c2e
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/Modutil.pm
@@ -0,0 +1,263 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+
+package PKI::TPS::Modutil;
+
+
+sub new {
+ my $class = shift;
+ my ($dir) = @_;
+
+ if (! $dir) { die "no module directory provided\n"; }
+
+ my $self = {};
+
+ $self->{dir} = $dir;
+ $self->{modules} = makemodules($self);
+
+ bless $self, $class;
+ return $self;
+}
+
+sub exists {
+ my $self = shift;
+
+ return -e "$self->{dir}/secmod.db";
+}
+
+sub create {
+ my $self = shift;
+
+ my $mods = `modutil -force -dbdir '$self->{dir}' -nocertdb -create`;
+ return $mods;
+}
+
+use Data::Dumper;
+
+sub makemodules {
+ my $self = shift;
+ my $modules = {};
+
+ my $mods = `modutil -force -dbdir '$self->{dir}' -nocertdb -list`;
+ #my $mods = join "",<::DATA>;
+
+ #print "raw mods = $mods";
+
+ my (@modules) = (
+ $mods =~ /
+ ^ #beginning of a line
+ \s+ #some spaces
+ \d+\.\s* #some digits
+ (.*?) #lots of text
+ ((?=^\s*\d+)|(?=------)) #if we would next match some spaces and digits
+ /msxg );
+
+ @modules = grep /.+/ms, @modules;
+
+ foreach $module (@modules) {
+ #print "Module #$i:$module --\n";
+ $module = "modulename:$module";
+ my ($moduleheader, $rest) = (
+ $module =~ /
+ (.*status: .*?\n) # moduleheader
+ (\s*slot:.*) # slot
+ (?=\n(\n|$)) #empty line
+ /msxg );
+ #print "moduleheader: $moduleheader\n";
+ my $m = makehash($moduleheader);
+ $modules->{$m->{modulename}} = $m;
+ $m->{tokens} = {};
+
+ my @tokens = split "\n\n", $rest;
+
+
+
+# get summary slot info with: -list
+ foreach my $token (@tokens) {
+ #print "slottext: $slot\n";
+ my $slh = makehash($token);
+ $m->{tokens}->{$slh->{token}} = $slh;
+ }
+
+# get detailed slot info with: -list "modulename"
+
+ my $moduledetail = `modutil -force -dbdir '$self->{dir}' -nocertdb -list "$m->{modulename}" 2> /dev/null`;
+ my @details= split "\n\n", $moduledetail;
+ while ($details[0] !~ /.*Name:.*/) {
+ shift @details;
+ };
+
+ $m->{detail} = makehash(shift @details);
+ foreach $d (@details) {
+ my $sdh = makehash($d);
+ my $tokenname = $sdh->{"Token Name"};
+ $tokenname =~ s/\s+$//; # remove trailing spaces
+ if ($tokenname) {
+ $m->{tokens}->{$tokenname}->{detail} = $sdh;
+ }
+ }
+ $i++;
+
+ }
+ return $modules;
+}
+
+# input: a multi-list string with nv/pairs
+# return a hashtable reference
+sub makehash {
+ my $str = shift;
+ my $ht = { };
+ my @lines = split "\n", $str;
+ my $line;
+LINE:
+ foreach $line (@lines) {
+ if ($line =~ /Using database directory/) { next LINE; }
+ if ($line =~ /--------------/) { next LINE; }
+ my ($name, $value) = ($line =~ /^\s*(.*?):\s*(.*?)\s*$/);
+ if ($name) {
+ #print "name:$name\n";
+ #print "value:$value\n";
+ $ht->{$name} = $value;
+ }
+ }
+ return $ht;
+}
+
+sub getmodules {
+ my $self = shift;
+ #print "modules: ".$self->{modules}. "\n";
+ #print "keys: ".(join ",",keys %{$self->{modules}})."\n";
+ return keys %{$self->{modules}};
+}
+
+sub getmodule {
+ my $self = shift;
+ my $modulename = shift;
+
+ #print Dumper($self->{modules});
+ return $self->{modules}->{$modulename};
+}
+
+
+sub gettokens {
+ my $self = shift;
+ my $module = shift;
+
+ return keys %{$module->{tokens}};
+}
+
+sub gettoken {
+ my $self = shift;
+ my $token= shift;
+ foreach my $m (values %{$self->{modules}}) {
+ foreach $t (values %{$m->{tokens}}) {
+ #print join ",", keys %{$t};
+ #print Dumper($t->{detail});
+ if ($t->{detail}->{"Token Name"} eq $token) {
+ return $t;
+ }
+ }
+ }
+}
+
+
+
+package main;
+
+sub ::test {
+
+# initialize
+ my $modutil = new PKI::TPS::Modutil(".");
+
+#make database if it doesn't exist
+ if (! $modutil->exists()) {
+ $modutil->create();
+ }
+
+#get an array of module names
+ my @mods = $modutil->getmodules();
+
+ print "Found ".@mods." pkcs#11 modules\n";
+
+#for each module...
+ foreach my $modname (@mods) {
+ my $module = $modutil->getmodule($modname);
+
+ print "Module: $modname\n";
+ print "Library: ".$module->{detail}->{"Library file"}."\n";
+ print "Other keys: ".(join ",", keys %{$module->{detail}})."\n";
+
+#find all the tokens in a module, e.g. each partition for a lunasa
+ foreach my $tokenname ($modutil->gettokens($module)) {
+ print " token: $tokenname\n";
+ my $token = $modutil->gettoken($tokenname);
+
+#dump out the information we have on the token
+ foreach my $key (keys %{$token}) {
+ print " token keys/values: $key: ".$token->{$key}."\n";
+ }
+ my @detailkeys = (keys %{$token->{detail}}) ;
+ print " token detail keys:". (join ",", @detailkeys)."\n";
+ print " token detail Manufacturer:". $token->{detail}->{Manufacturer}."\n";
+ print "\n";
+ }
+ print "\n";
+ }
+
+}
+
+# this is where 'main' starts
+
+if ($ARGV[0] eq "--test") {
+ ::test();
+}
+
+1;
+
+__DATA__
+Listing of PKCS #11 Modules
+-----------------------------------------------------------
+ 1. NSS Internal PKCS #11 Module
+ slots: 2 slots attached
+ status: loaded
+
+ slot: NSS Internal Cryptographic Services
+ token: NSS Generic Crypto Services
+
+ slot: NSS User Private Key and Certificate Services
+ token: NSS Certificate DB
+
+ 2. lunasa
+ library name: /usr/lunasa/lib/libCryptoki2.so
+ slots: 2 slots attached
+ status: loaded
+
+ slot: LunaNet Slot
+ token: lunasa1-ca
+
+ slot: LunaNet Slot
+ token: lunasa2-ca
+-----------------------------------------------------------
+
+
diff --git a/base/tps/lib/perl/PKI/TPS/NamePanel.pm b/base/tps/lib/perl/PKI/TPS/NamePanel.pm
new file mode 100755
index 000000000..a474d80b9
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/NamePanel.pm
@@ -0,0 +1,611 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use FileHandle;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+use PKI::TPS::CertInfo;
+use URI::URL;
+use URI::Escape;
+
+package PKI::TPS::NamePanel;
+$PKI::TPS::NamePanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+our $cert_req_header="-----BEGIN NEW CERTIFICATE REQUEST-----";
+our $cert_req_footer="-----END NEW CERTIFICATE REQUEST-----";
+our $cert_header="-----BEGIN CERTIFICATE-----";
+our $cert_footer="-----END CERTIFICATE-----";
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(12);
+ $self->{"getName"} = &PKI::TPS::Common::r("Subject Names");
+ $self->{"vmfile"} = "namepanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("NamePanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("NamePanel: update");
+ my $instanceDir = $::config->get("service.instanceDir");
+
+ my $count = $q->param('urls');
+
+ &PKI::TPS::Wizard::debug_log("NamePanel: update - selected ca= $count");
+
+ my $host = "";
+ my $https_ee_port = "";
+
+ my $useExternalCA = "off";
+ if ($count =~ /http/) {
+ my $info = new URI::URL($count);
+ $host = $info->host;
+ $https_ee_port = $info->port;
+ } else {
+ $host = $::config->get("preop.securitydomain.ca$count.host");
+ if ($host eq "") {
+ $useExternalCA = "on";
+ } else {
+ $https_ee_port = $::config->get("preop.securitydomain.ca$count.secureport");
+ &PKI::TPS::Wizard::debug_log("NamePanel: update - host= $host, https_ee_port= $https_ee_port");
+ }
+ }
+ $::config->put("preop.certenroll.useExternalCA", $useExternalCA);
+
+ $::config->put("preop.ca.url", "https://" . $host . ":" . $https_ee_port);
+
+ my $tokenname = $::config->get("preop.module.token");
+ &PKI::TPS::Wizard::debug_log("NamePanel: update got token name = $tokenname");
+ my $hw;
+ my $tk;
+
+ if (($tokenname eq "") || ($tokenname eq "NSS Certificate DB")) {
+ $hw = "";
+ $tk = "";
+ } else {
+ $hw = "-h $tokenname";
+ $tk = $tokenname.":";
+ }
+
+ # is nickname changed because of token (hardware) selection?
+ my $changed = "false";
+ foreach my $certtag (@PKI::TPS::Wizard::certtags) {
+ &PKI::TPS::Wizard::debug_log("NamePanel: update begins for certag= $certtag");
+ my $cert_dn = $q->param($certtag);
+ $::config->put("preop.cert.".$certtag.".dn", $cert_dn);
+ $::config->commit();
+
+ my $sslnickname = $::config->get("preop.cert.sslserver.nickname");
+ my $nickname = $q->param($certtag . "_nick");
+ if ($nickname ne "") {
+ &PKI::TPS::Wizard::debug_log("NamePanel: update nickname for $certtag set to $nickname");
+ &PKI::TPS::Wizard::debug_log("NamePanel: update nickname for $certtag being updated in config file");
+ $::config->put("preop.cert.".$certtag.".nickname", $nickname);
+ $::config->commit();
+ } else {
+ $nickname = $::config->get("preop.cert.$certtag.nickname");
+ if ($nickname eq "") {
+ $nickname = "TPS ".$certtag." cert";
+ &PKI::TPS::Wizard::debug_log("NamePanel: update nickname not found for $certtag -- try $nickname");
+ }
+ }
+
+ my $cert_request = $::config->get("preop.cert.$certtag.certreq");
+ if ($cert_request ne "") {
+ &PKI::TPS::Wizard::debug_log("NamePanel: update do not generate new keys");
+ goto GEN_CERT;
+ }
+ &PKI::TPS::Wizard::debug_log("NamePanel: update generate new keys");
+
+ # =====generate requests========
+ # getting new request should void old cert
+ my $file= "$instanceDir/conf/".$certtag."_cert.txt";
+ my $tmp = `rm $file`;
+
+ &PKI::TPS::Wizard::debug_log("NamePanel: retrieving $tokenname from pwdconf");
+ my $token_pwd = $::pwdconf->get($tokenname);
+ &PKI::TPS::Wizard::debug_log("NamePanel: creating pwfile");
+ open FILE, ">$instanceDir/conf/.pwfile";
+ system( "chmod 00660 $instanceDir/conf/.pwfile" );
+ $token_pwd =~ s/\n//g;
+ print FILE $token_pwd;
+ close FILE;
+
+ my $keytype = $::config->get("preop.cert.$certtag.keytype");
+ if ($keytype eq "") {
+ $keytype = "rsa";
+ }
+
+ my $select = $::config->get("preop.cert.$certtag.keysize.select");
+
+ my $keysize;
+
+ if ($keytype eq "rsa") {
+ $keysize = 2048;
+ } elsif ($keytype eq "ecc") {
+ $keysize = 256;
+ }
+
+ if (($select eq "") || ($select eq "default")) {
+ my $size = $::config->get("preop.cert.$certtag.keysize.size");
+ if ($size ne "") {
+ $keysize = $size;
+ }
+ } else {
+ my $size = $::config->get("preop.cert.$certtag.keysize.customsize");
+ if ($size ne "") {
+ $keysize = $size;
+ }
+ if (($keytype eq "ecc") && ($keysize ne 256)) {
+ &PKI::TPS::Wizard::debug_log("NamePanel: update got keysize from config= $keysize changing to 256, the only supported ECC strength");
+ $keysize = 256;
+ }
+ }
+
+ &PKI::TPS::Wizard::debug_log("NamePanel: update got key type $keytype");
+ my $req;
+ my $debug_req;
+ my $filename = "/tmp/random.$$";
+ `dd if\=/dev/urandom of\=\"$filename\" count\=256 bs\=1`;
+ if ($keytype eq "rsa") {
+ #XXX temporary
+ &PKI::TPS::Wizard::debug_log("NamePanel: update "."certutil -R -s $cert_dn -k $keytype -g $keysize -d $instanceDir/alias $hw -f $instanceDir/conf/.pwfile -a -z $filename");
+ my $tmpfile = "/tmp/req$$";
+ system("certutil -R -s \"$cert_dn\" -k $keytype -g $keysize -d $instanceDir/alias $hw -f $instanceDir/conf/.pwfile -a -z $filename > $tmpfile");
+ $req = `cat $tmpfile`;
+ system("rm $tmpfile");
+ } elsif ($keytype eq "ecc") {
+ #only support curve nistp256 for now
+ my $tmpfile = "/tmp/req$$";
+ system("certutil -d $instanceDir/alias $hw -f $instanceDir/conf/.pwfile -R -s \"$cert_dn\" -k ec -q nistp256 -a -z $filename> $tmpfile");
+ $req = `cat $tmpfile`;
+ system("rm $tmpfile");
+ } else {
+ &PKI::TPS::Wizard::debug_log("NamePanel: update unsupported keytype $keytype");
+ }
+ system("rm $filename");
+
+ my $save_line = 0;
+ my @req_a = split "\n", $req;
+ foreach my $line (@req_a) {
+ chomp( $line );
+ $line =~ s/ //g;
+ if ($line eq $cert_req_header) {
+ $save_line = 1;
+ } elsif( $line eq $cert_req_footer ) {
+ $save_line = 0;
+ last;
+ } elsif( $save_line == 1 ) {
+ $cert_request .= "$line";
+ }
+ }
+ &PKI::TPS::Wizard::debug_log("NamePanel: update putting cert_request in CS.cfg: $cert_request");
+ $::config->put("preop.cert.$certtag.certreq", $cert_request);
+ $::config->commit();
+
+GEN_CERT:
+# =====request for certs========
+# see if there is an existing cert
+
+ my $cert = $::config->get("preop.cert.$certtag.cert");
+ my $sdom = $::config->get("config.sdomainEEURL");
+ my $sdom_url = new URI::URL($sdom);
+
+ if (($useExternalCA eq "on") && ($certtag ne "subsystem")) {
+ &PKI::TPS::Wizard::debug_log("NamePanel: update External CA selected");
+ if ($cert eq "") {
+ &PKI::TPS::Wizard::debug_log("NamePanel: update no cert found...need manual enrollment");
+ }
+ } else {
+ if ($cert eq "") {
+ &PKI::TPS::Wizard::debug_log("NamePanel: update External CA not selected...need automatic enrollment");
+
+ my $machineName = $::config->get("service.machineName");
+ my $securePort = $::config->get("service.securePort");
+ my $session_id = $::config->get("preop.sessionID");
+
+ if ($cert_request ne "") {
+ &PKI::TPS::Wizard::debug_log("NamePanel: update found existing request: $cert_request");
+ } else {
+ &PKI::TPS::Wizard::debug_log("NamePanel: update existing request not found");
+ #something is wrong...no request, no cert
+ goto DONE;
+ return $cert;
+ }
+
+ my $instanceID = $::config->get("service.instanceID");
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $db_password = "";
+ &PKI::TPS::Wizard::debug_log("NamePanel: greping password");
+
+ my $tmpfile = "/tmp/grep$$";
+ system ("grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10- > $tmpfile");
+ $db_password = `cat $tmpfile`;
+ $db_password =~ s/\n$//g;
+ system("rm $tmpfile");
+
+ my $profile_id = $::config->get("preop.cert.$certtag.profile");
+ &PKI::TPS::Wizard::debug_log("NamePanel: profileId=" . $profile_id);
+ my $requestor_name = "TPS-" . $machineName . "-" . $securePort;
+ my $params = "profileId=" . $profile_id . "&" .
+ "cert_request_type=" . "pkcs10" . "&" .
+ "requestor_name=" . $requestor_name . "&" .
+ "cert_request=" .
+ URI::Escape::uri_escape("$cert_request") . "&" .
+ "xmlOutput=true" . "&" .
+ "sessionID=" . $session_id . "&" .
+ "auth_hostname=" . $sdom_url->host . "&" .
+ "auth_port=" . $sdom_url->port;
+
+ if ($certtag eq "subsystem") {
+ $host = $sdom_url->host;
+ $https_ee_port = $sdom_url->port;
+ }
+ if ($changed eq "true") {
+$req = "/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"$token_pwd\" -v -n \"$sslnickname\" -r \"/ca/ee/ca/profileSubmit\" $host:$https_ee_port";
+$debug_req = "/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"(sensitive)\" -v -n \"$sslnickname\" -r \"/ca/ee/ca/profileSubmit\" $host:$https_ee_port";
+ } else {
+$req = "/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"$db_password\" -v -n \"$sslnickname\" -r \"/ca/ee/ca/profileSubmit\" $host:$https_ee_port";
+$debug_req = "/usr/bin/sslget -e \"$params\" -d \"$instanceDir/alias\" -p \"(sensitive)\" -v -n \"$sslnickname\" -r \"/ca/ee/ca/profileSubmit\" $host:$https_ee_port";
+ }
+
+ &PKI::TPS::Wizard::debug_log("debug_req = " . $debug_req);
+ my $content = `$req`;
+ &PKI::TPS::Wizard::debug_log("content = " . $content);
+
+ $content =~ /(\<XMLResponse\>.*\<\/XMLResponse\>)/;
+ $content = $1;
+
+ if ($content eq "") {
+ $::symbol{errorString} = "CA returned no response. Please check that the CA is available and also check the host's firewall settings.";
+ return 0;
+ }
+
+ my $parser = XML::Simple->new();
+ &PKI::TPS::Wizard::debug_log("NamePanel: response content= " . $content);
+ my $response = $parser->XMLin($content);
+ my $status = $response->{Status};
+ if ($status ne "0") {
+ my $error = $response->{Error};
+ &PKI::TPS::Wizard::debug_log("NamePanel: Error = $error");
+ $::symbol{errorString} = "CA response: $error. Please check previous related panels." . " Please check that the CA is available and also check the host's firewall settings.";
+ return 0;
+ }
+
+ $cert = $response->{Requests}->{Request}->{b64};
+ &PKI::TPS::Wizard::debug_log("NamePanel: new cert generated= " . $cert);
+
+# my $reqid = $response->{Requests}->{Request}->{Id};
+# $::config->put("preop.admincert.requestId.0", $reqid);
+# my $sn = $response->{Requests}->{Request}->{serialno};
+# $::config->put("preop.admincert.serialno.0", $sn);
+# $::config->commit();
+
+ &PKI::TPS::Wizard::debug_log("NamePanel: update putting cert in CS.cfg: $cert");
+ $::config->put("preop.cert.$certtag.cert", $cert);
+ $::config->commit();
+
+ } else {
+ # cert is not null
+ &PKI::TPS::Wizard::debug_log("NamePanel: update External CA not selected. Cert found...no need for enrollment");
+ }
+
+# write cert to file so certutil can import
+ my $cert_fn = "$instanceDir/conf/".$certtag."_cert.txt";
+ open FILE, "> $cert_fn";
+ print FILE $cert_header."\n".$cert."\n".$cert_footer;
+ close FILE;
+
+ # import cert, whether it was imported before or not
+ my $nickname = $::config->get("preop.cert.$certtag.nickname");
+ if ($nickname eq "") {
+ #XXX
+ $nickname = "TPS ".$certtag." cert";
+ &PKI::TPS::Wizard::debug_log("NamePanel: update nickname not found for $certtag -- try $nickname");
+ }
+
+ if ($certtag ne "sslserver") {
+ &PKI::TPS::Wizard::debug_log("NamePanel: update: try to delete existing cert $nickname, if any....ok if it fails");
+ $tmp = `certutil -d $instanceDir/alias -D -n "$nickname"`;
+ $tmp = `certutil -d $instanceDir/alias -D $hw -f $instanceDir/conf/.pwfile -n "$tk$nickname"`;
+ } else {
+ &PKI::TPS::Wizard::debug_log("NamePanel: update: try to delete existing cert $sslnickname, if any....ok if it fails");
+ $tmp = `certutil -d $instanceDir/alias -D -n "$sslnickname"`;
+ $tmp = `certutil -d $instanceDir/alias -D $hw -f $instanceDir/conf/.pwfile -n "$tk$sslnickname"`;
+ }
+
+ &PKI::TPS::Wizard::debug_log("NamePanel: update: try to import cert from $cert_fn");
+ $tmp = `certutil -d $instanceDir/alias $hw -f $instanceDir/conf/.pwfile -A -n "$nickname" -t "u,u,u" -a -i $cert_fn`;
+ # changed the cert, need to change nickname too, if necessary
+ if ($hw ne "") {
+ if ($certtag eq "sslserver") {
+ if ($changed eq "false") {
+ $::config->put("preop.cert.$certtag.nickname", "$tk$nickname");
+ }
+ $changed = "true";
+ }
+ if ($certtag eq "subsystem") {
+ &PKI::TPS::Wizard::debug_log("NamePanel: update: sslnickname changed");
+ $::config->put("preop.cert.$certtag.nickname", "$tk$nickname");
+ $::config->put("conn.ca1.clientNickname", "$tk$nickname");
+ $::config->put("conn.drm1.clientNickname", "$tk$nickname");
+ $::config->put("conn.tks1.clientNickname", "$tk$nickname");
+ }
+ $::config->commit();
+ } else {
+ if ($certtag eq "subsystem") {
+ # setting these just in case the subsystem nickname changed.
+ &PKI::TPS::Wizard::debug_log("NamePanel: update: setting in case the subsystem nickname changed");
+ $::config->put("conn.ca1.clientNickname", "$nickname");
+ $::config->put("conn.drm1.clientNickname", "$nickname");
+ $::config->put("conn.tks1.clientNickname", "$nickname");
+ }
+ $::config->commit();
+ }
+
+
+ &PKI::TPS::Wizard::debug_log("NamePanel: update: done importing cert: $tk$nickname");
+ $tmp = `rm $cert_fn`;
+ }
+ }
+
+ # set selftest and audit logging variables (always use the "latest" subsystem nickname)
+ my $selftestNickname = $::config->get( "preop.cert.subsystem.nickname" );
+ my $selftestNickname_sslserver = $::config->get( "preop.cert.sslserver.nickname" );
+ my $selftestNickname_audit_signing = $::config->get( "preop.cert.audit_signing.nickname" );
+ if ($hw ne "") {
+ $::config->put( "selftests.plugin.TPSPresence.nickname",
+ "$tk$selftestNickname" );
+ $::config->put( "selftests.plugin.TPSValidity.nickname",
+ "$tk$selftestNickname" );
+
+ $::config->put( "tps.cert.sslserver.nickname",
+ "$tk$selftestNickname_sslserver" );
+ $::config->put( "tps.cert.subsystem.nickname",
+ "$tk$selftestNickname" );
+ $::config->put( "tps.cert.audit_signing.nickname",
+ "$tk$selftestNickname_audit_signing" );
+
+ $::config->put( "logging.audit.signedAuditCertNickname",
+ "$tk$selftestNickname_audit_signing" );
+ } else {
+ $::config->put( "selftests.plugin.TPSPresence.nickname",
+ "$selftestNickname" );
+ $::config->put( "selftests.plugin.TPSValidity.nickname",
+ "$selftestNickname" );
+
+ $::config->put( "tps.cert.sslserver.nickname",
+ "$selftestNickname_sslserver" );
+ $::config->put( "tps.cert.subsystem.nickname",
+ "$selftestNickname" );
+ $::config->put( "tps.cert.audit_signing.nickname",
+ "$selftestNickname_audit_signing" );
+
+ $::config->put( "logging.audit.signedAuditCertNickname",
+ "$selftestNickname_audit_signing" );
+ }
+ $::config->commit();
+
+DONE:
+ $::config->put("preop.namepanel.done", "true");
+ $::config->commit();
+
+ &PKI::TPS::Wizard::debug_log("NamePanel: removing pwfile");
+ my $tmp = `rm $instanceDir/conf/.pwfile`;
+ return 1;
+}
+
+sub readFile
+{
+ my $fn = $_[0];
+ open FILE, "< $fn" or return "";
+ my $content = join "",<FILE>;
+ close FILE;
+
+ return $content;
+}
+
+use Data::Dumper;
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("NamePanel: display");
+
+ my $domain_name = $::config->get("preop.securitydomain.name");
+ if ($domain_name eq "") {
+ $domain_name = "TPS Domain";
+ }
+ my $machine_name = $::config->get("service.machineName");
+ my $instance_id = $::config->get("service.instanceID");
+
+ my $i = 0;
+ foreach my $certtag (@PKI::TPS::Wizard::certtags) {
+ &PKI::TPS::Wizard::debug_log("NamePanel: display certtag=$certtag");
+ my $cert_dn = $::config->get("preop.cert.".$certtag.".dn");
+ if ($cert_dn eq "") {
+ if ($certtag eq "subsystem") {
+ $cert_dn = "CN=TPS Subsystem, " .
+ "OU=" . $instance_id . ", " .
+ "O=" . $domain_name;
+ } elsif ($certtag eq "sslserver") {
+ $cert_dn ="CN=" . $machine_name . ", " .
+ "OU=" . $instance_id . ", " .
+ "O=" . $domain_name;
+ } else {
+ &PKI::TPS::Wizard::debug_log("NamePanel: display other certtag=$certtag");
+ $cert_dn = $certtag;
+ }
+ $::config->put("preop.cert.".$certtag.".dn", $cert_dn);
+ $::config->commit();
+ } else {
+ if (!($cert_dn =~ /O=/)) {
+ $cert_dn .= ", O=" . $domain_name;
+ $::config->put("preop.cert.".$certtag.".dn", $cert_dn);
+ $::config->commit();
+ }
+ }
+
+ my $name = $::config->get("preop.cert.".$certtag.".userfriendlyname");
+ if ($name eq "") {
+ $name = $certtag."Cert ".$instance_id;
+ $::config->put("preop.cert.".$certtag.".userfriendlyname", $name);
+ $::config->commit();
+ }
+
+ my $cert = new PKI::TPS::CertInfo($name,
+ $cert_dn, $certtag);
+ $::symbol{certs}[$i++] = $cert;
+ }
+
+ &PKI::TPS::Wizard::debug_log("NamePanel: getting CA info");
+ $::symbol{urls} = [];
+ my $count = 0;
+
+ while (1) {
+ my $host = $::config->get("preop.securitydomain.ca$count.host") || "";
+ if ($host eq "") {
+ goto DONE;
+ }
+ my $https_ee_port = $::config->get("preop.securitydomain.ca$count.secureport");
+ my $name = $::config->get("preop.securitydomain.ca$count.subsystemname");
+ my $item = $name . " - https://" . $host . ":" . $https_ee_port;
+ $::symbol{urls}[$count++] = $item;
+
+ }
+DONE:
+
+ $::symbol{urls}[$count++] = "External CA";
+ $::symbol{urls_size} = $count+1;
+
+ return 1;
+}
+
+
+# arg0 filename containing certificate request
+# return certificate request plus header and footer
+sub extract_cert_req_from_file
+{
+ my $save_line = 0;
+
+ my $filename = $_[0];
+
+ my $fd = new FileHandle;
+
+ my $cert_request = "";
+
+ $fd->open( "<$filename" ) or die "Could not open '$filename'!\n";
+
+ while( <$fd> )
+ {
+ my $line = $_;
+ chomp( $line );
+
+ if( $line eq $cert_req_header ) {
+ $save_line = 1;
+ $cert_request .= "$line\n";
+ } elsif( $line eq $cert_req_footer ) {
+ $cert_request .= "$line\n";
+ $save_line = 0;
+ last;
+ } elsif( $save_line == 1 ) {
+ $cert_request .= "$line\n";
+ }
+ }
+
+ $fd->close();
+
+ return $cert_request;
+}
+
+# arg0 message containing certificate request
+# return certificate request sans header and footer
+sub extract_cert_req_from_file_sans_header_and_footer
+{
+ my $filename = $_[0];
+ my $save_line = 0;
+
+ my $fd = new FileHandle;
+
+ my $cert_request = "";
+
+ $fd->open( "<$filename" ) or die "Could not open '$filename'!\n";
+
+ while( <$fd> )
+ {
+ my $line = $_;
+ chomp( $line );
+
+ if( $line eq $cert_req_header ) {
+ $save_line = 1;
+ } elsif( $line eq $cert_req_footer ) {
+ $save_line = 0;
+ last;
+ } elsif( $save_line == 1 ) {
+ $cert_request .= "$line\n";
+ }
+ }
+
+ $fd->close();
+
+ return $cert_request;
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.namepanel.done");
+}
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/ReqCertInfo.pm b/base/tps/lib/perl/PKI/TPS/ReqCertInfo.pm
new file mode 100755
index 000000000..f2faee2c7
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/ReqCertInfo.pm
@@ -0,0 +1,234 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+
+package PKI::TPS::ReqCertInfo;
+$PKI::TPS::ReqCertInfo::VERSION = '1.00';
+
+our $cert_req_header="-----BEGIN NEW CERTIFICATE REQUEST-----";
+our $cert_req_footer="-----END NEW CERTIFICATE REQUEST-----";
+our $cert_header="-----BEGIN CERTIFICATE-----";
+our $cert_footer="-----END CERTIFICATE-----";
+
+sub new {
+ my ($class, $name, $dn, $tag) = @_;
+ my $self = {};
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: start new");
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: creating name: $name, dn: $dn, tag: $tag");
+
+ $self->{"getUserFriendlyName"} = \&get_user_friendly_name;
+ $self->{"getCertTag"} = \&get_cert_tag;
+ $self->{"getCert"} = \&get_cert;
+ $self->{"getCertpp"} = \&get_cert_pp;
+ $self->{"getRequest"} = \&get_request;
+ $self->{"getDN"} = \&get_dn;
+ $self->{"useDefaultKey"} = \&use_default_key;
+ $self->{"getCustomKeysize"} = \&get_custom_keysize;
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: end new");
+
+ $self->{name} = $name;
+ $self->{dn} = $dn;
+ $self->{tag} = $tag;
+
+ bless $self, $class;
+ return $self;
+}
+
+sub get_user_friendly_name
+{
+ my ($self) = @_;
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: get_user_friendly_name");
+ return $self->{name};
+}
+
+sub readFile
+{
+ my $fn = $_[0];
+ open FILE, "< $fn" or return "";
+ my $content = join "",<FILE>;
+ close FILE;
+
+ return $content;
+}
+
+sub wrap_lines
+{
+ my $lines = shift;
+ my $temp ;
+ foreach my $line (split "\n", $lines) {
+ if (length $line > 59) {
+ $line =~ s/(.{0,60})/$1\n/g;
+ }
+ # get rid of a line that is just an empty newline
+ $line =~ s/^\n$//gms;
+ $temp .= $line;
+ }
+ # collapse multiple newlines into one
+ $temp =~ s/\n+/\n/gms;
+ $temp =~ s/\n$//gms;
+ $temp;
+
+}
+
+sub get_request
+{
+ my ($self) = @_;
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: get_request");
+ # first, try to see if request has been made before
+# my $req = readFile( "/var/lib/pki-tps/conf/$self->{tag}_cert_request.txt");
+
+ my $req = $::config->get("preop.cert.$self->{tag}.certreq");
+
+ $req = wrap_lines($req);
+
+ if ($req ne "") {
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: get_request found existing request");
+ return $cert_req_header."\n".$req."\n".$cert_req_footer;;
+ } else {
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: get_request existing request not found");
+ }
+
+ return $req;
+}
+
+sub get_cert
+{
+ my ($self) = @_;
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: get_cert");
+# see if there is an existing cert
+# my $cert = readFile("/var/lib/pki-tps/conf/".$self->{tag}."_cert.txt");
+ my $cert = $::config->get("preop.cert.$self->{tag}.cert");
+
+ $cert = wrap_lines($cert);
+ if ($cert ne "") {
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: get_cert found existing cert");
+ return $cert_header."\n".$cert."\n".$cert_footer;;
+ } else {
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: get_cert existing cert not found");
+ }
+ if ($cert eq "") {
+ $cert = "...paste certificate here...";
+ }
+
+
+ return $cert;
+}
+
+sub get_cert_pp
+{
+ my ($self) = @_;
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: get_cert_pp");
+ my $instanceDir = $::config->get("service.instanceDir");
+
+ my $hw;
+ my $tokenname = $::config->get("preop.module.token");
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: update got token name = $tokenname");
+
+ if (($tokenname eq "") || ($tokenname eq "NSS Certificate DB")) {
+ $hw = "";
+ } else {
+ $hw = "-h $tokenname";
+ }
+
+ my $token_pwd = $::pwdconf->get($tokenname);
+ open FILE, ">$instanceDir/conf/.pwfile";
+ system( "chmod 00660 $instanceDir/conf/.pwfile" );
+ $token_pwd =~ s/\n//g;
+ print FILE $token_pwd;
+ close FILE;
+
+ my $nickname = $::config->get("preop.cert.$self->{tag}.nickname");
+ if ($nickname eq "") {
+#XXX
+ $nickname = "TPS ".$self->{tag}." cert";
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: get_cert_pp nickname not found for $self->{tag} -- try $nickname");
+ }
+ my $certpp="";
+# my $found = -e "/var/lib/pki-tps/conf/$self->{tag}_cert.txt";
+ my $cert = $::config->get("preop.cert.$self->{tag}.cert");
+
+ if ($cert ne "") {
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: get_cert_pp found request, ready to get prettyprint");
+ my $tmp = `certutil -d $instanceDir/alias $hw -f $instanceDir/conf/.pwfile -n "$nickname" -L > $instanceDir/conf/$self->{tag}_cert_pp.txt`;
+ $certpp = readFile("$instanceDir/conf/$self->{tag}_cert_pp.txt");
+ $certpp =~ s/"//g;
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: get_cert_pp pp=$certpp");
+ $tmp =`rm $instanceDir/conf/$self->{tag}_cert_pp.txt`;
+ } else {
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: get_cert_pp cert not found, will not get prettyprint");
+ }
+ my $tmp = `rm $instanceDir/conf/.pwfile`;
+
+ return $certpp;
+}
+
+sub get_cert_tag
+{
+ my ($self) = @_;
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: get_cert_tag");
+ return $self->{tag};
+}
+
+sub get_dn
+{
+ my ($self) = @_;
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: get_cert_dn");
+ return $self->{dn};
+}
+
+sub use_default_key
+{
+ my ($self) = @_;
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: use_default_key");
+ my $select = $::config->get("preop.cert.$self->{tag}.keysize.select");
+ if ($select ne "") {
+ if ($select eq "custom") {
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: use_default_key from config = $select returning 0");
+ return 0;
+ }
+ }
+
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: use_default_key returning 1");
+ return 1;
+}
+
+sub get_custom_keysize
+{
+ my ($self) = @_;
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: get_custom_keysize");
+ my $keysize = $::config->get("preop.cert.$self->{tag}.keysize.customsize");
+ if ($keysize ne "") {
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: get_custom_keysize from config = $keysize");
+ return $keysize;
+ } else {
+ &PKI::TPS::Wizard::debug_log("ReqCertInfo: get_custom_keysize not from config");
+ }
+ return 2048;
+}
+
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/SecurityDomainPanel.pm b/base/tps/lib/perl/PKI/TPS/SecurityDomainPanel.pm
new file mode 100755
index 000000000..5301d1369
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/SecurityDomainPanel.pm
@@ -0,0 +1,204 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+use URI::URL;
+use XML::Simple;
+use Data::Dumper;
+
+package PKI::TPS::SecurityDomainPanel;
+$PKI::TPS::SecurityDomainPanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(1);
+ $self->{"getName"} = &PKI::TPS::Common::r("Security Domain");
+ $self->{"vmfile"} = "securitydomainpanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("SecurityPanel: validate");
+
+ return 1;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub pingCS
+{
+ my( $instanceDir ) = $_[0];
+ my( $db_password ) = $_[1];
+ my( $nickname ) = $_[2];
+ my( $hostname ) = $_[3];
+ my( $port ) = $_[4];
+
+ my $content = `/usr/bin/sslget -d $instanceDir/alias -p $db_password -v -r "/ca/admin/ca/getStatus" $hostname:$port`;
+ if( "$content" eq "" ) {
+ return 0;
+ } else {
+ $content =~ /(\<XMLResponse\>.*\<\/XMLResponse\>)/;
+ $content = $1;
+
+ my $parser = XML::Simple->new();
+ my $response = $parser->XMLin($content);
+ my $state = $response->{State};
+
+ if( "$state" eq "1" ) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("SecurityPanel: display");
+ $::symbol{panelname} = "Security Domain";
+ $::symbol{sdomainName} = "Security Domain";
+
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $db_password =~ s/\n$//g;
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+ my $hostname = $::config->get("service.machineName");
+ my $default_https_admin_port = 9445;
+
+ # check to see if "default" security domain exists on local machine
+ my $status = pingCS( $instanceDir,
+ $db_password,
+ $nickname,
+ $hostname,
+ $default_https_admin_port );
+ if( "$status" eq "1" ) {
+ # "default" security domain exists on local machine;
+ # fill "sdomainURL" in with "default" security domain
+ # as an initial "guess"
+ $::symbol{sdomainURL} = "https://" . $hostname . ":"
+ . $default_https_admin_port;
+ } else {
+ # "default" security domain does NOT exist on local machine;
+ # leave "sdomainURL" blank
+ $::symbol{sdomainURL} = "";
+ }
+
+ $::symbol{sdomainAdminURL} = "https://" . $hostname . ":"
+ . $default_https_admin_port;
+
+ my $initDaemon = "pki-cad";
+ my $initCommand = "";
+ my $instanceID = "&lt;security_domain_instance_name&gt; ";
+ if( $^O eq "linux" ) {
+ $initCommand = "/sbin/service $initDaemon";
+ } else {
+ ## default case: e. g. - ( $^O eq "solaris" )
+ $initCommand = "/etc/init.d/$initDaemon";
+ }
+ $::symbol{initCommand} = $initCommand;
+ $::symbol{instanceID} = $instanceID;
+ return 1;
+}
+
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("SecurityPanel: update");
+ my $sdomainURL = $q->param("sdomainURL");
+
+ if ($sdomainURL eq "") {
+ &PKI::TPS::Wizard::debug_log("SecurityPanel: sdomainURL has not been specified!");
+ $::symbol{errorString} = "Security Domain HTTPS has not been specified!";
+ return 0;
+ }
+
+ my $sdomainURL_info = new URI::URL($sdomainURL);
+
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $db_password = `grep \"internal:\" \"$instanceDir/conf/password.conf\" | cut -c10-`;
+ $db_password =~ s/\n$//g;
+ my $nickname = $::config->get("preop.cert.sslserver.nickname");
+ my $hostname = $sdomainURL_info->host;
+ my $https_admin_port = $sdomainURL_info->port;
+
+ # check to see if "default" security domain exists on local machine
+ my $status = pingCS( $instanceDir,
+ $db_password,
+ $nickname,
+ $hostname,
+ $https_admin_port );
+ if( "$status" ne "1" ) {
+ # invalid security domain specified
+ &PKI::TPS::Wizard::debug_log("SecurityPanel: sdomainURL not found");
+ $::symbol{errorString} = "Security Domain HTTPS Admin URL not found";
+ return 0;
+ }
+
+ # save urls in CS.cfg
+ &PKI::TPS::Wizard::debug_log("SecurityPanel: sdomainURL=" . $sdomainURL);
+ $::config->put("config.sdomainAdminURL", $sdomainURL);
+
+ # Add values necessary for 'pkiremove' . . .
+ $::config->put("securitydomain.select", "existing");
+ $::config->put("securitydomain.host", $sdomainURL_info->host);
+ $::config->put("securitydomain.httpsadminport", $sdomainURL_info->port);
+ $::config->put("preop.securitydomain.done", "true");
+ $::config->commit();
+
+ return 1;
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.securitydomain.done");
+}
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/SizePanel.pm b/base/tps/lib/perl/PKI/TPS/SizePanel.pm
new file mode 100755
index 000000000..8ac49b68d
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/SizePanel.pm
@@ -0,0 +1,249 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+use PKI::TPS::CertInfo;
+
+package PKI::TPS::SizePanel;
+$PKI::TPS::SizePanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(11);
+ $self->{"getName"} = &PKI::TPS::Common::r("Key Pairs");
+ $self->{"vmfile"} = "sizepanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("SizePanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("SizePanel: update");
+
+ my $instanceDir = $::config->get("service.instanceDir");
+ my $done = $::config->get("preop.SizePanel.done");
+ my $genKeyPair = $q->param('generateKeyPair') || "";
+ &PKI::TPS::Wizard::debug_log("SizePanel: update generateKeyPair value=$genKeyPair");
+ if ($done eq "true") {
+ if ($genKeyPair eq "") {
+ &PKI::TPS::Wizard::debug_log("SizePanel: update generateKeyPair value not found, turn to off");
+ $genKeyPair = "off";
+ }
+ } else {
+ # firstime should always generate keys
+ $genKeyPair = "on";
+ }
+
+ foreach my $certtag (@PKI::TPS::Wizard::certtags) {
+ my $select = $q->param($certtag.'_choice');
+ my $keytype = $q->param($certtag.'_keytype');
+ my $size = $q->param($certtag.'_custom_size');
+
+ &PKI::TPS::Wizard::debug_log("SizePanel: update $certtag _choice=$select $certtag _keytype=$keytype customsize= $size");
+
+ $::config->put("preop.keysize.select", $select);
+ $::config->put("preop.cert.".$certtag.".keysize.select", $select);
+
+ if (! isSupportedSize($keytype, $size)) {
+ &PKI::TPS::Wizard::debug_log("SizePanel: update size $size not supported");
+ return 0;
+ }
+ $::config->put("preop.cert.".$certtag.".keysize.customsize", $size);
+ $::config->put("preop.cert.".$certtag.".keytype", $keytype);
+
+ if ($select eq "default") {
+ my $defaultSize = getDefaultSize($keytype);
+ &PKI::TPS::Wizard::debug_log("SizePanel: update in default, defaultsize = $defaultSize");
+ $::config->put("preop.keysize.customsize", $defaultSize);
+ $::config->put("preop.keysize.size", $defaultSize);
+ $::config->put("preop.cert.".$certtag.".keysize.size", $defaultSize);
+
+ } elsif ($select eq "custom") {
+ &PKI::TPS::Wizard::debug_log("SizePanel: update in custom, customsize = $size");
+ $::config->put("preop.keysize.size", $size);
+ $::config->put("preop.cert.".$certtag.".keysize.size", $size);
+ }
+
+ if ($genKeyPair eq "on") {
+ $::config->put("preop.cert.".$certtag.".certreq", "");
+ $::config->put("preop.cert.".$certtag.".cert", "");
+ }
+ }
+#XXX should have better error checking to work better
+ $done = $::config->put("preop.SizePanel.done", "true");
+
+ $::config->commit();
+
+ return 1;
+}
+
+sub getDefaultSize {
+ my $keytype = $_[0];
+
+ if ($keytype eq "ecc") {
+ return 256;
+ } elsif ($keytype eq "rsa") {
+ return 2048;
+ }
+
+ $::symbol{errorString} = "Unsupported keytype $keytype";
+ return 0;
+}
+
+sub isSupportedSize {
+ my $keytype = $_[0];
+ my $size = $_[1];
+
+ if (($keytype eq "ecc") && ($size ne "256")) {
+ &PKI::TPS::Wizard::debug_log("SizePanel: isSupportedSize ECC only supports size 256");
+ $::symbol{errorString} = "Unsupported Size $size. ECC only supports size 256";
+ return 0;
+ }
+
+ if (($size eq "256") || ($size eq "512") || ($size eq "1024") ||
+ ($size eq "2048") || ($size eq "4096")) {
+ return 1;
+ }
+ # wrong size
+ $::symbol{errorString} = "Unsupported Size $size. RSA only supports sizes 256, 512, 1024, 2048, and 4096";
+ return 0;
+}
+
+sub display
+{
+ my ($q) = @_;
+
+ &PKI::TPS::Wizard::debug_log("SizePanel: display");
+
+ my $done = $::config->get("preop.SizePanel.done");
+ &PKI::TPS::Wizard::debug_log("SizePanel: display is panel done? $done");
+ if ($done eq "true") {
+ $::symbol{firsttime} = "false";
+ } else {
+ $::symbol{firsttime} = "true";
+ }
+
+ my $domain_name = $::config->get("preop.securitydomain.name");
+ if ($domain_name eq "") {
+ $domain_name = "TPS Domain";
+ }
+
+ my $machine_name = $::config->get("service.machineName");
+ my $instance_id = $::config->get("service.instanceID");
+
+ my $i = 0;
+ foreach my $certtag (@PKI::TPS::Wizard::certtags) {
+ my $cert_dn = $::config->get("preop.cert.".$certtag.".dn");
+ if ($cert_dn eq "") {
+ if ($certtag eq "subsystem") {
+ $cert_dn = "CN=TPS Subsystem, " .
+ "OU=" . $instance_id . ", " .
+ "O=" . $domain_name;
+ } elsif ($certtag eq "sslserver") {
+ $cert_dn ="CN=" . $machine_name . ", " .
+ "OU=" . $instance_id . ", " .
+ "O=" . $domain_name;
+ } else {
+ $cert_dn = $certtag;
+ }
+ }
+ my $name = $::config->get("preop.cert.".$certtag.".userfriendlyname");
+ if ($name eq "") {
+ $name = $certtag."Cert ".$instance_id;
+ }
+ my $cert = new PKI::TPS::CertInfo($name,
+ $cert_dn, $certtag);
+ $::symbol{certs}[$i++] = $cert;
+ }
+
+ #for "common key settings"
+ my $select = $::config->get("preop.keysize.select");
+ if (($select eq "") || ($select eq "default")) {
+ $::symbol{select} = "default";
+ } else {
+ &PKI::TPS::Wizard::debug_log("SizePanel: display keysize select= $select");
+ $::symbol{select} = $select;
+ }
+ my $default_size = $::config->get("preop.keysize.size");
+ if ($default_size eq "") {
+ $::symbol{default_keysize} = 2048;
+ } else {
+ $::symbol{default_keysize} = $default_size;
+ }
+ my $default_ecc_size = $::config->get("preop.keysize.ecc.size");
+ if ($default_ecc_size eq "") {
+ $::symbol{default_ecc_keysize} = 256;
+ } else {
+ $::symbol{default_ecc_keysize} = $default_ecc_size;
+ }
+
+ my $custom_size = $::config->get("preop.keysize.customsize");
+ if ($custom_size eq "") {
+ $::symbol{custom_size} = 2048;
+ } else {
+ $::symbol{custom_size} = $default_size;
+ }
+
+
+ return 1;
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.SizePanel.done");
+}
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/SubsystemTypePanel.pm b/base/tps/lib/perl/PKI/TPS/SubsystemTypePanel.pm
new file mode 100755
index 000000000..793849332
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/SubsystemTypePanel.pm
@@ -0,0 +1,147 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+
+package PKI::TPS::SubsystemTypePanel;
+$PKI::TPS::SubsystemTypePanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(3);
+ $self->{"getName"} = &PKI::TPS::Common::r("Subsystem Type");
+ $self->{"vmfile"} = "createsubsystempanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("SubsystemTypePanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("SubsystemTypePanel: update");
+ $::symbol{systemname} = "Token Processing ";
+ $::symbol{subsystemName} = "Token Processing System";
+ $::symbol{fullsystemname} = "Token Processing System ";
+ $::symbol{machineName} = "localhost";
+ $::symbol{http_port} = "7888";
+ $::symbol{https_port} = "7889";
+ $::symbol{non_clientauth_https_port} = "7890";
+ $::symbol{check_clonesubsystem} = " ";
+ $::symbol{check_newsubsystem} = " ";
+ $::symbol{disableClone} = 1;
+
+ my $subsystemName = $q->param('subsystemName');
+ $::config->put("preop.subsystem.name", $subsystemName);
+ $::config->put("preop.subsystemtype.done", "true");
+ $::config->commit();
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("SubsystemTypePanel: display");
+ $::symbol{systemname} = "Token Processing ";
+ $::symbol{subsystemName} = "Token Processing System";
+ $::symbol{fullsystemname} = "Token Processing System ";
+
+ my $machineName = $::config->get("service.machineName");
+ my $unsecurePort = $::config->get("service.unsecurePort");
+ my $securePort = $::config->get("service.securePort");
+ my $non_clientauth_securePort = $::config->get("service.non_clientauth_securePort");
+
+
+ $::symbol{machineName} = $machineName;
+ $::symbol{http_port} = $unsecurePort;
+ $::symbol{https_port} = $securePort;
+ $::symbol{non_clientauth_https_port} = $non_clientauth_securePort;
+ $::symbol{check_clonesubsystem} = "";
+ $::symbol{check_newsubsystem} = "checked ";
+
+ my $session_id = $q->param("session_id");
+ $::config->put("preop.sessionID", $session_id);
+ $::config->commit();
+
+ $::symbol{urls} = [];
+ my $count = 0;
+ while (1) {
+ my $host = $::config->get("preop.securitydomain.tps$count.host") || "";
+ if ($host eq "") {
+ goto DONE;
+ }
+ my $port = $::config->get("preop.securitydomain.tps$count.non_clientauth_secure_port");
+ my $name = $::config->get("preop.securitydomain.tps$count.subsystemname");
+ unshift(@{$::symbol{urls}}, "https://" . $host . ":" . $port);
+ $count++;
+ }
+DONE:
+ $::symbol{urls_size} = $count;
+
+# if ($count == 0) {
+ $::symbol{disableClone} = 1;
+# }
+
+ # XXX - how to deal with urls
+ return 1;
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.subsystemtype.done");
+}
+
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/TKSInfoPanel.pm b/base/tps/lib/perl/PKI/TPS/TKSInfoPanel.pm
new file mode 100755
index 000000000..720093ac5
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/TKSInfoPanel.pm
@@ -0,0 +1,159 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+use URI::URL;
+
+package PKI::TPS::TKSInfoPanel;
+$PKI::TPS::TKSInfoPanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(5);
+ $self->{"getName"} = &PKI::TPS::Common::r("TKS Information");
+ $self->{"vmfile"} = "tksinfopanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("TKSInfoPanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("TKSInfoPanel: update");
+
+ my $count = defined($q->param('urls')) ? $q->param('urls') : "";
+ if ($count eq "") {
+ $::symbol{errorString} = "no TKS info provided. CA, TKS and optionally DRM must be installed prior to TPS installation";
+ return 0;
+ }
+ &PKI::TPS::Wizard::debug_log("TKSInfoPanel: update - got urls = $count");
+
+ my $instanceID = $::config->get("service.instanceID");
+ my $host = "";
+ my $https_agent_port = "";
+ my $https_admin_port = "";
+
+ if ($count =~ /http/) {
+ # this is for pkisilent
+ my $info = new URI::URL($count);
+ $host = defined($info->host) ? $info->host : "";
+ $https_agent_port = defined($info->port) ? $info->port : "";
+ $https_admin_port = defined($q->param('adminport')) ? $q->param('adminport') : "";
+ } else {
+ $host = defined($::config->get("preop.securitydomain.tks$count.host")) ?
+ $::config->get("preop.securitydomain.tks$count.host") : "";
+ $https_admin_port = defined($::config->get("preop.securitydomain.tks$count.secureadminport")) ?
+ $::config->get("preop.securitydomain.tks$count.secureadminport") : "";
+ $https_agent_port = defined($::config->get("preop.securitydomain.tks$count.secureagentport")) ?
+ $::config->get("preop.securitydomain.tks$count.secureagentport") : "";
+ }
+
+ if (($host eq "") || ($https_agent_port eq "")) {
+ $::symbol{errorString} = "no TKS found. CA, TKS and optionally DRM must be installed prior to TPS installation";
+ return 0;
+ }
+
+ if ($https_admin_port eq "") {
+ if ($count =~ /http/) {
+ $::symbol{errorString} = "TKS admin port must be provided";
+ } else {
+ $::symbol{errorString} = "TKS admin port not provided by security domain.";
+ }
+ return 0;
+ }
+
+ my $subsystemCertNickName = $::config->get("preop.cert.subsystem.nickname");
+ $::config->put("preop.tksinfo.select", "https://$host:$https_admin_port");
+ $::config->put("conn.tks1.clientNickname", $subsystemCertNickName);
+ $::config->put("conn.tks1.hostport", $host . ":" . $https_agent_port);
+ $::config->put("preop.tksinfo.done", "true");
+ $::config->commit();
+
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("TKSInfoPanel: display");
+ $::symbol{urls} = [];
+ my $count = 0;
+ while (1) {
+ my $host = "";
+ $host = $::config->get("preop.securitydomain.tks$count.host");
+ if ($host eq "") {
+ goto DONE;
+ }
+ my $https_agent_port = $::config->get("preop.securitydomain.tks$count.secureagentport");
+ my $name = $::config->get("preop.securitydomain.tks$count.subsystemname");
+ $::symbol{urls}[$count++] = $name . " - https://" . $host . ":" . $https_agent_port;
+ }
+DONE:
+ $::symbol{urls_size} = $count;
+ if ($count eq 0) {
+ $::symbol{errorString} = "no TKS found. CA, TKS and optionally DRM must be installed prior to TPS installation";
+ return 0;
+ }
+
+ return 1;
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.tksinfo.done");
+}
+
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/WelcomePanel.pm b/base/tps/lib/perl/PKI/TPS/WelcomePanel.pm
new file mode 100755
index 000000000..a1c77e7cd
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/WelcomePanel.pm
@@ -0,0 +1,96 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+use strict;
+use warnings;
+use PKI::TPS::GlobalVar;
+use PKI::TPS::Common;
+
+package PKI::TPS::WelcomePanel;
+$PKI::TPS::WelcomePanel::VERSION = '1.00';
+
+use PKI::TPS::BasePanel;
+our @ISA = qw(PKI::TPS::BasePanel);
+
+sub new {
+ my $class = shift;
+ my $self = {};
+
+ $self->{"isSubPanel"} = \&is_sub_panel;
+ $self->{"hasSubPanel"} = \&has_sub_panel;
+ $self->{"isPanelDone"} = \&is_panel_done;
+ $self->{"getPanelNo"} = &PKI::TPS::Common::r(0);
+ $self->{"getName"} = &PKI::TPS::Common::r("Welcome");
+ $self->{"vmfile"} = "welcomepanel.vm";
+ $self->{"update"} = \&update;
+ $self->{"panelvars"} = \&display;
+ bless $self,$class;
+ return $self;
+}
+
+sub is_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub has_sub_panel
+{
+ my ($q) = @_;
+ return 0;
+}
+
+sub validate
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("WelcomePanel: validate");
+ return 1;
+}
+
+sub update
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("WelcomePanel: update");
+ $::config->put("preop.welcome.done", "true");
+ $::config->commit();
+ return 1;
+}
+
+sub display
+{
+ my ($q) = @_;
+ &PKI::TPS::Wizard::debug_log("XXX " . $::config->get("logging.debug.enable"));
+ &PKI::TPS::Wizard::debug_log("WelcomePanel: display");
+ $::symbol{wizardname} = "TPS Configuration Wizard";
+ $::symbol{systemname} = "TPS";
+ $::symbol{fullsystemname} = "Token Processing System";
+
+ return 1;
+}
+
+sub is_panel_done
+{
+ return $::config->get("preop.welcome.done");
+}
+
+1;
diff --git a/base/tps/lib/perl/PKI/TPS/wizard.pm b/base/tps/lib/perl/PKI/TPS/wizard.pm
new file mode 100755
index 000000000..db8b26526
--- /dev/null
+++ b/base/tps/lib/perl/PKI/TPS/wizard.pm
@@ -0,0 +1,509 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+# wizard -
+# Fedora Certificate System - Token Processing System configuration wizard
+
+
+# This script is run as a 'mod_perl' CGI. Configure mod_perl by adding
+# the following to /etc/httpd/conf.d/perl.conf
+#
+# PerlModule ModPerl::Registry
+# PerlModule Apache::compat
+# PerlModule RHCS::TPS::Wizard
+# PerlSetEnv RHCS_DOCROOT /u/sparkins/t/cs_tip/certsystem/prj/common/ui
+# <Location /wizard>
+# SetHandler perl-script
+# PerlHandler RHCS::TPS::Wizard
+# Order deny,allow
+# Allow from all
+# </Location>
+
+
+# Note: The Velocity parser is not very helpful when it comes to
+# errors right now. Here are some common errors, and what they mean:
+#
+# ERROR:
+# [Mon Apr 03 13:57:33 2006] [error] [client 172.16.24.26]
+# Can't use string ("0") as an ARRAY ref while "strict refs"
+# in use at /usr/lib/perl5/site_perl/5.8.5/Template/Velocity.pm
+# line 423.\n, referer: http://chico/wizard?p=2
+# MEANING
+# This probably means that your *.vm file refers to an array
+# variable in a foreach statement that is not defined
+# Check your foreach array variables.
+
+use warnings;
+use ModPerl::Registry;
+use Template::Velocity;
+use Getopt::Std;
+use Data::Dumper;
+use CGI::Carp qw(fatalsToBrowser);
+use CGI;
+use APR::Const -compile => qw(:error SUCCESS);
+use PKI::TPS::GlobalVar;
+use PKI::TPS::WelcomePanel;
+use PKI::TPS::SecurityDomainPanel;
+use PKI::TPS::DisplayCertChainPanel;
+use PKI::TPS::SubsystemTypePanel;
+use PKI::TPS::CAInfoPanel;
+use PKI::TPS::TKSInfoPanel;
+use PKI::TPS::DRMInfoPanel;
+use PKI::TPS::DisplayCertChain2Panel;
+use PKI::TPS::AdminAuthPanel;
+use PKI::TPS::AgentAuthPanel;
+use PKI::TPS::AuthDBPanel;
+use PKI::TPS::DatabasePanel;
+use PKI::TPS::ModulePanel;
+use PKI::TPS::SizePanel;
+use PKI::TPS::NamePanel;
+use PKI::TPS::ConfigHSMLoginPanel;
+use PKI::TPS::CertRequestPanel;
+use PKI::TPS::AdminPanel;
+use PKI::TPS::ImportAdminCertPanel;
+use PKI::TPS::DonePanel;
+use PKI::TPS::Config;
+
+use PKI::TPS::Common qw(yes no r);
+
+package PKI::TPS::Wizard;
+$PKI::TPS::Wizard::VERSION = '1.00';
+
+# read configuration file
+my $flavor = "pki";
+$flavor =~ s/\n//g;
+
+my $pkiroot = $ENV{PKI_ROOT};
+
+my $config = PKI::TPS::Config->new();
+$config->load_file("$pkiroot/conf/CS.cfg");
+# read password cache file
+my $pwdconf = PKI::TPS::Config->new();
+$pwdconf->load_file("$pkiroot/conf/pwcache.conf");
+# SELinux disallows performing a "chmod" on this file
+if( $^O ne "linux" ) {
+ system( "chmod 00660 $pkiroot/conf/pwcache.conf" );
+}
+
+# create cfg debug log
+my $logfile = $config->get("service.instanceDir") . "/logs/debug";
+system( "touch $logfile" );
+system( "chmod 00640 $logfile" );
+open( DEBUG, ">>" . $logfile ) ||
+warn( "Could not open '" . $logfile . "': $!" );
+
+# apache server
+
+our $debug;
+
+my $STATUS_OK = 0; # Apache 2 needs this to be zero
+my $STATUS_ERROR = 2;
+my $STATUS_REDIRECT = 3;
+
+&debug_log("TPS wizard: starting up");
+
+my $docroot = $ENV{PKI_DOCROOT};
+
+if (! $docroot) {
+ &debug_log("TPS wizard: ERROR: PKI_DOCROOT is null");
+ return 0;
+}
+
+our $parser = new Template::Velocity($docroot);
+our $symbol;
+our @certtags;
+
+makepanels();
+
+&debug_log("TPS wizard: start up complete");
+
+1;
+
+sub debug_log
+{
+ my ($msg) = @_;
+ my $date = `date`;
+ chomp($date);
+ if( -w $logfile ) {
+ print DEBUG "$date - $msg\n";
+ }
+}
+
+ # initializes entries in parser's global symbol table for panels
+sub makepanels
+{
+ #REAL PANELS BELOW
+ my $welcome = new PKI::TPS::WelcomePanel();
+ my $securitydomain = new PKI::TPS::SecurityDomainPanel();
+ my $displaycertchain = new PKI::TPS::DisplayCertChainPanel();
+ my $subsystem = new PKI::TPS::SubsystemTypePanel();
+ my $cainfopanel = new PKI::TPS::CAInfoPanel();
+# my $displaycertchain2 = new PKI::TPS::DisplayCertChain2Panel();
+ my $tksinfopanel = new PKI::TPS::TKSInfoPanel();
+ my $drminfopanel = new PKI::TPS::DRMInfoPanel();
+ my $authdbpanel = new PKI::TPS::AuthDBPanel();
+ my $databasepanel = new PKI::TPS::DatabasePanel();
+ my $modulepanel = new PKI::TPS::ModulePanel();
+ my $confighsmloginpanel = new PKI::TPS::ConfigHSMLoginPanel();
+ my $sizepanel = new PKI::TPS::SizePanel();
+ my $namepanel = new PKI::TPS::NamePanel();
+ my $certrequestpanel = new PKI::TPS::CertRequestPanel();
+ my $adminpanel = new PKI::TPS::AdminPanel();
+ my $importadmincertpanel = new PKI::TPS::ImportAdminCertPanel();
+ my $donepanel = new PKI::TPS::DonePanel();
+
+ $symbol{panels} = [
+ $welcome, # com.netscape.cms.servlet.csadmin.WelcomePanel
+ $modulepanel, # com.netscape.cms.servlet.csadmin.ModulePanel
+ $confighsmloginpanel, # com.netscape.cms.servlet.csadmin.ConfigHSMLoginPanel
+ $securitydomain, # com.netscape.cms.servlet.csadmin.SecurityDomainPanel
+ $displaycertchain, # com.netscape.cms.servlet.csadmin.DisplayCertChainPanel
+ $subsystem, # com.netscape.cms.servlet.csadmin.CreateSubsystemPanel
+ $cainfopanel, # com.netscape.cms.servlet.csadmin.CAInfoPanel
+# $displaycertchain2, # com.netscape.cms.servlet.csadmin.DisplayCertChain2Panel
+ $tksinfopanel, # com.netscape.cms.servlet.csadmin.TKSInfoPanel
+ $drminfopanel, # com.netscape.cms.servlet.csadmin.DRMInfoPanel
+ $authdbpanel, # com.netscape.cms.servlet.csadmin.DatabasePanel
+ $databasepanel, # com.netscape.cms.servlet.csadmin.DatabasePanel
+ $sizepanel, # com.netscape.cms.servlet.csadmin.SizePanel
+ $namepanel, # com.netscape.cms.servlet.csadmin.NamePanel
+ $certrequestpanel, # com.netscape.cms.servlet.csadmin.CertRequestPanel
+ $adminpanel, # com.netscape.cms.servlet.csadmin.AdminPanel
+ $importadmincertpanel, # com.netscape.cms.servlet.csadmin.ImportAdminCertPanel
+ $donepanel, # com.netscape.cms.servlet.csadmin.DonePanel</param-value>
+ ];
+};
+
+sub render_panel
+{
+ my ($panelnum, $q) = @_;
+
+ $symbol{errorString} = "";
+
+ my $currentpanel;
+
+ if ($q->param('op') && $q->param('op') eq "next") {
+ $currentpanel = $symbol{panels}[$panelnum];
+ # validate variables for panel
+ if ($currentpanel->{validate}) {
+ $currentpanel->{validate}($q);
+ }
+ # execute current panel
+ my $status = "0";
+
+ if ($currentpanel->{update}) {
+ $status = $currentpanel->{update}($q);
+ &debug_log("TPS wizard: update returns status '" .
+ $status . "'");
+ if ($status == $STATUS_REDIRECT) {
+ return $STATUS_REDIRECT;
+ }
+
+ }
+
+ &debug_log("TPS wizard: about to find out about sub panel");
+ if ($status eq "1") {
+ if ($currentpanel->{hasSubPanel} && &{$currentpanel->{hasSubPanel}}($q)) {
+ &debug_log("TPS wizard: has sub panel");
+ $panelnum = $panelnum + 2;
+ } elsif ($currentpanel->{isSubPanel} && &{$currentpanel->{isSubPanel}}($q)) {
+ &debug_log("TPS wizard: is sub panel");
+ $panelnum = $panelnum - 1;
+ } else {
+ &debug_log("TPS wizard: no sub panel and is not subpanel");
+ $panelnum = $panelnum + 1;
+ }
+ }
+ } elsif ($q->param('op') && $q->param('op') eq "back") {
+ $panelnum = $panelnum - 1;
+ #check if this a subpanel, if so, go back to it's parent.
+ #only handles one-deep at this point
+ my $panel = $symbol{panels}[$panelnum];
+ if (&{$panel->{isSubPanel}}($q)) {
+ $panelnum = $panelnum - 1;
+ }
+ } elsif ($q->param('op') && $q->param('op') eq "apply") {
+ &debug_log("TPS wizard: update : apply button pressed");
+ $currentpanel = $symbol{panels}[$panelnum];
+ # validate variables for panel
+ if ($currentpanel->{validate}) {
+ $currentpanel->{validate}($q);
+ }
+ # execute current panel
+ if ($currentpanel->{update}) {
+ my $status = $currentpanel->{update}($q);
+ &debug_log("TPS wizard: update returns status '" .
+ $status . "'");
+ if ($status == $STATUS_REDIRECT) {
+ return $STATUS_REDIRECT;
+ }
+
+ }
+ }
+
+ &debug_log("TPS wizard: after looking into about sub panel");
+
+ # advance to next panel
+ $currentpanel = $symbol{panels}[$panelnum];
+
+ # initialize symbol table values
+ $symbol{showApplyButton} = "false";
+
+ # fill in variables for new panel
+ if ($currentpanel->{panelvars}) {
+ $Data::Dumper::Indent = 1;
+ # The '&debug_log("q=".Dumper($q));' call must be commented out to fix
+ # Bugzilla Bug #249923: Incorrect file permissions on
+ # various files and/or directories
+ # &debug_log("q=".Dumper($q));
+ $currentpanel->{panelvars}($q);
+ }
+
+ $symbol{panel} = "tps/admin/console/config/".$currentpanel->{vmfile};
+
+ #wizard.vm:
+ $symbol{name} = "Token Processing System";
+ $symbol{title} = $currentpanel->{getName}();
+ if ($panelnum == 0) {
+ $symbol{firstpanel} = "1";
+ } else {
+ $symbol{firstpanel} = "0";
+ }
+ if ($panelnum == 16) {
+ $symbol{lastpanel} = "1";
+ } else {
+ $symbol{lastpanel} = "0";
+ }
+ $symbol{p} = $panelnum;
+ $symbol{subpanelno} = $panelnum+1;
+ $symbol{productversion} = $::config->get("preop.product.version");
+ $symbol{csstate} = "1";
+
+# $symbol{urls} = [ "cert1", "cert2" ]; #createsubsystem
+# $symbol{urls_size} = 2;
+# $symbol{instanceId} = "tps";
+# $symbol{errorString} = "";
+
+ #modulepanel
+# $symbol{certs} = [ ];
+# $symbol{reqscerts} = [ ];
+ $symbol{ppcerts} = [ ];
+
+ return $STATUS_OK;
+}
+
+
+
+sub dbg {
+ my $msg = shift;
+ $::symbol{dbg} .= "$msg\n";
+}
+
+sub handler {
+ my $r = shift;
+
+ *::symbol = \%symbol;
+ *::s = \$s;
+ *::config = \$config;
+ *::pwdconf = \$pwdconf;
+
+ &debug_log("TPS wizard: in handler");
+ if ($#ARGV == -1) {
+ $r->send_http_header('text/html');
+ }
+
+ my $q = new CGI;
+
+ # check cookie
+ my $cookie = $q->cookie('pin');
+ my $pin = $::config->get("preop.pin");
+ if ($cookie ne $pin) {
+ print $q->redirect("login");
+ return;
+ }
+
+ # output http parameters
+ &debug_log("TPS wizard: uri='" . $ENV{REQUEST_URI} . "'");
+ my @pnames = $q->param();
+ foreach $pn (@pnames) {
+ # 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 =~ /^__/ ||
+ $pn =~ /password$/ ||
+ $pn =~ /passwd$/ ||
+ $pn =~ /pwd$/ ||
+ $pn =~ /admin_password_again/i ||
+ $pn =~ /directoryManagerPwd/i ||
+ $pn =~ /bindpassword/i ||
+ $pn =~ /bindpwd/i ||
+ $pn =~ /passwd/i ||
+ $pn =~ /password/i ||
+ $pn =~ /pin/i ||
+ $pn =~ /pwd/i ||
+ $pn =~ /pwdagain/i ||
+ $pn =~ /uPasswd/i ) {
+ &debug_log("TPS wizard: http parameter name='" . $pn . "' value='(sensitive)'");
+ } else {
+ &debug_log("TPS wizard: http parameter name='" . $pn . "' value='" . $q->param($pn) . "'");
+ }
+ }
+
+ my $panelnum = $q->param('p');
+ if (!defined($panelnum) || $panelnum eq "") {
+ # Apache fails to pick up the p parameter after
+ # redirecting from the security domain. This is
+ # a quick hack to solve the issue.
+ if ($ENV{'QUERY_STRING'} ne "") {
+ $ENV{'QUERY_STRING'} =~ /p=([0-9]+)&/;
+ $panelnum = $1;
+ }
+ }
+
+ use subs qw(debug);
+ *debug = \&Template::Velocity::Executor::debug;
+
+ $::symbol{dbg} = "";
+
+ &debug_log("TPS wizard: before argparsing");
+ if ($#ARGV == -1) {
+ $Data::Dumper::Maxdepth = 7;
+ $startfile = "tps/admin/console/config/wizard.vm";
+ }
+
+ &debug_log("TPS wizard: setting up test objects");
+
+ #initialize from config file
+ my $certlist = $::config->get("preop.cert.list");
+ if ($certlist eq "") {
+ $certlist = "sslserver,subsystem";
+ }
+ @certtags = split(/,/, $certlist);
+ $numtags = @certtags;
+ if ($numtags eq 0) {
+ @certtags = ("sslserver", "subsystem");
+ }
+ &debug_log("TPS wizard: found $numtags certtags");
+
+ if (! $panelnum) {
+ $panelnum = 0;
+ }
+
+ my $status = render_panel($panelnum, $q);
+ if ($status == 3) {
+ $r->header_out(Location => $symbol{redirect});
+ $r->status(301);
+ $r->send_http_header();
+ return;
+ }
+
+ use Data::Dumper;
+ &debug_log("TPS wizard: executing file $startfile");
+ foreach $q (sort keys %symbol) {
+ &debug_log("TPS wizard:/config/wizard?p=9&SecToken=NSS%20Generic%20Crypto%20Services sym{$q}=".$symbol{$q});
+ }
+
+ my $result;
+ if ($q->param('xml') && $q->param('xml') eq "true") {
+ $r->send_http_header('text/xml');
+ $result = "<xml>";
+ foreach $s (sort keys %symbol) {
+ if ($s =~ /^__/) {
+ next;
+ }
+ $result .= "<" . $s . ">";
+ my $v = $symbol{$s};
+ $result .= &get_xml($s, $v);
+ $result .= "</" . $s . ">";
+ }
+ $result .= "</xml>";
+ } else {
+ $result = $parser->execute_file($startfile);
+ if (!defined $result) {
+ die("Couldn't execute template file: $docroot/$startfile");
+ }
+ }
+
+ print "$result\n";
+ return $STATUS_OK;
+}
+
+sub escape_xml
+{
+ my ($v) = @_;
+ $v =~ s/\"/&quot;/g;
+ $v =~ s/\'/&apos;/g;
+ $v =~ s/\&/&amp;/g;
+ $v =~ s/</&lt;/g;
+ $v =~ s/>/&gt;/g;
+ return $v;
+}
+
+sub get_xml
+{
+ my ($s, $v) = @_;
+
+ my $result;
+ if (ref($v) eq "HASH") {
+ foreach my $xkey (keys %$v) {
+ $result .= "<" . $xkey . ">";
+ $result .= &get_xml($xkey, $v{$xkey});
+ # $result .= "-" . ref($xkey);
+ $result .= "</" . $xkey . ">";
+ }
+ } elsif (ref($v) eq "PKI::TPS::CertInfo") {
+ my $certinfo = $v;
+ $result .= "<certinfo>";
+ $result .= "<dn>" . $certinfo->get_dn() ."</dn>";
+ $result .= "<tag>" . $certinfo->get_cert_tag() . "</tag>";
+ $result .= "<friendly>" . $certinfo->get_user_friendly_name() .
+ "</friendly>";
+ $result .= "</certinfo>";
+ } elsif (ref($v) eq "PKI::TPS::ReqCertInfo") {
+ my $reqcertinfo = $v;
+ $result .= "<reqcertinfo>";
+ $result .= "<name>" . $reqcertinfo->get_user_friendly_name() ."</name>";
+ $result .= "<req>" . $reqcertinfo->get_request() ."</req>";
+ $result .= "<cert>" . $reqcertinfo->get_cert() ."</cert>";
+ $result .= "<certpp>" . &escape_xml($reqcertinfo->get_cert_pp()) ."</certpp>";
+ $result .= "<tag>" . $reqcertinfo->get_cert_tag() ."</tag>";
+ $result .= "<dn>" . $reqcertinfo->get_cert_tag() ."</dn>";
+ $result .= "</reqcertinfo>";
+ } elsif (ref($v) eq "ARRAY") {
+ my $pos = 0;
+ foreach my $item (@$v) {
+ $result .= "<element>";
+ $result .= &get_xml("p" . $pos, $item);
+ # $result .= "-" . ref($item);
+ $result .= "</element>";
+ $pos++;
+ }
+ } else {
+ $result .= &escape_xml($v);
+ }
+ return $result;
+}
+
+1;
diff --git a/base/tps/lib/perl/Template/Velocity.pm b/base/tps/lib/perl/Template/Velocity.pm
new file mode 100755
index 000000000..ea5eb6d72
--- /dev/null
+++ b/base/tps/lib/perl/Template/Velocity.pm
@@ -0,0 +1,1052 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+
+use strict;
+
+package Template::Velocity::Executor;
+sub new;
+
+package Template::Velocity;
+
+
+# The Template::Velocity package implements a Template execution
+# engine similar to the Java Velocity package.
+
+use Parse::RecDescent;
+use Data::Dumper;
+
+
+$Template::Velocity::parser;
+
+our $docroot="docroot";
+our $parser;
+my %parsetrees = ();
+my $debugflag = 0;
+
+
+#GRAMMAR defined here
+
+my $vmgrammar = q{
+
+ {
+ use Data::Dumper;
+ sub Dumper
+ {
+ $::debugdumper = undef;
+ if ($::debugflag && $::debugdumper ) { return Data::Dumper(@_); }
+ else {""};
+ }
+
+ }
+
+
+# Template is the top-level object
+ template: <skip:'[ \t]*'> section(s) /\Z/
+
+ section: blockdirective
+ | nonblockdirective
+ | plainline
+
+ blockdirective: ifblock
+ | foreachblock
+
+ plainline : <skip:''> /[ \t]*/ ...!'#' linecomp(s?) /\n*/
+
+ HASH: '#'
+
+# HMM - this doesn't handle multiple variables on one line?
+ linecomp: variable
+ | <skip:'[ \t]*'> /[^\$\n]*/
+
+ nonblockdirective: '#' 'include' <commit> includeargs /\n*/ { $item[4] ; }
+ | '#' 'parse' <commit> parseargs /\n*/ { $item[4] ; }
+ | '#' 'set' <commit> setargs /\n*/ { $item[4] ; }
+ | <error:unknown command $text>
+
+
+ ifblock: ifdirective section(s) elseclause(?) enddirective
+
+
+# this bubbles up the result of the expression inside the if()
+# which is from the 'ifargs' rule
+ ifdirective: '#' 'if' <skip:'[ \t]*'> ifargs /\n/
+
+ enddirective: <skip:'[ \t]*'> '#' 'end' "\n"
+
+ elseclause: elsedirective section(s)
+
+ elsedirective: '#' 'else' "\n"
+
+ foreachblock: foreachdirective section(s) enddirective
+
+ foreachdirective: '#' 'foreach' foreachargs "\n"
+
+ ifargs: '(' expression ')'
+ | <error:Argument to if must be an expression: $text>
+
+ foreachargs: '(' variablename 'in' variable ')'
+ | <error:Arguments to 'foreach' must be of form \$a in \$b: $text>
+
+ includeargs: '(' string ')'
+ | <error:invalid argument to include: $text>
+
+ parseargs: '(' expression ')'
+ | <error:invalid argument to parsearges: $text>
+
+
+ setargs: <skip:'[ \t]*'> '(' assignment ')'
+ | <error:Argument to set must be an assignment : $text>
+
+
+# expression evaluation
+
+# this goes roughly in order of precendence:
+# ==
+# &&, ||
+# +, -
+# *
+# !
+
+# does not properly distinguish between lvalues and rvalues
+
+
+ expression: boolean
+ | <error>
+
+
+ assignment: variablename '=' boolean
+
+ boolean: equality (boolean_operator equality)(?)
+
+ boolean_operator: ( '&&' | '||' )
+
+ equality: summation (equality_operator summation)(?)
+
+
+ equality_operator: ( '==' | '!=' )
+
+ summation: product (summation_operator summation)(?)
+
+ summation_operator: ( '+' | '-' )
+
+
+# must parenthesize operator '*' to get it to appear in the $item array
+
+ product: negation ('*' product)(?)
+
+#XXX need to implement
+ negation: notoperator(?) factor
+
+ notoperator: "!"
+
+ factor: number
+ | string
+ | variable
+
+
+
+# These rules deal with variables
+# handles $process
+# $file.executablename
+# $process.getpid()
+# $person.getparent().getbrother().slap()
+# $fred.getchildren()
+
+# You'd make a dependency on the 'variable' rule if you want the value
+# of the variable.
+# You'd make a dependency on the 'variablename' rule if you want the
+# name of the variable.
+# (There's no real difference here - the expression evaluation is
+# in the variable() subroutine)
+
+ variable: variablename { ["variable", $item[1][1] ]; }
+
+ variablename: '$' identifier subfield(s?)
+ {
+ my $variableinfo = {
+ top => $item{identifier},
+ fields => $item{'subfield(s?)'}
+ };
+ $return = [ "variablename", \$variableinfo ];
+ }
+
+ subfield: '.' identifier arglist(?)
+ {
+ my $d;
+ my $a = $item{"arglist(?)"};
+ my $args;
+
+ #::debug "arglist = ".Dumper($a)."\n";
+ if ($a) {
+
+ my ($argcount, $al, $alpresent);
+
+ #$args = @{$a}->[2];
+ $args = $a->[0][2];
+ #::debug "arglist args=".Dumper($args)."\n";
+ $alpresent = $args;
+ $argcount = $#$args;
+ if ($alpresent && $argcount == -1) {
+ $args->[0] = [ ];
+ }
+ }
+
+ #::debug "arglist identifier=".$item{identifier}."\n";
+ $return = [ "subfield", {
+ fieldname => $item{identifier},
+ arglist => $args->[0],
+ } ];
+ }
+
+ arglist: '(' list(?) ')'
+
+ list: expression (',' list)(s?)
+
+
+# Basic data types
+# identifiers, numbers and strings
+
+ identifier: /[A-Za-z0-9_]+/ { $item[1]; }
+
+ number: /\d+/ {$item[1]; }
+
+ #XXX skip is all wrong here... should be in []
+ string: <skip:'[ \t]'> '"' <skip:""> /[^"]*/ '"' { $return = ["string",$item[4]]; }
+ | <skip:'[ \t]'> "'" <skip:""> /[^']*/ "'" { $return = ["string",$item[4]]; }
+
+
+# other literals
+ whitespace: /\s*/
+
+
+};
+
+
+# Get a parser object (transforming the built-in text grammar into RecDescent
+# data structure). This object can be reused for parsing multiple velocity files
+sub new
+{
+ #$::debugflag = 0;
+ my $class = shift;
+ $docroot = shift;
+ undef $::RD_HINT;
+ undef $::RD_WARN;
+ #$::RD_TRACE = 1;
+ $parser = new Parse::RecDescent($vmgrammar) or die "Bad Grammar\n";
+ $Data::Dumper::Maxdepth = 1;;
+ my $self = {};
+ $self->{parser} = $parser;
+ # ugly - :-(
+ $Template::Velocity::parser = $parser;
+ bless $self, $class;
+ return $self;
+}
+
+
+# Execute a template. Given a text string and a parser object, will return
+# a parse tree, useful for feeding into the executor.
+sub execute_string
+{
+ my $self = shift;
+ my $string = shift;
+ my $rule = shift;
+ if (! $rule ) { $rule = "template"; }
+ #print Dumper($self);
+
+ my $parser = $self->{parser};
+ my $parsetree = $parser->$rule($string);
+ my $executor = new Template::Velocity::Executor($parsetree, $parser );
+
+ my @value = $executor->run();
+ #my @value = Template::Velocity::Executor::execute($parsetree, $parser);
+ my $value = shift @value;
+ return $value;
+}
+
+
+sub execute_file
+{
+
+ my $self = shift;
+ my $filename = shift;
+
+ my $rule;
+ my $tree = $parsetrees{$filename};
+
+ if (! $tree) {
+ $rule = "template";
+ open my $fh, "<$docroot/$filename" or return undef;
+ my $string = join "",<$fh>;
+ close $fh;
+ $tree = $parser->$rule($string);
+ $parsetrees{$filename} = $tree;
+ }
+
+ my $executor = new Template::Velocity::Executor($tree, $parser );
+
+ my @value = $executor->run();
+ my $value = shift @value;
+ return $value;
+
+
+}
+
+
+
+
+
+
+
+
+sub Dumper
+{
+ return "";
+ if ($::debugflag && $::debugdumper) {
+ return Data::Dumper->Dump([@_]);
+ }
+ else {""};
+}
+
+
+
+
+# This autoaction returns an array of each parse element
+# The net result is a parse tree
+# I couldn't use <autotree> because I wanted to preserve
+# the order of the elements, and <autotree> returns a
+# hashtable, not an array
+
+$::RD_AUTOACTION = q{
+ [@item];
+};
+
+# debug flags set here
+
+
+
+
+
+
+######### EXECUTE FUNCTIONS
+
+
+# These functions deal with executing the velocity parse tree
+{
+ package Template::Velocity::Executor::Rules;
+ use Data::Dumper;
+
+ # this imports symbols from these other packages, so
+ # we don't have to always use the fully-qualified names
+ *exe_all = \&Template::Velocity::Executor::exe_all;
+ *exe_optional = \&Template::Velocity::Executor::exe_optional;
+ *execute = \&Template::Velocity::Executor::execute;
+ *debug = \&Template::Velocity::Executor::debug;
+ *indent = \&Template::Velocity::Executor::indent;
+ *deindent = \&Template::Velocity::Executor::deindent;
+#XXX probably should be $, not &
+ *docroot = \&Template::Velocity::docroot;
+
+ sub Dumper
+ {
+ return "";
+ if ($::debugflag && $::debugdumper) { return Dumper(@_); }
+ else {""};
+ }
+
+ #template: <skip:'[ \t]*'> section(s) /\Z/
+ sub template {
+ my $f = "template";
+ my @item = exe_all(@_);
+ debug ("$::level $f - sections should be an array of text: .".Dumper($item[2])."\n");
+ my $sections = $item[2];
+ debug ("sections is a: ".(ref $sections)." - it should be an array\n");
+ my $r= ( join "", @{$item[2]});
+ return $r;
+ }
+
+
+ #linecomp: variable
+ # | <skip:'[ \t]*'> /[^\$\n]*/
+ sub linecomp {
+ my $item;
+ debug ("linecomp: _[2] = '".$_[2]."'\n");
+ if ($_[2]) {
+ debug ("linecomp: inside if\n");
+ $item = $_[1].$_[2];
+ } else {
+ debug ("linecomp: inside else{\n");
+ ($item) = exe_all($_[1]);
+ debug ("linecomp: end of else}\n");
+ debug ("linecomp: item =\n".Dumper($item)."\n");
+ }
+ debug ("linecomp: returning $item\n");
+ return $item;
+ }
+
+ # plainline : <skip:''> /[ \t]*/ ...!'#' linecomp(s?) /\n+/
+ sub plainline {
+ my @item = exe_all(@_);
+ debug ("$::level in plainline - linecomps should be an array of text: .".Dumper($item[4])."\n");
+ my $r = join "", @{$item[4]};
+ debug ("$::level in plainline - joined as: $r\n");
+ $r = $item[2] . $r. $item[5];
+ debug ("$::level in plainline - returning : $r\n");
+ return $r;
+ }
+
+ sub expression {
+ debug ("$::level expression = ".Dumper($_[1])."\n");
+ my ($item) = exe_all($_[1]);
+ debug ("$::level expression returning $item\n");
+ return $item;
+ }
+
+ #foreachblock: foreachdirective section(s) enddirective
+ sub foreachblock {
+ my $f = "foreachblock";
+ debug ("$::level $f started!\n");
+ my ($directive) = exe_all($_[1]);
+ debug ("$::level $f directive = \n".Dumper($directive)."\n");
+ my ($variable, $list) = @{$directive};
+ my $variablename = $$variable->{top};
+ debug ("$::level $f variable = $variablename\n");
+ debug ("$::level $f list = \n".Dumper($list)."\n");
+
+ my $result = "";
+ foreach my $q (@{$list}) {
+ debug ("$::level $f q=$q\n");
+ $::symbol{$variablename} = $q;
+ debug ("$::level $f setting variable $variablename = $q\n");
+
+ my ($sections) = exe_all($_[2]);
+ debug ("$::level $f sections was: ".Dumper($sections)."\n");
+ $result .= join "",@{$sections};
+ }
+ return $result;
+ }
+
+ #foreachdirective: '#' 'foreach' foreachargs "\n"
+ sub foreachdirective {
+ my ($item) = exe_all($_[3]);
+ return $item;
+ }
+
+ #foreachargs: '(' variablename 'in' expression ')'
+ sub foreachargs {
+ my $f = "foreachargs";
+ my ($variable, $list) = exe_all($_[2], $_[4]);
+ debug ("$::level $f variable = \n".Dumper($variable)."\n");
+ debug ("$::level $f list = \n".Dumper($list)."\n");
+ return [$variable, $list];
+ }
+
+ # XXX if block should only execute section(s) if if arg is positve)
+ # likewise for else
+ #ifblock: ifdirective section(s) elseclause(?) enddirective
+ sub ifblock {
+ my $f = "ifblock";
+ my @item = exe_all(@_);
+ debug ("$::level $f - sections should be an array of text: .".Dumper($item[2])."\n");
+ my $sections = $item[2];
+ my $else = $item[3];
+ debug ("$::level $f sections is a: ".(ref $sections)." - it should be an array\n");
+ debug ("$::level item1: if expression = ".$item[1]."\n");
+ debug ("$::level $f elseclause is a: ".(ref $else)." - it should be an scalar\n");
+ my $r= (
+ $item[1]>0 ? # if expression
+ (join "", @{$item[2]}) :
+ ($item[3] ? join "",@{$item[3]} : "")
+ );
+ # this is not quite right ... elseclause returns a scalar (it joins the sections)
+ # so why do I have to join again here? possibly because it's a '?'
+ return $r;
+ }
+
+ #elseclause: elsedirective section(s)
+ sub elseclause {
+ my $f = "elseclause";
+ my ($sections) = exe_all($_[2]);
+ debug ("$::level $f sections is a: ".(ref $sections)." - it should be an array\n");
+ my $return = join "", @{$sections};
+ debug ("$::level $f returning: $return\n");
+ return $return;
+ }
+
+ sub ifargs {
+ debug ("$::level ifargs [2] = ".Dumper($_[2])."\n");
+ my ($item) = exe_all($_[2]);
+ debug ("$::level item = ".Dumper($item)."\n");
+ my $r = $item>0 ? 1 : 0;
+ debug ("$::level ifargs returning $r\n");
+ return $r;
+ }
+
+ #ifdirective: '#' 'if' <skip:'[ \t]*'> ifargs /\n/
+ sub ifdirective {
+ my ($item) = exe_all($_[4]);
+ my $r = $item>0 ? 1 : 0;
+ debug ("$::level ifdirective returning $r\n");
+ return $r;
+ }
+
+ #boolean: equality (boolean_operator equality)(?)
+ sub boolean {
+ my $f = "boolean";
+ my ($equality, $alt) = ( execute($_[1]), $_[2]);
+ my $r = $equality;
+ if (scalar @$alt) {
+ my ($op, $equality2) = exe_optional($alt, 1,2);
+
+ if ($op eq '&&') {
+ $r = $equality && $equality2;
+ }
+ if ($op eq '||') {
+ $r = $equality || $equality2;
+ }
+ }
+
+ return $r;
+ }
+
+
+ #summation: product (summation_operator summation)(?)
+ sub summation {
+ #my @item = exe_all(@_);
+ my $f = "summation";
+ my ($product, $alt) = ( execute($_[1]), $_[2]);
+ debug("$::level $f - product = $product, alternation = $alt\n");
+ debug("$::level $f - alternation = \n".Dumper($alt)."\n");
+
+ if (scalar @$alt) {
+ if (0) {
+ debug("$::level $f - alt1= \n".Dumper($alt->[0][1])."\n");
+ debug("$::level $f - alt2= \n".Dumper($alt->[0][2])."\n");
+ my ($operator, $summation) = ( execute($alt->[0][1]), execute($alt->[0][2]),);
+ }
+ my ($operator, $summation) = exe_optional($alt, 1,2);
+
+ if ($operator eq '+') { return $product + $summation;
+ } else { return $product - $summation; }
+ } else {
+ return $product;
+ }
+ }
+
+
+
+ #equality: summation (equality_operator summation)(?)
+ sub equality {
+ my $f = "equality";
+ my ($summation, $alt) = ( execute($_[1]), $_[2] );
+
+ if (scalar @$alt) {
+ my ($operator, $summation2) = exe_optional($alt, 1,2);
+
+ # string comparison used, so (0.0) is NOT equal to (0)
+ if ($operator eq '==') { return ($summation eq $summation2) ? 1:0; }
+ else { return ($summation eq $summation2) ? 0:1; }
+ } else {
+ return $summation;
+ }
+ }
+
+
+ sub product {
+ my $f = "product";
+ my ($negation, $alt) = ( execute($_[1]), $_[2]);
+ debug("$::level $f negation = $negation, alternation = $alt\n");
+ debug("$::level $f - alternation = ".Dumper($alt)."\n");
+
+ if (scalar @$alt) {
+ if (0) {
+ debug("$::level $f - alt1= \n".Dumper($alt->[0][1])."\n");
+ debug("$::level $f - alt2= \n".Dumper($alt->[0][2])."\n");
+ my ($operator, $product) = ( execute($alt->[0][1]), execute($alt->[0][2]),);
+ }
+ my ($operator, $product) = exe_optional($alt,1,2);
+ return ($negation * $product);
+ } else {
+ return $negation;
+ }
+ }
+
+ sub factor {
+ my ($value) = exe_all($_[1]);
+ return $value;
+ }
+
+ #negation: notoperator(?) factor
+ sub negation {
+ debug ("$::level in negation... input = ".(join ",",@_)."\n");
+ #my @item = exe_all(@_);
+ my ($alt, $value) = ( $_[1], execute($_[2]) );
+ debug ("$::level negation: alternation= $alt\n");
+ debug ("$::level negation: value = $value\n");
+ my $operator = execute($alt->[0][1]);
+
+ my $r;
+ if ($operator && $operator eq '!') {
+ if ($value ) { $r = 0; }
+ else { $r = 1; }
+ debug ("$::level negation: inverting\n");
+ } else {
+ debug ("$::level negation: not inverting\n");
+ $r = $value;
+ }
+ debug ("$::level negation: returning $r\n");
+ return $r;
+ }
+
+ #setargs: <skip:'[ \t]*'> '(' assignment ')'
+ sub setargs {
+ my $f = "setargs";
+ my ($args) = exe_all($_[3]);
+ debug("$::level $f args = \n".Dumper($args)."\n");
+ my ($variable, $value) = @{$args};
+ debug("$::level $f variable type =".(ref $variable)."\n");
+ debug("$::level $f variable = \n".Dumper($variable)."\n");
+ my $symbolname = $$variable->{top};
+ debug("$::level $f setting variable '$symbolname' = $value\n");
+ $::symbol{$symbolname} = $value;
+ return "";
+ }
+
+ #assignment: variablename '=' boolean
+ sub assignment {
+ my $f = "assignment";
+ my ($variable, $value) = exe_all($_[1],$_[3]);
+ debug("$::level $f variable = \n".Dumper($variable)."\n");
+ my $r = [ $variable, $value ];
+ debug("$::level $f returning: \n".Dumper($r)."\n");
+ return $r;
+ }
+
+ #includeargs: '(' string ')'
+ sub includeargs {
+ my $f = "includeargs";
+ my ($filename ) = execute($_[2]);
+
+ debug("including file: $filename\n");
+ open my $fh, "<$docroot/$filename" or return "filenotfound $docroot/$filename!\n";
+ my $file = join "", <$fh>;
+ close FILE;
+
+ return $file;
+ }
+
+ sub parseargs {
+ my $f = "parseargs";
+ my ($filename ) = execute($_[2]);
+
+ debug("parsing file: $filename\n");
+
+ #open my $fh, "<$docroot/$filename" or return "filenotfound $docroot/$filename!\n";
+ #my $file = join "", <$fh>;
+ #close FILE;
+
+ #my $parsetree = $Template::Velocity::parser->template($file);
+ #my @value = execute($parsetree);
+ #my $value = shift @value;
+
+ my @value = Template::Velocity::execute_file(undef,$filename);
+ my $value = shift @value;
+
+ return $value;
+ }
+
+# variables
+
+# variables
+# this rule converts a variable name/identifier into its value
+# $main.subfield(argument1,argument2).subfield2(arg1,arg2)
+# There are two data structures at work here.
+# 1. the data structure specifying the variable name to be queried
+# this represents $a.b.c(100,9,5,4)
+#{
+# 'top' => 'a'
+# 'fields' => [
+# { 'fieldname' => 'b', 'arglist' => undef },
+# { 'fieldname' => 'c', 'arglist' => [ '100', 9, 5, '4', ], }
+# ],
+#}
+# 2. Data structure specifying the symbol table
+
+# return value could be:
+# a scalar: either a string/number value or reference to an array of values
+# an array
+
+ sub variable {
+# look up the root object in the symbol table
+ my $f = "variable";
+ debug("$::level $f: input\n".Dumper(\@_)."\n");
+ my $var = $_[1];
+ debug("$::level $f var=\n".Dumper($var)."\n");
+# $$var works with # 27: '#set (\$a=1+3)\n\$a\n'
+#0 REF(0x8fa0510)
+# -> HASH(0x8fa1454)
+# 'fields' => ARRAY(0x8fa8c08)
+# empty array
+# 'top' => 'a'
+
+# $var works with # 25: '$employee.add(100,4+5,2+3,4,4,5,6)'
+#DB<2> x $var
+#0 HASH(0x9c7a340)
+# 'fields' => ARRAY(0xa06e7d8)
+# 0 ARRAY(0xa06e9ac)
+# 0 'subfield'
+# 1 HASH(0xa06e880)
+# 'arglist' => ARRAY(0xa074184)
+
+ my $top = $$var->{top}; # name of the root object
+ debug("$::level $f top=\n".Dumper($top)."\n");
+ my $fields = $$var->{fields}; # array of the subidentifiers
+ my $val = "";
+
+ debug("$::level $f - top_id = $top\n");
+ debug("$::level $f : var: \n".Dumper($var)."\n");
+ debug("$::level $f - fields = \n".Dumper($fields)."\n");
+
+
+ debug("$::level $f : top = ".$top."\n");
+ if (! defined $::symbol{$top} ) {
+# XXX
+ debug ("symbol table = ",(join ",",sort keys %::symbol)."\n");
+ debug ("undefined variable: $top\n");
+ return 0;
+ }
+ debug("$::level $f symbol table: \n".Dumper(\%::symbol)."\n");
+ $val = $::symbol{$top};
+ debug("$::level $f val before: \n".Dumper($val)."\n");
+
+ debug("$::level $f - fields = \n".Dumper($fields)."\n");
+ my $pass = 1;
+ foreach my $field (@$fields) {
+ my $args;
+
+ my ($fieldname, $values);
+ {
+ debug("$::level $f pass $pass \@_=\n".Dumper(\@_)."\n");
+ debug("$::level $f before strip field = \n".Dumper($field)."\n");
+#shift @$fn; # 'subfield' string
+#$fn = $fn->[0];
+#$fn = [ (@{$fn}) ];
+#shift @$fn;
+ debug("$::level $f after strip fn = \n".Dumper($field)."\n");
+
+ $fieldname = $field->[1]->{fieldname};
+ debug("$::level $f processing field: $fieldname\n");
+ $args= $field->[1]->{arglist};
+
+
+# convert the argument list (which could be expressions, other
+# variables, etc) into raw values
+ if ($args) {
+ debug("$::level $f executing $fieldname with args:\n".Dumper($args)."\n");
+ ($values) = execute($args);
+ debug("$::level $f returned values:\n".Dumper($values)."\n");
+ }
+ }
+
+ debug("$::level $f after execute, \@_=\n".Dumper(\@_)."\n");
+
+#call the function
+ if (ref $val) {
+ debug("$::level $f : inside loop(before) {\n".Dumper($val)."\n");
+ debug("$::level $f : inside loop(before) {\n".Dumper($val)."\n");
+ if ($args) {
+ debug("$::level $f: function call\n");
+#$val = $$val->$fieldname ($args); # method call
+ my $func = $val->{$fieldname}; # method call
+ debug("$::level $f: $fieldname func=\n ".Dumper($func)."\n");
+ no strict;
+ $val = &$func($val, @$values);
+ debug("$::level $f: $fieldname result=$val\n");
+ debug("$::level $f: $fieldname result=\n".Dumper($val)."\n");
+
+ } else {
+ &::debug("$::level $f: plain field access\n");
+ if (ref $val eq "REF") {
+ $val = $$val->{$fieldname}; # field access
+ } else {
+ $val = $val->{$fieldname}; # field access
+ }
+ }
+ debug("$::level $f } inside loop(after val retrieval) val=\n".Dumper($val)."\n");
+ }
+ $pass++;
+
+ }
+
+ return $val;
+ }
+
+ #$return = [ "variablename", \$variableinfo ];
+ sub variablename {
+ my $f = "variablename";
+ debug("$::level $f: input\n".Dumper(\@_)."\n");
+ my $var = $_[1];
+ return $var;
+ }
+
+ #arglist: '(' list(?) ')'
+ sub arglist {
+ my ($list) = exe_all($_[2]);
+ debug("$::level list: ".Dumper($list)."\n");
+ if ($list) {
+ my $ll = $list->[0];
+ debug("$::level ll \n".Dumper($ll)."\n");
+ debug("$::level \$\$list: \n");
+ return $ll;
+ }
+ return undef;
+ }
+
+ #list: expression (',' list)(s?)
+ sub list {
+ my ($expr, $alt) = ( execute($_[1]), $_[2] );
+
+ if (scalar @$alt) {
+ my ($list) = exe_optional($alt, 2);
+
+ debug("$::level list: expr: $expr\n");
+ debug("$::level list: list: $list\n:");
+ debug("$::level list ".Dumper($list)."\n");
+ my $r = [ $expr, (@$list) ];
+ return $r;
+ }
+ debug("$::level returning simple expression: $expr\n:");
+ return [$expr];
+ }
+
+
+
+ sub _default {
+ debug ("$::level default rule {\n");
+ indent();
+ debug ("$::level parsing parameters\n");
+ my @item = exe_all(@_);
+ debug ("$::level default rule - last item in array is: ".$item[$#item]."\n");
+ my $r = join "",@item[1..$#item];
+ debug ("$::level default rule - returning: $r\n");
+ deindent();
+ debug ("$::level }\n");
+ return $r;
+
+ }
+
+
+}
+
+
+package Template::Velocity::Executor;
+
+use Data::Dumper;
+
+
+
+sub new
+{
+ my $class = shift;
+
+ my $parsetree = shift;
+ my $parser = shift;
+
+ my $self = {};
+ $self->{parser} = $parser;
+ $self->{parsetree} = $parsetree;
+ bless $self, $class;
+ return $self;
+}
+
+
+sub run {
+ my $self = shift;
+
+ return (execute($self->{parsetree}));
+}
+
+
+
+my $level = " ";
+
+sub debug {
+ if ($::debugflag) {
+ print @_;
+ }
+}
+
+# This basically all works calling execute($parsetree).
+# Execute will look the Parsetree, which is built by a special autoaction
+#
+# It will call top-down, into functions called 'Executor::XXX', (where XXX is
+# the name of the production)
+#
+# Additional trees, representing child productions, will be passed in
+# as arguments to the Executor::XXX function. These arguments be processed
+# before the Executor::XXX function can proceed.
+#
+# If no such function is present, Executor:_default will be run
+#
+# To process the arguments, use this in the Executor function:
+# my @item = exe(@_);
+# Which will give you an @item array similar to that in the RD rules, one
+# exception being that productions which return arrays are flattened into
+# the @item array. (bad idea?)
+#
+
+
+
+# executes a parsetree (gotten as a result of calling recdescent $parser->rule()
+# and returns the string value of the result.
+
+sub Dumper {
+ "";
+}
+
+sub execute {
+ my $result;
+ my $tree = shift; # a reference to a tree is passed in
+ debug "$level execute: {\n";
+ indent();
+ debug ("$level tree = \n".Dumper($tree)."\n");
+
+# there are 3 possible things this tree could be:
+
+# 1 a scalar .. in which case this rule represents a literal, and the
+# the literal is just returned
+#
+# 2 an array of the form (array, ...) - in which case this is the result of a production
+# which returned an array of trees. This happens
+# if you specify (s), (?), etc, in a production.
+# 3 an array of the form (scalar, ...) - in which case this refers to a subrule
+#
+
+# case 1...
+ my $type = ref $tree;
+ if ($type) {
+ debug "\n$level tree type: ".(ref $tree)." \n";
+ } else {
+ debug "\n$level tree type: scalar \n";
+ }
+ if ($type ne "ARRAY") {
+ debug "$level returning literal: '$tree'\n";
+ deindent();
+ debug "$level }\n\n";
+ return $tree;
+ }
+
+ my @result;
+
+# if this tree is the result of a auto-generated rule (e.g. alternation)
+# then tree[0] is not a name.. it is an array. just call the default action with
+# the arguments
+
+ my $rule = @{$tree}->[0]; # rule name is first
+
+ if ($rule && ref $rule eq "ARRAY") { # case 2
+ debug "$level element[0] is an array (case 2) \n";
+ debug "$level contents of input: \n".Dumper(\@{$tree})."\n";
+ #@result = exe(@{$rule});
+ debug "$level running exe on the array..\n";
+ # not sure about this...
+ @result = (exe_all(@{$tree}));
+ debug "$level contents of output: \n".Dumper(\@result)."\n";
+ #shift @result; # get rid of function name
+ $result = \@result;
+
+ } else { # case 3
+ my @args = @{$tree};
+
+ debug "$level rule is a function to execute (case 3): '$rule'\n";
+ indent();
+ my $qr = "Template::Velocity::Executor::Rules::$rule";
+ if (defined &$qr) {
+ no strict ;
+ $result = (&$qr(@args));
+ } else {
+ debug "$level no function defined for: '$rule' - calling default action\n";
+ $result = Template::Velocity::Executor::Rules::_default(@args);
+ }
+ }
+ deindent();
+ debug "$level function: $rule returned=\n".Dumper($result)."\n";
+
+ debug "$level }\n";
+ return $result;
+
+ }
+
+# these hold and set the current indent level. It's only used for nested debug messages
+sub indent {
+ if (!$debugflag) { return; }
+ $level .= " ";
+ $Data::Dumper::Pad = $level." ";
+}
+sub deindent {
+ if (!$debugflag) { return; }
+ $level = substr ($level,0,-2);
+ $Data::Dumper::Pad = $level." ";
+}
+
+
+sub exe_optional {
+ my @r;
+ my $f = shift;
+ foreach my $q (@_) {
+ debug("$level: getting arg# $q\n");
+ push @r, execute($f->[0][$q]);
+ }
+ return @r;
+}
+
+# exe: for each argument, run the 'execute' function
+#
+
+sub exe_all {
+ my $d = $Data::Dumper::Maxdepth;
+ $Data::Dumper::Maxdepth = 9;
+ debug "\n$level exe_all (".$_[0].") arguments: {\n".Dumper(\@_)." \n";
+ my @r;
+ indent();
+
+ foreach my $i (@_) {
+ push @r, execute($i);
+ }
+ deindent();
+ debug "$level exe_all: returning: \n".Dumper(\@r)."$level}\n\n";
+ $Data::Dumper::Maxdepth = $d;
+ return @r;
+}
+
+
+
+
+
+#package RHCS::TPS::GlobalVar;
+
+#sub new { my $self = {}; bless $self; return $self; }
+
+
+1;
+
diff --git a/base/tps/scripts/addAgents.ldif b/base/tps/scripts/addAgents.ldif
new file mode 100644
index 000000000..d366bc8a7
--- /dev/null
+++ b/base/tps/scripts/addAgents.ldif
@@ -0,0 +1,60 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+dn: uid=admin,ou=People,$TOKENDB_ROOT
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+objectClass: tpsProfileId
+uid: admin
+userPassword: $TOKENDB_AGENT_PWD
+sn: TUS Administrator
+cn: TUS Administrator
+userCertificate:: $TOKENDB_AGENT_CERT
+profileID: All Profiles
+
+dn: cn=TUS Agents,ou=Groups,$TOKENDB_ROOT
+objectClass: top
+objectClass: groupOfNames
+cn: TUS Agents
+member: uid=admin,ou=People,$TOKENDB_ROOT
+description: Agents for TUS
+
+dn: cn=TUS Officers,ou=Groups,$TOKENDB_ROOT
+objectClass: top
+objectClass: groupOfNames
+cn: TUS Officers
+member: uid=admin,ou=People,$TOKENDB_ROOT
+description: Security Officers for TUS
+
+dn: cn=TUS Administrators,ou=Groups,$TOKENDB_ROOT
+objectClass: top
+objectClass: groupOfNames
+cn: TUS Administrators
+member: uid=admin,ou=People,$TOKENDB_ROOT
+description: Administrators for TUS
+
+dn: cn=TUS Operators,ou=Groups,$TOKENDB_ROOT
+objectClass: top
+objectClass: groupOfNames
+cn: TUS Operators
+member: uid=admin,ou=People,$TOKENDB_ROOT
+description: Operators for TUS
diff --git a/base/tps/scripts/addIndexes.ldif b/base/tps/scripts/addIndexes.ldif
new file mode 100644
index 000000000..7a910be3e
--- /dev/null
+++ b/base/tps/scripts/addIndexes.ldif
@@ -0,0 +1,76 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+dn: cn=tokenUserID,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config
+objectclass: top
+objectclass: nsIndex
+cn: tokenUserID
+nsindextype: eq
+nsindextype: pres
+nsindextype: sub
+nssystemindex: false
+
+dn: cn=tokenID,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config
+objectclass: top
+objectclass: nsIndex
+cn: tokenID
+nsindextype: eq
+nsindextype: pres
+nsindextype: sub
+nssystemindex: false
+
+dn: cn=dateOfCreate,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config
+objectclass: top
+objectclass: nsIndex
+cn: dateOfCreate
+nsindextype: eq
+nsindextype: pres
+nsindextype: sub
+nssystemindex: false
+
+dn: cn=dateOfModify,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config
+objectclass: top
+objectclass: nsIndex
+cn: dateOfModify
+nsindextype: eq
+nsindextype: pres
+nsindextype: sub
+nssystemindex: false
+
+dn: cn=userCertificate,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config
+objectclass: top
+objectclass: nsIndex
+cn: userCertificate
+nsindextype: eq
+nssystemindex: false
+
+dn: cn=tokenSerial,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config
+objectclass: top
+objectclass: nsIndex
+cn: tokenSerial
+nsindextype: eq
+nssystemindex: false
+
+dn: cn=tokenKeyType,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config
+objectclass: top
+objectclass: nsIndex
+cn: tokenKeyType
+nsindextype: eq
+nssystemindex: false
diff --git a/base/tps/scripts/addTokens.ldif b/base/tps/scripts/addTokens.ldif
new file mode 100644
index 000000000..9b8a99e27
--- /dev/null
+++ b/base/tps/scripts/addTokens.ldif
@@ -0,0 +1,44 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+dn: ou=Tokens,$TOKENDB_ROOT
+objectclass: top
+objectclass: organizationalunit
+ou: Tokens
+
+dn: ou=Activities,$TOKENDB_ROOT
+objectclass: top
+objectclass: organizationalunit
+ou: Activities
+
+dn: ou=Certificates,$TOKENDB_ROOT
+objectclass: top
+objectclass: organizationalunit
+ou: Certificates
+
+dn: ou=People,$TOKENDB_ROOT
+objectclass: top
+objectclass: organizationalunit
+ou: People
+
+dn: ou=Groups,$TOKENDB_ROOT
+objectclass: top
+objectclass: organizationalunit
+ou: Groups
diff --git a/base/tps/scripts/addVLVIndexes.ldif b/base/tps/scripts/addVLVIndexes.ldif
new file mode 100644
index 000000000..9dc86ece1
--- /dev/null
+++ b/base/tps/scripts/addVLVIndexes.ldif
@@ -0,0 +1,51 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+dn: cn=tus-listTokens-vlv,cn=userRoot,cn=ldbm database,cn=plugins,cn=config
+cn: tus-listtokens-vlv
+objectClass: top
+objectClass: vlvsearch
+vlvBase: ou=Tokens,$TOKENDB_ROOT
+vlvFilter: (&(cn=*)(tokenUserID=*))
+vlvScope: 2
+
+dn: cn=tus-listActivities-vlv,cn=userRoot,cn=ldbm database,cn=plugins,cn=config
+cn: tus-listActivities-vlv
+objectClass: top
+objectClass: vlvsearch
+vlvBase: ou=Activities,$TOKENDB_ROOT
+vlvFilter: (&(tokenID=*)(tokenUserID=*))
+vlvScope: 2
+
+dn: cn=listTokensIndex,cn=tus-listTokens-vlv,cn=userRoot,cn=ldbm database,cn=plugins,cn=config
+cn: listTokensIndex
+objectClass: top
+objectClass: vlvindex
+vlvSort: -dateOfModify
+vlvEnabled: 1
+vlvUses: 0
+
+dn: cn=listActivitiesIndex,cn=tus-listActivities-vlv,cn=userRoot,cn=ldbm database,cn=plugins,cn=config
+cn: listActivitiesIndex
+objectClass: top
+objectClass: vlvindex
+vlvSort: -dateOfCreate
+vlvEnabled: 1
+vlvUses: 0
diff --git a/base/tps/scripts/database.ldif b/base/tps/scripts/database.ldif
new file mode 100644
index 000000000..706a3327e
--- /dev/null
+++ b/base/tps/scripts/database.ldif
@@ -0,0 +1,39 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+dn: cn=$DATABASE, cn=ldbm database, cn=plugins, cn=config
+objectClass: top
+objectClass: extensibleObject
+objectClass: nsBackendInstance
+cn: $DATABASE
+nsslapd-suffix: $BASEDN
+
+dn: cn=$BASEDN, cn=mapping tree, cn=config
+objectClass: top
+objectClass: extensibleObject
+objectClass: nsMappingTree
+cn: $BASEDN
+nsslapd-backend: $DATABASE
+nsslapd-state: Backend
+
+dn: $BASEDN
+objectClass: top
+objectClass: $OBJECTCLASS
+$TYPE: $VALUE
diff --git a/base/tps/scripts/nss_pcache b/base/tps/scripts/nss_pcache
new file mode 100755
index 000000000..f87d7bbf6
--- /dev/null
+++ b/base/tps/scripts/nss_pcache
@@ -0,0 +1,66 @@
+#!/bin/bash
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+# 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 '$0' from non-existent directory!"
+ exit 255
+fi
+
+OS=`uname -s`
+PLATFORM=""
+
+if [ $OS = "Linux" ]; then
+ PLATFORM=`uname -i`
+ if [ $PLATFORM = "i386" ]; then
+ # 32-bit Linux
+ LD_LIBRARY_PATH=/usr/lib/dirsec:/usr/lib:$LD_LIBRARY_PATH
+ elif [ $PLATFORM = "x86_64" ]; then
+ # 64-bit Linux
+ LD_LIBRARY_PATH=/usr/lib64/dirsec:/usr/lib64:/usr/lib:$LD_LIBRARY_PATH
+ fi
+ export LD_LIBRARY_PATH
+elif [ $OS = "SunOS" ]; then
+ PLATFORM=`uname -p`
+ if [ "${PLATFORM}" = "sparc" ] &&
+ [ -d "/usr/lib/sparcv9/" ] ; then
+ PLATFORM="sparcv9"
+ fi
+ if [ $PLATFORM = "sparc" ]; then
+ # 32-bit Solaris
+ LD_LIBRARY_PATH=/usr/lib/dirsec:/usr/lib:$LD_LIBRARY_PATH
+ elif [ $PLATFORM = "sparcv9" ]; then
+ # 64-bit Solaris
+ LD_LIBRARY_PATH=/usr/lib/sparcv9/dirsec:/usr/lib/sparcv9:/usr/lib/dirsec:/usr/lib:$LD_LIBRARY_PATH
+ fi
+ export LD_LIBRARY_PATH
+fi
+
+FORTITUDE_DIR=/usr/sbin
+if [ $OS = "SunOS" ]; then
+ FORTITUDE_DIR=/opt/fortitude/bin
+fi
+
+$FORTITUDE_DIR/nss_pcache $@
diff --git a/base/tps/scripts/schemaMods.ldif b/base/tps/scripts/schemaMods.ldif
new file mode 100644
index 000000000..fd7b09331
--- /dev/null
+++ b/base/tps/scripts/schemaMods.ldif
@@ -0,0 +1,58 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( dateOfCreate-oid NAME 'dateOfCreate' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( dateOfModify-oid NAME 'dateOfModify' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( modified-oid NAME 'modified' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-ORIGIN 'user defined' )
+attributeTypes: ( tokenUserID-oid NAME 'tokenUserID' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( tokenStatus-oid NAME 'tokenStatus' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( tokenAppletID-oid NAME 'tokenAppletID' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( keyInfo-oid NAME 'keyInfo' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( numberOfResets-oid NAME 'numberOfResets' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-ORIGIN 'user defined' )
+attributeTypes: ( numberOfEnrollments-oid NAME 'numberOfEnrollments' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-ORIGIN 'user defined' )
+attributeTypes: ( numberOfRenewals-oid NAME 'numberOfRenewals' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-ORIGIN 'user defined' )
+attributeTypes: ( numberOfRecoveries-oid NAME 'numberOfRecoveries' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-ORIGIN 'user defined' )
+attributeTypes: ( allowPinReset-oid NAME 'allowPinReset' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( extensions-oid NAME 'extensions' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( tokenOp-oid NAME 'tokenOp' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( tokenID-oid NAME 'tokenID' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( tokenMsg-oid NAME 'tokenMsg' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( tokenResult-oid NAME 'tokenResult' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( tokenIP-oid NAME 'tokenIP' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( tokenPolicy-oid NAME 'tokenPolicy' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( tokenIssuer-oid NAME 'tokenIssuer' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( tokenSubject-oid NAME 'tokenSubject' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( tokenSerial-oid NAME 'tokenSerial' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( tokenOrigin-oid NAME 'tokenOrigin' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( tokenType-oid NAME 'tokenType' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( tokenKeyType-oid NAME 'tokenKeyType' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( tokenReason-oid NAME 'tokenReason' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( tokenNotBefore-oid NAME 'tokenNotBefore' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( tokenNotAfter-oid NAME 'tokenNotAfter' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+attributeTypes: ( profileID-oid NAME 'profileID' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+-
+add: objectClasses
+objectClasses: ( tokenRecord-oid NAME 'tokenRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( dateOfCreate $ dateOfModify $ modified $ tokenReason $ tokenUserID $ tokenStatus $ tokenAppletID $ keyInfo $ tokenPolicy $ extensions $ numberOfResets $ numberOfEnrollments $ numberOfRenewals $ numberOfRecoveries $ userCertificate $ tokenType ) X-ORIGIN 'user defined' )
+objectClasses: ( tokenActivity-oid NAME 'tokenActivity' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( dateOfCreate $ dateOfModify $ tokenOp $ tokenIP $ tokenResult $ tokenID $ tokenUserID $ tokenMsg $ extensions $ tokenType ) X-ORIGIN 'user defined' )
+objectClasses: ( tokenCert-oid NAME 'tokenCert' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( dateOfCreate $ dateOfModify $ userCertificate $ tokenUserID $ tokenID $ tokenIssuer $ tokenOrigin $ tokenSubject $ tokenSerial $ tokenStatus $ tokenType $ tokenKeyType $ tokenNotBefore $ tokenNotAfter $ extensions ) X-ORIGIN 'user defined' )
+objectClasses: ( tpsProfileID-oid NAME 'tpsProfileID' DESC 'CMS defined class' SUP top AUXILIARY MAY ( profileID ) X-ORIGIN 'user-defined' )
diff --git a/base/tps/scripts/vlvtasks.ldif b/base/tps/scripts/vlvtasks.ldif
new file mode 100644
index 000000000..b6b4bb762
--- /dev/null
+++ b/base/tps/scripts/vlvtasks.ldif
@@ -0,0 +1,28 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+dn: cn=index1160528734, cn=index, cn=tasks, cn=config
+objectclass: top
+objectclass: extensibleObject
+cn: index1160528734
+ttl: 4
+nsInstance: userRoot
+nsIndexVLVAttribute: listTokensIndex
+nsIndexVLVAttribute: listActivitiesIndex
diff --git a/base/tps/setup/CMakeLists.txt b/base/tps/setup/CMakeLists.txt
new file mode 100644
index 000000000..f5f069cdb
--- /dev/null
+++ b/base/tps/setup/CMakeLists.txt
@@ -0,0 +1,8 @@
+set(VERSION ${APPLICATION_VERSION})
+
+install(
+ FILES
+ registry_instance
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/${PROJECT_NAME}/setup
+)
diff --git a/base/tps/setup/create.pl b/base/tps/setup/create.pl
new file mode 100755
index 000000000..e8da7d859
--- /dev/null
+++ b/base/tps/setup/create.pl
@@ -0,0 +1,973 @@
+##############################################################
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+# This script is to create a new instance of Token Processing
+# Service within CS installation.
+#
+# To execute:
+# perl create.pl
+#
+##############################################################
+
+use FindBin;
+
+##############################################################
+# Advance Options
+##############################################################
+
+my $hsm = ""; # hardware token label (i.e. 'nFast')
+my $hsm_ca = ""; # hardware token label for CA certificate (i.e. 'nFast')
+my $nickName = "Server-Cert"; # nickname
+
+##############################################################
+# Private
+##############################################################
+my $hsmLabel;
+my $serverRoot;
+my $instanceID;
+my $serverID;
+my $serverName;
+my $port;
+my $securePort;
+my $uid;
+my $gid;
+my $tmpDir;
+my $tpsDir;
+my $tusHost;
+my $tusPort;
+my $tusRoot;
+my $tusSuffix;
+my $tusAgentCert;
+my $caHost;
+my $caPort;
+my $drmHost;
+my $drmPort;
+my $serverKeyGen;
+my $tksHost;
+my $tksPort;
+my $ldapHost;
+my $ldapPort;
+my $ldapRoot;
+my $pathSep;
+my $objExt;
+my $libPrefix;
+
+my $defaultUID = "root";
+my $defaultServerRoot = "$FindBin::Bin";
+$defaultServerRoot =~ s/\/bin\/cert\/tps\/setup//;
+$defaultServerRoot =~ s/\/$//;
+my $defaultServerID = "machine";
+my $defaultServerName = "machine.fedora.com";
+my $defaultInstanceID = "tps-machine";
+my $defaultSuffix = "dc=machine,dc=fedora,dc=com";
+
+sub PromptUser
+{
+ print ("************************************************\n");
+ print ("Token Processing Service (TPS) Setup\n");
+ print ("************************************************\n");
+ print ("This script will assist you in setting up TPS.\n");
+ print ("Before running this script, you should already \n");
+ print ("install a certificate authority (CA), a token key \n");
+ print ("service (TKS), an authentication directory and a token \n");
+ print ("database.\n");
+ print ("\n");
+ print ("CA is responsible for issuing certificates while TKS \n");
+ print ("ensures a secure channel between the client and \n");
+ print ("the backend. User requests are authenticated against \n");
+ print ("the authentication directory which contains user \n");
+ print ("information. The token database collects statistics \n");
+ print ("on token activities.\n");
+ print ("\n");
+ print ("The authentication database and the token database are \n");
+ print ("regular directory server instances that can be created \n");
+ print ("via Console.\n");
+ print ("\n");
+ print ("If you need other advanced options such as hardware \n");
+ print ("token support, you need to modify the advanced option \n");
+ print ("section of this script manually.\n");
+ print ("\n");
+ print ("************************************************\n");
+ print ("GENERAL SETUP SECTION \n");
+ print ("\n");
+ print ("This script is about to create your TPS instance in your \n");
+ print ("existing CS installation.\n");
+ print ("************************************************\n");
+ print ("\n");
+
+ASK_SERVER_ROOT:
+ print ("Enter the path to the server root [$defaultServerRoot]: ");
+ chomp ($serverRoot = <STDIN>);
+ if ($serverRoot eq "") {
+ $serverRoot = "$defaultServerRoot";
+ }
+ if ($serverRoot =~ /\/$/) {
+ print ("Error: '$serverRoot' cannot end with '/'.\n");
+ goto ASK_SERVER_ROOT;
+ }
+ if (!(-d $serverRoot)) {
+ print ("Error: '$serverRoot' directory does not exit.\n");
+ goto ASK_SERVER_ROOT;
+ }
+ if (!(-f "$serverRoot/admin-serv/config/adm.conf")) {
+ print ("Error: '$serverRoot' directory does not contain $serverRoot/admin-serv/config/adm.conf.\n");
+ goto ASK_SERVER_ROOT;
+ }
+
+ # read some good parameters from adm.conf
+ open(F, "$serverRoot/admin-serv/config/adm.conf");
+ while (<F>) {
+ if (/ldapHost:\s*(\S+)/) {
+ $defaultServerName = $1;
+ }
+ if (/ldapStart:\s*slapd-(\S+)\//) {
+ $defaultServerID = $1;
+ }
+ }
+ close(F);
+
+ open(F, "$serverRoot/admin-serv/config/magnus.conf");
+ while (<F>) {
+ if (/User (\S+)/) {
+ $defaultUID = $1;
+ }
+ }
+ close(F);
+
+ $defaultSuffix = $defaultServerName;
+ $defaultSuffix =~ s/\./,dc=/g;
+ $defaultSuffix =~ s/^[^,]+,//;
+
+ASK_TPS_ROOT:
+ print ("Enter the path to the TPS release [$serverRoot/bin/cert/tps]: ");
+ chomp ($tpsDir = <STDIN>);
+ if ($tpsDir eq "") {
+ $tpsDir = "$serverRoot/bin/cert/tps";
+ }
+ if (!(-d $tpsDir)) {
+ print ("Error: '$tpsDir' directory does not exit.\n");
+ goto ASK_TPS_ROOT;
+ }
+ if (!(-d "$tpsDir/config")) {
+ print ("Error: '$tpsDir/config' directory does not exit.\n");
+ goto ASK_TPS_ROOT;
+ }
+
+ print ("Enter the hostname of this machine [$defaultServerID]: ");
+ chomp ($serverID = <STDIN>);
+ if ($serverID eq "") {
+ $serverID = "$defaultServerID";
+ }
+ print ("Enter the fully-qualified hostname of this machine [$defaultServerName]: ");
+ chomp ($serverName = <STDIN>);
+ if ($serverName eq "") {
+ $serverName = "$defaultServerName";
+ }
+
+ASK_INSTANCE_ID:
+ print ("Enter the instance ID of your new TPS instance [tps-$defaultServerID]: ");
+ chomp ($instanceID = <STDIN>);
+ if ($instanceID eq "") {
+ $instanceID = "tps-$defaultServerID";
+ }
+ if (-d "$serverRoot/$instanceID") {
+ print ("Error: '$serverRoot/$instanceID' directory already exist.\n");
+ goto ASK_INSTANCE_ID;
+ }
+
+ # update nickName
+ $nickName = "$nickName $instanceID";
+
+ print ("\n");
+ print ("************************************************\n");
+ print ("SERVICE PORTS SECTION \n");
+ print ("\n");
+ print ("TPS listens on the following ports. Please make \n");
+ print ("sure you specify unused ports.\n");
+ print ("************************************************\n");
+ print ("\n");
+
+ print ("Enter the UID that TPS should be running as [$defaultUID]: ");
+ chomp ($uid = <STDIN>);
+ if ($uid eq "") {
+ $uid = "$defaultUID";
+ }
+
+ my $defaultGID = $defaultUID;
+ print ("Enter the GID that TPS should be running as [$defaultGID]: ");
+ chomp ($gid = <STDIN>);
+ if ($gid eq "") {
+ $gid = "$defaultGID";
+ }
+
+ASK_EE_PORT:
+ print ("Enter the end entity port number of your TPS [7888]: ");
+ chomp ($port = <STDIN>);
+ if ($port eq "") {
+ $port = "7888";
+ }
+ if ($port eq "") {
+ goto ASK_EE_PORT;
+ }
+
+ASK_AGENT_PORT:
+ print ("Enter the agent port number of your TPS [7889]: ");
+ chomp ($securePort = <STDIN>);
+ if ($securePort eq "") {
+ $securePort = "7889";
+ }
+ if ($securePort eq "") {
+ goto ASK_AGENT_PORT;
+ }
+
+ print ("\n");
+ print ("************************************************\n");
+ print ("AUTHENTICATION (LDAP) DIRECTORY SECTION \n");
+ print ("\n");
+ print ("TPS verifies the user IDs and \n");
+ print ("passwords against this LDAP database before executing \n");
+ print ("requests from users.\n");
+ print ("************************************************\n");
+ print ("\n");
+
+ASK_AUTH_HOST:
+ print ("Enter the hostname of the authentication directory [$defaultServerName]: ");
+ chomp ($ldapHost = <STDIN>);
+ if ($ldapHost eq "") {
+ $ldapHost = "$defaultServerName";
+ }
+ if ($ldapHost eq "") {
+ goto ASK_AUTH_HOST;
+ }
+
+ASK_AUTH_PORT:
+ print ("Enter the port number of the authentication directory [389]: ");
+ chomp ($ldapPort = <STDIN>);
+ if ($ldapPort eq "") {
+ $ldapPort = "389";
+ }
+ if ($ldapPort eq "") {
+ goto ASK_AUTH_PORT;
+ }
+
+ASK_AUTH_ROOT:
+ print ("Enter the root suffix of the authentication directory [$defaultSuffix]: ");
+ chomp ($ldapRoot = <STDIN>);
+ if ($ldapRoot eq "") {
+ $ldapRoot = "$defaultSuffix";
+ }
+ if ($ldapRoot eq "") {
+ goto ASK_AUTH_ROOT;
+ }
+
+ print ("\n");
+ print ("************************************************\n");
+ print ("CA CONNECTION SECTION \n");
+ print ("\n");
+ print ("TPS submits certificate requests \n");
+ print ("to CA for signing.\n");
+ print ("************************************************\n");
+ print ("\n");
+
+ASK_CA_HOST:
+ print ("Enter the hostname of the CA [$defaultServerName]: ");
+ chomp ($caHost = <STDIN>);
+ if ($caHost eq "") {
+ $caHost = "$defaultServerName";
+ }
+ if ($caHost eq "") {
+ goto ASK_CA_HOST;
+ }
+
+ASK_CA_PORT:
+ print ("Enter the secure end entity port number of the CA [443]: ");
+ chomp ($caPort = <STDIN>);
+ if ($caPort eq "") {
+ $caPort = "443";
+ }
+ if ($caPort eq "") {
+ goto ASK_CA_PORT;
+ }
+
+ print ("\n");
+ print ("************************************************\n");
+ print ("TKS CONNECTION SECTION \n");
+ print ("\n");
+ print ("TPS obtains session keys from TKS \n");
+ print ("for establishing secure channels.\n");
+ print ("************************************************\n");
+ print ("\n");
+
+ASK_TKS_HOST:
+ print ("Enter the hostname of the TKS [$defaultServerName]: ");
+ chomp ($tksHost = <STDIN>);
+ if ($tksHost eq "") {
+ $tksHost = "$defaultServerName";
+ }
+ if ($tksHost eq "") {
+ goto ASK_TKS_HOST;
+ }
+
+ASK_TKS_PORT:
+ print ("Enter the secure agent port number of the TKS [8100]: ");
+ chomp ($tksPort = <STDIN>);
+ if ($tksPort eq "") {
+ $tksPort = "8100";
+ }
+ if ($tksPort eq "") {
+ goto ASK_TKS_PORT;
+ }
+
+ print ("\n");
+ print ("Do you want to perform server-side key generation optionally [yes]: \n");
+ chomp ($continue = <STDIN>);
+ print ("\n");
+
+ if ($continue eq "") {
+ $continue = "yes";
+ }
+ if ($continue eq "yes") {
+ $serverKeyGen = "true";
+
+ print ("************************************************\n");
+ print ("DRM CONNECTION SECTION \n");
+ print ("\n");
+ print ("TPS submits archival and recovery requests \n");
+ print ("to DRM.\n");
+ print ("************************************************\n");
+ print ("\n");
+
+ASK_DRM_HOST:
+ print ("Enter the hostname of the DRM [$defaultServerName]: ");
+ chomp ($drmHost = <STDIN>);
+ if ($drmHost eq "") {
+ $drmHost = "$defaultServerName";
+ }
+ if ($drmHost eq "") {
+ goto ASK_DRM_HOST;
+ }
+
+ASK_DRM_PORT:
+ print ("Enter the secure agent port number of the DRM [8100]: ");
+ chomp ($drmPort = <STDIN>);
+ if ($drmPort eq "") {
+ $drmPort = "8100";
+ }
+ if ($drmPort eq "") {
+ goto ASK_DRM_PORT;
+ }
+ print ("\n");
+ } else {
+ $serverKeyGen = "false";
+ }
+
+ print ("************************************************\n");
+ print ("TOKEN DATABASE (LDAP) CONNECTION SECTION \n");
+ print ("\n");
+ print ("TPS sends statistics information to the database \n");
+ print ("for auditing purposes.\n");
+ print ("************************************************\n");
+ print ("\n");
+
+ASK_TUS_HOST:
+ print ("Enter the hostname of the token database [$defaultServerName]: ");
+ chomp ($tusHost = <STDIN>);
+ if ($tusHost eq "") {
+ $tusHost = "$defaultServerName";
+ }
+ if ($tusHost eq "") {
+ goto ASK_TUS_HOST;
+ }
+
+ASK_TUS_PORT:
+ print ("Enter the port number of the token database [3890]: ");
+ chomp ($tusPort = <STDIN>);
+ if ($tusPort eq "") {
+ $tusPort = "3890";
+ }
+ if ($tusPort eq "") {
+ goto ASK_TUS_PORT;
+ }
+
+ASK_TUS_ROOT:
+ print ("Enter the root suffix of the token database [$defaultSuffix]: ");
+ chomp ($tusRoot = <STDIN>);
+ if ($tusRoot eq "") {
+ $tusRoot = "$defaultSuffix";
+ }
+ if ($tusRoot eq "") {
+ goto ASK_TUS_ROOT;
+ }
+
+ASK_TUS_PWD:
+ print ("Enter the password of the directory manager: ");
+ if (!&IsWindows()) {
+ system("stty -echo");
+ }
+ chomp ($tusPass = <STDIN>);
+ if (!&IsWindows()) {
+ system("stty echo");
+ }
+ if ($tusPass eq "") {
+ goto ASK_TUS_PWD;
+ }
+
+ if (&IsWindows()) {
+ $tmpDir = "c:\\temp";
+ } else {
+ $tmpDir = "/tmp";
+ }
+ print ("\n");
+}
+
+sub ToContinue
+{
+ do {
+ print ("Please enter 'proceed' to continue.\n");
+ chomp ($continue = <STDIN>);
+ } while ($continue ne "proceed");
+}
+
+sub CreateSecurityDatabase
+{
+ print ("This program is about to create the NSS certificate DB.\n");
+ &ToContinue();
+ print ("\n");
+
+ &CertUtil_CreateDatabase($serverRoot, "$instanceID-$serverID-");
+ print ("\n");
+
+ print ("This program is about to generate the certificate request.\n");
+ &ToContinue();
+ print ("\n");
+
+ASK_SERVER_CERT:
+ &CertUtil_GenerateCSR($serverRoot, "$instanceID-$serverID-",
+ $hsm, "CN=" . $serverName);
+ print ("\n");
+
+ print ("Please submit the certificate request to the CA's Manual TPS Server Certificate Enrollment profile for signing.\n");
+ print ("Note that correct OIDs (i.e. 1.3.6.1.5.5.7.3.1, 1.3.6.1.5.5.7.3.2 and 1.3.6.1.5.5.7.3.4) must be populated in the\n");
+ print ("extended key usage extension of the certificate.\n");
+ print ("In addition, this certificate must be added to \n");
+ print ("CA and TKS as trusted agent.\n");
+ print ("\n");
+ print ("This program is about to import the TPS system certificate.\n");
+ print ("Please paste in your certificate (including header and footer).\n");
+ print ("\n");
+ my $serverCert = &PromptCertificate();
+ &CertUtil_ImportServerCert($serverRoot, "$instanceID-$serverID-",
+ $hsm, $nickName, $serverCert);
+ print ("\n");
+
+ &CertUtil_Print($serverRoot, "$instanceID-$serverID-", $hsm, $nickName);
+ print ("\n");
+ print ("Is the server certificate correct [yes]: \n");
+ chomp ($continue = <STDIN>);
+ print ("\n");
+ if ($continue eq "") {
+ $continue = "yes";
+ }
+ if ($continue eq "no") {
+ goto ASK_SERVER_CERT;
+ }
+
+ $i = 0;
+ print ("This program is about to import one or more CA certificates.\n");
+ while (1) {
+ASK_AGAIN:
+ print ("Do you have CA certificate to import [yes]: \n");
+ chomp ($continue = <STDIN>);
+ print ("\n");
+ if ($continue eq "") {
+ $continue = "yes";
+ }
+ if ($continue eq "no") {
+ goto DONE;
+ }
+ print ("Please paste in your CA certificate (including header and footer).\n");
+ print ("\n");
+ my $caCert = &PromptCertificate();
+ &CertUtil_ImportCACert($serverRoot, "$instanceID-$serverID-",
+ $hsm_ca, "caCert$i $instanceID", "$caCert");
+ print ("\n");
+
+ &CertUtil_Print($serverRoot, "$instanceID-$serverID-", $hsm_ca, "caCert$i $instanceID");
+ print ("\n");
+ print ("Is the CA certificate correct [yes]: \n");
+ chomp ($continue = <STDIN>);
+ print ("\n");
+ if ($continue eq "") {
+ $continue = "yes";
+ }
+ if ($continue eq "no") {
+ &CertUtil_Delete($serverRoot, "$instanceID-$serverID-", $hsm, "caCert$i $instanceID");
+ goto ASK_AGAIN;
+ }
+ $i++;
+ }
+
+DONE:
+
+ print ("The following shows all imported certificates.\n");
+ &CertUtil_List($serverRoot, "$instanceID-$serverID-", $hsm);
+ print ("\n");
+ &ToContinue();
+}
+
+sub PromptCertificate
+{
+ my $startCert = 0;
+ my $cert;
+ while (1) {
+ chomp ($continue = <STDIN>);
+ if ($continue eq "-----END CERTIFICATE-----") {
+ $cert .= $continue . "\n";
+ goto DONE;
+ }
+ if ($startCert == 1) {
+ $cert .= $continue . "\n";
+ }
+ if ($continue eq "-----BEGIN CERTIFICATE-----") {
+ $startCert = 1;
+ $cert .= $continue . "\n";
+ }
+ }
+DONE:
+ return $cert;
+}
+
+sub Main
+{
+ if (&IsWindows()) {
+ $pathSep = ";";
+ $objExt = ".dll";
+ $libPrefix = "";
+ } else {
+ $pathSep = ":";
+ $objExt = ".so";
+ $libPrefix = "lib";
+ }
+
+ if ($hsm eq "") {
+ $hsmLabel = "";
+ } else {
+ $hsmLabel = $hsm . ":";
+ }
+
+ &PromptUser();
+
+ print ("************************************************\n");
+ print ("TPS INSTANCE CREATION \n");
+ print ("************************************************\n");
+ print ("This program is about to create the TPS instance.\n");
+ print ("If there is any error, please ctrl-C to exit and ");
+ print ("restart the process.\n");
+ print ("\n");
+ &ToContinue();
+ print ("\n");
+
+ &CreateInstanceDir();
+ &CopyTemplates();
+ &PopulateTPSTemplates();
+ print ("\n");
+
+ print ("************************************************\n");
+ print ("SECURITY DATABASE CREATION (OPTIONAL) \n");
+ print ("\n");
+ print ("Keys and certificates will be stored in the security\n");
+ print ("databases.\n");
+ print ("************************************************\n");
+
+ print ("This program is about to create the security databases.\n");
+
+ASK_AGAIN:
+ print ("Do you want to create the security databases automatically [yes]: \n");
+ chomp ($continue = <STDIN>);
+ print ("\n");
+
+ if ($continue eq "") {
+ $continue = "yes";
+ }
+ if ($continue eq "no") {
+ print ("Please place your own security databases ");
+ print ("in $serverRoot/alias/$instanceID-$serverID-*.db\n");
+ print ("\n");
+ } elsif ($continue eq "yes") {
+ &CreateSecurityDatabase();
+ } else {
+ goto ASK_AGAIN;
+ }
+
+ print ("************************************************\n");
+ print ("TOKEN DATABASE POPULATION (OPTIONAL) \n");
+ print ("\n");
+ print ("Token database's Schema and default structure will be setup.\n");
+ print ("Your first authorized agent certificate will be \n");
+ print ("imported into the database. TPS agent port can \n");
+ print ("be accessed by browser that contain the authorized \n");
+ print ("agent certificate.\n");
+ print ("************************************************\n");
+ print ("This program is about to populate the token database.\n");
+
+ASK_AGAIN2:
+ print ("Do you want to populate the token database automatically [yes]: \n");
+ chomp ($continue = <STDIN>);
+ print ("\n");
+ if ($continue eq "") {
+ $continue = "yes";
+ }
+ if ($continue eq "no") {
+ print ("Please populate the token database manually.\n");
+ } elsif ($continue eq "yes") {
+ &PopulateTUS();
+ } else {
+ goto ASK_AGAIN2;
+ }
+
+ print ("\n");
+ print ("************************************************\n");
+ print ("SETUP IS DONE \n");
+ print ("************************************************\n");
+ print ("You should manually start your TPS by \n");
+ print ("running the start script in the TPS instance.\n");
+ print ("\n");
+ print (" $serverRoot/$instanceID/start\n");
+ print ("\n");
+ print ("You can use your ESC client to access TPS's \n");
+ print ("end entity port.\n");
+ print ("\n");
+ print (" http://$serverName:$port/nk_service\n");
+ print ("\n");
+ print ("You can use your browser to access TPS's \n");
+ print ("agent port for agent/administrator operations.\n");
+ print ("\n");
+ print (" https://$serverName:$securePort/tus\n");
+ print ("\n");
+ print ("\n");
+}
+
+sub CopyTemplate
+{
+ my ($from, $to) = @_;
+
+ print "Copying $from to $to ...\n";
+ open(IN, "<$from");
+ open(OUT, ">$to");
+ while (<IN>) {
+ s/\[SERVER_ROOT\]/$serverRoot/g;
+ s/\[INSTANCE_ID\]/$instanceID/g;
+ s/\[SERVER_NAME\]/$serverName/g;
+ s/\[PORT\]/$port/g;
+ s/\[SECURE_PORT\]/$securePort/g;
+ s/\[NICKNAME\]/$nickName/g;
+ s/\[USERID\]/$uid/g;
+ s/\[GROUPID\]/$gid/g;
+ s/\[TMP_DIR\]/$tmpDir/g;
+ s/\[TPS_DIR\]/$tpsDir/g;
+ s/\[LIB_PREFIX\]/$libPrefix/g;
+ s/\[OBJ_EXT\]/$objExt/g;
+ s/\[HSM_LABEL\]/$hsmLabel/g;
+ s/\[TUS_AGENT_CERT\]/$tusAgentCert/g;
+ s/\[TUS_HOST\]/$tusHost/g;
+ s/\[TUS_PORT\]/$tusPort/g;
+ s/\[TUS_ROOT\]/$tusRoot/g;
+ s/\[TUS_PASS\]/$tusPass/g;
+ s/\[CA_HOST\]/$caHost/g;
+ s/\[CA_PORT\]/$caPort/g;
+ s/\[DRM_HOST\]/$drmHost/g;
+ s/\[DRM_PORT\]/$drmPort/g;
+ s/\[SERVER_KEYGEN\]/$serverKeyGen/g;
+ s/\[TKS_HOST\]/$tksHost/g;
+ s/\[TKS_PORT\]/$tksPort/g;
+ s/\[LDAP_HOST\]/$ldapHost/g;
+ s/\[LDAP_PORT\]/$ldapPort/g;
+ s/\[LDAP_ROOT\]/$ldapRoot/g;
+ s/\[PROCESS_ID\]/$$/g;
+ print OUT $_;
+ }
+ close(OUT);
+ close(IN);
+}
+
+sub IsWindows
+{
+ if ($^O eq "MSWin32") {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+sub CopyFiles
+{
+ my ($from, $to) = @_;
+
+ print("Copying files from $from to $to ...\n");
+ if (&IsWindows()) {
+ system("xcopy /E /I /Q $from $to");
+ } else {
+ system("cp -R $from $to");
+ }
+}
+
+sub PopulateTPSTemplates
+{
+ &CopyTemplate("$tpsDir/config/CS.cfg",
+ "$serverRoot/$instanceID/config/CS.cfg");
+ chmod(00660, "$serverRoot/$instanceID/config/CS.cfg");
+
+ print "Creating $serverRoot/cgi-bin ...\n";
+ mkdir ("$serverRoot/cgi-bin", 0755);
+
+ &CopyFiles("$tpsDir/forms/esc", "$serverRoot/cgi-bin");
+ &CopyFiles("$tpsDir/forms/tus", "$serverRoot/cgi-bin");
+}
+
+sub PopulateTUS
+{
+ print ("Please paste in your TPS Agent certificate (including header and footer).\n");
+ print ("\n");
+ my $cert = &PromptCertificate();
+ $cert =~ s/-----BEGIN CERTIFICATE-----\s*//g;
+ $cert =~ s/-----END CERTIFICATE-----\s*//g;
+ $cert =~ s/\s*//g;
+
+ $tusAgentCert = $cert;
+
+ print ("\n");
+ &ToContinue();
+ print ("\n");
+
+ open(F1, "$tpsDir/scripts/addVLVIndexes.ldif");
+ open(F2, ">$serverRoot/$instanceID/config/addVLVIndexes.ldif");
+ while (<F1>) {
+ s/{rootSuffix}/$tusRoot/;
+ print F2 $_;
+ }
+
+ close(F1);
+ close(F2);
+ &LDAPAdd("$serverRoot/$instanceID/config/addVLVIndexes.ldif");
+
+ &CopyTemplate("$tpsDir/scripts/schemaMods.ldif",
+ "$serverRoot/$instanceID/config/schemaMods.ldif");
+ &CopyTemplate("$tpsDir/scripts/addTokens.ldif",
+ "$serverRoot/$instanceID/config/addTokens.ldif");
+ &CopyTemplate("$tpsDir/scripts/addIndexes.ldif",
+ "$serverRoot/$instanceID/config/addIndexes.ldif");
+ &CopyTemplate("$tpsDir/scripts/addAgents.ldif",
+ "$serverRoot/$instanceID/config/addAgents.ldif");
+
+ &LDAPModify("$serverRoot/$instanceID/config/schemaMods.ldif");
+ &LDAPAdd("$serverRoot/$instanceID/config/addIndexes.ldif");
+ &LDAPAdd("$serverRoot/$instanceID/config/addTokens.ldif");
+ &LDAPAdd("$serverRoot/$instanceID/config/addAgents.ldif");
+}
+
+sub CopyTemplates
+{
+ &CopyTemplate("./templates/start", "$serverRoot/$instanceID/start");
+ chmod(0755, "$serverRoot/$instanceID/start");
+ &CopyTemplate("./templates/stop", "$serverRoot/$instanceID/stop");
+ chmod(0755, "$serverRoot/$instanceID/stop");
+ &CopyTemplate("./templates/config/contexts.properties",
+ "$serverRoot/$instanceID/config/contexts.properties");
+ &CopyTemplate("./templates/config/jvm12.conf",
+ "$serverRoot/$instanceID/config/jvm12.conf");
+ &CopyTemplate("./templates/config/magnus.conf",
+ "$serverRoot/$instanceID/config/magnus.conf");
+ &CopyTemplate("./templates/config/magnus.conf.clfilter",
+ "$serverRoot/$instanceID/config/magnus.conf.clfilter");
+ &CopyTemplate("./templates/config/mime.types",
+ "$serverRoot/$instanceID/config/mime.types");
+ &CopyTemplate("./templates/config/obj.conf",
+ "$serverRoot/$instanceID/config/obj.conf");
+ &CopyTemplate("./templates/config/obj.conf.clfilter",
+ "$serverRoot/$instanceID/config/obj.conf.clfilter");
+ &CopyTemplate("./templates/config/rules.properties",
+ "$serverRoot/$instanceID/config/rules.properties");
+ &CopyTemplate("./templates/config/server.dtd",
+ "$serverRoot/$instanceID/config/server.dtd");
+ &CopyTemplate("./templates/config/server.xml",
+ "$serverRoot/$instanceID/config/server.xml");
+ &CopyTemplate("./templates/config/server.xml.clfilter",
+ "$serverRoot/$instanceID/config/server.xml.clfilter");
+ &CopyTemplate("./templates/config/servlets.properties",
+ "$serverRoot/$instanceID/config/servlets.properties");
+ &CopyTemplate("./templates/config/web-apps.xml",
+ "$serverRoot/$instanceID/config/web-apps.xml");
+ &CopyTemplate("./templates/config/web-apps.xml.clfilter",
+ "$serverRoot/$instanceID/config/web-apps.xml.clfilter");
+}
+
+sub CreateInstanceDir
+{
+ print "Creating $serverRoot/$instanceID ...\n";
+ mkdir ("$serverRoot/$instanceID", 0755);
+
+ print "Creating $serverRoot/$instanceID/config ...\n";
+ mkdir ("$serverRoot/$instanceID/config", 0755);
+
+ print "Creating $serverRoot/$instanceID/logs ...\n";
+ mkdir ("$serverRoot/$instanceID/logs", 0755);
+}
+
+sub getPath
+{
+ if (&IsWindows()) {
+ return $ENV{PATH};
+ } else {
+ return $ENV{LD_LIBRARY_PATH};
+ }
+}
+
+sub setPath
+{
+ my ($path) = @_;
+
+ if (&IsWindows()) {
+ $ENV{PATH} = $path;
+ } else {
+ $ENV{LD_LIBRARY_PATH} = $path;
+ }
+}
+
+sub CertUtil_CreateDatabase
+{
+ my ($serverRoot, $prefix) = @_;
+
+ $OrgPath = &getPath();
+ &setPath($serverRoot . "/bin/cert/lib" . $pathSep . $OrgPath);
+
+ system("$serverRoot/bin/cert/tools/certutil -N -d $serverRoot/alias -P $prefix");
+
+ &setPath($OrgPath);
+}
+
+sub CertUtil_GenerateCSR
+{
+ my ($serverRoot, $prefix, $token, $subject) = @_;
+
+ $OrgPath = &getPath();
+ &setPath($serverRoot . "/bin/cert/lib" . $pathSep . $OrgPath);
+
+ system("$serverRoot/bin/cert/tools/certutil -R -d $serverRoot/alias -P $prefix -h '$token' -s '$subject' -a");
+
+ &setPath($OrgPath);
+}
+
+sub CertUtil_List
+{
+ my ($serverRoot, $prefix, $token) = @_;
+
+ $OrgPath = &getPath();
+ &setPath($serverRoot . "/bin/cert/lib" . $pathSep . $OrgPath);
+
+ system("$serverRoot/bin/cert/tools/certutil -L -d $serverRoot/alias -P $prefix -h '$token'");
+
+ &setPath($OrgPath);
+}
+
+sub CertUtil_Print
+{
+ my ($serverRoot, $prefix, $token, $nickName) = @_;
+
+ $OrgPath = &getPath();
+ &setPath($serverRoot . "/bin/cert/lib" . $pathSep . $OrgPath);
+
+ if ($token ne "") {
+ #57616 - certutil is not being consistent, nickname
+ # requires token name for no reason.
+ system("$serverRoot/bin/cert/tools/certutil -L -d $serverRoot/alias -P $prefix -h '$token' -n '$token:$nickName'");
+ } else {
+ system("$serverRoot/bin/cert/tools/certutil -L -d $serverRoot/alias -P $prefix -h '$token' -n '$nickName'");
+ }
+
+ &setPath($OrgPath);
+}
+
+sub CertUtil_Delete
+{
+ my ($serverRoot, $prefix, $token, $nickName) = @_;
+
+ $OrgPath = &getPath();
+ &setPath($serverRoot . "/bin/cert/lib" . $pathSep . $OrgPath);
+
+ system("$serverRoot/bin/cert/tools/certutil -D -d $serverRoot/alias -P $prefix -h '$token' -n '$nickName'");
+
+ &setPath($OrgPath);
+}
+
+sub CertUtil_ImportServerCert
+{
+ my ($serverRoot, $prefix, $token, $nickName, $cert) = @_;
+
+ $OrgPath = &getPath();
+ &setPath($serverRoot . "/bin/cert/lib" . $pathSep . $OrgPath);
+
+ open(F, "|$serverRoot/bin/cert/tools/certutil -A -d $serverRoot/alias -P $prefix -h '$token' -n '$nickName' -t 'u,u,u' -a");
+ print F $cert;
+ close(F);
+
+ &setPath($OrgPath);
+}
+
+sub CertUtil_ImportCACert
+{
+ my ($serverRoot, $prefix, $token, $nickName, $cert) = @_;
+
+ $OrgPath = &getPath();
+ &setPath($serverRoot . "/bin/cert/lib" . $pathSep . $OrgPath);
+
+ open(F, "|$serverRoot/bin/cert/tools/certutil -A -d $serverRoot/alias -P $prefix -h '$token' -n '$nickName' -t 'CT,CT,CT' -a");
+ print F $cert;
+ close(F);
+
+ &setPath($OrgPath);
+}
+
+sub LDAPModify
+{
+ my ($file) = @_;
+
+ $OrgPath = &getPath();
+ &setPath($serverRoot . "/shared/lib" . $pathSep . $OrgPath);
+
+ system("$serverRoot/shared/bin/ldapmodify -x -h '$tusHost' -p '$tusPort' -D 'cn=directory manager' -w '$tusPass' -f '$file'");
+
+ &setPath($OrgPath);
+}
+
+sub LDAPAdd
+{
+ my ($file) = @_;
+
+ $OrgPath = &getPath();
+ &setPath($serverRoot . "/shared/lib" . $pathSep . $OrgPath);
+
+ system("$serverRoot/shared/bin/ldapmodify -x -h '$tusHost' -p '$tusPort' -D 'cn=directory manager' -w '$tusPass' -a -f '$file'");
+
+ &setPath($OrgPath);
+}
+
+&Main();
diff --git a/base/tps/setup/registry_instance b/base/tps/setup/registry_instance
new file mode 100644
index 000000000..cb1c4b344
--- /dev/null
+++ b/base/tps/setup/registry_instance
@@ -0,0 +1,116 @@
+# Establish PKI Variable "Slot" Substitutions
+
+PKI_FLAVOR=[PKI_FLAVOR]
+export PKI_FLAVOR
+
+PKI_SUBSYSTEM_TYPE=[PKI_SUBSYSTEM_TYPE]
+export PKI_SUBSYSTEM_TYPE
+
+PKI_USER=[PKI_USER]
+export PKI_USER
+
+PKI_GROUP=[PKI_GROUP]
+export PKI_GROUP
+
+PKI_INSTANCE_ID=[PKI_INSTANCE_ID]
+export PKI_INSTANCE_ID
+
+PKI_INSTANCE_INITSCRIPT=[PKI_INSTANCE_INITSCRIPT]
+export PKI_INSTANCE_INITSCRIPT
+
+PKI_HTTPD_CONF=[HTTPD_CONF]
+export PKI_HTTPD_CONF
+
+PKI_SERVER_ROOT=[SERVER_ROOT]
+export PKI_SERVER_ROOT
+
+PKI_SYSTEM_USER_LIBRARIES=[SYSTEM_USER_LIBRARIES]
+export PKI_SYSTEM_USER_LIBRARIES
+
+PKI_FORTITUDE_DIR=[FORTITUDE_DIR]
+export PKI_FORTITUDE_DIR
+
+PKI_NSS_CONF=[NSS_CONF]
+export PKI_NSS_CONF
+
+PKI_SERVER_NAME=[SERVER_NAME]
+export PKI_SERVER_NAME
+
+PKI_LOCK_FILE="[PKI_LOCKDIR]/${PKI_INSTANCE_ID}.pid"
+export PKI_LOCK_FILE
+
+PKI_PID_FILE="[PKI_PIDDIR]/${PKI_INSTANCE_ID}.pid"
+export PKI_PID_FILE
+
+PKI_SELINUX_TYPE="pki_tps_t"
+export PKI_SELINUX_TYPE
+
+pki_instance_configuration_file=${PKI_SERVER_ROOT}/conf/CS.cfg
+export pki_instance_configuration_file
+
+RESTART_SERVER=${PKI_SERVER_ROOT}/conf/restart_server_after_configuration
+export RESTART_SERVER
+
+########################################################################
+# This section contains modified content of "/etc/sysconfig/httpd" #
+########################################################################
+# Configuration file for the ${PKI_INSTANCE_ID} service.
+
+#
+# The default processing model (MPM) is the process-based
+# 'prefork' model. A thread-based model, 'worker', is also
+# available, but does not work with some modules (such as PHP).
+# The service must be stopped before changing this variable.
+#
+PKI_HTTPD=${PKI_FORTITUDE_DIR}/sbin/httpd.worker
+export PKI_HTTPD
+
+#
+# To pass additional options (for instance, -D definitions) to the
+# httpd binary at startup, set PKI_OPTIONS here.
+#
+PKI_OPTIONS="-f ${PKI_HTTPD_CONF}"
+export PKI_OPTIONS
+
+#
+# By default, the httpd process is started in the C locale; to
+# change the locale in which the server runs, the PKI_HTTPD_LANG
+# variable can be set.
+#
+PKI_HTTPD_LANG=C
+export PKI_HTTPD_LANG
+########################################################################
+# #
+########################################################################
+
+# This will prevent initlog from swallowing up a pass-phrase prompt if
+# mod_ssl needs a pass-phrase from the user.
+PKI_INITLOG_ARGS=""
+export PKI_INITLOG_ARGS
+
+# Set PKI_HTTPD=/usr/sbin/httpd.worker in /etc/sysconfig/httpd to use a server
+# with the thread-based "worker" MPM; BE WARNED that some modules may not
+# work correctly with a thread-based MPM; notably PHP will refuse to start.
+
+# Path to the server binary and short-form for messages.
+httpd=${PKI_HTTPD}
+export httpd
+
+pki_logs_directory=${PKI_SERVER_ROOT}/logs
+export pki_logs_directory
+
+# see if httpd is linked with the openldap libraries - we need to override
+# their use of OpenSSL
+if [ ${OS} = "Linux" ]; then
+ hasopenldap=0
+
+ /usr/bin/ldd ${httpd} 2>&1 | grep libldap- > /dev/null 2>&1 && hasopenldap=1
+
+ if [ ${hasopenldap} -eq 1 ] ; then
+ LD_PRELOAD="${PKI_SYSTEM_USER_LIBRARIES}/libssl3.so:${LD_PRELOAD}"
+ export LD_PRELOAD
+ fi
+elif [ ${OS} = "SunOS" ]; then
+ LD_PRELOAD_64="${PKI_SYSTEM_USER_LIBRARIES}/dirsec/libssl3.so:${LD_PRELOAD_64}"
+ export LD_PRELOAD_64
+fi
diff --git a/base/tps/src/CMakeLists.txt b/base/tps/src/CMakeLists.txt
new file mode 100644
index 000000000..5f588663c
--- /dev/null
+++ b/base/tps/src/CMakeLists.txt
@@ -0,0 +1,148 @@
+project(tps_library CXX)
+
+set(TPS_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+add_subdirectory(tus)
+
+set(TPS_PUBLIC_INCLUDE_DIRS
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${TPS_INCLUDE_DIR}
+ CACHE INTERNAL "tps public include directories"
+)
+
+set(TPS_PRIVATE_INCLUDE_DIRS
+ ${TPS_PUBLIC_INCLUDE_DIRS}
+ ${CMAKE_BINARY_DIR}
+ ${NSS_INCLUDE_DIRS}
+ ${NSPR_INCLUDE_DIRS}
+ ${APR_INCLUDE_DIRS}
+ ${SVRCORE_INCLUDE_DIRS}
+ ${LDAP_INCLUDE_DIRS}
+)
+
+set(TPS_SHARED_LIBRARY
+ tps_library
+ CACHE INTERNAL "tps shared library"
+)
+
+set(TPS_LINK_LIBRARIES
+ ${NSPR_LIBRARIES}
+ ${NSS_LIBRARIES}
+ ${APR_LIBRARIES}
+ ${SVRCORE_LIBRARIES}
+ ${LDAP_LIBRARIES}
+ ${TOKENDB_SHARED_LIBRARY}
+)
+
+set(tps_library_SRCS
+ main/Buffer.cpp
+ main/NameValueSet.cpp
+ main/ConfigStore.cpp
+ main/Util.cpp
+ main/RA_Msg.cpp
+ main/RA_pblock.cpp
+ main/RA_Session.cpp
+ main/RA_Context.cpp
+ main/Login.cpp
+ main/SecureId.cpp
+ main/Memory.cpp
+ main/AuthenticationEntry.cpp
+ main/AuthParams.cpp
+ main/Authentication.cpp
+ main/AttributeSpec.cpp
+ main/ObjectSpec.cpp
+ main/PKCS11Obj.cpp
+ main/LogFile.cpp
+ main/RollingLogFile.cpp
+ httpClient/httpClient.cpp
+ httpClient/Cache.cpp
+ httpClient/engine.cpp
+ httpClient/http.cpp
+ httpClient/response.cpp
+ httpClient/request.cpp
+ httpClient/nscperror.cpp
+ cms/HttpConnection.cpp
+ cms/ConnectionInfo.cpp
+ cms/CertEnroll.cpp
+ apdu/APDU.cpp
+ apdu/Unblock_Pin_APDU.cpp
+ apdu/Create_Object_APDU.cpp
+ apdu/Set_Pin_APDU.cpp
+ apdu/Set_IssuerInfo_APDU.cpp
+ apdu/Get_IssuerInfo_APDU.cpp
+ apdu/Create_Pin_APDU.cpp
+ apdu/List_Pins_APDU.cpp
+ apdu/Initialize_Update_APDU.cpp
+ apdu/Get_Version_APDU.cpp
+ apdu/Get_Status_APDU.cpp
+ apdu/Get_Data_APDU.cpp
+ apdu/External_Authenticate_APDU.cpp
+ apdu/Generate_Key_APDU.cpp
+ apdu/Read_Buffer_APDU.cpp
+ apdu/Read_Object_APDU.cpp
+ apdu/Write_Object_APDU.cpp
+ apdu/Put_Key_APDU.cpp
+ apdu/Select_APDU.cpp
+ apdu/Delete_File_APDU.cpp
+ apdu/Install_Applet_APDU.cpp
+ apdu/Format_Muscle_Applet_APDU.cpp
+ apdu/Load_File_APDU.cpp
+ apdu/Install_Load_APDU.cpp
+ apdu/Lifecycle_APDU.cpp
+ apdu/List_Objects_APDU.cpp
+ apdu/Import_Key_APDU.cpp
+ apdu/Import_Key_Enc_APDU.cpp
+ apdu/APDU_Response.cpp
+ msg/RA_Begin_Op_Msg.cpp
+ msg/RA_End_Op_Msg.cpp
+ msg/RA_Login_Request_Msg.cpp
+ msg/RA_Login_Response_Msg.cpp
+ msg/RA_SecureId_Request_Msg.cpp
+ msg/RA_SecureId_Response_Msg.cpp
+ msg/RA_ASQ_Request_Msg.cpp
+ msg/RA_ASQ_Response_Msg.cpp
+ msg/RA_New_Pin_Request_Msg.cpp
+ msg/RA_New_Pin_Response_Msg.cpp
+ msg/RA_Token_PDU_Request_Msg.cpp
+ msg/RA_Token_PDU_Response_Msg.cpp
+ msg/RA_Status_Update_Request_Msg.cpp
+ msg/RA_Status_Update_Response_Msg.cpp
+ msg/RA_Extended_Login_Request_Msg.cpp
+ msg/RA_Extended_Login_Response_Msg.cpp
+ channel/Channel.cpp
+ channel/Secure_Channel.cpp
+ engine/RA.cpp
+ processor/RA_Processor.cpp
+ processor/RA_Enroll_Processor.cpp
+ processor/RA_Pin_Reset_Processor.cpp
+ processor/RA_Renew_Processor.cpp
+ processor/RA_Unblock_Processor.cpp
+ processor/RA_Format_Processor.cpp
+ selftests/SelfTest.cpp
+ selftests/TPSPresence.cpp
+ selftests/TPSSystemCertsVerification.cpp
+ selftests/TPSValidity.cpp
+)
+
+include_directories(${TPS_PRIVATE_INCLUDE_DIRS})
+
+add_library(${TPS_SHARED_LIBRARY} SHARED ${tps_library_SRCS})
+target_link_libraries(${TPS_SHARED_LIBRARY} ${TPS_LINK_LIBRARIES})
+
+set_target_properties(
+ ${TPS_SHARED_LIBRARY}
+ PROPERTIES
+ OUTPUT_NAME
+ tps
+)
+
+install(
+ TARGETS
+ ${TPS_SHARED_LIBRARY}
+ LIBRARY DESTINATION ${LIB_INSTALL_DIR}/tps
+)
+
+add_subdirectory(authentication)
+add_subdirectory(modules)
+
diff --git a/base/tps/src/apdu/APDU.cpp b/base/tps/src/apdu/APDU.cpp
new file mode 100644
index 000000000..1ae729cc5
--- /dev/null
+++ b/base/tps/src/apdu/APDU.cpp
@@ -0,0 +1,331 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "engine/RA.h"
+#include "main/Util.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs an APDU.
+ *
+ * ==============
+ * APDU:
+ * APDU are commands that can be sent from an authorized entity
+ * (such as RA) to the token. It takes the following form:
+ * ---------------------------------------------------
+ * | CLA | INS | P1 | P2 | lc | data...
+ * ---------------------------------------------------
+ *
+ * The values for the APDU header: CLA, INS, P1, P2 and lc are defined
+ * in each individual APDU class.
+ *
+ * ==============
+ * Status Words (response):
+ * When APDUs are sent to the token, a response is returned. The following
+ * is a list of all possible Return Codes (Status Words):
+ *
+ * <I'm hoping not having to type this out...waiting for Bob to get back
+ * to me with an electronic copy of his file...>
+ *
+ * ==============
+ * ObjectID:
+ * byte[0] - an ASCII letter,
+ * 'c' - An object containing PKCS11 attributes for a certificate
+ * 'k' - An object containing PKCS11 attributes for a public or private key
+ * 'r' - An object containing PKCS11 attributes for a "reader"
+ * <upper case letters signify objects containing raw data
+ * corresponding to lower cases objects above
+ * byte[1] - an ASCII numeral, in the range '0' - '9'
+ * byte[2] - binary zero
+ * byte[3] - binary zero
+ *
+ * ==============
+ * ACLs:
+ * Each key or object on the card is associated with an ACL.
+ *
+ * ACL for objects:
+ * [2-byte] Read Permissions;
+ * [2-byte] Write Permissions;
+ * [2-byte] Delete Permissions;
+ *
+ * Each permission is a 2-byte word. A 1 in a bit grants permission
+ * to it's corresponding identity if pass authentication.
+ * permission 2-byte word format:
+ * Bit 15 - reserved
+ * Bit 14 - Identity #14 (strong - Secure Channel required)
+ * Bit 13 - reserved
+ * ...
+ * Bit 7 - Identity #7 (PIN identity)
+ * ...
+ * Bit 1 - Identity #1 (PIN identity)
+ * Bit 0 - Identity #0 (PIN identity)
+ *
+ * All 0 means operation never allowed
+ */
+TPS_PUBLIC APDU::APDU ()
+{
+ m_data = Buffer(0, (BYTE)0);
+ m_mac = Buffer(0, (BYTE)0);
+} /* APDU */
+
+/**
+ * Destroys an APDU.
+ */
+TPS_PUBLIC APDU::~APDU ()
+{
+} /* ~APDU */
+
+/**
+ * Copy constructor.
+ */
+TPS_PUBLIC APDU::APDU (const APDU &cpy)
+{
+ *this = cpy;
+} /* APDU */
+
+/**
+ * Operator for simple assignment.
+ */
+TPS_PUBLIC APDU& APDU::operator=(const APDU &cpy)
+{
+ if (this == &cpy)
+ return *this;
+ m_cla = cpy.m_cla;
+ m_ins = cpy.m_ins;
+ m_p1 = cpy.m_p1;
+ m_p2 = cpy.m_p2;
+ m_data = cpy.m_data;
+ return *this;
+} /* operator= */
+
+TPS_PUBLIC APDU_Type APDU::GetType()
+{
+ return APDU_UNDEFINED;
+}
+
+/**
+ * Sets APDU's CLA parameter.
+ */
+TPS_PUBLIC void APDU::SetCLA(BYTE cla)
+{
+ m_cla = cla;
+} /* SetCLA */
+
+/**
+ * Sets APDU's INS parameter.
+ */
+TPS_PUBLIC void APDU::SetINS(BYTE ins)
+{
+ m_ins = ins;
+} /* SetINS */
+
+/**
+ * Sets APDU's P1 parameter.
+ */
+TPS_PUBLIC void APDU::SetP1(BYTE p1)
+{
+ m_p1 = p1;
+} /* SetP1 */
+
+/**
+ * Sets APDU's P2 parameter.
+ */
+TPS_PUBLIC void APDU::SetP2(BYTE p2)
+{
+ m_p2 = p2;
+} /* SetP2 */
+
+
+TPS_PUBLIC BYTE APDU::GetCLA()
+{
+ return m_cla;
+}
+
+TPS_PUBLIC BYTE APDU::GetINS()
+{
+ return m_ins;
+}
+
+TPS_PUBLIC BYTE APDU::GetP1()
+{
+ return m_p1;
+}
+
+TPS_PUBLIC BYTE APDU::GetP2()
+{
+ return m_p2;
+}
+
+TPS_PUBLIC Buffer &APDU::GetData()
+{
+ return m_data;
+}
+
+TPS_PUBLIC Buffer &APDU::GetMAC()
+{
+ return m_mac;
+}
+
+/**
+ * Sets APDU's data parameter.
+ */
+TPS_PUBLIC void APDU::SetData(Buffer &data)
+{
+ m_data = data;
+} /* SetData */
+
+TPS_PUBLIC void APDU::SetMAC(Buffer &mac)
+{
+ m_mac = mac;
+} /* SetMAC */
+
+/**
+ * populates "data" with data that's to be mac'd.
+ * note: mac is not handled in here
+ *
+ * @param data results buffer
+ */
+TPS_PUBLIC void APDU::GetDataToMAC(Buffer &data)
+{
+ data += Buffer(1, m_cla);
+ data += Buffer(1, m_ins);
+ data += Buffer(1, m_p1);
+ data += Buffer(1, m_p2);
+ data += Buffer(1, (BYTE)m_data.size() + 8);
+ data += Buffer(m_data, m_data.size());
+}
+
+/*
+ * pad the message, if needed, and then
+ * encrypt it with the encryption session key
+ * and then set data
+ *
+ */
+TPS_PUBLIC PRStatus APDU::SecureMessage(PK11SymKey *encSessionKey)
+{
+ PRStatus rv = PR_SUCCESS;
+ Buffer data_to_enc;
+ Buffer padding;
+ Buffer data_encrypted;
+ int pad_needed = 0;
+#ifdef ENC_DEBUG
+ m_plainText = m_data;
+ // developer debugging only, not for production
+// RA::DebugBuffer("APDU::SecureMessage", "plaintext (pre padding) = ", &m_plainText);
+#endif
+
+ if (encSessionKey == NULL) {
+ // RA::Debug("APDU::SecureMessage", "no encryption session key");
+ rv = PR_FAILURE;
+ goto done;
+ }
+// RA::Debug(LL_ALL_DATA_IN_PDU, "APDU::SecureMessage", "plaintext data length = %d", m_data.size());
+
+ data_to_enc += (BYTE)m_data.size();
+ data_to_enc += m_data;
+
+ if ((data_to_enc.size() % 8) == 0)
+ pad_needed = 0;
+ else if (data_to_enc.size() < 8) {
+ pad_needed = 8 - data_to_enc.size();
+ } else { // data size > 8 and not divisible by 8
+ pad_needed = 8 - (data_to_enc.size() % 8);
+ }
+ if (pad_needed) {
+// RA::Debug(LL_ALL_DATA_IN_PDU, "APDU::SecureMessage", "padding needed =%d", pad_needed);
+ data_to_enc += Buffer(1, 0x80);
+ pad_needed --;
+
+ if (pad_needed) {
+// RA::Debug(LL_ALL_DATA_IN_PDU, "APDU::SecureMessage", "padding needed =%d", pad_needed);
+ padding = Buffer(pad_needed, (BYTE)0);
+ for (int i = 0; i < pad_needed; i++) {
+ ((BYTE*)padding)[i] = 0x00;
+ } /* for */
+ } // pad needed
+
+ } else {
+ // RA::Debug(LL_ALL_DATA_IN_PDU, "APDU::SecureMessage", "padding not needed");
+ }
+
+ if (padding.size() > 0) {
+ data_to_enc += Buffer(padding, padding.size());
+ }
+
+#ifdef ENC_DEBUG
+// RA::DebugBuffer("APDU::SecureMessage", "data to encrypt (post padding)= ",&data_to_enc);
+#endif
+
+ // now, encrypt "data_to_enc"
+ rv = Util::EncryptData(encSessionKey, data_to_enc, data_encrypted);
+ if (rv == PR_FAILURE) {
+ // RA::Error("APDU::SecureMessage", "encryption failed");
+ goto done;
+ } else {
+ // RA::Debug(LL_PER_PDU, "APDU::SecureMessage", "encryption succeeded");
+ // RA::Debug(LL_PER_PDU, "APDU::SecureMessage", "encrypted data length = %d",
+// data_encrypted.size());
+ // set "m_data"
+ m_data = data_encrypted;
+ }
+
+ // lc should be automatically set correctly when getEncoding is called
+
+ done:
+ return rv;
+
+}
+
+
+/**
+ * Retrieves APDU's encoding.
+ * The encoding of APDU is as follows:
+ *
+ * CLA 1 byte
+ * INS 1 byte
+ * P1 1 byte
+ * P2 1 byte
+ * <Data Size> 1 byte
+ * <Data> <Data Size> byte(s)
+ * 0 1 byte
+ *
+ * @param data the result buffer which will contain the actual data
+ * including the APDU header, data, and pre-calculated mac.
+ */
+TPS_PUBLIC void APDU::GetEncoding(Buffer &data)
+{
+ data += Buffer(1, m_cla);
+ data += Buffer(1, m_ins);
+ data += Buffer(1, m_p1);
+ data += Buffer(1, m_p2);
+ data += Buffer(1, (BYTE)m_data.size() + m_mac.size());
+ data += Buffer(m_data, m_data.size());
+ if (m_mac.size() > 0) {
+ data += Buffer(m_mac, m_mac.size());
+ }
+} /* Encode */
diff --git a/base/tps/src/apdu/APDU_Response.cpp b/base/tps/src/apdu/APDU_Response.cpp
new file mode 100644
index 000000000..fac9b1ff4
--- /dev/null
+++ b/base/tps/src/apdu/APDU_Response.cpp
@@ -0,0 +1,111 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include "apdu/APDU_Response.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a response object.
+ */
+APDU_Response::APDU_Response ()
+{
+}
+
+TPS_PUBLIC APDU_Response::APDU_Response (Buffer &data)
+{
+ m_data = data;
+}
+
+/**
+ * Destroys a response object.
+ */
+APDU_Response::~APDU_Response ()
+{
+}
+
+/**
+ * Copy constructor.
+ */
+APDU_Response::APDU_Response (const APDU_Response &cpy)
+{
+ *this = cpy;
+}
+
+/**
+ * Operator for simple assignment.
+ */
+APDU_Response& APDU_Response::operator=(const APDU_Response &cpy)
+{
+ if (this == &cpy)
+ return *this;
+ m_data = cpy.m_data;
+ return *this;
+}
+
+
+
+/**
+ * Retrieves the byte encoding of the response
+ * object including the last 2 state bytes.
+ */
+TPS_PUBLIC Buffer &APDU_Response::GetData()
+{
+ return m_data;
+}
+
+/**
+ * Retrieves the 1st status byte.
+ */
+BYTE APDU_Response::GetSW1()
+{
+ if (m_data == NULL) {
+ return 0x0;
+ } else {
+ if (m_data.size() < 2) {
+ return 0x0;
+ } else {
+ return ((BYTE*)m_data)[((int)m_data.size())-2];
+ }
+ }
+}
+
+
+/**
+ * Retrieves the 2nd status byte.
+ */
+BYTE APDU_Response::GetSW2()
+{
+ if (m_data == NULL) {
+ return 0x0;
+ } else {
+ if (m_data.size() < 2) {
+ return 0x0;
+ } else {
+ return ((BYTE*)m_data)[((int)m_data.size())-1];
+ }
+ }
+}
diff --git a/base/tps/src/apdu/Create_Object_APDU.cpp b/base/tps/src/apdu/Create_Object_APDU.cpp
new file mode 100644
index 000000000..2da9f20d3
--- /dev/null
+++ b/base/tps/src/apdu/Create_Object_APDU.cpp
@@ -0,0 +1,121 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Create_Object_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a Create Object APDU. This APDU is usually sent right
+ * before Write_Buffer_APDU is sent. This APDU only creates an Object
+ * on token, but does not actually writes object content until
+ * Write_Buffer_APDU is sent.
+ *
+ * CreateObject APDU format:
+ * CLA 0x84
+ * INS 0x5a
+ * P1 0x00
+ * P2 0x00
+ * lc 0x0e
+ * DATA <Object Parameters>
+ *
+ * [DATA] Object Parameters are:
+ * Long Object ID;
+ * Long Object Size;
+ * ObjectACL ObjectACL;
+ *
+ * Connection requirement:
+ * Secure Channel
+ *
+ * Possible error Status Codes:
+ * 9C 06 - unauthorized
+ * 9C 08 - object already exists
+ * 9C 01 - insufficient memory on card to complete the operation
+ *
+ * NOTE:
+ * Observe that the PIN identity is hard-coded at n.2 for each
+ * permission. In Housekey, this is probably a non-issue, however,
+ * in housekey, do we not allow multiple people (presumably closely
+ * -related) to share one token with individual certs? We should
+ * consider exposing this as an input param.
+ *
+ * @param object_id as defined in APDU
+ * @param len length of object
+ * @see APDU
+ */
+TPS_PUBLIC Create_Object_APDU::Create_Object_APDU (BYTE *object_id, BYTE *permissions, int len)
+{
+ SetCLA(0x84);
+ SetINS(0x5a);
+ SetP1(0x00);
+ SetP2(0x00);
+ Buffer data;
+ data =
+ /* Object ID */
+ Buffer(1, (BYTE)object_id[0]) +
+ Buffer(1, (BYTE)object_id[1]) +
+ Buffer(1, (BYTE)object_id[2]) +
+ Buffer(1, (BYTE)object_id[3]) +
+ /* data length */
+ Buffer(1, (BYTE)(len >> 24)) +
+ Buffer(1, (BYTE)((len >> 16) & 0xff)) +
+ Buffer(1, (BYTE)((len >> 8) & 0xff)) +
+ Buffer(1, (BYTE)(len & 0xff)) +
+ /* ACLs */
+
+ /* should take from caller
+ // read permission
+ Buffer(1, (BYTE)0xFF) + // means "read" never allowed
+ Buffer(1, (BYTE)0xFF) +
+
+ // write permission
+ Buffer(1, (BYTE)0x40) + //means "write" for identity n.2 (PIN required)
+ Buffer(1, (BYTE)0x00) +
+
+ // delete permission
+ Buffer(1, (BYTE)0x40) + //means "delete" for identity n.2 (PIN) required
+ Buffer(1, (BYTE)0x00);
+ */
+
+ Buffer(1, (BYTE) permissions[0]) +
+ Buffer(1, (BYTE) permissions[1]) +
+ Buffer(1, (BYTE) permissions[2]) +
+ Buffer(1, (BYTE) permissions[3]) +
+ Buffer(1, (BYTE) permissions[4]) +
+ Buffer(1, (BYTE) permissions[5]);
+
+ SetData(data);
+}
+
+TPS_PUBLIC Create_Object_APDU::~Create_Object_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Create_Object_APDU::GetType()
+{
+ return APDU_CREATE_OBJECT;
+}
diff --git a/base/tps/src/apdu/Create_Pin_APDU.cpp b/base/tps/src/apdu/Create_Pin_APDU.cpp
new file mode 100644
index 000000000..db2ad3d0a
--- /dev/null
+++ b/base/tps/src/apdu/Create_Pin_APDU.cpp
@@ -0,0 +1,73 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include <string.h>
+#include "apdu/APDU.h"
+#include "apdu/Create_Pin_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs CreatePIN APDU.
+ * CLA 0x80
+ * INS 0x40
+ * P1 <Pin number>
+ * P2 <Max # of allowed attempts>
+ * lc <data length>
+ * DATA <Pin Value>
+ *
+ * Connection requirement:
+ * Secure Channel
+ *
+ * Possible error Status Codes:
+ * 9C 06 - unauthorized
+ * 9C 10 - incorrect p1
+ * 9C 0E - invalid parameter (data)
+ *
+ * @param p1 Pin number: 0x00 - 0x07
+ * @param p2 Max # of consecutive unsuccessful verifications
+ * before the PIN blocks.
+ * @param data pin
+ * @see APDU
+ */
+TPS_PUBLIC Create_Pin_APDU::Create_Pin_APDU (BYTE p1, BYTE p2, Buffer &data)
+{
+// SetCLA(0xB0);
+ SetCLA(0x84);
+ SetINS(0x40);
+ SetP1(p1);
+ SetP2(p2);
+ SetData(data);
+}
+
+TPS_PUBLIC Create_Pin_APDU::~Create_Pin_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Create_Pin_APDU::GetType()
+{
+ return APDU_CREATE_PIN;
+}
diff --git a/base/tps/src/apdu/Delete_File_APDU.cpp b/base/tps/src/apdu/Delete_File_APDU.cpp
new file mode 100644
index 000000000..2306f0255
--- /dev/null
+++ b/base/tps/src/apdu/Delete_File_APDU.cpp
@@ -0,0 +1,59 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Delete_File_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Delete File APDU.
+ */
+TPS_PUBLIC Delete_File_APDU::Delete_File_APDU (Buffer &AID)
+{
+ SetCLA(0x84);
+ SetINS(0xE4);
+ SetP1(0x00);
+ SetP2(0x00);
+
+ Buffer AIDTLV(AID.size() + 2);
+ ((BYTE*)AIDTLV)[0] = 0x4F;
+ ((BYTE*)AIDTLV)[1] = AID.size();
+ for(unsigned int i=0; i < AID.size(); ++i ) {
+ ((BYTE*)AIDTLV)[i+2] = ((BYTE*)AID)[i];
+ }
+
+ SetData(AIDTLV);
+}
+
+TPS_PUBLIC Delete_File_APDU::~Delete_File_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Delete_File_APDU::GetType()
+{
+ return APDU_DELETE_FILE;
+}
diff --git a/base/tps/src/apdu/External_Authenticate_APDU.cpp b/base/tps/src/apdu/External_Authenticate_APDU.cpp
new file mode 100644
index 000000000..32c414584
--- /dev/null
+++ b/base/tps/src/apdu/External_Authenticate_APDU.cpp
@@ -0,0 +1,76 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/External_Authenticate_APDU.h"
+#include "channel/Secure_Channel.h"
+#include "engine/RA.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs External Authenticate APDU. This allows
+ * setting of the security level.
+ */
+TPS_PUBLIC External_Authenticate_APDU::External_Authenticate_APDU (Buffer &data,
+ SecurityLevel sl)
+{
+ SetCLA(0x84);
+ SetINS(0x82);
+ SetP1(0x01);
+
+ if (sl == SECURE_MSG_MAC_ENC) {
+ SetP1(0x03);
+// RA::Debug("External_Authenticate_APDU::External_Authenticate_APDU",
+ // "Security level set to 3 - attempted =%d", (int)sl);
+ } else if (sl == SECURE_MSG_NONE) {
+ SetP1(0x00);
+// RA::Debug("External_Authenticate_APDU::External_Authenticate_APDU",
+// "Security level set to 0 - attempted =%d", (int)sl);
+ } else { // default
+ SetP1(0x01);
+ // RA::Debug("External_Authenticate_APDU::External_Authenticate_APDU",
+// "Security level set to 1 - attempted =%d", (int)sl);
+ }
+
+ SetP2(0x00);
+ SetData(data);
+}
+
+TPS_PUBLIC External_Authenticate_APDU::~External_Authenticate_APDU ()
+{
+}
+
+TPS_PUBLIC Buffer &External_Authenticate_APDU::GetHostCryptogram()
+{
+ return GetData();
+}
+
+TPS_PUBLIC APDU_Type External_Authenticate_APDU::GetType()
+{
+ return APDU_EXTERNAL_AUTHENTICATE;
+}
+
diff --git a/base/tps/src/apdu/Format_Muscle_Applet_APDU.cpp b/base/tps/src/apdu/Format_Muscle_Applet_APDU.cpp
new file mode 100644
index 000000000..dff95b8cd
--- /dev/null
+++ b/base/tps/src/apdu/Format_Muscle_Applet_APDU.cpp
@@ -0,0 +1,107 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Format_Muscle_Applet_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Format Muscle Applet APDU.
+ */
+TPS_PUBLIC Format_Muscle_Applet_APDU::Format_Muscle_Applet_APDU (
+ unsigned short memSize,
+ Buffer &PIN0, BYTE pin0Tries,
+ Buffer &unblockPIN0, BYTE unblock0Tries,
+ Buffer &PIN1, BYTE pin1Tries,
+ Buffer &unblockPIN1, BYTE unblock1Tries,
+ unsigned short objCreationPermissions,
+ unsigned short keyCreationPermissions,
+ unsigned short pinCreationPermissions)
+{
+ SetCLA(0xB0);
+ SetINS(0x2A);
+ SetP1(0x00);
+ SetP2(0x00);
+
+ Buffer data; data.reserve(100);
+ Buffer pin((BYTE *)"Muscle00", 8);
+ data += pin.size();
+ data += pin;
+
+ pin = Buffer((BYTE*) PIN0, PIN0.size());
+ data += pin0Tries; // pin tries
+ data += unblock0Tries; // unblock tries
+ data += pin.size();
+ data += pin;
+
+ pin = Buffer((BYTE*)unblockPIN0, unblockPIN0.size());
+ data += pin.size();
+ data += pin;
+
+ pin = Buffer((BYTE*)PIN1, PIN1.size());
+ data += pin1Tries; // pin tries
+ data += unblock1Tries; // unblock tries
+ data += pin.size();
+ data += pin;
+
+ pin = Buffer((BYTE*)unblockPIN1, unblockPIN1.size());
+ data += pin.size();
+ data += pin;
+
+ data += (BYTE)0; data += (BYTE)0; // fluff
+
+ data += (memSize >> 8) & 0xff;
+ data += memSize & 0xff;
+
+ data += (BYTE)(objCreationPermissions >> 8);
+ data += (BYTE)(objCreationPermissions & 0xFF);
+ data += (BYTE)(keyCreationPermissions >> 8);
+ data += (BYTE)(keyCreationPermissions & 0xFF);
+ data += (BYTE)(pinCreationPermissions >> 8);
+ data += (BYTE)(pinCreationPermissions & 0xFF);
+
+ SetData(data);
+}
+
+TPS_PUBLIC Format_Muscle_Applet_APDU::~Format_Muscle_Applet_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Format_Muscle_Applet_APDU::GetType()
+{
+ return APDU_FORMAT_MUSCLE_APPLET;
+}
+
+TPS_PUBLIC void Format_Muscle_Applet_APDU::GetEncoding(Buffer &data)
+{
+ data += Buffer(1, m_cla);
+ data += Buffer(1, m_ins);
+ data += Buffer(1, m_p1);
+ data += Buffer(1, m_p2);
+ data += Buffer(1, (BYTE)m_data.size());
+ data += Buffer(m_data, m_data.size());
+} /* Encode */
diff --git a/base/tps/src/apdu/Generate_Key_APDU.cpp b/base/tps/src/apdu/Generate_Key_APDU.cpp
new file mode 100644
index 000000000..7d78b5513
--- /dev/null
+++ b/base/tps/src/apdu/Generate_Key_APDU.cpp
@@ -0,0 +1,68 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Generate_Key_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Generate Key APDU.
+ */
+TPS_PUBLIC Generate_Key_APDU::Generate_Key_APDU (BYTE p1, BYTE p2, BYTE alg, int keysize, BYTE option,
+BYTE type, Buffer &wrapped_challenge, Buffer &key_check)
+{
+ SetCLA(0x84);
+ SetINS(0x0C);
+ SetP1(p1);
+ SetP2(p2);
+ Buffer data;
+ data =
+ Buffer(1,alg) +
+ Buffer(1,(BYTE)(keysize/256)) +
+ Buffer(1,(BYTE)(keysize%256)) +
+ Buffer(1,option) +
+ Buffer(1,type) +
+ Buffer(1,(BYTE)wrapped_challenge.size()) +
+ Buffer(wrapped_challenge) +
+
+ Buffer(1,(BYTE)key_check.size());
+
+ if(key_check.size() > 0)
+ data = data + Buffer(key_check);
+
+ SetData(data);
+
+}
+
+TPS_PUBLIC Generate_Key_APDU::~Generate_Key_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Generate_Key_APDU::GetType()
+{
+ return APDU_GENERATE_KEY;
+}
diff --git a/base/tps/src/apdu/Get_Data_APDU.cpp b/base/tps/src/apdu/Get_Data_APDU.cpp
new file mode 100644
index 000000000..1cb4d9a5b
--- /dev/null
+++ b/base/tps/src/apdu/Get_Data_APDU.cpp
@@ -0,0 +1,59 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Get_Data_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Get Data APDU.
+ */
+TPS_PUBLIC Get_Data_APDU::Get_Data_APDU ()
+{
+ SetCLA(0x80);
+ SetINS(0xCA);
+ SetP1(0x9F);
+ SetP2(0x7F);
+}
+
+TPS_PUBLIC Get_Data_APDU::~Get_Data_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Get_Data_APDU::GetType()
+{
+ return APDU_GET_DATA;
+}
+
+TPS_PUBLIC void Get_Data_APDU::GetEncoding(Buffer &data)
+{
+ data += Buffer(1, m_cla);
+ data += Buffer(1, m_ins);
+ data += Buffer(1, m_p1);
+ data += Buffer(1, m_p2);
+ data += Buffer(1, 0x2D);
+} /* Encode */
diff --git a/base/tps/src/apdu/Get_IssuerInfo_APDU.cpp b/base/tps/src/apdu/Get_IssuerInfo_APDU.cpp
new file mode 100644
index 000000000..c83d920df
--- /dev/null
+++ b/base/tps/src/apdu/Get_IssuerInfo_APDU.cpp
@@ -0,0 +1,80 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include <string.h>
+#include "apdu/APDU.h"
+#include "apdu/Get_IssuerInfo_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs GetIssuer APDU.
+ *
+ * SecureGetIssuer APDU format:
+ * CLA 0x84
+ * INS 0xF6
+ * P1 0x00
+ * P2 0x00
+ * lc 0xE0
+ * DATA <Issuer Info>
+ *
+ * Connection requirement:
+ * Secure Channel
+ *
+ * Possible error Status Codes:
+ * 9C 06 - unauthorized
+ *
+ * @param p1 always 0x00
+ * @param p2 always 0x00
+ * @param data issuer info
+ * @see APDU
+ */
+TPS_PUBLIC Get_IssuerInfo_APDU::Get_IssuerInfo_APDU ()
+{
+ SetCLA(0x84);
+ SetINS(0xF6);
+ SetP1(0x00);
+ SetP2(0x00);
+}
+
+TPS_PUBLIC Get_IssuerInfo_APDU::~Get_IssuerInfo_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Get_IssuerInfo_APDU::GetType()
+{
+ return APDU_GET_ISSUERINFO;
+}
+
+TPS_PUBLIC void Get_IssuerInfo_APDU::GetEncoding(Buffer &data)
+{
+ data += Buffer(1, m_cla);
+ data += Buffer(1, m_ins);
+ data += Buffer(1, m_p1);
+ data += Buffer(1, m_p2);
+ data += Buffer(1, 0xe0);
+} /* Encode */
+
diff --git a/base/tps/src/apdu/Get_Status_APDU.cpp b/base/tps/src/apdu/Get_Status_APDU.cpp
new file mode 100644
index 000000000..dcf7c9fac
--- /dev/null
+++ b/base/tps/src/apdu/Get_Status_APDU.cpp
@@ -0,0 +1,59 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Get_Status_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Get Status APDU.
+ */
+TPS_PUBLIC Get_Status_APDU::Get_Status_APDU ()
+{
+ SetCLA(0xB0);
+ SetINS(0x3C);
+ SetP1(0x00);
+ SetP2(0x00);
+}
+
+TPS_PUBLIC Get_Status_APDU::~Get_Status_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Get_Status_APDU::GetType()
+{
+ return APDU_GET_STATUS;
+}
+
+TPS_PUBLIC void Get_Status_APDU::GetEncoding(Buffer &data)
+{
+ data += Buffer(1, m_cla);
+ data += Buffer(1, m_ins);
+ data += Buffer(1, m_p1);
+ data += Buffer(1, m_p2);
+ data += Buffer(1, 16);
+} /* Encode */
diff --git a/base/tps/src/apdu/Get_Version_APDU.cpp b/base/tps/src/apdu/Get_Version_APDU.cpp
new file mode 100644
index 000000000..eb7e53728
--- /dev/null
+++ b/base/tps/src/apdu/Get_Version_APDU.cpp
@@ -0,0 +1,59 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Get_Version_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Get Version APDU.
+ */
+TPS_PUBLIC Get_Version_APDU::Get_Version_APDU ()
+{
+ SetCLA(0xB0);
+ SetINS(0x70);
+ SetP1(0x00);
+ SetP2(0x00);
+}
+
+TPS_PUBLIC Get_Version_APDU::~Get_Version_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Get_Version_APDU::GetType()
+{
+ return APDU_GET_VERSION;
+}
+
+TPS_PUBLIC void Get_Version_APDU::GetEncoding(Buffer &data)
+{
+ data += Buffer(1, m_cla);
+ data += Buffer(1, m_ins);
+ data += Buffer(1, m_p1);
+ data += Buffer(1, m_p2);
+ data += Buffer(1, 4);
+} /* Encode */
diff --git a/base/tps/src/apdu/Import_Key_APDU.cpp b/base/tps/src/apdu/Import_Key_APDU.cpp
new file mode 100644
index 000000000..18c6c886f
--- /dev/null
+++ b/base/tps/src/apdu/Import_Key_APDU.cpp
@@ -0,0 +1,79 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include <string.h>
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+#include "apdu/Import_Key_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Import Key APDU.
+ *
+ * CLA 0x84
+ * INS 0x32
+ * P1 Key Number (0x00 -0x0F) - key slot number defined in CS.cfg
+ * P2 0x00
+ * P3 Import Parameters Length (6 bytes: 3 shorts if just for ACL)
+ * DATA Import Parameters
+ *
+ * This function allows th eimport of a key into the card by (over)-writing the Cardlet memory. Object ID 0xFFFFFFFE needs to be initialized with a key blob before invocation of this function so tha tit can retrieve the key from this object. The exact key blob contents depend on th ekey's algorithm, type and actual import parameters. The key's number, algorithm type, and parameters are specified by argumetns P1, P2, P3, and DATA. Appropriate values for these are specified below:
+
+[DATA]
+Import Parameters:
+KeyACL ACL for the imported key;
+Byte[] Additional parameters; // Optional
+If KeyBlob's Encoding is BLOB_ENC_PLAIN(0x00), there are no additional parameters.
+ */
+TPS_PUBLIC Import_Key_APDU::Import_Key_APDU (BYTE p1)
+{
+ SetCLA(0x84);
+ SetINS(0x32);
+ SetP1(p1);
+ SetP2(0x00);
+ // SetP3(p3);
+
+ Buffer data;
+ data =
+ Buffer(1, (BYTE)0xFF) + // means "read allowed" by anyone
+ Buffer(1, (BYTE) 0xFF) +
+ Buffer(1, (BYTE) 0x40) + // means "write" allowed for RA only
+ Buffer(1, (BYTE) 0x00) +
+ Buffer(1, (BYTE) 0xFF) + // means "use" allowed for everyone
+ Buffer(1, (BYTE) 0xFF);
+
+ SetData(data);
+}
+
+TPS_PUBLIC Import_Key_APDU::~Import_Key_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Import_Key_APDU::GetType()
+{
+ return APDU_IMPORT_KEY;
+}
diff --git a/base/tps/src/apdu/Import_Key_Enc_APDU.cpp b/base/tps/src/apdu/Import_Key_Enc_APDU.cpp
new file mode 100644
index 000000000..6df161157
--- /dev/null
+++ b/base/tps/src/apdu/Import_Key_Enc_APDU.cpp
@@ -0,0 +1,70 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include <string.h>
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+#include "apdu/Import_Key_Enc_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Import Key Encrypted APDU.
+ *
+ * CLA 0x80
+ * INS 0x0A
+ * P1 private Key Number (0x00 -0x0F) - key slot number defined in CMS.cfg
+ * P2 public Key Number (0x00 -0x0F) - key slot number defined in CMS.cfg
+ * DATA:
+ * Wrapped Key DesKey
+ * Byte IV_Length
+ * Byte IV_Data
+ *
+ * This function allows the import of a key into the card by (over)-writing the Cardlet memory. Object ID 0xFFFFFFFE needs to be initialized with a key blob before invocation of this function so that it can retrieve the key from this object. The exact key blob contents depend on the key's algorithm, type and actual import parameters. The key's number, algorithm type, and parameters are specified by argumetns P1, P2, P3, and DATA. Appropriate values for these are specified below:
+
+[DATA]
+Import Parameters:
+...to be provided
+ */
+TPS_PUBLIC Import_Key_Enc_APDU::Import_Key_Enc_APDU (BYTE p1, BYTE p2,
+ Buffer& data)
+{
+ SetCLA(0x84);
+ SetINS(0x0A);
+ SetP1(p1);
+ SetP2(p2);
+
+ SetData(data);
+}
+
+TPS_PUBLIC Import_Key_Enc_APDU::~Import_Key_Enc_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Import_Key_Enc_APDU::GetType()
+{
+ return APDU_IMPORT_KEY_ENC;
+}
diff --git a/base/tps/src/apdu/Initialize_Update_APDU.cpp b/base/tps/src/apdu/Initialize_Update_APDU.cpp
new file mode 100644
index 000000000..a87091122
--- /dev/null
+++ b/base/tps/src/apdu/Initialize_Update_APDU.cpp
@@ -0,0 +1,66 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Initialize_Update_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Initialize Update APDU.
+ */
+TPS_PUBLIC Initialize_Update_APDU::Initialize_Update_APDU (BYTE key_version, BYTE key_index, Buffer &data)
+{
+ SetCLA(0x80);
+ SetINS(0x50);
+ SetP1(key_version);
+ SetP2(key_index);
+ SetData(data);
+}
+
+TPS_PUBLIC Initialize_Update_APDU::~Initialize_Update_APDU ()
+{
+}
+
+TPS_PUBLIC Buffer &Initialize_Update_APDU::GetHostChallenge()
+{
+ return GetData();
+}
+
+TPS_PUBLIC APDU_Type Initialize_Update_APDU::GetType()
+{
+ return APDU_INITIALIZE_UPDATE;
+}
+
+TPS_PUBLIC void Initialize_Update_APDU::GetEncoding(Buffer &data)
+{
+ data += Buffer(1, m_cla);
+ data += Buffer(1, m_ins);
+ data += Buffer(1, m_p1);
+ data += Buffer(1, m_p2);
+ data += Buffer(1, (BYTE)m_data.size());
+ data += Buffer(m_data, m_data.size());
+} /* Encode */
diff --git a/base/tps/src/apdu/Install_Applet_APDU.cpp b/base/tps/src/apdu/Install_Applet_APDU.cpp
new file mode 100644
index 000000000..0a6b9b7c1
--- /dev/null
+++ b/base/tps/src/apdu/Install_Applet_APDU.cpp
@@ -0,0 +1,112 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Install_Applet_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Install Applet APDU.
+ */
+TPS_PUBLIC Install_Applet_APDU::Install_Applet_APDU (Buffer &packageAID, Buffer &appletAID,
+ BYTE appPrivileges, unsigned int instanceSize, unsigned int appletMemorySize)
+{
+ SetCLA(0x84);
+ SetINS(0xE6);
+ SetP1(0x0C);
+ SetP2(0x00);
+
+ Buffer data;
+ data.reserve(32); // pre-allocate
+ data += packageAID.size();
+ data += packageAID;
+ data += appletAID.size();
+ data += appletAID;
+ data += appletAID.size();
+ data += appletAID;
+
+ data += 0x01; // length of application privileges byte
+ data += appPrivileges;
+
+ Buffer installParams; installParams.reserve(6);
+ installParams += 0xEF;
+ installParams += 0x04;
+ installParams += 0xC8;
+ installParams += 0x02;
+
+ installParams += (instanceSize>>8) & 0xff;
+ installParams += instanceSize & 0xff;
+ installParams += 0xC9;
+
+
+ //installParams += 0x01;
+ //installParams += (BYTE)0x00;
+
+ //Now add some applet specific init data that the applet supports
+ //Length of applet specific data
+
+ installParams += 0x04;
+
+ //Issuer info length.
+ //Leave this to zero since TPS already writes phone home info to card.
+ installParams += (BYTE)0x00;
+
+ //Length of applet memory size
+ installParams += (BYTE)0x02;
+
+ // Applet memory block size
+
+ installParams += (appletMemorySize>>8) & 0xff;
+ installParams += appletMemorySize & 0xff;
+
+ data += installParams.size();
+ data += installParams;
+ data += (BYTE) 0x00; // size of token return data
+
+ SetData(data);
+}
+
+/**
+ * Constructs Install Applet APDU.
+ */
+TPS_PUBLIC Install_Applet_APDU::Install_Applet_APDU (Buffer &data)
+{
+ SetCLA(0x84);
+ SetINS(0xE6);
+ SetP1(0x0C);
+ SetP2(0x00);
+ SetData(data);
+}
+
+TPS_PUBLIC Install_Applet_APDU::~Install_Applet_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Install_Applet_APDU::GetType()
+{
+ return APDU_INSTALL_APPLET;
+}
diff --git a/base/tps/src/apdu/Install_Load_APDU.cpp b/base/tps/src/apdu/Install_Load_APDU.cpp
new file mode 100644
index 000000000..6169538e5
--- /dev/null
+++ b/base/tps/src/apdu/Install_Load_APDU.cpp
@@ -0,0 +1,91 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Install_Load_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Install Load APDU.
+ */
+TPS_PUBLIC Install_Load_APDU::Install_Load_APDU (Buffer& packageAID, Buffer& sdAID,
+ unsigned int fileLen)
+{
+ SetCLA(0x84);
+ SetINS(0xE6);
+ SetP1(0x02);
+ SetP2(0x00);
+
+ Buffer inputData(packageAID.size() + sdAID.size() + 11);
+
+ unsigned int i = 0; // offset
+ ((BYTE*)inputData)[i++] = packageAID.size();
+ inputData.replace(i, packageAID, packageAID.size());
+ i += packageAID.size();
+
+ ((BYTE*)inputData)[i++] = sdAID.size();
+ inputData.replace(i, sdAID, sdAID.size());
+ i += sdAID.size();
+
+ ((BYTE*)inputData)[i++] = 0;
+
+ ((BYTE*)inputData)[i++] = 6;
+
+ ((BYTE*)inputData)[i++] = 0xEF;
+ ((BYTE*)inputData)[i++] = 0x04;
+ ((BYTE*)inputData)[i++] = 0xC6;
+ ((BYTE*)inputData)[i++] = 0x02;
+ fileLen += 24 + sdAID.size(); // !!! XXX
+
+ ((BYTE*)inputData)[i++] = ((fileLen) >> 8) & 0xff;
+ ((BYTE*)inputData)[i++] = fileLen & 0xff;
+
+ ((BYTE*)inputData)[i++] = 0;
+
+ SetData(inputData);
+}
+
+/**
+ * Constructs Install Load APDU. Used when data was pre-constructed
+ */
+TPS_PUBLIC Install_Load_APDU::Install_Load_APDU (Buffer& data)
+{
+ SetCLA(0x84);
+ SetINS(0xE6);
+ SetP1(0x02);
+ SetP2(0x00);
+ SetData(data);
+}
+
+TPS_PUBLIC Install_Load_APDU::~Install_Load_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Install_Load_APDU::GetType()
+{
+ return APDU_INSTALL_LOAD;
+}
diff --git a/base/tps/src/apdu/Lifecycle_APDU.cpp b/base/tps/src/apdu/Lifecycle_APDU.cpp
new file mode 100644
index 000000000..e7236147e
--- /dev/null
+++ b/base/tps/src/apdu/Lifecycle_APDU.cpp
@@ -0,0 +1,50 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Lifecycle_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Lifecycle APDU.
+ */
+TPS_PUBLIC Lifecycle_APDU::Lifecycle_APDU (BYTE lifecycle)
+{
+ SetCLA(0x84);
+ SetINS(0xf0);
+ SetP1(lifecycle);
+ SetP2(0x00);
+}
+
+TPS_PUBLIC Lifecycle_APDU::~Lifecycle_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Lifecycle_APDU::GetType()
+{
+ return APDU_LIFECYCLE;
+}
diff --git a/base/tps/src/apdu/List_Objects_APDU.cpp b/base/tps/src/apdu/List_Objects_APDU.cpp
new file mode 100644
index 000000000..86ae570d9
--- /dev/null
+++ b/base/tps/src/apdu/List_Objects_APDU.cpp
@@ -0,0 +1,61 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include <string.h>
+#include "apdu/APDU.h"
+#include "apdu/List_Objects_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Set Pin APDU.
+ */
+TPS_PUBLIC List_Objects_APDU::List_Objects_APDU (BYTE seq)
+{
+ SetCLA(0xB0);
+ SetINS(0x58);
+ SetP1(seq);
+ SetP2(0x00);
+}
+
+TPS_PUBLIC List_Objects_APDU::~List_Objects_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type List_Objects_APDU::GetType()
+{
+ return APDU_LIST_OBJECTS;
+}
+
+TPS_PUBLIC void List_Objects_APDU::GetEncoding(Buffer &data)
+{
+ data += Buffer(1, m_cla);
+ data += Buffer(1, m_ins);
+ data += Buffer(1, m_p1);
+ data += Buffer(1, m_p2);
+ data += Buffer(1, 0x0E);
+} /* Encode */
+
diff --git a/base/tps/src/apdu/List_Pins_APDU.cpp b/base/tps/src/apdu/List_Pins_APDU.cpp
new file mode 100644
index 000000000..218072f21
--- /dev/null
+++ b/base/tps/src/apdu/List_Pins_APDU.cpp
@@ -0,0 +1,63 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include <string.h>
+#include "apdu/APDU.h"
+#include "apdu/List_Pins_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Set Pin APDU.
+ */
+TPS_PUBLIC List_Pins_APDU::List_Pins_APDU (BYTE ret_size)
+{
+ SetCLA(0xB0);
+// SetCLA(0x84);
+ SetINS(0x48);
+ SetP1(0x00);
+ SetP2(0x00);
+ m_ret_size = ret_size;
+}
+
+TPS_PUBLIC List_Pins_APDU::~List_Pins_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type List_Pins_APDU::GetType()
+{
+ return APDU_LIST_PINS;
+}
+
+TPS_PUBLIC void List_Pins_APDU::GetEncoding(Buffer &data)
+{
+ data += Buffer(1, m_cla);
+ data += Buffer(1, m_ins);
+ data += Buffer(1, m_p1);
+ data += Buffer(1, m_p2);
+ data += Buffer(1, m_ret_size);
+} /* Encode */
+
diff --git a/base/tps/src/apdu/Load_File_APDU.cpp b/base/tps/src/apdu/Load_File_APDU.cpp
new file mode 100644
index 000000000..c41f0ec73
--- /dev/null
+++ b/base/tps/src/apdu/Load_File_APDU.cpp
@@ -0,0 +1,52 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Load_File_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Load File APDU.
+ */
+TPS_PUBLIC Load_File_APDU::Load_File_APDU (BYTE refControl, BYTE blockNum, Buffer& data)
+{
+ SetCLA(0x84);
+ SetINS(0xE8);
+ SetP1(refControl);
+ SetP2(blockNum);
+
+ SetData(data);
+}
+
+TPS_PUBLIC Load_File_APDU::~Load_File_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Load_File_APDU::GetType()
+{
+ return APDU_LOAD_FILE;
+}
diff --git a/base/tps/src/apdu/Put_Key_APDU.cpp b/base/tps/src/apdu/Put_Key_APDU.cpp
new file mode 100644
index 000000000..0a061394f
--- /dev/null
+++ b/base/tps/src/apdu/Put_Key_APDU.cpp
@@ -0,0 +1,53 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include <string.h>
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+#include "apdu/Put_Key_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Put Key APDU.
+ */
+TPS_PUBLIC Put_Key_APDU::Put_Key_APDU (BYTE p1, BYTE p2, Buffer &data)
+{
+ SetCLA(0x84);
+ SetINS(0xd8);
+ SetP1(p1);
+ SetP2(p2);
+ SetData(data);
+}
+
+TPS_PUBLIC Put_Key_APDU::~Put_Key_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Put_Key_APDU::GetType()
+{
+ return APDU_PUT_KEY;
+}
diff --git a/base/tps/src/apdu/Read_Buffer_APDU.cpp b/base/tps/src/apdu/Read_Buffer_APDU.cpp
new file mode 100644
index 000000000..22f23fe1f
--- /dev/null
+++ b/base/tps/src/apdu/Read_Buffer_APDU.cpp
@@ -0,0 +1,63 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Read_Buffer_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Read Buffer APDU.
+ */
+TPS_PUBLIC Read_Buffer_APDU::Read_Buffer_APDU (int len, int offset)
+{
+ SetCLA(0x84);
+ SetINS(0x08);
+ SetP1(len);
+ SetP2(0x00);
+ Buffer data;
+ data = Buffer(1,(BYTE)(offset/256)) + Buffer(1,(BYTE)(offset%256));
+ SetData(data);
+}
+
+TPS_PUBLIC Read_Buffer_APDU::~Read_Buffer_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Read_Buffer_APDU::GetType()
+{
+ return APDU_READ_BUFFER;
+}
+
+TPS_PUBLIC int Read_Buffer_APDU::GetLen()
+{
+ return m_p1;
+}
+
+TPS_PUBLIC int Read_Buffer_APDU::GetOffset()
+{
+ return (((int)((BYTE*)m_data)[0]) << 8) + ((int)((BYTE*)m_data)[1]);
+}
diff --git a/base/tps/src/apdu/Read_Object_APDU.cpp b/base/tps/src/apdu/Read_Object_APDU.cpp
new file mode 100644
index 000000000..21722d331
--- /dev/null
+++ b/base/tps/src/apdu/Read_Object_APDU.cpp
@@ -0,0 +1,88 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Read_Object_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Read Object APDU.
+ *
+ * ReadObject APDU format:
+ * CLA 0x84
+ * INS 0x56
+ * P1 0x00
+ * P2 0x00
+ * lc 0x09
+ * DATA <Data Parameters>
+ *
+ * [DATA] Parameters are:
+ * Long Object ID;
+ * Long Offset
+ * Byte Data Size;
+ *
+ * Connection requirement:
+ * Secure Channel
+ *
+ * Possible error Status Codes:
+ * 9C 06 - unauthorized
+ * 9C 07 - object not found
+ *
+ * @param object_id as defined in APDU
+ * @param offset
+ * @param data
+ * @see APDU
+ */
+TPS_PUBLIC Read_Object_APDU::Read_Object_APDU (BYTE *object_id, int offset, int len)
+{
+ SetCLA(0x84);
+ SetINS(0x56);
+ SetP1(0x00);
+ SetP2(0x00);
+ Buffer data;
+ data =
+ Buffer(1, (BYTE)object_id[0]) +
+ Buffer(1, (BYTE)object_id[1]) +
+ Buffer(1, (BYTE)object_id[2]) +
+ Buffer(1, (BYTE)object_id[3]) +
+ Buffer(1,(BYTE)((offset>>24) & 0xff)) +
+ Buffer(1,(BYTE)((offset>>16) & 0xff)) +
+ Buffer(1,(BYTE)((offset>>8) & 0xff)) +
+ Buffer(1,(BYTE)(offset & 0xff)) +
+ Buffer(1, (BYTE)len);
+ SetData(data);
+}
+
+TPS_PUBLIC Read_Object_APDU::~Read_Object_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Read_Object_APDU::GetType()
+{
+ return APDU_READ_OBJECT;
+}
+
diff --git a/base/tps/src/apdu/Select_APDU.cpp b/base/tps/src/apdu/Select_APDU.cpp
new file mode 100644
index 000000000..4f5917b29
--- /dev/null
+++ b/base/tps/src/apdu/Select_APDU.cpp
@@ -0,0 +1,49 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include <string.h>
+#include "apdu/APDU.h"
+#include "apdu/Select_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+TPS_PUBLIC Select_APDU::Select_APDU (BYTE p1, BYTE p2, Buffer &data)
+{
+ SetCLA(0x00);
+ SetINS(0xa4);
+ SetP1(p1);
+ SetP2(p2);
+ SetData(data);
+}
+
+TPS_PUBLIC Select_APDU::~Select_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Select_APDU::GetType()
+{
+ return APDU_SELECT;
+}
diff --git a/base/tps/src/apdu/Set_IssuerInfo_APDU.cpp b/base/tps/src/apdu/Set_IssuerInfo_APDU.cpp
new file mode 100644
index 000000000..77b1d0f8d
--- /dev/null
+++ b/base/tps/src/apdu/Set_IssuerInfo_APDU.cpp
@@ -0,0 +1,76 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include <string.h>
+#include "apdu/APDU.h"
+#include "apdu/Set_IssuerInfo_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs SetIssuer APDU.
+ *
+ * SecureSetIssuer APDU format:
+ * CLA 0x84
+ * INS 0xF4
+ * P1 0x00
+ * P2 0x00
+ * lc 0xE0
+ * DATA <Issuer Info>
+ *
+ * Connection requirement:
+ * Secure Channel
+ *
+ * Possible error Status Codes:
+ * 9C 06 - unauthorized
+ *
+ * @param p1 always 0x00
+ * @param p2 always 0x00
+ * @param data issuer info
+ * @see APDU
+ */
+TPS_PUBLIC Set_IssuerInfo_APDU::Set_IssuerInfo_APDU (BYTE p1, BYTE p2, Buffer &data)
+{
+ SetCLA(0x84);
+ SetINS(0xF4);
+ SetP1(p1);
+ SetP2(p2);
+ SetData(data);
+}
+
+TPS_PUBLIC Set_IssuerInfo_APDU::~Set_IssuerInfo_APDU ()
+{
+}
+
+TPS_PUBLIC Buffer &Set_IssuerInfo_APDU::GetIssuerInfo()
+{
+ return GetData();
+}
+
+TPS_PUBLIC APDU_Type Set_IssuerInfo_APDU::GetType()
+{
+ return APDU_SET_ISSUERINFO;
+}
diff --git a/base/tps/src/apdu/Set_Pin_APDU.cpp b/base/tps/src/apdu/Set_Pin_APDU.cpp
new file mode 100644
index 000000000..3faaa89ed
--- /dev/null
+++ b/base/tps/src/apdu/Set_Pin_APDU.cpp
@@ -0,0 +1,76 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include <string.h>
+#include "apdu/APDU.h"
+#include "apdu/Set_Pin_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs SetPin APDU.
+ *
+ * SecureSetPIN APDU format:
+ * CLA 0x80
+ * INS 0x04
+ * P1 <Pin number>
+ * P2 0x00
+ * lc <data length>
+ * DATA <New Pin Value>
+ *
+ * Connection requirement:
+ * Secure Channel
+ *
+ * Possible error Status Codes:
+ * 9C 06 - unauthorized
+ *
+ * @param p1 Pin number: 0x00 - 0x07
+ * @param p2 always 0x00
+ * @param data pin
+ * @see APDU
+ */
+TPS_PUBLIC Set_Pin_APDU::Set_Pin_APDU (BYTE p1, BYTE p2, Buffer &data)
+{
+ SetCLA(0x84);
+ SetINS(0x04);
+ SetP1(p1);
+ SetP2(p2);
+ SetData(data);
+}
+
+TPS_PUBLIC Set_Pin_APDU::~Set_Pin_APDU ()
+{
+}
+
+TPS_PUBLIC Buffer &Set_Pin_APDU::GetNewPIN()
+{
+ return GetData();
+}
+
+TPS_PUBLIC APDU_Type Set_Pin_APDU::GetType()
+{
+ return APDU_SET_PIN;
+}
diff --git a/base/tps/src/apdu/Unblock_Pin_APDU.cpp b/base/tps/src/apdu/Unblock_Pin_APDU.cpp
new file mode 100644
index 000000000..c580dc9f2
--- /dev/null
+++ b/base/tps/src/apdu/Unblock_Pin_APDU.cpp
@@ -0,0 +1,50 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Unblock_Pin_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Unblock Pin APDU.
+ */
+TPS_PUBLIC Unblock_Pin_APDU::Unblock_Pin_APDU ()
+{
+ SetCLA(0x84);
+ SetINS(0x02);
+ SetP1(0x00);
+ SetP2(0x00);
+}
+
+TPS_PUBLIC Unblock_Pin_APDU::~Unblock_Pin_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Unblock_Pin_APDU::GetType()
+{
+ return APDU_UNBLOCK_PIN;
+}
diff --git a/base/tps/src/apdu/Write_Object_APDU.cpp b/base/tps/src/apdu/Write_Object_APDU.cpp
new file mode 100644
index 000000000..958ee4384
--- /dev/null
+++ b/base/tps/src/apdu/Write_Object_APDU.cpp
@@ -0,0 +1,103 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Write_Object_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Write Buffer APDU. This APDU is usually sent right after
+ * the Create_Object_APDU is sent. This APDU writes the actual object
+ * content into the object that was created with Create_Object_APDU.
+ * This APDU is used for both write and re-writes of data.
+ * The object data is stored starting from the byte specified by the
+ * offset parameter.
+ * Up to 240 bytes can be transferred with a single APDU. If more bytes
+ * need to be transferred, then multiple WriteObject commands must be
+ * used with different offsets.
+ *
+ * WriteObject APDU format:
+ * CLA 0x84
+ * INS 0x54
+ * P1 0x00
+ * P2 0x00
+ * lc Data Size + 9
+ * DATA <Data Parameters>
+ *
+ * [DATA] Parameters are:
+ * Long Object ID;
+ * Long Offset
+ * Byte Data Size;
+ * Byte[] Object Data
+ *
+ * Connection requirement:
+ * Secure Channel
+ *
+ * Possible error Status Codes:
+ * 9C 06 - unauthorized
+ * 9C 07 - object not found
+ *
+ * @param object_id as defined in APDU
+ * @param offset
+ * @param data
+ * @see APDU
+ */
+TPS_PUBLIC Write_Object_APDU::Write_Object_APDU (BYTE *object_id, int offset, Buffer &data)
+{
+ SetCLA(0x84);
+ SetINS(0x54);
+ SetP1(0x00);
+ SetP2(0x00);
+ Buffer data1;
+ data1 =
+ Buffer(1, (BYTE)object_id[0]) +
+ Buffer(1, (BYTE)object_id[1]) +
+
+ Buffer(1, (BYTE)object_id[2]) +
+ Buffer(1, (BYTE)object_id[3]) +
+ /*
+ Buffer(1, (BYTE)0x00) +
+ Buffer(1, (BYTE)0x00) +
+ */
+ Buffer(1,(BYTE)((offset>>24) & 0xff)) +
+ Buffer(1,(BYTE)((offset>>16) & 0xff)) +
+ Buffer(1,(BYTE)((offset>>8) & 0xff)) +
+ Buffer(1,(BYTE)(offset & 0xff)) +
+ Buffer(1, (BYTE)data.size()) +
+ Buffer(data);
+ SetData(data1);
+}
+
+TPS_PUBLIC Write_Object_APDU::~Write_Object_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Write_Object_APDU::GetType()
+{
+ return APDU_WRITE_OBJECT;
+}
+
diff --git a/base/tps/src/authentication/CMakeLists.txt b/base/tps/src/authentication/CMakeLists.txt
new file mode 100644
index 000000000..ba8ca07dc
--- /dev/null
+++ b/base/tps/src/authentication/CMakeLists.txt
@@ -0,0 +1,52 @@
+project(ldapauth_library CXX)
+
+set(LDAPAUTH_PUBLIC_INCLUDE_DIRS
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${TPS_INCLUDE_DIR}
+ CACHE INTERNAL "ldapauth public include directories"
+)
+
+set(LDAPAUTH_PRIVATE_INCLUDE_DIRS
+ ${LDAPAUTH_PUBLIC_INCLUDE_DIRS}
+ ${CMAKE_BINARY_DIR}
+ ${NSPR_INCLUDE_DIRS}
+ ${NSS_INCLUDE_DIRS}
+ ${SVRCORE_INCLUDE_DIRS}
+ ${LDAP_INCLUDE_DIRS}
+)
+
+set(LDAPAUTH_SHARED_LIBRARY
+ ldapauth_library
+ CACHE INTERNAL "ldapauth shared library"
+)
+
+set(LDAPAUTH_LINK_LIBRARIES
+ ${NSPR_LIBRARIES}
+ ${NSS_LIBRARIES}
+ ${SVRCORE_LIBRARIES}
+ ${LDAP_LIBRARIES}
+ ${TOKENDB_SHARED_LIBRARY}
+ ${TPS_SHARED_LIBRARY}
+)
+
+set(ldapauth_library_SRCS
+ LDAP_Authentication.cpp
+)
+
+include_directories(${LDAPAUTH_PRIVATE_INCLUDE_DIRS})
+
+add_library(${LDAPAUTH_SHARED_LIBRARY} SHARED ${ldapauth_library_SRCS})
+target_link_libraries(${LDAPAUTH_SHARED_LIBRARY} ${LDAPAUTH_LINK_LIBRARIES})
+
+set_target_properties(${LDAPAUTH_SHARED_LIBRARY}
+ PROPERTIES
+ OUTPUT_NAME
+ ldapauth
+)
+
+install(
+ TARGETS
+ ${LDAPAUTH_SHARED_LIBRARY}
+ LIBRARY DESTINATION ${LIB_INSTALL_DIR}/tps
+)
diff --git a/base/tps/src/authentication/LDAP_Authentication.cpp b/base/tps/src/authentication/LDAP_Authentication.cpp
new file mode 100644
index 000000000..3e073dfff
--- /dev/null
+++ b/base/tps/src/authentication/LDAP_Authentication.cpp
@@ -0,0 +1,424 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "engine/RA.h"
+#include "ldap.h"
+#include "authentication/LDAP_Authentication.h"
+#include "authentication/Authentication.h"
+#include "main/Memory.h"
+#include "main/Util.h"
+
+/**
+ * Constructs a base processor.
+ */
+LDAP_Authentication::LDAP_Authentication ()
+{
+ m_hostport = NULL;
+ m_baseDN = NULL;
+ m_connInfo = NULL;
+ m_attributes = NULL;
+ m_ssl = NULL;
+ m_bindDN = NULL;
+ m_bindPwd = NULL;
+}
+
+/**
+ * Destructs processor.
+ */
+LDAP_Authentication::~LDAP_Authentication ()
+{
+ if( m_hostport != NULL ) {
+ PL_strfree( m_hostport );
+ m_hostport = NULL;
+ }
+
+ if( m_baseDN != NULL ) {
+ PL_strfree( m_baseDN );
+ m_baseDN = NULL;
+ }
+
+ if( m_connInfo != NULL ) {
+ delete m_connInfo;
+ m_connInfo = NULL;
+ }
+}
+
+/*
+ * Search for password name "name" in the password file "filepath"
+ */
+static char *get_pwd_from_conf(char *filepath, const char *name)
+{
+ PRFileDesc *fd;
+ char line[1024];
+ int removed_return;
+ char *val= NULL;
+
+ fd= PR_Open(filepath, PR_RDONLY, 400);
+ if (fd == NULL) {
+ return NULL;
+ }
+
+ while (1) {
+ int n = Util::ReadLine(fd, line, 1024, &removed_return);
+ if (n > 0) {
+ /* handle comment line */
+ if (line[0] == '#')
+ continue;
+ int c = 0;
+ while ((c < n) && (line[c] != ':')) {
+ c++;
+ }
+ if (c < n) {
+ line[c] = '\0';
+ } else {
+ continue; /* no ':', skip this line */
+ }
+ if (!PL_strcmp (line, name)) {
+ val = PL_strdup(&line[c+1]);
+ break;
+ }
+ } else if (n == 0 && removed_return == 1) {
+ continue; /* skip empty line */
+ } else {
+ break;
+ }
+ }
+ if( fd != NULL ) {
+ PR_Close( fd );
+ fd = NULL;
+ }
+ return val;
+
+}
+
+void LDAP_Authentication::Initialize(int instanceIndex) {
+ char configname[256];
+ const char *prefix="auth.instance";
+
+ m_index = instanceIndex;
+ PR_snprintf((char *)configname, 256, "%s.%d.hostport", prefix, instanceIndex);
+ m_hostport = PL_strdup(RA::GetConfigStore()->GetConfigAsString(configname));
+ PR_snprintf((char *)configname, 256, "%s.%d.SSLOn", prefix, instanceIndex);
+ m_isSSL = RA::GetConfigStore()->GetConfigAsBool(configname, true);
+ PR_snprintf((char *)configname, 256, "%s.%d.retries", prefix, instanceIndex);
+ m_retries = RA::GetConfigStore()->GetConfigAsInt(configname, 1);
+ PR_snprintf((char *)configname, 256, "%s.%d.retryConnect", prefix, instanceIndex);
+ m_connectRetries = RA::GetConfigStore()->GetConfigAsInt(configname, 3);
+ m_connInfo = new ConnectionInfo();
+ m_connInfo->BuildFailoverList(m_hostport);
+ PR_snprintf((char *)configname, 256, "%s.%d.baseDN", prefix, instanceIndex);
+ m_baseDN = PL_strdup(RA::GetConfigStore()->GetConfigAsString(configname));
+ PR_snprintf((char *)configname, 256, "%s.%d.attributes", prefix, instanceIndex);
+ m_attributes = PL_strdup(RA::GetConfigStore()->GetConfigAsString(configname));
+ /* support of SSL */
+ PR_snprintf((char *)configname, 256, "%s.%d.ssl", prefix, instanceIndex);
+ m_ssl = PL_strdup(RA::GetConfigStore()->GetConfigAsString(configname));
+ PR_snprintf((char *)configname, 256, "%s.%d.bindDN", prefix, instanceIndex);
+ m_bindDN = PL_strdup(RA::GetConfigStore()->GetConfigAsString(configname));
+ PR_snprintf((char *)configname, 256, "%s.%d.bindPWD", prefix, instanceIndex);
+ char *m_bindPwdPath = PL_strdup(RA::GetConfigStore()->GetConfigAsString(configname));
+ m_bindPwd = get_pwd_from_conf(m_bindPwdPath, "tokendbBindPass");
+}
+
+/**
+ * @return (0:login correct) (-1:LDAP error) (-2:User not found) (-3:Password error)
+ */
+
+#define TPS_AUTH_OK 0
+#define TPS_AUTH_ERROR_LDAP -1
+#define TPS_AUTH_ERROR_USERNOTFOUND -2
+#define TPS_AUTH_ERROR_PASSWORDINCORRECT -3
+
+int LDAP_Authentication::Authenticate(AuthParams *params)
+{
+ char buffer[500];
+ char ldapuri[1024];
+ char *host = NULL;
+ char *portStr = NULL;
+ int port = 0;
+ LDAP *ld = NULL;
+ int status = TPS_AUTH_ERROR_LDAP;
+ int version = LDAP_VERSION3;
+ LDAPMessage *result = NULL, *e = NULL;
+ char *dn = NULL;
+ char *uid = NULL;
+ char *password = NULL;
+ int retries = 0;
+ int rc =0;
+
+ if (params == NULL) {
+ status = TPS_AUTH_ERROR_USERNOTFOUND;
+ goto loser;
+ }
+
+ uid = params->GetUID();
+ password = params->GetPassword();
+
+ GetHostPort(&host, &portStr);
+ port = atoi(portStr);
+
+ if ((m_ssl != NULL) && (strcmp(m_ssl, "true")==0)) {
+ /* handling of SSL */
+ snprintf(ldapuri, 1024, "ldaps://%s:%i", host, port);
+ } else {
+ snprintf(ldapuri, 1024, "ldap://%s:%i", host, port);
+ }
+ status = ldap_initialize(&ld, ldapuri);
+
+ while ((ld == NULL) && (retries < m_connectRetries)) {
+ RA::IncrementAuthCurrentIndex(m_connInfo->GetHostPortListLen());
+ GetHostPort(&host, &portStr);
+ port = atoi(portStr);
+ if ((m_ssl != NULL) && (strcmp(m_ssl, "true")==0)) {
+ /* handling of SSL */
+ snprintf(ldapuri, 1024, "ldaps://%s:%i", host, port);
+ } else {
+ snprintf(ldapuri, 1024, "ldap://%s:%i", host, port);
+ }
+ status = ldap_initialize(&ld, ldapuri);
+ retries++;
+ }
+
+ if (ld == NULL) {
+ status = TPS_AUTH_ERROR_LDAP;
+ goto loser;
+ }
+
+ PR_snprintf((char *)buffer, 500, "(uid=%s)", uid);
+
+ while (retries < m_connectRetries) {
+ RA::IncrementAuthCurrentIndex(m_connInfo->GetHostPortListLen());
+ GetHostPort(&host, &portStr);
+ port = atoi(portStr);
+ RA::Debug("ldap auth:"," host=%s, portstr=%s, port=%d", host, portStr, port);
+ if ((m_ssl != NULL) && (strcmp(m_ssl, "true")==0)) {
+ /* handling of SSL */
+ snprintf(ldapuri, 1024, "ldaps://%s:%i", host, port);
+ } else {
+ snprintf(ldapuri, 1024, "ldap://%s:%i", host, port);
+ }
+ status = ldap_initialize(&ld, ldapuri);
+
+ if (ld == NULL) {
+ RA::Debug("LDAP_Authentication::Authenticate:", "ld null. Trying failover...");
+ retries++;
+ continue;
+ }
+
+ if (ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_SUCCESS) {
+ status = TPS_AUTH_ERROR_LDAP;
+ goto loser;
+ }
+
+ if (m_bindDN != NULL && strlen(m_bindDN) > 0) {
+ RA::Debug("LDAP_Authentication::Authenticate", "Simple bind required '%s'", m_bindDN);
+ struct berval credential;
+ credential.bv_val = m_bindPwd;
+ credential.bv_len= strlen(m_bindPwd);
+ rc = ldap_sasl_bind_s(ld, m_bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ }
+
+ int ldap_status = LDAP_OTHER;
+ if ((ldap_status = ldap_search_ext_s(ld, m_baseDN, LDAP_SCOPE_SUBTREE, buffer, NULL, 0, NULL, NULL, NULL, 0, &result)) != LDAP_SUCCESS) {
+ if (ldap_status != LDAP_NO_SUCH_OBJECT) {
+ RA::Debug("LDAP_Authentication::Authenticate:", "LDAP_UNAVAILABLE. Trying failover...");
+ retries++;
+ continue; // do failover
+ }
+ status = TPS_AUTH_ERROR_USERNOTFOUND;
+ } else {
+ for (e = ldap_first_entry(ld, result); e != NULL; e = ldap_next_entry(ld, e)) {
+ if ((dn = ldap_get_dn(ld, e)) != NULL) {
+ RA::Debug("LDAP_Authentication::Authenticate", "User bind required '%s' '(sensitive)'", dn );
+ struct berval credential;
+ credential.bv_val = password;
+ credential.bv_len= strlen(password);
+ rc = ldap_sasl_bind_s(ld, dn, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc == LDAP_SUCCESS) {
+ /* retrieve attributes and, */
+ /* put them into the auth parameters */
+ if (m_attributes != NULL) {
+ RA::Debug("LDAP_Authentication::Authenticate", "Attributes %s", m_attributes);
+ char *m_dup_attributes = strdup(m_attributes);
+ char *token = NULL;
+ token = strtok(m_dup_attributes, ",");
+ while( token != NULL ) {
+ struct berval **v = NULL;
+ v = ldap_get_values_len(ld, e, token);
+ if ((v != NULL) && (v[0]!= NULL) && (v[0]->bv_val != NULL)) {
+ RA::Debug("LDAP_Authentication::Authenticate", "Exposed %s=%s", token, v[0]->bv_val);
+ params->Add(token, PL_strdup(v[0]->bv_val));
+ RA::Debug("LDAP_Authentication::Authenticate", "Size %d", params->Size());
+ }
+ token = strtok( NULL, "," );
+ if( v != NULL ) {
+ ldap_value_free_len( v );
+ v = NULL;
+ }
+
+ }
+ free(m_dup_attributes);
+ }
+ status = TPS_AUTH_OK; // SUCCESS - PASSWORD VERIFIED
+ } else {
+ status = TPS_AUTH_ERROR_PASSWORDINCORRECT;
+ goto loser;
+ }
+ } else {
+ status = TPS_AUTH_ERROR_USERNOTFOUND;
+ goto loser;
+ }
+ }
+ RA::Debug("LDAP_Authentication::Authenticate:", " authentication completed for %s",uid);
+ break;
+ }
+ } //while
+
+ if (dn == NULL) {
+ status = TPS_AUTH_ERROR_USERNOTFOUND;
+ goto loser;
+ }
+
+loser:
+
+ if (result != NULL) {
+ ldap_msgfree(result);
+ }
+
+ if (dn != NULL) {
+ ldap_memfree(dn);
+ }
+
+ if (ld != NULL) {
+ ldap_unbind_ext_s(ld, NULL, NULL);
+ ld = NULL;
+ }
+ return status;
+}
+
+void LDAP_Authentication::GetHostPort(char **p, char **q) {
+ int num=0;
+ int auth_curr = RA::GetAuthCurrentIndex();
+ char *hp = (m_connInfo->GetHostPortList())[auth_curr];
+ char *host_port = PL_strdup(hp);
+
+ char *lasts = NULL;
+ char *tok = PL_strtok_r((char *)host_port, ":", &lasts);
+ while (tok != NULL) {
+ if (num == 0)
+ *p = PL_strdup(tok);
+ else
+ *q = PL_strdup(tok);
+ tok = PL_strtok_r(NULL, ":", &lasts);
+ num++;
+ }
+
+ PR_Free(host_port);
+}
+
+bool LDAP_Authentication::IsSSL() {
+ return m_isSSL;
+}
+
+char *LDAP_Authentication::GetHostPort() {
+ return m_hostport;
+}
+
+Authentication *GetAuthentication() {
+ LDAP_Authentication *auth = new LDAP_Authentication();
+ return (Authentication *)auth;
+}
+
+const char *LDAP_Authentication::GetTitle(char *locale)
+{
+ char configname[256];
+ const char *prefix="auth.instance";
+ PR_snprintf((char *)configname, 256, "%s.%d.ui.title.%s",
+ prefix, m_index, locale);
+RA::Debug("LDAP_Authentication::GetTitle", "%s", configname);
+ return RA::GetConfigStore()->GetConfigAsString(configname);
+}
+
+const char *LDAP_Authentication::GetDescription(char *locale)
+{
+ char configname[256];
+ const char *prefix="auth.instance";
+ PR_snprintf((char *)configname, 256, "%s.%d.ui.description.%s",
+ prefix, m_index, locale);
+RA::Debug("LDAP_Authentication::GetDescription", "%s", configname);
+RA::Debug("LDAP_Authentication::GetDescription", "%s", RA::GetConfigStore()->GetConfigAsString(configname));
+ return RA::GetConfigStore()->GetConfigAsString(configname);
+}
+
+int LDAP_Authentication::GetNumOfParamNames()
+{
+ return 2;
+}
+
+char *LDAP_Authentication::GetParamID(int index)
+{
+ if (index == 0)
+ return ( char * ) "UID";
+ else if (index == 1)
+ return ( char * ) "PASSWORD";
+ else
+ return NULL;
+}
+
+const char *LDAP_Authentication::GetParamName(int index, char *locale)
+{
+ char configname[256];
+ const char *prefix="auth.instance";
+ PR_snprintf((char *)configname, 256, "%s.%d.ui.id.%s.name.%s",
+ prefix, m_index, GetParamID(index), locale);
+
+RA::Debug("LDAP_Authentication::GetParamName", "%s", configname);
+
+ return RA::GetConfigStore()->GetConfigAsString(configname);
+}
+
+char *LDAP_Authentication::GetParamType(int index)
+{
+ if (index == 0)
+ return ( char * ) "string";
+ else if (index == 1)
+ return ( char * ) "password";
+ else
+ return NULL;
+}
+
+const char *LDAP_Authentication::GetParamDescription(int index, char *locale)
+{
+ char configname[256];
+ const char *prefix="auth.instance";
+ PR_snprintf((char *)configname, 256, "%s.%d.ui.id.%s.description.%s",
+ prefix, m_index, GetParamID(index), locale);
+ return RA::GetConfigStore()->GetConfigAsString(configname);
+}
+
+char *LDAP_Authentication::GetParamOption(int index)
+{
+ return ( char * ) "";
+}
+
diff --git a/base/tps/src/channel/Channel.cpp b/base/tps/src/channel/Channel.cpp
new file mode 100644
index 000000000..6b77d3a19
--- /dev/null
+++ b/base/tps/src/channel/Channel.cpp
@@ -0,0 +1,69 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "main/Util.h"
+#include "engine/RA.h"
+#include "channel/Channel.h"
+#include "msg/RA_Token_PDU_Request_Msg.h"
+#include "msg/RA_Token_PDU_Response_Msg.h"
+#include "apdu/Lifecycle_APDU.h"
+#include "apdu/Initialize_Update_APDU.h"
+#include "apdu/External_Authenticate_APDU.h"
+#include "apdu/Create_Object_APDU.h"
+#include "apdu/Set_Pin_APDU.h"
+#include "apdu/Read_Buffer_APDU.h"
+#include "apdu/Write_Object_APDU.h"
+#include "apdu/Generate_Key_APDU.h"
+#include "apdu/Put_Key_APDU.h"
+#include "apdu/Delete_File_APDU.h"
+#include "apdu/Load_File_APDU.h"
+#include "apdu/Install_Applet_APDU.h"
+#include "apdu/Install_Load_APDU.h"
+#include "apdu/Format_Muscle_Applet_APDU.h"
+#include "apdu/Create_Pin_APDU.h"
+#include "apdu/List_Pins_APDU.h"
+#include "apdu/APDU_Response.h"
+#include "main/Memory.h"
+
+/**
+ * Constructs a secure channel between the RA and the
+ * token key directly.
+ */
+Channel::Channel()
+{
+} /* Channel */
+
+/**
+ * Destroys this secure channel.
+ */
+Channel::~Channel ()
+{
+} /* ~Channel */
+
+/**
+ * Closes secure channel.
+ */
+int Channel::Close()
+{
+ /* currently do not have anything to terminate here */
+ return 1;
+}
diff --git a/base/tps/src/channel/Secure_Channel.cpp b/base/tps/src/channel/Secure_Channel.cpp
new file mode 100644
index 000000000..50b24ae99
--- /dev/null
+++ b/base/tps/src/channel/Secure_Channel.cpp
@@ -0,0 +1,2550 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "main/Util.h"
+#include "engine/RA.h"
+#include "channel/Secure_Channel.h"
+#include "msg/RA_Token_PDU_Request_Msg.h"
+#include "msg/RA_Token_PDU_Response_Msg.h"
+#include "apdu/Lifecycle_APDU.h"
+#include "apdu/Initialize_Update_APDU.h"
+#include "apdu/External_Authenticate_APDU.h"
+#include "apdu/Create_Object_APDU.h"
+#include "apdu/Set_Pin_APDU.h"
+#include "apdu/Set_IssuerInfo_APDU.h"
+#include "apdu/Get_IssuerInfo_APDU.h"
+#include "apdu/Import_Key_APDU.h"
+#include "apdu/Import_Key_Enc_APDU.h"
+#include "apdu/Read_Buffer_APDU.h"
+#include "apdu/Read_Object_APDU.h"
+#include "apdu/Write_Object_APDU.h"
+#include "apdu/Generate_Key_APDU.h"
+#include "apdu/Put_Key_APDU.h"
+#include "apdu/Delete_File_APDU.h"
+#include "apdu/Load_File_APDU.h"
+#include "apdu/Install_Applet_APDU.h"
+#include "apdu/Install_Load_APDU.h"
+#include "apdu/Format_Muscle_Applet_APDU.h"
+#include "apdu/Create_Pin_APDU.h"
+#include "apdu/List_Pins_APDU.h"
+#include "apdu/APDU_Response.h"
+#include "main/Memory.h"
+
+/**
+ * Constructs a secure channel between the RA and the
+ * token key directly. APDUs that are sent via this channel
+ * will be mac'ed using the session key calculated by
+ * TKS which maintains all the user keys.
+ */
+
+Secure_Channel::Secure_Channel(RA_Session *session, PK11SymKey *session_key,
+ PK11SymKey *enc_session_key,
+ char *drm_des_key_s,
+ char *kek_des_key_s, char *keycheck_s,
+ Buffer &key_diversification_data, Buffer &key_info_data,
+ Buffer &card_challenge, Buffer &card_cryptogram,
+ Buffer &host_challenge, Buffer &host_cryptogram)
+{
+ m_icv = Buffer(8,(BYTE)0);
+ m_session = session;
+ m_session_key = session_key;
+ m_enc_session_key = enc_session_key;
+ m_drm_wrapped_des_key_s = drm_des_key_s;
+ m_kek_wrapped_des_key_s = kek_des_key_s;
+ m_keycheck_s = keycheck_s;
+ m_key_diversification_data = key_diversification_data;
+ m_key_info_data = key_info_data;
+ m_card_challenge = card_challenge;
+ m_card_cryptogram = card_cryptogram;
+ m_host_challenge = host_challenge;
+ m_host_cryptogram = host_cryptogram;
+} /* Secure_Channel */
+
+/**
+ * Destroys this secure channel.
+ */
+Secure_Channel::~Secure_Channel ()
+{
+ /* m_session (RA_Session) should not be destroyed at this level. */
+ if( m_session_key != NULL ) {
+ PK11_FreeSymKey( m_session_key );
+ m_session_key = NULL;
+ }
+ if( m_enc_session_key != NULL ) {
+ PK11_FreeSymKey( m_enc_session_key );
+ m_enc_session_key = NULL;
+ }
+ if (m_drm_wrapped_des_key_s != NULL) {
+ PR_Free(m_drm_wrapped_des_key_s);
+ m_drm_wrapped_des_key_s = NULL;
+ }
+ if (m_kek_wrapped_des_key_s != NULL) {
+ PR_Free(m_kek_wrapped_des_key_s);
+ m_kek_wrapped_des_key_s = NULL;
+ }
+ if (m_keycheck_s != NULL) {
+ PR_Free(m_keycheck_s);
+ m_keycheck_s = NULL;
+ }
+} /* ~Secure_Channel */
+
+/**
+ * Closes secure channel.
+ */
+int Secure_Channel::Close()
+{
+ /* currently do not have anything to terminate here */
+ return 1;
+}
+
+/*
+ * to be called by all token request types
+ * it resets m_data if security level is to do encryption
+ */
+int Secure_Channel::ComputeAPDU(APDU *apdu)
+{
+ int rc = -1;
+ Buffer *mac = NULL;
+
+ if (apdu == NULL) {
+ goto loser;
+ }
+ RA::Debug(LL_PER_PDU, "Secure_Channel::ComputeAPDU", "apdu type = %d",
+ apdu->GetType());
+
+ mac = ComputeAPDUMac(apdu);
+ if (mac == NULL)
+ goto loser;
+
+ if (m_security_level == SECURE_MSG_MAC_ENC) {
+ PRStatus status = apdu->SecureMessage(m_enc_session_key);
+ if (status == PR_FAILURE) {
+ goto loser;
+ }
+ }
+
+ rc = 1;
+ loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+
+ return rc;
+}
+
+/**
+ * Calculates MAC for the given APDU.
+ */
+Buffer *Secure_Channel::ComputeAPDUMac(APDU *apdu)
+{
+ Buffer data;
+ Buffer *mac = new Buffer(8, (BYTE)0);
+
+ if (apdu == NULL) {
+ RA::Error("Secure_Channel::ComputeAPDUMac", "apdu NULL");
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ return NULL;
+ }
+ apdu->GetDataToMAC(data);
+
+ // developer debugging only - not for deployment
+ // RA::DebugBuffer("Secure_Channel::ComputeAPDUMac", "Data To MAC'ed",
+ // &data);
+
+ // Compute MAC will padd the data if it is
+ // not in 8 byte multiples
+ Util::ComputeMAC(m_session_key, data, m_icv, *mac);
+ apdu->SetMAC(*mac);
+ m_icv = *mac;
+
+ return mac;
+} /* EncodeAPDUMac */
+
+/**
+ * Sends the token an external authenticate APDU.
+ */
+int Secure_Channel::ExternalAuthenticate()
+{
+ int rc = -1;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ External_Authenticate_APDU *external_auth_apdu = NULL;
+ APDU_Response *response = NULL;
+ Buffer *mac = NULL;
+
+ RA::Debug("Secure_Channel::ExternalAuthenticate",
+ "Secure_Channel::ExternalAuthenticate");
+
+ // This command is very strange
+ external_auth_apdu =
+ new External_Authenticate_APDU(m_host_cryptogram, m_security_level);
+
+ // Need to update APDU length to include 8-bytes MAC
+ // before mac'ing the data
+ mac = ComputeAPDUMac(external_auth_apdu);
+ external_auth_apdu->SetMAC(*mac);
+
+ token_pdu_request_msg =
+ new RA_Token_PDU_Request_Msg(external_auth_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::ExternalAuthenticate",
+ "Sent external_auth_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::ExternalAuthenticate",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::ExternalAuthenticate",
+ "Invalid Msg Type");
+ goto loser;
+ }
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::ExternalAuthenticate",
+ "No Response From Token");
+ goto loser;
+ }
+ if (response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::ExternalAuthenticate",
+ "Invalid Response From Token");
+ goto loser;
+ }
+
+ // must return 0x90 0x00
+ if (!(response->GetSW1() == 0x90 && response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::ExternalAuthenticate",
+ "Bad Response %x %x", response->GetSW1(), response->GetSW2());
+ goto loser;
+ }
+
+ rc = 1;
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+} /* ExternalAuthenticate */
+
+int Secure_Channel::DeleteFileX(RA_Session *session, Buffer *aid)
+{
+ int rc = 0;
+ APDU_Response *delete_response = NULL;
+ RA_Token_PDU_Request_Msg *delete_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *delete_response_msg = NULL;
+ Delete_File_APDU *delete_apdu = NULL;
+ // Buffer *mac = NULL;
+
+ RA::Debug("RA_Processor::DeleteFile",
+ "RA_Processor::DeleteFile");
+
+ delete_apdu = new Delete_File_APDU(*aid);
+ rc = ComputeAPDU(delete_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(delete_apdu);
+ delete_apdu->SetMAC(*mac);
+ */
+ delete_request_msg =
+ new RA_Token_PDU_Request_Msg(delete_apdu);
+ session->WriteMsg(delete_request_msg);
+
+ RA::Debug("RA_Processor::DeleteFile",
+ "Sent delete_request_msg");
+
+ delete_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (delete_response_msg == NULL)
+ {
+ RA::Error("RA_Processor::DeleteFile",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (delete_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::DeleteFile",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+ delete_response = delete_response_msg->GetResponse();
+ if (delete_response == NULL) {
+ RA::Error("Secure_Channel::DeleteFile",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (delete_response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::DeleteFile",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+
+ if (!(delete_response->GetSW1() == 0x90 &&
+ delete_response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::DeleteFile",
+ "Bad Response %x %x", delete_response->GetSW1(),
+ delete_response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+
+ rc = 1;
+
+loser:
+ if( delete_request_msg != NULL ) {
+ delete delete_request_msg;
+ delete_request_msg = NULL;
+ }
+ if( delete_response_msg != NULL ) {
+ delete delete_response_msg;
+ delete_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+int Secure_Channel::InstallLoad(RA_Session *session,
+ Buffer& packageAID, Buffer& sdAID, unsigned int fileLen)
+{
+ int rc = 0;
+ APDU_Response *install_response = NULL;
+ RA_Token_PDU_Request_Msg *install_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *install_response_msg = NULL;
+ Install_Load_APDU *install_apdu = NULL;
+ // Buffer *mac = NULL;
+
+ RA::Debug("RA_Processor::InstallLoad",
+ "RA_Processor::InstallLoad");
+
+ install_apdu = new Install_Load_APDU(packageAID, sdAID, fileLen);
+ rc = ComputeAPDU(install_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(install_apdu);
+ install_apdu->SetMAC(*mac);
+ */
+ install_request_msg =
+ new RA_Token_PDU_Request_Msg(install_apdu);
+ session->WriteMsg(install_request_msg);
+
+ RA::Debug("RA_Processor::InstallLoad",
+ "Sent install_request_msg");
+
+ install_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (install_response_msg == NULL)
+ {
+ RA::Error("RA_Processor::InstallLoad",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (install_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::InstallLoad",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+ install_response = install_response_msg->GetResponse();
+ if (install_response == NULL) {
+ RA::Error("Secure_Channel::InstallLoad",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (install_response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::InstallLoad",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+
+ if (!(install_response->GetSW1() == 0x90 &&
+ install_response->GetSW2() == 0x00)) {
+ RA::Error("Secure_Channel::InstallLoad",
+ "Error Response from token %2x%2x",
+ install_response->GetSW1(),
+ install_response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+
+ rc = 1;
+
+loser:
+ if( install_request_msg != NULL ) {
+ delete install_request_msg;
+ install_request_msg = NULL;
+ }
+ if( install_response_msg != NULL ) {
+ delete install_response_msg;
+ install_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+int Secure_Channel::InstallApplet(RA_Session *session,
+ Buffer &packageAID, Buffer &appletAID,
+ BYTE appPrivileges, unsigned int instanceSize, unsigned int appletMemorySize)
+{
+ int rc = 0;
+ APDU_Response *install_response = NULL;
+ RA_Token_PDU_Request_Msg *install_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *install_response_msg = NULL;
+ Install_Applet_APDU *install_apdu = NULL;
+ // Buffer *mac = NULL;
+
+ RA::Debug("RA_Processor::InstallApplet",
+ "RA_Processor::InstallApplet");
+
+ install_apdu = new Install_Applet_APDU(packageAID, appletAID, appPrivileges,
+ instanceSize, appletMemorySize );
+ rc = ComputeAPDU(install_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(install_apdu);
+ install_apdu->SetMAC(*mac);
+ */
+ install_request_msg =
+ new RA_Token_PDU_Request_Msg(install_apdu);
+ session->WriteMsg(install_request_msg);
+
+ RA::Debug("RA_Processor::InstallApplet",
+ "Sent install_request_msg");
+
+ install_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (install_response_msg == NULL)
+ {
+ RA::Error("RA_Processor::InstallApplet",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (install_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::InstallApplet",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+ install_response = install_response_msg->GetResponse();
+ if (install_response == NULL) {
+ RA::Error("Secure_Channel::InstallApplet",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (install_response->GetData().size() < 2) {
+ RA::Debug("Secure_Channel::InstallApplet",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+
+ if (!(install_response->GetSW1() == 0x90 &&
+ install_response->GetSW2() == 0x00)) {
+ RA::Error("Secure_Channel::InstallApplet",
+ "Error Response from Token %2x%2x",
+ install_response->GetSW1(),
+ install_response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+
+ rc = 1;
+
+loser:
+ if( install_request_msg != NULL ) {
+ delete install_request_msg;
+ install_request_msg = NULL;
+ }
+ if( install_response_msg != NULL ) {
+ delete install_response_msg;
+ install_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+int Secure_Channel::LoadFile(RA_Session *session, BYTE refControl, BYTE blockNum,
+ Buffer *data)
+{
+ int rc = 0;
+ APDU_Response *load_file_response = NULL;
+ RA_Token_PDU_Request_Msg *load_file_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *load_file_response_msg = NULL;
+ Load_File_APDU *load_file_apdu = NULL;
+ // Buffer *mac = NULL;
+
+ RA::Debug("Secure_Channel::LoadFile",
+ "begin LoadFile");
+
+ load_file_apdu = new Load_File_APDU(refControl, blockNum, *data);
+
+ rc = ComputeAPDU(load_file_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(load_file_apdu);
+ load_file_apdu->SetMAC(*mac);
+ */
+ load_file_request_msg =
+ new RA_Token_PDU_Request_Msg(load_file_apdu);
+
+ session->WriteMsg(load_file_request_msg);
+
+ RA::Debug("RA_Processor::LoadFile",
+ "Sent load_file_request_msg");
+
+ load_file_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (load_file_response_msg == NULL)
+ {
+ RA::Error("RA_Processor::LoadFile",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (load_file_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::LoadFile",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+ load_file_response = load_file_response_msg->GetResponse();
+ if (load_file_response == NULL) {
+ RA::Error("Secure_Channel::LoadFile",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (load_file_response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::LoadFile",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(load_file_response->GetSW1() == 0x90 &&
+ load_file_response->GetSW2() == 0x00)) {
+ RA::Error("Secure_Channel::LoadFile",
+ "Error Response from Token %2x%2x",
+ load_file_response->GetSW1(),
+ load_file_response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+
+ rc = 1;
+
+loser:
+ if( load_file_request_msg != NULL ) {
+ delete load_file_request_msg;
+ load_file_request_msg = NULL;
+ }
+ if( load_file_response_msg != NULL ) {
+ delete load_file_response_msg;
+ load_file_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+int Secure_Channel::IsPinPresent(BYTE pin_number)
+{
+ int rc = -1;
+ List_Pins_APDU *list_pins_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ Buffer *mac = NULL;
+
+ RA::Debug("Secure_Channel::IsPinPresent",
+ "Secure_Channel::IsPinPresent");
+ list_pins_apdu = new List_Pins_APDU(2);
+ list_pins_apdu = (List_Pins_APDU *) ComputeAPDU(list_pins_apdu);
+
+ /*
+ mac = ComputeAPDUMac(set_pin_apdu);
+ set_pin_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ list_pins_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::IsPinPresent",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::IsPinReset",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::IsPinReset",
+ "Invalid Msg Type");
+ goto loser;
+ }
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::IsPinReset",
+ "No Response From Token");
+ goto loser;
+ }
+
+ rc = 1;
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+/**
+ * Get Issuer Info
+ */
+Buffer Secure_Channel::GetIssuerInfo()
+{
+ Buffer data;
+ int rc = -1;
+ Get_IssuerInfo_APDU *get_issuerinfo_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+
+ RA::Debug("Secure_Channel::GetIssuerInfo",
+ "Secure_Channel::GetIssuerInfo");
+ get_issuerinfo_apdu = new Get_IssuerInfo_APDU();
+ rc = ComputeAPDU(get_issuerinfo_apdu);
+ if (rc == -1) {
+ goto loser;
+ }
+
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ get_issuerinfo_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::GetIssuerInfo",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::GetIssuerInfo",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::GetIssuerInfo",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::GetIssuerInfo",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::GetIssuerInfo",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::GetIssuerInfo",
+ "Bad Response");
+ rc = -1;
+ goto loser;
+ }
+
+ data = response->GetData();
+ rc = 1;
+loser:
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return data;
+} /* SetIssuerInfo */
+/**
+ * Set Issuer Info
+ */
+int Secure_Channel::SetIssuerInfo(Buffer *info)
+{
+ int rc = -1;
+ Set_IssuerInfo_APDU *set_issuerinfo_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+
+ RA::Debug("Secure_Channel::SetIssuerInfo",
+ "Secure_Channel::SetIssuerInfo");
+ set_issuerinfo_apdu = new Set_IssuerInfo_APDU(0x0, 0x0, *info);
+ rc = ComputeAPDU(set_issuerinfo_apdu);
+ if (rc == -1) {
+ goto loser;
+ }
+
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ set_issuerinfo_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::SetIssuerInfo",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::SetIssuerInfo",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::SetIssuerInfo",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::SetIssuerInfo",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::SetIssuerInfo",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::SetIssuerInfo",
+ "Bad Response");
+ rc = -1;
+ goto loser;
+ }
+
+ rc = 1;
+loser:
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+} /* SetIssuerInfo */
+
+/**
+ * Resets token's pin.
+ */
+int Secure_Channel::ResetPin(BYTE pin_number, char *new_pin)
+{
+ int rc = -1;
+ Set_Pin_APDU *set_pin_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+
+ RA::Debug("Secure_Channel::ResetPin",
+ "Secure_Channel::ResetPin");
+ Buffer data = Buffer((BYTE *)new_pin, strlen(new_pin));
+ set_pin_apdu = new Set_Pin_APDU(0x0, 0x0, data);
+ rc = ComputeAPDU(set_pin_apdu);
+ if (rc == -1) {
+ goto loser;
+ }
+
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ set_pin_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::ResetPin",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::ResetPin",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::ResetPin",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::ResetPin",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::ResetPin",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::ResetPin",
+ "Bad Response");
+ rc = -1;
+ goto loser;
+ }
+
+ rc = 1;
+loser:
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+} /* ResetPin */
+
+/**
+ * inject key (public key, mostly)
+ * @param key_number key slot number (from config file)
+ */
+int Secure_Channel::ImportKey(BYTE key_number)
+{
+ int rc = -1;
+ Import_Key_APDU *import_key_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ Buffer *mac = NULL;
+
+ RA::Debug("Secure_Channel::ImportKey",
+ "Secure_Channel::ImportKey");
+
+ import_key_apdu = new Import_Key_APDU(key_number);
+ rc = ComputeAPDU(import_key_apdu);
+ if (rc == -1) {
+ goto loser;
+ }
+
+ /*
+ mac = ComputeAPDUMac(import_key_apdu);
+ import_key_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ import_key_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::ImportKey",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::ImportKey",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::ImportKey",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::ImportKey",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::ImportKey",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::ImportKey",
+ "Error Response from Token %2x%2x",
+ response->GetSW1(),
+ response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+
+ rc = 1;
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+} /* ImportKey */
+
+/**
+ * inject an encrypted key (private key, mostly)
+ * @param key_number key slot number (from config file)
+ */
+int Secure_Channel::ImportKeyEnc(BYTE priv_key_number, BYTE pub_key_number, Buffer* data)
+{
+ int rc = -1;
+ Import_Key_Enc_APDU *import_key_enc_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ Buffer *mac = NULL;
+ BYTE objid[4];
+
+ objid[0] = 0xFF;
+ objid[1] = 0xFF;
+ objid[2] = 0xFF;
+ objid[3] = 0xFE;
+
+
+ RA::Debug("Secure_Channel::ImportKeyEnc",
+ "Secure_Channel::ImportKeyEnc");
+
+ import_key_enc_apdu = new Import_Key_Enc_APDU(priv_key_number, pub_key_number, *data);
+ rc = ComputeAPDU(import_key_enc_apdu);
+ if (rc == -1) {
+ goto loser;
+ }
+
+ /*
+ mac = ComputeAPDUMac(import_key_enc_apdu);
+ import_key_enc_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ import_key_enc_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::ImportKeyEnc",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::ImportKeyEnc",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::ImportKeyEnc",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::ImportKeyEnc",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::ImportKeyEnc",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::ImportKeyEnc",
+ "Error Response from Token %2x%2x",
+ response->GetSW1(),
+ response->GetSW2());
+ /*XXX debuging
+ debugBuf = ReadObject((BYTE*)objid, 0, 16);
+ if (debugBuf != NULL)
+ RA::DebugBuffer("Secure_Channel::ImportKeyEnc(): Error:", "debugBuf=",
+ debugBuf);
+ else
+ RA::Debug("Secure_Channel::ImportKeyEnc(): Error:", "ReadObject for debugging returns none");
+ */
+ rc = -1;
+ goto loser;
+ }
+
+ /* XXX debugging
+ debugBuf = ReadObject((BYTE*)objid, 0, 200);
+ if (debugBuf != NULL)
+ RA::DebugBuffer("Secure_Channel::ImportKeyEnc(): Success:", "debugBuf=",
+ debugBuf);
+ else
+ RA::Debug("Secure_Channel::ImportKeyEnc(): Sucess:", "ReadObject for debugging returns none");
+
+ */
+
+ rc = 1;
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+} /* ImportKeyEnc */
+
+
+/**
+ * Put Keys
+ *
+ * Global Platform Open Platform Card Specification
+ * Version 2.0.1 Page 9-19
+ * Sample Data:
+ *
+ * _____________ CLA
+ * | __________ INS
+ * | | _______ P1
+ * | | | ____ P2
+ * | | | | _ Len
+ * | | | | |
+ * 84 D8 00 81 4B
+ * 01
+ * 81 10 B4 BA A8 9A 8C D0 29 2B 45 21 0E (AUTH KEY)
+ * 1B C8 4B 1C 31
+ * 03 8B AF 47
+ * 81 10 B4 BA A8 9A 8C D0 29 2B 45 21 0E (MAC KEY)
+ * 1B C8 4B 1C 31
+ * 03 8B AF 47
+ * 81 10 B4 BA A8 9A 8C D0 29 2B 45 21 0E (KEK KEY)
+ * 1B C8 4B 1C 31
+ * 03 8B AF 47
+ * 5E B8 64 3F 73 9D 7D 62
+ *
+ * Data:
+ *
+ * - New key set version
+ * - key set data field (implicit key index P2+0)
+ * - key set data field (implicit key index P2+1)
+ * - key set data field (implicit key index P2+2)
+ *
+ * Key Set Data:
+ *
+ * Length Meaning
+ * ====== =========
+ * 1 Algorithm ID of key
+ * 1-n Length of key
+ * variable Key data value
+ * 0-n Length of Key check value
+ * variable Key check value (if present)
+ */
+int Secure_Channel::PutKeys(RA_Session *session, BYTE key_version,
+ BYTE key_index, Buffer *key_data)
+{
+ int rc = 0;
+ APDU_Response *put_key_response = NULL;
+ RA_Token_PDU_Request_Msg *put_key_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *put_key_response_msg = NULL;
+ Put_Key_APDU *put_key_apdu = NULL;
+ // Buffer *mac = NULL;
+ const char *FN="Secure_Channel::PutKeys";
+
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "RA_Processor::PutKey");
+
+ //For certain keys that require the implicit keyset
+ //00 00
+ //
+ if(key_version == 0xFF)
+ key_version = 0;
+
+ put_key_apdu = new Put_Key_APDU(key_version, 0x80 | key_index,
+ *key_data);
+ rc = ComputeAPDU(put_key_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(put_key_apdu);
+ put_key_apdu->SetMAC(*mac);
+ */
+ put_key_request_msg =
+ new RA_Token_PDU_Request_Msg(put_key_apdu);
+ session->WriteMsg(put_key_request_msg);
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "Sent put_key_request_msg");
+
+ put_key_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (put_key_response_msg == NULL)
+ {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (put_key_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+ put_key_response =
+ put_key_response_msg->GetResponse();
+ if (put_key_response == NULL) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (put_key_response->GetData().size() < 2) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(put_key_response->GetSW1() == 0x90 &&
+ put_key_response->GetSW2() == 0x00)) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "Error Response %2x%2x",
+ put_key_response->GetSW1(),
+ put_key_response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+
+ /* check error */
+ rc = 0;
+
+loser:
+ if( put_key_request_msg != NULL ) {
+ delete put_key_request_msg;
+ put_key_request_msg = NULL;
+ }
+ if( put_key_response_msg != NULL ) {
+ delete put_key_response_msg;
+ put_key_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+/**
+ * Sets token's lifecycle state.
+ */
+int Secure_Channel::SetLifecycleState(BYTE flag)
+{
+ int rc = -1;
+ Lifecycle_APDU *lifecycle_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ Buffer *mac = NULL;
+ const char *FN = "Secure_Channel::SetLifecycleState";
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Begin");
+ lifecycle_apdu = new Lifecycle_APDU(flag);
+ rc = ComputeAPDU(lifecycle_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(lifecycle_apdu);
+ lifecycle_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ lifecycle_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE)
+ {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Invalid Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (response->GetData().size() < 2) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Error Response from token: %2x%2x",
+ response->GetSW1(),
+ response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+
+ rc = 0;
+
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+} /* SetLifecycleState */
+
+
+char * Secure_Channel::getDrmWrappedDESKey()
+{
+ return PL_strdup(m_drm_wrapped_des_key_s);
+}
+
+char * Secure_Channel::getKekWrappedDESKey()
+{
+ return PL_strdup(m_kek_wrapped_des_key_s);
+}
+
+char * Secure_Channel::getKeycheck()
+{
+ return PL_strdup(m_keycheck_s);
+}
+
+
+/**
+ * Requests token to generate key in buffer.
+ */
+int Secure_Channel::StartEnrollment(BYTE p1, BYTE p2, Buffer *wrapped_challenge,
+ Buffer *key_check, BYTE alg, int keysize, BYTE option)
+{
+ int rc = -1;
+ Generate_Key_APDU *generate_key_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ Buffer *mac = NULL;
+ Buffer data;
+
+ RA::Debug("Secure_Channel::GenerateKey",
+ "Secure_Channel::GenerateKey");
+ generate_key_apdu = new Generate_Key_APDU(p1, p2, alg, keysize, option,
+ alg, *wrapped_challenge, *key_check);
+ rc = ComputeAPDU(generate_key_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(generate_key_apdu);
+ generate_key_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ generate_key_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::GenerateKey",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::GenerateKey",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE)
+ {
+ RA::Error("Secure_Channel::GenerateKey",
+ "Invalid Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("SecureChannel::GenerateKey", "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+
+ data = response->GetData();
+ if (data.size() != 4) {
+ RA::Error("SecureChannel::GenerateKey", "Token returned error");
+ rc = -1;
+ goto loser;
+ }
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::GenerateKey",
+ "Error Response from token %2x%2x",
+ response->GetSW1(),
+ response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+
+ /* key length */
+ rc = ((BYTE*)data)[0] * 256 + ((BYTE*)data)[1];
+
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+} /* GenerateKey */
+
+/**
+ * Reads data from token's buffer.
+ */
+int Secure_Channel::ReadBuffer(BYTE *buf, int buf_len)
+{
+ int rc = -1;
+ Read_Buffer_APDU *read_buffer_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ int offset = 0;
+ int wanted = buf_len;
+ int received = 0;
+ int request = 0;
+ int data_len;
+ Buffer data;
+ Buffer *mac = NULL;
+ const char *FN="Secure_Channel::ReadBuffer";
+
+#define MAX_READ_BUFFER_SIZE 0xd0
+ RA::Debug("Secure_Channel::ReadBuffer",
+ "Secure_Channel::ReadBuffer");
+
+ while (1)
+ {
+ if (wanted > MAX_READ_BUFFER_SIZE)
+ {
+ request = MAX_READ_BUFFER_SIZE;
+ }
+ else
+ {
+ request = wanted;
+ }
+ read_buffer_apdu = new Read_Buffer_APDU(request,offset);
+ rc = ComputeAPDU(read_buffer_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(read_buffer_apdu);
+ read_buffer_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ read_buffer_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL)
+ {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "Error Response from token %2x%2x",
+ response->GetSW1(),
+ response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+ data = response->GetData();
+ data_len = data.size() - 2;
+ if (data_len == 0)
+ {
+ break;
+ }
+
+// copy data into buffer
+ for (int i = 0; i < data_len; i++)
+ {
+ buf[offset+i] = ((BYTE*)data)[i];
+ }
+
+ received += data_len;
+ wanted -= data_len;
+ offset += data_len;
+
+ if (wanted == 0)
+ {
+ break;
+ }
+
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+ };
+
+ rc = received;
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+} /* ReadBuffer */
+
+/**
+ * Writes object to token.
+ */
+int Secure_Channel::CreateObject(BYTE *object_id, BYTE *permissions, int len)
+{
+ int rc = -1;
+ Create_Object_APDU *create_obj_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ Buffer *mac = NULL;
+
+ RA::Debug("Secure_Channel::CreateObject",
+ "Secure_Channel::CreateObject");
+ create_obj_apdu = new Create_Object_APDU(object_id, permissions, len);
+ rc = ComputeAPDU(create_obj_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(create_obj_apdu);
+ create_obj_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ create_obj_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::CreateObject",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::CreateObject",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::CreateObject",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::CreateObject",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::CreateObject",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::CreateObject",
+ "Error Response from token %2x%2x",
+ response->GetSW1(),
+ response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+
+ rc = 1;
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+} /* CreateObject */
+
+Buffer *Secure_Channel::ReadObject(BYTE *object_id, int offset, int len)
+{
+ int rc = -1;
+ Buffer data;
+ Read_Object_APDU *read_obj_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ Buffer *mac = NULL;
+ Buffer *buf = NULL;
+ Buffer result = Buffer();
+
+ RA::Debug("Secure_Channel::ReadObject",
+ "Secure_Channel::ReadObject");
+ int cur_read = 0;
+ int cur_offset = 0;
+ int sum = 0;
+
+#define MAX_READ_BUFFER_SIZE 0xd0
+
+ if (len > MAX_READ_BUFFER_SIZE) {
+ cur_offset = offset;
+ cur_read = MAX_READ_BUFFER_SIZE;
+ } else {
+ cur_offset = offset;
+ cur_read = len;
+ }
+
+ while (sum < len) {
+
+ read_obj_apdu = new Read_Object_APDU(object_id, cur_offset, cur_read);
+ rc = ComputeAPDU(read_obj_apdu);
+ if (rc == -1)
+ goto loser;
+
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ read_obj_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::ReadObject",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::ReadObject",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE)
+ {
+ RA::Error("Secure_Channel::ReadObject",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::ReadObject",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+
+ if (response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::ReadObject",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::ReadObject",
+ "Error Response from token %2x%2x",
+ response->GetSW1(),
+ response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+ data = response->GetData();
+ result += Buffer(data.substr(0, data.size() - 2));
+
+ sum += (data.size() - 2);
+ cur_offset += (data.size() - 2);
+
+ if ((len - sum) < MAX_READ_BUFFER_SIZE) {
+ cur_read = len - sum;
+ } else {
+ cur_read = MAX_READ_BUFFER_SIZE;
+ }
+ if (token_pdu_request_msg != NULL) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if (token_pdu_response_msg != NULL) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ }
+
+ buf = new Buffer((BYTE*)result, result.size());
+
+loser:
+ if (mac != NULL)
+ delete mac;
+ if (token_pdu_request_msg != NULL)
+ delete token_pdu_request_msg;
+ if (token_pdu_response_msg != NULL)
+ delete token_pdu_response_msg;
+
+ return buf;
+}
+
+/**
+ * Writes data to token's buffer.
+ */
+int Secure_Channel::WriteObject(BYTE *objid, BYTE *buf, int buf_len)
+{
+ int rc = -1;
+ int i;
+ Write_Object_APDU *write_buffer_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ int offset = 0;
+ int len = 0;
+ int to_send = buf_len;
+ BYTE *data = buf;
+#define MAX_WRITE_BUFFER_SIZE 0xd0
+ Buffer *send_buf = NULL;
+ Buffer *mac = NULL;
+
+ RA::Debug("Secure_Channel::WriteObject",
+ "Secure_Channel::WriteObject");
+ while (1)
+ {
+ send_buf = new Buffer(MAX_WRITE_BUFFER_SIZE, (BYTE)0);
+ mac = new Buffer(8, (BYTE)0);
+
+ if (to_send > MAX_WRITE_BUFFER_SIZE)
+ {
+ len = MAX_WRITE_BUFFER_SIZE;
+ }
+ else
+ {
+ len = to_send;
+ }
+ RA::Debug("Secure_Channel::WriteObject",
+ "Sent total=%d len=%d", buf_len, len);
+
+ for (i = 0; i < len; i++)
+ {
+ ((BYTE*)*send_buf)[i] = ((BYTE*)data)[i];
+ }
+ Buffer x_buf = Buffer(*send_buf, len);
+
+ write_buffer_apdu = new Write_Object_APDU(objid, offset, x_buf);
+ rc = ComputeAPDU(write_buffer_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(write_buffer_apdu);
+ write_buffer_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ write_buffer_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::WriteObject",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::WriteObject",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::WriteObject",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::WriteObject",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::WriteObject",
+ "Error Response from token %2x%2x",
+ response->GetSW1(),
+ response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+ data += len;
+ to_send -= len;
+ offset += len;
+
+ if (to_send == 0)
+ break; /* done */
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+ if( send_buf != NULL ) {
+ delete send_buf;
+ send_buf = NULL;
+ }
+ }
+
+ rc = 1;
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+ if( send_buf != NULL ) {
+ delete send_buf;
+ send_buf = NULL;
+ }
+
+ return rc;
+} /* WriteObject */
+
+int Secure_Channel::CreatePin(BYTE pin_number,
+ BYTE max_retries, const char *pin)
+{
+ int rc = -1;
+ Create_Pin_APDU *create_pin_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ Buffer *mac = NULL;
+
+ RA::Debug("Secure_Channel::CreatePin",
+ "Secure_Channel::CreatePin");
+ Buffer pin_buffer = Buffer((BYTE*)pin, strlen(pin));
+ create_pin_apdu = new Create_Pin_APDU(pin_number, max_retries,
+ pin_buffer);
+ rc = ComputeAPDU(create_pin_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(set_pin_apdu);
+ set_pin_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ create_pin_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::CreatePin",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::CreatePin",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::CreatePin",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::CreatePin",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+
+ rc = 1;
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+APDU_Response *Secure_Channel::SendTokenAPU(APDU *apdu)
+{
+ int rc;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+
+ RA::Debug("Secure_Channel::SendTokenAPDU",
+ "Secure_Channel::SendTokenAPDU");
+ rc = ComputeAPDU(apdu);
+ if (rc == -1)
+ goto loser;
+
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::SendTokenAPDU",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::SendTokenAPDU",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::SendTokenAPDU",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::SendTokenAPDU",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+
+loser:
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return response;
+}
+
+
+static void AppendSHORTtoBuffer(Buffer &buf,unsigned short s)
+{
+
+ buf += s/256;
+ buf += s%256;
+}
+
+
+static void AppendLONGtoBuffer(Buffer &buf, unsigned int l)
+{
+ buf += l>>24;
+ buf += (l >> 16) & 0xFF;
+ buf += (l >> 8) & 0xFF;
+ buf += l & 0xFF;
+}
+
+static void AppendAttribute(Buffer &buf, unsigned int type, unsigned int length, BYTE *b)
+{
+ AppendLONGtoBuffer(buf, type);
+ AppendSHORTtoBuffer(buf, length);
+ buf += Buffer(b,length);
+}
+
+static void AppendKeyCapabilities(Buffer &b, const char *opType, const char *tokenType, const char *keyTypePrefix, const char *keyType) {
+ char configname[256];
+
+ bool bvalue = false;
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.encrypt",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_ENCRYPT, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.sign",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_SIGN, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.signRecover",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_SIGN_RECOVER, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.decrypt",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_DECRYPT, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.derive",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_DERIVE, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.unwrap",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_UNWRAP, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.wrap",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_WRAP, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.verifyRecover",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_VERIFY_RECOVER, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.verify",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_VERIFY, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.sensitive",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_SENSITIVE, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.private",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_PRIVATE, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.token",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_TOKEN, 1, Util::bool2byte(bvalue));
+}
+
+static void FinalizeBuffer(Buffer &b, const char* id)
+{
+ ((BYTE*)b)[0] = 0;
+ ((BYTE*)b)[1] = id[0];
+ ((BYTE*)b)[2] = id[1];
+ ((BYTE*)b)[3] = 0;
+ ((BYTE*)b)[4] = 0;
+ ((BYTE*)b)[5] = (b.size()-7) / 256;
+ ((BYTE*)b)[6] = (b.size()-7) % 256;
+}
+
+/**
+ * Creates object on token.
+ */
+int Secure_Channel::CreateObject(BYTE *objid, BYTE *permissions, Buffer *obj)
+{
+ int rc = -1;
+ rc = CreateObject(objid, permissions, obj->size());
+ if (rc == -1)
+ goto loser;
+ rc = WriteObject(objid, (BYTE*)*obj, obj->size());
+ if (rc == -1)
+ goto loser;
+ rc = 1;
+loser:
+ return rc;
+} /* CreateObject */
+
+int Secure_Channel::CreateCertificate(const char *id, Buffer *cert)
+{
+ BYTE perms[6];
+
+ perms[0] = 0xff;
+ perms[1] = 0xff;
+ perms[2] = 0x40;
+ perms[3] = 0x00;
+ perms[4] = 0x40;
+ perms[5] = 0x00;
+
+ return CreateObject((BYTE*)id, perms, cert);
+} /* CreateCertificate */
+
+/*
+Cert attrib object (c0):
+CKA_LABEL(0x0003): cert nickname
+CKA_ID (0x0102): 20 bytes same as public key
+CKA_CERTIFICATE_TYPE(0x0080): 00 00 00 00 (CKC_X_509)
+CKA_CLASS(0x0000): 01 00 00 00 (little-endian for CKO_CERTIFICATE)
+CKA_TOKEN(0x0001): true
+
+0000000 0063 3000 0000 6400 0000 0300 294a 616d /Jam
+0000020 6965 204e 6963 6f6c 736f 6e27 7320 416d /ie Nicolson's Am
+0000040 6572 6963 6120 4f6e 6c69 6e65 2049 6e63 /erica Online Inc
+0000060 2049 4420 2332
+ 0000 0102 0014 709b a306 /ID #2
+0000100 3fc8 9ad4 23c6 a1b2 eb04 d8ff f7dd 3f55
+0000120 0000 0080 0004 0000 0000 0000 0000 0004
+0000140 0100 0000 0000 0001 0001 0100 0000 0000
+0000160 0000 0000 0000 0000 0000 0000 0000 0000
+
+mine: (no subject)
+
+
+ 0063 3000 0000 4500 0000 0300 0A74 6861
+ 7965 7330 3939 33
+ 0000 0102 0014 206E 8B36
+ 03A5 568D 266D 51EC 40F0 E35B B55F 8BCC
+ 0000 0080 0004 0000 0000 0000 0000 0004
+ 0100 0000 0000 0001 0001 01
+
+*/
+
+Buffer Secure_Channel::CreatePKCS11CertAttrsBuffer(TokenKeyType key_type, const char *id, const char *label, Buffer *keyid)
+{
+ BYTE type[4] = { 0,0,0,0 };
+ BYTE p11class[4] = { 1,0,0,0 };
+ BYTE tokenflag[1] = { 1 };
+
+ Buffer b(256); // allocate some space
+ b.resize(7); // this keeps the allocated space around
+
+ RA::Debug("Secure_Channel::CreatePKCS11CertAttrs", "id=%s", id);
+ RA::Debug("Secure_Channel::CreatePKCS11CertAttrs", "label=%s", label);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11CertAttrs", "keyid", keyid);
+ AppendAttribute(b, CKA_LABEL, strlen(label), (BYTE*)label);
+ // hash of pubk
+ AppendAttribute(b, CKA_ID, keyid->size(), (BYTE*)*keyid);
+ // type of cert
+ AppendAttribute(b, CKA_CERTIFICATE_TYPE, 4, type);
+ AppendAttribute(b, CKA_CLASS, 4, p11class ); // type of object
+ AppendAttribute(b, CKA_TOKEN, 1, tokenflag);
+ FinalizeBuffer(b, id);
+
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11CertAttrsBuffer", "buffer", &b);
+
+ return b;
+}
+
+int Secure_Channel::CreatePKCS11CertAttrs(TokenKeyType key_type, const char *id, const char *label, Buffer *keyid)
+{
+ BYTE type[4] = { 0,0,0,0 };
+ BYTE p11class[4] = { 1,0,0,0 };
+ BYTE tokenflag[1] = { 1 };
+
+ Buffer b(256); // allocate some space
+ b.resize(7); // this keeps the allocated space around
+
+ RA::Debug("Secure_Channel::CreatePKCS11CertAttrs", "id=%s", id);
+ RA::Debug("Secure_Channel::CreatePKCS11CertAttrs", "label=%s", label);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11CertAttrs", "keyid", keyid);
+ AppendAttribute(b, CKA_LABEL, strlen(label), (BYTE*)label);
+ // hash of pubk
+ AppendAttribute(b, CKA_ID, keyid->size(), (BYTE*)*keyid);
+ // type of cert
+ AppendAttribute(b, CKA_CERTIFICATE_TYPE, 4, type);
+ AppendAttribute(b, CKA_CLASS, 4, p11class ); // type of object
+ AppendAttribute(b, CKA_TOKEN, 1, tokenflag);
+ FinalizeBuffer(b, id);
+
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11CertAttrs", "buffer", &b);
+
+ BYTE perms[6];
+
+ perms[0] = 0xff;
+ perms[1] = 0xff;
+ perms[2] = 0x40;
+ perms[3] = 0x00;
+ perms[4] = 0x40;
+ perms[5] = 0x00;
+
+ return CreateObject((BYTE*)id, perms, &b);
+} /* CreatePKCS11CertAttrs */
+
+/*
+
+Private Key: (k0)
+CKA_SUBJECT (0x0101): subject name of cert
+CKA_LABEL (0x0003): nickname of cert
+CKA_MODULUS (0x0120)
+ (sha1 hash of spki)
+CKA_ID (0x0102): ?? (20 bytes, 70 9b a3 06 3f c8 9a d4 23 c6 a1 b2 eb 04 d8 ff f7 dd 3f 55)
+CKA_SENSITIVE(0x0103): true
+CKA_PRIVATE(0x0002): true
+CKA_TOKEN(0x0001): true
+CKA_KEY_TYPE(0x0100): 0x00000000 (CKK_RSA)
+cKA_CLASS(0x0000): 03 00 00 00 (little-endian(!) for CKO_PRIVATE_KEY)
+
+
+0000000 006b 3000 0001 8400 0001 0100 8630 8183
+0000020 310b 3009 0603 5504 0613 0255 5331 1b30
+0000040 1906 0355 040a 1312 416d 6572 6963 6120
+0000060 4f6e 6c69 6e65 2049 6e63 3118 3016 060a
+0000100 0992 2689 93f2 2c64 0101 1308 6e69 636f
+0000120 6c73 6f6e 3124 3022 0609 2a86 4886 f70d
+0000140 0109 0116 156e 6963 6f6c 736f 6e40 6e65
+0000160 7473 6361 7065 2e63 6f6d 3117 3015 0603
+0000200 5504 0313 0e4a 616d 6965 204e 6963 6f6c
+0000220 736f 6e00 00
+ 00 0300 294a 616d 6965 204e
+0000240 6963 6f6c 736f 6e27 7320 416d 6572 6963
+0000260 6120 4f6e 6c69 6e65 2049 6e63 2049 4420
+0000300 2332
+ 0000 0120 0080 a70e 07f4 3f51 86c7
+0000320 4f8d 4b64 522d 8c4b 31ae 58f2 f04d a9fd
+0000340 2701 637e 5245 bb48 23ec 2259 742b ddc4
+0000360 e5da f571 78df 07ba b555 6d05 0de5 7329
+0000400 f073 94e2 00a6 f846 d99d d01c 8b62 684c
+0000420 5133 9b16 3c8f ee83 34fc 844d 829b 6fca
+0000440 e694 c432 9532 6413 323c 8b81 bc64 ed30
+0000460 6074 6926 aff5 6b7f cb43 0c40 c039 ba55
+0000500 7d3a 365d bb82 0b49 0000 0102 0014 709b
+0000520 a306 3fc8 9ad4 23c6 a1b2 eb04 d8ff f7dd
+0000540 3f55 0000 0103 0001 0100 0000 0200 0101
+0000560 0000 0001 0001 0100 0001 0000 0400 0000
+0000600 0000 0000 0000 0403 0000 0000 0000 0000
+0000620 0000 0000 0000 0000 0000 0000 0000 0000
+0000640 0000 015e ffff ffff fffe 0002 0002 0002
+0000660 014e 0000 0000 0000 0000 0000 0000 0000
+0000700 0000 0000 0000 0000 0000 0000 0000 0000
+
+mine:
+
+ 006B 3000 0000 D900 0000 0300 0A74 6861
+ 7965 7330 3939 33
+ 0000 0120 0080 DB1F EF
+ 9EEA 63EC F3A9 F831 EDB2 AC38 3957 1917
+ 186D 1CEB 782D 34BA B6DA 4F65 54A5 68B0
+ A08F 7840 FDF8 E115 E8A4 1522 4706 B807
+ 572A 31D2 2BB9 DD9F AF0C 2E0B 8183 ADE2
+ 78C4 B13E 0ED6 92F1 9989 D872 1474 A7A6
+ 2205 7928 1977 075A 5A76 B24D 8FE0 99C1
+ 32BE AE72 5C5D A8FA 3E93 F815 0669 074A
+ 2FF5 99EE 4A29 EDC8 5B79 7B93 5D
+ 0000 0102 0014 206E 8B36 03A5 568D 266D
+ 51EC 40F0 E35B B55F 8BCC
+ 0000 0103 0001 0100 00
+ 00020001010000000100010100000100
+ 00040000000000000000000403000000
+
+ H 00020001010000000100010100000100
+ H 00040000000000000000000403000000
+
+ M 00020001010000000100010100000100
+ M 00040000000000000000000403000000
+*/
+Buffer Secure_Channel::CreatePKCS11PriKeyAttrsBuffer(TokenKeyType key_type, const char *id, const char *label, Buffer *keyid,
+ Buffer *modulus, const char *opType, const char *tokenType, const char *keyTypePrefix)
+{
+ // BYTE sensitiveflag[1] = { 1 };
+ // BYTE privateflag[1] = { 1 };
+ // BYTE token[1] = { 1 };
+ BYTE keytype[4] = { 0,0,0,0 };
+ BYTE p11class[4] = { 3,0,0,0 };
+ // BYTE ZERO[1] = { 0 };
+ // BYTE ONE[1] = { 1 };
+ // char configname[256];
+
+ Buffer b(256); // allocate some space
+ b.resize(7); // this keeps the allocated space around
+
+ RA::Debug("Secure_Channel::CreatePKCS11PriAttrs", "label=%s", label);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PriAttrs", "keyid", keyid);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PriAttrs", "modulus", modulus);
+ RA::Debug("Secure_Channel::CreatePKCS11PriAttrs", "id=%s",id);
+
+// AppendAttribute(b,CKA_LABEL, strlen(label), (BYTE*)label);
+ AppendAttribute(b,CKA_MODULUS, modulus->size(), (BYTE*)*modulus);
+ AppendAttribute(b,CKA_KEY_TYPE, 4, keytype);
+ AppendAttribute(b,CKA_CLASS, 4, p11class );
+ // hash of pubk
+ AppendAttribute(b,CKA_ID, keyid->size(), (BYTE*)*keyid);
+
+ AppendKeyCapabilities(b, opType, tokenType, keyTypePrefix, "private");
+
+ FinalizeBuffer(b, id);
+
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PriAttrsBuffer", "buffer", &b);
+
+ return b;
+
+} /* CreatePKCS11PriKeyAttrs */
+
+int Secure_Channel::CreatePKCS11PriKeyAttrs(TokenKeyType key_type, const char *id, const char *label, Buffer *keyid,
+ Buffer *modulus, const char *opType, const char *tokenType, const char *keyTypePrefix)
+{
+ // BYTE sensitiveflag[1] = { 1 };
+ // BYTE privateflag[1] = { 1 };
+ // BYTE token[1] = { 1 };
+ BYTE keytype[4] = { 0,0,0,0 };
+ BYTE p11class[4] = { 3,0,0,0 };
+ // BYTE ZERO[1] = { 0 };
+ // BYTE ONE[1] = { 1 };
+ // char configname[256];
+
+ Buffer b(256); // allocate some space
+ b.resize(7); // this keeps the allocated space around
+
+ RA::Debug("Secure_Channel::CreatePKCS11PriAttrs", "label=%s", label);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PriAttrs", "keyid", keyid);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PriAttrs", "modulus", modulus);
+
+// AppendAttribute(b,CKA_LABEL, strlen(label), (BYTE*)label);
+ AppendAttribute(b,CKA_MODULUS, modulus->size(), (BYTE*)*modulus);
+ AppendAttribute(b,CKA_KEY_TYPE, 4, keytype);
+ AppendAttribute(b,CKA_CLASS, 4, p11class );
+ // hash of pubk
+ AppendAttribute(b,CKA_ID, keyid->size(), (BYTE*)*keyid);
+
+ AppendKeyCapabilities(b, opType, tokenType, keyTypePrefix, "private");
+
+ FinalizeBuffer(b, id);
+
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PriAttrs", "buffer", &b);
+
+ BYTE perms[6];
+
+ perms[0] = 0xff;
+ perms[1] = 0xff;
+ perms[2] = 0x40;
+ perms[3] = 0x00;
+ perms[4] = 0x40;
+ perms[5] = 0x00;
+
+ return CreateObject((BYTE*)id, perms, &b);
+
+} /* CreatePKCS11PriKeyAttrs */
+
+/*
+Public Key: (k1)
+CKA_PUBLIC_EXPONENT(0x0122)
+CKA_MODULUS(0x0120)
+CKA_ID (0x0102): (20 bytes) same as private key
+CKA_CLASS(0x0000): 02 00 00 00 (little-endian for CKO_PUBLIC_KEY)
+
+0000000 006b 3100 0000 b300 0001 2200 0301 0001
+0000020 0000 0120 0080 a70e 07f4 3f51 86c7 4f8d
+0000040 4b64 522d 8c4b 31ae 58f2 f04d a9fd 2701
+0000060 637e 5245 bb48 23ec 2259 742b ddc4 e5da
+0000100 f571 78df 07ba b555 6d05 0de5 7329 f073
+0000120 94e2 00a6 f846 d99d d01c 8b62 684c 5133
+0000140 9b16 3c8f ee83 34fc 844d 829b 6fca e694
+0000160 c432 9532 6413 323c 8b81 bc64 ed30 6074
+0000200 6926 aff5 6b7f cb43 0c40 c039 ba55 7d3a
+0000220 365d bb82 0b49 0000 0102 0014 709b a306
+0000240 3fc8 9ad4 23c6 a1b2 eb04 d8ff f7dd 3f55
+0000260 0000 0000 0004 0200 0000 0000 0000 0000
+0000300 0000 0000 0000 0000 0000 0000 0000 0000
+*
+0000400
+
+mine:
+ 006B 3100 0000 B300 0001 2200 0301 0001
+ 0000 0120 0080 F3E1 1AF0 906D BD35 4792
+ 348A CC4D 6147 CFAC 659A D018 34DD 4621
+ AB57 75F5 B5E0 87D4 F6C2 2B89 3324 D980
+ 2926 4BF1 0F64 A6E5 4368 9DA5 2620 335E
+ ADCD 7540 7CBA B1F9 4ACE EEF8 13FF 6524
+ B76F C7B1 2D21 DD42 5342 EFC3 034E 39DD
+ ACBC 5C43 AC14 974A 45D4 5E66 6FFA BB17
+ 1E98 C177 68CC B51B 1B7E 28C5 38AB 729D
+ 27FD 3077 8C39 0000 0102 0014 815B 6FFE
+ 9B2A 8515 9C76 0F92 4A4E 349F 61EA 521F
+ 0000 0000 0004 0200 0000
+
+
+*/
+Buffer Secure_Channel::CreatePKCS11PubKeyAttrsBuffer(TokenKeyType key_type, const char *id, const char *label, Buffer *keyid,
+ Buffer *exponent, Buffer *modulus, const char *opType, const char *tokenType, const char *keyTypePrefix)
+{
+#if 0
+ BYTE pubexp[3] = // XXX should I really hardcode this!?
+ {
+ 0x01,0x00,0x01
+ };
+#endif
+ BYTE p11class[4] = { 2,0,0,0 };
+ // BYTE ZERO[1] = { 0 };
+ // BYTE ONE[1] = { 1 };
+ // char configname[256];
+
+ Buffer b(256); // allocate some space
+ b.resize(7); // this keeps the allocated space around
+
+ RA::Debug("Secure_Channel::CreatePKCS11PubAttrs", "label=%s", label);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PubAttrs", "keyid", keyid);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PubAttrs", "modulus", modulus);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PubAttrs", "exponent", exponent);
+
+ AppendAttribute(b, CKA_PUBLIC_EXPONENT, exponent->size(),(BYTE*) *exponent);
+ AppendAttribute(b,CKA_MODULUS, modulus->size(), (BYTE*)*modulus);
+ // XXX TUES
+ // hash of pubk
+ AppendAttribute(b,CKA_ID, keyid->size(), (BYTE*)*keyid);
+ AppendAttribute(b, CKA_CLASS, 4, p11class ); // type of object
+
+ AppendKeyCapabilities(b, opType, tokenType, keyTypePrefix, "public");
+
+
+ FinalizeBuffer(b, id);
+
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PubAttrsBuffer", "buffer", &b);
+
+ return b;
+} /* CreatePKCS11PubKeyAttrs */
+
+int Secure_Channel::CreatePKCS11PubKeyAttrs(TokenKeyType key_type, const char *id, const char *label, Buffer *keyid,
+ Buffer *exponent, Buffer *modulus, const char *opType, const char *tokenType, const char *keyTypePrefix)
+{
+#if 0
+ BYTE pubexp[3] = // XXX should I really hardcode this!?
+ {
+ 0x01,0x00,0x01
+ };
+#endif
+ BYTE p11class[4] = { 2,0,0,0 };
+ // BYTE ZERO[1] = { 0 };
+ // BYTE ONE[1] = { 1 };
+ // char configname[256];
+
+ Buffer b(256); // allocate some space
+ b.resize(7); // this keeps the allocated space around
+
+ RA::Debug("Secure_Channel::CreatePKCS11PubAttrs", "label=%s", label);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PubAttrs", "keyid", keyid);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PubAttrs", "modulus", modulus);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PubAttrs", "exponent", exponent);
+
+ AppendAttribute(b, CKA_PUBLIC_EXPONENT, exponent->size(),(BYTE*) *exponent);
+ AppendAttribute(b,CKA_MODULUS, modulus->size(), (BYTE*)*modulus);
+ // XXX TUES
+ // hash of pubk
+ AppendAttribute(b,CKA_ID, keyid->size(), (BYTE*)*keyid);
+ AppendAttribute(b, CKA_CLASS, 4, p11class ); // type of object
+
+ AppendKeyCapabilities(b, opType, tokenType, keyTypePrefix, "public");
+
+
+ FinalizeBuffer(b, id);
+
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PubAttrs", "buffer", &b);
+
+ BYTE perms[6];
+
+ perms[0] = 0xff;
+ perms[1] = 0xff;
+ perms[2] = 0x40;
+ perms[3] = 0x00;
+ perms[4] = 0x40;
+ perms[5] = 0x00;
+
+ return CreateObject((BYTE*)id, perms, &b);
+} /* CreatePKCS11PubKeyAttrs */
+
+Buffer &Secure_Channel::GetKeyDiversificationData()
+{
+ return m_key_diversification_data;
+} /* GetKeyDiversificationData */
+
+Buffer &Secure_Channel::GetKeyInfoData()
+{
+ return m_key_info_data;
+} /* GetKeyInfoData */
+
+Buffer &Secure_Channel::GetCardChallenge()
+{
+ return m_card_challenge;
+} /* GetCardChallenge */
+
+Buffer &Secure_Channel::GetCardCryptogram()
+{
+ return m_card_cryptogram;
+} /* GetCardCryptogram */
+
+Buffer &Secure_Channel::GetHostChallenge()
+{
+ return m_host_challenge;
+} /* GetCardCryptogram */
+
+Buffer &Secure_Channel::GetHostCryptogram()
+{
+ return m_host_cryptogram;
+} /* GetHostCryptogram */
+
+SecurityLevel Secure_Channel::GetSecurityLevel()
+{
+ return m_security_level;
+}
+
+void Secure_Channel::SetSecurityLevel(SecurityLevel level)
+{
+ m_security_level = level;
+}
diff --git a/base/tps/src/cms/CertEnroll.cpp b/base/tps/src/cms/CertEnroll.cpp
new file mode 100644
index 000000000..89990d021
--- /dev/null
+++ b/base/tps/src/cms/CertEnroll.cpp
@@ -0,0 +1,725 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <string.h>
+
+#include "main/RA_Session.h"
+#include "main/RA_Msg.h"
+#include "main/Buffer.h"
+#include "main/Util.h"
+#include "engine/RA.h"
+#include "cms/HttpConnection.h"
+#include "cms/CertEnroll.h"
+
+// for public key processing
+#include "pk11func.h"
+#include "cryptohi.h"
+#include "keyhi.h"
+#include "base64.h"
+#include "nssb64.h"
+#include "prlock.h"
+
+#include "main/Memory.h"
+
+Buffer * parseResponse(char * /*response*/);
+ReturnStatus verifyProof(SECKEYPublicKey* , SECItem* ,
+ unsigned short , unsigned char* ,
+ unsigned char* );
+
+#ifdef XP_WIN32
+#define TOKENDB_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TOKENDB_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs handle for Certificate Enrollment
+ */
+TOKENDB_PUBLIC CertEnroll::CertEnroll()
+{
+}
+
+/**
+ * Destructs handle for Certificate Enrollment
+ */
+TOKENDB_PUBLIC CertEnroll::~CertEnroll()
+{
+}
+
+/**
+ * Revokes a certificate in the CA
+ * reason:
+ * 0 = Unspecified
+ * 1 = Key compromised
+ * 2 = CA key compromised
+ * 3 = Affiliation changed
+ * 4 = Certificate superseded
+ * 5 = Cessation of operation
+ * 6 = Certificate is on hold
+ * serialno: serial number in decimal
+ */
+TOKENDB_PUBLIC int CertEnroll::RevokeCertificate(const char *reason, const char *serialno, const char *connid, char *&o_status)
+{
+ char parameters[5000];
+ char configname[5000];
+ int num;
+
+ PR_snprintf((char *)parameters, 5000, "op=revoke&revocationReason=%s&revokeAll=(certRecordId%%3D%s)&totalRecordCount=1", reason, serialno);
+
+ PR_snprintf((char *)configname, 256, "conn.%s.servlet.revoke", connid);
+ char *servletID = (char*)RA::GetConfigStore()->GetConfigAsString(configname);
+
+ PSHttpResponse *resp = sendReqToCA(servletID, parameters, connid);
+
+ if (resp != NULL) {
+ char *content = resp->getContent();
+ char *p = strstr(content, "status=");
+ num = *(p+7) - '0';
+ RA::Debug("CertEnroll::RevokeCertificate", "serialno=%s reason=%s connid=%s status=%d", serialno, reason, connid, num);
+ if (num != 0) {
+ char *q = strstr(p, "error=");
+ q = q+6;
+ o_status = PL_strdup(q);
+ RA::Debug("CertEnroll::RevokeCertificate", "status string=%s", q);
+ }
+ if (content != NULL) {
+ resp->freeContent();
+ content = NULL;
+ }
+ delete resp;
+ resp = NULL;
+ } else {
+ RA::Debug("CertEnroll::RevokeCertificate", "serialno=%s reason=%s connid=%s failed: resp is NULL");
+ o_status = PL_strdup("resp from sendReqToCA is NULL");
+ num = 1; //non-zero
+ }
+ return num;
+}
+
+TOKENDB_PUBLIC int CertEnroll::UnrevokeCertificate(const char *serialno, const char *connid,
+ char *&o_status)
+{
+ char parameters[5000];
+ char configname[5000];
+ int num;
+
+ PR_snprintf((char *)parameters, 5000, "serialNumber=%s",serialno);
+
+ PR_snprintf((char *)configname, 256, "conn.%s.servlet.unrevoke", connid);
+ char *servletID = (char*)RA::GetConfigStore()->GetConfigAsString(configname);
+
+ PSHttpResponse *resp = sendReqToCA(servletID, parameters, connid);
+ if (resp != NULL) {
+ // XXX - need to parse response
+ char *content = resp->getContent();
+ char *p = strstr(content, "status=");
+ num = *(p+7) - '0';
+ RA::Debug("CertEnroll::UnrevokeCertificate", "status=%d", num);
+
+ if (num != 0) {
+ char *q = strstr(p, "error=");
+ q = q+6;
+ o_status = PL_strdup(q);
+ RA::Debug("CertEnroll::UnrevokeCertificate", "status string=%s", q);
+ }
+
+ if (content != NULL) {
+ resp->freeContent();
+ content = NULL;
+ }
+ delete resp;
+ resp = NULL;
+ } else {
+ RA::Debug("CertEnroll::UnrevokeCertificate", "serialno=%s reason=%s connid=%s failed: resp is NULL");
+ o_status = PL_strdup("resp from sendReqToCA is NULL");
+ num = 1; //non-zero
+ }
+
+ return num;
+}
+
+TOKENDB_PUBLIC Buffer *CertEnroll::RenewCertificate(PRUint64 serialno, const char *connid, const char *profileId, char *error_msg)
+{
+ char parameters[5000];
+ char configname[5000];
+
+ RA::Debug("CertEnroll::RenewCertificate", "begins. profileId=%s",profileId);
+ // on CA, renewal expects parameter "serial_num" if renew by serial number
+ // ahh. need to allow larger serialno...later
+ PR_snprintf((char *)parameters, 5000, "serial_num=%u&profileId=%s&renewal=true",
+ (int)serialno, profileId);
+ RA::Debug("CertEnroll::RenewCertificate", "got parameters =%s", parameters);
+ //e.g. conn.ca1.servlet.renewal=/ca/ee/ca/profileSubmitSSLClient
+ PR_snprintf((char *)configname, 256, "conn.%s.servlet.renewal", connid);
+ const char *servlet = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (servlet == NULL) {
+ RA::Debug("CertEnroll::RenewCertificate",
+ "Missing the configuration parameter for %s", configname);
+ PR_snprintf(error_msg, 512, "Missing the configuration parameter for %s", configname);
+ return NULL;
+ }
+
+ // on CA, same profile servlet processes the renewal as well as enrollment
+ PSHttpResponse *resp = sendReqToCA(servlet, parameters, connid);
+ // XXX - need to parse response
+ Buffer * certificate = NULL;
+ if (resp != NULL) {
+ RA::Debug(LL_PER_PDU, "CertEnroll::RenewCertificate",
+ "sendReqToCA done");
+
+ certificate = parseResponse(resp);
+ RA::Debug(LL_PER_PDU, "CertEnroll::RenewCertificate",
+ "parseResponse done");
+
+ if( resp != NULL ) {
+ delete resp;
+ resp = NULL;
+ }
+ } else {
+ RA::Error("CertEnroll::RenewCertificate",
+ "sendReqToCA failure");
+ PR_snprintf(error_msg, 512, "sendReqToCA failure");
+ return NULL;
+ }
+
+ return certificate;
+}
+
+
+/**
+ * Sends certificate request to CA for enrollment.
+ */
+Buffer * CertEnroll::EnrollCertificate(
+ SECKEYPublicKey *pk_parsed,
+ const char *profileId,
+ const char *uid,
+ const char *cuid /*token id*/,
+ const char *connid,
+ char *error_msg,
+ SECItem** encodedPublicKeyInfo)
+{
+ char parameters[5000];
+
+ SECItem* si = SECKEY_EncodeDERSubjectPublicKeyInfo(pk_parsed);
+ if (si == NULL) {
+
+ RA::Error("CertEnroll::EnrollCertificate",
+ "SECKEY_EncodeDERSubjectPublicKeyInfo returns error");
+ PR_snprintf(error_msg, 512, "SECKEY_EncodeDERSubjectPublicKeyInfo returns error");
+ return NULL;
+ }
+
+ // b64 encode it
+ char* pk_b64 = BTOA_ConvertItemToAscii(si);
+
+ if(encodedPublicKeyInfo == NULL)
+ {
+ if( si != NULL ) {
+ SECITEM_FreeItem( si, PR_TRUE );
+ si = NULL;
+ }
+ }
+ else
+ {
+
+ *encodedPublicKeyInfo = si;
+
+ }
+
+ if (pk_b64 == NULL) {
+ RA::Error(LL_PER_PDU, "CertEnroll::EnrollCertificate",
+ "BTOA_ConvertItemToAscii returns error");
+
+ PR_snprintf(error_msg, 512, "BTOA_ConvertItemToAscii returns error");
+ return NULL;
+ }
+ RA::Debug(LL_PER_PDU, "CertEnroll::EnrollCertificate",
+ "after BTOA_ConvertItemToAscii pk_b64=%s",pk_b64);
+
+ char *url_pk = Util::URLEncode(pk_b64);
+ char *url_uid = Util::URLEncode(uid);
+ char *url_cuid = Util::URLEncode(cuid);
+ const char *servlet;
+ char configname[256];
+
+ PR_snprintf((char *)configname, 256, "conn.%s.servlet.enrollment", connid);
+ servlet = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ PR_snprintf((char *)parameters, 5000, "profileId=%s&tokencuid=%s&screenname=%s&publickey=%s", profileId, url_cuid, url_uid, url_pk);
+
+ PSHttpResponse *resp = sendReqToCA(servlet, parameters, connid);
+ Buffer * certificate = NULL;
+ if (resp != NULL) {
+ RA::Debug(LL_PER_PDU, "CertEnroll::EnrollCertificate",
+ "sendReqToCA done");
+
+ certificate = parseResponse(resp);
+ RA::Debug(LL_PER_PDU, "CertEnroll::EnrollCertificate",
+ "parseResponse done");
+
+ if( resp != NULL ) {
+ delete resp;
+ resp = NULL;
+ }
+ } else {
+ RA::Error("CertEnroll::EnrollCertificate",
+ "sendReqToCA failure");
+ PR_snprintf(error_msg, 512, "sendReqToCA failure");
+ return NULL;
+ }
+
+ if( pk_b64 != NULL ) {
+ PR_Free( pk_b64 );
+ pk_b64 = NULL;
+ }
+ if( url_pk != NULL ) {
+ PR_Free( url_pk );
+ url_pk = NULL;
+ }
+ if( url_uid != NULL ) {
+ PR_Free( url_uid );
+ url_uid = NULL;
+ }
+ if( url_cuid != NULL ) {
+ PR_Free( url_cuid );
+ url_cuid = NULL;
+ }
+
+ return certificate;
+}
+
+/**
+ * Extracts information from the public key blob and verify proof.
+ *
+ * Muscle Key Blob Format (RSA Public Key)
+ * ---------------------------------------
+ *
+ * The key generation operation places the newly generated key into
+ * the output buffer encoding in the standard Muscle key blob format.
+ * For an RSA key the data is as follows:
+ *
+ * Byte Encoding (0 for plaintext)
+ *
+ * Byte Key Type (1 for RSA public)
+ *
+ * Short Key Length (1024 û high byte first)
+ *
+ * Short Modulus Length
+ *
+ * Byte[] Modulus
+ *
+ * Short Exponent Length
+ *
+ * Byte[] Exponent
+ *
+ *
+ * Signature Format (Proof)
+ * ---------------------------------------
+ *
+ * The key generation operation creates a proof-of-location for the
+ * newly generated key. This proof is a signature computed with the
+ * new private key using the RSA-with-MD5 signature algorithm. The
+ * signature is computed over the Muscle Key Blob representation of
+ * the new public key and the challenge sent in the key generation
+ * request. These two data fields are concatenated together to form
+ * the input to the signature, without any other data or length fields.
+ *
+ * Byte[] Key Blob Data
+ *
+ * Byte[] Challenge
+ *
+ *
+ * Key Generation Result
+ * ---------------------------------------
+ *
+ * The key generation command puts the key blob and the signature (proof)
+ * into the output buffer using the following format:
+ *
+ * Short Length of the Key Blob
+ *
+ * Byte[] Key Blob Data
+ *
+ * Short Length of the Proof
+ *
+ * Byte[] Proof (Signature) Data
+ *
+ * @param blob the publickey blob to be parsed
+ * @param challenge the challenge generated by RA
+ * @return
+ * rc is 1 if success, -1 if failure
+ * pk is the public key resulted from parsing the blob.
+ *
+ ******/
+
+SECKEYPublicKey *CertEnroll::ParsePublicKeyBlob(unsigned char *blob,
+ Buffer *challenge)
+{
+ char configname[5000];
+ SECKEYPublicKey *pk = NULL;
+
+ ReturnStatus rs;
+ rs.status = PR_FAILURE;
+ rs.statusNum = ::MSG_INVALID;
+
+ if ((blob == NULL) || (challenge == NULL)) {
+ RA::Error(LL_PER_PDU, "CertEnroll::ParsePublicKeyBlob", "invalid input");
+ return NULL;
+ }
+
+ /*
+ * decode blob into structures
+ */
+
+ // offset to the beginning of the public key length. should be 0
+ unsigned short pkeyb_len_offset = 0;
+
+ unsigned short pkeyb_len = 0;
+ unsigned char* pkeyb;
+ unsigned short proofb_len = 0;
+ unsigned char* proofb;
+
+ /*
+ * now, convert lengths
+ */
+ // 1st, keyblob length
+ unsigned char len0 = blob[pkeyb_len_offset];
+ unsigned char len1 = blob[pkeyb_len_offset +1];
+ pkeyb_len = (unsigned short) ((len0 << 8) | (len1 & 0xFF));
+
+ RA::Debug(LL_PER_PDU, "CertEnroll::ParsePublicKeyBlob",
+ "pkeyb_len =%d",pkeyb_len);
+
+ if (pkeyb_len <= 0) {
+ RA::Error("CertEnroll::ParsePublicKeyBlob", "public key blob length = %d", pkeyb_len);
+ return NULL;
+ }
+ // 2nd, proofblob length
+ unsigned short proofb_len_offset = pkeyb_len_offset + 2 + pkeyb_len;
+ len0 = blob[proofb_len_offset];
+ len1 = blob[proofb_len_offset +1];
+ proofb_len = (unsigned short) (len0 << 8 | len1 & 0xFF);
+ RA::Debug(LL_PER_PDU, "CertEnroll::ParsePublicKeyBlob",
+ "proofb_len =%d", proofb_len);
+
+ // public key blob
+ pkeyb = &blob[pkeyb_len_offset + 2];
+
+ // proof blob
+ proofb = &blob[proofb_len_offset + 2];
+
+ SECItem siProof;
+ siProof.type = (SECItemType) 0;
+ siProof.data = (unsigned char *)proofb;
+ siProof.len = proofb_len;
+
+ // convert pkeyb to pkey
+ // 1 byte encoding, 1 byte key type, 2 bytes key length, then the key
+ unsigned short pkey_offset = 4;
+ // now, convert lengths for modulus and exponent
+ len0 = pkeyb[pkey_offset];
+ len1 = pkeyb[pkey_offset + 1];
+ unsigned short mod_len = (len0 << 8 | len1);
+
+ len0 = pkeyb[pkey_offset + 2 + mod_len];
+ len1 = pkeyb[pkey_offset + 2 + mod_len + 1];
+ unsigned short exp_len = (len0 << 8 | len1);
+
+
+ // public key mod blob
+ unsigned char * modb = &pkeyb[pkey_offset + 2];
+
+ // public key exp blob
+ unsigned char * expb = &pkeyb[pkey_offset + 2 + mod_len + 2];
+
+ // construct SECItem
+ SECItem siMod;
+ siMod.type = (SECItemType) 0;
+ siMod.data = (unsigned char *) modb;
+ siMod.len = mod_len;
+
+ SECItem siExp;
+ siExp.type = (SECItemType) 0;
+ siExp.data = (unsigned char *)expb;
+ siExp.len = exp_len;
+
+ // construct SECKEYRSAPublicKeyStr
+ SECKEYRSAPublicKeyStr rsa_pks;
+ rsa_pks.modulus = siMod;
+ rsa_pks.publicExponent = siExp;
+
+ // construct SECKEYPublicKey
+ // this is to be returned
+ pk = (SECKEYPublicKey *) malloc(sizeof(SECKEYPublicKey));
+ pk->keyType = rsaKey;
+ pk->pkcs11Slot = NULL;
+ pk->pkcs11ID = CK_INVALID_HANDLE;
+ pk->u.rsa = rsa_pks;
+
+ PR_snprintf((char *)configname, 256, "general.verifyProof");
+ int verifyProofEnable = RA::GetConfigStore()->GetConfigAsInt(configname, 0x1);
+ if (verifyProofEnable) {
+ rs = verifyProof(pk, &siProof, pkeyb_len, pkeyb, challenge);
+ if (rs.status == PR_FAILURE) {
+ RA::Error("CertEnroll::ParsePublicKeyBlob",
+ "verify proof failed");
+ free(pk);
+ pk = NULL;
+ }
+ }
+
+ return pk;
+}
+
+
+/**
+ * verify the proof.
+ * @param pk the public key from the input blob
+ * @param siProof the proof from the input blob
+ * @param pkeyb_len the length of the publickey blob
+ * @param pkeyb the public key blob
+ * @param challenge the challenge generated by RA
+ *
+ * @return
+ * returns success indication in case of success
+ * returns error message number as defined in ReturnStatus in Base.h
+ */
+ReturnStatus CertEnroll::verifyProof(SECKEYPublicKey* pk, SECItem* siProof,
+ unsigned short pkeyb_len, unsigned char* pkeyb,
+ Buffer* challenge) {
+
+ ReturnStatus rs;
+ VFYContext * vc = NULL;
+ rs.statusNum = ::VRFY_SUCCESS;
+ rs.status = PR_SUCCESS;
+
+ // verify proof (signature)
+ RA::Debug(LL_PER_PDU, "CertEnroll::verifyProof",
+ "verify proof begins");
+
+ vc = VFY_CreateContext(pk, siProof, SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE, NULL);
+
+ if (vc == NULL) {
+ RA::Error("CertEnroll::verifyProof",
+ "VFY_CreateContext() failed");
+ rs.status = PR_FAILURE;
+ rs.statusNum = ::VFY_BEGIN_FAILURE;
+ return rs;
+ } else {
+ RA::Debug(LL_PER_PDU, "CertEnroll::verifyProof",
+ "VFY_CreateContext() succeeded");
+ }
+
+ unsigned char proof[1024];
+ int i =0;
+ for (i = 0; i<pkeyb_len; i++) {
+ proof[i] = pkeyb[i];
+ }
+ // RA::DebugBuffer("CertEnroll::VerifyProof","VerifyProof:: challenge =", challenge);
+ unsigned char* chal = (unsigned char *)(BYTE *) (*challenge);
+ unsigned int j = 0;
+ for (j=0; j < challenge->size(); i++, j++) {
+ proof[i] = chal[j];
+ // RA::Debug(LL_PER_PDU, "CertEnroll::VerifyProof","proof[%d]= %x",
+ // i, proof[i]);
+ }
+
+ SECStatus vs = VFY_Begin(vc);
+ if (vs == SECSuccess) {
+ vs = VFY_Update(vc, (unsigned char *)proof , pkeyb_len + challenge->size());
+ if (vs == SECSuccess) {
+ vs = VFY_End(vc);
+ if (vs == SECFailure) {
+ RA::Error("CertEnroll::verifyProof",
+ "VFY_End() failed pkeyb_len=%d challenge_size=%d", pkeyb_len, challenge->size());
+ rs.statusNum = ::VFY_UPDATE_FAILURE;
+ rs.status = PR_FAILURE;
+ }
+ } else {
+ RA::Error("CertEnroll::verifyProof",
+ "VFY_Update() failed");
+ rs.statusNum = ::VFY_UPDATE_FAILURE;
+ rs.status = PR_FAILURE;
+ }
+ } else {
+ RA::Error("CertEnroll::verifyProof",
+ "VFY_Begin() failed");
+
+ rs.statusNum = ::VFY_BEGIN_FAILURE;
+ rs.status = PR_FAILURE;
+ }
+
+ if( vc != NULL ) {
+ VFY_DestroyContext( vc, PR_TRUE );
+ vc = NULL;
+ }
+ RA::Debug(LL_PER_PDU, "CertEnroll::verifyProof",
+ " VFY_End() returned %d",vs);
+
+ return rs;
+
+}
+
+/**
+ * sendReqToCA sends cert enrollment request via HTTPS to the CA
+ * @param pk normalized public key
+ * @param uid uid/screenname
+ * @param cuid cud number of the client token
+ * @param timeout timeout value for connection
+ * @return
+ * PSHttpResponse if success
+ * NULL if failure
+ */
+PSHttpResponse * CertEnroll::sendReqToCA(const char *servlet, const char *parameters, const char *connid)
+{
+ // compose http uri
+
+ RA::Debug(LL_PER_PDU, "CertEnroll::sendReqToCA",
+ "begins");
+
+ HttpConnection *caConn = RA::GetCAConn(connid);
+ if (caConn == NULL) {
+ RA::Debug(LL_PER_PDU, "CertEnroll::sendReqToCA", "Failed to get CA Connection %s", connid);
+ RA::Error(LL_PER_PDU, "CertEnroll::sendReqToCA", "Failed to get CA Connection %s", connid);
+ return NULL;
+ }
+ // PRLock *ca_lock = RA::GetCALock();
+ int ca_curr = RA::GetCurrentIndex(caConn);
+ int maxRetries = caConn->GetNumOfRetries();
+ ConnectionInfo *connInfo = caConn->GetFailoverList();
+ char **hostport = connInfo->GetHostPortList();
+ int currRetries = 0;
+
+ RA::Debug(LL_PER_PDU, "Before calling getResponse, caHostPort is %s", hostport[ca_curr]);
+
+ PSHttpResponse * response = caConn->getResponse(ca_curr, servlet, parameters);
+ while (response == NULL) {
+ RA::Failover(caConn, connInfo->GetHostPortListLen());
+ ca_curr = RA::GetCurrentIndex(caConn);
+
+ if (++currRetries >= maxRetries) {
+ RA::Debug(LL_PER_PDU, "Used up all the retries. Response is NULL","");
+ RA::Error("CertEnroll::sendReqToCA", "Failed connecting to CA after %d retries", currRetries);
+ if (caConn != NULL) {
+ RA::ReturnCAConn(caConn);
+ }
+ return NULL;
+ }
+ response = caConn->getResponse(ca_curr, servlet, parameters);
+ }
+
+ if (caConn != NULL) {
+ RA::ReturnCAConn(caConn);
+ }
+ return response;
+}
+
+/**
+ * parse the http response and retrieve the certificate.
+ * @param resp the response returned from http request
+ * @return
+ * The certificate in Buffer if success
+ * NULL if failure
+ */
+Buffer * CertEnroll::parseResponse(PSHttpResponse * resp)
+{
+ unsigned int i;
+ unsigned char blob[8192]; /* cert returned */
+ int blob_len; /* cert length */
+ char *certB64 = NULL;
+ char *certB64End = NULL;
+ unsigned int certB64Len = 0;
+ Buffer *cert = NULL;
+ char * response = NULL;
+ SECItem * outItemOpt = NULL;
+
+ if (resp == NULL) {
+ RA::Debug(LL_PER_PDU, "CertEnroll::parseResponse",
+ "no response found");
+ return NULL;
+ }
+ response = resp->getContent();
+ if (response == NULL) {
+ RA::Debug(LL_PER_PDU, "CertEnroll::parseResponse",
+ "no content found");
+ return NULL;
+ }
+
+ // process result
+ // first look for errorCode="" to look for success clue
+ // and errorReason="..." to extract error reason
+ char pattern[20] = "errorCode=\"0\"";
+ char * err = strstr((char *)response, (char *)pattern);
+
+ RA::Debug(LL_PER_PDU, "CertEnroll::parseResponse",
+ "begin parsing err: %s", err);
+
+ if (err == NULL) {
+ RA::Error("CertEnroll::parseResponse",
+ "can't find pattern for cert request response");
+ goto endParseResp;
+ }
+
+ // if success, look for "outputList.outputVal=" to extract
+ // the cert
+ certB64 = strstr((char *)response, "outputVal=");
+ certB64 = &certB64[11]; // point pass open "
+
+ certB64End = strstr(certB64, "\";");
+ *certB64End = '\0';
+
+ certB64Len = strlen(certB64);
+ RA::Debug(LL_PER_PDU, "CertEnroll::parseResponse",
+ "certB64 len = %d", certB64Len);
+
+ for (i=0; i<certB64Len-1 ; i++) {
+ if (certB64[i] == '\\') { certB64[i] = ' '; certB64[i+1] = ' '; }
+ }
+
+ // b64 decode and put back in blob
+ RA::Debug(LL_PER_PDU, "CertEnroll::parseResponse",
+ "b64 decode received cert");
+
+ outItemOpt = NSSBase64_DecodeBuffer(NULL, NULL, certB64, certB64Len);
+ if (outItemOpt == NULL) {
+ RA::Error("CertEnroll::parseResponse",
+ "b64 decode failed");
+
+ goto endParseResp;
+ }
+ RA::Debug(LL_PER_PDU, "CertEnroll::parseResponse",
+ "b64 decode len =%d",outItemOpt->len);
+
+ memcpy((char*)blob, (const char*)(outItemOpt->data), outItemOpt->len);
+ blob_len = outItemOpt->len;
+
+ cert = new Buffer((BYTE *) blob, blob_len);
+ if( outItemOpt != NULL ) {
+ SECITEM_FreeItem( outItemOpt, PR_TRUE );
+ outItemOpt = NULL;
+ }
+
+ RA::Debug(LL_PER_PDU, "CertEnroll::parseResponse",
+ "finished");
+
+ endParseResp:
+ resp->freeContent();
+ return cert;
+}
+
diff --git a/base/tps/src/cms/ConnectionInfo.cpp b/base/tps/src/cms/ConnectionInfo.cpp
new file mode 100644
index 000000000..3ab503c5d
--- /dev/null
+++ b/base/tps/src/cms/ConnectionInfo.cpp
@@ -0,0 +1,78 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "plstr.h"
+#include "cms/ConnectionInfo.h"
+#include "engine/RA.h"
+#include "httpClient/httpc/engine.h"
+#include "main/Util.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a base processor.
+ */
+TPS_PUBLIC ConnectionInfo::ConnectionInfo ()
+{
+ for( int i = 0; i < HOST_PORT_MEMBERS; i++ ) {
+ m_hostPortList[i] = NULL;
+ }
+}
+
+/**
+ * Destructs processor.
+ */
+TPS_PUBLIC ConnectionInfo::~ConnectionInfo()
+{
+ for (int i=0; i<m_len; i++) {
+ if( m_hostPortList[i] != NULL ) {
+ PL_strfree( m_hostPortList[i] );
+ m_hostPortList[i] = NULL;
+ }
+ }
+}
+
+TPS_PUBLIC void ConnectionInfo::BuildFailoverList(const char *str) {
+ char *lasts = NULL;
+ char *tok = PL_strtok_r((char *)str, " ", &lasts);
+ m_len = 0;
+ while (tok != NULL) {
+ m_hostPortList[m_len] = PL_strdup(tok);
+ tok = PL_strtok_r(NULL, " ", &lasts);
+ m_len++;
+ }
+}
+
+TPS_PUBLIC int ConnectionInfo::GetHostPortListLen() {
+ return m_len;
+}
+
+TPS_PUBLIC char **ConnectionInfo::GetHostPortList() {
+ return m_hostPortList;
+}
+
diff --git a/base/tps/src/cms/HttpConnection.cpp b/base/tps/src/cms/HttpConnection.cpp
new file mode 100644
index 000000000..89f773557
--- /dev/null
+++ b/base/tps/src/cms/HttpConnection.cpp
@@ -0,0 +1,245 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "cms/HttpConnection.h"
+#include "main/Memory.h"
+#include "main/NameValueSet.h"
+#include "engine/RA.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a base class for HttpConnection
+ */
+TPS_PUBLIC HttpConnection::HttpConnection(const char *id, ConnectionInfo *cinfo, int retries, int timeout,
+ bool isSSL, const char *nickname, bool keepAlive, NameValueSet *headers)
+{
+ m_failoverList = cinfo;
+ m_retries = retries;
+ m_timeout = timeout;
+ m_Id = PL_strdup(id);
+ m_isSSL = isSSL;
+ m_clientnickname = PL_strdup(nickname);
+ m_keepAlive = keepAlive;
+ m_headers = headers;
+ m_curr = 0;
+ m_lock = PR_NewLock();
+}
+
+/**
+ * Destructs processor.
+ */
+TPS_PUBLIC HttpConnection::~HttpConnection ()
+{
+ if( m_clientnickname != NULL ) {
+ PL_strfree( m_clientnickname );
+ m_clientnickname = NULL;
+ }
+ if( m_Id != NULL ) {
+ PL_strfree( m_Id );
+ m_Id = NULL;
+ }
+ if( m_failoverList != NULL ) {
+ delete m_failoverList;
+ m_failoverList = NULL;
+ }
+ if( m_headers != NULL ) {
+ delete m_headers;
+ m_headers = NULL;
+ }
+ if( m_lock != NULL ) {
+ PR_DestroyLock( m_lock );
+ m_lock = NULL;
+ }
+}
+
+TPS_PUBLIC int HttpConnection::GetNumOfRetries() {
+ return m_retries;
+}
+
+int HttpConnection::GetTimeout() {
+ return m_timeout;
+}
+
+TPS_PUBLIC ConnectionInfo *HttpConnection::GetFailoverList() {
+ return m_failoverList;
+}
+
+TPS_PUBLIC char *HttpConnection::GetId() {
+ return m_Id;
+}
+
+TPS_PUBLIC bool HttpConnection::IsSSL() {
+ return m_isSSL;
+}
+
+TPS_PUBLIC char * HttpConnection::GetClientNickname() {
+ return m_clientnickname;
+}
+
+TPS_PUBLIC bool HttpConnection::IsKeepAlive() {
+ return m_keepAlive;
+}
+
+TPS_PUBLIC PSHttpResponse *HttpConnection::getResponse(int index, const char *servlet, const char *body) {
+ char *host_port;
+ char uri[800];
+ char *nickname;
+ const char *httpprotocol;
+
+ ConnectionInfo *failoverList = GetFailoverList();
+ int len = failoverList->ConnectionInfo::GetHostPortListLen();
+ if (index >= len) {
+ index = len - 1; // use the last one
+ }
+ host_port= (failoverList->GetHostPortList())[index];
+
+ if (IsSSL()) {
+ httpprotocol = "https";
+ } else {
+ httpprotocol = "http";
+ }
+
+ PR_snprintf((char *)uri, 800,
+ "%s://%s/%s",
+ httpprotocol, host_port, servlet);
+
+ RA::Debug("HttpConnection::getResponse", "Send request to host %s servlet %s", host_port, servlet);
+
+ RA::Debug(LL_PER_PDU, "HttpConnection::getResponse", "uri=%s", uri);
+ RA::Debug(LL_PER_PDU, "HttpConnection::getResponse", "host_port=%s", host_port);
+
+ char *pPort = NULL;
+ char *pPortActual = NULL;
+
+
+ char hostName[512];
+
+ /*
+ * Isolate the host name, account for IPV6 numeric addresses.
+ *
+ */
+
+ if(host_port)
+ strncpy(hostName,host_port,512);
+
+ pPort = hostName;
+ while(1) {
+ pPort = strchr(pPort, ':');
+ if (pPort) {
+ pPortActual = pPort;
+ pPort++;
+ } else
+ break;
+ }
+
+ if(pPortActual)
+ *pPortActual = '\0';
+
+
+ /*
+ * Rifle through the values for the host
+ */
+
+ PRAddrInfo *ai;
+ void *iter;
+ PRNetAddr addr;
+ int family = PR_AF_INET;
+
+ ai = PR_GetAddrInfoByName(hostName, PR_AF_UNSPEC, PR_AI_ADDRCONFIG);
+ if (ai) {
+ printf("%s\n", PR_GetCanonNameFromAddrInfo(ai));
+ iter = NULL;
+ while ((iter = PR_EnumerateAddrInfo(iter, ai, 0, &addr)) != NULL) {
+ char buf[512];
+ PR_NetAddrToString(&addr, buf, sizeof buf);
+ RA::Debug( LL_PER_PDU,
+ "HttpConnection::getResponse: ",
+ "Sending addr -- Msg='%s'\n",
+ buf );
+ family = PR_NetAddrFamily(&addr);
+ RA::Debug( LL_PER_PDU,
+ "HttpConnection::getResponse: ",
+ "Sending family -- Msg='%d'\n",
+ family );
+ break;
+ }
+ PR_FreeAddrInfo(ai);
+
+ }
+
+ PSHttpServer httpserver(host_port, family);
+ nickname = GetClientNickname();
+ if (IsSSL())
+ httpserver.setSSL(PR_TRUE);
+ else
+ httpserver.setSSL(PR_FALSE);
+
+ PSHttpRequest httprequest(&httpserver, uri, HTTP11, 0);
+ if (IsSSL()) {
+ httprequest.setSSL(PR_TRUE);
+ if (nickname != NULL) {
+ httprequest.setCertNickName(nickname);
+ } else {
+ return NULL;
+ }
+ } else
+ httprequest.setSSL(PR_FALSE);
+
+ httprequest.setMethod("POST");
+
+ if (body != NULL) {
+ httprequest.setBody( strlen(body), body);
+ }
+
+ httprequest.addHeader( "Content-Type", "application/x-www-form-urlencoded" );
+ if (m_headers != NULL) {
+ for (int i=0; i<m_headers->Size(); i++) {
+ char *name = m_headers->GetNameAt(i);
+ httprequest.addHeader(name, m_headers->GetValue(name));
+ }
+ }
+
+ if (IsKeepAlive())
+ httprequest.addHeader( "Connection", "keep-alive" );
+
+ HttpEngine httpEngine;
+ return httpEngine.makeRequest(httprequest, httpserver, (PRIntervalTime)GetTimeout(),
+ PR_FALSE /*expectChunked*/);
+}
+
+TPS_PUBLIC PRLock * HttpConnection::GetLock() {
+ return m_lock;
+}
+
+TPS_PUBLIC int HttpConnection::GetCurrentIndex() {
+ return m_curr;
+}
+
+TPS_PUBLIC void HttpConnection::SetCurrentIndex(int index) {
+ m_curr = index;
+}
diff --git a/base/tps/src/engine/RA.cpp b/base/tps/src/engine/RA.cpp
new file mode 100644
index 000000000..862b9e105
--- /dev/null
+++ b/base/tps/src/engine/RA.cpp
@@ -0,0 +1,3624 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include <stdio.h>
+//#include <wchar.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "httpd/httpd.h"
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+#include "prprf.h"
+#include "plhash.h"
+#include "pk11func.h"
+#include "cert.h"
+#include "certt.h"
+#include "secerr.h"
+#include "tus/tus_db.h"
+#include "secder.h"
+#include "nss.h"
+#include "nssb64.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "main/Memory.h"
+#include "main/ConfigStore.h"
+#include "main/RA_Context.h"
+#include "channel/Secure_Channel.h"
+#include "engine/RA.h"
+#include "main/Util.h"
+#include "cms/HttpConnection.h"
+#include "main/RA_pblock.h"
+#include "main/LogFile.h"
+#include "main/RollingLogFile.h"
+#include "selftests/SelfTest.h"
+
+typedef struct
+{
+ enum
+ {
+ PW_NONE = 0,
+ PW_FROMFILE = 1,
+ PW_PLAINTEXT = 2,
+ PW_EXTERNAL = 3
+ } source;
+ char *data;
+} secuPWData;
+
+
+static ConfigStore *m_cfg = NULL;
+static LogFile* m_debug_log = (LogFile *)NULL;
+static LogFile* m_error_log = (LogFile *)NULL;
+static LogFile* m_audit_log = (LogFile *)NULL;
+static LogFile* m_selftest_log = (LogFile *)NULL;
+
+static int tokendbInitialized = 0;
+static int tpsConfigured = 0;
+
+RA_Context *RA::m_ctx = NULL;
+bool RA::m_pod_enable=false;
+int RA::m_pod_curr = 0;
+PRLock *RA::m_pod_lock = NULL;
+int RA::m_auth_curr;
+PRLock *RA::m_verify_lock = NULL;
+PRLock *RA::m_auth_lock = NULL;
+PRLock *RA::m_debug_log_lock = NULL;
+PRLock *RA::m_error_log_lock = NULL;
+PRLock *RA::m_selftest_log_lock = NULL;
+PRLock *RA::m_config_lock = NULL;
+PRMonitor *RA::m_audit_log_monitor = NULL;
+bool RA::m_audit_enabled = false;
+bool RA::m_audit_signed = false;
+SECKEYPrivateKey *RA::m_audit_signing_key = NULL;
+NSSUTF8 *RA::m_last_audit_signature = NULL;
+SECOidTag RA::m_audit_signAlgTag;
+SecurityLevel RA::m_global_security_level;
+char *RA::m_signedAuditSelectedEvents = NULL;
+char *RA::m_signedAuditSelectableEvents = NULL;
+char *RA::m_signedAuditNonSelectableEvents = NULL;
+
+char *RA::m_audit_log_buffer = NULL;
+PRThread *RA::m_flush_thread = (PRThread *) NULL;
+size_t RA::m_bytes_unflushed =0;
+size_t RA::m_buffer_size = 512;
+int RA::m_flush_interval = 5;
+
+int RA::m_audit_log_level = (int) LL_PER_SERVER;
+int RA::m_debug_log_level = (int) LL_PER_SERVER;
+int RA::m_error_log_level = (int) LL_PER_SERVER;
+int RA::m_selftest_log_level = (int) LL_PER_SERVER;
+int RA::m_caConns_len = 0;
+int RA::m_tksConns_len = 0;
+int RA::m_drmConns_len = 0;
+int RA::m_auth_len = 0;
+
+#define MAX_BODY_LEN 4096
+
+#define MAX_CA_CONNECTIONS 20
+#define MAX_TKS_CONNECTIONS 20
+#define MAX_DRM_CONNECTIONS 20
+#define MAX_AUTH_LIST_MEMBERS 20
+HttpConnection* RA::m_caConnection[MAX_CA_CONNECTIONS];
+HttpConnection* RA::m_tksConnection[MAX_TKS_CONNECTIONS];
+AuthenticationEntry* RA::m_auth_list[MAX_AUTH_LIST_MEMBERS];
+HttpConnection* RA::m_drmConnection[MAX_DRM_CONNECTIONS];
+int RA::m_num_publishers = 0;
+PublisherEntry *RA::publisher_list = NULL;
+
+/* TKS response parameters */
+const char *RA::TKS_RESPONSE_STATUS = "status";
+const char *RA::TKS_RESPONSE_SessionKey = "sessionKey";
+const char *RA::TKS_RESPONSE_EncSessionKey = "encSessionKey";
+const char *RA::TKS_RESPONSE_KEK_DesKey = "kek_wrapped_desKey";
+const char *RA::TKS_RESPONSE_DRM_Trans_DesKey = "drm_trans_wrapped_desKey";
+const char *RA::TKS_RESPONSE_HostCryptogram = "hostCryptogram";
+
+const char *RA::CFG_DEBUG_ENABLE = "logging.debug.enable";
+const char *RA::CFG_DEBUG_FILENAME = "logging.debug.filename";
+const char *RA::CFG_DEBUG_LEVEL = "logging.debug.level";
+const char *RA::CFG_AUDIT_ENABLE = "logging.audit.enable";
+const char *RA::CFG_AUDIT_FILENAME = "logging.audit.filename";
+const char *RA::CFG_SIGNED_AUDIT_FILENAME = "logging.audit.signedAuditFilename";
+const char *RA::CFG_AUDIT_LEVEL = "logging.audit.level";
+const char *RA::CFG_AUDIT_SIGNED = "logging.audit.logSigning";
+const char *RA::CFG_AUDIT_SIGNING_CERT_NICK = "logging.audit.signedAuditCertNickname";
+const char *RA::CFG_ERROR_ENABLE = "logging.error.enable";
+const char *RA::CFG_ERROR_FILENAME = "logging.error.filename";
+const char *RA::CFG_ERROR_LEVEL = "logging.error.level";
+const char *RA::CFG_SELFTEST_ENABLE = "selftests.container.logger.enable";
+const char *RA::CFG_SELFTEST_FILENAME = "selftests.container.logger.fileName";
+const char *RA::CFG_SELFTEST_LEVEL = "selftests.container.logger.level";
+const char *RA::CFG_CHANNEL_SEC_LEVEL = "channel.securityLevel";
+const char *RA::CFG_CHANNEL_ENCRYPTION = "channel.encryption";
+const char *RA::CFG_APPLET_CARDMGR_INSTANCE_AID = "applet.aid.cardmgr_instance";
+const char *RA::CFG_APPLET_NETKEY_INSTANCE_AID = "applet.aid.netkey_instance";
+const char *RA::CFG_APPLET_NETKEY_FILE_AID = "applet.aid.netkey_file";
+const char *RA::CFG_APPLET_NETKEY_OLD_INSTANCE_AID = "applet.aid.netkey_old_instance";
+const char *RA::CFG_APPLET_NETKEY_OLD_FILE_AID = "applet.aid.netkey_old_file";
+const char *RA::CFG_APPLET_SO_PIN = "applet.so_pin";
+const char *RA::CFG_APPLET_DELETE_NETKEY_OLD = "applet.delete_old";
+const char *RA::CFG_AUDIT_SELECTED_EVENTS="logging.audit.selected.events";
+const char *RA::CFG_AUDIT_NONSELECTABLE_EVENTS="logging.audit.nonselectable.events";
+const char *RA::CFG_AUDIT_SELECTABLE_EVENTS="logging.audit.selectable.events";
+const char *RA::CFG_AUDIT_BUFFER_SIZE = "logging.audit.buffer.size";
+const char *RA::CFG_AUDIT_FLUSH_INTERVAL = "logging.audit.flush.interval";
+const char *RA::CFG_AUDIT_FILE_TYPE = "logging.audit.file.type";
+const char *RA::CFG_DEBUG_FILE_TYPE = "logging.debug.file.type";
+const char *RA::CFG_ERROR_FILE_TYPE = "logging.error.file.type";
+const char *RA::CFG_SELFTEST_FILE_TYPE = "selftests.container.logger.file.type";
+const char *RA::CFG_AUDIT_PREFIX = "logging.audit";
+const char *RA::CFG_ERROR_PREFIX = "logging.error";
+const char *RA::CFG_DEBUG_PREFIX = "logging.debug";
+const char *RA::CFG_SELFTEST_PREFIX = "selftests.container.logger";
+
+const char *RA::CFG_AUTHS_ENABLE="auth.enable";
+
+/* default values */
+const char *RA::CFG_DEF_CARDMGR_INSTANCE_AID = "A0000000030000";
+const char *RA::CFG_DEF_NETKEY_INSTANCE_AID = "627601FF000000";
+const char *RA::CFG_DEF_NETKEY_FILE_AID = "627601FF0000";
+const char *RA::CFG_DEF_NETKEY_OLD_INSTANCE_AID = "A00000000101";
+const char *RA::CFG_DEF_NETKEY_OLD_FILE_AID = "A000000001";
+const char *RA::CFG_DEF_APPLET_SO_PIN = "000000000000";
+
+typedef IPublisher* (*makepublisher)();
+typedef Authentication* (*makeauthentication)();
+
+extern void BuildHostPortLists(char *host, char *port, char **hostList,
+ char **portList, int len);
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a Registration Authority object.
+ */
+RA::RA ()
+{
+}
+
+/**
+ * Destructs a Registration Authority object.
+ */
+RA::~RA ()
+{
+ do_free(m_signedAuditSelectedEvents);
+ do_free(m_signedAuditSelectableEvents);
+ do_free(m_signedAuditNonSelectableEvents);
+
+ if (m_cfg != NULL) {
+ delete m_cfg;
+ m_cfg = NULL;
+ }
+}
+
+TPS_PUBLIC ConfigStore *RA::GetConfigStore()
+{
+ return m_cfg;
+}
+
+PRLock *RA::GetVerifyLock()
+{
+ return m_verify_lock;
+}
+
+PRLock *RA::GetConfigLock()
+{
+ return m_config_lock;
+}
+
+void RA::do_free(char *p)
+{
+ if (p != NULL) {
+ PR_Free(p);
+ p = NULL;
+ }
+}
+
+int RA::InitializeSignedAudit()
+{
+ // cfu
+ RA::Debug("RA:: InitializeSignedAudit", "begins pid: %d",getpid());
+ tpsConfigured = m_cfg->GetConfigAsBool("tps.configured", false);
+ // During installation config, don't do this
+ if (IsTpsConfigured() && (m_audit_signed == true) && (m_audit_signing_key == NULL)) {
+ RA::Debug("RA:: InitializeSignedAudit", "signed audit is on... initializing signing key...");
+ // get audit signing cert
+ const char *audit_signing_cert_nick = m_cfg->GetConfigAsString(CFG_AUDIT_SIGNING_CERT_NICK, "auditSigningCert cert-pki-tps");
+ char certNick[256];
+ PR_snprintf((char *)certNick, 256, audit_signing_cert_nick);
+ RA::Debug("RA:: InitializeSignedAudit", "got audit signing cert nickname: %s", certNick);
+
+ CERTCertDBHandle *cert_handle = 0;
+ cert_handle = CERT_GetDefaultCertDB();
+ if (cert_handle == 0) {
+ RA::Debug("RA:: InitializeSignedAudit", "did not get cert_handle");
+ goto loser;
+ } else {
+ RA::Debug("RA:: InitializeSignedAudit", "got cert_handle");
+ }
+ CERTCertificate *cert = NULL;
+ cert = CERT_FindCertByNickname( cert_handle, (char *) certNick );
+ if (cert != NULL) { // already configed
+ RA::Debug("RA:: InitializeSignedAudit", "got audit signing cert");
+ // get private key from cert
+ m_audit_signing_key =
+ PK11_FindKeyByAnyCert(cert, /*wincx*/ NULL);
+ if (m_audit_signing_key == NULL) {
+ RA::Debug("RA:: InitializeSignedAudit", "audit signing key not initialized...");
+ goto loser;
+ } else {
+ RA::Debug("RA:: InitializeSignedAudit", "got audit signing key");
+ }
+ switch(m_audit_signing_key->keyType) {
+ case rsaKey:
+ m_audit_signAlgTag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
+ break;
+ case dsaKey:
+ m_audit_signAlgTag = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST;
+ break;
+ default:
+ RA::Debug("RA:: InitializeSignedAudit", "unknown key type for audit signing cert");
+ goto loser;
+ break;
+ } //switch
+ RA::Debug("RA:: InitializeSignedAudit", "audit signing initialized");
+// m_cfg->Add("tps.signedAudit.initialized", "true");
+ } else {
+ RA::Debug("RA:: InitializeSignedAudit", "no audit signing cert found... still configuring...");
+ }
+
+ RA::getLastSignature();
+ if (cert != NULL) {
+ CERT_DestroyCertificate(cert);
+ cert = NULL;
+ }
+ } // if (m_audit_signed == true)
+
+ // Initialize audit flush thread
+ if (IsTpsConfigured() && (m_flush_thread == NULL)) {
+ m_flush_thread = PR_CreateThread( PR_USER_THREAD, RunFlushThread, (void *) NULL,
+ PR_PRIORITY_NORMAL, /* Priority */
+ PR_GLOBAL_THREAD, /* Scope */
+ PR_JOINABLE_THREAD, /* State */
+ 0 /* Stack Size */);
+ }
+
+ return 0;
+loser:
+ RA::Debug("RA:: InitializeSignedAudit", "audit function startup failed");
+ return -1;
+//do something
+}
+
+void RA::RunFlushThread(void *arg) {
+ RA::Debug("RA::FlushThread", "Starting audit flush thread");
+ while (m_flush_interval >0) {
+ PR_Sleep(PR_SecondsToInterval(m_flush_interval));
+ if (m_flush_interval ==0)
+ break;
+ if (m_bytes_unflushed > 0)
+ FlushAuditLogBuffer();
+ }
+}
+
+/*
+ * read off the last sig record of the audit file for computing MAC
+ */
+void RA::getLastSignature() {
+ char line[1024];
+ char *sig = NULL;
+
+ RA::Debug("RA:: getLastSignature", "starts");
+ if ((m_audit_log != NULL) && (m_audit_log_monitor != NULL)) {
+ PR_EnterMonitor(m_audit_log_monitor);
+ int removed_return;
+ while (1) {
+ int n = m_audit_log->ReadLine(line, 1024, &removed_return);
+ if (n > 0) {
+ sig = strstr(line, "AUDIT_LOG_SIGNING");
+ if (sig != NULL) {
+ // sig entry found
+ m_last_audit_signature = PL_strdup(line);
+ }
+ } else if (n == 0 && removed_return == 1) {
+ continue; /* skip empty line */
+ } else {
+ break;
+ }
+ }
+ RA::Debug("RA:: getLastSignature", "ends");
+ PR_ExitMonitor(m_audit_log_monitor);
+ }
+
+ if (m_last_audit_signature != NULL) {
+ RA::Debug("RA:: getLastSignature", "got last sig from file: %s",
+ m_last_audit_signature);
+ }
+}
+
+TPS_PUBLIC LogFile* RA::GetLogFile(const char *log_type)
+{
+ if (strcmp(log_type, "RollingLogFile") == 0) {
+ return new RollingLogFile();
+ } else {
+ return new LogFile(); // default
+ }
+}
+
+/**
+ * Initializes RA with the given configuration file.
+ */
+TPS_PUBLIC int RA::Initialize(char *cfg_path, RA_Context *ctx)
+{
+ int rc = -1;
+ int i = 0;
+ int status = 0;
+
+ // Authentication *auth;
+ // int secLevel = 0; // for getting config param
+ bool global_enc = false;
+ SecurityLevel security_level = SECURE_MSG_MAC_ENC;
+
+ m_verify_lock = PR_NewLock();
+ m_debug_log_lock = PR_NewLock();
+ m_error_log_lock = PR_NewLock();
+ m_selftest_log_lock = PR_NewLock();
+ m_config_lock = PR_NewLock();
+ m_cfg = ConfigStore::CreateFromConfigFile(cfg_path);
+ if( m_cfg == NULL ) {
+ rc = -2;
+ goto loser;
+ }
+
+ m_ctx = ctx;
+
+ if (m_cfg->GetConfigAsBool(CFG_DEBUG_ENABLE, 0)) {
+ m_debug_log = GetLogFile(m_cfg->GetConfigAsString(CFG_DEBUG_FILE_TYPE, "LogFile"));
+ status = m_debug_log->startup(ctx, CFG_DEBUG_PREFIX,
+ m_cfg->GetConfigAsString(CFG_DEBUG_FILENAME, "/tmp/debug.log"),
+ false);
+ if (status != PR_SUCCESS)
+ goto loser;
+
+ status = m_debug_log->open();
+ if (status != PR_SUCCESS)
+ goto loser;
+ }
+
+ m_error_log_level = m_cfg->GetConfigAsInt(CFG_ERROR_LEVEL, (int) LL_PER_SERVER);
+ m_debug_log_level = m_cfg->GetConfigAsInt(CFG_DEBUG_LEVEL, (int) LL_PER_SERVER);
+ m_selftest_log_level = m_cfg->GetConfigAsInt(CFG_SELFTEST_LEVEL, (int) LL_PER_SERVER);
+
+ if (m_cfg->GetConfigAsBool(CFG_ERROR_ENABLE, 0)) {
+ m_error_log = GetLogFile(m_cfg->GetConfigAsString(CFG_ERROR_FILE_TYPE, "LogFile"));
+ status = m_error_log->startup(ctx, CFG_ERROR_PREFIX,
+ m_cfg->GetConfigAsString(CFG_ERROR_FILENAME, "/tmp/error.log"),
+ false);
+ if (status != PR_SUCCESS)
+ goto loser;
+
+ status = m_error_log->open();
+ if (status != PR_SUCCESS)
+ goto loser;
+
+ }
+
+ if (m_cfg->GetConfigAsBool(CFG_SELFTEST_ENABLE, 0)) {
+ m_selftest_log = GetLogFile(m_cfg->GetConfigAsString(CFG_SELFTEST_FILE_TYPE, "LogFile"));
+ status = m_selftest_log->startup(ctx, CFG_SELFTEST_PREFIX,
+ m_cfg->GetConfigAsString(CFG_SELFTEST_FILENAME, "/tmp/selftest.log"),
+ false);
+ if (status != PR_SUCCESS)
+ goto loser;
+
+ status = m_selftest_log->open();
+ if (status != PR_SUCCESS)
+ goto loser;
+
+ }
+
+
+ RA::Debug("RA:: Initialize", "CS TPS starting...");
+
+ rc = InitializeTokendb(cfg_path);
+ if( rc != LDAP_SUCCESS ) {
+ RA::Debug("RA:: Initialize", "Token DB initialization failed, server continues");
+ ctx->LogError( "RA::Initialize",
+ __LINE__,
+ "The TPS plugin could NOT load the "
+ "Tokendb library! See specific details in the "
+ "TPS plugin log files." );
+ // Since the server hasn't started yet, there is
+ // no need to perform a call to RA::Shutdown()!
+ //goto loser;
+ } else
+ RA::Debug("RA:: Initialize", "Token DB initialization succeeded");
+
+ //testTokendb();
+
+ m_pod_enable = m_cfg->GetConfigAsBool("failover.pod.enable", false);
+ m_pod_curr = 0;
+ m_auth_curr = 0;
+ m_pod_lock = PR_NewLock();
+ m_auth_lock = PR_NewLock();
+
+
+ // make encryption not default for operations globally
+ // individual security levels can override
+ // secLevel = RA::GetConfigAsInt(RA::CFG_CHANNEL_SEC_LEVEL,
+ // SECURE_MSG_MAC);
+
+ global_enc = m_cfg->GetConfigAsBool(RA::CFG_CHANNEL_ENCRYPTION, true);
+ if (global_enc == true)
+ security_level = SECURE_MSG_MAC_ENC;
+ else
+ security_level = SECURE_MSG_MAC;
+
+ RA::SetGlobalSecurityLevel(security_level);
+
+ // Initialize the CA connection pool to be empty
+ for (i=0; i<MAX_CA_CONNECTIONS; i++) {
+ m_caConnection[i] = NULL;
+ }
+
+ // Initialize the TKS connection pool to be empty
+ for (i=0; i<MAX_TKS_CONNECTIONS; i++) {
+ m_tksConnection[i] = NULL;
+ }
+
+ // Initialize the DRM connection pool to be empty
+ for (i=0; i<MAX_DRM_CONNECTIONS; i++) {
+ m_drmConnection[i] = NULL;
+ }
+
+ // Initialize the authentication list to be empty
+ for (i=0; i<MAX_AUTH_LIST_MEMBERS; i++) {
+ m_auth_list[i] = NULL;
+ }
+
+ // even rc != 0, we still go ahead starting up the server.
+ rc = InitializeAuthentication();
+
+ //Initialize Publisher Library
+ InitializePublishers();
+
+ rc = 1;
+loser:
+
+ // Log the status of this TPS plugin into the web server's log:
+ if( rc != 1 ) {
+ ctx->LogError( "RA::Initialize",
+ __LINE__,
+ "The TPS plugin could NOT be "
+ "loaded (rc = %d)! See specific details in the "
+ "TPS plugin log files.", rc );
+ } else {
+ ctx->LogInfo( "RA::Initialize",
+ __LINE__,
+ "The TPS plugin was "
+ "successfully loaded!" );
+ }
+ return rc;
+}
+
+int RA::InitializeInChild(RA_Context *ctx, int nSignedAuditInitCount) {
+
+ int rc = -1;
+ SECStatus rv;
+ int status = 0;
+ char configname[256];
+
+ RA::Debug( LL_PER_SERVER, "RA::InitializeInChild", "begins: %d pid: %d ppid: %d",
+ nSignedAuditInitCount,getpid(),getppid());
+ if (!NSS_IsInitialized()) {
+
+ RA::Debug( LL_PER_SERVER, "RA::InitializeInChild", "Initializing NSS");
+
+ PR_snprintf((char *)configname, 256, "%s/alias",
+ m_cfg->GetConfigAsString("service.instanceDir", NULL));
+ rv = NSS_Initialize (configname, "", "", SECMOD_DB, NSS_INIT_READONLY);
+ if (rv != SECSuccess) {
+ RA::Error( LL_PER_SERVER, "RA::InitializeInChild",
+ "NSS not initialized successfully");
+ ctx->InitializationError( "RA::InitializeHttpConnections",
+ __LINE__ );
+ goto loser;
+ }
+ } else {
+ RA::Debug( LL_PER_SERVER, "RA::InitializeInChild", "NSS already initialized");
+ }
+ //initialize CA Connections
+ status = InitializeHttpConnections("ca", &m_caConns_len,
+ m_caConnection, ctx);
+ if (status != 0) {
+ RA::Debug( LL_PER_SERVER, "RA::InitializeInChild",
+ "Failed to initialize CA Connection, rc=%i",
+ (int)status);
+ goto loser;
+ }
+ // initialize TKS connections
+ status = InitializeHttpConnections("tks", &m_tksConns_len,
+ m_tksConnection, ctx);
+ if (status != 0) {
+ RA::Debug( LL_PER_SERVER, "RA::InitializeInChild",
+ "Failed to initialize TKS Connection, rc=%i",
+ (int)status);
+ goto loser;
+ }
+ // initialize DRM connections
+ status = InitializeHttpConnections("drm", &m_drmConns_len,
+ m_drmConnection, ctx);
+ if (status != 0) {
+ RA::Debug( LL_PER_SERVER, "RA::InitializeInChild",
+ "Failed to initialize DRM Connection, rc=%i",
+ (int)status);
+ goto loser;
+ }
+
+ // open audit log
+ m_audit_log_monitor = PR_NewMonitor();
+ m_audit_log_level = m_cfg->GetConfigAsInt(CFG_AUDIT_LEVEL, (int) LL_PER_SERVER);
+
+ // get events for audit signing
+ m_signedAuditSelectedEvents = PL_strdup(m_cfg->GetConfigAsString(
+ CFG_AUDIT_SELECTED_EVENTS, ""));
+ m_signedAuditSelectableEvents = PL_strdup(m_cfg->GetConfigAsString(
+ CFG_AUDIT_SELECTABLE_EVENTS, ""));
+ m_signedAuditNonSelectableEvents= PL_strdup(m_cfg->GetConfigAsString(
+ CFG_AUDIT_NONSELECTABLE_EVENTS, ""));
+ m_audit_enabled = m_cfg->GetConfigAsBool(CFG_AUDIT_ENABLE, false);
+ m_buffer_size = m_cfg->GetConfigAsInt(CFG_AUDIT_BUFFER_SIZE, 512);
+ m_flush_interval = m_cfg->GetConfigAsInt(CFG_AUDIT_FLUSH_INTERVAL, 5);
+
+ if (m_audit_enabled && (nSignedAuditInitCount > 1 )) {
+ // is audit logSigning on?
+ m_audit_signed = m_cfg->GetConfigAsBool(CFG_AUDIT_SIGNED, false);
+ RA::Debug("RA:: InitializeInChild", "Audit signing is %s",
+ m_audit_signed? "true":"false");
+
+ m_audit_log = GetLogFile(m_cfg->GetConfigAsString(CFG_AUDIT_FILE_TYPE, "LogFile"));
+ status = m_audit_log->startup(ctx, CFG_AUDIT_PREFIX,
+ m_cfg->GetConfigAsString((m_audit_signed)?
+ CFG_SIGNED_AUDIT_FILENAME:CFG_AUDIT_FILENAME,
+ "/tmp/audit.log"),
+ m_audit_signed);
+ if (status != PR_SUCCESS)
+ goto loser;
+
+ status = m_audit_log->open();
+
+ if (status != PR_SUCCESS)
+ goto loser;
+
+ m_audit_log_buffer = (char *) PR_Malloc(m_buffer_size);
+ if (m_audit_log_buffer == NULL) {
+ RA::Debug("RA:: Initialize", "Unable to allocate memory for audit log buffer ..");
+ goto loser;
+ }
+ PR_snprintf((char *) m_audit_log_buffer, m_buffer_size, "");
+ m_bytes_unflushed = 0;
+ }
+
+ RA::Debug("RA::InitializeInChild", "nSignedAuditInitCount=%i",
+ nSignedAuditInitCount);
+ if (NSS_IsInitialized() && (nSignedAuditInitCount >1)) {
+ status = InitializeSignedAudit();
+ if (status == 0) {
+ RA::Audit(EV_AUDIT_LOG_STARTUP, AUDIT_MSG_FORMAT, "System", "Success",
+ "audit function startup");
+ }
+
+ // As per CC requirements, we want to flush the audit log immediately
+ // to ensure that the audit log is not full
+ FlushAuditLogBuffer();
+
+ rc = SelfTest::runStartUpSelfTests(); // run general self tests
+ if (rc != 0) goto loser;
+ }
+
+ if (m_debug_log != NULL) {
+ m_debug_log->child_init();
+ }
+
+ if (m_error_log != NULL) {
+ m_error_log->child_init();
+ }
+
+ if (m_selftest_log != NULL) {
+ m_selftest_log->child_init();
+ }
+
+ if (m_audit_log != NULL) {
+ m_audit_log->child_init();
+ }
+
+ rc =1;
+loser:
+ // Log the status of this TPS plugin into the web server's log:
+ if( rc != 1 ) {
+ ctx->LogError( "RA::InitializeInChild",
+ __LINE__,
+ "The TPS plugin could NOT be "
+ "initialized (rc = %d)! See specific details in the "
+ "TPS plugin log files.", rc );
+ } else {
+ ctx->LogInfo( "RA::InitializeInChild",
+ __LINE__,
+ "The TPS plugin was "
+ "successfully initialized!" );
+ }
+
+ return rc;
+}
+
+int RA::testTokendb() {
+ // try to see if we can talk to the database
+ int st = 0;
+ LDAPMessage *ldapResult = NULL;
+ const char * filter = "(cn=0000000000080000*)";
+
+ if ((st = find_tus_db_entries(filter, 0, &ldapResult)) != LDAP_SUCCESS) {
+ RA::Debug("RA::testing", "response from token DB failed");
+ } else {
+ RA::Debug("RA::testing", "response from token DB succeeded");
+ }
+ if (ldapResult != NULL) {
+ ldap_msgfree(ldapResult);
+ }
+
+ return st;
+}
+
+/*
+ * returns true if item is a value in the comma separated list
+ * used by audit logging functions and profile selection functions
+ */
+TPS_PUBLIC bool RA::match_comma_list(const char* item, char *list)
+{
+ char *pList = PL_strdup(list);
+ char *sresult = NULL;
+ char *lasts = NULL;
+
+ sresult = PL_strtok_r(pList, ",", &lasts);
+ while (sresult != NULL) {
+ if (PL_strcmp(sresult, item) == 0) {
+ if (pList != NULL) {
+ PR_Free(pList);
+ pList = NULL;
+ }
+ return true;
+ }
+ sresult = PL_strtok_r(NULL, ",", &lasts);
+ }
+ if (pList != NULL) {
+ PR_Free(pList);
+ pList = NULL;
+ }
+ return false;
+}
+
+/*
+ * return comma separated list with all instances of item removed
+ * must be freed by caller
+ */
+TPS_PUBLIC char* RA::remove_from_comma_list(const char*item, char *list)
+{
+ int len = PL_strlen(list);
+ char *pList=PL_strdup(list);
+ char *ret = (char *) PR_Malloc(len);
+ char *sresult = NULL;
+ char *lasts = NULL;
+
+
+ PR_snprintf(ret, len, "");
+ sresult = PL_strtok_r(pList, ",", &lasts);
+ while (sresult != NULL) {
+ if (PL_strcmp(sresult, item) != 0) {
+ PR_snprintf(ret, len, "%s%s%s", ret, (PL_strlen(ret)>0)? "," : "", sresult);
+ }
+ sresult = PL_strtok_r(NULL, ",",&lasts);
+ }
+ if (pList != NULL) {
+ PR_Free(pList);
+ pList = NULL;
+ }
+ return ret;
+}
+
+
+/*
+ * returns true if an audit event is valid, false if not
+ */
+bool RA::IsValidEvent(const char *auditEvent)
+{
+ return match_comma_list(auditEvent, m_signedAuditNonSelectableEvents) ||
+ match_comma_list(auditEvent, m_signedAuditSelectableEvents);
+}
+
+/*
+ * returns true if an audit event is selected, false if not
+ */
+bool RA::IsAuditEventSelected(const char* auditEvent)
+{
+ return match_comma_list(auditEvent, m_signedAuditNonSelectableEvents) ||
+ match_comma_list(auditEvent, m_signedAuditSelectedEvents);
+}
+
+int RA::IsTokendbInitialized()
+{
+ return tokendbInitialized;
+}
+
+int RA::IsTpsConfigured()
+{
+ return tpsConfigured;
+}
+
+TPS_PUBLIC int RA::Child_Shutdown()
+{
+ RA::Debug("RA::Child_Shutdown", "starts");
+ // clean up connections
+ if (m_caConnection != NULL) {
+ for (int i=0; i<m_caConns_len; i++) {
+ if( m_caConnection[i] != NULL ) {
+ delete m_caConnection[i];
+ m_caConnection[i] = NULL;
+ }
+ }
+ }
+
+ if (m_tksConnection != NULL) {
+ for (int i=0; i<m_tksConns_len; i++) {
+ if( m_tksConnection[i] != NULL ) {
+ delete m_tksConnection[i];
+ m_tksConnection[i] = NULL;
+ }
+ }
+ }
+ if (m_drmConnection != NULL) {
+ for (int i=0; i<m_drmConns_len; i++) {
+ if( m_drmConnection[i] != NULL ) {
+ delete m_drmConnection[i];
+ m_drmConnection[i] = NULL;
+ }
+ }
+ }
+
+ /* log audit log shutdown */
+ PR_EnterMonitor(m_audit_log_monitor);
+ if( (m_audit_log != NULL) && (m_audit_log->isOpen())) {
+ if (m_audit_log_buffer != NULL) {
+ m_flush_interval = 0; // terminate flush thread
+ PR_Interrupt(m_flush_thread);
+ if (m_flush_thread != NULL) {
+ PR_JoinThread(m_flush_thread);
+ }
+ }
+ if ((m_audit_signed) && (m_audit_signing_key != NULL)) {
+ RA::Audit(EV_AUDIT_LOG_SHUTDOWN, AUDIT_MSG_FORMAT, "System", "Success",
+ "audit function shutdown");
+ }
+
+ if (m_bytes_unflushed > 0) {
+ FlushAuditLogBuffer();
+ }
+ }
+
+ if (m_audit_log != NULL) {
+ m_audit_log->shutdown();
+ delete m_audit_log;
+ m_audit_log = NULL;
+ }
+
+ if (m_audit_log_buffer) {
+ PR_Free(m_audit_log_buffer);
+ m_audit_log_buffer = NULL;
+ }
+
+ PR_ExitMonitor(m_audit_log_monitor);
+
+ if( m_audit_log_monitor != NULL ) {
+ PR_DestroyMonitor( m_audit_log_monitor );
+ m_audit_log_monitor = NULL;
+ }
+
+ return 1;
+}
+
+
+/**
+ * Shutdown RA.
+ */
+TPS_PUBLIC int RA::Shutdown()
+{
+ RA::Debug("RA::Shutdown", "starts");
+
+ tus_db_end();
+ tus_db_cleanup();
+
+ if( m_pod_lock != NULL ) {
+ PR_DestroyLock( m_pod_lock );
+ m_pod_lock = NULL;
+ }
+
+ if( m_auth_lock != NULL ) {
+ PR_DestroyLock( m_auth_lock );
+ m_auth_lock = NULL;
+ }
+
+ /* close debug file if opened */
+ if ( m_debug_log != NULL ) {
+ m_debug_log->shutdown();
+ delete m_debug_log;
+ m_debug_log = NULL;
+ }
+
+ /* close error file if opened */
+ if( m_error_log != NULL ) {
+ m_error_log->shutdown();
+ delete m_error_log;
+ m_error_log = NULL;
+ }
+
+ /* close self test file if opened */
+ if( m_selftest_log != NULL ) {
+ m_selftest_log->shutdown();
+ delete m_selftest_log;
+ m_selftest_log = NULL;
+ }
+
+ if( m_verify_lock != NULL ) {
+ PR_DestroyLock( m_verify_lock );
+ m_verify_lock = NULL;
+ }
+
+ if( m_debug_log_lock != NULL ) {
+ PR_DestroyLock( m_debug_log_lock );
+ m_debug_log_lock = NULL;
+ }
+
+ if( m_error_log_lock != NULL ) {
+ PR_DestroyLock( m_error_log_lock );
+ m_error_log_lock = NULL;
+ }
+
+ if( m_selftest_log_lock != NULL ) {
+ PR_DestroyLock( m_selftest_log_lock );
+ m_selftest_log_lock = NULL;
+ }
+
+ if( m_config_lock != NULL ) {
+ PR_DestroyLock( m_config_lock );
+ m_config_lock = NULL;
+ }
+
+ if (m_auth_list != NULL) {
+ for (int i=0; i<m_auth_len; i++) {
+ if( m_auth_list[i] != NULL ) {
+ delete m_auth_list[i];
+ m_auth_list[i] = NULL;
+ }
+ }
+ }
+
+ /* destroy configuration hashtable */
+ if( m_cfg != NULL ) {
+ delete m_cfg;
+ m_cfg = NULL;
+ }
+
+ CleanupPublishers();
+
+ return 1;
+}
+
+HttpConnection *RA::GetTKSConn(const char *id) {
+ HttpConnection *tksconn = NULL;
+ for (int i=0; i<m_tksConns_len; i++) {
+ if (strcmp(m_tksConnection[i]->GetId(), id) == 0) {
+ tksconn = m_tksConnection[i];
+ break;
+ }
+ }
+ return tksconn;
+}
+
+HttpConnection *RA::GetDRMConn(const char *id) {
+ HttpConnection *drmconn = NULL;
+ for (int i=0; i<m_drmConns_len; i++) {
+ if (strcmp(m_drmConnection[i]->GetId(), id) == 0) {
+ drmconn = m_drmConnection[i];
+ break;
+ }
+ }
+ return drmconn;
+}
+
+void RA::ReturnTKSConn(HttpConnection *conn) {
+ // do nothing for now
+}
+
+void RA::ReturnDRMConn(HttpConnection *conn) {
+ // do nothing for now
+}
+
+HttpConnection *RA::GetCAConn(const char *id) {
+ HttpConnection *caconn = NULL;
+ if (id == NULL)
+ return NULL;
+ for (int i=0; i<m_caConns_len; i++) {
+ if (strcmp(m_caConnection[i]->GetId(), id) == 0) {
+ caconn = m_caConnection[i];
+ break;
+ }
+ }
+ return caconn;
+}
+
+AuthenticationEntry *RA::GetAuth(const char *id) {
+ AuthenticationEntry *authEntry = NULL;
+ for (int i=0; i<m_auth_len; i++) {
+ authEntry = m_auth_list[i];
+ if (strcmp(authEntry->GetId(), id) == 0)
+ return authEntry;
+ }
+ return NULL;
+}
+
+void RA::ReturnCAConn(HttpConnection *conn) {
+ // do nothing for now
+}
+
+TPS_PUBLIC PRLock *RA::GetAuthLock() {
+ return m_auth_lock;
+}
+
+int RA::GetPodIndex() {
+ PR_Lock(m_pod_lock);
+ int index = m_pod_curr;
+ PR_Unlock(m_pod_lock);
+ return index;
+}
+
+void RA::SetPodIndex(int index) {
+ PR_Lock(m_pod_lock);
+ m_pod_curr = index;
+ PR_Unlock(m_pod_lock);
+}
+
+void RA::SetCurrentIndex(HttpConnection *&conn, int index) {
+ PRLock *lock = conn->GetLock();
+ PR_Lock(lock);
+ conn->SetCurrentIndex(index);
+ PR_Unlock(lock);
+}
+
+int RA::GetCurrentIndex(HttpConnection *conn) {
+ PRLock *lock = conn->GetLock();
+ PR_Lock(lock);
+ int index = conn->GetCurrentIndex();
+ PR_Unlock(lock);
+ return index;
+}
+
+TPS_PUBLIC int RA::GetAuthCurrentIndex() {
+ PR_Lock(m_auth_lock);
+ int index = m_auth_curr;
+ PR_Unlock(m_auth_lock);
+ return index;
+}
+
+void RA::SetAuthCurrentIndex(int index) {
+ PR_Lock(m_auth_lock);
+ m_auth_curr = index;
+ PR_Unlock(m_auth_lock);
+}
+
+TPS_PUBLIC void RA::IncrementAuthCurrentIndex(int len) {
+ PR_Lock(m_auth_lock);
+ if ((++m_auth_curr) >= len)
+ m_auth_curr = 0;
+ PR_Unlock(m_auth_lock);
+}
+
+void RA::SetGlobalSecurityLevel(SecurityLevel sl) {
+ m_global_security_level = sl;
+ RA::Debug(" RA::SetGlobalSecurityLevel", "global security level set to %d", (int) sl);
+
+}
+
+SecurityLevel RA::GetGlobalSecurityLevel() {
+ return m_global_security_level;
+}
+
+
+/*
+ * recovers user encryption key that was previously archived.
+ * It expects DRM to search its archival db by cert.
+ *
+ * input:
+ * @param cuid (cuid of the recovering key's token)
+ * @param userid (uid of the recovering key owner
+ * @param desKey_s (came from TKS - session key wrapped with DRM transport
+ * @param cert (base64 encoded cert of the recovering key)
+ * @param connId (drm connectoin id)
+ *
+ * output:
+ * @param publickey_s public key provided by DRM
+ * @param wrappedPrivateKey_s encrypted private key provided by DRM
+ * @param ivParam_s returned intialization vector
+ */
+void RA::RecoverKey(RA_Session *session, const char* cuid,
+ const char *userid, char* desKey_s,
+ char *b64cert, char **publicKey_s,
+ char **wrappedPrivateKey_s, const char *connId, char **ivParam_s)
+{
+ int status;
+ PSHttpResponse *response = NULL;
+ HttpConnection *drmConn = NULL;
+ char body[MAX_BODY_LEN];
+ char configname[256];
+ char * cert_s;
+ int drm_curr = 0;
+ long s;
+ char * content = NULL;
+ char ** hostport= NULL;
+ const char* servletID = NULL;
+ char *wrappedDESKey_s= NULL;
+ Buffer *decodeKey = NULL;
+ ConnectionInfo *connInfo = NULL;
+ RA_pblock *ra_pb = NULL;
+ int currRetries = 0;
+ char *p = NULL;
+
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey");
+ if (cuid == NULL) {
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, cuid NULL");
+ goto loser;
+ }
+ if (userid == NULL) {
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, userid NULL");
+ goto loser;
+ }
+ if (b64cert == NULL) {
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, b64cert NULL");
+ goto loser;
+ }
+ if (desKey_s == NULL) {
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, desKey_s NULL");
+ goto loser;
+ }
+ if (connId == NULL) {
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, connId NULL");
+ goto loser;
+ }
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, desKey_s=%s, connId=%s",desKey_s, connId);
+
+ cert_s = Util::URLEncode(b64cert);
+ drmConn = RA::GetDRMConn(connId);
+ if (drmConn == NULL) {
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, failed getting drmconn");
+ goto loser;
+ }
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, got drmconn");
+ connInfo = drmConn->GetFailoverList();
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, got drm failover");
+ decodeKey = Util::URLDecode(desKey_s);
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey,url decoded des");
+ wrappedDESKey_s = Util::SpecialURLEncode(*decodeKey);
+
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, wrappedDESKey_s=%s", wrappedDESKey_s);
+
+ PR_snprintf((char *)body, MAX_BODY_LEN,
+ "CUID=%s&userid=%s&drm_trans_desKey=%s&cert=%s",cuid, userid, wrappedDESKey_s, cert_s);
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, body=%s", body);
+ PR_snprintf((char *)configname, 256, "conn.%s.servlet.TokenKeyRecovery", connId);
+ servletID = GetConfigStore()->GetConfigAsString(configname);
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, configname=%s", configname);
+
+ drm_curr = RA::GetCurrentIndex(drmConn);
+ response = drmConn->getResponse(drm_curr, servletID, body);
+ hostport = connInfo->GetHostPortList();
+ if (response == NULL) {
+ RA::Debug(LL_PER_PDU, "The recoverKey response from DRM ",
+ "at %s is NULL.", hostport[drm_curr]);
+
+ //goto loser;
+ } else {
+ RA::Debug(LL_PER_PDU, "The recoverKey response from DRM ",
+ "at %s is not NULL.", hostport[drm_curr]);
+ }
+
+ while (response == NULL) {
+ RA::Failover(drmConn, connInfo->GetHostPortListLen());
+
+ drm_curr = RA::GetCurrentIndex(drmConn);
+ RA::Debug(LL_PER_PDU, "RA is reconnecting to DRM ",
+ "at %s for recoverKey.", hostport[drm_curr]);
+
+ if (++currRetries >= drmConn->GetNumOfRetries()) {
+ RA::Debug("Used up all the retries in recoverKey. Response is NULL","");
+ RA::Error("RA::RecoverKey","Failed connecting to DRM after %d retries", currRetries);
+
+ goto loser;
+ }
+ response = drmConn->getResponse(drm_curr, servletID, body);
+ }
+
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey - got response");
+ // XXXskip handling fallback host for prototype
+
+ content = response->getContent();
+ p = strstr(content, "status=");
+ content = p; //skip the HTTP header
+
+ s = response->getStatus();
+
+ if ((content != NULL) && (s == 200)) {
+ RA::Debug("RA::RecoverKey", "response from DRM status ok");
+
+ Buffer* status_b;
+ char* status_s;
+
+ ra_pb = ( RA_pblock * ) session->create_pblock(content);
+ if (ra_pb == NULL)
+ goto loser;
+
+ status_b = ra_pb->find_val("status");
+ if (status_b == NULL) {
+ status = 4;
+ goto loser;
+ }
+ else {
+ status_s = status_b->string();
+ status = atoi(status_s);
+ if (status_s != NULL) {
+ PR_Free(status_s);
+ }
+ }
+
+
+ char * tmp = NULL;
+ tmp = ra_pb->find_val_s("public_key");
+ if ((tmp == NULL) || (strcmp(tmp,"")==0)) {
+ RA::Error(LL_PER_PDU, "RecoverKey"," got no public key");
+ goto loser;
+ } else {
+ RA::Debug(LL_PER_PDU, "RecoverKey", "got public key =%s", tmp);
+ *publicKey_s = PL_strdup(tmp);
+ }
+
+ tmp = NULL;
+ tmp = ra_pb->find_val_s("wrapped_priv_key");
+ if ((tmp == NULL) || (strcmp(tmp,"")==0)) {
+ RA::Error(LL_PER_PDU, "RecoverKey"," got no wrapped private key");
+ //XXX goto loser;
+ } else {
+ RA::Debug(LL_PER_PDU, "RecoverKey", "got wrappedprivate key =%s", tmp);
+ *wrappedPrivateKey_s = PL_strdup(tmp);
+ }
+
+ tmp = ra_pb->find_val_s("iv_param");
+ if ((tmp == NULL) || (strcmp(tmp,"")==0)) {
+ RA::Error(LL_PER_PDU, "RecoverKey",
+ "did not get iv_param for recovered key in DRM response");
+ } else {
+ RA::Debug(LL_PER_PDU, "ServerSideKeyGen", "got iv_param for recovered key =%s", tmp);
+ *ivParam_s = PL_strdup(tmp);
+ }
+
+ } else {// if content is NULL or status not 200
+ if (content != NULL)
+ RA::Debug("RA::RecoverKey", "response from DRM error status %ld", s);
+ else
+ RA::Debug("RA::RecoverKey", "response from DRM no content");
+ }
+ loser:
+ if (desKey_s != NULL)
+ PR_Free(desKey_s);
+
+ if (decodeKey != NULL)
+ PR_Free(decodeKey);
+
+ if (wrappedDESKey_s != NULL)
+ PR_Free(wrappedDESKey_s);
+
+ if (drmConn != NULL)
+ RA::ReturnDRMConn(drmConn);
+
+ if (response != NULL) {
+ if (content != NULL)
+ response->freeContent();
+ delete response;
+ }
+
+ if (ra_pb != NULL) {
+ delete ra_pb;
+ }
+
+}
+
+
+
+/*
+ * input:
+ * @param desKey_s provided for drm to wrap user private
+ * @param publicKey_s returned for key injection back to token
+ *
+ * Output:
+ * @param publicKey_s public key provided by DRM
+ * @param wrappedPrivateKey_s encrypted private key provided by DRM
+ */
+void RA::ServerSideKeyGen(RA_Session *session, const char* cuid,
+ const char *userid, char* desKey_s,
+ char **publicKey_s,
+ char **wrappedPrivateKey_s,
+ char **ivParam_s, const char *connId,
+ bool archive, int keysize)
+{
+
+ const char *FN="RA::ServerSideKeyGen";
+ int status;
+ PSHttpResponse *response = NULL;
+ HttpConnection *drmConn = NULL;
+ char body[MAX_BODY_LEN];
+ char configname[256];
+
+ long s;
+ char * content = NULL;
+ char ** hostport = NULL;
+ const char* servletID = NULL;
+ char *wrappedDESKey_s = NULL;
+ Buffer *decodeKey = NULL;
+ ConnectionInfo *connInfo = NULL;
+ RA_pblock *ra_pb = NULL;
+ int drm_curr = 0;
+ int currRetries = 0;
+ char *p = NULL;
+
+ if ((cuid == NULL) || (strcmp(cuid,"")==0)) {
+ RA::Debug( LL_PER_CONNECTION, FN,
+ "error: passed invalid cuid");
+ goto loser;
+ }
+ if ((userid == NULL) || (strcmp(userid,"")==0)) {
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "error: passed invalid userid");
+ goto loser;
+ }
+ if ((desKey_s == NULL) || (strcmp(desKey_s,"")==0)) {
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "error: passed invalid desKey_s");
+ goto loser;
+ }
+ if ((connId == NULL) ||(strcmp(connId,"")==0)) {
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "error: passed invalid connId");
+ goto loser;
+ }
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "desKey_s=%s, connId=%s",desKey_s, connId);
+ drmConn = RA::GetDRMConn(connId);
+
+ if (drmConn == NULL) {
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "drmconn is null");
+ goto loser;
+ }
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "found DRM connection info");
+ connInfo = drmConn->GetFailoverList();
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "got DRM failover list");
+
+ decodeKey = Util::URLDecode(desKey_s);
+ if (decodeKey == NULL) {
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "url-decoding of des key-transport-key failed");
+ goto loser;
+ }
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "successfully url-decoded key-transport-key");
+ wrappedDESKey_s = Util::SpecialURLEncode(*decodeKey);
+
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "wrappedDESKey_s=%s", wrappedDESKey_s);
+
+ PR_snprintf((char *)body, MAX_BODY_LEN,
+ "archive=%s&CUID=%s&userid=%s&keysize=%d&drm_trans_desKey=%s",archive?"true":"false",cuid, userid, keysize, wrappedDESKey_s);
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "sending to DRM: query=%s", body);
+
+ PR_snprintf((char *)configname, 256, "conn.%s.servlet.GenerateKeyPair", connId);
+ servletID = GetConfigStore()->GetConfigAsString(configname);
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "finding DRM servlet info, configname=%s", configname);
+
+ drm_curr = RA::GetCurrentIndex(drmConn);
+ response = drmConn->getResponse(drm_curr, servletID, body);
+ hostport = connInfo->GetHostPortList();
+ if (response == NULL) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "failed to get response from DRM at %s",
+ hostport[drm_curr]);
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "failed to get response from DRM at %s",
+ hostport[drm_curr]);
+ } else {
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "response from DRM (%s) is not NULL.",
+ hostport[drm_curr]);
+ }
+
+ while (response == NULL) {
+ RA::Failover(drmConn, connInfo->GetHostPortListLen());
+
+ drm_curr = RA::GetCurrentIndex(drmConn);
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "RA is failing over to DRM at %s", hostport[drm_curr]);
+
+ if (++currRetries >= drmConn->GetNumOfRetries()) {
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "Failed to get response from all DRMs in conn group '%s'"
+ " after %d retries", connId, currRetries);
+ RA::Error(LL_PER_CONNECTION, FN,
+ "Failed to get response from all DRMs in conn group '%s'"
+ " after %d retries", connId, currRetries);
+
+
+ goto loser;
+ }
+ response = drmConn->getResponse(drm_curr, servletID, body);
+ }
+
+ RA::Debug(" RA:: ServerSideKeyGen", "in ServerSideKeyGen - got response");
+ // XXX skip handling fallback host for prototype
+
+ content = response->getContent();
+ p = strstr(content, "status=");
+ content = p; //skip the HTTP header
+ s = response->getStatus();
+
+ if ((content != NULL) && (s == 200)) {
+ RA::Debug("RA::ServerSideKeyGen", "response from DRM status ok");
+
+ Buffer* status_b;
+ char* status_s;
+
+ ra_pb = ( RA_pblock * ) session->create_pblock(content);
+ if (ra_pb == NULL)
+ goto loser;
+
+ status_b = ra_pb->find_val("status");
+ if (status_b == NULL) {
+ status = 4;
+ goto loser;
+ } else {
+ status_s = status_b->string();
+ status = atoi(status_s);
+ if (status_s != NULL) {
+ PR_Free(status_s);
+ }
+ }
+
+ char * tmp = NULL;
+ tmp = ra_pb->find_val_s("public_key");
+ if (tmp == NULL) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "Did not get public key in DRM response");
+ } else {
+ RA::Debug(LL_PER_PDU, "ServerSideKeyGen", "got public key =%s", tmp);
+ *publicKey_s = PL_strdup(tmp);
+ }
+
+ tmp = NULL;
+ tmp = ra_pb->find_val_s("wrapped_priv_key");
+ if ((tmp == NULL) || (strcmp(tmp,"")==0)) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "did not get wrapped private key in DRM response");
+ } else {
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "got wrappedprivate key =%s", tmp);
+ *wrappedPrivateKey_s = PL_strdup(tmp);
+ }
+
+ tmp = ra_pb->find_val_s("iv_param");
+ if ((tmp == NULL) || (strcmp(tmp,"")==0)) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "did not get iv_param for private key in DRM response");
+ } else {
+ RA::Debug(LL_PER_PDU, "ServerSideKeyGen", "got iv_param for private key =%s", tmp);
+ *ivParam_s = PL_strdup(tmp);
+ }
+
+ } else {// if content is NULL or status not 200
+ if (content != NULL)
+ RA::Debug("RA::ServerSideKeyGen", "response from DRM error status %ld", s);
+ else
+ RA::Debug("RA::ServerSideKeyGen", "response from DRM no content");
+ }
+
+ loser:
+ if (desKey_s != NULL)
+ PR_Free(desKey_s);
+
+ if (decodeKey != NULL) {
+ delete decodeKey;
+ }
+
+ if (wrappedDESKey_s != NULL)
+ PR_Free(wrappedDESKey_s);
+
+ if (drmConn != NULL)
+ RA::ReturnDRMConn(drmConn);
+
+ if (response != NULL) {
+ if (content != NULL)
+ response->freeContent();
+ delete response;
+ }
+
+ if (ra_pb != NULL) {
+ delete ra_pb;
+ }
+
+}
+
+
+#define DES2_WORKAROUND
+#define MAX_BODY_LEN 4096
+
+PK11SymKey *RA::ComputeSessionKey(RA_Session *session,
+ Buffer &CUID,
+ Buffer &keyInfo,
+ Buffer &card_challenge,
+ Buffer &host_challenge,
+ Buffer **host_cryptogram,
+ Buffer &card_cryptogram,
+ PK11SymKey **encSymKey,
+ char** drm_desKey_s,
+ char** kek_desKey_s,
+ char** keycheck_s,
+ const char *connId)
+{
+ PK11SymKey *symKey = NULL;
+ PK11SymKey *symKey24 = NULL;
+ PK11SymKey *encSymKey24 = NULL;
+ PK11SymKey *transportKey = NULL;
+ PK11SymKey *encSymKey16 = NULL;
+ char body[MAX_BODY_LEN];
+ char configname[256];
+ char * cardc = NULL;
+ char * hostc = NULL;
+ char * cardCrypto = NULL;
+ char * cuid = NULL;
+ char * keyinfo = NULL;
+ PSHttpResponse *response = NULL;
+ HttpConnection *tksConn = NULL;
+ RA_pblock *ra_pb = NULL;
+ SECItem *SecParam = PK11_ParamFromIV(CKM_DES3_ECB, NULL);
+ char* transportKeyName = NULL;
+
+ RA::Debug(LL_PER_PDU, "Start ComputeSessionKey", "");
+ tksConn = RA::GetTKSConn(connId);
+ if (tksConn == NULL) {
+ RA::Error(LL_PER_PDU, "RA::ComputeSessionKey", "Failed to get TKSConnection %s", connId);
+ return NULL;
+ } else {
+ int currRetries = 0;
+ ConnectionInfo *connInfo = tksConn->GetFailoverList();
+
+ PR_snprintf((char *) configname, 256, "conn.%s.keySet", connId);
+ const char *keySet = RA::GetConfigStore()->GetConfigAsString(configname, "defKeySet");
+ // is serversideKeygen on?
+ PR_snprintf((char *) configname, 256, "conn.%s.serverKeygen", connId);
+ bool serverKeygen = RA::GetConfigStore()->GetConfigAsBool(configname, false);
+ if (serverKeygen)
+ RA::Debug(LL_PER_PDU, "RA::ComputeSessionKey", "serverKeygen for %s is on", connId);
+ else
+ RA::Debug(LL_PER_PDU, "RA::ComputeSessionKey", "serverKeygen for %s is off", connId);
+
+ cardc = Util::SpecialURLEncode(card_challenge);
+ hostc = Util::SpecialURLEncode(host_challenge);
+ cardCrypto = Util::SpecialURLEncode(card_cryptogram);
+ cuid = Util::SpecialURLEncode(CUID);
+ keyinfo = Util::SpecialURLEncode(keyInfo);
+
+ if ((cardc == NULL) || (hostc == NULL) || (cardCrypto == NULL) ||
+ (cuid == NULL) || (keyinfo == NULL))
+ goto loser;
+
+ PR_snprintf((char *)body, MAX_BODY_LEN,
+ "serversideKeygen=%s&CUID=%s&card_challenge=%s&host_challenge=%s&KeyInfo=%s&card_cryptogram=%s&keySet=%s", serverKeygen? "true":"false", cuid,
+ cardc, hostc, keyinfo, cardCrypto, keySet);
+
+ PR_snprintf((char *)configname, 256, "conn.%s.servlet.computeSessionKey", connId);
+ const char *servletID = GetConfigStore()->GetConfigAsString(configname);
+ int tks_curr = RA::GetCurrentIndex(tksConn);
+ response = tksConn->getResponse(tks_curr, servletID, body);
+ char **hostport = connInfo->GetHostPortList();
+ if (response == NULL)
+ RA::Debug(LL_PER_PDU, "The computeSessionKey response from TKS ",
+ "at %s is NULL.", hostport[tks_curr]);
+ else
+ RA::Debug(LL_PER_PDU, "The computeSessionKey response from TKS ",
+ "at %s is not NULL.", hostport[tks_curr]);
+
+ while (response == NULL) {
+ RA::Failover(tksConn, connInfo->GetHostPortListLen());
+
+ tks_curr = RA::GetCurrentIndex(tksConn);
+ RA::Debug(LL_PER_PDU, "RA is reconnecting to TKS ",
+ "at %s for computeSessionKey.", hostport[tks_curr]);
+
+ if (++currRetries >= tksConn->GetNumOfRetries()) {
+ RA::Debug("Used up all the retries in ComputeSessionKey. Response is NULL","");
+ RA::Error("RA::ComputeSessionKey","Failed connecting to TKS after %d retries", currRetries);
+
+ goto loser;
+ }
+ response = tksConn->getResponse(tks_curr, servletID, body);
+ }
+
+ RA::Debug(LL_PER_PDU, "ComputeSessionKey Response is not ","NULL");
+ char * content = response->getContent();
+
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+
+ if (content != NULL) {
+ Buffer *status_b;
+
+ char *status_s, *sessionKey_s, *encSessionKey_s, *hostCryptogram_s;
+ int status;
+
+ /* strip the http header */
+ /* raidzilla 57722: strip the HTTP header and just pass
+ name value pairs into the pblock parsing code.
+ */
+ RA::Debug("RA::Engine", "Pre-processing content '%s", content);
+ char *cx = content;
+ while (cx[0] != '\0' && (!(cx[0] == '\r' && cx[1] == '\n' &&
+ cx[2] == '\r' && cx[3] == '\n')))
+ {
+ cx++;
+ }
+ if (cx[0] != '\0') {
+ cx+=4;
+ }
+ RA::Debug("RA::Engine", "Post-processing content '%s", cx);
+ ra_pb = ( RA_pblock * ) session->create_pblock(cx);
+ if (ra_pb == NULL) {
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "fail no ra_pb");
+ goto loser;
+ }
+
+ status_b = ra_pb->find_val(TKS_RESPONSE_STATUS);
+ if (status_b == NULL) {
+ status = 4;
+ RA::Error(LL_PER_SERVER, "RA:ComputeSessionKey", "Bad TKS Connection. Please make sure TKS is accessible by TPS.");
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "fail no status");
+ goto loser;
+ // return NULL;
+ }
+ else {
+ status_s = status_b->string();
+ status = atoi(status_s);
+ if (status_s != NULL) {
+ PR_Free(status_s);
+ }
+ }
+
+ // Now unwrap the session keys with shared secret transport key
+
+ PR_snprintf((char *)configname, 256, "conn.%s.tksSharedSymKeyName", connId);
+
+ transportKeyName = (char *) m_cfg->GetConfigAsString(configname, TRANSPORT_KEY_NAME);
+
+ RA::Debug(LL_PER_PDU,"RA:ComputeSessionKey","Shared Secret key name: %s.", transportKeyName);
+
+ transportKey = FindSymKeyByName( slot, transportKeyName);
+
+ if ( transportKey == NULL ) {
+ RA::Debug(LL_PER_PDU,"RA::ComputeSessionKey","fail getting transport key");
+ goto loser;
+ }
+
+ sessionKey_s = ra_pb->find_val_s(TKS_RESPONSE_SessionKey);
+ if (sessionKey_s == NULL) {
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "fail no sessionKey_b");
+ goto loser;
+ }
+
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "mac session key=%s", sessionKey_s);
+ Buffer *decodeKey = Util::URLDecode(sessionKey_s);
+
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "decodekey len=%d",decodeKey->size());
+
+ BYTE *keyData = (BYTE *)*decodeKey;
+ SECItem wrappeditem = {siBuffer , keyData, 16 };
+
+ symKey = PK11_UnwrapSymKey(transportKey,
+ CKM_DES3_ECB,SecParam, &wrappeditem,
+ CKM_DES3_ECB,
+ CKA_UNWRAP,
+ 16);
+
+ if ( symKey ) {
+ symKey24 = CreateDesKey24Byte(slot, symKey);
+ }
+
+ if( decodeKey != NULL ) {
+ delete decodeKey;
+ decodeKey = NULL;
+ }
+ if (symKey24 == NULL)
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "MAC Session key is NULL");
+
+
+ encSessionKey_s = ra_pb->find_val_s(TKS_RESPONSE_EncSessionKey);
+ if (encSessionKey_s == NULL) {
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "fail no encSessionKey_b");
+ goto loser;
+ }
+
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "encSessionKey=%s", encSessionKey_s);
+ Buffer *decodeEncKey = Util::URLDecode(encSessionKey_s);
+
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey",
+ "decodeEnckey len=%d",decodeEncKey->size());
+
+ BYTE *EnckeyData = (BYTE *)*decodeEncKey;
+ wrappeditem.data = (unsigned char *) EnckeyData;
+ wrappeditem.len = 16;
+
+ encSymKey16 = PK11_UnwrapSymKey(transportKey,
+ CKM_DES3_ECB,SecParam, &wrappeditem,
+ CKM_DES3_ECB,
+ CKA_UNWRAP,
+ 16);
+
+ if ( encSymKey16 ) {
+ encSymKey24 = CreateDesKey24Byte(slot, encSymKey16);
+ }
+
+ *encSymKey = encSymKey24;
+
+ if( decodeEncKey != NULL ) {
+ delete decodeEncKey;
+ decodeEncKey = NULL;
+ }
+
+ if (encSymKey24 == NULL)
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "encSessionKey is NULL");
+
+ if (serverKeygen) {
+ char * tmp= NULL;
+ tmp = ra_pb->find_val_s(TKS_RESPONSE_DRM_Trans_DesKey);
+ if (tmp == NULL) {
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "drm_desKey not retrieved");
+ RA::Error(LL_PER_PDU, "RA:ComputeSessionKey", "drm_desKey not retrieved");
+ goto loser;
+ } else {
+ *drm_desKey_s = PL_strdup(tmp);
+ }
+ // wrapped des key is to be sent to DRM "as is"
+ // thus should not be touched
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "drm_desKey=%s", *drm_desKey_s );
+
+ tmp = ra_pb->find_val_s(TKS_RESPONSE_KEK_DesKey);
+ if (tmp == NULL) {
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "kek-wrapped desKey not retrieved");
+ RA::Error(LL_PER_PDU, "RA:ComputeSessionKey", "kek-wrapped desKey not retrieved");
+ goto loser;
+ } else {
+ *kek_desKey_s = PL_strdup(tmp);
+ }
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "kek_desKey=%s", *kek_desKey_s );
+
+
+ tmp = ra_pb->find_val_s("keycheck");
+ if (tmp == NULL) {
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "keycheck not retrieved");
+ RA::Error(LL_PER_PDU, "RA:ComputeSessionKey", "keycheck not retrieved");
+ goto loser;
+ } else {
+ *keycheck_s = PL_strdup(tmp);
+ }
+ }// serversideKeygen
+
+ hostCryptogram_s = ra_pb->find_val_s(TKS_RESPONSE_HostCryptogram);
+ if (hostCryptogram_s == NULL)
+ goto loser;
+
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "hostC=%s", hostCryptogram_s);
+ *host_cryptogram = Util::URLDecode(hostCryptogram_s);
+ } // if content != NULL
+
+ } // else tksConn != NULL
+ RA::Debug(LL_PER_PDU, "finish ComputeSessionKey", "");
+
+
+ loser:
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+ if( cardc != NULL ) {
+ PR_Free( cardc );
+ cardc = NULL;
+ }
+ if( hostc != NULL ) {
+ PR_Free( hostc );
+ hostc = NULL;
+ }
+ if( cuid != NULL ) {
+ PR_Free( cuid );
+ cuid = NULL;
+ }
+ if( keyinfo != NULL ) {
+ PR_Free( keyinfo );
+ keyinfo = NULL;
+ }
+ if (cardCrypto != NULL) {
+ PR_Free( cardCrypto );
+ cardCrypto = NULL;
+ }
+
+ if( response != NULL ) {
+ response->freeContent();
+ delete response;
+ response = NULL;
+ }
+
+ if ( SecParam != NULL ) {
+ SECITEM_FreeItem(SecParam, PR_TRUE);
+ SecParam = NULL;
+ }
+
+ if (ra_pb != NULL) {
+ delete ra_pb;
+ }
+
+ if ( symKey != NULL ) {
+ PK11_FreeSymKey( symKey );
+ symKey = NULL;
+ }
+
+ if ( encSymKey16 != NULL ) {
+ PK11_FreeSymKey( encSymKey16 );
+ encSymKey16 = NULL;
+ }
+
+ // in production, if TKS is unreachable, symKey will be NULL,
+ // and this will signal error to the caller.
+ return symKey24;
+}
+
+Buffer *RA::ComputeHostCryptogram(Buffer &card_challenge,
+ Buffer &host_challenge)
+{
+ /* hardcoded enc auth key */
+ BYTE enc_auth_key[16] = {
+ 0x40, 0x41, 0x42, 0x43,
+ 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b,
+ 0x4c, 0x4d, 0x4e, 0x4f
+ };
+ Buffer input = Buffer(16, (BYTE)0);
+ int i;
+ Buffer icv = Buffer(8, (BYTE)0);
+ Buffer *output = new Buffer(8, (BYTE)0);
+ BYTE *cc = (BYTE*)card_challenge;
+ int cc_len = card_challenge.size();
+ BYTE *hc = (BYTE*)host_challenge;
+ int hc_len = host_challenge.size();
+
+ /* copy card and host challenge into input buffer */
+ for (i = 0; i < 8; i++) {
+ ((BYTE*)input)[i] = cc[i];
+ }
+ for (i = 0; i < 8; i++) {
+ ((BYTE*)input)[8+i] = hc[i];
+ }
+
+ PK11SymKey *key = Util::DeriveKey(
+ Buffer(enc_auth_key, 16), Buffer(hc, hc_len),
+ Buffer(cc, cc_len));
+ Util::ComputeMAC(key, input, icv, *output);
+
+ return output;
+}
+
+TPS_PUBLIC void RA::DebugBuffer(const char *func_name, const char *prefix, Buffer *buf)
+{
+ RA::DebugBuffer(LL_PER_CONNECTION, func_name, prefix, buf);
+}
+
+void RA::DebugBuffer(RA_Log_Level level, const char *func_name, const char *prefix, Buffer *buf)
+{
+ int i;
+ PRTime now;
+ const char* time_fmt = "%Y-%m-%d %H:%M:%S";
+ char datetime[1024];
+ PRExplodedTime time;
+ BYTE *data = *buf;
+ int sum = 0;
+ PRThread *ct;
+
+ if ((m_debug_log == NULL) || (!m_debug_log->isOpen()))
+ return;
+ if ((int) level >= m_debug_log_level)
+ return;
+ PR_Lock(m_debug_log_lock);
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+ ct = PR_GetCurrentThread();
+ m_debug_log->printf("[%s] %x %s - ", datetime, ct, func_name);
+ m_debug_log->printf("%s (length='%d')", prefix, buf->size());
+ m_debug_log->printf("\n");
+ m_debug_log->printf("[%s] %x %s - ", datetime, ct, func_name);
+ for (i=0; i<(int)buf->size(); i++) {
+ m_debug_log->printf("%02x ", (unsigned char)data[i]);
+ sum++;
+ if (sum == 10) {
+ m_debug_log->printf("\n");
+ m_debug_log->printf("[%s] %x %s - ", datetime, ct, func_name);
+ sum = 0;
+ }
+ }
+ m_debug_log->write("\n");
+ PR_Unlock(m_debug_log_lock);
+}
+
+TPS_PUBLIC void RA::Debug (const char *func_name, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ RA::DebugThis(LL_PER_SERVER, func_name, fmt, ap);
+ va_end(ap);
+}
+
+TPS_PUBLIC void RA::Debug (RA_Log_Level level, const char *func_name, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ RA::DebugThis(level, func_name, fmt, ap);
+ va_end(ap);
+}
+
+
+
+void RA::DebugThis (RA_Log_Level level, const char *func_name, const char *fmt, va_list ap)
+{
+ PRTime now;
+ const char* time_fmt = "%Y-%m-%d %H:%M:%S";
+ char datetime[1024];
+ PRExplodedTime time;
+ PRThread *ct;
+
+ if ((m_debug_log == NULL) || (!m_debug_log->isOpen()))
+ return;
+ if ((int) level >= m_debug_log_level)
+ return;
+ PR_Lock(m_debug_log_lock);
+ now = PR_Now();
+ ct = PR_GetCurrentThread();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+ m_debug_log->printf("[%s] %x %s - ", datetime, ct, func_name);
+ m_debug_log->vfprintf(fmt, ap);
+ m_debug_log->write("\n");
+ PR_Unlock(m_debug_log_lock);
+}
+
+TPS_PUBLIC void RA::Audit (const char *func_name, const char *fmt, ...)
+{
+ if (!RA::IsAuditEventSelected(func_name))
+ return;
+
+ va_list ap;
+ va_start(ap, fmt);
+ RA::AuditThis (LL_PER_SERVER, func_name, fmt, ap);
+ va_end(ap);
+ va_start(ap, fmt);
+// RA::DebugThis (LL_PER_SERVER, func_name, fmt, ap);
+ va_end(ap);
+}
+
+TPS_PUBLIC void RA::Audit (RA_Log_Level level, const char *func_name, const char *fmt, ...)
+{
+ if (!RA::IsAuditEventSelected(func_name))
+ return;
+
+ va_list ap;
+ va_start(ap, fmt);
+ RA::AuditThis (level, func_name, fmt, ap);
+ va_end(ap);
+ va_start(ap, fmt);
+ RA::DebugThis (level, func_name, fmt, ap);
+ va_end(ap);
+}
+
+void RA::AuditThis (RA_Log_Level level, const char *func_name, const char *fmt, va_list ap)
+{
+ PRTime now;
+ const char* time_fmt = "%Y-%m-%d %H:%M:%S";
+ char datetime[1024];
+ PRExplodedTime time;
+ PRThread *ct;
+ char *message_p1 = NULL;
+ char *message_p2 = NULL;
+ int nbytes;
+ int status;
+
+ if (!m_audit_enabled) return;
+
+ if ((m_audit_log == NULL) || (!m_audit_log->isOpen()) || (m_audit_log_buffer == NULL))
+ return;
+ if ((int) level >= m_audit_log_level)
+ return;
+
+ PR_EnterMonitor(m_audit_log_monitor);
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+ ct = PR_GetCurrentThread();
+
+ message_p1 = PR_smprintf("[%s] %x [AuditEvent=%s]", datetime, ct, func_name);
+ message_p2 = PR_vsmprintf(fmt, ap);
+
+ /* write out the message first */
+ NSSUTF8 *audit_msg = PR_smprintf("%s%s\n", message_p1, message_p2);
+ nbytes = (unsigned) PL_strlen((const char*) audit_msg);
+ if ((m_bytes_unflushed + nbytes) >= m_buffer_size) {
+ FlushAuditLogBuffer();
+ status = m_audit_log->write(audit_msg);
+ if (status != PR_SUCCESS) {
+ m_audit_log->get_context()->LogError( "RA::AuditThis",
+ __LINE__,
+ "AuditThis: Failure to write to the audit log. Shutting down ...");
+ _exit(APEXIT_CHILDFATAL);
+ }
+ m_audit_log->setSigned(false);
+
+ if (m_audit_signed) SignAuditLog(audit_msg);
+ } else {
+ PL_strcat(m_audit_log_buffer, audit_msg);
+ m_bytes_unflushed += nbytes;
+ }
+
+ PR_Free(message_p1);
+ PR_Free(message_p2);
+
+ if (audit_msg)
+ PR_Free(audit_msg);
+
+ PR_ExitMonitor(m_audit_log_monitor);
+
+}
+
+TPS_PUBLIC void RA::FlushAuditLogBuffer()
+{
+ int status;
+
+ if (!m_audit_enabled) return;
+
+ PR_EnterMonitor(m_audit_log_monitor);
+ if ((m_bytes_unflushed > 0) && (m_audit_log_buffer != NULL) && (m_audit_log != NULL)) {
+ status = m_audit_log->write(m_audit_log_buffer);
+ if (status != PR_SUCCESS) {
+ m_audit_log->get_context()->LogError( "RA::FlushAuditLogBuffer",
+ __LINE__,
+ "RA::FlushAuditLogBuffer: Failure to write to the audit log. Shutting down ...");
+ _exit(APEXIT_CHILDFATAL);
+ }
+ m_audit_log->setSigned(false);
+ if (m_audit_signed) {
+ SignAuditLog((NSSUTF8 *) m_audit_log_buffer);
+ }
+ m_bytes_unflushed=0;
+ PR_snprintf((char *) m_audit_log_buffer, m_buffer_size, "");
+ }
+ PR_ExitMonitor(m_audit_log_monitor);
+}
+
+TPS_PUBLIC void RA::SignAuditLog(NSSUTF8 * audit_msg)
+{
+ char *audit_sig_msg = NULL;
+ char sig[4096];
+ int status;
+
+ if (!m_audit_enabled) return;
+
+ PR_EnterMonitor(m_audit_log_monitor);
+ audit_sig_msg = GetAuditSigningMessage(audit_msg);
+
+ if (audit_sig_msg != NULL) {
+ PR_snprintf(sig, 4096, "%s\n", audit_sig_msg);
+ status = m_audit_log->write(sig);
+ if (status != PR_SUCCESS) {
+ m_audit_log->get_context()->LogError( "RA::SignAuditLog",
+ __LINE__,
+ "SignAuditLog: Failure to write to the audit log. Shutting down ..");
+ _exit(APEXIT_CHILDFATAL);
+ }
+ if (m_last_audit_signature != NULL) {
+ PR_Free( m_last_audit_signature );
+ }
+ m_last_audit_signature = PL_strdup(audit_sig_msg);
+ m_audit_log->setSigned(true);
+
+ PR_Free(audit_sig_msg);
+ }
+ PR_ExitMonitor(m_audit_log_monitor);
+}
+
+TPS_PUBLIC void RA::ra_free_values(struct berval **values)
+{
+ free_values(values, 1);
+}
+
+/* sign audit_msg and last signature
+ returns char* - must be freed by caller */
+TPS_PUBLIC char * RA::GetAuditSigningMessage(const NSSUTF8 * audit_msg)
+{
+ PRTime now;
+ const char* time_fmt = "%Y-%m-%d %H:%M:%S";
+ char datetime[1024];
+ PRExplodedTime time;
+ PRThread *ct;
+ SECStatus rv;
+
+ SECItem signedResult;
+ NSSUTF8 *sig_b64 = NULL;
+ NSSUTF8 *out_sig_b64 = NULL;
+ SGNContext *sign_ctxt=NULL;
+ char *audit_sig_msg = NULL;
+ char sig[4096];
+
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+ ct = PR_GetCurrentThread();
+
+ if (m_audit_signed==true) {
+ sign_ctxt = SGN_NewContext(m_audit_signAlgTag, m_audit_signing_key);
+ if( SGN_Begin(sign_ctxt) != SECSuccess ) {
+ RA::Debug("RA:: SignAuditLog", "SGN_Begin failed");
+ goto loser;
+ }
+
+ if (m_last_audit_signature != NULL) {
+ RA::Debug("RA:: SignAuditLog", "m_last_audit_signature == %s",
+ m_last_audit_signature);
+
+ PR_snprintf(sig, 4096, "%s\n", m_last_audit_signature);
+ rv = SGN_Update( (SGNContext*)sign_ctxt,
+ (unsigned char *) sig,
+ (unsigned)PL_strlen((const char*)sig));
+ if (rv != SECSuccess) {
+ RA::Debug("RA:: SignAuditLog", "SGN_Update failed");
+ goto loser;
+ }
+
+ } else {
+ RA::Debug("RA:: SignAuditLog", "m_last_audit_signature == NULL");
+ }
+
+ /* make sign the UTF-8 bytes later */
+
+ if( SGN_Update( (SGNContext*)sign_ctxt,
+ (unsigned char *) audit_msg,
+ (unsigned)PL_strlen((const char*)audit_msg)) != SECSuccess) {
+ RA::Debug("RA:: SignAuditLog", "SGN_Update failed");
+ goto loser;
+ }
+
+ if( SGN_End(sign_ctxt, &signedResult) != SECSuccess) {
+ RA::Debug("RA:: SignAuditLog", "SGN_End failed");
+ goto loser;
+ }
+
+ sig_b64 = NSSBase64_EncodeItem(NULL, NULL, 0, &signedResult);
+ if (sig_b64 == NULL) {
+ RA::Debug("RA:: SignAuditLog", "NSSBase64_EncodeItem failed");
+ goto loser;
+ }
+
+ /* get rid of the carriage return line feed */
+ int sig_len = PL_strlen(sig_b64);
+ out_sig_b64 = (char *) PORT_Alloc (sig_len);
+ if (out_sig_b64 == NULL) {
+ RA::Debug("RA:: SignAuditLog", "PORT_Alloc for out_sig_b64 failed");
+ goto loser;
+ }
+ int i = 0;
+ char *p = sig_b64;
+ for (i = 0; i< sig_len; i++, p++) {
+ if ((*p!=13) && (*p!= 10)) {
+ out_sig_b64[i] = *p;
+ } else {
+ i--;
+ continue;
+ }
+ }
+
+ /*
+ * write out the signature
+ */
+ audit_sig_msg = PR_smprintf(AUDIT_SIG_MSG_FORMAT,
+ datetime, ct, "AUDIT_LOG_SIGNING",
+ "System", "Success", out_sig_b64);
+
+ }
+
+loser:
+ if (m_audit_signed==true) {
+ if (sign_ctxt)
+ SGN_DestroyContext(sign_ctxt, PR_TRUE);
+ if (sig_b64)
+ PR_Free(sig_b64);
+ if (out_sig_b64)
+ PR_Free(out_sig_b64);
+ if (&signedResult)
+ SECITEM_FreeItem(&signedResult, PR_FALSE);
+ }
+
+ return audit_sig_msg;
+}
+
+TPS_PUBLIC void RA::SetFlushInterval(int interval)
+{
+ char interval_str[512];
+ int status;
+ char error_msg[512];
+
+ RA::Debug("RA::SetFlushInterval", "Setting flush interval to %d seconds", interval);
+ m_flush_interval = interval;
+
+ // Interrupt the flush thread to set new interval
+ // Get monitor so as not to interrupt the flush thread during flushing
+
+ PR_EnterMonitor(m_audit_log_monitor);
+ PR_Interrupt(m_flush_thread);
+ PR_ExitMonitor(m_audit_log_monitor);
+
+ PR_snprintf((char *) interval_str, 512, "%d", interval);
+ m_cfg->Add(CFG_AUDIT_FLUSH_INTERVAL, interval_str);
+ status = m_cfg->Commit(false, error_msg, 512);
+ if (status != 0) {
+ RA::Debug("RA:SetFlushInterval", error_msg);
+ }
+}
+
+TPS_PUBLIC void RA::SetBufferSize(int size)
+{
+ char * new_buffer;
+ char size_str[512];
+ int status;
+ char error_msg[512];
+
+ RA::Debug("RA::SetBufferSize", "Setting buffer size to %d bytes", size);
+
+ PR_EnterMonitor(m_audit_log_monitor);
+ FlushAuditLogBuffer();
+ if (m_audit_log_buffer != NULL) {
+ new_buffer = (char *) PR_Realloc(m_audit_log_buffer, size);
+ m_audit_log_buffer = new_buffer;
+ } else {
+ m_audit_log_buffer = (char *) PR_Malloc(size);
+ }
+ m_buffer_size = size;
+ PR_ExitMonitor(m_audit_log_monitor);
+
+ PR_snprintf((char *) size_str, 512, "%d", size);
+ m_cfg->Add(CFG_AUDIT_BUFFER_SIZE, size_str);
+
+ status = m_cfg->Commit(false, error_msg, 512);
+ if (status != 0) {
+ RA::Debug("RA:SetFlushInterval", error_msg);
+ }
+}
+
+
+TPS_PUBLIC void RA::Error (const char *func_name, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ RA::ErrorThis(LL_PER_SERVER, func_name, fmt, ap);
+ va_end(ap);
+ va_start(ap, fmt);
+ RA::DebugThis(LL_PER_SERVER, func_name, fmt, ap);
+ va_end(ap);
+}
+
+TPS_PUBLIC void RA::Error (RA_Log_Level level, const char *func_name, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ RA::ErrorThis(level, func_name, fmt, ap);
+ va_end(ap);
+ va_start(ap, fmt);
+ RA::DebugThis(level, func_name, fmt, ap);
+ va_end(ap);
+}
+
+void RA::ErrorThis (RA_Log_Level level, const char *func_name, const char *fmt, va_list ap)
+{
+ PRTime now;
+ const char* time_fmt = "%Y-%m-%d %H:%M:%S";
+ char datetime[1024];
+ PRExplodedTime time;
+ PRThread *ct;
+
+ if ((m_error_log == NULL) || (!m_error_log->isOpen()))
+ return;
+ if ((int) level >= m_error_log_level)
+ return;
+ PR_Lock(m_error_log_lock);
+ now = PR_Now();
+ ct = PR_GetCurrentThread();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+ m_error_log->printf("[%s] %x %s - ", datetime, ct, func_name);
+ m_error_log->vfprintf(fmt, ap);
+ m_error_log->write("\n");
+ PR_Unlock(m_error_log_lock);
+}
+
+TPS_PUBLIC void RA::SelfTestLog (const char *func_name, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ RA::SelfTestLogThis(LL_PER_SERVER, func_name, fmt, ap);
+ va_end(ap);
+ va_start(ap, fmt);
+ RA::DebugThis(LL_PER_SERVER, func_name, fmt, ap);
+ va_end(ap);
+}
+
+TPS_PUBLIC void RA::SelfTestLog (RA_Log_Level level, const char *func_name, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ RA::SelfTestLogThis(level, func_name, fmt, ap);
+ va_end(ap);
+ va_start(ap, fmt);
+ RA::DebugThis(level, func_name, fmt, ap);
+ va_end(ap);
+}
+
+void RA::SelfTestLogThis (RA_Log_Level level, const char *func_name, const char *fmt, va_list ap)
+{
+ PRTime now;
+ const char* time_fmt = "%Y-%m-%d %H:%M:%S";
+ char datetime[1024];
+ PRExplodedTime time;
+ PRThread *ct;
+
+ if ((m_selftest_log == NULL) || (!m_selftest_log->isOpen()))
+ return;
+ if ((int) level >= m_selftest_log_level)
+ return;
+ PR_Lock(m_selftest_log_lock);
+ now = PR_Now();
+ ct = PR_GetCurrentThread();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+ m_selftest_log->printf("[%s] %x %s - ", datetime, ct, func_name);
+ m_selftest_log->vfprintf(fmt, ap);
+ m_selftest_log->write("\n");
+ PR_Unlock(m_selftest_log_lock);
+}
+
+PublisherEntry *RA::getPublisherById(const char *publisher_id)
+{
+
+ PublisherEntry *cur = RA::publisher_list;
+
+ if(cur == NULL)
+ {
+ return NULL;
+ }
+
+ while(cur != NULL)
+ {
+ if(!strcmp(publisher_id,cur->id))
+ {
+ break;
+ }
+
+ cur = cur->next;
+ }
+
+ return cur;
+
+}
+
+int RA::InitializePublishers()
+
+{
+ RA::m_num_publishers = 0;
+
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers: Attempting to load the configurable list of Publishers.", "");
+
+ const char *pub_prefix = "publisher.instance";
+ const char *pub_suffix = "publisherId";
+
+ const char *publisher_id = NULL;
+ const char *publisher_lib_name = NULL;
+ const char *publisher_lib_factory_name = NULL;
+
+ char config_str[500];
+
+ int i = -1;
+ int res = 0;
+
+ PublisherEntry *new_entry;
+
+ while(1)
+ {
+ i++;
+
+ PR_snprintf((char *)config_str, 256,"%s.%d.%s", pub_prefix,i,pub_suffix);
+ publisher_id = m_cfg->GetConfigAsString(config_str,NULL);
+
+ if(publisher_id != NULL)
+ {
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers:"," Found publisher id %s ", publisher_id);
+ PR_snprintf((char *)config_str, 256, "%s.%d.%s",pub_prefix,i,"libraryName");
+
+ publisher_lib_name = m_cfg->GetConfigAsString(config_str,NULL);
+
+ if(publisher_lib_name != NULL)
+ {
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers:"," Found publisher lib name %s ", publisher_lib_name);
+ PR_snprintf((char *)config_str, 256, "%s.%d.%s",pub_prefix,i,"libraryFactory");
+
+ publisher_lib_factory_name = m_cfg->GetConfigAsString(config_str,NULL);
+
+ if(publisher_lib_factory_name)
+ {
+
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers:"," Found publisher lib factory name %s ", publisher_lib_factory_name);
+
+ PRLibrary *pb = PR_LoadLibrary(publisher_lib_name);
+
+ if(pb)
+ {
+ void *sym = PR_FindSymbol(pb,publisher_lib_factory_name);
+
+ if(sym == NULL)
+ {
+
+ RA::Error(LL_PER_PDU, "RA:InitializePublishers",
+ "Failed to find symbol '%s' publisher %s error code: %d",publisher_lib_factory_name,publisher_lib_name,PR_GetError());
+
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers: Failed to load publish library.", "");
+
+
+ continue;
+ }
+ makepublisher make_pub = (makepublisher ) sym;
+
+ IPublisher *publisher = (* make_pub )();
+
+ if(publisher == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA:InitializePublishers",
+ "Failed to initialize publisher %s error code: %d",publisher_lib_name,PR_GetError());
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers: Failed to allocate Netkey publisher.", "");
+ continue;
+ }
+ if(publisher)
+ {
+ res = publisher->init();
+ }
+
+ if(!res)
+ {
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers: Failed to initialize publisher %s.", publisher_lib_name);
+ continue;
+ }
+
+ new_entry = (PublisherEntry *) malloc(sizeof(PublisherEntry));
+
+ if(new_entry == NULL)
+ {
+
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers: Failed to allocate PublisherEntry structure", "");
+
+ break;
+
+ }
+ new_entry->id = strdup(publisher_id);
+ new_entry->publisher = publisher;
+ new_entry->publisher_lib = pb;
+
+ if(RA::publisher_list == NULL)
+ {
+ RA::publisher_list = new_entry;
+ new_entry->next = NULL;
+
+ }
+
+ else
+ {
+ PublisherEntry *cur = RA::publisher_list;
+
+ while(cur->next != NULL)
+ {
+ cur= cur->next;
+ }
+
+ cur->next = new_entry;
+ new_entry->next = NULL;
+
+ }
+
+ RA::m_num_publishers++;
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers:"," Successfully initialized publisher %s.", publisher_lib_name);
+ }
+ else
+ {
+ RA::Error(LL_PER_PDU, "RA:InitializePublishers",
+ "Failed to open library %s error code: %d",publisher_lib_name,PR_GetError());
+
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers"," Failed to load publish library.", "");
+
+ continue;
+
+ }
+ }
+ else
+ {
+ continue;
+ }
+ }
+ else
+ {
+ continue;
+
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if(RA::m_num_publishers == 0)
+ {
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers:"," Did not load any publisher libraries, possibly not configured for publishing. Server continues normally... ");
+ return 0;
+ }
+ else
+ {
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers:"," Loaded %d Publisher(s).", RA::m_num_publishers);
+
+ return 1;
+ }
+
+}
+
+void RA::CleanupPublishers()
+{
+
+ if(RA::m_num_publishers == 0)
+ return;
+
+ RA::Debug(LL_PER_PDU, "RA::CleanupPublishers:"," Loaded %d publishers.", RA::m_num_publishers);
+
+ PublisherEntry *cur = RA::publisher_list;
+
+ if(cur == NULL)
+ {
+ return ;
+ }
+
+ while(cur != NULL)
+ {
+
+ PublisherEntry *next =cur->next;
+
+ if(cur)
+ {
+
+ RA::Debug(LL_PER_PDU, "RA::CleanupPublishers:"," Cleanup up publisher %s", cur->id);
+ if( cur->id != NULL)
+ {
+ free( cur->id );
+ cur->id = NULL;
+ }
+
+ if( cur->publisher != NULL ) {
+ delete cur->publisher;
+ cur->publisher = NULL;
+ }
+
+ if( cur->publisher_lib != NULL ) {
+ PR_UnloadLibrary( cur->publisher_lib );
+ cur->publisher_lib = NULL;
+ }
+
+ if( cur != NULL ) {
+ free( cur );
+ cur = NULL;
+ }
+
+ cur = next;
+
+ }
+ }
+
+
+}
+
+int RA::InitializeHttpConnections(const char *id, int *len, HttpConnection **conn, RA_Context *ctx) {
+ char configname[256];
+ char connID[100];
+ CERTCertDBHandle *handle = 0;
+ int rc = 0;
+ int i=0;
+
+ *len = 0;
+
+ // Initialize each connection
+ while (1) {
+ i++;
+ PR_snprintf((char *)configname, 256, "conn.%s%d.hostport", id, i);
+ const char *host_port = m_cfg->GetConfigAsString(configname);
+ if (host_port == NULL) {
+ break;
+ }
+ ConnectionInfo *cinfo = new ConnectionInfo();
+ cinfo->BuildFailoverList(host_port);
+ PR_snprintf((char *)configname, 256, "conn.%s%d.retryConnect", id, i);
+ int retries = m_cfg->GetConfigAsInt(configname, 3);
+ PR_snprintf((char *)configname, 256, "conn.%s%d.timeout", id, i);
+ int timeout = m_cfg->GetConfigAsInt(configname, 10);
+ PR_snprintf((char *)connID, 100, "%s%d", id, i);
+ PR_snprintf((char *)configname, 256, "conn.%s%d.clientNickname", id, i);
+ const char *clientnickname = m_cfg->GetConfigAsString(configname);
+
+ handle = CERT_GetDefaultCertDB();
+ if( handle == 0 ) {
+ ctx->InitializationError( "RA::InitializeHttpConnections",
+ __LINE__ );
+ rc = -1;
+ if (cinfo != NULL) {
+ delete cinfo;
+ cinfo = NULL;
+ }
+ goto loser;
+ }
+
+ // (2) Since NSS has been initialized, verify the presence of the
+ // specified certificate:
+ if( ( clientnickname != NULL ) &&
+ ( PL_strcmp( clientnickname, "" ) != 0 ) ) {
+ SelfTest::Initialize(m_cfg);
+
+ rc = SelfTest::runStartUpSelfTests(clientnickname);
+ if (rc != 0) goto loser;
+ } else {
+ RA::Error( LL_PER_SERVER,
+ "RA::InitializeHttpConnections",
+ "An empty or missing %s certificate nickname "
+ "was specified for connection %d!",
+ id,
+ i );
+ rc = -3;
+ if (cinfo != NULL) {
+ delete cinfo;
+ cinfo = NULL;
+ }
+ goto loser;
+ }
+
+ PR_snprintf((char *)configname, 256, "conn.%s%d.SSLOn", id, i);
+ bool isSSL = m_cfg->GetConfigAsBool(configname, true);
+ PR_snprintf((char *)configname, 256, "conn.%s%d.keepAlive", id, i);
+ bool keepAlive = m_cfg->GetConfigAsBool(configname, true);
+ conn[*len] = new HttpConnection(connID, cinfo, retries, timeout, isSSL, clientnickname, keepAlive, NULL);
+ (*len)++;
+ }
+
+loser:
+
+ return rc;
+}
+
+int RA::InitializeTokendb(char *cfg_path)
+{
+ char *error = NULL;
+ int status;
+
+ if (tokendbInitialized)
+ return 0;
+
+ RA::Debug("RA::InitializeTokendb", "config path = %s", cfg_path);
+
+ if (get_tus_db_config(cfg_path) != 1) {
+ RA::Debug("RA::InitializeTokendb", "get_tus_db_config failed");
+ return -1;
+ }
+
+ tokendbInitialized = 1;
+
+ RA::Debug("RA::InitializeTokendb", "Initializing TUS database");
+ if( ( status = tus_db_init( &error ) ) != LDAP_SUCCESS ) {
+ if( error != NULL ) {
+ RA::Debug( "RA::InitializeTokendb",
+ "Token DB initialization failed: '%s'",
+ error );
+ PR_smprintf_free( error );
+ error = NULL;
+ } else {
+ RA::Debug( "RA::InitializeTokendb",
+ "Token DB initialization failed" );
+ }
+ }
+
+ return status;
+}
+
+TPS_PUBLIC void RA::update_signed_audit_selected_events(char *new_selected)
+{
+ char *tmp = NULL;
+ m_cfg->Add(CFG_AUDIT_SELECTED_EVENTS, new_selected);
+
+ tmp = m_signedAuditSelectedEvents;
+ m_signedAuditSelectedEvents = PL_strdup(new_selected);
+ PL_strfree(tmp);
+}
+
+TPS_PUBLIC void RA::update_signed_audit_enable(const char *enable)
+{
+ m_cfg->Add(CFG_AUDIT_ENABLE, enable);
+}
+
+
+TPS_PUBLIC void RA::update_signed_audit_log_signing(const char *enable)
+{
+ m_cfg->Add(CFG_AUDIT_SIGNED, enable);
+}
+
+TPS_PUBLIC int RA::setup_audit_log(bool enable_signing, bool signing_changed)
+{
+ int status =0;
+ PR_EnterMonitor(m_audit_log_monitor);
+
+ // get buffer if required
+ if (m_audit_log_buffer == NULL) {
+ m_audit_log_buffer = (char *) PR_Malloc(m_buffer_size);
+ if (m_audit_log_buffer == NULL) {
+ RA::Debug(LL_PER_PDU, "RA:: setup_audit_log", "Unable to allocate memory for audit log buffer ..");
+ goto loser;
+ }
+ PR_snprintf((char *) m_audit_log_buffer, m_buffer_size, "");
+ m_bytes_unflushed = 0;
+ }
+
+ // close old log file if signing config changed
+ if (signing_changed && m_audit_log !=NULL) {
+ RA::Debug(LL_PER_PDU, "RA::setup_audit_log","Closing old audit log file");
+ FlushAuditLogBuffer();
+ m_audit_log->shutdown();
+ delete m_audit_log;
+ m_audit_log = NULL;
+ }
+
+ // open new log file if required
+ if (m_audit_log == NULL) {
+ RA::Debug(LL_PER_PDU, "RA::setup_audit_log","Opening audit log file");
+ m_audit_log = GetLogFile(m_cfg->GetConfigAsString(CFG_AUDIT_FILE_TYPE, "LogFile"));
+ status = m_audit_log->startup(m_ctx, CFG_AUDIT_PREFIX,
+ m_cfg->GetConfigAsString((enable_signing)?
+ CFG_SIGNED_AUDIT_FILENAME:CFG_AUDIT_FILENAME,
+ "/tmp/audit.log"),
+ enable_signing);
+ if (status != PR_SUCCESS)
+ goto loser;
+
+ status = m_audit_log->open();
+ if (status != PR_SUCCESS)
+ goto loser;
+ }
+
+ // update variables and CS.cfg
+ m_audit_signed = enable_signing;
+ update_signed_audit_log_signing(enable_signing? "true":"false");
+
+ // initialize signing cert and flush thread, if needed
+ status = InitializeSignedAudit();
+ if (status != 0) {
+ RA::Debug(LL_PER_PDU, "RA::setup_audit_log","Failure in InitializeSignedAudit");
+ goto loser;
+ }
+
+ PR_ExitMonitor(m_audit_log_monitor);
+ return 0;
+
+ loser:
+ RA::Debug(LL_PER_PDU, "RA::setup_audit_log","Failure in audit log setup");
+ PR_ExitMonitor(m_audit_log_monitor);
+ return -1;
+}
+
+TPS_PUBLIC void RA::enable_audit_logging(bool enable)
+{
+ m_audit_enabled = enable;
+ update_signed_audit_enable(enable? "true": "false");
+}
+
+
+TPS_PUBLIC int RA::ra_find_tus_certificate_entries_by_order_no_vlv (char *filter,
+ LDAPMessage **result, int order)
+{
+ return find_tus_certificate_entries_by_order_no_vlv(filter, result, order);
+}
+
+TPS_PUBLIC int RA::ra_find_tus_certificate_entries_by_order (char *filter,
+ int max, LDAPMessage **result, int order)
+{
+ return find_tus_certificate_entries_by_order(filter, max, result, order);
+}
+
+TPS_PUBLIC CERTCertificate **RA::ra_get_certificates(LDAPMessage *e) {
+ return get_certificates(e);
+}
+
+TPS_PUBLIC LDAPMessage *RA::ra_get_first_entry(LDAPMessage *e) {
+ return get_first_entry(e);
+}
+
+TPS_PUBLIC LDAPMessage *RA::ra_get_next_entry(LDAPMessage *e) {
+ return get_next_entry(e);
+}
+
+TPS_PUBLIC struct berval **RA::ra_get_attribute_values(LDAPMessage *e, const char *p) {
+ return get_attribute_values(e, p);
+}
+
+TPS_PUBLIC char *RA::ra_get_token_id(LDAPMessage *e) {
+ return get_token_id(e);
+}
+
+TPS_PUBLIC char *RA::ra_get_cert_tokenType(LDAPMessage *entry) {
+ return get_cert_tokenType(entry);
+}
+
+TPS_PUBLIC char *RA::ra_get_token_status(LDAPMessage *entry) {
+ return get_token_status(entry);
+}
+
+TPS_PUBLIC char *RA::ra_get_cert_cn(LDAPMessage *entry) {
+ return get_cert_cn(entry);
+}
+
+TPS_PUBLIC char *RA::ra_get_cert_attr_byname(LDAPMessage *entry, const char *name) {
+ return get_cert_attr_byname(entry, name);
+}
+
+TPS_PUBLIC char *RA::ra_get_cert_status(LDAPMessage *entry) {
+ return get_cert_status(entry);
+}
+
+TPS_PUBLIC char *RA::ra_get_cert_type(LDAPMessage *entry) {
+ return get_cert_type(entry);
+}
+
+TPS_PUBLIC char *RA::ra_get_cert_serial(LDAPMessage *entry) {
+ return get_cert_serial(entry);
+}
+
+TPS_PUBLIC char *RA::ra_get_cert_issuer(LDAPMessage *entry) {
+ return get_cert_issuer(entry);
+}
+
+TPS_PUBLIC int RA::ra_tus_has_active_tokens(char *userid) {
+ return tus_has_active_tokens(userid);
+}
+
+TPS_PUBLIC char *RA::ra_get_token_reason(LDAPMessage *msg) {
+ return get_token_reason(msg);
+}
+
+TPS_PUBLIC int RA::ra_get_number_of_entries(LDAPMessage *ldapResult) {
+ return get_number_of_entries(ldapResult);
+}
+
+TPS_PUBLIC int RA::ra_find_tus_token_entries_no_vlv(char *filter,
+ LDAPMessage **ldapResult, int num)
+{
+ return find_tus_token_entries_no_vlv(filter, ldapResult, num);
+}
+
+TPS_PUBLIC int RA::ra_find_tus_token_entries(char *filter, int maxReturns,
+ LDAPMessage **ldapResult, int num)
+{
+ return find_tus_token_entries(filter, maxReturns, ldapResult, num);
+}
+
+TPS_PUBLIC int RA::ra_is_tus_db_entry_disabled(char *cuid)
+{
+ return is_tus_db_entry_disabled(cuid);
+}
+
+TPS_PUBLIC int RA::ra_is_token_present(char *cuid)
+{
+ return is_token_present(cuid);
+}
+
+TPS_PUBLIC int RA::ra_is_token_pin_resetable(char *cuid)
+{
+ return is_token_pin_resetable(cuid);
+}
+
+TPS_PUBLIC int RA::ra_is_update_pin_resetable_policy(char *cuid)
+{
+ return is_update_pin_resetable_policy(cuid);
+}
+
+TPS_PUBLIC char *RA::ra_get_token_policy(char *cuid)
+{
+ return get_token_policy(cuid);
+}
+
+TPS_PUBLIC char *RA::ra_get_token_userid(char *cuid)
+{
+ return get_token_userid(cuid);
+}
+
+TPS_PUBLIC int RA::ra_update_token_policy(char *cuid, char *policy)
+{
+ return update_token_policy(cuid, policy);
+}
+
+TPS_PUBLIC int RA::ra_update_cert_status(char *cn, const char *status)
+{
+ return update_cert_status(cn, status);
+}
+
+TPS_PUBLIC int RA::ra_update_token_status_reason_userid(char *userid, char *cuid, const char *status, const char *reason, int modifyDateOfCreate)
+{
+ return update_token_status_reason_userid(userid, cuid, status, reason, modifyDateOfCreate);
+}
+
+TPS_PUBLIC int RA::ra_allow_token_reenroll(char *cuid)
+{
+ return allow_token_reenroll(cuid);
+}
+
+TPS_PUBLIC int RA::ra_allow_token_renew(char *cuid)
+{
+ return allow_token_renew(cuid);
+}
+
+TPS_PUBLIC int RA::ra_force_token_format(char *cuid)
+{
+ return force_token_format(cuid);
+}
+
+TPS_PUBLIC void RA::ra_tus_print_integer(char *out, SECItem *data)
+{
+ tus_print_integer(out, data);
+}
+
+TPS_PUBLIC int RA::ra_delete_certificate_entry(LDAPMessage* e)
+{
+ char *dn = get_dn(e);
+ int rc = LDAP_SUCCESS;
+
+ if (dn != NULL) {
+ rc = delete_tus_general_db_entry(dn);
+ if (rc != LDAP_SUCCESS) {
+ RA::Debug("RA::delete_certificate_entry",
+ "Failed to remove certificate entry: %s", dn);
+ }
+ PL_strfree(dn);
+ dn = NULL;
+ }
+ return rc;
+}
+
+int RA::tdb_activity(const char *ip, const char *cuid, const char *op, const char *result, const char *msg, const char *userid, const char *token_type)
+{
+ return add_activity(ip, cuid, op, result, msg, userid, token_type);
+}
+
+int RA::tdb_update_certificates(char* cuid, char **tokentypes, char *userid, CERTCertificate ** certificates, char **ktypes, char **origins, int numOfCerts)
+{
+ int rc = -1;
+ LDAPMessage *ldapResult = NULL;
+ int k = 0;
+ char serialnumber[512];
+ char filter[512];
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ int i = 0;
+
+ if ((rc = find_tus_db_entry(cuid, 0, &ldapResult)) != LDAP_SUCCESS) {
+ goto loser;
+ }
+
+ RA::Debug(LL_PER_PDU, "RA::tdb_update_certificates","numOfCerts %d", numOfCerts);
+ /* update certificates */
+ for (i = 0; i < numOfCerts; i++) {
+ if (certificates[i] == NULL) {
+ RA::Debug(LL_PER_PDU, "RA::tdb_update_certificates",
+ "no certificate found at index %d for tokendb entry: %s", i, cuid);
+ } else {
+ RA::Debug(LL_PER_PDU, "RA::tdb_update_certificates",
+ "cert=%x", certificates[i]);
+
+ k++;
+ }
+ }
+
+ for (i = 0; i < numOfCerts; i++) {
+ if (certificates[i] != NULL) {
+ RA::Debug(LL_PER_PDU, "RA::tdb_update_certificates",
+ "adding cert=%x", certificates[i]);
+
+ tus_print_integer(serialnumber, &(certificates[i])->serialNumber);
+ PR_snprintf(filter, 512, "tokenSerial=%s", serialnumber);
+
+ int r = find_tus_certificate_entries_by_order_no_vlv(filter, &result, 1);
+ RA::Debug(LL_PER_PDU, "RA::tdb_update_certificates",
+ "find_tus_certificate_entries_by_order_no_vlv returned %d", r);
+ bool found = false;
+ if (r == LDAP_SUCCESS) {
+ for (e = get_first_entry(result); e != NULL; e = get_next_entry(e)) {
+ struct berval **values = get_attribute_values(e, "tokenID");
+ if ((values == NULL) || (values[0] == NULL)) {
+ RA::Debug(LL_PER_PDU, "RA::tdb_update_certificates",
+ "unable to get tokenid");
+ if (values != NULL) {
+ ldap_value_free_len(values);
+ values = NULL;
+ }
+ continue;
+ }
+
+ char *cn = get_cert_cn(e);
+ if (PL_strcmp(cuid, values[0]->bv_val)== 0) found = true;
+ if (cn != NULL) {
+ RA::Debug(LL_PER_PDU, "RA::tdb_update_certificates", "Updating cert status of %s to active in tokendb", cn);
+ r = update_cert_status(cn, "active");
+ if (r != LDAP_SUCCESS) {
+ RA::Debug("RA::tdb_update_certificates",
+ "Unable to modify cert status to active in tokendb: %s", cn);
+ }
+ PL_strfree(cn);
+ cn = NULL;
+ }
+
+ ldap_value_free_len(values);
+ }
+
+ ldap_msgfree(result);
+ }
+ if (!found)
+ add_certificate(cuid, origins[i], tokentypes[i], userid, certificates[i],
+ ktypes[i], "active");
+ }
+ }
+loser:
+ if (ldapResult != NULL) {
+ ldap_msgfree(ldapResult);
+ }
+ return rc;
+}
+
+/*
+ * This adds a brand new token entry to tus.
+ */
+int RA::tdb_add_token_entry(char *userid, char* cuid, const char *status, const char *token_type) {
+ int rc = -1;
+ int r = -1;
+ LDAPMessage *ldapResult = NULL;
+
+ if (tokendbInitialized != 1) {
+ r = 0;
+ goto loser;
+ }
+
+ RA::Debug(LL_PER_PDU, "RA::tdb_add_token_entry",
+ "searching for tokendb entry: %s", cuid);
+
+ if ((rc = find_tus_db_entry(cuid, 0, &ldapResult)) != LDAP_SUCCESS) {
+ /* create a new entry */
+ rc = add_default_tus_db_entry(userid, "~tps", cuid, status, NULL, NULL, token_type);
+ if (rc != LDAP_SUCCESS) {
+ RA::Error(LL_PER_PDU, "RA:tdb_add_token_entry",
+ "failed to add tokendb entry");
+ r = -1;
+ goto loser;
+ } else
+ RA::Debug(LL_PER_PDU, "RA::tdb_add_token_entry",
+ "add tokendb entry successful");
+ r = 0;
+ goto loser;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA::tdb_add_token_entry",
+ "entry in tokendb exists.");
+
+ // try to see if the userid is there
+ LDAPMessage *e = ra_get_first_entry(ldapResult);
+ struct berval **uid = ra_get_attribute_values(e, "tokenUserID");
+
+ if ((uid != NULL) && (uid[0] != NULL)) {
+ if (uid[0]->bv_val != NULL) {
+ if (strlen(uid[0]->bv_val) > 0 && strcmp(uid[0]->bv_val, userid) != 0) {
+ ldap_value_free_len(uid);
+ RA::Debug(LL_PER_PDU, "RA::tdb_add_token_entry",
+ "This token does not belong to this user: %s", userid);
+ r = -1;
+ goto loser;
+ } else {
+ if (strlen(uid[0]->bv_val) > 0 && strcmp(uid[0]->bv_val, userid) == 0) {
+ ldap_value_free_len(uid);
+ r = 0;
+ goto loser;
+ }
+ }
+ }
+ ldap_value_free_len(uid);
+ }
+
+ // this is the recycled token, update userid and dateOfCreate
+ rc = ra_update_token_status_reason_userid(userid, cuid, status, "", 1);
+ r = rc;
+ }
+loser:
+ if (ldapResult != NULL) {
+ ldap_msgfree(ldapResult);
+ }
+ return r;
+}
+
+/*
+ * This adds entry to tokendb if entry not found
+ * It is then supposed to modify entry (not yet implemented)
+ */
+int RA::tdb_update(const char *userid, char* cuid, char* applet_version, char *key_info, const char *state, const char *reason, const char *token_type)
+{
+ int rc = -1;
+ LDAPMessage *ldapResult = NULL;
+ // char filter[255];
+
+ if (tokendbInitialized != 1) {
+ rc = 0;
+ goto loser;
+ }
+
+
+ // PR_snprintf(filter, 255, "(cn=%s)", cuid);
+ RA::Debug(LL_PER_PDU, "RA::tdb_update",
+ "searching for tokendb entry: %s", cuid);
+
+ if ((rc = find_tus_db_entry(cuid, 0, &ldapResult)) != LDAP_SUCCESS) {
+ /* create a new entry */
+ rc = add_default_tus_db_entry(userid, "~tps", cuid, state, applet_version,
+ key_info, token_type);
+ if (rc != LDAP_SUCCESS) {
+ RA::Error(LL_PER_PDU, "RA:tdb_update",
+ "failed to add tokendb entry");
+ rc = -1;
+ goto loser;
+ } else
+ RA::Debug(LL_PER_PDU, "RA::tdb_update",
+ "add tokendb entry successful");
+ rc = 0;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA::tdb_update",
+ "entry in tokendb exists...should modify entry");
+
+ /* need code to modify things such as applet version ...*/
+ /* ldap modify code to follow...*/
+ rc = update_tus_db_entry ("~tps", cuid, userid, key_info, state,
+ applet_version, reason, token_type);
+ }
+loser:
+ if (ldapResult != NULL) {
+ ldap_msgfree(ldapResult);
+ }
+ return rc;
+}
+
+int RA::InitializeAuthentication() {
+ char configname[256];
+ const char *authid;
+ const char *type;
+ const char *authPrefix = "auth.instance";
+ const char *lib = NULL;
+ const char *libfactory = NULL;
+ int i=-1;
+ int rc=0;
+ // AuthenticationEntry *authEntry;
+
+ while (1) {
+ i++;
+ PR_snprintf((char *)configname, 256, "%s.%d.authId", authPrefix, i);
+ authid = m_cfg->GetConfigAsString(configname, NULL);
+ if (authid != NULL) {
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Found authentication id=%s", authid);
+ PR_snprintf((char *)configname, 256, "%s.%d.libraryName", authPrefix, i);
+ lib = m_cfg->GetConfigAsString(configname, NULL);
+ if (lib != NULL) {
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Found authentication library=%s", lib);
+ PR_snprintf((char *)configname, 256, "%s.%d.libraryFactory", authPrefix, i);
+ libfactory = m_cfg->GetConfigAsString(configname, NULL);
+ if (libfactory != NULL) {
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Found authentication library factory=%s", libfactory);
+ PRLibrary *pb = PR_LoadLibrary(lib);
+ if (pb) {
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication", "Successfully loaded the library %s", lib);
+ void *sym = PR_FindSymbol(pb, libfactory);
+ if (sym == NULL) {
+ RA::Error(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Failed to find symbol '%s' in '%s' library, error code: %d",
+ libfactory, lib, PR_GetError());
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Failed to load the library symbol");
+ continue;
+ }
+ makeauthentication make_auth = (makeauthentication)sym;
+ Authentication *authentication = (*make_auth)();
+ if (authentication == NULL) {
+ RA::Error(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Failed to create authentication instance with library %s, error code=%d.",
+ lib, PR_GetError());
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Failed to create authentication instance with library %s, error code=%d.",
+ lib, PR_GetError());
+ continue;
+ } else {
+ authentication->Initialize(i);
+ m_auth_list[m_auth_len] = new AuthenticationEntry();
+ m_auth_list[m_auth_len]->SetId(authid);
+ m_auth_list[m_auth_len]->SetLibrary(pb);
+ m_auth_list[m_auth_len]->SetAuthentication(authentication);
+ PR_snprintf((char *)configname, 256, "%s.%d.type", authPrefix, i);
+ type = m_cfg->GetConfigAsString(configname, NULL);
+ m_auth_list[m_auth_len]->SetType(type);
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication:",
+ "Successfully initialized authentication %s.", lib);
+ }
+ } else {
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Failed to load the library %s: error=%d", lib, PR_GetError());
+ continue;
+ }
+ } else {
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Failed to find the library factory %s", libfactory);
+ continue;
+ }
+ } else {
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Failed to find the library %s", lib);
+ continue;
+ }
+ m_auth_len++;
+ } else {
+ break;
+ }
+ }
+
+ if (m_auth_len == 0) {
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication",
+ "No authentication module gets loaded, but server continues starting up...");
+ rc = -1;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Total number of authentication modules get loaded: %d", m_auth_len);
+ }
+
+ return rc;
+}
+
+int RA::Failover(HttpConnection *&conn, int len) {
+ int rc = 0;
+ if (m_pod_enable) {
+ PR_Lock(m_pod_lock);
+ if (++m_pod_curr >= len)
+ m_pod_curr = 0;
+ HttpConnection *conn = NULL;
+ for (int i=0; i<m_caConns_len; i++) {
+ conn = m_caConnection[i];
+ RA::SetCurrentIndex(conn, m_pod_curr);
+ conn = m_drmConnection[i];
+ RA::SetCurrentIndex(conn, m_pod_curr);
+ conn = m_tksConnection[i];
+ RA::SetCurrentIndex(conn, m_pod_curr);
+ }
+ PR_Unlock(m_pod_lock);
+ } else {
+ if (conn != NULL) {
+ int curr = RA::GetCurrentIndex(conn);
+ if (++curr >= len)
+ curr = 0;
+ RA::SetCurrentIndex(conn, curr);
+ } else
+ rc = -1;
+ }
+ return rc;
+}
+
+TPS_PUBLIC SECCertificateUsage RA::getCertificateUsage(const char *certusage) {
+ SECCertificateUsage cu = -1;
+ if ((certusage == NULL) || *certusage == 0)
+ cu = certificateUsageCheckAllUsages;
+ else if (strcmp(certusage, "CheckAllUsages") == 0)
+ cu = certificateUsageCheckAllUsages;
+ else if (strcmp(certusage, "SSLServer") == 0)
+ cu = certificateUsageSSLServer;
+ else if (strcmp(certusage, "SSLServerWithStepUp") == 0)
+ cu = certificateUsageSSLServerWithStepUp;
+ else if (strcmp(certusage, "SSLClient") == 0)
+ cu = certificateUsageSSLClient;
+ else if (strcmp(certusage, "SSLCA") == 0)
+ cu = certificateUsageSSLCA;
+ else if (strcmp(certusage, "AnyCA") == 0)
+ cu = certificateUsageAnyCA;
+ else if (strcmp(certusage, "StatusResponder") == 0)
+ cu = certificateUsageStatusResponder;
+ else if (strcmp(certusage, "ObjectSigner") == 0)
+ cu = certificateUsageObjectSigner;
+ else if (strcmp(certusage, "UserCertImport") == 0)
+ cu = certificateUsageUserCertImport;
+ else if (strcmp(certusage, "ProtectedObjectSigner") == 0)
+ cu = certificateUsageProtectedObjectSigner;
+ else if (strcmp(certusage, "VerifyCA") == 0)
+ cu = certificateUsageVerifyCA;
+ else if (strcmp(certusage, "EmailSigner") == 0)
+ cu = certificateUsageEmailSigner;
+
+ return cu;
+}
+
+TPS_PUBLIC bool RA::verifySystemCertByNickname(const char *nickname, const char *certusage) {
+ SECStatus rv = SECFailure;
+ CERTCertDBHandle *certdb = CERT_GetDefaultCertDB();
+ if (certdb == NULL) {
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "fatal error:%s", "cert db not found");
+ return false;
+ }
+ CERTCertificate *cert = NULL;
+ PR_ASSERT(certdb != NULL);
+ SECCertificateUsage cu = getCertificateUsage(certusage);
+ if (cu == -1) {
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "error: invalid certificate usage %s for cert %s", (certusage !=NULL)? certusage:"", nickname);
+ return false;
+ }
+ SECCertificateUsage currUsage = 0;
+
+ cert = CERT_FindCertByNickname(certdb, nickname);
+ if (cert == NULL) {
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "nickname not found:%s",
+ nickname);
+ } else {
+ rv = CERT_VerifyCertificateNow(certdb, cert, true, cu , NULL, &currUsage);
+ /*
+ * to find actual certificate usage, pass 0 as cu in above call
+ */
+ if (cu == certificateUsageCheckAllUsages) {
+ if (currUsage & certificateUsageSSLServer)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is SSLServer");
+ if (currUsage & certificateUsageSSLServerWithStepUp)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is SSLServerWithStepUp");
+ if (currUsage & certificateUsageSSLClient)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is SSLClient");
+ if (currUsage & certificateUsageAnyCA)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is AnyCA");
+ if (currUsage & certificateUsageSSLCA)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is SSLCA");
+ if (currUsage & certificateUsageEmailSigner)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is EmailSigner");
+ if (currUsage & certificateUsageStatusResponder)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is StatusResponder");
+ if (currUsage & certificateUsageObjectSigner)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is ObjectSigner");
+ if (currUsage & certificateUsageUserCertImport)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is UserCertImport");
+ if (currUsage & certificateUsageProtectedObjectSigner)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is ProtectedObjectSigner");
+ if (currUsage & certificateUsageVerifyCA)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is VerifyCA");
+
+ if (currUsage ==
+ /* 0x0b80 */
+ ( certUsageUserCertImport |
+ certUsageVerifyCA |
+ certUsageProtectedObjectSigner |
+ certUsageAnyCA )) { /* cert is good for nothing */
+
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname() failed:", "cert is good for nothing: %d %s", currUsage, nickname);
+ rv = SECFailure;
+ } else {
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname() passed:", "%s", nickname);
+ rv = SECSuccess;
+ }
+ }
+ }
+
+ if (cert != NULL) {
+ CERT_DestroyCertificate(cert);
+ }
+ if (rv == SECSuccess)
+ return true;
+ else
+ return false;
+}
+
+/*
+ * tps.cert.list=sslserver,subsystem,audit_signing
+ * tps.cert.sslserver.nickname=xxx
+ * tps.cert.sslserver.certusage=SSLServer
+ * tps.cert.subsystem.nickname=xxx
+ * tps.cert.subsystem.certusage=SSLClient
+ * tps.cert.audit_signing.nickname=xxx
+ * tps.cert.audit_signing.certusage=ObjectSigner
+ */
+TPS_PUBLIC bool RA::verifySystemCerts() {
+ bool verifyResult = false;
+ bool rv = false; /* final return value */
+ char configname[256];
+ char configname_nn[256];
+ char configname_cu[256];
+ char audit_msg[512]="";
+ const char *certList = NULL;
+ ConfigStore *store = RA::GetConfigStore();
+
+ PR_snprintf((char *)configname, 256, "tps.cert.list");
+ certList = store->GetConfigAsString(configname, NULL);
+ if (certList == NULL) {
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCerts",
+ "config not found:%s", configname);
+ PR_snprintf(audit_msg, 512, "%s undefined in CS.cfg", configname);
+ RA::Audit(EV_CIMC_CERT_VERIFICATION, AUDIT_MSG_FORMAT, "System", "Failure", audit_msg);
+ return false;
+ } else {
+ char *certList_x = PL_strdup(certList);
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCerts",
+ "found cert list:%s", certList_x);
+ char *sresult = NULL;
+ char *lasts = NULL;
+ const char *nn = NULL;
+ const char *cu = NULL;
+
+ sresult = PL_strtok_r(certList_x, ",", &lasts);
+ while (sresult != NULL) {
+ PR_snprintf((char *)configname_nn, 256, "tps.cert.%s.nickname",
+ sresult);
+ nn = store->GetConfigAsString(configname_nn, NULL);
+ if ((nn == NULL) || *nn==0) {
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCerts",
+ "cert nickname not found for cert tag:%s", sresult);
+ PR_snprintf(audit_msg, 512, "%s undefined in CS.cfg", configname_nn);
+ RA::Audit(EV_CIMC_CERT_VERIFICATION, AUDIT_MSG_FORMAT, "System", "Failure", audit_msg);
+ sresult = PL_strtok_r(NULL, ",", &lasts);
+ rv = false;
+ continue;
+ }
+ PR_snprintf((char *)configname_cu, 256, "tps.cert.%s.certusage",
+ sresult);
+ cu = store->GetConfigAsString(configname_cu, NULL);
+ if ((cu == NULL) || *cu==0) {
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCerts",
+ "certificate usage not found for cert tag:%s. Getting current certificate usage", sresult);
+ } else {
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCerts",
+ "found certificate usage:%s", cu);
+ }
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCerts",
+ "Verifying cert tag: %s, nickname:%s, certificate usage:%s"
+ , sresult, nn, (cu!=NULL)? cu: "");
+
+ verifyResult = verifySystemCertByNickname(nn, cu);
+ if (verifyResult == true) {
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCerts",
+ "cert verification passed on cert nickname:%s", nn);
+ PR_snprintf(audit_msg, 512, "Certificate verification succeeded:%s",
+ nn);
+ RA::Audit(EV_CIMC_CERT_VERIFICATION, AUDIT_MSG_FORMAT, "System", "Success", audit_msg);
+ } else {
+ rv = false;
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCerts",
+ "cert verification failed on cert nickname:%s", nn);
+ PR_snprintf(audit_msg, 512, "Certificate verification failed:%s",
+ nn);
+ RA::Audit(EV_CIMC_CERT_VERIFICATION, AUDIT_MSG_FORMAT, "System", "Failure", audit_msg);
+ }
+ sresult = PL_strtok_r(NULL, ",", &lasts);
+ }
+
+ if (certList_x != NULL) {
+ PL_strfree(certList_x);
+ }
+ }
+
+ return rv;
+}
+
+PK11SymKey *RA::FindSymKeyByName( PK11SlotInfo *slot, char *keyname) {
+char *name = NULL;
+ PK11SymKey *foundSymKey= NULL;
+ PK11SymKey *firstSymKey= NULL;
+ PK11SymKey *sk = NULL;
+ PK11SymKey *nextSymKey = NULL;
+ secuPWData pwdata;
+
+ pwdata.source = secuPWData::PW_NONE;
+ pwdata.data = (char *) NULL;
+ if (keyname == NULL)
+ {
+ goto cleanup;
+ }
+ if (slot== NULL)
+ {
+ goto cleanup;
+ }
+ /* Initialize the symmetric key list. */
+ firstSymKey = PK11_ListFixedKeysInSlot( slot , NULL, ( void *) &pwdata );
+ /* scan through the symmetric key list for a key matching our nickname */
+ sk = firstSymKey;
+ while( sk != NULL )
+ {
+ /* get the nickname of this symkey */
+ name = PK11_GetSymKeyNickname( sk );
+
+ /* if the name matches, make a 'copy' of it */
+ if ( name != NULL && !strcmp( keyname, name ))
+ {
+ if (foundSymKey == NULL)
+ {
+ foundSymKey = PK11_ReferenceSymKey(sk);
+ }
+ PORT_Free(name);
+ }
+
+ sk = PK11_GetNextSymKey( sk );
+ }
+
+ /* We're done with the list now, let's free all the keys in it
+ It's okay to free our key, because we made a copy of it */
+
+ sk = firstSymKey;
+ while( sk != NULL )
+ {
+ nextSymKey = PK11_GetNextSymKey(sk);
+ PK11_FreeSymKey(sk);
+ sk = nextSymKey;
+ }
+
+ cleanup:
+ return foundSymKey;
+}
+
+PK11SymKey *RA::CreateDesKey24Byte(PK11SlotInfo *slot, PK11SymKey *origKey)
+{
+ PK11SymKey *newKey = NULL;
+ PK11SymKey *firstEight = NULL;
+ PK11SymKey *concatKey = NULL;
+ PK11SymKey *internalOrigKey = NULL;
+ CK_ULONG bitPosition = 0;
+ SECItem paramsItem = { siBuffer, NULL, 0 };
+ CK_OBJECT_HANDLE keyhandle = 0;
+ RA::Debug("RA_Enroll_Processor::CreateDesKey24Byte",
+ "entering.");
+
+ PK11SlotInfo *internal = PK11_GetInternalSlot();
+ if ( slot == NULL || origKey == NULL || internal == NULL)
+ goto loser;
+
+ if( internal != slot ) { //Make sure we do this on the NSS Generic Crypto services because concatanation
+ // only works there.
+ internalOrigKey = PK11_MoveSymKey( internal, CKA_ENCRYPT, 0, PR_FALSE, origKey );
+ }
+ // Extract first eight bytes from generated key into another key.
+ bitPosition = 0;
+ paramsItem.data = (CK_BYTE *) &bitPosition;
+ paramsItem.len = sizeof bitPosition;
+
+ if ( internalOrigKey)
+ firstEight = PK11_Derive(internalOrigKey, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT , CKA_DERIVE, 8);
+ else
+ firstEight = PK11_Derive(origKey, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT , CKA_DERIVE, 8);
+
+ if (firstEight == NULL ) {
+ RA::Debug("RA_Enroll_Processor::CreateDesKey24Byte",
+ "error deriving 8 byte portion of key.");
+ goto loser;
+ }
+
+ //Concatenate 8 byte key to the end of the original key, giving new 24 byte key
+ keyhandle = PK11_GetSymKeyHandle(firstEight);
+
+ paramsItem.data=(unsigned char *) &keyhandle;
+ paramsItem.len=sizeof(keyhandle);
+
+ if ( internalOrigKey ) {
+ concatKey = PK11_Derive ( internalOrigKey , CKM_CONCATENATE_BASE_AND_KEY , &paramsItem ,CKM_DES3_ECB , CKA_DERIVE , 0);
+ } else {
+ concatKey = PK11_Derive ( origKey , CKM_CONCATENATE_BASE_AND_KEY , &paramsItem ,CKM_DES3_ECB , CKA_DERIVE , 0);
+ }
+
+ if ( concatKey == NULL ) {
+ RA::Debug("RA_Enroll_Processor::CreateDesKey24Byte",
+ "error concatenating 8 bytes on end of key.");
+ goto loser;
+ }
+
+ //Make sure we move this to the proper token, in case it got moved by NSS
+ //during the derive phase.
+
+ newKey = PK11_MoveSymKey ( slot, CKA_ENCRYPT, 0, PR_FALSE, concatKey);
+
+ if ( newKey == NULL ) {
+ RA::Debug("RA_Enroll_Processor::CreateDesKey24Byte",
+ "error moving key to original slot.");
+ }
+
+loser:
+
+ if ( concatKey != NULL ) {
+ PK11_FreeSymKey( concatKey );
+ concatKey = NULL;
+ }
+
+ if ( firstEight != NULL ) {
+ PK11_FreeSymKey ( firstEight );
+ firstEight = NULL;
+ }
+
+ if ( internalOrigKey != NULL ) {
+ PK11_FreeSymKey ( internalOrigKey );
+ internalOrigKey = NULL;
+ }
+
+ if ( internal != NULL ) {
+ PK11_FreeSlot( internal);
+ internal = NULL;
+ }
+
+ return newKey;
+}
diff --git a/base/tps/src/httpClient/Cache.cpp b/base/tps/src/httpClient/Cache.cpp
new file mode 100644
index 000000000..2ea628f8c
--- /dev/null
+++ b/base/tps/src/httpClient/Cache.cpp
@@ -0,0 +1,496 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+/**
+ * Simple cache implementation
+ */
+#include <string.h>
+#include <time.h>
+
+// NSS includes
+#include "pk11func.h"
+#include "hasht.h"
+
+// NSPR includes
+#include "nspr.h"
+#include "plhash.h"
+#include "plstr.h"
+#include "plbase64.h"
+
+// Always before PSCommonLib.h
+#define COMMON_LIB_DLL
+#include "httpClient/httpc/PSCommonLib.h"
+#include "httpClient/httpc/Defines.h"
+//-- #include "httpClient/httpc/PSError.h"
+#include "httpClient/httpc/Iterator.h"
+#include "httpClient/httpc/Cache.h"
+//-- #include "httpClient/httpc/DebugLogger.h"
+//-- #include "httpClient/httpc/ErrorLogger.h"
+
+#include "engine/RA.h"
+#include "main/Memory.h"
+
+//-- static const char *DEBUG_MODULE = NULL;
+//-- static const char *DEBUG_CLASS_NAME = "StringKeyCache";
+
+// From the NSPR implementation of hashtables
+/* Compute the number of buckets in ht */
+#define NBUCKETS(ht) (1 << (PL_HASH_BITS - (ht)->shift))
+
+
+/**
+ * Called from the destructor
+ */
+extern "C" {
+static PRIntn onCacheRelease( PLHashEntry* he, PRIntn index, void* arg );
+/**
+ * Called to allocate and return copies of keys
+ */
+static PRIntn getKeys( PLHashEntry* he, PRIntn index, void* arg );
+}
+
+/**
+ * Constructor
+ *
+ * @param key Pointer to the key being cached
+ * @param data Pointer to the data being cached
+ */
+CacheEntry::CacheEntry( const char* key, void *data ) {
+ if( key != NULL ) {
+ m_key = strdup( key );
+ } else {
+ m_key = NULL;
+ }
+ m_data = data;
+ // NSPR counts in microseconds
+ m_startTime = (time_t)(PR_Now() / 1000000);
+}
+
+/**
+ * Destructor
+ */
+CacheEntry::~CacheEntry() {
+ if( m_key != NULL ) {
+ free( m_key );
+ m_key = NULL;
+ }
+}
+
+/**
+ * Returns a pointer to the cached key
+ *
+ * @return A pointer to the cached key
+ */
+const char *CacheEntry::GetKey() {
+ return m_key;
+}
+
+/**
+ * Returns a pointer to the cached data
+ *
+ * @return A pointer to the cached data
+ */
+void *CacheEntry::GetData() {
+ return m_data;
+}
+
+
+/**
+ * Returns the time when the entry was created
+ *
+ * @return The time when the entry was created
+ */
+long CacheEntry::GetStartTime() {
+ return (long)m_startTime;
+}
+
+
+/**
+ * Default constructor
+ */
+Cache::Cache() {
+ m_cache = NULL;
+ m_cacheLock = NULL;
+}
+
+/**
+ * Constructor
+ *
+ * @param name of the cache
+ * @param ttl Time to live of each cache entry
+ * @param implicitLock true if the Cache is to do locking internally
+ * when required; false if the caller will take responsibility
+ */
+Cache::Cache( const char *name, int ttl, bool implicitLock ) {
+
+ Initialize( name, ttl, implicitLock );
+}
+
+/**
+ * Destructor
+ */
+Cache::~Cache() {
+
+ if( m_cacheLock ) {
+ PR_DestroyRWLock( m_cacheLock );
+ m_cacheLock = NULL;
+ }
+ if( m_cache ) {
+ PL_HashTableEnumerateEntries( m_cache, onCacheRelease, NULL );
+ PL_HashTableDestroy( m_cache );
+ m_cache = NULL;
+ }
+
+}
+
+/**
+ * Initializes the object - to be called from the constructor
+ *
+ * @param name of the cache
+ * @param ttl Time to live of each cache entry
+ * @param implicitLock true if the Cache is to do locking internally
+ * when required; false if the caller will take responsibility
+ */
+void Cache::Initialize( const char *name, int ttl, bool implicitLock ) {
+
+ if ( !m_cache ) {
+ m_implicitLock = implicitLock;
+ m_ttl = ttl;
+ m_cache = PL_NewHashTable( 0,
+ PL_HashString,
+ PL_CompareStrings,
+ PL_CompareValues,
+ NULL,
+ NULL
+ );
+ m_cacheLock = PR_NewRWLock( PR_RWLOCK_RANK_NONE, name );
+ m_name = name;
+ }
+
+}
+
+/**
+ * Acquires a read lock on the cache. Multiple threads may simultaneously
+ * have a read lock, but attempts to acquire a read lock will block
+ * if another thread already has a write lock. It is illegal to request
+ * a read lock if the thread already has one.
+ */
+void Cache::ReadLock() {
+ PR_RWLock_Rlock( m_cacheLock );
+}
+
+/**
+ * Acquires a write lock on the cache. Only one thread may have a write
+ * lock at any given time; attempts to acquire a write lock will block
+ * if another thread already has one. It is illegal to request
+ * a write lock if the thread already has one.
+ */
+void Cache::WriteLock() {
+ PR_RWLock_Wlock( m_cacheLock );
+}
+
+/**
+ * Releases a read or write lock that the thread has on the cache
+ */
+void Cache::Unlock() {
+ PR_RWLock_Unlock( m_cacheLock );
+}
+
+/**
+ * Returns the number of entries in the cache
+ *
+ * @return The number of entries in the cache
+ */
+int Cache::GetCount() {
+ int nKeys = 0;
+ if ( m_implicitLock ) {
+ ReadLock();
+ }
+ nKeys = m_cache->nentries;
+ if ( m_implicitLock ) {
+ Unlock();
+ }
+ return nKeys;
+}
+
+class KeyIterator : public Iterator {
+public:
+ /**
+ * Constructor
+ *
+ * @param ht A hashtable to iterate on
+ * @param cacheLock Lock for accessing the hashtable
+ * @param implictLock true if hashtable locking is to be done
+ * internally
+ */
+ KeyIterator( PLHashTable *ht, PRRWLock *cacheLock, bool implicitLock ) {
+ m_table = ht;
+ m_bucketIndex = 0;
+ m_entry = m_table->buckets[m_bucketIndex];
+ m_cacheLock = cacheLock;
+ m_implicitLock = implicitLock;
+ }
+
+ /**
+ * Destructor
+ */
+ virtual ~KeyIterator() {
+ }
+
+ /**
+ * Returns true if there is at least one more key
+ *
+ * @return true if there is at least one more key
+ */
+ bool HasMore() {
+ if ( NULL == m_entry ) {
+ Next();
+ }
+ return ( NULL != m_entry );
+ }
+
+ /**
+ * Returns the next key, if any; the key is deallocated by the Iterator
+ * in its destructor
+ *
+ * @return The next key, if any, or NULL
+ */
+ void *Next() {
+ PLHashEntry *he = m_entry;
+ m_entry = (m_entry != NULL) ? m_entry->next : NULL;
+ int nBuckets = NBUCKETS(m_table);
+ if ( m_implicitLock ) {
+ PR_RWLock_Rlock( m_cacheLock );
+ }
+ while ( (NULL == m_entry) && (m_bucketIndex < (nBuckets-1)) ) {
+ m_bucketIndex++;
+ m_entry = m_table->buckets[m_bucketIndex];
+ }
+ if ( m_implicitLock ) {
+ PR_RWLock_Unlock( m_cacheLock );
+ }
+ return ( he != NULL ) ? (void *)he->key : NULL;
+ }
+
+private:
+ PLHashTable *m_table;
+ PLHashEntry *m_entry;
+ int m_bucketIndex;
+ PRRWLock* m_cacheLock;
+ bool m_implicitLock;
+};
+
+/**
+ * Constructor
+ *
+ * @param name of the cache
+ * @param ttl Time to live of each cache entry
+ * @param implicitLock true if the Cache is to do locking internally
+ * when required; false if the caller will take responsibility
+ */
+StringKeyCache::StringKeyCache( const char *name, int ttl,
+ bool implicitLock ) {
+
+ Initialize( name, ttl, implicitLock );
+
+}
+
+/**
+ * Destructor
+ */
+StringKeyCache::~StringKeyCache() {
+}
+
+/**
+ * Returns a cache entry
+ *
+ * @param key The name of the cache entry
+ * @return The corresponding cache entry, or NULL if not found
+ */
+CacheEntry *StringKeyCache::Get( const char *key ) {
+ // Avoid recursion when the debug log is starting up
+
+ if ( m_implicitLock ) {
+ ReadLock();
+ }
+ CacheEntry *entry =
+ (CacheEntry *)PL_HashTableLookupConst( m_cache, key );
+ if ( m_implicitLock ) {
+ Unlock();
+ }
+ if ( entry && m_ttl ) {
+ // Check if the cache entry has expired
+ // NSPR counts in microseconds
+ time_t now = (time_t)(PR_Now() / 1000000);
+ if ( ((long)now - entry->GetStartTime()) > m_ttl ) {
+ if( key != NULL ) {
+ Remove( key );
+ key = NULL;
+ }
+ if( entry != NULL ) {
+ delete entry;
+ entry = NULL;
+ }
+ // Avoid recursion when the debug log is starting up
+ if ( PL_strcasecmp( m_name, "DebugLogModuleCache" ) ) {
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( DEBUG_MODULE );
+//-- logger->Log( LOGLEVEL_FINER, DEBUG_CLASS_NAME,
+//-- "Get",
+ RA::Debug( LL_PER_PDU,
+ "StringKeyCache::Get: ",
+ "Entry %s expired from cache %s",
+ key,
+ m_name );
+ }
+ }
+ }
+
+ return entry;
+}
+
+/**
+ * Adds a cache entry
+ *
+ * @param key The name of the cache entry; an internal copy is made
+ * @param value The value of the cache entry
+ * @return The corresponding cache entry, or NULL if it couldn't be added
+ */
+CacheEntry *StringKeyCache::Put( const char *key, void *value ) {
+ CacheEntry *entry = new CacheEntry( key, value );
+ if ( m_implicitLock ) {
+ WriteLock();
+ }
+ PL_HashTableAdd( m_cache, entry->GetKey(), entry );
+ if ( m_implicitLock ) {
+ Unlock();
+ }
+
+ return entry;
+}
+
+/**
+ * Removes a cache entry; does not free the entry object
+ *
+ * @param key The name of the cache entry
+ * @return The corresponding cache entry, or NULL if not found
+ */
+CacheEntry *StringKeyCache::Remove( const char *key ) {
+
+ if ( m_implicitLock ) {
+ WriteLock();
+ }
+ CacheEntry *entry =
+ (CacheEntry *)PL_HashTableLookupConst( m_cache, key );
+ if( entry ) {
+ PL_HashTableRemove( m_cache, key );
+ }
+ if ( m_implicitLock ) {
+ Unlock();
+ }
+
+ return entry;
+}
+
+class KeyArray {
+public:
+ KeyArray( int nKeys ) {
+ m_nKeys = nKeys;
+ m_keys = new char *[m_nKeys];
+ m_currentKey = 0;
+ }
+ virtual ~KeyArray() {
+ }
+ int m_currentKey;
+ int m_nKeys;
+ char **m_keys;
+};
+
+/**
+ * Returns an iterator over keys in the cache
+ *
+ * @return An iterator over keys in the cache
+ */
+Iterator *StringKeyCache::GetKeyIterator() {
+ return new KeyIterator( m_cache, m_cacheLock, m_implicitLock );
+}
+
+/**
+ * Allocates and returns a list of keys in the cache
+ *
+ * @param keys Returns an array of names; each name and also the
+ * array itself are to be freed by the caller with delete
+ * @return The number of keys found
+ */
+int StringKeyCache::GetKeys( char ***keys ) {
+
+ int nKeys = GetCount();
+ if ( m_implicitLock ) {
+ ReadLock();
+ }
+ KeyArray keyArray( nKeys );
+ PL_HashTableEnumerateEntries( m_cache, getKeys, &keyArray );
+ if ( m_implicitLock ) {
+ Unlock();
+ }
+ if( ( keyArray.m_nKeys < 1 ) && keyArray.m_keys ) {
+ delete [] keyArray.m_keys;
+ keyArray.m_keys = NULL;
+ }
+ *keys = keyArray.m_keys;
+
+ return keyArray.m_nKeys;
+}
+
+/**
+ * Adds cache entry keys to an accumulator
+ */
+extern "C" {
+static PRIntn getKeys( PLHashEntry* he, PRIntn index, void* arg ) {
+ PRIntn result = HT_ENUMERATE_NEXT;
+ if ( he != NULL ) {
+ if ( he->key ) {
+ KeyArray *keys = (KeyArray *)arg;
+ int len = strlen( (char *)he->key );
+ int i = keys->m_currentKey;
+ keys->m_keys[i] = new char[len+1];
+ strcpy( keys->m_keys[i], (char *)he->key );
+ keys->m_currentKey++;
+ }
+ }
+ return result;
+}
+
+/**
+ * Frees keys of entries in cache; does not free values
+ */
+static PRIntn onCacheRelease( PLHashEntry* he, PRIntn index, void* arg ) {
+ PRIntn result = HT_ENUMERATE_NEXT;
+ if( he != NULL ) {
+ if( he->key != NULL ) {
+ free( (char *) he->key );
+ he->key = NULL;
+ result = HT_ENUMERATE_REMOVE;
+ }
+ }
+ return result;
+}
+} // extern "C"
diff --git a/base/tps/src/httpClient/engine.cpp b/base/tps/src/httpClient/engine.cpp
new file mode 100644
index 000000000..621a37244
--- /dev/null
+++ b/base/tps/src/httpClient/engine.cpp
@@ -0,0 +1,775 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#include "nspr.h"
+#include "sslproto.h"
+#include "prerror.h"
+
+#include "ssl.h"
+#include "nss.h"
+#include "pk11func.h"
+#include "cert.h"
+#include "certt.h"
+#include "sslerr.h"
+#include "secerr.h"
+
+#include "httpClient/httpc/engine.h"
+#include "httpClient/httpc/http.h"
+#include "httpClient/httpc/PSPRUtil.h"
+#include "httpClient/httpc/Defines.h"
+//-- #include "httpClient/httpc/DebugLogger.h"
+#include "engine/RA.h"
+#include "main/Memory.h"
+
+char* certName = NULL;
+char* password = NULL;
+int ciphers[32];
+int cipherCount = 0;
+int _doVerifyServerCert = 1;
+
+//-- static const char *DEBUG_MODULE = "httpclient";
+//-- static const char *DEBUG_CLASS_NAME = "HttpEngine";
+
+PRIntervalTime Engine::globaltimeout = PR_TicksPerSecond()*30;
+
+static char * ownPasswd( PK11SlotInfo *slot, PRBool retry, void *arg) {
+ if (!retry) {
+ if( password != NULL ) {
+ return PL_strdup(password);
+ } else {
+ return PL_strdup( "httptest" );
+ }
+ } else {
+ return NULL;
+ }
+}
+
+/**
+ * Function: SECStatus myBadCertHandler()
+ * <BR>
+ * Purpose: This callback is called when the incoming certificate is not
+ * valid. We define a certain set of parameters that still cause the
+ * certificate to be "valid" for this session, and return SECSuccess to cause
+ * the server to continue processing the request when any of these conditions
+ * are met. Otherwise, SECFailure is return and the server rejects the
+ * request.
+ */
+SECStatus myBadCertHandler( void *arg, PRFileDesc *socket ) {
+
+ SECStatus secStatus = SECFailure;
+ PRErrorCode err;
+
+ /* log invalid cert here */
+
+ if ( !arg ) {
+ return secStatus;
+ }
+
+ *(PRErrorCode *)arg = err = PORT_GetError();
+
+ /* If any of the cases in the switch are met, then we will proceed */
+ /* with the processing of the request anyway. Otherwise, the default */
+ /* case will be reached and we will reject the request. */
+
+ switch (err) {
+ case SEC_ERROR_INVALID_AVA:
+ case SEC_ERROR_INVALID_TIME:
+ case SEC_ERROR_BAD_SIGNATURE:
+ case SEC_ERROR_EXPIRED_CERTIFICATE:
+ case SEC_ERROR_UNKNOWN_ISSUER:
+ case SEC_ERROR_UNTRUSTED_CERT:
+ case SEC_ERROR_CERT_VALID:
+ case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
+ case SEC_ERROR_CRL_EXPIRED:
+ case SEC_ERROR_CRL_BAD_SIGNATURE:
+ case SEC_ERROR_EXTENSION_VALUE_INVALID:
+ case SEC_ERROR_CA_CERT_INVALID:
+ case SEC_ERROR_CERT_USAGES_INVALID:
+ case SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION:
+ case SEC_ERROR_EXTENSION_NOT_FOUND: // Added by Rob 5/21/2002
+ secStatus = SECSuccess;
+ break;
+ default:
+ secStatus = SECFailure;
+ break;
+ }
+
+ return secStatus;
+}
+
+
+PRBool __EXPORT InitSecurity(char* certDir, char* certname, char* certpassword, char *prefix,int verify ) {
+ if (certpassword) {
+ password = PL_strdup(certpassword);
+ } else {
+ password = PL_strdup( "httptest" );
+ }
+ if (certname) {
+ certName = PL_strdup(certname);
+ }
+
+ SECStatus stat;
+ PR_Init( PR_USER_THREAD, PR_PRIORITY_NORMAL, 0 );
+ if (!NSS_IsInitialized()) {
+ stat = NSS_Initialize( certDir, prefix, prefix,"secmod.db",
+ NSS_INIT_READONLY);
+ } else {
+ stat = SECSuccess;
+ RA::Debug( LL_PER_PDU,
+ "initSecurity: ",
+ "NSS Already initialized" );
+
+ }
+
+ if (SECSuccess != stat) {
+ // int err = PR_GetError();
+ return PR_FAILURE;
+ }
+ PK11_SetPasswordFunc(ownPasswd);
+
+ stat = NSS_SetDomesticPolicy();
+ SSL_CipherPrefSetDefault( SSL_RSA_WITH_NULL_MD5, PR_TRUE );
+
+ _doVerifyServerCert = verify;
+
+
+ return PR_TRUE;
+}
+
+
+int ssl2Suites[] = {
+ SSL_EN_RC4_128_WITH_MD5, /* A */
+ SSL_EN_RC4_128_EXPORT40_WITH_MD5, /* B */
+ SSL_EN_RC2_128_CBC_WITH_MD5, /* C */
+ SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, /* D */
+ SSL_EN_DES_64_CBC_WITH_MD5, /* E */
+ SSL_EN_DES_192_EDE3_CBC_WITH_MD5, /* F */
+ 0
+};
+
+int ssl3Suites[] = {
+ SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, /* a */
+ SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, /* b */
+ SSL_RSA_WITH_RC4_128_MD5, /* c */
+ SSL_RSA_WITH_3DES_EDE_CBC_SHA, /* d */
+ SSL_RSA_WITH_DES_CBC_SHA, /* e */
+ SSL_RSA_EXPORT_WITH_RC4_40_MD5, /* f */
+ SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, /* g */
+ SSL_FORTEZZA_DMS_WITH_NULL_SHA, /* h */
+ SSL_RSA_WITH_NULL_MD5, /* i */
+ SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, /* j */
+ SSL_RSA_FIPS_WITH_DES_CBC_SHA, /* k */
+ TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, /* l */
+ TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, /* m */
+ 0
+};
+
+int tlsSuites[] = {
+// TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
+// TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
+// TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ TLS_RSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+// TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+// TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+// TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+ TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+ TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+ TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+};
+
+void disableAllCiphersOnSocket(PRFileDesc* sock) {
+ int i;
+ int numsuites = SSL_NumImplementedCiphers;
+
+ /* disable all the cipher suites for that socket */
+ for (i = 0; i<numsuites; i++) {
+ SSL_CipherPrefSet(sock, SSL_ImplementedCiphers[i], SSL_NOT_ALLOWED);
+ }
+}
+
+void __EXPORT EnableAllSSL3Ciphers(PRFileDesc* sock) {
+ int i =0;
+ while (ssl3Suites[i]) {
+ SSL_CipherPrefSet(sock, ssl3Suites[i], SSL_ALLOWED);
+ }
+}
+
+void __EXPORT EnableAllTLSCiphers(PRFileDesc* sock) {
+ int i =0;
+ while (tlsSuites[i]) {
+ SSL_CipherPrefSet(sock, tlsSuites[i++], SSL_ALLOWED);
+ }
+}
+
+PRBool __EXPORT EnableCipher(const char* cipherString) {
+ int ndx;
+
+ if (!cipherString) {
+ return PR_FALSE;
+ }
+
+ while (0 != (ndx = *cipherString++)) {
+ int* cptr;
+ int cipher;
+
+ if (! isalpha(ndx)) {
+ continue;
+ }
+ cptr = islower(ndx) ? ssl3Suites : ssl2Suites;
+ for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; ) {
+ /* do nothing */;
+ }
+ ciphers[cipherCount++] = cipher;
+ }
+
+ return PR_TRUE;
+}
+
+SECStatus certcallback (
+ void *arg,
+ PRFileDesc *fd,
+ PRBool checksig,
+ PRBool isServer) {
+ return SECSuccess; // always succeed
+}
+
+/**
+ * Function: SECStatus myAuthCertificate()
+ * <BR>
+ * Purpose: This function is our custom certificate authentication handler.
+ * <BR>
+ * Note: This implementation is essentially the same as the default
+ * SSL_AuthCertificate().
+ */
+extern "C" {
+
+static SECStatus myAuthCertificate( void *arg,
+ PRFileDesc *socket,
+ PRBool checksig,
+ PRBool isServer ) {
+
+ SECCertUsage certUsage;
+ CERTCertificate * cert;
+ void * pinArg;
+ char * hostName = NULL;
+ SECStatus secStatus = SECSuccess;
+//-- static const char *DEBUG_METHOD_NAME = "myAuthCertificate";
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( "httpclient");
+
+ if ( !arg || !socket ) {
+ return SECFailure;
+ }
+
+ /* Define how the cert is being used based upon the isServer flag. */
+
+ certUsage = isServer ? certUsageSSLClient : certUsageSSLServer;
+
+ cert = SSL_PeerCertificate( socket );
+
+ pinArg = SSL_RevealPinArg( socket );
+
+ // Skip the server cert verification fconditionally, because our test
+ // servers do not have a valid root CA cert.
+ if ( _doVerifyServerCert ) {
+
+ PRLock *verify_lock = RA::GetVerifyLock();
+ if (verify_lock == NULL) {
+ return SECFailure;
+ }
+ PR_Lock(verify_lock);
+ /* This function is not thread-safe. So we need to use a global lock */
+ secStatus = CERT_VerifyCertNow( (CERTCertDBHandle *)arg,
+ cert,
+ checksig,
+ certUsage,
+ pinArg);
+ PR_Unlock(verify_lock);
+
+ if( SECSuccess != secStatus ) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ if (cert == NULL) {
+ RA::Debug( LL_PER_PDU,
+ "myAuthCertificate: ",
+ "Server Certificate Not Found" );
+ } else {
+ if (cert->subjectName == NULL) {
+ RA::Debug( LL_PER_PDU,
+ "myAuthCertificate: ",
+ "Untrusted server certificate" );
+ } else {
+ RA::Debug( LL_PER_PDU,
+ "myAuthCertificate: ",
+ "Untrusted server certificate error=%d subject='%s'", PORT_GetError(), cert->subjectName );
+ }
+ }
+ }
+ }
+
+ /* If this is a server, we're finished. */
+ if (isServer || secStatus != SECSuccess) {
+ return secStatus;
+ }
+
+ /* Certificate is OK. Since this is the client side of an SSL
+ * connection, we need to verify that the name field in the cert
+ * matches the desired hostname. This is our defense against
+ * man-in-the-middle attacks.
+ */
+
+ /* SSL_RevealURL returns a hostName, not an URL. */
+ hostName = SSL_RevealURL( socket );
+
+ if (hostName && hostName[0]) {
+ secStatus = CERT_VerifyCertName( cert, hostName );
+ if( SECSuccess != secStatus ) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "myAuthCertificate: ",
+ "Server name does not match that in certificate" );
+ }
+ } else {
+ secStatus = SECFailure;
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "myAuthCertificate: ",
+ "server name has been specified" );
+ }
+
+ if( hostName != NULL ) {
+ PR_Free( hostName );
+ hostName = NULL;
+ }
+
+ return secStatus;
+}
+
+
+/* Function: SECStatus ownGetClientAuthData()
+ *
+ * Purpose: This callback is used by SSL to pull client certificate
+ * information upon server request.
+ */
+static SECStatus ownGetClientAuthData(void *arg, PRFileDesc *socket,
+ CERTDistNames *caNames,
+ CERTCertificate **pRetCert,/*return */
+ SECKEYPrivateKey **pRetKey) {
+ CERTCertificate * cert = NULL;
+ SECKEYPrivateKey * privKey = NULL;
+ void * proto_win = NULL;
+ SECStatus rv = SECFailure;
+ char * localNickName = (char *)arg;
+
+ proto_win = SSL_RevealPinArg(socket);
+
+ if (localNickName) {
+ RA::Debug( LL_PER_PDU,
+ "ownGetClientAuthData: ",
+ "ownGetClientAuthData looking for nickname=%s",
+ localNickName );
+ cert = PK11_FindCertFromNickname(localNickName, proto_win);
+ if (cert) {
+ RA::Debug( LL_PER_PDU,
+ "ownGetClientAuthData: ",
+ "ownGetClientAuthData found cert" );
+ privKey = PK11_FindKeyByAnyCert(cert, proto_win);
+ if (privKey) {
+ RA::Debug( LL_PER_PDU,
+ "ownGetClientAuthData: ",
+ "ownGetClientAuthData found priv key for cert" );
+ rv = SECSuccess;
+ } else {
+ if( cert != NULL ) {
+ CERT_DestroyCertificate( cert );
+ cert = NULL;
+ }
+ }
+ }
+ else {
+ RA::Debug( LL_PER_PDU,
+ "ownGetClientAuthData: ",
+ "ownGetClientAuthData did NOT find cert" );
+ }
+
+ if (rv == SECSuccess) {
+ *pRetCert = cert;
+ *pRetKey = privKey;
+ }
+
+ // if( localNickName != NULL ) {
+ // free( localNickName );
+ // localNickName = NULL;
+ // }
+ return rv;
+ }
+ else {
+ RA::Debug( LL_PER_PDU,
+ "ownGetClientAuthData: ",
+ "ownGetClientAuthData does not have nickname" );
+ }
+
+ char* chosenNickName = certName ? (char *)PL_strdup(certName) : NULL;
+ if (chosenNickName) {
+ cert = PK11_FindCertFromNickname(chosenNickName, proto_win);
+ if (cert) {
+ privKey = PK11_FindKeyByAnyCert(cert, proto_win);
+ if (privKey) {
+ rv = SECSuccess;
+ } else {
+ if( cert != NULL ) {
+ CERT_DestroyCertificate( cert );
+ cert = NULL;
+ }
+ }
+ }
+ } else {
+ /* no nickname given, automatically find the right cert */
+ CERTCertNicknames * names;
+ int i;
+
+ names = CERT_GetCertNicknames( CERT_GetDefaultCertDB(),
+ SEC_CERT_NICKNAMES_USER,
+ proto_win);
+
+ if (names != NULL) {
+ for( i=0; i < names->numnicknames; i++ ) {
+ cert = PK11_FindCertFromNickname(names->nicknames[i],
+ proto_win);
+ if (!cert) {
+ continue;
+ }
+
+ /* Only check unexpired certs */
+ if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_FALSE) !=
+ secCertTimeValid) {
+ if( cert != NULL ) {
+ CERT_DestroyCertificate( cert );
+ cert = NULL;
+ }
+ continue;
+ }
+
+ rv = NSS_CmpCertChainWCANames(cert, caNames);
+
+ if (rv == SECSuccess) {
+ privKey = PK11_FindKeyByAnyCert(cert, proto_win);
+ if (privKey) {
+ // got the key
+ break;
+ }
+
+ // cert database password was probably wrong
+ rv = SECFailure;
+ break;
+ };
+ } /* for loop */
+ CERT_FreeNicknames(names);
+ } // names
+ } // no nickname chosen
+
+ if (rv == SECSuccess) {
+ *pRetCert = cert;
+ *pRetKey = privKey;
+ }
+
+ if( chosenNickName != NULL ) {
+ free( chosenNickName );
+ chosenNickName = NULL;
+ }
+
+ return rv;
+}
+} // extern "C"
+
+void nodelay(PRFileDesc* fd) {
+ PRSocketOptionData opt;
+ PRStatus rv;
+
+ opt.option = PR_SockOpt_NoDelay;
+ opt.value.no_delay = PR_FALSE;
+
+ rv = PR_GetSocketOption(fd, &opt);
+ if (rv == PR_FAILURE) {
+ return;
+ }
+
+ opt.option = PR_SockOpt_NoDelay;
+ opt.value.no_delay = PR_TRUE;
+ rv = PR_SetSocketOption(fd, &opt);
+ if (rv == PR_FAILURE) {
+ return;
+ }
+
+ return;
+}
+
+
+void __EXPORT setDefaultAllTLSCiphers() {
+ int i =0;
+ char alg[256];
+ while (tlsSuites[i]) {
+ PR_snprintf((char *)alg, 256, "%x", tlsSuites[i]);
+ RA::Debug( LL_PER_PDU,
+ "setDefaultAllTLSCiphers",
+ alg);
+ SSL_CipherPrefSetDefault(tlsSuites[i++], PR_TRUE);
+ }
+}
+
+/**
+ * Returns a file descriptor for I/O if the HTTP connection is successful
+ * @param addr PRnetAddr structure which points to the server to connect to
+ * @param SSLOn boo;elan to state if this is an SSL client
+ */
+PRFileDesc * Engine::_doConnect(PRNetAddr *addr, PRBool SSLOn,
+ const PRInt32* cipherSuite,
+ PRInt32 count, const char *nickName,
+ PRBool handshake,
+ /*const SecurityProtocols& secprots,*/
+ const char *serverName, PRIntervalTime timeout) {
+//-- static const char *DEBUG_METHOD_NAME = "doConnect";
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( "httpclient");
+ PRFileDesc *tcpsock = NULL;
+ PRFileDesc *sock = NULL;
+
+ SSL_CipherPrefSetDefault(0xC005 /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA */, PR_TRUE);
+ setDefaultAllTLSCiphers();
+
+ tcpsock = PR_OpenTCPSocket(addr->raw.family);
+
+ if (nickName != NULL)
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "_doConnect has nickname=%s",
+ nickName );
+ else
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "_doConnect has nickname=NULL" );
+
+ if (!tcpsock) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+//XXXX log NSPR error code
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "PR_OpenTCPSocket returned NULL" );
+ return NULL;
+ }
+
+ nodelay(tcpsock);
+
+ if (PR_TRUE == SSLOn) {
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "SSL is ON" );
+ sock=SSL_ImportFD(NULL, tcpsock);
+ if (!sock) {
+ //xxx log
+ if( tcpsock != NULL ) {
+ PR_Close( tcpsock );
+ tcpsock = NULL;
+ }
+ return NULL;
+ }
+
+ int error = 0;
+ PRBool rv = SSL_OptionSet(sock, SSL_SECURITY, 1);
+ if ( SECSuccess == rv ) {
+ rv = SSL_OptionSet(sock, SSL_HANDSHAKE_AS_CLIENT, 1);
+ }
+ if ( SECSuccess == rv ) {
+ rv = SSL_OptionSet(sock, SSL_ENABLE_SSL3, PR_TRUE);
+ }
+ if ( SECSuccess == rv ) {
+ rv = SSL_OptionSet(sock, SSL_ENABLE_TLS, PR_TRUE);
+ }
+ if ( SECSuccess != rv ) {
+ error = PORT_GetError();
+ if( sock != NULL ) {
+ PR_Close( sock );
+ sock = NULL;
+ }
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "SSL_OptionSet error: %d",
+ error );
+ return NULL;
+ }
+
+ rv = SSL_GetClientAuthDataHook( sock,
+ ownGetClientAuthData,
+ (void*)nickName);
+ if ( SECSuccess != rv ) {
+ error = PORT_GetError();
+ if( sock != NULL ) {
+ PR_Close( sock );
+ sock = NULL;
+ }
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "SSL_GetClientAuthDataHook error: %d",
+ error );
+ return NULL;
+ }
+
+ rv = SSL_AuthCertificateHook(sock,
+ (SSLAuthCertificate)myAuthCertificate,
+ (void *)CERT_GetDefaultCertDB());
+
+ if (rv != SECSuccess ) {
+ if( sock != NULL ) {
+ PR_Close( sock );
+ sock = NULL;
+ }
+ return NULL;
+ }
+
+ PRErrorCode errCode = 0;
+
+ rv = SSL_BadCertHook( sock,
+ (SSLBadCertHandler)myBadCertHandler,
+ &errCode );
+ rv = SSL_SetURL( sock, serverName );
+
+ if (rv != SECSuccess ) {
+ error = PORT_GetError();
+ if( sock != NULL ) {
+ PR_Close( sock );
+ sock = NULL;
+ }
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "SSL_SetURL error: %d",
+ error );
+ return NULL;
+ }
+
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "end SSL is ON" );
+ //EnableAllTLSCiphers( sock);
+ //EnableAllSSL3Ciphers( sock);
+ } else {
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "SSL is OFF" );
+ sock = tcpsock;
+ }
+
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "about to call PR_Connect, timeout =%d",
+ timeout );
+
+ if ( PR_Connect(sock, addr, timeout) == PR_FAILURE ) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "PR_Connect error: %d Msg=%s",
+ PR_GetError(),
+ "XXX" );
+ if( sock != NULL ) {
+ PR_Close( sock );
+ sock = NULL;
+ }
+ return NULL;
+ }
+
+ return (sock);
+}
+
+/**
+ * Called from higher level to connect, sends a request
+ * and gets a response as an HttpResponse object
+ *
+ * @param request Contains the entire request url + headers etc
+ * @param server Has the host, port, protocol info
+ * @param timeout Time in seconds to wait for a response
+ * @return The response body and headers
+ */
+PSHttpResponse * HttpEngine::makeRequest( PSHttpRequest &request,
+ const PSHttpServer& server,
+ int timeout, PRBool expectChunked ) {
+ PRNetAddr addr;
+ PRFileDesc *sock = NULL;
+ PSHttpResponse *resp = NULL;
+
+ PRBool response_code = 0;
+
+ server.getAddr(&addr);
+
+ char *nickName = request.getCertNickName();
+
+ char *serverName = (char *)server.getAddr();
+ sock = _doConnect( &addr, request.isSSL(), 0, 0,nickName, 0, serverName );
+
+ if ( sock != NULL) {
+ PRBool status = request.send( sock );
+ if ( status ) {
+ resp = new PSHttpResponse( sock, &request, timeout, expectChunked );
+ response_code = resp->processResponse();
+
+ RA::Debug( LL_PER_PDU,
+ "HttpEngine::makeRequest: ",
+ "makeRequest response %d",
+ response_code );
+
+ if(!response_code)
+ {
+ RA::Debug( LL_PER_PDU,
+ "HttpEngine::makeRequest: ",
+ "Deleting response because of FALSE return, returning NULL." );
+ if( resp != NULL ) {
+ delete resp;
+ resp = NULL;
+ }
+ if( sock != NULL ) {
+ PR_Close( sock );
+ sock = NULL;
+ }
+
+ return NULL;
+
+ }
+ }
+ if( sock != NULL ) {
+ PR_Close( sock );
+ sock = NULL;
+ }
+ }
+
+ return resp;
+}
diff --git a/base/tps/src/httpClient/http.cpp b/base/tps/src/httpClient/http.cpp
new file mode 100644
index 000000000..60ca48bf5
--- /dev/null
+++ b/base/tps/src/httpClient/http.cpp
@@ -0,0 +1,307 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#include <string.h>
+
+#include "httpClient/httpc/http.h"
+#include "httpClient/httpc/engine.h"
+#include "httpClient/httpc/request.h"
+#include "httpClient/httpc/response.h"
+//-- #include "httpClient/httpc/DebugLogger.h"
+//-- #include "httpClient/httpc/ErrorLogger.h"
+#include "httpClient/httpc/PSPRUtil.h"
+#include "httpClient/httpc/Defines.h"
+#include "engine/RA.h"
+#include "main/Memory.h"
+
+
+//-- static const char *DEBUG_MODULE = "httpclient";
+//-- static const char *DEBUG_CLASS_NAME = "PSHttpServer";
+
+/**
+ * Constructor
+ * @param addr The hostname:port of the server to connect to. The default
+ * port is 80
+ * @param af The protocol family like PR_AF_INET
+ */
+PSHttpServer::PSHttpServer(const char *addr, PRUint16 af) {
+ SSLOn = PR_FALSE;
+ PRUint16 port = 80;
+//-- static const char *DEBUG_METHOD_NAME = "Constructor";
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( DEBUG_MODULE );
+
+ char *pPort;
+
+
+ _addr = NULL;
+// if( _addr != NULL ) {
+// PL_strfree( _addr );
+// _addr = NULL;
+// }
+
+ if (addr) {
+ _addr = PL_strdup(addr);
+ }
+
+ pPort = PL_strchr(_addr, ':');
+ if (pPort) {
+ *pPort = '\0';
+ port = (PRUint16) atoi(++pPort);
+ }
+
+ /* kludge for doing IPv6 tests on localhost */
+ if (!PL_strcmp(_addr, "ip6-localhost") && (af == PR_AF_INET6)) {
+ PL_strcpy(_addr, "::1");
+ }
+
+// PR_InitializeNetAddr(PR_IpAddrNull, port, &_netAddr);
+
+ if (PR_StringToNetAddr(_addr, &_netAddr) == PR_FAILURE) {
+ char buf[2000];
+ PRHostEnt ent;
+
+ RA::Debug( LL_PER_PDU,
+ "PSHttpServer::PSHttpServer ",
+ " host %s port %d ",_addr,port );
+ PR_InitializeNetAddr(PR_IpAddrNull, port, &_netAddr);
+ if (PR_GetIPNodeByName(_addr, af, PR_AI_DEFAULT,
+ buf, sizeof(buf), &ent) == PR_SUCCESS) {
+ PR_EnumerateHostEnt(0, &ent, port, &_netAddr);
+ } else {
+//-- ErrorLogger::GetErrorLogger()->Log(
+//-- LOGLEVEL_SEVERE, PR_GetError(),
+ RA::Debug( LL_PER_PDU,
+ "PSHttpServer::PSHttpServer: ",
+ "PR_GetIPNodeByName returned error %d [%s] for "
+ "address %s",
+ PR_GetError (),
+ "XXX",
+ addr );
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpServer::PSHttpServer: ",
+ "PR_GetIPNodeByName returned error %d [%s] for "
+ "address %s",
+ PR_GetError(),
+ "XXX",
+ addr );
+ }
+ }
+}
+
+/**
+ * Destructor of the Httpserver class
+ */
+PSHttpServer::~PSHttpServer() {
+ if( _addr != NULL ) {
+ PL_strfree( _addr );
+ _addr = NULL;
+ }
+}
+
+/**
+ * Turns SSL on or off for the connection
+ * @param SSLstate PR_TRUE to make an SSL connection
+ */
+void PSHttpServer::setSSL(PRBool SSLstate) {
+ SSLOn = SSLstate;
+}
+
+/**
+ * Returns the current SSL state for this PSHttpServer object
+ * @return PR_TRUE if SSL is enabled else PR_FALSE
+ */
+PRBool PSHttpServer::isSSL() const {
+ return SSLOn;
+}
+
+/**
+ * Returns the IP address of the HTTP server
+ * @return IP address of the server as a long
+ */
+
+long PSHttpServer::getIp() const {
+ return _netAddr.inet.ip;
+}
+
+/**
+ * Returns the port for the HTTP server
+ * @return port of the server
+ */
+
+long PSHttpServer::getPort() const {
+ return (long) PR_ntohs(_netAddr.inet.port);
+}
+
+/**
+ * Returns the server IP address as a string
+ * @return server address as string
+*/
+const char * PSHttpServer::getAddr() const {
+ return _addr;
+}
+
+/**
+ * Gets the server addr as a PR_NetAddr structure
+ * @param addr PR_netaddr struct in which server address is returned
+ */
+void PSHttpServer::getAddr(PRNetAddr *addr) const {
+ memcpy(addr, &_netAddr, sizeof(_netAddr));
+}
+
+/**
+ * Fets the protocol as string: "HTTP/1.0" "HTTP/1.1" etc
+ * @return Protocol string
+ */
+const char *HttpProtocolToString(HttpProtocol proto) {
+ switch(proto) {
+ case HTTP09:
+ return "";
+ case HTTP10:
+ return "HTTP/1.0";
+ case HTTP11:
+ return "HTTP/1.1";
+ case HTTPBOGUS:
+ return "BOGO-PROTO";
+ case HTTPNA:
+ return NULL;
+ }
+
+ return NULL;
+}
+
+/**
+* Constructor for HttpMessage. This is a base class for PSHttpRequest
+*/
+HttpMessage :: HttpMessage(long len, const char* buf) {
+ firstline = NULL;
+ cl = 0;
+ proto = HTTPNA;
+
+ // search for the first line
+ int counter=0;
+ PRBool found = PR_FALSE;
+ while ( ( (counter++<len) && (PR_FALSE == found) ) ) {
+ if (buf[counter] != '\n') {
+ continue;
+ }
+ found = PR_TRUE;
+ }
+
+ // extract the first line
+ if (PR_TRUE == found) {
+ firstline=new char[counter+1];
+ memcpy(firstline, buf, counter);
+ firstline[counter] = '\0';
+ }
+}
+
+HttpMessage :: ~HttpMessage() {
+ if( firstline != NULL ) {
+ delete firstline;
+ firstline = NULL;
+ }
+}
+
+/*SecurityProtocols :: SecurityProtocols(PRBool s2, PRBool s3, PRBool t)
+{
+ ssl2 = s2;
+ ssl3 = s3;
+ tls = t;
+};
+
+const SecurityProtocols& SecurityProtocols :: operator = (const RWTPtrSlist<char>& protlist)
+{
+ ssl2 = PR_FALSE;
+ ssl3 = PR_FALSE;
+ tls = PR_FALSE;
+ PRInt32 i;
+ for (i = 0;i<protlist.entries();i++)
+ {
+ if (0 == strcmp(protlist.at(i), "SSL2"))
+ {
+ ssl2 = PR_TRUE;
+ };
+ if (0 == strcmp(protlist.at(i), "SSL3"))
+ {
+ ssl3 = PR_TRUE;
+ };
+ if (0 == strcmp(protlist.at(i), "TLS"))
+ {
+ tls = PR_TRUE;
+ };
+ };
+ return *this;
+};
+
+const SecurityProtocols& SecurityProtocols :: operator = (const SecurityProtocols& rhs)
+{
+ ssl2 = rhs.ssl2;
+ ssl3 = rhs.ssl3;
+ tls = rhs.tls;
+ return *this;
+};
+*/
+
+
+PRBool PSHttpServer::putFile(const char* localFile,
+ const char* remoteUri) const {
+ PSHttpRequest request(this, remoteUri, HTTP10, Engine::globaltimeout);
+ request.setMethod("PUT");
+ request.useLocalFileAsBody(localFile);
+
+ PRBool rv = _putFile(request);
+ return rv;
+}
+
+PRBool PSHttpServer::putFile(const char *uri, int size) const {
+ PSHttpRequest request(this, uri, HTTP10, Engine::globaltimeout);
+ request.setMethod("PUT");
+ request.addRandomBody(size);
+
+ PRBool rv = _putFile(request);;
+ return rv;
+}
+
+PRBool PSHttpServer::_putFile(PSHttpRequest& request) const {
+ HttpEngine engine;
+ PRBool rv = PR_TRUE;
+
+ PSHttpResponse* response = engine.makeRequest(request, *this);
+
+ if (response) {
+ int status = response->getStatus();
+ if (status == 200 || status == 201 || status == 204) {
+ rv = PR_TRUE;
+ } else {
+ rv = PR_FALSE;
+ }
+ if( response != NULL ) {
+ delete response;
+ response = NULL;
+ }
+ } else {
+ rv = PR_FALSE;
+ }
+ return rv;
+}
+
diff --git a/base/tps/src/httpClient/httpClient.cpp b/base/tps/src/httpClient/httpClient.cpp
new file mode 100644
index 000000000..7f4e9fff3
--- /dev/null
+++ b/base/tps/src/httpClient/httpClient.cpp
@@ -0,0 +1,130 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "nspr.h"
+#include <sys/types.h>
+
+#include <stdio.h>
+#ifndef XP_WIN32
+#include <unistd.h> /* sleep */
+#else /* XP_WIN32 */
+#include <windows.h>
+#endif /* XP_WIN32 */
+
+#include "main/Base.h"
+#include "httpClient/httpc/http.h"
+#include "httpClient/httpc/request.h"
+#include "httpClient/httpc/response.h"
+#include "httpClient/httpc/engine.h"
+
+#include "engine/RA.h"
+#include "main/Memory.h"
+
+/*
+ * httpSend: sends to an HTTP server
+ * host_port should be in the for "host:port"
+ * e.g. ca.fedora.redhat.com:1027
+ * uri should contain uri including parameter values
+ * e.g. https://ca.fedora.redhat.com:1027/ca/profileSubmitSSLClient?profileId=userKey&screenname=user1&publickey=YWJjMTIzCg
+ * method has to be "GET" or "POST"
+ * body is the HTTP body. Can have nothing.
+ */
+PSHttpResponse *httpSend(char *host_port, char *uri, char *method, char *body)
+{
+ const char* nickname;
+ nickname = RA::GetConfigStore()->GetConfigAsString("ra.clientNickname", "");
+
+ char *pPort = NULL;
+ char *pPortActual = NULL;
+
+
+ char hostName[512];
+
+ /*
+ * Isolate the host name, account for IPV6 numeric addresses.
+ *
+ */
+
+ if(host_port)
+ strncpy(hostName,host_port,512);
+
+ pPort = hostName;
+ while(1) {
+ pPort = strchr(pPort, ':');
+ if (pPort) {
+ pPortActual = pPort;
+ pPort++;
+ } else
+ break;
+ }
+
+ if(pPortActual)
+ *pPortActual = '\0';
+
+
+ /*
+ * Rifle through the values for the host
+ */
+
+ PRAddrInfo *ai;
+ void *iter;
+ PRNetAddr addr;
+ int family = PR_AF_INET;
+
+ ai = PR_GetAddrInfoByName(hostName, PR_AF_UNSPEC, PR_AI_ADDRCONFIG);
+ if (ai) {
+ printf("%s\n", PR_GetCanonNameFromAddrInfo(ai));
+ iter = NULL;
+ while ((iter = PR_EnumerateAddrInfo(iter, ai, 0, &addr)) != NULL) {
+ char buf[512];
+ PR_NetAddrToString(&addr, buf, sizeof buf);
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::httpSend: ",
+ "Sending addr -- Msg='%s'\n",
+ buf );
+ family = PR_NetAddrFamily(&addr);
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::httpSend: ",
+ "Sending family -- Msg='%d'\n",
+ family );
+ break;
+ }
+ PR_FreeAddrInfo(ai);
+
+ }
+
+ PSHttpServer server(host_port, family);
+ server.setSSL(PR_TRUE);
+ // use "HTTP10" if no chunking
+ PSHttpRequest request( &server, uri, HTTP11, 0 );
+ request.setSSL(PR_TRUE);
+ request.setCertNickName(nickname);
+ request.setMethod(method);
+ if (body != NULL)
+ request.setBody( strlen(body), body);
+
+ // use with "POST" only
+ request.addHeader( "Content-Type", "text/xml" );
+ request.addHeader( "Connection", "keep-alive" );
+ HttpEngine engine;
+ PSHttpResponse *resp = engine.makeRequest( request, server, 120 /*_timeout*/ , PR_TRUE /* expect chunked*/);
+
+ return resp;
+}
diff --git a/base/tps/src/httpClient/nscperror.cpp b/base/tps/src/httpClient/nscperror.cpp
new file mode 100644
index 000000000..38c722de2
--- /dev/null
+++ b/base/tps/src/httpClient/nscperror.cpp
@@ -0,0 +1,358 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+/* nscperrors.c
+ * Very crude error handling for nspr and libsec.
+ */
+
+#include "prerror.h"
+
+#define NSCP_NSPR_ERROR_BASE (PR_NSPR_ERROR_BASE)
+#define NSCP_NSPR_MAX_ERROR ((PR_MAX_ERROR) - 1)
+#define NSCP_LIBSEC_ERROR_BASE (-8192)
+#define NSCP_LIBSEC_MAX_ERROR (NSCP_LIBSEC_ERROR_BASE + 118)
+#define NSCP_LIBSSL_ERROR_BASE (-12288)
+#define NSCP_LIBSSL_MAX_ERROR (NSCP_LIBSSL_ERROR_BASE + 89)
+
+typedef struct nscp_error_t {
+ int errorNumber;
+ const char *errorString;
+} nscp_error_t;
+
+nscp_error_t nscp_nspr_errors[] = {
+ { 0, "Out of memory" },
+ { 1, "Bad file descriptor" },
+ { 2, "Data temporarily not available" },
+ { 3, "Access fault" },
+ { 4, "Invalid method" },
+ { 5, "Illegal access" },
+ { 6, "Unknown error" },
+ { 7, "Pending interrupt" },
+ { 8, "Not implemented" },
+ { 9, "IO error" },
+ { 10, "IO timeout error" },
+ { 11, "IO already pending error" },
+ { 12, "Directory open error" },
+ { 13, "Invalid Argument" },
+ { 14, "Address not available" },
+ { 15, "Address not supported" },
+ { 16, "Already connected" },
+ { 17, "Bad address" },
+ { 18, "Address already in use" },
+ { 19, "Connection refused" },
+ { 20, "Network unreachable" },
+ { 21, "Connection timed out" },
+ { 22, "Not connected" },
+ { 23, "Load library error" },
+ { 24, "Unload library error" },
+ { 25, "Find symbol error" },
+ { 26, "Insufficient resources" },
+ { 27, "Directory lookup error" },
+ { 28, "Invalid thread private data key" },
+ { 29, "PR_PROC_DESC_TABLE_FULL_ERROR" },
+ { 30, "PR_SYS_DESC_TABLE_FULL_ERROR" },
+ { 31, "Descriptor is not a socket" },
+ { 32, "Descriptor is not a TCP socket" },
+ { 33, "Socket address is already bound" },
+ { 34, "No access rights" },
+ { 35, "Operation not supported" },
+ { 36, "Protocol not supported" },
+ { 37, "Remote file error" },
+ { 38, "Buffer overflow error" },
+ { 39, "Connection reset by peer" },
+ { 40, "Range error" },
+ { 41, "Deadlock error" },
+ { 42, "File is locked" },
+ { 43, "File is too big" },
+ { 44, "No space on device" },
+ { 45, "Pipe error" },
+ { 46, "No seek on device" },
+ { 47, "File is a directory" },
+ { 48, "Loop error" },
+ { 49, "Name too long" },
+ { 50, "File not found" },
+ { 51, "File is not a directory" },
+ { 52, "Read-only filesystem" },
+ { 53, "Directory not empty" },
+ { 54, "Filesystem mounted" },
+ { 55, "Not same device" },
+ { 56, "Directory corrupted" },
+ { 57, "File exists" },
+ { 58, "Maximum directory entries" },
+ { 59, "Invalid device state" },
+ { 60, "Device is locked" },
+ { 61, "No more files" },
+ { 62, "End of file" },
+ { 63, "File seek error" },
+ { 64, "File is busy" },
+ { 65, "NSPR error 65" },
+ { 66, "In progress error" },
+ { 67, "Already initiated" },
+ { 68, "Group empty" },
+ { 69, "Invalid state" },
+ { 70, "Network down" },
+ { 71, "Socket shutdown" },
+ { 72, "Connect aborted" },
+ { 73, "Host unreachable" }
+};
+
+#if (PR_MAX_ERROR - PR_NSPR_ERROR_BASE) > 74
+// cfu temporarily get rid of the "#error NSPR error table is too small" error
+//#error NSPR error table is too small
+#endif
+
+nscp_error_t nscp_libsec_errors[] = {
+ { 0, "SEC_ERROR_IO - I/O Error" },
+ { 1, "SEC_ERROR_LIBRARY_FAILURE - Library Failure" },
+ { 2, "SEC_ERROR_BAD_DATA - Bad data was received" },
+ { 3, "SEC_ERROR_OUTPUT_LEN" },
+ { 4, "SEC_ERROR_INPUT_LEN" },
+ { 5, "SEC_ERROR_INVALID_ARGS" },
+ { 6, "SEC_ERROR_INVALID_ALGORITHM - Certificate contains invalid encryption or signature algorithm" },
+ { 7, "SEC_ERROR_INVALID_AVA" },
+ { 8, "SEC_ERROR_INVALID_TIME - Certificate contains an invalid time value" },
+ { 9, "SEC_ERROR_BAD_DER - Certificate is improperly DER encoded" },
+ { 10, "SEC_ERROR_BAD_SIGNATURE - Certificate has invalid signature" },
+ { 11, "SEC_ERROR_EXPIRED_CERTIFICATE - Certificate has expired" },
+ { 12, "SEC_ERROR_REVOKED_CERTIFICATE - Certificate has been revoked" },
+ { 13, "SEC_ERROR_UNKNOWN_ISSUER - Certificate is signed by an unknown issuer" },
+ { 14, "SEC_ERROR_BAD_KEY - Invalid public key in certificate." },
+ { 15, "SEC_ERROR_BAD_PASSWORD" },
+ { 16, "SEC_ERROR_UNUSED" },
+ { 17, "SEC_ERROR_NO_NODELOCK" },
+ { 18, "SEC_ERROR_BAD_DATABASE - Problem using certificate or key database" },
+ { 19, "SEC_ERROR_NO_MEMORY - Out of Memory" },
+ { 20, "SEC_ERROR_UNTRUSTED_ISSUER - Certificate is signed by an untrusted issuer" },
+ { 21, "SEC_ERROR_UNTRUSTED_CERT" },
+ { 22, "SEC_ERROR_DUPLICATE_CERT" },
+ { 23, "SEC_ERROR_DUPLICATE_CERT_TIME" },
+ { 24, "SEC_ERROR_ADDING_CERT" },
+ { 25, "SEC_ERROR_FILING_KEY" },
+ { 26, "SEC_ERROR_NO_KEY" },
+ { 27, "SEC_ERROR_CERT_VALID" },
+ { 28, "SEC_ERROR_CERT_NOT_VALID" },
+ { 29, "SEC_ERROR_CERT_NO_RESPONSE" },
+ { 30, "SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE" },
+ { 31, "SEC_ERROR_CRL_EXPIRED" },
+ { 32, "SEC_ERROR_CRL_BAD_SIGNATURE" },
+ { 33, "SEC_ERROR_CRL_INVALID" },
+ { 34, "SEC_ERROR_EXTENSION_VALUE_INVALID" },
+ { 35, "SEC_ERROR_EXTENSION_NOT_FOUND" },
+ { 36, "SEC_ERROR_CA_CERT_INVALID" },
+ { 37, "SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID" },
+ { 38, "SEC_ERROR_CERT_USAGES_INVALID" },
+ { 39, "SEC_INTERNAL_ONLY" },
+ { 40, "SEC_ERROR_INVALID_KEY" },
+ { 41, "SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION" },
+ { 42, "SEC_ERROR_OLD_CRL" },
+ { 43, "SEC_ERROR_NO_EMAIL_CERT" },
+ { 44, "SEC_ERROR_NO_RECIPIENT_CERTS_QUERY" },
+ { 45, "SEC_ERROR_NOT_A_RECIPIENT" },
+ { 46, "SEC_ERROR_PKCS7_KEYALG_MISMATCH" },
+ { 47, "SEC_ERROR_PKCS7_BAD_SIGNATURE" },
+ { 48, "SEC_ERROR_UNSUPPORTED_KEYALG" },
+ { 49, "SEC_ERROR_DECRYPTION_DISALLOWED" },
+ { 50, "XP_SEC_FORTEZZA_BAD_CARD" },
+ { 51, "XP_SEC_FORTEZZA_NO_CARD" },
+ { 52, "XP_SEC_FORTEZZA_NONE_SELECTED" },
+ { 53, "XP_SEC_FORTEZZA_MORE_INFO" },
+ { 54, "XP_SEC_FORTEZZA_PERSON_NOT_FOUND" },
+ { 55, "XP_SEC_FORTEZZA_NO_MORE_INFO" },
+ { 56, "XP_SEC_FORTEZZA_BAD_PIN" },
+ { 57, "XP_SEC_FORTEZZA_PERSON_ERROR" },
+ { 58, "SEC_ERROR_NO_KRL" },
+ { 59, "SEC_ERROR_KRL_EXPIRED" },
+ { 60, "SEC_ERROR_KRL_BAD_SIGNATURE" },
+ { 61, "SEC_ERROR_REVOKED_KEY" },
+ { 62, "SEC_ERROR_KRL_INVALID" },
+ { 63, "SEC_ERROR_NEED_RANDOM" },
+ { 64, "SEC_ERROR_NO_MODULE" },
+ { 65, "SEC_ERROR_NO_TOKEN" },
+ { 66, "SEC_ERROR_READ_ONLY" },
+ { 67, "SEC_ERROR_NO_SLOT_SELECTED" },
+ { 68, "SEC_ERROR_CERT_NICKNAME_COLLISION" },
+ { 69, "SEC_ERROR_KEY_NICKNAME_COLLISION" },
+ { 70, "SEC_ERROR_SAFE_NOT_CREATED" },
+ { 71, "SEC_ERROR_BAGGAGE_NOT_CREATED" },
+ { 72, "XP_JAVA_REMOVE_PRINCIPAL_ERROR" },
+ { 73, "XP_JAVA_DELETE_PRIVILEGE_ERROR" },
+ { 74, "XP_JAVA_CERT_NOT_EXISTS_ERROR" },
+ { 75, "SEC_ERROR_BAD_EXPORT_ALGORITHM" },
+ { 76, "SEC_ERROR_EXPORTING_CERTIFICATES" },
+ { 77, "SEC_ERROR_IMPORTING_CERTIFICATES" },
+ { 78, "SEC_ERROR_PKCS12_DECODING_PFX" },
+ { 79, "SEC_ERROR_PKCS12_INVALID_MAC" },
+ { 80, "SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM" },
+ { 81, "SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE" },
+ { 82, "SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE" },
+ { 83, "SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM" },
+ { 84, "SEC_ERROR_PKCS12_UNSUPPORTED_VERSION" },
+ { 85, "SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT" },
+ { 86, "SEC_ERROR_PKCS12_CERT_COLLISION" },
+ { 87, "SEC_ERROR_USER_CANCELLED" },
+ { 88, "SEC_ERROR_PKCS12_DUPLICATE_DATA" },
+ { 89, "SEC_ERROR_MESSAGE_SEND_ABORTED" },
+ { 90, "SEC_ERROR_INADEQUATE_KEY_USAGE" },
+ { 91, "SEC_ERROR_INADEQUATE_CERT_TYPE" },
+ { 92, "SEC_ERROR_CERT_ADDR_MISMATCH" },
+ { 93, "SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY" },
+ { 94, "SEC_ERROR_PKCS12_IMPORTING_CERT_CHAIN" },
+ { 95, "SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME" },
+ { 96, "SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY" },
+ { 97, "SEC_ERROR_PKCS12_UNABLE_TO_WRITE" },
+ { 98, "SEC_ERROR_PKCS12_UNABLE_TO_READ" },
+ { 99, "SEC_ERROR_PKCS12_KEY_DATABASE_NOT_INITIALIZED" },
+ { 100, "SEC_ERROR_KEYGEN_FAIL" },
+ { 101, "SEC_ERROR_INVALID_PASSWORD" },
+ { 102, "SEC_ERROR_RETRY_OLD_PASSWORD" },
+ { 103, "SEC_ERROR_BAD_NICKNAME" },
+ { 104, "SEC_ERROR_NOT_FORTEZZA_ISSUER" },
+ { 105, "unused error" },
+ { 106, "SEC_ERROR_JS_INVALID_MODULE_NAME" },
+ { 107, "SEC_ERROR_JS_INVALID_DLL" },
+ { 108, "SEC_ERROR_JS_ADD_MOD_FAILURE" },
+ { 109, "SEC_ERROR_JS_DEL_MOD_FAILURE" },
+ { 110, "SEC_ERROR_OLD_KRL" },
+ { 111, "SEC_ERROR_CKL_CONFLICT" },
+ { 112, "SEC_ERROR_CERT_NOT_IN_NAME_SPACE" },
+ { 113, "SEC_ERROR_KRL_NOT_YET_VALID" },
+ { 114, "SEC_ERROR_CRL_NOT_YET_VALID" },
+ { 115, "SEC_ERROR_CERT_STATUS_SERVER_ERROR" },
+ { 116, "SEC_ERROR_CERT_STATUS_UNKNOWN" },
+ { 117, "SEC_ERROR_CERT_REVOKED_SINCE" },
+ { 118, "SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE" }
+};
+
+nscp_error_t nscp_libssl_errors[] = {
+ { 0, "SSL_ERROR_EXPORT_ONLY_SERVER - client does not support high-grade encryption." },
+ { 1, "SSL_ERROR_US_ONLY_SERVER - client requires high-grade encryption which is not supported." },
+ { 2, "SSL_ERROR_NO_CYPHER_OVERLAP - no common encryption algorithm(s) with client." },
+ { 3, "SSL_ERROR_NO_CERTIFICATE - unable to find the certificate or key necessary for authentication." },
+ { 4, "SSL_ERROR_BAD_CERTIFICATE - unable to communicate securely wih peer: peer's certificate was rejected." },
+ { 5, "unused SSL error #5" },
+ { 6, "SSL_ERROR_BAD_CLIENT - protocol error." },
+ { 7, "SSL_ERROR_BAD_SERVER - protocol error." },
+ { 8, "SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE - unsupported certificate type." },
+ { 9, "SSL_ERROR_UNSUPPORTED_VERSION - client is using unsupported SSL version." },
+ { 10, "unused SSL error #10" },
+ { 11, "SSL_ERROR_WRONG_CERTIFICATE - the public key in the server's own certificate does not match its private key" },
+ { 12, "SSL_ERROR_BAD_CERT_DOMAIN - requested domain name does not match the server's certificate." },
+ { 13, "SSL_ERROR_POST_WARNING" },
+ { 14, "SSL_ERROR_SSL2_DISABLED - peer only supports SSL version 2, which is locally disabled" },
+ { 15, "SSL_ERROR_BAD_MAC_READ - SSL has received a record with an incorrect Message Authentication Code." },
+ { 16, "SSL_ERROR_BAD_MAC_ALERT - SSL has received an error indicating an incorrect Message Authentication Code." },
+ { 17, "SSL_ERROR_BAD_CERT_ALERT - SSL client cannot verify your certificate." },
+ { 18, "SSL_ERROR_REVOKED_CERT_ALERT - the server has rejected your certificate as revoked." },
+ { 19, "SSL_ERROR_EXPIRED_CERT_ALERT - the server has rejected your certificate as expired." },
+ { 20, "SSL_ERROR_SSL_DISABLED - cannot connect: SSL is disabled." },
+ { 21, "SSL_ERROR_FORTEZZA_PQG - cannot connect: SSL peer is in another Fortezza domain" },
+ { 22, "SSL_ERROR_UNKNOWN_CIPHER_SUITE - an unknown SSL cipher suite has been requested" },
+ { 23, "SSL_ERROR_NO_CIPHERS_SUPPORTED - no cipher suites are present and enabled in this program" },
+ { 24, "SSL_ERROR_BAD_BLOCK_PADDING" },
+ { 25, "SSL_ERROR_RX_RECORD_TOO_LONG" },
+ { 26, "SSL_ERROR_TX_RECORD_TOO_LONG" },
+ { 27, "SSL_ERROR_RX_MALFORMED_HELLO_REQUEST" },
+ { 28, "SSL_ERROR_RX_MALFORMED_CLIENT_HELLO" },
+ { 29, "SSL_ERROR_RX_MALFORMED_SERVER_HELLO" },
+ { 30, "SSL_ERROR_RX_MALFORMED_CERTIFICATE" },
+ { 31, "SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH" },
+ { 32, "SSL_ERROR_RX_MALFORMED_CERT_REQUEST" },
+ { 33, "SSL_ERROR_RX_MALFORMED_HELLO_DONE" },
+ { 34, "SSL_ERROR_RX_MALFORMED_CERT_VERIFY" },
+ { 35, "SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH" },
+ { 36, "SSL_ERROR_RX_MALFORMED_FINISHED" },
+ { 37, "SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER" },
+ { 38, "SSL_ERROR_RX_MALFORMED_ALERT" },
+ { 39, "SSL_ERROR_RX_MALFORMED_HANDSHAKE" },
+ { 40, "SSL_ERROR_RX_MALFORMED_APPLICATION_DATA" },
+ { 41, "SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST" },
+ { 42, "SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO" },
+ { 43, "SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO" },
+ { 44, "SSL_ERROR_RX_UNEXPECTED_CERTIFICATE" },
+ { 45, "SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH" },
+ { 46, "SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST" },
+ { 47, "SSL_ERROR_RX_UNEXPECTED_HELLO_DONE" },
+ { 48, "SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY" },
+ { 49, "SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH" },
+ { 50, "SSL_ERROR_RX_UNEXPECTED_FINISHED" },
+ { 51, "SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER" },
+ { 52, "SSL_ERROR_RX_UNEXPECTED_ALERT" },
+ { 53, "SSL_ERROR_RX_UNEXPECTED_HANDSHAKE" },
+ { 54, "SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA" },
+ { 55, "SSL_ERROR_RX_UNKNOWN_RECORD_TYPE" },
+ { 56, "SSL_ERROR_RX_UNKNOWN_HANDSHAKE" },
+ { 57, "SSL_ERROR_RX_UNKNOWN_ALERT" },
+ { 58, "SSL_ERROR_CLOSE_NOTIFY_ALERT - SSL peer has closed the connection" },
+ { 59, "SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT" },
+ { 60, "SSL_ERROR_DECOMPRESSION_FAILURE_ALERT" },
+ { 61, "SSL_ERROR_HANDSHAKE_FAILURE_ALERT" },
+ { 62, "SSL_ERROR_ILLEGAL_PARAMETER_ALERT" },
+ { 63, "SSL_ERROR_UNSUPPORTED_CERT_ALERT" },
+ { 64, "SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT" },
+ { 65, "SSL_ERROR_GENERATE_RANDOM_FAILURE" },
+ { 66, "SSL_ERROR_SIGN_HASHES_FAILURE" },
+ { 67, "SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE" },
+ { 68, "SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE" },
+ { 69, "SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE" },
+ { 70, "SSL_ERROR_ENCRYPTION_FAILURE" },
+ { 71, "SSL_ERROR_DECRYPTION_FAILURE" },
+ { 72, "SSL_ERROR_SOCKET_WRITE_FAILURE" },
+ { 73, "SSL_ERROR_MD5_DIGEST_FAILURE" },
+ { 74, "SSL_ERROR_SHA_DIGEST_FAILURE" },
+ { 75, "SSL_ERROR_MAC_COMPUTATION_FAILURE" },
+ { 76, "SSL_ERROR_SYM_KEY_CONTEXT_FAILURE" },
+ { 77, "SSL_ERROR_SYM_KEY_UNWRAP_FAILURE" },
+ { 78, "SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED" },
+ { 79, "SSL_ERROR_IV_PARAM_FAILURE" },
+ { 80, "SSL_ERROR_INIT_CIPHER_SUITE_FAILURE" },
+ { 81, "SSL_ERROR_SESSION_KEY_GEN_FAILURE" },
+ { 82, "SSL_ERROR_NO_SERVER_KEY_FOR_ALG" },
+ { 83, "SSL_ERROR_TOKEN_INSERTION_REMOVAL" },
+ { 84, "SSL_ERROR_TOKEN_SLOT_NOT_FOUND" },
+ { 85, "SSL_ERROR_NO_COMPRESSION_OVERLAP" },
+ { 86, "SSL_ERROR_HANDSHAKE_NOT_COMPLETED" },
+ { 87, "SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE" },
+ { 88, "SSL_ERROR_CERT_KEA_MISMATCH" },
+ { 89, "SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA - the CA that signed the client certificate is not trusted locally" }
+};
+
+#ifdef WIN32
+#define __EXPORT __declspec(dllexport)
+#else
+#define __EXPORT
+#endif
+
+__EXPORT const char* nscperror_lookup(int error)
+{
+ const char *errmsg;
+
+ if ((error >= NSCP_NSPR_ERROR_BASE) && (error <= NSCP_NSPR_MAX_ERROR)) {
+ errmsg = nscp_nspr_errors[error-NSCP_NSPR_ERROR_BASE].errorString;
+ return errmsg;
+ } else if ((error >= NSCP_LIBSEC_ERROR_BASE) &&
+ (error <= NSCP_LIBSEC_MAX_ERROR)) {
+ return nscp_libsec_errors[error-NSCP_LIBSEC_ERROR_BASE].errorString;
+ } else if ((error >= NSCP_LIBSSL_ERROR_BASE) &&
+ (error <= NSCP_LIBSSL_MAX_ERROR)) {
+ return nscp_libssl_errors[error-NSCP_LIBSSL_ERROR_BASE].errorString;
+ } else {
+ return (const char *)NULL;
+ }
+}
diff --git a/base/tps/src/httpClient/request.cpp b/base/tps/src/httpClient/request.cpp
new file mode 100644
index 000000000..629f74821
--- /dev/null
+++ b/base/tps/src/httpClient/request.cpp
@@ -0,0 +1,431 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#include <string.h>
+#include "httpClient/httpc/request.h"
+#include "httpClient/httpc/engine.h"
+#include "httpClient/httpc/PSPRUtil.h"
+#include "engine/RA.h"
+#include "main/Memory.h"
+
+//-- static const char *DEBUG_MODULE = "httpclient";
+//-- static const char *DEBUG_CLASS_NAME = "PSHttpRequest";
+
+/**
+ * Constructor
+ * @param server The server to send request to
+ * @param uri The uri representing the request e.g /presence/start
+ * @param prot HTTP10 or HTTP11 .
+ * @param to Timeout ... ignore for now
+ */
+
+PSHttpRequest::PSHttpRequest(const PSHttpServer* server,
+ const char *uri,
+ HttpProtocol prot,
+ PRIntervalTime to) : NetRequest(server) {
+ //timeout = to;
+ timeout = PR_INTERVAL_NO_TIMEOUT;
+ _method = PL_strdup("GET");
+ _uri = PL_strdup(uri);
+ _proto = prot;
+ _body = NULL;
+ _bodyLength = -1;
+ _expectedResponseLength = -1;
+ _expectStandardBody = PR_FALSE;
+ _expectDynamicBody = PR_FALSE;
+ _hangupOk = PR_FALSE;
+ _fileFd = NULL;
+ nickName = NULL;
+ _headers = new StringKeyCache("request",10*60);
+}
+
+/**
+ * Destructor
+ *
+ */
+
+PSHttpRequest::~PSHttpRequest() {
+ if( _method != NULL ) {
+ PL_strfree( _method );
+ _method = NULL;
+ }
+ if( _uri != NULL ) {
+ PL_strfree( _uri );
+ _uri = NULL;
+ }
+ if( nickName != NULL ) {
+ PL_strfree( nickName );
+ nickName = NULL;
+ }
+ if( _fileFd != NULL ) {
+ PR_Close( _fileFd );
+ _fileFd = NULL;
+ }
+ if( _headers != NULL ) {
+ delete _headers;
+ _headers = NULL;
+ }
+}
+
+/**
+ * sets the request method for Http protocol
+ * @param method GET /POST etc
+ *
+ */
+
+PRBool PSHttpRequest::setMethod(const char *method) {
+ if( _method != NULL ) {
+ free( _method );
+ _method = NULL;
+ }
+ _method = PL_strdup(method);
+ return PR_TRUE;
+}
+
+void PSHttpRequest::setExpectedResponseLength(int size) {
+ _expectedResponseLength = size;
+}
+
+void PSHttpRequest::setExpectStandardBody() {
+ _expectStandardBody = PR_TRUE;
+}
+
+void PSHttpRequest::setExpectDynamicBody() {
+ _expectDynamicBody = PR_TRUE;
+}
+
+PRBool PSHttpRequest::getExpectStandardBody() {
+ return _expectStandardBody;
+}
+
+PRBool PSHttpRequest::getExpectDynamicBody() {
+ return _expectDynamicBody;
+}
+
+int PSHttpRequest::getExpectedResponseLength() {
+ return _expectedResponseLength;
+}
+
+/**
+ * Returns the method to use
+ *
+ * @return GET /POST etc
+ */
+
+char * PSHttpRequest::getMethod() {
+ return _method;
+}
+
+/**
+ * Returns HTTP0 or HTTP11
+ */
+HttpProtocol HttpMessage::getProtocol() const {
+ return proto;
+}
+
+/**
+ * Adds an HTTP header to the request
+ *
+ * @param name header name
+ * @param value header value
+ */
+PRBool PSHttpRequest::addHeader(const char *name, const char *value) {
+ char *dvalue = PL_strdup(value);
+ CacheEntry *entry = _headers->Put(name,dvalue);
+ if (entry == NULL ) {
+ if( dvalue != NULL ) {
+ PL_strfree( dvalue );
+ dvalue = NULL;
+ }
+ return PR_FALSE;
+ } else {
+ return PR_TRUE;
+ }
+}
+
+/**
+ * Gets the value for a header for this HTTP request object
+ *
+ * @param name Name of the header
+ * @return The value of the header in the request object
+ */
+
+const char * PSHttpRequest::getHeader(const char *name) {
+ CacheEntry *entry = _headers->Get(name);
+ return entry ? (char *)entry->GetData() : NULL;
+}
+
+/**
+ * Sets the body of a POST message
+ *
+ * @param size Content length
+ * @param body Content of the message; it is not copied
+ * @return PR_TRUE if the Content-length header can be set
+ */
+PRBool PSHttpRequest::setBody(int size, const char* body) {
+ char byteStr[12];
+
+ sprintf(byteStr, "%d", size);
+ if (!addHeader("Content-length", byteStr)) {
+ return PR_FALSE;
+ }
+
+ _bodyLength = size;
+ _body = (char *)body;
+
+ return PR_TRUE;
+}
+
+PRBool PSHttpRequest::addRandomBody(int size) {
+ char byteStr[12];
+
+ sprintf(byteStr, "%d", size);
+ if (!addHeader("Content-length", byteStr)) {
+ return PR_FALSE;
+ }
+
+ _bodyLength = size;
+
+ return PR_TRUE;
+}
+
+PRBool PSHttpRequest::useLocalFileAsBody(const char* fileName) {
+ PRBool res = PR_FALSE;
+ PRFileInfo finfo;
+ if (PR_GetFileInfo(fileName, &finfo) == PR_SUCCESS) {
+ res = PR_TRUE;
+ char byteStr[25];
+ sprintf(byteStr, "%d", finfo.size);
+ if (!addHeader("Content-length", byteStr)) {
+ return PR_FALSE;
+ }
+ _bodyLength = finfo.size;
+ _fileFd = PR_Open(fileName, PR_RDONLY, 0);
+ if (!_fileFd) {
+ return PR_FALSE;
+ }
+ }
+
+ return PR_TRUE;
+}
+
+/**
+ * This function sends the HTTP request to the server.
+ * @param sock - the connection onto which the request is to be sent
+ */
+
+PRBool PSHttpRequest::send( PRFileDesc *sock ) {
+ const char *hostname;
+//-- static const char *DEBUG_METHOD_NAME = "send";
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( DEBUG_MODULE );
+
+ PRBool rv = PR_FALSE;
+ if (!sock) {
+ return rv;
+ }
+
+ char *data = NULL;
+
+ if (_proto == HTTP11) {
+ hostname = getHeader("Host");
+
+ if (hostname == NULL) {
+ // long port = _server->getPort();
+
+ char address[100];
+ PR_snprintf(address, 100, "%s:%d", _server->getAddr(),
+ _server->getPort());
+ addHeader("Host", address);
+ }
+ }
+
+ // create the HTTP string "GET /presence/stop HTTP/1.0"
+ char *path = strstr( _uri, "//" );
+ if ( path ) {
+ path = strchr( path + 2, '/' );
+ }
+ if ( !path ) {
+ path = _uri;
+ }
+ data = PR_smprintf( "%s %s %s\r\n", _method, path,
+ HttpProtocolToString(_proto) );
+
+ // Send HTTP headers
+ char **keys;
+ char *headerValue = NULL;
+ int nKeys = _headers->GetKeys( &keys );
+ for ( int i = 0 ; i < nKeys; i++ ) {
+ CacheEntry *entry = _headers->Get( keys[i] );
+ if (entry) {
+ headerValue = (char *)entry->GetData();
+ //adds the headers name: value
+ data = PR_sprintf_append(data,"%s: %s\r\n",keys[i],headerValue);
+ if( headerValue != NULL ) {
+ PL_strfree( headerValue );
+ headerValue = NULL;
+ }
+ }
+ entry = _headers->Remove(keys[i]);
+ if( entry != NULL ) {
+ delete entry;
+ entry = NULL;
+ }
+ if( keys[i] != NULL ) {
+ delete [] ( keys[i] );
+ keys[i] = NULL;
+ }
+ }
+ if( keys != NULL ) {
+ delete [] keys;
+ keys = NULL;
+ }
+
+ // Send terminator
+ data = PR_sprintf_append(data,"\r\n");
+
+ int len = PL_strlen(data);
+ //send the data ..
+ int bytes = PR_Send(sock, data, len, 0, timeout);
+ if( data != NULL ) {
+ PR_smprintf_free( data );
+ data = NULL;
+ }
+ if ( bytes != len ) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpRequest::send: ",
+ "Error sending request -- PR_Send returned(%d) Msg=%s\n",
+ PR_GetError(),
+ "XXX" );
+ return PR_FALSE;
+ }
+
+ if ( _fileFd ) {
+ // Send body from file
+ PRInt32 bytesSent = PR_TransmitFile(sock, _fileFd, 0, 0,
+ PR_TRANSMITFILE_KEEP_OPEN,
+ timeout);
+ if ( bytesSent < 0 ) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpRequest::send: ",
+ "Error sending request\n" );
+ return PR_FALSE;
+ }
+ } else if (_bodyLength > 0) {
+ // Send internally stored body
+ char *allocated = NULL;
+ if ( !_body ) {
+ // Send a generated pattern
+ _body = allocated = new char[_bodyLength];
+ for ( int index = 0; index < _bodyLength; index++ ) {
+ _body[index] = (unsigned char)(index %256);
+ }
+ }
+ int sentBytes = 0;
+ char *toSend = _body;
+ for ( int i = _bodyLength; i > 0; i -= sentBytes ) {
+ sentBytes = PR_Send( sock, toSend, i, 0, timeout );
+ if ( sentBytes < 0 ) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpRequest::send: ",
+ "Error sending request in PR_Send\n" );
+ return PR_FALSE;
+ }
+ toSend += sentBytes;
+ }
+ if ( allocated ) {
+ if( _body != NULL ) {
+ delete [] _body;
+ _body = NULL;
+ }
+ }
+ }
+
+ return PR_TRUE;
+}
+
+/**
+ * Sets the nickname for the client cert to be send to the server
+ * @param certName Nickname of the cert in the cert db
+ */
+void PSHttpRequest::setCertNickName(const char *certName) {
+ nickName = PL_strdup(certName);
+}
+
+/**
+ * Gets the nickname for the client cert
+ * @return certName Nickname of the cert in the cert db
+ */
+char * PSHttpRequest::getCertNickName() {
+ return nickName;
+}
+
+void PSHttpRequest::setHangupOk() {
+ _hangupOk = PR_TRUE;
+}
+
+PRBool PSHttpRequest::isHangupOk() {
+ return(_hangupOk);
+}
+
+
+/**
+ * returns PR_TRUE if ssl is enabled for this request
+ */
+PRBool NetRequest::isSSL() const {
+ return SSLOn;
+}
+
+/**
+ * enable/disable SSL for the request
+ */
+void NetRequest::setSSL(PRBool SSLstate) {
+ SSLOn=SSLstate;
+}
+
+/**
+* Constructor for NetRequest class. This is a superclass of httprequest class
+* @param server The server to which the request is to be send
+*/
+NetRequest :: NetRequest(const PSHttpServer* server) {
+ _server = server;
+ timeout = Engine::globaltimeout;
+ SSLOn=PR_FALSE;
+ if (server)
+ SSLOn=server->isSSL();
+ handshake = PR_FALSE;
+ cipherCount = 0;
+ cipherSet = NULL;
+
+}
+
+/**
+* Returns the current configured timeout
+*/
+PRIntervalTime NetRequest :: getTimeout() const {
+ return timeout;
+}
diff --git a/base/tps/src/httpClient/response.cpp b/base/tps/src/httpClient/response.cpp
new file mode 100644
index 000000000..89b900492
--- /dev/null
+++ b/base/tps/src/httpClient/response.cpp
@@ -0,0 +1,1115 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+/**
+ * HTTP response handler
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <math.h>
+
+#include "nspr.h"
+#include "engine/RA.h"
+#include "main/Util.h"
+#include "httpClient/httpc/response.h"
+#include "httpClient/httpc/engine.h"
+//-- #include "httpClient/httpc/DebugLogger.h"
+#include "httpClient/httpc/PSPRUtil.h"
+#include "main/Memory.h"
+
+//-- static const char *DEBUG_MODULE = "httpclient";
+//-- static const char *DEBUG_CLASS_NAME = "PSHttpResponse";
+void printBuf(int , char* );
+
+/**
+ * Constructor. This class is used by the HttpResponse class for reading and
+ * processing data from the socket
+ * @param socket The NSPR socket from which the response is expected
+ * @param size The size of the internal buffer to hold data
+ * @param timeout Timeout in seconds on receiving a response
+ */
+
+RecvBuf::RecvBuf( const PRFileDesc *socket, int size, int timeout ) {
+ _socket = socket;
+ _allocSize = size;
+ _buf = (char *)PR_Malloc(size);
+ _curPos = 0;
+ _curSize = 0;
+ _chunkedMode = PR_FALSE;
+ _currentChunkSize = _currentChunkBytesRead = 0;
+ _timeout = PR_TicksPerSecond() * timeout;
+ _content = NULL;
+}
+
+/**
+ * Destructor
+ */
+RecvBuf::~RecvBuf() {
+ if( _buf != NULL ) {
+ PR_Free( _buf );
+ _buf = NULL;
+ }
+}
+
+/**
+ * Reads the specified number of bytes from the socket and place it into the buffer
+ *
+ * @param socket The NSPR socket from which the response is expected
+ * @param size The size of the buffer
+ * @return PR_TRUE on success, otherwise PR_FALSE
+ */
+PRBool RecvBuf::_getBytes(int size) {
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( DEBUG_MODULE );
+ PRErrorCode pec;
+ _curPos = 0;
+
+ int num =1;
+ int i =0;
+ PRBool endChunk= PR_FALSE;
+ RA::Debug( LL_PER_PDU,
+ "RecvBuf::_getBytes: ",
+ "Start RecvBuf::_getBytes" );
+ // actual reading from the socket happens here
+ do {
+ num = PR_Recv( (PRFileDesc*)_socket,
+ &_buf[_curSize],
+ _allocSize-_curSize,
+ 0,
+ _timeout );
+ RA::Debug( LL_PER_PDU,
+ "RecvBuf::_getBytes: ",
+ "num of bytes read from the socket=%d",
+ num );
+ /*
+ * in chunked mode, ending chunk contains a 0 to begin
+ * loop through to see if it contains just 0 (skip carriage returns
+ * endChunk indicates possible end chunk.
+ */
+ if ((_chunkedMode == PR_TRUE) && (num < 10)) {
+ endChunk = PR_FALSE;
+
+ for (i=0; i< num; i++) {
+ if (endChunk == PR_TRUE) {
+ if ((_buf[_curSize+i] == 13) || (_buf[_curSize+i] == 10))
+ continue;
+ else {
+ endChunk = PR_FALSE;
+ break; // not an endChunk
+ }
+ } else { // endChunk==PR_FALSE
+ if (_buf[_curSize+i] == '0') {
+ RA::Debug( LL_PER_PDU,
+ "RecvBuf::_getBytes: ",
+ "may be chunked mode end chunk" );
+ endChunk = PR_TRUE;
+ } else if ((_buf[_curSize+i] == 13) || (_buf[_curSize+i] == 10))
+ continue;
+ else {
+ endChunk = PR_FALSE;
+ break; // not an endChunk
+ }
+ }
+ } // for
+ }
+
+ if (num >0)
+ _curSize = _curSize+num;
+
+ if (_chunkedMode == PR_FALSE) {
+ if (getAllContent()) {
+ RA::Debug( LL_PER_PDU,
+ "RecvBuf::_getBytes: ",
+ "Already got all the content, no need to call PR_Recv again." );
+ break;
+ }
+ }
+
+ if (endChunk == PR_TRUE)
+ break;
+ } while (num > 0);
+
+ if (num <0) {
+ pec = PR_GetError();
+ RA::Debug( LL_PER_PDU,
+ "RecvBuf::_getBytes: ",
+ "error in pr_recv, err=%d",
+ pec );
+ }
+
+ if ( _curSize <= 0 ) {
+ return PR_FALSE;
+ }
+
+ _buf[_curSize] = '\0';
+//-- logger->Log( LOGLEVEL_FINEST, DEBUG_CLASS_NAME,
+//-- "getBytes",
+
+ _content = (char *) PR_Malloc(_curSize+1);
+ if (_content == NULL) {
+ return PR_FALSE;
+ }
+ memcpy((char*) _content, (const char *)_buf, _curSize+1);
+ _contentSize = _curSize +1;
+
+ RA::Debug(LL_PER_PDU, "RecvBuf::_getBytes",
+ "buffer received with size %d follows:", _contentSize);
+ printBuf(_contentSize, _content);
+
+ return PR_TRUE;
+}
+
+int RecvBuf::getAllContent() {
+ //int result[10];
+ //int j=0;
+ //int k=0;
+ int number = 0;
+ for (int i=0; i<_curSize; i++) {
+ if (_buf[i] == '\r') {
+ if (i < (_curSize-3)) {
+ if (_buf[i+1] == '\n' && _buf[i+2] == '\r'
+ && _buf[i+3] == '\n') {
+ // find content length
+// strcasestr may not be supported by Solaris
+// char *clen = strcasestr(_buf, "Content-length:");
+ char *clen = strstr(_buf, "Content-Length:");
+ if (clen != NULL) {
+ clen = &clen[16];
+ number = atoi(clen);
+/*
+ while (1) {
+ if ((number=Util::ascii2numeric(clen[j++])) >= 0) {
+ result[k++] = number;
+ } else {
+ break;
+ }
+ }
+
+ number = 0;
+ for (int l=0; l<k; l++)
+ number = (int)(number + result[l]*(float)pow((float)10, (float)k-l-1));
+*/
+ RA::Debug( LL_PER_PDU,
+ "RecvBuf::getAllContent: ",
+ "content length number=%d",
+ number );
+ }
+ int remainingBytes = _curSize - (i+4);
+ RA::Debug( LL_PER_PDU,
+ "RecvBuf::getAllContent: ",
+ "remainingbytes=%d",
+ remainingBytes );
+ if (remainingBytes == number)
+ return 1;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+void printBuf(int len, char* buf) {
+ RA::Debug(LL_PER_PDU, "response:printBuf",
+ "Buffer print begins");
+ RA::Debug(LL_PER_PDU, "response::printBuf",
+ "%s", buf);
+ RA::Debug(LL_PER_PDU, "response:printBuf",
+ "Buffer print end");
+ /*
+ int times = len/256;
+ if (len%256)
+ times++;
+ RA::Debug("response:printBuf",
+ "%d times", times);
+ RA::Debug("response:printBuf",
+ "attempting to print the whole buffer:");
+
+ int i;
+
+ for (i = 0; i< times; i++) {
+ char *temp;
+ temp = PL_strdup((char *)buf+i*256);
+ RA::Debug("response:printBuf",
+ "%s", temp);
+ }
+ */
+}
+
+/**
+ * gets the next char from the buffer. If all the data in the buffer is read,
+ * read a chunk to the buffer
+ * @returns - the next char from the data
+ */
+char RecvBuf::_getChar() {
+ if (_curPos >= _curSize) {
+ if (!_getBytes(_allocSize)) {
+ /* bugscape #55624: Solaris RA exited
+ with a signal ABRT if we raised exception
+ without handling it */
+ return -1;
+ /* throw RecvBuf::EndOfFile(); */
+ }
+ }
+
+ return _buf[_curPos++];
+}
+
+
+/**
+ * gets the next char from the buffer. If all the data in the buffer is read ,
+ * read a chunk to the buffer
+ * @returns - the next char from the data
+ */
+char RecvBuf::getChar() {
+ if (!_chunkedMode)
+ return _getChar();
+
+ else
+ {
+ if (_currentChunkSize == 0)
+ {
+ // read the chunk header
+ char ch, chunkStr[20];
+ int index = 0;
+
+ while (!isspace(ch = _getChar()) )
+ chunkStr[index++] = ch;
+ chunkStr[index] = '\0';
+
+ sscanf((char *)chunkStr, "%x", (unsigned int *)(&_currentChunkSize));
+
+ if (ch != '\n')
+ {
+ char ch2 = _getChar();
+ if (ch != '\r' || ch2 != '\n')
+ {
+ printf( "did not find CRLF after chunk");
+ }
+ }
+
+ if (_currentChunkSize == 0)
+ return -1;
+
+ _currentChunkBytesRead = 1;
+ return _buf[_curPos++];
+ }
+ else
+ if (_currentChunkBytesRead < _currentChunkSize)
+ {
+ // read a byte from the chunk
+ _currentChunkBytesRead++;
+ return _getChar();
+ }
+ else
+ {
+ // read the chunk trailer
+ char ch1 = _getChar();
+ char ch2 = _getChar();
+ if (ch1 != '\r' || ch2 != '\n')
+ {
+ printf( "did not find CRLF after chunk");
+ };
+ _currentChunkSize = _currentChunkBytesRead = 0;
+ return getChar();
+ };
+ };
+
+}
+
+char *RecvBuf::get_content() {
+ return _content;
+}
+
+int RecvBuf::get_contentSize() {
+ return _contentSize;
+}
+
+/**
+ * Decrements the pointer to the internal buffer so that the next read would
+ * retrieve the last data again
+ */
+void RecvBuf::putBack() {
+ if (_curPos > 0) {
+ _curPos--;
+ if (_chunkedMode) {
+ _currentChunkBytesRead--;
+ }
+ }
+}
+
+/**
+ * Sets the chunked mode for reading data
+ * Not used now..
+ */
+void RecvBuf::setChunkedMode() {
+ _chunkedMode = PR_TRUE;
+ _currentChunkSize = _currentChunkBytesRead = 0;
+}
+
+/**
+ * Gets the timeout in seconds for reading
+ *
+ * @return The timeout in seconds for reading
+ */
+int RecvBuf::getTimeout() {
+ return _timeout / PR_TicksPerSecond();
+}
+
+
+Response::Response(const PRFileDesc *sock, NetRequest *request) {
+ _socket = sock;
+ _request = request;
+}
+
+/**
+ * Constructor
+ */
+
+PSHttpResponse::PSHttpResponse( const PRFileDesc *sock,
+ PSHttpRequest *request,
+ int timeout , PRBool expectChunked):
+ Response(sock, request) {
+ _request = request;
+ _proto = HTTPNA;
+ _protocol = NULL;
+ retcode =0 ;
+ _statusNum = NULL;
+ _statusString = NULL;
+ _keepAlive = -1;
+ _connectionClosed = 0;
+ _bodyLength = -1;
+ _content = NULL;
+
+ _headers = new StringKeyCache("response",10*60);
+ _expectChunked = expectChunked;
+ _chunkedResponse = PR_FALSE;
+ _timeout = timeout;
+}
+
+PSHttpResponse::~PSHttpResponse() {
+ if( _protocol != NULL ) {
+ PL_strfree( _protocol );
+ _protocol = NULL;
+ }
+ if( _statusString != NULL ) {
+ PL_strfree( _statusString );
+ _statusString = NULL;
+ }
+ if( _statusNum != NULL ) {
+ PL_strfree( _statusNum );
+ _statusNum = NULL;
+ }
+ if (_headers) {
+ Iterator* iterator = _headers->GetKeyIterator();
+ while ( iterator->HasMore() ) {
+ const char* name = (const char*)iterator->Next();
+ CacheEntry* entry = _headers->Remove( name );
+ if ( entry ) {
+ char* value = (char*)entry->GetData();
+ if( value != NULL ) {
+ PL_strfree( value );
+ value = NULL;
+ }
+ if( entry != NULL ) {
+ delete entry;
+ entry = NULL;
+ }
+ }
+ }
+ if( iterator != NULL ) {
+ delete iterator;
+ iterator = NULL;
+ }
+ if( _headers != NULL ) {
+ delete _headers;
+ _headers = NULL;
+ }
+ }
+ _socket = 0;
+}
+
+long PSHttpResponse::getStatus() {
+ return _statusNum ? atoi(_statusNum) : 0;
+}
+
+int PSHttpResponse::getReturnCode() {
+ return retcode;
+}
+
+char * PSHttpResponse::getStatusString() {
+ return _statusString?_statusString:(char*)"";
+}
+
+HttpProtocol PSHttpResponse::getProtocol() {
+ // first check the response protocol
+ if (_proto == HTTPNA) {
+ if (_protocol) {
+ int major, minor;
+
+ sscanf(_protocol, "HTTP/%d.%d", &major, &minor);
+
+ switch(major) {
+ case 1:
+ switch(minor) {
+ case 0:
+ _proto = HTTP10;
+ break;
+ case 1:
+ _proto = HTTP11;
+ break;
+ }
+ break;
+ }
+ } else {
+ _proto = HTTP09;
+ }
+ }
+
+ if (_proto == HTTP11) {
+ // A 1.1 compliant server response shows the protocol as HTTP/1.1 even
+ // for a HTTP/1.0 request, but it promises to only use HTTP/1.0 syntax.
+ if (_request->getProtocol() == HTTP10) {
+ _proto = HTTP10;
+ }
+ }
+
+ return _proto;
+};
+
+char * PSHttpResponse::getHeader(const char *name) {
+ CacheEntry *entry = _headers->Get(name);
+ return entry ? (char *)entry->GetData() : NULL;
+}
+
+int PSHttpResponse::getHeaders(char ***keys) {
+
+ return _headers->GetKeys( keys );
+
+}
+
+long PSHttpResponse::getBodyLength() {
+ return _bodyLength;
+}
+
+char * PSHttpResponse::getContent() {
+ return _content;
+}
+
+void PSHttpResponse::freeContent() {
+ if( _content != NULL ) {
+ PR_Free( _content );
+ _content = NULL;
+ }
+}
+
+int PSHttpResponse::getContentSize() {
+
+ return _contentSize;
+}
+
+char *PSHttpResponse::toString() {
+ char *resp = (char *)"";
+ char **keys;
+ char *headerBuf = NULL;
+ int nHeaders = getHeaders( &keys );
+ if ( nHeaders > 0 ) {
+ char **values = new char*[nHeaders];
+ int len = 0;
+ int *keyLengths = new int[nHeaders];
+ int *valueLengths = new int[nHeaders];
+ int i;
+ for( i = 0; i < nHeaders; i++ ) {
+ keyLengths[i] = strlen( keys[i] );
+ len += keyLengths[i] + 1;
+ values[i] = getHeader(keys[i]);
+ valueLengths[i] = strlen( values[i] );
+ len += valueLengths[i] + 1;
+ }
+ headerBuf = new char[len + nHeaders * 2];
+ char *p = headerBuf;
+ for( i = 0; i < nHeaders; i++ ) {
+ strcpy( p, keys[i] );
+ p += keyLengths[i];
+ *p++ = ':';
+ strcpy( p, values[i] );
+ p += valueLengths[i];
+ *p++ = ',';
+ }
+ *p = 0;
+ for( i = 0; i < nHeaders; i++ ) {
+ if( keys[i] != NULL ) {
+ delete [] keys[i];
+ keys[i] = NULL;
+ }
+ }
+ if( keys != NULL ) {
+ delete [] keys;
+ keys = NULL;
+ }
+ if( values != NULL ) {
+ delete [] values;
+ values = NULL;
+ }
+ if( keyLengths != NULL ) {
+ delete [] keyLengths;
+ keyLengths = NULL;
+ }
+ if( valueLengths != NULL ) {
+ delete [] valueLengths;
+ valueLengths = NULL;
+ }
+ }
+
+ char *s = NULL;
+ if ( headerBuf ) {
+ s = PR_smprintf( "PSHttpResponse [%s\nbody bytes:%d]",
+ headerBuf, _bodyLength );
+ } else {
+ s = PR_smprintf( "PSHttpResponse [body bytes:%d]", _bodyLength );
+ }
+ resp = new char[strlen(s) + 1];
+ strcpy( resp, s );
+ if( s != NULL ) {
+ PR_smprintf_free( s );
+ s = NULL;
+ }
+ return resp;
+}
+
+PRBool PSHttpResponse::checkKeepAlive() {
+ HttpProtocol proto;
+ const char *connectionHeader;
+//-- static const char *DEBUG_METHOD_NAME = "checkKeepAlive";
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( DEBUG_MODULE );
+
+ if (_keepAlive < 0) {
+ proto = getProtocol();
+ if (proto == HTTP11) {
+ // default is connection: keep-alive
+ _keepAlive = 1;
+ } else {
+ // default is connection: close
+ // _keepAlive = 0;
+ //CMS needs keepalive with HTTP10 (so no chunked encoding)
+ _keepAlive=1;
+ }
+
+ connectionHeader = _request->getHeader("connection");
+ if (connectionHeader) {
+ if (!PL_strcasecmp(connectionHeader, "keep-alive")) {
+ _keepAlive = 1;
+ } else if (!PL_strcasecmp(connectionHeader, "close")) {
+ _keepAlive = 0;
+ } else {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::checkKeepAlive: ",
+ "Unknown connection header" );
+ }
+ }
+ }
+
+ return (_keepAlive == 0?PR_FALSE:PR_TRUE);
+}
+
+PRBool PSHttpResponse::checkConnection() {
+ // return true if the connection is OPEN
+ return (_connectionClosed == 0?PR_TRUE:PR_FALSE);
+}
+
+
+int PSHttpResponse::_verifyStandardBody(RecvBuf &buf,
+ int expectedBytes,
+ PRBool check) {
+ int bytesRead = 0;
+ int curPos = 0;
+ char ch;
+//-- static const char *DEBUG_METHOD_NAME = "_verifyStandardBody";
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( DEBUG_MODULE );
+
+ while(expectedBytes > 0 ) {
+ ch = buf.getChar();
+ if (ch < 0 ) {
+ break;
+ }
+ // if check is true, we think we know what the content looks like
+ if ( check ) {
+ if (ch != (char) curPos%256) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::_verifyStandardBody: ",
+ "Response data corrupt at byte %d (%d, %d)",
+ curPos,
+ ch,
+ ( curPos % 256 ) );
+ check = PR_FALSE;
+ break;
+ }
+ curPos++;
+ }
+
+ bytesRead++;
+
+ if (expectedBytes > 0) {
+ expectedBytes--;
+ }
+ }
+
+ return bytesRead;
+}
+
+
+PRBool PSHttpResponse::_handleBody( RecvBuf &buf ) {
+ char *clHeader; // content length header
+ char *teHeader; // transfer-encoding header
+ int expected_cl=-1; // expected content length
+//-- static const char *DEBUG_METHOD_NAME = "_handleBody";
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( DEBUG_MODULE );
+
+ teHeader = getHeader("transfer-encoding");
+ if (teHeader && !PL_strcasecmp(teHeader, "chunked")) {
+ _chunkedResponse = PR_TRUE;
+ buf.setChunkedMode();
+ } else {
+ _chunkedResponse = PR_FALSE;
+ clHeader = getHeader("Content-length");
+ if (clHeader) {
+ expected_cl = atoi(clHeader);
+ }
+ }
+
+ if (_request->getExpectStandardBody()) {
+ _bodyLength = _verifyStandardBody(buf, expected_cl, PR_TRUE);
+
+ } else {
+ _bodyLength = _verifyStandardBody(buf, expected_cl, PR_FALSE);
+ }
+
+ if (expected_cl >= 0) {
+ if (_bodyLength != expected_cl) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::_handleBody: ",
+ "Content length was incorrect (%d/%d bytes)",
+ _bodyLength,
+ expected_cl );
+ }
+ }
+
+ return PR_TRUE;
+}
+
+/**
+ * Reads until the first space character
+ *
+ * @param buf Receive buffer to read from
+ * @param headerBuf Array to read header into
+ * @param len Size of headerBuf
+ * @return Number of characters read, or -1 if too many
+ */
+static int readHeader( RecvBuf& buf, char* headerBuf, int len ) {
+ int index = 0;
+
+ do {
+ char ch = buf.getChar();
+
+ if ( ch != -1 && !isspace(ch) ) {
+ headerBuf[index++] = ch;
+ if ( index >= (len-1) ) {
+ return -1;
+ }
+ } else {
+ headerBuf[index] = '\0';
+ break;
+ }
+ } while( true );
+ // RA::Debug( LL_PER_PDU,
+ // "readHeader: ",
+ // "headerBuf = %s",
+ // headerBuf );
+
+ return index;
+}
+
+
+PRBool PSHttpResponse::processResponse() {
+ RecvBuf buf( _socket, 8192, _timeout );
+
+ if (_expectChunked) {
+ buf.setChunkedMode();
+ }
+
+//-- static const char *DEBUG_METHOD_NAME = "processResponse";
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( DEBUG_MODULE );
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Entered processResponse()" );
+
+ try {
+ char tmp[2048];
+ int tmpLen = sizeof(tmp);
+
+ // Get protocol string
+ int nRead = readHeader( buf, tmp, tmpLen );
+
+ if ( nRead < 0 ) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Returned more than expected bytes %d "
+ "in protocol header",
+ sizeof( tmp ) );
+ return PR_FALSE;
+ }
+
+ _protocol = PL_strdup(tmp);
+//-- logger->Log( LOGLEVEL_FINER, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Protocol header: %s",
+ _protocol );
+
+ // Get status num
+ nRead = readHeader( buf, tmp, tmpLen );
+ if ( nRead < 0 ) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Returned more than expected bytes %d "
+ "in status header",
+ tmpLen );
+ return PR_FALSE;
+ }
+
+ _statusNum = PL_strdup( tmp );
+
+//-- logger->Log( LOGLEVEL_FINER, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Status header: %s",
+ _statusNum );
+ retcode = atoi( tmp );
+
+ // Get status string
+ int index = 0;
+ do {
+ char ch = buf.getChar();
+ if ( ch != -1 && ch != '\r' ) {
+ tmp[index++] = ch;
+ if ( index >= (tmpLen-2) ) {
+ tmp[index] = 0;
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Returned more than expected bytes %d "
+ "in protocol header:\n%s",
+ tmpLen,
+ tmp );
+ return PR_FALSE;
+ }
+ } else {
+ break;
+ }
+ } while (true);
+ tmp[index] = '\0';
+ _statusString = PL_strdup( tmp );
+
+ // Skip CRLF
+ (void)buf.getChar();
+
+ // loop over response headers
+ index = 0;
+#ifdef CHECK
+ PRBool doneParsing = PR_FALSE;
+ PRBool atEOL = PR_FALSE;
+ PRBool inName = PR_TRUE;
+ char name[2048];
+ int nameLen = sizeof(name);
+
+ while ( !doneParsing ) {
+ char value[2048];
+ int valueLen = sizeof(value);
+ char ch = buf.getChar();
+
+ switch( ch ) {
+ case ':':
+ if ( inName ) {
+ name[index] = '\0';
+ index = 0;
+ inName = PR_FALSE;
+
+ nRead = readHeader( buf, value, valueLen );
+ if ( nRead < 0 ) {
+//-- logger->Log( LOGLEVEL_SEVERE,
+//-- DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Name %s in header does not "
+ "have a value",
+ name );
+ // return PR_FALSE;
+ } else {
+ value[index++] = ch;
+ if ( index >= (int)(sizeof(value) - 1 ) ) {
+//-- logger->Log( LOGLEVEL_SEVERE,
+//-- DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Name %s in header does not "
+ "have a value",
+ name );
+ // return PR_FALSE;
+ }
+ }
+ break;
+ case '\r':
+ if ( inName && !atEOL ) {
+ name[index] = '\0';
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Name %s in header does not "
+ "have a value",
+ name );
+ // return PR_FALSE;
+ }
+ break;
+ case '\n':
+ if ( atEOL ) {
+ doneParsing = PR_TRUE;
+ break;
+ }
+ if ( inName ) {
+ name[index] = '\0';
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Name %s in header does not "
+ "have a value",
+ name );
+ // return PR_FALSE;
+ }
+ value[index] = '\0';
+ index = 0;
+ inName = PR_TRUE;
+ _headers->Put(name, PL_strdup(value));
+ atEOL = PR_TRUE;
+ break;
+ default:
+ atEOL = PR_FALSE;
+ if (inName) {
+ name[index++] = ch;
+ } else {
+ value[index++] = ch;
+ }
+ if ( inName && (index >= (nameLen-2)) ) {
+ name[index] = '\0';
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Name %s in header exceeds the expected "
+ "%d max characters",
+ name,
+ nameLen );
+ // return PR_FALSE;
+ } else if ( !inName && (index >= (valueLen-1)) ) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Name %s in header does not "
+ "have a value",
+ name );
+ // return PR_FALSE;
+ }
+ break;
+ }
+ }
+
+ } //while
+#endif //CHECK
+ } catch ( RecvBuf::EndOfFile & ) {
+ if ( !_request->isHangupOk() ) {
+
+ int errCode = PR_GetError();
+ if ( PR_IO_TIMEOUT_ERROR == errCode ) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Timed out reading response (%d seconds)",
+ buf.getTimeout() );
+ } else {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Received unexpected end of file from server\n%s",
+ "XXX" );
+ }
+ }
+ return PR_FALSE;
+ }
+
+ // Read the body (HEAD requests don't have bodies)
+ // jpierre 1xx, 204 and 304 don't have bodies either
+ if ( PL_strcmp(_request->getMethod(), "HEAD") &&
+ (!((retcode>=100) && (retcode<200))) &&
+ (retcode!=204) &&
+ (retcode!=304) ) {
+ if ( _handleBody(buf) == PR_FALSE ) {
+ return PR_FALSE;
+ }
+ }
+
+ if ( checkConnection() && !checkKeepAlive() ) {
+ // if connection is still open, and we didn't expect a keepalive,
+ // read another byte to see if the connection has closed.
+ try {
+ char ch;
+ ch = buf.getChar();
+ buf.putBack();
+ // conflict!
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Connection kept alive when it shouldn't" );
+ } catch (RecvBuf::EndOfFile &) {
+ _connectionClosed = 1;
+ }
+ }
+
+ _checkResponseSanity();
+ _content = (char *)buf.get_content();
+ _contentSize = buf.get_contentSize();
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "processed Buffer contentSize=%d",
+ getContentSize() );
+ if (_content != NULL) {
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "processed Buffer content=%s",
+ _content );
+ }
+ // char * yo = getContent();
+
+ return PR_TRUE;
+}
+
+void PSHttpResponse::_checkResponseSanity() {
+ char *clHeader = getHeader("Content-length");
+ char *teHeader = getHeader("Transfer-encoding");
+//-- static const char *DEBUG_METHOD_NAME = "checkResponseSanity";
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( DEBUG_MODULE );
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::_checkResponseSanity: ",
+ "in _checkResponseSanity" );
+
+ ///////////////////////////////////////////////////
+ // Check items relevant to HTTP/1.0 and HTTP/1.1 //
+ ///////////////////////////////////////////////////
+
+ // check for both content-length and chunked
+ if ( clHeader && teHeader ) {
+//-- logger->Log( LOGLEVEL_FINER, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::_checkResponseSanity: ",
+ "Response contains both content-length and "
+ "transfer-encoding" );
+ }
+
+ // check for basic headers
+ if ( !getHeader("Date") ) {
+//-- logger->Log( LOGLEVEL_WARNING, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::_checkResponseSanity: ",
+ "Response does not contain a date header" );
+ }
+ if ( !getHeader("Server") ) {
+//-- logger->Log( LOGLEVEL_WARNING, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::_checkResponseSanity: ",
+ "Response does not contain a server header" );
+ }
+
+ int expectedLength;
+ if ((expectedLength = _request->getExpectedResponseLength()) > 0) {
+ if (expectedLength != _bodyLength) {
+//-- logger->Log( LOGLEVEL_INFO, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::_checkResponseSanity: ",
+ "Response body length does not match expected "
+ "response length (%d/%d)",
+ _bodyLength,
+ expectedLength );
+ }
+ }
+
+ ///////////////////////////////////////
+ // Check items relevant to HTTP/1.0 //
+ ///////////////////////////////////////
+ if ( getProtocol() == HTTP10 ) {
+ if ( _chunkedResponse ) {
+//-- logger->Log( LOGLEVEL_INFO, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::_checkResponseSanity: ",
+ "Server sent a chunked HTTP/1.0 response" );
+ }
+ }
+
+ ///////////////////////////////////////
+ // Check items relevant to HTTP/1.1 //
+ ///////////////////////////////////////
+ if ( getProtocol() == HTTP11 ) {
+ if ( (!clHeader && !_chunkedResponse) &&
+ (!((retcode>=100) && (retcode<200))) &&
+ (retcode!=204) &&
+ (retcode!=304) ) {
+//-- logger->Log( LOGLEVEL_INFO, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::_checkResponseSanity: ",
+ "Server responded with a HTTP/1.1 response without "
+ "content-length or chunked encoding" );
+ }
+ }
+}
diff --git a/base/tps/src/include/apdu/APDU.h b/base/tps/src/include/apdu/APDU.h
new file mode 100644
index 000000000..e0f778a19
--- /dev/null
+++ b/base/tps/src/include/apdu/APDU.h
@@ -0,0 +1,116 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef APDU_H
+#define APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "pk11func.h"
+#include "main/Base.h"
+#include "main/Buffer.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+enum APDU_Type {
+ APDU_UNDEFINED = 0,
+ APDU_CREATE_OBJECT = 1,
+ APDU_EXTERNAL_AUTHENTICATE = 2,
+ APDU_INITIALIZE_UPDATE = 3,
+ APDU_LIFECYCLE = 4,
+ APDU_READ_BUFFER = 5,
+ APDU_SET_PIN = 6,
+ APDU_UNBLOCK_PIN = 7,
+ APDU_WRITE_OBJECT = 8,
+ APDU_GENERATE_KEY = 9,
+ APDU_PUT_KEY = 10,
+ APDU_SELECT = 11,
+ APDU_GET_VERSION = 12,
+ APDU_DELETE_FILE = 13,
+ APDU_INSTALL_APPLET = 14,
+ APDU_FORMAT_MUSCLE_APPLET = 15,
+ APDU_LOAD_FILE = 16,
+ APDU_INSTALL_LOAD = 17,
+ APDU_GET_STATUS = 18 ,
+ APDU_LIST_PINS = 19,
+ APDU_CREATE_PIN = 20,
+ APDU_GET_DATA = 21,
+ APDU_READ_OBJECT = 22,
+ APDU_LIST_OBJECTS = 23,
+ APDU_IMPORT_KEY = 24,
+ APDU_IMPORT_KEY_ENC = 25,
+ APDU_SET_ISSUERINFO = 26,
+ APDU_GET_ISSUERINFO = 27
+};
+
+class APDU
+{
+ public:
+ TPS_PUBLIC APDU();
+ TPS_PUBLIC APDU(const APDU &cpy);
+ TPS_PUBLIC virtual ~APDU();
+ public:
+ TPS_PUBLIC APDU& operator=(const APDU& cpy);
+ public:
+ TPS_PUBLIC virtual void SetCLA(BYTE cla);
+ TPS_PUBLIC virtual void SetINS(BYTE ins);
+ TPS_PUBLIC virtual void SetP1(BYTE p1);
+ TPS_PUBLIC virtual void SetP2(BYTE p2);
+ TPS_PUBLIC virtual void SetData(Buffer &data);
+ TPS_PUBLIC virtual void SetMAC(Buffer &mac);
+ TPS_PUBLIC virtual void GetEncoding(Buffer &data);
+ TPS_PUBLIC virtual void GetDataToMAC(Buffer &data);
+ TPS_PUBLIC virtual PRStatus SecureMessage(PK11SymKey *encSessionKey);
+ TPS_PUBLIC virtual APDU_Type GetType();
+ TPS_PUBLIC Buffer &GetData();
+ TPS_PUBLIC Buffer &GetMAC();
+ TPS_PUBLIC BYTE GetCLA();
+ TPS_PUBLIC BYTE GetINS();
+ TPS_PUBLIC BYTE GetP1();
+ TPS_PUBLIC BYTE GetP2();
+ protected:
+ BYTE m_cla;
+ BYTE m_ins;
+ BYTE m_p1;
+ BYTE m_p2;
+ Buffer m_data;
+ Buffer m_plainText;
+ Buffer m_mac;
+};
+
+#endif /* APDU_H */
diff --git a/base/tps/src/include/apdu/APDU_Response.h b/base/tps/src/include/apdu/APDU_Response.h
new file mode 100644
index 000000000..0d5c62b9d
--- /dev/null
+++ b/base/tps/src/include/apdu/APDU_Response.h
@@ -0,0 +1,66 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef APDU_RESPONSE_H
+#define APDU_RESPONSE_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class APDU_Response
+{
+ public:
+ APDU_Response();
+ TPS_PUBLIC APDU_Response(Buffer &data);
+ ~APDU_Response();
+ APDU_Response(const APDU_Response &cpy);
+ public:
+ APDU_Response& operator=(const APDU_Response& cpy);
+ public:
+ BYTE GetSW1();
+ BYTE GetSW2();
+ TPS_PUBLIC Buffer &GetData();
+ private:
+ Buffer m_data;
+};
+
+#endif /* APDU_Response_H */
diff --git a/base/tps/src/include/apdu/Create_Object_APDU.h b/base/tps/src/include/apdu/Create_Object_APDU.h
new file mode 100644
index 000000000..7433e7ceb
--- /dev/null
+++ b/base/tps/src/include/apdu/Create_Object_APDU.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef CREATE_OBJECT_APDU_H
+#define CREATE_OBJECT_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Create_Object_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Create_Object_APDU(BYTE *object_id, BYTE *permissions, int len);
+ TPS_PUBLIC ~Create_Object_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* CREATE_OBJECT_APDU_H */
diff --git a/base/tps/src/include/apdu/Create_Pin_APDU.h b/base/tps/src/include/apdu/Create_Pin_APDU.h
new file mode 100644
index 000000000..7f666467d
--- /dev/null
+++ b/base/tps/src/include/apdu/Create_Pin_APDU.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef CREATE_PIN_APDU_H
+#define CREATE_PIN_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Create_Pin_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Create_Pin_APDU(BYTE p1, BYTE p2, Buffer &data);
+ TPS_PUBLIC ~Create_Pin_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* CREATE_PIN_APDU_H */
diff --git a/base/tps/src/include/apdu/Delete_File_APDU.h b/base/tps/src/include/apdu/Delete_File_APDU.h
new file mode 100644
index 000000000..9e2eeeeb2
--- /dev/null
+++ b/base/tps/src/include/apdu/Delete_File_APDU.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef DELETE_FILE_APDU_H
+#define DELETE_FILE_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Delete_File_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Delete_File_APDU(Buffer &AID);
+ TPS_PUBLIC ~Delete_File_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* DELETE_FILE_APDU_H */
diff --git a/base/tps/src/include/apdu/External_Authenticate_APDU.h b/base/tps/src/include/apdu/External_Authenticate_APDU.h
new file mode 100644
index 000000000..ff9a6bee7
--- /dev/null
+++ b/base/tps/src/include/apdu/External_Authenticate_APDU.h
@@ -0,0 +1,62 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef EXTERNAL_AUTHENTICATE_APDU_H
+#define EXTERNAL_AUTHENTICATE_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+#include "channel/Secure_Channel.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class External_Authenticate_APDU : public APDU
+{
+ public:
+ // TPS_PUBLIC External_Authenticate_APDU(Buffer &data);
+ TPS_PUBLIC External_Authenticate_APDU(Buffer &data, SecurityLevel sl);
+ TPS_PUBLIC ~External_Authenticate_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ public:
+ TPS_PUBLIC Buffer &GetHostCryptogram();
+};
+
+#endif /* EXTERNAL_AUTHENTICATE_APDU_H */
diff --git a/base/tps/src/include/apdu/Format_Muscle_Applet_APDU.h b/base/tps/src/include/apdu/Format_Muscle_Applet_APDU.h
new file mode 100644
index 000000000..b7fbbbea1
--- /dev/null
+++ b/base/tps/src/include/apdu/Format_Muscle_Applet_APDU.h
@@ -0,0 +1,65 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef FORMAT_MUSCLE_APPLET_APDU_H
+#define FORMAT_MUSCLE_APPLET_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Format_Muscle_Applet_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Format_Muscle_Applet_APDU(unsigned short memSize,
+ Buffer &PIN0, BYTE pin0Tries,
+ Buffer &unblockPIN0, BYTE unblock0Tries,
+ Buffer &PIN1, BYTE pin1Tries,
+ Buffer &unblockPIN1, BYTE unblock1Tries,
+ unsigned short objCreationPermissions,
+ unsigned short keyCreationPermissions,
+ unsigned short pinCreationPermissions);
+ TPS_PUBLIC ~Format_Muscle_Applet_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ TPS_PUBLIC void GetEncoding(Buffer &data);
+};
+
+#endif /* FORMAT_MUSCLE_APPLET_APDU_H */
diff --git a/base/tps/src/include/apdu/Generate_Key_APDU.h b/base/tps/src/include/apdu/Generate_Key_APDU.h
new file mode 100644
index 000000000..d245b8336
--- /dev/null
+++ b/base/tps/src/include/apdu/Generate_Key_APDU.h
@@ -0,0 +1,60 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef GENERATE_KEY_APDU_H
+#define GENERATE_KEY_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Generate_Key_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Generate_Key_APDU (BYTE p1, BYTE p2, BYTE alg,
+ int keysize, BYTE option,
+ BYTE type, Buffer &wrapped_challenge, Buffer &key_check);
+ TPS_PUBLIC ~Generate_Key_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* GENERATE_KEY_APDU_H */
diff --git a/base/tps/src/include/apdu/Get_Data_APDU.h b/base/tps/src/include/apdu/Get_Data_APDU.h
new file mode 100644
index 000000000..a4f78634d
--- /dev/null
+++ b/base/tps/src/include/apdu/Get_Data_APDU.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef GET_DATA_APDU_H
+#define GET_DATA_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Get_Data_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Get_Data_APDU();
+ TPS_PUBLIC ~Get_Data_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ TPS_PUBLIC void GetEncoding(Buffer &data);
+};
+
+#endif /* GET_DATA_APDU_H */
diff --git a/base/tps/src/include/apdu/Get_IssuerInfo_APDU.h b/base/tps/src/include/apdu/Get_IssuerInfo_APDU.h
new file mode 100644
index 000000000..075acc6d9
--- /dev/null
+++ b/base/tps/src/include/apdu/Get_IssuerInfo_APDU.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef GET_ISSUERINFO_APDU_H
+#define GET_ISSUERINFO_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Get_IssuerInfo_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Get_IssuerInfo_APDU();
+ TPS_PUBLIC ~Get_IssuerInfo_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ TPS_PUBLIC void GetEncoding(Buffer &data);
+};
+
+#endif /* GET_ISSUERINFO_APDU_H */
diff --git a/base/tps/src/include/apdu/Get_Status_APDU.h b/base/tps/src/include/apdu/Get_Status_APDU.h
new file mode 100644
index 000000000..5d047bf16
--- /dev/null
+++ b/base/tps/src/include/apdu/Get_Status_APDU.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef GET_STATUS_APDU_H
+#define GET_STATUS_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Get_Status_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Get_Status_APDU();
+ TPS_PUBLIC ~Get_Status_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ TPS_PUBLIC void GetEncoding(Buffer &data);
+};
+
+#endif /* GET_STATUS_APDU_H */
diff --git a/base/tps/src/include/apdu/Get_Version_APDU.h b/base/tps/src/include/apdu/Get_Version_APDU.h
new file mode 100644
index 000000000..8b6ff3c33
--- /dev/null
+++ b/base/tps/src/include/apdu/Get_Version_APDU.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef GET_VERSION_APDU_H
+#define GET_VERSION_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Get_Version_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Get_Version_APDU();
+ TPS_PUBLIC ~Get_Version_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ TPS_PUBLIC void GetEncoding(Buffer &data);
+};
+
+#endif /* GET_VERSION_APDU_H */
diff --git a/base/tps/src/include/apdu/Import_Key_APDU.h b/base/tps/src/include/apdu/Import_Key_APDU.h
new file mode 100644
index 000000000..e00d97081
--- /dev/null
+++ b/base/tps/src/include/apdu/Import_Key_APDU.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef IMPORT_KEY_APDU_H
+#define IMPORT_KEY_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Import_Key_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Import_Key_APDU(BYTE p1);
+ TPS_PUBLIC ~Import_Key_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* IMPORT_KEY_APDU_H */
diff --git a/base/tps/src/include/apdu/Import_Key_Enc_APDU.h b/base/tps/src/include/apdu/Import_Key_Enc_APDU.h
new file mode 100644
index 000000000..bcc974987
--- /dev/null
+++ b/base/tps/src/include/apdu/Import_Key_Enc_APDU.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef IMPORT_KEY_ENC_APDU_H
+#define IMPORT_KEY_ENC_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Import_Key_Enc_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Import_Key_Enc_APDU(BYTE p1, BYTE p2, Buffer& data);
+ TPS_PUBLIC ~Import_Key_Enc_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* IMPORT_KEY_ENC_APDU_H */
diff --git a/base/tps/src/include/apdu/Initialize_Update_APDU.h b/base/tps/src/include/apdu/Initialize_Update_APDU.h
new file mode 100644
index 000000000..8e20d77ab
--- /dev/null
+++ b/base/tps/src/include/apdu/Initialize_Update_APDU.h
@@ -0,0 +1,60 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef INITIALIZE_UPDATE_APDU_H
+#define INITIALIZE_UPDATE_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Initialize_Update_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Initialize_Update_APDU(BYTE key_version, BYTE key_index, Buffer &data);
+ TPS_PUBLIC ~Initialize_Update_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ TPS_PUBLIC void GetEncoding(Buffer &data);
+ public:
+ TPS_PUBLIC Buffer &GetHostChallenge();
+};
+
+#endif /* INITIALIZE_UPDATE_APDU_H */
diff --git a/base/tps/src/include/apdu/Install_Applet_APDU.h b/base/tps/src/include/apdu/Install_Applet_APDU.h
new file mode 100644
index 000000000..08b799a64
--- /dev/null
+++ b/base/tps/src/include/apdu/Install_Applet_APDU.h
@@ -0,0 +1,59 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef INSTALL_APPLET_APDU_H
+#define INSTALL_APPLET_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Install_Applet_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Install_Applet_APDU(Buffer &packageAID, Buffer &appletAID,
+ BYTE appPrivileges, unsigned int instanceSize, unsigned int appletMemorySize);
+ TPS_PUBLIC Install_Applet_APDU(Buffer &data);
+ TPS_PUBLIC ~Install_Applet_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* INSTALL_APPLET_APDU_H */
diff --git a/base/tps/src/include/apdu/Install_Load_APDU.h b/base/tps/src/include/apdu/Install_Load_APDU.h
new file mode 100644
index 000000000..7d0ff9761
--- /dev/null
+++ b/base/tps/src/include/apdu/Install_Load_APDU.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef INSTALL_LOAD_APDU_H
+#define INSTALL_LOAD_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Install_Load_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Install_Load_APDU(Buffer& packageAID, Buffer& sdAID, unsigned int fileLen);
+ TPS_PUBLIC Install_Load_APDU(Buffer& data);
+ TPS_PUBLIC ~Install_Load_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* INSTALL_LOAD_APDU_H */
diff --git a/base/tps/src/include/apdu/Lifecycle_APDU.h b/base/tps/src/include/apdu/Lifecycle_APDU.h
new file mode 100644
index 000000000..a3adaf9c4
--- /dev/null
+++ b/base/tps/src/include/apdu/Lifecycle_APDU.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef LIFECYCLE_APDU_H
+#define LIFECYCLE_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Lifecycle_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Lifecycle_APDU(BYTE lifecycle);
+ TPS_PUBLIC ~Lifecycle_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* LIFECYCLE_APDU_H */
diff --git a/base/tps/src/include/apdu/List_Objects_APDU.h b/base/tps/src/include/apdu/List_Objects_APDU.h
new file mode 100644
index 000000000..7d5b45bff
--- /dev/null
+++ b/base/tps/src/include/apdu/List_Objects_APDU.h
@@ -0,0 +1,59 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef LIST_OBJECTS_APDU_H
+#define LIST_OBJECTS_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class List_Objects_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC List_Objects_APDU(BYTE ret_size);
+ TPS_PUBLIC ~List_Objects_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ public:
+ TPS_PUBLIC void GetEncoding(Buffer &data);
+};
+
+#endif /* LIST_OBJECTS_APDU_H */
diff --git a/base/tps/src/include/apdu/List_Pins_APDU.h b/base/tps/src/include/apdu/List_Pins_APDU.h
new file mode 100644
index 000000000..04d1102c9
--- /dev/null
+++ b/base/tps/src/include/apdu/List_Pins_APDU.h
@@ -0,0 +1,60 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef LIST_PINS_APDU_H
+#define LIST_PINS_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class List_Pins_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC List_Pins_APDU(BYTE ret_size);
+ TPS_PUBLIC ~List_Pins_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ public:
+ BYTE m_ret_size;
+ TPS_PUBLIC void GetEncoding(Buffer &data);
+};
+
+#endif /* LIST_PINS_APDU_H */
diff --git a/base/tps/src/include/apdu/Load_File_APDU.h b/base/tps/src/include/apdu/Load_File_APDU.h
new file mode 100644
index 000000000..ae5f57445
--- /dev/null
+++ b/base/tps/src/include/apdu/Load_File_APDU.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef LOAD_FILE_APDU_H
+#define LOAD_FILE_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Load_File_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Load_File_APDU(BYTE refControl, BYTE blockNum, Buffer& data);
+ TPS_PUBLIC ~Load_File_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* LOAD_FILE_APDU_H */
diff --git a/base/tps/src/include/apdu/Put_Key_APDU.h b/base/tps/src/include/apdu/Put_Key_APDU.h
new file mode 100644
index 000000000..63aa54599
--- /dev/null
+++ b/base/tps/src/include/apdu/Put_Key_APDU.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef PUT_KEY_APDU_H
+#define PUT_KEY_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Put_Key_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Put_Key_APDU(BYTE p1, BYTE p2, Buffer &data);
+ TPS_PUBLIC ~Put_Key_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* PUT_KEY_APDU_H */
diff --git a/base/tps/src/include/apdu/Read_Buffer_APDU.h b/base/tps/src/include/apdu/Read_Buffer_APDU.h
new file mode 100644
index 000000000..3c94b564d
--- /dev/null
+++ b/base/tps/src/include/apdu/Read_Buffer_APDU.h
@@ -0,0 +1,61 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef READ_BUFFER_APDU_H
+#define READ_BUFFER_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Read_Buffer_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Read_Buffer_APDU(int len, int offset);
+ TPS_PUBLIC ~Read_Buffer_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ public:
+ TPS_PUBLIC int GetLen();
+ TPS_PUBLIC int GetOffset();
+
+};
+
+#endif /* READ_BUFFER_APDU_H */
diff --git a/base/tps/src/include/apdu/Read_Object_APDU.h b/base/tps/src/include/apdu/Read_Object_APDU.h
new file mode 100644
index 000000000..e2357acdd
--- /dev/null
+++ b/base/tps/src/include/apdu/Read_Object_APDU.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef OBJECT_OBJECT_APDU_H
+#define OBJECT_OBJECT_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Read_Object_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Read_Object_APDU(BYTE *object_id, int offset, int len);
+ TPS_PUBLIC ~Read_Object_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* OBJECT_OBJECT_APDU_H */
diff --git a/base/tps/src/include/apdu/Select_APDU.h b/base/tps/src/include/apdu/Select_APDU.h
new file mode 100644
index 000000000..92c1c8ee8
--- /dev/null
+++ b/base/tps/src/include/apdu/Select_APDU.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef SELECT_APDU_H
+#define SELECT_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Select_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Select_APDU(BYTE p1, BYTE p2, Buffer &data);
+ TPS_PUBLIC ~Select_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* SELECT_APDU_H */
diff --git a/base/tps/src/include/apdu/Set_IssuerInfo_APDU.h b/base/tps/src/include/apdu/Set_IssuerInfo_APDU.h
new file mode 100644
index 000000000..2507fdc97
--- /dev/null
+++ b/base/tps/src/include/apdu/Set_IssuerInfo_APDU.h
@@ -0,0 +1,59 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef SET_ISSUERINFO_APDU_H
+#define SET_ISSUERINFO_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Set_IssuerInfo_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Set_IssuerInfo_APDU(BYTE p1, BYTE p2, Buffer &data);
+ TPS_PUBLIC ~Set_IssuerInfo_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ public:
+ TPS_PUBLIC Buffer &GetIssuerInfo();
+};
+
+#endif /* SET_ISSUERINFO_APDU_H */
diff --git a/base/tps/src/include/apdu/Set_Pin_APDU.h b/base/tps/src/include/apdu/Set_Pin_APDU.h
new file mode 100644
index 000000000..f649147a1
--- /dev/null
+++ b/base/tps/src/include/apdu/Set_Pin_APDU.h
@@ -0,0 +1,59 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef SET_PIN_APDU_H
+#define SET_PIN_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Set_Pin_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Set_Pin_APDU(BYTE p1, BYTE p2, Buffer &data);
+ TPS_PUBLIC ~Set_Pin_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ public:
+ TPS_PUBLIC Buffer &GetNewPIN();
+};
+
+#endif /* SET_PIN_APDU_H */
diff --git a/base/tps/src/include/apdu/Unblock_Pin_APDU.h b/base/tps/src/include/apdu/Unblock_Pin_APDU.h
new file mode 100644
index 000000000..583e7ae7d
--- /dev/null
+++ b/base/tps/src/include/apdu/Unblock_Pin_APDU.h
@@ -0,0 +1,54 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef UNBLOCK_PIN_APDU_H
+#define UNBLOCK_PIN_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Unblock_Pin_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Unblock_Pin_APDU();
+ TPS_PUBLIC ~Unblock_Pin_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* UNBLOCK_PIN_APDU_H */
diff --git a/base/tps/src/include/apdu/Write_Object_APDU.h b/base/tps/src/include/apdu/Write_Object_APDU.h
new file mode 100644
index 000000000..670cd6bbd
--- /dev/null
+++ b/base/tps/src/include/apdu/Write_Object_APDU.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef WRITE_OBJECT_APDU_H
+#define WRITE_OBJECT_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Write_Object_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Write_Object_APDU(BYTE *object_id, int offset, Buffer &data);
+ TPS_PUBLIC ~Write_Object_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* WRITE_OBJECT_APDU_H */
diff --git a/base/tps/src/include/authentication/AuthParams.h b/base/tps/src/include/authentication/AuthParams.h
new file mode 100644
index 000000000..e0d39a249
--- /dev/null
+++ b/base/tps/src/include/authentication/AuthParams.h
@@ -0,0 +1,64 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef AUTHPARAMS_H
+#define AUTHPARAMS_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/NameValueSet.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class AuthParams : public NameValueSet
+{
+ public:
+ TPS_PUBLIC AuthParams();
+ virtual ~AuthParams();
+ public:
+ TPS_PUBLIC void SetUID(char *uid);
+ TPS_PUBLIC char *GetUID();
+ TPS_PUBLIC void SetPassword(char *pwd);
+ TPS_PUBLIC char *GetPassword();
+ void SetSecuridValue(char *securidValue);
+ TPS_PUBLIC char *GetSecuridValue();
+ void SetSecuridPin(char *securidPin);
+ TPS_PUBLIC char *GetSecuridPin();
+};
+
+#endif /* AUTHPARAMS_H */
diff --git a/base/tps/src/include/authentication/Authentication.h b/base/tps/src/include/authentication/Authentication.h
new file mode 100644
index 000000000..ae2b0c6fb
--- /dev/null
+++ b/base/tps/src/include/authentication/Authentication.h
@@ -0,0 +1,80 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef AUTHENTICATION_H
+#define AUTHENTICATION_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Login.h"
+#include "main/SecureId.h"
+#include "main/RA_Session.h"
+#include "authentication/AuthParams.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#define TPS_AUTH_OK 0
+#define TPS_AUTH_ERROR_LDAP -1
+#define TPS_AUTH_ERROR_USERNOTFOUND -2
+#define TPS_AUTH_ERROR_PASSWORDINCORRECT -3
+
+
+class Authentication
+{
+ public:
+ TPS_PUBLIC Authentication();
+ TPS_PUBLIC virtual ~Authentication();
+ public:
+ virtual int Authenticate(AuthParams *params);
+ virtual void Initialize(int index);
+ public:
+ virtual const char *GetTitle(char *locale);
+ virtual const char *GetDescription(char *locale);
+ virtual int GetNumOfParamNames();
+ virtual char *GetParamID(int index);
+ virtual const char *GetParamName(int index, char *locale);
+ virtual char *GetParamType(int index);
+ virtual const char *GetParamDescription(int index, char *locale);
+ virtual char *GetParamOption(int index);
+ int GetNumOfRetries(); // retries if the user entered the wrong password/securid
+
+ protected:
+ int m_retries;
+};
+
+#endif /* AUTHENTICATION_H */
diff --git a/base/tps/src/include/authentication/LDAP_Authentication.h b/base/tps/src/include/authentication/LDAP_Authentication.h
new file mode 100644
index 000000000..2a8c0a7d5
--- /dev/null
+++ b/base/tps/src/include/authentication/LDAP_Authentication.h
@@ -0,0 +1,85 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef LDAP_AUTHENTICATION_H
+#define LDAP_AUTHENTICATION_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Login.h"
+#include "main/SecureId.h"
+#include "main/RA_Session.h"
+#include "authentication/Authentication.h"
+
+class LDAP_Authentication : public Authentication
+{
+ public:
+ LDAP_Authentication();
+ ~LDAP_Authentication();
+ public:
+ int Authenticate(AuthParams *params);
+ void Initialize(int index);
+ public:
+ bool IsSSL();
+ char *GetHostPort();
+
+ public:
+ void GetHostPort(char **p, char **q);
+ virtual const char *GetTitle(char *locale);
+ virtual const char *GetDescription(char *locale);
+ virtual int GetNumOfParamNames();
+ virtual char *GetParamID(int index);
+ virtual const char *GetParamName(int index, char *locale);
+ virtual char *GetParamType(int index);
+ virtual const char *GetParamDescription(int index, char *locale);
+ virtual char *GetParamOption(int index);
+
+ private:
+ int m_index;
+ bool m_isSSL;
+ char *m_hostport;
+ char *m_attributes;
+ char *m_ssl;
+ char *m_baseDN;
+ char *m_bindDN;
+ char *m_bindPwd;
+ int m_connectRetries; // for failover
+ ConnectionInfo *m_connInfo;
+};
+ extern "C"
+ {
+ Authentication *GetAuthentication();
+ };
+
+#endif /* LDAP_AUTHENTICATION_H */
diff --git a/base/tps/src/include/channel/Channel.h b/base/tps/src/include/channel/Channel.h
new file mode 100644
index 000000000..a49af8bf1
--- /dev/null
+++ b/base/tps/src/include/channel/Channel.h
@@ -0,0 +1,55 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef CHANNEL_H
+#define CHANNEL_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "pk11func.h"
+#include "main/Buffer.h"
+#include "main/RA_Session.h"
+#include "apdu/APDU.h"
+#include "apdu/APDU_Response.h"
+
+class Channel
+{
+ public:
+ Channel();
+ ~Channel();
+ public:
+ int Close();
+};
+
+#endif /* CHANNEL_H */
diff --git a/base/tps/src/include/channel/Secure_Channel.h b/base/tps/src/include/channel/Secure_Channel.h
new file mode 100644
index 000000000..bac072407
--- /dev/null
+++ b/base/tps/src/include/channel/Secure_Channel.h
@@ -0,0 +1,158 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef SECURE_CHANNEL_H
+#define SECURE_CHANNEL_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "pk11func.h"
+#include "main/Buffer.h"
+#include "main/RA_Session.h"
+#include "apdu/APDU.h"
+#include "apdu/APDU_Response.h"
+#include "channel/Channel.h"
+
+enum SecurityLevel {
+ SECURE_MSG_ANY = 0,
+ SECURE_MSG_MAC = 1,
+ SECURE_MSG_NONE = 2, // not yet supported
+ SECURE_MSG_MAC_ENC = 3
+} ;
+
+enum TokenKeyType {
+ KEY_TYPE_ENCRYPTION = 0,
+ KEY_TYPE_SIGNING = 1,
+ KEY_TYPE_SIGNING_AND_ENCRYPTION = 2
+};
+
+class Secure_Channel : public Channel
+{
+ public:
+
+ Secure_Channel(
+ RA_Session *session,
+ PK11SymKey *session_key,
+ PK11SymKey *enc_session_key,
+ char *drm_des_key_s,
+ char *kek_des_key_s,
+ char *keycheck_s,
+ Buffer &key_diversification_data,
+ Buffer &key_info_data,
+ Buffer &card_challenge,
+ Buffer &card_cryptogram,
+ Buffer &host_challenge,
+ Buffer &host_cryptogram);
+
+ ~Secure_Channel();
+ public:
+ Buffer &GetKeyDiversificationData();
+ Buffer &GetKeyInfoData();
+ Buffer &GetCardChallenge();
+ Buffer &GetCardCryptogram();
+ Buffer &GetHostChallenge();
+ Buffer &GetHostCryptogram();
+ SecurityLevel GetSecurityLevel();
+ void SetSecurityLevel(SecurityLevel level);
+ char *getDrmWrappedDESKey();
+ char *getKekWrappedDESKey();
+ char *getKeycheck();
+
+ public:
+ int ImportKeyEnc(BYTE priv_key_number, BYTE pub_key_number, Buffer* data);
+ int ImportKey(BYTE key_number);
+ int CreatePin(BYTE pin_number, BYTE max_retries, const char *pin);
+ int ExternalAuthenticate();
+ int SetIssuerInfo(Buffer *info);
+ Buffer GetIssuerInfo();
+ int ResetPin(BYTE pin_number, char *pin);
+ int IsPinPresent(BYTE pin_number);
+ int SetLifecycleState(BYTE flag);
+ int StartEnrollment(BYTE p1, BYTE p2, Buffer *wrapped_challenge,
+ Buffer *key_check,
+ BYTE alg, int keysize, BYTE option);
+ int ReadBuffer(BYTE *buf, int buf_len);
+ int CreateObject(BYTE *object_id, BYTE* permissions, int len);
+ int WriteObject(BYTE *objid, BYTE *buf, int buf_len);
+ Buffer *ReadObject(BYTE *objid, int offset, int len);
+ int PutKeys(RA_Session *session, BYTE key_version,
+ BYTE key_index, Buffer *key_data);
+ int LoadFile(RA_Session *session, BYTE refControl, BYTE blockNum,
+ Buffer *data);
+ int InstallApplet(RA_Session *session,
+ Buffer &packageAID, Buffer &appletAID,
+ BYTE appPrivileges, unsigned int instanceSize, unsigned int appletMemorySize);
+ int InstallLoad(RA_Session *session,
+ Buffer& packageAID, Buffer& sdAID, unsigned int fileLen);
+ int DeleteFileX(RA_Session *session, Buffer *aid);
+ int Close();
+ public:
+ int CreateObject(BYTE *objid, BYTE *perms, Buffer *obj);
+ int CreateCertificate(const char *id, Buffer *cert);
+
+ Buffer CreatePKCS11CertAttrsBuffer(TokenKeyType type, const char *id, const char *label, Buffer *keyid);
+ int CreatePKCS11CertAttrs(TokenKeyType type, const char *id, const char *label, Buffer *keyid);
+ Buffer CreatePKCS11PriKeyAttrsBuffer(TokenKeyType type, const char *id, const char *label, Buffer *keyid,
+ Buffer *modulus, const char *opType, const char *tokenType, const char *keyTypePrefix);
+ int CreatePKCS11PriKeyAttrs(TokenKeyType type, const char *id, const char *label, Buffer *keyid,
+ Buffer *modulus, const char *opType, const char *tokenType, const char *keyTypePrefix);
+ Buffer CreatePKCS11PubKeyAttrsBuffer(TokenKeyType type, const char *id, const char *label, Buffer *keyid,
+ Buffer *exponent, Buffer *modulus, const char *opType, const char *tokenType, const char *keyTypePrefix);
+ int CreatePKCS11PubKeyAttrs(TokenKeyType type, const char *id, const char *label, Buffer *keyid,
+ Buffer *exponent, Buffer *modulus, const char *opType, const char *tokenType, const char *keyTypePrefix);
+ APDU_Response *SendTokenAPU(APDU *apdu);
+
+ public:
+ Buffer *ComputeAPDUMac(APDU *apdu);
+ int ComputeAPDU(APDU *apdu);
+
+ private:
+ PK11SymKey *m_session_key;
+ PK11SymKey *m_enc_session_key;
+ char *m_drm_wrapped_des_key_s;
+ char *m_kek_wrapped_des_key_s;
+ char *m_keycheck_s;
+ RA_Session *m_session;
+ Buffer m_icv;
+ Buffer m_cryptogram;
+ Buffer m_key_diversification_data;
+ Buffer m_key_info_data;
+ Buffer m_card_challenge;
+ Buffer m_card_cryptogram;
+ Buffer m_host_challenge;
+ Buffer m_host_cryptogram;
+ SecurityLevel m_security_level;
+};
+
+#endif /* SECURE_CHANNEL_H */
diff --git a/base/tps/src/include/cms/CertEnroll.h b/base/tps/src/include/cms/CertEnroll.h
new file mode 100644
index 000000000..442e28e8c
--- /dev/null
+++ b/base/tps/src/include/cms/CertEnroll.h
@@ -0,0 +1,75 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef CERTENROLL_H
+#define CERTENROLL_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Buffer.h"
+
+#include "httpClient/httpc/response.h"
+#include "keythi.h"
+
+#ifdef XP_WIN32
+#define TOKENDB_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TOKENDB_PUBLIC
+#endif /* !XP_WIN32 */
+
+class CertEnroll
+{
+ public:
+
+ TOKENDB_PUBLIC CertEnroll();
+ TOKENDB_PUBLIC ~CertEnroll();
+
+ SECKEYPublicKey *ParsePublicKeyBlob(unsigned char * /*blob*/,
+ Buffer * /*challenge*/);
+ Buffer *EnrollCertificate(SECKEYPublicKey * /*pk_parsed*/,
+ const char *profileId,
+ const char * /*uid*/,
+ const char * /*token cuid*/, const char *connid,
+ char *error_msg,
+ SECItem** encodedPublicKeyInfo = NULL);
+ ReturnStatus verifyProof(SECKEYPublicKey* /*pk*/, SECItem* /*siProof*/,
+ unsigned short /*pkeyb_len*/, unsigned char* /*pkeyb*/,
+ Buffer* /*challenge*/);
+ TOKENDB_PUBLIC Buffer *RenewCertificate(PRUint64 serialno, const char *connid, const char *profileId, char *error_msg);
+ TOKENDB_PUBLIC int RevokeCertificate(const char *reason, const char *serialno, const char *connid, char *&status);
+ TOKENDB_PUBLIC int UnrevokeCertificate(const char *serialno, const char *connid, char *&status);
+ PSHttpResponse * sendReqToCA(const char *servlet, const char *parameters, const char *connid);
+ Buffer * parseResponse(PSHttpResponse * /*resp*/);
+};
+#endif /* CERTENROLL_H */
diff --git a/base/tps/src/include/cms/ConnectionInfo.h b/base/tps/src/include/cms/ConnectionInfo.h
new file mode 100644
index 000000000..07e9c3a73
--- /dev/null
+++ b/base/tps/src/include/cms/ConnectionInfo.h
@@ -0,0 +1,66 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef CONNECTIONINFO_H
+#define CONNECTIONINFO_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Buffer.h"
+#include "main/NameValueSet.h"
+#include "pk11func.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#define HOST_PORT_MEMBERS 20
+
+class ConnectionInfo
+{
+ public:
+ TPS_PUBLIC ConnectionInfo();
+ TPS_PUBLIC ~ConnectionInfo();
+ TPS_PUBLIC void BuildFailoverList(const char *str);
+ TPS_PUBLIC int GetHostPortListLen();
+ TPS_PUBLIC char **GetHostPortList();
+
+ private:
+ int m_len;
+ char *m_hostPortList[HOST_PORT_MEMBERS];
+};
+
+#endif /* CONNECTIONINFO_H */
diff --git a/base/tps/src/include/cms/HttpConnection.h b/base/tps/src/include/cms/HttpConnection.h
new file mode 100644
index 000000000..da9d3a7fd
--- /dev/null
+++ b/base/tps/src/include/cms/HttpConnection.h
@@ -0,0 +1,88 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef HTTPCONNECTION_H
+#define HTTPCONNECTION_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/response.h"
+#include "httpClient/httpc/request.h"
+#include "httpClient/httpc/engine.h"
+#include "httpClient/httpc/http.h"
+#include "ConnectionInfo.h"
+#include "main/NameValueSet.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class HttpConnection
+{
+ public:
+// HttpConnection();
+ TPS_PUBLIC HttpConnection(const char *id, ConnectionInfo *cinfo, int retries, int timeout,
+ bool isSSL, const char *clientnickname, bool keepAlive, NameValueSet *headers);
+ TPS_PUBLIC virtual ~HttpConnection();
+
+ public:
+ TPS_PUBLIC int GetNumOfRetries(); // failover retries
+ TPS_PUBLIC int GetTimeout();
+ TPS_PUBLIC ConnectionInfo *GetFailoverList();
+ TPS_PUBLIC char *GetId();
+ TPS_PUBLIC bool IsSSL();
+ TPS_PUBLIC char *GetClientNickname();
+ TPS_PUBLIC bool IsKeepAlive();
+ TPS_PUBLIC PSHttpResponse *getResponse(int index, const char *servletID, const char *body);
+ TPS_PUBLIC PRLock *GetLock();
+ TPS_PUBLIC int GetCurrentIndex();
+ TPS_PUBLIC void SetCurrentIndex(int index);
+
+ protected:
+ int m_max_conn;
+ ConnectionInfo *m_failoverList;
+ int m_retries;
+ int m_timeout;
+ char *m_Id;
+ bool m_isSSL;
+ char *m_clientnickname;
+ bool m_keepAlive;
+ NameValueSet *m_headers;
+ PRLock *m_lock;
+ int m_curr;
+};
+
+#endif /* HTTPCONNECTION_H */
diff --git a/base/tps/src/include/engine/RA.h b/base/tps/src/include/engine/RA.h
new file mode 100644
index 000000000..9e7db9857
--- /dev/null
+++ b/base/tps/src/include/engine/RA.h
@@ -0,0 +1,374 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_H
+#define RA_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "pk11func.h"
+#include "engine/audit.h"
+#include "ldap.h"
+#include "lber.h"
+#include "main/Base.h"
+#include "main/ConfigStore.h"
+#include "main/Buffer.h"
+#include "main/PublishEntry.h"
+#include "main/AuthenticationEntry.h"
+#include "main/LogFile.h"
+#include "authentication/Authentication.h"
+#include "apdu/APDU.h"
+#include "main/RA_Context.h"
+#include "channel/Secure_Channel.h"
+#include "cms/HttpConnection.h"
+#include "cms/ConnectionInfo.h"
+#include "publisher/IPublisher.h"
+
+/*
+ *
+ * LL_PER_SERVER = 4 these messages will occur only once during the
+ * entire invocation of the server, e.g. at startup
+ * or shutdown time., reading the conf parameters.
+ * Perhaps other infrequent events relating to
+ * failing over of CA, TKS, too
+ *
+ * LL_PER_CONNECTION = 6 these messages happen once per connection - most
+ * of the log events will be at this level
+ *
+ * LL_PER_PDU = 8 these messages relate to PDU processing. If you
+ * have something that is done for every PDU, such
+ * as applying the MAC, it should be logged at this
+ * level
+ *
+ * LL_ALL_DATA_IN_PDU = 9 dump all the data in the PDU - a more chatty
+ * version of the above
+ */
+enum RA_Log_Level {
+ LL_PER_SERVER = 4,
+ LL_PER_CONNECTION = 6,
+ LL_PER_PDU = 8,
+ LL_ALL_DATA_IN_PDU = 9
+};
+
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/* For now, this value must correspond exactly to the successful exit */
+/* status of RA::Initialize( char *cfg_path, RA_Context *ctx ). */
+#define RA_INITIALIZATION_SUCCESS 1
+
+#define TRANSPORT_KEY_NAME "sharedSecret"
+
+typedef char NSSUTF8;
+
+class RA
+{
+ public:
+ RA();
+ ~RA();
+ public:
+ static bool IsAuditEventSelected(const char *auditEvent);
+ static bool IsValidEvent(const char *auditEvent);
+ static void getLastSignature();
+ static int IsTokendbInitialized();
+ static int IsTpsConfigured();
+ TPS_PUBLIC static int Initialize(char *cfg_path, RA_Context *ctx);
+// TPS_PUBLIC static int InitializeInChild(RA_Context *ctx);
+ TPS_PUBLIC static int InitializeInChild(RA_Context *ctx, int nSignedAuditInitCount);
+ TPS_PUBLIC static int Shutdown();
+ TPS_PUBLIC static int Child_Shutdown();
+ public:
+
+ static PK11SymKey *ComputeSessionKey(RA_Session *session,
+ Buffer &CUID,
+ Buffer &keyinfo,
+ Buffer &card_challenge,
+ Buffer &host_challenge,
+ Buffer **host_cryptogram,
+ Buffer &card_cryptogram,
+ PK11SymKey **encSymKey,
+ char** drm_kekSessionKey_s,
+ char** kek_kekSessionKey_s,
+ char **keycheck_s,
+ const char *connId);
+ static void ServerSideKeyGen(RA_Session *session, const char* cuid,
+ const char *userid, char* kekSessionKey_s,
+ char **publickey_s,
+ char **wrappedPrivateKey_s,
+ char **ivParam_s, const char *connId,
+ bool archive, int keysize);
+ static void RecoverKey(RA_Session *session, const char* cuid,
+ const char *userid, char* kekSessionKey_s,
+ char *cert_s, char **publickey_s,
+ char **wrappedPrivateKey_s, const char *connId, char **ivParam_s);
+
+ static Buffer *ComputeHostCryptogram(Buffer &card_challenge, Buffer &host_challenge);
+
+ static PK11SymKey *FindSymKeyByName( PK11SlotInfo *slot, char *keyname);
+ static PK11SymKey *CreateDesKey24Byte(PK11SlotInfo *slot, PK11SymKey *origKey);
+ public:
+ TPS_PUBLIC static ConfigStore *GetConfigStore();
+ TPS_PUBLIC static bool match_comma_list(const char* item, char *list);
+ TPS_PUBLIC static char* remove_from_comma_list(const char*item, char *list);
+ public:
+ TPS_PUBLIC static void Audit(const char *func_name, const char *fmt, ...);
+ TPS_PUBLIC static void Error(const char *func_name, const char *fmt, ...);
+ TPS_PUBLIC static void SelfTestLog(const char *func_name, const char *fmt, ...);
+ TPS_PUBLIC static void Debug(const char *func_name, const char *fmt, ...);
+ TPS_PUBLIC static void DebugBuffer(const char *func_name, const char *prefix, Buffer *buf);
+ TPS_PUBLIC static void Audit(RA_Log_Level level, const char *func_name, const char *fmt, ...);
+ TPS_PUBLIC static void Error(RA_Log_Level level, const char *func_name, const char *fmt, ...);
+ TPS_PUBLIC static void SelfTestLog(RA_Log_Level level, const char *func_name, const char *fmt, ...);
+ TPS_PUBLIC static void Debug(RA_Log_Level level, const char *func_name, const char *fmt, ...);
+ static void DebugBuffer(RA_Log_Level level, const char *func_name, const char *prefix, Buffer *buf);
+ TPS_PUBLIC static void FlushAuditLogBuffer();
+ TPS_PUBLIC static void SignAuditLog(NSSUTF8 *msg);
+ TPS_PUBLIC static char *GetAuditSigningMessage(const NSSUTF8 *msg);
+ TPS_PUBLIC static void SetFlushInterval(int interval);
+ TPS_PUBLIC static void SetBufferSize(int size);
+ static void RunFlushThread(void *arg);
+ TPS_PUBLIC static int setup_audit_log(bool enable_signing, bool signing_changed);
+ TPS_PUBLIC static void enable_audit_logging(bool enable);
+ private:
+ static void AuditThis(RA_Log_Level level, const char *func_name, const char *fmt, va_list ap);
+ static void ErrorThis(RA_Log_Level level, const char *func_name, const char *fmt, va_list ap);
+ static void SelfTestLogThis(RA_Log_Level level, const char *func_name, const char *fmt, va_list ap);
+ static void DebugThis(RA_Log_Level level, const char *func_name, const char *fmt, va_list ap);
+ static void do_free(char *s);
+ public:
+ static int InitializeTokendb(char *cfg_path);
+ static int InitializeSignedAudit();
+ static PRLock *GetVerifyLock();
+ static PRLock *GetConfigLock();
+ TPS_PUBLIC static CERTCertificate **ra_get_certificates(LDAPMessage *e);
+ TPS_PUBLIC static LDAPMessage *ra_get_first_entry(LDAPMessage *e);
+ TPS_PUBLIC static LDAPMessage *ra_get_next_entry(LDAPMessage *e);
+ TPS_PUBLIC static struct berval **ra_get_attribute_values(LDAPMessage *e, const char *p);
+ TPS_PUBLIC static void ra_free_values(struct berval **values);
+ TPS_PUBLIC static char *ra_get_cert_attr_byname(LDAPMessage *e, const char *name);
+ TPS_PUBLIC static char *ra_get_token_id(LDAPMessage *e);
+ TPS_PUBLIC static char *ra_get_cert_tokenType(LDAPMessage *entry);
+ TPS_PUBLIC static char *ra_get_token_status(LDAPMessage *entry);
+ TPS_PUBLIC static char *ra_get_cert_cn(LDAPMessage *entry);
+ TPS_PUBLIC static char *ra_get_cert_status(LDAPMessage *entry);
+ TPS_PUBLIC static char *ra_get_cert_type(LDAPMessage *entry);
+ TPS_PUBLIC static char *ra_get_cert_serial(LDAPMessage *entry);
+ TPS_PUBLIC static char *ra_get_cert_issuer(LDAPMessage *entry);
+ TPS_PUBLIC static int ra_delete_certificate_entry(LDAPMessage *entry);
+ TPS_PUBLIC static int ra_tus_has_active_tokens(char *userid);
+ TPS_PUBLIC static char *ra_get_token_reason(LDAPMessage *msg);
+ TPS_PUBLIC static int ra_get_number_of_entries(LDAPMessage *ldapResult);
+ TPS_PUBLIC static int ra_find_tus_token_entries(char *filter,
+ int maxReturns, LDAPMessage **ldapResult, int num);
+ TPS_PUBLIC static int ra_find_tus_token_entries_no_vlv(char *filter,
+ LDAPMessage **ldapResult, int num);
+ TPS_PUBLIC static int ra_is_tus_db_entry_disabled(char *cuid);
+ TPS_PUBLIC static int ra_is_token_pin_resetable(char *cuid);
+ TPS_PUBLIC static int ra_is_token_present(char *cuid);
+ TPS_PUBLIC static int ra_allow_token_reenroll(char *cuid);
+ TPS_PUBLIC static int ra_allow_token_renew(char *cuid);
+ TPS_PUBLIC static int ra_force_token_format(char *cuid);
+ TPS_PUBLIC static int ra_is_update_pin_resetable_policy(char *cuid);
+ TPS_PUBLIC static char *ra_get_token_policy(char *cuid);
+ TPS_PUBLIC static char *ra_get_token_userid(char *cuid);
+ TPS_PUBLIC static int ra_update_token_policy(char *cuid, char *policy);
+ TPS_PUBLIC static int ra_update_cert_status(char *cn, const char *status);
+ TPS_PUBLIC static int ra_find_tus_certificate_entries_by_order(
+ char *filter, int num, LDAPMessage **msg, int order);
+ TPS_PUBLIC static int ra_find_tus_certificate_entries_by_order_no_vlv(
+ char *filter, LDAPMessage **msg, int order);
+ TPS_PUBLIC static void ra_tus_print_integer(char *out, SECItem *data);
+ TPS_PUBLIC static int ra_update_token_status_reason_userid(char *userid,
+ char *cuid, const char *status, const char *reason, int modifyDateOfCreate);
+ static int tdb_add_token_entry(char *userid, char* cuid, const char *status, const char *token_type);
+ static int tdb_update(const char *userid, char *cuid, char *applet_version, char *key_info, const char *state, const char *reason, const char * token_type);
+ static int tdb_update_certificates(char *cuid, char **tokentypes, char *userid, CERTCertificate **certificates, char **ktypes, char **origins, int numOfCerts);
+ static int tdb_activity(const char *ip, const char *cuid, const char *op, const char *result, const char *msg, const char *userid, const char *token_type);
+ static int testTokendb();
+ static int InitializeAuthentication();
+ static AuthenticationEntry *GetAuth(const char *id);
+ public:
+ static HttpConnection *GetCAConn(const char *id);
+ static void ReturnCAConn(HttpConnection *conn);
+ static HttpConnection *GetTKSConn(const char *id);
+ static void ReturnTKSConn(HttpConnection *conn);
+
+ static HttpConnection *GetDRMConn(const char *id);
+ static void ReturnDRMConn(HttpConnection *conn);
+ static int GetCurrentIndex(HttpConnection *conn);
+ static LogFile* GetLogFile(const char *log_type);
+
+ public:
+
+ static void SetPodIndex(int index);
+ static int GetPodIndex();
+ TPS_PUBLIC static int GetAuthCurrentIndex();
+ static void SetAuthCurrentIndex(int index);
+ TPS_PUBLIC static PRLock *GetAuthLock();
+ TPS_PUBLIC static void IncrementAuthCurrentIndex(int len);
+ TPS_PUBLIC static void update_signed_audit_selected_events(char *new_selected);
+ TPS_PUBLIC static void update_signed_audit_enable(const char *enable);
+ TPS_PUBLIC static void update_signed_audit_log_signing(const char *enable);
+
+ static void SetGlobalSecurityLevel(SecurityLevel sl);
+ static SecurityLevel GetGlobalSecurityLevel();
+ public: /* default values */
+ static const char *CFG_DEF_CARDMGR_INSTANCE_AID;
+ static const char *CFG_DEF_NETKEY_INSTANCE_AID;
+ static const char *CFG_DEF_NETKEY_FILE_AID;
+ static const char *CFG_DEF_NETKEY_OLD_INSTANCE_AID;
+ static const char *CFG_DEF_NETKEY_OLD_FILE_AID;
+ static const char *CFG_DEF_APPLET_SO_PIN;
+ public:
+ static const char *CFG_APPLET_DELETE_NETKEY_OLD;
+ static const char *CFG_APPLET_CARDMGR_INSTANCE_AID;
+ static const char *CFG_APPLET_NETKEY_INSTANCE_AID;
+ static const char *CFG_APPLET_NETKEY_FILE_AID;
+ static const char *CFG_APPLET_NETKEY_OLD_INSTANCE_AID;
+ static const char *CFG_APPLET_NETKEY_OLD_FILE_AID;
+ static const char *CFG_APPLET_SO_PIN;
+ static const char *CFG_DEBUG_ENABLE;
+ static const char *CFG_DEBUG_FILENAME;
+ static const char *CFG_DEBUG_LEVEL;
+ static const char *CFG_AUDIT_ENABLE;
+ static const char *CFG_AUDIT_FILENAME;
+ static const char *CFG_SIGNED_AUDIT_FILENAME;
+ static const char *CFG_AUDIT_LEVEL;
+ static const char *CFG_AUDIT_SIGNED;
+ static const char *CFG_AUDIT_SIGNING_CERT_NICK;
+ static const char *CFG_AUDIT_SELECTED_EVENTS;
+ static const char *CFG_AUDIT_SELECTABLE_EVENTS;
+ static const char *CFG_AUDIT_NONSELECTABLE_EVENTS;
+ static const char *CFG_ERROR_LEVEL;
+ static const char *CFG_ERROR_ENABLE;
+ static const char *CFG_ERROR_FILENAME;
+ static const char *CFG_SELFTEST_LEVEL;
+ static const char *CFG_SELFTEST_ENABLE;
+ static const char *CFG_SELFTEST_FILENAME;
+ static const char *CFG_CHANNEL_SEC_LEVEL;
+ static const char *CFG_CHANNEL_ENCRYPTION;
+ static const char *CFG_AUDIT_BUFFER_SIZE;
+ static const char *CFG_AUDIT_FLUSH_INTERVAL;
+ static const char *CFG_AUDIT_FILE_TYPE;
+ static const char *CFG_DEBUG_FILE_TYPE;
+ static const char *CFG_ERROR_FILE_TYPE;
+ static const char *CFG_SELFTEST_FILE_TYPE;
+ static const char *CFG_AUDIT_PREFIX;
+ static const char *CFG_DEBUG_PREFIX;
+ static const char *CFG_ERROR_PREFIX;
+ static const char *CFG_SELFTEST_PREFIX;
+
+
+ static const char *CFG_AUTHS_ENABLE;
+ static const char *CFG_AUTHS_CURRENTIMPL;
+ static const char *CFG_AUTHS_PLUGINS_NUM;
+ static const char *CFG_AUTHS_PLUGIN_NAME;
+
+ static const char *CFG_IPUBLISHER_LIB;
+ static const char *CFG_IPUBLISHER_FACTORY;
+
+ public:
+ static const char *TKS_RESPONSE_STATUS;
+ static const char *TKS_RESPONSE_SessionKey;
+ static const char *TKS_RESPONSE_EncSessionKey;
+ static const char *TKS_RESPONSE_KEK_DesKey;
+ static const char *TKS_RESPONSE_DRM_Trans_DesKey;
+ static const char *TKS_RESPONSE_HostCryptogram;
+
+ public:
+ static int m_used_tks_conn;
+ static int m_used_ca_conn;
+
+ static int m_used_drm_conn;
+ static HttpConnection* m_drmConnection[];
+ static int m_drmConns_len;
+ static int m_pod_curr;
+ static int m_auth_curr;
+ static bool m_pod_enable;
+ static PRLock *m_verify_lock;
+ static PRLock *m_pod_lock;
+ static PRLock *m_auth_lock;
+ static PRLock *m_error_log_lock;
+ static PRLock *m_selftest_log_lock;
+ static PRMonitor *m_audit_log_monitor;
+ static PRLock *m_debug_log_lock;
+ static PRLock *m_config_lock;
+ static int m_audit_log_level;
+ static int m_debug_log_level;
+ static int m_error_log_level;
+ static int m_selftest_log_level;
+ TPS_PUBLIC static bool m_audit_signed;
+ TPS_PUBLIC static bool m_audit_enabled;
+ static SECKEYPrivateKey *m_audit_signing_key;
+ static char *m_last_audit_signature;
+ static SECOidTag m_audit_signAlgTag;
+ TPS_PUBLIC static char *m_signedAuditSelectedEvents;
+ TPS_PUBLIC static char *m_signedAuditSelectableEvents;
+ TPS_PUBLIC static char *m_signedAuditNonSelectableEvents;
+ static char *m_audit_log_buffer;
+ static PRThread *m_flush_thread;
+ static size_t m_bytes_unflushed;
+ static size_t m_buffer_size;
+ static int m_flush_interval;
+
+ static HttpConnection* m_caConnection[];
+ static HttpConnection* m_tksConnection[];
+ static int m_caConns_len;
+ static int m_tksConns_len;
+ static int m_auth_len;
+ static AuthenticationEntry *m_auth_list[];
+ static SecurityLevel m_global_security_level;
+ static void SetCurrentIndex(HttpConnection *&conn, int index);
+
+ static PublisherEntry *publisher_list;
+ static int m_num_publishers;
+ static RA_Context *m_ctx;
+
+
+ static PublisherEntry *getPublisherById(const char *publisher_id);
+ static int InitializePublishers();
+ static int InitializeHttpConnections(const char *id, int *len, HttpConnection **conn, RA_Context *ctx);
+ static void CleanupPublishers();
+ static int Failover(HttpConnection *&conn, int len);
+
+ TPS_PUBLIC static SECCertificateUsage getCertificateUsage(const char *certusage);
+ TPS_PUBLIC static bool verifySystemCertByNickname(const char *nickname, const char *certUsage);
+ TPS_PUBLIC static bool verifySystemCerts();
+
+};
+
+#endif /* RA_H */
diff --git a/base/tps/src/include/engine/audit.h b/base/tps/src/include/engine/audit.h
new file mode 100644
index 000000000..f8b50de37
--- /dev/null
+++ b/base/tps/src/include/engine/audit.h
@@ -0,0 +1,90 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef AUDIT_H
+#define AUDIT_H
+
+#define AUDIT_SIG_MSG_FORMAT "[%s] %x [AuditEvent=%s][SubjectID=%s][Outcome=%s] signature of audit buffer just flushed: sig: %s"
+#define AUDIT_MSG_FORMAT "[SubjectID=%s][Outcome=%s] %s"
+
+// for EV_ROLE_ASSUME
+#define AUDIT_MSG_ROLE "[SubjectID=%s][Role=%s][Outcome=%s] %s"
+
+// for EV_CONFIG, EV_CONFIG_ROLE, EV_CONFIG_TOKEN, EV_CONFIG_PROFILE, EV_CONFIG_AUDIT
+/*
+ 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
+ Object which identifies the object being modified has the same format name;;value eg. tokenid;;12345
+*/
+#define AUDIT_MSG_CONFIG "[SubjectID=%s][Role=%s][Outcome=%s][Object=%s][ParamNameValPairs=%s] %s"
+
+// for EV_APPLET_UPGRADE; note: "op" is operation such as "format," "enrollment"
+#define AUDIT_MSG_APPLET_UPGRADE "[SubjectID=%s][CUID=%s][MSN=%s][Outcome=%s][op=%s][KeyVersion=%s][OldAppletVersion=%s][NewAppletVersion=%s] %s"
+
+// for EV_KEY_CHANGEOVER; note: "op" is operation such as "format," "enrollment," "pinReset," "renewal"
+#define AUDIT_MSG_KEY_CHANGEOVER "[SubjectID=%s][CUID=%s][MSN=%s][Outcome=%s][op=%s][AppletVersion=%s][OldKeyVersion=%s][NewKeyVersion=%s] %s"
+
+// for EV_AUTH_SUCCESS and EV_AUTH_FAIL
+#define AUDIT_MSG_AUTH "[SubjectID=%s][AuthID=%s][Outcome=%s] %s"
+
+// for EV_AUTHZ_SUCCESS and EV_AUTHZ_FAIL
+#define AUDIT_MSG_AUTHZ "[SubjectID=%s][op=%s][Outcome=%s] %s"
+
+// for op's EV_FORMAT, EV_ENROLLMENT, EV_PIN_RESET, EV_RENEWAL
+#define AUDIT_MSG_PROC "[SubjectID=%s][CUID=%s][MSN=%s][Outcome=%s][op=%s][AppletVersion=%s][KeyVersion=%s] %s"
+
+// for op's EV_ENROLLMENT and EV_RENEWAL.
+#define AUDIT_MSG_PROC_CERT_REQ "[SubjectID=%s][CUID=%s][MSN=%s][Outcome=%s][op=%s][AppletVersion=%s][KeyVersion=%s][Serial=%s][CA_ID=%s] %s"
+
+// op is either "revoke" or "unrevoke"
+#define AUDIT_MSG_CERT_STATUS_CHANGE "[SubjectID=%s][Outcome=%s][op=%s][Serial=%s][CA_ID=%s] %s"
+
+/*
+ * Audit events definitions
+ */
+#define EV_AUDIT_LOG_STARTUP "AUDIT_LOG_STARTUP"
+#define EV_AUDIT_LOG_SHUTDOWN "AUDIT_LOG_SHUTDOWN"
+#define EV_CIMC_CERT_VERIFICATION "CIMC_CERT_VERIFICATION"
+#define EV_ROLE_ASSUME "ROLE_ASSUME"
+#define EV_ENROLLMENT "ENROLLMENT"
+#define EV_PIN_RESET "PIN_RESET"
+#define EV_FORMAT "FORMAT"
+#define EV_AUTHZ_FAIL "AUTHZ_FAIL"
+#define EV_AUTHZ_SUCCESS "AUTHZ_SUCCESS"
+
+// config operations from the TUS interface
+#define EV_CONFIG "CONFIG" // for config operations not specifically defined below
+#define EV_CONFIG_ROLE "CONFIG_ROLE"
+#define EV_CONFIG_TOKEN "CONFIG_TOKEN"
+#define EV_CONFIG_PROFILE "CONFIG_PROFILE"
+#define EV_CONFIG_AUDIT "CONFIG_AUDIT"
+
+#define EV_APPLET_UPGRADE "APPLET_UPGRADE"
+#define EV_KEY_CHANGEOVER "KEY_CHANGEOVER"
+
+#define EV_RENEWAL "RENEWAL"
+
+// authentication for both user login for token ops and role user login (this is different from EV_AUTHZ which is for role authorization)
+#define EV_AUTH_SUCCESS "AUTH_SUCCESS"
+#define EV_AUTH_FAIL "AUTH_FAIL"
+
+#endif //AUDIT_H
diff --git a/base/tps/src/include/httpClient/httpc/AccessLogger.h b/base/tps/src/include/httpClient/httpc/AccessLogger.h
new file mode 100644
index 000000000..2b600d7e6
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/AccessLogger.h
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __ACCESS_LOGGER_H__
+#define __ACCESS_LOGGER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/Logger.h"
+
+/**
+ * A singleton class for writing to an access log
+ */
+class EXPORT_DECL AccessLogger : public Logger {
+private:
+ AccessLogger();
+ virtual ~AccessLogger();
+
+public:
+/**
+ * Gets a logger object with parameters obtained from the configuration manager
+ */
+static AccessLogger *GetAccessLogger();
+
+/**
+ * Writes an access log entry
+ *
+ * @param hostName The IP address or host name of the requestor
+ * @param userName The authenticated user name; NULL or "" if not authenticated
+ * @param requestName The name of the requested function
+ * @param status The status returned to the client
+ * @param responseLength The number of bytes returned to the client
+ * @return 0 on success
+ */
+int Log( const char *hostName,
+ const char *userName,
+ const char *requestName,
+ int status,
+ int responseLength );
+
+/**
+ * Initializes the object with parameters from the Config Manager
+ *
+ * @param configName The name of the configuration entry to use
+ * @return 0 on success
+ */
+ int Initialize( const char *configName );
+
+/**
+ * Flush any unwritten buffers
+ */
+void Flush();
+
+protected:
+/**
+ * Gets a formatted timestamp
+ *
+ * @param now The current time
+ * @param buffer Buffer to put time in
+ * @return A formatted timestamp
+ */
+char *GetTimeStamp( struct tm *now, char *buffer );
+
+private:
+ char *m_buffer;
+ int m_bufferIndex;
+ int m_bufferTime;
+ int m_bufferSize;
+ time_t m_lastWrite;
+ char m_gmtOffset[16];
+};
+
+#endif // __ACCESS_LOGGER_H__
diff --git a/base/tps/src/include/httpClient/httpc/Auth.h b/base/tps/src/include/httpClient/httpc/Auth.h
new file mode 100644
index 000000000..72a5f77ee
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/Auth.h
@@ -0,0 +1,155 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_AUTH_H__
+#define __PS_AUTH_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "ldap.h"
+
+class PSConfig;
+class Pool;
+class PoolNode;
+
+/**
+ * Utility classes for authentication and authorization
+ *
+ * @author rweltman@netscape.com
+ * @version 1.0
+ */
+
+/**
+ * Maintains a pool of LDAP connections; not yet implemented as a pool
+ */
+class LDAPConnectionPool {
+public:
+ LDAPConnectionPool( const char *host, int port, int poolSize );
+ virtual ~LDAPConnectionPool() {}
+ int Initialize();
+ PoolNode *GetConnection();
+ PoolNode *GetAuthenticatedConnection( const char *binddn,
+ const char *bindpwd );
+ void ReleaseConnection( PoolNode *node );
+protected:
+private:
+ const char* m_host;
+ int m_port;
+ int m_size;
+ Pool *m_pool;
+ bool m_initialized;
+};
+
+/**
+ * Produces an authenticator for an auth domain and authenticates
+ */
+class EXPORT_DECL Authenticator {
+public:
+ virtual int Authenticate( const char *username,
+ const char *password,
+ char *&actualID ) = 0;
+ static Authenticator *GetAuthenticator( const char *domain );
+};
+
+class EXPORT_DECL LDAPAuthenticator:public Authenticator {
+public:
+ LDAPAuthenticator();
+ virtual ~LDAPAuthenticator();
+ virtual int Authenticate( const char *username,
+ const char *password,
+ char *&dn );
+
+protected:
+ static int GetHashSize();
+ char *CheckCache( const char *username,
+ const char *password );
+ void UpdateCache( const char *username,
+ const char *dn,
+ const char *password );
+ char *CreateHash( const char *password,
+ char *hash,
+ int maxChars );
+ /**
+ * Returns the DN corresponding to a username, if any
+ *
+ * @param username The user name to look up
+ * @param status The status of an LDAP search, if any
+ * @return The corresponding DN, or NULL if no DN found
+ */
+ char *GetUserDN( const char *username, int& status );
+
+private:
+ LDAPConnectionPool *m_pool;
+ const char* m_host;
+ int m_port;
+ const char* m_binddn;
+ const char* m_bindpassword;
+ const char* m_basedn;
+ const char* m_searchfilter;
+ const char* m_searchscope;
+ int m_nsearchscope;
+ char* m_attrs[2];
+ StringKeyCache *m_cache;
+};
+
+class EXPORT_DECL LDAPAuthorizer {
+public:
+ LDAPAuthorizer();
+ virtual ~LDAPAuthorizer();
+ static LDAPAuthorizer *GetAuthorizer();
+ virtual int Authorize( const char *dn,
+ const char *pwd,
+ const char *methodName );
+
+protected:
+ int GetLdapConnection( LDAP** ld );
+ int CheckCache( const char *username,
+ const char *methodName );
+ void UpdateCache( const char *username,
+ const char *methodName );
+
+private:
+ LDAPConnectionPool *m_pool;
+ const char* m_binddn;
+ const char* m_bindpassword;
+ const char* m_basedn;
+ const char* m_searchfilter;
+ const char* m_searchscope;
+ int m_nsearchscope;
+ char* m_attrs[2];
+ StringKeyCache *m_cache;
+};
+
+#endif // __PS_HELPER_H__
diff --git a/base/tps/src/include/httpClient/httpc/ByteBuffer.h b/base/tps/src/include/httpClient/httpc/ByteBuffer.h
new file mode 100644
index 000000000..cd5568c35
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/ByteBuffer.h
@@ -0,0 +1,194 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __BYTE_BUFFER_H
+#define __BYTE_BUFFER_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * ByteBuffer.h 1.000 06/12/2002
+ *
+ * A byte buffer class
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+typedef unsigned char Byte;
+
+class EXPORT_DECL ByteBuffer {
+public:
+ /**
+ * Constructor
+ */
+ ByteBuffer();
+
+ /**
+ * Destructor
+ */
+ virtual ~ByteBuffer();
+
+public:
+ /**
+ * Reads a single byte from the buffer
+ *
+ * @param b byte returned
+ * @return 0 on success
+ */
+ int GetByte(Byte* b);
+
+ /**
+ * Reads a number of bytes as specified by size from the buffer
+ *
+ * @param size bytes to read
+ * @param buf bytes read
+ * @return 0 on success
+ */
+ int GetBytes(int size, Byte* buf);
+
+ /**
+ * Reads a short value from the buffer
+ *
+ * @param s a short value
+ * @return 0 on success
+ */
+ int GetShort(unsigned short* s);
+
+ /**
+ * Reads a integer value from the buffer
+ *
+ * @param i a integer value
+ * @return 0 on success
+ */
+ int GetInt(unsigned int* i);
+
+ /**
+ * Reads a string of given length from the buffer
+ *
+ * @param len length of the string
+ * @param str string value
+ * @return 0 on success
+ */
+ int GetString(int len, char* str);
+
+ /**
+ * Writes a single byte to the buffer
+ *
+ * @param b byte to set
+ * @return 0 on success
+ */
+ int SetByte(Byte b);
+
+ /**
+ * Writes a number of bytes as specified by size to the buffer
+ *
+ * @param size number of bytes
+ * @param buf bytes to write
+ * @return 0 on success
+ */
+ int SetBytes(int size, Byte* buf);
+
+ /**
+ * Writes a short value to the buffer
+ *
+ * @param s a short value
+ * @return 0 on success
+ */
+ int SetShort(unsigned short s);
+
+ /**
+ * Writes an integer value to the buffer
+ *
+ * @param i an integer value
+ * @return 0 on success
+ */
+ int SetInt(unsigned int i);
+
+ /**
+ * Writes a string to the buffer
+ *
+ * @param str a string to write
+ * @return 0 on success
+ */
+ int SetString(char* str);
+
+ /**
+ * Gets the current position in the buffer
+ *
+ * @param pos position in the buffer
+ * @return 0 on success
+ */
+ int GetPosition(unsigned long* pos);
+
+ /**
+ * Sets the pointer to the position specified by pos in the buffer
+ *
+ * @param pos position to be set in the buffer
+ * @return 0 on success
+ */
+ int SetPosition(unsigned long pos);
+
+ /**
+ * Gets total number of bytes in the buffer
+ *
+ * @param total total number of bytes
+ * @return 0 on success
+ */
+ int GetTotalBytes(unsigned long* total);
+
+ /**
+ * Dumps the buffer to the debug log
+ *
+ * @param logLevel Lowest debug level for which the log should be dumped
+ */
+ void Dump(int logLevel);
+
+private:
+ int SetTotalBytes(unsigned long size, unsigned long allocUnit);
+ int ValidateBuffer(unsigned long increment);
+
+private:
+ Byte* m_buffer;
+ Byte* m_bufferEnd;
+ Byte* m_bufPtr;
+ Byte* m_maxPtr;
+};
+
+#endif // __BYTE_BUFFER_H
+
diff --git a/base/tps/src/include/httpClient/httpc/CERTUtil.h b/base/tps/src/include/httpClient/httpc/CERTUtil.h
new file mode 100644
index 000000000..1f26efbb8
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/CERTUtil.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef _CERT_UTIL_H
+#define _CERT_UTIL_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * NSS CERT utility functions
+ */
+class EXPORT_DECL CERTUtil {
+private:
+ /**
+ * Constructor - can't be instantiated
+ */
+ CERTUtil() {}
+
+ /**
+ * Destructor
+ */
+ ~CERTUtil() {}
+
+public:
+ static CERTCertificate* FindCertificate(const char* nickname);
+ static SECItem* FindExtension(CERTCertificate* cert, const SECItem* oid);
+ static int GetAsInteger(SECItem* item);
+ static char* GetAsString(SECItem* item);
+ static bool IsCertExpired(CERTCertificate* cert);
+};
+
+#endif // _CERT_UTIL_H
+
diff --git a/base/tps/src/include/httpClient/httpc/Cache.h b/base/tps/src/include/httpClient/httpc/Cache.h
new file mode 100644
index 000000000..bc68f04df
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/Cache.h
@@ -0,0 +1,226 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef _CACHE_H_
+#define _CACHE_H_
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/Iterator.h"
+
+/**
+ * Simple cache implementation
+ */
+
+/**
+ * Contains a cache entry and housekeeping info
+ */
+class CacheEntry {
+public:
+ /**
+ * Constructor
+ *
+ * @param key Pointer to the key being cached
+ * @param data Pointer to the data being cached
+ */
+ CacheEntry( const char *key, void *data );
+ /**
+ * Destructor
+ */
+ virtual ~CacheEntry();
+
+ /**
+ * Returns a pointer to the cached key
+ *
+ * @return A pointer to the cached key
+ */
+ const char *GetKey();
+
+ /**
+ * Returns a pointer to the cached data
+ *
+ * @return A pointer to the cached data
+ */
+ void *GetData();
+ /**
+ * Returns the time when the entry was created
+ *
+ * @return The time when the entry was created
+ */
+ long GetStartTime();
+
+private:
+ char *m_key;
+ void *m_data;
+ time_t m_startTime;
+};
+
+/**
+ * Contains a generic cache; this is currently an abstract base class
+ */
+class Cache {
+protected:
+ /**
+ * Default constructor
+ */
+ Cache();
+
+public:
+ /**
+ * Constructor
+ *
+ * @param name of the cache
+ * @param ttl Time to live of each cache entry
+ * @param implicitLock true if the Cached is to do locking internally
+ * when required; false if the caller will take responsibility
+ */
+ Cache( const char *name, int ttl, bool implictLock = false );
+
+ /**
+ * Destructor
+ */
+ virtual ~Cache();
+
+ /**
+ * Returns the number of entries in the cache
+ *
+ * @return The number of entries in the cache
+ */
+ virtual int GetCount();
+
+ /**
+ * Acquires a read lock on the cache. Multiple threads may simultaneously
+ * have a read lock, but attempts to acquire a read lock will block
+ * if another thread already has a write lock. It is illegal to request
+ * a read lock if the thread already has one.
+ */
+ void ReadLock();
+
+ /**
+ * Acquires a write lock on the cache. Only one thread may have a write
+ * lock at any given time; attempts to acquire a write lock will block
+ * if another thread already has one. It is illegal to request
+ * a write lock if the thread already has one.
+ */
+ void WriteLock();
+
+ /**
+ * Releases a read or write lock that the thread has on the cache
+ */
+ void Unlock();
+
+protected:
+ /**
+ * Initializes the object - to be called from the constructor
+ *
+ * @param name of the cache
+ * @param ttl Time to live of each cache entry
+ * @param implicitLock true if the Cached is to do locking internally
+ * when required; false if the caller will take responsibility
+ */
+ void Initialize( const char *name, int ttl, bool implictLock );
+
+protected:
+ const char *m_name;
+ int m_ttl;
+ PLHashTable* m_cache;
+ PRRWLock* m_cacheLock;
+ bool m_implicitLock;
+};
+
+/**
+ * Contains a cache where the keys are strings
+ */
+class StringKeyCache : public Cache {
+public:
+ /**
+ * Constructor
+ *
+ * @param name of the cache
+ * @param ttl Time to live of each cache entry
+ * @param implicitLock true if the Cached is to do locking internally
+ * when required; false if the caller will take responsibility
+ */
+ StringKeyCache( const char *name, int ttl, bool implictLock = false );
+
+ /**
+ * Destructor
+ */
+ virtual ~StringKeyCache();
+
+ /**
+ * Returns a cache entry
+ *
+ * @param key The name of the cache entry
+ * @return The corresponding cache entry, or NULL if not found
+ */
+ CacheEntry *Get( const char *key );
+
+ /**
+ * Adds a cache entry
+ *
+ * @param key The name of the cache entry; an internal copy is made
+ * @param value The value of the cache entry
+ * @return The corresponding cache entry, or NULL if it couldn't be added
+ */
+ CacheEntry *Put( const char *key, void *value );
+
+ /**
+ * Removes a cache entry; does not free the entry object
+ *
+ * @param key The name of the cache entry
+ * @return The corresponding cache entry, or NULL if not found
+ */
+ CacheEntry *Remove( const char *key );
+
+ /**
+ * Allocates and returns a list of keys in the cache
+ *
+ * @param keys Returns an array of names; each name and also the
+ * array itself are to be freed by the caller with delete
+ * @return The number of keys found
+ */
+ int GetKeys( char ***keys );
+
+ /**
+ * Returns an iterator over keys in the cache
+ *
+ * @return An iterator over keys in the cache
+ */
+ Iterator *GetKeyIterator();
+
+};
+
+#endif // _CACHE_H_
diff --git a/base/tps/src/include/httpClient/httpc/Connection.h b/base/tps/src/include/httpClient/httpc/Connection.h
new file mode 100644
index 000000000..5619d0dff
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/Connection.h
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __CONNECTION_H
+#define __CONNECTION_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * Connection.h 1.000 06/12/2002
+ *
+ * Base class for all connection types. A user should extend this class
+ * and provide its protocol specific implementation
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+class EXPORT_DECL Connection {
+ friend class ServerConnection;
+public:
+ /**
+ * Constructor
+ */
+ Connection();
+
+ /**
+ * Destructor
+ */
+ virtual ~Connection();
+
+public:
+ /**
+ * Initiates a connection to a specified host.
+ *
+ * @param host server host name
+ * @param port server port
+ * @return 0 on success, negative error code otherwise
+ */
+ int Connect(const char* host, int port);
+
+ /**
+ * Reads specified number of bytes from the connection. The connection
+ * is locked for the period it is being read.
+ *
+ * @param buf buffer to read into
+ * @param size number of bytes to read
+ * @param timeout timeout before the read terminates
+ * @return number of bytes actually read
+ */
+ int Read(void* buf, int size, long timeout);
+
+ /**
+ * Writes specified number of bytes to the connection. The connection
+ * is locked for the period it is being written.
+ *
+ * @param buf buffer to write from
+ * @param size number of bytes to write
+ * @param timeout timeout before the write terminates
+ * @return number of bytes actually written
+ */
+ int Write(void* buf, int size, long timeout);
+
+ /**
+ * Gets the status of the connection
+ *
+ * @return true if closed, false otherwise
+ */
+ bool IsClosed();
+
+ /**
+ * Closes the connection
+ */
+ void Close();
+
+protected:
+ Socket* m_socket;
+
+private:
+ PRLock* m_lock;
+ bool m_closed;
+};
+
+#endif // __CONNECTION_H
+
diff --git a/base/tps/src/include/httpClient/httpc/ConnectionListener.h b/base/tps/src/include/httpClient/httpc/ConnectionListener.h
new file mode 100644
index 000000000..0b55900b3
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/ConnectionListener.h
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __CONNECTION_LISTENER_H
+#define __CONNECTION_LISTENER_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * ConnectionListener.h 1.000 06/12/2002
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+class EXPORT_DECL ConnectionListener {
+public:
+ virtual int OnConnectionReceived(Connection*) = 0;
+ virtual int OnDataAvailable(Connection*) = 0;
+ virtual int OnConnectionClosed(Connection*) = 0;
+ virtual int OnConnectionError(Connection*, int, const char*) = 0;
+};
+
+#endif // __CONNECTION_LISTENER_H
+
+
diff --git a/base/tps/src/include/httpClient/httpc/DebugLogger.h b/base/tps/src/include/httpClient/httpc/DebugLogger.h
new file mode 100644
index 000000000..37c7971c0
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/DebugLogger.h
@@ -0,0 +1,185 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __DEBUG_LOGGER_H__
+#define __DEBUG_LOGGER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+struct PLHashTable;
+
+/**
+ * The DebugLogger class writes debug log entries conditionally. A single
+ * instance can be shared among modules or different modules can have
+ * their own instances. In either case, the log level can be changed
+ * globally across all instances with a single function call. All instances
+ * write through a singleton to ensure coordination in writing to a single
+ * file.
+ */
+class EXPORT_DECL DebugLogger {
+public:
+private:
+ DebugLogger( const char *moduleName );
+ virtual ~DebugLogger();
+
+public:
+/**
+ * Gets a logger object for a particular module. Provide a module name
+ * if there will be more than one logger object in use, with each module
+ * having its own instance. Pass NULL if a single logger object will be
+ * shared throughout the application.
+ *
+ * @param moduleName Name of a module
+ * @return A logger instance
+ */
+static DebugLogger *GetDebugLogger( const char *moduleName = NULL );
+
+/**
+ * Sets global default values for loggers; the values are assigned to
+ * DebugLogger objects created after this call returns
+ *
+ * @param configParams A table of key-value pairs to assign configuration
+ * parameters
+ */
+static void SetDefaults( PLHashTable *configParams );
+
+/**
+ * Sets the log level for this object
+ *
+ * @param logLevel Log level setting for the module
+ */
+void SetLogLevel( int logLevel );
+
+/**
+ * Gets the log level for this object
+ *
+ * @return logLevel Log level setting for the object
+ */
+int GetLogLevel();
+
+/**
+ * Sets the log level for a particular module or all modules
+ * in all debug logger objects
+ *
+ * @param logLevel Log level setting for the module
+ * @param moduleName Name of the module (does not need to be known before
+ * this call); if NULL, the level is applied to all modules
+ */
+static void SetGlobalLogLevel( int logLevel,
+ const char *moduleName = NULL );
+
+/**
+ * Gets the log level for a particular module
+ *
+ * @param moduleName Name of the module
+ * @return logLevel Log level setting for the module
+ */
+static int GetLogLevel( const char *moduleName );
+
+/**
+ * Writes a debug log entry if logLevel is equal to or higher than the
+ * logLevel setting of the object
+ *
+ * @param logLevel One of the log levels defined above
+ * @param className The name of the class recording the log entry
+ * @param methodName The name of the method that is calling this log method
+ * @param fmt A sprintf format string for the remaining arguments
+ * @param ... A varargs list of things to log
+ * @return 0 on success
+ */
+int Log( int logLevel,
+ const char *className,
+ const char *methodName,
+ const char *fmt, ... );
+
+/**
+ * Writes a trace entry if the logLevel setting of the object is FINER or FINEST
+ *
+ * @param className The name of the class recording the log entry
+ * @param methodName The name of the method that is calling this log method
+ * @param args An optional descriptive string
+ * @return 0 on success
+ */
+int Entering( const char *className,
+ const char *methodName,
+ const char *args = NULL );
+
+/**
+ * Writes a trace entry if the logLevel setting of the object is FINER or FINEST
+ *
+ * @param className The name of the class recording the log entry
+ * @param methodName The name of the method that is calling this log method
+ * @param args An optional descriptive string
+ * @return 0 on success
+ */
+int Exiting( const char *className,
+ const char *methodName,
+ const char *args = NULL );
+/**
+ * Shut down, flushing any buffers and releasing resources
+ */
+void Close();
+
+/**
+ * Shut down, flushing any buffers and releasing resources
+ */
+static void CloseAll();
+
+protected:
+/**
+ * Sets the log level for a particular module
+ *
+ * @param logLevel Log level setting for the module
+ * @param moduleName Name of the module (does not need to be known before
+ * this call)
+ */
+static void SetOneLogLevel( int logLevel,
+ const char *moduleName );
+
+private:
+/**
+ * Initializes the object with parameters from the Config Manager
+ *
+ * @param configName The name of the configuration entry to use
+ * @return 0 on success
+ */
+static int Initialize( const char *configName );
+
+private:
+ int m_level;
+ char *m_module;
+};
+
+#endif // __DEBUG_LOGGER_H__
diff --git a/base/tps/src/include/httpClient/httpc/Defines.h b/base/tps/src/include/httpClient/httpc/Defines.h
new file mode 100644
index 000000000..90af8e3d0
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/Defines.h
@@ -0,0 +1,219 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __DEFINES_H__
+#define __DEFINES_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * Defines.h 1.000 04/30/2002
+ *
+ * This file contains global constants for the Presence Server
+ *
+ * @author Rob Weltman
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+
+// ??? SSR till we have server logging functionality
+#ifdef _DEBUG
+#define PS_LOG_LEVEL PS_LOG_LEVEL_DEBUG
+#else
+#define PS_LOG_LEVEL PS_LOG_LEVEL_WARN
+#endif
+
+#define PS_SERVER_CONFIG_FILE "psserver.conf"
+
+// Configuration file for WASP SOAP server
+#define SOAP_CONFIG_FILE "config.xml"
+
+#define CLIENT_DESCRIPTION "Netscape Presence Server"
+#define SERVER_VERSION "1.0"
+
+// Key to SoapAction field in WASP call context
+#define HEADER_FIELD_SOAPACTION "SOAP_ACTION"
+// Key to status field in WASP call context
+#define HEADER_STATUS "HEADER_STATUS"
+
+// Keys to client parameters passed through the call context
+
+#define SERVER_URL "SERVER_URL"
+#define CERTIFICATE_DIRECTORY "CERTIFICATE_DIRECTORY"
+#define CERTIFICATE_NICKNAME "CERTIFICATE_NICKNAME"
+#define DO_SERVER_CERT_VALIDATION "DO_SERVER_CERT_VALIDATION"
+#define CERTIFICATE_PASSWORD "CERTIFICATE_PASSWORD"
+
+#define STRING_ON_LINE "ONLINE"
+#define STRING_OFF_LINE "OFFLINE"
+
+#define BATCH_RESULT_SIZE 1000
+#define MAX_ATTR_SIZE 5
+
+#define NAME_BUFFER_LENGTH 256
+#define ATTR_BUFFER_LENGTH 256
+
+// Static strings for the attributes we support
+#define BUDDY_ATTRIBUTE_ON_LINE_STATUS "onlinestatus"
+#define BUDDY_ATTRIBUTE_IDLE_TIME "idletime"
+#define BUDDY_ATTRIBUTE_ON_LINE_SINCE "onlinesince"
+#define BUDDY_ATTRIBUTE_AWAY_MESSAGE "awaymessage"
+#define BUDDY_ATTRIBUTE_PROFILE "profile"
+#define BUDDY_ATTRIBUTE_CONNECTION_TYPE "connectiontype"
+#define BUDDY_ATTRIBUTE_CAPABILITIES "capabilities"
+
+#define PS_LOG_LEVEL_DEBUG 0
+#define PS_LOG_LEVEL_WARN 1
+#define PS_LOG_LEVEL_ERROR 2
+
+
+// Presence Server config parameters in the bootstrap configuration file
+// psserver.conf
+#define INSTANCE_ID "instanceid"
+#define HOST_ID "hostid"
+#define DOMAIN_NAME "domainname"
+#define SERVER_HOST "serverhost"
+#define SERVER_PORT "serverport"
+#define BINDDN "binddn"
+#define BINDPASSWORD "bindpassword"
+
+// dn, cn constants
+#define PS_ATTRIBUTE_DN "dn"
+#define PS_ATTRIBUTE_CN "cn"
+
+// nsPlugin class required attributes
+#define PLUGIN_DN "dn"
+#define PLUGIN_CN "cn"
+#define PLUGIN_ID "nspluginid"
+#define PLUGIN_PATH "nspluginpath"
+#define PLUGIN_INIT_FUNC "nsplugininitfunc"
+#define PLUGIN_ENABLED "nspluginenabled"
+#define PLUGIN_VERSION "nspluginversion"
+#define PLUGIN_DESC "nsplugindescription"
+
+// Operations when updating server
+#define PS_OPERATION_ADD 1
+#define PS_OPERATION_DELETE 2
+#define PS_OPERATION_REPLACE 4
+
+// Names of LDAP attributes for the LDAP data source
+#define LDAP_SOURCE_DN "dn"
+#define LDAP_SOURCE_CN "cn"
+#define LDAP_SOURCE_GROUP_NAME "nspsgroupname"
+#define LDAP_SOURCE_SERVER_ADDRESS "nsserveraddress"
+#define LDAP_SOURCE_SERVER_PORT "nsserverport"
+#define LDAP_SOURCE_BIND_DN "nsbinddn"
+#define LDAP_SOURCE_BIND_PASSWORD "nsbindpassword"
+#define LDAP_SOURCE_BASE_DN "nsbasedn"
+#define LDAP_SOURCE_SEARCH_FILTER "nssearchfilter"
+#define LDAP_SOURCE_SEARCH_SCOPE "nssearchscope"
+#define LDAP_SOURCE_IM_ID "nsimattributetype"
+#define LDAP_SOURCE_SEARCHABLE_ATTRIBUTES "nssearchableattributes"
+#define LDAP_SOURCE_ENABLE_SSL "nsenablessl"
+
+
+// Configuration attribute name for max results to return
+#define SEARCH_MAX_RESULTS "nsmaxresults"
+
+// Max results to return if SEARCH_MAX_RESULTS is not defined
+#define DEFAULT_MAX_RESULTS 1000
+
+// Names of configuration clusters
+#define CONFIG_BASE "ConfigBase"
+#define CONFIG_AUTHORIZE "ConfigAuthorize"
+#define CONFIG_ACCESS_LOG "ConfigAccessLog"
+#define CONFIG_ERROR_LOG "ConfigErrorLog"
+#define CONFIG_DEBUG_LOG "ConfigDebugLog"
+#define CONFIG_SERVER_LOCAL "ConfigServerLocal"
+
+// Configuration attributes for loggers
+#define LOG_ACCESS_DIR "nslogdir"
+#define LOG_ERROR_DIR "nslogdir"
+#define LOG_DEBUG_DIR "nslogdir"
+#define LOG_ACCESS_BUFFER_SIZE "nslogbuffersize"
+#define LOG_ACCESS_BUFFER_TIME "nslogbuffertime"
+#define LOG_ACCESS_ROTATION_TIME "nslogrotationtime"
+#define LOG_ACCESS_ROTATION_SIZE "nslogrotationsize"
+#define LOG_ACCESS_MAX_LOGS "nslogmaxlogs"
+#define LOG_ERROR_ROTATION_TIME "nslogrotationtime"
+#define LOG_ERROR_ROTATION_SIZE "nslogrotationsize"
+#define LOG_ERROR_MAX_LOGS "nslogmaxlogs"
+#define LOG_DEBUG_LEVEL "nsloglevel"
+#define LOG_DEBUG_FORMAT "nslogformat"
+
+// Static constants for logging
+#define LOG_ACCESS_FILENAME "access"
+#define LOG_ERROR_FILENAME "error"
+#define LOG_DEBUG_FILENAME "debug"
+
+// Log level definitions
+
+typedef enum {
+ LOGLEVEL_OFF = 0,
+ LOGLEVEL_SEVERE = 1,
+ LOGLEVEL_WARNING = 2,
+ LOGLEVEL_INFO = 3,
+ LOGLEVEL_CONFIG = 4,
+ LOGLEVEL_FINE = 5,
+ LOGLEVEL_FINER = 6,
+ LOGLEVEL_FINEST = 7,
+ LOGLEVEL_ALL = 100
+} LogLevel;
+
+// Config params
+#define CONFIG_DEFAULT_BUFFER_LEN 2048
+#define BASE_CONFIG_DN "cn=Netscape Presence Server,cn=Server Group,cn=%s,ou=%s,o=NetscapeRoot"
+
+// COOL Service params
+#define COOL_SERVICE_SERVER_HOST "CoolServerHost"
+#define COOL_SERVICE_SERVER_PORT "CoolServerPort"
+#define COOL_SERVICE_LOGIN_NAME "CoolLoginName"
+#define COOL_SERVICE_LOGIN_PSWD "CoolLoginPswd"
+
+#define COOL_DEFAULT_SERVER_HOST "coolkey.fedora.redhat.com"
+#define COOL_DEFAULT_SERVER_PORT "5190"
+
+// Key to service ID in global config
+#define SERVICE_TYPE "service_type"
+
+#define MODULE_IM_SERVICE "ModuleIMService"
+#define MODULE_DATA_SOURCE "ModuleDataSource"
+
+#define PROVIDER_BATCH_SIZE_ATTR "nsbatchsize"
+#define PROVIDER_UPDATE_INTERVAL_ATTR "nsupdateinterval"
+
+#define THREAD_POOL_TASK_NAME "ThreadPoolTask"
+
+#endif // __DEFINES_H__
diff --git a/base/tps/src/include/httpClient/httpc/ErrorLogger.h b/base/tps/src/include/httpClient/httpc/ErrorLogger.h
new file mode 100644
index 000000000..df2617b06
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/ErrorLogger.h
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __ERROR_LOGGER_H__
+#define __ERROR_LOGGER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/Logger.h"
+
+/**
+ * A singleton class for writing to an error log
+ */
+class EXPORT_DECL ErrorLogger : public Logger {
+private:
+ ErrorLogger();
+ virtual ~ErrorLogger();
+
+public:
+ /**
+ * Gets a logger object with parameters obtained from the
+ * configuration manager
+ */
+ static ErrorLogger *GetErrorLogger();
+
+ /**
+ * Writes an error log entry
+ *
+ * @param level SEVERE, WARNING, or INFO
+ * @param errorCode An error code
+ * @param fmt A message to be written to the log
+ * @return 0 on success
+ */
+ int Log( int level,
+ int errorCode,
+ const char *fmt,
+ ... );
+
+ /**
+ * Initializes the object with parameters from the Config Manager
+ *
+ * @param configName The name of the configuration entry to use
+ * @return 0 on success
+ */
+ int Initialize( const char *configName );
+
+protected:
+ /**
+ * Writes the fixed argument part of an error log entry
+ *
+ * @param fp File pointer to write to
+ * @param level SEVERE, WARNING, or INFO
+ * @param errorCode An error code
+ * @return 0 on success
+ */
+ int LogProlog( FILE *fp,
+ int level,
+ int errorCode );
+};
+
+#endif // __ERROR_LOGGER_H__
diff --git a/base/tps/src/include/httpClient/httpc/Iterator.h b/base/tps/src/include/httpClient/httpc/Iterator.h
new file mode 100644
index 000000000..9b15a93e2
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/Iterator.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef _ITERATOR_H_
+#define _ITERATOR_H_
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * Base class for iterators
+ */
+
+class EXPORT_DECL Iterator {
+public:
+ /**
+ * Returns true if there is at least one more element
+ *
+ * @return true if there is at least one more element
+ */
+ virtual bool HasMore() = 0;
+
+ /**
+ * Returns the next element, if any
+ *
+ * @return The next element, if any, or NULL
+ */
+ virtual void *Next() = 0;
+};
+
+#endif // _ITERATOR_H_
diff --git a/base/tps/src/include/httpClient/httpc/LogRotationTask.h b/base/tps/src/include/httpClient/httpc/LogRotationTask.h
new file mode 100644
index 000000000..eed098b6b
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/LogRotationTask.h
@@ -0,0 +1,132 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __LOG_ROTATION_TASK_H__
+#define __LOG_ROTATION_TASK_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/ScheduledTask.h"
+
+/**
+ * Log rotation task in Presence Server
+ */
+
+class EXPORT_DECL LogRotationTask: public ScheduledTask {
+public:
+ /**
+ * Constructor - creates an initialized task for log rotation
+ *
+ * @param name Name of task
+ * @param fileName Name of file to rotate
+ * @param startTime Time when the file is to be rotated
+ * @param maxLogs Max logs to keep
+ * @param interval Time between rotations
+ * @param fp File pointer for log file
+ * @param lock Lock for writing to log file
+ */
+ LogRotationTask( const char *name,
+ const char *fileName,
+ time_t startTime,
+ int maxLogs,
+ int interval,
+ FILE **fp,
+ PRLock *lock );
+ /**
+ * Destructor
+ */
+ virtual ~LogRotationTask();
+ /**
+ * Returns a copy of the task
+ *
+ * @return A copy of the task
+ */
+ virtual ScheduledTask *Clone();
+ /**
+ * Executes the task
+ *
+ * @return 0 on successfully starting the task
+ */
+ virtual int Start();
+
+protected:
+ /**
+ * Composes a file name from a base name and a time value
+ *
+ * @param filename The base file name (may be a path)
+ * @param ltime The time value
+ * @param outbuf Returns the composed file name
+ * @return 0 on success
+ */
+ int CreateFilename( const char *filename,
+ time_t ltime,
+ char *outbuf );
+ /**
+ * Extracts the folder and base name components of a file path
+ *
+ * @param fileName The full file path to examine
+ * @param dirName A buffer in which to place the folder found
+ * @param baseName A buffer in which to place the base name found
+ */
+ static void GetPathComponents( const char *fileName,
+ char *dirName,
+ char *baseName );
+
+ /**
+ * Counts the number of files with the same initial path as fileName
+ * (the same folder and the same base pattern)
+ *
+ * @param fileName The file name to compare (including a folder)
+ * @return The number of matching files
+ */
+ static int CountFiles( const char *fileName );
+
+ /**
+ * Purges (deletes) files with the same initial path as fileName
+ * (the same folder and the same base pattern)
+ *
+ * @param fileName The file name to compare (including a folder)
+ * @param maxLogs The number of files to purge to
+ * @return The number of files purged
+ */
+ static int PurgeLogs( const char *fileName, int maxLogs );
+
+ char *m_fileName;
+ int m_maxLogs;
+ FILE **m_fp;
+ PRLock *m_lock;
+};
+
+#endif // __LOG_ROTATION_TASK_H__
diff --git a/base/tps/src/include/httpClient/httpc/Logger.h b/base/tps/src/include/httpClient/httpc/Logger.h
new file mode 100644
index 000000000..b41d5dfbf
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/Logger.h
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __LOGGER_H__
+#define __LOGGER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <time.h>
+
+struct PRLock;
+class LogRotationTask;
+
+/**
+ * A base class for writing to a log
+ */
+class EXPORT_DECL Logger {
+
+protected:
+ /**
+ * Constructor
+ */
+ Logger();
+
+ /**
+ * Destructor
+ */
+ virtual ~Logger();
+
+ /**
+ * Parses a time string in HH:MM format into a time_t for the next
+ * occurrence of the time
+ *
+ * @param timeString A time string in HH:MM format
+ * @return A time_t for the next occurrence of the time, or -1 if the
+ * string is not in a valid format
+ */
+ time_t ParseTime( const char *timeString );
+
+ /**
+ * Creates a time-of-day rotation task
+ *
+ * @param taskName Name of task
+ * @param filename Name of log file
+ * @param rotationTime Time of day to rotate at
+ * @return Rotation task on success
+ */
+ LogRotationTask *CreateRotationTask( const char *taskName,
+ const char *filename,
+ const char *rotationTime );
+
+public:
+
+ /**
+ * Shut down, flushing any buffers and releasing resources
+ */
+ void Close();
+ /**
+ * Gets the local time of day
+ *
+ * @param now The current local time of day
+ */
+ static void GetLocalTime( struct tm *now );
+
+protected:
+ int m_rotationSize;
+ time_t m_rotationTime;
+ int m_maxLogs;
+ char *m_dir;
+ FILE *m_fp;
+ /**
+ * Lock for writing to the file
+ */
+ PRLock *m_fileLock;
+ /**
+ * Task that rotates a log file
+ */
+ LogRotationTask *m_rotator;
+ /**
+ * True if object has been successfully initialized
+ */
+ bool m_initialized;
+};
+
+#endif // __LOGGER_H__
diff --git a/base/tps/src/include/httpClient/httpc/NSPRerrs.h b/base/tps/src/include/httpClient/httpc/NSPRerrs.h
new file mode 100644
index 000000000..2e131fd7a
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/NSPRerrs.h
@@ -0,0 +1,160 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/NSPRerrs.h
+ */
+
+/* General NSPR 2.0 errors */
+/* Caller must #include "prerror.h" */
+
+ER2( PR_OUT_OF_MEMORY_ERROR, "Memory allocation attempt failed." )
+ER2( PR_BAD_DESCRIPTOR_ERROR, "Invalid file descriptor." )
+ER2( PR_WOULD_BLOCK_ERROR, "The operation would have blocked." )
+ER2( PR_ACCESS_FAULT_ERROR, "Invalid memory address argument." )
+ER2( PR_INVALID_METHOD_ERROR, "Invalid function for file type." )
+ER2( PR_ILLEGAL_ACCESS_ERROR, "Invalid memory address argument." )
+ER2( PR_UNKNOWN_ERROR, "Some unknown error has occurred." )
+ER2( PR_PENDING_INTERRUPT_ERROR,"Operation interrupted by another thread." )
+ER2( PR_NOT_IMPLEMENTED_ERROR, "function not implemented." )
+ER2( PR_IO_ERROR, "I/O function error." )
+ER2( PR_IO_TIMEOUT_ERROR, "I/O operation timed out." )
+ER2( PR_IO_PENDING_ERROR, "I/O operation on busy file descriptor." )
+ER2( PR_DIRECTORY_OPEN_ERROR, "The directory could not be opened." )
+ER2( PR_INVALID_ARGUMENT_ERROR, "Invalid function argument." )
+ER2( PR_ADDRESS_NOT_AVAILABLE_ERROR, "Network address not available (in use?)." )
+ER2( PR_ADDRESS_NOT_SUPPORTED_ERROR, "Network address type not supported." )
+ER2( PR_IS_CONNECTED_ERROR, "Already connected." )
+ER2( PR_BAD_ADDRESS_ERROR, "Network address is invalid." )
+ER2( PR_ADDRESS_IN_USE_ERROR, "Local Network address is in use." )
+ER2( PR_CONNECT_REFUSED_ERROR, "Connection refused by peer." )
+ER2( PR_NETWORK_UNREACHABLE_ERROR, "Network address is presently unreachable." )
+ER2( PR_CONNECT_TIMEOUT_ERROR, "Connection attempt timed out." )
+ER2( PR_NOT_CONNECTED_ERROR, "Network file descriptor is not connected." )
+ER2( PR_LOAD_LIBRARY_ERROR, "Failure to load dynamic library." )
+ER2( PR_UNLOAD_LIBRARY_ERROR, "Failure to unload dynamic library." )
+ER2( PR_FIND_SYMBOL_ERROR,
+"Symbol not found in any of the loaded dynamic libraries." )
+ER2( PR_INSUFFICIENT_RESOURCES_ERROR, "Insufficient system resources." )
+ER2( PR_DIRECTORY_LOOKUP_ERROR,
+"A directory lookup on a network address has failed." )
+ER2( PR_TPD_RANGE_ERROR,
+"Attempt to access a TPD key that is out of range." )
+ER2( PR_PROC_DESC_TABLE_FULL_ERROR, "Process open FD table is full." )
+ER2( PR_SYS_DESC_TABLE_FULL_ERROR, "System open FD table is full." )
+ER2( PR_NOT_SOCKET_ERROR,
+"Network operation attempted on non-network file descriptor." )
+ER2( PR_NOT_TCP_SOCKET_ERROR,
+"TCP-specific function attempted on a non-TCP file descriptor." )
+ER2( PR_SOCKET_ADDRESS_IS_BOUND_ERROR, "TCP file descriptor is already bound." )
+ER2( PR_NO_ACCESS_RIGHTS_ERROR, "Access Denied." )
+ER2( PR_OPERATION_NOT_SUPPORTED_ERROR,
+"The requested operation is not supported by the platform." )
+ER2( PR_PROTOCOL_NOT_SUPPORTED_ERROR,
+"The host operating system does not support the protocol requested." )
+ER2( PR_REMOTE_FILE_ERROR, "Access to the remote file has been severed." )
+ER2( PR_BUFFER_OVERFLOW_ERROR,
+"The value requested is too large to be stored in the data buffer provided." )
+ER2( PR_CONNECT_RESET_ERROR, "TCP connection reset by peer." )
+ER2( PR_RANGE_ERROR, "Unused." )
+ER2( PR_DEADLOCK_ERROR, "The operation would have deadlocked." )
+ER2( PR_FILE_IS_LOCKED_ERROR, "The file is already locked." )
+ER2( PR_FILE_TOO_BIG_ERROR,
+"Write would result in file larger than the system allows." )
+ER2( PR_NO_DEVICE_SPACE_ERROR, "The device for storing the file is full." )
+ER2( PR_PIPE_ERROR, "Unused." )
+ER2( PR_NO_SEEK_DEVICE_ERROR, "Unused." )
+ER2( PR_IS_DIRECTORY_ERROR,
+"Cannot perform a normal file operation on a directory." )
+ER2( PR_LOOP_ERROR, "Symbolic link loop." )
+ER2( PR_NAME_TOO_LONG_ERROR, "File name is too long." )
+ER2( PR_FILE_NOT_FOUND_ERROR, "File not found." )
+ER2( PR_NOT_DIRECTORY_ERROR,
+"Cannot perform directory operation on a normal file." )
+ER2( PR_READ_ONLY_FILESYSTEM_ERROR,
+"Cannot write to a read-only file system." )
+ER2( PR_DIRECTORY_NOT_EMPTY_ERROR,
+"Cannot delete a directory that is not empty." )
+ER2( PR_FILESYSTEM_MOUNTED_ERROR,
+"Cannot delete or rename a file object while the file system is busy." )
+ER2( PR_NOT_SAME_DEVICE_ERROR,
+"Cannot rename a file to a file system on another device." )
+ER2( PR_DIRECTORY_CORRUPTED_ERROR,
+"The directory object in the file system is corrupted." )
+ER2( PR_FILE_EXISTS_ERROR,
+"Cannot create or rename a filename that already exists." )
+ER2( PR_MAX_DIRECTORY_ENTRIES_ERROR,
+"Directory is full. No additional filenames may be added." )
+ER2( PR_INVALID_DEVICE_STATE_ERROR,
+"The required device was in an invalid state." )
+ER2( PR_DEVICE_IS_LOCKED_ERROR, "The device is locked." )
+ER2( PR_NO_MORE_FILES_ERROR, "No more entries in the directory." )
+ER2( PR_END_OF_FILE_ERROR, "Encountered end of file." )
+ER2( PR_FILE_SEEK_ERROR, "Seek error." )
+ER2( PR_FILE_IS_BUSY_ERROR, "The file is busy." )
+ER2( PR_IN_PROGRESS_ERROR,
+"Operation is still in progress (probably a non-blocking connect)." )
+ER2( PR_ALREADY_INITIATED_ERROR,
+"Operation has already been initiated (probably a non-blocking connect)." )
+
+#ifdef PR_GROUP_EMPTY_ERROR
+ER2( PR_GROUP_EMPTY_ERROR, "The wait group is empty." )
+#endif
+
+#ifdef PR_INVALID_STATE_ERROR
+ER2( PR_INVALID_STATE_ERROR, "Object state improper for request." )
+#endif
+
+#ifdef PR_NETWORK_DOWN_ERROR
+ER2( PR_NETWORK_DOWN_ERROR, "Network is down." )
+#endif
+
+#ifdef PR_SOCKET_SHUTDOWN_ERROR
+ER2( PR_SOCKET_SHUTDOWN_ERROR, "The socket was previously shut down." )
+#endif
+
+#ifdef PR_CONNECT_ABORTED_ERROR
+ER2( PR_CONNECT_ABORTED_ERROR, "TCP Connection aborted." )
+#endif
+
+#ifdef PR_HOST_UNREACHABLE_ERROR
+ER2( PR_HOST_UNREACHABLE_ERROR, "Host is unreachable." )
+#endif
+
+/* always last */
+ER2( PR_MAX_ERROR, "Placeholder for the end of the list" )
diff --git a/base/tps/src/include/httpClient/httpc/PSBuddy.h b/base/tps/src/include/httpClient/httpc/PSBuddy.h
new file mode 100644
index 000000000..4d84b8727
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSBuddy.h
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_BUDDY_H__
+#define __PS_BUDDY_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSBuddy.h 1.000 05/15/2002
+ *
+ * Interface to store buddy online status attributes
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/15/2002
+ */
+class EXPORT_DECL PSBuddy {
+public:
+ PSBuddy() { };
+ virtual ~PSBuddy() { };
+ /**
+ * Gets the buddy name
+ *
+ * @return name of the buddy
+ */
+ virtual const char* GetName() = 0;
+
+ /**
+ * Gets online status of the buddy
+ *
+ * @return true if online, false otherwise
+ */
+ virtual bool IsOnline() = 0;
+
+ /**
+ * Gets the value of the specified online status attribute
+ *
+ * @param attribute type
+ * @param attribute value upon success
+ * @return 0 on Success, error code otherwise
+ */
+ virtual int GetStatus(const char*, char**) = 0;
+
+ /**
+ * Returns a copy of the buddy
+ *
+ * @return A copy of the buddy
+ */
+ virtual PSBuddy* Clone() = 0;
+};
+
+#endif // __PS_BUDDY_H__
+
+
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSBuddyCache.h b/base/tps/src/include/httpClient/httpc/PSBuddyCache.h
new file mode 100644
index 000000000..3c880074b
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSBuddyCache.h
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_BUDDY_CACHE_H__
+#define __PS_BUDDY_CACHE_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSBuddyCache.h 1.000 04/30/2002
+ *
+ * Cache of PSBuddy objects containing online status
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class PSBuddyCache
+{
+public:
+
+ /**
+ * Constructor - initializes the internal cache
+ */
+ PSBuddyCache();
+
+ /**
+ * Destructor
+ */
+ virtual ~PSBuddyCache();
+
+ /**
+ * Adds a buddy to the cache. The old entry, if exists, is deleted
+ * from the cache
+ *
+ * @param name name of the new buddy
+ * @param buddy object containing onlinestatus attributes
+ * @return 0 on success
+ */
+ int AddBuddy(const char* name, PSBuddy* buddy);
+
+ /**
+ * Removes a buddy from the cache
+ *
+ * @param name name of the buddy to be removed
+ * @return 0 on success
+ */
+ int RemoveBuddy(const char* name);
+
+ /**
+ * Gets the buddy object
+ *
+ * @param name name of the new buddy
+ * @return object containing onlinestatus attributes, NULL if not found
+ */
+ PSBuddy* GetBuddy(const char* name);
+
+ /**
+ * Gets count of buddies in the cache
+ *
+ * @return count of buddies
+ */
+ int GetBuddyCount();
+
+ /**
+ * Gets all the screen names
+ *
+ * @param names On return, contains array of screen names
+ * @return number of screen names
+ */
+ int GetAllBuddies(char*** names);
+
+ /**
+ * Acquires a read lock on the cache. Multiple threads may simultaneously
+ * have a read lock, but attempts to acquire a read lock will block
+ * if another thread already has a write lock. It is illegal to request
+ * a read lock if the thread already has one.
+ */
+ void ReadLock();
+
+ /**
+ * Releases a read lock that the thread has on the cache
+ */
+ void Unlock();
+
+private:
+ StringKeyCache* m_buddies;
+};
+
+#endif // __PS_BUDDY_CACHE_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSBuddyList.h b/base/tps/src/include/httpClient/httpc/PSBuddyList.h
new file mode 100644
index 000000000..49155a8a5
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSBuddyList.h
@@ -0,0 +1,373 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_BUDDY_LIST_H__
+#define __PS_BUDDY_LIST_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSBuddyList.h 1.000 05/21/2002
+ *
+ * This class maintains users information which are set for
+ * online status tracking. The online status of users are updated
+ * through a PSBuddyListener interface implemented by this class.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/21/2002
+ */
+class PSBuddyList :
+ public PSBuddyListener
+{
+private:
+
+ /**
+ * Constructor
+ */
+ PSBuddyList();
+
+ /**
+ * Destructor
+ */
+ virtual ~PSBuddyList();
+
+public:
+
+ /**
+ * Gets an instance of the class
+ */
+ static PSBuddyList* GetBuddyList();
+
+ public:
+
+ /**
+ * Save the users maintain by an instance of presence server
+ * to a local file in the BLT format
+ *
+ * @return 0 on succcess, negative error code otherwise
+ */
+ int SaveBuddyList();
+
+ /**
+ * Loads the users into an instance of presence server
+ * from a local file
+ *
+ * @return 0 on succcess, negative error code otherwise
+ */
+ int LoadBuddyList();
+
+ /**
+ * Sets a service provider. We currently support only one service
+ * provider in a presence server instance.
+ *
+ * @return 0 on succcess, negative error code otherwise
+ */
+ int RegisterService(PSBuddyService* service);
+
+ /**
+ * Gets the online status of a user along with the
+ * requested additional attributes
+ *
+ * @param group group name to which the user belongs
+ * @param name the screen name of the user to query status for
+ * @param nAttributes number of attributes
+ * @param attributes the names of the attributes of the user to return
+ * @param user upon return, filled with user attributes
+ * @return 0 on success, a negative error code on failure
+ */
+ int GetUserStatus( const char* group,
+ const char* name,
+ int nAttributes,
+ char** attributes,
+ PSUser** user );
+
+ /**
+ * Gets the online status of multiple users along with the requested
+ * additional attributes
+ *
+ * @param group group name to which the user belongs
+ * @param nUsers the number of screen names to status query for
+ * @param names the screen names of the users to query status for
+ * @param nAttributes number of attributes
+ * @param attributes the names of the attributes of the user to return
+ * @param user upon return, filled with user attributes
+ * @return 0 on success, a negative error code on failure
+ */
+ int GetMultipleUserStatus( const char* group,
+ int nUsers,
+ char** names,
+ int nAttributes,
+ char** attributes,
+ PSUser*** users );
+
+ /**
+ * Gets the screen names and attributes of users that match
+ * certain search criteria
+ *
+ * @param group group name to query from
+ * @param filter an LDAP-like search expression on
+ * presence status attributes
+ * @param nAttrbiutes number of attributes
+ * @param attributes the names of the attributes of the user to return
+ * @param user upon return, an array of users with
+ * requested attributes
+ * @return number of users returned, or a negative error code
+ */
+ int GetUsersByFilter( const char* group,
+ const char* filter,
+ int nAttributes,
+ char** attributes,
+ PSUser*** users );
+
+ /**
+ * Gets the screen names and attributes of users that match certain search
+ * criteria and sorts the results (currently only by entryId)
+ *
+ * @param group group name to query from
+ * @param filter an LDAP-like search expression on presence status
+ * attributes
+ * @param sortKey name of attribute to sort on
+ * @param sortKeyType 1 for numeric, 2 for string
+ * @param nAttributes number of attributes
+ * @param attributes the names of the attributes of the user to return
+ * @param user upon return, an array of users with requested
+ * attributes
+ * @return number of users returned, or a negative error code
+ */
+ int GetSortedUsersByFilter( const char* group,
+ const char* filter,
+ const char *sortKey,
+ int sortKeyType,
+ int nAttributes,
+ char** attributes,
+ PSUser*** users );
+
+ /**
+ * Gets the number of users who are online or offline in a group
+ *
+ * @param group Name of group to query; NULL or empty for all groups
+ * @param bOnline true to return the count of online users, false for offline
+ * @return Number of users, or a negative error code on failure
+ *
+ * Error Code(s):
+ * PS_UNKOWN_GROUP
+ */
+ int GetBuddyCount( const char* group, int bOnline );
+
+ /**
+ * Add a new group
+ *
+ * @param group name of the new group
+ * @param nAttributes number of attributes
+ * @param attributes attributes the group will support
+ * @return 0 on success, a negative error code on failure
+ */
+ int AddGroup( const char* group, int nAttributes, char** attributes );
+
+ /**
+ * Adds a user to be tracked.
+ *
+ * @param group name of the group to add the user in
+ * @param name screen name of the user to track
+ * @param nAttributes number of attributes
+ * @param attributes the attributes of the users to be stored
+ * @return on success, 0 or an error code
+ */
+ int AddUser( const char* group,
+ const char* name,
+ int nAttributes,
+ PSAttribute** attributes );
+
+ /**
+ * Adds a number of users to track.
+ *
+ * @param group name of the group to which the users belong
+ * @param nUsers number of users
+ * @param users names and attributes of users to track
+ * @return number of users added on success,
+ or a negative error code on failure
+ */
+ int AddUsers( const char* group,
+ int nUsers,
+ PSUser** users );
+
+ /**
+ * Removes a user to be tracked.
+ *
+ * @param group name of the group to which the user belongs
+ * @param name screen name of the user to be removed
+ * @return 0 on success, or a negative error code on failure
+ */
+ int RemoveUser( const char* group, const char* name );
+
+ /**
+ * Removes a number of users to be tracked.
+ *
+ * @param group name of the group to which the users belong
+ * @param nUsers number of users
+ * @param names screen name of the users to be removed
+ * @return number of users removed on success,
+ * or a negative error code on failure
+ */
+ int RemoveUsers( const char* group, int nUsers, char** names );
+
+ /**
+ * Removes a group.
+ *
+ * @param group name of the group to be removed
+ * @return number of users removed on success,
+ * or a negative error code on failure
+ *
+ * Error Code(s):
+ * PS_UNKNOWN_GROUP
+ */
+ int RemoveGroup(const char* group);
+
+ /**
+ * Gets the list of groups.
+ *
+ * @param groups upon return, array containing group names
+ * @return number of groups or 0 if no group present
+ *
+ * Error Code(s):
+ * PS_NO_GROUPS
+ */
+ int GetAllGroups(char*** groups);
+
+ /**
+ * Gets the users in a group(s).
+ *
+ * @param group name of the group to query
+ * @param users upon return, array of User objects
+ * @return number of users returned,
+ * or a negative error code on failure
+ */
+ int GetAllUsers( const char* group, PSUser*** users );
+
+ /**
+ * Gets the attributes supported by a group(s)
+ *
+ * @param group name of the group
+ * @param attributes upon return, array of attributes
+ * @return number of users removed on success,
+ * or a negative error code on failure
+ */
+ int GetSearchableAttributes( const char* group, char*** attributes );
+
+ // PSBuddyListener interface
+ /**
+ * Callback to notify buddy changes
+ *
+ * @param service the reporting buddy service
+ * @param buddy buddy object containing online status attributes
+ * @return 0 on success
+ */
+ int OnBuddyChanged(PSBuddyService* service, PSBuddy* buddy);
+
+ /**
+ * Callback to refresh the list of screen names to the buddy queue
+ *
+ * @param the reporting buddy service
+ * @return 0 on success
+ */
+ int OnRefreshList(PSBuddyService* service);
+
+ /**
+ * Removes a user from a group based on its entry Id
+ *
+ * @param group name of the group
+ * @param entryId user's entry id
+ * @return 0
+ */
+ int RemoveUserByEntryId(const char* group, char* entryId);
+
+protected:
+
+ /**
+ * Gets the max number of search results to return
+ *
+ * @return The max number of search results to return
+ */
+ int GetMaxSearchResults();
+
+private:
+
+ /**
+ * Parses the LDAP like filter and create a map object containing
+ * filter in the form of name-value pair
+ *
+ * @param filter LDAP like filter
+ * @param map array containing break up of filter into name-value pair
+ * @return 0 on success
+ */
+ int ParseFilter(const char* filter, PSAttribute*** map);
+
+ /**
+ * Checks whether a given string is NULL or ""
+ *
+ * @param value a string to be tested for NULL or ""
+ * @return true if NULL, false otherwise
+ */
+ bool IsNull(const char* value);
+
+ /**
+ * Prints buddy information
+ *
+ * @param buddy a buddy object containing online status attributes
+ * @return 0 on success
+ */
+ int DumpBuddy(PSBuddy* buddy);
+
+ /**
+ * Sorts a list of users based on a "entryId"
+ *
+ * @param users array of users to be sorted
+ * @param nUsers number of users in the array
+ * @return 0 on success
+ */
+ int SortUsersByEntryId(PSUser** users, int nUsers);
+
+private:
+ PSBuddyCache* m_buddies;
+ PSGroupCache* m_groups;
+ PSBuddyService* m_service;
+
+ /* flag indicating if buddy list is loaded from the disk */
+ bool m_loadedList;
+};
+
+#endif // __PS_BUDDY_LIST_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSBuddyListener.h b/base/tps/src/include/httpClient/httpc/PSBuddyListener.h
new file mode 100644
index 000000000..87e701373
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSBuddyListener.h
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_BUDDY_LISTENER_H__
+#define __PS_BUDDY_LISTENER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSBuddyListener.h 1.000 05/15/2002
+ *
+ * A listener interface for getting notifications from a buddy service.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/15/2002
+ */
+class PSBuddyListener :
+ public PSListener
+{
+public:
+
+/**
+ * Notifies the listener of the buddy status changes
+ *
+ * @param the reporting buddy service
+ * @param buddy object containing online status attributes
+ * @return 0 on success
+ */
+virtual int OnBuddyChanged(PSBuddyService*, PSBuddy*) = 0;
+
+/**
+ * Notifies the listener of the service to refresh the list
+ * of screen names to the buddy queue
+ *
+ * @param the reporting buddy service
+ * @return 0 on success
+ */
+virtual int OnRefreshList(PSBuddyService*) = 0;
+
+};
+
+#endif // __PS_BUDDY_LISTENER_H__
+
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSBuddyService.h b/base/tps/src/include/httpClient/httpc/PSBuddyService.h
new file mode 100644
index 000000000..2556420e9
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSBuddyService.h
@@ -0,0 +1,121 @@
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_BUDDY_SERVICE_H__
+#define __PS_BUDDY_SERVICE_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSBuddyService.h 1.000 05/16/2002
+ *
+ * A pure virtual class defining Buddy Service interface
+ * to be implemented by the various IM presence service providers.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/16/2002
+ */
+class EXPORT_DECL PSBuddyService {
+public:
+
+/**
+ * Registers a listener with this class. The listener
+ * is notified of any changes to the buddies being tracked.
+ *
+ * @param a buddy service listener
+ * @return 0 on success
+ */
+virtual int RegisterListener(PSListener*) = 0;
+
+/**
+ * An entry point to start the service. This function is responsible
+ * for authentication with the backend service.
+ *
+ * @param config parameters for the service to start
+ * @return 0 on success
+ */
+virtual int SignOn(PSConfig*) = 0;
+
+/**
+ * Shutdown of the service.
+ *
+ * @return 0 on success
+ */
+virtual int SignOff() = 0;
+
+/**
+ * Sets a user name for online status tracking.
+ *
+ * @param user name to be tracked
+ * @return 0 on success
+ */
+virtual int WatchBuddy(const char*) = 0;
+
+/**
+ * Sets a number of users for online status tracking
+ *
+ * @param number of users to be tracked
+ * @param array of user names
+ * @return 0 on success
+ */
+virtual int WatchBuddies(int, char**) = 0;
+
+/**
+ * Unsets a user name from online status tracking.
+ *
+ * @param user name to be tracked
+ * @return 0 on success
+ */
+virtual int UnwatchBuddy(const char*) = 0;
+
+/**
+ * Unsets a number of users from online status tracking
+ *
+ * @param number of users to be tracked
+ * @param array of user names
+ * @return 0 on success
+ */
+virtual int UnwatchBuddies(int, char**) = 0;
+
+/**
+ * Gets the service config entry
+ *
+ * @return config object
+ */
+virtual PSConfig* GetServiceConfig() = 0;
+
+};
+
+#endif // __PS_BUDDY_SERVICE_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSCertExtension.h b/base/tps/src/include/httpClient/httpc/PSCertExtension.h
new file mode 100644
index 000000000..f528a54b4
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSCertExtension.h
@@ -0,0 +1,153 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef _PS_CERT_EXTENSION_H
+#define _PS_CERT_EXTENSION_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * Presence Server cert extension. This extension contains customer
+ * specific information as per the contract apart from host and port
+ * used by BIG service provider to send user updates.
+ */
+
+class EXPORT_DECL PSCertExtension {
+public:
+ /**
+ * Constructor -
+ */
+ PSCertExtension();
+
+ /**
+ * Destructor
+ */
+ ~PSCertExtension();
+
+public:
+ /**
+ * Loads the extension data from the specified cert. This function
+ * will also verify the validity these fields :
+ * HOST_NAME - should not be NULL or ""
+ * PORT_NUMBER - > 0 and <= 65535
+ * MAX_USERS - >= 0
+ *
+ * @param nickname cert nickname which contains the extension
+ * return 0 on success,
+ * -1 if nickname is missing from the argument
+ * -2 if unable to find the cert
+ * -3 if the presence extension is mising
+ * -4 if the required values (hostname, port, maxusers) are invalid
+ * -5 if the cert is expired
+ */
+ int Load(const char* nickname);
+
+ /**
+ * Gets the service version number from the cert ext
+ *
+ * return version number as specified in the cert
+ */
+ int GetVersion();
+
+ /**
+ * Gets the street address from the cert
+ *
+ * return street address as specified in the cert ext
+ */
+ const char* GetStreetAddress();
+
+ /**
+ * Gets the telephone number from the cert
+ *
+ * return telephone number as specified in the cert ext
+ */
+ const char* GetTelephoneNumber();
+
+ /**
+ * Gets the RFC822 name from the cert
+ *
+ * return RFC822 name as specified in the cert ext
+ */
+ const char* GetRFC822Name();
+
+ /**
+ * Gets the IM id from the cert
+ *
+ * return IM id as specified in the cert ext
+ */
+ const char* GetID();
+
+ /**
+ * Gets the hostname from the cert ext
+ *
+ * return hostname as specified in the cert ext
+ */
+ const char* GetHostName();
+
+ /**
+ * Gets the port number from the cert ext
+ *
+ * return port number as specified in the cert ext
+ */
+ int GetPortNumber();
+
+ /**
+ * Gets the max users allowed from the cert ext
+ *
+ * return max users as specified in the cert ext
+ */
+ int GetMaxUsers();
+
+ /**
+ * Gets the service level from the cert ext
+ *
+ * return service level as specified in the cert ext
+ */
+ int GetServiceLevel();
+
+private:
+ int m_version;
+ char* m_streetAddress;
+ char* m_telephoneNumber;
+ char* m_rfc822Name;
+ char* m_id;
+ char* m_hostName;
+ int m_portNumber;
+ int m_maxUsers;
+ int m_serviceLevel;
+};
+
+#endif // _PS_CERT_EXTENSION_H
+
diff --git a/base/tps/src/include/httpClient/httpc/PSCommonLib.h b/base/tps/src/include/httpClient/httpc/PSCommonLib.h
new file mode 100644
index 000000000..09903b38f
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSCommonLib.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef _PS_COMMON_LIB_H_
+#define _PS_COMMON_LIB_H_
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#undef EXPORT_DECL
+#ifdef _MSC_VER
+#ifdef COMMON_LIB_DLL
+#define EXPORT_DECL __declspec( dllexport )
+#else
+#define EXPORT_DECL __declspec (dllimport )
+#endif // COMMON_LIB_DLL
+#else
+#define EXPORT_DECL
+#endif // _MSC_VER
+
+#endif // _PS_COMMON_LIB_H_
diff --git a/base/tps/src/include/httpClient/httpc/PSConfig.h b/base/tps/src/include/httpClient/httpc/PSConfig.h
new file mode 100644
index 000000000..897def3c9
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSConfig.h
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_CONFIG_H__
+#define __PS_CONFIG_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSConfig.h 1.000 04/30/2002
+ *
+ * This class provides structure to store and fetch string type data.
+ * Typical usage of this class would be storing server config data.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class EXPORT_DECL PSConfig {
+public:
+ PSConfig();
+ PSConfig( const char *name );
+ virtual ~PSConfig();
+
+public:
+ void SetAttribute( const char* key, char* value );
+ char* GetAttribute( const char* key );
+ void SetName( const char *name );
+ const char *GetName();
+
+private:
+ PLHashTable* m_entryData;
+ const char *m_name;
+};
+
+#endif // __PS_CONFIG_H__
diff --git a/base/tps/src/include/httpClient/httpc/PSConfigManager.h b/base/tps/src/include/httpClient/httpc/PSConfigManager.h
new file mode 100644
index 000000000..d2f5d3335
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSConfigManager.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_CONFIG_MANAGER_H__
+#define __PS_CONFIG_MANAGER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSConfigManager.h 1.000 04/30/2002
+ *
+ * This class is a singleton that provides access to configuration parameters
+ * for the Presence Server.
+ *
+ * @author rweltman@netscape.com
+ * @version 1.0
+ */
+class EXPORT_DECL PSConfigManager {
+private:
+ PSConfigManager();
+ virtual ~PSConfigManager();
+
+public:
+ static PSConfigManager *GetConfigManager();
+
+public:
+ void SetConfigEntry( PSConfig *entry );
+ PSConfig *GetConfigEntry( const char *name );
+
+private:
+ PLHashTable* m_configEntries;
+};
+
+#endif // __PS_CONFIG_MANAGER_H__
diff --git a/base/tps/src/include/httpClient/httpc/PSConfigReader.h b/base/tps/src/include/httpClient/httpc/PSConfigReader.h
new file mode 100644
index 000000000..a507a26dc
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSConfigReader.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_CONFIG_READER_H__
+#define __PS_CONFIG_READER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSConfigReader.h 1.000 04/30/2002
+ *
+ * This class provides access to the server configuration entries. The
+ * implementation of the config store is hidden from the user.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class EXPORT_DECL PSConfigReader
+{
+private:
+ PSConfigReader();
+ virtual ~PSConfigReader();
+
+public:
+ static PSConfigReader* GetConfigReader();
+
+public:
+ int GetSubEntries(const char* root, char*** entries);
+ int GetEntryConfig(const char* entry, PSConfig** params);
+
+private:
+ int Init();
+
+private:
+ LDAP* m_LD;
+ char* m_bindPassword;
+};
+
+#endif // __PS_CONFIG_READER_H__
diff --git a/base/tps/src/include/httpClient/httpc/PSCrypt.h b/base/tps/src/include/httpClient/httpc/PSCrypt.h
new file mode 100644
index 000000000..bfd05788d
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSCrypt.h
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PSCRYPT_H__
+#define __PSCRYPT_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * Encrypt/Decrypt
+ */
+
+class EXPORT_DECL PSCrypt {
+private:
+ /**
+ * Constructor
+ */
+ PSCrypt( );
+ /**
+ * Destructor
+ */
+ virtual ~PSCrypt();
+
+public:
+ /**
+ * Retuns the decrypted string
+ * Assumption: The input string is base64 encoded
+ * Assumption: Caller has to free the returned string using free
+ * @param base64 encoded string to be decrypted
+ * @param decrypted upon return, string in ascii
+ * @return 0 on success, -1 on failure
+ */
+ static int Decrypt (const char* encrypted, char** decrypted);
+
+ /**
+ * Retuns the encrypted string in base64
+ *
+ * Assumption: Caller has to free the returned string using free
+ * @param text to encrypt
+ * @param encrypted upon return, text in base64
+ * @return 0 on success, -1 on failure
+ */
+ static int Encrypt(const char* text, char** encrypted);
+};
+
+#endif /* __PSCRYPT_H__ */
+
diff --git a/base/tps/src/include/httpClient/httpc/PSDataSourceListener.h b/base/tps/src/include/httpClient/httpc/PSDataSourceListener.h
new file mode 100644
index 000000000..36842904d
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSDataSourceListener.h
@@ -0,0 +1,106 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_DATA_SOURCE_LISTENER_H__
+#define __PS_DATA_SOURCE_LISTENER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/PSUser.h"
+
+/**
+ * PSDataSourceListener.h 1.000 04/30/2002
+ *
+ * A listener class for data source type plugins. The plugins
+ * notify the data source service manager through the functions
+ * provided by this interface.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class EXPORT_DECL PSDataSourceListener :
+ public PSListener
+{
+public:
+
+/**
+ * Notifies the listener of any errors encountered by
+ * the data sources
+ *
+ * @param sourceId reporting source ID
+ * @param errCode error code
+ * @param errString error message
+ * @return 0 on success
+ */
+virtual int OnSourceError( const char* sourceId,
+ int errCode,
+ const char* errString) = 0;
+
+/**
+ * Notifies the listener of any new group
+ *
+ * @param group name of the group
+ * @param nAttrs number of attributes
+ * @param attrs array of attributes supported by the group
+ * @return 0 on success
+ */
+virtual int OnNewGroup( const char* group, int nAttrs, char** attrs ) = 0;
+
+/**
+ * Notifies the listener of any new users
+ *
+ * @param group name of the group
+ * @param nUsers number of users
+ * @param users array containing user objects
+ * @return 0 on success
+ */
+virtual int OnNewUsers( const char* group, int nUsers, PSUser** users ) = 0;
+
+/**
+ * Notifies the listener of any changes to the user being
+ * watched
+ *
+ * @param op operation to be performed ( add/replace/remove)
+ * @param group name of the group
+ * @param user the user object containing modified attributes
+ * @return 0 on success
+ */
+virtual int OnUserChanged(int op, const char* group, PSUser* user) = 0;
+
+};
+
+#endif // __PS_DATA_SOURCE_LISTENER_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSDataSourceManager.h b/base/tps/src/include/httpClient/httpc/PSDataSourceManager.h
new file mode 100644
index 000000000..1b0662b69
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSDataSourceManager.h
@@ -0,0 +1,152 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_DATA_SOURCE_MANAGER_H__
+#define __PS_DATA_SOURCE_MANAGER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSDataSourceManager.h 1.000 05/21/2002
+ *
+ * This class manages presence server data sources plugins.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/21/2002
+ */
+class PSDataSourceManager :
+ public PSDataSourceListener
+{
+private:
+
+ /**
+ * Constructor - creates a data source manager object
+ */
+ PSDataSourceManager();
+
+ /**
+ * Destructor
+ */
+ virtual ~PSDataSourceManager();
+
+public:
+
+ /**
+ * Gets an instance of this class.
+ */
+ static PSDataSourceManager* GetDataSourceManager();
+
+public:
+
+ /**
+ * Registers a listener with this class. Only one listener is
+ * allowed to be registered. If an attempt is made to register
+ * more than one listener, then an error condition is raised.
+ *
+ * @param listener a server listener
+ * @return 0 on success, negative error upon failure
+ */
+ int RegisterListener(PSServerListener* listener);
+
+ /**
+ * Loads all data source type plugins.
+ *
+ * @return 0 for success, negative error code otherwise
+ */
+ int LoadDataSources();
+
+ /**
+ * Unloads all data source type plugins.
+ *
+ * @return 0 for success, negative error code otherwise
+ */
+ int UnloadDataSources();
+
+// PSDataSourceListener interface
+public:
+
+ /**
+ * Callback function to notify the manager upon data source error.
+ *
+ * @param sourceid id of the source calling
+ * @param errorcode error code
+ * @param errorstring error string
+ * @return 0 on success
+ *
+ */
+ int OnSourceError(const char* sourceid, int errorcode, const char* errorstring);
+
+ /**
+ * Callback function to notify the manager upon new group.
+ *
+ * @param group name of the new group
+ * @param nAttrs number of attributes
+ * @param attrs attributes the group will support
+ * @return 0 on success
+ *
+ */
+ int OnNewGroup(const char* group, int nAttrs, char** attrs);
+
+ /**
+ * Callback function to notify the manager of new users
+ *
+ * @param group name of the group
+ * @param nUsers number of users
+ * @param users array containing user objects
+ * @return 0 on success, a negative error code on failure
+ */
+ int OnNewUsers(const char* group, int nUsers, PSUser** users);
+
+ /**
+ * Callback function to notify the manager of changes to a user.
+ * The valid operations are :
+ * PS_OPERATION_ADD
+ * PS_OPERATION_REPLACE
+ * PS_OPERATION_DELETE
+ *
+ * @param op operation to be performed
+ * @param group name of the group
+ * @param user the user object containing modified attributes
+ * @return 0 on success, a negative error code on failure
+ */
+ int OnUserChanged(int op, const char* group, PSUser* user);
+
+private:
+ char* m_dataSourceDN;
+ PSServerListener* m_serverListener;
+ bool m_dataSourcesLoaded;
+};
+
+#endif // __PS_DATA_SOURCE_MANAGER_H__
diff --git a/base/tps/src/include/httpClient/httpc/PSGroup.h b/base/tps/src/include/httpClient/httpc/PSGroup.h
new file mode 100644
index 000000000..8427c39c3
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSGroup.h
@@ -0,0 +1,97 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_GROUP_H__
+#define __PS_GROUP_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+class PSUser;
+
+/**
+ * PSGroup.h 1.000 04/30/2002
+ *
+ * This class stores information about the users belonging to a group.
+ * All the users must belong to at least one group in the server.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class PSGroup
+{
+public:
+ PSGroup(const char* name, int nAttributes, char** attributes);
+ virtual ~PSGroup();
+
+public:
+ char* GetName();
+ int GetAttributeCount();
+ char** GetAttributes();
+ int GetAttributes(int offset, char** & attributes);
+
+ int AddUser(PSUser* user);
+ int RemoveUser(const char* name);
+ PSUser* GetUser(const char* name);
+ bool UserExists(const char* name);
+
+ int GetUserCount();
+ int GetAllUsers(int offset, PSUser** & users, int maxcount);
+ int GetAllUsers(int offset, char** & names, int maxcount);
+
+ int UpdateStatus(const char* name, bool changeToOnline);
+ int GetOnlineUsers(char*** names);
+ int GetOfflineUsers(char*** names);
+ int GetOnlineCount();
+ int GetOfflineCount();
+
+ void ReadLock();
+ void Unlock();
+
+private:
+ char* m_name;
+ int m_count;
+ char** m_attributes;
+
+ PRRWLock* m_psOnlineLock;
+ PRRWLock* m_psOfflineLock;
+ StringList* m_psOnlineUsers;
+ StringList* m_psOfflineUsers;
+
+ StringKeyCache* m_users;
+};
+
+#endif // __PS_GROUP_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSGroupCache.h b/base/tps/src/include/httpClient/httpc/PSGroupCache.h
new file mode 100644
index 000000000..6807e50e4
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSGroupCache.h
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_GROUP_CACHE_H__
+#define __PS_GROUP_CACHE_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSGroupCache.h 1.000 04/30/2002
+ *
+ * This class provides caching of various groups maintained in the
+ * server.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class PSGroupCache
+{
+public:
+ PSGroupCache();
+ virtual ~PSGroupCache();
+
+ int AddGroup(const char* name, PSGroup* group);
+ int RemoveGroup(const char* name);
+ PSGroup* GetGroup(const char* name);
+ bool GroupExists(const char* name);
+ int GetAllGroups(char*** names);
+
+ int GetAttributeCount(int nGroups, char** groups);
+ int GetUserCount(int nGroups, char** groups);
+ int GetOnlineCount(int nGroups, char** groups);
+ int GetOfflineCount(int nGroups, char** groups);
+
+ void ReadLock();
+ void Unlock();
+
+private:
+ StringKeyCache* m_groups;
+};
+
+#endif // __PS_GROUP_CACHE_H__
diff --git a/base/tps/src/include/httpClient/httpc/PSHelper.h b/base/tps/src/include/httpClient/httpc/PSHelper.h
new file mode 100644
index 000000000..7b9240b1b
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSHelper.h
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_HELPER_H__
+#define __PS_HELPER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSHelper.h 1.000 04/30/2002
+ *
+ * A utility class used for logging, utility functions
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+// ??? SSR temporary logging solution
+class EXPORT_DECL PSLogger
+{
+public:
+ PSLogger(int level);
+ virtual ~PSLogger();
+
+public:
+ void Log(int level, char* fmt, ...);
+private:
+ int m_Level;
+};
+
+extern "C" {
+ EXPORT_DECL PSLogger* getServerLogger();
+ EXPORT_DECL void toLower(char* str);
+ EXPORT_DECL void normalize(char* str);
+}
+
+#endif // __PS_HELPER_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSListener.h b/base/tps/src/include/httpClient/httpc/PSListener.h
new file mode 100644
index 000000000..1d85a9912
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSListener.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_LISTENER_H__
+#define __PS_LISTENER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSListener.h 1.000 05/22/2002
+ *
+ * A Generic base class for all listeners.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/22/2002
+ */
+class EXPORT_DECL PSListener
+{
+};
+
+#endif // __PS_LISTENER_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSPRUtil.h b/base/tps/src/include/httpClient/httpc/PSPRUtil.h
new file mode 100644
index 000000000..f3b104cc0
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSPRUtil.h
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef _PS_PRUTIL_H
+#define _PS_PRUTIL_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * NSPR related Utility functions
+ */
+
+// define a stuct to store the mesasge
+struct tuple_str {
+ PRErrorCode errNum;
+ const char * errString;
+};
+
+typedef struct tuple_str tuple_str;
+
+#define ER2(a,b) {a, b},
+#define ER3(a,b,c) {a, c},
+
+
+class EXPORT_DECL PSPRUtil {
+
+private:
+ /**
+ * Constructor - can't be instantiated
+ */
+ PSPRUtil() {}
+
+ /**
+ * Destructor
+ */
+ ~PSPRUtil() {}
+
+public:
+ /**
+ * Returns a string corresponding to an NSPR or NSS error code
+ *
+ * @param errNum Error number from PR_GetError()
+ * @retuns An immutable string, the empty string if the code is not known
+ */
+ static const char * GetErrorString (PRErrorCode errCode);
+
+
+ /**
+ * Returns an error string for the latest NSPR or NSS error
+ *
+ * @return An error string, or the empty string if there is no current
+ * NSPR or NSS error
+ */
+ static const char * GetErrorString();
+
+
+};
+
+#endif // _PS_PRUTIL_H
+
diff --git a/base/tps/src/include/httpClient/httpc/PSPlugin.h b/base/tps/src/include/httpClient/httpc/PSPlugin.h
new file mode 100644
index 000000000..f6655591e
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSPlugin.h
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_PLUGIN_H__
+#define __PS_PLUGIN_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSPlugin.h 1.000 04/30/2002
+ *
+ * Pure virtual class defining the functions to be implemented by
+ * different types of plugins in the server. The listener object passed
+ * the Init function is used to notify the server.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class EXPORT_DECL PSPlugin {
+public:
+
+/**
+ * Initialize the plugin.
+ *
+ * @param a listener for this plugin
+ * @return 0 on success
+ */
+virtual int Init(PSListener*) = 0;
+
+/**
+ * Start the plugin.
+ *
+ * @param config params for the plugin
+ * @return 0 on success
+ */
+virtual int Start(PSConfig*) = 0;
+
+/**
+ * Stops the plugin.
+ *
+ * @return 0 on success
+ */
+virtual int Stop() = 0;
+
+};
+
+#endif // __PSPLUGIN_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSPluginManager.h b/base/tps/src/include/httpClient/httpc/PSPluginManager.h
new file mode 100644
index 000000000..7ea12829a
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSPluginManager.h
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_PLUGIN_MANAGER_H__
+#define __PS_PLUGIN_MANAGER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSPluginManager.h 1.000 05/21/2002
+ *
+ * This class manages loading and unloading of all server plugin modules.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/21/2002
+ */
+class PSPluginManager
+{
+private:
+
+/**
+ * Constructor - creates an instance of Plugin manager object
+ */
+PSPluginManager();
+
+/**
+ * Destructor
+ */
+virtual ~PSPluginManager();
+
+public:
+
+/**
+ * Gets an instance of the class
+ */
+static PSPluginManager* GetPluginManager();
+
+public:
+
+/**
+ * Loads a group of plugins based on the type (dn) specified. If the loading
+ * is successful the specified listener is registered with the plugin and
+ * the plugin is started.
+ *
+ * @param dn root DN of the plugins
+ * @param listener listener associated with the specified type of plugins
+ * @return 0 on success, negative error code otherwise
+ */
+int LoadPlugin(const char* dn, PSListener* listener);
+
+/**
+ * Unloads a group of plugins based on the type ( dn ) specified.
+ * This function just issues a Stop on all the loaded plugins.
+ * It doesn't attempt to release any allocated data structures.
+ *
+ * @param dn root DN of the plugins
+ * @return 0 for success or error code for failure
+ */
+int UnloadPlugin(const char* dn);
+
+private:
+ StringKeyCache* m_serverPlugins;
+};
+
+#endif // __PS_PLUGIN_MANAGER_H__
+
+
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSServer.h b/base/tps/src/include/httpClient/httpc/PSServer.h
new file mode 100644
index 000000000..86d2ca326
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSServer.h
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_SERVER_H__
+#define __PS_SERVER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <time.h>
+#include <ctype.h>
+
+#include "nspr.h"
+#include "plhash.h"
+#include "plstr.h"
+
+#include "ldap.h"
+
+#define PRESENCESERVER_DLL
+#include "httpClient/httpc/PSServerLib.h"
+#include "httpClient/httpc/PresenceServer.h"
+
+#include "httpClient/httpc/Defines.h"
+#include "httpClient/httpc/PSError.h"
+#include "httpClient/httpc/PSHelper.h"
+#include "httpClient/httpc/PSConfig.h"
+#include "httpClient/httpc/PSConfigReader.h"
+#include "httpClient/httpc/PSConfigManager.h"
+#include "httpClient/httpc/Cache.h"
+#include "httpClient/httpc/StringList.h"
+#include "httpClient/httpc/StringUtil.h"
+#include "httpClient/httpc/ScheduledTask.h"
+#include "httpClient/httpc/PSCrypt.h"
+
+#include "httpClient/httpc/PSListener.h"
+#include "httpClient/httpc/PSBuddy.h"
+#include "httpClient/httpc/PSBuddyService.h"
+#include "httpClient/httpc/PSBuddyListener.h"
+#include "httpClient/httpc/PSServerListener.h"
+#include "httpClient/httpc/PSServiceListener.h"
+#include "httpClient/httpc/PSPluginManager.h"
+#include "httpClient/httpc/PSServiceManager.h"
+#include "httpClient/httpc/PSPlugin.h"
+#include "httpClient/httpc/PSUser.h"
+#include "httpClient/httpc/PSDataSourceListener.h"
+#include "httpClient/httpc/PSDataSourceManager.h"
+#include "httpClient/httpc/PSGroup.h"
+#include "httpClient/httpc/PSGroupCache.h"
+#include "httpClient/httpc/PSBuddyCache.h"
+#include "httpClient/httpc/PSBuddyList.h"
+#include "httpClient/httpc/PresenceManager.h"
+#include "httpClient/httpc/PSServerManager.h"
+
+#include "httpClient/httpc/ErrorLogger.h"
+#include "httpClient/httpc/DebugLogger.h"
+#include "httpClient/httpc/ScheduledTask.h"
+#include "httpClient/httpc/LogRotationTask.h"
+#include "httpClient/httpc/TaskList.h"
+#include "httpClient/httpc/Scheduler.h"
+
+#endif // __PS_SERVER_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSServerLib.h b/base/tps/src/include/httpClient/httpc/PSServerLib.h
new file mode 100644
index 000000000..079134230
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSServerLib.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_SERVER_LIB_H__
+#define __PS_SERVER_LIB_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSServerLib.h 1.000 05/27/2002
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/27/2002
+ */
+
+#ifdef _MSC_VER
+ #ifdef PRESENCESERVER_DLL
+ #define EXPORT_DECL __declspec( dllexport )
+ #else
+ #define EXPORT_DECL __declspec (dllimport )
+ #endif // PRESENCESERVER_DLL
+#else
+ #define EXPORT_DECL
+#endif // _MSC_VER
+
+#endif // __PS_SERVER_LIB_H__
+
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSServerListener.h b/base/tps/src/include/httpClient/httpc/PSServerListener.h
new file mode 100644
index 000000000..152fbf58f
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSServerListener.h
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_SERVER_LISTENER_H__
+#define __PS_SERVER_LISTENER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSServerListener.h 1.000 04/30/2002
+ *
+ * A listener class to report back into the server.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class EXPORT_DECL PSServerListener :
+ public PSListener
+{
+public:
+
+/**
+ * Callback to report startup of a service.
+ *
+ * @param reporting module ID
+ * @return 0 on success
+ */
+virtual int OnStartup(const char*) = 0;
+
+/**
+ * Callback to report shutdown of a service.
+ *
+ * @param reporting module ID
+ * @return 0 on success
+ */
+virtual int OnShutdown(const char*) = 0;
+
+/**
+ * Callback to report any errors encountered during service execution.
+ *
+ * @param reporting module ID
+ * @param error code
+ * @param error message
+ * @return 0 on success
+ */
+virtual int OnCriticalError(const char*, int, const char*) = 0;
+
+};
+
+#endif // __PS_SERVER_LISTENER_H__
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSServerManager.h b/base/tps/src/include/httpClient/httpc/PSServerManager.h
new file mode 100644
index 000000000..6597ad605
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSServerManager.h
@@ -0,0 +1,145 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_SERVER_MANAGER_H__
+#define __PS_SERVER_MANAGER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSServerManager.h 1.000 05/21/2002
+ *
+ * This class manages the server execution. It is responsible for loading
+ * of configurations, starting of services and proper shutdown of services.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/21/2002
+ */
+class PSServerManager :
+ public PSServerListener
+{
+private:
+
+/**
+ * Constructor - creates an instance of server manager object
+ */
+PSServerManager();
+
+/**
+ * Destructor
+ */
+virtual ~PSServerManager();
+
+public:
+
+/**
+ * Gets an instance of this class.
+ */
+static PSServerManager* GetServerManager();
+
+public:
+
+/**
+ * Loads general configuration into the ConfigManager
+ *
+ * @return 0 on success, negative error code otherwise
+ */
+int InitServices();
+
+/**
+ * Starts services after server startup. The presence services are
+ * started before anything else and if it fails then no attempt is
+ * made to start other services.
+ *
+ * @return 0 on success, negative error code otherwise
+ */
+int StartServices();
+
+/**
+ * Stops services before server shutdown.
+ *
+ * @return 0 on success, negative error code otherwise
+ */
+int StopServices();
+
+private:
+
+/**
+ * Loads one configuration entry
+ *
+ * @param configdn The DN of the LDAP entry containing the config
+ * @param configName The name of the config entry
+ * @param descr A description of the config entry
+ * @return 0 on success
+ */
+int LoadOneConfig(const char* configdn, const char* configName, const char* descr);
+
+// PSServerListener interface
+public:
+
+/**
+ * Callback to notify server upon a service startup
+ *
+ * @param moduleid the notifying service id
+ * @return 0 on success
+ */
+int OnStartup(const char* moduleid);
+
+/**
+ * Callback to notify server upon a service shutdown
+ *
+ * @param moduleid the notifying service id
+ * @return 0 on success
+ */
+int OnShutdown(const char* moduleid);
+
+/**
+ * Callback to notify server upon a critical errors. The server immediately
+ * shuts down upon receipt of any such notification.
+ *
+ * @param moduleid the notifying service id
+ * @param errorcode negative error code
+ * @param errorstring negative error code
+ * @return 0 on success
+ */
+int OnCriticalError(const char* moduleid, int errorcode, const char* errorstring);
+
+private:
+ bool m_loadServiceDone;
+};
+
+#endif // __PS_SERVER_MANAGER_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSServiceListener.h b/base/tps/src/include/httpClient/httpc/PSServiceListener.h
new file mode 100644
index 000000000..358f0c295
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSServiceListener.h
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_SERVICE_LISTENER_H__
+#define __PS_SERVICE_LISTENER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSServiceListener.h 1.000 05/16/2002
+ *
+ * A listener interface for all the IM services to report back into
+ * service manager.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/16/2002
+ */
+class EXPORT_DECL PSServiceListener :
+ public PSListener
+{
+public:
+
+/**
+ * Callback to report start of a buddy service.
+ *
+ * @param reporting module
+ * @return 0 on success
+ */
+virtual int OnServiceStart(PSBuddyService*) = 0;
+
+/**
+ * Callback to report buddy service errors.
+ *
+ * @param reporting module
+ * @param error code
+ * @param error message
+ * @return 0 on success
+ */
+virtual int OnServiceError(PSBuddyService*, int, const char*) = 0;
+
+
+/**
+ * Callback to report shutdown of a buddy service.
+ *
+ * @param reporting module
+ * @return 0 on success
+ */
+virtual int OnServiceStop(PSBuddyService*) = 0;
+
+};
+
+#endif // __PS_SERVICE_LISTENER_H__
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSServiceManager.h b/base/tps/src/include/httpClient/httpc/PSServiceManager.h
new file mode 100644
index 000000000..1fd755c14
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSServiceManager.h
@@ -0,0 +1,145 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PS_SERVICE_MANAGER_H__
+#define __PS_SERVICE_MANAGER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSServiceManager.h 1.000 05/16/2002
+ *
+ * A Singleton class to manage presence services. Currently we support
+ * only one service to be loaded.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/16/2002
+ */
+class PSServiceManager :
+ public PSServiceListener
+{
+private:
+
+/**
+ * Constructor - creates a service manager object
+ */
+PSServiceManager();
+
+/**
+ * Destructor
+ */
+virtual ~PSServiceManager();
+
+public:
+
+/**
+ * Gets an instance of this class.
+ */
+static PSServiceManager* GetServiceManager();
+
+public:
+
+/**
+ * Registers a listener with this class. Only one listener is
+ * allowed to be registered. If an attempt is made to register
+ * more than one listener, then an error condition is raised.
+ *
+ * @param listener a server listener
+ * @return 0 on success, negative error upon failure
+ */
+int RegisterListener(PSServerListener* listener);
+
+/**
+ * Loads all providers type plugins.
+ *
+ * @return 0 for success, negative error code otherwise
+ */
+int LoadServices();
+
+/**
+ * Unloads all providers type plugins.
+ *
+ * @return 0 for success, negative error code otherwise
+ */
+int UnloadServices();
+
+/**
+ * Gets the service currently loaded. Only one service can
+ * be configured at a time.
+ *
+ * @return an im service
+ */
+PSBuddyService* GetService();
+
+// PSServiceListener interface
+public:
+
+/**
+ * Callback function to notify the manager of a service being started.
+ *
+ * @param service a buddy service
+ */
+int OnServiceStart(PSBuddyService* service);
+
+/**
+ * Callback function to notify the manager of a service error.
+ *
+ * @param service a buddy service
+ * @param errorcode a negative error code
+ * @param errorstring an error message
+ */
+int OnServiceError(PSBuddyService* service, int errorcode, const char* errorstring);
+
+/**
+ * Callback function to notify the manager of a service being stopped.
+ *
+ * @param service a buddy service
+ */
+int OnServiceStop(PSBuddyService* service);
+
+private:
+ char* m_serviceDN;
+ PSServerListener* m_serverListener;
+ PSBuddyService* m_service;
+
+ bool m_servicesLoaded;
+};
+
+#endif // __PS_SERVICE_MANAGER_H__
+
+
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSUser.h b/base/tps/src/include/httpClient/httpc/PSUser.h
new file mode 100644
index 000000000..a66c4e32f
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSUser.h
@@ -0,0 +1,164 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PSUSER_H__
+#define __PSUSER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "PresenceServer.h"
+
+/**
+ * PSUser.h 1.000 04/30/2002
+ *
+ * This class represents one attribute of a user.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class EXPORT_DECL PSAttribute
+{
+public:
+
+/**
+ * Construts a new PSAttribute object.
+ *
+ * @param name name of the attribute
+ * @param value value of the attribute
+ */
+PSAttribute(const char* name, const char* value);
+
+/**
+ * Destructor
+ */
+virtual ~PSAttribute();
+
+/**
+ * Gets the name of the attribute.
+ *
+ * @return name of the attribute
+ */
+char* GetName();
+
+/**
+ * Gets the value of the specified attribute.
+ *
+ * @return value of the attribute
+ */
+char* GetValue();
+
+private:
+ char* m_name;
+ char* m_value;
+};
+
+/**
+ * PSUser.h 1.000 04/30/2002
+ *
+ * This class represents information about a single user.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class EXPORT_DECL PSUser
+{
+public:
+
+/**
+ * Construts a new PSUser object with just one attribute.
+ *
+ * @param name name of the user
+ * @param attribute a user attribute
+ */
+PSUser(const char* name, PSAttribute* attribute);
+
+/**
+ * Construts a new PSUser object with number of attributes.
+ *
+ * @param name name of the user
+ * @param nAttributes number of attributes
+ * @param attribute array containing user attributes
+ */
+PSUser(const char* name, int nAttributes, PSAttribute** attributes);
+
+/**
+ * Destructor
+ */
+virtual ~PSUser();
+
+/**
+ * Gets the name of the user.
+ *
+ * @return user name
+ */
+char* GetName();
+
+/**
+ * Get the count of user attributes.
+ *
+ * @return count of user attributes
+ */
+int GetCount();
+
+/**
+ * Gets a list of attribute objects for the user.
+ *
+ * @return array of attribute objects
+ */
+PSAttribute** GetAttributes();
+
+/**
+ * Gets the user attribute based on the specified attribute name.
+ *
+ * @return user attribute object on success, NULL otherwise
+ */
+PSAttribute* Lookup(char* key);
+
+/**
+ * Creates a new copy of the current user object.
+ *
+ * @return new user object
+ */
+void Clone(PSUser** user);
+
+private:
+ char* m_name;
+ int m_attrCount;
+ PSAttribute** m_attributes;
+};
+
+#endif
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSWaspLib.h b/base/tps/src/include/httpClient/httpc/PSWaspLib.h
new file mode 100644
index 000000000..8fdea6bcc
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSWaspLib.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef _PS_WASP_LIB_H_
+#define _PS_WASP_LIB_H_
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#ifdef _MSC_VER
+#undef EXPORT_DECL
+#ifdef WASP_LIB_DLL
+#define EXPORT_DECL __declspec( dllexport )
+#else
+#define EXPORT_DECL __declspec (dllimport )
+#endif // EXPORT_LIB_DLL
+#else
+#define EXPORT_DECL
+#endif // _MSC_VER
+
+// Key to hostname in WASP CallContext
+#define CONTEXT_HOSTNAME_TOKEN "Hostname"
+
+#endif // _PS_WASP_LIB_H_
diff --git a/base/tps/src/include/httpClient/httpc/Pool.h b/base/tps/src/include/httpClient/httpc/Pool.h
new file mode 100644
index 000000000..074b36b3b
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/Pool.h
@@ -0,0 +1,149 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __POOL_H__
+#define __POOL_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#define AUTOTOOLS_CONFIG_H
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * Utility classes for object pools
+ *
+ * @author rweltman@netscape.com
+ * @version 1.0
+ */
+
+class PoolNode;
+class Pool;
+
+typedef int (*PoolEnumerator)(PoolNode *node);
+
+/**
+ * A node in a pool
+ */
+class EXPORT_DECL PoolNode {
+ friend class Pool;
+public:
+ /**
+ * Constructor
+ *
+ * @param data The real data of the node
+ */
+ PoolNode( void *data );
+ /**
+ * Destructor
+ */
+ virtual ~PoolNode();
+ /**
+ * Returns the real data of the node
+ *
+ * @return The real data of the node
+ */
+ void *GetData();
+ /**
+ * Returns the next entry in the list
+ *
+ * @return The next entry in the list
+ */
+ PoolNode *GetNext();
+ /**
+ * Returns the previous entry in the list
+ *
+ * @return The previous entry in the list
+ */
+ PoolNode *GetPrev();
+private:
+ void *m_data;
+ PoolNode *m_next;
+ PoolNode *m_prev;
+};
+
+/**
+ * A generic object pool
+ */
+class EXPORT_DECL Pool {
+public:
+ /**
+ * Constructor - creates a pool with an internal list of nodes
+ *
+ * @param name Name of pool
+ * @param poolSize Max number of nodes kept
+ * @param enumerator Optional enumerator to be called on destruction
+ */
+ Pool( const char *name, int poolSize, PoolEnumerator enumerator = NULL );
+ /**
+ * Destructor - Empties the pool
+ */
+ virtual ~Pool();
+ /**
+ * Appends an entry to the end of the internal list
+ *
+ * @param node An entry to add
+ * @return The added entry
+ */
+ PoolNode *Append( PoolNode *node );
+ /**
+ * Retrieves the head of the internal list and removes it
+ *
+ * @return The head of the internal list
+ */
+ PoolNode *RemoveHead();
+ /**
+ * Returns true if the pool is empty
+ *
+ * @return true if the pool is empty
+ */
+ bool IsEmpty();
+
+ /**
+ * Returns the number of entries in the pool
+ *
+ * @return The number of entries in the pool
+ */
+ int GetCount();
+
+protected:
+private:
+ PoolNode *m_list;
+ char *m_name;
+ int m_maxNodes;
+ int m_count;
+ PoolEnumerator m_enumerator;
+ PRRWLock *m_lock;
+ PRLock *m_conditionLock;
+ PRCondVar *m_condition;
+};
+
+#endif // __POOL_H__
diff --git a/base/tps/src/include/httpClient/httpc/PresenceManager.h b/base/tps/src/include/httpClient/httpc/PresenceManager.h
new file mode 100644
index 000000000..f7f4f753f
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PresenceManager.h
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PRESENCEMANAGER_H__
+#define __PRESENCEMANAGER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#define AUTOTOOLS_CONFIG_H
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/PSUser.h"
+
+/**
+ * PresenceManager.h 1.000 04/30/2002
+ *
+ * Wrapper class around the core buddylist management API.
+ *
+ * @author Rob Weltman
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class EXPORT_DECL PresenceManager {
+public:
+ PresenceManager();
+ virtual ~PresenceManager();
+
+ int GetUserStatus(const char* group, const char* name, int nAttributes, char** attributes, PSUser** user);
+ int GetMultipleUserStatus(const char* group,
+ int nUsers,
+ char** names,
+ int nAttributes,
+ char** attributes,
+ PSUser*** users);
+ int GetUsersByFilter(const char* group, const char* filter, int nAttributes, char** attributes, PSUser*** users);
+ int GetSortedUsersByFilter(const char* group, const char* filter,
+ const char *sortKey, int sortKeyType,
+ int nAttributes, char** attributes, PSUser*** users);
+ /**
+ * Gets the number of users who are online or offline in a group
+ *
+ * @param group Name of group to query; NULL or empty for all groups
+ * @param bOnline true to return the count of online users, false for
+ * offline
+ * @return Number of users, or a negative error code on failure
+ *
+ * Error Code(s):
+ * PS_UNKOWN_GROUP
+ */
+ int GetUserCount( const char* group, int bOnline );
+ int AddGroup(const char* group, int nAttributes, char** attributes);
+ int AddUser(const char* group, const char* name, int nAttributes, PSAttribute** attributes);
+ int AddUsers(const char* group, int nUsers, PSUser** users);
+ int RemoveUser(const char* group, const char* name);
+ int RemoveUsers(const char* group, int nUsers, char** names);
+ int RemoveGroup(const char* group);
+ int GetAllGroups(char*** groups);
+ int GetAllUsers(const char* group, PSUser*** users);
+ int GetSearchableAttributes(const char* group, char*** attributes);
+
+private:
+};
+
+#endif // __PRESENCEMANAGER_H__
diff --git a/base/tps/src/include/httpClient/httpc/PresenceServer.h b/base/tps/src/include/httpClient/httpc/PresenceServer.h
new file mode 100644
index 000000000..1a9b259e9
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PresenceServer.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PRESENCE_SERVER_H__
+#define __PRESENCE_SERVER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/PSServerLib.h"
+
+/**
+ * PresenceServer.h 1.000 04/30/2002
+ *
+ * Starts and stops presence services
+ *
+ * @author Rob Weltman
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+
+extern "C" {
+EXPORT_DECL int presence_main( int argc, char* argv[] );
+EXPORT_DECL void presence_exit();
+}
+
+#endif // __PRESENCE_SERVER_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PresenceServerImpl.h b/base/tps/src/include/httpClient/httpc/PresenceServerImpl.h
new file mode 100644
index 000000000..8c07b9140
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PresenceServerImpl.h
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __PRESENCE_SERVER_IMPL_H__
+#define __PRESENCE_SERVER_IMPL_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+class PSUser;
+
+/**
+ * PresenceServerImpl.h 1.000 04/30/2002
+ *
+ * Interface for WASP implementation of presence service
+ *
+ * @author Rob Weltman
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+
+class EXPORT_DECL PresenceServerImpl:public PresenceServiceImpl {
+public:
+ PresenceServerImpl() {}
+ virtual ~PresenceServerImpl() {}
+ virtual int getAllGroups (ArrayOfstring *& groups);
+ virtual int getAllUsers (WASP_String * group, ArrayOfstring *& users);
+ virtual int removeGroup (WASP_String * group);
+ virtual int getUsersByFilter (WASP_String * group, WASP_String * filter, int nAttributes, ArrayOfstring * attributes, ArrayOfPresenceUser *& users);
+ virtual int getMultipleUserStatus (WASP_String * group,
+ int nUsers,
+ ArrayOfstring * names,
+ int nAttributes,
+ ArrayOfstring * attributes,
+ ArrayOfPresenceUser *& users);
+ virtual int removeUser (WASP_String * group, WASP_String * name);
+ virtual int getUserStatus (WASP_String * group, WASP_String * name, int nAttributes, ArrayOfstring * attributes, PresenceUser *& user);
+ /**
+ * Gets the number of users who are online or offline in a group
+ *
+ * @param group Name of group to query; NULL or empty for all groups
+ * @param bOnline true to return the count of online users, false for offline
+ * @return Number of users, or a negative error code on failure
+ *
+ * Error Code(s):
+ * PS_UNKOWN_GROUP
+ */
+ virtual int getUserCount( WASP_String* group, int bOnline );
+ virtual int addUsers (WASP_String * group, int nUsers, ArrayOfPresenceUser * users);
+ virtual int addGroup (WASP_String * group, int nAttributes, ArrayOfstring * attributes);
+ virtual int getSearchableAttributes (WASP_String * group, ArrayOfstring *& attributes);
+ virtual int addUser (WASP_String * group, WASP_String * name, int nAttributes, ArrayOfUserAttribute * attributes);
+ virtual int getSortedUsersByFilter (WASP_String * group,
+ WASP_String * filter,
+ WASP_String * sortKey,
+ int sortKeyType,
+ int nAttributes,
+ ArrayOfstring * attributes,
+ ArrayOfPresenceUser *& users);
+ virtual int removeUsers (WASP_String * group, int nUsers, ArrayOfstring * names);
+protected:
+ void doLog(const char *func, int status);
+ static int parseUsers(int nUsers, PSUser** tusers,
+ ArrayOfPresenceUser*& users);
+ /**
+ * Decodes an array of Unicode strings from a WASP string array object;
+ * the result should be freed by deleting the individual strings as well as
+ * the array itself; nStrings is set to 0 if wStrings is NULL
+ *
+ * @param attributes WASP string array object to convert
+ * @param nAttributes Number of strings to process
+ * @return Array of strings
+ */
+ char **DecodeStringArrayObject( ArrayOfstring* wStrings,
+ int& nStrings );
+};
+
+#endif // __PRESENCE_SERVER_IMPL_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/SECerrs.h b/base/tps/src/include/httpClient/httpc/SECerrs.h
new file mode 100644
index 000000000..d7495ff28
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/SECerrs.h
@@ -0,0 +1,522 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/SECerrs.h
+ */
+
+/* General security error codes */
+/* Caller must #include "secerr.h" */
+
+ER3(SEC_ERROR_IO, SEC_ERROR_BASE + 0,
+"An I/O error occurred during security authorization.")
+
+ER3(SEC_ERROR_LIBRARY_FAILURE, SEC_ERROR_BASE + 1,
+"security library failure.")
+
+ER3(SEC_ERROR_BAD_DATA, SEC_ERROR_BASE + 2,
+"security library: received bad data.")
+
+ER3(SEC_ERROR_OUTPUT_LEN, SEC_ERROR_BASE + 3,
+"security library: output length error.")
+
+ER3(SEC_ERROR_INPUT_LEN, SEC_ERROR_BASE + 4,
+"security library has experienced an input length error.")
+
+ER3(SEC_ERROR_INVALID_ARGS, SEC_ERROR_BASE + 5,
+"security library: invalid arguments.")
+
+ER3(SEC_ERROR_INVALID_ALGORITHM, SEC_ERROR_BASE + 6,
+"security library: invalid algorithm.")
+
+ER3(SEC_ERROR_INVALID_AVA, SEC_ERROR_BASE + 7,
+"security library: invalid AVA.")
+
+ER3(SEC_ERROR_INVALID_TIME, SEC_ERROR_BASE + 8,
+"Improperly formatted time string.")
+
+ER3(SEC_ERROR_BAD_DER, SEC_ERROR_BASE + 9,
+"security library: improperly formatted DER-encoded message.")
+
+ER3(SEC_ERROR_BAD_SIGNATURE, SEC_ERROR_BASE + 10,
+"Peer's certificate has an invalid signature.")
+
+ER3(SEC_ERROR_EXPIRED_CERTIFICATE, SEC_ERROR_BASE + 11,
+"Peer's Certificate has expired.")
+
+ER3(SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_BASE + 12,
+"Peer's Certificate has been revoked.")
+
+ER3(SEC_ERROR_UNKNOWN_ISSUER, SEC_ERROR_BASE + 13,
+"Peer's Certificate issuer is not recognized.")
+
+ER3(SEC_ERROR_BAD_KEY, SEC_ERROR_BASE + 14,
+"Peer's public key is invalid.")
+
+ER3(SEC_ERROR_BAD_PASSWORD, SEC_ERROR_BASE + 15,
+"The security password entered is incorrect.")
+
+ER3(SEC_ERROR_RETRY_PASSWORD, SEC_ERROR_BASE + 16,
+"New password entered incorrectly. Please try again.")
+
+ER3(SEC_ERROR_NO_NODELOCK, SEC_ERROR_BASE + 17,
+"security library: no nodelock.")
+
+ER3(SEC_ERROR_BAD_DATABASE, SEC_ERROR_BASE + 18,
+"security library: bad database.")
+
+ER3(SEC_ERROR_NO_MEMORY, SEC_ERROR_BASE + 19,
+"security library: memory allocation failure.")
+
+ER3(SEC_ERROR_UNTRUSTED_ISSUER, SEC_ERROR_BASE + 20,
+"Peer's certificate issuer has been marked as not trusted by the user.")
+
+ER3(SEC_ERROR_UNTRUSTED_CERT, SEC_ERROR_BASE + 21,
+"Peer's certificate has been marked as not trusted by the user.")
+
+ER3(SEC_ERROR_DUPLICATE_CERT, (SEC_ERROR_BASE + 22),
+"Certificate already exists in your database.")
+
+ER3(SEC_ERROR_DUPLICATE_CERT_NAME, (SEC_ERROR_BASE + 23),
+"Downloaded certificate's name duplicates one already in your database.")
+
+ER3(SEC_ERROR_ADDING_CERT, (SEC_ERROR_BASE + 24),
+"Error adding certificate to database.")
+
+ER3(SEC_ERROR_FILING_KEY, (SEC_ERROR_BASE + 25),
+"Error refiling the key for this certificate.")
+
+ER3(SEC_ERROR_NO_KEY, (SEC_ERROR_BASE + 26),
+"The private key for this certificate cannot be found in key database")
+
+ER3(SEC_ERROR_CERT_VALID, (SEC_ERROR_BASE + 27),
+"This certificate is valid.")
+
+ER3(SEC_ERROR_CERT_NOT_VALID, (SEC_ERROR_BASE + 28),
+"This certificate is not valid.")
+
+ER3(SEC_ERROR_CERT_NO_RESPONSE, (SEC_ERROR_BASE + 29),
+"Cert Library: No Response")
+
+ER3(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE, (SEC_ERROR_BASE + 30),
+"The certificate issuer's certificate has expired. Check your system date and time.")
+
+ER3(SEC_ERROR_CRL_EXPIRED, (SEC_ERROR_BASE + 31),
+"The CRL for the certificate's issuer has expired. Update it or check your system data and time.")
+
+ER3(SEC_ERROR_CRL_BAD_SIGNATURE, (SEC_ERROR_BASE + 32),
+"The CRL for the certificate's issuer has an invalid signature.")
+
+ER3(SEC_ERROR_CRL_INVALID, (SEC_ERROR_BASE + 33),
+"New CRL has an invalid format.")
+
+ER3(SEC_ERROR_EXTENSION_VALUE_INVALID, (SEC_ERROR_BASE + 34),
+"Certificate extension value is invalid.")
+
+ER3(SEC_ERROR_EXTENSION_NOT_FOUND, (SEC_ERROR_BASE + 35),
+"Certificate extension not found.")
+
+ER3(SEC_ERROR_CA_CERT_INVALID, (SEC_ERROR_BASE + 36),
+"Issuer certificate is invalid.")
+
+ER3(SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID, (SEC_ERROR_BASE + 37),
+"Certificate path length constraint is invalid.")
+
+ER3(SEC_ERROR_CERT_USAGES_INVALID, (SEC_ERROR_BASE + 38),
+"Certificate usages field is invalid.")
+
+ER3(SEC_INTERNAL_ONLY, (SEC_ERROR_BASE + 39),
+"**Internal ONLY module**")
+
+ER3(SEC_ERROR_INVALID_KEY, (SEC_ERROR_BASE + 40),
+"The key does not support the requested operation.")
+
+ER3(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 41),
+"Certificate contains unknown critical extension.")
+
+ER3(SEC_ERROR_OLD_CRL, (SEC_ERROR_BASE + 42),
+"New CRL is not later than the current one.")
+
+ER3(SEC_ERROR_NO_EMAIL_CERT, (SEC_ERROR_BASE + 43),
+"Not encrypted or signed: you do not yet have an email certificate.")
+
+ER3(SEC_ERROR_NO_RECIPIENT_CERTS_QUERY, (SEC_ERROR_BASE + 44),
+"Not encrypted: you do not have certificates for each of the recipients.")
+
+ER3(SEC_ERROR_NOT_A_RECIPIENT, (SEC_ERROR_BASE + 45),
+"Cannot decrypt: you are not a recipient, or matching certificate and \
+private key not found.")
+
+ER3(SEC_ERROR_PKCS7_KEYALG_MISMATCH, (SEC_ERROR_BASE + 46),
+"Cannot decrypt: key encryption algorithm does not match your certificate.")
+
+ER3(SEC_ERROR_PKCS7_BAD_SIGNATURE, (SEC_ERROR_BASE + 47),
+"Signature verification failed: no signer found, too many signers found, \
+or improper or corrupted data.")
+
+ER3(SEC_ERROR_UNSUPPORTED_KEYALG, (SEC_ERROR_BASE + 48),
+"Unsupported or unknown key algorithm.")
+
+ER3(SEC_ERROR_DECRYPTION_DISALLOWED, (SEC_ERROR_BASE + 49),
+"Cannot decrypt: encrypted using a disallowed algorithm or key size.")
+
+
+/* Fortezza Alerts */
+ER3(XP_SEC_FORTEZZA_BAD_CARD, (SEC_ERROR_BASE + 50),
+"Fortezza card has not been properly initialized. \
+Please remove it and return it to your issuer.")
+
+ER3(XP_SEC_FORTEZZA_NO_CARD, (SEC_ERROR_BASE + 51),
+"No Fortezza cards Found")
+
+ER3(XP_SEC_FORTEZZA_NONE_SELECTED, (SEC_ERROR_BASE + 52),
+"No Fortezza card selected")
+
+ER3(XP_SEC_FORTEZZA_MORE_INFO, (SEC_ERROR_BASE + 53),
+"Please select a personality to get more info on")
+
+ER3(XP_SEC_FORTEZZA_PERSON_NOT_FOUND, (SEC_ERROR_BASE + 54),
+"Personality not found")
+
+ER3(XP_SEC_FORTEZZA_NO_MORE_INFO, (SEC_ERROR_BASE + 55),
+"No more information on that Personality")
+
+ER3(XP_SEC_FORTEZZA_BAD_PIN, (SEC_ERROR_BASE + 56),
+"Invalid Pin")
+
+ER3(XP_SEC_FORTEZZA_PERSON_ERROR, (SEC_ERROR_BASE + 57),
+"Couldn't initialize Fortezza personalities.")
+/* end fortezza alerts. */
+
+ER3(SEC_ERROR_NO_KRL, (SEC_ERROR_BASE + 58),
+"No KRL for this site's certificate has been found.")
+
+ER3(SEC_ERROR_KRL_EXPIRED, (SEC_ERROR_BASE + 59),
+"The KRL for this site's certificate has expired.")
+
+ER3(SEC_ERROR_KRL_BAD_SIGNATURE, (SEC_ERROR_BASE + 60),
+"The KRL for this site's certificate has an invalid signature.")
+
+ER3(SEC_ERROR_REVOKED_KEY, (SEC_ERROR_BASE + 61),
+"The key for this site's certificate has been revoked.")
+
+ER3(SEC_ERROR_KRL_INVALID, (SEC_ERROR_BASE + 62),
+"New KRL has an invalid format.")
+
+ER3(SEC_ERROR_NEED_RANDOM, (SEC_ERROR_BASE + 63),
+"security library: need random data.")
+
+ER3(SEC_ERROR_NO_MODULE, (SEC_ERROR_BASE + 64),
+"security library: no security module can perform the requested operation.")
+
+ER3(SEC_ERROR_NO_TOKEN, (SEC_ERROR_BASE + 65),
+"The security card or token does not exist, needs to be initialized, or has been removed.")
+
+ER3(SEC_ERROR_READ_ONLY, (SEC_ERROR_BASE + 66),
+"security library: read-only database.")
+
+ER3(SEC_ERROR_NO_SLOT_SELECTED, (SEC_ERROR_BASE + 67),
+"No slot or token was selected.")
+
+ER3(SEC_ERROR_CERT_NICKNAME_COLLISION, (SEC_ERROR_BASE + 68),
+"A certificate with the same nickname already exists.")
+
+ER3(SEC_ERROR_KEY_NICKNAME_COLLISION, (SEC_ERROR_BASE + 69),
+"A key with the same nickname already exists.")
+
+ER3(SEC_ERROR_SAFE_NOT_CREATED, (SEC_ERROR_BASE + 70),
+"error while creating safe object")
+
+ER3(SEC_ERROR_BAGGAGE_NOT_CREATED, (SEC_ERROR_BASE + 71),
+"error while creating baggage object")
+
+ER3(XP_JAVA_REMOVE_PRINCIPAL_ERROR, (SEC_ERROR_BASE + 72),
+"Couldn't remove the principal")
+
+ER3(XP_JAVA_DELETE_PRIVILEGE_ERROR, (SEC_ERROR_BASE + 73),
+"Couldn't delete the privilege")
+
+ER3(XP_JAVA_CERT_NOT_EXISTS_ERROR, (SEC_ERROR_BASE + 74),
+"This principal doesn't have a certificate")
+
+ER3(SEC_ERROR_BAD_EXPORT_ALGORITHM, (SEC_ERROR_BASE + 75),
+"Required algorithm is not allowed.")
+
+ER3(SEC_ERROR_EXPORTING_CERTIFICATES, (SEC_ERROR_BASE + 76),
+"Error attempting to export certificates.")
+
+ER3(SEC_ERROR_IMPORTING_CERTIFICATES, (SEC_ERROR_BASE + 77),
+"Error attempting to import certificates.")
+
+ER3(SEC_ERROR_PKCS12_DECODING_PFX, (SEC_ERROR_BASE + 78),
+"Unable to import. Decoding error. File not valid.")
+
+ER3(SEC_ERROR_PKCS12_INVALID_MAC, (SEC_ERROR_BASE + 79),
+"Unable to import. Invalid MAC. Incorrect password or corrupt file.")
+
+ER3(SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM, (SEC_ERROR_BASE + 80),
+"Unable to import. MAC algorithm not supported.")
+
+ER3(SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE,(SEC_ERROR_BASE + 81),
+"Unable to import. Only password integrity and privacy modes supported.")
+
+ER3(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE, (SEC_ERROR_BASE + 82),
+"Unable to import. File structure is corrupt.")
+
+ER3(SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM, (SEC_ERROR_BASE + 83),
+"Unable to import. Encryption algorithm not supported.")
+
+ER3(SEC_ERROR_PKCS12_UNSUPPORTED_VERSION, (SEC_ERROR_BASE + 84),
+"Unable to import. File version not supported.")
+
+ER3(SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT,(SEC_ERROR_BASE + 85),
+"Unable to import. Incorrect privacy password.")
+
+ER3(SEC_ERROR_PKCS12_CERT_COLLISION, (SEC_ERROR_BASE + 86),
+"Unable to import. Same nickname already exists in database.")
+
+ER3(SEC_ERROR_USER_CANCELLED, (SEC_ERROR_BASE + 87),
+"The user pressed cancel.")
+
+ER3(SEC_ERROR_PKCS12_DUPLICATE_DATA, (SEC_ERROR_BASE + 88),
+"Not imported, already in database.")
+
+ER3(SEC_ERROR_MESSAGE_SEND_ABORTED, (SEC_ERROR_BASE + 89),
+"Message not sent.")
+
+ER3(SEC_ERROR_INADEQUATE_KEY_USAGE, (SEC_ERROR_BASE + 90),
+"Certificate key usage inadequate for attempted operation.")
+
+ER3(SEC_ERROR_INADEQUATE_CERT_TYPE, (SEC_ERROR_BASE + 91),
+"Certificate type not approved for application.")
+
+ER3(SEC_ERROR_CERT_ADDR_MISMATCH, (SEC_ERROR_BASE + 92),
+"Address in signing certificate does not match address in message headers.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY, (SEC_ERROR_BASE + 93),
+"Unable to import. Error attempting to import private key.")
+
+ER3(SEC_ERROR_PKCS12_IMPORTING_CERT_CHAIN, (SEC_ERROR_BASE + 94),
+"Unable to import. Error attempting to import certificate chain.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME, (SEC_ERROR_BASE + 95),
+"Unable to export. Unable to locate certificate or key by nickname.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY, (SEC_ERROR_BASE + 96),
+"Unable to export. Private Key could not be located and exported.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_WRITE, (SEC_ERROR_BASE + 97),
+"Unable to export. Unable to write the export file.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_READ, (SEC_ERROR_BASE + 98),
+"Unable to import. Unable to read the import file.")
+
+ER3(SEC_ERROR_PKCS12_KEY_DATABASE_NOT_INITIALIZED, (SEC_ERROR_BASE + 99),
+"Unable to export. Key database corrupt or deleted.")
+
+ER3(SEC_ERROR_KEYGEN_FAIL, (SEC_ERROR_BASE + 100),
+"Unable to generate public/private key pair.")
+
+ER3(SEC_ERROR_INVALID_PASSWORD, (SEC_ERROR_BASE + 101),
+"Password entered is invalid. Please pick a different one.")
+
+ER3(SEC_ERROR_RETRY_OLD_PASSWORD, (SEC_ERROR_BASE + 102),
+"Old password entered incorrectly. Please try again.")
+
+ER3(SEC_ERROR_BAD_NICKNAME, (SEC_ERROR_BASE + 103),
+"Certificate nickname already in use.")
+
+ER3(SEC_ERROR_NOT_FORTEZZA_ISSUER, (SEC_ERROR_BASE + 104),
+"Peer FORTEZZA chain has a non-FORTEZZA Certificate.")
+
+ER3(SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY, (SEC_ERROR_BASE + 105),
+"A sensitive key cannot be moved to the slot where it is needed.")
+
+ER3(SEC_ERROR_JS_INVALID_MODULE_NAME, (SEC_ERROR_BASE + 106),
+"Invalid module name.")
+
+ER3(SEC_ERROR_JS_INVALID_DLL, (SEC_ERROR_BASE + 107),
+"Invalid module path/filename")
+
+ER3(SEC_ERROR_JS_ADD_MOD_FAILURE, (SEC_ERROR_BASE + 108),
+"Unable to add module")
+
+ER3(SEC_ERROR_JS_DEL_MOD_FAILURE, (SEC_ERROR_BASE + 109),
+"Unable to delete module")
+
+ER3(SEC_ERROR_OLD_KRL, (SEC_ERROR_BASE + 110),
+"New KRL is not later than the current one.")
+
+ER3(SEC_ERROR_CKL_CONFLICT, (SEC_ERROR_BASE + 111),
+"New CKL has different issuer than current CKL. Delete current CKL.")
+
+ER3(SEC_ERROR_CERT_NOT_IN_NAME_SPACE, (SEC_ERROR_BASE + 112),
+"The Certifying Authority for this certificate is not permitted to issue a \
+certificate with this name.")
+
+ER3(SEC_ERROR_KRL_NOT_YET_VALID, (SEC_ERROR_BASE + 113),
+"The key revocation list for this certificate is not yet valid.")
+
+ER3(SEC_ERROR_CRL_NOT_YET_VALID, (SEC_ERROR_BASE + 114),
+"The certificate revocation list for this certificate is not yet valid.")
+
+ER3(SEC_ERROR_UNKNOWN_CERT, (SEC_ERROR_BASE + 115),
+"The requested certificate could not be found.")
+
+ER3(SEC_ERROR_UNKNOWN_SIGNER, (SEC_ERROR_BASE + 116),
+"The signer's certificate could not be found.")
+
+ER3(SEC_ERROR_CERT_BAD_ACCESS_LOCATION, (SEC_ERROR_BASE + 117),
+"The location for the certificate status server has invalid format.")
+
+ER3(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE, (SEC_ERROR_BASE + 118),
+"The OCSP response cannot be fully decoded; it is of an unknown type.")
+
+ER3(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE, (SEC_ERROR_BASE + 119),
+"The OCSP server returned unexpected/invalid HTTP data.")
+
+ER3(SEC_ERROR_OCSP_MALFORMED_REQUEST, (SEC_ERROR_BASE + 120),
+"The OCSP server found the request to be corrupted or improperly formed.")
+
+ER3(SEC_ERROR_OCSP_SERVER_ERROR, (SEC_ERROR_BASE + 121),
+"The OCSP server experienced an internal error.")
+
+ER3(SEC_ERROR_OCSP_TRY_SERVER_LATER, (SEC_ERROR_BASE + 122),
+"The OCSP server suggests trying again later.")
+
+ER3(SEC_ERROR_OCSP_REQUEST_NEEDS_SIG, (SEC_ERROR_BASE + 123),
+"The OCSP server requires a signature on this request.")
+
+ER3(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST, (SEC_ERROR_BASE + 124),
+"The OCSP server has refused this request as unauthorized.")
+
+ER3(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS, (SEC_ERROR_BASE + 125),
+"The OCSP server returned an unrecognizable status.")
+
+ER3(SEC_ERROR_OCSP_UNKNOWN_CERT, (SEC_ERROR_BASE + 126),
+"The OCSP server has no status for the certificate.")
+
+ER3(SEC_ERROR_OCSP_NOT_ENABLED, (SEC_ERROR_BASE + 127),
+"You must enable OCSP before performing this operation.")
+
+ER3(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER, (SEC_ERROR_BASE + 128),
+"You must set the OCSP default responder before performing this operation.")
+
+ER3(SEC_ERROR_OCSP_MALFORMED_RESPONSE, (SEC_ERROR_BASE + 129),
+"The response from the OCSP server was corrupted or improperly formed.")
+
+ER3(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE, (SEC_ERROR_BASE + 130),
+"The signer of the OCSP response is not authorized to give status for \
+this certificate.")
+
+ER3(SEC_ERROR_OCSP_FUTURE_RESPONSE, (SEC_ERROR_BASE + 131),
+"The OCSP response is not yet valid (contains a date in the future).")
+
+ER3(SEC_ERROR_OCSP_OLD_RESPONSE, (SEC_ERROR_BASE + 132),
+"The OCSP response contains out-of-date information.")
+
+ER3(SEC_ERROR_DIGEST_NOT_FOUND, (SEC_ERROR_BASE + 133),
+"The CMS or PKCS #7 Digest was not found in signed message.")
+
+ER3(SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE, (SEC_ERROR_BASE + 134),
+"The CMS or PKCS #7 Message type is unsupported.")
+
+ER3(SEC_ERROR_MODULE_STUCK, (SEC_ERROR_BASE + 135),
+"PKCS #11 module could not be removed because it is still in use.")
+
+ER3(SEC_ERROR_BAD_TEMPLATE, (SEC_ERROR_BASE + 136),
+"Could not decode ASN.1 data. Specified template was invalid.")
+
+ER3(SEC_ERROR_CRL_NOT_FOUND, (SEC_ERROR_BASE + 137),
+"No matching CRL was found.")
+
+ER3(SEC_ERROR_REUSED_ISSUER_AND_SERIAL, (SEC_ERROR_BASE + 138),
+"You are attempting to import a cert with the same issuer/serial as \
+an existing cert, but that is not the same cert.")
+
+ER3(SEC_ERROR_BUSY, (SEC_ERROR_BASE + 139),
+"NSS could not shutdown. Objects are still in use.")
+
+ER3(SEC_ERROR_EXTRA_INPUT, (SEC_ERROR_BASE + 140),
+"DER-encoded message contained extra unused data.")
+
+ER3(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE, (SEC_ERROR_BASE + 141),
+"Unsupported elliptic curve.")
+
+ER3(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM, (SEC_ERROR_BASE + 142),
+"Unsupported elliptic curve point form.")
+
+ER3(SEC_ERROR_UNRECOGNIZED_OID, (SEC_ERROR_BASE + 143),
+"Unrecognized Object IDentifier.")
+
+ER3(SEC_ERROR_OCSP_INVALID_SIGNING_CERT, (SEC_ERROR_BASE + 144),
+"Invalid OCSP signing certificate in OCSP response.")
+
+ER3(SEC_ERROR_REVOKED_CERTIFICATE_CRL, (SEC_ERROR_BASE + 145),
+"Certificate is revoked in issuer's certificate revocation list.")
+
+ER3(SEC_ERROR_REVOKED_CERTIFICATE_OCSP, (SEC_ERROR_BASE + 146),
+"Issuer's OCSP responder reports certificate is revoked.")
+
+ER3(SEC_ERROR_CRL_INVALID_VERSION, (SEC_ERROR_BASE + 147),
+"Issuer's Certificate Revocation List has an unknown version number.")
+
+ER3(SEC_ERROR_CRL_V1_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 148),
+"Issuer's V1 Certificate Revocation List has a critical extension.")
+
+ER3(SEC_ERROR_CRL_UNKNOWN_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 149),
+"Issuer's V2 Certificate Revocation List has an unknown critical extension.")
+
+ER3(SEC_ERROR_UNKNOWN_OBJECT_TYPE, (SEC_ERROR_BASE + 150),
+"Unknown object type specified.")
+
+ER3(SEC_ERROR_INCOMPATIBLE_PKCS11, (SEC_ERROR_BASE + 151),
+"PKCS #11 driver violates the spec in an incompatible way.")
+
+ER3(SEC_ERROR_NO_EVENT, (SEC_ERROR_BASE + 152),
+"No new slot event is available at this time.")
+
+ER3(SEC_ERROR_CRL_ALREADY_EXISTS, (SEC_ERROR_BASE + 153),
+"CRL already exists.")
+
+ER3(SEC_ERROR_NOT_INITIALIZED, (SEC_ERROR_BASE + 154),
+"NSS is not initialized.")
+
+ER3(SEC_ERROR_TOKEN_NOT_LOGGED_IN, (SEC_ERROR_BASE + 155),
+"The operation failed because the PKCS#11 token is not logged in.")
+
diff --git a/base/tps/src/include/httpClient/httpc/SSLServerSocket.h b/base/tps/src/include/httpClient/httpc/SSLServerSocket.h
new file mode 100644
index 000000000..a059d7279
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/SSLServerSocket.h
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __SSL_SERVER_SOCKET_H
+#define __SSL_SERVER_SOCKET_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * SSLServerSocket.h 1.000 06/12/2002
+ *
+ * A Secure server socket implementation based on NSPR / NSS
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+class EXPORT_DECL SSLServerSocket : public ServerSocket {
+public:
+ /**
+ * Constructor
+ */
+ SSLServerSocket( const char* host,
+ int port,
+ const char* nickname,
+ int requestcert );
+
+ /**
+ * Destructor
+ */
+ virtual ~SSLServerSocket();
+
+public:
+ /**
+ * Initializes cert and private key before calling base class
+ * Accept function.
+ */
+ Socket* Accept();
+
+private:
+ /**
+ * Overrides base class function to create SSL sockets
+ *
+ * @return a newly accepted SSL socket
+ */
+ Socket* InternalAccept(PRFileDesc* fd);
+
+private:
+ char* m_nickName;
+ int m_requestCert;
+ CERTCertificate* m_serverCert;
+ SECKEYPrivateKey* m_serverPrivKey;
+ SSLKEAType m_certKEA;
+};
+
+#endif // __SSL_SERVER_SOCKET_H
+
+
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/SSLSocket.h b/base/tps/src/include/httpClient/httpc/SSLSocket.h
new file mode 100644
index 000000000..14d647c60
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/SSLSocket.h
@@ -0,0 +1,132 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __SSL_SOCKET_H
+#define __SSL_SOCKET_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * SSLSocket.h 1.000 06/12/2002
+ *
+ * A Secure socket implementation based on NSPR / NSS
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+class EXPORT_DECL SSLSocket : public Socket {
+ friend class SSLServerSocket;
+public:
+ /**
+ * Constructor
+ */
+ SSLSocket();
+
+ /**
+ * Destructor
+ */
+ virtual ~SSLSocket();
+
+private:
+ /**
+ * Sets up this socket to behave as a SSL server
+ *
+ * @param cert server certificate object
+ * @param privKey private key structure
+ * @param password password to access DB
+ * @param requestCert whether to request cert from the client
+ * @return 0 on success, negative error code otherwise
+ *
+ */
+ int SetupSSLServer( CERTCertificate* serverCert,
+ SECKEYPrivateKey* privKey,
+ SSLKEAType certKEA,
+ int requestCert );
+private:
+ // server callbacks
+ /**
+ * Specifies a certificate authentication callback function called
+ * to authenticate an incoming certificate
+ *
+ * @param arg pointer supplied by the application
+ * (in the call to SSL_AuthCertificateHook)
+ * that can be used to pass state information
+ * @param socket pointer to the file descriptor for the SSL socket
+ * @param checksig PR_TRUE means signatures are to be checked and
+ * the certificate chain is to be validated
+ * @param isServer PR_TRUE means the callback function should
+ * evaluate the certificate as a server does,
+ * treating the remote end is a client
+ * @return SECSuccess on success, SECFailure otherwise
+ *
+ */
+ static SECStatus AuthCertificate( void* arg,
+ PRFileDesc* socket,
+ PRBool checksig,
+ PRBool isServer );
+
+ /**
+ * Sets up a callback function to deal with a situation where the
+ * SSL_AuthCertificate callback function has failed. This callback
+ * function allows the application to override the decision made by
+ * the certificate authorization callback and authorize the certificate
+ * for use in the SSL connection.
+ *
+ * @param arg The arg parameter passed to SSL_BadCertHook
+ * @param socket pointer to the file descriptor for the SSL socket
+ * @return SECSuccess on success, SECFailure otherwise
+ */
+ static SECStatus BadCertHandler( void* arg,
+ PRFileDesc* socket );
+
+ /**
+ * Sets up a callback function used by SSL to inform either a client
+ * application or a server application when the handshake is completed
+ *
+ * @param arg The arg parameter passed to SSL_HandshakeCallback
+ * @param socket pointer to the file descriptor for the SSL socket
+ * @return SECSuccess on success, SECFailure otherwise
+ */
+ static SECStatus HandshakeCallback( PRFileDesc* socket,
+ void* arg );
+
+private:
+ bool m_initializedAsServer;
+};
+
+#endif // __SSL_SOCKET_H
+
+
diff --git a/base/tps/src/include/httpClient/httpc/SSLerrs.h b/base/tps/src/include/httpClient/httpc/SSLerrs.h
new file mode 100644
index 000000000..818da3e87
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/SSLerrs.h
@@ -0,0 +1,392 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/SSLerrs.h
+ */
+
+/* SSL-specific security error codes */
+/* caller must include "sslerr.h" */
+
+ER3(SSL_ERROR_EXPORT_ONLY_SERVER, SSL_ERROR_BASE + 0,
+"Unable to communicate securely. Peer does not support high-grade encryption.")
+
+ER3(SSL_ERROR_US_ONLY_SERVER, SSL_ERROR_BASE + 1,
+"Unable to communicate securely. Peer requires high-grade encryption which is not supported.")
+
+ER3(SSL_ERROR_NO_CYPHER_OVERLAP, SSL_ERROR_BASE + 2,
+"Cannot communicate securely with peer: no common encryption algorithm(s).")
+
+ER3(SSL_ERROR_NO_CERTIFICATE, SSL_ERROR_BASE + 3,
+"Unable to find the certificate or key necessary for authentication.")
+
+ER3(SSL_ERROR_BAD_CERTIFICATE, SSL_ERROR_BASE + 4,
+"Unable to communicate securely with peer: peers's certificate was rejected.")
+
+/* unused (SSL_ERROR_BASE + 5),*/
+
+ER3(SSL_ERROR_BAD_CLIENT, SSL_ERROR_BASE + 6,
+"The server has encountered bad data from the client.")
+
+ER3(SSL_ERROR_BAD_SERVER, SSL_ERROR_BASE + 7,
+"The client has encountered bad data from the server.")
+
+ER3(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE, SSL_ERROR_BASE + 8,
+"Unsupported certificate type.")
+
+ER3(SSL_ERROR_UNSUPPORTED_VERSION, SSL_ERROR_BASE + 9,
+"Peer using unsupported version of security protocol.")
+
+/* unused (SSL_ERROR_BASE + 10),*/
+
+ER3(SSL_ERROR_WRONG_CERTIFICATE, SSL_ERROR_BASE + 11,
+"Client authentication failed: private key in key database does not match public key in certificate database.")
+
+ER3(SSL_ERROR_BAD_CERT_DOMAIN, SSL_ERROR_BASE + 12,
+"Unable to communicate securely with peer: requested domain name does not match the server's certificate.")
+
+/* SSL_ERROR_POST_WARNING (SSL_ERROR_BASE + 13),
+ defined in sslerr.h
+*/
+
+ER3(SSL_ERROR_SSL2_DISABLED, (SSL_ERROR_BASE + 14),
+"Peer only supports SSL version 2, which is locally disabled.")
+
+
+ER3(SSL_ERROR_BAD_MAC_READ, (SSL_ERROR_BASE + 15),
+"SSL received a record with an incorrect Message Authentication Code.")
+
+ER3(SSL_ERROR_BAD_MAC_ALERT, (SSL_ERROR_BASE + 16),
+"SSL peer reports incorrect Message Authentication Code.")
+
+ER3(SSL_ERROR_BAD_CERT_ALERT, (SSL_ERROR_BASE + 17),
+"SSL peer cannot verify your certificate.")
+
+ER3(SSL_ERROR_REVOKED_CERT_ALERT, (SSL_ERROR_BASE + 18),
+"SSL peer rejected your certificate as revoked.")
+
+ER3(SSL_ERROR_EXPIRED_CERT_ALERT, (SSL_ERROR_BASE + 19),
+"SSL peer rejected your certificate as expired.")
+
+ER3(SSL_ERROR_SSL_DISABLED, (SSL_ERROR_BASE + 20),
+"Cannot connect: SSL is disabled.")
+
+ER3(SSL_ERROR_FORTEZZA_PQG, (SSL_ERROR_BASE + 21),
+"Cannot connect: SSL peer is in another FORTEZZA domain.")
+
+
+ER3(SSL_ERROR_UNKNOWN_CIPHER_SUITE , (SSL_ERROR_BASE + 22),
+"An unknown SSL cipher suite has been requested.")
+
+ER3(SSL_ERROR_NO_CIPHERS_SUPPORTED , (SSL_ERROR_BASE + 23),
+"No cipher suites are present and enabled in this program.")
+
+ER3(SSL_ERROR_BAD_BLOCK_PADDING , (SSL_ERROR_BASE + 24),
+"SSL received a record with bad block padding.")
+
+ER3(SSL_ERROR_RX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 25),
+"SSL received a record that exceeded the maximum permissible length.")
+
+ER3(SSL_ERROR_TX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 26),
+"SSL attempted to send a record that exceeded the maximum permissible length.")
+
+/*
+ * Received a malformed (too long or short or invalid content) SSL handshake.
+ */
+ER3(SSL_ERROR_RX_MALFORMED_HELLO_REQUEST , (SSL_ERROR_BASE + 27),
+"SSL received a malformed Hello Request handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO , (SSL_ERROR_BASE + 28),
+"SSL received a malformed Client Hello handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_SERVER_HELLO , (SSL_ERROR_BASE + 29),
+"SSL received a malformed Server Hello handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CERTIFICATE , (SSL_ERROR_BASE + 30),
+"SSL received a malformed Certificate handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 31),
+"SSL received a malformed Server Key Exchange handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CERT_REQUEST , (SSL_ERROR_BASE + 32),
+"SSL received a malformed Certificate Request handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_HELLO_DONE , (SSL_ERROR_BASE + 33),
+"SSL received a malformed Server Hello Done handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CERT_VERIFY , (SSL_ERROR_BASE + 34),
+"SSL received a malformed Certificate Verify handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 35),
+"SSL received a malformed Client Key Exchange handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_FINISHED , (SSL_ERROR_BASE + 36),
+"SSL received a malformed Finished handshake message.")
+
+/*
+ * Received a malformed (too long or short) SSL record.
+ */
+ER3(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER , (SSL_ERROR_BASE + 37),
+"SSL received a malformed Change Cipher Spec record.")
+
+ER3(SSL_ERROR_RX_MALFORMED_ALERT , (SSL_ERROR_BASE + 38),
+"SSL received a malformed Alert record.")
+
+ER3(SSL_ERROR_RX_MALFORMED_HANDSHAKE , (SSL_ERROR_BASE + 39),
+"SSL received a malformed Handshake record.")
+
+ER3(SSL_ERROR_RX_MALFORMED_APPLICATION_DATA , (SSL_ERROR_BASE + 40),
+"SSL received a malformed Application Data record.")
+
+/*
+ * Received an SSL handshake that was inappropriate for the state we're in.
+ * E.g. Server received message from server, or wrong state in state machine.
+ */
+ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST , (SSL_ERROR_BASE + 41),
+"SSL received an unexpected Hello Request handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO , (SSL_ERROR_BASE + 42),
+"SSL received an unexpected Client Hello handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO , (SSL_ERROR_BASE + 43),
+"SSL received an unexpected Server Hello handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CERTIFICATE , (SSL_ERROR_BASE + 44),
+"SSL received an unexpected Certificate handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 45),
+"SSL received an unexpected Server Key Exchange handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST , (SSL_ERROR_BASE + 46),
+"SSL received an unexpected Certificate Request handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE , (SSL_ERROR_BASE + 47),
+"SSL received an unexpected Server Hello Done handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY , (SSL_ERROR_BASE + 48),
+"SSL received an unexpected Certificate Verify handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 49),
+"SSL received an unexpected Cllient Key Exchange handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_FINISHED , (SSL_ERROR_BASE + 50),
+"SSL received an unexpected Finished handshake message.")
+
+/*
+ * Received an SSL record that was inappropriate for the state we're in.
+ */
+ER3(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER , (SSL_ERROR_BASE + 51),
+"SSL received an unexpected Change Cipher Spec record.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 52),
+"SSL received an unexpected Alert record.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE , (SSL_ERROR_BASE + 53),
+"SSL received an unexpected Handshake record.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA, (SSL_ERROR_BASE + 54),
+"SSL received an unexpected Application Data record.")
+
+/*
+ * Received record/message with unknown discriminant.
+ */
+ER3(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE , (SSL_ERROR_BASE + 55),
+"SSL received a record with an unknown content type.")
+
+ER3(SSL_ERROR_RX_UNKNOWN_HANDSHAKE , (SSL_ERROR_BASE + 56),
+"SSL received a handshake message with an unknown message type.")
+
+ER3(SSL_ERROR_RX_UNKNOWN_ALERT , (SSL_ERROR_BASE + 57),
+"SSL received an alert record with an unknown alert description.")
+
+/*
+ * Received an alert reporting what we did wrong. (more alerts above)
+ */
+ER3(SSL_ERROR_CLOSE_NOTIFY_ALERT , (SSL_ERROR_BASE + 58),
+"SSL peer has closed this connection.")
+
+ER3(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 59),
+"SSL peer was not expecting a handshake message it received.")
+
+ER3(SSL_ERROR_DECOMPRESSION_FAILURE_ALERT , (SSL_ERROR_BASE + 60),
+"SSL peer was unable to succesfully decompress an SSL record it received.")
+
+ER3(SSL_ERROR_HANDSHAKE_FAILURE_ALERT , (SSL_ERROR_BASE + 61),
+"SSL peer was unable to negotiate an acceptable set of security parameters.")
+
+ER3(SSL_ERROR_ILLEGAL_PARAMETER_ALERT , (SSL_ERROR_BASE + 62),
+"SSL peer rejected a handshake message for unacceptable content.")
+
+ER3(SSL_ERROR_UNSUPPORTED_CERT_ALERT , (SSL_ERROR_BASE + 63),
+"SSL peer does not support certificates of the type it received.")
+
+ER3(SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT , (SSL_ERROR_BASE + 64),
+"SSL peer had some unspecified issue with the certificate it received.")
+
+
+ER3(SSL_ERROR_GENERATE_RANDOM_FAILURE , (SSL_ERROR_BASE + 65),
+"SSL experienced a failure of its random number generator.")
+
+ER3(SSL_ERROR_SIGN_HASHES_FAILURE , (SSL_ERROR_BASE + 66),
+"Unable to digitally sign data required to verify your certificate.")
+
+ER3(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE , (SSL_ERROR_BASE + 67),
+"SSL was unable to extract the public key from the peer's certificate.")
+
+ER3(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 68),
+"Unspecified failure while processing SSL Server Key Exchange handshake.")
+
+ER3(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 69),
+"Unspecified failure while processing SSL Client Key Exchange handshake.")
+
+ER3(SSL_ERROR_ENCRYPTION_FAILURE , (SSL_ERROR_BASE + 70),
+"Bulk data encryption algorithm failed in selected cipher suite.")
+
+ER3(SSL_ERROR_DECRYPTION_FAILURE , (SSL_ERROR_BASE + 71),
+"Bulk data decryption algorithm failed in selected cipher suite.")
+
+ER3(SSL_ERROR_SOCKET_WRITE_FAILURE , (SSL_ERROR_BASE + 72),
+"Attempt to write encrypted data to underlying socket failed.")
+
+ER3(SSL_ERROR_MD5_DIGEST_FAILURE , (SSL_ERROR_BASE + 73),
+"MD5 digest function failed.")
+
+ER3(SSL_ERROR_SHA_DIGEST_FAILURE , (SSL_ERROR_BASE + 74),
+"SHA-1 digest function failed.")
+
+ER3(SSL_ERROR_MAC_COMPUTATION_FAILURE , (SSL_ERROR_BASE + 75),
+"MAC computation failed.")
+
+ER3(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE , (SSL_ERROR_BASE + 76),
+"Failure to create Symmetric Key context.")
+
+ER3(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE , (SSL_ERROR_BASE + 77),
+"Failure to unwrap the Symmetric key in Client Key Exchange message.")
+
+ER3(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED , (SSL_ERROR_BASE + 78),
+"SSL Server attempted to use domestic-grade public key with export cipher suite.")
+
+ER3(SSL_ERROR_IV_PARAM_FAILURE , (SSL_ERROR_BASE + 79),
+"PKCS11 code failed to translate an IV into a param.")
+
+ER3(SSL_ERROR_INIT_CIPHER_SUITE_FAILURE , (SSL_ERROR_BASE + 80),
+"Failed to initialize the selected cipher suite.")
+
+ER3(SSL_ERROR_SESSION_KEY_GEN_FAILURE , (SSL_ERROR_BASE + 81),
+"Client failed to generate session keys for SSL session.")
+
+ER3(SSL_ERROR_NO_SERVER_KEY_FOR_ALG , (SSL_ERROR_BASE + 82),
+"Server has no key for the attempted key exchange algorithm.")
+
+ER3(SSL_ERROR_TOKEN_INSERTION_REMOVAL , (SSL_ERROR_BASE + 83),
+"PKCS#11 token was inserted or removed while operation was in progress.")
+
+ER3(SSL_ERROR_TOKEN_SLOT_NOT_FOUND , (SSL_ERROR_BASE + 84),
+"No PKCS#11 token could be found to do a required operation.")
+
+ER3(SSL_ERROR_NO_COMPRESSION_OVERLAP , (SSL_ERROR_BASE + 85),
+"Cannot communicate securely with peer: no common compression algorithm(s).")
+
+ER3(SSL_ERROR_HANDSHAKE_NOT_COMPLETED , (SSL_ERROR_BASE + 86),
+"Cannot initiate another SSL handshake until current handshake is complete.")
+
+ER3(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE , (SSL_ERROR_BASE + 87),
+"Received incorrect handshakes hash values from peer.")
+
+ER3(SSL_ERROR_CERT_KEA_MISMATCH , (SSL_ERROR_BASE + 88),
+"The certificate provided cannot be used with the selected key exchange algorithm.")
+
+ER3(SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA , (SSL_ERROR_BASE + 89),
+"No certificate authority is trusted for SSL client authentication.")
+
+ER3(SSL_ERROR_SESSION_NOT_FOUND , (SSL_ERROR_BASE + 90),
+"Client's SSL session ID not found in server's session cache.")
+
+ER3(SSL_ERROR_DECRYPTION_FAILED_ALERT , (SSL_ERROR_BASE + 91),
+"Peer was unable to decrypt an SSL record it received.")
+
+ER3(SSL_ERROR_RECORD_OVERFLOW_ALERT , (SSL_ERROR_BASE + 92),
+"Peer received an SSL record that was longer than is permitted.")
+
+ER3(SSL_ERROR_UNKNOWN_CA_ALERT , (SSL_ERROR_BASE + 93),
+"Peer does not recognize and trust the CA that issued your certificate.")
+
+ER3(SSL_ERROR_ACCESS_DENIED_ALERT , (SSL_ERROR_BASE + 94),
+"Peer received a valid certificate, but access was denied.")
+
+ER3(SSL_ERROR_DECODE_ERROR_ALERT , (SSL_ERROR_BASE + 95),
+"Peer could not decode an SSL handshake message.")
+
+ER3(SSL_ERROR_DECRYPT_ERROR_ALERT , (SSL_ERROR_BASE + 96),
+"Peer reports failure of signature verification or key exchange.")
+
+ER3(SSL_ERROR_EXPORT_RESTRICTION_ALERT , (SSL_ERROR_BASE + 97),
+"Peer reports negotiation not in compliance with export regulations.")
+
+ER3(SSL_ERROR_PROTOCOL_VERSION_ALERT , (SSL_ERROR_BASE + 98),
+"Peer reports incompatible or unsupported protocol version.")
+
+ER3(SSL_ERROR_INSUFFICIENT_SECURITY_ALERT , (SSL_ERROR_BASE + 99),
+"Server requires ciphers more secure than those supported by client.")
+
+ER3(SSL_ERROR_INTERNAL_ERROR_ALERT , (SSL_ERROR_BASE + 100),
+"Peer reports it experienced an internal error.")
+
+ER3(SSL_ERROR_USER_CANCELED_ALERT , (SSL_ERROR_BASE + 101),
+"Peer user canceled handshake.")
+
+ER3(SSL_ERROR_NO_RENEGOTIATION_ALERT , (SSL_ERROR_BASE + 102),
+"Peer does not permit renegotiation of SSL security parameters.")
+
+ER3(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED , (SSL_ERROR_BASE + 103),
+"SSL server cache not configured and not disabled for this socket.")
+
+ER3(SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT , (SSL_ERROR_BASE + 104),
+"SSL peer does not support requested TLS hello extension.")
+
+ER3(SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT , (SSL_ERROR_BASE + 105),
+"SSL peer could not obtain your certificate from the supplied URL.")
+
+ER3(SSL_ERROR_UNRECOGNIZED_NAME_ALERT , (SSL_ERROR_BASE + 106),
+"SSL peer has no certificate for the requested DNS name.")
+
+ER3(SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT , (SSL_ERROR_BASE + 107),
+"SSL peer was unable to get an OCSP response for its certificate.")
+
+ER3(SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT , (SSL_ERROR_BASE + 108),
+"SSL peer reported bad certificate hash value.")
diff --git a/base/tps/src/include/httpClient/httpc/ScheduledTask.h b/base/tps/src/include/httpClient/httpc/ScheduledTask.h
new file mode 100644
index 000000000..cbb99ab61
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/ScheduledTask.h
@@ -0,0 +1,86 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __SCHEDULED_TASK_H__
+#define __SCHEDULED_TASK_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <time.h>
+
+class TaskList;
+
+/**
+ * Base class for scheduled tasks in Presence Server
+ */
+
+class EXPORT_DECL ScheduledTask {
+ friend class TaskList;
+public:
+ /**
+ * Constructor - creates an empty task
+ */
+ ScheduledTask();
+ /**
+ * Constructor - creates an empty task
+ *
+ * @param name Name of task
+ */
+ ScheduledTask( const char *name );
+ /**
+ * Destructor
+ */
+ virtual ~ScheduledTask();
+ /**
+ * Returns a copy of the task
+ *
+ * @return A copy of the task
+ */
+ virtual ScheduledTask *Clone();
+ /**
+ * Executes the task
+ *
+ * @return 0 on successfully starting the task
+ */
+ virtual int Start();
+protected:
+ char *m_name;
+ ScheduledTask *m_next;
+ ScheduledTask *m_prev;
+ time_t m_time;
+ int m_interval;
+};
+
+#endif // __SCHEDULED_TASK_H__
diff --git a/base/tps/src/include/httpClient/httpc/Scheduler.h b/base/tps/src/include/httpClient/httpc/Scheduler.h
new file mode 100644
index 000000000..a0e77ffb4
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/Scheduler.h
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __SCHEDULER_H__
+#define __SCHEDULER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+class ScheduledTask;
+class TaskList;
+
+/**
+ * Base class for scheduled tasks in Presence Server
+ */
+
+class EXPORT_DECL Scheduler {
+private:
+ /**
+ * Constructor - creates a scheduler object
+ */
+ Scheduler();
+ /**
+ * Destructor
+ */
+ ~Scheduler();
+public:
+ /**
+ * Returns the single scheduler object
+ *
+ * @return The single scheduler object
+ */
+ static Scheduler *GetScheduler();
+ /**
+ * Starts executing a sleep and check task list loop
+ *
+ * @return 0 on success
+ */
+ int Run();
+ /**
+ * Shuts down the scheduler
+ */
+ static void Shutdown();
+ /**
+ * Launches a thread that executes Run()
+ *
+ * @param interval Interval in seconds between checking for task execution
+ * time
+ * @return 0 on success
+ */
+ int Start( int interval );
+ /**
+ * Adds a task to the list
+ *
+ * @param task A task to be executed
+ */
+ void AddTask( ScheduledTask *task );
+ /**
+ * Removes a task from the list
+ *
+ * @param taskName Name of a task to be removed
+ */
+ void RemoveTask( const char *taskName );
+private:
+ TaskList *m_taskList;
+ int m_interval;
+ bool m_done;
+ bool m_running;
+};
+
+#endif /* __SCHEDULER_H__ */
+
diff --git a/base/tps/src/include/httpClient/httpc/SecurityHeaders.h b/base/tps/src/include/httpClient/httpc/SecurityHeaders.h
new file mode 100644
index 000000000..a54ecb1a2
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/SecurityHeaders.h
@@ -0,0 +1,48 @@
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __SECURITY_HEADERS_H__
+#define __SECURITY_HEADERS_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+// SOAP header elements defined by WS-SECURITY and used to transfer
+// username and password
+#define HEADER_FIELD_USERNAME "Username"
+#define HEADER_FIELD_PASSWORD "Password"
+#define HEADER_FIELD_SECURITY "Security"
+#define HEADER_FIELD_NS "http://schemas.xmlsoap.org/ws/2002/04/secext"
+#define HEADER_FIELD_TOKEN "UsernameToken"
+
+#endif /* __SECURITY_HEADERS_H__ */
+
diff --git a/base/tps/src/include/httpClient/httpc/ServerConnection.h b/base/tps/src/include/httpClient/httpc/ServerConnection.h
new file mode 100644
index 000000000..bc33aa216
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/ServerConnection.h
@@ -0,0 +1,179 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __SERVER_CONNECTION_H
+#define __SERVER_CONNECTION_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * ServerConnection.h 1.000 06/12/2002
+ *
+ * This class handles server side connections. The accept happens on
+ * a separate thread and newly accepted connection are polled for
+ * read ready state. Once data is available on one or more connections
+ * the listeners are notified about it.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+class EXPORT_DECL ServerConnection {
+ friend class PollThread;
+ friend class AcceptThread;
+public:
+ /**
+ * Constructor
+ */
+ ServerConnection();
+
+ /**
+ * Destructor
+ */
+ virtual ~ServerConnection();
+
+public:
+ /**
+ * Registers a listener interface to notify on the connections
+ *
+ * @param listener listener object
+ * @return 0 on success, negative error code otherwise
+ */
+ int RegisterListener(ConnectionListener* listener);
+
+ /**
+ * Listens for connections on a specified socket
+ *
+ * @param host host name / ip
+ * @param port listen port
+ * @return 0 on success, negative error code otherwise
+ */
+
+ int Start(char* host, int port);
+
+ /**
+ * Listens for connections on a specified socket for SSL connections
+ *
+ * @param host host name / ip
+ * @param port listen port
+ * @param nickename name of the server cert
+ * @param password password for DB
+ * @param requestCert request client certficate for authentication
+ * @return 0 on success, negative error code otherwise
+ */
+ int Start( char* host,
+ int port,
+ const char* nickname,
+ int requestcert);
+
+ /**
+ * Closes the server connection
+ *
+ * @return 0 on success, negative error code otherwise
+ */
+ int Shutdown();
+
+ /**
+ * Releases the connection to the read pool.
+ *
+ * @param conn a connection object
+ */
+ void PollRead(Connection* conn);
+
+ /**
+ * Releases the connection to the write pool.
+ *
+ * @param conn a connection object
+ */
+ void Release(Connection* conn);
+
+ /**
+ * Gets a connection from the write pool. This connection should be
+ * returned to the pool after writing.
+ *
+ * @return 0 on success, negative error code otherwise
+ */
+ Connection* GetConnection();
+
+ /**
+ * Returns the number of connections
+ *
+ * @return number of connections
+ */
+ int GetCount();
+
+ static void Poll(void* arg);
+ static void Accept(void* arg);
+
+protected:
+ /**
+ * Protocol specific implementations should implement this
+ * function and return their own connection object
+ *
+ * @return a newly created connection
+ */
+ virtual Connection* AcceptedConnection();
+
+ const char* GetPeerHost(Connection* conn);
+ int GetPeerPort(Connection* conn);
+
+private:
+ int InternalStart();
+ void SetServerFlag(Connection* conn);
+ PRFileDesc* GetFD( Connection* conn );
+ void SetSocket(Connection* conn, Socket* socket);
+ int UpdateWritePool(Connection* conn);
+
+private:
+ ServerSocket* m_server;
+ ConnectionListener* m_connectionListener;
+
+ Pool* m_readPool;
+ Pool* m_writePool;
+
+ PRLock* m_readLock;
+ PRLock* m_writeLock;
+
+ PRBool m_threadInitialized;
+ PRLock* m_threadLock;
+ PRCondVar* m_threadCondv;
+
+ int m_totalConnections;
+ bool m_serverRunning;
+};
+
+#endif // __SERVER_CONNECTION_H
+
+
diff --git a/base/tps/src/include/httpClient/httpc/ServerHeaderProcessor.h b/base/tps/src/include/httpClient/httpc/ServerHeaderProcessor.h
new file mode 100644
index 000000000..213d3b13b
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/ServerHeaderProcessor.h
@@ -0,0 +1,72 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef __WASP_SERVER_HEADER_PROCESSOR_H
+#define __WASP_SERVER_HEADER_PROCESSOR_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <waspc/config/config.h>
+#include <waspc/util/exceptions.h>
+#include <waspc/xmlprotocol/header/HeaderProcessor.h>
+
+class ServerHeaderProcessorItemConfiguration;
+
+/**
+ * Creates WS-Security header with a session token
+ */
+class EXPORT_DECL ServerHeaderProcessor : public WASP_HeaderProcessor {
+protected:
+ virtual ~ServerHeaderProcessor();
+public:
+ ServerHeaderProcessor();
+
+ //inherited methods from WASP_Configurable
+ virtual void load (WASP_Configuration *, EXCENV_DECL);
+ virtual void init (EXCENV_DECL);
+ virtual void destroy ();
+
+ //inherited from WASP_HeaderProcessor
+ virtual void processInput(WASP_XMLProtocolMessage *message, EXCENV_DECL);
+ virtual void processOutput(WASP_XMLProtocolMessage *message, EXCENV_DECL);
+ virtual void processInputFault(WASP_XMLProtocolMessage *message, EXCENV_DECL);
+ virtual void processOutputFault(WASP_XMLProtocolMessage *message, EXCENV_DECL);
+ virtual WASP_String **getUnderstandHeaders(int &count, EXCENV_DECL);
+
+protected:
+ WASP_String **mppsUnderstandHeaderNamesAndNs;
+ int miUnderstandHeaderCount;
+};
+
+#endif //__WASP_SERVER_HEADER_PROCESSOR_H
diff --git a/base/tps/src/include/httpClient/httpc/ServerSocket.h b/base/tps/src/include/httpClient/httpc/ServerSocket.h
new file mode 100644
index 000000000..3cec2444a
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/ServerSocket.h
@@ -0,0 +1,113 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __SERVER_SOCKET_H
+#define __SERVER_SOCKET_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * ServerSocket.h 1.000 06/12/2002
+ *
+ * A NSPR implementation of ServerSocket
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+class EXPORT_DECL ServerSocket {
+public:
+
+ /**
+ * Constructor - Creates a new TCP socket
+ *
+ * @param host host name / ip
+ * @param port a listen port
+ */
+ ServerSocket(const char* host, int port);
+
+ /**
+ * Constructor - Creates a new TCP socket
+ *
+ * @param port a listen port
+ */
+ ServerSocket(int port);
+
+ /**
+ * Desstructor
+ */
+ virtual ~ServerSocket();
+
+public:
+
+ /**
+ * Binds the socket to the specified port and starts listening for
+ * connections. The first connection is accepted from the queue of
+ * pending connections and creates a new socket for the newly accepted
+ * connection. The accept is blocked with no time out in its own thread.
+ *
+ * @return a new socket for the newly accepted connection
+ */
+ virtual Socket* Accept();
+
+ /**
+ * Closes the server socket
+ */
+ virtual void Shutdown();
+
+protected:
+ /**
+ * Internal method to call accept. Sub classes should override this
+ * to provide their own implementation for returned sockets.
+ *
+ * @return a newly accepted socket
+ */
+ virtual Socket* InternalAccept(PRFileDesc* fd);
+
+protected:
+ bool m_initialized;
+
+private:
+ PRFileDesc* m_fd;
+ PRNetAddr m_addr;
+ char* m_host;
+ int m_port;
+ int m_backlog;
+};
+
+#endif // __SERVER_SOCKET_H
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/Socket.h b/base/tps/src/include/httpClient/httpc/Socket.h
new file mode 100644
index 000000000..c2ef4afd4
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/Socket.h
@@ -0,0 +1,157 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __SOCKET_H
+#define __SOCKET_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * Socket.h 1.000 06/12/2002
+ *
+ * A NSPR implementation of socket
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+class EXPORT_DECL Socket {
+ friend class ServerSocket;
+ friend class ServerConnection;
+public:
+
+ /**
+ * Constructor
+ */
+ Socket();
+
+ /**
+ * Constructor - creates a socket connecting to the host and port
+ *
+ * @param host hostname to connect to
+ * @param port port of the machine
+ */
+ Socket(const char* host, int port);
+
+ /**
+ * Destructor
+ */
+ virtual ~Socket();
+
+public:
+
+ /**
+ * Reads specified number of bytes from the socket. This is a blocking
+ * socket read with timeout.
+ *
+ * @param buf buffer to read into
+ * @param size number of bytes to read
+ * @param timeout timeout before the read terminates
+ * @return number of bytes actually read
+ */
+ int Read(void* buf, int size, long timeout);
+
+ /**
+ * Writes specified number of bytes to the socket. This is a blocking
+ * socket write with timeout.
+ *
+ * @param buf buffer to write from
+ * @param size number of bytes to write
+ * @param timeout timeout before the write terminates
+ * @return number of bytes actually written
+ */
+ int Write(void* buf, int size, long timeout);
+
+ /**
+ * Gets ip address for a specified socket
+ *
+ * @return ip address
+ */
+ const char* GetLocalIp();
+
+ /**
+ * Gets port for a specified socket
+ *
+ * @return port
+ */
+ int GetLocalPort();
+
+ /**
+ * Gets ip address of a connected peer
+ *
+ * @return ip address
+ */
+ const char* GetPeerIp();
+
+ /**
+ * Gets port of a connected peer
+ *
+ * @return ip address
+ */
+ int GetPeerPort();
+
+ /**
+ * Shuts down part of a full-duplex connection on a specified socket
+ *
+ * @param how the kind of disallowed operations on the socket
+ * the possible values are :
+ * PR_SHUTDOWN_RCV
+ * PR_SHUTDOWN_SEND
+ * PR_SHUTDOWN_BOTH
+ */
+ void Shutdown(PRShutdownHow how);
+
+protected:
+ int Init(PRFileDesc* fd);
+
+private:
+ void CancelIO(PRInt32 err);
+
+protected:
+ PRFileDesc* m_fd;
+
+private:
+ char* m_localIp;
+ char* m_peerIp;
+ int m_localPort;
+ int m_peerPort;
+ bool m_initialized;
+ PRLock* m_readLock;
+ PRLock* m_writeLock;
+};
+
+#endif // __SOCKET_H
+
+
diff --git a/base/tps/src/include/httpClient/httpc/SocketINC.h b/base/tps/src/include/httpClient/httpc/SocketINC.h
new file mode 100644
index 000000000..43b36c9a0
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/SocketINC.h
@@ -0,0 +1,163 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef _SOCKET_INC_H_
+#define _SOCKET_INC_H_
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * SocketINC.h 1.000 06/12/2002
+ *
+ * Public header file for Socket / Connection module
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+/**************************************************
+ * Imported header files
+ **************************************************/
+#include <time.h>
+#include <string.h>
+
+#include "nspr.h"
+#include "plhash.h"
+#include "plstr.h"
+#include "private/pprio.h"
+
+#include "pk11func.h"
+#include "secitem.h"
+#include "ssl.h"
+#include "certt.h"
+#include "nss.h"
+#include "secrng.h"
+#include "secder.h"
+#include "key.h"
+#include "sslproto.h"
+
+#include "httpClient/httpc/Defines.h" // ??? SSR should be spilt into respective modules
+#include "httpClient/httpc/Pool.h"
+#include "httpClient/httpc/DebugLogger.h"
+#include "httpClient/httpc/ErrorLogger.h"
+#include "httpClient/httpc/CERTUtil.h"
+#include "httpClient/httpc/PSPRUtil.h"
+
+/**************************************************
+ * Socket / Connection module header files
+ **************************************************/
+#include "httpClient/httpc/Socket.h"
+#include "httpClient/httpc/ServerSocket.h"
+#include "httpClient/httpc/SSLSocket.h"
+#include "httpClient/httpc/SSLServerSocket.h"
+#include "httpClient/httpc/Connection.h"
+#include "httpClient/httpc/ConnectionListener.h"
+#include "httpClient/httpc/ServerConnection.h"
+
+
+/*************************************************
+ * Error codes used by this module
+ *************************************************/
+// Socket errors
+typedef enum {
+ SOCKET_ERROR_CREATE_SOCKET = -2001,
+ SOCKET_ERROR_SET_OPTION = -2002,
+ SOCKET_ERROR_BIND = -2003,
+ SOCKET_ERROR_LISTEN = -2004,
+ SOCKET_ERROR_CONNECTION_CLOSED = -2005,
+ SOCKET_ERROR_READ = -2006,
+ SOCKET_ERROR_WRITE = -2007,
+ SOCKET_ERROR_ACCEPT_THREAD = -2008,
+ SOCKET_ERROR_ALREADY_REGISTERED = -2009,
+ SOCKET_ERROR_ALREADY_LISTENING = -2010,
+ SOCKET_ERROR_POLL_THREAD = -2011,
+ SOCKET_ERROR_NO_LISTENER = -2012,
+ SOCKET_ERROR_POLL = -2013,
+ SOCKET_ERROR_POLL_TIMED_OUT = -2014,
+ SOCKET_ERROR_ALREADY_CONNECTED = -2015,
+ SOCKET_ERROR_INITIALIZATION_FAILED = -2016
+} SocketError;
+
+typedef enum {
+ SSL_ERROR_SERVER_CERT = -2016,
+ SSL_ERROR_SERVER_PRIVATE_KEY = -2017,
+ SSL_ERROR_IMPORT_FD = -2018,
+ SSL_ERROR_OPTION_SECURITY = -2019,
+ SSL_ERROR_OPTION_SERVER_HANDSHAKE = -2020,
+ SSL_ERROR_OPTION_REQUEST_CERTIFCATE = -2021,
+ SSL_ERROR_OPTION_REQUIRE_CERTIFCATE = -2022,
+ SSL_ERROR_CALLBACK_AUTH_CERTIFICATE = -2023,
+ SSL_ERROR_CALLBACK_BAD_CERT_HANDLER = -2024,
+ SSL_ERROR_CALLBACK_HAND_SHAKE = -2025,
+ SSL_ERROR_CALLBACK_PASSWORD_ARG = -2026,
+ SSL_ERROR_CONFIG_SECURE_SERVER = -2027,
+ SSL_ERROR_RESET_HAND_SHAKE = -2028,
+ SSL_ERROR_OPTION_ENABLE_FDX = -2029
+} SslError;
+
+/**************************************************
+ * Defines used by this module
+ **************************************************/
+#define SOCKET_DEFAULT_HOST_NAME "localhost"
+#define SOCKET_DEFAULT_READ_TIME_OUT 1000UL // 1 sec
+#define SOCKET_DEFAULT_WRITE_TIME_OUT 0xffffffffUL // infinte
+#define SOCKET_DEFAULT_READ_BUFFER_SIZE 4096 // 4k
+#define SOCKET_DEFAULT_WRITE_BUFFER_SIZE 4096 // 4k
+#define SOCKET_DEFAULT_POLL_TIMEOUT 1000UL // 1 sec
+#define SOCKET_DEFAULT_BACKLOG 50 // pending conns
+#define SOCKET_DEFAULT_POOL_SIZE 100 // conn pool size
+
+typedef enum {
+ SOCKET_ERROR_SEVERE = 1,
+ SOCKET_ERROR_WARNING = 2,
+ SOCKET_ERROR_INFO = 3
+} SocketErrorLevel;
+
+
+typedef enum {
+ REQUEST_CERT_NONE = 0,
+ REQUIRE_CERT_NONE = 1,
+ REQUEST_CERT_ONCE = 2,
+ REQUIRE_CERT_ONCE = 3,
+ REQUEST_CERT_ALL = 4,
+ REQUIRE_CERT_ALL = 5
+} RequireCert;
+
+#endif // _SOCKET_INC_H_
+
+
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/SocketLib.h b/base/tps/src/include/httpClient/httpc/SocketLib.h
new file mode 100644
index 000000000..5a00b2ecb
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/SocketLib.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef _SOCKET_LIB_H_
+#define _SOCKET_LIB_H_
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * SocketLib.h 1.000 06/12/2002
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+#undef EXPORT_DECL
+#ifdef _MSC_VER
+#ifdef PS_SOCKET_LIB_INTERNAL
+ #define EXPORT_DECL __declspec( dllexport )
+#else
+ #define EXPORT_DECL __declspec (dllimport )
+#endif // PS_SOCKET_LIB_INTERNAL
+#else
+ #define EXPORT_DECL
+#endif // _MSC_VER
+
+#endif // _CONNECTION_LIB_H_
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/StringList.h b/base/tps/src/include/httpClient/httpc/StringList.h
new file mode 100644
index 000000000..80cd61dd6
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/StringList.h
@@ -0,0 +1,151 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef _STRING_LIST_H
+#define _STRING_LIST_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * Simple String list class using the STL List template
+ */
+
+#include <list>
+#ifdef HPUX
+#include <iostream.h>
+#else
+#include <iostream>
+#endif
+
+#include "httpClient/httpc/Iterator.h"
+
+#ifndef HPUX
+using namespace std;
+#endif
+
+typedef EXPORT_DECL list<const char *> LISTSTR;
+
+class EXPORT_DECL StringList {
+public:
+ /**
+ * Constructor
+ */
+ StringList();
+
+ /**
+ * Destructor
+ */
+ ~StringList();
+
+ /**
+ * Appends a string to the end of the list
+ *
+ * @param value The string value to append
+ */
+ void Add( const char *value );
+
+ /**
+ * Gets the string at a particular index in the list
+ *
+ * @param index Index of the string to retrieve
+ * @return The string at the specified index, or NULL if outside
+ * the range of the list
+ */
+ const char *GetAt( int index );
+
+ /**
+ * Returns the index of a string in the list
+ *
+ * @param matchString The string to match
+ * @param startIndex The index to start searching from
+ * @return The index of the string, or -1 if not found
+ */
+ int Find( const char *matchString,
+ int startIndex );
+
+ /**
+ * Returns the number of strings in the list
+ *
+ * @return The number of strings in the list
+ */
+ int GetCount();
+
+ /**
+ * Inserts a string before the specified position
+ *
+ * @param index Position to insert the string
+ * @param value The string to insert
+ * @return The index of the string, or -1 if the requested index
+ * is beyond the end of the list
+ */
+ int Insert( int index, const char *value );
+
+ /**
+ * Removes a string at the specified position
+ *
+ * @param index Position to remove the string
+ * @return 0 on sucess, or -1 if the requested index
+ * is beyond the end of the list
+ */
+ int Remove( int index );
+
+ /**
+ * Removes all strings
+ */
+ void RemoveAll();
+
+ /**
+ * Returns an iterator over strings in the list
+ *
+ * @return An iterator over strings in the list
+ */
+ Iterator *GetIterator();
+
+ EXPORT_DECL friend ostream& operator<< ( ostream& os, StringList& list );
+
+protected:
+ /**
+ * Gets the iterator for an indexed element
+ *
+ * @param index Position to get
+ * @return Iterator for the position (could be end())
+ */
+ LISTSTR::iterator GetIteratorAt( int index );
+
+private:
+ LISTSTR m_list;
+};
+
+#endif // _STRING_LIST_H
diff --git a/base/tps/src/include/httpClient/httpc/StringUtil.h b/base/tps/src/include/httpClient/httpc/StringUtil.h
new file mode 100644
index 000000000..5c8955d37
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/StringUtil.h
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef _STRING_UTIL_H
+#define _STRING_UTIL_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * String utility functions
+ */
+
+class EXPORT_DECL StringUtil {
+private:
+ /**
+ * Constructor - can't be instantiated
+ */
+ StringUtil() {}
+
+ /**
+ * Destructor
+ */
+ ~StringUtil() {}
+
+public:
+ /**
+ * Normalizes a screen name
+ *
+ * @param raw The raw screen name
+ * @param normalized The normalized screen name (lower case, no spaces)
+ */
+ static void NormalizeScreenName( const char *raw, char *normalized );
+
+ /**
+ * Converts the string to lower case
+ *
+ * @param raw string to be converted
+ */
+ static void ToLower(char* raw);
+};
+
+#endif // _STRING_UTIL_H
diff --git a/base/tps/src/include/httpClient/httpc/TaskList.h b/base/tps/src/include/httpClient/httpc/TaskList.h
new file mode 100644
index 000000000..779d27ead
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/TaskList.h
@@ -0,0 +1,114 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __TASK_LIST_H__
+#define __TASK_LIST_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * Base class for scheduled tasks in Presence Server
+ */
+
+class EXPORT_DECL TaskList {
+public:
+ /**
+ * Constructor - creates an empty task list
+ *
+ * @param name Name of task list
+ */
+ TaskList( const char *name );
+ /**
+ * Destructor - Empties the task list, deleting each entry
+ */
+ virtual ~TaskList();
+ /**
+ * Returns true if the task list is empty
+ *
+ * @return true if the task list is empty
+ */
+ bool IsEmpty();
+ /**
+ * Adds a task to the list; the list is sorted by execution time
+ *
+ * @param node An entry to add
+ * @return The added entry
+ */
+ ScheduledTask *Add( ScheduledTask *node );
+ /**
+ * Removes a node from the list but does not delete it
+ *
+ * @param taskName The name of the node to remove
+ * @return The node with the name taskName, or NULL if not found
+ */
+ ScheduledTask *Remove( const char *taskName );
+ /**
+ * Executes each task for which the time is right in a separate thread;
+ * if the task is repeating, a new entry is created for it, otherwise
+ * it is removed from the list
+ *
+ * @return The number of tasks executed
+ */
+ int ExecuteCurrent();
+ /**
+ * Dumps the task list to the debug log
+ *
+ * @param logLevel Lowest debug level for which the log should be dumped
+ */
+ void Dump( int logLevel );
+private:
+ /**
+ * Removes a node from the list but does not delete it; does not lock
+ *
+ * @param node The node to remove
+ * @return The node
+ */
+ ScheduledTask *InternalRemove( ScheduledTask *node );
+ /**
+ * Adds a task to the list; the list is sorted by execution time
+ *
+ * @param node An entry to add
+ * @return The added entry
+ */
+ ScheduledTask *InternalAdd( ScheduledTask *node );
+
+ char *m_name;
+ ScheduledTask *m_next;
+ int m_interval;
+ PRLock *m_lock;
+};
+
+#endif /* __TASK_LIST_H__ */
+
diff --git a/base/tps/src/include/httpClient/httpc/ThreadPool.h b/base/tps/src/include/httpClient/httpc/ThreadPool.h
new file mode 100644
index 000000000..389d42606
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/ThreadPool.h
@@ -0,0 +1,159 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef __THREAD_POOL_H
+#define __THREAD_POOL_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * ThreadPool.h 1.000 06/12/2002
+ *
+ * A worker thread pool.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+class EXPORT_DECL ThreadPool {
+ friend class WorkerThread;
+public:
+ /**
+ * Constructor - creates the pool with default values
+ *
+ * @param name name of the threadpool
+ */
+ ThreadPool(const char* name);
+
+ /**
+ * Constructor
+ *
+ * @param name name of the threadpool
+ * @param min minimum threads in the pool
+ * @param max maximum threads that can be created
+ * @param timeout timeout for each thread
+ */
+ ThreadPool(const char* name, int min, int max, int timeout);
+
+ /**
+ * Destructor
+ */
+ virtual ~ThreadPool();
+
+public:
+
+ /**
+ * Initializes the thread pool with minimum threads
+ */
+ void Init();
+
+ /**
+ * Shutdown the thread pool
+ */
+ void Shutdown();
+
+ /**
+ * Adds a task for future execution
+ *
+ * @param task a task to execute
+ */
+ void AddTask(ScheduledTask* task);
+
+ /**
+ * Executes the task immediately
+ *
+ * @param task a task to execute
+ */
+ void ExecuteTask(ScheduledTask* task);
+
+ /**
+ * Gets the number of active threads in the pool
+ *
+ * @return number of active threads
+ */
+ int GetThreads();
+
+ /**
+ * Gets the number of pending tasks in the list
+ *
+ * @return number of pending tasks
+ */
+ int GetPendingTasks();
+
+ /**
+ * Function to start a NSPR thread
+ */
+ static void StartWorkerThread(void* arg);
+
+private:
+ /**
+ * Initializes constructor params
+ */
+ void ConstructorInit(const char* name, int min, int max, int timeout);
+
+ /**
+ * Creates a new thread
+ */
+ void CreateNewThread();
+
+ /**
+ * Notify one of the threads waiting on a condition
+ */
+ void Notify();
+
+private:
+ char* m_name;
+ TaskList* m_taskList;
+
+ int m_minThreads;
+ int m_maxThreads;
+ int m_timeout;
+
+ int m_threads;
+ int m_activeThreads;
+
+ PRBool m_threadWait;
+ PRLock* m_threadLock;
+ PRCondVar* m_threadCondVar;
+
+ PRBool m_newThreadInitialized;
+ PRLock* m_newThreadLock;
+ PRCondVar* m_newThreadCondVar;
+
+ bool m_keepRunning;
+};
+
+#endif // __THREAD_POOL_H
+
diff --git a/base/tps/src/include/httpClient/httpc/URLUtil.h b/base/tps/src/include/httpClient/httpc/URLUtil.h
new file mode 100644
index 000000000..379986999
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/URLUtil.h
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef _URL_UTIL_H
+#define _URL_UTIL_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * URL utility functions
+ */
+
+typedef enum {
+ URL_TYPE_HTTP = 1,
+ URL_TYPE_HTTPS = 2,
+ URL_TYPE_LDAP = 3,
+ URL_TYPE_LDAPS = 4,
+ URL_TYPE_UNKNOWN = 5
+} UrlType;
+
+class EXPORT_DECL URLUtil {
+private:
+ /**
+ * Constructor - can't be instantiated
+ */
+ URLUtil() {}
+
+ /**
+ * Destructor
+ */
+ ~URLUtil() {}
+
+public:
+ /**
+ * Parses the URL
+ *
+ * @param url url to parse
+ * @param type protocol header type
+ * @param host hostname from the url
+ * @param port port number from the url
+ * @param path uri from the url
+ * @return 0 on success, negative error code otherwise
+ */
+ static int ParseURL( const char* url,
+ int* type,
+ char** host,
+ int* port,
+ char** path );
+
+private:
+ static int ParseURLType(const char* url, int* type, int* hlen);
+ static int ParseAtPort(const char* url, int* port, char** path);
+ static int ParseAtPath(const char* url, char** path);
+ static int GetPort(const char* url, int* port);
+ static bool IsAsciiSpace(char c);
+ static bool IsAsciiDigit(char c);
+};
+
+#endif // _URL_UTIL_H
+
diff --git a/base/tps/src/include/httpClient/httpc/engine.h b/base/tps/src/include/httpClient/httpc/engine.h
new file mode 100644
index 000000000..9a57b024e
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/engine.h
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef _HTTP_ENGINE_
+#define _HTTP_ENGINE_
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/http.h"
+#include "httpClient/httpc/response.h"
+#include "httpClient/httpc/request.h"
+
+class __EXPORT Engine {
+ public:
+ Engine() {};
+ ~Engine() {};
+
+ PRFileDesc *_doConnect(PRNetAddr *addr, PRBool SSLOn = PR_FALSE,
+ const PRInt32* cipherSuite = NULL,
+ PRInt32 count = 0, const char* nickname = NULL,
+ PRBool handshake = PR_FALSE,
+ /*const SecurityProtocols& secprots = SecurityProtocols() ,*/
+ const char *serverName ="localhost",
+ PRIntervalTime iv = PR_SecondsToInterval(30));
+ static PRIntervalTime globaltimeout;
+};
+
+
+class __EXPORT HttpEngine: public Engine {
+ public:
+ HttpEngine() {};
+ ~HttpEngine() {};
+
+ PSHttpResponse *makeRequest( PSHttpRequest &request,
+ const PSHttpServer& server,
+ int timeout = 30, PRBool expectChunked = PR_FALSE);
+};
+
+PRBool __EXPORT InitSecurity(char* dbpath, char* certname, char* certpassword,
+ char * prefix ,int verify=1);
+PRBool __EXPORT EnableCipher(const char* ciphername);
+void __EXPORT EnableAllSSL3Ciphers();
+void __EXPORT EnableAllTLSCiphers();
+__EXPORT const char * nscperror_lookup(int error);
+
+#endif
diff --git a/base/tps/src/include/httpClient/httpc/http.h b/base/tps/src/include/httpClient/httpc/http.h
new file mode 100644
index 000000000..0dccfddbd
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/http.h
@@ -0,0 +1,120 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef _HTTP_SERVER_
+#define _HTTP_SERVER_
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdlib.h>
+#include <prnetdb.h>
+#include <prio.h>
+#include <time.h>
+#include <plhash.h>
+#include <nspr.h>
+#include <plstr.h>
+
+#include "httpClient/httpc/PSCommonLib.h"
+#include "httpClient/httpc/Cache.h"
+#include "httpClient/httpc/Defines.h"
+//#include "httpClient/httpc/DebugLogger.h"
+//#include "httpClient/httpc/ErrorLogger.h"
+
+#ifdef WIN32
+#define __EXPORT __declspec(dllexport)
+#else
+#define __EXPORT
+#endif
+
+class PSHttpRequest;
+
+class __EXPORT PSHttpServer
+{
+public:
+ PSHttpServer(const char *addr, PRUint16 af);
+ ~PSHttpServer();
+
+ long getIp() const;
+ long getPort() const;
+ const char *getAddr() const;
+ void getAddr(PRNetAddr *addr) const;
+ void setSSL(PRBool SSLstate);
+ PRBool isSSL() const;
+
+ // put a file on the server of size bytes
+ PRBool putFile(const char *uri, int size) const;
+ PRBool putFile(const char* uri, const char* localFile) const;
+
+private:
+ char *_addr;
+ PRNetAddr _netAddr;
+ PRBool SSLOn;
+ PRBool _putFile(PSHttpRequest& rq) const;
+};
+
+typedef __EXPORT enum HttpProtocol_e { HTTPNA = 0x0,
+ HTTP09 = 0x1,
+ HTTP10 = 0x2,
+ HTTP11 = 0x4,
+ HTTPBOGUS = 0x8 } HttpProtocol;
+
+#define NUM_PROTOS 5 // needed for arrays of tests
+
+__EXPORT const char *HttpProtocolToString(HttpProtocol);
+
+class __EXPORT HttpMessage
+{
+ public:
+ HttpMessage(long len = 0, const char* buf = NULL);
+ ~HttpMessage();
+
+ PRBool operator == (const HttpMessage& rhs);
+
+ void addData(long len, const void* buf);
+
+ // set data on the message
+ void setProtocol(HttpProtocol prot);
+
+ // get data about the message
+ HttpProtocol getProtocol() const;
+
+
+ protected:
+ char* firstline; // first line - may be the request-line or server status
+ HttpProtocol proto;
+ long cl;
+};
+
+
+#endif
diff --git a/base/tps/src/include/httpClient/httpc/request.h b/base/tps/src/include/httpClient/httpc/request.h
new file mode 100644
index 000000000..0399732ef
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/request.h
@@ -0,0 +1,115 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef _REQUEST_H_
+#define _REQUEST_H_
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/http.h"
+
+// abstract request class
+class __EXPORT NetRequest
+{
+ public:
+ NetRequest(const PSHttpServer* server);
+ PRBool isSSL() const;
+ void setSSL(PRBool SSLstate);
+ void getAddr(PRNetAddr *addr);
+ const char* getAddr();
+ const char* getHost();
+ const PSHttpServer * getServer();
+ void setServer(PSHttpServer* _server);
+ PRIntervalTime getTimeout() const;
+ const PRInt32* cipherSet;
+ PRInt32 cipherCount;
+ PRBool handshake;
+// SecurityProtocols secprots;
+
+ protected:
+ PRBool SSLOn;
+ const PSHttpServer * _server;
+ PRIntervalTime timeout;
+
+};
+
+// Netscape-style request
+class __EXPORT PSHttpRequest: public HttpMessage, public NetRequest
+{
+public:
+ PSHttpRequest(const PSHttpServer* server, const char *uri, HttpProtocol proto, PRIntervalTime to);
+ virtual ~PSHttpRequest();
+
+ // connection related stuff
+
+ // set data on the request
+ PRBool setMethod(const char *method);
+ PRBool addHeader(const char *name, const char *value);
+ PRBool addRandomBody(int size);
+ PRBool useLocalFileAsBody(const char* fileName);
+ PRBool setBody(int size, const char* body);
+ void setExpectedResponseLength(int size);
+ void setExpectStandardBody();
+ void setExpectDynamicBody();
+ void setHangupOk();
+ PRBool isHangupOk();
+
+ // get data about the request
+ char *getMethod();
+ //HttpProtocol getProtocol();
+ const char *getHeader(const char *name);
+ int getExpectedResponseLength();
+ PRBool getExpectStandardBody();
+ PRBool getExpectDynamicBody();
+
+ PRBool send(PRFileDesc *sock);
+ void setCertNickName(const char *);
+ char *getCertNickName();
+
+private:
+ char *_method;
+ char *_uri;
+ HttpProtocol _proto;
+ int _bodyLength;
+ char *_body;
+ char *nickName;
+ StringKeyCache *_headers;
+ int _expectedResponseLength;
+ PRBool _expectStandardBody;
+ PRBool _expectDynamicBody;
+ PRBool _hangupOk;
+ PRFileDesc* _fileFd;
+};
+
+#endif
diff --git a/base/tps/src/include/httpClient/httpc/response.h b/base/tps/src/include/httpClient/httpc/response.h
new file mode 100644
index 000000000..5c45d574c
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/response.h
@@ -0,0 +1,148 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 **/
+
+#ifndef _RESPONSE_H_
+#define _RESPONSE_H_
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/http.h"
+#include "httpClient/httpc/request.h"
+
+class __EXPORT RecvBuf
+{
+public:
+ RecvBuf(const PRFileDesc *socket, int size, int timeout = 30);
+ virtual ~RecvBuf();
+
+ char getChar();
+ void putBack();
+
+ void setChunkedMode();
+ int getAllContent();
+ int getTimeout();
+
+ char *get_content();
+ int get_contentSize();
+
+ class EndOfFile {};
+ class EndOfChunking {};
+
+private:
+ char _getChar();
+ PRBool _getBytes(int size);
+
+ const PRFileDesc *_socket;
+ int _allocSize;
+ char *_buf;
+ int _curPos;
+ int _curSize;
+
+ PRBool _chunkedMode;
+ int _currentChunkSize;
+ int _currentChunkBytesRead;
+ PRIntervalTime _timeout;
+ char *_content;
+ int _contentSize;
+};
+
+
+class __EXPORT Response
+{
+ public:
+ Response(const PRFileDesc *sock, NetRequest *request);
+
+ protected:
+ const PRFileDesc *_socket;
+ NetRequest *_request;
+};
+
+
+class __EXPORT PSHttpResponse: public Response
+{
+ public:
+ PSHttpResponse( const PRFileDesc *sock,
+ PSHttpRequest *request );
+ PSHttpResponse( const PRFileDesc *sock,
+ PSHttpRequest *request,
+ int timeout, PRBool expectChunked );
+ virtual ~PSHttpResponse();
+ virtual PRBool processResponse();
+
+ int getReturnCode();
+ long getStatus();
+ char *getStatusString();
+ HttpProtocol getProtocol();
+ char *getHeader(const char *name);
+ int getHeaders(char ***keys);
+
+ PRBool checkKeepAlive(); // return true if we *expect* keepalive based on request
+ PRBool checkConnection(); // return true if connection is open
+
+ long getBodyLength();
+ char *getContent();
+ void freeContent();
+ int getContentSize();
+ char *toString();
+
+ protected:
+ PSHttpRequest *_request;
+ int _verifyStandardBody(RecvBuf &, int, PRBool);
+ PRBool _handleBody(RecvBuf &buf);
+ void _checkResponseSanity();
+
+ HttpProtocol _proto;
+ char *_protocol;
+ int retcode;
+ char *_statusNum;
+ char *_statusString;
+
+ int _keepAlive;
+ int _connectionClosed;
+
+ long _bodyLength;
+
+ PRBool _expectChunked;
+ PRBool _chunkedResponse;
+
+ StringKeyCache *_headers;
+
+ int _timeout;
+ char *_content;
+ int _contentSize;
+};
+
+
+#endif
diff --git a/base/tps/src/include/main/AttributeSpec.h b/base/tps/src/include/main/AttributeSpec.h
new file mode 100644
index 000000000..3aa0655b5
--- /dev/null
+++ b/base/tps/src/include/main/AttributeSpec.h
@@ -0,0 +1,68 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_ATTRIBUTESPEC_H
+#define RA_ATTRIBUTESPEC_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "pk11func.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class AttributeSpec
+{
+ public:
+ AttributeSpec();
+ ~AttributeSpec();
+ public:
+ static AttributeSpec *Parse(Buffer *b, int offset);
+ void SetAttributeID(unsigned long v);
+ unsigned long GetAttributeID();
+ void SetType(BYTE v);
+ BYTE GetType();
+ void SetData(Buffer data);
+ Buffer GetData(); // this gets entire AttributeSpec
+ Buffer GetValue(); // this gets AttributeValue
+ public:
+ unsigned long m_id;
+ BYTE m_type;
+ Buffer m_data; // this contains AttributeValue
+};
+
+#endif /* RA_ATTRIBUTESPEC_H */
diff --git a/base/tps/src/include/main/AuthenticationEntry.h b/base/tps/src/include/main/AuthenticationEntry.h
new file mode 100644
index 000000000..e4ec0715c
--- /dev/null
+++ b/base/tps/src/include/main/AuthenticationEntry.h
@@ -0,0 +1,64 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef AUTHENTICATIONENTRY_H
+#define AUTHENTICATIONENTRY_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "authentication/Authentication.h"
+
+class AuthenticationEntry
+{
+ public:
+ AuthenticationEntry();
+ virtual ~AuthenticationEntry();
+ public:
+ void SetLibrary(PRLibrary* lib);
+ PRLibrary *GetLibrary();
+ void SetId(const char *id);
+ char *GetId();
+ void SetAuthentication(Authentication *auth);
+ Authentication *GetAuthentication();
+ void SetType(const char *type);
+ char *GetType();
+
+ private:
+ PRLibrary *m_lib;
+ char *m_Id;
+ char *m_type;
+ Authentication *m_authentication;
+};
+
+#endif /* AUTHENTICATIONENTRY_H */
diff --git a/base/tps/src/include/main/Base.h b/base/tps/src/include/main/Base.h
new file mode 100644
index 000000000..3c5260178
--- /dev/null
+++ b/base/tps/src/include/main/Base.h
@@ -0,0 +1,63 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef BASE_H
+#define BASE_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "nspr.h"
+
+typedef unsigned char BYTE;
+
+enum nsNKeyMsgEnum {
+ VRFY_FAILURE,
+ VRFY_SUCCESS,
+ ENCODE_DER_PUBKEY_FAILURE,
+ B64ENCODE_FAILURE,
+ VFY_BEGIN_FAILURE,
+ VFY_UPDATE_FAILURE,
+ HTTP_REQ_EXE_FAILURE,
+ HTTP_ERROR_RCVD,
+ BASE64_DECODE_FAILURE,
+ REQ_TO_CA_SUCCESS,
+ MSG_INVALID
+};
+
+struct ReturnStatus {
+ PRStatus status;
+ nsNKeyMsgEnum statusNum;
+};
+
+#endif /* BASE_H */
diff --git a/base/tps/src/include/main/Buffer.h b/base/tps/src/include/main/Buffer.h
new file mode 100644
index 000000000..4fa7af6df
--- /dev/null
+++ b/base/tps/src/include/main/Buffer.h
@@ -0,0 +1,196 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#ifndef BUFFER_H
+#define BUFFER_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include "main/Base.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * This class represents a byte array.
+ */
+class Buffer {
+
+ private:
+ BYTE *buf;
+ unsigned int len;
+ unsigned int res;
+
+ public:
+ /**
+ * Creates an empty Buffer.
+ */
+ TPS_PUBLIC Buffer() : buf(0), len(0), res(0) { }
+
+ /**
+ * Creates a Buffer of length 'len', with each byte initialized to 'b'.
+ */
+ TPS_PUBLIC Buffer(unsigned int len, BYTE b);
+
+ /**
+ * Creates a Buffer of length 'len', initialized to zeroes.
+ */
+ TPS_PUBLIC explicit Buffer(unsigned int len);
+
+ /**
+ * Creates a Buffer of length 'len', initialized from 'buf'. 'buf' must
+ * contain at least 'len' bytes.
+ */
+ TPS_PUBLIC Buffer(const BYTE* buf, unsigned int len);
+
+ /**
+ * Copy constructor.
+ */
+ TPS_PUBLIC Buffer(const Buffer& cpy);
+
+ /**
+ * Destructor.
+ */
+ TPS_PUBLIC ~Buffer();
+
+ /**
+ * Assignment operator.
+ */
+ TPS_PUBLIC Buffer& operator=(const Buffer& cpy);
+
+ /**
+ * Returns true if the two buffers are the same length and contain
+ * the same byte at each offset.
+ */
+ TPS_PUBLIC bool operator==(const Buffer& cmp) const;
+
+ /**
+ * Returns ! operator==(cmp).
+ */
+ TPS_PUBLIC bool operator!=(const Buffer& cmp) const { return ! (*this == cmp); }
+
+ /**
+ * Concatenation operator.
+ */
+ TPS_PUBLIC Buffer operator+(const Buffer&addend) const;
+
+ /**
+ * Append operators.
+ */
+ TPS_PUBLIC Buffer& operator+=(const Buffer&addend);
+ TPS_PUBLIC Buffer& operator+=(BYTE b);
+
+ /**
+ * Returns a pointer into the Buffer. This also enables the subscript
+ * operator, so you can say, for example, 'buf[4] = b' or 'b = buf[4]'.
+ */
+ TPS_PUBLIC operator BYTE*() { return buf; }
+ TPS_PUBLIC operator const BYTE*() const { return buf; }
+
+ /**
+ * The length of buffer. The actual amount of space allocated may be
+ * higher--see capacity().
+ */
+ TPS_PUBLIC unsigned int size() const { return len; }
+
+ /**
+ * The amount of memory allocated for the buffer. This is the maximum
+ * size the buffer can grow before it needs to allocate more memory.
+ */
+ TPS_PUBLIC unsigned int capacity() const { return res; }
+
+ /**
+ * Sets all bytes in the buffer to 0.
+ */
+ TPS_PUBLIC void zeroize();
+
+ /**
+ * Changes the length of the Buffer. If 'newLen' is shorter than the
+ * current length, the Buffer is truncated. If 'newLen' is longer, the
+ * new bytes are initialized to 0. If 'newLen' is the same as size(),
+ * this is a no-op.
+ */
+ TPS_PUBLIC void resize(unsigned int newLen);
+
+ /**
+ * Ensures that capacity() is at least 'reserve'. Allocates more memory
+ * if necessary. If 'reserve' is <= capacity(), this is a no-op.
+ * Does not affect size().
+ */
+ TPS_PUBLIC void reserve(unsigned int reserve);
+
+ /**
+ * Returns a new Buffer that is a substring of this Buffer, starting
+ * from offset 'start' and continuing for 'len' bytes. This Buffer
+ * must have size() >= (start + len).
+ */
+ TPS_PUBLIC Buffer substr(unsigned int start, unsigned int len) const;
+
+ /**
+ * Replaces bytes i through i+n in this Buffer using the values in 'cpy'.
+ * This Buffer is resized if necessary. The 'cpy' argument can be a
+ * Buffer.
+ */
+ TPS_PUBLIC void replace(unsigned int i, const BYTE* cpy, unsigned int n);
+
+ /**
+ * returns a hex version of the buffer
+ */
+ TPS_PUBLIC char *toHex();
+
+ /**
+ * Dumps this Buffer to the given file as formatted hex: 16 bytes per
+ * line, separated by spaces.
+ */
+ TPS_PUBLIC void dump(FILE* file) const;
+
+ /**
+ * returns a null-terminated string of the buf.
+ * should be called only by callers that are certain that buf
+ * is entirely representable by printable characters and wants
+ * a string instead.
+ */
+ TPS_PUBLIC char *string();
+
+ /**
+ * dump()s this Buffer to stdout.
+ */
+ TPS_PUBLIC void dump() const;
+
+};
+
+#endif
diff --git a/base/tps/src/include/main/ConfigStore.h b/base/tps/src/include/main/ConfigStore.h
new file mode 100644
index 000000000..d34e0ce7b
--- /dev/null
+++ b/base/tps/src/include/main/ConfigStore.h
@@ -0,0 +1,126 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef CONFIG_STORE_H
+#define CONFIG_STORE_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "plhash.h"
+#include "main/Buffer.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef XP_WIN32
+#define TOKENDB_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TOKENDB_PUBLIC
+#endif /* !XP_WIN32 */
+
+class ConfigStoreRoot;
+
+class ConfigStore
+{
+ public:
+ ConfigStore(ConfigStoreRoot* root, const char *subStoreName);
+ //ConfigStore::ConfigStore(const ConfigStore &X);
+
+ ~ConfigStore();
+ static ConfigStore *Parse(const char *s, const char *separator);
+ static ConfigStore *CreateFromConfigFile(const char *cfg_path);
+
+ int IsNameDefined(const char *name);
+ void SetFilePath(const char* cfg_file_path);
+ void Add(const char *name, const char *value);
+ void Remove(const char *name);
+ const char * GetConfig(const char *name);
+ int Size();
+ const char * GetNameAt(int pos);
+ ConfigStore GetSubStore(const char*name);
+ ConfigStore *GetPatternSubStore(const char* pattern);
+
+ // Retrieve config parameters
+ Buffer * GetConfigAsBuffer(const char *key);
+ Buffer * GetConfigAsBuffer(const char *key, const char *def);
+ int GetConfigAsInt(const char *key);
+ TPS_PUBLIC int GetConfigAsInt(const char *key, int def);
+ unsigned int GetConfigAsUnsignedInt(const char *key);
+ TPS_PUBLIC unsigned int GetConfigAsUnsignedInt(const char *key,
+ unsigned int def);
+ bool GetConfigAsBool(const char *key);
+ TPS_PUBLIC bool GetConfigAsBool(const char *key, bool def);
+ TOKENDB_PUBLIC const char *GetConfigAsString(const char *key, const char *def);
+ TPS_PUBLIC int Commit(const bool backup, char* error_msg, int len);
+ TPS_PUBLIC const char *GetConfigAsString(const char *key);
+ TPS_PUBLIC const char *GetOrderedList();
+ /**
+ * operator[] is used to look up config strings in the ConfigStore.
+ * For example:
+ * <PRE>
+ * const char *param = cfg["filename"]; // equivalent
+ * const char *param = cfg.GetConfig("filename"); // equivalent
+ * </PRE>
+ */
+ const char * operator[](const char*key);
+
+ private:
+ char *m_substore_name;
+ ConfigStoreRoot *m_root;
+ char *m_cfg_file_path;
+ PRLock *m_lock;
+};
+
+class ConfigStoreRoot
+{
+ friend class ConfigStore;
+ public:
+ ConfigStoreRoot();
+ ~ConfigStoreRoot();
+ void addref();
+ void release();
+
+ private:
+ PLHashTable* getSet();
+ PLHashTable *m_set;
+ int m_set_refcount;
+
+};
+
+
+
+#endif /* CONFIG_STORE_H */
diff --git a/base/tps/src/include/main/LogFile.h b/base/tps/src/include/main/LogFile.h
new file mode 100644
index 000000000..663929eb2
--- /dev/null
+++ b/base/tps/src/include/main/LogFile.h
@@ -0,0 +1,89 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifndef LOGFILE_H
+#define LOGFILE_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include "main/RA_Context.h"
+#include "main/Util.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class LogFile {
+ protected:
+ PRFileDesc *m_fd;
+ char* m_fname;
+ volatile bool m_signed_log;
+ volatile size_t m_bytes_written;
+ volatile bool m_signed;
+ PRMonitor *m_monitor;
+ RA_Context *m_ctx;
+
+ public:
+ TPS_PUBLIC LogFile();
+ TPS_PUBLIC virtual ~LogFile() {}
+
+ /* startup and shutdown */
+ virtual int startup(RA_Context* ctx, const char* prefix, const char *fname, bool sign_audit);
+ virtual void shutdown();
+ virtual void child_init() {}
+
+ /* open/close the file */
+ int open();
+ int close();
+ bool isOpen();
+
+ /* read and write */
+ virtual int write(const char * msg);
+ int printf(const char* fmt, ...);
+ int write(char *msg, size_t n);
+ int vfprintf(const char* fmt, va_list ap);
+ int ReadLine(char *buf, int buf_len, int *removed_return);
+
+ /* accessor and setters */
+ void setSigned(bool val);
+ bool getSigned();
+ int get_bytes_written();
+ void set_bytes_written(int val);
+ RA_Context * get_context();
+ void set_context(RA_Context *ctx);
+};
+
+#endif
diff --git a/base/tps/src/include/main/Login.h b/base/tps/src/include/main/Login.h
new file mode 100644
index 000000000..81a22870e
--- /dev/null
+++ b/base/tps/src/include/main/Login.h
@@ -0,0 +1,55 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef LOGIN_H
+#define LOGIN_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+
+class Login
+{
+ public:
+ Login(char *uid, char *pwd);
+ ~Login();
+ public:
+ char *GetUID();
+ char *GetPassword();
+ private:
+ char *m_uid;
+ char *m_pwd;
+};
+
+#endif /* LOGIN_H */
diff --git a/base/tps/src/include/main/Memory.h b/base/tps/src/include/main/Memory.h
new file mode 100644
index 000000000..ca9608466
--- /dev/null
+++ b/base/tps/src/include/main/Memory.h
@@ -0,0 +1,130 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_MEMORY_H
+#define RA_MEMORY_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/MemoryMgr.h"
+
+#ifdef MEM_PROFILING
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+extern void MEM_init(char *audit_file, char *dump_file);
+extern void MEM_shutdown();
+extern void MEM_dump_unfree();
+extern char *MEM_strdup(const char *, const char *, const char *, const char *, int);
+extern void *MEM_malloc(int, const char *, const char *, const char *, int);
+extern void MEM_free(void *i, const char *, const char *, const char *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#ifdef malloc
+#undef malloc
+#endif
+
+#ifdef free
+#undef free
+#endif
+
+#ifdef strdup
+#undef strdup
+#endif
+
+#ifdef PL_strdup
+#undef PL_strdup
+#endif
+
+#ifdef PL_strfree
+#undef PL_strfree
+#endif
+
+
+#define strdup(s) MEM_strdup(s,"strcpy",__FUNCTION__,__FILE__,__LINE__)
+#define malloc(size) MEM_malloc(size,"malloc",__FUNCTION__,__FILE__,__LINE__)
+#define free(p) MEM_free(p,"free",__FUNCTION__,__FILE__,__LINE__)
+#define PR_MALLOC(size) MEM_malloc(size,"PL_MALLOC",__FUNCTION__,__FILE__,__LINE__)
+#define PR_Malloc(size) MEM_malloc(size,"PR_Malloc",__FUNCTION__,__FILE__,__LINE__)
+#define PR_Free(p) MEM_free(p,"free",__FUNCTION__,__FILE__,__LINE__)
+
+#define PL_strdup(s) MEM_strdup(s,"PL_strdup",__FUNCTION__,__FILE__,__LINE__)
+#define PL_strfree(p) MEM_free(p,"PL_strfree",__FUNCTION__,__FILE__,__LINE__)
+
+#if 0
+extern void *operator new(size_t size, const char *func, const char *file, int line);
+extern void *operator new[](size_t size, const char *func, const char *file, int line);
+#endif
+extern void operator delete(void* p);
+extern void operator delete[](void* p);
+
+inline void *operator new(size_t size, const char *func, const char *file, int line)
+{
+ return MEM_malloc(size, "new", func, file, line);
+}
+
+inline void *operator new[](size_t size, const char *func, const char *file, int line)
+{
+ return MEM_malloc(size, "new[]", func, file, line);
+}
+
+#if 0
+inline void operator delete(void *p)
+{
+ MEM_free(p,"delete","", "", 0);
+}
+
+inline void operator delete[](void *p)
+{
+ MEM_free(p,"delete[]","", "", 0);
+}
+#endif
+
+
+#ifdef new
+#undef new
+#endif
+
+#define new new(__FUNCTION__,__FILE__,__LINE__)
+
+#endif
+
+#endif /* RA_MEMORY_H */
diff --git a/base/tps/src/include/main/MemoryMgr.h b/base/tps/src/include/main/MemoryMgr.h
new file mode 100644
index 000000000..7e2f71dc1
--- /dev/null
+++ b/base/tps/src/include/main/MemoryMgr.h
@@ -0,0 +1,46 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_MEMORY_MGR_H
+#define RA_MEMORY_MGR_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/* Uncomment the following to enable memory profiling */
+
+/* #define MEM_PROFILING */
+#define MEM_AUDIT_FILE "/tmp/mem-audit.log"
+#define MEM_DUMP_FILE "/tmp/mem-dump.log"
+
+#endif /* RA_MEMORY_MGR_H */
diff --git a/base/tps/src/include/main/NameValueSet.h b/base/tps/src/include/main/NameValueSet.h
new file mode 100644
index 000000000..6c9055a59
--- /dev/null
+++ b/base/tps/src/include/main/NameValueSet.h
@@ -0,0 +1,72 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef NAME_VALUE_SET_H
+#define NAME_VALUE_SET_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "plhash.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class NameValueSet
+{
+ public:
+ TPS_PUBLIC NameValueSet();
+ TPS_PUBLIC ~NameValueSet();
+ public:
+ TPS_PUBLIC static NameValueSet *Parse(const char *s, const char *separator);
+ TPS_PUBLIC int IsNameDefined(const char *name);
+ TPS_PUBLIC void Remove(const char *name);
+ TPS_PUBLIC void Add(const char *name, const char *value);
+ TPS_PUBLIC char *GetValue(const char *name);
+ TPS_PUBLIC int Size();
+ TPS_PUBLIC char *GetNameAt(int pos);
+ TPS_PUBLIC int GetValueAsInt(const char *key);
+ TPS_PUBLIC int GetValueAsInt(const char *key, int def);
+ TPS_PUBLIC int GetValueAsBool(const char *key);
+ TPS_PUBLIC int GetValueAsBool(const char *key, int def);
+ TPS_PUBLIC char *GetValueAsString(const char *key, char *def);
+ TPS_PUBLIC char *GetValueAsString(const char *key);
+
+ private:
+ PLHashTable *m_set;
+};
+
+#endif /* NAME_VALUE_SET_H */
diff --git a/base/tps/src/include/main/ObjectSpec.h b/base/tps/src/include/main/ObjectSpec.h
new file mode 100644
index 000000000..3b0bee72c
--- /dev/null
+++ b/base/tps/src/include/main/ObjectSpec.h
@@ -0,0 +1,79 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_OBJECTSPEC_H
+#define RA_OBJECTSPEC_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "pk11func.h"
+#include "main/Buffer.h"
+#include "main/AttributeSpec.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class ObjectSpec
+{
+ public:
+ ObjectSpec();
+ ~ObjectSpec();
+ public:
+ static ObjectSpec *ParseFromTokenData(unsigned long objid, Buffer *b);
+ static ObjectSpec *Parse(Buffer *b, int offset, int *nread);
+ static void ParseAttributes(char *objectID, ObjectSpec *ObjectSpec, Buffer *b);
+ static void ParseCertificateAttributes(char *objectID, ObjectSpec *ObjectSpec, Buffer *b);
+ static void ParseKeyAttributes(char *objectID, ObjectSpec *ObjectSpec, Buffer *b);
+ static void ParseCertificateBlob(char *objectID, ObjectSpec *ObjectSpec, Buffer *b);
+
+ void SetObjectID(unsigned long v);
+ unsigned long GetObjectID();
+ void SetFixedAttributes(unsigned long v);
+ unsigned long GetFixedAttributes();
+ int GetAttributeSpecCount();
+ AttributeSpec *GetAttributeSpec(int p);
+ void AddAttributeSpec(AttributeSpec *p);
+ void RemoveAttributeSpec(int p);
+ Buffer GetData();
+ public:
+ unsigned long m_objectID;
+ unsigned long m_fixedAttributes;
+#define MAX_ATTRIBUTE_SPEC 30
+ AttributeSpec *m_attributeSpec[MAX_ATTRIBUTE_SPEC];
+};
+
+#endif /* RA_OBJECTSPEC_H */
diff --git a/base/tps/src/include/main/PKCS11Obj.h b/base/tps/src/include/main/PKCS11Obj.h
new file mode 100644
index 000000000..ef3fca964
--- /dev/null
+++ b/base/tps/src/include/main/PKCS11Obj.h
@@ -0,0 +1,80 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_PKCS11OBJ_H
+#define RA_PKCS11OBJ_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "pk11func.h"
+#include "main/ObjectSpec.h"
+#include "main/Buffer.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class PKCS11Obj
+{
+ public:
+ PKCS11Obj();
+ ~PKCS11Obj();
+ public:
+ static PKCS11Obj *Parse(Buffer *b, int offset);
+ void SetFormatVersion(unsigned short v);
+ unsigned short GetFormatVersion();
+ void SetObjectVersion(unsigned short v);
+ unsigned short GetObjectVersion();
+ void SetCUID(Buffer CUID);
+ Buffer GetCUID();
+ void SetTokenName(Buffer tokenName);
+ Buffer GetTokenName();
+ Buffer GetData();
+ Buffer GetCompressedData();
+ int GetObjectSpecCount();
+ ObjectSpec *GetObjectSpec(int p);
+ void AddObjectSpec(ObjectSpec *p);
+ void RemoveObjectSpec(int p);
+ public:
+ unsigned short m_formatVersion;
+ unsigned short m_objectVersion;
+ Buffer m_CUID;
+ Buffer m_tokenName;
+#define MAX_OBJECT_SPEC 20
+ ObjectSpec *m_objSpec[MAX_OBJECT_SPEC];
+};
+
+#endif /* RA_PKCS11OBj_H */
diff --git a/base/tps/src/include/main/PublishEntry.h b/base/tps/src/include/main/PublishEntry.h
new file mode 100644
index 000000000..05d5939a4
--- /dev/null
+++ b/base/tps/src/include/main/PublishEntry.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_PUBLISH_ENTRY_H
+#define RA_PUBLISH_ENTRY_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "publisher/IPublisher.h"
+#define MAX_PUBLISHERS 10
+
+struct PublisherEntry
+{
+
+ char *id;
+ IPublisher *publisher;
+ PRLibrary *publisher_lib;
+ char *factory;
+
+ struct PublisherEntry *next;
+};
+
+typedef struct PublisherEntry PublisherEntry;
+
+#endif /* RA_PUBLISH_ENTRY_H */
+
diff --git a/base/tps/src/include/main/RA_Context.h b/base/tps/src/include/main/RA_Context.h
new file mode 100644
index 000000000..e313f45fd
--- /dev/null
+++ b/base/tps/src/include/main/RA_Context.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_CONTEXT_H
+#define RA_CONTEXT_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Context
+{
+ public:
+ TPS_PUBLIC RA_Context();
+ TPS_PUBLIC virtual ~RA_Context();
+ public:
+ virtual void LogError(const char *func, int line, const char *fmt,...);
+ virtual void LogInfo(const char *func, int line, const char *fmt,...);
+ virtual void InitializationError(const char *func, int line);
+};
+
+#endif /* RA_CONTEXT_H */
diff --git a/base/tps/src/include/main/RA_Msg.h b/base/tps/src/include/main/RA_Msg.h
new file mode 100644
index 000000000..d94063b00
--- /dev/null
+++ b/base/tps/src/include/main/RA_Msg.h
@@ -0,0 +1,79 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_MSG_H
+#define RA_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+
+enum RA_Op_Type {
+ OP_ENROLL = 1,
+ OP_UNBLOCK = 2,
+ OP_RESET_PIN = 3,
+ OP_RENEW = 4,
+ OP_FORMAT = 5
+};
+
+enum RA_Msg_Type {
+ MSG_UNDEFINED = -1,
+ MSG_BEGIN_OP = 2,
+ MSG_LOGIN_REQUEST = 3,
+ MSG_LOGIN_RESPONSE = 4,
+ MSG_SECUREID_REQUEST = 5,
+ MSG_SECUREID_RESPONSE = 6,
+ MSG_ASQ_REQUEST = 7,
+ MSG_ASQ_RESPONSE = 8,
+ MSG_NEW_PIN_REQUEST = 11,
+ MSG_NEW_PIN_RESPONSE = 12,
+ MSG_TOKEN_PDU_REQUEST = 9,
+ MSG_TOKEN_PDU_RESPONSE = 10,
+ MSG_END_OP = 13,
+ MSG_STATUS_UPDATE_REQUEST = 14,
+ MSG_STATUS_UPDATE_RESPONSE = 15,
+ MSG_EXTENDED_LOGIN_REQUEST = 16,
+ MSG_EXTENDED_LOGIN_RESPONSE = 17
+};
+
+class RA_Msg
+{
+ public:
+ RA_Msg();
+ virtual ~RA_Msg();
+ public:
+ virtual RA_Msg_Type GetType();
+};
+
+#endif /* RA_MSG_H */
diff --git a/base/tps/src/include/main/RA_Session.h b/base/tps/src/include/main/RA_Session.h
new file mode 100644
index 000000000..520a94b6a
--- /dev/null
+++ b/base/tps/src/include/main/RA_Session.h
@@ -0,0 +1,61 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_SESSION_H
+#define RA_SESSION_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_pblock.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Session
+{
+ public:
+ TPS_PUBLIC RA_Session();
+ TPS_PUBLIC virtual ~RA_Session();
+ public:
+ virtual RA_pblock *create_pblock( char *data );
+ virtual RA_Msg *ReadMsg();
+ virtual char *GetRemoteIP();
+ virtual void WriteMsg(RA_Msg *msg);
+};
+
+#endif /* RA_SESSION_H */
diff --git a/base/tps/src/include/main/RA_pblock.h b/base/tps/src/include/main/RA_pblock.h
new file mode 100644
index 000000000..685dc321b
--- /dev/null
+++ b/base/tps/src/include/main/RA_pblock.h
@@ -0,0 +1,74 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_PBLOCK_H
+#define RA_PBLOCK_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Buffer.h"
+
+#define MAX_NVS 50
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+struct Buffer_nv {
+ char *name;
+ char *value_s;
+ Buffer *value;
+};
+
+class RA_pblock
+{
+ public:
+ TPS_PUBLIC RA_pblock( int tm_nargs, Buffer_nv** tm_nvs );
+ TPS_PUBLIC ~RA_pblock();
+ public:
+ Buffer_nv **GetNVs();
+ TPS_PUBLIC Buffer *find_val( const char * name );
+ TPS_PUBLIC char* find_val_s( const char * name );
+ void free_pblock();
+ TPS_PUBLIC char *get_name( int i );
+ TPS_PUBLIC int get_num_of_names();
+ public:
+ // an array of pointers to name/value pairs
+ Buffer_nv *m_nvs[MAX_NVS];
+ int m_nargs;
+};
+
+#endif /* RA_PBLOCK_H */
diff --git a/base/tps/src/include/main/RollingLogFile.h b/base/tps/src/include/main/RollingLogFile.h
new file mode 100644
index 000000000..63239b94b
--- /dev/null
+++ b/base/tps/src/include/main/RollingLogFile.h
@@ -0,0 +1,93 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifndef ROLLINGLOGFILE_H
+#define ROLLINGLOGFILE_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#include "main/LogFile.h"
+
+class RollingLogFile: public LogFile {
+ private:
+ size_t m_max_file_size;
+ volatile int m_rollover_interval;
+ volatile int m_expiration_time;
+ int m_expiration_sleep_time;
+ volatile bool m_rotation_needed;
+ PRThread* m_rollover_thread;
+ PRThread* m_expiration_thread;
+
+ public:
+ static const char *CFG_MAX_FILE_SIZE;
+ static const char *CFG_ROLLOVER_INTERVAL;
+ static const char *CFG_EXPIRATION_INTERVAL;
+ static const int MAX_SLEEP;
+
+ public:
+ TPS_PUBLIC RollingLogFile();
+ TPS_PUBLIC ~RollingLogFile() {}
+
+ int startup(RA_Context *ctx, const char* prefix, const char *fname, bool sign_audit);
+ void shutdown();
+ void child_init();
+ int write(char *msg);
+ void rotate();
+
+ /* accessors and mutators */
+ void set_rollover_interval(int interval);
+ int get_rollover_interval();
+ void set_expiration_time(int interval);
+ int get_expiration_time();
+ void set_rotation_needed(bool val);
+ bool get_rotation_needed();
+
+ private:
+ static void start_rollover_thread(void *args);
+ void run_rollover_thread();
+
+ static void start_expiration_thread(void *args);
+ void run_expiration_thread();
+ void expire();
+
+};
+
+#endif
diff --git a/base/tps/src/include/main/SecureId.h b/base/tps/src/include/main/SecureId.h
new file mode 100644
index 000000000..fd7e6a158
--- /dev/null
+++ b/base/tps/src/include/main/SecureId.h
@@ -0,0 +1,55 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef SECUREID_H
+#define SECUREID_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+
+class SecureId
+{
+ public:
+ SecureId(char *value, char *pin);
+ ~SecureId();
+ public:
+ char *GetValue();
+ char *GetPIN(); /* optional pin */
+ private:
+ char *m_value;
+ char *m_pin;
+};
+
+#endif /* RA_MSG_H */
diff --git a/base/tps/src/include/main/Util.h b/base/tps/src/include/main/Util.h
new file mode 100644
index 000000000..c4d670483
--- /dev/null
+++ b/base/tps/src/include/main/Util.h
@@ -0,0 +1,99 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_UTIL_H
+#define RA_UTIL_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "pk11func.h"
+#include "main/Buffer.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Util
+{
+ public:
+ TPS_PUBLIC Util();
+ TPS_PUBLIC ~Util();
+ public:
+ TPS_PUBLIC static int ReadLine(PRFileDesc *f, char *buf, int buf_len, int *removed_return);
+ TPS_PUBLIC static int ascii2numeric(char ch);
+ TPS_PUBLIC static char *Buffer2String (Buffer &data);
+ TPS_PUBLIC static Buffer *Str2Buf (const char *s);
+ TPS_PUBLIC static char *URLEncode (Buffer &data);
+ TPS_PUBLIC static char *URLEncodeInHex (Buffer &data);
+ TPS_PUBLIC static char *URLEncode (const char *data);
+ TPS_PUBLIC static char *URLEncode1 (const char *data);
+ TPS_PUBLIC static Buffer *URLDecode(const char *data);
+ TPS_PUBLIC static char *SpecialURLEncode (Buffer &data);
+ TPS_PUBLIC static Buffer *SpecialURLDecode(const char *data);
+ TPS_PUBLIC static PRStatus GetRandomChallenge(Buffer &random);
+ TPS_PUBLIC static PRStatus CreateKeySetData(
+ Buffer &key_set_version,
+ Buffer &old_kek_key,
+ Buffer &new_auth_key,
+ Buffer &new_mac_key,
+ Buffer &new_kek_key,
+ Buffer &output);
+ TPS_PUBLIC static PRStatus ComputeCryptogram(PK11SymKey *key,
+ const Buffer &card_challenge,
+ const Buffer &host_challenge,
+ Buffer &output);
+ TPS_PUBLIC static PRStatus ComputeMAC(PK11SymKey *key,
+ Buffer &input, const Buffer &icv,
+ Buffer &output);
+ TPS_PUBLIC static PRStatus ComputeKeyCheck(
+ const Buffer& newKey, Buffer& output);
+ TPS_PUBLIC static PK11SymKey *DeriveKey(const Buffer& permKey,
+ const Buffer& hostChallenge,
+ const Buffer& cardChallenge);
+ TPS_PUBLIC static PRStatus EncryptData(PK11SymKey *encSessionKey,
+ Buffer &input, Buffer &output);
+ TPS_PUBLIC static PRStatus EncryptData(Buffer &kek_key,
+ Buffer &input, Buffer &output);
+ TPS_PUBLIC static PK11SymKey *DiversifyKey(PK11SymKey *master,
+ Buffer &data, PK11SlotInfo *slot);
+ TPS_PUBLIC static PRStatus DecryptData(Buffer &kek_key,
+ Buffer &input, Buffer &output);
+ TPS_PUBLIC static PRStatus DecryptData(PK11SymKey* enc_key,
+ Buffer &input, Buffer &output);
+ TPS_PUBLIC static BYTE* bool2byte(bool p);
+};
+
+#endif /* RA_UTIL_H */
diff --git a/base/tps/src/include/modules/tps/AP_Context.h b/base/tps/src/include/modules/tps/AP_Context.h
new file mode 100644
index 000000000..4faca55ac
--- /dev/null
+++ b/base/tps/src/include/modules/tps/AP_Context.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef AP_CONTEXT_H
+#define AP_CONTEXT_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Context.h"
+
+class AP_Context : public RA_Context
+{
+ public:
+ AP_Context( server_rec *sv );
+ virtual ~AP_Context();
+ public:
+ virtual void LogError( const char *func, int line,
+ const char *fmt, ... );
+ virtual void LogInfo( const char *func, int line,
+ const char *fmt, ... );
+ virtual void InitializationError( const char *func, int line );
+ private:
+ server_rec *m_sv;
+};
+
+#endif /* AP_CONTEXT_H */
diff --git a/base/tps/src/include/modules/tps/AP_Session.h b/base/tps/src/include/modules/tps/AP_Session.h
new file mode 100644
index 000000000..832166a1b
--- /dev/null
+++ b/base/tps/src/include/modules/tps/AP_Session.h
@@ -0,0 +1,56 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef AP_SESSION_H
+#define AP_SESSION_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Session.h"
+
+class AP_Session : public RA_Session
+{
+ public:
+ AP_Session( request_rec *rq );
+ virtual ~AP_Session();
+ public:
+ virtual char *GetRemoteIP();
+ virtual RA_pblock *create_pblock( char *data );
+ virtual RA_Msg *ReadMsg();
+ virtual void WriteMsg( RA_Msg *msg );
+ private:
+ request_rec *m_rq;
+};
+
+#endif /* AP_SESSION_H */
diff --git a/base/tps/src/include/msg/RA_ASQ_Request_Msg.h b/base/tps/src/include/msg/RA_ASQ_Request_Msg.h
new file mode 100644
index 000000000..15f8bd7a4
--- /dev/null
+++ b/base/tps/src/include/msg/RA_ASQ_Request_Msg.h
@@ -0,0 +1,62 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_ASQ_REQUEST_MSG_H
+#define RA_ASQ_REQUEST_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_ASQ_Request_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_ASQ_Request_Msg(char *question);
+ TPS_PUBLIC ~RA_ASQ_Request_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC char *GetQuestion();
+ private:
+ char *m_question;
+};
+
+#endif /* RA_ASQ_REQUEST_MSG_H */
diff --git a/base/tps/src/include/msg/RA_ASQ_Response_Msg.h b/base/tps/src/include/msg/RA_ASQ_Response_Msg.h
new file mode 100644
index 000000000..3614e443f
--- /dev/null
+++ b/base/tps/src/include/msg/RA_ASQ_Response_Msg.h
@@ -0,0 +1,62 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_ASQ_RESPONSE_MSG_H
+#define RA_ASQ_RESPONSE_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_ASQ_Response_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_ASQ_Response_Msg(char *answer);
+ TPS_PUBLIC ~RA_ASQ_Response_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC char *GetAnswer();
+ private:
+ char *m_answer;
+};
+
+#endif /* RA_ASQ_RESPONSE_MSG_H */
diff --git a/base/tps/src/include/msg/RA_Begin_Op_Msg.h b/base/tps/src/include/msg/RA_Begin_Op_Msg.h
new file mode 100644
index 000000000..48a61a659
--- /dev/null
+++ b/base/tps/src/include/msg/RA_Begin_Op_Msg.h
@@ -0,0 +1,64 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_BEGIN_OP_MSG_H
+#define RA_BEGIN_OP_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Msg.h"
+#include "main/NameValueSet.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Begin_Op_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_Begin_Op_Msg(RA_Op_Type op, NameValueSet *exts);
+ TPS_PUBLIC ~RA_Begin_Op_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC RA_Op_Type GetOpType();
+ TPS_PUBLIC NameValueSet *GetExtensions();
+ private:
+ RA_Op_Type m_op;
+ NameValueSet *m_exts;
+};
+
+#endif /* RA_BEGIN_OP_MSG_H */
diff --git a/base/tps/src/include/msg/RA_End_Op_Msg.h b/base/tps/src/include/msg/RA_End_Op_Msg.h
new file mode 100644
index 000000000..fe396f05b
--- /dev/null
+++ b/base/tps/src/include/msg/RA_End_Op_Msg.h
@@ -0,0 +1,84 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_END_OP_MSG_H
+#define RA_END_OP_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+
+#define NKEY_ERROR_NO_ERROR 0
+#define NKEY_ERROR_SNAC 1
+#define NKEY_ERROR_SEC_INIT_UPDATE 2
+#define NKEY_ERROR_CREATE_CARDMGR 3
+#define NKEY_ERROR_MAC_RESET_PIN_PDU 4
+#define NKEY_ERROR_MAC_CERT_PDU 5
+#define NKEY_ERROR_MAC_LIFESTYLE_PDU 6
+#define NKEY_ERROR_MAC_ENROLL_PDU 7
+#define NKEY_ERROR_READ_OBJECT_PDU 8
+#define NKEY_ERROR_BAD_STATUS 9
+#define NKEY_ERROR_CA_RESPONSE 10
+#define NKEY_ERROR_READ_BUFFER_OVERFLOW 11
+#define NKEY_ERROR_TOKEN_RESET_PIN_FAILED 12
+#define NKEY_ERROR_CONNECTION 13
+
+#define RESULT_GOOD 0
+#define RESULT_ERROR 1
+
+class RA_End_Op_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_End_Op_Msg(RA_Op_Type op, int result, int msg);
+ TPS_PUBLIC ~RA_End_Op_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC RA_Op_Type GetOpType();
+ TPS_PUBLIC int GetResult();
+ TPS_PUBLIC int GetMsg();
+ private:
+ RA_Op_Type m_op;
+ int m_result;
+ int m_msg;
+};
+
+#endif /* RA_BEGIN_OP_MSG_H */
diff --git a/base/tps/src/include/msg/RA_Extended_Login_Request_Msg.h b/base/tps/src/include/msg/RA_Extended_Login_Request_Msg.h
new file mode 100644
index 000000000..fdfceedcf
--- /dev/null
+++ b/base/tps/src/include/msg/RA_Extended_Login_Request_Msg.h
@@ -0,0 +1,73 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_EXTENDED_LOGIN_REQUEST_MSG_H
+#define RA_EXTENDED_LOGIN_REQUEST_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Extended_Login_Request_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_Extended_Login_Request_Msg(int invalid_pw,
+ int blocked, char **parameters, int len,
+ char *title, char *description);
+ TPS_PUBLIC ~RA_Extended_Login_Request_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC int IsInvalidPassword();
+ TPS_PUBLIC int IsBlocked();
+ TPS_PUBLIC int GetLen();
+ TPS_PUBLIC char *GetParam(int i);
+ TPS_PUBLIC char *GetTitle();
+ TPS_PUBLIC char *GetDescription();
+ private:
+ char *m_title;
+ char *m_description;
+ int m_invalid_pw;
+ int m_blocked;
+ char **m_parameters;
+ int m_len;
+};
+
+#endif /* RA_EXTENDED_LOGIN_REQUEST_MSG_H */
diff --git a/base/tps/src/include/msg/RA_Extended_Login_Response_Msg.h b/base/tps/src/include/msg/RA_Extended_Login_Response_Msg.h
new file mode 100644
index 000000000..37da9feb3
--- /dev/null
+++ b/base/tps/src/include/msg/RA_Extended_Login_Response_Msg.h
@@ -0,0 +1,63 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_EXTENDED_LOGIN_RESPONSE_MSG_H
+#define RA_EXTENDED_LOGIN_RESPONSE_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "authentication/AuthParams.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Extended_Login_Response_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_Extended_Login_Response_Msg(AuthParams *param);
+ TPS_PUBLIC ~RA_Extended_Login_Response_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC AuthParams *GetAuthParams();
+ private:
+ AuthParams *m_params;
+};
+
+#endif /* RA_EXTENDED_LOGIN_RESPONSE_MSG_H */
diff --git a/base/tps/src/include/msg/RA_Login_Request_Msg.h b/base/tps/src/include/msg/RA_Login_Request_Msg.h
new file mode 100644
index 000000000..01a7a5acd
--- /dev/null
+++ b/base/tps/src/include/msg/RA_Login_Request_Msg.h
@@ -0,0 +1,63 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_LOGIN_REQUEST_MSG_H
+#define RA_LOGIN_REQUEST_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Login_Request_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_Login_Request_Msg(int invalid_pw, int blocked);
+ TPS_PUBLIC ~RA_Login_Request_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC int IsInvalidPassword();
+ TPS_PUBLIC int IsBlocked();
+ private:
+ int m_invalid_pw;
+ int m_blocked;
+};
+
+#endif /* RA_LOGIN_REQUEST_MSG_H */
diff --git a/base/tps/src/include/msg/RA_Login_Response_Msg.h b/base/tps/src/include/msg/RA_Login_Response_Msg.h
new file mode 100644
index 000000000..dcc9e3530
--- /dev/null
+++ b/base/tps/src/include/msg/RA_Login_Response_Msg.h
@@ -0,0 +1,64 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_LOGIN_RESPONSE_MSG_H
+#define RA_LOGIN_RESPONSE_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Login_Response_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_Login_Response_Msg(char *uid, char *password);
+ TPS_PUBLIC ~RA_Login_Response_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC char *GetUID();
+ TPS_PUBLIC char *GetPassword();
+ private:
+ char *m_uid;
+ char *m_password;
+};
+
+#endif /* RA_LOGIN_RESPONSE_MSG_H */
diff --git a/base/tps/src/include/msg/RA_New_Pin_Request_Msg.h b/base/tps/src/include/msg/RA_New_Pin_Request_Msg.h
new file mode 100644
index 000000000..8ebf16259
--- /dev/null
+++ b/base/tps/src/include/msg/RA_New_Pin_Request_Msg.h
@@ -0,0 +1,63 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_NEW_PIN_REQUEST_MSG_H
+#define RA_NEW_PIN_REQUEST_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_New_Pin_Request_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_New_Pin_Request_Msg(int min_len, int max_len);
+ TPS_PUBLIC ~RA_New_Pin_Request_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC int GetMinLen();
+ TPS_PUBLIC int GetMaxLen();
+ private:
+ int m_min_len;
+ int m_max_len;
+};
+
+#endif /* RA_NEW_PIN_REQUEST_MSG_H */
diff --git a/base/tps/src/include/msg/RA_New_Pin_Response_Msg.h b/base/tps/src/include/msg/RA_New_Pin_Response_Msg.h
new file mode 100644
index 000000000..f062adcf0
--- /dev/null
+++ b/base/tps/src/include/msg/RA_New_Pin_Response_Msg.h
@@ -0,0 +1,62 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_NEW_PIN_RESPONSE_MSG_H
+#define RA_NEW_PIN_RESPONSE_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_New_Pin_Response_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_New_Pin_Response_Msg(char *new_pin);
+ TPS_PUBLIC ~RA_New_Pin_Response_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC char *GetNewPIN();
+ private:
+ char *m_new_pin;
+};
+
+#endif /* RA_NEW_PIN_RESPONSE_MSG_H */
diff --git a/base/tps/src/include/msg/RA_SecureId_Request_Msg.h b/base/tps/src/include/msg/RA_SecureId_Request_Msg.h
new file mode 100644
index 000000000..132e04c22
--- /dev/null
+++ b/base/tps/src/include/msg/RA_SecureId_Request_Msg.h
@@ -0,0 +1,63 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_SECUREID_REQUEST_MSG_H
+#define RA_SECUREID_REQUEST_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_SecureId_Request_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_SecureId_Request_Msg(int pin_required, int next_value);
+ TPS_PUBLIC ~RA_SecureId_Request_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC int IsPinRequired();
+ TPS_PUBLIC int IsNextValue();
+ private:
+ int m_pin_required;
+ int m_next_value;
+};
+
+#endif /* RA_SECUREID_REQUEST_MSG_H */
diff --git a/base/tps/src/include/msg/RA_SecureId_Response_Msg.h b/base/tps/src/include/msg/RA_SecureId_Response_Msg.h
new file mode 100644
index 000000000..279e07475
--- /dev/null
+++ b/base/tps/src/include/msg/RA_SecureId_Response_Msg.h
@@ -0,0 +1,64 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_SECUREID_RESPONSE_MSG_H
+#define RA_SECUREID_RESPONSE_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_SecureId_Response_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_SecureId_Response_Msg(char *value, char *pin);
+ TPS_PUBLIC ~RA_SecureId_Response_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC char *GetValue();
+ TPS_PUBLIC char *GetPIN();
+ private:
+ char *m_value;
+ char *m_pin;
+};
+
+#endif /* RA_SECUREID_RESPONSE_MSG_H */
diff --git a/base/tps/src/include/msg/RA_Status_Update_Request_Msg.h b/base/tps/src/include/msg/RA_Status_Update_Request_Msg.h
new file mode 100644
index 000000000..bdc037c97
--- /dev/null
+++ b/base/tps/src/include/msg/RA_Status_Update_Request_Msg.h
@@ -0,0 +1,65 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_STATUS_UPDATE_REQUEST_MSG_H
+#define RA_STATUS_UPDATE_REQUEST_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Status_Update_Request_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_Status_Update_Request_Msg(int status, const char *info);
+ TPS_PUBLIC ~RA_Status_Update_Request_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ TPS_PUBLIC int GetStatus();
+ TPS_PUBLIC char *GetInfo();
+ private:
+ int m_status;
+ char *m_info;
+};
+
+#endif /* RA_STATUS_UPDATE_REQUEST_MSG_H */
diff --git a/base/tps/src/include/msg/RA_Status_Update_Response_Msg.h b/base/tps/src/include/msg/RA_Status_Update_Response_Msg.h
new file mode 100644
index 000000000..c5a13eaa4
--- /dev/null
+++ b/base/tps/src/include/msg/RA_Status_Update_Response_Msg.h
@@ -0,0 +1,63 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_STATUS_UPDATE_RESPONSE_MSG_H
+#define RA_STATUS_UPDATE_RESPONSE_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Status_Update_Response_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_Status_Update_Response_Msg(int status);
+ TPS_PUBLIC ~RA_Status_Update_Response_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ TPS_PUBLIC int GetStatus();
+ private:
+ int m_status;
+};
+
+#endif /* RA_STATUS_UPDATE_REQUEST_MSG_H */
diff --git a/base/tps/src/include/msg/RA_Token_PDU_Request_Msg.h b/base/tps/src/include/msg/RA_Token_PDU_Request_Msg.h
new file mode 100644
index 000000000..bcbdfc7fc
--- /dev/null
+++ b/base/tps/src/include/msg/RA_Token_PDU_Request_Msg.h
@@ -0,0 +1,63 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_TOKEN_PDU_REQUEST_MSG_H
+#define RA_TOKEN_PDU_REQUEST_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Token_PDU_Request_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_Token_PDU_Request_Msg(APDU *apdu);
+ TPS_PUBLIC ~RA_Token_PDU_Request_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ TPS_PUBLIC APDU *GetAPDU();
+ private:
+ APDU *m_apdu;
+};
+
+#endif /* RA_TOKEN_PDU_REQUEST_MSG_H */
diff --git a/base/tps/src/include/msg/RA_Token_PDU_Response_Msg.h b/base/tps/src/include/msg/RA_Token_PDU_Response_Msg.h
new file mode 100644
index 000000000..e7c2d538f
--- /dev/null
+++ b/base/tps/src/include/msg/RA_Token_PDU_Response_Msg.h
@@ -0,0 +1,62 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_TOKEN_PDU_RESPONSE_MSG_H
+#define RA_TOKEN_PDU_RESPONSE_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "apdu/APDU.h"
+#include "apdu/APDU_Response.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Token_PDU_Response_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_Token_PDU_Response_Msg(APDU_Response *response);
+ TPS_PUBLIC ~RA_Token_PDU_Response_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ TPS_PUBLIC APDU_Response *GetResponse();
+ private:
+ APDU_Response *m_response;
+};
+
+#endif /* RA_TOKEN_PDU_RESPONSE_MSG_H */
diff --git a/base/tps/src/include/processor/RA_Enroll_Processor.h b/base/tps/src/include/processor/RA_Enroll_Processor.h
new file mode 100644
index 000000000..b78d33f36
--- /dev/null
+++ b/base/tps/src/include/processor/RA_Enroll_Processor.h
@@ -0,0 +1,300 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_ENROLL_PROCESSOR_H
+#define RA_ENROLL_PROCESSOR_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Session.h"
+#include "main/PKCS11Obj.h"
+#include "processor/RA_Processor.h"
+#include "cms/HttpConnection.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Enroll_Processor : public RA_Processor
+{
+ public:
+ TPS_PUBLIC RA_Enroll_Processor();
+ TPS_PUBLIC ~RA_Enroll_Processor();
+ public:
+ int ParsePublicKeyBlob(unsigned char *blob,
+ unsigned char *challenge,
+ SECKEYPublicKey *pk);
+ RA_Status DoEnrollment(AuthParams *login, RA_Session *session,
+ CERTCertificate **certificates,
+ char **origins,
+ char **ktypes,
+ int pkcs11obj,
+ PKCS11Obj * pkcs_objx,
+ NameValueSet *extensions,
+ int index, int keyTypeNum,
+ int start_progress,
+ int end_progress,
+ Secure_Channel *channel, Buffer *wrapped_challenge,
+ const char *tokenType,
+ const char *keyType,
+ Buffer *key_check,
+ Buffer *plaintext_challenge,
+ const char *cuid,
+ const char *msn,
+ const char *khex,
+ TokenKeyType key_type,
+ const char *profileId,
+ const char *userid,
+ const char *cert_id,
+ const char *publisher_id,
+ const char *cert_attr_id,
+ const char *pri_attr_id,
+ const char *pub_attr_id,
+ BYTE se_p1, BYTE se_p2, int keysize, const char *connid, const char *keyTypePrefix,char * applet_version);
+
+ bool DoRenewal(const char *connid,
+ const char *profileId,
+ CERTCertificate *i_cert,
+ CERTCertificate **o_cert,
+ char *error_msg, int *error_code);
+
+ bool GenerateCertificate(AuthParams *login,
+ int keyTypeNum,
+ const char *keyTypeValue,
+ int i,
+ RA_Session *session,
+ char **origins,
+ char **ktypes,
+ char *tokenType,
+ PKCS11Obj *pkcs11objx,
+ int pkcs11obj_enable,
+ NameValueSet *extensions,
+ Secure_Channel *channel,
+ Buffer *wrapped_challenge,
+ Buffer *key_check,
+ Buffer *plaintext_challenge,
+ char *cuid,
+ char *msn,
+ const char *final_applet_version,
+ char *khex,
+ const char *userid,
+ RA_Status &o_status,
+ CERTCertificate **certificates);
+
+ bool GenerateCertsAfterRecoveryPolicy(AuthParams *login,
+ RA_Session *session,
+ char **&origins,
+ char **&ktypes,
+ char *&tokenType,
+ PKCS11Obj *pkcs11objx,
+ int pkcs11obj_enable,
+ NameValueSet *extensions,
+ Secure_Channel *channel,
+ Buffer *wrapped_challenge,
+ Buffer *key_check,
+ Buffer *plaintext_challenge,
+ char *cuid,
+ char *msn,
+ const char *final_applet_version,
+ char *khex,
+ const char *userid,
+ RA_Status &o_status,
+ CERTCertificate **&certificates,
+ int &o_certNums, char **&tokenTypes);
+
+ bool GenerateCertificates(AuthParams *login,
+ RA_Session *session,
+ char **&origins,
+ char **&ktypes,
+ char *tokenType,
+ PKCS11Obj *pkcs11objx,
+ int pkcs11obj_enable,
+ NameValueSet *extensions,
+ Secure_Channel *channel,
+ Buffer *wrapped_challenge,
+ Buffer *key_check,
+ Buffer *plaintext_challenge,
+ char *cuid,
+ char *msn,
+ const char *final_applet_version,
+ char *khex,
+ const char *userid,
+ RA_Status &o_status,
+ CERTCertificate **&certificates,
+ int &o_certNums, char **&tokenTypes);
+
+ int DoPublish(
+ const char *cuid,
+ SECItem *encodedPublicKeyInfo,
+ Buffer *cert,
+ const char *publisher_id,
+ char *applet_version);
+
+ bool ProcessRecovery(AuthParams *login,
+ char *reason,
+ RA_Session *session,
+ char **&origins,
+ char **&ktypes,
+ char *tokenType,
+ PKCS11Obj *pkcs11objx,
+ int pkcs11obj_enable,
+ NameValueSet *extensions,
+ Secure_Channel *channel,
+ Buffer *wrapped_challenge,
+ Buffer *key_check,
+ Buffer *plaintext_challenge,
+ char *cuid,
+ char *msn,
+ const char *final_applet_version,
+ char *khex,
+ const char *userid,
+ RA_Status &o_status,
+ CERTCertificate **&certificates,
+ char *lostTokenCUID,
+ int &o_certNums, char **&tokenTypes, char *origTokenType);
+
+ bool ProcessRenewal(AuthParams *login,
+ RA_Session *session,
+ char **&ktypes,
+ char **&origins,
+ char *tokenType,
+ PKCS11Obj *pkcs11objx,
+ int pkcs11obj_enable,
+ Secure_Channel *channel,
+ const char *cuid,
+ char *msn,
+ const char *final_applet_version,
+ const char *userid,
+ RA_Status &o_status,
+ CERTCertificate **&certificates,
+ int &o_certNums, char **&tokenTypes);
+
+ bool GetCardManagerAppletInfo(
+ RA_Session*,
+ Buffer *,
+ RA_Status&,
+ char*&,
+ char*&,
+ Buffer& );
+
+ bool GetAppletInfo(
+ RA_Session *a_session, /* in */
+ Buffer *a_aid , /* in */
+ BYTE &o_major_version,
+ BYTE &o_minor_version,
+ BYTE &o_app_major_version,
+ BYTE &o_app_minor_version);
+
+ bool FormatAppletVersionInfo(
+ RA_Session *a_session,
+ const char *a_tokenType,
+ char *a_cuid,
+ BYTE a_app_major_version,
+ BYTE a_app_minor_version,
+ RA_Status &status, // out
+ char * &o_appletVersion // out
+ );
+
+ bool RequestUserId(
+ RA_Session * a_session,
+ NameValueSet *extensions,
+ const char * a_configname,
+ const char * a_tokenType,
+ char *a_cuid,
+ AuthParams *& o_login, // out
+ const char *&o_userid, // out
+ RA_Status &o_status //out
+ );
+
+
+ bool AuthenticateUser(
+ RA_Session * a_session,
+ const char * a_configname,
+ char *a_cuid,
+ NameValueSet *a_extensions,
+ const char *a_tokenType,
+ AuthParams *& a_login,
+ const char *&o_userid,
+ RA_Status &o_status
+ );
+
+ bool AuthenticateUserLDAP(
+ RA_Session *a_session,
+ NameValueSet *extensions,
+ char *a_cuid,
+ AuthenticationEntry *a_auth,
+ AuthParams *& o_login,
+ RA_Status &o_status,
+ const char *token_type);
+
+ bool CheckAndUpgradeApplet(
+ RA_Session *a_session,
+ NameValueSet *a_extensions,
+ char *a_cuid,
+ const char *a_tokenType,
+ char *&o_current_applet_on_token,
+ BYTE &o_major_version,
+ BYTE &o_minor_version,
+ Buffer *a_aid,
+ const char *msn,
+ const char *userid,
+ RA_Status &o_status,
+ char **key_version );
+
+ bool CheckAndUpgradeSymKeys(
+ RA_Session *session,
+ NameValueSet* extensions,
+ char *cuid,
+ const char *tokenType,
+ char *msn,
+ const char* applet_version,
+ const char* userid,
+ const char* key_version,
+ Buffer *a_cardmanagerAID, /* in */
+ Buffer *a_appletAID, /* in */
+ Secure_Channel *&channel, /* out */
+ RA_Status &status /* out */
+ );
+
+ TPS_PUBLIC RA_Status Process(RA_Session *session, NameValueSet *extensions);
+
+ private:
+ int GetNextFreeCertIdNumber(PKCS11Obj *pkcs11objx);
+ bool isCertRenewable(CERTCertificate *cert, int graceBefore, int graceAfter);
+ int UnrevokeRecoveredCert(const LDAPMessage *e, char *&statusString);
+};
+
+#endif /* RA_ENROLL_PROCESSOR_H */
diff --git a/base/tps/src/include/processor/RA_Format_Processor.h b/base/tps/src/include/processor/RA_Format_Processor.h
new file mode 100644
index 000000000..836c89080
--- /dev/null
+++ b/base/tps/src/include/processor/RA_Format_Processor.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_FORMAT_PROCESSOR_H
+#define RA_FORMAT_PROCESSOR_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "processor/RA_Processor.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Format_Processor : public RA_Processor
+{
+ public:
+ TPS_PUBLIC RA_Format_Processor();
+ TPS_PUBLIC ~RA_Format_Processor();
+ public:
+ TPS_PUBLIC RA_Status Process(RA_Session *session, NameValueSet *extensions);
+};
+
+#endif /* RA_UPGRADE_PROCESSOR_H */
diff --git a/base/tps/src/include/processor/RA_Pin_Reset_Processor.h b/base/tps/src/include/processor/RA_Pin_Reset_Processor.h
new file mode 100644
index 000000000..a3d511865
--- /dev/null
+++ b/base/tps/src/include/processor/RA_Pin_Reset_Processor.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_PIN_RESET_PROCESSOR_H
+#define RA_PIN_RESET_PROCESSOR_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "processor/RA_Processor.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Pin_Reset_Processor : public RA_Processor
+{
+ public:
+ TPS_PUBLIC RA_Pin_Reset_Processor();
+ TPS_PUBLIC ~RA_Pin_Reset_Processor();
+ public:
+ TPS_PUBLIC RA_Status Process(RA_Session *session, NameValueSet *extensions);
+};
+
+#endif /* RA_PIN_RESET_PROCESSOR_H */
diff --git a/base/tps/src/include/processor/RA_Processor.h b/base/tps/src/include/processor/RA_Processor.h
new file mode 100644
index 000000000..74e869a52
--- /dev/null
+++ b/base/tps/src/include/processor/RA_Processor.h
@@ -0,0 +1,214 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_PROCESSOR_H
+#define RA_PROCESSOR_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Login.h"
+#include "main/SecureId.h"
+#include "main/RA_Session.h"
+#include "authentication/AuthParams.h"
+#include "apdu/APDU.h"
+#include "apdu/APDU_Response.h"
+#include "channel/Secure_Channel.h"
+
+enum RA_Status {
+ STATUS_NO_ERROR=0,
+ STATUS_ERROR_SNAC=1,
+ STATUS_ERROR_SEC_INIT_UPDATE=2,
+ STATUS_ERROR_CREATE_CARDMGR=3,
+ STATUS_ERROR_MAC_RESET_PIN_PDU=4,
+ STATUS_ERROR_MAC_CERT_PDU=5,
+ STATUS_ERROR_MAC_LIFESTYLE_PDU=6,
+ STATUS_ERROR_MAC_ENROLL_PDU=7,
+ STATUS_ERROR_READ_OBJECT_PDU=8,
+ STATUS_ERROR_BAD_STATUS=9,
+ STATUS_ERROR_CA_RESPONSE=10,
+ STATUS_ERROR_READ_BUFFER_OVERFLOW=11,
+ STATUS_ERROR_TOKEN_RESET_PIN_FAILED=12,
+ STATUS_ERROR_CONNECTION=13,
+ STATUS_ERROR_LOGIN=14,
+ STATUS_ERROR_DB=15,
+ STATUS_ERROR_TOKEN_DISABLED=16,
+ STATUS_ERROR_SECURE_CHANNEL=17,
+ STATUS_ERROR_MISCONFIGURATION=18,
+ STATUS_ERROR_UPGRADE_APPLET=19,
+ STATUS_ERROR_KEY_CHANGE_OVER=20,
+ STATUS_ERROR_EXTERNAL_AUTH=21,
+ STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND=22,
+ STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND=23,
+ STATUS_ERROR_PUBLISH=24,
+ STATUS_ERROR_LDAP_CONN=25,
+ STATUS_ERROR_DISABLED_TOKEN=26,
+ STATUS_ERROR_NOT_PIN_RESETABLE=27,
+ STATUS_ERROR_CONN_LOST=28,
+ STATUS_ERROR_CREATE_TUS_TOKEN_ENTRY=29,
+ STATUS_ERROR_NO_SUCH_TOKEN_STATE=30,
+ STATUS_ERROR_NO_SUCH_LOST_REASON=31,
+ STATUS_ERROR_UNUSABLE_TOKEN_KEYCOMPROMISE=32,
+ STATUS_ERROR_INACTIVE_TOKEN_NOT_FOUND=33,
+ STATUS_ERROR_HAS_AT_LEAST_ONE_ACTIVE_TOKEN=34,
+ STATUS_ERROR_CONTACT_ADMIN=35,
+ STATUS_ERROR_RECOVERY_IS_PROCESSED=36,
+ STATUS_ERROR_RECOVERY_FAILED=37,
+ STATUS_ERROR_NO_OPERATION_ON_LOST_TOKEN=38,
+ STATUS_ERROR_KEY_ARCHIVE_OFF=39,
+ STATUS_ERROR_NO_TKS_CONNID=40,
+ STATUS_ERROR_UPDATE_TOKENDB_FAILED=41,
+ STATUS_ERROR_REVOKE_CERTIFICATES_FAILED=42,
+ STATUS_ERROR_NOT_TOKEN_OWNER=43,
+ STATUS_ERROR_RENEWAL_IS_PROCESSED=44,
+ STATUS_ERROR_RENEWAL_FAILED=45
+};
+
+class RA_Processor
+{
+ public:
+ RA_Processor();
+ virtual ~RA_Processor();
+ virtual RA_Status Process(RA_Session *session, NameValueSet *extensions);
+ char *MapPattern(NameValueSet *nv, char *pattern);
+
+ int InitializeUpdate(RA_Session *session,
+ BYTE key_version, BYTE key_index,
+ Buffer &key_diversification_data,
+ Buffer &key_info_data,
+ Buffer &card_challenge,
+ Buffer &card_cryptogram,
+ Buffer &host_challenge, const char *connId);
+
+ int CreatePin(RA_Session *session, BYTE pin_number, BYTE max_retries, char *pin);
+
+ int IsPinPresent(RA_Session *session,BYTE pin_number);
+
+ AuthParams *RequestLogin(RA_Session *session, int invalid_pw, int blocked);
+ AuthParams *RequestExtendedLogin(RA_Session *session, int invalid_pw, int blocked, char **parameters, int len, char *title, char *description);
+
+ void StatusUpdate(RA_Session *session, NameValueSet *extensions, int status, const char *info);
+ void StatusUpdate(RA_Session *session, int status, const char *info);
+
+ Buffer *GetAppletVersion(RA_Session *session);
+
+ Secure_Channel *SetupSecureChannel(RA_Session *session, BYTE key_version, BYTE key_index, const char *connId);
+ Secure_Channel *SetupSecureChannel(RA_Session *session,
+ BYTE key_version, BYTE key_index, SecurityLevel security_level, const char *connId);
+
+ SecureId *RequestSecureId(RA_Session *session);
+
+ char *RequestNewPin(RA_Session *session, unsigned int min_len, unsigned int max_len);
+
+ char *RequestASQ(RA_Session *session, char *question);
+
+ int EncryptData(Buffer &cuid, Buffer &versionID, Buffer &in, Buffer &out, const char *connid);
+
+ int ComputeRandomData(Buffer &data_out, int dataSize, const char *connid);
+
+ int CreateKeySetData(
+ Buffer &cuid,
+ Buffer &versionID,
+ Buffer &NewMasterVer,
+ Buffer &out,
+ const char *connid);
+
+ bool GetTokenType(
+ const char *prefix,
+ int major_version, int minor_version,
+ const char *cuid, const char *msn,
+ NameValueSet *extensions,
+ RA_Status &o_status,
+ const char *&o_tokenType);
+
+ Buffer *ListObjects(RA_Session *session, BYTE seq);
+
+ Buffer *GetStatus(RA_Session *session, BYTE p1, BYTE p2);
+
+ Buffer *GetData(RA_Session *session);
+
+ int SelectApplet(RA_Session *session, BYTE p1, BYTE p2, Buffer *aid);
+
+ int UpgradeApplet(
+ RA_Session *session,
+ char *prefix,
+ char *tokenType,
+ BYTE major_version, BYTE minor_version,
+ const char *new_version,
+ const char *applet_dir,
+ SecurityLevel security_level,
+ const char *connid,
+ NameValueSet *extensions,
+ int start_progress, int end_progress,
+ char **key_version);
+
+ int UpgradeKey(RA_Session *session, BYTE major_version, BYTE minor_version, int new_version);
+
+ int SelectCardManager(RA_Session *session, char *prefix, char *tokenType);
+
+ int FormatMuscleApplet(
+ RA_Session *session,
+ unsigned short memSize,
+ Buffer &PIN0, BYTE pin0Tries,
+ Buffer &unblockPIN0, BYTE unblock0Tries,
+ Buffer &PIN1, BYTE pin1Tries,
+ Buffer &unblockPIN1, BYTE unblock1Tries,
+ unsigned short objCreationPermissions,
+ unsigned short keyCreationPermissions,
+ unsigned short pinCreationPermissions);
+
+ Secure_Channel *GenerateSecureChannel(
+ RA_Session *session, const char *connid,
+ Buffer &card_diversification_data,
+ Buffer &card_key_data,
+ Buffer &card_challenge,
+ Buffer &card_cryptogram,
+ Buffer &host_challenge);
+ AuthenticationEntry *GetAuthenticationEntry(
+ const char * a_prefix,
+ const char * a_configname,
+ const char * a_tokenType);
+
+ protected:
+ RA_Status Format(RA_Session *session, NameValueSet *extensions, bool skipAuth);
+ bool RevokeCertificates(RA_Session *session, char *cuid, char *audit_msg,
+ char *final_applet_version,
+ char *keyVersion,
+ char *tokenType, char *userid, RA_Status &status );
+ int IsTokenDisabledByTus(Secure_Channel *channel);
+
+ int totalAvailableMemory;
+ int totalFreeMemory;
+};
+
+#endif /* RA_PROCESSOR_H */
diff --git a/base/tps/src/include/processor/RA_Renew_Processor.h b/base/tps/src/include/processor/RA_Renew_Processor.h
new file mode 100644
index 000000000..bb8710a74
--- /dev/null
+++ b/base/tps/src/include/processor/RA_Renew_Processor.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_RENEW_PROCESSOR_H
+#define RA_RENEW_PROCESSOR_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "processor/RA_Processor.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Renew_Processor : public RA_Processor
+{
+ public:
+ TPS_PUBLIC RA_Renew_Processor();
+ TPS_PUBLIC ~RA_Renew_Processor();
+ public:
+ TPS_PUBLIC RA_Status Process(RA_Session *session, NameValueSet *extensions);
+};
+
+#endif /* RA_RENEW_PROCESSOR_H */
diff --git a/base/tps/src/include/processor/RA_Unblock_Processor.h b/base/tps/src/include/processor/RA_Unblock_Processor.h
new file mode 100644
index 000000000..ae28ea593
--- /dev/null
+++ b/base/tps/src/include/processor/RA_Unblock_Processor.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_UNBLOCK_PROCESSOR_H
+#define RA_UNBLOCK_PROCESSOR_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "processor/RA_Processor.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Unblock_Processor : public RA_Processor
+{
+ public:
+ TPS_PUBLIC RA_Unblock_Processor();
+ TPS_PUBLIC ~RA_Unblock_Processor();
+ public:
+ TPS_PUBLIC RA_Status Process(RA_Session *session, NameValueSet *extensions);
+};
+
+#endif /* RA_UNBLOCK_PROCESSOR_H */
diff --git a/base/tps/src/include/publisher/IConnector.h b/base/tps/src/include/publisher/IConnector.h
new file mode 100644
index 000000000..9a5caa70e
--- /dev/null
+++ b/base/tps/src/include/publisher/IConnector.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef __ICONNECTOR_H__
+#define __ICONNECTOR_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#if !defined (I_CONNECTOR_H)
+#define I_CONNECTOR_H
+
+#include "IPublish_Data.h"
+class IConnector
+{
+public:
+
+ virtual ~IConnector() {};
+ virtual int init() = 0;
+ virtual void shutdown() = 0;
+ virtual int send_msg(IPublish_Data *data) =0;
+
+};
+
+#endif
+
+#endif /* __ICONNECTOR_H__ */
+
diff --git a/base/tps/src/include/publisher/IPublish_Data.h b/base/tps/src/include/publisher/IPublish_Data.h
new file mode 100644
index 000000000..50b7e3247
--- /dev/null
+++ b/base/tps/src/include/publisher/IPublish_Data.h
@@ -0,0 +1,56 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef __IPUBLISH_DATA_H__
+#define __IPUBLISH_DATA_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#if !defined (IPUBLISH_DATA_H)
+#define IPUBLISH_DATA_H
+
+
+
+class IPublish_Data
+{
+public:
+
+ virtual void Reset() = 0;
+
+};
+
+#endif
+
+#endif /* __IPUBLISH_DATA_H__ */
+
diff --git a/base/tps/src/include/publisher/IPublisher.h b/base/tps/src/include/publisher/IPublisher.h
new file mode 100644
index 000000000..56a1b7357
--- /dev/null
+++ b/base/tps/src/include/publisher/IPublisher.h
@@ -0,0 +1,74 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef __IPUBLISHER_H__
+#define __IPUBLISHER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#if !defined (IPUBLISHER_H)
+
+#define IPUBLISHER_H
+
+#include "IConnector.h"
+
+class IPublisher
+{
+
+public:
+
+ virtual ~IPublisher() {
+ if( m_connector != NULL ) {
+ delete m_connector;
+ m_connector = NULL;
+ }
+ };
+ virtual int init(void) = 0;
+
+ virtual int publish(unsigned char *cuid, int cuid_len,long key_type,unsigned char * public_key,int public_key_len,
+ unsigned long cert_activate_date,unsigned long cert_expire_date,unsigned long applet_version,unsigned long applet_version_date)= 0;
+
+ IConnector *getConnector() { return m_connector;}
+
+protected:
+
+ IConnector * m_connector;
+
+
+};
+
+#endif
+
+#endif /* __IPUBLISHER_H__ */
+
diff --git a/base/tps/src/include/publisher/NetkeyPublisher.h b/base/tps/src/include/publisher/NetkeyPublisher.h
new file mode 100644
index 000000000..05cf4d191
--- /dev/null
+++ b/base/tps/src/include/publisher/NetkeyPublisher.h
@@ -0,0 +1,74 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef __NETKEY_PUBLISHER_H__
+#define __NETKEY_PUBLISHER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#if !defined (NETKEY_PUBLISHER_H)
+#define NETKEY_PUBLISHER_H
+
+#include "IPublisher.h"
+class IPublisher;
+class NetkeyPublisher : public IPublisher
+{
+
+public:
+
+
+ NetkeyPublisher();
+ ~NetkeyPublisher();
+
+ int init(void) ;
+
+ int publish(unsigned char *cuid, int cuid_len,long key_type,unsigned char * public_key,int public_key_len,
+ unsigned long cert_activate_date,unsigned long cert_expire_date,unsigned long applet_version,unsigned long applet_version_date);
+
+
+ static pthread_mutex_t mutex;
+
+
+};
+
+extern "C"
+{
+ IPublisher *GetIPublisher();
+
+};
+
+#endif
+
+#endif /* __NETKEY_PUBLISHER_H__ */
+
diff --git a/base/tps/src/include/selftests/SelfTest.h b/base/tps/src/include/selftests/SelfTest.h
new file mode 100644
index 000000000..c52f62f23
--- /dev/null
+++ b/base/tps/src/include/selftests/SelfTest.h
@@ -0,0 +1,74 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifndef SELFTEST_H
+#define SELFTEST_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#include "main/ConfigStore.h"
+
+
+class SelfTest
+{
+ public:
+ SelfTest();
+ ~SelfTest();
+ static void Initialize (ConfigStore *cfg);
+ static int runStartUpSelfTests (const char *nickname); /* per cert */
+ static int runStartUpSelfTests (); /* general */
+ static int runOnDemandSelfTests ();
+ static int isOnDemandEnabled ();
+ static int isOnDemandCritical ();
+
+ static const int nTests;
+ static const char *TEST_NAMES[];
+
+ protected:
+ static const char *CFG_SELFTEST_STARTUP;
+ static const char *CFG_SELFTEST_ONDEMAND;
+
+ private:
+ static int isInitialized;
+ static int StartupSystemCertsVerificationRun;
+};
+
+#endif
diff --git a/base/tps/src/include/selftests/TPSPresence.h b/base/tps/src/include/selftests/TPSPresence.h
new file mode 100644
index 000000000..114f4ae57
--- /dev/null
+++ b/base/tps/src/include/selftests/TPSPresence.h
@@ -0,0 +1,78 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifndef TPSPRESENCE_H
+#define TPSPRESENCE_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#include "main/ConfigStore.h"
+#include "selftests/SelfTest.h"
+
+class TPSPresence : public SelfTest
+{
+
+ public:
+ TPSPresence();
+ ~TPSPresence();
+ static void Initialize (ConfigStore *cfg);
+ static int runSelfTest ();
+ static int runSelfTest (const char *nick_name);
+ static int runSelfTest (const char *nick_name, CERTCertificate **cert);
+ static bool isStartupEnabled ();
+ static bool isOnDemandEnabled ();
+ static bool isStartupCritical ();
+ static bool isOnDemandCritical ();
+ static const char *TEST_NAME;
+
+ private:
+ static bool startupEnabled;
+ static bool onDemandEnabled;
+ static bool startupCritical;
+ static bool onDemandCritical;
+ static int initialized;
+ static char *nickname;
+ static const char *UNINITIALIZED_NICKNAME;
+ static const char *NICKNAME_NAME;
+ static const char *CRITICAL_TEST_NAME;
+};
+
+#endif
diff --git a/base/tps/src/include/selftests/TPSSystemCertsVerification.h b/base/tps/src/include/selftests/TPSSystemCertsVerification.h
new file mode 100644
index 000000000..40a4d3fd4
--- /dev/null
+++ b/base/tps/src/include/selftests/TPSSystemCertsVerification.h
@@ -0,0 +1,76 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifndef TPSSYSTEMCERTSVERIFICATION_H
+#define TPSSYSTEMCERTSVERIFICATION_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+// #include "main/Util.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#include "main/ConfigStore.h"
+#include "selftests/SelfTest.h"
+
+class TPSSystemCertsVerification : public SelfTest
+{
+
+ public:
+ TPSSystemCertsVerification();
+ ~TPSSystemCertsVerification();
+ static void Initialize (ConfigStore *cfg);
+ static int runSelfTest ();
+ static bool isStartupEnabled ();
+ static bool isOnDemandEnabled ();
+ static bool isStartupCritical ();
+ static bool isOnDemandCritical ();
+ static const char *TEST_NAME;
+
+ private:
+ static bool startupEnabled;
+ static bool onDemandEnabled;
+ static bool startupCritical;
+ static bool onDemandCritical;
+ static int initialized;
+ static const char *CRITICAL_TEST_NAME;
+ static const char *UNINITIALIZED_NICKNAME;
+ static const char *SUBSYSTEM_NICKNAME;
+};
+
+#endif
diff --git a/base/tps/src/include/selftests/TPSValidity.h b/base/tps/src/include/selftests/TPSValidity.h
new file mode 100644
index 000000000..548052a83
--- /dev/null
+++ b/base/tps/src/include/selftests/TPSValidity.h
@@ -0,0 +1,79 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifndef TPSVALIDITY_H
+#define TPSVALIDITY_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+// #include "main/Util.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#include "main/ConfigStore.h"
+#include "selftests/SelfTest.h"
+
+class TPSValidity : public SelfTest
+{
+
+ public:
+ TPSValidity();
+ ~TPSValidity();
+ static void Initialize (ConfigStore *cfg);
+ static int runSelfTest ();
+ static int runSelfTest (const char *nick_name);
+ static int runSelfTest (const char *nick_name, CERTCertificate *cert);
+ static bool isStartupEnabled ();
+ static bool isOnDemandEnabled ();
+ static bool isStartupCritical ();
+ static bool isOnDemandCritical ();
+ static const char *TEST_NAME;
+
+ private:
+ static bool startupEnabled;
+ static bool onDemandEnabled;
+ static bool startupCritical;
+ static bool onDemandCritical;
+ static int initialized;
+ static char *nickname;
+ static const char *UNINITIALIZED_NICKNAME;
+ static const char *NICKNAME_NAME;
+ static const char *CRITICAL_TEST_NAME;
+};
+
+#endif
diff --git a/base/tps/src/include/service/NK_Context.h b/base/tps/src/include/service/NK_Context.h
new file mode 100644
index 000000000..e5ed59992
--- /dev/null
+++ b/base/tps/src/include/service/NK_Context.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef NK_CONTEXT_H
+#define NK_CONTEXT_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Context.h"
+
+class NK_Context : public RA_Context
+{
+ public:
+ NK_Context(pblock *pb, Session *sn, Request *rq);
+ virtual ~NK_Context();
+ public:
+ virtual void LogError(const char *func, int line, const char *fmt,...);
+ virtual void LogInfo(const char *func, int line, const char *fmt,...);
+ virtual void InitializationError(const char *func, int line);
+ private:
+ pblock *m_pb;
+ Session *m_sn;
+ Request *m_rq;
+};
+
+#endif /* NK_CONTEXT_H */
diff --git a/base/tps/src/include/service/NK_Session.h b/base/tps/src/include/service/NK_Session.h
new file mode 100644
index 000000000..55cd19439
--- /dev/null
+++ b/base/tps/src/include/service/NK_Session.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef NK_SESSION_H
+#define NK_SESSION_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Session.h"
+
+class NK_Session : public RA_Session
+{
+ public:
+ NK_Session(pblock *pb, Session *sn, Request *rq);
+ virtual ~NK_Session();
+ public:
+ virtual char *GetRemoteIP();
+ virtual RA_pblock *create_pblock( char *data );
+ virtual RA_Msg *ReadMsg();
+ virtual void WriteMsg(RA_Msg *msg);
+ private:
+ pblock *m_pb;
+ Session *m_sn;
+ Request *m_rq;
+};
+
+#endif /* NK_SESSION_H */
diff --git a/base/tps/src/include/tus/tus_db.h b/base/tps/src/include/tus/tus_db.h
new file mode 100644
index 000000000..b1c7ebe86
--- /dev/null
+++ b/base/tps/src/include/tus/tus_db.h
@@ -0,0 +1,273 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef TUS_DB_H
+#define TUS_DB_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#include "ldap.h"
+#include "lber.h"
+#include "pk11func.h"
+#include "cryptohi.h"
+#include "keyhi.h"
+#include "base64.h"
+#include "nssb64.h"
+#include "prlock.h"
+
+#define I_TOKEN_ID 0
+#define TOKEN_ID "cn"
+#define I_TOKEN_USER 1
+#define TOKEN_USER "tokenUserID"
+#define I_TOKEN_STATUS 2
+#define TOKEN_STATUS "tokenStatus"
+#define I_TOKEN_APPLET 3
+#define TOKEN_APPLET "tokenAppletID"
+#define I_TOKEN_KEY_INFO 4
+#define TOKEN_KEY_INFO "keyInfo"
+#define I_TOKEN_MODS 5
+#define TOKEN_MODS "modified"
+#define I_TOKEN_C_DATE 6
+#define TOKEN_C_DATE "dateOfCreate"
+#define I_TOKEN_M_DATE 7
+#define TOKEN_M_DATE "dateOfModify"
+#define I_TOKEN_RESETS 8
+#define TOKEN_RESETS "numberOfResets"
+#define I_TOKEN_ENROLLMENTS 9
+#define TOKEN_ENROLLMENTS "numberOfEnrollments"
+#define I_TOKEN_RENEWALS 10
+#define TOKEN_RENEWALS "numberOfRenewals"
+#define I_TOKEN_RECOVERIES 11
+#define TOKEN_RECOVERIES "numberOfRecoveries"
+#define I_TOKEN_POLICY 12
+#define TOKEN_POLICY "tokenPolicy"
+
+#define I_TOKEN_CUID 13
+#define TOKEN_CUID "tokenID"
+#define I_TOKEN_OP 14
+#define TOKEN_OP "tokenOp"
+#define I_TOKEN_MSG 15
+#define TOKEN_MSG "tokenMsg"
+#define I_TOKEN_RESULT 16
+#define TOKEN_RESULT "tokenResult"
+#define I_TOKEN_IP 17
+#define TOKEN_IP "tokenIP"
+#define I_TOKEN_CERT 18
+#define TOKEN_CERT "userCertificate"
+#define I_TOKEN_SUBJECT 19
+#define TOKEN_SUBJECT "tokenSubject"
+#define I_TOKEN_ISSUER 20
+#define TOKEN_ISSUER "tokenIssuer"
+#define I_TOKEN_ORIGIN 21
+#define TOKEN_ORIGIN "tokenOrigin"
+#define I_TOKEN_SERIAL 22
+#define TOKEN_SERIAL "tokenSerial"
+#define I_TOKEN_TYPE 23
+#define TOKEN_TYPE "tokenType"
+#define I_TOKEN_KEY_TYPE 24
+#define TOKEN_KEY_TYPE "tokenKeyType"
+#define I_TOKEN_REASON 13
+#define TOKEN_REASON "tokenReason"
+#define I_TOKEN_NOT_BEFORE 26
+#define TOKEN_NOT_BEFORE "tokenNotBefore"
+#define I_TOKEN_NOT_AFTER 27
+#define TOKEN_NOT_AFTER "tokenNotAfter"
+
+#define I_STATE_UNINITIALIZED 0
+#define STATE_UNINITIALIZED "uninitialized"
+#define I_STATE_ACTIVE 1
+#define STATE_ACTIVE "active"
+#define I_STATE_DISABLED 2
+#define STATE_DISABLED "disabled"
+#define I_STATE_LOST 3
+#define STATE_LOST "lost"
+
+#define C_TIME "createTimeStamp"
+#define M_TIME "modifyTimeStamp"
+#define USER_ID "uid"
+#define USER_PASSWORD "userPassword"
+#define USER_SN "sn"
+#define USER_CN "cn"
+#define USER_GIVENNAME "givenName"
+#define USER_CERT "userCertificate"
+#define PROFILE_ID "profileID"
+#define GROUP_MEMBER "member"
+#define SUBGROUP_ID "cn"
+
+/* roles */
+#define OPERATOR "Operators"
+#define AGENT "Agents"
+#define ADMINISTRATOR "Administrators"
+#define MAX_RETRIES 2
+
+#define ALL_PROFILES "All Profiles"
+#define NO_PROFILES "NO_PROFILES"
+#define NO_TOKEN_TYPE "no_token_type"
+
+TPS_PUBLIC void set_tus_db_port(int number);
+TPS_PUBLIC void set_tus_db_host(char *name);
+TPS_PUBLIC void set_tus_db_baseDN(char *dn);
+TPS_PUBLIC void set_tus_db_bindDN(char *dn);
+TPS_PUBLIC void set_tus_db_bindPass(char *p);
+
+TPS_PUBLIC int is_tus_db_initialized();
+TPS_PUBLIC int get_tus_db_config(char *name);
+TPS_PUBLIC int tus_db_init(char **errorMsg);
+TPS_PUBLIC int allow_token_reenroll(char *cn);
+TPS_PUBLIC int allow_token_renew(char *cn);
+TPS_PUBLIC int force_token_format(char *cn);
+TPS_PUBLIC int is_token_pin_resetable(char *cn);
+TPS_PUBLIC int is_update_pin_resetable_policy(char *cn);
+TPS_PUBLIC int is_token_present(char *cn);
+TPS_PUBLIC int update_token_policy (char *cn, char *policy);
+TPS_PUBLIC char *get_token_policy (char *cn);
+TPS_PUBLIC char *get_token_userid(char *cn);
+TPS_PUBLIC void tus_db_end();
+TPS_PUBLIC void tus_db_cleanup();
+TPS_PUBLIC void tus_print_as_hex(char *out, SECItem *data);
+TPS_PUBLIC void tus_print_integer(char *out, SECItem *data);
+TPS_PUBLIC int is_tus_db_entry_disabled(char *cn);
+TPS_PUBLIC int add_default_tus_db_entry (const char *uid, const char *agentid, char *cn, const char *status, char *applet_version, char *key_info, const char *token_type );
+TPS_PUBLIC int delete_tus_db_entry (char *userid, char *cn);
+TPS_PUBLIC int delete_tus_general_db_entry (char *dn);
+TPS_PUBLIC int find_tus_db_entry (char *cn, int max, LDAPMessage **result);
+TPS_PUBLIC int find_tus_db_entries (const char *filter, int max, LDAPMessage **result);
+TPS_PUBLIC int find_tus_db_entries_pcontrol_1 (const char *filter, int max, int time_limit, int size_limit, LDAPMessage **result);
+TPS_PUBLIC int find_tus_token_entries (char *filter, int max, LDAPMessage **result, int order);
+TPS_PUBLIC int find_tus_token_entries_no_vlv (char *filter, LDAPMessage **result, int order);
+TPS_PUBLIC int tus_has_active_tokens(char *userid);
+TPS_PUBLIC char *get_token_reason(LDAPMessage *e);
+
+TPS_PUBLIC int update_tus_db_entry (const char *agentid,
+ char *cn, const char *uid, char *keyInfo,
+ const char *status,
+ char *applet_version, const char *reason, const char* token_type);
+TPS_PUBLIC int update_tus_db_entry_with_mods (const char *agentid, const char *cn, LDAPMod **mods);
+TPS_PUBLIC int check_and_modify_tus_db_entry (char *userid, char *cn, char *check, LDAPMod **mods);
+TPS_PUBLIC int modify_tus_db_entry (char *userid, char *cn, LDAPMod **mods);
+TPS_PUBLIC int add_activity (const char *ip, const char *id, const char *op, const char *result, const char *msg, const char *userid, const char *token_type);
+TPS_PUBLIC int find_tus_certificate_entries_by_order_no_vlv (char *filter,
+ LDAPMessage **result, int order);
+TPS_PUBLIC int find_tus_certificate_entries_by_order (char *filter, int max,
+ LDAPMessage **result, int order);
+TPS_PUBLIC int add_certificate (char *tokenid, char *origin, char *tokenType, char *userid, CERTCertificate *certificate, char *ktype, const char *status);
+TPS_PUBLIC int add_tus_db_entry (char *cn, LDAPMod **mods);
+TPS_PUBLIC int add_new_tus_db_entry (const char *userid, char *cn, const char *uid, int flag, const char *status, char *applet_version, char *key_info, const char *token_type);
+TPS_PUBLIC int find_tus_activity_entries (char *filter, int max, LDAPMessage **result);
+TPS_PUBLIC int find_tus_activity_entries_pcontrol_1 (char *filter, int max, int time_limit, int size_limit, LDAPMessage **result);
+TPS_PUBLIC int find_tus_activity_entries_no_vlv (char *filter, LDAPMessage **result, int order);
+TPS_PUBLIC int get_number_of_entries (LDAPMessage *result);
+TPS_PUBLIC int free_results (LDAPMessage *results);
+
+TPS_PUBLIC LDAPMessage *get_first_entry (LDAPMessage *result);
+TPS_PUBLIC LDAPMessage *get_next_entry (LDAPMessage *entry);
+TPS_PUBLIC CERTCertificate **get_certificates(LDAPMessage *entry);
+
+TPS_PUBLIC char **get_token_states();
+TPS_PUBLIC char **get_token_attributes();
+TPS_PUBLIC char **get_activity_attributes();
+TPS_PUBLIC char **get_user_attributes();
+TPS_PUBLIC char **get_view_user_attributes();
+TPS_PUBLIC struct berval **get_attribute_values(LDAPMessage *entry, const char *attribute);
+TPS_PUBLIC void free_values(struct berval **values, int ldapValues);
+TPS_PUBLIC struct berval **get_token_users(LDAPMessage *entry);
+TPS_PUBLIC char *get_token_id(LDAPMessage *entry);
+TPS_PUBLIC char *get_cert_tokenType(LDAPMessage *entry);
+TPS_PUBLIC char *get_token_status(LDAPMessage *entry);
+TPS_PUBLIC char *get_cert_cn(LDAPMessage *entry);
+TPS_PUBLIC char *get_cert_status(LDAPMessage *entry);
+TPS_PUBLIC char *get_cert_type(LDAPMessage *entry);
+TPS_PUBLIC char *get_cert_serial(LDAPMessage *entry);
+TPS_PUBLIC char *get_cert_issuer(LDAPMessage *entry);
+TPS_PUBLIC char *get_cert_attr_byname(LDAPMessage *entry, const char *name);
+TPS_PUBLIC char *get_applet_id(LDAPMessage *entry);
+TPS_PUBLIC char *get_key_info(LDAPMessage *entry);
+TPS_PUBLIC char *get_creation_date(LDAPMessage *entry);
+TPS_PUBLIC char *get_modification_date(LDAPMessage *entry);
+TPS_PUBLIC char *get_policy_name();
+TPS_PUBLIC char *get_reason_name();
+int find_tus_certificate_entries (char *filter, int max, LDAPMessage **result);
+TPS_PUBLIC char **get_certificate_attributes();
+
+TPS_PUBLIC int get_number_of_modifications(LDAPMessage *entry);
+TPS_PUBLIC int get_number_of_resets(LDAPMessage *entry);
+TPS_PUBLIC int get_number_of_enrollments(LDAPMessage *entry);
+TPS_PUBLIC int get_number_of_renewals(LDAPMessage *entry);
+TPS_PUBLIC int get_number_of_recoveries(LDAPMessage *entry);
+
+TPS_PUBLIC char *get_token_users_name();
+TPS_PUBLIC char *get_token_id_name();
+TPS_PUBLIC char *get_token_status_name();
+TPS_PUBLIC char *get_applet_id_name();
+TPS_PUBLIC char *get_key_info_name();
+TPS_PUBLIC char *get_creation_date_name();
+TPS_PUBLIC char *get_modification_date_name();
+TPS_PUBLIC char *get_number_of_modifications_name();
+TPS_PUBLIC char *get_number_of_resets_name();
+TPS_PUBLIC char *get_number_of_enrollments_name();
+TPS_PUBLIC char *get_number_of_renewals_name();
+TPS_PUBLIC char *get_number_of_recoveries_name();
+TPS_PUBLIC char *get_dn(LDAPMessage *entry);
+
+TPS_PUBLIC LDAPMod **allocate_modifications(int size);
+TPS_PUBLIC void free_modifications(LDAPMod **mods, int ldapValues);
+TPS_PUBLIC char **allocate_values(int size, int extra);
+TPS_PUBLIC char **create_modification_date_change();
+TPS_PUBLIC int base64_decode(char *src, unsigned char *dst);
+TPS_PUBLIC char *tus_authenticate(char *cert);
+TPS_PUBLIC int tus_authorize(const char *group, const char *userid);
+TPS_PUBLIC int update_cert_status(char *cn, const char *status);
+TPS_PUBLIC int update_token_status_reason(char *userid, char *cuid,
+ const char *tokenStatus, const char *reason);
+TPS_PUBLIC int update_token_status_reason_userid(const char *userid, char *cuid,
+ const char *tokenStatus, const char *reason, int modifyDateOfCreate);
+
+TPS_PUBLIC int add_user_db_entry(const char *agentid, char *userid, char *userPassword, char *sn, char *givenName, char *cn, char * userCert);
+TPS_PUBLIC int find_tus_user_entries_no_vlv(char *filter, LDAPMessage **result, int order);
+TPS_PUBLIC int update_user_db_entry(const char *agentid, char *uid, char *lastName, char *givenName, char *userCN, char *userCert);
+TPS_PUBLIC int add_profile_to_user(const char *agentid, char *userid, const char *profile);
+TPS_PUBLIC int delete_profile_from_user(const char *agentid, char *userid, const char *profile);
+TPS_PUBLIC int add_user_to_role_db_entry(const char *agentid, char *userid, const char *role);
+TPS_PUBLIC int delete_user_from_role_db_entry(const char *agentid, char *userid, const char *role);
+TPS_PUBLIC int find_tus_user_role_entries( const char*uid, LDAPMessage **result);
+TPS_PUBLIC char *get_authorized_profiles(const char *userid, int is_admin);
+TPS_PUBLIC int delete_user_db_entry(const char *agentid, char *uid);
+TPS_PUBLIC int delete_all_profiles_from_user(const char *agentid, char *userid);
+#endif /* TUS_DB_H */
diff --git a/base/tps/src/main/AttributeSpec.cpp b/base/tps/src/main/AttributeSpec.cpp
new file mode 100644
index 000000000..23c2cd978
--- /dev/null
+++ b/base/tps/src/main/AttributeSpec.cpp
@@ -0,0 +1,115 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <string.h>
+#include "prmem.h"
+#include "pk11func.h"
+#include "main/Buffer.h"
+#include "main/AttributeSpec.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+AttributeSpec::AttributeSpec ()
+{
+}
+
+AttributeSpec::~AttributeSpec ()
+{
+}
+
+AttributeSpec *AttributeSpec::Parse(Buffer *b, int offset)
+{
+ AttributeSpec *o = new AttributeSpec();
+ unsigned long id = (((unsigned char *)*b)[offset+0] << 24) +
+ (((unsigned char *)*b)[offset+1] << 16) +
+ (((unsigned char *)*b)[offset+2] << 8) +
+ (((unsigned char *)*b)[offset+3]);
+ o->SetAttributeID(id);
+ // The following line generates the following known benign warning
+ // message on Windows platforms:
+ //
+ // AttributeSpec.cpp(40) : warning C4244: 'argument' : conversion
+ // from 'unsigned long' to 'unsigned char', possible loss of data
+ //
+ o->SetType((unsigned long)(((unsigned char *)*b)[offset+4]));
+ // DatatypeString contains two bytes for AttributeLen of AttributeData
+ Buffer data;
+ if (o->GetType() == (BYTE) 0)
+ data = b->substr(offset+5+2, b->size() - 5-2);
+ else
+ data = b->substr(offset+5, b->size() - 5);
+
+ o->SetData(data);
+ return o;
+}
+
+void AttributeSpec::SetAttributeID(unsigned long v)
+{
+ m_id = v;
+}
+
+unsigned long AttributeSpec::GetAttributeID()
+{
+ return m_id;
+}
+
+void AttributeSpec::SetType(BYTE v)
+{
+ m_type = v;
+}
+
+BYTE AttributeSpec::GetType()
+{
+ return m_type;
+}
+
+// sets AttributeData (for string type, contains AttributeLen+AttributeValue)
+void AttributeSpec::SetData(Buffer data)
+{
+ m_data = data;
+}
+
+// gets AttributeData
+Buffer AttributeSpec::GetValue()
+{
+ return m_data;
+}
+
+// gets AttributeSpec
+Buffer AttributeSpec::GetData()
+{
+ Buffer data = Buffer();
+ data += Buffer(1, (BYTE)(m_id >> 24) & 0xff);
+ data += Buffer(1, (BYTE)(m_id >> 16) & 0xff);
+ data += Buffer(1, (BYTE)(m_id >> 8) & 0xff);
+ data += Buffer(1, (BYTE)m_id & 0xff);
+ data += Buffer(1, m_type);
+ if (m_type == 0) { /* String */
+ data += Buffer(1, (m_data.size() >> 8) & 0xff);
+ data += Buffer(1, m_data.size() & 0xff);
+ }
+ data += m_data;
+ return data;
+}
+
diff --git a/base/tps/src/main/AuthParams.cpp b/base/tps/src/main/AuthParams.cpp
new file mode 100644
index 000000000..3a124252e
--- /dev/null
+++ b/base/tps/src/main/AuthParams.cpp
@@ -0,0 +1,72 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "authentication/AuthParams.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+TPS_PUBLIC AuthParams::AuthParams () {
+}
+
+/**
+ * Destructs processor.
+ */
+AuthParams::~AuthParams () {
+}
+
+TPS_PUBLIC void AuthParams::SetUID(char *uid) {
+ Add("UID", uid);
+}
+
+TPS_PUBLIC char *AuthParams::GetUID() {
+ return GetValue("UID");
+}
+
+TPS_PUBLIC void AuthParams::SetPassword(char *pwd) {
+ Add("PASSWORD", pwd);
+}
+
+TPS_PUBLIC char *AuthParams::GetPassword() {
+ return GetValue("PASSWORD");
+}
+
+void AuthParams::SetSecuridValue(char *securidValue) {
+ Add("SECURID_VALUE", securidValue);
+}
+
+TPS_PUBLIC char *AuthParams::GetSecuridValue() {
+ return GetValue("SECURID_VALUE");
+}
+
+void AuthParams::SetSecuridPin(char *securidPin) {
+ Add("SECURID_PIN", securidPin);
+}
+
+TPS_PUBLIC char *AuthParams::GetSecuridPin() {
+ return GetValue("SECURID_PIN");
+}
+
diff --git a/base/tps/src/main/Authentication.cpp b/base/tps/src/main/Authentication.cpp
new file mode 100644
index 000000000..34ab76f0a
--- /dev/null
+++ b/base/tps/src/main/Authentication.cpp
@@ -0,0 +1,105 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "main/RA_Session.h"
+#include "main/Login.h"
+#include "main/SecureId.h"
+#include "main/Util.h"
+#include "main/Memory.h"
+#include "authentication/Authentication.h"
+#include "authentication/AuthParams.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a base authentication
+ */
+TPS_PUBLIC Authentication::Authentication ()
+{
+}
+
+/**
+ * Destructs processor.
+ */
+TPS_PUBLIC Authentication::~Authentication ()
+{
+}
+
+void Authentication::Initialize(int index)
+{
+}
+
+int Authentication::Authenticate(AuthParams *params)
+{
+ return -1;
+}
+
+int Authentication::GetNumOfRetries() {
+ return m_retries;
+}
+
+const char *Authentication::GetTitle(char *locale)
+{
+ return NULL;
+}
+
+const char *Authentication::GetDescription(char *locale)
+{
+ return NULL;
+}
+
+int Authentication::GetNumOfParamNames()
+{
+ return 0;
+}
+
+char *Authentication::GetParamID(int index)
+{
+ return NULL;
+}
+
+const char *Authentication::GetParamName(int index, char *locale)
+{
+ return NULL;
+}
+
+char *Authentication::GetParamType(int index)
+{
+ return NULL;
+}
+
+const char *Authentication::GetParamDescription(int index, char *locale)
+{
+ return NULL;
+}
+
+char *Authentication::GetParamOption(int index)
+{
+ return NULL;
+}
+
diff --git a/base/tps/src/main/AuthenticationEntry.cpp b/base/tps/src/main/AuthenticationEntry.cpp
new file mode 100644
index 000000000..eb7f75419
--- /dev/null
+++ b/base/tps/src/main/AuthenticationEntry.cpp
@@ -0,0 +1,91 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "plstr.h"
+#include "main/AuthenticationEntry.h"
+
+/**
+ * Constructs a base authentication
+ */
+AuthenticationEntry::AuthenticationEntry ()
+{
+ m_lib = NULL;
+ m_Id = NULL;
+ m_type = NULL;
+ m_authentication = NULL;
+}
+
+/**
+ * Destructs processor.
+ */
+AuthenticationEntry::~AuthenticationEntry ()
+{
+ if (m_lib != NULL) {
+ PR_UnloadLibrary(m_lib);
+ m_lib = NULL;
+ }
+
+ if( m_Id != NULL ) {
+ PL_strfree( m_Id );
+ m_Id = NULL;
+ }
+
+ if( m_type != NULL ) {
+ PL_strfree( m_type );
+ m_type = NULL;
+ }
+
+ m_authentication = NULL;
+}
+
+void AuthenticationEntry::SetLibrary(PRLibrary* lib) {
+ m_lib = lib;
+}
+
+PRLibrary *AuthenticationEntry::GetLibrary() {
+ return m_lib;
+}
+
+void AuthenticationEntry::SetId(const char *id) {
+ m_Id = PL_strdup(id);
+}
+
+char *AuthenticationEntry::GetId() {
+ return m_Id;
+}
+
+void AuthenticationEntry::SetAuthentication(Authentication *auth) {
+ m_authentication = auth;
+}
+
+Authentication *AuthenticationEntry::GetAuthentication() {
+ return m_authentication;
+}
+
+void AuthenticationEntry::SetType(const char *type) {
+ m_type = PL_strdup(type);
+}
+
+char *AuthenticationEntry::GetType() {
+ return m_type;
+}
diff --git a/base/tps/src/main/Buffer.cpp b/base/tps/src/main/Buffer.cpp
new file mode 100644
index 000000000..2a547feea
--- /dev/null
+++ b/base/tps/src/main/Buffer.cpp
@@ -0,0 +1,243 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <memory.h>
+#include <assert.h>
+#include <stdio.h>
+
+#include "main/Buffer.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+TPS_PUBLIC Buffer::Buffer(const BYTE *buf_, unsigned int len_) : len(len_), res(len_)
+{
+ buf = new BYTE[len];
+ memcpy(buf, buf_, len);
+}
+
+TPS_PUBLIC Buffer::Buffer(const Buffer& cpy)
+{
+ buf = 0;
+ *this = cpy;
+}
+
+TPS_PUBLIC Buffer::Buffer(unsigned int len_) : len(len_), res(len_)
+{
+ buf = new BYTE[res];
+ memset(buf, 0, len_);
+}
+
+TPS_PUBLIC Buffer::Buffer(unsigned int len_, BYTE b) : len(len_), res(len_)
+{
+ if (len_ == 0) {
+ buf = NULL;
+ } else {
+ buf = new BYTE[res];
+ memset(buf, b, len);
+ }
+}
+
+TPS_PUBLIC Buffer::~Buffer()
+{
+ if( buf != NULL ) {
+ delete [] buf;
+ buf = NULL;
+ }
+}
+
+TPS_PUBLIC bool
+Buffer::operator==(const Buffer& cmp) const
+{
+ if( len != cmp.len ) return false;
+ for( unsigned int i=0; i < len; ++i ) {
+ if( buf[i] != cmp.buf[i] ) {
+ return false;
+ }
+ }
+ return true;
+}
+
+TPS_PUBLIC Buffer&
+Buffer::operator=(const Buffer& cpy)
+{
+ if( this == &cpy ) return *this;
+ len = cpy.len;
+ if( buf != NULL ) {
+ delete [] buf;
+ buf = NULL;
+ }
+ if (cpy.len == 0) {
+ buf = NULL;
+ } else {
+ buf = new BYTE[len];
+ memcpy(buf, cpy.buf, len);
+ }
+ res = len;
+
+ return *this;
+}
+
+TPS_PUBLIC void
+Buffer::zeroize()
+{
+ if( len > 0 ) {
+ memset( buf, 0, len );
+ }
+}
+
+TPS_PUBLIC Buffer
+Buffer::operator+(const Buffer& addend) const
+{
+ Buffer result(len + addend.len);
+ memcpy(result.buf, buf, len);
+ memcpy(result.buf+len, addend.buf, addend.len);
+ return result;
+}
+
+TPS_PUBLIC Buffer&
+Buffer::operator+=(const Buffer& addend)
+{
+ unsigned int oldLen = len;
+ resize(len + addend.len);
+ memcpy(buf+oldLen, addend.buf, addend.len);
+ return *this;
+}
+
+TPS_PUBLIC Buffer&
+Buffer::operator+=(BYTE b)
+{
+ resize(len+1);
+ buf[len-1] = b;
+ return *this;
+}
+
+TPS_PUBLIC void
+Buffer::reserve(unsigned int n)
+{
+ if( n > res ) {
+ BYTE *newBuf = new BYTE[n];
+ memcpy(newBuf, buf, len);
+ if( buf != NULL ) {
+ delete [] buf;
+ buf = NULL;
+ }
+ buf = newBuf;
+ res = n;
+ }
+}
+
+TPS_PUBLIC void
+Buffer::resize(unsigned int newLen)
+{
+ if( newLen == len ) {
+ return;
+ } else if( newLen < len ) {
+ len = newLen;
+ } else if( newLen <= res ) {
+ assert( newLen > len );
+ memset(buf+len, 0, newLen-len);
+ len = newLen;
+ } else {
+ assert( newLen > len && newLen > res );
+ BYTE *newBuf = new BYTE[newLen];
+ memcpy(newBuf, buf, len);
+ memset(newBuf+len, 0, newLen-len);
+ if( buf != NULL ) {
+ delete [] buf;
+ buf = NULL;
+ }
+ buf = newBuf;
+ len = newLen;
+ res = newLen;
+ }
+}
+
+TPS_PUBLIC Buffer
+Buffer::substr(unsigned int i, unsigned int n) const
+{
+ assert( i < len && (i+n) <= len );
+ return Buffer( buf+i, n );
+}
+
+TPS_PUBLIC void
+Buffer::replace(unsigned int i, const BYTE* cpy, unsigned int n)
+{
+ if (len > i+n) {
+ resize( len);
+ }else {
+ resize( i+n );
+ }
+ memcpy(buf+i, cpy, n);
+}
+
+TPS_PUBLIC void
+Buffer::dump() const
+{
+ unsigned int i;
+
+ for( i=0; i < len; ++i ) {
+ printf("%02x ", buf[i]);
+ if( i % 16 == 15 ) printf("\n");
+ }
+ printf("\n");
+}
+
+/*
+ * if caller knows it's a string, pad with ending 0 and return.
+ * note:
+ * It is the caller's responsibility to make sure it's a string.
+ * Memory needs to be released by the caller.
+ */
+TPS_PUBLIC char *
+Buffer::string()
+{
+ unsigned int i;
+ char *s = (char *) PR_Malloc(len+1);
+ for (i = 0; i < len; i++) {
+ s[i] = buf[i];
+ }
+ s[i] = '\0';
+ return s;
+}
+
+TPS_PUBLIC char *
+Buffer::toHex()
+{
+ unsigned int i;
+
+ char *hx = (char *)PR_Malloc(1024);
+ if (hx == NULL)
+ return NULL;
+ for( i=0; i < len; ++i ) {
+ PR_snprintf(hx+(i*2),1024-(i*2),"%02x", (unsigned char)buf[i]);
+ }
+
+ return hx;
+}
+
+static const char hextbl[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+};
diff --git a/base/tps/src/main/ConfigStore.cpp b/base/tps/src/main/ConfigStore.cpp
new file mode 100644
index 000000000..e526b4039
--- /dev/null
+++ b/base/tps/src/main/ConfigStore.cpp
@@ -0,0 +1,893 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include <string.h>
+#include <regex.h>
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+#include "prprf.h"
+#include "main/ConfigStore.h"
+#include "main/Memory.h"
+#include "main/Util.h"
+#include "engine/RA.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef XP_WIN32
+#define TOKENDB_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TOKENDB_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+static PR_CALLBACK void*
+_AllocTable(void* pool, PRSize size)
+{
+ return PR_MALLOC(size);
+}
+
+static PR_CALLBACK void
+_FreeTable(void* pool, void* item)
+{
+ PR_DELETE(item);
+}
+
+static PR_CALLBACK PLHashEntry*
+_AllocEntry(void* pool, const void* key)
+{
+ return PR_NEW(PLHashEntry);
+}
+
+static PR_CALLBACK void
+_FreeEntry(void* pool, PLHashEntry* he, PRUintn flag)
+{
+ if( he == NULL ) {
+ return;
+ }
+
+ if (flag == HT_FREE_VALUE) {
+ if( he->value != NULL ) {
+ PL_strfree( (char*) he->value );
+ he->value = NULL;
+ }
+ } else if (flag == HT_FREE_ENTRY) {
+ if( he->key != NULL ) {
+ PL_strfree( (char*) he->key );
+ he->key = NULL;
+ }
+ if( he->value != NULL ) {
+ PL_strfree( (char*) he->value );
+ he->value = NULL;
+ }
+ PR_DELETE(he);
+ }
+}
+
+static PLHashAllocOps _AllocOps = {
+ _AllocTable,
+ _FreeTable,
+ _AllocEntry,
+ _FreeEntry
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+///// ConfigStoreRoot
+
+ConfigStoreRoot::ConfigStoreRoot()
+{
+ m_set = PL_NewHashTable(3, PL_HashString,
+ PL_CompareStrings, PL_CompareValues,
+ &_AllocOps, NULL);
+
+ m_set_refcount = 0;
+}
+
+// If the ConfigStoreRoot goes out of scope, we can't destroy
+// the Hashtable because others maybe depending on the values
+// inside.
+ConfigStoreRoot::~ConfigStoreRoot ()
+{
+ if( m_set != NULL ) {
+ if (m_set_refcount==0) {
+ PL_HashTableDestroy( m_set );
+ m_set = NULL;
+ }
+ }
+}
+
+void ConfigStoreRoot::addref()
+{
+ m_set_refcount++;
+}
+
+void ConfigStoreRoot::release()
+{
+ m_set_refcount--;
+}
+
+PLHashTable *ConfigStoreRoot::getSet()
+{
+ return m_set;
+}
+
+
+// ConfigureStore
+
+ConfigStore::ConfigStore(ConfigStoreRoot* root, const char *subStoreName)
+{
+ m_substore_name = PL_strdup(subStoreName);
+ m_root = root;
+ root->addref();
+ m_lock = PR_NewLock();
+}
+
+ConfigStore::~ConfigStore ()
+{
+ if (m_substore_name != NULL) {
+ PR_Free(m_substore_name);
+ }
+ if (m_cfg_file_path != NULL) {
+ PR_Free(m_cfg_file_path);
+ }
+ m_root->release();
+ delete m_root;
+
+ if (m_lock != NULL )
+ PR_DestroyLock(m_lock);
+}
+
+
+
+/*
+ConfigStore::ConfigStore(const ConfigStore &X)
+{
+ m_substore_name = X.m_substore_name;
+ m_root = X.m_root;
+ m_root.addref();
+}
+
+*/
+
+
+
+ConfigStore ConfigStore::GetSubStore(const char *substore)
+{
+ char *newname=NULL;
+ const char *name = m_substore_name;
+ if (strlen(name)==0) { // this is the root
+ newname = PL_strdup(substore);
+ } else {
+ newname = PR_smprintf("%s.%s",name,substore);
+ }
+ return ConfigStore(m_root,newname);
+}
+
+/**
+ * Reads configuration file and puts name value
+ * pair into the global hashtable.
+ */
+static int ReadLine(PRFileDesc *f, char *buf, int buf_len, int *removed_return)
+{
+ char *cur = buf;
+ int sum = 0;
+ PRInt32 rc;
+
+ *removed_return = 0;
+ while (1) {
+ rc = PR_Read(f, cur, 1);
+ if (rc == -1 || rc == 0)
+ break;
+ if (*cur == '\r') {
+ continue;
+ }
+ if (*cur == '\n') {
+ *cur = '\0';
+ *removed_return = 1;
+ break;
+ }
+ sum++;
+ cur++;
+ }
+ return sum;
+}
+
+#define MAX_CFG_LINE_LEN 4096
+
+ConfigStore *ConfigStore::CreateFromConfigFile(const char *cfg_path)
+{
+ PRFileDesc *f = NULL;
+ int removed_return;
+ char line[MAX_CFG_LINE_LEN];
+ ConfigStoreRoot *root = NULL;
+ ConfigStore *cfg = NULL;
+
+ f = PR_Open(cfg_path, PR_RDWR, 00400|00200);
+ if (f == NULL)
+ goto loser;
+
+ root = new ConfigStoreRoot();
+ cfg = new ConfigStore(root,"");
+
+ while (1) {
+ int n = ReadLine(f, line, MAX_CFG_LINE_LEN, &removed_return);
+ if (n > 0) {
+ if (line[0] == '#') // handle comment line
+ continue;
+ int c = 0;
+ while ((c < n) && (line[c] != '=')) {
+ c++;
+ }
+ if (c < n) {
+ line[c] = '\0';
+ } else {
+ continue; /* no '=', skip this line */
+ }
+ cfg->Add(line, &line[c+1]);
+ } else if (n == 0 && removed_return == 1) {
+ continue; /* skip empty line */
+ } else {
+ break;
+ }
+ }
+ if( f != NULL ) {
+ PR_Close( f );
+ f = NULL;
+ }
+ cfg->SetFilePath(cfg_path);
+
+loser:
+ return cfg;
+}
+
+/**
+ * Parses string of format "n1=v1&n2=v2..."
+ * into a ConfigStore.
+ */
+ConfigStore *ConfigStore::Parse(const char *s, const char *separator)
+{
+ char *pair;
+ char *line = NULL;
+ int i;
+ int len;
+ char *lasts = NULL;
+
+ if (s == NULL)
+ return NULL;
+ ConfigStoreRoot *root = new ConfigStoreRoot();
+ ConfigStore *set= new ConfigStore(root,"");
+
+ line = PL_strdup(s);
+ pair = PL_strtok_r(line, separator, &lasts);
+ while (pair != NULL) {
+ len = strlen(pair);
+ i = 0;
+ while (1) {
+ if (i >= len) {
+ goto skip;
+ }
+ if (pair[i] == '\0') {
+ goto skip;
+ }
+ if (pair[i] == '=') {
+ pair[i] = '\0';
+ break;
+ }
+ i++;
+ }
+ set->Add(&pair[0], &pair[i+1]);
+skip:
+ pair = PL_strtok_r(NULL, separator, &lasts);
+ }
+ if( line != NULL ) {
+ PL_strfree( line );
+ line = NULL;
+ }
+ return set;
+}
+
+typedef struct {
+ int index;
+ char *key;
+} Criteria;
+
+typedef struct {
+ PRCList list;
+ char *key;
+} OrderedEntry_t;
+
+typedef struct {
+ regex_t *regex;
+ ConfigStore *store;
+} PatternEntry_t;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+static PRIntn CountLoop(PLHashEntry *he, PRIntn index, void *arg)
+{
+ Criteria *criteria = (Criteria *)arg;
+ criteria->index++;
+ return HT_ENUMERATE_NEXT;
+}
+
+static PRIntn Loop(PLHashEntry *he, PRIntn index, void *arg)
+{
+ Criteria *criteria = (Criteria *)arg;
+ if (criteria != NULL && index == criteria->index) {
+ criteria->key = (char *)he->key;
+ return HT_ENUMERATE_STOP;
+ } else {
+ return HT_ENUMERATE_NEXT;
+ }
+}
+
+/**
+ * Called from PL_HashTableEnumerateEntries
+ * A pointer to a PRCList (circular linked list) is passed in.
+ * Once enumeration is complete, the PRCList will contain a lexically
+ * ordered list of a copy of the keys in the hash.
+ * The caller needs to free the copies
+ */
+static PRIntn OrderLoop(PLHashEntry *he, PRIntn index, void *arg)
+{
+ PRCList *qp = (PRCList *)arg;
+ OrderedEntry_t *entry;
+
+ if (he != NULL) {
+ entry = (OrderedEntry_t *) PR_Malloc(sizeof(OrderedEntry_t));
+ entry->key = PL_strdup((char *) he->key);
+ if (index ==0) {
+ PR_APPEND_LINK((PRCList *)entry, qp);
+ return HT_ENUMERATE_NEXT;
+ }
+ PRCList *head = PR_LIST_HEAD(qp);
+ PRCList *next;
+ while (head != qp) {
+ OrderedEntry_t *current = (OrderedEntry_t *) head;
+ if (strcmp((char *) he->key, (char *) current->key) <=0)
+ break;
+ next = PR_NEXT_LINK(head);
+ head = next;
+ }
+ PR_INSERT_BEFORE((PRCList*) entry, head);
+ return HT_ENUMERATE_NEXT;
+ } else {
+ return HT_ENUMERATE_STOP;
+ }
+}
+
+/**
+ * Called from PL_HashTableEnumerateEntries
+ * A pointer to a PatternEntry is passed in. A PatternEntry consists of
+ * a pointer a regex_t and a pointer to a new config store.
+ * Once enumeration is complete, the new config store will contain
+ * all the parameters (key and values) whose keys match the regex.
+ */
+static PRIntn PatternLoop(PLHashEntry *he, PRIntn index, void *arg)
+{
+ PatternEntry_t *entry = (PatternEntry_t *) arg;
+
+ if (entry == NULL) {
+ return HT_ENUMERATE_STOP;
+ }
+
+ regex_t *r = entry->regex;
+ ConfigStore *store = entry->store;
+
+ if ((r == NULL) || (store == NULL)) {
+ return HT_ENUMERATE_STOP;
+ }
+
+ size_t no_sub = r->re_nsub+1;
+ regmatch_t *result = NULL;
+
+ result = (regmatch_t *) PR_Malloc(sizeof(regmatch_t) * no_sub);
+
+ if ((he != NULL) && (he->key != NULL) && (he->value != NULL)) {
+ if (regexec(r, (char *) he->key, no_sub, result, 0)==0) {
+ // Found a match
+ store->Add((const char*) he->key, (const char *) he->value);
+ }
+ } else {
+ return HT_ENUMERATE_STOP;
+ }
+
+ if (result != NULL) PR_Free(result);
+ return HT_ENUMERATE_NEXT;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+int ConfigStore::Size()
+{
+ Criteria criteria;
+ criteria.index = 0;
+ criteria.key = NULL;
+
+ PR_Lock(m_lock);
+ PL_HashTableEnumerateEntries(m_root->getSet(), &CountLoop, &criteria);
+ PR_Unlock(m_lock);
+
+ return criteria.index;
+}
+
+const char *ConfigStore::GetNameAt(int pos)
+{
+ Criteria criteria;
+ criteria.index = pos;
+ criteria.key = NULL;
+
+ PR_Lock(m_lock);
+ PL_HashTableEnumerateEntries(m_root->getSet(), &Loop, &criteria);
+ PR_Unlock(m_lock);
+
+ return criteria.key;
+}
+
+/**
+ * Checks if a key is defined.
+ */
+int ConfigStore::IsNameDefined(const char *name)
+{
+ if (m_root->getSet()!= NULL) {
+ if (GetConfig(name) != NULL)
+ return 1;
+ }
+ return 0;
+}
+
+void ConfigStore::SetFilePath(const char* cfg_file_path)
+{
+ m_cfg_file_path = PL_strdup(cfg_file_path);
+}
+
+void ConfigStore::Add(const char *name, const char *value)
+{
+ if (IsNameDefined(name)) {
+ PR_Lock(m_lock);
+ PL_HashTableRemove(m_root->getSet(), name);
+ PL_HashTableAdd(m_root->getSet(), PL_strdup(name), PL_strdup(value));
+ PR_Unlock(m_lock);
+ } else {
+ PR_Lock(m_lock);
+ PL_HashTableAdd(m_root->getSet(), PL_strdup(name), PL_strdup(value));
+ PR_Unlock(m_lock);
+ }
+}
+
+void ConfigStore::Remove(const char *name)
+{
+ if (IsNameDefined(name)) {
+ PR_Lock(m_lock);
+ PL_HashTableRemove(m_root->getSet(), name);
+ PR_Unlock(m_lock);
+ }
+}
+
+const char *ConfigStore::GetConfig(const char *name)
+{
+ char buf[256];
+ char *ret;
+ if (m_root->getSet() ==NULL) {
+ return NULL;
+ }
+ if (PL_strlen(m_substore_name) == 0) {
+ PL_strncpy(buf,name,256);
+ } else {
+ PR_snprintf(buf,256,"%s.%s",m_substore_name,name);
+ }
+
+ PR_Lock(m_lock);
+ ret = (char *)PL_HashTableLookupConst(m_root->getSet(), buf);
+ PR_Unlock(m_lock);
+
+ return ret;
+}
+
+/**
+ * Retrieves configuration value as integer.
+ */
+int ConfigStore::GetConfigAsInt(const char *name)
+{
+ char *value = NULL;
+ value = (char *)GetConfig(name);
+ if (value == NULL)
+ return 0;
+ return atoi(value);
+}
+
+/**
+ * Retrieves configuration value as integer. If name is
+ * not defined, default value is returned.
+ */
+TPS_PUBLIC int ConfigStore::GetConfigAsInt(const char *name, int def)
+{
+ char *value = NULL;
+
+ value = (char *)GetConfig(name);
+ if (value == NULL)
+ return def;
+ return atoi(value);
+}
+
+
+/**
+ * Retrieves configuration value as unsigned integer.
+ */
+unsigned int ConfigStore::GetConfigAsUnsignedInt(const char *name)
+{
+ char *value = NULL;
+ int i = 0;
+
+ value = (char *)GetConfig(name);
+ if (value == NULL) {
+ return 0;
+ }
+
+ i = atoi(value);
+ if (i < 0) {
+ return 0;
+ }
+ return i;
+}
+
+/**
+ * Retrieves configuration value as unsigned integer. If name is
+ * not defined, default value is returned.
+ */
+TPS_PUBLIC unsigned int ConfigStore::GetConfigAsUnsignedInt(const char *name, unsigned int def)
+{
+ char *value = NULL;
+ int i = 0;
+
+ value = (char *)GetConfig(name);
+ if (value == NULL) {
+ return def;
+ }
+
+ i = atoi(value);
+ if (i < 0) {
+ return def;
+ }
+ return i;
+}
+
+
+/**
+ * Retrieves configuration value as boolean.
+ */
+bool ConfigStore::GetConfigAsBool(const char *name)
+{
+ char *value = NULL;
+
+ value = (char *)GetConfig(name);
+ if (value == NULL)
+ return false;
+ if (PL_CompareStrings("true", value) != 0)
+ return true;
+ else
+ return false;
+}
+
+/**
+ * Retrieves configuration value as boolean. If name is
+ * not defined, default value is returned.
+ */
+TPS_PUBLIC bool ConfigStore::GetConfigAsBool(const char *name, bool def)
+{
+ char *value = NULL;
+
+ value = (char *)GetConfig(name);
+ if (value == NULL)
+ return def;
+
+ if (PL_CompareStrings("true", value) != 0)
+ return true;
+ else if (PL_CompareStrings("false", value) != 0)
+ return false;
+ else
+ return def;
+}
+
+/**
+ * Retrieves configuration value as string. If key is
+ * not defined, default value is returned.
+ */
+TOKENDB_PUBLIC const char *ConfigStore::GetConfigAsString(const char *name, const char *def)
+{
+ char *value = NULL;
+
+ value = (char *)GetConfig(name);
+ if (value == NULL)
+ return def;
+ return value;
+}
+
+/**
+ * Retrieves configuration value as string.
+ */
+TPS_PUBLIC const char *ConfigStore::GetConfigAsString(const char *name)
+{
+ return (char *)GetConfig(name);
+}
+
+
+/**
+ * Allow operator[] overloading for retrieval of config strings
+ */
+const char* ConfigStore::operator[](const char*name)
+{
+ return GetConfigAsString(name);
+}
+
+
+Buffer *ConfigStore::GetConfigAsBuffer(const char *key)
+{
+ return GetConfigAsBuffer(key, NULL);
+}
+
+Buffer *ConfigStore::GetConfigAsBuffer(const char *key, const char *def)
+{
+ const char *value = NULL;
+
+ value = (char *)GetConfig(key);
+ if (value == NULL) {
+ if (def == NULL) {
+ return NULL;
+ } else {
+ return Util::Str2Buf(def);
+ }
+ } else {
+ return Util::Str2Buf(value);
+ }
+}
+
+/**
+ * returns a string containing all the parameters in the ConfigStore hash set in the
+ * format key1=value1&&key2=value2&& ...
+ * The list will be lexically ordered by parameter key values.
+ * The string needs to be freed by the caller.
+ **/
+TPS_PUBLIC const char* ConfigStore::GetOrderedList()
+{
+ char *outstr = NULL;
+ char *new_string = NULL;
+ PRCList order_list;
+ PR_INIT_CLIST(&order_list);
+
+ PR_Lock(m_lock);
+ PL_HashTableEnumerateEntries(m_root->getSet(), &OrderLoop, &order_list);
+ PR_Unlock(m_lock);
+
+ PRCList *current = PR_LIST_HEAD(&order_list);
+ PRCList *next;
+
+ outstr = (char*) PR_Malloc(128);
+ int allocated = 128;
+ int needed = 0;
+ PR_snprintf(outstr, 128, "");
+
+ while (current != &order_list) {
+ OrderedEntry_t *entry = (OrderedEntry_t *) current;
+ const char *value = GetConfigAsString(entry->key, "");
+
+ if ((entry != NULL) && (entry->key != NULL)) {
+ needed = PL_strlen(outstr) + PL_strlen(entry->key) + PL_strlen(value) + 4;
+ if (allocated <= needed) {
+ while (allocated <= needed) {
+ allocated = allocated * 2;
+ }
+ new_string = (char *)PR_Malloc(allocated);
+ PR_snprintf(new_string, allocated, "%s", outstr);
+ PR_Free(outstr);
+ outstr = new_string;
+ }
+
+ PL_strcat(outstr, entry->key);
+ PL_strcat(outstr, "=");
+ PL_strcat(outstr, value);
+
+ // free the memory for the Ordered Entry
+ PL_strfree(entry->key);
+ }
+
+ next = PR_NEXT_LINK(current);
+ PR_REMOVE_AND_INIT_LINK(current);
+ if (current != NULL) {
+ PR_Free(current);
+ }
+ current = next;
+
+ if (current != &order_list) PL_strcat(outstr, "&&");
+ }
+ return outstr;
+}
+
+/**
+ * Commits changes to the config file
+ */
+TPS_PUBLIC int ConfigStore::Commit(const bool backup, char *error_msg, int len)
+{
+ char name_tmp[256], cdate[256], name_bak[256], bak_dir[256];
+ char basename[256], dirname[256];
+ PRFileDesc *ftmp = NULL;
+ PRExplodedTime time;
+ PRTime now;
+ PRStatus status;
+
+ if (m_cfg_file_path == NULL) {
+ PR_snprintf(error_msg, len, "ConfigStore::Commit(): m_cfg_file_path is NULL!");
+ return 1;
+ }
+
+ if (strrchr(m_cfg_file_path, '/') != NULL) {
+ PR_snprintf((char *) basename, 256, "%s", strrchr(m_cfg_file_path, '/') +1);
+ PR_snprintf((char *) dirname, PL_strlen(m_cfg_file_path) - PL_strlen(basename), "%s", m_cfg_file_path);
+ PL_strcat(dirname, '\0');
+ } else {
+ PR_snprintf((char *) basename, 256, "%s", m_cfg_file_path);
+ PR_snprintf((char *) dirname, 256, ".");
+ }
+ PR_snprintf(bak_dir, 256, "%s/bak", dirname);
+
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_snprintf(cdate, 16, "%04d%02d%02d%02d%02d%02dZ",
+ time.tm_year, (time.tm_month + 1), time.tm_mday,
+ time.tm_hour, time.tm_min, time.tm_sec);
+ PR_snprintf(name_tmp, 256, "%s.%s.tmp", m_cfg_file_path,cdate);
+ PR_snprintf(name_bak, 256, "%s/%s.%s", bak_dir, basename, cdate);
+
+ ftmp = PR_Open(name_tmp, PR_WRONLY| PR_CREATE_FILE, 00400|00200);
+ if (ftmp == NULL) {
+ // unable to create temporary config file
+ PR_snprintf(error_msg, len, "ConfigStore::Commit(): unable to create temporary config file");
+ return 1;
+ }
+
+ PRCList order_list;
+ PR_INIT_CLIST(&order_list);
+
+ PR_Lock(m_lock);
+ PL_HashTableEnumerateEntries(m_root->getSet(), &OrderLoop, &order_list);
+ PR_Unlock(m_lock);
+
+ PRCList *current = PR_LIST_HEAD(&order_list);
+ PRCList *next;
+
+ while (current != &order_list) {
+ OrderedEntry_t *entry = (OrderedEntry_t *) current;
+ PR_Write(ftmp, entry->key, PL_strlen(entry->key));
+ PR_Write(ftmp, "=", 1);
+ const char *value = GetConfigAsString(entry->key, "");
+ PR_Write(ftmp, value, PL_strlen(value));
+ PR_Write(ftmp, "\n", 1);
+
+ // free the memory for the Ordered Entry
+ if (entry->key != NULL) PL_strfree(entry->key);
+
+ next = PR_NEXT_LINK(current);
+ PR_REMOVE_AND_INIT_LINK(current);
+ if (current != NULL) {
+ PR_Free(current);
+ }
+ current = next;
+ }
+
+ PR_Close(ftmp);
+
+ if (backup) {
+ // create the backup directory if it does not exist
+ if (PR_Access(bak_dir, PR_ACCESS_EXISTS) != PR_SUCCESS) {
+ PR_MkDir(bak_dir, 00770);
+ }
+ status = PR_Rename(m_cfg_file_path, name_bak);
+ if (status != PR_SUCCESS) {
+ // failed to back up CS.cfg
+ }
+ }
+ if (PR_Access(m_cfg_file_path, PR_ACCESS_EXISTS) == PR_SUCCESS) {
+ // backup is false, or backup failed
+ status = PR_Delete(m_cfg_file_path);
+ if (status != PR_SUCCESS) {
+ // failed to delete old CS.cfg file
+ PR_snprintf(error_msg, len, "ConfigStore::Commit(): unable to delete old CS.cfg file");
+ return 1;
+ }
+ }
+
+ status = PR_Rename(name_tmp, m_cfg_file_path);
+ if (status != PR_SUCCESS) {
+ // failed to move tmp to CS.cfg
+ // major badness - we now have only tmp file, no CS.cfg
+ PR_snprintf(error_msg, len, "ConfigStore::Commit(): failed to move tmp file to CS.cfg");
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * Takes in a string containing a regular expression.
+ * Returns a new ConfigStore which contains only those parameters whose
+ * keys match the pattern.
+ * The new Configstore must of course be freed by the caller.
+ **/
+ConfigStore *ConfigStore::GetPatternSubStore(const char *pattern)
+{
+
+ ConfigStoreRoot *root = NULL;
+ ConfigStore *ret = NULL;
+ PatternEntry_t entry;
+ regex_t *regex = NULL;
+ int err_no=0; /* For regerror() */
+
+ regex = (regex_t *) malloc(sizeof(regex_t));
+ memset(regex, 0, sizeof(regex_t));
+
+ if((err_no=regcomp(regex, pattern, 0))!=0) /* Compile the regex */
+ {
+ // Error in computing the regex
+ size_t length;
+ char *buffer;
+ length = regerror (err_no, regex, NULL, 0);
+ buffer = (char *) PR_Malloc(length);
+ regerror (err_no, regex, buffer, length);
+ // PR_fprintf(m_dump_f, "%s\n", buffer); /* Print the error */
+ PR_Free(buffer);
+ regfree(regex);
+ return NULL;
+ }
+
+ entry.regex = regex;
+ root = new ConfigStoreRoot();
+ ret = new ConfigStore(root, "");
+ entry.store = ret;
+
+ PR_Lock(m_lock);
+ PL_HashTableEnumerateEntries(m_root->getSet(), &PatternLoop, &entry);
+ PR_Unlock(m_lock);
+
+ /* cleanup */
+ //regfree(entry.regex);
+ //entry.store = NULL;
+
+ ret->SetFilePath("");
+ return ret;
+}
+
diff --git a/base/tps/src/main/LogFile.cpp b/base/tps/src/main/LogFile.cpp
new file mode 100644
index 000000000..d908ca0c5
--- /dev/null
+++ b/base/tps/src/main/LogFile.cpp
@@ -0,0 +1,298 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include <unistd.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "main/ConfigStore.h"
+#include "engine/RA.h"
+#include "main/LogFile.h"
+#include "main/RA_Context.h"
+#include "main/Util.h"
+
+//default constructor
+LogFile::LogFile():
+ m_fd(NULL),
+ m_fname(NULL),
+ m_signed_log(false),
+ m_bytes_written(0),
+ m_signed(false),
+ m_monitor(NULL),
+ m_ctx(NULL) { }
+
+int LogFile::startup(RA_Context *ctx, const char* prefix, const char *fname, bool signed_audit)
+{
+ if (ctx == NULL) {
+ return PR_FAILURE;
+ }
+
+ if (fname == NULL) {
+ ctx->LogError("LogFile::startup",
+ __LINE__,
+ "startup error, fname is NULL");
+ return PR_FAILURE;
+ }
+
+ m_ctx = ctx;
+ m_signed_log = signed_audit;
+ m_fname = PL_strdup(fname);
+ m_bytes_written =0;
+ m_signed = false;
+ m_fd = (PRFileDesc*) NULL;
+ m_monitor = PR_NewMonitor();
+
+ m_ctx->LogInfo( "LogFile::startup",
+ __LINE__,
+ "thread = 0x%lx: Logfile %s startup complete",
+ PR_GetCurrentThread(), m_fname);
+ return PR_SUCCESS;
+}
+
+bool LogFile::isOpen()
+{
+ if (m_fd != NULL) return true;
+ return false;
+}
+
+void LogFile::shutdown()
+{
+ m_ctx->LogInfo( "LogFile::shutdown",
+ __LINE__,
+ "thread = 0x%lx: Logfile %s shutting down pid: %d",
+ PR_GetCurrentThread(), m_fname,getpid());
+
+ PR_EnterMonitor(m_monitor);
+ if (m_fd != NULL) {
+ close();
+ m_fd = (PRFileDesc *) NULL;
+ }
+
+ if (m_fname != NULL) {
+ PR_Free(m_fname);
+ m_fname = NULL;
+ }
+
+ PR_ExitMonitor(m_monitor);
+
+ if (m_monitor != NULL) {
+ PR_DestroyMonitor(m_monitor);
+ m_monitor = (PRMonitor *) NULL;
+ }
+}
+
+int LogFile::open()
+{
+ PRFileInfo info;
+ PR_EnterMonitor(m_monitor);
+
+ m_ctx->LogInfo( "LogFile::open",
+ __LINE__,
+ "Opening Log File: %s pid: %d",
+ m_fname,getpid());
+
+ if (m_fd == NULL) {
+ m_fd = PR_Open(m_fname, PR_RDWR | PR_CREATE_FILE | PR_APPEND, 440|200);
+ if (m_fd == NULL) {
+ m_ctx->LogError( "LogFile::open",
+ __LINE__,
+ "Unable to open log file %s error no: %d",
+ m_fname,PR_GetError());
+
+
+ goto loser;
+ }
+ PRStatus status = PR_GetOpenFileInfo(m_fd, &info);
+ if (status != PR_SUCCESS) {
+ m_ctx->LogError( "LogFile::open",
+ __LINE__,
+ "Unable to get file information for log file %s",
+ m_fname);
+ goto loser;
+ }
+
+ set_bytes_written(info.size);
+ }
+ PR_ExitMonitor(m_monitor);
+ return PR_SUCCESS;
+
+ loser:
+ if (m_fd != NULL) {
+ PR_Close(m_fd);
+ m_fd = (PRFileDesc *)NULL;
+ }
+ set_bytes_written(0);
+ PR_ExitMonitor(m_monitor);
+ return PR_FAILURE;
+}
+
+int LogFile::close()
+{
+ PRStatus status;
+ PR_EnterMonitor(m_monitor);
+ status = PR_Close(m_fd);
+ if (status != PR_SUCCESS) {
+ m_ctx->LogError( "LogFile::close",
+ __LINE__,
+ "Failed to close log file %s",
+ m_fname);
+ }
+ PR_ExitMonitor(m_monitor);
+ return status;
+}
+
+int LogFile::ReadLine(char *buf, int buf_len, int *removed_return)
+{
+ return Util::ReadLine(m_fd, buf,buf_len, removed_return);
+}
+
+int LogFile::printf(const char* fmt, ...)
+{
+ PRInt32 status;
+ char msg[4096];
+ va_list ap;
+ va_start(ap, fmt);
+ PR_vsnprintf((char *) msg, 4096, fmt, ap);
+ status = this->write(msg);
+ va_end(ap);
+ return status;
+}
+
+int LogFile::write(char *msg_in, size_t n)
+{
+ char msg[4096];
+ PRInt32 status;
+
+ if (n > 4096) {
+ m_ctx->LogError("LogFile::write",
+ __LINE__,
+ "Trying to write more than 4096 bytes in one write to log file %s. Truncating ...",
+ m_fname);
+ n=4096;
+ }
+
+ PR_snprintf(msg, n, "%s", msg_in);
+ status = this->write(msg);
+ return status;
+}
+
+int LogFile::vfprintf(const char* fmt, va_list ap)
+{
+ char msg[4096];
+ PRInt32 status;
+
+ PR_vsnprintf((char *) msg, 4096, fmt, ap);
+ status = this->write(msg);
+ return status;
+}
+
+int LogFile::write(const char * msg)
+{
+ PRErrorCode error;
+ PRInt32 status;
+ int len;
+
+ if (msg == NULL) {
+ return PR_SUCCESS;
+ }
+
+ PR_EnterMonitor(m_monitor);
+ len = PL_strlen(msg);
+ if (m_fd != NULL) {
+ status = PR_Write(m_fd, msg, len);
+ if (status != len) {
+ m_ctx->LogError( "LogFile::write",
+ __LINE__,
+ "Too few or too many bytes written to log file %s",
+ m_fname);
+ goto loser;
+ } else if (status < 0) {
+ // write failed
+ error = PR_GetError();
+ m_ctx->LogError( "LogFile::write",
+ __LINE__,
+ "Write to log file %s failed: code %d",
+ m_fname, error);
+ goto loser;
+ } else {
+ set_bytes_written(get_bytes_written() + len);
+ }
+ }
+ PR_ExitMonitor(m_monitor);
+ return PR_SUCCESS;
+ loser:
+ PR_ExitMonitor(m_monitor);
+ return PR_FAILURE;
+}
+
+void LogFile::setSigned(bool val) {
+ m_signed = val;
+}
+
+bool LogFile::getSigned() {
+ return m_signed;
+}
+
+int LogFile::get_bytes_written() {
+ return m_bytes_written;
+}
+
+void LogFile::set_bytes_written(int val) {
+ if (val >=0) {
+ m_bytes_written = val;
+ } else {
+ m_ctx->LogError("LogFile::set_bytes_written",
+ __LINE__,
+ "Attempt to set m_bytes_written to a negative value. Ignoring");
+ }
+}
+
+RA_Context * LogFile::get_context() {
+ return m_ctx;
+}
+
+void LogFile::set_context(RA_Context *ctx) {
+ m_ctx = ctx;
+}
+
+
diff --git a/base/tps/src/main/Login.cpp b/base/tps/src/main/Login.cpp
new file mode 100644
index 000000000..116ac7769
--- /dev/null
+++ b/base/tps/src/main/Login.cpp
@@ -0,0 +1,72 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "plstr.h"
+#include "main/Base.h"
+#include "main/Login.h"
+#include "main/Memory.h"
+
+/**
+ * Constructs a login object.
+ */
+Login::Login (char *uid, char *pwd)
+{
+ if (uid == NULL) {
+ m_uid = NULL;
+ } else {
+ m_uid = PL_strdup(uid);
+ }
+ if (pwd == NULL) {
+ m_pwd = NULL;
+ } else {
+ m_pwd = PL_strdup(pwd);
+ }
+}
+
+/**
+ * Destructs login object.
+ */
+Login::~Login ()
+{
+ if( m_uid != NULL ) {
+ PL_strfree( m_uid );
+ m_uid = NULL;
+ }
+ if( m_pwd != NULL ) {
+ PL_strfree( m_pwd );
+ m_pwd = NULL;
+ }
+}
+
+/**
+ * Retrieves user id.
+ */
+char *Login::GetUID()
+{
+ return m_uid;
+}
+
+/**
+ * Retrieves password.
+ */
+char *Login::GetPassword()
+{
+ return m_pwd;
+}
diff --git a/base/tps/src/main/Memory.cpp b/base/tps/src/main/Memory.cpp
new file mode 100644
index 000000000..1ee5027d0
--- /dev/null
+++ b/base/tps/src/main/Memory.cpp
@@ -0,0 +1,268 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+#include "prprf.h"
+#include "plhash.h"
+#include "pk11func.h"
+
+#include "main/MemoryMgr.h"
+
+#ifdef MEM_PROFILING
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct _ref_block
+{
+ int id;
+ void *ptr;
+ const char *file;
+ const char *func;
+ const char *type;
+ int line;
+ int size;
+ int used;
+ PRTime time;
+} ref_block;
+
+#define MAX_BLOCKS 8096
+static ref_block m_rb[MAX_BLOCKS];
+
+static PRLock *m_free_block_lock = NULL;
+static PRLock *m_dump_lock = NULL;
+static PRLock *m_audit_lock = NULL;
+
+ref_block *get_free_block()
+{
+ int i;
+ PR_Lock(m_free_block_lock);
+ for (i = 0; i < MAX_BLOCKS; i++) {
+ if (m_rb[i].used == 0) {
+ // lock
+ m_rb[i].used = 1;
+ m_rb[i].time = PR_Now();
+ PR_Unlock(m_free_block_lock);
+ return &m_rb[i];
+ }
+ }
+ PR_Unlock(m_free_block_lock);
+ return NULL;
+}
+
+ref_block *find_block(void *ptr)
+{
+ int i;
+ for (i = 0; i < MAX_BLOCKS; i++) {
+ if (m_rb[i].used == 1 && m_rb[i].ptr == ptr) {
+ return &m_rb[i];
+ }
+ }
+ return NULL;
+}
+
+void free_block(ref_block *rb)
+{
+ rb->used = 0;
+}
+
+static PRFileDesc *m_audit_f = NULL;
+static PRFileDesc *m_dump_f = NULL;
+
+void MEM_init(char *audit_file, char *dump_file)
+{
+ m_audit_f = PR_Open(audit_file, PR_RDWR|PR_CREATE_FILE|PR_APPEND,
+ 00200|00400);
+ m_dump_f = PR_Open(dump_file, PR_RDWR|PR_CREATE_FILE|PR_APPEND,
+ 00200|00400);
+
+ int i;
+ for (i = 0; i < MAX_BLOCKS; i++) {
+ m_rb[i].id = i;
+ m_rb[i].used = 0;
+ }
+ m_free_block_lock = PR_NewLock();
+ m_dump_lock = PR_NewLock();
+ m_audit_lock = PR_NewLock();
+}
+
+void MEM_shutdown()
+{
+ PR_DestroyLock(m_free_block_lock);
+ PR_DestroyLock(m_dump_lock);
+ PR_DestroyLock(m_audit_lock);
+ if (m_dump_f != NULL) {
+ PR_Close(m_dump_f);
+ }
+ if (m_audit_f != NULL) {
+ PR_Close(m_audit_f);
+ }
+}
+
+static void MEM_audit_block(ref_block *ref, const char *type, const char *func, const char *file, int line, PRFileDesc *f)
+{
+ PRTime now;
+ const char* time_fmt = "%Y-%m-%d %H:%M:%S";
+ char datetime[1024];
+ PRExplodedTime time;
+ char datetime1[1024];
+ PRExplodedTime time1;
+
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+
+ PR_ExplodeTime(ref->time, PR_LocalTimeParameters, &time1);
+ PR_FormatTimeUSEnglish(datetime1, 1024, time_fmt, &time1);
+
+ PR_Lock(m_audit_lock);
+ PR_fprintf(f, "[%s] ID='%d' Size='%d' Type='%s' Func='%s' File='%s' Line='%d' Time='%s'\n",
+ datetime, ref->id, ref->size, type, func, file, line, datetime1);
+ PR_Sync(f);
+ PR_Unlock(m_audit_lock);
+}
+
+void MEM_dump_unfree()
+{
+ int i;
+ PRTime now;
+ const char* time_fmt = "%Y-%m-%d %H:%M:%S";
+ char datetime[1024];
+ PRExplodedTime time;
+ char datetime1[1024];
+ PRExplodedTime time1;
+ int sum_count = 0;
+ int sum_mem = 0;
+
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+
+ PR_Lock(m_dump_lock);
+ PR_fprintf(m_dump_f, "--------------------------------------------\n");
+ PR_fprintf(m_dump_f, "Memory Report - '%s'\n", datetime);
+ PR_fprintf(m_dump_f, "1) Unfree Blocks:\n");
+ PR_fprintf(m_dump_f, "\n");
+ for (i = 0; i < MAX_BLOCKS; i++) {
+ if (!m_rb[i].used)
+ continue;
+ PR_ExplodeTime(m_rb[i].time, PR_LocalTimeParameters, &time1);
+ PR_FormatTimeUSEnglish(datetime1, 1024, time_fmt, &time1);
+ PR_fprintf(m_dump_f, " ID='%d' Size='%d' Type='%s' Func='%s' File='%s' Line='%d' Time='%s'\n", m_rb[i].id, m_rb[i].size, m_rb[i].type, m_rb[i].func, m_rb[i].file, m_rb[i].line, datetime1);
+ sum_mem += m_rb[i].size;
+ sum_count += 1;
+ }
+ PR_fprintf(m_dump_f, "\n");
+ PR_fprintf(m_dump_f, "2) Total Unfree Memory Size:\n");
+ PR_fprintf(m_dump_f, " %d bytes\n", sum_mem);
+ PR_fprintf(m_dump_f, "\n");
+ PR_fprintf(m_dump_f, "3) Total Unfree Memory Blocks:\n");
+ PR_fprintf(m_dump_f, " %d\n", sum_count);
+ PR_fprintf(m_dump_f, "\n");
+ PR_fprintf(m_dump_f, "--------------------------------------------\n");
+ PR_Sync(m_dump_f);
+ PR_Unlock(m_dump_lock);
+}
+
+char *MEM_strdup(const char *s, const char *type, const char *func, const char *file, int line)
+{
+ ref_block *rb = get_free_block();
+ if (rb == NULL)
+ return NULL;
+
+ char *buf = strdup(s);
+
+ rb->ptr = buf;
+ rb->func = func;
+ rb->file = file;
+ rb->line = line;
+ rb->type = type;
+ rb->size = strlen(s) + 1;
+ MEM_audit_block(rb, rb->type, rb->func, rb->file, rb->line, m_audit_f);
+
+ return buf;
+}
+
+void *MEM_malloc(int size, const char *type, const char *func, const char *file, int line)
+{
+ ref_block *rb = get_free_block();
+ if (rb == NULL)
+ return NULL;
+ void *buf = malloc(size);
+
+ rb->ptr = buf;
+ rb->func = func;
+ rb->file = file;
+ rb->line = line;
+ rb->type = type;
+ rb->size = size;
+ MEM_audit_block(rb, rb->type, rb->func, rb->file, rb->line, m_audit_f);
+
+ return buf;
+}
+
+void MEM_free(void *p, const char *type, const char *func, const char *file, int line)
+{
+ if (p == NULL)
+ return;
+ ref_block *rb = find_block(p);
+ if (rb == NULL)
+ return;
+ MEM_audit_block(rb, type, func, file, line, m_audit_f);
+ free(p);
+ free_block(rb);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#if 0
+void *operator new(size_t size, const char *func, const char *file, int line)
+{
+ return MEM_malloc(size, func, file, line);
+}
+
+void *operator new[](size_t size, const char *func, const char *file, int line)
+{
+ return MEM_malloc(size, func, file, line);
+}
+
+#endif
+void operator delete(void *p)
+{
+ MEM_free(p,"delete","", "", 0);
+}
+
+void operator delete[](void *p)
+{
+ MEM_free(p,"delete[]","", "", 0);
+}
+
+#endif /* MEM_PROFILING */
+
diff --git a/base/tps/src/main/NameValueSet.cpp b/base/tps/src/main/NameValueSet.cpp
new file mode 100644
index 000000000..bd95a8e4a
--- /dev/null
+++ b/base/tps/src/main/NameValueSet.cpp
@@ -0,0 +1,322 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include <string.h>
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+#include "prprf.h"
+#include "main/NameValueSet.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+static PR_CALLBACK void*
+_AllocTable(void* pool, PRSize size)
+{
+ return PR_MALLOC(size);
+}
+
+static PR_CALLBACK void
+_FreeTable(void* pool, void* item)
+{
+ PR_DELETE(item);
+}
+
+static PR_CALLBACK PLHashEntry*
+_AllocEntry(void* pool, const void* key)
+{
+ return PR_NEW(PLHashEntry);
+}
+
+static PR_CALLBACK void
+_FreeEntry(void* pool, PLHashEntry* he, PRUintn flag)
+{
+ if( he == NULL ) {
+ return;
+ }
+
+ if (flag == HT_FREE_VALUE) {
+ if( he->value != NULL ) {
+ PL_strfree( ( char* ) he->value );
+ he->value = NULL;
+ }
+ } else if (flag == HT_FREE_ENTRY) {
+ if( he->key != NULL ) {
+ PL_strfree( ( char* ) he->key );
+ he->key = NULL;
+ }
+ if( he->value != NULL ) {
+ PL_strfree( ( char* ) he->value );
+ he->value = NULL;
+ }
+ PR_DELETE(he);
+ }
+}
+
+static PLHashAllocOps _AllocOps = {
+ _AllocTable,
+ _FreeTable,
+ _AllocEntry,
+ _FreeEntry
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+TPS_PUBLIC NameValueSet::NameValueSet()
+{
+ m_set = PL_NewHashTable(3, PL_HashString,
+ PL_CompareStrings, PL_CompareValues,
+ &_AllocOps, NULL);
+}
+
+TPS_PUBLIC NameValueSet::~NameValueSet ()
+{
+ if( m_set != NULL ) {
+ PL_HashTableDestroy( m_set );
+ m_set = NULL;
+ }
+
+ return;
+}
+
+/**
+ * Parsers string of format "n1=v1&n2=v2..."
+ * into a NameValueSet.
+ */
+TPS_PUBLIC NameValueSet *NameValueSet::Parse(const char *s, const char *separator)
+{
+ NameValueSet *set = NULL;
+ char *pair;
+ char *line = NULL;
+ int i;
+ int len;
+ char *lasts = NULL;
+
+ if (s == NULL)
+ return NULL;
+ set = new NameValueSet();
+ line = PL_strdup(s);
+ pair = PL_strtok_r(line, separator, &lasts);
+ while (pair != NULL) {
+ len = strlen(pair);
+ i = 0;
+ while (1) {
+ if (i >= len) {
+ goto skip;
+ }
+ if (pair[i] == '\0') {
+ goto skip;
+ }
+ if (pair[i] == '=') {
+ pair[i] = '\0';
+ break;
+ }
+ i++;
+ }
+ set->Add(&pair[0], &pair[i+1]);
+skip:
+ pair = PL_strtok_r(NULL, separator, &lasts);
+ }
+ if( line != NULL ) {
+ PL_strfree( line );
+ line = NULL;
+ }
+ return set;
+}
+
+typedef struct {
+ int index;
+ char *key;
+} Criteria;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+static PRIntn CountLoop(PLHashEntry *he, PRIntn index, void *arg)
+{
+ Criteria *criteria = (Criteria *)arg;
+ criteria->index++;
+ return HT_ENUMERATE_NEXT;
+}
+
+static PRIntn Loop(PLHashEntry *he, PRIntn index, void *arg)
+{
+ Criteria *criteria = (Criteria *)arg;
+ if (criteria != NULL && index == criteria->index) {
+ criteria->key = (char *)he->key;
+ return HT_ENUMERATE_STOP;
+ } else {
+ return HT_ENUMERATE_NEXT;
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+TPS_PUBLIC int NameValueSet::Size()
+{
+ Criteria criteria;
+ criteria.index = 0;
+ criteria.key = NULL;
+ PL_HashTableEnumerateEntries(m_set, &CountLoop, &criteria);
+ return criteria.index;
+}
+
+TPS_PUBLIC char *NameValueSet::GetNameAt(int pos)
+{
+ Criteria criteria;
+ criteria.index = pos;
+ criteria.key = NULL;
+ PL_HashTableEnumerateEntries(m_set, &Loop, &criteria);
+ return criteria.key;
+}
+
+/**
+ * Checks if a key is defined.
+ */
+TPS_PUBLIC int NameValueSet::IsNameDefined(const char *name)
+{
+ if (GetValue(name) == NULL)
+ return 0;
+ else
+ return 1;
+}
+
+TPS_PUBLIC void NameValueSet::Add(const char *name, const char *value)
+{
+ if (IsNameDefined(name)) {
+ PL_HashTableAdd(m_set, PL_strdup(name), PL_strdup(value));
+ } else {
+ PL_HashTableAdd(m_set, PL_strdup(name), PL_strdup(value));
+ }
+}
+
+TPS_PUBLIC void NameValueSet::Remove(const char *name)
+{
+ if (IsNameDefined(name)) {
+ PL_HashTableRemove(m_set, name);
+ }
+}
+
+TPS_PUBLIC char *NameValueSet::GetValue(const char *name)
+{
+ return (char *)PL_HashTableLookupConst(m_set, name);
+}
+
+/**
+ * Retrieves configuration value as integer.
+ */
+TPS_PUBLIC int NameValueSet::GetValueAsInt(const char *name)
+{
+ char *value = NULL;
+
+ value = (char *)GetValue(name);
+ if (value == NULL)
+ return 0;
+ return atoi(value);
+}
+
+/**
+ * Retrieves configuration value as integer. If name is
+ * not defined, default value is returned.
+ */
+TPS_PUBLIC int NameValueSet::GetValueAsInt(const char *name, int def)
+{
+ char *value = NULL;
+
+ value = (char *)GetValue(name);
+ if (value == NULL)
+ return def;
+ return atoi(value);
+}
+
+
+/**
+ * Retrieves configuration value as boolean.
+ */
+TPS_PUBLIC int NameValueSet::GetValueAsBool(const char *name)
+{
+ char *value = NULL;
+
+ value = (char *)GetValue(name);
+ if (value == NULL)
+ return 0;
+ if (PL_CompareStrings("true", value) != 0)
+ return 1;
+ else
+ return 0;
+}
+
+/**
+ * Retrieves configuration value as boolean. If name is
+ * not defined, default value is returned.
+ */
+TPS_PUBLIC int NameValueSet::GetValueAsBool(const char *name, int def)
+{
+ char *value = NULL;
+
+ value = (char *)GetValue(name);
+ if (value == NULL)
+ return def;
+ if (PL_CompareStrings("true", value) != 0)
+ return 1;
+ else
+ return 0;
+}
+
+/**
+ * Retrieves configuration value as string. If key is
+ * not defined, default value is returned.
+ */
+TPS_PUBLIC char *NameValueSet::GetValueAsString(const char *name, char *def)
+{
+ char *value = NULL;
+
+ value = (char *)GetValue(name);
+ if (value == NULL)
+ return def;
+ return value;
+}
+
+/**
+ * Retrieves configuration value as string.
+ */
+TPS_PUBLIC char *NameValueSet::GetValueAsString(const char *name)
+{
+ return (char *)GetValue(name);
+}
+
diff --git a/base/tps/src/main/ObjectSpec.cpp b/base/tps/src/main/ObjectSpec.cpp
new file mode 100644
index 000000000..2896a85f0
--- /dev/null
+++ b/base/tps/src/main/ObjectSpec.cpp
@@ -0,0 +1,515 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <string.h>
+#include "prmem.h"
+#include "pk11func.h"
+#include "main/Buffer.h"
+#include "main/ObjectSpec.h"
+#include "engine/RA.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+ObjectSpec::ObjectSpec ()
+{
+ for (int i = 0; i < MAX_ATTRIBUTE_SPEC; i++) {
+ m_attributeSpec[i] = NULL;
+ }
+ m_fixedAttributes = 0;
+}
+
+ObjectSpec::~ObjectSpec ()
+{
+ for (int i = 0; i < MAX_ATTRIBUTE_SPEC; i++) {
+ if (m_attributeSpec[i] != NULL) {
+ delete m_attributeSpec[i];
+ m_attributeSpec[i] = NULL;
+ }
+ }
+}
+
+#define DATATYPE_STRING 0
+#define DATATYPE_INTEGER 1
+#define DATATYPE_BOOL_FALSE 2
+#define DATATYPE_BOOL_TRUE 3
+
+/**
+ * Parse 'c' object.
+ */
+void ObjectSpec::ParseAttributes(char *objectID, ObjectSpec *ObjectSpec, Buffer *b)
+{
+ int curpos = 7;
+ unsigned long fixedAttrs = 0;
+ unsigned int xclass = 0;
+ unsigned int id = 0;
+
+ /* skip first 7 bytes */
+
+ while (curpos < ((int)(b->size()))) {
+ unsigned long attribute_id =
+ (((BYTE*)*b)[curpos] << 24) +
+ (((BYTE*)*b)[curpos+1] << 16) +
+ (((BYTE*)*b)[curpos+2] << 8) +
+ ((BYTE*)*b)[curpos+3];
+ unsigned short attribute_size =
+ (((BYTE*)*b)[curpos+4] << 8) +
+ ((BYTE*)*b)[curpos+5];
+ BYTE type = 0;
+ Buffer data;
+ int found = 0;
+ /* modify fixed attributes */
+
+ switch (attribute_id) {
+ case CKA_TOKEN:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00000080;
+ }
+ break;
+ case CKA_PRIVATE:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00000100;
+ } else {
+ }
+ break;
+ case CKA_MODIFIABLE:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00000200;
+ }
+ break;
+ case CKA_DERIVE:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00000400;
+ }
+ break;
+ case CKA_LOCAL:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00000800;
+ }
+ break;
+ case CKA_ENCRYPT:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00001000;
+ }
+ break;
+ case CKA_DECRYPT:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00002000;
+ }
+ break;
+ case CKA_WRAP:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00004000;
+ }
+ break;
+ case CKA_UNWRAP:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00008000;
+ }
+ break;
+ case CKA_SIGN:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00010000;
+ }
+ break;
+ case CKA_SIGN_RECOVER:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00020000;
+ }
+ break;
+ case CKA_VERIFY:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00040000;
+ }
+ break;
+ case CKA_VERIFY_RECOVER:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00080000;
+ }
+ break;
+ case CKA_SENSITIVE:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00100000;
+ }
+ break;
+ case CKA_ALWAYS_SENSITIVE:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00200000;
+ }
+ break;
+ case CKA_EXTRACTABLE:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00400000;
+ }
+ break;
+ case CKA_NEVER_EXTRACTABLE:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00800000;
+ }
+ break;
+ case CKA_SUBJECT:
+ type = DATATYPE_STRING;
+ data = b->substr(curpos+6, attribute_size);
+ /* build by PKCS11 */
+ break;
+ case CKA_LABEL:
+ type = DATATYPE_STRING;
+ data = b->substr(curpos+6, attribute_size);
+ found = 1;
+ break;
+ case CKA_MODULUS:
+ type = DATATYPE_STRING;
+ data = b->substr(curpos+6, attribute_size);
+ /* build by PKCS11 */
+ break;
+ case CKA_ID:
+ type = DATATYPE_STRING;
+ data = b->substr(curpos+6, attribute_size);
+ /* build by PKCS11 */
+ break;
+ case CKA_KEY_TYPE:
+ type = DATATYPE_INTEGER;
+ data = b->substr(curpos+6, 4);
+ /* build by PKCS11 */
+ break;
+ case CKA_CLASS:
+ type = DATATYPE_INTEGER;
+ data = b->substr(curpos+6, 4);
+ xclass = ((BYTE*)data)[0];
+ /* build by PKCS11 */
+ break;
+ case CKA_PUBLIC_EXPONENT:
+ type = DATATYPE_STRING;
+ data = b->substr(curpos+6, attribute_size);
+ /* build by PKCS11 */
+ break;
+ case CKA_CERTIFICATE_TYPE:
+ type = DATATYPE_INTEGER;
+ data = b->substr(curpos+6, 4);
+ /* build by PKCS11 */
+ break;
+ default:
+ RA::Debug("ObjectSpec::ParseKeyBlob",
+ "skipped attribute_id = %lx",
+ attribute_id);
+ break;
+ }
+
+
+ if (found) {
+ /* add attribute spec */
+ AttributeSpec *attrSpec = new AttributeSpec();
+ attrSpec->SetAttributeID(attribute_id);
+ attrSpec->SetType(type);
+
+ switch (type) {
+ case DATATYPE_STRING:
+ attrSpec->SetData(data);
+ break;
+ case DATATYPE_INTEGER:
+ attrSpec->SetData(data);
+ break;
+ case DATATYPE_BOOL_FALSE:
+ break;
+ case DATATYPE_BOOL_TRUE:
+ break;
+ default:
+ break;
+ }
+
+ ObjectSpec->AddAttributeSpec(attrSpec);
+ }
+
+
+ curpos += 4 + 2 + attribute_size;
+ }
+
+ //Here the objectID fixed attribute gets massaged. Here's how:
+ // The objectID becomes the cert container id, ex: 01
+ // Each key pair associated with the cert must have the same ID.
+ // This is done by math using the following formula:
+ // Given a cert id of "2", the keyAttrIds of the keys are originally
+ // configured as k4 and k5. Note that one is twice the cert id, and
+ // the other is twice the cert id plus 1. In order to map the key ids
+ // down to the cert's id, the code below changes both "4" and "5" back
+ // to "2".
+
+ int val = (objectID[1] - '0');
+ switch (objectID[0]) {
+ case 'c':
+ id = val;
+#if 0
+ fixedAttrs |=
+ 0x00000080 /* CKA_TOKEN */
+ ;
+#endif
+ break;
+ case 'k':
+ if (val % 2) {
+ id = (val-1)/2;
+ } else {
+ id = (val/2);
+ }
+#if 0
+ if (xclass == CKO_PUBLIC_KEY) {
+ fixedAttrs |=
+ 0x00000800 /* CKA_LOCAL */ |
+ 0x00000080 /* CKA_TOKEN */
+ ;
+ }
+ if (xclass == CKO_PRIVATE_KEY) {
+ fixedAttrs |=
+ 0x00000800 /* CKA_LOCAL */ |
+ 0x00000080 /* CKA_TOKEN */
+ ;
+ }
+#endif
+ break;
+ }
+
+ ObjectSpec->SetFixedAttributes(fixedAttrs | (xclass << 4) | id);
+}
+
+/**
+ * Parse 'c' object.
+ */
+void ObjectSpec::ParseCertificateAttributes(char *objectID, ObjectSpec *ObjectSpec, Buffer *b)
+{
+ ParseAttributes(objectID, ObjectSpec, b);
+}
+
+/**
+ * Parse 'k' object.
+ */
+void ObjectSpec::ParseKeyAttributes(char *objectID, ObjectSpec *ObjectSpec, Buffer *b)
+{
+ ParseAttributes(objectID, ObjectSpec, b);
+}
+
+/**
+ * Parse 'C' object.
+ */
+void ObjectSpec::ParseCertificateBlob(char *objectID, ObjectSpec *ObjectSpec, Buffer *b)
+{
+ unsigned long fixedAttrs = 0;
+ unsigned int xclass = 0;
+ unsigned int id = 0;
+
+ AttributeSpec *value = new AttributeSpec();
+ value->SetAttributeID(CKA_VALUE);
+ value->SetType(DATATYPE_STRING);
+ value->SetData(*b);
+ ObjectSpec->AddAttributeSpec(value);
+
+ fixedAttrs = 0x00000080; /* CKA_TOKEN */
+ xclass = CKO_CERTIFICATE;
+ id = objectID[1] - '0';
+
+ ObjectSpec->SetFixedAttributes(fixedAttrs| (xclass << 4) | id);
+}
+
+/**
+ * Convert object from token into object spec.
+ *
+ * Reference:
+ * http://netkey/design/applet_readable_object_spec-0.1.txt
+ * http://netkey/design/pkcs11obj.txt
+ */
+ObjectSpec *ObjectSpec::ParseFromTokenData(unsigned long objid, Buffer *b)
+{
+ char objectID[4];
+
+ ObjectSpec *o = new ObjectSpec();
+ o->SetObjectID(objid);
+
+ objectID[0] = (char)((objid >> 24) & 0xff);
+ objectID[1] = (char)((objid >> 16) & 0xff);
+ objectID[2] = (char)((objid >> 8) & 0xff);
+ objectID[3] = (char)((objid) & 0xff);
+
+ switch (objectID[0]) {
+ case 'c': /* certificate attributes */
+ ParseCertificateAttributes(objectID, o, b);
+ break;
+ case 'k': /* public key or private key attributes */
+ ParseKeyAttributes(objectID, o, b);
+ break;
+ case 'C': /* certificate in DER */
+ ParseCertificateBlob(objectID, o, b);
+ break;
+ default:
+ RA::Debug("ObjectSpec::ParseKeyBlob",
+ "unknown objectID = %c", objectID[0]);
+ /* error */
+ break;
+ }
+
+ return o;
+}
+
+ObjectSpec *ObjectSpec::Parse(Buffer *b, int offset, int *nread)
+{
+ int sum = 0;
+
+
+ if((b->size() - offset) < 10)
+ return NULL;
+
+ ObjectSpec *o = new ObjectSpec();
+ unsigned long id =
+ (((unsigned char *)*b)[offset + 0] << 24) +
+ (((unsigned char *)*b)[offset + 1] << 16) +
+ (((unsigned char *)*b)[offset + 2] << 8) +
+ (((unsigned char *)*b)[offset + 3]);
+
+ o->SetObjectID(id);
+ unsigned long attribute =
+ (((unsigned char *)*b)[offset + 4] << 24) +
+ (((unsigned char *)*b)[offset + 5] << 16) +
+ (((unsigned char *)*b)[offset + 6] << 8) +
+ (((unsigned char *)*b)[offset + 7]);
+ o->SetFixedAttributes(attribute);
+ unsigned short count = (((unsigned char *)*b)[offset + 8] << 8) +
+ ((unsigned char *)*b)[offset + 9];
+ sum += 10;
+ int curpos = offset + 10;
+ for (int i = 0; i < count; i++) {
+ int len = 0;
+ switch (((unsigned char *)*b)[curpos+4]) {
+ case DATATYPE_STRING:
+ len = 4 + 1 + 2 + (((unsigned char *)*b)[curpos+5]<<8) + ((unsigned char *)*b)[curpos+6];
+ break;
+ case DATATYPE_INTEGER:
+ len = 4 + 1 + 4;
+ break;
+ case DATATYPE_BOOL_FALSE:
+ len = 4 + 1;
+ break;
+ case DATATYPE_BOOL_TRUE:
+ len = 4 + 1;
+ break;
+ }
+ Buffer attr = b->substr(curpos, len);
+ AttributeSpec *attrSpec = AttributeSpec::Parse(&attr, 0);
+ o->AddAttributeSpec(attrSpec);
+ curpos += len;
+ sum += len;
+ }
+ *nread = sum;
+ return o;
+}
+
+void ObjectSpec::SetObjectID(unsigned long v)
+{
+ m_objectID = v;
+}
+
+unsigned long ObjectSpec::GetObjectID()
+{
+ return m_objectID;
+}
+
+void ObjectSpec::SetFixedAttributes(unsigned long v)
+{
+ m_fixedAttributes = v;
+}
+
+unsigned long ObjectSpec::GetFixedAttributes()
+{
+ return m_fixedAttributes;
+}
+
+
+int ObjectSpec::GetAttributeSpecCount()
+{
+ for (int i = 0; i < MAX_ATTRIBUTE_SPEC; i++) {
+ if (m_attributeSpec[i] == NULL) {
+ return i;
+ }
+ }
+ return 0;
+}
+
+AttributeSpec *ObjectSpec::GetAttributeSpec(int p)
+{
+ if (p < MAX_ATTRIBUTE_SPEC) {
+ if (m_attributeSpec[p] != NULL) {
+ return m_attributeSpec[p];
+ }
+ }
+ return NULL;
+}
+
+void ObjectSpec::AddAttributeSpec(AttributeSpec *p)
+{
+ for (int i = 0; i < MAX_ATTRIBUTE_SPEC; i++) {
+ if (m_attributeSpec[i] == NULL) {
+ m_attributeSpec[i] = p;
+ return;
+ }
+ }
+}
+
+void ObjectSpec::RemoveAttributeSpec(int p)
+{
+ if (p < MAX_ATTRIBUTE_SPEC) {
+ if (m_attributeSpec[p] != NULL) {
+ delete m_attributeSpec[p];
+ m_attributeSpec[p] = NULL;
+ }
+ // fill hole
+ int empty = p;
+ for (int x = p+1; x < MAX_ATTRIBUTE_SPEC; x++) {
+ if (m_attributeSpec[x] != NULL) {
+ m_attributeSpec[empty] = m_attributeSpec[x];
+ m_attributeSpec[x] = NULL;
+ empty++;
+ }
+ }
+ }
+
+}
+
+Buffer ObjectSpec::GetData()
+{
+ Buffer data = Buffer();
+
+ data += Buffer(1, (BYTE)(m_objectID >> 24) & 0xff);
+ data += Buffer(1, (BYTE)(m_objectID >> 16) & 0xff);
+ data += Buffer(1, (BYTE)(m_objectID >> 8) & 0xff);
+ data += Buffer(1, (BYTE)(m_objectID & 0xff));
+ data += Buffer(1, (BYTE)(m_fixedAttributes >> 24) & 0xff);
+ data += Buffer(1, (BYTE)(m_fixedAttributes >> 16) & 0xff);
+ data += Buffer(1, (BYTE)(m_fixedAttributes >> 8) & 0xff);
+ data += Buffer(1, (BYTE)(m_fixedAttributes & 0xff));
+
+ unsigned short attributeCount = GetAttributeSpecCount();
+ data += Buffer(1, (attributeCount >> 8) & 0xff);
+ data += Buffer(1, attributeCount & 0xff);
+ for (int i = 0; i < attributeCount; i++) {
+ AttributeSpec *spec = GetAttributeSpec(i);
+ data += spec->GetData();
+ }
+
+ return data;
+}
diff --git a/base/tps/src/main/PKCS11Obj.cpp b/base/tps/src/main/PKCS11Obj.cpp
new file mode 100644
index 000000000..061dc7a91
--- /dev/null
+++ b/base/tps/src/main/PKCS11Obj.cpp
@@ -0,0 +1,491 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <string.h>
+#include "prmem.h"
+#include "pk11func.h"
+#include "zlib.h"
+#include "engine/RA.h"
+#include "main/Buffer.h"
+#include "main/PKCS11Obj.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+PKCS11Obj::PKCS11Obj ()
+{
+ for (int i = 0; i < MAX_OBJECT_SPEC; i++) {
+ m_objSpec[i] = NULL;
+ }
+}
+
+PKCS11Obj::~PKCS11Obj ()
+{
+ for (int i = 0; i < MAX_OBJECT_SPEC; i++) {
+ if (m_objSpec[i] != NULL) {
+ delete m_objSpec[i];
+ m_objSpec[i] = NULL;
+ }
+ }
+}
+
+PKCS11Obj *PKCS11Obj::Parse(Buffer *b, int offset)
+{
+ PKCS11Obj *o = new PKCS11Obj();
+
+ unsigned short formatVersion = (((BYTE *)*b)[offset + 0] << 8) +
+ (((BYTE *)*b)[offset + 1]);
+ o->SetFormatVersion(formatVersion);
+ unsigned short objectVersion = (((BYTE *)*b)[offset + 2] << 8) +
+
+ (((BYTE *)*b)[offset + 3]);
+ o->SetObjectVersion(objectVersion);
+ o->SetCUID(b->substr(offset + 4, 10));
+
+ unsigned short compressionType =
+ (((BYTE *)*b)[offset + 14] << 8) + (((BYTE *)*b)[offset + 15]);
+ unsigned short compressedDataSize =
+ (((BYTE *)*b)[offset + 16] << 8) + (((BYTE *)*b)[offset + 17]);
+#if 0
+ unsigned short compressedDataOffset =
+ (unsigned short)(((unsigned char *)*b)[offset + 18] << 8) + (((unsigned char *)*b)[offset + 19]);
+#endif
+
+ Buffer data;
+ if (compressionType == 0) { /* no compression */
+ data = b->substr(offset + 20, compressedDataSize);
+ } else if (compressionType == 1) { /* zlib */
+ Buffer compressedData = b->substr(offset + 20, compressedDataSize);
+
+#define MAX_UNCOMPRESS_SIZE 20000
+ unsigned char buf[MAX_UNCOMPRESS_SIZE];
+ int rc = 0;
+ uLong len = MAX_UNCOMPRESS_SIZE;
+ rc = uncompress((Bytef*)buf, (uLongf*)&len,
+ (Bytef*)((BYTE*)compressedData),
+ (uLong)compressedData.size());
+ RA::Debug("PKCS11Obj::Parse","uncompress ret=%d",rc);
+ data = Buffer(buf,(unsigned int) len);
+ } else {
+ /* error */
+ }
+
+
+ unsigned short objOffset = (((BYTE *)data)[0] << 8) +
+ ((BYTE *)data)[1];
+ unsigned short objCount = (((BYTE *)data)[2] << 8) +
+ ((BYTE *)data)[3];
+ Buffer tokenName = data.substr(5, ((BYTE *)data)[4]);
+ o->SetTokenName(tokenName);
+
+ RA::Debug("PKCS11Obj::Parse", "objcount = %d", objCount);
+
+ int curpos = (int)objOffset;
+ int nread = 0;
+ for (int i = 0; i < objCount; i++) {
+ RA::Debug("PKCS11Obj::Parse", "working on object %d", i);
+ ObjectSpec *objSpec = ObjectSpec::Parse(&data, curpos, &nread);
+ if(!objSpec)
+ continue;
+ o->AddObjectSpec(objSpec);
+
+ unsigned long oid = objSpec->GetObjectID();
+ char b[2];
+
+ b[0] = (char)((oid >> 24) & 0xff);
+ b[1] = (char)((oid >> 16) & 0xff);
+
+ RA::Debug("PKCS11Obj::Parse", "About to parse = %c%c", b[0],b[1]);
+
+ // add corresponding 'C' object for 'c'
+ if (b[0] == 'c') {
+ for (int j = 0; j < objSpec->GetAttributeSpecCount();
+ j++) {
+ AttributeSpec *as = objSpec->GetAttributeSpec(j);
+ if (as->GetAttributeID() == CKA_VALUE) {
+ if (as->GetType() == (BYTE) 0) {
+ Buffer cert = as->GetValue();
+
+ unsigned long certid =
+ ('C' << 24) + (b[1] << 16);
+ ObjectSpec *certSpec =
+ ObjectSpec::ParseFromTokenData(
+ certid, &cert);
+ o->AddObjectSpec(certSpec);
+
+ objSpec->RemoveAttributeSpec(j);
+ break;
+ }
+ }
+ }
+
+ }
+
+ Buffer objSpecData = objSpec->GetData();
+ curpos += nread;
+ }
+
+ return o;
+}
+
+
+void PKCS11Obj::SetFormatVersion(unsigned short v)
+{
+ m_formatVersion = v;
+}
+
+void PKCS11Obj::SetObjectVersion(unsigned short v)
+{
+ m_objectVersion = v;
+}
+
+unsigned short PKCS11Obj::GetFormatVersion()
+{
+ return m_formatVersion;
+}
+
+unsigned short PKCS11Obj::GetObjectVersion()
+{
+ return m_objectVersion;
+}
+
+void PKCS11Obj::SetCUID(Buffer CUID)
+{
+ m_CUID = CUID;
+}
+
+Buffer PKCS11Obj::GetCUID()
+{
+ return m_CUID;
+}
+
+void PKCS11Obj::SetTokenName(Buffer tokenName)
+{
+ m_tokenName = tokenName;
+}
+
+Buffer PKCS11Obj::GetTokenName()
+{
+ return m_tokenName;
+}
+
+int PKCS11Obj::GetObjectSpecCount()
+{
+ for (int i = 0; i < MAX_OBJECT_SPEC; i++) {
+ if (m_objSpec[i] == NULL) {
+ return i;
+ }
+ }
+ return 0;
+}
+
+ObjectSpec *PKCS11Obj::GetObjectSpec(int p)
+{
+ if (p < MAX_OBJECT_SPEC) {
+ if (m_objSpec[p] != NULL) {
+ return m_objSpec[p];
+ }
+ }
+ return NULL;
+}
+
+void PKCS11Obj::AddObjectSpec(ObjectSpec *p)
+{
+ for (int i = 0; i < MAX_OBJECT_SPEC; i++) {
+ if (m_objSpec[i] == NULL) {
+ m_objSpec[i] = p;
+ return;
+ } else {
+ // check duplicated
+ if (p->GetObjectID() == m_objSpec[i]->GetObjectID()) {
+ delete m_objSpec[i];
+ m_objSpec[i] = p;
+ return;
+ }
+ }
+ }
+}
+
+void PKCS11Obj::RemoveObjectSpec(int p)
+{
+ if (p < MAX_OBJECT_SPEC) {
+ if (m_objSpec[p] != NULL) {
+ delete m_objSpec[p];
+ m_objSpec[p] = NULL;
+ }
+ // fill hole
+ int empty = p;
+ for (int x = p+1; x < MAX_OBJECT_SPEC; x++) {
+ if (m_objSpec[x] != NULL) {
+ m_objSpec[empty] = m_objSpec[x];
+ m_objSpec[x] = NULL;
+ empty++;
+ }
+ }
+ }
+}
+
+Buffer PKCS11Obj::GetData()
+{
+ Buffer data = Buffer();
+
+ unsigned short objectOffset = m_tokenName.size() + 2 + 3;
+ data += Buffer(1, (objectOffset >> 8) & 0xff);
+ data += Buffer(1, objectOffset & 0xff);
+ unsigned short objectCount = GetObjectSpecCount();
+ unsigned short objectCountX = objectCount;
+ if (objectCountX == 0) {
+ objectCountX = 0;
+ } else {
+ objectCountX = objectCountX - (objectCountX / 4);
+ }
+ data += Buffer(1, (objectCountX >> 8) & 0xff);
+ data += Buffer(1, objectCountX & 0xff);
+ data += Buffer(1, m_tokenName.size() & 0xff);
+ data += m_tokenName;
+ for (int i = 0; i < objectCount; i++) {
+ ObjectSpec *spec = GetObjectSpec(i);
+ unsigned long objectID = spec->GetObjectID();
+ char c = (char)((objectID >> 24) & 0xff);
+ unsigned long fixedAttrs = spec->GetFixedAttributes();
+ unsigned int xclass = (fixedAttrs & 0x70) >> 4;
+ char cont_id = (char) ((objectID >> 16) & 0xff);
+ unsigned int id = (fixedAttrs & 0x0f);
+ /* locate all certificate objects */
+ if (c == 'c' && xclass == CKO_CERTIFICATE) {
+
+ //We need to use the container id, there may be more than one cert
+ //with the same CKA_ID byte
+
+ id = (unsigned int) (cont_id - '0');
+
+ /* locate the certificate object */
+ for (int u = 0; u < objectCount; u++) {
+ ObjectSpec *u_spec = GetObjectSpec(u);
+ unsigned long u_objectID = u_spec->GetObjectID();
+ char u_c = (char)((u_objectID >> 24) & 0xff);
+ unsigned long u_fixedAttrs =
+ u_spec->GetFixedAttributes();
+ unsigned int u_xclass = (u_fixedAttrs & 0x70) >> 4;
+ unsigned int u_id = (u_fixedAttrs & 0x0f);
+ if (u_c == 'C' && u_xclass == CKO_CERTIFICATE && u_id == id) {
+ AttributeSpec * u_attr =
+ u_spec->GetAttributeSpec(0);
+ AttributeSpec * n_attr = new AttributeSpec();
+ n_attr->SetAttributeID(u_attr->GetAttributeID());
+ n_attr->SetType(u_attr->GetType());
+ n_attr->SetData(u_attr->GetValue());
+ spec->AddAttributeSpec(n_attr);
+ }
+ }
+
+ data += spec->GetData();
+
+ /* locate public object */
+ for (int x = 0; x < objectCount; x++) {
+ ObjectSpec *x_spec = GetObjectSpec(x);
+ unsigned long x_fixedAttrs =
+ x_spec->GetFixedAttributes();
+ unsigned int x_xclass = (x_fixedAttrs & 0x70) >> 4;
+ unsigned int x_id = (x_fixedAttrs & 0x0f);
+ if (x_xclass == CKO_PUBLIC_KEY && x_id == id) {
+ data += x_spec->GetData();
+ }
+ }
+
+ /* locate private object */
+ for (int y = 0; y < objectCount; y++) {
+ ObjectSpec *y_spec = GetObjectSpec(y);
+ unsigned long y_fixedAttrs =
+ y_spec->GetFixedAttributes();
+ unsigned int y_xclass = (y_fixedAttrs & 0x70) >> 4;
+ unsigned int y_id = (y_fixedAttrs & 0x0f);
+ if (y_xclass == CKO_PRIVATE_KEY && y_id == id) {
+ data += y_spec->GetData();
+ }
+ }
+ }
+ }
+
+ Buffer header = Buffer();
+ header += Buffer(1, (m_formatVersion >> 8) & 0xff);
+ header += Buffer(1, m_formatVersion & 0xff);
+ header += Buffer(1, (m_objectVersion >> 8) & 0xff);
+ header += Buffer(1, m_objectVersion & 0xff);
+ header += m_CUID;
+ // COMP_NONE = 0x00
+ // COMP_ZLIB = 0x01
+ unsigned short compressionType = 0x00;
+ header += Buffer(1, (compressionType >> 8) & 0xff);
+ header += Buffer(1, compressionType & 0xff);
+ unsigned short compressedDataSize = data.size();
+ header += Buffer(1, (compressedDataSize >> 8) & 0xff);
+ header += Buffer(1, compressedDataSize & 0xff);
+ unsigned short compressedDataOffset = 20;
+ header += Buffer(1, (compressedDataOffset >> 8) & 0xff);
+ header += Buffer(1, compressedDataOffset & 0xff);
+
+ return header + data;
+}
+
+Buffer PKCS11Obj::GetCompressedData()
+{
+ Buffer data = Buffer();
+ Buffer error = Buffer(0);
+
+ unsigned short objectOffset = m_tokenName.size() + 2 + 3;
+ data += Buffer(1, (objectOffset >> 8) & 0xff);
+ data += Buffer(1, objectOffset & 0xff);
+ unsigned short objectCount = GetObjectSpecCount();
+ unsigned short objectCountX = objectCount;
+ if (objectCountX == 0) {
+ objectCountX = 0;
+ } else {
+ objectCountX = objectCountX - (objectCountX / 4);
+ }
+ data += Buffer(1, (objectCountX >> 8) & 0xff);
+ data += Buffer(1, objectCountX & 0xff);
+ data += Buffer(1, m_tokenName.size() & 0xff);
+ data += m_tokenName;
+ RA::Debug("PKCS11Obj::GetCompressedData", "object count = %d", objectCount);
+ for (int i = 0; i < objectCount; i++) {
+ ObjectSpec *spec = GetObjectSpec(i);
+ unsigned long objectID = spec->GetObjectID();
+ RA::Debug("PKCS11Obj::GetCompressedData", "objid = %lu", objectID);
+ char c = (char)((objectID >> 24) & 0xff);
+ unsigned long fixedAttrs = spec->GetFixedAttributes();
+ unsigned int xclass = (fixedAttrs & 0x70) >> 4;
+ char cont_id = (char) ((objectID >> 16) & 0xff);
+ unsigned int id = (fixedAttrs & 0x0f);
+
+ /* locate all certificate objects */
+ if (c == 'c' && xclass == CKO_CERTIFICATE) {
+
+ //We need to use the container id, there may be more than one cert
+ //with the same CKA_ID byte
+
+ id = (unsigned int) (cont_id - '0');
+
+ /* locate the certificate object */
+ for (int u = 0; u < objectCount; u++) {
+ ObjectSpec *u_spec = GetObjectSpec(u);
+ unsigned long u_objectID = u_spec->GetObjectID();
+ char u_c = (char)((u_objectID >> 24) & 0xff);
+ unsigned long u_fixedAttrs =
+ u_spec->GetFixedAttributes();
+ unsigned int u_xclass = (u_fixedAttrs & 0x70) >> 4;
+ unsigned int u_id = (u_fixedAttrs & 0x0f);
+ char cont_u_id = (char) ((u_objectID >> 16) & 0xff);
+ if (u_c == 'C' && u_xclass == CKO_CERTIFICATE && u_id == id) {
+ RA::Debug("PKCS11Obj::GetCompressedData", "located Certificate id = %d cont_u_id = %c", u_id,cont_u_id);
+ AttributeSpec * u_attr =
+ u_spec->GetAttributeSpec(0);
+ AttributeSpec * n_attr = new AttributeSpec();
+ n_attr->SetAttributeID(u_attr->GetAttributeID());
+ n_attr->SetType(u_attr->GetType());
+ n_attr->SetData(u_attr->GetValue());
+ spec->AddAttributeSpec(n_attr);
+ }
+ }
+
+ /* output certificate attribute object */
+ data += spec->GetData();
+
+ /* locate public object */
+ for (int x = 0; x < objectCount; x++) {
+ ObjectSpec *x_spec = GetObjectSpec(x);
+ unsigned long x_fixedAttrs =
+ x_spec->GetFixedAttributes();
+ unsigned int x_xclass = (x_fixedAttrs & 0x70) >> 4;
+ unsigned int x_id = (x_fixedAttrs & 0x0f);
+ if (x_xclass == CKO_PUBLIC_KEY && x_id == id) {
+ RA::Debug("PKCS11Obj::GetCompressedData", "located Public Key = %d", x_id);
+ data += x_spec->GetData();
+ }
+
+ }
+
+ /* locate private object */
+ for (int y = 0; y < objectCount; y++) {
+ ObjectSpec *y_spec = GetObjectSpec(y);
+ unsigned long y_fixedAttrs =
+ y_spec->GetFixedAttributes();
+ unsigned int y_xclass = (y_fixedAttrs & 0x70) >> 4;
+ unsigned int y_id = (y_fixedAttrs & 0x0f);
+ if (y_xclass == CKO_PRIVATE_KEY && y_id == id) {
+ RA::Debug("PKCS11Obj::GetCompressedData", "located Private Key = %d", y_id);
+ data += y_spec->GetData();
+ }
+ }
+ }
+ }
+
+#define MAX_COMPRESS_SIZE 50000
+ char buffer[MAX_COMPRESS_SIZE];
+ unsigned long len = MAX_COMPRESS_SIZE ;
+
+ int rc = 0;
+
+ RA::Debug("PKCS11Obj", "before compress length = %d", len);
+
+ BYTE *src_buffer = (BYTE*)data;
+
+ RA::Debug("PKCS11Obj", "sizeof src_buffer = %d", sizeof(src_buffer));
+ RA::Debug("PKCS11Obj", "data size = %d", data.size());
+
+ rc = compress((Bytef*)buffer, (uLongf*)&len, (Bytef*)src_buffer,
+ (uLong)data.size());
+
+
+ if(rc != Z_OK) {
+ RA::Debug("PKCS11Obj", "failure compressing data, possibly buffer overrun! Error: %d ",rc);
+
+ return error;
+ }
+
+ RA::Debug("PKCS11Obj", "after compress length = %d", len);
+ RA::Debug("PKCS11Obj", "rc = %d", rc);
+
+ Buffer compressedData = Buffer((BYTE*)buffer, len);
+
+ Buffer header = Buffer();
+ header += Buffer(1, (m_formatVersion >> 8) & 0xff);
+ header += Buffer(1, m_formatVersion & 0xff);
+ header += Buffer(1, (m_objectVersion >> 8) & 0xff);
+ header += Buffer(1, m_objectVersion & 0xff);
+ header += m_CUID;
+ // COMP_NONE = 0x00
+ // COMP_ZLIB = 0x01
+ unsigned short compressionType = 0x01;
+ header += Buffer(1, (compressionType >> 8) & 0xff);
+ header += Buffer(1, compressionType & 0xff);
+ unsigned short compressedDataSize = compressedData.size();
+ header += Buffer(1, (compressedDataSize >> 8) & 0xff);
+ header += Buffer(1, compressedDataSize & 0xff);
+ unsigned short compressedDataOffset = 20;
+ header += Buffer(1, (compressedDataOffset >> 8) & 0xff);
+ header += Buffer(1, compressedDataOffset & 0xff);
+
+ return header + compressedData;
+}
+
diff --git a/base/tps/src/main/RA_Context.cpp b/base/tps/src/main/RA_Context.cpp
new file mode 100644
index 000000000..e3a66cdbb
--- /dev/null
+++ b/base/tps/src/main/RA_Context.cpp
@@ -0,0 +1,56 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "main/RA_Msg.h"
+#include "main/RA_Context.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a session that represents the
+ * connection between RA and the netkey client.
+ */
+TPS_PUBLIC RA_Context::RA_Context ()
+{
+}
+
+/**
+ * Destructs the session.
+ */
+TPS_PUBLIC RA_Context::~RA_Context ()
+{
+}
+
+void RA_Context::LogError(const char *func, int line, const char *fmt,...)
+{
+}
+
+void RA_Context::LogInfo(const char *func, int line, const char *fmt,...)
+{
+}
+
+void RA_Context::InitializationError(const char *func, int line)
+{
+}
+
diff --git a/base/tps/src/main/RA_Msg.cpp b/base/tps/src/main/RA_Msg.cpp
new file mode 100644
index 000000000..d54db69fb
--- /dev/null
+++ b/base/tps/src/main/RA_Msg.cpp
@@ -0,0 +1,45 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "main/RA_Msg.h"
+#include "main/Memory.h"
+
+/**
+ * Constructs a message that represents the
+ * message between RA and the netkey client.
+ */
+RA_Msg::RA_Msg ()
+{
+}
+
+/**
+ * Destructs the message.
+ */
+RA_Msg::~RA_Msg ()
+{
+}
+
+/**
+ * Retrieves the message type.
+ */
+RA_Msg_Type RA_Msg::GetType ()
+{
+ return MSG_UNDEFINED;
+}
diff --git a/base/tps/src/main/RA_Session.cpp b/base/tps/src/main/RA_Session.cpp
new file mode 100644
index 000000000..57f7e4efa
--- /dev/null
+++ b/base/tps/src/main/RA_Session.cpp
@@ -0,0 +1,75 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "engine/RA.h"
+#include "main/RA_Msg.h"
+#include "main/RA_Session.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a session that represents the
+ * connection between RA and the netkey client.
+ */
+TPS_PUBLIC RA_Session::RA_Session ()
+{
+}
+
+/**
+ * Destructs the session.
+ */
+TPS_PUBLIC RA_Session::~RA_Session ()
+{
+}
+
+char *RA_Session::GetRemoteIP()
+{
+ return NULL;
+}
+
+RA_pblock *RA_Session::create_pblock( char *data )
+{
+ // Since this method is virtual,
+ // report an error if no subclass method has been defined.
+ RA::Error( "RA_pblock::find_val",
+ "No subclass method has been defined for this virtual method!" );
+ return NULL;
+}
+
+/**
+ * Reads a message that is sent by
+ * the client.
+ */
+RA_Msg *RA_Session::ReadMsg()
+{
+ return NULL;
+}
+
+/**
+ * Sends a message to the client.
+ */
+void RA_Session::WriteMsg(RA_Msg *msg)
+{
+}
diff --git a/base/tps/src/main/RA_pblock.cpp b/base/tps/src/main/RA_pblock.cpp
new file mode 100644
index 000000000..e59e4c7f1
--- /dev/null
+++ b/base/tps/src/main/RA_pblock.cpp
@@ -0,0 +1,176 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "prmem.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <string.h>
+#include "engine/RA.h"
+#include "main/Buffer.h"
+#include "main/Memory.h"
+#include "main/Util.h"
+#include "main/RA_pblock.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+TPS_PUBLIC RA_pblock::RA_pblock( int tm_nargs, Buffer_nv** tm_nvs )
+{
+ m_nargs = tm_nargs;
+
+ if( tm_nvs != NULL ) {
+ for( int i = 0; i < MAX_NVS; i++ ) {
+ m_nvs[i] = tm_nvs[i];
+ }
+ } else {
+ for( int i = 0; i < MAX_NVS; i++ ) {
+ m_nvs[i] = NULL;
+ }
+ }
+}
+
+TPS_PUBLIC RA_pblock::~RA_pblock()
+{
+ free_pblock();
+}
+
+Buffer_nv **RA_pblock::GetNVs()
+{
+ return m_nvs;
+}
+
+// returns url-decoded value
+TPS_PUBLIC Buffer *RA_pblock::find_val( const char * name )
+{
+ for( int i = 0; i < m_nargs; i++ ) {
+ if( i >= MAX_NVS ) {
+ continue;
+ }
+
+ if( ( m_nvs[i] == NULL ) ||
+ ( m_nvs[i]->name == NULL ) ||
+ ( m_nvs[i]->value == NULL ) ) {
+ continue;
+ }
+
+ if( PR_CompareStrings( m_nvs[i]->name, name ) == 1 ) {
+ return m_nvs[i]->value;
+ }
+ }
+
+ return NULL;
+}
+
+TPS_PUBLIC char *RA_pblock::get_name( int i )
+{
+ return m_nvs[i]->name;
+}
+
+TPS_PUBLIC int RA_pblock::get_num_of_names()
+{
+ return m_nargs;
+}
+
+// returns non-urldecoded value
+TPS_PUBLIC char* RA_pblock::find_val_s( const char * name )
+{
+ RA::Debug( LL_PER_PDU, "RA_pblock::find_val_s",
+ "searching for name= %s", name );
+
+ int end = m_nargs;
+
+ if( MAX_NVS < m_nargs ) {
+ RA::Error( "RA_pblock::find_val_s",
+ "MAX_NVS too small, needs increasing... "
+ "m_nargs= %d, MAX_NVS=%d", m_nargs, MAX_NVS );
+ end = MAX_NVS;
+ }
+
+ for( int i = 0; i < end; i++ ) {
+ if( ( m_nvs[i] == NULL ) ||
+ ( m_nvs[i]->name == NULL ) ||
+ ( m_nvs[i]->value_s == NULL ) ) {
+ continue;
+ }
+
+ /* RA::Debug( LL_PER_PDU, "RA_pblock::find_val_s", */
+ /* "found %s", m_nvs[i]->name ); */
+
+ if( PR_CompareStrings( m_nvs[i]->name, name ) == 1 ) {
+ return m_nvs[i]->value_s;
+ }
+ }
+
+ return NULL;
+}
+
+void RA_pblock::free_pblock()
+{
+ RA::Debug( LL_PER_PDU, "RA_pblock::free_pblock", "in free_pblock" );
+
+ int end = m_nargs;
+
+ if( MAX_NVS < m_nargs ) {
+ RA::Error( "RA_pblock::free_pblock",
+ "MAX_NVS too small, needs increasing... "
+ "m_nargs= %d, MAX_NVS=%d", m_nargs, MAX_NVS );
+ end = MAX_NVS;
+ }
+
+ for( int i = 0; i < end ; i++ ) {
+ if( m_nvs[i] == NULL ) {
+ continue;
+ }
+
+ if( m_nvs[i]->value ) {
+ delete( m_nvs[i]->value );
+ m_nvs[i]->value = NULL;
+ }
+
+ if( m_nvs[i]->value_s ) {
+ PL_strfree( m_nvs[i]->value_s );
+ m_nvs[i]->value_s = NULL;
+ }
+
+ if( m_nvs[i]->name != NULL ) {
+ PL_strfree( m_nvs[i]->name );
+ m_nvs[i]->name = NULL;
+ }
+
+ if( m_nvs[i] != NULL ) {
+ PR_Free( m_nvs[i] );
+ m_nvs[i] = NULL;
+ }
+ }
+
+ RA::Debug( LL_PER_PDU, "RA_pblock::free_pblock", "in free_pblock done" );
+}
+
diff --git a/base/tps/src/main/RollingLogFile.cpp b/base/tps/src/main/RollingLogFile.cpp
new file mode 100644
index 000000000..692a94334
--- /dev/null
+++ b/base/tps/src/main/RollingLogFile.cpp
@@ -0,0 +1,493 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "main/ConfigStore.h"
+#include "engine/RA.h"
+#include "main/RA_Context.h"
+#include "main/LogFile.h"
+#include "main/RollingLogFile.h"
+
+const char *RollingLogFile::CFG_MAX_FILE_SIZE= "maxFileSize";
+const char *RollingLogFile::CFG_ROLLOVER_INTERVAL= "rolloverInterval";
+const char *RollingLogFile::CFG_EXPIRATION_INTERVAL= "expirationTime";
+const int RollingLogFile::MAX_SLEEP = 21600; /* 6 hours */
+
+RollingLogFile::RollingLogFile() :
+ m_max_file_size(2000),
+ m_rollover_interval(0),
+ m_expiration_time(0),
+ m_expiration_sleep_time(0),
+ m_rotation_needed(false),
+ m_rollover_thread(NULL),
+ m_expiration_thread(NULL) { }
+
+int RollingLogFile::startup(RA_Context *ctx, const char* prefix, const char *fname, bool signed_audit)
+{
+ char configname[256];
+
+ if (ctx == NULL) {
+ return PR_FAILURE;
+ }
+
+ if (fname == NULL) {
+ ctx->LogError("RollingLogFile::startup",
+ __LINE__,
+ "startup error, fname is NULL");
+ return PR_FAILURE;
+ }
+
+ if (prefix == NULL) {
+ ctx->LogError("RollingLogFile::startup",
+ __LINE__,
+ "startup error for file %s: prefix is NULL",
+ fname);
+ return PR_FAILURE;
+ }
+
+ ConfigStore* store = RA::GetConfigStore();
+
+ if (store == NULL) {
+ ctx->LogError("RollingLogFile::startup",
+ __LINE__,
+ "Error in obtaining config store to set up rolling log for %s",
+ fname);
+ return PR_FAILURE;
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s", prefix, CFG_MAX_FILE_SIZE);
+ m_max_file_size = store->GetConfigAsInt(configname, 2000); /* 2 MB */
+
+ PR_snprintf((char *)configname, 256, "%s.%s", prefix, CFG_ROLLOVER_INTERVAL);
+ m_rollover_interval = store->GetConfigAsInt(configname, 2592000); /* 30 days */
+
+ PR_snprintf((char *)configname, 256, "%s.%s", prefix, CFG_EXPIRATION_INTERVAL);
+ m_expiration_time = store->GetConfigAsInt(configname, 0); /* disabled, by default */
+
+ m_rollover_thread = (PRThread *) NULL;
+ m_expiration_thread = (PRThread*) NULL;
+ m_rotation_needed = false;
+
+ LogFile::startup(ctx, prefix, fname, signed_audit);
+
+ m_ctx->LogInfo( "RollingLogFile::startup",
+ __LINE__,
+ "thread = 0x%lx: Rolling log file %s startup complete",
+ PR_GetCurrentThread(), m_fname);
+ return PR_SUCCESS;
+}
+
+void RollingLogFile::shutdown()
+{
+ m_ctx->LogInfo( "RollingLogFile::shutdown",
+ __LINE__,
+ "thread = 0x%lx: Rolling log file %s shutting down",
+ PR_GetCurrentThread(), m_fname);
+
+ // interrupt and join threads
+
+ set_expiration_time(0);
+ if (m_expiration_thread != NULL) {
+ PR_Interrupt(m_expiration_thread);
+ PR_JoinThread(m_expiration_thread);
+ m_expiration_thread = (PRThread*) NULL;
+ }
+
+ set_rollover_interval(0);
+ if (m_rollover_thread != NULL) {
+ PR_Interrupt(m_rollover_thread);
+ PR_JoinThread(m_rollover_thread);
+ m_rollover_thread = (PRThread*) NULL;
+ }
+
+ LogFile::shutdown();
+}
+
+int RollingLogFile::write(char *msg) {
+ int status;
+ PR_EnterMonitor(m_monitor);
+
+ if (m_rotation_needed && m_signed && m_signed_log) {
+ rotate();
+ m_rotation_needed = false;
+ }
+
+ status = LogFile::write(msg);
+ if ((get_bytes_written() >= ((int) m_max_file_size*1024)) && (m_max_file_size >0)) {
+ if (! m_signed_log) {
+ rotate();
+ m_rotation_needed = false;
+ } else {
+ m_rotation_needed = true;
+ }
+ }
+ PR_ExitMonitor(m_monitor);
+ return status;
+}
+
+/* this is always called under a monitor */
+void RollingLogFile::rotate() {
+ PRTime now;
+ const char* time_fmt = "%Y%m%d-%H%M%S";
+ char datetime[1024];
+ char backup_fname[1024];
+ char *first_sig = (char *) NULL;
+ PRExplodedTime time;
+ int status;
+
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+ PR_snprintf((char *) backup_fname, 1024, "%s.%s", m_fname, datetime);
+
+ /* close the old file */
+ status = LogFile::close();
+ if (status != PR_SUCCESS) {
+ m_ctx->LogError( "RollingLogFile::rotate",
+ __LINE__,
+ "Failed to close log file %s",
+ m_fname);
+ goto loser;
+ } else {
+ m_fd = (PRFileDesc *) NULL;
+ }
+
+ status = PR_Rename(m_fname, backup_fname);
+ if (status != PR_SUCCESS) {
+ m_ctx->LogError( "RollingLogFile::rotate",
+ __LINE__,
+ "Failed to rename %s to %s",
+ m_fname, backup_fname);
+
+ status = LogFile::open();
+ if (status != PR_SUCCESS) {
+ m_ctx->LogError("RollingLogFile::rotate",
+ __LINE__,
+ "Failed to reopen log file %s",
+ m_fname);
+ }
+ goto loser;
+ }
+
+ /* open the new file */
+ m_fd = PR_Open(m_fname, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE, 440|200);
+ set_bytes_written(0);
+ if (m_fd == NULL) {
+ m_ctx->LogError( "RollingLogFile::rotate",
+ __LINE__,
+ "Failed to reopen log file %s",
+ m_fname);
+ } else {
+ if (m_signed_log) {
+ first_sig = RA::GetAuditSigningMessage("");
+ if (first_sig != NULL) {
+ status = LogFile::write(first_sig);
+ if (status != PR_SUCCESS) {
+ m_ctx->LogError("RollingLogFile::rotate",
+ __LINE__,
+ "Failed to write signature to new (rotated) log file %s",
+ m_fname);
+ } else {
+ status = LogFile::write("\n");
+ if (RA::m_last_audit_signature != NULL) {
+ PR_Free( RA::m_last_audit_signature );
+ }
+ RA::m_last_audit_signature = PL_strdup(first_sig);
+ m_signed = true;
+ }
+ PR_Free(first_sig);
+ } else {
+ m_ctx->LogError("RollingLogFile::rotate",
+ __LINE__,
+ "Failed to generate signature for new (rotated) log file %s",
+ m_fname);
+ }
+ }
+ }
+
+
+ loser:
+ m_rotation_needed = false;
+}
+
+void RollingLogFile::child_init()
+{
+ set_rollover_interval(m_rollover_interval);
+ set_expiration_time(m_expiration_time);
+}
+
+
+void RollingLogFile::set_rollover_interval(int interval)
+{
+ m_rollover_interval = interval;
+ if ((m_rollover_interval>0) && (m_rollover_thread == NULL)) {
+ m_rollover_thread = PR_CreateThread( PR_USER_THREAD,
+ start_rollover_thread,
+ (void *) this,
+ PR_PRIORITY_NORMAL, /* Priority */
+ PR_LOCAL_THREAD, /* Scope */
+ PR_JOINABLE_THREAD, /* State */
+ 0 /* Stack Size */);
+
+ } else {
+ if (m_rollover_thread != NULL) PR_Interrupt(m_rollover_thread);
+ }
+}
+
+void RollingLogFile::start_rollover_thread(void *args) {
+ RollingLogFile *rf;
+ if (args != NULL) {
+ rf = (RollingLogFile *) args;
+ rf->run_rollover_thread();
+ }
+}
+
+void RollingLogFile::run_rollover_thread() {
+
+ m_ctx->LogInfo( "RollingLogFile::run_rollover_thread",
+ __LINE__,
+ "thread = 0x%lx: Rollover thread for %s starting",
+ PR_GetCurrentThread(), m_fname);
+
+ while (m_rollover_interval > 0) {
+ PR_Sleep(PR_SecondsToInterval(m_rollover_interval));
+
+ PR_EnterMonitor(m_monitor);
+ if (m_rollover_interval == 0) break;
+ if (get_bytes_written()>0) {
+ if (! m_signed_log) {
+ rotate();
+ } else {
+ m_rotation_needed = true;
+ }
+ }
+ PR_ExitMonitor(m_monitor);
+ }
+
+ m_ctx->LogInfo( "RollingLogFile::run_rollover_thread",
+ __LINE__,
+ "thread = 0x%lx: Rollover thread for %s ending",
+ PR_GetCurrentThread(), m_fname);
+
+ PR_ExitMonitor(m_monitor);
+}
+
+void RollingLogFile::set_expiration_time(int interval)
+{
+ m_expiration_time = interval;
+ m_expiration_sleep_time = interval;
+
+ if ((interval>0) && (m_expiration_thread == NULL)) {
+ m_expiration_thread = PR_CreateThread( PR_USER_THREAD,
+ start_expiration_thread,
+ (void *) this,
+ PR_PRIORITY_NORMAL, /* Priority */
+ PR_GLOBAL_THREAD, /* Scope */
+ PR_JOINABLE_THREAD, /* State */
+ 0 /* Stack Size */);
+
+ } else {
+ if (m_expiration_thread != NULL) PR_Interrupt(m_expiration_thread);
+ }
+}
+
+void RollingLogFile::start_expiration_thread(void *args) {
+ RollingLogFile *rf;
+ if (args != NULL) {
+ rf = (RollingLogFile *) args;
+ rf->run_expiration_thread();
+ }
+}
+
+/* wait for a bit and then call expire().
+ Note that PR_Sleep() requires a small interval
+ (about 6 hrs to prevent overflow) */
+void RollingLogFile::run_expiration_thread() {
+ int interval;
+
+ m_ctx->LogInfo( "RollingLogFile::run_expiration_thread",
+ __LINE__,
+ "thread = 0x%lx: Expiration thread for %s starting",
+ PR_GetCurrentThread(), m_fname);
+
+ while (m_expiration_time > 0) {
+ expire();
+ while (m_expiration_sleep_time > 0) {
+ if (m_expiration_sleep_time > MAX_SLEEP) {
+ interval = MAX_SLEEP;
+ } else {
+ interval = m_expiration_sleep_time;
+ }
+
+ PR_Sleep(PR_SecondsToInterval(interval));
+ m_expiration_sleep_time = m_expiration_sleep_time - interval;
+
+ if (m_expiration_time == 0) break;
+ }
+
+ if (m_expiration_time == 0) break;
+ }
+
+ m_ctx->LogInfo( "RollingLogFile::run_expiration_thread",
+ __LINE__,
+ "thread = 0x%lx: Expiration thread for %s ending",
+ PR_GetCurrentThread(), m_fname);
+}
+
+/* remove log files that have not been modified in specified time */
+void RollingLogFile::expire() {
+ char basename[256];
+ char dirname[256];
+ char searchStr[256];
+ char full_search_name[256];
+ PRDir *dir;
+ PRDirEntry *entry;
+ PRFileInfo info;
+ PRTime expireTime;
+ PRTime now;
+ PRTime earliestModTime;
+ PRInt64 expiration_interval;
+ PRInt64 usec_per_sec;
+ PRInt64 tmp, tmp1;
+ PRStatus status;
+
+ if (m_expiration_time == 0) {
+ return;
+ }
+
+ if (strrchr(m_fname, '/') != NULL) {
+ PR_snprintf((char *) basename, 256, "%s", strrchr(m_fname, '/') +1);
+ PR_snprintf((char *) dirname, PL_strlen(m_fname) - PL_strlen(basename), "%s", m_fname);
+ PL_strcat(dirname, '\0');
+ } else {
+ PR_snprintf((char *) basename, 256, "%s", m_fname);
+ PR_snprintf((char *) dirname, 256, ".");
+ }
+
+ LL_I2L(tmp, m_expiration_time);
+ LL_I2L(usec_per_sec, PR_USEC_PER_SEC);
+ LL_MUL(expiration_interval, tmp, usec_per_sec);
+
+ now = PR_Now();
+ earliestModTime=now;
+ LL_SUB(expireTime, now, expiration_interval);
+
+ dir = PR_OpenDir(dirname);
+
+ if (dir == NULL) {
+ m_ctx->LogError( "RollingLogFile::expire",
+ __LINE__,
+ "Failed to open log file directory %s",
+ dirname);
+ return;
+ }
+
+ PR_snprintf(searchStr, 256, "%s.", basename);
+
+ while ((entry=PR_ReadDir(dir, PR_SKIP_BOTH)) != NULL) {
+ /* look only for entries of form basename. */
+
+ if (PL_strstr(entry->name, searchStr) != NULL) {
+ PR_snprintf(full_search_name, 256, "%s/%s", dirname, entry->name);
+ status = PR_GetFileInfo(full_search_name, &info);
+
+ if (status != PR_SUCCESS) {
+ m_ctx->LogError( "RollingLogFile::expire",
+ __LINE__,
+ "Failed to get file info for log file %s",
+ full_search_name);
+ // log failure to get file info
+ } else {
+ if (LL_CMP(info.modifyTime,<, expireTime)) {
+ status = PR_Delete(full_search_name);
+ if (status != PR_SUCCESS) {
+ m_ctx->LogError( "RollingLogFile::expire",
+ __LINE__,
+ "Failed to delete expired log file %s",
+ full_search_name);
+ } else {
+ RA::Debug("RollingLogFile::expire", "Deleted expired file: %s",
+ full_search_name);
+ }
+ } else {
+ if (LL_CMP(info.modifyTime,<,earliestModTime)) {
+ earliestModTime = info.modifyTime;
+ }
+ }
+ }
+ }
+ }
+
+ PR_CloseDir(dir);
+
+ /* set next wakeup interval */
+ /* A complicated 64-bit way of calculating :
+ m_expiration_sleep_time = (earliestModTime + m_expiration_time * 1000000 - PR_Now())/1000000;
+ */
+
+ LL_ADD(tmp, earliestModTime, expiration_interval);
+ LL_SUB(tmp1, tmp, now);
+ LL_DIV(tmp, tmp1, usec_per_sec);
+ LL_L2I(m_expiration_sleep_time, tmp);
+
+}
+
+int RollingLogFile::get_rollover_interval() {
+ return m_rollover_interval;
+}
+
+void RollingLogFile::set_rotation_needed(bool val) {
+ m_rotation_needed = val;
+}
+
+bool RollingLogFile::get_rotation_needed() {
+ return m_rotation_needed;
+}
+
+int RollingLogFile::get_expiration_time() {
+ return m_expiration_time;
+}
+
+
diff --git a/base/tps/src/main/SecureId.cpp b/base/tps/src/main/SecureId.cpp
new file mode 100644
index 000000000..46394100e
--- /dev/null
+++ b/base/tps/src/main/SecureId.cpp
@@ -0,0 +1,71 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "plstr.h"
+#include "main/SecureId.h"
+#include "main/Memory.h"
+
+/**
+ * Creates a Secure ID object.
+ */
+SecureId::SecureId (char *value, char *pin)
+{
+ if (value == NULL) {
+ m_value = NULL;
+ } else {
+ m_value = PL_strdup(value);
+ }
+ if (pin == NULL) {
+ m_pin = NULL;
+ } else {
+ m_pin = PL_strdup(pin);
+ }
+}
+
+/**
+ * Destructs a Secure ID object.
+ */
+SecureId::~SecureId ()
+{
+ if( m_value != NULL ) {
+ PL_strfree( m_value );
+ m_value = NULL;
+ }
+ if( m_pin != NULL ) {
+ PL_strfree( m_pin );
+ m_pin = NULL;
+ }
+}
+
+/**
+ * Retrieves the optional Secure ID value.
+ */
+char *SecureId::GetValue()
+{
+ return m_value;
+}
+
+/**
+ * Retrieves the Secure ID PIN.
+ */
+char *SecureId::GetPIN()
+{
+ return m_pin;
+}
diff --git a/base/tps/src/main/Util.cpp b/base/tps/src/main/Util.cpp
new file mode 100644
index 000000000..2849121e4
--- /dev/null
+++ b/base/tps/src/main/Util.cpp
@@ -0,0 +1,1168 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <string.h>
+#include "prmem.h"
+#include "prio.h"
+#include "pk11func.h"
+#include "main/Util.h"
+#include "main/Buffer.h"
+#include "engine/RA.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+TPS_PUBLIC Util::Util ()
+{
+}
+
+TPS_PUBLIC Util::~Util ()
+{
+}
+
+/*
+ * Reads a line from file
+ */
+TPS_PUBLIC int Util::ReadLine(PRFileDesc *f, char *buf, int buf_len, int *removed_return)
+{
+ char *cur = buf;
+ int sum = 0;
+ PRInt32 rc;
+
+ *removed_return = 0;
+ while (1) {
+ rc = PR_Read(f, cur, 1);
+ if (rc == -1 || rc == 0)
+ break;
+ if (*cur == '\r') {
+ continue;
+ }
+ if (*cur == '\n') {
+ *cur = '\0';
+ *removed_return = 1;
+ break;
+ }
+ sum++;
+ cur++;
+ }
+ return sum;
+}
+
+TPS_PUBLIC int Util::ascii2numeric (char c)
+{
+ int num;
+ switch (c) {
+ case '0': case '1': case '2':case '3':case '4':case '5':
+ case '6': case '7': case '8': case '9':
+ num = c - '0';
+ break;
+ default:
+ num = -1;
+ break;
+ }
+ return num;
+}
+
+static BYTE ZERO[1] = { 0 };
+static BYTE ONE[1] = { 1 };
+
+TPS_PUBLIC BYTE* Util::bool2byte(bool b) {
+ if (b)
+ return ONE;
+ else
+ return ZERO;
+}
+
+static int isAlphaNumeric (char ch)
+{
+ return (((ch >='a') && (ch <= 'z')) || /* logical AND &&, OR || */
+ ((ch >='A') && (ch <= 'Z')) ||
+ ((ch >='0') && (ch <= '9')) );
+}
+
+static char bin2hex (BYTE ch)
+{
+ ch = ch & 0x0f;
+ ch += '0';
+ if (ch > '9')
+ ch += 7;
+ return (ch);
+}
+
+static BYTE hex2bin (BYTE ch)
+{
+ if (ch > '9')
+ ch = ch - 'A' + 10;
+ else
+ ch = ch - '0';
+ return (ch);
+}
+
+
+TPS_PUBLIC char *Util::SpecialURLEncode(Buffer &data) {
+ int i;
+ BYTE *buf = (BYTE*)data;
+ int len = (int)data.size();
+ char *ret = NULL;
+ int sum = 0;
+
+ for (i = 0; i < len; i ++) {
+ if (buf[i] == ' ') {
+ sum+=1;
+ } else if (isAlphaNumeric(buf[i])) {
+ sum+=1;
+ } else {
+ sum+=3;
+ }
+ }
+ ret = (char *)PR_Malloc(sum + 1); // allocate more than we may need
+ if (ret == NULL)
+ return NULL;
+ char *cur = ret;
+
+ for (i = 0; i < len; i ++) {
+ if (buf[i] == ' ') {
+ *cur++ = '+';
+ } else if (isAlphaNumeric(buf[i])) {
+ *cur++ = buf[i];
+ } else {
+ *cur++ = '#';
+ *cur++ = bin2hex(buf[i] >> 4);
+ *cur++ = bin2hex(buf[i]);
+ }
+ }
+ *cur = '\0'; // null-terminated
+ return ret;
+}
+
+TPS_PUBLIC char *Util::URLEncode (Buffer &data)
+{
+ int i;
+ BYTE *buf = (BYTE*)data;
+ int len = (int)data.size();
+ int sum = 0;
+
+ for (i = 0; i < len; i ++) {
+ if (buf[i] == ' ') {
+ sum+=1;
+ } else if (isAlphaNumeric(buf[i])) {
+ sum+=1;
+ } else {
+ sum+=3;
+ }
+ }
+ char *ret = (char *)PR_Malloc(sum + 1); // allocate more than we may need
+ char *cur = ret;
+
+ for (i = 0; i < len; i ++) {
+ if (buf[i] == ' ') {
+ *cur++ = '+';
+ } else if (isAlphaNumeric(buf[i])) {
+ *cur++ = buf[i];
+ } else {
+ *cur++ = '%';
+ *cur++ = bin2hex(buf[i] >> 4);
+ *cur++ = bin2hex(buf[i]);
+ }
+ }
+ *cur = '\0'; // null-terminated
+ return ret;
+}
+
+TPS_PUBLIC char *Util::URLEncodeInHex (Buffer &data)
+{
+ int i;
+ BYTE *buf = (BYTE*)data;
+ int len = (int)data.size();
+ int sum = 0;
+
+ for (i = 0; i < len; i ++) {
+ sum+=3;
+ }
+
+ char *ret = (char *)PR_Malloc(sum + 1); // allocate more than we may need
+ char *cur = ret;
+
+ for (i = 0; i < len; i ++) {
+ *cur++ = '%';
+ *cur++ = bin2hex(buf[i] >> 4);
+ *cur++ = bin2hex(buf[i]);
+ }
+ *cur = '\0'; // null-terminated
+ return ret;
+}
+
+TPS_PUBLIC char * Util::URLEncode1(const char *str)
+{
+ int sum = 0;
+ if (str == NULL)
+ return NULL;
+
+ // URL-encode the base-64 encoded public key. This code copies
+ // From input buffer str[] to output buffer encoded_str[]
+ int i = 0;
+ int j = 0;
+ char c;
+
+ i = 0;
+ j = 0;
+ while (1) {
+ c = str[j];
+ if (c == '/') {
+ sum+=3;
+ } else if (c == '=') {
+ sum+=3;
+ } else if (c == '\r') {
+ sum+=3;
+ } else if (c == '\n') {
+ sum+=3;
+ } else if (c == '+') {
+ sum+=3;
+ } else if (c == '&') {
+ sum+=3;
+ } else if (c == ' ') {
+ sum+=1;
+ } else {
+ sum+=1;
+ }
+ if (c == '\0') {
+ break;
+ }
+ i++;
+ j++;
+ }
+
+ char *encoded_str = (char *)PR_Malloc(sum); //allocate more than we may need
+
+ if (encoded_str == NULL)
+ return NULL;
+
+ i = 0;
+ j = 0;
+ while (1) {
+ c = str[j];
+ if (c == '/') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '2';
+ encoded_str[i] = 'F';
+ } else if (c == '&') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '2';
+ encoded_str[i] = '6';
+ } else if (c == '=') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '3';
+ encoded_str[i] = 'D';
+ } else if (c == '\r') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '0';
+ encoded_str[i] = 'D';
+ } else if (c == '\n') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '0';
+ encoded_str[i] = 'A';
+ } else if (c == '+') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '2';
+ encoded_str[i] = 'B';
+ } else if (c == ' ') {
+ encoded_str[i] = '+';
+ } else {
+ encoded_str[i] = str[j];
+ }
+ if (encoded_str[i] == '\0') {
+ break;
+ }
+ i++;
+ j++;
+ }
+ encoded_str[i] = '\0';
+
+ // DONT print, some of the sensitive information get printed.
+ /*
+ RA::Debug(LL_PER_PDU, "CertEnroll::urlEncode",
+ "URL-encoded encoded_str =%s",encoded_str);
+ */
+
+ return encoded_str;
+}
+/**
+ * this urlEncode function takes a char string
+ */
+TPS_PUBLIC char * Util::URLEncode(const char *str)
+{
+ int sum = 0;
+ if (str == NULL)
+ return NULL;
+
+ // URL-encode the base-64 encoded public key. This code copies
+ // From input buffer str[] to output buffer encoded_str[]
+ int i = 0;
+ int j = 0;
+ char c;
+
+ i = 0;
+ j = 0;
+ while (1) {
+ c = str[j];
+ if (c == '/') {
+ sum+=3;
+ } else if (c == '=') {
+ sum+=3;
+ } else if (c == '\r') {
+ sum+=3;
+ } else if (c == '\n') {
+ sum+=3;
+ } else if (c == '+') {
+ sum+=3;
+ } else if (c == ' ') {
+ sum+=1;
+ } else {
+ sum+=1;
+ }
+ if (c == '\0') {
+ break;
+ }
+ i++;
+ j++;
+ }
+
+ char *encoded_str = (char *)PR_Malloc(sum); //allocate more than we may need
+
+ if (encoded_str == NULL)
+ return NULL;
+
+ i = 0;
+ j = 0;
+ while (1) {
+ c = str[j];
+ if (c == '/') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '2';
+ encoded_str[i] = 'F';
+ } else if (c == '=') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '3';
+ encoded_str[i] = 'D';
+ } else if (c == '\r') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '0';
+ encoded_str[i] = 'D';
+ } else if (c == '\n') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '0';
+ encoded_str[i] = 'A';
+ } else if (c == '+') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '2';
+ encoded_str[i] = 'B';
+ } else if (c == ' ') {
+ encoded_str[i] = '+';
+ } else {
+ encoded_str[i] = str[j];
+ }
+ if (encoded_str[i] == '\0') {
+ break;
+ }
+ i++;
+ j++;
+ }
+ encoded_str[i] = '\0';
+
+ // DONT print, some of the sensitive information get printed.
+ /*
+ RA::Debug(LL_PER_PDU, "CertEnroll::urlEncode",
+ "URL-encoded encoded_str =%s",encoded_str);
+ */
+
+ return encoded_str;
+}
+
+/* s Format: 01AFEE */
+TPS_PUBLIC Buffer *Util::Str2Buf (const char *s)
+{
+ int len = strlen(s) / 2;
+ BYTE *ret = (BYTE *)PR_Malloc(len);
+ if (ret == NULL)
+ return NULL;
+
+ for (int i = 0; i < len; i ++) {
+ ret[i] = hex2bin(s[i*2]) * 16 + hex2bin(s[i*2+1]);
+ }
+
+ Buffer *newbuf = new Buffer(ret, len);
+ if( ret != NULL ) {
+ PR_Free( ret );
+ ret = NULL;
+ }
+ return newbuf;
+}
+
+TPS_PUBLIC char *Util::Buffer2String (Buffer &data)
+{
+ int i;
+ BYTE *buf = (BYTE*)data;
+ int len = (int)data.size();
+ int sum = 0;
+
+ for (i = 0; i < len; i ++) {
+ sum+=2;
+ }
+ char *ret = (char *)PR_Malloc(sum + 1); // allocate more than we may need
+ if (ret == NULL)
+ return NULL;
+ char *cur = ret;
+
+ for (i = 0; i < len; i ++) {
+ *cur++ = bin2hex(buf[i] >> 4);
+ *cur++ = bin2hex(buf[i]);
+ }
+ *cur = '\0'; // null-terminated
+ return ret;
+}
+
+TPS_PUBLIC Buffer *Util::SpecialURLDecode(const char *data)
+{
+ int i;
+ Buffer buf;
+ Buffer *ret = NULL;
+ int len = strlen(data);
+ BYTE *tmp = NULL;
+ int sum = 0;
+
+ if (len == 0)
+ return NULL;
+ tmp = (BYTE *)malloc(len);
+ if (tmp == NULL)
+ return NULL;
+ for (i = 0; i < len; i++) {
+ if (data[i] == '+') {
+ tmp[sum++] = ' ';
+ } else if (data[i] == '#') {
+ tmp[sum++] = (hex2bin(data[i+1]) << 4) + hex2bin(data[i+2]);
+ i+=2;
+ } else {
+ tmp[sum++] = (BYTE)data[i];
+ }
+ }
+
+ ret = new Buffer(tmp, sum);
+ if( tmp != NULL ) {
+ free( tmp );
+ tmp = NULL;
+ }
+ return ret;
+}
+
+TPS_PUBLIC Buffer *Util::URLDecode(const char *data)
+{
+ int i;
+ Buffer buf;
+ Buffer *ret = NULL;
+ int len = strlen(data);
+ BYTE *tmp = NULL;
+ int sum = 0;
+
+ if (len == 0)
+ return NULL;
+ tmp = (BYTE *)PR_Malloc(len);
+ for (i = 0; i < len; i++) {
+ if (data[i] == '+') {
+ tmp[sum++] = ' ';
+ } else if (data[i] == '%') {
+ tmp[sum++] = (hex2bin(data[i+1]) << 4) + hex2bin(data[i+2]);
+ i+=2;
+ } else {
+ tmp[sum++] = (BYTE)data[i];
+ }
+ }
+
+ ret = new Buffer(tmp, sum);
+ if( tmp != NULL ) {
+ PR_Free( tmp );
+ tmp = NULL;
+ }
+ return ret;
+}
+
+
+TPS_PUBLIC PRStatus Util::GetRandomChallenge(Buffer &random)
+{
+ PRStatus rv = PR_FAILURE;
+ SECStatus status;
+
+ status = PK11_GenerateRandom(random, random.size());
+ if (status != SECSuccess) {
+ goto loser;
+ }
+ rv = PR_SUCCESS;
+loser:
+ return rv;
+} /* GetRandomChallenge */
+
+#define DES2_WORKAROUND
+
+TPS_PUBLIC PK11SymKey *Util::DiversifyKey(PK11SymKey *masterKey, Buffer &data, PK11SlotInfo *slot)
+{
+ PK11SymKey *key = NULL;
+ PRStatus status = PR_FAILURE ;
+ PK11Context *context = NULL;
+#ifdef DES2_WORKAROUND
+ unsigned char keyData[24];
+#else
+ unsigned char keyData[16];
+#endif
+ SECItem keyItem = { siBuffer, keyData, sizeof keyData };
+ SECStatus s;
+ int i;
+ int len;
+ static SECItem noParams = { siBuffer, 0, 0 };
+
+ /* XXX
+ - masterKey could be just a double-length
+ DES Key (16 bytes).
+ - we may need to add the first 8 bytes to
+ the end to make the key 24 bytes long (DES3 Key)
+ */
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT,
+ masterKey,
+ &noParams);
+ if (!context) goto done;
+
+ /* Part 1 */
+ s = PK11_CipherOp(context, &keyData[0], &len, 8, &((BYTE*)data)[0], 8);
+ if (s != SECSuccess) goto done;
+
+ /* Part 2 */
+ s = PK11_CipherOp(context, &keyData[8], &len, 8, &((BYTE*)data)[8], 8);
+ if (s != SECSuccess) goto done;
+
+#ifdef DES2_WORKAROUND
+ /* Part 3 */
+ for(i = 0;i < 8;i++)
+ {
+ keyData[i+16] = keyData[i];
+ }
+#endif
+
+ key = PK11_ImportSymKeyWithFlags(
+ slot,
+ CKM_DES3_ECB,
+ PK11_OriginGenerated,
+ CKA_ENCRYPT,
+ &keyItem, CKF_SIGN | CKF_ENCRYPT, PR_FALSE, 0);
+
+ status = PR_SUCCESS;
+
+done:
+
+ return key;
+}
+
+TPS_PUBLIC PRStatus Util::ComputeKeyCheck(const Buffer& newKey, Buffer& output)
+{
+ PK11SymKey *key = NULL;
+ PRStatus status = PR_FAILURE ;
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+ PK11Context *context = NULL;
+ SECStatus s = SECFailure;
+ int len;
+ static SECItem noParams = { siBuffer, 0, 0 };
+#ifdef DES2_WORKAROUND
+ unsigned char keyData[24];
+#else
+ unsigned char keyData[16];
+#endif
+ SECItem keyItem = {siBuffer, keyData, sizeof(keyData) };
+ unsigned char value[8];
+ // convert 16-byte to 24-byte triple-DES key
+ memcpy(keyData, newKey, 16);
+#ifdef DES2_WORKAROUND
+ memcpy(keyData+16, newKey, 8);
+#endif
+
+ memset(value, 0, sizeof value);
+
+ key = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
+ PK11_OriginGenerated, CKA_ENCRYPT, &keyItem,
+ CKF_ENCRYPT, PR_FALSE, 0);
+ if( ! key ) {
+ goto done;
+ }
+
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, key,
+ &noParams);
+ if (!context) {
+ goto done;
+ }
+ s = PK11_CipherOp(context, &value[0], &len, 8, &value[0], 8);
+ if (s != SECSuccess) {
+ goto done;
+ }
+
+ output.resize(3);
+ output.replace(0, value, 3);
+
+ status = PR_SUCCESS;
+done:
+ memset(keyData, 0, sizeof keyData);
+ if( context != NULL ) {
+ PK11_DestroyContext( context, PR_TRUE );
+ context = NULL;
+ }
+ if( slot != NULL ) {
+ PK11_FreeSlot( slot );
+ slot = NULL;
+ }
+ if( key != NULL ) {
+ PK11_FreeSymKey( key );
+ key = NULL;
+ }
+
+ return status;
+}
+
+TPS_PUBLIC PRStatus Util::ComputeCryptogram(PK11SymKey *key,
+ const Buffer &card_challenge, const Buffer &host_challenge,
+ Buffer &output)
+{
+ Buffer icv(8, (BYTE)0);
+ Buffer input = card_challenge + host_challenge;
+
+ return ComputeMAC(key, input, icv, output);
+} /* ComputeCryptogram */
+
+
+TPS_PUBLIC PRStatus Util::ComputeMAC(PK11SymKey *key, Buffer &x_input,
+ const Buffer &icv, Buffer &output)
+{
+ PRStatus rv = PR_SUCCESS;
+ PK11Context *context = NULL;
+// NetkeyICV temp;
+ unsigned char result[8];
+ int i;
+ SECStatus s;
+ int len;
+#ifdef USE_DESMAC
+ CK_ULONG macLen = sizeof result;
+ SECItem params = { siBuffer, (unsigned char *)&macLen, sizeof macLen };
+#endif
+ static SECItem noParams = { siBuffer, 0, 0 };
+ static unsigned char macPad[] = {
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ BYTE *input = (BYTE *) x_input;
+ int inputLen = x_input.size();
+
+#ifdef USE_DESMAC
+ context = PK11_CreateContextBySymKey(CKM_DES3_MAC_GENERAL, CKA_SIGN,
+ key, &params);
+ if (!context) { rv = PR_FAILURE; goto done; }
+
+ s = PK11_DigestBegin(context);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+
+ s = PK11_DigestOp(context, icv, 8);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+
+ while(inputLen >= 8)
+ {
+ s = PK11_DigestOp(context, input, 8);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+
+ input += 8;
+ inputLen -= 8;
+ }
+
+ for (i = 0;i < inputLen;i++)
+ {
+ result[i] = input[i];
+ }
+
+ input = macPad;
+ for(;i < 8;i++)
+ {
+ result[i] = *input++;
+ }
+
+ s = PK11_DigestOp(context, result, sizeof result);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+
+ s = PK11_DigestFinal(context, output, (unsigned int *)&len, sizeof output);
+ if (1 != SECSuccess) { rv = PR_FAILURE; goto done; }
+
+#else
+
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, key, &noParams);
+ if (!context) { rv = PR_FAILURE; goto done; }
+
+ memcpy(result, icv, sizeof result);
+
+ /* Process whole blocks */
+ while(inputLen >= 8)
+ {
+ for(i = 0;i < 8;i++)
+ {
+ result[i] ^= input[i];
+ }
+
+ s = PK11_CipherOp(context, result, &len, sizeof result, result, sizeof result);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+ if (len != sizeof result) /* assert? */
+ {
+ //PR_SetError(PR_UNKNOWN_ERROR, 0);
+ rv = PR_FAILURE;
+ goto done;
+ }
+
+ input += 8;
+ inputLen -= 8;
+ }
+
+ /*
+ * Fold in remaining data (if any)
+ * Set i to number of bytes processed
+ */
+ for(i = 0;i < inputLen;i++)
+ {
+ result[i] ^= input[i];
+ }
+
+ /*
+ * Fill remainder of last block. There
+ * will be at least one byte handled here.
+ */
+ input = macPad;
+ while(i < 8)
+ {
+ result[i] ^= *input++;
+ i++;
+ }
+
+ s = PK11_CipherOp(context, result, &len, sizeof result, result, sizeof result);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+ if (len != sizeof result)
+ {
+ //PR_SetError(PR_UNKNOWN_ERROR, 0);
+ rv = PR_FAILURE;
+ goto done;
+ }
+
+ output.replace(0, result, sizeof result);
+#endif
+
+done:
+ if( context != NULL )
+ {
+ PK11_Finalize( context );
+ PK11_DestroyContext( context, PR_TRUE );
+ context = NULL;
+ }
+ memset(result, 0, sizeof result);
+
+ return rv;
+} /* ComputeMAC */
+
+TPS_PUBLIC PK11SymKey *Util::DeriveKey(const Buffer& permKey,
+ const Buffer& hostChallenge,
+ const Buffer& cardChallenge)
+{
+ PK11SymKey *key = NULL, *master = NULL;
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+ PK11Context *context = NULL;
+ unsigned char derivationData[16];
+#ifdef DES2_WORKAROUND
+ unsigned char keyData[24];
+#else
+ unsigned char keyData[16];
+#endif
+ int i;
+ SECStatus s;
+ int len;
+ SECItem keyItem = { siBuffer, keyData, sizeof keyData };
+ static SECItem noParams = { siBuffer, 0, 0 };
+ BYTE masterKeyData[24];
+ SECItem masterKeyItem = {siBuffer, masterKeyData, sizeof(masterKeyData) };
+
+ // convert 16-byte to 24-byte triple-DES key
+ memcpy(masterKeyData, permKey, 16);
+ memcpy(masterKeyData+16, permKey, 8);
+
+ master = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
+ PK11_OriginGenerated, CKA_ENCRYPT, &masterKeyItem,
+ CKF_ENCRYPT, PR_FALSE, 0);
+ if( ! master ) goto done;
+
+ for(i = 0;i < 4;i++)
+ {
+ derivationData[i] = cardChallenge[i+4];
+ derivationData[i+4] = hostChallenge[i];
+ derivationData[i+8] = cardChallenge[i];
+ derivationData[i+12] = hostChallenge[i+4];
+ }
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, master,
+ &noParams);
+ if (!context) goto done;
+
+ /* Part 1 */
+ s = PK11_CipherOp(context, &keyData[0], &len, 8, &derivationData[0], 8);
+ if (s != SECSuccess) goto done;
+
+ /* Part 2 */
+ s = PK11_CipherOp(context, &keyData[8], &len, 8, &derivationData[8], 8);
+ if (s != SECSuccess) goto done;
+
+#ifdef DES2_WORKAROUND
+ /* Part 3 */
+ for(i = 0;i < 8;i++)
+ {
+ keyData[i+16] = keyData[i];
+ }
+#endif
+
+ key = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB, PK11_OriginGenerated,
+ CKA_ENCRYPT, &keyItem, CKF_SIGN | CKF_ENCRYPT, PR_FALSE, 0);
+
+done:
+ memset(keyData, 0, sizeof keyData);
+ if( context != NULL ) {
+ PK11_DestroyContext( context, PR_TRUE );
+ context = NULL;
+ }
+ if( slot != NULL ) {
+ PK11_FreeSlot( slot );
+ slot = NULL;
+ }
+ if( master != NULL ) {
+ PK11_FreeSymKey( master );
+ master = NULL;
+ }
+
+ return key;
+}
+
+/**
+ *
+ * 01
+ * 81 10 B4 BA A8 9A 8C D0 29 2B 45 21 0E (AUTH KEY)
+ * 1B C8 4B 1C 31
+ * 03 8B AF 47
+ * 81 10 B4 BA A8 9A 8C D0 29 2B 45 21 0E (MAC KEY)
+ * 1B C8 4B 1C 31
+ * 03 8B AF 47
+ * 81 10 B4 BA A8 9A 8C D0 29 2B 45 21 0E (KEK KEY)
+ * 1B C8 4B 1C 31
+ * 03 8B AF 47
+ *
+ */
+TPS_PUBLIC PRStatus Util::CreateKeySetData(Buffer &newMasterVer, Buffer &old_kek_key, Buffer &new_auth_key, Buffer &new_mac_key, Buffer &new_kek_key, Buffer &output)
+{
+ PRStatus rv = PR_FAILURE;
+
+ Buffer result;
+
+ Buffer encrypted_auth_key(16);
+ Util::EncryptData(old_kek_key, new_auth_key, encrypted_auth_key);
+ Buffer kc_auth_key(3);
+ Util::ComputeKeyCheck(new_auth_key, kc_auth_key);
+ Buffer encrypted_mac_key(16);
+ Util::EncryptData(old_kek_key, new_mac_key, encrypted_mac_key);
+ Buffer kc_mac_key(3);
+ Util::ComputeKeyCheck(new_mac_key, kc_mac_key);
+ Buffer encrypted_kek_key(16);
+ Util::EncryptData(old_kek_key, new_auth_key, encrypted_kek_key);
+ Buffer kc_kek_key(3);
+ Util::ComputeKeyCheck(new_kek_key, kc_kek_key);
+
+ result = newMasterVer +
+ Buffer(1, (BYTE)0x81) +
+ Buffer(1, (BYTE)0x10) +
+ encrypted_auth_key +
+ Buffer(1, (BYTE)0x03) +
+ kc_auth_key +
+ Buffer(1, (BYTE)0x81) +
+ Buffer(1, (BYTE)0x10) +
+ encrypted_mac_key +
+ Buffer(1, (BYTE)0x03) +
+ kc_mac_key +
+ Buffer(1, (BYTE)0x81) +
+ Buffer(1, (BYTE)0x10) +
+ encrypted_kek_key +
+ Buffer(1, (BYTE)0x03) +
+ kc_kek_key;
+
+ output = result;
+
+ rv = PR_SUCCESS;
+ return rv;
+}
+
+
+/*
+ * for Secure Messaging in Secure Channel
+ */
+TPS_PUBLIC PRStatus Util::EncryptData(PK11SymKey *encSessionKey,
+ Buffer &input, Buffer &output)
+{
+ PRStatus rv = PR_FAILURE;
+ SECStatus s = SECFailure;
+ //static SECItem noParams = { siBuffer, 0, 0 };
+ static unsigned char d[8] = { 0,0,0,0,0,0,0,0 };
+ static SECItem ivParams = { siBuffer, d, 8 };
+ PK11Context *context = NULL;
+ unsigned char result[8];
+ int len;
+ int i;
+
+ /* this is ECB mode
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, encSessionKey,
+ &noParams);
+ */
+ // use CBC mode
+ context = PK11_CreateContextBySymKey(CKM_DES3_CBC, CKA_ENCRYPT, encSessionKey,
+ &ivParams);
+ if (!context) {
+ goto done;
+ }
+
+ for(i = 0;i < (int)input.size();i += 8) {
+ s = PK11_CipherOp(context, result, &len, 8,
+ (unsigned char *)(((BYTE*)input)+i), 8);
+
+ if (s != SECSuccess) {
+ goto done;
+ }
+ output.replace(i, result, 8);
+ }
+
+ rv = PR_SUCCESS;
+// RA::Debug("Util::EncryptData", "success");
+done:
+
+ //#define VRFY_ENC_SESSION_KEY
+ // fix this to use CBC mode later
+#ifdef VRFY_ENC_SESSION_KEY
+ Buffer enc_key_buffer = Buffer((BYTE *) PK11_GetKeyData(encSessionKey)->data, PK11_GetKeyData(encSessionKey)->len);
+ RA::DebugBuffer("Util::EncryptData", "Verifying Encrypted Data",
+ &output);
+ Buffer out1 = Buffer(16, (BYTE)0);
+ PRStatus status = Util::DecryptData(enc_key_buffer, output, out1);
+ RA::DebugBuffer("Util::EncryptData", "Decrypted Data",
+ &out1);
+#endif
+
+
+ if( context != NULL ) {
+ PK11_DestroyContext( context, PR_TRUE );
+ context = NULL;
+ }
+
+ return rv;
+}
+
+
+TPS_PUBLIC PRStatus Util::EncryptData(Buffer &kek_key, Buffer &input, Buffer &output)
+{
+ PRStatus rv = PR_FAILURE;
+
+ PK11SymKey *master = NULL;
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+ PK11Context *context = NULL;
+ int i;
+ SECStatus s = SECFailure;
+ int len;
+ static SECItem noParams = { siBuffer, 0, 0 };
+#ifdef DES2_WORKAROUND
+ unsigned char masterKeyData[24];
+#else
+ unsigned char masterKeyData[16];
+#endif
+ SECItem masterKeyItem = {siBuffer, masterKeyData, sizeof(masterKeyData) };
+ unsigned char result[8];
+
+ // convert 16-byte to 24-byte triple-DES key
+ memcpy(masterKeyData, (BYTE*)kek_key, 16);
+#ifdef DES2_WORKAROUND
+ memcpy(masterKeyData+16, (BYTE*)kek_key, 8);
+#endif
+
+ master = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
+ PK11_OriginGenerated, CKA_ENCRYPT, &masterKeyItem,
+ CKF_ENCRYPT, PR_FALSE, 0);
+ if( ! master ) {
+ goto done;
+ }
+
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, master,
+ &noParams);
+ if (!context) {
+ goto done;
+ }
+
+ for(i = 0;i < (int)input.size();i += 8) {
+ s = PK11_CipherOp(context, result, &len, 8,
+ (unsigned char *)(((BYTE*)input)+i), 8);
+
+ if (s != SECSuccess) {
+ goto done;
+ }
+ output.replace(i, result, 8);
+ }
+
+ rv = PR_SUCCESS;
+
+done:
+
+ memset(masterKeyData, 0, sizeof masterKeyData);
+ if( context != NULL ) {
+ PK11_DestroyContext( context, PR_TRUE );
+ context = NULL;
+ }
+ if( slot != NULL ) {
+ PK11_FreeSlot( slot );
+ slot = NULL;
+ }
+ if( master != NULL ) {
+ PK11_FreeSymKey( master );
+ master = NULL;
+ }
+
+ return rv;
+}
+
+TPS_PUBLIC PRStatus Util::DecryptData(Buffer &kek_key, Buffer &input, Buffer &output)
+{
+ PRStatus rv = PR_FAILURE;
+
+ PK11SymKey *master = NULL;
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+ PK11Context *context = NULL;
+ int i;
+ SECStatus s = SECFailure;
+ int len;
+ static SECItem noParams = { siBuffer, 0, 0 };
+#ifdef DES2_WORKAROUND
+ unsigned char masterKeyData[24];
+#else
+ unsigned char masterKeyData[16];
+#endif
+ SECItem masterKeyItem = {siBuffer, masterKeyData, sizeof(masterKeyData) };
+ unsigned char result[8];
+
+ // convert 16-byte to 24-byte triple-DES key
+ memcpy(masterKeyData, (BYTE*)kek_key, 16);
+#ifdef DES2_WORKAROUND
+ memcpy(masterKeyData+16, (BYTE*)kek_key, 8);
+#endif
+
+ master = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
+ PK11_OriginGenerated, CKA_DECRYPT, &masterKeyItem,
+ CKF_DECRYPT, PR_FALSE, 0);
+ if( ! master ) {
+ goto done;
+ }
+
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_DECRYPT, master,
+ &noParams);
+ if (!context) {
+ goto done;
+ }
+
+ for(i = 0;i < (int)input.size();i += 8) {
+ s = PK11_CipherOp(context, result, &len, 8,
+ (unsigned char *)(((BYTE *)input)+i), 8);
+
+ if (s != SECSuccess) {
+ goto done;
+ }
+ output.replace(i, result, 8);
+ }
+
+ rv = PR_SUCCESS;
+
+done:
+
+ memset(masterKeyData, 0, sizeof masterKeyData);
+ if( context != NULL ) {
+ PK11_DestroyContext( context, PR_TRUE );
+ context = NULL;
+ }
+ if( slot != NULL ) {
+ PK11_FreeSlot( slot );
+ slot = NULL;
+ }
+ if( master != NULL ) {
+ PK11_FreeSymKey( master );
+ master = NULL;
+ }
+
+ return rv;
+}
+
+// this one takes PK11SymKey instead
+TPS_PUBLIC PRStatus Util::DecryptData(PK11SymKey* enc_key, Buffer &input, Buffer &output)
+{
+ PRStatus rv = PR_FAILURE;
+
+ PK11Context *context = NULL;
+ int i;
+ SECStatus s = SECFailure;
+ int len;
+ // static SECItem noParams = { siBuffer, 0, 0 };
+ static unsigned char d[8] = { 0,0,0,0,0,0,0,0 };
+ static SECItem ivParams = { siBuffer, d, 8 };
+ unsigned char result[8];
+
+ if( ! enc_key ) {
+ goto done;
+ }
+
+ context = PK11_CreateContextBySymKey(CKM_DES3_CBC, CKA_DECRYPT, enc_key,
+ &ivParams);
+ if (!context) {
+ goto done;
+ }
+
+ for(i = 0;i < (int)input.size();i += 8) {
+ s = PK11_CipherOp(context, result, &len, 8,
+ (unsigned char *)(((BYTE *)input)+i), 8);
+
+ if (s != SECSuccess) {
+ goto done;
+ }
+ output.replace(i, result, 8);
+ }
+
+ rv = PR_SUCCESS;
+
+done:
+
+ if( context != NULL ) {
+ PK11_DestroyContext( context, PR_TRUE );
+ context = NULL;
+ }
+
+ return rv;
+}
+
diff --git a/base/tps/src/modules/CMakeLists.txt b/base/tps/src/modules/CMakeLists.txt
new file mode 100644
index 000000000..b72b73c0c
--- /dev/null
+++ b/base/tps/src/modules/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_subdirectory(tokendb)
+add_subdirectory(tps)
diff --git a/base/tps/src/modules/tokendb/CMakeLists.txt b/base/tps/src/modules/tokendb/CMakeLists.txt
new file mode 100644
index 000000000..7b6edae91
--- /dev/null
+++ b/base/tps/src/modules/tokendb/CMakeLists.txt
@@ -0,0 +1,48 @@
+project(tokendb_module CXX)
+
+set(TOKENDB_PRIVATE_INCLUDE_DIRS
+ ${TOKENDB_PUBLIC_INCLUDE_DIRS}
+ ${CMAKE_BINARY_DIR}
+ ${NSPR_INCLUDE_DIRS}
+ ${NSS_INCLUDE_DIRS}
+ ${APR_INCLUDE_DIRS}
+ ${SVRCORE_INCLUDE_DIRS}
+ ${LDAP_INCLUDE_DIRS}
+)
+
+set(TOKENDB_MODULE
+ tokendb_module
+ CACHE INTERNAL "tokendb apache module"
+)
+
+set(TOKENDB_LINK_LIBRARIES
+ ${TOKENDB_SHARED_LIBRARY}
+ ${NSPR_LIBRARIES}
+ ${NSS_LIBRARIES}
+ ${APR_LIBRARIES}
+ ${SVRCORE_LIBRARIES}
+ ${LDAP_LIBRARIES}
+)
+
+set(tokendb_module_SRCS
+ mod_tokendb.cpp
+)
+
+include_directories(${TOKENDB_PRIVATE_INCLUDE_DIRS})
+
+add_library(${TOKENDB_MODULE} MODULE ${tokendb_module_SRCS})
+target_link_libraries(${TOKENDB_MODULE} ${TOKENDB_LINK_LIBRARIES})
+
+set_target_properties(${TOKENDB_MODULE}
+ PROPERTIES
+ OUTPUT_NAME
+ mod_tokendb
+ PREFIX ""
+)
+
+install(
+ TARGETS
+ ${TOKENDB_MODULE}
+ DESTINATION
+ ${LIB_INSTALL_DIR}/httpd/modules
+)
diff --git a/base/tps/src/modules/tokendb/mod_tokendb.cpp b/base/tps/src/modules/tokendb/mod_tokendb.cpp
new file mode 100644
index 000000000..3e411c99a
--- /dev/null
+++ b/base/tps/src/modules/tokendb/mod_tokendb.cpp
@@ -0,0 +1,7756 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifdef XP_WIN32
+#define TOKENDB_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TOKENDB_PUBLIC
+#endif /* !XP_WIN32 */
+
+
+
+/* _________________________________________________________________
+**
+** Tokendb Module Headers
+** _________________________________________________________________
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef XP_WIN32
+#include <unistd.h> /* sleep */
+#else /* XP_WIN32 */
+#include <windows.h>
+#endif /* XP_WIN32 */
+
+#include "nspr.h"
+#include "prio.h"
+#include "plstr.h"
+#include "prmem.h"
+#include "prtime.h"
+#include "prthread.h"
+#include "cert.h"
+#include "regex.h"
+#include "nss3/base64.h"
+
+#include "httpd/httpd.h"
+#include "httpd/http_config.h"
+#include "httpd/http_log.h"
+#include "httpd/http_protocol.h"
+#include "httpd/http_main.h"
+#include "httpd/http_request.h"
+
+#include "apr_strings.h"
+
+#include "cms/CertEnroll.h"
+#include "engine/RA.h"
+#include "tus/tus_db.h"
+#include "processor/RA_Processor.h"
+#include "selftests/SelfTest.h"
+
+extern TOKENDB_PUBLIC char *nss_var_lookup( apr_pool_t *p, server_rec *s,
+ conn_rec *c, request_rec *r,
+ char *var );
+
+
+/* _________________________________________________________________
+**
+** Tokendb Module Definitions
+** _________________________________________________________________
+*/
+
+#define JS_START "<SCRIPT LANGUAGE=\"JavaScript\">\n<!--\n"
+#define JS_STOP "//-->\n</SCRIPT>\n"
+#define CMS_TEMPLATE_TAG "<CMS_TEMPLATE>"
+
+#define MAX_INJECTION_SIZE 5120
+#define MAX_OVERLOAD 20
+#define LOW_INJECTION_SIZE 2048
+#define SHORT_LEN 256
+
+#define BASE64_HEADER "-----BEGIN CERTIFICATE-----\n"
+#define BASE64_FOOTER "-----END CERTIFICATE-----\n"
+
+#define TOKENDB_OPERATORS_IDENTIFIER "TUS Operators"
+#define TOKENDB_AGENTS_IDENTIFIER "TUS Agents"
+#define TOKENDB_ADMINISTRATORS_IDENTIFIER "TUS Administrators"
+
+#define OP_PREFIX "op.format"
+
+#define NUM_PROFILES_TO_DISPLAY 15
+#define NUM_ENTRIES_PER_PAGE 25
+#define MAX_LEN_PROFILES_TO_DISPLAY 1000
+
+#define error_out(msg1,msg2) \
+ PR_snprintf(injection, MAX_INJECTION_SIZE, \
+ "%s%s%s%s%s", JS_START, "var error = \"Error: ", \
+ msg1,"\";\n", JS_STOP ); \
+ buf = getData( errorTemplate, injection ); \
+ ap_log_error( ( const char * ) "tus", __LINE__, \
+ APLOG_ERR, 0, rq->server, \
+ ( const char * ) msg2 ); \
+ ( void ) ap_rwrite( ( const void * ) buf, PL_strlen( buf ), rq );
+
+#define ldap_error_out(msg1,msg2) \
+ PR_snprintf( injection, MAX_INJECTION_SIZE, \
+ "%s%s%s%s%s%s", JS_START, \
+ "var error = \"", msg1, \
+ ldap_err2string( status ), \
+ "\";\n", JS_STOP ); \
+ buf = getData( errorTemplate, injection ); \
+ ap_log_error( ( const char * ) "tus", __LINE__, \
+ APLOG_ERR, 0, rq->server, \
+ ( const char * ) msg2, \
+ ldap_err2string( status ) ); \
+ ( void ) ap_rwrite( ( const void * ) buf, PL_strlen( buf ), rq );
+
+#define post_ldap_error(msg) \
+ ap_log_error( ( const char * ) "tus", __LINE__, \
+ APLOG_ERR, 0, rq->server, \
+ (const char *) msg, ldap_err2string( status ) );
+
+#define get_cfg_string(cname, vname) \
+ if( ( s = PL_strstr( buf, cname ) ) != NULL ) { \
+ s += PL_strlen( cname ); \
+ v = s; \
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && \
+ ( PRUint32 ) ( s - buf ) < size ) { \
+ s++; \
+ } \
+ n = s - v; \
+ s = PL_strndup( v, n ); \
+ if( s != NULL ) { \
+ if( vname != NULL ) { \
+ PL_strfree( vname ); \
+ vname = NULL; \
+ } \
+ vname = s; \
+ } else { \
+ do_free(buf); \
+ return 0; \
+ } \
+ }
+
+#define get_cfg_int(cname, vname) \
+ if( ( s = PL_strstr( buf, cname ) ) != NULL ) { \
+ s += PL_strlen( cname ); \
+ v = s; \
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && \
+ ( PRUint32 ) ( s - buf ) < size ) { \
+ s++; \
+ } \
+ n = s - v; \
+ s = PL_strndup( v, n ); \
+ if( s != NULL ) { \
+ char *endptr = NULL; \
+ errno = 0; \
+ vname = strtol(s, &endptr, 10);\
+ if ((errno == ERANGE && (vname == LONG_MAX || vname == LONG_MIN)) \
+ || (endptr == s)) { \
+ vname=0; \
+ } \
+ do_free(s); \
+ } else { \
+ do_free(buf); \
+ do_free(s); \
+ return 0; \
+ } \
+ }
+
+/**
+ * Provide reasonable defaults for some defines.
+ */
+enum MOD_TOKENDB_BOOL {
+ MOD_TOKENDB_FALSE = 0,
+ MOD_TOKENDB_TRUE = 1
+};
+
+#define MAX_TOKEN_UI_STATE 6
+
+enum token_ui_states {
+ TOKEN_UNINITIALIZED = 0,
+ TOKEN_DAMAGED =1,
+ TOKEN_PERM_LOST=2,
+ TOKEN_TEMP_LOST=3,
+ TOKEN_FOUND =4,
+ TOKEN_TEMP_LOST_PERM_LOST =5,
+ TOKEN_TERMINATED = 6
+};
+
+/* _________________________________________________________________
+**
+** Tokendb Module Request Data
+** _________________________________________________________________
+*/
+
+#ifdef DEBUG_Tokendb
+static PRFileDesc *debug_fd = NULL;
+#endif
+
+static char *templateDir = NULL;
+static char *errorTemplate = NULL;
+static char *indexTemplate = NULL;
+static char *indexAdminTemplate = NULL;
+static char *indexOperatorTemplate = NULL;
+static char *newTemplate = NULL;
+static char *searchTemplate = NULL;
+static char *searchResultTemplate = NULL;
+static char *searchAdminTemplate = NULL;
+static char *searchAdminResultTemplate = NULL;
+static char *searchActivityTemplate = NULL;
+static char *searchCertificateTemplate = NULL;
+static char *searchCertificateResultTemplate = NULL;
+static char *searchActivityResultTemplate = NULL;
+static char *searchActivityAdminTemplate = NULL;
+static char *searchActivityAdminResultTemplate = NULL;
+static char *editTemplate = NULL;
+static char *editResultTemplate = NULL;
+static char *showTemplate = NULL;
+static char *showCertTemplate = NULL;
+static char *showAdminTemplate = NULL;
+static char *deleteTemplate = NULL;
+static char *doTokenTemplate = NULL;
+static char *doTokenConfirmTemplate = NULL;
+static char *revokeTemplate = NULL;
+static char *addResultTemplate = NULL;
+static char *deleteResultTemplate = NULL;
+static char *editUserTemplate = NULL;
+static char *searchUserResultTemplate = NULL;
+static char *searchUserTemplate = NULL;
+static char *newUserTemplate = NULL;
+static char *userDeleteTemplate = NULL;
+static char *auditAdminTemplate = NULL;
+static char *selfTestTemplate = NULL;
+static char *selfTestResultsTemplate = NULL;
+static char *agentSelectConfigTemplate = NULL;
+static char *selectConfigTemplate = NULL;
+static char *agentViewConfigTemplate = NULL;
+static char *editConfigTemplate = NULL;
+static char *confirmConfigChangesTemplate = NULL;
+static char *addConfigTemplate = NULL;
+static char *confirmDeleteConfigTemplate = NULL;
+static int maxSizeLimit = 0;
+static int defaultSizeLimit = 0;
+static int maxTimeLimit = 0;
+static int defaultTimeLimit = 0;
+static int pwLength = 0;
+
+static char *profileList = NULL;
+static char *transitionList = NULL;
+
+static int sendInPieces = 0;
+static RA_Processor m_processor;
+
+
+
+/* _________________________________________________________________
+**
+** Tokendb Module Command Data
+** _________________________________________________________________
+*/
+
+static const char MOD_TOKENDB_CONFIGURATION_FILE_PARAMETER[] =
+"TokendbConfigPathFile";
+
+static const char MOD_TOKENDB_CONFIGURATION_FILE_USAGE[] =
+"Tokendb Configuration Filename prefixed by a complete path, or\n"
+"a path that is relative to the Apache server root.";
+
+
+
+/* _________________________________________________________________
+**
+** Tokendb Module Server Configuration Creation Data
+** _________________________________________________________________
+*/
+
+typedef struct {
+ char *Tokendb_Configuration_File;
+ MOD_TOKENDB_BOOL enabled;
+} mod_tokendb_server_configuration;
+
+
+
+/* _________________________________________________________________
+**
+** Tokendb Module Registration Data
+** _________________________________________________________________
+*/
+
+#define MOD_TOKENDB_CONFIG_KEY tokendb_module
+
+static const char MOD_TOKENDB_CONFIG_KEY_NAME[] = "tokendb_module";
+
+extern module TOKENDB_PUBLIC MOD_TOKENDB_CONFIG_KEY;
+
+
+
+/* _________________________________________________________________
+**
+** Tokendb Module Helper Functions
+** _________________________________________________________________
+*/
+
+/**
+ * Terminate Apache
+ */
+void tokendb_die( void )
+{
+ /*
+ * This is used for fatal errors and here
+ * it is common module practice to really
+ * exit from the complete program.
+ */
+ exit( 1 );
+}
+
+
+void tokendbDebug( const char* msg )
+{
+ RA::Debug( "mod_tokendb::mod_tokendb_handler",
+ msg);
+#if 0
+ if( debug_fd ) {
+ PR_fprintf( debug_fd, msg );
+ }
+#endif
+}
+
+inline void do_free(char * buf)
+{
+ if (buf != NULL) {
+ PR_Free(buf);
+ buf = NULL;
+ }
+}
+
+inline void do_strfree(char *buf)
+{
+ if (buf != NULL) {
+ PL_strfree(buf);
+ buf = NULL;
+ }
+}
+
+inline bool valid_berval(struct berval** b)
+{
+ return (b != NULL) && (b[0] != NULL) && (b[0]->bv_val != NULL);
+}
+
+/**
+ * unencode
+ * summary: takes a URL encoded string and returns an unencoded string
+ * : must be freed by caller
+ */
+char *unencode(const char *src)
+{
+ char *dest = NULL;
+ char *dp = NULL;
+ dest = (char *) PR_Malloc(PL_strlen(src)* sizeof(char) + 1);
+ dp = dest;
+ for(; PL_strlen(src) > 0 ; src++, dp++)
+ if(*src == '+')
+ *dp = ' ';
+ else if(*src == '%') {
+ int code;
+ if (sscanf(src+1, "%2x", &code) != 1) code = '?';
+ *dp = code;
+ src +=2;
+ }
+ else
+ *dp = *src;
+ *dp = '\0';
+ return dest;
+}
+
+/**
+ * get_field
+ * summary: used to parse query strings in get and post requests
+ * : returns the value of the parameter following fname, in query string s.
+ * must be freed by caller.
+ * example: get_field("op=hello&name=foo&title=bar", "name=") returns foo
+ */
+char *get_field( char *s, const char* fname, int len)
+{
+ char *end = NULL;
+ char *tmp = NULL;
+ char *ret = NULL;
+ int n;
+
+ if( ( s = PL_strstr( s, fname ) ) == NULL ) {
+ return NULL;
+ }
+
+ s += strlen(fname);
+ end = PL_strchr( s, '&' );
+
+ if( end != NULL ) {
+ n = end - s;
+ } else {
+ n = PL_strlen( s );
+ }
+
+ if (n == 0) {
+ return NULL;
+ } else if (n > len) {
+ /* string too long */
+ return NULL;
+ } else {
+ tmp = (char *) PL_strndup(s,n);
+ ret = unencode(tmp);
+ do_free(tmp);
+ return ret;
+ }
+}
+
+/**
+ * get_post_field
+ * summary: get value from apr_table containing HTTP-Post values
+ * params: post - apr_table with post data
+ * : fname = name of post-field
+ */
+char *get_post_field( apr_table_t *post, const char *fname, int len)
+{
+ char *ret = NULL;
+ if (post) {
+ ret = unencode(apr_table_get(post, fname));
+ if ((ret != NULL) && ((int) PL_strlen(ret) > len)) {
+ PR_Free(ret);
+ return NULL;
+ } else {
+ return ret;
+ }
+ } else {
+ return NULL;
+ }
+}
+
+char *get_post_field_s( apr_table_t *post, const char *fname)
+{
+ char *ret = NULL;
+ if (post) {
+ ret = unencode(apr_table_get(post, fname));
+ return ret;
+ } else {
+ return NULL;
+ }
+}
+
+/**
+ * similar to get_post_field - but returns the original post data
+ * without unencoding - used for userCert
+ */
+char *get_encoded_post_field(apr_table_t *post, const char *fname, int len)
+{
+ char *ret = NULL;
+ if (post) {
+ ret = PL_strdup(apr_table_get(post, fname));
+ if ((ret != NULL) && ((int) PL_strlen(ret) > len)) {
+ PL_strfree(ret);
+ return NULL;
+ } else {
+ return ret;
+ }
+ } else {
+ return NULL;
+ }
+}
+
+/**
+ * match_profile
+ * summary: returns true if the profile passed in matches an existing profile
+ * in the profileList read from CS.cfg. Called when confirming that
+ * a user entered "other profile" is a real profile
+ */
+bool match_profile(const char *profile)
+{
+ return RA::match_comma_list(profile, profileList);
+}
+
+int get_token_ui_state(char *state, char *reason)
+{
+ int ret = 0;
+ if (strcmp(state, STATE_UNINITIALIZED) == 0) {
+ ret = TOKEN_UNINITIALIZED;
+ } else if (strcasecmp(state, STATE_ACTIVE) == 0) {
+ ret = TOKEN_FOUND;
+ } else if (strcasecmp(state, STATE_LOST) == 0) {
+ if (strcasecmp(reason, "keyCompromise") == 0) {
+ /* perm lost or temp -> perm lost */
+ ret = TOKEN_PERM_LOST;
+ } else if (strcasecmp(reason, "destroyed") == 0) {
+ ret = TOKEN_DAMAGED;
+ } else if (strcasecmp(reason, "onHold") == 0) {
+ ret = TOKEN_TEMP_LOST;
+ }
+ } else if (strcasecmp(state, "terminated") == 0) {
+ ret = TOKEN_TERMINATED;
+ } else {
+ /* state is disabled or otherwise : what to do here? */
+ ret = TOKEN_PERM_LOST;
+ }
+ return ret;
+}
+
+bool transition_allowed(int oldState, int newState)
+{
+ /* parse the allowed transitions string and look for old:new */
+ char search[128];
+
+ if (transitionList == NULL) return true;
+
+ PR_snprintf(search, 128, "%d:%d", oldState, newState);
+ return RA::match_comma_list(search, transitionList);
+}
+
+void add_allowed_token_transitions(int token_ui_state, char *injection)
+{
+ bool first = true;
+ int i=1;
+ char state[128];
+
+ sprintf(state, "var allowed_transitions=\"");
+ PL_strcat(injection, state);
+ for (i=1; i<=MAX_TOKEN_UI_STATE; i++) {
+ if (transition_allowed(token_ui_state, i)) {
+ if (first) {
+ sprintf(state, "%d", i);
+ first = false;
+ } else {
+ sprintf(state, ",%d", i);
+ }
+ PL_strcat(injection, state);
+ }
+ }
+ PL_strcat(injection, "\";\n");
+}
+
+char *getTemplateFile( char *fileName, int *injectionTagOffset )
+{
+ char *buf = NULL;
+ char *s = NULL;
+ PRFileDesc *fd = NULL;
+ char fullFileName[4096];
+ PRFileInfo info;
+ PRUint32 fileSize;
+ PRUint32 size;
+ PRInt32 k, n;
+
+ *injectionTagOffset = -1;
+
+ PR_snprintf( fullFileName, 4096, "%s/%s", templateDir, fileName );
+
+ if( PR_GetFileInfo( fullFileName, &info ) != PR_SUCCESS ) {
+ return buf;
+ }
+
+ fileSize = info.size;
+ size = fileSize + 1;
+
+ buf = ( char * ) PR_Malloc( size );
+ if( buf == NULL ) {
+ return buf;
+ }
+
+ fd = PR_Open( fullFileName, PR_RDONLY, 00400 );
+ if( fd == NULL ) {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return NULL;
+ }
+
+ k = 0;
+ while( ( n = PR_Read( fd, &buf[k], fileSize-k ) ) > 0 ) {
+ k += n;
+ if( ( PRUint32 ) k >= fileSize ) {
+ break;
+ }
+ }
+
+ if( fd != NULL ) {
+ PR_Close( fd );
+ fd = NULL;
+ }
+
+ if( n < 0 || ( ( PRUint32 ) k > fileSize ) ) {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return NULL;
+ }
+
+ buf[k] = '\0';
+
+ if( ( s = PL_strstr( buf, CMS_TEMPLATE_TAG ) ) != NULL ) {
+ *injectionTagOffset = PL_strlen( buf ) - PL_strlen( s );
+ }
+
+ return buf;
+}
+
+
+char *getData( char *fileName, char *injection )
+{
+ char *buf = NULL;
+ char *s = NULL;
+ PRFileDesc *fd = NULL;
+ char fullFileName[4096];
+ PRFileInfo info;
+ PRUint32 fileSize;
+ PRUint32 size, len;
+ PRUint32 injectionSize;
+ PRInt32 k, n;
+
+ PR_snprintf( fullFileName, 4096, "%s/%s", templateDir, fileName );
+
+ if( PR_GetFileInfo( fullFileName, &info ) != PR_SUCCESS ) {
+ return buf;
+ }
+
+ fileSize = info.size;
+ size = fileSize;
+ injectionSize = 0;
+
+ if( injection != NULL && PL_strlen( injection ) > 0 ) {
+ injectionSize = PL_strlen( injection );
+ size += injectionSize;
+ }
+
+ size++;
+
+ buf = ( char * ) PR_Malloc( size );
+ if( buf == NULL ) {
+ return buf;
+ }
+
+ fd = PR_Open( fullFileName, PR_RDONLY, 00400 );
+ if( fd == NULL ) {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return NULL;
+ }
+
+ k = 0;
+ while( ( n = PR_Read( fd, &buf[k], fileSize-k ) ) > 0 ) {
+ k += n;
+ if( ( PRUint32 ) k >= fileSize ) {
+ break;
+ }
+ }
+
+ if( fd != NULL ) {
+ PR_Close( fd );
+ fd = NULL;
+ }
+
+ if( n < 0 || ( ( PRUint32 ) k > fileSize ) ) {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return NULL;
+ }
+
+ buf[k] = '\0';
+ if( injectionSize > 0 ) {
+ if( ( s = PL_strstr( buf, CMS_TEMPLATE_TAG ) ) != NULL ) {
+ len = PL_strlen( s ) - PL_strlen( CMS_TEMPLATE_TAG );
+ memmove( s + injectionSize,
+ s + PL_strlen( CMS_TEMPLATE_TAG ),
+ len + 1 );
+ memcpy( s, injection, injectionSize );
+ }
+ }
+
+ return buf;
+}
+
+/**
+ * returns string with special characters escaped. Caller must free the contents
+ */
+char *escapeSpecialChars(char* src)
+{
+ char *ret;
+ int i =0;
+
+ if (PL_strlen(src) == 0) {
+ return PL_strdup(src);
+ }
+ ret = (char *)PR_Malloc(PL_strlen(src) * 2 + 1);
+
+ while (*src != '\0') {
+ if (*src == '"') {
+ ret[i++] = '\\';
+ ret[i++] = '"';
+ } else {
+ ret[i++] = *src;
+ }
+ src++;
+ }
+ ret[i]='\0';
+ return ret;
+}
+
+void getCertificateFilter( char *filter, char *query )
+{
+ char *uid = NULL;
+ char *tid = NULL;
+ char *end = NULL;
+ char *cn = NULL;
+ char *view = NULL;
+ int len = 0;
+ int i = 0;
+
+ tid = PL_strstr( query, "tid=" );
+ uid = PL_strstr( query, "uid=" );
+ cn = PL_strstr( query, "cn=" );
+ view = PL_strstr( query, "op=view" );
+
+ if( view == NULL ) {
+ view = PL_strstr( query, "op=show" );
+ }
+
+ filter[0] = '\0';
+
+ if( tid == NULL && uid == NULL && cn == NULL ) {
+ PL_strcat( filter, "(tokenID=*)" );
+ return;
+ }
+
+ if( tid != NULL && uid != NULL && view != NULL ) {
+ PL_strcat( filter, "(&" );
+ }
+
+ if( tid != NULL ) {
+ PL_strcat( filter, "(tokenID=" );
+ end = PL_strchr( tid, '&' );
+ len = PL_strlen( filter );
+ if( end != NULL ) {
+ i = end - tid - 4;
+
+ if( i > 0 ) {
+ memcpy( filter+len, tid+4, i );
+ }
+ filter[len+i] = '\0';
+ } else {
+ PL_strcat( filter, tid+4 );
+ }
+ if( view != NULL ) {
+ PL_strcat( filter, "*)" );
+ } else {
+ PL_strcat( filter, ")" );
+ }
+ }
+
+ if( uid != NULL && view != NULL ) {
+ PL_strcat( filter, "(tokenUserID=" );
+ end = PL_strchr( uid, '&' );
+ len = PL_strlen( filter );
+ if( end != NULL ) {
+ i = end - uid - 4;
+ if( i > 0 ) {
+ memcpy( filter+len, uid+4, i );
+ }
+
+ filter[len+i] = '\0';
+ } else {
+ PL_strcat( filter, uid+4 );
+ }
+
+ PL_strcat( filter, "*)" );
+ /* PL_strcat( filter, ")" ); */
+ }
+
+ if( cn != NULL ) {
+ PL_strcat( filter, "(cn=" );
+ end = PL_strchr( cn, '&' );
+ len = PL_strlen( filter );
+ if( end != NULL ) {
+ i = end - cn - 3;
+ if( i > 0 ) {
+ memcpy( filter+len, cn+3, i );
+ }
+
+ filter[len+i] = '\0';
+ } else {
+ PL_strcat( filter, cn+3 );
+ }
+
+ PL_strcat( filter, "*)" );
+ /* PL_strcat( filter, ")" ); */
+ }
+
+ if(tid != NULL && uid != NULL && view != NULL) {
+ PL_strcat( filter, ")" );
+ }
+}
+
+
+void getActivityFilter( char *filter, char *query )
+{
+ char *uid = NULL;
+ char *tid = NULL;
+ char *end = NULL;
+ char *view = NULL;
+ int len = 0;
+ int i = 0;
+
+ tid = PL_strstr( query, "tid=" );
+ uid = PL_strstr( query, "uid=" );
+ view = PL_strstr( query, "op=view" );
+ filter[0] = '\0';
+
+ if( tid == NULL && uid == NULL ) {
+ PL_strcat( filter, "(tokenID=*)" );
+ }
+
+ if( tid != NULL && uid != NULL && view != NULL ) {
+ PL_strcat( filter, "(&" );
+ }
+
+ if( tid != NULL ) {
+ PL_strcat( filter, "(tokenID=" );
+ end = PL_strchr( tid, '&' );
+ len = PL_strlen( filter );
+
+ if( end != NULL ) {
+ i = end - tid - 4;
+ if( i > 0 ) {
+ memcpy( filter+len, tid+4, i );
+ }
+ filter[len+i] = '\0';
+ } else {
+ PL_strcat( filter, tid+4 );
+ }
+
+ if( view != NULL ) {
+ PL_strcat( filter, "*)" );
+ } else {
+ PL_strcat( filter, ")" );
+ }
+ }
+
+ if( uid != NULL && view != NULL ) {
+ PL_strcat( filter, "(tokenUserID=" );
+ end = PL_strchr( uid, '&' );
+ len = PL_strlen( filter );
+ if( end != NULL ) {
+ i = end - uid - 4;
+ if( i > 0 ) {
+ memcpy( filter+len, uid+4, i );
+ }
+
+ filter[len+i] = '\0';
+ } else {
+ PL_strcat( filter, uid+4 );
+ }
+
+ PL_strcat( filter, "*)" );
+ /* PL_strcat( filter, ")" ); */
+ }
+
+ if( tid != NULL && uid != NULL && view != NULL) {
+ PL_strcat( filter, ")" );
+ }
+}
+
+/**
+ * get_user_filter
+ * summary: returns an ldap search filter used for displaying
+ * user data when searching users based on uid, firstName and lastName
+ * params: filter - ldap search filter. Resu;t returned here.
+ * query - query string passed in
+ */
+void getUserFilter (char *filter, char *query) {
+ char *uid = NULL;
+ char *firstName = NULL;
+ char *lastName = NULL;
+
+ uid = get_field(query, "uid=", SHORT_LEN);
+ firstName = get_field(query, "firstName=", SHORT_LEN);
+ lastName = get_field(query, "lastName=", SHORT_LEN);
+
+ filter[0] = '\0';
+
+ if ((uid == NULL) && (firstName == NULL) && (lastName ==NULL)) {
+ PL_strcat(filter, "(objectClass=Person");
+ } else {
+ PL_strcat(filter, "(&(objectClass=Person)");
+ }
+
+ if (uid != NULL) {
+ PL_strcat(filter, "(uid=");
+ PL_strcat(filter, uid);
+ PL_strcat(filter,")");
+ }
+
+ if (lastName != NULL) {
+ PL_strcat(filter, "(sn=");
+ PL_strcat(filter, lastName);
+ PL_strcat(filter,")");
+ }
+
+ if (firstName != NULL) {
+ PL_strcat(filter, "(givenName=");
+ PL_strcat(filter, firstName);
+ PL_strcat(filter,")");
+ }
+
+ PL_strcat(filter, ")");
+
+ do_free(uid);
+ do_free(firstName);
+ do_free(lastName);
+}
+
+/**
+ * add_profile_filter
+ * summary: returns an ldap search filter which is a concatenation
+ * of the authorized profile search filter and the regular search
+ * filter. To be freed by caller.
+ * params: filter - search filter
+ * auth_filter: authorized profiles filter
+ */
+char *add_profile_filter( char *filter, char *auth_filter)
+{
+ char *ret;
+ int size;
+ char no_auth_filter[] = "(tokenType=\"\")";
+ if (filter == NULL) return NULL;
+ if ((auth_filter == NULL) || (PL_strstr( auth_filter, ALL_PROFILES))) {
+ ret = PL_strdup(filter);
+ } else if (PL_strstr( auth_filter, NO_PROFILES)) {
+ size = (PL_strlen(filter) + PL_strlen(no_auth_filter) + 4) * sizeof(char);
+ ret = (char *) PR_Malloc(size);
+ PR_snprintf(ret, size, "%s%s%s%s",
+ "(&", filter,no_auth_filter, ")");
+ } else {
+ size = (PL_strlen(filter) + PL_strlen(auth_filter) + 4) * sizeof(char);
+ ret = (char *) PR_Malloc(size);
+ PR_snprintf(ret, size, "%s%s%s%s",
+ "(&", filter, auth_filter, ")");
+ }
+ return ret;
+}
+
+
+void getFilter( char *filter, char *query )
+{
+ char *uid = NULL;
+ char *tid = NULL;
+ char *end = NULL;
+ char *view = NULL;
+ int len = 0;
+ int i = 0;
+
+ tid = PL_strstr( query, "tid=" );
+ uid = PL_strstr( query, "uid=" );
+ view = PL_strstr( query, "op=view" );
+ filter[0] = '\0';
+
+ if( tid == NULL && uid == NULL ) {
+ PL_strcat( filter, "(cn=*)" );
+ }
+
+ if( tid != NULL && uid != NULL && view != NULL ) {
+ PL_strcat( filter, "(&" );
+ }
+
+ if( tid != NULL ) {
+ PL_strcat( filter, "(cn=" );
+ end = PL_strchr( tid, '&' );
+ len = PL_strlen( filter );
+
+ if( end != NULL ) {
+ i = end - tid - 4;
+ if( i > 0 ) {
+ memcpy( filter+len, tid+4, i );
+ }
+
+ filter[len+i] = '\0';
+ } else {
+ PL_strcat( filter, tid+4 );
+ }
+
+ if (view != NULL) {
+ PL_strcat( filter, "*)" );
+ } else {
+ PL_strcat( filter, ")" );
+ }
+ }
+
+ if( uid != NULL && view != NULL ) {
+ PL_strcat( filter, "(tokenUserID=" );
+ end = PL_strchr( uid, '&' );
+ len = PL_strlen( filter );
+ if( end != NULL ) {
+ i = end - uid - 4;
+ if( i > 0 ) {
+ memcpy( filter+len, uid+4, i );
+ }
+
+ filter[len+i] = '\0';
+ } else {
+ PL_strcat( filter, uid+4 );
+ }
+
+ PL_strcat( filter, "*)" );
+ /* PL_strcat( filter, ")" ); */
+ }
+
+ if( tid != NULL && uid != NULL && view != NULL ) {
+ PL_strcat( filter, ")" );
+ }
+}
+
+
+void getCN( char *cn, char *query )
+{
+ char *tid = NULL;
+ char *end = NULL;
+ int i = 0;
+
+ cn[0] = '\0';
+ tid = PL_strstr( query, "tid=" );
+ if( tid != NULL ) {
+ end = PL_strchr( tid, '&' );
+
+ if( end != NULL ) {
+ i = end - tid - 4;
+
+ if( i > 0 ) {
+ memcpy( cn, tid+4, i );
+ }
+
+ cn[i] = '\0';
+ } else {
+ PL_strcat( cn, tid+4 );
+ }
+ }
+}
+
+
+void getTemplateName( char *cn, char *query )
+{
+ char *tid = NULL;
+ char *end = NULL;
+ int i = 0;
+
+ cn[0] = '\0';
+ tid = PL_strstr( query, "template=" );
+
+ if( tid != NULL ) {
+ end = PL_strchr( tid, '&' );
+
+ if( end != NULL ) {
+ i = end - tid - 4;
+
+ if( i > 0 ) {
+ memcpy( cn, tid+4, i );
+ }
+
+ cn[i] = '\0';
+ } else {
+ PL_strcat( cn, tid+4 );
+ }
+ }
+}
+
+
+char *parse_modification_number( char *s )
+{
+ char *end = NULL;
+ int n;
+
+ if( ( s = PL_strstr( s, "m=" ) ) == NULL ) {
+ return NULL;
+ }
+
+ s += 2;
+ end = PL_strchr( s, '&' );
+
+ if( end != NULL ) {
+ n = end - s;
+ } else {
+ n = PL_strlen( s );
+ }
+
+ return PL_strndup( s, n );
+}
+
+
+char **parse_modification_number_change( char *s )
+{
+ char *end = NULL;
+ char **v = NULL;
+ char tmp[32];
+ int n, m;
+
+ end = PL_strchr( s, '&' );
+
+ if( end != NULL ) {
+ n = end - s;
+ if( n > 0 ) {
+ memcpy( tmp, s, n );
+ }
+ tmp[n] = '\0';
+ } else {
+ n = PL_strlen( s );
+ PL_strcpy( tmp, s );
+ }
+
+ m = atoi( tmp );
+ m++;
+ PR_snprintf( tmp, 32, "%d", m );
+ n = PL_strlen( tmp );
+
+ if( ( v = allocate_values( 1, n+1 ) ) == NULL ) {
+ return NULL;
+ }
+
+ PL_strcpy( v[0], tmp );
+
+ return v;
+}
+
+
+char **parse_status_change( char *s )
+{
+ char *end = NULL;
+ char **v = NULL;
+ int n;
+
+ end = PL_strchr( s, '&' );
+ if( end != NULL ) {
+ n = end - s;
+ } else {
+ n = PL_strlen( s );
+ }
+
+ if( ( v = allocate_values( 1, n+1 ) ) == NULL ) {
+ return NULL;
+ }
+ PL_strncpy( v[0], s, n );
+
+ return v;
+}
+
+
+char **parse_uid_change( char *s )
+{
+ char *end = NULL;
+ char *p = NULL;
+ char *q = NULL;
+ char **v = NULL;
+ int i, k, n, m;
+
+ end = PL_strchr( s, '&' );
+ if( end != NULL ) {
+ n = end - s;
+ } else {
+ n = PL_strlen( s );
+ }
+
+ k = n;
+ p = s;
+ m = 1;
+
+ while( k > 0 ) {
+ if( ( p = PL_strnchr( p, ',', k ) ) == NULL ) {
+ break;
+ }
+
+ p++;
+ k = n - ( p - s );
+ m++;
+ }
+
+ if( ( v = allocate_values( m, n+1 ) ) == NULL ) {
+ return NULL;
+ }
+
+ if( m > 1 ) {
+ k = n;
+ p = s;
+ i = 0;
+
+ while( k > 0 ) {
+ if( ( q = PL_strnchr( p, ',', k ) ) != NULL ) {
+ PL_strncpy( v[i], p, q-p );
+ q++;
+ p = q;
+ k = n - ( p - s );
+ i++;
+ v[i] = v[i-1] + PL_strlen( v[i-1] ) + 1;
+ } else {
+ PL_strncpy( v[i], p, k );
+ break;
+ }
+ }
+ } else {
+ PL_strncpy( v[0], s, n );
+ }
+
+ return v;
+}
+
+
+char **parse_reason_change( char *s )
+{
+ char *end = NULL;
+ char **v = NULL;
+ int n;
+
+ end = PL_strchr( s, '&' );
+ if( end != NULL ) {
+ n = end - s;
+ } else {
+ n = PL_strlen( s );
+ }
+
+ if( ( v = allocate_values( 1, n+1 ) ) == NULL ) {
+ return NULL;
+ }
+ PL_strncpy( v[0], s, n );
+
+ return v;
+}
+
+
+char **parse_policy_change( char *s )
+{
+ char *end = NULL;
+ char **v = NULL;
+ int n;
+
+ end = PL_strchr( s, '&' );
+
+ if( end != NULL ) {
+ n = end - s;
+ } else {
+ n = PL_strlen( s );
+ }
+
+ if( ( v = allocate_values( 1, n+1 ) ) == NULL ) {
+ return NULL;
+ }
+
+ PL_strncpy( v[0], s, n );
+
+ return v;
+}
+
+
+LDAPMod **getModifications( char *query )
+{
+ LDAPMod **mods = NULL;
+ char **v = NULL;
+ int n = 0;
+ int k = 0;
+ char *s;
+
+ s = query;
+
+ while( ( s = PL_strchr( s, '&' ) ) != NULL ) {
+ s++;
+ n++;
+ }
+
+ if( n > 0 && PL_strstr( query, "&tid=" ) != NULL ) {
+ n--;
+ }
+
+ if( n > 0 ) {
+ n++;
+ } else {
+ return NULL;
+ }
+
+
+ mods = allocate_modifications( n );
+
+ if( mods == NULL ) {
+ return NULL;
+ }
+
+ if( ( v = create_modification_date_change() ) == NULL ) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return NULL;
+ }
+
+ mods[0]->mod_op = LDAP_MOD_REPLACE;
+ mods[0]->mod_type = get_modification_date_name();
+ mods[0]->mod_values = v;
+ k = 1;
+
+ if( k < n && ( ( s = PL_strstr( query, "m=" ) ) != NULL ) ) {
+ s += 2;
+ if( ( v = parse_modification_number_change( s ) ) == NULL ) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return NULL;
+ }
+
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = get_number_of_modifications_name();
+ mods[k]->mod_values = v;
+ k++;
+ }
+
+ if( k < n && ( ( s = PL_strstr( query, "s=" ) ) != NULL ) ) {
+ s += 2;
+
+ if( ( v = parse_status_change( s ) ) == NULL ) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return NULL;
+ }
+
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = get_token_status_name();
+ mods[k]->mod_values = v;
+ k++;
+ }
+
+ if( k < n && ( ( s = PL_strstr( query, "uid=" ) ) != NULL ) ) {
+ s += 4;
+ if( ( v = parse_uid_change( s ) ) == NULL ) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return NULL;
+ }
+
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = get_token_users_name();
+ mods[k]->mod_values = v;
+ k++;
+ }
+
+ if( k < n && ( ( s = PL_strstr( query, "tokenPolicy=" ) ) != NULL ) ) {
+ s += 12;
+
+ if( ( v = parse_policy_change( s ) ) == NULL ) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return NULL;
+ }
+
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = get_policy_name();
+ mods[k]->mod_values = v;
+ k++;
+ }
+
+ if( k < n && ( ( s = PL_strstr( query, "tokenReason=" ) ) != NULL ) ) {
+ s += 12;
+
+ if( ( v = parse_reason_change( s ) ) == NULL ) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return NULL;
+ }
+
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = get_reason_name();
+ mods[k]->mod_values = v;
+ k++;
+ }
+
+ return mods;
+}
+
+int get_tus_config( char *name )
+{
+ PRFileDesc *fd = NULL;
+ char *buf = NULL;
+ char *s = NULL;
+ char *v = NULL;
+ PRFileInfo info;
+ PRUint32 size;
+ int k, n;
+
+ if( PR_GetFileInfo( name, &info ) != PR_SUCCESS ) {
+ return 0;
+ }
+
+ size = info.size;
+ size++;
+ buf = (char *)PR_Malloc( size );
+
+ if( buf == NULL ) {
+ return 0;
+ }
+
+ fd = PR_Open( name, PR_RDONLY, 00400 );
+ if( fd == NULL ) {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+
+ k = 0;
+ while( ( n = PR_Read( fd, &buf[k], size-k-1 ) ) > 0 ) {
+ k += n;
+ if( ( PRUint32 ) ( k+1 ) >= size ) {
+ break;
+ }
+ }
+
+ if( fd != NULL ) {
+ PR_Close( fd );
+ fd = NULL;
+ }
+
+ if( n < 0 || ( ( PRUint32 ) ( k+1 ) > size ) ) {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+
+ buf[k] = '\0';
+
+ if( ( s = PL_strstr( buf, "tokendb.templateDir=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.templateDir=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( templateDir != NULL ) {
+ PL_strfree( templateDir );
+ templateDir = NULL;
+ }
+ templateDir = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.errorTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.errorTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( errorTemplate != NULL ) {
+ PL_strfree( errorTemplate );
+ errorTemplate = NULL;
+ }
+ errorTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.indexTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.indexTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( indexTemplate != NULL ) {
+ PL_strfree( indexTemplate );
+ indexTemplate = NULL;
+ }
+ indexTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.indexAdminTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.indexAdminTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( indexAdminTemplate != NULL ) {
+ PL_strfree( indexAdminTemplate );
+ indexAdminTemplate = NULL;
+ }
+ indexAdminTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.indexOperatorTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.indexOperatorTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( indexOperatorTemplate != NULL ) {
+ PL_strfree( indexOperatorTemplate );
+ indexOperatorTemplate = NULL;
+ }
+ indexOperatorTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.newTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.newTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 )( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( newTemplate != NULL ) {
+ PL_strfree( newTemplate );
+ newTemplate = NULL;
+ }
+ newTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchUserResultTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.searchUserResultTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 )( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ do_free(searchUserResultTemplate);
+ searchUserResultTemplate = s;
+ } else {
+ do_free(buf);
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.newUserTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.newUserTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 )( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ do_free(newUserTemplate);
+ newUserTemplate = s;
+ } else {
+ do_free(buf);
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.searchTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchTemplate != NULL ) {
+ PL_strfree( searchTemplate );
+ searchTemplate = NULL;
+ }
+ searchTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchCertificateTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.searchCertificateTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchCertificateTemplate != NULL ) {
+ PL_strfree( searchCertificateTemplate );
+ searchCertificateTemplate = NULL;
+ }
+ searchCertificateTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchAdminTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.searchAdminTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchAdminTemplate != NULL ) {
+ PL_strfree( searchAdminTemplate );
+ searchAdminTemplate = NULL;
+ }
+ searchAdminTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchUserTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.searchUserTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchUserTemplate != NULL ) {
+ PL_strfree( searchUserTemplate );
+ searchUserTemplate = NULL;
+ }
+ searchUserTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchActivityTemplate=" ) ) != NULL) {
+ s += PL_strlen( "tokendb.searchActivityTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchActivityTemplate != NULL ) {
+ PL_strfree( searchActivityTemplate );
+ searchActivityTemplate = NULL;
+ }
+ searchActivityTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchActivityAdminTemplate=" ) ) != NULL) {
+ s += PL_strlen( "tokendb.searchActivityAdminTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchActivityAdminTemplate != NULL ) {
+ PL_strfree( searchActivityAdminTemplate );
+ searchActivityAdminTemplate = NULL;
+ }
+ searchActivityAdminTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchCertificateResultTemplate=" ) ) !=
+ NULL ) {
+ s += PL_strlen( "tokendb.searchCertificateResultTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchCertificateResultTemplate != NULL ) {
+ PL_strfree( searchCertificateResultTemplate );
+ searchCertificateResultTemplate = NULL;
+ }
+ searchCertificateResultTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchActivityResultTemplate=" ) ) !=
+ NULL ) {
+ s += PL_strlen( "tokendb.searchActivityResultTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchActivityResultTemplate != NULL ) {
+ PL_strfree( searchActivityResultTemplate );
+ searchActivityResultTemplate = NULL;
+ }
+ searchActivityResultTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchAdminResultTemplate=" ) ) !=
+ NULL ) {
+ s += PL_strlen( "tokendb.searchAdminResultTemplate=" );
+ v = s;
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchAdminResultTemplate != NULL ) {
+ PL_strfree( searchAdminResultTemplate );
+ searchAdminResultTemplate = NULL;
+ }
+ searchAdminResultTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchResultTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.searchResultTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchResultTemplate != NULL ) {
+ PL_strfree( searchResultTemplate );
+ searchResultTemplate = NULL;
+ }
+ searchResultTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.deleteTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.deleteTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( deleteTemplate != NULL ) {
+ PL_strfree( deleteTemplate );
+ deleteTemplate = NULL;
+ }
+ deleteTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.userDeleteTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.userDeleteTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( userDeleteTemplate != NULL ) {
+ PL_strfree( userDeleteTemplate );
+ userDeleteTemplate = NULL;
+ }
+ userDeleteTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.doTokenConfirmTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.doTokenConfirmTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( doTokenConfirmTemplate != NULL ) {
+ PL_strfree( doTokenConfirmTemplate );
+ revokeTemplate = NULL;
+ }
+ doTokenConfirmTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.doTokenTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.doTokenTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( doTokenTemplate != NULL ) {
+ PL_strfree( doTokenTemplate );
+ revokeTemplate = NULL;
+ }
+ doTokenTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.revokeTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.revokeTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( revokeTemplate != NULL ) {
+ PL_strfree( revokeTemplate );
+ revokeTemplate = NULL;
+ }
+ revokeTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.showAdminTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.showAdminTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( showAdminTemplate != NULL ) {
+ PL_strfree( showAdminTemplate );
+ showAdminTemplate = NULL;
+ }
+ showAdminTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.showCertTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.showCertTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if (s != NULL) {
+ if( showCertTemplate != NULL ) {
+ PL_strfree( showCertTemplate );
+ showCertTemplate = NULL;
+ }
+ showCertTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.showTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.showTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( showTemplate != NULL ) {
+ PL_strfree( showTemplate );
+ showTemplate = NULL;
+ }
+ showTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchActivityAdminResultTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.searchActivityAdminResultTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchActivityAdminResultTemplate != NULL ) {
+ PL_strfree( searchActivityAdminResultTemplate );
+ searchActivityAdminResultTemplate = NULL;
+ }
+ searchActivityAdminResultTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.editUserTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.editUserTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( editUserTemplate != NULL ) {
+ PL_strfree( editUserTemplate );
+ editUserTemplate = NULL;
+ }
+ editUserTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.editTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.editTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( editTemplate != NULL ) {
+ PL_strfree( editTemplate );
+ editTemplate = NULL;
+ }
+ editTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.editResultTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.editResultTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( editResultTemplate != NULL ) {
+ PL_strfree( editResultTemplate );
+ editResultTemplate = NULL;
+ }
+ editResultTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.addResultTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.addResultTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( addResultTemplate != NULL ) {
+ PL_strfree( addResultTemplate );
+ addResultTemplate = NULL;
+ }
+ addResultTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.deleteResultTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.deleteResultTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( deleteResultTemplate != NULL ) {
+ PL_strfree( deleteResultTemplate );
+ deleteResultTemplate = NULL;
+ }
+ deleteResultTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.tokendb.sendInPieces=" ) ) != NULL ) {
+ s += 13;
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ sendInPieces = atoi( s );
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ /* keep this assignment to profileList for backwards compatibility.
+ It has been superseded by target.Profiles.list.
+ This should be removed in a future release */
+ if( ( s = PL_strstr( buf, "target.tokenType.list=" ) ) != NULL ) {
+ s += PL_strlen( "target.tokenType.list=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( profileList != NULL ) {
+ PL_strfree( profileList );
+ profileList = NULL;
+ }
+ profileList = s;
+ } else {
+ do_free(buf);
+ return 0;
+ }
+ }
+
+ get_cfg_string("tokendb.allowedTransitions=", transitionList);
+ get_cfg_string("tokendb.auditAdminTemplate=", auditAdminTemplate);
+ get_cfg_string("tokendb.selfTestTemplate=", selfTestTemplate);
+ get_cfg_string("tokendb.selfTestResultsTemplate=", selfTestResultsTemplate);
+ get_cfg_string("tokendb.selectConfigTemplate=", selectConfigTemplate);
+ get_cfg_string("tokendb.agentSelectConfigTemplate=", agentSelectConfigTemplate);
+ get_cfg_string("tokendb.editConfigTemplate=", editConfigTemplate);
+ get_cfg_string("tokendb.agentViewConfigTemplate=", agentViewConfigTemplate);
+ get_cfg_string("tokendb.confirmConfigChangesTemplate=", confirmConfigChangesTemplate);
+ get_cfg_string("tokendb.addConfigTemplate=", addConfigTemplate);
+ get_cfg_string("tokendb.confirmDeleteConfigTemplate=", confirmDeleteConfigTemplate);
+ get_cfg_string("target.Profiles.list=", profileList);
+ get_cfg_int("general.search.sizelimit.max=", maxSizeLimit);
+ get_cfg_int("general.search.sizelimit.default=", defaultSizeLimit);
+ get_cfg_int("general.search.timelimit.max=", maxTimeLimit);
+ get_cfg_int("general.search.timelimit.min=", defaultTimeLimit);
+ get_cfg_int("general.pwlength.min=", pwLength);
+
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+
+ tus_db_end();
+
+ return 1;
+}
+
+
+/* _________________________________________________________________
+**
+** Tokendb Module Request Phase
+** _________________________________________________________________
+*/
+
+/**
+ * Terminate the Tokendb module
+ */
+static apr_status_t
+mod_tokendb_terminate( void *data )
+{
+ /* This routine is ONLY called when this server's */
+ /* pool has been cleared or destroyed. */
+
+ /* Log Tokendb module debug information. */
+ RA::Debug( "mod_tokendb::mod_tokendb_terminate",
+ "The Tokendb module has been terminated!" );
+
+ tus_db_end();
+ tus_db_cleanup();
+
+ /* Since all members of mod_tokendb_server_configuration are allocated */
+ /* from a pool, there is no need to unset any of these members. */
+
+ /* Shutdown all APR library routines. */
+ /* NOTE: This automatically destroys all memory pools. */
+ /* Allow the TPS/NSS Modules to perform this task. */
+ /* apr_terminate(); */
+
+ /* Terminate the entire Apache server */
+ /* NOTE: Allow the TPS/NSS Modules to perform this task. */
+
+ return OK;
+}
+
+
+/**
+ * Initialize the Tokendb module
+ */
+static int
+mod_tokendb_initialize( apr_pool_t *p,
+ apr_pool_t *plog,
+ apr_pool_t *ptemp,
+ server_rec *sv )
+{
+ mod_tokendb_server_configuration *sc = NULL;
+ char *cfg_path_file = NULL;
+ char *error = NULL;
+ int status;
+
+ /* Retrieve the Tokendb module. */
+ sc = ( ( mod_tokendb_server_configuration * )
+ ap_get_module_config( sv->module_config,
+ &MOD_TOKENDB_CONFIG_KEY ) );
+
+ /* Check to see if the Tokendb module has been loaded. */
+ if( sc->enabled == MOD_TOKENDB_TRUE ) {
+ return OK;
+ }
+
+ /* Load the Tokendb module. */
+
+#ifdef DEBUG_Tokendb
+ debug_fd = PR_Open( "/tmp/tus-debug.log",
+ PR_RDWR | PR_CREATE_FILE | PR_APPEND,
+ 00400 | 00200 );
+#endif
+
+ /* Retrieve the path to where the configuration files are located, and */
+ /* insure that the Tokendb module configuration file is located here. */
+ if( sc->Tokendb_Configuration_File != NULL ) {
+ /* provide Tokendb Config File from */
+ /* <apache_server_root>/conf/httpd.conf */
+ if( sc->Tokendb_Configuration_File[0] == '/' ) {
+ /* Complete path to Tokendb Config File is denoted */
+ cfg_path_file = apr_psprintf( p,
+ "%s",
+ ( char * )
+ sc->Tokendb_Configuration_File );
+ } else {
+ /* Tokendb Config File is located relative */
+ /* to the Apache server root */
+ cfg_path_file = apr_psprintf( p,
+ "%s/%s",
+ ( char * ) ap_server_root,
+ ( char * )
+ sc->Tokendb_Configuration_File );
+ }
+ } else {
+ /* Log information regarding this failure. */
+ ap_log_error( "mod_tokendb_initialize",
+ __LINE__, APLOG_ERR, 0, sv,
+ "The tokendb module was installed incorrectly since the "
+ "parameter named '%s' is missing from the Apache "
+ "Configuration file!",
+ ( char * ) MOD_TOKENDB_CONFIGURATION_FILE_PARAMETER );
+
+ /* Display information on the screen regarding this failure. */
+ printf( "\nUnable to start Apache:\n"
+ " The tokendb module is missing the required parameter named"
+ " \n'%s' in the Apache Configuration file!\n",
+ ( char * ) MOD_TOKENDB_CONFIGURATION_FILE_PARAMETER );
+
+ goto loser;
+ }
+
+ /* Initialize the Token DB. */
+ if( get_tus_config( cfg_path_file ) &&
+ get_tus_db_config( cfg_path_file ) ) {
+ RA::Debug( "mod_tokendb::mod_tokendb_initialize",
+ "Initializing TUS database");
+ if( ( status = tus_db_init( &error ) ) != LDAP_SUCCESS ) {
+ if( error != NULL ) {
+ RA::Debug( "mod_tokendb::mod_tokendb_initialize",
+ "Token DB initialization failed: '%s'",
+ error );
+ PR_smprintf_free( error );
+ error = NULL;
+ } else {
+ RA::Debug( "mod_tokendb::mod_tokendb_initialize",
+ "Token DB initialization failed" );
+ }
+
+#if 0
+ goto loser;
+#endif
+ } else {
+ RA::Debug( "mod_tokendb::mod_tokendb_initialize",
+ "Token DB initialization succeeded" );
+ }
+ } else {
+ RA::Debug( "mod_tokendb::mod_tokendb_initialize",
+ "Error reading tokendb config file: '%s'",
+ cfg_path_file );
+ }
+
+ /* Initialize the "server" member of mod_tokendb_server_configuration. */
+ sc->enabled = MOD_TOKENDB_TRUE;
+
+ /* Register a server termination routine. */
+ apr_pool_cleanup_register( p,
+ sv,
+ mod_tokendb_terminate,
+ apr_pool_cleanup_null );
+
+ /* Log Tokendb module debug information. */
+ RA::Debug( "mod_tokendb::mod_tokendb_initialize",
+ "The Tokendb module has been successfully loaded!" );
+
+ return OK;
+
+loser:
+ /* Log Tokendb module debug information. */
+ RA::Debug( "mod_tokendb::mod_tokendb_initialize",
+ "Failed loading the Tokendb module!" );
+
+ /* Since all members of mod_tokendb_server_configuration are allocated */
+ /* from a pool, there is no need to unset any of these members. */
+
+ /* Shutdown all APR library routines. */
+ /* NOTE: This automatically destroys all memory pools. */
+ apr_terminate();
+
+ /* Terminate the entire Apache server */
+ tokendb_die();
+
+ return DECLINED;
+}
+
+
+char *stripBase64HeaderAndFooter( char *cert )
+{
+ char *base64_data = NULL;
+ char *data = NULL;
+ char *footer = NULL;
+
+ if( ( cert != NULL ) &&
+ ( strlen( cert ) > strlen( BASE64_HEADER ) ) ) {
+ /* Strip off the base64 header. */
+ data = ( char * ) ( cert + strlen( BASE64_HEADER ) );
+
+ /* Find base64 footer. */
+ footer = ( char * ) strstr( ( const char * ) data,
+ ( const char * ) BASE64_FOOTER );
+ if( footer != NULL ) {
+ /* Strip off the base64 footer. */
+ footer[0] = '\0';
+ }
+
+ /* Finally, store data in the base64_data storage area. */
+ base64_data = strdup( data );
+ }
+
+ return base64_data;
+}
+
+/**
+ * util_read
+ * summary: called from read_post. reads posted data
+ */
+static int util_read(request_rec *r, const char **rbuf)
+{
+ int rc = OK;
+
+ if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) {
+ return rc;
+ }
+
+ if (ap_should_client_block(r)) {
+ char argsbuffer[HUGE_STRING_LEN];
+ int rsize, len_read, rpos=0;
+ long length = r->remaining;
+ *rbuf = (const char*) apr_pcalloc(r->pool, length + 1);
+
+
+ while ((len_read =
+ ap_get_client_block(r, argsbuffer, sizeof(argsbuffer))) > 0) {
+ if ((rpos + len_read) > length) {
+ rsize = length - rpos;
+ }
+ else {
+ rsize = len_read;
+ }
+ memcpy((char*)*rbuf + rpos, argsbuffer, rsize);
+ rpos += rsize;
+ }
+
+ }
+
+ return rc;
+}
+
+/**
+ * read_post
+ * read data in a post request and store it in an apr_table
+ */
+static int read_post(request_rec *r, apr_table_t **tab)
+{
+ const char *data;
+ const char *key, *val;
+ int rc = OK;
+
+ if((rc = util_read(r, &data)) != OK) {
+ return rc;
+ }
+
+ if(*tab) {
+ apr_table_clear(*tab);
+ }
+ else {
+ *tab = apr_table_make(r->pool, 8);
+ }
+
+ while(*data && (val = ap_getword(r->pool, &data, '&'))) {
+ key = ap_getword(r->pool, &val, '=');
+
+ ap_unescape_url((char*)key);
+ ap_unescape_url((char*)val);
+
+ apr_table_merge(*tab, key, val);
+ }
+
+ return OK;
+}
+
+/**
+ * add_authorization_data
+ * writes variable that describe whether the user is an admin, agent or operator to the
+ * injection data. Used by templates to determine which tabs to display
+ */
+void add_authorization_data(const char *userid, int is_admin, int is_operator, int is_agent, char *injection)
+{
+ if (is_agent) {
+ PL_strcat(injection, "var agentAuth = \"true\";\n");
+ }
+ if (is_operator) {
+ PL_strcat(injection, "var operatorAuth = \"true\";\n");
+ }
+ if (is_admin) {
+ PL_strcat(injection, "var adminAuth = \"true\";\n");
+ }
+}
+
+/**
+ * check_injection_size
+ * Used when the injection size can become large - as in the case where lists of tokens, certs or activities are being returned.
+ * If the free space in injection drops below a threshold, more space is allocated. Fails if injection exceeds a certain size.
+ * This should not happen because the number of entries to return per page is limited.
+ *
+ * returns 0 on success,1 on failure
+ */
+int check_injection_size(char **injection, int *psize, char *fixed_injection)
+{
+ char *new_ptr = NULL;
+ if (((*psize) - PL_strlen(*injection)) <= LOW_INJECTION_SIZE) {
+ if ((*psize) > MAX_OVERLOAD * MAX_INJECTION_SIZE) {
+ tokendbDebug("Error: Injection exceeds maximum size. Output will be truncated");
+ return 1;
+ }
+ if (*injection == fixed_injection) {
+ *injection = (char *) PR_Malloc(MAX_INJECTION_SIZE + (*psize));
+ if (*injection != NULL) {
+ PL_strcpy(*injection, fixed_injection);
+ (*psize) += MAX_INJECTION_SIZE;
+ } else {
+ tokendbDebug("Error: Unable to allocate memory for injection. Output will be truncated");
+ *injection = fixed_injection;
+ return 1;
+ }
+ } else {
+ new_ptr = (char *) PR_Realloc(*injection, (*psize) + MAX_INJECTION_SIZE);
+ if (new_ptr != NULL) {
+ //allocation successful
+ *injection = new_ptr;
+ (*psize) += MAX_INJECTION_SIZE;
+ } else {
+ tokendbDebug("Error: Failed to reallocate memory for injection. Output will be truncated");
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+ * We need to compare current values in the database entry e with new values.
+ * If they are different, then we need to provide the audit message
+ */
+int audit_attribute_change(LDAPMessage *e, const char *fname, char *fvalue, char *msg)
+{
+ struct berval **attr_values = NULL;
+ char pString[512]="";
+
+ attr_values = get_attribute_values( e, fname );
+ if (attr_values != NULL) {
+ if (fvalue == NULL) {
+ // value has been deleted
+ PR_snprintf(pString, 512, "%s;;no_value", fname);
+ } else if (valid_berval(attr_values) &&
+ (strcmp(fvalue, attr_values[0]->bv_val) != 0)) {
+ // value has been changed
+ PR_snprintf(pString, 512, "%s;;%s", fname, fvalue);
+ }
+ free_values(attr_values, 1);
+ attr_values = NULL;
+ } else if (fvalue != NULL) {
+ // value has been added
+ PR_snprintf(pString, 512, "%s;;%s", fname, fvalue);
+ }
+
+ if (strlen(pString) > 0) {
+ if (strlen(msg) != 0) PL_strncat(msg, "+", 4096 - strlen(msg));
+ PL_strncat(msg, pString, 4096 - strlen(msg));
+ }
+ return 0;
+}
+
+/**
+ * replaces all instances of a substring oldstr with newstr
+ * must be freed by caller
+ **/
+char *replace(const char *s, const char *oldstr, const char *newstr)
+{
+ char *ret = NULL;
+ int i, count = 0;
+ size_t newlen = PL_strlen(newstr);
+ size_t oldlen = PL_strlen(oldstr);
+
+ for (i = 0; s[i] != '\0'; i++) {
+ if (PL_strstr(&s[i], oldstr) == &s[i]) {
+ count++;
+ i += oldlen - 1;
+ }
+ }
+
+ ret = (char *) PR_Malloc(PL_strlen(s) + count * (newlen - oldlen) + 1);
+
+ i = 0;
+ while (*s) {
+ if (PL_strstr(s, oldstr) == s) {
+ PL_strncpy(&ret[i], newstr, newlen);
+ i += newlen;
+ s += oldlen;
+ } else
+ ret[i++] = *s++;
+ }
+ ret[i] = '\0';
+
+ return ret;
+}
+
+char *escapeString(const char *s)
+{
+ char *ret, *ret1, *ret2, *ret3;
+
+ ret1 = replace(s, "\"", "&dbquote");
+ ret2 = replace(ret1, "\'", "&singlequote");
+ ret3 = replace(ret2, "<", "&lessthan");
+ ret = replace(ret3, ">", "&greaterthan");
+ do_free(ret1);
+ do_free(ret2);
+ do_free(ret3);
+ return ret;
+}
+
+char *unescapeString(const char *s)
+{
+ char *ret, *ret1, *ret2, *ret3;
+
+ ret1 = replace(s, "&dbquote", "\"");
+ ret2 = replace(ret1,"&singlequote", "\'");
+ ret3 = replace(ret2, "&lessthan", "<");
+ ret = replace(ret3, "&greaterthan", ">");
+ do_free(ret1);
+ do_free(ret2);
+ do_free(ret3);
+ return ret;
+}
+
+
+/**
+ * determines if the parameter set named pname of type ptype
+ * has been defined.
+ **/
+bool config_param_exists(char *ptype, char* pname)
+{
+ char configname[256]="";
+ PR_snprintf( ( char * ) configname, 256, "target.%s.list", ptype );
+ const char* conf_list = RA::GetConfigStore()->GetConfigAsString( configname );
+ return RA::match_comma_list((const char*) pname, (char *) conf_list);
+}
+
+/**
+ * takes in the type and name of the parameter set.
+ * returns the current state and timestamp of this parameter set.
+ *
+ * If a parameter set is being viewed in the UI for the first time, the state is returned
+ * as "Enabled" and the timestamp is set to the current timestamp.
+ **/
+void get_config_state_timestamp(char *type, char *name, char **pstate, char **ptimestamp)
+{
+ char configname[256] = "";
+ bool commit_needed = false;
+ const char *tmp_state = NULL;
+ const char *tmp_timestamp = NULL;
+ int status;
+ PRLock *config_lock = RA::GetConfigLock();
+
+ PR_Lock(config_lock);
+ PR_snprintf(configname, 256, "config.%s.%s.state", type, name);
+
+ tmp_state = RA::GetConfigStore()->GetConfigAsString(configname);
+ if ((tmp_state == NULL) && (config_param_exists(type, name))) {
+ RA::GetConfigStore()->Add(configname, "Enabled");
+ commit_needed = true;
+ *pstate = (char *) PL_strdup("Enabled");
+ } else {
+ *pstate = (char *) PL_strdup(tmp_state);
+ }
+
+ PR_snprintf(configname, 256, "config.%s.%s.timestamp", type, name);
+ tmp_timestamp = RA::GetConfigStore()->GetConfigAsString(configname);
+ if ((tmp_timestamp == NULL) && (config_param_exists(type, name))) {
+ char new_ts[256];
+ PR_snprintf(new_ts, 256, "%lld", PR_Now());
+ RA::GetConfigStore()->Add(configname, new_ts);
+ commit_needed = true;
+ *ptimestamp = (char *) PL_strdup(new_ts);
+ } else {
+ *ptimestamp = (char *) PL_strdup(tmp_timestamp);
+ }
+
+ PR_Unlock(config_lock);
+ if (commit_needed) {
+ char error_msg[512];
+ status = RA::GetConfigStore()->Commit(false, error_msg, 512);
+ if (status != 0) {
+ tokendbDebug(error_msg);
+ }
+ }
+}
+
+/**
+ * takes in a parameter set type and name
+ * removes any variables defining the state and timestamp.
+ * Called when a parameter set is deleted.
+ **/
+void remove_config_state_timestamp(char *type, char *name)
+{
+ char configname[256] = "";
+ PRLock *config_lock = RA::GetConfigLock();
+
+ PR_Lock(config_lock);
+ PR_snprintf(configname, 256, "config.%s.%s.state", type, name);
+ RA::GetConfigStore()->Remove(configname);
+
+ PR_snprintf(configname, 256, "config.%s.%s.timestamp", type, name);
+ RA::GetConfigStore()->Remove(configname);
+ PR_Unlock(config_lock);
+
+}
+
+/**
+ * takes in a parameter set type
+ * returns true if this parameter set type must be approved/ disabled by an agent
+ **/
+bool agent_must_approve(char *conf_type)
+{
+ const char* agent_list = RA::GetConfigStore()->GetConfigAsString("target.agent_approve.list");
+ return RA::match_comma_list((const char*) conf_type, (char *) agent_list);
+}
+
+/**
+ * This is the main function used to set the state and timestamp for parameter sets
+ * managed by the UI. The function includes checks to enforce only allowed transitions.
+ *
+ * Arguments are as follows:
+ * type: parameter set type
+ * name: parameter set name
+ * old_ts: old timestamp of parameter set. Used to check for concurrency conflicts.
+ * new_state: state to transition to: one of "Enabled", "Disabled", "Pending_Approval" or "Writing"
+ * who: role requesting the transition, one of "Agent" or "Admin"
+ * new_config: true if this is a new parameter set, false otherwise
+ * userid: userid of user requesting the transition, used for audit log message
+ *
+ * function will return 0 on success, non-zero otherwise
+ **/
+int set_config_state_timestamp(char *type, char* name, char *old_ts, const char *new_state, const char *who, bool new_config, char *userid)
+{
+ char ts_name[256] = "";
+ char state_name[256] = "";
+ char writer_name[256] = "";
+ char new_ts[256] ="";
+ char final_state[256] = "";
+ char me[256]="";
+ int ret =0;
+ PRTime now;
+ PRThread *ct = NULL;
+ PRLock *config_lock = RA::GetConfigLock();
+
+ PR_snprintf(ts_name, 256, "config.%s.%s.timestamp", type, name);
+ PR_snprintf(state_name, 256, "config.%s.%s.state", type, name);
+ PR_snprintf(writer_name, 256, "config.%s.%s.writer", type, name);
+
+ ct = PR_GetCurrentThread();
+ PR_snprintf(me, 256, "%x", ct);
+
+ PR_Lock(config_lock);
+ if (new_config) {
+ if (agent_must_approve(type)) {
+ RA::GetConfigStore()->Add(state_name, "Disabled");
+ } else {
+ RA::GetConfigStore()->Add(state_name, "Enabled");
+ }
+ now = PR_Now();
+ PR_snprintf(new_ts, 256, "%lld", now);
+ RA::GetConfigStore()->Add(ts_name, new_ts);
+ }
+
+ // used to make sure auditing is correct
+ PR_snprintf(final_state, 256, "%s", new_state);
+
+ const char *cur_state = RA::GetConfigStore()->GetConfigAsString(state_name);
+ const char *cur_writer = RA::GetConfigStore()->GetConfigAsString(writer_name, "");
+ const char *cur_ts = RA::GetConfigStore()->GetConfigAsString(ts_name);
+
+ if ((cur_state == NULL) || (cur_ts == NULL)) {
+ // this item has likely been deleted
+ ret=20;
+ goto release_and_exit;
+ }
+
+ if ((PL_strcmp(cur_ts, old_ts) != 0) && (!new_config)) {
+ // version out of date
+ ret=1;
+ goto release_and_exit;
+ }
+
+ if (PL_strcmp(cur_state, new_state) == 0) {
+ ret=0;
+ goto release_and_exit;
+ }
+
+ if (PL_strcmp(who, "Admin")==0) {
+ if (PL_strcmp(new_state, "Disabled")==0) {
+ if ((PL_strcmp(cur_state, "Writing") == 0) && (PL_strcmp(me, cur_writer) == 0)) {
+ // "Writing" to "Disabled", with me as writer, admin finishes writes after "Save"
+ now = PR_Now();
+ PR_snprintf(new_ts, 256, "%lld", now);
+ RA::GetConfigStore()->Add(ts_name, new_ts);
+ if (agent_must_approve(type)) {
+ RA::GetConfigStore()->Add(state_name, new_state);
+ } else {
+ PR_snprintf(final_state, 256, "Enabled");
+ RA::GetConfigStore()->Add(state_name, "Enabled");
+ }
+ ret=0;
+ goto release_and_exit;
+ } else {
+ ret=2;
+ goto release_and_exit;
+ }
+ } else if (PL_strcmp(new_state, "Enabled")==0) {
+ if ((!agent_must_approve(type)) && (PL_strcmp(cur_state, "Writing") == 0)
+ && (PL_strcmp(me, cur_writer) == 0)) {
+ now = PR_Now();
+ PR_snprintf(new_ts, 256, "%lld", now);
+ RA::GetConfigStore()->Add(ts_name, new_ts);
+ ret = 0;
+ goto release_and_exit;
+ }
+
+ // no valid transitions for admin (if agent approval required)
+ ret=3;
+ goto release_and_exit;
+ } else if (PL_strcmp(new_state, "Pending_Approval")==0) {
+ if (PL_strcmp(cur_state, "Disabled") == 0) {
+ // Disabled -> Pending (admin submits for approval with no changes)
+ RA::GetConfigStore()->Add(state_name, new_state);
+ ret=0;
+ goto release_and_exit;
+ } else if ((PL_strcmp(cur_state, "Writing") == 0) && (PL_strcmp(me, cur_writer) == 0)) {
+ // Writing -> Pending. (admin finishes writes after "Submit for Approval")
+ now = PR_Now();
+ PR_snprintf(new_ts, 256, "%lld", now);
+ RA::GetConfigStore()->Add(ts_name, new_ts);
+ RA::GetConfigStore()->Add(state_name, new_state);
+ ret=0;
+ goto release_and_exit;
+ } else {
+ ret=4;
+ goto release_and_exit;
+ }
+ } else if (PL_strcmp(new_state, "Writing")==0) {
+ if (PL_strcmp(cur_state, "Disabled") == 0) {
+ // Disabled -> Writing (admin start to write changes - need to save writer)
+ RA::GetConfigStore()->Add(writer_name, me);
+ RA::GetConfigStore()->Add(state_name, new_state);
+ ret=0;
+ goto release_and_exit;
+ } if ((!agent_must_approve(type)) && (PL_strcmp(cur_state, "Enabled") == 0)) {
+ // Enabled -> Writing (admin start to write changes for case where agent need not approve - need to save writer)
+ RA::GetConfigStore()->Add(writer_name, me);
+ RA::GetConfigStore()->Add(state_name, new_state);
+ ret=0;
+ goto release_and_exit;
+ } else {
+ ret=5;
+ goto release_and_exit;
+ }
+ }
+ }
+
+ if (PL_strcmp(who, "Agent")==0) {
+ if (PL_strcmp(new_state, "Disabled")==0) {
+ if ((PL_strcmp(cur_state, "Enabled") == 0) || (PL_strcmp(cur_state, "Pending_Approval") == 0)) {
+ // "Enabled or Pending" to "Disabled", agent disables or rejects
+ RA::GetConfigStore()->Add(state_name, new_state);
+ ret=0;
+ goto release_and_exit;
+ } else {
+ ret=6;
+ goto release_and_exit;
+ }
+ } else if (PL_strcmp(new_state, "Enabled")==0) {
+ if ((PL_strcmp(cur_state, "Disabled") == 0) || (PL_strcmp(cur_state, "Pending_Approval") == 0)) {
+ // "Disabled or Pending" to "Enabled", agent approves
+ RA::GetConfigStore()->Add(state_name, new_state);
+ ret=0;
+ goto release_and_exit;
+ } else {
+ ret=7;
+ goto release_and_exit;
+ }
+ } else if (PL_strcmp(new_state, "Pending_Approval")==0) {
+ // no valid transitions for agent
+ ret=8;
+ goto release_and_exit;
+ } else if (PL_strcmp(new_state, "Writing")==0) {
+ // no valid transitions for agent
+ ret=9;
+ goto release_and_exit;
+ }
+ }
+
+release_and_exit:
+ PR_Unlock(config_lock);
+
+ //audit changes
+ char pString[256]="";
+ char msg[256] = "";
+
+ if (PL_strcmp(new_ts, "") != 0) {
+ PR_snprintf(pString, 256, "%s;;%s+%s;;%s", state_name, final_state, ts_name, new_ts);
+ PR_snprintf(msg, 256, "config item state and timestamp changed");
+ } else {
+ PR_snprintf(pString, 256, "%s;;%s", state_name, final_state);
+ PR_snprintf(msg, 256, "config item state changed");
+ }
+ if (ret == 0) {
+ RA::Audit(EV_CONFIG_AUDIT, AUDIT_MSG_CONFIG, userid, who, "Success", type, pString, msg);
+ } else {
+ PR_snprintf(msg, 256, "config item state or timestamp change failed, return value is %d", ret);
+ RA::Audit(EV_CONFIG, AUDIT_MSG_CONFIG, userid, who, "Failure", type, pString, msg);
+ }
+ return ret;
+}
+
+/**
+ * takes in the type and name of the parameter set
+ * looks up the regular expression pattern for this parameter set in CS.cfg and substitutes
+ * $name with the name of the parameter set.
+ * returns this "fixed" pattern as a string (that must be freed by caller)
+ **/
+char *get_fixed_pattern(char *ptype, char *pname)
+{
+ char configname[256]="";
+ char tmpc[256]="";
+ char *p = NULL;
+ char *fixed_pattern = NULL;
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.pattern", ptype );
+ const char* pattern = RA::GetConfigStore()->GetConfigAsString( configname );
+
+ if (pattern == NULL) {
+ tokendbDebug("get_pattern_substore: pattern is NULL");
+ return NULL;
+ }
+
+ if ((p = PL_strstr(pattern, "$name"))) {
+ PL_strncpy(tmpc, pattern, p-pattern);
+ tmpc[p-pattern] = '\0';
+ sprintf(tmpc+(p-pattern), "%s%s", pname, p+PL_strlen("$name"));
+ fixed_pattern = (char *) PL_strdup(tmpc);
+ p = NULL;
+ } else {
+ fixed_pattern=PL_strdup(pattern);
+ }
+
+ tokendbDebug(fixed_pattern);
+
+ return fixed_pattern;
+}
+
+/**
+ * get ConfigStore with entries that match the relevant pattern
+ * must be freed by caller
+ **/
+ConfigStore *get_pattern_substore(char *ptype, char *pname)
+{
+ char *fixed_pattern = NULL;
+ ConfigStore *store = NULL;
+
+ fixed_pattern=get_fixed_pattern(ptype, pname);
+ if (fixed_pattern == NULL) {
+ return NULL;
+ }
+ store = RA::GetConfigStore()->GetPatternSubStore(fixed_pattern);
+
+ do_strfree(fixed_pattern);
+ return store;
+}
+
+/***
+ * parse the parameter string of form foo=bar&&foo2=baz&& ...
+ * and perform (and audit) the changes
+ **/
+void parse_and_apply_changes(char* userid, char* ptype, char* pname, const char *operation, char *params) {
+ char *pair;
+ char *line = NULL;
+ int i;
+ int len;
+ char *lasts = NULL;
+ int op=0;
+ char audit_str[4096] = "";
+ char *fixed_pattern = NULL;
+ regex_t *regex=NULL;
+ int err_no;
+
+ if (PL_strstr(operation, "ADD")) {
+ op=1;
+ } else if (PL_strstr(operation, "DELETE")) {
+ op=2;
+ } else if (PL_strstr(operation, "MODIFY")) {
+ op=3;
+ }
+
+ tokendbDebug(operation);
+
+ // get the correct pattern and regex
+ fixed_pattern = get_fixed_pattern(ptype, pname);
+ if (fixed_pattern == NULL) {
+ tokendbDebug("parse_and_apply_changes: pattern is NULL. Aborting changes ..");
+ return;
+ }
+
+ regex = (regex_t *) malloc(sizeof(regex_t));
+ memset(regex, 0, sizeof(regex_t));
+
+ if((err_no=regcomp(regex, fixed_pattern, 0))!=0) /* Comple the regex */
+ {
+ // Error in computing the regex
+ size_t length;
+ char *buffer;
+ length = regerror (err_no, regex, NULL, 0);
+ buffer = (char *) PR_Malloc(length);
+ regerror (err_no, regex, buffer, length);
+ tokendbDebug("parse_and_apply_changes: error computing the regex, aborting changes");
+ tokendbDebug(buffer);
+ PR_Free(buffer);
+ regfree(regex);
+ return;
+ }
+ size_t no_sub = regex->re_nsub+1;
+ regmatch_t *result = NULL;
+
+ line = PL_strdup(params);
+ pair = PL_strtok_r(line, "&&", &lasts);
+ while (pair != NULL) {
+ len = strlen(pair);
+ i = 0;
+ while (1) {
+ if (i >= len) {
+ goto skip1;
+ }
+ if (pair[i] == '\0') {
+ goto skip1;
+ }
+ if (pair[i] == '=') {
+ pair[i] = '\0';
+ break;
+ }
+ i++;
+ }
+
+ result = NULL;
+ result = (regmatch_t *) PR_Malloc(sizeof(regmatch_t) * no_sub);
+ if (regexec(regex, (char *) &pair[0], no_sub, result, 0)!=0) {
+ tokendbDebug("parse_and_apply_changes: parameter does not match pattern. Dropping edit ..");
+ tokendbDebug(&pair[0]);
+ if (result != NULL) {
+ PR_Free(result);
+ result=NULL;
+ }
+ goto skip1;
+ }
+ if (result != NULL) {
+ PR_Free(result);
+ result=NULL;
+ }
+
+ if (op == 1) { //ADD
+ RA::GetConfigStore()->Add(&pair[0], &pair[i+1]);
+ PR_snprintf(audit_str, 4096, "%s;;%s", &pair[0], &pair[i+1]);
+ RA::Audit(EV_CONFIG, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", audit_str, "config parameter added");
+ } else if (op == 2) { //DELETE
+ RA::GetConfigStore()->Remove(&pair[0]);
+ PR_snprintf(audit_str, 4096, "%s;;%s", &pair[0], &pair[i+1]);
+ RA::Audit(EV_CONFIG, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", audit_str, "config parameter deleted");
+ } else if (op == 3) { //MODIFY
+ RA::GetConfigStore()->Add(&pair[0], &pair[i+1]);
+ PR_snprintf(audit_str, 4096, "%s;;%s", &pair[0], &pair[i+1]);
+ RA::Audit(EV_CONFIG, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", audit_str, "config parameter modified");
+ }
+ skip1:
+ pair = PL_strtok_r(NULL, "&&", &lasts);
+ }
+ do_strfree(line);
+ do_strfree(fixed_pattern);
+}
+
+static int get_time_limit(char *query)
+{
+ char *val = NULL;
+ int ret;
+
+ val = get_field(query, "timeLimit=", SHORT_LEN);
+ if (val == NULL) {
+ return maxTimeLimit;
+ }
+
+ ret = atoi(val);
+ if ((ret == 0) || (ret > maxTimeLimit)) {
+ return maxTimeLimit;
+ }
+ return ret;
+}
+
+static int get_size_limit(char *query)
+{
+ char *val = NULL;
+ int ret;
+
+ val = get_field(query, "sizeLimit=", SHORT_LEN);
+ if (val == NULL) {
+ return maxSizeLimit;
+ }
+
+ ret = atoi(val);
+ if ((ret == 0) || (ret > maxSizeLimit)) {
+ return maxSizeLimit;
+ }
+ return ret;
+}
+
+/**
+ * generate a simple password of at least specified length
+ * containing upper case, lower case and special characters
+ */
+#define PW_MAX_LEN 1024
+
+static char *generatePassword(int length)
+{
+ char choices[80] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*_-+=':;.,";
+ bool pw_ok = false;
+ int i=0;
+ int upper=0, lower=0, number=0, special=0;
+ char pw[PW_MAX_LEN] = "";
+
+ srand(time(0));
+
+ while (!pw_ok) {
+ int x;
+ x = 0 + int(79.0 * rand()/(RAND_MAX+1.0));
+ pw[i] = choices[x];
+ if (isupper(choices[x])) upper ++;
+ if (islower(choices[x])) lower ++;
+ if (isdigit(choices[x])) number ++;
+ if (! isalpha(choices[x])) special ++;
+
+ if ((i >= length) && (upper >=2) && (lower >=2) && (special >=2) && (number >=2))
+ pw_ok = true;
+ i++;
+ if (i == PW_MAX_LEN) {
+ i=0;
+ upper = 0;
+ lower = 0;
+ special =0;
+ number =0;
+ PR_snprintf(pw, PW_MAX_LEN, "");
+ }
+ }
+
+ return PL_strdup(pw);
+}
+
+
+/**
+ * mod_tokendb_handler handles the protocol between the tokendb and the RA
+ */
+static int
+mod_tokendb_handler( request_rec *rq )
+{
+ int sendPieces = 0;
+ int rc = 0;
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ LDAPMod **mods = NULL;
+ char *injection = NULL;
+ char *mNum = NULL;
+ char *buf = NULL;
+ char *uri = NULL;
+ char *query = NULL;
+ char *cert = NULL;
+ char *base64_cert = NULL;
+ char *userid = NULL;
+ char *error = NULL;
+ char *tid = NULL;
+ char *question = NULL;
+ const char *tokentype = NULL;
+
+
+ /* user fields */
+ char *uid = NULL;
+ char *firstName = NULL;
+ char *lastName = NULL;
+ char *opOperator = NULL;
+ char *opAdmin = NULL;
+ char *opAgent = NULL;
+ char *userCert = NULL;
+
+ /* keep track of which menu we are in - operator or agent */
+ char *topLevel = NULL;
+
+ char **attrs = NULL;
+ char **vals = NULL;
+ struct berval **bvals = NULL;
+ int maxReturns;
+ int q;
+ int i, n, len, nEntries, entryNum;
+ int status = LDAP_SUCCESS;
+ int size, tagOffset, statusNum;
+ char fixed_injection[MAX_INJECTION_SIZE];
+ char pString[512] = "";
+ char oString[512] = "";
+ char pLongString[4096] = "";
+ char configname[512] ="";
+ char filter[512] = "";
+ char msg[512] = "";
+ char question_no[100] ="";
+ char cuid[256] = "";
+ char cuidUserId[100]="";
+ char tokenStatus[100]="";
+ char tokenReason[100]="";
+ int token_ui_state= 0;
+ bool show_token_ui_state = false;
+ char serial[100]="";
+ char userCN[256]="";
+ char tokenType[512]="";
+ apr_table_t *post = NULL; /* used for POST data */
+
+ char *statusString = NULL;
+ char *s1, *s2;
+ char *end;
+ struct berval **attr_values = NULL;
+ char *auth_filter = NULL;
+
+ /* authorization */
+ int is_admin = 0;
+ int is_agent = 0;
+ int is_operator = 0;
+
+ int end_val =0;
+ int start_val = 0;
+
+ /* current operation for audit */
+ char *op = NULL;
+
+ RA::Debug( "mod_tokendb_handler::mod_tokendb_handler",
+ "mod_tokendb_handler::mod_tokendb_handler" );
+
+ RA::Debug( "mod_tokendb::mod_tokendb_handler",
+ "uri '%s'", rq->uri);
+
+ /* XXX: We need to change "tus" to "tokendb" */
+ if (strcmp(rq->handler, "tus") != 0) {
+ RA::Debug( "mod_tokendb::mod_tokendb_handler", "DECLINED uri '%s'", rq->uri);
+ return DECLINED;
+ }
+
+ RA::Debug( "mod_tokendb::mod_tokendb_handler",
+ "uri '%s' DONE", rq->uri);
+
+ tokendbDebug( "tokendb request arrived...serving tokendb\n" );
+
+ injection = fixed_injection;
+
+ ap_set_content_type( rq, "text/html" );
+
+ if( !is_tus_db_initialized() ) {
+ tokendbDebug( "token DB was not initialized \n" );
+
+ if( ( status = tus_db_init( &error ) ) != LDAP_SUCCESS ) {
+ if( error != NULL ) {
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s", JS_START,
+ "var error = \"", error,
+ "\";\n", JS_STOP );
+
+ buf = getData( errorTemplate, injection );
+
+ ( void ) ap_rwrite( ( const void * ) buf,
+ PL_strlen( buf ), rq );
+
+ PR_smprintf_free( error );
+ error = NULL;
+ } else {
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s", JS_START,
+ "var error = \"", "NULL",
+ "\";\n", JS_STOP );
+
+ buf = getData( errorTemplate, injection );
+
+ ( void ) ap_rwrite( ( const void * ) buf,
+ PL_strlen( buf ), rq );
+ }
+
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+
+ return DONE;
+ }
+ } else {
+ tokendbDebug( "token DB was initialized\n" );
+ }
+
+ tokendbDebug( "authentication\n" );
+
+ cert = nss_var_lookup( rq->pool,
+ rq->server,
+ rq->connection,
+ rq,
+ ( char * ) "SSL_CLIENT_CERT" );
+ if( cert == NULL ) {
+ error_out("Authentication Failure", "Failed to authenticate request");
+ RA::Audit(EV_AUTH_FAIL, AUDIT_MSG_AUTH, "null", "null", "Failure", "authentication failure, no cert");
+ do_free(buf);
+ return DONE;
+ }
+
+ tokendbDebug( cert );
+ tokendbDebug( "\n" );
+
+ base64_cert = stripBase64HeaderAndFooter( cert );
+
+ tokendbDebug( base64_cert );
+ tokendbDebug( "\n" );
+
+ userid = tus_authenticate( base64_cert );
+
+ if( userid == NULL ) {
+ error_out("Authentication Failure", "Failed to authenticate request");
+
+ SECStatus rv;
+ SECItem certDER;
+ CERTCertificate *c = NULL;
+
+ rv = ATOB_ConvertAsciiToItem(&certDER, base64_cert);
+ if (rv) {
+ RA::Debug("mod_tokendb_handler::mod_tokendb_handler", "Error converting certificate data to binary");
+ } else {
+ c = CERT_DecodeCertFromPackage((char *)certDER.data, certDER.len);
+ }
+
+ RA::Audit(EV_AUTH_FAIL, AUDIT_MSG_AUTH,
+ (c!= NULL) && (c->subjectName != NULL) ? c->subjectName : "null",
+ "null", "Failure", "authentication failure");
+ do_free(buf);
+
+ if (c != NULL) {
+ CERT_DestroyCertificate(c);
+ }
+
+ return DONE;
+ }
+ do_free(base64_cert);
+
+ // useful to indicate cn of user cert
+ RA::Audit(EV_AUTH_SUCCESS, AUDIT_MSG_AUTH, userid, userid, "Success", "authentication success");
+
+ /* authorization */
+ is_admin = tus_authorize(TOKENDB_ADMINISTRATORS_IDENTIFIER, userid);
+ if (is_admin) {
+ RA::Audit(EV_ROLE_ASSUME, AUDIT_MSG_ROLE, userid, "Tokendb Admin", "Success", "assume privileged role");
+ }
+
+ is_agent = tus_authorize(TOKENDB_AGENTS_IDENTIFIER, userid);
+ if (is_agent) {
+ RA::Audit(EV_ROLE_ASSUME, AUDIT_MSG_ROLE, userid, "Tokendb Agent", "Success", "assume privileged role");
+ }
+
+ is_operator = tus_authorize(TOKENDB_OPERATORS_IDENTIFIER, userid);
+ if (is_operator) {
+ RA::Audit(EV_ROLE_ASSUME, AUDIT_MSG_ROLE, userid, "Tokendb Operator", "Success", "assume privileged role");
+ }
+
+ if( rq->uri != NULL ) {
+ uri = PL_strdup( rq->uri );
+ }
+
+ if (rq->method_number == M_POST) {
+ status = read_post(rq, &post);
+ if(post && !apr_is_empty_table(post)) {
+ query = PL_strdup( apr_table_get(post, "query"));
+ }
+ } else {
+ /* GET request */
+ if( rq->args != NULL ) {
+ query = PL_strdup( rq->args );
+ }
+ }
+
+ RA::Debug( "mod_tokendb_handler::mod_tokendb_handler",
+ "uri='%s' params='%s'",
+ uri, ( query==NULL?"":query ) );
+
+ if( query == NULL ) {
+ char *itemplate = NULL;
+ tokendbDebug( "authorization for index case\n" );
+ if (is_agent) {
+ itemplate = indexTemplate;
+ } else if (is_operator) {
+ itemplate = indexOperatorTemplate;
+ } else if (is_admin) {
+ itemplate = indexAdminTemplate;
+ } else {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "index", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "index", "Success", "Tokendb user authorization");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var agent_target_list = \"",
+ RA::GetConfigStore()->GetConfigAsString("target.agent_approve.list", ""), "\";\n",
+ "var target_list = \"",
+ RA::GetConfigStore()->GetConfigAsString("target.configure.list", ""), "\";\n" );
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( itemplate, injection );
+ itemplate = NULL;
+ } else if( ( PL_strstr( query, "op=index_operator" ) ) ) {
+ tokendbDebug( "authorization for op=index_operator\n" );
+ if (!is_operator) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "index_operator", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "index_operator", "Success", "Tokendb user authorization");
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid,
+ "\";\n" );
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( indexOperatorTemplate, injection );
+ } else if( ( PL_strstr( query, "op=index_admin" ) ) ) {
+ tokendbDebug( "authorization\n" );
+ if (!is_admin) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "index_admin", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "index_admin", "Success", "Tokendb user authorization");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var target_list = \"", RA::GetConfigStore()->GetConfigAsString("target.configure.list", ""), "\";\n" );
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( indexAdminTemplate, injection );
+ } else if( ( PL_strstr( query, "op=do_token" ) ) ) {
+ tokendbDebug( "authorization for do_token\n" );
+
+ if( !is_agent ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "do_token", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "do_token", "Success", "Tokendb user authorization");
+
+ /* XXX - chrisho */
+ /* op=do_token */
+ /* question=1|2|... */
+ /* tid=cuid */
+
+ tokendbDebug( "print query\n" );
+ tokendbDebug( query );
+ tokendbDebug( "\n" );
+
+ tid = PL_strstr( query, "tid=" );
+ if( tid != NULL ) {
+ end = PL_strchr( tid, '&' );
+ if( end != NULL ) {
+ i = end - tid - 4;
+ if( i > 0 ) {
+ memcpy( cuid, tid+4, i );
+ }
+ cuid[i] = '\0';
+ } else {
+ PL_strcpy( cuid, tid+4 );
+ }
+ }
+
+ tokendbDebug( "cuid:" );
+ tokendbDebug( cuid );
+ tokendbDebug( "\n" );
+ question = PL_strstr( query, "question=" );
+ q = question[9] - '0';
+
+ PR_snprintf( question_no, 256, "%d", q );
+
+ tokendbDebug( "question_no:" );
+ tokendbDebug( question_no );
+
+ rc = find_tus_db_entry( cuid, 1, &result );
+ if( rc == 0 ) {
+ e = get_first_entry( result );
+ if( e != NULL ) {
+ attr_values = get_attribute_values( e, "tokenUserID" );
+ tokendbDebug( "cuidUserId:" );
+ if (valid_berval(attr_values)) {
+ PL_strcpy( cuidUserId, attr_values[0]->bv_val );
+ tokendbDebug( cuidUserId );
+ free_values(attr_values, 1);
+ attr_values = NULL;
+ } else
+ tokendbDebug("null");
+
+ attr_values = get_attribute_values( e, "tokenType" );
+ tokendbDebug( "tokenType:" );
+ if (valid_berval(attr_values)) {
+ PL_strcpy( tokenType, attr_values[0]->bv_val );
+ tokendbDebug( tokenType );
+ free_values(attr_values, 1);
+ attr_values = NULL;
+ } else
+ tokendbDebug("null");
+
+ attr_values = get_attribute_values( e, "tokenStatus" );
+ tokendbDebug( "tokenStatus:" );
+ if (valid_berval(attr_values)) {
+ PL_strcpy( tokenStatus, attr_values[0]->bv_val );
+ tokendbDebug( tokenStatus );
+ free_values(attr_values, 1);
+ attr_values = NULL;
+ } else
+ tokendbDebug("null");
+
+ attr_values = get_attribute_values( e, "tokenReason" );
+ tokendbDebug( "tokenReason:" );
+ if (valid_berval(attr_values)) {
+ PL_strcpy( tokenReason, attr_values[0]->bv_val );
+ tokendbDebug( tokenReason );
+ free_values(attr_values, 1);
+ attr_values = NULL;
+ } else
+ tokendbDebug("null");
+ }
+ }
+
+ if( result != NULL ) {
+ ldap_msgfree( result );
+ }
+
+ token_ui_state = get_token_ui_state(tokenStatus, tokenReason);
+
+ /* Is this token physically damaged */
+ if(( q == 1 ) && (transition_allowed(token_ui_state, 1))) {
+
+ PR_snprintf((char *)msg, 256,
+ "'%s' marked token physically damaged", userid);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "initiated",
+ msg, cuidUserId, tokenType);
+
+ /* get the certificates on this lost token */
+ PR_snprintf( ( char * ) filter, 256,
+ "(&(tokenID=%s)(tokenUserID=%s))",
+ cuid, cuidUserId );
+ rc = find_tus_certificate_entries_by_order_no_vlv( filter,
+ &result, 1 );
+ if( rc == 0 ) {
+ CertEnroll *certEnroll = new CertEnroll();
+ for( e = get_first_entry( result );
+ e != NULL;
+ e = get_next_entry( e ) ) {
+ char *attr_status = get_cert_status( e );
+
+ if( strcmp( attr_status, "revoked" ) == 0 ) {
+ if( attr_status != NULL ) {
+ PL_strfree( attr_status );
+ attr_status = NULL;
+ }
+
+ continue;
+ }
+
+ char *attr_serial= get_cert_serial( e );
+ char *attr_tokenType = get_cert_tokenType( e );
+ char *attr_keyType = get_cert_type( e );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.recovery."
+ "destroyed.revokeCert",
+ attr_tokenType, attr_keyType );
+
+ bool revokeCert = RA::GetConfigStore()->
+ GetConfigAsBool( configname, true );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.recovery."
+ "destroyed.revokeCert.reason",
+ attr_tokenType, attr_keyType );
+
+ char *revokeReason = ( char * )
+ ( RA::GetConfigStore()->
+ GetConfigAsString( configname,
+ "0" ) );
+
+ if( revokeCert ) {
+ char *attr_cn = get_cert_cn( e );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.ca.conn",
+ attr_tokenType, attr_keyType );
+
+ char *connid = ( char * )
+ ( RA::GetConfigStore()->
+ GetConfigAsString( configname ) );
+
+ PR_snprintf( serial, 100, "0x%s", attr_serial );
+
+ statusNum = certEnroll->RevokeCertificate(revokeReason,
+ serial, connid, statusString );
+
+ if (statusNum != 0) { // revocation errors
+ if( strcmp( revokeReason, "6" ) == 0 ) {
+ PR_snprintf((char *)msg, 256, "Errors in marking certificate on_hold '%s' : %s", attr_cn, statusString);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType);
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Failure", "revoked_on_hold", serial, connid, statusString);
+ } else {
+ PR_snprintf((char *)msg, 256, "Errors in revoking certificate '%s' : %s", attr_cn, statusString);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType);
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Failure", "revoke", serial, connid, statusString);
+ }
+ } else {
+ // update certificate status
+ if( strcmp( revokeReason, "6" ) == 0 ) {
+ PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as revoked_on_hold", attr_cn);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType);
+ update_cert_status( attr_cn, "revoked_on_hold" );
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Success", "revoked_on_hold", serial, connid, "");
+ } else {
+ PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as revoked", attr_cn);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType);
+ update_cert_status( attr_cn, "revoked" );
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Success", "revoke", serial, connid, "");
+ }
+ }
+
+ if( attr_cn != NULL ) {
+ PL_strfree( attr_cn );
+ attr_cn = NULL;
+ }
+ do_free(statusString);
+ }
+
+ if( attr_status != NULL ) {
+ PL_strfree( attr_status );
+ attr_status = NULL;
+ }
+
+ if( attr_serial != NULL ) {
+ PL_strfree( attr_serial );
+ attr_serial = NULL;
+ }
+
+ if( attr_tokenType != NULL ) {
+ PL_strfree( attr_tokenType );
+ attr_tokenType = NULL;
+ }
+
+ if( attr_keyType != NULL ) {
+ PL_strfree( attr_keyType );
+ attr_keyType = NULL;
+ }
+ }
+
+ if( result != NULL ) {
+ ldap_msgfree( result );
+ }
+
+ if( certEnroll != NULL ) {
+ delete certEnroll;
+ certEnroll = NULL;
+ }
+
+ }
+
+ /* change the tokenStatus to lost (reason: destroyed). */
+ rc = update_token_status_reason( cuidUserId, cuid,
+ "lost", "destroyed" );
+ if( rc == -1 ) {
+ tokendbDebug( "token is physically damaged. rc = -1\n" );
+
+ PR_snprintf(oString, 512, "token_id;;%s", cuid);
+ PR_snprintf(pString, 512, "tokenStatus;;lost+tokenReason;;destroyed");
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked physically damaged, rc=-1");
+
+ PR_snprintf((char *)msg, 256, "Failed to update token status as physically damaged");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure",
+ msg, cuidUserId, tokenType);
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s", JS_START,
+ "var error = \"Failed to create LDAPMod: ",
+ "\";\n", JS_STOP );
+
+ buf = getData( errorTemplate, injection );
+
+ ap_log_error( ( const char * ) "tus", __LINE__,
+ APLOG_ERR, 0, rq->server,
+ ( const char * ) "Failed to create LDAPMod" );
+
+ ( void ) ap_rwrite( ( const void * ) buf,
+ PL_strlen( buf ), rq );
+
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ } else if( rc > 0 ) {
+ tokendbDebug( "token is physically damaged. rc > 0\n" );
+
+ PR_snprintf(oString, 512, "token_id;;%s", cuid);
+ PR_snprintf(pString, 512, "tokenStatus;;lost+tokenReason;;destroyed");
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked physically damaged, rc>0");
+
+ PR_snprintf((char *)msg, 256, "Failed to update token status as physically damaged");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure",
+ msg, cuidUserId, tokenType);
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s", JS_START,
+ "var error = \"LDAP mod error: ",
+ ldap_err2string( rc ),
+ "\";\n", JS_STOP );
+
+ buf = getData( errorTemplate, injection );
+
+ ap_log_error( ( const char * ) "tus", __LINE__,
+ APLOG_ERR, 0, rq->server,
+ ( const char * ) "LDAP error: %s",
+ ldap_err2string( rc ) );
+
+ ( void ) ap_rwrite( ( const void * ) buf,
+ PL_strlen( buf ), rq );
+
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+
+ PR_snprintf(oString, 512, "token_id;;%s", cuid);
+ PR_snprintf(pString, 512, "tokenStatus;;lost+tokenReason;;destroyed");
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Success", oString, pString, "token marked physically damaged");
+
+ PR_snprintf((char *)msg, 256, "Token marked as physically damaged");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success",
+ msg, cuidUserId, tokenType);
+
+ /* Is this token permanently lost? */
+ } else if(((q == 2) && (transition_allowed(token_ui_state, 2))) ||
+ ((q == 6) && (transition_allowed(token_ui_state, 6)))) {
+ if (q == 2) {
+ PR_snprintf((char *)msg, 256,
+ "'%s' marked token permanently lost", userid);
+ } else {
+ PR_snprintf((char *)msg, 256,
+ "'%s' marked token terminated", userid);
+ }
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "initiated",
+ msg, cuidUserId, tokenType);
+
+ /* get the certificates on this lost token */
+ PR_snprintf( ( char * ) filter, 256,
+ "(&(tokenID=%s)(tokenUserID=%s))",
+ cuid, cuidUserId );
+
+ rc = find_tus_certificate_entries_by_order_no_vlv( filter,
+ &result, 1 );
+ if( rc == 0 ) {
+ CertEnroll *certEnroll = new CertEnroll();
+ for( e = get_first_entry( result );
+ e != NULL;
+ e = get_next_entry( e ) ) {
+ char *attr_status = get_cert_status( e );
+
+ if( strcmp( attr_status, "revoked" ) == 0 ) {
+ if( attr_status != NULL ) {
+ PL_strfree( attr_status );
+ attr_status = NULL;
+ }
+
+ continue;
+ }
+
+ char *attr_serial= get_cert_serial( e );
+ char *attr_tokenType = get_cert_tokenType( e );
+ char *attr_keyType = get_cert_type( e );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.recovery."
+ "keyCompromise.revokeCert",
+ attr_tokenType, attr_keyType );
+
+ bool revokeCert = RA::GetConfigStore()->
+ GetConfigAsBool( configname, true );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.recovery."
+ "keyCompromise.revokeCert.reason",
+ attr_tokenType, attr_keyType );
+
+ char *revokeReason = ( char * )
+ ( RA::GetConfigStore()->
+ GetConfigAsString( configname,
+ "1" ) );
+
+ if( revokeCert ) {
+ char *attr_cn = get_cert_cn( e );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.ca.conn",
+ attr_tokenType, attr_keyType );
+
+ char *connid = ( char * )
+ ( RA::GetConfigStore()->
+ GetConfigAsString( configname ) );
+
+ PR_snprintf( serial, 100, "0x%s", attr_serial );
+
+ statusNum = certEnroll->
+ RevokeCertificate( revokeReason,
+ serial,
+ connid,
+ statusString );
+ if (statusNum != 0) { // revocation errors
+ if( strcmp( revokeReason, "6" ) == 0 ) {
+ PR_snprintf((char *)msg, 256, "Errors in marking certificate on_hold '%s' : %s", attr_cn, statusString);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType);
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Failure", "revoked_on_hold", serial, connid, statusString);
+ } else {
+ PR_snprintf((char *)msg, 256, "Errors in revoking certificate '%s' : %s", attr_cn, statusString);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType);
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Failure", "revoke", serial, connid, statusString);
+ }
+ } else {
+ // update certificate status
+ if( strcmp( revokeReason, "6" ) == 0 ) {
+ PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as revoked_on_hold", attr_cn);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType);
+ update_cert_status( attr_cn, "revoked_on_hold" );
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Success", "revoked_on_hold", serial, connid, "");
+ } else {
+ PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as revoked", attr_cn);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType);
+ update_cert_status( attr_cn, "revoked" );
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Success", "revoke", serial, connid, "");
+ }
+ }
+
+ if( attr_cn != NULL ) {
+ PL_strfree( attr_cn );
+ attr_cn = NULL;
+ }
+ do_free(statusString);
+ }
+
+ if( attr_status != NULL ) {
+ PL_strfree( attr_status );
+ attr_status = NULL;
+ }
+
+ if( attr_serial != NULL ) {
+ PL_strfree( attr_serial );
+ attr_serial = NULL;
+ }
+
+ if( attr_tokenType != NULL ) {
+ PL_strfree( attr_tokenType );
+ attr_tokenType = NULL;
+ }
+
+ if( attr_keyType != NULL ) {
+ PL_strfree( attr_keyType );
+ attr_keyType = NULL;
+ }
+ }
+
+ if( result != NULL ) {
+ ldap_msgfree( result );
+ }
+
+ if( certEnroll != NULL ) {
+ delete certEnroll;
+ certEnroll = NULL;
+ }
+ }
+
+ /* revoke all the certs on the token. make http connection to CA */
+
+ /* change the tokenStatus to lost (reason: keyCompromise) */
+ tokendbDebug( "Revoke all the certs on this token "
+ "(reason: keyCompromise)\n" );
+
+ PR_snprintf(oString, 512, "token_id;;%s", cuid);
+
+ if (q == 6) { /* terminated */
+ PR_snprintf(pString, 512, "tokenStatus;;terminated+tokenReason;;keyCompromise");
+ rc = update_token_status_reason( cuidUserId, cuid,
+ "terminated", "keyCompromise" );
+ } else {
+ PR_snprintf(pString, 512, "tokenStatus;;lost+tokenReason;;keyCompromise");
+ rc = update_token_status_reason( cuidUserId, cuid,
+ "lost", "keyCompromise" );
+ }
+ if( rc == -1 ) {
+ if (q == 6) { /* terminated*/
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked terminated, rc=-1");
+ PR_snprintf((char *)msg, 256, "Failure in updating token status to terminated");
+ } else {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked permanently lost, rc=-1");
+ PR_snprintf((char *)msg, 256, "Failure in updating token status to permanently lost");
+ }
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure",
+ msg, cuidUserId, tokenType);
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s", JS_START,
+ "var error = \"Failed to create LDAPMod: ",
+ "\";\n", JS_STOP );
+
+ buf = getData( errorTemplate, injection );
+
+ ap_log_error( ( const char * ) "tus", __LINE__,
+ APLOG_ERR, 0, rq->server,
+ ( const char * ) "Failed to create LDAPMod" );
+
+ ( void ) ap_rwrite( ( const void * ) buf,
+ PL_strlen( buf ), rq );
+
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ } else if( rc > 0 ) {
+ if (q == 6) { /* terminated*/
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked terminated, rc=>0");
+ PR_snprintf((char *)msg, 256, "Failure in updating token status to terminated");
+ } else {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked permanently lost, rc>0");
+ PR_snprintf((char *)msg, 256, "Failure in updating token status to permanently lost");
+ }
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure",
+ msg, cuidUserId, tokenType);
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s", JS_START,
+ "var error = \"LDAP mod error: ",
+ ldap_err2string( rc ),
+ "\";\n", JS_STOP );
+
+ buf = getData( errorTemplate, injection );
+
+ ap_log_error( ( const char * ) "tus", __LINE__,
+ APLOG_ERR, 0, rq->server,
+ ( const char * ) "LDAP error: %s",
+ ldap_err2string( rc ) );
+
+ ( void ) ap_rwrite( ( const void * ) buf,
+ PL_strlen( buf ), rq );
+
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ if (q == 6) { /* terminated*/
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Success", oString, pString, "token marked terminated");
+ PR_snprintf((char *)msg, 256, "Token marked terminated");
+ } else {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Success", oString, pString, "token marked permanently lost");
+ PR_snprintf((char *)msg, 256, "Token marked permanently lost");
+ }
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success",
+ msg, cuidUserId, tokenType);
+
+ /* Is this token temporarily lost? */
+ } else if(( q == 3 ) && (transition_allowed(token_ui_state, 3))) {
+ bool revocation_errors = false;
+ PR_snprintf((char *)msg, 256,
+ "'%s' marked token temporarily lost", userid);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "initiated",
+ msg, cuidUserId, tokenType);
+
+ /* all certs on the token are revoked (onHold) */
+ tokendbDebug( "Revoke all the certs on this token "
+ "(reason: onHold)\n" );
+
+ /* get the certificates on this lost token */
+ PR_snprintf( ( char * ) filter, 256,
+ "(&(tokenID=%s)(tokenUserID=%s))",
+ cuid, cuidUserId );
+
+ rc = find_tus_certificate_entries_by_order_no_vlv( filter,
+ &result, 1 );
+ if( rc == 0 ) {
+ CertEnroll *certEnroll = new CertEnroll();
+ for( e = get_first_entry( result );
+ e != NULL;
+ e = get_next_entry( e ) ) {
+ char *attr_status = get_cert_status( e );
+ if( strcmp( attr_status, "revoked" ) == 0 ||
+ strcmp( attr_status, "revoked_on_hold" ) == 0 ) {
+ if( attr_status != NULL ) {
+ PL_strfree( attr_status );
+ attr_status = NULL;
+ }
+
+ continue;
+ }
+
+ char *attr_serial= get_cert_serial( e );
+ char *attr_tokenType = get_cert_tokenType( e );
+ char *attr_keyType = get_cert_type( e );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.recovery."
+ "onHold.revokeCert",
+ attr_tokenType, attr_keyType );
+
+ bool revokeCert = RA::GetConfigStore()->
+ GetConfigAsBool( configname, true );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.recovery.onHold."
+ "revokeCert.reason",
+ attr_tokenType, attr_keyType );
+
+ char *revokeReason = ( char * )
+ ( RA::GetConfigStore()->
+ GetConfigAsString( configname,
+ "0" ) );
+
+ if( revokeCert ) {
+ char *attr_cn = get_cert_cn( e );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.ca.conn",
+ attr_tokenType, attr_keyType );
+
+ char *connid = ( char * )
+ ( RA::GetConfigStore()->
+ GetConfigAsString( configname ) );
+
+ PR_snprintf( serial, 100, "0x%s", attr_serial );
+
+ statusNum = certEnroll->
+ RevokeCertificate( revokeReason,
+ serial,
+ connid,
+ statusString );
+
+ if (statusNum != 0) { // revocation errors
+ if( strcmp( revokeReason, "6" ) == 0 ) {
+ PR_snprintf((char *)msg, 256, "Errors in marking certificate on_hold '%s' : %s", attr_cn, statusString);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType);
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Failure", "revoked_on_hold", serial, connid, statusString);
+ } else {
+ PR_snprintf((char *)msg, 256, "Errors in revoking certificate '%s' : %s", attr_cn, statusString);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType);
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Failure", "revoke", serial, connid, statusString);
+ }
+ revocation_errors = true;
+ } else {
+ // update certificate status
+ if( strcmp( revokeReason, "6" ) == 0 ) {
+ PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as revoked_on_hold", attr_cn);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType);
+ update_cert_status( attr_cn, "revoked_on_hold" );
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Success", "revoked_on_hold", serial, connid, "");
+ } else {
+ PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as revoked", attr_cn);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType);
+ update_cert_status( attr_cn, "revoked" );
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Success", "revoke", serial, connid, "");
+ }
+ }
+
+ do_free(statusString);
+ }
+
+ if( attr_status != NULL ) {
+ PL_strfree( attr_status );
+ attr_status = NULL;
+ }
+
+ if( attr_serial != NULL ) {
+ PL_strfree( attr_serial );
+ attr_serial = NULL;
+ }
+
+ if( attr_tokenType != NULL ) {
+ PL_strfree( attr_tokenType );
+ attr_tokenType = NULL;
+ }
+
+ if( attr_keyType != NULL ) {
+ PL_strfree( attr_keyType );
+ attr_keyType = NULL;
+ }
+ }
+
+ if (result != NULL) {
+ ldap_msgfree( result );
+ }
+
+ if( certEnroll != NULL ) {
+ delete certEnroll;
+ certEnroll = NULL;
+ }
+
+ }
+
+ PR_snprintf(oString, 512, "token_id;;%s", cuid);
+ PR_snprintf(pString, 512, "tokenStatus;;lost+tokenReason;;onHold");
+ if (revocation_errors) {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked temporarily lost failed, failed to revoke certificates");
+
+ PR_snprintf((char *)msg, 256, "Failed to revoke certificates");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure",
+ msg, cuidUserId, tokenType);
+
+ error_out("Errors in revoking certificates.", "Errors in revoking certificates.");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ rc = update_token_status_reason( cuidUserId, cuid,
+ "lost", "onHold" );
+ if( rc == -1 ) {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked temporarily lost, rc=-1");
+
+ PR_snprintf((char *)msg, 256, "Failed to update token status as temporarily lost");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure",
+ msg, cuidUserId, tokenType);
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s", JS_START,
+ "var error = \"Failed to create LDAPMod: ",
+ "\";\n", JS_STOP );
+
+ buf = getData( errorTemplate, injection );
+
+ ap_log_error( ( const char * ) "tus", __LINE__,
+ APLOG_ERR, 0, rq->server,
+ ( const char * ) "Failed to create LDAPMod" );
+
+ ( void ) ap_rwrite( ( const void * ) buf,
+ PL_strlen( buf ), rq );
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ } else if( rc > 0 ) {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked temporarily lost, rc>0");
+
+ PR_snprintf((char *)msg, 256, "Failed to update token status as temporarily lost");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure",
+ msg, cuidUserId, tokenType);
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s", JS_START,
+ "var error = \"LDAP mod error: ",
+ ldap_err2string( rc ),
+ "\";\n", JS_STOP );
+
+ buf = getData( errorTemplate, injection );
+
+ ap_log_error( ( const char * ) "tus", __LINE__,
+ APLOG_ERR, 0, rq->server,
+ ( const char * ) "LDAP error: %s",
+ ldap_err2string( rc ) );
+
+ ( void ) ap_rwrite( ( const void * ) buf,
+ PL_strlen( buf ), rq );
+
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Success", oString, pString, "token marked temporarily lost");
+ PR_snprintf((char *)msg, 256, "Token marked temporarily lost");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success",
+ msg, cuidUserId, tokenType);
+
+ /* Is this temporarily lost token found? */
+ } else if(( q == 4 ) && ( transition_allowed(token_ui_state, 4) )) {
+
+ PR_snprintf((char *)msg, 256,
+ "'%s' marked lost token found", userid);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "initiated",
+ msg, cuidUserId, tokenType);
+
+ tokendbDebug( "The temporarily lost token is found.\n" );
+
+ // to find out the tokenType on this lost token
+ PR_snprintf( ( char * ) filter, 256,
+ "(&(tokenID=%s)(tokenUserID=%s))",
+ cuid, cuidUserId );
+
+ /* all certs on the token are unrevoked (offHold) */
+ /* get the certificates on this lost token */
+ tokendbDebug( "Offhold all the certificates on "
+ "the temp lost token." );
+
+ rc = find_tus_certificate_entries_by_order_no_vlv( filter,
+ &result, 1 );
+ if( rc == 0 ) {
+ CertEnroll *certEnroll = new CertEnroll();
+ for( e = get_first_entry( result );
+ e != NULL;
+ e = get_next_entry( e ) ) {
+ char *attr_status = get_cert_status( e );
+ if( strcmp( attr_status, "active" ) == 0 ||
+ strcmp( attr_status, "revoked" ) == 0 ) {
+ if( attr_status != NULL ) {
+ PL_strfree( attr_status );
+ attr_status = NULL;
+ }
+
+ continue;
+ }
+
+ char *attr_serial= get_cert_serial( e );
+ char *attr_tokenType = get_cert_tokenType( e );
+ char *attr_keyType = get_cert_type( e );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.recovery."
+ "onHold.revokeCert",
+ attr_tokenType, attr_keyType );
+
+ bool revokeCert = RA::GetConfigStore()->
+ GetConfigAsBool( configname, true );
+ if( revokeCert ) {
+ char *attr_cn = get_cert_cn( e );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.ca.conn",
+ attr_tokenType, attr_keyType );
+
+ char *connid = ( char * )
+ ( RA::GetConfigStore()->
+ GetConfigAsString( configname ) );
+
+
+ PR_snprintf( serial, 100, "0x%s", attr_serial );
+
+ int statusNum = certEnroll->
+ UnrevokeCertificate( serial,
+ connid,
+ statusString );
+
+ if (statusNum == 0) {
+ PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as active", attr_cn);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType);
+ update_cert_status( attr_cn, "active" );
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Success", "unrevoke", serial, connid, "");
+ } else {
+ PR_snprintf((char *)msg, 256, "Errors in unrevoking Certificate '%s': %s", attr_cn, statusString);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType);
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Failure", "unrevoke", serial, connid, statusString);
+ }
+
+ if( attr_cn != NULL ) {
+ PL_strfree( attr_cn );
+ attr_cn = NULL;
+ }
+
+ do_free(statusString);
+ }
+
+ if( attr_serial != NULL ) {
+ PL_strfree( attr_serial );
+ attr_serial = NULL;
+ }
+
+ if( attr_tokenType != NULL ) {
+ PL_strfree( attr_tokenType );
+ attr_tokenType = NULL;
+ }
+
+ if( attr_keyType != NULL ) {
+ PL_strfree( attr_keyType );
+ attr_keyType = NULL;
+ }
+ } // end of for loop
+
+ if( result != NULL ) {
+ ldap_msgfree( result );
+ }
+
+ if( certEnroll != NULL ) {
+ delete certEnroll;
+ certEnroll = NULL;
+ }
+ }
+
+ update_token_status_reason( cuidUserId, cuid, "active", NULL );
+ PR_snprintf(oString, 512, "token_id;;%s", cuid);
+ PR_snprintf(pString, 512, "tokenStatus;;active+tokenReason;;null");
+
+ if( rc == -1 ) {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "lost token marked found, rc=-1");
+ PR_snprintf((char *)msg, 256, "Failed to update lost token status as found");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure",
+ msg, cuidUserId, tokenType);
+
+ error_out("Failed to create LDAPMod: ", "Failed to create LDAPMod");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ } else if( rc > 0 ) {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "lost token marked found, rc>0");
+ PR_snprintf((char *)msg, 256, "Failed to update lost token status as found");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure",
+ msg, cuidUserId, tokenType);
+
+ ldap_error_out("LDAP mod error: ", "LDAP error: %s");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Success", oString, pString, "lost token marked found");
+ PR_snprintf((char *)msg, 256, "Lost token marked found");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success",
+ msg, cuidUserId, tokenType);
+
+ /* Does this temporarily lost token become permanently lost? */
+ } else if ( (q == 5) && (transition_allowed(token_ui_state, 5)) ) {
+
+ PR_snprintf((char *)msg, 256,
+ "'%s' marked lost token permanently lost", userid);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "initiated",
+ msg, cuidUserId, tokenType);
+
+ tokendbDebug( "Change the revocation reason from onHold "
+ "to keyCompromise\n" );
+
+ // to find out the tokenType on this lost token
+ PR_snprintf( ( char * ) filter, 256,
+ "(&(tokenID=%s)(tokenUserID=%s))",
+ cuid, cuidUserId );
+
+ /* revoke all the certs on this token (reason: keyCompromise) */
+ tokendbDebug( "Revoke all the certs on this token "
+ "(reason: keyCompromise)\n" );
+
+ /* get the certificates on this lost token */
+ PR_snprintf( ( char * ) filter, 256,
+ "(&(tokenID=%s)(tokenUserID=%s))",
+ cuid, cuidUserId );
+
+ rc = find_tus_certificate_entries_by_order_no_vlv( filter,
+ &result, 1 );
+ if( rc == 0 ) {
+ CertEnroll *certEnroll = new CertEnroll();
+ for( e = get_first_entry(result);
+ e != NULL;
+ e = get_next_entry( e ) ) {
+ char *attr_status = get_cert_status( e );
+ if( strcmp( attr_status, "revoked" ) == 0 ) {
+ if( attr_status != NULL ) {
+ PL_strfree( attr_status );
+ attr_status = NULL;
+ }
+ continue;
+ }
+
+ char *attr_serial= get_cert_serial( e );
+ char *attr_tokenType = get_cert_tokenType( e );
+ char *attr_keyType = get_cert_type( e );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.recovery."
+ "keyCompromise.revokeCert",
+ attr_tokenType, attr_keyType );
+
+ bool revokeCert = RA::GetConfigStore()->
+ GetConfigAsBool( configname, true );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.recovery."
+ "keyCompromise.revokeCert.reason",
+ attr_tokenType, attr_keyType );
+
+ char *revokeReason = ( char * )
+ ( RA::GetConfigStore()->
+ GetConfigAsString( configname,
+ "1" ) );
+
+ if( revokeCert ) {
+ char *attr_cn = get_cert_cn( e );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.ca.conn",
+ attr_tokenType, attr_keyType );
+
+ char *connid = ( char * )
+ ( RA::GetConfigStore()->
+ GetConfigAsString( configname ) );
+
+ PR_snprintf( serial, 100, "0x%s", attr_serial );
+
+ int statusNum = 0;
+ if(( strcmp( attr_status, "revoked_on_hold" ) == 0 ) && (strcmp(revokeReason, "6" ) != 0)) {
+ statusNum = certEnroll->
+ UnrevokeCertificate( serial,
+ connid,
+ statusString );
+ if (statusNum == 0) {
+ PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as active", attr_cn);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "initiated", msg, cuidUserId, attr_tokenType);
+ update_cert_status( attr_cn, "active" );
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Success", "unrevoke", serial, connid, "");
+
+ do_free(statusString);
+ statusNum = certEnroll->
+ RevokeCertificate( revokeReason,
+ serial,
+ connid,
+ statusString );
+ if (statusNum == 0) {
+ PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as revoked", attr_cn);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType);
+ update_cert_status( attr_cn, "revoked" );
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Success", "revoke", serial, connid, "");
+ } else {
+ PR_snprintf((char *)msg, 256, "Errors in revoking Certificate '%s' : %s", attr_cn, statusString);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType);
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Failure", "revoke", serial, connid, statusString);
+ }
+ } else {
+ PR_snprintf((char *)msg, 256, "Errors in unrevoking Certificate '%s' : %s", attr_cn, statusString);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType);
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Failure", "unrevoke", serial, connid, statusString);
+ }
+
+ do_free(statusString);
+ }
+
+ if( attr_cn != NULL ) {
+ PL_strfree( attr_cn );
+ attr_cn = NULL;
+ }
+ }
+
+ if( attr_serial != NULL ) {
+ PL_strfree( attr_serial );
+ attr_serial = NULL;
+ }
+
+ if( attr_tokenType != NULL ) {
+ PL_strfree( attr_tokenType );
+ attr_tokenType = NULL;
+ }
+
+ if( attr_keyType != NULL ) {
+ PL_strfree( attr_keyType );
+ attr_keyType = NULL;
+ }
+ } // end of the for loop
+
+ if( result != NULL ) {
+ ldap_msgfree( result );
+ }
+
+ if( certEnroll != NULL ) {
+ delete certEnroll;
+ certEnroll = NULL;
+ }
+ }
+
+ rc = update_token_status_reason( cuidUserId, cuid,
+ "lost", "keyCompromise" );
+
+ PR_snprintf(oString, 512, "token_id;;%s", cuid);
+ PR_snprintf(pString, 512, "tokenStatus;;lost+tokenReason;;keyCompromise");
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Success", oString, pString, "lost token marked permanently lost");
+
+ PR_snprintf((char *)msg, 256, "Lost token marked permanently lost");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success",
+ msg, cuidUserId, tokenType);
+ } else {
+ // invalid operation or transition
+ error_out("Transition or operation not allowed", "Transition or operation not allowed");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ tokendbDebug( "do_token: rc = 0\n" );
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%d%s%s%s%s%s%s%s", JS_START,
+ "var rc = \"", rc, "\";\n",
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid,
+ "\";\n" );
+
+ add_allowed_token_transitions(token_ui_state, injection);
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( doTokenTemplate, injection );
+/* currently not used - alee
+ } else if( ( PL_strstr( query, "op=revoke" ) ) ) {
+ tokendbDebug("authorization\n");
+
+ if( ! is_agent ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "revoke", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "revoke", "Success", "Tokendb user authorization");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid,
+ "\";\n" );
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( revokeTemplate, injection );
+*/
+ } else if( ( PL_strstr( query, "op=search_activity_admin" ) ) ) {
+ tokendbDebug( "authorization\n" );
+
+ if (! is_admin) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "search_activity_admin", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "search_activity_admin", "Success", "Tokendb user authorization");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid,
+ "\";\n" );
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( searchActivityAdminTemplate, injection );
+ } else if( ( PL_strstr( query, "op=search_activity" ) ) ) {
+ tokendbDebug( "authorization\n" );
+
+ if ((! is_agent) && (! is_operator)) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "search_activity", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "search_activity", "Success", "Tokendb user authorization");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid,
+ "\";\n" );
+
+ topLevel = get_field(query, "top=", SHORT_LEN);
+ if ((topLevel != NULL) && (PL_strstr(topLevel, "operator"))) {
+ PL_strcat(injection, "var topLevel = \"operator\";\n");
+ }
+ do_free(topLevel);
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( searchActivityTemplate, injection );
+ } else if( ( PL_strstr( query, "op=search_admin" ) ) ||
+ ( PL_strstr( query, "op=search_users" ) )) {
+ tokendbDebug( "authorization\n" );
+
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "search_admin,search_users", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "search_admin,search_users", "Success", "Tokendb user authorization");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid,
+ "\";\n" );
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ if ( PL_strstr( query, "op=search_admin" ) ) {
+ buf = getData( searchAdminTemplate, injection );
+ } else if ( PL_strstr( query, "op=search_users" ) ) {
+ buf = getData( searchUserTemplate, injection );
+ }
+ } else if ( PL_strstr( query, "op=search_certificate" ) ) {
+ tokendbDebug( "authorization\n" );
+ if ((! is_agent) && (! is_operator)) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "search_certificate", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "search_certificate", "Success", "Tokendb user authorization");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid,
+ "\";\n");
+
+ topLevel = get_field(query, "top=", SHORT_LEN);
+ if ((topLevel != NULL) && (PL_strstr(topLevel, "operator"))) {
+ PL_strcat(injection, "var topLevel = \"operator\";\n");
+ }
+ do_free(topLevel);
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( searchCertificateTemplate, injection );
+ } else if( ( PL_strstr( query, "op=search" ) ) ) {
+ tokendbDebug( "authorization for op=search\n" );
+ if ((! is_agent) && (! is_operator)) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "search", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "search", "Success", "Tokendb user authorization");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid,
+ "\";\n");
+
+ topLevel = get_field(query, "top=", SHORT_LEN);
+ if ((topLevel != NULL) && (PL_strstr(topLevel, "operator"))) {
+ PL_strcat(injection, "var topLevel = \"operator\";\n");
+ }
+ do_free(topLevel);
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( searchTemplate, injection );
+ } else if( ( PL_strstr( query, "op=new" ) ) ) {
+ tokendbDebug( "authorization\n" );
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "new", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "new", "Success", "Tokendb user authorization");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid,
+ "\";\n" );
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( newTemplate,injection );
+ } else if ( ( PL_strstr( query, "op=add_user" ) ) ) {
+ tokendbDebug( "authorization for add_user\n" );
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "add_user", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "add_user", "Success", "Tokendb user authorization");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid,
+ "\";\n");
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( newUserTemplate,injection );
+
+ } else if ( ( PL_strstr( query, "op=confirm_delete_config" ) ) ) {
+ tokendbDebug( "authorization for confirm_delete_config\n" );
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "confirm_delete_config", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "confirm_delete_config", "Success", "Tokendb user authorization");
+
+ char *ptype = NULL;
+ char *pname = NULL;
+ char *ptimestamp = NULL;
+ char *pvalues = NULL;
+ char *large_injection = NULL;
+ char *pstate = NULL;
+ char *disp_conf_type = NULL;
+
+ ptype = get_post_field(post, "ptype", SHORT_LEN);
+ pname = get_post_field(post, "pname", SHORT_LEN);
+ pstate = get_post_field(post, "pstate", SHORT_LEN);
+ ptimestamp = get_post_field(post, "ptimestamp", SHORT_LEN);
+ pvalues = get_post_field_s(post, "pvalues");
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", ptype );
+ disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+ large_injection = (char *) PR_Malloc(PL_strlen(pvalues) + MAX_INJECTION_SIZE);
+ PR_snprintf( large_injection, PL_strlen(pvalues) + MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var conf_type = \"", ptype, "\";\n",
+ "var disp_conf_type = \"", disp_conf_type, "\";\n",
+ "var conf_name = \"", pname, "\";\n",
+ "var conf_state = \"", pstate, "\";\n",
+ "var conf_tstamp = \"", ptimestamp, "\";\n",
+ "var agent_must_approve = \"", agent_must_approve(ptype)? "true": "false", "\";\n",
+ "var conf_values= \"", pvalues, "\";\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, large_injection);
+ PL_strcat(large_injection, JS_STOP);
+
+ buf = getData( confirmDeleteConfigTemplate, large_injection );
+
+ do_free(ptype);
+ do_free(pname);
+ do_free(ptimestamp);
+ do_free(pvalues);
+ do_free(pstate);
+ do_free(large_injection);
+ } else if( ( PL_strstr( query, "op=delete_config_parameter" ) ) ) {
+ tokendbDebug( "authorization for op=delete_config_parameter\n" );
+ if (! is_admin) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "delete_config_parameter", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "delete_config_parameter", "Success", "Tokendb user authorization");
+
+ char *ptype = NULL;
+ char *pname = NULL;
+ char *ptimestamp = NULL;
+
+ char *key_values = NULL;
+ char *new_value = NULL;
+ char *conf_list = NULL;
+ ConfigStore *store = NULL;
+ int return_done = 0;
+ int status=0;
+
+ ptype = get_post_field(post, "ptype", SHORT_LEN);
+ pname = get_post_field(post, "pname", SHORT_LEN);
+ ptimestamp = get_post_field(post, "ptimestamp", SHORT_LEN);
+
+ if ((ptype == NULL) || (pname == NULL) || (PL_strlen(pname)==0) || (PL_strlen(ptype)==0)) {
+ error_out("Invalid Invocation: Parameter type or name is NULL or empty", "Parameter type or name is NULL or empty");
+ return_done = 1;
+ goto delete_config_parameter_cleanup;
+ }
+
+ if (!config_param_exists(ptype, pname)) {
+ error_out("Parameter does not exist", "Parameter does not exist");
+ return_done = 1;
+ goto delete_config_parameter_cleanup;
+ }
+
+ status = set_config_state_timestamp(ptype, pname, ptimestamp, "Writing", "Admin", false, userid);
+ if (status != 0) {
+ error_out("The data you are viewing has changed. Please reload the data and try your edits again.", "Data Out of Date");
+ return_done=1;
+ goto delete_config_parameter_cleanup;
+ }
+
+ store = get_pattern_substore(ptype, pname);
+
+ key_values = (char *) store->GetOrderedList();
+ if (PL_strlen(key_values) > 0) parse_and_apply_changes(userid, ptype, pname, "DELETE", key_values);
+
+ // remove from the list for that config type
+ PR_snprintf( ( char * ) configname, 256, "target.%s.list", ptype );
+ conf_list = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+ new_value = RA::remove_from_comma_list((const char*) pname, (char *)conf_list);
+ RA::GetConfigStore()->Add(configname, new_value);
+
+ // remove state and timestamp variables
+ remove_config_state_timestamp(ptype, pname);
+
+ tokendbDebug("Committing delete ..");
+ char error_msg[512];
+ status = RA::GetConfigStore()->Commit(true, error_msg, 512);
+ if (status != 0) {
+ tokendbDebug(error_msg);
+ }
+
+ PR_snprintf(oString, 512, "%s", pname);
+ PR_snprintf(pLongString, 4096, "%s;;%s", configname, new_value);
+ RA::Audit(EV_CONFIG, AUDIT_MSG_CONFIG, userid, "Admin", "Success", oString, pLongString, "config item deleted");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var flash = \"Configuration changes have been saved.\";\n",
+ "var agent_target_list = \"",
+ RA::GetConfigStore()->GetConfigAsString("target.agent_approve.list", ""), "\";\n",
+ "var target_list = \"", RA::GetConfigStore()->GetConfigAsString("target.configure.list", ""), "\";\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( indexTemplate, injection );
+ delete_config_parameter_cleanup:
+ do_free(ptype);
+ do_free(pname);
+ do_free(key_values);
+ do_free(new_value);
+ do_free(ptimestamp);
+
+ if (store != NULL) {
+ delete store;
+ store = NULL;
+ }
+ if (return_done == 1) {
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ } else if( ( PL_strstr( query, "op=add_config_parameter" ) ) ) {
+ tokendbDebug( "authorization for op=add_config_parameter\n" );
+ if (! is_admin) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "add_config_parameter", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "add_config_parameter", "Success", "Tokendb user authorization");
+
+ char *ptype = NULL;
+ char *pname = NULL;
+
+ ConfigStore *store = NULL;
+ char *pattern = NULL;
+ char *disp_conf_type = NULL;
+ int return_done =0;
+
+ ptype = get_post_field(post, "ptype", SHORT_LEN);
+ pname = get_post_field(post, "pname", SHORT_LEN);
+
+ if ((ptype == NULL) || (pname == NULL) || (PL_strlen(pname)==0) || (PL_strlen(ptype)==0)) {
+ error_out("Invalid Invocation: Parameter type or name is NULL or empty", "Parameter type or name is NULL or empty");
+ return_done = 1;
+ goto add_config_parameter_cleanup;
+ }
+
+ if (config_param_exists(ptype, pname)) {
+ error_out("Parameter already exists. Use edit instead.", "Parameter already exists");
+ return_done = 1;
+ goto add_config_parameter_cleanup;
+ }
+
+ /* extra check (just in case) */
+ store = get_pattern_substore(ptype, pname);
+
+ if ((store != NULL) && (store->Size() != 0)) {
+ error_out("Config entries already exist for this parameter. This is an error. Manually delete them first.", "Setup Error");
+ return_done = 1;
+ goto add_config_parameter_cleanup;
+ }
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.pattern", ptype );
+ pattern = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", ptype );
+ disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var conf_type = \"", ptype, "\";\n",
+ "var disp_conf_type = \"", disp_conf_type, "\";\n",
+ "var conf_name = \"", pname, "\";\n",
+ "var conf_pattern = \"", pattern, "\";\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection); //needed?
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( addConfigTemplate, injection );
+ add_config_parameter_cleanup:
+ do_free(ptype);
+ do_free(pname);
+
+ if (store != NULL) {
+ delete store;
+ store = NULL;
+ }
+ if (return_done == 1) {
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ } else if( ( PL_strstr( query, "op=agent_change_config_state" ) ) ) {
+ tokendbDebug( "authorization for op=agent_change_config_state\n" );
+ if (! is_agent) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "agent_change_config_state", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "agent_change_config_state", "Success", "Tokendb user authorization");
+
+ char *ptype = NULL;
+ char *pname = NULL;
+ char *ptimestamp = NULL;
+ char *choice = NULL;
+
+ char pstate[128]="";
+ int return_done =0;
+ int set_status = 0;
+
+ ptype = get_post_field(post, "ptype", SHORT_LEN);
+ pname = get_post_field(post, "pname", SHORT_LEN);
+ ptimestamp = get_post_field(post, "ptimestamp", SHORT_LEN);
+ choice = get_post_field(post, "choice", SHORT_LEN);
+
+ if ((ptype == NULL) || (pname == NULL) || (ptimestamp == NULL) || (choice == NULL)) {
+ error_out("Invalid Invocation: A required parameter is NULL", "Invalid Invocation: A required parameter is NULL");
+ return_done=1;
+ goto agent_change_config_state_cleanup;
+ }
+
+ // check if agent has permission to see this config parameter
+ if (!agent_must_approve(ptype)) {
+ error_out("Invalid Invocation: Agent is not permitted to change the state of this configuration item",
+ "Invalid Invocation: Agent is not permitted to change the state of this configuration item");
+ return_done=1;
+ goto agent_change_config_state_cleanup;
+ }
+
+ if ((PL_strcmp(choice, "Disable") == 0) || (PL_strcmp(choice, "Reject") == 0)) {
+ PR_snprintf(pstate, 128, "Disabled");
+ } else {
+ PR_snprintf(pstate, 128, "Enabled");
+ }
+
+ set_status = set_config_state_timestamp(ptype, pname, ptimestamp, pstate, "Agent", false, userid);
+
+ if (set_status != 0) {
+ error_out("The data you are viewing has been changed by an administrator and is out of date. Please reload the data and try again.",
+ "Data Out of Date");
+ return_done=1;
+ goto agent_change_config_state_cleanup;
+ }
+
+ char error_msg[512];
+ status = RA::GetConfigStore()->Commit(false, error_msg, 512);
+ if (status != 0) {
+ tokendbDebug(error_msg);
+ }
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var flash = \"Configuration changes have been saved.\";\n",
+ "var agent_target_list = \"",
+ RA::GetConfigStore()->GetConfigAsString("target.agent_approve.list", ""), "\";\n",
+ "var target_list = \"", RA::GetConfigStore()->GetConfigAsString("target.configure.list", ""), "\";\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( indexTemplate, injection );
+ agent_change_config_state_cleanup:
+ do_free(ptype);
+ do_free(pname);
+ do_strfree(ptimestamp);
+ do_strfree(choice);
+
+ if (return_done == 1) {
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ } else if( ( PL_strstr( query, "op=agent_view_config" ) ) ) {
+ tokendbDebug( "authorization for op=agent_view_config\n" );
+ if (! is_agent) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "agent_view_config", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "agent_view_config", "Success", "Tokendb user authorization");
+
+ char *ptype = NULL;
+ char *pname = NULL;
+ char *pstate = NULL;
+ char *ptimestamp = NULL;
+ char *disp_conf_type = NULL;
+ int return_done = 0;
+
+ char *key_values = NULL;
+ char *large_injection = NULL;
+ char *escaped = NULL;
+ ConfigStore *store = NULL;
+
+ ptype = get_post_field(post, "ptype", SHORT_LEN);
+ pname = get_post_field(post, "pname", SHORT_LEN);
+
+ if ((ptype == NULL) || (pname == NULL)) {
+ error_out("Invalid Invocation: Parameter type or name is NULL", "Invalid Invocation: Parameter type or name is NULL");
+ return_done =1;
+ goto agent_view_config_cleanup;
+ }
+
+ // check if agent has permission to see this config parameter
+ if (! agent_must_approve(ptype)) {
+ error_out("Invalid Invocation: Agent is not permitted to view this configuration item",
+ "Invalid Invocation: Agent is not permitted to view this configuration item");
+ return_done =1;
+ goto agent_view_config_cleanup;
+ }
+
+ get_config_state_timestamp(ptype, pname, &pstate, &ptimestamp);
+
+ store = get_pattern_substore(ptype, pname);
+
+ if (store == NULL) {
+ error_out("Setup Error: Pattern Substore is NULL", "Pattern Substore is NULL");
+ return_done =1;
+ goto agent_view_config_cleanup;
+ }
+
+ key_values = (char *) store->GetOrderedList();
+ escaped = escapeSpecialChars(key_values);
+ tokendbDebug( "got ordered list");
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", ptype );
+ disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+ large_injection = (char *) PR_Malloc(PL_strlen(key_values) + MAX_INJECTION_SIZE);
+ PR_snprintf( large_injection, PL_strlen(key_values) + MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var conf_type = \"", ptype, "\";\n",
+ "var disp_conf_type = \"", disp_conf_type, "\";\n",
+ "var conf_name = \"", pname, "\";\n",
+ "var conf_state = \"", pstate, "\";\n",
+ "var conf_tstamp = \"", ptimestamp, "\";\n",
+ "var conf_values= \"", escaped, "\";\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, large_injection); //needed?
+ PL_strcat(large_injection, JS_STOP);
+
+ buf = getData( agentViewConfigTemplate, large_injection );
+ agent_view_config_cleanup:
+ do_free(ptype);
+ do_free(pname);
+ do_free(pstate);
+ do_free(ptimestamp);
+ do_free(key_values);
+ do_free(large_injection);
+ do_strfree(escaped);
+
+ if (store != NULL) {
+ delete store;
+ store = NULL;
+ }
+
+ if (return_done != 0 ) {
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ } else if( ( PL_strstr( query, "op=edit_config_parameter" ) ) ) {
+ tokendbDebug( "authorization for op=edit_config_parameter\n" );
+ if (! is_admin) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "edit_config_parameter", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "edit_config_parameter", "Success", "Tokendb user authorization");
+
+ char *ptype = NULL;
+ char *pname = NULL;
+
+ char *pstate = NULL;
+ char *ptimestamp = NULL;
+ char *key_values = NULL;
+ char *escaped = NULL;
+ ConfigStore *store = NULL;
+ char *large_injection = NULL;
+ char *pattern = NULL;
+ char *disp_conf_type = NULL;
+ int return_done = 0;
+
+ ptype = get_post_field(post, "ptype", SHORT_LEN);
+ pname = get_post_field(post, "pname", SHORT_LEN);
+
+ if ((ptype == NULL) || (pname == NULL)) {
+ error_out("Invalid Invocation: Parameter type or name is NULL", "Invalid Invocation: Parameter type or name is NULL");
+ return_done =1;
+ goto edit_config_parameter_cleanup;
+ }
+
+ get_config_state_timestamp(ptype, pname, &pstate, &ptimestamp);
+ tokendbDebug(pstate);
+ tokendbDebug(ptimestamp);
+
+ store = get_pattern_substore(ptype, pname);
+
+ if (store == NULL) {
+ error_out("Setup Error", "Pattern Substore is NULL");
+ return_done =1;
+ goto edit_config_parameter_cleanup;
+ }
+
+ key_values = (char *) store->GetOrderedList();
+ //escaped = escapeSpecialChars(key_values);
+ escaped = escapeString(key_values);
+ tokendbDebug( "got ordered list");
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.pattern", ptype );
+ pattern = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", ptype );
+ disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+ large_injection = (char *) PR_Malloc(PL_strlen(key_values) + MAX_INJECTION_SIZE);
+ PR_snprintf( large_injection, PL_strlen(key_values) + MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var conf_type = \"", ptype, "\";\n",
+ "var disp_conf_type = \"", disp_conf_type, "\";\n",
+ "var conf_name = \"", pname, "\";\n",
+ "var conf_state = \"", pstate, "\";\n",
+ "var conf_tstamp = \"", ptimestamp, "\";\n",
+ "var agent_must_approve = \"", agent_must_approve(ptype)? "true": "false", "\";\n",
+ "var conf_pattern = \"", pattern, "\";\n",
+ "var conf_values= \"", escaped, "\";\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, large_injection); //needed?
+ PL_strcat(large_injection, JS_STOP);
+
+ buf = getData( editConfigTemplate, large_injection );
+ edit_config_parameter_cleanup:
+ do_free(ptype);
+ do_free(pname);
+ do_strfree(ptimestamp);
+ do_strfree(pstate);
+ do_free(large_injection);
+ do_free(key_values);
+ do_strfree(escaped);
+
+ if (store != NULL) {
+ delete store;
+ store = NULL;
+ }
+ if (return_done == 1) {
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ } else if( ( PL_strstr( query, "op=return_to_edit_config_parameter" ) ) ) {
+ tokendbDebug( "authorization for op=return_to_edit_config_parameter\n" );
+ if (! is_admin) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "return_to_edit_config_parameter", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "return_to_edit_config_parameter", "Success", "Tokendb user authorization");
+
+ char *ptype = NULL;
+ char *pname = NULL;
+ char *pstate = NULL;
+ char *ptimestamp = NULL;
+ char *pvalues = NULL;
+
+ char *large_injection = NULL;
+ char *pattern = NULL;
+ char *disp_conf_type = NULL;
+ int return_done = 0;
+
+ ptype = get_post_field(post, "ptype", SHORT_LEN);
+ pname = get_post_field(post, "pname", SHORT_LEN);
+ pstate = get_post_field(post, "pstate", SHORT_LEN);
+ ptimestamp = get_post_field(post, "ptimestamp", SHORT_LEN);
+ pvalues = get_post_field_s(post, "pvalues");
+
+ if ((ptype == NULL) || (pname == NULL) || (pstate == NULL) || (ptimestamp == NULL) || (pvalues == NULL)) {
+ error_out("Invalid Invocation: A required parameter is missing", "Invalid Invocation: A required parameter is missing");
+ return_done =1;
+ goto return_to_edit_config_parameter_cleanup;
+ }
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.pattern", ptype );
+ pattern = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", ptype );
+ disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+
+ large_injection = (char *) PR_Malloc(PL_strlen(pvalues) + MAX_INJECTION_SIZE);
+ PR_snprintf( large_injection, PL_strlen(pvalues) + MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var conf_type = \"", ptype, "\";\n",
+ "var disp_conf_type = \"", disp_conf_type, "\";\n",
+ "var conf_name = \"", pname, "\";\n",
+ "var conf_state = \"", pstate, "\";\n",
+ "var conf_tstamp = \"", ptimestamp, "\";\n",
+ "var agent_must_approve = \"", agent_must_approve(ptype)? "true": "false", "\";\n",
+ "var conf_pattern = \"", pattern, "\";\n",
+ "var conf_values= \"", pvalues, "\";\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, large_injection); //needed?
+ PL_strcat(large_injection, JS_STOP);
+
+ buf = getData( editConfigTemplate, large_injection );
+ return_to_edit_config_parameter_cleanup:
+ do_free(ptype);
+ do_free(pname);
+ do_free(ptimestamp);
+ do_free(pstate);
+ do_free(pvalues);
+ do_free(large_injection);
+
+ if (return_done == 1) {
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ } else if( ( PL_strstr( query, "op=confirm_config_changes" ) ) ) {
+ tokendbDebug( "authorization for op=confirm_config_changes\n" );
+ if (! is_admin) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "confirm_config_changes", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "confirm_config_changes", "Success", "Tokendb user authorization");
+
+ char *ptype = NULL;
+ char *pname = NULL;
+ char *pvalues = NULL;
+ char *ptimestamp = NULL;
+ char *choice = NULL;
+
+ char *cur_ts = NULL;
+ char *cur_state = NULL;
+ char *changed_str = NULL;
+ char *added_str = NULL;
+ char *deleted_str = NULL;
+ char *escaped_deleted_str = NULL;
+ char *escaped_added_str = NULL;
+ char *escaped_changed_str = NULL;
+ char *escaped_pvalues = NULL;
+ char *disp_conf_type = NULL;
+ int return_done=0;
+ char flash[512]="";
+
+ char *pair = NULL;
+ char *line = NULL;
+ int i;
+ int len;
+ char *lasts = NULL;
+ char *value = NULL;
+ ConfigStore *store = NULL;
+
+ ptype = get_post_field(post, "ptype", SHORT_LEN);
+ pname = get_post_field(post, "pname", SHORT_LEN);
+ ptimestamp = get_post_field(post, "ptimestamp", SHORT_LEN);
+ escaped_pvalues = get_post_field_s(post, "pvalues");
+ choice = get_post_field(post, "choice", SHORT_LEN);
+
+ if ((ptype == NULL) || (pname == NULL) || (escaped_pvalues == NULL) || (ptimestamp == NULL)) {
+ error_out("Invalid Invocation: A required parameter is NULL", "A required parameter is NULL");
+ return_done=1;
+ goto confirm_config_changes_cleanup;
+ }
+
+ tokendbDebug(ptype);
+ tokendbDebug(pname);
+
+ if (PL_strlen(escaped_pvalues) == 0) {
+ error_out("Empty Data not allowed. Use Delete Parameter instead", "Empty Data");
+ return_done=1;
+ goto confirm_config_changes_cleanup;
+ }
+
+ get_config_state_timestamp(ptype, pname, &cur_state, &cur_ts);
+ if (PL_strcmp(cur_ts, ptimestamp) != 0) {
+ error_out("The data you are viewing has changed. Please reload the data and try your edits again.", "Data Out of Date");
+ return_done=1;
+ goto confirm_config_changes_cleanup;
+ }
+
+
+ store = get_pattern_substore(ptype, pname);
+ if (store == NULL) {
+ error_out("Setup Error", "Pattern Substore is NULL");
+ return_done=1;
+ goto confirm_config_changes_cleanup;
+ }
+
+ // parse the pvalues string of form foo=bar&&foo2=baz&& ...
+ pvalues = unescapeString(escaped_pvalues);
+ changed_str = (char*) PR_Malloc(PL_strlen(pvalues));
+ added_str = (char*) PR_Malloc(PL_strlen(pvalues));
+
+ PR_snprintf(changed_str, PL_strlen(pvalues),"");
+ PR_snprintf(added_str, PL_strlen(pvalues), "");
+
+ line = PL_strdup(pvalues);
+ pair = PL_strtok_r(line, "&&", &lasts);
+ while (pair != NULL) {
+ len = strlen(pair);
+ i = 0;
+ while (1) {
+ if (i >= len) {
+ goto skip;
+ }
+ if (pair[i] == '\0') {
+ goto skip;
+ }
+ if (pair[i] == '=') {
+ pair[i] = '\0';
+ break;
+ }
+ i++;
+ }
+ if ((value= (char *) store->GetConfigAsString(&pair[0]))) { // key exists
+ if (PL_strcmp(value, &pair[i+1]) != 0) {
+ // value has changed
+ PR_snprintf(changed_str, PL_strlen(pvalues), "%s%s%s=%s", changed_str,
+ (PL_strlen(changed_str) != 0) ? "&&" : "",
+ &pair[0], &pair[i+1]);
+ }
+ store->Remove(&pair[0]);
+ } else { // new key
+ PR_snprintf(added_str, PL_strlen(pvalues), "%s%s%s=%s", added_str,
+ (PL_strlen(added_str) != 0) ? "&&" : "",
+ &pair[0], &pair[i+1]);
+ }
+ skip:
+ pair = PL_strtok_r(NULL, "&&", &lasts);
+ }
+
+ // remaining entries have been deleted
+ deleted_str = (char *) store->GetOrderedList();
+
+ //escape special characters
+ escaped_deleted_str = escapeString(deleted_str);
+ escaped_added_str = escapeString(added_str);
+ escaped_changed_str = escapeString(changed_str);
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", ptype );
+ disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+ if ((PL_strlen(escaped_added_str) + PL_strlen(escaped_changed_str) + PL_strlen(escaped_deleted_str))!=0) {
+ int injection_size = PL_strlen(escaped_deleted_str) + PL_strlen(escaped_pvalues) + PL_strlen(escaped_added_str) +
+ PL_strlen(escaped_changed_str) + MAX_INJECTION_SIZE;
+ char * large_injection = (char *) PR_Malloc(injection_size);
+
+ PR_snprintf( large_injection, injection_size,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var conf_type = \"", ptype, "\";\n",
+ "var disp_conf_type = \"", disp_conf_type, "\";\n",
+ "var conf_name = \"", pname, "\";\n",
+ "var conf_tstamp = \"", ptimestamp, "\";\n",
+ "var conf_state = \"", cur_state, "\";\n",
+ "var conf_values = \"", escaped_pvalues, "\";\n",
+ "var added_str= \"", escaped_added_str, "\";\n",
+ "var changed_str= \"", escaped_changed_str, "\";\n",
+ "var conf_approval_requested = \"", (PL_strcmp(choice, "Save") == 0) ? "FALSE" : "TRUE", "\";\n",
+ "var deleted_str= \"", escaped_deleted_str, "\";\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, large_injection); //needed?
+ PL_strcat(large_injection, JS_STOP);
+
+ buf = getData( confirmConfigChangesTemplate, large_injection );
+
+ do_free(large_injection);
+
+ } else {
+ // no changes need to be saved
+
+ if (PL_strcmp(choice, "Save") != 0) {
+ int status = set_config_state_timestamp(ptype, pname, ptimestamp, "Pending_Approval", "Admin", false, userid);
+ if (status != 0) {
+ error_out("The data you are viewing has changed. Please reload the data and try your edits again.", "Data Out of Date");
+ return_done=1;
+ goto confirm_config_changes_cleanup;
+ }
+ char error_msg[512];
+ status = RA::GetConfigStore()->Commit(false, error_msg, 512);
+ if (status != 0) {
+ tokendbDebug(error_msg);
+ }
+
+ PR_snprintf(flash, 512, "Configuration Parameters have been submitted for Agent Approval");
+ } else {
+ PR_snprintf(flash, 512, "The data displayed is up-to-date. No changes need to be saved.");
+ }
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var flash = \"", flash , "\";\n",
+ "var agent_target_list = \"",
+ RA::GetConfigStore()->GetConfigAsString("target.agent_approve.list", ""), "\";\n",
+ "var target_list = \"", RA::GetConfigStore()->GetConfigAsString("target.configure.list", ""), "\";\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+ buf = getData( indexTemplate, injection );
+ }
+
+ confirm_config_changes_cleanup:
+ do_strfree(cur_state);
+ do_strfree(cur_ts);
+ do_free(changed_str);
+ do_free(added_str);
+ do_free(deleted_str);
+ do_strfree(escaped_deleted_str);
+ do_strfree(escaped_added_str);
+ do_strfree(escaped_changed_str);
+ do_strfree(escaped_pvalues);
+ do_free(ptype);
+ do_free(pname);
+ do_free(pvalues);
+ do_free(ptimestamp);
+ do_free(choice);
+ do_strfree(line);
+
+ if (store != NULL) {
+ delete store;
+ store = NULL;
+ }
+ if (return_done != 0) {
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ } else if( ( PL_strstr( query, "op=save_config_changes" ) ) ) {
+ tokendbDebug( "authorization for op=save_config_changes\n" );
+ if (! is_admin) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "save_config_changes", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "save_config_parameter", "Success", "Tokendb user authorization");
+
+ char *ptype = NULL;
+ char *pname = NULL;
+ char *ptimestamp = NULL;
+ char *escaped_added_str = NULL;
+ char *escaped_deleted_str = NULL;
+ char *escaped_changed_str = NULL;
+ char *new_config = NULL;
+ char *approval_requested = NULL;
+ char *pstate = NULL;
+ char flash[256] = "";
+ int return_done = 0;
+ bool new_config_bool = false;
+
+ ptype = get_post_field(post, "ptype", SHORT_LEN);
+ pname = get_post_field(post, "pname", SHORT_LEN);
+ ptimestamp = get_post_field(post, "ptimestamp", SHORT_LEN);
+ escaped_added_str = get_post_field_s(post, "added_params");
+ escaped_deleted_str = get_post_field_s(post, "deleted_params");
+ escaped_changed_str = get_post_field_s(post, "changed_params");
+ new_config = get_post_field(post, "new_config", SHORT_LEN);
+ approval_requested = get_post_field(post, "approval_requested", SHORT_LEN);
+ new_config_bool = (PL_strcmp(new_config, "true") == 0) ? true : false;
+
+ tokendbDebug(ptype);
+ tokendbDebug(pname);
+ tokendbDebug(new_config);
+ tokendbDebug(ptimestamp);
+ tokendbDebug(approval_requested);
+
+ char *added_str = unescapeString(escaped_added_str);
+ char *deleted_str = unescapeString(escaped_deleted_str);
+ char *changed_str = unescapeString(escaped_changed_str);
+
+ tokendbDebug(added_str);
+ tokendbDebug(deleted_str);
+ tokendbDebug(changed_str);
+
+ if ((ptype == NULL) || (pname == NULL)) {
+ error_out("Invalid Invocation: Parameter type, name or values is NULL", "Parameter type, name or values is NULL");
+ return_done = 1;
+ goto save_config_changes_cleanup;
+ }
+
+ if (set_config_state_timestamp(ptype, pname, ptimestamp, "Writing", "Admin", new_config_bool, userid) != 0) {
+ error_out("The data you are viewing has changed. Please reload the data and try your edits again.", "Data Out of Date");
+ return_done=1;
+ goto save_config_changes_cleanup;
+ }
+
+ if (new_config) {
+ do_free(ptimestamp);
+ get_config_state_timestamp(ptype, pname, &pstate, &ptimestamp);
+ }
+
+ if (PL_strlen(added_str) != 0) parse_and_apply_changes(userid, ptype, pname, "ADD", added_str);
+ if (PL_strlen(deleted_str) != 0) parse_and_apply_changes(userid, ptype, pname, "DELETE", deleted_str);
+ if (PL_strlen(changed_str) != 0) parse_and_apply_changes(userid, ptype, pname, "MODIFY", changed_str);
+
+ if (PL_strcmp(new_config, "true") ==0) {
+ // add to the list for that config type
+ PR_snprintf( ( char * ) configname, 256, "target.%s.list", ptype );
+ const char *conf_list = RA::GetConfigStore()->GetConfigAsString( configname );
+ char value[4096] = "";
+ PR_snprintf(value, 4096, "%s%s%s", conf_list, (PL_strlen(conf_list) > 0) ? "," : "", pname);
+ RA::GetConfigStore()->Add(configname, value);
+
+ PR_snprintf(oString, 512, "%s", pname);
+ PR_snprintf(pLongString, 4096, "%s;;%s", configname, value);
+ RA::Audit(EV_CONFIG, AUDIT_MSG_CONFIG, userid, "Admin", "Success", oString, pLongString, "config item added");
+ }
+
+ if (PL_strcmp(approval_requested, "TRUE") == 0) {
+ int status = set_config_state_timestamp(ptype, pname, ptimestamp, "Pending_Approval", "Admin", false, userid);
+ if (status != 0) {
+ error_out("The data you are viewing has changed. Please reload the data and try your edits again.", "Data Out of Date");
+ return_done=1;
+ goto save_config_changes_cleanup;
+ }
+ PR_snprintf(flash, 256, "Configuration Parameters have been saved and submitted for approval");
+ } else {
+ int status = set_config_state_timestamp(ptype, pname, ptimestamp, "Disabled", "Admin", false, userid);
+ if (status != 0) {
+ error_out("The data you are viewing has changed. Please reload the data and try your edits again.", "Data Out of Date");
+ return_done=1;
+ goto save_config_changes_cleanup;
+ }
+ PR_snprintf(flash, 256, "Configuration Parameters have been saved");
+ }
+
+ if ((PL_strlen(added_str) != 0) || (PL_strlen(deleted_str) != 0) || (PL_strlen(changed_str) != 0)) {
+ char error_msg[512];
+ status = RA::GetConfigStore()->Commit(true, error_msg, 512);
+ if (status != 0) {
+ tokendbDebug(error_msg);
+ }
+
+ RA::Audit(EV_CONFIG, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", "", "config changes committed to filesystem");
+ } else {
+ // commit state changes
+ char error_msg[512];
+ status = RA::GetConfigStore()->Commit(false, error_msg, 512);
+ if (status != 0) {
+ tokendbDebug(error_msg);
+ }
+ }
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var flash = \"" , flash, "\";\n",
+ "var agent_target_list = \"",
+ RA::GetConfigStore()->GetConfigAsString("target.agent_approve.list", ""), "\";\n",
+ "var target_list = \"", RA::GetConfigStore()->GetConfigAsString("target.configure.list", ""), "\";\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( indexTemplate, injection );
+ save_config_changes_cleanup:
+ do_free(ptype);
+ do_free(pname);
+ do_free(added_str);
+ do_free(deleted_str);
+ do_free(changed_str);
+ do_free(escaped_added_str);
+ do_free(escaped_deleted_str);
+ do_free(escaped_changed_str);
+ do_free(new_config);
+ do_free(ptimestamp);
+ do_free(pstate);
+ do_free(approval_requested);
+ if (return_done == 1) {
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ } else if( ( PL_strstr( query, "op=view_admin" ) ) ||
+ ( PL_strstr( query, "op=view_certificate" ) ) ||
+ ( PL_strstr( query, "op=view_activity_admin" ) ) ||
+ ( PL_strstr( query, "op=view_activity" ) ) ||
+ ( PL_strstr( query, "op=view_users" ) ) ||
+ ( PL_strstr( query, "op=view" ) ) ||
+ ( PL_strstr( query, "op=edit_user" ) ) ||
+ ( PL_strstr( query, "op=edit" ) ) ||
+ ( PL_strstr( query, "op=show_certificate" ) ) ||
+ ( PL_strstr( query, "op=show" ) ) ||
+ ( PL_strstr( query, "op=do_confirm_token" ) ) ||
+ ( PL_strstr( query, "op=user_delete_confirm"))||
+ ( PL_strstr( query, "op=confirm" ) ) ) {
+
+ op = get_field(query, "op=", SHORT_LEN);
+
+ if( ( PL_strstr( query, "op=confirm" ) ) ||
+ ( PL_strstr( query, "op=view_admin" ) ) ||
+ ( PL_strstr( query, "op=view_activity_admin" ) ) ||
+ ( PL_strstr( query, "op=show_admin" ) ) ||
+ ( PL_strstr( query, "op=view_users") ) ||
+ ( PL_strstr( query, "op=edit_user") ) ||
+ ( PL_strstr( query, "op=user_delete_confirm") ) ) {
+ tokendbDebug( "authorization for admin ops\n" );
+
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, op, "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, op, "Success", "Tokendb user authorization");
+ } else if ((PL_strstr(query, "op=edit")) ||
+ (PL_strstr(query, "do_confirm_token"))) {
+ tokendbDebug( "authorization for op=edit and op=do_confirm_token\n" );
+
+ if (! is_agent ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, op, "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, op, "Success", "Tokendb user authorization");
+ } else if (PL_strstr(query, "op=view_activity")) {
+ tokendbDebug( "authorization for view_activity\n" );
+
+ /* check removed -- all roles permitted
+ if ( (! is_agent) && (! is_operator) && (! is_admin)) {
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DECLINED;
+ } */
+ } else {
+ tokendbDebug( "authorization\n" );
+
+ if ((! is_agent) && (!is_operator)) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, op, "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, op, "Success", "Tokendb user authorization");
+ }
+
+ do_free(op);
+
+ if ((PL_strstr( query, "op=view_activity_admin")) ||
+ (PL_strstr( query, "op=view_activity" ) )) {
+ getActivityFilter( filter, query );
+ } else if( PL_strstr( query, "op=view_certificate" ) ) {
+ getCertificateFilter( filter, query );
+ } else if( PL_strstr( query, "op=show_certificate" ) ) {
+ getCertificateFilter( filter, query );
+ } else if ((PL_strstr( query, "op=view_users" ) ) ||
+ (PL_strstr( query, "op=user_delete_confirm")) ||
+ (PL_strstr( query, "op=edit_user" ) )) {
+ getUserFilter( filter, query );
+ } else {
+ getFilter( filter, query );
+ }
+
+ auth_filter = get_authorized_profiles(userid, is_admin);
+
+ tokendbDebug("auth_filter");
+ tokendbDebug(auth_filter);
+
+ char *complete_filter = add_profile_filter(filter, auth_filter);
+ do_free(auth_filter);
+
+ int time_limit = get_time_limit(query);
+ int size_limit = get_size_limit(query);
+
+ tokendbDebug( "looking for filter:" );
+ tokendbDebug( complete_filter );
+ tokendbDebug( filter );
+ tokendbDebug( "\n" );
+
+ /* retrieve maxCount */
+ s1 = PL_strstr( query, "maxCount=" );
+ if( s1 == NULL ) {
+ maxReturns = 100;
+ } else {
+ s2 = PL_strchr( ( const char * ) s1, '&' );
+ if( s2 == NULL ) {
+ maxReturns = atoi( s1+9 );
+ } else {
+ *s2 = '\0';
+ maxReturns = atoi( s1+9 );
+ *s2 = '&';
+ }
+ }
+
+ if (( PL_strstr( query, "op=view_activity_admin_all" )) ||
+ ( PL_strstr( query, "op=view_activity_all") )) {
+ // TODO: error check to confirm that search filter is non-empty
+ status = find_tus_activity_entries_no_vlv( complete_filter, &result, 1 );
+ } else if (( PL_strstr( query, "op=view_activity_admin" )) ||
+ ( PL_strstr( query, "op=view_activity" ) )) {
+ if (PL_strcmp(complete_filter, "(&(tokenID=*)(tokenUserID=*))") == 0) {
+ tokendbDebug("activity vlv search");
+ status = find_tus_activity_entries(complete_filter, maxReturns, &result);
+ } else {
+ status = find_tus_activity_entries_pcontrol_1( complete_filter, maxReturns, time_limit, size_limit, &result);
+ }
+ } else if(( PL_strstr( query, "op=view_certificate_all" ) ) ||
+ ( PL_strstr( query, "op=show_certificate") )) {
+
+ // TODO: error check to confirm that search filter is non-empty
+ ap_log_error( ( const char * ) "tus", __LINE__,
+ APLOG_ERR, 0, rq->server,
+ ( const char * ) "LDAP filter: %s", complete_filter);
+
+ status = find_tus_certificate_entries_by_order_no_vlv( complete_filter,
+ &result,
+ 0 );
+ } else if( PL_strstr( query, "op=view_certificate" )) {
+ ap_log_error( ( const char * ) "tus", __LINE__,
+ APLOG_ERR, 0, rq->server,
+ ( const char * ) "LDAP filter: %s", complete_filter);
+
+ status = find_tus_certificate_entries_by_order( complete_filter,
+ maxReturns,
+ &result,
+ 0 );
+ } else if( PL_strstr( query, "op=show_admin" ) ||
+ PL_strstr( query, "op=show" ) ||
+ PL_strstr( query, "op=confirm" ) ||
+ PL_strstr( query, "op=do_confirm_token" ) ) {
+ status = find_tus_token_entries_no_vlv( complete_filter, &result, 0 );
+ } else if ((PL_strstr (query, "op=view_users" )) ||
+ (PL_strstr (query, "op=user_delete_confirm")) ||
+ (PL_strstr (query, "op=edit_user" ))) {
+ status = find_tus_user_entries_no_vlv( filter, &result, 0);
+ } else {
+ if (PL_strcmp(complete_filter, "(&(cn=*)(tokenUserID=*))") == 0) {
+ tokendbDebug("token vlv search");
+ status = find_tus_db_entries(complete_filter, maxReturns, &result);
+ } else {
+ status = find_tus_db_entries_pcontrol_1( complete_filter, maxReturns, time_limit, size_limit, &result );
+ }
+ }
+
+ if( status != LDAP_SUCCESS ) {
+ ldap_error_out("LDAP search error: ", "LDAP search error: %s");
+ do_free(complete_filter);
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+
+ do_free(complete_filter);
+ nEntries = get_number_of_entries( result );
+ entryNum = 0;
+ size = 0;
+
+ PL_strcpy( injection, JS_START );
+ PL_strcat( injection, "var userid = \"" );
+ PL_strcat( injection, userid );
+ PL_strcat( injection, "\";\n" );
+ PL_strcat( injection, "var uriBase = \"" );
+ PL_strcat( injection, uri );
+ PL_strcat( injection, "\";\n" );
+
+ if( nEntries > 1 ) {
+ if( sendInPieces && PL_strstr( query, "op=view_activity_admin" ) ) {
+ buf = getTemplateFile( searchActivityAdminResultTemplate,
+ &tagOffset );
+ if( buf != NULL && tagOffset >= 0 ) {
+ ( void ) ap_rwrite( ( const void * ) buf, tagOffset, rq );
+ sendPieces = 1;
+ }
+ } else if( sendInPieces && PL_strstr( query, "op=view_activity" ) ) {
+ buf = getTemplateFile( searchActivityResultTemplate,
+ &tagOffset );
+ if( buf != NULL && tagOffset >= 0 ) {
+ ( void ) ap_rwrite( ( const void * ) buf, tagOffset, rq );
+ sendPieces = 1;
+ }
+ } else if( sendInPieces &&
+ PL_strstr( query, "op=view_certificate" ) ) {
+ buf = getTemplateFile( searchCertificateResultTemplate,
+ &tagOffset );
+ if( buf != NULL && tagOffset >= 0 ) {
+ ( void ) ap_rwrite( ( const void * ) buf, tagOffset, rq );
+ sendPieces = 1;
+ }
+ } else if (sendInPieces && PL_strstr( query, "op=view_users" )) {
+ buf = getTemplateFile( searchUserResultTemplate, &tagOffset );
+ if( buf != NULL && tagOffset >= 0 ) {
+ ( void ) ap_rwrite( ( const void * ) buf, tagOffset, rq );
+ sendPieces = 1;
+ }
+ } else if( sendInPieces && PL_strstr( query, "op=view" ) ) {
+ buf = getTemplateFile( searchResultTemplate, &tagOffset );
+ if( buf != NULL && tagOffset >= 0 ) {
+ ( void ) ap_rwrite( ( const void * ) buf, tagOffset, rq );
+ sendPieces = 1;
+ }
+ }
+
+ PL_strcat( injection, "var total = \"" );
+
+ len = PL_strlen( injection );
+
+ PR_snprintf( &injection[len], ( MAX_INJECTION_SIZE-len ),
+ "%d", nEntries );
+
+ PL_strcat( injection, "\";\n" );
+ } else {
+ if( ( vals = get_token_states() ) != NULL ) {
+ PL_strcat( injection, "var tokenStates = \"" );
+ for( i = 0; vals[i] != NULL; i++ ) {
+ if( i > 0 ) {
+ PL_strcat( injection, "," );
+ }
+
+ PL_strcat( injection, vals[i] );
+ }
+
+ if( i > 0 ) {
+ PL_strcat( injection, "\";\n" );
+ } else {
+ PL_strcat( injection, "null;\n" );
+ }
+ }
+ }
+
+ PL_strcat( injection, "var results = new Array();\n" );
+ PL_strcat( injection, "var item = 0;\n" );
+
+ if( PL_strstr( query, "op=do_confirm_token" ) ) {
+ question = PL_strstr( query, "question=" );
+
+ q = question[9] - '0';
+
+ PR_snprintf( question_no, 256, "%d", q );
+
+ PL_strcat( injection, "var question = \"" );
+ PL_strcat( injection, question_no );
+ PL_strcat( injection, "\";\n" );
+ }
+
+ if (PL_strstr( query, "op=do_confirm_token" ) ||
+ PL_strstr( query, "op=show" )) {
+ show_token_ui_state = true;
+ }
+
+ /* get attributes to be displayed to the user */
+ if (( PL_strstr( query, "op=view_activity_admin" ) ) ||
+ ( PL_strstr( query, "op=view_activity" ) )) {
+ attrs = get_activity_attributes();
+ } else if( PL_strstr( query, "op=view_certificate" ) ) {
+ attrs = get_certificate_attributes();
+ } else if( PL_strstr( query, "op=show_certificate" ) ) {
+ attrs = get_certificate_attributes();
+ } else if ((PL_strstr( query, "op=user_delete_confirm")) ||
+ (PL_strstr( query, "op=edit_user") ) ) {
+ attrs = get_user_attributes();
+ } else if (PL_strstr( query, "op=view_users") ) {
+ attrs = get_view_user_attributes();
+ } else {
+ attrs = get_token_attributes();
+ }
+
+ /* start_val used in paging of profiles on the edit_user page */
+ if (PL_strstr( query, "op=edit_user") ) {
+ char *start_val_str = get_field(query, "start_val=", SHORT_LEN);
+ if (start_val_str != NULL) {
+ start_val = atoi(start_val_str);
+ do_free(start_val_str);
+ } else {
+ start_val = 0;
+ }
+ end_val = start_val + NUM_PROFILES_TO_DISPLAY;
+ }
+
+ /* flash used to display edit result upon redirection back to the edit_user page */
+ if (PL_strstr(query, "op=edit_user") ) {
+ char *flash = get_field(query, "flash=", SHORT_LEN);
+ if (flash != NULL) {
+ PL_strcat(injection, "var flash = \"");
+ PL_strcat(injection, flash);
+ PL_strcat(injection, "\";\n");
+ do_free(flash);
+ }
+ PR_snprintf(msg, 256, "var num_profiles_to_display = %d ;\n", NUM_PROFILES_TO_DISPLAY);
+ PL_strcat(injection, msg);
+ }
+
+ int injection_size = MAX_INJECTION_SIZE;
+ /* start_entry_val is used for pagination of entries on all other pages */
+ int start_entry_val;
+ int end_entry_val;
+ int first_pass = 1;
+ int one_time = 1;
+ char *start_entry_val_str = get_field(query, "start_entry_val=", SHORT_LEN);
+ if (start_entry_val_str != NULL) {
+ start_entry_val = atoi(start_entry_val_str);
+ do_free(start_entry_val_str);
+ } else {
+ start_entry_val = 1;
+ }
+ end_entry_val = start_entry_val + NUM_ENTRIES_PER_PAGE;
+
+ if( (maxReturns > 0) && (maxReturns < nEntries)) {
+ PR_snprintf(msg, 256, "var limited = %d ;\n", maxReturns);
+ PL_strcat( injection, msg);
+ }
+
+ for( e = get_first_entry( result );
+ ( maxReturns > 0 ) && ( e != NULL );
+ e = get_next_entry( e ) ) {
+ maxReturns--;
+ entryNum++;
+
+ if ((entryNum < start_entry_val) || (entryNum >= end_entry_val)) {
+ if (one_time == 1) {
+ PL_strcat(injection, "var my_query = \"");
+ PL_strcat(injection, query);
+ PL_strcat(injection, "\";\n");
+ one_time =0;
+ }
+ // skip values not within the page range
+ if (entryNum == end_entry_val) {
+ PL_strcat( injection, "var has_more_entries = 1;\n");
+ break;
+ }
+ continue;
+ }
+
+ PL_strcat( injection, "var o = new Object();\n" );
+
+ for( n = 0; attrs[n] != NULL; n++ ) {
+ /* Get the values of the attribute. */
+ if( ( bvals = get_attribute_values( e, attrs[n] ) ) != NULL ) {
+ int v_start =0;
+ int v_end = MAX_INJECTION_SIZE;
+ PL_strcat( injection, "o." );
+ PL_strcat( injection, attrs[n] );
+ PL_strcat( injection, " = " );
+
+ if (PL_strstr(attrs[n], PROFILE_ID)) {
+ v_start = start_val;
+ v_end = end_val;
+ }
+
+ for( i = v_start; (bvals[i] != NULL) && (i < v_end); i++ ) {
+ if( i > start_val ) {
+ PL_strcat( injection, "#" );
+ } else {
+ PL_strcat( injection, "\"" );
+ }
+
+ // make sure to escape any special characters
+ if (bvals[i]->bv_val != NULL) {
+ char *escaped = escapeSpecialChars(bvals[i]->bv_val);
+ PL_strcat( injection, escaped );
+ if (escaped != NULL) {
+ PL_strfree(escaped);
+ }
+ }
+ }
+
+ if( i > v_start ) {
+ PL_strcat( injection, "\";\n" );
+ } else {
+ PL_strcat( injection, "null;\n" );
+ }
+
+ if ((PL_strcmp(attrs[n], TOKEN_STATUS)==0) && show_token_ui_state && valid_berval(bvals)) {
+ PL_strncpy( tokenStatus, bvals[0]->bv_val, 100 );
+ }
+
+ if ((PL_strcmp(attrs[n], TOKEN_REASON)==0) && show_token_ui_state && valid_berval(bvals)) {
+ PL_strncpy( tokenReason, bvals[0]->bv_val, 100 );
+ }
+
+ if (PL_strstr(attrs[n], PROFILE_ID)) {
+ if (bvals[i] != NULL) {
+ PL_strcat( injection, "var has_more_profile_vals = \"true\";\n");
+ } else {
+ PL_strcat( injection, "var has_more_profile_vals = \"false\";\n");
+ }
+ PR_snprintf(msg, 256, "var start_val = %d ;\n var end_val = %d ;\n",
+ start_val, i);
+ PL_strcat( injection, msg);
+ }
+
+ /* Free the attribute values from memory when done. */
+ if( bvals != NULL ) {
+ free_values( bvals, 1 );
+ bvals = NULL;
+ }
+ }
+ }
+
+ PL_strcat( injection, "results[item++] = o;\n" );
+
+ if (check_injection_size(&injection, &injection_size, fixed_injection) != 0) {
+ // failed to allocate more space to injection, truncating output
+ break;
+ }
+
+ if( first_pass == 1 && nEntries > 1 && sendPieces == 0 ) {
+ first_pass=0;
+
+ PR_snprintf(msg, 256, "var start_entry_val = %d ; \nvar num_entries_per_page= %d ; \n",
+ start_entry_val, NUM_ENTRIES_PER_PAGE);
+ PL_strcat( injection, msg);
+ }
+
+ if( sendPieces ) {
+ ( void ) ap_rwrite( ( const void * ) injection,
+ PL_strlen( injection ), rq );
+ injection[0] = '\0';
+ }
+
+ }
+
+ if( result != NULL ) {
+ free_results( result );
+ result = NULL;
+ }
+
+ /* populate the user roles */
+ if ((PL_strstr( query, "op=edit_user")) ||
+ (PL_strstr( query, "op=user_delete_confirm"))) {
+
+ uid = get_field(query, "uid=", SHORT_LEN);
+ bool officer = false;
+ bool agent = false;
+ bool admin = false;
+ status = find_tus_user_role_entries( uid, &result );
+ for (e = get_first_entry( result );
+ e != NULL;
+ e = get_next_entry( e ) ) {
+ char *dn = NULL;
+ dn = get_dn(e);
+ if (PL_strstr(dn, "Operators"))
+ officer=true;
+ if (PL_strstr(dn, "Agents"))
+ agent = true;
+ if (PL_strstr(dn, "Administrators"))
+ admin = true;
+ if (dn != NULL) {
+ PL_strfree(dn);
+ dn=NULL;
+ }
+ }
+ if (officer) {
+ PL_strcat( injection, "var operator = \"CHECKED\"\n");
+ } else {
+ PL_strcat( injection, "var operator = \"\"\n");
+ }
+ if (agent) {
+ PL_strcat( injection, "var agent = \"CHECKED\"\n");
+ } else {
+ PL_strcat( injection, "var agent = \"\"\n");
+ }
+ if (admin) {
+ PL_strcat( injection, "var admin = \"CHECKED\"\n");
+ } else {
+ PL_strcat( injection, "var admin = \"\"\n");
+ }
+
+ if( result != NULL ) {
+ free_results( result );
+ result = NULL;
+ }
+ do_free(uid);
+ }
+
+ /* populate the profile checkbox */
+ /* for sanity, we limit the number of entries displayed as well as the max number of characters transferred */
+ if (PL_strstr( query, "op=edit_user")) {
+ if (profileList != NULL) {
+ int n_profiles = 0;
+ int l_profiles = 0;
+ bool more_profiles = false;
+
+ char *pList = PL_strdup(profileList);
+ char *sresult = NULL;
+
+ PL_strcat( injection, "var profile_list = new Array(");
+ sresult = strtok(pList, ",");
+ n_profiles++;
+ while (sresult != NULL) {
+ n_profiles++;
+ l_profiles += PL_strlen(sresult);
+ if ((n_profiles > NUM_PROFILES_TO_DISPLAY) || (l_profiles > MAX_LEN_PROFILES_TO_DISPLAY)) {
+ PL_strcat(injection, "\"Other Profiles\",");
+ more_profiles = true;
+ break;
+ }
+
+ PL_strcat(injection, "\"");
+ PL_strcat(injection, sresult);
+ PL_strcat(injection, "\",");
+ sresult = strtok(NULL, ",");
+ }
+ do_free(pList);
+ PL_strcat(injection, "\"All Profiles\")\n");
+ if (more_profiles) {
+ PL_strcat(injection, "var more_profiles=\"true\";\n");
+ } else {
+ PL_strcat(injection, "var more_profiles=\"false\";\n");
+ }
+ }
+ }
+ topLevel = get_field(query, "top=", SHORT_LEN);
+ if ((topLevel != NULL) && (PL_strstr(topLevel, "operator"))) {
+ PL_strcat(injection, "var topLevel = \"operator\";\n");
+ }
+ do_free(topLevel);
+
+ /* populate the authorized token transitions */
+ if (show_token_ui_state) {
+ token_ui_state = get_token_ui_state(tokenStatus, tokenReason);
+ add_allowed_token_transitions(token_ui_state, injection);
+ }
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat( injection, JS_STOP );
+
+ if( sendPieces ) {
+ ( void ) ap_rwrite( ( const void * ) injection,
+ PL_strlen( injection ), rq );
+
+ mNum = buf + tagOffset + PL_strlen( CMS_TEMPLATE_TAG );
+
+ ( void ) ap_rwrite( ( const void * ) mNum,
+ PL_strlen( mNum ), rq );
+
+ mNum = NULL;
+
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ } else {
+ if( PL_strstr( query, "op=view_activity_admin" ) ) {
+ buf = getData( searchActivityAdminResultTemplate, injection );
+ } else if( PL_strstr( query, "op=view_activity" ) ) {
+ buf = getData( searchActivityResultTemplate, injection );
+ } else if( PL_strstr( query, "op=view_certificate" ) ) {
+ buf = getData( searchCertificateResultTemplate, injection );
+ } else if( PL_strstr( query, "op=show_admin" ) ) {
+ buf = getData( showAdminTemplate, injection );
+ } else if( PL_strstr( query, "op=view_admin" ) ) {
+ buf = getData( searchAdminResultTemplate, injection );
+ } else if (PL_strstr( query, "op=view_users") ) {
+ buf = getData( searchUserResultTemplate, injection);
+ } else if( PL_strstr( query, "op=view" ) ) {
+ buf = getData( searchResultTemplate, injection );
+ } else if (PL_strstr( query, "op=edit_user") ) {
+ buf = getData( editUserTemplate, injection);
+ } else if( PL_strstr( query, "op=edit" ) ) {
+ buf = getData( editTemplate, injection );
+ } else if( PL_strstr( query, "op=show_certificate" ) ) {
+ buf = getData( showCertTemplate, injection );
+ } else if( PL_strstr( query, "op=do_confirm_token" ) ) {
+ buf = getData( doTokenConfirmTemplate, injection );
+ } else if( PL_strstr( query, "op=show" ) ) {
+ buf = getData( showTemplate, injection );
+ } else if( PL_strstr( query, "op=confirm" ) ) {
+ buf = getData( deleteTemplate, injection );
+ } else if ( PL_strstr( query, "op=user_delete_confirm" ) ) {
+ buf = getData( userDeleteTemplate, injection );
+ }
+
+ }
+
+ if( injection != fixed_injection ) {
+ if( injection != NULL ) {
+ PR_Free( injection );
+ injection = NULL;
+ }
+
+ injection = fixed_injection;
+ }
+ } else if ( PL_strstr( query, "op=add_profile_user" )) {
+ tokendbDebug("authorization for op=add_profile_user");
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "add_profile_user", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "add_profile_user", "Success", "Tokendb user authorization");
+ uid = get_post_field(post, "uid", SHORT_LEN);
+ char *profile = get_post_field(post, "profile_0", SHORT_LEN);
+ char *other_profile = get_post_field(post, "other_profile", SHORT_LEN);
+ if ((profile != NULL) && (uid != NULL)) {
+ if (PL_strstr(profile, "Other Profiles")) {
+ if ((other_profile != NULL) && (match_profile(other_profile))) {
+ do_free(profile);
+ profile = PL_strdup(other_profile);
+ } else {
+ error_out("Invalid Profile to be added", "Invalid Profile to be added");
+ do_free(profile);
+ do_free(other_profile);
+ do_free(uid);
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return OK;
+ }
+ }
+ if (PL_strstr(profile, ALL_PROFILES)) {
+ status = delete_all_profiles_from_user(userid, uid);
+ }
+
+ PR_snprintf(oString, 512, "userid;;%s", uid);
+ PR_snprintf(pString, 512, "profile;;%s", profile);
+
+ status = add_profile_to_user(userid, uid, profile);
+ if ((status != LDAP_SUCCESS) && (status != LDAP_TYPE_OR_VALUE_EXISTS)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "Failure", oString, pString, "failure adding profile to user");
+ PR_snprintf(msg, 512, "LDAP Error in adding profile %s to user %s",
+ profile, uid);
+ post_ldap_error(msg);
+ }
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "profile added to user");
+ }
+ do_free(other_profile);
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ PR_snprintf((char *)msg, 512,
+ "'%s' has added profile %s to user %s", userid, profile, uid);
+ RA::tdb_activity(rq->connection->remote_ip, "", "add_profile", "success", msg, uid, NO_TOKEN_TYPE);
+
+ PR_snprintf(oString, 512, "userid;;%s", uid);
+ PR_snprintf(pString, 512, "profile;;%s", profile);
+
+ PR_snprintf(injection, MAX_INJECTION_SIZE,
+ "/tus/tus?op=edit_user&uid=%s&flash=Profile+%s+has+been+added+to+the+user+record",
+ uid, profile);
+ do_free(profile);
+ do_free(uid);
+ rq->method = apr_pstrdup(rq->pool, "GET");
+ rq->method_number = M_GET;
+
+ ap_internal_redirect_handler(injection, rq);
+ return OK;
+ } else if ( PL_strstr( query, "op=save_user" )) {
+ tokendbDebug( "authorization for op=save_user\n" );
+
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "save_user", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "save_user", "Success", "Tokendb user authorization");
+ // first save user details
+ uid = get_post_field(post, "uid", SHORT_LEN);
+ firstName = get_post_field(post, "firstName", SHORT_LEN);
+ lastName = get_post_field(post, "lastName", SHORT_LEN);
+ userCert = get_encoded_post_field(post, "userCert", HUGE_STRING_LEN);
+ opOperator = get_post_field(post, "opOperator", SHORT_LEN);
+ opAgent = get_post_field(post, "opAgent", SHORT_LEN);
+ opAdmin = get_post_field(post, "opAdmin", SHORT_LEN);
+
+ // construct audit log message
+ PR_snprintf(oString, 512, "userid;;%s", uid);
+ PR_snprintf(pLongString, 4096, "");
+ PR_snprintf(filter, 512, "uid=%s", uid);
+ status = find_tus_user_entries_no_vlv( filter, &result, 0);
+ e = get_first_entry( result );
+ if( e != NULL ) {
+ audit_attribute_change(e, "givenName", firstName, pLongString);
+ audit_attribute_change(e, "sn", lastName, pLongString);
+ }
+
+ if( result != NULL ) {
+ free_results( result );
+ result = NULL;
+ }
+
+ // now check cert
+ char *test_user = tus_authenticate(userCert);
+ if ((test_user != NULL) && (strcmp(test_user, uid) == 0)) {
+ // cert did not change
+ } else {
+ if (strlen(pLongString) > 0) PL_strcat(pLongString, "+");
+ PR_snprintf(pLongString, 4096, "%suserCertificate;;%s", pLongString, userCert);
+ }
+
+ PR_snprintf((char *)userCN, 256,
+ "%s%s%s", ((firstName != NULL && PL_strlen(firstName) > 0)? firstName: ""),
+ ((firstName != NULL && PL_strlen(firstName) > 0)? " ": ""), lastName);
+
+ status = update_user_db_entry(userid, uid, lastName, firstName, userCN, userCert);
+
+ do_free(firstName);
+ do_free(lastName);
+ do_free(userCert);
+
+ if( status != LDAP_SUCCESS ) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pLongString, "user record failed to be updated");
+ ldap_error_out("LDAP modify error: ", "LDAP error: %s");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ do_free(uid);
+ do_free(opOperator);
+ do_free(opAgent);
+ do_free(opAdmin);
+
+ return DONE;
+ }
+ if (strlen(pLongString) > 0)
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pLongString, "user record updated");
+
+ bool has_role = tus_authorize(TOKENDB_OPERATORS_IDENTIFIER, uid);
+ PR_snprintf(pString, 512, "role;;operator");
+ if ((opOperator != NULL) && (PL_strstr(opOperator, OPERATOR))) {
+ if (!has_role) {
+ status = add_user_to_role_db_entry(userid, uid, OPERATOR);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_TYPE_OR_VALUE_EXISTS)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error adding user to role");
+ PR_snprintf(msg, 512, "Error adding user %s to role %s", uid, OPERATOR);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user added to role");
+ }
+ }
+ } else if (has_role) {
+ status = delete_user_from_role_db_entry(userid, uid, OPERATOR);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error deleting user from role");
+ PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, OPERATOR);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user deleted from role");
+ }
+ }
+
+ has_role = tus_authorize(TOKENDB_AGENTS_IDENTIFIER, uid);
+ PR_snprintf(pString, 512, "role;;agent");
+ if ((opAgent != NULL) && (PL_strstr(opAgent, AGENT))) {
+ if (!has_role) {
+ status = add_user_to_role_db_entry(userid, uid, AGENT);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_TYPE_OR_VALUE_EXISTS)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error adding user to role");
+ PR_snprintf(msg, 512, "Error adding user %s to role %s", uid, AGENT);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user added to role");
+ }
+ }
+ } else if (has_role) {
+ status = delete_user_from_role_db_entry(userid, uid, AGENT);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error deleting user from role");
+ PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, AGENT);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user deleted from role");
+ }
+ }
+
+ has_role = tus_authorize(TOKENDB_ADMINISTRATORS_IDENTIFIER, uid);
+ PR_snprintf(pString, 512, "role;;administrator");
+ if ((opAdmin != NULL) && (PL_strstr(opAdmin, ADMINISTRATOR))) {
+ if (!has_role) {
+ status = add_user_to_role_db_entry(userid, uid, ADMINISTRATOR);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_TYPE_OR_VALUE_EXISTS)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error adding user to role");
+ PR_snprintf(msg, 512, "Error adding user %s to role %s", uid, ADMINISTRATOR);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user added to role");
+ }
+ }
+ } else if (has_role) {
+ status = delete_user_from_role_db_entry(userid, uid, ADMINISTRATOR);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error deleting user from role");
+ PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, ADMINISTRATOR);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user deleted from role");
+ }
+ }
+
+ do_free(opOperator);
+ do_free(opAgent);
+ do_free(opAdmin);
+
+ // save profile details
+ char *nProfileStr = get_post_field(post, "nProfiles", SHORT_LEN);
+ int nProfiles = atoi (nProfileStr);
+ do_free(nProfileStr);
+
+ for (int i=0; i< nProfiles; i++) {
+ char p_name[256];
+ char p_delete[256];
+ PR_snprintf(p_name, 256, "profile_%d", i);
+ PR_snprintf(p_delete, 256, "delete_%d", i);
+ char *profile = get_post_field(post, p_name, SHORT_LEN);
+ char *p_del = get_post_field(post, p_delete, SHORT_LEN);
+
+ if ((profile != NULL) && (p_del != NULL) && (PL_strstr(p_del, "delete"))) {
+ PR_snprintf(pString, 512, "profile_id;;%s", profile);
+ status = delete_profile_from_user(userid, uid, profile);
+ if ((status != LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "error deleting profile from user");
+ PR_snprintf(msg, 512, "LDAP Error in deleting profile %s from user %s",
+ profile, uid);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "profile deleted from user");
+ }
+ }
+ do_free(profile);
+ do_free(p_del);
+ }
+
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ PR_snprintf((char *)msg, 512,
+ "'%s' has modified user %s", userid, uid);
+ RA::tdb_activity(rq->connection->remote_ip, "", "modify_user", "success", msg, uid, NO_TOKEN_TYPE);
+
+ PR_snprintf(injection, MAX_INJECTION_SIZE,
+ "/tus/tus?op=edit_user&uid=%s&flash=User+record+%s+has+been+updated",
+ uid, uid);
+ do_free(uid);
+ rq->method = apr_pstrdup(rq->pool, "GET");
+ rq->method_number = M_GET;
+
+ ap_internal_redirect_handler(injection, rq);
+ return OK;
+ } else if( PL_strstr( query, "op=save" ) ) {
+ tokendbDebug( "authorization\n" );
+
+ if( ! is_agent ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "save", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "save", "Success", "Tokendb user authorization");
+
+ getCN( filter, query );
+ mNum = parse_modification_number( query );
+ mods = getModifications( query );
+
+ if( mNum != NULL ) {
+ status = check_and_modify_tus_db_entry( userid, filter,
+ mNum, mods );
+
+ PL_strfree( mNum );
+
+ mNum = NULL;
+ } else {
+ status = modify_tus_db_entry( userid, filter, mods );
+ }
+
+ int cc;
+ PR_snprintf(oString, 512, "token_id;;%s", filter);
+ PR_snprintf(pLongString, 4096, "");
+ int first_item = 1;
+ for (cc = 0; mods[cc] != NULL; cc++) {
+ if (! first_item) PL_strcat(pLongString, "+");
+ if (mods[cc]->mod_type != NULL) {
+ PL_strcat(pLongString, mods[cc]->mod_type);
+ PL_strcat(pLongString, ";;");
+ PL_strcat(pLongString, *mods[cc]->mod_values);
+ first_item =0;
+ }
+ }
+
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+
+ if( status != LDAP_SUCCESS ) {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pLongString, "failed to modify token record");
+ ldap_error_out("LDAP modify error: ", "LDAP error: %s");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Success", oString, pLongString, "token record modified");
+ PR_snprintf((char *)msg, 256, "Token record modified by %s", userid);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "save", "success",
+ msg, cuidUserId, tokenType);
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var tid = \"", filter, "\";\n");
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( editResultTemplate, injection );
+
+ } else if ( PL_strstr( query, "op=do_delete_user" ) ) {
+ tokendbDebug( "authorization for do_delete_user\n" );
+
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "do_delete_user", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "do_delete_user", "Success", "Tokendb user authorization");
+
+ uid = get_post_field(post, "uid", SHORT_LEN);
+
+ if (uid == NULL) {
+ error_out("Error in delete user. userid is null", "Error in delete user. userid is null");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+
+ bool officer = false;
+ bool agent = false;
+ bool admin = false;
+ status = find_tus_user_role_entries( uid, &result );
+ for (e = get_first_entry( result );
+ e != NULL;
+ e = get_next_entry( e ) ) {
+ char *dn = NULL;
+ dn = get_dn(e);
+ if (PL_strstr(dn, "Operators"))
+ officer=true;
+ if (PL_strstr(dn, "Agents"))
+ agent = true;
+ if (PL_strstr(dn, "Administrators"))
+ admin = true;
+ if (dn != NULL) {
+ PL_strfree(dn);
+ dn=NULL;
+ }
+ }
+
+ if (result != NULL) {
+ free_results( result );
+ result = NULL;
+ }
+
+ if (officer) {
+ status = delete_user_from_role_db_entry(userid, uid, OPERATOR);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) {
+ PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, OPERATOR);
+ post_ldap_error(msg);
+ }
+ }
+
+ if (agent) {
+ status = delete_user_from_role_db_entry(userid, uid, AGENT);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) {
+ PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, AGENT);
+ post_ldap_error(msg);
+ }
+ }
+
+ if (admin) {
+ status = delete_user_from_role_db_entry(userid, uid, ADMINISTRATOR);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) {
+ PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, ADMINISTRATOR);
+ post_ldap_error(msg);
+ }
+ }
+
+ status = delete_user_db_entry(userid, uid);
+
+ if ((status != LDAP_SUCCESS) && (status != LDAP_NO_SUCH_OBJECT)) {
+ PR_snprintf(oString, 512, "uid;;%s", uid);
+ PR_snprintf(pString, 512, "status;;%d", status);
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "error in deleting user");
+
+ PR_snprintf(msg, 512, "Error deleting user %s", uid);
+ ldap_error_out(msg, msg);
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ do_free(uid);
+
+ return DONE;
+ }
+
+ PR_snprintf((char *)msg, 256,
+ "'%s' has deleted user %s", userid, uid);
+ RA::tdb_activity(rq->connection->remote_ip, "", "delete_user", "success", msg, uid, NO_TOKEN_TYPE);
+ PR_snprintf(oString, 512, "uid;;%s", uid);
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, "", "tokendb user deleted");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var tid = \"", uid, "\";\n",
+ "var deleteType = \"user\";\n");
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ do_free(uid);
+
+ buf = getData( deleteResultTemplate, injection );
+ } else if ( PL_strstr( query, "op=addUser" ) ) {
+ tokendbDebug( "authorization for addUser\n" );
+
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "addUser", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "addUser", "Success", "Tokendb user authorization");
+
+ uid = get_post_field(post, "userid", SHORT_LEN);
+ firstName = get_post_field(post, "firstName", SHORT_LEN);
+ lastName = get_post_field(post, "lastName", SHORT_LEN);
+ opOperator = get_post_field(post, "opOperator", SHORT_LEN);
+ opAdmin = get_post_field(post, "opAdmin", SHORT_LEN);
+ opAgent = get_post_field(post, "opAgent", SHORT_LEN);
+ userCert = get_encoded_post_field(post, "cert", HUGE_STRING_LEN);
+
+ if ((PL_strlen(uid) == 0) || (PL_strlen(lastName) == 0)) {
+ error_out("Bad input to op=addUser", "Bad input to op=addUser");
+ do_free(uid);
+ do_free(firstName);
+ do_free(lastName);
+ do_free(opOperator);
+ do_free(opAdmin);
+ do_free(opAgent);
+ do_free(userCert);
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return OK;
+ }
+ PR_snprintf((char *)userCN, 256,
+ "%s%s%s", ((firstName != NULL && PL_strlen(firstName) > 0)? firstName: ""),
+ ((firstName != NULL && PL_strlen(firstName) > 0)? " ": ""), lastName);
+
+ PR_snprintf(oString, 512, "uid;;%s", uid);
+ PR_snprintf(pString, 512, "givenName;;%s+sn;;%s",
+ ((firstName != NULL && PL_strlen(firstName) > 0)? firstName: ""), lastName);
+
+ /* to meet STIG requirements, every user in ldap must have a password, even if that password is never used */
+ char *pwd = generatePassword(pwLength);
+ status = add_user_db_entry(userid, uid, pwd, lastName, firstName, userCN, userCert);
+ do_free(pwd);
+
+ if (status != LDAP_SUCCESS) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "Failure", oString, pString, "failure in adding tokendb user");
+ PR_snprintf((char *)msg, 512, "LDAP Error in adding new user %s", uid);
+ ldap_error_out(msg, msg);
+ do_free(uid);
+ do_free(firstName);
+ do_free(lastName);
+ do_free(opOperator);
+ do_free(opAdmin);
+ do_free(opAgent);
+ do_free(userCert);
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return OK;
+ }
+
+ PR_snprintf((char *)msg, 512,
+ "'%s' has created new user %s", userid, uid);
+ RA::tdb_activity(rq->connection->remote_ip, "", "add_user", "success", msg, uid, NO_TOKEN_TYPE);
+
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "tokendb user added");
+
+ PR_snprintf(pString, 512, "role;;operator");
+ if ((opOperator != NULL) && (PL_strstr(opOperator, OPERATOR))) {
+ status = add_user_to_role_db_entry(userid, uid, OPERATOR);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_TYPE_OR_VALUE_EXISTS)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error adding user to role");
+ PR_snprintf(msg, 512, "Error adding user %s to role %s", uid, OPERATOR);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user added to role");
+ }
+ } else {
+ status = delete_user_from_role_db_entry(userid, uid, OPERATOR);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error deleting user from role");
+ PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, OPERATOR);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user deleted from role");
+ }
+
+ }
+
+ PR_snprintf(pString, 512, "role;;agent");
+ if ((opAgent != NULL) && (PL_strstr(opAgent, AGENT))) {
+ status = add_user_to_role_db_entry(userid, uid, AGENT);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_TYPE_OR_VALUE_EXISTS)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error adding user to role");
+ PR_snprintf(msg, 512, "Error adding user %s to role %s", uid, AGENT);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user added to role");
+ }
+ } else {
+ status = delete_user_from_role_db_entry(userid, uid, AGENT);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error deleting user from role");
+ PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, AGENT);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user deleted from role");
+ }
+ }
+
+ PR_snprintf(pString, 512, "role;;admin");
+ if ((opAdmin != NULL) && (PL_strstr(opAdmin, ADMINISTRATOR))) {
+ status = add_user_to_role_db_entry(userid, uid, ADMINISTRATOR);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_TYPE_OR_VALUE_EXISTS)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error adding user to role");
+ PR_snprintf(msg, 512, "Error adding user %s to role %s", uid, ADMINISTRATOR);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user added to role");
+ }
+ } else {
+ status = delete_user_from_role_db_entry(userid, uid, ADMINISTRATOR);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error deleting user from role");
+ PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, ADMINISTRATOR);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user deleted from role");
+ }
+ }
+
+ do_free(firstName);
+ do_free(lastName);
+ do_free(opOperator);
+ do_free(opAdmin);
+ do_free(opAgent);
+ do_free(userCert);
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var tid = \"", uid, "\";\n",
+ "var addType = \"user\";\n");
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ do_free(uid);
+
+ buf = getData( addResultTemplate, injection );
+
+ } else if( PL_strstr( query, "op=add" ) ) {
+ tokendbDebug( "authorization for op=add\n" );
+ RA_Status token_type_status;
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "add", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "add", "Success", "Tokendb user authorization");
+
+ getCN( filter, query );
+
+ if (m_processor.GetTokenType(OP_PREFIX, 0, 0, filter, (const char*) NULL, (NameValueSet*) NULL,
+ token_type_status, tokentype)) {
+ PL_strcpy(tokenType, tokentype);
+ } else {
+ PL_strcpy(tokenType, NO_TOKEN_TYPE);
+ }
+
+ if( strcmp( filter, "" ) == 0 ) {
+ error_out("No Token ID Found", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ status = add_default_tus_db_entry( NULL, userid,
+ filter, "uninitialized",
+ NULL, NULL, tokenType );
+
+ PR_snprintf(oString, 512, "token_id;;%s", filter);
+ if( status != LDAP_SUCCESS ) {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Admin", "Failure", oString, "", "failed to add token record");
+ ldap_error_out("LDAP add error: ", "LDAP error: %s");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Admin", "Success", oString, "", "token record added");
+
+ PR_snprintf((char *)msg, 256,
+ "'%s' has created new token", userid);
+ RA::tdb_activity(rq->connection->remote_ip, filter, "add", "token", msg, "success", tokenType);
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var tid = \"", filter, "\";\n",
+ "var addType = \"token\";\n");
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+
+ buf = getData( addResultTemplate, injection );
+ } else if( PL_strstr( query, "op=delete" ) ) {
+ RA_Status token_type_status;
+ tokendbDebug( "authorization for op=delete\n" );
+
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "delete", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "delete", "Success", "Tokendb user authorization");
+
+ getCN( filter, query );
+
+ if (m_processor.GetTokenType(OP_PREFIX, 0, 0, filter, (const char*) NULL, (NameValueSet*) NULL,
+ token_type_status, tokentype)) {
+ PL_strcpy(tokenType, tokentype);
+ } else {
+ PL_strcpy(tokenType, NO_TOKEN_TYPE);
+ }
+
+
+ PR_snprintf((char *)msg, 256,
+ "'%s' has deleted token", userid);
+ RA::tdb_activity(rq->connection->remote_ip, filter, "delete", "token", msg, "", tokenType);
+
+ PR_snprintf(oString, 512, "token_id;;%s", filter);
+ status = delete_tus_db_entry( userid, filter );
+
+ if( status != LDAP_SUCCESS ) {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Admin", "Failure", oString, "", "failure in deleting token record");
+ ldap_error_out("LDAP delete error: ", "LDAP error: %s");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Admin", "Success", oString, "", "token record deleted");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var tid = \"", filter, "\";\n",
+ "var deleteType = \"token\";\n");
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( deleteResultTemplate, injection );
+ } else if ( PL_strstr( query, "op=audit_admin") ) {
+ tokendbDebug( "authorization for op=audit_admin\n" );
+
+ if (!is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "audit_admin", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "audit_admin", "Success", "Tokendb user authorization");
+
+ PR_snprintf (injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%d%s%s%d%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var signedAuditEnable = \"", RA::m_audit_enabled ? "true": "false", "\";\n",
+ "var logSigningEnable = \"", RA::m_audit_signed ? "true" : "false", "\";\n",
+ "var signedAuditLogInterval = \"", RA::m_flush_interval, "\";\n",
+ "var signedAuditLogBufferSize = \"", RA::m_buffer_size, "\";\n",
+ "var signedAuditSelectedEvents = \"", RA::m_signedAuditSelectedEvents, "\";\n",
+ "var signedAuditSelectableEvents = \"", RA::m_signedAuditSelectableEvents, "\";\n",
+ "var signedAuditNonSelectableEvents = \"", RA::m_signedAuditNonSelectableEvents, "\";\n");
+
+ RA::Debug( "mod_tokendb::mod_tokendb_handler",
+ "signedAudit: %s %s %d %d %s %s %s",
+ RA::m_audit_enabled ? "true": "false",
+ RA::m_audit_signed ? "true": "false",
+ RA::m_flush_interval,
+ RA::m_buffer_size,
+ RA::m_signedAuditSelectedEvents,
+ RA::m_signedAuditSelectableEvents,
+ RA::m_signedAuditNonSelectableEvents);
+
+ char *flash = get_field(query, "flash=", SHORT_LEN);
+ if (flash != NULL) {
+ PL_strcat(injection, "var flash = \"");
+ PL_strcat(injection, flash);
+ PL_strcat(injection, "\";\n");
+ do_free(flash);
+ }
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+ buf = getData(auditAdminTemplate, injection);
+ } else if (PL_strstr( query, "op=update_audit_admin") ) {
+ tokendbDebug( "authorization for op=audit_admin\n" );
+
+ if (!is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "update_audit_admin", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "update_audit_admin", "Success", "Tokendb user authorization");
+
+ int need_update=0;
+
+ bool o_signing = RA::m_audit_signed;
+ bool n_signing = o_signing;
+ char *logSigning = get_post_field(post, "logSigningEnable", SHORT_LEN);
+ if (logSigning != NULL) {
+ n_signing = (PL_strcmp(logSigning, "true") == 0)? true: false;
+ }
+ do_free(logSigning);
+
+ bool o_enable = RA::m_audit_enabled;
+ bool n_enable = o_enable;
+ char *auditEnable = get_post_field(post, "auditEnable", SHORT_LEN);
+ if (auditEnable != NULL) {
+ n_enable = (PL_strcmp(auditEnable, "true") == 0)? true: false;
+ }
+ do_free(auditEnable);
+
+ if ((o_signing == n_signing) && (o_enable == n_enable)) {
+ // nothing changed, continue
+ } else {
+ if (o_signing != n_signing) {
+ PR_snprintf(pString, 512, "logging.audit.logSigning;;%s", (n_signing)? "true":"false");
+ if (o_enable != n_enable) {
+ PL_strcat(pString, "+logging.audit.enable;;");
+ PL_strcat(pString, (n_enable)? "true" : "false");
+ }
+ } else {
+ PR_snprintf(pString, 512, "logging.audit.enable;;%s", (n_enable)? "true":"false");
+ }
+
+ RA::Audit(EV_CONFIG_AUDIT, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", pString, "attempting to modify audit log configuration");
+
+ if (n_enable) { // be sure to log audit log startup messages,if any
+ RA::enable_audit_logging(n_enable);
+ }
+
+ RA::setup_audit_log(n_signing, n_signing != o_signing);
+
+ if (n_enable && !o_enable) {
+ RA::Audit(EV_AUDIT_LOG_STARTUP, AUDIT_MSG_FORMAT, "System", "Success",
+ "audit function startup");
+ } else if (!n_enable && o_enable) {
+ RA::Audit(EV_AUDIT_LOG_SHUTDOWN, AUDIT_MSG_FORMAT, "System", "Success",
+ "audit function shutdown");
+ }
+ RA::FlushAuditLogBuffer();
+
+ // sleep to ensure all logs written
+ PR_Sleep(PR_SecondsToInterval(1));
+
+ if (!n_enable) { // turn off logging after all logs written
+ RA::enable_audit_logging(n_enable);
+ }
+ need_update = 1;
+
+ RA::Audit(EV_CONFIG_AUDIT, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", pString, "audit log config modified");
+ PR_snprintf((char *)msg, 512, "'%s' has modified audit log config: %s", userid, pString);
+ RA::tdb_activity(rq->connection->remote_ip, "", "modify_audit_signing", "success", msg, userid, NO_TOKEN_TYPE);
+ }
+
+ char *logSigningInterval_str = get_post_field(post, "logSigningInterval", SHORT_LEN);
+ int logSigningInterval = atoi(logSigningInterval_str);
+ do_free(logSigningInterval_str);
+
+ if ((logSigningInterval>=0) &&(logSigningInterval != RA::m_flush_interval)) {
+ RA::SetFlushInterval(logSigningInterval);
+ PR_snprintf((char *)msg, 512, "'%s' has modified the audit log signing interval to %d seconds", userid, logSigningInterval);
+ RA::tdb_activity(rq->connection->remote_ip, "", "modify_audit_signing", "success", msg, userid, NO_TOKEN_TYPE);
+
+ PR_snprintf(pString, 512, "logging.audit.flush.interval;;%d", logSigningInterval);
+ RA::Audit(EV_CONFIG_AUDIT, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", pString, "audit log configuration modified");
+ }
+
+ char *logSigningBufferSize_str = get_post_field(post, "logSigningBufferSize", SHORT_LEN);
+ int logSigningBufferSize = atoi(logSigningBufferSize_str);
+ do_free(logSigningBufferSize_str);
+
+ if ((logSigningBufferSize >= 512) && (logSigningBufferSize != (int) RA::m_buffer_size)) {
+ RA::SetBufferSize(logSigningBufferSize);
+ PR_snprintf((char *)msg, 512, "'%s' has modified the audit log signing buffer size to %d bytes", userid, logSigningBufferSize);
+ RA::tdb_activity(rq->connection->remote_ip, "", "modify_audit_signing", "success", msg, userid, NO_TOKEN_TYPE);
+
+ PR_snprintf(pString, 512, "logging.audit.buffer.size;;%d", logSigningBufferSize);
+ RA::Audit(EV_CONFIG_AUDIT, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", pString, "audit log configuration modified");
+ }
+
+ char *nEvents_str = get_post_field(post, "nEvents", SHORT_LEN);
+ int nEvents = atoi(nEvents_str);
+ do_free(nEvents_str);
+
+ char new_selected[MAX_INJECTION_SIZE];
+
+ int first_match = 1;
+ for (int i=0; i< nEvents; i++) {
+ char e_name[256];
+ PR_snprintf(e_name, 256, "event_%d", i);
+ char *event = get_post_field(post, e_name, SHORT_LEN);
+ if ((event != NULL) && RA::IsValidEvent(event)) {
+ if (first_match != 1) {
+ PL_strcat(new_selected, ",");
+ }
+ first_match = 0;
+ PL_strcat(new_selected, event);
+ }
+ do_free(event);
+ }
+
+ if (PL_strcmp(new_selected, RA::m_signedAuditSelectedEvents) != 0) {
+ need_update = 1;
+ RA::update_signed_audit_selected_events(new_selected);
+
+ PR_snprintf((char *)msg, 512,
+ "'%s' has modified audit signing configuration", userid);
+ RA::tdb_activity(rq->connection->remote_ip, "", "modify_audit_signing", "success", msg, userid, NO_TOKEN_TYPE);
+
+ PR_snprintf(pLongString, 4096, "logging.audit.selected.events;;%s", new_selected);
+ RA::Audit(EV_CONFIG_AUDIT, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", pLongString, "audit log configuration modified");
+
+ }
+
+ if (need_update == 1) {
+ tokendbDebug("Updating signed audit events in CS.cfg");
+ char error_msg[512];
+ status = RA::GetConfigStore()->Commit(true, error_msg, 512);
+ if (status != 0) {
+ tokendbDebug(error_msg);
+ }
+ }
+
+ PR_snprintf(injection, MAX_INJECTION_SIZE,
+ "/tus/tus?op=audit_admin&flash=Signed+Audit+configuration+has+been+updated");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ rq->method = apr_pstrdup(rq->pool, "GET");
+ rq->method_number = M_GET;
+
+ ap_internal_redirect_handler(injection, rq);
+ return OK;
+ } else if ( PL_strstr( query, "op=self_test") ) {
+ tokendbDebug( "authorization for op=self_test\n" );
+
+ if (!is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "self_test", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_free(uri);
+ do_free(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "self_test", "Success", "Tokendb user authorization");
+
+ PR_snprintf (injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%d%s%s%d%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var enabled = ", SelfTest::isOnDemandEnabled(), ";\n",
+ "var critical = ", SelfTest::isOnDemandCritical(), ";\n");
+
+ if (SelfTest::nTests > 0)
+ PL_strcat(injection, "var test_list = [");
+ for (int i = 0; i < SelfTest::nTests; i++) {
+ RA::Debug( "mod_tokendb::mod_tokendb_handler", "test name: %s", SelfTest::TEST_NAMES[i]);
+ if (i > 0)
+ PL_strcat(injection, ", ");
+ PL_strcat(injection, "\"");
+ PL_strcat(injection, SelfTest::TEST_NAMES[i]);
+ PL_strcat(injection, "\"");
+ }
+ if (SelfTest::nTests > 0)
+ PL_strcat(injection, "];\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+ buf = getData(selfTestTemplate, injection);
+ } else if ( PL_strstr( query, "op=run_self_test" ) ) {
+ tokendbDebug( "authorization for run_self_test\n" );
+
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "run_self_test", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_free(uri);
+ do_free(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "run_self_test", "Success", "Tokendb user authorization");
+
+ rc = SelfTest::runOnDemandSelfTests();
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%d%s%s%d%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var enabled = ", SelfTest::isOnDemandEnabled(), ";\n",
+ "var result = \"", rc, "\";\n");
+
+ if (SelfTest::nTests > 0)
+ PL_strcat(injection, "var test_list = [");
+ for (int i = 0; i < SelfTest::nTests; i++) {
+ RA::Debug( "mod_tokendb::mod_tokendb_handler", "test name: %s", SelfTest::TEST_NAMES[i]);
+ if (i > 0)
+ PL_strcat(injection, ", ");
+ PL_strcat(injection, "\"");
+ PL_strcat(injection, SelfTest::TEST_NAMES[i]);
+ PL_strcat(injection, "\"");
+ }
+ if (SelfTest::nTests > 0)
+ PL_strcat(injection, "];\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( selfTestResultsTemplate, injection );
+ } else if( ( PL_strstr( query, "op=agent_select_config" ) ) ) {
+ tokendbDebug( "authorization for op=agent_select_config\n" );
+ if (! is_agent) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "agent_select_config", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "agent_select_config", "Success", "Tokendb user authorization");
+
+ char *conf_type = NULL;
+ char *disp_conf_type = NULL;
+ conf_type = get_field(query, "type=", SHORT_LEN);
+
+ if (conf_type == NULL) {
+ error_out("Invalid Invocation: Type is NULL", "Type is NULL");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ do_free(conf_type);
+ return DONE;
+ }
+
+ // check if agent has permission to see this config parameter
+ if (! agent_must_approve(conf_type)) {
+ error_out("Invalid Invocation: Agent is not permitted to view this configuration item", "Agent is not permitted to view this configuration item");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.list", conf_type );
+ const char *conf_list = RA::GetConfigStore()->GetConfigAsString( configname );
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", conf_type );
+ disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var conf_type = \"", conf_type, "\";\n",
+ "var disp_conf_type = \"", disp_conf_type, "\";\n",
+ "var conf_list = \"", (conf_list != NULL)? conf_list : "", "\";\n");
+
+ do_free(conf_type);
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection); //needed?
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( agentSelectConfigTemplate, injection );
+ } else if( ( PL_strstr( query, "op=select_config_parameter" ) ) ) {
+ tokendbDebug( "authorization for op=select_config_parameter\n" );
+ if (! is_admin) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "select_config_parameter", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "select_config_parameter", "Success", "Tokendb user authorization");
+
+ char *conf_type = NULL;
+ conf_type = get_field(query, "type=", SHORT_LEN);
+
+ if (conf_type == NULL) {
+ error_out("Invalid Invocation: Type is NULL", "Type is NULL");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ PR_snprintf( ( char * ) configname, 256,
+ "target.%s.list", conf_type );
+ const char *conf_list = RA::GetConfigStore()->GetConfigAsString( configname );
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", conf_type );
+ const char *disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var conf_type = \"", conf_type, "\";\n",
+ "var disp_conf_type = \"", disp_conf_type, "\";\n",
+ "var conf_list = \"", (conf_list != NULL)? conf_list : "", "\";\n");
+
+ do_free(conf_type);
+ // do_free(conf_list);
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection); //needed?
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( selectConfigTemplate, injection );
+ }
+
+ if( buf != NULL ) {
+ len = PL_strlen( buf );
+
+ ( void ) ap_rwrite( ( const void * ) buf, len, rq );
+
+ do_free(buf);
+ }
+ do_free(userid);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return OK;
+}
+
+
+
+/* _________________________________________________________________
+**
+** Tokendb Module Command Phase
+** _________________________________________________________________
+*/
+
+static const char *mod_tokendb_get_config_path_file( cmd_parms *cmd,
+ void *mconfig,
+ const char *tokendbconf )
+{
+ if( cmd->path ) {
+ ap_log_error( APLOG_MARK, APLOG_ERR, 0, NULL,
+ "The %s config param cannot be specified "
+ "in a Directory section.",
+ cmd->directive->directive );
+ } else {
+ mod_tokendb_server_configuration *sc = NULL;
+
+ /* Retrieve the Tokendb module. */
+ sc = ( ( mod_tokendb_server_configuration * )
+ ap_get_module_config( cmd->server->module_config,
+ &MOD_TOKENDB_CONFIG_KEY ) );
+
+ /* Initialize the "Tokendb Configuration File" */
+ /* member of mod_tokendb_server_configuration. */
+ sc->Tokendb_Configuration_File = apr_pstrdup( cmd->pool, tokendbconf );
+ }
+
+ return NULL;
+}
+
+
+static const command_rec mod_tokendb_config_cmds[] = {
+ AP_INIT_TAKE1( MOD_TOKENDB_CONFIGURATION_FILE_PARAMETER,
+ ( const char*(*)() ) mod_tokendb_get_config_path_file,
+ NULL,
+ RSRC_CONF,
+ MOD_TOKENDB_CONFIGURATION_FILE_USAGE ),
+ { NULL }
+};
+
+
+
+/* _________________________________________________________________
+**
+** Tokendb Module Server Configuration Creation Phase
+** _________________________________________________________________
+*/
+
+/**
+ * Create Tokendb module server configuration
+ */
+static void *
+mod_tokendb_config_server_create( apr_pool_t *p, server_rec *sv )
+{
+ /* Initialize all APR library routines. */
+ apr_initialize();
+
+ /* Create a memory pool for this server. */
+ mod_tokendb_server_configuration *sc = ( mod_tokendb_server_configuration * )
+ apr_pcalloc( p,
+ ( apr_size_t )
+ sizeof( *sc ) );
+
+ /* Initialize all members of mod_tokendb_server_configuration. */
+ sc->Tokendb_Configuration_File = NULL;
+ sc->enabled = MOD_TOKENDB_FALSE;
+
+ return sc;
+}
+
+
+
+/* _________________________________________________________________
+**
+** Tokendb Module Registration Phase
+** _________________________________________________________________
+*/
+
+static void
+mod_tokendb_register_hooks( apr_pool_t *p )
+{
+ static const char *const mod_tokendb_preloaded_modules[] = { "mod_nss.c",
+ "mod_tps.cpp",
+ NULL };
+ static const char *const mod_tokendb_postloaded_modules[] = { NULL };
+
+ ap_hook_post_config( mod_tokendb_initialize,
+ mod_tokendb_preloaded_modules,
+ mod_tokendb_postloaded_modules,
+ APR_HOOK_MIDDLE );
+
+ ap_hook_handler( mod_tokendb_handler,
+ mod_tokendb_preloaded_modules,
+ mod_tokendb_postloaded_modules,
+ APR_HOOK_MIDDLE );
+}
+
+
+module TOKENDB_PUBLIC MOD_TOKENDB_CONFIG_KEY = {
+ STANDARD20_MODULE_STUFF,
+ NULL, /* create per-dir config structures */
+ NULL, /* merge per-dir config structures */
+ mod_tokendb_config_server_create, /* create per-server config structures */
+ NULL, /* merge per-server config structures */
+ mod_tokendb_config_cmds, /* table of configuration directives */
+ mod_tokendb_register_hooks /* register hooks */
+};
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/base/tps/src/modules/tps/AP_Context.cpp b/base/tps/src/modules/tps/AP_Context.cpp
new file mode 100644
index 000000000..cde314254
--- /dev/null
+++ b/base/tps/src/modules/tps/AP_Context.cpp
@@ -0,0 +1,83 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "httpd/httpd.h"
+#include "httpd/http_log.h"
+#include "nspr.h"
+
+#include "modules/tps/AP_Context.h"
+
+#define MAX_LOG_MSG_SIZE 4096
+
+
+AP_Context::AP_Context( server_rec *sv )
+{
+ m_sv = sv;
+}
+
+
+AP_Context::~AP_Context()
+{
+ /* no clean up */
+}
+
+
+void AP_Context::LogError( const char *func, int line, const char *fmt, ... )
+{
+ char buf[MAX_LOG_MSG_SIZE];
+
+ va_list argp;
+ va_start( argp, fmt );
+ PR_vsnprintf( buf, MAX_LOG_MSG_SIZE, fmt, argp );
+ va_end( argp );
+
+ ap_log_error( func, line, APLOG_ERR, 0, m_sv, buf );
+}
+
+
+void AP_Context::LogInfo( const char *func, int line, const char *fmt, ... )
+{
+ char buf[MAX_LOG_MSG_SIZE];
+
+ va_list argp;
+ va_start( argp, fmt );
+ PR_vsnprintf( buf, MAX_LOG_MSG_SIZE, fmt, argp );
+ va_end( argp );
+
+ ap_log_error( func, line, APLOG_INFO, 0, m_sv, buf );
+}
+
+
+void AP_Context::InitializationError( const char *func, int line )
+{
+ ap_log_error( func, line, APLOG_INFO, 0, m_sv,
+ "The nss module must be initialized "
+ "prior to calling the tps module." );
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/base/tps/src/modules/tps/AP_Session.cpp b/base/tps/src/modules/tps/AP_Session.cpp
new file mode 100644
index 000000000..36f455355
--- /dev/null
+++ b/base/tps/src/modules/tps/AP_Session.cpp
@@ -0,0 +1,1169 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include "nspr.h"
+#include "httpd/httpd.h"
+#include "httpd/http_protocol.h"
+
+#include "engine/RA.h"
+#include "main/Util.h"
+#include "main/RA_Msg.h"
+#include "main/RA_pblock.h"
+#include "main/RA_Session.h"
+#include "msg/RA_Begin_Op_Msg.h"
+#include "msg/RA_Login_Response_Msg.h"
+#include "msg/RA_Extended_Login_Response_Msg.h"
+#include "msg/RA_SecureId_Response_Msg.h"
+#include "msg/RA_ASQ_Response_Msg.h"
+#include "msg/RA_New_Pin_Response_Msg.h"
+#include "msg/RA_Token_PDU_Response_Msg.h"
+#include "msg/RA_Login_Request_Msg.h"
+#include "msg/RA_Extended_Login_Request_Msg.h"
+#include "msg/RA_SecureId_Request_Msg.h"
+#include "msg/RA_ASQ_Request_Msg.h"
+#include "msg/RA_New_Pin_Request_Msg.h"
+#include "msg/RA_Token_PDU_Request_Msg.h"
+#include "msg/RA_End_Op_Msg.h"
+#include "msg/RA_Status_Update_Request_Msg.h"
+#include "msg/RA_Status_Update_Response_Msg.h"
+#include "modules/tps/AP_Session.h"
+#include "main/Memory.h"
+#include "apr_strings.h"
+
+/**
+ * http parameters used in the protocol
+ */
+#define PARAM_MSG_TYPE "msg_type"
+#define PARAM_OPERATION "operation"
+#define PARAM_INVALID_PW "invalid_pw"
+#define PARAM_BLOCKED "blocked"
+#define PARAM_SCREEN_NAME "screen_name"
+#define PARAM_PASSWORD "password"
+#define PARAM_PIN_REQUIRED "pin_required"
+#define PARAM_NEXT_VALUE "next_value"
+#define PARAM_VALUE "value"
+#define PARAM_PIN "pin"
+#define PARAM_QUESTION "question"
+#define PARAM_ANSWER "answer"
+#define PARAM_MINIMUM_LENGTH "minimum_length"
+#define PARAM_MAXIMUM_LENGTH "maximum_length"
+#define PARAM_NEW_PIN "new_pin"
+#define PARAM_PDU_SIZE "pdu_size"
+#define PARAM_PDU_DATA "pdu_data"
+#define PARAM_RESULT "result"
+#define PARAM_MESSAGE "message"
+#define PARAM_STATUS "current_state"
+#define PARAM_INFO "next_task_name"
+#define PARAM_EXTENSIONS "extensions"
+
+#define MAX_RA_MSG_SIZE 4096
+#define MAX_LOG_MSG_SIZE 4096
+
+// maximum number of digits for message length
+#define MAX_LEN_DIGITS 4
+
+
+static int contains_sensitive_keywords(char *msg)
+{
+ if (strstr(msg, "password" ) != NULL ) {
+ return 1;
+ }
+ if (strstr(msg, "PASSWORD" ) != NULL ) {
+ return 1;
+ }
+ if (strstr(msg, "new_pin" ) != NULL ) {
+ return 1;
+ }
+ return 0;
+}
+
+
+/**
+ * AP_Session represents an active connection between the
+ * Registration authority and the token client.
+ *
+ * Note that AP_Session encapsulates all the glue logic
+ * between Apache and the RA. If we need to go to anther platform
+ * (i.e. NPE, NES, or other web servers) later, we just need
+ * to implement a new Session implementation.
+ */
+AP_Session::AP_Session( request_rec *rq )
+{
+ m_rq = rq;
+ /* REQUEST_CHUNKED_DECHUNK If chunked, remove the chunks for me */
+ ap_setup_client_block( rq, REQUEST_CHUNKED_DECHUNK);
+}
+
+
+AP_Session::~AP_Session()
+{
+ /* no clean up */
+}
+
+
+char *AP_Session::GetRemoteIP()
+{
+ return ( m_rq->connection->remote_ip );
+}
+
+
+/**
+ * reads from network "s=xx" where xx is the length of the message
+ * that follows. The length is returned as int.
+ * @return length in int
+ */
+static int GetMsgLen( request_rec *rq )
+{
+ int len=0;
+ char msg_len[MAX_LEN_DIGITS]; // msg_len can't take more than 4 digits
+ char *p_msg_len = msg_len;
+ int sum = 0;
+
+ /* read msg size */
+ len = ( int ) ap_get_client_block( rq, p_msg_len,
+ ( apr_size_t ) 1 ); /* s */
+ if( len != 1 ) {
+ RA::Error( "AP_Session::GetMsgLen",
+ "ap_get_client_block returned error: %d", len );
+
+ return 0;
+ }
+
+ len = ( int ) ap_get_client_block( rq, p_msg_len,
+ ( apr_size_t ) 1 ); /* = */
+
+ if( len != 1 ) {
+ RA::Error( "AP_Session::GetMsgLen",
+ "ap_get_client_block returned error: %d", len );
+
+ return 0;
+ }
+
+ while( 1 ) {
+ if( sum > ( MAX_LEN_DIGITS -1 ) ) {
+ /* the length is too large */
+ RA::Error( "AP_Session::ReadMsg", "Message Size is too large." );
+ return -1;
+ }
+
+ len = ( int ) ap_get_client_block( rq, p_msg_len, ( apr_size_t ) 1 );
+
+ if( len != 1 ) {
+ break;
+ }
+
+ if( len != 0 ) {
+ if( *p_msg_len == '&' ) {
+ break;
+ }
+
+ p_msg_len++;
+ sum++;
+ }
+ }
+
+ *p_msg_len = '\0';
+
+ return atoi( msg_len );
+}
+
+static int GetMsg( request_rec *rq, char *buf, int size )
+{
+ int len;
+ int sum = 0;
+ char *p_msg = buf;
+
+ while( 1 ) {
+ len = ( int ) ap_get_client_block( rq, p_msg, ( apr_size_t ) 1 );
+ if( len != 1 ) {
+ return -1;
+ }
+ p_msg += len;
+ sum += len;
+ buf[sum] = '\0';
+ if( sum == size ) {
+ break;
+ }
+ }
+
+ buf[sum] = '\0';
+
+ return sum;
+}
+
+char *stripEmptyArgs( char *data )
+{
+ char *n_data = ( char * ) PR_Malloc( strlen( data ) + 2 );
+ n_data[0] = '\0';
+ int nv_count = 0;
+
+ if( data != NULL && strlen( data ) > 0 ) {
+ char *lasts = NULL;
+ char *tok = PL_strtok_r( data, " ", &lasts );
+
+ while( tok != NULL ) {
+ if( tok[strlen( tok )-1] != '=' ) {
+ n_data = strcat( n_data, tok );
+ n_data = strcat( n_data, " " );
+ nv_count++;
+ }
+
+ tok = PL_strtok_r( NULL, " ", &lasts );
+ }
+ int len = strlen( n_data );
+ n_data[len-1] = '\0';
+ }
+
+ if( ( nv_count > MAX_NVS ) || ( n_data[0] == '\0' ) ) {
+ PR_Free( n_data );
+ n_data = NULL;
+ }
+
+ return n_data;
+}
+
+
+int pblock_str2pblock( char *n_data, apr_array_header_t *tm_pblock , request_rec *rec)
+{
+ int element = 0;
+
+ if( n_data != NULL && strlen( n_data ) > 0 ) {
+ char *lasts = NULL;
+ char *tok = PL_strtok_r( n_data, " ", &lasts );
+
+ /* store each name/value pair in the string into the pblock array */
+ while( tok != NULL ) {
+ char name[4096];
+ char value[4096];
+
+ for( int i = 0; i < ( int ) strlen( tok ); i++ ) {
+ if( tok[i] != '=' ) {
+ /* extract and add to the name portion */
+ name[i] = tok[i];
+ } else {
+ /* null terminate the name portion */
+ name[i] = '\0';
+ /* extract the entire value portion */
+ strcpy( value, &tok[i+1] );
+ break;
+ }
+ }
+
+ /* store the name/value pair as an entry in the pblock array */
+ ( ( apr_table_entry_t * ) tm_pblock->elts )[element].key =
+ apr_pstrdup(rec->pool, name);
+ ( ( apr_table_entry_t * ) tm_pblock->elts )[element].val =
+ apr_pstrdup(rec->pool, value);
+
+ /* increment the entry to the pblock array */
+ element++;
+
+ /* get the next name/value pair from the string */
+ tok = PL_strtok_r( NULL, " ", &lasts );
+ }
+ }
+
+ return element;
+}
+
+
+/**
+ * Parses the data and creates an RA_pblock to store name/value pairs
+ * @param data null-terminated string containing a string with format:
+ * n1=v1&n2=v2&n3=v3&...
+ * @return
+ * pointer to RA_pblock if success
+ * NULL if failure;
+ */
+RA_pblock *AP_Session::create_pblock( char *data )
+{
+ if( ( data == NULL ) || ( data[0] == '\0' ) ) {
+ RA::Error( "AP_Session::create_pblock",
+ "data is NULL" );
+ return NULL;
+ }
+
+ if(contains_sensitive_keywords(data)) {
+ RA::Debug( LL_PER_PDU,
+ "AP_Session::create_pblock",
+ "Data '(sensitive)'");
+ } else {
+ RA::Debug( LL_PER_PDU,
+ "AP_Session::create_pblock",
+ "Data '%s'", data);
+ }
+
+ //
+ // The data contains a set of name value pairs separated by an '&'
+ // (i. e. - n1=v1&n2=v2...). Replace each '&' with a ' '.
+ //
+ // Note that since the values are expected to have been url-encoded,
+ // they must be url-decoded within the subclass method.
+ //
+ int i, j;
+ int len = strlen( data );
+
+ for( i = 0; i < len; i++ ) {
+ // need to check if data[i] is a valid url-encoded char...later
+ if( data[i] == '&' ) {
+ data[i] = ' ';
+ }
+ }
+
+ apr_array_header_t *tm_pblock = apr_array_make( m_rq->pool,
+ MAX_NVS,
+ sizeof( apr_table_entry_t )
+ );
+
+ if( tm_pblock == NULL ) {
+ RA::Error( "AP_Session::create_pblock",
+ "apr_array_make returns NULL" );
+ return NULL;
+ }
+
+ //
+ // The data is in the format of "name=v1 name=v2 name=v3". If the data
+ // has content like "name=v1 name= name=v3", the pblock_str2pblock will
+ // return (-1). This is because pblock_str2pblock does not know how to
+ // handle the case of an empty value. Therefore, before we invoke
+ // pblock_str2pblock, we make sure to remove any input data which
+ // contains an empty value.
+ //
+ char *n_data = stripEmptyArgs( data );
+ if( n_data == NULL ) {
+ RA::Error( "AP_Session::create_pblock",
+ "stripEmptyArgs was either empty or "
+ "contained more than %d name/value pairs!",
+ MAX_NVS );
+ return NULL;
+ }
+
+ int tm_nargs = pblock_str2pblock( n_data, tm_pblock , m_rq);
+ apr_table_entry_t *pe = NULL;
+
+ RA::Debug( LL_PER_PDU,
+ "AP_Session::create_pblock",
+ "Found Arguments=%d, nalloc=%d",
+ tm_nargs,
+ tm_pblock->nalloc );
+
+ // url decode all values and place into Buffer_nv's
+ Buffer_nv *tm_nvs[MAX_NVS];
+
+ for( i = 0, j = 0; i < tm_nargs; i++, j++ ) {
+ tm_nvs[j] = NULL;
+
+ pe = ( apr_table_entry_t * ) tm_pblock->elts;
+
+ if( pe == NULL ) {
+ continue;
+ }
+
+ if( ( pe[i].key == NULL ) ||
+ ( ( PR_CompareStrings( pe[i].key, "" ) == 1 ) ) ||
+ ( pe[i].val == NULL ) ||
+ ( ( PR_CompareStrings( pe[i].val, "" ) == 1 ) ) ) {
+ RA::Debug( LL_ALL_DATA_IN_PDU,
+ "AP_Session::create_pblock",
+ "name/value pair contains NULL...skip" );
+ continue;
+ }
+
+ if(contains_sensitive_keywords(pe[i].key)) {
+ RA::Debug( LL_PER_PDU,
+ "AP_Session::create_pblock",
+ "entry name=%s, value=<...do not print...>",
+ pe[i].key );
+ } else {
+ RA::Debug( LL_PER_PDU,
+ "AP_Session::create_pblock",
+ "entry name=%s, value=%s",
+ pe[i].key,
+ pe[i].val );
+ }
+
+ Buffer *decoded = NULL;
+
+ decoded = Util::URLDecode( pe[i].val );
+
+ tm_nvs[j] = ( struct Buffer_nv * )
+ PR_Malloc( sizeof( struct Buffer_nv ) );
+
+ if( tm_nvs[j] != NULL ) {
+ tm_nvs[j]->name = PL_strdup( pe[i].key );
+ tm_nvs[j]->value_s = PL_strdup( pe[i].val );
+ tm_nvs[j]->value = decoded;
+ } else {
+ RA::Debug( LL_PER_PDU,
+ "AP_Session::create_pblock",
+ "tm_nvs[%d] is NULL",
+ j );
+ }
+ } // for
+
+ RA_pblock *ra_pb = new RA_pblock( tm_nargs, tm_nvs );
+
+ if( n_data != NULL ) {
+ PR_Free( n_data );
+ n_data = NULL;
+ }
+
+ if( ra_pb == NULL ) {
+ RA::Error( "AP_Session::create_pblock",
+ "RA_pblock is NULL" );
+ return NULL;
+ }
+
+ return ra_pb;
+}
+
+RA_Msg *AP_Session::ReadMsg()
+{
+ int len;
+ int msg_len = 0;
+ char msg[MAX_RA_MSG_SIZE];
+ char *msg_type = NULL;
+ int i_msg_type;
+ Buffer *msg_type_b = NULL;
+
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "========== ReadMsg Begins =======" );
+
+ msg_len = GetMsgLen( m_rq );
+
+ if( ( msg_len <= 0 ) || ( msg_len > MAX_RA_MSG_SIZE ) ) {
+ RA::Error( "AP_Session::ReadMsg",
+ "Message Size not in range. size =%d. Operation may have been cancelled.", msg_len );
+ return NULL;
+ }
+
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg", "msg_len=%d", msg_len );
+
+ len = GetMsg( m_rq, msg, msg_len );
+
+ if( len != msg_len ) {
+ RA::Error( "AP_Session::ReadMsg",
+ "Message Size Mismatch. Expected '%d' Received '%d'",
+ msg_len, len );
+ return NULL;
+ }
+
+ if(!contains_sensitive_keywords(msg)) {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Received len='%d' msg='%s'", len, msg );
+ } else {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Received len='%d' msg='<Password or new pin>'", len );
+ }
+
+ RA_Msg *ret_msg = NULL;
+
+ // format into array of name/value pair with value Buffer's
+ RA_pblock *ra_pb = ( RA_pblock * ) create_pblock( msg );
+
+ if( ra_pb == NULL ) {
+ goto loser;
+ }
+
+ // msg_type_b will be freed by destructor of RA_pblock
+ msg_type_b = ra_pb->find_val( PARAM_MSG_TYPE );
+ if( msg_type_b == NULL ) {
+ goto loser;
+ }
+
+ // msg_type should be freed when done using
+ msg_type = msg_type_b->string();
+
+ if( msg_type == NULL ) {
+ RA::Error( "AP_Session::ReadMsg",
+ "Parameter Not Found %s", PARAM_MSG_TYPE );
+ goto loser;
+ }
+
+ i_msg_type = atoi( msg_type );
+
+ switch( i_msg_type )
+ {
+ case MSG_BEGIN_OP: /* BEGIN_OP */
+ {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Found %s=%s (%s)", PARAM_MSG_TYPE,
+ "BEGIN_OP", msg_type );
+
+ Buffer *opB = ra_pb->find_val( PARAM_OPERATION );
+
+ if( opB == NULL ) {
+ goto loser;
+ }
+
+ RA::DebugBuffer( "AP_Session::ReadMsg", "content=", opB );
+
+ char *op_c = opB->string();
+
+ if( op_c == NULL ) {
+ goto loser;
+ }
+
+ int i_op = atoi( op_c );
+
+ if( op_c != NULL ) {
+ PR_Free( op_c );
+ op_c = NULL;
+ }
+
+ NameValueSet *exts = NULL;
+
+ Buffer *opE = ra_pb->find_val( PARAM_EXTENSIONS ); // optional
+
+ if( opE != NULL ) {
+ char *op_e = opE->string();
+ if( op_e == NULL ) {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "No extensions" );
+ } else {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Extensions %s", op_e );
+ exts = NameValueSet::Parse( op_e, "&" );
+ if( op_e != NULL ) {
+ PR_Free( op_e );
+ op_e = NULL;
+ }
+ }
+ }
+
+ switch( i_op )
+ {
+ case OP_ENROLL:
+ {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "begin_op_msg msg_type=ENROLL" );
+ ret_msg = new RA_Begin_Op_Msg( OP_ENROLL, exts );
+ break;
+ }
+ case OP_UNBLOCK:
+ {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "begin_op_msg msg_type=UNBLOCK" );
+ ret_msg = new RA_Begin_Op_Msg( OP_UNBLOCK, exts );
+ break;
+ }
+ case OP_RESET_PIN:
+ {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "begin_op_msg msg_type=RESET_PIN" );
+ ret_msg = new RA_Begin_Op_Msg( OP_RESET_PIN, exts );
+ break;
+ }
+ case OP_RENEW:
+ {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "begin_op_msg msg_type=RENEW" );
+ ret_msg = new RA_Begin_Op_Msg( OP_RENEW, exts );
+ break;
+ }
+ case OP_FORMAT:
+ {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "begin_op_msg msg_type=FORMAT" );
+ ret_msg = new RA_Begin_Op_Msg( OP_FORMAT, exts );
+ break;
+ }
+ default:
+ {
+ break;
+ /* error */
+ }
+ } // switch( i_op )
+
+ break;
+ }
+ case MSG_EXTENDED_LOGIN_RESPONSE: /* LOGIN_RESPONSE */
+ {
+ char *name = NULL;
+ Buffer* value = NULL;
+ char *bufferStr = NULL;
+ AuthParams *params = new AuthParams();
+ int i;
+
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Found %s=%s (%s)", PARAM_MSG_TYPE,
+ "EXTENDED_LOGIN_RESPONSE", msg_type );
+
+ i = ra_pb->get_num_of_names();
+
+ for( i = 0; i < ra_pb->get_num_of_names(); i++ ) {
+ name = ra_pb->get_name( i );
+ if( name != NULL ) {
+ value = ra_pb->find_val( ( const char * ) name );
+ bufferStr = value->string();
+ if( value != NULL ) {
+ params->Add( name, bufferStr );
+ }
+ if (bufferStr != NULL) {
+ PR_Free(bufferStr);
+ bufferStr = NULL;
+ }
+ }
+ }
+
+ ret_msg = new RA_Extended_Login_Response_Msg( params );
+
+ break;
+ }
+ case MSG_LOGIN_RESPONSE: /* LOGIN_RESPONSE */
+ {
+ char *uid = NULL, *password = NULL;
+ Buffer *uid_b, *pwd_b = NULL;
+
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Found %s=%s (%s)", PARAM_MSG_TYPE,
+ "LOGIN_RESPONSE", msg_type );
+
+ uid_b = ra_pb->find_val( PARAM_SCREEN_NAME );
+
+ if( uid_b == NULL ) {
+ goto aloser;
+ }
+
+ uid = uid_b->string();
+
+ if( uid == NULL ) {
+ goto aloser;
+ }
+
+ pwd_b = ra_pb->find_val( PARAM_PASSWORD );
+
+ if( pwd_b == NULL ) {
+ goto aloser;
+ }
+
+ password = pwd_b->string();
+
+ if( password == NULL ) {
+ goto aloser;
+ }
+
+ ret_msg = new RA_Login_Response_Msg( uid, password );
+
+ aloser:
+ if( uid != NULL ) {
+ PR_Free( uid );
+ uid = NULL;
+ }
+
+ if( password != NULL ) {
+ PR_Free( password );
+ password = NULL;
+ }
+
+ goto loser;
+
+ break;
+ }
+ case MSG_STATUS_UPDATE_RESPONSE: /* SECUREID_RESPONSE */
+ {
+ char *value = NULL;
+ Buffer *value_b;
+
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Found %s=%s (%s)", PARAM_MSG_TYPE,
+ "STATUS_UPDATE_RESPONSE", msg_type );
+
+ value_b = ra_pb->find_val( PARAM_STATUS );
+
+ if( value_b == NULL ) {
+ goto zloser;
+ }
+
+ value = value_b->string();
+
+ if( value == NULL ) {
+ goto zloser;
+ }
+
+ ret_msg = new RA_Status_Update_Response_Msg( atoi( value ) );
+
+ zloser:
+ if( value != NULL ) {
+ PR_Free( value );
+ value = NULL;
+ }
+
+ goto loser;
+
+ break;
+ }
+ case MSG_SECUREID_RESPONSE: /* SECUREID_RESPONSE */
+ {
+ char *value = NULL, *pin = NULL;
+ Buffer *value_b = NULL, *pin_b = NULL;
+
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Found %s=%s (%s)", PARAM_MSG_TYPE,
+ "SECUREID_RESPONSE", msg_type );
+
+ value_b = ra_pb->find_val( PARAM_VALUE );
+
+ if( value_b == NULL ) {
+ goto bloser;
+ }
+
+ value = value_b->string();
+
+ if( value == NULL ) {
+ goto bloser;
+ }
+
+ pin_b = ra_pb->find_val( PARAM_PIN );
+
+ if( pin_b == NULL ) {
+ goto bloser;
+ }
+
+ pin = pin_b->string();
+
+ if( pin == NULL ) {
+ pin_b->zeroize();
+ goto bloser;
+ }
+
+ ret_msg = new RA_SecureId_Response_Msg( value, pin );
+
+ if( pin != NULL ) {
+ // zeroize memory before releasing
+ unsigned int i = 0;
+ for( i = 0; i < strlen( pin ); i++ ) {
+ pin[i] = '\0';
+ }
+ if( pin != NULL ) {
+ PR_Free( pin );
+ pin = NULL;
+ }
+ }
+
+ pin_b->zeroize();
+
+ bloser:
+ if( value != NULL ) {
+ PR_Free( value );
+ value = NULL;
+ }
+
+ if( pin != NULL ) {
+ PR_Free( pin );
+ pin = NULL;
+ }
+
+ goto loser;
+
+ break;
+ }
+ case MSG_ASQ_RESPONSE: /* ASQ_RESPONSE */
+ {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Found %s=%s (%s)", PARAM_MSG_TYPE,
+ "ASQ_RESPONSE", msg_type );
+
+ Buffer *ans_b = ra_pb->find_val( PARAM_ANSWER );
+
+ if( ans_b == NULL ) {
+ goto loser;
+ }
+
+ char *answer = ans_b->string();
+
+ if( answer == NULL ) {
+ goto loser;
+ }
+
+ ret_msg = new RA_ASQ_Response_Msg( answer );
+
+ if( answer != NULL ) {
+ PR_Free( answer );
+ answer = NULL;
+ }
+
+ break;
+ }
+ case MSG_TOKEN_PDU_RESPONSE: /* TOKEN_PDU_RESPONSE */
+ {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Found %s=%s (%s)", PARAM_MSG_TYPE,
+ "TOKEN_PDU_RESPONSE", msg_type );
+
+ unsigned int pdu_size =0;
+
+ Buffer *pdu_size_b = ra_pb->find_val( PARAM_PDU_SIZE );
+
+ if( pdu_size_b == NULL ) {
+ goto loser;
+ }
+
+ char *p = pdu_size_b->string();
+
+ pdu_size = atoi( p );
+
+ if( p != NULL ) {
+ PR_Free( p );
+ p = NULL;
+ }
+
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Found %s=%d", PARAM_PDU_SIZE, pdu_size );
+
+ if( pdu_size > 261 ) {
+ RA::Error( LL_PER_PDU, "AP_Session::ReadMsg",
+ "%s exceeds limit", PARAM_PDU_SIZE );
+ goto loser;
+ }
+
+ Buffer *decoded_pdu = ra_pb->find_val( PARAM_PDU_DATA );
+
+ if( decoded_pdu == NULL ) {
+ goto loser;
+ }
+
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "decoded_pdu size= %d", decoded_pdu->size() );
+
+ if( pdu_size != decoded_pdu->size() ) {
+ goto loser;
+ }
+
+ RA::DebugBuffer( "AP_Session::ReadMsg",
+ "decoded pdu = ", decoded_pdu );
+
+ APDU_Response *response = new APDU_Response( *decoded_pdu );
+
+ ret_msg = new RA_Token_PDU_Response_Msg( response );
+
+ break;
+ }
+ case MSG_NEW_PIN_RESPONSE: /* NEW_PIN_RESPONSE */
+ {
+ char *new_pin = NULL;
+ Buffer *new_pin_b = NULL;
+
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Found %s=%s (%s)", PARAM_MSG_TYPE,
+ "NEW_PIN_RESPONSE", msg_type );
+
+ new_pin_b = ra_pb->find_val( PARAM_NEW_PIN );
+
+ if( new_pin_b == NULL ) {
+ goto loser;
+ }
+
+ new_pin = new_pin_b->string();
+
+ if( new_pin == NULL ) {
+ new_pin_b->zeroize();
+ goto loser;
+ }
+
+ ret_msg = new RA_New_Pin_Response_Msg( new_pin );
+
+ if( new_pin != NULL ) {
+ // zeroize memory before releasing
+ unsigned int i = 0;
+
+ for( i = 0; i< strlen( new_pin ); i++ ) {
+ new_pin[i] = '\0';
+ }
+
+ if( new_pin != NULL ) {
+ PR_Free( new_pin );
+ new_pin = NULL;
+ }
+ }
+
+ new_pin_b->zeroize();
+
+ break;
+ }
+ default:
+ {
+ RA::Error( "AP_Session::ReadMsg", "Found %s=%s",
+ PARAM_MSG_TYPE, "UNDEFINED" );
+ /* error */
+ break;
+ }
+ } // switch( i_msg_type )
+
+loser:
+ if( msg_type != NULL ) {
+ PR_Free( msg_type );
+ msg_type = NULL;
+ }
+
+ if( ra_pb != NULL ) {
+ delete ra_pb;
+ ra_pb = NULL;
+ }
+
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "========= ReadMsg Ends =========" );
+
+ return ret_msg;
+}
+
+static void CreateChunk( char *msgbuf, char *buf, int buflen )
+{
+ int len;
+
+ len = strlen( msgbuf );
+ sprintf( buf, "s=%d&%s", len, msgbuf );
+}
+
+void AP_Session::WriteMsg( RA_Msg *msg )
+{
+ char msgbuf[MAX_RA_MSG_SIZE];
+ char buf[MAX_RA_MSG_SIZE];
+
+ switch( msg->GetType() )
+ {
+ case MSG_EXTENDED_LOGIN_REQUEST:
+ {
+ RA_Extended_Login_Request_Msg *login_request_msg =
+ ( RA_Extended_Login_Request_Msg * ) msg;
+ int invalid_password = login_request_msg->IsInvalidPassword();
+ int is_blocked = login_request_msg->IsBlocked();
+
+ char *title = Util::URLEncode( login_request_msg->GetTitle() );
+ char *desc = Util::URLEncode( login_request_msg->GetDescription() );
+
+ sprintf( msgbuf, "%s=%d&%s=%d&%s=%d&%s=%s&%s=%s",
+ PARAM_MSG_TYPE, MSG_EXTENDED_LOGIN_REQUEST,
+ "invalid_login", invalid_password,
+ PARAM_BLOCKED, is_blocked,
+ "title", title,
+ "description", desc);
+ if (title != NULL) {
+ PR_Free(title);
+ title = NULL;
+ }
+
+ if (desc != NULL) {
+ PR_Free(desc);
+ desc = NULL;
+ }
+
+ for( int i = 0; i < login_request_msg->GetLen(); i++ ) {
+ char *p = login_request_msg->GetParam( i );
+ char *encp = Util::URLEncode1( p );
+ sprintf( msgbuf, "%s&required_parameter%d=%s",
+ msgbuf, i, encp );
+ if (encp != NULL) {
+ PR_Free(encp);
+ encp = NULL;
+ }
+ }
+
+ CreateChunk( msgbuf, buf, MAX_RA_MSG_SIZE );
+
+ RA::Debug( "AP_Session::WriteMsg", "Sent '%s'", buf );
+
+ ( void ) ap_rwrite( ( const void * ) buf, strlen( buf ), m_rq );
+ break;
+ }
+ case MSG_LOGIN_REQUEST:
+ {
+ RA_Login_Request_Msg *login_request_msg =
+ ( RA_Login_Request_Msg * ) msg;
+ int invalid_password = login_request_msg->IsInvalidPassword();
+ int is_blocked = login_request_msg->IsBlocked();
+
+ sprintf( msgbuf, "%s=%d&%s=%d&%s=%d",
+ PARAM_MSG_TYPE, MSG_LOGIN_REQUEST,
+ PARAM_INVALID_PW, invalid_password,
+ PARAM_BLOCKED, is_blocked );
+
+ CreateChunk( msgbuf, buf, MAX_RA_MSG_SIZE );
+
+ RA::Debug( "AP_Session::WriteMsg", "Sent '%s'", buf );
+
+ ( void ) ap_rwrite( ( const void * ) buf, strlen( buf ), m_rq );
+
+ break;
+ }
+ case MSG_END_OP:
+ {
+ RA_End_Op_Msg *end_op = ( RA_End_Op_Msg * ) msg;
+ int result = end_op->GetResult();
+ int local_msg = end_op->GetMsg();
+ int op = end_op->GetOpType();
+
+ sprintf( msgbuf, "%s=%d&%s=%d&%s=%d&%s=%d\r\n0\r\n",
+ PARAM_MSG_TYPE, MSG_END_OP,
+ PARAM_OPERATION, op,
+ PARAM_RESULT, result,
+ PARAM_MESSAGE, local_msg );
+
+ CreateChunk( msgbuf, buf, MAX_RA_MSG_SIZE );
+
+ RA::Debug( "AP_Session::WriteMsg", "Sent '%s'", buf );
+
+ ( void ) ap_rwrite( ( const void * ) buf, strlen( buf ), m_rq );
+
+ break;
+ }
+ case MSG_STATUS_UPDATE_REQUEST:
+ {
+ RA_Status_Update_Request_Msg *status_update_request_msg =
+ ( RA_Status_Update_Request_Msg * ) msg;
+ int status = status_update_request_msg->GetStatus();
+ char *info = status_update_request_msg->GetInfo();
+
+ sprintf( msgbuf, "%s=%d&%s=%d&%s=%s",
+ PARAM_MSG_TYPE, MSG_STATUS_UPDATE_REQUEST,
+ PARAM_STATUS, status,
+ PARAM_INFO, info );
+
+ CreateChunk( msgbuf, buf, MAX_RA_MSG_SIZE );
+
+ RA::Debug( "AP_Session::WriteMsg", "Sent '%s'", buf );
+
+ ( void ) ap_rwrite( ( const void * ) buf, strlen( buf ), m_rq );
+
+ break;
+ }
+ case MSG_SECUREID_REQUEST:
+ {
+ RA_SecureId_Request_Msg *secureid_request_msg =
+ ( RA_SecureId_Request_Msg * ) msg;
+ int is_pin_required = secureid_request_msg->IsPinRequired();
+ int is_next_value = secureid_request_msg->IsNextValue();
+
+ sprintf( msgbuf, "%s=%d&%s=%d&%s=%d",
+ PARAM_MSG_TYPE, MSG_SECUREID_REQUEST,
+ PARAM_PIN_REQUIRED, is_pin_required,
+ PARAM_NEXT_VALUE, is_next_value );
+
+ CreateChunk( msgbuf, buf, MAX_RA_MSG_SIZE );
+
+ RA::Debug( "AP_Session::WriteMsg", "Sent '%s'", buf );
+
+ ( void ) ap_rwrite( ( const void * ) buf, strlen( buf ), m_rq );
+
+ break;
+ }
+ case MSG_ASQ_REQUEST:
+ {
+ RA_ASQ_Request_Msg *asq_request_msg = ( RA_ASQ_Request_Msg * ) msg;
+ char *question = asq_request_msg->GetQuestion();
+
+ sprintf( msgbuf, "%s=%d&%s=%s",
+ PARAM_MSG_TYPE, MSG_ASQ_REQUEST,
+ PARAM_QUESTION, question );
+
+ CreateChunk( msgbuf, buf, MAX_RA_MSG_SIZE );
+
+ RA::Debug( "AP_Session::WriteMsg", "Sent '%s'", buf );
+
+ ( void ) ap_rwrite( ( const void * ) buf, strlen( buf ), m_rq );
+
+ break;
+ }
+ case MSG_NEW_PIN_REQUEST:
+ {
+ RA_New_Pin_Request_Msg *new_pin_request_msg =
+ ( RA_New_Pin_Request_Msg * ) msg;
+ int min = new_pin_request_msg->GetMinLen();
+ int max = new_pin_request_msg->GetMaxLen();
+
+ sprintf( msgbuf, "%s=%d&%s=%d&%s=%d",
+ PARAM_MSG_TYPE, MSG_NEW_PIN_REQUEST,
+ PARAM_MINIMUM_LENGTH, min,
+ PARAM_MAXIMUM_LENGTH, max );
+
+ CreateChunk( msgbuf, buf, MAX_RA_MSG_SIZE );
+
+ RA::Debug( "AP_Session::WriteMsg", "Sent '%s'", buf );
+
+ ( void ) ap_rwrite( ( const void * ) buf, strlen( buf ), m_rq );
+
+ break;
+ }
+ case MSG_TOKEN_PDU_REQUEST:
+ {
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg =
+ ( RA_Token_PDU_Request_Msg * ) msg;
+ APDU *apdu = token_pdu_request_msg->GetAPDU();
+ Buffer encoding;
+
+ apdu->GetEncoding( encoding );
+
+ int pdu_len = encoding.size();
+
+ RA::Debug( LL_PER_CONNECTION, "AP_Session::WriteMsg",
+ "pdu_len='%d'", pdu_len );
+
+ Buffer pdu = encoding;
+ char *pdu_encoded = NULL;
+
+ if( RA::GetConfigStore()->GetConfigAsBool( "pdu_encoding.hex_mode",
+ 1 ) ) {
+ // pdu will be encoded in Hex mode which is easier to read
+ pdu_encoded = Util::URLEncodeInHex( pdu );
+ } else {
+ pdu_encoded = Util::URLEncode( pdu );
+ }
+
+ sprintf( msgbuf, "%s=%d&%s=%d&%s=%s",
+ PARAM_MSG_TYPE, MSG_TOKEN_PDU_REQUEST,
+ PARAM_PDU_SIZE, pdu_len,
+ PARAM_PDU_DATA, pdu_encoded );
+
+ CreateChunk( msgbuf, buf, MAX_RA_MSG_SIZE );
+
+ if( pdu_encoded != NULL ) {
+ PR_Free( pdu_encoded );
+ pdu_encoded = NULL;
+ }
+
+ RA::Debug( "AP_Session::WriteMsg", "Sent '%s'", buf );
+
+ ( void ) ap_rwrite( ( const void * ) buf, strlen( buf ), m_rq );
+
+ break;
+ }
+ default:
+ {
+ break;
+ /* error */
+ }
+ } // switch( msg->GetType() )
+
+ ap_rflush(m_rq);
+
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/base/tps/src/modules/tps/CMakeLists.txt b/base/tps/src/modules/tps/CMakeLists.txt
new file mode 100644
index 000000000..275d8b30a
--- /dev/null
+++ b/base/tps/src/modules/tps/CMakeLists.txt
@@ -0,0 +1,52 @@
+project(tps_module CXX)
+
+set(TPS_PRIVATE_INCLUDE_DIRS
+ ${TPS_INCLUDE_DIR}
+ ${CMAKE_BINARY_DIR}
+ ${NSPR_INCLUDE_DIRS}
+ ${NSS_INCLUDE_DIRS}
+ ${APR_INCLUDE_DIRS}
+ ${SVRCORE_INCLUDE_DIRS}
+ ${LDAP_INCLUDE_DIRS}
+)
+
+set(TPS_MODULE
+ tps_module
+ CACHE INTERNAL "tps apache module"
+)
+
+set(TPS_LINK_LIBRARIES
+ ${TPS_SHARED_LIBRARY}
+ ${NSPR_LIBRARIES}
+ ${NSS_LIBRARIES}
+ ${APR_LIBRARIES}
+ ${SVRCORE_LIBRARIES}
+ ${LDAP_LIBRARIES}
+ ${TOKENDB_SHARED_LIBRARY}
+ ${TPS_SHARED_LIBRARY}
+)
+
+set(tps_module_SRCS
+ AP_Context.cpp
+ AP_Session.cpp
+ mod_tps.cpp
+)
+
+include_directories(${TPS_PRIVATE_INCLUDE_DIRS})
+
+add_library(${TPS_MODULE} MODULE ${tps_module_SRCS})
+target_link_libraries(${TPS_MODULE} ${TPS_LINK_LIBRARIES})
+
+set_target_properties(${TPS_MODULE}
+ PROPERTIES
+ OUTPUT_NAME
+ mod_tps
+ PREFIX ""
+)
+
+install(
+ TARGETS
+ ${TPS_MODULE}
+ DESTINATION
+ ${LIB_INSTALL_DIR}/httpd/modules
+)
diff --git a/base/tps/src/modules/tps/mod_tps.cpp b/base/tps/src/modules/tps/mod_tps.cpp
new file mode 100644
index 000000000..dc6cc95f9
--- /dev/null
+++ b/base/tps/src/modules/tps/mod_tps.cpp
@@ -0,0 +1,732 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+
+
+/* _________________________________________________________________
+**
+** TPS Module Headers
+** _________________________________________________________________
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include "nspr.h"
+
+#include "httpd/httpd.h"
+#include "httpd/http_config.h"
+#include "httpd/http_log.h"
+#include "httpd/http_protocol.h"
+#include "httpd/http_main.h"
+
+#include "apr_strings.h"
+
+#include "engine/RA.h"
+#include "main/Memory.h"
+#include "main/RA_Msg.h"
+#include "main/RA_Session.h"
+#include "modules/tps/AP_Context.h"
+#include "modules/tps/AP_Session.h"
+#include "msg/RA_Begin_Op_Msg.h"
+#include "msg/RA_End_Op_Msg.h"
+#include "processor/RA_Enroll_Processor.h"
+#include "processor/RA_Format_Processor.h"
+#include "processor/RA_Pin_Reset_Processor.h"
+#include "processor/RA_Renew_Processor.h"
+#include "processor/RA_Unblock_Processor.h"
+#include "ssl.h"
+
+#define MOD_TPS_KEY_NAME "mod_tps"
+
+/* _________________________________________________________________
+**
+** TPS Module Request Data
+** _________________________________________________________________
+*/
+
+/**
+ * Processors for different operations.
+ */
+static RA_Enroll_Processor m_enroll_processor;
+static RA_Unblock_Processor m_unblock_processor;
+static RA_Pin_Reset_Processor m_pin_reset_processor;
+static RA_Renew_Processor m_renew_processor;
+static RA_Format_Processor m_format_processor;
+
+
+/* _________________________________________________________________
+**
+** TPS Module Command Data
+** _________________________________________________________________
+*/
+
+static const char MOD_TPS_CONFIGURATION_FILE_PARAMETER[] = "TPSConfigPathFile";
+
+static const char MOD_TPS_CONFIGURATION_FILE_USAGE[] =
+"TPS Configuration Filename prefixed by a complete path, or\n"
+"a path that is relative to the Apache server root.";
+
+/* per-process config structure */
+typedef struct {
+ int nInitCount;
+ int nSignedAuditInitCount;
+} mod_tps_global_config;
+
+
+/* _________________________________________________________________
+**
+** TPS Module Server Configuration Creation Data
+** _________________________________________________________________
+*/
+
+typedef struct {
+ char *TPS_Configuration_File;
+ AP_Context *context;
+ mod_tps_global_config *gconfig; /* pointer to per-process config */
+} mod_tps_server_configuration;
+
+
+
+/* _________________________________________________________________
+**
+** TPS Module Registration Data
+** _________________________________________________________________
+*/
+
+#define MOD_TPS_CONFIG_KEY tps_module
+
+static const char MOD_TPS_CONFIG_KEY_NAME[] = "tps_module";
+
+extern module TPS_PUBLIC MOD_TPS_CONFIG_KEY;
+
+
+
+/* _________________________________________________________________
+**
+** TPS Module Helper Functions
+** _________________________________________________________________
+*/
+
+mod_tps_global_config *mod_tps_config_global_create(server_rec *s)
+{
+ apr_pool_t *pool = s->process->pool;
+ mod_tps_global_config *globalc = NULL;
+ void *vglobalc = NULL;
+
+ apr_pool_userdata_get(&vglobalc, MOD_TPS_KEY_NAME, pool);
+ if (vglobalc) {
+ return (mod_tps_global_config *) vglobalc; /* reused for lifetime of the server */
+ }
+
+ /*
+ * allocate an own subpool which survives server restarts
+ */
+ globalc = (mod_tps_global_config *)apr_palloc(pool, sizeof(*globalc));
+
+ /*
+ * initialize per-module configuration
+ */
+ globalc->nInitCount = 0;
+ globalc->nSignedAuditInitCount = 0;
+
+ apr_pool_userdata_set(globalc, MOD_TPS_KEY_NAME,
+ apr_pool_cleanup_null,
+ pool);
+
+ return globalc;
+}
+
+/**
+ * Terminate Apache
+ */
+void tps_die( void )
+{
+ /*
+ * This is used for fatal errors and here
+ * it is common module practice to really
+ * exit from the complete program.
+ */
+ exit( 1 );
+}
+
+
+/**
+ * Creates an RA_Session from the RA framework.
+ *
+ * Centralize the allocation of the session object here so that
+ * we can provide our own session management here in the future.
+ */
+static RA_Session *
+mod_tps_create_session( request_rec *rq )
+{
+ return new AP_Session( rq );
+} /* mod_tps_create_session */
+
+
+/**
+ * Returns RA_Session to the RA framework.
+ */
+static void
+mod_tps_destroy_session( RA_Session *session )
+{
+ if( session != NULL ) {
+ delete session;
+ session = NULL;
+ }
+} /* mod_tps_destroy_session */
+
+
+
+/* _________________________________________________________________
+**
+** TPS Module Request Phase
+** _________________________________________________________________
+*/
+
+/**
+ * Terminate the TPS module
+ */
+static apr_status_t
+mod_tps_terminate( void *data )
+{
+ /* This routine is ONLY called when this server's */
+ /* pool has been cleared or destroyed. */
+
+ /* Log TPS module debug information. */
+ RA::Debug( "mod_tps::mod_tps_terminate",
+ "The TPS module has been terminated!" );
+
+ /* Free TPS resources. */
+ RA::Shutdown();
+
+ /* Since all members of mod_tps_server_configuration are allocated */
+ /* from a pool, there is no need to unset any of these members. */
+
+#ifdef MEM_PROFILING
+ /* If memory profiling is enabled, turn off memory profiling. */
+ MEM_shutdown();
+#endif
+
+ SSL_ClearSessionCache();
+ /* Shutdown all APR library routines. */
+ /* NOTE: This automatically destroys all memory pools. */
+ /* Allow the NSS Module to perform this task. */
+ /* apr_terminate(); */
+
+
+ /* Terminate the entire Apache server */
+ /* NOTE: Allow the NSS Module to perform this task. */
+ /* tps_die(); */
+
+ return OK;
+}
+
+static apr_status_t
+mod_tps_child_terminate (void *data)
+{
+ RA::Debug("mod_tps::mod_tps_child_terminate",
+ "The TPS module has been terminated!" );
+
+ /* Free TPS resources. */
+ RA::Child_Shutdown();
+
+ return OK;
+}
+
+static int
+mod_tps_initialize( apr_pool_t *p,
+ apr_pool_t *plog,
+ apr_pool_t *ptemp,
+ server_rec *sv )
+{
+ mod_tps_server_configuration *sc = NULL;
+ char *cfg_path_file = NULL;
+ int status;
+
+ /* Retrieve the TPS module. */
+ sc = ( ( mod_tps_server_configuration * )
+ ap_get_module_config( sv->module_config,
+ &MOD_TPS_CONFIG_KEY ) );
+
+ /* Check to see if the TPS module has been loaded. */
+ if( sc->context != NULL ) {
+ return OK;
+ }
+
+ sc->gconfig->nInitCount++;
+
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, sv,
+ "Entering mod_tps_initialize - init count is [%d]",
+ sc->gconfig->nInitCount);
+
+ /* Load the TPS module. */
+
+#ifdef MEM_PROFILING
+ /* If memory profiling is enabled, turn on memory profiling. */
+ MEM_init( MEM_AUDIT_FILE, MEM_DUMP_FILE );
+#endif
+
+ /* Retrieve the path to where the configuration files are located, */
+ /* and insure that the TPS module configuration file is located here. */
+ if( sc->TPS_Configuration_File != NULL ) {
+ /* provide TPS Config File from <apache_server_root>/conf/httpd.conf */
+ if( sc->TPS_Configuration_File[0] == '/' ) {
+ /* Complete path to TPS Config File is denoted */
+ cfg_path_file = apr_psprintf( p,
+ "%s",
+ ( char * )
+ sc->TPS_Configuration_File );
+ } else {
+ /* TPS Config File is located relative to the Apache server root */
+ cfg_path_file = apr_psprintf( p,
+ "%s/%s",
+ ( char * ) ap_server_root,
+ ( char * )
+ sc->TPS_Configuration_File );
+ }
+ } else {
+ /* Log information regarding this failure. */
+ ap_log_error( "mod_tps_initialize",
+ __LINE__, APLOG_ERR, 0, sv,
+ "The tps module was installed incorrectly since the "
+ "parameter named '%s' is missing from the Apache "
+ "Configuration file!",
+ ( char * ) MOD_TPS_CONFIGURATION_FILE_PARAMETER );
+
+ /* Display information on the screen regarding this failure. */
+ printf( "\nUnable to start Apache:\n"
+ " The tps module is missing the required parameter named\n"
+ " '%s' in the Apache Configuration file!\n",
+ ( char * ) MOD_TPS_CONFIGURATION_FILE_PARAMETER );
+
+ goto loser;
+ }
+
+ /* Initialize the "server" member of mod_tps_server_configuration. */
+ sc->context = new AP_Context( sv );
+
+ status = RA::Initialize( cfg_path_file, sc->context );
+ if( status != RA_INITIALIZATION_SUCCESS ) {
+ /* Log information regarding this failure. */
+ ap_log_error( "mod_tps_initialize",
+ __LINE__, APLOG_ERR, 0, sv,
+ "The tps module was installed incorrectly "
+ "since the file named '%s' does not exist!",
+ cfg_path_file );
+
+ /* Display information on the screen regarding this failure. */
+ printf( "\nUnable to start Apache:\n"
+ " The tps module configuration file called\n"
+ " '%s' does not exist!\n",
+ cfg_path_file );
+
+ /* Since all members of mod_tps_server_configuration are allocated */
+ /* from a pool, there is no need to unset any of these members. */
+
+ goto loser;
+ }
+
+ if (sc->gconfig->nInitCount < 2 ) {
+ sc->gconfig->nSignedAuditInitCount++;
+ status = RA::InitializeInChild( sc->context,
+ sc->gconfig->nSignedAuditInitCount);
+ } else {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, sv,
+ "mod_tps_initialize - pid is [%d] - post config already done once -"
+ " additional config will be done in init_child",
+ getpid());
+ status = RA_INITIALIZATION_SUCCESS;
+ }
+
+ if (status != RA_INITIALIZATION_SUCCESS ) {
+ ap_log_error( "mod_tps_initialize",
+ __LINE__, APLOG_ERR, 0, sv,
+ "The tps module failed to do the initializeInChild tasks. ");
+ printf( "\nUnable to start Apache:\n"
+ " The tps module failed to do the initializeInChild tasks. ");
+ goto loser;
+ }
+
+ /* Register a server termination routine. */
+ apr_pool_cleanup_register( p,
+ sv,
+ mod_tps_terminate,
+ apr_pool_cleanup_null );
+
+ /* Log TPS module debug information. */
+ RA::Debug( "mod_tps::mod_tps_initialize",
+ "The TPS module has been successfully loaded!" );
+
+ return OK;
+
+loser:
+ /* Log TPS module debug information. */
+ RA::Debug( "mod_tps::mod_tps_initialize",
+ "Failed loading the TPS module!" );
+
+ if( sc->context != NULL ) {
+ /* Free TPS resources. */
+ RA::Shutdown();
+
+ /* Since all members of mod_tps_server_configuration are allocated */
+ /* from a pool, there is no need to unset any of these members. */
+ }
+
+#ifdef MEM_PROFILING
+ /* If memory profiling is enabled, turn off memory profiling. */
+ MEM_shutdown();
+#endif
+
+ /* Shutdown all APR library routines. */
+ /* NOTE: This automatically destroys all memory pools. */
+ apr_terminate();
+
+ /* Terminate the entire Apache server */
+ tps_die();
+
+ return DECLINED;
+}
+
+/**
+ * mod_tps_handler handles the protocol between the token client
+ * and the RA (Session)
+ */
+static int
+mod_tps_handler( request_rec *rq )
+{
+ char buf[1024];
+ int ret_code = DECLINED;
+ int status = DECLINED;
+ RA_Session *session = NULL;
+ RA_Begin_Op_Msg *begin_op_msg = NULL;
+ NameValueSet *extensions = NULL;
+ const char *tenc = apr_table_get(rq->headers_in, "Transfer-Encoding");
+
+ /* Log TPS module debug information. */
+ RA::Debug( "mod_tps::mod_tps_handler",
+ "mod_tps::mod_tps_handler" );
+
+ RA::Debug( "mod_tps::mod_tps_handler",
+ "uri '%s'", rq->uri);
+
+ /* XXX: We need to change "nk_service" to "tps",
+ and need to update ESC. */
+ if (strcmp(rq->handler,"nk_service") != 0) {
+ RA::Debug( "mod_tps::mod_tps_handler",
+ "DECLINED uri '%s'", rq->uri);
+ return DECLINED;
+ }
+
+ RA::Debug( "mod_tps::mod_tps_handler",
+ "uri '%s' DONE", rq->uri);
+
+ /*
+ * check to see if the http request contains
+ * "transfer-encoding: chunked"
+ */
+ /* XXX: rq->chunked not set to true even in the chunked mode */
+ if(!tenc || PL_strcasecmp(tenc, "chunked") != 0) {
+ /* print the following when browser accesses directly */
+ strcpy( buf, "<HTML>Registration Authority</HTML>" );
+
+ /* write out the data */
+ ( void ) ap_rwrite( ( const void * ) buf, strlen( buf ), rq );
+
+ ret_code = OK;
+
+ return ret_code;
+ }
+
+ /* request contains chunked encoding */
+ session = mod_tps_create_session( rq );
+
+ /* read in the data present on the connection */
+ begin_op_msg = ( RA_Begin_Op_Msg * ) session->ReadMsg();
+ if( begin_op_msg == NULL ) {
+ /* Log TPS module error information. */
+ RA::Error( "mod_tps::mod_tps_handler",
+ "no begin op found" );
+ goto loser;
+ }
+
+ /* retrieve the extensions */
+ extensions = begin_op_msg->GetExtensions();
+
+ /* perform the appropriate processing based upon the type of operation */
+ if( begin_op_msg->GetOpType() == OP_ENROLL ) {
+ status = m_enroll_processor.Process( session, extensions );
+ } else if( begin_op_msg->GetOpType() == OP_UNBLOCK ) {
+ status = m_unblock_processor.Process( session, extensions );
+ } else if( begin_op_msg->GetOpType() == OP_RESET_PIN ) {
+ status = m_pin_reset_processor.Process( session, extensions );
+ } else if( begin_op_msg->GetOpType() == OP_RENEW ) {
+ status = m_renew_processor.Process( session, extensions );
+ } else if( begin_op_msg->GetOpType() == OP_FORMAT ) {
+ status = m_format_processor.Process( session, extensions );
+ } else {
+ /* Log TPS module error information. */
+ RA::Error( "mod_tps::mod_tps_handler",
+ "unknown operation requested (op='%d')",
+ begin_op_msg->GetOpType() );
+ goto loser;
+ } /* if */
+
+ ret_code = OK;
+
+loser:
+ /* determine the results of the operation and report it */
+ if( begin_op_msg != NULL ) {
+ int result;
+
+ if( status == 0 ) {
+ result = RESULT_GOOD;
+ } else {
+ result = RESULT_ERROR;
+ }
+
+ RA_End_Op_Msg *end_op = new RA_End_Op_Msg( begin_op_msg->GetOpType(),
+ result,
+ status );
+
+ session->WriteMsg( end_op );
+
+ if( end_op != NULL ) {
+ delete end_op;
+ end_op = NULL;
+ }
+ }
+
+ /* remove any operational messages */
+ if( begin_op_msg != NULL ) {
+ delete begin_op_msg;
+ begin_op_msg = NULL;
+ }
+
+ /* remove any sessions */
+ if( session != NULL ) {
+ mod_tps_destroy_session( session );
+ session = NULL;
+ }
+
+ return ret_code;
+} /* mod_tps_handler */
+
+
+
+/* _________________________________________________________________
+**
+** TPS Module Command Phase
+** _________________________________________________________________
+*/
+
+static const char *mod_tps_get_config_path_file( cmd_parms *cmd,
+ void *mconfig,
+ const char *tpsconf )
+{
+ if( cmd->path ) {
+ ap_log_error( APLOG_MARK, APLOG_ERR, 0, NULL,
+ "The %s config param cannot be specified "
+ "in a Directory section.",
+ cmd->directive->directive );
+ } else {
+ mod_tps_server_configuration *sc = NULL;
+
+ /* Retrieve the TPS module. */
+ sc = ( ( mod_tps_server_configuration * )
+ ap_get_module_config( cmd->server->module_config,
+ &MOD_TPS_CONFIG_KEY ) );
+
+ /* Initialize the "TPS Configuration File" */
+ /* member of mod_tps_server_configuration. */
+ sc->TPS_Configuration_File = apr_pstrdup( cmd->pool, tpsconf );
+ }
+
+ return NULL;
+}
+
+
+static const command_rec mod_tps_config_cmds[] = {
+ AP_INIT_TAKE1( MOD_TPS_CONFIGURATION_FILE_PARAMETER,
+ ( const char*(*)() ) mod_tps_get_config_path_file,
+ NULL,
+ RSRC_CONF,
+ MOD_TPS_CONFIGURATION_FILE_USAGE ),
+ { NULL }
+};
+
+
+
+/* _________________________________________________________________
+**
+** TPS Module Server Configuration Creation Phase
+** _________________________________________________________________
+*/
+
+/**
+ * Create TPS module server configuration
+ */
+static void *
+mod_tps_config_server_create( apr_pool_t *p, server_rec *sv )
+{
+ /* Initialize all APR library routines. */
+ apr_initialize();
+
+ /* Create a memory pool for this server. */
+ mod_tps_server_configuration *sc = ( mod_tps_server_configuration * )
+ apr_pcalloc( p,
+ ( apr_size_t )
+ sizeof( *sc ) );
+
+ /* Initialize all members of mod_tps_server_configuration. */
+ sc->TPS_Configuration_File = NULL;
+ sc->context = NULL;
+ sc->gconfig = mod_tps_config_global_create(sv);
+
+ return sc;
+}
+
+static void mod_tps_init_child(apr_pool_t *p, server_rec *sv)
+{
+ int status = -1;
+ mod_tps_server_configuration *srv_cfg = NULL;
+ srv_cfg = ( ( mod_tps_server_configuration * )
+ ap_get_module_config(sv->module_config, &MOD_TPS_CONFIG_KEY));
+
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0 /* status */, NULL,
+ "Entering mod_tps_init_child pid [%d] init count is [%d]",
+ getpid(), srv_cfg->gconfig->nInitCount);
+
+ srv_cfg = ( ( mod_tps_server_configuration * )
+ ap_get_module_config(sv->module_config, &MOD_TPS_CONFIG_KEY));
+
+ if (srv_cfg->gconfig->nInitCount > 1) {
+ srv_cfg->gconfig->nSignedAuditInitCount++;
+ status = RA::InitializeInChild(srv_cfg->context,
+ srv_cfg->gconfig->nSignedAuditInitCount);
+
+
+ if (status != RA_INITIALIZATION_SUCCESS) {
+ /* Need to shut down, the child was not initialized properly. */
+ ap_log_error( "mod_tps_init_child",
+ __LINE__, APLOG_ERR, 0, sv,
+ "The tps module failed to do the initializeInChild tasks. ");
+ printf( "\nUnable to start Apache:\n"
+ " The tps module failed to do the initializeInChild tasks. ");
+ goto loser;
+ }
+
+ /* Register a server termination routine. */
+ apr_pool_cleanup_register( p,
+ sv,
+ mod_tps_child_terminate,
+ apr_pool_cleanup_null );
+ } else {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, sv,
+ "mod_tps_init_child - pid is [%d] - config should be done in regular post config",
+ getpid());
+ }
+
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0 /* status */, NULL,
+ "Leaving mod_tps_init_child");
+ return;
+loser:
+ /* Log TPS module debug information. */
+ RA::Debug( "mod_tps::mod_tps_initialize",
+ "Failed loading the TPS module!" );
+
+ /* Free TPS resources. */
+ /* If we are here, the parent should be up. */
+ RA::Shutdown();
+
+ /* Since all members of mod_tps_server_configuration are allocated */
+ /* from a pool, there is no need to unset any of these members. */
+
+#ifdef MEM_PROFILING
+ /* If memory profiling is enabled, turn off memory profiling. */
+ MEM_shutdown();
+#endif
+
+ /* Shutdown all APR library routines. */
+ /* NOTE: This automatically destroys all memory pools. */
+ apr_terminate();
+
+ /* Terminate the entire Apache server */
+ _exit(APEXIT_CHILDFATAL);
+
+ return;
+
+}
+
+
+
+/* _________________________________________________________________
+**
+** TPS Module Registration Phase
+** _________________________________________________________________
+*/
+
+static void
+mod_tps_register_hooks( apr_pool_t *p )
+{
+ static const char *const mod_tps_preloaded_modules[] = { "mod_nss.c",
+ NULL };
+ static const char *const mod_tps_postloaded_modules[] = { NULL };
+
+ ap_hook_post_config( mod_tps_initialize,
+ mod_tps_preloaded_modules,
+ mod_tps_postloaded_modules,
+ APR_HOOK_MIDDLE );
+
+ ap_hook_child_init(mod_tps_init_child, NULL,NULL, APR_HOOK_MIDDLE);
+
+ ap_hook_handler( mod_tps_handler,
+ mod_tps_preloaded_modules,
+ mod_tps_postloaded_modules,
+ APR_HOOK_MIDDLE );
+}
+
+
+module TPS_PUBLIC MOD_TPS_CONFIG_KEY = {
+ STANDARD20_MODULE_STUFF,
+ NULL, /* create per-dir config structures */
+ NULL, /* merge per-dir config structures */
+ mod_tps_config_server_create, /* create per-server config structures */
+ NULL, /* merge per-server config structures */
+ mod_tps_config_cmds, /* table of configuration directives */
+ mod_tps_register_hooks /* register hooks */
+};
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/base/tps/src/msg/RA_ASQ_Request_Msg.cpp b/base/tps/src/msg/RA_ASQ_Request_Msg.cpp
new file mode 100644
index 000000000..112c42152
--- /dev/null
+++ b/base/tps/src/msg/RA_ASQ_Request_Msg.cpp
@@ -0,0 +1,70 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "plstr.h"
+#include "main/Base.h"
+#include "msg/RA_ASQ_Request_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs A Security Question (ASQ) request message.
+ */
+TPS_PUBLIC RA_ASQ_Request_Msg::RA_ASQ_Request_Msg (char *question)
+{
+ if (question == NULL)
+ m_question = NULL;
+ else
+ m_question = PL_strdup(question);
+}
+
+
+/**
+ * Destructs a ASQ request message.
+ */
+TPS_PUBLIC RA_ASQ_Request_Msg::~RA_ASQ_Request_Msg ()
+{
+ if( m_question != NULL ) {
+ PL_strfree( m_question );
+ m_question = NULL;
+ }
+}
+
+/**
+ * Retrieves the message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_ASQ_Request_Msg::GetType ()
+{
+ return MSG_ASQ_REQUEST;
+}
+
+/**
+ * Retrieves the security question for
+ * the end user.
+ */
+TPS_PUBLIC char *RA_ASQ_Request_Msg::GetQuestion()
+{
+ return m_question;
+}
diff --git a/base/tps/src/msg/RA_ASQ_Response_Msg.cpp b/base/tps/src/msg/RA_ASQ_Response_Msg.cpp
new file mode 100644
index 000000000..5e480c1f1
--- /dev/null
+++ b/base/tps/src/msg/RA_ASQ_Response_Msg.cpp
@@ -0,0 +1,68 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "plstr.h"
+#include "msg/RA_ASQ_Response_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs A Security Question (ASQ) response.
+ */
+TPS_PUBLIC RA_ASQ_Response_Msg::RA_ASQ_Response_Msg (char *answer)
+{
+ if (answer == NULL)
+ m_answer = NULL;
+ else
+ m_answer = PL_strdup(answer);
+}
+
+/**
+ * Destructs a ASQ response.
+ */
+TPS_PUBLIC RA_ASQ_Response_Msg::~RA_ASQ_Response_Msg ()
+{
+ if( m_answer != NULL ) {
+ PL_strfree( m_answer );
+ m_answer = NULL;
+ }
+}
+
+/**
+ * Retrieves message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_ASQ_Response_Msg::GetType ()
+{
+ return MSG_ASQ_RESPONSE;
+}
+
+/**
+ * Retrieves the answer to the security question
+ * from the end user.
+ */
+TPS_PUBLIC char *RA_ASQ_Response_Msg::GetAnswer()
+{
+ return m_answer;
+}
diff --git a/base/tps/src/msg/RA_Begin_Op_Msg.cpp b/base/tps/src/msg/RA_Begin_Op_Msg.cpp
new file mode 100644
index 000000000..44d568bd9
--- /dev/null
+++ b/base/tps/src/msg/RA_Begin_Op_Msg.cpp
@@ -0,0 +1,72 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "msg/RA_Begin_Op_Msg.h"
+#include "main/Memory.h"
+#include "main/NameValueSet.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a begin op message. Each operation
+ * transaction (i.e. enrollment, reset pin)
+ * starts with a Begin Op message.
+ */
+TPS_PUBLIC RA_Begin_Op_Msg::RA_Begin_Op_Msg (RA_Op_Type op, NameValueSet *exts)
+{
+ m_op = op;
+ m_exts = exts;
+}
+
+/**
+ * Destructs a begin op message.
+ */
+TPS_PUBLIC RA_Begin_Op_Msg::~RA_Begin_Op_Msg ()
+{
+ if( m_exts != NULL ) {
+ delete m_exts;
+ m_exts = NULL;
+ }
+}
+
+/**
+ * Retrieves message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_Begin_Op_Msg::GetType ()
+{
+ return MSG_BEGIN_OP;
+}
+
+TPS_PUBLIC NameValueSet *RA_Begin_Op_Msg::GetExtensions()
+{
+ return m_exts;
+}
+
+/**
+ * Retrieves operation type.
+ */
+TPS_PUBLIC RA_Op_Type RA_Begin_Op_Msg::GetOpType()
+{
+ return m_op;
+}
diff --git a/base/tps/src/msg/RA_End_Op_Msg.cpp b/base/tps/src/msg/RA_End_Op_Msg.cpp
new file mode 100644
index 000000000..232122d49
--- /dev/null
+++ b/base/tps/src/msg/RA_End_Op_Msg.cpp
@@ -0,0 +1,73 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "msg/RA_End_Op_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a begin op message. Each operation
+ * transaction (i.e. enrollment, reset pin)
+ * starts with a Begin Op message.
+ */
+TPS_PUBLIC RA_End_Op_Msg::RA_End_Op_Msg (RA_Op_Type op, int result, int msg)
+{
+ m_op = op;
+ m_result = result;
+ m_msg = msg;
+}
+
+/**
+ * Destructs a begin op message.
+ */
+TPS_PUBLIC RA_End_Op_Msg::~RA_End_Op_Msg ()
+{
+}
+
+/**
+ * Retrieves message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_End_Op_Msg::GetType ()
+{
+ return MSG_END_OP;
+}
+
+/**
+ * Retrieves operation type.
+ */
+TPS_PUBLIC RA_Op_Type RA_End_Op_Msg::GetOpType()
+{
+ return m_op;
+}
+
+TPS_PUBLIC int RA_End_Op_Msg::GetResult()
+{
+ return m_result;
+}
+
+TPS_PUBLIC int RA_End_Op_Msg::GetMsg()
+{
+ return m_msg;
+}
diff --git a/base/tps/src/msg/RA_Extended_Login_Request_Msg.cpp b/base/tps/src/msg/RA_Extended_Login_Request_Msg.cpp
new file mode 100644
index 000000000..9da2f6d8f
--- /dev/null
+++ b/base/tps/src/msg/RA_Extended_Login_Request_Msg.cpp
@@ -0,0 +1,114 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+
+#include "plstr.h"
+#include "main/Base.h"
+#include "msg/RA_Extended_Login_Request_Msg.h"
+#include "engine/RA.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a login request message that requests
+ * user id and password from the end user.
+ */
+TPS_PUBLIC RA_Extended_Login_Request_Msg::RA_Extended_Login_Request_Msg (int invalid_pw, int blocked, char **parameters, int len, char *title, char *description)
+{
+ m_invalid_pw = invalid_pw;
+ m_blocked = blocked;
+ m_title = PL_strdup(title);
+ m_description = PL_strdup(description);
+ if (parameters != NULL) {
+ if (len > 0) {
+ m_parameters = (char **) PR_Malloc (len);
+ for (int i = 0; i < len; i++) {
+ m_parameters[i] = PL_strdup(parameters[i]);
+ }
+ } else {
+ m_parameters = NULL;
+ }
+ }
+ m_len = len;
+}
+
+/**
+ * Destructs a login request message.
+ */
+TPS_PUBLIC RA_Extended_Login_Request_Msg::~RA_Extended_Login_Request_Msg ()
+{
+ for (int i = 0; i < m_len; i++) {
+ PL_strfree(m_parameters[i]);
+ }
+ if (m_parameters != NULL) {
+ PR_Free(m_parameters);
+ }
+}
+
+TPS_PUBLIC int RA_Extended_Login_Request_Msg::GetLen ()
+{
+ return m_len;
+}
+
+TPS_PUBLIC char *RA_Extended_Login_Request_Msg::GetTitle()
+{
+ return m_title;
+}
+
+TPS_PUBLIC char *RA_Extended_Login_Request_Msg::GetDescription()
+{
+ return m_description;
+}
+
+TPS_PUBLIC char *RA_Extended_Login_Request_Msg::GetParam (int i)
+{
+ return m_parameters[i];
+}
+
+/**
+ * Retrieves message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_Extended_Login_Request_Msg::GetType ()
+{
+ return MSG_EXTENDED_LOGIN_REQUEST;
+}
+
+/**
+ * Is the password invalid in the previous login
+ * request.
+ */
+TPS_PUBLIC int RA_Extended_Login_Request_Msg::IsInvalidPassword()
+{
+ return m_invalid_pw;
+}
+
+/**
+ * Should the client block due to the previous
+ * invalid login.
+ */
+TPS_PUBLIC int RA_Extended_Login_Request_Msg::IsBlocked()
+{
+ return m_blocked;
+}
diff --git a/base/tps/src/msg/RA_Extended_Login_Response_Msg.cpp b/base/tps/src/msg/RA_Extended_Login_Response_Msg.cpp
new file mode 100644
index 000000000..f1d66b558
--- /dev/null
+++ b/base/tps/src/msg/RA_Extended_Login_Response_Msg.cpp
@@ -0,0 +1,65 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "plstr.h"
+#include "msg/RA_Extended_Login_Response_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a login response message.
+ */
+TPS_PUBLIC RA_Extended_Login_Response_Msg::RA_Extended_Login_Response_Msg (AuthParams *params)
+{
+ m_params = params;
+}
+
+/**
+ * Destructs a login response message.
+ */
+TPS_PUBLIC RA_Extended_Login_Response_Msg::~RA_Extended_Login_Response_Msg ()
+{
+ if( m_params != NULL ) {
+ delete m_params;
+ m_params = NULL;
+ }
+}
+
+/**
+ * Retrieves message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_Extended_Login_Response_Msg::GetType ()
+{
+ return MSG_EXTENDED_LOGIN_RESPONSE;
+}
+
+/**
+ * Retrieves null-pointer terminated
+ * user ID given by the end user.
+ */
+TPS_PUBLIC AuthParams *RA_Extended_Login_Response_Msg::GetAuthParams()
+{
+ return m_params;
+}
diff --git a/base/tps/src/msg/RA_Login_Request_Msg.cpp b/base/tps/src/msg/RA_Login_Request_Msg.cpp
new file mode 100644
index 000000000..7bad331d7
--- /dev/null
+++ b/base/tps/src/msg/RA_Login_Request_Msg.cpp
@@ -0,0 +1,71 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "msg/RA_Login_Request_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a login request message that requests
+ * user id and password from the end user.
+ */
+TPS_PUBLIC RA_Login_Request_Msg::RA_Login_Request_Msg (int invalid_pw, int blocked)
+{
+ m_invalid_pw = invalid_pw;
+ m_blocked = blocked;
+}
+
+/**
+ * Destructs a login request message.
+ */
+TPS_PUBLIC RA_Login_Request_Msg::~RA_Login_Request_Msg ()
+{
+}
+
+/**
+ * Retrieves message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_Login_Request_Msg::GetType ()
+{
+ return MSG_LOGIN_REQUEST;
+}
+
+/**
+ * Is the password invalid in the previous login
+ * request.
+ */
+TPS_PUBLIC int RA_Login_Request_Msg::IsInvalidPassword()
+{
+ return m_invalid_pw;
+}
+
+/**
+ * Should the client block due to the previous
+ * invalid login.
+ */
+TPS_PUBLIC int RA_Login_Request_Msg::IsBlocked()
+{
+ return m_blocked;
+}
diff --git a/base/tps/src/msg/RA_Login_Response_Msg.cpp b/base/tps/src/msg/RA_Login_Response_Msg.cpp
new file mode 100644
index 000000000..67d796e6e
--- /dev/null
+++ b/base/tps/src/msg/RA_Login_Response_Msg.cpp
@@ -0,0 +1,85 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "plstr.h"
+#include "msg/RA_Login_Response_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a login response message.
+ */
+TPS_PUBLIC RA_Login_Response_Msg::RA_Login_Response_Msg (char *uid, char *password)
+{
+ if (uid == NULL)
+ m_uid = NULL;
+ else
+ m_uid = PL_strdup(uid);
+ if (password == NULL)
+ m_password = NULL;
+ else
+ m_password = PL_strdup(password);
+}
+
+/**
+ * Destructs a login response message.
+ */
+TPS_PUBLIC RA_Login_Response_Msg::~RA_Login_Response_Msg ()
+{
+ if( m_uid != NULL ) {
+ PL_strfree( m_uid );
+ m_uid = NULL;
+ }
+ if( m_password != NULL ) {
+ PL_strfree( m_password );
+ m_password = NULL;
+ }
+}
+
+/**
+ * Retrieves message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_Login_Response_Msg::GetType ()
+{
+ return MSG_LOGIN_RESPONSE;
+}
+
+/**
+ * Retrieves null-pointer terminated
+ * user ID given by the end user.
+ */
+TPS_PUBLIC char *RA_Login_Response_Msg::GetUID()
+{
+ return m_uid;
+}
+
+/**
+ * Retrieves null-pointer terminated password
+ * given by the end user.
+ */
+TPS_PUBLIC char *RA_Login_Response_Msg::GetPassword()
+{
+ return m_password;
+}
diff --git a/base/tps/src/msg/RA_New_Pin_Request_Msg.cpp b/base/tps/src/msg/RA_New_Pin_Request_Msg.cpp
new file mode 100644
index 000000000..71889359e
--- /dev/null
+++ b/base/tps/src/msg/RA_New_Pin_Request_Msg.cpp
@@ -0,0 +1,70 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "msg/RA_New_Pin_Request_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a new pin request for the token.
+ */
+TPS_PUBLIC RA_New_Pin_Request_Msg::RA_New_Pin_Request_Msg (int min_len, int max_len)
+{
+ m_min_len = min_len;
+ m_max_len = max_len;
+}
+
+
+/**
+ * Destructs a new pin request.
+ */
+TPS_PUBLIC RA_New_Pin_Request_Msg::~RA_New_Pin_Request_Msg ()
+{
+}
+
+/**
+ * Retrieves the message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_New_Pin_Request_Msg::GetType ()
+{
+ return MSG_NEW_PIN_REQUEST;
+}
+
+/**
+ * Retrieves the minimium length required for the new password.
+ */
+TPS_PUBLIC int RA_New_Pin_Request_Msg::GetMinLen()
+{
+ return m_min_len;
+}
+
+
+/**
+ * Retrieves the maximium length required for the new password.
+ */
+TPS_PUBLIC int RA_New_Pin_Request_Msg::GetMaxLen()
+{
+ return m_max_len;
+}
diff --git a/base/tps/src/msg/RA_New_Pin_Response_Msg.cpp b/base/tps/src/msg/RA_New_Pin_Response_Msg.cpp
new file mode 100644
index 000000000..69b63f934
--- /dev/null
+++ b/base/tps/src/msg/RA_New_Pin_Response_Msg.cpp
@@ -0,0 +1,68 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "plstr.h"
+#include "msg/RA_New_Pin_Response_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a new pin response.
+ */
+TPS_PUBLIC RA_New_Pin_Response_Msg::RA_New_Pin_Response_Msg (char *new_pin)
+{
+ if (new_pin == NULL)
+ m_new_pin = NULL;
+ else
+ m_new_pin = PL_strdup(new_pin);
+}
+
+/**
+ * Destructs a new pin response.
+ */
+TPS_PUBLIC RA_New_Pin_Response_Msg::~RA_New_Pin_Response_Msg ()
+{
+ if( m_new_pin != NULL ) {
+ PL_strfree( m_new_pin );
+ m_new_pin = NULL;
+ }
+}
+
+/**
+ * Retrieves the message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_New_Pin_Response_Msg::GetType ()
+{
+ return MSG_NEW_PIN_RESPONSE;
+}
+
+/**
+ * Retrieves the null-pointer terminated new pin
+ * from the end user.
+ */
+TPS_PUBLIC char *RA_New_Pin_Response_Msg::GetNewPIN()
+{
+ return m_new_pin;
+}
diff --git a/base/tps/src/msg/RA_SecureId_Request_Msg.cpp b/base/tps/src/msg/RA_SecureId_Request_Msg.cpp
new file mode 100644
index 000000000..064461225
--- /dev/null
+++ b/base/tps/src/msg/RA_SecureId_Request_Msg.cpp
@@ -0,0 +1,69 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "msg/RA_SecureId_Request_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a Secure ID request message for requesting
+ * Secure ID input from the end user.
+ */
+TPS_PUBLIC RA_SecureId_Request_Msg::RA_SecureId_Request_Msg (int pin_required, int next_value)
+{
+ m_pin_required = pin_required;
+ m_next_value = next_value;
+}
+
+/**
+ * Destructs a Secure ID request.
+ */
+TPS_PUBLIC RA_SecureId_Request_Msg::~RA_SecureId_Request_Msg ()
+{
+}
+
+/**
+ * Retrieves the message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_SecureId_Request_Msg::GetType ()
+{
+ return MSG_SECUREID_REQUEST;
+}
+
+/**
+ * Is PIN required?
+ */
+TPS_PUBLIC int RA_SecureId_Request_Msg::IsPinRequired()
+{
+ return m_pin_required;
+}
+
+/**
+ * Is next value required?
+ */
+TPS_PUBLIC int RA_SecureId_Request_Msg::IsNextValue()
+{
+ return m_next_value;
+}
diff --git a/base/tps/src/msg/RA_SecureId_Response_Msg.cpp b/base/tps/src/msg/RA_SecureId_Response_Msg.cpp
new file mode 100644
index 000000000..ff4191a61
--- /dev/null
+++ b/base/tps/src/msg/RA_SecureId_Response_Msg.cpp
@@ -0,0 +1,83 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "plstr.h"
+#include "msg/RA_SecureId_Response_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a Secure ID response.
+ */
+TPS_PUBLIC RA_SecureId_Response_Msg::RA_SecureId_Response_Msg (char *value, char *pin)
+{
+ if (value == NULL)
+ m_value = NULL;
+ else
+ m_value = PL_strdup(value);
+ if (pin == NULL)
+ m_pin = NULL;
+ else
+ m_pin = PL_strdup(pin);
+}
+
+/**
+ * Destructs a Secure ID response.
+ */
+TPS_PUBLIC RA_SecureId_Response_Msg::~RA_SecureId_Response_Msg ()
+{
+ if( m_value != NULL ) {
+ PL_strfree( m_value );
+ m_value = NULL;
+ }
+ if( m_pin != NULL ) {
+ PL_strfree( m_pin );
+ m_pin = NULL;
+ }
+}
+
+/**
+ * Retrieves the message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_SecureId_Response_Msg::GetType ()
+{
+ return MSG_SECUREID_RESPONSE;
+}
+
+/**
+ * Retrieves the value.
+ */
+TPS_PUBLIC char *RA_SecureId_Response_Msg::GetValue()
+{
+ return m_value;
+}
+
+/**
+ * Retrieves the PIN.
+ */
+TPS_PUBLIC char *RA_SecureId_Response_Msg::GetPIN()
+{
+ return m_pin;
+}
diff --git a/base/tps/src/msg/RA_Status_Update_Request_Msg.cpp b/base/tps/src/msg/RA_Status_Update_Request_Msg.cpp
new file mode 100644
index 000000000..7bb0baefc
--- /dev/null
+++ b/base/tps/src/msg/RA_Status_Update_Request_Msg.cpp
@@ -0,0 +1,66 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "msg/RA_Status_Update_Request_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a Token PDU request.
+ */
+TPS_PUBLIC RA_Status_Update_Request_Msg::RA_Status_Update_Request_Msg (int status, const char *info)
+{
+ m_status = status;
+ m_info = PL_strdup((char *) info);
+}
+
+/**
+ * Destructs a Token PDU request.
+ */
+TPS_PUBLIC RA_Status_Update_Request_Msg::~RA_Status_Update_Request_Msg ()
+{
+ if( m_info != NULL ) {
+ PL_strfree( m_info );
+ m_info = NULL;
+ }
+}
+
+/**
+ * Retrieves the message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_Status_Update_Request_Msg::GetType ()
+{
+ return MSG_STATUS_UPDATE_REQUEST;
+}
+
+TPS_PUBLIC int RA_Status_Update_Request_Msg::GetStatus()
+{
+ return m_status;
+}
+
+TPS_PUBLIC char *RA_Status_Update_Request_Msg::GetInfo()
+{
+ return m_info;
+}
diff --git a/base/tps/src/msg/RA_Status_Update_Response_Msg.cpp b/base/tps/src/msg/RA_Status_Update_Response_Msg.cpp
new file mode 100644
index 000000000..6053c9af6
--- /dev/null
+++ b/base/tps/src/msg/RA_Status_Update_Response_Msg.cpp
@@ -0,0 +1,56 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "msg/RA_Status_Update_Response_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a Token PDU request.
+ */
+TPS_PUBLIC RA_Status_Update_Response_Msg::RA_Status_Update_Response_Msg (int status)
+{
+ m_status = status;
+}
+
+/**
+ * Destructs a Token PDU request.
+ */
+TPS_PUBLIC RA_Status_Update_Response_Msg::~RA_Status_Update_Response_Msg ()
+{
+}
+
+/**
+ * Retrieves the message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_Status_Update_Response_Msg::GetType ()
+{
+ return MSG_STATUS_UPDATE_RESPONSE;
+}
+
+TPS_PUBLIC int RA_Status_Update_Response_Msg::GetStatus()
+{
+ return m_status;
+}
diff --git a/base/tps/src/msg/RA_Token_PDU_Request_Msg.cpp b/base/tps/src/msg/RA_Token_PDU_Request_Msg.cpp
new file mode 100644
index 000000000..34b3d584b
--- /dev/null
+++ b/base/tps/src/msg/RA_Token_PDU_Request_Msg.cpp
@@ -0,0 +1,63 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "msg/RA_Token_PDU_Request_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a Token PDU request.
+ */
+TPS_PUBLIC RA_Token_PDU_Request_Msg::RA_Token_PDU_Request_Msg (APDU *apdu)
+{
+ m_apdu = apdu;
+}
+
+/**
+ * Destructs a Token PDU request.
+ */
+TPS_PUBLIC RA_Token_PDU_Request_Msg::~RA_Token_PDU_Request_Msg ()
+{
+ if( m_apdu != NULL ) {
+ delete m_apdu;
+ m_apdu = NULL;
+ }
+}
+
+/**
+ * Retrieves the message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_Token_PDU_Request_Msg::GetType ()
+{
+ return MSG_TOKEN_PDU_REQUEST;
+}
+
+/**
+ * Retrieves the APDU that is targeted for the token.
+ */
+TPS_PUBLIC APDU *RA_Token_PDU_Request_Msg::GetAPDU()
+{
+ return m_apdu;
+}
diff --git a/base/tps/src/msg/RA_Token_PDU_Response_Msg.cpp b/base/tps/src/msg/RA_Token_PDU_Response_Msg.cpp
new file mode 100644
index 000000000..41b11388c
--- /dev/null
+++ b/base/tps/src/msg/RA_Token_PDU_Response_Msg.cpp
@@ -0,0 +1,68 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "apdu/APDU_Response.h"
+#include "msg/RA_Token_PDU_Response_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a Token PDU response.
+ */
+TPS_PUBLIC RA_Token_PDU_Response_Msg::RA_Token_PDU_Response_Msg (APDU_Response *response)
+{
+ m_response = response;
+}
+
+/**
+ * Destructs a Token PDU response.
+ */
+TPS_PUBLIC RA_Token_PDU_Response_Msg::~RA_Token_PDU_Response_Msg ()
+{
+ if( m_response != NULL ) {
+ delete m_response;
+ m_response = NULL;
+ }
+}
+
+/**
+ * Retrieves the message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_Token_PDU_Response_Msg::GetType ()
+{
+ return MSG_TOKEN_PDU_RESPONSE;
+}
+
+/**
+ * Retrieves the response from the token.
+ * This response does not follow the standard
+ * APDU format. It is just a sequence of data
+ * with 2 bytes, at the end, that indicates
+ * the status.
+ */
+TPS_PUBLIC APDU_Response *RA_Token_PDU_Response_Msg::GetResponse()
+{
+ return m_response;
+}
diff --git a/base/tps/src/processor/RA_Enroll_Processor.cpp b/base/tps/src/processor/RA_Enroll_Processor.cpp
new file mode 100644
index 000000000..d88d84087
--- /dev/null
+++ b/base/tps/src/processor/RA_Enroll_Processor.cpp
@@ -0,0 +1,5194 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+/**
+ * RA_Enroll_Processor handles initialization and enrollment of the token
+ */
+
+
+/* variable naming convention:
+ * a_ passed as an 'in' argument to a method
+ * o_ passed as an 'out' argument to a method
+ * m_ member variable
+ */
+
+
+#include <string.h>
+#include <time.h>
+#include "pkcs11.h"
+
+// for public key processing
+#include "secder.h"
+#include "pk11func.h"
+#include "cryptohi.h"
+#include "keyhi.h"
+#include "base64.h"
+#include "nssb64.h"
+#include "prlock.h"
+
+#include "cert.h"
+#include "main/RA_Session.h"
+#include "main/RA_Msg.h"
+#include "main/Buffer.h"
+#include "main/Util.h"
+#include "main/PKCS11Obj.h"
+#include "engine/RA.h"
+#include "channel/Secure_Channel.h"
+#include "msg/RA_SecureId_Request_Msg.h"
+#include "msg/RA_SecureId_Response_Msg.h"
+#include "msg/RA_New_Pin_Request_Msg.h"
+#include "msg/RA_New_Pin_Response_Msg.h"
+#include "processor/RA_Processor.h"
+#include "processor/RA_Enroll_Processor.h"
+#include "tus/tus_db.h"
+
+#include "cms/CertEnroll.h"
+#include "httpClient/httpc/response.h"
+#include "main/Memory.h"
+
+#define OP_PREFIX "op.enroll"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+SECStatus PK11_GenerateRandom(unsigned char *,int);
+void PrintPRTime(PRTime, const char *);
+
+
+// This parameter is read from the config file. It is the
+// applet build ID which the administrator wants to set as
+// the 'latest applet' to upgrade to.
+static const char *g_applet_target_version = NULL;
+
+
+/**
+ * this function returns a new allocated string
+ * @param cuid a 20 character string. Usually this is 20 hex
+ * digits representing a token CUID.
+ * @returns a new string which is basically a copy of the input, but
+ * with extra colons. The caller is responsible for freeing the
+ * returned string with PR_Free().
+ */
+
+static char *GetPrettyPrintCUID(const char *cuid)
+{
+ int i,j;
+ char *ret = NULL;
+
+ if (cuid == NULL)
+ return NULL;
+ if (strlen(cuid) != 20)
+ return NULL;
+ ret = (char *)PR_Malloc(20+4+1);
+ j = 0;
+ for (i = 0; i < 24; i++) {
+ if (i == 4 || i == 9 || i == 14 || i == 19) {
+ ret[i] = '-';
+ } else {
+ ret[i] = cuid[j];
+ j++;
+ }
+ }
+ ret[24] = '\0';
+ return ret;
+}
+
+static SECItem *
+PK11_GetPubIndexKeyID(CERTCertificate *cert) {
+ SECKEYPublicKey *pubk;
+ SECItem *newItem = NULL;
+
+ pubk = CERT_ExtractPublicKey(cert);
+ if (pubk == NULL) return NULL;
+
+ switch (pubk->keyType) {
+ case rsaKey:
+ newItem = SECITEM_DupItem(&pubk->u.rsa.modulus);
+ break;
+ case dsaKey:
+ newItem = SECITEM_DupItem(&pubk->u.dsa.publicValue);
+ break;
+ case dhKey:
+ newItem = SECITEM_DupItem(&pubk->u.dh.publicValue);
+ break;
+ case ecKey:
+ newItem = SECITEM_DupItem(&pubk->u.ec.publicValue);
+ break;
+ case fortezzaKey:
+ default:
+ newItem = NULL; /* Fortezza Fix later... */
+ }
+ SECKEY_DestroyPublicKey(pubk);
+ /* make hash of it */
+ return newItem;
+}
+
+
+/**
+ * Constructs a processor for handling enrollment operation.
+ */
+TPS_PUBLIC RA_Enroll_Processor::RA_Enroll_Processor ()
+{
+}
+
+/**
+ * Destructs enrollment processor.
+ */
+TPS_PUBLIC RA_Enroll_Processor::~RA_Enroll_Processor ()
+{
+}
+
+RA_Status RA_Enroll_Processor::DoEnrollment(AuthParams *login, RA_Session *session,
+ CERTCertificate **certificates,
+ char **origins,
+ char **ktypes,
+ int pkcs11obj_enable,
+ PKCS11Obj *pkcs_objx,
+ NameValueSet *extensions,
+ int index, int keyTypeNum,
+ int start_progress,
+ int end_progress,
+ Secure_Channel *channel, Buffer *wrapped_challenge,
+ const char *tokenType,
+ const char *keyType,
+ Buffer *key_check,
+ Buffer *plaintext_challenge,
+ const char *cuid,
+ const char *msn,
+ const char *khex,
+ TokenKeyType key_type,
+ const char *profileId,
+ const char *userid,
+ const char *cert_id,
+ const char *publisher_id,
+ const char *cert_attr_id,
+ const char *pri_attr_id,
+ const char *pub_attr_id,
+ BYTE se_p1, BYTE se_p2, int keysize, const char *connid, const char *keyTypePrefix,char * applet_version)
+{
+ RA_Status status = STATUS_NO_ERROR;
+ int rc = -1;
+ int len = 0;
+ int publish_result = -1;
+ Buffer *public_key = NULL;
+ SECItem si_mod;
+ Buffer *modulus=NULL;
+ SECItem *si_kid = NULL;
+ Buffer *keyid=NULL;
+ SECItem si_exp;
+ Buffer *exponent=NULL;
+ CertEnroll *certEnroll = NULL;
+ Buffer *cert = NULL;
+ Buffer CUID = channel->GetKeyDiversificationData();
+ const char *label = NULL;
+ const char *cuid_label = NULL;
+ const char *pattern;
+ char configname[256];
+ NameValueSet nv;
+ const char *pretty_cuid = NULL;
+
+ const char *FN="RA_Enroll_Processor::DoEnrollment";
+
+ char *cert_string = NULL;
+ SECItem* encodedPublicKeyInfo = NULL;
+ SECItem **ppEncodedPublicKeyInfo = NULL;
+ CERTSubjectPublicKeyInfo* spkix = NULL;
+
+ char *pKey = NULL;
+ char *ivParam = NULL;
+ char *wrappedPrivKey = NULL;
+
+ const char *drmconnid = NULL;
+ bool serverKeygen = false;
+ SECKEYPublicKey *pk_p = NULL;
+
+ char audit_msg[512] = "";
+ char *keyVersion = NULL;
+ char cert_serial[2048] = "";
+ char activity_msg[4096] = "";
+
+ float progress_block_size = (float) (end_progress - start_progress) / keyTypeNum;
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Start of keygen/certificate enrollment");
+
+ // get key version for audit logs
+ if (channel != NULL) {
+ if( keyVersion != NULL ) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+ keyVersion = Util::Buffer2String(channel->GetKeyInfoData());
+ }
+
+ // check if we need to do key generation (by default, overwrite everything)
+ PR_snprintf((char *)configname, 256, "%s.%s.keyGen.%s.overwrite",
+ OP_PREFIX, tokenType, keyType);
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "looking for config %s", configname);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 1)) {
+ // do nothing
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "do overwrite");
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "do not overwrite, if %s exists", cert_id);
+ int num_objs = pkcs_objx->PKCS11Obj::GetObjectSpecCount();
+ char b[3];
+ bool foundObj = false;
+ for (int i = 0; i< num_objs; i++) {
+ ObjectSpec* os = pkcs_objx->GetObjectSpec(i);
+ unsigned long oid = os->GetObjectID();
+ b[0] = (char)((oid >> 24) & 0xff);
+ b[1] = (char)((oid >> 16) & 0xff);
+ b[2] = '\0';
+ /*
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "object id =%c:%c b=%s",b[0], b[1], b);
+ */
+ if (PL_strcasecmp(cert_id, b) == 0) {
+ foundObj = true;
+ break;
+ }
+ }
+
+
+ if (foundObj) {
+ // we already have a certificate there, skip enrollment
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Found certficate. Will not overwrite. Skipped enrollment");
+ return status;
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Certficate not found. Continuing with enrollment");
+ }
+ }
+
+ StatusUpdate(session, extensions,
+ start_progress + (index * progress_block_size) +
+ (progress_block_size * 15/100) /* progress */,
+ "PROGRESS_KEY_GENERATION");
+
+ if (key_type == KEY_TYPE_ENCRYPTION) {// do serverSide keygen?
+
+ PR_snprintf((char *)configname, 256, "%s.serverKeygen.enable", keyTypePrefix);
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "looking for config %s", configname);
+ serverKeygen = RA::GetConfigStore()->GetConfigAsBool(configname, false);
+ }
+
+ certEnroll = new CertEnroll();
+
+ if (serverKeygen) {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Private key is to be generated on server");
+
+ PR_snprintf((char *)configname, 256, "%s.serverKeygen.drm.conn", keyTypePrefix);
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "looking for config %s", configname);
+ drmconnid = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ PR_snprintf((char *)configname, 256, "%s.serverKeygen.archive", keyTypePrefix);
+ bool archive = RA::GetConfigStore()->GetConfigAsBool(configname, true);
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "calling ServerSideKeyGen with userid =%s, archive=%s", userid, archive? "true":"false");
+
+ RA::ServerSideKeyGen(session, cuid, userid,
+ channel->getDrmWrappedDESKey(), &pKey,
+ &wrappedPrivKey, &ivParam, drmconnid,
+ archive, keysize);
+
+ if (pKey == NULL) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Failed to generate key on server. Please check DRM.");
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "ServerSideKeyGen called, pKey is NULL");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+
+ PR_snprintf(audit_msg, 512, "ServerSideKeyGen called, failed to generate key on server");
+ goto loser;
+ } else
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "key value = %s", pKey);
+
+
+ if (wrappedPrivKey == NULL) {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "ServerSideKeyGen called, wrappedPrivKey is NULL");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "ServerSideKeyGen called, wrappedPrivKey is NULL");
+ goto loser;
+ } else
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "wrappedPrivKey = %s", wrappedPrivKey);
+
+ if (ivParam == NULL) {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "ServerSideKeyGen called, ivParam is NULL");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "ServerSideKeyGen called, ivParam is NULL");
+ goto loser;
+ } else
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "ivParam = %s", ivParam);
+
+ /*
+ * the following code converts b64-encoded public key info into SECKEYPublicKey
+ */
+ SECStatus rv;
+ SECItem der;
+ CERTSubjectPublicKeyInfo* spki = NULL;
+
+ der.type = (SECItemType) 0; /* initialize it, since convertAsciiToItem does not set it */
+ rv = ATOB_ConvertAsciiToItem (&der, pKey);
+ if (rv != SECSuccess){
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "failed to convert b64 private key to binary");
+ SECITEM_FreeItem(&der, PR_FALSE);
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "ServerSideKeyGen: failed to convert b64 private key to binary");
+ goto loser;
+ }else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "decoded private key as: secitem (len=%d)",der.len);
+
+ spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&der);
+
+ if (spki != NULL) {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Successfully decoded DER SubjectPublicKeyInfo structure");
+ pk_p = SECKEY_ExtractPublicKey(spki);
+ if (pk_p != NULL)
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Successfully extracted public key from SPKI structure");
+ else
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Failed to extract public key from SPKI");
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Failed to decode SPKI structure");
+ }
+
+ SECITEM_FreeItem(&der, PR_FALSE);
+ SECKEY_DestroySubjectPublicKeyInfo(spki);
+
+ }
+
+ } else { //generate keys on token
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Private key is to be generated on token");
+
+ BYTE alg = 0x80;
+
+ if(key_check && key_check->size())
+ alg = 0x81;
+
+ len = channel->StartEnrollment(
+ se_p1, se_p2,
+ wrapped_challenge,
+ key_check,
+ alg /* alg */, keysize,
+ 0x00 /* option */);
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "channel->StartEnrollment returned length of public key blob: len=%d", len);
+
+ StatusUpdate(session, extensions,
+ start_progress + (index * progress_block_size) +
+ (progress_block_size * 45/100) /* progress */,
+ "PROGRESS_READ_PUBLIC_KEY");
+
+ /* read the public key from buffer */
+ if (len <= 0) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Error generating key on token.");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "Error generating key on token");
+ goto loser;
+ }
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Reading public key buffer from token");
+
+ BYTE iobuf[4];
+ iobuf[0] = 0xff;
+ iobuf[1] = 0xff;
+ iobuf[2] = 0xff;
+ iobuf[3] = 0xff;
+ /* use ReadObject to read IO buffer */
+ public_key = channel->ReadObject(iobuf, 0, len);
+ if (public_key == NULL) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Unable to read public key buffer from token");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "Unable to read public key buffer from token");
+ goto loser;
+ }
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Successfully read public key buffer");
+
+ RA::DebugBuffer(LL_PER_CONNECTION,FN,
+ "public_key = ", public_key);
+
+ //got public key blob
+ // parse public key blob and check POP
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "challenge size=%d",plaintext_challenge->size());
+ RA::DebugBuffer("RA_Enroll_Processor::process", "challenge = ",
+ plaintext_challenge);
+
+
+ // send status update to the client
+ StatusUpdate(session, extensions,
+ start_progress + (index * progress_block_size) +
+ (progress_block_size * 55/100) /* progress */,
+ "PROGRESS_PARSE_PUBLIC_KEY");
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "About to Parse Public Key");
+
+ pk_p = certEnroll->ParsePublicKeyBlob(
+ (unsigned char *)(BYTE *)*public_key /*blob*/,
+ plaintext_challenge);
+
+ if (pk_p == NULL) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Failed to parse public key");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "Failed to parse public key");
+ goto loser;
+ }
+
+ } //serverKeygen or not
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Keys generated. Proceeding with certificate enrollment");
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ applet_version != NULL ? applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "keys generated");
+
+ if(publisher_id != NULL)
+ {
+ ppEncodedPublicKeyInfo = &encodedPublicKeyInfo;
+
+ }
+
+ pretty_cuid = GetPrettyPrintCUID(cuid);
+
+ nv.Add("pretty_cuid", pretty_cuid);
+ nv.Add("cuid", cuid);
+ nv.Add("msn", msn);
+ nv.Add("userid", userid);
+ nv.Add("profileId", profileId);
+
+ /* populate auth parameters output to nv also */
+ /* so we can reference to the auth parameter by */
+ /* using $auth.cn$, or $auth.mail$ */
+ if (login != NULL) {
+ int s = login->Size();
+ for (int x = 0; x < s; x++) {
+ char namebuf[2048];
+ char *name = login->GetNameAt(x);
+ sprintf(namebuf, "auth.%s", name);
+ nv.Add(namebuf, login->GetValue(name));
+ }
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.keyGen.%s.cuid_label",
+ OP_PREFIX, tokenType, keyType);
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Certificate label '%s'", configname);
+
+ pattern = RA::GetConfigStore()->GetConfigAsString(configname, "$cuid$");
+ cuid_label = MapPattern(&nv, (char *) pattern);
+
+ StatusUpdate(session, extensions,
+ start_progress + (index * progress_block_size) +
+ (progress_block_size * 60/100) /* progress */,
+ "PROGRESS_ENROLL_CERT");
+
+ cert = certEnroll->EnrollCertificate(
+ pk_p, profileId, userid, cuid_label,
+ connid, audit_msg, ppEncodedPublicKeyInfo);
+
+ if (cert == NULL) {
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC_CERT_REQ,
+ userid, cuid, msn, "failure", "enrollment", applet_version,
+ keyVersion != NULL ? keyVersion : "",
+ "", connid, audit_msg);
+ goto loser;
+ }
+
+ si_mod = pk_p->u.rsa.modulus;
+ modulus = new Buffer((BYTE*) si_mod.data, si_mod.len);
+
+ /*
+ * RFC 3279
+ * The keyIdentifier is composed of the 160-bit SHA-1 hash of the
+ * value of the BIT STRING subjectPublicKey (excluding the tag,
+ * length, and number of unused bits).
+ */
+ spkix = SECKEY_CreateSubjectPublicKeyInfo(pk_p);
+
+ /*
+ * NSS magically multiply the length with 2^3 in cryptohi/seckey.c
+ * Hack:
+ */
+ spkix->subjectPublicKey.len >>= 3;
+ si_kid = PK11_MakeIDFromPubKey(&spkix->subjectPublicKey);
+ spkix->subjectPublicKey.len <<= 3;
+
+
+ keyid = new Buffer((BYTE*) si_kid->data, si_kid->len);
+
+ si_exp = pk_p->u.rsa.publicExponent;
+ exponent = new Buffer((BYTE*) si_exp.data, si_exp.len);
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Keyid, modulus and exponent have been extracted from public key");
+
+ SECKEY_DestroySubjectPublicKeyInfo(spkix);
+
+ cert_string = (char *) cert->string();
+ certificates[index] = CERT_DecodeCertFromPackage((char *) cert_string,
+ (int) cert->size());
+ if (certificates[index] != NULL) {
+ RA::ra_tus_print_integer(cert_serial, &certificates[index]->serialNumber);
+ RA::Debug("DoEnrollment", "Received Certificate");
+ RA::Debug("DoEnrollment", cert_serial);
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC_CERT_REQ,
+ userid, cuid, msn, "success", "enrollment", applet_version,
+ (keyVersion != NULL) ? keyVersion : "", cert_serial, connid, "certificate received");
+ }
+ free(cert_string);
+ ktypes[index] = PL_strdup(keyType);
+ origins[index] = PL_strdup(cuid);
+
+ if (serverKeygen) {
+ //do PKCS#8
+
+ BYTE objid[4];
+
+ objid[0] = 0xFF;
+ objid[1] = 0x00;
+ objid[2] = 0xFF;
+ objid[3] = 0xF3;
+ Buffer priv_keyblob;
+ /* url decode wrappedPrivKey */
+ {
+ Buffer *decodeKey = Util::URLDecode(wrappedPrivKey);
+ // RA::DebugBuffer("cfu debug"," private key =",decodeKey);
+ priv_keyblob =
+ Buffer(1, 0x01) + // encryption
+ Buffer(1, 0x09)+ // keytype is RSAPKCS8Pair
+ Buffer(1,(BYTE)(keysize/256)) + // keysize is two bytes
+ Buffer(1,(BYTE)(keysize%256)) +
+ Buffer((BYTE*) *decodeKey, decodeKey->size());
+ delete decodeKey;
+ }
+
+ //inject PKCS#8 private key
+ BYTE perms[6];
+
+ perms[0] = 0x40;
+ perms[1] = 0x00;
+ perms[2] = 0x40;
+ perms[3] = 0x00;
+ perms[4] = 0x40;
+ perms[5] = 0x00;
+
+ if (channel->CreateObject(objid, perms, priv_keyblob.size()) != 1) {
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "ServerSideKeyGen: store keys in token failed, channel create object error");
+ goto loser;
+ }
+
+
+ if (channel->WriteObject(objid, (BYTE*)priv_keyblob, priv_keyblob.size()) != 1) {
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "ServerSideKeyGen: store keys in token failed, channel write object error");
+ goto loser;
+ }
+
+
+ /* url decode the wrapped kek session key and keycheck*/
+ Buffer data;
+ {
+
+ /*
+ RA::Debug(LL_PER_PDU, "", "getKekWrappedDESKey() returns =%s", channel->getKekWrappedDESKey());
+ RA::Debug(LL_PER_PDU, "", "getKeycheck() returns =%s", channel->getKeycheck());
+ */
+ Buffer *decodeKey = Util::URLDecode(channel->getKekWrappedDESKey());
+
+ /*
+ RA::Debug(LL_PER_PDU, "", "des key item len=%d",
+ decodeKey->size());
+ RA::DebugBuffer("cfu debug", "DES key =", decodeKey);
+ */
+ char *keycheck = channel->getKeycheck();
+ Buffer *decodeKeyCheck = Util::URLDecode(keycheck);
+ if (keycheck)
+ PL_strfree(keycheck);
+
+ /*
+ RA::Debug(LL_PER_PDU, "", "keycheck item len=%d",
+ decodeKeyCheck->size());
+ RA::DebugBuffer("cfu debug", "key check=", decodeKeyCheck);
+ */
+
+ //XXX need randomize this later
+
+ // BYTE iv[] = {0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01};
+ // get ivParam
+ Buffer *iv_decoded = Util::URLDecode(ivParam);
+ if (ivParam) {
+ PL_strfree(ivParam);
+ }
+
+ if(iv_decoded == NULL) {
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "ServerSideKeyGen: store keys in token failed, iv data not found");
+ delete decodeKey;
+ delete decodeKeyCheck;
+ goto loser;
+ }
+
+ BYTE alg = 0x80;
+ if(decodeKey && decodeKey->size()) {
+ alg = 0x81;
+ }
+
+ data =
+ Buffer((BYTE*)objid, 4)+ // object id
+ Buffer(1,alg) +
+ Buffer(1, (BYTE) decodeKey->size()) + // 1 byte length
+ Buffer((BYTE *) *decodeKey, decodeKey->size())+ // key -encrypted to 3des block
+ // check size
+ // key check
+ Buffer(1, (BYTE) decodeKeyCheck->size()) + //keycheck size
+ Buffer((BYTE *) *decodeKeyCheck , decodeKeyCheck->size())+ // keycheck
+ Buffer(1, iv_decoded->size())+ // IV_Length
+ Buffer((BYTE*)*iv_decoded, iv_decoded->size());
+
+ delete iv_decoded;
+ // RA::DebugBuffer("cfu debug", "ImportKeyEnc data buffer =", &data);
+
+ delete decodeKey;
+ delete decodeKeyCheck;
+ }
+
+ if (channel->ImportKeyEnc(se_p1, se_p2, &data) != 1) {
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "ServerSideKeyGen: store keys in token failed, channel import key error");
+ goto loser;
+ }
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ applet_version != NULL ? applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "server generated keys stored in token");
+
+
+ /*
+ * After keys are injected successfully, then write certificate object apdu
+ * to token
+ */
+
+ } // serverKeygen
+
+
+ StatusUpdate(session, extensions,
+ start_progress + (index * progress_block_size) +
+ (progress_block_size * 70/100) /* progress */,
+ "PROGRESS_PUBLISH_CERT");
+
+ //Attempt publish if relevant
+ if(ppEncodedPublicKeyInfo)
+ {
+
+ publish_result = DoPublish(cuid,encodedPublicKeyInfo,cert,publisher_id,applet_version);
+
+ }
+
+ if(ppEncodedPublicKeyInfo)
+ {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Deleting PublicKeyInfo object.");
+
+ SECITEM_FreeItem(*ppEncodedPublicKeyInfo, PR_TRUE);
+ }
+
+ if(publish_result == 0)
+ {
+ status = STATUS_ERROR_PUBLISH;
+
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Enroll Certificate Publish Failure %d", status);
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Enroll Certificate Publish Failure %d",status);
+ PR_snprintf(audit_msg, 512, "publish certificate error");
+ goto loser;
+ }
+
+ if (cert != NULL) {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Enroll Certificate Finished");
+ } else {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Enroll Certificate Failure");
+
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "cert is null");
+ goto loser;
+ }
+
+ StatusUpdate(session, extensions,
+ start_progress + (index * progress_block_size) +
+ (progress_block_size * 80/100) /* progress */,
+ "PROGRESS_IMPORT_CERT");
+
+ /* write certificate from CA to netkey */
+ if (pkcs11obj_enable) {
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (cert_id[0] << 24) +
+ (cert_id[1] << 16),
+ cert);
+ pkcs_objx->AddObjectSpec(objSpec);
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "About to create certificate object on token");
+ rc = channel->CreateCertificate(cert_id, cert);
+ if (rc == -1) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Failed to create certificate object on token");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "Failed to create certificate object on token");
+ goto loser;
+ }
+ }
+
+ // build label
+ PR_snprintf((char *)configname, 256, "%s.%s.keyGen.%s.label",
+ OP_PREFIX, tokenType, keyType);
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "label '%s'", configname);
+ pattern = RA::GetConfigStore()->GetConfigAsString(configname);
+ label = MapPattern(&nv, (char *) pattern);
+
+ if (pkcs11obj_enable) {
+ Buffer b = channel->CreatePKCS11CertAttrsBuffer(
+ key_type, cert_attr_id, label, keyid);
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (cert_attr_id[0] << 24) +
+ (cert_attr_id[1] << 16),
+ &b);
+ pkcs_objx->AddObjectSpec(objSpec);
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "About to create PKCS#11 certificate Attributes");
+ rc = channel->CreatePKCS11CertAttrs(key_type, cert_attr_id, label, keyid);
+ if (rc == -1) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "PKCS11 Certificate attributes creation failed");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "PKCS11 Certificate attributes creation failed");
+ goto loser;
+ }
+ }
+
+ if (pkcs11obj_enable) {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Create PKCS11 Private Key Attributes Buffer");
+ Buffer b = channel->CreatePKCS11PriKeyAttrsBuffer(key_type,
+ pri_attr_id, label, keyid, modulus, OP_PREFIX,
+ tokenType, keyTypePrefix);
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (pri_attr_id[0] << 24) +
+ (pri_attr_id[1] << 16),
+ &b);
+ pkcs_objx->AddObjectSpec(objSpec);
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Create PKCS11 Private Key Attributes");
+ rc = channel->CreatePKCS11PriKeyAttrs(key_type, pri_attr_id, label, keyid, modulus, OP_PREFIX, tokenType, keyTypePrefix);
+ if (rc == -1) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "PKCS11 private key attributes creation failed");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "PKCS11 private key attributes creation failed");
+ goto loser;
+ }
+ }
+
+ if (pkcs11obj_enable) {
+ Buffer b = channel->CreatePKCS11PubKeyAttrsBuffer(key_type,
+ pub_attr_id, label, keyid,
+ exponent, modulus, OP_PREFIX, tokenType, keyTypePrefix);
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (pub_attr_id[0] << 24) +
+ (pub_attr_id[1] << 16),
+ &b);
+ pkcs_objx->AddObjectSpec(objSpec);
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Create PKCS11 Public Key Attributes");
+ rc = channel->CreatePKCS11PubKeyAttrs(key_type, pub_attr_id, label, keyid,
+ exponent, modulus, OP_PREFIX, tokenType, keyTypePrefix);
+ if (rc == -1) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "PKCS11 public key attributes creation failed");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "PKCS11 public key attributes creation failed");
+ goto loser;
+ }
+ }
+ RA::Debug(LL_PER_CONNECTION,FN, "End of keygen/certificate enrollment");
+
+ PR_snprintf(activity_msg, 4096, "certificate %s stored on token", cert_serial);
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ applet_version != NULL ? applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ activity_msg);
+
+ RA::tdb_activity(session->GetRemoteIP(),
+ (char *) cuid,
+ "enrollment",
+ "success",
+ activity_msg,
+ userid != NULL? userid : "",
+ tokenType);
+
+loser:
+ if (strlen(audit_msg) > 0) { // a failure occurred
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "failure",
+ "enrollment",
+ applet_version != NULL ? applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ audit_msg);
+
+ if ((cuid != NULL) && (tokenType != NULL)) {
+ RA::tdb_activity(session->GetRemoteIP(),
+ (char *) cuid,
+ "enrollment",
+ "failure",
+ audit_msg,
+ userid != NULL? userid : "",
+ tokenType);
+ }
+ }
+
+ if( keyVersion != NULL ) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+
+ if( modulus != NULL ) {
+ delete modulus;
+ modulus = NULL;
+ }
+ if( keyid != NULL ) {
+ delete keyid;
+ keyid = NULL;
+ }
+ if( exponent != NULL ) {
+ delete exponent;
+ exponent = NULL;
+ }
+ if( cert != NULL ) {
+ delete cert;
+ cert = NULL;
+ }
+ if( public_key != NULL ) {
+ delete public_key;
+ public_key = NULL;
+ }
+
+ if (pKey !=NULL)
+ PR_Free(pKey);
+
+ if (wrappedPrivKey !=NULL)
+ PR_Free(wrappedPrivKey);
+
+ if( si_kid != NULL ) {
+ SECITEM_FreeItem( si_kid, PR_TRUE );
+ si_kid = NULL;
+ }
+ if( certEnroll != NULL ) {
+ delete certEnroll;
+ certEnroll = NULL;
+ }
+ if( label != NULL ) {
+ PL_strfree( (char *) label );
+ label = NULL;
+ }
+ if( cuid_label != NULL ) {
+ PL_strfree( (char *) cuid_label );
+ cuid_label = NULL;
+ }
+ if( pretty_cuid != NULL ) {
+ PR_Free( (char *) pretty_cuid );
+ pretty_cuid = NULL;
+ }
+ if (pk_p != NULL) {
+ if (serverKeygen) {
+ SECKEY_DestroyPublicKey(pk_p);
+ } else {
+ free(pk_p);
+ }
+ pk_p = NULL;
+ }
+ return status;
+}
+
+SECStatus getRandomNumber(unsigned long *number) {
+ SECStatus rv;
+
+ if (number == NULL) {
+ return SECFailure;
+ }
+
+ rv = PK11_GenerateRandom((unsigned char *) number, sizeof(unsigned long));
+ return rv;
+}
+
+
+/**
+ * @return true if successfull
+ */
+bool RA_Enroll_Processor::GetCardManagerAppletInfo(
+ RA_Session *a_session, /* in */
+ Buffer *a_cardmanagerAID, /* in */
+ RA_Status &a_status, /* out */
+ char * &msn, /* out */
+ char * &cuid, /* out */
+ Buffer &token_cuid /* out */
+)
+{
+ bool r = true; // result
+ Buffer *cplc_data = NULL;
+ Buffer token_msn;
+
+ SelectApplet(a_session, 0x04, 0x00, a_cardmanagerAID);
+ cplc_data = GetData(a_session);
+ if (cplc_data == NULL) {
+ RA::Error("RA_Enroll_Processor::Process",
+ "Get Data Failed");
+ a_status = STATUS_ERROR_SECURE_CHANNEL;
+ r = false;
+ goto loser;
+ }
+ RA::DebugBuffer("RA_Enroll_Processor::process", "CPLC Data = ",
+ cplc_data);
+ if (cplc_data->size() < 47) {
+ RA::Error("RA_Format_Processor::Process",
+ "Invalid CPLC Size");
+ a_status = STATUS_ERROR_SECURE_CHANNEL;
+ r = false;
+ goto loser;
+ }
+ token_cuid = Buffer(cplc_data->substr(3,4)) +
+ Buffer(cplc_data->substr(19,2)) +
+ Buffer(cplc_data->substr(15,4));
+ RA::DebugBuffer("RA_Enroll_Processor::process", "Token CUID= ",
+ &token_cuid);
+ cuid = Util::Buffer2String(token_cuid);
+ RA::Debug("RA_Enroll_Processor::process", "CUID(String)= '%s'",
+ cuid);
+ token_msn = Buffer(cplc_data->substr(41, 4));
+ RA::DebugBuffer("RA_Enroll_Processor::process", "Token MSN= ",
+ &token_msn);
+ msn = Util::Buffer2String(token_msn);
+ RA::Debug("RA_Enroll_Processor::process", "MSN(String)= '%s'",
+ msn);
+ loser:
+ if( cplc_data != NULL ) {
+ delete cplc_data;
+ }
+
+ return r;
+}
+
+bool RA_Enroll_Processor::GetAppletInfo(
+ RA_Session *a_session, /* in */
+ Buffer *a_aid , /* in */
+ BYTE &o_major_version,
+ BYTE &o_minor_version,
+ BYTE &o_app_major_version,
+ BYTE &o_app_minor_version)
+{
+ int total_mem = 0;
+ int free_mem = 0;
+ Buffer *token_status = NULL;
+ SelectApplet(a_session, 0x04, 0x00, a_aid);
+ token_status = GetStatus(a_session, 0x00, 0x00);
+ if (token_status == NULL) {
+ o_major_version = 0x0;
+ o_minor_version = 0x0;
+ o_app_major_version = 0x0;
+ o_app_minor_version = 0x0;
+ } else {
+ o_major_version = ((BYTE*)*token_status)[0]; // is this protocol version?
+ o_minor_version = ((BYTE*)*token_status)[1];
+ o_app_major_version = ((BYTE*)*token_status)[2]; // and this applet version?
+ o_app_minor_version = ((BYTE*)*token_status)[3];
+
+ BYTE tot_high = ((BYTE*)*token_status)[6];
+ BYTE tot_low = ((BYTE*)*token_status)[7];
+
+ BYTE free_high = ((BYTE*)*token_status)[10];
+ BYTE free_low = ((BYTE*)*token_status)[11];
+
+ total_mem = (tot_high << 8) + tot_low;
+ free_mem = (free_high << 8) + free_low;
+
+ totalAvailableMemory = total_mem;
+ totalFreeMemory = free_mem;
+
+ RA::DebugBuffer("RA_Enroll_Processor::Process AppletInfo Data", "Data=", token_status);
+ delete token_status;
+ }
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Major=%d Minor=%d Applet Major=%d Applet Minor=%d Total Mem %d Free Mem %d",
+ o_major_version, o_minor_version, o_app_major_version, o_app_minor_version,total_mem,free_mem);
+ return true;
+}
+
+
+/**
+ * Query applet for build ID info
+ * 'Pretty'-print it into useful format, along with version info
+ * example input:
+ * a_app_major_version = 1
+ * a_app_minor_version = 3
+ * Examples for the following outputs:
+ * o_av = "1.3.45FC0218"
+ * The caller is responsible for free'ing (o_av)
+ */
+bool RA_Enroll_Processor::FormatAppletVersionInfo(
+ RA_Session *a_session,
+ const char *a_tokenType,
+ char *a_cuid,
+ BYTE a_app_major_version,
+ BYTE a_app_minor_version,
+ RA_Status &o_status, // out
+ char * &o_av // out.
+)
+{
+ bool r=true;
+ char configname[256];
+ char *av=NULL;
+
+ // retrieve the 4-byte applet ID from the token
+ Buffer *tokenBuildID = GetAppletVersion(a_session);
+
+ if (tokenBuildID == NULL) {
+ // If there was no applet on the token
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.emptyToken.enable", OP_PREFIX,
+ a_tokenType);
+ // XXX checks if emptyToken is enabled. This should probably get moved
+ // to the applet update function, and leave this fn only for getting
+ // the version information
+ if (!RA::GetConfigStore()->GetConfigAsBool(configname, 0)) {
+ RA::Error("RA_Enroll_Processor::Process",
+ "no applet found and applet upgrade not enabled");
+ o_status = STATUS_ERROR_SECURE_CHANNEL; // XXX incorrect error message
+ r=false;
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid, "enrollment", "failure", "secure channel not established", "", a_tokenType); // XXX incorrect error message
+ goto loser;
+ }
+ } else {
+ // if there was an applet on the token:
+ char * bid_string = Util::Buffer2String(*tokenBuildID);
+ RA::Debug("RA_Enroll_Processor", "buildid = %s", bid_string);
+ av = PR_smprintf( "%x.%x.%s",
+ a_app_major_version, a_app_minor_version, bid_string);
+ PR_Free(bid_string);
+ }
+ o_av = (av == NULL) ? strdup("") : av;
+
+ RA::Debug("RA_Enroll_Processor", "final_applet_version = %s", o_av);
+loser:
+ if( tokenBuildID != NULL ) {
+ delete tokenBuildID;
+ }
+ return r;
+}
+
+/**
+ * Checks if we need to upgrade applet.
+ * The version of the current token is passed IN to this function
+ * in o_current_applet_on_token. If the applet is upgraded, this
+ * out parameter will be set to the new applet version id.
+ * maj/minor versions will be also updated if the applet was updated.
+ */
+bool RA_Enroll_Processor::CheckAndUpgradeApplet(
+ RA_Session *a_session,
+ NameValueSet *a_extensions,
+ char *a_cuid,
+ const char *a_tokenType,
+ char *&o_current_applet_on_token,
+ BYTE &o_major_version,
+ BYTE &o_minor_version,
+ Buffer *a_aid,
+ const char *a_msn,
+ const char *a_userid,
+ RA_Status &o_status,
+ char **keyVersion )
+{
+ int rc = 0;
+ const char *FN = "RA_Enroll_Processor::CheckAndUpgradeApplet";
+ bool r = true;
+ const char *applet_dir=NULL;
+ const char *connid = NULL;
+ Buffer *token_status = NULL;
+ char configname[256];
+
+ // You specify the following parameters to get applet upgrade working
+ // *.update.applet.enable=true
+ // *.update.applet.requiredVersion=maj.min.xxxxxxxx
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.encryption", OP_PREFIX, a_tokenType);
+ SecurityLevel security_level = SECURE_MSG_MAC;
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, true))
+ security_level = SECURE_MSG_MAC_ENC;
+
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.enable", OP_PREFIX, a_tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 0)) {
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.requiredVersion", OP_PREFIX, a_tokenType);
+ g_applet_target_version = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (g_applet_target_version == NULL) {
+ RA::Error(FN, "upgrade.version not found");
+ o_status = STATUS_ERROR_MISCONFIGURATION;
+ r = false;
+ goto loser;
+ }
+ /* Bugscape #55826: used case-insensitive check below */
+ if (PL_strcasecmp(g_applet_target_version, o_current_applet_on_token) != 0) {
+ RA::Debug(LL_PER_CONNECTION, FN, "tokenType=%s before updating applet", a_tokenType);
+ /* upgrade applet */
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.directory", OP_PREFIX, a_tokenType);
+ applet_dir = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (applet_dir == NULL || strlen(applet_dir) == 0) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "Failed to read applet directory parameter %s", configname);
+ o_status = STATUS_ERROR_MISCONFIGURATION;
+ r = false;
+ goto loser;
+ }
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, a_tokenType);
+ connid = RA::GetConfigStore()->GetConfigAsString(configname);
+ RA::Debug(FN, "TKS connection id =%s", connid);
+ //StatusUpdate(a_session, a_extensions, 5, "PROGRESS_UPGRADE_APPLET");
+
+ if (rc = UpgradeApplet(a_session, (char *) OP_PREFIX, (char*) a_tokenType,
+ o_major_version, o_minor_version,
+ g_applet_target_version,
+ applet_dir, security_level,
+ connid, a_extensions,
+ 5,
+ 12,
+ keyVersion) != 1) {
+
+ RA::Debug(FN, "applet upgrade failed");
+ /**
+ * Bugscape #55709: Re-select Net Key Applet ONLY on failure.
+ */
+ SelectApplet(a_session, 0x04, 0x00, a_aid);
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid, "enrollment", "failure", "applet upgrade error", "", a_tokenType);
+ o_status = STATUS_ERROR_UPGRADE_APPLET;
+ r = false;
+
+ if (rc == -1) {
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ a_userid, a_cuid, a_msn, "Failure", "enrollment",
+ *keyVersion != NULL? *keyVersion : "", o_current_applet_on_token, g_applet_target_version, "failed to setup secure channel");
+ } else {
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ a_userid, a_cuid, a_msn, "Success", "enrollment",
+ *keyVersion != NULL? *keyVersion : "", o_current_applet_on_token, g_applet_target_version, "setup secure channel");
+ }
+
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ a_userid, a_cuid, a_msn, "Failure", "enrollment",
+ *keyVersion != NULL? *keyVersion : "",
+ o_current_applet_on_token, g_applet_target_version,
+ "applet upgrade");
+
+ goto loser;
+ } else {
+ // there may be a better place to do this, but worth testing here
+ // RA::tdb_update(a_cuid, g_applet_target_version);
+ }
+
+ // Upgrade Applet reported success
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ a_userid, a_cuid, a_msn, "Success", "enrollment",
+ *keyVersion != NULL? *keyVersion : "", o_current_applet_on_token, g_applet_target_version, "setup secure channel");
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ a_userid, a_cuid, a_msn, "Success", "enrollment",
+ *keyVersion != NULL? *keyVersion : "",
+ o_current_applet_on_token, g_applet_target_version,
+ "applet upgrade");
+
+ o_current_applet_on_token = strdup(g_applet_target_version);
+
+ token_status = GetStatus(a_session, 0x00, 0x00);
+ if (token_status == NULL) {
+ RA::Error(FN, "Get Status Failed");
+ o_status = STATUS_ERROR_SECURE_CHANNEL; // XXX
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid, "enrollment", "failure", "secure channel error", "", a_tokenType);
+ r = false;
+ goto loser;
+ }
+
+ o_major_version = ((BYTE*)*token_status)[2]; // applet version
+ o_minor_version = ((BYTE*)*token_status)[3]; // not protocol version
+loser:
+ if( token_status != NULL ) {
+ delete token_status;
+ }
+ }
+ } else {
+ RA::Debug(FN, "Applet Upgrade has been disabled.");
+ }
+ return r;
+}
+
+/**
+ * Authenticate user with LDAP plugin
+ * @return true if authentication was successful
+ */
+bool RA_Enroll_Processor::AuthenticateUserLDAP(
+ RA_Session *a_session,
+ NameValueSet *a_extensions,
+ char *a_cuid,
+ AuthenticationEntry *a_auth,
+ AuthParams *&login,
+ RA_Status &o_status,
+ const char *a_token_type
+)
+{
+ const char *FN = "RA_Enroll_Processor::AuthenticateUserLDAP";
+ int retry_limit = a_auth->GetAuthentication()->GetNumOfRetries();
+ int retries = 0;
+ int rc;
+ bool r=false;
+
+ RA::Debug(LL_PER_PDU, FN, "LDAP_Authentication is invoked.");
+ rc = a_auth->GetAuthentication()->Authenticate(login);
+
+ RA::Debug(FN, "Authenticate returned: %d", rc);
+
+ // rc: (0:login correct) (-1:LDAP error) (-2:User not found) (-3:Password error)
+
+ // XXX replace with proper enums
+ // XXX evaluate rc==0 as specific case - this is success, it shouldn't be the default
+
+ while ((rc == TPS_AUTH_ERROR_USERNOTFOUND ||
+ rc == TPS_AUTH_ERROR_PASSWORDINCORRECT )
+ && (retries < retry_limit)) {
+ login = RequestLogin(a_session, 0 /* invalid_pw */, 0 /* blocked */);
+ retries++;
+ if (login != NULL)
+ rc = a_auth->GetAuthentication()->Authenticate(login);
+ }
+
+ switch (rc) {
+ case TPS_AUTH_OK:
+ RA::Debug(LL_PER_PDU, FN, "Authentication successful.");
+ r=true;
+ break;
+ case TPS_AUTH_ERROR_LDAP:
+ RA::Error(FN, "Authentication failed. LDAP Error");
+ o_status = STATUS_ERROR_LDAP_CONN;
+ RA::Debug(LL_PER_PDU, FN, "Authentication status=%d rc=%d", o_status,rc);
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid, "enrollment", "failure", "authentication error", "", a_token_type);
+ r = false;
+ break;
+ case TPS_AUTH_ERROR_USERNOTFOUND:
+ RA::Error(FN, "Authentication failed. User not found");
+ o_status = STATUS_ERROR_LOGIN;
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid, "enrollment", "failure", "authentication error", "", a_token_type);
+ r = false;
+ break;
+ case TPS_AUTH_ERROR_PASSWORDINCORRECT:
+ RA::Error(FN, "Authentication failed. Password Incorrect");
+ o_status = STATUS_ERROR_LOGIN;
+ RA::Debug(LL_PER_PDU, FN, "Authentication status=%d rc=%d", o_status,rc);
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid, "enrollment", "failure", "authentication error", "", a_token_type);
+ r = false;
+ break;
+ default:
+ RA::Error(FN, "Undefined LDAP Auth Error.");
+ r = false;
+ break;
+ }
+
+ return r;
+}
+
+/**
+ * Request Login info and user id from user, if necessary
+ * This call will allocate a new Login structure,
+ * and a char* for the user id. The caller is responsible
+ * for freeing this memory
+ * @return true of success, false if failure
+ */
+bool RA_Enroll_Processor::RequestUserId(
+ RA_Session * a_session,
+ NameValueSet *a_extensions,
+ const char * a_configname,
+ const char * a_tokenType,
+ char *a_cuid,
+ AuthParams *& o_login, const char *&o_userid, RA_Status &o_status)
+{
+
+ if (RA::GetConfigStore()->GetConfigAsBool(a_configname, 1)) {
+ if (a_extensions != NULL &&
+ a_extensions->GetValue("extendedLoginRequest") != NULL)
+ {
+ // XXX - extendedLoginRequest
+ RA::Debug("RA_Enroll_Processor::RequestUserId",
+ "Extended Login Request detected");
+ AuthenticationEntry *entry = GetAuthenticationEntry(
+ OP_PREFIX, a_configname, a_tokenType);
+ char **params = NULL;
+ char pb[1024];
+ char *locale = NULL;
+ if (a_extensions != NULL &&
+ a_extensions->GetValue("locale") != NULL)
+ {
+ locale = a_extensions->GetValue("locale");
+ } else {
+ locale = ( char * ) "en"; /* default to english */
+ }
+ int n = entry->GetAuthentication()->GetNumOfParamNames();
+ if (n > 0) {
+ RA::Debug("RA_Enroll_Processor::RequestUserId",
+ "Extended Login Request detected n=%d", n);
+ params = (char **) PR_Malloc(n);
+ for (int i = 0; i < n; i++) {
+ sprintf(pb,"id=%s&name=%s&desc=%s&type=%s&option=%s",
+ entry->GetAuthentication()->GetParamID(i),
+ entry->GetAuthentication()->GetParamName(i, locale),
+ entry->GetAuthentication()->GetParamDescription(i, locale),
+ entry->GetAuthentication()->GetParamType(i),
+ entry->GetAuthentication()->GetParamOption(i)
+ );
+ params[i] = PL_strdup(pb);
+ RA::Debug("RA_Enroll_Processor::RequestUserId",
+ "params[i]=%s", params[i]);
+ }
+ }
+ RA::Debug("RA_Enroll_Processor::RequestUserId", "Extended Login Request detected calling RequestExtendedLogin() locale=%s", locale);
+
+ char *title = PL_strdup(entry->GetAuthentication()->GetTitle(locale));
+ RA::Debug("RA_Enroll_Processor::RequestUserId", "title=%s", title);
+ char *description = PL_strdup(entry->GetAuthentication()->GetDescription(locale));
+ RA::Debug("RA_Enroll_Processor::RequestUserId", "description=%s", description);
+ o_login = RequestExtendedLogin(a_session, 0 /* invalid_pw */, 0 /* blocked */, params, n, title, description);
+
+ if (params != NULL) {
+ for (int nn=0; nn < n; nn++) {
+ if (params[nn] != NULL) {
+ PL_strfree(params[nn]);
+ params[nn] = NULL;
+ }
+ }
+ free(params);
+ params = NULL;
+ }
+
+ if (title != NULL) {
+ PL_strfree(title);
+ title = NULL;
+ }
+
+ if (description != NULL) {
+ PL_strfree(description);
+ description = NULL;
+ }
+
+ if (o_login == NULL) {
+ RA::Error("RA_Enroll_Processor::Process",
+ "login not provided");
+ o_status = STATUS_ERROR_LOGIN;
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid,
+ "enrollment", "failure", "login not found", "", a_tokenType);
+ return false;
+ }
+
+ RA::Debug("RA_Enroll_Processor::RequestUserId",
+ "Extended Login Request detected calling RequestExtendedLogin() login=%x", o_login);
+ o_userid = PL_strdup( o_login->GetUID() );
+ RA::Debug("RA_Enroll_Processor::Process",
+ "userid = '%s'", o_userid);
+ } else {
+ o_login = RequestLogin(a_session, 0 /* invalid_pw */, 0 /* blocked */);
+ if (o_login == NULL) {
+ RA::Error("RA_Enroll_Processor::Process",
+ "login not provided");
+ o_status = STATUS_ERROR_LOGIN;
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid,
+ "enrollment", "failure", "login not found", o_userid, a_tokenType);
+ return false;
+ }
+ o_userid = PL_strdup( o_login->GetUID() );
+ RA::Debug("RA_Enroll_Processor::Process",
+ "userid = '%s'", o_userid);
+ }
+ }
+ return true;
+}
+
+/**
+ * Authenticate the user with the configured authentication plugin
+ * @return true if authentication successful
+ */
+
+bool RA_Enroll_Processor::AuthenticateUser(
+ RA_Session * a_session,
+ const char * a_configname,
+ char *a_cuid,
+ NameValueSet *a_extensions,
+ const char *a_tokenType,
+ AuthParams *& a_login, const char *&o_userid, RA_Status &o_status
+ )
+{
+ bool r=false;
+
+ RA::Debug("RA_Enroll_Processor::AuthenticateUser", "started");
+ if (RA::GetConfigStore()->GetConfigAsBool(a_configname, false)) {
+ if (a_login == NULL) {
+ RA::Error("RA_Enroll_Processor::AuthenticateUser", "Login Request Disabled. Authentication failed.");
+ o_status = STATUS_ERROR_LOGIN;
+ goto loser;
+ }
+
+ RA::Debug("RA_Enroll_Processor::AuthenticateUser",
+ "Authentication enabled");
+ char configname[256];
+ PR_snprintf((char *)configname, 256, "%s.%s.auth.id", OP_PREFIX, a_tokenType);
+ const char *authid = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (authid == NULL) {
+ o_status = STATUS_ERROR_LOGIN;
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid, "enrollment", "failure", "login not found", "", a_tokenType);
+ goto loser;
+ }
+ AuthenticationEntry *auth = RA::GetAuth(authid);
+
+ if (auth == NULL) {
+ o_status = STATUS_ERROR_LOGIN;
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid, "enrollment", "failure", "authentication error", "", a_tokenType);
+ goto loser;
+ }
+
+ StatusUpdate(a_session, a_extensions, 2, "PROGRESS_START_AUTHENTICATION");
+
+ char *type = auth->GetType();
+ if (type == NULL) {
+ o_status = STATUS_ERROR_LOGIN;
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid, "enrollment", "failure", "authentication is missing param type", "", a_tokenType);
+ r = false;
+ goto loser;
+ }
+
+ if (strcmp(type, "LDAP_Authentication") == 0) {
+ RA::Debug("RA_Enroll_Processor::AuthenticateUser", "LDAP started");
+ r = AuthenticateUserLDAP(a_session, a_extensions, a_cuid, auth, a_login, o_status, a_tokenType);
+ o_status = STATUS_ERROR_LOGIN;
+ goto loser;
+ } else {
+ RA::Error("RA_Enroll_Processor::AuthenticateUser", "No Authentication type was found.");
+ o_status = STATUS_ERROR_LOGIN;
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid, "enrollment", "failure", "authentication error", "", a_tokenType);
+ r = false;
+ goto loser;
+ }
+ } else {
+ r = true;
+ RA::Debug("RA_Enroll_Processor::AuthenticateUser",
+ "Authentication has been disabled.");
+ }
+ loser:
+ return r;
+}
+
+
+
+
+ /**
+ * Checks if the token has the required key version.
+ * If not, we can swap out the keys on the token with another
+ * set of keys
+ */
+
+/* XXX AID's should be member variables */
+bool RA_Enroll_Processor::CheckAndUpgradeSymKeys(
+ //RA_Session * a_session,
+ //NameValueSet *a_extensions,
+ //const char * a_configname,
+ //char *a_cuid,
+ RA_Session *a_session,
+ NameValueSet* a_extensions,
+ char *a_cuid,
+ const char *a_tokenType,
+ char *a_msn,
+ const char *a_applet_version,
+ const char *a_userid,
+ const char *a_key_version,
+ Buffer *a_cardmanagerAID, /* in */
+ Buffer *a_appletAID, /* in */
+ Secure_Channel *&o_channel, /* out */
+ RA_Status &o_status /* out */
+ )
+{
+ char *FN = ( char * ) "RA_EnrollProcessor::CheckAndUpgradeSymKeys";
+ char configname[256];
+ const char *connid = NULL;
+ const char *tksid = NULL;
+ int rc;
+ bool r = false;
+ Buffer key_data_set;
+ char audit_msg[512] = "";
+ char curVer[10];
+ char newVer[10];
+
+ char *curKeyInfoStr = NULL;
+ char *newVersionStr = NULL;
+
+ // the TKS is responsible for doing much of the symmetric keys update
+ // so lets find which TKS we're talking about TKS now.
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, a_tokenType);
+ tksid = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ PR_snprintf((char *)configname, 256,"%s.%s.update.symmetricKeys.enable", OP_PREFIX, a_tokenType);
+
+ RA::Debug(FN, "Symmetric Keys %s", configname);
+
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 0)) {
+
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "tokenType=%s configured to update symmetric keys", a_tokenType);
+
+ // the requiredVersion config parameter indicates what key version
+ // the token should have before further operations. If the token
+ // has an older version, we try to change it.
+ PR_snprintf((char *)configname, 256,
+ "%s.%s.update.symmetricKeys.requiredVersion", OP_PREFIX, a_tokenType);
+
+ int requiredV = RA::GetConfigStore()->GetConfigAsInt(configname, 0x00);
+
+ // If there was a secure channel set up, let's clear it out
+ if( o_channel != NULL ) {
+ delete o_channel;
+ o_channel = NULL;
+ }
+ // try to make a secure channel with the 'requiredVersion' keys
+ // If this fails, we know we will have to attempt an upgrade
+ // of the keys
+ PR_snprintf((char *)configname, 256,"channel.defKeyIndex");
+ int defKeyIndex = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ o_channel = SetupSecureChannel(a_session,
+ requiredV,
+ defKeyIndex /* default key index */, tksid);
+
+ // If that failed, we need to find out what version of keys
+ // are on the token
+ if (o_channel != NULL) {
+ r = true;
+ } else {
+ /**
+ * Select Card Manager for Put Key operation.
+ */
+ SelectApplet(a_session, 0x04, 0x00, a_cardmanagerAID);
+ /* if the key of the required version is
+ * not found, create them.
+ */
+ // This sends a InitializeUpdate request to the token.
+ // We tell the token to use whatever it thinks is the
+ // default key version (0). It will return the version
+ // of the key it actually used later. (This is accessed
+ // with GetKeyInfoData below)
+ // [ Note: This is not explained very well in the manual
+ // The token can have multiple sets of symmetric keys
+ // Each set is given a version number, which I think is
+ // better thought of as a SLOT. One key slot is populated
+ // with a set of keys when the token is manufactured.
+ // This is then designated as the default key set version.
+ // Later, we will write a new key set with PutKey, and
+ // set it to be the new default]
+ PR_snprintf((char *)configname, 256,"channel.defKeyVersion");
+ int defKeyVer = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ PR_snprintf((char *)configname, 256,"channel.defKeyIndex");
+ int defKeyIndex = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ o_channel = SetupSecureChannel(a_session,
+ defKeyVer, /* default key version */
+ defKeyIndex /* default key index */, tksid);
+
+ if (o_channel == NULL) {
+ PR_snprintf(audit_msg, 512, "enrollment processing, failed to create secure channel");
+
+ RA::Error(FN, "failed to establish secure channel");
+ o_status = STATUS_ERROR_SECURE_CHANNEL;
+ goto loser;
+ }
+
+ /* Complete the secure channel handshake */
+ /* XXX need real enumeration of error codes here */
+ rc = o_channel->ExternalAuthenticate();
+ if (rc != 1) {
+ RA::Error(FN, "External authentication in secure channel failed");
+ o_status = STATUS_ERROR_EXTERNAL_AUTH;
+ /* XXX should print out error codes */
+ PR_snprintf(audit_msg, 512, "enrollment processing, external authentication error");
+ goto loser;
+ }
+
+ // Assemble the Buffer with the version information
+ // The second byte is the key offset, which is always 1
+ BYTE nv[2] = { requiredV, 0x01 };
+ Buffer newVersion(nv, 2);
+
+ // GetKeyInfoData will return a buffer which is bytes 11,12 of
+ // the data structure on page 89 of Cyberflex Access Programmer's
+ // Guide
+ // Byte 0 is the key set version.
+ // Byte 1 is the index into that key set
+ Buffer curKeyInfo = o_channel->GetKeyInfoData();
+
+
+ // This code makes a call to the TKS to get a new key set for
+ // the token. The new key set data is written to the Buffer
+ // key_data_set.
+ PR_snprintf((char *)configname, 256,"%s.%s.tks.conn", OP_PREFIX, a_tokenType);
+ connid = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ rc = CreateKeySetData(
+ o_channel->GetKeyDiversificationData(),
+ curKeyInfo,
+ newVersion,
+ key_data_set, connid);
+ if (rc != 1) {
+ RA::Error(FN, "failed to create new key set");
+ o_status = STATUS_ERROR_CREATE_CARDMGR;
+ PR_snprintf(audit_msg, 512, "enrollment processing, create card key error");
+ goto loser;
+ }
+
+ StatusUpdate(a_session, a_extensions, 13, "PROGRESS_PUT_KEY");
+
+ // sends a PutKey PDU with the new key set to change the
+ // keys on the token
+ BYTE curVersion = ((BYTE*)curKeyInfo)[0];
+ BYTE curIndex = ((BYTE*)curKeyInfo)[1];
+ rc = o_channel->PutKeys(a_session,
+ curVersion,
+ curIndex,
+ &key_data_set);
+
+
+ curKeyInfoStr = Util::Buffer2String(curKeyInfo);
+ newVersionStr = Util::Buffer2String(newVersion);
+
+ if(curKeyInfoStr != NULL && strlen(curKeyInfoStr) >= 2) {
+ curVer[0] = curKeyInfoStr[0]; curVer[1] = curKeyInfoStr[1]; curVer[2] = 0;
+ }
+ else {
+ curVer[0] = 0;
+ }
+
+ if(newVersionStr != NULL && strlen(newVersionStr) >= 2) {
+ newVer[0] = newVersionStr[0] ; newVer[1] = newVersionStr[1] ; newVer[2] = 0;
+ }
+ else {
+ newVer[0] = 0;
+ }
+
+
+ if (rc!=0) {
+ RA::Audit(EV_KEY_CHANGEOVER, AUDIT_MSG_KEY_CHANGEOVER,
+ a_userid != NULL ? a_userid : "", a_cuid != NULL ? a_cuid : "", a_msn != NULL ? a_msn : "", "Failure", "enrollment",
+ a_applet_version != NULL ? a_applet_version : "", curVer, newVer,
+ "key changeover");
+
+ if ((a_cuid != NULL) && (a_tokenType != NULL)) {
+ RA::tdb_activity(a_session->GetRemoteIP(),
+ a_cuid,
+ "enrollment",
+ "failure",
+ "key changeover failed",
+ a_userid != NULL? a_userid : "",
+ a_tokenType);
+ }
+ goto loser;
+ } else {
+ RA::Audit(EV_KEY_CHANGEOVER, AUDIT_MSG_KEY_CHANGEOVER,
+ a_userid != NULL ? a_userid : "", a_cuid != NULL ? a_cuid : "", a_msn != NULL ? a_msn : "", "Success", "enrollment",
+ a_applet_version != NULL ? a_applet_version : "", curVer, newVer,
+ "key changeover");
+ }
+
+ /**
+ * Re-select the Applet.
+ */
+ SelectApplet(a_session, 0x04, 0x00, a_appletAID);
+ if( o_channel != NULL ) {
+ delete o_channel;
+ o_channel = NULL;
+ }
+
+ // Make a new secure channel with the new symmetric keys
+ o_channel = SetupSecureChannel(a_session, requiredV,
+ defKeyIndex /* default key index */, tksid);
+ if (o_channel == NULL) {
+ RA::Error(FN, "failed to establish secure channel after reselect");
+ o_status = STATUS_ERROR_CREATE_CARDMGR;
+ PR_snprintf(audit_msg, 512, "enrollment processing, secure channel setup error after reselect");
+ goto loser;
+ } else {
+ RA::Debug(FN, "Key Upgrade has completed successfully.");
+ r = true; // Success!!
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ a_userid != NULL ? a_userid : "", a_cuid != NULL ? a_cuid : "",
+ a_msn != NULL ? a_msn : "", "success", "enrollment", a_applet_version != NULL ? a_applet_version : "",
+ newVer, "enrollment processing, key upgrade completed");
+ }
+
+ }
+ } else {
+
+ RA::Debug(FN, "Key Upgrade has been disabled.");
+
+ if( o_channel != NULL ) {
+ delete o_channel;
+ o_channel = NULL;
+ }
+ PR_snprintf((char *)configname, 256,"channel.defKeyVersion");
+ int defKeyVer = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ PR_snprintf((char *)configname, 256,"channel.defKeyIndex");
+ int defKeyIndex = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ o_channel = SetupSecureChannel(a_session,
+ defKeyVer,
+ defKeyIndex /* default key index */, tksid);
+ r = true; // Sucess!!
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ a_userid, a_cuid, a_msn, "success", "enrollment", a_applet_version,
+ a_key_version != NULL? a_key_version: "",
+ "enrollment processing, key upgrade disabled");
+ }
+loser:
+
+ if (curKeyInfoStr != NULL) {
+ PR_Free( (char *) curKeyInfoStr);
+ curKeyInfoStr = NULL;
+ }
+
+ if (newVersionStr != NULL) {
+ PR_Free( (char *) newVersionStr);
+ newVersionStr = NULL;
+ }
+
+ if (strlen(audit_msg) > 0) { // a failure occurred
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ a_userid != NULL ? a_userid : "",
+ a_cuid != NULL ? a_cuid : "",
+ a_msn != NULL ? a_msn : "",
+ "failure",
+ "enrollment",
+ a_applet_version != NULL ? a_applet_version : "",
+ a_key_version != NULL? a_key_version : "",
+ audit_msg);
+
+ if ((a_cuid != NULL) && (a_tokenType != NULL)) {
+ RA::tdb_activity(a_session->GetRemoteIP(),
+ a_cuid,
+ "enrollment",
+ "failure",
+ audit_msg,
+ a_userid != NULL? a_userid : "",
+ a_tokenType);
+ }
+ }
+
+ return r;
+}
+
+/**
+ * Processes the current session.
+ */
+TPS_PUBLIC RA_Status RA_Enroll_Processor::Process(RA_Session *session, NameValueSet *extensions)
+{
+ char *FN = ( char * ) "RA_Enroll_Processor::Process";
+ char configname[256];
+ char *cuid = NULL;
+ char *msn = NULL;
+ PRIntervalTime start, end;
+ RA_Status status = STATUS_NO_ERROR;
+ int rc = -1;
+ Secure_Channel *channel = NULL;
+ Buffer kdd;
+ AuthParams *login = NULL;
+ char *new_pin = NULL;
+#define PLAINTEXT_CHALLENGE_SIZE 16
+#define WRAPPED_CHALLENGE_SIZE 16
+ Buffer *plaintext_challenge =
+ new Buffer(PLAINTEXT_CHALLENGE_SIZE, (BYTE)0);
+ Buffer *wrapped_challenge = new Buffer(WRAPPED_CHALLENGE_SIZE, (BYTE)0);
+ Buffer *key_check = new Buffer(0, (BYTE)0);
+ const char *tokenType = NULL;
+
+ //SecurityLevel security_level = SECURE_MSG_MAC_ENC;
+ BYTE major_version = 0x0;
+ BYTE minor_version = 0x0;
+ BYTE app_major_version = 0x0;
+ BYTE app_minor_version = 0x0;
+ int isPinPresent = 0;
+ Buffer *object = NULL;
+ int seq = 0x00;
+ unsigned long lastFormatVersion = 0x00;
+ unsigned long lastObjectVersion = 0x00;
+ int foundLastObjectVersion = 0;
+ int pkcs11obj_enable = 0;
+ int compress = 0;
+ NameValueSet nv;
+ int o_certNums = 0;
+
+ CertEnroll *certEnroll = NULL;
+
+ Buffer *token_status = NULL;
+ char* appletVersion = NULL;
+ char *final_applet_version = NULL;
+
+ char *keyVersion = PL_strdup( "" );
+ const char *userid = PL_strdup( "" );
+ char *token_state = PL_strdup("inactive");
+ char *khex = NULL;
+
+ Buffer host_challenge = Buffer(8, (BYTE)0);
+ Buffer key_diversification_data;
+ Buffer key_info_data;
+ Buffer card_challenge;
+ Buffer card_cryptogram;
+ const char *connid = NULL;
+ const char *tksid = NULL;
+ const char *authid = NULL;
+ PKCS11Obj *pkcs11objx = NULL;
+ Buffer labelBuffer;
+ char activity_msg[4096];
+ char audit_msg[512] = "";
+
+ Buffer *CardManagerAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_CARDMGR_INSTANCE_AID,
+ RA::CFG_DEF_CARDMGR_INSTANCE_AID);
+ Buffer *NetKeyAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_NETKEY_INSTANCE_AID,
+ RA::CFG_DEF_NETKEY_INSTANCE_AID);
+ Buffer token_cuid;
+ int maxRetries = 3;
+ const char *pattern = NULL;
+ char *label = NULL;
+ CERTCertificate **certificates = NULL;
+ char **ktypes = NULL;
+ char **origins = NULL;
+ char **tokenTypes = NULL;
+ char *tokentype = NULL;
+ char *profile_state = NULL;
+ RA_Status st;
+ bool renewed = false;
+ bool do_force_format = false;
+
+ RA::Debug("RA_Enroll_Processor::Process", "Client %s",
+ session->GetRemoteIP());
+ RA::Debug(LL_PER_PDU, FN, "Begin enroll process");
+
+ // XXX need to validate all user input (convert to 'string' types)
+ // to ensure that no buffer overruns
+ start = PR_IntervalNow();
+
+ /* Get the card serial number */
+ if (!GetCardManagerAppletInfo(session, CardManagerAID, st, msn, cuid, token_cuid)) goto loser;
+
+ /* Get the applet version information */
+ if (!GetAppletInfo(session, NetKeyAID,
+ /*by ref*/ major_version, minor_version,
+ app_major_version, app_minor_version )) goto loser;
+
+ if (!GetTokenType(OP_PREFIX, major_version, minor_version,
+ cuid, msn, extensions,
+ status, tokenType)) { /* last two are 'out' params */
+ /* ADE figure out what to do here for this line*/
+ // RA::tdb_activity(session->GetRemoteIP(), cuid, "enrollment", "failure", "token type not found", "");
+ goto loser;
+ }
+
+ // check if profile is enabled here
+ PR_snprintf((char *)configname, 256, "config.Profiles.%s.state", tokenType);
+ profile_state = (char *) RA::GetConfigStore()->GetConfigAsString(configname);
+ if ((profile_state != NULL) && (PL_strcmp(profile_state, "Enabled") != 0)) {
+ RA::Error(FN, "Profile %s Disabled for CUID %s", tokenType, cuid);
+ status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "profile %s disabled", tokenType);
+ goto loser;
+ }
+
+ if (RA::ra_is_token_present(cuid)) {
+ RA::Debug(FN, "Found token %s", cuid);
+ if (RA::ra_is_tus_db_entry_disabled(cuid)) {
+ RA::Error(FN, "CUID %s Disabled", cuid);
+ status = STATUS_ERROR_DISABLED_TOKEN;
+ PR_snprintf(audit_msg, 512, "token disabled");
+ goto loser;
+ }
+
+ // at this point, token is either active or uninitialized (formatted)
+ // or the adminstrator has called for a force format.
+
+ do_force_format = RA::ra_force_token_format(cuid);
+
+ RA::Debug("RA_Enroll_Processor::Process","force format flag %d", do_force_format);
+
+ if (!RA::ra_allow_token_reenroll(cuid) &&
+ !RA::ra_allow_token_renew(cuid) &&
+ !do_force_format) {
+ RA::Error(FN, "CUID %s Re-Enrolled Disallowed", cuid);
+ status = STATUS_ERROR_DISABLED_TOKEN;
+ PR_snprintf(audit_msg, 512, "token re-enrollment or renewal disallowed");
+ goto loser;
+ }
+ } else {
+ RA::Debug(FN, "Not Found token %s", cuid);
+ // This is a new token. We need to check our policy to see
+ // if we should allow enrollment. raidzilla #57414
+ PR_snprintf((char *)configname, 256, "%s.allowUnknownToken",
+ OP_PREFIX);
+ if (!RA::GetConfigStore()->GetConfigAsBool(configname, 1)) {
+ RA::Error(FN, "CUID %s Enroll Unknown Token", cuid);
+ status = STATUS_ERROR_DISABLED_TOKEN;
+ PR_snprintf(audit_msg, 512, "unknown token disallowed");
+ goto loser;
+ }
+ }
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL ? keyVersion : "",
+ "token enabled");
+
+
+ /* XXX - this comment does not belong here
+ *
+ * This is very risky to call initialize and then
+ * external authenticate later on.
+ * The token will be locked if no external authenticate
+ * follows the initialize update.
+ */
+
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn",
+ OP_PREFIX, tokenType);
+ tksid = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (tksid == NULL) {
+ RA::Error(FN, "TKS Connection Parameter %s Not Found", configname);
+ status = STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "token type TKS connection parameter not found");
+ goto loser;
+ }
+
+ /* figure some more information about the applet version */
+ /* XXX should probably move this further down, since the results
+ of this function aren't used til much later */
+ if (!FormatAppletVersionInfo(session, tokenType, cuid,
+ app_major_version, app_minor_version,
+ status,
+ final_applet_version /*out */)) {
+ PR_snprintf(audit_msg, 512, "FormatAppletVersionInfo error");
+ goto loser;
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.loginRequest.enable", OP_PREFIX, tokenType);
+ if (!RequestUserId(session, extensions, configname, tokenType, cuid, login, userid, status)){
+ PR_snprintf(audit_msg, 512, "RequestUserId error");
+ goto loser;
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.auth.enable", OP_PREFIX, tokenType);
+
+ if (!AuthenticateUser(session, configname, cuid, extensions,
+ tokenType, login, userid, status)){
+ PR_snprintf(audit_msg, 512, "AuthenticateUser error");
+ goto loser;
+ }
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL ? keyVersion : "",
+ "token login successful");
+
+ // get authid for audit log
+ PR_snprintf((char *)configname, 256, "%s.%s.auth.id", OP_PREFIX, tokenType);
+ authid = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ StatusUpdate(session, extensions, 4, "PROGRESS_APPLET_UPGRADE");
+
+ if(do_force_format) {
+ bool skip_auth = true;
+ if(Format(session,extensions,skip_auth) != STATUS_NO_ERROR ) {
+ PR_snprintf(audit_msg,512, "ForceUpgradeApplet error");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ goto loser;
+ } else {
+ RA::Debug(LL_PER_CONNECTION, "RA_Enroll_Processor::Process",
+ "after Successful ForceUpdgradeApplet, succeeded!");
+
+ PR_snprintf(audit_msg,512, "ForceUpgradeApplet succeeded as per policy.");
+ status = STATUS_NO_ERROR;
+ goto loser;
+
+ }
+ } else {
+ if (! CheckAndUpgradeApplet(
+ session,
+ extensions,
+ cuid,
+ tokenType,
+ final_applet_version,
+ app_major_version, app_minor_version,
+ //appletVersion,
+ NetKeyAID,
+ msn,
+ userid,
+ status,
+ &keyVersion)) {
+ PR_snprintf(audit_msg, 512, "CheckAndUpgradeApplet error");
+ goto loser;
+ }
+ }
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL ? keyVersion : "",
+ "applet upgraded successfully");
+
+ isPinPresent = IsPinPresent(session, 0x0);
+
+ StatusUpdate(session, extensions, 12, "PROGRESS_KEY_UPGRADE");
+
+ if (!CheckAndUpgradeSymKeys(
+ session,
+ extensions,
+ cuid,
+ tokenType,
+ msn,
+ final_applet_version,
+ userid,
+ keyVersion,
+ CardManagerAID,
+ NetKeyAID,
+ channel,
+ status))
+ {
+ PR_snprintf(audit_msg, 512, "CheckAndUpgradeSymKeys error");
+ goto loser;
+ }
+
+ /* we should have a good channel here */
+ if (channel == NULL) {
+ RA::Error(FN, "no good channel");
+ status = STATUS_ERROR_CREATE_CARDMGR;
+ PR_snprintf(audit_msg, 512, "secure channel setup error");
+ goto loser;
+ }
+
+ if (channel != NULL) {
+ if( keyVersion != NULL ) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+ keyVersion = Util::Buffer2String(channel->GetKeyInfoData());
+ }
+
+ StatusUpdate(session, extensions, 14, "PROGRESS_TOKEN_AUTHENTICATION");
+
+ rc = channel->ExternalAuthenticate();
+ if (rc == -1) {
+ RA::Error(FN, "external authenticate failed");
+ status = STATUS_ERROR_CREATE_CARDMGR;
+ PR_snprintf(audit_msg, 512, "external authentication error");
+ goto loser;
+ }
+
+ RA::Debug(LL_PER_CONNECTION, FN, "after SetupSecureChannel, succeeded");
+
+ PR_snprintf((char *)configname, 256, "%s.%s.pinReset.enable", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 1)) {
+
+ PR_snprintf((char *)configname, 256, "%s.%s.pinReset.pin.minLen", OP_PREFIX, tokenType);
+ unsigned int minlen = RA::GetConfigStore()->GetConfigAsUnsignedInt(configname, 4);
+ PR_snprintf((char *)configname, 256,"%s.%s.pinReset.pin.maxLen", OP_PREFIX, tokenType);
+ unsigned int maxlen = RA::GetConfigStore()->GetConfigAsUnsignedInt(configname, 10);
+
+ new_pin = RequestNewPin(session, minlen, maxlen);
+ if (new_pin == NULL) {
+ RA::Error(FN, "new pin request failed");
+
+ status = STATUS_ERROR_MAC_RESET_PIN_PDU;
+ PR_snprintf(audit_msg, 512, "new pin request error");
+ goto loser;
+ }
+ RA::Debug(LL_PER_CONNECTION, "RA_Enroll_Processor::Process",
+ "after RequestNewPin, succeeded");
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL ? keyVersion : "",
+ "RequestNewPin completed successfully");
+
+ PR_snprintf((char *)configname, 256, "%s.%s.pinReset.enable", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 1)) {
+ if (!isPinPresent) {
+ PR_snprintf((char *)configname, 256, "%s.%s.pinReset.pin.maxRetries", OP_PREFIX, tokenType);
+ maxRetries = RA::GetConfigStore()->GetConfigAsInt(configname, 0x7f);
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "param=%s maxRetries=%d", configname, maxRetries);
+ rc = channel->CreatePin(0x0,
+ maxRetries,
+ RA::GetConfigStore()->GetConfigAsString("create_pin.string", "password"));
+ if (rc == -1) {
+ RA::Error("RA_Enroll_Processor::Process",
+ "create pin failed");
+
+ status = STATUS_ERROR_MAC_RESET_PIN_PDU;
+ PR_snprintf(audit_msg, 512, "create pin request error");
+ goto loser;
+ }
+
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL ? keyVersion : "",
+ "CreatePin completed successfully");
+
+ }
+ }
+
+ rc = channel->ResetPin(0x0, new_pin);
+ if (rc == -1) {
+ RA::Error("RA_Enroll_Processor::Process",
+ "reset pin failed");
+
+ status = STATUS_ERROR_MAC_RESET_PIN_PDU;
+ PR_snprintf(audit_msg, 512, "reset pin request error");
+ goto loser;
+ }
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL ? keyVersion : "",
+ "ResetPin completed successfully");
+ }
+
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "after ResetPin, succeeded");
+
+ // to help testing, we may use fix challenge
+ PR_snprintf((char *)configname, 256, "%s.%s.generateChallenge", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 1)) {
+ /* generate challenge for enrollment */
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Generate Challenge");
+/*
+ random number generation moved to TKS
+ rc = Util::GetRandomChallenge(*plaintext_challenge);
+ if (rc == -1) {
+ RA::Error("RA_Enroll_Processor::Process",
+ "random challenge creation failed");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "enrollment", "failure", "general challenge error", "", tokenType);
+ goto loser;
+ }
+*/
+
+ }
+ kdd = channel->GetKeyDiversificationData();
+ khex = kdd.toHex();
+ RA::Debug("RA_Enroll_Processor::Process", "cuid=%s", khex);
+
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType);
+ connid = RA::GetConfigStore()->GetConfigAsString(configname);
+ /* wrap challenge with KEK key */
+ rc = EncryptData(kdd,
+ channel->GetKeyInfoData(), *plaintext_challenge, *wrapped_challenge, connid);
+ if (rc == -1) {
+ RA::Error("RA_Enroll_Processor::Process",
+ "encryt data failed");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "challenge encryption error");
+ goto loser;
+ }
+ // read objects back
+ PR_snprintf((char *)configname, 256, "%s.%s.pkcs11obj.enable",
+ OP_PREFIX, tokenType);
+ pkcs11obj_enable = RA::GetConfigStore()->GetConfigAsBool(configname, 1);
+
+ if (pkcs11obj_enable) {
+ pkcs11objx = new PKCS11Obj();
+
+ // read old objects
+ seq = 0x00;
+ lastFormatVersion = 0x0100;
+ // lastObjectVersion = 0;
+ if (getRandomNumber(&lastObjectVersion) != SECSuccess) {
+ RA::Error(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Could not generate a random version number...assigning 0x00");
+ lastObjectVersion = 0x00;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "got random version numer: %ul", lastObjectVersion);
+ }
+
+ foundLastObjectVersion = 0;
+ do {
+ object = ListObjects(session, seq);
+ if (object == NULL) {
+ seq = 0;
+ } else {
+ seq = 1; // get next entry
+ Buffer objectID = object->substr(0, 4);
+ Buffer objectLen = object->substr(4, 4);
+ unsigned long objectIDVal =
+ ((((BYTE *)objectID)[0] << 24)) +
+ ((((BYTE *)objectID)[1] << 16)) +
+ ((((BYTE *)objectID)[2] << 8)) +
+ ((((BYTE *)objectID)[3]));
+ unsigned long objectLenVal =
+ ((((BYTE *)objectLen)[0] << 24)) +
+ ((((BYTE *)objectLen)[1] << 16)) +
+ ((((BYTE *)objectLen)[2] << 8)) +
+ ((((BYTE *)objectLen)[3]));
+
+ Buffer *o = channel->ReadObject((BYTE*)objectID, 0,
+ (int)objectLenVal);
+ if (o == NULL) {
+ status = STATUS_ERROR_CREATE_TUS_TOKEN_ENTRY;
+ PR_snprintf(audit_msg, 512, "error in creating token entry");
+ goto loser;
+ }
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "object read from token");
+
+ if (((unsigned char *)objectID)[0] == 'z' &&
+ ((unsigned char *)objectID)[1] == '0') {
+ lastFormatVersion = (((BYTE*)*o)[0] << 8) +
+ (((BYTE*)*o)[1]);
+ lastObjectVersion = (((BYTE*)*o)[2] << 8) +
+ (((BYTE*)*o)[3]);
+ foundLastObjectVersion = 1;
+
+ //
+ delete pkcs11objx;
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "parsing pkcs11obj read from token");
+ pkcs11objx = PKCS11Obj::Parse(o, 0);
+ seq = 0;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "new pkcs11obj");
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(objectIDVal, o);
+ if (objSpec != NULL) {
+ pkcs11objx->AddObjectSpec(objSpec);
+ }
+ }
+
+ delete o;
+ delete object;
+ }
+ } while (seq != 0);
+
+ }
+
+ rc = RA::tdb_add_token_entry((char *)userid, cuid, "uninitialized", tokenType);
+ if (rc == -1) {
+ status = STATUS_ERROR_CREATE_TUS_TOKEN_ENTRY;
+ PR_snprintf(audit_msg, 512, "error in creating uninitialized token entry");
+ goto loser;
+ }
+
+ StatusUpdate(session, extensions, 15, "PROGRESS_PROCESS_PROFILE");
+
+ tokentype = (char *)malloc(256 * sizeof(char)) ;
+ PL_strcpy(tokentype, tokenType);
+ /* generate signing key on netkey */
+ if (!GenerateCertsAfterRecoveryPolicy(login, session, origins, ktypes, tokentype, pkcs11objx,
+ pkcs11obj_enable, extensions, channel, wrapped_challenge,
+ key_check, plaintext_challenge, cuid, msn, final_applet_version,
+ khex, userid, status, certificates, o_certNums, tokenTypes)) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process"," - GenerateCertsAfterRecoveryPolicy returns false");
+ goto loser;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process"," - GenerateCertsAfterRecoveryPolicy returns true");
+ if (status == STATUS_NO_ERROR) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process"," - after GenerateCertsAfterRecoveryPolicy", "status is STATUS_NO_ERROR");
+ if (!GenerateCertificates(login, session, origins, ktypes, tokentype, pkcs11objx,
+ pkcs11obj_enable, extensions, channel, wrapped_challenge,
+ key_check, plaintext_challenge, cuid, msn, final_applet_version,
+ khex, userid, status, certificates, o_certNums, tokenTypes)) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process - after GenerateCertificates"," returns false might as well clean up token.");
+ bool skip_auth = true;
+ Format(session,extensions,skip_auth);
+ goto loser;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process - after GenerateCertificates"," returns true");
+ }
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process - after GenerateCertsAfterRecoveryPolicy", "status is %d", status);
+ }
+ }
+
+ if ((status == STATUS_ERROR_RENEWAL_IS_PROCESSED) &&
+ RA::ra_allow_token_renew(cuid)) {
+ renewed = true;
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "renewal happened.. ");
+ }
+
+ // read objects back
+ if (pkcs11obj_enable) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "pkcs11obj enabled");
+ pkcs11objx->SetFormatVersion(lastFormatVersion);
+ if (foundLastObjectVersion) {
+ while (lastObjectVersion == 0xff) {
+ if (getRandomNumber(&lastObjectVersion) != SECSuccess) {
+ RA::Error(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Encounter 0xff, could not generate a random version number...assigning 0x00");
+ lastObjectVersion = 0x00;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Encounter 0xff, got random version numer: %ul", lastObjectVersion);
+ }
+ }
+
+ pkcs11objx->SetObjectVersion(lastObjectVersion+1);
+ } else {
+ pkcs11objx->SetObjectVersion(lastObjectVersion);
+ }
+ pkcs11objx->SetCUID(token_cuid);
+
+ /* add additional certificate objects */
+ PR_snprintf((char *)configname, 256, "%s.certificates.num",
+ OP_PREFIX);
+ int certNum = RA::GetConfigStore()->GetConfigAsInt(configname);
+ if (certNum > 0) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "about to write certificate chain");
+ }
+ for (int i = 0; i < certNum; i++) {
+
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "root certificate #%d", i);
+
+ PR_snprintf((char *)configname, 256, "%s.certificates.value.%d",
+ OP_PREFIX, i);
+ char *certName = (char *)RA::GetConfigStore()->GetConfigAsString(configname);
+
+ /* retrieve certificate info */
+ PR_snprintf((char *)configname, 256, "%s.certificates.%s.nickName",
+ OP_PREFIX, certName);
+ char *certNickName = (char *)RA::GetConfigStore()->GetConfigAsString(configname);
+ PR_snprintf((char *)configname, 256, "%s.certificates.%s.certId",
+ OP_PREFIX, certName);
+ char *certId = (char *)
+ RA::GetConfigStore()->GetConfigAsString(configname, "C0");
+
+/*
+op.enroll.certificates.num=1
+op.enroll.certificates.value.0=caCert
+op.enroll.certificates.caCert.nickName=caCert0 fpki-tps
+op.enroll.certificates.caCert.certId=C5
+op.enroll.certificates.caCert.certAttrId=c5
+op.enroll.certificates.caCert.label=caCert Label
+ */
+
+ /* retrieve certificate */
+ CERTCertificate *cert = CERT_FindCertByNickname(
+ CERT_GetDefaultCertDB(), certNickName);
+
+ if (cert == NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Cannot find certificate %s", certNickName);
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Found certificate %s", certNickName);
+
+ /* add certificate to z object */
+ Buffer *certBuf = new Buffer((BYTE*)cert->derCert.data,
+ (unsigned int)cert->derCert.len);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Certificate buffer created");
+ ObjectSpec *objSpec = ObjectSpec::ParseFromTokenData(
+ (certId[0] << 24) +
+ (certId[1] << 16), certBuf);
+ pkcs11objx->AddObjectSpec(objSpec);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Certificate object Added to PKCS11 Object");
+
+ /* add PK11 attributes */
+ PR_snprintf((char *)configname, 256, "%s.certificates.%s.label",
+ OP_PREFIX, certName);
+ char *certLabel = (char *)RA::GetConfigStore()->GetConfigAsString(configname);
+ PR_snprintf((char *)configname, 256, "%s.certificates.%s.certAttrId",
+ OP_PREFIX, certName);
+ char *certAttrId = (char *)
+ RA::GetConfigStore()->GetConfigAsString(configname, "c0");
+
+ Buffer *keyid = NULL;
+ if (cert->subjectKeyID.data != NULL) {
+ keyid = new Buffer((BYTE*)cert->subjectKeyID.data,
+ (unsigned int)cert->subjectKeyID.len);
+ } else {
+ SECItem *pubKeyData = PK11_GetPubIndexKeyID(cert) ;
+ SECItem *tmpitem = PK11_MakeIDFromPubKey(pubKeyData);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Got Key ID");
+
+
+ keyid = new Buffer((BYTE*)tmpitem->data,
+ (unsigned int)tmpitem->len);
+ }
+
+ Buffer b = channel->CreatePKCS11CertAttrsBuffer(
+ KEY_TYPE_ENCRYPTION /* not being used */,
+ certAttrId, certLabel, keyid);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Created buffer for PKCS11 cert attributes");
+ objSpec = ObjectSpec::ParseFromTokenData(
+ (certAttrId[0] << 24) +
+ (certAttrId[1] << 16),
+ &b);
+ pkcs11objx->AddObjectSpec(objSpec);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Added PKCS11 certificate attribute");
+ }
+ }
+
+ // build label
+ PR_snprintf((char *)configname, 256, "%s.%s.keyGen.tokenName",
+ OP_PREFIX, tokentype);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "tokenName '%s'",
+ configname);
+ pattern = RA::GetConfigStore()->GetConfigAsString(configname, "$cuid$");
+ nv.Add("cuid", cuid);
+ nv.Add("msn", msn);
+ nv.Add("userid", userid);
+ nv.Add("profileId", tokenType);
+
+ /* populate auth parameters output to nv also */
+ /* so we can reference to the auth parameter by */
+ /* using $auth.cn$, or $auth.mail$ */
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "Check login");
+ if (login != NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "Found login");
+ int s = login->Size();
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "login size=%d", s);
+ for (int x = 0; x < s; x++) {
+ char namebuf[2048];
+ char *name = login->GetNameAt(x);
+ sprintf(namebuf, "auth.%s", name);
+ if (strcmp(name,"PASSWORD") != 0) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "Exposed %s=%s", namebuf, login->GetValue(name));
+ }
+ nv.Add(namebuf, login->GetValue(name));
+ }
+ }
+ label = MapPattern(&nv, (char *) pattern);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "labelName '%s'",
+ label);
+ labelBuffer = Buffer((BYTE*)label, strlen(label));
+ pkcs11objx->SetTokenName(labelBuffer);
+
+ // write PKCS11 Obj
+ BYTE objid[4];
+
+ objid[0] = 'z';
+ objid[1] = '0';
+ objid[2] = 0;
+ objid[3] = 0;
+ Buffer xb;
+
+ PR_snprintf((char *)configname, 256, "%s.%s.pkcs11obj.compress.enable",
+ OP_PREFIX, tokentype);
+ compress = RA::GetConfigStore()->GetConfigAsBool(configname, 1);
+
+ if (compress) {
+ xb = pkcs11objx->GetCompressedData();
+ RA::Debug("RA_Enroll_Processor::Process PKCSData", "Compressed Data");
+ } else {
+ xb = pkcs11objx->GetData();
+ RA::Debug("RA_Enroll_Processor::Process PKCSData", "Uncompressed Data");
+ }
+ RA::DebugBuffer("RA_Enroll_Processor::Process PKCSData", "PKCS Data=", &xb);
+
+
+ if(xb.size() == 0) {
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ RA::Debug("RA_Enroll_Processor::Failure to get token object!"," failed");
+ PR_snprintf(audit_msg, 512, "channel createObject failed");
+ goto loser;
+ }
+
+ if((int) xb.size() > totalAvailableMemory) {
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ RA::Debug("RA_Enroll_Processor::Failure pkcs11 object may exceed applet memory"," failed");
+ PR_snprintf(audit_msg, 512, "Applet memory exceeded when writing out final token data");
+ bool skip_auth = true;
+ if(!renewed) { //Renewal should leave what they have on the token.
+ Format(session,extensions,skip_auth);
+ }
+ goto loser;
+ }
+
+ BYTE perms[6];
+
+ perms[0] = 0xff;
+ perms[1] = 0xff;
+ perms[2] = 0x40;
+ perms[3] = 0x00;
+ perms[4] = 0x40;
+ perms[5] = 0x00;
+
+ if (channel->CreateObject(objid, perms, xb.size()) != 1) {
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ RA::Debug("RA_Enroll_Processor::channel createObject"," failed");
+ PR_snprintf(audit_msg, 512, "channel createObject failed");
+ goto loser;
+ }
+ // channel->CreateObject(objid, xb.size());
+ if (channel->WriteObject(objid, (BYTE*)xb, xb.size()) != 1) {
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ RA::Debug("RA_Enroll_Processor::channel writeObject"," failed");
+ PR_snprintf(audit_msg, 512, "channel writeObject failed");
+ goto loser;
+ }
+ }
+
+ StatusUpdate(session, extensions, 90, "PROGRESS_SET_LIFE_CYCLE_STATE");
+
+ // add issuer info to the token
+ PR_snprintf((char *)configname, 256, "%s.%s.issuerinfo.enable",
+ OP_PREFIX, tokenType);
+ RA::Debug("RA_Enroll_Processor", "Getting %s", configname);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 0)) {
+ if (channel != NULL) {
+ char issuer[224];
+ for (int i = 0; i < 224; i++) {
+ issuer[i] = 0;
+ }
+ PR_snprintf((char *)configname, 256, "%s.%s.issuerinfo.value",
+ OP_PREFIX, tokenType);
+ char *issuer_val = (char*)RA::GetConfigStore()->GetConfigAsString(
+ configname);
+ RA::Debug("RA_Enroll_Processor",
+ "Before pattern substitution mapping is %s", issuer_val);
+ issuer_val = MapPattern(&nv, (char *) issuer_val);
+ RA::Debug("RA_Enroll_Processor",
+ "After pattern substitution mapping is %s", issuer_val);
+ sprintf(issuer, "%s", issuer_val);
+ RA::Debug("RA_Enroll_Processor", "Set Issuer Info %s", issuer_val);
+ Buffer *info = new Buffer((BYTE*)issuer, 224);
+ rc = channel->SetIssuerInfo(info);
+
+ if (info != NULL) {
+ delete info;
+ info = NULL;
+ }
+ }
+ }
+ /* write lifecycle bit */
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "Set Lifecycle State");
+ rc = channel->SetLifecycleState(0x0f);
+ if (rc == -1) {
+ RA::Error("RA_Enroll_Processor::Process",
+ "Set life cycle state failed");
+ status = STATUS_ERROR_MAC_LIFESTYLE_PDU;
+ PR_snprintf(audit_msg, 512, "set life cycle state error");
+ goto loser;
+ }
+
+ rc = channel->Close();
+ if (rc == -1) {
+ RA::Error("RA_Enroll_Processor::Process",
+ "Failed to close channel");
+ status = STATUS_ERROR_CONNECTION;
+ PR_snprintf(audit_msg, 512, "channel not closed");
+ goto loser;
+ }
+
+ StatusUpdate(session, extensions, 100, "PROGRESS_DONE");
+
+ status = STATUS_NO_ERROR;
+
+ sprintf(activity_msg, "applet_version=%s tokenType=%s userid=%s",
+ final_applet_version, tokentype, userid);
+
+ if (renewed) {
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "renewal", "success", activity_msg, userid, tokenType);
+ } else {
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "enrollment", "success", activity_msg, userid, tokenType);
+ }
+ RA::tdb_update((char *)userid, cuid, (char *)final_applet_version, (char *)keyVersion, "active", "", tokenType);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "after tdb_update()");
+
+ RA::tdb_update_certificates(cuid, tokenTypes, (char*)userid, certificates, ktypes, origins, o_certNums);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "after tdb_update_certificates()");
+
+ rc = 1;
+
+ end = PR_IntervalNow();
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "after end");
+
+ /* audit log for successful enrollment */
+ if (renewed) {
+ if (authid != NULL) {
+ PR_snprintf(activity_msg, 4096, "renewal processing completed, authid = %s", authid);
+ } else {
+ PR_snprintf(activity_msg, 4096, "renewal processing completed");
+ }
+ RA::Audit(EV_RENEWAL, AUDIT_MSG_PROC,
+ userid, cuid, msn, "success", "renewal", final_applet_version, keyVersion, activity_msg);
+ } else {
+ if (authid != NULL) {
+ PR_snprintf(activity_msg, 4096, "enrollment processing completed, authid = %s", authid);
+ } else {
+ PR_snprintf(activity_msg, 4096, "enrollment processing completed");
+ }
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid, cuid, msn, "success", "enrollment", final_applet_version, keyVersion, activity_msg);
+ }
+
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "after audit, o_certNums=%d",o_certNums);
+
+loser:
+
+ if (strlen(audit_msg) > 0) { // a failure occurred
+ if (renewed) {
+ RA::Audit(EV_RENEWAL, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "failure",
+ "renewal",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL ? keyVersion : "",
+ audit_msg);
+
+ if ((cuid != NULL) && (tokenType != NULL)) {
+ RA::tdb_activity(session->GetRemoteIP(),
+ cuid,
+ "renewal",
+ "failure",
+ audit_msg,
+ userid != NULL? userid : "",
+ tokenType);
+ }
+ } else {
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "failure",
+ "enrollment",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL ? keyVersion : "",
+ audit_msg);
+
+ if ((cuid != NULL) && (tokenType != NULL)) {
+ RA::tdb_activity(session->GetRemoteIP(),
+ cuid,
+ "enrollment",
+ "failure",
+ audit_msg,
+ userid != NULL? userid : "",
+ tokenType);
+ }
+ }
+ }
+
+ if (tokenTypes != NULL) {
+ for (int nn=0; nn<o_certNums; nn++) {
+ if (tokenTypes[nn] != NULL)
+ PL_strfree(tokenTypes[nn]);
+ tokenTypes[nn] = NULL;
+ }
+ free(tokenTypes);
+ tokenTypes = NULL;
+ }
+ if (certificates != NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "before CERT_DestroyCertificate. certNums=%d", o_certNums);
+ for (int i=0;i < o_certNums; i++) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "CERT_DestroyCertificate: i=%d", i);
+ if (certificates[i] != NULL) {
+ CERT_DestroyCertificate(certificates[i]);
+ }
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "CERT_DestroyCertificate: i=%i done", i);
+ }
+ free(certificates);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "after CERT_DestroyCertificate");
+ }
+
+ if( certEnroll != NULL ) {
+ delete certEnroll;
+ certEnroll = NULL;
+ }
+
+ if (ktypes != NULL) {
+ for (int nn=0; nn < o_certNums; nn++) {
+ if (ktypes[nn] != NULL)
+ PL_strfree(ktypes[nn]);
+ ktypes[nn] = NULL;
+ }
+ free(ktypes);
+ ktypes = NULL;
+ }
+
+ if (origins != NULL) {
+ for (int nn=0; nn < o_certNums; nn++) {
+ if (origins[nn] != NULL)
+ PL_strfree(origins[nn]);
+ origins[nn] = NULL;
+ }
+ free(origins);
+ origins = NULL;
+ }
+
+ if( CardManagerAID != NULL ) {
+ delete CardManagerAID;
+ CardManagerAID = NULL;
+ }
+
+ if( NetKeyAID != NULL ) {
+ delete NetKeyAID;
+ NetKeyAID = NULL;
+ }
+
+ if( login != NULL ) {
+ delete login;
+ login = NULL;
+ }
+
+ if( channel != NULL ) {
+ delete channel;
+ channel = NULL;
+ }
+
+ if( new_pin != NULL ) {
+ PL_strfree( new_pin );
+ new_pin = NULL;
+ }
+
+ if( key_check != NULL ) {
+ delete key_check;
+ key_check = NULL;
+ }
+
+ if( wrapped_challenge != NULL ) {
+ delete wrapped_challenge;
+ wrapped_challenge = NULL;
+ }
+
+ if( plaintext_challenge != NULL ) {
+ delete plaintext_challenge;
+ plaintext_challenge = NULL;
+ }
+
+ if( token_status != NULL ) {
+ delete token_status;
+ token_status = NULL;
+ }
+
+ if( final_applet_version != NULL ) {
+ PR_Free( (char *) final_applet_version );
+ final_applet_version = NULL;
+ }
+
+ if( appletVersion != NULL ) {
+ PR_Free( (char *) appletVersion );
+ appletVersion = NULL;
+ }
+ if( khex != NULL ) {
+ PR_Free( khex );
+ khex = NULL;
+ }
+ if( keyVersion != NULL ) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+ if( userid != NULL ) {
+ PR_Free( (char *) userid );
+ userid = NULL;
+ }
+ if (token_state != NULL) {
+ PR_Free((char *)token_state);
+ token_state = NULL;
+ }
+ if( cuid != NULL ) {
+ PR_Free( cuid );
+ cuid = NULL;
+ }
+ if( msn != NULL ) {
+ PR_Free( msn );
+ msn = NULL;
+ }
+ if( label != NULL ) {
+ PL_strfree( (char *) label );
+ label = NULL;
+ }
+ if (tokentype != NULL) {
+ PR_Free(tokentype);
+ }
+ if (pkcs11objx != NULL) {
+ delete pkcs11objx;
+ }
+
+#ifdef MEM_PROFILING
+ MEM_dump_unfree();
+#endif
+
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "returning status");
+ return status;
+}
+
+
+bool RA_Enroll_Processor::GenerateCertificates(AuthParams *login, RA_Session *session, char **&origins, char **&ktypes,
+ char *tokenType, PKCS11Obj *pkcs11objx, int pkcs11obj_enable,
+ NameValueSet *extensions, Secure_Channel *channel, Buffer *wrapped_challenge,
+ Buffer *key_check, Buffer *plaintext_challenge, char *cuid, char *msn,
+ const char *final_applet_version, char *khex, const char *userid, RA_Status &o_status,
+ CERTCertificate **&certificates, int &o_certNums, char **&tokenTypes) {
+
+ bool noFailedCerts = true;
+ bool r=true;
+ int keyTypeNum = 0;
+ int i = 0;
+ char configname[256];
+ const char *FN = "RA_Enroll_Processor::GenerateCertificates";
+ RA_Status lastErrorStatus = STATUS_NO_ERROR;
+
+
+ RA::Debug(LL_PER_CONNECTION,FN, "tokenType=%s", tokenType);
+ PR_snprintf((char *)configname, 256, "%s.%s.keyGen.keyType.num", OP_PREFIX, tokenType);
+ keyTypeNum = RA::GetConfigStore()->GetConfigAsInt(configname);
+ if (keyTypeNum == 0) {
+ r = false;
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Profile parameters are not found");
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ goto loser;
+ }
+
+ ktypes = (char **) malloc (sizeof(char *) * keyTypeNum);
+ origins = (char **) malloc (sizeof(char *) * keyTypeNum);
+ tokenTypes = (char **) malloc (sizeof(char *) * keyTypeNum);
+
+ certificates = (CERTCertificate **) malloc (sizeof(CERTCertificate *) * keyTypeNum);
+ o_certNums = keyTypeNum;
+ for (i=0; i<keyTypeNum; i++) {
+ certificates[i] = NULL;
+ ktypes[i] = NULL;
+ origins[i] = NULL;
+ tokenTypes[i] = NULL;
+
+ }
+ for (i=0; i<keyTypeNum; i++) {
+
+ PR_snprintf((char *)configname, 256, "%s.%s.keyGen.keyType.value.%d", OP_PREFIX, tokenType, i);
+ const char *keyTypeValue = RA::GetConfigStore()->GetConfigAsString(configname, "signing");
+
+ r = GenerateCertificate(login,keyTypeNum, keyTypeValue, i, session, origins, ktypes, tokenType,
+ pkcs11objx, pkcs11obj_enable, extensions, channel, wrapped_challenge,
+ key_check, plaintext_challenge, cuid, msn, final_applet_version,
+ khex, userid, o_status, certificates);
+
+ RA::Debug("GenerateCertificates","configname %s result %d",configname,r);
+
+ tokenTypes[i] = PL_strdup(tokenType);
+ if(r == false) {
+ noFailedCerts = false;
+ lastErrorStatus = o_status;
+ break;
+ }
+
+ }
+
+ if (noFailedCerts == true) {
+ //In this special case of re-enroll
+ //Revoke current certs for this token
+ // before the just enrolled certs are written to the db
+ char error_msg[512];
+ bool success = RevokeCertificates(session, cuid,error_msg,(char *)final_applet_version,
+ NULL,(char *)tokenType,(char *)userid,o_status
+ );
+
+ RA::Debug("GenerateCertificates","Revoke result %d ",(int) success);
+
+ if (!success) {
+ //Don't blow the whole thing up for this.
+ RA::Debug("GenerateCertificates","Revocation failure %s ",error_msg);
+ }
+
+ }
+ loser:
+ if(lastErrorStatus != STATUS_NO_ERROR) {
+ o_status = lastErrorStatus;
+ }
+ return noFailedCerts;
+}
+
+bool RA_Enroll_Processor::GenerateCertificate(AuthParams *login, int keyTypeNum, const char *keyTypeValue, int i, RA_Session *session,
+ char **origins, char **ktypes, char *tokenType, PKCS11Obj *pkcs11objx, int pkcs11obj_enable,
+ NameValueSet *extensions, Secure_Channel *channel, Buffer *wrapped_challenge,
+ Buffer *key_check, Buffer *plaintext_challenge, char *cuid, char *msn,
+ const char *final_applet_version, char *khex, const char *userid,
+ RA_Status &o_status, CERTCertificate **certificates)
+{
+ bool r = true;
+ char configname[256];
+ char keyTypePrefix[200];
+ const char *FN="RA_Enroll_Processor::GenerateCertificate";
+
+ PR_snprintf((char *)keyTypePrefix, 256, "%s.%s.keyGen.%s", OP_PREFIX, tokenType, keyTypeValue);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::GenerateCertificate","keyTypePrefix is %s",keyTypePrefix);
+ PR_snprintf((char *)configname, 256, "%s.ca.profileId", keyTypePrefix);
+ const char *profileId = RA::GetConfigStore()->GetConfigAsString(configname, "");
+ PR_snprintf((char *)configname, 256,"%s.certId", keyTypePrefix);
+ const char *certId = RA::GetConfigStore()->GetConfigAsString(configname, "C0");
+ PR_snprintf((char *)configname, 256, "%s.certAttrId", keyTypePrefix);
+ const char *certAttrId = RA::GetConfigStore()->GetConfigAsString(configname, "c0");
+ PR_snprintf((char *)configname, 256, "%s.privateKeyAttrId", keyTypePrefix);
+ const char *priKeyAttrId = RA::GetConfigStore()->GetConfigAsString(configname, "k0");
+ PR_snprintf((char *)configname, 256,"%s.publicKeyAttrId", keyTypePrefix);
+ const char *pubKeyAttrId = RA::GetConfigStore()->GetConfigAsString(configname, "k1");
+ PR_snprintf((char *)configname, 256, "%s.keySize", keyTypePrefix);
+ int keySize = RA::GetConfigStore()->GetConfigAsInt(configname, 1024);
+
+ PR_snprintf((char *)configname, 256, "%s.publisherId", keyTypePrefix);
+ const char *publisherId = RA::GetConfigStore()->GetConfigAsString(configname, NULL);
+
+ PR_snprintf((char *)configname, 256, "%s.keyUsage", keyTypePrefix);
+ int keyUsage = RA::GetConfigStore()->GetConfigAsInt(configname, 0);
+ PR_snprintf((char *)configname, 256, "%s.keyUser", keyTypePrefix);
+ int keyUser = RA::GetConfigStore()->GetConfigAsInt(configname, 0);
+ PR_snprintf((char *)configname, 256, "%s.privateKeyNumber", keyTypePrefix);
+ int priKeyNumber = RA::GetConfigStore()->GetConfigAsInt(configname, 0);
+ PR_snprintf((char *)configname, 256, "%s.publicKeyNumber", keyTypePrefix);
+ int pubKeyNumber = RA::GetConfigStore()->GetConfigAsInt(configname, 1);
+
+
+ // get key capabilites to determine if the key type is SIGNING,
+ // ENCRYPTION, or SIGNING_AND_ENCRYPTION
+ PR_snprintf((char *)configname, 256, "%s.private.keyCapabilities.sign", keyTypePrefix);
+ bool isSigning = RA::GetConfigStore()->GetConfigAsBool(configname);
+ PR_snprintf((char *)configname, 256, "%s.public.keyCapabilities.encrypt", keyTypePrefix);
+ bool isEncrypt = RA::GetConfigStore()->GetConfigAsBool(configname);
+ int keyTypeEnum = 0;
+
+ if ((isSigning) &&
+ (isEncrypt)) {
+ keyTypeEnum = KEY_TYPE_SIGNING_AND_ENCRYPTION;
+ } else if (isSigning) {
+ keyTypeEnum = KEY_TYPE_SIGNING;
+ } else if (isEncrypt) {
+ keyTypeEnum = KEY_TYPE_ENCRYPTION;
+ }
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "key type is %d",keyTypeEnum);
+
+ PR_snprintf((char *)configname, 256, "%s.ca.conn", keyTypePrefix);
+ const char *caconnid = RA::GetConfigStore()->GetConfigAsString(configname);
+ certificates[i] = NULL;
+ ktypes[i] = NULL;
+ origins[i] = NULL;
+
+ o_status = DoEnrollment(login, session, certificates, origins, ktypes, pkcs11obj_enable,
+ pkcs11objx, extensions, i, keyTypeNum,
+ 15 /* start progress */,
+ 90 /* end progress */, channel, wrapped_challenge,
+ tokenType,
+ keyTypeValue,
+ key_check,
+ plaintext_challenge,
+ cuid,
+ msn,
+ khex, (TokenKeyType)keyTypeEnum, profileId, userid, certId,publisherId, certAttrId, priKeyAttrId,
+ pubKeyAttrId, (keyUser << 4)+priKeyNumber,
+ (keyUsage << 4)+pubKeyNumber, keySize, caconnid, keyTypePrefix,(char *)final_applet_version);
+
+ if (o_status != STATUS_NO_ERROR) {
+ r = false;
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Got a status error from DoEnrollment: %d", o_status);
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "enrollment", "failure", "enrollment error", "", tokenType);
+ goto loser;
+ }
+
+ loser:
+
+ return r;
+}
+
+bool RA_Enroll_Processor::GenerateCertsAfterRecoveryPolicy(AuthParams *login, RA_Session *session, char **&origins, char **&ktypes,
+ char *&tokenType, PKCS11Obj *pkcs11objx, int pkcs11obj_enable,
+ NameValueSet *extensions, Secure_Channel *channel, Buffer *wrapped_challenge,
+ Buffer *key_check, Buffer *plaintext_challenge, char *cuid, char *msn,
+ const char *final_applet_version, char *khex, const char *userid, RA_Status &o_status,
+ CERTCertificate **&certificates, int &o_certNums, char **&tokenTypes)
+{
+ LDAPMessage *ldapResult = NULL;
+ LDAPMessage *e = NULL;
+ int nEntries = 0;
+ char filter[512];
+ char configname[512];
+ char tokenStatus[100];
+ char *tokenid = NULL;
+ int rc = -1;
+ bool r=true;
+ o_status = STATUS_NO_ERROR;
+ char *origTokenType = NULL;
+
+ const char *FN="RA_Enroll_Process::GenerateCertsAfterRecoveryPolicy";
+ PR_snprintf(filter, 512, "tokenUserID=%s", userid);
+
+ rc = RA::ra_find_tus_token_entries_no_vlv(filter, &ldapResult, 1);
+
+ if (rc != LDAP_SUCCESS) {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Cant find any tokens associated with the userid=%s. "
+ "There should be at least one token.", userid);
+ r = false;
+ o_status = STATUS_ERROR_INACTIVE_TOKEN_NOT_FOUND;
+ goto loser;
+ } else {
+ nEntries = RA::ra_get_number_of_entries(ldapResult);
+ for (e = RA::ra_get_first_entry(ldapResult); e != NULL; e = RA::ra_get_next_entry(e)) {
+ struct berval ** attr_values = RA::ra_get_attribute_values(e, "tokenStatus");
+
+ if ((attr_values == NULL) || (attr_values[0] == NULL)) {
+ RA::Debug(LL_PER_CONNECTION,FN, "Error obtaining token status");
+ r = false;
+ o_status = STATUS_ERROR_BAD_STATUS;
+ if (attr_values != NULL) {
+ RA::ra_free_values(attr_values);
+ attr_values = NULL;
+ }
+ goto loser;
+ }
+
+ RA::Debug(LL_PER_CONNECTION,FN, "tokenStatus = %s",
+ attr_values[0]->bv_val);
+
+ strncpy(tokenStatus, attr_values[0]->bv_val, 100);
+ // free attr_values
+ if (attr_values != NULL) {
+ RA::ra_free_values(attr_values);
+ attr_values = NULL;
+ }
+ tokenid = RA::ra_get_token_id(e);
+ RA::Debug(LL_PER_CONNECTION,FN, "tokenID = %s", tokenid);
+ int cmp_result = PL_strcasecmp(tokenid, cuid);
+ free(tokenid);
+ if (cmp_result == 0) {
+ if (PL_strcasecmp(tokenStatus, "uninitialized") == 0 ) {
+ if (nEntries == 1) {
+ // need to do enrollment outside
+ break;
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "There are multiple token entries for user %s.", userid);
+
+ if (RA::ra_tus_has_active_tokens((char *)userid) == 0) {
+ r = false;
+ o_status = STATUS_ERROR_HAS_AT_LEAST_ONE_ACTIVE_TOKEN;
+ RA::Debug(LL_PER_CONNECTION,FN, "User already has one active token.");
+ goto loser;
+ } else {
+ // 1) current token is in active state
+ // 2) there are no other active tokens for this user
+ // 3) that means the previous one is the lost one
+ // get the most recent previous token:
+ LDAPMessage *prev = RA::ra_get_next_entry(e);
+ char *reason = RA::ra_get_token_reason(prev);
+ char *lostTokenCUID = RA::ra_get_token_id(prev);
+
+ // if the previous one is lost, then check lost reason
+ origTokenType = PL_strdup(tokenType);
+ if (PL_strcasecmp(reason, "keyCompromise") == 0) {
+ r = ProcessRecovery(login, reason, session, origins, ktypes,
+ tokenType, pkcs11objx, pkcs11obj_enable,
+ extensions, channel, wrapped_challenge,
+ key_check, plaintext_challenge, cuid, msn,
+ final_applet_version, khex, userid,
+ o_status, certificates, lostTokenCUID, o_certNums, tokenTypes, origTokenType);
+
+ break;
+ } else if (PL_strcasecmp(reason, "onHold") == 0) {
+ // then the inactive one becomes the temp token
+ // No recovery scheme, basically we are going to
+ // do the brand new enrollment
+ PR_snprintf(configname, 512, "op.enroll.%s.temporaryToken.tokenType", tokenType);
+ char *tempTokenType = (char *)(RA::GetConfigStore()->GetConfigAsString(configname, "userKeyTemporary"));
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Token type for temporary token: %s", tempTokenType);
+ PL_strcpy(tokenType, tempTokenType);
+ r = ProcessRecovery(login, reason, session, origins, ktypes,
+ tokenType, pkcs11objx, pkcs11obj_enable,
+ extensions, channel, wrapped_challenge,
+ key_check, plaintext_challenge, cuid, msn,
+ final_applet_version, khex, userid,
+ o_status, certificates, lostTokenCUID, o_certNums, tokenTypes, origTokenType);
+
+ break;
+ } else if (PL_strcasecmp(reason, "destroyed") == 0) {
+ r = ProcessRecovery(login, reason, session, origins, ktypes,
+ tokenType, pkcs11objx, pkcs11obj_enable,
+ extensions, channel, wrapped_challenge,
+ key_check, plaintext_challenge, cuid, msn,
+ final_applet_version, khex, userid,
+ o_status, certificates, lostTokenCUID, o_certNums, tokenTypes, origTokenType);
+
+ break;
+ } else {
+ r = false;
+ o_status = STATUS_ERROR_NO_SUCH_LOST_REASON;
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "No such lost reason=%s for this cuid=%s",
+ reason, cuid);
+ goto loser;
+ }
+ }
+ }
+ } else if (strcmp(tokenStatus, "active") == 0) {
+ r = true;
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "This is the active token. You can re-enroll if the re-enroll=true; or renew if renew=true.");
+ if (RA::ra_allow_token_renew(cuid)) {
+ // renewal allowed instead of re-enroll
+ r = ProcessRenewal(login, session, ktypes, origins,
+ tokenType, pkcs11objx, pkcs11obj_enable,
+ channel,
+ cuid, msn,
+ final_applet_version, userid,
+ o_status, certificates, o_certNums,
+ tokenTypes);
+ if (r == true) {
+ RA::Debug(LL_PER_CONNECTION,FN, "ProcessRenewal returns true");
+ } else
+ goto loser;
+ }
+ break;
+ } else if (strcmp(tokenStatus, "terminated") == 0) {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "terminated token cuid=%s", cuid);
+ r = false;
+ o_status = STATUS_ERROR_CONTACT_ADMIN;
+ goto loser;
+ } else if (strcmp(tokenStatus, "lost") == 0) {
+ char *reason = RA::ra_get_token_reason(e);
+ if (strcmp(reason, "keyCompromise") == 0) {
+ r = false;
+ o_status = STATUS_ERROR_UNUSABLE_TOKEN_KEYCOMPROMISE;
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "This token cannot be reused because it has been reported lost");
+ goto loser;
+ } else if (strcmp(reason, "onHold") == 0) {
+ if (RA::ra_tus_has_active_tokens((char *)userid) == 0) {
+ r = false;
+ o_status = STATUS_ERROR_HAS_AT_LEAST_ONE_ACTIVE_TOKEN;
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "User already has an active token.");
+ goto loser;
+ } else { // change it back to active token
+ r = false;
+ o_status = STATUS_ERROR_CONTACT_ADMIN;
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "User needs to contact administrator to report lost token (it should be put on Hold).");
+ break;
+ }
+ } else if (strcmp(reason, "destroyed") == 0) {
+ r = false;
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "This destroyed lost case should not be executed because the token is so damaged. It should not get here");
+ o_status = STATUS_ERROR_TOKEN_DISABLED;
+ goto loser;
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "No such lost reason=%s for this cuid=%s", reason, cuid);
+ r = false;
+ o_status = STATUS_ERROR_NO_SUCH_LOST_REASON;
+ goto loser;
+ }
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "No such token status for this cuid=%s", cuid);
+ r = false;
+ o_status = STATUS_ERROR_NO_SUCH_TOKEN_STATE;
+ goto loser;
+ }
+ } else { // cuid != cuid of the current token
+ continue;
+/*
+ if (RA::ra_tus_has_active_tokens((char *)userid) == 0) {
+ r = false;
+ o_status = STATUS_ERROR_HAS_AT_LEAST_ONE_ACTIVE_TOKEN;
+ RA::Debug("RA_Enroll_Processor::GenerateCertsAfterRecoveryPolicy", "You already have one active token.");
+ goto loser;
+ } else
+ continue;
+*/
+ }
+ }
+ }
+
+ loser:
+ if (origTokenType != NULL) {
+ PL_strfree(origTokenType);
+ origTokenType = NULL;
+ }
+ if (rc == 0)
+ if (ldapResult != NULL)
+ ldap_msgfree(ldapResult);
+
+
+RA::Debug("RA_Enroll_Processor::GenerateCertsAfterRecoveryPolicy", "returning boolean = %d", r);
+ return r;
+}
+
+/*
+ * cfu - check if a cert is within the renewal grace period
+ * utilize passed in grace period values.
+ */
+bool RA_Enroll_Processor::isCertRenewable(CERTCertificate *cert, int graceBefore, int graceAfter){
+ PRTime timeBefore, timeAfter, now;
+
+ //Grace period input in days
+ RA::Debug("RA_Enroll_Processor::isCertRenewable","graceBefore %d graceAfter %d",graceBefore,graceAfter);
+ PRTime graceBefore64, graceAfter64,microSecondsPerSecond;
+ PRInt64 graceBeforeSeconds,graceAfterSeconds;
+
+ LL_I2L(microSecondsPerSecond, PR_USEC_PER_SEC);
+
+ //Get number of microseconds in each grace period value.
+ LL_I2L(graceBeforeSeconds, graceBefore * 60 * 60 * 24);
+ LL_I2L(graceAfterSeconds,graceAfter * 60 * 60 * 24);
+
+ LL_MUL(graceBefore64, microSecondsPerSecond,graceBeforeSeconds);
+ LL_MUL(graceAfter64, microSecondsPerSecond,graceAfterSeconds);
+
+ PRTime lowerBound, upperBound;
+
+ DER_DecodeTimeChoice(&timeBefore, &cert->validity.notBefore);
+ DER_DecodeTimeChoice(&timeAfter, &cert->validity.notAfter);
+
+ PrintPRTime(timeBefore,"timeBefore");
+ PrintPRTime(timeAfter,"timeAfter");
+
+ now = PR_Now();
+
+ //Calculate lower and upper legal bounds for time
+ LL_SUB(lowerBound,timeAfter, graceBefore64);
+ LL_ADD(upperBound,timeAfter,graceAfter64);
+
+ PrintPRTime(lowerBound,"lowerBound");
+ PrintPRTime(now,"now");
+ PrintPRTime(upperBound,"upperBound");
+
+ if(LL_CMP(now,>=, lowerBound) && LL_CMP(now,<=,upperBound)) {
+ RA::Debug("RA_Enroll_Processor::isCertRenewable","returning true!");
+ return true;
+ }
+
+ RA::Debug("RA_Enroll_Processor::isCertRenewable","returning false!");
+
+ return false;
+}
+
+/*
+ * cfu
+ * DoRenewal - use i_cert's serial number for renewal
+ * i_cert - cert to renew
+ * o_cert - cert newly issued
+ */
+bool RA_Enroll_Processor::DoRenewal(const char *connid, const char *profileId, CERTCertificate *i_cert,
+CERTCertificate **o_cert, char *error_msg, int *error_code)
+{
+ RA_Status status = STATUS_NO_ERROR;
+ bool r = true;
+ CertEnroll *certRenewal = NULL;
+ Buffer *cert = NULL;
+ char *cert_string = NULL;
+
+ error_msg[0] =0;
+ *error_code=0; //assume undefined
+
+ PRUint64 snum = DER_GetInteger(&(i_cert)->serialNumber);
+ RA::Debug("RA_Enroll_Processor::DoRenewal", "begins renewal for serial number %u with profileId=%s", (int)snum, profileId);
+
+ certRenewal = new CertEnroll();
+ cert = certRenewal->RenewCertificate(snum, connid, profileId, error_msg);
+
+ if (error_msg[0] != 0) { // We can assume a non grace period error here.
+ *error_code = 1;
+ }
+// this is where renewal happens .. audit log for fail/ success here?
+ if (cert == NULL) {
+ r = false;
+ RA::Debug("RA_Enroll_Processor::DoRenewal", "Renewal failed for serial number %d", snum);
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ goto loser;
+ }
+ RA::Debug("RA_Enroll_Processor::DoRenewal", "Renewal suceeded for serial number %d", snum);
+
+ cert_string = (char *) cert->string();
+ *o_cert = CERT_DecodeCertFromPackage((char *) cert_string,
+ (int) cert->size());
+ if (o_cert != NULL) {
+ char msg[2048];
+ RA::ra_tus_print_integer(msg, &(o_cert[0])->serialNumber);
+ RA::Debug("DoRenewal", "Received newly issued Certificate");
+ RA::Debug("DoRenewal serial=", msg);
+ RA::Debug("DoRenewal", "yes");
+ } else {
+ r = false;
+ }
+ free(cert_string);
+
+loser:
+ if( certRenewal != NULL ) {
+ delete certRenewal;
+ certRenewal = NULL;
+ }
+ if( cert != NULL ) {
+ delete cert;
+ cert = NULL;
+ }
+ return r;
+}
+
+#define RENEWAL_FAILURE 1
+#define RENEWAL_FAILURE_GRACE 2
+
+/*
+* Renewal logic
+* 1. Create Optional local TPS grace period per token profile,
+* per token type, such as signing or encryption.
+* This grace period must match how the CA is configured. Ex:
+* op.enroll.userKey.renewal.encryption.enable=true
+* op.enroll.userKey.renewal.encryption.gracePeriod.enable=true
+* op.enroll.userKey.renewal.encryption.gracePeriod.before=30
+* op.enroll.userKey.renewal.encryption.gracePeriod.after=30
+* 2. In case of a grace period failure the code will go on
+* and attempt to renew the next certificate in the list.
+* 3. In case of any other code failure, the code will abort
+* and leave the token untouched, while informing the user
+* with an error message.
+*
+*
+*/
+bool RA_Enroll_Processor::ProcessRenewal(AuthParams *login, RA_Session *session, char **&ktypes,
+ char **&origins,
+ char *tokenType, PKCS11Obj *pkcs11objx, int pkcs11obj_enable,
+ Secure_Channel *channel,
+ const char *cuid, char *msn,
+ const char *final_applet_version, const char *userid,
+ RA_Status &o_status, CERTCertificate **&certificates,
+ int &o_certNums, char **&tokenTypes)
+{
+ bool r = true;
+ o_status = STATUS_ERROR_RENEWAL_IS_PROCESSED;
+ char keyTypePrefix[256];
+ char configname[256];
+ char filter[256];
+ LDAPMessage *result = NULL;
+ const char *pretty_cuid = NULL;
+ char audit_msg[512] = "";
+ char *keyVersion = NULL;
+ int renewal_failure_found = 0;
+
+ int maxCertUpdate = 25;
+ char *renewedCertUpdateList[25];
+ int renewedCertUpdateCount = 0;
+ int renew_error = 0;
+
+ int i = 0;
+ const char *FN="RA_Enroll_Processor::ProcessRenewal";
+
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "starts");
+
+ // get key version for audit logs
+ if (channel != NULL) {
+ if( keyVersion != NULL ) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+ keyVersion = Util::Buffer2String(channel->GetKeyInfoData());
+ }
+
+ // e.g. op.enroll.userKey.renewal.keyType.num
+ // renewal params will just have to match that of the previous
+ // enrollment tps profile. Will try to be smarter later...
+ PR_snprintf(configname, 256, "op.enroll.%s.renewal.keyType.num",
+ tokenType);
+ int keyTypeNum = RA::GetConfigStore()->GetConfigAsInt(configname, -1);
+ if (keyTypeNum == -1) {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "Missing the configuration parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "Missing the configuration parameter for %s", configname);
+ goto loser;
+ }
+
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "keyType.num=%d", keyTypeNum);
+
+ o_certNums = keyTypeNum;
+ certificates = (CERTCertificate **) malloc (sizeof(CERTCertificate *) * keyTypeNum);
+ ktypes = (char **) malloc (sizeof(char *) * keyTypeNum);
+ origins = (char **) malloc (sizeof(char *) * keyTypeNum);
+ tokenTypes = (char **) malloc (sizeof(char *) * keyTypeNum);
+
+ for (i=0; i<keyTypeNum; i++) {
+ certificates[i] = NULL;
+ ktypes[i] = NULL;
+ origins[i] = NULL;
+ tokenTypes[i] = NULL;
+ }
+
+ for (i=0; i<keyTypeNum; i++) {
+ bool renewable = true;
+ // e.g. op.enroll.userKey.renewal.keyType.value.0=signing
+ // e.g. op.enroll.userKey.renewal.keyType.value.1=encryption
+ PR_snprintf(configname, 256, "op.enroll.%s.renewal.keyType.value.%d", tokenType, i);
+ const char *keyTypeValue = (char *)(RA::GetConfigStore()->GetConfigAsString(configname));
+
+ if (keyTypeValue == NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal",
+ "Missing the configuration parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "Missing the configuration parameter for %s", configname);
+ goto loser;
+ }
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "keyType == %s ", keyTypeValue);
+ TokenKeyType key_type = KEY_TYPE_ENCRYPTION;
+ if (strcmp(keyTypeValue, "signing") == 0)
+ key_type = KEY_TYPE_SIGNING;
+ else if (strcmp(keyTypeValue, "encryption") == 0)
+ key_type = KEY_TYPE_ENCRYPTION;
+ else
+ key_type = KEY_TYPE_SIGNING_AND_ENCRYPTION;
+
+ // e.g. op.enroll.userKey.renewal.signing.enable=true
+ PR_snprintf(configname, 256, "op.enroll.%s.renewal.%s.enable", tokenType, keyTypeValue);
+ renewable = RA::GetConfigStore()->GetConfigAsBool(configname);
+
+ if (!renewable) {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "renewal not enabled");
+ continue;
+ }
+
+ // set allowable $$ config patterns
+ NameValueSet nv;
+ pretty_cuid = GetPrettyPrintCUID(cuid);
+
+ nv.Add("pretty_cuid", pretty_cuid);
+ nv.Add("cuid", cuid);
+ nv.Add("msn", msn);
+ nv.Add("userid", userid);
+ //nv.Add("profileId", profileId);
+
+ /* populate auth parameters output to nv also */
+ /* so we can reference to the auth parameter by */
+ /* using $auth.cn$, or $auth.mail$ */
+ if (login != NULL) {
+ int s = login->Size();
+ for (int x = 0; x < s; x++) {
+ char namebuf[2048];
+ char *name = login->GetNameAt(x);
+ sprintf(namebuf, "auth.%s", name);
+ nv.Add(namebuf, login->GetValue(name));
+ }
+ }
+
+ /*
+ * Get certs from the tokendb for this token to find out about
+ * renewal possibility
+ */
+
+
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "Renew the certs for %s", keyTypeValue);
+ PR_snprintf(filter, 256, "(&(tokenKeyType=%s)(tokenID=%s))",
+ keyTypeValue, cuid);
+ int rc = RA::ra_find_tus_certificate_entries_by_order_no_vlv(filter,
+ &result, 1);
+
+ tokenTypes[i] = PL_strdup(tokenType);
+ if (rc == LDAP_SUCCESS) {
+ bool renewed = false;
+ const char *caconnid;
+ const char *profileId;
+ PR_snprintf(keyTypePrefix, 256, "op.enroll.%s.keyGen.%s", tokenType,keyTypeValue);
+ PR_snprintf(configname, 256, "op.enroll.%s.renewal.%s.enable", tokenType, keyTypeValue);
+ PR_snprintf((char *)configname, 256,"op.enroll.%s.renewal.%s.certId", tokenType, keyTypeValue);
+ char *certId = (char *)RA::GetConfigStore()->GetConfigAsString(configname, "C0");
+ PR_snprintf((char *)configname, 256, "op.enroll.%s.renewal.%s.certAttrId", tokenType, keyTypeValue);
+ char *certAttrId = (char *)RA::GetConfigStore()->GetConfigAsString(configname, "c0");
+ //PR_snprintf((char *)configname, 256, "%s.privateKeyAttrId", keyTypePrefix);
+ //const char *priKeyAttrId = RA::GetConfigStore()->GetConfigAsString(configname, "k0");
+ //PR_snprintf((char *)configname, 256,"%s.publicKeyAttrId", keyTypePrefix);
+ //const char *pubKeyAttrId = RA::GetConfigStore()->GetConfigAsString(configname, "k1");
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal",
+ "certId=%s, certAttrId=%s",certId, certAttrId);
+
+ char finalCertId[3];
+ char finalCertAttrId[3];
+
+ finalCertId[0] = certId[0];
+ finalCertId[1] = certId[1];
+ finalCertId[2] = 0;
+
+ finalCertAttrId[0] = certAttrId[0];
+ finalCertAttrId[1] = certAttrId[1];
+ finalCertAttrId[2] = 0;
+
+ LDAPMessage *e= NULL;
+ char *attr_status = NULL;
+ for( e = RA::ra_get_first_entry( result );
+ e != NULL;
+ e = RA::ra_get_next_entry( e ) ) {
+ attr_status = RA::ra_get_cert_status( e );
+ if( (strcmp( attr_status, "revoked" ) == 0) ||
+ (strcmp( attr_status, "renewed" ) == 0) ) {
+ if (attr_status != NULL) {
+ PL_strfree(attr_status);
+ attr_status = NULL;
+ }
+ continue;
+ }
+
+ const char *label= NULL;
+ const char *pattern= NULL;
+ Buffer *certbuf = NULL;
+
+ // retrieve the most recent certificate to start
+
+ CERTCertificate **certs = RA::ra_get_certificates(e);
+ CERTCertificate *o_cert = NULL;
+ SECKEYPublicKey *pk_p = NULL;
+ SECItem si_mod;
+ Buffer *modulus=NULL;
+ SECItem *si_kid = NULL;
+ Buffer *keyid=NULL;
+ SECItem si_exp;
+ Buffer *exponent=NULL;
+ CERTSubjectPublicKeyInfo* spkix = NULL;
+
+ bool graceEnabled = false;
+ int graceBefore = 0;
+ int graceAfter = 0;
+
+ if (certs[0] != NULL) {
+
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal",
+ "Certificate to check for renew");
+
+ // check if renewable (note: CA makes the final decision)
+ /* testing...pass through for now
+ if (!isCertRenewable(certs[0])) {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal",
+ "Cert outside of renewal period");
+ r = false;
+ goto rloser;
+ }
+ */
+
+ // op.enroll.userKey.renewal.signing.ca.conn
+ // op.enroll.userKey.renewal.encryption.ca.conn
+ PR_snprintf(configname, 256,
+ "op.enroll.%s.renewal.%s.ca.conn", tokenType, keyTypeValue);
+ caconnid = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (caconnid == NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal",
+ "Missing the configuration parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "Missing the configuration parameter for %s", configname);
+ goto rloser;
+ }
+
+ // op.enroll.userKey.renewal.signing.ca.profileId
+ // op.enroll.userKey.renewal.encryption.ca.profileId
+ PR_snprintf(configname, 256,
+ "op.enroll.%s.renewal.%s.ca.profileId", tokenType, keyTypeValue);
+ profileId = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (profileId == NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal",
+ "Missing the configuration parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "Missing the configuration parameter for %s", configname);
+ goto rloser;
+ }
+
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal","got profileId=%s",profileId);
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "begin renewal");
+
+
+ PR_snprintf(configname,256,
+ "op.enroll.%s.renewal.%s.gracePeriod.enable",tokenType,keyTypeValue);
+
+ graceEnabled = RA::GetConfigStore()->GetConfigAsBool(configname,0);
+
+ if(graceEnabled) {
+
+ PR_snprintf(configname,256,
+ "op.enroll.%s.renewal.%s.gracePeriod.before",tokenType,keyTypeValue);
+
+ graceBefore = RA::GetConfigStore()->GetConfigAsInt(configname,0);
+
+ PR_snprintf(configname,256,
+ "op.enroll.%s.renewal.%s.gracePeriod.after",tokenType,keyTypeValue);
+
+ graceAfter = RA::GetConfigStore()->GetConfigAsInt(configname,0);
+ // check if renewable (note: CA makes the final decision)
+ if (!isCertRenewable(certs[0],graceBefore,graceAfter)) {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal",
+ "Cert outside of renewal period");
+ renewal_failure_found = RENEWAL_FAILURE_GRACE;
+ //Since this is merely a grace period failure for one cert
+ //let's keep going.
+ r = true;
+ goto rloser;
+ }
+
+ }
+
+ // send renewal request to CA
+ // o_cert is the cert gotten back
+ r = DoRenewal(caconnid, profileId, certs[0], &o_cert, audit_msg, &renew_error);
+ if (r == false) {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "after DoRenewal failure. o_cert %p renew_error %d",o_cert,renew_error);
+ o_status = STATUS_ERROR_MAC_ENROLL_PDU;
+ //Assume a renewal grace failure here since we can't obtain the reason.
+ //This is the most likely error and there is a chance the next renewal may succeed.
+ if ( renew_error == 0) { //Assume undefined error is error coming from CA
+ renewal_failure_found = RENEWAL_FAILURE_GRACE;
+ } else {
+ renewal_failure_found = RENEWAL_FAILURE;
+ }
+ char snum[2048];
+ RA::ra_tus_print_integer(snum, &(certs[0])->serialNumber);
+ RA::Audit(EV_RENEWAL, AUDIT_MSG_PROC_CERT_REQ,
+ userid, cuid, msn, "failure", "renewal", final_applet_version,
+ keyVersion != NULL ? keyVersion : "",
+ snum, caconnid, audit_msg);
+ //Since this is merely a grace period or renewal failure for one cert
+ //let's keep it going
+
+ if (renew_error == 0) { //undefined error means probably grace period, forgive that.
+ r = true;
+ }
+ goto rloser;
+ }
+
+ // got cert...
+
+ // build label
+ PR_snprintf((char *)configname, 256, "%s.%s.keyGen.%s.label",
+ OP_PREFIX, tokenType, keyTypeValue);
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "label '%s'", configname);
+ pattern = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ if(pattern == NULL)
+ {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "no configured cert label!");
+ renewal_failure_found = RENEWAL_FAILURE;
+ PR_snprintf(audit_msg,512, "No cert label configured for cert!");
+ goto rloser;
+ }
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "pattern '%s'",pattern);
+
+ label = MapPattern(&nv, (char *) pattern);
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "label '%s'",label);
+
+ if (o_cert != NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "got cert!!");
+// tmp_c = NSSBase64_EncodeItem(0, 0, 0, &(o_cert)->derCert);
+// RA::Debug("RA_Enroll_Processor::ProcessRenewal", "after NSSBase64_EncodeItem");
+
+ char snum[2048];
+ RA::ra_tus_print_integer(snum, &o_cert->serialNumber);
+ RA::Audit(EV_RENEWAL, AUDIT_MSG_PROC_CERT_REQ,
+ userid, cuid, msn, "success", "renewal", final_applet_version,
+ keyVersion != NULL ? keyVersion : "",
+ snum, caconnid, "certificate renewed");
+ } else {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "no cert!!");
+ PR_snprintf(audit_msg, 512, "No cert returned from DoRenewal");
+ goto rloser;
+ }
+
+ ktypes[i] = PL_strdup(keyTypeValue);
+ origins[i] = PL_strdup(cuid);
+ certificates[i] = o_cert;
+ //o_certNums++;
+
+ // For the encrytion cert we actually need to calculate the proper certId and certAttrId
+ // since we now leave previous encryption certs on the token to allow dencryption of old
+ // Emails by the user.
+
+ if( key_type == KEY_TYPE_ENCRYPTION) {
+
+ int new_cert_id = GetNextFreeCertIdNumber(pkcs11objx);
+
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal",
+ "Encryption cert, calculated new cert id: %d",new_cert_id);
+
+ //Is the calculated cert id reasonable based on the current state of the
+ // token and the expected renewal configuration.
+ if( !(new_cert_id > keyTypeNum ) || new_cert_id > 9) {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "RA_Enroll_Processor::ProcessRenewal","Possible misconfiguration or out of sync token!");
+ PR_snprintf(audit_msg, 512, "Renewal of cert failed, misconfiguration or out of sync token!");
+ renewal_failure_found = RENEWAL_FAILURE;
+ goto rloser;
+
+ }
+
+ finalCertId[0]= 'C';
+ finalCertId[1] = '0' + new_cert_id;
+
+ finalCertAttrId[0] = 'c';
+ finalCertAttrId[1] = '0' + new_cert_id;
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "finalCertId %s finalCertAttrId %s", finalCertId, finalCertAttrId);
+ }
+
+ // write certificate to token
+ certbuf = new Buffer(o_cert->derCert.data, o_cert->derCert.len);
+ if (pkcs11obj_enable)
+ {
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (finalCertId[0] << 24) +
+ (finalCertId[1] << 16),
+ certbuf);
+ pkcs11objx->AddObjectSpec(objSpec);
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Not implemented");
+ renewal_failure_found = RENEWAL_FAILURE;
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: pkcs11obj_enable = false not implemented");
+ goto rloser;
+/*
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "About to create certificate object on token");
+ rc = channel->CreateCertificate(certId, certbuf);
+ if (rc == -1) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Failed to create certificate object on token");
+
+ o_status = STATUS_ERROR_MAC_ENROLL_PDU;
+ goto rloser;
+ }
+*/
+ }
+
+ if (o_cert->subjectKeyID.data != NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "subjectKeyID found in cert");
+//later, add code to check if keys really exist on token!
+ keyid = new Buffer((BYTE*)o_cert->subjectKeyID.data,
+ (unsigned int)o_cert->subjectKeyID.len);
+
+ } else {// should always have keyid
+//use existing original keyid
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "no subjectKeyID found in cert, use existing");
+ keyid = new Buffer((BYTE*)certs[0]->subjectKeyID.data,
+ (unsigned int)certs[0]->subjectKeyID.len);
+ }
+
+ if (pkcs11obj_enable)
+ {
+ Buffer b = channel->CreatePKCS11CertAttrsBuffer(
+ key_type , finalCertAttrId, label, keyid);
+ if (b == NULL) {
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: CreatePKCS11CertAttrsBuffer returns null");
+ renewal_failure_found = RENEWAL_FAILURE;
+ goto rloser;
+ }
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (finalCertAttrId[0] << 24) +
+ (finalCertAttrId[1] << 16),
+ &b);
+ if (objSpec == NULL) {
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: ParseFromTokenData returns null");
+ renewal_failure_found = RENEWAL_FAILURE;
+ goto rloser;
+ }
+
+ //We need to massage the fixedAttributes of this object to allow the CKA_ID value
+ //of the original encryption cert to be available for coolkey to read.
+ // Coolkey only deals in a one byte index 0 - n, ex: "01".
+ // Coolkey uses the final byte of the "fixedAttributes" property of each object
+ // to identify the object. This value needs to be the same for each cert and its
+ // corresponding key pair. See ObjectSpec::ParseAttributes.
+
+ if (key_type == KEY_TYPE_ENCRYPTION) {
+
+ unsigned long currentFixedAttributes = objSpec->GetFixedAttributes();
+ unsigned long modifiedFixedAttributes = currentFixedAttributes;
+
+ // Here we want the original encryption cert's id number.
+ int val = (certId[1] - '0');
+
+ modifiedFixedAttributes &= (BYTE) 0xFFFFFFF0;
+ modifiedFixedAttributes |= (BYTE) val;
+ objSpec->SetFixedAttributes(modifiedFixedAttributes);
+
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal",
+ "original fixed Attributes %lu modified ones %lu",
+ currentFixedAttributes,modifiedFixedAttributes);
+ }
+
+ pkcs11objx->AddObjectSpec(objSpec);
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Not implemented");
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: pkcs11obj_enable = false not implemented");
+ renewal_failure_found = RENEWAL_FAILURE;
+ goto rloser;
+/*
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "About to create PKCS#11 certificate Attributes");
+ rc = channel->CreatePKCS11CertAttrs(keyTypeValue, certAttrId, label, keyid);
+ if (rc == -1) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "PKCS11 Certificate attributes creation failed");
+ o_status = STATUS_ERROR_MAC_ENROLL_PDU;
+ goto rloser;
+ }
+*/
+ }
+
+ spkix = &(o_cert->subjectPublicKeyInfo);
+ if (spkix == NULL) {
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: subjectPublicKeyInfo is null");
+ goto rloser;
+ }
+ pk_p = SECKEY_ExtractPublicKey(spkix);
+ if (pk_p == NULL) {
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: ExtractPublicKey is null");
+ goto rloser;
+ }
+ SECKEY_DestroySubjectPublicKeyInfo(spkix);
+
+ /* fill in keyid, modulus, and exponent */
+
+ si_mod = pk_p->u.rsa.modulus;
+ modulus = new Buffer((BYTE*) si_mod.data, si_mod.len);
+ if (modulus == NULL) {
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: modulus is null");
+ renewal_failure_found = RENEWAL_FAILURE;
+ goto rloser;
+ }
+ spkix = SECKEY_CreateSubjectPublicKeyInfo(pk_p);
+ if (spkix == NULL) {
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: CreateSubjectPublicKeyInfo returns null");
+ renewal_failure_found = RENEWAL_FAILURE;
+ goto rloser;
+ }
+
+ /*
+ * RFC 3279
+ * The keyIdentifier is composed of the 160-bit SHA-1 hash of the
+ * value of the BIT STRING subjectPublicKey (excluding the tag,
+ * length, and number of unused bits).
+ */
+ spkix->subjectPublicKey.len >>= 3;
+ si_kid = PK11_MakeIDFromPubKey(&spkix->subjectPublicKey);
+ if (si_kid == NULL) {
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: si_kid is null");
+ renewal_failure_found = RENEWAL_FAILURE;
+ goto rloser;
+ }
+ spkix->subjectPublicKey.len <<= 3;
+ SECKEY_DestroySubjectPublicKeyInfo(spkix);
+
+ if (keyid == NULL)
+ keyid = new Buffer((BYTE*) si_kid->data, si_kid->len);
+ if (keyid == NULL) {
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: keyid is null");
+ renewal_failure_found = RENEWAL_FAILURE;
+ goto rloser;
+ }
+ si_exp = pk_p->u.rsa.publicExponent;
+ exponent = new Buffer((BYTE*) si_exp.data, si_exp.len);
+ if (exponent == NULL) {
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: exponent is null");
+ renewal_failure_found = RENEWAL_FAILURE;
+ goto rloser;
+ }
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Keyid, modulus and exponent have been extracted from public key");
+
+ renewed = true;
+
+ RA::Audit(EV_RENEWAL, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "renewal",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "Cert written to token successfully");
+
+
+ rloser:
+
+ if( keyid != NULL ) {
+ delete keyid;
+ keyid = NULL;
+ }
+ if( label != NULL ) {
+ PL_strfree( (char *) label );
+ label = NULL;
+ }
+ if(renewal_failure_found == RENEWAL_FAILURE) {
+ RA::Debug("RA_Enroll_Processor_ProcessRenewal", "A renewal in list failed other than grace period error, aborting.");
+ goto loser;
+ }
+ }
+ break;
+ } //for
+ if((strcmp( attr_status, "active" ) == 0) &&
+ renewed) {
+ char *cn = RA::ra_get_cert_cn(e);
+ if(renewedCertUpdateCount < ( maxCertUpdate -1)) //unlikely scenario this fails
+ renewedCertUpdateList[renewedCertUpdateCount++] = PL_strdup(cn);
+ // Let's hold off on the celebration until the end.
+ // RA::ra_update_cert_status(cn, "renewed");
+ if (cn != NULL) {
+ PL_strfree(cn);
+ cn = NULL;
+ }
+ }
+ if( attr_status != NULL ) {
+ PL_strfree( attr_status );
+ attr_status = NULL;
+ }
+ } else {
+ r = false;
+ o_status = STATUS_ERROR_LDAP_CONN;
+ goto loser;
+ }
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal",
+ "Filter to find certificates = %s", filter);
+ }
+
+loser:
+ if (strlen(audit_msg) > 0) { // a failure occurred
+ RA::Audit(EV_RENEWAL, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "failure",
+ "renewal",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ audit_msg);
+ }
+
+ //Let's wait until all the certs are processed to actually update the renewal status
+ RA::Debug("RA_Enroll_Process::ProcessRenewal","renewedCertUpdateCount %d", renewedCertUpdateCount);
+ if(renewedCertUpdateCount > 0) {
+ for(int rr = 0; rr < renewedCertUpdateCount; rr++) {
+ if(renewedCertUpdateList[rr]) {
+ if(renewal_failure_found != RENEWAL_FAILURE) {
+ RA::Debug("RA_Enroll_Process::ProcessRenewal","updating to renewed status of cn= %s", renewedCertUpdateList[rr]);
+ RA::ra_update_cert_status(renewedCertUpdateList[rr],"renewed");
+ }
+ PL_strfree(renewedCertUpdateList[rr]);
+ renewedCertUpdateList[rr] = NULL;
+ }
+ }
+ } else {
+ // All certs failed to renew
+ RA::Debug("RA_Enroll_Process::ProcessRenewal","All certs failed to renew, bailing with error");
+ o_status = STATUS_ERROR_MAC_ENROLL_PDU;
+ r = false;
+
+ }
+
+ if( pretty_cuid != NULL ) {
+ PR_Free( (char *) pretty_cuid );
+ pretty_cuid = NULL;
+ }
+ if( result != NULL ) {
+ ldap_msgfree( result );
+ }
+
+ if( keyVersion != NULL ) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+
+ return r;
+}
+
+bool RA_Enroll_Processor::ProcessRecovery(AuthParams *login, char *reason, RA_Session *session, char **&origins, char **&ktypes,
+ char *tokenType, PKCS11Obj *pkcs11objx, int pkcs11obj_enable,
+ NameValueSet *extensions, Secure_Channel *channel, Buffer *wrapped_challenge,
+ Buffer *key_check, Buffer *plaintext_challenge, char *cuid, char *msn,
+ const char *final_applet_version, char *khex, const char *userid,
+ RA_Status &o_status, CERTCertificate **&certificates, char *lostTokenCUID,
+ int &o_certNums, char **&tokenTypes, char *origTokenType)
+{
+ bool r = true;
+ o_status = STATUS_ERROR_RECOVERY_IS_PROCESSED;
+ char keyTypePrefix[256];
+ char configname[256];
+ char filter[256];
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ char *o_pub = NULL;
+ char *o_priv = NULL;
+ const char *connid = NULL;
+ bool tksServerKeygen = false;
+ bool serverKeygen = false;
+ bool archive = false;
+ const char *pretty_cuid = NULL;
+ char audit_msg[512] = "";
+ char *keyVersion = NULL;
+ char *ivParam = NULL;
+
+ int i = 0;
+ int totalNumCerts = 0;
+ int actualCertIndex = 0;
+ int legalScheme = 0;
+ int isGenerateandRecover = 0;
+ const char *FN="RA_Enroll_Processor::ProcessRecovery";
+
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery","entering...");
+ // get key version for audit logs
+ if (channel != NULL) {
+ if( keyVersion != NULL ) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+ keyVersion = Util::Buffer2String(channel->GetKeyInfoData());
+ }
+
+ PR_snprintf(configname, 256, "op.enroll.%s.keyGen.recovery.%s.keyType.num",
+ tokenType, reason);
+ int keyTypeNum = RA::GetConfigStore()->GetConfigAsInt(configname, -1);
+ if (keyTypeNum == -1) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "Missing the configuration parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ goto loser;
+ }
+
+ //We will have to rifle through the configuration to see if there any recovery operations with
+ //scheme "GenerateNewKeyandRecoverLast" which allows for recovering the old key AND generating a new
+ // one for the encryption type only. If this scheme is present, the number of certs for bump by
+ // 1 for each occurance.
+
+ totalNumCerts = 0;
+ for(i = 0; i<keyTypeNum; i++) {
+ PR_snprintf(configname, 256, "op.enroll.%s.keyGen.recovery.%s.keyType.value.%d", tokenType, reason, i);
+ const char *keyTypeValue = (char *)(RA::GetConfigStore()->GetConfigAsString(configname));
+
+ if (keyTypeValue == NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Missing the configuration parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ goto loser;
+ }
+ PR_snprintf(configname, 256, "op.enroll.%s.keyGen.%s.recovery.%s.scheme", tokenType, keyTypeValue, reason);
+ char *scheme = (char *)(RA::GetConfigStore()->GetConfigAsString(configname));
+ if (scheme == NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Missing the configuration parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ goto loser;
+ }
+
+ //If we are doing "GenerateNewKeyandRecoverLast, we will create two certificates
+ //for that particular round.
+ if(PL_strcasecmp(scheme, "GenerateNewKeyandRecoverLast") == 0) {
+
+ //Make sure someone doesn't try "GenerateNewKeyandRecoverLast" with a signing key.
+
+ if(PL_strcasecmp(keyTypeValue,"encryption" ) != 0) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Invalid config param for %s. Can't use GenerateNewKeyandRecoveLaste scheme with non encryption key",
+ configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ goto loser;
+ }
+ totalNumCerts ++;
+ }
+ totalNumCerts ++;
+ }
+
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery","totalNumCerts %d ",totalNumCerts);
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "keyTypenum=%d", keyTypeNum);
+
+
+ if(!(totalNumCerts > keyTypeNum)) {
+ totalNumCerts = keyTypeNum;
+ }
+
+ o_certNums = totalNumCerts;
+ certificates = (CERTCertificate **) malloc (sizeof(CERTCertificate *) * totalNumCerts);
+ ktypes = (char **) malloc (sizeof(char *) * totalNumCerts);
+ origins = (char **) malloc (sizeof(char *) * totalNumCerts);
+ tokenTypes = (char **) malloc (sizeof(char *) * totalNumCerts);
+
+ for(i = 0; i < totalNumCerts; i++) {
+ ktypes[i] = NULL;
+ origins[i] = NULL;
+ tokenTypes[i] = NULL;
+ certificates[i] = NULL;
+ }
+
+ //Iterate through number of key types. Iteration will be modified in case we have to insert extra
+ //certificates due to the "GenerateNewKeyandRecoverLast" scheme.
+
+ actualCertIndex = 0;
+ legalScheme = 0;
+ for (i=0; i<keyTypeNum; i++) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery","Top cert loop: i %d actualCertIndex %d",i,actualCertIndex);
+ PR_snprintf(configname, 256, "op.enroll.%s.keyGen.recovery.%s.keyType.value.%d", tokenType, reason, i);
+ const char *keyTypeValue = (char *)(RA::GetConfigStore()->GetConfigAsString(configname));
+
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "keyType == %s ", keyTypeValue);
+
+ if (keyTypeValue == NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Missing the configuration parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ goto loser;
+ }
+ PR_snprintf(configname, 256, "op.enroll.%s.keyGen.%s.recovery.%s.scheme", tokenType, keyTypeValue, reason);
+ char *scheme = (char *)(RA::GetConfigStore()->GetConfigAsString(configname));
+ if (scheme == NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Missing the configuration parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ goto loser;
+ }
+
+ // set allowable $$ config patterns
+ NameValueSet nv;
+ pretty_cuid = GetPrettyPrintCUID(cuid);
+
+ nv.Add("pretty_cuid", pretty_cuid);
+ nv.Add("cuid", cuid);
+ nv.Add("msn", msn);
+ nv.Add("userid", userid);
+ //nv.Add("profileId", profileId);
+
+ /* populate auth parameters output to nv also */
+ /* so we can reference to the auth parameter by */
+ /* using $auth.cn$, or $auth.mail$ */
+ if (login != NULL) {
+ int s = login->Size();
+ for (int x = 0; x < s; x++) {
+ char namebuf[2048];
+ char *name = login->GetNameAt(x);
+ sprintf(namebuf, "auth.%s", name);
+ nv.Add(namebuf, login->GetValue(name));
+ }
+ }
+ //Check for the special scheme where we generate a new cert and
+ //recover the last one.
+
+ if(PL_strcasecmp(scheme, "GenerateNewKeyandRecoverLast") == 0) {
+ isGenerateandRecover = 1;
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Scheme %s: GenerateNewKeyandRecoverLast case!",scheme);
+ } else {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Scheme %s: Not GenerateNewKeyandRecoverLast case!",scheme);
+ isGenerateandRecover = 0;
+ }
+
+ if ((PL_strcasecmp(scheme, "GenerateNewKey") == 0) || isGenerateandRecover) {
+ legalScheme = 1;
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "Generate new key for %s", keyTypeValue);
+ r = GenerateCertificate(login, keyTypeNum, keyTypeValue, actualCertIndex, session, origins, ktypes, tokenType,
+ pkcs11objx, pkcs11obj_enable, extensions, channel, wrapped_challenge,
+ key_check, plaintext_challenge, cuid, msn, final_applet_version,
+ khex, userid, o_status, certificates);
+ tokenTypes[actualCertIndex] = PL_strdup(tokenType);
+ if (o_status == STATUS_NO_ERROR)
+ o_status = STATUS_ERROR_RECOVERY_IS_PROCESSED;
+ }
+
+ if ((PL_strcasecmp(scheme, "RecoverLast") == 0) || isGenerateandRecover) {
+ RA::Debug("RA_Enroll_Processor::RecoverLast", "Recover the key for %s", keyTypeValue);
+ // Special case for GenerateandRecover scenario.
+
+ legalScheme = 1;
+ if(isGenerateandRecover) {
+ RA::Debug("RA_Enroll_Processor::RecoverLast",
+ "Generate extra recoverd cert for GenerateNewKeyandRecoverLast");
+
+ actualCertIndex ++;
+ }
+ PR_snprintf(filter, 256, "(&(tokenKeyType=%s)(tokenID=%s))",
+ keyTypeValue, lostTokenCUID);
+ int rc = RA::ra_find_tus_certificate_entries_by_order_no_vlv(filter,
+ &result, 1);
+
+ tokenTypes[actualCertIndex] = PL_strdup(origTokenType);
+ char **attr = (char **) malloc (sizeof(char *) * totalNumCerts);
+ if (rc == LDAP_SUCCESS) {
+ // retrieve the most recent certificate, we just recover the most
+ // recent one
+ e = RA::ra_get_first_entry(result);
+ if (e != NULL) {
+ CERTCertificate **certs = RA::ra_get_certificates(e);
+ if (certs[0] != NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Certificate used to restore the private key");
+ PR_snprintf(configname, 256,
+ "op.enroll.%s.keyGen.%s.serverKeygen.drm.conn", tokenType, keyTypeValue);
+ const char *drmconnid = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (drmconnid == NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Missing the configuration parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "Key Recovery failed. Missing the configuration parameter for %s", configname);
+ goto loser;
+ }
+
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "begin recovery code");
+
+ SECKEYPublicKey *pk_p = NULL;
+ SECItem si_mod;
+ Buffer *modulus=NULL;
+ SECItem *si_kid = NULL;
+ Buffer *keyid=NULL;
+ SECItem si_exp;
+ Buffer *exponent=NULL;
+ CERTSubjectPublicKeyInfo* spkix = NULL;
+
+ //Now we have to get the original config params for the encryption cert and keys
+
+ //XXX these attr functions shouldn't take config params
+ PR_snprintf(keyTypePrefix, 256, "op.enroll.%s.keyGen.encryption", tokenType);
+
+ PR_snprintf((char *)configname, 256, "%s.keySize", keyTypePrefix);
+ int keysize = RA::GetConfigStore()->GetConfigAsInt(configname, 1024);
+
+ PR_snprintf((char *)configname, 256, "%s.keyUsage", keyTypePrefix);
+ int keyUsage = RA::GetConfigStore()->GetConfigAsInt(configname, 0);
+ PR_snprintf((char *)configname, 256, "%s.keyUser", keyTypePrefix);
+ int keyUser = RA::GetConfigStore()->GetConfigAsInt(configname, 0);
+
+ PR_snprintf((char *)configname, 256, "%s.certId",keyTypePrefix);
+
+ const char *origCertId = RA::GetConfigStore()->GetConfigAsString(configname, "C0");
+
+ //actually adjust the crucial values based on this extra certificate
+ //being generated.
+
+ int highestCertId = 0;
+ int newCertId = 0;
+ if(isGenerateandRecover) {
+ //find highest cert id number.
+ for(int j=0; j < keyTypeNum; j++) {
+ PR_snprintf((char *)configname, 256,"%s.certId", keyTypePrefix);
+ const char *cId = RA::GetConfigStore()->GetConfigAsString(configname, "C0");
+ int id_int = 0;
+ if(cId) {
+ id_int = cId[1] - '0';
+ }
+
+ if (id_int > highestCertId)
+ highestCertId = id_int;
+ }
+ highestCertId++;
+ } else {
+ highestCertId = origCertId[1] - '0';
+ }
+
+ newCertId = highestCertId;
+
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery","Calculated new CertID %d.",newCertId);
+
+ char certId[3];
+ char certAttrId[3];
+ char privateKeyAttrId[3];
+ char publicKeyAttrId[3];
+ int pubKeyNumber=0;
+ int priKeyNumber=0;
+
+ certId[0] = 'C';
+ certId[1] = '0' + newCertId;
+ certId[2] = 0;
+
+ certAttrId[0] = 'c';
+ certAttrId[1] = '0' + newCertId;
+ certAttrId[2] = 0;
+
+ pubKeyNumber = 2 * newCertId + 1;
+ priKeyNumber = 2 * newCertId;
+
+ privateKeyAttrId[0] = 'k';
+ privateKeyAttrId[1] = '0' + priKeyNumber;
+ privateKeyAttrId[2] = 0;
+
+ publicKeyAttrId[0] = 'k';
+ publicKeyAttrId[1] = '0' + pubKeyNumber;
+ publicKeyAttrId[2] = 0;
+
+ RA::Debug(
+ "RA_Enroll_Processor::ProcessRecovery",
+ "certId %s certAttrId %s privateKeyAttrId %s publicKeyAtrId %s priKeyNum %d pubKeyNum %d",
+ certId,certAttrId,privateKeyAttrId,publicKeyAttrId,priKeyNumber, pubKeyNumber);
+
+ PR_snprintf((char *)configname, 256, "%s.%s.keyGen.%s.label",
+ OP_PREFIX, tokenType, keyTypeValue);
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "label '%s'", configname);
+ const char *pattern = RA::GetConfigStore()->GetConfigAsString(configname);
+ const char* label = MapPattern(&nv, (char *) pattern);
+
+ BYTE objid[4];
+
+ objid[0] = 0xFF;
+ objid[1] = 0x00;
+ objid[2] = 0xFF;
+ objid[3] = 0xF3;
+
+ char *tmp_c = NULL;
+ if (certs[0] != NULL) {
+ tmp_c = NSSBase64_EncodeItem(0, 0, 0, &(certs[0]->derCert));
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "after NSSBase64_EncodeItem");
+ } else {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "no cert!!");
+ PR_snprintf(audit_msg, 512, "Key Recovery failed. no cert");
+ goto rloser;
+ }
+
+ if ((tmp_c == NULL) || (strcmp(tmp_c,"")==0)) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "NSSBase64_EncodeItem failed");
+ PR_snprintf(audit_msg, 512, "Key Recovery failed. NSSBase64_EncodeItem failed");
+ goto rloser;
+ }
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "NSSBase64_EncodeItem succeeded");
+ attr[0] = PL_strdup(tmp_c);
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "b64 encoded cert =%s",attr[0]);
+
+ if( newCertId > 9) {
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "RA_Enroll_Processor::ProcessRecovery","Possible misconfiguration or out of sync token!");
+ PR_snprintf(audit_msg, 512,
+ "Renewal of cert failed, misconfiguration or out of sync token!");
+ goto rloser;
+ }
+
+ // get serverKeygen and archive, check if they are enabled.
+ PR_snprintf((char *)configname, 256, "%s.%s.keyGen.%s.serverKeygen.enable",
+ OP_PREFIX, tokenType, keyTypeValue);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "looking for config %s", configname);
+ serverKeygen = RA::GetConfigStore()->GetConfigAsBool(configname, 0);
+ PR_snprintf((char *)configname, 256, "%s.%s.keyGen.%s.serverKeygen.archive",
+ OP_PREFIX, tokenType, keyTypeValue);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "looking for config %s", configname);
+ archive = RA::GetConfigStore()->GetConfigAsBool(configname, 0);
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType);
+ connid = RA::GetConfigStore()->GetConfigAsString(configname);
+ tksServerKeygen = false;
+ if (connid != NULL) {
+ PR_snprintf((char *)configname, 256, "conn.%s.serverKeygen", connid);
+ tksServerKeygen = RA::GetConfigStore()->GetConfigAsBool(configname, 0);
+ } else {
+ r = false;
+ o_status = STATUS_ERROR_NO_TKS_CONNID;
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::ProcessRecovery", "Missing tks.connid");
+ PR_snprintf(audit_msg, 512, "Key Recovery failed. Missing tks.connid");
+ goto rloser;
+ }
+
+ if (tksServerKeygen && archive && serverKeygen) {
+ RA::RecoverKey(session, lostTokenCUID, userid,
+ channel->getDrmWrappedDESKey(),
+ attr[0], &o_pub, &o_priv,
+ (char *)drmconnid,&ivParam);
+ } else {
+ r = false;
+ o_status = STATUS_ERROR_KEY_ARCHIVE_OFF;
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::ProcessRecovery", "Archival is turned off");
+ PR_snprintf(audit_msg, 512, "Key Recovery failed. Archival is turned off");
+ goto rloser;
+ }
+
+ if (o_pub == NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::DoEnrollment()", "RecoverKey called, o_pub is NULL");
+ r = false;
+ o_status = STATUS_ERROR_RECOVERY_FAILED;
+ PR_snprintf(audit_msg, 512, "Key Recovery failed. o_pub is NULL");
+ goto rloser;
+ } else
+ RA::Debug(LL_PER_PDU, "DoEnrollment", "o_pub = %s", o_pub);
+
+
+ if (o_priv == NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::DoEnrollment()", "RecoverKey called, o_priv is NULL");
+ /* XXX
+ r = false;
+ o_status = STATUS_ERROR_RECOVERY_FAILED;
+ goto rloser;
+ */
+ } else
+ RA::Debug(LL_PER_PDU, "DoEnrollment", "o_priv = %s", o_priv);
+
+ if (ivParam == NULL) {
+ RA::Debug(LL_PER_CONNECTION,"RA_Enroll_Processor::ProcessRecovery",
+ "ProcessRecovery called, ivParam is NULL");
+ r = false;
+ o_status = STATUS_ERROR_RECOVERY_FAILED;
+ PR_snprintf(audit_msg, 512, "RA_Enroll_Processor::ProcessRecovery called, ivParam is NULL");
+ goto rloser;
+ } else {
+ RA::Debug(LL_PER_CONNECTION,"ProcessRecovery",
+ "ivParam = %s", ivParam);
+ }
+
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::ProcessRecovery()", "key injection for RecoverKey occurs here");
+ /*
+ * the following code converts b64-encoded public key info into SECKEYPublicKey
+ */
+ SECStatus rv;
+ SECItem der;
+ CERTSubjectPublicKeyInfo* spki;
+
+ der.type = (SECItemType) 0; /* initialize it, since convertAsciiToItem does not set it */
+ rv = ATOB_ConvertAsciiToItem (&der, o_pub);
+ if (rv != SECSuccess){
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "after converting public key, rv is failure");
+ SECITEM_FreeItem(&der, PR_FALSE);
+ r = false;
+ o_status = STATUS_ERROR_RECOVERY_FAILED;
+ PR_snprintf(audit_msg, 512, "Key Recovery failed. after converting public key, rv is failure");
+ goto rloser;
+ }else {
+ RA::Debug(LL_PER_PDU, "ProcessRecovery", "item len=%d, item type=%d",der.len, der.type);
+
+ spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&der);
+ SECITEM_FreeItem(&der, PR_FALSE);
+
+ if (spki != NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "after converting public key spki is not NULL");
+ pk_p = SECKEY_ExtractPublicKey(spki);
+ if (pk_p != NULL)
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "after converting public key pk_p is not NULL");
+ else
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "after converting public key, pk_p is NULL");
+ } else
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "after converting public key, spki is NULL");
+
+ }
+ SECKEY_DestroySubjectPublicKeyInfo(spki);
+
+ if( pk_p == NULL ) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "pk_p is NULL; unable to continue");
+ r = false;
+ o_status = STATUS_ERROR_RECOVERY_FAILED;
+ PR_snprintf(audit_msg, 512, "Key Recovery failed. pk_p is NULL; unable to continue");
+ goto rloser;
+ }
+
+ // XXX - Add serial number and public key to audit log
+ //get serial number for audit log
+ //char msg[2048];
+ //RA::ra_tus_print_integer(msg, &certs[0]->serialNumber);
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "key recovered successfully");
+
+
+ /* fill in keyid, modulus, and exponent */
+
+ si_mod = pk_p->u.rsa.modulus;
+ modulus = new Buffer((BYTE*) si_mod.data, si_mod.len);
+
+ spkix = SECKEY_CreateSubjectPublicKeyInfo(pk_p);
+
+ /*
+ * RFC 3279
+ * The keyIdentifier is composed of the 160-bit SHA-1 hash of the
+ * value of the BIT STRING subjectPublicKey (excluding the tag,
+ * length, and number of unused bits).
+ */
+ spkix->subjectPublicKey.len >>= 3;
+ si_kid = PK11_MakeIDFromPubKey(&spkix->subjectPublicKey);
+ spkix->subjectPublicKey.len <<= 3;
+ SECKEY_DestroySubjectPublicKeyInfo(spkix);
+
+ keyid = new Buffer((BYTE*) si_kid->data, si_kid->len);
+ si_exp = pk_p->u.rsa.publicExponent;
+ exponent = new Buffer((BYTE*) si_exp.data, si_exp.len);
+
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ " keyid, modulus and exponent are retrieved");
+
+ ktypes[actualCertIndex] = PL_strdup(keyTypeValue);
+ // We now store the token id of the original token
+ // that generates this certificate so we can
+ // tell if the certificate should be operated
+ // on or not during formation operation
+ origins[actualCertIndex] = PL_strdup(lostTokenCUID);
+ certificates[actualCertIndex] = certs[0];
+
+
+ // Create KeyBlob for private key, but first b64 decode it
+ /* url decode o_priv */
+ {
+ Buffer priv_keyblob;
+ Buffer *decodeKey = Util::URLDecode(o_priv);
+ //RA::DebugBuffer("cfu debug"," private key =",decodeKey);
+ priv_keyblob =
+ Buffer(1, 0x01) + // encryption
+ Buffer(1, 0x09)+ // keytype is RSAPKCS8Pair
+ Buffer(1,(BYTE)(keysize/256)) + // keysize is two bytes
+ Buffer(1,(BYTE)(keysize%256)) +
+ Buffer((BYTE*) *decodeKey, decodeKey->size());
+ delete decodeKey;
+
+ //inject PKCS#8 private key
+ BYTE perms[6];
+
+ perms[0] = 0x40;
+ perms[1] = 0x00;
+ perms[2] = 0x40;
+ perms[3] = 0x00;
+ perms[4] = 0x40;
+ perms[5] = 0x00;
+
+ if (channel->CreateObject(objid, perms, priv_keyblob.size()) != 1) {
+ r = false;
+ PR_snprintf(audit_msg, 512, "Failed to write key to token. CreateObject failed.");
+ goto rloser;
+ }
+
+ if (channel->WriteObject(objid, (BYTE*)priv_keyblob, priv_keyblob.size()) != 1) {
+ r = false;
+ PR_snprintf(audit_msg, 512, "Failed to write key to token. WriteObject failed.");
+ goto rloser;
+ }
+ }
+
+ /* url decode the wrapped kek session key and keycheck*/
+ {
+ Buffer data;
+ /*
+ RA::Debug(LL_PER_PDU, "", "getKekWrappedDESKey() returns =%s", channel->getKekWrappedDESKey());
+ RA::Debug(LL_PER_PDU, "", "getKeycheck() returns =%s", channel->getKeycheck());
+ */
+ Buffer *decodeKey = Util::URLDecode(channel->getKekWrappedDESKey());
+
+ /*
+ RA::Debug(LL_PER_PDU, "", "des key item len=%d",
+ decodeKey->size());
+ RA::DebugBuffer("cfu debug", "DES key =", decodeKey);
+ */
+ char *keycheck = channel->getKeycheck();
+ Buffer *decodeKeyCheck = Util::URLDecode(keycheck);
+ if (keycheck)
+ PL_strfree(keycheck);
+
+ /*
+ RA::Debug(LL_PER_PDU, "", "keycheck item len=%d",
+ decodeKeyCheck->size());
+ RA::DebugBuffer("cfu debug", "key check=", decodeKeyCheck);
+ */
+
+ BYTE alg = 0x80;
+ if(decodeKey && decodeKey->size()) {
+ alg = 0x81;
+ }
+
+ //Get iv data returned by DRM
+
+ Buffer *iv_decoded = Util::URLDecode(ivParam);
+ if (ivParam) {
+ PL_strfree(ivParam);
+ }
+
+ if(iv_decoded == NULL) {
+ r = false;
+ PR_snprintf(audit_msg, 512, "ProcessRecovery: store keys in token failed, iv data not found");
+ delete decodeKey;
+ delete decodeKeyCheck;
+ goto rloser;
+ }
+
+ data =
+ Buffer((BYTE*)objid, 4)+ // object id
+ Buffer(1,alg) +
+ //Buffer(1, 0x08) + // key type is DES3: 8
+ Buffer(1, (BYTE) decodeKey->size()) + // 1 byte length
+ Buffer((BYTE *) *decodeKey, decodeKey->size())+ // key -encrypted to 3des block
+ // check size
+ // key check
+ Buffer(1, (BYTE) decodeKeyCheck->size()) + //keycheck size
+ Buffer((BYTE *) *decodeKeyCheck , decodeKeyCheck->size())+ // keycheck
+ Buffer(1, iv_decoded->size())+ // IV_Length
+ Buffer((BYTE*)*iv_decoded, iv_decoded->size());
+
+ //RA::DebugBuffer("cfu debug", "ImportKeyEnc data buffer =", &data);
+
+ delete decodeKey;
+ delete decodeKeyCheck;
+ delete iv_decoded;
+
+ if (channel->ImportKeyEnc((keyUser << 4)+priKeyNumber,
+ (keyUsage << 4)+pubKeyNumber, &data) != 1) {
+ r = false;
+ PR_snprintf(audit_msg, 512, "Failed to write key to token. ImportKeyEnc failed.");
+ goto rloser;
+ }
+ }
+
+ {
+ Buffer *certbuf = new Buffer(certs[0]->derCert.data, certs[0]->derCert.len);
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (certId[0] << 24) +
+ (certId[1] << 16),
+ certbuf);
+ pkcs11objx->AddObjectSpec(objSpec);
+ }
+ {
+ Buffer b = channel->CreatePKCS11CertAttrsBuffer(
+ KEY_TYPE_ENCRYPTION , certAttrId, label, keyid);
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (certAttrId[0] << 24) +
+ (certAttrId[1] << 16),
+ &b);
+ pkcs11objx->AddObjectSpec(objSpec);
+ }
+
+ {
+ Buffer b = channel->CreatePKCS11PriKeyAttrsBuffer(KEY_TYPE_ENCRYPTION,
+ privateKeyAttrId, label, keyid, modulus, OP_PREFIX,
+ tokenType, keyTypePrefix);
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (privateKeyAttrId[0] << 24) +
+ (privateKeyAttrId[1] << 16),
+ &b);
+ pkcs11objx->AddObjectSpec(objSpec);
+ }
+
+ {
+ Buffer b = channel->CreatePKCS11PubKeyAttrsBuffer(KEY_TYPE_ENCRYPTION,
+ publicKeyAttrId, label, keyid,
+ exponent, modulus, OP_PREFIX, tokenType, keyTypePrefix);
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (publicKeyAttrId[0] << 24) +
+ (publicKeyAttrId[1] << 16),
+ &b);
+ pkcs11objx->AddObjectSpec(objSpec);
+ }
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "key written to token successfully");
+
+ rloser:
+
+ if( modulus != NULL ) {
+ delete modulus;
+ modulus = NULL;
+ }
+ if( keyid != NULL ) {
+ delete keyid;
+ keyid = NULL;
+ }
+ if( exponent != NULL ) {
+ delete exponent;
+ exponent = NULL;
+ }
+ if( attr[0] != NULL ) {
+ PR_Free(attr[0]);
+ attr[0] = NULL;
+ }
+ if( o_pub != NULL ) {
+ PR_Free(o_pub);
+ o_pub = NULL;
+ }
+
+ if (o_priv !=NULL) {
+ PR_Free(o_priv);
+ o_priv = NULL;
+ }
+
+ if( si_kid != NULL ) {
+ SECITEM_FreeItem( si_kid, PR_TRUE );
+ si_kid = NULL;
+ }
+ if( label != NULL ) {
+ PL_strfree( (char *) label );
+ label = NULL;
+ }
+
+ }
+ }
+ } else {
+ r = false;
+ o_status = STATUS_ERROR_LDAP_CONN;
+ goto loser;
+ }
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Filter to find certificates = %s", filter);
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Recover key for %s", keyTypeValue);
+
+ //Unrevoke this successfully recovered certificate
+ if ( o_status == STATUS_ERROR_RECOVERY_IS_PROCESSED && e != NULL) {
+ char *statusString = NULL;
+ int statusNum = UnrevokeRecoveredCert(e, statusString);
+
+ // Error from the CA log and get out
+ if (statusNum != 0) {
+ r = false;
+ o_status = STATUS_ERROR_RECOVERY_FAILED;
+ if (statusString == NULL || strlen(statusString) == 0) {
+ statusString = PL_strdup("Unknown Key Recovery Error.");
+ }
+ RA::Debug("RA_Enroll::Prcessor::ProcessRecovery", "Unrevoke statusString: %s",statusString);
+ PR_snprintf(audit_msg, 512, "Key Recovery failed. Can not unrevoke recovered certificate! %s",statusString);
+ if (statusString) {
+ PL_strfree(statusString);
+ }
+ goto loser;
+ }
+
+ if (statusString) {
+ PL_strfree(statusString);
+ }
+ }
+ }
+ if( !legalScheme) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Misconfigure parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ goto loser;
+ }
+
+ actualCertIndex++;
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery","leaving cert loop... ");
+ }
+
+ loser:
+ if (strlen(audit_msg) > 0) { // a failure occurred
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "failure",
+ "enrollment",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ audit_msg);
+ }
+
+ if( pretty_cuid != NULL ) {
+ PR_Free( (char *) pretty_cuid );
+ pretty_cuid = NULL;
+ }
+ if( result != NULL ) {
+ ldap_msgfree( result );
+ }
+
+
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery","leaving whole function...");
+ return r;
+}
+
+int RA_Enroll_Processor::DoPublish(const char *cuid,SECItem *encodedPublicKeyInfo,Buffer *cert,const char *publisher_id,char *applet_version)
+{
+
+ int res = 0;
+
+ CERTCertificate *certObj = NULL;
+ const char *FN="DoPublish";
+
+ unsigned char *public_key_data = NULL;
+ int public_key_len = 0;
+ PRTime not_before,not_after;
+
+ // 1980 epoch offset
+
+ PRTime ul_1980 = ((365 * 10 + 2) * 86400);
+
+
+ if(! encodedPublicKeyInfo)
+ {
+ return 0;
+ }
+
+
+ RA::Debug(LL_PER_CONNECTION,FN, "1980 epoch offset %u ",ul_1980);
+
+ PRUint32 ul_not_before, ul_not_after;
+
+ int key_type = 1;
+
+ RA::Debug(LL_PER_CONNECTION,FN, "We got a public key back. Now attempt publish operation.");
+
+ public_key_data = encodedPublicKeyInfo->data;
+ public_key_len = encodedPublicKeyInfo->len;
+
+ unsigned long applet_version_long = 0;
+
+ char *end = NULL;
+
+ if(applet_version)
+ {
+ applet_version_long = (unsigned long) strtol((const char *)applet_version,&end,16);
+ }
+ if(cuid)
+ {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "cuid %s public_key_len %ud",cuid,public_key_len);
+
+ }
+ if(cert)
+ {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "cert.size() %ld. cert %s",cert->size(),(char *) (BYTE *) cert);
+
+ certObj = CERT_DecodeCertFromPackage((char *) cert->string(), (int) cert->size());
+ }
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "certObj %p.",certObj);
+
+ if(certObj && cuid != NULL)
+ {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "We got pointer to Certificate data.");
+ CERT_GetCertTimes (certObj, &not_before, &not_after);
+
+ ul_not_before = ( PRUint32 )( not_before/1000000 );
+ ul_not_after = ( PRUint32 )( not_after/1000000 );
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Cert date not_before %u not_after %u.",ul_not_before,ul_not_after);
+
+ // Convert to 1980 epoch time
+
+ ul_not_before -= (PRUint32) ul_1980;
+ ul_not_after -= (PRUint32) ul_1980;
+
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Cert date, after 1980 translation, not_before %ul not_after %ul.",ul_not_before,ul_not_after);
+
+
+ PublisherEntry *publish = RA::getPublisherById(publisher_id);
+
+ if(publish != NULL)
+ {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "publisher %s ",publish->id);
+ }
+ else
+ {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "publisher %s not found ",publisher_id);
+
+ }
+
+ res = 0;
+ if(publish && publish->publisher )
+ {
+ IPublisher *pb = publish->publisher;
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "publisher %p ",pb);
+ res = pb->publish((unsigned char *) cuid,(int) strlen(cuid),(long) key_type,(unsigned char *) public_key_data,(int) public_key_len,(unsigned long)ul_not_before,(unsigned long) ul_not_after,applet_version_long,applet_version_long - ul_1980);
+
+ }
+ if(!res)
+ {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Publish failed.");
+ }
+ else
+ {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Publish success.");
+ }
+ }
+ else
+ {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "No Publish failed Either cuid or certObj is NULL.");
+ }
+
+ if(certObj)
+ {
+
+ CERT_DestroyCertificate(certObj);
+ }
+ return res;
+}
+
+int RA_Enroll_Processor::GetNextFreeCertIdNumber(PKCS11Obj *pkcs11objx)
+{
+ if(!pkcs11objx)
+ return 0;
+
+ //Look through the objects actually currently on the token
+ //to determine an appropriate free certificate id
+
+ int num_objs = pkcs11objx->PKCS11Obj::GetObjectSpecCount();
+ char objid[2];
+
+ int highest_cert_id = 0;
+ for (int i = 0; i< num_objs; i++) {
+ ObjectSpec* os = pkcs11objx->GetObjectSpec(i);
+ unsigned long oid = os->GetObjectID();
+ objid[0] = (char)((oid >> 24) & 0xff);
+ objid[1] = (char)((oid >> 16) & 0xff);
+
+ if(objid[0] == 'C') { //found a certificate
+
+ int id_int = objid[1] - '0';
+
+ if(id_int > highest_cert_id) {
+ highest_cert_id = id_int;
+ }
+ }
+ }
+
+ RA::Debug(LL_PER_CONNECTION,
+ "RA_Enroll_Processor::GetNextFreeCertIdNumber",
+ "returning id number: %d", highest_cert_id + 1);
+ return highest_cert_id + 1;
+}
+
+//Unrevoke a cert that has been recovered
+int RA_Enroll_Processor::UnrevokeRecoveredCert(const LDAPMessage *e, char *&statusString)
+{
+ char configname[256];
+ CertEnroll certEnroll;
+ //Default to error return
+ int statusNum = 0;
+ char serial[100]="";
+
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "About to unrevoke recovered certificate.");
+
+ if (e == NULL) {
+ return 1;
+ }
+
+ char *attr_serial= RA::ra_get_cert_serial( (LDAPMessage *) e );
+ char *attr_tokenType = RA::ra_get_cert_tokenType( (LDAPMessage *) e );
+ char *attr_keyType = RA::ra_get_cert_type( (LDAPMessage *) e );
+
+ // does the config say we have to revoke this cert?
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.recovery."
+ "onHold.revokeCert",
+ attr_tokenType, attr_keyType );
+
+ RA::Debug("RA_Enroll_Processor::UnrevokeRecoveredCert",
+ "Recovered Cert Unrevoke config value %s \n", configname);
+ bool revokeCert = RA::GetConfigStore()->
+ GetConfigAsBool( configname, false );
+ if( revokeCert ) {
+ // Assume the worst
+ statusNum = 1;
+ // Get the conn to the CA
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.ca.conn",
+ attr_tokenType, attr_keyType );
+
+ char *connid = ( char * )
+ RA::GetConfigStore()->
+ GetConfigAsString( configname );
+
+ if (connid) {
+ PR_snprintf( serial, 100, "0x%s", attr_serial );
+
+ //Actually make call to the CA to unrevoke
+ statusNum = certEnroll.UnrevokeCertificate(serial, connid, statusString);
+
+ RA::Debug("RA_Enroll_Processor::UnrevokeRecoveredCert",
+ "Recovered Cert statusNum %d statusString %s \n", statusNum, statusString);
+ }
+ }
+
+ if (attr_serial) {
+ PL_strfree(attr_serial);
+ }
+
+ if (attr_tokenType) {
+ PL_strfree(attr_tokenType);
+ }
+
+ if (attr_keyType) {
+ PL_strfree(attr_keyType);
+ }
+ return statusNum;
+}
+
+void PrintPRTime(PRTime theTime, const char *theName)
+{
+ struct tm t;
+ PRExplodedTime explode;
+ char buffer[256];
+
+ if(!theName)
+ return;
+
+ PR_ExplodeTime (theTime, PR_LocalTimeParameters, &explode);
+
+ t.tm_sec = explode.tm_sec;
+ t.tm_min = explode.tm_min;
+ t.tm_hour = explode.tm_hour;
+ t.tm_mday = explode.tm_mday;
+ t.tm_mon = explode.tm_month;
+ t.tm_year = explode.tm_year - 1900;
+ t.tm_wday = explode.tm_wday;
+ t.tm_yday = explode.tm_yday;
+
+ PL_strncpy(buffer, asctime (&t), 256);
+ buffer[256 - 1] = 0;
+
+ RA::Debug("PrintPRTime","Date/Time: %s %s",theName,buffer);
+}
diff --git a/base/tps/src/processor/RA_Format_Processor.cpp b/base/tps/src/processor/RA_Format_Processor.cpp
new file mode 100644
index 000000000..b09a7495b
--- /dev/null
+++ b/base/tps/src/processor/RA_Format_Processor.cpp
@@ -0,0 +1,70 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <string.h>
+
+#include "main/RA_Session.h"
+#include "main/RA_Msg.h"
+#include "main/Buffer.h"
+#include "main/Util.h"
+#include "engine/RA.h"
+#include "channel/Secure_Channel.h"
+#include "msg/RA_SecureId_Request_Msg.h"
+#include "msg/RA_SecureId_Response_Msg.h"
+#include "msg/RA_New_Pin_Request_Msg.h"
+#include "msg/RA_New_Pin_Response_Msg.h"
+#include "processor/RA_Processor.h"
+#include "processor/RA_Format_Processor.h"
+#include "cms/CertEnroll.h"
+#include "httpClient/httpc/response.h"
+#include "main/Memory.h"
+#include "tus/tus_db.h"
+#include "ldap.h"
+
+#define OP_PREFIX "op.format"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a processor for handling upgrade operation.
+ */
+TPS_PUBLIC RA_Format_Processor::RA_Format_Processor ()
+{
+}
+
+/**
+ * Destructs upgrade processor.
+ */
+TPS_PUBLIC RA_Format_Processor::~RA_Format_Processor ()
+{
+}
+
+/**
+ * Processes the current session.
+ */
+TPS_PUBLIC RA_Status RA_Format_Processor::Process(RA_Session *session, NameValueSet *extensions)
+{
+ bool skip_auth = false;
+ return Format(session,extensions,skip_auth);
+}
diff --git a/base/tps/src/processor/RA_Pin_Reset_Processor.cpp b/base/tps/src/processor/RA_Pin_Reset_Processor.cpp
new file mode 100644
index 000000000..b776b55a4
--- /dev/null
+++ b/base/tps/src/processor/RA_Pin_Reset_Processor.cpp
@@ -0,0 +1,1013 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "engine/RA.h"
+#include "main/Util.h"
+#include "main/RA_Msg.h"
+#include "main/RA_Session.h"
+#include "channel/Secure_Channel.h"
+#include "processor/RA_Processor.h"
+#include "processor/RA_Pin_Reset_Processor.h"
+#include "main/Memory.h"
+#include "tus/tus_db.h"
+#define OP_PREFIX "op.pinReset"
+static const char *expected_version = NULL;
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a processor for hanlding pin reset operation.
+ */
+TPS_PUBLIC RA_Pin_Reset_Processor::RA_Pin_Reset_Processor()
+{
+}
+
+/**
+ * Destructs pin reset processor.
+ */
+TPS_PUBLIC RA_Pin_Reset_Processor::~RA_Pin_Reset_Processor()
+{
+}
+
+/**
+ * Process the current session.
+ */
+TPS_PUBLIC RA_Status RA_Pin_Reset_Processor::Process(RA_Session *session, NameValueSet *extensions)
+{
+ struct berval **tokenOwner=NULL;
+ char configname[256];
+ const char *tokenType = NULL;
+ char *cuid = NULL;
+ const char *msn = NULL;
+ PRIntervalTime start, end;
+ RA_Status status = STATUS_NO_ERROR;
+ int rc = -1;
+ AuthParams *login = NULL;
+ Secure_Channel *channel = NULL;
+ char *new_pin = NULL;
+ unsigned int minlen = 0, maxlen = 0;
+ const char *applet_dir;
+ bool upgrade_enc = false;
+ char curVer[10];
+ char newVer[10];
+
+ char *curKeyInfoStr = NULL;
+ char *newVersionStr = NULL;
+
+ SecurityLevel security_level = SECURE_MSG_MAC_ENC;
+ Buffer *CardManagerAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_CARDMGR_INSTANCE_AID,
+ RA::CFG_DEF_CARDMGR_INSTANCE_AID);
+ Buffer *NetKeyAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_NETKEY_INSTANCE_AID,
+ RA::CFG_DEF_NETKEY_INSTANCE_AID);
+
+ int i;
+ Buffer key_data_set;
+ Buffer *token_status = NULL;
+ Buffer *buildID = NULL;
+ char *policy = NULL;
+ char *tmp_policy = NULL;
+ const char* required_version = NULL;
+ const char *appletVersion = NULL;
+ const char *final_applet_version = NULL;
+ char *keyVersion = PL_strdup( "" );
+ const char *userid = PL_strdup( "" );
+ BYTE major_version = 0x0;
+ BYTE minor_version = 0x0;
+ BYTE app_major_version = 0x0;
+ BYTE app_minor_version = 0x0;
+ char *token_userid = NULL;
+
+ Buffer host_challenge = Buffer(8, (BYTE)0);
+ Buffer key_diversification_data;
+ Buffer key_info_data;
+ Buffer card_challenge;
+ Buffer card_cryptogram;
+ Buffer token_cuid;
+ Buffer token_msn;
+ const char *connId = NULL;
+ const char *connid = NULL;
+ const char *tksid = NULL;
+ const char *authid = NULL;
+ AuthParams *authParams = NULL;
+ start = PR_IntervalNow();
+ Buffer *cplc_data = NULL;
+ char activity_msg[4096];
+ LDAPMessage *e = NULL;
+ LDAPMessage *ldapResult = NULL;
+ int maxReturns = 10;
+ char audit_msg[512] = "";
+ char *profile_state = NULL;
+ int key_change_over_success = 0;
+
+
+ RA::Debug("RA_Pin_Reset_Processor::Process", "Client %s", session->GetRemoteIP());
+
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "RA_Pin_Reset_Processor::Process");
+
+
+ SelectApplet(session, 0x04, 0x00, CardManagerAID);
+ cplc_data = GetData(session);
+ if (cplc_data == NULL) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "Get Data Failed");
+ status = STATUS_ERROR_SECURE_CHANNEL;
+ PR_snprintf(audit_msg, 512, "Get Data Failed, status = STATUS_ERROR_SECURE_CHANNEL");
+ goto loser;
+ }
+ RA::DebugBuffer("RA_Pin_Reset_Processor::process", "CPLC Data = ",
+ cplc_data);
+ if (cplc_data->size() < 47) {
+ RA::Error("RA_Format_Processor::Process",
+ "Invalid CPLC Size");
+ status = STATUS_ERROR_SECURE_CHANNEL;
+ PR_snprintf(audit_msg, 512, "Invalid CPLC Size, status = STATUS_ERROR_SECURE_CHANNEL");
+ goto loser;
+ }
+ token_cuid = Buffer(cplc_data->substr(3,4)) +
+ Buffer(cplc_data->substr(19,2)) +
+ Buffer(cplc_data->substr(15,4));
+ RA::DebugBuffer("RA_Pin_Reset_Processor::process", "Token CUID= ",
+ &token_cuid);
+ cuid = Util::Buffer2String(token_cuid);
+
+ token_msn = Buffer(cplc_data->substr(41, 4));
+ RA::DebugBuffer("RA_Pin_Reset_Processor::process", "Token MSN= ",
+ &token_msn);
+ msn = Util::Buffer2String(token_msn);
+
+ /**
+ * Checks if the netkey has the required applet version.
+ */
+ SelectApplet(session, 0x04, 0x00, NetKeyAID);
+ token_status = GetStatus(session, 0x00, 0x00);
+ if (token_status == NULL) {
+ major_version = 0x0;
+ minor_version = 0x0;
+ app_major_version = 0x0;
+ app_minor_version = 0x0;
+ } else {
+ major_version = ((BYTE*)*token_status)[0];
+ minor_version = ((BYTE*)*token_status)[1];
+ app_major_version = ((BYTE*)*token_status)[2];
+ app_minor_version = ((BYTE*)*token_status)[3];
+ }
+
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "Major=%d Minor=%d", major_version, minor_version);
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "Applet Major=%d Applet Minor=%d", app_major_version, app_minor_version);
+
+ if (!RA::ra_is_token_present(cuid)) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "CUID %s Not Present", cuid);
+ status = STATUS_ERROR_DB;
+ PR_snprintf(audit_msg, 512, "CUID Not Present, status = STATUS_ERROR_DB");
+ goto loser;
+ }
+
+ // retrieve CUID
+
+ if (!GetTokenType(OP_PREFIX, major_version,
+ minor_version, cuid, msn,
+ extensions, status, tokenType)) {
+ PR_snprintf(audit_msg, 512, "Failed to get token type");
+ goto loser;
+ }
+
+ // check if profile is enabled
+ PR_snprintf((char *)configname, 256, "config.Profiles.%s.state", tokenType);
+ profile_state = (char *) RA::GetConfigStore()->GetConfigAsString(configname);
+ if ((profile_state != NULL) && (PL_strcmp(profile_state, "Enabled") != 0)) {
+ RA::Error("RA_Pin_Reset_Processor::Process", "Profile %s Disabled for CUID %s", tokenType, cuid);
+ status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "profile %s disabled", tokenType);
+ goto loser;
+ }
+
+ if (RA::ra_is_tus_db_entry_disabled(cuid)) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "CUID %s Disabled", cuid);
+ status = STATUS_ERROR_DISABLED_TOKEN;
+ PR_snprintf(audit_msg, 512, "Token disabled, status = STATUS_ERROR_DISABLED_TOKEN");
+ goto loser;
+ }
+
+ // we know cuid and msn here
+ RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "pin_reset",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "token enabled");
+
+ if (!RA::ra_is_token_pin_resetable(cuid)) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "CUID %s Cannot Pin Reset", cuid);
+ status = STATUS_ERROR_NOT_PIN_RESETABLE;
+ PR_snprintf(audit_msg, 512, "token cannot pin reset, status = STATUS_ERROR_PIN_RESETABLE");
+ goto loser;
+ }
+
+ // we know cuid and msn here
+ RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "pin_reset",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "pin reset allowed");
+
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn",
+ OP_PREFIX, tokenType);
+ tksid = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (tksid == NULL) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "TKS Connection Parameter %s Not Found", configname);
+ status = STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "TKS Connection Parameter %s Not Found, status = STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND", configname);
+ goto loser;
+ }
+
+ buildID = GetAppletVersion(session);
+ if (buildID == NULL) {
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.emptyToken.enable", OP_PREFIX,
+ tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 0)) {
+ appletVersion = PL_strdup( "unknown" );
+ } else {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "no applet found and applet upgrade not enabled");
+ status = STATUS_ERROR_SECURE_CHANNEL;
+ PR_snprintf(audit_msg, 512, "no applet found and applet upgrade not enabled, status = STATUS_ERROR_SECURE_CHANNEL");
+ goto loser;
+ }
+ } else {
+ char * buildid = Util::Buffer2String(*buildID);
+ RA::Debug("RA_Pin_Reset_Processor", "buildid = %s", buildid);
+ char version[13];
+ PR_snprintf((char *) version, 13,
+ "%x.%x.%s", app_major_version, app_minor_version,
+ buildid);
+ appletVersion = strdup(version);
+ if (buildid != NULL) {
+ PR_Free(buildid);
+ buildid = NULL;
+ }
+ }
+
+ final_applet_version = strdup(appletVersion);
+ RA::Debug("RA_Pin_Reset_Processor", "final_applet_version = %s", final_applet_version);
+
+ /**
+ * Checks if we need to upgrade applet.
+ */
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.enable", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 0)) {
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.requiredVersion", OP_PREFIX, tokenType);
+ required_version = RA::GetConfigStore()->GetConfigAsString(configname);
+ expected_version = PL_strdup(required_version);
+
+ if (expected_version == NULL) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "misconfiguration for upgrade");
+ status = STATUS_ERROR_MISCONFIGURATION;
+ PR_snprintf(audit_msg, 512, "misconfiguration for upgrade, status = STATUS_ERROR_MISCONFIGURATION");
+ goto loser;
+ }
+ /* Bugscape #55826: used case-insensitive check below */
+ if (PL_strcasecmp(expected_version, appletVersion) != 0) {
+ /* upgrade applet */
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.directory", OP_PREFIX, tokenType);
+ applet_dir = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (applet_dir == NULL || strlen(applet_dir) == 0) {
+ RA::Error(LL_PER_PDU, "RA_Processor::UpgradeApplet",
+ "Failed to get %s", applet_dir);
+ PR_snprintf(audit_msg, 512, "Failed to get %s", applet_dir);
+ goto loser;
+ }
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.encryption", OP_PREFIX, tokenType);
+ upgrade_enc = RA::GetConfigStore()->GetConfigAsBool(configname, true);
+ if (!upgrade_enc)
+ security_level = SECURE_MSG_MAC;
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType);
+ connid = RA::GetConfigStore()->GetConfigAsString(configname);
+ int upgrade_rc = UpgradeApplet(session, (char *) OP_PREFIX, (char*)tokenType, major_version, minor_version,
+ expected_version, applet_dir, security_level, connid, extensions, 30, 70, &keyVersion);
+ if (upgrade_rc != 1) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "upgrade failure");
+ status = STATUS_ERROR_UPGRADE_APPLET;
+ /**
+ * Bugscape #55709: Re-select Net Key Applet ONLY on failure.
+ */
+ SelectApplet(session, 0x04, 0x00, NetKeyAID);
+
+ if (upgrade_rc == -1) {
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ userid, cuid, msn, "Failure", "pin_reset",
+ keyVersion != NULL? keyVersion : "", appletVersion, expected_version, "failed to setup secure channel");
+ } else {
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ userid, cuid, msn, "Success", "pin_reset",
+ keyVersion != NULL? keyVersion : "", appletVersion, expected_version, "setup secure channel");
+ }
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ userid, cuid, msn, "Failure", "pin_reset",
+ keyVersion != NULL? keyVersion : "",
+ appletVersion, expected_version, "applet upgrade");
+ goto loser;
+ }
+
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ userid, cuid, msn, "Success", "pin_reset",
+ keyVersion != NULL? keyVersion : "", appletVersion, expected_version, "setup secure channel");
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ userid, cuid, msn, "Success", "pin_reset",
+ keyVersion != NULL? keyVersion : "",
+ appletVersion, expected_version, "applet upgrade");
+
+ final_applet_version = expected_version;
+ }
+ }
+
+ /**
+ * Checks if the netkey has the required key version.
+ */
+ PR_snprintf((char *)configname, 256, "%s.%s.update.symmetricKeys.enable", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 0)) {
+ PR_snprintf((char *)configname, 256, "%s.%s.update.symmetricKeys.requiredVersion", OP_PREFIX, tokenType);
+ int requiredVersion = RA::GetConfigStore()->GetConfigAsInt(configname, 0x00);
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType);
+ connId = RA::GetConfigStore()->GetConfigAsString(configname);
+ if( channel != NULL ) {
+ delete channel;
+ channel = NULL;
+ }
+ channel = SetupSecureChannel(session, requiredVersion,
+ 0x00 /* default key index */, connId);
+ if (channel == NULL) {
+
+ /* if version 0x02 key not found, create them */
+ SelectApplet(session, 0x04, 0x00, CardManagerAID);
+ channel = SetupSecureChannel(session,
+ 0x00, /* default key version */
+ 0x00 /* default key index */, connId);
+
+ if (channel == NULL) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "setup secure channel failure");
+ status = STATUS_ERROR_SECURE_CHANNEL;
+ PR_snprintf(audit_msg, 512, "setup secure channel failure, status = STATUS_ERROR_SECURE_CHANNEL");
+ goto loser;
+ }
+
+ rc = channel->ExternalAuthenticate();
+ if (rc != 1) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "External authentication in secure channel failed");
+ status = STATUS_ERROR_EXTERNAL_AUTH;
+ PR_snprintf(audit_msg, 512, "External authentication in secure channel failed, status = STATUS_ERROR_EXTERNAL_AUTH");
+ goto loser;
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.update.symmetricKeys.requiredVersion", OP_PREFIX, tokenType);
+ int v = RA::GetConfigStore()->GetConfigAsInt(configname, 0x00);
+ Buffer curKeyInfo = channel->GetKeyInfoData();
+ BYTE nv[2] = { v, 0x01 };
+ Buffer newVersion(nv, 2);
+ PR_snprintf((char *)configname, 256,"%s.%s.tks.conn", OP_PREFIX, tokenType);
+ connid = RA::GetConfigStore()->GetConfigAsString(configname);
+ rc = CreateKeySetData(
+ channel->GetKeyDiversificationData(),
+ curKeyInfo,
+ newVersion,
+ key_data_set, connid);
+ if (rc != 1) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "failed to create new key set");
+ status = STATUS_ERROR_CREATE_CARDMGR;
+ PR_snprintf(audit_msg, 512, "failed to create new key set, status = STATUS_ERROR_CREATE_CARDMGR");
+ goto loser;
+ }
+
+
+ BYTE curVersion = ((BYTE*)curKeyInfo)[0];
+ BYTE curIndex = ((BYTE*)curKeyInfo)[1];
+ rc = channel->PutKeys(session,
+ curVersion,
+ curIndex,
+ &key_data_set);
+
+ curKeyInfoStr = Util::Buffer2String(curKeyInfo);
+ newVersionStr = Util::Buffer2String(newVersion);
+
+ if(curKeyInfoStr != NULL && strlen(curKeyInfoStr) >= 2) {
+ curVer[0] = curKeyInfoStr[0]; curVer[1] = curKeyInfoStr[1]; curVer[2] = 0;
+ }
+ else {
+ curVer[0] = 0;
+ }
+
+ if(newVersionStr != NULL && strlen(newVersionStr) >= 2) {
+ newVer[0] = newVersionStr[0] ; newVer[1] = newVersionStr[1] ; newVer[2] = 0;
+ }
+ else {
+ newVer[0] = 0;
+ }
+
+ if (rc!=0) {
+ RA::Audit(EV_KEY_CHANGEOVER, AUDIT_MSG_KEY_CHANGEOVER,
+ userid != NULL ? userid : "", cuid != NULL ? cuid : "", msn != NULL ? msn : "", "Failure", "pin_reset",
+ final_applet_version != NULL ? final_applet_version : "", curVer, newVer,
+ "key changeover failed");
+ }
+
+ SelectApplet(session, 0x04, 0x00, NetKeyAID);
+ PR_snprintf((char *)configname, 256, "%s.%s.update.symmetricKeys.requiredVersion", OP_PREFIX, tokenType);
+ if( channel != NULL ) {
+ delete channel;
+ channel = NULL;
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType);
+ connId = RA::GetConfigStore()->GetConfigAsString(configname);
+ channel = SetupSecureChannel(session,
+ RA::GetConfigStore()->GetConfigAsInt(configname, 0x00),
+ 0x00 /* default key index */, connId);
+ if (channel == NULL) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "setup secure channel failure");
+ status = STATUS_ERROR_CREATE_CARDMGR;
+ PR_snprintf(audit_msg, 512, "setup secure channel failure, status = STATUS_ERROR_CREATE_CARDMGR");
+ goto loser;
+ }
+
+ RA::Audit(EV_KEY_CHANGEOVER, AUDIT_MSG_KEY_CHANGEOVER,
+ userid != NULL ? userid : "", cuid != NULL ? cuid : "", msn != NULL ? msn : "", "Success", "pin_reset",
+ final_applet_version != NULL ? final_applet_version : "", curVer, newVer,
+ "key changeover");
+ key_change_over_success = 1;
+ } else { key_change_over_success = 1; }
+ } else {
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType);
+ connId = RA::GetConfigStore()->GetConfigAsString(configname);
+ if( channel != NULL ) {
+ delete channel;
+ channel = NULL;
+ }
+ channel = SetupSecureChannel(session,
+ 0x00,
+ 0x00 /* default key index */, connId);
+ }
+
+ /* we should have a good channel here */
+ if (channel == NULL) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "no channel creation failure");
+ status = STATUS_ERROR_CREATE_CARDMGR;
+ PR_snprintf(audit_msg, 512, "no channel creation failure, status = STATUS_ERROR_CREATE_CARDMGR");
+ goto loser;
+ }
+
+ if (channel != NULL) {
+ if( keyVersion != NULL ) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+ keyVersion = Util::Buffer2String(channel->GetKeyInfoData());
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.loginRequest.enable", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 1)) {
+ if (extensions != NULL &&
+ extensions->GetValue("extendedLoginRequest") != NULL)
+ {
+ RA::Debug("RA_Enroll_Processor::RequestUserId",
+ "Extended Login Request detected");
+ AuthenticationEntry *entry = GetAuthenticationEntry(
+ OP_PREFIX, configname, tokenType);
+ char **params = NULL;
+ char pb[1024];
+ char *locale = NULL;
+ if (extensions != NULL &&
+ extensions->GetValue("locale") != NULL)
+ {
+ locale = extensions->GetValue("locale");
+ } else {
+ locale = ( char * ) "en"; /* default to english */
+ }
+ int n = entry->GetAuthentication()->GetNumOfParamNames();
+ if (n > 0) {
+ RA::Debug("RA_Enroll_Processor::RequestUserId",
+ "Extended Login Request detected n=%d", n);
+ params = (char **) PR_Malloc(n);
+ for (int i = 0; i < n; i++) {
+ sprintf(pb,"id=%s&name=%s&desc=%s&type=%s&option=%s",
+ entry->GetAuthentication()->GetParamID(i),
+ entry->GetAuthentication()->GetParamName(i, locale),
+ entry->GetAuthentication()->GetParamDescription(i,
+locale),
+ entry->GetAuthentication()->GetParamType(i),
+ entry->GetAuthentication()->GetParamOption(i)
+ );
+ params[i] = PL_strdup(pb);
+ RA::Debug("RA_Enroll_Processor::RequestUserId",
+ "params[i]=%s", params[i]);
+ }
+ }
+ RA::Debug("RA_Enroll_Processor::RequestUserId", "Extended Login Request detected calling RequestExtendedLogin() locale=%s", locale);
+
+ char *title = PL_strdup(entry->GetAuthentication()->GetTitle(locale));
+ RA::Debug("RA_Enroll_Processor::RequestUserId", "title=%s", title);
+ char *description = PL_strdup(entry->GetAuthentication()->GetDescription(locale));
+ RA::Debug("RA_Enroll_Processor::RequestUserId", "description=%s", description);
+ login = RequestExtendedLogin(session, 0 /* invalid_pw */, 0 /* blocked */, params, n, title, description);
+
+ RA::Debug("RA_Enroll_Processor::RequestUserId",
+ "Extended Login Request detected calling RequestExtendedLogin() login=%x", login);
+
+ if (params != NULL) {
+ for (int nn=0; nn < n; nn++) {
+ if (params[nn] != NULL) {
+ PL_strfree(params[nn]);
+ params[nn] = NULL;
+ }
+ }
+ free(params);
+ params = NULL;
+ }
+
+ if (title != NULL) {
+ PL_strfree(title);
+ title = NULL;
+ }
+
+ if (description != NULL) {
+ PL_strfree(description);
+ description = NULL;
+ }
+
+ } else {
+ login = RequestLogin(session, 0 /* invalid_pw */, 0 /* blocked */);
+ }
+ if (login == NULL) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "login not provided");
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "login not provided, status = STATUS_ERROR_LOGIN");
+
+ goto loser;
+ }
+ if( userid != NULL ) {
+ PR_Free( (char *) userid );
+ userid = NULL;
+ }
+ userid = PL_strdup( login->GetUID() );
+ }
+
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 30 /* progress */,
+ "PROGRESS_START_AUTHENTICATION");
+ }
+
+ RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "pin_reset",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "userid obtained");
+
+ PR_snprintf(configname, 256, "cn=%s", cuid);
+ rc = RA::ra_find_tus_token_entries(configname, maxReturns, &ldapResult, 0);
+
+ if (rc == 0) {
+ for (e = RA::ra_get_first_entry(ldapResult); e != NULL;
+ e = RA::ra_get_next_entry(e)) {
+ tokenOwner = RA::ra_get_attribute_values(e, "tokenUserID");
+ if ((tokenOwner != NULL) && (tokenOwner[0] != NULL) &&
+ (tokenOwner[0]->bv_val != NULL) && (strlen(tokenOwner[0]->bv_val) > 0) &&
+ (strcmp(userid, tokenOwner[0]->bv_val) != 0)) {
+ status = STATUS_ERROR_NOT_TOKEN_OWNER;
+ PR_snprintf(audit_msg, 512, "token owner mismatch, status = STATUS_ERROR_NOT_TOKEN_OWNER");
+ goto loser;
+ }
+ }
+ } else {
+ RA::Error("RA_Pin_Reset_Processor::Process", "Error in ldap connection with token database.");
+ status = STATUS_ERROR_LDAP_CONN;
+ PR_snprintf(audit_msg, 512, "Error in ldap connection with token database, status = STATUS_ERROR_LDAP_CONN");
+ goto loser;
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.auth.enable", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, false)) {
+ if (login == NULL) {
+ RA::Error("RA_Pin_Reset_Processor::Process", "Login Request Disabled. Authentication failed.");
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "Login Request Disabled. status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+
+
+ PR_snprintf((char *)configname, 256, "%s.%s.auth.id", OP_PREFIX, tokenType);
+ authid = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (authid == NULL) {
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "authid is null, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+ AuthenticationEntry *auth = RA::GetAuth(authid);
+
+ if(auth == NULL)
+ {
+ RA::Error("RA_Pin_Reset_Processor::Process", "Authentication manager is NULL . Authentication failed.");
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "Authentication manager is NULL, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+
+ char *type = auth->GetType();
+ if (type == NULL) {
+ status = STATUS_ERROR_LOGIN;
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "enrollment", "failure", "authentication is missing param type", "", tokenType);
+ PR_snprintf(audit_msg, 512, "authentication is missing param type, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+ if (strcmp(type, "LDAP_Authentication") == 0) {
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "LDAP_Authentication is invoked.");
+ int passwd_retries = auth->GetAuthentication()->GetNumOfRetries();
+ int retries = 0;
+ authParams = new AuthParams();
+ authParams->SetUID(login->GetUID());
+ authParams->SetPassword(login->GetPassword());
+ rc = auth->GetAuthentication()->Authenticate(authParams);
+
+ RA::Debug("RA_Pin_Reset_Processor::Process",
+ "Authenticate returns: %d", rc);
+
+ while ((rc == -2 || rc == -3) && (retries < passwd_retries)) {
+ login = RequestLogin(session, 0 /* invalid_pw */, 0 /* blocked */);
+ if (login == NULL) {
+ RA::Error("RA_Pin_Reset_Processor::Process", "Login Request Disabled. Authentication failed.");
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "Login Request Disabled, r=-2 or -3. status= STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+ retries++;
+ authParams->SetUID(login->GetUID());
+ authParams->SetPassword(login->GetPassword());
+ rc = auth->GetAuthentication()->Authenticate(authParams);
+ }
+
+ if (rc == -1) {
+ RA::Error("RA_Pin_Reset_Processor::Process", "Authentication failed.");
+ status = STATUS_ERROR_LDAP_CONN;
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process", "Authentication status = %d", status);
+ PR_snprintf(audit_msg, 512, "authentication failed, rc=-1, status = STATUS_ERROR_LDAP_CONN");
+ goto loser;
+ }
+
+ if (rc == -2 || rc == -3) {
+ RA::Error("RA_Pin_Reset_Processor::Process", "Authentication failed.");
+ status = STATUS_ERROR_LOGIN;
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process", "Authentication status = %d", status);
+ PR_snprintf(audit_msg, 512, "authentication failed, rc=-2 or rc=-3, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process", "Authentication successful.");
+ } else {
+ RA::Error("RA_Pin_Reset_Processor::Process", "No Authentication type was found.");
+ status = STATUS_ERROR_LOGIN;
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "enrollment", "failure", "authentication error", "", tokenType);
+ PR_snprintf(audit_msg, 512, "No Authentication type was found. status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "Authentication has been disabled.");
+ }
+
+ RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "pin_reset",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "authentication successful");
+
+
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "SetupSecureChannel");
+
+#if 0
+ if (RA::GetConfigStore()->GetConfigAsBool("tus.enable", 0)) {
+ if (IsTokenDisabledByTus(channel)) {
+ status = STATUS_ERROR_TOKEN_DISABLED;
+ goto loser;
+ }
+ }
+#endif
+
+ /* check if the user owns the token */
+ token_userid = RA::ra_get_token_userid(cuid);
+ if (token_userid == NULL) {
+ RA::Error(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "No user owns the token '%s'", cuid);
+ status = STATUS_ERROR_TOKEN_DISABLED;
+ PR_snprintf(audit_msg, 512, "No user owns the token, status = STATUS_ERROR_TOKEN_DISABLED");
+ goto loser;
+ } else {
+ if (strcmp(token_userid, userid) != 0) {
+ RA::Error(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "User does not own the token '%s'", cuid);
+ status = STATUS_ERROR_TOKEN_DISABLED;
+ PR_snprintf(audit_msg, 512, "User does not own the token. status = STATUS_ERROR_TOKEN_DISABLED");
+ goto loser;
+ }
+ }
+
+ RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "pin_reset",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "login successful");
+
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "ExternalAuthenticate");
+ rc = channel->ExternalAuthenticate();
+ if (rc == -1) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "External Authenticate failed.");
+ status = STATUS_ERROR_CREATE_CARDMGR;
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "pin reset", "failure", "external authentication error", "", tokenType);
+ PR_snprintf(audit_msg, 512, "External Authenticate failed, status = STATUS_ERROR_CREATE_CARDMGR");
+ goto loser;
+ }
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "RequestNewPin");
+ PR_snprintf((char *)configname, 256, "%s.%s.pinReset.pin.minLen", OP_PREFIX, tokenType);
+ minlen = RA::GetConfigStore()->GetConfigAsUnsignedInt(configname, 4);
+ PR_snprintf((char *)configname, 256, "%s.%s.pinReset.pin.maxLen", OP_PREFIX, tokenType);
+ maxlen = RA::GetConfigStore()->GetConfigAsUnsignedInt(configname, 10);
+ new_pin = RequestNewPin(session, minlen, maxlen);
+ if (new_pin == NULL) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "Set Pin failed.");
+ status = STATUS_ERROR_MAC_RESET_PIN_PDU;
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "pin reset", "failure", "request new pin error", "", tokenType);
+ PR_snprintf(audit_msg, 512, "RequestNewPin failed, status = STATUS_ERROR_MAC_RESET_PIN_PDU");
+ goto loser;
+ }
+
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 70 /* progress */,
+ "PROGRESS_PIN_RESET");
+ }
+
+ rc = channel->ResetPin(0x0, new_pin);
+ if (rc == -1) {
+ status = STATUS_ERROR_MAC_RESET_PIN_PDU;
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "pin reset", "failure", "ereset pin error", "", tokenType);
+ PR_snprintf(audit_msg, 512, "ResetPin failed, status = STATUS_ERROR_MAC_RESET_PIN_PDU");
+ goto loser;
+ }
+
+ rc = channel->Close();
+ if (rc == -1) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "Failed to close channel");
+ status = STATUS_ERROR_CONNECTION;
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "pin reset", "failure", "secure channel close error", "", tokenType);
+ PR_snprintf(audit_msg, 512, "Failed to close channel, status = STATUS_ERROR_CONNECTION");
+ goto loser;
+ }
+
+
+ //Update the KeyInfo in case of successful key changeover
+ if (key_change_over_success != 0) {
+ RA::tdb_update( userid != NULL ? userid : (char *) "",
+ cuid != NULL ? cuid : (char *) "" ,
+ final_applet_version != NULL ? (char *) final_applet_version : (char *) "" ,
+ keyVersion != NULL ? keyVersion : (char *) "","active", "",
+ tokenType != NULL ? tokenType : (char *) "");
+ }
+ RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "pin_reset",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "ResetPin successful");
+
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 100 /* progress */,
+ "PROGRESS_DONE");
+ }
+
+ end = PR_IntervalNow();
+
+ rc = 1;
+
+ if (RA::ra_is_token_present(cuid)) {
+ /*
+ * we want to have a tus policy to change PIN_RESET=YES
+ * parameter to PIN_RESET=NO
+ */
+ if (RA::ra_is_token_pin_resetable(cuid)) {
+ policy = RA::ra_get_token_policy(cuid);
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "Policy %s is %s", cuid, policy);
+ tmp_policy = PL_strstr(policy, "PIN_RESET=YES");
+ if (tmp_policy != NULL) {
+ tmp_policy[10] = 'N';
+ tmp_policy[11] = 'O';
+ for (i = 12; tmp_policy[i] != '\0'; i++)
+ tmp_policy[i] = tmp_policy[i+1];
+ rc = RA::ra_update_token_policy(cuid, policy);
+ if (rc != 0) {
+ RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "failure",
+ "pin_reset",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "failed to reset token policy");
+ }
+ }
+ }
+ }
+
+ sprintf(activity_msg, "applet_version=%s tokenType=%s",
+ (char *)final_applet_version, tokenType);
+ RA::tdb_activity(session->GetRemoteIP(), (char *)cuid, "pin reset", "success", activity_msg, userid, tokenType);
+
+ /* audit log for successful pin reset */
+ if (authid != NULL) {
+ sprintf(activity_msg, "pin_reset processing completed, authid = %s", authid);
+ } else {
+ sprintf(activity_msg, "pin_reset processing completed");
+ }
+ RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC,
+ userid, cuid, msn, "success", "pin_reset", final_applet_version, keyVersion!=NULL? keyVersion: "", activity_msg);
+
+loser:
+ if (strlen(audit_msg) > 0) {
+ RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "failure",
+ "pin_reset",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ audit_msg);
+
+ if ((cuid != NULL) && (tokenType != NULL)) {
+ RA::tdb_activity(session->GetRemoteIP(),
+ cuid,
+ "pin_reset",
+ "failure",
+ audit_msg,
+ userid != NULL ? userid : "",
+ tokenType);
+ }
+ }
+
+ if (curKeyInfoStr != NULL) {
+ PR_Free( (char *) curKeyInfoStr);
+ curKeyInfoStr = NULL;
+ }
+
+ if (newVersionStr != NULL) {
+ PR_Free( (char *) newVersionStr);
+ newVersionStr = NULL;
+ }
+
+ if( token_status != NULL ) {
+ delete token_status;
+ token_status = NULL;
+ }
+ if( CardManagerAID != NULL ) {
+ delete CardManagerAID;
+ CardManagerAID = NULL;
+ }
+ if( NetKeyAID != NULL ) {
+ delete NetKeyAID;
+ NetKeyAID = NULL;
+ }
+ if( login != NULL ) {
+ delete login;
+ login = NULL;
+ }
+ if( new_pin != NULL ) {
+ PL_strfree( new_pin );
+ new_pin = NULL;
+ }
+ if( channel != NULL ) {
+ delete channel;
+ channel = NULL;
+ }
+ if( cuid != NULL ) {
+ PR_Free( (char *) cuid );
+ cuid = NULL;
+ }
+ if( msn != NULL ) {
+ PR_Free( (char *) msn );
+ msn = NULL;
+ }
+ if( buildID != NULL ) {
+ delete buildID;
+ buildID = NULL;
+ }
+ if( appletVersion != NULL ) {
+ PR_Free( (char *) appletVersion );
+ appletVersion = NULL;
+ }
+ if( final_applet_version != NULL ) {
+ PR_Free( (char *) final_applet_version );
+ final_applet_version = NULL;
+ }
+ if( keyVersion != NULL ) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+ if( userid != NULL ) {
+ PR_Free( (char *) userid );
+ userid = NULL;
+ }
+ if( authParams != NULL ) {
+ delete authParams;
+ authParams = NULL;
+ }
+ if( cplc_data != NULL ) {
+ delete cplc_data;
+ cplc_data = NULL;
+ }
+
+ if (tokenOwner != NULL) {
+ ldap_value_free_len(tokenOwner);
+ tokenOwner = NULL;
+ }
+
+ if (ldapResult != NULL) {
+ ldap_msgfree(ldapResult);
+ ldapResult = NULL;
+ }
+
+#ifdef MEM_PROFILING
+ MEM_dump_unfree();
+#endif
+
+ return status;
+} /* Process */
diff --git a/base/tps/src/processor/RA_Processor.cpp b/base/tps/src/processor/RA_Processor.cpp
new file mode 100644
index 000000000..a9947555b
--- /dev/null
+++ b/base/tps/src/processor/RA_Processor.cpp
@@ -0,0 +1,3506 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "plstr.h"
+#include "engine/RA.h"
+#include "main/Buffer.h"
+#include "main/Base.h"
+#include "main/Util.h"
+#include "main/RA_Session.h"
+#include "main/RA_Msg.h"
+#include "main/Login.h"
+#include "main/SecureId.h"
+#include "main/Util.h"
+#include "httpClient/httpc/http.h"
+#include "httpClient/httpc/request.h"
+#include "httpClient/httpc/response.h"
+#include "httpClient/httpc/engine.h"
+#include "processor/RA_Processor.h"
+#include "cms/HttpConnection.h"
+#include "cms/CertEnroll.h"
+#include "msg/RA_Status_Update_Request_Msg.h"
+#include "msg/RA_Status_Update_Response_Msg.h"
+#include "msg/RA_Login_Request_Msg.h"
+#include "msg/RA_Login_Response_Msg.h"
+#include "msg/RA_Extended_Login_Request_Msg.h"
+#include "msg/RA_Extended_Login_Response_Msg.h"
+#include "msg/RA_ASQ_Request_Msg.h"
+#include "msg/RA_ASQ_Response_Msg.h"
+#include "msg/RA_New_Pin_Request_Msg.h"
+#include "msg/RA_New_Pin_Response_Msg.h"
+#include "msg/RA_SecureId_Request_Msg.h"
+#include "msg/RA_SecureId_Response_Msg.h"
+#include "msg/RA_Token_PDU_Request_Msg.h"
+#include "msg/RA_Token_PDU_Response_Msg.h"
+#include "apdu/Lifecycle_APDU.h"
+#include "apdu/Format_Muscle_Applet_APDU.h"
+#include "apdu/Initialize_Update_APDU.h"
+#include "apdu/Get_Version_APDU.h"
+#include "apdu/External_Authenticate_APDU.h"
+#include "apdu/Create_Object_APDU.h"
+#include "apdu/Get_Status_APDU.h"
+#include "apdu/Get_Data_APDU.h"
+#include "apdu/Set_Pin_APDU.h"
+#include "apdu/Read_Buffer_APDU.h"
+#include "apdu/Write_Object_APDU.h"
+#include "apdu/List_Objects_APDU.h"
+#include "apdu/Generate_Key_APDU.h"
+#include "apdu/List_Pins_APDU.h"
+#include "apdu/Create_Pin_APDU.h"
+#include "apdu/Put_Key_APDU.h"
+#include "apdu/Select_APDU.h"
+#include "apdu/APDU_Response.h"
+#include "channel/Secure_Channel.h"
+#include "main/Memory.h"
+
+#if 0
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include "tus/tus_db.h"
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+/**
+ * Constructs a base processor.
+ */
+RA_Processor::RA_Processor ()
+{
+ totalAvailableMemory = 0;
+ totalFreeMemory = 0;
+}
+
+
+/**
+ * Destructs processor.
+ */
+RA_Processor::~RA_Processor ()
+{
+}
+
+AuthenticationEntry *RA_Processor::GetAuthenticationEntry(
+ const char *prefix, const char * a_configname, const char *a_tokenType)
+{
+ AuthenticationEntry *auth = NULL;
+
+ if (!RA::GetConfigStore()->GetConfigAsBool(a_configname, false))
+ return NULL;
+
+ RA::Debug("RA_Enroll_Processor::AuthenticateUser",
+ "Authentication enabled");
+ char configname[256];
+ PR_snprintf((char *)configname, 256, "%s.%s.auth.id", prefix, a_tokenType);
+ const char *authid = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (authid == NULL) {
+ goto loser;
+ }
+ auth = RA::GetAuth(authid);
+ return auth;
+loser:
+ return NULL;
+}
+
+
+void RA_Processor::StatusUpdate(RA_Session *a_session,
+ NameValueSet *a_extensions,
+ int a_status, const char *a_info)
+{
+ if (a_extensions != NULL) {
+ if (a_extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(a_session, a_status, a_info);
+ }
+ }
+}
+
+void RA_Processor::StatusUpdate(RA_Session *session,
+ int status, const char *info)
+{
+ RA_Status_Update_Request_Msg *status_update_request_msg = NULL;
+ RA_Status_Update_Response_Msg *status_update_response_msg = NULL;
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::StatusUpdate",
+ "RA_Processor::StatusUpdate");
+
+ status_update_request_msg = new RA_Status_Update_Request_Msg(
+ status, info);
+ session->WriteMsg(status_update_request_msg);
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::StatusUpdate",
+ "Sent status_update_msg");
+
+ status_update_response_msg = (RA_Status_Update_Response_Msg *)
+ session->ReadMsg();
+ if (status_update_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::StatusUpdate",
+ "No Status Update Response Msg Received");
+ goto loser;
+ }
+ if (status_update_response_msg->GetType() != MSG_STATUS_UPDATE_RESPONSE) {
+ RA::Error("Secure_Channel::StatusUpdate",
+ "Invalid Msg Type");
+ goto loser;
+ }
+
+loser:
+ if( status_update_request_msg != NULL ) {
+ delete status_update_request_msg;
+ status_update_request_msg = NULL;
+ }
+ if( status_update_response_msg != NULL ) {
+ delete status_update_response_msg;
+ status_update_response_msg = NULL;
+ }
+
+} /* StatusUpdate */
+
+/**
+ * Requests login ID and password from user.
+ */
+AuthParams *RA_Processor::RequestExtendedLogin(RA_Session *session,
+ int invalid_pw, int blocked,
+ char **parameters, int len, char *title, char *description)
+{
+ RA_Extended_Login_Request_Msg *login_request_msg = NULL;
+ RA_Extended_Login_Response_Msg *login_response_msg = NULL;
+ AuthParams *login = NULL;
+ AuthParams *c = NULL;
+ int i = 0;
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::RequestExtendedLogin",
+ "RA_Processor::RequestExtendedLogin %s %s",
+ title, description);
+
+ login_request_msg = new RA_Extended_Login_Request_Msg(
+ invalid_pw, blocked, parameters, len, title, description);
+ session->WriteMsg(login_request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::RequestExtendedLogin",
+ "Sent login_request_msg");
+
+ login_response_msg = (RA_Extended_Login_Response_Msg *)
+ session->ReadMsg();
+ if (login_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::RequestExtendedLogin",
+ "No Extended Login Response Msg Received");
+ goto loser;
+ }
+ if (login_response_msg->GetType() != MSG_EXTENDED_LOGIN_RESPONSE) {
+ RA::Error("Secure_Channel::Login_Request",
+ "Invalid Msg Type");
+ goto loser;
+ }
+
+ login = new AuthParams();
+ c = login_response_msg->GetAuthParams();
+ for (i = 0; i < c->Size(); i++) {
+ login->Add(c->GetNameAt(i), c->GetValue(c->GetNameAt(i)));
+ }
+
+loser:
+ if( login_request_msg != NULL ) {
+ delete login_request_msg;
+ login_request_msg = NULL;
+ }
+ if( login_response_msg != NULL ) {
+ delete login_response_msg;
+ login_response_msg = NULL;
+ }
+
+ return login;
+} /* RequestExtendedLogin */
+
+/**
+ * Requests login ID and password from user.
+ */
+AuthParams *RA_Processor::RequestLogin(RA_Session *session,
+ int invalid_pw, int blocked)
+{
+ RA_Login_Request_Msg *login_request_msg = NULL;
+ RA_Login_Response_Msg *login_response_msg = NULL;
+ AuthParams *login = NULL;
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::Login_Request",
+ "RA_Processor::Login_Request");
+
+ login_request_msg = new RA_Login_Request_Msg(
+ invalid_pw, blocked);
+ session->WriteMsg(login_request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::Login_Request",
+ "Sent login_request_msg");
+
+ login_response_msg = (RA_Login_Response_Msg *)
+ session->ReadMsg();
+ if (login_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::Login_Request",
+ "No Login Response Msg Received");
+ goto loser;
+ }
+ if (login_response_msg->GetType() != MSG_LOGIN_RESPONSE) {
+ RA::Error("Secure_Channel::Login_Request",
+ "Invalid Msg Type");
+ goto loser;
+ }
+ login = new AuthParams();
+ login->Add("UID", login_response_msg->GetUID());
+ login->Add("PASSWORD", login_response_msg->GetPassword());
+
+loser:
+ if( login_request_msg != NULL ) {
+ delete login_request_msg;
+ login_request_msg = NULL;
+ }
+ if( login_response_msg != NULL ) {
+ delete login_response_msg;
+ login_response_msg = NULL;
+ }
+
+ return login;
+} /* RequestLogin */
+
+/**
+ * Upgrade the applet to the current session with the new version.
+ */
+int RA_Processor::UpgradeApplet(RA_Session *session, char *prefix, char *tokenType, BYTE major_version, BYTE minor_version, const char *new_version, const char *applet_dir, SecurityLevel security_level, const char *connid,
+ NameValueSet *extensions,
+ int start_progress,
+ int end_progress,
+ char **key_version)
+{
+ Buffer *NetKeyAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_NETKEY_INSTANCE_AID,
+ RA::CFG_DEF_NETKEY_INSTANCE_AID);
+ Buffer *OldAAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_NETKEY_OLD_INSTANCE_AID,
+ RA::CFG_DEF_NETKEY_OLD_INSTANCE_AID);
+ Buffer *OldPAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_NETKEY_OLD_FILE_AID,
+ RA::CFG_DEF_NETKEY_OLD_FILE_AID);
+ Buffer *NetKeyPAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_NETKEY_FILE_AID,
+ RA::CFG_DEF_NETKEY_FILE_AID);
+ Buffer *PIN = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_SO_PIN,
+ RA::CFG_DEF_APPLET_SO_PIN);
+ Buffer empty;
+ PRFileDesc *f = NULL;
+ char path[4096];
+ char configname[4096];
+ PRFileInfo info;
+ PRStatus status;
+ int rc = 0;
+ Secure_Channel *channel = NULL;
+ int size_to_send = 0;
+ char *dataf = NULL;
+ int block_size;
+ BYTE refControl;
+ int count;
+ Buffer programFile;
+ Buffer tag;
+ Buffer length;
+ Buffer tbsProgramFile;
+ unsigned int totalLen;
+ int num_loops;
+ float progress_block_size;
+ int x_blocksize;
+ int instance_size;
+ int applet_memory_size;
+ int defKeyVer;
+ int defKeyIndex;
+ char *ext;
+
+ if (applet_dir == NULL) {
+ RA::Error(LL_PER_PDU, "RA_Processor::UpgradeApplet",
+ "Failed to get upgrade.directory");
+ goto loser;
+ }
+ sprintf(configname, "general.applet_ext");
+ ext = (char*)RA::GetConfigStore()->GetConfigAsString(configname, "ijc");
+ sprintf(path, "%s/%s.%s", applet_dir, new_version, ext);
+ RA::Debug("RA_Processor::UpgradeApplet", "path = %s", path);
+ status = PR_GetFileInfo(path, &info);
+ if (status != PR_SUCCESS) {
+ RA::Error(LL_PER_PDU, "RA_Processor::UpgradeApplet",
+ "Failed to get file info");
+ goto loser;
+ }
+ f = PR_Open(path, PR_RDONLY, 400);
+ if (f == NULL) {
+ RA::Error(LL_PER_PDU, "RA_Processor::UpgradeApplet",
+ "Failed to open '%s'", path);
+ goto loser;
+ }
+ dataf = (char *)malloc(info.size);
+ PR_Read(f, dataf, info.size);
+ if( f != NULL ) {
+ PR_Close( f );
+ f = NULL;
+ }
+
+ /* Select Applet - Select Card manager */
+ SelectCardManager(session, prefix, tokenType);
+
+ PR_snprintf((char *)configname, 256,"channel.blockSize");
+ x_blocksize = RA::GetConfigStore()->GetConfigAsInt(configname, 0xf8);
+ PR_snprintf((char *)configname, 256,"channel.instanceSize");
+ instance_size = RA::GetConfigStore()->GetConfigAsInt(configname, 18000);
+
+ PR_snprintf((char *)configname, 256,"channel.appletMemorySize");
+
+ applet_memory_size = RA::GetConfigStore()->GetConfigAsInt(configname, 5000);
+
+ PR_snprintf((char *)configname, 256,"channel.defKeyVersion");
+ defKeyVer = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ PR_snprintf((char *)configname, 256,"channel.defKeyIndex");
+ defKeyIndex = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ channel = SetupSecureChannel(session, defKeyVer, defKeyIndex, security_level, connid);
+ if (channel == NULL) {
+ RA::Error(LL_PER_PDU, "RA_Processor::UpgradeApplet",
+ "channel creation failure");
+ rc = -1;
+ goto loser;
+ }
+
+ // get keyVersion
+ if (channel != NULL) {
+ *key_version = Util::Buffer2String(channel->GetKeyInfoData());
+ }
+
+ if (channel->ExternalAuthenticate() == -1) {
+ RA::Error(LL_PER_PDU, "RA_Processor::UpgradeApplet",
+ "failed to external authenticate during upgrade");
+ goto loser;
+ }
+
+ /* Delete File - Delete 627601ff000000 (CoolKey Instance) */
+ rc = channel->DeleteFileX(session, NetKeyAID);
+ if (rc != 1) {
+ /* it is ok to fail to delete file */
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::UpgradeApplet",
+ "Warning: failed to delete file", NetKeyAID);
+ }
+
+ if (RA::GetConfigStore()->GetConfigAsBool(RA::CFG_APPLET_DELETE_NETKEY_OLD, true)) {
+ /* Delete File - Delete a00000000101 */
+ rc = channel->DeleteFileX(session, OldAAID);
+ if (rc != 1) {
+ /* it is ok to fail to delete file */
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::UpgradeApplet",
+ "Warning: failed to delete file", OldAAID);
+ }
+ /* Delete File - Delete a000000001 */
+ rc = channel->DeleteFileX(session, OldPAID);
+ if (rc != 1) {
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::UpgradeApplet",
+ "Warning: failed to delete file", OldPAID);
+ }
+ }
+
+ /* Delete File - Delete 627601ff0000 */
+ channel->DeleteFileX(session, NetKeyPAID);
+
+ /* Install Applet - Install applet instance */
+ channel->InstallLoad(session,
+ *NetKeyPAID,
+ empty,
+ info.size);
+
+ /* Multiple Load Program File - Load 627601ff0000 */
+ programFile = Buffer ((BYTE *)dataf, info.size);
+ if( dataf != NULL ) {
+ free( dataf );
+ dataf = NULL;
+ }
+ tag = Buffer(1, 0xC4);
+ tbsProgramFile = tag + length + programFile;
+ totalLen = tbsProgramFile.size();
+ if( programFile.size() < 128 ) {
+ length = Buffer(1, programFile.size());
+ } else if( programFile.size() <= 255 ) {
+ length = Buffer(2, 0);
+ ((BYTE*)length)[0] = 0x81;
+ ((BYTE*)length)[1] = programFile.size();
+ } else {
+ length = Buffer(3, 0);
+ ((BYTE*)length)[0] = 0x82;
+ ((BYTE*)length)[1] = (programFile.size() >> 8) & 0xff;
+ ((BYTE*)length)[2] = programFile.size() & 0xff;
+ }
+ tbsProgramFile = tag + length + programFile;
+ totalLen = tbsProgramFile.size();
+
+ size_to_send = totalLen;
+ if (security_level == SECURE_MSG_MAC_ENC) {
+ // need leave room for possible encryption padding
+ block_size = x_blocksize - 0x10;
+ } else {
+ block_size = x_blocksize - 8;
+ }
+
+ // rough number is good enough
+ num_loops = size_to_send / block_size;
+ progress_block_size = (float) (end_progress - start_progress) / num_loops;
+
+ count = 0;
+ refControl = 0x00; // intermediate block
+ do {
+ if (size_to_send < block_size) {
+ block_size = size_to_send;
+ // last block
+ refControl = 0x80;
+ }
+ if (size_to_send - block_size == 0) {
+ // last block
+ refControl = 0x80;
+ }
+ Buffer d = tbsProgramFile.substr(totalLen - size_to_send, block_size);
+ channel->LoadFile(session, (BYTE)refControl, (BYTE)count, &d);
+
+ size_to_send -= block_size;
+
+ // send status update to the client
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session,
+ start_progress + (count * progress_block_size) /* progress */,
+ "PROGRESS_APPLET_BLOCK");
+ }
+ count++;
+ } while (size_to_send > 0);
+
+
+ /* Install Applet - Install applet instance */
+ channel->InstallApplet(session,
+ *NetKeyPAID,
+ *NetKeyAID,
+ 0 /* appPrivileges */,
+ instance_size /* instanceSize */,
+ applet_memory_size /* appletMemorySize */);
+
+ /* Select File - Select 627601ff000000 */
+ SelectApplet(session, 0x04, 0x00, NetKeyAID);
+
+ rc = 1;
+loser:
+ if( NetKeyAID != NULL ) {
+ delete NetKeyAID;
+ NetKeyAID = NULL;
+ }
+ if( OldAAID != NULL ) {
+ delete OldAAID;
+ OldAAID = NULL;
+ }
+ if( OldPAID != NULL ) {
+ delete OldPAID;
+ OldPAID = NULL;
+ }
+ if( NetKeyPAID != NULL ) {
+ delete NetKeyPAID;
+ NetKeyPAID = NULL;
+ }
+ if( PIN != NULL ) {
+ delete PIN;
+ PIN = NULL;
+ }
+ if( channel != NULL ) {
+ delete channel;
+ channel = NULL;
+ }
+ if( dataf != NULL ) {
+ free( dataf );
+ dataf = NULL;
+ }
+
+ return rc;
+}
+
+char *RA_Processor::MapPattern(NameValueSet *nv, char *pattern)
+{
+ int i=0,x=0,j=0,z=0;
+ unsigned int q = 0;
+ char token[4096];
+ char result[4096];
+ char *value;
+
+ if (pattern == NULL)
+ return NULL;
+ i = strlen(pattern);
+ for (x = 0; x < i; x++) {
+ if (pattern[x] == '$') {
+ if (pattern[x+1] == '$') {
+ result[z] = pattern[x];
+ z++;
+ x++;
+ } else {
+ x++;
+ j = 0;
+ while (pattern[x] != '$') {
+ token[j] = pattern[x];
+ j++;
+ x++;
+ }
+ token[j] = '\0';
+ value = nv->GetValue(token);
+ if (value != NULL) {
+ for (q = 0; q < strlen(value); q++) {
+ result[z] = value[q];
+ z++;
+ }
+
+ }
+ }
+ } else {
+ result[z] = pattern[x];
+ z++;
+ }
+ }
+ result[z] = '\0';
+
+ return PL_strdup(result);
+}
+
+int RA_Processor::FormatMuscleApplet(RA_Session *session,
+ unsigned short memSize,
+ Buffer &PIN0, BYTE pin0Tries,
+ Buffer &unblockPIN0, BYTE unblock0Tries,
+ Buffer &PIN1, BYTE pin1Tries,
+ Buffer &unblockPIN1, BYTE unblock1Tries,
+ unsigned short objCreationPermissions,
+ unsigned short keyCreationPermissions,
+ unsigned short pinCreationPermissions)
+{
+ int rc = 0;
+ APDU_Response *format_response = NULL;
+ RA_Token_PDU_Request_Msg *format_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *format_response_msg = NULL;
+ Format_Muscle_Applet_APDU *format_apdu = NULL;
+ // Buffer *mac = NULL;
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::FormatMuscle",
+ "RA_Processor::FormatMuscle");
+
+ format_apdu = new Format_Muscle_Applet_APDU(memSize, PIN0, pin0Tries,
+ unblockPIN0, unblock0Tries,
+ PIN1, pin1Tries,
+ unblockPIN1, unblock1Tries,
+ objCreationPermissions,
+ keyCreationPermissions,
+ pinCreationPermissions);
+ format_request_msg =
+ new RA_Token_PDU_Request_Msg(format_apdu);
+ session->WriteMsg(format_request_msg);
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::FormatMuscle",
+ "Sent format_request_msg");
+
+ format_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (format_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::FormatMuscle",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (format_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::FormatMuscle",
+ "Invalid Message Type");
+ goto loser;
+ }
+ format_response = format_response_msg->GetResponse();
+ if (!(format_response->GetSW1() == 0x90 &&
+ format_response->GetSW2() == 0x00)) {
+ RA::Error(LL_PER_PDU, "RA_Processor::FormatMuscle",
+ "Bad Response");
+ goto loser;
+ }
+ rc = 1;
+
+loser:
+ if( format_request_msg != NULL ) {
+ delete format_request_msg;
+ format_request_msg = NULL;
+ }
+ if( format_response_msg != NULL ) {
+ delete format_response_msg;
+ format_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+/**
+ * Determine the Token Type. The user can set up mapping rules in the
+ * config file which allow different operations depending on the
+ * CUID, applet version, ATR, etc.
+ */
+bool RA_Processor::GetTokenType(const char *prefix, int major_version, int minor_version, const char *cuid, const char *msn, NameValueSet *extensions,
+ RA_Status &o_status /* out */, const char *&o_tokenType /* out */)
+{
+ const char *e_tokenATR = NULL;
+ const char *tokenATR = NULL;
+ const char *e_tokenType = NULL;
+ const char *tokenType = NULL;
+ const char *tokenCUIDStart = NULL;
+ const char *tokenCUIDEnd = NULL;
+ const char *targetTokenType = NULL;
+ const char *majorVersion = NULL;
+ const char *minorVersion = NULL;
+ const char *order = NULL;
+ char *order_x = NULL;
+ const char *mappingId = NULL;
+ char configname[256];
+ int start_pos = 0, done = 0;
+ unsigned int end_pos = 0;
+ const char *cuid_x = NULL;
+ int rc=0;
+
+ cuid_x = cuid;
+
+ sprintf(configname, "%s.mapping.order", prefix);
+ order = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (order == NULL) {
+ RA::Error("RA_Processor::GetTokenType", "Token type is not found");
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND;
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetTokenType",
+ "cannot find config ", configname);
+ return false; /* no mapping found */
+ }
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetTokenType",
+ "Starting:");
+ order_x = PL_strdup(order);
+
+ start_pos = 0;
+ end_pos = 0;
+ done = 0;
+ while (1)
+ {
+ if (done) {
+ break;
+ }
+ end_pos = start_pos;
+ while ((end_pos < strlen(order)) && (order_x[end_pos] != ',')) {
+ end_pos++;
+ }
+ if (end_pos < strlen(order)) {
+ order_x[end_pos] = '\0';
+ done = 0;
+ } else {
+ done = 1;
+ }
+ mappingId = &order_x[start_pos];
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetTokenType",
+ "mappingId='%s'", mappingId);
+
+ start_pos = end_pos + 1;
+
+ sprintf(configname, "%s.mapping.%s.target.tokenType", prefix,
+ mappingId);
+ targetTokenType = RA::GetConfigStore()->GetConfigAsString(configname);
+
+
+ if (targetTokenType == NULL) {
+ break;
+ }
+ sprintf(configname, "%s.mapping.%s.filter.tokenType", prefix,
+ mappingId);
+ tokenType = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetTokenType",
+ "tokenType: %s",tokenType);
+
+ if (tokenType != NULL && strlen(tokenType) > 0) {
+ if (extensions == NULL) {
+ continue; /* mapping not matched, next mapping */
+ }
+ e_tokenType = extensions->GetValue("tokenType");
+ if (e_tokenType == NULL) {
+ continue; /* mapping not matched, next mapping */
+ }
+ if (strcmp(tokenType, e_tokenType) != 0) {
+ continue; /* mapping not matched, next mapping */
+ }
+ }
+ sprintf(configname, "%s.mapping.%s.filter.tokenATR", prefix,
+ mappingId);
+ tokenATR = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (tokenATR != NULL && strlen(tokenATR) > 0) {
+ if (extensions == NULL) {
+ continue; /* mapping not matched, next mapping */
+ }
+ e_tokenATR = extensions->GetValue("tokenATR");
+ if (e_tokenATR == NULL) {
+ continue; /* mapping not matched, next mapping */
+ }
+ if (strcmp(tokenATR, e_tokenATR) != 0) {
+ continue; /* mapping not matched, next mapping */
+ }
+ }
+ sprintf(configname, "%s.mapping.%s.filter.tokenCUID.start", prefix,
+ mappingId);
+ tokenCUIDStart = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (tokenCUIDStart != NULL && strlen(tokenCUIDStart) > 0) {
+ if (cuid_x == NULL) {
+ continue; /* mapping not matched, next mapping */
+ }
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetTokenType",
+ "cuid_x=%s tokenCUIDStart=%s %d", cuid_x, tokenCUIDStart,
+ PL_strcasecmp(cuid_x, tokenCUIDStart));
+
+ if(strlen(tokenCUIDStart) != 20)
+ {
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetTokenType",
+ "Invalid tokenCUIDStart: %s",tokenCUIDStart);
+ continue;
+ }
+
+ char *pend = NULL;
+ rc = strtol((const char *) tokenCUIDStart, &pend, 16);
+
+ if(*pend != '\0')
+ {
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetTokenType",
+ "Invalid tokenCUIDStart: %s",tokenCUIDStart);
+
+ continue;
+ }
+
+ if (PL_strcasecmp(cuid_x, tokenCUIDStart) < 0) {
+ continue; /* mapping not matched, next mapping */
+ }
+ }
+ sprintf(configname, "%s.mapping.%s.filter.tokenCUID.end", prefix,
+ mappingId);
+ tokenCUIDEnd = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (tokenCUIDEnd != NULL && strlen(tokenCUIDEnd) > 0) {
+ if (cuid_x == NULL) {
+ continue; /* mapping not matched, next mapping */
+ }
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetTokenType",
+ "cuid_x=%s tokenCUIDEnd=%s %d", cuid_x, tokenCUIDEnd,
+ PL_strcasecmp(cuid_x, tokenCUIDEnd));
+
+ if(strlen(tokenCUIDEnd) != 20)
+ {
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetTokenType",
+ "Invalid tokenCUIDEnd: %s",tokenCUIDEnd);
+ continue;
+ }
+
+ char *pend = NULL;
+ rc = strtol((const char *) tokenCUIDEnd, &pend, 16);
+
+ if(*pend != '\0')
+ {
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetTokenType",
+ "Invalid tokenCUIDEnd: %s",tokenCUIDEnd);
+
+ continue;
+ }
+
+ if (PL_strcasecmp(cuid_x, tokenCUIDEnd) > 0) {
+ continue; /* mapping not matched, next mapping */
+ }
+ }
+ sprintf(configname, "%s.mapping.%s.filter.appletMajorVersion",
+ prefix, mappingId);
+ majorVersion = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (majorVersion != NULL && strlen(majorVersion) > 0) {
+ if (major_version != atoi(majorVersion)) {
+ continue; /* mapping not matched, next mapping */
+ }
+ }
+ sprintf(configname, "%s.mapping.%s.filter.appletMinorVersion",
+ prefix, mappingId);
+ minorVersion = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (minorVersion != NULL && strlen(minorVersion) > 0) {
+ if (minor_version != atoi(minorVersion)) {
+ continue; /* mapping not matched, next mapping */
+ }
+ }
+
+ if( order_x != NULL ) {
+ PL_strfree( order_x );
+ order_x = NULL;
+ }
+ RA::Debug("RA_Processor::GetTokenType",
+ "Selected Token type is '%s'", targetTokenType);
+ o_tokenType = targetTokenType;
+ return true;
+ }
+
+
+ if( order_x != NULL ) {
+ PL_strfree( order_x );
+ order_x = NULL;
+ }
+ RA::Error("RA_Processor::GetTokenType", "Token type is not found");
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND;
+
+ return false;
+}
+
+int RA_Processor::SelectCardManager(RA_Session *session, char *prefix, char *tokenType)
+{
+ char configname[256];
+ int rc;
+ PR_snprintf((char *)configname, 256, "%s.%s.cardmgr_instance", prefix, tokenType);
+ const char *cardmgr_instance =
+ RA::GetConfigStore()->GetConfigAsString(configname);
+ Buffer *CardManagerAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ cardmgr_instance, RA::CFG_DEF_CARDMGR_INSTANCE_AID);
+ rc = SelectApplet(session, 0x04, 0x00, CardManagerAID);
+ if( CardManagerAID != NULL ) {
+ delete CardManagerAID;
+ CardManagerAID = NULL;
+ }
+ return rc;
+}
+
+/**
+ * GetData
+ */
+Buffer *RA_Processor::GetData(RA_Session *session)
+{
+ Buffer data;
+ Buffer *status = NULL;
+ APDU_Response *get_data_response = NULL;
+ RA_Token_PDU_Request_Msg *get_data_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *get_data_response_msg = NULL;
+ Get_Data_APDU *get_data_apdu = NULL;
+ Buffer get_status_data;
+
+ get_data_apdu =
+ new Get_Data_APDU();
+ get_data_request_msg =
+ new RA_Token_PDU_Request_Msg(get_data_apdu);
+ session->WriteMsg(get_data_request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetData",
+ "Sent get_data_request_msg");
+
+ get_data_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (get_data_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::GetData",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (get_data_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::GetData",
+ "Invalid Message Type");
+ goto loser;
+ }
+ get_data_response =
+ get_data_response_msg->GetResponse();
+ if (get_data_response == NULL) {
+ RA::Error(LL_PER_PDU, "Secure_Channel::GetData",
+ "No Response From Token");
+ goto loser;
+ }
+ data = get_data_response->GetData();
+
+ if (!(get_data_response->GetSW1() == 0x90 &&
+ get_data_response->GetSW2() == 0x00)) {
+ RA::Error(LL_PER_PDU, "RA_Processor::GetData",
+ "Bad Response");
+ goto loser;
+ }
+
+ status = new Buffer(data.substr(0, data.size()));
+
+loser:
+
+ if( get_data_request_msg != NULL ) {
+ delete get_data_request_msg;
+ get_data_request_msg = NULL;
+ }
+ if( get_data_response_msg != NULL ) {
+ delete get_data_response_msg;
+ get_data_response_msg = NULL;
+ }
+
+ return status;
+}
+
+Buffer *RA_Processor::ListObjects(RA_Session *session, BYTE seq)
+{
+ Buffer data;
+ Buffer *status = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *request_msg = NULL;
+ RA_Token_PDU_Response_Msg *response_msg = NULL;
+ List_Objects_APDU *list_objects_apdu = NULL;
+ Buffer get_status_data;
+
+ list_objects_apdu =
+ new List_Objects_APDU(seq);
+ request_msg =
+ new RA_Token_PDU_Request_Msg(list_objects_apdu);
+ session->WriteMsg(request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::ListObjects",
+ "Sent request_msg");
+
+ response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::ListObjects",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::ListObjects",
+ "Invalid Message Type");
+ goto loser;
+ }
+ response = response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error(LL_PER_PDU, "Secure_Channel::ListObjects",
+ "No Response From Token");
+ goto loser;
+ }
+
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ // RA::Error(LL_PER_PDU, "RA_Processor::ListObjects",
+ // "Bad Response");
+ goto loser;
+ }
+
+ data = response->GetData();
+
+ status = new Buffer(data.substr(0, data.size()));
+
+loser:
+
+ if( request_msg != NULL ) {
+ delete request_msg;
+ request_msg = NULL;
+ }
+ if( response_msg != NULL ) {
+ delete response_msg;
+ response_msg = NULL;
+ }
+
+ return status;
+}
+
+/**
+ * GetStatus
+ */
+Buffer *RA_Processor::GetStatus(RA_Session *session, BYTE p1, BYTE p2)
+{
+ Buffer data;
+ Buffer *status = NULL;
+ APDU_Response *get_status_response = NULL;
+ RA_Token_PDU_Request_Msg *get_status_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *get_status_response_msg = NULL;
+ Get_Status_APDU *get_status_apdu = NULL;
+ Buffer get_status_data;
+
+ get_status_apdu =
+ new Get_Status_APDU();
+ get_status_request_msg =
+ new RA_Token_PDU_Request_Msg(get_status_apdu);
+ session->WriteMsg(get_status_request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetStatus",
+ "Sent get_status_request_msg");
+
+ get_status_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (get_status_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::GetStatus",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (get_status_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::GetStatus",
+ "Invalid Message Type");
+ goto loser;
+ }
+ get_status_response =
+ get_status_response_msg->GetResponse();
+ if (get_status_response == NULL) {
+ RA::Error(LL_PER_PDU, "Secure_Channel::GetStatus",
+ "No Response From Token");
+ goto loser;
+ }
+ data = get_status_response->GetData();
+
+ if (!(get_status_response->GetSW1() == 0x90 &&
+ get_status_response->GetSW2() == 0x00)) {
+ RA::Error(LL_PER_PDU, "RA_Processor::GetStatus",
+ "Bad Response");
+ goto loser;
+ }
+
+ status = new Buffer(data.substr(0, data.size()));
+
+loser:
+
+ if( get_status_request_msg != NULL ) {
+ delete get_status_request_msg;
+ get_status_request_msg = NULL;
+ }
+ if( get_status_response_msg != NULL ) {
+ delete get_status_response_msg;
+ get_status_response_msg = NULL;
+ }
+
+ return status;
+}
+
+int RA_Processor::CreatePin(RA_Session *session, BYTE pin_number,
+ BYTE max_retries, char *pin)
+{
+ int rc = -1;
+ Create_Pin_APDU *create_pin_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ Buffer *mac = NULL;
+
+ RA::Debug("Secure_Channel::IsPinPresent",
+ "Secure_Channel::IsPinPresent");
+ Buffer pin_buffer = Buffer((BYTE*)pin, strlen(pin));
+ create_pin_apdu = new Create_Pin_APDU(pin_number, max_retries,
+ pin_buffer);
+
+ /*
+ mac = ComputeAPDUMac(set_pin_apdu);
+ set_pin_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ create_pin_apdu);
+ session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::CreatePin",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::CreatePin",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::CreatePin",
+ "Invalid Message Type");
+ goto loser;
+ }
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::CreatePin",
+ "No Response From Token");
+ goto loser;
+ }
+
+ rc = 1;
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+}
+int RA_Processor::IsPinPresent(RA_Session *session, BYTE pin_number)
+{
+ int rc = -1;
+ Buffer data;
+ List_Pins_APDU *list_pins_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ Buffer *mac = NULL;
+
+ RA::Debug("Secure_Channel::IsPinPresent",
+ "Secure_Channel::IsPinPresent");
+ list_pins_apdu = new List_Pins_APDU(2);
+
+ /*
+ mac = ComputeAPDUMac(set_pin_apdu);
+ set_pin_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ list_pins_apdu);
+ session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::IsPinPresent",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::IsPinReset",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::IsPinReset",
+ "Invalid Message Type");
+ goto loser;
+ }
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::IsPinReset",
+ "No Response From Token");
+ goto loser;
+ }
+ data = response->GetData();
+ if (data.size() < 2) {
+ RA::Error(LL_PER_PDU, "Secure_Channel::IsPinReset",
+ "Invalid Response From Token");
+ goto loser;
+ }
+
+ if (pin_number < 8) {
+ rc = ((((BYTE*)data)[1] & (1 << pin_number)) > 0);
+ } else {
+ rc = ((((BYTE*)data)[0] & (1 << (pin_number - 8))) > 0);
+ }
+
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+/**
+ * Select applet.
+ *
+ * Global Platform Open Platform Card Specification
+ * Version 2.0.1 Page 9-22
+ *
+ * Sample Data:
+ *
+ * _____________ CLA
+ * | __________ INS
+ * | | _______ P1
+ * | | | ____ P2
+ * | | | | _ Len
+ * | | | | |
+ * 00 A4 04 00 07
+ * 53 4C 42 47 49 4E 41
+ */
+int RA_Processor::SelectApplet(RA_Session *session, BYTE p1, BYTE p2, Buffer *aid)
+{
+ int rc = 0;
+ APDU_Response *select_response = NULL;
+ RA_Token_PDU_Request_Msg *select_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *select_response_msg = NULL;
+ Select_APDU *select_apdu = NULL;
+
+ if (aid != NULL) {
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::SelectApplet",
+ "RA_Processor::SelectApplet with aid= ", aid);
+ }
+
+ select_apdu = new Select_APDU(p1, p2, *aid);
+ select_request_msg =
+ new RA_Token_PDU_Request_Msg(select_apdu);
+ session->WriteMsg(select_request_msg);
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::SelectApplet",
+ "Sent select_request_msg");
+
+ select_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (select_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::SelectApplet",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (select_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_PDU, "Secure_Channel::SelectApplet",
+ "Invalid Message Type");
+ goto loser;
+ }
+ select_response = select_response_msg->GetResponse();
+ if (select_response == NULL) {
+ RA::Error(LL_PER_PDU, "Secure_Channel::SelectApplet",
+ "No Response From Token");
+ goto loser;
+ }
+ if (select_response->GetData().size() < 2) {
+ RA::Error(LL_PER_PDU, "Secure_Channel::SelectApplet",
+ "Invalid Response From Token");
+ goto loser;
+ }
+ if (!(select_response->GetSW1() == 0x90 &&
+ select_response->GetSW2() == 0x00)) {
+ RA::Error(LL_PER_PDU, "RA_Processor::SelectApplet",
+ "Bad Response");
+ goto loser;
+ }
+
+
+loser:
+ if( select_request_msg != NULL ) {
+ delete select_request_msg;
+ select_request_msg = NULL;
+ }
+ if( select_response_msg != NULL ) {
+ delete select_response_msg;
+ select_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+/**
+ * Get Build ID from Net Key Applet.
+ * @returns a buffer with 4 bytes of data. This is the applet ID.
+ * The caller is responsible for freeing the buffer with
+ * the 'delete' operator.
+ */
+Buffer *RA_Processor::GetAppletVersion(RA_Session *session)
+{
+ Buffer data;
+ Buffer *buildID = NULL;
+ APDU_Response *get_version_response = NULL;
+ RA_Token_PDU_Request_Msg *get_version_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *get_version_response_msg = NULL;
+ Get_Version_APDU *get_version_apdu = NULL;
+ Buffer get_version_data;
+
+ get_version_apdu =
+ new Get_Version_APDU();
+ get_version_request_msg =
+ new RA_Token_PDU_Request_Msg(get_version_apdu);
+ session->WriteMsg(get_version_request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetAppletVersion",
+ "Sent get_version_request_msg");
+
+ get_version_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (get_version_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::GetAppletVersion",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (get_version_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::GetAppletVersion",
+ "Invalid Message Type");
+ goto loser;
+ }
+ get_version_response =
+ get_version_response_msg->GetResponse();
+ if (get_version_response == NULL) {
+ RA::Error(LL_PER_PDU, "Secure_Channel::GetAppletVersion",
+ "No Response From Token");
+ goto loser;
+ }
+ data = get_version_response->GetData();
+ if (!(get_version_response->GetSW1() == 0x90 &&
+ get_version_response->GetSW2() == 0x00)) {
+ RA::Error(LL_PER_PDU, "RA_Processor::GetAppletVersion",
+ "Bad Response");
+ goto loser;
+ }
+
+ /* Sample: 3FBAB4BF9000 */
+ if (data.size() != 6) {
+ RA::Error(LL_PER_PDU, "Secure_Channel::GetAppletVersion",
+ "Invalid Applet Version");
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::GetAppletVersion",
+ "Bad Applet Version: ",
+ &data);
+ goto loser;
+ }
+
+ buildID = new Buffer(data.substr(0, 4));
+
+/*
+ buildID = (get_version_data[0] << 24) | (get_version_data[1] << 16) |
+ (get_version_data[2] << 8) | get_version_data[3];
+
+*/
+
+loser:
+
+ if( get_version_request_msg != NULL ) {
+ delete get_version_request_msg;
+ get_version_request_msg = NULL;
+ }
+ if( get_version_response_msg != NULL ) {
+ delete get_version_response_msg;
+ get_version_response_msg = NULL;
+ }
+ return buildID;
+}
+
+/*
+ * this one sets the security level
+ */
+Secure_Channel *RA_Processor::SetupSecureChannel(RA_Session *session,
+ BYTE key_version, BYTE key_index, SecurityLevel security_level,
+ const char *connId)
+{
+ Secure_Channel *channel = SetupSecureChannel(session, key_version, key_index, connId);
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel","Resetting security level ...");
+
+ /* Bugscape Bug #55774: Prevent NetKey RA from crashing . . . */
+ if( channel != NULL ) {
+ channel->SetSecurityLevel(security_level);
+ } else {
+ RA::Error( LL_PER_PDU, "RA_Processor::SetupSecureChannel", "%s %s",
+ "Failed to create a secure channel - potentially due to an",
+ "RA/TKS key mismatch or differing RA/TKS key versions." );
+ }
+ return channel;
+
+}
+
+int RA_Processor::InitializeUpdate(RA_Session *session,
+ BYTE key_version, BYTE key_index,
+ Buffer &key_diversification_data,
+ Buffer &key_info_data,
+ Buffer &card_challenge,
+ Buffer &card_cryptogram,
+ Buffer &host_challenge, const char *connId)
+{
+ int rc = -1;
+ APDU_Response *initialize_update_response = NULL;
+ RA_Token_PDU_Request_Msg *initialize_update_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *initialize_update_response_msg = NULL;
+ Initialize_Update_APDU *initialize_update_apdu = NULL;
+ Buffer update_response_data;
+ char configname[256];
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "RA_Processor::InitializeUpdate");
+
+
+ PR_snprintf((char *) configname, 256, "conn.%s.generateHostChallenge", connId);
+ bool gen_host_challenge_tks = RA::GetConfigStore()->GetConfigAsBool(configname, true);
+
+ if(gen_host_challenge_tks) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Generate host challenge on TKS.");
+ rc = ComputeRandomData(host_challenge, (int) host_challenge.size(), connId);
+ } else {
+ rc = Util::GetRandomChallenge(host_challenge);
+ }
+
+ if(rc == -1) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Failed to generate host challenge");
+ goto loser;
+
+ }
+
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Generated Host Challenge",
+ &host_challenge);
+
+ initialize_update_apdu =
+ new Initialize_Update_APDU(key_version, key_index, host_challenge);
+ initialize_update_request_msg =
+ new RA_Token_PDU_Request_Msg(initialize_update_apdu);
+ session->WriteMsg(initialize_update_request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Sent initialize_update_request_msg");
+
+ initialize_update_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (initialize_update_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (initialize_update_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Invalid Message Type");
+ goto loser;
+ }
+ initialize_update_response =
+ initialize_update_response_msg->GetResponse();
+ update_response_data = initialize_update_response->GetData();
+
+ if (!(initialize_update_response->GetSW1() == 0x90 &&
+ initialize_update_response->GetSW2() == 0x00)) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Key version mismatch - key changeover to follow");
+ goto loser;
+ }
+
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Update Response Data", &update_response_data);
+
+ /**
+ * Initialize Update response:
+ * Key Diversification Data - 10 bytes
+ * Key Information Data - 2 bytes
+ * Card Challenge - 8 bytes
+ * Card Cryptogram - 8 bytes
+ */
+ if (initialize_update_response->GetData().size() < 10) {
+ RA::Error(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Invalid Initialize Update Response Size");
+ goto loser;
+ }
+ key_diversification_data = Buffer(update_response_data.substr(0, 10));
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Key Diversification Data", &key_diversification_data);
+ key_info_data = Buffer(update_response_data.substr(10, 2));
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Key Info Data", &key_info_data);
+ card_challenge = Buffer(update_response_data.substr(12, 8));
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Card Challenge", &card_challenge);
+ card_cryptogram = Buffer(update_response_data.substr(20, 8));
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Card Cryptogram", &card_cryptogram);
+
+ rc = 1;
+
+loser:
+ if( initialize_update_request_msg != NULL ) {
+ delete initialize_update_request_msg;
+ initialize_update_request_msg = NULL;
+ }
+ if( initialize_update_response_msg != NULL ) {
+ delete initialize_update_response_msg;
+ initialize_update_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+/**
+ * Setup secure channel between RA and the token.
+ */
+Secure_Channel *RA_Processor::SetupSecureChannel(RA_Session *session,
+ BYTE key_version, BYTE key_index, const char *connId)
+{
+ Secure_Channel *channel = NULL;
+ APDU_Response *initialize_update_response = NULL;
+ RA_Token_PDU_Request_Msg *initialize_update_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *initialize_update_response_msg = NULL;
+ Initialize_Update_APDU *initialize_update_apdu = NULL;
+ Buffer update_response_data;
+ Buffer host_challenge = Buffer(8, (BYTE)0);
+ Buffer key_diversification_data;
+ Buffer key_info_data;
+ Buffer card_challenge;
+ Buffer card_cryptogram;
+ char configname[256];
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::Setup_Secure_Channel");
+
+ PR_snprintf((char *) configname, 256, "conn.%s.generateHostChallenge", connId);
+ bool gen_host_challenge_tks = RA::GetConfigStore()->GetConfigAsBool(configname, false);
+
+ int rc = 0;
+ if(gen_host_challenge_tks) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Generate host challenge on TKS.");
+ rc = ComputeRandomData(host_challenge, (int) host_challenge.size(), connId);
+ } else {
+ rc = Util::GetRandomChallenge(host_challenge);
+ }
+
+ if(rc == -1) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::SetupSecureChannel",
+ "Failed to generate host challenge");
+ goto loser;
+
+ }
+
+
+
+ /* if (Util::GetRandomChallenge(host_challenge) != PR_SUCCESS)
+ {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Failed to generate host challenge");
+ goto loser;
+ }
+
+*/
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Generated Host Challenge",
+ &host_challenge);
+
+ initialize_update_apdu =
+ new Initialize_Update_APDU(key_version, key_index, host_challenge);
+ initialize_update_request_msg =
+ new RA_Token_PDU_Request_Msg(initialize_update_apdu);
+ session->WriteMsg(initialize_update_request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Sent initialize_update_request_msg");
+
+ initialize_update_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (initialize_update_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (initialize_update_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Invalid Message Type");
+ goto loser;
+ }
+ initialize_update_response =
+ initialize_update_response_msg->GetResponse();
+ update_response_data = initialize_update_response->GetData();
+
+ if (!(initialize_update_response->GetSW1() == 0x90 &&
+ initialize_update_response->GetSW2() == 0x00)) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Key version mismatch - key changeover to follow");
+ goto loser;
+ }
+
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Update Response Data", &update_response_data);
+
+ /**
+ * Initialize Update response:
+ * Key Diversification Data - 10 bytes
+ * Key Information Data - 2 bytes
+ * Card Challenge - 8 bytes
+ * Card Cryptogram - 8 bytes
+ */
+ if (initialize_update_response->GetData().size() < 28) {
+ RA::Error(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Invalid Initialize Update Response Size");
+ goto loser;
+ }
+ key_diversification_data = Buffer(update_response_data.substr(0, 10));
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Key Diversification Data", &key_diversification_data);
+ key_info_data = Buffer(update_response_data.substr(10, 2));
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Key Info Data", &key_info_data);
+ card_challenge = Buffer(update_response_data.substr(12, 8));
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Card Challenge", &card_challenge);
+ card_cryptogram = Buffer(update_response_data.substr(20, 8));
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Card Cryptogram", &card_cryptogram);
+
+ channel = GenerateSecureChannel(
+ session, connId,
+ key_diversification_data,
+ key_info_data,
+ card_challenge,
+ card_cryptogram,
+ host_challenge);
+
+loser:
+ if( initialize_update_request_msg != NULL ) {
+ delete initialize_update_request_msg;
+ initialize_update_request_msg = NULL;
+ }
+ if( initialize_update_response_msg != NULL ) {
+ delete initialize_update_response_msg;
+ initialize_update_response_msg = NULL;
+ }
+
+ return channel;
+} /* SetupSecureChannel */
+
+/**
+ * Requests secure ID.
+ */
+SecureId *RA_Processor::RequestSecureId(RA_Session *session)
+{
+ SecureId *secure_id = NULL;
+ RA_SecureId_Request_Msg *secureid_request_msg = NULL;
+ RA_SecureId_Response_Msg *secureid_response_msg = NULL;
+ char *value;
+ char *pin;
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::SecureId_Request",
+ "RA_Processor::SecureId_Request");
+
+ secureid_request_msg = new RA_SecureId_Request_Msg(
+ 0 /* pin_required */, 0 /* next_value */);
+ session->WriteMsg(secureid_request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::SecureId_Request",
+ "Sent secureid_request_msg");
+
+ secureid_response_msg = (RA_SecureId_Response_Msg *)
+ session->ReadMsg();
+ if (secureid_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::SecureId_Request",
+ "No SecureID Response Msg Received");
+ goto loser;
+ }
+
+ if (secureid_response_msg->GetType() != MSG_SECUREID_RESPONSE) {
+ RA::Error("Secure_Channel::SecureId_Request",
+ "Invalid Msg Type");
+ goto loser;
+ }
+
+ value = secureid_response_msg->GetValue();
+ pin = secureid_response_msg->GetPIN();
+
+ secure_id = new SecureId(value, pin);
+
+loser:
+
+ if( secureid_request_msg != NULL ) {
+ delete secureid_request_msg;
+ secureid_request_msg = NULL;
+ }
+ if( secureid_response_msg != NULL ) {
+ delete secureid_response_msg;
+ secureid_response_msg = NULL;
+ }
+ return secure_id;
+} /* RequestSecureId */
+
+/**
+ * Requests new pin for token.
+ */
+char *RA_Processor::RequestNewPin(RA_Session *session, unsigned int min, unsigned int max)
+{
+ char *new_pin = NULL;
+ RA_New_Pin_Request_Msg *new_pin_request_msg = NULL;
+ RA_New_Pin_Response_Msg *new_pin_response_msg = NULL;
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::New_Pin_Request",
+ "RA_Processor::New_Pin_Request");
+
+ new_pin_request_msg = new RA_New_Pin_Request_Msg(
+ min, max);
+ session->WriteMsg(new_pin_request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::New_Pin_Request",
+ "Sent new_pin_request_msg");
+
+ new_pin_response_msg = (RA_New_Pin_Response_Msg *)
+ session->ReadMsg();
+ if (new_pin_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::New_Pin_Request",
+ "No New Pin Response Msg Received");
+ goto loser;
+ }
+
+ if (new_pin_response_msg->GetType() != MSG_NEW_PIN_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::New_Pin_Request",
+ "Invalid Message Type");
+ goto loser;
+ }
+
+ if (new_pin_response_msg->GetNewPIN() == NULL) {
+ RA::Error(LL_PER_PDU, "RA_Processor::New_Pin_Request",
+ "No New Pin");
+ goto loser;
+ }
+
+ new_pin = PL_strdup(new_pin_response_msg->GetNewPIN());
+
+ if (strlen(new_pin) < min) {
+ RA::Error(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "The length of the new pin is shorter than the mininum length (%d)", min);
+ if( new_pin != NULL ) {
+ PL_strfree( new_pin );
+ new_pin = NULL;
+ }
+ new_pin = NULL;
+ goto loser;
+ } else if (strlen(new_pin) > max) {
+ RA::Error(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "The length of the new pin is longer than the maximum length (%d)", max);
+ if( new_pin != NULL ) {
+ PL_strfree( new_pin );
+ new_pin = NULL;
+ }
+ new_pin = NULL;
+ goto loser;
+ }
+
+loser:
+
+ if( new_pin_request_msg != NULL ) {
+ delete new_pin_request_msg;
+ new_pin_request_msg = NULL;
+ }
+ if( new_pin_response_msg != NULL ) {
+ delete new_pin_response_msg;
+ new_pin_response_msg = NULL;
+ }
+
+ return new_pin;
+} /* RequestNewPin */
+
+/**
+ * Requests A Security Question (ASQ) from user.
+ */
+char *RA_Processor::RequestASQ(RA_Session *session, char *question)
+{
+ char *answer = NULL;
+ RA_ASQ_Request_Msg *asq_request_msg = NULL;
+ RA_ASQ_Response_Msg *asq_response_msg = NULL;
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::ASQ_Request",
+ "RA_Processor::ASQ_Request");
+
+ asq_request_msg = new RA_ASQ_Request_Msg(question);
+ session->WriteMsg(asq_request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::ASQ_Request",
+ "Sent asq_request_msg");
+
+ asq_response_msg = (RA_ASQ_Response_Msg *)
+ session->ReadMsg();
+ if (asq_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::ASQ_Request",
+ "No ASQ Response Msg Received");
+ goto loser;
+ }
+ if (asq_response_msg->GetType() != MSG_ASQ_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::ASQ_Request",
+ "Invalid Message Type");
+ goto loser;
+ }
+
+ if (asq_response_msg->GetAnswer() == NULL) {
+ RA::Error(LL_PER_PDU, "RA_Processor::ASQ_Request",
+ "No ASQ Answer");
+ goto loser;
+ }
+ answer = PL_strdup(asq_response_msg->GetAnswer());
+
+loser:
+ if( asq_request_msg != NULL ) {
+ delete asq_request_msg;
+ asq_request_msg = NULL;
+ }
+ if( asq_response_msg != NULL ) {
+ delete asq_response_msg;
+ asq_response_msg = NULL;
+ }
+
+ return answer;
+} /* RequestASQ */
+
+/**
+ * Creates a secure channel between RA and the token.
+ * challenges are sent to TKS which generates
+ * host cryptogram, and session key.
+ */
+Secure_Channel *RA_Processor::GenerateSecureChannel(
+ RA_Session *session, const char *connId,
+ Buffer &key_diversification_data, /* CUID */
+ Buffer &key_info_data,
+ Buffer &card_challenge,
+ Buffer &card_cryptogram,
+ Buffer &host_challenge)
+{
+ PK11SymKey *session_key = NULL;
+ Buffer *host_cryptogram = NULL;
+ char configname[256];
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::GenerateSecureChannel");
+
+ PK11SymKey *enc_session_key = NULL;
+
+
+ // desKey_s will be assigned to channel and will be destroyed when channel closed
+ char *drm_desKey_s = NULL;
+ char *kek_desKey_s = NULL;
+ char *keycheck_s = NULL;
+
+ session_key = RA::ComputeSessionKey(session, key_diversification_data,
+ key_info_data, card_challenge,
+ host_challenge, &host_cryptogram,
+ card_cryptogram, &enc_session_key,
+ &drm_desKey_s, &kek_desKey_s,
+ &keycheck_s, connId);
+ if (session_key == NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::GenerateSecureChannel - did not get session_key");
+ return NULL;
+ }
+
+ // is serversideKeygen on?
+ PR_snprintf((char *) configname, 256, "conn.%s.serverKeygen", connId);
+ bool serverKeygen = RA::GetConfigStore()->GetConfigAsBool(configname, false);
+
+ if (serverKeygen) {
+ if ((drm_desKey_s == NULL) || (strcmp(drm_desKey_s, "")==0)) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::GenerateSecureChannel - did not get drm_desKey_s");
+ return NULL;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::GenerateSecureChannel - drm_desKey_s = %s", drm_desKey_s);
+ }
+ if ((kek_desKey_s == NULL) || (strcmp(kek_desKey_s,"")==0)) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::GenerateSecureChannel - did not get kek_desKey_s");
+ return NULL;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::GenerateSecureChannel - kek_desKey_s = %s", kek_desKey_s);
+ }
+ if ((keycheck_s == NULL) || (strcmp(keycheck_s,"")==0)) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::GenerateSecureChannel - did not get keycheck_s");
+ return NULL;
+ }
+
+ if (enc_session_key == NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::GenerateSecureChannel - did not get enc_session_key");
+ return NULL;
+ }
+ if (host_cryptogram == NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::GenerateSecureChannel - did not get host_cryptogram");
+ return NULL;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::GenerateSecureChannel - keycheck_s = %s", keycheck_s);
+ }
+ }
+/*
+ host_cryptogram = RA::ComputeHostCryptogram(
+ card_challenge, host_challenge);
+*/
+
+
+ Secure_Channel *channel = new Secure_Channel(session, session_key,
+ enc_session_key,
+ drm_desKey_s, kek_desKey_s, keycheck_s,
+ key_diversification_data, key_info_data,
+ card_challenge, card_cryptogram,
+ host_challenge, *host_cryptogram);
+
+ if( host_cryptogram != NULL ) {
+ delete host_cryptogram;
+ host_cryptogram = NULL;
+ }
+
+ if (channel != NULL) {
+ // this can be overridden by individual processor later
+ channel->SetSecurityLevel(RA::GetGlobalSecurityLevel());
+ } else {
+ if( session_key != NULL ) {
+ PK11_FreeSymKey( session_key );
+ session_key = NULL;
+ }
+ if( enc_session_key != NULL ) {
+ PK11_FreeSymKey( enc_session_key );
+ enc_session_key = NULL;
+ }
+
+ }
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::GenerateSecureChannel", "complete");
+ return channel;
+} /* GenerateSecureChannel */
+
+int RA_Processor::CreateKeySetData(Buffer &CUID, Buffer &version,
+ Buffer &NewMasterVer, Buffer &out, const char *connid)
+{
+ char body[5000];
+ char configname[256];
+ HttpConnection *tksConn = NULL;
+ tksConn = RA::GetTKSConn(connid);
+ if (tksConn == NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::CreateKeySetData", "Failed to get TKSConnection %s", connid);
+ RA::Error(LL_PER_PDU, "RA_Processor::CreateKeySetData", "Failed to get TKSConnection %s", connid);
+ return -1;
+ } else {
+ // PRLock *tks_lock = RA::GetTKSLock();
+ int tks_curr = RA::GetCurrentIndex(tksConn);
+ int currRetries = 0;
+ char *cuid = Util::SpecialURLEncode(CUID);
+ char *versionID = Util::SpecialURLEncode(version);
+ char *masterV = Util::SpecialURLEncode(NewMasterVer);
+
+ PR_snprintf((char *)configname, 256, "conn.%s.keySet", connid);
+ const char *keySet = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ PR_snprintf((char *)body, 5000,
+ "newKeyInfo=%s&CUID=%s&KeyInfo=%s&keySet=%s", masterV, cuid, versionID,keySet);
+
+ PR_snprintf((char *)configname, 256, "conn.%s.servlet.createKeySetData", connid);
+ const char *servletID = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ if( cuid != NULL ) {
+ PR_Free( cuid );
+ cuid = NULL;
+ }
+ if( versionID != NULL ) {
+ PR_Free( versionID );
+ versionID = NULL;
+ }
+ if( masterV != NULL ) {
+ PR_Free( masterV );
+ masterV = NULL;
+ }
+
+ tks_curr = RA::GetCurrentIndex(tksConn);
+
+ PSHttpResponse * response = tksConn->getResponse(tks_curr, servletID, body);
+ ConnectionInfo *connInfo = tksConn->GetFailoverList();
+ char **hostport = connInfo->GetHostPortList();
+
+ if (response == NULL)
+ RA::Debug(LL_PER_PDU, "The CreateKeySetData response from TKS ",
+ "at %s is NULL.", hostport[tks_curr]);
+ else
+ RA::Debug(LL_PER_PDU, "The CreateKeySetData response from TKS ",
+ "at % is not NULL.", hostport[tks_curr]);
+
+ while (response == NULL) {
+ RA::Failover(tksConn, connInfo->GetHostPortListLen());
+ tks_curr = RA::GetCurrentIndex(tksConn);
+
+ RA::Debug(LL_PER_PDU, "RA is reconnecting to TKS ",
+ "at %s for createKeySetData.", hostport[tks_curr]);
+
+ if (++currRetries >= tksConn->GetNumOfRetries()) {
+ RA::Debug(LL_PER_PDU, "Used up all the retries. Response is NULL","");
+ RA::Error(LL_PER_PDU, "RA_Processor::CreateKeySetData","Failed connecting to TKS after %d retries", currRetries);
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+ return -1;
+ }
+ response = tksConn->getResponse(tks_curr, servletID, body);
+ }
+
+ int status = 0;
+
+ Buffer *keydataset = NULL;
+ if (response != NULL) {
+ RA::Debug(LL_PER_PDU,"Response is not ","NULL");
+ char * content = response->getContent();
+ if (content == NULL) {
+ RA::Debug(LL_PER_PDU,"TKSConnection::CreateKeySetData","Content Is NULL");
+ } else {
+ RA::Debug(LL_PER_PDU,"TKSConnection::CreateKeySetData","Content Is '%s'",
+ content);
+ }
+ if (content != NULL) {
+ char *statusStr = strstr((char *)content, "status=0&");
+ if (statusStr == NULL) {
+ status = 1;
+ char *p = strstr((char *)content, "status=");
+ if(p != NULL) {
+ status = int(p[7]) - 48;
+ } else {
+ status = 4;
+ return -1;
+ }
+ } else {
+ status = 0;
+ char *p = &content[9];
+ char *rcStr = strstr((char *)p, "keySetData=");
+ if (rcStr != NULL) {
+ rcStr = &rcStr[11];
+ if (!strcmp(rcStr, "%00")) {
+ return -1;
+ }
+ keydataset = Util::URLDecode(rcStr);
+ }
+ }
+ }
+ }
+
+ if (keydataset == NULL)
+ {
+ RA::Debug(LL_PER_PDU, "RA_Processor:CreateKeySetData",
+ "Key Set Data is NULL");
+
+ return -1;
+ }
+
+ RA::Debug(LL_PER_PDU, "RA_Processor:CreateKeySetData", "Status of CreateKeySetData=%d", status);
+ RA::Debug(LL_PER_PDU, "finish CreateKeySetData", "");
+
+ if (status > 0) {
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+ return -1;
+ } else {
+ out = *keydataset;
+ if( keydataset != NULL ) {
+ delete keydataset;
+ keydataset = NULL;
+ }
+ }
+
+ if( response != NULL ) {
+ response->freeContent();
+ delete response;
+ response = NULL;
+ }
+
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+ return 1;
+ }
+ BYTE kek_key[] = {
+ 0x40, 0x41, 0x42, 0x43,
+ 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b,
+ 0x4c, 0x4d, 0x4e, 0x4f
+ };
+ BYTE key[] = {
+ 0x40, 0x41, 0x42, 0x43,
+ 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b,
+ 0x4c, 0x4d, 0x4e, 0x4f
+ };
+ Buffer old_kek_key(kek_key, 16);
+ Buffer new_auth_key(key, 16);
+ Buffer new_mac_key(key, 16);
+ Buffer new_kek_key(key, 16);
+
+
+ Util::CreateKeySetData(
+ NewMasterVer,
+ old_kek_key,
+ new_auth_key,
+ new_mac_key,
+ new_kek_key,
+ out);
+
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+ return 1;
+}
+
+
+/**
+ * Input data wrapped by KEK key in TKS.
+ */
+int RA_Processor::EncryptData(Buffer &CUID, Buffer &version, Buffer &in, Buffer &out, const char *connid)
+{
+ char body[5000];
+ char configname[256];
+#define PLAINTEXT_CHALLENGE_SIZE 16
+ // khai, here we wrap the input with the KEK key
+ // in TKS
+ HttpConnection *tksConn = NULL;
+ char kek_key[16] = {
+ 0x40, 0x41, 0x42, 0x43,
+ 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b,
+ 0x4c, 0x4d, 0x4e, 0x4f
+ };
+ int status = 0;
+
+ tksConn = RA::GetTKSConn(connid);
+ if (tksConn == NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::EncryptData", "Failed to get TKSConnection %s", connid);
+ RA::Debug(LL_PER_PDU, "RA_Processor::EncryptData", "Failed to get TKSConnection %s", connid);
+ return -1;
+ } else {
+ int tks_curr = RA::GetCurrentIndex(tksConn);
+ int currRetries = 0;
+ char *data = NULL;
+ Buffer *zerob = new Buffer(PLAINTEXT_CHALLENGE_SIZE, (BYTE)0);
+ if (!(in == *zerob))
+ data = Util::SpecialURLEncode(in);
+ else
+ RA::Debug(LL_PER_PDU, "RA_Processor::EncryptData","Challenge to be generated on TKS");
+
+ if (zerob != NULL) {
+ delete zerob;
+ }
+
+ char *cuid = Util::SpecialURLEncode(CUID);
+ char *versionID = Util::SpecialURLEncode(version);
+
+ PR_snprintf((char *)configname, 256, "conn.%s.keySet", connid);
+ const char *keySet = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ PR_snprintf((char *)body, 5000, "data=%s&CUID=%s&KeyInfo=%s&keySet=%s",
+ ((data != NULL)? data:""), cuid, versionID,keySet);
+ PR_snprintf((char *)configname, 256, "conn.%s.servlet.encryptData", connid);
+ const char *servletID = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ if( cuid != NULL ) {
+ PR_Free( cuid );
+ cuid = NULL;
+ }
+ if( versionID != NULL ) {
+ PR_Free( versionID );
+ versionID = NULL;
+ }
+
+ PSHttpResponse *response = tksConn->getResponse(tks_curr, servletID, body);
+ ConnectionInfo *connInfo = tksConn->GetFailoverList();
+ char **hostport = connInfo->GetHostPortList();
+ if (response == NULL)
+ RA::Debug(LL_PER_PDU, "The encryptedData response from TKS ",
+ "at %s is NULL.", hostport[tks_curr]);
+ else
+ RA::Debug(LL_PER_PDU, "The encryptedData response from TKS ",
+ "at %s is not NULL.", hostport[tks_curr]);
+
+ while (response == NULL) {
+ RA::Failover(tksConn, connInfo->GetHostPortListLen());
+ tks_curr = RA::GetCurrentIndex(tksConn);
+ RA::Debug(LL_PER_PDU, "RA is reconnecting to TKS ",
+ "at %s for encryptData.", hostport[tks_curr]);
+
+ if (++currRetries >= tksConn->GetNumOfRetries()) {
+ RA::Debug(LL_PER_PDU, "Used up all the retries. Response is NULL","");
+ RA::Error(LL_PER_PDU, "RA_Processor::EncryptData", "Failed connecting to TKS after %d retries", currRetries);
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+ return -1;
+ }
+ response = tksConn->getResponse(tks_curr, servletID, body);
+ }
+
+ Buffer *encryptedData = NULL;
+ // preEncData is only useful when data is null, and data is to be randomly
+ // generated on TKS
+ Buffer *preEncData = NULL;
+ status = 0;
+ if (response != NULL) {
+ RA::Debug(LL_PER_PDU, "EncryptData Response is not ","NULL");
+ char *content = response->getContent();
+ if (content != NULL) {
+ char *statusStr = strstr((char *)content, "status=0&");
+ if (statusStr == NULL) {
+ char *p = strstr((char *)content, "status=");
+
+ if(p != NULL) {
+ status = int(p[7]) - 48;
+ } else {
+ status = 4;
+ return -1;
+ }
+ } else {
+ status = 0;
+ char *p = &content[9];
+ // get pre-encryption data
+ char *preStr = strstr((char *)p, "data=");
+ if (preStr != NULL) {
+ p = &preStr[5];
+ char pstr[PLAINTEXT_CHALLENGE_SIZE*3+1];
+ strncpy(pstr, p, PLAINTEXT_CHALLENGE_SIZE*3);
+ pstr[PLAINTEXT_CHALLENGE_SIZE*3] = '\0';
+ preEncData = Util::URLDecode(pstr);
+//RA::DebugBuffer("RA_Processor::EncryptData", "preEncData=", preEncData);
+ }
+
+ // get encrypted data
+ p = &content[9];
+ char *rcStr = strstr((char *)p, "encryptedData=");
+ if (rcStr != NULL) {
+ rcStr = &rcStr[14];
+ encryptedData = Util::URLDecode(rcStr);
+//RA::DebugBuffer("RA_Processor::EncryptData", "encryptedData=", encryptedData);
+ }
+ }
+ }
+ }
+ if (encryptedData == NULL)
+ RA::Debug(LL_PER_PDU, "RA_Processor:GetEncryptedData",
+ "Encrypted Data is NULL");
+
+ RA::Debug(LL_PER_PDU, "EncryptedData ", "status=%d", status);
+ RA::Debug(LL_PER_PDU, "finish EncryptedData", "");
+ if ((status > 0) || (preEncData == NULL) || (encryptedData == NULL)) {
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+ if( data != NULL ) {
+ PR_Free( data );
+ data = NULL;
+ }
+ return -1;
+ } else {
+ out = *encryptedData;
+ if( encryptedData != NULL ) {
+ delete encryptedData;
+ encryptedData = NULL;
+ }
+ if (data != NULL) {
+ RA::Debug(LL_PER_PDU, "EncryptedData ", "challenge overwritten by TKS");
+ PR_Free( data );
+ data = NULL;
+ }
+ in = *preEncData;
+
+ if( preEncData != NULL ) {
+ delete preEncData;
+ preEncData = NULL;
+ }
+ }
+ if( response != NULL ) {
+ response->freeContent();
+ delete response;
+ response = NULL;
+ }
+
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+ return 1;
+ }
+
+ Buffer kek_buffer = Buffer((BYTE*)kek_key, 16);
+ status = Util::EncryptData(kek_buffer, in, out);
+#if 0
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::EncryptData", "Encrypted Data",
+ &out);
+ Buffer out1 = Buffer(16, (BYTE)0);
+ status = Util::DecryptData(kek_buffer, out, out1);
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::EncryptData", "Clear Data",
+ &out1);
+#endif
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+ return status;
+}
+
+int RA_Processor::ComputeRandomData(Buffer &data_out, int dataSize, const char *connid)
+{
+ char body[5000];
+ char configname[256];
+ HttpConnection *tksConn = NULL;
+ int status = -1;
+ Buffer *decodedRandomData = NULL;
+ PSHttpResponse *response = NULL;
+
+ //check for absurd dataSize values
+ if(dataSize <= 0 || dataSize > 1024) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::ComputeRandomData", "Invalid dataSize requested %d", dataSize);
+ return -1;
+ }
+
+ tksConn = RA::GetTKSConn(connid);
+ if (tksConn == NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::ComputeRandomData", "Failed to get TKSConnection %s", connid);
+ return -1;
+ } else {
+ int tks_curr = RA::GetCurrentIndex(tksConn);
+ int currRetries = 0;
+
+ PR_snprintf((char *)body, 5000, "dataNumBytes=%d"
+ , dataSize );
+
+ PR_snprintf((char *)configname, 256, "conn.%s.servlet.computeRandomData", connid);
+ const char *servletID = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ response = tksConn->getResponse(tks_curr, servletID, body);
+ ConnectionInfo *connInfo = tksConn->GetFailoverList();
+ char **hostport = connInfo->GetHostPortList();
+ if (response == NULL)
+ RA::Debug(LL_PER_PDU, "The ComputeRandomData response from TKS ",
+ "at %s is NULL.", hostport[tks_curr]);
+ else
+ RA::Debug(LL_PER_PDU, "The ComputeRandomData response from TKS ",
+ "at %s is not NULL.", hostport[tks_curr]);
+
+ while (response == NULL) {
+ RA::Failover(tksConn, connInfo->GetHostPortListLen());
+ tks_curr = RA::GetCurrentIndex(tksConn);
+ RA::Debug(LL_PER_PDU, "RA_Processor::ComputeRandomData: RA is reconnecting to TKS ",
+ "at %s for ComputeRandomData.", hostport[tks_curr]);
+
+ if (++currRetries >= tksConn->GetNumOfRetries()) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::ComputeRandomData: Used up all the retries. Response is NULL","");
+ RA::Error(LL_PER_PDU, "RA_Processor::ComputeRandomData", "Failed connecting to TKS after %d retries", currRetries);
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+ status = -1;
+ goto loser;
+ }
+ response = tksConn->getResponse(tks_curr, servletID, body);
+ }
+
+ status = 0;
+ if (response != NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::ComputeRandomData Response is not ","NULL");
+ char *content = response->getContent();
+ if (content != NULL) {
+ char *statusStr = strstr((char *)content, "status=0&");
+ if (statusStr == NULL) {
+ char *p = strstr((char *)content, "status=");
+
+ if(p != NULL) {
+ status = int(p[7]) - 48;
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::ComputeRandomData status from TKS is ","status %d",status);
+ status = -1;
+ } else {
+ status = -1;
+ goto loser;
+ }
+ } else {
+ status = 0;
+ // skip over "status=0&"
+ char *p = &content[9];
+
+ // get random data
+ char *dataStr = strstr((char *)p, "DATA=");
+ if (dataStr != NULL) {
+ // skip over "DATA="
+ p = &dataStr[5];
+
+ char *dstr = new char[ dataSize *3 + 1];
+ if(!dstr) {
+ status = -1;
+ goto loser;
+ }
+ strncpy(dstr, p, dataSize * 3);
+ dstr[dataSize*3] = '\0';
+ decodedRandomData = Util::URLDecode(dstr);
+ RA::DebugBuffer("RA_Processor::ComputeRandomData", "decodedRandomData=", decodedRandomData);
+
+ if(dstr) {
+ data_out = *decodedRandomData;
+ delete [] dstr;
+ dstr = NULL;
+ }
+ if(decodedRandomData) {
+ delete decodedRandomData;
+ decodedRandomData = NULL;
+ }
+ }
+ }
+ }
+ }
+ }
+loser:
+ if( response != NULL ) {
+ response->freeContent();
+ delete response;
+ response = NULL;
+ }
+
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+
+ return status;
+}
+
+bool RA_Processor::RevokeCertificates(RA_Session *session, char *cuid,char *audit_msg,
+ char *final_applet_version,
+ char *keyVersion,
+ char *tokenType,
+ char *userid,
+ RA_Status &status )
+{
+ const char *OP_PREFIX = "op.format";
+ char *statusString = NULL;
+ char configname[256];
+ char filter[512];
+ char activity_msg[512];
+ char serial[100];
+ int rc = 0;
+ int statusNum;
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ bool revocation_failed = false;
+
+ RA::Debug("RA_Processor::RevokeCertificates","RevokeCertificates! cuid %s",cuid);
+ PR_snprintf((char *)filter, 256, "(tokenID=%s)", cuid);
+ rc = RA::ra_find_tus_certificate_entries_by_order(filter, 100, &result, 1);
+ if (rc == 0) {
+ CertEnroll *certEnroll = new CertEnroll();
+ for (e = RA::ra_get_first_entry(result); e != NULL; e = RA::ra_get_next_entry(e)) {
+ char *attr_status = RA::ra_get_cert_status(e);
+ if (strcmp(attr_status, "revoked") == 0) {
+ if (attr_status != NULL) {
+ PL_strfree(attr_status);
+ attr_status = NULL;
+ }
+ rc = RA::ra_delete_certificate_entry(e);
+ continue;
+ }
+ char *attr_serial= RA::ra_get_cert_serial(e);
+ /////////////////////////////////////////////////
+ // Raidzilla Bug #57803:
+ // If the certificate is not originally created for this
+ // token, we should not revoke the certificate here.
+ //
+ // To figure out if this certificate is originally created
+ // for this token, we check the tokenOrigin attribute.
+ /////////////////////////////////////////////////
+ char *origin = RA::ra_get_cert_attr_byname(e, "tokenOrigin");
+ if (origin != NULL) {
+ RA::Debug("RA_Processor::RevokeCertificates", "Origin is %s, Current is %s", origin, cuid);
+ if (strcmp(origin, cuid) != 0) {
+ // skip this certificate, no need to do nothing
+ // We did not create this originally
+
+ rc = RA::ra_delete_certificate_entry(e);
+ continue;
+ }
+ } else {
+ RA::Debug("RA_Processor::RevokeCertificates", "Origin is not present");
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.revokeCert", OP_PREFIX, tokenType);
+ bool revokeCert = RA::GetConfigStore()->GetConfigAsBool(configname, true);
+ if (revokeCert) {
+ char *attr_cn = RA::ra_get_cert_cn(e);
+ PR_snprintf((char *)configname, 256, "%s.%s.ca.conn", OP_PREFIX,
+ tokenType);
+ char *connid = (char *)(RA::GetConfigStore()->GetConfigAsString(configname));
+ if (connid == NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::RevokeCertificates", "Failed to get connection.");
+ status = STATUS_ERROR_REVOKE_CERTIFICATES_FAILED;
+ PR_snprintf(audit_msg, 512, "Failed to connect to CA, status = STATUS_ERROR_REVOKE_CERTIFICATES_FAILED");
+
+ revocation_failed = true;
+ goto loser;
+ }
+ PR_snprintf(serial, 100, "0x%s", attr_serial);
+
+ // if the certificates are revoked_on_hold, dont do
+ // anything because the certificates may be referenced
+ // by more than one token.
+ if (strcmp(attr_status, "revoked_on_hold") == 0) {
+ RA::Debug("RA_Processor::RevokeCertificates", "This is revoked_on_hold certificate, skip it.");
+ if (attr_status != NULL) {
+ PL_strfree(attr_status);
+ attr_status = NULL;
+ }
+ if (attr_serial != NULL) {
+ PL_strfree(attr_serial);
+ attr_serial = NULL;
+ }
+ if (attr_cn != NULL) {
+ PL_strfree(attr_cn);
+ attr_cn = NULL;
+ }
+
+ rc = RA::ra_delete_certificate_entry(e);
+ continue;
+ }
+ statusNum = certEnroll->RevokeCertificate("1", serial, connid, statusString);
+ RA::Debug("RA_Processor::RevokeCertificates", "Revoke cert %s status %d",serial,statusNum);
+
+ if (statusNum == 0) {
+ RA::Audit(EV_FORMAT, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Success", "revoke", serial, connid, "");
+ PR_snprintf(activity_msg, 512, "certificate %s revoked", serial);
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "format", "success", activity_msg, "", tokenType);
+ RA::ra_update_cert_status(attr_cn, "revoked");
+ } else {
+ RA::Audit(EV_FORMAT, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Failure", "revoke", serial, connid, statusString);
+ PR_snprintf(activity_msg, 512, "error in revoking certificate %s: %s", serial, statusString);
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "format", "failure", activity_msg, "", tokenType);
+ revocation_failed = true;
+ }
+
+ if (attr_status != NULL) {
+ PL_strfree(attr_status);
+ attr_status = NULL;
+ }
+ if (attr_serial != NULL) {
+ PL_strfree(attr_serial);
+ attr_serial = NULL;
+ }
+ if (attr_cn != NULL) {
+ PL_strfree(attr_cn);
+ attr_cn = NULL;
+ }
+ if (statusString != NULL) {
+ PR_Free(statusString);
+ statusString = NULL;
+ }
+ }
+ rc = RA::ra_delete_certificate_entry(e);
+ }
+ if (result != NULL)
+ ldap_msgfree(result);
+ if (certEnroll != NULL)
+ delete certEnroll;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Processor::RevokeCertificates", "Failed to revoke certificates on this token. Certs not found.");
+ status = STATUS_ERROR_REVOKE_CERTIFICATES_FAILED;
+ PR_snprintf(audit_msg, 512, "Failed to revoke certificates on this token. Certs not found. status = STATUS_ERROR_REVOKE_CERTIFICATES_FAILED");
+ revocation_failed = true;
+ goto loser;
+ }
+
+ rc = 0;
+ if (keyVersion != NULL) {
+ rc = RA::tdb_update("", cuid, (char *)final_applet_version, keyVersion, "uninitialized", "", tokenType);
+ }
+
+ if (rc != 0) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::RevokeCertificates",
+ "Failed to update the token database");
+ status = STATUS_ERROR_UPDATE_TOKENDB_FAILED;
+ PR_snprintf(audit_msg, 512, "Revoked certificates but failed to update the token database, status = STATUS_ERROR_UPDATE_TOKENDB_FAILED");
+ goto loser;
+ }
+
+loser:
+
+ return !revocation_failed;
+}
+
+RA_Status RA_Processor::Format(RA_Session *session, NameValueSet *extensions, bool skipAuth)
+{
+ const char *OP_PREFIX="op.format";
+ char configname[256];
+ char *cuid = NULL;
+ char *msn = NULL;
+ const char *tokenType = NULL;
+ PRIntervalTime start, end;
+ RA_Status status = STATUS_NO_ERROR;
+ int rc = -1;
+ Secure_Channel *channel = NULL;
+ Buffer kdd;
+ AuthParams *login = NULL;
+ // char *new_pin = NULL;
+ const char *applet_dir;
+ bool upgrade_enc = false;
+ SecurityLevel security_level = SECURE_MSG_MAC_ENC;
+
+ Buffer *buildID = NULL;
+ Buffer *token_status = NULL;
+ const char* required_version = NULL;
+ const char *appletVersion = NULL;
+ const char *final_applet_version = NULL;
+ const char *userid = PL_strdup( "" );
+ // BYTE se_p1 = 0x00;
+ // BYTE se_p2 = 0x00;
+ const char *expected_version;
+ int requiredV = 0;
+ const char *tksid = NULL;
+ const char *authid = NULL;
+ AuthParams *authParams = NULL;
+ Buffer host_challenge = Buffer(8, (BYTE)0);
+ Buffer key_diversification_data;
+ Buffer key_info_data;
+ Buffer card_challenge;
+ Buffer card_cryptogram;
+ Buffer *cplc_data = NULL;
+ char activity_msg[4096];
+ LDAPMessage *ldapResult = NULL;
+ LDAPMessage *e = NULL;
+ LDAPMessage *result = NULL;
+ char filter[512];
+ Buffer curKeyInfo;
+ BYTE curVersion;
+ char *curKeyInfoStr = NULL;
+ char *newVersionStr = NULL;
+ bool tokenFound = false;
+ int finalKeyVersion = 0;
+ char *keyVersion = NULL;
+ char *xuserid = NULL;
+ char audit_msg[512] = "";
+ char *profile_state = NULL;
+
+ Buffer *CardManagerAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_CARDMGR_INSTANCE_AID,
+ RA::CFG_DEF_CARDMGR_INSTANCE_AID);
+ Buffer *NetKeyAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_NETKEY_INSTANCE_AID,
+ RA::CFG_DEF_NETKEY_INSTANCE_AID);
+ Buffer key_data_set;
+ Buffer token_cuid;
+ Buffer token_msn;
+ RA::Debug(LL_PER_PDU, "RA_Processor::Format",
+ "Begin upgrade process");
+
+ BYTE major_version = 0x0;
+ BYTE minor_version = 0x0;
+ BYTE app_major_version = 0x0;
+ BYTE app_minor_version = 0x0;
+ const char *connid = NULL;
+ int upgrade_rc;
+
+ start = PR_IntervalNow();
+
+ RA::Debug("RA__Processor::Format", "Client %s", session->GetRemoteIP());
+
+
+ SelectApplet(session, 0x04, 0x00, CardManagerAID);
+ cplc_data = GetData(session);
+ if (cplc_data == NULL) {
+ RA::Error("RA_Format_Processor::Process",
+ "Get Data Failed");
+ status = STATUS_ERROR_SECURE_CHANNEL;
+ PR_snprintf(audit_msg, 512, "Get Data Failed, status = STATUS_ERROR_SECURE_CHANNEL");
+ goto loser;
+ }
+ RA::DebugBuffer("RA_Processor::Format", "CPLC Data = ",
+ cplc_data);
+ if (cplc_data->size() < 47) {
+ RA::Error("RA_Format_Processor::Process",
+ "Invalid CPLC Size");
+ status = STATUS_ERROR_SECURE_CHANNEL;
+ PR_snprintf(audit_msg, 512, "Invalid CPLC Size, status = STATUS_ERROR_SECURE_CHANNEL");
+ goto loser;
+ }
+ token_cuid = Buffer(cplc_data->substr(3,4)) +
+ Buffer(cplc_data->substr(19,2)) +
+ Buffer(cplc_data->substr(15,4));
+ RA::DebugBuffer("RA_Processor::Format", "Token CUID= ",
+ &token_cuid);
+ cuid = Util::Buffer2String(token_cuid);
+
+ token_msn = Buffer(cplc_data->substr(41, 4));
+ RA::DebugBuffer("RA_Processor::Format", "Token MSN= ",
+ &token_msn);
+ msn = Util::Buffer2String(token_msn);
+
+
+ /**
+ * Checks if the netkey has the required applet version.
+ */
+ SelectApplet(session, 0x04, 0x00, NetKeyAID);
+ token_status = GetStatus(session, 0x00, 0x00);
+ if (token_status == NULL) {
+ major_version = 0;
+ minor_version = 0;
+ app_major_version = 0x0;
+ app_minor_version = 0x0;
+ } else {
+ major_version = ((BYTE*)*token_status)[0];
+ minor_version = ((BYTE*)*token_status)[1];
+ app_major_version = ((BYTE*)*token_status)[2];
+ app_minor_version = ((BYTE*)*token_status)[3];
+ }
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::Format",
+ "Major=%d Minor=%d", major_version, minor_version);
+ RA::Debug(LL_PER_PDU, "RA_Processor::Format",
+ "Applet Major=%d Applet Minor=%d", app_major_version, app_minor_version);
+
+ if (!GetTokenType(OP_PREFIX, major_version,
+ minor_version, cuid, msn,
+ extensions, status, tokenType)) {
+ PR_snprintf(audit_msg, 512, "Failed to get token type");
+ goto loser;
+ }
+
+ // check if profile is enabled
+ PR_snprintf((char *)configname, 256, "config.Profiles.%s.state", tokenType);
+ profile_state = (char *) RA::GetConfigStore()->GetConfigAsString(configname);
+ if ((profile_state != NULL) && (PL_strcmp(profile_state, "Enabled") != 0)) {
+ RA::Error("RA_Format_Processor::Process", "Profile %s Disabled for CUID %s", tokenType, cuid);
+ status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "profile %s disabled", tokenType);
+ goto loser;
+ }
+
+ if (RA::ra_is_token_present(cuid)) {
+ RA::Debug("RA_Processor::Format",
+ "Found token %s", cuid);
+
+ if (RA::ra_is_tus_db_entry_disabled(cuid)) {
+ RA::Error("RA_Format_Processor::Process",
+ "CUID %s Disabled", cuid);
+ status = STATUS_ERROR_DISABLED_TOKEN;
+ PR_snprintf(audit_msg, 512, "CUID %s Disabled, status=STATUS_ERROR_DISABLED_TOKEN", cuid);
+ goto loser;
+ }
+ } else {
+ RA::Debug("RA_Processor::Format",
+ "Not Found token %s", cuid);
+ // This is a new token. We need to check our policy to see
+ // if we should allow enrollment. raidzilla #57414
+ PR_snprintf((char *)configname, 256, "%s.allowUnknownToken",
+ OP_PREFIX);
+ if (!RA::GetConfigStore()->GetConfigAsBool(configname, 1)) {
+ RA::Error("Process", "CUID %s Format Unknown Token", cuid);
+ status = STATUS_ERROR_DISABLED_TOKEN;
+ PR_snprintf(audit_msg, 512, "Unknown token disallowed, status=STATUS_ERROR_DISABLED_TOKEN");
+ goto loser;
+ }
+
+ }
+
+ // we know cuid and msn here
+ RA::Audit(EV_FORMAT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "format",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "token enabled");
+
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn",
+ OP_PREFIX, tokenType);
+ tksid = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (tksid == NULL) {
+ RA::Error("RA_Format_Processor::Process",
+ "TKS Connection Parameter %s Not Found", configname);
+ status = STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "TKS Connection Parameter %s Not Found, status = STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND", configname);
+ goto loser;
+ }
+
+ buildID = GetAppletVersion(session);
+ if (buildID == NULL) {
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.emptyToken.enable", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 0)) {
+ appletVersion = PL_strdup( "" );
+ } else {
+ RA::Error("RA_Format_Processor::Process",
+ "no applet found and applet upgrade not enabled");
+ status = STATUS_ERROR_SECURE_CHANNEL;
+ PR_snprintf(audit_msg, 512, "No applet found and applet upgrade not enabled, status = STATUS_ERROR_SECURE_CHANNEL");
+ goto loser;
+ }
+ } else {
+ char * buildid = Util::Buffer2String(*buildID);
+ RA::Debug("RA_Processor::Format", "buildid = %s", buildid);
+ char version[13];
+ PR_snprintf((char *) version, 13,
+ "%x.%x.%s", app_major_version, app_minor_version,
+ buildid);
+ appletVersion = strdup(version);
+ if (buildid != NULL) {
+ PR_Free(buildid);
+ buildid=NULL;
+ }
+ }
+
+ final_applet_version = strdup(appletVersion);
+ RA::Debug("RA_Processor::Format", "final_applet_version = %s", final_applet_version);
+
+ /**
+ * Checks if we need to upgrade applet.
+ */
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.requiredVersion", OP_PREFIX, tokenType);
+
+ required_version = RA::GetConfigStore()->GetConfigAsString(
+ configname);
+ expected_version = PL_strdup(required_version);
+
+ if (expected_version == NULL) {
+ RA::Error("RA_Format_Processor::Process",
+ "upgrade.version not found");
+ status = STATUS_ERROR_MISCONFIGURATION;
+ PR_snprintf(audit_msg, 512, "Upgrade version not found, status = STATUS_ERROR_MISCONFIGURATION");
+ goto loser;
+ }
+ /* upgrade applet */
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.directory", OP_PREFIX, tokenType);
+ applet_dir = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (applet_dir == NULL || strlen(applet_dir) == 0) {
+ RA::Error(LL_PER_PDU, "RA_Processor::UpdateApplet",
+ "Failed to get %s", applet_dir);
+ status = STATUS_ERROR_MISCONFIGURATION;
+ PR_snprintf(audit_msg, 512, "Failed to get %s, status = STATUS_ERROR_MISCONFIGURATION", applet_dir);
+ goto loser;
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.loginRequest.enable", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 1) && !skipAuth) {
+ if (extensions != NULL &&
+ extensions->GetValue("extendedLoginRequest") != NULL)
+ {
+ RA::Debug("RA_rocessor::Format",
+ "Extended Login Request detected");
+ AuthenticationEntry *entry = GetAuthenticationEntry(
+ OP_PREFIX, configname, tokenType);
+ char **params = NULL;
+ char pb[1024];
+ char *locale = NULL;
+ if (extensions != NULL &&
+ extensions->GetValue("locale") != NULL)
+ {
+ locale = extensions->GetValue("locale");
+ } else {
+ locale = ( char * ) "en"; /* default to english */
+ }
+ int n = entry->GetAuthentication()->GetNumOfParamNames();
+ if (n > 0) {
+ RA::Debug("RA_Processor::Format",
+ "Extended Login Request detected n=%d", n);
+ params = (char **) PR_Malloc(n);
+ for (int i = 0; i < n; i++) {
+ sprintf(pb,"id=%s&name=%s&desc=%s&type=%s&option=%s",
+ entry->GetAuthentication()->GetParamID(i),
+ entry->GetAuthentication()->GetParamName(i, locale),
+ entry->GetAuthentication()->GetParamDescription(i,
+locale),
+ entry->GetAuthentication()->GetParamType(i),
+ entry->GetAuthentication()->GetParamOption(i)
+ );
+ params[i] = PL_strdup(pb);
+ RA::Debug("RA_Processor::Format",
+ "params[i]=%s", params[i]);
+ }
+ }
+ RA::Debug("RA_rocessor::Format", "Extended Login Request detected calling RequestExtendedLogin() locale=%s", locale);
+
+ char *title = PL_strdup(entry->GetAuthentication()->GetTitle(locale));
+ RA::Debug("RA_Processor::Format", "title=%s", title);
+ char *description = PL_strdup(entry->GetAuthentication()->GetDescription(locale));
+ RA::Debug("RA_Processor::Format", "description=%s", description);
+ login = RequestExtendedLogin(session, 0 /* invalid_pw */, 0 /* blocked */, params, n, title, description);
+
+ if (params != NULL) {
+ for (int nn=0; nn < n; nn++) {
+ if (params[nn] != NULL) {
+ PL_strfree(params[nn]);
+ params[nn] = NULL;
+ }
+ }
+ free(params);
+ params = NULL;
+ }
+
+ if (title != NULL) {
+ PL_strfree(title);
+ title = NULL;
+ }
+
+ if (description != NULL) {
+ PL_strfree(description);
+ description = NULL;
+ }
+
+
+ RA::Debug("RA_Processor::Format",
+ "Extended Login Request detected calling RequestExtendedLogin() login=%x", login);
+ } else {
+ login = RequestLogin(session, 0 /* invalid_pw */, 0 /* blocked */);
+ }
+ if (login == NULL) {
+ RA::Error("RA_Format_Processor::Process",
+ "login not provided");
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "login not provided, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+ if( userid != NULL ) {
+ PR_Free( (char *) userid );
+ userid = NULL;
+ }
+ if (login->GetUID() == NULL) {
+ userid = NULL;
+ } else {
+ userid = PL_strdup( login->GetUID() );
+ }
+ }
+
+ // send status update to the client
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 2 /* progress */,
+ "PROGRESS_START_AUTHENTICATION");
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.auth.enable", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, false) && !skipAuth) {
+ if (login == NULL) {
+ RA::Error("RA_Format_Processor::Process", "Login Request Disabled. Authentication failed.");
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "login request disabled, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.auth.id", OP_PREFIX, tokenType);
+ authid = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (authid == NULL) {
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "login not found, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+ AuthenticationEntry *auth = RA::GetAuth(authid);
+
+ if(auth == NULL)
+ {
+ RA::Error("RA_Format_Processor::Process", "Authentication manager is NULL . Authentication failed.");
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "authentication manager is NULL, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+
+ char *type = auth->GetType();
+ if (type == NULL) {
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "authentication is missing param type, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+ if (strcmp(type, "LDAP_Authentication") == 0) {
+ RA::Debug(LL_PER_PDU, "RA_Format_Processor::Process",
+ "LDAP_Authentication is invoked.");
+ int passwd_retries = auth->GetAuthentication()->GetNumOfRetries();
+ int retries = 0;
+ authParams = new AuthParams();
+ authParams->SetUID(login->GetUID());
+ authParams->SetPassword(login->GetPassword());
+ rc = auth->GetAuthentication()->Authenticate(authParams);
+
+ RA::Debug("RA_Format_Processor::Process",
+ "Authenticate returns: %d", rc);
+
+ while ((rc == -2 || rc == -3) && (retries < passwd_retries)) {
+ login = RequestLogin(session, 0 /* invalid_pw */, 0 /* blocked */);
+ retries++;
+ if (login == NULL || login->GetUID() == NULL) {
+ RA::Error("RA_Format_Processor::Process", "Authentication failed.");
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "authentication failed, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+ authParams->SetUID(login->GetUID());
+ authParams->SetPassword(login->GetPassword());
+ rc = auth->GetAuthentication()->Authenticate(authParams);
+ }
+
+ if (rc == -1) {
+ RA::Error("RA_Format_Processor::Process", "Authentication failed.");
+ status = STATUS_ERROR_LDAP_CONN;
+ RA::Debug(LL_PER_PDU, "RA_Processor::Format", "Authentication status = %d", status);
+ PR_snprintf(audit_msg, 512, "Authentication failed, status = STATUS_ERROR_LDAP_CONN");
+ goto loser;
+ }
+
+ if (rc == -2 || rc == -3) {
+ RA::Error("RA_Format_Processor::Process", "Authentication failed.");
+ status = STATUS_ERROR_LOGIN;
+ RA::Debug(LL_PER_PDU, "RA_Processor::Format", "Authentication status = %d", status);
+ PR_snprintf(audit_msg, 512, "Authentication failed, rc=-2 or -3, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::Format", "Authentication successful.");
+ } else {
+ RA::Error("RA_Format_Processor::Process", "No Authentication type was found.");
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "No Authentication type found, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Format",
+ "Authentication has been disabled.");
+ }
+
+ // check if it is the token owner
+ xuserid = RA::ra_get_token_userid(cuid);
+ if (xuserid != NULL && strcmp(xuserid, "") != 0) {
+ if (login != NULL) {
+ if (strcmp(login->GetUID(), xuserid) != 0) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Format",
+ "Token owner mismatched");
+ status = STATUS_ERROR_NOT_TOKEN_OWNER;
+ PR_snprintf(audit_msg, 512, "Token owner mismatched, status = STATUS_ERROR_NOT_TOKEN_OWNER");
+ goto loser;
+ }
+ }
+ }
+
+ // we know cuid, msn and userid here
+ RA::Audit(EV_FORMAT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "format",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "logged into token");
+
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 10 /* progress */,
+ "PROGRESS_APPLET_UPGRADE");
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.encryption", OP_PREFIX, tokenType);
+ upgrade_enc = RA::GetConfigStore()->GetConfigAsBool(configname, true);
+ if (!upgrade_enc)
+ security_level = SECURE_MSG_MAC;
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType);
+ connid = RA::GetConfigStore()->GetConfigAsString(configname);
+ upgrade_rc = UpgradeApplet(session,(char *) OP_PREFIX, (char*)tokenType, major_version,
+ minor_version, expected_version, applet_dir, security_level, connid,
+ extensions, 10, 90, &keyVersion);
+ if (upgrade_rc != 1) {
+ RA::Debug("RA_Processor::Format",
+ "applet upgrade failed");
+ status = STATUS_ERROR_UPGRADE_APPLET;
+ /**
+ * Bugscape #55709: Re-select Net Key Applet ONLY on failure.
+ */
+ SelectApplet(session, 0x04, 0x00, NetKeyAID);
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "format", "failure", "applet upgrade error", "", tokenType);
+ // rc = -1 denotes Secure Channel Failure
+
+ if (rc == -1) {
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ userid, cuid, msn, "Failure", "format",
+ keyVersion != NULL? keyVersion : "", appletVersion, expected_version, "failed to setup secure channel");
+ } else {
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ userid, cuid, msn, "Success", "format",
+ keyVersion != NULL? keyVersion : "", appletVersion, expected_version, "setup secure channel");
+ }
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ userid, cuid, msn, "Failure", "format",
+ keyVersion != NULL? keyVersion : "", appletVersion, expected_version, "applet upgrade");
+
+ goto loser;
+ }
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ userid, cuid, msn, "Success", "format",
+ keyVersion != NULL? keyVersion : "", appletVersion, expected_version, "setup secure channel");
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ userid, cuid, msn, "Success", "format",
+ keyVersion != NULL? keyVersion : "", appletVersion, expected_version, "applet upgrade");
+
+ if( final_applet_version != NULL ) {
+ PR_Free( (char *) final_applet_version );
+ final_applet_version = NULL;
+ }
+
+ final_applet_version = expected_version;
+
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 90 /* progress */,
+ "PROGRESS_KEY_UPGRADE");
+ }
+
+ // add issuer info to the token
+ PR_snprintf((char *)configname, 256, "%s.%s.issuerinfo.enable",
+ OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 0)) {
+ PR_snprintf((char *)configname, 256,"channel.defKeyIndex");
+ int defKeyIndex = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ channel = SetupSecureChannel(session, 0x00,
+ defKeyIndex /* default key index */, connid);
+ rc = channel->ExternalAuthenticate();
+ if (channel != NULL) {
+ char issuer[224];
+ for (int i = 0; i < 224; i++) {
+ issuer[i] = 0;
+ }
+ PR_snprintf((char *)configname, 256, "%s.%s.issuerinfo.value",
+ OP_PREFIX, tokenType);
+ char *issuer_val = (char*)RA::GetConfigStore()->GetConfigAsString(
+ configname);
+ sprintf(issuer, "%s", issuer_val);
+ RA::Debug("RA_Processor::Format", "Set Issuer Info %s", issuer_val);
+ Buffer *info = new Buffer((BYTE*)issuer, 224);
+ rc = channel->SetIssuerInfo(info);
+
+ if (info != NULL) {
+ delete info;
+ info = NULL;
+ }
+ }
+ }
+
+ /**
+ * Checks if the netkey has the required key version.
+ */
+ PR_snprintf((char *)configname, 256, "%s.%s.update.symmetricKeys.enable", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 1)) {
+
+ PR_snprintf((char *)configname, 256, "%s.%s.update.symmetricKeys.requiredVersion", OP_PREFIX, tokenType);
+ requiredV = RA::GetConfigStore()->GetConfigAsInt(configname, 0x00);
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType);
+ tksid = RA::GetConfigStore()->GetConfigAsString(configname);
+ PR_snprintf((char *)configname, 256,"channel.defKeyIndex");
+ int defKeyIndex = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ channel = SetupSecureChannel(session, requiredV,
+ defKeyIndex /* default key index */, tksid);
+ if (channel == NULL) {
+ /**
+ * Select Card Manager for Put Key operation.
+ */
+ SelectApplet(session, 0x04, 0x00, CardManagerAID);
+ // send status update to the client
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 92 /* progress */,
+ "PROGRESS_SETUP_SECURE_CHANNEL");
+ }
+ /* if the key of the required version is
+ * not found, create them.
+ */
+ PR_snprintf((char *)configname, 256,"channel.defKeyVersion");
+ int defKeyVer = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ PR_snprintf((char *)configname, 256,"channel.defKeyIndex");
+ int defKeyIndex = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ channel = SetupSecureChannel(session,
+ defKeyVer, /* default key version */
+ defKeyIndex /* default key index */, tksid);
+
+ if (channel == NULL) {
+ RA::Error("RA_Upgrade_Processor::Process",
+ "failed to establish secure channel");
+ status = STATUS_ERROR_SECURE_CHANNEL;
+ PR_snprintf(audit_msg, 512, "Failed to establish secure channel");
+ goto loser;
+ }
+
+ // send status update to the client
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 94 /* progress */,
+ "PROGRESS_EXTERNAL_AUTHENTICATE");
+ }
+
+ rc = channel->ExternalAuthenticate();
+
+ PR_snprintf((char *)configname, 256, "%s.%s.update.symmetricKeys.requiredVersion", OP_PREFIX, tokenType);
+ int v = RA::GetConfigStore()->GetConfigAsInt(configname, 0x00);
+ curKeyInfo = channel->GetKeyInfoData();
+ BYTE nv[2] = { v, 0x01 };
+ Buffer newVersion(nv, 2);
+ PR_snprintf((char *)configname, 256,"%s.%s.tks.conn", OP_PREFIX, tokenType);
+ connid = RA::GetConfigStore()->GetConfigAsString(configname);
+ rc = CreateKeySetData(
+ channel->GetKeyDiversificationData(),
+ curKeyInfo,
+ newVersion,
+ key_data_set, connid);
+ if (rc != 1) {
+ RA::Error("RA_Format_Processor::Process",
+ "failed to create new key set");
+ status = STATUS_ERROR_CREATE_CARDMGR;
+ PR_snprintf(audit_msg, 512, "create key set error, status = STATUS_ERROR_CREATE_CARDMGR");
+ goto loser;
+ }
+
+ curVersion = ((BYTE*)curKeyInfo)[0];
+
+
+ // send status update to the client
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 96 /* progress */,
+ "PROGRESS_PUT_KEYS");
+ }
+
+ BYTE curIndex = ((BYTE*)curKeyInfo)[1];
+ rc = channel->PutKeys(session,
+ curVersion,
+ curIndex,
+ &key_data_set);
+
+
+ // need to check return value of rc
+ // and create audit log for failure
+
+ curKeyInfoStr = Util::Buffer2String(curKeyInfo);
+ newVersionStr = Util::Buffer2String(newVersion);
+
+ char curVer[10];
+ char newVer[10];
+
+ if(curKeyInfoStr != NULL && strlen(curKeyInfoStr) >= 2) {
+ curVer[0] = curKeyInfoStr[0]; curVer[1] = curKeyInfoStr[1]; curVer[2] = 0;
+ }
+ else {
+ curVer[0] = 0;
+ }
+
+ if(newVersionStr != NULL && strlen(newVersionStr) >= 2) {
+ newVer[0] = newVersionStr[0] ; newVer[1] = newVersionStr[1] ; newVer[2] = 0;
+ }
+ else {
+ newVer[0] = 0;
+ }
+
+ if (rc != 0) {
+ RA::Audit(EV_KEY_CHANGEOVER, AUDIT_MSG_KEY_CHANGEOVER,
+ userid != NULL ? userid : "", cuid != NULL ? cuid : "", msn != NULL ? msn : "", "Failure", "format",
+ final_applet_version != NULL ? final_applet_version : "", curVer, newVer,
+ "key changeover failed");
+ // do we goto loser here?
+ }
+
+ finalKeyVersion = ((int) ((BYTE *)newVersion)[0]);
+ /**
+ * Re-select Net Key Applet.
+ */
+ SelectApplet(session, 0x04, 0x00, NetKeyAID);
+ PR_snprintf((char *)configname, 256, "%s.%s.update.symmetricKeys.requiredVersion", OP_PREFIX, tokenType);
+ requiredV = RA::GetConfigStore()->GetConfigAsInt(configname, 0x00);
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType);
+ tksid = RA::GetConfigStore()->GetConfigAsString(configname);
+ if( channel != NULL ) {
+ delete channel;
+ channel = NULL;
+ }
+ // send status update to the client
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 98 /* progress */,
+ "PROGRESS_SETUP_SECURE_CHANNEL");
+ }
+
+
+ channel = SetupSecureChannel(session, requiredV,
+ defKeyIndex /* default key index */, tksid);
+ if (channel == NULL) {
+ RA::Error("RA_Format_Processor::Process",
+ "failed to establish secure channel after reselect");
+ status = STATUS_ERROR_CREATE_CARDMGR;
+ PR_snprintf(audit_msg, 512,"failed to establish secure channel after reselect, status = STATUS_ERROR_CREATE_CARDMGR");
+ goto loser;
+ }
+
+ RA::Audit(EV_KEY_CHANGEOVER, AUDIT_MSG_KEY_CHANGEOVER,
+ userid != NULL ? userid : "", cuid != NULL ? cuid : "", msn != NULL ? msn : "", "Success", "format",
+ final_applet_version != NULL ? final_applet_version : "", curVer, newVer,
+ "key changeover");
+
+ }
+ }
+
+ PR_snprintf((char *)filter, 256, "(cn=%s)", cuid);
+ rc = RA::ra_find_tus_token_entries(filter, 100, &result, 0);
+ if (rc == 0) {
+ for (e = RA::ra_get_first_entry(result); e != NULL; e = RA::ra_get_next_entry(e)) {
+ tokenFound = true;
+ break;
+ }
+ if (result != NULL)
+ ldap_msgfree(result);
+ }
+
+ // get keyVersion
+ if (channel != NULL) {
+ if (keyVersion != NULL) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+ keyVersion = Util::Buffer2String(channel->GetKeyInfoData());
+ }
+
+ // need to revoke all the certificates on this token
+ if (tokenFound) {
+
+ //Now we call a separate function, the audit_msg will get filled in there if needed.
+
+ bool success = RevokeCertificates(session, cuid,audit_msg,(char *)final_applet_version,
+ keyVersion,(char *)tokenType,(char *)userid,status
+ );
+
+ if(!success) {
+ goto loser;
+ }
+
+ } else {
+ rc = RA::tdb_update("", cuid, (char *)final_applet_version, keyVersion, "uninitialized", "", tokenType);
+ if (rc != 0) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Format",
+ "Failed to update the token database");
+ status = STATUS_ERROR_UPDATE_TOKENDB_FAILED;
+ PR_snprintf(audit_msg, 512, "Failed to update the token database, status = STATUS_ERROR_UPDATE_TOKENDB_FAILED");
+ goto loser;
+ }
+ }
+
+ // send status update to the client
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 100 /* progress */,
+ "PROGRESS_DONE");
+ }
+
+ status = STATUS_NO_ERROR;
+ rc = 1;
+
+ end = PR_IntervalNow();
+
+ sprintf(activity_msg, "applet_version=%s tokenType=%s",
+ final_applet_version, tokenType);
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "format", "success", activity_msg, userid, tokenType);
+
+ /* audit log for successful format */
+ if (authid != NULL) {
+ sprintf(activity_msg, "format processing complete, authid = %s", authid);
+ } else {
+ sprintf(activity_msg, "format processing complete");
+ }
+ RA::Audit(EV_FORMAT, AUDIT_MSG_PROC,
+ userid, cuid, msn, "success", "format", final_applet_version,
+ keyVersion != NULL? keyVersion : "", activity_msg);
+
+loser:
+ if (strlen(audit_msg) > 0) { // a failure occurred
+ RA::Audit(EV_FORMAT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "failure",
+ "format",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ audit_msg);
+
+ if ((cuid != NULL) && (tokenType != NULL)) {
+ RA::tdb_activity(session->GetRemoteIP(),
+ cuid,
+ "format",
+ "failure",
+ audit_msg,
+ userid != NULL? userid : "",
+ tokenType);
+ }
+ }
+
+ if (curKeyInfoStr != NULL) {
+ PR_Free( (char *) curKeyInfoStr);
+ curKeyInfoStr = NULL;
+ }
+
+ if (newVersionStr != NULL) {
+ PR_Free( (char *) newVersionStr);
+ newVersionStr = NULL;
+ }
+
+ if (keyVersion != NULL) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+
+ if (ldapResult != NULL) {
+ ldap_msgfree(ldapResult);
+ }
+
+ if( cplc_data != NULL ) {
+ delete cplc_data;
+ cplc_data = NULL;
+ }
+ if( CardManagerAID != NULL ) {
+ delete CardManagerAID;
+ CardManagerAID = NULL;
+ }
+ if( NetKeyAID != NULL ) {
+ delete NetKeyAID;
+ NetKeyAID = NULL;
+ }
+ if( channel != NULL ) {
+ delete channel;
+ channel = NULL;
+ }
+ if( token_status != NULL ) {
+ delete token_status;
+ token_status = NULL;
+ }
+ if( buildID != NULL ) {
+ delete buildID;
+ buildID = NULL;
+ }
+ if( appletVersion != NULL ) {
+ PR_Free( (char *) appletVersion );
+ appletVersion = NULL;
+ }
+ if( final_applet_version != NULL ) {
+ PR_Free( (char *) final_applet_version );
+ final_applet_version = NULL;
+ }
+ if( userid != NULL ) {
+ PR_Free( (char *) userid );
+ userid = NULL;
+ }
+ if( cuid != NULL ) {
+ PR_Free( cuid );
+ cuid = NULL;
+ }
+ if( msn != NULL ) {
+ PR_Free( msn );
+ msn = NULL;
+ }
+ if( authParams != NULL ) {
+ delete authParams;
+ authParams = NULL;
+ }
+ if( login != NULL ) {
+ delete login;
+ login = NULL;
+ }
+
+#ifdef MEM_PROFILING
+ MEM_dump_unfree();
+#endif
+
+ RA::Debug("RA_Processor::Format"," returning status %d", status);
+ return status;
+}
+
+/**
+ * Process the current session. It does nothing in the base
+ * class.
+ */
+RA_Status RA_Processor::Process(RA_Session *session, NameValueSet *extensions)
+{
+ return STATUS_NO_ERROR;
+} /* Process */
+
diff --git a/base/tps/src/processor/RA_Renew_Processor.cpp b/base/tps/src/processor/RA_Renew_Processor.cpp
new file mode 100644
index 000000000..5caa329b4
--- /dev/null
+++ b/base/tps/src/processor/RA_Renew_Processor.cpp
@@ -0,0 +1,57 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "engine/RA.h"
+#include "main/RA_Msg.h"
+#include "main/RA_Session.h"
+#include "processor/RA_Processor.h"
+#include "processor/RA_Renew_Processor.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a renew processor.
+ */
+TPS_PUBLIC RA_Renew_Processor::RA_Renew_Processor()
+{
+}
+
+/**
+ * Destructs a renew processor.
+ */
+TPS_PUBLIC RA_Renew_Processor::~RA_Renew_Processor()
+{
+}
+
+/**
+ * Processes the current session.
+ */
+TPS_PUBLIC RA_Status RA_Renew_Processor::Process(RA_Session *session, NameValueSet *extensions)
+{
+ RA::Debug("RA_Renew_Processor::Process",
+ "RA_Renew_Processor::Process");
+
+ return STATUS_NO_ERROR;
+}
diff --git a/base/tps/src/processor/RA_Unblock_Processor.cpp b/base/tps/src/processor/RA_Unblock_Processor.cpp
new file mode 100644
index 000000000..0bdbcfa2b
--- /dev/null
+++ b/base/tps/src/processor/RA_Unblock_Processor.cpp
@@ -0,0 +1,58 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "engine/RA.h"
+#include "main/RA_Msg.h"
+#include "main/RA_Session.h"
+#include "processor/RA_Processor.h"
+#include "processor/RA_Unblock_Processor.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs the unblock processor.
+ */
+TPS_PUBLIC RA_Unblock_Processor::RA_Unblock_Processor()
+{
+} /* RA_Unblock_Processor */
+
+/**
+ * Destructs the unblock processor.
+ */
+TPS_PUBLIC RA_Unblock_Processor::~RA_Unblock_Processor()
+{
+} /* RA_Unblock_Processor */
+
+/**
+ * Processes the current session.
+ */
+TPS_PUBLIC RA_Status RA_Unblock_Processor::Process(RA_Session *session, NameValueSet *extensions)
+{
+ RA::Debug("RA_Unblock_Processor::Process", "Client %s", session->GetRemoteIP());
+
+ RA::Debug("RA_Unblock_Processor::Process",
+ "RA_Unblock_Processor::Process");
+ return STATUS_NO_ERROR;
+} /* Process */
diff --git a/base/tps/src/selftests/SelfTest.cpp b/base/tps/src/selftests/SelfTest.cpp
new file mode 100644
index 000000000..71266d581
--- /dev/null
+++ b/base/tps/src/selftests/SelfTest.cpp
@@ -0,0 +1,220 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+
+#include "cert.h"
+#include "certt.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "engine/RA.h"
+#include "main/ConfigStore.h"
+#include "selftests/SelfTest.h"
+#include "selftests/TPSPresence.h"
+#include "selftests/TPSValidity.h"
+#include "selftests/TPSSystemCertsVerification.h"
+
+
+const char *SelfTest::CFG_SELFTEST_STARTUP = "selftests.container.order.startup";
+const char *SelfTest::CFG_SELFTEST_ONDEMAND = "selftests.container.order.onDemand";
+const int SelfTest::nTests = 3;
+const char *SelfTest::TEST_NAMES[SelfTest::nTests] = { TPSPresence::TEST_NAME, TPSValidity::TEST_NAME, TPSSystemCertsVerification::TEST_NAME };
+
+int SelfTest::isInitialized = 0;
+int SelfTest::StartupSystemCertsVerificationRun = 0;
+
+SelfTest::SelfTest()
+{
+}
+
+SelfTest::~SelfTest()
+{
+}
+
+void SelfTest::Initialize (ConfigStore *cfg)
+{
+ if (SelfTest::isInitialized == 0) {
+ SelfTest::isInitialized = 1;
+ TPSPresence::Initialize (cfg);
+ TPSValidity::Initialize (cfg);
+ TPSSystemCertsVerification::Initialize (cfg);
+ SelfTest::isInitialized = 2;
+ }
+ RA::SelfTestLog("SelfTest::Initialize", "%s", ((isInitialized==2)?"successfully completed":"failed"));
+}
+
+// Error codes:
+// -1 - missing cert db handle
+// 2 - missing cert
+// -3 - missing cert nickname
+// 4 - secCertTimeExpired
+// 5 - secCertTimeNotValidYet
+// critical errors are negative
+
+int SelfTest::runStartUpSelfTests (const char *nickname)
+{
+ int rc = 0;
+ CERTCertificate *cert = 0;
+
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "per cert selftests starting for %s", nickname);
+ if (TPSPresence::isStartupEnabled()) {
+ rc = TPSPresence::runSelfTest(nickname, &cert);
+ }
+ if (rc != 0 && TPSPresence::isStartupCritical()) {
+ if (rc > 0) rc *= -1;
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "Critical TPSPresence self test failure: %d", rc);
+ return rc;
+ } else if (rc != 0) {
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "Noncritical TPSPresence self test failure: %d", rc);
+ } else {
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "TPSPresence self test has been successfully completed.");
+ }
+ if (TPSValidity::isStartupEnabled()) {
+ rc = TPSValidity::runSelfTest(nickname, cert);
+ }
+ if (cert != 0) {
+ CERT_DestroyCertificate (cert);
+ cert = 0;
+ }
+ if (rc != 0 && TPSValidity::isStartupCritical()) {
+ if (rc > 0) rc *= -1;
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "Critical TPSValidity self test failure: %d", rc);
+ return rc;
+ } else if (rc != 0) {
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "Noncritical TPSValidity self test failure: %d", rc);
+ } else {
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "TPSValidity self test has been successfully completed.");
+ }
+
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "per cert selftests done for %s", nickname);
+ return 0;
+}
+
+int SelfTest::runStartUpSelfTests ()
+{
+ int rc = 0;
+
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "general selftests starting");
+ /* this only needs to run once at startup */
+ if (SelfTest::StartupSystemCertsVerificationRun == 0) {
+ if (TPSSystemCertsVerification::isStartupEnabled()) {
+ rc = TPSSystemCertsVerification::runSelfTest();
+ }
+ if (rc != 0 && TPSSystemCertsVerification::isStartupCritical()) {
+ if (rc > 0) rc *= -1;
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "Critical TPSSystemCertsVerification self test failure: %d", rc);
+ return rc;
+ } else if (rc != 0) {
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "Noncritical TPSSystemCertsVerification self test failure: %d", rc);
+ } else {
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "TPSSystemCertsVerification self test has been successfully completed.");
+ }
+ SelfTest::StartupSystemCertsVerificationRun = 1;
+ }
+
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "general selftests done");
+ return 0;
+}
+
+int SelfTest::runOnDemandSelfTests ()
+{
+ int rc = 0;
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "starting");
+ if (TPSPresence::isOnDemandEnabled()) {
+ rc = TPSPresence::runSelfTest();
+ }
+ if (rc != 0 && TPSPresence::isOnDemandCritical()) {
+ if (rc > 0) rc *= -1;
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "Critical TPSPresence self test failure: %d", rc);
+ return rc;
+ } else if (rc != 0) {
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "Noncritical TPSPresence self test failure: %d", rc);
+ } else {
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "TPSPresence self test has been successfully completed.");
+ }
+ if (TPSValidity::isOnDemandEnabled()) {
+ rc = TPSValidity::runSelfTest();
+ }
+ if (rc != 0 && TPSValidity::isOnDemandCritical()) {
+ if (rc > 0) rc *= -1;
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "Critical TPSValidity self test failure: %d", rc);
+ return rc;
+ } else if (rc != 0) {
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "Noncritical TPSValidity self test failure: %d", rc);
+ } else {
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "TPSValidity self test has been successfully completed.");
+ }
+
+ if (TPSSystemCertsVerification::isOnDemandEnabled()) {
+ rc = TPSSystemCertsVerification::runSelfTest();
+ }
+ if (rc != 0 && TPSSystemCertsVerification::isOnDemandCritical()) {
+ if (rc > 0) rc *= -1;
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "Critical TPSSystemCertsVerification self test failure: %d", rc);
+ return rc;
+ } else if (rc != 0) {
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "Noncritical TPSSystemCertsVerification self test failure: %d", rc);
+ } else {
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "TPSSystemCertsVerification self test has been successfully completed.");
+ }
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "done");
+ return rc;
+}
+
+int SelfTest::isOnDemandEnabled ()
+{
+ int n = 0;
+ if (TPSPresence::isOnDemandEnabled()) n++;
+ if (TPSValidity::isOnDemandEnabled()) n += 2;
+ if (TPSSystemCertsVerification::isOnDemandEnabled()) n += 4;
+ return n;
+}
+
+int SelfTest::isOnDemandCritical ()
+{
+ int n = 0;
+ if (TPSPresence::isOnDemandCritical()) n++;
+ if (TPSValidity::isOnDemandCritical()) n += 2;
+ if (TPSSystemCertsVerification::isOnDemandCritical()) n += 4;
+ return n;
+}
+
diff --git a/base/tps/src/selftests/TPSPresence.cpp b/base/tps/src/selftests/TPSPresence.cpp
new file mode 100644
index 000000000..7f37fd0fb
--- /dev/null
+++ b/base/tps/src/selftests/TPSPresence.cpp
@@ -0,0 +1,204 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+
+#include "cert.h"
+#include "certt.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "engine/RA.h"
+#include "main/ConfigStore.h"
+#include "selftests/TPSPresence.h"
+
+
+int TPSPresence::initialized = 0;
+bool TPSPresence::startupEnabled = false;
+bool TPSPresence::onDemandEnabled = false;
+bool TPSPresence::startupCritical = false;
+bool TPSPresence::onDemandCritical = false;
+char *TPSPresence::nickname = 0;
+const char *TPSPresence::UNINITIALIZED_NICKNAME = "[HSM_LABEL][NICKNAME]";
+const char *TPSPresence::NICKNAME_NAME = "selftests.plugin.TPSPresence.nickname";
+const char *TPSPresence::CRITICAL_TEST_NAME = "TPSPresence:critical";
+const char *TPSPresence::TEST_NAME = "TPSPresence";
+
+//default constructor
+TPSPresence::TPSPresence()
+{
+}
+
+TPSPresence::~TPSPresence()
+{
+}
+
+void TPSPresence::Initialize (ConfigStore *cfg)
+{
+ if (TPSPresence::initialized == 0) {
+ TPSPresence::initialized = 1;
+ const char* s = cfg->GetConfigAsString(CFG_SELFTEST_STARTUP);
+ if (s != 0) {
+ if (PL_strstr (s, TPSPresence::CRITICAL_TEST_NAME) != 0) {
+ startupCritical = true;
+ startupEnabled = true;
+ } else if (PL_strstr (s, TPSPresence::TEST_NAME) != 0) {
+ startupEnabled = true;
+ }
+ }
+ const char* d = cfg->GetConfigAsString(CFG_SELFTEST_ONDEMAND);
+ if (d != 0) {
+ if (PL_strstr (d, TPSPresence::CRITICAL_TEST_NAME) != 0) {
+ onDemandCritical = true;
+ onDemandEnabled = true;
+ } else if (PL_strstr (d, TPSPresence::TEST_NAME) != 0) {
+ onDemandEnabled = true;
+ }
+ }
+ char* n = (char*)(cfg->GetConfigAsString(TPSPresence::NICKNAME_NAME));
+ if (n != 0 && PL_strlen(n) > 0) {
+ if (PL_strstr (n, TPSPresence::UNINITIALIZED_NICKNAME) != NULL) {
+ TPSPresence::initialized = 0;
+ } else {
+ TPSPresence::nickname = n;
+ }
+
+ TPSPresence::nickname = n;
+ }
+ if (TPSPresence::initialized == 1) {
+ TPSPresence::initialized = 2;
+ }
+ }
+ RA::SelfTestLog("TPSPresence::Initialize", "%s", ((initialized==2)?"successfully completed":"failed"));
+}
+
+// Error codes:
+// -1 - missing cert db handle
+// 2 - missing cert
+// -3 - missing cert nickname
+// 4 - secCertTimeExpired
+// 5 - secCertTimeNotValidYet
+// critical errors are negative
+
+int TPSPresence::runSelfTest ()
+{
+ int rc = 0;
+
+ if (TPSPresence::initialized == 2) {
+ if (TPSPresence::nickname != 0 && PL_strlen(TPSPresence::nickname) > 0) {
+ rc = TPSPresence::runSelfTest (TPSPresence::nickname);
+ } else {
+ rc = -3;
+ }
+ }
+
+ return rc;
+}
+
+int TPSPresence::runSelfTest (const char *nick_name)
+{
+ int rc = 0;
+ CERTCertDBHandle *handle = 0;
+ CERTCertificate *cert = 0;
+
+ if (TPSPresence::initialized == 2) {
+ if (nick_name != 0 && PL_strlen(nick_name) > 0) {
+ handle = CERT_GetDefaultCertDB();
+ if (handle != 0) {
+ cert = CERT_FindCertByNickname( handle, (char *) nick_name);
+ if (cert != 0) {
+ CERT_DestroyCertificate (cert);
+ cert = 0;
+ } else {
+ rc = 2;
+ }
+ } else {
+ rc = -1;
+ }
+ } else {
+ rc = TPSPresence::runSelfTest ();
+ }
+ }
+
+ return rc;
+}
+
+int TPSPresence::runSelfTest (const char *nick_name, CERTCertificate **cert)
+{
+ int rc = 0;
+ CERTCertDBHandle *handle = 0;
+
+ if (TPSPresence::initialized == 2) {
+ handle = CERT_GetDefaultCertDB();
+ if (handle != 0) {
+ *cert = CERT_FindCertByNickname( handle, (char *) nick_name);
+ if (*cert == NULL) {
+ rc = 2;
+ }
+ } else {
+ rc = 1;
+ }
+ }
+
+ return rc;
+}
+
+bool TPSPresence::isStartupEnabled ()
+{
+ return startupEnabled;
+}
+
+bool TPSPresence::isOnDemandEnabled ()
+{
+ return onDemandEnabled;
+}
+
+bool TPSPresence::isStartupCritical ()
+{
+ return startupCritical;
+}
+
+bool TPSPresence::isOnDemandCritical ()
+{
+ return onDemandCritical;
+}
+
+
diff --git a/base/tps/src/selftests/TPSSystemCertsVerification.cpp b/base/tps/src/selftests/TPSSystemCertsVerification.cpp
new file mode 100644
index 000000000..a89d18d04
--- /dev/null
+++ b/base/tps/src/selftests/TPSSystemCertsVerification.cpp
@@ -0,0 +1,149 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+
+#include "cert.h"
+#include "certt.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "engine/RA.h"
+#include "main/ConfigStore.h"
+#include "selftests/TPSSystemCertsVerification.h"
+
+
+int TPSSystemCertsVerification::initialized = 0;
+bool TPSSystemCertsVerification::startupEnabled = false;
+bool TPSSystemCertsVerification::onDemandEnabled = false;
+bool TPSSystemCertsVerification::startupCritical = false;
+bool TPSSystemCertsVerification::onDemandCritical = false;
+const char *TPSSystemCertsVerification::CRITICAL_TEST_NAME = "TPSSystemCertsVerification:critical";
+const char *TPSSystemCertsVerification::TEST_NAME = "TPSSystemCertsVerification";
+// for testing if system is initialized
+const char *TPSSystemCertsVerification::UNINITIALIZED_NICKNAME = "[HSM_LABEL][NICKNAME]";
+const char *TPSSystemCertsVerification::SUBSYSTEM_NICKNAME= "tps.cert.subsystem.nickname";
+
+
+//default constructor
+TPSSystemCertsVerification::TPSSystemCertsVerification()
+{
+}
+
+TPSSystemCertsVerification::~TPSSystemCertsVerification()
+{
+}
+
+void TPSSystemCertsVerification::Initialize (ConfigStore *cfg)
+{
+ if (TPSSystemCertsVerification::initialized == 0) {
+ TPSSystemCertsVerification::initialized = 1;
+ const char* s = cfg->GetConfigAsString(CFG_SELFTEST_STARTUP);
+ if (s != NULL) {
+ if (PL_strstr (s, TPSSystemCertsVerification::CRITICAL_TEST_NAME) != NULL) {
+ startupCritical = true;
+ startupEnabled = true;
+ } else if (PL_strstr (s, TPSSystemCertsVerification::TEST_NAME) != NULL) {
+ startupEnabled = true;
+ }
+ }
+ const char* d = cfg->GetConfigAsString(CFG_SELFTEST_ONDEMAND);
+ if (d != NULL) {
+ if (PL_strstr (d, TPSSystemCertsVerification::CRITICAL_TEST_NAME) != NULL) {
+ onDemandCritical = true;
+ onDemandEnabled = true;
+ } else if (PL_strstr (d, TPSSystemCertsVerification::TEST_NAME) != NULL) {
+ onDemandEnabled = true;
+ }
+ }
+ char* n = (char*)(cfg->GetConfigAsString(TPSSystemCertsVerification::SUBSYSTEM_NICKNAME));
+ if (n != NULL && PL_strlen(n) > 0) {
+ if (PL_strstr (n, TPSSystemCertsVerification::UNINITIALIZED_NICKNAME) != NULL) {
+ TPSSystemCertsVerification::initialized = 0;
+ }
+ }
+ if (TPSSystemCertsVerification::initialized == 1) {
+ TPSSystemCertsVerification::initialized = 2;
+ }
+ }
+ RA::SelfTestLog("TPSSystemCertsVerification::Initialize", "%s", ((initialized==2)?"successfully completed":"failed"));
+}
+
+// Error codes:
+// -1 - failed system certs verification
+// critical errors are negative
+
+int TPSSystemCertsVerification::runSelfTest ()
+{
+ int rc = 0;
+
+ if (TPSSystemCertsVerification::initialized == 2) {
+ rc = RA::verifySystemCerts();
+ if (rc == true) {
+ return 0;
+ } else {
+ rc = -1;
+ }
+ }
+
+ return rc;
+}
+
+bool TPSSystemCertsVerification::isStartupEnabled ()
+{
+ return startupEnabled;
+}
+
+bool TPSSystemCertsVerification::isOnDemandEnabled ()
+{
+ return onDemandEnabled;
+}
+
+bool TPSSystemCertsVerification::isStartupCritical ()
+{
+ return startupCritical;
+}
+
+bool TPSSystemCertsVerification::isOnDemandCritical ()
+{
+ return onDemandCritical;
+}
+
diff --git a/base/tps/src/selftests/TPSValidity.cpp b/base/tps/src/selftests/TPSValidity.cpp
new file mode 100644
index 000000000..e70263e80
--- /dev/null
+++ b/base/tps/src/selftests/TPSValidity.cpp
@@ -0,0 +1,215 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+
+#include "cert.h"
+#include "certt.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "engine/RA.h"
+#include "main/ConfigStore.h"
+#include "selftests/TPSValidity.h"
+
+
+int TPSValidity::initialized = 0;
+bool TPSValidity::startupEnabled = false;
+bool TPSValidity::onDemandEnabled = false;
+bool TPSValidity::startupCritical = false;
+bool TPSValidity::onDemandCritical = false;
+char *TPSValidity::nickname = 0;
+const char *TPSValidity::UNINITIALIZED_NICKNAME = "[HSM_LABEL][NICKNAME]";
+const char *TPSValidity::NICKNAME_NAME = "selftests.plugin.TPSValidity.nickname";
+const char *TPSValidity::CRITICAL_TEST_NAME = "TPSValidity:critical";
+const char *TPSValidity::TEST_NAME = "TPSValidity";
+
+
+//default constructor
+TPSValidity::TPSValidity()
+{
+}
+
+TPSValidity::~TPSValidity()
+{
+}
+
+void TPSValidity::Initialize (ConfigStore *cfg)
+{
+ if (TPSValidity::initialized == 0) {
+ TPSValidity::initialized = 1;
+ const char* s = cfg->GetConfigAsString(CFG_SELFTEST_STARTUP);
+ if (s != NULL) {
+ if (PL_strstr (s, TPSValidity::CRITICAL_TEST_NAME) != NULL) {
+ startupCritical = true;
+ startupEnabled = true;
+ } else if (PL_strstr (s, TPSValidity::TEST_NAME) != NULL) {
+ startupEnabled = true;
+ }
+ }
+ const char* d = cfg->GetConfigAsString(CFG_SELFTEST_ONDEMAND);
+ if (d != NULL) {
+ if (PL_strstr (d, TPSValidity::CRITICAL_TEST_NAME) != NULL) {
+ onDemandCritical = true;
+ onDemandEnabled = true;
+ } else if (PL_strstr (d, TPSValidity::TEST_NAME) != NULL) {
+ onDemandEnabled = true;
+ }
+ }
+ char* n = (char*)(cfg->GetConfigAsString(TPSValidity::NICKNAME_NAME));
+ if (n != NULL && PL_strlen(n) > 0) {
+ if (PL_strstr (n, TPSValidity::UNINITIALIZED_NICKNAME) != NULL) {
+ TPSValidity::initialized = 0;
+ } else {
+ TPSValidity::nickname = n;
+ }
+ }
+ if (TPSValidity::initialized == 1) {
+ TPSValidity::initialized = 2;
+ }
+ }
+ RA::SelfTestLog("TPSValidity::Initialize", "%s", ((initialized==2)?"successfully completed":"failed"));
+}
+
+// Error codes:
+// -1 - missing cert db handle
+// 2 - missing cert
+// -3 - missing cert nickname
+// 4 - secCertTimeExpired
+// 5 - secCertTimeNotValidYet
+// critical errors are negative
+
+int TPSValidity::runSelfTest ()
+{
+ int rc = 0;
+
+ if (TPSValidity::initialized == 2) {
+ if (TPSValidity::nickname != NULL && PL_strlen(TPSValidity::nickname) > 0) {
+ rc = TPSValidity::runSelfTest (TPSValidity::nickname);
+ } else {
+ rc = -3;
+ }
+ }
+
+ return rc;
+}
+
+int TPSValidity::runSelfTest (const char *nick_name)
+{
+ SECCertTimeValidity certTimeValidity;
+ PRTime now;
+ int rc = 0;
+ CERTCertDBHandle *handle = 0;
+ CERTCertificate *cert = 0;
+
+ if (TPSValidity::initialized == 2) {
+ handle = CERT_GetDefaultCertDB();
+ if (handle != 0) {
+ cert = CERT_FindCertByNickname( handle, (char *) nick_name);
+ if (cert != 0) {
+ now = PR_Now();
+ certTimeValidity = CERT_CheckCertValidTimes (cert, now, PR_FALSE);
+ if (certTimeValidity == secCertTimeExpired) {
+ rc = 4;
+ } else if (certTimeValidity == secCertTimeNotValidYet) {
+ rc = 5;
+ }
+ CERT_DestroyCertificate (cert);
+ cert = 0;
+ } else {
+ rc = 2;
+ }
+ } else {
+ rc = -1;
+ }
+ }
+
+ return rc;
+}
+
+int TPSValidity::runSelfTest (const char *nick_name, CERTCertificate *cert)
+{
+ SECCertTimeValidity certTimeValidity;
+ PRTime now;
+ int rc = 0;
+
+ if (TPSValidity::initialized == 2) {
+ if (cert != 0) {
+ now = PR_Now();
+ certTimeValidity = CERT_CheckCertValidTimes (cert, now, PR_FALSE);
+ if (certTimeValidity == secCertTimeExpired) {
+ rc = 4;
+ } else if (certTimeValidity == secCertTimeNotValidYet) {
+ rc = 5;
+ }
+ CERT_DestroyCertificate (cert);
+ cert = 0;
+ } else if (nick_name != 0 && PL_strlen(nick_name) > 0) {
+ rc = TPSValidity::runSelfTest (nick_name);
+ } else {
+ rc = TPSValidity::runSelfTest ();
+ }
+ }
+
+ return rc;
+
+}
+
+bool TPSValidity::isStartupEnabled ()
+{
+ return startupEnabled;
+}
+
+bool TPSValidity::isOnDemandEnabled ()
+{
+ return onDemandEnabled;
+}
+
+bool TPSValidity::isStartupCritical ()
+{
+ return startupCritical;
+}
+
+bool TPSValidity::isOnDemandCritical ()
+{
+ return onDemandCritical;
+}
+
diff --git a/base/tps/src/test/Test_ConfigStore.cfg b/base/tps/src/test/Test_ConfigStore.cfg
new file mode 100644
index 000000000..60f8e8675
--- /dev/null
+++ b/base/tps/src/test/Test_ConfigStore.cfg
@@ -0,0 +1,28 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+integer=100
+string=steve
+sub1.integer=500
+sub1.string=paul
+sub1.sub2.integer=1000
+sub1.sub2.string=jim
+
+
diff --git a/base/tps/src/test/Test_ConfigStore.cpp b/base/tps/src/test/Test_ConfigStore.cpp
new file mode 100644
index 000000000..d81a67b03
--- /dev/null
+++ b/base/tps/src/test/Test_ConfigStore.cpp
@@ -0,0 +1,79 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+
+#include "main/ConfigStore.h"
+
+
+// This is needed to resolve a symbol expected by the linker
+int __nsapi30_table;
+
+ConfigStore getsubstore(ConfigStore& config, char *subname)
+{
+ printf("Getting sub store : %s\n", subname);
+ ConfigStore sub2 = config.GetSubStore(subname);
+ const char *t = sub2.GetConfigAsString("string");
+ printf("substore string : %s\n", t);
+
+
+ printf("returning substore to parent\n");
+ return sub2;
+}
+
+int main()
+{
+ int i;
+ const char *s;
+
+ ConfigStore *cfg = ConfigStore::CreateFromConfigFile("Test_ConfigStore.cfg");
+
+ printf("TOP LEVEL\n");
+ i = cfg->GetConfigAsInt("integer");
+ printf("int : %d\n",i);
+ s = cfg->GetConfigAsString("string");
+ printf("string : %s\n",s);
+
+
+ printf("\nSUB1 LEVEL\n");
+ ConfigStore subcfg = cfg->GetSubStore("sub1");
+ i = subcfg.GetConfigAsInt("integer");
+ printf("int : %d\n",i);
+ s = subcfg.GetConfigAsString("string");
+ printf("string : %s\n",s);
+ s = subcfg["string"];
+ printf("[string] : %s\n",s);
+
+ printf("\nSUB2 LEVEL in method\n");
+ ConfigStore sub2cfg = getsubstore(subcfg,"sub2");
+ printf("accessing sub2 from main\n");
+ i = sub2cfg.GetConfigAsInt("integer");
+ printf("int : %d\n",i);
+
+
+ printf("\nTOP LEVEL AGAIN\n");
+ i = cfg->GetConfigAsInt("integer");
+ printf("int : %d\n",i);
+ s = cfg->GetConfigAsString("string");
+
+ ConfigStore subcfg2 = cfg->GetSubStore("level2");
+
+
+}
+
diff --git a/base/tps/src/tus/CMakeLists.txt b/base/tps/src/tus/CMakeLists.txt
new file mode 100644
index 000000000..3148d9e59
--- /dev/null
+++ b/base/tps/src/tus/CMakeLists.txt
@@ -0,0 +1,50 @@
+project(tokendb_library C)
+
+set(TOKENDB_PUBLIC_INCLUDE_DIRS
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${TPS_INCLUDE_DIR}
+ CACHE INTERNAL "tokendb public include directories"
+)
+
+set(TOKENDB_PRIVATE_INCLUDE_DIRS
+ ${TOKENDB_PUBLIC_INCLUDE_DIRS}
+ ${CMAKE_BINARY_DIR}
+ ${NSPR_INCLUDE_DIRS}
+ ${NSS_INCLUDE_DIRS}
+ ${SVRCORE_INCLUDE_DIRS}
+ ${LDAP_INCLUDE_DIRS}
+)
+
+set(TOKENDB_SHARED_LIBRARY
+ tokendb_library
+ CACHE INTERNAL "tokendb shared library"
+)
+
+set(TOKENDB_LINK_LIBRARIES
+ ${NSPR_LIBRARIES}
+ ${NSS_LIBRARIES}
+ ${SVRCORE_LIBRARIES}
+ ${LDAP_LIBRARIES}
+)
+
+set(tokendb_library_SRCS
+ tus_db.c
+)
+
+include_directories(${TOKENDB_PRIVATE_INCLUDE_DIRS})
+
+add_library(${TOKENDB_SHARED_LIBRARY} SHARED ${tokendb_library_SRCS})
+target_link_libraries(${TOKENDB_SHARED_LIBRARY} ${TOKENDB_LINK_LIBRARIES})
+
+set_target_properties(${TOKENDB_SHARED_LIBRARY}
+ PROPERTIES
+ OUTPUT_NAME
+ tokendb
+)
+
+install(
+ TARGETS
+ ${TOKENDB_SHARED_LIBRARY}
+ LIBRARY DESTINATION ${LIB_INSTALL_DIR}/tps
+)
diff --git a/base/tps/src/tus/tus_db.c b/base/tps/src/tus/tus_db.c
new file mode 100644
index 000000000..c865bc371
--- /dev/null
+++ b/base/tps/src/tus/tus_db.c
@@ -0,0 +1,4515 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "nspr.h"
+#include "pk11func.h"
+#include "cryptohi.h"
+#include "keyhi.h"
+#include "base64.h"
+#include "nssb64.h"
+#include "prlock.h"
+#include "secder.h"
+#include "cert.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "plstr.h"
+#include "prmem.h"
+#include "prprf.h"
+#include "prtime.h"
+
+#include "tus/tus_db.h"
+
+static char *tokenActivityAttributes[] = { TOKEN_ID,
+ TOKEN_CUID,
+ TOKEN_OP,
+ TOKEN_USER,
+ TOKEN_MSG,
+ TOKEN_RESULT,
+ TOKEN_IP,
+ TOKEN_C_DATE,
+ TOKEN_M_DATE,
+ TOKEN_TYPE,
+ NULL };
+static char *tokenAttributes[] = { TOKEN_ID,
+ TOKEN_USER,
+ TOKEN_STATUS,
+ TOKEN_APPLET,
+ TOKEN_KEY_INFO,
+ TOKEN_MODS,
+ TOKEN_C_DATE,
+ TOKEN_M_DATE,
+ TOKEN_RESETS,
+ TOKEN_ENROLLMENTS,
+ TOKEN_RENEWALS,
+ TOKEN_RECOVERIES,
+ TOKEN_POLICY,
+ TOKEN_REASON,
+ TOKEN_TYPE,
+ NULL };
+static char *tokenCertificateAttributes[] = { TOKEN_ID,
+ TOKEN_CUID,
+ TOKEN_USER,
+ TOKEN_STATUS,
+ TOKEN_C_DATE,
+ TOKEN_M_DATE,
+ TOKEN_SUBJECT,
+ TOKEN_ISSUER,
+ TOKEN_SERIAL,
+ TOKEN_CERT,
+ TOKEN_TYPE,
+ TOKEN_NOT_BEFORE,
+ TOKEN_NOT_AFTER,
+ TOKEN_KEY_TYPE,
+ TOKEN_STATUS,
+ NULL };
+
+static char *userAttributes[] = {USER_ID,
+ USER_SN,
+ USER_GIVENNAME,
+ USER_CN,
+ USER_CERT,
+ C_TIME,
+ M_TIME,
+ PROFILE_ID,
+ NULL};
+
+static char *viewUserAttributes[] = {USER_ID,
+ USER_SN,
+ USER_CN,
+ C_TIME,
+ M_TIME,
+ NULL};
+
+static char *tokenStates[] = { STATE_UNINITIALIZED,
+ STATE_ACTIVE,
+ STATE_DISABLED,
+ NULL };
+
+#ifdef __cplusplus
+}
+#endif
+
+static char *ssl = NULL; /* true or false */
+static char *host = NULL;
+static int port = 0;
+static char *userBaseDN = NULL;
+static char *baseDN = NULL;
+static char *activityBaseDN = NULL;
+static char *certBaseDN = NULL;
+static char *bindDN = NULL;
+static char *bindPass = NULL;
+static char *defaultPolicy = NULL;
+
+static int ccHost = 0;
+static int ccBaseDN = 0;
+static int ccBindDN = 0;
+static int ccBindPass = 0;
+
+static LDAP *ld = NULL;
+static int bindStatus = -1;
+
+static PRFileDesc *debug_fd = NULL;
+static PRFileDesc *audit_fd = NULL;
+
+extern void audit_log(const char *func_name, const char *userid, const char *msg);
+
+char *get_pwd_from_conf(char *filepath, char *name);
+static int tus_check_conn();
+
+TPS_PUBLIC int valid_berval(struct berval **b)
+{
+ if ((b != NULL) && (b[0] != NULL) && (b[0]->bv_val != NULL))
+ return 1;
+ return 0;
+}
+
+TPS_PUBLIC void set_tus_db_port(int number)
+{
+ port = number;
+}
+
+TPS_PUBLIC void set_tus_db_hostport(char *name)
+{
+ char *s = NULL;
+
+ s = PL_strstr(name, ":");
+ if (s == NULL) {
+ set_tus_db_port(389);
+ } else {
+ set_tus_db_port(atoi(s+1));
+ s[0] = '\0';
+ }
+ set_tus_db_host(name);
+}
+
+TPS_PUBLIC void set_tus_db_host(char *name)
+{
+ if( ccHost > 0 && host != NULL ) {
+ PL_strfree( host );
+ host = NULL;
+ }
+ if( name != NULL ) {
+ host = PL_strdup( name );
+ }
+ ccHost++;
+}
+
+TPS_PUBLIC void set_tus_db_baseDN(char *dn)
+{
+ if( ccBaseDN > 0 && baseDN != NULL ) {
+ PL_strfree( baseDN );
+ baseDN = NULL;
+ }
+ if( dn != NULL ) {
+ baseDN = PL_strdup( dn );
+ }
+ ccBaseDN++;
+}
+
+TPS_PUBLIC void set_tus_db_userBaseDN(char *dn)
+{
+ if( userBaseDN != NULL ) {
+ PL_strfree( userBaseDN );
+ userBaseDN = NULL;
+ }
+ if( dn != NULL ) {
+ userBaseDN = PL_strdup( dn );
+ }
+}
+
+TPS_PUBLIC void set_tus_db_activityBaseDN(char *dn)
+{
+ if( activityBaseDN != NULL ) {
+ PL_strfree( activityBaseDN );
+ activityBaseDN = NULL;
+ }
+ if( dn != NULL ) {
+ activityBaseDN = PL_strdup( dn );
+ }
+}
+
+TPS_PUBLIC void set_tus_db_certBaseDN(char *dn)
+{
+ if( certBaseDN != NULL ) {
+ PL_strfree( certBaseDN );
+ certBaseDN = NULL;
+ }
+ if( dn != NULL ) {
+ certBaseDN = PL_strdup( dn );
+ }
+}
+
+TPS_PUBLIC void set_tus_db_bindDN(char *dn)
+{
+ if( ccBindDN > 0 && bindDN != NULL ) {
+ PL_strfree( bindDN );
+ bindDN = NULL;
+ }
+ if( dn != NULL ) {
+ bindDN = PL_strdup( dn );
+ }
+ ccBindDN++;
+}
+
+TPS_PUBLIC void set_tus_db_bindPass(char *p)
+{
+ if( ccBindPass > 0 && bindPass != NULL ) {
+ PL_strfree( bindPass );
+ bindPass = NULL;
+ }
+ if( p != NULL ) {
+ bindPass = PL_strdup( p );
+ }
+ ccBindPass++;
+}
+
+TPS_PUBLIC int is_tus_db_initialized()
+{
+ return ((ld != NULL && bindStatus == LDAP_SUCCESS)? 1: 0);
+}
+
+TPS_PUBLIC int get_tus_db_config(char *cfg_name)
+{
+ PRFileInfo info;
+ PRFileDesc *fd = NULL;
+ PRUint32 size;
+ int k, n, p;
+ char *buf = NULL;
+ char *s = NULL;
+ char *v = NULL;
+
+ if (PR_GetFileInfo (cfg_name, &info) != PR_SUCCESS)
+ return 0;
+ size = info.size;
+ size++;
+ buf = (char *)PR_Malloc(size);
+ if (buf == NULL)
+ return 0;
+
+ fd = PR_Open(cfg_name, PR_RDONLY, 400);
+ if (fd == NULL) {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+
+ k = 0;
+ while ((n = PR_Read(fd, &buf[k], size-k-1)) > 0) {
+ k += n;
+ if ((PRUint32)(k+1) >= size) break;
+ }
+ if( fd != NULL ) {
+ PR_Close( fd );
+ fd = NULL;
+ }
+ if (n < 0 || ((PRUint32)(k+1) > size)) {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ buf[k] = '\0';
+
+ if ((s = PL_strstr(buf, "tokendb.hostport=")) != NULL) {
+
+ s += 17;
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ set_tus_db_hostport(s);
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if ((s = PL_strstr(buf, "tokendb.port=")) != NULL) {
+
+ s += 13;
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ p = atoi(s);
+ set_tus_db_port(p);
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if ((s = PL_strstr(buf, "tokendb.ssl=")) != NULL) {
+
+ s += 12;
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ if (strcmp(s, "") != 0) {
+ ssl = PL_strdup( s );
+ }
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if ((s = PL_strstr(buf, "tokendb.auditLog=")) != NULL) {
+
+ s += 17;
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ if (strcmp(s, "") != 0) {
+ audit_fd = PR_Open(s, PR_RDWR | PR_CREATE_FILE | PR_APPEND,
+ 400 | 200);
+ }
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+ if ((s = PL_strstr(buf, "tokendb.host=")) != NULL) {
+
+ s += 13;
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ set_tus_db_host(s);
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if ((s = PL_strstr(buf, "tokendb.defaultPolicy=")) != NULL) {
+
+ s += 22;
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ defaultPolicy = PL_strdup( s );
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if ((s = PL_strstr(buf, "tokendb.userBaseDN=")) != NULL) {
+ s += 19;
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ set_tus_db_userBaseDN(s);
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if ((s = PL_strstr(buf, "tokendb.baseDN=")) != NULL) {
+ s += 15;
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ set_tus_db_baseDN(s);
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+ if ((s = PL_strstr(buf, "tokendb.activityBaseDN=")) != NULL) {
+ s += strlen("tokendb.activityBaseDN=");
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ set_tus_db_activityBaseDN(s);
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+ if ((s = PL_strstr(buf, "tokendb.certBaseDN=")) != NULL) {
+ s += strlen("tokendb.certBaseDN=");
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ set_tus_db_certBaseDN(s);
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+ if ((s = PL_strstr(buf, "tokendb.bindDN=")) != NULL) {
+ s += 15;
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ set_tus_db_bindDN(s);
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+ if ((s = PL_strstr(buf, "tokendb.bindPassPath=")) != NULL) {
+ s += 21;
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ /* read tokendbBindPass from bindPassPath */
+ char *p = NULL;
+ p = get_pwd_from_conf(s, "tokendbBindPass");
+ set_tus_db_bindPass(p);
+ if (p) {
+ if (debug_fd)
+ PR_fprintf(debug_fd, "freeing p - %s\n", p);
+ PR_Free( p );
+ }
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+
+ tus_db_end();
+
+ return 1;
+}
+
+
+TPS_PUBLIC char *tus_authenticate(char *cert)
+{
+ char *dst;
+ int len;
+ int certlen;
+ int rc = -1;
+#define MAX_FILTER_LEN 4096
+ char filter[MAX_FILTER_LEN];
+ char searchBase[MAX_FILTER_LEN];
+ struct berval **v = NULL;
+ char *userid = NULL;
+ LDAPMessage *result = NULL;
+ LDAPMessage *entry = NULL;
+ int i,j;
+ char *certX = NULL;
+ int tries;
+
+ tus_check_conn();
+ if (cert == NULL)
+ return NULL;
+
+ certlen = strlen(cert);
+
+ certX = malloc(certlen);
+ j = 0;
+ for (i = 0; i < certlen; i++) {
+ if (cert[i] != '\n' && cert[i] != '\r') {
+ certX[j++] = cert[i];
+ }
+ }
+ certX[j++] = '\0';
+ dst = malloc(3 * strlen(certX) / 4);
+ len = base64_decode(certX, ( unsigned char * ) dst);
+ free(certX);
+
+ if (len <= 0) {
+ if (dst != NULL) free(dst);
+ return NULL;
+ }
+
+ PR_snprintf(filter, MAX_FILTER_LEN, "(userCertificate=");
+
+ for (i = 0; i < len; i++) {
+ char c = dst[i];
+ PR_snprintf(filter, MAX_FILTER_LEN, "%s\\%02x", filter, (c & 0xff) );
+ }
+ PR_snprintf(filter, MAX_FILTER_LEN, "%s)", filter);
+ PR_snprintf(searchBase, MAX_FILTER_LEN, "ou=People, %s", userBaseDN);
+
+ if (dst != NULL) free(dst);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s(ld, searchBase, LDAP_SCOPE_SUBTREE,
+ filter, NULL, 0, NULL, NULL, NULL, 0, &result)) == LDAP_SUCCESS )
+ {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ if (rc != LDAP_SUCCESS) {
+ if (result != NULL) {
+ free_results(result);
+ result = NULL;
+ }
+ return NULL;
+ }
+
+ if (result == NULL)
+ return NULL;
+
+ entry = get_first_entry (result);
+ if (entry == NULL) {
+ if (result != NULL) {
+ free_results(result);
+ result = NULL;
+ }
+ return NULL;
+ }
+
+ v = ldap_get_values_len(ld, entry, "uid");
+ if (v == NULL) {
+ if (result != NULL) {
+ free_results(result);
+ result = NULL;
+ }
+ return NULL;
+ }
+
+ if (valid_berval(v) && PL_strlen(v[0]->bv_val) > 0) {
+ userid = PL_strdup(v[0]->bv_val);
+ }
+ if( v != NULL ) {
+ ldap_value_free_len( v );
+ v = NULL;
+ }
+
+ if (result != NULL) {
+ free_results(result);
+ result = NULL;
+ }
+
+ return userid;
+}
+
+/*********
+ * tus_authorize
+ * parameters passed in:
+ * char * group ("TUS Agents", "TUS Operators", "TUS Administrators")
+ * const char* userid
+ * returns : 1 if userid is member of that group
+ * 0 otherwise
+ **/
+
+TPS_PUBLIC int tus_authorize(const char *group, const char *userid)
+{
+ int rc;
+ char filter[4096];
+ int tries;
+ LDAPMessage *result = NULL;
+
+ PR_snprintf(filter, 4096,
+ "(&(cn=%s)(member=uid=%s,*))", group ,userid);
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s(ld, userBaseDN, LDAP_SCOPE_SUBTREE,
+ filter, NULL, 0, NULL, NULL, NULL, 0, &result)) == LDAP_SUCCESS )
+ {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ if (rc != LDAP_SUCCESS) {
+ if (result != NULL) {
+ free_results(result);
+ result = NULL;
+ }
+ return 0;
+ }
+ if (ldap_count_entries (ld, result) <= 0) {
+ if (result != NULL) {
+ free_results(result);
+ result = NULL;
+ }
+ return 0;
+ }
+ if (result != NULL) {
+ free_results(result);
+ result = NULL;
+ }
+ return 1;
+}
+
+/******
+ * get_authorized_profiles()
+ * params: userid
+ * : is_admin (1 if user is in admin group, 0 otherwise
+ * returns: ldap filter with the tokenTypes the user has access to - to be appended
+ * to any other user search filer.
+ * examples: (|(tokenType=foo)(tokenType=bar)
+ * example: (!(tokenType=foo)(tokenType=no_token_type)) -- if user is an admin, always
+ * add no_token_type to catch admin events
+ * example: NO_PROFILES -- not an admin, and no profiles
+ * exmaple: (tokenType=no_token_type) : admin with no other tokens
+ *
+ * Caller must free the result (char*)
+ **/
+TPS_PUBLIC char *get_authorized_profiles(const char *userid, int is_admin)
+{
+ int status;
+ char filter[512];
+ char ret[4096] = "";
+ char *profile_filter = NULL;
+ struct berval **vals = NULL;
+ int nVals;
+ int i;
+
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+
+// Debug("TUS","get_authorized_profiles");
+ PR_snprintf(filter, 512, "(uid=%s)", userid);
+ status = find_tus_user_entries_no_vlv(filter, &result, 0);
+
+ if (status == LDAP_SUCCESS) {
+
+ e = get_first_entry(result);
+
+ vals = get_attribute_values(e,"profileID");
+ if (valid_berval(vals)) {
+ nVals = ldap_count_values_len(vals);
+ if (nVals == 1) {
+ if (PL_strstr(vals[0]->bv_val, ALL_PROFILES)) {
+ if (is_admin) {
+ // all profiles
+ PR_snprintf(ret, 4096, ALL_PROFILES);
+ } else {
+ // all profile except admin no token events
+ PR_snprintf(ret, 4096, "(!(tokenType=%s))", NO_TOKEN_TYPE);
+ }
+ } else {
+ if (is_admin) {
+ PL_strcat(ret, "(|(tokenType=");
+ PL_strcat(ret, NO_TOKEN_TYPE);
+ PL_strcat(ret, ")(tokenType=");
+ PL_strcat(ret, vals[0]->bv_val);
+ PL_strcat(ret, "))");
+ } else {
+ PL_strcat(ret, "(tokenType=");
+ PL_strcat(ret, vals[0]->bv_val);
+ PL_strcat(ret, ")");
+ }
+ }
+ } else if (nVals > 1) {
+ for( i = 0; vals[i] != NULL; i++ ) {
+ if (i==0) {
+ PL_strcat(ret, "(|");
+ if (is_admin) {
+ PL_strcat(ret, "(tokenType=");
+ PL_strcat(ret, NO_TOKEN_TYPE);
+ PL_strcat(ret, ")");
+ }
+ }
+ if (vals[i]->bv_val != NULL) {
+ PL_strcat(ret, "(tokenType=");
+ PL_strcat(ret, vals[i]->bv_val);
+ PL_strcat(ret, ")");
+ }
+ }
+ PL_strcat(ret, ")");
+ } else if (nVals == 0) {
+ if (is_admin) {
+ PR_snprintf(ret, 4096, "(tokenType=%s)", NO_TOKEN_TYPE);
+ } else {
+ PR_snprintf(ret, 4096, NO_PROFILES);
+ }
+ } else { //error
+ return NULL;
+ }
+ } else {
+ if (is_admin) {
+ PR_snprintf(ret, 4096, "(tokenType=%s)", NO_TOKEN_TYPE);
+ } else {
+ PR_snprintf(ret, 4096, NO_PROFILES);
+ }
+ }
+ } else {
+ // log error message here
+ PR_snprintf(ret, 4096, NO_PROFILES);
+ }
+
+ profile_filter = PL_strdup(ret);
+
+ if (vals != NULL) {
+ free_values(vals, 1);
+ vals = NULL;
+ }
+
+ if (result != NULL) {
+ free_results(result);
+ result = NULL;
+ }
+
+ e = NULL;
+
+ return profile_filter;
+}
+
+static int tus_check_conn()
+{
+ int version = LDAP_VERSION3;
+ int status = -1;
+ char ldapuri[1024];
+
+/* for production, make sure this variable is not defined.
+ * Leaving it defined results in weird Apache SSL timeout errors */
+/*#define DEBUG_TOKENDB*/
+
+#ifdef DEBUG_TOKENDB
+ debug_fd = PR_Open("/tmp/debugTUSdb.log",
+ PR_RDWR | PR_CREATE_FILE | PR_APPEND,
+ 400 | 200);
+#endif
+ if (ld == NULL) {
+ if (ssl != NULL && strcmp(ssl, "true") == 0) {
+ /* enabling SSL */
+ snprintf(ldapuri, 1024, "ldaps://%s:%i", host, port);
+ } else {
+ snprintf(ldapuri, 1024, "ldap://%s:%i", host, port);
+ }
+ status = ldap_initialize(&ld, ldapuri);
+ if (ld == NULL) {
+ return status;
+ }
+
+ // This option was supported by mozldap but is not supported by openldap.
+ // Code to provide this functionality needs to be written - FIXME
+ /*if ((status = ldap_set_option (ld, LDAP_OPT_RECONNECT, LDAP_OPT_ON)) != LDAP_SUCCESS) {
+ return status;
+ }*/
+
+ if ((status = ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version)) != LDAP_SUCCESS) {
+ return status;
+ }
+ }
+ if (ld != NULL && bindStatus != LDAP_SUCCESS) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ bindStatus = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (bindStatus != LDAP_SUCCESS) {
+ return bindStatus;
+ }
+ }
+
+ return LDAP_SUCCESS;
+}
+
+TPS_PUBLIC int tus_db_init(char **errorMsg)
+{
+ return LDAP_SUCCESS;
+}
+
+TPS_PUBLIC void tus_db_end()
+{
+ if (ld != NULL) {
+ if (ldap_unbind_ext_s(ld, NULL, NULL) == LDAP_SUCCESS) {
+ ld = NULL;
+ bindStatus = -1;
+ }
+ }
+}
+
+TPS_PUBLIC void tus_db_cleanup()
+{
+ if (ssl != NULL) {
+ PL_strfree(ssl);
+ ssl = NULL;
+ }
+ if (host != NULL) {
+ PL_strfree(host);
+ host = NULL;
+ }
+ if (userBaseDN != NULL) {
+ PL_strfree(userBaseDN);
+ userBaseDN = NULL;
+ }
+ if (baseDN != NULL) {
+ PL_strfree(baseDN);
+ baseDN = NULL;
+ }
+ if (activityBaseDN != NULL) {
+ PL_strfree(activityBaseDN);
+ activityBaseDN = NULL;
+ }
+ if(certBaseDN != NULL) {
+ PL_strfree(certBaseDN);
+ certBaseDN = NULL;
+ }
+ if(bindDN != NULL) {
+ PL_strfree(bindDN);
+ bindDN = NULL;
+ }
+ if(bindPass != NULL) {
+ PL_strfree(bindPass);
+ bindPass = NULL;
+ }
+ if(defaultPolicy != NULL) {
+ PL_strfree(defaultPolicy);
+ defaultPolicy = NULL;
+ }
+ if (debug_fd != NULL) {
+ PR_Close(debug_fd);
+ debug_fd = NULL;
+ }
+ if (audit_fd != NULL) {
+ PR_Close(audit_fd);
+ audit_fd = NULL;
+ }
+}
+
+/*****
+ * tus_print_integer
+ * summary: prints serial number as hex string
+ * modeled on SECU_PrintInteger. The length
+ * 4 below is arbitrary - but works!
+ * params: out - output hexidecimal string
+ * data - serial number as SECItem
+ */
+TPS_PUBLIC void tus_print_integer(char *out, SECItem *i)
+{
+ int iv;
+
+ if (!i || !i->len || !i->data) {
+ sprintf(out, "(null)");
+ } else if (i->len > 4) {
+ tus_print_as_hex(out, i);
+ } else {
+ if (i->type == siUnsignedInteger && *i->data & 0x80) {
+ /* Make sure i->data has zero in the highest byte
+ * if i->data is an unsigned integer */
+ SECItem tmpI;
+ char data[] = {0, 0, 0, 0, 0};
+
+ PORT_Memcpy(data + 1, i->data, i->len);
+ tmpI.len = i->len + 1;
+ tmpI.data = (void*)data;
+
+ iv = DER_GetInteger(&tmpI);
+ } else {
+ iv = DER_GetInteger(i);
+ }
+ sprintf(out, "%x", iv);
+ }
+}
+
+/***
+ * tus_print_as_hex
+ * summary: prints serial number as a hex string, needed
+ * because DER_GetInteger only works for small numbers
+ * modeled on SECU_PrintAsHex
+ * params: out - output hexidecimal string
+ * data - serial number as SECItem
+ */
+TPS_PUBLIC void tus_print_as_hex(char *out, SECItem *data)
+{
+ unsigned i;
+ int isString = 1;
+ char tmp[32];
+
+ PR_snprintf(out, 2, "");
+
+ /* take a pass to see if it's all printable. */
+ for (i = 0; i < data->len; i++) {
+ unsigned char val = data->data[i];
+ if (!val || !isprint(val)) {
+ isString = 0;
+ break;
+ }
+ }
+
+ if (!isString) {
+ for (i = 0; i < data->len; i++) {
+ PR_snprintf(tmp, 32, "%02x", data->data[i]);
+ PL_strcat(out, tmp);
+ }
+ } else {
+ for (i = 0; i < data->len; i++) {
+ unsigned char val = data->data[i];
+
+ PR_snprintf(tmp, 32, "%c", val);
+ PL_strcat(out, tmp);
+ }
+ }
+ PL_strcat(out, '\0');
+}
+
+char **parse_number_change(int n)
+{
+ char tmp[32];
+ int l;
+ char **v = NULL;
+
+ PR_snprintf(tmp, 32, "%d", n);
+ l = PL_strlen(tmp);
+
+ if ((v = allocate_values(1, l+1)) == NULL) {
+ return NULL;
+ }
+ PL_strcpy(v[0], tmp);
+
+ return v;
+}
+
+TPS_PUBLIC int update_cert_status (char *cn, const char *status)
+{
+ char dn[256];
+ int len;
+ int tries;
+ int rc = -1;
+ char **v = NULL;
+ LDAPMod **mods = NULL;
+
+ tus_check_conn();
+ if (PR_snprintf(dn, 255, "cn=%s,%s", cn, certBaseDN) < 0)
+ return -1;
+
+ mods = allocate_modifications(2);
+ if (mods == NULL)
+ return -1;
+
+ if ((v = create_modification_date_change()) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+
+ mods[0]->mod_op = LDAP_MOD_REPLACE;
+ mods[0]->mod_type = tokenAttributes[I_TOKEN_M_DATE];
+ mods[0]->mod_values = v;
+ if (status != NULL && PL_strlen(status) > 0) {
+ len = PL_strlen(status);
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ PL_strcpy(v[0], status);
+
+ mods[1]->mod_op = LDAP_MOD_REPLACE;
+ mods[1]->mod_type = "tokenStatus";
+ mods[1]->mod_values = v;
+ }
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_modify_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+
+ return rc;
+}
+
+TPS_PUBLIC int update_token_policy (char *cn, char *policy)
+{
+ char dn[256];
+ int len, k;
+ int tries;
+ int rc = -1;
+ char **v = NULL;
+ LDAPMod **mods = NULL;
+
+ tus_check_conn();
+ if (PR_snprintf(dn, 255, "cn=%s,%s", cn, baseDN) < 0)
+ return -1;
+
+ mods = allocate_modifications(2);
+ if (mods == NULL)
+ return -1;
+
+ if ((v = create_modification_date_change()) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+
+ mods[0]->mod_op = LDAP_MOD_REPLACE;
+ mods[0]->mod_type = tokenAttributes[I_TOKEN_M_DATE];
+ mods[0]->mod_values = v;
+ k = 1;
+ if (policy != NULL && PL_strlen(policy) > 0) {
+ len = PL_strlen(policy);
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ PL_strcpy(v[0], policy);
+
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = tokenAttributes[I_TOKEN_POLICY];
+ mods[k]->mod_values = v;
+ k++;
+ }
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_modify_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+
+ return rc;
+}
+
+TPS_PUBLIC int update_tus_db_entry_with_mods (const char *agentid, const char *cn, LDAPMod **mods)
+{
+ char dn[256];
+ int tries;
+ int rc = -1;
+
+ tus_check_conn();
+ if (PR_snprintf(dn, 255, "cn=%s,%s", cn, baseDN) < 0)
+ return -1;
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_modify_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+
+ return rc;
+}
+
+/****
+ * update_tus_general_db_entry
+ * summary: internal function to modify a general db entry using ldap_modify_ext_s
+ * params: agentid - who is doing this modification (for audit logging)
+ * dn - dn to modify
+ * mods - NULL terminated list of modifications to apply
+ **/
+int update_tus_general_db_entry(const char *agentid, const char *dn, LDAPMod **mods)
+{
+ int tries;
+ int rc = -1;
+
+ tus_check_conn();
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_modify_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+/***
+ * update_user_db_entry
+ * summary: modifies an existing user entry
+ * params : agentid - agent that is performing this action (for audit log purposes)
+ * uid, lastName, firstName, userCN, userCert - for entry to be added
+ * returns: ldap return code
+ * */
+TPS_PUBLIC int update_user_db_entry(const char *agentid, char *uid, char *lastName, char *firstName, char *userCN, char *userCert)
+{
+ char dn[256];
+ LDAPMod a01;
+ LDAPMod a02;
+ LDAPMod a03;
+ LDAPMod a04;
+ LDAPMod *mods[5];
+ int rc = -1;
+ int certlen=0;
+ int i,j;
+ char *certX = NULL;
+ char *dst = NULL;
+
+ char *sn_values[] = {lastName, NULL};
+ char *givenName_values[] = {firstName, NULL};
+ char *cn_values[] = {userCN, NULL};
+ struct berval berval;
+ struct berval *cert_values[2];
+
+ a01.mod_op = LDAP_MOD_REPLACE;
+ a01.mod_type = USER_SN;
+ a01.mod_values = sn_values;
+
+ a02.mod_op = LDAP_MOD_REPLACE;
+ a02.mod_type = USER_CN;
+ a02.mod_values = cn_values;
+
+ a03.mod_op = LDAP_MOD_REPLACE;
+ a03.mod_type = USER_GIVENNAME;
+ a03.mod_values = ((firstName != NULL && PL_strlen(firstName) > 0)? givenName_values: NULL);
+
+ mods[0] = &a01;
+ mods[1] = &a02;
+ mods[2] = &a03;
+
+ certlen = strlen(userCert);
+
+ certX = malloc(certlen);
+ j = 0;
+ for (i = 0; i < certlen; i++) {
+ if (userCert[i] != '\n' && userCert[i] != '\r') {
+ certX[j++] = userCert[i];
+ }
+ }
+ certX[j++] = '\0';
+ dst = malloc(3 * strlen(certX) / 4);
+ certlen = base64_decode(certX, ( unsigned char * ) dst);
+ free(certX);
+
+ if (certlen > 0) {
+ berval.bv_len = certlen;
+ berval.bv_val = ( char * ) dst;
+ cert_values[0] = &berval;
+ cert_values[1] = NULL;
+
+ a04.mod_op =LDAP_MOD_REPLACE |LDAP_MOD_BVALUES;
+ a04.mod_type = "userCertificate";
+ a04.mod_bvalues = cert_values;
+
+ mods[3] = &a04;
+ } else {
+ mods[3] = NULL;
+ }
+
+ mods[4] = NULL;
+
+ if (PR_snprintf(dn, 255, "uid=%s, ou=People, %s", uid, userBaseDN) < 0 )
+ return -1;
+
+ rc = update_tus_general_db_entry(agentid, dn, mods);
+ if (dst != NULL) free(dst);
+ if (rc == LDAP_SUCCESS)
+ audit_log("modify_user", agentid, uid);
+
+ return rc;
+}
+
+TPS_PUBLIC int update_tus_db_entry (const char *agentid, char *cn, const char *uid, char *keyInfo, const char *status, char *applet_version, const char *reason, const char* token_type)
+{
+ char dn[256];
+ int len, k;
+ int tries;
+ int rc = -1;
+ char **v = NULL;
+ LDAPMod **mods = NULL;
+
+ tus_check_conn();
+ if (PR_snprintf(dn, 255, "cn=%s,%s", cn, baseDN) < 0)
+ return -1;
+
+ if (keyInfo == NULL && token_type == NULL)
+ mods = allocate_modifications(5);
+ else if (keyInfo == NULL || token_type == NULL)
+ mods = allocate_modifications(6);
+ else
+ mods = allocate_modifications(7);
+ if (mods == NULL)
+ return -1;
+
+ if ((v = create_modification_date_change()) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+
+ mods[0]->mod_op = LDAP_MOD_REPLACE;
+ mods[0]->mod_type = tokenAttributes[I_TOKEN_M_DATE];
+ mods[0]->mod_values = v;
+ k = 1;
+ if (applet_version != NULL && PL_strlen(applet_version) > 0) {
+ len = PL_strlen(applet_version);
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ PL_strcpy(v[0], applet_version);
+
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = tokenAttributes[I_TOKEN_APPLET];
+ mods[k]->mod_values = v;
+ k++;
+ }
+
+ /* for userid */
+ if (uid != NULL && PL_strlen(uid) > 0)
+ len = PL_strlen(uid);
+ else
+ len = 0;
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = "tokenUserID";
+ if (uid != NULL && PL_strlen(uid) > 0)
+ PL_strcpy(v[0], uid);
+ else
+ v[0] = "";
+ mods[k]->mod_values = v;
+ k++;
+
+ if (status != NULL && PL_strlen(status) > 0) {
+ len = PL_strlen(status);
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ PL_strcpy(v[0], status);
+
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = tokenAttributes[I_TOKEN_STATUS];
+ mods[k]->mod_values = v;
+ k++;
+ }
+
+ /* for tokenReason */
+ if (reason != NULL && PL_strlen(reason) > 0)
+ len = PL_strlen(reason);
+ else
+ len = 0;
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = "tokenReason";
+ if (reason != NULL && PL_strlen(reason) > 0)
+ PL_strcpy(v[0], reason);
+ else
+ v[0] = "";
+ mods[k]->mod_values = v;
+ k++;
+
+ /* for keyinfo */
+ if (keyInfo != NULL) {
+ if (keyInfo != NULL && PL_strlen(keyInfo) > 0)
+ len = PL_strlen(keyInfo);
+ else
+ len = 0;
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = tokenAttributes[I_TOKEN_KEY_INFO];
+ if (keyInfo != NULL && PL_strlen(keyInfo) > 0)
+ PL_strcpy(v[0], keyInfo);
+ else
+ v[0] = "";
+ mods[k]->mod_values = v;
+ k++;
+ }
+
+ /* for token_type */
+ if (token_type != NULL) {
+ if (token_type != NULL && PL_strlen(token_type) > 0)
+ len = PL_strlen(token_type);
+ else
+ len = 0;
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = TOKEN_TYPE;
+ if (len > 0)
+ PL_strcpy(v[0], token_type);
+ else
+ v[0] = "";
+ mods[k]->mod_values = v;
+ k++;
+ }
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_modify_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+
+ return rc;
+}
+
+int check_and_modify_tus_db_entry (char *userid, char *cn, char *check, LDAPMod **mods)
+{
+ char dn[256];
+ int rc = 0, tries = 0;
+
+ if (check == NULL) {
+ return -1;
+ }
+
+ struct berval check_ber;
+ check_ber.bv_val = check;
+ check_ber.bv_len = strlen(check);
+
+ tus_check_conn();
+ if (PR_snprintf(dn, 255, "cn=%s,%s", cn, baseDN) < 0)
+ return -1;
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_compare_ext_s(ld, dn, get_number_of_modifications_name(), &check_ber, NULL, NULL))
+ == LDAP_COMPARE_TRUE) {
+ break;
+ } else {
+ if (rc != LDAP_SERVER_DOWN && rc != LDAP_CONNECT_ERROR) {
+ return rc;
+ }
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ return rc;
+ }
+ }
+ }
+ if (tries >= MAX_RETRIES)
+ return rc;
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_modify_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ /* audit log */
+ if (rc == LDAP_SUCCESS) {
+ audit_log("check_and_modify_token", userid, cn);
+ }
+
+ return rc;
+}
+
+int modify_tus_db_entry (char *userid, char *cn, LDAPMod **mods)
+{
+ char dn[256];
+ int rc = 0, tries = 0;
+
+ tus_check_conn();
+ if (ld == NULL) {
+ if (debug_fd)
+ PR_fprintf(debug_fd, "tus_db mod: ld null...no ldap");
+ return -1;
+ }
+ if (mods == NULL) {
+ if (debug_fd)
+ PR_fprintf(debug_fd, "tus_db mod: mods null, can't modify");
+ return -1;
+ }
+ if (PR_snprintf(dn, 255, "cn=%s,%s", cn, baseDN) < 0)
+ return -1;
+ if (debug_fd)
+ PR_fprintf(debug_fd, "tus_db mod: modifying :%s\n",dn);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if (debug_fd)
+ PR_fprintf(debug_fd, "tus_db mod: tries=%d\n",tries);
+ if ((rc = ldap_modify_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ if (rc == LDAP_SUCCESS) {
+ audit_log("modify_token", userid, cn);
+ }
+
+ return rc;
+}
+
+int add_certificate (char *tokenid, char *origin, char *tokenType, char *userid, CERTCertificate *certificate, char *ktype, const char *status)
+{
+ PRExplodedTime time;
+ PRTime now;
+ LDAPMod a01;
+ LDAPMod a02;
+ LDAPMod a03;
+ LDAPMod a04;
+ LDAPMod a05;
+ LDAPMod a06;
+ LDAPMod a07;
+ LDAPMod a08;
+ LDAPMod a09;
+ LDAPMod a10;
+ LDAPMod a11;
+ LDAPMod a12;
+ LDAPMod a13;
+ LDAPMod a14;
+ LDAPMod a15;
+ LDAPMod a16;
+ LDAPMod *mods[17];
+ int rc = 0, tries = 0;
+ char dn[2049];
+ char cdate[256];
+ char name[2048];
+ char x_not_before[2048];
+ char x_not_after[2048];
+ char serialnumber[2048];
+ char *serial_values[2];
+ char *cn_values[2];
+ char *issuer_values[2];
+ char *subject_values[2];
+ char *cdate_values[2];
+ char *id_values[2];
+ char *userid_values[2];
+ char *type_values[2];
+ char *key_type_values[2];
+ char *origin_values[2];
+ char *status_values[2];
+ char *not_before_values[2];
+ char *not_after_values[2];
+ PRThread *ct;
+ struct berval berval;
+ struct berval *cert_values[2];
+ char *objectClass_values[] = { "top", "tokenCert", NULL };
+ PRTime not_before,not_after;
+ char zcdate[256];
+
+ tus_check_conn();
+ ct = PR_GetCurrentThread();
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_snprintf(cdate, 16, "%04d%02d%02d%02d%02d%02dZ",
+ time.tm_year, (time.tm_month + 1), time.tm_mday,
+ time.tm_hour, time.tm_min, time.tm_sec);
+
+ /* unique id per activity */
+ tus_print_integer(serialnumber, &certificate->serialNumber);
+
+ PR_snprintf(name, 16, "%04d%02d%02d%02d%02d%02dZ",
+ time.tm_year, (time.tm_month + 1), time.tm_mday,
+ time.tm_hour, time.tm_min, time.tm_sec);
+
+ /* unique id per activity */
+ PR_snprintf(zcdate, 256, "%s.%04d%02d%02d%02d%02d%02d",
+ serialnumber,
+ time.tm_year, (time.tm_month + 1), time.tm_mday,
+ time.tm_hour, time.tm_min, time.tm_sec);
+
+ cn_values[0] = zcdate;
+ cn_values[1] = NULL;
+
+ a01.mod_op = 0;
+ a01.mod_type = TOKEN_ID;
+ a01.mod_values = cn_values;
+
+ a02.mod_op = 0;
+ a02.mod_type = "objectClass";
+ a02.mod_values = objectClass_values;
+
+ cdate_values[0] = cdate;
+ cdate_values[1] = NULL;
+ a03.mod_op = 0;
+ a03.mod_type = TOKEN_C_DATE;
+ a03.mod_values = cdate_values;
+
+ a04.mod_op = 0;
+ a04.mod_type = TOKEN_M_DATE;
+ a04.mod_values = cdate_values;
+
+ id_values[0] = tokenid;
+ id_values[1] = NULL;
+ a05.mod_op = 0;
+ a05.mod_type = TOKEN_CUID;
+ a05.mod_values = id_values;
+
+ userid_values[0] = userid;
+ userid_values[1] = NULL;
+ a06.mod_op = 0;
+ a06.mod_type = TOKEN_USER;
+ a06.mod_values = userid_values;
+
+ berval.bv_len = certificate->derCert.len;
+ berval.bv_val = ( char * ) certificate->derCert.data;
+ cert_values[0] = &berval;
+ cert_values[1] = NULL;
+
+ a07.mod_op = LDAP_MOD_BVALUES;
+ a07.mod_type = TOKEN_CERT;
+ a07.mod_values = ( char ** ) cert_values;
+
+ subject_values[0] = certificate->subjectName;
+ subject_values[1] = NULL;
+ a08.mod_op = 0;
+ a08.mod_type = TOKEN_SUBJECT;
+ a08.mod_values = subject_values;
+
+ issuer_values[0] = certificate->issuerName;
+ issuer_values[1] = NULL;
+ a09.mod_op = 0;
+ a09.mod_type = TOKEN_ISSUER;
+ a09.mod_values = issuer_values;
+
+ serial_values[0] = serialnumber;
+ serial_values[1] = NULL;
+ a10.mod_op = 0;
+ a10.mod_type = TOKEN_SERIAL;
+ a10.mod_values = serial_values;
+
+ type_values[0] = tokenType;
+ type_values[1] = NULL;
+ a11.mod_op = 0;
+ a11.mod_type = TOKEN_TYPE;
+ a11.mod_values = type_values;
+
+ key_type_values[0] = ktype;
+ key_type_values[1] = NULL;
+ a12.mod_op = 0;
+ a12.mod_type = TOKEN_KEY_TYPE;
+ a12.mod_values = key_type_values;
+
+ status_values[0] = ( char * ) status;
+ status_values[1] = NULL;
+ a13.mod_op = 0;
+ a13.mod_type = TOKEN_STATUS;
+ a13.mod_values = status_values;
+
+ CERT_GetCertTimes (certificate, &not_before, &not_after);
+
+ PR_ExplodeTime(not_before, PR_LocalTimeParameters, &time);
+ PR_snprintf(x_not_before, 16, "%04d%02d%02d%02d%02d%02dZ",
+ time.tm_year, (time.tm_month + 1), time.tm_mday,
+ time.tm_hour, time.tm_min, time.tm_sec);
+
+ not_before_values[0] = x_not_before;
+ not_before_values[1] = NULL;
+ a14.mod_op = 0;
+ a14.mod_type = TOKEN_NOT_BEFORE;
+ a14.mod_values = not_before_values;
+
+ PR_ExplodeTime(not_after, PR_LocalTimeParameters, &time);
+ PR_snprintf(x_not_after, 16, "%04d%02d%02d%02d%02d%02dZ",
+ time.tm_year, (time.tm_month + 1), time.tm_mday,
+ time.tm_hour, time.tm_min, time.tm_sec);
+
+ not_after_values[0] = x_not_after;
+ not_after_values[1] = NULL;
+ a15.mod_op = 0;
+ a15.mod_type = TOKEN_NOT_AFTER;
+ a15.mod_values = not_after_values;
+
+ origin_values[0] = origin;
+ origin_values[1] = NULL;
+ a16.mod_op = 0;
+ a16.mod_type = TOKEN_ORIGIN;
+ a16.mod_values = origin_values;
+
+ mods[0] = &a01;
+ mods[1] = &a02;
+ mods[2] = &a03;
+ mods[3] = &a04;
+ mods[4] = &a05;
+ mods[5] = &a06;
+ mods[6] = &a07;
+ mods[7] = &a08;
+ mods[8] = &a09;
+ mods[9] = &a10;
+ mods[10] = &a11;
+ mods[11] = &a12;
+ mods[12] = &a13;
+ mods[13] = &a14;
+ mods[14] = &a15;
+ mods[15] = &a16;
+ mods[16] = NULL;
+
+ if (PR_snprintf(dn, 2048, "cn=%s,%s", cn_values[0], certBaseDN) < 0)
+ return -1;
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_add_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+int add_activity (const char *ip, const char *id, const char *op, const char *result, const char *msg, const char *userid, const char *token_type)
+{
+ PRExplodedTime time;
+ PRTime now;
+ LDAPMod a01;
+ LDAPMod a02;
+ LDAPMod a03;
+ LDAPMod a04;
+ LDAPMod a05;
+ LDAPMod a06;
+ LDAPMod a07;
+ LDAPMod a08;
+ LDAPMod a09;
+ LDAPMod a10;
+ LDAPMod a11;
+ LDAPMod *mods[12];
+ int rc = 0, tries = 0;
+ char dn[256];
+ char cdate[256];
+ char zcdate[256];
+ char *cn_values[2];
+ char *objectClass_values[] = { "top", "tokenActivity", NULL };
+ char *cdate_values[2];
+ char *id_values[2];
+ char *result_values[2];
+ char *op_values[2];
+ char *msg_values[2];
+ char *ip_values[2];
+ char *userid_values[2];
+ char *token_type_values[2];
+ PRThread *ct;
+
+ tus_check_conn();
+ id_values[0] = (char *) id;
+ id_values[1] = NULL;
+ result_values[0] = ( char * ) result;
+ result_values[1] = NULL;
+ op_values[0] = ( char * ) op;
+ op_values[1] = NULL;
+ msg_values[0] = ( char * ) msg;
+ msg_values[1] = NULL;
+ ip_values[0] = (char *) ip;
+ ip_values[1] = NULL;
+ userid_values[0] = (char *) userid;
+ userid_values[1] = NULL;
+ token_type_values[0] = (char *) token_type;
+ token_type_values[1] = NULL;
+
+ ct = PR_GetCurrentThread();
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_snprintf(cdate, 16, "%04d%02d%02d%02d%02d%02dZ",
+ time.tm_year, (time.tm_month + 1), time.tm_mday,
+ time.tm_hour, time.tm_min, time.tm_sec);
+
+ /* unique id per activity */
+ PR_snprintf(zcdate, 256, "%04d%02d%02d%02d%02d%02d%06d.%x",
+ time.tm_year, (time.tm_month + 1), time.tm_mday,
+ time.tm_hour, time.tm_min, time.tm_sec, time.tm_usec, ct);
+
+ cn_values[0] = zcdate;
+ cn_values[1] = NULL;
+
+ a01.mod_op = 0;
+ a01.mod_type = TOKEN_ID;
+ a01.mod_values = cn_values;
+
+ a02.mod_op = 0;
+ a02.mod_type = "objectClass";
+ a02.mod_values = objectClass_values;
+
+ cdate_values[0] = cdate;
+ cdate_values[1] = NULL;
+ a03.mod_op = 0;
+ a03.mod_type = TOKEN_C_DATE;
+ a03.mod_values = cdate_values;
+
+ a04.mod_op = 0;
+ a04.mod_type = TOKEN_M_DATE;
+ a04.mod_values = cdate_values;
+
+ a05.mod_op = 0;
+ a05.mod_type = TOKEN_CUID;
+ a05.mod_values = id_values;
+
+ a06.mod_op = 0;
+ a06.mod_type = TOKEN_OP;
+ a06.mod_values = op_values;
+
+ a07.mod_op = 0;
+ a07.mod_type = TOKEN_MSG;
+ a07.mod_values = msg_values;
+
+ a08.mod_op = 0;
+ a08.mod_type = TOKEN_RESULT;
+ a08.mod_values = result_values;
+
+ a09.mod_op = 0;
+ a09.mod_type = TOKEN_IP;
+ a09.mod_values = ip_values;
+
+ a10.mod_op = 0;
+ a10.mod_type = TOKEN_USER;
+ a10.mod_values = userid_values;
+
+ a11.mod_op = 0;
+ a11.mod_type = TOKEN_TYPE;
+ a11.mod_values = token_type_values;
+ mods[0] = &a01;
+ mods[1] = &a02;
+ mods[2] = &a03;
+ mods[3] = &a04;
+ mods[4] = &a05;
+ mods[5] = &a06;
+ mods[6] = &a07;
+ mods[7] = &a08;
+ mods[8] = &a09;
+ mods[9] = &a10;
+ mods[10] = &a11;
+ mods[11] = NULL;
+
+ if (PR_snprintf(dn, 255, "cn=%s,%s", zcdate, activityBaseDN) < 0)
+ return -1;
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_add_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+/**
+ * add_tus_general_db_entry
+ * summary: internal function to add a general ldap entry
+ * params: dn = dn to add
+ * mods = NULL terminated list of modifications (contains attribute values)
+ * returns: LDAP return code
+ **/
+int add_tus_general_db_entry (char *dn, LDAPMod **mods)
+{
+ int rc = 0, tries = 0;
+
+ tus_check_conn();
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_add_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+
+ }
+ return rc;
+}
+
+int add_tus_db_entry (char *cn, LDAPMod **mods)
+{
+ char dn[256];
+ int rc = 0, tries = 0;
+
+ tus_check_conn();
+ if (PR_snprintf(dn, 255, "cn=%s,%s", cn, baseDN) < 0)
+ return -1;
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_add_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+int add_new_tus_db_entry (const char *userid, char *cn, const char *uid, int flag, const char *status, char *applet_version, char *key_info, const char* token_type)
+{
+ PRExplodedTime time;
+ PRTime now;
+ LDAPMod a01;
+ LDAPMod a02;
+ LDAPMod a03;
+ LDAPMod a04;
+ LDAPMod a05;
+ LDAPMod a06;
+ LDAPMod a07;
+ LDAPMod a08;
+ LDAPMod a09;
+ LDAPMod a10;
+ LDAPMod a11;
+ LDAPMod a12;
+ LDAPMod a13;
+ LDAPMod a14;
+ LDAPMod a15;
+ LDAPMod a16;
+ LDAPMod *mods[17];
+ int rc = 0, tries = 0;
+ char dn[256];
+ char cdate[256];
+ char *cn_values[2];
+ char *objectClass_values[] = { "top", "tokenRecord", NULL };
+ char *cdate_values[2];
+ char *modified_values[] = { "0", NULL };
+ char *uid_values[] = { "", NULL };
+ char *status_values[] = { "", NULL };
+ char *aid_values[] = { "", NULL };
+ char *resets_values[] = { "0", NULL };
+ char *enrollments_values[] = { "0", NULL };
+ char *renewals_values[] = { "0", NULL };
+ char *recoveries_values[] = { "0", NULL };
+ char *key_info_values[] = { "", NULL };
+ char *reason_values[] = { "", NULL };
+ char *policy_values[2];
+ char *token_type_values[]= {"", NULL };
+
+ tus_check_conn();
+ cn_values[0] = cn;
+ cn_values[1] = NULL;
+
+ policy_values[0] = defaultPolicy;
+ policy_values[1] = NULL;
+
+ if (uid != NULL) uid_values[0] = ( char * ) uid;
+ if (key_info != NULL) key_info_values[0] = key_info;
+ status_values[0] = ( char * ) status;
+ token_type_values[0] = ( char *) token_type;
+
+ a01.mod_op = 0;
+ a01.mod_type = TOKEN_ID;
+ a01.mod_values = cn_values;
+
+ a02.mod_op = 0;
+ a02.mod_type = "objectClass";
+ a02.mod_values = objectClass_values;
+
+ cdate_values[0] = cdate;
+ cdate_values[1] = NULL;
+ a03.mod_op = 0;
+ a03.mod_type = TOKEN_C_DATE;
+ a03.mod_values = cdate_values;
+
+ a04.mod_op = 0;
+ a04.mod_type = TOKEN_M_DATE;
+ a04.mod_values = cdate_values;
+
+ a05.mod_op = 0;
+ a05.mod_type = TOKEN_MODS;
+ a05.mod_values = modified_values;
+
+ a06.mod_op = 0;
+ a06.mod_type = TOKEN_USER;
+ a06.mod_values = uid_values;
+
+ a07.mod_op = 0;
+ a07.mod_type = TOKEN_STATUS;
+ a07.mod_values = status_values;
+
+ a08.mod_op = 0;
+ a08.mod_type = TOKEN_APPLET;
+ if (applet_version != NULL) {
+ aid_values[0] = applet_version;
+ }
+ a08.mod_values = aid_values;
+
+ a09.mod_op = 0;
+ a09.mod_type = TOKEN_RESETS;
+ a09.mod_values = resets_values;
+
+ a10.mod_op = 0;
+ a10.mod_type = TOKEN_ENROLLMENTS;
+ a10.mod_values = enrollments_values;
+
+ a11.mod_op = 0;
+ a11.mod_type = TOKEN_RENEWALS;
+ a11.mod_values = renewals_values;
+
+ a12.mod_op = 0;
+ a12.mod_type = TOKEN_RECOVERIES;
+ a12.mod_values = recoveries_values;
+
+ a13.mod_op = 0;
+ a13.mod_type = TOKEN_KEY_INFO;
+ a13.mod_values = key_info_values;
+
+ a14.mod_op = 0;
+ a14.mod_type = TOKEN_POLICY;
+ a14.mod_values = policy_values;
+
+ a15.mod_op = 0;
+ a15.mod_type = TOKEN_REASON;
+ a15.mod_values = reason_values;
+
+ a16.mod_op = 0;
+ a16.mod_type = TOKEN_TYPE;
+ a16.mod_values = token_type_values;
+
+ mods[0] = &a01;
+ mods[1] = &a02;
+ mods[2] = &a03;
+ mods[3] = &a04;
+ mods[4] = &a05;
+ mods[5] = &a06;
+ mods[6] = &a07;
+ mods[7] = &a08;
+ mods[8] = &a09;
+ mods[9] = &a10;
+ mods[10] = &a11;
+ mods[11] = &a12;
+ mods[12] = &a13;
+ mods[13] = &a14;
+ mods[14] = &a15;
+ mods[15] = &a16;
+ mods[16] = NULL;
+
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+
+ PR_snprintf(cdate, 16, "%04d%02d%02d%02d%02d%02dZ",
+ time.tm_year, (time.tm_month + 1), time.tm_mday,
+ time.tm_hour, time.tm_min, time.tm_sec);
+
+ if (PR_snprintf(dn, 255, "cn=%s,%s", cn, baseDN) < 0)
+ return -1;
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_add_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ /* audit log */
+ if (rc == LDAP_SUCCESS) {
+ audit_log("add_token", userid, cn);
+ }
+
+ return rc;
+}
+
+TPS_PUBLIC int add_default_tus_db_entry (const char *uid, const char *agentid, char *cn, const char *status, char *applet_version, char *key_info, const char *token_type)
+{
+ return add_new_tus_db_entry (agentid, cn, uid, 0, status, applet_version, key_info, token_type);
+}
+
+/****
+ * add_user_db_entry
+ * summary: adds a new user entry
+ * params: agentid - user who is performing this change (for audit log)
+ * :userid, userPassword, sn, givenName, cn, userCert - details for user to be added
+ * returns: ldap return code
+ */
+TPS_PUBLIC int add_user_db_entry(const char *agentid, char *userid, char *userPassword, char *sn, char *givenName, char *cn, char *userCert)
+{
+ LDAPMod a01;
+ LDAPMod a02;
+ LDAPMod a03;
+ LDAPMod a04;
+ LDAPMod a05;
+ LDAPMod a06;
+ LDAPMod a07;
+ LDAPMod *mods[8];
+ int rc = 0;
+ char dn[256];
+ int i,j, certlen;
+ char *dst = NULL;
+ char *certX = NULL;
+ char *userid_values[] = {userid, NULL};
+ char *objectClass_values[] = { "top", "person", "organizationalPerson", "inetOrgPerson", "tpsProfileId", NULL };
+ char *userPassword_values[] = { userPassword, NULL };
+ char *sn_values[] = {sn, NULL};
+ char *cn_values[] = {cn, NULL};
+ char *givenName_values[] = {givenName, NULL};
+ struct berval berval;
+ struct berval *userCert_values[2];
+
+ a01.mod_op = 0;
+ a01.mod_type = USER_ID;
+ a01.mod_values = userid_values;
+
+ a02.mod_op = 0;
+ a02.mod_type = "objectClass";
+ a02.mod_values = objectClass_values;
+
+ a03.mod_op =0;
+ a03.mod_type = USER_PASSWORD;
+ a03.mod_values = userPassword_values;
+
+ a04.mod_op = 0;
+ a04.mod_type = USER_SN;
+ a04.mod_values = sn_values;
+
+ a05.mod_op =0;
+ a05.mod_type = USER_CN;
+ a05.mod_values = cn_values;
+
+ a06.mod_op =0;
+ a06.mod_type = USER_GIVENNAME;
+ a06.mod_values = givenName_values;
+
+ mods[0] = &a01;
+ mods[1] = &a02;
+ mods[2] = &a03;
+ mods[3] = &a04;
+ mods[4] = &a05;
+ if (givenName != NULL && PL_strlen(givenName) > 0) {
+ mods[5] = &a06;
+ }
+
+ // now handle certificate
+ certlen = strlen(userCert);
+
+ certX = malloc(certlen);
+ j = 0;
+ for (i = 0; i < certlen; i++) {
+ if (userCert[i] != '\n' && userCert[i] != '\r') {
+ certX[j++] = userCert[i];
+ }
+ }
+ certX[j++] = '\0';
+ dst = malloc(3 * strlen(certX) / 4);
+ certlen = base64_decode(certX, ( unsigned char * ) dst);
+ free(certX);
+
+ if (certlen > 0) {
+ berval.bv_len = certlen;
+ berval.bv_val = ( char * ) dst;
+ userCert_values[0] = &berval;
+ userCert_values[1] = NULL;
+
+ a07.mod_op = LDAP_MOD_BVALUES;
+ a07.mod_type = USER_CERT;
+ a07.mod_bvalues = userCert_values;
+
+ if (givenName != NULL && PL_strlen(givenName) > 0) {
+ mods[6] = &a07;
+ } else {
+ mods[5] = &a07;
+ }
+ } else {
+ if (givenName == NULL || PL_strlen(givenName) == 0) {
+ mods[5] = NULL;
+ }
+ mods[6] = NULL;
+ }
+
+ mods[7] = NULL;
+
+ if (PR_snprintf(dn, 255, "uid=%s,ou=People, %s", userid, userBaseDN) < 0)
+ return -1;
+
+ rc = add_tus_general_db_entry(dn, mods);
+ if (dst != NULL) free(dst);
+
+ if (rc != LDAP_SUCCESS) {
+ return rc;
+ }
+
+ audit_log("add_user", agentid, userid);
+ return rc;
+}
+
+/**
+ * add_user_to_role_db_entry
+ * summary: adds user to be member of group (administrators, agents, operators)
+ * params: agentid -user who is performing this change
+ * : userid - userid of user to be added to role
+ * : role - Operators, Agents or Administrators
+ * returns: LDAP return code
+ */
+TPS_PUBLIC int add_user_to_role_db_entry(const char *agentid, char *userid, const char *role) {
+ LDAPMod a01;
+ LDAPMod *mods[2];
+ int rc = 0;
+ char dn[256];
+ char userdn[256];
+ char msg[256];
+ char *userid_values[2];
+
+ if (PR_snprintf(userdn, 255, "uid=%s, ou=People, %s", userid, userBaseDN) < 0)
+ return -1;
+
+ userid_values[0] = userdn;
+ userid_values[1] = NULL;
+
+ a01.mod_op = LDAP_MOD_ADD;
+ a01.mod_type = GROUP_MEMBER;
+ a01.mod_values = userid_values;
+ mods[0] = &a01;
+ mods[1] = NULL;
+
+ if (PR_snprintf(dn, 255, "cn=TUS %s,ou=groups, %s", role, userBaseDN) < 0)
+ return -1;
+
+ rc = update_tus_general_db_entry(agentid, dn, mods);
+
+ if (rc == LDAP_SUCCESS) {
+ PR_snprintf(msg, 256, "Added role %s to user %s", role, userid);
+ audit_log("add_user_to_role", agentid, msg);
+ }
+ return rc;
+}
+
+/**
+ * delete_user_to_role_db_entry
+ * summary: removes user from role group (administrators, agents, operators)
+ * params: agentid -user who is performing this change
+ * : userid - userid of user to be removed from role
+ * : role - Operators, Agents or Administrators
+ * returns: LDAP return code
+ */
+TPS_PUBLIC int delete_user_from_role_db_entry(const char *agentid, char *userid, const char *role) {
+ LDAPMod a01;
+ LDAPMod *mods[2];
+ int rc = 0;
+ char dn[256];
+ char userdn[256];
+ char *userid_values[2];
+ char msg[256];
+
+ if (PR_snprintf(userdn, 255, "uid=%s, ou=People, %s", userid, userBaseDN) < 0)
+ return -1;
+
+ userid_values[0] = userdn;
+ userid_values[1] = NULL;
+
+ a01.mod_op = LDAP_MOD_DELETE;
+ a01.mod_type = GROUP_MEMBER;
+ a01.mod_values = userid_values;
+ mods[0] = &a01;
+ mods[1] = NULL;
+
+ if (PR_snprintf(dn, 255, "cn=TUS %s,ou=groups, %s", role, userBaseDN) < 0)
+ return -1;
+
+ rc = update_tus_general_db_entry(agentid, dn, mods);
+ if (rc == LDAP_SUCCESS) {
+ PR_snprintf(msg, 256, "Deleted role %s from user %s", role, userid);
+ audit_log("delete_user_from_role", agentid, msg);
+ }
+
+ return rc;
+}
+
+/**
+ * delete_profile_from_user
+ * summary: removes attribute profileID=profile from user entry
+ * params: agentid -user who is performing this change
+ * : userid - userid of user to be modified
+ * : profile - profile to be deleted
+ * returns: LDAP return code
+ */
+TPS_PUBLIC int delete_profile_from_user(const char *agentid, char *userid, const char *profile) {
+ LDAPMod a01;
+ LDAPMod *mods[2];
+ int rc = 0;
+ char dn[256];
+ char msg[256];
+ char *profileid_values[2] = {(char *) profile, NULL};
+
+ if (PR_snprintf(dn, 255, "uid=%s, ou=People, %s", userid, userBaseDN) < 0)
+ return -1;
+
+ a01.mod_op = LDAP_MOD_DELETE;
+ a01.mod_type = PROFILE_ID;
+ a01.mod_values = profileid_values;
+ mods[0] = &a01;
+ mods[1] = NULL;
+
+ rc = update_tus_general_db_entry(agentid, dn, mods);
+ if (rc == LDAP_SUCCESS) {
+ PR_snprintf(msg, 256, "Deleted profile %s from user %s", profile, userid);
+ audit_log("delete_profile_from_user", agentid, msg);
+ }
+
+ return rc;
+}
+
+/**
+ * delete_all_profiles_from_user
+ * summary: removes all attributes profileID from user entry
+ * same as above, but passing NULL for mod_values
+ * params: agentid -user who is performing this change
+ * : userid - userid of user to be modified
+ * : profile - profile to be deleted
+ * returns: LDAP return code
+ */
+TPS_PUBLIC int delete_all_profiles_from_user(const char *agentid, char *userid) {
+ LDAPMod a01;
+ LDAPMod *mods[2];
+ int rc = 0;
+ char dn[256];
+ char msg[256];
+
+ if (PR_snprintf(dn, 255, "uid=%s, ou=People, %s", userid, userBaseDN) < 0)
+ return -1;
+
+ a01.mod_op = LDAP_MOD_DELETE;
+ a01.mod_type = PROFILE_ID;
+ a01.mod_values = NULL; /* NULL will remove all values */
+ mods[0] = &a01;
+ mods[1] = NULL;
+
+ rc = update_tus_general_db_entry(agentid, dn, mods);
+ if (rc == LDAP_SUCCESS) {
+ PR_snprintf(msg, 256, "Deleted all profiles from user %s", userid);
+ audit_log("delete_all_profiles_from_user", agentid, msg);
+ }
+
+ return rc;
+}
+
+
+/**
+ * add_profile_to_user
+ * summary: adds attribute profileID=profile to user entry
+ * params: agentid -user who is performing this change
+ * : userid - userid of user to be modified
+ * : profile - profile (tokenType) to be added
+ * returns: LDAP return code
+ */
+TPS_PUBLIC int add_profile_to_user(const char *agentid, char *userid, const char *profile) {
+ LDAPMod a01;
+ LDAPMod *mods[2];
+ int rc = 0;
+ char dn[256];
+ char msg[256];
+ char *profileid_values[2] = {(char *) profile, NULL};
+
+ if (PR_snprintf(dn, 255, "uid=%s, ou=People, %s", userid, userBaseDN) < 0)
+ return -1;
+
+ a01.mod_op = LDAP_MOD_ADD;
+ a01.mod_type = PROFILE_ID;
+ a01.mod_values = profileid_values;
+ mods[0] = &a01;
+ mods[1] = NULL;
+
+ rc = update_tus_general_db_entry(agentid, dn, mods);
+ if (rc == LDAP_SUCCESS) {
+ PR_snprintf(msg, 256, "Added profile %s to user %s", profile, userid);
+ audit_log("add_profile_to_user", agentid, msg);
+ }
+
+ return rc;
+}
+
+int delete_tus_db_entry (char *userid, char *cn)
+{
+ char dn[256];
+ int rc = 0, tries = 0;
+
+ tus_check_conn();
+ if (PR_snprintf(dn, 255, "cn=%s,%s", cn, baseDN) < 0)
+ return -1;
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_delete_ext_s(ld, dn, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ /* audit log */
+ if (rc == LDAP_SUCCESS) {
+ audit_log("delete_token", userid, cn);
+ }
+
+ return rc;
+}
+
+int delete_tus_general_db_entry (char *dn)
+{
+ int rc = 0, tries = 0;
+
+ tus_check_conn();
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_delete_ext_s(ld, dn, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+/**
+ * delete_user_db_entry
+ * Deletes user entry
+ * params: agentid - user performing this change
+ * uid - user to be deleted
+ * returns: LDAP return code
+ */
+TPS_PUBLIC int delete_user_db_entry(const char *agentid, char *uid)
+{
+ char dn[256];
+ int rc =0;
+ if (PR_snprintf(dn, 255, "uid=%s,ou=People,%s", uid, userBaseDN) < 0)
+ return -1;
+ rc = delete_tus_general_db_entry(dn);
+
+ if (rc == LDAP_SUCCESS) {
+ audit_log("delete user", agentid, uid);
+ }
+
+ return rc;
+}
+
+
+TPS_PUBLIC int find_tus_db_entry (char *cn, int max, LDAPMessage **result)
+{
+ char dn[256];
+ int rc = 0, tries = 0;
+
+ tus_check_conn();
+ if (ld == NULL)
+ return -1;
+
+ if (PR_snprintf(dn, 255, "cn=%s,%s", cn, baseDN) < 0)
+ return -1;
+
+ if (debug_fd)
+ PR_fprintf(debug_fd, "find_tus_db_entry: looking for :%s\n",dn);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if (debug_fd)
+ PR_fprintf(debug_fd, "find_tus_db_entry: tries = %d\n",tries);
+ if ((rc = ldap_search_ext_s (ld, dn, LDAP_SCOPE_BASE, "(objectclass=*)",
+ NULL, 0, NULL, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ if (debug_fd)
+ PR_fprintf(debug_fd, "find_tus_db_entry: found it\n");
+
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ if (debug_fd)
+ PR_fprintf(debug_fd, "find_tus_db_entry: server down or connect error\n");
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ } else {/* can't find?*/
+ if (debug_fd)
+ PR_fprintf(debug_fd, "find_tus_db_entry: can't find\n");
+ break;
+ }
+ }
+
+ return rc;
+}
+
+TPS_PUBLIC int find_tus_db_entries (const char *filter, int max, LDAPMessage **result)
+{
+ int rc = LDAP_OTHER, tries = 0;
+
+ LDAPSortKey **sortKeyList;
+ LDAPControl *controls[3];
+ LDAPVLVInfo vlv_data;
+
+ tus_check_conn();
+ controls[0] = NULL;
+ controls[1] = NULL;
+ controls[2] = NULL;
+
+ vlv_data.ldvlv_before_count = 0;
+ vlv_data.ldvlv_after_count = max - 1;
+ vlv_data.ldvlv_attrvalue = NULL;
+ vlv_data.ldvlv_count = max;
+ vlv_data.ldvlv_offset = 0;
+ vlv_data.ldvlv_version = 1;
+ vlv_data.ldvlv_context = NULL;
+ vlv_data.ldvlv_extradata = NULL;
+ ldap_create_vlv_control(ld, &vlv_data, &controls[0]);
+
+ ldap_create_sort_keylist(&sortKeyList, "-dateOfModify");
+ ldap_create_sort_control(ld, sortKeyList, 1 /* non-critical */,
+ &controls[1]);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, baseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, controls, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ ldap_free_sort_keylist(sortKeyList);
+ ldap_control_free(controls[0]);
+ ldap_control_free(controls[1]);
+
+ return rc;
+}
+
+TPS_PUBLIC int find_tus_db_entries_pcontrol_1(const char *filter, int max, int time_limit, int size_limit, LDAPMessage **result)
+{
+ int rc = LDAP_OTHER, tries = 0;
+
+ LDAPSortKey **sortKeyList;
+ LDAPControl *controls[3];
+ struct berval *cookie=NULL;
+ struct timeval timeout;
+
+ timeout.tv_sec = time_limit;
+ timeout.tv_usec = 0;
+
+ tus_check_conn();
+ controls[0] = NULL;
+ controls[1] = NULL;
+ controls[2] = NULL;
+
+ rc = ldap_create_page_control(ld, max, cookie, 0, &controls[0]);
+
+ ldap_create_sort_keylist(&sortKeyList, "-dateOfModify");
+ ldap_create_sort_control(ld, sortKeyList, 1 /* non-critical */,
+ &controls[1]);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ rc = ldap_search_ext_s (ld, baseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, controls, NULL,
+ time_limit >0 ? &timeout : NULL,
+ size_limit, result);
+ if ((rc == LDAP_SUCCESS) || (rc == LDAP_PARTIAL_RESULTS)) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ if (cookie != NULL) {
+ ber_bvfree(cookie);
+ cookie = NULL;
+ }
+
+ ldap_free_sort_keylist(sortKeyList);
+
+ ldap_control_free(controls[0]);
+ ldap_control_free(controls[1]);
+
+ return rc;
+}
+
+static int sort_cmp(const char *v1, const char *v2)
+{
+ return PL_strcasecmp(v1, v2);
+}
+
+static int reverse_sort_cmp(const char *v1, const char *v2)
+{
+ return PL_strcasecmp(v2, v1);
+}
+
+typedef int (LDAP_SORT_AD_CMP_PROC) (const char * left, const char *right);
+static LDAP_SORT_AD_CMP_PROC *et_cmp_fn;
+
+struct entrything {
+ char **et_vals;
+ LDAPMessage *et_msg;
+};
+
+static int et_cmp(const void *aa, const void *bb)
+{
+ int i, rc;
+
+ struct entrything *a = (struct entrything *)aa;
+ struct entrything *b = (struct entrything *)bb;
+
+ if ((a == NULL) && (b == NULL))
+ return 0;
+ if (a == NULL)
+ return -1;
+ if (b == NULL)
+ return 1;
+
+ if ((a->et_vals == NULL) && (b->et_vals == NULL))
+ return 0;
+ if (a->et_vals == NULL)
+ return -1;
+ if (b->et_vals == NULL)
+ return 1;
+
+ for ( i = 0; a->et_vals[i] && b->et_vals[i]; i++ ) {
+ if ( (rc = (*et_cmp_fn)( a->et_vals[i], b->et_vals[i] )) != 0) {
+ return rc;
+ }
+ }
+
+ if ((a->et_vals[i] == NULL) && (b->et_vals[i] == NULL))
+ return 0;
+ if (a->et_vals[i] == NULL)
+ return -1;
+ return 1;
+}
+
+
+static int ldap_multisort_entries(LDAP *ld, LDAPMessage **chain, char **attr, LDAP_SORT_AD_CMP_PROC *cmp)
+{
+ int i, count, c;
+ struct entrything *et;
+ LDAPMessage *e;
+
+ if ((chain == NULL) || (cmp == NULL) || (attr == NULL)) {
+ return LDAP_PARAM_ERROR;
+ }
+
+ count = ldap_count_entries( ld, *chain );
+
+ if (count < 0) { /* error, usually with bad ld or malloc */
+ return LDAP_PARAM_ERROR;
+ }
+
+ if (count < 2) { /* nothing to sort */
+ return 0;
+ }
+
+ if ((et = (struct entrything *)PR_Malloc( count * sizeof(struct entrything) )) == NULL ) {
+ //ldap_set_option(ld, LDAP_OPT_ERROR_NUMBER, LDAP_NO_MEMORY);
+ return -1;
+ }
+
+ for (i=0, e=get_first_entry(*chain); e != NULL; e = get_next_entry(e)) {
+ et[i].et_msg = e;
+ et[i].et_vals = NULL;
+ if (attr == NULL) {
+ /* if attr =NULL, sort by dn -- not yet implemented , fixme.
+ char *dn;
+ LDAPDN *ldapdn;
+ dn = ldap_get_dn(ld, e);
+ ldapstr2dn(dn, ldapdn, LDAP_DN_FORMAT_LDAPV3|LDAP_DN_P_NO_SPACES);
+ et[i].et_vals = ldap_explode_dn(dn, 1);
+ ldap_memfree(dn); */
+ } else {
+ int attrcnt;
+ struct berval **vals;
+
+ for (attrcnt = 0; attr[attrcnt] != NULL; attrcnt++ ) {
+ vals = ldap_get_values_len(ld, e, attr[attrcnt]);
+ if (vals == NULL) {
+ continue;
+ }
+ for (c=0; vals[c] != NULL; c++);
+ et[i].et_vals = (char **) PR_Malloc((c+1) * sizeof(char *));
+ for (c=0; vals[c] != NULL; c++) {
+ if (vals[c]->bv_val != NULL) {
+ et[i].et_vals[c] = (char *) PL_strdup(vals[c]->bv_val);
+ } else {
+ et[i].et_vals[c] = NULL;
+ }
+ }
+ et[i].et_vals[c] = NULL;
+
+ if (vals != NULL) {
+ ldap_value_free_len(vals );
+ vals = NULL;
+ }
+ }
+ }
+ i++;
+ }
+
+ et_cmp_fn = cmp;
+ qsort((void *) et, (size_t) count, (size_t) sizeof(struct entrything), et_cmp);
+
+ // reconstruct chain
+
+ for (i=0; i< count-1; i++)
+ ldap_delete_result_entry(chain, et[i].et_msg);
+
+ for (i=count -2; i >=0; i--)
+ ldap_add_result_entry(chain, et[i].et_msg);
+
+ // free et
+ for (i= 0; i < count; i++) {
+ for (c=0; et[i].et_vals[c] != NULL; c++) {
+ PL_strfree( et[i].et_vals[c]);
+ et[i].et_vals[c] = NULL;
+ }
+ }
+
+ PR_Free( (char *) et );
+
+ return 0;
+}
+
+/* this is not implemented in openldap and must be implemented in custom code.
+ * This code is adopted from mozldap sort.c
+ */
+static int ldap_sort_entries(LDAP *ld, LDAPMessage **result, const char* attr, LDAP_SORT_AD_CMP_PROC *cmp)
+{
+ char *attrs[2];
+ attrs[0] = (char *) attr;
+ attrs[1] = NULL;
+ return ldap_multisort_entries(ld, result, attr ? attrs : NULL, cmp);
+}
+
+TPS_PUBLIC int find_tus_token_entries_no_vlv(char *filter, LDAPMessage **result, int order)
+{
+ int rc = LDAP_OTHER, tries = 0;
+
+ tus_check_conn();
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, baseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, NULL, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ /* we do client-side sorting here */
+ if (order == 0) {
+ rc = ldap_sort_entries(ld, result, "dateOfCreate",
+ sort_cmp);
+ } else { /* order == 1 */
+ rc = ldap_sort_entries(ld, result, "dateOfCreate",
+ reverse_sort_cmp);
+ }
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+/**
+ * find_tus_user_entries_no_vlv
+ * params: filter - ldap search filter
+ * result - hash of LDAP Search results.
+ * order - 0 (order results increasing by uid), (!=0) order by decreasing uid
+ */
+TPS_PUBLIC int find_tus_user_entries_no_vlv(char *filter, LDAPMessage **result, int order)
+{
+ int rc = LDAP_OTHER, tries = 0;
+ char peopleBaseDN[256];
+
+ PR_snprintf(peopleBaseDN, 256, "ou=People,%s", userBaseDN);
+
+ tus_check_conn();
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, peopleBaseDN, LDAP_SCOPE_ONELEVEL, filter,
+ userAttributes, 0, NULL, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ /* we do client-side sorting here */
+ if (order == 0) {
+ rc = ldap_sort_entries(ld, result, USER_ID, sort_cmp);
+ } else {
+ rc = ldap_sort_entries(ld, result, USER_ID, reverse_sort_cmp);
+ }
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+/**
+ * find_tus_user_role_entries
+ * summary: return the dns for the groups to which the user belongs
+ * (TUS Administrators, Agents, Operator)
+ * params: uid - userid
+ * result - hash of LDAPResults
+ */
+TPS_PUBLIC int find_tus_user_role_entries( const char*uid, LDAPMessage **result)
+{
+ int rc = LDAP_OTHER, tries = 0;
+ char groupBaseDN[256];
+ char filter[256];
+ char *subgroup_attrs[] = {SUBGROUP_ID, NULL};
+
+ PR_snprintf(groupBaseDN, 256, "ou=Groups,%s", userBaseDN);
+ PR_snprintf(filter, 256, "member=uid=%s,ou=People,%s", uid, userBaseDN);
+
+ tus_check_conn();
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, groupBaseDN, LDAP_SCOPE_SUBTREE, filter,
+ subgroup_attrs, 0, NULL, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+TPS_PUBLIC int find_tus_activity_entries_no_vlv(char *filter, LDAPMessage **result, int order)
+{
+ int rc = LDAP_OTHER, tries = 0;
+
+ tus_check_conn();
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, activityBaseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, NULL, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ /* we do client-side sorting here */
+ if (order == 0) {
+ rc = ldap_sort_entries(ld, result, "dateOfCreate",
+ sort_cmp);
+ } else { /* order == 1 */
+ rc = ldap_sort_entries(ld, result, "dateOfCreate",
+ reverse_sort_cmp);
+ }
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+TPS_PUBLIC int find_tus_token_entries(char *filter, int max, LDAPMessage **result, int order)
+{
+ int rc = LDAP_OTHER, tries = 0;
+ LDAPSortKey **sortKeyList;
+ LDAPControl *controls[3];
+ LDAPVLVInfo vlv_data;
+
+ tus_check_conn();
+ controls[0] = NULL;
+ controls[1] = NULL;
+ controls[2] = NULL;
+
+ vlv_data.ldvlv_before_count = 0;
+ vlv_data.ldvlv_after_count = max - 1;
+ vlv_data.ldvlv_attrvalue = NULL;
+ vlv_data.ldvlv_count = max;
+ vlv_data.ldvlv_offset = 0;
+ vlv_data.ldvlv_version = 1;
+ vlv_data.ldvlv_context = NULL;
+ vlv_data.ldvlv_extradata = NULL;
+ ldap_create_vlv_control(ld, &vlv_data, &controls[0]);
+
+ ldap_create_sort_keylist(&sortKeyList, "-dateOfCreate");
+ (*sortKeyList)->reverseOrder = order;
+ ldap_create_sort_control(ld, sortKeyList, 1 /* non-critical */,
+ &controls[1]);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, baseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, controls, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ ldap_free_sort_keylist(sortKeyList);
+ ldap_control_free(controls[0]);
+ ldap_control_free(controls[1]);
+
+ return rc;
+}
+
+TPS_PUBLIC int update_token_status_reason_userid(const char *userid, char *cuid,
+ const char *tokenStatus, const char *reason, int modifyDateOfCreate) {
+ LDAPMod **mods = NULL;
+ int status;
+ char **v = NULL;
+ int len = 0;
+
+ tus_check_conn();
+ if (modifyDateOfCreate)
+ mods = allocate_modifications(5);
+ else
+ mods = allocate_modifications(4);
+
+ if (mods == NULL) {
+ return -1;
+ } else {
+ if ((v = create_modification_date_change()) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ }
+
+ mods[0]->mod_op = LDAP_MOD_REPLACE;
+ mods[0]->mod_type = get_modification_date_name();
+ mods[0]->mod_values = v;
+
+ /* for token status */
+ if (tokenStatus != NULL && PL_strlen(tokenStatus) > 0) {
+ len = PL_strlen(tokenStatus);
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ PL_strcpy(v[0], tokenStatus);
+ mods[1]->mod_op = LDAP_MOD_REPLACE;
+ mods[1]->mod_type = get_token_status_name();
+ mods[1]->mod_values = v;
+ }
+
+ /* for token reason */
+ if (reason != NULL && PL_strlen(reason) > 0)
+ len = PL_strlen(reason);
+ else
+ len = 0;
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ mods[2]->mod_op = LDAP_MOD_REPLACE;
+ mods[2]->mod_type = tokenAttributes[13];
+ if (reason != NULL && PL_strlen(reason) > 0)
+ PL_strcpy(v[0], reason);
+ else
+ v[0] = "";
+ mods[2]->mod_values = v;
+
+ /* for userid */
+ if (userid != NULL && PL_strlen(userid) > 0)
+ len = PL_strlen(userid);
+ else
+ len = 0;
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ mods[3]->mod_op = LDAP_MOD_REPLACE;
+ mods[3]->mod_type = "tokenUserID";
+ if (userid != NULL && PL_strlen(userid) > 0)
+ PL_strcpy(v[0], userid);
+ else
+ v[0] = "";
+ mods[3]->mod_values = v;
+
+ if (modifyDateOfCreate) {
+ if ((v = create_modification_date_change()) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+
+ mods[4]->mod_op = LDAP_MOD_REPLACE;
+ mods[4]->mod_type = "dateOfCreate";
+ mods[4]->mod_values = v;
+
+ }
+
+ status = update_tus_db_entry_with_mods(userid, cuid, mods);
+ return status;
+}
+
+TPS_PUBLIC int update_token_status_reason(char *userid, char *cuid, const char *tokenStatus, const char *reason) {
+ LDAPMod **mods = NULL;
+ int status;
+ char **v = NULL;
+ int len = 0;
+
+ tus_check_conn();
+ mods = allocate_modifications(3);
+
+ if (mods == NULL) {
+ return -1;
+ } else {
+ if ((v = create_modification_date_change()) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ }
+
+ mods[0]->mod_op = LDAP_MOD_REPLACE;
+ mods[0]->mod_type = get_modification_date_name();
+ mods[0]->mod_values = v;
+
+ /* for token status */
+ if (tokenStatus != NULL && PL_strlen(tokenStatus) > 0) {
+ len = PL_strlen(tokenStatus);
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ PL_strcpy(v[0], tokenStatus);
+ mods[1]->mod_op = LDAP_MOD_REPLACE;
+ mods[1]->mod_type = get_token_status_name();
+ mods[1]->mod_values = v;
+ }
+
+ /* for token reason */
+ if (reason != NULL && PL_strlen(reason) > 0)
+ len = PL_strlen(reason);
+ else
+ len = 0;
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ mods[2]->mod_op = LDAP_MOD_REPLACE;
+ mods[2]->mod_type = tokenAttributes[13];
+ if (reason != NULL && PL_strlen(reason) > 0)
+ PL_strcpy(v[0], reason);
+ else
+ v[0] = "";
+ mods[2]->mod_values = v;
+
+ status = update_tus_db_entry_with_mods(userid, cuid, mods);
+ return status;
+}
+
+TPS_PUBLIC int tus_has_active_tokens(char *userid)
+{
+ LDAPMessage *result;
+ char filter[256];
+ int n = 0;
+
+ int rc = LDAP_OTHER, tries = 0;
+ LDAPSortKey **sortKeyList;
+ LDAPControl *controls[3];
+ LDAPVLVInfo vlv_data;
+ int max = 1000;
+
+ tus_check_conn();
+ PR_snprintf(filter, 256, "(&(tokenStatus=active)(tokenUserID=%s))", userid);
+ controls[0] = NULL;
+ controls[1] = NULL;
+ controls[2] = NULL;
+
+ vlv_data.ldvlv_before_count = 0;
+ vlv_data.ldvlv_after_count = max - 1;
+ vlv_data.ldvlv_attrvalue = NULL;
+ vlv_data.ldvlv_count = max;
+ vlv_data.ldvlv_offset = 0;
+ vlv_data.ldvlv_version = 1;
+ vlv_data.ldvlv_context = NULL;
+ vlv_data.ldvlv_extradata = NULL;
+ ldap_create_vlv_control(ld, &vlv_data, &controls[0]);
+
+ ldap_create_sort_keylist(&sortKeyList, "-dateOfCreate");
+ ldap_create_sort_control(ld, sortKeyList, 1 /* non-critical */,
+ &controls[1]);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, baseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, controls, NULL, NULL, 0, &result)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((n = ldap_count_entries (ld, result)) >= 0) {
+ break;
+ } else {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ ldap_free_sort_keylist(sortKeyList);
+ ldap_control_free(controls[0]);
+ ldap_control_free(controls[1]);
+
+ if (rc == LDAP_SUCCESS) {
+ if (n > 0)
+ return 0;
+ else
+ return -1;
+ }
+
+ return rc;
+}
+
+TPS_PUBLIC int find_tus_certificate_entries_by_order_no_vlv (char *filter,
+ LDAPMessage **result, int order)
+{
+ int rc = LDAP_OTHER, tries = 0;
+
+ tus_check_conn();
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, certBaseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, NULL, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ /* we do client-side sorting here */
+ if (order == 0) {
+ rc = ldap_sort_entries(ld, result, "dateOfCreate",
+ sort_cmp);
+ } else {
+ rc = ldap_sort_entries(ld, result, "dateOfCreate",
+ reverse_sort_cmp);
+ }
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+TPS_PUBLIC int find_tus_certificate_entries_by_order (char *filter, int max,
+ LDAPMessage **result, int order)
+{
+ int rc = LDAP_OTHER, tries = 0;
+ LDAPSortKey **sortKeyList;
+ LDAPControl *controls[3];
+ LDAPVLVInfo vlv_data;
+
+ tus_check_conn();
+ controls[0] = NULL;
+ controls[1] = NULL;
+ controls[2] = NULL;
+
+ vlv_data.ldvlv_before_count = 0;
+ vlv_data.ldvlv_after_count = max - 1;
+ vlv_data.ldvlv_attrvalue = NULL;
+ vlv_data.ldvlv_count = max;
+ vlv_data.ldvlv_offset = 0;
+ vlv_data.ldvlv_version = 1;
+ vlv_data.ldvlv_context = NULL;
+ vlv_data.ldvlv_extradata = NULL;
+ ldap_create_vlv_control(ld, &vlv_data, &controls[0]);
+
+ ldap_create_sort_keylist(&sortKeyList, "-dateOfCreate");
+ (*sortKeyList)->reverseOrder = order;
+ ldap_create_sort_control(ld, sortKeyList, 1 /* non-critical */,
+ &controls[1]);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, certBaseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, controls, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ ldap_free_sort_keylist(sortKeyList);
+ ldap_control_free(controls[0]);
+ ldap_control_free(controls[1]);
+
+ return rc;
+}
+
+int find_tus_certificate_entries (char *filter, int max, LDAPMessage **result)
+{
+ int rc = LDAP_OTHER, tries = 0;
+ LDAPSortKey **sortKeyList;
+ LDAPControl *controls[3];
+ LDAPVLVInfo vlv_data;
+
+ tus_check_conn();
+ controls[0] = NULL;
+ controls[1] = NULL;
+ controls[2] = NULL;
+
+ vlv_data.ldvlv_before_count = 0;
+ vlv_data.ldvlv_after_count = max - 1;
+ vlv_data.ldvlv_attrvalue = NULL;
+ vlv_data.ldvlv_count = max;
+ vlv_data.ldvlv_offset = 0;
+ vlv_data.ldvlv_version = 1;
+ vlv_data.ldvlv_context = NULL;
+ vlv_data.ldvlv_extradata = NULL;
+ ldap_create_vlv_control(ld, &vlv_data, &controls[0]);
+
+ ldap_create_sort_keylist(&sortKeyList, "-dateOfCreate");
+ ldap_create_sort_control(ld, sortKeyList, 1 /* non-critical */,
+ &controls[1]);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, certBaseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, controls, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ ldap_free_sort_keylist(sortKeyList);
+ ldap_control_free(controls[0]);
+ ldap_control_free(controls[1]);
+
+ return rc;
+}
+
+int find_tus_activity_entries (char *filter, int max, LDAPMessage **result)
+{
+ int rc = LDAP_OTHER, tries = 0;
+ LDAPSortKey **sortKeyList;
+ LDAPControl *controls[3];
+ LDAPVLVInfo vlv_data;
+
+ tus_check_conn();
+ controls[0] = NULL;
+ controls[1] = NULL;
+ controls[2] = NULL;
+
+ vlv_data.ldvlv_before_count = 0;
+ vlv_data.ldvlv_after_count = max - 1;
+ vlv_data.ldvlv_attrvalue = NULL;
+ vlv_data.ldvlv_count = max;
+ vlv_data.ldvlv_offset = 0;
+ vlv_data.ldvlv_version = 1;
+ vlv_data.ldvlv_context = NULL;
+ vlv_data.ldvlv_extradata = NULL;
+ ldap_create_vlv_control(ld, &vlv_data, &controls[0]);
+
+ ldap_create_sort_keylist(&sortKeyList, "-dateOfCreate");
+ ldap_create_sort_control(ld, sortKeyList, 1 /* non-critical */,
+ &controls[1]);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, activityBaseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, controls, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ ldap_free_sort_keylist(sortKeyList);
+ ldap_control_free(controls[0]);
+ ldap_control_free(controls[1]);
+
+ return rc;
+}
+
+TPS_PUBLIC int find_tus_activity_entries_pcontrol_1(char *filter, int max, int time_limit, int size_limit, LDAPMessage **result)
+{
+ int rc = LDAP_OTHER, tries = 0;
+ LDAPSortKey **sortKeyList;
+ LDAPControl *controls[3];
+ struct berval *cookie=NULL;
+ struct timeval timeout;
+
+ timeout.tv_sec = time_limit;
+ timeout.tv_usec = 0;
+
+ tus_check_conn();
+ controls[0] = NULL;
+ controls[1] = NULL;
+ controls[2] = NULL;
+
+ rc = ldap_create_page_control(ld, max, cookie, 0, &controls[0]);
+
+ ldap_create_sort_keylist(&sortKeyList, "-dateOfCreate");
+ ldap_create_sort_control(ld, sortKeyList, 1 /* non-critical */,
+ &controls[1]);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ rc = ldap_search_ext_s (ld, activityBaseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, controls, NULL,
+ time_limit >0 ? &timeout : NULL,
+ size_limit, result);
+ if ((rc == LDAP_SUCCESS) || (rc == LDAP_PARTIAL_RESULTS)) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ if (cookie != NULL) {
+ ber_bvfree(cookie);
+ cookie = NULL;
+ }
+
+ ldap_free_sort_keylist(sortKeyList);
+
+ ldap_control_free(controls[0]);
+ ldap_control_free(controls[1]);
+
+ return rc;
+}
+
+int get_number_of_entries (LDAPMessage *result)
+{
+ int n = 0, rc = 0, tries = 0;
+
+ tus_check_conn();
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((n = ldap_count_entries (ld, result)) >= 0) {
+ break;
+ } else {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return n;
+}
+
+int free_results (LDAPMessage *results)
+{
+ return ldap_msgfree (results);
+}
+
+LDAPMessage *get_first_entry (LDAPMessage *result)
+{
+ return ldap_first_entry (ld, result);
+}
+
+LDAPMessage *get_next_entry (LDAPMessage *entry)
+{
+ return ldap_next_entry (ld, entry);
+}
+
+TPS_PUBLIC char **get_token_states()
+{
+ return tokenStates;
+}
+
+TPS_PUBLIC char **get_certificate_attributes()
+{
+ return tokenCertificateAttributes;
+}
+
+TPS_PUBLIC char **get_activity_attributes()
+{
+ return tokenActivityAttributes;
+}
+
+TPS_PUBLIC char **get_token_attributes()
+{
+ return tokenAttributes;
+}
+
+TPS_PUBLIC char **get_user_attributes()
+{
+ return userAttributes;
+}
+
+TPS_PUBLIC char **get_view_user_attributes()
+{
+ return viewUserAttributes;
+}
+
+CERTCertificate **get_certificates(LDAPMessage *entry) {
+ int i;
+ struct berval **bvals;
+ CERTCertificate *cert;
+ int c = 0;
+ CERTCertificate **ret = NULL;
+
+ tus_check_conn();
+ bvals = ldap_get_values_len(ld, entry, "userCertificate");
+ if (bvals == NULL)
+ return NULL;
+
+ for (i = 0; bvals[i] != NULL; i++ )
+ c++;
+ ret = (CERTCertificate **) malloc ((sizeof (CERTCertificate *) * c) + 1);
+ c = 0;
+ for (i = 0; bvals[i] != NULL; i++ ) {
+ cert = CERT_DecodeCertFromPackage((char *) bvals[i]->bv_val, (int)
+ ( bvals[i]->bv_len ) );
+ ret[c] = cert;
+ c++;
+ }
+ ret[c] = NULL;
+ return ret;
+
+}
+
+struct berval **get_attribute_values(LDAPMessage *entry, const char *attribute)
+{
+ int i;
+ unsigned int j;
+ struct berval **bvals = NULL;
+ char buffer[2048];
+ int c = 0;
+ struct berval **ret = NULL;
+
+ tus_check_conn();
+ if (PL_strcasecmp(attribute, "userCertificate") == 0) {
+ bvals = ldap_get_values_len(ld, entry, attribute);
+ if (bvals == NULL)
+ return NULL;
+ for (i = 0; bvals[i] != NULL; i++ ) {
+ c++;
+ }
+ ret = (struct berval **) malloc ((sizeof (struct berval *) * c) + 1);
+ for (i=0; i< c; i++) {
+ ret[i] = (struct berval *) malloc(sizeof(struct berval));
+ }
+ ret[c] = NULL;
+ c = 0;
+ for (i = 0; bvals[i] != NULL; i++ ) {
+ char *tmp = BTOA_DataToAscii((unsigned char *)bvals[i]->bv_val,
+ (int)bvals[i]->bv_len);
+ snprintf(buffer, 2048, "%s", tmp);
+ PORT_Free(tmp);
+
+ /* remove \r\n that javascript does not like */
+ for (j = 0; j < strlen(buffer); j++) {
+ if (buffer[j] == '\r') {
+ buffer[j] = '.';
+ }
+ if (buffer[j] == '\n') {
+ buffer[j] = '.';
+ }
+ }
+ ret[c]->bv_val = PL_strdup(buffer);
+ ret[c]->bv_len = PL_strlen(buffer);
+ c++;
+ }
+ if (bvals != NULL) {
+ ldap_value_free_len(bvals);
+ bvals = NULL;
+ }
+
+ return ret;
+ } else {
+ return ldap_get_values_len(ld, entry, attribute);
+ }
+}
+
+void free_values(struct berval **values, int ldapValues)
+{
+ if (ldapValues != 0) {
+ if( values != NULL ) {
+ ldap_value_free_len( values );
+ values = NULL;
+ }
+ } else {
+ if( values != NULL ) {
+ PR_Free( values );
+ values = NULL;
+ }
+ }
+}
+
+TPS_PUBLIC char *get_token_users_name()
+{
+ return tokenAttributes[I_TOKEN_USER];
+}
+
+struct berval **get_token_users(LDAPMessage *entry)
+{
+ return ldap_get_values_len(ld, entry, TOKEN_USER);
+}
+
+char *get_token_id_name()
+{
+ return tokenAttributes[I_TOKEN_ID];
+}
+
+char *get_cert_attr_byname(LDAPMessage *entry, const char *name)
+{
+ struct berval **v = NULL;
+ char *value = NULL;
+
+ if (entry == NULL) return NULL;
+
+ v = ldap_get_values_len(ld, entry, name);
+ if (v == NULL) return NULL;
+ if ((valid_berval(v)) && (PL_strlen(v[0]->bv_val) > 0)) {
+ value = PL_strdup(v[0]->bv_val);
+ }
+ if( v != NULL ) {
+ ldap_value_free_len( v );
+ v = NULL;
+ }
+
+ return value;
+}
+
+int get_cert_attr_byname_int(LDAPMessage *entry, const char *name)
+{
+ struct berval **v = NULL;
+ int n = 0;
+
+ if (entry == NULL) return 0;
+
+ v = ldap_get_values_len(ld, entry, name);
+ if (v == NULL) return 0;
+ if ((valid_berval(v)) && (PL_strlen(v[0]->bv_val) > 0)) {
+ n = atoi(v[0]->bv_val);
+ }
+ if( v != NULL ) {
+ ldap_value_free_len( v );
+ v = NULL;
+ }
+
+ return n;
+}
+
+
+TPS_PUBLIC char *get_token_reason(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, "tokenReason");
+}
+
+char *get_token_id(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, TOKEN_ID);
+}
+
+char *get_cert_tokenType(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, "tokenType");
+}
+
+char *get_cert_serial(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, "tokenSerial");
+}
+
+char *get_cert_type(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, "tokenKeyType");
+}
+
+char *get_cert_status(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, "tokenStatus");
+}
+
+char *get_cert_issuer(LDAPMessage *entry) {
+ return get_cert_attr_byname(entry, "tokenIssuer");
+}
+
+char *get_cert_cn(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, "cn");
+}
+
+char *get_token_status_name()
+{
+ return tokenAttributes[I_TOKEN_STATUS];
+}
+
+TPS_PUBLIC char *get_reason_name()
+{
+ return tokenAttributes[I_TOKEN_REASON];
+}
+
+TPS_PUBLIC char *get_policy_name()
+{
+ return tokenAttributes[I_TOKEN_POLICY];
+}
+
+char *get_token_status(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, TOKEN_STATUS);
+}
+
+char *get_applet_id_name()
+{
+ return tokenAttributes[I_TOKEN_APPLET];
+}
+
+char *get_applet_id(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, TOKEN_APPLET);
+}
+
+char *get_key_info_name()
+{
+ return tokenAttributes[I_TOKEN_KEY_INFO];
+}
+
+char *get_key_info(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, TOKEN_KEY_INFO);
+}
+
+char *get_creation_date_name()
+{
+ return tokenAttributes[I_TOKEN_C_DATE];
+}
+
+char *get_creation_date(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, TOKEN_C_DATE);
+}
+
+char *get_modification_date_name()
+{
+ return tokenAttributes[I_TOKEN_M_DATE];
+}
+
+char *get_modification_date(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, TOKEN_M_DATE);
+}
+
+char *get_number_of_modifications_name()
+{
+ return tokenAttributes[I_TOKEN_MODS];
+}
+
+int get_number_of_modifications(LDAPMessage *entry)
+{
+ return get_cert_attr_byname_int(entry, TOKEN_MODS);
+}
+
+TPS_PUBLIC char *get_dn(LDAPMessage *entry)
+{
+ char *ret = NULL;
+ char *dn = NULL;
+ if ((dn = ldap_get_dn( ld, entry )) != NULL) {
+ ret = PL_strdup(dn);
+ ldap_memfree(dn);
+ }
+ return ret;
+}
+
+char *get_number_of_resets_name()
+{
+ return tokenAttributes[I_TOKEN_RESETS];
+}
+
+int get_number_of_resets(LDAPMessage *entry)
+{
+ return get_cert_attr_byname_int(entry, TOKEN_RESETS);
+}
+
+char *get_number_of_enrollments_name()
+{
+ return tokenAttributes[I_TOKEN_ENROLLMENTS];
+}
+
+int get_number_of_enrollments(LDAPMessage *entry)
+{
+ return get_cert_attr_byname_int(entry, TOKEN_ENROLLMENTS);
+}
+
+char *get_number_of_renewals_name()
+{
+ return tokenAttributes[I_TOKEN_RENEWALS];
+}
+
+int get_number_of_renewals(LDAPMessage *entry)
+{
+ return get_cert_attr_byname_int(entry, TOKEN_RENEWALS);
+}
+
+char *get_number_of_recoveries_name()
+{
+ return tokenAttributes[I_TOKEN_RECOVERIES];
+}
+
+int get_number_of_recoveries(LDAPMessage *entry)
+{
+ return get_cert_attr_byname_int(entry, TOKEN_RECOVERIES);
+}
+
+TPS_PUBLIC char *get_token_userid(char *cn)
+{
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ struct berval **v = NULL;
+ char *ret = NULL;
+ int rc = -1;
+
+ if (cn != NULL && PL_strlen(cn) > 0) {
+ if ((rc = find_tus_db_entry (cn, 0, &result)) == LDAP_SUCCESS) {
+ e = get_first_entry (result);
+ if (e != NULL) {
+ if ((v = ldap_get_values_len(ld, e, TOKEN_USER)) != NULL) {
+ if ((valid_berval(v)) && (PL_strlen(v[0]->bv_val) > 0)) {
+ ret = PL_strdup(v[0]->bv_val);
+ }
+ if( v != NULL ) {
+ ldap_value_free_len( v );
+ v = NULL;
+ }
+ }
+ }
+ if( result != NULL ) {
+ free_results( result );
+ result = NULL;
+ }
+ }
+ }
+ return ret;
+}
+
+TPS_PUBLIC char *get_token_policy(char *cn)
+{
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ struct berval **v = NULL;
+ char *ret = NULL;
+ int rc = -1;
+
+ if (cn != NULL && PL_strlen(cn) > 0) {
+ if ((rc = find_tus_db_entry(cn, 0, &result)) == LDAP_SUCCESS) {
+ e = get_first_entry (result);
+ if (e != NULL) {
+ if ((v = ldap_get_values_len(ld, e, TOKEN_POLICY)) != NULL) {
+ if ((valid_berval(v)) && (PL_strlen(v[0]->bv_val) > 0)) {
+ ret = PL_strdup(v[0]->bv_val);
+ }
+ if( v != NULL ) {
+ ldap_value_free_len( v );
+ v = NULL;
+ }
+ }
+ }
+ if( result != NULL ) {
+ free_results( result );
+ result = NULL;
+ }
+ }
+ }
+ return ret;
+}
+
+TPS_PUBLIC int allow_token_enroll_policy(char *cn, const char *policy)
+{
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ struct berval **v = NULL;
+ int can_reenroll = 0;
+ int token_is_uninitialized = 0;
+ int is_reenroll_attempt = 0;
+ int rc = -1;
+ char *token_status = NULL;
+
+ if(PL_strstr(policy,"RE_ENROLL"))
+ is_reenroll_attempt = 1;
+
+ if (cn != NULL && PL_strlen(cn) > 0) {
+ if ((rc = find_tus_db_entry (cn, 0, &result)) == LDAP_SUCCESS) {
+ e = get_first_entry (result);
+ if (e != NULL) {
+ if(is_reenroll_attempt) {
+ token_status = get_token_status(e);
+
+ if(token_status && PL_strcmp(token_status,STATE_UNINITIALIZED) == 0)
+ token_is_uninitialized = 1;
+
+ if(token_status) {
+ PR_Free(token_status);
+ token_status = NULL;
+ }
+ }
+
+ if ((v = ldap_get_values_len(ld, e, TOKEN_POLICY)) != NULL) {
+ if ((valid_berval(v)) && (PL_strlen(v[0]->bv_val) > 0)) {
+ if (PL_strstr(v[0]->bv_val, policy)) {
+ can_reenroll = 1;
+ } else {
+ if( is_reenroll_attempt && token_is_uninitialized) {
+ can_reenroll = 1;
+ }
+ }
+ }
+ if( v != NULL ) {
+ ldap_value_free_len( v );
+ v = NULL;
+ }
+ }
+ }
+ if( result != NULL ) {
+ free_results( result );
+ result = NULL;
+ }
+ }
+ }
+ return can_reenroll;
+}
+
+TPS_PUBLIC int allow_token_renew(char *cn)
+{
+ return allow_token_enroll_policy(cn, "RENEW=YES");
+}
+
+TPS_PUBLIC int allow_token_reenroll(char *cn)
+{
+ return allow_token_enroll_policy(cn, "RE_ENROLL=YES");
+}
+
+TPS_PUBLIC int force_token_format(char *cn)
+{
+ return allow_token_enroll_policy(cn,"FORCE_FORMAT=YES");
+}
+
+TPS_PUBLIC int is_token_present(char *cn)
+{
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ int present = 0;
+ int rc = -1;
+
+ if (cn != NULL && PL_strlen(cn) > 0) {
+ if ((rc = find_tus_db_entry (cn, 0, &result)) == LDAP_SUCCESS) {
+ e = get_first_entry (result);
+ if (e != NULL) {
+ present = 1;
+ }
+ if( result != NULL ) {
+ free_results( result );
+ result = NULL;
+ }
+ }
+ }
+ return present;
+}
+
+TPS_PUBLIC int is_token_pin_resetable(char *cn)
+{
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ struct berval **v = NULL;
+ int resetable = 1;
+ int rc = -1;
+
+ if (cn != NULL && PL_strlen(cn) > 0) {
+ if ((rc = find_tus_db_entry (cn, 0, &result)) == LDAP_SUCCESS) {
+ e = get_first_entry (result);
+ if (e != NULL) {
+ if ((v = ldap_get_values_len(ld, e, TOKEN_POLICY)) != NULL) {
+ if ((valid_berval(v)) && (PL_strlen(v[0]->bv_val) > 0)) {
+ if (PL_strstr(v[0]->bv_val, "PIN_RESET=NO")) {
+ resetable = 0;
+ }
+ }
+ if( v != NULL ) {
+ ldap_value_free_len( v );
+ v = NULL;
+ }
+ }
+ }
+ if( result != NULL ) {
+ free_results( result );
+ result = NULL;
+ }
+ }
+ }
+ return resetable;
+}
+
+TPS_PUBLIC int is_update_pin_resetable_policy(char *cn)
+{
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ struct berval **v = NULL;
+ int resetable = 0;
+ int rc = -1;
+
+ if (cn != NULL && PL_strlen(cn) > 0) {
+ if ((rc = find_tus_db_entry (cn, 0, &result)) == LDAP_SUCCESS) {
+ e = get_first_entry (result);
+ if (e != NULL) {
+ if ((v = ldap_get_values_len(ld, e, TOKEN_POLICY)) != NULL) {
+ if ((valid_berval(v)) && (PL_strlen(v[0]->bv_val) > 0)) {
+ if (PL_strstr(v[0]->bv_val, "RESET_PIN_RESET_TO_NO=YES")) {
+ resetable = 1;
+ }
+ }
+ if( v != NULL ) {
+ ldap_value_free_len( v );
+ v = NULL;
+ }
+ }
+ }
+ if( result != NULL ) {
+ free_results( result );
+ result = NULL;
+ }
+ }
+ }
+ return resetable;
+}
+
+TPS_PUBLIC int is_tus_db_entry_disabled(char *cn)
+{
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ struct berval **v = NULL;
+ int disabled = 0;
+ int rc = -1;
+
+ if (cn != NULL && PL_strlen(cn) > 0) {
+ if ((rc = find_tus_db_entry (cn, 0, &result)) == LDAP_SUCCESS) {
+ e = get_first_entry (result);
+ if (e != NULL) {
+ if ((v = ldap_get_values_len(ld, e, TOKEN_STATUS)) != NULL) {
+ if ((valid_berval(v)) && (PL_strlen(v[0]->bv_val) > 0)) {
+ if (!PL_strcasecmp(v[0]->bv_val, STATE_DISABLED)) {
+ disabled = 1;
+ }
+ }
+ if( v != NULL ) {
+ ldap_value_free_len( v );
+ v = NULL;
+ }
+ }
+ }
+ if( result != NULL ) {
+ free_results( result );
+ result = NULL;
+ }
+ }
+ }
+ return disabled;
+}
+
+TPS_PUBLIC LDAPMod **allocate_modifications(int size)
+{
+ int i, n;
+ LDAPMod **mods = NULL;
+ char *s;
+
+ n = ((size + 1) * sizeof(LDAPMod *)) + (size * sizeof(LDAPMod));
+ s = (char *) PR_Malloc(n);
+ if (s == NULL)
+ return NULL;
+ memset(s, 0, n);
+
+ mods = (LDAPMod **)s;
+
+ s += ((size + 1) * sizeof(LDAPMod *));
+
+ for (i = 0; i < size; i++) {
+ mods[i] = (LDAPMod *)s;
+ s += sizeof(LDAPMod);
+ }
+
+ return mods;
+}
+
+void free_modifications(LDAPMod **mods, int ldapValues)
+{
+ int i;
+
+ if( mods == NULL ) {
+ return;
+ }
+
+ if (ldapValues) {
+ ldap_mods_free(mods, 0);
+ return;
+ }
+
+ for (i = 0; mods[i] != NULL; i++) {
+ if ((mods[i]->mod_op & LDAP_MOD_BVALUES) &&
+ (mods[i]->mod_bvalues != NULL)) {
+ if( ( mods[i] != NULL ) && ( mods[i]->mod_bvalues != NULL ) ) {
+ PR_Free( mods[i]->mod_bvalues );
+ mods[i]->mod_bvalues = NULL;
+ }
+ } else if (mods[i]->mod_values != NULL) {
+ if( ( mods[i] != NULL ) && ( mods[i]->mod_values != NULL ) ) {
+ PR_Free( mods[i]->mod_values );
+ mods[i]->mod_values = NULL;
+ }
+ }
+ }
+ if( mods != NULL ) {
+ PR_Free( mods );
+ mods = NULL;
+ }
+}
+
+TPS_PUBLIC char **allocate_values(int size, int extra)
+{
+ int n;
+ char **values = NULL;
+ char *s;
+
+ n = (size + 1) * sizeof(char *);
+ if (extra > 0) {
+ n += extra * sizeof(char);
+ }
+ s = (char *) PR_Malloc(n);
+ if (s == NULL)
+ return NULL;
+ memset(s, 0, n);
+
+ values = (char **)s;
+
+ if (extra > 0) {
+ s += ((size + 1) * sizeof(char *));
+ values[0] = s;
+ }
+
+ return values;
+}
+
+TPS_PUBLIC char **create_modification_date_change()
+{
+ PRExplodedTime time;
+ PRTime now;
+ char **v = NULL;
+
+ if ((v = allocate_values(1, 16)) == NULL) {
+ return NULL;
+ }
+
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+
+ PR_snprintf(v[0], 16, "%04d%02d%02d%02d%02d%02dZ",
+ time.tm_year, (time.tm_month + 1), time.tm_mday,
+ time.tm_hour, time.tm_min, time.tm_sec);
+
+ return v;
+}
+
+/**
+ * Reads password.conf file
+ */
+static int ReadLine(PRFileDesc *f, char *buf, int buf_len, int *removed_return)
+{
+ char *cur = buf;
+ int sum = 0;
+ PRInt32 rc;
+
+ *removed_return = 0;
+ while (1) {
+ rc = PR_Read(f, cur, 1);
+ if (rc == -1 || rc == 0)
+ break;
+ if (*cur == '\r') {
+ continue;
+ }
+ if (*cur == '\n') {
+ *cur = '\0';
+ *removed_return = 1;
+ break;
+ }
+ sum++;
+ cur++;
+ }
+ return sum;
+}
+
+#define MAX_CFG_LINE_LEN 4096
+/*
+ * Search for password name "name" in the password file "filepath"
+ */
+char *get_pwd_from_conf(char *filepath, char *name)
+{
+ PRFileDesc *fd;
+ char line[MAX_CFG_LINE_LEN];
+ int removed_return;
+ char *val= NULL;
+
+ if (debug_fd)
+ PR_fprintf(debug_fd, "get_pwd_from_conf looking for %s\n", name);
+ fd= PR_Open(filepath, PR_RDONLY, 400);
+ if (fd == NULL) {
+ return NULL;
+ }
+ if (debug_fd)
+ PR_fprintf(debug_fd, "get_pwd_from_conf opened %s\n", filepath);
+
+ while (1) {
+ int n = ReadLine(fd, line, MAX_CFG_LINE_LEN, &removed_return);
+ if (n > 0) {
+ /* handle comment line */
+ if (line[0] == '#')
+ continue;
+ int c = 0;
+ while ((c < n) && (line[c] != ':')) {
+ c++;
+ }
+ if (c < n) {
+ line[c] = '\0';
+ } else {
+ continue; /* no ':', skip this line */
+ }
+ if (!PL_strcmp (line, name)) {
+ if (debug_fd)
+ PR_fprintf(debug_fd, "get_pwd_from_conf found %s is %s\n", line, &line[c+1]);
+ val = PL_strdup(&line[c+1]);
+ break;
+ }
+ } else if (n == 0 && removed_return == 1) {
+ continue; /* skip empty line */
+ } else {
+ break;
+ }
+ }
+ if( fd != NULL ) {
+ PR_Close( fd );
+ fd = NULL;
+ }
+ return val;
+
+}
+
+void audit_log(const char *func_name, const char *userid, const char *msg)
+{
+ const char* time_fmt = "%Y-%m-%d %H:%M:%S";
+ char datetime[1024];
+ PRTime now;
+ PRExplodedTime time;
+ PRThread *ct;
+
+ if (audit_fd == NULL)
+ return;
+
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+ ct = PR_GetCurrentThread();
+ PR_fprintf(audit_fd, "[%s] t=%x uid=%s op=%s - ",
+ datetime, ct, userid, func_name);
+ PR_fprintf(audit_fd, msg);
+ PR_fprintf(audit_fd, "\n");
+}
+
+int base64_decode( char *src, unsigned char *dst )
+{
+
+#define RIGHT2 0x03
+#define RIGHT4 0x0f
+
+ unsigned char b642nib[0x80] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
+ 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
+ 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
+ 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
+ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
+ 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
+ 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff
+ };
+ char *p, *stop;
+ unsigned char nib, *byte;
+ int i, len;
+
+ stop = strchr( src, '\0' );
+ byte = dst;
+ for ( p = src, len = 0; p < stop; p += 4, len += 3 ) {
+ for ( i = 0; i < 4; i++ ) {
+ if ( p[i] != '=' && (p[i] & 0x80 ||
+ b642nib[ p[i] & 0x7f ] > 0x3f) ) {
+ return( -1 );
+ }
+ }
+
+ /* first digit */
+ nib = b642nib[ p[0] & 0x7f ];
+ byte[0] = nib << 2;
+
+ /* second digit */
+ nib = b642nib[ p[1] & 0x7f ];
+ byte[0] |= nib >> 4;
+
+ /* third digit */
+ if ( p[2] == '=' ) {
+ len += 1;
+ break;
+ }
+ byte[1] = (nib & RIGHT4) << 4;
+ nib = b642nib[ p[2] & 0x7f ];
+ byte[1] |= nib >> 2;
+
+ /* fourth digit */
+ if ( p[3] == '=' ) {
+ len += 2;
+ break;
+ }
+ byte[2] = (nib & RIGHT2) << 6;
+ nib = b642nib[ p[3] & 0x7f ];
+ byte[2] |= nib;
+
+ byte += 3;
+ }
+
+ return( len );
+}
+
diff --git a/base/tps/stubs/modules/nss/mod_nss_stub.c b/base/tps/stubs/modules/nss/mod_nss_stub.c
new file mode 100644
index 000000000..b47fa0edb
--- /dev/null
+++ b/base/tps/stubs/modules/nss/mod_nss_stub.c
@@ -0,0 +1,51 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifdef XP_WIN32
+#define MOD_NSS_STUB_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define MOD_NSS_STUB_PUBLIC
+#endif /* !XP_WIN32 */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef XP_WIN32
+#include <unistd.h> /* sleep */
+#else /* XP_WIN32 */
+#include <windows.h>
+#endif /* XP_WIN32 */
+
+#include "httpd/httpd.h"
+#include "httpd/http_config.h"
+#include "httpd/http_log.h"
+#include "httpd/http_protocol.h"
+#include "httpd/http_main.h"
+#include "httpd/apr_strings.h"
+
+MOD_NSS_STUB_PUBLIC char *nss_var_lookup( apr_pool_t *p, server_rec *s,
+ conn_rec *c, request_rec *r,
+ char *var )
+{
+ return NULL;
+}
+
diff --git a/base/tps/tools/CMakeLists.txt b/base/tps/tools/CMakeLists.txt
new file mode 100644
index 000000000..6ed05c43d
--- /dev/null
+++ b/base/tps/tools/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(raclient)
diff --git a/base/tps/tools/raclient/CMakeLists.txt b/base/tps/tools/raclient/CMakeLists.txt
new file mode 100644
index 000000000..8f01b34d8
--- /dev/null
+++ b/base/tps/tools/raclient/CMakeLists.txt
@@ -0,0 +1,47 @@
+project(tpsclient CXX)
+
+set(TPS_PRIVATE_INCLUDE_DIRS
+ ${TPS_PUBLIC_INCLUDE_DIRS}
+ ${CMAKE_BINARY_DIR}
+ ${NSPR_INCLUDE_DIRS}
+ ${NSS_INCLUDE_DIRS}
+)
+
+set(TPS_EXECUTABLE
+ tpsclient
+ CACHE INTERNAL "tpsclient executable"
+)
+
+set(TPS_LINK_LIBRARIES
+ ${TPS_SHARED_LIBRARY}
+ ${NSPR_LIBRARIES}
+ ${NSS_LIBRARIES}
+)
+
+set(tpsclient_SRCS
+ RA_Client.cpp
+ RA_Conn.cpp
+ RA_Token.cpp
+)
+
+include_directories(${TPS_PRIVATE_INCLUDE_DIRS})
+
+add_executable(${TPS_EXECUTABLE} ${tpsclient_SRCS})
+target_link_libraries(${TPS_EXECUTABLE} ${TPS_LINK_LIBRARIES})
+
+install(
+ TARGETS
+ ${TPS_EXECUTABLE}
+ RUNTIME DESTINATION ${BIN_INSTALL_DIR}
+ LIBRARY DESTINATION ${LIB_INSTALL_DIR}/tps
+ ARCHIVE DESTINATION ${LIB_INSTALL_DIR}/tps
+)
+
+install(
+ FILES
+ enroll.tps
+ format.tps
+ reset_pin.tps
+ DESTINATION
+ ${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}/tps/samples
+)
diff --git a/base/tps/tools/raclient/RA_Client.cpp b/base/tps/tools/raclient/RA_Client.cpp
new file mode 100644
index 000000000..c2a610e33
--- /dev/null
+++ b/base/tps/tools/raclient/RA_Client.cpp
@@ -0,0 +1,1645 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include "prinrval.h"
+
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+#include "prprf.h"
+#include "pk11func.h"
+
+#include "main/NameValueSet.h"
+#include "main/Util.h"
+#include "main/RA_Msg.h"
+#include "authentication/AuthParams.h"
+#include "apdu/APDU_Response.h"
+#include "apdu/Initialize_Update_APDU.h"
+#include "apdu/External_Authenticate_APDU.h"
+#include "apdu/Set_Pin_APDU.h"
+#include "msg/RA_Begin_Op_Msg.h"
+#include "msg/RA_End_Op_Msg.h"
+#include "msg/RA_Login_Request_Msg.h"
+#include "msg/RA_Login_Response_Msg.h"
+#include "msg/RA_Extended_Login_Request_Msg.h"
+#include "msg/RA_Extended_Login_Response_Msg.h"
+#include "msg/RA_Token_PDU_Request_Msg.h"
+#include "msg/RA_Token_PDU_Response_Msg.h"
+#include "msg/RA_New_Pin_Request_Msg.h"
+#include "msg/RA_New_Pin_Response_Msg.h"
+#include "msg/RA_SecureId_Request_Msg.h"
+#include "msg/RA_SecureId_Response_Msg.h"
+#include "msg/RA_ASQ_Request_Msg.h"
+#include "msg/RA_ASQ_Response_Msg.h"
+#include "msg/RA_Status_Update_Request_Msg.h"
+#include "msg/RA_Status_Update_Response_Msg.h"
+#include "RA_Token.h"
+#include "RA_Client.h"
+
+#include "nss.h"
+
+static PRFileDesc *m_fd_debug = (PRFileDesc *) NULL;
+PRBool old_style = PR_TRUE;
+
+/**
+ * Constructs a RA client that talks to RA.
+ */
+RA_Client::RA_Client ()
+{
+ /* default global variables */
+ m_vars.Add ("ra_host", "air");
+ m_vars.Add ("ra_port", "8000");
+ m_vars.Add ("ra_uri", "/nk_service");
+}
+
+/**
+ * Destructs this RA client.
+ */
+RA_Client::~RA_Client ()
+{
+ if (m_fd_debug != NULL)
+ {
+ PR_Close (m_fd_debug);
+ m_fd_debug = NULL;
+ }
+}
+
+static void
+PrintHeader ()
+{
+ printf ("Registration Authority Client\n");
+ printf ("'op=help' for Help\n");
+}
+
+static void
+Output (const char *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ printf ("Output> ");
+ vprintf (fmt, ap);
+ printf ("\n");
+ va_end (ap);
+}
+
+static void
+PrintPrompt ()
+{
+ printf ("Command>");
+}
+
+static void
+OutputSuccess (const char *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ printf ("Result> Success - ");
+ vprintf (fmt, ap);
+ printf ("\n");
+ va_end (ap);
+}
+
+static void
+OutputError (const char *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ printf ("Result> Error - ");
+ vprintf (fmt, ap);
+ printf ("\n");
+ va_end (ap);
+}
+
+static int
+ReadLine (char *buf, int len)
+{
+ char *cur = buf;
+
+ while (1)
+ {
+ *cur = getchar ();
+ if (*cur == '\r')
+ {
+ continue;
+ }
+ if (*cur == '\n')
+ {
+ *cur = '\0';
+ return 1;
+ }
+ cur++;
+ }
+ return 0;
+}
+
+void
+RA_Client::Debug (const char *func_name, const char *fmt, ...)
+{
+ PRTime now;
+ const char *time_fmt = "%Y-%m-%d %H:%M:%S";
+ char datetime[1024];
+ PRExplodedTime time;
+
+ if (m_fd_debug == NULL)
+ return;
+ va_list ap;
+ va_start (ap, fmt);
+ now = PR_Now ();
+ PR_ExplodeTime (now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish (datetime, 1024, time_fmt, &time);
+ PR_fprintf (m_fd_debug, "[%s] %s - ", datetime, func_name);
+ PR_vfprintf (m_fd_debug, fmt, ap);
+ va_end (ap);
+ PR_Write (m_fd_debug, "\n", 1);
+}
+
+int
+RA_Client::OpHelp (NameValueSet * params)
+{
+ Output ("Available Operations:");
+ Output ("op=debug filename=<filename> - enable debugging");
+ Output ("op=help");
+ Output
+ ("op=ra_enroll uid=<uid> pwd=<pwd> num_threads=<number of threads> secureid_pin=<secureid_pin> keygen=<true|false> - Enrollment Via RA");
+ Output
+ ("op=ra_reset_pin uid=<uid> pwd=<pwd> num_threads=<number of threads> secureid_pin=<secureid_pin> new_pin=<new_pin> - Reset Pin Via RA");
+ Output
+ ("op=ra_update uid=<uid> pwd=<pwd> num_threads=<number of threads> secureid_pin=<secureid_pin> new_pin=<new_pin> - Reset Pin Via RA");
+ Output ("op=token_set <name>=<value> - Set Token Value");
+ Output ("op=token_status - Print Token Status");
+ Output ("op=var_get name=<name> - Get Value of Variable");
+ Output ("op=var_list - List All Variables");
+ Output ("op=var_set name=<name> value=<value> - Set Value to Variable");
+
+ return 1;
+}
+
+static void
+GetBuffer (Buffer & buf, char *output, int len)
+{
+ int i;
+
+ output[0] = '\0';
+ for (i = 0; i < (int) buf.size (); ++i)
+ {
+ sprintf (output, "%s%02x", output, ((BYTE *) buf)[i]);
+ }
+}
+
+static BYTE
+ToVal (char c)
+{
+ if (c >= '0' && c <= '9')
+ {
+ return c - '0';
+ }
+ else if (c >= 'A' && c <= 'Z')
+ {
+ return c - 'A' + 10;
+ }
+ else if (c >= 'a' && c <= 'z')
+ {
+ return c - 'a' + 10;
+ }
+
+ /* The following return is needed to suppress compiler warnings on Linux. */
+ return 0;
+}
+
+static Buffer *
+ToBuffer (char *input)
+{
+ int len = strlen (input) / 2;
+ BYTE *buffer = NULL;
+
+ buffer = (BYTE *) malloc (len);
+ if (buffer == NULL)
+ {
+ return NULL;
+ }
+
+ for (int i = 0; i < len; i++)
+ {
+ buffer[i] = (ToVal (input[i * 2]) * 16) + ToVal (input[i * 2 + 1]);
+ }
+ Buffer *j;
+ j = new Buffer (buffer, len);
+
+ if (buffer != NULL)
+ {
+ free (buffer);
+ buffer = NULL;
+ }
+
+ return j;
+}
+
+int
+RA_Client::OpTokenStatus (NameValueSet * params)
+{
+ int i;
+ char output[2048];
+
+ Output ("life_cycle_state : '%x'", m_token.GetLifeCycleState ());
+ Output ("pin : '%s'", m_token.GetPIN ());
+ GetBuffer (m_token.GetAppletVersion (), output, 2048);
+ Output ("app_ver : '%s' (%d bytes)", output,
+ m_token.GetAppletVersion ().size ());
+ Output ("major_ver : '%x'", m_token.GetMajorVersion ());
+ Output ("minor_ver : '%x'", m_token.GetMinorVersion ());
+ GetBuffer (m_token.GetCUID (), output, 2048);
+ Output ("cuid : '%s' (%d bytes)", output, m_token.GetCUID ().size ());
+ GetBuffer (m_token.GetMSN (), output, 2048);
+ Output ("msn : '%s' (%d bytes)", output, m_token.GetMSN ().size ());
+ GetBuffer (m_token.GetKeyInfo (), output, 2048);
+ Output ("key_info : '%s' (%d bytes)", output,
+ m_token.GetKeyInfo ().size ());
+ GetBuffer (m_token.GetAuthKey (), output, 2048);
+ Output ("auth_key : '%s' (%d bytes)", output,
+ m_token.GetAuthKey ().size ());
+ GetBuffer (m_token.GetMacKey (), output, 2048);
+ Output ("mac_key : '%s' (%d bytes)", output, m_token.GetMacKey ().size ());
+ GetBuffer (m_token.GetKekKey (), output, 2048);
+ Output ("kek_key : '%s' (%d bytes)", output, m_token.GetKekKey ().size ());
+
+ /* print all the public/private keys */
+ if (params->GetValue ("print_cert") != NULL)
+ {
+ for (i = 0; i < m_token.NoOfCertificates (); i++)
+ {
+ CERTCertificate *cert = m_token.GetCertificate (i);
+ Output ("Certificate #%d: '%s'", i, cert->nickname);
+ }
+ }
+
+ if (params->GetValue ("print_private") != NULL)
+ {
+ for (i = 0; i < m_token.NoOfPrivateKeys (); i++)
+ {
+ SECKEYPrivateKey *key = m_token.GetPrivateKey (i);
+#if 0
+ SECKEYPublicKey *pubKey = SECKEY_ConvertToPublicKey (key);
+ Buffer modulus = Buffer (pubKey->u.rsa.modulus.data,
+ pubKey->u.rsa.modulus.len);
+ Buffer exponent = Buffer (pubKey->u.rsa.publicExponent.data,
+ pubKey->u.rsa.publicExponent.len);
+#endif
+ Output ("Private Key #%d: '%s'", i,
+ PK11_GetPrivateKeyNickname (key));
+ }
+ }
+
+ return 1;
+}
+
+int
+RA_Client::OpTokenSet (NameValueSet * params)
+{
+ if (params->GetValue ("cuid") != NULL)
+ {
+ Buffer *CUID = ToBuffer (params->GetValue ("cuid"));
+ m_token.SetCUID (*CUID);
+ if (CUID != NULL)
+ {
+ delete CUID;
+ CUID = NULL;
+ }
+ }
+ if (params->GetValue ("msn") != NULL)
+ {
+ Buffer *MSN = ToBuffer (params->GetValue ("msn"));
+ m_token.SetMSN (*MSN);
+ if (MSN != NULL)
+ {
+ delete MSN;
+ MSN = NULL;
+ }
+ }
+ if (params->GetValue ("app_ver") != NULL)
+ {
+ Buffer *Version = ToBuffer (params->GetValue ("app_ver"));
+ m_token.SetAppletVersion (*Version);
+ if (Version != NULL)
+ {
+ delete Version;
+ Version = NULL;
+ }
+ }
+ if (params->GetValue ("major_ver") != NULL)
+ {
+ m_token.SetMajorVersion (atoi (params->GetValue ("major_ver")));
+ }
+ if (params->GetValue ("minor_ver") != NULL)
+ {
+ m_token.SetMinorVersion (atoi (params->GetValue ("minor_ver")));
+ }
+ if (params->GetValue ("key_info") != NULL)
+ {
+ Buffer *KeyInfo = ToBuffer (params->GetValue ("key_info"));
+ m_token.SetKeyInfo (*KeyInfo);
+ if (KeyInfo != NULL)
+ {
+ delete KeyInfo;
+ KeyInfo = NULL;
+ }
+ }
+ if (params->GetValue ("auth_key") != NULL)
+ {
+ Buffer *Key = ToBuffer (params->GetValue ("auth_key"));
+ m_token.SetAuthKey (*Key);
+ if (Key != NULL)
+ {
+ delete Key;
+ Key = NULL;
+ }
+ }
+ if (params->GetValue ("mac_key") != NULL)
+ {
+ Buffer *Key = ToBuffer (params->GetValue ("mac_key"));
+ m_token.SetMacKey (*Key);
+ if (Key != NULL)
+ {
+ delete Key;
+ Key = NULL;
+ }
+ }
+ if (params->GetValue ("kek_key") != NULL)
+ {
+ Buffer *Key = ToBuffer (params->GetValue ("kek_key"));
+ m_token.SetKekKey (*Key);
+ if (Key != NULL)
+ {
+ delete Key;
+ Key = NULL;
+ }
+ }
+ return 1;
+}
+
+static int
+HandleStatusUpdateRequest (RA_Client * client,
+ RA_Status_Update_Request_Msg * req,
+ RA_Token * token, RA_Conn * conn,
+ NameValueSet * vars, NameValueSet * params)
+{
+ client->Debug ("RA_Client::HandleStatusUpdateRequest",
+ "RA_Client::HandleStatusUpdateRequest");
+ RA_Status_Update_Response_Msg resp =
+ RA_Status_Update_Response_Msg (req->GetStatus ());
+ conn->SendMsg (&resp);
+ return 1;
+}
+
+static int
+HandleExtendedLoginRequest (RA_Client * client,
+ RA_Extended_Login_Request_Msg * req,
+ RA_Token * token, RA_Conn * conn,
+ NameValueSet * vars, NameValueSet * params)
+{
+ client->Debug ("RA_Client::HandleExtendLoginRequest",
+ "RA_Client::HandleExtendedLoginRequest");
+ AuthParams *auths = new AuthParams;
+ auths->SetUID (params->GetValue ("uid"));
+ auths->SetPassword (params->GetValue ("pwd"));
+ if (vars->GetValueAsBool ("test_enable", 0) == 1)
+ {
+ if (vars->GetValueAsBool ("test_el_resp_exclude_uid", 0) == 1)
+ {
+ auths->Remove ("UID");
+ }
+ if (vars->GetValueAsBool ("test_el_resp_exclude_pwd", 0) == 1)
+ {
+ auths->Remove ("PASSWORD");
+ }
+ if (vars->GetValueAsBool ("test_el_resp_include_invalid_param", 0) == 1)
+ {
+ auths->Add ("XXX", "YYY");
+ }
+ }
+ RA_Extended_Login_Response_Msg resp =
+ RA_Extended_Login_Response_Msg (auths);
+ conn->SendMsg (&resp);
+ return 1;
+}
+
+static int
+HandleLoginRequest (RA_Client * client,
+ RA_Login_Request_Msg * req,
+ RA_Token * token, RA_Conn * conn,
+ NameValueSet * vars, NameValueSet * params)
+{
+ client->Debug ("RA_Client::HandleLoginRequest",
+ "RA_Client::HandleLoginRequest");
+ RA_Login_Response_Msg resp =
+ RA_Login_Response_Msg (params->GetValue ("uid"),
+ params->GetValue ("pwd"));
+ conn->SendMsg (&resp);
+ return 1;
+}
+
+static int
+HandleNewPinRequest (RA_Client * client,
+ RA_New_Pin_Request_Msg * req,
+ RA_Token * token, RA_Conn * conn,
+ NameValueSet * vars, NameValueSet * params)
+{
+ client->Debug ("RA_Client::HandleNewPinRequest",
+ "RA_Client::HandleNewPinRequest");
+ int min_len = req->GetMinLen ();
+ int max_len = req->GetMaxLen ();
+ Output ("Min Len: '%d' Max Len: '%d'", min_len, max_len);
+ RA_New_Pin_Response_Msg resp =
+ RA_New_Pin_Response_Msg (params->GetValue ("new_pin"));
+ conn->SendMsg (&resp);
+
+ return 1;
+}
+
+static int
+HandleASQRequest (RA_Client * client,
+ RA_ASQ_Request_Msg * req,
+ RA_Token * token, RA_Conn * conn,
+ NameValueSet * vars, NameValueSet * params)
+{
+ client->Debug ("RA_Client::HandleASQRequest",
+ "RA_Client::HandleASQRequest");
+ Output ("ASQ Question: '%s'", req->GetQuestion ());
+ RA_ASQ_Response_Msg resp =
+ RA_ASQ_Response_Msg (params->GetValue ("answer"));
+ conn->SendMsg (&resp);
+
+ return 1;
+}
+
+static int
+HandleSecureIdRequest (RA_Client * client,
+ RA_SecureId_Request_Msg * req,
+ RA_Token * token, RA_Conn * conn,
+ NameValueSet * vars, NameValueSet * params)
+{
+ client->Debug ("RA_Client::HandleSecureIdRequest",
+ "RA_Client::HandleSecureIdRequest");
+ int pin_required = req->IsPinRequired ();
+ int next_value = req->IsNextValue ();
+ Output ("Pin Required: '%d' Next Value: '%d'", pin_required, next_value);
+ RA_SecureId_Response_Msg resp =
+ RA_SecureId_Response_Msg (params->GetValue ("secureid_value"),
+ params->GetValue ("secureid_pin"));
+ conn->SendMsg (&resp);
+ return 1;
+}
+
+static int
+HandleTokenPDURequest (RA_Client * client,
+ RA_Token_PDU_Request_Msg * req,
+ RA_Token * token, RA_Conn * conn,
+ NameValueSet * vars, NameValueSet * params)
+{
+ client->Debug ("RA_Client::HandleTokenPDURequest",
+ "RA_Client::HandleTokenPDURequest");
+ APDU *apdu = req->GetAPDU ();
+ APDU_Response *apdu_resp = token->Process (apdu, vars, params);
+ if (apdu_resp == NULL)
+ {
+ return 0;
+ }
+ RA_Token_PDU_Response_Msg *resp = new RA_Token_PDU_Response_Msg (apdu_resp);
+ conn->SendMsg (resp);
+
+ if (resp != NULL)
+ {
+ delete resp;
+ resp = NULL;
+ }
+ // if( apdu_resp != NULL ) {
+ // delete apdu_resp;
+ // apdu_resp = NULL;
+ // }
+
+ return 1;
+}
+
+
+typedef struct _ThreadArg
+{
+ PRTime time; /* processing time */
+ int status; /* status result */
+ NameValueSet *params; /* parameters */
+ RA_Client *client; /* client */
+ RA_Token *token; /* token */
+
+ PRLock *donelock; /* lock */
+ int done; /* are we done? */
+} ThreadArg;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ static void ThreadConnUpdate (void *arg)
+ {
+ PRTime start, end;
+ ThreadArg *targ = (ThreadArg *) arg;
+
+ start = PR_Now ();
+ RA_Conn conn (targ->client->m_vars.GetValue ("ra_host"),
+ atoi (targ->client->m_vars.GetValue ("ra_port")),
+ targ->client->m_vars.GetValue ("ra_uri"));
+
+ if (!conn.Connect ())
+ {
+ OutputError ("Cannot connect to %s:%d",
+ targ->client->m_vars.GetValue ("ra_host"),
+ atoi (targ->client->m_vars.GetValue ("ra_port")));
+ targ->status = 0;
+ if (!old_style)
+ {
+ PR_Lock (targ->donelock);
+ targ->done = PR_TRUE;
+ PR_Unlock (targ->donelock);
+ }
+
+ return;
+ }
+
+ NameValueSet *exts = NULL;
+ char *extensions =
+ targ->params->GetValueAsString ((char *) "extensions", NULL);
+ if (extensions != NULL)
+ {
+ exts = NameValueSet::Parse (extensions, "&");
+ }
+
+ RA_Begin_Op_Msg beginOp = RA_Begin_Op_Msg (OP_FORMAT, exts);
+ conn.SendMsg (&beginOp);
+
+ /* handle secure ID (optional) */
+ while (1)
+ {
+ RA_Msg *msg = (RA_Msg *) conn.ReadMsg (targ->token);
+ if (msg == NULL)
+ break;
+ if (msg->GetType () == MSG_LOGIN_REQUEST)
+ {
+ targ->status =
+ HandleLoginRequest (targ->client, (RA_Login_Request_Msg *) msg,
+ targ->token, &conn, &targ->client->m_vars,
+ targ->params);
+ }
+ else if (msg->GetType () == MSG_EXTENDED_LOGIN_REQUEST)
+ {
+ targ->status =
+ HandleExtendedLoginRequest (targ->client,
+ (RA_Extended_Login_Request_Msg *)
+ msg, targ->token, &conn,
+ &targ->client->m_vars,
+ targ->params);
+ }
+ else if (msg->GetType () == MSG_STATUS_UPDATE_REQUEST)
+ {
+ targ->status =
+ HandleStatusUpdateRequest (targ->client,
+ (RA_Status_Update_Request_Msg *) msg,
+ targ->token, &conn,
+ &targ->client->m_vars, targ->params);
+ }
+ else if (msg->GetType () == MSG_SECUREID_REQUEST)
+ {
+ targ->status =
+ HandleSecureIdRequest (targ->client,
+ (RA_SecureId_Request_Msg *) msg,
+ targ->token, &conn,
+ &targ->client->m_vars, targ->params);
+ }
+ else if (msg->GetType () == MSG_ASQ_REQUEST)
+ {
+ targ->status =
+ HandleASQRequest (targ->client, (RA_ASQ_Request_Msg *) msg,
+ targ->token, &conn, &targ->client->m_vars,
+ targ->params);
+ }
+ else if (msg->GetType () == MSG_TOKEN_PDU_REQUEST)
+ {
+ targ->status =
+ HandleTokenPDURequest (targ->client,
+ (RA_Token_PDU_Request_Msg *) msg,
+ targ->token, &conn,
+ &targ->client->m_vars, targ->params);
+ }
+ else if (msg->GetType () == MSG_NEW_PIN_REQUEST)
+ {
+ targ->status =
+ HandleNewPinRequest (targ->client,
+ (RA_New_Pin_Request_Msg *) msg,
+ targ->token, &conn, &targ->client->m_vars,
+ targ->params);
+ }
+ else if (msg->GetType () == MSG_END_OP)
+ {
+ RA_End_Op_Msg *endOp = (RA_End_Op_Msg *) msg;
+ if (endOp->GetResult () == 0)
+ {
+ targ->status = 1; /* error */
+ }
+ else
+ {
+ targ->status = 0;
+ }
+ if (msg != NULL)
+ {
+ delete msg;
+ msg = NULL;
+ }
+ break;
+ }
+ else
+ {
+ /* error */
+ targ->status = 0;
+ }
+ if (msg != NULL)
+ {
+ delete msg;
+ msg = NULL;
+ }
+
+ if (targ->status == 0)
+ break;
+ }
+
+ conn.Close ();
+ end = PR_Now ();
+ targ->time = (end - start) / 1000;
+
+ if (!old_style)
+ {
+ PR_Lock (targ->donelock);
+ targ->done = PR_TRUE;
+ PR_Unlock (targ->donelock);
+ }
+ }
+
+ static void ThreadConnResetPin (void *arg)
+ {
+ PRTime start, end;
+ ThreadArg *targ = (ThreadArg *) arg;
+
+ start = PR_Now ();
+ RA_Conn conn (targ->client->m_vars.GetValue ("ra_host"),
+ atoi (targ->client->m_vars.GetValue ("ra_port")),
+ targ->client->m_vars.GetValue ("ra_uri"));
+
+ if (!conn.Connect ())
+ {
+ OutputError ("Cannot connect to %s:%d",
+ targ->client->m_vars.GetValue ("ra_host"),
+ atoi (targ->client->m_vars.GetValue ("ra_port")));
+ targ->status = 0;
+
+ if (!old_style)
+ {
+ PR_Lock (targ->donelock);
+ targ->done = PR_TRUE;
+ PR_Unlock (targ->donelock);
+ }
+
+ return;
+ }
+
+ NameValueSet *exts = NULL;
+ char *extensions =
+ targ->params->GetValueAsString ((char *) "extensions", NULL);
+ if (extensions != NULL)
+ {
+ exts = NameValueSet::Parse (extensions, "&");
+ }
+
+ RA_Begin_Op_Msg beginOp = RA_Begin_Op_Msg (OP_RESET_PIN, exts);
+ conn.SendMsg (&beginOp);
+
+ /* handle secure ID (optional) */
+ while (1)
+ {
+ RA_Msg *msg = (RA_Msg *) conn.ReadMsg (targ->token);
+ if (msg == NULL)
+ break;
+ if (msg->GetType () == MSG_LOGIN_REQUEST)
+ {
+ targ->status =
+ HandleLoginRequest (targ->client, (RA_Login_Request_Msg *) msg,
+ targ->token, &conn, &targ->client->m_vars,
+ targ->params);
+ }
+ else if (msg->GetType () == MSG_EXTENDED_LOGIN_REQUEST)
+ {
+ targ->status =
+ HandleExtendedLoginRequest (targ->client,
+ (RA_Extended_Login_Request_Msg *)
+ msg, targ->token, &conn,
+ &targ->client->m_vars,
+ targ->params);
+ }
+ else if (msg->GetType () == MSG_STATUS_UPDATE_REQUEST)
+ {
+ targ->status =
+ HandleStatusUpdateRequest (targ->client,
+ (RA_Status_Update_Request_Msg *) msg,
+ targ->token, &conn,
+ &targ->client->m_vars, targ->params);
+ }
+ else if (msg->GetType () == MSG_SECUREID_REQUEST)
+ {
+ targ->status =
+ HandleSecureIdRequest (targ->client,
+ (RA_SecureId_Request_Msg *) msg,
+ targ->token, &conn,
+ &targ->client->m_vars, targ->params);
+ }
+ else if (msg->GetType () == MSG_ASQ_REQUEST)
+ {
+ targ->status =
+ HandleASQRequest (targ->client, (RA_ASQ_Request_Msg *) msg,
+ targ->token, &conn, &targ->client->m_vars,
+ targ->params);
+ }
+ else if (msg->GetType () == MSG_TOKEN_PDU_REQUEST)
+ {
+ targ->status =
+ HandleTokenPDURequest (targ->client,
+ (RA_Token_PDU_Request_Msg *) msg,
+ targ->token, &conn,
+ &targ->client->m_vars, targ->params);
+ }
+ else if (msg->GetType () == MSG_NEW_PIN_REQUEST)
+ {
+ targ->status =
+ HandleNewPinRequest (targ->client,
+ (RA_New_Pin_Request_Msg *) msg,
+ targ->token, &conn, &targ->client->m_vars,
+ targ->params);
+ }
+ else if (msg->GetType () == MSG_END_OP)
+ {
+ RA_End_Op_Msg *endOp = (RA_End_Op_Msg *) msg;
+ if (endOp->GetResult () == 0)
+ {
+ targ->status = 1; /* error */
+ }
+ else
+ {
+ targ->status = 0;
+ }
+ if (msg != NULL)
+ {
+ delete msg;
+ msg = NULL;
+ }
+ break;
+ }
+ else
+ {
+ /* error */
+ targ->status = 0;
+ }
+ if (msg != NULL)
+ {
+ delete msg;
+ msg = NULL;
+ }
+
+ if (targ->status == 0)
+ break;
+ }
+
+ conn.Close ();
+ end = PR_Now ();
+ targ->time = (end - start) / 1000;
+
+ if (!old_style)
+ {
+ PR_Lock (targ->donelock);
+ targ->done = PR_TRUE;
+ PR_Unlock (targ->donelock);
+ }
+ }
+
+#ifdef __cplusplus
+}
+#endif
+
+int
+RA_Client::OpConnUpdate (NameValueSet * params)
+{
+ int num_threads = params->GetValueAsInt ((char *) "num_threads", 1);
+ int i;
+ int status = 0;
+ PRThread **threads;
+ ThreadArg *arg;
+
+ threads = (PRThread **) malloc (sizeof (PRThread *) * num_threads);
+ if (threads == NULL)
+ {
+ return 0;
+ }
+ arg = (ThreadArg *) malloc (sizeof (ThreadArg) * num_threads);
+ if (arg == NULL)
+ {
+ return 0;
+ }
+
+ /* start threads */
+ for (i = 0; i < num_threads; i++)
+ {
+ arg[i].time = 0;
+ arg[i].status = 0;
+ arg[i].client = this;
+ if (i == 0)
+ {
+ arg[i].token = &this->m_token;
+ }
+ else
+ {
+ arg[i].token = this->m_token.Clone ();
+ }
+ arg[i].params = params;
+ threads[i] = PR_CreateThread (PR_USER_THREAD, ThreadConnUpdate, &arg[i], PR_PRIORITY_NORMAL, /* Priority */
+ PR_GLOBAL_THREAD, /* Scope */
+ PR_JOINABLE_THREAD, /* State */
+ 0 /* Stack Size */
+ );
+ }
+
+ /* join threads */
+ for (i = 0; i < num_threads; i++)
+ {
+ PR_JoinThread (threads[i]);
+ }
+
+ for (i = 0; i < num_threads; i++)
+ {
+ Output ("Thread (%d) status='%d' time='%d msec'", i,
+ arg[i].status, arg[i].time);
+ }
+
+ status = arg[0].status;
+
+ return status;
+}
+
+int
+RA_Client::OpConnResetPin (NameValueSet * params)
+{
+ int num_threads = params->GetValueAsInt ((char *) "num_threads", 1);
+ int i;
+ int status = 0;
+ PRThread **threads;
+ ThreadArg *arg;
+
+ threads = (PRThread **) malloc (sizeof (PRThread *) * num_threads);
+ if (threads == NULL)
+ {
+ return 0;
+ }
+ arg = (ThreadArg *) malloc (sizeof (ThreadArg) * num_threads);
+ if (arg == NULL)
+ {
+ return 0;
+ }
+
+ /* start threads */
+ for (i = 0; i < num_threads; i++)
+ {
+ arg[i].time = 0;
+ arg[i].status = 0;
+ arg[i].client = this;
+ if (i == 0)
+ {
+ arg[i].token = &this->m_token;
+ }
+ else
+ {
+ arg[i].token = this->m_token.Clone ();
+ }
+ arg[i].params = params;
+ threads[i] = PR_CreateThread (PR_USER_THREAD, ThreadConnResetPin, &arg[i], PR_PRIORITY_NORMAL, /* Priority */
+ PR_GLOBAL_THREAD, /* Scope */
+ PR_JOINABLE_THREAD, /* State */
+ 0 /* Stack Size */
+ );
+ }
+
+ /* join threads */
+ for (i = 0; i < num_threads; i++)
+ {
+ PR_JoinThread (threads[i]);
+ }
+
+ for (i = 0; i < num_threads; i++)
+ {
+ Output ("Thread (%d) status='%d' time='%d msec'", i,
+ arg[i].status, arg[i].time);
+ }
+
+ status = arg[0].status;
+
+ return status;
+}
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ static void ThreadConnEnroll (void *arg)
+ {
+ PRTime start, end;
+ ThreadArg *targ = (ThreadArg *) arg;
+
+ start = PR_Now ();
+ RA_Conn conn (targ->client->m_vars.GetValue ("ra_host"),
+ atoi (targ->client->m_vars.GetValue ("ra_port")),
+ targ->client->m_vars.GetValue ("ra_uri"));
+
+ if (!conn.Connect ())
+ {
+ OutputError ("Cannot connect to %s:%d",
+ targ->client->m_vars.GetValue ("ra_host"),
+ atoi (targ->client->m_vars.GetValue ("ra_port")));
+ targ->status = 0;
+
+ if (!old_style)
+ {
+ PR_Lock (targ->donelock);
+ targ->done = PR_TRUE;
+ PR_Unlock (targ->donelock);
+ }
+
+ return;
+ }
+
+ NameValueSet *exts = NULL;
+ char *extensions =
+ targ->params->GetValueAsString ((char *) "extensions", NULL);
+ if (extensions != NULL)
+ {
+ exts = NameValueSet::Parse (extensions, "&");
+ }
+
+ RA_Begin_Op_Msg beginOp = RA_Begin_Op_Msg (OP_ENROLL, exts);
+ conn.SendMsg (&beginOp);
+
+ /* handle secure ID (optional) */
+ while (1)
+ {
+ RA_Msg *msg = (RA_Msg *) conn.ReadMsg (targ->token);
+ if (msg == NULL)
+ break;
+ if (msg->GetType () == MSG_LOGIN_REQUEST)
+ {
+ targ->status = HandleLoginRequest (targ->client,
+ (RA_Login_Request_Msg *) msg,
+ targ->token, &conn,
+ &targ->client->m_vars,
+ targ->params);
+ }
+ else if (msg->GetType () == MSG_EXTENDED_LOGIN_REQUEST)
+ {
+ targ->status = HandleExtendedLoginRequest (targ->client,
+ (RA_Extended_Login_Request_Msg
+ *) msg, targ->token,
+ &conn,
+ &targ->client->m_vars,
+ targ->params);
+ }
+ else if (msg->GetType () == MSG_STATUS_UPDATE_REQUEST)
+ {
+ targ->status =
+ HandleStatusUpdateRequest (targ->client,
+ (RA_Status_Update_Request_Msg *) msg,
+ targ->token, &conn,
+ &targ->client->m_vars, targ->params);
+ }
+ else if (msg->GetType () == MSG_SECUREID_REQUEST)
+ {
+ targ->status = HandleSecureIdRequest (targ->client,
+ (RA_SecureId_Request_Msg *)
+ msg, targ->token, &conn,
+ &targ->client->m_vars,
+ targ->params);
+ }
+ else if (msg->GetType () == MSG_ASQ_REQUEST)
+ {
+ targ->status = HandleASQRequest (targ->client,
+ (RA_ASQ_Request_Msg *) msg,
+ targ->token, &conn,
+ &targ->client->m_vars,
+ targ->params);
+ }
+ else if (msg->GetType () == MSG_TOKEN_PDU_REQUEST)
+ {
+ targ->status = HandleTokenPDURequest (targ->client,
+ (RA_Token_PDU_Request_Msg *)
+ msg, targ->token, &conn,
+ &targ->client->m_vars,
+ targ->params);
+ targ->status = 1;
+ }
+ else if (msg->GetType () == MSG_NEW_PIN_REQUEST)
+ {
+ targ->status = HandleNewPinRequest (targ->client,
+ (RA_New_Pin_Request_Msg *)
+ msg, targ->token, &conn,
+ &targ->client->m_vars,
+ targ->params);
+ }
+ else if (msg->GetType () == MSG_END_OP)
+ {
+ RA_End_Op_Msg *endOp = (RA_End_Op_Msg *) msg;
+ if (endOp->GetResult () == 0)
+ {
+ targ->status = 1; /* error */
+ }
+ else
+ {
+ targ->status = 0;
+ }
+ if (msg != NULL)
+ {
+ delete msg;
+ msg = NULL;
+ }
+ break;
+ }
+ else
+ {
+ /* error */
+ targ->status = 0; /* error */
+ }
+ if (msg != NULL)
+ {
+ delete msg;
+ msg = NULL;
+ }
+ }
+
+ conn.Close ();
+ end = PR_Now ();
+ targ->time = (end - start) / 1000;
+
+ if (!old_style)
+ {
+ PR_Lock (targ->donelock);
+ targ->done = PR_TRUE;
+ PR_Unlock (targ->donelock);
+ }
+ }
+
+#ifdef __cplusplus
+}
+#endif
+
+int
+RA_Client::OpConnEnroll (NameValueSet * params)
+{
+ int num_threads = params->GetValueAsInt ((char *) "num_threads", 1);
+ int i;
+ int status = 0;
+ PRThread **threads;
+ ThreadArg *arg;
+
+ threads = (PRThread **) malloc (sizeof (PRThread *) * num_threads);
+ if (threads == NULL)
+ {
+ return 0; /* error */
+ }
+ arg = (ThreadArg *) malloc (sizeof (ThreadArg) * num_threads);
+ if (arg == NULL)
+ {
+ return 0;
+ }
+
+ /* start threads */
+ for (i = 0; i < num_threads; i++)
+ {
+ arg[i].time = 0;
+ arg[i].status = 0;
+ arg[i].client = this;
+ if (i == 0)
+ {
+ arg[i].token = &this->m_token;
+ }
+ else
+ {
+ arg[i].token = this->m_token.Clone ();
+ }
+ arg[i].params = params;
+ threads[i] = PR_CreateThread (PR_USER_THREAD, ThreadConnEnroll, &arg[i], PR_PRIORITY_NORMAL, /* Priority */
+ PR_GLOBAL_THREAD, /* Scope */
+ PR_JOINABLE_THREAD, /* State */
+ 0 /* Stack Size */
+ );
+ }
+
+ /* join threads */
+ for (i = 0; i < num_threads; i++)
+ {
+ PR_JoinThread (threads[i]);
+ }
+
+ status = 1;
+
+ for (i = 0; i < num_threads; i++)
+ {
+ Output ("Thread (%d) status='%d' time='%d msec'", i,
+ arg[i].status, arg[i].time);
+ if (arg[i].status != 1)
+ {
+ // if any thread fails, this operation
+ // is considered as failure
+ status = arg[i].status;
+ }
+ }
+
+
+ return status;
+}
+
+
+/*
+ * no more than num_threads will be running concurrently
+ * no more than a total of max_ops requests will be started
+ */
+int
+StartThreads (int num_threads, ThreadArg * arg, PRThread ** threads,
+ int max_ops, RA_Client * _this, NameValueSet * params,
+ RequestType op_type)
+{
+ int i;
+ int started = 0;
+
+ if (arg == NULL)
+ {
+ goto loser;
+ }
+
+ /* start threads */
+ for (i = 0; i < num_threads; i++)
+ {
+ if (started == max_ops)
+ {
+ break;
+ }
+ if (threads[i] == NULL)
+ {
+ arg[i].time = 0;
+ arg[i].status = 0;
+ arg[i].client = _this;
+ arg[i].done = PR_FALSE;
+
+ if (i == 0)
+ {
+ arg[i].token = &_this->m_token;
+ }
+ else
+ {
+
+ if (arg[i].token != NULL)
+ {
+ if (arg[i].token->m_pin)
+ {
+ PL_strfree (arg[i].token->m_pin);
+ arg[i].token->m_pin = NULL;
+ }
+ if (arg[i].token->m_session_key != NULL)
+ {
+ PORT_Free (arg[i].token->m_session_key);
+ arg[i].token->m_session_key = NULL;
+ }
+ if (arg[i].token->m_enc_session_key != NULL)
+ {
+ PORT_Free (arg[i].token->m_enc_session_key);
+ arg[i].token->m_enc_session_key = NULL;
+ }
+ if (arg[i].token->m_object != NULL)
+ {
+ delete (arg[i].token->m_object);
+ arg[i].token->m_object = NULL;
+ }
+
+ delete (arg[i].token);
+ arg[i].token = NULL;
+
+ }
+
+ arg[i].token = _this->m_token.Clone ();
+ }
+ arg[i].params = params;
+ Output ("WWWWWWWWW StartThreads -- thread (%d) begins", i);
+ if (op_type == OP_CLIENT_ENROLL)
+ {
+ threads[i] = PR_CreateThread (PR_USER_THREAD, ThreadConnEnroll, &arg[i], PR_PRIORITY_NORMAL, /* Priority */
+ PR_GLOBAL_THREAD, /* Scope */
+ PR_JOINABLE_THREAD, /* State */
+ 0 /* Stack Size */
+ );
+ }
+ else if (op_type == OP_CLIENT_FORMAT)
+ {
+ threads[i] = PR_CreateThread (PR_USER_THREAD, ThreadConnUpdate, &arg[i], PR_PRIORITY_NORMAL, /* Priority */
+ PR_GLOBAL_THREAD, /* Scope */
+ PR_JOINABLE_THREAD, /* State */
+ 0 /* Stack Size */
+ );
+ }
+ else
+ { // OP_CLIENT_RESET_PIN
+ threads[i] = PR_CreateThread (PR_USER_THREAD, ThreadConnResetPin, &arg[i], PR_PRIORITY_NORMAL, /* Priority */
+ PR_GLOBAL_THREAD, /* Scope */
+ PR_JOINABLE_THREAD, /* State */
+ 0 /* Stack Size */
+ );
+ }
+
+ started++;
+ }
+ else
+ {
+ Output ("thread[%d] is not NULL", i);
+ }
+ }
+
+loser:
+ Output ("StartThreads -- %d threads started", started);
+ return started;
+}
+
+/*
+ * no more than num_threads will be running concurrently
+ * no more than a total of max_ops requests will be started
+ */
+int
+RA_Client::OpConnStart (NameValueSet * params, RequestType op_type)
+{
+ // number of concurrent threads
+ int num_threads = params->GetValueAsInt ((char *) "num_threads", 1);
+ // number of total enrollments
+ int max_ops = params->GetValueAsInt ((char *) "max_ops", num_threads);
+ int count = 0;
+ int i;
+ int status = 1;
+ int started = 0;
+ PRThread **threads;
+ ThreadArg *arg;
+
+ threads = (PRThread **) malloc (sizeof (PRThread *) * num_threads);
+ if (threads == NULL)
+ {
+ return 0; /* error */
+ }
+ arg = (ThreadArg *) malloc (sizeof (ThreadArg) * num_threads);
+ if (arg == NULL)
+ {
+ return 0;
+ }
+
+ for (i = 0; i < num_threads; i++)
+ {
+ arg[i].donelock = PR_NewLock ();
+ arg[i].token = NULL;
+ threads[i] = NULL;
+ }
+
+ count = 0;
+ PRBool hasFreeThread = PR_TRUE;
+ while (count < max_ops)
+ {
+ // fully populate the thread pool
+
+ if (hasFreeThread)
+ {
+ started =
+ StartThreads (num_threads, arg, threads, max_ops - count, this,
+ params, op_type);
+ count += started;
+ Output ("OpConnStart: # requests started =%d", count);
+ hasFreeThread = PR_FALSE;
+ }
+
+ // PR_Sleep(PR_MillisecondsToInterval(500));
+ PR_Sleep (PR_SecondsToInterval (1));
+ Output ("OpConnStart: checking for free threads...");
+ // check if any threads are done
+ for (i = 0; i < num_threads; i++)
+ {
+ if (threads[i] != NULL)
+ {
+ PR_Lock (arg[i].donelock);
+ int arg_done = arg[i].done;
+ PR_Unlock (arg[i].donelock);
+ if (arg_done)
+ {
+ PR_JoinThread (threads[i]);
+ Output ("Thread (%d) status='%d' time='%d msec'", i,
+ arg[i].status, arg[i].time);
+
+ if (arg[i].status != 1)
+ {
+ // if any thread fails, this operation
+ // is considered as failure
+ status = arg[i].status;
+ }
+ threads[i] = NULL;
+
+ hasFreeThread = PR_TRUE;
+
+ }
+ }
+ }
+ Output ("OpConnStart: done checking for free threads...");
+ } // while
+
+ Output ("OpConnStart: TOTAL REQUESTS: %d", count);
+
+ for (i = 0; i < num_threads; i++)
+ {
+ if (threads[i] != NULL)
+ {
+ PR_JoinThread (threads[i]);
+ }
+ if (arg[i].donelock != NULL)
+ {
+ PR_DestroyLock (arg[i].donelock);
+ }
+ }
+
+ return status;
+
+}
+
+int
+RA_Client::OpVarSet (NameValueSet * params)
+{
+ m_vars.Add (params->GetValue ("name"), params->GetValue ("value"));
+ Output ("%s: '%s'", params->GetValue ("name"),
+ m_vars.GetValue (params->GetValue ("name")));
+ return 1;
+}
+
+int
+RA_Client::OpVarDebug (NameValueSet * params)
+{
+ if (m_fd_debug != NULL)
+ {
+ PR_Close (m_fd_debug);
+ m_fd_debug = NULL;
+ }
+ m_fd_debug = PR_Open (params->GetValue ("filename"),
+ PR_RDWR | PR_CREATE_FILE | PR_APPEND, 400 | 200);
+ return 1;
+}
+
+int
+RA_Client::OpVarGet (NameValueSet * params)
+{
+ char *value = m_vars.GetValue (params->GetValue ("name"));
+ Output ("%s: '%s'", params->GetValue ("name"), value);
+
+ return 1;
+}
+
+int
+RA_Client::OpVarList (NameValueSet * params)
+{
+ int i;
+ char *name;
+
+ for (i = 0; i < m_vars.Size (); i++)
+ {
+ name = m_vars.GetNameAt (i);
+ Output ("%s: '%s'", name, m_vars.GetValue (name));
+ }
+ return 1;
+}
+
+/**
+ * Invoke operation.
+ */
+void
+RA_Client::InvokeOperation (char *op, NameValueSet * params)
+{
+ PRTime start, end;
+ int status = 0;
+
+ start = PR_Now ();
+ Debug ("RA_Client::InvokeOperation", "op='%s'", op);
+ int max_ops = params->GetValueAsInt ((char *) "max_ops");
+ if (max_ops != 0)
+ old_style = PR_FALSE;
+
+ if (strcmp (op, "help") == 0)
+ {
+ status = OpHelp (params);
+ }
+ else if (strcmp (op, "ra_format") == 0)
+ {
+ if (old_style)
+ status = OpConnUpdate (params);
+ else
+ status = OpConnStart (params, OP_CLIENT_FORMAT);
+ }
+ else if (strcmp (op, "ra_reset_pin") == 0)
+ {
+ if (old_style)
+ status = OpConnResetPin (params);
+ else
+ status = OpConnStart (params, OP_CLIENT_RESET_PIN);
+ }
+ else if (strcmp (op, "ra_enroll") == 0)
+ {
+ if (old_style)
+ status = OpConnEnroll (params);
+ else
+ status = OpConnStart (params, OP_CLIENT_ENROLL);
+ }
+ else if (strcmp (op, "token_status") == 0)
+ {
+ status = OpTokenStatus (params);
+ }
+ else if (strcmp (op, "token_set") == 0)
+ {
+ status = OpTokenSet (params);
+ }
+ else if (strcmp (op, "debug") == 0)
+ {
+ status = OpVarDebug (params);
+ }
+ else if (strcmp (op, "var_set") == 0)
+ {
+ status = OpVarSet (params);
+ }
+ else if (strcmp (op, "var_get") == 0)
+ {
+ status = OpVarGet (params);
+ }
+ else if (strcmp (op, "var_list") == 0)
+ {
+ status = OpVarList (params);
+ }
+ end = PR_Now ();
+
+ if (status)
+ {
+ OutputSuccess ("Operation '%s' Success (%d msec)", op,
+ (end - start) / 1000);
+ }
+ else
+ {
+ OutputError ("Operation '%s' Failure (%d msec)", op,
+ (end - start) / 1000);
+ }
+}
+
+/**
+ * Execute RA client.
+ */
+void
+RA_Client::Execute ()
+{
+ char line[1024];
+ int rc;
+ char *op;
+ int done = 0;
+ char *lasts = NULL;
+
+ /* start main loop */
+ PrintHeader ();
+ while (!done)
+ {
+ PrintPrompt ();
+ rc = ReadLine (line, 1024);
+ printf ("%s\n", line);
+ if (rc <= 0)
+ {
+ break; /* exit if no more line */
+ }
+ if (line[0] == '#')
+ {
+ continue; /* ignore comment line */
+ }
+ /* format: 'op=cmd <parameters>' */
+ NameValueSet *params = NameValueSet::Parse (line, " ");
+ if (params == NULL)
+ {
+ continue;
+ }
+ op = params->GetValue ("op");
+ if (op == NULL)
+ {
+ /* user did not type op= */
+ op = PL_strtok_r (line, " ", &lasts);
+ if (op == NULL)
+ continue;
+ }
+ if (strcmp (op, "exit") == 0)
+ {
+ done = 1;
+ }
+ else
+ {
+ InvokeOperation (op, params);
+ }
+ if (params != NULL)
+ {
+ delete params;
+ params = NULL;
+ }
+ }
+} /* Execute */
+
+char *
+ownPasswd (PK11SlotInfo * slot, PRBool retry, void *arg)
+{
+ return PL_strdup ("password");
+}
+
+/**
+ * User certutil -d . -N to create a database.
+ * The database should have 'password' as the password.
+ */
+int
+main (int argc, char *argv[])
+{
+ char buffer[513];
+ SECStatus rv;
+ PK11SlotInfo *slot = NULL;
+ PRUint32 flags = 0;
+ // char *newpw = NULL;
+
+ /* Initialize NSPR & NSS */
+ PR_Init (PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
+ PK11_SetPasswordFunc (ownPasswd);
+ rv = NSS_Initialize (".", "", "", "", flags);
+ if (rv != SECSuccess)
+ {
+ PR_GetErrorText (buffer);
+ fprintf (stderr, "unable to initialize NSS library (%d - '%s')\n",
+ PR_GetError (), buffer);
+ exit (0);
+ }
+ slot = PK11_GetInternalKeySlot ();
+ if (PK11_NeedUserInit (slot))
+ {
+ rv = PK11_InitPin (slot, (char *) NULL, (char *) "password");
+ if (rv != SECSuccess)
+ {
+ PR_GetErrorText (buffer);
+ fprintf (stderr, "unable to set new PIN (%d - '%s')\n",
+ PR_GetError (), buffer);
+ exit (0);
+ }
+
+ }
+ if (PK11_NeedLogin (slot))
+ {
+ rv = PK11_Authenticate (slot, PR_TRUE, NULL);
+ if (rv != SECSuccess)
+ {
+ PR_GetErrorText (buffer);
+ fprintf (stderr, "unable to authenticate (%d - '%s')\n",
+ PR_GetError (), buffer);
+ exit (0);
+ }
+ }
+
+ /* Start RA Client */
+ RA_Client client;
+ client.Execute ();
+
+ /* Shutdown NSS and NSPR */
+ NSS_Shutdown ();
+ PR_Cleanup ();
+
+ return 1;
+}
diff --git a/base/tps/tools/raclient/RA_Client.h b/base/tps/tools/raclient/RA_Client.h
new file mode 100644
index 000000000..6ab2ecf97
--- /dev/null
+++ b/base/tps/tools/raclient/RA_Client.h
@@ -0,0 +1,78 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_CLIENT_H
+#define RA_CLIENT_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "prthread.h"
+#include "main/NameValueSet.h"
+#include "RA_Conn.h"
+#include "RA_Token.h"
+
+enum RequestType {
+ OP_CLIENT_ENROLL = 0,
+ OP_CLIENT_FORMAT = 1,
+ OP_CLIENT_RESET_PIN = 2
+};
+
+class RA_Client
+{
+ public:
+ RA_Client();
+ ~RA_Client();
+ public:
+ int OpHelp(NameValueSet *set);
+ int OpConnStart(NameValueSet *set, RequestType);
+ int OpConnResetPin(NameValueSet *set);
+ int OpConnEnroll(NameValueSet *set);
+ int OpConnUpdate(NameValueSet *set);
+ int OpTokenStatus(NameValueSet *set);
+ int OpTokenSet(NameValueSet *set);
+ int OpVarList(NameValueSet *set);
+ int OpVarSet(NameValueSet *set);
+ int OpVarDebug(NameValueSet *set);
+ int OpVarGet(NameValueSet *set);
+ int OpExit(NameValueSet *set);
+ public:
+ void Debug(const char *func_name, const char *fmt, ...);
+ void Execute();
+ void InvokeOperation(char *op, NameValueSet *set);
+ public:
+ RA_Token m_token;
+ NameValueSet m_vars;
+};
+
+#endif /* RA_CLIENT_H */
diff --git a/base/tps/tools/raclient/RA_Conn.cpp b/base/tps/tools/raclient/RA_Conn.cpp
new file mode 100644
index 000000000..17a3ed34f
--- /dev/null
+++ b/base/tps/tools/raclient/RA_Conn.cpp
@@ -0,0 +1,1037 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include <string.h>
+#include "prnetdb.h"
+#include "prerror.h"
+#include "prio.h"
+#include "plstr.h"
+#include "main/NameValueSet.h"
+#include "main/Util.h"
+#include "RA_Conn.h"
+#include "apdu/APDU_Response.h"
+#include "apdu/List_Objects_APDU.h"
+#include "apdu/Create_Object_APDU.h"
+#include "apdu/Generate_Key_APDU.h"
+#include "apdu/External_Authenticate_APDU.h"
+#include "apdu/Initialize_Update_APDU.h"
+#include "apdu/Lifecycle_APDU.h"
+#include "apdu/Set_Pin_APDU.h"
+#include "apdu/Get_Status_APDU.h"
+#include "apdu/Get_Data_APDU.h"
+#include "apdu/Format_Muscle_Applet_APDU.h"
+#include "apdu/Load_File_APDU.h"
+#include "apdu/Get_IssuerInfo_APDU.h"
+#include "apdu/Set_IssuerInfo_APDU.h"
+#include "apdu/Install_Applet_APDU.h"
+#include "apdu/Install_Load_APDU.h"
+#include "apdu/Import_Key_APDU.h"
+#include "apdu/Import_Key_Enc_APDU.h"
+#include "apdu/Install_Load_APDU.h"
+#include "apdu/Create_Pin_APDU.h"
+#include "apdu/Read_Buffer_APDU.h"
+#include "apdu/List_Pins_APDU.h"
+#include "apdu/Write_Object_APDU.h"
+#include "apdu/Delete_File_APDU.h"
+#include "apdu/Unblock_Pin_APDU.h"
+#include "apdu/Select_APDU.h"
+#include "apdu/Get_Version_APDU.h"
+#include "apdu/Put_Key_APDU.h"
+#include "msg/RA_Begin_Op_Msg.h"
+#include "msg/RA_End_Op_Msg.h"
+#include "msg/RA_Extended_Login_Request_Msg.h"
+#include "msg/RA_Login_Request_Msg.h"
+#include "msg/RA_SecureId_Request_Msg.h"
+#include "msg/RA_ASQ_Request_Msg.h"
+#include "msg/RA_New_Pin_Request_Msg.h"
+#include "msg/RA_Status_Update_Request_Msg.h"
+#include "msg/RA_Status_Update_Response_Msg.h"
+#include "msg/RA_Token_PDU_Request_Msg.h"
+#include "msg/RA_Login_Response_Msg.h"
+#include "msg/RA_Extended_Login_Response_Msg.h"
+#include "msg/RA_SecureId_Response_Msg.h"
+#include "msg/RA_ASQ_Response_Msg.h"
+#include "msg/RA_New_Pin_Response_Msg.h"
+#include "msg/RA_Token_PDU_Response_Msg.h"
+#include "engine/RA.h"
+
+/**
+ * http parameters used in the protocol
+ */
+#define PARAM_MSG_TYPE "msg_type"
+#define PARAM_OPERATION "operation"
+#define PARAM_EXTENSIONS "extensions"
+#define PARAM_INVALID_PW "invalid_pw"
+#define PARAM_BLOCKED "blocked"
+#define PARAM_SCREEN_NAME "screen_name"
+#define PARAM_PASSWORD "password"
+#define PARAM_PIN_REQUIRED "pin_required"
+#define PARAM_NEXT_VALUE "next_value"
+#define PARAM_VALUE "value"
+#define PARAM_PIN "pin"
+#define PARAM_QUESTION "question"
+#define PARAM_ANSWER "answer"
+#define PARAM_MINIMUM_LENGTH "minimum_length"
+#define PARAM_MAXIMUM_LENGTH "maximum_length"
+#define PARAM_NEW_PIN "new_pin"
+#define PARAM_PDU_SIZE "pdu_size"
+#define PARAM_PDU_DATA "pdu_data"
+#define PARAM_RESULT "result"
+#define PARAM_MESSAGE "message"
+#define PARAM_CURRENT_STATE "current_state"
+#define PARAM_NEXT_TASK_NAME "next_task_name"
+
+#define MAX_RA_MSG_SIZE 4096
+
+/**
+ * Constructs a RA connection.
+ */
+RA_Conn::RA_Conn (char *host, int port, char *uri)
+{
+ if (host == NULL)
+ m_host = NULL;
+ else
+ m_host = PL_strdup (host);
+ if (uri == NULL)
+ m_uri = NULL;
+ else
+ m_uri = PL_strdup (uri);
+ m_port = port;
+ m_read_header = 0;
+ m_fd = NULL;
+}
+
+/**
+ * Destructs a RA connection.
+ */
+RA_Conn::~RA_Conn ()
+{
+ if (m_host != NULL)
+ {
+ PL_strfree (m_host);
+ m_host = NULL;
+ }
+ if (m_uri != NULL)
+ {
+ PL_strfree (m_uri);
+ m_uri = NULL;
+ }
+ if (m_fd != NULL)
+ {
+ PR_Close (m_fd);
+ m_fd = NULL;
+ }
+}
+
+static void
+Output (const char *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ printf ("Output> ");
+ vprintf (fmt, ap);
+ printf ("\n");
+ va_end (ap);
+}
+
+
+#ifdef VERBOSE
+static void
+printBuf (Buffer * buf)
+{
+ int sum = 0;
+
+ BYTE *data = *buf;
+ int i = 0;
+ if (buf->size () > 255)
+ {
+ Output ("printBuf: TOO BIG to print");
+ return;
+ }
+ Output ("Begin printing buffer =====");
+ for (i = 0; i < (int) buf->size (); i++)
+ {
+ printf ("%02x ", (unsigned char) data[i]);
+ sum++;
+ if (sum == 10)
+ {
+ printf ("\n");
+ sum = 0;
+ }
+ }
+ Output ("End printing buffer =====");
+}
+#endif
+
+
+static PRUint32
+GetIPAddress (const char *hostName)
+{
+ const unsigned char *p;
+ char buf[PR_NETDB_BUF_SIZE];
+ PRStatus prStatus;
+ PRUint32 rv = 0;
+ PRHostEnt prHostEnt;
+
+ prStatus = PR_GetHostByName (hostName, buf, sizeof buf, &prHostEnt);
+ if (prStatus != PR_SUCCESS)
+ return rv;
+
+#undef h_addr
+#define h_addr h_addr_list[0] /* address, for backward compatibility */
+
+ p = (const unsigned char *) (prHostEnt.h_addr); /* in Network Byte order */
+ rv = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+ return rv;
+}
+
+/**
+ * Connects to the RA.
+ */
+int
+RA_Conn::Connect ()
+{
+ PRStatus rc;
+ char header[4096];
+
+ sprintf (header, "POST %s HTTP/1.1\r\n"
+ "Host: %s:%d\r\n"
+ "Transfer-Encoding: chunked\r\n" "\r\n", m_uri, m_host, m_port);
+
+ m_fd = PR_NewTCPSocket ();
+
+ /*
+ * Rifle through the values for the host
+ */
+
+ PRAddrInfo *ai;
+ void *iter;
+ PRNetAddr addr;
+ int family = PR_AF_INET;
+
+ ai = PR_GetAddrInfoByName(m_host, PR_AF_UNSPEC, PR_AI_ADDRCONFIG);
+ if (ai) {
+ iter = NULL;
+ while ((iter = PR_EnumerateAddrInfo(iter, ai, 0, &addr)) != NULL) {
+ family = PR_NetAddrFamily(&addr);
+ break;
+ }
+ PR_FreeAddrInfo(ai);
+ }
+
+ PR_SetNetAddr( PR_IpAddrNull, family, m_port, &addr );
+
+ m_fd = PR_OpenTCPSocket( family );
+ if( !m_fd ) {
+ return 0;
+ }
+
+ rc = PR_Connect (m_fd, &addr, PR_INTERVAL_NO_TIMEOUT /* timeout */ );
+ if (rc != PR_SUCCESS)
+ return 0;
+
+ /* Send header */
+
+ PR_Send (m_fd, header, strlen (header), 0, 1000000);
+
+ return 1;
+}
+
+static void
+CreateChunkEntity (char *msg, char *chunk, int chunk_len)
+{
+ int chunk_size;
+ int len;
+ Output ("***** msg = %s *****", msg);
+ len = strlen (msg);
+ sprintf (chunk, "s=%d&%s", len, msg);
+ chunk_size = strlen (chunk);
+ sprintf (chunk, "%x\r\ns=%d&%s\r\n", chunk_size, len, msg);
+}
+
+/**
+ * Sends message to the RA.
+ */
+int
+RA_Conn::SendMsg (RA_Msg * msg)
+{
+ char msgbuf[MAX_RA_MSG_SIZE];
+ char chunk[MAX_RA_MSG_SIZE];
+
+ /* send chunk size */
+ if (msg->GetType () == MSG_BEGIN_OP)
+ {
+ RA_Begin_Op_Msg *begin = (RA_Begin_Op_Msg *) msg;
+ sprintf (msgbuf, "%s=%d&%s=%d", PARAM_MSG_TYPE, MSG_BEGIN_OP,
+ PARAM_OPERATION, begin->GetOpType ());
+ NameValueSet *exts = begin->GetExtensions ();
+ if (exts != NULL)
+ {
+ sprintf (msgbuf, "%s&%s=", msgbuf, PARAM_EXTENSIONS);
+ for (int i = 0; i < exts->Size (); i++)
+ {
+ if (i != 0)
+ {
+ sprintf (msgbuf, "%s%%26", msgbuf);
+ }
+ char *name = exts->GetNameAt (i);
+ sprintf (msgbuf, "%s%s=%s",
+ msgbuf, name, exts->GetValueAsString (name));
+ }
+ }
+ CreateChunkEntity (msgbuf, chunk, 4096);
+ }
+ else if (msg->GetType () == MSG_LOGIN_RESPONSE)
+ {
+ RA_Login_Response_Msg *resp = (RA_Login_Response_Msg *) msg;
+ sprintf (msgbuf, "%s=%d&%s=%s&%s=%s",
+ PARAM_MSG_TYPE, MSG_LOGIN_RESPONSE,
+ PARAM_SCREEN_NAME, resp->GetUID (),
+ PARAM_PASSWORD, resp->GetPassword ());
+ CreateChunkEntity (msgbuf, chunk, 4096);
+ }
+ else if (msg->GetType () == MSG_EXTENDED_LOGIN_RESPONSE)
+ {
+ RA_Extended_Login_Response_Msg *resp =
+ (RA_Extended_Login_Response_Msg *) msg;
+ AuthParams *auth = resp->GetAuthParams ();
+ sprintf (msgbuf, "%s=%d&%s=%s&%s=%s",
+ PARAM_MSG_TYPE, MSG_EXTENDED_LOGIN_RESPONSE,
+ PARAM_SCREEN_NAME, auth->GetUID (),
+ PARAM_PASSWORD, auth->GetPassword ());
+ CreateChunkEntity (msgbuf, chunk, 4096);
+ }
+ else if (msg->GetType () == MSG_STATUS_UPDATE_RESPONSE)
+ {
+ RA_Status_Update_Response_Msg *resp =
+ (RA_Status_Update_Response_Msg *) msg;
+ int status = resp->GetStatus ();
+ sprintf (msgbuf, "%s=%d&%s=%d",
+ PARAM_MSG_TYPE, MSG_STATUS_UPDATE_RESPONSE,
+ PARAM_CURRENT_STATE, status);
+ CreateChunkEntity (msgbuf, chunk, 4096);
+ }
+ else if (msg->GetType () == MSG_SECUREID_RESPONSE)
+ {
+ RA_SecureId_Response_Msg *resp = (RA_SecureId_Response_Msg *) msg;
+ char *value = resp->GetValue ();
+ char *pin = resp->GetPIN ();
+ if (pin == NULL)
+ {
+ pin = (char *) "";
+ }
+ sprintf (msgbuf, "%s=%d&%s=%s&%s=%s",
+ PARAM_MSG_TYPE, MSG_SECUREID_RESPONSE,
+ PARAM_VALUE, value, PARAM_PIN, pin);
+ CreateChunkEntity (msgbuf, chunk, 4096);
+ }
+ else if (msg->GetType () == MSG_ASQ_RESPONSE)
+ {
+ RA_ASQ_Response_Msg *resp = (RA_ASQ_Response_Msg *) msg;
+ sprintf (msgbuf, "%s=%d&%s=%s",
+ PARAM_MSG_TYPE, MSG_ASQ_RESPONSE,
+ PARAM_ANSWER, resp->GetAnswer ());
+ CreateChunkEntity (msgbuf, chunk, 4096);
+ }
+ else if (msg->GetType () == MSG_NEW_PIN_RESPONSE)
+ {
+ RA_New_Pin_Response_Msg *resp = (RA_New_Pin_Response_Msg *) msg;
+ sprintf (msgbuf, "%s=%d&%s=%s",
+ PARAM_MSG_TYPE, MSG_NEW_PIN_RESPONSE,
+ PARAM_NEW_PIN, resp->GetNewPIN ());
+ CreateChunkEntity (msgbuf, chunk, 4096);
+ }
+ else if (msg->GetType () == MSG_TOKEN_PDU_RESPONSE)
+ {
+ RA_Token_PDU_Response_Msg *resp = (RA_Token_PDU_Response_Msg *) msg;
+ APDU_Response *apdu_resp = resp->GetResponse ();
+ Buffer pdu = apdu_resp->GetData ();
+ char *pdu_encoded = Util::URLEncode (pdu);
+ sprintf (msgbuf, "%s=%d&%s=%s&%s=%d",
+ PARAM_MSG_TYPE, MSG_TOKEN_PDU_RESPONSE,
+ PARAM_PDU_DATA, pdu_encoded, PARAM_PDU_SIZE, pdu.size ());
+ if (pdu_encoded != NULL)
+ {
+ PR_Free (pdu_encoded);
+ pdu_encoded = NULL;
+ }
+ CreateChunkEntity (msgbuf, chunk, 4096);
+ }
+ else
+ {
+ /* error */
+ }
+
+ /* send chunk */
+ Output ("sending chunk ----- %s -----", chunk);
+ PR_Send (m_fd, chunk, strlen (chunk), 0, 1000000);
+
+ return 1;
+}
+
+static int
+ReadResponseHeader (PRFileDesc * fd)
+{
+ char buf[1024];
+ PRInt32 rc;
+ char *cur = buf;
+ int i;
+
+ for (i = 0; i < 1024; i++)
+ {
+ buf[i] = 0;
+ }
+ while (1)
+ {
+ rc = PR_Recv (fd, cur, 1, 0, 1000000);
+ if (buf[0] == '\r' &&
+ buf[1] == '\n' && buf[2] == '\r' && buf[3] == '\n')
+ {
+ break;
+ }
+ if (*cur == '\r')
+ {
+ cur++;
+ }
+ else if (*cur == '\n')
+ {
+ cur++;
+ }
+ else
+ {
+ cur = buf;
+ }
+ }
+ return 1;
+}
+
+static int
+GetChunkSize (PRFileDesc * fd)
+{
+ char buf[1024];
+ char *cur = buf;
+ PRInt32 rc;
+ int i;
+ int ret;
+
+ for (i = 0; i < 1024; i++)
+ {
+ buf[i] = 0;
+ }
+ while (1)
+ {
+ rc = PR_Recv (fd, cur, 1, 0, 1000000);
+ if (rc <= 0)
+ {
+ return 0;
+ }
+ if (*cur == '\r')
+ {
+ *cur = '\0';
+ /* read \n */
+ rc = PR_Recv (fd, cur, 1, 0, 1000000);
+ if (rc <= 0)
+ {
+ return 0;
+ }
+ *cur = '\0';
+ break;
+ }
+ cur++;
+ }
+ sscanf (buf, "%x", (unsigned int *) (&ret));
+ return ret;
+}
+
+static int
+GetChunk (PRFileDesc * fd, char *buf, int buflen)
+{
+ int rc = 0;
+ int sum = 0;
+ char *cur = buf;
+
+ while (1)
+ {
+ rc = PR_Recv (fd, cur, buflen - sum, 0, 1000000);
+ if (rc <= 0)
+ {
+ return -1;
+ }
+ sum += rc;
+ cur += rc;
+ cur[sum] = '\0';
+ if (sum == buflen)
+ return sum;
+ }
+}
+
+bool
+RA_Conn::isEncrypted ()
+{
+ return m_encrypted_channel;
+}
+
+void
+RA_Conn::setEncryption (bool encrypted)
+{
+ Output ("RA_Conn::setEncryption: setting encrypted channel: %d", encrypted);
+ m_encrypted_channel = encrypted;
+}
+
+APDU *
+RA_Conn::CreateAPDU (RA_Token * tok, Buffer & in_apdu_data, Buffer & mac)
+{
+ APDU *apdu = NULL;
+ Buffer apdu_data;
+
+ if (isEncrypted () && (((BYTE *) in_apdu_data)[0] == 0x84))
+ {
+ tok->decryptMsg (in_apdu_data, apdu_data);
+ }
+ else
+ {
+ apdu_data = in_apdu_data;
+ }
+
+ if (((BYTE *) apdu_data)[1] == 0x5a)
+ {
+ /* Create_Object_APDU */
+ mac = Buffer (apdu_data.substr (apdu_data.size () - 8, 8));
+ BYTE object_id[4];
+ object_id[0] = ((BYTE *) apdu_data)[5];
+ object_id[1] = ((BYTE *) apdu_data)[6];
+ object_id[2] = ((BYTE *) apdu_data)[7];
+ object_id[3] = ((BYTE *) apdu_data)[8];
+ BYTE permissions[6];
+ permissions[0] = ((BYTE *) apdu_data)[13];
+ permissions[1] = ((BYTE *) apdu_data)[14];
+ permissions[2] = ((BYTE *) apdu_data)[15];
+ permissions[3] = ((BYTE *) apdu_data)[16];
+ permissions[4] = ((BYTE *) apdu_data)[17];
+ permissions[5] = ((BYTE *) apdu_data)[18];
+ int len =
+ (((BYTE *) apdu_data)[9] << 24) + (((BYTE *) apdu_data)[10] << 16) +
+ (((BYTE *) apdu_data)[11] << 8) + ((BYTE *) apdu_data)[12];
+ apdu = new Create_Object_APDU (object_id, permissions, len);
+ apdu->SetMAC (mac);
+ }
+ else if (((BYTE *) apdu_data)[1] == 0x82)
+ {
+ /* External_Authenticate_APDU */
+ BYTE encryption = ((BYTE *) apdu_data)[2]; // P1 is sec level
+ if (encryption == (BYTE) 0x03)
+ {
+ setEncryption (true);
+ }
+ else
+ {
+ Output ("RA_Conn::CreateAPDU(): not encrypted");
+ }
+
+ // mac is last 8 bytes
+ mac = Buffer (apdu_data.substr (apdu_data.size () - 8, 8));
+ Buffer *data = new Buffer (apdu_data.substr (5, 8));
+
+ if (isEncrypted () == true)
+ {
+ apdu = new External_Authenticate_APDU (*data, SECURE_MSG_MAC_ENC);
+ }
+ else
+ {
+ apdu = new External_Authenticate_APDU (*data, SECURE_MSG_ANY);
+ }
+ if (data != NULL)
+ {
+ delete data;
+ data = NULL;
+ }
+ apdu->SetMAC (mac);
+ }
+ else if (((BYTE *) apdu_data)[1] == 0x0A)
+ {
+ /* ImportKeyEnc APDU */
+ mac = Buffer (apdu_data.substr (apdu_data.size () - 8, 8));
+ BYTE p[2];
+ p[0] = ((BYTE *) apdu_data)[2]; /* p1 */
+ p[1] = ((BYTE *) apdu_data)[3]; /* p2 */
+ Buffer *data =
+ new Buffer (apdu_data.substr (5, apdu_data.size () - 8 - 5));
+ Buffer a;
+ apdu = new Import_Key_Enc_APDU ((BYTE) p[0], (BYTE) p[1], *data);
+ apdu->SetMAC (mac);
+ if (data != NULL)
+ {
+ delete data;
+ data = NULL;
+ }
+
+ }
+ else if (((BYTE *) apdu_data)[1] == 0x0C)
+ {
+ /* Generate_Key_APDU */
+ BYTE p[2];
+ p[0] = ((BYTE *) apdu_data)[2]; /* p1 */
+ p[1] = ((BYTE *) apdu_data)[3]; /* p2 */
+ mac = Buffer (apdu_data.substr (apdu_data.size () - 8, 8));
+ BYTE alg = ((BYTE *) apdu_data)[5];
+ int keysize = (((BYTE *) apdu_data)[6] << 8) + ((BYTE *) apdu_data)[7];
+ BYTE option = ((BYTE *) apdu_data)[8];
+ BYTE type = ((BYTE *) apdu_data)[9];
+ unsigned int wc_len = (unsigned int) ((BYTE *) apdu_data)[10];
+ Buffer *wrapped_challenge = new Buffer ((BYTE *) &
+ ((BYTE *) apdu_data)[11],
+ wc_len);
+ Buffer *key_check = new Buffer ((BYTE *) &
+ ((BYTE *) apdu_data)[11 + wc_len + 1],
+ (unsigned int) ((BYTE *) apdu_data)[11 +
+ wc_len]);
+ apdu =
+ new Generate_Key_APDU (p[0], p[1], alg, keysize, option, type,
+ *wrapped_challenge, *key_check);
+ if (wrapped_challenge != NULL)
+ {
+ delete wrapped_challenge;
+ wrapped_challenge = NULL;
+ }
+ if (key_check != NULL)
+ {
+ delete key_check;
+ key_check = NULL;
+ }
+ apdu->SetMAC (mac);
+ }
+ else if (((BYTE *) apdu_data)[1] == 0x50)
+ {
+ /* Initialize_Update_APDU */
+
+ setEncryption (false);
+ BYTE p[2];
+ p[0] = ((BYTE *) apdu_data)[2]; /* p1 */
+ p[1] = ((BYTE *) apdu_data)[3]; /* p2 */
+ Buffer *data = new Buffer (apdu_data.substr (5, 8));
+ apdu = new Initialize_Update_APDU (p[0], p[1], *data);
+ if (data != NULL)
+ {
+ delete data;
+ data = NULL;
+ }
+ }
+ else if (((BYTE *) apdu_data)[1] == 0x56)
+ { /* Read Objects */
+ BYTE p[4];
+ int offset = 0;
+ int size = 0;
+ p[0] = ((BYTE *) apdu_data)[5];
+ p[1] = ((BYTE *) apdu_data)[6];
+ p[2] = ((BYTE *) apdu_data)[7];
+ p[3] = ((BYTE *) apdu_data)[8];
+ offset = (((BYTE *) apdu_data)[9] << 24) +
+ (((BYTE *) apdu_data)[10] << 16) +
+ (((BYTE *) apdu_data)[11] << 8) + ((BYTE *) apdu_data)[12];
+ size = ((BYTE *) apdu_data)[13]; /* p2 */
+ apdu = new Read_Object_APDU (p, offset, size);
+ mac = Buffer (apdu_data.substr (apdu_data.size () - 8, 8));
+ apdu->SetMAC (mac);
+ }
+ else if (((BYTE *) apdu_data)[1] == 0x58)
+ { /* List Objects */
+ apdu = new List_Objects_APDU (((BYTE *) apdu_data)[2]);
+ }
+ else if (((BYTE *) apdu_data)[1] == 0xf0)
+ {
+ /* Lifecycle_APDU */
+ mac = Buffer (apdu_data.substr (apdu_data.size () - 8, 8));
+ apdu = new Lifecycle_APDU (((BYTE *) apdu_data)[2]);
+ apdu->SetMAC (mac);
+ }
+ else if (((BYTE *) apdu_data)[1] == 0x08)
+ {
+ /* Read_BufferAPDU */
+ mac = Buffer (apdu_data.substr (apdu_data.size () - 8, 8));
+ int len = ((BYTE *) apdu_data)[2];
+ int offset = (((BYTE *) apdu_data)[5] << 8) + ((BYTE *) apdu_data)[6];
+ apdu = new Read_Buffer_APDU (len, offset);
+ apdu->SetMAC (mac);
+ }
+ else if (((BYTE *) apdu_data)[1] == 0x04)
+ {
+ /* Set_Pin_APDU */
+ BYTE p[2];
+ p[0] = ((BYTE *) apdu_data)[2]; /* p1 */
+ p[1] = ((BYTE *) apdu_data)[3]; /* p2 */
+ mac = Buffer (apdu_data.substr (apdu_data.size () - 8, 8));
+ Buffer *data =
+ new Buffer (apdu_data.substr (5, apdu_data.size () - 8 - 5));
+ apdu = new Set_Pin_APDU (p[0], p[1], *data);
+ if (data != NULL)
+ {
+ delete data;
+ data = NULL;
+ }
+ apdu->SetMAC (mac);
+ }
+ else if (((BYTE *) apdu_data)[1] == 0x2a)
+ {
+ Buffer dummy;
+ apdu = new Format_Muscle_Applet_APDU (0,
+ dummy, 0,
+ dummy, 0,
+ dummy, 0, dummy, 0, 0, 0, 0);
+ }
+ else if (((BYTE *) apdu_data)[1] == 0xe6)
+ {
+ BYTE p1 = ((BYTE *) apdu_data)[2]; /* p1 */
+ mac = Buffer (apdu_data.substr (apdu_data.size () - 8, 8));
+/* Why was it ignored?
+ Buffer dummy;
+ if (p1 == 0x02) {
+ apdu = new Install_Load_APDU(dummy, dummy, 0);
+ } else {
+ apdu = new Install_Applet_APDU(dummy, dummy, 0,0);
+ }
+*/
+ Buffer *data =
+ new Buffer (apdu_data.substr (5, apdu_data.size () - 8 - 5));
+ if (p1 == 0x02)
+ {
+ apdu = new Install_Load_APDU (*data);
+ }
+ else
+ {
+ apdu = new Install_Applet_APDU (*data);
+ }
+ apdu->SetMAC (mac);
+ if (data != NULL)
+ {
+ delete data;
+ data = NULL;
+ }
+ }
+ else if (((BYTE *) apdu_data)[1] == 0xe8)
+ {
+ BYTE p[2];
+ p[0] = ((BYTE *) apdu_data)[2]; /* p1 */
+ p[1] = ((BYTE *) apdu_data)[3]; /* p2 */
+ mac = Buffer (apdu_data.substr (apdu_data.size () - 8, 8));
+ Buffer *data =
+ new Buffer (apdu_data.substr (5, apdu_data.size () - 8 - 5));
+ apdu = new Load_File_APDU (p[0], p[1], *data);
+ if (data != NULL)
+ {
+ delete data;
+ data = NULL;
+ }
+ apdu->SetMAC (mac);
+ }
+ else if (((BYTE *) apdu_data)[1] == 0xe4)
+ {
+ mac = Buffer (apdu_data.substr (apdu_data.size () - 8, 8));
+ // Delete File apdu has two extra bytes after header
+ // remove before proceed
+ Buffer *data =
+ new Buffer (apdu_data.substr (7, apdu_data.size () - 8 - 5 - 2));
+ apdu = new Delete_File_APDU (*data);
+ if (data != NULL)
+ {
+ delete data;
+ data = NULL;
+ }
+ apdu->SetMAC (mac);
+ }
+ else if (((BYTE *) apdu_data)[1] == 0x02)
+ {
+ /* Unblock_Pin_APDU */
+ mac = Buffer (apdu_data.substr (apdu_data.size () - 8, 8));
+ apdu = new Unblock_Pin_APDU ();
+ apdu->SetMAC (mac);
+ }
+ else if (((BYTE *) apdu_data)[1] == 0xa4)
+ { /* Select */
+ BYTE p[2];
+ p[0] = ((BYTE *) apdu_data)[2]; /* p1 */
+ p[1] = ((BYTE *) apdu_data)[3]; /* p2 */
+ Buffer *data = NULL;
+ if (apdu_data.size () == 5)
+ {
+ data = new Buffer ();
+ }
+ else
+ {
+ data = new Buffer (apdu_data.substr (5, apdu_data.size () - 5));
+ }
+ apdu = new Select_APDU (p[0], p[1], *data);
+ if (data != NULL)
+ {
+ delete data;
+ data = NULL;
+ }
+ }
+ else if (((BYTE *) apdu_data)[1] == 0x3C)
+ { /* Get Status */
+ apdu = new Get_Status_APDU ();
+ }
+ else if (((BYTE *) apdu_data)[1] == 0x70)
+ { /* Get Version */
+ apdu = new Get_Version_APDU ();
+ }
+ else if (((BYTE *) apdu_data)[1] == 0x48)
+ {
+ apdu = new List_Pins_APDU (0x02);
+ }
+ else if (((BYTE *) apdu_data)[1] == 0x40)
+ { /* Put Key */
+ BYTE p[2];
+ p[0] = ((BYTE *) apdu_data)[2]; /* p1 */
+ p[1] = ((BYTE *) apdu_data)[3]; /* p2 */
+ mac = Buffer (apdu_data.substr (apdu_data.size () - 8, 8));
+ Buffer *data =
+ new Buffer (apdu_data.substr (5, apdu_data.size () - 8 - 5));
+ apdu = new Create_Pin_APDU (p[0], p[1], *data);
+ apdu->SetMAC (mac);
+ if (data != NULL)
+ {
+ delete data;
+ data = NULL;
+ }
+ }
+ else if (((BYTE *) apdu_data)[1] == 0xca)
+ { /* Get Data */
+ apdu = new Get_Data_APDU ();
+ }
+ else if (((BYTE *) apdu_data)[1] == 0xf6)
+ { /* Get_IssuerInfo */
+ apdu = new Get_IssuerInfo_APDU ();
+ }
+ else if (((BYTE *) apdu_data)[1] == 0xf4)
+ { /* Set_IssuerInfo */
+ BYTE p[2];
+ p[0] = ((BYTE *) apdu_data)[2]; /* p1 */
+ p[1] = ((BYTE *) apdu_data)[3]; /* p2 */
+ mac = Buffer (apdu_data.substr (apdu_data.size () - 8, 8));
+ Buffer *data =
+ new Buffer (apdu_data.substr (5, apdu_data.size () - 8 - 5));
+ apdu = new Set_IssuerInfo_APDU (p[0], p[1], *data);
+ apdu->SetMAC (mac);
+ if (data != NULL)
+ {
+ delete data;
+ data = NULL;
+ }
+ }
+ else if (((BYTE *) apdu_data)[1] == 0xd8)
+ { /* Put Key */
+ BYTE p[2];
+ p[0] = ((BYTE *) apdu_data)[2]; /* p1 */
+ p[1] = ((BYTE *) apdu_data)[3]; /* p2 */
+ mac = Buffer (apdu_data.substr (apdu_data.size () - 8, 8));
+ Buffer *data =
+ new Buffer (apdu_data.substr (5, apdu_data.size () - 8 - 5));
+ apdu = new Put_Key_APDU (p[0], p[1], *data);
+ apdu->SetMAC (mac);
+ if (data != NULL)
+ {
+ delete data;
+ data = NULL;
+ }
+ }
+ else if (((BYTE *) apdu_data)[1] == 0x54)
+ {
+ /* Write_Object_APDU */
+ BYTE object_id[4];
+ object_id[0] = ((BYTE *) apdu_data)[5];
+ object_id[1] = ((BYTE *) apdu_data)[6];
+ object_id[2] = ((BYTE *) apdu_data)[7];
+ object_id[3] = ((BYTE *) apdu_data)[8];
+ mac = Buffer (apdu_data.substr (apdu_data.size () - 8, 8));
+ int offset =
+ (((BYTE *) apdu_data)[9] << 24) + (((BYTE *) apdu_data)[10] << 16) +
+ (((BYTE *) apdu_data)[11] << 8) + ((BYTE *) apdu_data)[12];
+ Buffer *data =
+ new Buffer (apdu_data.substr (14, apdu_data.size () - 8 - 11 - 3));
+ apdu = new Write_Object_APDU (object_id, offset, *data);
+ apdu->SetMAC (mac);
+ if (data != NULL)
+ {
+ delete data;
+ data = NULL;
+ }
+ }
+ else
+ {
+ /* error */
+ }
+ return apdu;
+}
+
+/**
+ * Retrieves message from the RA.
+ */
+RA_Msg *
+RA_Conn::ReadMsg (RA_Token * token)
+{
+ int len = 0;
+ char buf[4096];
+ PRInt32 rc;
+ int i;
+ char *msg_type_s = NULL;
+ int msg_type;
+ RA_Msg *msg = NULL;
+
+ if (!m_read_header)
+ {
+ ReadResponseHeader (m_fd);
+ m_read_header = 1;
+ }
+
+ /* read chunk size */
+ len = GetChunkSize (m_fd);
+ if (len <= 0)
+ {
+ return NULL;
+ }
+
+ for (i = 0; i < 4096; i++)
+ {
+ buf[i] = 0;
+ }
+
+ /* read chunk */
+ rc = GetChunk (m_fd, buf, len + 2);
+ if (rc <= 0)
+ {
+ return NULL;
+ }
+ buf[len] = '\0';
+
+ /* parse name value pair */
+ NameValueSet *params = NameValueSet::Parse (buf, "&");
+ if (params == NULL)
+ return NULL;
+ msg_type_s = params->GetValue (PARAM_MSG_TYPE);
+ if (msg_type_s == NULL)
+ {
+ if (params != NULL)
+ {
+ delete params;
+ params = NULL;
+ }
+ return NULL;
+ }
+ msg_type = atoi (msg_type_s);
+
+ if (msg_type == MSG_LOGIN_REQUEST)
+ {
+ msg =
+ new RA_Login_Request_Msg (atoi (params->GetValue (PARAM_INVALID_PW)),
+ atoi (params->GetValue (PARAM_BLOCKED)));
+ }
+ else if (msg_type == MSG_EXTENDED_LOGIN_REQUEST)
+ {
+ msg = new RA_Extended_Login_Request_Msg (0, 0, NULL, 0, NULL, NULL);
+ }
+ else if (msg_type == MSG_END_OP)
+ {
+ msg = new RA_End_Op_Msg ((RA_Op_Type)
+ atoi (params->GetValue (PARAM_OPERATION)),
+ atoi (params->GetValue (PARAM_RESULT)),
+ atoi (params->GetValue (PARAM_MESSAGE)));
+ }
+ else if (msg_type == MSG_SECUREID_REQUEST)
+ {
+ msg =
+ new
+ RA_SecureId_Request_Msg (atoi (params->GetValue (PARAM_PIN_REQUIRED)),
+ atoi (params->GetValue (PARAM_NEXT_VALUE)));
+ }
+ else if (msg_type == MSG_STATUS_UPDATE_REQUEST)
+ {
+ msg =
+ new
+ RA_Status_Update_Request_Msg (atoi
+ (params->
+ GetValue (PARAM_CURRENT_STATE)),
+ params->
+ GetValue (PARAM_NEXT_TASK_NAME));
+ }
+ else if (msg_type == MSG_ASQ_REQUEST)
+ {
+ msg = new RA_ASQ_Request_Msg (params->GetValue (PARAM_QUESTION));
+ }
+ else if (msg_type == MSG_NEW_PIN_REQUEST)
+ {
+ msg =
+ new
+ RA_New_Pin_Request_Msg (atoi
+ (params->GetValue (PARAM_MINIMUM_LENGTH)),
+ atoi (params->
+ GetValue (PARAM_MAXIMUM_LENGTH)));
+ }
+ else if (msg_type == MSG_TOKEN_PDU_REQUEST)
+ {
+ char *pdu_encoded = params->GetValue (PARAM_PDU_DATA);
+ Buffer *apdu_data = Util::URLDecode (pdu_encoded);
+
+#ifdef VERBOSE
+ Output ("ReadMsg: URLDecoded apdu = ");
+ printBuf (apdu_data);
+#endif
+
+ Buffer mac;
+ APDU *apdu = CreateAPDU (token, *apdu_data, mac);
+ msg = new RA_Token_PDU_Request_Msg (apdu);
+ if (apdu_data != NULL)
+ {
+ delete apdu_data;
+ apdu_data = NULL;
+ }
+ }
+ else
+ {
+ /* error */
+ if (params != NULL)
+ {
+ delete params;
+ params = NULL;
+ }
+ return NULL;
+ }
+
+ if (params != NULL)
+ {
+ delete params;
+ params = NULL;
+ }
+
+ return msg;
+}
+
+/**
+ * Terminates this connection.
+ */
+int
+RA_Conn::Close ()
+{
+ if (m_fd != NULL)
+ {
+ PR_Close (m_fd);
+ m_fd = NULL;
+ }
+ return 1;
+}
diff --git a/base/tps/tools/raclient/RA_Conn.h b/base/tps/tools/raclient/RA_Conn.h
new file mode 100644
index 000000000..307166eaf
--- /dev/null
+++ b/base/tps/tools/raclient/RA_Conn.h
@@ -0,0 +1,71 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_CONN_H
+#define RA_CONN_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include "prio.h"
+#include "RA_Token.h"
+#include "main/RA_Msg.h"
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+
+class RA_Conn
+{
+ public:
+ RA_Conn(char *host, int port, char *uri);
+ ~RA_Conn();
+ public:
+ int SendMsg(RA_Msg *msg);
+ RA_Msg *ReadMsg();
+ RA_Msg *ReadMsg(RA_Token *token);
+ int Connect();
+ int Close();
+ void setEncryption(bool encrypted);
+ bool isEncrypted();
+ public:
+ APDU *CreateAPDU(RA_Token *tok, Buffer &data, Buffer &mac);
+ private:
+ char *m_host;
+ int m_port;
+ char *m_uri;
+ PRFileDesc *m_fd;
+ int m_read_header;
+ bool m_encrypted_channel;
+};
+
+#endif /* RA_MSG_H */
diff --git a/base/tps/tools/raclient/RA_Token.cpp b/base/tps/tools/raclient/RA_Token.cpp
new file mode 100644
index 000000000..069d6c23c
--- /dev/null
+++ b/base/tps/tools/raclient/RA_Token.cpp
@@ -0,0 +1,2008 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; 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 ---
+
+#include "cryptohi.h"
+#include "plstr.h"
+#include "main/Util.h"
+#include "RA_Token.h"
+#include "apdu/APDU_Response.h"
+#include "apdu/Initialize_Update_APDU.h"
+#include "apdu/Generate_Key_APDU.h"
+#include "apdu/Put_Key_APDU.h"
+#include "apdu/Select_APDU.h"
+#include "apdu/Get_Data_APDU.h"
+#include "apdu/List_Objects_APDU.h"
+#include "apdu/Get_IssuerInfo_APDU.h"
+#include "apdu/Set_IssuerInfo_APDU.h"
+#include "apdu/Read_Object_APDU.h"
+#include "apdu/Get_Version_APDU.h"
+#include "apdu/Get_Status_APDU.h"
+#include "apdu/List_Pins_APDU.h"
+#include "apdu/Create_Pin_APDU.h"
+#include "keyhi.h"
+#include "nss.h"
+#include "cert.h"
+
+//#define VERIFY_PROOF
+
+static BYTE
+ToVal (char c)
+{
+ if (c >= '0' && c <= '9')
+ {
+ return c - '0';
+ }
+ else if (c >= 'A' && c <= 'Z')
+ {
+ return c - 'A' + 10;
+ }
+ else if (c >= 'a' && c <= 'z')
+ {
+ return c - 'a' + 10;
+ }
+
+ /* The following return is needed to suppress compiler warnings on Linux. */
+ return 0;
+}
+
+static Buffer *
+ToBuffer (char *input)
+{
+ int len = strlen (input) / 2;
+ BYTE *buffer = NULL;
+
+ buffer = (BYTE *) malloc (len);
+ if (buffer == NULL)
+ {
+ return NULL;
+ }
+
+ for (int i = 0; i < len; i++)
+ {
+ buffer[i] = (ToVal (input[i * 2]) * 16) + ToVal (input[i * 2 + 1]);
+ }
+ Buffer *j;
+ j = new Buffer (buffer, len);
+
+ if (buffer != NULL)
+ {
+ free (buffer);
+ buffer = NULL;
+ }
+
+ return j;
+}
+
+/**
+ * Constructs a virtual token.
+ */
+RA_Token::RA_Token ()
+{
+ m_session_key = NULL;
+ m_enc_session_key = NULL;
+ BYTE key_info[] = {
+ 0x01, 0x01
+ };
+ BYTE version[] = {
+ 0x00, 0x01, 0x02, 0x03
+ };
+ BYTE cuid[] = {
+ 0x00, 0x01, 0x02, 0x03,
+ 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09
+ };
+ BYTE msn[] = {
+ 0x00, 0x00, 0x00, 0x00
+ };
+ BYTE key[] = {
+ 0x40, 0x41, 0x42, 0x43,
+ 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b,
+ 0x4c, 0x4d, 0x4e, 0x4f
+ };
+
+ m_major_version = 0;
+ m_minor_version = 0;
+
+ /* default setting */
+ m_lifecycle_state = 0;
+ m_icv = Buffer (8, (BYTE) 0);
+ m_auth_key = Buffer (key, sizeof key);
+ m_mac_key = Buffer (key, sizeof key);
+ m_kek_key = Buffer (key, sizeof key);
+ m_cuid = Buffer (cuid, sizeof cuid);
+ m_msn = Buffer (msn, sizeof msn);
+ m_version = Buffer (version, sizeof version);
+ m_key_info = Buffer (key_info, sizeof key_info);
+ m_pin = PL_strdup ("password");
+ m_object_len = 0;
+ m_object = NULL;
+}
+
+
+/**
+ * Destructs token.
+ */
+RA_Token::~RA_Token ()
+{
+ if (m_pin != NULL)
+ {
+ PL_strfree (m_pin);
+ m_pin = NULL;
+ }
+ if (m_session_key != NULL)
+ {
+ PORT_Free (m_session_key);
+ m_session_key = NULL;
+ }
+ if (m_enc_session_key != NULL)
+ {
+ PORT_Free (m_enc_session_key);
+ m_enc_session_key = NULL;
+ }
+ if (m_object != NULL)
+ {
+ delete (m_object);
+ m_object = NULL;
+ }
+}
+
+RA_Token *
+RA_Token::Clone ()
+{
+ RA_Token *token = new RA_Token ();
+ token->m_icv = m_icv;
+ /*
+ token->m_session_key = m_session_key;
+ token->m_enc_session_key = m_enc_session_key;
+ */
+ token->m_session_key = NULL;
+ token->m_enc_session_key = NULL;
+ token->m_lifecycle_state = m_lifecycle_state;
+ token->m_auth_key = m_auth_key;
+ token->m_major_version = m_major_version;
+ token->m_minor_version = m_minor_version;
+ token->m_mac_key = m_mac_key;
+ token->m_kek_key = m_kek_key;
+ token->m_cuid = m_cuid;
+ token->m_version = m_version;
+ token->m_key_info = m_key_info;
+ PL_strfree (token->m_pin);
+ token->m_pin = PL_strdup (m_pin);
+ token->m_object_len = m_object_len;
+ return token;
+}
+
+static void
+Output (const char *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ printf ("Output> ");
+ vprintf (fmt, ap);
+ printf ("\n");
+ va_end (ap);
+}
+
+void
+printBuf (Buffer * buf)
+{
+ int sum = 0;
+
+ BYTE *data = *buf;
+ int i = 0;
+ if (buf->size () > 255)
+ {
+ Output ("printBuf: TOO BIG to print");
+ return;
+ }
+ Output ("Begin printing buffer =====");
+ for (i = 0; i < (int) buf->size (); i++)
+ {
+ printf ("%02x ", (unsigned char) data[i]);
+ sum++;
+ if (sum == 10)
+ {
+ printf ("\n");
+ sum = 0;
+ }
+ }
+ Output ("End printing buffer =====");
+}
+
+Buffer & RA_Token::GetCUID ()
+{
+ return m_cuid;
+}
+
+Buffer & RA_Token::GetMSN ()
+{
+ return m_msn;
+}
+
+void
+RA_Token::SetCUID (Buffer & cuid)
+{
+ m_cuid = cuid;
+}
+
+void
+RA_Token::SetMSN (Buffer & msn)
+{
+ m_msn = msn;
+}
+
+Buffer & RA_Token::GetAppletVersion ()
+{
+ return m_version;
+}
+
+void
+RA_Token::SetAppletVersion (Buffer & version)
+{
+ m_version = version;
+}
+
+void
+RA_Token::SetMajorVersion (int v)
+{
+ m_major_version = v;
+}
+
+void
+RA_Token::SetMinorVersion (int v)
+{
+ m_minor_version = v;
+}
+
+void
+RA_Token::SetAuthKey (Buffer & key)
+{
+ m_auth_key = key;
+}
+
+void
+RA_Token::SetMacKey (Buffer & key)
+{
+ m_mac_key = key;
+}
+
+void
+RA_Token::SetKekKey (Buffer & key)
+{
+ m_kek_key = key;
+}
+
+Buffer & RA_Token::GetKeyInfo ()
+{
+ return m_key_info;
+}
+
+void
+RA_Token::SetKeyInfo (Buffer & key_info)
+{
+ m_key_info = key_info;
+}
+
+int
+RA_Token::GetMajorVersion ()
+{
+ return m_major_version;
+}
+
+int
+RA_Token::GetMinorVersion ()
+{
+ return m_minor_version;
+}
+
+BYTE
+RA_Token::GetLifeCycleState ()
+{
+ return m_lifecycle_state;
+}
+
+char *
+RA_Token::GetPIN ()
+{
+ return m_pin;
+}
+
+Buffer & RA_Token::GetAuthKey ()
+{
+ return m_auth_key;
+}
+
+Buffer & RA_Token::GetMacKey ()
+{
+ return m_mac_key;
+}
+
+Buffer & RA_Token::GetKekKey ()
+{
+ return m_kek_key;
+}
+
+int
+RA_Token::NoOfPrivateKeys ()
+{
+ SECKEYPrivateKeyList *list = NULL;
+ SECKEYPrivateKeyListNode *node;
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot ();
+ int count;
+
+ list = PK11_ListPrivateKeysInSlot (slot);
+ for (count = 0, node = PRIVKEY_LIST_HEAD (list);
+ !PRIVKEY_LIST_END (node, list);
+ node = PRIVKEY_LIST_NEXT (node), count++)
+ {
+ /* nothing */
+ }
+ if (list != NULL)
+ {
+ SECKEY_DestroyPrivateKeyList (list);
+ list = NULL;
+ }
+
+ return count;
+}
+
+SECKEYPrivateKey *
+RA_Token::GetPrivateKey (int pos)
+{
+ SECKEYPrivateKeyList *list = NULL;
+ SECKEYPrivateKeyListNode *node;
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot ();
+ int count;
+
+ list = PK11_ListPrivateKeysInSlot (slot);
+ for (count = 0, node = PRIVKEY_LIST_HEAD (list);
+ !PRIVKEY_LIST_END (node, list);
+ node = PRIVKEY_LIST_NEXT (node), count++)
+ {
+ if (pos == count)
+ {
+ return node->key;
+ }
+ }
+ if (list != NULL)
+ {
+ SECKEY_DestroyPrivateKeyList (list);
+ list = NULL;
+ }
+
+ return NULL;
+}
+
+int
+RA_Token::NoOfCertificates ()
+{
+ CERTCertList *clist = NULL;
+ CERTCertListNode *cln;
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot ();
+ int count = 0;
+
+ clist = PK11_ListCertsInSlot (slot);
+ for (cln = CERT_LIST_HEAD (clist); !CERT_LIST_END (cln, clist);
+ cln = CERT_LIST_NEXT (cln))
+ {
+ count++;
+ }
+
+ return count;
+}
+
+CERTCertificate *
+RA_Token::GetCertificate (int pos)
+{
+ CERTCertList *clist = NULL;
+ CERTCertListNode *cln;
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot ();
+ int count = 0;
+
+ clist = PK11_ListCertsInSlot (slot);
+ for (cln = CERT_LIST_HEAD (clist); !CERT_LIST_END (cln, clist);
+ cln = CERT_LIST_NEXT (cln))
+ {
+ if (count == pos)
+ {
+ CERTCertificate *cert = cln->cert;
+ return cert;
+ }
+ count++;
+ }
+
+ return NULL;
+}
+
+void
+RA_Token::decryptMsg (Buffer & in_data, Buffer & out_data)
+{
+ Output ("RA_Token::decryptMsg: decryption about to proceed");
+
+ //add this header back later...does not include lc, since it might change
+ Buffer header = in_data.substr (0, 4);
+#ifdef VERBOSE
+ Output ("input data =");
+ printBuf (&in_data);
+ Output ("length = %d", in_data.size ());
+#endif
+
+ //add this mac back later
+ Buffer mac = in_data.substr (in_data.size () - 8, 8);
+
+#ifdef VERBOSE
+ Output ("mac=");
+ printBuf (&mac);
+#endif
+
+ // encrypted data area is the part without header and mac
+ Buffer enc_in_data = in_data.substr (5, in_data.size () - 8 - 5);
+
+#ifdef VERBOSE
+ Output ("RA_Token::decryptMsg: enc_in_data size: %d", enc_in_data.size ());
+ Output ("encrypted in_data =");
+ printBuf (&enc_in_data);
+#endif
+
+ Buffer d_apdu_data;
+ PRStatus status = Util::DecryptData (GetEncSessionKey (),
+ enc_in_data, d_apdu_data);
+#ifdef VERBOSE
+ Output ("RA_Token::decryptMsg: decrypted data size = %d, data=",
+ d_apdu_data.size ());
+ printBuf (&d_apdu_data);
+#endif
+
+ if (status == PR_SUCCESS)
+ {
+ Output ("RA_Token::decryptMsg: decrypt success");
+ }
+ else
+ {
+ Output ("RA_Token::decryptMsg: decrypt failure");
+ // return NULL;
+ }
+
+ /*
+ * the original (pre-encrypted) data would look like the following
+ * orig. Length | Data... | <80> | <padding>
+ * where orig. Length is one byte,
+ * if orig Length + 1byte length is multiple of 8,
+ * it wasn't padded
+ * if orig Length + 1byte length is not multiple of 8,
+ * '80' was appended to the right of data field
+ * if that was multiple was 8, it's done, otherwise
+ * it was padded with 0 until the data len is a multiple of 8
+ */
+ int origLen = (int) ((BYTE *) d_apdu_data)[0];
+ Output ("RA_Token::decryptMsg: origLen = %d", origLen);
+
+ Buffer orig_data;
+
+ // this should perfectly skip the paddings, if was any
+ orig_data = d_apdu_data.substr (1, origLen);
+ out_data = header;
+ out_data += Buffer (1, ((BYTE *) d_apdu_data)[0] + 0x08);
+ out_data += orig_data;
+ out_data += mac;
+
+#ifdef VERBOSE
+ Output ("decrypted pdu data:");
+ printBuf (&out_data);
+#endif
+}
+
+APDU_Response *
+RA_Token::ProcessInitializeUpdate (Initialize_Update_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+ BYTE requested_version = apdu->GetP1 ();
+ //BYTE requested_index = apdu->GetP2();
+ Buffer host_challenge = apdu->GetHostChallenge ();
+ m_host_challenge = host_challenge;
+// printf("Host Challenge: \n");
+// host_challenge.dump();
+
+ Buffer ki = GetKeyInfo ();
+ BYTE current_version = ((BYTE *) ki)[0];
+ //BYTE current_index = ((BYTE*)ki)[1];
+
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_iu_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_iu_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (requested_version != 0x00 && requested_version != current_version)
+ {
+ // return an error
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+
+ m_icv = Buffer (8, (BYTE) 0);
+
+ /**
+ * Initialize Update response:
+ * Key Diversification Data - 10 bytes
+ * Key Information Data - 2 bytes
+ * Card Challenge - 8 bytes
+ * Card Cryptogram - 8 bytes
+ */
+ Buffer card_challenge (8, (BYTE) 0);
+ Util::GetRandomChallenge (card_challenge);
+ m_card_challenge = card_challenge;
+
+ /* compute cryptogram */
+ Buffer icv = Buffer (8, (BYTE) 0);
+ Buffer input = host_challenge + card_challenge;
+ Buffer cryptogram (8, (BYTE) 0);
+
+ Buffer authkey = GetAuthKey ();
+ if (authkey == NULL)
+ {
+ return NULL;
+ }
+ PK11SymKey *encAuthKey = Util::DeriveKey (GetAuthKey (),
+ host_challenge, card_challenge);
+ Util::ComputeMAC (encAuthKey, input, icv, cryptogram);
+
+ // printf("Cryptogram: \n");
+ // cryptogram.dump();
+ //
+ // establish session key
+ m_session_key = CreateSessionKey (mac, m_card_challenge, m_host_challenge);
+ // establish Encryption session key
+ m_enc_session_key = CreateSessionKey (auth, m_card_challenge,
+ m_host_challenge);
+
+ Buffer data = GetCUID () + GetKeyInfo () +
+ card_challenge + cryptogram +
+ Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+
+ return apdu_resp;
+}
+
+int
+RA_Token::VerifyMAC (APDU * apdu)
+{
+ Buffer data;
+ Buffer mac = apdu->GetMAC ();
+
+ Output ("RA_Token::VerifyMAC: Begins==== apdu type =%d", apdu->GetType ());
+ if (mac.size () != 8)
+ {
+ Output ("RA_Token::VerifyMAC: no mac? ok");
+ return 1;
+ }
+
+ Buffer new_mac = Buffer (8, (BYTE) 0);
+
+ ComputeAPDUMac (apdu, new_mac);
+ if (new_mac != mac)
+ {
+#ifdef VERBOSE
+ Output ("old mac: ");
+ printBuf (&mac);
+ Output ("new mac: ");
+ printBuf (&new_mac);
+#endif
+ Output ("RA_Token::VerifyMAC: *** failed ***");
+ return 0;
+ }
+ else
+ {
+ Output ("RA_Token::VerifyMAC: passed");
+ return 1;
+ }
+}
+
+void
+RA_Token::ComputeAPDUMac (APDU * apdu, Buffer & new_mac)
+{
+ Buffer data;
+
+ apdu->GetDataToMAC (data);
+
+#ifdef VERBOSE
+ Output ("RA_Token::ComputeAPDUMac: data to mac =");
+ printBuf (&data);
+ Output ("RA_Token::ComputeAPDUMac: current m_icv =");
+ printBuf (&m_icv);
+#endif
+
+
+ Util::ComputeMAC (m_session_key, data, m_icv, new_mac);
+#ifdef VERBOSE
+ Output ("RA_Token::ComputeAPDUMac: got new mac =");
+#endif
+ printBuf (&new_mac);
+
+
+ m_icv = new_mac;
+} /* EncodeAPDUMac */
+
+PK11SymKey *
+RA_Token::GetEncSessionKey ()
+{
+ return m_enc_session_key;
+}
+
+PK11SymKey *
+RA_Token::CreateSessionKey (keyType keytype, Buffer & card_challenge,
+ Buffer & host_challenge)
+{
+ BYTE *key = NULL;
+ char input[16];
+ int i;
+ BYTE *cc = (BYTE *) card_challenge;
+ int cc_len = card_challenge.size ();
+ BYTE *hc = (BYTE *) host_challenge;
+ int hc_len = host_challenge.size ();
+
+ if (keytype == mac)
+ key = (BYTE *) m_mac_key;
+ else if (keytype == auth)
+ key = (BYTE *) m_auth_key;
+ else
+ key = (BYTE *) m_mac_key; // for now
+
+ /* copy card and host challenge into input buffer */
+ for (i = 0; i < 8; i++)
+ {
+ input[i] = cc[i];
+ }
+ for (i = 0; i < 8; i++)
+ {
+ input[8 + i] = hc[i];
+ }
+
+ PK11SymKey *session_key =
+ Util::DeriveKey (Buffer (key, 16), Buffer (hc, hc_len),
+ Buffer (cc, cc_len));
+
+ //printf("XXX mac key\n");
+ //m_mac_key.dump();
+ //printf("XXX card challenge\n");
+ //card_challenge.dump();
+ //printf("XXX host challenge\n");
+ //host_challenge.dump();
+ SECItem *data = PK11_GetKeyData (session_key);
+ Buffer db = Buffer (data->data, data->len);
+ // printf("session key:\n");
+ // db.dump();
+
+ return session_key;
+}
+
+APDU_Response *
+RA_Token::ProcessExternalAuthenticate (External_Authenticate_APDU * apdu,
+ NameValueSet * vars,
+ NameValueSet * params)
+{
+ Buffer host_cryptogram = apdu->GetHostCryptogram ();
+
+#ifdef VERBOSE
+ Output ("RA_Token::ProcessExternalAuthenticate");
+#endif
+ // printf("Host Cryptogram: \n");
+ // host_cryptogram.dump();
+
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_ea_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_ea_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+
+
+ Buffer data = Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+static int
+VerifyProof (SECKEYPublicKey * pk, SECItem * siProof,
+ unsigned short pkeyb_len, unsigned char *pkeyb,
+ Buffer * challenge)
+{
+ // this doesn't work, and not needed anymore
+ return 1;
+
+ int rs = 1;
+ unsigned short i = 0;
+ unsigned int j = 0;
+ unsigned char *chal = NULL;
+
+ VFYContext *vc = VFY_CreateContext (pk, siProof,
+ SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE,
+ NULL);
+ if (vc == NULL)
+ {
+ Output ("VerifyProof: CreateContext failed");
+ return 0; // error
+ }
+
+ SECStatus vs = VFY_Begin (vc);
+ if (vs == SECFailure)
+ {
+ rs = -1;
+ Output ("VerifyProof: Begin failed");
+ goto loser;
+ }
+ unsigned char proof[1024];
+
+ for (i = 0; i < pkeyb_len; i++)
+ {
+ proof[i] = pkeyb[i];
+ }
+ chal = (unsigned char *) (BYTE *) (*challenge);
+
+ for (j = 0; j < challenge->size (); i++, j++)
+ {
+ proof[i] = chal[j];
+ }
+ vs =
+ VFY_Update (vc, (unsigned char *) proof, pkeyb_len + challenge->size ());
+ if (vs == SECFailure)
+ {
+ rs = -1;
+ Output ("VerifyProof: Update failed");
+ goto loser;
+ }
+ vs = VFY_End (vc);
+ if (vs == SECFailure)
+ {
+ rs = -1;
+ Output ("VerifyProof: End failed");
+ goto loser;
+ }
+ else
+ {
+ Output ("VerifyProof good");
+ }
+
+loser:
+ if (vc != NULL)
+ {
+ VFY_DestroyContext (vc, PR_TRUE);
+ vc = NULL;
+ }
+ return rs;
+
+}
+
+static Buffer
+GetMusclePublicKeyData (SECKEYPublicKey * pubKey, int keylen)
+{
+ int i, j;
+
+ Buffer pk = Buffer (4 /* header len */ +
+ pubKey->u.rsa.modulus.len +
+ pubKey->u.rsa.publicExponent.len);
+
+ ((BYTE *) pk)[0] = 0; /* BLOB_ENC_PLAIN */
+ ((BYTE *) pk)[1] = 0x01; /* Public RSA Key */
+ ((BYTE *) pk)[2] = keylen / 256;
+ ((BYTE *) pk)[3] = keylen % 256;
+ ((BYTE *) pk)[4] = pubKey->u.rsa.modulus.len / 256;
+ ((BYTE *) pk)[5] = pubKey->u.rsa.modulus.len % 256;
+ for (i = 0; i < (int) pubKey->u.rsa.modulus.len; i++)
+ {
+ ((BYTE *) pk)[6 + i] = pubKey->u.rsa.modulus.data[i];
+ }
+ ((BYTE *) pk)[i++] = pubKey->u.rsa.publicExponent.len / 256;
+ ((BYTE *) pk)[i++] = pubKey->u.rsa.publicExponent.len % 256;
+ for (j = 0; j < (int) pubKey->u.rsa.publicExponent.len; j++)
+ {
+ ((BYTE *) pk)[i++] = pubKey->u.rsa.publicExponent.data[j];
+ }
+ return pk;
+}
+
+static Buffer
+Sign (SECKEYPrivateKey * privKey, Buffer & blob)
+{
+ SECStatus status;
+
+ SECItem sigitem;
+ int signature_len;
+
+ signature_len = PK11_SignatureLen (privKey);
+ sigitem.len = signature_len;
+ sigitem.data = (unsigned char *) PORT_Alloc (signature_len);
+
+ status = SEC_SignData (&sigitem, (BYTE *) blob, blob.size (), privKey,
+ SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE);
+ if (status != SECSuccess)
+ {
+ printf ("Signing error\n");
+ if (sigitem.data != NULL)
+ {
+ PORT_Free (sigitem.data);
+ sigitem.data = NULL;
+ }
+ return Buffer (16, (BYTE) 0); // sucks
+ }
+
+ Buffer proof = Buffer (sigitem.data, signature_len);
+ if (sigitem.data != NULL)
+ {
+ PORT_Free (sigitem.data);
+ sigitem.data = NULL;
+ }
+ return proof;
+}
+
+static Buffer
+GetKeyBlob (int keysize, SECKEYPublicKey * pubKey)
+{
+ Buffer blob = Buffer (1, (BYTE) 0) + /* encoding */
+ Buffer (1, (BYTE) 1) + /* key type */
+ Buffer (1, (BYTE) (keysize >> 8) & 0xff) + /* key size */
+ Buffer (1, (BYTE) keysize & 0xff) + /* key size */
+ Buffer (1, (BYTE) (pubKey->u.rsa.modulus.len >> 8) & 0xff) +
+ Buffer (1, (BYTE) pubKey->u.rsa.modulus.len & 0xff) +
+ Buffer ((BYTE *) pubKey->u.rsa.modulus.data, pubKey->u.rsa.modulus.len) +
+ Buffer (1, (BYTE) (pubKey->u.rsa.publicExponent.len >> 8) & 0xff) +
+ Buffer (1, (BYTE) pubKey->u.rsa.publicExponent.len & 0xff) +
+ Buffer ((BYTE *) pubKey->u.rsa.publicExponent.data,
+ pubKey->u.rsa.publicExponent.len);
+ return blob;
+}
+
+static Buffer
+GetSignBlob (Buffer & muscle_public_key, Buffer & challenge)
+{
+ int i, j;
+
+ Buffer data = Buffer (muscle_public_key.size () +
+ challenge.size (), (BYTE) 0);
+ for (i = 0; i < (int) muscle_public_key.size (); i++)
+ {
+ ((BYTE *) data)[i] = ((BYTE *) muscle_public_key)[i];
+ }
+ for (j = 0; j < (int) challenge.size (); j++, i++)
+ {
+ ((BYTE *) data)[i] = ((BYTE *) challenge)[j];
+ }
+ return data;
+}
+
+APDU_Response *
+RA_Token::ProcessGenerateKey (Generate_Key_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+ CK_MECHANISM_TYPE mechanism;
+ SECOidTag algtag;
+ PK11RSAGenParams rsaparams;
+ void *x_params;
+ SECKEYPrivateKey *privKey;
+ SECKEYPublicKey *pubKey;
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot ();
+ int publicExponent = 0x010001;
+ int buffer_size;
+ // RA::Debug( LL_PER_PDU,
+ // "RA_Token::ProcessGenerateKey: ",
+ // "=====ProcessGenerateKey():in ProcessGenerateKey====" );
+
+ // for testing only
+#ifdef VERBOSE
+ Output ("RA_Token::ProcessGenerateKey");
+#endif
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_gk_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_gk_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+
+ Buffer req = apdu->GetData ();
+ BYTE *raw = (BYTE *) req;
+ // BYTE alg = (BYTE)req[5];
+ int keysize = (((BYTE *) req)[1] << 8) + ((BYTE *) req)[2];
+// printf("Requested key size %d\n", keysize);
+
+ int wrapped_challenge_len = ((BYTE *) req)[5];
+// printf("Challenged Size=%d\n", wrapped_challenge_len);
+ Buffer wrapped_challenge = Buffer ((BYTE *) & raw[6],
+ wrapped_challenge_len);
+
+ rsaparams.keySizeInBits = keysize;
+ rsaparams.pe = publicExponent;
+ mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
+ algtag = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;
+ x_params = &rsaparams;
+
+ /* generate key pair */
+ char *keygen_param = params->GetValue ("keygen");
+ if (keygen_param == NULL || (strcmp (keygen_param, "true") == 0))
+ {
+ privKey = PK11_GenerateKeyPair (slot, mechanism,
+ x_params, &pubKey,
+ PR_FALSE /*isPerm */ ,
+ PR_TRUE /*isSensitive */ ,
+ NULL /*wincx */ );
+ if (privKey == NULL)
+ {
+ // printf("privKey == NULL\n");
+ buffer_size = 1024; /* testing */
+ }
+ else
+ {
+
+ /* put key in the buffer */
+ // printf("modulus len %d\n", pubKey->u.rsa.modulus.len);
+ // printf("exponent len %d\n", pubKey->u.rsa.publicExponent.len);
+
+ Buffer blob = GetKeyBlob (keysize, pubKey);
+
+/*
+ * The key generation operation creates a proof-of-location for the
+ * newly generated key. This proof is a signature computed with the
+ * new private key using the RSA-with-MD5 signature algorithm. The
+ * signature is computed over the Muscle Key Blob representation of
+ * the new public key and the challenge sent in the key generation
+ * request. These two data fields are concatenated together to form
+ * the input to the signature, without any other data or length fields.
+ */
+
+ Buffer challenge = Buffer (16, (BYTE) 0x00);
+ // printf("Encrypted Enrollment Challenge:\n");
+ // wrapped_challenge.dump();
+ Util::DecryptData (m_kek_key, wrapped_challenge, challenge);
+
+// printf("Enrollment Challenge:\n");
+// challenge.dump();
+// printf("after challenge dump");
+ Buffer muscle_public_key = GetMusclePublicKeyData (pubKey, keysize);
+// printf("after muscle_public_key get, muscle_public_key size=%d", muscle_public_key.size());
+ Buffer data_blob = GetSignBlob ( /*muscle_public_key */ blob,
+ challenge);
+// printf("after getsignblob, blob size =%d",blob.size());
+ Buffer proof = Sign (privKey, data_blob);
+// printf("begin verifying proof");
+ unsigned char *pkeyb = (unsigned char *) (BYTE *) data_blob;
+ int pkeyb_len = data_blob.size ();
+
+ SECItem siProof;
+ siProof.type = (SECItemType) 0;
+ siProof.data = (unsigned char *) proof;
+ siProof.len = proof.size ();
+
+ // int size = data_blob.size();
+ // RA::Debug( LL_PER_PDU,
+ // "RA_Token::ProcessGenerateKey: ",
+ // "==== proof size =%d, data_blob size=%d",
+ // siProof.len,
+ // data_blob.size() );
+ // RA::Debug( LL_PER_PDU,
+ // "RA_Token::ProcessGenerateKey: ",
+ // "==== === printing blob. size=%d",
+ // size );
+ // RA::Debug( LL_PER_PDU,
+ // "RA_Token::ProcessGenerateKey: ",
+ // "pubKey->u.rsa.publicExponent.data[37] =%d",
+ // pubKey->u.rsa.publicExponent.data[37] );
+
+ if (VerifyProof (pubKey, &siProof, pkeyb_len, pkeyb, &challenge) !=
+ 1)
+ {
+
+ Output ("VerifyProof failed");
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+
+ }
+
+ m_buffer =
+ Buffer (1, (BYTE) (blob.size () / 256)) +
+ Buffer (1, (BYTE) (blob.size () % 256)) +
+ Buffer (blob) +
+ Buffer (1, (BYTE) (proof.size () / 256)) +
+ Buffer (1, (BYTE) (proof.size () % 256)) + Buffer (proof);
+ buffer_size = m_buffer.size ();
+ } // if private key not NULL
+
+ }
+ else
+ {
+ // fake key
+ BYTE fake_key[] = {
+ 0x00, 0x8b, 0x00, 0x01, 0x04, 0x00, 0x00, 0x80, 0x9f, 0xf9,
+ 0x6e, 0xa6, 0x6c, 0xd9, 0x4b, 0x5c, 0x1a, 0xb6, 0xd8, 0x78,
+ 0xd2, 0xaf, 0x45, 0xd5, 0xce, 0x8a, 0xee, 0x69, 0xfc, 0xdb,
+ 0x16, 0x21, 0x46, 0x61, 0xb9, 0x91, 0x5d, 0xa8, 0x41, 0x3f,
+ 0x5c, 0xce, 0xce, 0x16, 0x0b, 0xc3, 0x16, 0x99, 0xb7, 0x81,
+ 0xe9, 0x9c, 0xe5, 0x31, 0x04, 0x6d, 0xab, 0xb2, 0xa3, 0xac,
+ 0x91, 0x2b, 0xbd, 0x9b, 0x48, 0xa8, 0xd7, 0xd8, 0x34, 0x67,
+ 0x4d, 0x58, 0xd3, 0xb9, 0x81, 0x4f, 0x8c, 0xf1, 0x2c, 0x92,
+ 0xfa, 0xe7, 0x98, 0x72, 0xea, 0x52, 0xbb, 0x43, 0x73, 0x9e,
+ 0x88, 0xdc, 0x6c, 0x44, 0xf3, 0x6d, 0xfd, 0x36, 0xa6, 0x5c,
+ 0x61, 0x7d, 0x88, 0x51, 0xc7, 0x32, 0x14, 0x64, 0xf3, 0xe0,
+ 0x6f, 0xfa, 0x86, 0x1d, 0xad, 0x6c, 0xdb, 0x8a, 0x1c, 0x30,
+ 0xb2, 0x46, 0x26, 0xba, 0x3c, 0x71, 0x2c, 0x03, 0x45, 0x97,
+ 0x7f, 0xb0, 0x10, 0x24, 0xf4, 0x45, 0x00, 0x03, 0x01, 0x00,
+ 0x01, 0x00, 0x80, 0x58, 0x06, 0x40, 0x4e, 0x05, 0xd8, 0x54,
+ 0x87, 0xb1, 0x5b, 0xfc, 0x67, 0x95, 0xe5
+ };
+ m_buffer = Buffer ((BYTE *) fake_key, sizeof fake_key);
+ buffer_size = m_buffer.size ();
+ }
+
+
+ Buffer data = Buffer (1, (BYTE) (buffer_size >> 8) & 0xff) + // key length
+ Buffer (1, (BYTE) buffer_size & 0xff) + // key length
+ Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessCreateObject (Create_Object_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+ Buffer inputdata;
+ m_chunk_len = 0;
+ m_object_len = 0;
+
+#ifdef VERBOSE
+ Output ("RA_Token::ProcessCreateObject");
+#endif
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_co_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_co_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+
+ inputdata = apdu->GetData ();
+// inputdata.dump();
+ m_objectid[0] = (char) (((BYTE *) inputdata)[0]);
+ m_objectid[1] = (char) (((BYTE *) inputdata)[1]);
+ m_objectid[2] = '\0';
+
+// skip permissions
+
+ m_object_len += (((BYTE *) inputdata)[4]) << 24;
+ m_object_len += (((BYTE *) inputdata)[5]) << 16;
+ m_object_len += (((BYTE *) inputdata)[6]) << 8;
+ m_object_len += ((BYTE *) inputdata)[7];
+
+ Buffer data = Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ if (m_object != NULL)
+ {
+ delete m_object;
+ m_object = NULL;
+ }
+ m_object = new Buffer (m_object_len, (BYTE) 0);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessLifecycle (Lifecycle_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+
+#ifdef VERBOSE
+ Output ("RA_Token::ProcessLifecycle");
+#endif
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_lc_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_lc_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+ Buffer data = Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessDeleteFile (Delete_File_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+#ifdef VERBOSE
+ Output ("RA_Token::ProcessDeleteFile");
+#endif
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_df_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_df_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+
+ Buffer data = Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessInstallApplet (Install_Applet_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+#ifdef VERBOSE
+ Output ("RA_Token::InstallApplet");
+#endif
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_ia_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_ia_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+
+ Buffer data = Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessInstallLoad (Install_Load_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+#ifdef VERBOSE
+ Output ("RA_Token::InstallLoad");
+#endif
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_il_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_il_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+
+ Buffer data = Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessLoadFile (Load_File_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+#ifdef VERBOSE
+ Output ("RA_Token::ProcessLoadFile");
+#endif
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_lf_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_lf_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+
+ Buffer data = Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessFormatMuscleApplet (Format_Muscle_Applet_APDU * apdu,
+ NameValueSet * vars,
+ NameValueSet * params)
+{
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+ Buffer data = Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessSelect (Select_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_se_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_se_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+ Buffer data = Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessListPins (List_Pins_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_lp_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_lp_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+ Buffer data = m_version + Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessGetIssuerInfo (Get_IssuerInfo_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_cp_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_cp_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+
+ Buffer data = m_version + Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessSetIssuerInfo (Set_IssuerInfo_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_cp_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_cp_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+
+ Buffer data = m_version + Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessCreatePin (Create_Pin_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_cp_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_cp_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+
+ Buffer data = m_version + Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessGetVersion (Get_Version_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_gv_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_gv_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+
+ Buffer data = m_version + Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessGetData (Get_Data_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_gd_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_gd_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+
+ Buffer data =
+ Buffer (1, (BYTE) 0x01) + Buffer (1, (BYTE) 0x00) +
+ Buffer (1, (BYTE) 0x01) +
+ m_cuid.substr (0, 4) +
+ Buffer (1, (BYTE) 0x01) + Buffer (1, (BYTE) 0x00) +
+ Buffer (1, (BYTE) 0x01) + Buffer (1, (BYTE) 0x00) +
+ Buffer (1, (BYTE) 0x01) + Buffer (1, (BYTE) 0x00) +
+ Buffer (1, (BYTE) 0x01) + Buffer (1, (BYTE) 0x00) +
+ m_cuid.substr (6, 4) +
+ m_cuid.substr (4, 2) +
+ Buffer (1, (BYTE) 0x01) + Buffer (1, (BYTE) 0x00) +
+ Buffer (1, (BYTE) 0x01) + Buffer (1, (BYTE) 0x00) +
+ Buffer (1, (BYTE) 0x00) + Buffer (1, (BYTE) 0x00) +
+ Buffer (1, (BYTE) 0x01) + Buffer (1, (BYTE) 0x00) +
+ Buffer (1, (BYTE) 0x01) + Buffer (1, (BYTE) 0x00) +
+ Buffer (1, (BYTE) 0x01) + Buffer (1, (BYTE) 0x00) +
+ Buffer (1, (BYTE) 0x01) + Buffer (1, (BYTE) 0x00) +
+ Buffer (1, (BYTE) 0x00) + Buffer (1, (BYTE) 0x00) +
+ Buffer (1, (BYTE) 0x01) + Buffer (1, (BYTE) 0x00) +
+ Buffer (1, (BYTE) 0x01) + Buffer (1, (BYTE) 0x00) +
+ m_msn.substr (0, 4) + Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessGetStatus (Get_Status_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_gs_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_gs_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+
+ //Return a reasonable value for available applet memory.
+ //Free mem - 8192
+ //Tot mem - 8447
+ BYTE free_mem_high = 0x20;
+ BYTE free_mem_low = 0x00;
+ BYTE tot_mem_high = 0x20;
+ BYTE tot_mem_low = 0xff;
+ Buffer data =
+ Buffer (1, (BYTE) m_major_version) + Buffer (1, (BYTE) m_minor_version) +
+ Buffer (1, (BYTE) 0x00) + Buffer (1, (BYTE) 0x00) +
+ Buffer (1, (BYTE) 0x01) + Buffer (1, (BYTE) 0x00) +
+ Buffer (1, (BYTE) tot_mem_high) + Buffer (1, (BYTE) tot_mem_low) +
+ Buffer (1, (BYTE) 0x01) + Buffer (1, (BYTE) 0x00) +
+ Buffer (1, (BYTE) free_mem_high) + Buffer (1, (BYTE) free_mem_low) +
+ Buffer (1, (BYTE) 0x01) + Buffer (1, (BYTE) 0x00) +
+ Buffer (1, (BYTE) 0x01) + Buffer (1, (BYTE) 0x00) +
+ Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessPutKey (Put_Key_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+#ifdef VERBOSE
+ Output ("RA_Token::ProcessPutKey");
+#endif
+ Buffer key_set_data = apdu->GetData ();
+ BYTE current_version = ((BYTE *) key_set_data)[0];
+ BYTE current_index = (apdu->GetP2 () & 0x0f);
+
+ BYTE ki[2] = { current_version, current_index };
+ Buffer kib (ki, 2);
+ SetKeyInfo (kib);
+
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_pk_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_pk_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+
+ //BYTE new_version = key_set_data[0];
+ Buffer e_auth = key_set_data.substr (3, 16);
+ Buffer e_mac = key_set_data.substr (25, 16);
+ Buffer e_kek = key_set_data.substr (47, 16);
+
+ // need to retrieve the old kek, and decrypt the data
+ // with it
+ Buffer auth;
+ Buffer mac;
+ Buffer kek;
+ Util::DecryptData (m_kek_key, e_auth, auth);
+ Util::DecryptData (m_kek_key, e_mac, mac);
+ Util::DecryptData (m_kek_key, e_kek, kek);
+
+ m_kek_key = kek;
+ m_mac_key = mac;
+ m_auth_key = auth;
+
+ Buffer data = Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessImportKeyEnc (Import_Key_Enc_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+#ifdef VERBOSE
+ Output ("RA_Token::ProcessImportKeyEnc");
+#endif
+ Buffer data;
+
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_ik_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_ik_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+ data = apdu->GetData ();
+
+ data = Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessReadBuffer (Read_Buffer_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+ Buffer buffer;
+
+#ifdef VERBOSE
+ Output ("RA_Token::ProcessReadBuffer");
+#endif
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_rb_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_rb_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+
+ int len = apdu->GetLen ();
+ int offset = apdu->GetOffset ();
+
+ if (offset + len <= (int) m_buffer.size ())
+ {
+ buffer = m_buffer.substr (offset, len);
+ }
+ else
+ {
+ Output ("TESTING offset = %d, len = %d, m_buffer.size = %d",
+ offset, len, m_buffer.size ());
+ buffer = Buffer (len, (BYTE) 0); /* for testing */
+ }
+ Buffer data = buffer + Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessUnblockPin (Unblock_Pin_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+#ifdef VERBOSE
+ Output ("RA_Token::ProcessUnblockPin");
+#endif
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_up_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_up_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+ Buffer data = Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessListObjects (List_Objects_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_lo_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_lo_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+
+ Buffer data = Buffer (1, (BYTE) 0x9C) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessReadObject (Read_Object_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+ Buffer buffer;
+
+#ifdef VERBOSE
+ Output ("RA_Token::ProcessReadObject");
+#endif
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_ro_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_ro_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+
+ Buffer buf = apdu->GetData();
+ int len = ((BYTE*)buf)[8];
+ int offset = (((BYTE*)buf)[4] << 24) + (((BYTE*)buf)[5] << 16) +
+ (((BYTE*)buf)[6] << 8) + ((BYTE*)buf)[7];
+
+ if (offset + len <= (int) m_buffer.size ())
+ {
+ buffer = m_buffer.substr (offset, len);
+ }
+ else
+ {
+ Output ("TESTING offset = %d, len = %d, m_buffer.size = %d",
+ offset, len, m_buffer.size ());
+ buffer = Buffer (len, (BYTE) 0); /* for testing */
+ }
+
+ Buffer data = buffer + Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessWriteBuffer (Write_Object_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+#ifdef VERBOSE
+ Output ("RA_Token::ProcessWriteBuffer");
+#endif
+#define MAX_WRITE_BUFFER_SIZE 0x40
+ int num = 0;
+ int rv = -1;
+ int index = MAX_WRITE_BUFFER_SIZE + 2;
+ PK11SlotInfo *slot;
+ CERTCertificate *cert = NULL;
+
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_wb_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_wb_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+ Buffer inputdata = apdu->GetData ();
+ num = m_object_len - m_chunk_len;
+ if (num > MAX_WRITE_BUFFER_SIZE)
+ {
+ for (int i = 2; i < index; i++)
+ {
+ BYTE data = ((BYTE *) inputdata)[i];
+ ((BYTE *) * m_object)[m_chunk_len] = data;
+ m_chunk_len++;
+ }
+ }
+ else
+ {
+ for (int i = 2; i < num + 2; i++)
+ {
+ ((BYTE *) * m_object)[m_chunk_len] = ((BYTE *) inputdata)[i];
+ m_chunk_len++;
+ }
+
+ if (strcmp (m_objectid, "C0") == 0)
+ {
+ // printf("RA_Token::ProcessWriteBuffer objectid = %s\n", m_objectid);
+ // we got the whole certificate, import to the db.
+ cert = CERT_DecodeCertFromPackage ((char *) ((BYTE *) * m_object),
+ m_object->size ());
+ if (cert == NULL)
+ {
+ // printf("cert is NULL\n");
+ }
+ else
+ {
+ slot = PK11_GetInternalKeySlot ();
+
+ rv = PK11_Authenticate (slot, PR_TRUE, NULL);
+ if (rv != SECSuccess)
+ {
+ // printf("Failed to authenticate to the internal token\n");
+ }
+ else
+ {
+ rv = PK11_ImportCert (slot, cert, CK_INVALID_HANDLE,
+ (char *) "testcert", PR_FALSE);
+ if (rv != SECSuccess)
+ {
+ printf
+ ("Failed to import the cert to the internal token\n");
+ }
+ }
+ }
+ }
+ }
+
+ Buffer data = Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::ProcessSetPin (Set_Pin_APDU * apdu,
+ NameValueSet * vars, NameValueSet * params)
+{
+ Buffer new_pin_buf = apdu->GetNewPIN ();
+#ifdef VERBOSE
+ Output ("RA_Token::ProcessSetPin");
+#endif
+
+ // for testing only
+ if (vars->GetValueAsBool("test_enable", 0) == 1) {
+ if (vars->GetValueAsBool("test_apdu_sp_return_enable", 0) == 1) {
+ Buffer *data = ToBuffer (vars->GetValue ("test_apdu_sp_return"));
+ APDU_Response *apdu_resp = new APDU_Response (*data);
+ return apdu_resp;
+ }
+ }
+
+ if (VerifyMAC (apdu) != 1)
+ {
+ Buffer data = Buffer (1, (BYTE) 0x6a) + Buffer (1, (BYTE) 0x88);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+ }
+#if 0
+ printf ("New PIN: \n");
+ new_pin_buf.dump ();
+#endif
+
+ /* replace current pin */
+ int i;
+ char *new_pin = (char *) malloc (new_pin_buf.size () + 1);
+ for (i = 0; i < (int) new_pin_buf.size (); i++)
+ {
+ new_pin[i] = ((BYTE *) new_pin_buf)[i];
+ }
+ new_pin[new_pin_buf.size ()] = '\0';
+
+ if (m_pin != NULL)
+ {
+ PL_strfree (m_pin);
+ m_pin = NULL;
+ }
+ m_pin = new_pin;
+
+ Buffer data = Buffer (1, (BYTE) 0x90) + Buffer (1, (BYTE) 0x00);
+ APDU_Response *apdu_resp = new APDU_Response (data);
+ return apdu_resp;
+}
+
+APDU_Response *
+RA_Token::Process (APDU * apdu, NameValueSet * vars, NameValueSet * params)
+{
+ APDU_Response *resp = NULL;
+
+ if (apdu->GetType () == APDU_INITIALIZE_UPDATE)
+ {
+ resp = ProcessInitializeUpdate ((Initialize_Update_APDU *) apdu, vars,
+ params);
+ }
+ else if (apdu->GetType () == APDU_EXTERNAL_AUTHENTICATE)
+ {
+ resp = ProcessExternalAuthenticate ((External_Authenticate_APDU *) apdu,
+ vars, params);
+ }
+ else if (apdu->GetType () == APDU_SET_PIN)
+ {
+ resp = ProcessSetPin ((Set_Pin_APDU *) apdu, vars, params);
+ }
+ else if (apdu->GetType () == APDU_LOAD_FILE)
+ {
+ resp = ProcessLoadFile ((Load_File_APDU *) apdu, vars, params);
+ }
+ else if (apdu->GetType () == APDU_FORMAT_MUSCLE_APPLET)
+ {
+ resp = ProcessFormatMuscleApplet ((Format_Muscle_Applet_APDU *) apdu,
+ vars, params);
+ }
+ else if (apdu->GetType () == APDU_INSTALL_LOAD)
+ {
+ resp = ProcessInstallLoad ((Install_Load_APDU *) apdu, vars, params);
+ }
+ else if (apdu->GetType () == APDU_INSTALL_APPLET)
+ {
+ resp = ProcessInstallApplet ((Install_Applet_APDU *) apdu, vars,
+ params);
+ }
+ else if (apdu->GetType () == APDU_DELETE_FILE)
+ {
+ resp = ProcessDeleteFile ((Delete_File_APDU *) apdu, vars, params);
+ }
+ else if (apdu->GetType () == APDU_CREATE_OBJECT)
+ {
+ resp = ProcessCreateObject ((Create_Object_APDU *) apdu, vars, params);
+ }
+ else if (apdu->GetType () == APDU_LIFECYCLE)
+ {
+ resp = ProcessLifecycle ((Lifecycle_APDU *) apdu, vars, params);
+ }
+ else if (apdu->GetType () == APDU_READ_BUFFER)
+ {
+ resp = ProcessReadBuffer ((Read_Buffer_APDU *) apdu, vars, params);
+ }
+ else if (apdu->GetType () == APDU_UNBLOCK_PIN)
+ {
+ resp = ProcessUnblockPin ((Unblock_Pin_APDU *) apdu, vars, params);
+ }
+ else if (apdu->GetType () == APDU_LIST_OBJECTS)
+ {
+ resp = ProcessListObjects ((List_Objects_APDU *) apdu, vars, params);
+ }
+ else if (apdu->GetType () == APDU_READ_OBJECT)
+ {
+ resp = ProcessReadObject ((Read_Object_APDU *) apdu, vars, params);
+ }
+ else if (apdu->GetType () == APDU_WRITE_OBJECT)
+ {
+ resp = ProcessWriteBuffer ((Write_Object_APDU *) apdu, vars, params);
+ }
+ else if (apdu->GetType () == APDU_SELECT)
+ {
+ resp = ProcessSelect ((Select_APDU *) apdu, vars, params);
+ }
+ else if (apdu->GetType () == APDU_GET_VERSION)
+ {
+ resp = ProcessGetVersion ((Get_Version_APDU *) apdu, vars, params);
+ }
+ else if (apdu->GetType () == APDU_PUT_KEY)
+ {
+ resp = ProcessPutKey ((Put_Key_APDU *) apdu, vars, params);
+ }
+ else if (apdu->GetType () == APDU_GET_STATUS)
+ {
+ resp = ProcessGetStatus ((Get_Status_APDU *) apdu, vars, params);
+ }
+ else if (apdu->GetType () == APDU_GET_ISSUERINFO)
+ {
+ resp = ProcessGetIssuerInfo ((Get_IssuerInfo_APDU *) apdu, vars, params);
+ }
+ else if (apdu->GetType () == APDU_SET_ISSUERINFO)
+ {
+ resp = ProcessSetIssuerInfo ((Set_IssuerInfo_APDU *) apdu, vars, params);
+ }
+ else if (apdu->GetType () == APDU_GET_DATA)
+ {
+ resp = ProcessGetData ((Get_Data_APDU *) apdu, vars, params);
+ }
+ else if (apdu->GetType () == APDU_LIST_PINS)
+ {
+ resp = ProcessListPins ((List_Pins_APDU *) apdu, vars, params);
+ }
+ else if (apdu->GetType () == APDU_CREATE_PIN)
+ {
+ resp = ProcessCreatePin ((Create_Pin_APDU *) apdu, vars, params);
+ }
+ else if (apdu->GetType () == APDU_GENERATE_KEY)
+ {
+ resp = ProcessGenerateKey ((Generate_Key_APDU *) apdu, vars, params);
+ }
+ else if (apdu->GetType () == APDU_IMPORT_KEY_ENC)
+ {
+ resp = ProcessImportKeyEnc ((Import_Key_Enc_APDU *) apdu, vars, params);
+ }
+ else
+ {
+ printf ("RA_Token: Unknown APDU (%d)\n", apdu->GetType ());
+ /* error */
+ }
+ return resp;
+}
diff --git a/base/tps/tools/raclient/RA_Token.h b/base/tps/tools/raclient/RA_Token.h
new file mode 100644
index 000000000..bf92e4e89
--- /dev/null
+++ b/base/tps/tools/raclient/RA_Token.h
@@ -0,0 +1,225 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifndef RA_TOKEN_H
+#define RA_TOKEN_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include "main/Buffer.h"
+#include "main/NameValueSet.h"
+#include "apdu/APDU_Response.h"
+#include "apdu/APDU.h"
+#include "apdu/Initialize_Update_APDU.h"
+#include "apdu/External_Authenticate_APDU.h"
+#include "apdu/Set_Pin_APDU.h"
+#include "apdu/Get_Status_APDU.h"
+#include "apdu/Create_Object_APDU.h"
+#include "apdu/Lifecycle_APDU.h"
+#include "apdu/Read_Buffer_APDU.h"
+#include "apdu/Get_IssuerInfo_APDU.h"
+#include "apdu/Set_IssuerInfo_APDU.h"
+#include "apdu/Load_File_APDU.h"
+#include "apdu/Format_Muscle_Applet_APDU.h"
+#include "apdu/Install_Applet_APDU.h"
+#include "apdu/Install_Load_APDU.h"
+#include "apdu/Unblock_Pin_APDU.h"
+#include "apdu/Write_Object_APDU.h"
+#include "apdu/Read_Object_APDU.h"
+#include "apdu/List_Pins_APDU.h"
+#include "apdu/List_Objects_APDU.h"
+#include "apdu/Create_Pin_APDU.h"
+#include "apdu/Generate_Key_APDU.h"
+#include "apdu/Select_APDU.h"
+#include "apdu/Delete_File_APDU.h"
+#include "apdu/Get_Version_APDU.h"
+#include "apdu/Get_Data_APDU.h"
+#include "apdu/Put_Key_APDU.h"
+#include "apdu/Import_Key_APDU.h"
+#include "apdu/Import_Key_Enc_APDU.h"
+
+typedef enum {
+ auth,
+ mac,
+ kek
+ } keyType;
+
+class RA_Token
+{
+ public:
+ RA_Token();
+ ~RA_Token();
+ public:
+ char *GetPIN();
+ Buffer &GetAuthKey();
+ Buffer &GetMacKey();
+ Buffer &GetKekKey();
+ Buffer &GetAppletVersion();
+ void SetAppletVersion(Buffer &version);
+ Buffer &GetCUID();
+ void SetCUID(Buffer &cuid);
+ Buffer &GetMSN();
+ void SetMSN(Buffer &msn);
+ Buffer &GetKeyInfo();
+ int GetMajorVersion();
+ int GetMinorVersion();
+ void SetKeyInfo(Buffer &key_info);
+ void SetAuthKey(Buffer &key);
+ void SetMacKey(Buffer &key);
+ void SetKekKey(Buffer &key);
+ void SetMajorVersion(int v);
+ void SetMinorVersion(int v);
+ BYTE GetLifeCycleState();
+ public:
+ int VerifyMAC(APDU *apdu);
+ void ComputeAPDUMac(APDU *apdu, Buffer &new_mac);
+ PK11SymKey *CreateSessionKey(keyType keytype,
+ Buffer &card_challenge,
+ Buffer &host_challenge);
+ RA_Token *Clone();
+ void decryptMsg(Buffer &in_data, Buffer &out_data);
+ PK11SymKey *GetEncSessionKey();
+ public:
+ int NoOfCertificates();
+ CERTCertificate *GetCertificate(int pos);
+ int NoOfPrivateKeys();
+ SECKEYPrivateKey *GetPrivateKey(int pos);
+ public:
+ APDU_Response *Process(APDU *apdu, NameValueSet *vars, NameValueSet *params);
+ APDU_Response *ProcessInitializeUpdate(
+ Initialize_Update_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessExternalAuthenticate(
+ External_Authenticate_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessReadObject(Read_Object_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessListObjects(List_Objects_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessDeleteFile(Delete_File_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessSetPin(Set_Pin_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessInstallApplet(Install_Applet_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessInstallLoad(Install_Load_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessLoadFile(Load_File_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessFormatMuscleApplet(Format_Muscle_Applet_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessGetVersion(Get_Version_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessListPins(List_Pins_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessCreatePin(Create_Pin_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessGetData(Get_Data_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessGetStatus(Get_Status_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessCreateObject(Create_Object_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessLifecycle(Lifecycle_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessReadBuffer(Read_Buffer_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessUnblockPin(Unblock_Pin_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessGetIssuerInfo(Get_IssuerInfo_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessSetIssuerInfo(Set_IssuerInfo_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessWriteBuffer(Write_Object_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessGenerateKey(Generate_Key_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessImportKeyEnc(Import_Key_Enc_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessSelect(Select_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ APDU_Response *ProcessPutKey(Put_Key_APDU *apdu,
+ NameValueSet *vars,
+ NameValueSet *params);
+ public:
+ Buffer m_card_challenge;
+ Buffer m_host_challenge;
+ PK11SymKey *m_session_key;
+ PK11SymKey *m_enc_session_key;
+ Buffer m_icv;
+ Buffer m_cuid;
+ Buffer m_msn;
+ Buffer m_version;
+ Buffer m_key_info;
+ Buffer m_auth_key;
+ Buffer m_mac_key;
+ Buffer m_kek_key;
+ Buffer m_buffer;
+ BYTE m_lifecycle_state;
+ char *m_pin;
+ Buffer* m_object;
+ int m_major_version;
+ int m_minor_version;
+ int m_object_len;
+ int m_chunk_len;
+ char m_objectid[3];
+};
+
+#endif /* RA_TOKEN_H */
diff --git a/base/tps/tools/raclient/enroll.tps b/base/tps/tools/raclient/enroll.tps
new file mode 100644
index 000000000..08e40b6e1
--- /dev/null
+++ b/base/tps/tools/raclient/enroll.tps
@@ -0,0 +1,42 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+########################################################
+# Description:
+# This data file tests enrollment operation.
+#
+# Execution:
+# tpsclient < enroll.test
+#
+########################################################
+op=var_set name=ra_host value=air
+op=var_set name=ra_port value=8099
+op=var_set name=ra_uri value=/nk_service
+# print original token status
+op=token_set cuid=a00192030405060708c9 msn=01020304 app_ver=6FBBC105 key_info=0101 major_ver=0 minor_ver=0
+op=token_set auth_key=404142434445464748494a4b4c4d4e4f
+op=token_set mac_key=404142434445464748494a4b4c4d4e4f
+op=token_set kek_key=404142434445464748494a4b4c4d4e4f
+op=token_status
+#op=ra_enroll uid=test pwd=password new_pin=password
+op=ra_enroll uid=sectest13 num_threads=1 pwd=home-boy new_pin=password
+# print changed token status
+op=token_status
+op=exit
diff --git a/base/tps/tools/raclient/enroll1.test b/base/tps/tools/raclient/enroll1.test
new file mode 100644
index 000000000..fdd54f704
--- /dev/null
+++ b/base/tps/tools/raclient/enroll1.test
@@ -0,0 +1,43 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+########################################################
+# Description:
+# This data file tests enrollent.
+#
+# Execution:
+# tpsclient < enroll.test
+#
+########################################################
+op=var_set name=ra_host value=air
+op=var_set name=ra_port value=8000
+op=var_set name=ra_uri value=/nk_service
+# print original token status
+op=token_status
+###set token params
+op=token_set cuid=a00192030405060708c9 msn=01020304 app_ver=6FBBC105 key_info=0101 major_ver=0 minor_ver=0
+op=token_set auth_key=404142434445464748494a4b4c4d4e4f
+op=token_set mac_key=404142434445464748494a4b4c4d4e4f
+op=token_set kek_key=404142434445464748494a4b4c4d4e4f
+op=token_status
+op=ra_enroll uid=sectest13 pwd=home-boy new_pin=password
+# print changed token status
+op=token_status
+op=exit
diff --git a/base/tps/tools/raclient/format.tps b/base/tps/tools/raclient/format.tps
new file mode 100644
index 000000000..f087a2d25
--- /dev/null
+++ b/base/tps/tools/raclient/format.tps
@@ -0,0 +1,45 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+########################################################
+# Description:
+# This data file tests token format operation.
+#
+# Execution:
+# tpsclient < format.test
+#
+########################################################
+op=var_set name=ra_host value=air
+op=var_set name=ra_port value=8000
+op=var_set name=ra_uri value=/nk_service
+op=var_list
+# print original token status
+op=token_status
+### set token params
+op=token_set cuid=a00192030405060708c9 app_ver=6FBBC105 key_info=0101
+op=token_set auth_key=404142434445464748494a4b4c4d4e4f
+op=token_set mac_key=404142434445464748494a4b4c4d4e4f
+op=token_set kek_key=404142434445464748494a4b4c4d4e4f
+op=token_status
+## perform format operation
+op=ra_format uid=test pwd=password num_threads=1 new_pin=password
+# print changed token status
+op=token_status
+op=exit
diff --git a/base/tps/tools/raclient/nt_enroll.test b/base/tps/tools/raclient/nt_enroll.test
new file mode 100644
index 000000000..f4faf18fe
--- /dev/null
+++ b/base/tps/tools/raclient/nt_enroll.test
@@ -0,0 +1,212 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+########################################################
+# Description:
+# This data file tests enrollment operation.
+#
+# Execution:
+# tpsclient < enroll.test
+#
+########################################################
+op=var_set name=ra_host value=water
+op=var_set name=ra_port value=7888
+op=var_set name=ra_uri value=/nk_service
+########################################################
+# Possible return codes:
+#
+# General errors:
+# 6400 - No specific diagnosis
+# 6700 - Wrong length in Lc
+# 6982 - Security status not satisfied
+# 6985 - Conditions of use not satisified
+# 6a86 - Incorrect P1 P2
+# 6d00 - Invalid instruction
+# 6e00 - Invalid class
+#
+# Install Load errors:
+# 6581 - Memory Failure
+# 6a80 - Incorrect parameters in data field
+# 6a84 - Not enough memory space
+# 6a88 - Referenced data not found
+#
+# Delete errors:
+# 6200 - Application has been logically deleted
+# 6581 - Memory failure
+# 6985 - Referenced data cannot be deleted
+# 6a88 - Referenced data not found
+# 6a82 - Application not found
+# 6a80 - Incorrect values in command data
+#
+# Get Data errors:
+# 6a88 - Referenced data not found
+#
+# Get Status errors:
+# 6310 - More data available
+# 6a88 - Referenced data not found
+# 6a80 - Incorrect values in command data
+#
+# Load errors:
+# 6581 - Memory failure
+# 6a84 - Not enough memory space
+# 6a86 - Incorrect P1/P2
+# 6985 - Conditions of use not satisified
+########################################################
+#
+########################################################
+# Negative Test Cases Testing:
+#
+# To enable the testing, you need to uncomment
+# the following:
+#
+#op=var_set name=test_enable value=true
+#
+# Init Update APDU:
+#
+#op=var_set name=test_apdu_iu_return_enable value=true
+#op=var_set name=test_apdu_iu_return value=6a88
+#
+# External Authenticate APDU:
+#
+#op=var_set name=test_apdu_ea_return_enable value=true
+#op=var_set name=test_apdu_ea_return value=6a88
+#
+# Generate Key APDU:
+#
+#op=var_set name=test_apdu_gk_return_enable value=true
+#op=var_set name=test_apdu_gk_return value=6a88
+#
+# Create Object APDU:
+#
+#op=var_set name=test_apdu_co_return_enable value=true
+#op=var_set name=test_apdu_co_return value=6a88
+#
+# Life Cycle APDU:
+#
+#op=var_set name=test_apdu_lc_return_enable value=true
+#op=var_set name=test_apdu_lc_return value=6a88
+#
+# Delete File APDU:
+#
+#op=var_set name=test_apdu_df_return_enable value=true
+#op=var_set name=test_apdu_df_return value=6a88
+#
+# Install Applet APDU:
+#
+#op=var_set name=test_apdu_ia_return_enable value=true
+#op=var_set name=test_apdu_ia_return value=6a88
+#
+# Install Load APDU:
+#
+#op=var_set name=test_apdu_il_return_enable value=true
+#op=var_set name=test_apdu_il_return value=6a88
+#
+# Load File APDU:
+#
+#op=var_set name=test_apdu_lf_return_enable value=true
+#op=var_set name=test_apdu_lf_return value=6a88
+#
+# Select Applet APDU:
+#
+#op=var_set name=test_apdu_se_return_enable value=true
+#op=var_set name=test_apdu_se_return value=6a88
+#
+# List PINs APDU:
+#
+#op=var_set name=test_apdu_lp_return_enable value=true
+#op=var_set name=test_apdu_lp_return value=6a88
+#
+# Create PIN APDU:
+#
+#op=var_set name=test_apdu_cp_return_enable value=true
+#op=var_set name=test_apdu_cp_return value=6a88
+#
+# Get Version APDU:
+#
+#op=var_set name=test_apdu_gv_return_enable value=true
+#op=var_set name=test_apdu_gv_return value=6a88
+#
+# Get Data APDU:
+#op=var_set name=test_apdu_gd_return_enable value=true
+#op=var_set name=test_apdu_gd_return value=6a88
+#
+# Get Status APDU:
+#
+#op=var_set name=test_apdu_gs_return_enable value=true
+#op=var_set name=test_apdu_gs_return value=6a88
+#
+# Put Key APDU:
+#
+#op=var_set name=test_apdu_pk_return_enable value=true
+#op=var_set name=test_apdu_pk_return value=6a88
+#
+# Import Key Enc APDU:
+#
+#op=var_set name=test_apdu_ik_return_enable value=true
+#op=var_set name=test_apdu_ik_return value=6a88
+#
+# Read Buffer APDU:
+#
+#op=var_set name=test_apdu_rb_return_enable value=true
+#op=var_set name=test_apdu_rb_return value=6a88
+#
+# Unblock PIN APDU:
+#
+#op=var_set name=test_apdu_up_return_enable value=true
+#op=var_set name=test_apdu_up_return value=6a88
+#
+# List Objects APDU:
+#
+#op=var_set name=test_apdu_lo_return_enable value=true
+#op=var_set name=test_apdu_lo_return value=6a88
+#
+# Read Object APDU:
+#
+#op=var_set name=test_apdu_ro_return_enable value=true
+#op=var_set name=test_apdu_ro_return value=6a88
+#
+# Write Buffer APDU:
+#
+#op=var_set name=test_apdu_wb_return_enable value=true
+#op=var_set name=test_apdu_wb_return value=6a88
+#
+# Set PIN APDU:
+#
+#op=var_set name=test_apdu_sp_return_enable value=true
+#op=var_set name=test_apdu_sp_return value=6a88
+#
+# ExtendedLoginRequest Message:
+#
+#op=var_set name=test_msg_el_resp_exclude_uid value=true
+#op=var_set name=test_msg_el_resp_exclude_pwd value=true
+#op=var_set name=test_msg_el_resp_add_invalid_param value=true
+#
+########################################################
+# print original token status
+op=token_set cuid=a00192030405060708c9 msn=01020304 app_ver=6FBBC105 key_info=0101 major_ver=0 minor_ver=0
+op=token_set auth_key=404142434445464748494a4b4c4d4e4f
+op=token_set mac_key=404142434445464748494a4b4c4d4e4f
+op=token_set kek_key=404142434445464748494a4b4c4d4e4f
+op=token_status
+#op=ra_enroll uid=test pwd=password new_pin=password
+op=ra_enroll uid=testuser1 num_threads=1 pwd=netscape new_pin=password
+# print changed token status
+op=token_status
+op=exit
diff --git a/base/tps/tools/raclient/readme.txt b/base/tps/tools/raclient/readme.txt
new file mode 100644
index 000000000..8997544ac
--- /dev/null
+++ b/base/tps/tools/raclient/readme.txt
@@ -0,0 +1,247 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+Overview
+========
+
+tpsclient is a test utility that talks to the TPS
+directly using HTTP protocol.
+
+It is a software-based token. It can be used as a driver
+for stress/scalability testing.
+
+It can be used for the following operations:
+
+ enrollment - This is for getting a certificate
+ into the token.
+ pin reset - This is for changing the token's pin.
+ format - This is for formatting the token to
+ remove the certificates from the token
+ and load fresh applets.
+
+Configuration
+=============
+
+The tpsclient utility accepts a test script file. Each script
+file contains a sequence of operations. Each operation
+is composed of a set of name value pairs. For example,
+
+ op=var_set name=ra_host value=familiar
+
+It starts with an operation type such as 'op=var_set' and
+follows by a list of parameters as 'name=ra_host value=familiar'.
+
+The currently supported operation types are as follows:
+
+ op=var_list - list all TPS connection parameters
+ op=var_get - retrieve the value of a TPS connection parameter
+ op=var_set - set the value of a TPS conection parameter
+
+ op=exit - exit this utility
+ op=help - get more information about each operation
+
+ op=token_status - list all token parameters
+ op=token_set - set the value of a token parameter
+
+ op=ra_enroll - perform an enrollment operation
+ op=ra_reset_pin - perform a pin reset operation
+ op=ra_format - perform a format operation
+
+Configuration Examples
+======================
+
+Setup TPS's connection information:
+
+ op=var_set name=ra_host value=familiar
+ op=var_set name=ra_port value=9003
+ op=var_set name=ra_uri value=/nk_service
+
+Setup token's ID, Applet ID, and Key Set Version:
+
+ op=token_set cuid=a00192030405060708c9 app_ver=6FBBC105 key_info=0101
+
+Setup Key Data: (Note that '404142434445464748494a4b4c4d4e4f' is the
+default key created by the manufacturer in the real token)
+
+ op=token_set auth_key=404142434445464748494a4b4c4d4e4f
+ op=token_set mac_key=404142434445464748494a4b4c4d4e4f
+ op=token_set kek_key=404142434445464748494a4b4c4d4e4f
+
+Perform an enrollment operation:
+
+ op=ra_enroll uid=sectest13 pwd=home-boy new_pin=password
+
+Perform a pin reset operation:
+
+ op=ra_reset_pin uid=test pwd=password new_pin=newpassw
+
+Perform a format operation:
+
+ op=ra_format uid=test pwd=password new_pin=newpassw
+
+Print the information inside token:
+
+ op=token_status
+
+Applet Upgrade Example
+======================
+
+To test applet upgrade, you should first setup TPS to enable
+applet upgrade. Please consult the TPS documentation for those
+details.
+
+You should try to do an enrollment operation with an applet
+version that's different from the one that's configured in
+the TPS's configuration file. For example, you should have
+the following in the test script.
+
+ op=token_set cuid=18888883333300000004 app_ver=402428AD key_info=0101
+
+This indicates that the token's applet version is currently at
+40248AD.
+
+
+After execution, you should see an audit event logged on the
+TPS's audit log file like this,
+
+
+ ...
+ [2004-11-15 16:56:38] 847f220 Enrollment - op='applet_upgrade'
+ app_ver='0.0.402428AD' new_app_ver='1.2.416DA155'
+ ...
+ ...
+ [2004-11-15 16:56:43] 847f220 Enrollment - status='success'
+ app_ver='1.2.416DA155' key_ver='0101' cuid='18888883333300000004'
+ msn='00000000' uid='user1' auth='ldap1' time='7243 msec'
+
+Key Change Over Example
+=======================
+
+To test key change over, you should setup a version 2 master key
+in TKS and enable the key change over feature in TPS. Please
+consult the TPS documentation for details.
+
+You should try to do an enrollment with a version 1 key in the
+token. TPS should change the key in your token to
+version 2. For example, you should have the following in
+the test script:
+
+ op=token_set cuid=a00192030405060708c9 app_ver=6FBBC105 key_info=0101
+ op=token_set auth_key=404142434445464748494a4b4c4d4e4f
+ op=token_set mac_key=404142434445464748494a4b4c4d4e4f
+ op=token_set kek_key=404142434445464748494a4b4c4d4e4f
+
+Note 'key_info=0101' indicates a version 1 key set.
+
+After the execution, you should see the following in the output:
+
+ ...
+ Output> cuid : 'a00192030405060708c9' (10 bytes)
+ Output> key_info : '0201' (2 bytes)
+ Output> auth_key : 'a3523ec8c0740b621e18e9cdd99f75fc' (16 bytes)
+ Output> mac_key : '903af964eb7ede26ea189243a5caad9c' (16 bytes)
+ Output> kek_key : '44ef9de3775121a871c152563d9b9860' (16 bytes)
+ ...
+
+'key_info: 0201' indicates that the current key set in the
+token now changed from '0101' to '0201'. And as you noticed,
+the key data for auth, mac, and kek keys are all different.
+
+If you check the TPS's log, you should see an audit event for
+the key change over operation.
+
+After this, you should try to enroll with a version 2 keys.
+For example, create a new test script that contains:
+
+ op=token_set cuid=a00192030405060708c9 app_ver=6FBBC105 key_info=0201
+ op=token_set auth_key=a3523ec8c0740b621e18e9cdd99f75fc
+ op=token_set mac_key=903af964eb7ede26ea189243a5caad9c
+ op=token_set kek_key=44ef9de3775121a871c152563d9b9860
+
+Execute this test script, and you should NOT see an audit
+event for key change over. It is because your token already
+has a version 2 key set.
+
+You can also try to key change over from version 2 back to
+version 1 with appropriate TPS configuration and test
+script.
+
+Choose a specific profile in TPS
+================================
+
+TPS can be configured to support several profiles like
+
+ 1) devicekey profile - used to issue only signing certs
+ 2) userKey profile - used to issue signing and encryption certs
+
+the tpsclient can be configured to tell TPS to select the right
+profile by adding the following to the op=ra_enroll line in the
+test script
+
+ op=ra_enroll uid=user1 num_threads=1 pwd=password new_pin=newpassw
+ extensions=tokenType=userKey
+
+ (OR)
+
+ op=ra_enroll uid=user1 num_threads=1 pwd=password new_pin=newpassw
+ extensions=tokenType=deviceKey
+
+Stress test Example
+===================
+
+tpsclient can be configured to start multiple threads to perform
+enrollment or pin reset or format operations, to stress the TPS
+installation.
+
+ op=ra_enroll uid=user1 num_threads=1 pwd=password new_pin=newpassw
+ extensions=tokenType=userKey
+
+In the above test script line, the num_threads parameter indicates
+the number of threads that will be started.
+
+Also , to control the number of operations being performed, the
+following parameter should be set in the test script line.
+
+ op=ra_enroll uid=user1 num_threads=1 pwd=password new_pin=newpassw
+ extensions=tokenType=userKey max_ops=10
+
+max_ops, indicates the number of operations that will be performed
+by all the threads.
+
+
+
+
+Execution
+=========
+
+For Enrollment Operation:
+
+ tpsclient < enroll.test
+
+For Reset Pin Operation:
+
+ tpsclient < reset_pin.test
+
+Note
+====
+
+You may need to setup LD_LIBRARY_PATH (On Linux, and Solaris) to
+point to the directory where you have NSPR, NSS, TPS shared libraries.
+
diff --git a/base/tps/tools/raclient/reset_pin.tps b/base/tps/tools/raclient/reset_pin.tps
new file mode 100644
index 000000000..1a81fd2a7
--- /dev/null
+++ b/base/tps/tools/raclient/reset_pin.tps
@@ -0,0 +1,42 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+########################################################
+# Description:
+# This data file tests pin reset operation.
+#
+# Execution:
+# tpsclient < reset_pin.test
+#
+########################################################
+op=var_set name=ra_host value=air
+op=var_set name=ra_port value=8000
+op=var_set name=ra_uri value=/nk_service
+op=var_list
+# print original token status
+op=token_set cuid=a00192030405060708c9 app_ver=6FBBC105 key_info=0101
+op=token_set auth_key=404142434445464748494a4b4c4d4e4f
+op=token_set mac_key=404142434445464748494a4b4c4d4e4f
+op=token_set kek_key=404142434445464748494a4b4c4d4e4f
+op=token_status
+op=ra_reset_pin uid=test pwd=password num_threads=1 new_pin=password
+# print changed token status
+op=token_status
+op=exit
diff --git a/base/tps/tools/raclient/reset_pin1.test b/base/tps/tools/raclient/reset_pin1.test
new file mode 100644
index 000000000..2169e7ce2
--- /dev/null
+++ b/base/tps/tools/raclient/reset_pin1.test
@@ -0,0 +1,40 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+########################################################
+# Description:
+# This data file tests pin reset.
+#
+# Execution:
+# tpsclient < reset_pin.test
+#
+# This one is failure case. The sectest12 requires securid but
+# the test doesnt provide one.
+########################################################
+op=var_set name=ra_host value=broom
+op=var_set name=ra_port value=2020
+op=var_set name=ra_uri value=/nk_service
+op=var_list
+# print original token status
+op=token_status
+op=ra_reset_pin uid=sectest12 pwd=blue77 new_pin=password
+# print changed token status
+op=token_status
+op=exit
diff --git a/base/tps/tools/raclient/reset_pin2.test b/base/tps/tools/raclient/reset_pin2.test
new file mode 100644
index 000000000..77b5d20d2
--- /dev/null
+++ b/base/tps/tools/raclient/reset_pin2.test
@@ -0,0 +1,39 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+########################################################
+# Description:
+# This data file tests pin reset.
+#
+# Execution:
+# tpsclient < reset_pin.test
+#
+# This one is success case. The sectest13 does not require securid.
+########################################################
+op=var_set name=ra_host value=broom
+op=var_set name=ra_port value=2020
+op=var_set name=ra_uri value=/nk_service
+op=var_list
+# print original token status
+op=token_status
+op=ra_reset_pin uid=sectest13 pwd=home-boy new_pin=password
+# print changed token status
+op=token_status
+op=exit
diff --git a/base/tps/tools/tus/add.c b/base/tps/tools/tus/add.c
new file mode 100644
index 000000000..f88ae9753
--- /dev/null
+++ b/base/tps/tools/tus/add.c
@@ -0,0 +1,117 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "nsapi.h"
+
+#include <time.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "ldap.h"
+
+#include "tus/tus_db.h"
+
+/* Specify the search criteria here. */
+static char *host = "localhost";
+static int port = 389;
+static char *baseDN = "ou=Tokens,dc=mcom,dc=com";
+static char *prefix = "0000";
+static char *suffix = "0000";
+static int start = 1;
+static int len = 0;
+static char *who = NULL;
+static char *password = NULL;
+static char *token_type = NULL;
+
+
+#define SCOPE LDAP_SCOPE_SUBTREE
+#define FILTER "(cn=*)"
+
+int main (int argc, char **argv)
+{
+ int i, h, rc;
+ char cn[256];
+ char *errorMsg = NULL;
+
+ if (argc < 9 || argc > 11) {
+ printf ("Usage:\n %s baseDN prefix suffix start len who password token_type host port", argv[0]);
+ return 1;
+ }
+
+ baseDN = argv[1];
+ prefix = argv[2];
+ suffix = argv[3];
+ start = atoi(argv[4]);
+ len = atoi(argv[5]);
+ who = argv[6];
+ password = argv[7];
+ token_type = argv[8];
+
+ if (argc > 9) {
+ host = argv[9];
+ }
+
+ if (argc > 10) {
+ port = atoi(argv[10]);
+ }
+
+ set_tus_db_baseDN(baseDN);
+ set_tus_db_port(port);
+ set_tus_db_host(host);
+ set_tus_db_bindDN(who);
+ set_tus_db_bindPass(password);
+ rc = tus_db_init(errorMsg);
+ if (rc != LDAP_SUCCESS) {
+ fprintf(stderr, "tus_db_init: (%d) %s\n", rc, errorMsg);
+ return 1;
+ }
+
+ for (i = 0; i < len; i++) {
+ h = start + i;
+ sprintf(cn, "%s%08X%s", prefix, h, suffix);
+ printf ("Adding %s\n", cn);
+
+ rc = add_default_tus_db_entry (NULL, "", cn, "active", "", "", token_type);
+ if (rc != LDAP_SUCCESS) {
+ fprintf( stderr, "ldap_add_ext_s: %s\n", ldap_err2string( rc ) );
+ return 1;
+ }
+ }
+
+ /* STEP 4: Disconnect from the server. */
+ tus_db_end();
+
+ return( 0 );
+}
diff --git a/base/tps/tools/tus/test.c b/base/tps/tools/tus/test.c
new file mode 100644
index 000000000..a307d1ccc
--- /dev/null
+++ b/base/tps/tools/tus/test.c
@@ -0,0 +1,117 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 ---
+ */
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include "ldap.h"
+#include "ldappr.h"
+
+/* Specify the search criteria here. */
+#define HOSTNAME "localhost"
+#define PORTNUMBER 389
+#define BASEDN "ou=Tokens,dc=mcom,dc=com"
+#define SCOPE LDAP_SCOPE_SUBTREE
+#define FILTER "(cn=*)"
+
+int
+main( int argc, char **argv )
+{
+ char ldapuri[1024];
+ LDAP *ld;
+ LDAPMessage *result = NULL, *e;
+ char *dn = NULL;
+ int version, rc;
+ /* Print out an informational message. */
+ printf( "Connecting to host %s at port %d...\n\n", HOSTNAME,
+ PORTNUMBER );
+
+ /* STEP 1: Get a handle to an LDAP connection and
+ set any session preferences. */
+ snprintf(ldapuri, 1024, "ldap://%s:%i", HOSTNAME, PORTNUMBER);
+ rc = ldap_initialize(&ld, ldapuri);
+
+ if ( ld == NULL ) {
+ perror( "ldap_initialize" );
+ return( 1 );
+ }
+
+ /* Use the LDAP_OPT_PROTOCOL_VERSION session preference to specify
+ that the client is an LDAPv3 client. */
+ version = LDAP_VERSION3;
+ ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
+
+ /* STEP 2: Bind to the server.
+ In this example, the client binds anonymously to the server
+ (no DN or credentials are specified). */
+ rc = ldap_sasl_bind_s(ld, NULL, LDAP_SASL_SIMPLE, NULL, NULL, NULL, NULL);
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf(stderr, "ldap_simple_bind_s: %s\n", ldap_err2string(rc));
+ return( 1 );
+ }
+
+ /* Print out an informational message. */
+ printf( "Searching the directory for entries\n"
+ " starting from the base DN %s\n"
+ " within the scope %d\n"
+ " matching the search filter %s...\n\n",
+ BASEDN, SCOPE, FILTER );
+
+ /* STEP 3: Perform the LDAP operations.
+ In this example, a simple search operation is performed.
+ The client iterates through each of the entries returned and
+ prints out the DN of each entry. */
+ rc = ldap_search_ext_s( ld, BASEDN, SCOPE, FILTER, NULL, 0,
+ NULL, NULL, NULL, 0, &result );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf(stderr, "ldap_search_ext_s: %s\n", ldap_err2string(rc));
+ return( 1 );
+ }
+ for ( e = ldap_first_entry( ld, result ); e != NULL;
+ e = ldap_next_entry( ld, e ) ) {
+ if ( (dn = ldap_get_dn( ld, e )) != NULL ) {
+ printf( "dn: %s\n", dn );
+ ldap_memfree( dn );
+ dn = NULL;
+ }
+ }
+ if( result != NULL ) {
+ ldap_msgfree( result );
+ result = NULL;
+ }
+
+ /* STEP 4: Disconnect from the server. */
+ ldap_unbind_ext_s( ld, NULL, NULL );
+ return( 0 );
+}
diff --git a/base/tps/ui/perl/Velocity.pm b/base/tps/ui/perl/Velocity.pm
new file mode 100755
index 000000000..f5f45431f
--- /dev/null
+++ b/base/tps/ui/perl/Velocity.pm
@@ -0,0 +1,1047 @@
+#! /usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+#
+
+
+use strict;
+
+package Template::Velocity::Executor;
+sub new;
+
+package Template::Velocity;
+
+
+# The Template::Velocity package implements a Template execution
+# engine similar to the Java Velocity package.
+
+use Parse::RecDescent;
+use Data::Dumper;
+
+
+$Template::Velocity::parser;
+
+my $docroot="docroot";
+my %parsetrees = ();
+my $debugflag = 0;
+
+
+#GRAMMAR defined here
+
+my $vmgrammar = q{
+
+ {
+ use Data::Dumper;
+ sub Dumper
+ {
+ $::debugdumper = undef;
+ if ($::debugflag && $::debugdumper ) { return Data::Dumper(@_); }
+ else {""};
+ }
+
+ }
+
+
+# Template is the top-level object
+ template: <skip:'[ \t]*'> section(s) /\Z/
+
+ section: blockdirective
+ | nonblockdirective
+ | plainline
+
+ blockdirective: ifblock
+ | foreachblock
+
+ plainline : <skip:''> /[ \t]*/ ...!'#' linecomp(s?) /\n*/
+
+ HASH: '#'
+
+# HMM - this doesn't handle multiple variables on one line?
+ linecomp: variable
+ | <skip:'[ \t]*'> /[^\$\n]*/
+
+ nonblockdirective: '#' 'include' <commit> includeargs /\n*/ { $item[4] ; }
+ | '#' 'parse' <commit> parseargs /\n*/ { $item[4] ; }
+ | '#' 'set' <commit> setargs /\n*/ { $item[4] ; }
+ | <error:unknown command $text>
+
+
+ ifblock: ifdirective section(s) elseclause(?) enddirective
+
+
+# this bubbles up the result of the expression inside the if()
+# which is from the 'ifargs' rule
+ ifdirective: '#' 'if' <skip:'[ \t]*'> ifargs /\n/
+
+ enddirective: <skip:'[ \t]*'> '#' 'end' "\n"
+
+ elseclause: elsedirective section(s)
+
+ elsedirective: '#' 'else' "\n"
+
+ foreachblock: foreachdirective section(s) enddirective
+
+ foreachdirective: '#' 'foreach' foreachargs "\n"
+
+ ifargs: '(' expression ')'
+ | <error:Argument to if must be an expression: $text>
+
+ foreachargs: '(' variablename 'in' variable ')'
+ | <error:Arguments to 'foreach' must be of form \$a in \$b: $text>
+
+ includeargs: '(' string ')'
+ | <error:invalid argument to include: $text>
+
+ parseargs: '(' expression ')'
+ | <error:invalid argument to parsearges: $text>
+
+
+ setargs: <skip:'[ \t]*'> '(' assignment ')'
+ | <error:Argument to set must be an assignment : $text>
+
+
+# expression evaluation
+
+# this goes roughly in order of precendence:
+# ==
+# &&, ||
+# +, -
+# *
+# !
+
+# does not properly distinguish between lvalues and rvalues
+
+
+ expression: boolean
+ | <error>
+
+
+ assignment: variablename '=' boolean
+
+ boolean: equality (boolean_operator equality)(?)
+
+ boolean_operator: ( '&&' | '||' )
+
+ equality: summation (equality_operator summation)(?)
+
+
+ equality_operator: ( '==' | '!=' )
+
+ summation: product (summation_operator summation)(?)
+
+ summation_operator: ( '+' | '-' )
+
+
+# must parenthesize operator '*' to get it to appear in the $item array
+
+ product: negation ('*' product)(?)
+
+#XXX need to implement
+ negation: notoperator(?) factor
+
+ notoperator: "!"
+
+ factor: number
+ | string
+ | variable
+
+
+
+# These rules deal with variables
+# handles $process
+# $file.executablename
+# $process.getpid()
+# $person.getparent().getbrother().slap()
+# $fred.getchildren()
+
+# You'd make a dependency on the 'variable' rule if you want the value
+# of the variable.
+# You'd make a dependency on the 'variablename' rule if you want the
+# name of the variable.
+# (There's no real difference here - the expression evaluation is
+# in the variable() subroutine)
+
+ variable: variablename { ["variable", $item[1][1] ]; }
+
+ variablename: '$' identifier subfield(s?)
+ {
+ my $variableinfo = {
+ top => $item{identifier},
+ fields => $item{'subfield(s?)'}
+ };
+ $return = [ "variablename", \$variableinfo ];
+ }
+
+ subfield: '.' identifier arglist(?)
+ {
+ my $d;
+ my $a = $item{"arglist(?)"};
+ my $args;
+
+ #::debug "arglist = ".Dumper($a)."\n";
+ if ($a) {
+
+ my ($argcount, $al, $alpresent);
+
+ #$args = @{$a}->[2];
+ $args = $a->[0][2];
+ #::debug "arglist args=".Dumper($args)."\n";
+ $alpresent = $args;
+ $argcount = $#$args;
+ if ($alpresent && $argcount == -1) {
+ $args->[0] = [ ];
+ }
+ }
+
+ #::debug "arglist identifier=".$item{identifier}."\n";
+ $return = [ "subfield", {
+ fieldname => $item{identifier},
+ arglist => $args->[0],
+ } ];
+ }
+
+ arglist: '(' list(?) ')'
+
+ list: expression (',' list)(s?)
+
+
+# Basic data types
+# identifiers, numbers and strings
+
+ identifier: /[A-Za-z0-9_]+/ { $item[1]; }
+
+ number: /\d+/ {$item[1]; }
+
+ #XXX skip is all wrong here... should be in []
+ string: <skip:'[ \t]'> '"' <skip:""> /[^"]*/ '"' { $return = ["string",$item[4]]; }
+ | <skip:'[ \t]'> "'" <skip:""> /[^']*/ "'" { $return = ["string",$item[4]]; }
+
+
+# other literals
+ whitespace: /\s*/
+
+
+};
+
+
+# Get a parser object (transforming the built-in text grammar into RecDescent
+# data structure). This object can be reused for parsing multiple velocity files
+sub new
+{
+ #$::debugflag = 0;
+ my $class = shift;
+ $docroot = shift;
+ undef $::RD_HINT;
+ undef $::RD_WARN;
+ #$::RD_TRACE = 1;
+ my $parser = new Parse::RecDescent($vmgrammar) or die "Bad Grammar\n";
+ $Data::Dumper::Maxdepth = 1;;
+ my $self = {};
+ $self->{parser} = $parser;
+ # ugly - :-(
+ $Template::Velocity::parser = $parser;
+ bless $self, $class;
+ return $self;
+}
+
+
+# Execute a template. Given a text string and a parser object, will return
+# a parse tree, useful for feeding into the executor.
+sub execute_string
+{
+ my $self = shift;
+ my $string = shift;
+ my $rule = shift;
+ if (! $rule ) { $rule = "template"; }
+ #print Dumper($self);
+
+ my $parser = $self->{parser};
+ my $parsetree = $parser->$rule($string);
+ my $executor = new Template::Velocity::Executor($parsetree, $parser );
+
+ my @value = $executor->run();
+ #my @value = Template::Velocity::Executor::execute($parsetree, $parser);
+ my $value = shift @value;
+ return $value;
+}
+
+
+sub execute_file
+{
+
+ my $self = shift;
+ my $filename = shift;
+
+ my $parser = $self->{parser};
+
+ my $rule;
+ my $tree = $parsetrees{$filename};
+
+ if (! $tree) {
+ $rule = "template";
+ open my $fh, "<$docroot/$filename" or return undef;
+ my $string = join "",<$fh>;
+ close $fh;
+ $tree = $parser->$rule($string);
+ $parsetrees{$filename} = $tree;
+ }
+
+ my $executor = new Template::Velocity::Executor($tree, $parser );
+
+ my @value = $executor->run();
+ my $value = shift @value;
+ return $value;
+
+
+}
+
+
+
+
+
+
+
+
+sub Dumper
+{
+ return "";
+ if ($::debugflag && $::debugdumper) {
+ return Data::Dumper->Dump([@_]);
+ }
+ else {""};
+}
+
+
+
+
+# This autoaction returns an array of each parse element
+# The net result is a parse tree
+# I couldn't use <autotree> because I wanted to preserve
+# the order of the elements, and <autotree> returns a
+# hashtable, not an array
+
+$::RD_AUTOACTION = q{
+ [@item];
+};
+
+# debug flags set here
+
+
+
+
+
+
+######### EXECUTE FUNCTIONS
+
+
+# These functions deal with executing the velocity parse tree
+{
+ package Template::Velocity::Executor::Rules;
+ use Data::Dumper;
+
+ # this imports symbols from these other packages, so
+ # we don't have to always use the fully-qualified names
+ *exe_all = \&Template::Velocity::Executor::exe_all;
+ *exe_optional = \&Template::Velocity::Executor::exe_optional;
+ *execute = \&Template::Velocity::Executor::execute;
+ *debug = \&Template::Velocity::Executor::debug;
+ *indent = \&Template::Velocity::Executor::indent;
+ *deindent = \&Template::Velocity::Executor::deindent;
+ *docroot = \&Template::Velocity::docroot;
+
+ sub Dumper
+ {
+ return "";
+ if ($::debugflag && $::debugdumper) { return Dumper(@_); }
+ else {""};
+ }
+
+ #template: <skip:'[ \t]*'> section(s) /\Z/
+ sub template {
+ my $f = "template";
+ my @item = exe_all(@_);
+ debug ("$::level $f - sections should be an array of text: .".Dumper($item[2])."\n");
+ my $sections = $item[2];
+ debug ("sections is a: ".(ref $sections)." - it should be an array\n");
+ my $r= ( join "", @{$item[2]});
+ return $r;
+ }
+
+
+ #linecomp: variable
+ # | <skip:'[ \t]*'> /[^\$\n]*/
+ sub linecomp {
+ my $item;
+ debug ("linecomp: _[2] = '".$_[2]."'\n");
+ if ($_[2]) {
+ debug ("linecomp: inside if\n");
+ $item = $_[1].$_[2];
+ } else {
+ debug ("linecomp: inside else{\n");
+ ($item) = exe_all($_[1]);
+ debug ("linecomp: end of else}\n");
+ debug ("linecomp: item =\n".Dumper($item)."\n");
+ }
+ debug ("linecomp: returning $item\n");
+ return $item;
+ }
+
+ # plainline : <skip:''> /[ \t]*/ ...!'#' linecomp(s?) /\n+/
+ sub plainline {
+ my @item = exe_all(@_);
+ debug ("$::level in plainline - linecomps should be an array of text: .".Dumper($item[4])."\n");
+ my $r = join "", @{$item[4]};
+ debug ("$::level in plainline - joined as: $r\n");
+ $r = $item[2] . $r. $item[5];
+ debug ("$::level in plainline - returning : $r\n");
+ return $r;
+ }
+
+ sub expression {
+ debug ("$::level expression = ".Dumper($_[1])."\n");
+ my ($item) = exe_all($_[1]);
+ debug ("$::level expression returning $item\n");
+ return $item;
+ }
+
+ #foreachblock: foreachdirective section(s) enddirective
+ sub foreachblock {
+ my $f = "foreachblock";
+ debug ("$::level $f started!\n");
+ my ($directive) = exe_all($_[1]);
+ debug ("$::level $f directive = \n".Dumper($directive)."\n");
+ my ($variable, $list) = @{$directive};
+ my $variablename = $$variable->{top};
+ debug ("$::level $f variable = $variablename\n");
+ debug ("$::level $f list = \n".Dumper($list)."\n");
+
+ my $result = "";
+ foreach my $q (@{$list}) {
+ debug ("$::level $f q=$q\n");
+ $::symbol{$variablename} = $q;
+ debug ("$::level $f setting variable $variablename = $q\n");
+
+ my ($sections) = exe_all($_[2]);
+ debug ("$::level $f sections was: ".Dumper($sections)."\n");
+ $result .= join "",@{$sections};
+ }
+ return $result;
+ }
+
+ #foreachdirective: '#' 'foreach' foreachargs "\n"
+ sub foreachdirective {
+ my ($item) = exe_all($_[3]);
+ return $item;
+ }
+
+ #foreachargs: '(' variablename 'in' expression ')'
+ sub foreachargs {
+ my $f = "foreachargs";
+ my ($variable, $list) = exe_all($_[2], $_[4]);
+ debug ("$::level $f variable = \n".Dumper($variable)."\n");
+ debug ("$::level $f list = \n".Dumper($list)."\n");
+ return [$variable, $list];
+ }
+
+ # XXX if block should only execute section(s) if if arg is positve)
+ # likewise for else
+ #ifblock: ifdirective section(s) elseclause(?) enddirective
+ sub ifblock {
+ my $f = "ifblock";
+ my @item = exe_all(@_);
+ debug ("$::level $f - sections should be an array of text: .".Dumper($item[2])."\n");
+ my $sections = $item[2];
+ my $else = $item[3];
+ debug ("$::level $f sections is a: ".(ref $sections)." - it should be an array\n");
+ debug ("$::level item1: if expression = ".$item[1]."\n");
+ debug ("$::level $f elseclause is a: ".(ref $else)." - it should be an scalar\n");
+ my $r= (
+ $item[1]>0 ? # if expression
+ (join "", @{$item[2]}) :
+ ($item[3] ? join "",@{$item[3]} : "")
+ );
+ # this is not quite right ... elseclause returns a scalar (it joins the sections)
+ # so why do I have to join again here? possibly because it's a '?'
+ return $r;
+ }
+
+ #elseclause: elsedirective section(s)
+ sub elseclause {
+ my $f = "elseclause";
+ my ($sections) = exe_all($_[2]);
+ debug ("$::level $f sections is a: ".(ref $sections)." - it should be an array\n");
+ my $return = join "", @{$sections};
+ debug ("$::level $f returning: $return\n");
+ return $return;
+ }
+
+ sub ifargs {
+ debug ("$::level ifargs [2] = ".Dumper($_[2])."\n");
+ my ($item) = exe_all($_[2]);
+ debug ("$::level item = ".Dumper($item)."\n");
+ my $r = $item>0 ? 1 : 0;
+ debug ("$::level ifargs returning $r\n");
+ return $r;
+ }
+
+ #ifdirective: '#' 'if' <skip:'[ \t]*'> ifargs /\n/
+ sub ifdirective {
+ my ($item) = exe_all($_[4]);
+ my $r = $item>0 ? 1 : 0;
+ debug ("$::level ifdirective returning $r\n");
+ return $r;
+ }
+
+ #boolean: equality (boolean_operator equality)(?)
+ sub boolean {
+ my $f = "boolean";
+ my ($equality, $alt) = ( execute($_[1]), $_[2]);
+ my $r = $equality;
+ if (scalar @$alt) {
+ my ($op, $equality2) = exe_optional($alt, 1,2);
+
+ if ($op eq '&&') {
+ $r = $equality && $equality2;
+ }
+ if ($op eq '||') {
+ $r = $equality || $equality2;
+ }
+ }
+
+ return $r;
+ }
+
+
+ #summation: product (summation_operator summation)(?)
+ sub summation {
+ #my @item = exe_all(@_);
+ my $f = "summation";
+ my ($product, $alt) = ( execute($_[1]), $_[2]);
+ debug("$::level $f - product = $product, alternation = $alt\n");
+ debug("$::level $f - alternation = \n".Dumper($alt)."\n");
+
+ if (scalar @$alt) {
+ if (0) {
+ debug("$::level $f - alt1= \n".Dumper($alt->[0][1])."\n");
+ debug("$::level $f - alt2= \n".Dumper($alt->[0][2])."\n");
+ my ($operator, $summation) = ( execute($alt->[0][1]), execute($alt->[0][2]),);
+ }
+ my ($operator, $summation) = exe_optional($alt, 1,2);
+
+ if ($operator eq '+') { return $product + $summation;
+ } else { return $product - $summation; }
+ } else {
+ return $product;
+ }
+ }
+
+
+
+ #equality: summation (equality_operator summation)(?)
+ sub equality {
+ my $f = "equality";
+ my ($summation, $alt) = ( execute($_[1]), $_[2] );
+
+ if (scalar @$alt) {
+ my ($operator, $summation2) = exe_optional($alt, 1,2);
+
+ # string comparison used, so (0.0) is NOT equal to (0)
+ if ($operator eq '==') { return ($summation eq $summation2) ? 1:0; }
+ else { return ($summation eq $summation2) ? 0:1; }
+ } else {
+ return $summation;
+ }
+ }
+
+
+ sub product {
+ my $f = "product";
+ my ($negation, $alt) = ( execute($_[1]), $_[2]);
+ debug("$::level $f negation = $negation, alternation = $alt\n");
+ debug("$::level $f - alternation = ".Dumper($alt)."\n");
+
+ if (scalar @$alt) {
+ if (0) {
+ debug("$::level $f - alt1= \n".Dumper($alt->[0][1])."\n");
+ debug("$::level $f - alt2= \n".Dumper($alt->[0][2])."\n");
+ my ($operator, $product) = ( execute($alt->[0][1]), execute($alt->[0][2]),);
+ }
+ my ($operator, $product) = exe_optional($alt,1,2);
+ return ($negation * $product);
+ } else {
+ return $negation;
+ }
+ }
+
+ sub factor {
+ my ($value) = exe_all($_[1]);
+ return $value;
+ }
+
+ #negation: notoperator(?) factor
+ sub negation {
+ debug ("$::level in negation... input = ".(join ",",@_)."\n");
+ #my @item = exe_all(@_);
+ my ($alt, $value) = ( $_[1], execute($_[2]) );
+ debug ("$::level negation: alternation= $alt\n");
+ debug ("$::level negation: value = $value\n");
+ my $operator = execute($alt->[0][1]);
+
+ my $r;
+ if ($operator && $operator eq '!') {
+ if ($value ) { $r = 0; }
+ else { $r = 1; }
+ debug ("$::level negation: inverting\n");
+ } else {
+ debug ("$::level negation: not inverting\n");
+ $r = $value;
+ }
+ debug ("$::level negation: returning $r\n");
+ return $r;
+ }
+
+ #setargs: <skip:'[ \t]*'> '(' assignment ')'
+ sub setargs {
+ my $f = "setargs";
+ my ($args) = exe_all($_[3]);
+ debug("$::level $f args = \n".Dumper($args)."\n");
+ my ($variable, $value) = @{$args};
+ debug("$::level $f variable type =".(ref $variable)."\n");
+ debug("$::level $f variable = \n".Dumper($variable)."\n");
+ my $symbolname = $$variable->{top};
+ debug("$::level $f setting variable '$symbolname' = $value\n");
+ $::symbol{$symbolname} = $value;
+ return "";
+ }
+
+ #assignment: variablename '=' boolean
+ sub assignment {
+ my $f = "assignment";
+ my ($variable, $value) = exe_all($_[1],$_[3]);
+ debug("$::level $f variable = \n".Dumper($variable)."\n");
+ my $r = [ $variable, $value ];
+ debug("$::level $f returning: \n".Dumper($r)."\n");
+ return $r;
+ }
+
+ #includeargs: '(' string ')'
+ sub includeargs {
+ my $f = "includeargs";
+ my ($filename ) = execute($_[2]);
+
+ debug("including file: $filename\n");
+ open my $fh, "<$docroot/$filename" or return "filenotfound $docroot/$filename!\n";
+ my $file = join "", <$fh>;
+ close FILE;
+
+ return $file;
+ }
+
+ sub parseargs {
+ my $f = "parseargs";
+ my ($filename ) = execute($_[2]);
+
+ debug("parsing file: $filename\n");
+ open my $fh, "<$docroot/$filename" or return "filenotfound $docroot/$filename!\n";
+ my $file = join "", <$fh>;
+ close FILE;
+
+ #$result = $parser->template($string);
+ my $parsetree = $Template::Velocity::parser->template($file);
+ my @value = execute($parsetree);
+ my $value = shift @value;
+
+ return $value;
+ }
+
+# variables
+
+# variables
+# this rule converts a variable name/identifier into its value
+# $main.subfield(argument1,argument2).subfield2(arg1,arg2)
+# There are two data structures at work here.
+# 1. the data structure specifying the variable name to be queried
+# this represents $a.b.c(100,9,5,4)
+#{
+# 'top' => 'a'
+# 'fields' => [
+# { 'fieldname' => 'b', 'arglist' => undef },
+# { 'fieldname' => 'c', 'arglist' => [ '100', 9, 5, '4', ], }
+# ],
+#}
+# 2. Data structure specifying the symbol table
+
+# return value could be:
+# a scalar: either a string/number value or reference to an array of values
+# an array
+
+ sub variable {
+# look up the root object in the symbol table
+ my $f = "variable";
+ debug("$::level $f: input\n".Dumper(\@_)."\n");
+ my $var = $_[1];
+ debug("$::level $f var=\n".Dumper($var)."\n");
+# $$var works with # 27: '#set (\$a=1+3)\n\$a\n'
+#0 REF(0x8fa0510)
+# -> HASH(0x8fa1454)
+# 'fields' => ARRAY(0x8fa8c08)
+# empty array
+# 'top' => 'a'
+
+# $var works with # 25: '$employee.add(100,4+5,2+3,4,4,5,6)'
+#DB<2> x $var
+#0 HASH(0x9c7a340)
+# 'fields' => ARRAY(0xa06e7d8)
+# 0 ARRAY(0xa06e9ac)
+# 0 'subfield'
+# 1 HASH(0xa06e880)
+# 'arglist' => ARRAY(0xa074184)
+
+ my $top = $$var->{top}; # name of the root object
+ debug("$::level $f top=\n".Dumper($top)."\n");
+ my $fields = $$var->{fields}; # array of the subidentifiers
+ my $val = "";
+
+ debug("$::level $f - top_id = $top\n");
+ debug("$::level $f : var: \n".Dumper($var)."\n");
+ debug("$::level $f - fields = \n".Dumper($fields)."\n");
+
+
+ debug("$::level $f : top = ".$top."\n");
+ if (! defined $::symbol{$top} ) {
+# XXX
+ debug ("symbol table = ",(join ",",sort keys %::symbol)."\n");
+ debug ("undefined variable: $top\n");
+ return 0;
+ }
+ debug("$::level $f symbol table: \n".Dumper(\%::symbol)."\n");
+ $val = $::symbol{$top};
+ debug("$::level $f val before: \n".Dumper($val)."\n");
+
+ debug("$::level $f - fields = \n".Dumper($fields)."\n");
+ my $pass = 1;
+ foreach my $field (@$fields) {
+ my $args;
+
+ my ($fieldname, $values);
+ {
+ debug("$::level $f pass $pass \@_=\n".Dumper(\@_)."\n");
+ debug("$::level $f before strip field = \n".Dumper($field)."\n");
+#shift @$fn; # 'subfield' string
+#$fn = $fn->[0];
+#$fn = [ (@{$fn}) ];
+#shift @$fn;
+ debug("$::level $f after strip fn = \n".Dumper($field)."\n");
+
+ $fieldname = $field->[1]->{fieldname};
+ debug("$::level $f processing field: $fieldname\n");
+ $args= $field->[1]->{arglist};
+
+
+# convert the argument list (which could be expressions, other
+# variables, etc) into raw values
+ if ($args) {
+ debug("$::level $f executing $fieldname with args:\n".Dumper($args)."\n");
+ ($values) = execute($args);
+ debug("$::level $f returned values:\n".Dumper($values)."\n");
+ }
+ }
+
+ debug("$::level $f after execute, \@_=\n".Dumper(\@_)."\n");
+
+#call the function
+ if (ref $val) {
+ debug("$::level $f : inside loop(before) {\n".Dumper($val)."\n");
+ debug("$::level $f : inside loop(before) {\n".Dumper($val)."\n");
+ if ($args) {
+ debug("$::level $f: function call\n");
+#$val = $$val->$fieldname ($args); # method call
+ my $func = $val->{$fieldname}; # method call
+ debug("$::level $f: $fieldname func=\n ".Dumper($func)."\n");
+ no strict;
+ $val = &$func($val, @$values);
+ debug("$::level $f: $fieldname result=$val\n");
+ debug("$::level $f: $fieldname result=\n".Dumper($val)."\n");
+
+ } else {
+ &::debug("$::level $f: plain field access\n");
+ if (ref $val eq "REF") {
+ $val = $$val->{$fieldname}; # field access
+ } else {
+ $val = $val->{$fieldname}; # field access
+ }
+ }
+ debug("$::level $f } inside loop(after val retrieval) val=\n".Dumper($val)."\n");
+ }
+ $pass++;
+
+ }
+
+ return $val;
+ }
+
+ #$return = [ "variablename", \$variableinfo ];
+ sub variablename {
+ my $f = "variablename";
+ debug("$::level $f: input\n".Dumper(\@_)."\n");
+ my $var = $_[1];
+ return $var;
+ }
+
+ #arglist: '(' list(?) ')'
+ sub arglist {
+ my ($list) = exe_all($_[2]);
+ debug("$::level list: ".Dumper($list)."\n");
+ if ($list) {
+ my $ll = $list->[0];
+ debug("$::level ll \n".Dumper($ll)."\n");
+ debug("$::level \$\$list: \n");
+ return $ll;
+ }
+ return undef;
+ }
+
+ #list: expression (',' list)(s?)
+ sub list {
+ my ($expr, $alt) = ( execute($_[1]), $_[2] );
+
+ if (scalar @$alt) {
+ my ($list) = exe_optional($alt, 2);
+
+ debug("$::level list: expr: $expr\n");
+ debug("$::level list: list: $list\n:");
+ debug("$::level list ".Dumper($list)."\n");
+ my $r = [ $expr, (@$list) ];
+ return $r;
+ }
+ debug("$::level returning simple expression: $expr\n:");
+ return [$expr];
+ }
+
+
+
+ sub _default {
+ debug ("$::level default rule {\n");
+ indent();
+ debug ("$::level parsing parameters\n");
+ my @item = exe_all(@_);
+ debug ("$::level default rule - last item in array is: ".$item[$#item]."\n");
+ my $r = join "",@item[1..$#item];
+ debug ("$::level default rule - returning: $r\n");
+ deindent();
+ debug ("$::level }\n");
+ return $r;
+
+ }
+
+
+}
+
+
+package Template::Velocity::Executor;
+
+use Data::Dumper;
+
+
+
+sub new
+{
+ my $class = shift;
+
+ my $parsetree = shift;
+ my $parser = shift;
+
+ my $self = {};
+ $self->{parser} = $parser;
+ $self->{parsetree} = $parsetree;
+ bless $self, $class;
+ return $self;
+}
+
+
+sub run {
+ my $self = shift;
+
+ return (execute($self->{parsetree}));
+}
+
+
+
+my $level = " ";
+
+sub debug {
+ if ($::debugflag) {
+ print @_;
+ }
+}
+
+# This basically all works calling execute($parsetree).
+# Execute will look the Parsetree, which is built by a special autoaction
+#
+# It will call top-down, into functions called 'Executor::XXX', (where XXX is
+# the name of the production)
+#
+# Additional trees, representing child productions, will be passed in
+# as arguments to the Executor::XXX function. These arguments be processed
+# before the Executor::XXX function can proceed.
+#
+# If no such function is present, Executor:_default will be run
+#
+# To process the arguments, use this in the Executor function:
+# my @item = exe(@_);
+# Which will give you an @item array similar to that in the RD rules, one
+# exception being that productions which return arrays are flattened into
+# the @item array. (bad idea?)
+#
+
+
+
+# executes a parsetree (gotten as a result of calling recdescent $parser->rule()
+# and returns the string value of the result.
+
+sub Dumper {
+ "";
+}
+
+sub execute {
+ my $result;
+ my $tree = shift; # a reference to a tree is passed in
+ debug "$level execute: {\n";
+ indent();
+ debug ("$level tree = \n".Dumper($tree)."\n");
+
+# there are 3 possible things this tree could be:
+
+# 1 a scalar .. in which case this rule represents a literal, and the
+# the literal is just returned
+#
+# 2 an array of the form (array, ...) - in which case this is the result of a production
+# which returned an array of trees. This happens
+# if you specify (s), (?), etc, in a production.
+# 3 an array of the form (scalar, ...) - in which case this refers to a subrule
+#
+
+# case 1...
+ my $type = ref $tree;
+ if ($type) {
+ debug "\n$level tree type: ".(ref $tree)." \n";
+ } else {
+ debug "\n$level tree type: scalar \n";
+ }
+ if ($type ne "ARRAY") {
+ debug "$level returning literal: '$tree'\n";
+ deindent();
+ debug "$level }\n\n";
+ return $tree;
+ }
+
+ my @result;
+
+# if this tree is the result of a auto-generated rule (e.g. alternation)
+# then tree[0] is not a name.. it is an array. just call the default action with
+# the arguments
+
+ my $rule = @{$tree}->[0]; # rule name is first
+
+ if ($rule && ref $rule eq "ARRAY") { # case 2
+ debug "$level element[0] is an array (case 2) \n";
+ debug "$level contents of input: \n".Dumper(\@{$tree})."\n";
+ #@result = exe(@{$rule});
+ debug "$level running exe on the array..\n";
+ # not sure about this...
+ @result = (exe_all(@{$tree}));
+ debug "$level contents of output: \n".Dumper(\@result)."\n";
+ #shift @result; # get rid of function name
+ $result = \@result;
+
+ } else { # case 3
+ my @args = @{$tree};
+
+ debug "$level rule is a function to execute (case 3): '$rule'\n";
+ indent();
+ my $qr = "Template::Velocity::Executor::Rules::$rule";
+ if (defined &$qr) {
+ no strict ;
+ $result = (&$qr(@args));
+ } else {
+ debug "$level no function defined for: '$rule' - calling default action\n";
+ $result = Template::Velocity::Executor::Rules::_default(@args);
+ }
+ }
+ deindent();
+ debug "$level function: $rule returned=\n".Dumper($result)."\n";
+
+ debug "$level }\n";
+ return $result;
+
+ }
+
+# these hold and set the current indent level. It's only used for nested debug messages
+sub indent {
+ $level .= " ";
+ $Data::Dumper::Pad = $level." ";
+}
+sub deindent {
+ $level = substr ($level,0,-2);
+ $Data::Dumper::Pad = $level." ";
+}
+
+
+sub exe_optional {
+ my @r;
+ my $f = shift;
+ foreach my $q (@_) {
+ debug("$level: getting arg# $q\n");
+ push @r, execute($f->[0][$q]);
+ }
+ return @r;
+}
+
+# exe: for each argument, run the 'execute' function
+#
+
+sub exe_all {
+ my $d = $Data::Dumper::Maxdepth;
+ $Data::Dumper::Maxdepth = 9;
+ debug "\n$level exe_all (".$_[0].") arguments: {\n".Dumper(\@_)." \n";
+ my @r;
+ indent();
+
+ foreach my $i (@_) {
+ push @r, execute($i);
+ }
+ deindent();
+ debug "$level exe_all: returning: \n".Dumper(\@r)."$level}\n\n";
+ $Data::Dumper::Maxdepth = $d;
+ return @r;
+}
+
+
+
+
+
+#package PKI::TPS::GlobalVar;
+
+#sub new { my $self = {}; bless $self; return $self; }
+
+
+1;
+
diff --git a/base/tps/wrappers/tpsclient.in b/base/tps/wrappers/tpsclient.in
new file mode 100755
index 000000000..5f2f6b3f5
--- /dev/null
+++ b/base/tps/wrappers/tpsclient.in
@@ -0,0 +1,78 @@
+#!/bin/sh
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; 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 ---
+
+
+###############################################################################
+## (1) Specify variables used by this script. ##
+###############################################################################
+
+LIB_DIR=@nss_libdir@:@nspr_libdir@:@ldapsdk_libdir@:@sasl_libdir@
+BIN_DIR=@libexecdir@
+COMMAND=tpsclient
+
+
+###############################################################################
+## (2) Set the LD_LIBRARY_PATH environment variable to determine the ##
+## search order this command wrapper uses to find shared libraries. ##
+###############################################################################
+
+LD_LIBRARY_PATH=${LIB_DIR}
+export LD_LIBRARY_PATH
+
+
+###############################################################################
+## (3) Set the PATH environment variable to determine the search ##
+## order this command wrapper uses to find binary executables. ##
+## ##
+## NOTE: Since the wrappers themselves are ALWAYS located in ##
+## "/usr/bin", this directory will always be excluded ##
+## from the search path. Since "/bin" is nothing more ##
+## than a symbolic link to "/usr/bin" on Solaris, this ##
+## directory will also always be excluded from the search ##
+## path on this platform. ##
+###############################################################################
+
+PATH=${BIN_DIR}
+export PATH
+
+
+###############################################################################
+## (4) Execute the binary executable specified by this command wrapper ##
+## based upon the preset LD_LIBRARY_PATH and PATH environment variables.##
+###############################################################################
+
+ORIGINAL_IFS=${IFS}
+IFS=:
+
+for dir in ${PATH}
+do
+ if [ -x ${dir}/${COMMAND} ]
+ then
+ IFS=${ORIGINAL_IFS}
+ ${dir}/${COMMAND} "$@"
+ exit $?
+ fi
+done
+
+echo "Unable to find \"${COMMAND}\" in \"${PATH}\"!"
+
+exit 255
+
diff --git a/base/util/CMakeLists.txt b/base/util/CMakeLists.txt
new file mode 100644
index 000000000..b8600ba4c
--- /dev/null
+++ b/base/util/CMakeLists.txt
@@ -0,0 +1,4 @@
+project(util Java)
+
+add_subdirectory(src)
+add_subdirectory(test)
diff --git a/base/util/LICENSE b/base/util/LICENSE
new file mode 100644
index 000000000..e281f4362
--- /dev/null
+++ b/base/util/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/base/util/src/CMakeLists.txt b/base/util/src/CMakeLists.txt
new file mode 100644
index 000000000..592e3b59b
--- /dev/null
+++ b/base/util/src/CMakeLists.txt
@@ -0,0 +1,369 @@
+project(pki-cmsutil_java Java)
+
+find_file(JSS_JAR
+ NAMES
+ jss4.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(LDAPJDK_JAR
+ NAMES
+ ldapjdk.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(COMMONS_CODEC_JAR
+ NAMES
+ commons-codec.jar
+ PATHS
+ /usr/share/java
+)
+
+find_file(XALAN_JAR
+ NAMES
+ xalan-j2.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(XERCES_JAR
+ NAMES
+ xerces-j2.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+set(pki-nsutil_java_SRCS
+ netscape/net/TransferProtocolClient.java
+ netscape/net/smtp/SmtpProtocolException.java
+ netscape/net/smtp/SmtpClient.java
+ netscape/net/NetworkClient.java
+ netscape/security/pkcs/ParsingException.java
+ netscape/security/pkcs/PKCS9Attribute.java
+ netscape/security/pkcs/EncodingException.java
+ netscape/security/pkcs/SignerInfo.java
+ netscape/security/pkcs/PKCS10Attribute.java
+ netscape/security/pkcs/PKCS9Attributes.java
+ netscape/security/pkcs/ContentInfo.java
+ netscape/security/pkcs/PKCS10.java
+ netscape/security/pkcs/PKCS10Attributes.java
+ netscape/security/pkcs/PKCS7.java
+ netscape/security/pkcs/PKCS8Key.java
+ netscape/security/x509/OIDName.java
+ netscape/security/x509/CertificateChain.java
+ netscape/security/x509/CertificateVersion.java
+ netscape/security/x509/LdapV3DNStrConverter.java
+ netscape/security/x509/IssuerAlternativeNameExtension.java
+ netscape/security/x509/PolicyMappingsExtension.java
+ netscape/security/x509/CRLExtensions.java
+ netscape/security/x509/X500NameAttrMap.java
+ netscape/security/x509/CertificatePolicySet.java
+ netscape/security/x509/X509Cert.java
+ netscape/security/x509/NSCCommentExtension.java
+ netscape/security/x509/Attribute.java
+ netscape/security/x509/PrivateKeyUsageExtension.java
+ netscape/security/x509/X509CRLImpl.java
+ netscape/security/x509/X500Signer.java
+ netscape/security/x509/CPSuri.java
+ netscape/security/x509/AlgorithmId.java
+ netscape/security/x509/SerialNumber.java
+ netscape/security/x509/X509CertImpl.java
+ netscape/security/x509/CertificatePolicyInfo.java
+ netscape/security/x509/CertException.java
+ netscape/security/x509/CRLNumberExtension.java
+ netscape/security/x509/GeneralNameInterface.java
+ netscape/security/x509/PolicyQualifiers.java
+ netscape/security/x509/AVA.java
+ netscape/security/x509/CertificateX509Key.java
+ netscape/security/x509/RFC822Name.java
+ netscape/security/x509/Extensions.java
+ netscape/security/x509/FreshestCRLExtension.java
+ netscape/security/x509/UserNotice.java
+ netscape/security/x509/ReasonFlags.java
+ netscape/security/x509/InvalidIPAddressException.java
+ netscape/security/x509/IPAddressName.java
+ netscape/security/x509/SubjectKeyIdentifierExtension.java
+ netscape/security/x509/GenericValueConverter.java
+ netscape/security/x509/CRLReasonExtension.java
+ netscape/security/x509/CertificateAlgorithmId.java
+ netscape/security/x509/DisplayText.java
+ netscape/security/x509/CertificateValidity.java
+ netscape/security/x509/PKIXExtensions.java
+ netscape/security/x509/PrintableConverter.java
+ netscape/security/x509/SubjectDirAttributesExtension.java
+ netscape/security/x509/CRLDistributionPoint.java
+ netscape/security/x509/NameConstraintsExtension.java
+ netscape/security/x509/X509AttributeName.java
+ netscape/security/x509/RFC1779StrConverter.java
+ netscape/security/x509/X500Name.java
+ netscape/security/x509/DNSName.java
+ netscape/security/x509/URIName.java
+ netscape/security/x509/CertAndKeyGen.java
+ netscape/security/x509/RevocationReason.java
+ netscape/security/x509/AVAValueConverter.java
+ netscape/security/x509/CRLDistributionPointsExtension.java
+ netscape/security/x509/GeneralSubtree.java
+ netscape/security/x509/X509Key.java
+ netscape/security/x509/PolicyConstraintsExtension.java
+ netscape/security/x509/X509CertInfo.java
+ netscape/security/x509/LdapDNStrConverter.java
+ netscape/security/x509/X509ExtensionException.java
+ netscape/security/x509/AuthorityKeyIdentifierExtension.java
+ netscape/security/x509/NoticeReference.java
+ netscape/security/x509/IA5StringConverter.java
+ netscape/security/x509/UniqueIdentity.java
+ netscape/security/x509/RevokedCertificate.java
+ netscape/security/x509/CertificateExtensions.java
+ netscape/security/x509/HoldInstructionExtension.java
+ netscape/security/x509/IssuingDistributionPoint.java
+ netscape/security/x509/GeneralName.java
+ netscape/security/x509/CertificateIssuerName.java
+ netscape/security/x509/IssuingDistributionPointExtension.java
+ netscape/security/x509/AlgIdDSA.java
+ netscape/security/x509/DeltaCRLIndicatorExtension.java
+ netscape/security/x509/GeneralSubtrees.java
+ netscape/security/x509/BasicConstraintsExtension.java
+ netscape/security/x509/CertAttrSet.java
+ netscape/security/x509/GeneralNamesException.java
+ netscape/security/x509/ACertAttrSet.java
+ netscape/security/x509/Qualifier.java
+ netscape/security/x509/KeyIdentifier.java
+ netscape/security/x509/CertificateSerialNumber.java
+ netscape/security/x509/KeyUsageExtension.java
+ netscape/security/x509/SubjectAlternativeNameExtension.java
+ netscape/security/x509/CertificateSubjectUniqueIdentity.java
+ netscape/security/x509/CertificateSubjectName.java
+ netscape/security/x509/GeneralNames.java
+ netscape/security/x509/Extension.java
+ netscape/security/x509/CertificatePoliciesExtension.java
+ netscape/security/x509/CertificateIssuerExtension.java
+ netscape/security/x509/RDN.java
+ netscape/security/x509/CertificatePolicyMap.java
+ netscape/security/x509/DirStrConverter.java
+ netscape/security/x509/CertificateIssuerUniqueIdentity.java
+ netscape/security/x509/PolicyQualifierInfo.java
+ netscape/security/x509/EDIPartyName.java
+ netscape/security/x509/InvalidityDateExtension.java
+ netscape/security/x509/CertificatePolicyId.java
+ netscape/security/x509/CertParseError.java
+ netscape/security/x509/OIDMap.java
+ netscape/security/x509/PolicyConstraint.java
+ netscape/security/x509/RevokedCertImpl.java
+ netscape/security/x509/OtherName.java
+ netscape/security/util/ASN1CharsetProvider.java
+ netscape/security/util/ASN1CharStrConvMap.java
+ netscape/security/util/BigInt.java
+ netscape/security/util/BitArray.java
+ netscape/security/util/ByteArrayLexOrder.java
+ netscape/security/util/ByteArrayTagOrder.java
+ netscape/security/util/CertPrettyPrint.java
+ netscape/security/util/CrlPrettyPrint.java
+ netscape/security/util/DerEncoder.java
+ netscape/security/util/DerInputBuffer.java
+ netscape/security/util/DerInputStream.java
+ netscape/security/util/DerOutputStream.java
+ netscape/security/util/DerValue.java
+ netscape/security/util/ExtPrettyPrint.java
+ netscape/security/util/IA5Charset.java
+ netscape/security/util/IA5CharsetDecoder.java
+ netscape/security/util/IA5CharsetEncoder.java
+ netscape/security/util/ObjectIdentifier.java
+ netscape/security/util/PrettyPrintFormat.java
+ netscape/security/util/PrettyPrintResources.java
+ netscape/security/util/PrintableCharset.java
+ netscape/security/util/PrintableCharsetDecoder.java
+ netscape/security/util/PrintableCharsetEncoder.java
+ netscape/security/util/PubKeyPrettyPrint.java
+ netscape/security/util/UniversalCharset.java
+ netscape/security/util/UniversalCharsetDecoder.java
+ netscape/security/util/UniversalCharsetEncoder.java
+ netscape/security/provider/DSA.java
+ netscape/security/provider/DSAPrivateKey.java
+ netscape/security/provider/DSAParameters.java
+ netscape/security/provider/DSAPublicKey.java
+ netscape/security/provider/RSAPublicKey.java
+ netscape/security/provider/SHA.java
+ netscape/security/provider/MD5.java
+ netscape/security/provider/DSAParameterGenerator.java
+ netscape/security/provider/CMS.java
+ netscape/security/provider/DSAKeyPairGenerator.java
+ netscape/security/provider/DSAKeyFactory.java
+ netscape/security/provider/Sun.java
+ netscape/security/provider/X509CertificateFactory.java
+ netscape/security/extensions/SubjectInfoAccessExtension.java
+ netscape/security/extensions/GenericASN1Extension.java
+ netscape/security/extensions/NSCertTypeExtension.java
+ netscape/security/extensions/CertificateScopeEntry.java
+ netscape/security/extensions/KerberosName.java
+ netscape/security/extensions/CertificateRenewalWindowExtension.java
+ netscape/security/extensions/PresenceServerExtension.java
+ netscape/security/extensions/OCSPNoCheckExtension.java
+ netscape/security/extensions/CertInfo.java
+ netscape/security/extensions/AccessDescription.java
+ netscape/security/extensions/InhibitAnyPolicyExtension.java
+ netscape/security/extensions/CertificateScopeOfUseExtension.java
+ netscape/security/extensions/AuthInfoAccessExtension.java
+ netscape/security/extensions/ExtendedKeyUsageExtension.java
+ netscape/security/acl/AclImpl.java
+ netscape/security/acl/AllPermissionsImpl.java
+ netscape/security/acl/PrincipalImpl.java
+ netscape/security/acl/AclEntryImpl.java
+ netscape/security/acl/OwnerImpl.java
+ netscape/security/acl/WorldGroupImpl.java
+ netscape/security/acl/GroupImpl.java
+ netscape/security/acl/PermissionImpl.java
+)
+
+set(pki-cmsutil_java_SRCS
+ com/netscape/cmsutil/ldap/LDAPUtil.java
+ com/netscape/cmsutil/xml/XMLObject.java
+ com/netscape/cmsutil/scep/CRSPKIMessage.java
+ com/netscape/cmsutil/util/Cert.java
+ com/netscape/cmsutil/util/Fmt.java
+ com/netscape/cmsutil/util/HMACDigest.java
+ com/netscape/cmsutil/util/Utils.java
+ com/netscape/cmsutil/net/ISocketFactory.java
+ com/netscape/cmsutil/crypto/Token.java
+ com/netscape/cmsutil/crypto/Module.java
+ com/netscape/cmsutil/crypto/CryptoUtil.java
+ com/netscape/cmsutil/password/PlainPasswordReader.java
+ com/netscape/cmsutil/password/IPasswordWriter.java
+ com/netscape/cmsutil/password/IPasswordStore.java
+ com/netscape/cmsutil/password/IPasswordReader.java
+ com/netscape/cmsutil/password/PlainPasswordWriter.java
+ com/netscape/cmsutil/password/PlainPasswordFile.java
+ com/netscape/cmsutil/radius/FramedProtocolAttribute.java
+ com/netscape/cmsutil/radius/TerminationActionAttribute.java
+ com/netscape/cmsutil/radius/NASPortTypeAttribute.java
+ com/netscape/cmsutil/radius/LoginLATServiceAttribute.java
+ com/netscape/cmsutil/radius/VendorSpecificAttribute.java
+ com/netscape/cmsutil/radius/ServiceTypeAttribute.java
+ com/netscape/cmsutil/radius/FramedAppleTalkLinkAttribute.java
+ com/netscape/cmsutil/radius/RadiusConn.java
+ com/netscape/cmsutil/radius/StateAttribute.java
+ com/netscape/cmsutil/radius/Attribute.java
+ com/netscape/cmsutil/radius/ReplyMessageAttribute.java
+ com/netscape/cmsutil/radius/ResponseAuthenticator.java
+ com/netscape/cmsutil/radius/GenericAttribute.java
+ com/netscape/cmsutil/radius/AccessChallenge.java
+ com/netscape/cmsutil/radius/FramedMTUAttribute.java
+ com/netscape/cmsutil/radius/NASPortAttribute.java
+ com/netscape/cmsutil/radius/CallingStationIdAttribute.java
+ com/netscape/cmsutil/radius/UserNameAttribute.java
+ com/netscape/cmsutil/radius/PacketFactory.java
+ com/netscape/cmsutil/radius/UserPasswordAttribute.java
+ com/netscape/cmsutil/radius/NASPacket.java
+ com/netscape/cmsutil/radius/FramedRoutingAttribute.java
+ com/netscape/cmsutil/radius/LoginLATNodeAttribute.java
+ com/netscape/cmsutil/radius/AttributeSet.java
+ com/netscape/cmsutil/radius/RequestAuthenticator.java
+ com/netscape/cmsutil/radius/CHAPPasswordAttribute.java
+ com/netscape/cmsutil/radius/FramedIPNetmaskAttribute.java
+ com/netscape/cmsutil/radius/LoginLATPortAttribute.java
+ com/netscape/cmsutil/radius/CallbackNumberAttribute.java
+ com/netscape/cmsutil/radius/RejectException.java
+ com/netscape/cmsutil/radius/ChallengeException.java
+ com/netscape/cmsutil/radius/NASClassAttribute.java
+ com/netscape/cmsutil/radius/LoginTCPPortAttribute.java
+ com/netscape/cmsutil/radius/IdleTimeoutAttribute.java
+ com/netscape/cmsutil/radius/AccessReject.java
+ com/netscape/cmsutil/radius/SessionTimeoutAttribute.java
+ com/netscape/cmsutil/radius/FramedIPAddressAttribute.java
+ com/netscape/cmsutil/radius/FramedRouteAttribute.java
+ com/netscape/cmsutil/radius/AccessAccept.java
+ com/netscape/cmsutil/radius/FramedAppleTalkNetworkAttribute.java
+ com/netscape/cmsutil/radius/ProxyStateAttribute.java
+ com/netscape/cmsutil/radius/FilterIdAttribute.java
+ com/netscape/cmsutil/radius/NASIdentifierAttribute.java
+ com/netscape/cmsutil/radius/LoginIPHostAttribute.java
+ com/netscape/cmsutil/radius/LoginServiceAttribute.java
+ com/netscape/cmsutil/radius/PortLimitAttribute.java
+ com/netscape/cmsutil/radius/AttributeFactory.java
+ com/netscape/cmsutil/radius/ServerPacket.java
+ com/netscape/cmsutil/radius/FramedAppleTalkZoneAttribute.java
+ com/netscape/cmsutil/radius/CHAPChallengeAttribute.java
+ com/netscape/cmsutil/radius/AccessRequest.java
+ com/netscape/cmsutil/radius/CallerStationIdAttribute.java
+ com/netscape/cmsutil/radius/Packet.java
+ com/netscape/cmsutil/radius/CallbackIdAttribute.java
+ com/netscape/cmsutil/radius/FramedIPXNetworkAttribute.java
+ com/netscape/cmsutil/radius/LoginLATGroupAttribute.java
+ com/netscape/cmsutil/radius/Authenticator.java
+ com/netscape/cmsutil/radius/NASIPAddressAttribute.java
+ com/netscape/cmsutil/radius/FramedCompressionAttribute.java
+ com/netscape/cmsutil/http/ConnectAsync.java
+ com/netscape/cmsutil/http/JssSSLSocketFactory.java
+ com/netscape/cmsutil/http/HttpClient.java
+ com/netscape/cmsutil/http/HttpMessage.java
+ com/netscape/cmsutil/http/HttpRequest.java
+ com/netscape/cmsutil/http/HttpResponse.java
+ com/netscape/cmsutil/http/Http.java
+ com/netscape/cmsutil/http/HttpEofException.java
+ com/netscape/cmsutil/http/HttpProtocolException.java
+ com/netscape/cmsutil/ocsp/Signature.java
+ com/netscape/cmsutil/ocsp/RevokedInfo.java
+ com/netscape/cmsutil/ocsp/TBSRequest.java
+ com/netscape/cmsutil/ocsp/CertID.java
+ com/netscape/cmsutil/ocsp/NameID.java
+ com/netscape/cmsutil/ocsp/KeyHashID.java
+ com/netscape/cmsutil/ocsp/OCSPRequest.java
+ com/netscape/cmsutil/ocsp/Response.java
+ com/netscape/cmsutil/ocsp/GoodInfo.java
+ com/netscape/cmsutil/ocsp/SingleResponse.java
+ com/netscape/cmsutil/ocsp/BasicOCSPResponse.java
+ com/netscape/cmsutil/ocsp/ResponseBytes.java
+ com/netscape/cmsutil/ocsp/OCSPResponse.java
+ com/netscape/cmsutil/ocsp/UnknownInfo.java
+ com/netscape/cmsutil/ocsp/OCSPResponseStatus.java
+ com/netscape/cmsutil/ocsp/CertStatus.java
+ com/netscape/cmsutil/ocsp/ResponseData.java
+ com/netscape/cmsutil/ocsp/Request.java
+ com/netscape/cmsutil/ocsp/ResponderID.java
+)
+
+set(CMAKE_JAVA_INCLUDE_PATH
+ ${LDAPJDK_JAR} ${XALAN_JAR} ${XERCES_JAR}
+ ${JSS_JAR} ${COMMONS_CODEC_JAR})
+
+set(CMAKE_JAVA_TARGET_VERSION ${APPLICATION_VERSION})
+
+# build pki-nsutil
+set(CMAKE_JAR_CLASSES_PREFIX netscape)
+add_jar(pki-nsutil ${pki-nsutil_java_SRCS})
+install_jar(pki-nsutil ${JAVA_JAR_INSTALL_DIR}/pki)
+set(PKI_NSUTIL_JAR ${pki-nsutil_JAR_FILE} CACHE INTERNAL "pki-nsutil jar file")
+
+# build pki-cmsutil
+set(CMAKE_JAR_CLASSES_PREFIX com/netscape/cmsutil)
+add_jar(pki-cmsutil ${pki-cmsutil_java_SRCS})
+add_dependencies(pki-cmsutil pki-nsutil)
+install_jar(pki-cmsutil ${JAVA_JAR_INSTALL_DIR}/pki)
+set(PKI_CMSUTIL_JAR ${pki-cmsutil_JAR_FILE} CACHE INTERNAL "pki-cmsutil jar file")
+
+create_javadoc(pki-util-${APPLICATION_VERSION}
+ PACKAGES com.netscape.cmsutil.crypto
+ com.netscape.cmsutil.http
+ com.netscape.cmsutil.ldap
+ com.netscape.cmsutil.net
+ com.netscape.cmsutil.ocsp
+ com.netscape.cmsutil.password
+ com.netscape.cmsutil.radius
+ com.netscape.cmsutil.scep
+ com.netscape.cmsutil.util
+ com.netscape.cmsutil.xml
+ SOURCEPATH ${CMAKE_CURRENT_SOURCE_DIR}
+ CLASSPATH ${CMAKE_JAVA_INCLUDE_PATH}
+ WINDOWTITLE "pki-util"
+ WINDOWTITLE "pki-util"
+ DOCTITLE "<h1>dogtag</h1>"
+ AUTHOR TRUE
+ USE TRUE
+ VERSION TRUE
+)
+add_dependencies(pki-util-${APPLICATION_VERSION}_javadoc pki-cmsutil)
diff --git a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
new file mode 100644
index 000000000..bf8a9cfc1
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
@@ -0,0 +1,1292 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmsutil.crypto;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.CharConversionException;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.interfaces.DSAParams;
+import java.security.interfaces.DSAPublicKey;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.security.pkcs.PKCS10;
+import netscape.security.pkcs.PKCS7;
+import netscape.security.util.BigInt;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateAlgorithmId;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateIssuerName;
+import netscape.security.x509.CertificateSerialNumber;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X500Signer;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.CryptoManager.NotInitializedException;
+import org.mozilla.jss.NoSuchTokenException;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.BIT_STRING;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.crypto.Algorithm;
+import org.mozilla.jss.crypto.BadPaddingException;
+import org.mozilla.jss.crypto.Cipher;
+import org.mozilla.jss.crypto.CryptoStore;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.DigestAlgorithm;
+import org.mozilla.jss.crypto.EncryptionAlgorithm;
+import org.mozilla.jss.crypto.IVParameterSpec;
+import org.mozilla.jss.crypto.IllegalBlockSizeException;
+import org.mozilla.jss.crypto.InternalCertificate;
+import org.mozilla.jss.crypto.InvalidKeyFormatException;
+import org.mozilla.jss.crypto.KeyGenAlgorithm;
+import org.mozilla.jss.crypto.KeyGenerator;
+import org.mozilla.jss.crypto.KeyPairAlgorithm;
+import org.mozilla.jss.crypto.KeyPairGenerator;
+import org.mozilla.jss.crypto.KeyWrapAlgorithm;
+import org.mozilla.jss.crypto.KeyWrapper;
+import org.mozilla.jss.crypto.NoSuchItemOnTokenException;
+import org.mozilla.jss.crypto.ObjectNotFoundException;
+import org.mozilla.jss.crypto.PBEAlgorithm;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.crypto.Signature;
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+import org.mozilla.jss.crypto.SymmetricKey;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.pkcs11.PK11ECPublicKey;
+import org.mozilla.jss.pkcs12.PasswordConverter;
+import org.mozilla.jss.pkcs7.EncryptedContentInfo;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.crmf.CertTemplate;
+import org.mozilla.jss.pkix.crmf.EncryptedKey;
+import org.mozilla.jss.pkix.crmf.EncryptedValue;
+import org.mozilla.jss.pkix.crmf.PKIArchiveOptions;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.pkix.primitive.Name;
+import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
+import org.mozilla.jss.util.Base64OutputStream;
+import org.mozilla.jss.util.Password;
+
+import com.netscape.cmsutil.util.Cert;
+import com.netscape.cmsutil.util.Utils;
+
+public class CryptoUtil {
+
+ public static final String CERTREQ_BEGIN_HEADING = "-----BEGIN CERTIFICATE REQUEST-----";
+ public static final String CERTREQ_END_HEADING = "-----END CERTIFICATE REQUEST-----";
+ public static final int LINE_COUNT = 76;
+ public static final String CERT_BEGIN_HEADING = "-----BEGIN CERTIFICATE-----";
+ public static final String CERT_END_HEADING = "-----END CERTIFICATE-----";
+
+ /*
+ * encodes cert
+ */
+ // private static BASE64Encoder mEncoder = new BASE64Encoder();
+ public static String toMIME64(X509CertImpl cert) {
+ try {
+ return "-----BEGIN CERTIFICATE-----\n"
+ // + mEncoder.encodeBuffer(cert.getEncoded())
+ + Utils.base64encode(cert.getEncoded())
+ + "-----END CERTIFICATE-----\n";
+ } catch (Exception e) {
+ }
+ return null;
+ }
+
+ public static boolean arraysEqual(byte[] bytes, byte[] ints) {
+ if (bytes == null || ints == null) {
+ return false;
+ }
+
+ if (bytes.length != ints.length) {
+ return false;
+ }
+
+ for (int i = 0; i < bytes.length; i++) {
+ if (bytes[i] != ints[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Retrieves handle to a JSS token.
+ */
+ public static CryptoToken getTokenByName(String token)
+ throws CryptoManager.NotInitializedException,
+ NoSuchTokenException {
+ CryptoManager cm = CryptoManager.getInstance();
+ CryptoToken t = null;
+
+ if (token.equals("internal")) {
+ t = cm.getInternalKeyStorageToken();
+ } else {
+ t = cm.getTokenByName(token);
+ }
+ return t;
+ }
+
+ /**
+ * Generates a RSA key pair.
+ */
+ public static KeyPair generateRSAKeyPair(String token, int keysize)
+ throws CryptoManager.NotInitializedException,
+ NoSuchTokenException,
+ NoSuchAlgorithmException,
+ TokenException {
+ CryptoToken t = getTokenByName(token);
+ KeyPairGenerator g = t.getKeyPairGenerator(KeyPairAlgorithm.RSA);
+
+ g.initialize(keysize);
+ KeyPair pair = g.genKeyPair();
+
+ return pair;
+ }
+
+ public static boolean isECCKey(X509Key key) {
+ String keyAlgo = key.getAlgorithm();
+ if (keyAlgo.equals("EC") ||
+ keyAlgo.equals("OID.1.2.840.10045.44")) { // ECC
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Generates an ecc key pair.
+ */
+ public static KeyPair generateECCKeyPair(String token, int keysize)
+ throws CryptoManager.NotInitializedException,
+ NoSuchTokenException,
+ NoSuchAlgorithmException,
+ TokenException {
+ return generateECCKeyPair(token, keysize, null, null);
+ }
+
+ public static KeyPair generateECCKeyPair(String token, int keysize,
+ org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage[] usage_ops,
+ org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage[] usage_mask)
+ throws CryptoManager.NotInitializedException,
+ NoSuchTokenException,
+ NoSuchAlgorithmException,
+ TokenException {
+ CryptoToken t = getTokenByName(token);
+
+ KeyPairAlgorithm alg = KeyPairAlgorithm.EC;
+ KeyPairGenerator g = t.getKeyPairGenerator(alg);
+
+ g.setKeyPairUsages(usage_ops, usage_mask);
+ g.initialize(keysize);
+
+ KeyPair pair = g.genKeyPair();
+
+ return pair;
+ }
+
+ /**
+ * Generates an ecc key pair by curve name
+ */
+ public static KeyPair generateECCKeyPair(String token, String curveName)
+ throws CryptoManager.NotInitializedException,
+ NoSuchTokenException,
+ NoSuchAlgorithmException,
+ TokenException {
+ return generateECCKeyPair(token, curveName, null, null);
+ }
+
+ public static KeyPair generateECCKeyPair(CryptoToken token, String curveName)
+ throws CryptoManager.NotInitializedException,
+ NoSuchTokenException,
+ NoSuchAlgorithmException,
+ TokenException {
+ return generateECCKeyPair(token, curveName, null, null);
+ }
+
+ public static KeyPair generateECCKeyPair(String token, String curveName,
+ org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage[] usage_ops,
+ org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage[] usage_mask)
+ throws CryptoManager.NotInitializedException,
+ NoSuchTokenException,
+ NoSuchAlgorithmException,
+ TokenException {
+ CryptoToken t = getTokenByName(token);
+ return generateECCKeyPair(t, curveName, usage_ops, usage_mask);
+ }
+
+ public static KeyPair generateECCKeyPair(CryptoToken token, String curveName,
+ org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage[] usage_ops,
+ org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage[] usage_mask)
+ throws CryptoManager.NotInitializedException,
+ NoSuchTokenException,
+ NoSuchAlgorithmException,
+ TokenException {
+ KeyPairAlgorithm alg = KeyPairAlgorithm.EC;
+ KeyPairGenerator g = token.getKeyPairGenerator(alg);
+
+ g.setKeyPairUsages(usage_ops, usage_mask);
+
+ System.out.println("CryptoUtil: generateECCKeyPair: curve = " + curveName);
+ int curveCode = 0;
+ try {
+ curveCode = g.getCurveCodeByName(curveName);
+ } catch (Exception e) {
+ System.out.println("CryptoUtil: generateECCKeyPair: " + e.toString());
+ throw new NoSuchAlgorithmException();
+ }
+ g.initialize(curveCode);
+
+ System.out.println("CryptoUtil: generateECCKeyPair: after KeyPairGenerator initialize with:" + curveName);
+ KeyPair pair = g.genKeyPair();
+
+ return pair;
+ }
+
+ public static byte[] getModulus(PublicKey pubk) {
+ RSAPublicKey rsaKey = (RSAPublicKey) pubk;
+
+ return rsaKey.getModulus().toByteArray();
+ }
+
+ public static byte[] getPublicExponent(PublicKey pubk) {
+ RSAPublicKey rsaKey = (RSAPublicKey) pubk;
+
+ return rsaKey.getPublicExponent().toByteArray();
+ }
+
+ 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[] base64Decode(String s) throws IOException {
+ // BASE64Decoder base64 = new BASE64Decoder();
+ // byte[] d = base64.decodeBuffer(s);
+ byte[] d = Utils.base64decode(s);
+
+ return d;
+ }
+
+ /*
+ * formats a cert request
+ */
+ public static String reqFormat(String content) {
+ String result = CERTREQ_BEGIN_HEADING + "\n";
+
+ while (content.length() >= LINE_COUNT) {
+ result = result + content.substring(0, LINE_COUNT) + "\n";
+ content = content.substring(LINE_COUNT);
+ }
+ if (content.length() > 0) {
+ result = result + content + "\n" + CERTREQ_END_HEADING;
+ } else {
+ result = result + CERTREQ_END_HEADING;
+ }
+
+ return result;
+ }
+
+ public static String getPKCS10FromKey(String dn,
+ byte modulus[], byte exponent[], byte prikdata[])
+ throws IOException,
+ InvalidKeyException,
+ TokenException,
+ NoSuchProviderException,
+ CertificateException,
+ SignatureException,
+ CryptoManager.NotInitializedException,
+ NoSuchAlgorithmException {
+ X509Key x509key = getPublicX509Key(modulus, exponent);
+ PrivateKey prik = findPrivateKeyFromID(prikdata);
+ PKCS10 pkcs10 = createCertificationRequest(dn, x509key, prik);
+ ByteArrayOutputStream bs = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(bs);
+ pkcs10.print(ps);
+ return bs.toString();
+ }
+
+ public static String getPKCS10FromKey(String dn,
+ byte modulus[], byte exponent[], byte prikdata[], String alg)
+ throws IOException,
+ InvalidKeyException,
+ TokenException,
+ NoSuchProviderException,
+ CertificateException,
+ SignatureException,
+ CryptoManager.NotInitializedException,
+ NoSuchAlgorithmException {
+ X509Key x509key = getPublicX509Key(modulus, exponent);
+ PrivateKey prik = findPrivateKeyFromID(prikdata);
+ PKCS10 pkcs10 = createCertificationRequest(dn, x509key, prik, alg);
+ ByteArrayOutputStream bs = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(bs);
+ pkcs10.print(ps);
+ return bs.toString();
+ }
+
+ /*
+ * formats a cert
+ */
+ public static String certFormat(String content) {
+ if (content == null || content.length() == 0) {
+ return "";
+ }
+ String result = CERT_BEGIN_HEADING + "\n";
+
+ while (content.length() >= LINE_COUNT) {
+ result = result + content.substring(0, LINE_COUNT) + "\n";
+ content = content.substring(LINE_COUNT);
+ }
+ if (content.length() > 0) {
+ result = result + content + "\n" + CERT_END_HEADING;
+ } else {
+ result = result + CERT_END_HEADING;
+ }
+
+ return result;
+ }
+
+ /**
+ * 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(CERT_BEGIN_HEADING) && s.endsWith(CERT_END_HEADING)) {
+ 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;
+ }
+
+ public static String normalizeCertAndReq(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-----", "");
+ s = s.replaceAll("-----BEGIN CERTIFICATE-----", "");
+ s = s.replaceAll("-----END CERTIFICATE-----", "");
+
+ 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;
+ }
+ if (nextLine.equals("-----BEGIN CERTIFICATE-----")) {
+ continue;
+ }
+ if (nextLine.equals("-----END CERTIFICATE-----")) {
+ continue;
+ }
+ sb.append(nextLine);
+ }
+ return sb.toString();
+ }
+
+ 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 void importCertificateChain(String certchain)
+ throws IOException,
+ CryptoManager.NotInitializedException,
+ TokenException,
+ CertificateEncodingException,
+ CertificateException {
+ byte[] blah = base64Decode(certchain);
+ CryptoManager manager = CryptoManager.getInstance();
+ PKCS7 pkcs7 = null;
+ try {
+ // try PKCS7 first
+ pkcs7 = new PKCS7(blah);
+ } catch (Exception e) {
+ }
+ X509Certificate cert = null;
+ if (pkcs7 == null) {
+ cert = manager.importCACertPackage(blah);
+ } else {
+ java.security.cert.X509Certificate certsInP7[] =
+ pkcs7.getCertificates();
+ if (certsInP7 == null) {
+ cert = manager.importCACertPackage(blah);
+ } else {
+ for (int i = 0; i < certsInP7.length; i++) {
+ // import P7 one by one
+ cert = manager.importCACertPackage(certsInP7[i].getEncoded());
+ }
+ }
+ }
+ X509Certificate[] certchains =
+ CryptoManager.getInstance().buildCertificateChain(cert);
+
+ if (certchains != null) {
+ cert = certchains[certchains.length - 1];
+ }
+ InternalCertificate icert = (InternalCertificate) cert;
+ icert.setSSLTrust(InternalCertificate.TRUSTED_CA
+ | InternalCertificate.TRUSTED_CLIENT_CA
+ | InternalCertificate.VALID_CA);
+ }
+
+ public static SEQUENCE parseCRMFMsgs(byte cert_request[])
+ throws IOException, InvalidBERException {
+ ByteArrayInputStream crmfBlobIn =
+ new ByteArrayInputStream(cert_request);
+ SEQUENCE crmfMsgs = (SEQUENCE)
+ new SEQUENCE.OF_Template(new CertReqMsg.Template()).decode(
+ crmfBlobIn);
+ return crmfMsgs;
+ }
+
+ public static X509Key getX509KeyFromCRMFMsgs(SEQUENCE crmfMsgs)
+ throws IOException, NoSuchAlgorithmException,
+ InvalidKeyException, InvalidKeyFormatException {
+ int nummsgs = crmfMsgs.size();
+ if (nummsgs <= 0) {
+ throw new IOException("invalid certificate requests");
+ }
+ CertReqMsg msg = (CertReqMsg) crmfMsgs.elementAt(0);
+ CertRequest certreq = msg.getCertReq();
+ CertTemplate certTemplate = certreq.getCertTemplate();
+ SubjectPublicKeyInfo spkinfo = certTemplate.getPublicKey();
+ PublicKey pkey = spkinfo.toPublicKey();
+ X509Key x509key = convertPublicKeyToX509Key(pkey);
+ return x509key;
+ }
+
+ public static X509Key getPublicX509Key(byte modulus[], byte exponent[])
+ throws InvalidKeyException {
+ return new netscape.security.provider.RSAPublicKey(new BigInt(modulus),
+ new BigInt(exponent));
+ }
+
+ public static X509Key getPublicX509ECCKey(byte encoded[])
+ throws InvalidKeyException {
+ try {
+ return X509Key.parse(new DerValue(encoded));
+ } catch (IOException e) {
+ throw new InvalidKeyException();
+ }
+ }
+
+ public static X509Key convertPublicKeyToX509Key(PublicKey pubk)
+ throws InvalidKeyException {
+ X509Key xKey;
+
+ if (pubk instanceof RSAPublicKey) {
+ RSAPublicKey rsaKey = (RSAPublicKey) pubk;
+
+ 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 {
+ // Assert.assert(pubk instanceof DSAPublicKey);
+ 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 String getSubjectName(SEQUENCE crmfMsgs)
+ throws IOException {
+ int nummsgs = crmfMsgs.size();
+ if (nummsgs <= 0) {
+ throw new IOException("invalid certificate requests");
+ }
+ CertReqMsg msg = (CertReqMsg) crmfMsgs.elementAt(0);
+ CertRequest certreq = msg.getCertReq();
+ CertTemplate certTemplate = certreq.getCertTemplate();
+ Name n = certTemplate.getSubject();
+ ByteArrayOutputStream subjectEncStream = new ByteArrayOutputStream();
+ n.encode(subjectEncStream);
+
+ byte[] b = subjectEncStream.toByteArray();
+ X500Name subject = new X500Name(b);
+ return subject.toString();
+ }
+
+ /**
+ * Creates a Certificate template.
+ */
+ public static X509CertInfo createX509CertInfo(KeyPair pair,
+ int serialno, String issuername, String subjname,
+ Date notBefore, Date notAfter)
+ throws IOException,
+ CertificateException,
+ InvalidKeyException {
+ return createX509CertInfo(convertPublicKeyToX509Key(pair.getPublic()),
+ serialno, issuername, subjname, notBefore, notAfter);
+ }
+
+ public static X509CertInfo createX509CertInfo(PublicKey publickey,
+ int serialno, String issuername, String subjname,
+ Date notBefore, Date notAfter)
+ throws IOException,
+ CertificateException,
+ InvalidKeyException {
+ return createX509CertInfo(convertPublicKeyToX509Key(publickey), serialno,
+ issuername, subjname, notBefore, notAfter);
+ }
+
+ public static X509CertInfo createX509CertInfo(X509Key x509key,
+ int serialno, String issuername, String subjname,
+ Date notBefore, Date notAfter)
+ throws IOException,
+ CertificateException,
+ InvalidKeyException {
+ // set default; use the other call with "alg" to set algorithm
+ String alg = "SHA256withRSA";
+ try {
+ return createX509CertInfo(x509key, serialno, issuername, subjname, notBefore, notAfter, alg);
+ } catch (NoSuchAlgorithmException ex) {
+ // for those that calls the old call without alg
+ throw new CertificateException("createX509CertInfo old call should not be here");
+ }
+ }
+
+ public static X509CertInfo createX509CertInfo(X509Key x509key,
+ int serialno, String issuername, String subjname,
+ Date notBefore, Date notAfter, String alg)
+ throws IOException,
+ CertificateException,
+ InvalidKeyException,
+ NoSuchAlgorithmException {
+ X509CertInfo info = new X509CertInfo();
+
+ info.set(X509CertInfo.VERSION, new
+ CertificateVersion(CertificateVersion.V3));
+ info.set(X509CertInfo.SERIAL_NUMBER, new
+ CertificateSerialNumber(serialno));
+ info.set(X509CertInfo.ISSUER, new
+ CertificateIssuerName(new X500Name(issuername)));
+ info.set(X509CertInfo.SUBJECT, new
+ CertificateSubjectName(new X500Name(subjname)));
+ info.set(X509CertInfo.VALIDITY, new
+ CertificateValidity(notBefore, notAfter));
+ info.set(X509CertInfo.ALGORITHM_ID, new
+ CertificateAlgorithmId(AlgorithmId.get(alg)));
+ info.set(X509CertInfo.KEY, new CertificateX509Key(x509key));
+ info.set(X509CertInfo.EXTENSIONS, new CertificateExtensions());
+ return info;
+ }
+
+ public static X509CertImpl signECCCert(PrivateKey privateKey,
+ X509CertInfo certInfo)
+ throws NoSuchTokenException,
+ CryptoManager.NotInitializedException,
+ NoSuchAlgorithmException,
+ NoSuchTokenException,
+ TokenException,
+ InvalidKeyException,
+ SignatureException,
+ IOException,
+ CertificateException {
+ // set default; use the other call with "alg" to specify algorithm
+ String alg = "SHA256withEC";
+ return signECCCert(privateKey, certInfo, alg);
+ }
+
+ public static X509CertImpl signECCCert(PrivateKey privateKey,
+ X509CertInfo certInfo, String alg)
+ throws NoSuchTokenException,
+ CryptoManager.NotInitializedException,
+ NoSuchAlgorithmException,
+ NoSuchTokenException,
+ TokenException,
+ InvalidKeyException,
+ SignatureException,
+ IOException,
+ CertificateException {
+ return signCert(privateKey, certInfo,
+ Cert.mapAlgorithmToJss(alg));
+ }
+
+ /**
+ * Signs certificate.
+ */
+ public static X509CertImpl signCert(PrivateKey privateKey,
+ X509CertInfo certInfo, String alg)
+ throws NoSuchTokenException,
+ CryptoManager.NotInitializedException,
+ NoSuchAlgorithmException,
+ NoSuchTokenException,
+ TokenException,
+ InvalidKeyException,
+ SignatureException,
+ IOException,
+ CertificateException {
+ return signCert(privateKey, certInfo,
+ Cert.mapAlgorithmToJss(alg));
+ }
+
+ public static X509CertImpl signCert(PrivateKey privateKey,
+ X509CertInfo certInfo, SignatureAlgorithm sigAlg)
+ throws NoSuchTokenException,
+ CryptoManager.NotInitializedException,
+ NoSuchAlgorithmException,
+ NoSuchTokenException,
+ TokenException,
+ InvalidKeyException,
+ SignatureException,
+ IOException,
+ CertificateException {
+
+ DerInputStream ds = new DerInputStream(ASN1Util.encode(sigAlg.toOID()));
+ ObjectIdentifier sigAlgOID = new ObjectIdentifier(ds);
+ AlgorithmId aid = new AlgorithmId(sigAlgOID);
+ certInfo.set(X509CertInfo.ALGORITHM_ID,
+ new CertificateAlgorithmId(aid));
+
+ 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();
+
+ aid.encode(tmp);
+ tmp.putBitString(signed);
+ out.write(DerValue.tag_Sequence, tmp);
+ X509CertImpl signedCert = new X509CertImpl(out.toByteArray());
+
+ return signedCert;
+ }
+
+ /**
+ * Creates a PKCS#10 request.
+ */
+ public static PKCS10 createCertificationRequest(String subjectName,
+ X509Key pubk, PrivateKey prik)
+ throws NoSuchAlgorithmException, NoSuchProviderException,
+ InvalidKeyException, IOException, CertificateException,
+ SignatureException {
+ // give default
+ String alg = "SHA256withRSA";
+ if (isECCKey(pubk)) {
+ alg = "SHA256withEC";
+ }
+ return createCertificationRequest(subjectName, pubk, prik, alg);
+ }
+
+ public static PKCS10 createCertificationRequest(String subjectName,
+ X509Key pubk, PrivateKey prik, String alg)
+ throws NoSuchAlgorithmException, NoSuchProviderException,
+ InvalidKeyException, IOException, CertificateException,
+ SignatureException {
+ X509Key key = pubk;
+ java.security.Signature sig = java.security.Signature.getInstance(alg,
+ "Mozilla-JSS");
+
+ sig.initSign(prik);
+ PKCS10 pkcs10 = new PKCS10(key);
+ X500Name name = new X500Name(subjectName);
+ X500Signer signer = new X500Signer(sig, name);
+
+ pkcs10.encodeAndSign(signer);
+ return pkcs10;
+ }
+
+ /**
+ * Creates a PKCS#10 request.
+ */
+ public static PKCS10 createCertificationRequest(String subjectName,
+ KeyPair keyPair)
+ throws NoSuchAlgorithmException, NoSuchProviderException,
+ InvalidKeyException, IOException, CertificateException,
+ SignatureException {
+ String alg;
+ PublicKey pubk = keyPair.getPublic();
+ X509Key key = convertPublicKeyToX509Key(pubk);
+ if (pubk instanceof RSAPublicKey) {
+ alg = "SHA256withRSA";
+ } else if (isECCKey(key)) {
+ alg = "SHA256withEC";
+ } else {
+ // Assert.assert(pubk instanceof DSAPublicKey);
+ alg = "DSA";
+ }
+ return createCertificationRequest(subjectName, keyPair, alg);
+ }
+
+ public static PKCS10 createCertificationRequest(String subjectName,
+ KeyPair keyPair, String alg)
+ throws NoSuchAlgorithmException, NoSuchProviderException,
+ InvalidKeyException, IOException, CertificateException,
+ SignatureException {
+ PublicKey pubk = keyPair.getPublic();
+ X509Key key = convertPublicKeyToX509Key(pubk);
+
+ 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 void unTrustCert(InternalCertificate cert) {
+ // remove TRUSTED_CA
+ int flag = cert.getSSLTrust();
+
+ flag ^= InternalCertificate.VALID_CA;
+ cert.setSSLTrust(flag);
+ }
+
+ /**
+ * Trusts a certificate by nickname.
+ */
+ public static void trustCertByNickname(String nickname)
+ throws CryptoManager.NotInitializedException,
+ TokenException {
+ CryptoManager cm = CryptoManager.getInstance();
+ X509Certificate certs[] = cm.findCertsByNickname(nickname);
+
+ if (certs == null) {
+ return;
+ }
+ for (int i = 0; i < certs.length; i++) {
+ trustCert((InternalCertificate) certs[i]);
+ }
+ }
+
+ /**
+ * Trusts a certificate.
+ */
+ public static void trustCert(InternalCertificate cert) {
+ int flag = InternalCertificate.VALID_CA | InternalCertificate.TRUSTED_CA
+ | InternalCertificate.USER
+ | InternalCertificate.TRUSTED_CLIENT_CA;
+
+ cert.setSSLTrust(flag);
+ cert.setObjectSigningTrust(flag);
+ cert.setEmailTrust(flag);
+ }
+
+ /**
+ * To certificate server point of view, SSL trust is
+ * what we referring.
+ */
+ public static boolean isCertTrusted(InternalCertificate cert) {
+ if (isTrust(cert.getSSLTrust()) && isTrust(cert.getObjectSigningTrust())
+ && isTrust(cert.getEmailTrust())) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public static boolean isTrust(int flag) {
+ if (((flag & InternalCertificate.VALID_CA) > 0)
+ && ((flag & InternalCertificate.TRUSTED_CA) > 0)
+ && ((flag & InternalCertificate.USER) > 0)
+ && ((flag & InternalCertificate.TRUSTED_CLIENT_CA) > 0)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Generates a symmetric key.
+ */
+ public static SymmetricKey generateKey(CryptoToken token,
+ KeyGenAlgorithm alg)
+ throws TokenException, NoSuchAlgorithmException,
+ IllegalStateException {
+ try {
+ KeyGenerator kg = token.getKeyGenerator(alg);
+
+ return kg.generate();
+ } catch (CharConversionException e) {
+ throw new RuntimeException(
+ "CharConversionException while generating symmetric key");
+ }
+ }
+
+ /**
+ * Compares 2 byte arrays to see if they are the same.
+ */
+ public static boolean compare(byte src[], byte dest[]) {
+ if (src != null && dest != null) {
+ if (src.length == dest.length) {
+ boolean matched = true;
+
+ for (int i = 0; i < src.length; i++) {
+ if (src[i] != dest[i]) {
+ matched = false;
+ }
+ }
+ if (matched) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public static String byte2string(byte id[]) {
+ return new BigInteger(id).toString(16);
+ }
+
+ public static byte[] string2byte(String id) {
+ return (new BigInteger(id, 16)).toByteArray();
+ }
+
+ /**
+ * Retrieves a private key from a unique key ID.
+ */
+ public static PrivateKey findPrivateKeyFromID(byte id[])
+ throws CryptoManager.NotInitializedException,
+ TokenException {
+ CryptoManager cm = CryptoManager.getInstance();
+ @SuppressWarnings("unchecked")
+ Enumeration<CryptoToken> enums = cm.getAllTokens();
+
+ while (enums.hasMoreElements()) {
+ CryptoToken token = enums.nextElement();
+ CryptoStore store = token.getCryptoStore();
+ PrivateKey keys[] = store.getPrivateKeys();
+
+ if (keys != null) {
+ for (int i = 0; i < keys.length; i++) {
+ if (compare(keys[i].getUniqueID(), id)) {
+ return keys[i];
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Retrieves all user certificates from all tokens.
+ */
+ public static X509CertImpl[] getAllUserCerts()
+ throws CryptoManager.NotInitializedException,
+ TokenException {
+ Vector<X509CertImpl> certs = new Vector<X509CertImpl>();
+ CryptoManager cm = CryptoManager.getInstance();
+ @SuppressWarnings("unchecked")
+ Enumeration<CryptoToken> enums = cm.getAllTokens();
+
+ while (enums.hasMoreElements()) {
+ CryptoToken token = (CryptoToken) enums.nextElement();
+
+ CryptoStore store = token.getCryptoStore();
+ org.mozilla.jss.crypto.X509Certificate list[] = store.getCertificates();
+
+ for (int i = 0; i < list.length; i++) {
+ try {
+ @SuppressWarnings("unused")
+ PrivateKey key = cm.findPrivKeyByCert(list[i]); // check for errors
+ X509CertImpl impl = null;
+
+ try {
+ impl = new X509CertImpl(list[i].getEncoded());
+ } catch (CertificateException e) {
+ continue;
+ }
+ certs.addElement(impl);
+ } catch (TokenException e) {
+ continue;
+ } catch (ObjectNotFoundException e) {
+ continue;
+ }
+ }
+ }
+ if (certs.size() == 0) {
+ return null;
+ } else {
+ X509CertImpl c[] = new X509CertImpl[certs.size()];
+
+ certs.copyInto(c);
+ return c;
+ }
+ }
+
+ /**
+ * Deletes a private key.
+ */
+ public static void deletePrivateKey(PrivateKey prikey)
+ throws CryptoManager.NotInitializedException, TokenException {
+
+ try {
+ CryptoToken token = prikey.getOwningToken();
+ CryptoStore store = token.getCryptoStore();
+
+ store.deletePrivateKey(prikey);
+ } catch (NoSuchItemOnTokenException e) {
+ }
+ }
+
+ /**
+ * Retrieves a private key by nickname.
+ */
+ public static PrivateKey getPrivateKey(String nickname)
+ throws CryptoManager.NotInitializedException, TokenException {
+ try {
+ CryptoManager cm = CryptoManager.getInstance();
+ X509Certificate cert = cm.findCertByNickname(nickname);
+ org.mozilla.jss.crypto.PrivateKey prikey = cm.findPrivKeyByCert(cert);
+
+ return prikey;
+ } catch (ObjectNotFoundException e) {
+ }
+ return null;
+ }
+
+ /**
+ * Deletes all certificates by a nickname.
+ */
+ public static void deleteAllCertificates(String nickname)
+ throws CryptoManager.NotInitializedException, TokenException {
+ CryptoManager cm = CryptoManager.getInstance();
+ X509Certificate certs[] = cm.findCertsByNickname(nickname);
+
+ if (certs == null) {
+ return;
+ }
+ for (int i = 0; i < certs.length; i++) {
+ try {
+ X509Certificate cert = certs[i];
+ org.mozilla.jss.crypto.PrivateKey prikey = cm.findPrivKeyByCert(
+ cert);
+ CryptoToken token = prikey.getOwningToken();
+ CryptoStore store = token.getCryptoStore();
+
+ store.deleteCert(cert);
+ } catch (NoSuchItemOnTokenException e) {
+ } catch (ObjectNotFoundException e) {
+ }
+ }
+ }
+
+ /**
+ * Imports a PKCS#7 certificate chain that includes the user
+ * certificate, and trusts the certificate.
+ */
+ public static X509Certificate importUserCertificateChain(String c,
+ String nickname)
+ throws CryptoManager.NotInitializedException,
+ CryptoManager.NicknameConflictException,
+ CryptoManager.UserCertConflictException,
+ NoSuchItemOnTokenException,
+ TokenException,
+ CertificateEncodingException {
+ CryptoManager cm = CryptoManager.getInstance();
+ X509Certificate cert = cm.importCertPackage(c.getBytes(), nickname);
+
+ trustCertByNickname(nickname);
+ return cert;
+ }
+
+ /**
+ * Imports a user certificate, and trusts the certificate.
+ */
+ public static void importUserCertificate(X509CertImpl cert, String nickname)
+ throws CryptoManager.NotInitializedException,
+ CertificateEncodingException,
+ NoSuchItemOnTokenException,
+ TokenException,
+ CryptoManager.NicknameConflictException,
+ CryptoManager.UserCertConflictException {
+ CryptoManager cm = CryptoManager.getInstance();
+
+ cm.importUserCACertPackage(cert.getEncoded(), nickname);
+ trustCertByNickname(nickname);
+ }
+
+ public static void importUserCertificate(X509CertImpl cert, String nickname,
+ boolean trust)
+ throws CryptoManager.NotInitializedException,
+ CertificateEncodingException,
+ NoSuchItemOnTokenException,
+ TokenException,
+ CryptoManager.NicknameConflictException,
+ CryptoManager.UserCertConflictException {
+ CryptoManager cm = CryptoManager.getInstance();
+
+ cm.importUserCACertPackage(cert.getEncoded(), nickname);
+ if (trust)
+ trustCertByNickname(nickname);
+ }
+
+ public static java.security.cert.X509Certificate[] getX509CertificateFromPKCS7(byte[] b) throws IOException {
+ ByteArrayInputStream bis = new ByteArrayInputStream(b);
+ CertificateChain certchain = new CertificateChain();
+
+ certchain.decode(bis);
+ java.security.cert.X509Certificate[] certs = certchain.getChain();
+
+ return certs;
+ }
+
+ @SuppressWarnings("deprecation")
+ public static String unwrapUsingPassphrase(String wrappedRecoveredKey, String recoveryPassphrase)
+ throws IOException, InvalidBERException, InvalidKeyException, IllegalStateException,
+ NoSuchAlgorithmException, InvalidAlgorithmParameterException, NotInitializedException, TokenException,
+ IllegalBlockSizeException, BadPaddingException {
+ EncryptedContentInfo cInfo = null;
+ String unwrappedData = null;
+
+ //We have to do this to get the decoding to work.
+ @SuppressWarnings("unused")
+ PBEAlgorithm pbeAlg = PBEAlgorithm.PBE_SHA1_DES3_CBC;
+
+ Password pass = new Password(recoveryPassphrase.toCharArray());
+ PasswordConverter passConverter = new
+ PasswordConverter();
+
+ byte[] encoded = Utils.base64decode(wrappedRecoveredKey);
+
+ ByteArrayInputStream inStream = new ByteArrayInputStream(encoded);
+ cInfo = (EncryptedContentInfo)
+ new EncryptedContentInfo.Template().decode(inStream);
+
+ byte[] decodedData = cInfo.decrypt(pass, passConverter);
+
+ unwrappedData = Utils.base64encode(decodedData);
+
+ return unwrappedData;
+ }
+
+ @SuppressWarnings("deprecation")
+ public static String unwrapUsingSymmetricKey(CryptoToken token, IVParameterSpec IV, byte[] wrappedRecoveredKey,
+ SymmetricKey recoveryKey, EncryptionAlgorithm alg) throws NoSuchAlgorithmException, TokenException,
+ BadPaddingException,
+ IllegalBlockSizeException, InvalidKeyException, InvalidAlgorithmParameterException {
+
+ Cipher decryptor = token.getCipherContext(alg);
+ decryptor.initDecrypt(recoveryKey, IV);
+ byte[] unwrappedData = decryptor.doFinal(wrappedRecoveredKey);
+ String unwrappedS = Utils.base64encode(unwrappedData);
+
+ return unwrappedS;
+ }
+
+ @SuppressWarnings("deprecation")
+ public static byte[] wrapPassphrase(CryptoToken token, String passphrase, IVParameterSpec IV, SymmetricKey sk,
+ EncryptionAlgorithm alg)
+ throws NoSuchAlgorithmException, TokenException, InvalidKeyException,
+ InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, IOException {
+ byte[] wrappedPassphrase = null;
+ Cipher encryptor = null;
+
+ encryptor = token.getCipherContext(alg);
+
+ if (encryptor != null) {
+ encryptor.initEncrypt(sk, IV);
+ wrappedPassphrase = encryptor.doFinal(passphrase.getBytes("UTF-8"));
+ } else {
+ throw new IOException("Failed to create cipher");
+ }
+
+ return wrappedPassphrase;
+ }
+
+ @SuppressWarnings("deprecation")
+ public static byte[] wrapSymmetricKey(CryptoManager manager, CryptoToken token, String transportCert,
+ SymmetricKey sk) throws CertificateEncodingException, TokenException, NoSuchAlgorithmException,
+ InvalidKeyException, InvalidAlgorithmParameterException {
+ byte transport[] = Utils.base64decode(transportCert);
+ X509Certificate tcert = manager.importCACertPackage(transport);
+ KeyWrapper rsaWrap = token.getKeyWrapper(KeyWrapAlgorithm.RSA);
+ rsaWrap.initWrap(tcert.getPublicKey(), null);
+ byte session_data[] = rsaWrap.wrap(sk);
+ return session_data;
+ }
+
+ @SuppressWarnings("deprecation")
+ public static byte[] createPKIArchiveOptions(CryptoManager manager, CryptoToken token, String transportCert,
+ SymmetricKey vek, String passphrase, KeyGenAlgorithm keyGenAlg, IVParameterSpec IV) throws TokenException,
+ CharConversionException,
+ NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException,
+ CertificateEncodingException, IOException, IllegalStateException, IllegalBlockSizeException,
+ BadPaddingException, InvalidBERException {
+ byte[] key_data = null;
+
+ //generate session key
+ SymmetricKey sk = CryptoUtil.generateKey(token, keyGenAlg);
+
+ if (passphrase != null) {
+ key_data = wrapPassphrase(token, passphrase, IV, sk, EncryptionAlgorithm.DES3_CBC_PAD);
+ } else {
+ // wrap payload using session key
+ KeyWrapper wrapper1 = token.getKeyWrapper(KeyWrapAlgorithm.DES3_CBC_PAD);
+ wrapper1.initWrap(sk, IV);
+ key_data = wrapper1.wrap(vek);
+ }
+
+ // wrap session key using transport key
+ byte[] session_data = wrapSymmetricKey(manager, token, transportCert, sk);
+
+ // create PKIArchiveOptions structure
+ AlgorithmIdentifier algS = new AlgorithmIdentifier(new OBJECT_IDENTIFIER("1.2.840.113549.3.7"),
+ new OCTET_STRING(IV.getIV()));
+ EncryptedValue encValue = new EncryptedValue(null, algS, new BIT_STRING(session_data, 0), null, null,
+ new BIT_STRING(key_data, 0));
+ EncryptedKey key = new EncryptedKey(encValue);
+ PKIArchiveOptions opt = new PKIArchiveOptions(key);
+
+ byte[] encoded = null;
+
+ //Let's make sure we can decode the encoded PKIArchiveOptions..
+ ByteArrayOutputStream oStream = new ByteArrayOutputStream();
+
+ opt.encode(oStream);
+
+ encoded = oStream.toByteArray();
+ ByteArrayInputStream inStream = new ByteArrayInputStream(encoded);
+
+ @SuppressWarnings("unused")
+ PKIArchiveOptions options = (PKIArchiveOptions)
+ (new PKIArchiveOptions.Template()).decode(inStream);
+
+ return encoded;
+ }
+}
+
+// START ENABLE_ECC
+// This following can be removed when JSS with ECC capability
+// is integrated.
+class CryptoAlgorithm extends Algorithm {
+ protected CryptoAlgorithm(int oidIndex, String name) {
+ super(oidIndex, name);
+ }
+}
+
+class CryptoKeyPairAlgorithm extends KeyPairAlgorithm {
+ protected CryptoKeyPairAlgorithm(int oidIndex, String name, Algorithm algFamily) {
+ super(oidIndex, name, algFamily);
+ }
+}
+
+class CryptoSignatureAlgorithm extends SignatureAlgorithm {
+ protected CryptoSignatureAlgorithm(int oidIndex, String name,
+ SignatureAlgorithm signingAlg, DigestAlgorithm digestAlg,
+ OBJECT_IDENTIFIER oid) {
+ super(oidIndex, name, signingAlg, digestAlg, oid);
+ }
+}
+// END ENABLE_ECC
diff --git a/base/util/src/com/netscape/cmsutil/crypto/Module.java b/base/util/src/com/netscape/cmsutil/crypto/Module.java
new file mode 100644
index 000000000..bf4a7fe73
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/crypto/Module.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.cmsutil.crypto;
+
+import java.util.Vector;
+
+import org.mozilla.jss.crypto.CryptoToken;
+
+public class Module {
+ // Common Name is the name given when module is added
+ private String mCommonName = "";
+ // User friendly name is the name to be displayed on panel
+ private String mUserFriendlyName = "";
+ private String mImagePath = "";
+ // a Vector of Tokens
+ private Vector<Token> mTokens = null;
+ private boolean mFound = false;
+
+ public Module(String name, String printName) {
+ mCommonName = name;
+ mUserFriendlyName = printName;
+ mTokens = new Vector<Token>();
+ }
+
+ public Module(String name, String printName, String image) {
+ mCommonName = name;
+ mUserFriendlyName = printName;
+ mImagePath = image;
+ mTokens = new Vector<Token>();
+ }
+
+ public void addToken(CryptoToken t) {
+ Token token = new Token(t);
+ mTokens.addElement(token);
+ }
+
+ public String getCommonName() {
+ return mCommonName;
+ }
+
+ public String getUserFriendlyName() {
+ return mUserFriendlyName;
+ }
+
+ public String getImagePath() {
+ return mImagePath;
+ }
+
+ public boolean isFound() {
+ return mFound;
+ }
+
+ public void setFound(boolean isFound) {
+ mFound = isFound;
+ }
+
+ public Vector<Token> getTokens() {
+ return mTokens;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/crypto/Token.java b/base/util/src/com/netscape/cmsutil/crypto/Token.java
new file mode 100644
index 000000000..c6f5a5e3c
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/crypto/Token.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.cmsutil.crypto;
+
+import org.mozilla.jss.crypto.CryptoToken;
+
+public class Token {
+ CryptoToken mToken;
+
+ public Token(CryptoToken token) {
+ mToken = token;
+ }
+
+ public String getNickName() {
+ String nickName = "";
+ try {
+ nickName = mToken.getName();
+ } catch (Exception e) {
+ }
+ return nickName;
+ }
+
+ public boolean isLoggedIn() {
+ boolean isLoggedIn = false;
+ try {
+ isLoggedIn = mToken.isLoggedIn();
+ } catch (Exception e) {
+ }
+
+ return isLoggedIn;
+ }
+
+ public boolean isPresent() {
+ boolean isPresent = false;
+ try {
+ isPresent = mToken.isPresent();
+ } catch (Exception e) {
+ }
+
+ return isPresent;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/http/ConnectAsync.java b/base/util/src/com/netscape/cmsutil/http/ConnectAsync.java
new file mode 100644
index 000000000..ca230ca21
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/http/ConnectAsync.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.cmsutil.http;
+
+import java.net.SocketException;
+
+import com.netscape.cmsutil.net.ISocketFactory;
+
+public class ConnectAsync extends Thread {
+ String host = null;
+ int port = 0;
+ ISocketFactory obj = null;
+
+ public ConnectAsync(ISocketFactory sock, String host, int port) {
+ super();
+ this.host = host;
+ this.port = port;
+ this.obj = sock;
+ setName("ConnectAsync");
+ }
+
+ public void run() {
+ try {
+ obj.makeSocket(host, port);
+ } catch (SocketException e) {
+ // Stop throwing exception
+ } catch (Exception e) {
+ // Stop throwing exception
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/http/Http.java b/base/util/src/com/netscape/cmsutil/http/Http.java
new file mode 100644
index 000000000..2cda7fd12
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/http/Http.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.cmsutil.http;
+
+public class Http {
+ public static final String HttpVers = "HTTP/1.0";
+
+ public static final String Vers1_0 = "HTTP/1.0";
+ public static final String Vers1_1 = "HTTP/1.1";
+ public static final String CRLF = "\r\n";
+
+ public static final char CR = '\r';
+ public static final char LF = '\n';
+ public static final char SP = ' ';
+
+}
diff --git a/base/util/src/com/netscape/cmsutil/http/HttpClient.java b/base/util/src/com/netscape/cmsutil/http/HttpClient.java
new file mode 100644
index 000000000..438c70c23
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/http/HttpClient.java
@@ -0,0 +1,217 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmsutil.http;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.Socket;
+
+import org.mozilla.jss.ssl.SSLCertificateApprovalCallback;
+
+import com.netscape.cmsutil.net.ISocketFactory;
+
+/**
+ * basic http client.
+ * not optimized for performance.
+ * handles only string content.
+ */
+public class HttpClient {
+ protected ISocketFactory mFactory = null;
+
+ protected Socket mSocket = null;
+ protected InputStream mInputStream = null;
+ protected OutputStream mOutputStream = null;
+
+ protected InputStreamReader mInputStreamReader = null;
+ protected OutputStreamWriter mOutputStreamWriter = null;
+ protected BufferedReader mBufferedReader = null;
+ protected SSLCertificateApprovalCallback mCertApprovalCallback = null;
+ protected boolean mConnected = false;
+
+ public HttpClient() {
+ }
+
+ public HttpClient(ISocketFactory factory) {
+ mFactory = factory;
+ }
+
+ public HttpClient(ISocketFactory factory, SSLCertificateApprovalCallback certApprovalCallback) {
+ mFactory = factory;
+ mCertApprovalCallback = certApprovalCallback;
+ }
+
+ public void connect(String host, int port)
+ throws IOException {
+ if (mFactory != null) {
+ if (mCertApprovalCallback == null) {
+ mSocket = mFactory.makeSocket(host, port);
+ } else {
+ mSocket = mFactory.makeSocket(host, port, mCertApprovalCallback, null);
+ }
+ } else {
+ mSocket = new Socket(host, port);
+ }
+
+ if (mSocket == null) {
+ IOException e = new IOException("Couldn't make connection");
+
+ throw e;
+ }
+
+ mInputStream = mSocket.getInputStream();
+ mOutputStream = mSocket.getOutputStream();
+ mInputStreamReader = new InputStreamReader(mInputStream, "UTF8");
+ mBufferedReader = new BufferedReader(mInputStreamReader);
+ mOutputStreamWriter = new OutputStreamWriter(mOutputStream, "UTF8");
+ mConnected = true;
+ }
+
+ // Inserted by beomsuk
+ public void connect(String host, int port, int timeout)
+ throws IOException {
+ if (mFactory != null) {
+ mSocket = mFactory.makeSocket(host, port, timeout);
+ } else {
+ mSocket = new Socket(host, port);
+ }
+
+ if (mSocket == null) {
+ IOException e = new IOException("Couldn't make connection");
+
+ throw e;
+ }
+
+ mInputStream = mSocket.getInputStream();
+ mOutputStream = mSocket.getOutputStream();
+ mInputStreamReader = new InputStreamReader(mInputStream, "UTF8");
+ mBufferedReader = new BufferedReader(mInputStreamReader);
+ mOutputStreamWriter = new OutputStreamWriter(mOutputStream, "UTF8");
+ mConnected = true;
+ }
+
+ // Insert end
+ public boolean connected() {
+ return mConnected;
+ }
+
+ /**
+ * Sends a request to http server.
+ * Returns a http response.
+ */
+ public HttpResponse send(HttpRequest request)
+ throws IOException {
+ HttpResponse resp = new HttpResponse();
+
+ if (mOutputStream == null)
+ throw new IOException("Output stream not initialized");
+ request.write(mOutputStreamWriter);
+ try {
+ resp.parse(mBufferedReader);
+ } catch (IOException e) {
+ // XXX should we disconnect in all cases ?
+ disconnect();
+ throw e;
+ }
+ disconnect();
+ return resp;
+ }
+
+ public void disconnect()
+ throws IOException {
+ mSocket.close();
+ mInputStream = null;
+ mOutputStream = null;
+ mConnected = false;
+ }
+
+ public InputStream getInputStream() {
+ return mInputStream;
+ }
+
+ public OutputStream getOutputStream() {
+ return mOutputStream;
+ }
+
+ public BufferedReader getBufferedReader() {
+ return mBufferedReader;
+ }
+
+ public InputStreamReader getInputStreamReader() {
+ return mInputStreamReader;
+ }
+
+ public OutputStreamWriter getOutputStreamWriter() {
+ return mOutputStreamWriter;
+ }
+
+ public Socket getSocket() {
+ return mSocket;
+ }
+
+ /**
+ * unit test
+ */
+ public static void main(String args[])
+ throws Exception {
+ HttpClient c = new HttpClient();
+ HttpRequest req = new HttpRequest();
+ HttpResponse resp = null;
+
+ System.out.println("connecting to " + args[0] + " " + args[1]);
+ c.connect(args[0], Integer.parseInt(args[1]));
+
+ req.setMethod("GET");
+ req.setURI(args[2]);
+ if (args.length >= 4)
+ req.setHeader("Connection", args[3]);
+ resp = c.send(req);
+
+ System.out.println("version " + resp.getHttpVers());
+ System.out.println("status code " + resp.getStatusCode());
+ System.out.println("reason " + resp.getReasonPhrase());
+ System.out.println("content " + resp.getContent());
+
+ //String lenstr = resp.getHeader("Content-Length");
+ //System.out.println("content len is "+lenstr);
+ //int length = Integer.parseInt(lenstr);
+ //char[] content = new char[length];
+ //c.mBufferedReader.read(content, 0, content.length);
+ //System.out.println(content);
+
+ if (args.length >= 4 && args[3].equalsIgnoreCase("keep-alive")) {
+ for (int i = 0; i < 2; i++) {
+ if (i == 1)
+ req.setHeader("Connection", "Close");
+ resp = c.send(req);
+ System.out.println("version " + resp.getHttpVers());
+ System.out.println("status code " + resp.getStatusCode());
+ System.out.println("reason " + resp.getReasonPhrase());
+ System.out.println("content " + resp.getContent());
+ //len = Integer.parseInt(resp.getHeader("Content-Length"));
+ //System.out.println("content len is "+len);
+ //msgbody = new char[len];
+ //c.mBufferedReader.read(msgbody, 0, len);
+ //System.out.println(content);
+ }
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/http/HttpEofException.java b/base/util/src/com/netscape/cmsutil/http/HttpEofException.java
new file mode 100644
index 000000000..824b9ea2a
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/http/HttpEofException.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.cmsutil.http;
+
+import java.io.IOException;
+
+public class HttpEofException extends IOException {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 433303354049669059L;
+
+ public HttpEofException() {
+ super();
+ }
+
+ public HttpEofException(String msg) {
+ super(msg);
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/http/HttpMessage.java b/base/util/src/com/netscape/cmsutil/http/HttpMessage.java
new file mode 100644
index 000000000..badec5930
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/http/HttpMessage.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.cmsutil.http;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ * Basic HTTP Message, excluding message body.
+ * Not optimized for performance.
+ * Set fields or parse from input.
+ */
+public class HttpMessage {
+ protected String mLine = null; // request or response line.
+ protected Hashtable<String, String> mHeaders = null;
+ protected String mContent = null; // arbitrary content chars assumed.
+
+ /**
+ * Instantiate a HttpResponse for write to http client.
+ */
+ public HttpMessage() {
+ mHeaders = new Hashtable<String, String>();
+ }
+
+ /**
+ * Set a header field. <br>
+ * Content-length is automatically set on write.<br>
+ * If value spans multiple lines must be in proper http format for
+ * multiple lines.
+ */
+ public void setHeader(String name, String value) {
+ if (mHeaders == null)
+ mHeaders = new Hashtable<String, String>();
+ mHeaders.put(name.toLowerCase(), value);
+ }
+
+ /**
+ * get a header
+ */
+ public String getHeader(String name) {
+ return (String) mHeaders.get(name.toLowerCase());
+ }
+
+ /**
+ * write http headers
+ * does not support values of more than one line
+ */
+ public void writeHeaders(OutputStreamWriter writer)
+ throws IOException {
+ if (mHeaders != null) {
+ Enumeration<String> keys = mHeaders.keys();
+ String header, value;
+
+ while (keys.hasMoreElements()) {
+ header = keys.nextElement();
+ value = mHeaders.get(header);
+ writer.write(header + ":" + value + Http.CRLF);
+ }
+ }
+ writer.write(Http.CRLF); // end with CRLF line.
+ }
+
+ /**
+ * read http headers.
+ * does not support values of more than one line or multivalue headers.
+ */
+ public void readHeaders(BufferedReader reader)
+ throws IOException {
+ mHeaders = new Hashtable<String, String>();
+
+ int colon;
+ String line, key, value;
+
+ while (true) {
+ line = reader.readLine();
+ if (line == null || line.equals(""))
+ break;
+ colon = line.indexOf(':');
+ if (colon == -1) {
+ mHeaders = null;
+ throw new HttpProtocolException("Bad Http header format");
+ }
+ key = line.substring(0, colon);
+ value = line.substring(colon + 1);
+ mHeaders.put(key.toLowerCase(), value.trim());
+ }
+ }
+
+ public void write(OutputStreamWriter writer)
+ throws IOException {
+ writer.write(mLine + Http.CRLF);
+ writeHeaders(writer);
+ writer.flush();
+ if (mContent != null) {
+ writer.write(mContent);
+ }
+ writer.flush();
+ }
+
+ public void parse(BufferedReader reader)
+ throws IOException {
+ String line = reader.readLine();
+
+ // if (line == null) {
+ // throw new HttpEofException("End of stream reached");
+ // }
+ if (line.equals("")) {
+ throw new HttpProtocolException("Bad Http req/resp line " + line);
+ }
+ mLine = line;
+ readHeaders(reader);
+
+ // won't work if content length is not set.
+ String lenstr = mHeaders.get("content-length");
+
+ if (lenstr != null) {
+ int len = Integer.parseInt(lenstr);
+ char[] cbuf = new char[len];
+ int done = reader.read(cbuf, 0, cbuf.length);
+ int total = done;
+
+ while (done >= 0 && total < len) {
+ done = reader.read(cbuf, total, len - total);
+ total += done;
+ }
+
+ mContent = new String(cbuf);
+ }
+ }
+
+ public void reset() {
+ mLine = null;
+ mHeaders = null;
+ mContent = null;
+ }
+
+ public void setContent(String content) {
+ mContent = content;
+ }
+
+ public String getContent() {
+ return mContent;
+ }
+
+}
diff --git a/base/util/src/com/netscape/cmsutil/http/HttpProtocolException.java b/base/util/src/com/netscape/cmsutil/http/HttpProtocolException.java
new file mode 100644
index 000000000..b5ceb1d7f
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/http/HttpProtocolException.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.cmsutil.http;
+
+import java.io.IOException;
+
+public class HttpProtocolException extends IOException {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -953002842302351684L;
+
+ public HttpProtocolException() {
+ super();
+ }
+
+ public HttpProtocolException(String msg) {
+ super(msg);
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/http/HttpRequest.java b/base/util/src/com/netscape/cmsutil/http/HttpRequest.java
new file mode 100644
index 000000000..9024dabf0
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/http/HttpRequest.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.cmsutil.http;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+
+/**
+ * Basic HTTP Request. not optimized for performance.
+ * Set fields or parse from input.
+ * Handles text content.
+ */
+public class HttpRequest extends HttpMessage {
+ public static final String GET = "GET";
+ public static final String POST = "POST";
+ public static final String HEAD = "HEAD";
+
+ protected String mMethod = null;
+ protected String mURI = null;
+ protected String mHttpVers = null;
+
+ /**
+ * Instantiate a HttpResponse for write to http client.
+ */
+ public HttpRequest() {
+ super();
+ }
+
+ /**
+ * set set request method.
+ */
+ public void setMethod(String method)
+ throws HttpProtocolException {
+ if (!method.equals(GET) && !method.equals(HEAD) &&
+ !method.equals(POST))
+ throw new HttpProtocolException("No such method " + method);
+ mMethod = method;
+ }
+
+ /**
+ * set reason phrase.
+ */
+ public void setURI(String uri) {
+ mURI = uri;
+ }
+
+ /**
+ * write request to the http client
+ */
+ public void write(OutputStreamWriter writer)
+ throws IOException {
+ if (mMethod == null || mURI == null) {
+ HttpProtocolException e = new HttpProtocolException(
+ "Http request method or uri not initialized");
+
+ //e.printStackTrace();
+ throw e;
+ }
+
+ mLine = mMethod + " " + mURI + " " + Http.HttpVers;
+ super.write(writer);
+ }
+
+ /**
+ * parse a http request from a http client
+ */
+ public void parse(BufferedReader reader)
+ throws IOException {
+ super.parse(reader);
+
+ int method = mLine.indexOf(Http.SP);
+
+ mMethod = mLine.substring(0, method);
+ if (!mMethod.equals(GET) && !mMethod.equals(POST) &&
+ !mMethod.equals(HEAD)) {
+ reset();
+ throw new HttpProtocolException("Bad Http request method");
+ }
+
+ int uri = mLine.lastIndexOf(Http.SP);
+
+ mURI = mLine.substring(method + 1, uri);
+
+ mHttpVers = mLine.substring(uri + 1);
+ if (!mHttpVers.equals("")) {
+ if (!mHttpVers.equals(Http.Vers1_0) &&
+ !mHttpVers.equals(Http.Vers1_1)) {
+ reset();
+ throw new HttpProtocolException("Bad Http version in request");
+ }
+ }
+ }
+
+ public void reset() {
+ mMethod = null;
+ mURI = null;
+ mHttpVers = null;
+ super.reset();
+ }
+
+ /**
+ * get method
+ */
+ public String getMethod() {
+ return mMethod;
+ }
+
+ /**
+ * get reason phrase
+ */
+ public String getURI() {
+ return mURI;
+ }
+
+ /**
+ * get http version
+ */
+ public String getHttpVers() {
+ return mHttpVers;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/http/HttpResponse.java b/base/util/src/com/netscape/cmsutil/http/HttpResponse.java
new file mode 100644
index 000000000..7ac7e2f69
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/http/HttpResponse.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.cmsutil.http;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+
+/**
+ * Basic HTTP Response.
+ * Set fields or parse from input.
+ * Handles only text content.
+ */
+public class HttpResponse extends HttpMessage {
+ protected String mStatusCode = null;
+ protected String mReasonPhrase = null;
+ protected String mHttpVers = null;
+
+ /**
+ * Instantiate a HttpResponse for write to http client.
+ */
+ public HttpResponse() {
+ super();
+ }
+
+ /**
+ * set status code of response
+ */
+ public void setStatusCode(int code) {
+ mStatusCode = String.valueOf(code);
+ }
+
+ /**
+ * set reason phrase.
+ */
+ public void setReasonPhrase(String phrase) {
+ mReasonPhrase = phrase;
+ }
+
+ /**
+ * get status code
+ */
+ public String getStatusCode() {
+ return mStatusCode;
+ }
+
+ /**
+ * get reason phrase
+ */
+ public String getReasonPhrase() {
+ return mReasonPhrase;
+ }
+
+ /**
+ * write the response out to the http client
+ */
+ public void write(OutputStreamWriter writer)
+ throws IOException {
+ if (mStatusCode == null) {
+ throw new HttpProtocolException("status code not set in response");
+ }
+ // write status-line
+ mLine = Http.HttpVers + " " + mStatusCode + " ";
+ if (mReasonPhrase != null)
+ mLine += mReasonPhrase;
+ mLine += Http.CRLF;
+ super.write(writer);
+ }
+
+ /**
+ * parse a http response from a http server
+ */
+ public void parse(BufferedReader reader)
+ throws IOException {
+ mHttpVers = null;
+ mStatusCode = null;
+ mReasonPhrase = null;
+
+ super.parse(reader);
+
+ int httpvers = mLine.indexOf(' ');
+
+ if (httpvers == -1) {
+ reset();
+ throw new HttpProtocolException("no Http version in response");
+ }
+ mHttpVers = mLine.substring(0, httpvers);
+ if (!mHttpVers.equals(Http.Vers1_0) &&
+ !mHttpVers.equals(Http.Vers1_1)) {
+ reset();
+ throw new HttpProtocolException("Bad Http version in response");
+ }
+
+ int code = mLine.indexOf(' ', httpvers + 1);
+
+ if (code == -1) {
+ reset();
+ throw new HttpProtocolException("no status code in response");
+ }
+ mStatusCode = mLine.substring(httpvers + 1, code);
+ try {
+ Integer.parseInt(mStatusCode);
+ } catch (NumberFormatException e) {
+ reset();
+ throw new HttpProtocolException("Bad status code in response");
+ }
+
+ mReasonPhrase = mLine.substring(code + 1);
+ }
+
+ public void reset() {
+ mStatusCode = null;
+ mHttpVers = null;
+ mReasonPhrase = null;
+ super.reset();
+ }
+
+ /**
+ * get http version
+ */
+ public String getHttpVers() {
+ return mHttpVers;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/http/JssSSLSocketFactory.java b/base/util/src/com/netscape/cmsutil/http/JssSSLSocketFactory.java
new file mode 100644
index 000000000..c2013a5d2
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/http/JssSSLSocketFactory.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.cmsutil.http;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.ssl.SSLCertificateApprovalCallback;
+import org.mozilla.jss.ssl.SSLClientCertificateSelectionCallback;
+import org.mozilla.jss.ssl.SSLHandshakeCompletedEvent;
+import org.mozilla.jss.ssl.SSLHandshakeCompletedListener;
+import org.mozilla.jss.ssl.SSLSocket;
+
+import com.netscape.cmsutil.net.ISocketFactory;
+
+/**
+ * Uses NSS ssl socket.
+ *
+ * @version $Revision$ $Date$
+ */
+public class JssSSLSocketFactory implements ISocketFactory {
+ private String mClientAuthCertNickname = null;
+ private SSLSocket s = null;
+
+ public JssSSLSocketFactory() {
+ }
+
+ public JssSSLSocketFactory(String certNickname) {
+ mClientAuthCertNickname = certNickname;
+ }
+
+ // XXX remove these static SSL cipher suite initializations later on.
+ static final int cipherSuites[] = {
+ SSLSocket.SSL3_RSA_WITH_RC4_128_MD5,
+ SSLSocket.SSL3_RSA_WITH_3DES_EDE_CBC_SHA,
+ SSLSocket.SSL3_RSA_WITH_DES_CBC_SHA,
+ SSLSocket.SSL3_RSA_EXPORT_WITH_RC4_40_MD5,
+ SSLSocket.SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
+ SSLSocket.SSL3_RSA_WITH_NULL_MD5,
+ SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+ SSLSocket.TLS_RSA_WITH_AES_128_CBC_SHA,
+ SSLSocket.TLS_RSA_WITH_AES_256_CBC_SHA,
+ SSLSocket.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
+ SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+ //SSLSocket.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ //SSLSocket.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+ //SSLSocket.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+ SSLSocket.TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+ SSLSocket.TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
+ SSLSocket.TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+ SSLSocket.TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
+ 0
+ };
+
+ static {
+ int i;
+
+ for (i = SSLSocket.SSL2_RC4_128_WITH_MD5; i <= SSLSocket.SSL2_RC2_128_CBC_EXPORT40_WITH_MD5; ++i) {
+ try {
+ SSLSocket.setCipherPreferenceDefault(i, false);
+ } catch (SocketException e) {
+ }
+ }
+
+ //skip SSL_EN_IDEA_128_EDE3_CBC_WITH_MD5
+ for (i = SSLSocket.SSL2_DES_64_CBC_WITH_MD5; i <= SSLSocket.SSL2_DES_192_EDE3_CBC_WITH_MD5; ++i) {
+ try {
+ SSLSocket.setCipherPreferenceDefault(i, false);
+ } catch (SocketException e) {
+ }
+ }
+ for (i = 0; cipherSuites[i] != 0; ++i) {
+ try {
+ SSLSocket.setCipherPreferenceDefault(cipherSuites[i], true);
+ } catch (SocketException e) {
+ }
+ }
+ }
+
+ public Socket makeSocket(String host, int port)
+ throws IOException, UnknownHostException {
+ return makeSocket(host, port, null, null);
+ }
+
+ public Socket makeSocket(String host, int port,
+ SSLCertificateApprovalCallback certApprovalCallback,
+ SSLClientCertificateSelectionCallback clientCertCallback)
+ throws IOException, UnknownHostException {
+
+ try {
+ s = new SSLSocket(host, port, null, 0, certApprovalCallback,
+ clientCertCallback);
+ for (int i = 0; cipherSuites[i] != 0; ++i) {
+ try {
+ SSLSocket.setCipherPreferenceDefault(cipherSuites[i], true);
+ } catch (SocketException e) {
+ }
+ }
+
+ s.setUseClientMode(true);
+ s.enableSSL2(false);
+ //TODO Do we rally want to set the default each time?
+ SSLSocket.enableSSL2Default(false);
+ s.enableV2CompatibleHello(false);
+
+ SSLHandshakeCompletedListener listener = null;
+
+ listener = new ClientHandshakeCB(this);
+ s.addHandshakeCompletedListener(listener);
+
+ if (mClientAuthCertNickname != null) {
+ // 052799 setClientCertNickname does not
+ // report error if the nickName is invalid.
+ // So we check this ourself using
+ // findCertByNickname
+ CryptoManager.getInstance().findCertByNickname(mClientAuthCertNickname);
+
+ s.setClientCertNickname(mClientAuthCertNickname);
+ }
+ s.forceHandshake();
+ } catch (org.mozilla.jss.crypto.ObjectNotFoundException e) {
+ throw new IOException(e.toString());
+ } catch (org.mozilla.jss.crypto.TokenException e) {
+ throw new IOException(e.toString());
+ } catch (UnknownHostException e) {
+ throw e;
+ } catch (IOException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new IOException(e.toString());
+ }
+ return s;
+ }
+
+ public Socket makeSocket(String host, int port, int timeout)
+ throws IOException, UnknownHostException {
+ Thread t = new ConnectAsync(this, host, port);
+
+ t.start();
+ try {
+ t.join(1000 * timeout);
+ } catch (InterruptedException e) {
+ }
+
+ if (t.isAlive()) {
+ }
+
+ return s;
+ }
+
+ 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) {
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/ldap/LDAPUtil.java b/base/util/src/com/netscape/cmsutil/ldap/LDAPUtil.java
new file mode 100644
index 000000000..e821db67a
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/ldap/LDAPUtil.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.cmsutil.ldap;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPModification;
+import netscape.ldap.util.LDIF;
+import netscape.ldap.util.LDIFAttributeContent;
+import netscape.ldap.util.LDIFContent;
+import netscape.ldap.util.LDIFModifyContent;
+import netscape.ldap.util.LDIFRecord;
+
+public class LDAPUtil {
+
+ // special chars are *, (, ), \, null
+ public static String SPECIAL_CHARS = "*()\\\000";
+
+ /**
+ * This method escapes special characters for LDAP filter (RFC 4515).
+ * Each special character will be replaced by a backslash followed by
+ * 2-digit hex of the ASCII code.
+ *
+ * @param string string to escape
+ * @return escaped string
+ */
+ public static String escape(String string) {
+ StringBuilder sb = new StringBuilder();
+ for (char c : string.toCharArray()) {
+ if (SPECIAL_CHARS.indexOf(c) >= 0) {
+ sb.append('\\');
+ if (c < 0x10) sb.append('0'); // make sure it's 2-digit
+ sb.append(Integer.toHexString(c));
+ } else {
+ sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+
+ public static void importLDIF(LDAPConnection conn, String filename, ArrayList<String> errors) throws IOException {
+ LDIF ldif = new LDIF(filename);
+ while (true) {
+ try {
+ LDIFRecord record = ldif.nextRecord();
+ if (record == null)
+ break;
+
+ String dn = record.getDN();
+ LDIFContent content = record.getContent();
+ int type = content.getType();
+ if (type == LDIFContent.ATTRIBUTE_CONTENT) {
+ LDIFAttributeContent c = (LDIFAttributeContent) content;
+ LDAPAttribute[] attrs = c.getAttributes();
+ LDAPAttributeSet myAttrs = new LDAPAttributeSet();
+ for (int i = 0; i < attrs.length; i++)
+ myAttrs.add(attrs[i]);
+ LDAPEntry entry = new LDAPEntry(dn, myAttrs);
+ try {
+ conn.add(entry);
+ } catch (LDAPException ee) {
+ errors.add("LDAPUtil:importLDIF: exception in adding entry " + dn +
+ ":" + ee.toString() + "\n");
+ }
+ } else if (type == LDIFContent.MODIFICATION_CONTENT) {
+ LDIFModifyContent c = (LDIFModifyContent) content;
+ LDAPModification[] mods = c.getModifications();
+ try {
+ conn.modify(dn, mods);
+ } catch (LDAPException ee) {
+ errors.add("LDAPUtil:importLDIF: exception in modifying entry " + dn +
+ ":" + ee.toString());
+ }
+ }
+ } catch (Exception e) {
+ throw new IOException(e.toString());
+ }
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/net/ISocketFactory.java b/base/util/src/com/netscape/cmsutil/net/ISocketFactory.java
new file mode 100644
index 000000000..18f6cac88
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/net/ISocketFactory.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.cmsutil.net;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+import org.mozilla.jss.ssl.SSLCertificateApprovalCallback;
+import org.mozilla.jss.ssl.SSLClientCertificateSelectionCallback;
+
+public interface ISocketFactory {
+ Socket makeSocket(String host, int port)
+ throws IOException, UnknownHostException;
+
+ Socket makeSocket(String host, int port, int timeout)
+ throws IOException, UnknownHostException;
+
+ Socket makeSocket(String host, int port,
+ SSLCertificateApprovalCallback certApprovalCallback,
+ SSLClientCertificateSelectionCallback clientCertCallback)
+ throws IOException, UnknownHostException;
+}
diff --git a/base/util/src/com/netscape/cmsutil/ocsp/BasicOCSPResponse.java b/base/util/src/com/netscape/cmsutil/ocsp/BasicOCSPResponse.java
new file mode 100644
index 000000000..11ae7f152
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/ocsp/BasicOCSPResponse.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.cmsutil.ocsp;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.mozilla.jss.asn1.ASN1Template;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.BIT_STRING;
+import org.mozilla.jss.asn1.EXPLICIT;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.Tag;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+
+/**
+ * RFC 2560:
+ *
+ * <pre>
+ * BasicOCSPResponse ::= SEQUENCE {
+ * tbsResponseData ResponseData,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signature BIT STRING,
+ * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+ * </pre>
+ *
+ * @version $Revision$ $Date$
+ */
+public class BasicOCSPResponse implements Response {
+ private byte mData[] = null;
+ private ResponseData _rd = null;
+ private AlgorithmIdentifier _signAlg = null;
+ private BIT_STRING _signature = null;
+ private Certificate _certs[] = null;
+
+ public BasicOCSPResponse(ResponseData rd, AlgorithmIdentifier signAlg,
+ BIT_STRING signature, Certificate certs[]) {
+ _rd = rd;
+ _signAlg = signAlg;
+ _signature = signature;
+ _certs = certs;
+ }
+
+ public BasicOCSPResponse(OCTET_STRING os) {
+ this(os.toByteArray());
+ }
+
+ public BasicOCSPResponse(byte data[]) {
+ mData = data;
+
+ // extract _rd, _signAlg, _signature and _certs
+ try {
+ BasicOCSPResponse resp = (BasicOCSPResponse) getTemplate().decode(new ByteArrayInputStream(data));
+ _rd = resp.getResponseData();
+ _signAlg = resp.getSignatureAlgorithm();
+ _signature = resp.getSignature();
+ _certs = resp.getCerts();
+ } catch (Exception e) {
+ // exception in decoding byte data
+ }
+ }
+
+ private static final Tag TAG = SEQUENCE.TAG;
+
+ public Tag getTag() {
+ return TAG;
+ }
+
+ public void encode(Tag t, OutputStream os) throws IOException {
+ if (mData != null) {
+ os.write(mData);
+ } else {
+ SEQUENCE seq = new SEQUENCE();
+ seq.addElement(_rd);
+ seq.addElement(_signAlg);
+ seq.addElement(_signature);
+ if (_certs != null) {
+ SEQUENCE certsSeq = new SEQUENCE();
+ for (Certificate c : _certs) {
+ certsSeq.addElement(c);
+ }
+ EXPLICIT certsExplicit = new EXPLICIT(new Tag(0), certsSeq);
+ seq.addElement(certsExplicit);
+ }
+ seq.encode(t, os);
+ }
+ }
+
+ public void encode(OutputStream os) throws IOException {
+ encode(TAG, os);
+ }
+
+ public OCTET_STRING getBytes() {
+ return null;
+ }
+
+ public ResponseData getResponseData() {
+ return _rd;
+ }
+
+ public AlgorithmIdentifier getSignatureAlgorithm() {
+ return _signAlg;
+ }
+
+ public BIT_STRING getSignature() {
+ return _signature;
+ }
+
+ public int getCertsCount() {
+ return (_certs != null) ? _certs.length : 0;
+ }
+
+ public Certificate[] getCerts() {
+ return _certs;
+ }
+
+ public Certificate getCertificateAt(int pos) {
+ return (_certs != null) ? _certs[pos] : null;
+ }
+
+ private static final Template templateInstance = new Template();
+
+ public static Template getTemplate() {
+ return templateInstance;
+ }
+
+ /**
+ * A Template for decoding <code>ResponseBytes</code>.
+ */
+ public static class Template implements ASN1Template {
+ private SEQUENCE.Template seqt;
+
+ public Template() {
+ seqt = new SEQUENCE.Template();
+ seqt.addElement(ResponseData.getTemplate());
+ seqt.addElement(AlgorithmIdentifier.getTemplate());
+ seqt.addElement(BIT_STRING.getTemplate());
+ seqt.addOptionalElement(new EXPLICIT.Template(
+ new Tag(0), new SEQUENCE.OF_Template(
+ Certificate.getTemplate())));
+ }
+
+ public boolean tagMatch(Tag tag) {
+ return TAG.equals(tag);
+ }
+
+ public ASN1Value decode(InputStream istream)
+ throws InvalidBERException, IOException {
+ return decode(TAG, istream);
+ }
+
+ public ASN1Value decode(Tag implicitTag, InputStream istream)
+ throws InvalidBERException, IOException {
+ SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream);
+
+ ResponseData rd = (ResponseData) seq.elementAt(0);
+ AlgorithmIdentifier alg = (AlgorithmIdentifier) seq.elementAt(1);
+ BIT_STRING bs = (BIT_STRING) seq.elementAt(2);
+ Certificate[] certs = null;
+ if (seq.size() == 4) {
+ // optional certificates are present
+ EXPLICIT certSeqExplicit = (EXPLICIT) seq.elementAt(3);
+ SEQUENCE certSeq = (SEQUENCE) certSeqExplicit.getContent();
+ if (certSeq != null) {
+ certs = new Certificate[certSeq.size()];
+ for (int x = 0; x < certSeq.size(); x++) {
+ certs[x] = (Certificate) certSeq.elementAt(x);
+ }
+ }
+ }
+
+ return new BasicOCSPResponse(rd, alg, bs, certs);
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/ocsp/CertID.java b/base/util/src/com/netscape/cmsutil/ocsp/CertID.java
new file mode 100644
index 000000000..b6979c784
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/ocsp/CertID.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.cmsutil.ocsp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.mozilla.jss.asn1.ASN1Template;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.Tag;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+
+/**
+ * RFC 2560:
+ *
+ * <pre>
+ * CertID ::= SEQUENCE {
+ * hashAlgorithm AlgorithmIdentifier,
+ * issuerNameHash OCTET STRING, -- Hash of Issuer's DN
+ * issuerKeyHash OCTET STRING, -- Hash of Issuers public key
+ * serialNumber CertificateSerialNumber }
+ * </pre>
+ *
+ * @version $Revision$ $Date$
+ */
+
+public class CertID implements ASN1Value {
+ ///////////////////////////////////////////////////////////////////////
+ // Members and member access
+ ///////////////////////////////////////////////////////////////////////
+ private AlgorithmIdentifier hashAlgorithm;
+ private OCTET_STRING issuerNameHash;
+ private OCTET_STRING issuerKeyHash;
+ private INTEGER serialNumber;
+ private SEQUENCE sequence;
+
+ public AlgorithmIdentifier getHashAlgorithm() {
+ return hashAlgorithm;
+ }
+
+ public OCTET_STRING getIssuerNameHash() {
+ return issuerNameHash;
+ }
+
+ public OCTET_STRING getIssuerKeyHash() {
+ return issuerKeyHash;
+ }
+
+ public INTEGER getSerialNumber() {
+ return serialNumber;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ // Constructors
+ ///////////////////////////////////////////////////////////////////////
+
+ public CertID(AlgorithmIdentifier hashAlgorithm,
+ OCTET_STRING issuerNameHash, OCTET_STRING issuerKeyHash,
+ INTEGER serialNumber) {
+ sequence = new SEQUENCE();
+
+ this.hashAlgorithm = hashAlgorithm;
+ sequence.addElement(hashAlgorithm);
+
+ this.issuerNameHash = issuerNameHash;
+ sequence.addElement(issuerNameHash);
+
+ this.issuerKeyHash = issuerKeyHash;
+ sequence.addElement(issuerKeyHash);
+
+ this.serialNumber = serialNumber;
+ sequence.addElement(serialNumber);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ // encoding/decoding
+ ///////////////////////////////////////////////////////////////////////
+
+ private static final Tag TAG = SEQUENCE.TAG;
+
+ public Tag getTag() {
+ return TAG;
+ }
+
+ public void encode(OutputStream ostream) throws IOException {
+ encode(TAG, ostream);
+ }
+
+ public void encode(Tag implicitTag, OutputStream ostream)
+ throws IOException {
+ sequence.encode(implicitTag, ostream);
+ }
+
+ private static final Template templateInstance = new Template();
+
+ public static Template getTemplate() {
+ return templateInstance;
+ }
+
+ /**
+ * A Template for decoding a <code>CertID</code>.
+ */
+ public static class Template implements ASN1Template {
+
+ private SEQUENCE.Template seqt;
+
+ public Template() {
+ seqt = new SEQUENCE.Template();
+ seqt.addElement(AlgorithmIdentifier.getTemplate());
+ seqt.addElement(OCTET_STRING.getTemplate());
+ seqt.addElement(OCTET_STRING.getTemplate());
+ seqt.addElement(INTEGER.getTemplate());
+ }
+
+ public boolean tagMatch(Tag tag) {
+ return TAG.equals(tag);
+ }
+
+ public ASN1Value decode(InputStream istream)
+ throws InvalidBERException, IOException {
+ return decode(TAG, istream);
+ }
+
+ public ASN1Value decode(Tag implicitTag, InputStream istream)
+ throws InvalidBERException, IOException {
+ SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream);
+
+ return new CertID(
+ (AlgorithmIdentifier) seq.elementAt(0),
+ (OCTET_STRING) seq.elementAt(1),
+ (OCTET_STRING) seq.elementAt(2),
+ (INTEGER) seq.elementAt(3));
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/ocsp/CertStatus.java b/base/util/src/com/netscape/cmsutil/ocsp/CertStatus.java
new file mode 100644
index 000000000..a90eb215f
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/ocsp/CertStatus.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.cmsutil.ocsp;
+
+import org.mozilla.jss.asn1.ASN1Value;
+
+/**
+ * RFC 2560:
+ *
+ * <pre>
+ * CertStatus ::= CHOICE {
+ * good [0] IMPLICIT NULL,
+ * revoked [1] IMPLICIT RevokedInfo,
+ * unknown [2] IMPLICIT UnknownInfo }
+ * </pre>
+ *
+ * @version $Revision$ $Date$
+ */
+public interface CertStatus extends ASN1Value {
+}
diff --git a/base/util/src/com/netscape/cmsutil/ocsp/GoodInfo.java b/base/util/src/com/netscape/cmsutil/ocsp/GoodInfo.java
new file mode 100644
index 000000000..fa7387260
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/ocsp/GoodInfo.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.cmsutil.ocsp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.mozilla.jss.asn1.ASN1Template;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.NULL;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.Tag;
+
+/**
+ * RFC 2560:
+ *
+ * <pre>
+ * CertStatus ::= CHOICE {
+ * good [0] IMPLICIT NULL,
+ * revoked [1] IMPLICIT RevokedInfo,
+ * unknown [2] IMPLICIT UnknownInfo }
+ * </pre>
+ *
+ * @version $Revision$ $Date$
+ */
+public class GoodInfo implements CertStatus {
+ private static final Tag TAG = SEQUENCE.TAG;
+
+ public GoodInfo() {
+ }
+
+ public Tag getTag() {
+ return Tag.get(0);
+ }
+
+ public void encode(Tag t, OutputStream os) throws IOException {
+ NULL.getInstance().encode(getTag(), os);
+ }
+
+ public void encode(OutputStream os) throws IOException {
+ encode(getTag(), os);
+ }
+
+ private static final Template templateInstance = new Template();
+
+ public static Template getTemplate() {
+ return templateInstance;
+ }
+
+ /**
+ * A Template for decoding <code>ResponseBytes</code>.
+ */
+ public static class Template implements ASN1Template {
+
+ private SEQUENCE.Template seqt;
+
+ public Template() {
+ seqt = new SEQUENCE.Template();
+ seqt.addElement(new NULL.Template());
+
+ }
+
+ public boolean tagMatch(Tag tag) {
+ return TAG.equals(tag);
+ }
+
+ public ASN1Value decode(InputStream istream)
+ throws InvalidBERException, IOException {
+ return decode(TAG, istream);
+ }
+
+ public ASN1Value decode(Tag implicitTag, InputStream istream)
+ throws InvalidBERException, IOException {
+ // SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,
+ // istream);
+
+ return new GoodInfo();
+
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/ocsp/KeyHashID.java b/base/util/src/com/netscape/cmsutil/ocsp/KeyHashID.java
new file mode 100644
index 000000000..358fb0ebd
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/ocsp/KeyHashID.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.cmsutil.ocsp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.mozilla.jss.asn1.ASN1Template;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.Tag;
+
+/**
+ * RFC 2560:
+ *
+ * <pre>
+ * ResponderID ::= CHOICE {
+ * byName [1] EXPLICIT Name,
+ * byKey [2] EXPLICIT KeyHash }
+ * </pre>
+ *
+ * @version $Revision$ $Date$
+ */
+public class KeyHashID implements ResponderID {
+ private OCTET_STRING _hash = null;
+ private static final Tag TAG = SEQUENCE.TAG;
+
+ public KeyHashID(OCTET_STRING hash) {
+ _hash = hash;
+ }
+
+ public Tag getTag() {
+ return Tag.get(2);
+ }
+
+ public void encode(Tag tag, OutputStream os) throws IOException {
+ _hash.encode(os);
+ }
+
+ public void encode(OutputStream os) throws IOException {
+ _hash.encode(os);
+ }
+
+ public OCTET_STRING getHash() {
+ return _hash;
+ }
+
+ private static final Template templateInstance = new Template();
+
+ public static Template getTemplate() {
+ return templateInstance;
+ }
+
+ /**
+ * A Template for decoding <code>ResponseBytes</code>.
+ */
+ public static class Template implements ASN1Template {
+
+ private SEQUENCE.Template seqt;
+
+ public Template() {
+ seqt = new SEQUENCE.Template();
+ // seqt.addElement(new EXPLICIT.Template(
+ // new Tag (2), new OCTET_STRING.Template()) );
+ seqt.addElement(new OCTET_STRING.Template());
+
+ }
+
+ public boolean tagMatch(Tag tag) {
+ return TAG.equals(tag);
+ }
+
+ public ASN1Value decode(InputStream istream)
+ throws InvalidBERException, IOException {
+ return decode(TAG, istream);
+ }
+
+ public ASN1Value decode(Tag implicitTag, InputStream istream)
+ throws InvalidBERException, IOException {
+ SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,
+ istream);
+
+ OCTET_STRING o = (OCTET_STRING) seq.elementAt(0);
+ return new KeyHashID(o);
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/ocsp/NameID.java b/base/util/src/com/netscape/cmsutil/ocsp/NameID.java
new file mode 100644
index 000000000..529ededbb
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/ocsp/NameID.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.cmsutil.ocsp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.mozilla.jss.asn1.ASN1Template;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.Tag;
+import org.mozilla.jss.pkix.primitive.Name;
+
+/**
+ * RFC 2560:
+ *
+ * <pre>
+ * ResponderID ::= CHOICE {
+ * byName [1] EXPLICIT Name,
+ * byKey [2] EXPLICIT KeyHash }
+ * </pre>
+ *
+ * @version $Revision$ $Date$
+ */
+public class NameID implements ResponderID {
+ private Name _name = null;
+ private static final Tag TAG = SEQUENCE.TAG;
+
+ public NameID(Name n) {
+ _name = n;
+ }
+
+ public Tag getTag() {
+ return Tag.get(1);
+ }
+
+ public void encode(Tag tag, OutputStream os) throws IOException {
+ _name.encode(os);
+ }
+
+ public void encode(OutputStream os) throws IOException {
+ _name.encode(os);
+ }
+
+ public Name getName() {
+ return _name;
+ }
+
+ private static final Template templateInstance = new Template();
+
+ public static Template getTemplate() {
+ return templateInstance;
+ }
+
+ /**
+ * A Template for decoding <code>ResponseBytes</code>.
+ */
+ public static class Template implements ASN1Template {
+
+ private SEQUENCE.Template seqt;
+
+ public Template() {
+ seqt = new SEQUENCE.Template();
+ // seqt.addElement(new EXPLICIT.Template(
+ // new Tag (1), new Name.Template()) );
+ seqt.addElement(new Name.Template());
+
+ }
+
+ public boolean tagMatch(Tag tag) {
+ return TAG.equals(tag);
+ }
+
+ public ASN1Value decode(InputStream istream)
+ throws InvalidBERException, IOException {
+ return decode(TAG, istream);
+ }
+
+ public ASN1Value decode(Tag implicitTag, InputStream istream)
+ throws InvalidBERException, IOException {
+ SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,
+ istream);
+
+ // EXPLICIT e_name = (EXPLICIT) seq.elementAt(0);
+ Name name = (Name) seq.elementAt(0);
+ return new NameID(name);
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/ocsp/OCSPRequest.java b/base/util/src/com/netscape/cmsutil/ocsp/OCSPRequest.java
new file mode 100644
index 000000000..963bdc832
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/ocsp/OCSPRequest.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 com.netscape.cmsutil.ocsp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.mozilla.jss.asn1.ASN1Template;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.EXPLICIT;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.Tag;
+
+/**
+ * RFC 2560:
+ *
+ * <pre>
+ * OCSPRequest ::= SEQUENCE {
+ * tbsRequest TBSRequest,
+ * optionalSignature [0] EXPLICIT Signature OPTIONAL }
+ * </pre>
+ *
+ * @version $Revision$ $Date$
+ */
+
+public class OCSPRequest implements ASN1Value {
+
+ ///////////////////////////////////////////////////////////////////////
+ // Members and member access
+ ///////////////////////////////////////////////////////////////////////
+ private TBSRequest tbsRequest;
+ private Signature optionalSignature;
+ private SEQUENCE sequence;
+
+ /**
+ * Returns the <code>TBSRequest</code> field.
+ */
+ public TBSRequest getTBSRequest() {
+ return tbsRequest;
+ }
+
+ /**
+ * Returns the <code>Signature</code> field.
+ */
+ public Signature getSignature() {
+ return optionalSignature;
+ }
+
+ /* THIS code is probably broken. It does not properly encode the explicit element */
+
+ public OCSPRequest(TBSRequest tbsRequest, Signature optionalSignature) {
+ sequence = new SEQUENCE();
+
+ this.tbsRequest = tbsRequest;
+ sequence.addElement(tbsRequest);
+
+ this.optionalSignature = optionalSignature;
+ if (optionalSignature != null) {
+ sequence.addElement(optionalSignature);
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ // encoding/decoding
+ ///////////////////////////////////////////////////////////////////////
+ private static final Tag TAG = SEQUENCE.TAG;
+
+ public Tag getTag() {
+ return TAG;
+ }
+
+ public void encode(OutputStream ostream) throws IOException {
+ encode(TAG, ostream);
+ }
+
+ public void encode(Tag implicitTag, OutputStream ostream)
+ throws IOException {
+ sequence.encode(implicitTag, ostream);
+ }
+
+ private static final Template templateInstance = new Template();
+
+ public static Template getTemplate() {
+ return templateInstance;
+ }
+
+ /**
+ * A Template for decoding OCSPRequest.
+ */
+ public static class Template implements ASN1Template {
+
+ private SEQUENCE.Template seqt;
+
+ public Template() {
+ seqt = new SEQUENCE.Template();
+ seqt.addElement(TBSRequest.getTemplate());
+ seqt.addOptionalElement(new EXPLICIT.Template(new Tag(0),
+ new Signature.Template()));
+ }
+
+ public boolean tagMatch(Tag tag) {
+ return TAG.equals(tag);
+ }
+
+ public ASN1Value decode(InputStream istream)
+ throws InvalidBERException, IOException {
+ return decode(TAG, istream);
+ }
+
+ public ASN1Value decode(Tag implicitTag, InputStream istream)
+ throws InvalidBERException, IOException {
+ SEQUENCE seq = (SEQUENCE) seqt.decode(istream);
+ Signature signature = null;
+ if (seq.elementAt(1) != null) {
+ signature = (Signature) ((EXPLICIT) seq.elementAt(1)).getContent();
+ }
+
+ return new OCSPRequest(
+ (TBSRequest) seq.elementAt(0),
+ signature);
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/ocsp/OCSPResponse.java b/base/util/src/com/netscape/cmsutil/ocsp/OCSPResponse.java
new file mode 100644
index 000000000..6696cd9dc
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/ocsp/OCSPResponse.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.cmsutil.ocsp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.mozilla.jss.asn1.ASN1Template;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.EXPLICIT;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.Tag;
+
+/**
+ * RFC 2560:
+ *
+ * <pre>
+ * OCSPResponse ::= SEQUENCE {
+ * responseStatus OCSPResponseStatus,
+ * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
+ * </pre>
+ *
+ * @version $Revision$ $Date$
+ */
+public class OCSPResponse implements ASN1Value {
+ ///////////////////////////////////////////////////////////////////////
+ // Members and member access
+ ///////////////////////////////////////////////////////////////////////
+ private OCSPResponseStatus responseStatus = null;
+ private ResponseBytes responseBytes = null;
+ private SEQUENCE sequence;
+
+ public OCSPResponseStatus getResponseStatus() {
+ return responseStatus;
+ }
+
+ public ResponseBytes getResponseBytes() {
+ return responseBytes;
+ }
+
+ public OCSPResponse(OCSPResponseStatus responseStatus,
+ ResponseBytes responseBytes) {
+ sequence = new SEQUENCE();
+
+ this.responseStatus = responseStatus;
+ sequence.addElement(responseStatus);
+
+ this.responseBytes = responseBytes;
+ sequence.addElement(new EXPLICIT(Tag.get(0), responseBytes));
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ // encoding/decoding
+ ///////////////////////////////////////////////////////////////////////
+
+ private static final Tag TAG = SEQUENCE.TAG;
+
+ public Tag getTag() {
+ return TAG;
+ }
+
+ public void encode(OutputStream ostream) throws IOException {
+ encode(TAG, ostream);
+ }
+
+ public void encode(Tag implicitTag, OutputStream ostream)
+ throws IOException {
+ sequence.encode(implicitTag, ostream);
+ }
+
+ private static final Template templateInstance = new Template();
+
+ public static Template getTemplate() {
+ return templateInstance;
+ }
+
+ /**
+ * A Template for decoding an <code>OCSPResponse</code>.
+ */
+ public static class Template implements ASN1Template {
+
+ private SEQUENCE.Template seqt;
+
+ public Template() {
+ seqt = new SEQUENCE.Template();
+ seqt.addElement(OCSPResponseStatus.getTemplate());
+ seqt.addOptionalElement(
+ new EXPLICIT.Template(
+ new Tag(0), new ResponseBytes.Template()));
+
+ }
+
+ public boolean tagMatch(Tag tag) {
+ return TAG.equals(tag);
+ }
+
+ public ASN1Value decode(InputStream istream)
+ throws InvalidBERException, IOException {
+ return decode(TAG, istream);
+ }
+
+ public ASN1Value decode(Tag implicitTag, InputStream istream)
+ throws InvalidBERException, IOException {
+ SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream);
+
+ OCSPResponseStatus rs = (OCSPResponseStatus) seq.elementAt(0);
+ ResponseBytes rb = null;
+ ASN1Value val = seq.elementAt(1);
+ if (val instanceof EXPLICIT) {
+ EXPLICIT exp = (EXPLICIT) val;
+ rb = (ResponseBytes) exp.getContent();
+ } else {
+ rb = (ResponseBytes) val;
+ }
+ return new OCSPResponse(rs, rb);
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/ocsp/OCSPResponseStatus.java b/base/util/src/com/netscape/cmsutil/ocsp/OCSPResponseStatus.java
new file mode 100644
index 000000000..38ca881c2
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/ocsp/OCSPResponseStatus.java
@@ -0,0 +1,120 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmsutil.ocsp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.mozilla.jss.asn1.ASN1Template;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.ENUMERATED;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.Tag;
+
+/**
+ * RFC 2560:
+ *
+ * <pre>
+ * OCSPResponseStatus ::= ENUMERATED {
+ * successful (0), --Response has valid confirmations
+ * malformedRequest (1), --Illegal confirmation request
+ * internalError (2), --Internal error in issuer
+ * tryLater (3), --Try again later
+ * --(4) is not used
+ * sigRequired (5), --Must sign the request
+ * unauthorized (6) --Request unauthorized
+ * }
+ * </pre>
+ *
+ * @version $Revision$ $Date$
+ */
+public class OCSPResponseStatus implements ASN1Value {
+ ///////////////////////////////////////////////////////////////////////
+ // Members and member access
+ ///////////////////////////////////////////////////////////////////////
+ public final static OCSPResponseStatus SUCCESSFUL =
+ new OCSPResponseStatus(0);
+ public final static OCSPResponseStatus MALFORMED_REQUEST =
+ new OCSPResponseStatus(1);
+ public final static OCSPResponseStatus INTERNAL_ERROR =
+ new OCSPResponseStatus(2);
+ public final static OCSPResponseStatus TRY_LATER =
+ new OCSPResponseStatus(3);
+ public final static OCSPResponseStatus SIG_REQUIRED =
+ new OCSPResponseStatus(5);
+ public final static OCSPResponseStatus UNAUTHORIZED =
+ new OCSPResponseStatus(6);
+
+ private ENUMERATED responseStatus;
+
+ public long getValue() {
+ return responseStatus.getValue();
+ }
+
+ public OCSPResponseStatus(long val) {
+ responseStatus = new ENUMERATED(val);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ // encoding/decoding
+ ///////////////////////////////////////////////////////////////////////
+
+ private static final Tag TAG = ENUMERATED.TAG;
+
+ public Tag getTag() {
+ return TAG;
+ }
+
+ public void encode(OutputStream ostream) throws IOException {
+ encode(TAG, ostream);
+ }
+
+ public void encode(Tag implicitTag, OutputStream ostream)
+ throws IOException {
+ responseStatus.encode(implicitTag, ostream);
+ }
+
+ private static final Template templateInstance = new Template();
+
+ public static Template getTemplate() {
+ return templateInstance;
+ }
+
+ /**
+ * A Template for decoding an <code>OCSPResponseStatus</code>.
+ */
+ public static class Template implements ASN1Template {
+ public boolean tagMatch(Tag tag) {
+ return TAG.equals(tag);
+ }
+
+ public ASN1Value decode(InputStream istream)
+ throws InvalidBERException, IOException {
+ return decode(TAG, istream);
+ }
+
+ public ASN1Value decode(Tag implicitTag, InputStream istream)
+ throws InvalidBERException, IOException {
+ ENUMERATED.Template enumt = new ENUMERATED.Template();
+ ENUMERATED enum1 = (ENUMERATED) enumt.decode(implicitTag, istream);
+
+ return new OCSPResponseStatus(enum1.getValue());
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/ocsp/Request.java b/base/util/src/com/netscape/cmsutil/ocsp/Request.java
new file mode 100644
index 000000000..85c97de22
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/ocsp/Request.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.cmsutil.ocsp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.mozilla.jss.asn1.ASN1Template;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.EXPLICIT;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.Tag;
+import org.mozilla.jss.pkix.cert.Extension;
+
+/**
+ * RFC 2560:
+ *
+ * <pre>
+ * Request ::= SEQUENCE {
+ * reqCert CertID,
+ * singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL }
+ * </pre>
+ *
+ * @version $Revision$ $Date$
+ */
+
+public class Request implements ASN1Value {
+ ///////////////////////////////////////////////////////////////////////
+ // members and member access
+ ///////////////////////////////////////////////////////////////////////
+ private CertID reqCert = null;
+ private SEQUENCE singleRequestExtensions = null;
+ private SEQUENCE sequence = null;
+
+ public CertID getCertID() {
+ return reqCert;
+ }
+
+ public int getExtensionsCount() {
+ if (singleRequestExtensions == null) {
+ return 0;
+ } else {
+ return singleRequestExtensions.size();
+ }
+ }
+
+ public Extension getRequestExtensionAt(int index) {
+ if (singleRequestExtensions == null) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+ return (Extension) singleRequestExtensions.elementAt(index);
+ }
+
+ public Request(CertID reqCert, SEQUENCE singleRequestExtensions) {
+ sequence = new SEQUENCE();
+
+ this.reqCert = reqCert;
+ sequence.addElement(reqCert);
+
+ if (singleRequestExtensions != null) {
+ this.singleRequestExtensions = singleRequestExtensions;
+ sequence.addElement(singleRequestExtensions);
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ // encode / decode
+ ///////////////////////////////////////////////////////////////////////
+ private static final Tag TAG = SEQUENCE.TAG;
+
+ public Tag getTag() {
+ return TAG;
+ }
+
+ public void encode(OutputStream ostream) throws IOException {
+ encode(TAG, ostream);
+ }
+
+ public void encode(Tag implicitTag, OutputStream ostream)
+ throws IOException {
+ sequence.encode(implicitTag, ostream);
+ }
+
+ private static final Template templateInstance = new Template();
+
+ public static Template getTemplate() {
+ return templateInstance;
+ }
+
+ /**
+ * A Template for decoding Request.
+ */
+ public static class Template implements ASN1Template {
+
+ private SEQUENCE.Template seqt;
+
+ public Template() {
+ seqt = new SEQUENCE.Template();
+ seqt.addElement(CertID.getTemplate());
+ seqt.addOptionalElement(new EXPLICIT.Template(new Tag(0),
+ new SEQUENCE.OF_Template(new Extension.Template())));
+ }
+
+ public boolean tagMatch(Tag tag) {
+ return TAG.equals(tag);
+ }
+
+ public ASN1Value decode(InputStream istream)
+ throws InvalidBERException, IOException {
+ return decode(TAG, istream);
+ }
+
+ public ASN1Value decode(Tag implicitTag, InputStream istream)
+ throws InvalidBERException, IOException {
+ SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream);
+
+ EXPLICIT tag = (EXPLICIT) seq.elementAt(1);
+
+ if (tag == null) {
+ return new Request(
+ (CertID) seq.elementAt(0),
+ (SEQUENCE) null);
+ } else {
+ return new Request(
+ (CertID) seq.elementAt(0),
+ (SEQUENCE) tag.getContent());
+ }
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/ocsp/ResponderID.java b/base/util/src/com/netscape/cmsutil/ocsp/ResponderID.java
new file mode 100644
index 000000000..02e30de05
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/ocsp/ResponderID.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.cmsutil.ocsp;
+
+import org.mozilla.jss.asn1.ASN1Value;
+
+/**
+ * RFC 2560:
+ *
+ * <pre>
+ * ResponderID ::= CHOICE {
+ * byName [1] EXPLICIT Name,
+ * byKey [2] EXPLICIT KeyHash }
+ * </pre>
+ *
+ * @version $Revision$ $Date$
+ */
+public interface ResponderID extends ASN1Value {
+}
diff --git a/base/util/src/com/netscape/cmsutil/ocsp/Response.java b/base/util/src/com/netscape/cmsutil/ocsp/Response.java
new file mode 100644
index 000000000..0d363e811
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/ocsp/Response.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.cmsutil.ocsp;
+
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.OCTET_STRING;
+
+/**
+ * RFC 2560:
+ *
+ * <pre>
+ * response OCTET STRING
+ * </pre>
+ *
+ * @version $Revision$ $Date$
+ */
+public interface Response extends ASN1Value {
+ public OCTET_STRING getBytes();
+}
diff --git a/base/util/src/com/netscape/cmsutil/ocsp/ResponseBytes.java b/base/util/src/com/netscape/cmsutil/ocsp/ResponseBytes.java
new file mode 100644
index 000000000..c5d461148
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/ocsp/ResponseBytes.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.cmsutil.ocsp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.mozilla.jss.asn1.ASN1Template;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.Tag;
+
+/**
+ * RFC 2560:
+ *
+ * <pre>
+ * ResponseBytes ::= SEQUENCE {
+ * responseType OBJECT IDENTIFIER,
+ * response OCTET STRING }
+ * </pre>
+ *
+ * @version $Revision$ $Date$
+ */
+public class ResponseBytes implements ASN1Value {
+ ///////////////////////////////////////////////////////////////////////
+ // Members and member access
+ ///////////////////////////////////////////////////////////////////////
+ public final static OBJECT_IDENTIFIER OCSP =
+ new OBJECT_IDENTIFIER("1.3.6.1.5.5.7.48.1");
+ public final static OBJECT_IDENTIFIER OCSP_BASIC =
+ new OBJECT_IDENTIFIER("1.3.6.1.5.5.7.48.1.1");
+
+ private OBJECT_IDENTIFIER responseType = null;
+ private OCTET_STRING response = null;
+ private SEQUENCE sequence;
+
+ public OBJECT_IDENTIFIER getObjectIdentifier() {
+ return responseType;
+ }
+
+ public OCTET_STRING getResponse() {
+ return response;
+ }
+
+ public ResponseBytes(OBJECT_IDENTIFIER responseType, OCTET_STRING response) {
+ sequence = new SEQUENCE();
+
+ this.responseType = responseType;
+ sequence.addElement(responseType);
+
+ this.response = response;
+ sequence.addElement(response);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ // encoding/decoding
+ ///////////////////////////////////////////////////////////////////////
+
+ private static final Tag TAG = SEQUENCE.TAG;
+
+ public Tag getTag() {
+ return TAG;
+ }
+
+ public void encode(OutputStream ostream) throws IOException {
+ encode(TAG, ostream);
+ }
+
+ public void encode(Tag implicitTag, OutputStream ostream)
+ throws IOException {
+ sequence.encode(implicitTag, ostream);
+ }
+
+ private static final Template templateInstance = new Template();
+
+ public static Template getTemplate() {
+ return templateInstance;
+ }
+
+ /**
+ * A Template for decoding <code>ResponseBytes</code>.
+ */
+ public static class Template implements ASN1Template {
+
+ private SEQUENCE.Template seqt;
+
+ public Template() {
+ seqt = new SEQUENCE.Template();
+ seqt.addElement(OBJECT_IDENTIFIER.getTemplate());
+ seqt.addElement(OCTET_STRING.getTemplate());
+ }
+
+ public boolean tagMatch(Tag tag) {
+ return TAG.equals(tag);
+ }
+
+ public ASN1Value decode(InputStream istream)
+ throws InvalidBERException, IOException {
+ return decode(TAG, istream);
+ }
+
+ public ASN1Value decode(Tag implicitTag, InputStream istream)
+ throws InvalidBERException, IOException {
+ SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream);
+
+ return new ResponseBytes(
+ (OBJECT_IDENTIFIER) seq.elementAt(0),
+ (OCTET_STRING) seq.elementAt(1));
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/ocsp/ResponseData.java b/base/util/src/com/netscape/cmsutil/ocsp/ResponseData.java
new file mode 100644
index 000000000..1b28cf134
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/ocsp/ResponseData.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.cmsutil.ocsp;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.asn1.ASN1Template;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.EXPLICIT;
+import org.mozilla.jss.asn1.GeneralizedTime;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.Tag;
+import org.mozilla.jss.pkix.cert.Extension;
+
+/**
+ * RFC 2560:
+ *
+ * <pre>
+ * ResponseData ::= SEQUENCE {
+ * version [0] EXPLICIT Version DEFAULT v1,
+ * responderID ResponderID,
+ * producedAt GeneralizedTime,
+ * responses SEQUENCE OF SingleResponse,
+ * responseExtensions [1] EXPLICIT Extensions OPTIONAL }
+ * </pre>
+ *
+ * @version $Revision$ $Date$
+ */
+public class ResponseData implements ASN1Value {
+ private static final INTEGER v1 = new INTEGER(0);
+ private INTEGER mVer;
+ private ResponderID mRID = null;
+ private GeneralizedTime mProduced = null;
+ private SingleResponse mSR[] = null;
+ private Extension mExts[] = null;
+
+ private static final Tag TAG = SEQUENCE.TAG;
+
+ public ResponseData(INTEGER ver, ResponderID rid, GeneralizedTime produced,
+ SingleResponse sr[], Extension exts[]) {
+ mVer = (ver != null) ? ver : v1;
+ mRID = rid;
+ mProduced = produced;
+ mSR = sr;
+ mExts = exts;
+ }
+
+ public ResponseData(ResponderID rid, GeneralizedTime produced,
+ SingleResponse sr[]) {
+ this(v1, rid, produced, sr, null);
+ }
+
+ public ResponseData(ResponderID rid, GeneralizedTime produced,
+ SingleResponse sr[], Extension exts[]) {
+ this(v1, rid, produced, sr, exts);
+ }
+
+ public Tag getTag() {
+ return TAG;
+ }
+
+ public void encode(OutputStream os) throws IOException {
+ encode(null, os);
+ }
+
+ public void encode(Tag t, OutputStream os) throws IOException {
+ SEQUENCE seq = new SEQUENCE();
+
+ if (mVer != v1) {
+ seq.addElement(new EXPLICIT(Tag.get(0), new INTEGER(mVer)));
+ }
+
+ seq.addElement(new EXPLICIT(mRID.getTag(), mRID));
+ seq.addElement(mProduced);
+ SEQUENCE responses = new SEQUENCE();
+ for (int i = 0; i < mSR.length; i++) {
+ responses.addElement(mSR[i]);
+ }
+ seq.addElement(responses);
+ if (mExts != null) {
+ SEQUENCE exts = new SEQUENCE();
+ for (int i = 0; i < mExts.length; i++) {
+ exts.addElement(mExts[i]);
+ }
+ seq.addElement(new EXPLICIT(Tag.get(1), exts));
+ }
+ if (t == null) {
+ seq.encode(os);
+ } else {
+ seq.encode(t, os);
+ }
+ }
+
+ public ResponderID getResponderID() {
+ return mRID;
+ }
+
+ public GeneralizedTime getProducedAt() {
+ return mProduced;
+ }
+
+ public int getResponseCount() {
+ return (mSR != null) ? mSR.length : 0;
+ }
+
+ public SingleResponse getResponseAt(int pos) {
+ return (mSR != null) ? mSR[pos] : null;
+ }
+
+ public int getResponseExtensionCount() {
+ return (mExts != null) ? mExts.length : 0;
+ }
+
+ public Extension getResponseExtensionAt(int pos) {
+ return (mExts != null) ? mExts[pos] : null;
+ }
+
+ private static final Template templateInstance = new Template();
+
+ public static Template getTemplate() {
+ return templateInstance;
+ }
+
+ /**
+ * A Template for decoding <code>ResponseBytes</code>.
+ */
+ public static class Template implements ASN1Template {
+
+ private SEQUENCE.Template seqt;
+
+ public Template() {
+ seqt = new SEQUENCE.Template();
+ seqt.addOptionalElement(new EXPLICIT.Template(
+ new Tag(0), new INTEGER.Template()));
+ seqt.addElement(new ANY.Template());
+ seqt.addElement(new GeneralizedTime.Template());
+ seqt.addElement(new SEQUENCE.OF_Template(
+ SingleResponse.getTemplate()));
+ seqt.addOptionalElement(new EXPLICIT.Template(
+ new Tag(1), new SEQUENCE.OF_Template(
+ Extension.getTemplate())));
+ }
+
+ public boolean tagMatch(Tag tag) {
+ return TAG.equals(tag);
+ }
+
+ public ASN1Value decode(InputStream istream)
+ throws InvalidBERException, IOException {
+ return decode(TAG, istream);
+ }
+
+ public ASN1Value decode(Tag implicitTag, InputStream istream)
+ throws InvalidBERException, IOException {
+ SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,
+ istream);
+
+ INTEGER ver = v1;
+ EXPLICIT e_ver = (EXPLICIT) seq.elementAt(0);
+ if (e_ver != null && e_ver.getTag().getNum() == 0) {
+ ver = (INTEGER) e_ver.getContent();
+ }
+ ResponderID rid = null;
+ ANY e_rid = (ANY) seq.elementAt(1);
+ if (e_rid.getTag().getNum() == 1) {
+ // name id
+ rid = (NameID)
+ NameID.getTemplate().decode(e_rid.getTag(),
+ new ByteArrayInputStream(e_rid.getEncoded()));
+ } else if (e_rid.getTag().getNum() == 2) {
+ // key hash id
+ rid = (KeyHashID)
+ KeyHashID.getTemplate().decode(e_rid.getTag(),
+ new ByteArrayInputStream(e_rid.getEncoded()));
+ }
+ GeneralizedTime producedAt = (GeneralizedTime) seq.elementAt(2);
+ SEQUENCE responses = (SEQUENCE) seq.elementAt(3);
+ SingleResponse sr[] = null;
+ if ((responses != null) && (responses.size() > 0)) {
+ sr = new SingleResponse[responses.size()];
+ for (int i = 0; i < responses.size(); i++) {
+ sr[i] = (SingleResponse) responses.elementAt(i);
+ }
+ }
+
+ //decode response extension sequence
+ EXPLICIT extns_exp = (EXPLICIT) seq.elementAt(4);
+ SEQUENCE extns_seq;
+ Extension[] extns_array = null;
+ if (extns_exp != null) {
+ extns_seq = (SEQUENCE) extns_exp.getContent();
+ extns_array = new Extension[extns_seq.size()];
+ for (int x = 0; x < extns_array.length; x++) {
+ extns_array[x] = (Extension) extns_seq.elementAt(x);
+ }
+ }
+
+ return new ResponseData(ver, rid, producedAt, sr, extns_array);
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/ocsp/RevokedInfo.java b/base/util/src/com/netscape/cmsutil/ocsp/RevokedInfo.java
new file mode 100644
index 000000000..9b0b2d186
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/ocsp/RevokedInfo.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.cmsutil.ocsp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.mozilla.jss.asn1.ASN1Template;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.EXPLICIT;
+import org.mozilla.jss.asn1.GeneralizedTime;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.Tag;
+
+/**
+ * RFC 2560:
+ *
+ * <pre>
+ * RevokedInfo ::= SEQUENCE {
+ * revocationTime GeneralizedTime,
+ * revocationReason [0] EXPLICIT CRLReason OPTIONAL }
+ * </pre>
+ *
+ * @version $Revision$ $Date$
+ */
+public class RevokedInfo implements CertStatus {
+ private static final Tag TAG = SEQUENCE.TAG;
+
+ private GeneralizedTime mRevokedAt;
+
+ public RevokedInfo(GeneralizedTime revokedAt) {
+ mRevokedAt = revokedAt;
+ }
+
+ public Tag getTag() {
+ return Tag.get(1);
+ }
+
+ public void encode(Tag t, OutputStream os) throws IOException {
+ SEQUENCE seq = new SEQUENCE();
+ seq.addElement(mRevokedAt);
+ seq.encode(t, os);
+ }
+
+ public void encode(OutputStream os) throws IOException {
+ encode(getTag(), os);
+ }
+
+ public GeneralizedTime getRevocationTime() {
+ return mRevokedAt;
+ }
+
+ private static final Template templateInstance = new Template();
+
+ public static Template getTemplate() {
+ return templateInstance;
+ }
+
+ /**
+ * A Template for decoding <code>ResponseBytes</code>.
+ */
+ public static class Template implements ASN1Template {
+
+ private SEQUENCE.Template seqt;
+
+ public Template() {
+ seqt = new SEQUENCE.Template();
+ seqt.addElement(new GeneralizedTime.Template());
+ seqt.addOptionalElement(
+ new EXPLICIT.Template(new Tag(0),
+ new INTEGER.Template()));
+
+ }
+
+ public boolean tagMatch(Tag tag) {
+ return TAG.equals(tag);
+ }
+
+ public ASN1Value decode(InputStream istream)
+ throws InvalidBERException, IOException {
+ return decode(TAG, istream);
+ }
+
+ public ASN1Value decode(Tag implicitTag, InputStream istream)
+ throws InvalidBERException, IOException {
+ SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,
+ istream);
+
+ GeneralizedTime revokedAt = (GeneralizedTime)
+ seq.elementAt(0);
+ return new RevokedInfo(revokedAt);
+
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/ocsp/Signature.java b/base/util/src/com/netscape/cmsutil/ocsp/Signature.java
new file mode 100644
index 000000000..b9b192aee
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/ocsp/Signature.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.cmsutil.ocsp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.mozilla.jss.asn1.ASN1Template;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.BIT_STRING;
+import org.mozilla.jss.asn1.EXPLICIT;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.Tag;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+
+/**
+ * RFC 2560:
+ *
+ * <pre>
+ * Signature ::= SEQUENCE {
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signature BIT STRING,
+ * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+ * </pre>
+ *
+ * @version $Revision$ $Date$
+ */
+
+public class Signature implements ASN1Value {
+ ///////////////////////////////////////////////////////////////////////
+ // Members and member access
+ ///////////////////////////////////////////////////////////////////////
+ private AlgorithmIdentifier signatureAlgorithm;
+ private BIT_STRING signature;
+ private SEQUENCE certs;
+ private SEQUENCE sequence;
+
+ public AlgorithmIdentifier getSignatureAlgorithm() {
+ return signatureAlgorithm;
+ }
+
+ public BIT_STRING getSignature() {
+ return signature;
+ }
+
+ public int getCertificateCount() {
+ if (certs == null) {
+ return 0;
+ } else {
+ return certs.size();
+ }
+ }
+
+ public Certificate getCertificateAt(int index) {
+ if (certs == null) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+ return (Certificate) certs.elementAt(index);
+ }
+
+ public Signature(AlgorithmIdentifier signatureAlgorithm,
+ BIT_STRING signature, SEQUENCE certs) {
+ sequence = new SEQUENCE();
+
+ this.signatureAlgorithm = signatureAlgorithm;
+ sequence.addElement(signatureAlgorithm);
+
+ this.signature = signature;
+ sequence.addElement(signature);
+
+ this.certs = certs;
+ sequence.addElement(certs);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ // encode / decode
+ ///////////////////////////////////////////////////////////////////////
+ private static final Tag TAG = SEQUENCE.TAG;
+
+ public Tag getTag() {
+ return TAG;
+ }
+
+ public void encode(OutputStream ostream) throws IOException {
+ encode(TAG, ostream);
+ }
+
+ public void encode(Tag implicitTag, OutputStream ostream)
+ throws IOException {
+ sequence.encode(implicitTag, ostream);
+ }
+
+ private static final Template templateInstance = new Template();
+
+ public static Template getTemplate() {
+ return templateInstance;
+ }
+
+ /**
+ * A Template for decoding Request.
+ */
+ public static class Template implements ASN1Template {
+
+ private SEQUENCE.Template seqt;
+
+ public Template() {
+ seqt = new SEQUENCE.Template();
+ seqt.addElement(AlgorithmIdentifier.getTemplate());
+ seqt.addElement(BIT_STRING.getTemplate());
+ seqt.addOptionalElement(
+ new EXPLICIT.Template(
+ new Tag(0),
+ new SEQUENCE.OF_Template(new Certificate.Template())
+ )
+ );
+ }
+
+ public boolean tagMatch(Tag tag) {
+ return TAG.equals(tag);
+ }
+
+ public ASN1Value decode(InputStream istream)
+ throws InvalidBERException, IOException {
+ return decode(TAG, istream);
+ }
+
+ public ASN1Value decode(Tag implicitTag, InputStream istream)
+ throws InvalidBERException, IOException {
+ SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream);
+ SEQUENCE certs = null;
+ if (seq.elementAt(2) != null) {
+ certs = (SEQUENCE) ((EXPLICIT) seq.elementAt(2)).getContent();
+ }
+
+ return new Signature(
+ (AlgorithmIdentifier) seq.elementAt(0),
+ (BIT_STRING) seq.elementAt(1),
+ certs);
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/ocsp/SingleResponse.java b/base/util/src/com/netscape/cmsutil/ocsp/SingleResponse.java
new file mode 100644
index 000000000..ab54e5019
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/ocsp/SingleResponse.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.cmsutil.ocsp;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.asn1.ASN1Template;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.EXPLICIT;
+import org.mozilla.jss.asn1.GeneralizedTime;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.Tag;
+import org.mozilla.jss.pkix.cert.Extension;
+
+/**
+ * RFC 2560:
+ *
+ * <pre>
+ * SingleResponse ::= SEQUENCE {
+ * certID CertID,
+ * certStatus CertStatus,
+ * thisUpdate GeneralizedTime,
+ * nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
+ * singleExtensions [1] EXPLICIT Extensions OPTIONAL }
+ * </pre>
+ *
+ * @version $Revision$ $Date$
+ */
+public class SingleResponse implements ASN1Value {
+ private CertID mCID = null;
+ private CertStatus mStatus = null;
+ private GeneralizedTime mThisUpdate = null;
+ private GeneralizedTime mNextUpdate = null;
+
+ private static final Tag TAG = SEQUENCE.TAG;
+
+ public SingleResponse(CertID cid, CertStatus s,
+ GeneralizedTime thisUpdate, GeneralizedTime nextUpdate) {
+ mCID = cid;
+ mStatus = s;
+ mThisUpdate = thisUpdate;
+ mNextUpdate = nextUpdate;
+ }
+
+ public CertID getCertID() {
+ return mCID;
+ }
+
+ public Tag getTag() {
+ return null;
+ }
+
+ public void encode(Tag t, OutputStream os) throws IOException {
+ SEQUENCE seq = new SEQUENCE();
+ seq.addElement(mCID);
+ seq.addElement(mStatus);
+ seq.addElement(mThisUpdate);
+ if (mNextUpdate != null) {
+ seq.addElement(new EXPLICIT(Tag.get(0), mNextUpdate));
+ }
+ if (t == null) {
+ seq.encode(os);
+ } else {
+ seq.encode(t, os);
+ }
+ }
+
+ public void encode(OutputStream os) throws IOException {
+ encode(null, os);
+ }
+
+ public CertStatus getCertStatus() {
+ return mStatus;
+ }
+
+ public GeneralizedTime getThisUpdate() {
+ return mThisUpdate;
+ }
+
+ public GeneralizedTime getNextUpdate() {
+ return mNextUpdate;
+ }
+
+ public int getExtensionCount() {
+ return 0;
+ }
+
+ public Extension getExtensionAt(int pos) {
+ return null;
+ }
+
+ private static final Template templateInstance = new Template();
+
+ public static Template getTemplate() {
+ return templateInstance;
+ }
+
+ /**
+ * A Template for decoding <code>ResponseBytes</code>.
+ */
+ public static class Template implements ASN1Template {
+
+ private SEQUENCE.Template seqt;
+
+ public Template() {
+ seqt = new SEQUENCE.Template();
+ seqt.addElement(new CertID.Template());
+ seqt.addElement(new ANY.Template());
+ seqt.addElement(new GeneralizedTime.Template());
+ seqt.addOptionalElement(new EXPLICIT.Template(
+ new Tag(0), new GeneralizedTime.Template()));
+ seqt.addOptionalElement(new EXPLICIT.Template(new Tag(1),
+ new SEQUENCE.OF_Template(new Extension.Template())));
+
+ }
+
+ public boolean tagMatch(Tag tag) {
+ return TAG.equals(tag);
+ }
+
+ public ASN1Value decode(InputStream istream)
+ throws InvalidBERException, IOException {
+ return decode(TAG, istream);
+ }
+
+ public ASN1Value decode(Tag implicitTag, InputStream istream)
+ throws InvalidBERException, IOException {
+ SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,
+ istream);
+
+ CertID cid = (CertID) seq.elementAt(0);
+ CertStatus status = null;
+ ANY e_status = (ANY) seq.elementAt(1);
+ if (e_status.getTag().getNum() == 0) {
+ status = (GoodInfo)
+ GoodInfo.getTemplate().decode(
+ e_status.getTag(),
+ new ByteArrayInputStream(e_status.getEncoded()));
+ // good
+ } else if (e_status.getTag().getNum() == 1) {
+ // revoked
+ status = (RevokedInfo)
+ RevokedInfo.getTemplate().decode(
+ e_status.getTag(),
+ new ByteArrayInputStream(e_status.getEncoded()));
+ } else if (e_status.getTag().getNum() == 2) {
+ // unknown
+ status = (UnknownInfo)
+ UnknownInfo.getTemplate().decode(
+ e_status.getTag(),
+ new ByteArrayInputStream(e_status.getEncoded()));
+ }
+ GeneralizedTime thisUpdate = (GeneralizedTime)
+ seq.elementAt(2);
+ GeneralizedTime nextUpdate = null;
+
+ return new SingleResponse(cid, status, thisUpdate,
+ nextUpdate);
+
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/ocsp/TBSRequest.java b/base/util/src/com/netscape/cmsutil/ocsp/TBSRequest.java
new file mode 100644
index 000000000..b7f706edb
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/ocsp/TBSRequest.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.cmsutil.ocsp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.asn1.ASN1Template;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.EXPLICIT;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.Tag;
+import org.mozilla.jss.pkix.cert.Extension;
+
+/**
+ * RFC 2560:
+ *
+ * <pre>
+ * TBSRequest ::= SEQUENCE {
+ * version [0] EXPLICIT Version DEFAULT v1,
+ * requestorName [1] EXPLICIT GeneralName OPTIONAL,
+ * requestList SEQUENCE OF Request,
+ * requestExtensions [2] EXPLICIT Extensions OPTIONAL }
+ * </pre>
+ *
+ * @version $Revision$ $Date$
+ */
+
+public class TBSRequest implements ASN1Value {
+ ///////////////////////////////////////////////////////////////////////
+ // members and member access
+ ///////////////////////////////////////////////////////////////////////
+ private static final INTEGER v1 = new INTEGER(0);
+ private INTEGER version;
+ private ANY requestorName;
+ private SEQUENCE requestList;
+ private SEQUENCE requestExtensions;
+
+ public INTEGER getVersion() {
+ return version;
+ }
+
+ public ANY getRequestorName() {
+ return requestorName;
+ }
+
+ public int getRequestCount() {
+ if (requestList == null) {
+ return 0;
+ } else {
+ return requestList.size();
+ }
+ }
+
+ public Request getRequestAt(int index) {
+ return (Request) requestList.elementAt(index);
+ }
+
+ public int getExtensionsCount() {
+ if (requestExtensions == null) {
+ return 0;
+ } else {
+ return requestExtensions.size();
+ }
+ }
+
+ public Extension getRequestExtensionAt(int index) {
+ return (Extension) requestExtensions.elementAt(index);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ // constructors
+ ///////////////////////////////////////////////////////////////////////
+
+ public TBSRequest(INTEGER version, ANY requestorName,
+ SEQUENCE requestList, SEQUENCE requestExtensions) {
+ this.version = (version != null) ? version : v1;
+ this.requestorName = requestorName;
+ this.requestList = requestList;
+ this.requestExtensions = requestExtensions;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ // encode / decode
+ ///////////////////////////////////////////////////////////////////////
+ public static final Tag TAG = SEQUENCE.TAG;
+
+ public Tag getTag() {
+ return TAG;
+ }
+
+ public void encode(OutputStream ostream)
+ throws IOException {
+ encode(TAG, ostream);
+ }
+
+ public void encode(Tag implicitTag, OutputStream ostream)
+ throws IOException {
+ SEQUENCE seq = new SEQUENCE();
+
+ if (version != v1) {
+ seq.addElement(new EXPLICIT(Tag.get(0), version));
+ }
+
+ if (requestorName != null) {
+ seq.addElement(new EXPLICIT(Tag.get(1), requestorName));
+ }
+
+ seq.addElement(requestList);
+
+ if (requestExtensions != null) {
+ seq.addElement(new EXPLICIT(Tag.get(2), requestExtensions));
+ }
+ if (implicitTag == null) {
+ seq.encode(ostream);
+ } else {
+ seq.encode(implicitTag, ostream);
+ }
+ }
+
+ private static final Template templateInstance = new Template();
+
+ public static Template getTemplate() {
+ return templateInstance;
+ }
+
+ /**
+ * A Template for decoding TBSRequest.
+ */
+ public static class Template implements ASN1Template {
+
+ private SEQUENCE.Template seqt;
+
+ public Template() {
+ seqt = new SEQUENCE.Template();
+ seqt.addElement(
+ new EXPLICIT.Template(
+ new Tag(0), new INTEGER.Template()),
+ new EXPLICIT(new Tag(0), new INTEGER(0))
+ );
+ seqt.addOptionalElement(
+ new EXPLICIT.Template(
+ new Tag(1), new ANY.Template()));
+ seqt.addElement(new SEQUENCE.OF_Template(new Request.Template()));
+ seqt.addOptionalElement(new EXPLICIT.Template(new Tag(2),
+ new SEQUENCE.OF_Template(new Extension.Template())));
+ }
+
+ public boolean tagMatch(Tag tag) {
+ return TAG.equals(tag);
+ }
+
+ public ASN1Value decode(InputStream istream)
+ throws InvalidBERException, IOException {
+ return decode(TAG, istream);
+ }
+
+ public ASN1Value decode(Tag implicitTag, InputStream istream)
+ throws InvalidBERException, IOException {
+ SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream);
+
+ INTEGER v = v1; //assume default version
+ EXPLICIT e_ver = (EXPLICIT) seq.elementAt(0);
+ if (e_ver != null) {
+ v = (INTEGER) e_ver.getContent();
+ }
+
+ ANY requestorname = null;
+ EXPLICIT e_requestorName = (EXPLICIT) seq.elementAt(1);
+ if (e_requestorName != null) {
+ requestorname = (ANY) e_requestorName.getContent();
+ }
+
+ //request sequence (element 2) done below
+
+ EXPLICIT exts = (EXPLICIT) seq.elementAt(3);
+ SEQUENCE exts_seq;
+ if (exts != null) {
+ exts_seq = (SEQUENCE) exts.getContent();
+ } else {
+ exts_seq = null;
+ }
+
+ return new TBSRequest(
+ v,
+ requestorname,
+ (SEQUENCE) seq.elementAt(2),
+ exts_seq);
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/ocsp/UnknownInfo.java b/base/util/src/com/netscape/cmsutil/ocsp/UnknownInfo.java
new file mode 100644
index 000000000..1fe4ea743
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/ocsp/UnknownInfo.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.cmsutil.ocsp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.mozilla.jss.asn1.ASN1Template;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.NULL;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.Tag;
+
+/**
+ * RFC 2560:
+ *
+ * <pre>
+ * UnknownInfo ::= NULL -- this can be replaced with an enumeration
+ * </pre>
+ *
+ * @version $Revision$ $Date$
+ */
+public class UnknownInfo implements CertStatus {
+ private static final Tag TAG = SEQUENCE.TAG;
+
+ public UnknownInfo() {
+ }
+
+ public Tag getTag() {
+ return Tag.get(2);
+ }
+
+ public void encode(Tag t, OutputStream os) throws IOException {
+ NULL.getInstance().encode(getTag(), os);
+ }
+
+ public void encode(OutputStream os) throws IOException {
+ encode(getTag(), os);
+ }
+
+ private static final Template templateInstance = new Template();
+
+ public static Template getTemplate() {
+ return templateInstance;
+ }
+
+ /**
+ * A Template for decoding <code>ResponseBytes</code>.
+ */
+ public static class Template implements ASN1Template {
+
+ private SEQUENCE.Template seqt;
+
+ public Template() {
+ // seqt = new SEQUENCE.Template();
+ // seqt.addElement(new NULL.Template() );
+
+ }
+
+ public boolean tagMatch(Tag tag) {
+ return TAG.equals(tag);
+ }
+
+ public ASN1Value decode(InputStream istream)
+ throws InvalidBERException, IOException {
+ return decode(TAG, istream);
+ }
+
+ public ASN1Value decode(Tag implicitTag, InputStream istream)
+ throws InvalidBERException, IOException {
+ // SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,
+ // istream);
+
+ return new UnknownInfo();
+
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/password/IPasswordReader.java b/base/util/src/com/netscape/cmsutil/password/IPasswordReader.java
new file mode 100644
index 000000000..759e9e777
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/password/IPasswordReader.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.cmsutil.password;
+
+import java.io.IOException;
+import java.util.Enumeration;
+
+public interface IPasswordReader {
+ public void init(String pwdPath) throws IOException;
+
+ public String getPassword(String tag);
+
+ public Enumeration<String> getTags();
+}
diff --git a/base/util/src/com/netscape/cmsutil/password/IPasswordStore.java b/base/util/src/com/netscape/cmsutil/password/IPasswordStore.java
new file mode 100644
index 000000000..49b2610fa
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/password/IPasswordStore.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.cmsutil.password;
+
+import java.io.IOException;
+import java.util.Enumeration;
+
+public interface IPasswordStore {
+ public void init(String pwdPath) throws IOException;
+
+ public String getPassword(String tag);
+
+ public Enumeration<String> getTags();
+
+ public Object putPassword(String tag, String password);
+
+ public void commit()
+ throws IOException, ClassCastException, NullPointerException;
+}
diff --git a/base/util/src/com/netscape/cmsutil/password/IPasswordWriter.java b/base/util/src/com/netscape/cmsutil/password/IPasswordWriter.java
new file mode 100644
index 000000000..c9f9691e7
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/password/IPasswordWriter.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.cmsutil.password;
+
+import java.io.IOException;
+
+public interface IPasswordWriter {
+ public void init(String pwdPath)
+ throws IOException;;
+
+ public Object putPassword(String tag, String password);
+
+ public void commit()
+ throws IOException, ClassCastException, NullPointerException;
+}
diff --git a/base/util/src/com/netscape/cmsutil/password/PlainPasswordFile.java b/base/util/src/com/netscape/cmsutil/password/PlainPasswordFile.java
new file mode 100644
index 000000000..eb43607f0
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/password/PlainPasswordFile.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.cmsutil.password;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.Vector;
+
+public class PlainPasswordFile implements IPasswordStore {
+ private String mPwdPath = "";
+ private Properties mPwdStore;
+ private static final String PASSWORD_WRITER_HEADER = "";
+
+ public PlainPasswordFile() {
+ }
+
+ public void init(String pwdPath)
+ throws IOException {
+ mPwdStore = new Properties();
+ // initialize mPwdStore
+ mPwdPath = pwdPath;
+
+ FileInputStream file = new FileInputStream(mPwdPath);
+ mPwdStore.load(file);
+ file.close();
+ }
+
+ public String getPassword(String tag) {
+ return (String) mPwdStore.getProperty(tag);
+ }
+
+ // return an array of String-based tag
+ public Enumeration<String> getTags() {
+ Enumeration<?> e = mPwdStore.propertyNames();
+ Vector<String> v = new Vector<String>();
+ while (e.hasMoreElements()) {
+ v.add((String) e.nextElement());
+ }
+ return v.elements();
+ }
+
+ public Object putPassword(String tag, String password) {
+ return mPwdStore.setProperty(tag, password);
+ }
+
+ public void commit()
+ throws IOException, ClassCastException, NullPointerException {
+ FileOutputStream file = new FileOutputStream(mPwdPath);
+ mPwdStore.store(file, PASSWORD_WRITER_HEADER);
+ file.close();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/password/PlainPasswordReader.java b/base/util/src/com/netscape/cmsutil/password/PlainPasswordReader.java
new file mode 100644
index 000000000..68724a9f6
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/password/PlainPasswordReader.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.cmsutil.password;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.Vector;
+
+public class PlainPasswordReader implements IPasswordReader {
+ private String mPwdPath = "";
+ private Properties mPwdStore;
+
+ public PlainPasswordReader() {
+ }
+
+ public void init(String pwdPath)
+ throws IOException {
+ mPwdStore = new Properties();
+ // initialize mPwdStore
+ mPwdPath = pwdPath;
+ mPwdStore = new Properties();
+
+ FileInputStream file = new FileInputStream(mPwdPath);
+ mPwdStore.load(file);
+ file.close();
+ }
+
+ public String getPassword(String tag) {
+ return (String) mPwdStore.getProperty(tag);
+ }
+
+ // return an array of String-based tag
+ public Enumeration<String> getTags() {
+ Enumeration<?> e = mPwdStore.propertyNames();
+ Vector<String> v = new Vector<String>();
+ while (e.hasMoreElements()) {
+ v.add((String) e.nextElement());
+ }
+ return v.elements();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/password/PlainPasswordWriter.java b/base/util/src/com/netscape/cmsutil/password/PlainPasswordWriter.java
new file mode 100644
index 000000000..3ceac4bd6
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/password/PlainPasswordWriter.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.cmsutil.password;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+public class PlainPasswordWriter implements IPasswordWriter {
+ private static final String PASSWORD_WRITER_HEADER = "";
+ private String mPwdPath = "";
+ private Properties mPwdStore;
+
+ public PlainPasswordWriter() {
+ }
+
+ public void init(String pwdPath)
+ throws IOException {
+ mPwdStore = new Properties();
+ // initialize mPwdStore
+ mPwdPath = pwdPath;
+ mPwdStore = new Properties();
+
+ FileInputStream file = new FileInputStream(mPwdPath);
+ mPwdStore.load(file);
+ file.close();
+ }
+
+ public Object putPassword(String tag, String password) {
+ return mPwdStore.setProperty(tag, password);
+ }
+
+ public void commit()
+ throws IOException, ClassCastException, NullPointerException {
+ FileOutputStream file = new FileOutputStream(mPwdPath);
+ mPwdStore.store(file, PASSWORD_WRITER_HEADER);
+ file.close();
+ }
+
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/AccessAccept.java b/base/util/src/com/netscape/cmsutil/radius/AccessAccept.java
new file mode 100644
index 000000000..4824c885f
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/AccessAccept.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class AccessAccept extends ServerPacket {
+ public AccessAccept(byte data[]) throws IOException {
+ super(data);
+ }
+
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/AccessChallenge.java b/base/util/src/com/netscape/cmsutil/radius/AccessChallenge.java
new file mode 100644
index 000000000..c06f809b1
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/AccessChallenge.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class AccessChallenge extends ServerPacket {
+ public AccessChallenge(byte data[]) throws IOException {
+ super(data);
+ }
+
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/AccessReject.java b/base/util/src/com/netscape/cmsutil/radius/AccessReject.java
new file mode 100644
index 000000000..5f32ef349
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/AccessReject.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class AccessReject extends ServerPacket {
+ public AccessReject(byte data[]) throws IOException {
+ super(data);
+ }
+
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/AccessRequest.java b/base/util/src/com/netscape/cmsutil/radius/AccessRequest.java
new file mode 100644
index 000000000..7856b0cc8
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/AccessRequest.java
@@ -0,0 +1,25 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmsutil.radius;
+
+public class AccessRequest extends NASPacket {
+ public AccessRequest(short id, Authenticator auth) {
+ super(ACCESS_REQUEST, id, auth);
+ }
+
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/Attribute.java b/base/util/src/com/netscape/cmsutil/radius/Attribute.java
new file mode 100644
index 000000000..5e79816e4
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/Attribute.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.cmsutil.radius;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+public abstract class Attribute {
+ public static final int USER_NAME = 1;
+ public static final int USER_PASSWORD = 2;
+ public static final int CHAP_PASSWORD = 3;
+ public static final int NAS_IP_ADDRESS = 4;
+ public static final int NAS_PORT = 5;
+ public static final int SERVICE_TYPE = 6;
+ public static final int FRAMED_PROTOCOL = 7;
+ public static final int FRAMED_IP_ADDRESS = 8;
+ public static final int FRAMED_IP_NETMASK = 9;
+ public static final int FRAMED_ROUTING = 10;
+ public static final int FILTER_ID = 11;
+ public static final int FRAMED_MTU = 12;
+ public static final int FRAMED_COMPRESSION = 13;
+ public static final int LOGIN_IP_HOST = 14;
+ public static final int LOGIN_SERVICE = 15;
+ public static final int LOGIN_TCP_PORT = 16;
+ // 17 HAS NOT BEEN ASSIGNED
+ public static final int REPLY_MESSAGE = 18;
+ public static final int CALLBACK_NUMBER = 19;
+ public static final int CALLBACK_ID = 20;
+ // 21 HAS NOT BEEN ASSIGNED
+ public static final int FRAMED_ROUTE = 22;
+ public static final int FRAMED_IPX_NETWORK = 23;
+ public static final int STATE = 24;
+ public static final int NAS_CLASS = 25;
+ public static final int VENDOR_SPECIFIC = 26;
+ public static final int SESSION_TIMEOUT = 27;
+ public static final int IDLE_TIMEOUT = 28;
+ public static final int TERMINATION_ACTION = 29;
+ public static final int CALLER_STATION_ID = 30;
+ public static final int CALLING_STATION_ID = 31;
+ public static final int NAS_IDENTIFIER = 32;
+ public static final int PROXY_STATE = 33;
+ public static final int LOGIN_LAT_SERVICE = 34;
+ public static final int LOGIN_LAT_NODE = 35;
+ public static final int LOGIN_LAT_GROUP = 36;
+ public static final int FRAMED_APPLETALK_LINK = 37;
+ public static final int FRAMED_APPLETALK_NETWORK = 38;
+ public static final int FRAMED_APPLETALK_ZONE = 39;
+ // 40-59 HAS NOT BEEN ASSIGNED
+ public static final int CHAP_CHALLENGE = 60;
+ public static final int NAS_PORT_TYPE = 61;
+ public static final int PORT_LIMIT = 62;
+ public static final int LOGIN_LAT_PORT = 63;
+
+ protected int _t = 0;
+
+ public Attribute() {
+ }
+
+ public Attribute(int t) {
+ _t = t;
+ }
+
+ public int getType() {
+ return _t;
+ }
+
+ public abstract byte[] getValue()
+ throws IOException;
+
+ public byte[] getData()
+ throws IOException {
+ ByteArrayOutputStream attrOS = new ByteArrayOutputStream();
+
+ attrOS.write(_t); // type
+ byte value[] = getValue();
+
+ attrOS.write(value.length + 2); // length
+ attrOS.write(value);
+
+ return attrOS.toByteArray();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/AttributeFactory.java b/base/util/src/com/netscape/cmsutil/radius/AttributeFactory.java
new file mode 100644
index 000000000..021c06720
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/AttributeFactory.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class AttributeFactory {
+ public static Attribute createAttribute(byte data[])
+ throws IOException {
+ switch (data[0] & 0xFF) {
+ case Attribute.USER_NAME: // 1
+ return new UserNameAttribute(data);
+
+ case Attribute.USER_PASSWORD: // 2
+ return new UserPasswordAttribute(data);
+
+ case Attribute.NAS_IP_ADDRESS: // 4
+ return new NASIPAddressAttribute(data);
+
+ case Attribute.NAS_PORT: // 5
+ return new NASPortAttribute(data);
+
+ case Attribute.CHAP_PASSWORD: // 3
+ return new CHAPPasswordAttribute(data);
+
+ case Attribute.SERVICE_TYPE: // 6
+ return new ServiceTypeAttribute(data);
+
+ case Attribute.FRAMED_PROTOCOL: // 7
+ return new FramedProtocolAttribute(data);
+
+ case Attribute.FRAMED_IP_ADDRESS: // 8
+ return new FramedIPAddressAttribute(data);
+
+ case Attribute.FRAMED_IP_NETMASK: // 9
+ return new FramedIPNetmaskAttribute(data);
+
+ case Attribute.FRAMED_ROUTING: // 10
+ return new FramedRoutingAttribute(data);
+
+ case Attribute.FILTER_ID: // 11
+ return new FilterIdAttribute(data);
+
+ case Attribute.FRAMED_MTU: // 12
+ return new FramedMTUAttribute(data);
+
+ case Attribute.FRAMED_COMPRESSION: // 13
+ return new FramedCompressionAttribute(data);
+
+ case Attribute.LOGIN_IP_HOST: // 14
+ return new LoginIPHostAttribute(data);
+
+ case Attribute.LOGIN_SERVICE: // 15
+ return new LoginServiceAttribute(data);
+
+ case Attribute.LOGIN_TCP_PORT: // 16
+ return new LoginTCPPortAttribute(data);
+
+ case Attribute.REPLY_MESSAGE: // 18
+ return new ReplyMessageAttribute(data);
+
+ case Attribute.CALLBACK_NUMBER: // 19
+ return new CallbackNumberAttribute(data);
+
+ case Attribute.CALLBACK_ID: // 20
+ return new CallbackIdAttribute(data);
+
+ case Attribute.FRAMED_ROUTE: // 22
+ return new FramedRouteAttribute(data);
+
+ case Attribute.FRAMED_IPX_NETWORK: // 23
+ return new FramedIPXNetworkAttribute(data);
+
+ case Attribute.STATE: // 24
+ return new StateAttribute(data);
+
+ case Attribute.NAS_CLASS: // 25
+ return new NASClassAttribute(data);
+
+ case Attribute.VENDOR_SPECIFIC: // 26
+ return new VendorSpecificAttribute(data);
+
+ case Attribute.SESSION_TIMEOUT: // 27
+ return new SessionTimeoutAttribute(data);
+
+ case Attribute.IDLE_TIMEOUT: // 28
+ return new IdleTimeoutAttribute(data);
+
+ case Attribute.TERMINATION_ACTION: // 29
+ return new TerminationActionAttribute(data);
+
+ case Attribute.CALLER_STATION_ID: // 30
+ return new CallerStationIdAttribute(data);
+
+ case Attribute.CALLING_STATION_ID: // 31
+ return new CallingStationIdAttribute(data);
+
+ case Attribute.NAS_IDENTIFIER: // 32
+ return new NASIdentifierAttribute(data);
+
+ case Attribute.PROXY_STATE: // 33
+ return new ProxyStateAttribute(data);
+
+ case Attribute.LOGIN_LAT_SERVICE: // 34
+ return new LoginLATServiceAttribute(data);
+
+ case Attribute.LOGIN_LAT_NODE: // 35
+ return new LoginLATNodeAttribute(data);
+
+ case Attribute.LOGIN_LAT_GROUP: // 36
+ return new LoginLATGroupAttribute(data);
+
+ case Attribute.FRAMED_APPLETALK_LINK: // 37
+ return new FramedAppleTalkLinkAttribute(data);
+
+ case Attribute.FRAMED_APPLETALK_NETWORK: // 38
+ return new FramedAppleTalkNetworkAttribute(data);
+
+ case Attribute.FRAMED_APPLETALK_ZONE: // 39
+ return new FramedAppleTalkZoneAttribute(data);
+
+ case Attribute.CHAP_CHALLENGE: // 60
+ return new CHAPChallengeAttribute(data);
+
+ case Attribute.NAS_PORT_TYPE: // 61
+ return new NASPortTypeAttribute(data);
+
+ case Attribute.PORT_LIMIT: // 62
+ return new PortLimitAttribute(data);
+
+ case Attribute.LOGIN_LAT_PORT: // 63
+ return new LoginLATPortAttribute(data);
+
+ default:
+ return new GenericAttribute(data);
+ // throw new IOException("Unknown attribute " + (data[0] & 0xFF));
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/AttributeSet.java b/base/util/src/com/netscape/cmsutil/radius/AttributeSet.java
new file mode 100644
index 000000000..d6974d371
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/AttributeSet.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.cmsutil.radius;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+public class AttributeSet {
+ private Vector<Attribute> _attrs = new Vector<Attribute>();
+
+ public AttributeSet() {
+ }
+
+ public void addAttribute(Attribute attr) {
+ _attrs.addElement(attr);
+ }
+
+ public int size() {
+ return _attrs.size();
+ }
+
+ public Enumeration<Attribute> getAttributes() {
+ return _attrs.elements();
+ }
+
+ public Attribute getAttributeByType(int type) {
+ int l = _attrs.size();
+
+ for (int i = 0; i < l; i++) {
+ Attribute attr = getAttributeAt(i);
+
+ if (attr.getType() == type)
+ return attr;
+ }
+ return null;
+ }
+
+ public Attribute getAttributeAt(int pos) {
+ return _attrs.elementAt(pos);
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/Authenticator.java b/base/util/src/com/netscape/cmsutil/radius/Authenticator.java
new file mode 100644
index 000000000..008af489a
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/Authenticator.java
@@ -0,0 +1,24 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmsutil.radius;
+
+import java.io.IOException;
+
+public abstract class Authenticator {
+ public abstract byte[] getData() throws IOException;
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/CHAPChallengeAttribute.java b/base/util/src/com/netscape/cmsutil/radius/CHAPChallengeAttribute.java
new file mode 100644
index 000000000..cd715a031
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/CHAPChallengeAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class CHAPChallengeAttribute extends Attribute {
+ private String _str = null;
+
+ public CHAPChallengeAttribute(byte value[]) {
+ super();
+ _t = CHAP_CHALLENGE;
+ _str = new String(value, 2, value.length - 2);
+ }
+
+ public String getString() {
+ return _str;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _str.getBytes();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/CHAPPasswordAttribute.java b/base/util/src/com/netscape/cmsutil/radius/CHAPPasswordAttribute.java
new file mode 100644
index 000000000..3f0ef1793
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/CHAPPasswordAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class CHAPPasswordAttribute extends Attribute {
+ private byte _value[] = null;
+ private int _ident = 0;
+ private String _str = null;
+
+ public CHAPPasswordAttribute(String s) {
+ _str = s;
+ }
+
+ public CHAPPasswordAttribute(byte value[]) {
+ super();
+ _t = CHAP_PASSWORD;
+ _ident = value[2];
+ _str = new String(value, 2, 16);
+ _value = value;
+ }
+
+ public int getIdent() {
+ return _ident;
+ }
+
+ public String getString() {
+ return _str;
+ }
+
+ public byte[] getValue() throws IOException {
+ byte val[] = new byte[1 + _str.length()];
+ byte s[] = _str.getBytes();
+
+ val[0] = (byte) _ident;
+ System.arraycopy(s, 0, val, 1, s.length);
+ return val;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/CallbackIdAttribute.java b/base/util/src/com/netscape/cmsutil/radius/CallbackIdAttribute.java
new file mode 100644
index 000000000..5fd806003
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/CallbackIdAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class CallbackIdAttribute extends Attribute {
+ private byte _value[] = null;
+ private String _str = null;
+
+ public CallbackIdAttribute(byte value[]) {
+ super();
+ _t = CALLBACK_ID;
+ _str = new String(value, 2, value.length - 2);
+ _value = value;
+ }
+
+ public String getString() {
+ return _str;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _str.getBytes();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/CallbackNumberAttribute.java b/base/util/src/com/netscape/cmsutil/radius/CallbackNumberAttribute.java
new file mode 100644
index 000000000..d6e45cecd
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/CallbackNumberAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class CallbackNumberAttribute extends Attribute {
+ private byte _value[] = null;
+ private String _str = null;
+
+ public CallbackNumberAttribute(byte value[]) {
+ super();
+ _t = CALLBACK_NUMBER;
+ _str = new String(value, 2, value.length - 2);
+ _value = value;
+ }
+
+ public String getString() {
+ return _str;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _str.getBytes();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/CallerStationIdAttribute.java b/base/util/src/com/netscape/cmsutil/radius/CallerStationIdAttribute.java
new file mode 100644
index 000000000..3b5eec804
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/CallerStationIdAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class CallerStationIdAttribute extends Attribute {
+ private byte _value[] = null;
+ private String _str = null;
+
+ public CallerStationIdAttribute(byte value[]) {
+ super();
+ _t = CALLER_STATION_ID;
+ _str = new String(value, 2, value.length - 2);
+ _value = value;
+ }
+
+ public String getString() {
+ return _str;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _str.getBytes();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/CallingStationIdAttribute.java b/base/util/src/com/netscape/cmsutil/radius/CallingStationIdAttribute.java
new file mode 100644
index 000000000..9a57f8089
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/CallingStationIdAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class CallingStationIdAttribute extends Attribute {
+ private byte _value[] = null;
+ private String _str = null;
+
+ public CallingStationIdAttribute(byte value[]) {
+ super();
+ _t = CALLING_STATION_ID;
+ _str = new String(value, 2, value.length - 2);
+ _value = value;
+ }
+
+ public String getString() {
+ return _str;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _str.getBytes();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/ChallengeException.java b/base/util/src/com/netscape/cmsutil/radius/ChallengeException.java
new file mode 100644
index 000000000..972f7f084
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/ChallengeException.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.cmsutil.radius;
+
+public class ChallengeException extends Exception {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3496050461777520369L;
+ private AccessChallenge _res = null;
+
+ public ChallengeException(AccessChallenge res) {
+ _res = res;
+ }
+
+ public AttributeSet getAttributeSet() {
+ return _res.getAttributeSet();
+ }
+
+ public String getState() {
+ return ((StateAttribute) (_res.getAttributeSet().getAttributeByType(Attribute.STATE))).getString();
+ }
+
+ public String getReplyMessage() {
+ return ((ReplyMessageAttribute) (_res.getAttributeSet().getAttributeByType(Attribute.REPLY_MESSAGE)))
+ .getString();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/FilterIdAttribute.java b/base/util/src/com/netscape/cmsutil/radius/FilterIdAttribute.java
new file mode 100644
index 000000000..879d7d5c7
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/FilterIdAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class FilterIdAttribute extends Attribute {
+ private byte _value[] = null;
+ private String _str = null;
+
+ public FilterIdAttribute(byte value[]) {
+ super();
+ _t = CHAP_PASSWORD;
+ _str = new String(value, 2, value.length - 2);
+ _value = value;
+ }
+
+ public String getString() {
+ return _str;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _str.getBytes();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/FramedAppleTalkLinkAttribute.java b/base/util/src/com/netscape/cmsutil/radius/FramedAppleTalkLinkAttribute.java
new file mode 100644
index 000000000..05273780f
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/FramedAppleTalkLinkAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class FramedAppleTalkLinkAttribute extends Attribute {
+ public static int UN_NUMBERED = 0;
+
+ private byte _value[] = null;
+ private int _type = 0;
+
+ public FramedAppleTalkLinkAttribute(byte value[]) {
+ super();
+ _t = FRAMED_APPLETALK_LINK;
+ _value = value;
+ _type = value[5] & 0xFF;
+ _type |= ((value[4] << 8) & 0xFF00);
+ _type |= ((value[3] << 16) & 0xFF0000);
+ _type |= ((value[2] << 24) & 0xFF000000);
+ }
+
+ public int getType() {
+ return _type;
+ }
+
+ public byte[] getValue() throws IOException {
+ byte[] p = new byte[4];
+
+ p[0] = (byte) ((_type >>> 24) & 0xFF);
+ p[1] = (byte) ((_type >>> 16) & 0xFF);
+ p[2] = (byte) ((_type >>> 8) & 0xFF);
+ p[3] = (byte) (_type & 0xFF);
+ return p;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/FramedAppleTalkNetworkAttribute.java b/base/util/src/com/netscape/cmsutil/radius/FramedAppleTalkNetworkAttribute.java
new file mode 100644
index 000000000..cea0d936a
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/FramedAppleTalkNetworkAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class FramedAppleTalkNetworkAttribute extends Attribute {
+ private byte _value[] = null;
+ private int _type = 0;
+
+ public FramedAppleTalkNetworkAttribute(byte value[]) {
+ super();
+ _t = FRAMED_APPLETALK_NETWORK;
+ _value = value;
+ _type = value[5] & 0xFF;
+ _type |= ((value[4] << 8) & 0xFF00);
+ _type |= ((value[3] << 16) & 0xFF0000);
+ _type |= ((value[2] << 24) & 0xFF000000);
+ }
+
+ public int getType() {
+ return _type;
+ }
+
+ public byte[] getValue() throws IOException {
+ byte[] p = new byte[4];
+
+ p[0] = (byte) ((_type >>> 24) & 0xFF);
+ p[1] = (byte) ((_type >>> 16) & 0xFF);
+ p[2] = (byte) ((_type >>> 8) & 0xFF);
+ p[3] = (byte) (_type & 0xFF);
+ return p;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/FramedAppleTalkZoneAttribute.java b/base/util/src/com/netscape/cmsutil/radius/FramedAppleTalkZoneAttribute.java
new file mode 100644
index 000000000..54ee47c45
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/FramedAppleTalkZoneAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class FramedAppleTalkZoneAttribute extends Attribute {
+ private byte _value[] = null;
+ private String _str = null;
+
+ public FramedAppleTalkZoneAttribute(byte value[]) {
+ super();
+ _t = FRAMED_APPLETALK_ZONE;
+ _str = new String(value, 2, value.length - 2);
+ _value = value;
+ }
+
+ public String getString() {
+ return _str;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _str.getBytes();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/FramedCompressionAttribute.java b/base/util/src/com/netscape/cmsutil/radius/FramedCompressionAttribute.java
new file mode 100644
index 000000000..b57c030b5
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/FramedCompressionAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class FramedCompressionAttribute extends Attribute {
+ public static final int NONE = 1;
+ public static final int VJ_TCP_IP_HEADER = 2;
+ public static final int IPX_HEADER = 2;
+ public static final int STAC_LZS = 3;
+
+ private byte _value[] = null;
+ private int _type = 0;
+
+ public FramedCompressionAttribute(byte value[]) {
+ super();
+ _t = FRAMED_COMPRESSION;
+ _type = value[5] & 0xFF;
+ _type |= ((value[4] << 8) & 0xFF00);
+ _type |= ((value[3] << 16) & 0xFF0000);
+ _type |= ((value[2] << 24) & 0xFF000000);
+ _value = value;
+ }
+
+ public int getType() {
+ return _type;
+ }
+
+ public byte[] getValue() throws IOException {
+ byte[] p = new byte[4];
+
+ p[0] = (byte) ((_type >>> 24) & 0xFF);
+ p[1] = (byte) ((_type >>> 16) & 0xFF);
+ p[2] = (byte) ((_type >>> 8) & 0xFF);
+ p[3] = (byte) (_type & 0xFF);
+ return p;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/FramedIPAddressAttribute.java b/base/util/src/com/netscape/cmsutil/radius/FramedIPAddressAttribute.java
new file mode 100644
index 000000000..2f66ee8c2
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/FramedIPAddressAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class FramedIPAddressAttribute extends Attribute {
+ private byte _value[] = null;
+ private byte _addr[] = new byte[4];
+
+ public FramedIPAddressAttribute(byte value[]) {
+ super();
+ _t = FRAMED_IP_ADDRESS;
+ _addr[0] = value[2];
+ _addr[1] = value[3];
+ _addr[2] = value[4];
+ _addr[3] = value[5];
+ _value = value;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _addr;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/FramedIPNetmaskAttribute.java b/base/util/src/com/netscape/cmsutil/radius/FramedIPNetmaskAttribute.java
new file mode 100644
index 000000000..f8e1980c7
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/FramedIPNetmaskAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class FramedIPNetmaskAttribute extends Attribute {
+ private byte _value[] = null;
+ private byte _mask[] = new byte[4];
+
+ public FramedIPNetmaskAttribute(byte value[]) {
+ super();
+ _t = FRAMED_IP_NETMASK;
+ _mask[0] = value[2];
+ _mask[1] = value[3];
+ _mask[2] = value[4];
+ _mask[3] = value[5];
+ _value = value;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _mask;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/FramedIPXNetworkAttribute.java b/base/util/src/com/netscape/cmsutil/radius/FramedIPXNetworkAttribute.java
new file mode 100644
index 000000000..92f47eec1
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/FramedIPXNetworkAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class FramedIPXNetworkAttribute extends Attribute {
+ private byte _value[] = null;
+ private byte _net[] = new byte[4];
+
+ public FramedIPXNetworkAttribute(byte value[]) {
+ super();
+ _t = FRAMED_IPX_NETWORK;
+ _net[0] = value[2];
+ _net[1] = value[3];
+ _net[2] = value[4];
+ _net[3] = value[5];
+ _value = value;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _net;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/FramedMTUAttribute.java b/base/util/src/com/netscape/cmsutil/radius/FramedMTUAttribute.java
new file mode 100644
index 000000000..5cd9551a2
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/FramedMTUAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class FramedMTUAttribute extends Attribute {
+ private byte _value[] = null;
+ private int _type = 0;
+
+ public FramedMTUAttribute(byte value[]) {
+ super();
+ _t = FRAMED_IP_ADDRESS;
+ _value = value;
+ _type = value[5] & 0xFF;
+ _type |= ((value[4] << 8) & 0xFF00);
+ _type |= ((value[3] << 16) & 0xFF0000);
+ _type |= ((value[2] << 24) & 0xFF000000);
+ }
+
+ public int getType() {
+ return _type;
+ }
+
+ public byte[] getValue() throws IOException {
+ byte[] p = new byte[4];
+
+ p[0] = (byte) ((_type >>> 24) & 0xFF);
+ p[1] = (byte) ((_type >>> 16) & 0xFF);
+ p[2] = (byte) ((_type >>> 8) & 0xFF);
+ p[3] = (byte) (_type & 0xFF);
+ return p;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/FramedProtocolAttribute.java b/base/util/src/com/netscape/cmsutil/radius/FramedProtocolAttribute.java
new file mode 100644
index 000000000..5af219b9a
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/FramedProtocolAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class FramedProtocolAttribute extends Attribute {
+ public static final int PPP = 1;
+ public static final int SLIP = 2;
+ public static final int ARAP = 3;
+ public static final int GANDALF = 4;
+ public static final int XYLOGICS = 5;
+ public static final int X_75 = 6;
+
+ private byte _value[] = null;
+ private int _type = 0;
+
+ public FramedProtocolAttribute(byte value[]) {
+ super();
+ _t = SERVICE_TYPE;
+ _type = value[5] & 0xFF;
+ _type |= ((value[4] << 8) & 0xFF00);
+ _type |= ((value[3] << 16) & 0xFF0000);
+ _type |= ((value[2] << 24) & 0xFF000000);
+ _value = value;
+ }
+
+ public int getType() {
+ return _type;
+ }
+
+ public byte[] getValue() throws IOException {
+ byte[] p = new byte[4];
+
+ p[0] = (byte) ((_type >>> 24) & 0xFF);
+ p[1] = (byte) ((_type >>> 16) & 0xFF);
+ p[2] = (byte) ((_type >>> 8) & 0xFF);
+ p[3] = (byte) (_type & 0xFF);
+ return p;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/FramedRouteAttribute.java b/base/util/src/com/netscape/cmsutil/radius/FramedRouteAttribute.java
new file mode 100644
index 000000000..9b123fe2a
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/FramedRouteAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class FramedRouteAttribute extends Attribute {
+ private byte _value[] = null;
+ private String _str = null;
+
+ public FramedRouteAttribute(byte value[]) {
+ super();
+ _t = FRAMED_ROUTE;
+ _str = new String(value, 2, value.length - 2);
+ _value = value;
+ }
+
+ public String getString() {
+ return _str;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _str.getBytes();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/FramedRoutingAttribute.java b/base/util/src/com/netscape/cmsutil/radius/FramedRoutingAttribute.java
new file mode 100644
index 000000000..14d2b0cc8
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/FramedRoutingAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class FramedRoutingAttribute extends Attribute {
+ public static final int NONE = 0;
+ public static final int SEND_ROUTING_PACKETS = 1;
+ public static final int LISTEN_FOR_ROUTING_PACKETS = 2;
+ public static final int SEND_AND_LISTEN = 3;
+
+ private byte _value[] = null;
+ private int _type = 0;
+
+ public FramedRoutingAttribute(byte value[]) {
+ super();
+ _t = FRAMED_ROUTING;
+ _type = value[5] & 0xFF;
+ _type |= ((value[4] << 8) & 0xFF00);
+ _type |= ((value[3] << 16) & 0xFF0000);
+ _type |= ((value[2] << 24) & 0xFF000000);
+ _value = value;
+ }
+
+ public int getType() {
+ return _type;
+ }
+
+ public byte[] getValue() throws IOException {
+ byte[] p = new byte[4];
+
+ p[0] = (byte) ((_type >>> 24) & 0xFF);
+ p[1] = (byte) ((_type >>> 16) & 0xFF);
+ p[2] = (byte) ((_type >>> 8) & 0xFF);
+ p[3] = (byte) (_type & 0xFF);
+ return p;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/GenericAttribute.java b/base/util/src/com/netscape/cmsutil/radius/GenericAttribute.java
new file mode 100644
index 000000000..ac1798ae3
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/GenericAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class GenericAttribute extends Attribute {
+ private byte _value[] = null;
+
+ public GenericAttribute(byte value[]) {
+ super();
+ _t = value[0];
+ _value = new byte[value.length - 2];
+ System.arraycopy(value, 2, _value, 0, _value.length);
+ }
+
+ public byte[] getValue() throws IOException {
+ return _value;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/IdleTimeoutAttribute.java b/base/util/src/com/netscape/cmsutil/radius/IdleTimeoutAttribute.java
new file mode 100644
index 000000000..44b0c5087
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/IdleTimeoutAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class IdleTimeoutAttribute extends Attribute {
+ private int _timeout = 0;
+
+ public IdleTimeoutAttribute(byte value[]) {
+ super();
+ _t = IDLE_TIMEOUT;
+ _timeout = value[5] & 0xFF;
+ _timeout |= ((value[4] << 8) & 0xFF00);
+ _timeout |= ((value[3] << 16) & 0xFF0000);
+ _timeout |= ((value[2] << 24) & 0xFF000000);
+ }
+
+ public IdleTimeoutAttribute(int timeout) {
+ super(IDLE_TIMEOUT);
+ _timeout = timeout;
+ }
+
+ public int getTimeout() {
+ return _timeout;
+ }
+
+ public byte[] getValue() throws IOException {
+ byte[] p = new byte[4];
+
+ p[0] = (byte) ((_timeout >>> 24) & 0xFF);
+ p[1] = (byte) ((_timeout >>> 16) & 0xFF);
+ p[2] = (byte) ((_timeout >>> 8) & 0xFF);
+ p[3] = (byte) (_timeout & 0xFF);
+ return p;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/LoginIPHostAttribute.java b/base/util/src/com/netscape/cmsutil/radius/LoginIPHostAttribute.java
new file mode 100644
index 000000000..0d1c0565a
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/LoginIPHostAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class LoginIPHostAttribute extends Attribute {
+ public static final int NAS_ALLOW_SELECT = 0xFFFFFFFF;
+ public static final int NAS_SELECT = 0;
+
+ private byte _value[] = null;
+ private int _type = 0;
+
+ public LoginIPHostAttribute(byte value[]) {
+ super();
+ _t = LOGIN_IP_HOST;
+ _type = value[5] & 0xFF;
+ _type |= ((value[4] << 8) & 0xFF00);
+ _type |= ((value[3] << 16) & 0xFF0000);
+ _type |= ((value[2] << 24) & 0xFF000000);
+ _value = value;
+ }
+
+ public int getType() {
+ return _type;
+ }
+
+ public byte[] getValue() throws IOException {
+ byte[] p = new byte[4];
+
+ p[0] = (byte) ((_type >>> 24) & 0xFF);
+ p[1] = (byte) ((_type >>> 16) & 0xFF);
+ p[2] = (byte) ((_type >>> 8) & 0xFF);
+ p[3] = (byte) (_type & 0xFF);
+ return p;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/LoginLATGroupAttribute.java b/base/util/src/com/netscape/cmsutil/radius/LoginLATGroupAttribute.java
new file mode 100644
index 000000000..4cee6bc3a
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/LoginLATGroupAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class LoginLATGroupAttribute extends Attribute {
+ private byte _value[] = null;
+ private String _str = null;
+
+ public LoginLATGroupAttribute(byte value[]) {
+ super();
+ _t = LOGIN_LAT_GROUP;
+ _str = new String(value, 2, value.length - 2);
+ _value = value;
+ }
+
+ public String getString() {
+ return _str;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _str.getBytes();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/LoginLATNodeAttribute.java b/base/util/src/com/netscape/cmsutil/radius/LoginLATNodeAttribute.java
new file mode 100644
index 000000000..2c2d3411e
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/LoginLATNodeAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class LoginLATNodeAttribute extends Attribute {
+ private byte _value[] = null;
+ private String _str = null;
+
+ public LoginLATNodeAttribute(byte value[]) {
+ super();
+ _t = LOGIN_LAT_NODE;
+ _str = new String(value, 2, value.length - 2);
+ _value = value;
+ }
+
+ public String getString() {
+ return _str;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _str.getBytes();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/LoginLATPortAttribute.java b/base/util/src/com/netscape/cmsutil/radius/LoginLATPortAttribute.java
new file mode 100644
index 000000000..330161ec8
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/LoginLATPortAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class LoginLATPortAttribute extends Attribute {
+ private byte _value[] = null;
+ private String _str = null;
+
+ public LoginLATPortAttribute(byte value[]) {
+ super();
+ _t = PROXY_STATE;
+ _str = new String(value, 2, value.length - 2);
+ _value = value;
+ }
+
+ public String getString() {
+ return _str;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _str.getBytes();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/LoginLATServiceAttribute.java b/base/util/src/com/netscape/cmsutil/radius/LoginLATServiceAttribute.java
new file mode 100644
index 000000000..158630d27
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/LoginLATServiceAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class LoginLATServiceAttribute extends Attribute {
+ private byte _value[] = null;
+ private String _str = null;
+
+ public LoginLATServiceAttribute(byte value[]) {
+ super();
+ _t = LOGIN_LAT_SERVICE;
+ _str = new String(value, 2, value.length - 2);
+ _value = value;
+ }
+
+ public String getString() {
+ return _str;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _str.getBytes();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/LoginServiceAttribute.java b/base/util/src/com/netscape/cmsutil/radius/LoginServiceAttribute.java
new file mode 100644
index 000000000..73f49d39f
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/LoginServiceAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class LoginServiceAttribute extends Attribute {
+ public static final int TELNET = 0;
+ public static final int RLOGIN = 1;
+ public static final int TCP_CLEAR = 2;
+ public static final int PORTMASTER = 3;
+ public static final int LAT = 4;
+ public static final int X25_PAD = 5;
+ public static final int X25_T3POS = 6;
+ public static final int TCP_CLEAR_QUIET = 8;
+
+ private byte _value[] = null;
+ private int _type = 0;
+
+ public LoginServiceAttribute(byte value[]) {
+ super();
+ _t = LOGIN_SERVICE;
+ _type = value[5] & 0xFF;
+ _type |= ((value[4] << 8) & 0xFF00);
+ _type |= ((value[3] << 16) & 0xFF0000);
+ _type |= ((value[2] << 24) & 0xFF000000);
+ _value = value;
+ }
+
+ public int getType() {
+ return _type;
+ }
+
+ public byte[] getValue() throws IOException {
+ byte[] p = new byte[4];
+
+ p[0] = (byte) ((_type >>> 24) & 0xFF);
+ p[1] = (byte) ((_type >>> 16) & 0xFF);
+ p[2] = (byte) ((_type >>> 8) & 0xFF);
+ p[3] = (byte) (_type & 0xFF);
+ return p;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/LoginTCPPortAttribute.java b/base/util/src/com/netscape/cmsutil/radius/LoginTCPPortAttribute.java
new file mode 100644
index 000000000..6b44f50c6
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/LoginTCPPortAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class LoginTCPPortAttribute extends Attribute {
+ private int _port = 0;
+
+ public LoginTCPPortAttribute(byte value[]) {
+ super();
+ _t = LOGIN_TCP_PORT;
+ _port = value[5] & 0xFF;
+ _port |= ((value[4] << 8) & 0xFF00);
+ _port |= ((value[3] << 16) & 0xFF0000);
+ _port |= ((value[2] << 24) & 0xFF000000);
+ }
+
+ public LoginTCPPortAttribute(int port) {
+ super(LOGIN_TCP_PORT);
+ _port = port;
+ }
+
+ public int getPort() {
+ return _port;
+ }
+
+ public byte[] getValue() throws IOException {
+ byte[] p = new byte[4];
+
+ p[0] = (byte) ((_port >>> 24) & 0xFF);
+ p[1] = (byte) ((_port >>> 16) & 0xFF);
+ p[2] = (byte) ((_port >>> 8) & 0xFF);
+ p[3] = (byte) (_port & 0xFF);
+ return p;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/NASClassAttribute.java b/base/util/src/com/netscape/cmsutil/radius/NASClassAttribute.java
new file mode 100644
index 000000000..57b983028
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/NASClassAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class NASClassAttribute extends Attribute {
+ private byte _value[] = null;
+ private String _str = null;
+
+ public NASClassAttribute(byte value[]) {
+ super();
+ _t = NAS_CLASS;
+ _str = new String(value, 2, value.length - 2);
+ _value = value;
+ }
+
+ public String getString() {
+ return _str;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _str.getBytes();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/NASIPAddressAttribute.java b/base/util/src/com/netscape/cmsutil/radius/NASIPAddressAttribute.java
new file mode 100644
index 000000000..d4022b3dd
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/NASIPAddressAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+import java.net.InetAddress;
+
+public class NASIPAddressAttribute extends Attribute {
+ private InetAddress _ip = null;
+ private byte _value[] = null;
+
+ public NASIPAddressAttribute(byte value[]) {
+ super();
+ _t = NAS_IP_ADDRESS;
+ _value = value;
+ }
+
+ public NASIPAddressAttribute(InetAddress ip) {
+ super(NAS_IP_ADDRESS);
+ _ip = ip;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _ip.getAddress();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/NASIdentifierAttribute.java b/base/util/src/com/netscape/cmsutil/radius/NASIdentifierAttribute.java
new file mode 100644
index 000000000..0a3a62cd8
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/NASIdentifierAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class NASIdentifierAttribute extends Attribute {
+ private byte _value[] = null;
+ private String _str = null;
+
+ public NASIdentifierAttribute(byte value[]) {
+ super();
+ _t = NAS_IDENTIFIER;
+ _str = new String(value, 2, value.length - 2);
+ _value = value;
+ }
+
+ public String getString() {
+ return _str;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _str.getBytes();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/NASPacket.java b/base/util/src/com/netscape/cmsutil/radius/NASPacket.java
new file mode 100644
index 000000000..70d143989
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/NASPacket.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.cmsutil.radius;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+public abstract class NASPacket extends Packet {
+ public NASPacket(int c, short id, Authenticator auth) {
+ super(c, id, auth);
+ }
+
+ public byte[] getData() throws IOException {
+ // prepare the attributes first
+ ByteArrayOutputStream attrsOS = new ByteArrayOutputStream();
+
+ for (int i = 0; i < _attrs.size(); i++) {
+ Attribute attr = (Attribute) getAttributeAt(i);
+
+ attrsOS.write(attr.getData());
+ }
+ byte attrsData[] = attrsOS.toByteArray();
+
+ ByteArrayOutputStream dataOS = new ByteArrayOutputStream();
+
+ dataOS.write(_c); // code
+ dataOS.write(_id); // identifier
+ int len = attrsData.length + 20;
+
+ dataOS.write((len >>> 8) & 0xFF);
+ dataOS.write(len & 0xFF);
+ dataOS.write(_auth.getData());
+ dataOS.write(attrsData);
+
+ return dataOS.toByteArray();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/NASPortAttribute.java b/base/util/src/com/netscape/cmsutil/radius/NASPortAttribute.java
new file mode 100644
index 000000000..0f7b31e75
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/NASPortAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class NASPortAttribute extends Attribute {
+ private int _port = 0;
+
+ public NASPortAttribute(byte value[]) {
+ super();
+ _t = NAS_PORT;
+ _port = value[5] & 0xFF;
+ _port |= ((value[4] << 8) & 0xFF00);
+ _port |= ((value[3] << 16) & 0xFF0000);
+ _port |= ((value[2] << 24) & 0xFF000000);
+ }
+
+ public NASPortAttribute(int port) {
+ super(NAS_PORT);
+ _port = port;
+ }
+
+ public byte[] getValue() throws IOException {
+ byte[] p = new byte[4];
+
+ p[0] = (byte) ((_port >>> 24) & 0xFF);
+ p[1] = (byte) ((_port >>> 16) & 0xFF);
+ p[2] = (byte) ((_port >>> 8) & 0xFF);
+ p[3] = (byte) (_port & 0xFF);
+ return p;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/NASPortTypeAttribute.java b/base/util/src/com/netscape/cmsutil/radius/NASPortTypeAttribute.java
new file mode 100644
index 000000000..84ccc3ae1
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/NASPortTypeAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class NASPortTypeAttribute extends Attribute {
+ public static final int ASYNC = 0;
+ public static final int SYNC = 1;
+ public static final int ISDN_SYNC = 2;
+ public static final int ISDN_ASYNC_V120 = 3;
+ public static final int ISDN_ASYNC_V110 = 4;
+ public static final int VIRTUAL = 5;
+ public static final int PIAFS = 6;
+ public static final int HDLC = 7;
+ public static final int X_25 = 8;
+ public static final int X_75 = 9;
+ public static final int G3_FAX = 10;
+ public static final int SDSL = 11;
+ public static final int ADSL_CAP = 12;
+ public static final int ADSL_DMT = 13;
+ public static final int IDSL = 14;
+ public static final int ETHERNET = 15;
+ public static final int XDSL = 16;
+ public static final int CABLE = 17;
+
+ private byte _value[] = null;
+
+ public NASPortTypeAttribute(byte value[]) {
+ super();
+ _t = NAS_PORT_TYPE;
+ _value = value;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _value;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/Packet.java b/base/util/src/com/netscape/cmsutil/radius/Packet.java
new file mode 100644
index 000000000..4fad0ba79
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/Packet.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.cmsutil.radius;
+
+public abstract class Packet {
+ public static final int ACCESS_REQUEST = 1;
+ public static final int ACCESS_ACCEPT = 2;
+ public static final int ACCESS_REJECT = 3;
+ // public static final int ACCOUNTING_REQUEST = 4;
+ // public static final int ACCOUNTING_RESPONSE = 5;
+ public static final int ACCESS_CHALLENGE = 11;
+ public static final int RESERVED = 255;
+
+ protected int _c = 0;
+ protected short _id = 0;
+ protected Authenticator _auth = null;
+ protected AttributeSet _attrs = new AttributeSet();
+
+ public Packet() {
+ }
+
+ public Packet(int c, short id, Authenticator auth) {
+ _c = c;
+ _id = id;
+ _auth = auth;
+ }
+
+ public int getCode() {
+ return _c;
+ }
+
+ public short getIdentifier() {
+ return _id;
+ }
+
+ public Authenticator getAuthenticator() {
+ return _auth;
+ }
+
+ public void addAttribute(Attribute attr) {
+ _attrs.addAttribute(attr);
+ }
+
+ public AttributeSet getAttributeSet() {
+ return _attrs;
+ }
+
+ public Attribute getAttributeAt(int pos) {
+ return _attrs.getAttributeAt(pos);
+ }
+
+ public String toString() {
+ return "Packet [code=" + _c + ",id=" + (_id & 0xFF) + "]";
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/PacketFactory.java b/base/util/src/com/netscape/cmsutil/radius/PacketFactory.java
new file mode 100644
index 000000000..8d2e20e74
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/PacketFactory.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class PacketFactory {
+ public static ServerPacket createServerPacket(byte data[])
+ throws IOException {
+ switch (data[0] & 0xFF) {
+ case Packet.ACCESS_ACCEPT:
+ return new AccessAccept(data);
+
+ case Packet.ACCESS_REJECT:
+ return new AccessReject(data);
+
+ case Packet.ACCESS_CHALLENGE:
+ return new AccessChallenge(data);
+
+ default:
+ throw new IOException("Unknown server packet " + (data[0] & 0xFF));
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/PortLimitAttribute.java b/base/util/src/com/netscape/cmsutil/radius/PortLimitAttribute.java
new file mode 100644
index 000000000..7903bb1fd
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/PortLimitAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class PortLimitAttribute extends Attribute {
+ private int _port = 0;
+
+ private byte _value[] = null;
+
+ public PortLimitAttribute(byte value[]) {
+ super();
+ _t = FRAMED_IP_ADDRESS;
+ _value = value;
+ _port = value[5] & 0xFF;
+ _port |= ((value[4] << 8) & 0xFF00);
+ _port |= ((value[3] << 16) & 0xFF0000);
+ _port |= ((value[2] << 24) & 0xFF000000);
+
+ }
+
+ public int getPort() {
+ return _port;
+ }
+
+ public byte[] getValue() throws IOException {
+ byte[] p = new byte[4];
+
+ p[0] = (byte) ((_port >>> 24) & 0xFF);
+ p[1] = (byte) ((_port >>> 16) & 0xFF);
+ p[2] = (byte) ((_port >>> 8) & 0xFF);
+ p[3] = (byte) (_port & 0xFF);
+ return p;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/ProxyStateAttribute.java b/base/util/src/com/netscape/cmsutil/radius/ProxyStateAttribute.java
new file mode 100644
index 000000000..83831b652
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/ProxyStateAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class ProxyStateAttribute extends Attribute {
+ private byte _value[] = null;
+ private String _str = null;
+
+ public ProxyStateAttribute(byte value[]) {
+ super();
+ _t = PROXY_STATE;
+ _str = new String(value, 2, value.length - 2);
+ _value = value;
+ }
+
+ public String getString() {
+ return _str;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _str.getBytes();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/RadiusConn.java b/base/util/src/com/netscape/cmsutil/radius/RadiusConn.java
new file mode 100644
index 000000000..b22807a5d
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/RadiusConn.java
@@ -0,0 +1,230 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmsutil.radius;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.SocketException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Properties;
+
+/**
+ * This class implements RFC2865 - Remote Authentication Dial In
+ * User Service (RADIUS), June 2000.
+ */
+public class RadiusConn {
+ public static int MAX_RETRIES = 10;
+ public static int OFFICAL_PORT = 1812;
+ public static int DEFAULT_PORT = 1645;
+ public static int DEFAULT_TIMEOUT = 5;
+
+ public static String OPTION_DEBUG = "OPTION_DEBUG";
+
+ private Properties _options = null;
+ private boolean _traceOn = true;
+ private String _host[] = new String[2];
+ private int _port[] = new int[2];
+ private int _selected = 0;
+ private String _secret = null;
+ private DatagramSocket _socket = null;
+ private short _id = (short) System.currentTimeMillis();
+ private int _maxRetries = MAX_RETRIES;
+ private SecureRandom _rand = null;
+
+ public RadiusConn(String host1, String host2, int port, String secret,
+ int timeout) throws SocketException {
+ this(host1, port, host2, port, secret, timeout, null, null);
+ }
+
+ public RadiusConn(String host, int port, String secret, byte seed[],
+ Properties options)
+ throws SocketException {
+ this(host, port, host, port, secret, DEFAULT_TIMEOUT, seed, options);
+ }
+
+ public RadiusConn(String host1, int port1, String host2, int port2,
+ String secret, int timeout, byte seed[], Properties options)
+ throws SocketException {
+ _host[0] = host1;
+ _port[0] = port1;
+ _host[1] = host2;
+ _port[1] = port2;
+ _selected = 0;
+ _secret = secret;
+ _options = options;
+ _socket = new DatagramSocket();
+ _socket.setSoTimeout(timeout * 1000);
+ if (seed == null) {
+ _rand = new SecureRandom();
+ } else {
+ _rand = new SecureRandom(seed);
+ }
+ }
+
+ public void disconnect() throws IOException {
+ _socket.disconnect();
+ }
+
+ public void authenticate(String name, String password)
+ throws IOException, NoSuchAlgorithmException,
+ RejectException, ChallengeException {
+ int retries = 0;
+ Packet res = null;
+
+ do {
+ AccessRequest req = createAccessRequest();
+
+ req.addAttribute(new UserNameAttribute(name));
+ req.addAttribute(new UserPasswordAttribute(req.getAuthenticator(),
+ _secret, password));
+ req.addAttribute(new NASIPAddressAttribute(InetAddress.getLocalHost()));
+ req.addAttribute(new NASPortAttribute(_socket.getLocalPort()));
+
+ send(req, _host[_selected], _port[_selected]);
+ try {
+ retries++;
+ res = receive();
+ if (res instanceof AccessReject) {
+ throw new RejectException((AccessReject) res);
+ } else if (res instanceof AccessChallenge) {
+ throw new ChallengeException((AccessChallenge) res);
+ }
+ } catch (InterruptedIOException e) {
+ if (retries >= _maxRetries) {
+ // switch server if maxRetries reaches limit
+ retries = 0;
+ if (_selected == 0) {
+ _selected = 1;
+ } else {
+ _selected = 0;
+ }
+ // throw e;
+ }
+
+ }
+ } while (res == null);
+ }
+
+ public void replyChallenge(String password, ChallengeException ce)
+ throws IOException, NoSuchAlgorithmException,
+ RejectException, ChallengeException {
+ replyChallenge(null, password, ce);
+ }
+
+ public void replyChallenge(String name, String password,
+ ChallengeException ce)
+ throws IOException, NoSuchAlgorithmException,
+ RejectException, ChallengeException {
+ StateAttribute state = (StateAttribute)
+ ce.getAttributeSet().getAttributeByType(Attribute.STATE);
+
+ if (state == null)
+ throw new IOException("State not found in challenge");
+ AccessRequest req = createAccessRequest();
+
+ req.addAttribute(state); // needed in challenge
+ if (name != null) {
+ req.addAttribute(new UserNameAttribute(name));
+ }
+ req.addAttribute(new UserPasswordAttribute(req.getAuthenticator(),
+ _secret, password));
+ req.addAttribute(new NASIPAddressAttribute(InetAddress.getLocalHost()));
+ req.addAttribute(new NASPortAttribute(_socket.getLocalPort()));
+
+ send(req, _host[_selected], _port[_selected]);
+ Packet res = receive();
+
+ if (res instanceof AccessReject) {
+ throw new RejectException((AccessReject) res);
+ } else if (res instanceof AccessChallenge) {
+ throw new ChallengeException((AccessChallenge) res);
+ }
+ }
+
+ public void replyChallenge(String name, String password, String state)
+ throws IOException, NoSuchAlgorithmException,
+ RejectException, ChallengeException {
+ if (state == null)
+ throw new IOException("State not found in challenge");
+ AccessRequest req = createAccessRequest();
+
+ req.addAttribute(new StateAttribute(state)); // needed in challenge
+ req.addAttribute(new UserNameAttribute(name));
+ req.addAttribute(new UserPasswordAttribute(req.getAuthenticator(),
+ _secret, password));
+ req.addAttribute(new NASIPAddressAttribute(InetAddress.getLocalHost()));
+ req.addAttribute(new NASPortAttribute(_socket.getLocalPort()));
+
+ send(req, _host[_selected], _port[_selected]);
+ Packet res = receive();
+
+ if (res instanceof AccessReject) {
+ throw new RejectException((AccessReject) res);
+ } else if (res instanceof AccessChallenge) {
+ throw new ChallengeException((AccessChallenge) res);
+ }
+ }
+
+ private short getIdentifier() {
+ return _id++;
+ }
+
+ private void send(NASPacket packet, String host, int port)
+ throws IOException {
+ DatagramPacket dp = new DatagramPacket(new byte[4096], 4096);
+
+ dp.setPort(port);
+ dp.setAddress(InetAddress.getByName(host));
+ byte data[] = packet.getData();
+
+ dp.setLength(data.length);
+ dp.setData(data);
+ _socket.send(dp);
+ if (_traceOn)
+ trace("Sent " + packet);
+ }
+
+ private ServerPacket receive()
+ throws IOException {
+ DatagramPacket dp = new DatagramPacket(new byte[4096], 4096);
+
+ _socket.receive(dp);
+ byte data[] = dp.getData();
+ ServerPacket p = PacketFactory.createServerPacket(data);
+
+ if (_traceOn)
+ trace("Received " + p + " size=" + p.getAttributeSet().size());
+ return p;
+ }
+
+ private AccessRequest createAccessRequest() throws NoSuchAlgorithmException {
+ RequestAuthenticator ra = new RequestAuthenticator(_rand, _secret);
+ AccessRequest req = new AccessRequest(getIdentifier(), ra);
+
+ return req;
+ }
+
+ private void trace(String msg) {
+ System.out.println("TRACE: " + msg);
+ System.out.flush();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/RejectException.java b/base/util/src/com/netscape/cmsutil/radius/RejectException.java
new file mode 100644
index 000000000..f312ef2a4
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/RejectException.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.cmsutil.radius;
+
+public class RejectException extends Exception {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6410697638175895003L;
+ private AccessReject _res = null;
+
+ public RejectException(AccessReject res) {
+ _res = res;
+ }
+
+ public AttributeSet getAttributeSet() {
+ return _res.getAttributeSet();
+ }
+
+ public String getReplyMessage() {
+ return ((ReplyMessageAttribute) (_res.getAttributeSet().getAttributeByType(Attribute.REPLY_MESSAGE)))
+ .getString();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/ReplyMessageAttribute.java b/base/util/src/com/netscape/cmsutil/radius/ReplyMessageAttribute.java
new file mode 100644
index 000000000..5ec4ea052
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/ReplyMessageAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class ReplyMessageAttribute extends Attribute {
+ private byte _value[] = null;
+ private String _str = null;
+
+ public ReplyMessageAttribute(byte value[]) {
+ super();
+ _t = REPLY_MESSAGE;
+ _str = new String(value, 2, value.length - 2);
+ _value = value;
+ }
+
+ public String getString() {
+ return _str;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _str.getBytes();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/RequestAuthenticator.java b/base/util/src/com/netscape/cmsutil/radius/RequestAuthenticator.java
new file mode 100644
index 000000000..5d82752dd
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/RequestAuthenticator.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.cmsutil.radius;
+
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+public class RequestAuthenticator extends Authenticator {
+ private byte _ra[] = null;
+
+ public RequestAuthenticator(SecureRandom rand, String secret)
+ throws NoSuchAlgorithmException {
+ byte[] authenticator = new byte[16];
+
+ rand.nextBytes(authenticator);
+
+ MessageDigest md5 = MessageDigest.getInstance("MD5");
+
+ md5.update(authenticator);
+ md5.update(secret.getBytes());
+ _ra = md5.digest();
+ }
+
+ public byte[] getData() throws IOException {
+ return _ra;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/ResponseAuthenticator.java b/base/util/src/com/netscape/cmsutil/radius/ResponseAuthenticator.java
new file mode 100644
index 000000000..3c3de33c4
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/ResponseAuthenticator.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class ResponseAuthenticator extends Authenticator {
+ private byte _data[] = null;
+
+ public ResponseAuthenticator(byte data[]) {
+ _data = data;
+ }
+
+ public byte[] getData() throws IOException {
+ return _data;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/ServerPacket.java b/base/util/src/com/netscape/cmsutil/radius/ServerPacket.java
new file mode 100644
index 000000000..f7d7fa302
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/ServerPacket.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public abstract class ServerPacket extends Packet {
+ public ServerPacket(byte data[]) throws IOException {
+ super();
+ _c = data[0];
+ _id = data[1];
+ int datalen = data[3] & 0xFF;
+
+ datalen |= ((data[2] << 8) & 0xFF00);
+ byte authData[] = new byte[16];
+
+ System.arraycopy(data, 4, authData, 0, 16);
+ _auth = new ResponseAuthenticator(authData);
+
+ // building attributes
+ int startp = 20;
+
+ while (startp != datalen) {
+ int attrLen = (data[startp + 1] & 0xFF);
+ byte attrData[] = new byte[attrLen];
+
+ System.arraycopy(data, startp, attrData, 0, attrData.length);
+ addAttribute(AttributeFactory.createAttribute(attrData));
+ startp += attrData.length;
+ }
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/ServiceTypeAttribute.java b/base/util/src/com/netscape/cmsutil/radius/ServiceTypeAttribute.java
new file mode 100644
index 000000000..f31c74f9a
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/ServiceTypeAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class ServiceTypeAttribute extends Attribute {
+ public static final int LOGIN = 1;
+ public static final int FRAMED = 2;
+ public static final int CALLBACK_LOGIN = 3;
+ public static final int CALLBACK_FRAMED = 4;
+ public static final int OUTBOUND = 5;
+ public static final int ADMINSITRATIVE = 6;
+ public static final int NAS_PROMPT = 7;
+ public static final int AUTHENTICATE_ONLY = 8;
+ public static final int CALLBACK_NAS_PROMPT = 9;
+ public static final int CALL_CHECK = 10;
+ public static final int CALLBACK_ADMINISTRATIVE = 11;
+
+ private byte _value[] = null;
+ private int _type = 0;
+
+ public ServiceTypeAttribute(byte value[]) {
+ super();
+ _t = SERVICE_TYPE;
+ _type = value[5] & 0xFF;
+ _type |= ((value[4] << 8) & 0xFF00);
+ _type |= ((value[3] << 16) & 0xFF0000);
+ _type |= ((value[2] << 24) & 0xFF000000);
+ _value = value;
+ }
+
+ public int getType() {
+ return _type;
+ }
+
+ public byte[] getValue() throws IOException {
+ byte[] p = new byte[4];
+
+ p[0] = (byte) ((_type >>> 24) & 0xFF);
+ p[1] = (byte) ((_type >>> 16) & 0xFF);
+ p[2] = (byte) ((_type >>> 8) & 0xFF);
+ p[3] = (byte) (_type & 0xFF);
+ return p;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/SessionTimeoutAttribute.java b/base/util/src/com/netscape/cmsutil/radius/SessionTimeoutAttribute.java
new file mode 100644
index 000000000..2809aee4b
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/SessionTimeoutAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class SessionTimeoutAttribute extends Attribute {
+ private int _timeout = 0;
+
+ public SessionTimeoutAttribute(byte value[]) {
+ super();
+ _t = SESSION_TIMEOUT;
+ _timeout = value[5] & 0xFF;
+ _timeout |= ((value[4] << 8) & 0xFF00);
+ _timeout |= ((value[3] << 16) & 0xFF0000);
+ _timeout |= ((value[2] << 24) & 0xFF000000);
+ }
+
+ public SessionTimeoutAttribute(int timeout) {
+ super(SESSION_TIMEOUT);
+ _timeout = timeout;
+ }
+
+ public byte[] getValue() throws IOException {
+ byte[] p = new byte[4];
+
+ p[0] = (byte) ((_timeout >>> 24) & 0xFF);
+ p[1] = (byte) ((_timeout >>> 16) & 0xFF);
+ p[2] = (byte) ((_timeout >>> 8) & 0xFF);
+ p[3] = (byte) (_timeout & 0xFF);
+ return p;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/StateAttribute.java b/base/util/src/com/netscape/cmsutil/radius/StateAttribute.java
new file mode 100644
index 000000000..027f95620
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/StateAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class StateAttribute extends Attribute {
+ private byte _value[] = null;
+ private String _str = null;
+
+ public StateAttribute(String str) {
+ _t = STATE;
+ _str = str;
+ }
+
+ public StateAttribute(byte value[]) {
+ super();
+ _t = STATE;
+ _str = new String(value, 2, value.length - 2);
+ _value = value;
+ }
+
+ public String getString() {
+ return _str;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _str.getBytes();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/TerminationActionAttribute.java b/base/util/src/com/netscape/cmsutil/radius/TerminationActionAttribute.java
new file mode 100644
index 000000000..b47a70d8c
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/TerminationActionAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class TerminationActionAttribute extends Attribute {
+ public static final int DEFAULT = 0;
+ public static final int RADIUS_REQUEST = 1;
+
+ private int _action = 0;
+
+ public TerminationActionAttribute(byte value[]) {
+ super();
+ _t = TERMINATION_ACTION;
+ _action = value[5] & 0xFF;
+ _action |= ((value[4] << 8) & 0xFF00);
+ _action |= ((value[3] << 16) & 0xFF0000);
+ _action |= ((value[2] << 24) & 0xFF000000);
+ }
+
+ public TerminationActionAttribute(int action) {
+ super(TERMINATION_ACTION);
+ _action = action;
+ }
+
+ public int getAction() {
+ return _action;
+ }
+
+ public byte[] getValue() throws IOException {
+ byte[] p = new byte[4];
+
+ p[0] = (byte) ((_action >>> 24) & 0xFF);
+ p[1] = (byte) ((_action >>> 16) & 0xFF);
+ p[2] = (byte) ((_action >>> 8) & 0xFF);
+ p[3] = (byte) (_action & 0xFF);
+ return p;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/UserNameAttribute.java b/base/util/src/com/netscape/cmsutil/radius/UserNameAttribute.java
new file mode 100644
index 000000000..af7ce6bbe
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/UserNameAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class UserNameAttribute extends Attribute {
+ private String _name = null;
+
+ public UserNameAttribute(byte value[]) {
+ super();
+ _t = USER_NAME;
+ _name = new String(value, 2, value.length - 2);
+ }
+
+ public UserNameAttribute(String name) {
+ super(USER_NAME);
+ _name = name;
+ }
+
+ public byte[] getValue() throws IOException {
+ return _name.getBytes();
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/UserPasswordAttribute.java b/base/util/src/com/netscape/cmsutil/radius/UserPasswordAttribute.java
new file mode 100644
index 000000000..31c27cdfd
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/UserPasswordAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class UserPasswordAttribute extends Attribute {
+ private Authenticator _ra = null;
+ private String _secret = null;
+ private String _password = null;
+
+ public UserPasswordAttribute(byte value[]) {
+ //
+ }
+
+ public UserPasswordAttribute(Authenticator ra, String secret, String password) {
+ super(USER_PASSWORD);
+ _ra = ra;
+ _secret = secret;
+ _password = password;
+ }
+
+ public byte[] getValue() throws IOException {
+ MessageDigest md5 = null;
+
+ try {
+ md5 = MessageDigest.getInstance("MD5");
+ } catch (NoSuchAlgorithmException e) {
+ throw new IOException(e.getMessage());
+ }
+ md5.update(_secret.getBytes());
+ md5.update(_ra.getData());
+ byte sum[] = md5.digest();
+
+ byte up[] = _password.getBytes();
+ int oglen = (up.length / 16) + 1;
+ byte ret[] = new byte[oglen * 16];
+
+ for (int i = 0; i < ret.length; i++) {
+ if ((i % 16) == 0) {
+ md5.reset();
+ md5.update(_secret.getBytes());
+ }
+ if (i < up.length) {
+ ret[i] = (byte) (sum[i % 16] ^ up[i]);
+ } else {
+ ret[i] = (byte) (sum[i % 16] ^ 0);
+ }
+ md5.update(ret[i]);
+ if ((i % 16) == 15) {
+ sum = md5.digest();
+ }
+ }
+ return ret;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/radius/VendorSpecificAttribute.java b/base/util/src/com/netscape/cmsutil/radius/VendorSpecificAttribute.java
new file mode 100644
index 000000000..5f3d9f170
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/radius/VendorSpecificAttribute.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.cmsutil.radius;
+
+import java.io.IOException;
+
+public class VendorSpecificAttribute extends Attribute {
+ private byte _value[] = null;
+ private String _id = null;
+ private String _str = null;
+
+ public VendorSpecificAttribute(byte value[]) {
+ super();
+ _t = VENDOR_SPECIFIC;
+ _id = new String(value, 2, 4);
+ _str = new String(value, 6, value.length - 6);
+ _value = value;
+ }
+
+ public String getId() {
+ return _id;
+ }
+
+ public String getString() {
+ return _str;
+ }
+
+ public byte[] getValue() throws IOException {
+ byte v[] = new byte[_id.length() + _str.length()];
+ byte idData[] = _id.getBytes();
+ byte strData[] = _str.getBytes();
+
+ System.arraycopy(idData, 0, v, 0, _id.length());
+ System.arraycopy(strData, 0, v, _id.length(), _str.length());
+ return v;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/scep/CRSPKIMessage.java b/base/util/src/com/netscape/cmsutil/scep/CRSPKIMessage.java
new file mode 100644
index 000000000..03bc68723
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/scep/CRSPKIMessage.java
@@ -0,0 +1,905 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmsutil.scep;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.CharConversionException;
+import java.io.IOException;
+import java.security.PublicKey;
+import java.util.Arrays;
+import java.util.Hashtable;
+
+import netscape.security.pkcs.PKCS10;
+
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.NULL;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.PrintableString;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.pkcs7.Attribute;
+import org.mozilla.jss.pkcs7.ContentInfo;
+import org.mozilla.jss.pkcs7.EncryptedContentInfo;
+import org.mozilla.jss.pkcs7.EnvelopedData;
+import org.mozilla.jss.pkcs7.IssuerAndSerialNumber;
+import org.mozilla.jss.pkcs7.RecipientInfo;
+import org.mozilla.jss.pkcs7.SignedData;
+import org.mozilla.jss.pkcs7.SignerInfo;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.pkix.cert.CertificateInfo;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+
+public class CRSPKIMessage {
+
+ // OIDs for authenticated attributes
+ public static OBJECT_IDENTIFIER CRS_MESSAGETYPE =
+ new OBJECT_IDENTIFIER(new long[] { 2, 16, 840, 1, 113733, 1, 9, 2 }
+ );
+ public static OBJECT_IDENTIFIER CRS_PKISTATUS =
+ new OBJECT_IDENTIFIER(new long[] { 2, 16, 840, 1, 113733, 1, 9, 3 }
+ );
+ public static OBJECT_IDENTIFIER CRS_FAILINFO =
+ new OBJECT_IDENTIFIER(new long[] { 2, 16, 840, 1, 113733, 1, 9, 4 }
+ );
+ public static OBJECT_IDENTIFIER CRS_SENDERNONCE =
+ new OBJECT_IDENTIFIER(new long[] { 2, 16, 840, 1, 113733, 1, 9, 5 }
+ );
+ public static OBJECT_IDENTIFIER CRS_RECIPIENTNONCE =
+ new OBJECT_IDENTIFIER(new long[] { 2, 16, 840, 1, 113733, 1, 9, 6 }
+ );
+ public static OBJECT_IDENTIFIER CRS_TRANSID =
+ new OBJECT_IDENTIFIER(new long[] { 2, 16, 840, 1, 113733, 1, 9, 7 }
+ );
+ public static OBJECT_IDENTIFIER CRS_EXTENSIONREQ =
+ new OBJECT_IDENTIFIER(new long[] { 2, 16, 840, 1, 113733, 1, 9, 8 }
+ );
+
+ // PKCS9 defined OIDs
+
+ public static OBJECT_IDENTIFIER PKCS9_CONTENT_TYPE =
+ new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 9, 3 }
+ );
+
+ public static OBJECT_IDENTIFIER PKCS9_MESSAGE_DIGEST =
+ new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 9, 4 }
+ );
+
+ /* PKCS 1 - rsaEncryption */
+ public static OBJECT_IDENTIFIER RSA_ENCRYPTION =
+ new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 1, 1 }
+ );
+
+ public static OBJECT_IDENTIFIER DES_CBC_ENCRYPTION =
+ new OBJECT_IDENTIFIER(new long[] { 1, 3, 14, 3, 2, 7 }
+ );
+
+ public static OBJECT_IDENTIFIER DES_EDE3_CBC_ENCRYPTION =
+ new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 3, 7 }
+ );
+
+ public static OBJECT_IDENTIFIER MD5_DIGEST =
+ new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 2, 5 }
+ );
+
+ public static OBJECT_IDENTIFIER SHA1_DIGEST =
+ new OBJECT_IDENTIFIER(new long[] { 1, 3, 14, 3, 2, 26 }
+ );
+
+ public static OBJECT_IDENTIFIER SHA256_DIGEST =
+ new OBJECT_IDENTIFIER(new long[] { 2, 16, 840, 1, 101, 3, 4, 2, 1 }
+ );
+
+ public static OBJECT_IDENTIFIER SHA512_DIGEST =
+ new OBJECT_IDENTIFIER(new long[] { 2, 16, 840, 1, 101, 3, 4, 2, 3 }
+ );
+
+ // Strings given in 'messageType' authenticated attribute
+ public final static String mType_PKCSReq = "19";
+ public final static String mType_CertRep = "3";
+ public final static String mType_GetCertInitial = "20";
+ public final static String mType_GetCert = "21";
+ public final static String mType_GetCRL = "22";
+
+ // Strings given in 'PKIStatus' authenticated attribute
+ public final static String mStatus_SUCCESS = "0";
+ public final static String mStatus_FAILURE = "2";
+ public final static String mStatus_PENDING = "3";
+
+ // Strings given in 'failInfo' authenticated attribute
+ public final static String mFailInfo_badAlg = "0";
+ public final static String mFailInfo_badMessageCheck = "1";
+ public final static String mFailInfo_badRequest = "2";
+ public final static String mFailInfo_badTime = "3";
+ public final static String mFailInfo_badCertId = "4";
+ public final static String mFailInfo_unsupportedExt = "5";
+ public final static String mFailInfo_mustArchiveKeys = "6";
+ public final static String mFailInfo_badIdentity = "7";
+ public final static String mFailInfo_popRequired = "8";
+ public final static String mFailInfo_popFailed = "9";
+ public final static String mFailInfo_noKeyReuse = "10";
+ public final static String mFailInfo_internalCAError = "11";
+ public final static String mFailInfo_tryLater = "12";
+
+ // ************************************************************************
+ // These private members represent the flattened structure of the PKIMessage
+ // ************************************************************************
+
+ // top level is just a ContentInfo
+ private ContentInfo crsci;
+ // it's content is a signedData
+ private SignedData sd;
+
+ // In the signed data, we have:
+ private int sdv; // Version
+ private ContentInfo data; // The data to be digested
+ private EnvelopedData sded; // Enveloped data inside of signed data
+ private byte[] signerCertBytes;
+ org.mozilla.jss.pkix.cert.Certificate signerCert;
+
+ private SET sis; // set of SignerInfos
+ private SignerInfo si; // First SignerInfo
+ private AlgorithmIdentifier digestAlgorithmId = null;
+ private int siv; // Version
+ private SET aa; // Authenticated Attributes
+ private SET aa_old; // Authenticated Attributes
+ private IssuerAndSerialNumber sgnIASN; // Signer's Issuer Name and Serialnum
+ private OCTET_STRING aa_digest; // digest of the authenticated attrs
+
+ private String messageType; // these are all authenticated attributes
+ private String failInfo;
+ private String pkiStatus;
+ private String transactionID;
+ private byte[] senderNonce;
+ private byte[] recipientNonce;
+ private OCTET_STRING msg_digest; // digest of the message
+
+ // Inside the sded Enveloped data
+ private RecipientInfo ri; // First RecipientInfo
+ private int riv; // Version
+ private AlgorithmIdentifier riAlgid; // alg that the bulk key is wrapped with
+ private byte[] riKey; // bulk key, wrapped with above algorithm
+ private byte[] cKey; // * 'clear', unwrapped key (not in ASN.1) *
+ private IssuerAndSerialNumber rcpIASN; // Recipient's Issuer Name and Serial Number
+
+ private EncryptedContentInfo eci;
+ private byte[] iv; // initialization vector for above key
+ private byte[] ec; // encrypted content (P10, in case of request)
+ private byte[] cc; // * 'clear' content (not in ASN.1) *
+ private String encryptionAlgorithm = null;
+
+ // For the CertRep, the enveloped content is another signed Data:
+ private SignedData crsd;
+ private int rsdVersion;
+ private byte[] rsdCert; // certificate to send in response
+
+ private PKCS10 myP10;
+
+ private Hashtable<String, Object> attrs; // miscellanous
+
+ // *** END *** //
+
+ public void debug() {
+ }
+
+ public void put(String a, Object b) {
+ attrs.put(a, b);
+ }
+
+ public Object get(Object a) {
+ return attrs.get(a);
+ }
+
+ private SignatureAlgorithm getSignatureAlgorithm(String hashAlgorithm) {
+ SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.RSASignatureWithMD5Digest;
+ if (hashAlgorithm != null) {
+ if (hashAlgorithm.equals("SHA1")) {
+ signatureAlgorithm = SignatureAlgorithm.RSASignatureWithSHA1Digest;
+ } else if (hashAlgorithm.equals("SHA256")) {
+ signatureAlgorithm = SignatureAlgorithm.RSASignatureWithSHA256Digest;
+ } else if (hashAlgorithm.equals("SHA512")) {
+ signatureAlgorithm = SignatureAlgorithm.RSASignatureWithSHA512Digest;
+ }
+ }
+ return signatureAlgorithm;
+ }
+
+ private OBJECT_IDENTIFIER getAlgorithmOID(String hashAlgorithm) {
+ OBJECT_IDENTIFIER oid = MD5_DIGEST;
+ if (hashAlgorithm != null) {
+ if (hashAlgorithm.equals("SHA1")) {
+ oid = SHA1_DIGEST;
+ } else if (hashAlgorithm.equals("SHA256")) {
+ oid = SHA256_DIGEST;
+ } else if (hashAlgorithm.equals("SHA512")) {
+ oid = SHA512_DIGEST;
+ }
+ }
+ return oid;
+ }
+
+ // getHashAlgorithm is added to work around issue 636217
+ private String getHashAlgorithm(OBJECT_IDENTIFIER algorithmOID) {
+ String hashAlgorithm = null;
+ if (algorithmOID != null) {
+ if (algorithmOID.equals(MD5_DIGEST)) {
+ hashAlgorithm = "MD5";
+ } else if (algorithmOID.equals(SHA1_DIGEST)) {
+ hashAlgorithm = "SHA1";
+ } else if (algorithmOID.equals(SHA256_DIGEST)) {
+ hashAlgorithm = "SHA256";
+ } else if (algorithmOID.equals(SHA512_DIGEST)) {
+ hashAlgorithm = "SHA512";
+ }
+ }
+ return hashAlgorithm;
+ }
+
+ // These functions are used to initialize the various blobs
+
+ public void makeSignedData(int version,
+ byte[] certificate, String hashAlgorithm) {
+
+ try {
+ SET digest_algs = new SET();
+
+ digest_algs.addElement(new AlgorithmIdentifier(getAlgorithmOID(hashAlgorithm), new NULL()));
+
+ // SET certs = new SET();
+ // certs.addElement(new ANY(certificate));
+
+ SET sis = new SET();
+
+ sis.addElement(si);
+
+ ContentInfo data = this.data;
+
+ this.sd = new SignedData(
+ digest_algs,
+ data,
+ null, // don't send the certs, he already has them
+ null, // crl's
+ sis);
+
+ } catch (Exception e) {
+ }
+ }
+
+ public byte[] getResponse() throws IOException, InvalidBERException {
+
+ crsci = new ContentInfo(ContentInfo.SIGNED_DATA,
+ sd);
+
+ return ASN1Util.encode(crsci);
+
+ // ANY a = crsci.getContent();
+ // return a.getEncoded();
+ }
+
+ /*
+ public void makeSignerInfo_old(int version,
+ // issuer and serialnumber
+ byte[] digest) {
+
+ si = new SignerInfo(new INTEGER(version),
+ sgnIASN, // issuer and serialnum
+ new AlgorithmIdentifier(MD5_DIGEST, new NULL()), // digest algorithm
+ this.aa, // Authenticated Attributes
+ new AlgorithmIdentifier(RSA_ENCRYPTION,new NULL()), // digest encryption algorithm
+ new OCTET_STRING(digest), // digest
+ null); // unauthenticated attributes
+
+ }
+ */
+
+ public void makeSignerInfo(int version,
+ // issuer and serialnumber
+ org.mozilla.jss.crypto.PrivateKey pk, String hashAlgorithm)
+ throws java.security.NoSuchAlgorithmException,
+ TokenException,
+ java.security.InvalidKeyException,
+ java.security.SignatureException,
+ org.mozilla.jss.CryptoManager.NotInitializedException {
+
+ si = new SignerInfo(sgnIASN, // issuer and serialnum
+ this.aa, // Authenticated Attributes
+ null, // Unauthenticated Attrs
+ ContentInfo.ENVELOPED_DATA, // content type
+ msg_digest.toByteArray(), // digest
+ getSignatureAlgorithm(hashAlgorithm),
+ pk);
+ }
+
+ public void makeAuthenticatedAttributes() {
+
+ aa = new SET();
+
+ try {
+ if (transactionID != null) {
+ SET tidset = new SET();
+
+ tidset.addElement((new PrintableString(transactionID)));
+ aa.addElement(new Attribute(CRS_TRANSID, tidset));
+ }
+
+ if (pkiStatus != null) {
+ SET pkistatusset = new SET();
+
+ pkistatusset.addElement(new PrintableString(pkiStatus));
+ aa.addElement(new Attribute(CRS_PKISTATUS, pkistatusset));
+ }
+
+ if (messageType != null) {
+ SET aaset = new SET();
+
+ aaset.addElement(new PrintableString(messageType));
+ aa.addElement(new Attribute(CRS_MESSAGETYPE, aaset));
+ }
+
+ if (failInfo != null) {
+ SET fiset = new SET();
+
+ fiset.addElement(new PrintableString(failInfo));
+ aa.addElement(new Attribute(CRS_FAILINFO, fiset));
+ }
+
+ if (senderNonce != null) {
+ SET snset = new SET();
+
+ snset.addElement(new OCTET_STRING(senderNonce));
+ aa.addElement(new Attribute(CRS_SENDERNONCE, snset));
+ }
+
+ if (recipientNonce != null) {
+ SET rnset = new SET();
+
+ rnset.addElement(new OCTET_STRING(recipientNonce));
+ aa.addElement(new Attribute(CRS_RECIPIENTNONCE, rnset));
+ }
+
+ // XXX sender nonce
+
+ } catch (CharConversionException e) {
+ }
+ }
+
+ public byte[] makeEnvelopedData(int version) {
+
+ byte[] r;
+
+ try {
+
+ if (this.ri != null) {
+ ContentInfo ci;
+
+ SET ris = new SET();
+
+ ris.addElement(this.ri);
+
+ this.sded = new EnvelopedData(
+ new INTEGER(version),
+ ris,
+ eci);
+
+ ci = new ContentInfo(ContentInfo.ENVELOPED_DATA,
+ sded);
+ ByteArrayOutputStream ba = new ByteArrayOutputStream();
+
+ ci.encode(ba);
+ r = ba.toByteArray();
+ } else {
+ r = new byte[0];
+ }
+
+ this.data = new ContentInfo(ContentInfo.DATA,
+ new OCTET_STRING(r));
+
+ return r;
+
+ // return this.sded.getEncodedContents();
+ } catch (Exception e) {
+ return null;
+ }
+
+ }
+
+ public void makeRecipientInfo(int version, byte[] riKey) {
+ this.riv = version;
+
+ this.riAlgid = new AlgorithmIdentifier(RSA_ENCRYPTION, new NULL());
+ this.riKey = riKey;
+
+ this.ri = new RecipientInfo(
+ new INTEGER(this.riv),
+ rcpIASN,
+ this.riAlgid,
+ new OCTET_STRING(this.riKey)
+ );
+ }
+
+ public void makeEncryptedContentInfo(byte[] iv, byte[] ec, String algorithm) {
+ this.iv = iv;
+ this.ec = ec;
+
+ try {
+ OBJECT_IDENTIFIER oid = DES_CBC_ENCRYPTION;
+ if (algorithm != null && algorithm.equals("DES3"))
+ oid = DES_EDE3_CBC_ENCRYPTION;
+
+ AlgorithmIdentifier aid = new AlgorithmIdentifier(oid, new OCTET_STRING(iv));
+
+ //eci = EncryptedContentInfo.createCRSCompatibleEncryptedContentInfo(
+ eci = new EncryptedContentInfo(ContentInfo.DATA,
+ aid,
+ new OCTET_STRING(ec)
+ );
+
+ } catch (Exception e) {
+ }
+ }
+
+ public byte[] makeSignedRep(int v, byte[] certificate) {
+ rsdVersion = v;
+ rsdCert = certificate;
+ try {
+ SET certs = new SET();
+ ANY cert = new ANY(certificate);
+
+ certs.addElement(cert);
+
+ 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);
+
+ return baos.toByteArray();
+ // return crsd.getEncodedContents();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("{ messageType=");
+ sb.append(getMessageType());
+ sb.append(", failInfo=");
+ sb.append(getFailInfo());
+ sb.append(", pkiStatus=");
+ sb.append(getPKIStatus());
+ sb.append(", transactionID=");
+ sb.append(getTransactionID());
+ sb.append(", senderNonce=");
+ sb.append(Arrays.toString(getSenderNonce()));
+ sb.append(", recipientNonce=");
+ sb.append(Arrays.toString(getRecipientNonce()));
+ sb.append(" }");
+
+ String s = sb.toString();
+ return s;
+ }
+
+ public String getMessageType() {
+ return messageType;
+ }
+
+ public String getFailInfo() {
+ return failInfo;
+ }
+
+ public String getPKIStatus() {
+ return pkiStatus;
+ }
+
+ public String getTransactionID() {
+ return transactionID;
+ }
+
+ public byte[] getSenderNonce() {
+ return senderNonce;
+ }
+
+ public byte[] getRecipientNonce() {
+ return recipientNonce;
+ }
+
+ public byte[] getWrappedKey() {
+ return riKey;
+ }
+
+ public byte[] getEncryptedPkcs10() {
+ return ec;
+ }
+
+ public byte[] getIV() {
+ return iv;
+ }
+
+ public String getEncryptionAlgorithm() {
+ return encryptionAlgorithm;
+ }
+
+ public String getDigestAlgorithmName() {
+ String name = null;
+ if (digestAlgorithmId != null) {
+ name = getHashAlgorithm(digestAlgorithmId.getOID());
+ }
+ return name;
+ }
+
+ public PublicKey getSignerPublicKey() {
+ try {
+
+ org.mozilla.jss.pkix.cert.Certificate.Template ct = new
+ org.mozilla.jss.pkix.cert.Certificate.Template();
+
+ ByteArrayInputStream bais = new ByteArrayInputStream(this.signerCertBytes);
+
+ signerCert = (org.mozilla.jss.pkix.cert.Certificate) ct.decode(bais);
+ return signerCert.getInfo().getSubjectPublicKeyInfo().toPublicKey();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public byte[] getAA() {
+ try {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ aa.encode(baos);
+ return baos.toByteArray();
+ } catch (Exception e) {
+ return null;
+ }
+
+ }
+
+ public void setAA_old(SET auth_attrs) {
+ aa_old = auth_attrs;
+ }
+
+ // SWP
+ public byte[] getAA_old() {
+ try {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ aa_old.encode(baos);
+ return baos.toByteArray();
+ } catch (Exception e) {
+ return null;
+ }
+
+ }
+
+ public byte[] getAADigest() {
+ return aa_digest.toByteArray();
+ }
+
+ public PKCS10 getP10() {
+ return myP10;
+ }
+
+ public void setP10(PKCS10 p10) {
+ myP10 = p10;
+ }
+
+ public void setSgnIssuerAndSerialNumber(IssuerAndSerialNumber iasn) {
+ this.sgnIASN = iasn;
+ }
+
+ public void setRcpIssuerAndSerialNumber(IssuerAndSerialNumber iasn) {
+ this.rcpIASN = iasn;
+ }
+
+ public IssuerAndSerialNumber getSgnIssuerAndSerialNumber() {
+ return this.sgnIASN;
+ }
+
+ public IssuerAndSerialNumber getRcpIssuerAndSerialNumber() {
+ return this.rcpIASN;
+ }
+
+ public void setMessageType(String messageType) {
+ this.messageType = messageType;
+ }
+
+ public void setPKIStatus(String pkiStatus) {
+ this.pkiStatus = pkiStatus;
+ }
+
+ public void setFailInfo(String failInfo) {
+ this.failInfo = failInfo;
+ }
+
+ public void setTransactionID(String tid) {
+ this.transactionID = tid;
+ }
+
+ public void setRecipientNonce(byte[] rn) {
+ this.recipientNonce = rn;
+ }
+
+ public void setSenderNonce(byte[] sn) {
+ this.senderNonce = sn;
+ }
+
+ // public void setCertificate(byte [] cert) { this.certificate = cert; }
+
+ public void setMsgDigest(byte[] digest) {
+ this.msg_digest = new OCTET_STRING(digest);
+ }
+
+ public void setAADigest(byte[] digest) {
+ this.aa_digest = new OCTET_STRING(digest);
+ }
+
+ public void setPending() {
+ // setIssuerAndSerialNumber();
+
+ setMessageType(mType_CertRep);
+ setPKIStatus(mStatus_PENDING);
+ };
+
+ public void setFailure(String failInfo) {
+ setMessageType(mType_CertRep);
+ setPKIStatus(mStatus_FAILURE);
+ setFailInfo(failInfo);
+ }
+
+ // Should add a Certificate to this call
+ public void setSuccess() {
+ setMessageType(mType_CertRep);
+ setPKIStatus(mStatus_SUCCESS);
+ }
+
+ /**
+ * Gets a byte array which is the der-encoded blob
+ * which gets sent back to the router.
+ */
+
+ public byte[] getEncoded() {
+ //Assert.assert(messageType != null);
+ //Assert.assert(pkiStatus != null);
+
+ return new byte[1]; // blagh
+ }
+
+ private void decodeCRSPKIMessage(ByteArrayInputStream bais) throws InvalidBERException, Exception {
+
+ org.mozilla.jss.pkcs7.ContentInfo.Template crscit;
+
+ crscit = new ContentInfo.Template();
+ crsci = (ContentInfo) crscit.decode(bais);
+
+ if (!ContentInfo.SIGNED_DATA.equals(crsci.getContentType())) {
+ throw new Exception("ContentType wasn't signed data, it was" + crsci.getContentType());
+ }
+
+ // Now that we know that the contentInfo is a SignedData, we can decode it
+ SignedData.Template sdt = new SignedData.Template();
+
+ sd = (SignedData) sdt.decode(
+ new ByteArrayInputStream(
+ ((ANY) crsci.getContent()).getEncoded()
+ ));
+ this.decodeSD();
+ }
+
+ public CRSPKIMessage() {
+ attrs = new Hashtable<String, Object>();
+ }
+
+ public CRSPKIMessage(ByteArrayInputStream bais) throws InvalidBERException, Exception {
+ attrs = new Hashtable<String, Object>();
+ decodeCRSPKIMessage(bais);
+ }
+
+ private void decodeSD() throws Exception {
+ ContentInfo sdci;
+
+ sis = sd.getSignerInfos();
+
+ decodeSI();
+
+ sdci = sd.getContentInfo();
+
+ // HACK to work with CRS
+ ANY a = (ANY) sdci.getContent();
+ ByteArrayInputStream s = new ByteArrayInputStream(a.getEncoded());
+ OCTET_STRING os = (OCTET_STRING) (new OCTET_STRING.Template()).decode(s);
+
+ ByteArrayInputStream s2 = new ByteArrayInputStream(os.toByteArray());
+ ContentInfo ci = (ContentInfo) (new ContentInfo.Template()).decode(s2);
+ ByteArrayInputStream s3 = new ByteArrayInputStream(((ANY) ci.getContent()).getEncoded());
+
+ EnvelopedData.Template edt = new EnvelopedData.Template();
+
+ sded = (EnvelopedData) edt.decode(s3);
+
+ SET signerCerts = (SET) sd.getCertificates();
+ Certificate firstCert = (Certificate) signerCerts.elementAt(0);
+
+ signerCertBytes = ASN1Util.encode(firstCert);
+
+ CertificateInfo firstCertInfo = firstCert.getInfo();
+
+ sgnIASN = new IssuerAndSerialNumber(firstCertInfo.getIssuer(),
+ firstCertInfo.getSerialNumber());
+
+ decodeED();
+ }
+
+ private void decodeSI() throws Exception {
+ if (sis.size() == 0) {
+ throw new Exception("SignerInfos is empty");
+ }
+ si = (SignerInfo) sis.elementAt(0);
+
+ digestAlgorithmId = si.getDigestAlgorithmIdentifer();
+
+ decodeAA();
+
+ aa_digest = new OCTET_STRING(si.getEncryptedDigest());
+ }
+
+ private void decodeED() throws Exception {
+ SET ris;
+
+ ris = (SET) sded.getRecipientInfos();
+
+ if (ris.size() == 0) {
+ throw new Exception("RecipientInfos is empty");
+ }
+ ri = (RecipientInfo) ris.elementAt(0);
+ eci = sded.getEncryptedContentInfo();
+
+ if (eci.getContentEncryptionAlgorithm().getOID().equals(DES_EDE3_CBC_ENCRYPTION)) {
+ encryptionAlgorithm = "DES3";
+ } else if (eci.getContentEncryptionAlgorithm().getOID().equals(DES_CBC_ENCRYPTION)) {
+ encryptionAlgorithm = "DES";
+ } else {
+ throw new Exception("P10 encrypted alg is not supported (not DES): "
+ + eci.getContentEncryptionAlgorithm().getOID());
+ }
+
+ ec = eci.getEncryptedContent().toByteArray();
+
+ OCTET_STRING.Template ost = new OCTET_STRING.Template();
+
+ OCTET_STRING os = (OCTET_STRING)
+ ost.decode(new ByteArrayInputStream(
+ ((ANY) eci.getContentEncryptionAlgorithm().getParameters()).getEncoded()
+ )
+ );
+
+ iv = os.toByteArray();
+
+ decodeRI();
+ }
+
+ /**
+ * The PKCS10 request is encrypt with a symmetric key.
+ * This key in turn is encrypted with the RSA key in the
+ * CA certificate.
+ *
+ * riAlgid is the algorithm the symm key is encrypted with. It had
+ * better be RSA
+ * riKey is the encrypted symmetric key
+ */
+
+ private void decodeRI() throws Exception {
+
+ // really should get issuer and serial number of our RI, as this
+ // indicates the key we should use to decrypt with. However, we're just
+ // going to assume that the key is the Signing cert for the server.
+
+ riAlgid = ri.getKeyEncryptionAlgorithmID();
+
+ if (!riAlgid.getOID().equals(RSA_ENCRYPTION)) {
+ throw new Exception("Request is protected by a key which we can't decrypt");
+ }
+
+ riKey = ri.getEncryptedKey().toByteArray();
+
+ }
+
+ private void decodeAA() throws InvalidBERException, IOException {
+ aa = si.getAuthenticatedAttributes();
+
+ int count;
+
+ for (count = 0; count < aa.size(); count++) {
+ Attribute a = (Attribute) aa.elementAt(count);
+ SET s = (SET) a.getValues();
+ ANY f = (ANY) s.elementAt(0);
+ PrintableString ps;
+ PrintableString.Template pst = new PrintableString.Template();
+ OCTET_STRING.Template ost = new OCTET_STRING.Template();
+
+ OBJECT_IDENTIFIER oid = a.getType();
+
+ if (oid.equals(CRS_MESSAGETYPE)) {
+ ps = (PrintableString) pst.decode(new ByteArrayInputStream(f.getEncoded()));
+ // We make a new string here
+ messageType = ps.toString();
+
+ } else if (oid.equals(CRS_PKISTATUS)) {
+ ps = (PrintableString) pst.decode(new ByteArrayInputStream(f.getEncoded()));
+ pkiStatus = new String(ps.toString());
+ } else if (oid.equals(CRS_FAILINFO)) {
+ ps = (PrintableString) pst.decode(new ByteArrayInputStream(f.getEncoded()));
+ failInfo = new String(ps.toString());
+ } else if (oid.equals(CRS_SENDERNONCE)) {
+ OCTET_STRING oss = (OCTET_STRING) ost.decode(new ByteArrayInputStream(f.getEncoded()));
+
+ senderNonce = oss.toByteArray();
+ } else if (oid.equals(CRS_RECIPIENTNONCE)) {
+ OCTET_STRING osr = (OCTET_STRING) ost.decode(new ByteArrayInputStream(f.getEncoded()));
+
+ recipientNonce = osr.toByteArray();
+ } else if (oid.equals(CRS_TRANSID)) {
+ ps = (PrintableString) pst.decode(new ByteArrayInputStream(f.getEncoded()));
+ transactionID = new String(ps.toString());
+ }
+
+ }
+
+ } // end of decodeAA();
+
+ public String getMessageTypeString() {
+ if (messageType == null) {
+ return null;
+ }
+
+ if (messageType.equals(mType_PKCSReq)) {
+ return "PKCSReq";
+ }
+ if (messageType.equals(mType_CertRep)) {
+ return "CertRep";
+ }
+ if (messageType.equals(mType_GetCertInitial)) {
+ return "GetCertInitial";
+ }
+ if (messageType.equals(mType_GetCert)) {
+ return "GetCert";
+ }
+ if (messageType.equals(mType_GetCRL)) {
+ return "GetCRL";
+ }
+ // messageType should match one of the above
+ //Assert.assert(false);
+ return null;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/util/Cert.java b/base/util/src/com/netscape/cmsutil/util/Cert.java
new file mode 100644
index 000000000..3563f70c7
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/util/Cert.java
@@ -0,0 +1,186 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmsutil.util;
+
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+
+import netscape.security.pkcs.PKCS7;
+import netscape.security.x509.X509CRLImpl;
+import netscape.security.x509.X509CertImpl;
+
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+
+public class Cert {
+
+ public static SignatureAlgorithm mapAlgorithmToJss(String algname) {
+ if (algname.equals("MD5withRSA"))
+ return SignatureAlgorithm.RSASignatureWithMD5Digest;
+ else if (algname.equals("MD2withRSA"))
+ return SignatureAlgorithm.RSASignatureWithMD2Digest;
+ else if (algname.equals("SHA1withRSA"))
+ return SignatureAlgorithm.RSASignatureWithSHA1Digest;
+ else if (algname.equals("SHA1withDSA"))
+ return SignatureAlgorithm.DSASignatureWithSHA1Digest;
+ else if (algname.equals("SHA256withRSA"))
+ return SignatureAlgorithm.RSASignatureWithSHA256Digest;
+ else if (algname.equals("SHA512withRSA"))
+ return SignatureAlgorithm.RSASignatureWithSHA512Digest;
+ else if (algname.equals("SHA1withEC"))
+ return SignatureAlgorithm.ECSignatureWithSHA1Digest;
+ else if (algname.equals("SHA256withEC"))
+ return SignatureAlgorithm.ECSignatureWithSHA256Digest;
+ else if (algname.equals("SHA384withEC"))
+ return SignatureAlgorithm.ECSignatureWithSHA384Digest;
+ else if (algname.equals("SHA512withEC"))
+ return SignatureAlgorithm.ECSignatureWithSHA512Digest;
+ return null;
+ }
+
+ public static String stripBrackets(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;
+ }
+
+ 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;
+ }
+
+ public static String stripCertBrackets(String s) {
+ return stripBrackets(s);
+ }
+
+ // private static BASE64Decoder mDecoder = new BASE64Decoder();
+ public static X509CertImpl mapCert(String mime64)
+ throws IOException {
+ mime64 = stripCertBrackets(mime64.trim());
+ String newval = normalizeCertStr(mime64);
+ // byte rawPub[] = mDecoder.decodeBuffer(newval);
+ byte rawPub[] = Utils.base64decode(newval);
+ X509CertImpl 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[] = mDecoder.decodeBuffer(newval);
+ byte rawPub[] = Utils.base64decode(newval);
+ PKCS7 p7 = null;
+
+ try {
+ p7 = new PKCS7(rawPub);
+ } catch (Exception e) {
+ throw new IOException("p7 is null");
+ }
+ return p7.getCertificates();
+ }
+
+ public static X509CRL mapCRL(String mime64)
+ throws IOException {
+ mime64 = stripCRLBrackets(mime64.trim());
+ String newval = normalizeCertStr(mime64);
+ // byte rawPub[] = mDecoder.decodeBuffer(newval);
+ byte rawPub[] = Utils.base64decode(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[] = Utils.base64decode(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 normalizeCertStrAndReq(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;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/util/Fmt.java b/base/util/src/com/netscape/cmsutil/util/Fmt.java
new file mode 100644
index 000000000..a24b8d090
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/util/Fmt.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.cmsutil.util;
+
+// Fmt - some simple single-arg sprintf-like routines
+//
+// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+//
+// Visit the ACME Labs Java page for up-to-date versions of this and other
+// fine Java utilities: http://www.acme.com/java/
+
+/// Some simple single-arg sprintf-like routines.
+// <P>
+// It is apparently impossible to declare a Java method that accepts
+// variable numbers of any type of argument. You can declare it to take
+// Objects, but numeric variables and constants are not in fact Objects.
+// <P>
+// However, using the built-in string concatenation, it's almost as
+// convenient to make a series of single-argument formatting routines.
+// <P>
+// Fmt can format the following types:
+// <BLOCKQUOTE><CODE>
+// byte short int long float double char String Object
+// </CODE></BLOCKQUOTE>
+// For each type there is a set of overloaded methods, each returning
+// a formatted String. There's the plain formatting version:
+// <BLOCKQUOTE><PRE>
+// Fmt.fmt( x )
+// </PRE></BLOCKQUOTE>
+// There's a version specifying a minimum field width:
+// <BLOCKQUOTE><PRE>
+// Fmt.fmt( x, minWidth )
+// </PRE></BLOCKQUOTE>
+// And there's a version that takes flags:
+// <BLOCKQUOTE><PRE>
+// Fmt.fmt( x, minWidth, flags )
+// </PRE></BLOCKQUOTE>
+// Currently available flags are:
+// <BLOCKQUOTE><PRE>
+// Fmt.ZF - zero-fill
+// Fmt.LJ - left justify
+// Fmt.HX - hexadecimal
+// Fmt.OC - octal
+// </PRE></BLOCKQUOTE>
+// The HX and OC flags imply unsigned output.
+// <P>
+// For doubles and floats, there's a significant-figures parameter before
+// the flags:
+// <BLOCKQUOTE><PRE>
+// Fmt.fmt( d )
+// Fmt.fmt( d, minWidth )
+// Fmt.fmt( d, minWidth, sigFigs )
+// Fmt.fmt( d, minWidth, sigFigs, flags )
+// </PRE></BLOCKQUOTE>
+// <P>
+// <A HREF="/resources/classes/Acme/Fmt.java">Fetch the software.</A><BR>
+// <A HREF="/resources/classes/Acme.tar.Z">Fetch the entire Acme package.</A>
+// <HR>
+// Similar classes:
+// <UL>
+// <LI> Andrew Scherpbier's <A HREF="http://www.sdsu.edu/doc/java-SDSU/sdsu.FormatString.html">FormatString</A>
+// Tries to allow variable numbers of arguments by
+// supplying overloaded routines with different combinations of parameters,
+// but doesn't actually supply that many. The floating point conversion
+// is described as "very incomplete".
+// <LI> Core Java's <A HREF="http://www.apl.jhu.edu/~hall/java/CoreJava-Format.html">Format</A>.
+// The design seems a little weird. They want you to create an instance,
+// passing the format string to the constructor, and then call an instance
+// method with your data to do the actual formatting. The extra steps are
+// pointless; better to just use static methods.
+// </UL>
+
+public class Fmt {
+
+ // Flags.
+ /// Zero-fill.
+ public static final int ZF = 1;
+ /// Left justify.
+ public static final int LJ = 2;
+ /// Hexadecimal.
+ public static final int HX = 4;
+ /// Octal.
+ public static final int OC = 8;
+ // Was a number - internal use.
+ private static final int WN = 16;
+
+ // byte
+ public static String fmt(byte b) {
+ return fmt(b, 0, 0);
+ }
+
+ public static String fmt(byte b, int minWidth) {
+ return fmt(b, minWidth, 0);
+ }
+
+ public static String fmt(byte b, int minWidth, int flags) {
+ boolean hexadecimal = ((flags & HX) != 0);
+ boolean octal = ((flags & OC) != 0);
+
+ if (hexadecimal)
+ return fmt(Integer.toString(b & 0xff, 16), minWidth, flags | WN);
+ else if (octal)
+ return fmt(Integer.toString(b & 0xff, 8), minWidth, flags | WN);
+ else
+ return fmt(Integer.toString(b & 0xff), minWidth, flags | WN);
+ }
+
+ // short
+ public static String fmt(short s) {
+ return fmt(s, 0, 0);
+ }
+
+ public static String fmt(short s, int minWidth) {
+ return fmt(s, minWidth, 0);
+ }
+
+ public static String fmt(short s, int minWidth, int flags) {
+ boolean hexadecimal = ((flags & HX) != 0);
+ boolean octal = ((flags & OC) != 0);
+
+ if (hexadecimal)
+ return fmt(
+ Integer.toString(s & 0xffff, 16), minWidth, flags | WN);
+ else if (octal)
+ return fmt(
+ Integer.toString(s & 0xffff, 8), minWidth, flags | WN);
+ else
+ return fmt(Integer.toString(s), minWidth, flags | WN);
+ }
+
+ // int
+ public static String fmt(int i) {
+ return fmt(i, 0, 0);
+ }
+
+ public static String fmt(int i, int minWidth) {
+ return fmt(i, minWidth, 0);
+ }
+
+ public static String fmt(int i, int minWidth, int flags) {
+ boolean hexadecimal = ((flags & HX) != 0);
+ boolean octal = ((flags & OC) != 0);
+
+ if (hexadecimal)
+ return fmt(
+ Long.toString(i & 0xffffffffL, 16), minWidth, flags | WN);
+ else if (octal)
+ return fmt(
+ Long.toString(i & 0xffffffffL, 8), minWidth, flags | WN);
+ else
+ return fmt(Integer.toString(i), minWidth, flags | WN);
+ }
+
+ // long
+ public static String fmt(long l) {
+ return fmt(l, 0, 0);
+ }
+
+ public static String fmt(long l, int minWidth) {
+ return fmt(l, minWidth, 0);
+ }
+
+ public static String fmt(long l, int minWidth, int flags) {
+ boolean hexadecimal = ((flags & HX) != 0);
+ boolean octal = ((flags & OC) != 0);
+
+ if (hexadecimal) {
+ if ((l & 0xf000000000000000L) != 0)
+ return fmt(
+ Long.toString(l >>> 60, 16) +
+ fmt(l & 0x0fffffffffffffffL, 15, HX | ZF),
+ minWidth, flags | WN);
+ else
+ return fmt(Long.toString(l, 16), minWidth, flags | WN);
+ } else if (octal) {
+ if ((l & 0x8000000000000000L) != 0)
+ return fmt(
+ Long.toString(l >>> 63, 8) +
+ fmt(l & 0x7fffffffffffffffL, 21, OC | ZF),
+ minWidth, flags | WN);
+ else
+ return fmt(Long.toString(l, 8), minWidth, flags | WN);
+ } else
+ return fmt(Long.toString(l), minWidth, flags | WN);
+ }
+
+ // float
+ public static String fmt(float f) {
+ return fmt(f, 0, 0, 0);
+ }
+
+ public static String fmt(float f, int minWidth) {
+ return fmt(f, minWidth, 0, 0);
+ }
+
+ public static String fmt(float f, int minWidth, int sigFigs) {
+ return fmt(f, minWidth, sigFigs, 0);
+ }
+
+ public static String fmt(float f, int minWidth, int sigFigs, int flags) {
+ if (sigFigs != 0)
+ return fmt(
+ sigFigFix(Float.toString(f), sigFigs), minWidth,
+ flags | WN);
+ else
+ return fmt(Float.toString(f), minWidth, flags | WN);
+ }
+
+ // double
+ public static String fmt(double d) {
+ return fmt(d, 0, 0, 0);
+ }
+
+ public static String fmt(double d, int minWidth) {
+ return fmt(d, minWidth, 0, 0);
+ }
+
+ public static String fmt(double d, int minWidth, int sigFigs) {
+ return fmt(d, minWidth, sigFigs, 0);
+ }
+
+ public static String fmt(double d, int minWidth, int sigFigs, int flags) {
+ if (sigFigs != 0)
+ return fmt(
+ sigFigFix(doubleToString(d), sigFigs), minWidth,
+ flags | WN);
+ else
+ return fmt(doubleToString(d), minWidth, flags | WN);
+ }
+
+ // char
+ public static String fmt(char c) {
+ return fmt(c, 0, 0);
+ }
+
+ public static String fmt(char c, int minWidth) {
+ return fmt(c, minWidth, 0);
+ }
+
+ public static String fmt(char c, int minWidth, int flags) {
+ // return fmt( Character.toString( c ), minWidth, flags );
+ // Character currently lacks a static toString method. Workaround
+ // is to make a temporary instance and use the instance toString.
+ return fmt(Character.valueOf(c).toString(), minWidth, flags);
+ }
+
+ // Object
+ public static String fmt(Object o) {
+ return fmt(o, 0, 0);
+ }
+
+ public static String fmt(Object o, int minWidth) {
+ return fmt(o, minWidth, 0);
+ }
+
+ public static String fmt(Object o, int minWidth, int flags) {
+ return fmt(o.toString(), minWidth, flags);
+ }
+
+ // String
+ public static String fmt(String s) {
+ return fmt(s, 0, 0);
+ }
+
+ public static String fmt(String s, int minWidth) {
+ return fmt(s, minWidth, 0);
+ }
+
+ public static String fmt(String s, int minWidth, int flags) {
+ int len = s.length();
+ boolean zeroFill = ((flags & ZF) != 0);
+ boolean leftJustify = ((flags & LJ) != 0);
+ boolean hexadecimal = ((flags & HX) != 0);
+ boolean octal = ((flags & OC) != 0);
+ boolean wasNumber = ((flags & WN) != 0);
+
+ if ((hexadecimal || octal || zeroFill) && !wasNumber)
+ throw new InternalError("Acme.Fmt: number flag on a non-number");
+ if (zeroFill && leftJustify)
+ throw new InternalError("Acme.Fmt: zero-fill left-justify is silly");
+ if (hexadecimal && octal)
+ throw new InternalError("Acme.Fmt: can't do both hex and octal");
+ if (len >= minWidth)
+ return s;
+ int fillWidth = minWidth - len;
+ StringBuffer fill = new StringBuffer(fillWidth);
+
+ for (int i = 0; i < fillWidth; ++i)
+ if (zeroFill)
+ fill.append('0');
+ else
+ fill.append(' ');
+ if (leftJustify)
+ return s + fill;
+ else if (zeroFill && s.startsWith("-"))
+ return "-" + fill + s.substring(1);
+ else
+ return fill + s;
+ }
+
+ // Internal routines.
+
+ private static String sigFigFix(String s, int sigFigs) {
+ // First dissect the floating-point number string into sign,
+ // integer part, fraction part, and exponent.
+ String sign;
+ String unsigned;
+
+ if (s.startsWith("-") || s.startsWith("+")) {
+ sign = s.substring(0, 1);
+ unsigned = s.substring(1);
+ } else {
+ sign = "";
+ unsigned = s;
+ }
+ String mantissa;
+ String exponent;
+ int eInd = unsigned.indexOf('e');
+
+ if (eInd == -1) {
+ mantissa = unsigned;
+ exponent = "";
+ } else {
+ mantissa = unsigned.substring(0, eInd);
+ exponent = unsigned.substring(eInd);
+ }
+ StringBuffer number, fraction;
+ int dotInd = mantissa.indexOf('.');
+
+ if (dotInd == -1) {
+ number = new StringBuffer(mantissa);
+ fraction = new StringBuffer("");
+ } else {
+ number = new StringBuffer(mantissa.substring(0, dotInd));
+ fraction = new StringBuffer(mantissa.substring(dotInd + 1));
+ }
+
+ int numFigs = number.length();
+ int fracFigs = fraction.length();
+
+ if ((numFigs == 0 || number.toString().equals("0")) &&
+ fracFigs > 0) {
+ // Don't count leading zeros in the fraction.
+ numFigs = 0;
+ for (int i = 0; i < fraction.length(); ++i) {
+ if (fraction.charAt(i) != '0')
+ break;
+ --fracFigs;
+ }
+ }
+ int mantFigs = numFigs + fracFigs;
+
+ if (sigFigs > mantFigs) {
+ // We want more figures; just append zeros to the fraction.
+ for (int i = mantFigs; i < sigFigs; ++i)
+ fraction.append('0');
+ } else if (sigFigs < mantFigs && sigFigs >= numFigs) {
+ // Want fewer figures in the fraction; chop.
+ fraction.setLength(
+ fraction.length() - (fracFigs - (sigFigs - numFigs)));
+ // Round?
+ } else if (sigFigs < numFigs) {
+ // Want fewer figures in the number; turn them to zeros.
+ fraction.setLength(0); // should already be zero, but make sure
+ for (int i = sigFigs; i < numFigs; ++i)
+ number.setCharAt(i, '0');
+ // Round?
+ }
+ // Else sigFigs == mantFigs, which is fine.
+
+ if (fraction.length() == 0)
+ return sign + number + exponent;
+ else
+ return sign + number + "." + fraction + exponent;
+ }
+
+ /// Improved version of Double.toString(), returns more decimal places.
+ // <P>
+ // The JDK 1.0.2 version of Double.toString() returns only six decimal
+ // places on some systems. In JDK 1.1 full precision is returned on
+ // all platforms.
+ // @deprecated
+ // @see java.lang.Double.toString
+ public static String doubleToString(double d) {
+ // Handle special numbers first, to avoid complications.
+ if (Double.isNaN(d))
+ return "NaN";
+ if (d == Double.NEGATIVE_INFINITY)
+ return "-Inf";
+ if (d == Double.POSITIVE_INFINITY)
+ return "Inf";
+
+ // Grab the sign, and then make the number positive for simplicity.
+ boolean negative = false;
+
+ if (d < 0.0D) {
+ negative = true;
+ d = -d;
+ }
+
+ // Get the native version of the unsigned value, as a template.
+ String unsStr = Double.toString(d);
+
+ // Dissect out the exponent.
+ String mantStr, expStr;
+ int exp;
+ int eInd = unsStr.indexOf('e');
+
+ if (eInd == -1) {
+ mantStr = unsStr;
+ expStr = "";
+ exp = 0;
+ } else {
+ mantStr = unsStr.substring(0, eInd);
+ expStr = unsStr.substring(eInd + 1);
+ if (expStr.startsWith("+"))
+ exp = Integer.parseInt(expStr.substring(1));
+ else
+ exp = Integer.parseInt(expStr);
+ }
+
+ // Dissect out the number part.
+ String numStr;
+ int dotInd = mantStr.indexOf('.');
+
+ if (dotInd == -1)
+ numStr = mantStr;
+ else
+ numStr = mantStr.substring(0, dotInd);
+ long num;
+
+ if (numStr.length() == 0)
+ num = 0;
+ else
+ num = Integer.parseInt(numStr);
+
+ // Build the new mantissa.
+ StringBuffer newMantBuf = new StringBuffer(numStr + ".");
+ double p = Math.pow(10, exp);
+ double frac = d - num * p;
+ String digits = "0123456789";
+ int nDigits = 16 - numStr.length(); // about 16 digits in a double
+
+ for (int i = 0; i < nDigits; ++i) {
+ p /= 10.0D;
+ int dig = (int) (frac / p);
+
+ if (dig < 0)
+ dig = 0;
+ if (dig > 9)
+ dig = 9;
+ newMantBuf.append(digits.charAt(dig));
+ frac -= dig * p;
+ }
+
+ if ((int) (frac / p + 0.5D) == 1) {
+ // Round up.
+ boolean roundMore = true;
+
+ for (int i = newMantBuf.length() - 1; i >= 0; --i) {
+ int dig = digits.indexOf(newMantBuf.charAt(i));
+
+ if (dig == -1)
+ continue;
+ ++dig;
+ if (dig == 10) {
+ newMantBuf.setCharAt(i, '0');
+ continue;
+ }
+ newMantBuf.setCharAt(i, digits.charAt(dig));
+ roundMore = false;
+ break;
+ }
+ if (roundMore) {
+ // If this happens, we need to prepend a 1. But I haven't
+ // found a test case yet, so I'm leaving it out for now.
+ // But if you get this message, please let me know!
+ newMantBuf.append("ROUNDMORE");
+ }
+ }
+
+ // Chop any trailing zeros.
+ int len = newMantBuf.length();
+
+ while (newMantBuf.charAt(len - 1) == '0')
+ newMantBuf.setLength(--len);
+ // And chop a trailing dot, if any.
+ if (newMantBuf.charAt(len - 1) == '.')
+ newMantBuf.setLength(--len);
+
+ // Done.
+ return (negative ? "-" : "") +
+ newMantBuf +
+ (expStr.length() != 0 ? ("e" + expStr) : "");
+ }
+
+ /******************************************************************************
+ * /// Test program.
+ * public static void main( String[] args )
+ * {
+ * System.out.println( "Starting tests." );
+ * show( Fmt.fmt( "Hello there." ) );
+ * show( Fmt.fmt( 123 ) );
+ * show( Fmt.fmt( 123, 10 ) );
+ * show( Fmt.fmt( 123, 10, Fmt.ZF ) );
+ * show( Fmt.fmt( 123, 10, Fmt.LJ ) );
+ * show( Fmt.fmt( -123 ) );
+ * show( Fmt.fmt( -123, 10 ) );
+ * show( Fmt.fmt( -123, 10, Fmt.ZF ) );
+ * show( Fmt.fmt( -123, 10, Fmt.LJ ) );
+ * show( Fmt.fmt( (byte) 0xbe, 22, Fmt.OC ) );
+ * show( Fmt.fmt( (short) 0xbabe, 22, Fmt.OC ) );
+ * show( Fmt.fmt( 0xcafebabe, 22, Fmt.OC ) );
+ * show( Fmt.fmt( 0xdeadbeefcafebabeL, 22, Fmt.OC ) );
+ * show( Fmt.fmt( 0x8000000000000000L, 22, Fmt.OC ) );
+ * show( Fmt.fmt( (byte) 0xbe, 16, Fmt.HX ) );
+ * show( Fmt.fmt( (short) 0xbabe, 16, Fmt.HX ) );
+ * show( Fmt.fmt( 0xcafebabe, 16, Fmt.HX ) );
+ * show( Fmt.fmt( 0xdeadbeefcafebabeL, 16, Fmt.HX ) );
+ * show( Fmt.fmt( 0x8000000000000000L, 16, Fmt.HX ) );
+ * show( Fmt.fmt( 'c' ) );
+ * show( Fmt.fmt( new java.util.Date() ) );
+ * show( Fmt.fmt( 123.456F ) );
+ * show( Fmt.fmt( 123456000000000000.0F ) );
+ * show( Fmt.fmt( 123.456F, 0, 8 ) );
+ * show( Fmt.fmt( 123.456F, 0, 7 ) );
+ * show( Fmt.fmt( 123.456F, 0, 6 ) );
+ * show( Fmt.fmt( 123.456F, 0, 5 ) );
+ * show( Fmt.fmt( 123.456F, 0, 4 ) );
+ * show( Fmt.fmt( 123.456F, 0, 3 ) );
+ * show( Fmt.fmt( 123.456F, 0, 2 ) );
+ * show( Fmt.fmt( 123.456F, 0, 1 ) );
+ * show( Fmt.fmt( 123456000000000000.0F, 0, 4 ) );
+ * show( Fmt.fmt( -123.456F, 0, 4 ) );
+ * show( Fmt.fmt( -123456000000000000.0F, 0, 4 ) );
+ * show( Fmt.fmt( 123.0F ) );
+ * show( Fmt.fmt( 123.0D ) );
+ * show( Fmt.fmt( 1.234567890123456789F ) );
+ * show( Fmt.fmt( 1.234567890123456789D ) );
+ * show( Fmt.fmt( 1234567890123456789F ) );
+ * show( Fmt.fmt( 1234567890123456789D ) );
+ * show( Fmt.fmt( 0.000000000000000000001234567890123456789F ) );
+ * show( Fmt.fmt( 0.000000000000000000001234567890123456789D ) );
+ * show( Fmt.fmt( 12300.0F ) );
+ * show( Fmt.fmt( 12300.0D ) );
+ * show( Fmt.fmt( 123000.0F ) );
+ * show( Fmt.fmt( 123000.0D ) );
+ * show( Fmt.fmt( 1230000.0F ) );
+ * show( Fmt.fmt( 1230000.0D ) );
+ * show( Fmt.fmt( 12300000.0F ) );
+ * show( Fmt.fmt( 12300000.0D ) );
+ * show( Fmt.fmt( Float.NaN ) );
+ * show( Fmt.fmt( Float.POSITIVE_INFINITY ) );
+ * show( Fmt.fmt( Float.NEGATIVE_INFINITY ) );
+ * show( Fmt.fmt( Double.NaN ) );
+ * show( Fmt.fmt( Double.POSITIVE_INFINITY ) );
+ * show( Fmt.fmt( Double.NEGATIVE_INFINITY ) );
+ * show( Fmt.fmt( 1.0F / 8.0F ) );
+ * show( Fmt.fmt( 1.0D / 8.0D ) );
+ * System.out.println( "Done with tests." );
+ * }
+ *
+ * private static void show( String str )
+ * {
+ * System.out.println( "#" + str + "#" );
+ * }
+ ******************************************************************************/
+
+}
diff --git a/base/util/src/com/netscape/cmsutil/util/HMACDigest.java b/base/util/src/com/netscape/cmsutil/util/HMACDigest.java
new file mode 100644
index 000000000..09bf53bbf
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/util/HMACDigest.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.cmsutil.util;
+
+import java.security.MessageDigest;
+
+/**
+ * This class implements the HMAC algorithm specified in RFC 2104 using
+ * any MessageDigest.
+ *
+ * @author mikep
+ * @version $Revision$, $Date$
+ * @see java.security.MessageDigest
+ */
+public class HMACDigest implements Cloneable {
+ public static final int PAD_BYTES = 64;
+ public static final int IPAD = 0x36;
+ public static final int OPAD = 0x5C;
+
+ /**
+ * inner padding - key XORd with ipad
+ */
+ private byte[] mKeyIpad = new byte[PAD_BYTES];
+
+ /**
+ * outer padding - key XORd with opad
+ */
+ private byte[] mKeyOpad = new byte[PAD_BYTES];
+
+ /**
+ * The real MessageDigest
+ */
+ private MessageDigest mMD = null;
+
+ /**
+ * Creates an HMACDigest
+ *
+ * @param md The MessageDigest to be used for the HMAC calculation. It
+ * must be clonable.
+ */
+ public HMACDigest(MessageDigest md) {
+ mMD = md;
+ }
+
+ /**
+ * Creates an HMACDigest and initializes the HMAC function
+ * with the given key.
+ *
+ * @param md The MessageDigest to be used for the HMAC calculation. It
+ * must be clonable.
+ * @param key The key value to be used in the HMAC calculation
+ */
+ public HMACDigest(MessageDigest md, byte[] key) {
+ this(md);
+ init(key);
+ }
+
+ /**
+ * Return the MessageDigest used for this HMAC
+ */
+ public MessageDigest getMessageDigest() {
+ return mMD;
+ }
+
+ /**
+ * Initialize the HMAC function
+ *
+ * The HMAC transform looks like:
+ *
+ * hash(key XOR opad, hash(key XOR ipad, text))
+ *
+ * where key is an n byte key
+ * ipad is the byte 0x36 repeated 64 times
+ * opad is the byte 0x5c repeated 64 times
+ * and text is the data being protected
+ *
+ * This routine must be called after every reset.
+ *
+ * @param key The password used to protect the hash value
+ */
+ public void init(byte[] key) {
+ int i;
+
+ reset();
+
+ // If the key is longer than 64 bytes, just hash it down
+ if (key.length > 64) {
+ key = mMD.digest(key);
+ mMD.reset(); // Redundant?
+ }
+
+ // Copy the key. Truncate if key is too long
+ for (i = 0; i < key.length && i < PAD_BYTES; i++) {
+ mKeyIpad[i] = key[i];
+ mKeyOpad[i] = key[i];
+ }
+
+ // XOR in the pads
+ for (i = 0; i < PAD_BYTES; i++) {
+ mKeyIpad[i] ^= IPAD;
+ mKeyOpad[i] ^= OPAD;
+ }
+
+ mMD.update(mKeyIpad);
+
+ // Hmmm, we really shouldn't key Opad around in memory for so
+ // long, but it would just force the user to key their key around
+ // until digest() time. Oh well, at least clear the key and Ipad
+ for (i = 0; i < PAD_BYTES; i++) {
+ mKeyIpad[i] = 0;
+ }
+ for (i = 0; i < key.length; i++) {
+ key[0] = 0;
+ }
+ }
+
+ /**
+ * Updates the digest using the specified array of bytes.
+ *
+ * @param input the array of bytes.
+ */
+ public void update(byte[] input) {
+ mMD.update(input);
+ }
+
+ /**
+ * Completes the HMAC computation with the outer pad
+ * The digest is reset after this call is made.
+ *
+ * @return the array of bytes for the resulting hash value.
+ */
+ public byte[] digest() {
+ byte[] finalDigest;
+ byte[] innerDigest = mMD.digest();
+
+ mMD.reset(); // Redundant?
+ mMD.update(mKeyOpad);
+ mMD.update(innerDigest);
+ finalDigest = mMD.digest();
+ reset(); // Clear pad arrays
+ return finalDigest;
+ }
+
+ /**
+ * Resets the digest for further use.
+ */
+ public void reset() {
+ int i;
+
+ mMD.reset();
+
+ // Clear out the pads
+ for (i = 0; i < PAD_BYTES; i++) {
+ mKeyIpad[i] = 0;
+ mKeyOpad[i] = 0;
+ }
+ }
+
+ /**
+ * Clone the HMACDigest
+ *
+ * @return a clone if the implementation is cloneable.
+ * @exception CloneNotSupportedException if this is called on a
+ * MessageDigest implementation that does not support <code>Cloneable</code>.
+ */
+ public Object clone() throws CloneNotSupportedException {
+ int i;
+
+ HMACDigest hd = (HMACDigest) super.clone();
+
+ hd.mKeyOpad = new byte[PAD_BYTES];
+ hd.mKeyIpad = new byte[PAD_BYTES];
+
+ for (i = 0; i < PAD_BYTES; i++) {
+ hd.mKeyOpad[i] = mKeyOpad[i];
+ hd.mKeyIpad[i] = mKeyIpad[i];
+ }
+
+ hd.mMD = (MessageDigest) mMD.clone();
+ return hd;
+ }
+
+}
diff --git a/base/util/src/com/netscape/cmsutil/util/Utils.java b/base/util/src/com/netscape/cmsutil/util/Utils.java
new file mode 100644
index 000000000..303566416
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/util/Utils.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.cmsutil.util;
+
+import org.apache.commons.codec.binary.Base64;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Vector;
+
+public class Utils {
+ /**
+ * Checks if this is NT.
+ */
+ public static boolean isNT() {
+ return File.separator.equals("\\");
+ }
+
+ public static boolean isUnix() {
+ return File.separator.equals("/");
+ }
+
+ public static boolean exec(String cmd) {
+ 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();
+
+ 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 static String SpecialURLDecode(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();
+ }
+
+ public static byte[] SpecialDecode(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.toByteArray();
+ }
+
+ public static 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().toUpperCase();
+ }
+
+ public static void checkHost(String hostname) throws UnknownHostException {
+ InetAddress.getByName(hostname);
+ }
+
+ public static void copy(String orig, String dest) {
+ try {
+ BufferedReader in = new BufferedReader(new FileReader(orig));
+ PrintWriter out = new PrintWriter(
+ new BufferedWriter(new FileWriter(dest)));
+ String line = "";
+ while (in.ready()) {
+ line = in.readLine();
+ if (line != null)
+ out.println(line);
+ }
+ in.close();
+ out.close();
+ } catch (Exception ee) {
+ }
+ }
+
+ 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<String> v) {
+ String s[] = new String[v.size()];
+
+ v.copyInto(s);
+ return s;
+ }
+
+ public static String base64encode(byte[] bytes) {
+ String string = new Base64(64).encodeToString(bytes);
+ return string;
+ }
+
+ public static byte[] base64decode(String string) {
+ byte[] bytes = Base64.decodeBase64(string);
+ return bytes;
+ }
+}
diff --git a/base/util/src/com/netscape/cmsutil/xml/XMLObject.java b/base/util/src/com/netscape/cmsutil/xml/XMLObject.java
new file mode 100644
index 000000000..ed2fb67ee
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/xml/XMLObject.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.cmsutil.xml;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.util.Vector;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+import org.xml.sax.SAXException;
+
+public class XMLObject {
+ private Document mDoc = null;
+
+ public XMLObject() throws ParserConfigurationException {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = factory.newDocumentBuilder();
+ mDoc = docBuilder.newDocument();
+ }
+
+ public XMLObject(InputStream s)
+ throws SAXException, IOException, ParserConfigurationException {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = factory.newDocumentBuilder();
+ mDoc = docBuilder.parse(s);
+ }
+
+ public XMLObject(File f)
+ throws SAXException, IOException, ParserConfigurationException {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = factory.newDocumentBuilder();
+ mDoc = docBuilder.parse(f);
+ }
+
+ public Document getDocument() {
+ return mDoc;
+ }
+
+ /**
+ * Each document should have 1 root only. This method should be called once.
+ */
+ public Node createRoot(String name) {
+ Element root = mDoc.createElement(name);
+ mDoc.appendChild(root);
+ return (Node) root;
+ }
+
+ public Node getRoot() {
+ return mDoc.getFirstChild();
+ }
+
+ /**
+ * If you have duplicate containers, then this method will return the
+ * first container in the list.
+ */
+ public Node getContainer(String tagname) {
+ NodeList list = mDoc.getElementsByTagName(tagname);
+ if (list.getLength() > 0)
+ return list.item(0);
+ return null;
+ }
+
+ public Node createContainer(Node containerParent, String containerName) {
+ Element node = mDoc.createElement(containerName);
+ containerParent.appendChild(node);
+ return (Node) node;
+ }
+
+ public void addItemToContainer(Node container, String tagname, String value) {
+ Element node = mDoc.createElement(tagname);
+ Text text = mDoc.createTextNode(value);
+ node.appendChild(text);
+ container.appendChild(node);
+ }
+
+ public String getValue(String tagname) {
+ Node n = getContainer(tagname);
+
+ if (n != null) {
+ NodeList c = n.getChildNodes();
+ if (c.getLength() == 0)
+ return null;
+ Node item = c.item(0);
+ return item.getNodeValue();
+ }
+
+ return null;
+ }
+
+ public Vector<String> getAllValues(String tagname) {
+ Vector<String> v = new Vector<String>();
+ NodeList nodes = mDoc.getElementsByTagName(tagname);
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Node n = nodes.item(i);
+ NodeList c = n.getChildNodes();
+ if (c.getLength() > 0) {
+ Node nn = c.item(0);
+ if (nn.getNodeType() == Node.TEXT_NODE)
+ v.addElement(nn.getNodeValue());
+ }
+ }
+ return v;
+ }
+
+ public Vector<String> getValuesFromContainer(Node container, String tagname) {
+ Vector<String> v = new Vector<String>();
+ NodeList c = container.getChildNodes();
+ int len = c.getLength();
+ for (int i = 0; i < len; i++) {
+ Node subchild = c.item(i);
+ if (subchild.getNodeName().equals(tagname)) {
+ NodeList grandchildren = subchild.getChildNodes();
+ if (grandchildren.getLength() > 0) {
+ Node grandchild = grandchildren.item(0);
+ if (grandchild.getNodeType() == Node.TEXT_NODE)
+ v.addElement(grandchild.getNodeValue());
+ }
+ }
+ }
+
+ return v;
+ }
+
+ public byte[] toByteArray() throws TransformerConfigurationException, TransformerException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ TransformerFactory tranFactory = TransformerFactory.newInstance();
+ Transformer aTransformer = tranFactory.newTransformer();
+ Source src = new DOMSource(mDoc);
+ Result dest = new StreamResult(bos);
+ aTransformer.transform(src, dest);
+ return bos.toByteArray();
+ }
+
+ public void output(OutputStream os)
+ throws TransformerConfigurationException, TransformerException {
+ TransformerFactory tranFactory = TransformerFactory.newInstance();
+ Transformer aTransformer = tranFactory.newTransformer();
+ Source src = new DOMSource(mDoc);
+ Result dest = new StreamResult(os);
+ aTransformer.transform(src, dest);
+ }
+
+ public String toXMLString() throws TransformerConfigurationException, TransformerException {
+ TransformerFactory tranFactory = TransformerFactory.newInstance();
+ Transformer transformer = tranFactory.newTransformer();
+ Source src = new DOMSource(mDoc);
+ StreamResult dest = new StreamResult(new StringWriter());
+ transformer.transform(src, dest);
+ String xmlString = dest.getWriter().toString();
+ return xmlString;
+ }
+}
diff --git a/base/util/src/netscape/net/NetworkClient.java b/base/util/src/netscape/net/NetworkClient.java
new file mode 100644
index 000000000..ae8cdfcf4
--- /dev/null
+++ b/base/util/src/netscape/net/NetworkClient.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 netscape.net;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+/**
+ * This is the base class for network clients.
+ *
+ * @version 1.21, 08/07/97
+ * @author Jonathan Payne
+ */
+public class NetworkClient {
+ /** Socket for communicating with server. */
+ protected Socket serverSocket = null;
+
+ /** Stream for printing to the server. */
+ public PrintStream serverOutput;
+
+ /** Buffered stream for reading replies from server. */
+ public InputStream serverInput;
+
+ /** Open a connection to the server. */
+ public void openServer(String server, int port)
+ throws IOException, UnknownHostException {
+ if (serverSocket != null)
+ closeServer();
+ serverSocket = doConnect(server, port);
+ serverOutput = new PrintStream(new BufferedOutputStream(serverSocket.getOutputStream()),
+ true);
+ serverInput = new BufferedInputStream(serverSocket.getInputStream());
+ }
+
+ /**
+ * Return a socket connected to the server, with any
+ * appropriate options pre-established
+ */
+ protected Socket doConnect(String server, int port)
+ throws IOException, UnknownHostException {
+ return new Socket(server, port);
+ }
+
+ /** Close an open connection to the server. */
+ public void closeServer() throws IOException {
+ if (!serverIsOpen()) {
+ return;
+ }
+ serverSocket.close();
+ serverSocket = null;
+ serverInput = null;
+ serverOutput = null;
+ }
+
+ /** Return server connection status */
+ public boolean serverIsOpen() {
+ return serverSocket != null;
+ }
+
+ /** Create connection with host <i>host</i> on port <i>port</i> */
+ public NetworkClient(String host, int port) throws IOException {
+ openServer(host, port);
+ }
+
+ public NetworkClient() {
+ }
+}
diff --git a/base/util/src/netscape/net/TransferProtocolClient.java b/base/util/src/netscape/net/TransferProtocolClient.java
new file mode 100644
index 000000000..76e3a9c21
--- /dev/null
+++ b/base/util/src/netscape/net/TransferProtocolClient.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 netscape.net;
+
+import java.io.IOException;
+import java.util.Vector;
+
+/**
+ * This class implements that basic intefaces of transfer protocols.
+ * It is used by subclasses implementing specific protocols.
+ *
+ * @version 1.25, 08/07/97
+ * @author Jonathan Payne
+ */
+
+public class TransferProtocolClient extends NetworkClient {
+ static final boolean debug = false;
+
+ /**
+ * Array of strings (usually 1 entry) for the last reply
+ * from the server.
+ */
+ protected Vector<String> serverResponse = new Vector<String>(1);
+
+ /** code for last reply */
+ protected int lastReplyCode;
+
+ /**
+ * Pulls the response from the server and returns the code as a
+ * number. Returns -1 on failure.
+ */
+ public int readServerResponse() throws IOException {
+ StringBuffer replyBuf = new StringBuffer(32);
+ int c;
+ int continuingCode = -1;
+ int code;
+ String response;
+
+ serverResponse.setSize(0);
+ while (true) {
+ while ((c = serverInput.read()) != -1) {
+ if (c == '\r') {
+ if ((c = serverInput.read()) != '\n')
+ replyBuf.append('\r');
+ }
+ replyBuf.append((char) c);
+ if (c == '\n')
+ break;
+ }
+ response = replyBuf.toString();
+ replyBuf.setLength(0);
+ if (debug) {
+ System.out.print(response);
+ }
+ try {
+ code = Integer.parseInt(response.substring(0, 3));
+ } catch (NumberFormatException e) {
+ code = -1;
+ } catch (StringIndexOutOfBoundsException e) {
+ /* this line doesn't contain a response code, so
+ we just completely ignore it */
+ continue;
+ }
+ serverResponse.addElement(response);
+ if (continuingCode != -1) {
+ /* we've seen a XXX- sequence */
+ if (code != continuingCode ||
+ (response.length() >= 4 && response.charAt(3) == '-')) {
+ continue;
+ } else {
+ /* seen the end of code sequence */
+ continuingCode = -1;
+ break;
+ }
+ } else if (response.length() >= 4 && response.charAt(3) == '-') {
+ continuingCode = code;
+ continue;
+ } else {
+ break;
+ }
+ }
+
+ return lastReplyCode = code;
+ }
+
+ /** Sends command <i>cmd</i> to the server. */
+ public void sendServer(String cmd) {
+ serverOutput.print(cmd);
+ if (debug) {
+ System.out.print("Sending: " + cmd);
+ }
+ }
+
+ /** converts the server response into a string. */
+ public String getResponseString() {
+ return (String) serverResponse.elementAt(0);
+ }
+
+ /** Returns all server response strings. */
+ public Vector<String> getResponseStrings() {
+ return serverResponse;
+ }
+
+ /** standard constructor to host <i>host</i>, port <i>port</i>. */
+ public TransferProtocolClient(String host, int port) throws IOException {
+ super(host, port);
+ }
+
+ /** creates an uninitialized instance of this class. */
+ public TransferProtocolClient() {
+ }
+}
diff --git a/base/util/src/netscape/net/smtp/SmtpClient.java b/base/util/src/netscape/net/smtp/SmtpClient.java
new file mode 100644
index 000000000..40b927b8f
--- /dev/null
+++ b/base/util/src/netscape/net/smtp/SmtpClient.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 netscape.net.smtp;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.net.InetAddress;
+
+import netscape.net.TransferProtocolClient;
+
+/**
+ * This class implements the SMTP client.
+ * You can send a piece of mail by creating a new SmtpClient, calling
+ * the "to" method to add destinations, calling "from" to name the
+ * sender, calling startMessage to return a stream to which you write
+ * the message (with RFC733 headers) and then you finally close the Smtp
+ * Client.
+ *
+ * @version 1.17, 12 Dec 1994
+ * @author James Gosling
+ */
+
+public class SmtpClient extends TransferProtocolClient {
+ SmtpPrintStream message;
+
+ /**
+ * issue the QUIT command to the SMTP server and close the connection.
+ */
+ public void closeServer() throws IOException {
+ if (serverIsOpen()) {
+ closeMessage();
+ issueCommand("QUIT\r\n", 221);
+ super.closeServer();
+ }
+ }
+
+ void issueCommand(String cmd, int expect) throws IOException {
+ sendServer(cmd);
+ int reply;
+ while ((reply = readServerResponse()) != expect)
+ if (reply != 220) {
+ throw new SmtpProtocolException(getResponseString());
+ }
+ }
+
+ private void toCanonical(String s) throws IOException {
+ issueCommand("rcpt to: " + s + "\r\n", 250);
+ }
+
+ public void to(String s) throws IOException {
+ int st = 0;
+ int limit = s.length();
+ int pos = 0;
+ int lastnonsp = 0;
+ int parendepth = 0;
+ boolean ignore = false;
+ while (pos < limit) {
+ int c = s.charAt(pos);
+ if (parendepth > 0) {
+ if (c == '(')
+ parendepth++;
+ else if (c == ')')
+ parendepth--;
+ if (parendepth == 0)
+ if (lastnonsp > st)
+ ignore = true;
+ else
+ st = pos + 1;
+ } else if (c == '(')
+ parendepth++;
+ else if (c == '<')
+ st = lastnonsp = pos + 1;
+ else if (c == '>')
+ ignore = true;
+ else if (c == ',') {
+ if (lastnonsp > st)
+ toCanonical(s.substring(st, lastnonsp));
+ st = pos + 1;
+ ignore = false;
+ } else {
+ if (c > ' ' && !ignore)
+ lastnonsp = pos + 1;
+ else if (st == pos)
+ st++;
+ }
+ pos++;
+ }
+ if (lastnonsp > st)
+ toCanonical(s.substring(st, lastnonsp));
+ }
+
+ public void from(String s) throws IOException {
+ issueCommand("mail from: " + s + "\r\n", 250);
+ }
+
+ /** open a SMTP connection to host <i>host</i>. */
+ private void openServer(String host) throws IOException {
+ openServer(host, 25);
+ issueCommand("helo " + InetAddress.getLocalHost().getHostName() + "\r\n", 250);
+ }
+
+ public PrintStream startMessage() throws IOException {
+ issueCommand("data\r\n", 354);
+ return message = new SmtpPrintStream(serverOutput, this);
+ }
+
+ void closeMessage() throws IOException {
+ if (message != null)
+ message.close();
+ }
+
+ /** New SMTP client connected to host <i>host</i>. */
+ public SmtpClient(String host) throws IOException {
+ super();
+ if (host != null) {
+ try {
+ openServer(host);
+ return;
+ } catch (Exception e) {
+ }
+ }
+ try {
+ String s;
+ try {
+ // java.security.AccessController.beginPrivileged();
+ s = System.getProperty("mail.host");
+ } finally {
+ // java.security.AccessController.endPrivileged();
+ }
+ if (s != null) {
+ openServer(s);
+ return;
+ }
+ } catch (Exception e) {
+ }
+ try {
+ openServer("localhost");
+ } catch (Exception e) {
+ openServer("mailhost");
+ }
+ }
+
+ /** Create an uninitialized SMTP client. */
+ public SmtpClient() throws IOException {
+ this(null);
+ }
+}
+
+class SmtpPrintStream extends java.io.PrintStream {
+ private SmtpClient target;
+ private int lastc = '\n';
+
+ SmtpPrintStream(OutputStream fos, SmtpClient cl) {
+ super(fos);
+ target = cl;
+ }
+
+ public void close() {
+ if (target == null)
+ return;
+ if (lastc != '\n') {
+ write('\r');
+ write('\n');
+ }
+ try {
+ target.issueCommand(".\r\n", 250);
+ target.message = null;
+ out = null;
+ target = null;
+ } catch (IOException e) {
+ }
+ }
+
+ public void write(int b) {
+ try {
+ // quote a dot at the beginning of a line
+ if (lastc == '\n' && b == '.') {
+ out.write('.');
+ }
+
+ // translate NL to CRLF
+ if (b == '\n') {
+ out.write('\r');
+ }
+ out.write(b);
+ lastc = b;
+ } catch (IOException e) {
+ }
+ }
+
+ public void write(byte b[], int off, int len) {
+ try {
+ int lc = lastc;
+ while (--len >= 0) {
+ int c = b[off++];
+
+ // quote a dot at the beginning of a line
+ if (lc == '\n' && c == '.')
+ out.write('.');
+
+ // translate NL to CRLF
+ if (c == '\n') {
+ out.write('\r');
+ }
+ out.write(c);
+ lc = c;
+ }
+ lastc = lc;
+ } catch (IOException e) {
+ }
+ }
+
+ public void print(String s) {
+ int len = s.length();
+ for (int i = 0; i < len; i++) {
+ write(s.charAt(i));
+ }
+ }
+}
diff --git a/base/util/src/netscape/net/smtp/SmtpProtocolException.java b/base/util/src/netscape/net/smtp/SmtpProtocolException.java
new file mode 100644
index 000000000..9ffe5d95b
--- /dev/null
+++ b/base/util/src/netscape/net/smtp/SmtpProtocolException.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 netscape.net.smtp;
+
+import java.io.IOException;
+
+/**
+ * This exeception is thrown when unexpected results are returned during
+ * an SMTP session.
+ */
+public class SmtpProtocolException extends IOException {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5586603317525864401L;
+
+ SmtpProtocolException(String s) {
+ super(s);
+ }
+}
diff --git a/base/util/src/netscape/security/acl/AclEntryImpl.java b/base/util/src/netscape/security/acl/AclEntryImpl.java
new file mode 100644
index 000000000..46365f5d8
--- /dev/null
+++ b/base/util/src/netscape/security/acl/AclEntryImpl.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 netscape.security.acl;
+
+import java.security.Principal;
+import java.security.acl.AclEntry;
+import java.security.acl.Group;
+import java.security.acl.Permission;
+import java.util.Enumeration;
+import java.util.Vector;
+
+/**
+ * This is a class that describes one entry that associates users
+ * or groups with permissions in the ACL.
+ * The entry may be used as a way of granting or denying permissions.
+ *
+ * @author Satish Dharmaraj
+ */
+public class AclEntryImpl implements AclEntry {
+ private Principal user = null;
+ private Vector<Permission> permissionSet = new Vector<Permission>(10, 10);
+ private boolean negative = false;
+
+ /**
+ * Construct an ACL entry that associates a user with permissions
+ * in the ACL.
+ *
+ * @param user The user that is associated with this entry.
+ */
+ public AclEntryImpl(Principal user) {
+ this.user = user;
+ }
+
+ /**
+ * Construct a null ACL entry
+ */
+ public AclEntryImpl() {
+ }
+
+ /**
+ * Sets the principal in the entity. If a group or a
+ * principal had already been set, a false value is
+ * returned, otherwise a true value is returned.
+ *
+ * @param user The user that is associated with this entry.
+ * @return true if the principal is set, false if there is
+ * one already.
+ */
+ public boolean setPrincipal(Principal user) {
+ if (this.user != null)
+ return false;
+ this.user = user;
+ return true;
+ }
+
+ /**
+ * This method sets the ACL to have negative permissions.
+ * That is the user or group is denied the permission set
+ * specified in the entry.
+ */
+ public void setNegativePermissions() {
+ negative = true;
+ }
+
+ /**
+ * Returns true if this is a negative ACL.
+ */
+ public boolean isNegative() {
+ return negative;
+ }
+
+ /**
+ * A principal or a group can be associated with multiple
+ * permissions. This method adds a permission to the ACL entry.
+ *
+ * @param permission The permission to be associated with
+ * the principal or the group in the entry.
+ * @return true if the permission was added, false if the
+ * permission was already part of the permission set.
+ */
+ public boolean addPermission(Permission permission) {
+
+ if (permissionSet.contains(permission))
+ return false;
+
+ permissionSet.addElement(permission);
+
+ return true;
+ }
+
+ /**
+ * The method disassociates the permission from the Principal
+ * or the Group in this ACL entry.
+ *
+ * @param permission The permission to be disassociated with
+ * the principal or the group in the entry.
+ * @return true if the permission is removed, false if the
+ * permission is not part of the permission set.
+ */
+ public boolean removePermission(Permission permission) {
+ return permissionSet.removeElement(permission);
+ }
+
+ /**
+ * Checks if the passed permission is part of the allowed
+ * permission set in this entry.
+ *
+ * @param permission The permission that has to be part of
+ * the permission set in the entry.
+ * @return true if the permission passed is part of the
+ * permission set in the entry, false otherwise.
+ */
+ public boolean checkPermission(Permission permission) {
+ return permissionSet.contains(permission);
+ }
+
+ /**
+ * return an enumeration of the permissions in this ACL entry.
+ */
+ public Enumeration<Permission> permissions() {
+ return permissionSet.elements();
+ }
+
+ /**
+ * Return a string representation of the contents of the ACL entry.
+ */
+ public String toString() {
+ StringBuffer s = new StringBuffer();
+ if (negative)
+ s.append("-");
+ else
+ s.append("+");
+ if (user instanceof Group)
+ s.append("Group.");
+ else
+ s.append("User.");
+ s.append(user + "=");
+ Enumeration<Permission> e = permissions();
+ while (e.hasMoreElements()) {
+ Permission p = (Permission) e.nextElement();
+ s.append(p);
+ if (e.hasMoreElements())
+ s.append(",");
+ }
+ return new String(s);
+ }
+
+ /**
+ * Clones an AclEntry.
+ */
+ public synchronized Object clone() {
+ AclEntryImpl cloned;
+ cloned = new AclEntryImpl(user);
+ cloned.permissionSet = new Vector<Permission>(permissionSet);
+ cloned.negative = negative;
+ return cloned;
+ }
+
+ /**
+ * Return the Principal associated in this ACL entry.
+ * The method returns null if the entry uses a group
+ * instead of a principal.
+ */
+ public Principal getPrincipal() {
+ return user;
+ }
+}
diff --git a/base/util/src/netscape/security/acl/AclImpl.java b/base/util/src/netscape/security/acl/AclImpl.java
new file mode 100644
index 000000000..76750b7b9
--- /dev/null
+++ b/base/util/src/netscape/security/acl/AclImpl.java
@@ -0,0 +1,391 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.acl;
+
+import java.security.Principal;
+import java.security.acl.Acl;
+import java.security.acl.AclEntry;
+import java.security.acl.Group;
+import java.security.acl.NotOwnerException;
+import java.security.acl.Permission;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.NoSuchElementException;
+import java.util.Vector;
+
+/**
+ * An Access Control List (ACL) is encapsulated by this class.
+ *
+ * @author Satish Dharmaraj
+ */
+public class AclImpl extends OwnerImpl implements Acl {
+ //
+ // Maintain four tables. one each for positive and negative
+ // ACLs. One each depending on whether the entity is a group
+ // or principal.
+ //
+ private Hashtable<Principal, AclEntry> allowedUsersTable = new Hashtable<Principal, AclEntry>(23);
+ private Hashtable<Principal, AclEntry> allowedGroupsTable = new Hashtable<Principal, AclEntry>(23);
+ private Hashtable<Principal, AclEntry> deniedUsersTable = new Hashtable<Principal, AclEntry>(23);
+ private Hashtable<Principal, AclEntry> deniedGroupsTable = new Hashtable<Principal, AclEntry>(23);
+ private String aclName = null;
+ private Vector<Permission> zeroSet = new Vector<Permission>(1, 1);
+
+ /**
+ * Constructor for creating an empty ACL.
+ */
+ public AclImpl(Principal owner, String name) {
+ super(owner);
+ try {
+ setName(owner, name);
+ } catch (Exception e) {
+ }
+ }
+
+ /**
+ * Sets the name of the ACL.
+ *
+ * @param caller the principal who is invoking this method.
+ * @param name the name of the ACL.
+ * @exception NotOwnerException if the caller principal is
+ * not on the owners list of the Acl.
+ */
+ public void setName(Principal caller, String name)
+ throws NotOwnerException {
+ if (!isOwner(caller))
+ throw new NotOwnerException();
+
+ aclName = name;
+ }
+
+ /**
+ * Returns the name of the ACL.
+ *
+ * @return the name of the ACL.
+ */
+ public String getName() {
+ return aclName;
+ }
+
+ /**
+ * Adds an ACL entry to this ACL. An entry associates a
+ * group or a principal with a set of permissions. Each
+ * user or group can have one positive ACL entry and one
+ * negative ACL entry. If there is one of the type (negative
+ * or positive) already in the table, a false value is returned.
+ * The caller principal must be a part of the owners list of
+ * the ACL in order to invoke this method.
+ *
+ * @param caller the principal who is invoking this method.
+ * @param entry the ACL entry that must be added to the ACL.
+ * @return true on success, false if the entry is already present.
+ * @exception NotOwnerException if the caller principal
+ * is not on the owners list of the Acl.
+ */
+ public synchronized boolean addEntry(Principal caller, AclEntry entry)
+ throws NotOwnerException {
+ if (!isOwner(caller))
+ throw new NotOwnerException();
+
+ Hashtable<Principal, AclEntry> aclTable = findTable(entry);
+ Principal key = entry.getPrincipal();
+
+ if (aclTable.get(key) != null)
+ return false;
+
+ aclTable.put(key, entry);
+ return true;
+ }
+
+ /**
+ * Removes an ACL entry from this ACL.
+ * The caller principal must be a part of the owners list of the ACL
+ * in order to invoke this method.
+ *
+ * @param caller the principal who is invoking this method.
+ * @param entry the ACL entry that must be removed from the ACL.
+ * @return true on success, false if the entry is not part of the ACL.
+ * @exception NotOwnerException if the caller principal is not
+ * the owners list of the Acl.
+ */
+ public synchronized boolean removeEntry(Principal caller, AclEntry entry)
+ throws NotOwnerException {
+ if (!isOwner(caller))
+ throw new NotOwnerException();
+
+ Hashtable<Principal, AclEntry> aclTable = findTable(entry);
+ Object key = entry.getPrincipal();
+
+ Object o = aclTable.remove(key);
+ return (o != null);
+ }
+
+ /**
+ * This method returns the set of allowed permissions for the
+ * specified principal. This set of allowed permissions is calculated
+ * as follows:
+ *
+ * If there is no entry for a group or a principal an empty permission
+ * set is assumed.
+ *
+ * The group positive permission set is the union of all
+ * the positive permissions of each group that the individual belongs to.
+ * The group negative permission set is the union of all
+ * the negative permissions of each group that the individual belongs to.
+ * If there is a specific permission that occurs in both
+ * the postive permission set and the negative permission set,
+ * it is removed from both. The group positive and negatoive permission
+ * sets are calculated.
+ *
+ * The individial positive permission set and the individual negative
+ * permission set is then calculated. Again abscence of an entry means
+ * the empty set.
+ *
+ * The set of permissions granted to the principal is then calculated using
+ * the simple rule: Individual permissions always override the Group permissions.
+ * Specifically, individual negative permission set (specific
+ * denial of permissions) overrides the group positive permission set.
+ * And the individual positive permission set override the group negative
+ * permission set.
+ *
+ * @param user the principal for which the ACL entry is returned.
+ * @return The resulting permission set that the principal is allowed.
+ */
+ public synchronized Enumeration<Permission> getPermissions(Principal user) {
+
+ Enumeration<Permission> individualPositive;
+ Enumeration<Permission> individualNegative;
+ Enumeration<Permission> groupPositive;
+ Enumeration<Permission> groupNegative;
+
+ //
+ // canonicalize the sets. That is remove common permissions from
+ // positive and negative sets.
+ //
+ groupPositive = subtract(getGroupPositive(user), getGroupNegative(user));
+ groupNegative = subtract(getGroupNegative(user), getGroupPositive(user));
+ individualPositive = subtract(getIndividualPositive(user), getIndividualNegative(user));
+ individualNegative = subtract(getIndividualNegative(user), getIndividualPositive(user));
+
+ //
+ // net positive permissions is individual positive permissions
+ // plus (group positive - individual negative).
+ //
+ Enumeration<Permission> temp1 = subtract(groupPositive, individualNegative);
+ Enumeration<Permission> netPositive = union(individualPositive, temp1);
+
+ // recalculate the enumeration since we lost it in performing the
+ // subtraction
+ //
+ individualPositive = subtract(getIndividualPositive(user), getIndividualNegative(user));
+ individualNegative = subtract(getIndividualNegative(user), getIndividualPositive(user));
+
+ //
+ // net negative permissions is individual negative permissions
+ // plus (group negative - individual positive).
+ //
+ temp1 = subtract(groupNegative, individualPositive);
+ Enumeration<Permission> netNegative = union(individualNegative, temp1);
+
+ return subtract(netPositive, netNegative);
+ }
+
+ /**
+ * This method checks whether or not the specified principal
+ * has the required permission. If permission is denied
+ * permission false is returned, a true value is returned otherwise.
+ * This method does not authenticate the principal. It presumes that
+ * the principal is a valid authenticated principal.
+ *
+ * @param principal the name of the authenticated principal
+ * @param permission the permission that the principal must have.
+ * @return true of the principal has the permission desired, false
+ * otherwise.
+ */
+ public boolean checkPermission(Principal principal, Permission permission) {
+ Enumeration<Permission> permSet = getPermissions(principal);
+ while (permSet.hasMoreElements()) {
+ Permission p = (Permission) permSet.nextElement();
+ if (p.equals(permission))
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * returns an enumeration of the entries in this ACL.
+ */
+ public synchronized Enumeration<AclEntry> entries() {
+ return new AclEnumerator(this,
+ allowedUsersTable, allowedGroupsTable,
+ deniedUsersTable, deniedGroupsTable);
+ }
+
+ /**
+ * return a stringified version of the
+ * ACL.
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ Enumeration<AclEntry> entries = entries();
+ while (entries.hasMoreElements()) {
+ AclEntry entry = (AclEntry) entries.nextElement();
+ sb.append(entry.toString().trim());
+ sb.append("\n");
+ }
+
+ return sb.toString();
+ }
+
+ //
+ // Find the table that this entry belongs to. There are 4
+ // tables that are maintained. One each for postive and
+ // negative ACLs and one each for groups and users.
+ // This method figures out which
+ // table is the one that this AclEntry belongs to.
+ //
+ private Hashtable<Principal, AclEntry> findTable(AclEntry entry) {
+ Hashtable<Principal, AclEntry> aclTable = null;
+
+ Principal p = entry.getPrincipal();
+ if (p instanceof Group) {
+ if (entry.isNegative())
+ aclTable = deniedGroupsTable;
+ else
+ aclTable = allowedGroupsTable;
+ } else {
+ if (entry.isNegative())
+ aclTable = deniedUsersTable;
+ else
+ aclTable = allowedUsersTable;
+ }
+ return aclTable;
+ }
+
+ //
+ // returns the set e1 U e2.
+ //
+ private <T> Enumeration<T> union(Enumeration<T> e1, Enumeration<T> e2) {
+ Vector<T> v = new Vector<T>(20, 20);
+
+ while (e1.hasMoreElements())
+ v.addElement(e1.nextElement());
+
+ while (e2.hasMoreElements()) {
+ T o = e2.nextElement();
+ if (!v.contains(o))
+ v.addElement(o);
+ }
+
+ return v.elements();
+ }
+
+ //
+ // returns the set e1 - e2.
+ //
+ private <T> Enumeration<T> subtract(Enumeration<T> e1, Enumeration<T> e2) {
+ Vector<T> v = new Vector<T>(20, 20);
+
+ while (e1.hasMoreElements())
+ v.addElement(e1.nextElement());
+
+ while (e2.hasMoreElements()) {
+ T o = e2.nextElement();
+ if (v.contains(o))
+ v.removeElement(o);
+ }
+
+ return v.elements();
+ }
+
+ private Enumeration<Permission> getGroupPositive(Principal user) {
+ Enumeration<Permission> groupPositive = zeroSet.elements();
+ Enumeration<Principal> e = allowedGroupsTable.keys();
+ while (e.hasMoreElements()) {
+ Group g = (Group) e.nextElement();
+ if (g.isMember(user)) {
+ AclEntry ae = (AclEntry) allowedGroupsTable.get(g);
+ groupPositive = union(ae.permissions(), groupPositive);
+ }
+ }
+ return groupPositive;
+ }
+
+ private Enumeration<Permission> getGroupNegative(Principal user) {
+ Enumeration<Permission> groupNegative = zeroSet.elements();
+ Enumeration<Principal> e = deniedGroupsTable.keys();
+ while (e.hasMoreElements()) {
+ Group g = (Group) e.nextElement();
+ if (g.isMember(user)) {
+ AclEntry ae = (AclEntry) deniedGroupsTable.get(g);
+ groupNegative = union(ae.permissions(), groupNegative);
+ }
+ }
+ return groupNegative;
+ }
+
+ private Enumeration<Permission> getIndividualPositive(Principal user) {
+ Enumeration<Permission> individualPositive = zeroSet.elements();
+ AclEntry ae = (AclEntry) allowedUsersTable.get(user);
+ if (ae != null)
+ individualPositive = ae.permissions();
+ return individualPositive;
+ }
+
+ private Enumeration<Permission> getIndividualNegative(Principal user) {
+ Enumeration<Permission> individualNegative = zeroSet.elements();
+ AclEntry ae = (AclEntry) deniedUsersTable.get(user);
+ if (ae != null)
+ individualNegative = ae.permissions();
+ return individualNegative;
+ }
+}
+
+final class AclEnumerator implements Enumeration<AclEntry> {
+ Acl acl;
+ Enumeration<AclEntry> u1, u2, g1, g2;
+
+ AclEnumerator(Acl acl, Hashtable<Principal, AclEntry> u1, Hashtable<Principal, AclEntry> g1,
+ Hashtable<Principal, AclEntry> u2, Hashtable<Principal, AclEntry> g2) {
+ this.acl = acl;
+ this.u1 = u1.elements();
+ this.u2 = u2.elements();
+ this.g1 = g1.elements();
+ this.g2 = g2.elements();
+ }
+
+ public boolean hasMoreElements() {
+ return (u1.hasMoreElements() ||
+ u2.hasMoreElements() ||
+ g1.hasMoreElements() || g2.hasMoreElements());
+ }
+
+ public AclEntry nextElement() {
+ synchronized (acl) {
+ if (u1.hasMoreElements())
+ return u1.nextElement();
+ if (u2.hasMoreElements())
+ return u2.nextElement();
+ if (g1.hasMoreElements())
+ return g1.nextElement();
+ if (g2.hasMoreElements())
+ return g2.nextElement();
+ }
+ throw new NoSuchElementException("Acl Enumerator");
+ }
+}
diff --git a/base/util/src/netscape/security/acl/AllPermissionsImpl.java b/base/util/src/netscape/security/acl/AllPermissionsImpl.java
new file mode 100644
index 000000000..f2b57742f
--- /dev/null
+++ b/base/util/src/netscape/security/acl/AllPermissionsImpl.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 netscape.security.acl;
+
+import java.security.acl.Permission;
+
+/**
+ * This class implements the principal interface for the set of all permissions.
+ *
+ * @author Satish Dharmaraj
+ */
+public class AllPermissionsImpl extends PermissionImpl {
+
+ public AllPermissionsImpl(String s) {
+ super(s);
+ }
+
+ /**
+ * This function returns true if the permission passed matches the permission represented in
+ * this interface.
+ *
+ * @param another The Permission object to compare with.
+ * @return true always
+ */
+ public boolean equals(Permission another) {
+ return true;
+ }
+}
diff --git a/base/util/src/netscape/security/acl/GroupImpl.java b/base/util/src/netscape/security/acl/GroupImpl.java
new file mode 100644
index 000000000..ed087a544
--- /dev/null
+++ b/base/util/src/netscape/security/acl/GroupImpl.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 netscape.security.acl;
+
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.Enumeration;
+import java.util.Vector;
+
+/**
+ * This class implements a group of principals.
+ *
+ * @author Satish Dharmaraj
+ */
+public class GroupImpl implements Group {
+ private Vector<Principal> groupMembers = new Vector<Principal>(50, 100);
+ private String group;
+
+ /**
+ * Constructs a Group object with no members.
+ *
+ * @param groupName the name of the group
+ */
+ public GroupImpl(String groupName) {
+ this.group = groupName;
+ }
+
+ /**
+ * adds the specified member to the group.
+ *
+ * @param user The principal to add to the group.
+ * @return true if the member was added - false if the
+ * member could not be added.
+ */
+ public boolean addMember(Principal user) {
+ if (groupMembers.contains(user))
+ return false;
+
+ // do not allow groups to be added to itself.
+ if (group.equals(user.toString()))
+ throw new IllegalArgumentException();
+
+ groupMembers.addElement(user);
+ return true;
+ }
+
+ /**
+ * removes the specified member from the group.
+ *
+ * @param user The principal to remove from the group.
+ * @param true if the principal was removed false if
+ * the principal was not a member
+ */
+ public boolean removeMember(Principal user) {
+ return groupMembers.removeElement(user);
+ }
+
+ /**
+ * returns the enumeration of the members in the group.
+ */
+ public Enumeration<Principal> members() {
+ return groupMembers.elements();
+ }
+
+ /**
+ * This function returns true if the group passed matches
+ * the group represented in this interface.
+ *
+ * @param another The group to compare this group to.
+ */
+ public boolean equals(Group another) {
+ return group.equals(another.toString());
+ }
+
+ /**
+ * Prints a stringified version of the group.
+ */
+ public String toString() {
+ return group;
+ }
+
+ /**
+ * return a hashcode for the principal.
+ */
+ public int hashCode() {
+ return group.hashCode();
+ }
+
+ /**
+ * returns true if the passed principal is a member of the group.
+ *
+ * @param member The principal whose membership must be checked for.
+ * @return true if the principal is a member of this group,
+ * false otherwise
+ */
+ public boolean isMember(Principal member) {
+
+ //
+ // if the member is part of the group (common case), return true.
+ // if not, recursively search depth first in the group looking for the
+ // principal.
+ //
+ if (groupMembers.contains(member)) {
+ return true;
+ } else {
+ Vector<Group> alreadySeen = new Vector<Group>(10);
+ return isMemberRecurse(member, alreadySeen);
+ }
+ }
+
+ /**
+ * return the name of the principal.
+ */
+ public String getName() {
+ return group;
+ }
+
+ //
+ // This function is the recursive search of groups for this
+ // implementation of the Group. The search proceeds building up
+ // a vector of already seen groups. Only new groups are considered,
+ // thereby avoiding loops.
+ //
+ boolean isMemberRecurse(Principal member, Vector<Group> alreadySeen) {
+ Enumeration<Principal> e = members();
+ while (e.hasMoreElements()) {
+ boolean mem = false;
+ Principal p = e.nextElement();
+
+ // if the member is in this collection, return true
+ if (p.equals(member)) {
+ return true;
+ } else if (p instanceof GroupImpl) {
+ //
+ // if not recurse if the group has not been checked already.
+ // Can call method in this package only if the object is an
+ // instance of this class. Otherwise call the method defined
+ // in the interface. (This can lead to a loop if a mixture of
+ // implementations form a loop, but we live with this improbable
+ // case rather than clutter the interface by forcing the
+ // implementation of this method.)
+ //
+ GroupImpl g = (GroupImpl) p;
+ alreadySeen.addElement(this);
+ if (!alreadySeen.contains(g))
+ mem = g.isMemberRecurse(member, alreadySeen);
+ } else if (p instanceof Group) {
+ Group g = (Group) p;
+ if (!alreadySeen.contains(g))
+ mem = g.isMember(member);
+ }
+
+ if (mem)
+ return mem;
+ }
+ return false;
+ }
+}
diff --git a/base/util/src/netscape/security/acl/OwnerImpl.java b/base/util/src/netscape/security/acl/OwnerImpl.java
new file mode 100644
index 000000000..3f47a1dd8
--- /dev/null
+++ b/base/util/src/netscape/security/acl/OwnerImpl.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 netscape.security.acl;
+
+import java.security.Principal;
+import java.security.acl.Group;
+import java.security.acl.LastOwnerException;
+import java.security.acl.NotOwnerException;
+import java.security.acl.Owner;
+import java.util.Enumeration;
+
+/**
+ * Class implementing the Owner interface. The
+ * initial owner principal is configured as
+ * part of the constructor.
+ *
+ * @author Satish Dharmaraj
+ */
+public class OwnerImpl implements Owner {
+ private Group ownerGroup;
+
+ public OwnerImpl(Principal owner) {
+ ownerGroup = new GroupImpl("AclOwners");
+ ownerGroup.addMember(owner);
+ }
+
+ /**
+ * Adds an owner. Owners can modify ACL contents and can disassociate
+ * ACLs from the objects they protect in the AclConfig interface.
+ * The caller principal must be a part of the owners list of the ACL in
+ * order to invoke this method. The initial owner is configured
+ * at ACL construction time.
+ *
+ * @param caller the principal who is invoking this method.
+ * @param owner The owner that should be added to the owners list.
+ * @return true if success, false if already an owner.
+ * @exception NotOwnerException if the caller principal is not on
+ * the owners list of the Acl.
+ */
+ public synchronized boolean addOwner(Principal caller, Principal owner)
+ throws NotOwnerException {
+ if (!isOwner(caller))
+ throw new NotOwnerException();
+
+ ownerGroup.addMember(owner);
+ return false;
+ }
+
+ /**
+ * Delete owner. If this is the last owner in the ACL, an exception is
+ * raised.
+ * The caller principal must be a part of the owners list of the ACL in
+ * order to invoke this method.
+ *
+ * @param caller the principal who is invoking this method.
+ * @param owner The owner to be removed from the owners list.
+ * @return true if the owner is removed, false if the owner is not part
+ * of the owners list.
+ * @exception NotOwnerException if the caller principal is not on
+ * the owners list of the Acl.
+ * @exception LastOwnerException if there is only one owner left in the group, then
+ * deleteOwner would leave the ACL owner-less. This exception is raised in such a case.
+ */
+ public synchronized boolean deleteOwner(Principal caller, Principal owner)
+ throws NotOwnerException, LastOwnerException {
+ if (!isOwner(caller))
+ throw new NotOwnerException();
+
+ Enumeration<? extends Principal> e = ownerGroup.members();
+ //
+ // check if there is atleast 2 members left.
+ //
+ e.nextElement(); // consume next element
+ if (e.hasMoreElements())
+ return ownerGroup.removeMember(owner);
+ else
+ throw new LastOwnerException();
+
+ }
+
+ /**
+ * returns if the given principal belongs to the owner list.
+ *
+ * @param owner The owner to check if part of the owners list
+ * @return true if the passed principal is in the owner list, false if not.
+ */
+ public synchronized boolean isOwner(Principal owner) {
+ return ownerGroup.isMember(owner);
+ }
+}
diff --git a/base/util/src/netscape/security/acl/PermissionImpl.java b/base/util/src/netscape/security/acl/PermissionImpl.java
new file mode 100644
index 000000000..2e73d3c7e
--- /dev/null
+++ b/base/util/src/netscape/security/acl/PermissionImpl.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 netscape.security.acl;
+
+import java.security.acl.Permission;
+
+/**
+ * The PermissionImpl class implements the permission
+ * interface for permissions that are strings.
+ *
+ * @author Satish Dharmaraj
+ */
+public class PermissionImpl implements Permission {
+
+ private String permission;
+
+ /**
+ * Construct a permission object using a string.
+ *
+ * @param permission the stringified version of the permission.
+ */
+ public PermissionImpl(String permission) {
+ this.permission = permission;
+ }
+
+ /**
+ * This function returns true if the object passed matches the permission
+ * represented in this interface.
+ *
+ * @param another The Permission object to compare with.
+ * @return true if the Permission objects are equal, false otherwise
+ */
+ public boolean equals(Object another) {
+ if (another instanceof Permission) {
+ Permission p = (Permission) another;
+ return permission.equals(p.toString());
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Prints a stringified version of the permission.
+ *
+ * @return the string representation of the Permission.
+ */
+ public String toString() {
+ return permission;
+ }
+}
diff --git a/base/util/src/netscape/security/acl/PrincipalImpl.java b/base/util/src/netscape/security/acl/PrincipalImpl.java
new file mode 100644
index 000000000..25fa11095
--- /dev/null
+++ b/base/util/src/netscape/security/acl/PrincipalImpl.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 netscape.security.acl;
+
+import java.security.Principal;
+
+/**
+ * This class implements the principal interface.
+ *
+ * @author Satish Dharmaraj
+ */
+public class PrincipalImpl implements Principal {
+
+ private String user;
+
+ /**
+ * Construct a principal from a string user name.
+ *
+ * @param user The string form of the principal name.
+ */
+ public PrincipalImpl(String user) {
+ this.user = user;
+ }
+
+ /**
+ * This function returns true if the object passed matches
+ * the principal represented in this implementation
+ *
+ * @param another the Principal to compare with.
+ * @return true if the Principal passed is the same as that
+ * encapsulated in this object, false otherwise
+ */
+ public boolean equals(Object another) {
+ if (another instanceof PrincipalImpl) {
+ PrincipalImpl p = (PrincipalImpl) another;
+ return user.equals(p.toString());
+ } else
+ return false;
+ }
+
+ /**
+ * Prints a stringified version of the principal.
+ */
+ public String toString() {
+ return user;
+ }
+
+ /**
+ * return a hashcode for the principal.
+ */
+ public int hashCode() {
+ return user.hashCode();
+ }
+
+ /**
+ * return the name of the principal.
+ */
+ public String getName() {
+ return user;
+ }
+
+}
diff --git a/base/util/src/netscape/security/acl/WorldGroupImpl.java b/base/util/src/netscape/security/acl/WorldGroupImpl.java
new file mode 100644
index 000000000..2f885cbec
--- /dev/null
+++ b/base/util/src/netscape/security/acl/WorldGroupImpl.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 netscape.security.acl;
+
+import java.security.Principal;
+
+/**
+ * This class implements a group of principals.
+ *
+ * @author Satish Dharmaraj
+ */
+public class WorldGroupImpl extends GroupImpl {
+
+ public WorldGroupImpl(String s) {
+ super(s);
+ }
+
+ /**
+ * returns true for all passed principals
+ *
+ * @param member The principal whose membership must be checked in this Group.
+ * @return true always since this is the "world" group.
+ */
+ public boolean isMember(Principal member) {
+ return true;
+ }
+}
diff --git a/base/util/src/netscape/security/extensions/AccessDescription.java b/base/util/src/netscape/security/extensions/AccessDescription.java
new file mode 100644
index 000000000..f13c937e7
--- /dev/null
+++ b/base/util/src/netscape/security/extensions/AccessDescription.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 netscape.security.extensions;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.GeneralName;
+
+public class AccessDescription implements Serializable {
+ ObjectIdentifier mOID = null;
+ GeneralName mLocation = null;
+
+ AccessDescription(ObjectIdentifier oid, GeneralName location) {
+ mOID = oid;
+ mLocation = location;
+ }
+
+ public ObjectIdentifier getMethod() {
+ return mOID;
+ }
+
+ public GeneralName getLocation() {
+ return mLocation;
+ }
+
+ /**
+ * For serialization:
+ * Note that GeneralName is not serializable. That is
+ * why we need to define our own serialization method.
+ */
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws IOException {
+ DerOutputStream seq = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+
+ tmp.putOID(mOID);
+ mLocation.encode(tmp);
+ seq.write(DerValue.tag_Sequence, tmp);
+ out.write(seq.toByteArray());
+ }
+
+ /**
+ * For serialization
+ * Note that GeneralName is not serializable. That is
+ * why we need to define our own serialization method.
+ */
+ private void readObject(java.io.ObjectInputStream in)
+ throws IOException {
+ DerValue val = new DerValue(in);
+ DerValue seq = val.data.getDerValue();
+
+ mOID = seq.getOID();
+ DerValue derLoc = val.data.getDerValue();
+
+ mLocation = new GeneralName(derLoc);
+ }
+}
diff --git a/base/util/src/netscape/security/extensions/AuthInfoAccessExtension.java b/base/util/src/netscape/security/extensions/AuthInfoAccessExtension.java
new file mode 100644
index 000000000..b8e2933dd
--- /dev/null
+++ b/base/util/src/netscape/security/extensions/AuthInfoAccessExtension.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 netscape.security.extensions;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import com.netscape.cmsutil.util.Utils;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CertAttrSet;
+import netscape.security.x509.Extension;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.URIName;
+
+/**
+ * This represents the authority information access extension
+ * as defined in RFC2459.
+ *
+ * id-pkix OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) dod(6)
+ * internet(1) security(5) mechanisms(5)
+ * pkix(7) } }
+ * id-pe OBJECT IDENTIFIER ::= { id-pkix 1 }
+ * id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
+ * AuthorityInfoAccessSyntax ::= SEQUENCE SIZE (1..MAX) OF AccessDescription
+ * AccessDescription ::= SEQUENCE {
+ * accessMethod OBJECT IDENTIFIER,
+ * accessLocation GeneralName
+ * }
+ * id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }
+ * id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 }
+ * id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 }
+ *
+ * Need to make sure the following is added to CMS.cfg:
+ * oidmap.auth_info_access.class=com.netscape.certsrv.cert.AuthInfoAccessExtension
+ * oidmap.auth_info_access.oid=1.3.6.1.5.5.7.1.1
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class AuthInfoAccessExtension extends Extension implements CertAttrSet {
+ private static final long serialVersionUID = 7373316523212538446L;
+ public static final String NAME = "AuthInfoAccessExtension";
+ public static final String NAME2 = "AuthorityInformationAccess";
+
+ public static final int OID_OCSP[] = { 1, 3, 6, 1, 5, 5, 7, 48, 1 };
+ public static final ObjectIdentifier METHOD_OCSP = new
+ ObjectIdentifier(OID_OCSP);
+
+ public static final int OID_CA_ISSUERS[] = { 1, 3, 6, 1, 5, 5, 7, 48, 2 };
+ public static final ObjectIdentifier METHOD_CA_ISSUERS = new
+ ObjectIdentifier(OID_CA_ISSUERS);
+
+ public static final int OID[] = { 1, 3, 6, 1, 5, 5, 7, 1, 1 };
+ public static final ObjectIdentifier ID = new ObjectIdentifier(OID);
+
+ private Vector<AccessDescription> mDesc = new Vector<AccessDescription>();
+
+ /**
+ * Create the extension from the passed DER encoded value of the same.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param value Array of DER encoded bytes of the actual value.
+ * @exception IOException on error.
+ */
+ public AuthInfoAccessExtension(boolean critical) {
+ this.extensionId = ID;
+ this.critical = critical;
+ this.extensionValue = null; // build this when encodeThis() is called
+ }
+
+ public AuthInfoAccessExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = ID;
+ this.critical = critical.booleanValue();
+ this.extensionValue = (byte[]) ((byte[]) value).clone();
+ decodeThis();
+ }
+
+ /**
+ * Sets extension attribute.
+ */
+ public void set(String name, Object obj) throws CertificateException {
+ // NOT USED
+ }
+
+ /**
+ * Retrieves extension attribute.
+ */
+ public Object get(String name) throws CertificateException {
+ // NOT USED
+ return null;
+ }
+
+ /**
+ * Deletes attribute.
+ */
+ public void delete(String name) throws CertificateException {
+ // NOT USED
+ }
+
+ /**
+ * Decodes this extension.
+ */
+ public void decode(InputStream in) throws IOException {
+ // NOT USED
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ // NOT USED
+ return null;
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return NAME;
+ }
+
+ /**
+ * Adds Access Description.
+ */
+ public void addAccessDescription(
+ ObjectIdentifier method,
+ GeneralName gn) {
+ clearValue();
+ mDesc.addElement(new AccessDescription(method, gn));
+ }
+
+ public AccessDescription getAccessDescription(int pos) {
+ return mDesc.elementAt(pos);
+ }
+
+ /**
+ * Returns the number of access description.
+ */
+ public int numberOfAccessDescription() {
+ return mDesc.size();
+ }
+
+ private void decodeThis() throws IOException {
+ DerValue val = new DerValue(this.extensionValue);
+
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding of AuthInfoAccess extension");
+ }
+ while (val.data.available() != 0) {
+ DerValue seq = val.data.getDerValue();
+ ObjectIdentifier method = seq.data.getDerValue().getOID();
+ GeneralName gn = new GeneralName(seq.data.getDerValue());
+
+ addAccessDescription(method, gn);
+ }
+ }
+
+ private void encodeThis() throws IOException {
+ DerOutputStream seq = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+
+ for (int i = 0; i < mDesc.size(); i++) {
+ DerOutputStream tmp0 = new DerOutputStream();
+ AccessDescription ad = mDesc.elementAt(i);
+
+ tmp0.putOID(ad.getMethod());
+ ad.getLocation().encode(tmp0);
+ tmp.write(DerValue.tag_Sequence, tmp0);
+ }
+ seq.write(DerValue.tag_Sequence, tmp);
+ this.extensionValue = seq.toByteArray();
+ }
+
+ /**
+ * Write the extension to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ if (this.extensionValue == null) {
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Returns a printable representation of the AuthInfoAccess.
+ */
+ public String toString() {
+ String s = super.toString() + "AuthInfoAccess [\n";
+
+ for (int i = 0; i < mDesc.size(); i++) {
+ AccessDescription ad = mDesc.elementAt(i);
+
+ s += "(" + i + ")";
+ s += " ";
+ s += ad.getMethod().toString() + " " + ad.getLocation().toString();
+ }
+ return (s + "]\n");
+ }
+
+ public static void main(String[] argv) {
+ AuthInfoAccessExtension aia = new AuthInfoAccessExtension(false);
+ GeneralName ocspName = new GeneralName(new
+ URIName("http://ocsp.netscape.com"));
+
+ aia.addAccessDescription(METHOD_OCSP, ocspName);
+ GeneralName caIssuersName = new GeneralName(new
+ URIName("http://ocsp.netscape.com"));
+
+ aia.addAccessDescription(METHOD_CA_ISSUERS, caIssuersName);
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+
+ try {
+ aia.encode(os);
+
+ System.out.println(Utils.base64encode(os.toByteArray()));
+ } catch (IOException e) {
+ System.out.println(e.toString());
+ }
+
+ try {
+ // test serialization
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(bos);
+
+ oos.writeObject(aia);
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(
+ bos.toByteArray());
+ ObjectInputStream ois = new ObjectInputStream(bis);
+ AuthInfoAccessExtension clone = (AuthInfoAccessExtension)
+ ois.readObject();
+
+ System.out.println(clone);
+ } catch (Exception e) {
+ System.out.println(e.toString());
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/extensions/CertInfo.java b/base/util/src/netscape/security/extensions/CertInfo.java
new file mode 100644
index 000000000..ab88ec8ab
--- /dev/null
+++ b/base/util/src/netscape/security/extensions/CertInfo.java
@@ -0,0 +1,120 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.extensions;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.util.Date;
+
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateAlgorithmId;
+import netscape.security.x509.CertificateIssuerName;
+import netscape.security.x509.CertificateSerialNumber;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+
+/**
+ * Extends X509CertInfo class so that minimal fields are initialized at
+ * creation time so an object of this type is always serializable.
+ */
+public class CertInfo extends X509CertInfo {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2883888348288591989L;
+ public static final CertificateSubjectName SERIALIZE_SUBJECT;
+ public static final CertificateIssuerName SERIALIZE_ISSUER;
+ public static final CertificateValidity SERIALIZE_VALIDITY;
+ public static final CertificateSerialNumber SERIALIZE_SERIALNO;
+ public static final CertificateAlgorithmId SERIALIZE_ALGOR;
+ public static final CertificateVersion FORCE_VERSION_3;
+
+ static {
+ try {
+ // force version 3
+ FORCE_VERSION_3 =
+ new CertificateVersion(CertificateVersion.V3);
+ SERIALIZE_SUBJECT =
+ new CertificateSubjectName(
+ new X500Name("cn=uninitialized"));
+ SERIALIZE_ISSUER =
+ new CertificateIssuerName(
+ new X500Name("cn=uninitialized"));
+ SERIALIZE_VALIDITY =
+ new CertificateValidity(new Date(0), new Date(0));
+ SERIALIZE_SERIALNO =
+ new CertificateSerialNumber(new BigInteger("0"));
+ SERIALIZE_ALGOR =
+ new CertificateAlgorithmId(
+ AlgorithmId.getAlgorithmId("MD5withRSA"));
+ } catch (IOException e) {
+ // should never happen. If does, system is hosed.
+ System.out.println("**** Impossible Error encountered ****");
+ throw new RuntimeException(e.toString());
+ } catch (NoSuchAlgorithmException e) {
+ // should never happen. If does, system is hosed.
+ System.out.println("**** Impossible Error encountered ****");
+ throw new RuntimeException(e.toString());
+ }
+ }
+
+ /**
+ * Initializes most fields required by der encoding so object will
+ * serialize properly.
+ */
+ // XXX should write a class to use something else for serialization
+ // but this is faster and done now for the time crunch.
+ public CertInfo() {
+ super();
+ makeSerializable(this);
+ }
+
+ public static void makeSerializable(X509CertInfo certinfo) {
+ try {
+ // force version 3.
+ certinfo.set(X509CertInfo.VERSION, FORCE_VERSION_3);
+
+ if (certinfo.get(X509CertInfo.SERIAL_NUMBER) == null) {
+ certinfo.set(X509CertInfo.SERIAL_NUMBER, SERIALIZE_SERIALNO);
+ }
+ if (certinfo.get(X509CertInfo.ALGORITHM_ID) == null) {
+ certinfo.set(X509CertInfo.ALGORITHM_ID, SERIALIZE_ALGOR);
+ }
+ if (certinfo.get(X509CertInfo.ISSUER) == null) {
+ certinfo.set(X509CertInfo.ISSUER, SERIALIZE_ISSUER);
+ }
+ if (certinfo.get(X509CertInfo.VALIDITY) == null) {
+ certinfo.set(X509CertInfo.VALIDITY, SERIALIZE_VALIDITY);
+ }
+ // set subject name anyway - it'll get overwritten.
+ if (certinfo.get(X509CertInfo.SUBJECT) == null) {
+ certinfo.set(X509CertInfo.SUBJECT, SERIALIZE_SUBJECT);
+ }
+ // key is set later in the request.
+ } // these exceptions shouldn't happen here unless the
+ // whole process is hosed.
+ catch (CertificateException e) {
+ } catch (IOException e) {
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/extensions/CertificateRenewalWindowExtension.java b/base/util/src/netscape/security/extensions/CertificateRenewalWindowExtension.java
new file mode 100644
index 000000000..018fd71c8
--- /dev/null
+++ b/base/util/src/netscape/security/extensions/CertificateRenewalWindowExtension.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 netscape.security.extensions;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.cert.CertificateException;
+import java.util.Date;
+import java.util.Enumeration;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CertAttrSet;
+import netscape.security.x509.Extension;
+
+/**
+ * This represents the CertificateRenewalWindow extension
+ * as defined in draft-thayes-cert-renewal-00
+ *
+ * CertificateRenewalWindow ::= SEQUENCE {
+ * beginTime GeneralizedTime,
+ * endTime GeneralizedTime OPTIONAL }
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class CertificateRenewalWindowExtension extends Extension
+ implements CertAttrSet {
+ private static final long serialVersionUID = 4470220533545299271L;
+ public static final String NAME = "CertificateRenewalWindow";
+ public static final int OID[] = { 2, 16, 840, 1, 113730, 1, 15 };
+ public static final ObjectIdentifier ID = new ObjectIdentifier(OID);
+
+ private Date mBeginTime = null;
+ private Date mEndTime = null; // optional
+
+ public CertificateRenewalWindowExtension(boolean critical, Date beginTime,
+ Date endTime) throws IOException {
+ this.extensionId = ID;
+ this.critical = critical;
+ mBeginTime = beginTime;
+ mEndTime = endTime;
+ encodeThis();
+ }
+
+ public CertificateRenewalWindowExtension(boolean critical) {
+ this.extensionId = ID;
+ this.critical = critical;
+ this.extensionValue = null; // build this when encodeThis() is called
+ }
+
+ public CertificateRenewalWindowExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = ID;
+ this.critical = critical.booleanValue();
+ this.extensionValue = (byte[]) ((byte[]) value).clone();
+ decodeThis();
+ }
+
+ public String getName() {
+ return NAME;
+ }
+
+ /**
+ * Sets extension attribute.
+ */
+ public void set(String name, Object obj) throws CertificateException {
+ // NOT USED
+ }
+
+ /**
+ * Retrieves extension attribute.
+ */
+ public Object get(String name) throws CertificateException {
+ // NOT USED
+ return null;
+ }
+
+ /**
+ * Deletes attribute.
+ */
+ public void delete(String name) throws CertificateException {
+ // NOT USED
+ }
+
+ /**
+ * Decodes this extension.
+ */
+ public void decode(InputStream in) throws IOException {
+ // NOT USED
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ // NOT USED
+ return null;
+ }
+
+ public Date getBeginTime() {
+ return mBeginTime;
+ }
+
+ public Date getEndTime() {
+ return mEndTime;
+ }
+
+ public void setBeginTime(Date d) {
+ mBeginTime = d;
+ }
+
+ public void setEndTime(Date d) {
+ mEndTime = d;
+ }
+
+ private void decodeThis() throws IOException {
+ DerValue val = new DerValue(this.extensionValue);
+
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding of CertificateWindow extension");
+ }
+ while (val.data.available() != 0) {
+ if (mBeginTime == null) {
+ mBeginTime = val.data.getGeneralizedTime();
+ } else {
+ mEndTime = val.data.getGeneralizedTime();
+ }
+ }
+ }
+
+ private void encodeThis() throws IOException {
+ DerOutputStream seq = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+
+ tmp.putGeneralizedTime(mBeginTime);
+ if (mEndTime != null) {
+ tmp.putGeneralizedTime(mEndTime);
+ }
+ seq.write(DerValue.tag_Sequence, tmp);
+ this.extensionValue = seq.toByteArray();
+ }
+
+ /**
+ * Write the extension to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ if (this.extensionValue == null) {
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Returns a printable representation of the CertificateRenewalWindow.
+ */
+ public String toString() {
+ String s = super.toString() + "CertificateRenewalWindow [\n";
+
+ s += "BeginTime: " + mBeginTime + "\n";
+ if (mEndTime != null) {
+ s += "EndTime: " + mEndTime;
+ }
+ return (s + "]\n");
+ }
+}
diff --git a/base/util/src/netscape/security/extensions/CertificateScopeEntry.java b/base/util/src/netscape/security/extensions/CertificateScopeEntry.java
new file mode 100644
index 000000000..527093ccf
--- /dev/null
+++ b/base/util/src/netscape/security/extensions/CertificateScopeEntry.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 netscape.security.extensions;
+
+import java.io.IOException;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.x509.GeneralName;
+
+/**
+ * This represents the CertificateScopeOfUse extension
+ * as defined in draft-thayes-cert-scope-00
+ *
+ * CertificateScopeEntry ::= SEQUENCE {
+ * name GeneralName, -- pattern, as for NameConstraints
+ * portNumber INTEGER OPTIONAL
+ * }
+ * CertificateScopeOfUse ::= SEQUENCE OF CertificateScopeEntry
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class CertificateScopeEntry {
+ private GeneralName mGn = null;
+ private BigInt mPort = null;
+
+ /**
+ * Constructs scope with der value.
+ */
+ public CertificateScopeEntry(DerValue val) throws IOException {
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding for PolicyQualifierInfo.");
+ }
+ DerValue gn = val.data.getDerValue();
+
+ mGn = new GeneralName(gn);
+ if (val.data.available() != 0) {
+ mPort = val.data.getInteger();
+ }
+ }
+
+ /**
+ * Constructs scope wit
+ */
+ public CertificateScopeEntry(GeneralName gn, BigInt port) {
+ mGn = gn;
+ mPort = port; // optional
+ }
+
+ public void encode(DerOutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ mGn.encode(tmp);
+ if (mPort != null) {
+ tmp.putInteger(mPort);
+ }
+ out.write(DerValue.tag_Sequence, tmp);
+ }
+
+ /**
+ * Returns a GeneralName
+ */
+ public GeneralName getGeneralName() {
+ return mGn;
+ }
+
+ /**
+ * Returns a port
+ */
+ public BigInt getPort() {
+ return mPort;
+ }
+
+ /**
+ * Returns a printable representation of the CertificateRenewalWindow.
+ */
+ public String toString() {
+ String s = super.toString() + "CertificateScopeEntry [\n";
+
+ s += "GeneralName: " + mGn;
+ if (mPort != null) {
+ s += "PortNumber: " + mPort;
+ }
+ return (s + "]\n");
+ }
+}
diff --git a/base/util/src/netscape/security/extensions/CertificateScopeOfUseExtension.java b/base/util/src/netscape/security/extensions/CertificateScopeOfUseExtension.java
new file mode 100644
index 000000000..16641f36b
--- /dev/null
+++ b/base/util/src/netscape/security/extensions/CertificateScopeOfUseExtension.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 netscape.security.extensions;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CertAttrSet;
+import netscape.security.x509.Extension;
+import netscape.security.x509.OIDMap;
+
+/**
+ * This represents the CertificateScopeOfUse extension
+ * as defined in draft-thayes-cert-scope-00
+ *
+ * CertificateScopeEntry ::= SEQUENCE {
+ * name GeneralName, -- pattern, as for NameConstraints
+ * portNumber INTEGER OPTIONAL
+ * }
+ * CertificateScopeOfUse ::= SEQUENCE OF CertificateScopeEntry
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class CertificateScopeOfUseExtension extends Extension
+ implements CertAttrSet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2143292831971567770L;
+ public static final String NAME = "CertificateScopeOfUse";
+ public static final int OID[] = { 2, 16, 840, 1, 113730, 1, 17 };
+ public static final ObjectIdentifier ID = new ObjectIdentifier(OID);
+
+ private Vector<CertificateScopeEntry> mEntries = null;
+
+ static {
+ try {
+ OIDMap.addAttribute(CertificateScopeOfUseExtension.class.getName(),
+ ID.toString(), NAME);
+ } catch (CertificateException e) {
+ }
+ }
+
+ public CertificateScopeOfUseExtension(boolean critical, Vector<CertificateScopeEntry> scopeEntries)
+ throws IOException {
+ this.extensionId = ID;
+ this.critical = critical;
+ this.extensionValue = null; // build this when encodeThis() is called
+ mEntries = scopeEntries;
+ encodeThis();
+ }
+
+ public CertificateScopeOfUseExtension(boolean critical) {
+ this.extensionId = ID;
+ this.critical = critical;
+ this.extensionValue = null; // build this when encodeThis() is called
+ }
+
+ public CertificateScopeOfUseExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = ID;
+ this.critical = critical.booleanValue();
+ this.extensionValue = (byte[]) ((byte[]) value).clone();
+ decodeThis();
+ }
+
+ public String getName() {
+ return NAME;
+ }
+
+ public Vector<CertificateScopeEntry> getCertificateScopeEntries() {
+ return mEntries;
+ }
+
+ /**
+ * Sets extension attribute.
+ */
+ public void set(String name, Object obj) throws CertificateException {
+ // NOT USED
+ }
+
+ /**
+ * Retrieves extension attribute.
+ */
+ public Object get(String name) throws CertificateException {
+ // NOT USED
+ return null;
+ }
+
+ /**
+ * Deletes attribute.
+ */
+ public void delete(String name) throws CertificateException {
+ // NOT USED
+ }
+
+ /**
+ * Decodes this extension.
+ */
+ public void decode(InputStream in) throws IOException {
+ // NOT USED
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ // NOT USED
+ return null;
+ }
+
+ private void decodeThis() throws IOException {
+ DerValue val = new DerValue(this.extensionValue);
+
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding of CertificateWindow extension");
+ }
+ mEntries = new Vector<CertificateScopeEntry>();
+ while (val.data.available() != 0) {
+ mEntries.addElement(new CertificateScopeEntry(
+ val.data.getDerValue()));
+ }
+ }
+
+ private void encodeThis() throws IOException {
+ DerOutputStream seq = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+
+ if (mEntries == null)
+ throw new IOException("Invalid Scope Entries");
+
+ for (int i = 0; i < mEntries.size(); i++) {
+ CertificateScopeEntry se = (CertificateScopeEntry)
+ mEntries.elementAt(i);
+
+ se.encode(tmp);
+ }
+
+ seq.write(DerValue.tag_Sequence, tmp);
+ this.extensionValue = seq.toByteArray();
+ }
+
+ /**
+ * Write the extension to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ if (this.extensionValue == null) {
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Returns a printable representation of the CertificateRenewalWindow.
+ */
+ public String toString() {
+ String s = super.toString() + "CertificateUseOfScope [\n";
+
+ if (mEntries != null) {
+ for (int i = 0; i < mEntries.size(); i++) {
+ CertificateScopeEntry se = (CertificateScopeEntry)
+ mEntries.elementAt(i);
+
+ s += se.toString();
+ }
+ }
+ return (s + "]\n");
+ }
+}
diff --git a/base/util/src/netscape/security/extensions/ExtendedKeyUsageExtension.java b/base/util/src/netscape/security/extensions/ExtendedKeyUsageExtension.java
new file mode 100644
index 000000000..939da036f
--- /dev/null
+++ b/base/util/src/netscape/security/extensions/ExtendedKeyUsageExtension.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 netscape.security.extensions;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CertAttrSet;
+import netscape.security.x509.Extension;
+import netscape.security.x509.OIDMap;
+
+/**
+ * This represents the extended key usage extension.
+ */
+public class ExtendedKeyUsageExtension extends Extension implements CertAttrSet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 765403075764697489L;
+ public static final String OID = "2.5.29.37";
+ public static final String NAME = OIDMap.EXT_KEY_USAGE_NAME;
+ public static final String OID_OCSPSigning = "1.3.6.1.5.5.7.3.9";
+ public static final String OID_CODESigning = "1.3.6.1.5.5.7.3.3";
+
+ public static final int OID_OCSP_SIGNING_STR[] =
+ { 1, 3, 6, 1, 5, 5, 7, 3, 9 };
+ public static final ObjectIdentifier OID_OCSP_SIGNING = new
+ ObjectIdentifier(OID_OCSP_SIGNING_STR);
+
+ public static final int OID_CODE_SIGNING_STR[] =
+ { 1, 3, 6, 1, 5, 5, 7, 3, 3 };
+ public static final ObjectIdentifier OID_CODE_SIGNING = new
+ ObjectIdentifier(OID_OCSP_SIGNING_STR);
+
+ private Vector<ObjectIdentifier> oidSet = null;
+ private byte mCached[] = null;
+
+ static {
+ try {
+ OIDMap.addAttribute(ExtendedKeyUsageExtension.class.getName(),
+ OID, ExtendedKeyUsageExtension.NAME);
+ } catch (CertificateException e) {
+ }
+ }
+
+ public ExtendedKeyUsageExtension() {
+ this(false, null);
+ }
+
+ public ExtendedKeyUsageExtension(boolean crit, Vector<ObjectIdentifier> oids) {
+ try {
+ extensionId = ObjectIdentifier.getObjectIdentifier(OID);
+ } catch (IOException e) {
+ // never here
+ }
+ critical = crit;
+ if (oids != null) {
+ oidSet = new Vector<ObjectIdentifier>(oids);
+ } else {
+ oidSet = new Vector<ObjectIdentifier>();
+ }
+ encodeExtValue();
+ }
+
+ public ExtendedKeyUsageExtension(Boolean crit, Object byteVal)
+ throws IOException {
+ extensionId = ObjectIdentifier.getObjectIdentifier(OID);
+ critical = crit.booleanValue();
+ extensionValue = (byte[]) ((byte[]) byteVal).clone();
+ decodeThis();
+ }
+
+ public void setCritical(boolean newValue) {
+ if (critical != newValue) {
+ critical = newValue;
+ mCached = null;
+ }
+ }
+
+ public Enumeration<ObjectIdentifier> getOIDs() {
+ if (oidSet == null)
+ return null;
+ return oidSet.elements();
+ }
+
+ public void deleteAllOIDs() {
+ if (oidSet == null)
+ return;
+ oidSet.clear();
+ }
+
+ public void addOID(ObjectIdentifier oid) {
+ if (oidSet == null) {
+ oidSet = new Vector<ObjectIdentifier>();
+ }
+
+ if (oidSet.contains(oid))
+ return;
+ oidSet.addElement(oid);
+ mCached = null;
+ }
+
+ public void encode(DerOutputStream out) throws IOException {
+ if (mCached == null) {
+ encodeExtValue();
+ super.encode(out);
+ mCached = out.toByteArray();
+ }
+ }
+
+ public String toString() {
+ String presentation = "oid=" + ExtendedKeyUsageExtension.OID + " ";
+
+ if (critical) {
+ presentation += "critical=true";
+ }
+ if (extensionValue != null) {
+ String extByteValue = new String(" val=");
+
+ for (int i = 0; i < extensionValue.length; i++) {
+ extByteValue += (extensionValue[i] + " ");
+ }
+ presentation += extByteValue;
+ }
+ return presentation;
+ }
+
+ public void decode(InputStream in)
+ throws CertificateException, IOException {
+ }
+
+ public void encode(OutputStream out)
+ throws CertificateException, IOException {
+ if (mCached == null) {
+ DerOutputStream temp = new DerOutputStream();
+
+ encode(temp);
+ }
+ out.write(mCached);
+ }
+
+ public void set(String name, Object obj)
+ throws CertificateException, IOException {
+ // NOT USED
+ }
+
+ public Object get(String name) throws CertificateException, IOException {
+ // NOT USED
+ return null;
+ }
+
+ public Enumeration<String> getAttributeNames() {
+ return null;
+ }
+
+ public String getName() {
+ return NAME;
+ }
+
+ public void delete(String name)
+ throws CertificateException, IOException {
+ // NOT USED
+ }
+
+ private void decodeThis() throws IOException {
+ DerValue val = new DerValue(this.extensionValue);
+
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding of AuthInfoAccess extension");
+ }
+ if (oidSet == null)
+ oidSet = new Vector<ObjectIdentifier>();
+ while (val.data.available() != 0) {
+ DerValue oidVal = val.data.getDerValue();
+
+ oidSet.addElement(oidVal.getOID());
+ }
+ }
+
+ private void encodeExtValue() {
+ DerOutputStream out = new DerOutputStream();
+ DerOutputStream temp = new DerOutputStream();
+
+ if (!oidSet.isEmpty()) {
+ Enumeration<ObjectIdentifier> oidList = oidSet.elements();
+
+ try {
+ while (oidList.hasMoreElements()) {
+ temp.putOID((ObjectIdentifier) oidList.nextElement());
+ }
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ try {
+ out.write(DerValue.tag_Sequence, temp);
+ } catch (IOException ex) {
+ }
+
+ extensionValue = out.toByteArray();
+ }
+}
diff --git a/base/util/src/netscape/security/extensions/GenericASN1Extension.java b/base/util/src/netscape/security/extensions/GenericASN1Extension.java
new file mode 100644
index 000000000..ff1ea7173
--- /dev/null
+++ b/base/util/src/netscape/security/extensions/GenericASN1Extension.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 netscape.security.extensions;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.security.cert.CertificateException;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CertAttrSet;
+import netscape.security.x509.Extension;
+import netscape.security.x509.OIDMap;
+
+/**
+ * Represent the AsnInteger Extension.
+ */
+public class GenericASN1Extension extends Extension
+ implements CertAttrSet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8047548816784949009L;
+
+ 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";
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ private String name;
+ public String OID = null;
+ public static Hashtable<String, String> mConfig = null;
+ public String pattern = null;
+ private int index = 0;
+
+ // Encode this value
+ private void encodeThis()
+ throws IOException, ParseException {
+ this.extensionValue = encodePattern();
+ }
+
+ // Encode pattern
+ private byte[] encodePattern()
+ throws IOException, ParseException {
+ DerOutputStream os = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+ String type = null;
+ String value = null;
+ String source = null;
+ while (index < pattern.length()) {
+ char ch = pattern.charAt(index);
+ switch (ch) {
+ case '{':
+ index++;
+ byte[] buff = encodePattern();
+ tmp.putDerValue(new DerValue(buff));
+ break;
+ case '}':
+ os.write(DerValue.tag_Sequence, tmp);
+ return os.toByteArray();
+ default:
+ type = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_TYPE);
+ if (type.equalsIgnoreCase("integer")) {
+ int num = Integer.parseInt((String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE));
+ PutInteger(tmp, num);
+ } else if (type.equalsIgnoreCase("ia5string")) {
+ source = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_SOURCE);
+ value = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE);
+ if (source.equalsIgnoreCase("file"))
+ PutIA5String(tmp, getFromFile(value));
+ else
+ PutIA5String(tmp, value);
+ } else if (type.equalsIgnoreCase("octetstring")) {
+ source = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_SOURCE);
+ value = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE);
+ // It should be colon seperated ASCII Hexdecimal String
+ if (source.equalsIgnoreCase("file"))
+ PutOctetString(tmp, getFromFile(value));
+ else
+ PutOctetString(tmp, value);
+ } else if (type.equalsIgnoreCase("bmpstring")) {
+ source = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_SOURCE);
+ value = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE);
+ if (source.equalsIgnoreCase("file"))
+ PutBMPString(tmp, getFromFile(value));
+ else
+ PutBMPString(tmp, value);
+ } else if (type.equalsIgnoreCase("printablestring")) {
+ source = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_SOURCE);
+ value = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE);
+ if (source.equalsIgnoreCase("file"))
+ PutPrintableString(tmp, getFromFile(value));
+ else
+ PutPrintableString(tmp, value);
+ } else if (type.equalsIgnoreCase("visiblestring")) {
+ source = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_SOURCE);
+ value = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE);
+ if (source.equalsIgnoreCase("file"))
+ PutVisibleString(tmp, getFromFile(value));
+ else
+ PutVisibleString(tmp, value);
+ } else if (type.equalsIgnoreCase("utctime")) {
+ value = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE);
+ PutUTCtime(tmp, value);
+ } else if (type.equalsIgnoreCase("oid")) {
+ value = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE);
+ PutOID(tmp, value);
+ } else if (type.equalsIgnoreCase("boolean")) {
+ boolean bool = false;
+ String b = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE);
+ if (b.equalsIgnoreCase("true"))
+ bool = true;
+ else
+ bool = false;
+ PutBoolean(tmp, bool);
+ } else if (type.equalsIgnoreCase("null")) {
+ tmp.putNull();
+ } else {
+ throw new ParseException("Unknown Attribute Type", 0);
+ }
+ }
+ index++;
+ }
+
+ return tmp.toByteArray();
+ }
+
+ /**
+ * Create a GenericASN1Extension with the value and oid.
+ * The criticality is set to false.
+ *
+ * @param the values to be set for the extension.
+ */
+ public GenericASN1Extension(String name, String oid, String pattern, boolean critical,
+ Hashtable<String, String> config)
+ throws IOException, ParseException {
+ ObjectIdentifier tmpid = new ObjectIdentifier(oid);
+ this.name = name;
+ OID = oid;
+ mConfig = config;
+ this.pattern = pattern;
+
+ try {
+ if (OIDMap.getName(tmpid) == null)
+ OIDMap.addAttribute("netscape.security.x509.GenericASN1Extension", oid, name);
+ } catch (CertificateException e) {
+ }
+
+ this.extensionId = tmpid;
+ this.critical = critical;
+ encodeThis();
+ }
+
+ /**
+ * Create a GenericASN1Extension with the value and oid.
+ * The criticality is set to false.
+ *
+ * @param the values to be set for the extension.
+ */
+ public GenericASN1Extension(Hashtable<String, String> config)
+ throws IOException, ParseException {
+ mConfig = config;
+ ObjectIdentifier tmpid = new ObjectIdentifier((String) mConfig.get(PROP_OID));
+ name = (String) mConfig.get(PROP_NAME);
+ OID = (String) mConfig.get(PROP_OID);
+ pattern = (String) mConfig.get(PROP_PATTERN);
+
+ try {
+ if (OIDMap.getName(tmpid) == null)
+ OIDMap.addAttribute("GenericASN1Extension", OID, name);
+ } catch (CertificateException e) {
+ }
+
+ this.extensionId = tmpid;
+ this.critical = false;
+ String b = (String) mConfig.get(PROP_CRITICAL);
+ if (b.equalsIgnoreCase("true"))
+ this.critical = true;
+ else
+ this.critical = false;
+ encodeThis();
+ }
+
+ /**
+ * Create the extension from the passed DER encoded value of the same.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param value Array of DER encoded bytes of the actual value.
+ * @exception IOException on error.
+ */
+ public GenericASN1Extension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = new ObjectIdentifier(OID);
+ this.critical = critical.booleanValue();
+
+ int len = Array.getLength(value);
+ byte[] extValue = new byte[len];
+ for (int i = 0; i < len; i++) {
+ extValue[i] = Array.getByte(value, i);
+ }
+ this.extensionValue = extValue;
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ return null;
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ /**
+ * Returns a printable representation of the GenericASN1Extension.
+ */
+ public String toString() {
+ return (null);
+ }
+
+ /**
+ * Decode the extension from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ /**
+ * Write the extension to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out)
+ throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ try {
+ if (this.extensionValue == null) {
+ this.extensionId = new ObjectIdentifier(OID);
+ this.critical = true;
+ encodeThis();
+ }
+ } catch (ParseException e) {
+ }
+
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Set the name of this attribute.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Return the OID of this attribute.
+ */
+ public String getOID() {
+ return OID;
+ }
+
+ /**
+ * Set the OID of this attribute.
+ */
+ public void setOID(String oid) {
+ OID = oid;
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement("octet");
+
+ return (elements.elements());
+ }
+
+ private void PutInteger(DerOutputStream os, int number)
+ throws IOException, ParseException {
+ os.putInteger(new BigInt(number));
+ return;
+ }
+
+ private void PutIA5String(DerOutputStream os, String value)
+ throws IOException, ParseException {
+ os.putIA5String(value);
+ return;
+ }
+
+ private void PutOctetString(DerOutputStream os, String value)
+ throws IOException, ParseException {
+ StringTokenizer token = new StringTokenizer(value, ":");
+ byte[] octets = new byte[token.countTokens()];
+ for (int i = 0; token.hasMoreElements(); i++) {
+ String num = (String) token.nextElement();
+ octets[i] = (byte) Integer.parseInt(num, 16);
+ }
+
+ os.putOctetString(octets);
+ return;
+ }
+
+ private void PutBMPString(DerOutputStream os, String value)
+ throws IOException, ParseException {
+ os.putBMPString(value);
+ return;
+ }
+
+ private void PutPrintableString(DerOutputStream os, String value)
+ throws IOException, ParseException {
+ os.putPrintableString(value);
+ return;
+ }
+
+ private void PutVisibleString(DerOutputStream os, String value)
+ throws IOException, ParseException {
+ os.putVisibleString(value);
+ return;
+ }
+
+ private void PutUTCtime(DerOutputStream os, String value)
+ throws IOException, ParseException {
+ DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
+ os.putUTCTime(df.parse(value));
+ return;
+ }
+
+ private void PutOID(DerOutputStream os, String value)
+ throws IOException, ParseException {
+ os.putOID(new ObjectIdentifier(value));
+ return;
+ }
+
+ private void PutBoolean(DerOutputStream os, boolean value)
+ throws IOException, ParseException {
+ os.putBoolean(value);
+ return;
+ }
+
+ private String getFromFile(String fname) throws IOException {
+ String s = null;
+ byte[] buff = null;
+ int i = 0;
+ int j = 0;
+ if ((fname == null) || (fname.equals(""))) {
+ throw new IOException("File name is not provided.");
+ }
+
+ FileInputStream fis = new FileInputStream(fname);
+ int n = 0;
+ while ((n = fis.available()) > 0) {
+ buff = new byte[n];
+ int result = fis.read(buff);
+ if (result == -1)
+ break;
+ s = new String(buff);
+ }
+
+ for (i = 0, j = 0; j < s.length(); j++) {
+ int ch = (int) s.charAt(j);
+ if (ch == 10 || ch == 13 || ch == 9)
+ continue;
+ i++;
+ }
+ buff = new byte[i];
+ for (i = 0, j = 0; j < s.length(); j++) {
+ int ch = (int) s.charAt(j);
+ if (ch == 10 || ch == 13 || ch == 9)
+ continue;
+ buff[i++] = (byte) ch;
+ }
+
+ s = new String(buff);
+
+ return s;
+ }
+}
diff --git a/base/util/src/netscape/security/extensions/InhibitAnyPolicyExtension.java b/base/util/src/netscape/security/extensions/InhibitAnyPolicyExtension.java
new file mode 100644
index 000000000..81b8cf5b5
--- /dev/null
+++ b/base/util/src/netscape/security/extensions/InhibitAnyPolicyExtension.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 netscape.security.extensions;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CertAttrSet;
+import netscape.security.x509.Extension;
+import netscape.security.x509.OIDMap;
+
+/**
+ * RFC3280:
+ *
+ * id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 }
+ *
+ * InhibitAnyPolicy ::= SkipCerts
+ *
+ * SkipCerts ::= INTEGER (0..MAX)
+ */
+public class InhibitAnyPolicyExtension
+ extends Extension implements CertAttrSet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8963439897419343166L;
+ public static final String OID = "2.5.29.54";
+ public static final String NAME = OIDMap.EXT_INHIBIT_ANY_POLICY_NAME;
+
+ private BigInt mSkipCerts = new BigInt(-1);
+
+ static {
+ try {
+ OIDMap.addAttribute(InhibitAnyPolicyExtension.class.getName(),
+ OID, NAME);
+ } catch (CertificateException e) {
+ }
+ }
+
+ public InhibitAnyPolicyExtension() {
+ this(false, null);
+ }
+
+ public InhibitAnyPolicyExtension(boolean crit, BigInt skipCerts) {
+ try {
+ extensionId = ObjectIdentifier.getObjectIdentifier(OID);
+ } catch (IOException e) {
+ // never here
+ }
+ critical = crit;
+ mSkipCerts = skipCerts;
+ encodeExtValue();
+ }
+
+ public InhibitAnyPolicyExtension(Boolean crit, Object value)
+ throws IOException {
+ extensionId = ObjectIdentifier.getObjectIdentifier(OID);
+ critical = crit.booleanValue();
+ //extensionValue = (byte[]) ((byte[]) byteVal).clone();
+ int len = Array.getLength(value);
+ byte[] extValue = new byte[len];
+ for (int i = 0; i < len; i++) {
+ extValue[i] = Array.getByte(value, i);
+ }
+
+ extensionValue = extValue;
+ decodeThis();
+ }
+
+ public void setCritical(boolean newValue) {
+ if (critical != newValue) {
+ critical = newValue;
+ }
+ }
+
+ public BigInt getSkipCerts() {
+ return mSkipCerts;
+ }
+
+ public String toString() {
+ String presentation = "ObjectId: " + OID + " ";
+
+ if (critical) {
+ presentation += "Criticality=true";
+ } else {
+ presentation += "Criticality=false";
+ }
+ if (extensionValue != null) {
+ String extByteValue = new String(" skipCerts=" + mSkipCerts);
+
+ presentation += extByteValue;
+ }
+ return presentation;
+ }
+
+ public void decode(InputStream in)
+ throws CertificateException, IOException {
+ }
+
+ public void set(String name, Object obj)
+ throws CertificateException, IOException {
+ // NOT USED
+ }
+
+ public Object get(String name) throws CertificateException, IOException {
+ // NOT USED
+ return null;
+ }
+
+ public Enumeration<String> getAttributeNames() {
+ return null;
+ }
+
+ public String getName() {
+ return NAME;
+ }
+
+ public void delete(String name)
+ throws CertificateException, IOException {
+ // NOT USED
+ }
+
+ private void decodeThis() throws IOException {
+ DerValue val = new DerValue(this.extensionValue);
+
+ mSkipCerts = val.getInteger();
+ }
+
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ if (this.extensionValue == null) {
+ try {
+ extensionId = ObjectIdentifier.getObjectIdentifier(OID);
+ } catch (IOException e) {
+ // never here
+ }
+ DerOutputStream os = new DerOutputStream();
+ os.putInteger(mSkipCerts);
+ this.extensionValue = os.toByteArray();
+ }
+
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ private void encodeExtValue() {
+ DerOutputStream out = new DerOutputStream();
+ try {
+ out.putInteger(mSkipCerts);
+ } catch (IOException e) {
+ }
+ extensionValue = out.toByteArray();
+ }
+}
diff --git a/base/util/src/netscape/security/extensions/KerberosName.java b/base/util/src/netscape/security/extensions/KerberosName.java
new file mode 100644
index 000000000..0a6a6e213
--- /dev/null
+++ b/base/util/src/netscape/security/extensions/KerberosName.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 netscape.security.extensions;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Vector;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * This represents a KerberosName as defined in
+ * RFC 1510.
+ *
+ * KerberosName ::= SEQUENCE {
+ * realm [0] Realm,
+ * principalName [1] CertPrincipalName -- defined above
+ * }
+ *
+ * CertPrincipalName ::= SEQUENCE {
+ * name-type[0] INTEGER,
+ * name-string[1] SEQUENCE OF UTF8String
+ * }
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class KerberosName {
+
+ public static final int OID[] = { 1, 3, 6, 1, 5, 2, 2 };
+ public static final ObjectIdentifier KRB5_PRINCIPAL_NAME = new
+ ObjectIdentifier(OID);
+
+ private String m_realm = null;
+ private int m_name_type = 0;
+ private Vector<String> m_name_strings = null;
+
+ public KerberosName(String realm, int name_type, Vector<String> name_strings) {
+ m_realm = realm;
+ m_name_type = name_type;
+ m_name_strings = name_strings;
+ }
+
+ /**
+ * Write the extension to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+
+ DerOutputStream seq = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+ DerOutputStream realm = new DerOutputStream();
+ realm.putGeneralString(m_realm);
+ tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ true, (byte) 0), realm);
+
+ DerOutputStream seq1 = new DerOutputStream();
+ DerOutputStream tmp1 = new DerOutputStream();
+ DerOutputStream name_type = new DerOutputStream();
+ name_type.putInteger(new BigInt(m_name_type));
+ tmp1.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ true, (byte) 0), name_type);
+
+ DerOutputStream name_strings = new DerOutputStream();
+ DerOutputStream name_string = new DerOutputStream();
+ for (int i = 0; i < m_name_strings.size(); i++) {
+ name_string.putGeneralString((String) m_name_strings.elementAt(i));
+ }
+ name_strings.write(DerValue.tag_SequenceOf, name_string);
+ tmp1.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ true, (byte) 1), name_strings);
+ seq1.write(DerValue.tag_Sequence, tmp1);
+ tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ true, (byte) 1), seq1);
+
+ seq.write(DerValue.tag_Sequence, tmp);
+ out.write(seq.toByteArray());
+ }
+
+ public byte[] toByteArray() throws IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ encode(bos);
+ return bos.toByteArray();
+ }
+
+ public String toString() {
+ String strings = null;
+ for (int i = 0; i < m_name_strings.size(); i++) {
+ if (strings == null) {
+ strings = (String) m_name_strings.elementAt(i);
+ } else {
+ strings += ",";
+ strings += (String) m_name_strings.elementAt(i);
+ }
+ }
+ return "Realm: " + m_realm + " Name Type: " + m_name_type + " Name String(s):" + strings;
+ }
+
+ public static void main(String[] argv) {
+ Vector<String> strings = new Vector<String>();
+ strings.addElement("name");
+ KerberosName k = new KerberosName("realm", 0, strings);
+
+ System.out.println(k.toString());
+ try {
+ FileOutputStream os = new FileOutputStream("/tmp/out.der");
+ k.encode(os);
+ os.close();
+ } catch (Exception e) {
+ System.out.println(e.toString());
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/extensions/NSCertTypeExtension.java b/base/util/src/netscape/security/extensions/NSCertTypeExtension.java
new file mode 100644
index 000000000..04b3038e5
--- /dev/null
+++ b/base/util/src/netscape/security/extensions/NSCertTypeExtension.java
@@ -0,0 +1,377 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.extensions;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CertAttrSet;
+import netscape.security.x509.Extension;
+
+/**
+ * NSCertTypeExtension
+ * Represents Netscape Certificate Type Extension
+ *
+ * <p>
+ * This deprecated extension, if present, defines both the purpose (e.g., encipherment, signature, certificate signing)
+ * and the application (e.g., SSL, S/Mime or Object Signing of the key contained in the certificate.
+ *
+ * @author galperin
+ * @version $Revision$, $Date$
+ */
+public class NSCertTypeExtension extends Extension implements CertAttrSet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1856407688086284397L;
+
+ // The object identifiers
+ 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);
+
+ /**
+ * Attribute names.
+ */
+ public static final String NAME = "NSCertType";
+ public static final String SSL_CLIENT = "ssl_client";
+ public static final String SSL_SERVER = "ssl_server";
+ public static final String EMAIL = "email";
+ public static final String OBJECT_SIGNING = "object_signing";
+ public static final String SSL_CA = "ssl_ca";
+ public static final String EMAIL_CA = "email_ca";
+ public static final String OBJECT_SIGNING_CA = "object_signing_ca";
+
+ /**
+ * Attribute names.
+ */
+ public static final int SSL_CLIENT_BIT = 0;
+ public static final int SSL_SERVER_BIT = 1;
+ public static final int EMAIL_BIT = 2;
+ public static final int OBJECT_SIGNING_BIT = 3;
+ // 4 is reserved.
+ public static final int SSL_CA_BIT = 5;
+ public static final int EMAIL_CA_BIT = 6;
+ public static final int OBJECT_SIGNING_CA_BIT = 7;
+
+ public static final int NBITS = 8;
+
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT = "x509.info.extensions.NSCertType";
+
+ // Private data members
+ private byte[] mBitString;
+
+ private static class MapEntry {
+ String mName;
+ int mPosition;
+
+ MapEntry(String name, int position) {
+ mName = name;
+ mPosition = position;
+ }
+ }
+
+ private static MapEntry[] mMapData =
+ {
+ new MapEntry(SSL_CLIENT, 0),
+ new MapEntry(SSL_SERVER, 1),
+ new MapEntry(EMAIL, 2),
+ new MapEntry(OBJECT_SIGNING, 3),
+ // note that bit 4 is reserved
+ new MapEntry(SSL_CA, 5),
+ new MapEntry(EMAIL_CA, 6),
+ new MapEntry(OBJECT_SIGNING_CA, 7),
+ };
+
+ private static Vector<String> mAttributeNames = new Vector<String>();
+
+ static {
+ for (int i = 0; i < mMapData.length; ++i) {
+ mAttributeNames.addElement(mMapData[i].mName);
+ }
+ }
+
+ private static int getPosition(String name) throws CertificateException {
+ for (int i = 0; i < mMapData.length; ++i) {
+ if (name.equalsIgnoreCase(mMapData[i].mName))
+ return mMapData[i].mPosition;
+ }
+ throw new CertificateException("Attribute name [" + name
+ + "] not recognized by"
+ + " CertAttrSet:NSCertType.");
+ }
+
+ // Encode this extension value
+ private void encodeThis() throws IOException {
+ DerOutputStream os = new DerOutputStream();
+
+ os.putUnalignedBitString(mBitString);
+ this.extensionValue = os.toByteArray();
+ }
+
+ /**
+ * Check if bit is set.
+ *
+ * @param position the position in the bit string to check.
+ */
+ public boolean isSet(int position) {
+ int index = position / 8;
+ byte pos = (byte) (1 << (7 - (position % 8)));
+
+ if (mBitString.length <= index)
+ return false;
+ return ((mBitString[index] & pos) != 0);
+ }
+
+ /**
+ * Set the bit at the specified position.
+ */
+ public void set(int position, boolean val) {
+ int index = position / 8;
+ byte pos = (byte) (1 << (7 - (position % 8)));
+
+ if (index >= mBitString.length) {
+ byte[] tmp = new byte[index + 1];
+
+ System.arraycopy(mBitString, 0, tmp, 0, mBitString.length);
+ mBitString = tmp;
+ }
+ if (val) {
+ mBitString[index] |= pos;
+ } else {
+ mBitString[index] &= ~pos;
+ }
+ }
+
+ /**
+ * Create NSCertTypeExtension from boolean array.
+ * The criticality is set to false.
+ */
+ public NSCertTypeExtension(boolean critical, boolean[] bits) {
+ this.extensionId = CertType_Id;
+ this.critical = critical;
+ this.mBitString = new byte[0];
+
+ for (int i = 0; i < bits.length && i < 8; i++) {
+ set(i, bits[i]);
+ }
+ }
+
+ public NSCertTypeExtension(boolean[] bits) {
+ this.extensionId = CertType_Id;
+ this.critical = false;
+ this.mBitString = new byte[0];
+
+ for (int i = 0; i < bits.length && i < 8; i++) {
+ set(i, bits[i]);
+ }
+ }
+
+ /**
+ * Create a NSCertTypeExtension with the passed bit settings.
+ * The criticality is set to false.
+ *
+ * @param bitString the bits to be set for the extension.
+ */
+ public NSCertTypeExtension(boolean critical, byte[] bitString) throws IOException {
+ this.mBitString = bitString;
+ this.extensionId = CertType_Id;
+ this.critical = critical;
+ encodeThis();
+ }
+
+ public NSCertTypeExtension(byte[] bitString) throws IOException {
+ this.mBitString = bitString;
+ this.extensionId = CertType_Id;
+ this.critical = false;
+ encodeThis();
+ }
+
+ /**
+ * Create the extension from the passed DER encoded value of the same.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param value Array of DER encoded bytes of the actual value.
+ * @exception IOException on error.
+ */
+ public NSCertTypeExtension(Boolean critical, Object value)
+ throws IOException {
+
+ /**
+ * Debug.trace("NSCertTypeExtension");
+ * this.mBitString = new byte[1];
+ * this.mBitString[0] = (byte)0x00;
+ * return;
+ **/
+
+ this.extensionId = CertType_Id;
+ this.critical = critical.booleanValue();
+ byte[] extValue = (byte[]) ((byte[]) value).clone();
+
+ this.extensionValue = extValue;
+ DerValue val = new DerValue(extValue);
+
+ this.mBitString = val.getUnalignedBitString().toByteArray();
+ }
+
+ /**
+ * Create a default key usage.
+ */
+ public NSCertTypeExtension() {
+ this.extensionId = CertType_Id;
+ this.critical = false;
+ this.mBitString = new byte[0];
+ try {
+ encodeThis();
+ } catch (Exception e) {
+ }
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws CertificateException {
+ if (!(obj instanceof Boolean)) {
+ throw new CertificateException("Attribute must be of type Boolean.");
+ }
+ boolean val = ((Boolean) obj).booleanValue();
+
+ set(getPosition(name), val);
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws CertificateException {
+ return new Boolean(isSet(getPosition(name)));
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws CertificateException {
+ set(getPosition(name), false);
+ }
+
+ /**
+ * Returns a printable representation of the NSCertType.
+ */
+ public String toString() {
+ String s = super.toString() + "NSCertType [\n";
+
+ try {
+
+ if (isSet(getPosition(SSL_CLIENT))) {
+ s += " SSL client";
+ }
+ if (isSet(getPosition(SSL_SERVER))) {
+ s += " SSL server";
+ }
+
+ if (isSet(getPosition(EMAIL))) {
+ s += " Email";
+ }
+
+ if (isSet(getPosition(OBJECT_SIGNING))) {
+ s += " Object Signing";
+ }
+
+ if (isSet(getPosition(SSL_CA))) {
+ s += " SSL CA";
+ }
+
+ if (isSet(getPosition(EMAIL_CA))) {
+ s += " Email CA";
+ }
+
+ if (isSet(getPosition(OBJECT_SIGNING_CA))) {
+ s += " Object Signing CA";
+ }
+
+ } catch (Exception e) {
+ // this is reached only if there is a bug
+ throw new IllegalArgumentException(e.getMessage());
+ }
+
+ s += "]\n";
+
+ return (s);
+ }
+
+ /**
+ * Decode the extension from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ /**
+ * Write the extension to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ encodeThis();
+ if (this.extensionValue == null) {
+ this.extensionId = CertType_Id;
+ this.critical = true;
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ return mAttributeNames.elements();
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+
+ public static void main(String[] argv) {
+ }
+}
diff --git a/base/util/src/netscape/security/extensions/OCSPNoCheckExtension.java b/base/util/src/netscape/security/extensions/OCSPNoCheckExtension.java
new file mode 100644
index 000000000..28da8085f
--- /dev/null
+++ b/base/util/src/netscape/security/extensions/OCSPNoCheckExtension.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 netscape.security.extensions;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CertAttrSet;
+import netscape.security.x509.Extension;
+import netscape.security.x509.OIDMap;
+
+/**
+ * This represents the OCSPNoCheck extension.
+ */
+public class OCSPNoCheckExtension extends Extension implements CertAttrSet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4692759557964594790L;
+ public static final String OID = "1.3.6.1.5.5.7.48.1.5";
+ public static final String NAME = "OCSPNoCheckExtension";
+
+ private byte mCached[] = null;
+
+ static {
+ try {
+ OIDMap.addAttribute(OCSPNoCheckExtension.class.getName(),
+ OID, NAME);
+ } catch (CertificateException e) {
+ }
+ }
+
+ public OCSPNoCheckExtension() {
+ this(Boolean.FALSE);
+ }
+
+ public OCSPNoCheckExtension(Boolean crit) {
+ try {
+ extensionId = ObjectIdentifier.getObjectIdentifier(OCSPNoCheckExtension.OID);
+ } catch (IOException e) {
+ // never here
+ }
+ critical = crit.booleanValue();
+ DerOutputStream tmpD = new DerOutputStream();
+
+ try {
+ tmpD.putNull();
+ } catch (IOException ex) {
+ }
+ extensionValue = tmpD.toByteArray();
+ }
+
+ public OCSPNoCheckExtension(Boolean crit, Object byteVal) {
+ try {
+ extensionId = ObjectIdentifier.getObjectIdentifier(OCSPNoCheckExtension.OID);
+ } catch (IOException e) {
+ // never here
+ }
+ critical = crit.booleanValue();
+ extensionValue = (byte[]) ((byte[]) byteVal).clone();
+ }
+
+ public void setCritical(boolean newValue) {
+ if (critical != newValue) {
+ critical = newValue;
+ mCached = null;
+ }
+ }
+
+ public void encode(DerOutputStream out) throws IOException {
+ if (mCached == null) {
+ super.encode(out);
+ mCached = out.toByteArray();
+ }
+ }
+
+ public String toString() {
+ String presentation = "oid=" + OID + " ";
+
+ if (critical) {
+ presentation += "critical=true";
+ }
+ if (extensionValue != null) {
+ String extByteValue = new String(" val=");
+
+ for (int i = 0; i < extensionValue.length; i++) {
+ extByteValue += (extensionValue[i] + " ");
+ }
+ presentation += extByteValue;
+ }
+ return presentation;
+ }
+
+ public void decode(InputStream in)
+ throws CertificateException, IOException {
+ // NOT USED
+ }
+
+ public void encode(OutputStream out)
+ throws CertificateException, IOException {
+ if (mCached == null) {
+ DerOutputStream temp = new DerOutputStream();
+
+ encode(temp);
+ }
+ out.write(mCached);
+ }
+
+ public void set(String name, Object obj)
+ throws CertificateException, IOException {
+ // NOT USED
+ }
+
+ public Object get(String name) throws CertificateException, IOException {
+ // NOT USED
+ return null;
+ }
+
+ public Enumeration<String> getAttributeNames() {
+ // NOT USED
+ return null;
+ }
+
+ public String getName() {
+ return NAME;
+ }
+
+ public void delete(String name)
+ throws CertificateException, IOException {
+ // NOT USED
+ }
+}
diff --git a/base/util/src/netscape/security/extensions/PresenceServerExtension.java b/base/util/src/netscape/security/extensions/PresenceServerExtension.java
new file mode 100644
index 000000000..c67fe9965
--- /dev/null
+++ b/base/util/src/netscape/security/extensions/PresenceServerExtension.java
@@ -0,0 +1,321 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.extensions;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CertAttrSet;
+import netscape.security.x509.Extension;
+
+public class PresenceServerExtension extends Extension implements CertAttrSet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6333109673043357921L;
+ private boolean mCritical;
+ private String mOID = null;
+ private int mVersion = 0;
+ private String mStreetAddress = null;
+ private String mTelephoneNumber = null;
+ private String mRFC822Name = null;
+ private String mID = null;
+ private String mHostName = null;
+ private int mPortNumber = 0;
+ private int mMaxUsers = 0;
+ private int mServiceLevel = 0;
+
+ public static final String OID = "2.16.840.1.113730.1.18";
+
+ /*
+ public PresenceServerExtension()
+ {
+ }
+ */
+
+ public PresenceServerExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = new ObjectIdentifier(OID);
+ this.critical = critical.booleanValue();
+ this.extensionValue = (byte[]) ((byte[]) value).clone();
+ decodeThis();
+ }
+
+ public PresenceServerExtension(
+ boolean critical,
+ int version,
+ String streetAddress,
+ String telephoneNumber,
+ String rfc822Name,
+ String ID,
+ String hostName,
+ int portNumber,
+ int maxUsers,
+ int serviceLevel)
+ throws IOException {
+ mCritical = critical;
+ mVersion = version;
+ mStreetAddress = streetAddress;
+ mTelephoneNumber = telephoneNumber;
+ mRFC822Name = rfc822Name;
+ mID = ID;
+ mHostName = hostName;
+ mPortNumber = portNumber;
+ mMaxUsers = maxUsers;
+ mServiceLevel = serviceLevel;
+
+ this.extensionId = new ObjectIdentifier(OID);
+ this.critical = mCritical;
+ encodeThis();
+ }
+
+ public int getVersion() {
+ return mVersion;
+ }
+
+ public String getStreetAddress() {
+ return mStreetAddress;
+ }
+
+ public String getTelephoneNumber() {
+ return mTelephoneNumber;
+ }
+
+ public String getRFC822() {
+ return mRFC822Name;
+ }
+
+ public String getID() {
+ return mID;
+ }
+
+ public String getHostName() {
+ return mHostName;
+ }
+
+ public int getPortNumber() {
+ return mPortNumber;
+ }
+
+ public int getMaxUsers() {
+ return mMaxUsers;
+ }
+
+ public int getServiceLevel() {
+ return mServiceLevel;
+ }
+
+ public void encodeThis() throws IOException {
+ DerOutputStream out = new DerOutputStream();
+ DerOutputStream temp = new DerOutputStream();
+ temp.putInteger(new BigInt(mVersion));
+ temp.putOctetString(mStreetAddress.getBytes());
+ temp.putOctetString(mTelephoneNumber.getBytes());
+ temp.putOctetString(mRFC822Name.getBytes());
+ temp.putOctetString(mID.getBytes());
+ temp.putOctetString(mHostName.getBytes());
+ temp.putInteger(new BigInt(mPortNumber));
+ temp.putInteger(new BigInt(mMaxUsers));
+ temp.putInteger(new BigInt(mServiceLevel));
+ out.write(DerValue.tag_Sequence, temp);
+ this.extensionValue = out.toByteArray();
+ }
+
+ public void decodeThis() throws IOException {
+ DerInputStream val = new DerInputStream(this.extensionValue);
+ byte data[] = null;
+ DerValue seq[] = val.getSequence(0);
+
+ mVersion = seq[0].getInteger().toInt();
+ data = null;
+ if (seq[1].length() > 0) {
+ data = seq[1].getOctetString();
+ }
+ if (data == null) {
+ mStreetAddress = "";
+ } else {
+ mStreetAddress = new String(data);
+ }
+ data = null;
+ if (seq[2].length() > 0)
+ data = seq[2].getOctetString();
+ if (data == null) {
+ mTelephoneNumber = "";
+ } else {
+ mTelephoneNumber = new String(data);
+ }
+ data = null;
+ if (seq[3].length() > 0)
+ data = seq[3].getOctetString();
+ if (data == null) {
+ mRFC822Name = "";
+ } else {
+ mRFC822Name = new String(data);
+ }
+ data = null;
+ if (seq[4].length() > 0)
+ data = seq[4].getOctetString();
+ if (data == null) {
+ mID = "";
+ } else {
+ mID = new String(data);
+ }
+ data = null;
+ if (seq[5].length() > 0)
+ data = seq[5].getOctetString();
+ if (data == null) {
+ mHostName = "";
+ } else {
+ mHostName = new String(data);
+ }
+ mPortNumber = seq[6].getInteger().toInt();
+ mMaxUsers = seq[7].getInteger().toInt();
+ mServiceLevel = seq[8].getInteger().toInt();
+ }
+
+ public void decode(InputStream in)
+ throws CertificateException, IOException {
+ }
+
+ public void encode(OutputStream out)
+ throws CertificateException, IOException {
+ DerOutputStream dos = new DerOutputStream();
+ super.encode(dos);
+ out.write(dos.toByteArray());
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ return null;
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ public Enumeration<String> getAttributeNames() {
+ return null;
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return "PresenceServerExtension";
+ }
+
+ /**
+ * Set the name of this attribute.
+ */
+ public void setName(String name) {
+ }
+
+ /**
+ * Return the OID of this attribute.
+ */
+ public String getOID() {
+ return OID;
+ }
+
+ /**
+ * Set the OID of this attribute.
+ */
+ public void setOID(String oid) {
+ }
+
+ public static void main(String args[]) throws Exception {
+ /*
+ 0 30 115: SEQUENCE {
+ 2 06 9: OBJECT IDENTIFIER '2 16 840 1 113730 1 100'
+ 13 04 102: OCTET STRING, encapsulates {
+ 15 30 100: SEQUENCE {
+ 17 02 1: INTEGER 0
+ 20 04 31: OCTET STRING
+ : 34 30 31 45 20 4D 69 64 64 6C 65 66 69 65 6C 64
+ : 20 52 64 2E 2C 4D 56 2C 43 41 39 34 30 34 31
+ 53 04 12: OCTET STRING
+ : 36 35 30 2D 31 31 31 2D 31 31 31 31
+ 67 04 18: OCTET STRING
+ : 61 64 6D 69 6E 40 6E 65 74 73 63 61 70 65 2E 63
+ : 6F 6D
+ 87 04 10: OCTET STRING
+ : 70 73 2D 63 61 70 69 74 6F 6C
+ 99 04 7: OCTET STRING
+ : 63 61 70 69 74 6F 6C
+ 108 02 1: INTEGER 80
+ 111 02 1: INTEGER 10
+ 114 02 1: INTEGER 1
+ : }
+ : }
+ : }
+ */
+ boolean critical = false;
+ int version = 1;
+ String streetAddress = "401E Middlefield Rd.,MV,CA94041";
+ String telephoneNumber = "650-111-1111";
+ String rfc822Name = "admin@netscape.com";
+ String ID = "ps-capitol";
+ String hostName = "capitol";
+ int portNumber = 80;
+ int maxUsers = 10;
+ int serviceLevel = 1;
+
+ PresenceServerExtension ext = new PresenceServerExtension(
+ critical,
+ version, streetAddress, telephoneNumber,
+ rfc822Name, ID, hostName, portNumber,
+ maxUsers, serviceLevel);
+
+ // encode
+
+ ByteArrayOutputStream dos = new ByteArrayOutputStream();
+ ext.encode(dos);
+ FileOutputStream fos = new FileOutputStream("pse.der");
+ fos.write(dos.toByteArray());
+ fos.close();
+
+ Extension ext1 = new Extension(new DerValue(dos.toByteArray()));
+
+ @SuppressWarnings("unused")
+ PresenceServerExtension ext2 = new PresenceServerExtension(
+ new Boolean(false), ext1.getExtensionValue());
+
+ }
+}
diff --git a/base/util/src/netscape/security/extensions/SubjectInfoAccessExtension.java b/base/util/src/netscape/security/extensions/SubjectInfoAccessExtension.java
new file mode 100644
index 000000000..5c373289f
--- /dev/null
+++ b/base/util/src/netscape/security/extensions/SubjectInfoAccessExtension.java
@@ -0,0 +1,254 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.extensions;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import com.netscape.cmsutil.util.Utils;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CertAttrSet;
+import netscape.security.x509.Extension;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.URIName;
+
+/**
+ * This represents the subject information access extension
+ * as defined in RFC3280.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class SubjectInfoAccessExtension extends Extension implements CertAttrSet {
+ private static final long serialVersionUID = 7237321566602583325L;
+
+ public static final String NAME = "SubjectInfoAccessExtension";
+
+ public static final int OID_OCSP[] = { 1, 3, 6, 1, 5, 5, 7, 48, 1 };
+ public static final ObjectIdentifier METHOD_OCSP = new
+ ObjectIdentifier(OID_OCSP);
+
+ public static final int OID_CA_ISSUERS[] = { 1, 3, 6, 1, 5, 5, 7, 48, 2 };
+ public static final ObjectIdentifier METHOD_CA_ISSUERS = new
+ ObjectIdentifier(OID_CA_ISSUERS);
+
+ public static final int OID[] = { 1, 3, 6, 1, 5, 5, 7, 1, 11 };
+ public static final ObjectIdentifier ID = new ObjectIdentifier(OID);
+
+ private Vector<AccessDescription> mDesc = new Vector<AccessDescription>();
+
+ /**
+ * Create the extension from the passed DER encoded value of the same.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param value Array of DER encoded bytes of the actual value.
+ * @exception IOException on error.
+ */
+ public SubjectInfoAccessExtension(boolean critical) {
+ this.extensionId = ID;
+ this.critical = critical;
+ this.extensionValue = null; // build this when encodeThis() is called
+ }
+
+ public SubjectInfoAccessExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = ID;
+ this.critical = critical.booleanValue();
+ this.extensionValue = (byte[]) ((byte[]) value).clone();
+ decodeThis();
+ }
+
+ /**
+ * Sets extension attribute.
+ */
+ public void set(String name, Object obj) throws CertificateException {
+ // NOT USED
+ }
+
+ /**
+ * Retrieves extension attribute.
+ */
+ public Object get(String name) throws CertificateException {
+ // NOT USED
+ return null;
+ }
+
+ /**
+ * Deletes attribute.
+ */
+ public void delete(String name) throws CertificateException {
+ // NOT USED
+ }
+
+ /**
+ * Decodes this extension.
+ */
+ public void decode(InputStream in) throws IOException {
+ // NOT USED
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ // NOT USED
+ return null;
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return NAME;
+ }
+
+ /**
+ * Adds Access Description.
+ */
+ public void addAccessDescription(
+ ObjectIdentifier method,
+ GeneralName gn) {
+ clearValue();
+ mDesc.addElement(new AccessDescription(method, gn));
+ }
+
+ public AccessDescription getAccessDescription(int pos) {
+ return mDesc.elementAt(pos);
+ }
+
+ /**
+ * Returns the number of access description.
+ */
+ public int numberOfAccessDescription() {
+ return mDesc.size();
+ }
+
+ private void decodeThis() throws IOException {
+ DerValue val = new DerValue(this.extensionValue);
+
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding of AuthInfoAccess extension");
+ }
+ while (val.data.available() != 0) {
+ DerValue seq = val.data.getDerValue();
+ ObjectIdentifier method = seq.data.getDerValue().getOID();
+ GeneralName gn = new GeneralName(seq.data.getDerValue());
+
+ addAccessDescription(method, gn);
+ }
+ }
+
+ private void encodeThis() throws IOException {
+ DerOutputStream seq = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+
+ for (int i = 0; i < mDesc.size(); i++) {
+ DerOutputStream tmp0 = new DerOutputStream();
+ AccessDescription ad = mDesc.elementAt(i);
+
+ tmp0.putOID(ad.getMethod());
+ ad.getLocation().encode(tmp0);
+ tmp.write(DerValue.tag_Sequence, tmp0);
+ }
+ seq.write(DerValue.tag_Sequence, tmp);
+ this.extensionValue = seq.toByteArray();
+ }
+
+ /**
+ * Write the extension to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ if (this.extensionValue == null) {
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Returns a printable representation of the AuthInfoAccess.
+ */
+ public String toString() {
+ String s = super.toString() + "AuthInfoAccess [\n";
+
+ for (int i = 0; i < mDesc.size(); i++) {
+ AccessDescription ad = mDesc.elementAt(i);
+
+ s += "(" + i + ")";
+ s += " ";
+ s += ad.getMethod().toString() + " " + ad.getLocation().toString();
+ }
+ return (s + "]\n");
+ }
+
+ public static void main(String[] argv) {
+ AuthInfoAccessExtension aia = new AuthInfoAccessExtension(false);
+ GeneralName ocspName = new GeneralName(new
+ URIName("http://ocsp.netscape.com"));
+
+ aia.addAccessDescription(METHOD_OCSP, ocspName);
+ GeneralName caIssuersName = new GeneralName(new
+ URIName("http://ocsp.netscape.com"));
+
+ aia.addAccessDescription(METHOD_CA_ISSUERS, caIssuersName);
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+
+ try {
+ aia.encode(os);
+
+ System.out.println(Utils.base64encode(os.toByteArray()));
+ } catch (IOException e) {
+ System.out.println(e.toString());
+ }
+
+ try {
+ // test serialization
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(bos);
+
+ oos.writeObject(aia);
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(
+ bos.toByteArray());
+ ObjectInputStream ois = new ObjectInputStream(bis);
+ AuthInfoAccessExtension clone = (AuthInfoAccessExtension)
+ ois.readObject();
+
+ System.out.println(clone);
+ } catch (Exception e) {
+ System.out.println(e.toString());
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/pkcs/ContentInfo.java b/base/util/src/netscape/security/pkcs/ContentInfo.java
new file mode 100644
index 000000000..9825494c2
--- /dev/null
+++ b/base/util/src/netscape/security/pkcs/ContentInfo.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 netscape.security.pkcs;
+
+import java.io.IOException;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * A ContentInfo type, as defined in PKCS#7.
+ *
+ * @version 1.12
+ * @author Benjamin Renaud
+ */
+
+public class ContentInfo {
+
+ // pkcs7 pre-defined content types
+ private static int[] pkcs7 = { 1, 2, 840, 113549, 1, 7 };
+ private static int[] data = { 1, 2, 840, 113549, 1, 7, 1 };
+ private static int[] sdata = { 1, 2, 840, 113549, 1, 7, 2 };
+ private static int[] edata = { 1, 2, 840, 113549, 1, 7, 3 };
+ private static int[] sedata = { 1, 2, 840, 113549, 1, 7, 4 };
+ private static int[] ddata = { 1, 2, 840, 113549, 1, 7, 5 };
+ private static int[] crdata = { 1, 2, 840, 113549, 1, 7, 6 };
+
+ public static final ObjectIdentifier PKCS7_OID =
+ new ObjectIdentifier(pkcs7);
+
+ public static final ObjectIdentifier DATA_OID =
+ new ObjectIdentifier(data);
+
+ public static final ObjectIdentifier SIGNED_DATA_OID =
+ new ObjectIdentifier(sdata);
+
+ public static final ObjectIdentifier ENVELOPED_DATA_OID =
+ new ObjectIdentifier(edata);
+
+ public static final ObjectIdentifier SIGNED_AND_ENVELOPED_DATA_OID =
+ new ObjectIdentifier(sedata);
+
+ public static final ObjectIdentifier DIGESTED_DATA_OID =
+ new ObjectIdentifier(ddata);
+
+ public static final ObjectIdentifier ENCRYPTED_DATA_OID =
+ new ObjectIdentifier(crdata);
+
+ ObjectIdentifier contentType;
+ DerValue content; // OPTIONAL
+
+ public ContentInfo(ObjectIdentifier contentType, DerValue content) {
+ this.contentType = contentType;
+ this.content = content;
+ }
+
+ /**
+ * Make a contentInfo of type data.
+ */
+ public ContentInfo(byte[] bytes) {
+ DerValue octetString = new DerValue(DerValue.tag_OctetString, bytes);
+ this.contentType = DATA_OID;
+ this.content = octetString;
+ }
+
+ public ContentInfo(DerInputStream derin)
+ throws IOException, ParsingException {
+ DerInputStream disType;
+ DerInputStream disTaggedContent;
+ DerValue type;
+ DerValue taggedContent;
+ DerValue[] typeAndContent;
+ DerValue[] contents;
+
+ typeAndContent = derin.getSequence(2);
+
+ // Parse the content type
+ type = typeAndContent[0];
+ disType = new DerInputStream(type.toByteArray());
+ contentType = disType.getOID();
+
+ // Parse the content (OPTIONAL field).
+ // Skip the [0] EXPLICIT tag by pretending that the content is the one
+ // and only element in an implicitly tagged set
+ if (typeAndContent.length > 1) { // content is OPTIONAL
+ taggedContent = typeAndContent[1];
+ disTaggedContent = new DerInputStream(taggedContent.toByteArray());
+ contents = disTaggedContent.getSet(1, true);
+ content = contents[0];
+ }
+ }
+
+ public DerValue getContent() {
+ return content;
+ }
+
+ public byte[] getData() throws IOException {
+ if (contentType.equals(DATA_OID)) {
+ return content.getOctetString();
+ }
+ throw new IOException("content type is not DATA: " + contentType);
+ }
+
+ public void encode(DerOutputStream out) throws IOException {
+ DerOutputStream contentDerCode;
+ DerOutputStream seq;
+ DerValue taggedContent;
+
+ contentDerCode = new DerOutputStream();
+ content.encode(contentDerCode);
+ // Add the [0] EXPLICIT tag in front of the content encoding
+ taggedContent = new DerValue((byte) 0xA0,
+ contentDerCode.toByteArray());
+
+ seq = new DerOutputStream();
+ seq.putOID(contentType);
+ seq.putDerValue(taggedContent);
+
+ out.write(DerValue.tag_Sequence, seq);
+ }
+
+ /**
+ * Returns a byte array representation of the data held in
+ * the content field.
+ */
+ public byte[] getContentBytes() throws IOException {
+ DerInputStream dis = new DerInputStream(content.toByteArray());
+ return dis.getOctetString();
+ }
+
+ public String toString() {
+ String out = "";
+
+ out += "Content Info Sequence\n\tContent type: " + contentType + "\n";
+ out += "\tContent: " + content;
+ return out;
+ }
+}
diff --git a/base/util/src/netscape/security/pkcs/EncodingException.java b/base/util/src/netscape/security/pkcs/EncodingException.java
new file mode 100644
index 000000000..cb495e990
--- /dev/null
+++ b/base/util/src/netscape/security/pkcs/EncodingException.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 netscape.security.pkcs;
+
+public class EncodingException extends Exception {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6126764125859196917L;
+
+ public EncodingException() {
+ super();
+ }
+
+ public EncodingException(String s) {
+ super(s);
+ }
+}
diff --git a/base/util/src/netscape/security/pkcs/PKCS10.java b/base/util/src/netscape/security/pkcs/PKCS10.java
new file mode 100644
index 000000000..a6ddd203f
--- /dev/null
+++ b/base/util/src/netscape/security/pkcs/PKCS10.java
@@ -0,0 +1,343 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.pkcs;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.CertificateException;
+
+import com.netscape.cmsutil.util.Utils;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X500Signer;
+import netscape.security.x509.X509Key;
+
+/**
+ * PKCS #10 certificate requests are created and sent to Certificate
+ * Authorities, which then create X.509 certificates and return them to
+ * the entity which created the certificate request. These cert requests
+ * basically consist of the subject's X.500 name and public key, signed
+ * using the corresponding private key.
+ *
+ * The ASN.1 syntax for a Certification Request is:
+ *
+ * <pre>
+ * CertificationRequest ::= SEQUENCE {
+ * certificationRequestInfo CertificationRequestInfo,
+ * signatureAlgorithm SignatureAlgorithmIdentifier,
+ * signature Signature
+ * }
+ *
+ * SignatureAlgorithmIdentifier ::= AlgorithmIdentifier
+ * Signature ::= BIT STRING
+ *
+ * CertificationRequestInfo ::= SEQUENCE {
+ * version Version,
+ * subject Name,
+ * subjectPublicKeyInfo SubjectPublicKeyInfo,
+ * attributes [0] IMPLICIT Attributes
+ * }
+ * Attributes ::= SET OF Attribute
+ * </pre>
+ *
+ * @author David Brownell
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.28
+ */
+public class PKCS10 {
+ /**
+ * Constructs an unsigned PKCS #10 certificate request. Before this
+ * request may be used, it must be encoded and signed. Then it
+ * must be retrieved in some conventional format (e.g. string).
+ *
+ * @param publicKey the public key that should be placed
+ * into the certificate generated by the CA.
+ */
+ public PKCS10(X509Key publicKey) {
+ subjectPublicKeyInfo = publicKey;
+ attributeSet = new PKCS10Attributes();
+ }
+
+ /**
+ * Constructs an unsigned PKCS #10 certificate request. Before this
+ * request may be used, it must be encoded and signed. Then it
+ * must be retrieved in some conventional format (e.g. string).
+ *
+ * @param publicKey the public key that should be placed
+ * into the certificate generated by the CA.
+ * @param attributes additonal set of PKCS10 attributes requested
+ * for in the certificate.
+ */
+ public PKCS10(X509Key publicKey, PKCS10Attributes attributes) {
+ subjectPublicKeyInfo = publicKey;
+ if (attributes != null)
+ attributeSet = attributes;
+ else
+ attributeSet = new PKCS10Attributes();
+ }
+
+ /**
+ * Parses an encoded, signed PKCS #10 certificate request, verifying
+ * the request's signature as it does so. This constructor would
+ * typically be used by a Certificate Authority, from which a new
+ * certificate would then be constructed.
+ *
+ * @param data the DER-encoded PKCS #10 request.
+ * @param sigver boolean specifies signature verification enabled or not
+ * @exception IOException for low level errors reading the data
+ * @exception SignatureException when the signature is invalid
+ * @exception NoSuchAlgorithmException when the signature
+ * algorithm is not supported in this environment
+ */
+ public PKCS10(byte data[], boolean sigver)
+ throws IOException, SignatureException, NoSuchAlgorithmException, java.security.NoSuchProviderException {
+ DerInputStream in;
+ DerValue seq[];
+ AlgorithmId id;
+ byte sigData[];
+ Signature sig;
+
+ certificateRequest = data;
+
+ //
+ // Outer sequence: request, signature algorithm, signature.
+ // Parse, and prepare to verify later.
+ //
+ in = new DerInputStream(data);
+ seq = in.getSequence(3);
+
+ if (seq.length != 3)
+ throw new IllegalArgumentException("not a PKCS #10 request");
+
+ data = seq[0].toByteArray(); // reusing this variable
+ certRequestInfo = seq[0].toByteArray(); // make a copy
+ id = AlgorithmId.parse(seq[1]);
+ sigData = seq[2].getBitString();
+
+ //
+ // Inner sequence: version, name, key, attributes
+ //
+ @SuppressWarnings("unused")
+ BigInt serial = seq[0].data.getInteger(); // consume serial
+
+ /*
+ if (serial.toInt () != 0)
+ throw new IllegalArgumentException ("not PKCS #10 v1");
+ */
+
+ subject = new X500Name(seq[0].data);
+
+ byte val1[] = seq[0].data.getDerValue().toByteArray();
+ subjectPublicKeyInfo = X509Key.parse(new DerValue(val1));
+ PublicKey publicKey = X509Key.parsePublicKey(new DerValue(val1));
+
+ // Cope with a somewhat common illegal PKCS #10 format
+ if (seq[0].data.available() != 0)
+ attributeSet = new PKCS10Attributes(seq[0].data);
+ else
+ attributeSet = new PKCS10Attributes();
+
+ //
+ // OK, we parsed it all ... validate the signature using the
+ // key and signature algorithm we found.
+ // temporary commented out
+ try {
+ String idName = id.getName();
+ if (idName.equals("MD5withRSA"))
+ idName = "MD5/RSA";
+ else if (idName.equals("MD2withRSA"))
+ idName = "MD2/RSA";
+ else if (idName.equals("SHA1withRSA"))
+ idName = "SHA1/RSA";
+ else if (idName.equals("SHA1withDSA"))
+ idName = "SHA1/DSA";
+ else if (idName.equals("SHA1withEC"))
+ idName = "SHA1/EC";
+ else if (idName.equals("SHA256withEC"))
+ idName = "SHA256/EC";
+ else if (idName.equals("SHA384withEC"))
+ idName = "SHA384/EC";
+ else if (idName.equals("SHA512withEC"))
+ idName = "SHA512/EC";
+
+ if (sigver) {
+ sig = Signature.getInstance(idName, "Mozilla-JSS");
+
+ sig.initVerify(publicKey);
+ sig.update(data);
+ if (!sig.verify(sigData))
+ throw new SignatureException("Invalid PKCS #10 signature");
+ }
+ } catch (InvalidKeyException e) {
+ throw new SignatureException("invalid key");
+ }
+ }
+
+ public PKCS10(byte data[])
+ throws IOException, SignatureException, NoSuchAlgorithmException, java.security.NoSuchProviderException {
+ this(data, true);
+ }
+
+ /**
+ * Create the signed certificate request. This will later be
+ * retrieved in either string or binary format.
+ *
+ * @param requester identifies the signer (by X.500 name)
+ * and provides the private key used to sign.
+ * @exception IOException on errors.
+ * @exception CertificateException on certificate handling errors.
+ * @exception SignatureException on signature handling errors.
+ */
+ public void encodeAndSign(X500Signer requester)
+ throws CertificateException, IOException, SignatureException {
+ DerOutputStream out, scratch;
+ byte certificateRequestInfo[];
+ byte sig[];
+
+ if (certificateRequest != null)
+ throw new SignatureException("request is already signed");
+
+ subject = requester.getSigner();
+
+ /*
+ * Encode cert request info, wrap in a sequence for signing
+ */
+ scratch = new DerOutputStream();
+ scratch.putInteger(new BigInt(0)); // version zero
+ subject.encode(scratch); // X.500 name
+ subjectPublicKeyInfo.encode(scratch); // public key
+ attributeSet.encode(scratch);
+
+ out = new DerOutputStream();
+ out.write(DerValue.tag_Sequence, scratch); // wrap it!
+ certificateRequestInfo = out.toByteArray();
+ scratch = out;
+
+ /*
+ * Sign it ...
+ */
+ requester.update(certificateRequestInfo, 0,
+ certificateRequestInfo.length);
+ sig = requester.sign();
+
+ /*
+ * Build guts of SIGNED macro
+ */
+ requester.getAlgorithmId().encode(scratch); // sig algorithm
+ scratch.putBitString(sig); // sig
+
+ /*
+ * Wrap those guts in a sequence
+ */
+ out = new DerOutputStream();
+ out.write(DerValue.tag_Sequence, scratch);
+ certificateRequest = out.toByteArray();
+ }
+
+ /**
+ * Returns the subject's name.
+ */
+ public X500Name getSubjectName() {
+ return subject;
+ }
+
+ /**
+ * Returns the subject's public key.
+ */
+ public X509Key getSubjectPublicKeyInfo() {
+ return subjectPublicKeyInfo;
+ }
+
+ /**
+ * Returns the additional attributes requested.
+ */
+ public PKCS10Attributes getAttributes() {
+ return attributeSet;
+ }
+
+ /**
+ * Returns the encoded and signed certificate request as a
+ * DER-encoded byte array.
+ *
+ * @return the certificate request, or null if encodeAndSign()
+ * has not yet been called.
+ */
+ public byte[] toByteArray() {
+ return certificateRequest;
+ }
+
+ /**
+ * Prints an E-Mailable version of the certificate request on the print
+ * stream passed. The format is a common base64 encoded one, supported
+ * by most Certificate Authorities because Netscape web servers have
+ * used this for some time. Some certificate authorities expect some
+ * more information, in particular contact information for the web
+ * server administrator.
+ *
+ * @param out the print stream where the certificate request
+ * will be printed.
+ * @exception IOException when an output operation failed
+ * @exception SignatureException when the certificate request was
+ * not yet signed.
+ */
+ public void print(PrintStream out)
+ throws IOException, SignatureException {
+ if (certificateRequest == null)
+ throw new SignatureException("Cert request was not signed");
+
+ out.println("-----BEGIN NEW CERTIFICATE REQUEST-----");
+ out.println(Utils.base64encode(certificateRequest));
+ out.println("-----END NEW CERTIFICATE REQUEST-----");
+ }
+
+ /**
+ * Provides a short description of this request.
+ */
+ public String toString() {
+ return "[PKCS #10 certificate request:\n"
+ + subjectPublicKeyInfo.toString()
+ + " subject: <" + subject + ">" + "\n"
+ + " attributes: " + attributeSet.toString()
+ + "\n]";
+ }
+
+ /**
+ * Retrieve the PKCS10 CertificateRequestInfo as a byte array
+ */
+ public byte[] getCertRequestInfo() {
+ return certRequestInfo;
+ }
+
+ private X500Name subject;
+ private X509Key subjectPublicKeyInfo;
+ private PKCS10Attributes attributeSet;
+
+ private byte certificateRequest[]; // signed
+ private byte certRequestInfo[]; // inner content signed
+}
diff --git a/base/util/src/netscape/security/pkcs/PKCS10Attribute.java b/base/util/src/netscape/security/pkcs/PKCS10Attribute.java
new file mode 100644
index 000000000..a649c395a
--- /dev/null
+++ b/base/util/src/netscape/security/pkcs/PKCS10Attribute.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 netscape.security.pkcs;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.security.cert.CertificateException;
+
+import netscape.security.util.DerEncoder;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.ACertAttrSet;
+import netscape.security.x509.CertAttrSet;
+import netscape.security.x509.Extensions;
+import netscape.security.x509.OIDMap;
+
+/**
+ * Represent a PKCS Attribute.
+ *
+ * <p>
+ * Attributes are addiitonal attributes which can be inserted in a PKCS certificate request. For example a
+ * "Driving License Certificate" could have the driving license number as a attribute.
+ *
+ * <p>
+ * Attributes are represented as a sequence of the attribute identifier (Object Identifier) and a set of DER encoded
+ * attribute values. The current implementation only supports one value per attribute.
+ *
+ * ASN.1 definition of Attribute:
+ *
+ * <pre>
+ * Attribute :: SEQUENCE {
+ * type AttributeValue,
+ * values SET OF AttributeValue
+ * }
+ * AttributeValue ::= ANY
+ * </pre>
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.13
+ */
+public class PKCS10Attribute implements DerEncoder, Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2002480042340316170L;
+ protected ObjectIdentifier attributeId = null;
+ protected CertAttrSet attributeValue = null;
+
+ /**
+ * Default constructor. Used only by sub-classes.
+ */
+ public PKCS10Attribute() {
+ }
+
+ /**
+ * Constructs an attribute from a DER encoded array of bytes.
+ */
+ public PKCS10Attribute(DerValue derVal) throws IOException {
+ if (derVal.tag != DerValue.tag_Sequence) {
+ throw new IOException("Sequence tag missing for PKCS10Attribute.");
+ }
+
+ DerInputStream in = derVal.toDerInputStream();
+ // Object identifier
+ attributeId = in.getOID();
+ // System.out.println("attribute ID in pkcs10 "+attributeId.toString());
+
+ // Rest of the stuff is attribute value(s), wrapped in a SET.
+ // For now, assume there is only one attribute value present.
+ DerValue[] inAttrValues = in.getSet(1);
+ int attrValueNum = inAttrValues.length;
+ if (attrValueNum > 1) {
+ throw new IOException("More than one value per attribute not supported");
+ }
+
+ // Read the first attribute value
+ DerValue inAttrValue = inAttrValues[0];
+
+ if (attributeId.equals(PKCS9Attribute.EXTENSION_REQUEST_OID)) {
+ //pkcs9 extensionAttr
+ try {
+ // remove the tag
+ //DerValue dv = inAttrValue.data.getDerValue();
+ // hack. toDerInputStream only gives one extension.
+ DerInputStream fi = new DerInputStream(inAttrValue.toByteArray());
+ attributeValue = (CertAttrSet) new
+ Extensions(fi);
+ //CertificateExtensions(fi);
+ return;
+ } catch (Exception e) {
+ throw new IOException(e.toString());
+ }
+ }
+ byte[] val = inAttrValue.toByteArray();
+ Class<?>[] params = { Object.class };
+ try {
+ @SuppressWarnings("unchecked")
+ Class<CertAttrSet> extClass = (Class<CertAttrSet>) OIDMap.getClass(attributeId);
+ if (extClass != null) {
+ Constructor<CertAttrSet> cons = (Constructor<CertAttrSet>) extClass.getConstructor(params);
+ Object value = Array.newInstance(byte.class, val.length);
+ for (int i = 0; i < val.length; i++) {
+ Array.setByte(value, i, val[i]);
+ }
+ Object[] passed = new Object[] { value };
+ attributeValue = cons.newInstance(passed);
+ } else {
+ // attribute classes are usable for PKCS10 attributes.
+ // this is used where the attributes are not actual
+ // implemented extensions.
+ attributeValue = new ACertAttrSet(inAttrValue);
+ }
+ } catch (InvocationTargetException invk) {
+ throw new IOException(invk.getTargetException().getMessage());
+ } catch (Exception e) {
+ throw new IOException(e.toString());
+ }
+ }
+
+ /**
+ * Constructs an attribute from individual components of ObjectIdentifier
+ * and the DER encoded value.
+ *
+ * @param attributeId the ObjectIdentifier of the attribute.
+ * @param attributeValue the CertAttrSet.
+ */
+ public PKCS10Attribute(ObjectIdentifier attributeId,
+ CertAttrSet attributeValue) {
+ this.attributeId = attributeId;
+ this.attributeValue = attributeValue;
+ }
+
+ /**
+ * Constructs an attribute from another attribute. To be used for
+ * creating decoded subclasses.
+ *
+ * @param attr the attribute to create from.
+ */
+ public PKCS10Attribute(PKCS10Attribute attr) {
+ this.attributeId = attr.attributeId;
+ this.attributeValue = attr.attributeValue;
+ }
+
+ /**
+ * Write the output to the DerOutputStream.
+ *
+ * @param out the OutputStream to write the attribute to.
+ * @exception CertificateException on certificate encoding errors.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out)
+ throws CertificateException, IOException {
+ // Encode the attribute value
+ DerOutputStream outAttrValue = new DerOutputStream();
+ attributeValue.encode(outAttrValue);
+
+ // Wrap the encoded attribute value into a SET
+ DerValue outAttrValueSet = new DerValue(DerValue.tag_Set,
+ outAttrValue.toByteArray());
+
+ // Create the attribute
+ DerOutputStream outAttr = new DerOutputStream();
+ outAttr.putOID(attributeId);
+ outAttr.putDerValue(outAttrValueSet);
+
+ // Wrap the OID and the set of attribute values into a SEQUENCE
+ DerOutputStream tmp = new DerOutputStream();
+ tmp.write(DerValue.tag_Sequence, outAttr);
+
+ // write the results to out
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * DER encode this object onto an output stream.
+ * Implements the <code>DerEncoder</code> interface.
+ *
+ * @param out
+ * the OutputStream on which to write the DER encoding.
+ *
+ * @exception IOException on encoding errors.
+ */
+ public void derEncode(OutputStream out) throws IOException {
+ try {
+ encode(out);
+ } catch (CertificateException ce) {
+ IOException ioe = new IOException(ce.toString());
+ ioe.fillInStackTrace();
+ throw ioe;
+ }
+ }
+
+ /**
+ * Returns the ObjectIdentifier of the attribute.
+ */
+ public ObjectIdentifier getAttributeId() {
+ return (attributeId);
+ }
+
+ /**
+ * Returns the attribute value as an byte array for further processing.
+ */
+ public CertAttrSet getAttributeValue() {
+ return (attributeValue);
+ }
+
+ /**
+ * Returns the attribute in user readable form.
+ */
+ public String toString() {
+ String s = "AttributeId: " + attributeId.toString() + "\n";
+ s += "AttributeValue: " + attributeValue.toString();
+
+ return (s);
+ }
+}
diff --git a/base/util/src/netscape/security/pkcs/PKCS10Attributes.java b/base/util/src/netscape/security/pkcs/PKCS10Attributes.java
new file mode 100644
index 000000000..8beb1e64c
--- /dev/null
+++ b/base/util/src/netscape/security/pkcs/PKCS10Attributes.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 netscape.security.pkcs;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import netscape.security.util.DerEncoder;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class defines the PKCS10 attributes for the request.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.10
+ */
+public class PKCS10Attributes extends Vector<PKCS10Attribute> implements DerEncoder {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1362260612357629542L;
+ private Hashtable<String, PKCS10Attribute> map;
+
+ /**
+ * Default constructor for the certificate attribute.
+ */
+ public PKCS10Attributes() {
+ map = new Hashtable<String, PKCS10Attribute>();
+ }
+
+ /**
+ * Create the object, decoding the values from the passed DER stream.
+ *
+ * @param in the DerInputStream to read the attributes from.
+ * @exception IOException on decoding errors.
+ */
+ public PKCS10Attributes(DerInputStream in)
+ throws IOException {
+
+ map = new Hashtable<String, PKCS10Attribute>();
+ DerValue[] attrs = in.getSet(5, true);
+
+ if (attrs != null) {
+ for (int i = 0; i < attrs.length; i++) {
+ PKCS10Attribute attr = new PKCS10Attribute(attrs[i]);
+ addElement(attr);
+ map.put(attr.getAttributeValue().getName(), attr);
+ }
+ }
+ }
+
+ /**
+ * Encode the attributes in DER form to the stream.
+ *
+ * @param out the OutputStream to marshal the contents to.
+ *
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out)
+ throws IOException {
+ derEncode(out);
+ }
+
+ /**
+ * Encode the attributes in DER form to the stream.
+ * Implements the <code>DerEncoder</code> interface.
+ *
+ * @param out the OutputStream to marshal the contents to.
+ * @exception IOException on encoding errors.
+ */
+ public void derEncode(OutputStream out)
+ throws IOException {
+
+ // first copy the elements into an array
+ PKCS10Attribute[] attribs = new PKCS10Attribute[size()];
+ copyInto(attribs);
+
+ DerOutputStream attrOut = new DerOutputStream();
+ attrOut.putOrderedSetOf(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0),
+ attribs);
+
+ out.write(attrOut.toByteArray());
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void setAttribute(String name, PKCS10Attribute attr) throws IOException {
+ map.put(name, attr);
+ addElement(attr);
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public PKCS10Attribute getAttribute(String name) throws IOException {
+ PKCS10Attribute attr = map.get(name);
+ /*
+ if (attr == null) {
+ throw new IOException("No attribute found with name " + name);
+ }
+ */
+ return (attr);
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void deleteAttribute(String name) throws IOException {
+ PKCS10Attribute attr = map.get(name);
+ if (attr == null) {
+ throw new IOException("No attribute found with name " + name);
+ }
+ map.remove(name);
+ removeElement(attr);
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<PKCS10Attribute> getElements() {
+ return map.elements();
+ }
+}
diff --git a/base/util/src/netscape/security/pkcs/PKCS7.java b/base/util/src/netscape/security/pkcs/PKCS7.java
new file mode 100644
index 000000000..c8fb69582
--- /dev/null
+++ b/base/util/src/netscape/security/pkcs/PKCS7.java
@@ -0,0 +1,446 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.pkcs;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.security.NoSuchAlgorithmException;
+import java.security.SignatureException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Vector;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+
+/**
+ * PKCS7 as defined in RSA Laboratories PKCS7 Technical Note. Profile
+ * Supports only <tt>SignedData</tt> ContentInfo
+ * type, where to the type of data signed is plain Data.
+ * For signedData, <tt>crls</tt>, <tt>attributes</tt> and
+ * PKCS#6 Extended Certificates are not supported.
+ *
+ * @version 1.33 97/12/10
+ * @author Benjamin Renaud
+ */
+public class PKCS7 {
+
+ private ObjectIdentifier contentType;
+
+ // the ASN.1 members for a signedData (and other) contentTypes
+ private BigInt version;
+ private AlgorithmId[] digestAlgorithmIds;
+ private ContentInfo contentInfo;
+ private X509Certificate[] certificates;
+ private SignerInfo[] signerInfos;
+
+ /**
+ * Unmarshals a PKCS7 block from its encoded form, parsing the
+ * encoded bytes from the InputStream.
+ *
+ * @param in an input stream holding at least one PKCS7 block.
+ * @exception ParsingException on parsing errors.
+ * @exception IOException on other errors.
+ */
+ public PKCS7(InputStream in) throws ParsingException, IOException {
+ DataInputStream dis = new DataInputStream(in);
+
+ int len = 0;
+ byte[] newbuf = new byte[len];
+ byte[] oldbuf = new byte[len];
+ byte[] data = new byte[len];
+
+ do {
+ newbuf = new byte[dis.available()];
+ len += dis.available();
+ dis.readFully(newbuf);
+ data = new byte[len];
+
+ System.arraycopy(oldbuf, 0, data, 0, oldbuf.length);
+ System.arraycopy(newbuf, 0, data, oldbuf.length, newbuf.length);
+ oldbuf = new byte[len];
+ System.arraycopy(data, 0, oldbuf, 0, data.length);
+
+ } while (dis.available() > 0);
+
+ parse(new DerInputStream(data));
+ }
+
+ /**
+ * Unmarshals a PKCS7 block from its encoded form, parsing the
+ * encoded bytes from the DerInputStream.
+ *
+ * @param derin a DerInputStream holding at least one PKCS7 block.
+ * @exception ParsingException on parsing errors.
+ */
+ public PKCS7(DerInputStream derin) throws ParsingException {
+ parse(derin);
+ }
+
+ /**
+ * Unmarshals a PKCS7 block from its encoded form, parsing the
+ * encoded bytes.
+ *
+ * @param bytes the encoded bytes.
+ * @exception ParsingException on parsing errors.
+ */
+ public PKCS7(byte[] bytes) throws ParsingException {
+ DerInputStream derin = new DerInputStream(bytes);
+ parse(derin);
+ }
+
+ private void parse(DerInputStream derin) throws ParsingException {
+ try {
+ ContentInfo contentInfo = new ContentInfo(derin);
+ contentType = contentInfo.contentType;
+ if (contentType.equals(ContentInfo.SIGNED_DATA_OID)) {
+ parseSignedData(contentInfo.getContent());
+ } else {
+ throw new ParsingException("content type " + contentType +
+ " not supported.");
+ }
+ } catch (IOException e) {
+ ParsingException pe =
+ new ParsingException("IOException: " + e.getMessage());
+ pe.fillInStackTrace();
+ throw pe;
+ }
+ }
+
+ /**
+ * Construct an initialized PKCS7 block.
+ *
+ * @param digestAlgorithmIds the message digest algorithm identifiers.
+ * @param contentInfo the content information.
+ * @param certificates an array of X.509 certificates.
+ * @param signerInfos an array of signer information.
+ */
+ public PKCS7(AlgorithmId[] digestAlgorithmIds,
+ ContentInfo contentInfo,
+ X509Certificate[] certificates,
+ SignerInfo[] signerInfos) {
+
+ version = new BigInt(1);
+ this.digestAlgorithmIds = digestAlgorithmIds;
+ this.contentInfo = contentInfo;
+ this.certificates = certificates;
+ this.signerInfos = signerInfos;
+ }
+
+ private void parseSignedData(DerValue val)
+ throws ParsingException, IOException {
+
+ DerInputStream dis = val.toDerInputStream();
+
+ // Version
+ version = dis.getInteger();
+
+ // digestAlgorithmIds
+ DerValue[] digestAlgorithmIdVals = dis.getSet(1);
+ int len = digestAlgorithmIdVals.length;
+ digestAlgorithmIds = new AlgorithmId[len];
+ try {
+ for (int i = 0; i < len; i++) {
+ DerValue oid = digestAlgorithmIdVals[i];
+ digestAlgorithmIds[i] = AlgorithmId.parse(oid);
+ }
+
+ } catch (IOException e) {
+ ParsingException pe =
+ new ParsingException("Error parsing digest AlgorithmId IDs: " +
+ e.getMessage());
+ pe.fillInStackTrace();
+ throw pe;
+ }
+ // contentInfo
+ contentInfo = new ContentInfo(dis);
+
+ /*
+ * check if certificates (implicit tag) are provided
+ * (certificates are OPTIONAL)
+ */
+ if ((byte) (dis.peekByte()) == (byte) 0xA0) {
+ DerValue[] certificateVals = dis.getSet(2, true);
+
+ len = certificateVals.length;
+ certificates = new X509Certificate[len];
+
+ for (int i = 0; i < len; i++) {
+ try {
+ X509Certificate cert = (X509Certificate) new
+ X509CertImpl(certificateVals[i]);
+ certificates[i] = cert;
+ } catch (CertificateException e) {
+ ParsingException pe =
+ new ParsingException("CertificateException: " +
+ e.getMessage());
+ pe.fillInStackTrace();
+ throw pe;
+ }
+ }
+ }
+
+ // check if crls (implicit tag) are provided (crls are OPTIONAL)
+ if ((byte) (dis.peekByte()) == (byte) 0xA1) {
+ dis.getSet(0, true);
+ }
+
+ // signerInfos
+ DerValue[] signerInfoVals = dis.getSet(1);
+
+ len = signerInfoVals.length;
+ signerInfos = new SignerInfo[len];
+
+ for (int i = 0; i < len; i++) {
+ DerInputStream in = signerInfoVals[i].toDerInputStream();
+ signerInfos[i] = new SignerInfo(in);
+ }
+
+ }
+
+ /**
+ * Encodes the signed data to an output stream.
+ *
+ * @param out the output stream to write the encoded data to.
+ * @exception IOException on encoding errors.
+ */
+ public void encodeSignedData(OutputStream out) throws IOException {
+ DerOutputStream derout = new DerOutputStream();
+ encodeSignedData(derout, true);
+ out.write(derout.toByteArray());
+ }
+
+ /**
+ * Like method above but not sorted.
+ */
+ public void encodeSignedData(OutputStream out, boolean sort)
+ throws IOException {
+ DerOutputStream derout = new DerOutputStream();
+ encodeSignedData(derout, sort);
+ out.write(derout.toByteArray());
+ }
+
+ /**
+ * encode signed data, sort certs by default.
+ */
+ public void encodeSignedData(DerOutputStream out)
+ throws IOException {
+ encodeSignedData(out, true);
+ }
+
+ /**
+ * Encodes the signed data to a DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the encoded data to.
+ * @exception IOException on encoding errors.
+ */
+ public void encodeSignedData(DerOutputStream out, boolean sort)
+ throws IOException {
+
+ DerOutputStream signedData = new DerOutputStream();
+
+ // version
+ signedData.putInteger(version);
+
+ // digestAlgorithmIds
+ signedData.putOrderedSetOf(DerValue.tag_Set, digestAlgorithmIds);
+
+ // contentInfo
+ contentInfo.encode(signedData);
+
+ // cast to X509CertImpl[] since X509CertImpl implements DerEncoder
+ X509CertImpl implCerts[] = new X509CertImpl[certificates.length];
+ try {
+ for (int i = 0; i < certificates.length; i++) {
+ implCerts[i] = (X509CertImpl) certificates[i];
+ }
+ } catch (ClassCastException e) {
+ IOException ioe =
+ new IOException("Certificates in PKCS7 " +
+ "must be of class " +
+ "netscape.security.X509CertImpl");
+ ioe.fillInStackTrace();
+ }
+
+ // Add the certificate set (tagged with [0] IMPLICIT)
+ // to the signed data
+ if (sort) {
+ signedData.putOrderedSetOf((byte) 0xA0, implCerts);
+ } else {
+ signedData.putSet((byte) 0xA0, implCerts);
+ }
+
+ // no crls (OPTIONAL field)
+
+ // signerInfos
+ signedData.putOrderedSetOf(DerValue.tag_Set, signerInfos);
+
+ // making it a signed data block
+ DerValue signedDataSeq = new DerValue(DerValue.tag_Sequence,
+ signedData.toByteArray());
+
+ // making it a content info sequence
+ ContentInfo block = new ContentInfo(ContentInfo.SIGNED_DATA_OID,
+ signedDataSeq);
+
+ // writing out the contentInfo sequence
+ block.encode(out);
+ }
+
+ /**
+ * This verifies a given SignerInfo.
+ *
+ * @param info the signer information.
+ * @param bytes the DER encoded content information.
+ *
+ * @exception NoSuchAlgorithmException on unrecognized algorithms.
+ * @exception SignatureException on signature handling errors.
+ */
+ public SignerInfo verify(SignerInfo info, byte[] bytes)
+ throws NoSuchAlgorithmException, SignatureException {
+ return info.verify(this, bytes);
+ }
+
+ /**
+ * Returns all signerInfos which self-verify.
+ *
+ * @param bytes the DER encoded content information.
+ *
+ * @exception NoSuchAlgorithmException on unrecognized algorithms.
+ * @exception SignatureException on signature handling errors.
+ */
+ public SignerInfo[] verify(byte[] bytes)
+ throws NoSuchAlgorithmException, SignatureException {
+
+ Vector<SignerInfo> intResult = new Vector<SignerInfo>();
+ for (int i = 0; i < signerInfos.length; i++) {
+
+ SignerInfo signerInfo = verify(signerInfos[i], bytes);
+ if (signerInfo != null) {
+ intResult.addElement(signerInfo);
+ }
+ }
+ if (intResult.size() != 0) {
+
+ SignerInfo[] result = new SignerInfo[intResult.size()];
+ intResult.copyInto(result);
+ return result;
+ }
+ return null;
+ }
+
+ /**
+ * Returns all signerInfos which self-verify.
+ *
+ * @exception NoSuchAlgorithmException on unrecognized algorithms.
+ * @exception SignatureException on signature handling errors.
+ */
+ public SignerInfo[] verify()
+ throws NoSuchAlgorithmException, SignatureException {
+ return verify(null);
+ }
+
+ /**
+ * Returns the version number of this PKCS7 block.
+ */
+ public BigInt getVersion() {
+ return version;
+ }
+
+ /**
+ * Returns the message digest algorithms specified in this PKCS7 block.
+ */
+ public AlgorithmId[] getDigestAlgorithmIds() {
+ return digestAlgorithmIds;
+ }
+
+ /**
+ * Returns the content information specified in this PKCS7 block.
+ */
+ public ContentInfo getContentInfo() {
+ return contentInfo;
+ }
+
+ /**
+ * Returns the X.509 certificates listed in this PKCS7 block.
+ */
+ public X509Certificate[] getCertificates() {
+ return certificates;
+ }
+
+ /**
+ * Returns the signer's information specified in this PKCS7 block.
+ */
+ public SignerInfo[] getSignerInfos() {
+ return signerInfos;
+ }
+
+ /**
+ * Returns the X.509 certificate listed in this PKCS7 block
+ * which has a matching serial number and Issuer name, or
+ * null if one is not found.
+ *
+ * @param serial the serial number of the certificate to retrieve.
+ * @param name the Distinguished Name of the Issuer.
+ */
+ public X509Certificate getCertificate(BigInt serial, X500Name name) {
+
+ for (int i = 0; i < certificates.length; i++) {
+ X509Certificate cert = certificates[i];
+ X500Name thisName = (X500Name) cert.getIssuerDN();
+ BigInteger tmpSerial = (BigInteger) cert.getSerialNumber();
+ BigInt thisSerial = new BigInt(tmpSerial);
+ if (serial.equals(thisSerial) && name.equals(thisName)) {
+ return cert;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the PKCS7 block in a printable string form.
+ */
+ public String toString() {
+ String out = "";
+
+ out += "PKCS7 :: version: " + version + "\n";
+ out += "PKCS7 :: digest AlgorithmIds: \n";
+ for (int i = 0; i < digestAlgorithmIds.length; i++) {
+ out += "\t" + digestAlgorithmIds[i] + "\n";
+ }
+ out += contentInfo + "\n";
+ out += "PKCS7 :: certificates: \n";
+ for (int i = 0; i < certificates.length; i++) {
+ out += "\t" + i + ". " + certificates[i] + "\n";
+ }
+ out += "PKCS7 :: signer infos: \n";
+ for (int i = 0; i < signerInfos.length; i++) {
+ out += ("\t" + i + ". " + signerInfos[i] + "\n");
+ }
+ return out;
+ }
+}
diff --git a/base/util/src/netscape/security/pkcs/PKCS8Key.java b/base/util/src/netscape/security/pkcs/PKCS8Key.java
new file mode 100644
index 000000000..7c5f64582
--- /dev/null
+++ b/base/util/src/netscape/security/pkcs/PKCS8Key.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 netscape.security.pkcs;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.Security;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.x509.AlgorithmId;
+
+/**
+ * Holds a PKCS#8 key, for example a private key
+ *
+ * @version 1.30, 97/12/10
+ * @author Dave Brownell
+ * @author Benjamin Renaud
+ */
+public class PKCS8Key implements PrivateKey {
+
+ /** use serialVersionUID from JDK 1.1. for interoperability */
+ private static final long serialVersionUID = -3836890099307167124L;
+
+ /* The algorithm information (name, parameters, etc). */
+ protected AlgorithmId algid;
+
+ /* The key bytes, without the algorithm information */
+ protected byte[] key;
+
+ /* The encoded for the key. */
+ protected byte[] encodedKey;
+
+ /* The version for this key */
+ public static final BigInteger VERSION = BigInteger.valueOf(0);
+
+ /**
+ * Default constructor. The key constructed must have its key
+ * and algorithm initialized before it may be used, for example
+ * by using <code>decode</code>.
+ */
+ public PKCS8Key() {
+ }
+
+ /**
+ * Construct PKCS#8 subject public key from a DER value. If
+ * the runtime environment is configured with a specific class for
+ * this kind of key, a subclass is returned. Otherwise, a generic
+ * PKCS8Key object is returned.
+ *
+ * <P>
+ * This mechanism gurantees that keys (and algorithms) may be freely manipulated and transferred, without risk of
+ * losing information. Also, when a key (or algorithm) needs some special handling, that specific need can be
+ * accomodated.
+ *
+ * @param in the DER-encoded SubjectPublicKeyInfo value
+ * @exception IOException on data format errors
+ */
+ public static PKCS8Key parse(DerValue in) throws IOException {
+ AlgorithmId algorithm;
+ PKCS8Key subjectKey;
+
+ if (in.tag != DerValue.tag_Sequence)
+ throw new IOException("corrupt private key");
+
+ BigInteger parsedVersion = in.data.getInteger().toBigInteger();
+ if (!VERSION.equals(parsedVersion)) {
+ throw new IOException("version mismatch: (supported: " +
+ VERSION + ", parsed: " +
+ parsedVersion);
+ }
+
+ algorithm = AlgorithmId.parse(in.data.getDerValue());
+
+ try {
+ subjectKey = buildPKCS8Key(algorithm, in.data.getOctetString());
+
+ } catch (InvalidKeyException e) {
+ throw new IOException("corrupt private key");
+ }
+
+ if (in.data.available() != 0)
+ throw new IOException("excess private key");
+ return subjectKey;
+ }
+
+ /**
+ * Parse the key bits. This may be redefined by subclasses to take
+ * advantage of structure within the key. For example, RSA public
+ * keys encapsulate two unsigned integers (modulus and exponent) as
+ * DER values within the <code>key</code> bits; Diffie-Hellman and
+ * DSS/DSA keys encapsulate a single unsigned integer.
+ *
+ * <P>
+ * This function is called when creating PKCS#8 SubjectPublicKeyInfo values using the PKCS8Key member functions,
+ * such as <code>parse</code> and <code>decode</code>.
+ *
+ * @exception IOException if a parsing error occurs.
+ * @exception InvalidKeyException if the key encoding is invalid.
+ */
+ protected void parseKeyBits() throws IOException, InvalidKeyException {
+ encode();
+ }
+
+ /*
+ * Factory interface, building the kind of key associated with this
+ * specific algorithm ID or else returning this generic base class.
+ * See the description above.
+ */
+ public static PKCS8Key buildPKCS8Key(AlgorithmId algid, byte[] key)
+ throws IOException, InvalidKeyException {
+ /*
+ * Use the algid and key parameters to produce the ASN.1 encoding
+ * of the key, which will then be used as the input to the
+ * key factory.
+ */
+ DerOutputStream pkcs8EncodedKeyStream = new DerOutputStream();
+ encode(pkcs8EncodedKeyStream, algid, key);
+ PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(pkcs8EncodedKeyStream.toByteArray());
+
+ try {
+ // Instantiate the key factory of the appropriate algorithm
+ KeyFactory keyFac = KeyFactory.getInstance(algid.getName());
+
+ // Generate the private key
+ PrivateKey privKey = keyFac.generatePrivate(pkcs8KeySpec);
+
+ if (privKey instanceof PKCS8Key) {
+ /*
+ * Return specialized PKCS8Key, where the structure within the
+ * key has been parsed
+ */
+ return (PKCS8Key) privKey;
+ }
+ } catch (NoSuchAlgorithmException e) {
+ // Return generic PKCS8Key with opaque key data (see below)
+ } catch (InvalidKeySpecException e) {
+ // Return generic PKCS8Key with opaque key data (see below)
+ }
+
+ /*
+ * Try again using JDK1.1-style for backwards compatibility.
+ */
+ String classname = "";
+ try {
+ Provider sunProvider;
+
+ sunProvider = Security.getProvider("SUN");
+ if (sunProvider == null)
+ throw new InstantiationException();
+ classname = sunProvider.getProperty("PrivateKey.PKCS#8." +
+ algid.getName());
+ if (classname == null) {
+ throw new InstantiationException();
+ }
+
+ Class<?> keyClass = Class.forName(classname);
+ Object inst;
+ PKCS8Key result;
+
+ inst = keyClass.newInstance();
+ if (inst instanceof PKCS8Key) {
+ result = (PKCS8Key) inst;
+ result.algid = algid;
+ result.key = key;
+ result.parseKeyBits();
+ return result;
+ }
+ } catch (ClassNotFoundException e) {
+ } catch (InstantiationException e) {
+ } catch (IllegalAccessException e) {
+ // this should not happen.
+ throw new IOException(classname + " [internal error]");
+ }
+
+ PKCS8Key result = new PKCS8Key();
+ result.algid = algid;
+ result.key = key;
+ return result;
+ }
+
+ /**
+ * Returns the algorithm to be used with this key.
+ */
+ public String getAlgorithm() {
+ return algid.getName();
+ }
+
+ /**
+ * Returns the algorithm ID to be used with this key.
+ */
+ public AlgorithmId getAlgorithmId() {
+ return algid;
+ }
+
+ /**
+ * PKCS#8 sequence on the DER output stream.
+ */
+ public final void encode(DerOutputStream out) throws IOException {
+ encode(out, this.algid, this.key);
+ }
+
+ /**
+ * Returns the DER-encoded form of the key as a byte array.
+ */
+ public synchronized byte[] getEncoded() {
+ byte[] result = null;
+ try {
+ result = encode();
+ } catch (InvalidKeyException e) {
+ }
+ return result;
+ }
+
+ /**
+ * Returns the format for this key: "PKCS#8"
+ */
+ public String getFormat() {
+ return "PKCS#8";
+ }
+
+ /**
+ * Returns the DER-encoded form of the key as a byte array.
+ *
+ * @exception InvalidKeyException if an encoding error occurs.
+ */
+ public byte[] encode() throws InvalidKeyException {
+ if (encodedKey == null) {
+ try {
+ DerOutputStream out;
+
+ out = new DerOutputStream();
+ encode(out);
+ encodedKey = out.toByteArray();
+
+ } catch (IOException e) {
+ throw new InvalidKeyException("IOException : " +
+ e.getMessage());
+ }
+ }
+ return copyEncodedKey(encodedKey);
+ }
+
+ /*
+ * Returns a printable representation of the key
+ */
+ public String toString() {
+ netscape.security.util.PrettyPrintFormat pp =
+ new netscape.security.util.PrettyPrintFormat(" ", 20);
+ String keybits = pp.toHexString(key);
+
+ return "algorithm = " + algid.toString()
+ + ", unparsed keybits = \n" + keybits;
+ }
+
+ /**
+ * Initialize an PKCS8Key object from an input stream. The data
+ * on that input stream must be encoded using DER, obeying the
+ * PKCS#8 format: a sequence consisting of a version, an algorithm
+ * ID and a bit string which holds the key. (That bit string is
+ * often used to encapsulate another DER encoded sequence.)
+ *
+ * <P>
+ * Subclasses should not normally redefine this method; they should instead provide a <code>parseKeyBits</code>
+ * method to parse any fields inside the <code>key</code> member.
+ *
+ * @param in an input stream with a DER-encoded PKCS#8
+ * SubjectPublicKeyInfo value
+ *
+ * @exception InvalidKeyException if a parsing error occurs.
+ */
+ public void decode(InputStream in) throws InvalidKeyException {
+ DerValue val;
+
+ try {
+ val = new DerValue(in);
+ if (val.tag != DerValue.tag_Sequence)
+ throw new InvalidKeyException("invalid key format");
+
+ BigInteger version = val.data.getInteger().toBigInteger();
+ if (!version.equals(PKCS8Key.VERSION)) {
+ throw new IOException("version mismatch: (supported: " +
+ PKCS8Key.VERSION + ", parsed: " +
+ version);
+ }
+ algid = AlgorithmId.parse(val.data.getDerValue());
+ key = val.data.getOctetString();
+ parseKeyBits();
+ if (val.data.available() != 0)
+ throw new InvalidKeyException("excess key data");
+
+ } catch (IOException e) {
+ // e.printStackTrace ();
+ throw new InvalidKeyException("IOException : " +
+ e.getMessage());
+ }
+ }
+
+ public void decode(byte[] encodedKey) throws InvalidKeyException {
+ decode(new ByteArrayInputStream(encodedKey));
+ }
+
+ /**
+ * Serialization write ... PKCS#8 keys serialize as
+ * themselves, and they're parsed when they get read back.
+ */
+ private synchronized void
+ writeObject(java.io.ObjectOutputStream stream)
+ throws IOException {
+ stream.write(getEncoded());
+ }
+
+ /**
+ * Serialization read ... PKCS#8 keys serialize as
+ * themselves, and they're parsed when they get read back.
+ */
+ private synchronized void readObject(ObjectInputStream stream)
+ throws IOException {
+
+ try {
+ decode(stream);
+
+ } catch (InvalidKeyException e) {
+ e.printStackTrace();
+ throw new IOException("deserialized key is invalid: " +
+ e.getMessage());
+ }
+ }
+
+ /*
+ * Make a copy of the encoded key.
+ */
+ private byte[] copyEncodedKey(byte[] encodedKey) {
+ int len = encodedKey.length;
+ byte[] copy = new byte[len];
+ System.arraycopy(encodedKey, 0, copy, 0, len);
+ return copy;
+ }
+
+ /*
+ * Produce PKCS#8 encoding from algorithm id and key material.
+ */
+ static void encode(DerOutputStream out, AlgorithmId algid, byte[] key)
+ throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ tmp.putInteger(new BigInt(VERSION.toByteArray()));
+ algid.encode(tmp);
+ tmp.putOctetString(key);
+ out.write(DerValue.tag_Sequence, tmp);
+ }
+
+ /**
+ * Compares two private keys. This returns false if the object with which
+ * to compare is not of type <code>Key</code>.
+ * Otherwise, the encoding of this key object is compared with the
+ * encoding of the given key object.
+ *
+ * @param object the object with which to compare
+ * @return <code>true</code> if this key has the same encoding as the
+ * object argument; <code>false</code> otherwise.
+ */
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+
+ if (object instanceof Key) {
+
+ // this encoding
+ byte[] b1;
+ if (encodedKey != null) {
+ b1 = encodedKey;
+ } else {
+ b1 = getEncoded();
+ }
+
+ // that encoding
+ byte[] b2 = ((Key) object).getEncoded();
+
+ // do the comparison
+ int i;
+ if (b1.length != b2.length)
+ return false;
+ for (i = 0; i < b1.length; i++) {
+ if (b1[i] != b2[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Calculates a hash code value for this object. Objects
+ * which are equal will also have the same hashcode.
+ */
+ public int hashCode() {
+ int retval = 0;
+ byte[] b1 = getEncoded();
+
+ for (int i = 1; i < b1.length; i++) {
+ retval += b1[i] * i;
+ }
+ return (retval);
+ }
+}
diff --git a/base/util/src/netscape/security/pkcs/PKCS9Attribute.java b/base/util/src/netscape/security/pkcs/PKCS9Attribute.java
new file mode 100644
index 000000000..6a6fd7dc9
--- /dev/null
+++ b/base/util/src/netscape/security/pkcs/PKCS9Attribute.java
@@ -0,0 +1,1123 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.pkcs;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.cert.CertificateException;
+import java.util.Date;
+import java.util.Hashtable;
+
+import netscape.security.util.DerEncoder;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CertificateExtensions;
+
+/**
+ * Class supporting any PKCS9 attribute except
+ * ExtendedCertificateAttribute. Supports DER decoding and access to
+ * attribute values, but not DER encoding or setting of values.
+ *
+ * @version 1.2 97/12/10
+ * @author Douglas Hoover
+ */
+public class PKCS9Attribute implements DerEncoder {
+
+ /*
+ * OIDs of PKCS #9 attribute types.
+ */
+ private static final String RSADSI_str = "1.2.840.113549";
+ private static final String PKCS_str = RSADSI_str + ".1";
+ private static final String PKCS9_str = PKCS_str + ".9";
+
+ /**
+ * Array of attribute OIDs defined in PKCS9, by number.
+ */
+ static final ObjectIdentifier[] PKCS9_OIDS =
+ //new ObjectIdentifier[10];
+ // There are some Obsolete(?) attribute identifiers.
+ // This is mainly for extensionRequest (14) in pkcs10.
+ // We just add the other 4 as by products.
+ new ObjectIdentifier[15];
+
+ static { // static initializer for PKCS9_OIDS
+ for (int i = 1; i < PKCS9_OIDS.length; i++) {
+ PKCS9_OIDS[i] = new ObjectIdentifier(PKCS9_str + "." + i);
+ }
+ }
+
+ public static final ObjectIdentifier EMAIL_ADDRESS_OID = PKCS9_OIDS[1];
+ public static final ObjectIdentifier UNSTRUCTURED_NAME_OID = PKCS9_OIDS[2];
+ public static final ObjectIdentifier CONTENT_TYPE_OID = PKCS9_OIDS[3];
+ public static final ObjectIdentifier MESSAGE_DIGEST_OID = PKCS9_OIDS[4];
+ public static final ObjectIdentifier SIGNING_TIME_OID = PKCS9_OIDS[5];
+ public static final ObjectIdentifier COUNTERSIGNATURE_OID = PKCS9_OIDS[6];
+ public static final ObjectIdentifier CHALLENGE_PASSWORD_OID = PKCS9_OIDS[7];
+ public static final ObjectIdentifier UNSTRUCTURED_ADDRESS_OID = PKCS9_OIDS[8];
+ public static final ObjectIdentifier EXTENDED_CERTIFICATE_ATTRIBUTES_OID = PKCS9_OIDS[9];
+
+ public static final ObjectIdentifier ISSUER_AND_SERIALNUMBER_OID = PKCS9_OIDS[10];
+ public static final ObjectIdentifier PASSWORD_CHECK_OID = PKCS9_OIDS[11];
+ public static final ObjectIdentifier PUBLIC_KEY_OID = PKCS9_OIDS[12];
+ public static final ObjectIdentifier SIGNING_DESCRIPTION_OID = PKCS9_OIDS[13];
+ public static final ObjectIdentifier EXTENSION_REQUEST_OID = PKCS9_OIDS[14];
+
+ public static final String EMAIL_ADDRESS_STR = "EmailAddress";
+ public static final String UNSTRUCTURED_NAME_STR = "UnstructuredName";
+ public static final String CONTENT_TYPE_STR = "ContentType";
+ public static final String MESSAGE_DIGEST_STR = "MessageDigest";
+ public static final String SIGNING_TIME_STR = "SigningTime";
+ public static final String COUNTERSIGNATURE_STR = "Countersignature";
+ public static final String CHALLENGE_PASSWORD_STR = "ChallengePassword";
+ public static final String UNSTRUCTURED_ADDRESS_STR = "UnstructuredAddress";
+ public static final String EXTENDED_CERTIFICATE_ATTRIBUTES_STR = "ExtendedCertificateAttributes";
+
+ public static final String ISSUER_AND_SERIALNUMBER_STR = "IssuerAndSerialNumber";
+ public static final String PASSWORD_CHECK_STR = "PasswordCheck";
+ public static final String PUBLIC_KEY_STR = "PublicKey";
+ public static final String SIGNING_DESCRIPTION_STR = "SigningDescription";
+ public static final String EXTENSION_REQUEST_STR = "ExtensionRequest";
+
+ /**
+ * Hashtable mapping names and variant names of supported
+ * attributes to their OIDs. This table contains all name forms
+ * that occur in PKCS9, in lower case.
+ */
+ private static final Hashtable<String, ObjectIdentifier> NAME_OID_TABLE = new Hashtable<String, ObjectIdentifier>(
+ 28);
+
+ static { // static initializer for PCKS9_NAMES
+ NAME_OID_TABLE.put("emailaddress", PKCS9_OIDS[1]);
+ NAME_OID_TABLE.put("unstructuredname", PKCS9_OIDS[2]);
+ NAME_OID_TABLE.put("contenttype", PKCS9_OIDS[3]);
+ NAME_OID_TABLE.put("messagedigest", PKCS9_OIDS[4]);
+ NAME_OID_TABLE.put("signingtime", PKCS9_OIDS[5]);
+ NAME_OID_TABLE.put("countersignature", PKCS9_OIDS[6]);
+ NAME_OID_TABLE.put("challengepassword", PKCS9_OIDS[7]);
+ NAME_OID_TABLE.put("unstructuredaddress", PKCS9_OIDS[8]);
+ NAME_OID_TABLE.put("extendedcertificateattributes", PKCS9_OIDS[9]);
+
+ NAME_OID_TABLE.put("issuerandserialNumber", PKCS9_OIDS[10]);
+ NAME_OID_TABLE.put("passwordcheck", PKCS9_OIDS[11]);
+ NAME_OID_TABLE.put("publickey", PKCS9_OIDS[12]);
+ NAME_OID_TABLE.put("signingdescription", PKCS9_OIDS[13]);
+ NAME_OID_TABLE.put("extensionrequest", PKCS9_OIDS[14]);
+ };
+
+ /**
+ * Hashtable mapping attribute OIDs defined in PKCS9 to the
+ * corresponding attribute value type.
+ */
+ private static final Hashtable<ObjectIdentifier, String> OID_NAME_TABLE = new Hashtable<ObjectIdentifier, String>(
+ 14);
+ static {
+ OID_NAME_TABLE.put(PKCS9_OIDS[1], EMAIL_ADDRESS_STR);
+ OID_NAME_TABLE.put(PKCS9_OIDS[2], UNSTRUCTURED_NAME_STR);
+ OID_NAME_TABLE.put(PKCS9_OIDS[3], CONTENT_TYPE_STR);
+ OID_NAME_TABLE.put(PKCS9_OIDS[4], MESSAGE_DIGEST_STR);
+ OID_NAME_TABLE.put(PKCS9_OIDS[5], SIGNING_TIME_STR);
+ OID_NAME_TABLE.put(PKCS9_OIDS[6], COUNTERSIGNATURE_STR);
+ OID_NAME_TABLE.put(PKCS9_OIDS[7], CHALLENGE_PASSWORD_STR);
+ OID_NAME_TABLE.put(PKCS9_OIDS[8], UNSTRUCTURED_ADDRESS_STR);
+ OID_NAME_TABLE.put(PKCS9_OIDS[9], EXTENDED_CERTIFICATE_ATTRIBUTES_STR);
+
+ OID_NAME_TABLE.put(PKCS9_OIDS[10], ISSUER_AND_SERIALNUMBER_STR);
+ OID_NAME_TABLE.put(PKCS9_OIDS[11], PASSWORD_CHECK_STR);
+ OID_NAME_TABLE.put(PKCS9_OIDS[12], PUBLIC_KEY_STR);
+ OID_NAME_TABLE.put(PKCS9_OIDS[13], SIGNING_DESCRIPTION_STR);
+ OID_NAME_TABLE.put(PKCS9_OIDS[14], EXTENSION_REQUEST_STR);
+ }
+
+ /**
+ * Acceptable ASN.1 tags for DER encodings of values of PKCS9
+ * attributes, by index in <code>PKCS9_OIDS</code>.
+ * Sets of acceptable tags are represented as arrays.
+ */
+ private static final Byte[][] PKCS9_VALUE_TAGS = {
+ null,
+ { Byte.valueOf(DerValue.tag_IA5String) }, // EMailAddress
+ { Byte.valueOf(DerValue.tag_IA5String) }, // UnstructuredName
+ { Byte.valueOf(DerValue.tag_ObjectId) }, // ContentType
+ { Byte.valueOf(DerValue.tag_OctetString) }, // MessageDigest
+ { Byte.valueOf(DerValue.tag_UtcTime) }, // SigningTime
+ { Byte.valueOf(DerValue.tag_Sequence) }, // Countersignature
+ { Byte.valueOf(DerValue.tag_PrintableString),
+ Byte.valueOf(DerValue.tag_T61String) }, // ChallengePassword
+ { Byte.valueOf(DerValue.tag_PrintableString),
+ Byte.valueOf(DerValue.tag_T61String) }, // UnstructuredAddress
+ { Byte.valueOf(DerValue.tag_SetOf) }, // ExtendedCertificateAttributes
+
+ null, //IssuerAndSerialNumber
+ null, //PasswordCheck
+ null, //PublicKey
+ null, //SigningDescription
+ { Byte.valueOf(DerValue.tag_Sequence) } //ExtensionRequest
+ };
+
+ /**
+ * Class types required for values for a given PKCS9
+ * attribute type.
+ *
+ * <P>
+ * The following table shows the correspondence between attribute types and value component classes.
+ *
+ * <P>
+ * <TABLE BORDER CELLPADDING=8 ALIGN=CENTER>
+ *
+ * <TR>
+ * <TH>OID</TH>
+ * <TH>Attribute Type Name</TH>
+ * <TH>Kind</TH>
+ * <TH>Value Class</TH>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.1</TD>
+ * <TD>EmailAddress</TD>
+ * <TD>Multiple-valued</TD>
+ * <TD><code>String[]</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.2</TD>
+ * <TD>UnstructuredName</TD>
+ * <TD>Multiple-valued</TD>
+ * <TD><code>String</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.3</TD>
+ * <TD>ContentType</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>ObjectIdentifier</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.4</TD>
+ * <TD>MessageDigest</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>byte[]</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.5</TD>
+ * <TD>SigningTime</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>Date</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.6</TD>
+ * <TD>Countersignature</TD>
+ * <TD>Multiple-valued</TD>
+ * <TD><code>SignerInfo</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.7</TD>
+ * <TD>ChallengePassword</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>String</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.8</TD>
+ * <TD>UnstructuredAddress</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>String</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.9</TD>
+ * <TD>ExtendedCertificateAttributes</TD>
+ * <TD>Multiple-valued</TD>
+ * <TD>(not supported)</TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.10</TD>
+ * <TD>IssuerAndSerialNumber</TD>
+ * <TD>Single-valued</TD>
+ * <TD>(not supported)</TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.11</TD>
+ * <TD>PasswordCheck</TD>
+ * <TD>Single-valued</TD>
+ * <TD>(not supported)</TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.12</TD>
+ * <TD>PublicKey</TD>
+ * <TD>Single-valued</TD>
+ * <TD>(not supported)</TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.13</TD>
+ * <TD>SigningDescription</TD>
+ * <TD>Single-valued</TD>
+ * <TD>(not supported)</TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.14</TD>
+ * <TD>ExtensionRequest</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>Sequence</code></TD>
+ * </TR>
+ *
+ * </TABLE>
+ */
+ private static final Class<?>[] VALUE_CLASSES = new Class[15];
+
+ static {
+ VALUE_CLASSES[0] = null; // not used
+ VALUE_CLASSES[1] = String[].class; // EMailAddress
+ VALUE_CLASSES[2] = String[].class; // UnstructuredName
+ VALUE_CLASSES[3] = ObjectIdentifier.class; // ContentType
+ VALUE_CLASSES[4] = byte[].class; // MessageDigest (byte[])
+ VALUE_CLASSES[5] = Date.class; // SigningTime
+ VALUE_CLASSES[6] = SignerInfo[].class; // Countersignature
+ VALUE_CLASSES[7] = String.class; // ChallengePassword
+ VALUE_CLASSES[8] = String[].class; // UnstructuredAddress
+ VALUE_CLASSES[9] = null; // ExtendedCertificateAttributes
+
+ VALUE_CLASSES[10] = null; // IssuerAndSerialNumber
+ VALUE_CLASSES[11] = null; // PasswordCheck
+ VALUE_CLASSES[12] = null; // PublicKey
+ VALUE_CLASSES[13] = null; // SigningDescription
+ VALUE_CLASSES[14] = CertificateExtensions.class; // ExtensionRequest
+ }
+
+ /**
+ * Array indicating which PKCS9 attributes are single-valued,
+ * by index in <code>PKCS9_OIDS</code>.
+ */
+ private static final boolean[] SINGLE_VALUED =
+ { false,
+ false, // EMailAddress
+ false, // UnstructuredName
+ true, // ContentType
+ true, // MessageDigest
+ true, // SigningTime
+ false, // Countersignature
+ true, // ChallengePassword
+ false, // UnstructuredAddress
+ false, // ExtendedCertificateAttributes
+
+ true, // IssuerAndSerialNumber
+ true, // PasswordCheck
+ true, // PublicKey
+ true, // SigningDescription
+ true // ExtensionRequest
+ };
+
+ /**
+ * The OID of this attribute is <code>PKCS9_OIDS[index]</code>.
+ */
+ private int index;
+
+ /**
+ * Value set of this attribute. Its class is given by <code>VALUE_CLASSES[index]</code>.
+ */
+ private Object value;
+
+ /**
+ * Construct an attribute object from the attribute's OID and
+ * value. If the attribute is single-valued, provide only one
+ * value. If the attribute is
+ * multiple-valued, provide an array containing all the values.
+ * Arrays of length zero are accepted, though probably useless.
+ *
+ * <P>
+ * The following table gives the class that <code>value</code> must have for a given attribute.
+ *
+ * <P>
+ * <TABLE BORDER CELLPADDING=8 ALIGN=CENTER>
+ *
+ * <TR>
+ * <TH>OID</TH>
+ * <TH>Attribute Type Name</TH>
+ * <TH>Kind</TH>
+ * <TH>Value Class</TH>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.1</TD>
+ * <TD>EmailAddress</TD>
+ * <TD>Multiple-valued</TD>
+ * <TD><code>String[]</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.2</TD>
+ * <TD>UnstructuredName</TD>
+ * <TD>Multiple-valued</TD>
+ * <TD><code>String[]</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.3</TD>
+ * <TD>ContentType</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>ObjectIdentifier</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.4</TD>
+ * <TD>MessageDigest</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>byte[]</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.5</TD>
+ * <TD>SigningTime</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>Date</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.6</TD>
+ * <TD>Countersignature</TD>
+ * <TD>Multiple-valued</TD>
+ * <TD><code>SignerInfo[]</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.7</TD>
+ * <TD>ChallengePassword</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>String</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.8</TD>
+ * <TD>UnstructuredAddress</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>String[]</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.9</TD>
+ * <TD>ExtendedCertificateAttributes</TD>
+ * <TD>Multiple-valued</TD>
+ * <TD>(not supported)</TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.10</TD>
+ * <TD>IssuerAndSerialNumber</TD>
+ * <TD>Single-valued</TD>
+ * <TD>(not supported)</TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.11</TD>
+ * <TD>PasswordCheck</TD>
+ * <TD>Single-valued</TD>
+ * <TD>(not supported)</TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.12</TD>
+ * <TD>PublicKey</TD>
+ * <TD>Single-valued</TD>
+ * <TD>(not supported)</TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.13</TD>
+ * <TD>SigningDescription</TD>
+ * <TD>Single-valued</TD>
+ * <TD>(not supported)</TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.14</TD>
+ * <TD>ExtensionRequest</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>Sequence</code></TD>
+ * </TR>
+ *
+ * </TABLE>
+ */
+ public PKCS9Attribute(ObjectIdentifier oid, Object value)
+ throws IllegalArgumentException {
+
+ init(oid, value);
+ }
+
+ /**
+ * Construct an attribute object from the attribute's name and
+ * value. If the attribute is single-valued, provide only one
+ * value. If the attribute is
+ * multiple-valued, provide an array containing all the values.
+ * Arrays of length zero are accepted, though probably useless.
+ *
+ * <P>
+ * The following table gives the class that <code>value</code> must have for a given attribute. Reasonable variants
+ * of these attributes are accepted; in particular, case does not matter.
+ *
+ * <P>
+ * <TABLE BORDER CELLPADDING=8 ALIGN=CENTER>
+ *
+ * <TR>
+ * <TH>OID</TH>
+ * <TH>Attribute Type Name</TH>
+ * <TH>Kind</TH>
+ * <TH>Value Class</TH>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.1</TD>
+ * <TD>EmailAddress</TD>
+ * <TD>Multiple-valued</TD>
+ * <TD><code>String[]</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.2</TD>
+ * <TD>UnstructuredName</TD>
+ * <TD>Multiple-valued</TD>
+ * <TD><code>String[]</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.3</TD>
+ * <TD>ContentType</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>ObjectIdentifier</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.4</TD>
+ * <TD>MessageDigest</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>byte[]</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.5</TD>
+ * <TD>SigningTime</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>Date</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.6</TD>
+ * <TD>Countersignature</TD>
+ * <TD>Multiple-valued</TD>
+ * <TD><code>SignerInfo[]</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.7</TD>
+ * <TD>ChallengePassword</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>String</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.8</TD>
+ * <TD>UnstructuredAddress</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>String[]</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.9</TD>
+ * <TD>ExtendedCertificateAttributes</TD>
+ * <TD>Multiple-valued</TD>
+ * <TD>(not supported)</TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.10</TD>
+ * <TD>IssuerAndSerialNumber</TD>
+ * <TD>Single-valued</TD>
+ * <TD>(not supported)</TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.11</TD>
+ * <TD>PasswordCheck</TD>
+ * <TD>Single-valued</TD>
+ * <TD>(not supported)</TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.12</TD>
+ * <TD>PublicKey</TD>
+ * <TD>Single-valued</TD>
+ * <TD>(not supported)</TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.13</TD>
+ * <TD>SigningDescription</TD>
+ * <TD>Single-valued</TD>
+ * <TD>(not supported)</TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.14</TD>
+ * <TD>ExtensionRequest</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>Sequence</code></TD>
+ * </TR>
+ *
+ * </TABLE>
+ *
+ * @exception IllegalArgumentException
+ * if the <code>name</code> is not recognized of the <code>value</code> has the wrong type.
+ */
+ public PKCS9Attribute(String name, Object value)
+ throws IllegalArgumentException {
+ ObjectIdentifier oid = getOID(name);
+
+ if (oid == null)
+ throw new IllegalArgumentException(
+ "Unrecognized attribute name " + name +
+ " constructing PKCS9Attribute.");
+
+ init(oid, value);
+ }
+
+ private void init(ObjectIdentifier oid, Object value)
+ throws IllegalArgumentException {
+
+ index = indexOf(oid, PKCS9_OIDS, 1);
+
+ if (index == -1)
+ throw new IllegalArgumentException(
+ "Unsupported OID " + oid +
+ " constructing PKCS9Attribute.");
+
+ if (!VALUE_CLASSES[index].isInstance(value))
+ throw new IllegalArgumentException(
+ "Wrong value class " +
+ " for attribute " + oid +
+ " constructing PKCS9Attribute; was " +
+ value.getClass().toString() + ", should be " +
+ VALUE_CLASSES[index].toString());
+
+ this.value = value;
+ }
+
+ /**
+ * Construct a PKCS9Attribute from its encoding on an input
+ * stream.
+ *
+ * @exception IOException on parsing error.
+ */
+ public PKCS9Attribute(DerValue derVal) throws IOException {
+
+ decode(derVal);
+ }
+
+ /**
+ * Decode a PKCS9 attribute.
+ *
+ * @param val
+ * the DerValue representing the DER encoding of the attribute.
+ */
+ private void decode(DerValue derVal) throws IOException {
+ DerInputStream derIn = new DerInputStream(derVal.toByteArray());
+ DerValue[] val = derIn.getSequence(2);
+
+ if (derIn.available() != 0)
+ throw new IOException("Excess data parsing PKCS9Attribute");
+
+ if (val.length != 2)
+ throw new IOException("PKCS9Attribute doesn't have two components");
+
+ DerValue[] elems;
+
+ // get the oid
+ ObjectIdentifier oid = val[0].getOID();
+
+ index = indexOf(oid, PKCS9_OIDS, 1);
+ Byte tag;
+
+ if (index == -1)
+ throw new IOException("Invalid OID for PKCS9 attribute: " +
+ oid);
+
+ elems = new DerInputStream(val[1].toByteArray()).getSet(1);
+
+ // check single valued have only one value
+ if (SINGLE_VALUED[index] && elems.length > 1)
+ throwSingleValuedException();
+
+ // check for illegal element tags
+ for (int i = 0; i < elems.length; i++) {
+ tag = Byte.valueOf(elems[i].tag);
+
+ if (indexOf(tag, PKCS9_VALUE_TAGS[index], 0) == -1)
+ throwTagException(tag);
+ }
+
+ switch (index) {
+ case 1: // email address
+ case 2: // unstructured name
+ case 8: // unstructured address
+ { // open scope
+ String[] values = new String[elems.length];
+
+ for (int i = 0; i < elems.length; i++)
+ values[i] = elems[i].getAsString();
+ value = values;
+ } // close scope
+ break;
+
+ case 3: // content type
+ value = elems[0].getOID();
+ break;
+
+ case 4: // message digest
+ value = elems[0].getOctetString();
+ break;
+
+ case 5: // signing time
+ value = (new DerInputStream(elems[0].toByteArray())).getUTCTime();
+ break;
+
+ case 6: // countersignature
+ { // open scope
+ SignerInfo[] values = new SignerInfo[elems.length];
+ for (int i = 0; i < elems.length; i++)
+ values[i] =
+ new SignerInfo(elems[i].toDerInputStream());
+ value = values;
+ } // close scope
+ break;
+
+ case 7: // challenge password
+ value = elems[0].getAsString();
+ break;
+
+ case 9: // extended-certificate attribute -- not
+ // supported
+ throw new IOException("PKCS9 extended-certificate " +
+ "attribute not supported.");
+
+ case 10: // IssuerAndSerialNumber attribute -- not
+ // supported
+ throw new IOException("PKCS9 IssuerAndSerialNumber " +
+ "attribute not supported.");
+
+ case 11: // passwordCheck attribute -- not
+ // supported
+ throw new IOException("PKCS9 passwordCheck " +
+ "attribute not supported.");
+ case 12: // PublicKey attribute -- not
+ // supported
+ throw new IOException("PKCS9 PublicKey " +
+ "attribute not supported.");
+ case 13: // SigningDescription attribute -- not
+ // supported
+ throw new IOException("PKCS9 SigningDescription " +
+ "attribute not supported.");
+ case 14: // ExtensionRequest attribute
+ value =
+ new CertificateExtensions(elems[0].toDerInputStream());
+
+ // break unnecessary
+
+ default: // can't happen
+ }
+
+ }
+
+ /**
+ * Write the DER encoding of this attribute to an output stream.
+ *
+ * <P>
+ * N.B.: This method always encodes values of ChallengePassword and UnstructuredAddress attributes as ASN.1
+ * <code>PrintableString</code>s, without checking whether they should be encoded as <code>T61String</code>s.
+ */
+ public void derEncode(OutputStream out) throws IOException {
+ DerOutputStream temp = new DerOutputStream();
+ temp.putOID(getOID());
+ switch (index) {
+ case 1: // email address
+ case 2: // unstructured name
+ { // open scope
+ String[] values = (String[]) value;
+ DerOutputStream[] temps = new
+ DerOutputStream[values.length];
+
+ for (int i = 0; i < values.length; i++) {
+ temps[i] = new DerOutputStream();
+
+ temps[i].putIA5String(values[i]);
+ }
+ temp.putOrderedSetOf(DerValue.tag_Set, temps);
+ } // close scope
+ break;
+
+ case 3: // content type
+ {
+ DerOutputStream temp2 = new DerOutputStream();
+ temp2.putOID((ObjectIdentifier) value);
+ temp.write(DerValue.tag_Set, temp2.toByteArray());
+ }
+ break;
+
+ case 4: // message digest
+ {
+ DerOutputStream temp2 = new DerOutputStream();
+ temp2.putOctetString((byte[]) value);
+ temp.write(DerValue.tag_Set, temp2.toByteArray());
+ }
+ break;
+
+ case 5: // signing time
+ {
+ DerOutputStream temp2 = new DerOutputStream();
+ temp2.putUTCTime((Date) value);
+ temp.write(DerValue.tag_Set, temp2.toByteArray());
+ }
+ break;
+
+ case 6: // countersignature
+ temp.putOrderedSetOf(DerValue.tag_Set, (DerEncoder[]) value);
+ break;
+
+ case 7: // challenge password
+ {
+ DerOutputStream temp2 = new DerOutputStream();
+ temp2.putPrintableString((String) value);
+ temp.write(DerValue.tag_Set, temp2.toByteArray());
+ }
+ break;
+
+ case 8: // unstructured address
+ { // open scope
+ String[] values = (String[]) value;
+ DerOutputStream[] temps = new
+ DerOutputStream[values.length];
+
+ for (int i = 0; i < values.length; i++) {
+ temps[i] = new DerOutputStream();
+
+ temps[i].putPrintableString(values[i]);
+ }
+ temp.putOrderedSetOf(DerValue.tag_Set, temps);
+ } // close scope
+ break;
+
+ case 9: // extended-certificate attribute -- not
+ // supported
+ throw new IOException("PKCS9 extended-certificate " +
+ "attribute not supported.");
+
+ case 10: // IssuerAndSerialNumber attribute -- not
+ // supported
+ throw new IOException("PKCS9 IssuerAndSerialNumber " +
+ "attribute not supported.");
+
+ case 11: // passwordCheck attribute -- not
+ // supported
+ throw new IOException("PKCS9 passwordCheck " +
+ "attribute not supported.");
+ case 12: // PublicKey attribute -- not
+ // supported
+ throw new IOException("PKCS9 PublicKey " +
+ "attribute not supported.");
+ case 13: // SigningDescription attribute -- not
+ // supported
+ throw new IOException("PKCS9 SigningDescription " +
+ "attribute not supported.");
+ case 14: // ExtensionRequest attribute
+ try {
+ DerOutputStream temp2 = new DerOutputStream();
+ //temp2.putSequence((CertificateExtensions) value);
+ ((CertificateExtensions) value).encode(temp2);
+ temp.write(DerValue.tag_Sequence, temp2.toByteArray());
+ } catch (CertificateException e) {
+ throw new IOException("PKCS9 extension attributes not encoded");
+ }
+
+ // break unnecessary
+ default: // can't happen
+ }
+
+ DerOutputStream derOut = new DerOutputStream();
+ derOut.write(DerValue.tag_Sequence, temp.toByteArray());
+
+ out.write(derOut.toByteArray());
+
+ }
+
+ /**
+ * Get the value of this attribute. If the attribute is
+ * single-valued, return just the one value. If the attribute is
+ * multiple-valued, return an array containing all the values.
+ * It is possible for this array to be of length 0.
+ *
+ * <P>
+ * The following table gives the class of the value returned, depending on the type of this attribute.
+ *
+ * <P>
+ * <TABLE BORDER CELLPADDING=8 ALIGN=CENTER>
+ *
+ * <TR>
+ * <TH>OID</TH>
+ * <TH>Attribute Type Name</TH>
+ * <TH>Kind</TH>
+ * <TH>Value Class</TH>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.1</TD>
+ * <TD>EmailAddress</TD>
+ * <TD>Multiple-valued</TD>
+ * <TD><code>String[]</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.2</TD>
+ * <TD>UnstructuredName</TD>
+ * <TD>Multiple-valued</TD>
+ * <TD><code>String[]</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.3</TD>
+ * <TD>ContentType</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>ObjectIdentifier</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.4</TD>
+ * <TD>MessageDigest</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>byte[]</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.5</TD>
+ * <TD>SigningTime</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>Date</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.6</TD>
+ * <TD>Countersignature</TD>
+ * <TD>Multiple-valued</TD>
+ * <TD><code>SignerInfo[]</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.7</TD>
+ * <TD>ChallengePassword</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>String</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.8</TD>
+ * <TD>UnstructuredAddress</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>String[]</code></TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.9</TD>
+ * <TD>ExtendedCertificateAttributes</TD>
+ * <TD>Multiple-valued</TD>
+ * <TD>(not supported)</TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.10</TD>
+ * <TD>IssuerAndSerialNumber</TD>
+ * <TD>Single-valued</TD>
+ * <TD>(not supported)</TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.11</TD>
+ * <TD>PasswordCheck</TD>
+ * <TD>Single-valued</TD>
+ * <TD>(not supported)</TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.12</TD>
+ * <TD>PublicKey</TD>
+ * <TD>Single-valued</TD>
+ * <TD>(not supported)</TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.13</TD>
+ * <TD>SigningDescription</TD>
+ * <TD>Single-valued</TD>
+ * <TD>(not supported)</TD>
+ * </TR>
+ *
+ * <TR>
+ * <TD>1.2.840.113549.1.9.14</TD>
+ * <TD>ExtensionRequest</TD>
+ * <TD>Single-valued</TD>
+ * <TD><code>Sequence</code></TD>
+ * </TR>
+ *
+ * </TABLE>
+ *
+ */
+ public Object getValue() {
+ return value;
+ }
+
+ /**
+ * Show whether this attribute is single-valued.
+ */
+ public boolean isSingleValued() {
+ return SINGLE_VALUED[index];
+ }
+
+ /**
+ * Return the OID of this attribute.
+ */
+ public ObjectIdentifier getOID() {
+ return PKCS9_OIDS[index];
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (String) OID_NAME_TABLE.get(PKCS9_OIDS[index]);
+ }
+
+ /**
+ * Return the OID for a given attribute name or null if we don't recognize
+ * the name.
+ */
+ public static ObjectIdentifier getOID(String name) {
+ return (ObjectIdentifier) NAME_OID_TABLE.get(name.toLowerCase());
+ }
+
+ /**
+ * Return the attribute name for a given OID or null if we don't recognize
+ * the oid.
+ */
+ public static String getName(ObjectIdentifier oid) {
+ return (String) OID_NAME_TABLE.get(oid);
+ }
+
+ /**
+ * Returns a string representation of this attribute.
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer(100);
+
+ buf.append("[");
+
+ buf.append(OID_NAME_TABLE.get(PKCS9_OIDS[index]));
+ buf.append(": ");
+
+ if (SINGLE_VALUED[index]) {
+ if (value instanceof byte[]) { // special case for octet string
+ netscape.security.util.PrettyPrintFormat pp =
+ new netscape.security.util.PrettyPrintFormat(" ", 20);
+ String valuebits = pp.toHexString(((byte[]) value));
+ buf.append(valuebits);
+ } else {
+ buf.append(value.toString());
+ }
+ buf.append("]");
+ return buf.toString();
+ } else { // multiple-valued
+ boolean first = true;
+ Object[] values = (Object[]) value;
+
+ for (int j = 0; j < values.length; j++) {
+ if (first)
+ first = false;
+ else
+ buf.append(", ");
+
+ buf.append(values[j].toString());
+ }
+ return buf.toString();
+ }
+ }
+
+ /**
+ * Beginning the search at <code>start</code>, find the first
+ * index <code>i</code> such that <code>a[i] = obj</code>.
+ *
+ * @return the index, if found, and -1 otherwise.
+ */
+ static int indexOf(Object obj, Object[] a, int start) {
+ for (int i = start; i < a.length; i++) {
+ if (obj.equals(a[i]))
+ return i;
+ }
+ return -1;
+ }
+
+ /**
+ * Throw an exception when there are multiple values for
+ * a single-valued attribute.
+ */
+ private void throwSingleValuedException() throws IOException {
+ throw new IOException("Single-value attribute " +
+ getOID() + " (" + getName() + ")" +
+ " has multiple values.");
+ }
+
+ /**
+ * Throw an exception when the tag on a value encoding is
+ * wrong for the attribute whose value it is.
+ */
+ private void throwTagException(Byte tag)
+ throws IOException {
+ Byte[] expectedTags = PKCS9_VALUE_TAGS[index];
+ StringBuffer msg = new StringBuffer(100);
+ msg.append("Value of attribute ");
+ msg.append(getOID().toString());
+ msg.append(" (");
+ msg.append(getName());
+ msg.append(") has wrong tag: ");
+ msg.append(tag.toString());
+ msg.append(". Expected tags: ");
+
+ msg.append(expectedTags[0].toString());
+
+ for (int i = 1; i < expectedTags.length; i++) {
+ msg.append(", ");
+ msg.append(expectedTags[i].toString());
+ }
+ msg.append(".");
+ throw new IOException(msg.toString());
+ }
+
+}
diff --git a/base/util/src/netscape/security/pkcs/PKCS9Attributes.java b/base/util/src/netscape/security/pkcs/PKCS9Attributes.java
new file mode 100644
index 000000000..485cdded1
--- /dev/null
+++ b/base/util/src/netscape/security/pkcs/PKCS9Attributes.java
@@ -0,0 +1,312 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.pkcs;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Hashtable;
+
+import netscape.security.util.DerEncoder;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * A set of attributes of class PKCS9Attribute.
+ *
+ * @version 1.2 97/12/10
+ * @author Douglas Hoover
+ */
+public class PKCS9Attributes {
+
+ /**
+ * Attributes in this set indexed by OID.
+ */
+ private final Hashtable<ObjectIdentifier, PKCS9Attribute> attributes = new Hashtable<ObjectIdentifier, PKCS9Attribute>(3);
+
+ /**
+ * The keys of this hashtable are the OIDs of permitted attributes.
+ */
+ private final Hashtable<ObjectIdentifier, ObjectIdentifier> permittedAttributes;
+
+ /**
+ * The DER encoding of this attribute set. The tag byte must be
+ * DerValue.tag_SetOf.
+ */
+ private final byte[] derEncoding;
+
+ /**
+ * Construct a set of PKCS9 Attributes from its
+ * DER encoding on a DerInputStream, accepting only attributes
+ * with OIDs on the given
+ * list. If the array is null, accept all attributes supported by
+ * class PKCS9Attribute.
+ *
+ * @param permittedAttributes
+ * Array of attribute OIDs that will be accepted.
+ * @param buf
+ * the contents of the DER encoding of the attribute set.
+ *
+ * @exception IOException
+ * on i/o error, encoding syntax error, unacceptable or
+ * unsupported attribute, or duplicate attribute.
+ *
+ * @see PKCS9Attribute
+ */
+ public PKCS9Attributes(ObjectIdentifier[] permittedAttributes,
+ DerInputStream in) throws IOException {
+ if (permittedAttributes != null) {
+ this.permittedAttributes =
+ new Hashtable<ObjectIdentifier, ObjectIdentifier>(permittedAttributes.length);
+
+ for (int i = 0; i < permittedAttributes.length; i++)
+ this.permittedAttributes.put(permittedAttributes[i],
+ permittedAttributes[i]);
+ } else {
+ this.permittedAttributes = null;
+ }
+
+ // derEncoding initialized in <code>decode()</code>
+ derEncoding = decode(in);
+ }
+
+ /**
+ * Construct a set of PKCS9 Attributes from its contents of its
+ * DER encoding on a DerInputStream. Accept all attributes
+ * supported by class PKCS9Attribute.
+ *
+ * @exception IOException
+ * on i/o error, encoding syntax error, or unsupported or
+ * duplicate attribute.
+ *
+ * @see PKCS9Attribute
+ */
+ public PKCS9Attributes(DerInputStream in) throws IOException {
+ // anything goes
+ // derEncoding initialized in <code>decode()</code>
+ derEncoding = decode(in);
+ permittedAttributes = null;
+ }
+
+ /**
+ * Construct a set of PKCS9 Attributes from the given array of
+ * PCK9 attributes.
+ * DER encoding on a DerInputStream. All attributes in <code>attribs</code> must be
+ * supported by class PKCS9Attribute.
+ *
+ * @exception IOException
+ * on i/o error, encoding syntax error, or unsupported or
+ * duplicate attribute.
+ *
+ * @see PKCS9Attribute
+ */
+ public PKCS9Attributes(PKCS9Attribute[] attribs)
+ throws IllegalArgumentException, IOException {
+ ObjectIdentifier oid;
+ for (int i = 0; i < attribs.length; i++) {
+ oid = attribs[i].getOID();
+ if (attributes.containsKey(oid))
+ throw new IllegalArgumentException(
+ "PKCSAttribute " + attribs[i].getOID() +
+ " duplicated while constructing " +
+ "PKCS9Attributes.");
+
+ attributes.put(oid, attribs[i]);
+ }
+ derEncoding = generateDerEncoding();
+ permittedAttributes = null;
+ }
+
+ /**
+ * Decode this set of PKCS9 attribute set from the contents of its
+ * DER encoding.
+ *
+ * @param buf
+ * the contents of the DER encoding of the attribute set.
+ *
+ * @exception IOException
+ * on i/o error, encoding syntax error, unacceptable or
+ * unsupported attribute, or duplicate attribute.
+ */
+ private byte[] decode(DerInputStream in) throws IOException {
+
+ DerValue val = in.getDerValue();
+
+ // save the DER encoding with its proper tag byte.
+ byte[] derEncoding = val.toByteArray();
+ derEncoding[0] = DerValue.tag_SetOf;
+
+ DerInputStream derIn = new DerInputStream(derEncoding);
+ DerValue[] derVals = derIn.getSet(3, true);
+
+ PKCS9Attribute attrib;
+ ObjectIdentifier oid;
+
+ for (int i = 0; i < derVals.length; i++) {
+ attrib = new PKCS9Attribute(derVals[i]);
+ oid = attrib.getOID();
+
+ if (attributes.get(oid) != null)
+ throw new IOException("Duplicate PKCS9 attribute: " + oid);
+
+ if (permittedAttributes != null &&
+ !permittedAttributes.containsKey(oid))
+ throw new IOException("Attribute " + oid +
+ " not permitted in this attribute set");
+
+ attributes.put(oid, attrib);
+ }
+ return derEncoding;
+
+ }
+
+ /**
+ * Put the DER encoding of this PKCS9 attribute set on an
+ * DerOutputStream, tagged with the given implicit tag.
+ *
+ * @param tag the implicit tag to use in the DER encoding.
+ * @param out the output stream on which to put the DER encoding.
+ *
+ * @exception IOException on output error.
+ */
+ public void encode(byte tag, OutputStream out) throws IOException {
+ out.write(tag);
+ out.write(derEncoding, 1, derEncoding.length - 1);
+ }
+
+ private byte[] generateDerEncoding() throws IOException {
+ DerOutputStream out = new DerOutputStream();
+ Object[] attribVals = attributes.values().toArray();
+
+ out.putOrderedSetOf(DerValue.tag_SetOf,
+ castToDerEncoder(attribVals));
+ return out.toByteArray();
+ }
+
+ /**
+ * Return the DER encoding of this attribute set, tagged with
+ * DerValue.tag_SetOf.
+ */
+ public byte[] getDerEncoding() throws IOException {
+ return (byte[]) derEncoding.clone();
+
+ }
+
+ /**
+ * Get an attribute from this set.
+ */
+ public PKCS9Attribute getAttribute(ObjectIdentifier oid) {
+ return attributes.get(oid);
+ }
+
+ /**
+ * Get an attribute from this set.
+ */
+ public PKCS9Attribute getAttribute(String name) {
+ return attributes.get(PKCS9Attribute.getOID(name));
+ }
+
+ /**
+ * Get an array of all attributes in this set, in order of OID.
+ */
+ public PKCS9Attribute[] getAttributes() {
+ PKCS9Attribute[] attribs = new PKCS9Attribute[attributes.size()];
+
+ int j = 0;
+ for (int i = 1; i < PKCS9Attribute.PKCS9_OIDS.length &&
+ j < attribs.length; i++) {
+ attribs[j] = getAttribute(PKCS9Attribute.PKCS9_OIDS[i]);
+
+ if (attribs[j] != null)
+ j++;
+ }
+ return attribs;
+ }
+
+ /**
+ * Get an attribute value by OID.
+ */
+ public Object getAttributeValue(ObjectIdentifier oid)
+ throws IOException {
+ try {
+ Object value = getAttribute(oid).getValue();
+ return value;
+ } catch (NullPointerException ex) {
+ throw new IOException("No value found for attribute " + oid);
+ }
+
+ }
+
+ /**
+ * Get an attribute value by type name.
+ */
+ public Object getAttributeValue(String name) throws IOException {
+ ObjectIdentifier oid = PKCS9Attribute.getOID(name);
+
+ if (oid == null)
+ throw new IOException("Attribute name " + name +
+ " not recognized or not supported.");
+
+ return getAttributeValue(oid);
+ }
+
+ /**
+ * Returns the PKCS9 block in a printable string form.
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer(200);
+ buf.append("PKCS9 Attributes: [\n\t");
+
+ PKCS9Attribute value;
+
+ boolean first = true;
+ for (int i = 1; i < PKCS9Attribute.PKCS9_OIDS.length; i++) {
+ value = getAttribute(PKCS9Attribute.PKCS9_OIDS[i]);
+
+ if (value == null)
+ continue;
+
+ // we have a value; print it
+ if (first)
+ first = false;
+ else
+ buf.append(";\n\t");
+
+ buf.append(value.toString());
+ }
+
+ buf.append("\n\t] (end PKCS9 Attributes)");
+
+ return buf.toString();
+ }
+
+ /**
+ * Cast an object array whose components are <code>DerEncoder</code>s to <code>DerEncoder[]</code>.
+ */
+ static DerEncoder[] castToDerEncoder(Object[] objs) {
+
+ DerEncoder[] encoders = new DerEncoder[objs.length];
+
+ for (int i = 0; i < encoders.length; i++)
+ encoders[i] = (DerEncoder) objs[i];
+
+ return encoders;
+ }
+
+}
diff --git a/base/util/src/netscape/security/pkcs/ParsingException.java b/base/util/src/netscape/security/pkcs/ParsingException.java
new file mode 100644
index 000000000..88e91a8db
--- /dev/null
+++ b/base/util/src/netscape/security/pkcs/ParsingException.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 netscape.security.pkcs;
+
+import java.io.IOException;
+
+public class ParsingException extends IOException {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8135726194372647410L;
+
+ public ParsingException() {
+ super();
+ }
+
+ public ParsingException(String s) {
+ super(s);
+ }
+}
diff --git a/base/util/src/netscape/security/pkcs/SignerInfo.java b/base/util/src/netscape/security/pkcs/SignerInfo.java
new file mode 100644
index 000000000..adb0115cc
--- /dev/null
+++ b/base/util/src/netscape/security/pkcs/SignerInfo.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 netscape.security.pkcs;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.X509Certificate;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerEncoder;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.X500Name;
+
+/**
+ * A SignerInfo, as defined in PKCS#7's signedData type.
+ *
+ * @author Benjamin Renaud
+ * @version 1.27 97/12/10
+ */
+public class SignerInfo implements DerEncoder {
+
+ BigInt version;
+ X500Name issuerName;
+ BigInt certificateSerialNumber;
+ AlgorithmId digestAlgorithmId;
+ AlgorithmId digestEncryptionAlgorithmId;
+ byte[] encryptedDigest;
+
+ PKCS9Attributes authenticatedAttributes;
+ PKCS9Attributes unauthenticatedAttributes;
+
+ public SignerInfo(X500Name issuerName,
+ BigInt serial,
+ AlgorithmId digestAlgorithmId,
+ AlgorithmId digestEncryptionAlgorithmId,
+ byte[] encryptedDigest) {
+ this.version = new BigInt(1);
+ this.issuerName = issuerName;
+ this.certificateSerialNumber = serial;
+ this.digestAlgorithmId = digestAlgorithmId;
+ this.digestEncryptionAlgorithmId = digestEncryptionAlgorithmId;
+ this.encryptedDigest = encryptedDigest;
+ }
+
+ public SignerInfo(X500Name issuerName,
+ BigInt serial,
+ AlgorithmId digestAlgorithmId,
+ PKCS9Attributes authenticatedAttributes,
+ AlgorithmId digestEncryptionAlgorithmId,
+ byte[] encryptedDigest,
+ PKCS9Attributes unauthenticatedAttributes) {
+ this.version = new BigInt(1);
+ this.issuerName = issuerName;
+ this.certificateSerialNumber = serial;
+ this.digestAlgorithmId = digestAlgorithmId;
+ this.authenticatedAttributes = authenticatedAttributes;
+ this.digestEncryptionAlgorithmId = digestEncryptionAlgorithmId;
+ this.encryptedDigest = encryptedDigest;
+ this.unauthenticatedAttributes = unauthenticatedAttributes;
+ }
+
+ public SignerInfo(DerInputStream derin)
+ throws IOException, ParsingException {
+
+ // version
+ version = derin.getInteger();
+
+ // issuerAndSerialNumber
+ DerValue[] issuerAndSerialNumber = derin.getSequence(2);
+ byte[] issuerBytes = issuerAndSerialNumber[0].toByteArray();
+ issuerName = new X500Name(new DerValue(DerValue.tag_Sequence,
+ issuerBytes));
+ certificateSerialNumber = issuerAndSerialNumber[1].getInteger();
+
+ // digestAlgorithmId
+ DerValue tmp = derin.getDerValue();
+
+ digestAlgorithmId = AlgorithmId.parse(tmp);
+
+ /*
+ * check if set of auth attributes (implicit tag) is provided
+ * (auth attributes are OPTIONAL)
+ */
+ if ((byte) (derin.peekByte()) == (byte) 0xA0) {
+ authenticatedAttributes = new PKCS9Attributes(derin);
+ }
+
+ // digestEncryptionAlgorithmId - little RSA naming scheme -
+ // signature == encryption...
+ tmp = derin.getDerValue();
+
+ digestEncryptionAlgorithmId = AlgorithmId.parse(tmp);
+
+ // encryptedDigest
+ encryptedDigest = derin.getOctetString();
+
+ /*
+ * check if set of unauth attributes (implicit tag) is provided
+ * (unauth attributes are OPTIONAL)
+ */
+ if (derin.available() != 0 && (byte) (derin.peekByte()) == (byte) 0xA1) {
+ unauthenticatedAttributes = new PKCS9Attributes(derin);
+ }
+
+ // all done
+ if (derin.available() != 0) {
+ throw new ParsingException("extra data at the end");
+ }
+ }
+
+ public void encode(DerOutputStream out) throws IOException {
+
+ derEncode(out);
+ }
+
+ /**
+ * DER encode this object onto an output stream.
+ * Implements the <code>DerEncoder</code> interface.
+ *
+ * @param out
+ * the output stream on which to write the DER encoding.
+ *
+ * @exception IOException on encoding error.
+ */
+ public void derEncode(OutputStream out) throws IOException {
+ DerOutputStream seq = new DerOutputStream();
+ seq.putInteger(version);
+ DerOutputStream issuerAndSerialNumber = new DerOutputStream();
+ issuerName.encode(issuerAndSerialNumber);
+ issuerAndSerialNumber.putInteger(certificateSerialNumber);
+ seq.write(DerValue.tag_Sequence, issuerAndSerialNumber);
+
+ digestAlgorithmId.encode(seq);
+
+ // encode authenticated attributes if there are any
+ if (authenticatedAttributes != null)
+ authenticatedAttributes.encode((byte) 0xA0, seq);
+
+ digestEncryptionAlgorithmId.encode(seq);
+
+ seq.putOctetString(encryptedDigest);
+
+ // encode unauthenticated attributes if there are any
+ if (unauthenticatedAttributes != null)
+ unauthenticatedAttributes.encode((byte) 0xA1, seq);
+
+ DerOutputStream tmp = new DerOutputStream();
+ tmp.write(DerValue.tag_Sequence, seq);
+
+ out.write(tmp.toByteArray());
+ }
+
+ public X509Certificate getCertificate(PKCS7 block)
+ throws IOException {
+ return block.getCertificate(certificateSerialNumber, issuerName);
+ }
+
+ /* Returns null if verify fails, this signerInfo if
+ verify succeeds. */
+ SignerInfo verify(PKCS7 block, byte[] data)
+ throws NoSuchAlgorithmException, SignatureException {
+
+ try {
+
+ ContentInfo content = block.getContentInfo();
+ if (data == null) {
+ data = content.getContentBytes();
+ }
+
+ String digestAlgname =
+ getDigestAlgorithmId().getName();
+
+ byte[] dataSigned;
+
+ // if there are authenticate attributes, get the message
+ // digest and compare it with the digest of data
+ if (authenticatedAttributes == null) {
+ dataSigned = data;
+ } else {
+
+ // first, check content type
+ ObjectIdentifier contentType = (ObjectIdentifier)
+ authenticatedAttributes.getAttributeValue(
+ PKCS9Attribute.CONTENT_TYPE_OID);
+ if (contentType == null ||
+ !contentType.equals(content.contentType))
+ return null; // contentType does not match, bad SignerInfo
+
+ // now, check message digest
+ byte[] messageDigest = (byte[])
+ authenticatedAttributes.getAttributeValue(
+ PKCS9Attribute.MESSAGE_DIGEST_OID);
+
+ if (messageDigest == null) // fail if there is no message digest
+ return null;
+
+ MessageDigest md = MessageDigest.getInstance(digestAlgname);
+ byte[] computedMessageDigest = md.digest(data);
+
+ if (messageDigest.length != computedMessageDigest.length)
+ return null;
+ for (int i = 0; i < messageDigest.length; i++) {
+ if (messageDigest[i] != computedMessageDigest[i])
+ return null;
+ }
+
+ // message digest attribute matched
+ // digest of original data
+
+ // the data actually signed is the DER encoding of
+ // the authenticated attributes (tagged with
+ // the "SET OF" tag, not 0xA0).
+ dataSigned = authenticatedAttributes.getDerEncoding();
+ }
+
+ // put together digest algorithm and encryption algorithm
+ // to form signing algorithm
+ String encryptionAlgname =
+ getDigestEncryptionAlgorithmId().getName();
+
+ String algname;
+ if (encryptionAlgname.equals("DSA") ||
+ encryptionAlgname.equals("SHA1withDSA")) {
+ algname = "DSA";
+ } else {
+ algname = digestAlgname + "/" + encryptionAlgname;
+ }
+
+ Signature sig = Signature.getInstance(algname);
+ X509Certificate cert = getCertificate(block);
+
+ if (cert == null) {
+ return null;
+ }
+
+ PublicKey key = cert.getPublicKey();
+ sig.initVerify(key);
+
+ sig.update(dataSigned);
+
+ if (sig.verify(encryptedDigest)) {
+ return this;
+ }
+
+ } catch (IOException e) {
+ throw new SignatureException("IO error verifying signature:\n" +
+ e.getMessage());
+
+ } catch (InvalidKeyException e) {
+ throw new SignatureException("InvalidKey: " + e.getMessage());
+
+ }
+ return null;
+ }
+
+ /* Verify the content of the pkcs7 block. */
+ SignerInfo verify(PKCS7 block)
+ throws NoSuchAlgorithmException, SignatureException {
+ return verify(block, null);
+ }
+
+ public BigInt getVersion() {
+ return version;
+ }
+
+ public X500Name getIssuerName() {
+ return issuerName;
+ }
+
+ public BigInt getCertificateSerialNumber() {
+ return certificateSerialNumber;
+ }
+
+ public AlgorithmId getDigestAlgorithmId() {
+ return digestAlgorithmId;
+ }
+
+ public PKCS9Attributes getAuthenticatedAttributes() {
+ return authenticatedAttributes;
+ }
+
+ public AlgorithmId getDigestEncryptionAlgorithmId() {
+ return digestEncryptionAlgorithmId;
+ }
+
+ public byte[] getEncryptedDigest() {
+ return encryptedDigest;
+ }
+
+ public PKCS9Attributes getUnauthenticatedAttributes() {
+ return unauthenticatedAttributes;
+ }
+
+ public String toString() {
+ netscape.security.util.PrettyPrintFormat pp =
+ new netscape.security.util.PrettyPrintFormat(" ", 20);
+ String digestbits = pp.toHexString(encryptedDigest);
+
+ String out = "";
+
+ out += "Signer Info for (issuer): " + issuerName + "\n";
+ out += "\tversion: " + version + "\n";
+ out += "\tcertificateSerialNumber: " + certificateSerialNumber +
+ "\n";
+ out += "\tdigestAlgorithmId: " + digestAlgorithmId + "\n";
+ if (authenticatedAttributes != null) {
+ out += "\tauthenticatedAttributes: " + authenticatedAttributes +
+ "\n";
+ }
+ out += "\tdigestEncryptionAlgorithmId: " + digestEncryptionAlgorithmId +
+ "\n";
+
+ out += "\tencryptedDigest: " + "\n" +
+ digestbits + "\n";
+ if (unauthenticatedAttributes != null) {
+ out += "\tunauthenticatedAttributes: " +
+ unauthenticatedAttributes + "\n";
+ }
+ return out;
+ }
+
+}
diff --git a/base/util/src/netscape/security/provider/CMS.java b/base/util/src/netscape/security/provider/CMS.java
new file mode 100644
index 000000000..4a4f150ab
--- /dev/null
+++ b/base/util/src/netscape/security/provider/CMS.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 netscape.security.provider;
+
+import java.security.AccessController;
+import java.security.Provider;
+
+/**
+ * The CMS Security Provider.
+ */
+
+public final class CMS extends Provider {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1065207998900104219L;
+ private static final String INFO = "CMS " +
+ "(DSA key/parameter generation; DSA signing; " +
+ "SHA-1, MD5 digests; SecureRandom; X.509 certificates)";
+
+ public CMS() {
+ /* We are the SUN provider */
+ super("CMS", 1.0, INFO);
+
+ AccessController.doPrivileged(new java.security.PrivilegedAction<Object>() {
+ public Object run() {
+ /*
+ * Certificates
+ */
+ put("CertificateFactory.X.509", "netscape.security.provider.X509CertificateFactory");
+ put("Alg.Alias.CertificateFactory.X.509", "X.509");
+ return null;
+ }
+ });
+ }
+}
diff --git a/base/util/src/netscape/security/provider/DSA.java b/base/util/src/netscape/security/provider/DSA.java
new file mode 100644
index 000000000..262095576
--- /dev/null
+++ b/base/util/src/netscape/security/provider/DSA.java
@@ -0,0 +1,660 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.provider;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.interfaces.DSAParams;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * The Digital Signature Standard (using the Digital Signature
+ * Algorithm), as described in fips186 of the National Instute of
+ * Standards and Technology (NIST), using fips180-1 (SHA-1).
+ *
+ * @author Benjamin Renaud
+ *
+ * @version 1.86, 97/09/17
+ *
+ * @see DSAPublicKey
+ * @see DSAPrivateKey
+ */
+
+public final class DSA extends Signature {
+
+ /* Are we debugging? */
+ private static boolean debug = false;
+
+ /* The parameter object */
+ private DSAParams params;
+
+ /* algorithm parameters */
+ private BigInteger presetP, presetQ, presetG;
+
+ /* The public key, if any */
+ private BigInteger presetY;
+
+ /* The private key, if any */
+ private BigInteger presetX;
+
+ /* The SHA hash for the data */
+ private MessageDigest dataSHA;
+
+ /* The random seed used to generate k */
+ private int[] Kseed;
+
+ /* The random seed used to generate k (specified by application) */
+ private byte[] KseedAsByteArray;
+
+ /*
+ * The random seed used to generate k
+ * (prevent the same Kseed from being used twice in a row
+ */
+ private int[] previousKseed;
+
+ /* The RNG used to output a seed for generating k */
+ private SecureRandom signingRandom;
+
+ /**
+ * Construct a blank DSA object. It can generate keys, but must be
+ * initialized before being usable for signing or verifying.
+ */
+ public DSA() throws NoSuchAlgorithmException {
+ super("SHA/DSA");
+ dataSHA = MessageDigest.getInstance("SHA");
+ }
+
+ /**
+ * Initialize the DSA object with a DSA private key.
+ *
+ * @param privateKey the DSA private key
+ *
+ * @exception InvalidKeyException if the key is not a valid DSA private
+ * key.
+ */
+ protected void engineInitSign(PrivateKey privateKey)
+ throws InvalidKeyException {
+ if (!(privateKey instanceof java.security.interfaces.DSAPrivateKey)) {
+ throw new InvalidKeyException("not a DSA private key: " +
+ privateKey);
+ }
+ java.security.interfaces.DSAPrivateKey priv =
+ (java.security.interfaces.DSAPrivateKey) privateKey;
+
+ this.presetX = priv.getX();
+ initialize(priv.getParams());
+ }
+
+ /**
+ * Initialize the DSA object with a DSA public key.
+ *
+ * @param publicKey the DSA public key.
+ *
+ * @exception InvalidKeyException if the key is not a valid DSA public
+ * key.
+ */
+ protected void engineInitVerify(PublicKey publicKey)
+ throws InvalidKeyException {
+ if (!(publicKey instanceof java.security.interfaces.DSAPublicKey)) {
+ throw new InvalidKeyException("not a DSA public key: " +
+ publicKey);
+ }
+ java.security.interfaces.DSAPublicKey pub =
+ (java.security.interfaces.DSAPublicKey) publicKey;
+ this.presetY = pub.getY();
+ initialize(pub.getParams());
+ }
+
+ private void initialize(DSAParams params) {
+ dataSHA.reset();
+ setParams(params);
+ }
+
+ /**
+ * Sign all the data thus far updated. The signature is formatted
+ * according to the Canonical Encoding Rules, returned as a DER
+ * sequence of Integer, r and s.
+ *
+ * @return a signature block formatted according to the Canonical
+ * Encoding Rules.
+ *
+ * @exception SignatureException if the signature object was not
+ * properly initialized, or if another exception occurs.
+ *
+ * @see netscape.security.provider.DSA#engineUpdate
+ * @see netscape.security.provider.DSA#engineVerify
+ */
+ protected byte[] engineSign() throws SignatureException {
+ BigInteger k = generateK(presetQ);
+ BigInteger r = generateR(presetP, presetQ, presetG, k);
+ BigInteger s = generateS(presetX, presetQ, r, k);
+
+ // got to convert to BigInt...
+ BigInt rAsBigInt = new BigInt(r.toByteArray());
+ BigInt sAsBigInt = new BigInt(s.toByteArray());
+
+ try {
+ DerOutputStream outseq = new DerOutputStream(100);
+ outseq.putInteger(rAsBigInt);
+ outseq.putInteger(sAsBigInt);
+ DerValue result = new DerValue(DerValue.tag_Sequence,
+ outseq.toByteArray());
+
+ return result.toByteArray();
+
+ } catch (IOException e) {
+ throw new SignatureException("error encoding signature");
+ }
+ }
+
+ /**
+ * Verify all the data thus far updated.
+ *
+ * @param signature the alledged signature, encoded using the
+ * Canonical Encoding Rules, as a sequence of integers, r and s.
+ *
+ * @exception SignatureException if the signature object was not
+ * properly initialized, or if another exception occurs.
+ *
+ * @see netscape.security.provider.DSA#engineUpdate
+ * @see netscape.security.provider.DSA#engineSign
+ */
+ protected boolean engineVerify(byte[] signature)
+ throws SignatureException {
+
+ BigInteger r = null;
+ BigInteger s = null;
+ // first decode the signature.
+ try {
+ DerInputStream in = new DerInputStream(signature);
+ DerValue[] values = in.getSequence(2);
+
+ r = values[0].getInteger().toBigInteger();
+ s = values[1].getInteger().toBigInteger();
+
+ } catch (IOException e) {
+ throw new SignatureException("invalid encoding for signature");
+ }
+ BigInteger w = generateW(presetP, presetQ, presetG, s);
+ BigInteger v = generateV(presetY, presetP, presetQ, presetG, w, r);
+
+ return v.equals(r);
+ }
+
+ BigInteger generateR(BigInteger p, BigInteger q, BigInteger g,
+ BigInteger k) {
+ BigInteger temp = g.modPow(k, p);
+ return temp.remainder(q);
+
+ }
+
+ BigInteger generateS(BigInteger x, BigInteger q,
+ BigInteger r, BigInteger k) {
+
+ byte[] s2 = dataSHA.digest();
+ BigInteger temp = new BigInteger(1, s2);
+ BigInteger k1 = k.modInverse(q);
+
+ BigInteger s = x.multiply(r);
+ s = temp.add(s);
+ s = k1.multiply(s);
+ return s.remainder(q);
+ }
+
+ BigInteger generateW(BigInteger p, BigInteger q,
+ BigInteger g, BigInteger s) {
+ return s.modInverse(q);
+ }
+
+ BigInteger generateV(BigInteger y, BigInteger p,
+ BigInteger q, BigInteger g,
+ BigInteger w, BigInteger r) {
+
+ byte[] s2 = dataSHA.digest();
+ BigInteger temp = new BigInteger(1, s2);
+
+ temp = temp.multiply(w);
+ BigInteger u1 = temp.remainder(q);
+
+ BigInteger u2 = (r.multiply(w)).remainder(q);
+
+ BigInteger t1 = g.modPow(u1, p);
+ BigInteger t2 = y.modPow(u2, p);
+ BigInteger t3 = t1.multiply(t2);
+ BigInteger t5 = t3.remainder(p);
+ return t5.remainder(q);
+ }
+
+ /*
+ * Please read bug report 4044247 for an alternative, faster,
+ * NON-FIPS approved method to generate K
+ */
+ BigInteger generateK(BigInteger q) {
+
+ BigInteger k = null;
+
+ // The application specified a Kseed for us to use.
+ // Note that we do not allow usage of the same Kseed twice in a row
+ if (Kseed != null && compareSeeds(Kseed, previousKseed) != 0) {
+ k = generateK(Kseed, q);
+ if (k.signum() > 0 && k.compareTo(q) < 0) {
+ previousKseed = new int[Kseed.length];
+ System.arraycopy(Kseed, 0, previousKseed, 0, Kseed.length);
+ return k;
+ }
+ }
+
+ // The application did not specify a Kseed for us to use.
+ // We'll generate a new Kseed by getting random bytes from
+ // a SecureRandom object.
+ SecureRandom random = getSigningRandom();
+
+ while (true) {
+ int[] seed = new int[5];
+
+ for (int i = 0; i < 5; i++)
+ seed[i] = random.nextInt();
+ k = generateK(seed, q);
+ if (k.signum() > 0 && k.compareTo(q) < 0) {
+ previousKseed = new int[seed.length];
+ System.arraycopy(seed, 0, previousKseed, 0, seed.length);
+ return k;
+ }
+ }
+ }
+
+ // Use the application-specified SecureRandom Object if provided.
+ // Otherwise, use our default SecureRandom Object.
+ private SecureRandom getSigningRandom() {
+ if (signingRandom == null) {
+ if (appRandom != null)
+ signingRandom = appRandom;
+ else
+ signingRandom = new SecureRandom();
+ }
+ return signingRandom;
+ }
+
+ /*
+ * return 0 if equal
+ * return 1 if not equal
+ */
+ private int compareSeeds(int[] seed1, int[] seed2) {
+
+ if ((seed1 == null && seed1 == null) ||
+ (seed1 == null && seed2 != null) ||
+ (seed1 != null && seed2 == null) ||
+ seed1.length != seed2.length)
+ return 1;
+
+ for (int i = 0; i < seed1.length; i++) {
+ if (seed1[i] != seed2[i])
+ return 1;
+ }
+
+ return 0;
+
+ }
+
+ /**
+ * Compute k for a DSA signature.
+ *
+ * @param seed the seed for generating k. This seed should be
+ * secure. This is what is refered to as the KSEED in the DSA
+ * specification.
+ *
+ * @param g the g parameter from the DSA key pair.
+ */
+ BigInteger generateK(int[] seed, BigInteger q) {
+
+ // check out t in the spec.
+ int[] t = { 0xEFCDAB89, 0x98BADCFE, 0x10325476,
+ 0xC3D2E1F0, 0x67452301 };
+ //
+ int[] tmp = DSA.SHA_7(seed, t);
+ byte[] tmpBytes = new byte[tmp.length * 4];
+ for (int i = 0; i < tmp.length; i++) {
+ int k = tmp[i];
+ for (int j = 0; j < 4; j++) {
+ tmpBytes[(i * 4) + j] = (byte) (k >>> (24 - (j * 8)));
+ }
+ }
+ BigInteger k = new BigInteger(1, tmpBytes).mod(q);
+ return k;
+ }
+
+ // Constants for each round
+ private static final int round1_kt = 0x5a827999;
+ private static final int round2_kt = 0x6ed9eba1;
+ private static final int round3_kt = 0x8f1bbcdc;
+ private static final int round4_kt = 0xca62c1d6;
+
+ /**
+ * Computes set 1 thru 7 of SHA-1 on m1.
+ */
+ static int[] SHA_7(int[] m1, int[] h) {
+
+ int[] W = new int[80];
+ System.arraycopy(m1, 0, W, 0, m1.length);
+ int temp = 0;
+
+ for (int t = 16; t <= 79; t++) {
+ temp = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
+ W[t] = ((temp << 1) | (temp >>> (32 - 1)));
+ }
+
+ int a = h[0], b = h[1], c = h[2], d = h[3], e = h[4];
+ for (int i = 0; i < 20; i++) {
+ temp = ((a << 5) | (a >>> (32 - 5))) +
+ ((b & c) | ((~b) & d)) + e + W[i] + round1_kt;
+ e = d;
+ d = c;
+ c = ((b << 30) | (b >>> (32 - 30)));
+ b = a;
+ a = temp;
+ }
+
+ // Round 2
+ for (int i = 20; i < 40; i++) {
+ temp = ((a << 5) | (a >>> (32 - 5))) +
+ (b ^ c ^ d) + e + W[i] + round2_kt;
+ e = d;
+ d = c;
+ c = ((b << 30) | (b >>> (32 - 30)));
+ b = a;
+ a = temp;
+ }
+
+ // Round 3
+ for (int i = 40; i < 60; i++) {
+ temp = ((a << 5) | (a >>> (32 - 5))) +
+ ((b & c) | (b & d) | (c & d)) + e + W[i] + round3_kt;
+ e = d;
+ d = c;
+ c = ((b << 30) | (b >>> (32 - 30)));
+ b = a;
+ a = temp;
+ }
+
+ // Round 4
+ for (int i = 60; i < 80; i++) {
+ temp = ((a << 5) | (a >>> (32 - 5))) +
+ (b ^ c ^ d) + e + W[i] + round4_kt;
+ e = d;
+ d = c;
+ c = ((b << 30) | (b >>> (32 - 30)));
+ b = a;
+ a = temp;
+ }
+ int[] md = new int[5];
+ md[0] = h[0] + a;
+ md[1] = h[1] + b;
+ md[2] = h[2] + c;
+ md[3] = h[3] + d;
+ md[4] = h[4] + e;
+ return md;
+ }
+
+ /**
+ * This implementation recognizes the following parameter:
+ * <dl>
+ *
+ * <dt><tt>Kseed</tt>
+ *
+ * <dd>a byte array.
+ *
+ * </dl>
+ *
+ * @deprecated
+ */
+ protected void engineSetParameter(String key, Object param) {
+
+ if (key.equals("KSEED")) {
+
+ if (param instanceof byte[]) {
+
+ Kseed = byteArray2IntArray((byte[]) param);
+ KseedAsByteArray = (byte[]) param;
+
+ } else {
+ debug("unrecognized param: " + key);
+ throw new InvalidParameterException("Kseed not a byte array");
+ }
+
+ } else {
+ throw new InvalidParameterException("invalid parameter");
+ }
+ }
+
+ /**
+ * Return the value of the requested parameter. Recognized
+ * parameters are:
+ *
+ * <dl>
+ *
+ * <dt><tt>Kseed</tt>
+ *
+ * <dd>a byte array.
+ *
+ * </dl>
+ *
+ * @return the value of the requested parameter.
+ *
+ * @deprecated
+ */
+ protected Object engineGetParameter(String key) {
+ if (key.equals("KSEED")) {
+ return KseedAsByteArray;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Set the algorithm object.
+ */
+ private void setParams(DSAParams params) {
+ this.params = params;
+ this.presetP = params.getP();
+ this.presetQ = params.getQ();
+ this.presetG = params.getG();
+ }
+
+ /**
+ * Update a byte to be signed or verified.
+ *
+ * @param b the byte to updated.
+ */
+ protected void engineUpdate(byte b) {
+ dataSHA.update(b);
+ }
+
+ /**
+ * Update an array of bytes to be signed or verified.
+ *
+ * @param data the bytes to be updated.
+ */
+ protected void engineUpdate(byte[] data, int off, int len) {
+ dataSHA.update(data, off, len);
+ }
+
+ /**
+ * Return a human readable rendition of the engine.
+ */
+ public String toString() {
+ String printable = "DSA Signature";
+ if (presetP != null && presetQ != null && presetG != null) {
+ printable += "\n\tp: " + presetP.toString(16);
+ printable += "\n\tq: " + presetQ.toString(16);
+ printable += "\n\tg: " + presetG.toString(16);
+ } else {
+ printable += "\n\t P, Q or G not initialized.";
+ }
+ if (presetY != null) {
+ printable += "\n\ty: " + presetY.toString(16);
+ }
+ if (presetY == null && presetX == null) {
+ printable += "\n\tUNINIIALIZED";
+ }
+ return printable;
+ }
+
+ /*
+ * Utility routine for converting a byte array into an int array
+ */
+ private int[] byteArray2IntArray(byte[] byteArray) {
+
+ int j = 0;
+ byte[] newBA;
+ int mod = byteArray.length % 4;
+
+ // guarantee that the incoming byteArray is a multiple of 4
+ // (pad with 0's)
+ switch (mod) {
+ case 3:
+ newBA = new byte[byteArray.length + 1];
+ break;
+ case 2:
+ newBA = new byte[byteArray.length + 2];
+ break;
+ case 1:
+ newBA = new byte[byteArray.length + 3];
+ break;
+ default:
+ newBA = new byte[byteArray.length + 0];
+ break;
+ }
+ System.arraycopy(byteArray, 0, newBA, 0, byteArray.length);
+
+ // copy each set of 4 bytes in the byte array into an integer
+ int[] newSeed = new int[newBA.length / 4];
+ for (int i = 0; i < newBA.length; i += 4) {
+ newSeed[j] = newBA[i + 3] & 0xFF;
+ newSeed[j] |= (newBA[i + 2] << 8) & 0xFF00;
+ newSeed[j] |= (newBA[i + 1] << 16) & 0xFF0000;
+ newSeed[j] |= (newBA[i + 0] << 24) & 0xFF000000;
+ j++;
+ }
+
+ return newSeed;
+ }
+
+ /* We include the test vectors from the DSA specification, FIPS
+ 186, and the FIPS 186 Change No 1, which updates the test
+ vector using SHA-1 instead of SHA (for both the G function and
+ the message hash. */
+
+ static void testDSA() throws Exception {
+ PrintStream p = System.out;
+
+ DSA dsa = new DSA();
+ int[] Kseed = { 0x687a66d9, 0x0648f993, 0x867e121f,
+ 0x4ddf9ddb, 0x1205584 };
+ BigInteger k = dsa.generateK(Kseed, q512);
+ p.println("k: " + k.toString(16));
+ BigInteger r = dsa.generateR(p512, q512, g512, k);
+ p.println("r: " + r.toString(16));
+ byte[] abc = { 0x61, 0x62, 0x63 };
+ dsa.dataSHA.update(abc);
+ BigInteger s = dsa.generateS(x512, q512, r, k);
+ p.println("s: " + s.toString(16));
+
+ dsa.dataSHA.update(abc);
+ BigInteger w = dsa.generateW(p512, q512, g512, s);
+ p.println("w: " + w.toString(16));
+ BigInteger v = dsa.generateV(y512, p512, q512, g512, w, r);
+ p.println("v: " + v.toString(16));
+ if (v.equals(r)) {
+ p.println("signature verifies.");
+ } else {
+ p.println("signature does not verify.");
+ }
+ }
+
+ /* Test vector: 512-bit keys generated by our key generator. */
+
+ static BigInteger p512 =
+ new BigInteger("fca682ce8e12caba26efccf7110e526db078b05edecb" +
+ "cd1eb4a208f3ae1617ae01f35b91a47e6df63413c5e1" +
+ "2ed0899bcd132acd50d99151bdc43ee737592e17", 16);
+
+ static BigInteger q512 =
+ new BigInteger("962eddcc369cba8ebb260ee6b6a126d9346e38c5", 16);
+
+ static BigInteger g512 =
+ new BigInteger("678471b27a9cf44ee91a49c5147db1a9aaf244f05a43" +
+ "4d6486931d2d14271b9e35030b71fd73da179069b32e" +
+ "2935630e1c2062354d0da20a6c416e50be794ca4", 16);
+
+ static BigInteger x512 =
+ new BigInteger("3406c2d71b04b5fc0db62afcad58a6607d3de688", 16);
+
+ static BigInteger y512 =
+ new BigInteger("2d335d76b8ec9d610aa8f2cbb4b149fd96fdd" +
+ "3a9a6e62bd6c2e01d406be4d1d72718a2fe08bea6d12f5e452474461f70f4" +
+ "dea60508e9fe2eaec23d2ec5d1a866", 16);
+
+ /* Official NIST 512-bit test keys */
+
+ static String pString = "8df2a494492276aa3d25759bb06869cbeac0d83afb8d0" +
+ "cf7cbb8324f0d7882e5d0762fc5b7210eafc2e9adac32ab7aac49693dfbf83724c2ec" +
+ "0736ee31c80291";
+
+ static BigInteger testP = new BigInteger(pString, 16);
+
+ static String gString = "626d027839ea0a13413163a55b4cb500299d5522956ce" +
+ "fcb3bff10f399ce2c2e71cb9de5fa24babf58e5b79521925c9cc42e9f6f464b088cc5" +
+ "72af53e6d78802";
+
+ static BigInteger testG = new BigInteger(gString, 16);
+
+ static BigInteger testQ = new BigInteger("c773218c737ec8ee993b4f2ded30" +
+ "f48edace915f", 16);
+
+ static BigInteger testX = new BigInteger("2070b3223dba372fde1c0ffc7b2e" +
+ "3b498b260614", 16);
+
+ static String yString = "19131871d75b1612a819f29d78d1b0d7346f7aa77" +
+ "bb62a859bfd6c5675da9d212d3a36ef1672ef660b8c7c255cc0ec74858fba33f44c06" +
+ "699630a76b030ee333";
+
+ static BigInteger testY = new BigInteger(yString, 16);
+
+ /* End test vector values */
+
+ private static void debug(String s) {
+ if (debug) {
+ System.err.println(s);
+ }
+ }
+
+}
diff --git a/base/util/src/netscape/security/provider/DSAKeyFactory.java b/base/util/src/netscape/security/provider/DSAKeyFactory.java
new file mode 100755
index 000000000..41f0081f2
--- /dev/null
+++ b/base/util/src/netscape/security/provider/DSAKeyFactory.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 netscape.security.provider;
+
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyFactorySpi;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.interfaces.DSAParams;
+import java.security.spec.DSAPrivateKeySpec;
+import java.security.spec.DSAPublicKeySpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+/**
+ * This class implements the DSA key factory of the Sun provider.
+ *
+ * @author Jan Luehe
+ *
+ * @version 1.8, 97/12/10
+ *
+ * @since JDK1.2
+ */
+
+public class DSAKeyFactory extends KeyFactorySpi {
+
+ /**
+ * Generates a public key object from the provided key specification
+ * (key material).
+ *
+ * @param keySpec the specification (key material) of the public key
+ *
+ * @return the public key
+ *
+ * @exception InvalidKeySpecException if the given key specification
+ * is inappropriate for this key factory to produce a public key.
+ */
+ protected PublicKey engineGeneratePublic(KeySpec keySpec)
+ throws InvalidKeySpecException {
+ try {
+ if (keySpec instanceof DSAPublicKeySpec) {
+ DSAPublicKeySpec dsaPubKeySpec = (DSAPublicKeySpec) keySpec;
+ return new DSAPublicKey(dsaPubKeySpec.getY(),
+ dsaPubKeySpec.getP(),
+ dsaPubKeySpec.getQ(),
+ dsaPubKeySpec.getG());
+
+ } else if (keySpec instanceof X509EncodedKeySpec) {
+ return new DSAPublicKey(((X509EncodedKeySpec) keySpec).getEncoded());
+
+ } else {
+ throw new InvalidKeySpecException("Inappropriate key specification");
+ }
+ } catch (InvalidKeyException e) {
+ throw new InvalidKeySpecException("Inappropriate key specification: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Generates a private key object from the provided key specification
+ * (key material).
+ *
+ * @param keySpec the specification (key material) of the private key
+ *
+ * @return the private key
+ *
+ * @exception InvalidKeySpecException if the given key specification
+ * is inappropriate for this key factory to produce a private key.
+ */
+ protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
+ throws InvalidKeySpecException {
+ try {
+ if (keySpec instanceof DSAPrivateKeySpec) {
+ DSAPrivateKeySpec dsaPrivKeySpec = (DSAPrivateKeySpec) keySpec;
+ return new DSAPrivateKey(dsaPrivKeySpec.getX(),
+ dsaPrivKeySpec.getP(),
+ dsaPrivKeySpec.getQ(),
+ dsaPrivKeySpec.getG());
+
+ } else if (keySpec instanceof PKCS8EncodedKeySpec) {
+ return new DSAPrivateKey(((PKCS8EncodedKeySpec) keySpec).getEncoded());
+
+ } else {
+ throw new InvalidKeySpecException("Inappropriate key specification");
+ }
+ } catch (InvalidKeyException e) {
+ throw new InvalidKeySpecException("Inappropriate key specification: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Returns a specification (key material) of the given key object
+ * in the requested format.
+ *
+ * @param key the key
+ *
+ * @param keySpec the requested format in which the key material shall be
+ * returned
+ *
+ * @return the underlying key specification (key material) in the
+ * requested format
+ *
+ * @exception InvalidKeySpecException if the requested key specification is
+ * inappropriate for the given key, or the given key cannot be processed
+ * (e.g., the given key has an unrecognized algorithm or format).
+ */
+ @SuppressWarnings("unchecked")
+ protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
+ throws InvalidKeySpecException {
+
+ DSAParams params;
+
+ try {
+
+ if (key instanceof java.security.interfaces.DSAPublicKey) {
+
+ // Determine valid key specs
+ Class<?> dsaPubKeySpec = Class.forName
+ ("java.security.spec.DSAPublicKeySpec");
+ Class<?> x509KeySpec = Class.forName
+ ("java.security.spec.X509EncodedKeySpec");
+
+ if (dsaPubKeySpec.isAssignableFrom(keySpec)) {
+ java.security.interfaces.DSAPublicKey dsaPubKey = (java.security.interfaces.DSAPublicKey) key;
+ params = dsaPubKey.getParams();
+ return (T) new DSAPublicKeySpec(dsaPubKey.getY(),
+ params.getP(),
+ params.getQ(),
+ params.getG());
+
+ } else if (x509KeySpec.isAssignableFrom(keySpec)) {
+ return (T) new X509EncodedKeySpec(key.getEncoded());
+
+ } else {
+ throw new InvalidKeySpecException("Inappropriate key specification");
+ }
+
+ } else if (key instanceof java.security.interfaces.DSAPrivateKey) {
+
+ // Determine valid key specs
+ Class<?> dsaPrivKeySpec = Class.forName
+ ("java.security.spec.DSAPrivateKeySpec");
+ Class<?> pkcs8KeySpec = Class.forName
+ ("java.security.spec.PKCS8EncodedKeySpec");
+
+ if (dsaPrivKeySpec.isAssignableFrom(keySpec)) {
+ java.security.interfaces.DSAPrivateKey dsaPrivKey = (java.security.interfaces.DSAPrivateKey) key;
+ params = dsaPrivKey.getParams();
+ return (T) new DSAPrivateKeySpec(dsaPrivKey.getX(),
+ params.getP(),
+ params.getQ(),
+ params.getG());
+
+ } else if (pkcs8KeySpec.isAssignableFrom(keySpec)) {
+ return (T) new PKCS8EncodedKeySpec(key.getEncoded());
+
+ } else {
+ throw new InvalidKeySpecException("Inappropriate key specification");
+ }
+
+ } else {
+ throw new InvalidKeySpecException("Inappropriate key type");
+ }
+
+ } catch (ClassNotFoundException e) {
+ throw new InvalidKeySpecException("Unsupported key specification: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Translates a key object, whose provider may be unknown or potentially
+ * untrusted, into a corresponding key object of this key factory.
+ *
+ * @param key the key whose provider is unknown or untrusted
+ *
+ * @return the translated key
+ *
+ * @exception InvalidKeyException if the given key cannot be processed by
+ * this key factory.
+ */
+ protected Key engineTranslateKey(Key key) throws InvalidKeyException {
+
+ try {
+
+ if (key instanceof java.security.interfaces.DSAPublicKey) {
+ // Check if key originates from this factory
+ if (key instanceof netscape.security.provider.DSAPublicKey) {
+ return key;
+ }
+ // Convert key to spec
+ DSAPublicKeySpec dsaPubKeySpec = engineGetKeySpec(key, DSAPublicKeySpec.class);
+ // Create key from spec, and return it
+ return engineGeneratePublic(dsaPubKeySpec);
+
+ } else if (key instanceof java.security.interfaces.DSAPrivateKey) {
+ // Check if key originates from this factory
+ if (key instanceof netscape.security.provider.DSAPrivateKey) {
+ return key;
+ }
+ // Convert key to spec
+ DSAPrivateKeySpec dsaPrivKeySpec = engineGetKeySpec(key, DSAPrivateKeySpec.class);
+ // Create key from spec, and return it
+ return engineGeneratePrivate(dsaPrivKeySpec);
+
+ } else {
+ throw new InvalidKeyException("Wrong algorithm type");
+ }
+
+ } catch (InvalidKeySpecException e) {
+ throw new InvalidKeyException("Cannot translate key: "
+ + e.getMessage());
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/provider/DSAKeyPairGenerator.java b/base/util/src/netscape/security/provider/DSAKeyPairGenerator.java
new file mode 100644
index 000000000..3e04792bf
--- /dev/null
+++ b/base/util/src/netscape/security/provider/DSAKeyPairGenerator.java
@@ -0,0 +1,398 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.provider;
+
+import java.math.BigInteger;
+import java.security.AlgorithmParameterGenerator;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.ProviderException;
+import java.security.SecureRandom;
+import java.security.interfaces.DSAParams;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+import java.util.Hashtable;
+
+import netscape.security.x509.AlgIdDSA;
+
+/**
+ * This class generates DSA key parameters and public/private key
+ * pairs according to the DSS standard NIST FIPS 186. It uses the
+ * updated version of SHA, SHA-1 as described in FIPS 180-1.
+ *
+ * @author Benjamin Renaud
+ *
+ * @version 1.23, 97/12/10
+ */
+
+public class DSAKeyPairGenerator extends KeyPairGenerator
+ implements java.security.interfaces.DSAKeyPairGenerator {
+
+ private static Hashtable<Integer, AlgIdDSA> precomputedParams;
+
+ static {
+
+ /* We support precomputed parameter for 512, 768 and 1024 bit
+ moduli. In this file we provide both the seed and counter
+ value of the generation process for each of these seeds,
+ for validation purposes. We also include the test vectors
+ from the DSA specification, FIPS 186, and the FIPS 186
+ Change No 1, which updates the test vector using SHA-1
+ instead of SHA (for both the G function and the message
+ hash.
+ */
+
+ precomputedParams = new Hashtable<Integer, AlgIdDSA>();
+
+ /*
+ * L = 512
+ * SEED = b869c82b35d70e1b1ff91b28e37a62ecdc34409b
+ * counter = 123
+ */
+ BigInteger p512 =
+ new BigInteger("fca682ce8e12caba26efccf7110e526db078b05edecb" +
+ "cd1eb4a208f3ae1617ae01f35b91a47e6df63413c5e1" +
+ "2ed0899bcd132acd50d99151bdc43ee737592e17", 16);
+
+ BigInteger q512 =
+ new BigInteger("962eddcc369cba8ebb260ee6b6a126d9346e38c5", 16);
+
+ BigInteger g512 =
+ new BigInteger("678471b27a9cf44ee91a49c5147db1a9aaf244f05a43" +
+ "4d6486931d2d14271b9e35030b71fd73da179069b32e" +
+ "2935630e1c2062354d0da20a6c416e50be794ca4", 16);
+
+ /*
+ * L = 768
+ * SEED = 77d0f8c4dad15eb8c4f2f8d6726cefd96d5bb399
+ * counter = 263
+ */
+ BigInteger p768 =
+ new BigInteger("e9e642599d355f37c97ffd3567120b8e25c9cd43e" +
+ "927b3a9670fbec5d890141922d2c3b3ad24800937" +
+ "99869d1e846aab49fab0ad26d2ce6a22219d470bc" +
+ "e7d777d4a21fbe9c270b57f607002f3cef8393694" +
+ "cf45ee3688c11a8c56ab127a3daf", 16);
+
+ BigInteger q768 =
+ new BigInteger("9cdbd84c9f1ac2f38d0f80f42ab952e7338bf511",
+ 16);
+
+ BigInteger g768 =
+ new BigInteger("30470ad5a005fb14ce2d9dcd87e38bc7d1b1c5fac" +
+ "baecbe95f190aa7a31d23c4dbbcbe06174544401a" +
+ "5b2c020965d8c2bd2171d3668445771f74ba084d2" +
+ "029d83c1c158547f3a9f1a2715be23d51ae4d3e5a" +
+ "1f6a7064f316933a346d3f529252", 16);
+
+ /*
+ * L = 1024
+ * SEED = 8d5155894229d5e689ee01e6018a237e2cae64cd
+ * counter = 92
+ */
+ BigInteger p1024 =
+ new BigInteger("fd7f53811d75122952df4a9c2eece4e7f611b7523c" +
+ "ef4400c31e3f80b6512669455d402251fb593d8d58" +
+ "fabfc5f5ba30f6cb9b556cd7813b801d346ff26660" +
+ "b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c6" +
+ "1bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554" +
+ "135a169132f675f3ae2b61d72aeff22203199dd148" +
+ "01c7", 16);
+
+ BigInteger q1024 =
+ new BigInteger("9760508f15230bccb292b982a2eb840bf0581cf5",
+ 16);
+
+ BigInteger g1024 =
+ new BigInteger("f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa" +
+ "3aea82f9574c0b3d0782675159578ebad4594fe671" +
+ "07108180b449167123e84c281613b7cf09328cc8a6" +
+ "e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f" +
+ "0bfa213562f1fb627a01243bcca4f1bea8519089a8" +
+ "83dfe15ae59f06928b665e807b552564014c3bfecf" +
+ "492a", 16);
+
+ try {
+ AlgIdDSA alg512 = new AlgIdDSA(p512, q512, g512);
+ AlgIdDSA alg768 = new AlgIdDSA(p768, q768, g768);
+ AlgIdDSA alg1024 = new AlgIdDSA(p1024, q1024, g1024);
+
+ precomputedParams.put(Integer.valueOf(512), alg512);
+ precomputedParams.put(Integer.valueOf(768), alg768);
+ precomputedParams.put(Integer.valueOf(1024), alg1024);
+
+ } catch (Exception e) {
+ throw new InternalError("initializing precomputed " +
+ "algorithm parameters for Sun DSA");
+ }
+ }
+
+ /* The modulus length */
+ private int modlen = 1024;
+
+ /* Generate new parameters, even if we have precomputed ones. */
+ boolean generateNewParameters = false;
+
+ /* preset algorithm parameters. */
+ private BigInteger presetP, presetQ, presetG;
+
+ /* The source of random bits to use */
+ SecureRandom random;
+
+ public DSAKeyPairGenerator() {
+ super("DSA");
+ }
+
+ public void initialize(int strength, SecureRandom random) {
+ if ((strength < 512) || (strength > 1024) || (strength % 64 != 0)) {
+ throw new InvalidParameterException("Modulus size must range from 512 to 1024 "
+ + "and be a multiple of 64");
+ }
+
+ /* Set the random */
+ this.random = random;
+ if (this.random == null) {
+ this.random = new SecureRandom();
+ }
+
+ this.modlen = strength;
+ DSAParams params = null;
+
+ /* Find the precomputed parameters, if any */
+ if (!generateNewParameters) {
+ Integer mod = Integer.valueOf(this.modlen);
+ params = precomputedParams.get(mod);
+ }
+ if (params != null) {
+ setParams(params);
+ }
+ }
+
+ /**
+ * Initializes the DSA key pair generator. If <code>genParams</code> is false, a set of pre-computed parameters is
+ * used. In this case, <code>modelen</code> must be 512, 768, or 1024.
+ */
+ public void initialize(int modlen, boolean genParams, SecureRandom random)
+ throws InvalidParameterException {
+ if (genParams == false && modlen != 512 && modlen != 768
+ && modlen != 1024) {
+ throw new InvalidParameterException("No precomputed parameters for requested modulus size "
+ + "available");
+ }
+ this.generateNewParameters = genParams;
+ initialize(modlen, random);
+ }
+
+ /**
+ * Initializes the DSA object using a DSA parameter object.
+ *
+ * @param params a fully initialized DSA parameter object.
+ */
+ public void initialize(DSAParams params, SecureRandom random)
+ throws InvalidParameterException {
+ initialize(params.getP().bitLength(), random);
+ setParams(params);
+ }
+
+ /**
+ * Initializes the DSA object using a parameter object.
+ *
+ * @param params the parameter set to be used to generate
+ * the keys.
+ * @param random the source of randomness for this generator.
+ *
+ * @exception InvalidAlgorithmParameterException if the given parameters
+ * are inappropriate for this key pair generator
+ */
+ public void initialize(AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidAlgorithmParameterException {
+ if (!(params instanceof DSAParameterSpec)) {
+ throw new InvalidAlgorithmParameterException("Inappropriate parameter");
+ }
+ initialize(((DSAParameterSpec) params).getP().bitLength(),
+ random);
+ setParams((DSAParameterSpec) params);
+ }
+
+ /**
+ * Generates a pair of keys usable by any JavaSecurity compliant
+ * DSA implementation.
+ *
+ * @param rnd the source of random bits from which the random key
+ * generation parameters are drawn. In particular, this includes
+ * the XSEED parameter.
+ *
+ * @exception InvalidParameterException if the modulus is not
+ * between 512 and 1024.
+ */
+ public KeyPair generateKeyPair() {
+
+ // set random if initialize() method has been skipped
+ if (this.random == null) {
+ this.random = new SecureRandom();
+ }
+
+ if (presetP == null || presetQ == null || presetG == null ||
+ generateNewParameters) {
+
+ AlgorithmParameterGenerator dsaParamGen;
+
+ try {
+ dsaParamGen = AlgorithmParameterGenerator.getInstance("DSA",
+ "SUN");
+ } catch (NoSuchAlgorithmException e) {
+ // this should never happen, because we provide it
+ throw new RuntimeException(e.getMessage());
+ } catch (NoSuchProviderException e) {
+ // this should never happen, because we provide it
+ throw new RuntimeException(e.getMessage());
+ }
+
+ dsaParamGen.init(modlen, random);
+
+ DSAParameterSpec dsaParamSpec;
+ try {
+ dsaParamSpec = (DSAParameterSpec)
+ dsaParamGen.generateParameters().getParameterSpec
+ (DSAParameterSpec.class);
+ } catch (InvalidParameterSpecException e) {
+ // this should never happen
+ throw new RuntimeException(e.getMessage());
+ }
+ presetP = dsaParamSpec.getP();
+ presetQ = dsaParamSpec.getQ();
+ presetG = dsaParamSpec.getG();
+ }
+
+ return generateKeyPair(presetP, presetQ, presetG, random);
+ }
+
+ public KeyPair generateKeyPair(BigInteger p, BigInteger q, BigInteger g,
+ SecureRandom random) {
+
+ BigInteger x = generateX(random, q);
+ BigInteger y = generateY(x, p, g);
+
+ try {
+ DSAPublicKey pub = new DSAPublicKey(y, p, q, g);
+ DSAPrivateKey priv = new DSAPrivateKey(x, p, q, g);
+
+ KeyPair pair = new KeyPair(pub, priv);
+ return pair;
+
+ } catch (InvalidKeyException e) {
+ throw new ProviderException(e.getMessage());
+ }
+ }
+
+ /* Test vectors from the DSA specs. */
+
+ private static int[] testXSeed = { 0xbd029bbe, 0x7f51960b, 0xcf9edb2b,
+ 0x61f06f0f, 0xeb5a38b6 };
+
+ private int[] x_t = { 0x67452301, 0xefcdab89, 0x98badcfe,
+ 0x10325476, 0xc3d2e1f0 };
+
+ /**
+ * Generate the private key component of the key pair using the
+ * provided source of random bits. This method uses the random but
+ * source passed to generate a seed and then calls the seed-based
+ * generateX method.
+ */
+ private BigInteger generateX(SecureRandom random, BigInteger q) {
+ BigInteger x = null;
+ while (true) {
+ int[] seed = new int[5];
+ for (int i = 0; i < 5; i++) {
+ seed[i] = random.nextInt();
+ }
+ x = generateX(seed, q);
+ if (x.signum() > 0 && (x.compareTo(q) < 0)) {
+ break;
+ }
+ }
+ return x;
+ }
+
+ /**
+ * Given a seed, generate the private key component of the key
+ * pair. In the terminology used in the DSA specification
+ * (FIPS-186) seed is the XSEED quantity.
+ *
+ * @param seed the seed to use to generate the private key.
+ */
+ BigInteger generateX(int[] seed, BigInteger q) {
+
+ /* Test vector
+ int[] tseed = { 0xbd029bbe, 0x7f51960b, 0xcf9edb2b,
+ 0x61f06f0f, 0xeb5a38b6 };
+ seed = tseed;
+ */
+ // check out t in the spec.
+ int[] t = { 0x67452301, 0xEFCDAB89, 0x98BADCFE,
+ 0x10325476, 0xC3D2E1F0 };
+ //
+
+ int[] tmp = DSA.SHA_7(seed, t);
+ byte[] tmpBytes = new byte[tmp.length * 4];
+ for (int i = 0; i < tmp.length; i++) {
+ int k = tmp[i];
+ for (int j = 0; j < 4; j++) {
+ tmpBytes[(i * 4) + j] = (byte) (k >>> (24 - (j * 8)));
+ }
+ }
+ BigInteger x = new BigInteger(1, tmpBytes).mod(q);
+ return x;
+ }
+
+ /**
+ * Generate the public key component y of the key pair.
+ *
+ * @param x the private key component.
+ *
+ * @param p the base parameter.
+ */
+ BigInteger generateY(BigInteger x, BigInteger p, BigInteger g) {
+ BigInteger y = g.modPow(x, p);
+ return y;
+ }
+
+ /**
+ * Set the parameters.
+ */
+ private void setParams(DSAParams params) {
+ presetP = params.getP();
+ presetQ = params.getQ();
+ presetG = params.getG();
+ }
+
+ /**
+ * Set the parameters.
+ */
+ private void setParams(DSAParameterSpec params) {
+ presetP = params.getP();
+ presetQ = params.getQ();
+ presetG = params.getG();
+ }
+}
diff --git a/base/util/src/netscape/security/provider/DSAParameterGenerator.java b/base/util/src/netscape/security/provider/DSAParameterGenerator.java
new file mode 100755
index 000000000..cd7b8de33
--- /dev/null
+++ b/base/util/src/netscape/security/provider/DSAParameterGenerator.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 netscape.security.provider;
+
+import java.math.BigInteger;
+import java.security.AlgorithmParameterGeneratorSpi;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+/*
+ * This class generates parameters for the DSA algorithm. It uses a default
+ * prime modulus size of 1024 bits, which can be overwritten during
+ * initialization.
+ *
+ * @author Jan Luehe
+ *
+ * @version 1.4, 97/12/10
+ *
+ * @see java.security.AlgorithmParameters
+ * @see java.security.spec.AlgorithmParameterSpec
+ * @see DSAParameters
+ *
+ * @since JDK1.2
+ */
+
+public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
+
+ // the modulus length
+ private int modLen = 1024; // default
+
+ // the source of randomness
+ private SecureRandom random;
+
+ // useful constants
+ private static final BigInteger ZERO = BigInteger.valueOf(0);
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+ private static final BigInteger TWO = BigInteger.valueOf(2);
+
+ // Make a SHA-1 hash function
+ private SHA sha;
+
+ public DSAParameterGenerator() {
+ this.sha = new SHA();
+ }
+
+ /**
+ * Initializes this parameter generator for a certain strength
+ * and source of randomness.
+ *
+ * @param strength the strength (size of prime) in bits
+ * @param random the source of randomness
+ */
+ protected void engineInit(int strength, SecureRandom random) {
+ /*
+ * Bruce Schneier, "Applied Cryptography", 2nd Edition,
+ * Description of DSA:
+ * [...] The algorithm uses the following parameter:
+ * p=a prime number L bits long, when L ranges from 512 to 1024 and is
+ * a multiple of 64. [...]
+ */
+ if ((strength < 512) || (strength > 1024) || (strength % 64 != 0)) {
+ throw new InvalidParameterException("Prime size must range from 512 to 1024 "
+ + "and be a multiple of 64");
+ }
+ this.modLen = strength;
+ this.random = random;
+ }
+
+ /**
+ * Initializes this parameter generator with a set of
+ * algorithm-specific parameter generation values.
+ *
+ * @param params the set of algorithm-specific parameter generation values
+ * @param random the source of randomness
+ *
+ * @exception InvalidAlgorithmParameterException if the given parameter
+ * generation values are inappropriate for this parameter generator
+ */
+ protected void engineInit(AlgorithmParameterSpec genParamSpec,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException {
+ throw new InvalidAlgorithmParameterException("Invalid parameter");
+ }
+
+ /**
+ * Generates the parameters.
+ *
+ * @return the new AlgorithmParameters object
+ */
+ protected AlgorithmParameters engineGenerateParameters() {
+ AlgorithmParameters algParams = null;
+ try {
+ if (this.random == null) {
+ this.random = new SecureRandom();
+ }
+
+ BigInteger[] pAndQ = generatePandQ(this.random, this.modLen);
+ BigInteger paramP = pAndQ[0];
+ BigInteger paramQ = pAndQ[1];
+ BigInteger paramG = generateG(paramP, paramQ);
+
+ DSAParameterSpec dsaParamSpec = new DSAParameterSpec(paramP,
+ paramQ,
+ paramG);
+ algParams = AlgorithmParameters.getInstance("DSA", "SUN");
+ algParams.init(dsaParamSpec);
+ } catch (InvalidParameterSpecException e) {
+ // this should never happen
+ throw new RuntimeException(e.getMessage());
+ } catch (NoSuchAlgorithmException e) {
+ // this should never happen, because we provide it
+ throw new RuntimeException(e.getMessage());
+ } catch (NoSuchProviderException e) {
+ // this should never happen, because we provide it
+ throw new RuntimeException(e.getMessage());
+ }
+
+ return algParams;
+ }
+
+ /*
+ * Generates the prime and subprime parameters for DSA,
+ * using the provided source of randomness.
+ * This method will generate new seeds until a suitable
+ * seed has been found.
+ *
+ * @param random the source of randomness to generate the
+ * seed
+ * @param L the size of <code>p</code>, in bits.
+ *
+ * @return an array of BigInteger, with <code>p</code> at index 0 and
+ * <code>q</code> at index 1.
+ */
+ BigInteger[] generatePandQ(SecureRandom random, int L) {
+ BigInteger[] result = null;
+ byte[] seed = new byte[20];
+
+ while (result == null) {
+ for (int i = 0; i < 20; i++) {
+ seed[i] = (byte) random.nextInt();
+ }
+ result = generatePandQ(seed, L);
+ }
+ return result;
+ }
+
+ /*
+ * Generates the prime and subprime parameters for DSA.
+ *
+ * <p>The seed parameter corresponds to the <code>SEED</code> parameter
+ * referenced in the FIPS specification of the DSA algorithm,
+ * and L is the size of <code>p</code>, in bits.
+ *
+ * @param seed the seed to generate the parameters
+ * @param L the size of <code>p</code>, in bits.
+ *
+ * @return an array of BigInteger, with <code>p</code> at index 0,
+ * <code>q</code> at index 1, the seed at index 2, and the counter value
+ * at index 3, or null if the seed does not yield suitable numbers.
+ */
+ BigInteger[] generatePandQ(byte[] seed, int L) {
+
+ /* Useful variables */
+ int g = seed.length * 8;
+ int n = (L - 1) / 160;
+ int b = (L - 1) % 160;
+
+ BigInteger SEED = new BigInteger(1, seed);
+ BigInteger TWOG = TWO.pow(2 * g);
+
+ /* Step 2 (Step 1 is getting seed). */
+ byte[] U1 = SHA(seed);
+ byte[] U2 = SHA(toByteArray((SEED.add(ONE)).mod(TWOG)));
+
+ xor(U1, U2);
+ byte[] U = U1;
+
+ /* Step 3: For q by setting the msb and lsb to 1 */
+ U[0] |= 0x80;
+ U[19] |= 1;
+ BigInteger q = new BigInteger(1, U);
+
+ /* Step 5 */
+ if (!q.isProbablePrime(40)) {
+ return null;
+
+ } else {
+ BigInteger V[] = new BigInteger[n + 1];
+ BigInteger offset = TWO;
+
+ /* Step 6 */
+ for (int counter = 0; counter < 4096; counter++) {
+
+ /* Step 7 */
+ for (int k = 0; k <= n; k++) {
+ BigInteger K = BigInteger.valueOf(k);
+ BigInteger tmp = (SEED.add(offset).add(K)).mod(TWOG);
+ V[k] = new BigInteger(1, SHA(toByteArray(tmp)));
+ }
+
+ /* Step 8 */
+ BigInteger W = V[0];
+ for (int i = 1; i < n; i++) {
+ W = W.add(V[i].multiply(TWO.pow(i * 160)));
+ }
+ W = W.add((V[n].mod(TWO.pow(b))).multiply(TWO.pow(n * 160)));
+
+ BigInteger TWOLm1 = TWO.pow(L - 1);
+ BigInteger X = W.add(TWOLm1);
+
+ /* Step 9 */
+ BigInteger c = X.mod(q.multiply(TWO));
+ BigInteger p = X.subtract(c.subtract(ONE));
+
+ /* Step 10 - 13 */
+ if (p.compareTo(TWOLm1) > -1 && p.isProbablePrime(15)) {
+ BigInteger[] result = { p, q, SEED,
+ BigInteger.valueOf(counter) };
+ return result;
+ }
+ offset = offset.add(BigInteger.valueOf(n)).add(ONE);
+ }
+ return null;
+ }
+ }
+
+ /*
+ * Generates the <code>g</code> parameter for DSA.
+ *
+ * @param p the prime, <code>p</code>.
+ * @param q the subprime, <code>q</code>.
+ *
+ * @param the <code>g</code>
+ */
+ BigInteger generateG(BigInteger p, BigInteger q) {
+ BigInteger h = ONE;
+ BigInteger pMinusOneOverQ = (p.subtract(ONE)).divide(q);
+ BigInteger g = ONE;
+ while (g.compareTo(TWO) < 0) {
+ g = h.modPow(pMinusOneOverQ, p);
+ h = h.add(ONE);
+ }
+ return g;
+ }
+
+ /*
+ * Returns the SHA-1 digest of some data
+ */
+ private byte[] SHA(byte[] array) {
+ sha.engineReset();
+ sha.engineUpdate(array, 0, array.length);
+ return sha.engineDigest();
+ }
+
+ /*
+ * Converts the result of a BigInteger.toByteArray call to an exact
+ * signed magnitude representation for any positive number.
+ */
+ private byte[] toByteArray(BigInteger bigInt) {
+ byte[] result = bigInt.toByteArray();
+ if (result[0] == 0) {
+ byte[] tmp = new byte[result.length - 1];
+ System.arraycopy(result, 1, tmp, 0, tmp.length);
+ result = tmp;
+ }
+ return result;
+ }
+
+ /*
+ * XORs U2 into U1
+ */
+ private void xor(byte[] U1, byte[] U2) {
+ for (int i = 0; i < U1.length; i++) {
+ U1[i] ^= U2[i];
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/provider/DSAParameters.java b/base/util/src/netscape/security/provider/DSAParameters.java
new file mode 100755
index 000000000..e2a5dd128
--- /dev/null
+++ b/base/util/src/netscape/security/provider/DSAParameters.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 netscape.security.provider;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.AlgorithmParametersSpi;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class implements the parameter set used by the
+ * Digital Signature Algorithm as specified in the FIPS 186
+ * standard.
+ *
+ * @author Jan Luehe
+ *
+ * @version 1.8, 97/12/10
+ *
+ * @since JDK1.2
+ */
+
+public class DSAParameters extends AlgorithmParametersSpi {
+
+ // the prime (p)
+ protected BigInteger p;
+
+ // the sub-prime (q)
+ protected BigInteger q;
+
+ // the base (g)
+ protected BigInteger g;
+
+ protected void engineInit(AlgorithmParameterSpec paramSpec)
+ throws InvalidParameterSpecException {
+ if (!(paramSpec instanceof DSAParameterSpec)) {
+ throw new InvalidParameterSpecException("Inappropriate parameter specification");
+ }
+ this.p = ((DSAParameterSpec) paramSpec).getP();
+ this.q = ((DSAParameterSpec) paramSpec).getQ();
+ this.g = ((DSAParameterSpec) paramSpec).getG();
+ }
+
+ protected void engineInit(byte[] params) throws IOException {
+ DerValue encodedParams = new DerValue(params);
+
+ if (encodedParams.tag != DerValue.tag_Sequence) {
+ throw new IOException("DSA params parsing error");
+ }
+
+ encodedParams.data.reset();
+
+ this.p = encodedParams.data.getInteger().toBigInteger();
+ this.q = encodedParams.data.getInteger().toBigInteger();
+ this.g = encodedParams.data.getInteger().toBigInteger();
+
+ if (encodedParams.data.available() != 0) {
+ throw new IOException("encoded params have " +
+ encodedParams.data.available() +
+ " extra bytes");
+ }
+ }
+
+ protected void engineInit(byte[] params, String decodingMethod)
+ throws IOException {
+ engineInit(params);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected <T extends AlgorithmParameterSpec> T engineGetParameterSpec(Class<T> paramSpec)
+ throws InvalidParameterSpecException {
+ try {
+ Class<?> dsaParamSpec = Class.forName
+ ("java.security.spec.DSAParameterSpec");
+ if (dsaParamSpec.isAssignableFrom(paramSpec)) {
+ return (T) new DSAParameterSpec(this.p, this.q, this.g);
+ } else {
+ throw new InvalidParameterSpecException("Inappropriate parameter Specification");
+ }
+ } catch (ClassNotFoundException e) {
+ throw new InvalidParameterSpecException("Unsupported parameter specification: " + e.getMessage());
+ }
+ }
+
+ protected byte[] engineGetEncoded() throws IOException {
+ DerOutputStream out = new DerOutputStream();
+ DerOutputStream bytes = new DerOutputStream();
+
+ bytes.putInteger(new BigInt(p.toByteArray()));
+ bytes.putInteger(new BigInt(q.toByteArray()));
+ bytes.putInteger(new BigInt(g.toByteArray()));
+ out.write(DerValue.tag_Sequence, bytes);
+ return out.toByteArray();
+ }
+
+ protected byte[] engineGetEncoded(String encodingMethod)
+ throws IOException {
+ return engineGetEncoded();
+ }
+
+ /*
+ * Returns a formatted string describing the parameters.
+ */
+ protected String engineToString() {
+ return "\n\tp: " + new BigInt(p).toString()
+ + "\n\tq: " + new BigInt(q).toString()
+ + "\n\tg: " + new BigInt(g).toString()
+ + "\n";
+ }
+}
diff --git a/base/util/src/netscape/security/provider/DSAPrivateKey.java b/base/util/src/netscape/security/provider/DSAPrivateKey.java
new file mode 100644
index 000000000..0cfc5e5ea
--- /dev/null
+++ b/base/util/src/netscape/security/provider/DSAPrivateKey.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 netscape.security.provider;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.security.AlgorithmParameters;
+import java.security.InvalidKeyException;
+import java.security.interfaces.DSAParams;
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+import netscape.security.pkcs.PKCS8Key;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerValue;
+import netscape.security.x509.AlgIdDSA;
+
+/**
+ * A PKCS#8 private key for the Digital Signature Algorithm.
+ *
+ * @author Benjamin Renaud
+ *
+ * @version 1.47, 97/12/10
+ *
+ * @see DSAPublicKey
+ * @see AlgIdDSA
+ * @see DSA
+ */
+
+public final class DSAPrivateKey extends PKCS8Key
+ implements java.security.interfaces.DSAPrivateKey, Serializable {
+
+ /** use serialVersionUID from JDK 1.1. for interoperability */
+ private static final long serialVersionUID = -3244453684193605938L;
+
+ /* the private key */
+ private BigInteger x;
+
+ /*
+ * Keep this constructor for backwards compatibility with JDK1.1.
+ */
+ public DSAPrivateKey() {
+ }
+
+ /**
+ * Make a DSA private key out of a private key and three parameters.
+ */
+ public DSAPrivateKey(BigInteger x, BigInteger p,
+ BigInteger q, BigInteger g)
+ throws InvalidKeyException {
+ this.x = x;
+ algid = new AlgIdDSA(p, q, g);
+
+ try {
+ key = new DerValue(DerValue.tag_Integer,
+ x.toByteArray()).toByteArray();
+ encode();
+ } catch (IOException e) {
+ throw new InvalidKeyException("could not DER encode x: " +
+ e.getMessage());
+ }
+ }
+
+ /**
+ * Make a DSA private key from its DER encoding (PKCS #8).
+ */
+ public DSAPrivateKey(byte[] encoded) throws InvalidKeyException {
+ clearOldKey();
+ decode(encoded);
+ }
+
+ /**
+ * Returns the DSA parameters associated with this key, or null if the
+ * parameters could not be parsed.
+ */
+ public DSAParams getParams() {
+ try {
+ if (algid instanceof DSAParams) {
+ return (DSAParams) algid;
+ } else {
+ DSAParameterSpec paramSpec;
+ AlgorithmParameters algParams = algid.getParameters();
+ if (algParams == null) {
+ return null;
+ }
+ paramSpec = (DSAParameterSpec) algParams.getParameterSpec
+ (DSAParameterSpec.class);
+ return (DSAParams) paramSpec;
+ }
+ } catch (InvalidParameterSpecException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Get the raw private key, x, without the parameters.
+ *
+ */
+ public BigInteger getX() {
+ return x;
+ }
+
+ private void clearOldKey() {
+ int i;
+ if (this.encodedKey != null) {
+ for (i = 0; i < this.encodedKey.length; i++) {
+ this.encodedKey[i] = (byte) 0x00;
+ }
+ }
+ if (this.key != null) {
+ for (i = 0; i < this.key.length; i++) {
+ this.key[i] = (byte) 0x00;
+ }
+ }
+ }
+
+ public String toString() {
+ return "Sun DSA Private Key \nparameters:" + algid + "\nx: " +
+ x.toString(16) + "\n";
+ }
+
+ protected void parseKeyBits() throws InvalidKeyException {
+ DerInputStream in = new DerInputStream(key);
+
+ try {
+ x = in.getInteger().toBigInteger();
+ } catch (IOException e) {
+ throw new InvalidKeyException(e.getMessage());
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/provider/DSAPublicKey.java b/base/util/src/netscape/security/provider/DSAPublicKey.java
new file mode 100644
index 000000000..89262809b
--- /dev/null
+++ b/base/util/src/netscape/security/provider/DSAPublicKey.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 netscape.security.provider;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.security.AlgorithmParameters;
+import java.security.InvalidKeyException;
+import java.security.interfaces.DSAParams;
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerValue;
+import netscape.security.x509.AlgIdDSA;
+import netscape.security.x509.X509Key;
+
+/**
+ * An X.509 public key for the Digital Signature Algorithm.
+ *
+ * @author Benjamin Renaud
+ *
+ * @version 1.52, 97/12/10
+ *
+ * @see DSAPrivateKey
+ * @see AlgIdDSA
+ * @see DSA
+ */
+
+public final class DSAPublicKey extends X509Key
+ implements java.security.interfaces.DSAPublicKey, Serializable {
+
+ /** use serialVersionUID from JDK 1.1. for interoperability */
+ private static final long serialVersionUID = -2994193307391104133L;
+
+ /* the public key */
+ private BigInteger y;
+
+ /*
+ * Keep this constructor for backwards compatibility with JDK1.1.
+ */
+ public DSAPublicKey() {
+ }
+
+ /**
+ * Make a DSA public key out of a public key and three parameters.
+ */
+ public DSAPublicKey(BigInteger y, BigInteger p, BigInteger q,
+ BigInteger g)
+ throws InvalidKeyException {
+ this.y = y;
+ algid = new AlgIdDSA(p, q, g);
+
+ try {
+ key = new DerValue(DerValue.tag_Integer,
+ y.toByteArray()).toByteArray();
+ encode();
+ } catch (IOException e) {
+ throw new InvalidKeyException("could not DER encode y: " +
+ e.getMessage());
+ }
+ }
+
+ /**
+ * Make a DSA public key from its DER encoding (X.509).
+ */
+ public DSAPublicKey(byte[] encoded) throws InvalidKeyException {
+ decode(encoded);
+ }
+
+ /**
+ * Returns the DSA parameters associated with this key, or null if the
+ * parameters could not be parsed.
+ */
+ public DSAParams getParams() {
+ try {
+ if (algid instanceof DSAParams) {
+ return (DSAParams) algid;
+ } else {
+ DSAParameterSpec paramSpec;
+ AlgorithmParameters algParams = algid.getParameters();
+ if (algParams == null) {
+ return null;
+ }
+ paramSpec = (DSAParameterSpec) algParams.getParameterSpec
+ (DSAParameterSpec.class);
+ return (DSAParams) paramSpec;
+ }
+ } catch (InvalidParameterSpecException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Get the raw public value, y, without the parameters.
+ *
+ */
+ public BigInteger getY() {
+ return y;
+ }
+
+ public String toString() {
+ return "Sun DSA Public Key\n Parameters:" + algid
+ + "\n y:\n" + (new BigInt(y)).toString() + "\n";
+ }
+
+ protected void parseKeyBits() throws InvalidKeyException {
+ try {
+ DerInputStream in = new DerInputStream(key);
+ y = in.getInteger().toBigInteger();
+ } catch (IOException e) {
+ throw new InvalidKeyException("Invalid key: y value\n" +
+ e.getMessage());
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/provider/MD5.java b/base/util/src/netscape/security/provider/MD5.java
new file mode 100644
index 000000000..d7aeacaee
--- /dev/null
+++ b/base/util/src/netscape/security/provider/MD5.java
@@ -0,0 +1,378 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.provider;
+
+import java.security.DigestException;
+import java.security.MessageDigestSpi;
+
+/**
+ * The MD5 class is used to compute an MD5 message digest over a given
+ * buffer of bytes. It is an implementation of the RSA Data Security Inc
+ * MD5 algorithim as described in internet RFC 1321.
+ *
+ * @version 1.24 97/12/10
+ * @author Chuck McManis
+ * @author Benjamin Renaud
+ */
+
+public final class MD5 extends MessageDigestSpi implements Cloneable {
+
+ /** contains the computed message digest */
+ private byte[] digestBits;
+
+ private String algorithm;
+
+ private int state[];
+ private long count; // bit count AND buffer[] index aid
+ private byte buffer[];
+ private int transformBuffer[];
+
+ private static final int S11 = 7;
+ private static final int S12 = 12;
+ private static final int S13 = 17;
+ private static final int S14 = 22;
+ private static final int S21 = 5;
+ private static final int S22 = 9;
+ private static final int S23 = 14;
+ private static final int S24 = 20;
+ private static final int S31 = 4;
+ private static final int S32 = 11;
+ private static final int S33 = 16;
+ private static final int S34 = 23;
+ private static final int S41 = 6;
+ private static final int S42 = 10;
+ private static final int S43 = 15;
+ private static final int S44 = 21;
+
+ private static final int MD5_LENGTH = 16;
+
+ /**
+ * Standard constructor, creates a new MD5 instance, allocates its
+ * buffers from the heap.
+ */
+ public MD5() {
+ init();
+ }
+
+ /* **********************************************************
+ * The MD5 Functions. These are copied verbatim from
+ * the RFC to insure accuracy. The results of this
+ * implementation were checked against the RSADSI version.
+ * **********************************************************
+ */
+
+ private int F(int x, int y, int z) {
+ return ((x & y) | ((~x) & z));
+ }
+
+ private int G(int x, int y, int z) {
+ return ((x & z) | (y & (~z)));
+ }
+
+ private int H(int x, int y, int z) {
+ return ((x ^ y) ^ z);
+ }
+
+ private int I(int x, int y, int z) {
+ return (y ^ (x | (~z)));
+ }
+
+ private int rotateLeft(int a, int n) {
+ return ((a << n) | (a >>> (32 - n)));
+ }
+
+ private int FF(int a, int b, int c, int d, int x, int s, int ac) {
+ a += F(b, c, d) + x + ac;
+ a = rotateLeft(a, s);
+ a += b;
+ return a;
+ }
+
+ private int GG(int a, int b, int c, int d, int x, int s, int ac) {
+ a += G(b, c, d) + x + ac;
+ a = rotateLeft(a, s);
+ a += b;
+ return a;
+ }
+
+ private int HH(int a, int b, int c, int d, int x, int s, int ac) {
+ a += H(b, c, d) + x + ac;
+ a = rotateLeft(a, s);
+ a += b;
+ return a;
+ }
+
+ private int II(int a, int b, int c, int d, int x, int s, int ac) {
+ a += I(b, c, d) + x + ac;
+ a = rotateLeft(a, s);
+ a += b;
+ return a;
+ }
+
+ /**
+ * This is where the functions come together as the generic MD5
+ * transformation operation, it is called by update() which is
+ * synchronized (to protect transformBuffer). It consumes sixteen
+ * bytes from the buffer, beginning at the specified offset.
+ */
+ void transform(byte buf[], int offset) {
+ int a, b, c, d;
+ int x[] = transformBuffer;
+
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+
+ for (int i = 0; i < 16; i++) {
+ x[i] = (int) buf[i * 4 + offset] & 0xff;
+ for (int j = 1; j < 4; j++) {
+ x[i] += ((int) buf[i * 4 + j + offset] & 0xff) << (j * 8);
+ }
+ }
+
+ /* Round 1 */
+ a = FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
+ d = FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
+ c = FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
+ b = FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
+ a = FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
+ d = FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
+ c = FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
+ b = FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
+ a = FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
+ d = FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
+ c = FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+ b = FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+ a = FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+ d = FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+ c = FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+ b = FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+ a = GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
+ d = GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
+ c = GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+ b = GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
+ a = GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
+ d = GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
+ c = GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+ b = GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
+ a = GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
+ d = GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+ c = GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
+ b = GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
+ a = GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+ d = GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
+ c = GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
+ b = GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+ a = HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
+ d = HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
+ c = HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+ b = HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+ a = HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
+ d = HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
+ c = HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
+ b = HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+ a = HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+ d = HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
+ c = HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
+ b = HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
+ a = HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
+ d = HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+ c = HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+ b = HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+ a = II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
+ d = II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
+ c = II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+ b = II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
+ a = II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+ d = II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
+ c = II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+ b = II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
+ a = II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
+ d = II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+ c = II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
+ b = II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+ a = II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
+ d = II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+ c = II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
+ b = II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ }
+
+ /**
+ * Initialize the MD5 state information and reset the bit count
+ * to 0. Given this implementation you are constrained to counting
+ * 2^64 bits.
+ */
+ public void init() {
+ state = new int[4];
+ transformBuffer = new int[16];
+ buffer = new byte[64];
+ digestBits = new byte[16];
+ count = 0;
+ // Load magic initialization constants.
+ state[0] = 0x67452301;
+ state[1] = 0xefcdab89;
+ state[2] = 0x98badcfe;
+ state[3] = 0x10325476;
+ for (int i = 0; i < digestBits.length; i++)
+ digestBits[i] = 0;
+ }
+
+ protected void engineReset() {
+ init();
+ }
+
+ /**
+ * Return the digest length in bytes
+ */
+ protected int engineGetDigestLength() {
+ return (MD5_LENGTH);
+ }
+
+ /**
+ * Update adds the passed byte to the digested data.
+ */
+ protected synchronized void engineUpdate(byte b) {
+ int index;
+
+ index = (int) ((count >>> 3) & 0x3f);
+ count += 8;
+ buffer[index] = b;
+ if (index >= 63) {
+ transform(buffer, 0);
+ }
+ }
+
+ /**
+ * Update adds the selected part of an array of bytes to the digest.
+ * This version is more efficient than the byte-at-a-time version;
+ * it avoids data copies and reduces per-byte call overhead.
+ */
+ protected synchronized void engineUpdate(byte input[], int offset,
+ int len) {
+ int i;
+
+ for (i = offset; len > 0;) {
+ int index = (int) ((count >>> 3) & 0x3f);
+
+ if (index == 0 && len > 64) {
+ count += (64 * 8);
+ transform(input, i);
+ len -= 64;
+ i += 64;
+ } else {
+ count += 8;
+ buffer[index] = input[i];
+ if (index >= 63)
+ transform(buffer, 0);
+ i++;
+ len--;
+ }
+ }
+ }
+
+ /**
+ * Perform the final computations, any buffered bytes are added
+ * to the digest, the count is added to the digest, and the resulting
+ * digest is stored. After calling final you will need to call
+ * init() again to do another digest.
+ */
+ private void finish() {
+ byte bits[] = new byte[8];
+ byte padding[];
+ int i, index, padLen;
+
+ for (i = 0; i < 8; i++) {
+ bits[i] = (byte) ((count >>> (i * 8)) & 0xff);
+ }
+
+ index = (int) (count >> 3) & 0x3f;
+ padLen = (index < 56) ? (56 - index) : (120 - index);
+ padding = new byte[padLen];
+ padding[0] = (byte) 0x80;
+ engineUpdate(padding, 0, padding.length);
+ engineUpdate(bits, 0, bits.length);
+
+ for (i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ digestBits[i * 4 + j] = (byte) ((state[i] >>> (j * 8)) & 0xff);
+ }
+ }
+ }
+
+ /**
+ */
+ protected byte[] engineDigest() {
+ finish();
+
+ byte[] result = new byte[MD5_LENGTH];
+ System.arraycopy(digestBits, 0, result, 0, MD5_LENGTH);
+
+ init();
+
+ return result;
+ }
+
+ /**
+ */
+ protected int engineDigest(byte[] buf, int offset, int len)
+ throws DigestException {
+ finish();
+
+ if (len < MD5_LENGTH)
+ throw new DigestException("partial digests not returned");
+ if (buf.length - offset < MD5_LENGTH)
+ throw new DigestException("insufficient space in the output " +
+ "buffer to store the digest");
+
+ System.arraycopy(digestBits, 0, buf, offset, MD5_LENGTH);
+
+ init();
+
+ return MD5_LENGTH;
+ }
+
+ /*
+ * Clones this object.
+ */
+ public Object clone() {
+ MD5 that = null;
+ try {
+ that = (MD5) super.clone();
+ that.state = (int[]) this.state.clone();
+ that.transformBuffer = (int[]) this.transformBuffer.clone();
+ that.buffer = (byte[]) this.buffer.clone();
+ that.digestBits = (byte[]) this.digestBits.clone();
+ that.count = this.count;
+ return that;
+ } catch (CloneNotSupportedException e) {
+ }
+ return that;
+ }
+}
diff --git a/base/util/src/netscape/security/provider/RSAPublicKey.java b/base/util/src/netscape/security/provider/RSAPublicKey.java
new file mode 100644
index 000000000..4c65b4fa0
--- /dev/null
+++ b/base/util/src/netscape/security/provider/RSAPublicKey.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 netscape.security.provider;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.security.InvalidKeyException;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.X509Key;
+
+/**
+ * An X.509 public key for the RSA Algorithm.
+ *
+ * @author galperin
+ *
+ * @version $Revision$, $Date$
+ *
+ */
+
+public final class RSAPublicKey extends X509Key implements Serializable {
+
+ /* XXX This currently understands only PKCS#1 RSA Encryption OID
+ and parameter format
+ Later we may consider adding X509v3 OID for RSA keys. Besides
+ different OID it also has a parameter equal to modulus size
+ in bits (redundant!)
+ */
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7764823589128565374L;
+
+ private static final ObjectIdentifier ALGORITHM_OID =
+ AlgorithmId.RSAEncryption_oid;
+
+ private BigInt modulus;
+ private BigInt publicExponent;
+
+ /*
+ * Keep this constructor for backwards compatibility with JDK1.1.
+ */
+ public RSAPublicKey() {
+ }
+
+ /**
+ * Make a RSA public key out of a public exponent and modulus
+ */
+ public RSAPublicKey(BigInt modulus, BigInt publicExponent)
+ throws InvalidKeyException {
+ this.modulus = modulus;
+ this.publicExponent = publicExponent;
+ this.algid = new AlgorithmId(ALGORITHM_OID);
+
+ try {
+ DerOutputStream out = new DerOutputStream();
+
+ out.putInteger(modulus);
+ out.putInteger(publicExponent);
+ key = (new DerValue(DerValue.tag_Sequence,
+ out.toByteArray())).toByteArray();
+ encode();
+ } catch (IOException ex) {
+ throw new InvalidKeyException("could not DER encode : " +
+ ex.getMessage());
+ }
+ }
+
+ /**
+ * Make a RSA public key from its DER encoding (X.509).
+ */
+ public RSAPublicKey(byte[] encoded) throws InvalidKeyException {
+ decode(encoded);
+ }
+
+ /**
+ * Get key size as number of bits in modulus
+ * (Always rounded up to a multiple of 8)
+ *
+ */
+ public int getKeySize() {
+ return this.modulus.byteLength() * 8;
+ }
+
+ /**
+ * Get the raw public exponent
+ *
+ */
+ public BigInt getPublicExponent() {
+ return this.publicExponent;
+ }
+
+ /**
+ * Get the raw modulus
+ *
+ */
+ public BigInt getModulus() {
+ return this.modulus;
+ }
+
+ public String toString() {
+ return "RSA Public Key\n Algorithm: " + algid
+ + "\n modulus:\n" + this.modulus.toString() + "\n"
+ + "\n publicExponent:\n" + this.publicExponent.toString()
+ + "\n";
+ }
+
+ protected void parseKeyBits() throws InvalidKeyException {
+ if (!this.algid.getOID().equals(ALGORITHM_OID) &&
+ !this.algid.getOID().equals(AlgorithmId.RSA_oid)) {
+ throw new InvalidKeyException("Key algorithm OID is not RSA");
+ }
+
+ try {
+ DerValue val = new DerValue(key);
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new InvalidKeyException("Invalid RSA public key format:" +
+ " must be a SEQUENCE");
+ }
+
+ DerInputStream in = val.data;
+
+ this.modulus = in.getInteger();
+ this.publicExponent = in.getInteger();
+ } catch (IOException e) {
+ throw new InvalidKeyException("Invalid RSA public key: " +
+ e.getMessage());
+ }
+ }
+
+}
diff --git a/base/util/src/netscape/security/provider/SHA.java b/base/util/src/netscape/security/provider/SHA.java
new file mode 100644
index 000000000..42a6b8b90
--- /dev/null
+++ b/base/util/src/netscape/security/provider/SHA.java
@@ -0,0 +1,349 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.provider;
+
+import java.security.DigestException;
+import java.security.MessageDigestSpi;
+
+/**
+ * This class implements the Secure Hash Algorithm (SHA) developed by
+ * the National Institute of Standards and Technology along with the
+ * National Security Agency. This is the updated version of SHA
+ * fip-180 as superseded by fip-180-1.
+ *
+ * <p>
+ * It implement JavaSecurity MessageDigest, and can be used by in the Java Security framework, as a pluggable
+ * implementation, as a filter for the digest stream classes.
+ *
+ * @version 1.30 97/12/10
+ * @author Roger Riggs
+ * @author Benjamin Renaud
+ */
+
+public class SHA extends MessageDigestSpi implements Cloneable {
+
+ /* This private hookm controlled by the appropriate constructor,
+ causes this class to implement the first version of SHA,
+ as defined in FIPS 180, as opposed to FIPS 180-1. This was
+ useful for DSA testing. */
+ private int version = 1;
+
+ private static final int SHA_LENGTH = 20;
+
+ // Buffer of int's and count of characters accumulated
+ // 64 bytes are included in each hash block so the low order
+ // bits of count are used to know how to pack the bytes into ints
+ // and to know when to compute the block and start the next one.
+ private int W[] = new int[80];
+ private long count = 0;
+ private final int countmax = 64;
+ private final int countmask = (countmax - 1);
+
+ private int AA, BB, CC, DD, EE;
+
+ SHA(int version) {
+ this();
+ this.version = version;
+ }
+
+ /**
+ * Creates a new SHA object.
+ */
+ public SHA() {
+ init();
+ }
+
+ /**
+ * Return the length of the digest in bytes
+ */
+ protected int engineGetDigestLength() {
+ return (SHA_LENGTH);
+ }
+
+ public void engineUpdate(byte b) {
+ engineUpdate((int) b);
+ }
+
+ /**
+ * Update a byte.
+ *
+ * @param b the byte
+ */
+ private void engineUpdate(int b) {
+ int word;
+ int offset;
+
+ /* compute word offset and bit offset within word the low bits
+ of count are inverted to make put the bytes in the write
+ order */
+ word = ((int) count & countmask) >>> 2;
+ offset = (~(int) count & 3) << 3;
+
+ W[word] = (W[word] & ~(0xff << offset)) | ((b & 0xff) << offset);
+
+ /* If this is the last byte of a block, compute the partial hash */
+ if (((int) count & countmask) == countmask) {
+ computeBlock();
+ }
+ count++;
+ }
+
+ /**
+ * Update a buffer.
+ *
+ * @param b the data to be updated.
+ * @param off the start offset in the data
+ * @param len the number of bytes to be updated.
+ */
+ public void engineUpdate(byte b[], int off, int len) {
+ int word;
+
+ if ((off < 0) || (len < 0) || (off + len > b.length))
+ throw new ArrayIndexOutOfBoundsException();
+
+ // Use single writes until integer aligned
+ while ((len > 0) &&
+ ((int) count & 3) != 0) {
+ engineUpdate(b[off]);
+ off++;
+ len--;
+ }
+
+ /* Assemble groups of 4 bytes to be inserted in integer array */
+ for (; len >= 4; len -= 4, off += 4) {
+
+ word = ((int) count & countmask) >> 2;
+
+ W[word] = ((b[off] & 0xff) << 24) |
+ ((b[off + 1] & 0xff) << 16) |
+ ((b[off + 2] & 0xff) << 8) |
+ ((b[off + 3] & 0xff));
+
+ count += 4;
+ if (((int) count & countmask) == 0) {
+ computeBlock();
+ }
+ }
+
+ /* Use single writes for last few bytes */
+ for (; len > 0; len--, off++) {
+ engineUpdate(b[off]);
+ }
+ }
+
+ /**
+ * Resets the buffers and hash value to start a new hash.
+ */
+ public void init() {
+ AA = 0x67452301;
+ BB = 0xefcdab89;
+ CC = 0x98badcfe;
+ DD = 0x10325476;
+ EE = 0xc3d2e1f0;
+
+ for (int i = 0; i < 80; i++)
+ W[i] = 0;
+ count = 0;
+ }
+
+ /**
+ * Resets the buffers and hash value to start a new hash.
+ */
+ public void engineReset() {
+ init();
+ }
+
+ /**
+ * Computes the final hash and returns the final value as a
+ * byte[20] array. The object is reset to be ready for further
+ * use, as specified in the JavaSecurity MessageDigest
+ * specification.
+ */
+ public byte[] engineDigest() {
+ byte hashvalue[] = new byte[SHA_LENGTH];
+
+ try {
+ engineDigest(hashvalue, 0, hashvalue.length);
+ } catch (DigestException e) {
+ throw new InternalError("");
+ }
+ return hashvalue;
+ }
+
+ /**
+ * Computes the final hash and returns the final value as a
+ * byte[20] array. The object is reset to be ready for further
+ * use, as specified in the JavaSecurity MessageDigest
+ * specification.
+ */
+ public int engineDigest(byte[] hashvalue, int offset, int len)
+ throws DigestException {
+
+ if (len < SHA_LENGTH)
+ throw new DigestException("partial digests not returned");
+ if (hashvalue.length - offset < SHA_LENGTH)
+ throw new DigestException("insufficient space in the output " +
+ "buffer to store the digest");
+
+ /* The number of bits before padding occurs */
+ long bits = count << 3;
+
+ engineUpdate(0x80);
+
+ /* Pad with zeros until length is a multiple of 448 (the last two
+ 32 ints are used a holder for bits (see above). */
+ while ((int) (count & countmask) != 56) {
+ engineUpdate(0);
+ }
+
+ W[14] = (int) (bits >>> 32);
+ W[15] = (int) (bits & 0xffffffff);
+
+ count += 8;
+ computeBlock();
+
+ // Copy out the result
+ hashvalue[offset + 0] = (byte) (AA >>> 24);
+ hashvalue[offset + 1] = (byte) (AA >>> 16);
+ hashvalue[offset + 2] = (byte) (AA >>> 8);
+ hashvalue[offset + 3] = (byte) (AA >>> 0);
+
+ hashvalue[offset + 4] = (byte) (BB >>> 24);
+ hashvalue[offset + 5] = (byte) (BB >>> 16);
+ hashvalue[offset + 6] = (byte) (BB >>> 8);
+ hashvalue[offset + 7] = (byte) (BB >>> 0);
+
+ hashvalue[offset + 8] = (byte) (CC >>> 24);
+ hashvalue[offset + 9] = (byte) (CC >>> 16);
+ hashvalue[offset + 10] = (byte) (CC >>> 8);
+ hashvalue[offset + 11] = (byte) (CC >>> 0);
+
+ hashvalue[offset + 12] = (byte) (DD >>> 24);
+ hashvalue[offset + 13] = (byte) (DD >>> 16);
+ hashvalue[offset + 14] = (byte) (DD >>> 8);
+ hashvalue[offset + 15] = (byte) (DD >>> 0);
+
+ hashvalue[offset + 16] = (byte) (EE >>> 24);
+ hashvalue[offset + 17] = (byte) (EE >>> 16);
+ hashvalue[offset + 18] = (byte) (EE >>> 8);
+ hashvalue[offset + 19] = (byte) (EE >>> 0);
+
+ engineReset(); // remove the evidence
+
+ return SHA_LENGTH;
+ }
+
+ // Constants for each round
+ private final int round1_kt = 0x5a827999;
+ private final int round2_kt = 0x6ed9eba1;
+ private final int round3_kt = 0x8f1bbcdc;
+ private final int round4_kt = 0xca62c1d6;
+
+ /**
+ * Compute a the hash for the current block.
+ *
+ * This is in the same vein as Peter Gutmann's algorithm listed in
+ * the back of Applied Cryptography, Compact implementation of
+ * "old" NIST Secure Hash Algorithm.
+ *
+ */
+ private void computeBlock() {
+ int temp, a, b, c, d, e;
+
+ // The first 16 ints have the byte stream, compute the rest of
+ // the buffer
+ for (int t = 16; t <= 79; t++) {
+ if (version == 0) {
+ W[t] = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
+ } else {
+ temp = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
+ W[t] = ((temp << 1) | (temp >>> (32 - 1)));
+ }
+ }
+
+ a = AA;
+ b = BB;
+ c = CC;
+ d = DD;
+ e = EE;
+
+ // Round 1
+ for (int i = 0; i < 20; i++) {
+ temp = ((a << 5) | (a >>> (32 - 5))) +
+ ((b & c) | ((~b) & d)) + e + W[i] + round1_kt;
+ e = d;
+ d = c;
+ c = ((b << 30) | (b >>> (32 - 30)));
+ b = a;
+ a = temp;
+ }
+
+ // Round 2
+ for (int i = 20; i < 40; i++) {
+ temp = ((a << 5) | (a >>> (32 - 5))) +
+ (b ^ c ^ d) + e + W[i] + round2_kt;
+ e = d;
+ d = c;
+ c = ((b << 30) | (b >>> (32 - 30)));
+ b = a;
+ a = temp;
+ }
+
+ // Round 3
+ for (int i = 40; i < 60; i++) {
+ temp = ((a << 5) | (a >>> (32 - 5))) +
+ ((b & c) | (b & d) | (c & d)) + e + W[i] + round3_kt;
+ e = d;
+ d = c;
+ c = ((b << 30) | (b >>> (32 - 30)));
+ b = a;
+ a = temp;
+ }
+
+ // Round 4
+ for (int i = 60; i < 80; i++) {
+ temp = ((a << 5) | (a >>> (32 - 5))) +
+ (b ^ c ^ d) + e + W[i] + round4_kt;
+ e = d;
+ d = c;
+ c = ((b << 30) | (b >>> (32 - 30)));
+ b = a;
+ a = temp;
+ }
+ AA += a;
+ BB += b;
+ CC += c;
+ DD += d;
+ EE += e;
+ }
+
+ /*
+ * Clones this object.
+ */
+ public Object clone() {
+ SHA that = null;
+ try {
+ that = (SHA) super.clone();
+ that.W = new int[80];
+ System.arraycopy(this.W, 0, that.W, 0, W.length);
+ return that;
+ } catch (CloneNotSupportedException e) {
+ }
+ return that;
+ }
+}
diff --git a/base/util/src/netscape/security/provider/Sun.java b/base/util/src/netscape/security/provider/Sun.java
new file mode 100644
index 000000000..df384aeab
--- /dev/null
+++ b/base/util/src/netscape/security/provider/Sun.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 netscape.security.provider;
+
+import java.security.Provider;
+
+/**
+ * The SUN Security Provider.
+ *
+ * @author Benjamin Renaud
+ *
+ * @version 1.24, 97/12/10
+ */
+
+/**
+ * Defines the SUN provider.
+ *
+ * Algorithm supported, and their names:
+ *
+ * - SHA-1 is the message digest scheme decribed FIPS 180-1.
+ * Aliases for SHA-1 are SHA.
+ *
+ * - DSA is the signature scheme described in FIPS 186. (SHA used in
+ * DSA is SHA-1: FIPS 186 with Change No 1.) Aliases for DSA are
+ * SHA/DSA, SHA-1/DSA, SHA1/DSA, DSS and the object identifier
+ * strings "OID.1.3.14.3.2.13", "OID.1.3.14.3.2.27" and
+ * "OID.1.2.840.10040.4.3".
+ *
+ * - DSA is the key generation scheme as described in FIPS 186.
+ * Aliases for DSA include the OID strings "OID.1.3.14.3.2.12"
+ * and "OID.1.2.840.10040.4.1".
+ *
+ * - MD5 is the message digest scheme described in RFC 1321.
+ * There are no aliases for MD5.
+ *
+ * Notes: The name of algorithm described in FIPS-180 is SHA-0, and is
+ * not supported by the SUN provider.)
+ */
+public final class Sun extends Provider {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 9134942296334703727L;
+ private static String info = "SUN Security Provider v1.0, " +
+ "DSA signing and key generation, SHA-1 and MD5 message digests.";
+
+ public Sun() {
+ /* We are the SUN provider */
+ super("SUN", 1.0, info);
+
+ try {
+
+ // AccessController.beginPrivileged();
+
+ /*
+ * Signature engines
+ */
+ put("Signature.DSA", "netscape.security.provider.DSA");
+
+ put("Alg.Alias.Signature.SHA/DSA", "DSA");
+ put("Alg.Alias.Signature.SHA1/DSA", "DSA");
+ put("Alg.Alias.Signature.SHA-1/DSA", "DSA");
+ put("Alg.Alias.Signature.DSS", "DSA");
+ put("Alg.Alias.Signature.OID.1.3.14.3.2.13", "DSA");
+ put("Alg.Alias.Signature.OID.1.3.14.3.2.27", "DSA");
+ put("Alg.Alias.Signature.OID.1.2.840.10040.4.3", "DSA");
+ // the following are not according to our formal spec but
+ // are still supported
+ put("Alg.Alias.Signature.1.3.14.3.2.13", "DSA");
+ put("Alg.Alias.Signature.1.3.14.3.2.27", "DSA");
+ put("Alg.Alias.Signature.1.2.840.10040.4.3", "DSA");
+ put("Alg.Alias.Signature.SHAwithDSA", "DSA");
+ put("Alg.Alias.Signature.SHA1withDSA", "DSA");
+
+ /*
+ * Key Pair Generator engines
+ */
+ put("KeyPairGenerator.DSA",
+ "netscape.security.provider.DSAKeyPairGenerator");
+
+ put("Alg.Alias.KeyPairGenerator.OID.1.3.14.3.2.12", "DSA");
+ put("Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1", "DSA");
+ // the following are not according to our formal spec but
+ // are still supported
+ put("Alg.Alias.KeyPairGenerator.1.3.14.3.2.12", "DSA");
+ put("Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1", "DSA");
+
+ /*
+ * Digest engines
+ */
+ put("MessageDigest.MD5", "netscape.security.provider.MD5");
+ put("MessageDigest.SHA-1", "netscape.security.provider.SHA");
+
+ put("Alg.Alias.MessageDigest.SHA", "SHA-1");
+ put("Alg.Alias.MessageDigest.SHA1", "SHA-1");
+
+ /*
+ * Algorithm Parameter Generator engines
+ */
+ put("AlgorithmParameterGenerator.DSA",
+ "netscape.security.provider.DSAParameterGenerator");
+
+ /*
+ * Algorithm Parameter engines
+ */
+ put("AlgorithmParameters.DSA",
+ "netscape.security.provider.DSAParameters");
+ put("Alg.Alias.AlgorithmParameters.1.3.14.3.2.12", "DSA");
+ put("Alg.Alias.AlgorithmParameters.1.2.840.10040.4.1", "DSA");
+ /*
+ * Key factories
+ */
+ put("KeyFactory.DSA", "netscape.security.provider.DSAKeyFactory");
+
+ } finally {
+ // AccessController.endPrivileged();
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/provider/X509CertificateFactory.java b/base/util/src/netscape/security/provider/X509CertificateFactory.java
new file mode 100644
index 000000000..9780983a5
--- /dev/null
+++ b/base/util/src/netscape/security/provider/X509CertificateFactory.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 netscape.security.provider;
+
+import java.io.InputStream;
+import java.security.cert.CRL;
+import java.security.cert.CRLException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactorySpi;
+import java.util.Collection;
+
+import netscape.security.x509.X509CRLImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509ExtensionException;
+
+public class X509CertificateFactory extends CertificateFactorySpi {
+
+ public Certificate engineGenerateCertificate(InputStream inStream)
+ throws CertificateException {
+ return new X509CertImpl(inStream);
+ }
+
+ public Collection<Certificate> engineGenerateCertificates(InputStream inStream)
+ throws CertificateException {
+ return null;
+ }
+
+ public CRL engineGenerateCRL(InputStream inStream)
+ throws CRLException {
+ X509CRLImpl crl = null;
+ try {
+ crl = new X509CRLImpl(inStream);
+ } catch (X509ExtensionException e) {
+ ;
+ }
+
+ return crl;
+ }
+
+ public Collection<CRL> engineGenerateCRLs(InputStream inStream)
+ throws CRLException {
+ return null;
+ }
+
+}
diff --git a/base/util/src/netscape/security/util/ASN1CharStrConvMap.java b/base/util/src/netscape/security/util/ASN1CharStrConvMap.java
new file mode 100644
index 000000000..c9c364f4f
--- /dev/null
+++ b/base/util/src/netscape/security/util/ASN1CharStrConvMap.java
@@ -0,0 +1,168 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.util;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Maps a ASN.1 character string type to a charset encoder and decoder.
+ * The converter is used to convert a DerValue of a ASN.1 character string type
+ * from bytes to unicode characters and vice versa.
+ *
+ * <p>
+ * A global default ASN1CharStrConvMap is created when the class is initialized. The global default map is extensible.
+ *
+ * @author Lily Hsiao
+ * @author Slava Galperin
+ *
+ */
+
+public class ASN1CharStrConvMap {
+ // public constructors
+
+ /**
+ * Constructs a ASN1CharStrConvMap.
+ */
+ public ASN1CharStrConvMap() {
+ }
+
+ /**
+ * Get an encoder for the specified DER tag.
+ *
+ * @param tag A DER tag of a ASN.1 character string type,
+ * for example DerValue.tag_PrintableString.
+ *
+ * @return An encoder for the DER tag.
+ */
+ public CharsetEncoder getEncoder(byte tag) {
+ Charset charset = charsets.get(tag);
+ if (charset == null)
+ return null;
+ return charset.newEncoder();
+ }
+
+ /**
+ * Get a decoder for the given DER tag.
+ *
+ * @param tag A DER tag of a ASN.1 character string type,
+ * for example DerValue.tag_PrintableString.
+ *
+ * @return A decoder for the DER tag.
+ */
+ public CharsetDecoder getDecoder(byte tag) {
+ Charset charset = charsets.get(tag);
+ if (charset == null)
+ return null;
+ return charset.newDecoder();
+ }
+
+ /**
+ * Add a tag-charset entry in the map.
+ *
+ * @param tag A DER tag of a ASN.1 character string type,
+ * ex. DerValue.tag_IA5String
+ * @param charset A charset for the tag.
+ */
+ public void addEntry(byte tag, Charset charset) {
+
+ Charset currentCharset = charsets.get(tag);
+
+ if (currentCharset != null) {
+ if (currentCharset != charset) {
+ throw new IllegalArgumentException(
+ "a DER tag to converter entry already exists.");
+ } else {
+ return;
+ }
+ }
+
+ charsets.put(tag, charset);
+ }
+
+ /**
+ * Get an iterator of all tags in the map.
+ *
+ * @return An Iterator of DER tags in the map as Bytes.
+ */
+ public Iterator<Byte> getTags() {
+ return charsets.keySet().iterator();
+ }
+
+ // static public methods.
+
+ /**
+ * Get the global ASN1CharStrConvMap.
+ *
+ * @return The global default ASN1CharStrConvMap.
+ */
+ static public ASN1CharStrConvMap getDefault() {
+ return defaultMap;
+ }
+
+ /**
+ * Set the global default ASN1CharStrConvMap.
+ *
+ * @param newDefault The new default ASN1CharStrConvMap.
+ */
+ static public void setDefault(ASN1CharStrConvMap newDefault) {
+ if (newDefault == null)
+ throw new IllegalArgumentException(
+ "Cannot set a null default Der Tag Converter map");
+ defaultMap = newDefault;
+ }
+
+ // private methods and variables.
+
+ private Map<Byte, Charset> charsets = new HashMap<Byte, Charset>();
+
+ private static ASN1CharStrConvMap defaultMap;
+
+ /**
+ * Create the default converter map on initialization
+ */
+ static {
+ ASN1CharsetProvider provider = new ASN1CharsetProvider();
+
+ defaultMap = new ASN1CharStrConvMap();
+ defaultMap.addEntry(DerValue.tag_PrintableString,
+ provider.charsetForName("ASN.1-Printable"));
+ defaultMap.addEntry(DerValue.tag_VisibleString,
+ provider.charsetForName("ASN.1-Printable"));
+ defaultMap.addEntry(DerValue.tag_IA5String,
+ provider.charsetForName("ASN.1-IA5"));
+ defaultMap.addEntry(DerValue.tag_BMPString,
+ Charset.forName("UnicodeBig"));
+ defaultMap.addEntry(DerValue.tag_UniversalString,
+ provider.charsetForName("ASN.1-Universal"));
+ // XXX this is an oversimplified implementation of T.61 strings, it
+ // doesn't handle all cases
+ defaultMap.addEntry(DerValue.tag_T61String,
+ Charset.forName("ISO-8859-1"));
+ // UTF8String added to ASN.1 in 1998
+ defaultMap.addEntry(DerValue.tag_UTF8String,
+ Charset.forName("UTF-8"));
+ defaultMap.addEntry(DerValue.tag_GeneralString,
+ Charset.forName("UTF-8"));
+ };
+
+};
diff --git a/base/util/src/netscape/security/util/ASN1CharsetProvider.java b/base/util/src/netscape/security/util/ASN1CharsetProvider.java
new file mode 100644
index 000000000..1de1c3c48
--- /dev/null
+++ b/base/util/src/netscape/security/util/ASN1CharsetProvider.java
@@ -0,0 +1,30 @@
+package netscape.security.util;
+
+import java.nio.charset.Charset;
+import java.nio.charset.spi.CharsetProvider;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+public class ASN1CharsetProvider extends CharsetProvider {
+
+ protected Map<String, Charset> charsets = new HashMap<String, Charset>();
+
+ public ASN1CharsetProvider() {
+ addCharset(new PrintableCharset());
+ addCharset(new IA5Charset());
+ addCharset(new UniversalCharset());
+ }
+
+ public Iterator<Charset> charsets() {
+ return charsets.values().iterator();
+ }
+
+ public Charset charsetForName(String charsetName) {
+ return charsets.get(charsetName);
+ }
+
+ public void addCharset(Charset cs) {
+ charsets.put(cs.name(), cs);
+ }
+}
diff --git a/base/util/src/netscape/security/util/BigInt.java b/base/util/src/netscape/security/util/BigInt.java
new file mode 100644
index 000000000..9210648f1
--- /dev/null
+++ b/base/util/src/netscape/security/util/BigInt.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 netscape.security.util;
+
+import java.math.BigInteger;
+
+/**
+ * A low-overhead arbitrary-precision <em>unsigned</em> integer.
+ * This is intended for use with ASN.1 parsing, and printing of
+ * such parsed values. Convert to "BigInteger" if you need to do
+ * arbitrary precision arithmetic, rather than just represent
+ * the number as a wrapped array of bytes.
+ *
+ * <P>
+ * <em><b>NOTE:</b> This class may eventually disappear, to
+ * be supplanted by big-endian byte arrays which hold both signed
+ * and unsigned arbitrary-precision integers.
+ *
+ * @version 1.23
+ * @author David Brownell
+ */
+public final class BigInt {
+
+ // Big endian -- MSB first.
+ private byte[] places;
+
+ /**
+ * Constructs a "Big" integer from a set of (big-endian) bytes.
+ * Leading zeroes should be stripped off.
+ *
+ * @param data a sequence of bytes, most significant bytes/digits
+ * first. CONSUMED.
+ */
+ public BigInt(byte[] data) {
+ places = data.clone();
+ }
+
+ /**
+ * Constructs a "Big" integer from a "BigInteger", which must be
+ * positive (or zero) in value.
+ */
+ public BigInt(BigInteger i) {
+ byte[] temp = i.toByteArray();
+
+ if ((temp[0] & 0x80) != 0)
+ throw new IllegalArgumentException("negative BigInteger");
+
+ // XXX we assume exactly _one_ sign byte is used...
+
+ if (temp[0] != 0)
+ places = temp;
+ else {
+ // Note that if i = new BigInteger("0"),
+ // i.toByteArray() contains only 1 zero.
+ if (temp.length == 1) {
+ places = new byte[1];
+ places[0] = (byte) 0;
+ } else {
+ places = new byte[temp.length - 1];
+ for (int j = 1; j < temp.length; j++)
+ places[j - 1] = temp[j];
+ }
+ }
+ }
+
+ /**
+ * Constructs a "Big" integer from a normal Java integer.
+ *
+ * @param i the java primitive integer
+ */
+ public BigInt(int i) {
+ if (i < (1 << 8)) {
+ places = new byte[1];
+ places[0] = (byte) i;
+ } else if (i < (1 << 16)) {
+ places = new byte[2];
+ places[0] = (byte) (i >> 8);
+ places[1] = (byte) i;
+ } else if (i < (1 << 24)) {
+ places = new byte[3];
+ places[0] = (byte) (i >> 16);
+ places[1] = (byte) (i >> 8);
+ places[2] = (byte) i;
+ } else {
+ places = new byte[4];
+ places[0] = (byte) (i >> 24);
+ places[1] = (byte) (i >> 16);
+ places[2] = (byte) (i >> 8);
+ places[3] = (byte) i;
+ }
+ }
+
+ /**
+ * Converts the "big" integer to a java primitive integer.
+ *
+ * @exception NumberFormatException if 32 bits is insufficient.
+ */
+ public int toInt() {
+ if (places.length > 4)
+ throw new NumberFormatException("BigInt.toInt, too big");
+ int retval = 0, i = 0;
+ for (; i < places.length; i++)
+ retval = (retval << 8) + ((int) places[i] & 0xff);
+ return retval;
+ }
+
+ /**
+ * Returns a hexadecimal printed representation. The value is
+ * formatted to fit on lines of at least 75 characters, with
+ * embedded newlines. Words are separated for readability,
+ * with eight words (32 bytes) per line.
+ */
+ public String toString() {
+ return hexify();
+ }
+
+ /**
+ * Returns a BigInteger value which supports many arithmetic
+ * operations. Assumes negative values will never occur.
+ */
+ public BigInteger toBigInteger() {
+ return new BigInteger(1, places);
+ }
+
+ /**
+ * Returns the length of the data as a byte array.
+ */
+ public int byteLength() {
+ return places.length;
+ }
+
+ /**
+ * Returns the data as a byte array. The most significant bit
+ * of the array is bit zero (as in <code>java.math.BigInteger</code>).
+ */
+ public byte[] toByteArray() {
+ if (places.length == 0) {
+ byte zero[] = new byte[1];
+ zero[0] = (byte) 0;
+ return zero;
+ } else {
+ return places.clone();
+ }
+ }
+
+ private static final String digits = "0123456789abcdef";
+
+ private String hexify() {
+ if (places.length == 0)
+ return " 0 ";
+
+ StringBuffer buf = new StringBuffer(places.length * 2);
+ buf.append(" "); // four spaces
+ for (int i = 0; i < places.length; i++) {
+ buf.append(digits.charAt((places[i] >> 4) & 0x0f));
+ buf.append(digits.charAt(places[i] & 0x0f));
+ if (((i + 1) % 32) == 0) {
+ if ((i + 1) != places.length)
+ buf.append("\n "); // line after four words
+ } else if (((i + 1) % 4) == 0)
+ buf.append(' '); // space between words
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Returns true iff the parameter is a numerically equivalent
+ * BigInt.
+ *
+ * @param other the object being compared with this one.
+ */
+ public boolean equals(Object other) {
+ if (other instanceof BigInt)
+ return equals((BigInt) other);
+ return false;
+ }
+
+ /**
+ * Returns true iff the parameter is numerically equivalent.
+ *
+ * @param other the BigInt being compared with this one.
+ */
+ public boolean equals(BigInt other) {
+ if (this == other)
+ return true;
+
+ byte[] otherPlaces = other.toByteArray();
+ if (places.length != otherPlaces.length)
+ return false;
+ for (int i = 0; i < places.length; i++)
+ if (places[i] != otherPlaces[i])
+ return false;
+ return true;
+ }
+}
diff --git a/base/util/src/netscape/security/util/BitArray.java b/base/util/src/netscape/security/util/BitArray.java
new file mode 100644
index 000000000..ab77c226e
--- /dev/null
+++ b/base/util/src/netscape/security/util/BitArray.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 netscape.security.util;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * A packed array of booleans.
+ *
+ * @author Joshua Bloch
+ * @author Douglas Hoover
+ * @version 1.2 97/12/10
+ */
+
+public class BitArray {
+
+ private byte[] repn;
+ private int length;
+
+ private static final int BITS_PER_UNIT = 8;
+
+ private static int subscript(int idx) {
+ return idx / BITS_PER_UNIT;
+ }
+
+ private static int position(int idx) { // bits big-endian in each unit
+ return 1 << (BITS_PER_UNIT - 1 - (idx % BITS_PER_UNIT));
+ }
+
+ /**
+ * Creates a BitArray of the specified size, initialized to zeros.
+ */
+ public BitArray(int length) throws IllegalArgumentException {
+ if (length < 0) {
+ throw new IllegalArgumentException("Negative length for BitArray");
+ }
+
+ this.length = length;
+
+ repn = new byte[(length + BITS_PER_UNIT - 1) / BITS_PER_UNIT];
+ }
+
+ /**
+ * Creates a BitArray of the specified size, initialized from the
+ * specified byte array. The most significant bit of a[0] gets
+ * index zero in the BitArray. The array a must be large enough
+ * to specify a value for every bit in the BitArray. In other words,
+ * 8*a.length >= length.
+ */
+ public BitArray(int length, byte[] a) throws IllegalArgumentException {
+
+ if (length < 0) {
+ throw new IllegalArgumentException("Negative length for BitArray");
+ }
+ if (a.length * BITS_PER_UNIT < length) {
+ throw new IllegalArgumentException("Byte array too short to represent " +
+ "bit array of given length");
+ }
+
+ this.length = length;
+
+ int repLength = ((length + BITS_PER_UNIT - 1) / BITS_PER_UNIT);
+ int unusedBits = repLength * BITS_PER_UNIT - length;
+ byte bitMask = (byte) (0xFF << unusedBits);
+
+ /*
+ normalize the representation:
+ 1. discard extra bytes
+ 2. zero out extra bits in the last byte
+ */
+ repn = new byte[repLength];
+ System.arraycopy(a, 0, repn, 0, repLength);
+ if (repn.length > 0)
+ repn[repn.length - 1] = (byte) (repn[repn.length - 1] & bitMask);
+ }
+
+ /**
+ * Create a BitArray whose bits are those of the given array
+ * of Booleans.
+ */
+ public BitArray(boolean[] bits) {
+ length = bits.length;
+ repn = new byte[(length + 7) / 8];
+
+ for (int i = 0; i < length; i++) {
+ set(i, bits[i]);
+ }
+ }
+
+ /**
+ * Copy constructor (for cloning).
+ */
+ private BitArray(BitArray ba) {
+ length = ba.length;
+ repn = (byte[]) ba.repn.clone();
+ }
+
+ /**
+ * Returns the indexed bit in this BitArray.
+ */
+ public boolean get(int index) throws ArrayIndexOutOfBoundsException {
+ if (index < 0 || index >= length) {
+ throw new ArrayIndexOutOfBoundsException(Integer.toString(index));
+ }
+
+ return (repn[subscript(index)] & position(index)) != 0;
+ }
+
+ /**
+ * Sets the indexed bit in this BitArray.
+ */
+ public void set(int index, boolean value)
+ throws ArrayIndexOutOfBoundsException {
+ if (index < 0 || index >= length) {
+ throw new ArrayIndexOutOfBoundsException(Integer.toString(index));
+ }
+ int idx = subscript(index);
+ int bit = position(index);
+
+ if (value) {
+ repn[idx] |= bit;
+ } else {
+ repn[idx] &= ~bit;
+ }
+ }
+
+ /**
+ * Returns the length of this BitArray.
+ */
+ public int length() {
+ return length;
+ }
+
+ /**
+ * Returns a Byte array containing the contents of this BitArray.
+ * The bit stored at index zero in this BitArray will be copied
+ * into the most significant bit of the zeroth element of the
+ * returned byte array. The last byte of the returned byte array
+ * will be contain zeros in any bits that do not have corresponding
+ * bits in the BitArray. (This matters only if the BitArray's size
+ * is not a multiple of 8.)
+ */
+ public byte[] toByteArray() {
+ return (byte[]) repn.clone();
+ }
+
+ public boolean equals(Object obj) {
+ if (obj == this)
+ return true;
+ if (obj == null || !(obj instanceof BitArray))
+ return false;
+
+ BitArray ba = (BitArray) obj;
+
+ if (ba.length != length)
+ return false;
+
+ for (int i = 0; i < repn.length; i += 1) {
+ if (repn[i] != ba.repn[i])
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Return a boolean array with the same bit values a this BitArray.
+ */
+ public boolean[] toBooleanArray() {
+ boolean[] bits = new boolean[length];
+
+ for (int i = 0; i < length; i++) {
+ bits[i] = get(i);
+ }
+ return bits;
+ }
+
+ /**
+ * Returns a hash code value for this bit array.
+ *
+ * @return a hash code value for this bit array.
+ */
+ public int hashCode() {
+ int hashCode = 0;
+
+ for (int i = 0; i < repn.length; i++)
+ hashCode = 31 * hashCode + repn[i];
+
+ return hashCode ^ length;
+ }
+
+ public Object clone() {
+ return new BitArray(this);
+ }
+
+ private static final byte[][] NYBBLE = {
+ { (byte) '0', (byte) '0', (byte) '0', (byte) '0' },
+ { (byte) '0', (byte) '0', (byte) '0', (byte) '1' },
+ { (byte) '0', (byte) '0', (byte) '1', (byte) '0' },
+ { (byte) '0', (byte) '0', (byte) '1', (byte) '1' },
+ { (byte) '0', (byte) '1', (byte) '0', (byte) '0' },
+ { (byte) '0', (byte) '1', (byte) '0', (byte) '1' },
+ { (byte) '0', (byte) '1', (byte) '1', (byte) '0' },
+ { (byte) '0', (byte) '1', (byte) '1', (byte) '1' },
+ { (byte) '1', (byte) '0', (byte) '0', (byte) '0' },
+ { (byte) '1', (byte) '0', (byte) '0', (byte) '1' },
+ { (byte) '1', (byte) '0', (byte) '1', (byte) '0' },
+ { (byte) '1', (byte) '0', (byte) '1', (byte) '1' },
+ { (byte) '1', (byte) '1', (byte) '0', (byte) '0' },
+ { (byte) '1', (byte) '1', (byte) '0', (byte) '1' },
+ { (byte) '1', (byte) '1', (byte) '1', (byte) '0' },
+ { (byte) '1', (byte) '1', (byte) '1', (byte) '1' }
+ };
+
+ private static final int BYTES_PER_LINE = 8;
+
+ /**
+ * Returns a string representation of this BitArray.
+ */
+ public String toString() {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ for (int i = 0; i < repn.length - 1; i++) {
+ out.write(NYBBLE[(repn[i] >> 4) & 0x0F], 0, 4);
+ out.write(NYBBLE[repn[i] & 0x0F], 0, 4);
+
+ if (i % BYTES_PER_LINE == BYTES_PER_LINE - 1) {
+ out.write('\n');
+ } else {
+ out.write(' ');
+ }
+ }
+
+ // in last byte of repn, use only the valid bits
+ for (int i = BITS_PER_UNIT * (repn.length - 1); i < length; i++) {
+ out.write(get(i) ? '1' : '0');
+ }
+
+ return new String(out.toByteArray());
+
+ }
+
+}
diff --git a/base/util/src/netscape/security/util/ByteArrayLexOrder.java b/base/util/src/netscape/security/util/ByteArrayLexOrder.java
new file mode 100644
index 000000000..2ee2f740e
--- /dev/null
+++ b/base/util/src/netscape/security/util/ByteArrayLexOrder.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 netscape.security.util;
+
+import java.util.Comparator;
+
+/**
+ * Compare two byte arrays in lexicographical order.
+ *
+ * @version 1.4 97/12/10
+ * @author D. N. Hoover
+ */
+public class ByteArrayLexOrder implements Comparator<byte[]> {
+
+ /**
+ * Perform lexicographical comparison of two byte arrays,
+ * regarding each byte as unsigned. That is, compare array entries
+ * in order until they differ--the array with the smaller entry
+ * is "smaller". If array entries are
+ * equal till one array ends, then the longer array is "bigger".
+ *
+ * @param obj1 first byte array to compare.
+ * @param obj2 second byte array to compare.
+ * @return negative number if obj1 < obj2, 0 if obj1 == obj2,
+ * positive number if obj1 > obj2.
+ *
+ * @exception <code>ClassCastException</code> if either argument is not a byte array.
+ */
+ public final int compare(byte[] bytes1, byte[] bytes2) {
+
+ int diff;
+ for (int i = 0; i < bytes1.length && i < bytes2.length; i++) {
+ diff = (bytes1[i] & 0xFF) - (bytes2[i] & 0xFF);
+ if (diff != 0) {
+ return diff;
+ }
+ }
+ // if array entries are equal till the first ends, then the
+ // longer is "bigger"
+ return bytes1.length - bytes2.length;
+ }
+
+}
diff --git a/base/util/src/netscape/security/util/ByteArrayTagOrder.java b/base/util/src/netscape/security/util/ByteArrayTagOrder.java
new file mode 100644
index 000000000..e57a3b5f1
--- /dev/null
+++ b/base/util/src/netscape/security/util/ByteArrayTagOrder.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 netscape.security.util;
+
+import java.util.Comparator;
+
+public class ByteArrayTagOrder implements Comparator<byte[]> {
+
+ /**
+ * Compare two byte arrays, by the order of their tags,
+ * as defined in ITU-T X.680, sec. 6.4. (First compare
+ * tag classes, then tag numbers, ignoring the constructivity bit.)
+ *
+ * @param obj1 first byte array to compare.
+ * @param obj2 second byte array to compare.
+ * @return negative number if obj1 < obj2, 0 if obj1 == obj2,
+ * positive number if obj1 > obj2.
+ *
+ * @exception <code>ClassCastException</code> if either argument is not a byte array.
+ */
+
+ public final int compare(byte[] bytes1, byte[] bytes2) {
+
+ // tag order is same as byte order ignoring any difference in
+ // the constructivity bit (0x02)
+ return (bytes1[0] | 0x20) - (bytes2[0] | 0x20);
+ }
+
+}
diff --git a/base/util/src/netscape/security/util/CertPrettyPrint.java b/base/util/src/netscape/security/util/CertPrettyPrint.java
new file mode 100644
index 000000000..3a8c65fd0
--- /dev/null
+++ b/base/util/src/netscape/security/util/CertPrettyPrint.java
@@ -0,0 +1,345 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.util;
+
+import java.security.MessageDigest;
+import java.security.PublicKey;
+import java.security.cert.Certificate;
+import java.text.DateFormat;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.TimeZone;
+
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.Extension;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.pkcs7.ContentInfo;
+import org.mozilla.jss.pkcs7.SignedData;
+
+/**
+ * This class will display the certificate content in predefined
+ * format.
+ *
+ * @author Jack Pan-Chen
+ * @version $Revision$, $Date$
+ */
+public class CertPrettyPrint {
+
+ /*==========================================================
+ * constants
+ *==========================================================*/
+ private final static String CUSTOM_LOCALE = "Custom";
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private X509CertImpl mX509Cert = null;
+ private Certificate mCert = null;
+ private PrettyPrintFormat pp = null;
+ private byte[] mCert_b = null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ public CertPrettyPrint(Certificate cert) {
+ if (cert instanceof X509CertImpl)
+ mX509Cert = (X509CertImpl) cert;
+
+ pp = new PrettyPrintFormat(":");
+ }
+
+ public CertPrettyPrint(byte[] certb) {
+ mCert_b = certb;
+ pp = new PrettyPrintFormat(":");
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * This method return string representation of the certificate
+ * 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) {
+
+ if (mX509Cert != null)
+ return X509toString(clientLocale);
+ else if (mCert_b != null)
+ return pkcs7toString(clientLocale);
+ else
+ return null;
+ }
+
+ public String pkcs7toString(Locale clientLocale) {
+ String content = "";
+
+ try {
+ mX509Cert = new X509CertImpl(mCert_b);
+ return toString(clientLocale);
+ } catch (Exception e) {
+ }
+
+ ContentInfo ci = null;
+ try {
+ ci = (ContentInfo)
+ ASN1Util.decode(ContentInfo.getTemplate(), mCert_b);
+ } catch (Exception e) {
+ return "";
+ }
+
+ if (ci.getContentType().equals(ContentInfo.SIGNED_DATA)) {
+ SignedData sd = null;
+ try {
+ sd = (SignedData) ci.getInterpretedContent();
+ } catch (Exception e) {
+ return "";
+ }
+
+ if (sd.hasCertificates()) {
+ SET certs = sd.getCertificates();
+
+ for (int i = 0; i < certs.size(); i++) {
+ org.mozilla.jss.pkix.cert.Certificate cert =
+ (org.mozilla.jss.pkix.cert.Certificate) certs.elementAt(i);
+ X509CertImpl certImpl = null;
+ try {
+ certImpl = new X509CertImpl(
+ ASN1Util.encode(cert));
+ } catch (Exception e) {
+ }
+
+ CertPrettyPrint print = new CertPrettyPrint(certImpl);
+ content += print.toString(Locale.getDefault());
+ content += "\n";
+ }
+
+ return content;
+ }
+ }
+
+ return content;
+ }
+
+ public 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;
+ }
+
+ public 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 String X509toString(Locale clientLocale) {
+
+ //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 {
+ X509CertInfo info = (X509CertInfo) mX509Cert.get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+ String serial2 = mX509Cert.getSerialNumber().toString(16).toUpperCase();
+
+ //get correct instance of key
+ PublicKey pKey = mX509Cert.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;
+ }
+
+ //take care of spki
+ sb.append(pp.indent(4) + resource.getString(
+ PrettyPrintResources.TOKEN_CERTIFICATE) + "\n");
+ sb.append(pp.indent(8) + resource.getString(
+ PrettyPrintResources.TOKEN_DATA) + "\n");
+ sb.append(pp.indent(12) + resource.getString(
+ PrettyPrintResources.TOKEN_VERSION) + " v");
+ sb.append((mX509Cert.getVersion() + 1) + "\n");
+ sb.append(pp.indent(12) + resource.getString(
+ PrettyPrintResources.TOKEN_SERIAL) + "0x" + serial2 + "\n");
+ //XXX I18N Algorithm Name ?
+ sb.append(pp.indent(12) + resource.getString(
+ PrettyPrintResources.TOKEN_SIGALG) + mX509Cert.getSigAlgName() +
+ " - " + mX509Cert.getSigAlgOID() + "\n");
+ //XXX I18N IssuerDN ?
+ sb.append(pp.indent(12) + resource.getString(
+ PrettyPrintResources.TOKEN_ISSUER) +
+ mX509Cert.getIssuerDN().toString() + "\n");
+ sb.append(pp.indent(12) + resource.getString(
+ PrettyPrintResources.TOKEN_VALIDITY) + "\n");
+ String notBefore = dateFormater.format(mX509Cert.getNotBefore());
+ String notAfter = dateFormater.format(mX509Cert.getNotAfter());
+
+ //get timezone and timezone ID
+ if (TimeZone.getDefault() != null) {
+ tz = TimeZone.getDefault().getDisplayName(
+ TimeZone.getDefault().inDaylightTime(
+ mX509Cert.getNotBefore()),
+ TimeZone.SHORT,
+ clientLocale);
+ tzid = TimeZone.getDefault().getID();
+ }
+ // Specify notBefore
+ if (tz.equals(tzid) || tzid.equals(CUSTOM_LOCALE)) {
+ // Do NOT append timezone ID
+ sb.append(pp.indent(16)
+ + resource.getString(
+ PrettyPrintResources.TOKEN_NOT_BEFORE)
+ + notBefore
+ + "\n");
+ } else {
+ // Append timezone ID
+ sb.append(pp.indent(16)
+ + resource.getString(
+ PrettyPrintResources.TOKEN_NOT_BEFORE)
+ + notBefore
+ + " " + tzid + "\n");
+ }
+ // re-get timezone (just in case it is different . . .)
+ if (TimeZone.getDefault() != null) {
+ tz = TimeZone.getDefault().getDisplayName(
+ TimeZone.getDefault().inDaylightTime(
+ mX509Cert.getNotAfter()),
+ TimeZone.SHORT,
+ clientLocale);
+ }
+ // Specify notAfter
+ if (tz.equals(tzid) || tzid.equals(CUSTOM_LOCALE)) {
+ // Do NOT append timezone ID
+ sb.append(pp.indent(16)
+ + resource.getString(
+ PrettyPrintResources.TOKEN_NOT_AFTER)
+ + notAfter
+ + "\n");
+ } else {
+ // Append timezone ID
+ sb.append(pp.indent(16)
+ + resource.getString(
+ PrettyPrintResources.TOKEN_NOT_AFTER)
+ + notAfter
+ + " " + tzid + "\n");
+ }
+ //XXX I18N SubjectDN ?
+ sb.append(pp.indent(12) + resource.getString(
+ PrettyPrintResources.TOKEN_SUBJECT) +
+ mX509Cert.getSubjectDN().toString() + "\n");
+ sb.append(pp.indent(12) + resource.getString(
+ PrettyPrintResources.TOKEN_SPKI) + "\n");
+
+ PubKeyPrettyPrint pkpp = new PubKeyPrettyPrint(key);
+
+ sb.append(pkpp.toString(clientLocale, 16, 16));
+
+ //take care of extensions
+ CertificateExtensions extensions = (CertificateExtensions)
+ info.get(X509CertInfo.EXTENSIONS);
+
+ sb.append(pp.indent(12) + resource.getString(
+ PrettyPrintResources.TOKEN_EXTENSIONS) + "\n");
+ if (extensions != null)
+ for (int i = 0; i < extensions.size(); i++) {
+ Extension ext = (Extension) extensions.elementAt(i);
+ ExtPrettyPrint extpp = new ExtPrettyPrint(ext, 16);
+
+ sb.append(extpp.toString());
+ }
+
+ //take care of signature
+ sb.append(pp.indent(8) + resource.getString(
+ PrettyPrintResources.TOKEN_SIGNATURE) + "\n");
+ //XXX I18N Algorithm Name ?
+ sb.append(pp.indent(12) + resource.getString(
+ PrettyPrintResources.TOKEN_ALGORITHM) +
+ mX509Cert.getSigAlgName() + " - " + mX509Cert.getSigAlgOID() + "\n");
+ sb.append(pp.indent(12) + resource.getString(
+ PrettyPrintResources.TOKEN_SIGNATURE) + "\n");
+ sb.append(pp.toHexString(mX509Cert.getSignature(), 16, 16));
+
+ // fingerprints
+ String[] hashes = new String[] { "MD2", "MD5", "SHA1", "SHA256", "SHA512" };
+ String certFingerprints = "";
+
+ sb.append(pp.indent(8) + "FingerPrint\n");
+ for (int i = 0; i < hashes.length; i++) {
+ MessageDigest md = MessageDigest.getInstance(hashes[i]);
+
+ md.update(mX509Cert.getEncoded());
+ certFingerprints += pp.indent(12) + hashes[i] + ":\n" +
+ pp.toHexString(md.digest(), 16, 16);
+ }
+
+ sb.append(certFingerprints);
+ } catch (Exception e) {
+ }
+
+ return sb.toString();
+ }
+
+}
diff --git a/base/util/src/netscape/security/util/CrlPrettyPrint.java b/base/util/src/netscape/security/util/CrlPrettyPrint.java
new file mode 100644
index 000000000..edf1217ea
--- /dev/null
+++ b/base/util/src/netscape/security/util/CrlPrettyPrint.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 netscape.security.util;
+
+import java.text.DateFormat;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.TimeZone;
+
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.RevokedCertificate;
+import netscape.security.x509.X509CRLImpl;
+
+/**
+ * This class will display the certificate content in predefined
+ * format.
+ *
+ * @author Andrew Wnuk
+ * @version $Revision$, $Date$
+ */
+public class CrlPrettyPrint {
+
+ /*==========================================================
+ * constants
+ *==========================================================*/
+ private final static String CUSTOM_LOCALE = "Custom";
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private X509CRLImpl mCRL = null;
+ private PrettyPrintFormat pp = null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ public CrlPrettyPrint(X509CRLImpl crl) {
+ mCRL = crl;
+ 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");
+ sb.append(pp.indent(12) + resource.getString(
+ PrettyPrintResources.TOKEN_VERSION) + " v");
+ sb.append((mCRL.getVersion() + 1) + "\n");
+ sb.append(pp.indent(12) + resource.getString(
+ PrettyPrintResources.TOKEN_SIGALG) + mCRL.getSigAlgName() +
+ " - " + mCRL.getSigAlgOID() + "\n");
+ sb.append(pp.indent(12) + resource.getString(
+ PrettyPrintResources.TOKEN_ISSUER) +
+ mCRL.getIssuerDN().toString() + "\n");
+ // Format thisUpdate
+ String thisUpdate = dateFormater.format(mCRL.getThisUpdate());
+
+ // get timezone and timezone ID
+ if (TimeZone.getDefault() != null) {
+ tz = TimeZone.getDefault().getDisplayName(
+ TimeZone.getDefault().inDaylightTime(
+ mCRL.getThisUpdate()),
+ 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 (mCRL.getNextUpdate() != null) {
+ // Format nextUpdate
+ String nextUpdate = dateFormater.format(mCRL.getNextUpdate());
+
+ // re-get timezone (just in case it is different . . .)
+ if (TimeZone.getDefault() != null) {
+ tz = TimeZone.getDefault().getDisplayName(
+ TimeZone.getDefault().inDaylightTime(
+ mCRL.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));
+ if (crlSize > 0 && pageStart > 0 && pageSize > 0) {
+ long upperLimit = (pageStart + pageSize - 1 > crlSize) ? crlSize : pageStart + pageSize - 1;
+
+ sb.append("" + pageStart + "-" + upperLimit + " of " + crlSize);
+ }
+ sb.append("\n");
+
+ Set<RevokedCertificate> revokedCerts = mCRL.getRevokedCertificates();
+
+ if (revokedCerts != null) {
+ Iterator<RevokedCertificate> i = revokedCerts.iterator();
+ long l = 1;
+
+ while ((i.hasNext()) && ((crlSize == 0) || (pageStart + pageSize > l))) {
+ RevokedCertificate revokedCert = i.next();
+
+ if ((crlSize == 0) || ((pageStart <= l) && (pageStart + pageSize > 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++;
+ }
+ }
+ }
+
+ CRLExtensions crlExtensions = mCRL.getExtensions();
+
+ if (crlExtensions != null) {
+ sb.append(pp.indent(8) + resource.getString(
+ PrettyPrintResources.TOKEN_EXTENSIONS) + "\n");
+ for (int k = 0; k < crlExtensions.size(); k++) {
+ Extension ext = (Extension) crlExtensions.elementAt(k);
+ ExtPrettyPrint extpp = new ExtPrettyPrint(ext, 12);
+
+ sb.append(extpp.toString());
+ }
+ }
+
+ //take care of signature
+ sb.append(pp.indent(8) + resource.getString(
+ PrettyPrintResources.TOKEN_SIGNATURE) + "\n");
+ //XXX I18N Algorithm Name ?
+ sb.append(pp.indent(12) + resource.getString(
+ PrettyPrintResources.TOKEN_ALGORITHM) +
+ mCRL.getSigAlgName() + " - " + mCRL.getSigAlgOID() + "\n");
+ sb.append(pp.indent(12) + resource.getString(
+ PrettyPrintResources.TOKEN_SIGNATURE) + "\n");
+ sb.append(pp.toHexString(mCRL.getSignature(), 16, 16));
+
+ } catch (Exception e) {
+ sb.append("\n\n" + pp.indent(4) + resource.getString(
+ PrettyPrintResources.TOKEN_DECODING_ERROR) + "\n\n");
+ e.printStackTrace();
+ }
+
+ return sb.toString();
+ }
+}
diff --git a/base/util/src/netscape/security/util/DerEncoder.java b/base/util/src/netscape/security/util/DerEncoder.java
new file mode 100644
index 000000000..c2eb64fc0
--- /dev/null
+++ b/base/util/src/netscape/security/util/DerEncoder.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 netscape.security.util;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Interface to an object that knows how to write its own DER
+ * encoding to an output stream.
+ *
+ * @version 1.2 97/12/10
+ * @author D. N. Hoover
+ */
+public interface DerEncoder {
+
+ /**
+ * DER encode this object and write the results to a stream.
+ *
+ * @param out the stream on which the DER encoding is written.
+ */
+ public void derEncode(OutputStream out)
+ throws IOException;
+
+}
diff --git a/base/util/src/netscape/security/util/DerInputBuffer.java b/base/util/src/netscape/security/util/DerInputBuffer.java
new file mode 100644
index 000000000..7534f3d06
--- /dev/null
+++ b/base/util/src/netscape/security/util/DerInputBuffer.java
@@ -0,0 +1,186 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * DER input buffer ... this is the main abstraction in the DER library
+ * which actively works with the "untyped byte stream" abstraction. It
+ * does so with impunity, since it's not intended to be exposed to the
+ * anyone who could violate the "typed value stream" DER model and hence
+ * corrupt the input stream of DER values.
+ *
+ * @version 1.11
+ * @author David Brownell
+ */
+class DerInputBuffer extends ByteArrayInputStream implements Cloneable {
+
+ DerInputBuffer(byte[] buf) {
+ super(buf);
+ }
+
+ DerInputBuffer(byte[] buf, int offset, int len) {
+ super(buf, offset, len);
+ }
+
+ DerInputBuffer dup() {
+ try {
+ DerInputBuffer retval = (DerInputBuffer) clone();
+
+ retval.mark(Integer.MAX_VALUE);
+ return retval;
+ } catch (CloneNotSupportedException e) {
+ throw new IllegalArgumentException(e.toString());
+ }
+ }
+
+ byte[] toByteArray() {
+ int len = available();
+ if (len <= 0)
+ return null;
+ byte[] retval = new byte[len];
+
+ System.arraycopy(buf, pos, retval, 0, len);
+ return retval;
+ }
+
+ int peek() throws IOException {
+ if (pos >= count)
+ throw new IOException("out of data");
+ else
+ return buf[pos];
+ }
+
+ /**
+ * Compares this DerInputBuffer for equality with the specified
+ * object.
+ */
+ public boolean equals(Object other) {
+ if (other instanceof DerInputBuffer)
+ return equals((DerInputBuffer) other);
+ else
+ return false;
+ }
+
+ boolean equals(DerInputBuffer other) {
+ if (this == other)
+ return true;
+
+ int max = this.available();
+ if (other.available() != max)
+ return false;
+ for (int i = 0; i < max; i++) {
+ if (this.buf[this.pos + i] != other.buf[other.pos + i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ void truncate(int len) throws IOException {
+ if (len > available())
+ throw new IOException("insufficient data");
+ count = pos + len;
+ }
+
+ /**
+ * Returns the unsigned integer which takes up the specified number
+ * of bytes in this buffer.
+ */
+ BigInt getUnsigned(int len) throws IOException {
+ if (len > available())
+ throw new IOException("short read, getInteger");
+
+ /*
+ * A prepended zero is used to ensure that the integer is
+ * interpreted as unsigned even when the high order bit is
+ * zero. We don't support signed BigInts.
+ *
+ * Fix this here ... BigInts aren't expected to have these,
+ * and stuff like signing (sigsize = f(modulus)) misbehaves.
+ */
+ if (len > 1 && buf[pos] == 0) {
+ len--;
+ skip(1);
+ }
+
+ /*
+ * Consume the rest of the buffer, returning its value as
+ * an unsigned integer.
+ */
+ byte[] bytes = new byte[len];
+
+ System.arraycopy(buf, pos, bytes, 0, len);
+ skip(len);
+ return new BigInt(bytes);
+ }
+
+ /**
+ * Returns the bit string which takes up the rest of this buffer.
+ * This bit string must be byte-aligned.
+ */
+ byte[] getBitString() {
+ if (pos >= count || buf[pos] != 0)
+ return null;
+ /*
+ * Just copy the data into an aligned, padded octet buffer,
+ * and consume the rest of the buffer.
+ */
+ int len = available();
+ byte[] retval = new byte[len - 1];
+
+ System.arraycopy(buf, pos + 1, retval, 0, len - 1);
+ pos = count;
+ return retval;
+ }
+
+ /**
+ * Returns the bit string which takes up the rest of this buffer.
+ * The bit string need not be byte-aligned.
+ */
+ BitArray getUnalignedBitString() {
+ if (pos >= count)
+ return null;
+ /*
+ * Just copy the data into an aligned, padded octet buffer,
+ * and consume the rest of the buffer.
+ */
+ int len = available();
+ byte[] bits = new byte[len - 1];
+ int length = bits.length * 8 - buf[pos]; // number of valid bits
+
+ System.arraycopy(buf, pos + 1, bits, 0, len - 1);
+
+ BitArray bitArray = new BitArray(length, bits);
+ pos = count;
+ return bitArray;
+ }
+
+ /**
+ * Package-access method to optimize output operations
+ */
+ void dump(OutputStream out, int length) throws IOException {
+ if (count < mark + length)
+ throw new IOException("short DER value (encode)");
+ out.write(buf, mark, length);
+ }
+
+}
diff --git a/base/util/src/netscape/security/util/DerInputStream.java b/base/util/src/netscape/security/util/DerInputStream.java
new file mode 100644
index 000000000..20ced6757
--- /dev/null
+++ b/base/util/src/netscape/security/util/DerInputStream.java
@@ -0,0 +1,662 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+import java.util.Vector;
+
+/**
+ * A DER input stream, used for parsing ASN.1 DER-encoded data such as
+ * that found in X.509 certificates. DER is a subset of BER/1, which has
+ * the advantage that it allows only a single encoding of primitive data.
+ * (High level data such as dates still support many encodings.) That is,
+ * it uses the "Definite" Encoding Rules (DER) not the "Basic" ones (BER).
+ *
+ * <P>
+ * Note that, like BER/1, DER streams are streams of explicitly tagged data values. Accordingly, this programming
+ * interface does not expose any variant of the java.io.InputStream interface, since that kind of input stream holds
+ * untagged data values and using that I/O model could prevent correct parsing of the DER data.
+ *
+ * <P>
+ * At this time, this class supports only a subset of the types of DER data encodings which are defined. That subset is
+ * sufficient for parsing most X.509 certificates.
+ *
+ * @version 1.35
+ *
+ * @author David Brownell
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ */
+public class DerInputStream {
+ /*
+ * This version only supports fully buffered DER. This is easy to
+ * work with, though if large objects are manipulated DER becomes
+ * awkward to deal with. That's where BER is useful, since BER
+ * handles streaming data relatively well.
+ */
+ DerInputBuffer buffer;
+
+ /**
+ * Create a DER input stream from a data buffer. The buffer is not
+ * copied, it is shared. Accordingly, the buffer should be treated
+ * as read-only.
+ *
+ * @param data the buffer from which to create the string (CONSUMED)
+ */
+ public DerInputStream(byte[] data) {
+ buffer = new DerInputBuffer(data);
+ buffer.mark(Integer.MAX_VALUE);
+ }
+
+ /**
+ * Create a DER input stream from part of a data buffer.
+ * The buffer is not copied, it is shared. Accordingly, the
+ * buffer should be treated as read-only.
+ *
+ * @param data the buffer from which to create the string (CONSUMED)
+ * @param offset the first index of <em>data</em> which will
+ * be read as DER input in the new stream
+ * @param len how long a chunk of the buffer to use,
+ * starting at "offset"
+ */
+ public DerInputStream(byte[] data, int offset, int len) {
+ buffer = new DerInputBuffer(data, offset, len);
+ buffer.mark(Integer.MAX_VALUE);
+ }
+
+ DerInputStream(DerInputBuffer buf) {
+ buffer = buf;
+ buffer.mark(Integer.MAX_VALUE);
+ }
+
+ /**
+ * Creates a new DER input stream from part of this input stream.
+ *
+ * @param len how long a chunk of the current input stream to use,
+ * starting at the current position.
+ * @param do_skip true if the existing data in the input stream should
+ * be skipped. If this value is false, the next data read
+ * on this stream and the newly created stream will be the
+ * same.
+ */
+ public DerInputStream subStream(int len, boolean do_skip)
+ throws IOException {
+ DerInputBuffer newbuf = buffer.dup();
+
+ newbuf.truncate(len);
+ if (do_skip)
+ buffer.skip(len);
+ return new DerInputStream(newbuf);
+ }
+
+ /**
+ * Return what has been written to this DerInputStream
+ * as a byte array. Useful for debugging.
+ */
+ public byte[] toByteArray() {
+ return buffer.toByteArray();
+ }
+
+ /*
+ * PRIMITIVES -- these are "universal" ASN.1 simple types.
+ *
+ * INTEGER, BIT STRING, OCTET STRING, NULL
+ * OBJECT IDENTIFIER, SEQUENCE (OF), SET (OF)
+ * PrintableString, T61String, IA5String, UTCTime
+ */
+
+ /**
+ * Get an (unsigned) integer from the input stream.
+ */
+ public BigInt getInteger() throws IOException {
+ if (buffer.read() != DerValue.tag_Integer)
+ throw new IOException("DER input, Integer tag error");
+
+ return buffer.getUnsigned(getLength(buffer));
+ }
+
+ /**
+ * Get a bit string from the input stream. Only octet-aligned
+ * bitstrings (multiples of eight bits in length) are handled
+ * by this method.
+ */
+ public byte[] getBitString() throws IOException {
+ if (buffer.read() != DerValue.tag_BitString)
+ throw new IOException("DER input not an bit string");
+ int length = getLength(buffer);
+
+ /*
+ * This byte affects alignment and padding (for the last byte).
+ * Use getUnalignedBitString() for none 8-bit aligned bit strings.
+ */
+ if (buffer.read() != 0)
+ return null;
+ length--;
+
+ /*
+ * Just read the data into an aligned, padded octet buffer.
+ */
+ byte[] retval = new byte[length];
+ if (buffer.read(retval) != length)
+ throw new IOException("short read of DER bit string");
+ return retval;
+ }
+
+ /**
+ * Get a bit string from the input stream. The bit string need
+ * not be byte-aligned.
+ */
+ public BitArray getUnalignedBitString() throws IOException {
+ if (buffer.read() != DerValue.tag_BitString)
+ throw new IOException("DER input not a bit string");
+
+ int length = getLength(buffer) - 1;
+
+ /*
+ * First byte = number of excess bits in the last octet of the
+ * representation.
+ */
+ int validBits = length * 8 - buffer.read();
+
+ byte[] repn = new byte[length];
+
+ if (buffer.read(repn) != length)
+ throw new IOException("short read of DER bit string");
+ return new BitArray(validBits, repn);
+ }
+
+ /**
+ * Returns an ASN.1 OCTET STRING from the input stream.
+ */
+ public byte[] getOctetString() throws IOException {
+ if (buffer.read() != DerValue.tag_OctetString)
+ throw new IOException("DER input not an octet string");
+
+ int length = getLength(buffer);
+ byte[] retval = new byte[length];
+ if (buffer.read(retval) != length)
+ throw new IOException("short read of DER octet string");
+
+ return retval;
+ }
+
+ /**
+ * Returns the asked number of bytes from the input stream.
+ */
+ public void getBytes(byte[] val) throws IOException {
+ if (val.length != 0) {
+ if (buffer.read(val) != val.length) {
+ throw new IOException("short read of DER octet string");
+ }
+ }
+ }
+
+ /**
+ * Reads an encoded null value from the input stream.
+ */
+ public void getNull() throws IOException {
+ if (buffer.read() != DerValue.tag_Null || buffer.read() != 0)
+ throw new IOException("getNull, bad data");
+ }
+
+ /**
+ * Reads an X.200 style Object Identifier from the stream.
+ */
+ public ObjectIdentifier getOID() throws IOException {
+ return new ObjectIdentifier(this);
+ }
+
+ /**
+ * Return a sequence of encoded entities. ASN.1 sequences are
+ * ordered, and they are often used, like a "struct" in C or C++,
+ * to group data values. They may have optional or context
+ * specific values.
+ *
+ * @param startLen guess about how long the sequence will be
+ * (used to initialize an auto-growing data structure)
+ * @return array of the values in the sequence
+ */
+ public DerValue[] getSequence(int startLen) throws IOException {
+ int b = buffer.read();
+ if (b != DerValue.tag_Sequence)
+ throw new IOException("Sequence tag error " + b);
+ return readVector(startLen);
+ }
+
+ public void skipSequence(int startLen) throws IOException {
+ int b = buffer.read();
+ if (b != DerValue.tag_Sequence)
+ throw new IOException("Sequence tag error " + b);
+ int len = getLength(buffer);
+ buffer.skip(len);
+ }
+
+ /**
+ * Return a set of encoded entities. ASN.1 sets are unordered,
+ * though DER may specify an order for some kinds of sets (such
+ * as the attributes in an X.500 relative distinguished name)
+ * to facilitate binary comparisons of encoded values.
+ *
+ * @param startLen guess about how large the set will be
+ * (used to initialize an auto-growing data structure)
+ * @return array of the values in the sequence
+ */
+ public DerValue[] getSet(int startLen) throws IOException {
+ if (buffer.read() != DerValue.tag_Set)
+ throw new IOException("Set tag error");
+ return readVector(startLen);
+ }
+
+ /**
+ * Return a set of encoded entities. ASN.1 sets are unordered,
+ * though DER may specify an order for some kinds of sets (such
+ * as the attributes in an X.500 relative distinguished name)
+ * to facilitate binary comparisons of encoded values.
+ *
+ * @param startLen guess about how large the set will be
+ * (used to initialize an auto-growing data structure)
+ * @param implicit if true tag is assumed implicit.
+ * @return array of the values in the sequence
+ */
+ public DerValue[] getSet(int startLen, boolean implicit) throws IOException {
+ int tag = buffer.read();
+ if (!implicit) {
+ if (tag != DerValue.tag_Set) {
+ throw new IOException("Set tag error");
+ }
+ }
+ return (readVector(startLen));
+ }
+
+ /*
+ * Read a "vector" of values ... set or sequence have the
+ * same encoding, except for the initial tag, so both use
+ * this same helper routine.
+ */
+ protected DerValue[] readVector(int startLen) throws IOException {
+ int len = getLength(buffer);
+ DerInputStream newstr;
+
+ if (len == 0)
+ // return empty array instead of null, which should be
+ // used only for missing optionals
+ return new DerValue[0];
+
+ /*
+ * Create a temporary stream from which to read the data,
+ * unless it's not really needed.
+ */
+ if (buffer.available() == len)
+ newstr = this;
+ else
+ newstr = subStream(len, true);
+
+ /*
+ * Pull values out of the stream.
+ */
+ Vector<DerValue> vec = new Vector<DerValue>(startLen);
+ DerValue value;
+
+ do {
+ value = new DerValue(newstr.buffer);
+ vec.addElement(value);
+ } while (newstr.available() > 0);
+
+ if (newstr.available() != 0)
+ throw new IOException("extra data at end of vector");
+
+ /*
+ * Now stick them into the array we're returning.
+ */
+ int i, max = vec.size();
+ DerValue[] retval = new DerValue[max];
+
+ for (i = 0; i < max; i++)
+ retval[i] = (DerValue) vec.elementAt(i);
+
+ return retval;
+ }
+
+ /**
+ * Get a single DER-encoded value from the input stream.
+ * It can often be useful to pull a value from the stream
+ * and defer parsing it. For example, you can pull a nested
+ * sequence out with one call, and only examine its elements
+ * later when you really need to.
+ */
+ public DerValue getDerValue() throws IOException {
+ return new DerValue(buffer);
+ }
+
+ public String getPrintableString() throws IOException {
+ return (new DerValue(buffer)).getPrintableString();
+ }
+
+ public String getT61String() throws IOException {
+ return (new DerValue(buffer)).getT61String();
+ }
+
+ public String getIA5String() throws IOException {
+ return (new DerValue(buffer)).getIA5String();
+ }
+
+ public String getBMPString() throws IOException {
+ return (new DerValue(buffer)).getBMPString();
+ }
+
+ public String getUniversalString() throws IOException {
+ return (new DerValue(buffer)).getUniversalString();
+ }
+
+ /**
+ * Get a UTC encoded time value from the input stream.
+ */
+ public Date getUTCTime() throws IOException {
+ if (buffer.read() != DerValue.tag_UtcTime)
+ throw new IOException("DER input, UTCtime tag invalid ");
+ if (buffer.available() < 11)
+ throw new IOException("DER input, UTCtime short input");
+
+ int len = getLength(buffer);
+
+ if (len < 11 || len > 17)
+ throw new IOException("DER getUTCTime length error");
+
+ /*
+ * UTC time encoded as ASCII chars, YYMMDDhhmmss.
+ * If YY <= 50, we assume 20YY;
+ * if YY > 50, we assume 19YY, as per IETF-PKIX part I.
+ */
+ int year, month, day, hour, minute, second;
+
+ year = 10 * Character.digit((char) buffer.read(), 10);
+ year += Character.digit((char) buffer.read(), 10);
+ if (year <= 50) // origin 2000
+ year += 2000;
+ else
+ year += 1900; // origin 1900
+
+ month = 10 * Character.digit((char) buffer.read(), 10);
+ month += Character.digit((char) buffer.read(), 10);
+ month -= 1; // months are 0-11
+
+ day = 10 * Character.digit((char) buffer.read(), 10);
+ day += Character.digit((char) buffer.read(), 10);
+
+ hour = 10 * Character.digit((char) buffer.read(), 10);
+ hour += Character.digit((char) buffer.read(), 10);
+
+ minute = 10 * Character.digit((char) buffer.read(), 10);
+ minute += Character.digit((char) buffer.read(), 10);
+
+ len -= 10;
+
+ /**
+ * We allow for non-encoded seconds, even though the
+ * IETF-PKIX specification says that the seconds should
+ * always be encoded even if it is zero.
+ */
+
+ if (len == 3 || len == 7) {
+ second = 10 * Character.digit((char) buffer.read(), 10);
+ second += Character.digit((char) buffer.read(), 10);
+ len -= 2;
+ } else
+ second = 0;
+
+ if (month < 0 || day <= 0
+ || month > 11 || day > 31 || hour >= 24
+ || minute >= 60 || second >= 60)
+ throw new IOException("Parse UTC time, invalid format");
+
+ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+ cal.set(year, month, day, hour, minute, second);
+ cal.set(Calendar.MILLISECOND, 0); /* To clear millisecond field */
+ cal.set(Calendar.ERA, GregorianCalendar.AD);
+ Date readDate = cal.getTime();
+ long utcTime = readDate.getTime();
+
+ /*
+ * Finally, "Z" or "+hhmm" or "-hhmm" ... offsets change hhmm
+ */
+ if (!(len == 1 || len == 5))
+ throw new IOException("Parse UTC time, invalid offset");
+
+ switch (buffer.read()) {
+ case '+': {
+ int Htmp = 10 * Character.digit((char) buffer.read(), 10);
+ Htmp += Character.digit((char) buffer.read(), 10);
+ int Mtmp = 10 * Character.digit((char) buffer.read(), 10);
+ Mtmp += Character.digit((char) buffer.read(), 10);
+
+ if (Htmp >= 24 || Mtmp >= 60)
+ throw new IOException("Parse UTCtime, +hhmm");
+
+ utcTime += ((Htmp * 60) + Mtmp) * 60 * 1000;
+ }
+ break;
+
+ case '-': {
+ int Htmp = 10 * Character.digit((char) buffer.read(), 10);
+ Htmp += Character.digit((char) buffer.read(), 10);
+ int Mtmp = 10 * Character.digit((char) buffer.read(), 10);
+ Mtmp += Character.digit((char) buffer.read(), 10);
+
+ if (Htmp >= 24 || Mtmp >= 60)
+ throw new IOException("Parse UTCtime, -hhmm");
+
+ utcTime -= ((Htmp * 60) + Mtmp) * 60 * 1000;
+ }
+ break;
+
+ case 'Z':
+ break;
+
+ default:
+ throw new IOException("Parse UTCtime, garbage offset");
+ }
+ readDate.setTime(utcTime);
+ return readDate;
+ }
+
+ /**
+ * Get a Generalized encoded time value from the input stream.
+ */
+ public Date getGeneralizedTime() throws IOException {
+ if (buffer.read() != DerValue.tag_GeneralizedTime)
+ throw new IOException("DER input, GeneralizedTime tag invalid ");
+
+ if (buffer.available() < 13)
+ throw new IOException("DER input, GeneralizedTime short input");
+
+ int len = getLength(buffer);
+
+ /*
+ * Generalized time encoded as ASCII chars, YYYYMMDDhhmm[ss]
+ */
+ int year, month, day, hour, minute, second;
+
+ year = 1000 * Character.digit((char) buffer.read(), 10);
+ year += 100 * Character.digit((char) buffer.read(), 10);
+ year += 10 * Character.digit((char) buffer.read(), 10);
+ year += Character.digit((char) buffer.read(), 10);
+
+ month = 10 * Character.digit((char) buffer.read(), 10);
+ month += Character.digit((char) buffer.read(), 10);
+ month -= 1; // Calendar months are 0-11
+
+ day = 10 * Character.digit((char) buffer.read(), 10);
+ day += Character.digit((char) buffer.read(), 10);
+
+ hour = 10 * Character.digit((char) buffer.read(), 10);
+ hour += Character.digit((char) buffer.read(), 10);
+
+ minute = 10 * Character.digit((char) buffer.read(), 10);
+ minute += Character.digit((char) buffer.read(), 10);
+
+ len -= 12;
+
+ /**
+ * We allow for non-encoded seconds, even though the
+ * IETF-PKIX specification says that the seconds should
+ * always be encoded even if it is zero.
+ */
+
+ if (len == 3 || len == 7) {
+ second = 10 * Character.digit((char) buffer.read(), 10);
+ second += Character.digit((char) buffer.read(), 10);
+ len -= 2;
+ } else
+ second = 0;
+
+ if (month < 0 || day <= 0
+ || month > 11 || day > 31 || hour >= 24
+ || minute >= 60 || second >= 60)
+ throw new IOException("Parse Generalized time, invalid format");
+
+ /* Shouldn't this construct a Gregorian calendar directly???
+ * We don't really want locale dependant processing here */
+ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+ cal.set(year, month, day, hour, minute, second);
+ cal.set(Calendar.MILLISECOND, 0); /* To clear millisecond field */
+ cal.set(Calendar.ERA, GregorianCalendar.AD);
+ Date readDate = cal.getTime();
+ long utcTime = readDate.getTime();
+
+ /*
+ * Finally, "Z" or "+hhmm" or "-hhmm" ... offsets change hhmm
+ */
+ if (!(len == 1 || len == 5))
+ throw new IOException("Parse Generalized time, invalid offset");
+
+ switch (buffer.read()) {
+ case '+': {
+ int Htmp = 10 * Character.digit((char) buffer.read(), 10);
+ Htmp += Character.digit((char) buffer.read(), 10);
+ int Mtmp = 10 * Character.digit((char) buffer.read(), 10);
+ Mtmp += Character.digit((char) buffer.read(), 10);
+
+ if (Htmp >= 24 || Mtmp >= 60)
+ throw new IOException("Parse GeneralizedTime, +hhmm");
+
+ utcTime += ((Htmp * 60) + Mtmp) * 60 * 1000;
+ }
+ break;
+
+ case '-': {
+ int Htmp = 10 * Character.digit((char) buffer.read(), 10);
+ Htmp += Character.digit((char) buffer.read(), 10);
+ int Mtmp = 10 * Character.digit((char) buffer.read(), 10);
+ Mtmp += Character.digit((char) buffer.read(), 10);
+
+ if (Htmp >= 24 || Mtmp >= 60)
+ throw new IOException("Parse GeneralizedTime, -hhmm");
+
+ utcTime -= ((Htmp * 60) + Mtmp) * 60 * 1000;
+ }
+ break;
+
+ case 'Z':
+ break;
+
+ default:
+ throw new IOException("Parse GeneralizedTime, garbage offset");
+ }
+ readDate.setTime(utcTime);
+ return readDate;
+ }
+
+ /*
+ * Get a byte from the input stream.
+ */
+ // package private
+ int getByte() throws IOException {
+ return (0x00ff & buffer.read());
+ }
+
+ public int peekByte() throws IOException {
+ return buffer.peek();
+ }
+
+ // package private
+ int getLength() throws IOException {
+ return getLength(buffer);
+ }
+
+ /*
+ * Get a length from the input stream, allowing for at most 32 bits of
+ * encoding to be used. (Not the same as getting a tagged integer!)
+ */
+ static int getLength(InputStream in) throws IOException {
+ int value, tmp;
+
+ tmp = in.read();
+ if ((tmp & 0x080) == 0x00) { // 1 byte datum?
+ value = tmp;
+ } else { // no, more ...
+ tmp &= 0x07f;
+
+ /*
+ * NOTE: tmp == 0 indicates BER encoded data.
+ * tmp > 4 indicates more than 4Gb of data.
+ */
+ if (tmp <= 0 || tmp > 4)
+ throw new IOException("DerInput.getLength(): lengthTag="
+ + tmp + ", "
+ + ((tmp == 0) ? "Indefinite length encoding not supported"
+ + " or incorrect DER encoding."
+ : "too big."));
+
+ for (value = 0; tmp > 0; tmp--) {
+ value <<= 8;
+ value += 0x0ff & in.read();
+ }
+ }
+ return value;
+ }
+
+ /**
+ * Mark the current position in the buffer, so that
+ * a later call to <code>reset</code> will return here.
+ */
+ public void mark(int value) {
+ buffer.mark(value);
+ }
+
+ /**
+ * Return to the position of the last <code>mark</code> call. A mark is implicitly set at the beginning of
+ * the stream when it is created.
+ */
+ public void reset() {
+ buffer.reset();
+ }
+
+ /**
+ * Returns the number of bytes available for reading.
+ * This is most useful for testing whether the stream is
+ * empty.
+ */
+ public int available() {
+ return buffer.available();
+ }
+}
diff --git a/base/util/src/netscape/security/util/DerOutputStream.java b/base/util/src/netscape/security/util/DerOutputStream.java
new file mode 100644
index 000000000..62290d604
--- /dev/null
+++ b/base/util/src/netscape/security/util/DerOutputStream.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 netscape.security.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetEncoder;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+/**
+ * Output stream marshaling DER-encoded data. This is eventually provided
+ * in the form of a byte array; there is no advance limit on the size of
+ * that byte array.
+ *
+ * <P>
+ * At this time, this class supports only a subset of the types of DER data encodings which are defined. That subset is
+ * sufficient for generating most X.509 certificates.
+ *
+ * @version 1.32
+ *
+ * @author David Brownell
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ */
+public class DerOutputStream
+ extends ByteArrayOutputStream implements DerEncoder {
+ /**
+ * Construct an DER output stream.
+ *
+ * @param size how large a buffer to preallocate.
+ */
+ public DerOutputStream(int size) {
+ super(size);
+ }
+
+ /**
+ * Construct an DER output stream.
+ */
+ public DerOutputStream() {
+ }
+
+ /**
+ * Writes tagged, pre-marshaled data. This calcuates and encodes
+ * the length, so that the output data is the standard triple of
+ * { tag, length, data } used by all DER values.
+ *
+ * @param tag the DER value tag for the data, such as <em>DerValue.tag_Sequence</em>
+ * @param buf buffered data, which must be DER-encoded
+ */
+ public void write(byte tag, byte[] buf) throws IOException {
+ write(tag);
+ putLength(buf.length);
+ write(buf, 0, buf.length);
+ }
+
+ /**
+ * Writes tagged data using buffer-to-buffer copy. As above,
+ * this writes a standard DER record. This is often used when
+ * efficiently encapsulating values in sequences.
+ *
+ * @param tag the DER value tag for the data, such as <em>DerValue.tag_Sequence</em>
+ * @param out buffered data
+ */
+ public void write(byte tag, DerOutputStream out) throws IOException {
+ write(tag);
+ putLength(out.count);
+ write(out.buf, 0, out.count);
+ }
+
+ /**
+ * Writes implicitly tagged data using buffer-to-buffer copy. As above,
+ * this writes a standard DER record. This is often used when
+ * efficiently encapsulating implicitly tagged values.
+ *
+ * @param tag the DER value of the context-specific tag that replaces
+ * original tag of the value in the output , such as in
+ *
+ * <pre>
+ * <em> <field> [N] IMPLICIT <type></em>
+ * </pre>
+ *
+ * For example, <em>FooLength [1] IMPLICIT INTEGER</em>, with value=4;
+ * would be encoded as "81 01 04" whereas in explicit
+ * tagging it would be encoded as "A1 03 02 01 04".
+ * Notice that the tag is A1 and not 81, this is because with
+ * explicit tagging the form is always constructed.
+ * @param value original value being implicitly tagged
+ */
+ public void writeImplicit(byte tag, DerOutputStream value)
+ throws IOException {
+ write(tag);
+ write(value.buf, 1, value.count - 1);
+ }
+
+ /**
+ * Marshals pre-encoded DER value onto the output stream.
+ */
+ public void putDerValue(DerValue val) throws IOException {
+ val.encode(this);
+ }
+
+ /*
+ * PRIMITIVES -- these are "universal" ASN.1 simple types.
+ *
+ * BOOLEAN, INTEGER, BIT STRING, OCTET STRING, NULL
+ * OBJECT IDENTIFIER, SEQUENCE(OF), SET(OF)
+ * PrintableString, T61String, IA5String, UTCTime
+ */
+
+ /**
+ * Marshals a DER boolean on the output stream.
+ */
+ public void putBoolean(boolean val) throws IOException {
+ write(DerValue.tag_Boolean);
+ putLength(1);
+ if (val) {
+ write(0xff);
+ } else {
+ write(0);
+ }
+ }
+
+ /**
+ * Marshals a DER unsigned integer on the output stream.
+ */
+ public void putInteger(BigInt i) throws IOException {
+ putUnsignedInteger(i.toByteArray());
+ }
+
+ /**
+ * Marshals a DER unsigned integer on the output stream.
+ */
+ public void putUnsignedInteger(byte[] integerBytes) throws IOException {
+
+ write(DerValue.tag_Integer);
+ if ((integerBytes[0] & 0x080) != 0) {
+ /*
+ * prepend zero so it's not read as a negative number
+ */
+ putLength(integerBytes.length + 1);
+ write(0);
+ } else
+ putLength(integerBytes.length);
+ write(integerBytes, 0, integerBytes.length);
+ }
+
+ /**
+ * Marshals a DER enumerated value on the output stream.
+ */
+ public void putEnumerated(int i) throws IOException {
+ write(DerValue.tag_Enumerated);
+
+ int bytemask = 0xff000000;
+ int signmask = 0x80000000;
+ int length;
+ if ((i & 0x80000000) != 0) {
+ // negative case
+ for (length = 4; length > 1; --length) {
+ if ((i & bytemask) != bytemask)
+ break;
+ bytemask = bytemask >>> 8;
+ signmask = signmask >>> 8;
+ }
+ if ((i & signmask) == 0) {
+ // ensure negative case
+ putLength(length + 1);
+ write(0xff);
+ } else {
+ putLength(length);
+ }
+ // unrolled loop
+ switch (length) {
+ case 4:
+ write((byte) (i >>> 24));
+ case 3:
+ write((byte) (i >>> 16));
+ case 2:
+ write((byte) (i >>> 8));
+ case 1:
+ write((byte) i);
+ }
+ } else {
+ // positive case
+ for (length = 4; length > 0; --length) {
+ if ((i & bytemask) != 0)
+ break;
+ bytemask = bytemask >>> 8;
+ signmask = signmask >>> 8;
+ }
+ if ((i & signmask) != 0) {
+ // ensure posititive case
+ putLength(length + 1);
+ write(0x00);
+ } else {
+ putLength(length);
+ }
+ // unrolled loop
+ switch (length) {
+ case 4:
+ write((byte) (i >>> 24));
+ case 3:
+ write((byte) (i >>> 16));
+ case 2:
+ write((byte) (i >>> 8));
+ case 1:
+ write((byte) i);
+ }
+ }
+ }
+
+ /**
+ * Marshals a DER bit string on the output stream. The bit
+ * string must be byte-aligned.
+ *
+ * @param bits the bit string, MSB first
+ */
+ public void putBitString(byte[] bits) throws IOException {
+ write(DerValue.tag_BitString);
+ putLength(bits.length + 1);
+ write(0); // all of last octet is used
+ write(bits);
+ }
+
+ /**
+ * Converts a boolean array to a BitArray. Trims trailing 0 bits
+ * in accordance with DER encoding standard. We assume the input is not
+ * null.
+ */
+ private static BitArray toBitArray(boolean[] bitString) {
+ if (bitString.length == 0) {
+ return new BitArray(bitString);
+ }
+
+ // find index of last 1 bit. -1 if there aren't any
+ int i;
+ for (i = bitString.length - 1; i >= 0; i--) {
+ if (bitString[i]) {
+ break;
+ }
+ }
+ int length = i + 1;
+
+ // if length changed, copy to new appropriately-sized array
+ if (length != bitString.length) {
+ boolean[] newBitString = new boolean[length];
+ System.arraycopy(bitString, 0, newBitString, 0, length);
+ bitString = newBitString;
+ }
+
+ return new BitArray(bitString);
+ }
+
+ /**
+ * Converts bit string to a BitArray, stripping off trailing 0 bits.
+ * We assume that the bit string is not null.
+ */
+ private static BitArray toBitArray(byte[] bitString) {
+ // compute length in bits of bit string
+ int length, i;
+ int maxIndex = 0;
+
+ if (bitString.length == 0) {
+ return new BitArray(0, bitString);
+ }
+
+ // find the index of the last byte with a 1 bit
+ for (i = 0; i < bitString.length; i++) {
+ if (bitString[i] != 0) {
+ maxIndex = i;
+ }
+ }
+ byte lastByte = bitString[maxIndex];
+ length = (maxIndex + 1) * 8; // maximum, might reduce in next step
+
+ // now find the last 1 bit in this last byte
+ for (i = 1; i <= 0x80; i <<= 1) {
+ if ((lastByte & i) == 0) {
+ length--;
+ } else {
+ break;
+ }
+ }
+ return new BitArray(length, bitString);
+ }
+
+ /**
+ * Marshals a DER bit string on the output stream.
+ * The bit strings need not be byte-aligned.
+ *
+ * @param bits the bit string, MSB first
+ */
+ public void putUnalignedBitString(BitArray ba) throws IOException {
+ byte[] bits = ba.toByteArray();
+
+ write(DerValue.tag_BitString);
+ putLength(bits.length + 1);
+ write(bits.length * 8 - ba.length()); // excess bits in last octet
+ write(bits);
+ }
+
+ /**
+ * Marshals a DER bit string on the output stream.
+ * All trailing 0 bits will be stripped off in accordance with DER
+ * encoding.
+ *
+ * @param bits the bit string, MSB first
+ */
+ public void putUnalignedBitString(byte[] bitString) throws IOException {
+ putUnalignedBitString(toBitArray(bitString));
+ }
+
+ /**
+ * Marshals a DER bit string on the output stream.
+ * All trailing 0 bits will be stripped off in accordance with DER
+ * encoding.
+ *
+ * @param bits the bit string as an array of booleans.
+ */
+ public void putUnalignedBitString(boolean[] bitString) throws IOException {
+ putUnalignedBitString(toBitArray(bitString));
+ }
+
+ /**
+ * DER-encodes an ASN.1 OCTET STRING value on the output stream.
+ *
+ * @param octets the octet string
+ */
+ public void putOctetString(byte[] octets) throws IOException {
+ write(DerValue.tag_OctetString, octets);
+ }
+
+ /**
+ * Marshals a DER "null" value on the output stream. These are
+ * often used to indicate optional values which have been omitted.
+ */
+ public void putNull() throws IOException {
+ write(DerValue.tag_Null);
+ putLength(0);
+ }
+
+ /**
+ * Marshals an object identifier (OID) on the output stream.
+ * Corresponds to the ASN.1 "OBJECT IDENTIFIER" construct.
+ */
+ public void putOID(ObjectIdentifier oid) throws IOException {
+ oid.encode(this);
+ }
+
+ /**
+ * Marshals a sequence on the output stream. This supports both
+ * the ASN.1 "SEQUENCE" (zero to N values) and "SEQUENCE OF"
+ * (one to N values) constructs.
+ */
+ public void putSequence(DerValue[] seq) throws IOException {
+ DerOutputStream bytes = new DerOutputStream();
+ int i;
+
+ for (i = 0; i < seq.length; i++)
+ seq[i].encode(bytes);
+
+ write(DerValue.tag_Sequence, bytes);
+ }
+
+ /**
+ * Marshals the contents of a set on the output stream without
+ * ordering the elements. Ok for BER encoding, but not for DER
+ * encoding.
+ *
+ * For DER encoding, use orderedPutSet() or orderedPutSetOf().
+ */
+ public void putSet(DerValue[] set) throws IOException {
+ DerOutputStream bytes = new DerOutputStream();
+ int i;
+
+ for (i = 0; i < set.length; i++)
+ set[i].encode(bytes);
+
+ write(DerValue.tag_Set, bytes);
+ }
+
+ /**
+ * NSCP :
+ * Like putOrderSetOf, except not sorted.
+ * This may defy DER encoding but is needed for compatibility
+ * with communicator.
+ */
+ public void putSet(byte tag, DerEncoder[] set) throws IOException {
+ putOrderedSet(tag, set, null);
+ }
+
+ /**
+ * Marshals the contents of a set on the output stream. Sets
+ * are semantically unordered, but DER requires that encodings of
+ * set elements be sorted into ascending lexicographical order
+ * before being output. Hence sets with the same tags and
+ * elements have the same DER encoding.
+ *
+ * This method supports the ASN.1 "SET OF" construct, but not
+ * "SET", which uses a different order.
+ */
+ public void putOrderedSetOf(byte tag, DerEncoder[] set) throws IOException {
+ putOrderedSet(tag, set, lexOrder);
+ }
+
+ /**
+ * Marshals the contents of a set on the output stream. Sets
+ * are semantically unordered, but DER requires that encodings of
+ * set elements be sorted into ascending tag order
+ * before being output. Hence sets with the same tags and
+ * elements have the same DER encoding.
+ *
+ * This method supports the ASN.1 "SET" construct, but not
+ * "SET OF", which uses a different order.
+ */
+ public void putOrderedSet(byte tag, DerEncoder[] set) throws IOException {
+ putOrderedSet(tag, set, tagOrder);
+ }
+
+ /**
+ * Lexicographical order comparison on byte arrays, for ordering
+ * elements of a SET OF objects in DER encoding.
+ */
+ private static ByteArrayLexOrder lexOrder = new ByteArrayLexOrder();
+
+ /**
+ * Tag order comparison on byte arrays, for ordering elements of
+ * SET objects in DER encoding.
+ */
+ private static ByteArrayTagOrder tagOrder = new ByteArrayTagOrder();
+
+ /**
+ * Marshals a the contents of a set on the output stream with the
+ * encodings of its sorted in increasing order.
+ *
+ * @param order the order to use when sorting encodings of components.
+ */
+ private void putOrderedSet(byte tag, DerEncoder[] set,
+ Comparator<byte[]> order) throws IOException {
+ DerOutputStream[] streams = new DerOutputStream[set.length];
+
+ for (int i = 0; i < set.length; i++) {
+ streams[i] = new DerOutputStream();
+ set[i].derEncode(streams[i]);
+ }
+
+ // order the element encodings
+ byte[][] bufs = new byte[streams.length][];
+ for (int i = 0; i < streams.length; i++) {
+ bufs[i] = streams[i].toByteArray();
+ }
+ if (order != null) {
+ Arrays.sort(bufs, order);
+ }
+
+ DerOutputStream bytes = new DerOutputStream();
+ for (int i = 0; i < streams.length; i++) {
+ bytes.write(bufs[i]);
+ }
+ write(tag, bytes);
+
+ }
+
+ /**
+ * Converts string to printable and writes to der output stream.
+ */
+ public void putPrintableString(String s) throws IOException {
+ putStringType(DerValue.tag_PrintableString, s);
+ }
+
+ public void putVisibleString(String s) throws IOException {
+ putStringType(DerValue.tag_VisibleString, s);
+ }
+
+ /**
+ * Marshals a string which is consists of BMP (unicode) characters
+ */
+ public void putBMPString(String s) throws IOException {
+ putStringType(DerValue.tag_BMPString, s);
+ }
+
+ public void putGeneralString(String s) throws IOException {
+ putStringType(DerValue.tag_GeneralString, s);
+ }
+
+ // /*
+ // * T61 is an 8 bit extension to ASCII, escapes e.g. to Japanese
+ // */
+ // void putT61String(String s) throws IOException
+ // {
+ // // XXX IMPLEMENT ME
+ //
+ // throw new IOException("DerOutputStream.putT61String() NYI");
+ // }
+
+ // /*
+ // * Universal String.
+ // */
+ // void putUniversalString(String s) throws IOException
+ // {
+ // // XXX IMPLEMENT ME
+ //
+ // throw new IOException("DerOutputStream.putUniversalString() NYI");
+ // }
+
+ /**
+ * Marshals a string which is consists of IA5(ASCII) characters
+ */
+ public void putIA5String(String s) throws IOException {
+ putStringType(DerValue.tag_IA5String, s);
+ }
+
+ public void putUTF8String(String s) throws IOException {
+ putStringType(DerValue.tag_UTF8String, s);
+ }
+
+ public void putStringType(byte tag, String s) throws IOException {
+ try {
+ CharsetEncoder encoder = ASN1CharStrConvMap.getDefault().getEncoder(tag);
+ if (encoder == null)
+ throw new IOException("No encoder for tag");
+
+ CharBuffer charBuffer = CharBuffer.wrap(s.toCharArray());
+ ByteBuffer byteBuffer = encoder.encode(charBuffer);
+
+ write(tag);
+ putLength(byteBuffer.limit());
+ write(byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.limit());
+
+ } catch (CharacterCodingException e) {
+ throw new IOException("Not a valid string type " + tag, e);
+ }
+ }
+
+ private void put2DateBytes(byte[] buffer, int value, int offset) {
+ int upper = value / 10;
+ int lower = value % 10;
+ buffer[offset] = (byte) ((byte) upper + (byte) '0');
+ buffer[offset + 1] = (byte) ((byte) lower + (byte) '0');
+ }
+
+ private static Calendar GMTGregorianCalendar = null;
+
+ private Calendar getGMTGregorianCalendar() {
+ if (GMTGregorianCalendar == null) {
+ TimeZone tz = TimeZone.getTimeZone("GMT");
+ GMTGregorianCalendar = new GregorianCalendar(tz);
+ }
+ return (Calendar) GMTGregorianCalendar.clone();
+ }
+
+ public byte[] getDateBytes(Date d, boolean UTC) {
+
+ byte[] datebytes;
+
+ if (UTC) {
+ datebytes = new byte[13];
+ } else { // generalized time has 4 digits for yr
+ datebytes = new byte[15];
+ }
+
+ Calendar cal = getGMTGregorianCalendar();
+ cal.setTime(d);
+
+ int i = 0;
+ if (!UTC) {
+ put2DateBytes(datebytes, cal.get(Calendar.YEAR) / 100, i);
+ i += 2;
+ }
+ put2DateBytes(datebytes, cal.get(Calendar.YEAR) % 100, i);
+ // Calendar's MONTH is zero-based
+ i += 2;
+ put2DateBytes(datebytes, cal.get(Calendar.MONTH) + 1, i);
+ i += 2;
+ put2DateBytes(datebytes, cal.get(Calendar.DAY_OF_MONTH), i);
+ i += 2;
+ put2DateBytes(datebytes, cal.get(Calendar.HOUR_OF_DAY), i);
+ i += 2;
+ put2DateBytes(datebytes, cal.get(Calendar.MINUTE), i);
+ i += 2;
+ put2DateBytes(datebytes, cal.get(Calendar.SECOND), i);
+ i += 2;
+ // datebytes[i] = 'Z';
+ datebytes[i] = (byte) 'Z';
+
+ return datebytes;
+ }
+
+ /**
+ * Marshals a DER UTC time/date value.
+ *
+ * <P>
+ * YYMMDDhhmmss{Z|+hhmm|-hhmm} ... emits only using Zulu time and with seconds (even if seconds=0) as per IETF-PKIX
+ * partI.
+ */
+ public void putUTCTime(Date d) throws IOException {
+ /*
+ * Format the date.
+ */
+
+ // This was the old code. Way too slow to be usable (stevep)
+
+ // String pattern = "yyMMddHHmmss'Z'";
+ // SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+ // TimeZone tz = TimeZone.getTimeZone("GMT");
+ // sdf.setTimeZone(tz);
+ // byte[] utc = (sdf.format(d)).getBytes();
+
+ byte[] datebytes = getDateBytes(d, true); // UTC = true
+
+ /*
+ * Write the formatted date.
+ */
+ write(DerValue.tag_UtcTime);
+ putLength(datebytes.length);
+ write(datebytes);
+ }
+
+ /**
+ * Marshals a DER Generalized Time/date value.
+ *
+ * <P>
+ * YYYYMMDDhhmmss{Z|+hhmm|-hhmm} ... emits only using Zulu time and with seconds (even if seconds=0) as per
+ * IETF-PKIX partI.
+ */
+ public void putGeneralizedTime(Date d) throws IOException {
+ /*
+ * Format the date.
+ */
+ TimeZone tz = TimeZone.getTimeZone("GMT");
+
+ // This is way too slow to be usable (stevep)
+ String pattern = "yyyyMMddHHmmss'Z'";
+ SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+ sdf.setTimeZone(tz);
+ byte[] gt = (sdf.format(d)).getBytes();
+
+ /*
+ * Write the formatted date.
+ */
+ write(DerValue.tag_GeneralizedTime);
+ putLength(gt.length);
+ write(gt);
+ }
+
+ /**
+ * Put the encoding of the length in the stream.
+ *
+ * @param len the length of the attribute.
+ * @exception IOException on writing errors.
+ */
+ public void putLength(int len) throws IOException {
+ if (len < 128) {
+ write((byte) len);
+
+ } else if (len < (1 << 8)) {
+ write((byte) 0x081);
+ write((byte) len);
+
+ } else if (len < (1 << 16)) {
+ write((byte) 0x082);
+ write((byte) (len >> 8));
+ write((byte) len);
+
+ } else if (len < (1 << 24)) {
+ write((byte) 0x083);
+ write((byte) (len >> 16));
+ write((byte) (len >> 8));
+ write((byte) len);
+
+ } else {
+ write((byte) 0x084);
+ write((byte) (len >> 24));
+ write((byte) (len >> 16));
+ write((byte) (len >> 8));
+ write((byte) len);
+ }
+ }
+
+ /**
+ * Put the tag of the attribute in the stream.
+ *
+ * @param class the tag class type, one of UNIVERSAL, CONTEXT,
+ * APPLICATION or PRIVATE
+ * @param form if true, the value is constructed, otherwise it is
+ * primitive.
+ * @param val the tag value
+ */
+ public void putTag(byte tagClass, boolean form, byte val) {
+ byte tag = (byte) (tagClass | val);
+ if (form) {
+ tag |= (byte) 0x20;
+ }
+ write(tag);
+ }
+
+ /**
+ * Write the current contents of this <code>DerOutputStream</code> to an <code>OutputStream</code>.
+ *
+ * @exception IOException on output error.
+ */
+ public void derEncode(OutputStream out) throws IOException {
+ out.write(toByteArray());
+ }
+}
diff --git a/base/util/src/netscape/security/util/DerValue.java b/base/util/src/netscape/security/util/DerValue.java
new file mode 100644
index 000000000..71b6f7f2c
--- /dev/null
+++ b/base/util/src/netscape/security/util/DerValue.java
@@ -0,0 +1,715 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetDecoder;
+import java.util.Arrays;
+
+import netscape.security.x509.AVAValueConverter;
+import netscape.security.x509.GenericValueConverter;
+
+/**
+ * Represents a single DER-encoded value. DER encoding rules are a subset
+ * of the "Basic" Encoding Rules (BER), but they only support a single way
+ * ("Definite" encoding) to encode any given value.
+ *
+ * <P>
+ * All DER-encoded data are triples <em>{type, length, data}</em>. This class represents such tagged values as they have
+ * been read (or constructed), and provides structured access to the encoded data.
+ *
+ * <P>
+ * At this time, this class supports only a subset of the types of DER data encodings which are defined. That subset is
+ * sufficient for parsing most X.509 certificates, and working with selected additional formats (such as PKCS #10
+ * certificate requests, and some kinds of PKCS #7 data).
+ *
+ * @version 1.43
+ *
+ * @author David Brownell
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ */
+public class DerValue {
+ /** The tag class types */
+ public static final byte TAG_UNIVERSAL = (byte) 0x000;
+ public static final byte TAG_APPLICATION = (byte) 0x040;
+ public static final byte TAG_CONTEXT = (byte) 0x080;
+ public static final byte TAG_PRIVATE = (byte) 0x0c0;
+
+ /** The DER tag of the value; one of the tag_ constants. */
+ public byte tag;
+
+ protected DerInputBuffer buffer;
+
+ /**
+ * The DER-encoded data of the value.
+ */
+ public DerInputStream data;
+
+ private int length;
+
+ /*
+ * The type starts at the first byte of the encoding, and
+ * is one of these tag_* values. That may be all the type
+ * data that is needed.
+ */
+
+ /*
+ * These tags are the "universal" tags ... they mean the same
+ * in all contexts. (Mask with 0x1f -- five bits.)
+ */
+
+ /** Tag value indicating an ASN.1 "BOOLEAN" value. */
+ public final static byte tag_Boolean = 0x01;
+
+ /** Tag value indicating an ASN.1 "INTEGER" value. */
+ public final static byte tag_Integer = 0x02;
+
+ /** Tag value indicating an ASN.1 "BIT STRING" value. */
+ public final static byte tag_BitString = 0x03;
+
+ /** Tag value indicating an ASN.1 "OCTET STRING" value. */
+ public final static byte tag_OctetString = 0x04;
+
+ /** Tag value indicating an ASN.1 "NULL" value. */
+ public final static byte tag_Null = 0x05;
+
+ /** Tag value indicating an ASN.1 "OBJECT IDENTIFIER" value. */
+ public final static byte tag_ObjectId = 0x06;
+
+ /** Tag value including an ASN.1 "ENUMERATED" value */
+ public final static byte tag_Enumerated = 0x0A;
+
+ /** Tag value including a "printable" string */
+ public final static byte tag_PrintableString = 0x13;
+
+ public final static byte tag_VisibleString = 0x1A;
+
+ /** Tag value including a "teletype" string */
+ public final static byte tag_T61String = 0x14;
+
+ /** Tag value including an ASCII string */
+ public final static byte tag_IA5String = 0x16;
+
+ /** Tag value indicating an ASN.1 "UTCTime" value. */
+ public final static byte tag_UtcTime = 0x17;
+
+ /** Tag value indicating an ASN.1 "GeneralizedTime" value. */
+ public final static byte tag_GeneralizedTime = 0x18;
+
+ /** Tag value indicating an ASN.1 "GeneralString" value. */
+ public final static byte tag_GeneralString = 0x1B;
+
+ /** Tag value indicating an ASN.1 "BMPString" value. */
+ public final static byte tag_BMPString = 0x1E;
+
+ /** Tag value indicating an ASN.1 "UniversalString" value. */
+ public final static byte tag_UniversalString = 0x1C;
+
+ /** Tag value indicating an ASN.1 "UTF8String" value. (since 1998) */
+ public final static byte tag_UTF8String = 0x0C;
+
+ // CONSTRUCTED seq/set
+
+ /**
+ * Tag value indicating an ASN.1
+ * "SEQUENCE" (zero to N elements, order is significant).
+ */
+ public final static byte tag_Sequence = 0x30;
+
+ /**
+ * Tag value indicating an ASN.1
+ * "SEQUENCE OF" (one to N elements, order is significant).
+ */
+ public final static byte tag_SequenceOf = 0x30;
+
+ /**
+ * Tag value indicating an ASN.1
+ * "SET" (zero to N members, order does not matter).
+ */
+ public final static byte tag_Set = 0x31;
+
+ /**
+ * Tag value indicating an ASN.1
+ * "SET OF" (one to N members, order does not matter).
+ */
+ public final static byte tag_SetOf = 0x31;
+
+ /*
+ * These values are the high order bits for the other kinds of tags.
+ */
+ boolean isUniversal() {
+ return ((tag & 0x0c0) == 0x000);
+ }
+
+ boolean isApplication() {
+ return ((tag & 0x0c0) == 0x040);
+ }
+
+ /**
+ * Returns true iff the CONTEXT SPECIFIC bit is set in the type tag.
+ * This is associated with the ASN.1 "DEFINED BY" syntax.
+ */
+ public boolean isContextSpecific() {
+ return ((tag & 0x0c0) == 0x080);
+ }
+
+ /**
+ * Returns true iff the CONTEXT SPECIFIC TAG matches the passed tag.
+ */
+ public boolean isContextSpecific(byte cntxtTag) {
+ if (!isContextSpecific()) {
+ return false;
+ }
+ return ((tag & 0x01f) == cntxtTag);
+ }
+
+ boolean isPrivate() {
+ return ((tag & 0x0c0) == 0x0c0);
+ }
+
+ /** Returns true iff the CONSTRUCTED bit is set in the type tag. */
+ public boolean isConstructed() {
+ return ((tag & 0x020) == 0x020);
+ }
+
+ /**
+ * Creates a DER value from a string
+ * using a generic way of determining the proper tag for the string.
+ * Assumes the string is a Generic attribute value and uses
+ * the converter for generic string values to convert to the Der Value.
+ */
+ public DerValue(String value)
+ throws IOException {
+ AVAValueConverter genericValue = new GenericValueConverter();
+ DerValue val;
+
+ val = genericValue.getValue(value);
+ tag = val.tag;
+ buffer = val.buffer;
+ length = val.length;
+ data = val.data;
+ data.mark(Integer.MAX_VALUE);
+ }
+
+ /**
+ * Creates a DerValue from a tag and some DER-encoded data.
+ *
+ * @param tag the DER type tag
+ * @param data the DER-encoded data
+ */
+ public DerValue(byte tag, byte[] data) {
+ this.tag = tag;
+ buffer = new DerInputBuffer(data.clone());
+ length = data.length;
+ this.data = new DerInputStream(buffer);
+ this.data.mark(Integer.MAX_VALUE);
+ }
+
+ /**
+ * Creates a DerValue from a tag and some DER-encoded data.
+ *
+ * @param tag the DER type tag
+ * @param data the DER-encoded data
+ * @param offset offset of the data
+ * @param length length of the data
+ */
+ public DerValue(byte tag, byte[] data, int offset, int length) {
+ this(tag, Arrays.copyOfRange(data, offset, offset + length));
+ }
+
+ /*
+ * package private
+ */
+ DerValue(DerInputBuffer in) throws IOException {
+ // NOTE: This must handle the special value used
+ // to terminate BER indefinite encodings (tag and
+ // length are both zero)
+
+ // XXX must also parse BER-encoded constructed
+ // values such as sequences, sets...
+
+ tag = (byte) in.read();
+ length = DerInputStream.getLength(in);
+
+ buffer = in.dup();
+ buffer.truncate(length);
+ data = new DerInputStream(buffer);
+
+ in.skip(length);
+ }
+
+ /**
+ * Get an ASN.1/DER encoded datum from a buffer. The
+ * entire buffer must hold exactly one datum, including
+ * its tag and length.
+ *
+ * @param buf buffer holding a single DER-encoded datum.
+ */
+ public DerValue(byte[] buf) throws IOException {
+ init(true, new ByteArrayInputStream(buf));
+ }
+
+ /**
+ * Get an ASN.1/DER encoded datum from part of a buffer.
+ * That part of the buffer must hold exactly one datum, including
+ * its tag and length.
+ *
+ * @param buf the buffer
+ * @param offset start point of the single DER-encoded dataum
+ * @param length how many bytes are in the encoded datum
+ */
+ public DerValue(byte[] buf, int offset, int len) throws IOException {
+ init(true, new ByteArrayInputStream(buf, offset, len));
+ }
+
+ /**
+ * Get an ASN1/DER encoded datum from an input stream. The
+ * stream may have additional data following the encoded datum.
+ *
+ * @param in the input stream holding a single DER datum,
+ * which may be followed by additional data
+ */
+ public DerValue(InputStream in) throws IOException {
+ init(false, in);
+ }
+
+ /*
+ * helper routine
+ */
+ private void init(boolean fullyBuffered, InputStream in)
+ throws IOException {
+ byte[] bytes;
+
+ tag = (byte) in.read();
+ length = DerInputStream.getLength(in);
+
+ /*
+ if (length == 0)
+ return;
+ */
+
+ if (fullyBuffered && in.available() != length)
+ throw new IOException("extra DER value data (constructor)");
+
+ bytes = new byte[length];
+
+ // n.b. readFully not needed in normal fullyBuffered case
+ DataInputStream dis = new DataInputStream(in);
+
+ dis.readFully(bytes);
+ buffer = new DerInputBuffer(bytes);
+ data = new DerInputStream(buffer);
+ }
+
+ /**
+ * Encode an ASN1/DER encoded datum onto a DER output stream.
+ */
+ public void encode(DerOutputStream out)
+ throws IOException {
+ out.write(tag);
+ out.putLength(length);
+ buffer.dump(out, length);
+
+ }
+
+ /**
+ * Returns an ASN.1 BOOLEAN
+ *
+ * @return the boolean held in this DER value
+ */
+ public boolean getBoolean() throws IOException {
+ if (tag != tag_Boolean) {
+ throw new IOException("DerValue.getBoolean, not a BOOLEAN " + tag);
+ }
+ if (length != 1) {
+ throw new IOException("DerValue.getBoolean, invalid length " + length);
+ }
+ if (buffer.read() != 0) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns an ASN.1 OBJECT IDENTIFIER.
+ *
+ * @return the OID held in this DER value
+ */
+ public ObjectIdentifier getOID() throws IOException {
+ if (tag != tag_ObjectId)
+ throw new IOException("DerValue.getOID, not an OID " + tag);
+ return new ObjectIdentifier(buffer);
+ }
+
+ /**
+ * Returns an ASN.1 OCTET STRING
+ *
+ * @return the octet string held in this DER value
+ */
+ public byte[] getOctetString() throws IOException {
+ if (tag != tag_OctetString)
+ throw new IOException(
+ "DerValue.getOctetString, not an Octet String: " + tag);
+
+ byte[] bytes = new byte[length];
+
+ if (buffer.read(bytes) != length)
+ throw new IOException("short read on DerValue buffer");
+ return bytes;
+ }
+
+ /**
+ * Returns an ASN.1 unsigned integer value of enumerated value.
+ *
+ * @return the (unsigned) integer held in this DER value
+ */
+ public int getEnumerated()
+ throws IOException {
+ if (tag != tag_Enumerated)
+ throw new IOException("DerValue.getEnumerated, not an ENUMERATED " + tag);
+ if (length == 0)
+ return 0;
+ if (length > 4 || length < 1)
+ throw new IOException("DerValue.getEnumerated, invalid length " + length + "(must be between 1 and 4)");
+
+ int value = 0;
+ int nextbyte = buffer.read();
+ if (nextbyte == -1)
+ throw new IOException("short read on DerValue buffer");
+ // perform sign extension
+ value = (byte) nextbyte;
+
+ for (int i = length - 1; i > 0; --i) {
+ nextbyte = buffer.read();
+ if (nextbyte == -1)
+ throw new IOException("short read on DerValue buffer");
+ value = 256 * value + nextbyte;
+ }
+ return value;
+ }
+
+ /**
+ * Returns an ASN.1 unsigned INTEGER value.
+ *
+ * @return the (unsigned) integer held in this DER value
+ */
+ public BigInt getInteger() throws IOException {
+ if (tag != tag_Integer)
+ throw new IOException("DerValue.getInteger, not an int " + tag);
+ return buffer.getUnsigned(data.available());
+ }
+
+ /**
+ * Returns an ASN.1 unsigned INTEGER value, the parameter determining
+ * if the tag is implicit.
+ *
+ * @param tagImplicit if true, ignores the tag value as it is
+ * assumed implicit.
+ * @return the (unsigned) integer held in this DER value
+ */
+ public BigInt getInteger(boolean tagImplicit) throws IOException {
+ if (!tagImplicit) {
+ if (tag != tag_Integer) {
+ throw new IOException("DerValue.getInteger, not an int "
+ + tag);
+ }
+ }
+ return buffer.getUnsigned(data.available());
+ }
+
+ /**
+ * Returns an ASN.1 BIT STRING value. The bit string must be byte-aligned.
+ *
+ * @return the bit string held in this value
+ */
+ public byte[] getBitString() throws IOException {
+ if (tag != tag_BitString)
+ throw new IOException(
+ "DerValue.getBitString, not a bit string " + tag);
+
+ return buffer.getBitString();
+ }
+
+ /**
+ * Returns an ASN.1 BIT STRING value that need not be byte-aligned.
+ *
+ * @return a BitArray representing the bit string held in this value
+ */
+ public BitArray getUnalignedBitString() throws IOException {
+ if (tag != tag_BitString)
+ throw new IOException(
+ "DerValue.getBitString, not a bit string " + tag);
+
+ return buffer.getUnalignedBitString();
+ }
+
+ /**
+ * Returns the name component as a Java string, regardless of its
+ * encoding restrictions (ASCII, T61, Printable, etc).
+ */
+ public String getAsString() throws IOException {
+ AVAValueConverter genericValue = new GenericValueConverter();
+ return genericValue.getAsString(this);
+ }
+
+ /**
+ * Returns an ASN.1 BIT STRING value, with the tag assumed implicit
+ * based on the parameter. The bit string must be byte-aligned.
+ *
+ * @param tagImplicit if true, the tag is assumed implicit.
+ * @return the bit string held in this value
+ */
+ public byte[] getBitString(boolean tagImplicit) throws IOException {
+ if (!tagImplicit) {
+ if (tag != tag_BitString)
+ throw new IOException("DerValue.getBitString, not a bit string "
+ + tag);
+ }
+ return buffer.getBitString();
+ }
+
+ /**
+ * Returns an ASN.1 BIT STRING value, with the tag assumed implicit
+ * based on the parameter. The bit string need not be byte-aligned.
+ *
+ * @param tagImplicit if true, the tag is assumed implicit.
+ * @return the bit string held in this value
+ */
+ public BitArray getUnalignedBitString(boolean tagImplicit)
+ throws IOException {
+ if (!tagImplicit) {
+ if (tag != tag_BitString)
+ throw new IOException("DerValue.getBitString, not a bit string "
+ + tag);
+ }
+ return buffer.getUnalignedBitString();
+ }
+
+ /**
+ * Returns an ASN.1 STRING value
+ *
+ * @return the printable string held in this value
+ */
+ public String getPrintableString()
+ throws IOException {
+ if (tag != tag_PrintableString)
+ throw new IOException(
+ "DerValue.getPrintableString, not a string " + tag);
+
+ return getASN1CharString();
+ }
+
+ /*
+ * @eturns a string if the DerValue is a ASN.1 character string type and
+ * if there is a decoder for the type. Returns null otherwise.
+ */
+ public String getASN1CharString() throws IOException {
+ try {
+ CharsetDecoder decoder = ASN1CharStrConvMap.getDefault().getDecoder(tag);
+ if (decoder == null)
+ return null;
+
+ ByteBuffer byteBuffer = ByteBuffer.allocate(length);
+
+ data.reset();
+ data.getBytes(byteBuffer.array());
+
+ CharBuffer charBuffer = decoder.decode(byteBuffer);
+ return charBuffer.toString();
+
+ } catch (CharacterCodingException e) {
+ throw new IOException("Misformed DER value", e);
+ }
+ }
+
+ /**
+ * Returns an ASN.1 T61 (Teletype) STRING value
+ *
+ * @return the teletype string held in this value
+ */
+ public String getT61String() throws IOException {
+ if (tag != tag_T61String)
+ throw new IOException(
+ "DerValue.getT61String, not T61 " + tag);
+
+ return getASN1CharString();
+ }
+
+ /**
+ * Returns an ASN.1 IA5 (ASCII) STRING value
+ *
+ * @return the ASCII string held in this value
+ */
+ public String getIA5String() throws IOException {
+ if (tag != tag_IA5String)
+ throw new IOException(
+ "DerValue.getIA5String, not IA5 " + tag);
+
+ return getASN1CharString();
+ }
+
+ public String getBMPString()
+ throws IOException {
+ if (tag != tag_BMPString)
+ throw new IOException(
+ "DerValue.getBMPString, not BMP " + tag);
+
+ return getASN1CharString();
+ }
+
+ public String getUniversalString()
+ throws IOException {
+ if (tag != tag_UniversalString)
+ throw new IOException(
+ "DerValue.getUniversalString, not UniversalString " + tag);
+
+ return getASN1CharString();
+ }
+
+ public String getUTF8String()
+ throws IOException {
+ if (tag != tag_UTF8String)
+ throw new IOException(
+ "DerValue.getUTF8String, not UTF8String " + tag);
+
+ return getASN1CharString();
+ }
+
+ /**
+ * Returns true iff the other object is a DER value which
+ * is bitwise equal to this one.
+ *
+ * @param other the object being compared with this one
+ */
+ public boolean equals(Object other) {
+ if (other instanceof DerValue)
+ return equals((DerValue) other);
+ else
+ return false;
+ }
+
+ /**
+ * Bitwise equality comparison. DER encoded values have a single
+ * encoding, so that bitwise equality of the encoded values is an
+ * efficient way to establish equivalence of the unencoded values.
+ *
+ * @param other the object being compared with this one
+ */
+ public boolean equals(DerValue other) {
+ data.reset();
+ other.data.reset();
+ if (this == other)
+ return true;
+ else if (tag != other.tag) {
+ return false;
+ } else {
+ return buffer.equals(other.buffer);
+ }
+ }
+
+ /**
+ * Returns a printable representation of the value.
+ *
+ * @return printable representation of the value
+ */
+ public String toString() {
+ try {
+ String s = getAsString();
+ if (s != null)
+ return s;
+ if (tag == tag_Null)
+ return "[DerValue, null]";
+ if (tag == tag_ObjectId)
+ return "OID." + getOID();
+
+ // integers
+ else
+ return "[DerValue, tag = " + tag
+ + ", length = " + length + "]";
+ } catch (IOException e) {
+ throw new IllegalArgumentException("misformatted DER value");
+ }
+ }
+
+ /**
+ * Returns a DER-encoded value, such that if it's passed to the
+ * DerValue constructor, a value equivalent to "this" is returned.
+ *
+ * @return DER-encoded value, including tag and length.
+ */
+ public byte[] toByteArray() throws IOException {
+ DerOutputStream out = new DerOutputStream();
+
+ encode(out);
+ data.reset();
+ return out.toByteArray();
+ }
+
+ /**
+ * For "set" and "sequence" types, this function may be used
+ * to return a DER stream of the members of the set or sequence.
+ * This operation is not supported for primitive types such as
+ * integers or bit strings.
+ */
+ public DerInputStream toDerInputStream() throws IOException {
+ if (tag == tag_Sequence || tag == tag_Set)
+ return new DerInputStream(buffer);
+ throw new IOException("toDerInputStream rejects tag type " + tag);
+ }
+
+ /**
+ * Get the length of the encoded value.
+ */
+ public int length() {
+ return length;
+ }
+
+ /**
+ * Create the tag of the attribute.
+ *
+ * @param class the tag class type, one of UNIVERSAL, CONTEXT,
+ * APPLICATION or PRIVATE
+ * @param form if true, the value is constructed, otherwise it
+ * is primitive.
+ * @param val the tag value
+ */
+ public static byte createTag(byte tagClass, boolean form, byte val) {
+ byte tag = (byte) (tagClass | val);
+ if (form) {
+ tag |= (byte) 0x20;
+ }
+ return (tag);
+ }
+
+ /**
+ * Set the tag of the attribute. Commonly used to reset the
+ * tag value used for IMPLICIT encodings.
+ *
+ * @param tag the tag value
+ */
+ public void resetTag(byte tag) {
+ this.tag = tag;
+ }
+}
diff --git a/base/util/src/netscape/security/util/ExtPrettyPrint.java b/base/util/src/netscape/security/util/ExtPrettyPrint.java
new file mode 100644
index 000000000..90d0d094f
--- /dev/null
+++ b/base/util/src/netscape/security/util/ExtPrettyPrint.java
@@ -0,0 +1,1653 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.util;
+
+import java.math.BigInteger;
+import java.text.DateFormat;
+import java.util.Enumeration;
+import java.util.ResourceBundle;
+import java.util.Vector;
+
+import netscape.security.extensions.AccessDescription;
+import netscape.security.extensions.AuthInfoAccessExtension;
+import netscape.security.extensions.CertificateScopeEntry;
+import netscape.security.extensions.CertificateScopeOfUseExtension;
+import netscape.security.extensions.ExtendedKeyUsageExtension;
+import netscape.security.extensions.InhibitAnyPolicyExtension;
+import netscape.security.extensions.NSCertTypeExtension;
+import netscape.security.extensions.OCSPNoCheckExtension;
+import netscape.security.extensions.PresenceServerExtension;
+import netscape.security.extensions.SubjectInfoAccessExtension;
+import netscape.security.x509.Attribute;
+import netscape.security.x509.AuthorityKeyIdentifierExtension;
+import netscape.security.x509.BasicConstraintsExtension;
+import netscape.security.x509.CPSuri;
+import netscape.security.x509.CRLDistributionPoint;
+import netscape.security.x509.CRLDistributionPointsExtension;
+import netscape.security.x509.CRLDistributionPointsExtension.Reason;
+import netscape.security.x509.CRLNumberExtension;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.CertificateIssuerExtension;
+import netscape.security.x509.CertificatePoliciesExtension;
+import netscape.security.x509.CertificatePolicyInfo;
+import netscape.security.x509.CertificatePolicyMap;
+import netscape.security.x509.DeltaCRLIndicatorExtension;
+import netscape.security.x509.DisplayText;
+import netscape.security.x509.Extension;
+import netscape.security.x509.FreshestCRLExtension;
+import netscape.security.x509.GeneralName;
+import netscape.security.x509.GeneralNameInterface;
+import netscape.security.x509.GeneralNames;
+import netscape.security.x509.HoldInstructionExtension;
+import netscape.security.x509.InvalidityDateExtension;
+import netscape.security.x509.IssuerAlternativeNameExtension;
+import netscape.security.x509.IssuingDistributionPoint;
+import netscape.security.x509.IssuingDistributionPointExtension;
+import netscape.security.x509.KeyIdentifier;
+import netscape.security.x509.KeyUsageExtension;
+import netscape.security.x509.NSCCommentExtension;
+import netscape.security.x509.NameConstraintsExtension;
+import netscape.security.x509.NoticeReference;
+import netscape.security.x509.OIDMap;
+import netscape.security.x509.PolicyConstraintsExtension;
+import netscape.security.x509.PolicyMappingsExtension;
+import netscape.security.x509.PolicyQualifierInfo;
+import netscape.security.x509.PolicyQualifiers;
+import netscape.security.x509.PrivateKeyUsageExtension;
+import netscape.security.x509.Qualifier;
+import netscape.security.x509.RDN;
+import netscape.security.x509.SerialNumber;
+import netscape.security.x509.SubjectAlternativeNameExtension;
+import netscape.security.x509.SubjectDirAttributesExtension;
+import netscape.security.x509.SubjectKeyIdentifierExtension;
+import netscape.security.x509.UserNotice;
+
+/**
+ * This class will display the certificate content in predefined
+ * format.
+ *
+ * @author Andrew Wnuk
+ * @version $Revision$, $Date$
+ */
+public class ExtPrettyPrint {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private Extension mExt = null;
+ private ResourceBundle mResource = null;
+ private ResourceBundle resource = null;
+ private PrettyPrintFormat pp = null;
+ private int mIndentSize = 0;
+
+ DateFormat dateFormater = null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ public ExtPrettyPrint(Extension ext, int indentSize) {
+ mExt = ext;
+ mResource = ResourceBundle.getBundle(PrettyPrintResources.class.getName());
+ mIndentSize = indentSize;
+ pp = new PrettyPrintFormat(":");
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * This method return string representation of the certificate
+ * 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(int indentSize) {
+ public String toString() {
+
+ StringBuffer sb = new StringBuffer();
+
+ //check if the extension is known
+ if (mExt instanceof KeyUsageExtension) {
+ return getKeyUsage();
+ }
+ if (mExt instanceof NSCertTypeExtension) {
+ return getCertType();
+ }
+ if (mExt instanceof AuthorityKeyIdentifierExtension) {
+ return getAuthorityKeyIdentifier();
+ }
+ if (mExt instanceof SubjectKeyIdentifierExtension) {
+ return getSubjectKeyIdentifier();
+ }
+ if (mExt instanceof CRLReasonExtension) {
+ return getCRLReasonExtension();
+ }
+ if (mExt instanceof BasicConstraintsExtension) {
+ return getBasicConstraintsExtension();
+ }
+ if (mExt instanceof NSCCommentExtension) {
+ return getNSCCommentExtension();
+ }
+ if (mExt instanceof NameConstraintsExtension) {
+ return getNameConstraintsExtension();
+ }
+ if (mExt instanceof CRLNumberExtension) {
+ return getCRLNumberExtension();
+ }
+ if (mExt instanceof DeltaCRLIndicatorExtension) {
+ return getDeltaCRLIndicatorExtension();
+ }
+ if (mExt instanceof IssuerAlternativeNameExtension) {
+ return getIssuerAlternativeNameExtension();
+ }
+ if (mExt instanceof SubjectAlternativeNameExtension) {
+ return getSubjectAlternativeNameExtension();
+ }
+ if (mExt instanceof FreshestCRLExtension) {
+ return getFreshestCRLExtension();
+ }
+ if (mExt instanceof CRLDistributionPointsExtension) {
+ return getCRLDistributionPointsExtension();
+ }
+ if (mExt instanceof IssuingDistributionPointExtension) {
+ return getIssuingDistributionPointExtension();
+ }
+ if (mExt instanceof ExtendedKeyUsageExtension) {
+ return getExtendedKeyUsageExtension();
+ }
+ if (mExt instanceof AuthInfoAccessExtension) {
+ return getAuthInfoAccessExtension();
+ }
+ if (mExt instanceof SubjectInfoAccessExtension) {
+ return getSubjectInfoAccessExtension();
+ }
+ if (mExt instanceof OCSPNoCheckExtension) {
+ return getOCSPNoCheckExtension();
+ }
+ if (mExt instanceof PrivateKeyUsageExtension) {
+ return getPrivateKeyUsageExtension();
+ }
+ if (mExt instanceof InvalidityDateExtension) {
+ return getInvalidityDateExtension();
+ }
+ if (mExt instanceof CertificateIssuerExtension) {
+ return getCertificateIssuerExtension();
+ }
+ if (mExt instanceof HoldInstructionExtension) {
+ return getHoldInstructionExtension();
+ }
+ if (mExt instanceof PolicyConstraintsExtension) {
+ return getPolicyConstraintsExtension();
+ }
+ if (mExt instanceof PolicyMappingsExtension) {
+ return getPolicyMappingsExtension();
+ }
+ if (mExt instanceof SubjectDirAttributesExtension) {
+ return getSubjectDirAttributesExtension();
+ }
+ if (mExt instanceof CertificateScopeOfUseExtension) {
+ return getCertificateScopeOfUseExtension();
+ }
+ if (mExt instanceof PresenceServerExtension) {
+ return getPresenceServerExtension();
+ }
+
+ if (mExt instanceof InhibitAnyPolicyExtension) {
+ return getInhibitAnyPolicyExtension();
+ }
+
+ if (mExt instanceof CertificatePoliciesExtension) {
+ return getCertificatePoliciesExtension();
+ }
+
+ //unknown cert extension
+ try {
+ String extName = OIDMap.getName(mExt.getExtensionId());
+
+ if (extName == null)
+ sb.append(pp.indent(mIndentSize) + mResource.getString(
+ PrettyPrintResources.TOKEN_IDENTIFIER) +
+ mExt.getExtensionId().toString() + "\n");
+ else
+ sb.append(pp.indent(mIndentSize) + mResource.getString(
+ PrettyPrintResources.TOKEN_IDENTIFIER) + " " + extName + " - " +
+ mExt.getExtensionId().toString() + "\n");
+
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_CRITICAL));
+ if (mExt.isCritical()) {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_VALUE) + "\n");
+ sb.append(pp.toHexString(mExt.getExtensionValue(), mIndentSize + 8, 16));
+ return sb.toString();
+ } catch (Exception e) {
+ return "";
+ }
+
+ }
+
+ /*==========================================================
+ * Private methods
+ *==========================================================*/
+
+ private String getNSCCommentExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(
+ PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NSC_COMMENT) +
+ "- " + mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_CRITICAL));
+ if (mExt.isCritical()) {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+ sb.append(pp.indent(mIndentSize + 4) + ((NSCCommentExtension) mExt).toPrint(mIndentSize) + "\n");
+ return sb.toString();
+ } catch (Exception e) {
+ return sb.toString();
+ }
+ }
+
+ private String getNameConstraintsExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(
+ PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NAME_CONSTRAINTS) +
+ "- " + mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_CRITICAL));
+ if (mExt.isCritical()) {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+
+ sb.append(pp.indent(mIndentSize + 4) + ((NameConstraintsExtension) mExt).toPrint(mIndentSize + 4));
+
+ return sb.toString();
+ } catch (Exception e) {
+ return sb.toString();
+ }
+ }
+
+ private String getOCSPNoCheckExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(
+ PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_OCSP_NOCHECK) +
+ "- " + mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_CRITICAL));
+ if (mExt.isCritical()) {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+ return sb.toString();
+ } catch (Exception e) {
+ return sb.toString();
+ }
+ }
+
+ private String getSubjectInfoAccessExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(
+ PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_SIA) +
+ "- " + mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_CRITICAL));
+ if (mExt.isCritical()) {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_ACCESS_DESC) + "\n");
+ SubjectInfoAccessExtension aia = (SubjectInfoAccessExtension) mExt;
+
+ for (int i = 0; i < aia.numberOfAccessDescription(); i++) {
+ AccessDescription ad = (AccessDescription)
+ aia.getAccessDescription(i);
+ ObjectIdentifier method = ad.getMethod();
+
+ if (method.equals(SubjectInfoAccessExtension.METHOD_OCSP)) {
+ sb.append(pp.indent(mIndentSize + 8) + "Method #" + i + ": " +
+ "ocsp" + "\n");
+ } else {
+ sb.append(pp.indent(mIndentSize + 8) + "Method #" + i + ": " +
+ method.toString() + "\n");
+ }
+ sb.append(pp.indent(mIndentSize + 8) + "Location #" + i + ": " +
+ ad.getLocation().toString() + "\n");
+ }
+ return sb.toString();
+ } catch (Exception e) {
+ return sb.toString();
+ }
+ }
+
+ private String getAuthInfoAccessExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(
+ PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_AIA) +
+ "- " + mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_CRITICAL));
+ if (mExt.isCritical()) {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_ACCESS_DESC) + "\n");
+ AuthInfoAccessExtension aia = (AuthInfoAccessExtension) mExt;
+
+ for (int i = 0; i < aia.numberOfAccessDescription(); i++) {
+ AccessDescription ad = (AccessDescription)
+ aia.getAccessDescription(i);
+ ObjectIdentifier method = ad.getMethod();
+
+ if (method.equals(AuthInfoAccessExtension.METHOD_OCSP)) {
+ sb.append(pp.indent(mIndentSize + 8) + "Method #" + i + ": " +
+ "ocsp" + "\n");
+ } else {
+ sb.append(pp.indent(mIndentSize + 8) + "Method #" + i + ": " +
+ method.toString() + "\n");
+ }
+ sb.append(pp.indent(mIndentSize + 8) + "Location #" + i + ": " +
+ ad.getLocation().toString() + "\n");
+ }
+ return sb.toString();
+ } catch (Exception e) {
+ return sb.toString();
+ }
+ }
+
+ private String getPresenceServerExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(
+ PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_PRESENCE_SERVER) +
+ "- " + mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_CRITICAL));
+ if (mExt.isCritical()) {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+
+ PresenceServerExtension pse = (PresenceServerExtension) mExt;
+
+ sb.append(pp.indent(mIndentSize + 4) + "Version : " + pse.getVersion() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + "Street Address : " + pse.getStreetAddress() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + "Telephone Number : " + pse.getTelephoneNumber() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + "RFC822 Name : " + pse.getRFC822() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + "ID : " + pse.getID() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + "Host Name : " + pse.getHostName() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + "Port Number : " + pse.getPortNumber() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + "Max Users : " + pse.getMaxUsers() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + "Service Level : " + pse.getServiceLevel() + "\n");
+
+ return sb.toString();
+ } catch (Exception e) {
+ return sb.toString();
+ }
+ }
+
+ private String getPrivateKeyUsageExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(
+ PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_PRIVATE_KEY_USAGE) +
+ "- " + mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_CRITICAL));
+ if (mExt.isCritical()) {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+
+ PrivateKeyUsageExtension usage = (PrivateKeyUsageExtension) mExt;
+
+ sb.append(pp.indent(mIndentSize + 4) + "Validity:\n");
+
+ if (dateFormater == null) {
+ dateFormater = DateFormat.getDateInstance(DateFormat.FULL);
+ }
+ String notBefore = dateFormater.format(usage.getNotBefore());
+ String notAfter = dateFormater.format(usage.getNotAfter());
+
+ sb.append(pp.indent(mIndentSize + 8) + "Not Before: " + notBefore + "\n");
+ sb.append(pp.indent(mIndentSize + 8) + "Not After: " + notAfter + "\n");
+
+ return sb.toString();
+ } catch (Exception e) {
+ return sb.toString();
+ }
+ }
+
+ private String getExtendedKeyUsageExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(
+ PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_EXTENDED_KEY_USAGE) +
+ "- " + mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_CRITICAL));
+ if (mExt.isCritical()) {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_EXTENDED_KEY_USAGE) + "\n");
+ ExtendedKeyUsageExtension usage = (ExtendedKeyUsageExtension) mExt;
+ Enumeration<ObjectIdentifier> e = usage.getOIDs();
+
+ if (e != null) {
+ while (e.hasMoreElements()) {
+ ObjectIdentifier oid = (ObjectIdentifier) e.nextElement();
+
+ if (oid.equals(ExtendedKeyUsageExtension.OID_OCSP_SIGNING)) {
+ sb.append(pp.indent(mIndentSize + 8) + "OCSPSigning" + "\n");
+ } else {
+ sb.append(pp.indent(mIndentSize + 8) + oid.toString() + "\n");
+ }
+ }
+ }
+ return sb.toString();
+ } catch (Exception e) {
+ return sb.toString();
+ }
+ }
+
+ /**
+ * String Representation of KeyUsageExtension
+ */
+ private String getKeyUsage() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(
+ PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_KEY_USAGE) +
+ "- " + mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_CRITICAL));
+ if (mExt.isCritical()) {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_KEY_USAGE) + "\n");
+ KeyUsageExtension usage = (KeyUsageExtension) mExt;
+
+ if (((Boolean) usage.get(KeyUsageExtension.DIGITAL_SIGNATURE)).booleanValue()) {
+ sb.append(pp.indent(mIndentSize + 8) + mResource.getString(KeyUsageExtension.DIGITAL_SIGNATURE) + "\n");
+ }
+ if (((Boolean) usage.get(KeyUsageExtension.NON_REPUDIATION)).booleanValue()) {
+ sb.append(pp.indent(mIndentSize + 8) + mResource.getString(KeyUsageExtension.NON_REPUDIATION) + "\n");
+ }
+ if (((Boolean) usage.get(KeyUsageExtension.KEY_ENCIPHERMENT)).booleanValue()) {
+ sb.append(pp.indent(mIndentSize + 8) + mResource.getString(KeyUsageExtension.KEY_ENCIPHERMENT) + "\n");
+ }
+ if (((Boolean) usage.get(KeyUsageExtension.DATA_ENCIPHERMENT)).booleanValue()) {
+ sb.append(pp.indent(mIndentSize + 8) + mResource.getString(KeyUsageExtension.DATA_ENCIPHERMENT) + "\n");
+ }
+ if (((Boolean) usage.get(KeyUsageExtension.KEY_AGREEMENT)).booleanValue()) {
+ sb.append(pp.indent(mIndentSize + 8) + mResource.getString(KeyUsageExtension.KEY_AGREEMENT) + "\n");
+ }
+ if (((Boolean) usage.get(KeyUsageExtension.KEY_CERTSIGN)).booleanValue()) {
+ sb.append(pp.indent(mIndentSize + 8) + mResource.getString(KeyUsageExtension.KEY_CERTSIGN) + "\n");
+ }
+ if (((Boolean) usage.get(KeyUsageExtension.CRL_SIGN)).booleanValue()) {
+ sb.append(pp.indent(mIndentSize + 8) + mResource.getString(KeyUsageExtension.CRL_SIGN) + "\n");
+ }
+ if (((Boolean) usage.get(KeyUsageExtension.ENCIPHER_ONLY)).booleanValue()) {
+ sb.append(pp.indent(mIndentSize + 8) + mResource.getString(KeyUsageExtension.ENCIPHER_ONLY) + "\n");
+ }
+ if (((Boolean) usage.get(KeyUsageExtension.DECIPHER_ONLY)).booleanValue()) {
+ sb.append(pp.indent(mIndentSize + 8) + mResource.getString(KeyUsageExtension.DECIPHER_ONLY) + "\n");
+ }
+ return sb.toString();
+ } catch (Exception e) {
+ return sb.toString();
+ }
+
+ }
+
+ /**
+ * String Representation of NSCertTypeExtension
+ */
+ private String getCertType() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_CERT_TYPE)
+ + "- " + mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL));
+ if (mExt.isCritical()) {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CERT_USAGE) + "\n");
+ NSCertTypeExtension type = (NSCertTypeExtension) mExt;
+
+ if (((Boolean) type.get(NSCertTypeExtension.SSL_CLIENT)).booleanValue()) {
+ sb.append(pp.indent(mIndentSize + 8) + mResource.getString(NSCertTypeExtension.SSL_CLIENT) + "\n");
+ }
+ if (((Boolean) type.get(NSCertTypeExtension.SSL_SERVER)).booleanValue()) {
+ sb.append(pp.indent(mIndentSize + 8) + mResource.getString(NSCertTypeExtension.SSL_SERVER) + "\n");
+ }
+ if (((Boolean) type.get(NSCertTypeExtension.EMAIL)).booleanValue()) {
+ sb.append(pp.indent(mIndentSize + 8) + mResource.getString(NSCertTypeExtension.EMAIL) + "\n");
+ }
+ if (((Boolean) type.get(NSCertTypeExtension.OBJECT_SIGNING)).booleanValue()) {
+ sb.append(pp.indent(mIndentSize + 8) + mResource.getString(NSCertTypeExtension.OBJECT_SIGNING) + "\n");
+ }
+ if (((Boolean) type.get(NSCertTypeExtension.SSL_CA)).booleanValue()) {
+ sb.append(pp.indent(mIndentSize + 8) + mResource.getString(NSCertTypeExtension.SSL_CA) + "\n");
+ }
+ if (((Boolean) type.get(NSCertTypeExtension.EMAIL_CA)).booleanValue()) {
+ sb.append(pp.indent(mIndentSize + 8) + mResource.getString(NSCertTypeExtension.EMAIL_CA) + "\n");
+ }
+ if (((Boolean) type.get(NSCertTypeExtension.OBJECT_SIGNING_CA)).booleanValue()) {
+ sb.append(pp.indent(mIndentSize + 8)
+ + mResource.getString(NSCertTypeExtension.OBJECT_SIGNING_CA) + "\n");
+ }
+ return sb.toString();
+ } catch (Exception e) {
+ return "";
+ }
+
+ }
+
+ /**
+ * String Representation of SubjectKeyIdentifierExtension
+ */
+ private String getSubjectKeyIdentifier() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_SKI)
+ + "- " + mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL));
+ if (mExt.isCritical()) {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+ SubjectKeyIdentifierExtension id = (SubjectKeyIdentifierExtension) mExt;
+ KeyIdentifier keyId = (KeyIdentifier) id.get(SubjectKeyIdentifierExtension.KEY_ID);
+
+ if (keyId != null) {
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_KEY_ID) + "\n");
+ sb.append(pp.toHexString(keyId.getIdentifier(), 24, 16));
+ }
+ return sb.toString();
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ /**
+ * String Representation of AuthorityKeyIdentifierExtension
+ */
+ private String getAuthorityKeyIdentifier() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_AKI)
+ + "- " + mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL));
+ if (mExt.isCritical()) {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+ AuthorityKeyIdentifierExtension id = (AuthorityKeyIdentifierExtension) mExt;
+ KeyIdentifier keyId = (KeyIdentifier) id.get(AuthorityKeyIdentifierExtension.KEY_ID);
+
+ if (keyId != null) {
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_KEY_ID) + "\n");
+ sb.append(pp.toHexString(keyId.getIdentifier(), mIndentSize + 8, 16));
+ // sb.append(pp.toHexString(keyId.getIdentifier(),24,16));
+ }
+ GeneralNames authNames = (GeneralNames) id.get(AuthorityKeyIdentifierExtension.AUTH_NAME);
+
+ if (authNames != null) {
+ for (int i = 0; i < authNames.size(); i++) {
+ GeneralName authName = (GeneralName) authNames.elementAt(i);
+
+ if (authName != null) {
+ sb.append(pp.indent(mIndentSize + 4)
+ + mResource.getString(PrettyPrintResources.TOKEN_AUTH_NAME) + authName.toString()
+ + "\n");
+ }
+ }
+ }
+
+ SerialNumber serial = (SerialNumber) id.get(AuthorityKeyIdentifierExtension.SERIAL_NUMBER);
+
+ if (serial != null) {
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_SERIAL) +
+ "0x" + serial.getNumber().toBigInteger().toString(16).toUpperCase() + "\n");
+ }
+ return sb.toString();
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ /**
+ * String Representation of CRLReasonExtension
+ */
+ private String getCRLReasonExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_REVOCATION_REASON) + "- " +
+ mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL));
+ CRLReasonExtension ext = (CRLReasonExtension) mExt;
+
+ if (((Extension) mExt).isCritical()) {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_REASON) +
+ ext.getReason().toString() + "\n");
+
+ return sb.toString();
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ /**
+ * String Representation of InhibitAnyPolicyExtension
+ */
+ private String getInhibitAnyPolicyExtension() {
+ StringBuffer sb = new StringBuffer();
+ try {
+ sb.append(pp.indent(mIndentSize) +
+ mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_INHIBIT_ANY_POLICY_EXT) + "- " +
+ mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) +
+ mResource.getString(PrettyPrintResources.TOKEN_CRITICAL));
+ InhibitAnyPolicyExtension ext = (InhibitAnyPolicyExtension) mExt;
+ if (((Extension) mExt).isCritical())
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_YES) + "\n");
+ else
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_NO) + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_SKIP_CERTS));
+ BigInt num = ext.getSkipCerts();
+ sb.append("" + num.toInt() + "\n");
+ return sb.toString();
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ /**
+ * String Representation of BasicConstraintsExtension
+ */
+ private String getBasicConstraintsExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_BASIC_CONSTRAINTS) + "- " +
+ mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL));
+ BasicConstraintsExtension ext = (BasicConstraintsExtension) mExt;
+
+ if (((Extension) mExt).isCritical()) {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_IS_CA));
+ boolean isCA = ((Boolean) ext.get(BasicConstraintsExtension.IS_CA)).booleanValue();
+
+ if (isCA) {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+ Integer pathLength = (Integer) ext.get(BasicConstraintsExtension.PATH_LEN);
+
+ if (pathLength != null) {
+ if (pathLength.longValue() >= 0) {
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_PATH_LEN) +
+ pathLength.toString() + "\n");
+ } else if (pathLength.longValue() == -1 || pathLength.longValue() == -2) {
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_PATH_LEN) +
+ mResource.getString(PrettyPrintResources.TOKEN_PATH_LEN_UNLIMITED) + "\n");
+ } else {
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_PATH_LEN) +
+ mResource.getString(PrettyPrintResources.TOKEN_PATH_LEN_INVALID) +
+ " (" + pathLength.toString() + ")\n");
+ }
+ }
+
+ return sb.toString();
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ /**
+ * String Representation of CRLNumberExtension
+ */
+ private String getCRLNumberExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_CRL_NUMBER) + "- " +
+ mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL));
+ CRLNumberExtension ext = (CRLNumberExtension) mExt;
+
+ if (((Extension) mExt).isCritical()) {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+ BigInteger crlNumber = (BigInteger) ext.get(CRLNumberExtension.NUMBER);
+
+ if (crlNumber != null) {
+ sb.append(pp.indent(mIndentSize + 4) +
+ mResource.getString(PrettyPrintResources.TOKEN_NUMBER) +
+ crlNumber.toString() + "\n");
+ }
+
+ return sb.toString();
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ /**
+ * String Representation of DeltaCRLIndicatorExtension
+ */
+ private String getDeltaCRLIndicatorExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_DELTA_CRL_INDICATOR) + "- " +
+ mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL));
+ DeltaCRLIndicatorExtension ext = (DeltaCRLIndicatorExtension) mExt;
+
+ if (((Extension) mExt).isCritical()) {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+ BigInteger crlNumber = (BigInteger) ext.get(DeltaCRLIndicatorExtension.NUMBER);
+
+ if (crlNumber != null) {
+ sb.append(pp.indent(mIndentSize + 4) +
+ mResource.getString(PrettyPrintResources.TOKEN_BASE_CRL_NUMBER) +
+ crlNumber.toString() + "\n");
+ }
+
+ return sb.toString();
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ /**
+ * String Representation of IssuerAlternativeName Extension
+ */
+ private String getIssuerAlternativeNameExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_ISSUER_ALT_NAME) + "- " +
+ mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL));
+ IssuerAlternativeNameExtension ext = (IssuerAlternativeNameExtension) mExt;
+
+ if (((Extension) mExt).isCritical()) {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+
+ GeneralNames issuerNames = (GeneralNames) ext.get(IssuerAlternativeNameExtension.ISSUER_NAME);
+
+ if (issuerNames != null) {
+ sb.append(pp.indent(mIndentSize + 4) +
+ mResource.getString(PrettyPrintResources.TOKEN_ISSUER_NAMES) + "\n");
+ for (int i = 0; i < issuerNames.size(); i++) {
+ GeneralName issuerName = (GeneralName) issuerNames.elementAt(i);
+
+ if (issuerName != null) {
+ String nameType = "";
+
+ if (issuerName.getType() == GeneralNameInterface.NAME_DIRECTORY)
+ nameType = "DirectoryName: ";
+ sb.append(pp.indent(mIndentSize + 8) + nameType + issuerName.toString() + "\n");
+ }
+ }
+ }
+
+ return sb.toString();
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ /**
+ * String Representation of SubjectAlternativeName Extension
+ */
+ private String getSubjectAlternativeNameExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_SUBJECT_ALT_NAME) + "- " +
+ mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL));
+ SubjectAlternativeNameExtension ext = (SubjectAlternativeNameExtension) mExt;
+
+ if (((Extension) mExt).isCritical()) {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+
+ GeneralNames subjectNames = (GeneralNames) ext.get(SubjectAlternativeNameExtension.SUBJECT_NAME);
+
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_VALUE) + "\n");
+ for (int i = 0; i < subjectNames.size(); i++) {
+ GeneralName subjectName = (GeneralName) subjectNames.elementAt(i);
+
+ if (subjectName != null) {
+ String nameType = "";
+
+ if (subjectName.getType() == GeneralNameInterface.NAME_DIRECTORY)
+ nameType = "DirectoryName: ";
+ sb.append(pp.indent(mIndentSize + 8) + nameType + subjectName.toString() + "\n");
+ }
+ }
+
+ return sb.toString();
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ /**
+ * String Representation of CertificateScopeOfUse Extension
+ */
+ private String getCertificateScopeOfUseExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_CERT_SCOPE_OF_USE) + "- " +
+ mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL));
+ CertificateScopeOfUseExtension ext = (CertificateScopeOfUseExtension) mExt;
+
+ if (mExt.isCritical()) {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+ Vector<CertificateScopeEntry> entries = ext.getCertificateScopeEntries();
+
+ if (entries != null) {
+ sb.append(pp.indent(mIndentSize + 4) +
+ mResource.getString(PrettyPrintResources.TOKEN_SCOPE_OF_USE) + "\n");
+ for (int i = 0; i < entries.size(); i++) {
+ CertificateScopeEntry se = (CertificateScopeEntry) entries.elementAt(i);
+ GeneralName gn = se.getGeneralName();
+
+ if (gn != null) {
+ String nameType = "";
+
+ if (gn.getType() == GeneralNameInterface.NAME_DIRECTORY)
+ nameType = "DirectoryName: ";
+ sb.append(pp.indent(mIndentSize + 8) + nameType + gn.toString() + "\n");
+ }
+ BigInt port = se.getPort();
+
+ if (port != null) {
+ sb.append(pp.indent(mIndentSize + 8) + PrettyPrintResources.TOKEN_PORT +
+ port.toBigInteger().toString() + "\n");
+ }
+ }
+ }
+ return sb.toString();
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ /**
+ * String Representation of FreshestCRLExtension
+ */
+ private String getFreshestCRLExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+
+ //
+ // Generic stuff: name, OID, criticality
+ //
+ sb.append(pp.indent(mIndentSize) +
+ mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_FRESHEST_CRL_EXT) + "- " +
+ mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) +
+ mResource.getString(PrettyPrintResources.TOKEN_CRITICAL));
+ if (((Extension) mExt).isCritical()) {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+
+ //
+ // Now the CRLDP-specific stuff
+ //
+ FreshestCRLExtension ext = (FreshestCRLExtension) mExt;
+
+ int numPoints = ext.getNumPoints();
+
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_CRLDP_NUMPOINTS)
+ + numPoints + "\n");
+
+ for (int i = 0; i < numPoints; i++) {
+
+ //
+ // print one individual CRL distribution point
+ //
+
+ int idt;
+
+ idt = mIndentSize + 4; // reset each time through loop
+ boolean isEmpty = true;
+
+ sb.append(pp.indent(idt) +
+ mResource.getString(PrettyPrintResources.TOKEN_CRLDP_POINTN) +
+ i + "\n");
+
+ CRLDistributionPoint pt = ext.getPointAt(i);
+
+ idt += 4; // further indent rest of information
+
+ if (pt.getFullName() != null) {
+ isEmpty = false;
+ sb.append(pp.indent(idt) +
+ mResource.getString(PrettyPrintResources.TOKEN_CRLDP_DISTPOINT)
+ + pt.getFullName() + "\n");
+ }
+
+ if (pt.getRelativeName() != null) {
+ isEmpty = false;
+ sb.append(pp.indent(idt) +
+ mResource.getString(PrettyPrintResources.TOKEN_CRLDP_DISTPOINT)
+ + pt.getRelativeName() + "\n");
+ }
+
+ if (pt.getReasons() != null) {
+ isEmpty = false;
+ byte[] reasonBits = pt.getReasons().toByteArray();
+ String reasonList = reasonBitsToReasonList(reasonBits);
+
+ sb.append(pp.indent(idt) +
+ mResource.getString(PrettyPrintResources.TOKEN_CRLDP_REASONS)
+ + reasonList + "\n");
+ }
+
+ if (pt.getCRLIssuer() != null) {
+ isEmpty = false;
+ sb.append(pp.indent(idt) +
+ mResource.getString(PrettyPrintResources.TOKEN_CRLDP_CRLISSUER)
+ + pt.getCRLIssuer() + "\n");
+ }
+
+ if (isEmpty) {
+ sb.append(pp.indent(idt) + "<i>empty</i>\n");
+ }
+
+ }
+
+ return sb.toString();
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ /**
+ * String Representation of CRLDistributionPointsExtension
+ */
+ private String getCRLDistributionPointsExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+
+ //
+ // Generic stuff: name, OID, criticality
+ //
+ sb.append(pp.indent(mIndentSize) +
+ mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_CRL_DP_EXT) + "- " +
+ mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) +
+ mResource.getString(PrettyPrintResources.TOKEN_CRITICAL));
+ if (((Extension) mExt).isCritical()) {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+
+ //
+ // Now the CRLDP-specific stuff
+ //
+ CRLDistributionPointsExtension ext =
+ (CRLDistributionPointsExtension) mExt;
+
+ int numPoints = ext.getNumPoints();
+
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_CRLDP_NUMPOINTS)
+ + numPoints + "\n");
+
+ for (int i = 0; i < numPoints; i++) {
+
+ //
+ // print one individual CRL distribution point
+ //
+
+ int idt;
+
+ idt = mIndentSize + 4; // reset each time through loop
+ boolean isEmpty = true;
+
+ sb.append(pp.indent(idt) +
+ mResource.getString(PrettyPrintResources.TOKEN_CRLDP_POINTN) +
+ i + "\n");
+
+ CRLDistributionPoint pt = ext.getPointAt(i);
+
+ idt += 4; // further indent rest of information
+
+ if (pt.getFullName() != null) {
+ isEmpty = false;
+ sb.append(pp.indent(idt) +
+ mResource.getString(PrettyPrintResources.TOKEN_CRLDP_DISTPOINT)
+ + pt.getFullName() + "\n");
+ }
+
+ if (pt.getRelativeName() != null) {
+ isEmpty = false;
+ sb.append(pp.indent(idt) +
+ mResource.getString(PrettyPrintResources.TOKEN_CRLDP_DISTPOINT)
+ + pt.getRelativeName() + "\n");
+ }
+
+ if (pt.getReasons() != null) {
+ isEmpty = false;
+ byte[] reasonBits = pt.getReasons().toByteArray();
+ String reasonList = reasonBitsToReasonList(reasonBits);
+
+ sb.append(pp.indent(idt) +
+ mResource.getString(PrettyPrintResources.TOKEN_CRLDP_REASONS)
+ + reasonList + "\n");
+ }
+
+ if (pt.getCRLIssuer() != null) {
+ isEmpty = false;
+ sb.append(pp.indent(idt) +
+ mResource.getString(PrettyPrintResources.TOKEN_CRLDP_CRLISSUER)
+ + pt.getCRLIssuer() + "\n");
+ }
+
+ if (isEmpty) {
+ sb.append(pp.indent(idt) + "<i>empty</i>\n");
+ }
+
+ }
+
+ return sb.toString();
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ private static String reasonBitsToReasonList(byte[] reasonBits) {
+
+ Reason[] reasons = Reason.bitArrayToReasonArray(reasonBits);
+
+ if (reasons.length == 0) {
+ return "";
+ } else {
+ StringBuffer buf = new StringBuffer();
+
+ buf.append(reasons[0].getName());
+ for (int i = 1; i < reasons.length; i++) {
+ buf.append(", ");
+ buf.append(reasons[i].getName());
+ }
+ return buf.toString();
+ }
+ }
+
+ /**
+ * String Representation of IssuerAlternativeName Extension
+ */
+ private String getIssuingDistributionPointExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_ISSUING_DIST_POINT) + "- " +
+ mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL));
+ if (((Extension) mExt).isCritical()) {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+
+ IssuingDistributionPointExtension ext = (IssuingDistributionPointExtension) mExt;
+ IssuingDistributionPoint issuingDistributionPoint = ext.getIssuingDistributionPoint();
+
+ if (issuingDistributionPoint != null) {
+ GeneralNames fullNames = issuingDistributionPoint.getFullName();
+ RDN relativeName = issuingDistributionPoint.getRelativeName();
+
+ if (fullNames != null || relativeName != null) {
+ sb.append(pp.indent(mIndentSize + 4)
+ + mResource.getString(PrettyPrintResources.TOKEN_DIST_POINT_NAME) + "\n");
+ if (fullNames != null) {
+ sb.append(pp.indent(mIndentSize + 8)
+ + mResource.getString(PrettyPrintResources.TOKEN_FULL_NAME) + "\n");
+ for (int i = 0; i < fullNames.size(); i++) {
+ GeneralName fullName = (GeneralName) fullNames.elementAt(i);
+
+ if (fullName != null) {
+ sb.append(pp.indent(mIndentSize + 12) + fullName.toString() + "\n");
+ }
+ }
+ }
+ if (relativeName != null) {
+ sb.append(pp.indent(mIndentSize + 8)
+ + mResource.getString(PrettyPrintResources.TOKEN_RELATIVE_NAME) +
+ relativeName.toString() + "\n");
+ }
+ }
+
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_ONLY_USER_CERTS));
+ if (issuingDistributionPoint.getOnlyContainsUserCerts()) {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_ONLY_CA_CERTS));
+ if (issuingDistributionPoint.getOnlyContainsCACerts()) {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+
+ BitArray onlySomeReasons = issuingDistributionPoint.getOnlySomeReasons();
+
+ if (onlySomeReasons != null) {
+ sb.append(pp.indent(mIndentSize + 4)
+ + mResource.getString(PrettyPrintResources.TOKEN_ONLY_SOME_REASONS));
+ sb.append("0x" + pp.toHexString(onlySomeReasons.toByteArray()));
+ }
+
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_INDIRECT_CRL));
+ if (issuingDistributionPoint.getIndirectCRL()) {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+ }
+
+ return sb.toString();
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ /**
+ * String Representation of InvalidityDateExtension
+ */
+ private String getInvalidityDateExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(
+ PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_INVALIDITY_DATE) +
+ "- " + mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_CRITICAL));
+ InvalidityDateExtension ext = (InvalidityDateExtension) mExt;
+
+ if (((Extension) mExt).isCritical()) {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_DATE_OF_INVALIDITY) +
+ ext.getInvalidityDate().toString() + "\n");
+ return sb.toString();
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ /**
+ * String Representation of CertificateIssuerExtension
+ */
+ private String getCertificateIssuerExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(
+ PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_CERTIFICATE_ISSUER) +
+ "- " + mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_CRITICAL));
+ CertificateIssuerExtension ext = (CertificateIssuerExtension) mExt;
+
+ if (((Extension) mExt).isCritical()) {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+
+ GeneralNames issuerNames = (GeneralNames) ext.get(
+ CertificateIssuerExtension.CERTIFICATE_ISSUER);
+
+ if (issuerNames != null) {
+ sb.append(pp.indent(mIndentSize + 4) +
+ mResource.getString(PrettyPrintResources.TOKEN_ISSUER_NAMES) + "\n");
+ for (int i = 0; i < issuerNames.size(); i++) {
+ GeneralName issuerName = (GeneralName) issuerNames.elementAt(i);
+
+ if (issuerName != null) {
+ String nameType = "";
+
+ if (issuerName.getType() == GeneralNameInterface.NAME_DIRECTORY)
+ nameType = "DirectoryName: ";
+ sb.append(pp.indent(mIndentSize + 8) + nameType + issuerName.toString() + "\n");
+ }
+ }
+ }
+
+ return sb.toString();
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ /**
+ * String Representation of HoldInstructionExtension
+ */
+ private String getHoldInstructionExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(
+ PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_HOLD_INSTRUCTION) +
+ "- " + mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_CRITICAL));
+ HoldInstructionExtension ext = (HoldInstructionExtension) mExt;
+
+ if (((Extension) mExt).isCritical()) {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_HOLD_INSTRUCTION_CODE) +
+ ext.getHoldInstructionCodeDescription() + "\n");
+ return sb.toString();
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ /**
+ * String Representation of PolicyConstraintsExtension
+ */
+ private String getPolicyConstraintsExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(
+ PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(
+ mResource.getString(
+ PrettyPrintResources.TOKEN_POLICY_CONSTRAINTS) +
+ "- " + mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_CRITICAL));
+ if (((Extension) mExt).isCritical()) {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+
+ PolicyConstraintsExtension ext = (PolicyConstraintsExtension) mExt;
+ int require = ext.getRequireExplicitMapping();
+ int inhibit = ext.getInhibitPolicyMapping();
+
+ sb.append(
+ pp.indent(mIndentSize + 4) +
+ mResource.getString(
+ PrettyPrintResources.TOKEN_REQUIRE_EXPLICIT_POLICY) +
+ ((require == -1) ?
+ mResource.getString(PrettyPrintResources.TOKEN_NOT_SET) :
+ String.valueOf(require)) + "\n");
+ sb.append(
+ pp.indent(mIndentSize + 4) +
+ mResource.getString(
+ PrettyPrintResources.TOKEN_INHIBIT_POLICY_MAPPING) +
+ ((inhibit == -1) ?
+ mResource.getString(PrettyPrintResources.TOKEN_NOT_SET) :
+ String.valueOf(inhibit)) + "\n");
+ return sb.toString();
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ /**
+ * String Representation of PolicyMappingsExtension
+ */
+ private String getPolicyMappingsExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(
+ PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_POLICY_MAPPINGS) +
+ "- " + mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_CRITICAL));
+ if (((Extension) mExt).isCritical()) {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+
+ PolicyMappingsExtension ext = (PolicyMappingsExtension) mExt;
+ Enumeration<CertificatePolicyMap> maps = ext.getMappings();
+
+ sb.append(pp.indent(mIndentSize + 4) +
+ mResource.getString(PrettyPrintResources.TOKEN_MAPPINGS));
+ if (maps == null || !maps.hasMoreElements()) {
+ sb.append(
+ mResource.getString(PrettyPrintResources.TOKEN_NONE) + "\n");
+ } else {
+ sb.append("\n");
+ for (int i = 0; maps.hasMoreElements(); i++) {
+ sb.append(pp.indent(mIndentSize + 8) +
+ mResource.getString(
+ PrettyPrintResources.TOKEN_MAP) + i + ":" + "\n");
+ CertificatePolicyMap m =
+ (CertificatePolicyMap) maps.nextElement();
+
+ sb.append(pp.indent(mIndentSize + 12) +
+ mResource.getString(
+ PrettyPrintResources.TOKEN_ISSUER_DOMAIN_POLICY) +
+ m.getIssuerIdentifier().getIdentifier().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 12) +
+ mResource.getString(
+ PrettyPrintResources.TOKEN_SUBJECT_DOMAIN_POLICY) +
+ m.getSubjectIdentifier().getIdentifier().toString() + "\n");
+ }
+ }
+ return sb.toString();
+ } catch (Throwable e) {
+ return "";
+ }
+ }
+
+ /**
+ * String Representation of SubjectDirAttributesExtension
+ */
+ private String getSubjectDirAttributesExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(
+ PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_SUBJECT_DIR_ATTR) +
+ "- " + mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) +
+ mResource.getString(PrettyPrintResources.TOKEN_CRITICAL));
+ if (((Extension) mExt).isCritical()) {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+
+ SubjectDirAttributesExtension ext =
+ (SubjectDirAttributesExtension) mExt;
+
+ sb.append(pp.indent(mIndentSize + 4) +
+ mResource.getString(PrettyPrintResources.TOKEN_ATTRIBUTES));
+ Enumeration<Attribute> attrs = ext.getAttributesList();
+
+ if (attrs == null || !attrs.hasMoreElements()) {
+ sb.append(
+ mResource.getString(PrettyPrintResources.TOKEN_NONE) + "\n");
+ } else {
+ sb.append("\n");
+ for (int j = 0; attrs.hasMoreElements(); j++) {
+ Attribute attr = (Attribute) attrs.nextElement();
+
+ sb.append(pp.indent(mIndentSize + 8) +
+ mResource.getString(
+ PrettyPrintResources.TOKEN_ATTRIBUTE) + j + ":" + "\n");
+ sb.append(pp.indent(mIndentSize + 12) +
+ mResource.getString(
+ PrettyPrintResources.TOKEN_IDENTIFIER) +
+ attr.getOid().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 12) +
+ mResource.getString(
+ PrettyPrintResources.TOKEN_VALUES));
+ Enumeration<String> values = attr.getValues();
+
+ if (values == null || !values.hasMoreElements()) {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_NONE) + "\n");
+ } else {
+ for (int k = 0; values.hasMoreElements(); k++) {
+ String v = (String) values.nextElement();
+
+ if (k != 0)
+ sb.append(",");
+ sb.append(v);
+ }
+ }
+ sb.append("\n");
+ }
+ }
+ return sb.toString();
+ } catch (Throwable e) {
+ return "";
+ }
+ }
+
+ private String getCertificatePoliciesExtension() {
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ sb.append(pp.indent(mIndentSize) + mResource.getString(
+ PrettyPrintResources.TOKEN_IDENTIFIER));
+ sb.append(mResource.getString(PrettyPrintResources.TOKEN_CERT_POLICIES) +
+ "- " + mExt.getExtensionId().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_CRITICAL));
+ if (mExt.isCritical()) {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_YES) + "\n");
+ } else {
+ sb.append(mResource.getString(
+ PrettyPrintResources.TOKEN_NO) + "\n");
+ }
+ sb.append(pp.indent(mIndentSize + 4) + mResource.getString(
+ PrettyPrintResources.TOKEN_CERT_POLICIES) + "\n");
+ CertificatePoliciesExtension cp = (CertificatePoliciesExtension) mExt;
+ @SuppressWarnings("unchecked")
+ Vector<CertificatePolicyInfo> cpv = (Vector<CertificatePolicyInfo>) cp.get("infos");
+ Enumeration<CertificatePolicyInfo> e = cpv.elements();
+
+ if (e != null) {
+ while (e.hasMoreElements()) {
+ CertificatePolicyInfo cpi = e.nextElement();
+
+ sb.append(pp.indent(mIndentSize + 8)
+ + "Policy Identifier: " + cpi.getPolicyIdentifier().getIdentifier().toString() + "\n");
+ PolicyQualifiers cpq = cpi.getPolicyQualifiers();
+ if (cpq != null) {
+ for (int i = 0; i < cpq.size(); i++) {
+ PolicyQualifierInfo pq = cpq.getInfoAt(i);
+ Qualifier q = pq.getQualifier();
+ if (q instanceof CPSuri) {
+ sb.append(pp.indent(mIndentSize + 12)
+ + "Policy Qualifier Identifier: CPS Pointer Qualifier - "
+ + pq.getId() + "\n");
+ sb.append(pp.indent(mIndentSize + 12)
+ + "Policy Qualifier Data: " + ((CPSuri) q).getURI() + "\n");
+ } else if (q instanceof UserNotice) {
+ sb.append(pp.indent(mIndentSize + 12)
+ + "Policy Qualifier Identifier: CPS User Notice Qualifier - "
+ + pq.getId() + "\n");
+ NoticeReference nref = ((UserNotice) q).getNoticeReference();
+ DisplayText dt = ((UserNotice) q).getDisplayText();
+ sb.append(pp.indent(mIndentSize + 12) + "Policy Qualifier Data: \n");
+ if (nref != null) {
+ sb.append(pp.indent(mIndentSize + 16)
+ + "Organization: " + nref.getOrganization().toString() + "\n");
+ sb.append(pp.indent(mIndentSize + 16) + "Notice Numbers: ");
+ int[] nums = nref.getNumbers();
+ for (int k = 0; k < nums.length; k++) {
+ if (k != 0) {
+ sb.append(",");
+ sb.append(nums[k]);
+ } else {
+ sb.append(nums[k]);
+ }
+ }
+ sb.append("\n");
+ }
+ if (dt != null) {
+ sb.append(pp.indent(mIndentSize + 16) + "Explicit Text: " + dt.toString() + "\n");
+ }
+ }
+ }
+ }
+ }
+ }
+ return sb.toString();
+ } catch (Exception e) {
+ return sb.toString();
+ }
+ }
+
+}
diff --git a/base/util/src/netscape/security/util/IA5Charset.java b/base/util/src/netscape/security/util/IA5Charset.java
new file mode 100644
index 000000000..db6da2331
--- /dev/null
+++ b/base/util/src/netscape/security/util/IA5Charset.java
@@ -0,0 +1,24 @@
+package netscape.security.util;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+
+public class IA5Charset extends Charset {
+
+ public IA5Charset() {
+ super("ASN.1-IA5", null);
+ }
+
+ public boolean contains(Charset cs) {
+ return false;
+ }
+
+ public CharsetDecoder newDecoder() {
+ return new IA5CharsetDecoder(this);
+ }
+
+ public CharsetEncoder newEncoder() {
+ return new IA5CharsetEncoder(this);
+ }
+}
diff --git a/base/util/src/netscape/security/util/IA5CharsetDecoder.java b/base/util/src/netscape/security/util/IA5CharsetDecoder.java
new file mode 100644
index 000000000..620d65aca
--- /dev/null
+++ b/base/util/src/netscape/security/util/IA5CharsetDecoder.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 netscape.security.util;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+
+/**
+ * Converts bytes in ASN.1 IA5String character set to IA5String characters.
+ *
+ * @author Lily Hsiao
+ * @author Slava Galperin
+ */
+
+public class IA5CharsetDecoder extends CharsetDecoder {
+
+ public IA5CharsetDecoder(Charset cs) {
+ super(cs, 1, 1);
+ }
+
+ protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
+
+ while (true) {
+
+ if (in.remaining() < 1)
+ return CoderResult.UNDERFLOW;
+
+ in.mark();
+ byte b = in.get();
+
+ if (CodingErrorAction.REPORT == unmappableCharacterAction() && (b & 0x80) != 0) {
+ return CoderResult.unmappableForLength(1);
+ }
+
+ if (out.remaining() < 1) {
+ in.reset();
+ return CoderResult.OVERFLOW;
+ }
+
+ out.put((char) (b & 0x7f));
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/util/IA5CharsetEncoder.java b/base/util/src/netscape/security/util/IA5CharsetEncoder.java
new file mode 100644
index 000000000..dad0c9a2d
--- /dev/null
+++ b/base/util/src/netscape/security/util/IA5CharsetEncoder.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 netscape.security.util;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+
+/**
+ * Converts characters in ASN.1 IA5String character set to IA5String bytes.
+ *
+ * @author Lily Hsiao
+ * @author Slava Galperin
+ */
+
+public class IA5CharsetEncoder extends CharsetEncoder {
+
+ public IA5CharsetEncoder(Charset cs) {
+ super(cs, 1, 1);
+ }
+
+ /*
+ * Converts an array of Unicode characters into an array of IA5String
+ * bytes and returns the conversion result.
+ * @param in input character buffer to convert.
+ * @param out byte buffer to store output.
+ * @return encoding result.
+ */
+ protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
+
+ while (true) {
+
+ if (in.remaining() < 1)
+ return CoderResult.UNDERFLOW;
+
+ in.mark();
+ char c = in.get();
+
+ if (CodingErrorAction.REPORT == unmappableCharacterAction() && (c & 0xFF80) != 0) {
+ return CoderResult.unmappableForLength(1);
+ }
+
+ if (out.remaining() < 1) {
+ in.reset();
+ return CoderResult.OVERFLOW;
+ }
+
+ out.put((byte) (c & 0x7f));
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/util/ObjectIdentifier.java b/base/util/src/netscape/security/util/ObjectIdentifier.java
new file mode 100644
index 000000000..6ff02d1b0
--- /dev/null
+++ b/base/util/src/netscape/security/util/ObjectIdentifier.java
@@ -0,0 +1,426 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.util;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+
+/**
+ * Represent an ISO Object Identifier.
+ *
+ * <P>
+ * Object Identifiers are arbitrary length hierarchical identifiers. The individual components are numbers, and they
+ * define paths from the root of an ISO-managed identifier space. You will sometimes see a string name used instead of
+ * (or in addition to) the numerical id. These are synonyms for the numerical IDs, but are not widely used since most
+ * sites do not know all the requisite strings, while all sites can parse the numeric forms.
+ *
+ * <P>
+ * So for example, JavaSoft has the sole authority to assign the meaning to identifiers below the 1.3.6.1.4.42.2.17 node
+ * in the hierarchy, and other organizations can easily acquire the ability to assign such unique identifiers.
+ *
+ * @version 1.23
+ *
+ * @author David Brownell
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ */
+final public class ObjectIdentifier implements Serializable {
+ /** use serialVersionUID from JDK 1.1. for interoperability */
+ private static final long serialVersionUID = 8697030238860181294L;
+
+ /**
+ * Constructs an object identifier from a string. This string
+ * should be of the form 1.23.34.45.56 etc.
+ */
+ public ObjectIdentifier(String oid) {
+ if (oid == null)
+ return;
+
+ int ch = '.';
+ int start = 0;
+ int end = 0;
+
+ // Calculate length of oid
+ componentLen = 0;
+ while ((end = oid.indexOf(ch, start)) != -1) {
+ start = end + 1;
+ componentLen += 1;
+ }
+ componentLen += 1;
+ components = new int[componentLen];
+
+ start = 0;
+ int i = 0;
+ String comp = null;
+ while ((end = oid.indexOf(ch, start)) != -1) {
+ comp = oid.substring(start, end);
+ components[i++] = Integer.valueOf(comp).intValue();
+ start = end + 1;
+ }
+ comp = oid.substring(start);
+ components[i] = Integer.valueOf(comp).intValue();
+ }
+
+ /**
+ * Constructs an object ID from an array of integers. This
+ * is used to construct constant object IDs.
+ */
+ public ObjectIdentifier(int values[]) {
+ try {
+ components = (int[]) values.clone();
+ componentLen = values.length;
+ } catch (Throwable t) {
+ System.out.println("X509.ObjectIdentifier(), no cloning!");
+ }
+ }
+
+ /**
+ * Constructs an object ID from an ASN.1 encoded input stream.
+ * The encoding of the ID in the stream uses "DER", a BER/1 subset.
+ * In this case, that means a triple { typeId, length, data }.
+ *
+ * <P>
+ * <STRONG>NOTE:</STRONG> When an exception is thrown, the input stream has not been returned to its "initial"
+ * state.
+ *
+ * @param in DER-encoded data holding an object ID
+ * @exception IOException indicates a decoding error
+ */
+ public ObjectIdentifier(DerInputStream in)
+ throws IOException {
+ byte type_id;
+ int bufferEnd;
+
+ /*
+ * Object IDs are a "universal" type, and their tag needs only
+ * one byte of encoding. Verify that the tag of this datum
+ * is that of an object ID.
+ *
+ * Then get and check the length of the ID's encoding. We set
+ * up so that we can use in.available() to check for the end of
+ * this value in the data stream.
+ */
+ type_id = (byte) in.getByte();
+ if (type_id != DerValue.tag_ObjectId)
+ throw new IOException(
+ "X509.ObjectIdentifier() -- data isn't an object ID"
+ + " (tag = " + type_id + ")");
+
+ bufferEnd = in.available() - in.getLength() - 1;
+ if (bufferEnd < 0)
+ throw new IOException(
+ "X509.ObjectIdentifier() -- not enough data");
+
+ initFromEncoding(in, bufferEnd);
+ }
+
+ /*
+ * Build the OID from the rest of a DER input buffer; the tag
+ * and length have been removed/verified
+ */
+ ObjectIdentifier(DerInputBuffer buf) throws IOException {
+ initFromEncoding(new DerInputStream(buf), 0);
+ }
+
+ /*
+ * Helper function -- get the OID from a stream, after tag and
+ * length are verified.
+ */
+ private void initFromEncoding(DerInputStream in, int bufferEnd)
+ throws IOException {
+
+ /*
+ * Now get the components ("sub IDs") one at a time. We fill a
+ * temporary buffer, resizing it as needed.
+ */
+ int component;
+ boolean first_subid = true;
+
+ for (components = new int[allocationQuantum], componentLen = 0; in.available() > bufferEnd;) {
+ component = getComponent(in);
+
+ if (first_subid) {
+ int X, Y;
+
+ /*
+ * The ISO root has three children (0, 1, 2) and those nodes
+ * aren't allowed to assign IDs larger than 39. These rules
+ * are memorialized by some special casing in the BER encoding
+ * of object IDs ... or maybe it's vice versa.
+ *
+ * NOTE: the allocation quantum is large enough that we know
+ * we don't have to reallocate here!
+ */
+ if (component < 40)
+ X = 0;
+ else if (component < 80)
+ X = 1;
+ else
+ X = 2;
+ Y = component - (X * 40);
+
+ components[0] = X;
+ components[1] = Y;
+ componentLen = 2;
+
+ first_subid = false;
+
+ } else {
+
+ /*
+ * Other components are encoded less exotically. The only
+ * potential trouble is the need to grow the array.
+ */
+ if (componentLen >= components.length) {
+ int tmp_components[];
+
+ tmp_components = new int[components.length
+ + allocationQuantum];
+ System.arraycopy(components, 0, tmp_components, 0,
+ components.length);
+ components = tmp_components;
+ }
+ components[componentLen++] = component;
+ }
+ }
+
+ /*
+ * Final sanity check -- if we didn't use exactly the number of bytes
+ * specified, something's quite wrong.
+ */
+ if (in.available() != bufferEnd) {
+ throw new IOException(
+ "X509.ObjectIdentifier() -- malformed input data");
+ }
+ }
+
+ /*
+ * n.b. the only public interface is DerOutputStream.putOID()
+ */
+ void encode(DerOutputStream out) throws IOException {
+ DerOutputStream bytes = new DerOutputStream();
+ int i;
+
+ bytes.write((components[0] * 40) + components[1]);
+ for (i = 2; i < componentLen; i++)
+ putComponent(bytes, components[i]);
+
+ /*
+ * Now that we've constructed the component, encode
+ * it in the stream we were given.
+ */
+ out.write(DerValue.tag_ObjectId, bytes);
+ }
+
+ /*
+ * Tricky OID component parsing technique ... note that one bit
+ * per octet is lost, this returns at most 28 bits of component.
+ * Also, notice this parses in big-endian format.
+ */
+ private static int getComponent(DerInputStream in)
+ throws IOException {
+ int retval, i, tmp;
+
+ for (i = 0, retval = 0; i < 4; i++) {
+ retval <<= 7;
+ tmp = in.getByte();
+ retval |= (tmp & 0x07f);
+ if ((tmp & 0x080) == 0)
+ return retval;
+ }
+
+ throw new IOException("X509.OID, component value too big");
+ }
+
+ /*
+ * Reverse of the above routine. Notice it needs to emit in
+ * big-endian form, so it buffers the output until it's ready.
+ * (Minimum length encoding is a DER requirement.)
+ */
+ private static void putComponent(DerOutputStream out, int val)
+ throws IOException {
+ int i;
+ byte buf[] = new byte[4];
+
+ for (i = 0; i < 4; i++) {
+ buf[i] = (byte) (val & 0x07f);
+ val >>>= 7;
+ if (val == 0)
+ break;
+ }
+ for (; i > 0; --i)
+ out.write(buf[i] | 0x080);
+ out.write(buf[0]);
+ }
+
+ // XXX this API should probably facilitate the JDK sort utility
+
+ /**
+ * Compares this identifier with another, for sorting purposes.
+ * An identifier does not precede itself.
+ *
+ * @param other identifer that may precede this one.
+ * @return true iff <em>other</em> precedes this one
+ * in a particular sorting order.
+ */
+ public boolean precedes(ObjectIdentifier other) {
+ int i;
+
+ // shorter IDs go first
+ if (other == this || componentLen < other.componentLen)
+ return false;
+ if (other.componentLen < componentLen)
+ return true;
+
+ // for each component, the lesser component goes first
+ for (i = 0; i < componentLen; i++) {
+ if (other.components[i] < components[i])
+ return true;
+ }
+
+ // identical IDs don't precede each other
+ return false;
+ }
+
+ public boolean equals(Object other) {
+ if (other instanceof ObjectIdentifier)
+ return equals((ObjectIdentifier) other);
+ else
+ return false;
+ }
+
+ /**
+ * Compares this identifier with another, for equality.
+ *
+ * @return true iff the names are identical.
+ */
+ public boolean equals(ObjectIdentifier other) {
+ int i;
+
+ if (other == this)
+ return true;
+ if (componentLen != other.componentLen)
+ return false;
+ for (i = 0; i < componentLen; i++) {
+ if (components[i] != other.components[i])
+ return false;
+ }
+ return true;
+ }
+
+ public int hashCode() {
+ int h = 0;
+ int oflow = 0;
+
+ for (int i = 0; i < componentLen; i++) {
+ oflow = (h & 0xff800000) >> 23;
+ h <<= 9;
+ h += components[i];
+ h ^= oflow;
+ }
+ return h;
+ }
+
+ /**
+ * Returns a string form of the object ID. The format is the
+ * conventional "dot" notation for such IDs, without any
+ * user-friendly descriptive strings, since those strings
+ * will not be understood everywhere.
+ */
+ public String toString() {
+ String retval;
+ int i;
+
+ for (i = 0, retval = ""; i < componentLen; i++) {
+ if (i != 0)
+ retval += ".";
+ retval += components[i];
+ }
+ return retval;
+ }
+
+ /*
+ * To simplify, we assume no individual component of an object ID is
+ * larger than 32 bits. Then we represent the path from the root as
+ * an array that's (usually) only filled at the beginning.
+ */
+ private int components[]; // path from root
+ private int componentLen; // how much is used.
+
+ private static final int allocationQuantum = 5; // >= 2
+
+ /**
+ * Netscape Enhancement:
+ * This function implements a object identifier factory. It
+ * should help reduces in-memory Object Identifier object.
+ * This function also provide additional checking on the OID.
+ * A valid OID should start with 0, 1, or 2.
+ *
+ * Notes:
+ * This function never returns null. IOException is raised
+ * in error conditions.
+ */
+ public static Hashtable<String, ObjectIdentifier> mOIDs = new Hashtable<String, ObjectIdentifier>();
+
+ public static ObjectIdentifier getObjectIdentifier(String oid)
+ throws IOException {
+ int value;
+
+ if (oid == null)
+ throw new IOException("empty object identifier");
+
+ oid = oid.trim();
+
+ ObjectIdentifier thisOID = mOIDs.get(oid);
+ if (thisOID != null)
+ return thisOID;
+
+ StringTokenizer token = new StringTokenizer(oid, ".");
+ value = new Integer(token.nextToken()).intValue();
+ /* First token should be 0, 1, 2 */
+ if (value >= 0 && value <= 2) {
+ value = new Integer(token.nextToken()).intValue();
+ /* Second token should be 0 <= && >= 39 */
+ if (value >= 0 && value <= 39) {
+ thisOID = new ObjectIdentifier(oid);
+ if (thisOID.toString().equals(oid)) {
+ mOIDs.put(oid, thisOID);
+ return thisOID;
+ }
+ throw new IOException("invalid oid " + oid);
+ } else
+ throw new IOException("invalid oid " + oid);
+ } else
+ throw new IOException("invalid oid " + oid);
+ }
+
+ public static ObjectIdentifier getObjectIdentifier(int values[])
+ throws IOException {
+ String retval;
+ int i;
+
+ for (i = 0, retval = ""; i < values.length; i++) {
+ if (i != 0)
+ retval += ".";
+ retval += values[i];
+ }
+ return getObjectIdentifier(retval);
+ }
+}
diff --git a/base/util/src/netscape/security/util/PrettyPrintFormat.java b/base/util/src/netscape/security/util/PrettyPrintFormat.java
new file mode 100644
index 000000000..25bc23d26
--- /dev/null
+++ b/base/util/src/netscape/security/util/PrettyPrintFormat.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 netscape.security.util;
+
+/**
+ * This class will display the certificate content in predefined
+ * format.
+ *
+ * @author Andrew Wnuk
+ * @version $Revision$, $Date$
+ */
+public class PrettyPrintFormat {
+
+ /*==========================================================
+ * 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/base/util/src/netscape/security/util/PrettyPrintResources.java b/base/util/src/netscape/security/util/PrettyPrintResources.java
new file mode 100644
index 000000000..a3f068f64
--- /dev/null
+++ b/base/util/src/netscape/security/util/PrettyPrintResources.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 netscape.security.util;
+
+import java.util.ListResourceBundle;
+
+import netscape.security.extensions.NSCertTypeExtension;
+import netscape.security.x509.KeyUsageExtension;
+
+/**
+ * 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_CERT_POLICIES = "tokenCertPolicies";
+ public final static String TOKEN_SIA = "tokenSIA";
+ 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_INHIBIT_ANY_POLICY_EXT = "InhibitAnyPolicy";
+ public final static String TOKEN_SKIP_CERTS = "SkipCerts";
+
+ 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_CERT_POLICIES, "Certificate Policies: " },
+ { TOKEN_SIA, "Subject 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_INHIBIT_ANY_POLICY_EXT, "Inhibit Any-Policy " },
+ { TOKEN_SKIP_CERTS, "Skip Certs: " },
+ { 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/base/util/src/netscape/security/util/PrintableCharset.java b/base/util/src/netscape/security/util/PrintableCharset.java
new file mode 100644
index 000000000..a9cf15c04
--- /dev/null
+++ b/base/util/src/netscape/security/util/PrintableCharset.java
@@ -0,0 +1,46 @@
+package netscape.security.util;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+
+public class PrintableCharset extends Charset {
+
+ public PrintableCharset() {
+ super("ASN.1-Printable", null);
+ }
+
+ public static boolean isPrintableChar(char c) {
+ if ((c < 'A' || c > 'Z') &&
+ (c < 'a' || c > 'z') &&
+ (c < '0' || c > '9') &&
+ (c != ' ') &&
+ (c != '\'') &&
+ (c != '(') &&
+ (c != ')') &&
+ (c != '+') &&
+ (c != ',') &&
+ (c != '-') &&
+ (c != '.') &&
+ (c != '/') &&
+ (c != ':') &&
+ (c != '=') &&
+ (c != '?')) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ public boolean contains(Charset cs) {
+ return false;
+ }
+
+ public CharsetDecoder newDecoder() {
+ return new PrintableCharsetDecoder(this);
+ }
+
+ public CharsetEncoder newEncoder() {
+ return new PrintableCharsetEncoder(this);
+ }
+}
diff --git a/base/util/src/netscape/security/util/PrintableCharsetDecoder.java b/base/util/src/netscape/security/util/PrintableCharsetDecoder.java
new file mode 100644
index 000000000..014095494
--- /dev/null
+++ b/base/util/src/netscape/security/util/PrintableCharsetDecoder.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 netscape.security.util;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+
+/**
+ * Converts bytes in ASN.1 PrintableString character set to PrintableString
+ * characters.
+ *
+ * @author Lily Hsiao
+ * @author Slava Galperin
+ */
+
+public class PrintableCharsetDecoder extends CharsetDecoder {
+
+ public PrintableCharsetDecoder(Charset cs) {
+ super(cs, 1, 1);
+ }
+
+ protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
+
+ while (true) {
+
+ if (in.remaining() < 1)
+ return CoderResult.UNDERFLOW;
+
+ in.mark();
+ byte b = in.get();
+ char c = (char) (b & 0x7f);
+
+ if (CodingErrorAction.REPORT == unmappableCharacterAction() &&
+ !PrintableCharset.isPrintableChar(c)) {
+ /*
+ "bug" fix for 359010
+ return CoderResult.unmappableForLength(1);
+ */
+ continue;
+ }
+
+ if (out.remaining() < 1) {
+ in.reset();
+ return CoderResult.OVERFLOW;
+ }
+
+ out.put(c);
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/util/PrintableCharsetEncoder.java b/base/util/src/netscape/security/util/PrintableCharsetEncoder.java
new file mode 100644
index 000000000..bc658096a
--- /dev/null
+++ b/base/util/src/netscape/security/util/PrintableCharsetEncoder.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 netscape.security.util;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+
+/**
+ * Converts characters in ASN.1 PrintableString character set to PrintableString
+ * bytes.
+ *
+ * @author Lily Hsiao
+ * @author Slava Galperin
+ */
+
+public class PrintableCharsetEncoder extends CharsetEncoder {
+
+ public PrintableCharsetEncoder(Charset cs) {
+ super(cs, 1, 1);
+ }
+
+ /*
+ * Converts an array of Unicode characters into an array of PrintableString
+ * bytes and returns the conversion result.
+ * @param in input character buffer to convert.
+ * @param out byte buffer to store output.
+ * @return encoding result.
+ */
+ protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
+
+ while (true) {
+
+ if (in.remaining() < 1)
+ return CoderResult.UNDERFLOW;
+
+ in.mark();
+ char c = in.get();
+
+ if (CodingErrorAction.REPORT == unmappableCharacterAction() &&
+ !PrintableCharset.isPrintableChar(c)) {
+ return CoderResult.unmappableForLength(1);
+ }
+
+ if (out.remaining() < 1) {
+ in.reset();
+ return CoderResult.OVERFLOW;
+ }
+
+ out.put((byte) (c & 0x7f));
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/util/PubKeyPrettyPrint.java b/base/util/src/netscape/security/util/PubKeyPrettyPrint.java
new file mode 100644
index 000000000..46c007cd9
--- /dev/null
+++ b/base/util/src/netscape/security/util/PubKeyPrettyPrint.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 netscape.security.util;
+
+import java.security.PublicKey;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+import netscape.security.provider.RSAPublicKey;
+import netscape.security.x509.X509Key;
+
+/**
+ * This class will display the certificate content in predefined
+ * format.
+ *
+ * @author Jack Pan-Chen
+ * @author Andrew Wnuk
+ * @version $Revision$, $Date$
+ */
+public class PubKeyPrettyPrint {
+
+ /*==========================================================
+ * variables
+ *==========================================================*/
+ private X509Key mX509Key = null;
+ private PrettyPrintFormat pp = null;
+
+ /*==========================================================
+ * constructors
+ *==========================================================*/
+
+ public PubKeyPrettyPrint(PublicKey key) {
+ if (key instanceof X509Key)
+ mX509Key = (X509Key) key;
+
+ pp = new PrettyPrintFormat(":");
+ }
+
+ /*==========================================================
+ * public methods
+ *==========================================================*/
+
+ /**
+ * This method return string representation of the certificate
+ * 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, int indentSize, int lineLen) {
+
+ if (mX509Key != null)
+ return X509toString(clientLocale, indentSize, lineLen);
+ else
+ return null;
+ }
+
+ public String X509toString(Locale clientLocale, int indentSize, int lineLen) {
+
+ //get I18N resources
+ ResourceBundle resource = ResourceBundle.getBundle(
+ PrettyPrintResources.class.getName());
+
+ StringBuffer sb = new StringBuffer();
+
+ try {
+ String alg = mX509Key.getAlgorithm();
+
+ //XXX I18N Algorithm Name ?
+ sb.append(pp.indent(indentSize) + resource.getString(
+ PrettyPrintResources.TOKEN_ALGORITHM) +
+ alg + " - " +
+ mX509Key.getAlgorithmId().getOID().toString() + "\n");
+
+ if (alg.equals("RSA")) {
+
+ RSAPublicKey rsakey = new RSAPublicKey(mX509Key.getEncoded());
+
+ sb.append(pp.indent(indentSize) + resource.getString(
+ PrettyPrintResources.TOKEN_PUBLIC_KEY) + "\n");
+ sb.append(pp.indent(indentSize + 4) + resource.getString(
+ PrettyPrintResources.TOKEN_PUBLIC_KEY_EXPONENT) +
+ rsakey.getPublicExponent().toInt() + "\n");
+ sb.append(pp.indent(indentSize + 4) + resource.getString(
+ PrettyPrintResources.TOKEN_PUBLIC_KEY_MODULUS) +
+ "(" + rsakey.getKeySize() + " bits) :\n");
+ sb.append(pp.toHexString(
+ rsakey.getModulus().toByteArray(),
+ indentSize + 8, lineLen));
+ } else {
+
+ // DSAPublicKey is more complicated to decode, since
+ // the DSAParams (PQG) is not fully decoded.
+ // So, we just print the entire public key blob
+
+ sb.append(pp.indent(indentSize) + resource.getString(
+ PrettyPrintResources.TOKEN_PUBLIC_KEY) + "\n");
+ sb.append(pp.toHexString(mX509Key.getKey(), indentSize + 4, lineLen));
+ }
+
+ } catch (Exception e) {
+ }
+
+ return sb.toString();
+ }
+}
diff --git a/base/util/src/netscape/security/util/UniversalCharset.java b/base/util/src/netscape/security/util/UniversalCharset.java
new file mode 100644
index 000000000..59cc3c6f4
--- /dev/null
+++ b/base/util/src/netscape/security/util/UniversalCharset.java
@@ -0,0 +1,24 @@
+package netscape.security.util;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+
+public class UniversalCharset extends Charset {
+
+ public UniversalCharset() {
+ super("ASN.1-Universal", null);
+ }
+
+ public boolean contains(Charset cs) {
+ return false;
+ }
+
+ public CharsetDecoder newDecoder() {
+ return new UniversalCharsetDecoder(this);
+ }
+
+ public CharsetEncoder newEncoder() {
+ return new UniversalCharsetEncoder(this);
+ }
+}
diff --git a/base/util/src/netscape/security/util/UniversalCharsetDecoder.java b/base/util/src/netscape/security/util/UniversalCharsetDecoder.java
new file mode 100644
index 000000000..a41c5ad50
--- /dev/null
+++ b/base/util/src/netscape/security/util/UniversalCharsetDecoder.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 netscape.security.util;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+
+/**
+ * Converts bytes in ASN.1 UniversalString character set to UniversalString
+ * characters.
+ *
+ * @author Lily Hsiao
+ * @author Slava Galperin
+ */
+
+public class UniversalCharsetDecoder extends CharsetDecoder {
+
+ public UniversalCharsetDecoder(Charset cs) {
+ super(cs, 0.25f, 1);
+ }
+
+ protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
+
+ while (true) {
+ // XXX we do not know what to do with truly UCS-4 characters here
+ // we also assumed network byte order
+
+ if (in.remaining() < 4)
+ return CoderResult.UNDERFLOW;
+
+ in.mark();
+ byte b0 = in.get();
+ byte b1 = in.get();
+ byte b2 = in.get();
+ byte b3 = in.get();
+
+ if (CodingErrorAction.REPORT == unmappableCharacterAction() &&
+ !((b0 == 0 && b1 == 0) || (b2 == 0 && b3 == 0))) {
+ return CoderResult.unmappableForLength(4);
+ }
+
+ char c;
+ if (b2 == 0 && b3 == 0) {
+ // Try to be a bit forgiving. If the byte order is
+ // reversed, we still try handle it.
+
+ // Sample Date Set (1):
+ // 0000000 f 0 \0 \0 213 0 \0 \0 S 0 \0 \0
+ // 0000014
+
+ // Sample Date Set (2):
+ // 0000000 w \0 \0 \0 w \0 \0 \0 w \0 \0 \0 . \0 \0 \0
+ // 0000020 ( \0 \0 \0 t \0 \0 \0 o \0 \0 \0 b \0 \0 \0
+ // 0000040 e \0 \0 \0 | \0 \0 \0 n \0 \0 \0 o \0 \0 \0
+ // 0000060 t \0 \0 \0 t \0 \0 \0 o \0 \0 \0 b \0 \0 \0
+ // 0000100 e \0 \0 \0 ) \0 \0 \0 . \0 \0 \0 c \0 \0 \0
+ // 0000120 o \0 \0 \0 m \0 \0 \0
+ // 0000130
+ c = (char) (((b1 << 8) & 0xff00) + (b0 & 0x00ff));
+
+ } else { // (b0 == 0 && b1 == 0)
+ // This should be the right order.
+ //
+ // 0000000 0000 00c4 0000 0064 0000 006d 0000 0069
+ // 0000020 0000 006e 0000 0020 0000 0051 0000 0041
+ // 0000040
+
+ c = (char) (((b2 << 8) & 0xff00) + (b3 & 0x00ff));
+ }
+
+ if (out.remaining() < 1) {
+ in.reset();
+ return CoderResult.OVERFLOW;
+ }
+
+ out.put(c);
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/util/UniversalCharsetEncoder.java b/base/util/src/netscape/security/util/UniversalCharsetEncoder.java
new file mode 100644
index 000000000..cd2a51296
--- /dev/null
+++ b/base/util/src/netscape/security/util/UniversalCharsetEncoder.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 netscape.security.util;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+
+/**
+ * Converts characters in ASN.1 UniversalString character set to UniversalString
+ * bytes.
+ *
+ * @author Lily Hsiao
+ * @author Slava Galperin
+ */
+
+public class UniversalCharsetEncoder extends CharsetEncoder {
+
+ public UniversalCharsetEncoder(Charset cs) {
+ super(cs, 4, 4, new byte[] { 0, 0, 0, 0 });
+ }
+
+ /*
+ * Converts an array of Unicode characters into an array of UniversalString
+ * bytes and returns the conversion result.
+ * @param in input character buffer to convert.
+ * @param out byte buffer to store output.
+ * @return encoding result.
+ */
+ protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
+
+ while (true) {
+
+ if (in.remaining() < 1)
+ return CoderResult.UNDERFLOW;
+
+ in.mark();
+ char c = in.get();
+
+ if (out.remaining() < 4) {
+ in.reset();
+ return CoderResult.OVERFLOW;
+ }
+
+ out.put((byte) 0);
+ out.put((byte) 0);
+ out.put((byte) ((c >> 8) & 0xff));
+ out.put((byte) (c & 0xff));
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/x509/ACertAttrSet.java b/base/util/src/netscape/security/x509/ACertAttrSet.java
new file mode 100755
index 000000000..8a757d7f5
--- /dev/null
+++ b/base/util/src/netscape/security/x509/ACertAttrSet.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * A plain certattr set used by pkcs10 to parse an unknown attribute.
+ *
+ * @author Lily Hsiao
+ */
+public class ACertAttrSet implements CertAttrSet {
+
+ protected DerValue mDerValue = null;
+
+ public ACertAttrSet(DerValue derValue) throws IOException {
+ mDerValue = derValue;
+ }
+
+ public DerValue getDerValue() {
+ return mDerValue;
+ }
+
+ /**
+ * Returns a short string describing this certificate attribute.
+ *
+ * @return value of this certificate attribute in
+ * printable form.
+ */
+ public String toString() {
+ return "ACertAttrSet value " + (mDerValue == null ? "null" : "not null");
+ }
+
+ /**
+ * Encodes the attribute to the output stream in a format
+ * that can be parsed by the <code>decode</code> method.
+ *
+ * @param out the OutputStream to encode the attribute to.
+ *
+ * @exception CertificateException on encoding or validity errors.
+ * @exception IOException on other errors.
+ */
+ public void encode(OutputStream out)
+ throws CertificateException, IOException {
+ mDerValue.encode((DerOutputStream) out);
+ }
+
+ /**
+ * Decodes the attribute in the input stream.
+ *
+ * @param in the InputStream to read the encoded attribute from.
+ *
+ * @exception CertificateException on decoding or validity errors.
+ * @exception IOException on other errors.
+ */
+ public void decode(InputStream in)
+ throws CertificateException, IOException {
+ throw new IOException("not supported");
+ }
+
+ /**
+ * Sets an attribute value within this CertAttrSet.
+ *
+ * @param name the name of the attribute (e.g. "x509.info.key")
+ * @param obj the attribute object.
+ *
+ * @exception CertificateException on attribute handling errors.
+ * @exception IOException on other errors.
+ */
+ public void set(String name, Object obj)
+ throws CertificateException, IOException {
+ throw new IOException("not supported");
+ }
+
+ /**
+ * Gets an attribute value for this CertAttrSet.
+ *
+ * @param name the name of the attribute to return.
+ *
+ * @exception CertificateException on attribute handling errors.
+ * @exception IOException on other errors.
+ */
+ public Object get(String name)
+ throws CertificateException, IOException {
+ throw new IOException("not supported");
+ }
+
+ /**
+ * Deletes an attribute value from this CertAttrSet.
+ *
+ * @param name the name of the attribute to delete.
+ *
+ * @exception CertificateException on attribute handling errors.
+ * @exception IOException on other errors.
+ */
+ public void delete(String name)
+ throws CertificateException, IOException {
+ throw new IOException("not supported");
+ }
+
+ /**
+ * Returns an enumeration of the names of the attributes existing within
+ * this attribute.
+ *
+ * @return an enumeration of the attribute names.
+ */
+ public Enumeration<String> getAttributeNames() {
+ return null;
+ }
+
+ /**
+ * Returns the name (identifier) of this CertAttrSet.
+ *
+ * @return the name of this CertAttrSet.
+ */
+ public String getName() {
+ return "Generic Extension";
+ }
+}
diff --git a/base/util/src/netscape/security/x509/AVA.java b/base/util/src/netscape/security/x509/AVA.java
new file mode 100644
index 000000000..ad94c2c61
--- /dev/null
+++ b/base/util/src/netscape/security/x509/AVA.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.UnsupportedCharsetException;
+
+import netscape.security.util.DerEncoder;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * X.500 Attribute-Value-Assertion (AVA): an attribute, as identified by
+ * some attribute ID, has some particular value. Values are as a rule ASN.1
+ * printable strings. A conventional set of type IDs is recognized when
+ * parsing (and generating) RFC 1779 syntax strings.
+ *
+ * <P>
+ * AVAs are components of X.500 relative names. Think of them as being individual fields of a database record. The
+ * attribute ID is how you identify the field, and the value is part of a particular record.
+ *
+ * @see X500Name
+ * @see RDN
+ * @see LdapDNStrConverter
+ *
+ * @version 1.14
+ *
+ * @author David Brownell
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ */
+// public ... when RDN is public and X.500Names can be
+// constructed using RDNs, and all three classes are cleaner
+public final class AVA implements DerEncoder {
+ ObjectIdentifier oid;
+ DerValue value;
+
+ /**
+ * Constructs an AVA from a Ldap DN string with one AVA component
+ * using the global default LdapDNStrConverter.
+ *
+ * @see LdapDNStrConverter
+ * @param avaString a Ldap DN string with one AVA component.
+ */
+ public AVA(String avaString)
+ throws IOException {
+ AVA ava;
+ ava = LdapDNStrConverter.getDefault().parseAVA(avaString);
+ oid = ava.getOid();
+ value = ava.getValue();
+ }
+
+ /**
+ * Like AVA(String) with a DER encoding order given for Directory Strings.
+ */
+ public AVA(String avaString, byte[] tags)
+ throws IOException {
+ AVA ava;
+ ava = LdapDNStrConverter.getDefault().parseAVA(avaString, tags);
+ oid = ava.getOid();
+ value = ava.getValue();
+ }
+
+ /**
+ * Constructs an AVA from a Ldap DN string containing one AVA
+ * component using the specified LdapDNStrConverter.
+ *
+ * @see LdapDNStrConverter
+ * @param avaString a Ldap DN string containing one AVA.
+ * @param ldapDNStrConverter a LdapDNStrConverter
+ */
+ public AVA(String avaString, LdapDNStrConverter ldapDNStrConverter)
+ throws IOException {
+ AVA ava;
+ ava = ldapDNStrConverter.parseAVA(avaString);
+ oid = ava.getOid();
+ value = ava.getValue();
+ }
+
+ /**
+ * Constructs an AVA from an OID and DerValue.
+ *
+ * @param type an ObjectIdentifier
+ * @param val a DerValue
+ */
+ public AVA(ObjectIdentifier type, DerValue val)
+ throws IOException {
+ oid = type;
+ value = val;
+ }
+
+ /**
+ * Constructs an AVA from an input stream of UTF8 bytes that form
+ * a Ldap DN string. Then parse the Ldap DN string using the global
+ * default LdapDNStrConverter. <br>
+ * Parses an RFC 1779 style AVA string: CN=fee fie foe fum
+ * or perhaps with quotes. Not all defined AVA tags are supported;
+ * of current note are X.400 related ones (PRMD, ADMD, etc).
+ *
+ * This terminates at unescaped AVA separators ("+") or RDN
+ * separators (",", ";"), or DN terminators (">"), and removes
+ * cosmetic whitespace at the end of values.
+ *
+ * @see LdapDNStrConverter
+ * @param in the input stream.
+ */
+ public AVA(InputStream in) throws IOException {
+ try {
+ // convert from UTF8 bytes to java string then parse it.
+ byte[] buffer = new byte[in.available()];
+ in.read(buffer);
+
+ Charset charset = Charset.forName("UTF-8");
+ CharsetDecoder decoder = charset.newDecoder();
+
+ CharBuffer charBuffer = decoder.decode(ByteBuffer.wrap(buffer));
+
+ AVA a = LdapDNStrConverter.getDefault().parseAVA(charBuffer.toString());
+ oid = a.getOid();
+ value = a.getValue();
+
+ } catch (UnsupportedCharsetException e) {
+ throw new IOException("UTF8 encoding not supported", e);
+ }
+ }
+
+ /**
+ * Constructs an AVA from a Der Input Stream.
+ *
+ * @param in the Der Input Stream.
+ */
+ public AVA(DerInputStream in) throws IOException {
+ DerValue assertion = in.getDerValue();
+
+ /*
+ * Individual attribute value assertions are SEQUENCE of two values.
+ * That'd be a "struct" outside of ASN.1.
+ */
+ if (assertion.tag != DerValue.tag_Sequence)
+ throw new CertParseError("X500 AVA, not a sequence");
+
+ ObjectIdentifier o = assertion.data.getOID();
+ oid = X500NameAttrMap.getDefault().getOid(o);
+ if (oid == null) {
+ // NSCP #329837
+ // if this OID is not recongized in our map (table),
+ // it is fine. we just store it as regular OID.
+ oid = o;
+ }
+ value = assertion.data.getDerValue();
+
+ if (assertion.data.available() != 0)
+ throw new CertParseError("AVA, extra bytes = "
+ + assertion.data.available());
+ }
+
+ // other public methods.
+
+ /**
+ * Returns true if another AVA has the same OID and DerValue.
+ *
+ * @param other the other AVA.
+ * @return ture iff other AVA has same oid and value.
+ */
+ public boolean equals(AVA other) {
+ return oid.equals(other.oid) && value.equals(other.value);
+ }
+
+ /**
+ * Compares the AVA with an Object, returns true if the object is
+ * an AVA and has the same OID and value.
+ *
+ * @param other the other object.
+ * @return true iff other object is an AVA and has same oid and value.
+ */
+ public boolean equals(Object other) {
+ if (other instanceof AVA)
+ return equals((AVA) other);
+ else
+ return false;
+ }
+
+ /**
+ * Encodes the AVA to a Der output stream.
+ * AVAs are encoded as a SEQUENCE of two elements.
+ *
+ * @param out The Der output stream.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ derEncode(out);
+ }
+
+ /**
+ * DER encode this object onto an output stream.
+ * Implements the <code>DerEncoder</code> interface.
+ *
+ * @param out
+ * the output stream on which to write the DER encoding.
+ *
+ * @exception IOException on encoding error.
+ */
+ public void derEncode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ DerOutputStream tmp2 = new DerOutputStream();
+
+ tmp.putOID(oid);
+ value.encode(tmp);
+ tmp2.write(DerValue.tag_Sequence, tmp);
+ out.write(tmp2.toByteArray());
+ }
+
+ /**
+ * Returns a Ldap DN string with one AVA component using
+ * the global default LdapDNStrConverter.
+ *
+ * @return a Ldap DN string
+ * @exception IOException if an error occurs during conversion.
+ * @see LdapDNStrConverter
+ */
+ public String toLdapDNString()
+ throws IOException {
+ LdapDNStrConverter v = LdapDNStrConverter.getDefault();
+ return v.encodeAVA(this);
+ }
+
+ /**
+ * Returns a Ldap DN string with one AVA component using the specified
+ * LdapDNStrConverter.
+ *
+ * @return a Ldap DN string
+ * @param ldapDNStrConverter a Ldap DN String Converter
+ * @exception IOException if an error occurs during the conversion.
+ * @see LdapDNStrConverter
+ */
+ public String toLdapDNString(LdapDNStrConverter ldapDNStrConverter)
+ throws IOException {
+ return ldapDNStrConverter.encodeAVA(this);
+ }
+
+ /**
+ * Returns a Ldap DN string with the AVA component using the global
+ * default LdapDNStrConverter, or null if an error occurs in conversion.
+ *
+ * @return a Ldap DN string containing the AVA, or null if an
+ * error occurs in the conversion.
+ */
+ public String toString() {
+ String s;
+ try {
+ // NOTE that a LdapDNString is returned here to match the
+ // original source from sun. Could also return the raw value
+ // (before Ldap escaping) here.
+ s = toLdapDNString();
+ } catch (IOException e) {
+ return null;
+ }
+ return s;
+ }
+
+ /**
+ * Returns the OID in the AVA.
+ *
+ * @return the ObjectIdentifier in this AVA.
+ */
+ public ObjectIdentifier getOid() {
+ return oid;
+ }
+
+ /**
+ * Returns the value in this AVA as a DerValue
+ *
+ * @return attribute value in this AVA.
+ */
+ public DerValue getValue() {
+ return value;
+ }
+
+}
diff --git a/base/util/src/netscape/security/x509/AVAValueConverter.java b/base/util/src/netscape/security/x509/AVAValueConverter.java
new file mode 100644
index 000000000..cd3ce7616
--- /dev/null
+++ b/base/util/src/netscape/security/x509/AVAValueConverter.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 netscape.security.x509;
+
+import java.io.IOException;
+
+import netscape.security.util.DerValue;
+
+/**
+ * Interface for classes that convert a attribute value string to a
+ * DER encoded ASN.1 value and vice versa.
+ * The converters are associated with attribute types, such as
+ * directory string, ia5string, etc.
+ *
+ * <P>
+ * For example, to convert a string, such as an organization name for the "O" attribute to a DerValue, the "O" attribute
+ * is mapped to the DirStrConverter which is used to convert the organization name to a DER encoded Directory String
+ * which is a DerValue of a ASN.1 PrintableString, T.61String or UniversalString for the organization name.
+ *
+ * @author Lily Hsiao, Slava Galperin at Netscape Communications, Inc.
+ */
+
+public interface AVAValueConverter {
+ /**
+ * Converts a string to a DER encoded attribute value.
+ *
+ * @param valueString An AVA value string not encoded in any form.
+ *
+ * @return A DerValue object.
+ *
+ * @exception IOException if an error occurs during the conversion.
+ */
+ public DerValue getValue(String valueString)
+ throws IOException;
+
+ /**
+ * Converts a string to a DER encoded attribute value.
+ * Specify the order of DER tags to use if more than one encoding is
+ * possible. Currently Directory Strings can have different order
+ * for backwards compatibility. By 2003 all should be UTF8String.
+ *
+ * @param valueString An AVA value string not encoded in any form.
+ *
+ * @return A DerValue object.
+ *
+ * @exception IOException if an error occurs during the conversion.
+ */
+ public DerValue getValue(String valueString, byte[] tags)
+ throws IOException;
+
+ /**
+ * Converts a BER encoded value to a DER encoded attribute value.
+ *
+ * @param berStream A byte array of the BER encoded AVA value.
+ * @return A DerValue object.
+ */
+ public DerValue getValue(byte[] berStream)
+ throws IOException;
+
+ /**
+ * Converts a DER encoded value to a string, not encoded in any form.
+ *
+ * @param avaValue A DerValue object.
+ *
+ * @return A string for the value or null if it can't be converted.
+ *
+ * @exception IOException if an error occurs during the conversion.
+ */
+ public String getAsString(DerValue avaValue)
+ throws IOException;
+}
diff --git a/base/util/src/netscape/security/x509/AlgIdDSA.java b/base/util/src/netscape/security/x509/AlgIdDSA.java
new file mode 100644
index 000000000..0a64ad37b
--- /dev/null
+++ b/base/util/src/netscape/security/x509/AlgIdDSA.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.ProviderException;
+import java.security.interfaces.DSAParams;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class identifies DSS/DSA Algorithm variants, which are distinguished
+ * by using different algorithm parameters <em>P, Q, G</em>. It uses the
+ * NIST/IETF standard DER encoding. These are used to implement the Digital
+ * Signature Standard (DSS), FIPS 186.
+ *
+ * <P>
+ * <em><b>NOTE:</b> At this time, DSS/DSA Algorithm IDs must always
+ * include these parameters. Use of DSS/DSA in modes where parameters are
+ * either implicit (e.g. a default applicable to a site or a larger scope),
+ * or are derived from some Certificate Authority's DSS certificate, is
+ * not currently supported. </em>
+ *
+ * @version 1.31
+ * @author David Brownell
+ */
+public final class AlgIdDSA extends AlgorithmId implements DSAParams {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5978220691806461631L;
+ /*
+ * The three unsigned integer parameters.
+ */
+ private BigInteger p, q, g;
+
+ /** Returns the DSS/DSA parameter "P" */
+ public BigInteger getP() {
+ return p;
+ }
+
+ /** Returns the DSS/DSA parameter "Q" */
+ public BigInteger getQ() {
+ return q;
+ }
+
+ /** Returns the DSS/DSA parameter "G" */
+ public BigInteger getG() {
+ return g;
+ }
+
+ /**
+ * Default constructor. The OID and parameters must be
+ * deserialized before this algorithm ID is used.
+ */
+ // XXX deprecated for general use
+ public AlgIdDSA() {
+ }
+
+ AlgIdDSA(DerValue val) throws IOException {
+ super(val.getOID());
+ }
+
+ /**
+ * Construct an AlgIdDSA from an X.509 encoded byte array.
+ */
+ public AlgIdDSA(byte[] encodedAlg) throws IOException {
+ super(new DerValue(encodedAlg).getOID());
+ }
+
+ /**
+ * Constructs a DSS/DSA Algorithm ID from unsigned integers that
+ * define the algorithm parameters. Those integers are encoded
+ * as big-endian byte arrays.
+ *
+ * @param p the DSS/DSA paramter "P"
+ * @param q the DSS/DSA paramter "Q"
+ * @param g the DSS/DSA paramter "G"
+ */
+ public AlgIdDSA(byte p[], byte q[], byte g[])
+ throws IOException {
+ this(new BigInteger(1, p),
+ new BigInteger(1, q),
+ new BigInteger(1, g));
+ }
+
+ /**
+ * Constructs a DSS/DSA Algorithm ID from numeric parameters.
+ *
+ * @param p the DSS/DSA paramter "P"
+ * @param q the DSS/DSA paramter "Q"
+ * @param g the DSS/DSA paramter "G"
+ */
+ public AlgIdDSA(BigInteger p, BigInteger q, BigInteger g) {
+ super(DSA_oid);
+
+ try {
+ this.p = p;
+ this.q = q;
+ this.g = g;
+ initializeParams();
+
+ } catch (IOException e) {
+ /* this should not happen */
+ throw new ProviderException("Construct DSS/DSA Algorithm ID");
+ }
+ }
+
+ /**
+ * Returns "DSA", indicating the Digital Signature Algorithm (DSA) as
+ * defined by the Digital Signature Standard (DSS), FIPS 186.
+ */
+ public String getName() {
+ return "DSA";
+ }
+
+ /*
+ * For algorithm IDs which haven't been created from a DER encoded
+ * value, "params" must be created.
+ */
+ private void initializeParams()
+ throws IOException {
+ DerOutputStream out = new DerOutputStream();
+
+ out.putInteger(new BigInt(p.toByteArray()));
+ out.putInteger(new BigInt(q.toByteArray()));
+ out.putInteger(new BigInt(g.toByteArray()));
+ params = new DerValue(DerValue.tag_Sequence, out.toByteArray());
+ }
+
+ /**
+ * Parses algorithm parameters P, Q, and G. They're found
+ * in the "params" member, which never needs to be changed.
+ */
+ protected void decodeParams()
+ throws IOException {
+ if (params == null || params.tag != DerValue.tag_Sequence)
+ throw new IOException("DSA alg parsing error");
+
+ params.data.reset();
+
+ this.p = params.data.getInteger().toBigInteger();
+ this.q = params.data.getInteger().toBigInteger();
+ this.g = params.data.getInteger().toBigInteger();
+
+ if (params.data.available() != 0)
+ throw new IOException("AlgIdDSA params, extra=" +
+ params.data.available());
+ }
+
+ /*
+ * Returns a formatted string describing the parameters.
+ */
+ public String toString() {
+ return paramsToString();
+ }
+
+ /*
+ * Returns a string describing the parameters.
+ */
+ protected String paramsToString() {
+ return "\n p:\n" + (new BigInt(p)).toString() +
+ "\n q:\n" + (new BigInt(q)).toString() +
+ "\n g:\n" + (new BigInt(g)).toString() +
+ "\n";
+ }
+}
diff --git a/base/util/src/netscape/security/x509/AlgorithmId.java b/base/util/src/netscape/security/x509/AlgorithmId.java
new file mode 100644
index 000000000..b0113af41
--- /dev/null
+++ b/base/util/src/netscape/security/x509/AlgorithmId.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.security.AlgorithmParameters;
+import java.security.NoSuchAlgorithmException;
+
+import netscape.security.util.DerEncoder;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * This class identifies algorithms, such as cryptographic transforms, each
+ * of which may be associated with parameters. Instances of this base class
+ * are used when this runtime environment has no special knowledge of the
+ * algorithm type, and may also be used in other cases. Equivalence is
+ * defined according to OID and (where relevant) parameters.
+ *
+ * <P>
+ * Subclasses may be used, for example when when the algorithm ID has associated parameters which some code (e.g. code
+ * using public keys) needs to have parsed. Two examples of such algorithms are Diffie-Hellman key exchange, and the
+ * Digital Signature Standard Algorithm (DSS/DSA).
+ *
+ * <P>
+ * The OID constants defined in this class correspond to some widely used algorithms, for which conventional string
+ * names have been defined. This class is not a general repository for OIDs, or for such string names. Note that the
+ * mappings between algorithm IDs and algorithm names is not one-to-one.
+ *
+ * @version 1.70
+ *
+ * @author David Brownell
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ */
+public class AlgorithmId implements Serializable, DerEncoder {
+
+ /** use serialVersionUID from JDK 1.1. for interoperability */
+ private static final long serialVersionUID = 7205873507486557157L;
+
+ /* Are we debugging? */
+ private static boolean debug = false;
+
+ /**
+ * The object identitifer being used for this algorithm.
+ */
+ private ObjectIdentifier algid = null;
+
+ // The (parsed) parameters
+ private AlgorithmParameters algParams;
+
+ /**
+ * Parameters for this algorithm. These are stored in unparsed
+ * DER-encoded form; subclasses can be made to automaticaly parse
+ * them so there is fast access to these parameters.
+ */
+ protected DerValue params = null;
+
+ protected String paramsString = null;
+
+ /**
+ * Returns one of the algorithm IDs most commonly associated
+ * with this algorithm name.
+ *
+ * @param algname the name being used
+ * @deprecated use the short get form of this method.
+ * @exception NoSuchAlgorithmException on error.
+ */
+ public static AlgorithmId getAlgorithmId(String algname)
+ throws NoSuchAlgorithmException {
+ return get(algname);
+ }
+
+ public AlgorithmParameters getParameters() {
+ return this.algParams;
+ }
+
+ public String getParametersString() {
+ return this.paramsString;
+ }
+
+ public void setParametersString(String paramStr) {
+
+ this.paramsString = paramStr;
+ }
+
+ /**
+ * Returns one of the algorithm IDs most commonly associated
+ * with this algorithm name.
+ *
+ * @param algname the name being used
+ * @exception NoSuchAlgorithmException on error.
+ */
+ public static AlgorithmId get(String algname)
+ throws NoSuchAlgorithmException {
+ ObjectIdentifier oid = algOID(algname);
+
+ if (oid == null)
+ throw new NoSuchAlgorithmException("unrecognized algorithm name: " + algname);
+
+ return new AlgorithmId(oid);
+ }
+
+ /**
+ * Parse (unmarshal) an ID from a DER sequence input value. This form
+ * parsing might be used when expanding a value which has already been
+ * partially unmarshaled as a set or sequence member.
+ *
+ * @exception IOException on error.
+ * @param val the input value, which contains the algid and, if
+ * there are any parameters, those parameters.
+ * @return an ID for the algorithm. If the system is configured
+ * appropriately, this may be an instance of a class
+ * with some kind of special support for this algorithm.
+ * In that case, you may "narrow" the type of the ID.
+ */
+ public static AlgorithmId parse(DerValue val)
+ throws IOException {
+ if (val.tag != DerValue.tag_Sequence)
+ throw new IOException("algid parse error, not a sequence");
+
+ /*
+ * Get the algorithm ID and any parameters.
+ */
+ ObjectIdentifier algid;
+ DerValue params;
+ DerInputStream in = val.toDerInputStream();
+
+ algid = in.getOID();
+ if (in.available() == 0)
+ params = null;
+ else {
+ params = in.getDerValue();
+ if (params.tag == DerValue.tag_Null)
+ params = null;
+ }
+
+ /*
+ * Figure out what class (if any) knows about this oid's
+ * parameters. Make one, and give it the data to decode.
+ */
+ AlgorithmId alg = new AlgorithmId(algid, params);
+ if (params != null)
+ alg.decodeParams();
+
+ /*
+ * Set the raw params string in case
+ * higher level code might want the info
+ */
+
+ String paramStr = null;
+
+ if (params != null) {
+ paramStr = params.toString();
+ }
+
+ alg.setParametersString(paramStr);
+
+ return alg;
+ }
+
+ public static AlgorithmId parse(byte[] val)
+ throws IOException {
+ return null;
+ }
+
+ /**
+ * Constructs a parameterless algorithm ID.
+ *
+ * @param oid the identifier for the algorithm
+ */
+ public AlgorithmId(ObjectIdentifier oid) {
+ algid = oid;
+ }
+
+ private AlgorithmId(ObjectIdentifier oid, DerValue params)
+ throws IOException {
+ this.algid = oid;
+ this.params = params;
+ if (this.params != null)
+ decodeParams();
+ }
+
+ /**
+ * Constructs an algorithm ID which will be initialized
+ * separately, for example by deserialization.
+ *
+ * @deprecated use one of the other constructors.
+ */
+ public AlgorithmId() {
+ }
+
+ protected void decodeParams() throws IOException {
+ try {
+ this.algParams = AlgorithmParameters.getInstance
+ (this.algid.toString());
+ } catch (NoSuchAlgorithmException e) {
+ /*
+ * This algorithm parameter type is not supported, so we cannot
+ * parse the parameters.
+ */
+ this.algParams = null;
+ return;
+ }
+ // Decode (parse) the parameters
+ this.algParams.init(this.params.toByteArray());
+ }
+
+ /**
+ * Marshal a DER-encoded "AlgorithmID" sequence on the DER stream.
+ */
+ public final void encode(DerOutputStream out)
+ throws IOException {
+ derEncode(out);
+ }
+
+ /**
+ * DER encode this object onto an output stream.
+ * Implements the <code>DerEncoder</code> interface.
+ *
+ * @param out
+ * the output stream on which to write the DER encoding.
+ *
+ * @exception IOException on encoding error.
+ */
+ public void derEncode(OutputStream out) throws IOException {
+ DerOutputStream bytes = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+
+ bytes.putOID(algid);
+ if (params == null)
+ bytes.putNull();
+ else
+ bytes.putDerValue(params);
+ tmp.write(DerValue.tag_Sequence, bytes);
+ out.write(tmp.toByteArray());
+ }
+
+ // XXXX cleaning required
+ /**
+ * Returns the DER-encoded X.509 AlgorithmId as a byte array.
+ */
+ public final byte[] encode() throws IOException {
+ DerOutputStream out = new DerOutputStream();
+ DerOutputStream bytes = new DerOutputStream();
+
+ bytes.putOID(algid);
+ if (params == null)
+ bytes.putNull();
+ else
+ bytes.putDerValue(params);
+ out.write(DerValue.tag_Sequence, bytes);
+ return out.toByteArray();
+ }
+
+ /**
+ * Returns list of signing algorithms for a key algorithm such as
+ * RSA or DSA.
+ */
+ public static String[] getSigningAlgorithms(AlgorithmId alg) {
+ ObjectIdentifier algOid = alg.getOID();
+ //System.out.println("Key Alg oid "+algOid.toString());
+ if (algOid.equals(DSA_oid) || algOid.equals(DSA_OIW_oid)) {
+ return DSA_SIGNING_ALGORITHMS;
+ } else if (algOid.equals(RSA_oid) || algOid.equals(RSAEncryption_oid)) {
+ return RSA_SIGNING_ALGORITHMS;
+ } else if (algOid.equals(ANSIX962_EC_Public_Key_oid) || algOid.equals(ANSIX962_SHA1_With_EC_oid)) {
+ return EC_SIGNING_ALGORITHMS;
+ } else {
+ return null;
+ }
+ }
+
+ /*
+ * Translates from some common algorithm names to the
+ * OID with which they're usually associated ... this mapping
+ * is the reverse of the one below, except in those cases
+ * where synonyms are supported or where a given algorithm
+ * is commonly associated with multiple OIDs.
+ */
+ private static ObjectIdentifier algOID(String name) {
+ // Digesting algorithms
+
+ if (name.equals("MD5"))
+ return AlgorithmId.MD5_oid;
+ if (name.equals("MD2"))
+ return AlgorithmId.MD2_oid;
+ if (name.equals("SHA") || name.equals("SHA1")
+ || name.equals("SHA-1"))
+ return AlgorithmId.SHA_oid;
+ if (name.equals("SHA256") || name.equals("SHA-256"))
+ return AlgorithmId.SHA256_oid;
+ if (name.equals("SHA512") || name.equals("SHA-512"))
+ return AlgorithmId.SHA512_oid;
+
+ // Various public key algorithms
+
+ if (name.equals("RSA"))
+ return AlgorithmId.RSA_oid;
+
+ if (name.equals("RSAEncryption"))
+ return AlgorithmId.RSAEncryption_oid;
+ if (name.equals("Diffie-Hellman") || name.equals("DH"))
+ return AlgorithmId.DH_oid;
+ if (name.equals("DSA"))
+ return AlgorithmId.DSA_oid;
+
+ // Common signature types
+
+ if (name.equals("SHA1withEC") || name.equals("SHA1/EC")
+ || name.equals("1.2.840.10045.4.1"))
+ return AlgorithmId.sha1WithEC_oid;
+ if (name.equals("SHA256withEC") || name.equals("SHA256/EC")
+ || name.equals("1.2.840.10045.4.3.2"))
+ return AlgorithmId.sha256WithEC_oid;
+ if (name.equals("SHA384withEC") || name.equals("SHA384/EC")
+ || name.equals("1.2.840.10045.4.3.3"))
+ return AlgorithmId.sha384WithEC_oid;
+ if (name.equals("SHA512withEC") || name.equals("SHA512/EC")
+ || name.equals("1.2.840.10045.4.3.4"))
+ return AlgorithmId.sha512WithEC_oid;
+ if (name.equals("SHA1withRSA") || name.equals("SHA1/RSA")
+ || name.equals("1.2.840.113549.1.1.5"))
+ return AlgorithmId.sha1WithRSAEncryption_oid;
+ if (name.equals("SHA256withRSA") || name.equals("SHA256/RSA")
+ || name.equals("1.2.840.113549.1.1.11"))
+ return AlgorithmId.sha256WithRSAEncryption_oid;
+ if (name.equals("SHA512withRSA") || name.equals("SHA512/RSA")
+ || name.equals("1.2.840.113549.1.1.13"))
+ return AlgorithmId.sha512WithRSAEncryption_oid;
+ if (name.equals("MD5withRSA") || name.equals("MD5/RSA"))
+ return AlgorithmId.md5WithRSAEncryption_oid;
+ if (name.equals("MD2withRSA") || name.equals("MD2/RSA"))
+ return AlgorithmId.md2WithRSAEncryption_oid;
+ if (name.equals("SHAwithDSA") || name.equals("SHA1withDSA")
+ || name.equals("SHA/DSA") || name.equals("SHA1/DSA"))
+ return AlgorithmId.sha1WithDSA_oid;
+
+ return null;
+ }
+
+ /*
+ * For the inevitable cases where key or signature types are not
+ * configured in an environment which encounters such keys or
+ * signatures, we still attempt to provide user-friendly names
+ * for some of the most common algorithms. Subclasses can of
+ * course override getName().
+ *
+ * Wherever possible, the names are those defined by the IETF.
+ * Such names are noted below.
+ */
+ private String algName() {
+ // Common message digest algorithms
+
+ if (algid.equals(AlgorithmId.MD5_oid))
+ return "MD5"; // RFC 1423
+ if (algid.equals(AlgorithmId.MD2_oid))
+ return "MD2"; // RFC 1423
+ if (algid.equals(AlgorithmId.SHA_oid))
+ return "SHA";
+ if (algid.equals(AlgorithmId.SHA256_oid))
+ return "SHA256";
+ if (algid.equals(AlgorithmId.SHA512_oid))
+ return "SHA512";
+
+ // Common key types
+
+ if (algid.equals(AlgorithmId.ANSIX962_EC_Public_Key_oid))
+ return "EC";
+ if (algid.equals(AlgorithmId.RSAEncryption_oid)
+ || algid.equals(AlgorithmId.RSA_oid))
+ return "RSA";
+ if (algid.equals(AlgorithmId.DH_oid)
+ || algid.equals(AlgorithmId.DH_PKIX_oid))
+ return "Diffie-Hellman";
+ if (algid.equals(AlgorithmId.DSA_oid)
+ || algid.equals(AlgorithmId.DSA_OIW_oid))
+ return "DSA";
+
+ // Common signature types
+
+ if (algid.equals(AlgorithmId.sha1WithEC_oid))
+ return "SHA1withEC";
+ if (algid.equals(AlgorithmId.sha256WithEC_oid))
+ return "SHA256withEC";
+ if (algid.equals(AlgorithmId.sha384WithEC_oid))
+ return "SHA384withEC";
+ if (algid.equals(AlgorithmId.sha512WithEC_oid))
+ return "SHA512withEC";
+ if (algid.equals(AlgorithmId.md5WithRSAEncryption_oid))
+ return "MD5withRSA";
+ if (algid.equals(AlgorithmId.md2WithRSAEncryption_oid))
+ return "MD2withRSA";
+ if (algid.equals(AlgorithmId.sha1WithRSAEncryption_oid))
+ return "SHA1withRSA";
+ if (algid.equals(AlgorithmId.sha256WithRSAEncryption_oid))
+ return "SHA256withRSA";
+ if (algid.equals(AlgorithmId.sha512WithRSAEncryption_oid))
+ return "SHA512withRSA";
+ if (algid.equals(AlgorithmId.sha1WithDSA_oid)
+ || algid.equals(AlgorithmId.sha1WithDSA_OIW_oid)
+ || algid.equals(AlgorithmId.shaWithDSA_OIW_oid))
+ return "SHA1withDSA";
+
+ // default returns a dot-notation ID
+
+ return "OID." + algid.toString();
+ }
+
+ /**
+ * Returns the ISO OID for this algorithm. This is usually converted
+ * to a string and used as part of an algorithm name, for example
+ * "OID.1.3.14.3.2.13" style notation. Use the <code>getName</code> call when you do not need to ensure cross-system
+ * portability
+ * of algorithm names, or need a user friendly name.
+ */
+ final public ObjectIdentifier getOID() {
+ return algid;
+ }
+
+ /**
+ * Returns a name for the algorithm which may be more intelligible
+ * to humans than the algorithm's OID, but which won't necessarily
+ * be comprehensible on other systems. For example, this might
+ * return a name such as "MD5withRSA" for a signature algorithm on
+ * some systems. It also returns names like "OID.1.2.3.4", when
+ * no particular name for the algorithm is known.
+ */
+ public String getName() {
+ return algName();
+ }
+
+ /**
+ * Returns a string describing the algorithm and its parameters.
+ */
+ public String toString() {
+ return (algName() + paramsToString());
+ }
+
+ /**
+ * Returns the DER encoded parameter, which can then be
+ * used to initialize java.security.AlgorithmParamters.
+ *
+ * @return DER encoded parameters, or null not present.
+ */
+ public byte[] getEncodedParams() throws IOException {
+ if (params == null)
+ return null;
+ else
+ return params.toByteArray();
+ }
+
+ /**
+ * Provides a human-readable description of the algorithm parameters.
+ * This may be redefined by subclasses which parse those parameters.
+ */
+ protected String paramsToString() {
+ if (params == null) {
+ return "";
+ } else if (algParams != null) {
+ return algParams.toString();
+ } else {
+ return ", params unparsed";
+ }
+ }
+
+ /**
+ * Returns true iff the argument indicates the same algorithm
+ * with the same parameters.
+ */
+ public boolean equals(AlgorithmId other) {
+ if (!algid.equals(other.algid))
+ return false;
+ else if (params == null && other.params == null)
+ return true;
+ else if (params == null)
+ return false;
+ else
+ return params.equals(other.params);
+ }
+
+ /**
+ * Compares this AlgorithmID to another. If algorithm parameters are
+ * available, they are compared. Otherwise, just the object IDs
+ * for the algorithm are compared.
+ *
+ * @param other preferably an AlgorithmId, else an ObjectIdentifier
+ */
+ public boolean equals(Object other) {
+ if (other instanceof AlgorithmId)
+ return equals((AlgorithmId) other);
+ else if (other instanceof ObjectIdentifier)
+ return equals((ObjectIdentifier) other);
+ else
+ return false;
+ }
+
+ /**
+ * Compares two algorithm IDs for equality. Returns true iff
+ * they are the same algorithm, ignoring algorithm parameters.
+ */
+ public final boolean equals(ObjectIdentifier id) {
+ return algid.equals(id);
+ }
+
+ /*****************************************************************/
+
+ /*
+ * HASHING ALGORITHMS
+ */
+ private static final int MD2_data[] = { 1, 2, 840, 113549, 2, 2 };
+ private static final int MD5_data[] = { 1, 2, 840, 113549, 2, 5 };
+ // sha = { 1, 3, 14, 3, 2, 18 };
+ private static final int SHA1_OIW_data[] = { 1, 3, 14, 3, 2, 26 };
+ private static final int SHA256_data[] = { 2, 16, 840, 1, 101, 3, 4, 2, 1 };
+ private static final int SHA512_data[] = { 2, 16, 840, 1, 101, 3, 4, 2, 3 };
+
+ /**
+ * Algorithm ID for the MD2 Message Digest Algorthm, from RFC 1319.
+ * OID = 1.2.840.113549.2.2
+ */
+ public static final ObjectIdentifier MD2_oid = new ObjectIdentifier(MD2_data);
+
+ /**
+ * Algorithm ID for the MD5 Message Digest Algorthm, from RFC 1321.
+ * OID = 1.2.840.113549.2.5
+ */
+ public static final ObjectIdentifier MD5_oid = new ObjectIdentifier(MD5_data);
+
+ /**
+ * Algorithm ID for the SHA1 Message Digest Algorithm, from FIPS 180-1.
+ * This is sometimes called "SHA", though that is often confusing since
+ * many people refer to FIPS 180 (which has an error) as defining SHA.
+ * OID = 1.3.14.3.2.26
+ */
+ public static final ObjectIdentifier SHA_oid = new ObjectIdentifier(SHA1_OIW_data);
+
+ public static final ObjectIdentifier SHA256_oid = new ObjectIdentifier(SHA256_data);
+
+ public static final ObjectIdentifier SHA512_oid = new ObjectIdentifier(SHA512_data);
+
+ /*
+ * COMMON PUBLIC KEY TYPES
+ */
+ private static final int DH_data[] = { 1, 2, 840, 113549, 1, 3, 1 };
+ private static final int DH_PKIX_data[] = { 1, 2, 840, 10046, 2, 1 };
+ private static final int DSA_OIW_data[] = { 1, 3, 14, 3, 2, 12 };
+ private static final int DSA_PKIX_data[] = { 1, 2, 840, 10040, 4, 1 };
+ private static final int RSA_data[] = { 1, 2, 5, 8, 1, 1 };
+ private static final int RSAEncryption_data[] =
+ { 1, 2, 840, 113549, 1, 1, 1 };
+ private static final int ANSI_X962_public_key_data[] =
+ { 1, 2, 840, 10045, 2, 1 };
+ private static final int ANSI_X962_sha1_with_ec_data[] =
+ { 1, 2, 840, 10045, 4, 1 };
+
+ public static final ObjectIdentifier ANSIX962_EC_Public_Key_oid = new ObjectIdentifier(ANSI_X962_public_key_data);
+ public static final ObjectIdentifier ANSIX962_SHA1_With_EC_oid = new ObjectIdentifier(ANSI_X962_sha1_with_ec_data);
+
+ /*
+ * Note the preferred OIDs are named simply with no "OIW" or
+ * "PKIX" in them, even though they may point to data from these
+ * specs; e.g. SHA_oid, DH_oid, DSA_oid, SHA1WithDSA_oid...
+ */
+ /**
+ * Algorithm ID for Diffie Hellman Key agreement, from PKCS #3.
+ * Parameters include public values P and G, and may optionally specify
+ * the length of the private key X. Alternatively, algorithm parameters
+ * may be derived from another source such as a Certificate Authority's
+ * certificate.
+ * OID = 1.2.840.113549.1.3.1
+ */
+ public static final ObjectIdentifier DH_oid = new ObjectIdentifier(DH_data);
+
+ /**
+ * Algorithm ID for the Diffie Hellman Key Agreement (DH), from the
+ * IETF PKIX IPKI Part I.
+ * Parameters may include public values P and G.
+ * OID = 1.2.840.10046.2.1
+ */
+ public static final ObjectIdentifier DH_PKIX_oid = new ObjectIdentifier(DH_PKIX_data);
+
+ /**
+ * Algorithm ID for the Digital Signing Algorithm (DSA), from the
+ * NIST OIW Stable Agreements part 12.
+ * Parameters may include public values P, Q, and G; or these may be
+ * derived from
+ * another source such as a Certificate Authority's certificate.
+ * OID = 1.3.14.3.2.12
+ */
+ public static final ObjectIdentifier DSA_OIW_oid = new ObjectIdentifier(DSA_OIW_data);
+
+ /**
+ * Algorithm ID for the Digital Signing Algorithm (DSA), from the
+ * IETF PKIX IPKI Part I.
+ * Parameters may include public values P, Q, and G; or these may be
+ * derived from
+ * another source such as a Certificate Authority's certificate.
+ * OID = 1.2.840.10040.4.1
+ */
+ public static final ObjectIdentifier DSA_oid = new ObjectIdentifier(DSA_PKIX_data);
+
+ /**
+ * Algorithm ID for RSA keys used for any purpose, as defined in X.509.
+ * The algorithm parameter is a single value, the number of bits in the
+ * public modulus.
+ * OID = 1.2.5.8.1.1
+ */
+ public static final ObjectIdentifier RSA_oid = new ObjectIdentifier(RSA_data);
+
+ /**
+ * Algorithm ID for RSA keys used with RSA encryption, as defined
+ * in PKCS #1. There are no parameters associated with this algorithm.
+ * OID = 1.2.840.113549.1.1.1
+ */
+ public static final ObjectIdentifier RSAEncryption_oid = new ObjectIdentifier(RSAEncryption_data);
+
+ /*
+ * COMMON SIGNATURE ALGORITHMS
+ */
+ private static final int sha1WithEC_data[] =
+ { 1, 2, 840, 10045, 4, 1 };
+ private static final int sha256WithEC_data[] =
+ { 1, 2, 840, 10045, 4, 3, 2 };
+ private static final int sha384WithEC_data[] =
+ { 1, 2, 840, 10045, 4, 3, 3 };
+ private static final int sha512WithEC_data[] =
+ { 1, 2, 840, 10045, 4, 3, 4 };
+ private static final int md2WithRSAEncryption_data[] =
+ { 1, 2, 840, 113549, 1, 1, 2 };
+ private static final int md5WithRSAEncryption_data[] =
+ { 1, 2, 840, 113549, 1, 1, 4 };
+ private static final int sha1WithRSAEncryption_data[] =
+ { 1, 2, 840, 113549, 1, 1, 5 };
+ private static final int sha256WithRSAEncryption_data[] =
+ { 1, 2, 840, 113549, 1, 1, 11 };
+ private static final int sha512WithRSAEncryption_data[] =
+ { 1, 2, 840, 113549, 1, 1, 13 };
+ private static final int sha1WithRSAEncryption_OIW_data[] =
+ { 1, 3, 14, 3, 2, 29 };
+ private static final int shaWithDSA_OIW_data[] =
+ { 1, 3, 14, 3, 2, 13 };
+ private static final int sha1WithDSA_OIW_data[] =
+ { 1, 3, 14, 3, 2, 27 };
+ private static final int dsaWithSHA1_PKIX_data[] =
+ { 1, 2, 840, 10040, 4, 3 };
+
+ public static final ObjectIdentifier sha1WithEC_oid = new
+ ObjectIdentifier(sha1WithEC_data);
+
+ public static final ObjectIdentifier sha256WithEC_oid = new
+ ObjectIdentifier(sha256WithEC_data);
+
+ public static final ObjectIdentifier sha384WithEC_oid = new
+ ObjectIdentifier(sha384WithEC_data);
+
+ public static final ObjectIdentifier sha512WithEC_oid = new
+ ObjectIdentifier(sha512WithEC_data);
+
+ /**
+ * Identifies a signing algorithm where an MD2 digest is encrypted
+ * using an RSA private key; defined in PKCS #1. Use of this
+ * signing algorithm is discouraged due to MD2 vulnerabilities.
+ * OID = 1.2.840.113549.1.1.2
+ */
+ public static final ObjectIdentifier md2WithRSAEncryption_oid = new
+ ObjectIdentifier(md2WithRSAEncryption_data);
+
+ /**
+ * Identifies a signing algorithm where an MD5 digest is
+ * encrypted using an RSA private key; defined in PKCS #1.
+ * OID = 1.2.840.113549.1.1.4
+ */
+ public static final ObjectIdentifier md5WithRSAEncryption_oid = new
+ ObjectIdentifier(md5WithRSAEncryption_data);
+
+ /**
+ * The proper one for sha1/rsa
+ */
+ public static final ObjectIdentifier sha1WithRSAEncryption_oid = new
+ ObjectIdentifier(sha1WithRSAEncryption_data);
+
+ /**
+ * The proper one for sha256/rsa
+ */
+ public static final ObjectIdentifier sha256WithRSAEncryption_oid = new
+ ObjectIdentifier(sha256WithRSAEncryption_data);
+
+ /**
+ * The proper one for sha512/rsa
+ */
+ public static final ObjectIdentifier sha512WithRSAEncryption_oid = new
+ ObjectIdentifier(sha512WithRSAEncryption_data);
+
+ /**
+ * Identifies a signing algorithm where an SHA1 digest is
+ * encrypted using an RSA private key; defined in NIST OIW.
+ * OID = 1.3.14.3.2.29
+ */
+ public static final ObjectIdentifier sha1WithRSAEncryption_OIW_oid = new
+ ObjectIdentifier(sha1WithRSAEncryption_OIW_data);
+
+ /**
+ * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a
+ * SHA digest is signed using the Digital Signing Algorithm (DSA).
+ * This should not be used.
+ * OID = 1.3.14.3.2.13
+ */
+ public static final ObjectIdentifier shaWithDSA_OIW_oid = new ObjectIdentifier(shaWithDSA_OIW_data);
+
+ /**
+ * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a
+ * SHA1 digest is signed using the Digital Signing Algorithm (DSA).
+ * OID = 1.3.14.3.2.27
+ */
+ public static final ObjectIdentifier sha1WithDSA_OIW_oid = new ObjectIdentifier(sha1WithDSA_OIW_data);
+
+ /**
+ * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a
+ * SHA1 digest is signed using the Digital Signing Algorithm (DSA).
+ * OID = 1.2.840.10040.4.3
+ */
+ public static final ObjectIdentifier sha1WithDSA_oid = new ObjectIdentifier(dsaWithSHA1_PKIX_data);
+
+ /**
+ * Supported signing algorithms for a DSA key.
+ */
+ public static final String[] DSA_SIGNING_ALGORITHMS = new String[]
+ { "SHA1withDSA" };
+
+ /**
+ * Supported signing algorithms for a RSA key.
+ */
+ public static final String[] RSA_SIGNING_ALGORITHMS = new String[]
+ { "SHA1withRSA", "SHA256withRSA", "SHA512withRSA", "MD5withRSA", "MD2withRSA" };
+
+ public static final String[] EC_SIGNING_ALGORITHMS = new String[]
+ { "SHA1withEC", "SHA256withEC", "SHA384withEC", "SHA512withEC" };
+
+ /**
+ * All supported signing algorithms.
+ */
+ public static final String[] ALL_SIGNING_ALGORITHMS = new String[]
+ {
+ "SHA1withRSA", "MD5withRSA", "MD2withRSA", "SHA1withDSA", "SHA256withRSA", "SHA512withRSA", "SHA1withEC",
+ "SHA256withEC", "SHA384withEC", "SHA512withEC" };
+
+}
diff --git a/base/util/src/netscape/security/x509/Attribute.java b/base/util/src/netscape/security/x509/Attribute.java
new file mode 100644
index 000000000..11e22db10
--- /dev/null
+++ b/base/util/src/netscape/security/x509/Attribute.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerEncoder;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * An attribute, as identified by some attribute ID, has some particular values.
+ * Values are as a rule ASN.1 printable strings. A conventional set of type IDs
+ * is recognized when parsing. The following shows the syntax:
+ *
+ * <pre>
+ *
+ * Attribute ::= SEQUENCE {
+ * type AttributeType,
+ * value SET OF AttributeValue
+ * -- at least one value is required --}
+ *
+ * AttributeType ::= OBJECT IDENTIFIER
+ *
+ * AttributeValue ::= ANY
+ *
+ * </pre>
+ *
+ * Refer to draft-ietf-pkix-ipki-part1-11 for the support attributes listed on
+ * page 96 of the internet draft. The are listed here for easy reference: name,
+ * common name, surname, given name, initials, generation qualifier, dn qualifier,
+ * country name, locality name, state or province name, organization name, organization
+ * unit name, title, pkcs9 email. Not all the attributes are supported. Please check
+ * the X500NameAttrMap for defined attributes.
+ *
+ * @author Christine Ho
+ */
+
+public final class Attribute implements Serializable, DerEncoder {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -931486084625476764L;
+ //private variables
+ ObjectIdentifier oid;
+ Vector<String> valueSet = new Vector<String>();
+ transient protected X500NameAttrMap attrMap;
+
+ //========== CONSTRUCTOR ==================================
+
+ /**
+ * Construct an attribute from attribute type and attribute value
+ *
+ * @param oid the object identifier of the attribute type
+ * @param value the value string
+ */
+ public Attribute(ObjectIdentifier oid, String value)
+ throws IOException {
+
+ //pre-condition verification
+ if ((oid == null) || (value == null))
+ throw new IOException("Invalid Input - null passed");
+
+ attrMap = X500NameAttrMap.getDefault();
+ this.oid = oid;
+ valueSet.addElement(value);
+ }
+
+ /**
+ * Construct an attribute from attribute type and attribute values
+ *
+ * @param oid the object identifier of the attribute type
+ * @param values String value vector
+ */
+ public Attribute(ObjectIdentifier oid, Vector<String> values)
+ throws IOException {
+
+ //pre-condition verification
+ if ((oid == null) || (values == null))
+ throw new IOException("Invalid Input - null passed");
+
+ attrMap = X500NameAttrMap.getDefault();
+ this.oid = oid;
+
+ //copy the value into the valueSet list
+ Enumeration<String> vals = values.elements();
+ while (vals.hasMoreElements()) {
+ valueSet.addElement(vals.nextElement());
+ }
+ }
+
+ /**
+ * Construct an attribute from attribute type and attribute values
+ *
+ * @param oid attribute type string CN,OU,O,C,L,TITLE,ST,STREET,UID,MAIL,E,DC
+ * @param values String value vector
+ */
+ public Attribute(String attr, Vector<String> values)
+ throws IOException {
+
+ //pre-condition verification
+ if ((attr == null) || (values == null))
+ throw new IOException("Invalid Input - null passed");
+
+ ObjectIdentifier identifier = null;
+ try {
+ identifier = new ObjectIdentifier(attr);
+ } catch (Exception e) {
+ }
+
+ ObjectIdentifier id = identifier;
+ if (identifier == null) {
+ attrMap = X500NameAttrMap.getDefault();
+ id = attrMap.getOid(attr);
+ if (id == null)
+ throw new IOException("Attr is not supported - does not contain in attr map");
+ }
+ this.oid = id;
+
+ //copy the value into the valueSet list
+ Enumeration<String> vals = values.elements();
+ while (vals.hasMoreElements()) {
+ valueSet.addElement(vals.nextElement());
+ }
+ }
+
+ /**
+ * Construct an attribute from a der encoded object. This der
+ * der encoded value should represent the attribute object.
+ *
+ * @param value the attribute object in der encode form.
+ */
+ public Attribute(DerValue val)
+ throws IOException {
+
+ //pre-condition verification
+ if (val == null)
+ throw new IOException("Invalid Input - null passed");
+
+ attrMap = X500NameAttrMap.getDefault();
+
+ decodeThis(val);
+
+ }
+
+ //========== PUBLIC METHODS ==================================
+
+ /**
+ * Returns the OID in the Attribute.
+ *
+ * @return the ObjectIdentifier in this Attribute.
+ */
+ public ObjectIdentifier getOid() {
+ return oid;
+ }
+
+ /**
+ * Returns enumeration of values in this attribute.
+ *
+ * @return Enumeration of values of this Attribute.
+ */
+ public Enumeration<String> getValues() {
+ if (valueSet == null)
+ return null;
+ return valueSet.elements();
+ }
+
+ /**
+ * Encodes the Attribute to a Der output stream.
+ * Attribute are encoded as a SEQUENCE of two elements.
+ *
+ * @param out The Der output stream.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ encodeThis(out);
+ }
+
+ /**
+ * DER encode this object onto an output stream.
+ * Implements the <code>DerEncoder</code> interface.
+ *
+ * @param out
+ * the output stream on which to write the DER encoding.
+ *
+ * @exception IOException on encoding error.
+ */
+ public void derEncode(OutputStream out) throws IOException {
+ encodeThis(out);
+ }
+
+ /**
+ * Prints a string version of this extension.
+ */
+ public String toString() {
+ String theoid = "Attribute: " + oid + "\n";
+ String values = "Values: ";
+ Enumeration<String> n = valueSet.elements();
+ if (n.hasMoreElements()) {
+ values += n.nextElement();
+ while (n.hasMoreElements())
+ values += "," + n.nextElement();
+ }
+ return theoid + values + "\n";
+ }
+
+ //========== PRIVATE METHODS ==================================
+
+ //encode the attribute object
+ private void encodeThis(OutputStream out)
+ throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ DerOutputStream tmp2 = new DerOutputStream();
+
+ tmp.putOID(oid);
+ encodeValueSet(tmp);
+ tmp2.write(DerValue.tag_Sequence, tmp);
+ out.write(tmp2.toByteArray());
+ }
+
+ //encode the attribute object
+ private void encodeValueSet(OutputStream out)
+ throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ DerOutputStream tmp2 = new DerOutputStream();
+
+ //get the attribute converter
+ AVAValueConverter converter = attrMap.getValueConverter(oid);
+ if (converter == null) {
+ converter = new GenericValueConverter();
+ //throw new IOException("Converter not found: unsupported attribute type");
+ }
+
+ //loop through all the values and encode
+ Enumeration<String> vals = valueSet.elements();
+ while (vals.hasMoreElements()) {
+ String val = vals.nextElement();
+ DerValue derobj = converter.getValue(val);
+ derobj.encode(tmp);
+ }
+
+ tmp2.write(DerValue.tag_SetOf, tmp);
+ out.write(tmp2.toByteArray());
+ }
+
+ //decode the attribute object
+ private void decodeThis(DerValue val)
+ throws IOException {
+
+ //pre-condition verification
+ if (val == null) {
+ throw new IOException("Invalid Input - null passed.");
+ }
+
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding for Attribute.");
+ }
+
+ if (val.data.available() == 0) {
+ throw new IOException("No data available in "
+ + "passed DER encoded value.");
+ }
+ this.oid = val.data.getDerValue().getOID();
+
+ if (val.data.available() == 0) {
+ throw new IOException("Invalid encoding for Attribute - value missing");
+ }
+ decodeValueSet(val.data.getDerValue());
+
+ if (this.oid == null)
+ throw new IOException("Invalid encoding for Attribute - OID missing");
+
+ }
+
+ //decode the attribute value set
+ private void decodeValueSet(DerValue val)
+ throws IOException {
+ //pre-condition verification
+ if (val == null) {
+ throw new IOException("Invalid Input - null passed.");
+ }
+
+ AVAValueConverter converter = attrMap.getValueConverter(this.oid);
+ if (converter == null) {
+ converter = new GenericValueConverter();
+ //throw new IOException("Attribute is not supported - not in attr map");
+ }
+
+ if (val.tag != DerValue.tag_SetOf) {
+ throw new IOException("Invalid encoding for Attribute Value Set.");
+ }
+
+ if (val.data.available() == 0) {
+ throw new IOException("No data available in "
+ + "passed DER encoded attribute value set.");
+ }
+
+ //get the value set
+ while (val.data.available() != 0) {
+ DerValue value = val.data.getDerValue();
+ valueSet.addElement(converter.getAsString(value));
+ }
+ }
+
+}
diff --git a/base/util/src/netscape/security/x509/AuthorityKeyIdentifierExtension.java b/base/util/src/netscape/security/x509/AuthorityKeyIdentifierExtension.java
new file mode 100644
index 000000000..91b6c2598
--- /dev/null
+++ b/base/util/src/netscape/security/x509/AuthorityKeyIdentifierExtension.java
@@ -0,0 +1,340 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class represents the Authority Key Identifier Extension.
+ *
+ * <p>
+ * The authority key identifier extension provides a means of identifying the particular public key used to sign a
+ * certificate. This extension would be used where an issuer has multiple signing keys (either due to multiple
+ * concurrent key pairs or due to changeover).
+ * <p>
+ * The ASN.1 syntax for this is:
+ *
+ * <pre>
+ * AuthorityKeyIdentifier ::= SEQUENCE {
+ * keyIdentifier [0] KeyIdentifier OPTIONAL,
+ * authorityCertIssuer [1] GeneralNames OPTIONAL,
+ * authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL
+ * }
+ * KeyIdentifier ::= OCTET STRING
+ * </pre>
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.9
+ * @see Extension
+ * @see CertAttrSet
+ */
+public class AuthorityKeyIdentifierExtension extends Extension
+ implements CertAttrSet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -157913621972354170L;
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT =
+ "x509.info.extensions.AuthorityKeyIdentifier";
+ /**
+ * Attribute names.
+ */
+ public static final String NAME = "AuthorityKeyIdentifier";
+ public static final String KEY_ID = "key_id";
+ public static final String AUTH_NAME = "auth_name";
+ public static final String SERIAL_NUMBER = "serial_number";
+
+ // Private data members
+ private static final byte TAG_ID = 0;
+ private static final byte TAG_NAMES = 1;
+ private static final byte TAG_SERIAL_NUM = 2;
+
+ private KeyIdentifier id = null;
+ private GeneralNames names = null;
+ private SerialNumber serialNum = null;
+
+ // Encode only the extension value
+ private void encodeThis() throws IOException {
+ DerOutputStream seq = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+ if (id != null) {
+ DerOutputStream tmp1 = new DerOutputStream();
+ id.encode(tmp1);
+ tmp.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
+ false, TAG_ID), tmp1);
+ }
+ try {
+ if (names != null) {
+ DerOutputStream tmp1 = new DerOutputStream();
+ names.encode(tmp1);
+ tmp.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
+ true, TAG_NAMES), tmp1);
+ }
+ } catch (Exception e) {
+ throw new IOException(e.toString());
+ }
+ if (serialNum != null) {
+ DerOutputStream tmp1 = new DerOutputStream();
+ serialNum.encode(tmp1);
+ tmp.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
+ false, TAG_SERIAL_NUM), tmp1);
+ }
+ seq.write(DerValue.tag_Sequence, tmp);
+ this.extensionValue = seq.toByteArray();
+ }
+
+ /**
+ * Exposed critical parameter. 99/11/03
+ */
+ public AuthorityKeyIdentifierExtension(boolean critical,
+ KeyIdentifier kid, GeneralNames name,
+ SerialNumber sn)
+ throws IOException {
+ this.id = kid;
+ this.names = name;
+ this.serialNum = sn;
+
+ this.extensionId = PKIXExtensions.AuthorityKey_Id;
+ this.critical = critical;
+ encodeThis();
+ }
+
+ /**
+ * The default constructor for this extension. Null parameters make
+ * the element optional (not present).
+ *
+ * @param id the KeyIdentifier associated with this extension.
+ * @param names the GeneralNames associated with this extension
+ * @param serialNum the CertificateSerialNumber associated with
+ * this extension.
+ * @exception IOException on error.
+ */
+ public AuthorityKeyIdentifierExtension(KeyIdentifier kid, GeneralNames name,
+ SerialNumber sn)
+ throws IOException {
+ this.id = kid;
+ this.names = name;
+ this.serialNum = sn;
+
+ this.extensionId = PKIXExtensions.AuthorityKey_Id;
+ this.critical = false;
+ encodeThis();
+ }
+
+ /**
+ * Create the extension from the passed DER encoded value of the same.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param value Array of DER encoded bytes of the actual value.
+ * @exception IOException on error.
+ */
+ public AuthorityKeyIdentifierExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = PKIXExtensions.AuthorityKey_Id;
+ this.critical = critical.booleanValue();
+
+ if (!(value instanceof byte[]))
+ throw new IOException("Illegal argument type");
+
+ int len = Array.getLength(value);
+ byte[] extValue = new byte[len];
+ System.arraycopy(value, 0, extValue, 0, len);
+
+ this.extensionValue = extValue;
+ DerValue val = new DerValue(extValue);
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding for " +
+ "AuthorityKeyIdentifierExtension.");
+ }
+
+ // NB. this is always encoded with the IMPLICIT tag
+ // The checks only make sense if we assume implicit tagging,
+ // with explicit tagging the form is always constructed.
+ while (val.data.available() != 0) {
+ DerValue opt = val.data.getDerValue();
+
+ if (opt.isContextSpecific(TAG_ID) && !opt.isConstructed()) {
+ if (id != null)
+ throw new IOException("Duplicate KeyIdentifier in " +
+ "AuthorityKeyIdentifier.");
+ opt.resetTag(DerValue.tag_OctetString);
+ id = new KeyIdentifier(opt);
+
+ } else if (opt.isContextSpecific(TAG_NAMES) &&
+ opt.isConstructed()) {
+ if (names != null)
+ throw new IOException("Duplicate GeneralNames in " +
+ "AuthorityKeyIdentifier.");
+ try {
+ opt.resetTag(DerValue.tag_Sequence);
+ names = new GeneralNames(opt);
+ } catch (GeneralNamesException e) {
+ throw new IOException(e.toString());
+ }
+
+ } else if (opt.isContextSpecific(TAG_SERIAL_NUM) &&
+ !opt.isConstructed()) {
+ if (serialNum != null)
+ throw new IOException("Duplicate SerialNumber in " +
+ "AuthorityKeyIdentifier.");
+ opt.resetTag(DerValue.tag_Integer);
+ serialNum = new SerialNumber(opt);
+ } else
+ throw new IOException("Invalid encoding of " +
+ "AuthorityKeyIdentifierExtension.");
+ }
+ }
+
+ /**
+ * Return the object as a string.
+ */
+ public String toString() {
+ String s = super.toString() + "AuthorityKeyIdentifier [\n";
+ if (id != null) {
+ s += id.toString();
+ }
+ if (names != null) {
+ s += names.toString() + "\n";
+ }
+ if (serialNum != null) {
+ s += serialNum.toString() + "\n";
+ }
+ return (s + "]\n");
+ }
+
+ /**
+ * Decode the extension from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ /**
+ * Write the extension to the OutputStream.
+ *
+ * @param out the OutputStream to write the extension to.
+ * @exception IOException on error.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ if (this.extensionValue == null) {
+ extensionId = PKIXExtensions.AuthorityKey_Id;
+ critical = false;
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ clearValue();
+ if (name.equalsIgnoreCase(KEY_ID)) {
+ if (!(obj instanceof KeyIdentifier)) {
+ throw new IOException("Attribute value should be of " +
+ "type KeyIdentifier.");
+ }
+ id = (KeyIdentifier) obj;
+ } else if (name.equalsIgnoreCase(AUTH_NAME)) {
+ if (!(obj instanceof GeneralNames)) {
+ throw new IOException("Attribute value should be of " +
+ "type GeneralNames.");
+ }
+ names = (GeneralNames) obj;
+ } else if (name.equalsIgnoreCase(SERIAL_NUMBER)) {
+ if (!(obj instanceof SerialNumber)) {
+ throw new IOException("Attribute value should be of " +
+ "type SerialNumber.");
+ }
+ serialNum = (SerialNumber) obj;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:AuthorityKeyIdentifier.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(KEY_ID)) {
+ return (id);
+ } else if (name.equalsIgnoreCase(AUTH_NAME)) {
+ return (names);
+ } else if (name.equalsIgnoreCase(SERIAL_NUMBER)) {
+ return (serialNum);
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:AuthorityKeyIdentifier.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(KEY_ID)) {
+ id = null;
+ } else if (name.equalsIgnoreCase(AUTH_NAME)) {
+ names = null;
+ } else if (name.equalsIgnoreCase(SERIAL_NUMBER)) {
+ serialNum = null;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:AuthorityKeyIdentifier.");
+ }
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(KEY_ID);
+ elements.addElement(AUTH_NAME);
+ elements.addElement(SERIAL_NUMBER);
+
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/BasicConstraintsExtension.java b/base/util/src/netscape/security/x509/BasicConstraintsExtension.java
new file mode 100644
index 000000000..2688e961d
--- /dev/null
+++ b/base/util/src/netscape/security/x509/BasicConstraintsExtension.java
@@ -0,0 +1,295 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class represents the Basic Constraints Extension.
+ *
+ * <p>
+ * The basic constraints extension identifies whether the subject of the certificate is a CA and how deep a
+ * certification path may exist through that CA.
+ *
+ * <pre>
+ * The ASN.1 syntax for this extension is:
+ * BasicConstraints ::= SEQUENCE {
+ * cA BOOLEAN DEFAULT FALSE,
+ * pathLenConstraint INTEGER (0..MAX) OPTIONAL
+ * }
+ * </pre>
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.7
+ * @see CertAttrSet
+ * @see Extension
+ */
+public class BasicConstraintsExtension extends Extension
+ implements CertAttrSet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6213957094939885889L;
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT = "x509.info.extensions.BasicConstraints";
+ /**
+ * Attribute names.
+ */
+ public static final String NAME = "BasicConstraints";
+ public static final String IS_CA = "is_ca";
+ public static final String PATH_LEN = "path_len";
+
+ // Private data members
+ private boolean ca = false;
+ private int pathLen = -1;
+
+ // Encode this extension value
+ private void encodeThis() throws IOException {
+ DerOutputStream out = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+
+ if (ca) {
+ tmp.putBoolean(ca);
+ }
+ if (pathLen >= 0) {
+ tmp.putInteger(new BigInt(pathLen));
+ }
+ out.write(DerValue.tag_Sequence, tmp);
+ this.extensionValue = out.toByteArray();
+ }
+
+ /**
+ * Default constructor for this object.
+ *
+ * @param ca true, if the subject of the Certificate is a CA.
+ * @param len specifies the depth of the certification path.
+ */
+ public BasicConstraintsExtension(boolean ca, int len) throws IOException {
+ this.ca = ca;
+ this.pathLen = len;
+ this.extensionId = PKIXExtensions.BasicConstraints_Id;
+ if (ca) {
+ critical = true;
+ } else {
+ critical = false;
+ }
+ encodeThis();
+ }
+
+ /**
+ * Default constructor for this object.
+ *
+ * @param ca true, if the subject of the Certificate is a CA.
+ * @param len specifies the depth of the certification path.
+ */
+ public BasicConstraintsExtension(boolean ca, boolean critical, int len) throws IOException {
+ this.ca = ca;
+ this.pathLen = len;
+ this.extensionId = PKIXExtensions.BasicConstraints_Id;
+ this.critical = critical;
+ encodeThis();
+ }
+
+ /**
+ * Create the extension from the passed DER encoded value of the same.
+ *
+ * @param extension the DER encoded value of the extension.
+ * @exception IOException on error.
+ */
+ public BasicConstraintsExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = PKIXExtensions.BasicConstraints_Id;
+ this.critical = critical.booleanValue();
+
+ if (value instanceof byte[]) {
+ int len = Array.getLength(value);
+ byte[] extValue = new byte[len];
+ System.arraycopy(value, 0, extValue, 0, len);
+
+ this.extensionValue = extValue;
+ DerValue val = new DerValue(extValue);
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding of BasicConstraints");
+ }
+
+ // non-CA cert with no limit to certification path length
+ if (val.data == null || val.data.available() < 1) {
+ this.ca = false;
+ this.pathLen = -1;
+ return;
+ }
+ DerValue opt = val.data.getDerValue();
+ if (opt.tag != DerValue.tag_Boolean) {
+ this.ca = false;
+ } else {
+ this.ca = true;
+ if (val.data.available() != 0) {
+ opt = val.data.getDerValue();
+ } else {
+ this.pathLen = -1;
+ return;
+ }
+ }
+ if (opt.tag != DerValue.tag_Integer) {
+ throw new IOException("Invalid encoding of BasicConstraints");
+ }
+ this.pathLen = (opt.getInteger()).toInt();
+ /*
+ * Activate this check once again after PKIX profiling
+ * is a standard and this check no longer imposes an
+ * interoperability barrier.
+ * if (ca) {
+ * if (!this.critical) {
+ * throw new IOException("Criticality cannot be false for CA.");
+ * }
+ * }
+ */
+ } else
+ throw new IOException("Invalid argument type");
+ }
+
+ /**
+ * Return user readable form of extension.
+ */
+ public String toString() {
+ String s = super.toString() + "BasicConstraints:[\n";
+
+ s += ((ca) ? ("CA:true") : ("CA:false")) + "\n";
+ if (pathLen >= 0) {
+ s += "PathLen:" + pathLen + "\n";
+ } else {
+ s += "PathLen: undefined\n";
+ }
+ return (s + "]\n");
+ }
+
+ /**
+ * Decode the extension from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ /**
+ * Encode this extension value to the output stream.
+ *
+ * @param out the DerOutputStream to encode the extension to.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ if (extensionValue == null) {
+ this.extensionId = PKIXExtensions.BasicConstraints_Id;
+ /* #57286 - so that profile can set critiality */
+ /*
+ if (ca) {
+ critical = true;
+ } else {
+ critical = false;
+ }
+ */
+ encodeThis();
+ }
+ super.encode(tmp);
+
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ clearValue();
+ if (name.equalsIgnoreCase(IS_CA)) {
+ if (!(obj instanceof Boolean)) {
+ throw new IOException("Attribute value should be of type Boolean.");
+ }
+ ca = ((Boolean) obj).booleanValue();
+ } else if (name.equalsIgnoreCase(PATH_LEN)) {
+ if (!(obj instanceof Integer)) {
+ throw new IOException("Attribute value should be of type Integer.");
+ }
+ pathLen = ((Integer) obj).intValue();
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:BasicConstraints.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(IS_CA)) {
+ return (new Boolean(ca));
+ } else if (name.equalsIgnoreCase(PATH_LEN)) {
+ return (Integer.valueOf(pathLen));
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:BasicConstraints.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(IS_CA)) {
+ ca = false;
+ } else if (name.equalsIgnoreCase(PATH_LEN)) {
+ pathLen = -1;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:BasicConstraints.");
+ }
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(IS_CA);
+ elements.addElement(PATH_LEN);
+
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/CPSuri.java b/base/util/src/netscape/security/x509/CPSuri.java
new file mode 100644
index 000000000..d0a2e0762
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CPSuri.java
@@ -0,0 +1,66 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.IOException;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * Represent the CPSuri Qualifier.
+ *
+ * CPSuri ::= IA5String;
+ *
+ * @author Thomas Kwan
+ */
+public class CPSuri extends Qualifier {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2814961293159006960L;
+ private String mURI = null;
+
+ /**
+ * Create a PolicyQualifierInfo
+ *
+ * @param id the ObjectIdentifier for the policy id.
+ */
+ public CPSuri(String uri) {
+ mURI = uri;
+ }
+
+ public CPSuri(DerValue val) throws IOException {
+ mURI = val.getIA5String();
+ }
+
+ /**
+ * Write the PolicyQualifier to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the object to.
+ * @exception IOException on errors.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ out.putIA5String(mURI);
+ }
+
+ public String getURI() {
+ return mURI;
+ }
+}
diff --git a/base/util/src/netscape/security/x509/CRLDistributionPoint.java b/base/util/src/netscape/security/x509/CRLDistributionPoint.java
new file mode 100644
index 000000000..c7ad84389
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CRLDistributionPoint.java
@@ -0,0 +1,467 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import netscape.security.util.BitArray;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.asn1.ASN1Template;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.BIT_STRING;
+import org.mozilla.jss.asn1.EXPLICIT;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.Tag;
+
+/**
+ * <pre>
+ * DistributionPoint ::= SEQUENCE {
+ * distributionPoint [0] DistributionPointName OPTIONAL,
+ * reasons [1] ReasonFlags OPTIONAL,
+ * cRLIssuer [2] GeneralNames OPTIONAL }
+ *
+ * DistributionPointName ::= CHOICE {
+ * fullName [0] GeneralNames,
+ * nameRelativeToCRLIssuer [1] RelativeDistinguishedName }
+ *
+ * ReasonFlags ::= BIT STRING {
+ * unused (0),
+ * keyCompromise (1),
+ * cACompromise (2),
+ * affiliationChanged (3),
+ * superseded (4),
+ * cessationOfOperation (5),
+ * certificateHold (6) }
+ * </pre>
+ */
+public class CRLDistributionPoint implements ASN1Value {
+
+ // at most one of the two following may be specified:
+ private GeneralNames fullName;
+ private RDN relativeName;
+
+ // cache encoding of fullName
+ private ANY fullNameEncoding;
+
+ private BitArray reasons; // optional, may be null
+ private GeneralNames CRLIssuer; // optional, may be null
+ private ANY CRLIssuerEncoding;
+
+ // default constructor does nothing.
+
+ /**
+ * Returns the <code>fullName</code> of the <code>DistributionPointName</code>, which may be <code>null</code>.
+ */
+ public GeneralNames getFullName() {
+ return fullName;
+ }
+
+ /**
+ * Returns the <code>relativeName</code> of the <code>DistributionPointName</code>, which may be <code>null</code>.
+ */
+ public RDN getRelativeName() {
+ return relativeName;
+ }
+
+ /**
+ * Sets the <code>fullName</code> of the <code>DistributionPointName</code>. It may be set to <code>null</code>.
+ * If it is set to a non-null value, <code>relativeName</code> will be
+ * set to <code>null</code>, because at most one of these two attributes
+ * can be specified at a time.
+ *
+ * @exception GeneralNamesException If an error occurs encoding the
+ * name.
+ */
+ public void setFullName(GeneralNames fullName)
+ throws GeneralNamesException, IOException {
+ this.fullName = fullName;
+ if (fullName != null) {
+ // encode the name to catch any problems with it
+ DerOutputStream derOut = new DerOutputStream();
+ fullName.encode(derOut);
+ try {
+ ANY raw = new ANY(derOut.toByteArray());
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ raw.encodeWithAlternateTag(Tag.get(0), bos);
+ fullNameEncoding = new ANY(bos.toByteArray());
+ } catch (InvalidBERException e) {
+ // assume this won't happen, since it would imply a bug
+ // in DerOutputStream
+ throw new GeneralNamesException(e.toString());
+ }
+
+ this.relativeName = null;
+ }
+ }
+
+ /**
+ * Sets the <code>relativeName</code> of the <code>DistributionPointName</code>. It may be set to <code>null</code>.
+ * If it is set to a non-null value, <code>fullName</code> will be
+ * set to <code>null</code>, because at most one of these two attributes
+ * can be specified at a time.
+ */
+ public void setRelativeName(RDN relativeName) {
+ this.relativeName = relativeName;
+ if (relativeName != null) {
+ this.fullName = null;
+ }
+ }
+
+ /**
+ * Returns the reason flags for this distribution point. May be <code>null</code>.
+ */
+ public BitArray getReasons() {
+ return reasons;
+ }
+
+ /**
+ * Sets the reason flags for this distribution point. May be set to <code>null</code>.
+ */
+ public void setReasons(BitArray reasons) {
+ this.reasons = reasons;
+ }
+
+ /**
+ * Returns the CRLIssuer for the CRL at this distribution point.
+ * May be <code>null</code>.
+ */
+ public GeneralNames getCRLIssuer() {
+ return CRLIssuer;
+ }
+
+ /**
+ * Sets the CRLIssuer for the CRL at this distribution point.
+ * May be set to <code>null</code>.
+ *
+ * @exception GeneralNamesException If an error occurs encoding the name.
+ */
+ public void setCRLIssuer(GeneralNames CRLIssuer)
+ throws GeneralNamesException, IOException {
+ this.CRLIssuer = CRLIssuer;
+
+ if (CRLIssuer != null) {
+ // encode the name to catch any problems with it
+ DerOutputStream derOut = new DerOutputStream();
+ CRLIssuer.encode(derOut);
+ try {
+ ANY raw = new ANY(derOut.toByteArray());
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ raw.encodeWithAlternateTag(Tag.get(2), bos);
+ CRLIssuerEncoding = new ANY(bos.toByteArray());
+ } catch (InvalidBERException e) {
+ throw new GeneralNamesException(e.toString());
+ }
+ }
+ }
+
+ /////////////////////////////////////////////////////////////
+ // DER encoding
+ /////////////////////////////////////////////////////////////
+
+ private static final Tag TAG = SEQUENCE.TAG;
+
+ public Tag getTag() {
+ return TAG;
+ }
+
+ public void encode(OutputStream ostream) throws IOException {
+ encode(TAG, ostream);
+ }
+
+ public void encode(Tag implicitTag, OutputStream ostream)
+ throws IOException {
+ SEQUENCE seq = new SEQUENCE();
+ DerOutputStream derOut;
+
+ try {
+
+ // Encodes the DistributionPointName. Because DistributionPointName
+ // is a CHOICE, the [0] tag is forced to be EXPLICIT.
+ if (fullName != null) {
+ EXPLICIT distPoint = new EXPLICIT(Tag.get(0), fullNameEncoding);
+ seq.addElement(distPoint);
+ } else if (relativeName != null) {
+ derOut = new DerOutputStream();
+ relativeName.encode(derOut);
+ ANY rn = new ANY(derOut.toByteArray());
+ EXPLICIT raw = new EXPLICIT(Tag.get(1), rn);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ raw.encode(bos);
+ ANY distPointName = new ANY(bos.toByteArray());
+ EXPLICIT distPoint = new EXPLICIT(Tag.get(0), distPointName);
+ seq.addElement(distPoint);
+ }
+
+ // Encodes the ReasonFlags.
+ if (reasons != null) {
+ derOut = new DerOutputStream();
+ derOut.putUnalignedBitString(reasons);
+ ANY raw = new ANY(derOut.toByteArray());
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ raw.encodeWithAlternateTag(Tag.get(1), bos);
+ ANY reasonEncoding = new ANY(bos.toByteArray());
+ seq.addElement(Tag.get(1), reasonEncoding);
+ }
+
+ // Encodes the CRLIssuer
+ if (CRLIssuer != null) {
+ seq.addElement(Tag.get(2), CRLIssuerEncoding);
+ }
+
+ seq.encode(implicitTag, ostream);
+
+ } catch (InvalidBERException e) {
+ // this shouldn't happen unless there is a bug in one of
+ // the Sun encoding classes
+ throw new IOException(e.toString());
+ }
+ }
+
+ // Template singleton
+ private static Template templateInstance = new Template();
+
+ /**
+ * Returns an instance of a template for decoding a CRLDistributionPoint.
+ */
+ public static Template getTemplate() {
+ return templateInstance;
+ }
+
+ public static void main(String args[]) {
+ try {
+ if (args.length != 1) {
+ System.out.println("Usage: CRLDistributionPoint <outfile>");
+ System.exit(-1);
+ }
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ SEQUENCE cdps = new SEQUENCE();
+
+ // URI only
+ CRLDistributionPoint cdp = new CRLDistributionPoint();
+ URIName uri = new URIName("http://www.mycrl.com/go/here");
+ GeneralNames generalNames = new GeneralNames();
+ generalNames.addElement(uri);
+ cdp.setFullName(generalNames);
+ cdps.addElement(cdp);
+
+ // DN only
+ cdp = new CRLDistributionPoint();
+ X500Name dn = new X500Name("CN=Otis Smith,E=otis@fedoraproject.org" +
+ ",OU=Certificate Server,O=Fedora,C=US");
+ generalNames = new GeneralNames();
+ generalNames.addElement(dn);
+ cdp.setFullName(generalNames);
+ cdps.addElement(cdp);
+
+ // DN + reason
+ BitArray ba = new BitArray(5, new byte[] { (byte) 0x28 });
+ cdp = new CRLDistributionPoint();
+ cdp.setFullName(generalNames);
+ cdp.setReasons(ba);
+ cdps.addElement(cdp);
+
+ // relative DN + reason + crlIssuer
+ cdp = new CRLDistributionPoint();
+ RDN rdn = new RDN("OU=foobar dept");
+ cdp.setRelativeName(rdn);
+ cdp.setReasons(ba);
+ cdp.setCRLIssuer(generalNames);
+ cdps.addElement(cdp);
+
+ cdps.encode(bos);
+
+ byte[] encoded = bos.toByteArray();
+ (new FileOutputStream(args[0])).write(encoded);
+
+ SEQUENCE.OF_Template seqt = new SEQUENCE.OF_Template(getTemplate());
+
+ cdps = (SEQUENCE) ASN1Util.decode(seqt, encoded);
+
+ int size = cdps.size();
+ System.out.println("Total number of CDPs: " + size);
+ for (int i = 0; i < size; i++) {
+ System.out.println("\nCDP " + i);
+ cdp = (CRLDistributionPoint) cdps.elementAt(i);
+ GeneralNames gn = cdp.getFullName();
+ if (gn == null) {
+ System.out.println("No full name");
+ } else {
+ System.out.println(gn);
+ }
+ rdn = cdp.getRelativeName();
+ if (rdn == null) {
+ System.out.println("No relative name");
+ } else {
+ System.out.println(rdn);
+ }
+ if (cdp.getReasons() == null) {
+ System.out.println("No reasons");
+ } else {
+ System.out.println(cdp.getReasons());
+ }
+ gn = cdp.getCRLIssuer();
+ if (gn == null) {
+ System.out.println("No cRLIssuer");
+ } else {
+ System.out.println(gn);
+ }
+ }
+ System.out.println("Done");
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Template for decoding CRLDistributionPoint.
+ */
+ public static class Template implements ASN1Template {
+
+ public boolean tagMatch(Tag tag) {
+ return TAG.equals(tag);
+ }
+
+ public ASN1Value decode(InputStream istream)
+ throws IOException, InvalidBERException {
+ return decode(TAG, istream);
+ }
+
+ public ASN1Value decode(Tag implicitTag, InputStream istream)
+ throws IOException, InvalidBERException {
+ CRLDistributionPoint cdp = new CRLDistributionPoint();
+
+ //
+ // construct the top-level sequence
+ //
+
+ SEQUENCE.Template seqt = SEQUENCE.getTemplate();
+
+ // distributionPoint
+ seqt.addOptionalElement(
+ new EXPLICIT.Template(Tag.get(0), ANY.getTemplate()));
+
+ // reasons
+ seqt.addOptionalElement(Tag.get(1), BIT_STRING.getTemplate());
+
+ // cRLIssuer
+ // This will have a tag of 2, but we can't say that here
+ // because ANYs can't have implicit tags. We don't need to say
+ // it, because we do check the tags on the other two elements
+ // in the sequence, so we'll know if we get this one.
+ seqt.addOptionalElement(ANY.getTemplate());
+
+ //
+ // decode the top-level sequence
+ //
+ SEQUENCE top = (SEQUENCE) seqt.decode(implicitTag, istream);
+
+ // decode the distribution point name
+ if (top.elementAt(0) != null) {
+ EXPLICIT exp = (EXPLICIT) top.elementAt(0);
+ ANY distPoint = (ANY) exp.getContent();
+ if (distPoint.getTag().equals(Tag.get(0))) {
+ // fullName
+ try {
+ DerValue dv = new DerValue(distPoint.getEncoded());
+ //toFile("encodedFullName", distPoint.getEncoded());
+ dv.resetTag(DerValue.tag_Sequence);
+ cdp.setFullName(new GeneralNames(dv));
+ } catch (GeneralNamesException e) {
+ throw new InvalidBERException("fullName: " + e.toString());
+ } catch (IOException e) {
+ throw new InvalidBERException("fullName: " + e.toString());
+ }
+ } else if (distPoint.getTag().equals(Tag.get(1))) {
+ // relative name
+ try {
+ DerValue dv = new DerValue(distPoint.getEncoded());
+ /* dv is as follows:
+ 0 12: [1] {
+ 2 10: SET {
+ 4 8: SEQUENCE {
+ 6 3: OBJECT IDENTIFIER commonName (2 5 4 3)
+ 11 1: PrintableString 'x'
+ : }
+ : }
+ : }
+ */
+ dv = dv.data.getDerValue(); // skipping the tag
+ /* after the skipping, we have:
+ 0 10: SET {
+ 2 8: SEQUENCE {
+ 4 3: OBJECT IDENTIFIER commonName (2 5 4 3)
+ 9 1: PrintableString 'x'
+ : }
+ : }
+ */
+ dv.resetTag(DerValue.tag_Set);
+ cdp.setRelativeName(new RDN(dv));
+ } catch (IOException e) {
+ throw new InvalidBERException("relativeName " +
+ e.toString());
+ }
+ } else {
+ throw new InvalidBERException(
+ "Unknown tag " + distPoint.getTag() +
+ " in distributionPoint");
+ }
+ }
+
+ // decode the reasons
+ if (top.elementAt(1) != null) {
+ BIT_STRING bs = (BIT_STRING) top.elementAt(1);
+ byte[] bits = bs.getBits();
+ cdp.setReasons(
+ new BitArray((bits.length * 8) - bs.getPadCount(), bits));
+ }
+
+ // decode the cRLIssuer
+ if (top.elementAt(2) != null) {
+ ANY issuer = (ANY) top.elementAt(2);
+ if (!issuer.getTag().equals(Tag.get(2))) {
+ throw new InvalidBERException("Invalid tag " + issuer.getTag());
+ }
+ try {
+ DerValue dv = new DerValue(issuer.getEncoded());
+ dv.resetTag(DerValue.tag_Sequence);
+ cdp.setCRLIssuer(new GeneralNames(dv));
+ } catch (GeneralNamesException e) {
+ throw new InvalidBERException("cRLIssuer " + e.toString());
+ } catch (IOException e) {
+ throw new InvalidBERException("cRLIssuer " + e.toString());
+ }
+ }
+
+ return cdp;
+
+ }
+ }
+
+}
diff --git a/base/util/src/netscape/security/x509/CRLDistributionPointsExtension.java b/base/util/src/netscape/security/x509/CRLDistributionPointsExtension.java
new file mode 100644
index 000000000..c939a7431
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CRLDistributionPointsExtension.java
@@ -0,0 +1,391 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.BufferedOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import netscape.security.util.BitArray;
+import netscape.security.util.DerOutputStream;
+
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.SEQUENCE;
+
+/**
+ * An extension that tells applications where to find the CRL for
+ * this certificate.
+ *
+ * <pre>
+ * cRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
+ *
+ * DistributionPoint ::= SEQUENCE {
+ * distributionPoint [0] DistributionPointName OPTIONAL,
+ * reasons [1] ReasonFlags OPTIONAL,
+ * cRLIssuer [2] GeneralNames OPTIONAL }
+ *
+ * DistributionPointName ::= CHOICE {
+ * fullName [0] GeneralNames,
+ * nameRelativeToCRLIssuer [1] RelativeDistinguishedName }
+ *
+ * ReasonFlags ::= BIT STRING {
+ * unused (0),
+ * keyCompromise (1),
+ * cACompromise (2),
+ * affiliationChanged (3),
+ * superseded (4),
+ * cessationOfOperation (5),
+ * certificateHold (6) }
+ * </pre>
+ */
+public class CRLDistributionPointsExtension extends Extension
+ implements CertAttrSet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8551761833349709229L;
+ // vector of CRLDistributionPoint
+ private SEQUENCE distributionPoints = new SEQUENCE();
+
+ // Cached DER-encoding to improve performance.
+ private byte[] cachedEncoding = null;
+
+ /**
+ * This constructor is called by the CertificateExtensions class to decode
+ * an extension whose OID indicates it is a CRLDistributionsPoints
+ * extension.
+ */
+ public CRLDistributionPointsExtension(Boolean critical, Object value)
+ //throws IOException
+ {
+ try {
+
+ this.extensionId = PKIXExtensions.CRLDistributionPoints_Id;
+ this.critical = critical.booleanValue();
+ this.extensionValue = (byte[]) ((byte[]) value).clone();
+
+ // decode the value
+ try {
+ SEQUENCE.OF_Template seqOfCRLDP =
+ new SEQUENCE.OF_Template(CRLDistributionPoint.getTemplate());
+
+ distributionPoints =
+ (SEQUENCE) ASN1Util.decode(seqOfCRLDP, extensionValue);
+ } catch (InvalidBERException e) {
+ throw new IOException("Invalid BER-encoding: " + e.toString());
+ }
+ } catch (IOException e) {
+ System.out.println("Big error");
+ System.out.println(e);
+ e.printStackTrace();
+ //throw e;
+ }
+ }
+
+ /**
+ * The Object Identifier for this extension.
+ */
+ public static final String OID = "2.5.29.31";
+
+ /**
+ * Creates a new CRLDistributionPoints extension, with the given
+ * distribution point as the first element.
+ */
+ public CRLDistributionPointsExtension(CRLDistributionPoint dp) {
+ this.extensionId = PKIXExtensions.CRLDistributionPoints_Id;
+ this.critical = false;
+ distributionPoints.addElement(dp);
+ }
+
+ /**
+ * Adds an additional distribution point to the end of the sequence.
+ */
+ public void addPoint(CRLDistributionPoint dp) {
+ distributionPoints.addElement(dp);
+ cachedEncoding = null;
+ }
+
+ /**
+ * Returns the number of distribution points in the sequence.
+ */
+ public int getNumPoints() {
+ return distributionPoints.size();
+ }
+
+ /**
+ * Returns the DistributionPoint at the given index in the sequence.
+ */
+ public CRLDistributionPoint getPointAt(int index) {
+ return (CRLDistributionPoint) distributionPoints.elementAt(index);
+ }
+
+ /**
+ * Sets the criticality of this extension. PKIX dictates that this
+ * extension SHOULD NOT be critical, so applications can make it critical
+ * if they have a very good reason. By default, the extension is not
+ * critical.
+ */
+ public void setCritical(boolean critical) {
+ this.critical = critical;
+ }
+
+ /**
+ * Encodes this extension to the given DerOutputStream.
+ * This method re-encodes each time it is called, so it is not very
+ * efficient.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ extensionValue = ASN1Util.encode(distributionPoints);
+ super.encode(out);
+ }
+
+ /**
+ * Should be called if any change is made to this data structure
+ * so that the cached DER encoding can be discarded.
+ */
+ public void flushCachedEncoding() {
+ cachedEncoding = null;
+ }
+
+ /////////////////////////////////////////////////////////////
+ // CertAttrSet interface
+ // This interface is not really appropriate for this extension
+ // because it is so complicated. Therefore, we only provide a
+ // minimal implementation.
+ /////////////////////////////////////////////////////////////
+ public static final String NAME = "CRLDistributionPoints";
+
+ static {
+ try {
+ OIDMap.addAttribute(CRLDistributionPointsExtension.class.getName(),
+ OID, NAME);
+ } catch (CertificateException e) {
+ }
+ }
+
+ public String toString() {
+ return NAME;
+ }
+
+ /**
+ * DER-encodes this extension to the given OutputStream.
+ */
+ public void encode(OutputStream ostream)
+ throws CertificateException, IOException {
+ if (cachedEncoding == null) {
+ // only re-encode if necessary
+ DerOutputStream tmp = new DerOutputStream();
+ encode(tmp);
+ cachedEncoding = tmp.toByteArray();
+ }
+ ostream.write(cachedEncoding);
+ }
+
+ public void decode(InputStream in)
+ throws CertificateException, IOException {
+ throw new IOException("Not supported");
+ }
+
+ public void set(String name, Object obj)
+ throws CertificateException, IOException {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:CRLDistributionPointsExtension");
+ }
+
+ public Object get(String name)
+ throws CertificateException, IOException {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:CRLDistributionPointsExtension");
+ }
+
+ public void delete(String name)
+ throws CertificateException, IOException {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:CRLDistributionPointsExtension");
+ }
+
+ /*
+ * TODO use an empty collection to generate these
+ */
+ public Enumeration<String> getAttributeNames() {
+ return (new Vector<String>()).elements();
+ }
+
+ public String getName() {
+ return NAME;
+ }
+
+ /**
+ * Test driver.
+ */
+ public static void main(String args[]) {
+
+ try {
+
+ if (args.length != 1) {
+ System.out.println("Usage: CRLDistributionPointsExtentions " +
+ "<outfile>");
+ System.exit(-1);
+ }
+
+ BufferedOutputStream bos = new BufferedOutputStream(
+ new FileOutputStream(args[0]));
+
+ // URI only
+ CRLDistributionPoint cdp = new CRLDistributionPoint();
+ URIName uri = new URIName("http://www.mycrl.com/go/here");
+ GeneralNames generalNames = new GeneralNames();
+ generalNames.addElement(uri);
+ cdp.setFullName(generalNames);
+ CRLDistributionPointsExtension crldpExt =
+ new CRLDistributionPointsExtension(cdp);
+
+ // DN only
+ cdp = new CRLDistributionPoint();
+ X500Name dn = new X500Name("CN=Otis Smith,E=otis@fedoraproject.org" +
+ ",OU=Certificate Server,O=Fedora,C=US");
+ generalNames = new GeneralNames();
+ generalNames.addElement(dn);
+ cdp.setFullName(generalNames);
+ crldpExt.addPoint(cdp);
+
+ // DN + reason
+ BitArray ba = new BitArray(5, new byte[] { (byte) 0x28 });
+ cdp = new CRLDistributionPoint();
+ cdp.setFullName(generalNames);
+ cdp.setReasons(ba);
+ crldpExt.addPoint(cdp);
+
+ // relative DN + reason + crlIssuer
+ cdp = new CRLDistributionPoint();
+ RDN rdn = new RDN("OU=foobar dept");
+ cdp.setRelativeName(rdn);
+ cdp.setReasons(ba);
+ cdp.setCRLIssuer(generalNames);
+ crldpExt.addPoint(cdp);
+
+ crldpExt.setCritical(true);
+ crldpExt.encode(bos);
+
+ bos.close();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Represents a reason that a cert may be revoked. These reasons are
+ * expressed in a ReasonFlags bit string.
+ */
+ public static class Reason {
+
+ private String name;
+ private byte bitMask;
+
+ private Reason() {
+ }
+
+ private Reason(String name, byte bitMask) {
+ this.name = name;
+ this.bitMask = bitMask;
+ map.put(name, this);
+ list.addElement(this);
+ }
+
+ private static Hashtable<String, Reason> map = new Hashtable<String, Reason>();
+ private static Vector<Reason> list = new Vector<Reason>();
+
+ public static Reason fromString(String name) {
+ return map.get(name);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public byte getBitMask() {
+ return bitMask;
+ }
+
+ /**
+ * Given a bit array representing reason flags, extracts the reasons
+ * and returns them as an array.
+ *
+ * @param bitFlags A bit vector containing reason flags.
+ * @return An array of reasons contained in the bit vector.
+ * May be zero-length but will not be null.
+ */
+ public static Reason[] bitArrayToReasonArray(byte bitFlags) {
+ return bitArrayToReasonArray(new byte[] { bitFlags });
+ }
+
+ /**
+ * Given a bit array representing reason flags, extracts the reasons
+ * and returns them as an array. Currently, only the first byte
+ * of the bitflags are examined.
+ *
+ * @param bitFlags A bit vector containing reason flags. The format
+ * is big-endian (MSB first). Only the first byte is examined.
+ * @return An array of reasons contained in the bit vector.
+ * May be zero-length but will not be null.
+ */
+ public static Reason[] bitArrayToReasonArray(byte[] bitFlags) {
+ byte first = bitFlags[0];
+ int size = list.size();
+ Vector<Reason> result = new Vector<Reason>();
+ for (int i = 0; i < size; i++) {
+ Reason r = list.elementAt(i);
+ byte b = r.getBitMask();
+ if ((first & b) != 0) {
+ result.addElement(r);
+ }
+ }
+ size = result.size();
+ Reason[] retval = new Reason[size];
+ for (int i = 0; i < size; i++) {
+ retval[i] = result.elementAt(i);
+ }
+ return retval;
+ }
+
+ public static final Reason UNUSED =
+ new Reason("unused", (byte) 0x80);
+ public static final Reason KEY_COMPROMISE =
+ new Reason("keyCompromise", (byte) 0x40);
+ public static final Reason CA_COMPROMISE =
+ new Reason("cACompromise", (byte) 0x20);
+ public static final Reason AFFILIATION_CHANGED =
+ new Reason("affiliationChanged", (byte) 0x10);
+ public static final Reason SUPERSEDED =
+ new Reason("superseded", (byte) 0x08);
+ public static final Reason CESSATION_OF_OPERATION =
+ new Reason("cessationOfOperation", (byte) 0x04);
+ public static final Reason CERTIFICATE_HOLD =
+ new Reason("certificateHold", (byte) 0x02);
+ }
+
+}
diff --git a/base/util/src/netscape/security/x509/CRLExtensions.java b/base/util/src/netscape/security/x509/CRLExtensions.java
new file mode 100755
index 000000000..bdadcc12e
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CRLExtensions.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.security.cert.CRLException;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class defines the CRL Extensions.
+ *
+ * @author Hemma Prafullchandra
+ * @version 1.4
+ */
+public class CRLExtensions extends Vector<Extension> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 365767738692986418L;
+ private Hashtable<String, Extension> map;
+
+ // Parse the encoded extension
+ private void parseExtension(Extension ext) throws X509ExtensionException {
+ try {
+ Class<?> extClass = OIDMap.getClass(ext.getExtensionId());
+ if (extClass == null) { // Unsupported extension
+ if (ext.isCritical()) {
+ throw new IOException("Unsupported CRITICAL extension: "
+ + ext.getExtensionId());
+ } else {
+ map.put(ext.getExtensionId().toString(), ext);
+ addElement(ext);
+ return;
+ }
+ }
+ Class<?>[] params = { Boolean.class, Object.class };
+ Constructor<?> cons = extClass.getConstructor(params);
+ byte[] extData = ext.getExtensionValue();
+ int extLen = extData.length;
+ Object value = Array.newInstance(byte.class, extLen);
+
+ for (int i = 0; i < extLen; i++) {
+ Array.setByte(value, i, extData[i]);
+ }
+ Object[] passed = new Object[] { new Boolean(ext.isCritical()),
+ value };
+ CertAttrSet crlExt = (CertAttrSet) cons.newInstance(passed);
+ map.put(crlExt.getName(), (Extension) crlExt);
+ addElement((Extension) crlExt);
+
+ } catch (InvocationTargetException invk) {
+ throw new X509ExtensionException(
+ invk.getTargetException().getMessage());
+
+ } catch (Exception e) {
+ throw new X509ExtensionException(e.toString());
+ }
+ }
+
+ /**
+ * Default constructor.
+ */
+ public CRLExtensions() {
+ map = new Hashtable<String, Extension>();
+ }
+
+ /**
+ * Create the object, decoding the values from the passed DER stream.
+ *
+ * @param in the DerInputStream to read the Extension from.
+ * @exception CRLException on decoding errors.
+ * @exception X509ExtensionException on extension handling errors.
+ */
+ public CRLExtensions(DerInputStream in)
+ throws CRLException, X509ExtensionException {
+
+ map = new Hashtable<String, Extension>();
+ try {
+ DerValue[] exts = in.getSequence(5);
+
+ for (int i = 0; i < exts.length; i++) {
+ Extension ext = new Extension(exts[i]);
+ parseExtension(ext);
+ }
+ } catch (IOException e) {
+ throw new CRLException("Parsing error: " + e.toString());
+ }
+ }
+
+ /**
+ * Decode the extensions from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception CRLException on decoding or validity errors.
+ * @exception X509ExtensionException on extension handling errors.
+ */
+ public void decode(InputStream in)
+ throws CRLException, X509ExtensionException {
+ try {
+ DerValue val = new DerValue(in);
+ DerInputStream str = val.toDerInputStream();
+
+ map = new Hashtable<String, Extension>();
+ DerValue[] exts = str.getSequence(5);
+
+ for (int i = 0; i < exts.length; i++) {
+ Extension ext = new Extension(exts[i]);
+ parseExtension(ext);
+ }
+ } catch (IOException e) {
+ throw new CRLException("Parsing error: " + e.toString());
+ }
+ }
+
+ /**
+ * Encode the extensions in DER form to the stream.
+ *
+ * @param out the DerOutputStream to marshal the contents to.
+ * @param isExplicit the tag indicating whether this is an entry
+ * extension or a CRL extension.
+ * @exception CRLException on encoding errors.
+ */
+ public void encode(OutputStream out, boolean isExplicit)
+ throws CRLException {
+ try {
+ // #381559
+ if (size() == 0)
+ return;
+ DerOutputStream extOut = new DerOutputStream();
+ for (int i = 0; i < size(); i++) {
+ Object thisOne = elementAt(i);
+ if (thisOne instanceof CertAttrSet)
+ ((CertAttrSet) thisOne).encode(extOut);
+ else if (thisOne instanceof Extension)
+ ((Extension) thisOne).encode(extOut);
+ else
+ throw new CRLException("Illegal extension object");
+ }
+
+ DerOutputStream seq = new DerOutputStream();
+ seq.write(DerValue.tag_Sequence, extOut);
+
+ DerOutputStream tmp = new DerOutputStream();
+ if (isExplicit)
+ tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ true, (byte) 0), seq);
+ else
+ tmp = seq;
+
+ out.write(tmp.toByteArray());
+ } catch (IOException e) {
+ throw new CRLException("Encoding error: " + e.toString());
+ } catch (CertificateException e) {
+ throw new CRLException("Encoding error: " + e.toString());
+ }
+ }
+
+ /**
+ * Get the extension with this alias.
+ *
+ * @param alias the identifier string for the extension to retrieve.
+ * @exception X509ExtensionException on extension handling errors.
+ */
+ public Extension get(String alias) throws X509ExtensionException {
+ X509AttributeName attr = new X509AttributeName(alias);
+ String name;
+ String id = attr.getPrefix();
+ if (id.equalsIgnoreCase(X509CertImpl.NAME)) { // fully qualified
+ int index = alias.lastIndexOf(".");
+ name = alias.substring(index + 1);
+ } else
+ name = alias;
+ Extension ext = (Extension) map.get(name);
+ if (ext == null)
+ throw new X509ExtensionException("No extension found with name: "
+ + alias);
+ return ext;
+ }
+
+ /**
+ * Set the extension value with this alias.
+ *
+ * @param alias the identifier string for the extension to set.
+ * @param obj the Object to set the extension identified by the
+ * alias.
+ * @exception IOException on errors.
+ */
+ public void set(String alias, Extension obj) throws IOException {
+ map.put(alias, obj);
+ addElement(obj);
+ }
+
+ /**
+ * Return an enumeration of names of the extensions.
+ *
+ * @return an enumeration of the names of the extensions in this CRL.
+ */
+ public Enumeration<Extension> getElements() {
+ return (map.elements());
+ }
+}
diff --git a/base/util/src/netscape/security/x509/CRLNumberExtension.java b/base/util/src/netscape/security/x509/CRLNumberExtension.java
new file mode 100755
index 000000000..7c89b179f
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CRLNumberExtension.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.math.BigInteger;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * Represent the CRL Number Extension.
+ *
+ * <p>
+ * This extension, if present, conveys a monotonically increasing sequence number for each CRL issued by a given CA
+ * through a specific CA X.500 Directory entry or CRL distribution point. This extension allows users to easily
+ * determine when a particular CRL supersedes another CRL.
+ *
+ * @author Hemma Prafullchandra
+ * @version 1.2
+ * @see Extension
+ * @see CertAttrSet
+ */
+public class CRLNumberExtension extends Extension
+ implements CertAttrSet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2992307666566322402L;
+ /**
+ * Attribute name.
+ */
+ public static final String NAME = "CRLNumber";
+ public static final String NUMBER = "value";
+
+ private BigInt crlNumber = null;
+
+ // Encode this extension value
+ private void encodeThis() throws IOException {
+ if (crlNumber == null)
+ throw new IOException("Unintialized CRL number extension");
+ DerOutputStream os = new DerOutputStream();
+ os.putInteger(this.crlNumber);
+ this.extensionValue = os.toByteArray();
+ }
+
+ /**
+ * Create a CRLNumberExtension with the integer value .
+ * The criticality is set to false.
+ *
+ * @param crlNum the value to be set for the extension.
+ */
+ public CRLNumberExtension(int crlNum) throws IOException {
+ this.crlNumber = new BigInt(crlNum);
+ this.extensionId = PKIXExtensions.CRLNumber_Id;
+ this.critical = false;
+ encodeThis();
+ }
+
+ /**
+ * Create a CRLNumberExtension with the BigInteger value .
+ * The criticality is set to false.
+ *
+ * @param crlNum the value to be set for the extension.
+ */
+ public CRLNumberExtension(BigInteger crlNum) throws IOException {
+ this.crlNumber = new BigInt(crlNum);
+ this.extensionId = PKIXExtensions.CRLNumber_Id;
+ this.critical = false;
+ encodeThis();
+ }
+
+ /**
+ * Create a CRLNumberExtension with the BigInteger value .
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param crlNum the value to be set for the extension.
+ */
+ public CRLNumberExtension(Boolean critical, BigInteger crlNum) throws IOException {
+ this.crlNumber = new BigInt(crlNum);
+ this.extensionId = PKIXExtensions.CRLNumber_Id;
+ this.critical = critical.booleanValue();
+ encodeThis();
+ }
+
+ /**
+ * Create the extension from the passed DER encoded value of the same.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param value Array of DER encoded bytes of the actual value.
+ * @exception IOException on error.
+ */
+ public CRLNumberExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = PKIXExtensions.CRLNumber_Id;
+ this.critical = critical.booleanValue();
+
+ int len = Array.getLength(value);
+ byte[] extValue = new byte[len];
+ for (int i = 0; i < len; i++) {
+ extValue[i] = Array.getByte(value, i);
+ }
+ this.extensionValue = extValue;
+ DerValue val = new DerValue(extValue);
+ this.crlNumber = val.getInteger();
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ if (name.equalsIgnoreCase(NUMBER)) {
+ if (!(obj instanceof BigInteger)) {
+ throw new IOException("Attribute must be of type BigInteger.");
+ }
+ crlNumber = new BigInt((BigInteger) obj);
+ } else {
+ throw new IOException("Attribute name not recognized by"
+ + " CertAttrSet:CRLNumber.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(NUMBER)) {
+ if (crlNumber == null)
+ return null;
+ else
+ return crlNumber.toBigInteger();
+ } else {
+ throw new IOException("Attribute name not recognized by"
+ + " CertAttrSet:CRLNumber.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(NUMBER)) {
+ crlNumber = null;
+ } else {
+ throw new IOException("Attribute name not recognized by"
+ + " CertAttrSet:CRLNumber.");
+ }
+ }
+
+ /**
+ * Returns a printable representation of the CRLNumberExtension.
+ */
+ public String toString() {
+ String s = super.toString() + "CRL Number: " +
+ ((crlNumber == null) ? "" : crlNumber.toString())
+ + "\n";
+ return (s);
+ }
+
+ /**
+ * Decode the extension from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ /**
+ * Write the extension to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ if (this.extensionValue == null) {
+ this.extensionId = PKIXExtensions.CRLNumber_Id;
+ this.critical = false;
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(NUMBER);
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/CRLReasonExtension.java b/base/util/src/netscape/security/x509/CRLReasonExtension.java
new file mode 100644
index 000000000..3c11fc70b
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CRLReasonExtension.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * Represent the CRLReason Extension of CRL entry.
+ *
+ * <p>
+ * This extension, if present, defines the identifies the reason for the certificate revocation.
+ *
+ * @author galperin
+ * @version $Revision$, $Date$
+ * @see Extension
+ * @see CertAttrSet
+ */
+
+public final class CRLReasonExtension extends Extension implements CertAttrSet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4544973296866779535L;
+ /**
+ * Canned instances for all revocation reasons
+ */
+ public static final CRLReasonExtension UNSPECIFIED = new CRLReasonExtension(RevocationReason.UNSPECIFIED);
+ public static final CRLReasonExtension KEY_COMPROMISE = new CRLReasonExtension(RevocationReason.KEY_COMPROMISE);
+ public static final CRLReasonExtension CA_COMPROMISE = new CRLReasonExtension(RevocationReason.CA_COMPROMISE);
+ public static final CRLReasonExtension AFFILIATION_CHANGED = new CRLReasonExtension(
+ RevocationReason.AFFILIATION_CHANGED);
+ public static final CRLReasonExtension SUPERSEDED = new CRLReasonExtension(RevocationReason.SUPERSEDED);
+ public static final CRLReasonExtension CESSATION_OF_OPERATION = new CRLReasonExtension(
+ RevocationReason.CESSATION_OF_OPERATION);
+ public static final CRLReasonExtension CERTIFICATE_HOLD = new CRLReasonExtension(RevocationReason.CERTIFICATE_HOLD);
+ public static final CRLReasonExtension REMOVE_FROM_CRL = new CRLReasonExtension(RevocationReason.REMOVE_FROM_CRL);
+ public static final CRLReasonExtension PRIVILEGE_WITHDRAWN = new CRLReasonExtension(
+ RevocationReason.PRIVILEGE_WITHDRAWN);
+ public static final CRLReasonExtension AA_COMPROMISE = new CRLReasonExtension(RevocationReason.AA_COMPROMISE);
+
+ /**
+ * Attribute names.
+ */
+ public static final String NAME = "CRLReason";
+ public static final String REASON = "value";
+
+ private RevocationReason mReason = null;
+
+ public RevocationReason getReason() {
+ return mReason;
+ }
+
+ /**
+ * Default constructor
+ *
+ */
+
+ public CRLReasonExtension() {
+ this.extensionId = PKIXExtensions.ReasonCode_Id;
+ this.critical = false;
+ mReason = null;
+ }
+
+ /**
+ * Create extension value for specific revocation reason
+ *
+ */
+
+ public CRLReasonExtension(RevocationReason reason) {
+ this.extensionId = PKIXExtensions.ReasonCode_Id;
+ this.critical = false;
+ mReason = reason;
+ }
+
+ public CRLReasonExtension(Boolean critical, RevocationReason reason)
+ throws IOException {
+ this.extensionId = PKIXExtensions.ReasonCode_Id;
+ this.critical = critical.booleanValue();
+ mReason = reason;
+ }
+
+ /**
+ * Create the object from the passed DER encoded value.
+ *
+ * @param derVal the DerValue decoded from the stream.
+ * @exception IOException on decoding errors.
+ */
+ public CRLReasonExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = PKIXExtensions.ReasonCode_Id;
+ this.critical = critical.booleanValue();
+
+ byte[] extValue = (byte[]) ((byte[]) value).clone();
+ this.extensionValue = extValue;
+ DerValue val = new DerValue(extValue);
+ int reasonCode = val.getEnumerated();
+ mReason = RevocationReason.fromInt(reasonCode);
+ if (mReason == null)
+ throw new IOException("Unknown revocation reason value " + reasonCode);
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ if (!(obj instanceof RevocationReason)) {
+ throw new IOException("Attribute must be of type RevocationReason.");
+ }
+
+ if (name.equalsIgnoreCase(REASON)) {
+ mReason = (RevocationReason) obj;
+ } else {
+ throw new IOException("Name not recognized by CRLReason");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(REASON)) {
+ return mReason;
+ } else {
+ throw new IOException("Name not recognized by CRLReason");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(REASON)) {
+ mReason = null;
+ } else {
+ throw new IOException("Name not recognized by CRLReason");
+ }
+ }
+
+ /**
+ * Returns a printable representation of the ReasonFlags.
+ */
+ public String toString() {
+ String s = super.toString() + "CRL Reason [" + mReason + "]\n";
+ return (s);
+ }
+
+ /**
+ * Decode the extension from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ // Encode this extension value
+ private void encodeThis() throws IOException {
+ if (mReason == null)
+ throw new IOException("Unintialized CRLReason extension");
+ DerOutputStream os = new DerOutputStream();
+ os.putEnumerated(mReason.toInt());
+ this.extensionValue = os.toByteArray();
+ }
+
+ /**
+ * Write the extension to the DerOutputStream.
+ *
+ * @param out the OutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ if (this.extensionValue == null) {
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(REASON);
+
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+
+ public boolean equals(Object other) {
+ if (this == other)
+ return true;
+ else if (other instanceof CRLReasonExtension)
+ return ((CRLReasonExtension) other).mReason == mReason &&
+ ((CRLReasonExtension) other).critical == critical;
+ else
+ return false;
+ }
+
+}
diff --git a/base/util/src/netscape/security/x509/CertAndKeyGen.java b/base/util/src/netscape/security/x509/CertAndKeyGen.java
new file mode 100644
index 000000000..1579d46bf
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CertAndKeyGen.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+import netscape.security.pkcs.PKCS10;
+
+/**
+ * Generate a pair of keys, and provide access to them. This class is
+ * provided primarily for ease of use.
+ *
+ * <P>
+ * This provides some simple certificate management functionality. Specifically, it allows you to create self-signed
+ * X.509 certificates as well as PKCS 10 based certificate signing requests.
+ *
+ * <P>
+ * Keys for some public key signature algorithms have algorithm parameters, such as DSS/DSA. Some sites' Certificate
+ * Authorities adopt fixed algorithm parameters, which speeds up some operations including key generation and signing.
+ * <em>At this time, this interface
+ * does not provide a way to provide such algorithm parameters, e.g.
+ * by providing the CA certificate which includes those parameters.</em>
+ *
+ * <P>
+ * Also, note that at this time only signature-capable keys may be acquired through this interface. Diffie-Hellman keys,
+ * used for secure key exchange, may be supported later.
+ *
+ * @author David Brownell
+ * @author Hemma Prafullchandra
+ * @version 1.44
+ * @see PKCS10
+ * @see X509CertImpl
+ */
+public final class CertAndKeyGen {
+ /**
+ * Creates a CertAndKeyGen object for a particular key type
+ * and signature algorithm.
+ *
+ * @param keyType type of key, e.g. "RSA", "DSA"
+ * @param sigAlg name of the signature algorithm, e.g. "MD5WithRSA",
+ * "MD2WithRSA", "SHAwithDSA".
+ * @exception NoSuchAlgorithmException on unrecognized algorithms.
+ */
+ public CertAndKeyGen(String keyType, String sigAlg)
+ throws NoSuchAlgorithmException {
+ keyGen = KeyPairGenerator.getInstance(keyType);
+ this.sigAlg = sigAlg;
+ }
+
+ /**
+ * Sets the source of random numbers used when generating keys.
+ * If you do not provide one, a system default facility is used.
+ * You may wish to provide your own source of random numbers
+ * to get a reproducible sequence of keys and signatures, or
+ * because you may be able to take advantage of strong sources
+ * of randomness/entropy in your environment.
+ *
+ * @deprecated All random numbers come from PKCS #11 now.
+ */
+ public void setRandom(SecureRandom generator) {
+ }
+
+ // want "public void generate (X509Certificate)" ... inherit DSA/D-H param
+
+ /**
+ * Generates a random public/private key pair, with a given key
+ * size. Different algorithms provide different degrees of security
+ * for the same key size, because of the "work factor" involved in
+ * brute force attacks. As computers become faster, it becomes
+ * easier to perform such attacks. Small keys are to be avoided.
+ *
+ * <P>
+ * Note that not all values of "keyBits" are valid for all algorithms, and not all public key algorithms are
+ * currently supported for use in X.509 certificates. If the algorithm you specified does not produce X.509
+ * compatible keys, an invalid key exception is thrown.
+ *
+ * @param keyBits the number of bits in the keys.
+ * @exception InvalidKeyException if the environment does not
+ * provide X.509 public keys for this signature algorithm.
+ */
+ public void generate(int keyBits)
+ throws InvalidKeyException {
+ KeyPair pair;
+
+ try {
+ keyGen.initialize(keyBits);
+ pair = keyGen.generateKeyPair();
+
+ } catch (Exception e) {
+ throw new IllegalArgumentException(e.getMessage());
+ }
+
+ PublicKey publicKey = pair.getPublic();
+
+ if (publicKey instanceof X509Key) {
+ this.publicKey = (X509Key) publicKey;
+
+ } else {
+ throw new InvalidKeyException("public key " + publicKey +
+ " not an X509Key.");
+ }
+ privateKey = pair.getPrivate();
+ }
+
+ /**
+ * Returns the public key of the generated key pair.
+ */
+ public X509Key getPublicKey() {
+ return publicKey;
+ }
+
+ /**
+ * Returns the private key of the generated key pair.
+ *
+ * <P>
+ * <STRONG><em>Be extremely careful when handling private keys.
+ * When private keys are not kept secret, they lose their ability
+ * to securely authenticate specific entities ... that is a huge
+ * security risk!</em></STRONG>
+ */
+ public PrivateKey getPrivateKey() {
+ return privateKey;
+ }
+
+ /**
+ * Returns a self-signed X.509v1 certificate for the public key.
+ * The certificate is immediately valid.
+ *
+ * <P>
+ * Such certificates normally are used to identify a "Certificate Authority" (CA). Accordingly, they will not always
+ * be accepted by other parties. However, such certificates are also useful when you are bootstrapping your security
+ * infrastructure, or deploying system prototypes.
+ *
+ * @deprecated Use the new <a href =
+ * "#getSelfCertificate(netscape.security.x509.X500Name, long)">
+ *
+ * @param myname X.500 name of the subject (who is also the issuer)
+ * @param validity how long the certificate should be valid, in seconds
+ */
+ public X509Cert getSelfCert(X500Name myname, long validity)
+ throws InvalidKeyException, SignatureException, NoSuchAlgorithmException {
+ X509Certificate cert;
+
+ try {
+ cert = getSelfCertificate(myname, validity);
+ return new X509Cert(cert.getEncoded());
+ } catch (CertificateException e) {
+ throw new SignatureException(e.getMessage());
+ } catch (NoSuchProviderException e) {
+ throw new NoSuchAlgorithmException(e.getMessage());
+ } catch (IOException e) {
+ throw new SignatureException(e.getMessage());
+ }
+ }
+
+ /**
+ * Returns a self-signed X.509v3 certificate for the public key.
+ * The certificate is immediately valid. No extensions.
+ *
+ * <P>
+ * Such certificates normally are used to identify a "Certificate Authority" (CA). Accordingly, they will not always
+ * be accepted by other parties. However, such certificates are also useful when you are bootstrapping your security
+ * infrastructure, or deploying system prototypes.
+ *
+ * @param myname X.500 name of the subject (who is also the issuer)
+ * @param validity how long the certificate should be valid, in seconds
+ * @exception CertificateException on certificate handling errors.
+ * @exception InvalidKeyException on key handling errors.
+ * @exception SignatureException on signature handling errors.
+ * @exception NoSuchAlgorithmException on unrecognized algorithms.
+ * @exception NoSuchProviderException on unrecognized providers.
+ */
+ public X509Certificate getSelfCertificate(X500Name myname, long validity)
+ throws CertificateException, InvalidKeyException, SignatureException,
+ NoSuchAlgorithmException, NoSuchProviderException {
+ X500Signer issuer;
+ X509CertImpl cert;
+ Date firstDate, lastDate;
+
+ try {
+ issuer = getSigner(myname);
+
+ firstDate = new Date();
+ lastDate = new Date();
+ lastDate.setTime(lastDate.getTime() + validity * 1000);
+
+ CertificateValidity interval =
+ new CertificateValidity(firstDate, lastDate);
+
+ X509CertInfo info = new X509CertInfo();
+ // Add all mandatory attributes
+ info.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V1));
+ info.set(X509CertInfo.SERIAL_NUMBER,
+ new CertificateSerialNumber((int) (firstDate.getTime() / 1000)));
+ AlgorithmId algID = issuer.getAlgorithmId();
+ info.set(X509CertInfo.ALGORITHM_ID,
+ new CertificateAlgorithmId(algID));
+ info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(myname));
+ info.set(X509CertInfo.KEY, new CertificateX509Key(publicKey));
+ info.set(X509CertInfo.VALIDITY, interval);
+ info.set(X509CertInfo.ISSUER,
+ new CertificateIssuerName(issuer.getSigner()));
+
+ cert = new X509CertImpl(info);
+ cert.sign(privateKey, algID.getName());
+
+ return (X509Certificate) cert;
+
+ } catch (IOException e) {
+ throw new CertificateEncodingException("getSelfCert: " +
+ e.getMessage());
+ }
+ }
+
+ /**
+ * Returns a PKCS #10 certificate request. The caller uses either <code>PKCS10.print</code> or
+ * <code>PKCS10.toByteArray</code> operations on the result, to get the request in an appropriate
+ * transmission format.
+ *
+ * <P>
+ * PKCS #10 certificate requests are sent, along with some proof of identity, to Certificate Authorities (CAs) which
+ * then issue X.509 public key certificates.
+ *
+ * @param myname X.500 name of the subject
+ * @exception InvalidKeyException on key handling errors.
+ * @exception SignatureException on signature handling errors.
+ */
+ public PKCS10 getCertRequest(X500Name myname)
+ throws InvalidKeyException, SignatureException {
+ PKCS10 req = new PKCS10(publicKey);
+
+ try {
+ req.encodeAndSign(getSigner(myname));
+
+ } catch (CertificateException e) {
+ throw new SignatureException(sigAlg + " CertificateException");
+
+ } catch (IOException e) {
+ throw new SignatureException(sigAlg + " IOException");
+
+ } catch (NoSuchAlgorithmException e) {
+ // "can't happen"
+ throw new SignatureException(sigAlg + " unavailable?");
+ }
+ return req;
+ }
+
+ private X500Signer getSigner(X500Name me)
+ throws InvalidKeyException, NoSuchAlgorithmException {
+ Signature signature = Signature.getInstance(sigAlg);
+
+ signature.initSign(privateKey);
+ return new X500Signer(signature, me);
+ }
+
+ private String sigAlg;
+ private KeyPairGenerator keyGen;
+ private X509Key publicKey;
+ private PrivateKey privateKey;
+}
diff --git a/base/util/src/netscape/security/x509/CertAttrSet.java b/base/util/src/netscape/security/x509/CertAttrSet.java
new file mode 100755
index 000000000..7e8d6db82
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CertAttrSet.java
@@ -0,0 +1,120 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+
+/**
+ * This interface defines the methods required of a certificate attribute.
+ * Examples of X.509 certificate attributes are Validity, Issuer_Name, and
+ * Subject Name. A CertAttrSet may compromise one attribute or many
+ * attributes.
+ * <p>
+ * A CertAttrSet itself can also be comprised of other sub-sets. In the case of X.509 V3 certificates, for example, the
+ * "extensions" attribute has subattributes, such as those for KeyUsage and AuthorityKeyIdentifier.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.9
+ * @see CertificateException
+ */
+public interface CertAttrSet {
+ /**
+ * Returns a short string describing this certificate attribute.
+ *
+ * @return value of this certificate attribute in
+ * printable form.
+ */
+ String toString();
+
+ /**
+ * Encodes the attribute to the output stream in a format
+ * that can be parsed by the <code>decode</code> method.
+ *
+ * @param out the OutputStream to encode the attribute to.
+ *
+ * @exception CertificateException on encoding or validity errors.
+ * @exception IOException on other errors.
+ */
+ void encode(OutputStream out)
+ throws CertificateException, IOException;
+
+ /**
+ * Decodes the attribute in the input stream.
+ *
+ * @param in the InputStream to read the encoded attribute from.
+ *
+ * @exception CertificateException on decoding or validity errors.
+ * @exception IOException on other errors.
+ */
+ void decode(InputStream in)
+ throws CertificateException, IOException;
+
+ /**
+ * Sets an attribute value within this CertAttrSet.
+ *
+ * @param name the name of the attribute (e.g. "x509.info.key")
+ * @param obj the attribute object.
+ *
+ * @exception CertificateException on attribute handling errors.
+ * @exception IOException on other errors.
+ */
+ void set(String name, Object obj)
+ throws CertificateException, IOException;
+
+ /**
+ * Gets an attribute value for this CertAttrSet.
+ *
+ * @param name the name of the attribute to return.
+ *
+ * @exception CertificateException on attribute handling errors.
+ * @exception IOException on other errors.
+ */
+ Object get(String name)
+ throws CertificateException, IOException;
+
+ /**
+ * Deletes an attribute value from this CertAttrSet.
+ *
+ * @param name the name of the attribute to delete.
+ *
+ * @exception CertificateException on attribute handling errors.
+ * @exception IOException on other errors.
+ */
+ void delete(String name)
+ throws CertificateException, IOException;
+
+ /**
+ * Returns an enumeration of the names of the attributes existing within
+ * this attribute.
+ *
+ * @return an enumeration of the attribute names.
+ */
+ Enumeration<String> getAttributeNames();
+
+ /**
+ * Returns the name (identifier) of this CertAttrSet.
+ *
+ * @return the name of this CertAttrSet.
+ */
+ String getName();
+}
diff --git a/base/util/src/netscape/security/x509/CertException.java b/base/util/src/netscape/security/x509/CertException.java
new file mode 100644
index 000000000..31d9e686e
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CertException.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 netscape.security.x509;
+
+/**
+ * CertException indicates one of a variety of certificate problems.
+ *
+ * @version 1.18
+ *
+ * @author David Brownell
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ */
+public class CertException extends SecurityException {
+
+ // Zero is reserved.
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4046189948107720588L;
+
+ /** Indicates that the signature in the certificate is not valid. */
+ public static final int verf_INVALID_SIG = 1;
+
+ /** Indicates that the certificate was revoked, and so is invalid. */
+ public static final int verf_INVALID_REVOKED = 2;
+
+ /** Indicates that the certificate is not yet valid. */
+ public static final int verf_INVALID_NOTBEFORE = 3;
+
+ /** Indicates that the certificate has expired and so is not valid. */
+ public static final int verf_INVALID_EXPIRED = 4;
+
+ /**
+ * Indicates that a certificate authority in the certification
+ * chain is not trusted.
+ */
+ public static final int verf_CA_UNTRUSTED = 5;
+
+ /** Indicates that the certification chain is too long. */
+ public static final int verf_CHAIN_LENGTH = 6;
+
+ /** Indicates an error parsing the ASN.1/DER encoding of the certificate. */
+ public static final int verf_PARSE_ERROR = 7;
+
+ /** Indicates an error constructing a certificate or certificate chain. */
+ public static final int err_CONSTRUCTION = 8;
+
+ /** Indicates a problem with the public key */
+ public static final int err_INVALID_PUBLIC_KEY = 9;
+
+ /** Indicates a problem with the certificate version */
+ public static final int err_INVALID_VERSION = 10;
+
+ /** Indicates a problem with the certificate format */
+ public static final int err_INVALID_FORMAT = 11;
+
+ /** Indicates a problem with the certificate encoding */
+ public static final int err_ENCODING = 12;
+
+ // Private data members
+ private int verfCode;
+ private String moreData;
+
+ /**
+ * Constructs a certificate exception using an error code
+ * (<code>verf_*</code>) and a string describing the context
+ * of the error.
+ */
+ public CertException(int code, String moredata) {
+ verfCode = code;
+ moreData = moredata;
+ }
+
+ /**
+ * Constructs a certificate exception using just an error code,
+ * without a string describing the context.
+ */
+ public CertException(int code) {
+ verfCode = code;
+ }
+
+ /**
+ * Returns the error code with which the exception was created.
+ */
+ public int getVerfCode() {
+ return verfCode;
+ }
+
+ /**
+ * Returns a string describing the context in which the exception
+ * was reported.
+ */
+ public String getMoreData() {
+ return moreData;
+ }
+
+ /**
+ * Return a string corresponding to the error code used to create
+ * this exception.
+ */
+ public String getVerfDescription() {
+ switch (verfCode) {
+ case verf_INVALID_SIG:
+ return "The signature in the certificate is not valid.";
+ case verf_INVALID_REVOKED:
+ return "The certificate has been revoked.";
+ case verf_INVALID_NOTBEFORE:
+ return "The certificate is not yet valid.";
+ case verf_INVALID_EXPIRED:
+ return "The certificate has expired.";
+ case verf_CA_UNTRUSTED:
+ return "The Authority which issued the certificate is not trusted.";
+ case verf_CHAIN_LENGTH:
+ return "The certificate path to a trusted authority is too long.";
+ case verf_PARSE_ERROR:
+ return "The certificate could not be parsed.";
+ case err_CONSTRUCTION:
+ return "There was an error when constructing the certificate.";
+ case err_INVALID_PUBLIC_KEY:
+ return "The public key was not in the correct format.";
+ case err_INVALID_VERSION:
+ return "The certificate has an invalid version number.";
+ case err_INVALID_FORMAT:
+ return "The certificate has an invalid format.";
+ case err_ENCODING:
+ return "Problem encountered while encoding the data.";
+
+ default:
+ return "Unknown code: " + verfCode;
+ }
+ }
+
+ /**
+ * Returns a string describing the certificate exception.
+ */
+ public String toString() {
+ return "[Certificate Exception: " + getMessage() + "]";
+ }
+
+ /**
+ * Returns a string describing the certificate exception.
+ */
+ public String getMessage() {
+ return getVerfDescription()
+ + ((moreData != null)
+ ? ("\n (" + moreData + ")") : "");
+ }
+}
diff --git a/base/util/src/netscape/security/x509/CertParseError.java b/base/util/src/netscape/security/x509/CertParseError.java
new file mode 100644
index 000000000..7328c7207
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CertParseError.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 netscape.security.x509;
+
+//back out these changes until backwards compatibility with
+//CertException is not an issue.
+//import java.security.CertificateException;
+
+/**
+ * CertException indicates one of a variety of certificate problems.
+ *
+ * @version 1.7
+ * @author David Brownell
+ */
+
+class CertParseError extends CertException {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7623327377774730807L;
+
+ CertParseError(String where) {
+ super(CertException.verf_PARSE_ERROR, where);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/CertificateAlgorithmId.java b/base/util/src/netscape/security/x509/CertificateAlgorithmId.java
new file mode 100644
index 000000000..41610844e
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CertificateAlgorithmId.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class defines the AlgorithmId for the Certificate.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.7
+ */
+public class CertificateAlgorithmId implements CertAttrSet, Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6084780721443376563L;
+
+ private AlgorithmId algId;
+
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT = "x509.info.algorithmID";
+ /**
+ * Sub attributes name for this CertAttrSet.
+ */
+ public static final String NAME = "algorithmID";
+ public static final String ALGORITHM = "algorithm";
+
+ /**
+ * Default constructor for the certificate attribute.
+ *
+ * @param algId the Algorithm identifier
+ */
+ public CertificateAlgorithmId(AlgorithmId algId) {
+ this.algId = algId;
+ }
+
+ /**
+ * Create the object, decoding the values from the passed DER stream.
+ *
+ * @param in the DerInputStream to read the serial number from.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateAlgorithmId(DerInputStream in) throws IOException {
+ DerValue val = in.getDerValue();
+ algId = AlgorithmId.parse(val);
+ }
+
+ /**
+ * Create the object, decoding the values from the passed stream.
+ *
+ * @param in the InputStream to read the serial number from.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateAlgorithmId(InputStream in) throws IOException {
+ DerValue val = new DerValue(in);
+ algId = AlgorithmId.parse(val);
+ }
+
+ /**
+ * Return the algorithm identifier as user readable string.
+ */
+ public String toString() {
+ if (algId == null)
+ return "";
+ return (algId.toString() +
+ ", OID = " + (algId.getOID()).toString() + "\n");
+ }
+
+ private synchronized void writeObject(ObjectOutputStream stream)
+ throws IOException {
+ encode(stream);
+ }
+
+ private synchronized void readObject(ObjectInputStream stream)
+ throws IOException {
+ decode(stream);
+ }
+
+ /**
+ * Encode the algorithm identifier in DER form to the stream.
+ *
+ * @param out the DerOutputStream to marshal the contents to.
+ * @exception IOException on errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ algId.encode(tmp);
+
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Decode the algorithm identifier from the passed stream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ DerValue derVal = new DerValue(in);
+ algId = AlgorithmId.parse(derVal);
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ if (!(obj instanceof AlgorithmId)) {
+ throw new IOException("Attribute must be of type AlgorithmId.");
+ }
+ if (name.equalsIgnoreCase(ALGORITHM)) {
+ algId = (AlgorithmId) obj;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:CertificateAlgorithmId.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(ALGORITHM)) {
+ return (algId);
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:CertificateAlgorithmId.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(ALGORITHM)) {
+ algId = null;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:CertificateAlgorithmId.");
+ }
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(ALGORITHM);
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/CertificateChain.java b/base/util/src/netscape/security/x509/CertificateChain.java
new file mode 100644
index 000000000..b60325378
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CertificateChain.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.security.cert.X509Certificate;
+
+import netscape.security.pkcs.ContentInfo;
+import netscape.security.pkcs.PKCS7;
+import netscape.security.pkcs.SignerInfo;
+
+public class CertificateChain implements Serializable {
+ public CertificateChain() {
+ }
+
+ /**
+ * constructs a certificate chain from a certificate.
+ *
+ * @param cert a certificate
+ */
+ public CertificateChain(X509Certificate cert) {
+ mChain = new X509Certificate[1];
+ mChain[0] = cert;
+ }
+
+ /**
+ * constructs a certificate chain from a X509 certificate array.
+ *
+ * @param chain a certificate array.
+ */
+ public CertificateChain(X509Certificate[] chain) {
+ mChain = (X509Certificate[]) chain.clone();
+ }
+
+ /**
+ * returns the certificate at specified index in chain.
+ *
+ * @param index the index.
+ * @return the X509 certificate at the given index.
+ */
+ public X509Certificate getCertificate(int index) {
+ return mChain[index];
+ }
+
+ /**
+ * returns the first certificate in chain.
+ *
+ * @return the X509 certificate at the given index.
+ */
+ public X509Certificate getFirstCertificate() {
+ return mChain[0];
+ }
+
+ /**
+ * returns the certificate chain as an array of X509 certificates.
+ *
+ * @return an array of X509 Certificates.
+ */
+ public X509Certificate[] getChain() {
+ return (X509Certificate[]) mChain.clone();
+ }
+
+ public void encode(OutputStream out)
+ throws IOException {
+ encode(out, true);
+ }
+
+ /**
+ * encode in PKCS7 blob.
+ */
+ public void encode(OutputStream out, boolean sort)
+ throws IOException {
+ PKCS7 p7 = new PKCS7(new AlgorithmId[0],
+ new ContentInfo(new byte[0]), mChain,
+ new SignerInfo[0]);
+ p7.encodeSignedData(out, sort);
+ }
+
+ /**
+ * decode from PKCS7 blob.
+ */
+ public void decode(InputStream in)
+ throws IOException {
+ PKCS7 p7 = new PKCS7(in);
+ mChain = p7.getCertificates();
+ }
+
+ /**
+ * for serialization
+ */
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws IOException {
+ encode(out);
+ }
+
+ /**
+ * for serialization
+ */
+ private void readObject(java.io.ObjectInputStream in)
+ throws IOException {
+ decode(in);
+ }
+
+ /**
+ * Converts the certificate chain to a readable string.
+ */
+ public String toString() {
+ String s = "[\n";
+ if (mChain == null)
+ return "[empty]";
+ for (int i = 0; i < mChain.length; i++) {
+ s += mChain[i].toString();
+ }
+ s += "]\n";
+ return s;
+ }
+
+ private X509Certificate[] mChain = null;
+}
diff --git a/base/util/src/netscape/security/x509/CertificateExtensions.java b/base/util/src/netscape/security/x509/CertificateExtensions.java
new file mode 100644
index 000000000..b9667d8f6
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CertificateExtensions.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class defines the Extensions attribute for the Certificate.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.11
+ * @see CertAttrSet
+ */
+public class CertificateExtensions extends Vector<Extension>
+ implements CertAttrSet, Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7172635300185788849L;
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT = "x509.info.extensions";
+ /**
+ * name
+ */
+ public static final String NAME = "extensions";
+
+ private Hashtable<String, Extension> map;
+
+ // Parse the encoded extension
+ public void parseExtension(Extension ext) throws IOException {
+ try {
+ @SuppressWarnings("unchecked")
+ Class<CertAttrSet> extClass = (Class<CertAttrSet>) OIDMap.getClass(ext.getExtensionId());
+ if (extClass == null) { // Unsupported extension
+ if (ext.isCritical()) {
+ throw new IOException("Unsupported CRITICAL extension: "
+ + ext.getExtensionId());
+ } else {
+ map.put(ext.getExtensionId().toString(), ext);
+ addElement(ext);
+ return;
+ }
+ }
+ Class<?>[] params = { Boolean.class, Object.class };
+ Constructor<CertAttrSet> cons = extClass.getConstructor(params);
+
+ byte[] extData = ext.getExtensionValue();
+ int extLen = extData.length;
+ Object value = Array.newInstance(byte.class, extLen);
+
+ for (int i = 0; i < extLen; i++) {
+ Array.setByte(value, i, extData[i]);
+ }
+ Object[] passed = new Object[] { new Boolean(ext.isCritical()),
+ value };
+ CertAttrSet certExt = cons.newInstance(passed);
+ if (certExt != null && certExt.getName() != null) {
+ map.put(certExt.getName(), (Extension) certExt);
+ addElement((Extension) certExt);
+ }
+ } catch (NoSuchMethodException nosuch) {
+ throw new IOException(nosuch.toString());
+ } catch (InvocationTargetException invk) {
+ throw new IOException(invk.getTargetException().toString());
+ } catch (Exception e) {
+ throw new IOException(e.toString());
+ }
+ }
+
+ /**
+ * Default constructor for the certificate attribute.
+ */
+ public CertificateExtensions() {
+ map = new Hashtable<String, Extension>();
+ }
+
+ /**
+ * Create the object, decoding the values from the passed DER stream.
+ *
+ * @param in the DerInputStream to read the Extension from.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateExtensions(DerInputStream in)
+ throws IOException {
+
+ map = new Hashtable<String, Extension>();
+ DerValue[] exts = in.getSequence(5);
+
+ for (int i = 0; i < exts.length; i++) {
+ Extension ext = new Extension(exts[i]);
+ parseExtension(ext);
+ }
+ }
+
+ /**
+ * Decode the extensions from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ DerValue val = new DerValue(in);
+ DerInputStream str = val.toDerInputStream();
+
+ map = new Hashtable<String, Extension>();
+ DerValue[] exts = str.getSequence(5);
+
+ for (int i = 0; i < exts.length; i++) {
+ Extension ext = new Extension(exts[i]);
+ parseExtension(ext);
+ }
+ }
+
+ /**
+ * Decode the extensions from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decodeEx(InputStream in) throws IOException {
+ DerValue val = new DerValue(in);
+ DerInputStream str = null;
+ if (val.isConstructed() && val.isContextSpecific((byte) 3)) {
+ str = val.data;
+ } else {
+ str = val.toDerInputStream();
+ }
+
+ map = new Hashtable<String, Extension>();
+ DerValue[] exts = str.getSequence(5);
+
+ for (int i = 0; i < exts.length; i++) {
+ Extension ext = new Extension(exts[i]);
+ parseExtension(ext);
+ }
+ }
+
+ private synchronized void writeObject(ObjectOutputStream stream)
+ throws CertificateException, IOException {
+ encode(stream);
+ }
+
+ private synchronized void readObject(ObjectInputStream stream)
+ throws CertificateException, IOException {
+ decodeEx(stream);
+ }
+
+ /**
+ * Encode the extensions in DER form to the stream.
+ *
+ * @param out the DerOutputStream to marshal the contents to.
+ * @exception CertificateException on encoding errors.
+ * @exception IOException on errors.
+ */
+ public void encode(OutputStream out)
+ throws CertificateException, IOException {
+ DerOutputStream extOut = new DerOutputStream();
+ for (int i = 0; i < size(); i++) {
+ Object thisOne = elementAt(i);
+ if (thisOne instanceof CertAttrSet)
+ ((CertAttrSet) thisOne).encode(extOut);
+ else if (thisOne instanceof Extension)
+ ((Extension) thisOne).encode(extOut);
+ else
+ throw new CertificateException("Invalid extension object");
+ }
+
+ DerOutputStream seq = new DerOutputStream();
+ seq.write(DerValue.tag_Sequence, extOut);
+
+ DerOutputStream tmp = new DerOutputStream();
+ tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 3),
+ seq);
+
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Set the attribute value.
+ *
+ * @param name the extension name used in the cache.
+ * @param obj the object to set.
+ * @exception IOException if the object could not be cached.
+ */
+ public void set(String name, Object obj) throws IOException {
+ map.put(name, (Extension) obj);
+ addElement((Extension) obj);
+ }
+
+ /**
+ * Get the attribute value.
+ *
+ * @param name the extension name used in the lookup.
+ * @exception IOException if named extension is not found.
+ */
+ public Object get(String name) throws IOException {
+ Object obj = map.get(name);
+ if (obj == null) {
+ throw new IOException("No extension found with name " + name);
+ }
+ return (obj);
+ }
+
+ /**
+ * Delete the attribute value.
+ *
+ * @param name the extension name used in the lookup.
+ * @exception IOException if named extension is not found.
+ */
+ public void delete(String name) throws IOException {
+ Object obj = map.get(name);
+ if (obj == null) {
+ throw new IOException("No extension found with name " + name);
+ }
+ map.remove(name);
+ removeElement(obj);
+ }
+
+ public Enumeration<String> getNames() {
+ return map.keys();
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<Extension> getAttributes() {
+ return (map.elements());
+ }
+
+ public Enumeration<String> getAttributeNames() {
+ return (map.keys());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/CertificateIssuerExtension.java b/base/util/src/netscape/security/x509/CertificateIssuerExtension.java
new file mode 100644
index 000000000..774116bcc
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CertificateIssuerExtension.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * Represent the CRL Certificate Issuer Extension.
+ *
+ * <p>
+ * This CRL entry extension identifies the certificate issuer associated with an entry in an indirect CRL, i.e. a CRL
+ * that has the indirectCRL indicator set in its issuing distribution point extension.
+ *
+ * @see Extension
+ * @see CertAttrSet
+ */
+
+public class CertificateIssuerExtension extends Extension
+ implements CertAttrSet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8643788952936025986L;
+ /**
+ * Attribute name.
+ */
+ public static final String NAME = "CertificateIssuer";
+ public static final String CERTIFICATE_ISSUER = "value";
+
+ /**
+ * The Object Identifier for this extension.
+ */
+ public static final String OID = "2.5.29.29";
+
+ // private data members
+ GeneralNames names = null;
+
+ static {
+ try {
+ OIDMap.addAttribute(CertificateIssuerExtension.class.getName(),
+ OID, NAME);
+ } catch (CertificateException e) {
+ }
+ }
+
+ // Encode this extension
+ private void encodeThis() throws IOException {
+ DerOutputStream os = new DerOutputStream();
+ try {
+ names.encode(os);
+ } catch (GeneralNamesException e) {
+ throw new IOException(e.toString());
+ }
+ this.extensionValue = os.toByteArray();
+ }
+
+ /**
+ * Create a CertificateIssuerExtension with the passed GeneralNames
+ * and criticality.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param names the GeneralNames for the issuer.
+ * @exception IOException on error.
+ */
+ public CertificateIssuerExtension(Boolean critical, GeneralNames names)
+ throws IOException {
+ this.names = names;
+ this.extensionId = PKIXExtensions.CertificateIssuer_Id;
+ this.critical = critical.booleanValue();
+ encodeThis();
+ }
+
+ /**
+ * Create a CertificateIssuerExtension with the passed GeneralNames.
+ *
+ * @param names the GeneralNames for the issuer.
+ * @exception IOException on error.
+ */
+ public CertificateIssuerExtension(GeneralNames names)
+ throws IOException {
+ this.names = names;
+ this.extensionId = PKIXExtensions.CertificateIssuer_Id;
+ this.critical = true;
+ encodeThis();
+ }
+
+ /**
+ * Create a default CertificateIssuerExtension.
+ */
+ public CertificateIssuerExtension() {
+ extensionId = PKIXExtensions.CertificateIssuer_Id;
+ critical = false;
+ names = new GeneralNames();
+ }
+
+ /**
+ * Create the extension from the passed DER encoded value.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param value Array of DER encoded bytes of the actual value.
+ * @exception IOException on error.
+ */
+ public CertificateIssuerExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = PKIXExtensions.CertificateIssuer_Id;
+ this.critical = critical.booleanValue();
+
+ int len = Array.getLength(value);
+ byte[] extValue = new byte[len];
+ for (int i = 0; i < len; i++) {
+ extValue[i] = Array.getByte(value, i);
+ }
+ this.extensionValue = extValue;
+ DerValue val = new DerValue(extValue);
+ try {
+ names = new GeneralNames(val);
+ } catch (GeneralNamesException e) {
+ throw new IOException("CertificateIssuerExtension: " +
+ e.toString());
+ }
+ }
+
+ /**
+ * Returns a printable representation of the CertificateIssuerName.
+ */
+ public String toString() {
+ if (names == null)
+ return "";
+ String s = super.toString() + "CertificateIssuerName [\n"
+ + names.toString() + "]\n";
+ return (s);
+ }
+
+ /**
+ * Decode the extension from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ /**
+ * Write the extension to the OutputStream.
+ *
+ * @param out the OutputStream to write the extension to.
+ * @exception IOException on encoding error.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ if (extensionValue == null) {
+ extensionId = PKIXExtensions.CertificateIssuer_Id;
+ critical = false;
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ if (name.equalsIgnoreCase(CERTIFICATE_ISSUER)) {
+ if (!(obj instanceof GeneralNames)) {
+ throw new IOException("Attribute value should be of" +
+ " type GeneralNames.");
+ }
+ names = (GeneralNames) obj;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:CertificateIssuerName.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(CERTIFICATE_ISSUER)) {
+ return (names);
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:CertificateIssuerName.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(CERTIFICATE_ISSUER)) {
+ names = null;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:CertificateIssuerName.");
+ }
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(CERTIFICATE_ISSUER);
+
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/CertificateIssuerName.java b/base/util/src/netscape/security/x509/CertificateIssuerName.java
new file mode 100644
index 000000000..a2f9026c1
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CertificateIssuerName.java
@@ -0,0 +1,172 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class defines the X500Name attribute for the Certificate.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.6
+ * @see CertAttrSet
+ */
+public class CertificateIssuerName implements CertAttrSet {
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT = "x509.info.issuer";
+ /**
+ * Sub attributes name for this CertAttrSet.
+ */
+ public static final String NAME = "issuer";
+ public static final String DN_NAME = "dname";
+
+ // Private data member
+ private X500Name dnName;
+
+ /**
+ * Default constructor for the certificate attribute.
+ *
+ * @param name the X500Name
+ */
+ public CertificateIssuerName(X500Name name) {
+ this.dnName = name;
+ }
+
+ /**
+ * Create the object, decoding the values from the passed DER stream.
+ *
+ * @param in the DerInputStream to read the X500Name from.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateIssuerName(DerInputStream in) throws IOException {
+ dnName = new X500Name(in);
+ }
+
+ /**
+ * Create the object, decoding the values from the passed stream.
+ *
+ * @param in the InputStream to read the X500Name from.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateIssuerName(InputStream in) throws IOException {
+ DerValue derVal = new DerValue(in);
+ dnName = new X500Name(derVal);
+ }
+
+ /**
+ * Return the name as user readable string.
+ */
+ public String toString() {
+ if (dnName == null)
+ return "";
+ return (dnName.toString());
+ }
+
+ /**
+ * Encode the name in DER form to the stream.
+ *
+ * @param out the DerOutputStream to marshal the contents to.
+ * @exception IOException on errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ dnName.encode(tmp);
+
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Decode the name in DER form from the stream.
+ *
+ * @param in the InputStream to marshal the contents from.
+ * @exception IOException on errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ DerValue derVal = new DerValue(in);
+ dnName = new X500Name(derVal);
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ if (!(obj instanceof X500Name)) {
+ throw new IOException("Attribute must be of type X500Name.");
+ }
+ if (name.equalsIgnoreCase(DN_NAME)) {
+ this.dnName = (X500Name) obj;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:CertificateIssuerName.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(DN_NAME)) {
+ return (dnName);
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:CertificateIssuerName.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(DN_NAME)) {
+ dnName = null;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:CertificateIssuerName.");
+ }
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(DN_NAME);
+
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/CertificateIssuerUniqueIdentity.java b/base/util/src/netscape/security/x509/CertificateIssuerUniqueIdentity.java
new file mode 100644
index 000000000..351116ffb
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CertificateIssuerUniqueIdentity.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class defines the subject/issuer unique identity attribute
+ * for the Certificate.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.6
+ * @see CertAttrSet
+ */
+public class CertificateIssuerUniqueIdentity implements CertAttrSet {
+ private UniqueIdentity id;
+
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT = "x509.info.issuerID";
+ /**
+ * Sub attributes name for this CertAttrSet.
+ */
+ public static final String NAME = "issuerID";
+ public static final String ID = "id";
+
+ /**
+ * Default constructor for the certificate attribute.
+ *
+ * @param key the UniqueIdentity
+ */
+ public CertificateIssuerUniqueIdentity(UniqueIdentity id) {
+ this.id = id;
+ }
+
+ /**
+ * Create the object, decoding the values from the passed DER stream.
+ *
+ * @param in the DerInputStream to read the UniqueIdentity from.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateIssuerUniqueIdentity(DerInputStream in)
+ throws IOException {
+ id = new UniqueIdentity(in);
+ }
+
+ /**
+ * Create the object, decoding the values from the passed stream.
+ *
+ * @param in the InputStream to read the UniqueIdentity from.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateIssuerUniqueIdentity(InputStream in)
+ throws IOException {
+ DerValue val = new DerValue(in);
+ id = new UniqueIdentity(val);
+ }
+
+ /**
+ * Create the object, decoding the values from the passed DER value.
+ *
+ * @param in the DerValue to read the UniqueIdentity from.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateIssuerUniqueIdentity(DerValue val)
+ throws IOException {
+ id = new UniqueIdentity(val);
+ }
+
+ /**
+ * Return the identity as user readable string.
+ */
+ public String toString() {
+ if (id == null)
+ return "";
+ return (id.toString());
+ }
+
+ /**
+ * Decode the identity in DER form from the stream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ DerValue val = new DerValue(in);
+ id = new UniqueIdentity(val);
+ }
+
+ /**
+ * Encode the identity in DER form to the stream.
+ *
+ * @param out the DerOutputStream to marshal the contents to.
+ * @exception IOException on errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ id.encode(tmp, DerValue.createTag(DerValue.TAG_CONTEXT, false, (byte) 1));
+
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ if (!(obj instanceof UniqueIdentity)) {
+ throw new IOException("Attribute must be of type UniqueIdentity.");
+ }
+ if (name.equalsIgnoreCase(ID)) {
+ id = (UniqueIdentity) obj;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet: CertificateIssuerUniqueIdentity.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(ID)) {
+ return (id);
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet: CertificateIssuerUniqueIdentity.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(ID)) {
+ id = null;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet: CertificateIssuerUniqueIdentity.");
+ }
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(ID);
+
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/CertificatePoliciesExtension.java b/base/util/src/netscape/security/x509/CertificatePoliciesExtension.java
new file mode 100644
index 000000000..fedc15917
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CertificatePoliciesExtension.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * This class defines the Certificate Policies Extension.
+ *
+ * <p>
+ * The certificate policies extension conatins a sequence of policy information terms, each of which consists of an
+ * object identifier (OID) and optional qualifiers. These policy information terms indicate the policy under which the
+ * certificate has been issued and the purposes for which the certificate may be used. Aplications with specific policy
+ * requirements are expected to have a list of those policies which they will accept and to compare the policy OIDs in
+ * the certificate to that list. If this extension is critical, the path validation software must be able to interpret
+ * this extension, or must reject the certificate.
+ *
+ * <pre>
+ * CertificatePolicies ::= SEQUENECE OF PolicyInformation
+ * </pre>
+ *
+ * @author Christine Ho
+ * @see Extension
+ * @see CertAttrSet
+ */
+public class CertificatePoliciesExtension extends Extension
+ implements CertAttrSet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3729294064061837367L;
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT = "x509.info.extensions.CertificatePolicies";
+ /**
+ * Attribute names.
+ */
+ public static final String NAME = "CertificatePolicies";
+ public static final String INFOS = "infos";
+
+ // Private data members
+ private Vector<CertificatePolicyInfo> mInfos;
+
+ // Encode this extension value
+ private void encodeThis() throws IOException {
+ DerOutputStream os = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+
+ for (int i = 0; i < mInfos.size(); i++) {
+ ((CertificatePolicyInfo) mInfos.elementAt(i)).encode(tmp);
+ }
+ os.write(DerValue.tag_Sequence, tmp);
+ extensionValue = os.toByteArray();
+ }
+
+ public CertificatePoliciesExtension(boolean critical, Vector<CertificatePolicyInfo> infos) throws IOException {
+ this.mInfos = infos;
+ this.extensionId = PKIXExtensions.CertificatePolicies_Id;
+ this.critical = critical;
+ encodeThis();
+ }
+
+ /**
+ * Create a CertificatePolicies with the Vector of CertificatePolicyInfo.
+ *
+ * @param infos the Vector of CertificatePolicyInfo.
+ */
+ public CertificatePoliciesExtension(Vector<CertificatePolicyInfo> infos) throws IOException {
+ this.mInfos = infos;
+ this.extensionId = PKIXExtensions.CertificatePolicies_Id;
+ this.critical = false;
+ encodeThis();
+ }
+
+ /**
+ * Create a default CertificatePoliciesExtension.
+ */
+ public CertificatePoliciesExtension() {
+ this.extensionId = PKIXExtensions.CertificatePolicies_Id;
+ critical = false;
+ mInfos = new Vector<CertificatePolicyInfo>(1, 1);
+ }
+
+ /**
+ * Create the extension from the passed DER encoded value.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param value Array of DER encoded bytes of the actual value.
+ * @exception IOException on error.
+ */
+ public CertificatePoliciesExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = PKIXExtensions.CertificatePolicies_Id;
+ this.critical = critical.booleanValue();
+
+ int len = Array.getLength(value);
+ byte[] extValue = new byte[len];
+ for (int i = 0; i < len; i++) {
+ extValue[i] = Array.getByte(value, i);
+ }
+ this.extensionValue = extValue;
+ DerValue val = new DerValue(extValue);
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding for " +
+ "CertificatePoliciesExtension.");
+ }
+ mInfos = new Vector<CertificatePolicyInfo>(1, 1);
+ while (val.data.available() != 0) {
+ DerValue seq = val.data.getDerValue();
+ CertificatePolicyInfo info = new CertificatePolicyInfo(seq);
+ mInfos.addElement(info);
+ }
+ }
+
+ /**
+ * Returns a printable representation of the policy extension.
+ */
+ public String toString() {
+ if (mInfos == null)
+ return "";
+ String s = super.toString() + "Certificate Policies [\n"
+ + mInfos.toString() + "]\n";
+
+ return (s);
+ }
+
+ /**
+ * Write the extension to the OutputStream.
+ *
+ * @param out the OutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ if (extensionValue == null) {
+ extensionId = PKIXExtensions.CertificatePolicies_Id;
+ critical = false;
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Decode the extension from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ @SuppressWarnings("unchecked")
+ public void set(String name, Object obj) throws IOException {
+ clearValue();
+ if (name.equalsIgnoreCase(INFOS)) {
+ if (!(obj instanceof Vector)) {
+ throw new IOException("Attribute value should be of" +
+ " type Vector.");
+ }
+ mInfos = (Vector<CertificatePolicyInfo>) obj;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:CertificatePoliciesExtension.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(INFOS)) {
+ return (mInfos);
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:CertificatePoliciesExtension.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(INFOS)) {
+ mInfos = null;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:CertificatePoliciesExtension.");
+ }
+ }
+
+ /**
+ * Return an enumeration of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<Vector<CertificatePolicyInfo>> getAttributes() {
+ Vector<Vector<CertificatePolicyInfo>> elements = new Vector<Vector<CertificatePolicyInfo>>();
+ elements.addElement(mInfos);
+ return (elements.elements());
+ }
+
+ private static final String[] NAMES = { INFOS };
+
+ @Override
+ public Enumeration<String> getAttributeNames() {
+ // TODO Auto-generated method stub
+ return Collections.enumeration(Arrays.asList(NAMES));
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+
+ public static void main(String args[]) {
+
+ /**
+ * From ASN.1 dump
+ *
+ * 0 30 133: SEQUENCE {
+ * 3 30 45: . SEQUENCE {
+ * 5 06 3: . . OBJECT IDENTIFIER '1 2 3 5'
+ * 10 30 38: . . SEQUENCE {
+ * 12 30 36: . . . SEQUENCE {
+ * 14 06 8: . . . . OBJECT IDENTIFIER cps (1 3 6 1 5 5 7 2 1)
+ * : . . . . . (PKIX policy qualifier)
+ * 24 16 24: . . . . IA5String 'http://home.netscape.com'
+ * : . . . . }
+ * : . . . }
+ * : . . }
+ * 50 30 84: . SEQUENCE {
+ * 52 06 2: . . OBJECT IDENTIFIER '2 3 5'
+ * 56 30 78: . . SEQUENCE {
+ * 58 30 36: . . . SEQUENCE {
+ * 60 06 8: . . . . OBJECT IDENTIFIER cps (1 3 6 1 5 5 7 2 1)
+ * : . . . . . (PKIX policy qualifier)
+ * 70 16 24: . . . . IA5String 'http://home.netscape.com'
+ * : . . . . }
+ * 96 30 38: . . . SEQUENCE {
+ * 98 06 8: . . . . OBJECT IDENTIFIER unotice (1 3 6 1 5 5 7 2 2)
+ * : . . . . . (PKIX policy qualifier)
+ * 108 30 26: . . . . SEQUENCE {
+ * 110 30 16: . . . . . SEQUENCE {
+ * 112 1E 8: . . . . . . BMPString (1993) '_..o.r.g'
+ * 122 02 1: . . . . . . INTEGER 1
+ * 125 02 1: . . . . . . INTEGER 2
+ * : . . . . . . }
+ * 128 1E 6: . . . . . BMPString (1993) '_..d.t'
+ * : . . . . . }
+ * : . . . . }
+ * : . . . }
+ * : . . }
+ * : . }
+ **/
+
+ CertificatePolicyId plcyId0 = new CertificatePolicyId(
+ new ObjectIdentifier("1.2.3.5")
+ );
+ PolicyQualifiers qualifiers0 = new PolicyQualifiers();
+ CPSuri cpsQualifier0 = new CPSuri("http://home.netscape.com");
+ PolicyQualifierInfo qualifierInfo0 = new PolicyQualifierInfo(
+ PolicyQualifierInfo.QT_CPS,
+ cpsQualifier0
+ );
+ qualifiers0.add(qualifierInfo0);
+ CertificatePolicyInfo info0 = new CertificatePolicyInfo(
+ plcyId0, qualifiers0);
+ CertificatePolicyId plcyId1 = new CertificatePolicyId(
+ new ObjectIdentifier("2.3.5")
+ );
+ PolicyQualifiers qualifiers1 = new PolicyQualifiers();
+ DisplayText org1 = new DisplayText(DisplayText.tag_BMPString,
+ "org");
+ int nums[] = { 1, 2 };
+ NoticeReference nr1 = new NoticeReference(org1, nums);
+ DisplayText dt1 = new DisplayText(DisplayText.tag_BMPString,
+ "dt");
+ UserNotice userNotice1 = new UserNotice(nr1, dt1);
+ PolicyQualifierInfo qualifierInfo1 = new PolicyQualifierInfo(
+ PolicyQualifierInfo.QT_UNOTICE,
+ userNotice1
+ );
+ qualifiers1.add(qualifierInfo0);
+ qualifiers1.add(qualifierInfo1);
+ CertificatePolicyInfo info1 = new CertificatePolicyInfo(
+ plcyId1, qualifiers1);
+ Vector<CertificatePolicyInfo> infos = new Vector<CertificatePolicyInfo>();
+ infos.addElement(info0);
+ infos.addElement(info1);
+ try {
+ CertificatePoliciesExtension ext =
+ new CertificatePoliciesExtension(infos);
+
+ // BASE64 encode the whole thing and write it to stdout
+ System.out.println(Utils.base64encode(ext.getExtensionValue()));
+ } catch (IOException e) {
+ System.out.println(e.toString());
+ }
+ }
+
+}
diff --git a/base/util/src/netscape/security/x509/CertificatePolicyId.java b/base/util/src/netscape/security/x509/CertificatePolicyId.java
new file mode 100644
index 000000000..bfc93b0bb
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CertificatePolicyId.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 netscape.security.x509;
+
+import java.io.IOException;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * Represent the CertificatePolicyId ASN.1 object.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.5
+ */
+public class CertificatePolicyId implements java.io.Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2376810529862707757L;
+ private ObjectIdentifier id;
+
+ /**
+ * Create a CertificatePolicyId with the ObjectIdentifier.
+ *
+ * @param id the ObjectIdentifier for the policy id.
+ */
+ public CertificatePolicyId(ObjectIdentifier id) {
+ this.id = id;
+ }
+
+ /**
+ * Create the object from its Der encoded value.
+ *
+ * @param val the DER encoded value for the same.
+ */
+ public CertificatePolicyId(DerValue val) throws IOException {
+ this.id = val.getOID();
+ }
+
+ /**
+ * Return the value of the CertificatePolicyId as an ObjectIdentifier.
+ */
+ public ObjectIdentifier getIdentifier() {
+ return (id);
+ }
+
+ /**
+ * Returns a printable representation of the CertificatePolicyId.
+ */
+ public String toString() {
+ String s = "CertificatePolicyId: ["
+ + id.toString()
+ + "]\n";
+
+ return (s);
+ }
+
+ /**
+ * Write the CertificatePolicyId to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the object to.
+ * @exception IOException on errors.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ out.putOID(id);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/CertificatePolicyInfo.java b/base/util/src/netscape/security/x509/CertificatePolicyInfo.java
new file mode 100644
index 000000000..33e541c65
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CertificatePolicyInfo.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 netscape.security.x509;
+
+import java.io.IOException;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * Represent the CertificatePolicyInformation ASN.1 object.
+ *
+ * @author Christine Ho
+ */
+public class CertificatePolicyInfo implements java.io.Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8516006396099280477L;
+ private CertificatePolicyId mPolicyIdentifier;
+ private PolicyQualifiers mPolicyQualifiers;
+
+ /**
+ * Create a CertificatePolicyInfo with the passed CertificatePolicyId's.
+ *
+ * @param id the CertificatePolicyId.
+ */
+ public CertificatePolicyInfo(CertificatePolicyId id) {
+ this.mPolicyIdentifier = id;
+ this.mPolicyQualifiers = null;
+ }
+
+ public CertificatePolicyInfo(CertificatePolicyId id, PolicyQualifiers qualifiers) {
+ this.mPolicyIdentifier = id;
+ this.mPolicyQualifiers = qualifiers;
+ }
+
+ /**
+ * Create the CertificatePolicyInfo from the DER encoded value.
+ *
+ * @param val the DER encoded value of the same.
+ */
+ public CertificatePolicyInfo(DerValue val) throws IOException {
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding for CertificatePolicyInfo");
+ }
+ mPolicyIdentifier = new CertificatePolicyId(val.data.getDerValue());
+ // The specification is not clear on whether qualifier is
+ // optional or not. GTE CyberTrust Root certificate has
+ // no qualifier.
+ if (val.data.available() == 0) {
+ mPolicyQualifiers = null;
+ } else {
+ mPolicyQualifiers = new PolicyQualifiers(val.data.getDerValue());
+ }
+ }
+
+ /**
+ * return the policy identifier of the policy info
+ */
+ public CertificatePolicyId getPolicyIdentifier() {
+ return (mPolicyIdentifier);
+ }
+
+ public PolicyQualifiers getPolicyQualifiers() {
+ return mPolicyQualifiers;
+ }
+
+ /**
+ * Returns a printable representation of the CertificatePolicyId.
+ */
+ public String toString() {
+ String s = "CertificatePolicyInfo: [\n"
+ + "PolicyIdentifier:" + mPolicyIdentifier.toString()
+
+ + "]\n";
+ return (s);
+ }
+
+ /**
+ * Write the CertificatePolicyInfo to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the object to.
+ * @exception IOException on errors.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ mPolicyIdentifier.encode(tmp);
+ if (mPolicyQualifiers != null) {
+ mPolicyQualifiers.encode(tmp);
+ }
+ out.write(DerValue.tag_Sequence, tmp);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/CertificatePolicyMap.java b/base/util/src/netscape/security/x509/CertificatePolicyMap.java
new file mode 100644
index 000000000..75ddf3314
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CertificatePolicyMap.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 netscape.security.x509;
+
+import java.io.IOException;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * Represent the CertificatePolicyMap ASN.1 object.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.5
+ */
+public class CertificatePolicyMap {
+ private CertificatePolicyId issuerDomain;
+ private CertificatePolicyId subjectDomain;
+
+ /**
+ * Create a CertificatePolicyMap with the passed CertificatePolicyId's.
+ *
+ * @param issuer the CertificatePolicyId for the issuer CA.
+ * @param subject the CertificatePolicyId for the subject CA.
+ */
+ public CertificatePolicyMap(CertificatePolicyId issuer,
+ CertificatePolicyId subject) {
+ this.issuerDomain = issuer;
+ this.subjectDomain = subject;
+ }
+
+ /**
+ * Create the CertificatePolicyMap from the DER encoded value.
+ *
+ * @param val the DER encoded value of the same.
+ */
+ public CertificatePolicyMap(DerValue val) throws IOException {
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding for CertificatePolicyMap");
+ }
+ issuerDomain = new CertificatePolicyId(val.data.getDerValue());
+ subjectDomain = new CertificatePolicyId(val.data.getDerValue());
+ }
+
+ /**
+ * Return the issuer CA part of the policy map.
+ */
+ public CertificatePolicyId getIssuerIdentifier() {
+ return (issuerDomain);
+ }
+
+ /**
+ * Return the subject CA part of the policy map.
+ */
+ public CertificatePolicyId getSubjectIdentifier() {
+ return (subjectDomain);
+ }
+
+ /**
+ * Returns a printable representation of the CertificatePolicyId.
+ */
+ public String toString() {
+ String s = "CertificatePolicyMap: [\n"
+ + "IssuerDomain:" + issuerDomain.toString()
+ + "SubjectDomain:" + subjectDomain.toString()
+ + "]\n";
+
+ return (s);
+ }
+
+ /**
+ * Write the CertificatePolicyMap to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the object to.
+ * @exception IOException on errors.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ issuerDomain.encode(tmp);
+ subjectDomain.encode(tmp);
+ out.write(DerValue.tag_Sequence, tmp);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/CertificatePolicySet.java b/base/util/src/netscape/security/x509/CertificatePolicySet.java
new file mode 100644
index 000000000..86d9c107f
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CertificatePolicySet.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.util.Vector;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class defines the certificate policy set ASN.1 object.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.4
+ */
+public class CertificatePolicySet {
+ private Vector<CertificatePolicyId> ids;
+
+ /**
+ * The default constructor for this class.
+ *
+ * @param ids the sequence of CertificatePolicyId's.
+ */
+ public CertificatePolicySet(Vector<CertificatePolicyId> ids) {
+ this.ids = ids;
+ }
+
+ /**
+ * Create the object from the DerValue.
+ *
+ * @param in the passed DerInputStream.
+ * @exception IOException on decoding errors.
+ */
+ public CertificatePolicySet(DerInputStream in) throws IOException {
+ ids = new Vector<CertificatePolicyId>(1, 1);
+ DerValue[] seq = in.getSequence(5);
+
+ for (int i = 0; i < seq.length; i++) {
+ CertificatePolicyId id = new CertificatePolicyId(seq[i]);
+ ids.addElement(id);
+ }
+ }
+
+ /**
+ * Return printable form of the object.
+ */
+ public String toString() {
+ String s = "CertificatePolicySet:[\n"
+ + ids.toString()
+ + "]\n";
+
+ return (s);
+ }
+
+ /**
+ * Encode the policy set to the output stream.
+ *
+ * @param out the DerOutputStream to encode the data to.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ for (int i = 0; i < ids.size(); i++) {
+ ((CertificatePolicyId) ids.elementAt(i)).encode(tmp);
+ }
+ out.write(DerValue.tag_Sequence, tmp);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/CertificateSerialNumber.java b/base/util/src/netscape/security/x509/CertificateSerialNumber.java
new file mode 100644
index 000000000..e9655178f
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CertificateSerialNumber.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class defines the SerialNumber attribute for the Certificate.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.6
+ * @see CertAttrSet
+ */
+public class CertificateSerialNumber implements CertAttrSet {
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT = "x509.info.serialNumber";
+
+ /**
+ * Sub attributes name for this CertAttrSet.
+ */
+ public static final String NAME = "serialNumber";
+ public static final String NUMBER = "number";
+
+ private SerialNumber serial;
+
+ /**
+ * Default constructor for the certificate attribute.
+ *
+ * @param serial the serial number for the certificate.
+ */
+ public CertificateSerialNumber(BigInteger num) {
+ this.serial = new SerialNumber(num);
+ }
+
+ /**
+ * Default constructor for the certificate attribute.
+ *
+ * @param serial the serial number for the certificate.
+ */
+ public CertificateSerialNumber(int num) {
+ this.serial = new SerialNumber(num);
+ }
+
+ /**
+ * Create the object, decoding the values from the passed DER stream.
+ *
+ * @param in the DerInputStream to read the serial number from.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateSerialNumber(DerInputStream in) throws IOException {
+ serial = new SerialNumber(in);
+ }
+
+ /**
+ * Create the object, decoding the values from the passed stream.
+ *
+ * @param in the InputStream to read the serial number from.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateSerialNumber(InputStream in) throws IOException {
+ serial = new SerialNumber(in);
+ }
+
+ /**
+ * Create the object, decoding the values from the passed DerValue.
+ *
+ * @param val the DER encoded value.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateSerialNumber(DerValue val) throws IOException {
+ serial = new SerialNumber(val);
+ }
+
+ /**
+ * Return the serial number as user readable string.
+ */
+ public String toString() {
+ if (serial == null)
+ return "";
+ return (serial.toString());
+ }
+
+ /**
+ * Encode the serial number in DER form to the stream.
+ *
+ * @param out the DerOutputStream to marshal the contents to.
+ * @exception IOException on errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ serial.encode(tmp);
+
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Decode the serial number in DER form from the stream.
+ *
+ * @param in the InputStream to marshal the contents from.
+ * @exception IOException on errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ DerValue derVal = new DerValue(in);
+ serial = new SerialNumber(derVal);
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ if (!(obj instanceof SerialNumber)) {
+ throw new IOException("Attribute must be of type SerialNumber.");
+ }
+ if (name.equalsIgnoreCase(NUMBER)) {
+ serial = (SerialNumber) obj;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:CertificateSerialNumber.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(NUMBER)) {
+ return (serial);
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:CertificateSerialNumber.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(NUMBER)) {
+ serial = null;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:CertificateSerialNumber.");
+ }
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(NUMBER);
+
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/CertificateSubjectName.java b/base/util/src/netscape/security/x509/CertificateSubjectName.java
new file mode 100644
index 000000000..6159638b9
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CertificateSubjectName.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class defines the X500Name attribute for the Certificate.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.6
+ * @see CertAttrSet
+ */
+public class CertificateSubjectName implements CertAttrSet, Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 503643453152834350L;
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT = "x509.info.subject";
+ /**
+ * Sub attributes name for this CertAttrSet.
+ */
+ public static final String NAME = "subject";
+ public static final String DN_NAME = "dname";
+
+ // Private data member
+ private X500Name dnName;
+
+ /**
+ * Default constructor for the certificate attribute.
+ *
+ * @param name the X500Name
+ */
+ public CertificateSubjectName(X500Name name) {
+ this.dnName = name;
+ }
+
+ /**
+ * Create the object, decoding the values from the passed DER stream.
+ *
+ * @param in the DerInputStream to read the X500Name from.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateSubjectName(DerInputStream in) throws IOException {
+ dnName = new X500Name(in);
+ }
+
+ /**
+ * Create the object, decoding the values from the passed stream.
+ *
+ * @param in the InputStream to read the X500Name from.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateSubjectName(InputStream in) throws IOException {
+ DerValue derVal = new DerValue(in);
+ dnName = new X500Name(derVal);
+ }
+
+ /**
+ * Return the name as user readable string.
+ */
+ public String toString() {
+ if (dnName == null)
+ return "";
+ return (dnName.toString());
+ }
+
+ private synchronized void writeObject(ObjectOutputStream stream)
+ throws IOException {
+ encode(stream);
+ }
+
+ private synchronized void readObject(ObjectInputStream stream)
+ throws IOException {
+ decodeEx(stream);
+ }
+
+ /**
+ * Encode the name in DER form to the stream.
+ *
+ * @param out the DerOutputStream to marshal the contents to.
+ * @exception IOException on errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ dnName.encode(tmp);
+
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Decode the name in DER form from the stream.
+ *
+ * @param in the InputStream to marshal the contents from.
+ * @exception IOException on errors.
+ */
+ public void decodeEx(InputStream in) throws IOException {
+ DerValue derVal = new DerValue(in);
+
+ // dnName = new X500Name(derVal);
+ dnName = new X500Name(derVal.toByteArray());
+ }
+
+ /**
+ * Decode the name in DER form from the stream.
+ *
+ * @param in the InputStream to marshal the contents from.
+ * @exception IOException on errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ DerValue derVal = new DerValue(in);
+
+ dnName = new X500Name(derVal);
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ if (!(obj instanceof X500Name)) {
+ throw new IOException("Attribute must be of type X500Name.");
+ }
+ if (name.equalsIgnoreCase(DN_NAME)) {
+ this.dnName = (X500Name) obj;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:CertificateSubjectName.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(DN_NAME)) {
+ return (dnName);
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:CertificateSubjectName.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(DN_NAME)) {
+ dnName = null;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:CertificateSubjectName.");
+ }
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(DN_NAME);
+
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/CertificateSubjectUniqueIdentity.java b/base/util/src/netscape/security/x509/CertificateSubjectUniqueIdentity.java
new file mode 100644
index 000000000..51687e86d
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CertificateSubjectUniqueIdentity.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class defines the subject/issuer unique identity attribute
+ * for the Certificate.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.6
+ * @see CertAttrSet
+ */
+public class CertificateSubjectUniqueIdentity implements CertAttrSet {
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT = "x509.info.subjectID";
+ /**
+ * Sub attributes name for this CertAttrSet.
+ */
+ public static final String NAME = "subjectID";
+ public static final String ID = "id";
+
+ private UniqueIdentity id;
+
+ /**
+ * Default constructor for the certificate attribute.
+ *
+ * @param key the UniqueIdentity
+ */
+ public CertificateSubjectUniqueIdentity(UniqueIdentity id) {
+ this.id = id;
+ }
+
+ /**
+ * Create the object, decoding the values from the passed DER stream.
+ *
+ * @param in the DerInputStream to read the UniqueIdentity from.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateSubjectUniqueIdentity(DerInputStream in)
+ throws IOException {
+ id = new UniqueIdentity(in);
+ }
+
+ /**
+ * Create the object, decoding the values from the passed stream.
+ *
+ * @param in the InputStream to read the UniqueIdentity from.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateSubjectUniqueIdentity(InputStream in)
+ throws IOException {
+ DerValue val = new DerValue(in);
+ id = new UniqueIdentity(val);
+ }
+
+ /**
+ * Create the object, decoding the values from the passed DER value.
+ *
+ * @param in the DerValue to read the UniqueIdentity from.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateSubjectUniqueIdentity(DerValue val)
+ throws IOException {
+ id = new UniqueIdentity(val);
+ }
+
+ /**
+ * Return the identity as user readable string.
+ */
+ public String toString() {
+ if (id == null)
+ return "";
+ return (id.toString());
+ }
+
+ /**
+ * Decode the identity in DER form from the stream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ DerValue val = new DerValue(in);
+ id = new UniqueIdentity(val);
+ }
+
+ /**
+ * Encode the identity in DER form to the stream.
+ *
+ * @param out the DerOutputStream to marshal the contents to.
+ * @exception IOException on errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ id.encode(tmp, DerValue.createTag(DerValue.TAG_CONTEXT, false, (byte) 2));
+
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ if (!(obj instanceof UniqueIdentity)) {
+ throw new IOException("Attribute must be of type UniqueIdentity.");
+ }
+ if (name.equalsIgnoreCase(ID)) {
+ id = (UniqueIdentity) obj;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet: CertificateSubjectUniqueIdentity.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(ID)) {
+ return (id);
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet: CertificateSubjectUniqueIdentity.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(ID)) {
+ id = null;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet: CertificateSubjectUniqueIdentity.");
+ }
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(ID);
+
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/CertificateValidity.java b/base/util/src/netscape/security/x509/CertificateValidity.java
new file mode 100644
index 000000000..0c2c841b0
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CertificateValidity.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class defines the interval for which the certificate is valid.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.12
+ * @see CertAttrSet
+ */
+public class CertificateValidity implements CertAttrSet, Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8277703278213804194L;
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT = "x509.info.validity";
+ /**
+ * Sub attributes name for this CertAttrSet.
+ */
+ public static final String NAME = "validity";
+ public static final String NOT_BEFORE = "notBefore";
+ public static final String NOT_AFTER = "notAfter";
+ private static final long YR_2050 = 2524636800000L;
+
+ // Private data members
+ private Date notBefore;
+ private Date notAfter;
+
+ // Returns the first time the certificate is valid.
+ private Date getNotBefore() {
+ return (new Date(notBefore.getTime()));
+ }
+
+ // Returns the last time the certificate is valid.
+ private Date getNotAfter() {
+ return (new Date(notAfter.getTime()));
+ }
+
+ // Construct the class from the DerValue
+ private void construct(DerValue derVal) throws IOException {
+ if (derVal.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoded CertificateValidity, " +
+ "starting sequence tag missing.");
+ }
+ // check if UTCTime encoded or GeneralizedTime
+ if (derVal.data.available() == 0)
+ throw new IOException("No data encoded for CertificateValidity");
+
+ DerInputStream derIn = new DerInputStream(derVal.toByteArray());
+ DerValue[] seq = derIn.getSequence(2);
+ if (seq.length != 2)
+ throw new IOException("Invalid encoding for CertificateValidity");
+
+ if (seq[0].tag == DerValue.tag_UtcTime) {
+ notBefore = derVal.data.getUTCTime();
+ } else if (seq[0].tag == DerValue.tag_GeneralizedTime) {
+ notBefore = derVal.data.getGeneralizedTime();
+ } else {
+ throw new IOException("Invalid encoding for CertificateValidity");
+ }
+
+ if (seq[1].tag == DerValue.tag_UtcTime) {
+ notAfter = derVal.data.getUTCTime();
+ } else if (seq[1].tag == DerValue.tag_GeneralizedTime) {
+ notAfter = derVal.data.getGeneralizedTime();
+ } else {
+ throw new IOException("Invalid encoding for CertificateValidity");
+ }
+ }
+
+ /**
+ * Default constructor for the class.
+ */
+ public CertificateValidity() {
+ }
+
+ /**
+ * The default constructor for this class for the specified interval.
+ *
+ * @param notBefore the date and time before which the certificate
+ * is not valid.
+ * @param notAfter the date and time after which the certificate is
+ * not valid.
+ */
+ public CertificateValidity(Date notBefore, Date notAfter) {
+ this.notBefore = notBefore;
+ this.notAfter = notAfter;
+ }
+
+ /**
+ * Create the object, decoding the values from the passed DER stream.
+ *
+ * @param in the DerInputStream to read the CertificateValidity from.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateValidity(DerInputStream in) throws IOException {
+ DerValue derVal = in.getDerValue();
+ construct(derVal);
+ }
+
+ /**
+ * Return the validity period as user readable string.
+ */
+ public String toString() {
+ if (notBefore == null || notAfter == null)
+ return "";
+ return ("Validity: [From: " + notBefore.toString() +
+ ",\n To: " + notAfter.toString() + "]");
+ }
+
+ /**
+ * Decode the CertificateValidity period from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ DerValue derVal = new DerValue(in);
+ construct(derVal);
+ }
+
+ private synchronized void writeObject(ObjectOutputStream stream)
+ throws IOException {
+ encode(stream);
+ }
+
+ private synchronized void readObject(ObjectInputStream stream)
+ throws IOException {
+ decode(stream);
+ }
+
+ /**
+ * Encode the CertificateValidity period in DER form to the stream.
+ *
+ * @param out the OutputStream to marshal the contents to.
+ * @exception IOException on errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+
+ // in cases where default constructor is used check for
+ // null values
+ if (notBefore == null || notAfter == null) {
+ throw new IOException("CertAttrSet:CertificateValidity:" +
+ " null values to encode.\n");
+ }
+ DerOutputStream pair = new DerOutputStream();
+
+ if (notBefore.getTime() < YR_2050) {
+ pair.putUTCTime(notBefore);
+ } else
+ pair.putGeneralizedTime(notBefore);
+
+ if (notAfter.getTime() < YR_2050) {
+ pair.putUTCTime(notAfter);
+ } else {
+ pair.putGeneralizedTime(notAfter);
+ }
+ DerOutputStream seq = new DerOutputStream();
+ seq.write(DerValue.tag_Sequence, pair);
+
+ out.write(seq.toByteArray());
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ if (!(obj instanceof Date)) {
+ throw new IOException("Attribute must be of type Date.");
+ }
+ if (name.equalsIgnoreCase(NOT_BEFORE)) {
+ notBefore = (Date) obj;
+ } else if (name.equalsIgnoreCase(NOT_AFTER)) {
+ notAfter = (Date) obj;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet: CertificateValidity.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(NOT_BEFORE)) {
+ return (getNotBefore());
+ } else if (name.equalsIgnoreCase(NOT_AFTER)) {
+ return (getNotAfter());
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet: CertificateValidity.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(NOT_BEFORE)) {
+ notBefore = null;
+ } else if (name.equalsIgnoreCase(NOT_AFTER)) {
+ notAfter = null;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet: CertificateValidity.");
+ }
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(NOT_BEFORE);
+ elements.addElement(NOT_AFTER);
+
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+
+ /**
+ * Verify that the current time is within the validity period.
+ *
+ * @exception CertificateExpiredException if the certificate has expired.
+ * @exception CertificateNotYetValidException if the certificate is not
+ * yet valid.
+ */
+ public void valid()
+ throws CertificateNotYetValidException, CertificateExpiredException {
+ Date now = new Date();
+ valid(now);
+ }
+
+ /**
+ * Verify that the passed time is within the validity period.
+ *
+ * @param now the Date against which to compare the validity
+ * period.
+ *
+ * @exception CertificateExpiredException if the certificate has expired
+ * with respect to the <code>Date</code> supplied.
+ * @exception CertificateNotYetValidException if the certificate is not
+ * yet valid with respect to the <code>Date</code> supplied.
+ *
+ */
+ public void valid(Date now)
+ throws CertificateNotYetValidException, CertificateExpiredException {
+ /*
+ * we use the internal Dates rather than the passed in Date
+ * because someone could override the Date methods after()
+ * and before() to do something entirely different.
+ */
+ if (notBefore.after(now)) {
+ throw new CertificateNotYetValidException("NotBefore: " +
+ notBefore.toString());
+ }
+ if (notAfter.before(now)) {
+ throw new CertificateExpiredException("NotAfter: " +
+ notAfter.toString());
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/x509/CertificateVersion.java b/base/util/src/netscape/security/x509/CertificateVersion.java
new file mode 100644
index 000000000..d3659779f
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CertificateVersion.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class defines the version of the X509 Certificate.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.8
+ * @see CertAttrSet
+ */
+public class CertificateVersion implements CertAttrSet {
+ /**
+ * X509Certificate Version 1
+ */
+ public static final int V1 = 0;
+ /**
+ * X509Certificate Version 2
+ */
+ public static final int V2 = 1;
+ /**
+ * X509Certificate Version 3
+ */
+ public static final int V3 = 2;
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT = "x509.info.version";
+ /**
+ * Sub attributes name for this CertAttrSet.
+ */
+ public static final String NAME = "version";
+ public static final String VERSION = "number";
+
+ // Private data members
+ int version = V1;
+
+ // Returns the version number.
+ private int getVersion() {
+ return (version);
+ }
+
+ // Construct the class from the passed DerValue
+ private void construct(DerValue derVal) throws IOException {
+ if (derVal.isConstructed() && derVal.isContextSpecific()) {
+ derVal = derVal.data.getDerValue();
+ version = derVal.getInteger().toInt();
+ if (derVal.data.available() != 0) {
+ throw new IOException("X.509 version, bad format");
+ }
+ }
+ }
+
+ /**
+ * The default constructor for this class,
+ * sets the version to 0 (i.e. X.509 version 1).
+ */
+ public CertificateVersion() {
+ version = V1;
+ }
+
+ /**
+ * The constructor for this class for the required version.
+ *
+ * @param version the version for the certificate.
+ * @exception IOException if the version is not valid.
+ */
+ public CertificateVersion(int version) throws IOException {
+
+ // check that it is a valid version
+ if (version == V1 || version == V2 || version == V3)
+ this.version = version;
+ else {
+ throw new IOException("X.509 Certificate version " +
+ version + " not supported.\n");
+ }
+ }
+
+ /**
+ * Create the object, decoding the values from the passed DER stream.
+ *
+ * @param in the DerInputStream to read the CertificateVersion from.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateVersion(DerInputStream in) throws IOException {
+ version = V1;
+ DerValue derVal = in.getDerValue();
+
+ construct(derVal);
+ }
+
+ /**
+ * Create the object, decoding the values from the passed stream.
+ *
+ * @param in the InputStream to read the CertificateVersion from.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateVersion(InputStream in) throws IOException {
+ version = V1;
+ DerValue derVal = new DerValue(in);
+
+ construct(derVal);
+ }
+
+ /**
+ * Create the object, decoding the values from the passed DerValue.
+ *
+ * @param val the Der encoded value.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateVersion(DerValue val) throws IOException {
+ version = V1;
+
+ construct(val);
+ }
+
+ /**
+ * Return the version number of the certificate.
+ */
+ public String toString() {
+ return ("Version: V" + (version + 1));
+ }
+
+ /**
+ * Encode the CertificateVersion period in DER form to the stream.
+ *
+ * @param out the OutputStream to marshal the contents to.
+ * @exception IOException on errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ // Nothing for default
+ if (version == V1) {
+ return;
+ }
+ DerOutputStream tmp = new DerOutputStream();
+ tmp.putInteger(new BigInt(version));
+
+ DerOutputStream seq = new DerOutputStream();
+ seq.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0),
+ tmp);
+
+ out.write(seq.toByteArray());
+ }
+
+ /**
+ * Decode the CertificateVersion period in DER form from the stream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ DerValue derVal = new DerValue(in);
+ construct(derVal);
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ if (!(obj instanceof Integer)) {
+ throw new IOException("Attribute must be of type Integer.");
+ }
+ if (name.equalsIgnoreCase(VERSION)) {
+ version = ((Integer) obj).intValue();
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet: CertificateVersion.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(VERSION)) {
+ return (Integer.valueOf(getVersion()));
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet: CertificateVersion.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(VERSION)) {
+ version = V1;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet: CertificateVersion.");
+ }
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(VERSION);
+
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+
+ /**
+ * Compare versions.
+ */
+ public int compare(int vers) {
+ return (version - vers);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/CertificateX509Key.java b/base/util/src/netscape/security/x509/CertificateX509Key.java
new file mode 100644
index 000000000..c7003bb8e
--- /dev/null
+++ b/base/util/src/netscape/security/x509/CertificateX509Key.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class defines the X509Key attribute for the Certificate.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.5
+ * @see CertAttrSet
+ */
+public class CertificateX509Key implements CertAttrSet, Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6718749024328681131L;
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT = "x509.info.key";
+ /**
+ * Sub attributes name for this CertAttrSet.
+ */
+ public static final String NAME = "key";
+ public static final String KEY = "value";
+
+ // Private data member
+ private X509Key key;
+
+ /**
+ * Default constructor for the certificate attribute.
+ *
+ * @param key the X509Key
+ */
+ public CertificateX509Key(X509Key key) {
+ this.key = key;
+ }
+
+ /**
+ * Create the object, decoding the values from the passed DER stream.
+ *
+ * @param in the DerInputStream to read the X509Key from.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateX509Key(DerInputStream in) throws IOException {
+ DerValue val = in.getDerValue();
+ key = X509Key.parse(val);
+ }
+
+ /**
+ * Create the object, decoding the values from the passed stream.
+ *
+ * @param in the InputStream to read the X509Key from.
+ * @exception IOException on decoding errors.
+ */
+ public CertificateX509Key(InputStream in) throws IOException {
+ DerValue val = new DerValue(in);
+ key = X509Key.parse(val);
+ }
+
+ /**
+ * Return the key as printable string.
+ */
+ public String toString() {
+ if (key == null)
+ return "";
+ return (key.toString());
+ }
+
+ /**
+ * Decode the key in DER form from the stream.
+ *
+ * @param in the InputStream to unmarshal the contents from
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ DerValue val = new DerValue(in);
+ key = X509Key.parse(val);
+ }
+
+ private synchronized void writeObject(ObjectOutputStream stream)
+ throws IOException {
+ encode(stream);
+ }
+
+ private synchronized void readObject(ObjectInputStream stream)
+ throws IOException {
+ decode(stream);
+ }
+
+ /**
+ * Encode the key in DER form to the stream.
+ *
+ * @param out the OutputStream to marshal the contents to.
+ * @exception IOException on errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ key.encode(tmp);
+
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ if (!(obj instanceof X509Key)) {
+ throw new IOException("Attribute must be of type X509Key.");
+ }
+ if (name.equalsIgnoreCase(KEY)) {
+ this.key = (X509Key) obj;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet: CertificateX509Key.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(KEY)) {
+ return (key);
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet: CertificateX509Key.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(KEY)) {
+ key = null;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet: CertificateX509Key.");
+ }
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(KEY);
+
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/DNSName.java b/base/util/src/netscape/security/x509/DNSName.java
new file mode 100644
index 000000000..831f51cc1
--- /dev/null
+++ b/base/util/src/netscape/security/x509/DNSName.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 netscape.security.x509;
+
+import java.io.IOException;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class implements the DNSName as required by the GeneralNames
+ * ASN.1 object.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.4
+ */
+public class DNSName implements GeneralNameInterface {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2907649488092607056L;
+ private String name;
+
+ /**
+ * Create the DNSName object from the passed encoded Der value.
+ *
+ * @param derValue the encoded DER DNSName.
+ * @exception IOException on error.
+ */
+ public DNSName(DerValue derValue) throws IOException {
+ name = derValue.getIA5String();
+ }
+
+ /**
+ * Create the DNSName object with the specified name.
+ *
+ * @param name the DNSName.
+ */
+ public DNSName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Return the type of the GeneralName.
+ */
+ public int getType() {
+ return (GeneralNameInterface.NAME_DNS);
+ }
+
+ /**
+ * Encode the DNS name into the DerOutputStream.
+ *
+ * @param out the DER stream to encode the DNSName to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ out.putIA5String(name);
+ }
+
+ /**
+ * Convert the name into user readable string.
+ */
+ public String toString() {
+ return ("DNSName: " + name);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/DeltaCRLIndicatorExtension.java b/base/util/src/netscape/security/x509/DeltaCRLIndicatorExtension.java
new file mode 100755
index 000000000..da870f4fd
--- /dev/null
+++ b/base/util/src/netscape/security/x509/DeltaCRLIndicatorExtension.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.math.BigInteger;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * Represent the Delta CRL Indicator Extension.
+ *
+ * <p>
+ * The delta CRL indicator is a critical CRL extension that identifies a delta-CRL. The value of BaseCRLNumber
+ * identifies the CRL number of the base CRL that was used as the starting point in the generation of this delta- CRL.
+ * The delta-CRL contains the changes between the base CRL and the current CRL issued along with the delta-CRL.
+ *
+ * @see Extension
+ * @see CertAttrSet
+ */
+public class DeltaCRLIndicatorExtension extends Extension
+ implements CertAttrSet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7182919216525364676L;
+ /**
+ * Attribute name.
+ */
+ public static final String NAME = "DeltaCRLIndicator";
+ public static final String NUMBER = "value";
+
+ /**
+ * The Object Identifier for this extension.
+ */
+ public static final String OID = "2.5.29.27";
+
+ private BigInt baseCRLNumber = null;
+
+ static {
+ try {
+ OIDMap.addAttribute(DeltaCRLIndicatorExtension.class.getName(),
+ OID, NAME);
+ } catch (CertificateException e) {
+ }
+ }
+
+ // Encode this extension value
+ private void encodeThis() throws IOException {
+ if (baseCRLNumber == null)
+ throw new IOException("Unintialized delta CRL indicator extension");
+ DerOutputStream os = new DerOutputStream();
+ os.putInteger(this.baseCRLNumber);
+ this.extensionValue = os.toByteArray();
+ }
+
+ /**
+ * Create a DeltaCRLIndicatorExtension with the integer value.
+ * The criticality is set to true.
+ *
+ * @param baseCRLNum the value to be set for the extension.
+ */
+ public DeltaCRLIndicatorExtension(int baseCRLNum) throws IOException {
+ this.baseCRLNumber = new BigInt(baseCRLNum);
+ this.extensionId = PKIXExtensions.DeltaCRLIndicator_Id;
+ this.critical = true;
+ encodeThis();
+ }
+
+ /**
+ * Create a DeltaCRLIndicatorExtension with the BigInteger value.
+ * The criticality is set to true.
+ *
+ * @param baseCRLNum the value to be set for the extension.
+ */
+ public DeltaCRLIndicatorExtension(BigInteger baseCRLNum) throws IOException {
+ this.baseCRLNumber = new BigInt(baseCRLNum);
+ this.extensionId = PKIXExtensions.DeltaCRLIndicator_Id;
+ this.critical = true;
+ encodeThis();
+ }
+
+ /**
+ * Create a DeltaCRLIndicatorExtension with the BigInteger value.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param baseCRLNum the value to be set for the extension.
+ */
+ public DeltaCRLIndicatorExtension(Boolean critical, BigInteger baseCRLNum)
+ throws IOException {
+ this.baseCRLNumber = new BigInt(baseCRLNum);
+ this.extensionId = PKIXExtensions.DeltaCRLIndicator_Id;
+ this.critical = critical.booleanValue();
+ encodeThis();
+ }
+
+ /**
+ * Create the extension from the passed DER encoded value of the same.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param value Array of DER encoded bytes of the actual value.
+ * @exception IOException on error.
+ */
+ public DeltaCRLIndicatorExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = PKIXExtensions.DeltaCRLIndicator_Id;
+ this.critical = critical.booleanValue();
+
+ int len = Array.getLength(value);
+ byte[] extValue = new byte[len];
+ for (int i = 0; i < len; i++) {
+ extValue[i] = Array.getByte(value, i);
+ }
+ this.extensionValue = extValue;
+ DerValue val = new DerValue(extValue);
+ this.baseCRLNumber = val.getInteger();
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ if (name.equalsIgnoreCase(NUMBER)) {
+ if (!(obj instanceof BigInteger)) {
+ throw new IOException("Attribute must be of type BigInteger.");
+ }
+ baseCRLNumber = new BigInt((BigInteger) obj);
+ } else {
+ throw new IOException("Attribute name not recognized by" +
+ " CertAttrSet:DeltaCRLIndicator.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(NUMBER)) {
+ if (baseCRLNumber == null)
+ return null;
+ else
+ return baseCRLNumber.toBigInteger();
+ } else {
+ throw new IOException("Attribute name not recognized by" +
+ " CertAttrSet:DeltaCRLIndicator.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(NUMBER)) {
+ baseCRLNumber = null;
+ } else {
+ throw new IOException("Attribute name not recognized by" +
+ " CertAttrSet:DeltaCRLIndicator.");
+ }
+ }
+
+ /**
+ * Returns a printable representation of the DeltaCRLIndicatorExtension.
+ */
+ public String toString() {
+ String s = super.toString() + "Delta CRL Indicator: " +
+ ((baseCRLNumber == null) ? "" : baseCRLNumber.toString())
+ + "\n";
+ return (s);
+ }
+
+ /**
+ * Decode the extension from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ /**
+ * Write the extension to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ if (this.extensionValue == null) {
+ this.extensionId = PKIXExtensions.DeltaCRLIndicator_Id;
+ this.critical = true;
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(NUMBER);
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/DirStrConverter.java b/base/util/src/netscape/security/x509/DirStrConverter.java
new file mode 100644
index 000000000..776344c0a
--- /dev/null
+++ b/base/util/src/netscape/security/x509/DirStrConverter.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetEncoder;
+
+import netscape.security.util.ASN1CharStrConvMap;
+import netscape.security.util.DerValue;
+
+/**
+ * A DirStrConverter converts a string to a DerValue of ASN.1 Directory String,
+ * which is a CHOICE of Printable (subset of ASCII), T.61 (Teletex) or
+ * Universal String (UCS-4), and vice versa.
+ *
+ * <p>
+ * The string to DerValue conversion is done as follows. If the string has only PrintableString characters it is
+ * converted to a ASN.1 Printable String using the PrintableString encoder from the global default ASN1CharStrConvMap.
+ * If it has only characters covered in the PrintableString or T.61 character set it is converted to a ASN.1 T.61 string
+ * using the T.61 encoder from the ASN1CharStrCovnMap. Otherwise it is converted to a ASN.1 UniversalString (UCS-4
+ * character set) which covers all characters.
+ *
+ * @see AVAValueConverter
+ * @see ASN1CharStrConvMap
+ *
+ * @author Lily Hsiao, Slava Galperin at Netscape Communications, Inc.
+ */
+
+public class DirStrConverter implements AVAValueConverter {
+ // public constructors
+
+ /**
+ * Constructs a DirStrConverter.
+ */
+ public DirStrConverter() {
+ }
+
+ // public functions
+
+ /**
+ * Converts a string to a DER encoded ASN1 Directory String, which is a
+ * CHOICE of PrintableString, T.61String or UniversalString.
+ * The string is taken as is i.e. should not be in Ldap DN string syntax.
+ *
+ * @param ds a string representing a directory string value.
+ *
+ * @return a DerValue
+ *
+ * @exception IOException if the string cannot be converted, such as
+ * when a UniversalString encoder
+ * isn't available and the string contains
+ * characters covered only in the universal
+ * string (or UCS-4) character set.
+ */
+ private static byte[] DefEncodingOrder =
+ new byte[] {
+ DerValue.tag_PrintableString,
+ DerValue.tag_T61String,
+ DerValue.tag_UniversalString
+ };
+
+ public static synchronized void
+ setDefEncodingOrder(byte[] defEncodingOrder) {
+ DefEncodingOrder = defEncodingOrder;
+ }
+
+ public DerValue getValue(String ds)
+ throws IOException {
+ return getValue(ds, DefEncodingOrder);
+ }
+
+ /**
+ * Like getValue(String) with specified DER tags as encoding order.
+ */
+ public DerValue getValue(String valueString, byte[] tags) throws IOException {
+ // try to convert to printable, then t61 the universal -
+ // i.e. from minimal to the most liberal.
+
+ if (tags == null || tags.length == 0)
+ tags = DefEncodingOrder;
+
+ for (int i = 0; i < tags.length; i++) {
+ try {
+ CharsetEncoder encoder = ASN1CharStrConvMap.getDefault().getEncoder(tags[i]);
+ if (encoder == null)
+ continue;
+
+ CharBuffer charBuffer = CharBuffer.wrap(valueString.toCharArray());
+ ByteBuffer byteBuffer = encoder.encode(charBuffer);
+
+ return new DerValue(tags[i], byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.limit());
+
+ } catch (CharacterCodingException e) {
+ continue;
+ }
+ }
+
+ throw new IOException(
+ "Cannot convert the directory string value to a ASN.1 type");
+ }
+
+ /**
+ * Creates a DerValue from a BER encoded value, obtained from for example
+ * a attribute value in octothorpe form of a Ldap DN string.
+ * Checks if the BER encoded value is legal for a DirectoryString.
+ *
+ * NOTE: currently only supports DER encoding for the BER encoded value.
+ *
+ * @param berStream Byte array of a BER encoded value.
+ *
+ * @return DerValue object.
+ *
+ * @exception IOException If the BER value cannot be converted to a
+ * valid Directory String DER value.
+ */
+ public DerValue getValue(byte[] berByteStream)
+ throws IOException {
+ DerValue value = new DerValue(berByteStream);
+
+ /*
+ if (value.tag != DerValue.tag_PrintableString &&
+ value.tag != DerValue.tag_T61String &&
+ value.tag != DerValue.tag_UniversalString)
+ throw new IOException("Invalid Directory String AVA Value");
+ */
+
+ return value;
+ }
+
+ /**
+ * Converts a DerValue to a string.
+ * The string is not in any syntax, such as RFC1779 string syntax.
+ *
+ * @param avaValue a DerValue
+ * @return a string if the value can be converted.
+ * @exception IOException if a decoder needed for the
+ * conversion is not available.
+ */
+ public String getAsString(DerValue avaValue)
+ throws IOException {
+ /*
+ if (avaValue.tag != DerValue.tag_PrintableString &&
+ avaValue.tag != DerValue.tag_BMPString &&
+ avaValue.tag != DerValue.tag_UniversalString &&
+ avaValue.tag != DerValue.tag_T61String)
+ throw new IllegalArgumentException(
+ "Invalid Directory String value");
+ // NOTE will return null if a decoder is not available.
+ */
+ return avaValue.getASN1CharString();
+ }
+
+}
diff --git a/base/util/src/netscape/security/x509/DisplayText.java b/base/util/src/netscape/security/x509/DisplayText.java
new file mode 100644
index 000000000..a379617a7
--- /dev/null
+++ b/base/util/src/netscape/security/x509/DisplayText.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 netscape.security.x509;
+
+import java.io.IOException;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * Represent the DisplayText.
+ *
+ * DisplayText ::= CHOICE {
+ * visibleString VisibleString (SIZE (1..200)),
+ * bmpString BMPString (SIZE (1..200)),
+ * utf8String UTF8String (SIZE (1..200)),
+ * }
+ *
+ * @author Thomas Kwan
+ */
+public class DisplayText {
+
+ /** Tag value indicating an ASN.1 "BMPString" value. */
+ public final static byte tag_IA5String = 0x16;
+ public final static byte tag_BMPString = 0x1E;
+ public final static byte tag_VisibleString = 0x1A;
+ public final static byte tag_UTF8String = 0x0C;
+
+ private byte mTag;
+ private String mS = null;
+
+ public DisplayText(byte tag, String s) {
+ mTag = tag;
+ mS = s;
+ }
+
+ public DisplayText(DerValue val) throws IOException {
+ mTag = val.tag;
+ mS = val.getAsString();
+ }
+
+ /**
+ * Write the DisplayText to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the object to.
+ * @exception IOException on errors.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ out.putStringType(mTag, mS);
+ }
+
+ public String getText() {
+ return mS;
+ }
+
+ public String toString() {
+ if (mTag == tag_IA5String) {
+ return "IA5String: " + mS;
+ } else if (mTag == tag_BMPString) {
+ return "BMPString: " + mS;
+ } else if (mTag == tag_VisibleString) {
+ return "VisibleString: " + mS;
+ } else {
+ return "UTF8String: " + mS;
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/x509/EDIPartyName.java b/base/util/src/netscape/security/x509/EDIPartyName.java
new file mode 100644
index 000000000..0c69242cc
--- /dev/null
+++ b/base/util/src/netscape/security/x509/EDIPartyName.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 netscape.security.x509;
+
+import java.io.IOException;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class defines the EDIPartyName of the GeneralName choice.
+ * The ASN.1 syntax for this is:
+ *
+ * <pre>
+ * EDIPartyName ::= SEQUENCE {
+ * nameAssigner [0] DirectoryString OPTIONAL,
+ * partyName [1] DirectoryString }
+ * </pre>
+ *
+ * @author Hemma Prafullchandra
+ * @version 1.2
+ * @see GeneralName
+ * @see GeneralNames
+ * @see GeneralNameInterface
+ */
+public class EDIPartyName implements GeneralNameInterface {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8669257424766789063L;
+ // Private data members
+ private static final byte TAG_ASSIGNER = 0;
+ private static final byte TAG_PARTYNAME = 1;
+
+ private String assigner = null;
+ private String party = null;
+
+ /**
+ * Create the EDIPartyName object from the specified names.
+ *
+ * @param assignerName the name of the assigner
+ * @param partyName the name of the EDI party.
+ */
+ public EDIPartyName(String assignerName, String partyName) {
+ this.assigner = assignerName;
+ this.party = partyName;
+ }
+
+ /**
+ * Create the EDIPartyName object from the specified name.
+ *
+ * @param partyName the name of the EDI party.
+ */
+ public EDIPartyName(String partyName) {
+ this.party = partyName;
+ }
+
+ /**
+ * Create the EDIPartyName object from the passed encoded Der value.
+ *
+ * @param derValue the encoded DER EDIPartyName.
+ * @exception IOException on error.
+ */
+ public EDIPartyName(DerValue derValue) throws IOException {
+ DerInputStream in = new DerInputStream(derValue.toByteArray());
+ DerValue[] seq = in.getSequence(2);
+
+ int len = seq.length;
+ if (len < 1 || len > 2)
+ throw new IOException("Invalid encoding of EDIPartyName");
+
+ for (int i = 0; i < len; i++) {
+ DerValue opt = seq[i];
+ if (opt.isContextSpecific((byte) TAG_ASSIGNER) &&
+ !opt.isConstructed()) {
+ if (assigner != null)
+ throw new IOException("Duplicate nameAssigner found in"
+ + " EDIPartyName");
+ opt = opt.data.getDerValue();
+ assigner = opt.getAsString();
+ }
+ if (opt.isContextSpecific((byte) TAG_PARTYNAME) &&
+ !opt.isConstructed()) {
+ if (party != null)
+ throw new IOException("Duplicate partyName found in"
+ + " EDIPartyName");
+ opt = opt.data.getDerValue();
+ party = opt.getAsString();
+ }
+ }
+ }
+
+ /**
+ * Return the type of the GeneralName.
+ */
+ public int getType() {
+ return (GeneralNameInterface.NAME_EDI);
+ }
+
+ /**
+ * Encode the EDI party name into the DerOutputStream.
+ *
+ * @param out the DER stream to encode the EDIPartyName to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ DerOutputStream tagged = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+
+ if (assigner != null) {
+ DerOutputStream tmp2 = new DerOutputStream();
+ // XXX - shd check is chars fit into PrintableString
+ tmp2.putPrintableString(assigner);
+ tagged.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ false, TAG_ASSIGNER), tmp2);
+ }
+ if (party == null)
+ throw new IOException("Cannot have null partyName");
+
+ // XXX - shd check is chars fit into PrintableString
+ tmp.putPrintableString(party);
+ tagged.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ false, TAG_PARTYNAME), tmp);
+
+ out.write(DerValue.tag_Sequence, tagged);
+ }
+
+ /**
+ * Return the printable string.
+ */
+ public String toString() {
+ return ("EDIPartyName: " +
+ ((assigner == null) ? "" :
+ (" nameAssigner = " + assigner + ","))
+ + " partyName = " + party);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/Extension.java b/base/util/src/netscape/security/x509/Extension.java
new file mode 100644
index 000000000..7dc9e2890
--- /dev/null
+++ b/base/util/src/netscape/security/x509/Extension.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * Represent a X509 Extension Attribute.
+ *
+ * <p>
+ * Extensions are addiitonal attributes which can be inserted in a X509 v3 certificate. For example a
+ * "Driving License Certificate" could have the driving license number as a extension.
+ *
+ * <p>
+ * Extensions are represented as a sequence of the extension identifier (Object Identifier), a boolean flag stating
+ * whether the extension is to be treated as being critical and the extension value itself (this is again a DER encoding
+ * of the extension value).
+ *
+ * <pre>
+ * ASN.1 definition of Extension:
+ * Extension ::= SEQUENCE {
+ * ExtensionId OBJECT IDENTIFIER,
+ * critical BOOLEAN DEFAULT FALSE,
+ * extensionValue OCTET STRING
+ * }
+ * </pre>
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.9
+ */
+public class Extension implements Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -643549610716024753L;
+ protected ObjectIdentifier extensionId = null;
+ protected boolean critical = false;
+ protected byte[] extensionValue = null;
+
+ /**
+ * Default constructor. Used only by sub-classes.
+ */
+ public Extension() {
+ }
+
+ /**
+ * Constructs an extension from a DER encoded array of bytes.
+ */
+ public Extension(DerValue derVal) throws IOException {
+
+ DerInputStream in = derVal.toDerInputStream();
+
+ // Object identifier
+ extensionId = in.getOID();
+
+ // If the criticality flag was false, it will not have been encoded.
+ DerValue val = in.getDerValue();
+ if (val.tag == DerValue.tag_Boolean) {
+ critical = val.getBoolean();
+
+ // Extension value (DER encoded)
+ val = in.getDerValue();
+ extensionValue = val.getOctetString();
+ } else {
+ critical = false;
+ extensionValue = val.getOctetString();
+ }
+ }
+
+ /**
+ * Constructs an Extension from individual components of ObjectIdentifier,
+ * criticality and the DER encoded OctetString.
+ *
+ * @param extensionId the ObjectIdentifier of the extension
+ * @param critical the boolean indicating if the extension is critical
+ * @param extensionValue the DER encoded octet string of the value.
+ */
+ public Extension(ObjectIdentifier extensionId, boolean critical,
+ byte[] extensionValue) throws IOException {
+ this.extensionId = extensionId;
+ this.critical = critical;
+ // passed in a DER encoded octet string, strip off the tag
+ // and length
+ DerValue inDerVal = new DerValue(extensionValue);
+ this.extensionValue = inDerVal.getOctetString();
+ }
+
+ /**
+ * Constructs an Extension from another extension. To be used for
+ * creating decoded subclasses.
+ *
+ * @param ext the extension to create from.
+ */
+ public Extension(Extension ext) {
+ this.extensionId = ext.extensionId;
+ this.critical = ext.critical;
+ this.extensionValue = ext.extensionValue;
+ }
+
+ /**
+ * Write the extension to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the extension to.
+ * @exception IOException on encoding errors
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ DerOutputStream bytes = new DerOutputStream();
+
+ if (extensionId == null)
+ throw new IOException("Null OID to encode for the extension!");
+
+ bytes.putOID(extensionId);
+ if (critical)
+ bytes.putBoolean(critical);
+ if (extensionValue != null)
+ bytes.putOctetString(extensionValue);
+
+ out.write(DerValue.tag_Sequence, bytes);
+ }
+
+ /**
+ * Returns true if extension is critical.
+ */
+ public boolean isCritical() {
+ return (critical);
+ }
+
+ public void setCritical(boolean c) {
+ critical = c;
+ }
+
+ public void clearValue() {
+ extensionValue = null;
+ }
+
+ /**
+ * Returns the ObjectIdentifier of the extension.
+ */
+ public ObjectIdentifier getExtensionId() {
+ return (extensionId);
+ }
+
+ public void setExtensionId(ObjectIdentifier oid) {
+ extensionId = oid;
+ }
+
+ /**
+ * Returns the extension value as an byte array for further processing.
+ * Note, this is the raw DER value of the extension, not the DER
+ * encoded octet string which is in the certificate.
+ */
+ public byte[] getExtensionValue() {
+ if (extensionValue == null)
+ return null;
+
+ byte[] dup = new byte[extensionValue.length];
+ System.arraycopy(extensionValue, 0, dup, 0, dup.length);
+ return dup;
+ }
+
+ public void setExtensionValue(byte value[]) {
+ extensionValue = value;
+ }
+
+ /**
+ * Returns the Extension in user readable form.
+ */
+ public String toString() {
+ String s = "ObjectId: " + extensionId.toString();
+ if (critical) {
+ s += " Criticality=true\n";
+ } else {
+ s += " Criticality=false\n";
+ }
+ return (s);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/Extensions.java b/base/util/src/netscape/security/x509/Extensions.java
new file mode 100644
index 000000000..622367ab6
--- /dev/null
+++ b/base/util/src/netscape/security/x509/Extensions.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class defines the Extensions attribute for the Certificate.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.11
+ * @see CertAttrSet
+ */
+public class Extensions extends Vector<Extension>
+ implements CertAttrSet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4597917347772057433L;
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT = "x509.info.extensions";
+ /**
+ * name
+ */
+ public static final String NAME = "extensions";
+
+ private Hashtable<String, Extension> map;
+
+ // Parse the encoded extension
+ public void parseExtension(Extension ext) throws IOException {
+ try {
+ @SuppressWarnings("unchecked")
+ Class<CertAttrSet> extClass = (Class<CertAttrSet>) OIDMap.getClass(ext.getExtensionId());
+ if (extClass == null) { // Unsupported extension
+ if (ext.isCritical()) {
+ throw new IOException("Unsupported CRITICAL extension: "
+ + ext.getExtensionId());
+ } else {
+ map.put(ext.getExtensionId().toString(), ext);
+ addElement(ext);
+ return;
+ }
+ }
+ Class<?>[] params = { Boolean.class, Object.class };
+ Constructor<CertAttrSet> cons = extClass.getConstructor(params);
+
+ byte[] extData = ext.getExtensionValue();
+ int extLen = extData.length;
+ Object value = Array.newInstance(byte.class, extLen);
+
+ for (int i = 0; i < extLen; i++) {
+ Array.setByte(value, i, extData[i]);
+ }
+ Object[] passed = new Object[] { new Boolean(ext.isCritical()),
+ value };
+ CertAttrSet certExt = cons.newInstance(passed);
+ map.put(certExt.getName(), (Extension) certExt);
+ addElement((Extension) certExt);
+
+ } catch (NoSuchMethodException nosuch) {
+ throw new IOException(nosuch.toString());
+ } catch (InvocationTargetException invk) {
+ throw new IOException(invk.getTargetException().toString());
+ } catch (Exception e) {
+ throw new IOException(e.toString());
+ }
+ }
+
+ /**
+ * Default constructor for the certificate attribute.
+ */
+ public Extensions() {
+ map = new Hashtable<String, Extension>();
+ }
+
+ /**
+ * Create the object, decoding the values from the passed DER stream.
+ *
+ * @param in the DerInputStream to read the Extension from.
+ * @exception IOException on decoding errors.
+ */
+ public Extensions(DerInputStream in)
+ throws IOException {
+
+ map = new Hashtable<String, Extension>();
+ DerValue[] exts = in.getSequence(5);
+
+ for (int i = 0; i < exts.length; i++) {
+ Extension ext = new Extension(exts[i]);
+ parseExtension(ext);
+ }
+ }
+
+ /**
+ * Decode the extensions from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ DerValue val = new DerValue(in);
+ DerInputStream str = val.toDerInputStream();
+
+ map = new Hashtable<String, Extension>();
+ DerValue[] exts = str.getSequence(5);
+
+ for (int i = 0; i < exts.length; i++) {
+ Extension ext = new Extension(exts[i]);
+ parseExtension(ext);
+ }
+ }
+
+ /**
+ * Encode the extensions in DER form to the stream.
+ *
+ * @param out the DerOutputStream to marshal the contents to.
+ * @exception CertificateException on encoding errors.
+ * @exception IOException on errors.
+ */
+ public void encode(OutputStream out)
+ throws CertificateException, IOException {
+ DerOutputStream extOut = new DerOutputStream();
+ for (int i = 0; i < size(); i++) {
+ Object thisOne = elementAt(i);
+ if (thisOne instanceof CertAttrSet)
+ ((CertAttrSet) thisOne).encode(extOut);
+ else if (thisOne instanceof Extension)
+ ((Extension) thisOne).encode(extOut);
+ else
+ throw new CertificateException("Invalid extension object");
+ }
+
+ DerOutputStream seq = new DerOutputStream();
+ seq.write(DerValue.tag_Sequence, extOut);
+
+ out.write(seq.toByteArray());
+ }
+
+ /**
+ * Set the attribute value.
+ *
+ * @param name the extension name used in the cache.
+ * @param obj the object to set.
+ * @exception IOException if the object could not be cached.
+ */
+ public void set(String name, Object obj) throws IOException {
+ map.put(name, (Extension) obj);
+ addElement((Extension) obj);
+ }
+
+ /**
+ * Get the attribute value.
+ *
+ * @param name the extension name used in the lookup.
+ * @exception IOException if named extension is not found.
+ */
+ public Object get(String name) throws IOException {
+ Object obj = map.get(name);
+ if (obj == null) {
+ throw new IOException("No extension found with name " + name);
+ }
+ return (obj);
+ }
+
+ /**
+ * Delete the attribute value.
+ *
+ * @param name the extension name used in the lookup.
+ * @exception IOException if named extension is not found.
+ */
+ public void delete(String name) throws IOException {
+ Object obj = map.get(name);
+ if (obj == null) {
+ throw new IOException("No extension found with name " + name);
+ }
+ map.remove(name);
+ removeElement(obj);
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ return map.keys();
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/FreshestCRLExtension.java b/base/util/src/netscape/security/x509/FreshestCRLExtension.java
new file mode 100644
index 000000000..c749ae04e
--- /dev/null
+++ b/base/util/src/netscape/security/x509/FreshestCRLExtension.java
@@ -0,0 +1,396 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.BufferedOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import netscape.security.util.BitArray;
+import netscape.security.util.DerOutputStream;
+
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.SEQUENCE;
+
+/**
+ * An extension that tells applications where to find
+ * the latest (freshest) delta CRL for this certificate
+ * or full CRL.
+ *
+ * <pre>
+ * cRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
+ *
+ * DistributionPoint ::= SEQUENCE {
+ * distributionPoint [0] DistributionPointName OPTIONAL,
+ * reasons [1] ReasonFlags OPTIONAL,
+ * cRLIssuer [2] GeneralNames OPTIONAL }
+ *
+ * DistributionPointName ::= CHOICE {
+ * fullName [0] GeneralNames,
+ * nameRelativeToCRLIssuer [1] RelativeDistinguishedName }
+ *
+ * ReasonFlags ::= BIT STRING {
+ * unused (0),
+ * keyCompromise (1),
+ * cACompromise (2),
+ * affiliationChanged (3),
+ * superseded (4),
+ * cessationOfOperation (5),
+ * certificateHold (6) }
+ * </pre>
+ */
+public class FreshestCRLExtension extends Extension
+ implements CertAttrSet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8040203589629281781L;
+
+ // vector of CRLDistributionPoint
+ private SEQUENCE distributionPoints = new SEQUENCE();
+
+ public FreshestCRLExtension() {
+ this.extensionId = PKIXExtensions.FreshestCRL_Id;
+ this.critical = false;
+ }
+
+ // Cached DER-encoding to improve performance.
+ private byte[] cachedEncoding = null;
+
+ // Attribute name
+ public static final String NAME = "FreshestCRL";
+
+ // The Object Identifier for this extension.
+ public static final String OID = "2.5.29.46";
+
+ static {
+ try {
+ OIDMap.addAttribute(FreshestCRLExtension.class.getName(),
+ OID, NAME);
+ } catch (CertificateException e) {
+ }
+ }
+
+ /**
+ * This constructor is called by the CertificateExtensions class to decode
+ * an extension whose OID indicates it is a CRLDistributionsPoints
+ * extension.
+ */
+ public FreshestCRLExtension(Boolean critical, Object value)
+ //throws IOException
+ {
+ try {
+ this.extensionId = PKIXExtensions.FreshestCRL_Id;
+ this.critical = critical.booleanValue();
+ this.extensionValue = (byte[]) ((byte[]) value).clone();
+
+ // decode the value
+ try {
+ SEQUENCE.OF_Template seqOfCRLDP =
+ new SEQUENCE.OF_Template(CRLDistributionPoint.getTemplate());
+
+ distributionPoints =
+ (SEQUENCE) ASN1Util.decode(seqOfCRLDP, extensionValue);
+ } catch (InvalidBERException e) {
+ throw new IOException("Invalid BER-encoding: " + e.toString());
+ }
+ } catch (IOException e) {
+ System.out.println("Big error");
+ System.out.println(e);
+ e.printStackTrace();
+ //throw e;
+ }
+ }
+
+ /**
+ * Creates a new FreshestCRL extension, with the given
+ * distribution point as the first element.
+ */
+ public FreshestCRLExtension(CRLDistributionPoint dp) {
+ this.extensionId = PKIXExtensions.FreshestCRL_Id;
+ this.critical = false;
+ distributionPoints.addElement(dp);
+ }
+
+ /**
+ * Adds an additional distribution point to the end of the sequence.
+ */
+ public void addPoint(CRLDistributionPoint dp) {
+ distributionPoints.addElement(dp);
+ cachedEncoding = null;
+ }
+
+ /**
+ * Returns the number of distribution points in the sequence.
+ */
+ public int getNumPoints() {
+ return distributionPoints.size();
+ }
+
+ /**
+ * Returns the DistributionPoint at the given index in the sequence.
+ */
+ public CRLDistributionPoint getPointAt(int index) {
+ return (CRLDistributionPoint) distributionPoints.elementAt(index);
+ }
+
+ /**
+ * Sets the criticality of this extension. PKIX dictates that this
+ * extension SHOULD NOT be critical, so applications can make it critical
+ * if they have a very good reason. By default, the extension is not
+ * critical.
+ */
+ public void setCritical(boolean critical) {
+ this.critical = critical;
+ }
+
+ /**
+ * Encodes this extension to the given DerOutputStream.
+ * This method re-encodes each time it is called, so it is not very
+ * efficient.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ extensionValue = ASN1Util.encode(distributionPoints);
+ super.encode(out);
+ }
+
+ /**
+ * Should be called if any change is made to this data structure
+ * so that the cached DER encoding can be discarded.
+ */
+ public void flushCachedEncoding() {
+ cachedEncoding = null;
+ }
+
+ /////////////////////////////////////////////////////////////
+ // CertAttrSet interface
+ // This interface is not really appropriate for this extension
+ // because it is so complicated. Therefore, we only provide a
+ // minimal implementation.
+ /////////////////////////////////////////////////////////////
+ public String toString() {
+ return NAME;
+ }
+
+ /**
+ * DER-encodes this extension to the given OutputStream.
+ */
+ public void encode(OutputStream ostream)
+ throws CertificateException, IOException {
+ if (cachedEncoding == null) {
+ // only re-encode if necessary
+ DerOutputStream tmp = new DerOutputStream();
+ encode(tmp);
+ cachedEncoding = tmp.toByteArray();
+ }
+ ostream.write(cachedEncoding);
+ }
+
+ public void decode(InputStream in)
+ throws CertificateException, IOException {
+ throw new IOException("Not supported");
+ }
+
+ public void set(String name, Object obj)
+ throws CertificateException, IOException {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:FreshestCRLExtension");
+ }
+
+ public Object get(String name)
+ throws CertificateException, IOException {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:FreshestCRLExtension");
+ }
+
+ public void delete(String name)
+ throws CertificateException, IOException {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:FreshestCRLExtension");
+ }
+
+ /*
+ * TODO replacewith empty collection
+ */
+ public Enumeration<String> getAttributeNames() {
+ return (new Vector<String>()).elements();
+ }
+
+ public String getName() {
+ return NAME;
+ }
+
+ /**
+ * Test driver.
+ */
+ public static void main(String args[]) {
+
+ try {
+
+ if (args.length != 1) {
+ System.out.println("Usage: FreshestCRLExtentions " +
+ "<outfile>");
+ System.exit(-1);
+ }
+
+ BufferedOutputStream bos = new BufferedOutputStream(
+ new FileOutputStream(args[0]));
+
+ // URI only
+ CRLDistributionPoint cdp = new CRLDistributionPoint();
+ URIName uri = new URIName("http://www.mycrl.com/go/here");
+ GeneralNames generalNames = new GeneralNames();
+ generalNames.addElement(uri);
+ cdp.setFullName(generalNames);
+ FreshestCRLExtension crldpExt =
+ new FreshestCRLExtension(cdp);
+
+ // DN only
+ cdp = new CRLDistributionPoint();
+ X500Name dn = new X500Name("CN=Otis Smith,E=otis@fedoraproject.org" +
+ ",OU=Certificate Server,O=Fedora,C=US");
+ generalNames = new GeneralNames();
+ generalNames.addElement(dn);
+ cdp.setFullName(generalNames);
+ crldpExt.addPoint(cdp);
+
+ // DN + reason
+ BitArray ba = new BitArray(5, new byte[] { (byte) 0x28 });
+ cdp = new CRLDistributionPoint();
+ cdp.setFullName(generalNames);
+ cdp.setReasons(ba);
+ crldpExt.addPoint(cdp);
+
+ // relative DN + reason + crlIssuer
+ cdp = new CRLDistributionPoint();
+ RDN rdn = new RDN("OU=foobar dept");
+ cdp.setRelativeName(rdn);
+ cdp.setReasons(ba);
+ cdp.setCRLIssuer(generalNames);
+ crldpExt.addPoint(cdp);
+
+ crldpExt.setCritical(true);
+ crldpExt.encode(bos);
+
+ bos.close();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Represents a reason that a cert may be revoked. These reasons are
+ * expressed in a ReasonFlags bit string.
+ */
+ public static class Reason {
+
+ private String name;
+ private byte bitMask;
+
+ private Reason() {
+ }
+
+ private Reason(String name, byte bitMask) {
+ this.name = name;
+ this.bitMask = bitMask;
+ map.put(name, this);
+ list.addElement(this);
+ }
+
+ private static Hashtable<String, Reason> map = new Hashtable<String, Reason>();
+ private static Vector<Reason> list = new Vector<Reason>();
+
+ public static Reason fromString(String name) {
+ return map.get(name);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public byte getBitMask() {
+ return bitMask;
+ }
+
+ /**
+ * Given a bit array representing reason flags, extracts the reasons
+ * and returns them as an array.
+ *
+ * @param bitFlags A bit vector containing reason flags.
+ * @return An array of reasons contained in the bit vector.
+ * May be zero-length but will not be null.
+ */
+ public static Reason[] bitArrayToReasonArray(byte bitFlags) {
+ return bitArrayToReasonArray(new byte[] { bitFlags });
+ }
+
+ /**
+ * Given a bit array representing reason flags, extracts the reasons
+ * and returns them as an array. Currently, only the first byte
+ * of the bitflags are examined.
+ *
+ * @param bitFlags A bit vector containing reason flags. The format
+ * is big-endian (MSB first). Only the first byte is examined.
+ * @return An array of reasons contained in the bit vector.
+ * May be zero-length but will not be null.
+ */
+ public static Reason[] bitArrayToReasonArray(byte[] bitFlags) {
+ byte first = bitFlags[0];
+ int size = list.size();
+ Vector<Reason> result = new Vector<Reason>();
+ for (int i = 0; i < size; i++) {
+ Reason r = (Reason) list.elementAt(i);
+ byte b = r.getBitMask();
+ if ((first & b) != 0) {
+ result.addElement(r);
+ }
+ }
+ size = result.size();
+ Reason[] retval = new Reason[size];
+ for (int i = 0; i < size; i++) {
+ retval[i] = result.elementAt(i);
+ }
+ return retval;
+ }
+
+ public static final Reason UNUSED =
+ new Reason("unused", (byte) 0x80);
+ public static final Reason KEY_COMPROMISE =
+ new Reason("keyCompromise", (byte) 0x40);
+ public static final Reason CA_COMPROMISE =
+ new Reason("cACompromise", (byte) 0x20);
+ public static final Reason AFFILIATION_CHANGED =
+ new Reason("affiliationChanged", (byte) 0x10);
+ public static final Reason SUPERSEDED =
+ new Reason("superseded", (byte) 0x08);
+ public static final Reason CESSATION_OF_OPERATION =
+ new Reason("cessationOfOperation", (byte) 0x04);
+ public static final Reason CERTIFICATE_HOLD =
+ new Reason("certificateHold", (byte) 0x02);
+ }
+
+}
diff --git a/base/util/src/netscape/security/x509/GeneralName.java b/base/util/src/netscape/security/x509/GeneralName.java
new file mode 100644
index 000000000..5ed98d830
--- /dev/null
+++ b/base/util/src/netscape/security/x509/GeneralName.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 netscape.security.x509;
+
+import java.io.IOException;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class implements the ASN.1 GeneralName object class.
+ * <p>
+ * The ASN.1 syntax for this is:
+ *
+ * <pre>
+ * GeneralName ::= CHOICE {
+ * otherName [0] OtherName,
+ * rfc822Name [1] IA5String,
+ * dNSName [2] IA5String,
+ * x400Address [3] ORAddress,
+ * directoryName [4] Name,
+ * ediPartyName [5] EDIPartyName,
+ * uniformResourceIdentifier [6] IA5String,
+ * iPAddress [7] OCTET STRING,
+ * registeredID [8] OBJECT IDENTIFIER
+ * }
+ * </pre>
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.7
+ */
+public class GeneralName implements GeneralNameInterface {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2244101501095555042L;
+ // Private data members
+ private GeneralNameInterface name = null;
+
+ /**
+ * Default constructor for the class.
+ *
+ * @param name the selected CHOICE from the list.
+ */
+ public GeneralName(GeneralNameInterface name) {
+ this.name = name;
+ }
+
+ /**
+ * Create the object from its DER encoded value.
+ *
+ * @param encName the DER encoded GeneralName.
+ */
+ public GeneralName(DerValue encName) throws IOException {
+ short tag = (byte) (encName.tag & 0x1f);
+
+ // NB. this is always encoded with the IMPLICIT tag
+ // The checks only make sense if we assume implicit tagging,
+ // with explicit tagging the form is always constructed.
+ switch (tag) {
+ case GeneralNameInterface.NAME_RFC822:
+ if (encName.isContextSpecific() && !encName.isConstructed()) {
+ encName.resetTag(DerValue.tag_IA5String);
+ name = new RFC822Name(encName);
+ } else
+ throw new IOException("Invalid encoding of RFC822 name");
+ break;
+
+ case GeneralNameInterface.NAME_DNS:
+ if (encName.isContextSpecific() && !encName.isConstructed()) {
+ encName.resetTag(DerValue.tag_IA5String);
+ name = new DNSName(encName);
+ } else
+ throw new IOException("Invalid encoding of DNS name");
+ break;
+
+ case GeneralNameInterface.NAME_URI:
+ if (encName.isContextSpecific() && !encName.isConstructed()) {
+ encName.resetTag(DerValue.tag_IA5String);
+ name = new URIName(encName);
+ } else
+ throw new IOException("Invalid encoding of URI");
+ break;
+
+ case GeneralNameInterface.NAME_IP:
+ if (encName.isContextSpecific() && !encName.isConstructed()) {
+ encName.resetTag(DerValue.tag_OctetString);
+ name = new IPAddressName(encName);
+ } else
+ throw new IOException("Invalid encoding of IP address");
+ break;
+
+ case GeneralNameInterface.NAME_ANY:
+ if (encName.isContextSpecific() && encName.isConstructed()) {
+ encName.resetTag(DerValue.tag_OctetString);
+ name = new OtherName(encName);
+ } else
+ throw new IOException("Invalid encoding of other name");
+ break;
+
+ case GeneralNameInterface.NAME_OID:
+ if (encName.isContextSpecific() && !encName.isConstructed()) {
+ encName.resetTag(DerValue.tag_ObjectId);
+ name = new OIDName(encName);
+ } else
+ throw new IOException("Invalid encoding of OID name");
+ break;
+
+ case GeneralNameInterface.NAME_DIRECTORY:
+ if (encName.isContextSpecific() && encName.isConstructed()) {
+ // Unlike the other cases, DirectoryName is EXPLICITly
+ // tagged, because the X.500 Name type is a CHOICE.
+ // Therefore, the sequence is actually nested in the
+ // content of this value. We'll pretend it's an octet
+ // string so we can get at the content bytes.
+ encName.resetTag(DerValue.tag_OctetString);
+ byte[] content = encName.getOctetString();
+ name = new X500Name(content);
+ } else
+ throw new IOException("Invalid encoding of Directory name");
+ break;
+
+ case GeneralNameInterface.NAME_EDI:
+ if (encName.isContextSpecific() && encName.isConstructed()) {
+ encName.resetTag(DerValue.tag_Sequence);
+ name = new EDIPartyName(encName);
+ } else
+ throw new IOException("Invalid encoding of EDI name");
+ break;
+
+ default:
+ throw new IOException("Unrecognized GeneralName tag, ("
+ + tag + ")");
+ }
+ }
+
+ /**
+ * Return the type of the general name.
+ */
+ public int getType() {
+ return (name.getType());
+ }
+
+ /**
+ * Return the name as user readable string
+ */
+ public String toString() {
+ return (name.toString());
+ }
+
+ /**
+ * Encode the name to the specified DerOutputStream.
+ *
+ * @param out the DerOutputStream to encode the the GeneralName to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ name.encode(tmp);
+ int nameType = name.getType();
+ boolean constructedForm;
+
+ if (nameType == GeneralNameInterface.NAME_ANY ||
+ nameType == GeneralNameInterface.NAME_X400 ||
+ nameType == GeneralNameInterface.NAME_DIRECTORY ||
+ nameType == GeneralNameInterface.NAME_EDI) {
+ constructedForm = true;
+ } else {
+ constructedForm = false;
+ }
+
+ if (nameType == GeneralNameInterface.NAME_DIRECTORY) {
+ // EXPLICIT tag, because Name is a CHOICE type
+ out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ constructedForm, (byte) nameType), tmp);
+ } else {
+ // IMPLICIT tag, the default
+ out.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
+ constructedForm, (byte) nameType), tmp);
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/x509/GeneralNameInterface.java b/base/util/src/netscape/security/x509/GeneralNameInterface.java
new file mode 100644
index 000000000..4a9673663
--- /dev/null
+++ b/base/util/src/netscape/security/x509/GeneralNameInterface.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 netscape.security.x509;
+
+import java.io.IOException;
+
+import netscape.security.util.DerOutputStream;
+
+/**
+ * This interface specifies the abstract methods which have to be
+ * implemented by all the members of the GeneralNames ASN.1 object.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.6
+ */
+public interface GeneralNameInterface extends java.io.Serializable {
+ /**
+ * The list of names supported.
+ */
+ public static final int NAME_ANY = 0;
+ public static final int NAME_RFC822 = 1;
+ public static final int NAME_DNS = 2;
+ public static final int NAME_X400 = 3;
+ public static final int NAME_DIRECTORY = 4;
+ public static final int NAME_EDI = 5;
+ public static final int NAME_URI = 6;
+ public static final int NAME_IP = 7;
+ public static final int NAME_OID = 8;
+
+ /**
+ * Return the type of the general name, as
+ * defined above.
+ */
+ int getType();
+
+ /**
+ * Encode the name to the specified DerOutputStream.
+ *
+ * @param out the DerOutputStream to encode the GeneralName to.
+ * @exception IOException thrown if the GeneralName could not be
+ * encoded.
+ */
+ void encode(DerOutputStream out) throws IOException;
+}
diff --git a/base/util/src/netscape/security/x509/GeneralNames.java b/base/util/src/netscape/security/x509/GeneralNames.java
new file mode 100644
index 000000000..9e06db5ac
--- /dev/null
+++ b/base/util/src/netscape/security/x509/GeneralNames.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This object class represents the GeneralNames type required in
+ * X509 certificates.
+ * <p>
+ * The ASN.1 syntax for this is:
+ *
+ * <pre>
+ * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+ * </pre>
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.7
+ */
+public class GeneralNames extends Vector<GeneralNameInterface> {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3204492869396713312L;
+
+ /**
+ * Create the GeneralNames, decoding from the passed DerValue.
+ *
+ * <b>Caution when using this constructor. It may be broken!
+ * Better to call addElement(gni) directly where gni is
+ * a GeneralNameInterface object </b>
+ *
+ * @param derVal the DerValue to construct the GeneralNames from.
+ * @exception GeneralNamesException on decoding error.
+ * @exception IOException on error.
+ */
+ public GeneralNames(DerValue derVal)
+ throws IOException, GeneralNamesException {
+ if (derVal.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding for GeneralNames.");
+ }
+ if (derVal.data.available() == 0) {
+ throw new GeneralNamesException("No data available in "
+ + "passed DER encoded value.");
+ }
+ // Decode all the GeneralName's
+ while (derVal.data.available() != 0) {
+ DerValue encName = derVal.data.getDerValue();
+
+ GeneralName name = new GeneralName(encName);
+ addElement(name);
+ }
+ }
+
+ /**
+ * Create the GeneralNames
+ *
+ * @param names a non-empty array of names to put into the
+ * generalNames
+ */
+
+ public GeneralNames(GeneralNameInterface[] names)
+ throws GeneralNamesException {
+ if (names == null || names.length == 0)
+ throw new GeneralNamesException("Cannot create empty GeneralNames");
+
+ for (int i = 0; i < names.length; i++) {
+ addElement(names[i]);
+ }
+ }
+
+ /**
+ * The default constructor for this class.
+ */
+ public GeneralNames() {
+ super(1, 1);
+ }
+
+ /**
+ * Write the extension to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the extension to.
+ * @exception GeneralNamesException on encoding error.
+ * @exception IOException on error.
+ */
+ public void encode(DerOutputStream out)
+ throws IOException, GeneralNamesException {
+ if (size() == 0) {
+ return;
+ }
+
+ Enumeration<GeneralNameInterface> names = elements();
+ DerOutputStream temp = new DerOutputStream();
+
+ while (names.hasMoreElements()) {
+ Object obj = names.nextElement();
+ if (!(obj instanceof GeneralNameInterface)) {
+ throw new GeneralNamesException("Element in GeneralNames "
+ + "not of type GeneralName.");
+ }
+ GeneralNameInterface intf = (GeneralNameInterface) obj;
+ if (obj instanceof GeneralName) {
+ intf.encode(temp);
+ } else {
+ DerOutputStream gname = new DerOutputStream();
+ intf.encode(gname);
+ int nameType = intf.getType();
+ // constructed form
+ if (nameType == GeneralNameInterface.NAME_ANY ||
+ nameType == GeneralNameInterface.NAME_X400 ||
+ nameType == GeneralNameInterface.NAME_EDI) {
+
+ temp.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
+ true, (byte) nameType), gname);
+ } else if (nameType == GeneralNameInterface.NAME_DIRECTORY) {
+ // EXPLICIT tag because directoryName is a CHOICE
+ temp.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ true, (byte) nameType), gname);
+ } else
+ // primitive form
+ temp.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
+ false, (byte) nameType), gname);
+ }
+
+ }
+
+ out.write(DerValue.tag_Sequence, temp);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/GeneralNamesException.java b/base/util/src/netscape/security/x509/GeneralNamesException.java
new file mode 100644
index 000000000..6309ed114
--- /dev/null
+++ b/base/util/src/netscape/security/x509/GeneralNamesException.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 netscape.security.x509;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * Generic General Names Exception.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.4
+ */
+public class GeneralNamesException extends GeneralSecurityException {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8320001725384815795L;
+
+ /**
+ * Constructs a GeneralNamesException with no detail message.
+ */
+ public GeneralNamesException() {
+ super();
+ }
+
+ /**
+ * Constructs the exception with the specified error message.
+ *
+ * @param message the requisite error message.
+ */
+ public GeneralNamesException(String message) {
+ super(message);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/GeneralSubtree.java b/base/util/src/netscape/security/x509/GeneralSubtree.java
new file mode 100644
index 000000000..635427e0b
--- /dev/null
+++ b/base/util/src/netscape/security/x509/GeneralSubtree.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 netscape.security.x509;
+
+import java.io.IOException;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.PrettyPrintFormat;
+
+/**
+ * Represent the GeneralSubtree ASN.1 object, whose syntax is:
+ *
+ * <pre>
+ * GeneralSubtree ::= SEQUENCE {
+ * base GeneralName,
+ * minimum [0] BaseDistance DEFAULT 0,
+ * maximum [1] BaseDistance OPTIONAL
+ * }
+ * BaseDistance ::= INTEGER (0..MAX)
+ * </pre>
+ *
+ * @version 1.5
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ */
+public class GeneralSubtree {
+ private static final byte TAG_MIN = 0;
+ private static final byte TAG_MAX = 1;
+ private static final int MIN_DEFAULT = 0;
+
+ private GeneralName name;
+ private int minimum = MIN_DEFAULT;
+ private int maximum = -1;
+
+ private PrettyPrintFormat pp = new PrettyPrintFormat(":");
+
+ /**
+ * The default constructor for the class.
+ *
+ * @param name the GeneralName
+ * @param min the minimum BaseDistance
+ * @param max the maximum BaseDistance
+ */
+ public GeneralSubtree(GeneralName name, int min, int max) {
+ this.name = name;
+ this.minimum = min;
+ this.maximum = max;
+ }
+
+ /**
+ * Create the object from its DER encoded form.
+ *
+ * @param val the DER encoded from of the same.
+ */
+ public GeneralSubtree(DerValue val) throws IOException {
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding for GeneralSubtree.");
+ }
+ name = new GeneralName(val.data.getDerValue());
+
+ // NB. this is always encoded with the IMPLICIT tag
+ // The checks only make sense if we assume implicit tagging,
+ // with explicit tagging the form is always constructed.
+ while (val.data.available() != 0) {
+ DerValue opt = val.data.getDerValue();
+
+ if (opt.isContextSpecific(TAG_MIN) && !opt.isConstructed()) {
+ opt.resetTag(DerValue.tag_Integer);
+ minimum = (opt.getInteger()).toInt();
+
+ } else if (opt.isContextSpecific(TAG_MAX) && !opt.isConstructed()) {
+ opt.resetTag(DerValue.tag_Integer);
+ maximum = (opt.getInteger()).toInt();
+ } else
+ throw new IOException("Invalid encoding of GeneralSubtree.");
+ }
+ }
+
+ /**
+ * Return a printable string of the GeneralSubtree.
+ */
+ public String toString() {
+ String s = "\n GeneralSubtree: [\n" +
+ " GeneralName: " + ((name == null) ? "" : name.toString()) +
+ "\n Minimum: " + minimum;
+ if (maximum == -1) {
+ s += "\t Maximum: undefined";
+ } else
+ s += "\t Maximum: " + maximum;
+ s += " ]\n";
+ return (s);
+ }
+
+ public String toPrint(int indent) {
+ String s = "\n" + pp.indent(indent) + "GeneralSubtree: [\n" + pp.indent(indent + 2) +
+ "GeneralName: " + ((name == null) ? "" : name.toString()) +
+ "\n" + pp.indent(indent + 2) + "Minimum: " + minimum;
+ if (maximum == -1) {
+ s += "\n" + pp.indent(indent + 2) + "Maximum: undefined";
+ } else
+ s += "\n" + pp.indent(indent + 2) + "Maximum: " + maximum;
+ s += "]\n";
+ return (s);
+ }
+
+ /**
+ * Encode the GeneralSubtree.
+ *
+ * @param out the DerOutputStream to encode this object to.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ DerOutputStream seq = new DerOutputStream();
+
+ name.encode(seq);
+
+ if (minimum != MIN_DEFAULT) {
+ DerOutputStream tmp = new DerOutputStream();
+ tmp.putInteger(new BigInt(minimum));
+ seq.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
+ false, TAG_MIN), tmp);
+ }
+ if (maximum != -1) {
+ DerOutputStream tmp = new DerOutputStream();
+ tmp.putInteger(new BigInt(maximum));
+ seq.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
+ false, TAG_MAX), tmp);
+ }
+ out.write(DerValue.tag_Sequence, seq);
+ }
+
+ public GeneralName getGeneralName() {
+ return name;
+ }
+
+ public int getMaxValue() {
+ return maximum;
+ }
+
+ public int getMinValue() {
+ return minimum;
+ }
+}
diff --git a/base/util/src/netscape/security/x509/GeneralSubtrees.java b/base/util/src/netscape/security/x509/GeneralSubtrees.java
new file mode 100644
index 000000000..37097ca71
--- /dev/null
+++ b/base/util/src/netscape/security/x509/GeneralSubtrees.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.PrettyPrintFormat;
+
+/**
+ * Represent the GeneralSubtrees ASN.1 object.
+ *
+ * @version 1.4
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ */
+public class GeneralSubtrees {
+ private Vector<GeneralSubtree> trees;
+ private PrettyPrintFormat pp = new PrettyPrintFormat(":");
+
+ /**
+ * The default constructor for the class.
+ *
+ * @param trees the sequence of GeneralSubtree.
+ */
+ public GeneralSubtrees(Vector<GeneralSubtree> trees) {
+ this.trees = trees;
+ }
+
+ /**
+ * Create the object from the passed DER encoded form.
+ *
+ * @param val the DER encoded form of the same.
+ */
+ public GeneralSubtrees(DerValue val) throws IOException {
+ trees = new Vector<GeneralSubtree>(1, 1);
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding of GeneralSubtrees.");
+ }
+ while (val.data.available() != 0) {
+ DerValue opt = val.data.getDerValue();
+ GeneralSubtree tree = new GeneralSubtree(opt);
+ trees.addElement(tree);
+ }
+ }
+
+ /**
+ * Return a printable string of the GeneralSubtree.
+ */
+ public String toString() {
+ String s = " GeneralSubtrees:\n" + trees.toString()
+ + "\n";
+
+ return (s);
+ }
+
+ public String toPrint(int indent) {
+
+ String s = "";
+ GeneralSubtree element;
+
+ for (Enumeration<GeneralSubtree> e = trees.elements(); e.hasMoreElements();) {
+ element = (GeneralSubtree) e.nextElement();
+ s = s + pp.indent(indent + 4) + element.toPrint(indent) + "\n";
+ }
+
+ return (s);
+ }
+
+ /**
+ * Encode the GeneralSubtrees.
+ *
+ * @param out the DerOutputStrean to encode this object to.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ DerOutputStream seq = new DerOutputStream();
+
+ for (int i = 0; i < trees.size(); i++) {
+ ((GeneralSubtree) trees.elementAt(i)).encode(seq);
+ }
+ out.write(DerValue.tag_Sequence, seq);
+ }
+
+ public Vector<GeneralSubtree> getSubtrees() {
+ return trees;
+ }
+}
diff --git a/base/util/src/netscape/security/x509/GenericValueConverter.java b/base/util/src/netscape/security/x509/GenericValueConverter.java
new file mode 100644
index 000000000..73bc1979c
--- /dev/null
+++ b/base/util/src/netscape/security/x509/GenericValueConverter.java
@@ -0,0 +1,143 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetEncoder;
+
+import netscape.security.util.ASN1CharStrConvMap;
+import netscape.security.util.DerValue;
+
+/**
+ * A GenericValueConverter converts a string that is not associated with
+ * a particular attribute to a DER encoded ASN.1 character string type.
+ * Currently supports PrintableString, IA5String, BMPString T.61String and
+ * Universal String.
+ *
+ * <p>
+ * The conversion is done as follows. An encoder is obtained for the all the character sets from the global default
+ * ASN1CharStrConvMap. The encoders are then used to convert the string to the smallest character set first --
+ * printableString. If the string contains characters outside of that character set, it is converted to the next
+ * character set -- IA5String character set. If that is not enough it is converted to a BMPString, then Universal String
+ * which contains all characters.
+ *
+ * @author Lily Hsiao, Slava Galperin at Netscape Communications, Inc.
+ *
+ */
+
+public class GenericValueConverter implements AVAValueConverter {
+ public GenericValueConverter() {
+ }
+
+ /**
+ * Converts a string to a DER encoded ASN.1 primtable string, defined here
+ * as a PrintableString, IA5String, T.61String, BMPString or
+ * UniversalString. The string is not expected to be encoded in any form.
+ *
+ * <p>
+ * If an encoder is not available for a character set that is needed to convert the string, the string cannot be
+ * converted and an IOException is thrown. For example, if the string contains characters outside the
+ * PrintableString character and only a PrintableString encoder is available then an IOException is thrown.
+ *
+ * @param s A string representing a generic attribute string value.
+ *
+ * @return The DER value of the attribute.
+ *
+ * @exception IOException if the string cannot be converted, such as
+ * when an encoder needed is
+ * unavailable.
+ */
+ public DerValue getValue(String s)
+ throws IOException {
+ return getValue(s, null);
+ }
+
+ public DerValue getValue(String valueString, byte[] tags) throws IOException {
+ // try to convert to printable, then t61 the universal -
+ // i.e. from minimal coverage to the broadest.
+
+ if (tags == null || tags.length == 0)
+ tags = DefEncodingTags;
+
+ for (int i = 0; i < tags.length; i++) {
+ try {
+ CharsetEncoder encoder = ASN1CharStrConvMap.getDefault().getEncoder(tags[i]);
+ if (encoder == null)
+ continue;
+
+ CharBuffer charBuffer = CharBuffer.wrap(valueString.toCharArray());
+ ByteBuffer byteBuffer = encoder.encode(charBuffer);
+
+ return new DerValue(tags[i], byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.limit());
+
+ } catch (CharacterCodingException e) {
+ continue;
+ }
+ }
+
+ throw new IOException(
+ "Cannot convert the string value to a ASN.1 type");
+ }
+
+ /**
+ * Creates a DerValue from the byte array of BER encoded value.
+ *
+ * NOTE: currently only supports DER encoding (a form of BER) on input .
+ *
+ * @param berStream Byte array of a BER encoded value.
+ *
+ * @return DerValue object.
+ *
+ * @exception IOException If the BER value cannot be converted to a
+ * valid Directory String DER value.
+ */
+ public DerValue getValue(byte[] berByteStream)
+ throws IOException {
+ // accepts any tag.
+ DerValue value = new DerValue(berByteStream);
+ return value;
+ }
+
+ /**
+ * Converts a DerValue of ASN1 Character string type to a java string
+ * (the string is not encoded in any form).
+ *
+ * @param avaValue A DerValue
+ * @return A string representing the attribute value.
+ * @exception IOException if a decoder needed for the
+ * conversion is not available or if BER value
+ * is not one of the ASN1 character string types
+ * here.
+ */
+ public String getAsString(DerValue avaValue)
+ throws IOException {
+ return avaValue.getASN1CharString();
+ }
+
+ private static byte DefEncodingTags[] = {
+ DerValue.tag_PrintableString,
+ DerValue.tag_IA5String,
+ DerValue.tag_BMPString,
+ DerValue.tag_UTF8String,
+ DerValue.tag_T61String,
+ DerValue.tag_UniversalString
+ };
+}
diff --git a/base/util/src/netscape/security/x509/HoldInstructionExtension.java b/base/util/src/netscape/security/x509/HoldInstructionExtension.java
new file mode 100644
index 000000000..b42bb6ac9
--- /dev/null
+++ b/base/util/src/netscape/security/x509/HoldInstructionExtension.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * Represent the CRL Hold Instruction Code Extension.
+ *
+ * <p>
+ * 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.
+ *
+ * @see Extension
+ * @see CertAttrSet
+ */
+
+public class HoldInstructionExtension extends Extension
+ implements CertAttrSet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6706557233070964984L;
+ /**
+ * Attribute name.
+ */
+ public static final String NAME = "HoldInstruction";
+ public static final String HOLD_INSTRUCTION = "value";
+
+ /**
+ * The Object Identifier for this extension.
+ */
+ public static final String OID = "2.5.29.23";
+
+ public static final String NONE_HOLD_INSTR_OID_STR =
+ "1.2.840.10040.2.1";
+ public static final ObjectIdentifier NONE_HOLD_INSTR_OID =
+ new ObjectIdentifier(NONE_HOLD_INSTR_OID_STR);
+
+ public static final String CALL_ISSUER_HOLD_INSTR_OID_STR =
+ "1.2.840.10040.2.2";
+ public static final ObjectIdentifier CALL_ISSUER_HOLD_INSTR_OID =
+ new ObjectIdentifier(CALL_ISSUER_HOLD_INSTR_OID_STR);
+
+ public static final String REJECT_HOLD_INSTR_OID_STR =
+ "1.2.840.10040.2.3";
+ public static final ObjectIdentifier REJECT_HOLD_INSTR_OID =
+ new ObjectIdentifier(REJECT_HOLD_INSTR_OID_STR);
+
+ private ObjectIdentifier holdInstructionCodeOIDs[] = { NONE_HOLD_INSTR_OID,
+ CALL_ISSUER_HOLD_INSTR_OID,
+ REJECT_HOLD_INSTR_OID };
+ private ObjectIdentifier holdInstructionCodeOID = null;
+
+ private String holdInstructionDescription[] = { "None",
+ "Call Issuer",
+ "Reject" };
+
+ static {
+ try {
+ OIDMap.addAttribute(HoldInstructionExtension.class.getName(),
+ OID, NAME);
+ } catch (CertificateException e) {
+ }
+ }
+
+ private int getHoldInstructionCodeFromOID(ObjectIdentifier oid) {
+ for (int i = 0; i < holdInstructionCodeOIDs.length; i++) {
+ if (oid.equals(holdInstructionCodeOIDs[i]))
+ return (i + 1);
+ }
+ return 0;
+ }
+
+ private String getHoldInstructionDescription(ObjectIdentifier oid) {
+ String description = "Invalid";
+ if (oid != null) {
+ int i = getHoldInstructionCodeFromOID(oid);
+ if (i > 0 && i < 4)
+ description = holdInstructionDescription[i - 1];
+ }
+ return (description);
+ }
+
+ // Encode this extension value
+ private void encodeThis() throws IOException {
+ if (holdInstructionCodeOID == null)
+ throw new IOException("Unintialized hold instruction extension");
+ DerOutputStream os = new DerOutputStream();
+ os.putOID(holdInstructionCodeOID);
+ this.extensionValue = os.toByteArray();
+ }
+
+ /**
+ * Create a HoldInstructionExtension with the date.
+ * The criticality is set to false.
+ *
+ * @param code the value to be set for the extension.
+ */
+ public HoldInstructionExtension(int code)
+ throws IOException {
+ if (code < 1 || code > 3)
+ throw new IOException("Invalid hold instruction code");
+ holdInstructionCodeOID = holdInstructionCodeOIDs[code - 1];
+ this.extensionId = PKIXExtensions.HoldInstructionCode_Id;
+ this.critical = false;
+ encodeThis();
+ }
+
+ /**
+ * Create a HoldInstructionExtension with the date.
+ * The criticality is set to false.
+ *
+ * @param oidStr the value to be set for the extension.
+ */
+ public HoldInstructionExtension(String oidStr)
+ throws IOException {
+ ObjectIdentifier oid = new ObjectIdentifier(oidStr);
+ if (oid == null || getHoldInstructionCodeFromOID(oid) == 0)
+ throw new IOException("Invalid hold instruction code");
+ holdInstructionCodeOID = oid;
+ this.extensionId = PKIXExtensions.HoldInstructionCode_Id;
+ this.critical = false;
+ encodeThis();
+ }
+
+ /**
+ * Create a HoldInstructionExtension with the date.
+ * The criticality is set to false.
+ *
+ * @param oid the value to be set for the extension.
+ */
+ public HoldInstructionExtension(ObjectIdentifier oid)
+ throws IOException {
+ if (getHoldInstructionCodeFromOID(oid) == 0)
+ throw new IOException("Invalid hold instruction code");
+ holdInstructionCodeOID = oid;
+ this.extensionId = PKIXExtensions.HoldInstructionCode_Id;
+ this.critical = false;
+ encodeThis();
+ }
+
+ /**
+ * Create a HoldInstructionExtension with the date.
+ * The criticality is set to false.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param code the value to be set for the extension.
+ */
+ public HoldInstructionExtension(Boolean critical, int code)
+ throws IOException {
+ if (code < 1 || code > 3)
+ throw new IOException("Invalid hold instruction code");
+ holdInstructionCodeOID = holdInstructionCodeOIDs[code - 1];
+ this.extensionId = PKIXExtensions.HoldInstructionCode_Id;
+ this.critical = critical.booleanValue();
+ encodeThis();
+ }
+
+ /**
+ * Create a HoldInstructionExtension with the date.
+ * The criticality is set to false.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param oidStr the value to be set for the extension.
+ */
+ public HoldInstructionExtension(Boolean critical, String oidStr)
+ throws IOException {
+ ObjectIdentifier oid = new ObjectIdentifier(oidStr);
+ if (oid == null || getHoldInstructionCodeFromOID(oid) == 0)
+ throw new IOException("Invalid hold instruction code");
+ holdInstructionCodeOID = oid;
+ this.extensionId = PKIXExtensions.HoldInstructionCode_Id;
+ this.critical = critical.booleanValue();
+ encodeThis();
+ }
+
+ /**
+ * Create a HoldInstructionExtension with the date.
+ * The criticality is set to false.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param oid the value to be set for the extension.
+ */
+ public HoldInstructionExtension(Boolean critical, ObjectIdentifier oid)
+ throws IOException {
+ if (getHoldInstructionCodeFromOID(oid) == 0)
+ throw new IOException("Invalid hold instruction code");
+ holdInstructionCodeOID = oid;
+ this.extensionId = PKIXExtensions.HoldInstructionCode_Id;
+ this.critical = critical.booleanValue();
+ encodeThis();
+ }
+
+ /**
+ * Create the extension from the passed DER encoded value of the same.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param value Array of DER encoded bytes of the actual value.
+ * @exception IOException on error.
+ */
+ public HoldInstructionExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = PKIXExtensions.HoldInstructionCode_Id;
+ this.critical = critical.booleanValue();
+
+ int len = Array.getLength(value);
+ byte[] extValue = new byte[len];
+ for (int i = 0; i < len; i++) {
+ extValue[i] = Array.getByte(value, i);
+ }
+ this.extensionValue = extValue;
+ DerValue val = new DerValue(extValue);
+ if (val.tag == DerValue.tag_ObjectId) {
+ DerInputStream derInputStream = new DerInputStream(val.toByteArray());
+ holdInstructionCodeOID = derInputStream.getOID();
+ if (getHoldInstructionCodeFromOID(holdInstructionCodeOID) == 0)
+ throw new IOException("Invalid encoding for HoldInstructionExtension");
+ } else {
+ throw new IOException("Invalid encoding for HoldInstructionExtension");
+ }
+ }
+
+ /**
+ * Get the hold instruction code.
+ */
+ public ObjectIdentifier getHoldInstructionCode() {
+ return holdInstructionCodeOID;
+ }
+
+ public String getHoldInstructionCodeDescription() {
+ return getHoldInstructionDescription(holdInstructionCodeOID);
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ if (name.equalsIgnoreCase(HOLD_INSTRUCTION)) {
+ if (!(obj instanceof ObjectIdentifier)) {
+ throw new IOException("Attribute must be of type String.");
+ }
+ holdInstructionCodeOID = (ObjectIdentifier) obj;
+ } else {
+ throw new IOException("Attribute name not recognized by" +
+ " CertAttrSet:HoldInstructionCode.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(HOLD_INSTRUCTION)) {
+ return holdInstructionCodeOID;
+ } else {
+ throw new IOException("Attribute name not recognized by" +
+ " CertAttrSet:HoldInstructionCode.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(HOLD_INSTRUCTION)) {
+ holdInstructionCodeOID = null;
+ } else {
+ throw new IOException("Attribute name not recognized by" +
+ " CertAttrSet:HoldInstructionCode.");
+ }
+ }
+
+ /**
+ * Returns a printable representation of the HoldInstructionExtension.
+ */
+ public String toString() {
+ String s = super.toString() + "Hold Instruction Code: " +
+ getHoldInstructionDescription(holdInstructionCodeOID) + "\n";
+ return (s);
+ }
+
+ /**
+ * Decode the extension from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ /**
+ * Write the extension to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ if (this.extensionValue == null) {
+ this.extensionId = PKIXExtensions.HoldInstructionCode_Id;
+ this.critical = true;
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(HOLD_INSTRUCTION);
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/IA5StringConverter.java b/base/util/src/netscape/security/x509/IA5StringConverter.java
new file mode 100644
index 000000000..eced75a58
--- /dev/null
+++ b/base/util/src/netscape/security/x509/IA5StringConverter.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetEncoder;
+
+import netscape.security.util.ASN1CharStrConvMap;
+import netscape.security.util.DerValue;
+
+/**
+ * A AVAValueConverter that converts a IA5String attribute to a DerValue
+ * and vice versa. An example an attribute that is a IA5String string is "E".
+ *
+ * @see AVAValueConverter
+ *
+ * @author Lily Hsiao, Slava Galperin at Netscape Communications, Inc.
+ */
+
+public class IA5StringConverter implements AVAValueConverter {
+ // public constructors
+
+ /*
+ * Contructs a IA5String Converter.
+ */
+ public IA5StringConverter() {
+ }
+
+ /*
+ * Converts a string with ASN.1 IA5String characters to a DerValue.
+ *
+ * @param valueString a string with IA5String characters.
+ *
+ * @return a DerValue.
+ *
+ * @exception IOException if a IA5String encoder is not
+ * available for the conversion.
+ */
+ public DerValue getValue(String valueString)
+ throws IOException {
+ return getValue(valueString, null);
+ }
+
+ public DerValue getValue(String valueString, byte[] tags) throws IOException {
+ try {
+ CharsetEncoder encoder = ASN1CharStrConvMap.getDefault().getEncoder(DerValue.tag_IA5String);
+ if (encoder == null)
+ throw new IOException("No encoder for IA5String");
+
+ CharBuffer charBuffer = CharBuffer.wrap(valueString.toCharArray());
+ ByteBuffer byteBuffer = encoder.encode(charBuffer);
+
+ return new DerValue(DerValue.tag_IA5String,
+ byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.limit());
+
+ } catch (CharacterCodingException e) {
+ throw new IllegalArgumentException("Invalid IA5String AVA Value string");
+ }
+ }
+
+ /*
+ * Converts a BER encoded value of IA5String to a DER encoded value.
+ * Checks if the BER encoded value is a IA5String.
+ * NOTE only DER encoding is currently supported on for the BER
+ * encoded value.
+ *
+ * @param berStream a byte array of the BER encoded value.
+ *
+ * @return a DerValue.
+ *
+ * @exception IOException if the BER value cannot be converted
+ * to a IA5String DER value.
+ */
+ public DerValue getValue(byte[] berStream)
+ throws IOException {
+ DerValue value = new DerValue(berStream);
+ if (value.tag == DerValue.tag_IA5String)
+ return value;
+ if (value.tag == DerValue.tag_PrintableString)
+ return value;
+ throw new IOException("Invalid IA5String AVA Value.");
+ }
+
+ /*
+ * Converts a DerValue of IA5String to a java string with IA5String
+ * characters.
+ *
+ * @param avaValue a DerValue.
+ *
+ * @return a string with IA5String characters.
+ *
+ * @exception IOException if the DerValue is not a IA5String i.e.
+ * The DerValue cannot be converted to a string
+ * with IA5String characters.
+ */
+ public String getAsString(DerValue avaValue)
+ throws IOException {
+ if (avaValue.tag == DerValue.tag_IA5String)
+ return avaValue.getIA5String();
+ if (avaValue.tag == DerValue.tag_PrintableString)
+ return avaValue.getPrintableString();
+ throw new IOException("Invalid IA5String AVA Value.");
+ }
+
+}
diff --git a/base/util/src/netscape/security/x509/IPAddressName.java b/base/util/src/netscape/security/x509/IPAddressName.java
new file mode 100644
index 000000000..75b5bc564
--- /dev/null
+++ b/base/util/src/netscape/security/x509/IPAddressName.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.util.StringTokenizer;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class implements the IPAddressName as required by the GeneralNames
+ * ASN.1 object.
+ *
+ * @see GeneralName
+ * @see GeneralNameInterface
+ * @see GeneralNames
+ *
+ * @version 1.2
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ */
+public class IPAddressName implements GeneralNameInterface {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4240184399679453666L;
+ private byte[] address;
+
+ /**
+ * Create the IPAddressName object from the passed encoded Der value.
+ *
+ * @param derValue the encoded DER IPAddressName.
+ * @exception IOException on error.
+ */
+ public IPAddressName(DerValue derValue) throws IOException {
+ address = derValue.getOctetString();
+ }
+
+ /**
+ * Create the IPAddressName object with the specified name.
+ *
+ * @param name the IPAddressName.
+ */
+ public IPAddressName(byte[] address) {
+ this.address = address;
+ }
+
+ protected static final char IPv4_LEN = 4;
+ protected static final char IPv6_LEN = 16;
+ protected static final IPAddr IPv4 = new IPv4Addr();
+ protected static final IPAddr IPv6 = new IPv6Addr();
+
+ /**
+ * Create the IPAddressName object with a string representing the
+ * ip address and a string representing the netmask, with encoding
+ * having ip address encoding followed by the netmask encoding.
+ * This form is needed for name constraints extension.
+ *
+ * @param s the ip address in the format: n.n.n.n or x:x:x:x:x:x:x:x (RFC 1884)
+ * @param netmask the netmask address in the format: n.n.n.n or x:x:x:x:x:x:x:x (RFC 1884)
+ */
+ public IPAddressName(String s, String netmask) {
+ // Based on PKIX RFC2459. IPAddress has
+ // 8 bytes (instead of 4 bytes) in the
+ // context of NameConstraints
+ IPAddr ipAddr = null;
+ if (s.indexOf(':') != -1) {
+ ipAddr = IPv6;
+ address = new byte[IPv6_LEN * 2];
+ } else {
+ ipAddr = IPv4;
+ address = new byte[IPv4_LEN * 2];
+ }
+ StringTokenizer st = new StringTokenizer(s, ",");
+ int numFilled = ipAddr.getIPAddr(st.nextToken(), address, 0);
+ if (st.hasMoreTokens()) {
+ ipAddr.getIPAddr(st.nextToken(), address, numFilled);
+ } else {
+ for (int i = numFilled; i < address.length; i++)
+ address[i] = (byte) 0xff;
+ }
+ }
+
+ /**
+ * Create the IPAddressName object with a string representing the
+ * ip address.
+ *
+ * @param s the ip address in the format: n.n.n.n or x:x:x:x:x:x:x:x
+ */
+ public IPAddressName(String s) {
+ IPAddr ipAddr = null;
+ if (s.indexOf(':') != -1) {
+ ipAddr = IPv6;
+ address = new byte[IPv6_LEN];
+ } else {
+ ipAddr = IPv4;
+ address = new byte[IPv4_LEN];
+ }
+ ipAddr.getIPAddr(s, address, 0);
+ }
+
+ /**
+ * Return the type of the GeneralName.
+ */
+ public int getType() {
+ return (GeneralNameInterface.NAME_IP);
+ }
+
+ /**
+ * Encode the IPAddress name into the DerOutputStream.
+ *
+ * @param out the DER stream to encode the IPAddressName to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ out.putOctetString(address);
+ }
+
+ /**
+ * Return a printable string of IPaddress
+ */
+ public String toString() {
+ if (address.length == 4) {
+ return ("IPAddress: " + (address[0] & 0xff) + "."
+ + (address[1] & 0xff) + "."
+ + (address[2] & 0xff) + "." + (address[3] & 0xff));
+ } else {
+ String r = "IPAddress: " + Integer.toHexString(address[0] & 0xff);
+ String hexString = Integer.toHexString(address[1] & 0xff);
+ if (hexString.length() == 1) {
+ r = r + "0" + hexString;
+ } else {
+ r += hexString;
+ }
+ for (int i = 2; i < address.length;) {
+ r += ":" + Integer.toHexString(address[i] & 0xff);
+ hexString = Integer.toHexString(address[i + 1] & 0xff);
+ if (hexString.length() == 1) {
+ r = r + "0" + hexString;
+ } else {
+ r += hexString;
+ }
+ i += 2;
+ }
+ return r;
+ }
+ }
+}
+
+interface IPAddr {
+ public int getIPAddr(String s, byte[] address, int start);
+
+ public int getLength();
+}
+
+class IPv4Addr implements IPAddr {
+ protected static final int IPv4_LEN = 4;
+
+ /**
+ * Gets an IP v4 address in the form n.n.n.n.
+ */
+ public int getIPAddr(String s, byte[] address, int start) {
+ StringTokenizer st = new StringTokenizer(s, ".");
+ int nt = st.countTokens();
+ if (nt != IPv4_LEN)
+ throw new InvalidIPAddressException(s);
+ try {
+ int end = start + nt;
+ for (int i = start; i < end; i++) {
+ Integer j = new Integer(st.nextToken());
+ address[i] = (byte) j.intValue();
+ }
+ } catch (NumberFormatException e) {
+ throw new InvalidIPAddressException(s);
+ }
+ return nt;
+ }
+
+ public int getLength() {
+ return IPv4_LEN;
+ }
+}
+
+class IPv6Addr implements IPAddr {
+ /**
+ * Gets an IP address in the forms as defined in RFC1884:<br>
+ * <ul>
+ * <li>x:x:x:x:x:x:x:x
+ * <li>...::xxx (using :: shorthand)
+ * <li>...:n.n.n.n (with n.n.n.n at the end)
+ * </ul>
+ */
+ public int getIPAddr(String s, byte[] address, int start) {
+ int lastcolon = -2;
+ int end = start + 16;
+ int idx = start;
+ for (int i = start; i < address.length; i++)
+ address[i] = 0;
+ if (s.indexOf('.') != -1) { // has n.n.n.n at the end
+ lastcolon = s.lastIndexOf(':');
+ if (lastcolon == -1)
+ throw new InvalidIPAddressException(s);
+ end -= 4;
+ IPAddressName.IPv4.getIPAddr(
+ s.substring(lastcolon + 1), address, end);
+ }
+ try {
+ String s1 = s;
+ if (lastcolon != -2)
+ s1 = s.substring(0, lastcolon + 1);
+ int lastDoubleColon = s1.indexOf("::");
+ String l = s1, r = null;
+ StringTokenizer lt = null, rt = null;
+ if (lastDoubleColon != -1) {
+ l = s1.substring(0, lastDoubleColon);
+ r = s1.substring(lastDoubleColon + 2);
+ if (l.length() == 0)
+ l = null;
+ if (r.length() == 0)
+ r = null;
+ }
+ int at = 0;
+ if (l != null) {
+ lt = new StringTokenizer(l, ":", false);
+ at += lt.countTokens();
+ }
+ if (r != null) {
+ rt = new StringTokenizer(r, ":", false);
+ at += rt.countTokens();
+ }
+ if (at > 8 ||
+ (lastcolon != -2 && (at > 6 || (lastDoubleColon == -1 && at != 6))))
+ throw new InvalidIPAddressException(s);
+ if (l != null) {
+ while (lt.hasMoreTokens()) {
+ String tok = lt.nextToken();
+ int j = Integer.parseInt(tok, 16);
+ address[idx++] = (byte) ((j >> 8) & 0xFF);
+ address[idx++] = (byte) (j & 0xFF);
+ }
+ }
+ if (r != null) {
+ idx = end - (rt.countTokens() * 2);
+ while (rt.hasMoreTokens()) {
+ String tok = rt.nextToken();
+ int j = Integer.parseInt(tok, 16);
+ address[idx++] = (byte) ((j >> 8) & 0xFF);
+ address[idx++] = (byte) (j & 0xFF);
+ }
+ }
+ } catch (NumberFormatException e) {
+ throw new InvalidIPAddressException(s);
+ }
+ return 16;
+ }
+
+ public int getLength() {
+ return 16;
+ }
+}
diff --git a/base/util/src/netscape/security/x509/InvalidIPAddressException.java b/base/util/src/netscape/security/x509/InvalidIPAddressException.java
new file mode 100644
index 000000000..f544df200
--- /dev/null
+++ b/base/util/src/netscape/security/x509/InvalidIPAddressException.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 netscape.security.x509;
+
+public class InvalidIPAddressException extends RuntimeException {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1601934234587845028L;
+
+ public InvalidIPAddressException() {
+ super();
+ }
+
+ public InvalidIPAddressException(String ip) {
+ super("Invalid IP Address '" + ip + "'");
+ }
+}
diff --git a/base/util/src/netscape/security/x509/InvalidityDateExtension.java b/base/util/src/netscape/security/x509/InvalidityDateExtension.java
new file mode 100755
index 000000000..44c76275f
--- /dev/null
+++ b/base/util/src/netscape/security/x509/InvalidityDateExtension.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.security.cert.CertificateException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * Represent the CRL Invalidity Date Extension.
+ *
+ * <p>
+ * This CRL entry extension, if present, provides the date on which it is known or suspected that the private key was
+ * compromised or that the certificate otherwise became invalid. Invalidity date may be earlier than the revocation
+ * date.
+ *
+ * @see Extension
+ * @see CertAttrSet
+ */
+
+public class InvalidityDateExtension extends Extension
+ implements CertAttrSet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2191026017389643053L;
+ /**
+ * Attribute name.
+ */
+ public static final String NAME = "InvalidityDate";
+ public static final String INVALIDITY_DATE = "value";
+
+ /**
+ * The Object Identifier for this extension.
+ */
+ public static final String OID = "2.5.29.24";
+
+ private Date invalidityDate = null;
+
+ static {
+ try {
+ OIDMap.addAttribute(InvalidityDateExtension.class.getName(),
+ OID, NAME);
+ } catch (CertificateException e) {
+ }
+ }
+
+ // Encode this extension value
+ private void encodeThis() throws IOException {
+ if (invalidityDate == null)
+ throw new IOException("Unintialized invalidity date extension");
+ DerOutputStream os = new DerOutputStream();
+ os.putGeneralizedTime(this.invalidityDate);
+ this.extensionValue = os.toByteArray();
+ }
+
+ /**
+ * Create a InvalidityDateExtension with the date.
+ * The criticality is set to false.
+ *
+ * @param dateOfInvalidity the value to be set for the extension.
+ */
+ public InvalidityDateExtension(Date dateOfInvalidity)
+ throws IOException {
+ this.invalidityDate = dateOfInvalidity;
+ this.extensionId = PKIXExtensions.InvalidityDate_Id;
+ this.critical = false;
+ encodeThis();
+ }
+
+ /**
+ * Create a InvalidityDateExtension with the date.
+ * The criticality is set to false.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param dateOfInvalidity the value to be set for the extension.
+ */
+ public InvalidityDateExtension(Boolean critical, Date dateOfInvalidity)
+ throws IOException {
+ this.invalidityDate = dateOfInvalidity;
+ this.extensionId = PKIXExtensions.InvalidityDate_Id;
+ this.critical = critical.booleanValue();
+ encodeThis();
+ }
+
+ /**
+ * Create the extension from the passed DER encoded value of the same.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param value Array of DER encoded bytes of the actual value.
+ * @exception IOException on error.
+ */
+ public InvalidityDateExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = PKIXExtensions.InvalidityDate_Id;
+ this.critical = critical.booleanValue();
+
+ int len = Array.getLength(value);
+ byte[] extValue = new byte[len];
+ for (int i = 0; i < len; i++) {
+ extValue[i] = Array.getByte(value, i);
+ }
+ this.extensionValue = extValue;
+ DerValue val = new DerValue(extValue);
+ if (val.tag == DerValue.tag_GeneralizedTime) {
+ DerInputStream derInputStream = new DerInputStream(val.toByteArray());
+ this.invalidityDate = derInputStream.getGeneralizedTime();
+ } else {
+ throw new IOException("Invalid encoding for InvalidityDateExtension");
+ }
+ }
+
+ /**
+ * Get the invalidity date.
+ */
+ public Date getInvalidityDate() {
+ return invalidityDate;
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ if (name.equalsIgnoreCase(INVALIDITY_DATE)) {
+ if (!(obj instanceof Date)) {
+ throw new IOException("Attribute must be of type Date.");
+ }
+ invalidityDate = (Date) obj;
+ } else {
+ throw new IOException("Attribute name not recognized by" +
+ " CertAttrSet:InvalidityDate.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(INVALIDITY_DATE)) {
+ if (invalidityDate == null)
+ return null;
+ else
+ return invalidityDate;
+ } else {
+ throw new IOException("Attribute name not recognized by" +
+ " CertAttrSet:InvalidityDate.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(INVALIDITY_DATE)) {
+ invalidityDate = null;
+ } else {
+ throw new IOException("Attribute name not recognized by" +
+ " CertAttrSet:InvalidityDate.");
+ }
+ }
+
+ /**
+ * Returns a printable representation of the InvalidityDateExtension.
+ */
+ public String toString() {
+ String s = super.toString() + "Invalidity Date: " +
+ ((invalidityDate == null) ? "" : invalidityDate.toString())
+ + "\n";
+ return (s);
+ }
+
+ /**
+ * Decode the extension from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ /**
+ * Write the extension to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ if (this.extensionValue == null) {
+ this.extensionId = PKIXExtensions.InvalidityDate_Id;
+ this.critical = true;
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(INVALIDITY_DATE);
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/IssuerAlternativeNameExtension.java b/base/util/src/netscape/security/x509/IssuerAlternativeNameExtension.java
new file mode 100644
index 000000000..df0289f9e
--- /dev/null
+++ b/base/util/src/netscape/security/x509/IssuerAlternativeNameExtension.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This represents the Issuer Alternative Name Extension.
+ *
+ * This extension, if present, allows the issuer to specify multiple
+ * alternative names.
+ *
+ * <p>
+ * Extensions are represented as a sequence of the extension identifier (Object Identifier), a boolean flag stating
+ * whether the extension is to be treated as being critical and the extension value itself (this is again a DER encoding
+ * of the extension value).
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.7
+ * @see Extension
+ * @see CertAttrSet
+ */
+public class IssuerAlternativeNameExtension
+ extends Extension implements CertAttrSet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -269518027483586255L;
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT =
+ "x509.info.extensions.IssuerAlternativeName";
+ /**
+ * Attribute names.
+ */
+ public static final String NAME = "IssuerAlternativeName";
+ public static final String ISSUER_NAME = "issuer_name";
+
+ // private data members
+ GeneralNames names;
+
+ // Encode this extension
+ private void encodeThis() throws IOException {
+ DerOutputStream os = new DerOutputStream();
+ try {
+ names.encode(os);
+ } catch (GeneralNamesException e) {
+ throw new IOException(e.toString());
+ }
+ this.extensionValue = os.toByteArray();
+ }
+
+ /**
+ * Create a IssuerAlternativeNameExtension with the passed GeneralNames.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param names the GeneralNames for the issuer.
+ * @exception IOException on error.
+ */
+ public IssuerAlternativeNameExtension(Boolean critical, GeneralNames names)
+ throws IOException {
+ this.names = names;
+ this.extensionId = PKIXExtensions.IssuerAlternativeName_Id;
+ this.critical = critical.booleanValue();
+ encodeThis();
+ }
+
+ /**
+ * Create a IssuerAlternativeNameExtension with the passed GeneralNames.
+ *
+ * @param names the GeneralNames for the issuer.
+ * @exception IOException on error.
+ */
+ public IssuerAlternativeNameExtension(GeneralNames names)
+ throws IOException {
+ this.names = names;
+ this.extensionId = PKIXExtensions.IssuerAlternativeName_Id;
+ this.critical = false;
+ encodeThis();
+ }
+
+ /**
+ * Create a default IssuerAlternativeNameExtension.
+ */
+ public IssuerAlternativeNameExtension() {
+ extensionId = PKIXExtensions.IssuerAlternativeName_Id;
+ critical = false;
+ names = new GeneralNames();
+ }
+
+ /**
+ * Create the extension from the passed DER encoded value.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param value Array of DER encoded bytes of the actual value.
+ * @exception IOException on error.
+ */
+ public IssuerAlternativeNameExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = PKIXExtensions.IssuerAlternativeName_Id;
+ this.critical = critical.booleanValue();
+
+ int len = Array.getLength(value);
+ byte[] extValue = new byte[len];
+ for (int i = 0; i < len; i++) {
+ extValue[i] = Array.getByte(value, i);
+ }
+ this.extensionValue = extValue;
+ DerValue val = new DerValue(extValue);
+ try {
+ names = new GeneralNames(val);
+ } catch (GeneralNamesException e) {
+ throw new IOException("IssuerAlternativeNameExtension"
+ + e.toString());
+ }
+ }
+
+ /**
+ * Returns a printable representation of the IssuerAlternativeName.
+ */
+ public String toString() {
+ if (names == null)
+ return "";
+ String s = super.toString() + "IssuerAlternativeName [\n"
+ + names.toString() + "]\n";
+ return (s);
+ }
+
+ /**
+ * Decode the extension from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ /**
+ * Write the extension to the OutputStream.
+ *
+ * @param out the OutputStream to write the extension to.
+ * @exception IOException on encoding error.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ if (extensionValue == null) {
+ extensionId = PKIXExtensions.IssuerAlternativeName_Id;
+ critical = false;
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ clearValue();
+ if (name.equalsIgnoreCase(ISSUER_NAME)) {
+ if (!(obj instanceof GeneralNames)) {
+ throw new IOException("Attribute value should be of" +
+ " type GeneralNames.");
+ }
+ names = (GeneralNames) obj;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:IssuerAlternativeName.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(ISSUER_NAME)) {
+ return (names);
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:IssuerAlternativeName.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(ISSUER_NAME)) {
+ names = null;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:IssuerAlternativeName.");
+ }
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(ISSUER_NAME);
+
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/IssuingDistributionPoint.java b/base/util/src/netscape/security/x509/IssuingDistributionPoint.java
new file mode 100644
index 000000000..0f0747f84
--- /dev/null
+++ b/base/util/src/netscape/security/x509/IssuingDistributionPoint.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 netscape.security.x509;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import netscape.security.util.BitArray;
+import netscape.security.util.DerOutputStream;
+
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.BOOLEAN;
+import org.mozilla.jss.asn1.EXPLICIT;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.Tag;
+
+/**
+ * <pre>
+ * issuingDistributionPoint ::= SEQUENCE {
+ * distributionPoint [0] DistributionPointName OPTIONAL,
+ * onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE,
+ * onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE,
+ * onlySomeReasons [3] ReasonFlags OPTIONAL,
+ * indirectCRL [4] BOOLEAN DEFAULT FALSE }
+ *
+ * DistributionPointName ::= CHOICE {
+ * fullName [0] GeneralNames,
+ * nameRelativeToCRLIssuer [1] RelativeDistinguishedName }
+ *
+ * ReasonFlags ::= BIT STRING {
+ * unused (0),
+ * keyCompromise (1),
+ * cACompromise (2),
+ * affiliationChanged (3),
+ * superseded (4),
+ * cessationOfOperation (5),
+ * certificateHold (6) }
+ *
+ * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+ *
+ * GeneralName ::= CHOICE {
+ * otherName [0] OtherName,
+ * rfc822Name [1] IA5String,
+ * dNSName [2] IA5String,
+ * x400Address [3] ORAddress,
+ * directoryName [4] Name,
+ * ediPartyName [5] EDIPartyName,
+ * uniformResourceIdentifier [6] IA5String,
+ * iPAddress [7] OCTET STRING,
+ * registeredID [8] OBJECT IDENTIFIER}
+ *
+ * OtherName ::= SEQUENCE {
+ * type-id OBJECT IDENTIFIER,
+ * value [0] EXPLICIT ANY DEFINED BY type-id }
+ *
+ * EDIPartyName ::= SEQUENCE {
+ * nameAssigner [0] DirectoryString OPTIONAL,
+ * partyName [1] DirectoryString }
+ *
+ * RelativeDistinguishedName ::=
+ * SET OF AttributeTypeAndValue
+ *
+ * AttributeTypeAndValue ::= SEQUENCE {
+ * type AttributeType,
+ * value AttributeValue }
+ *
+ * AttributeType ::= OBJECT IDENTIFIER
+ *
+ * AttributeValue ::= ANY DEFINED BY AttributeType
+ * </pre>
+ *
+ * See the documentation in <code>CRLDistributionPoint</code> for
+ * the <code>DistributionPointName</code> and <code>ReasonFlags</code> ASN.1 types.
+ */
+public class IssuingDistributionPoint implements ASN1Value {
+
+ // at most one of the following two may be specified. One or both can
+ // be null.
+ private GeneralNames fullName = null;
+ private RDN relativeName = null;
+
+ private boolean onlyContainsUserCerts = false; // DEFAULT FALSE
+ private boolean onlyContainsCACerts = false; // DEFAULT FALSE
+ private BitArray onlySomeReasons = null; // optional, may be null
+ private boolean indirectCRL = false; // DEFAULT FALSE
+
+ // cache encoding of fullName
+ private ANY fullNameEncoding;
+
+ /**
+ * Returns the <code>fullName</code> of the <code>DistributionPointName</code>, which may be <code>null</code>.
+ */
+ public GeneralNames getFullName() {
+ return fullName;
+ }
+
+ /**
+ * Returns the <code>relativeName</code> of the <code>DistributionPointName</code>, which may be <code>null</code>.
+ */
+ public RDN getRelativeName() {
+ return relativeName;
+ }
+
+ /**
+ * Sets the <code>fullName</code> of the <code>DistributionPointName</code>. It may be set to <code>null</code>.
+ * If it is set to a non-null value, <code>relativeName</code> will be
+ * set to <code>null</code>, because at most one of these two attributes
+ * can be specified at a time.
+ *
+ * @exception GeneralNamesException If an error occurs encoding the
+ * name.
+ */
+ public void setFullName(GeneralNames fullName)
+ throws GeneralNamesException, IOException {
+ this.fullName = fullName;
+ if (fullName != null) {
+ // encode the name to catch any problems with it
+ DerOutputStream derOut = new DerOutputStream();
+ fullName.encode(derOut);
+ try {
+ ANY raw = new ANY(derOut.toByteArray());
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ raw.encodeWithAlternateTag(Tag.get(0), bos);
+ fullNameEncoding = new ANY(bos.toByteArray());
+ } catch (InvalidBERException e) {
+ // assume this won't happen, since it would imply a bug
+ // in DerOutputStream
+ throw new GeneralNamesException(e.toString());
+ }
+
+ this.relativeName = null;
+ }
+ }
+
+ /**
+ * Sets the <code>relativeName</code> of the <code>DistributionPointName</code>. It may be set to <code>null</code>.
+ * If it is set to a non-null value, <code>fullName</code> will be
+ * set to <code>null</code>, because at most one of these two attributes
+ * can be specified at a time.
+ */
+ public void setRelativeName(RDN relativeName) {
+ this.relativeName = relativeName;
+ if (relativeName != null) {
+ this.fullName = null;
+ }
+ }
+
+ public boolean getOnlyContainsUserCerts() {
+ return onlyContainsUserCerts;
+ }
+
+ public void setOnlyContainsUserCerts(boolean b) {
+ onlyContainsUserCerts = b;
+ }
+
+ public boolean getOnlyContainsCACerts() {
+ return onlyContainsCACerts;
+ }
+
+ public void setOnlyContainsCACerts(boolean b) {
+ onlyContainsCACerts = b;
+ }
+
+ /**
+ * Returns the reason flags for this distribution point. May be <code>null</code>.
+ */
+ public BitArray getOnlySomeReasons() {
+ return onlySomeReasons;
+ }
+
+ /**
+ * Sets the reason flags for this distribution point. May be set to <code>null</code>.
+ */
+ public void setOnlySomeReasons(BitArray reasons) {
+ this.onlySomeReasons = reasons;
+ }
+
+ public boolean getIndirectCRL() {
+ return indirectCRL;
+ }
+
+ public void setIndirectCRL(boolean b) {
+ indirectCRL = b;
+ }
+
+ /////////////////////////////////////////////////////////////
+ // DER encoding
+ /////////////////////////////////////////////////////////////
+ private static final Tag TAG = SEQUENCE.TAG;
+
+ public Tag getTag() {
+ return TAG;
+ }
+
+ public void encode(OutputStream ostream) throws IOException {
+ encode(TAG, ostream);
+ }
+
+ public void encode(Tag implicitTag, OutputStream ostream)
+ throws IOException {
+
+ SEQUENCE seq = new SEQUENCE();
+ DerOutputStream derOut;
+
+ try {
+
+ // Encodes the DistributionPointName. Because DistributionPointName
+ // is a CHOICE, the [0] tag is forced to be EXPLICIT.
+ if (fullName != null) {
+ EXPLICIT distPoint = new EXPLICIT(Tag.get(0), fullNameEncoding);
+ seq.addElement(distPoint);
+ } else if (relativeName != null) {
+ derOut = new DerOutputStream();
+ relativeName.encode(derOut);
+ ANY raw = new ANY(derOut.toByteArray());
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ raw.encodeWithAlternateTag(Tag.get(1), bos);
+ ANY distPointName = new ANY(bos.toByteArray());
+ EXPLICIT distPoint = new EXPLICIT(Tag.get(0), distPointName);
+ seq.addElement(distPoint);
+ }
+
+ if (onlyContainsUserCerts != false) {
+ seq.addElement(Tag.get(1), new BOOLEAN(true));
+ }
+ if (onlyContainsCACerts != false) {
+ seq.addElement(Tag.get(2), new BOOLEAN(true));
+ }
+
+ // Encodes the ReasonFlags.
+ if (onlySomeReasons != null) {
+ derOut = new DerOutputStream();
+ derOut.putUnalignedBitString(onlySomeReasons);
+ ANY raw = new ANY(derOut.toByteArray());
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ raw.encodeWithAlternateTag(Tag.get(3), bos);
+ ANY reasonEncoding = new ANY(bos.toByteArray());
+ seq.addElement(reasonEncoding);
+ }
+
+ if (indirectCRL != false) {
+ seq.addElement(Tag.get(4), new BOOLEAN(true));
+ }
+
+ seq.encode(implicitTag, ostream);
+
+ } catch (InvalidBERException e) {
+ // this shouldn't happen unless there is a bug in one of
+ // the Sun encoding classes
+ throw new IOException(e.toString());
+ }
+ }
+
+ public static void main(String args[]) {
+
+ try {
+ if (args.length != 1) {
+ System.out.println("Usage: IssuingDistributionPoint <outfile>");
+ System.exit(-1);
+ }
+
+ BufferedOutputStream bos = new BufferedOutputStream(
+ new FileOutputStream(args[0]));
+
+ SEQUENCE idps = new SEQUENCE();
+
+ IssuingDistributionPoint idp = new IssuingDistributionPoint();
+
+ X500Name dn = new X500Name("CN=Skovw Wjasldk,E=nicolson@netscape.com" +
+ ",OU=Certificate Server,O=Netscape,C=US");
+ GeneralNames generalNames = new GeneralNames();
+ generalNames.addElement(dn);
+ idp.setFullName(generalNames);
+ idps.addElement(idp);
+
+ idp = new IssuingDistributionPoint();
+ URIName uri = new URIName("http://www.mycrl.com/go/here");
+ generalNames = new GeneralNames();
+ generalNames.addElement(uri);
+ idp.setFullName(generalNames);
+ idp.setOnlyContainsUserCerts(true);
+ idp.setOnlyContainsCACerts(true);
+ idp.setIndirectCRL(true);
+ BitArray ba = new BitArray(5, new byte[] { (byte) 0x28 });
+ idp.setOnlySomeReasons(ba);
+ idps.addElement(idp);
+
+ idps.encode(bos);
+ bos.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/base/util/src/netscape/security/x509/IssuingDistributionPointExtension.java b/base/util/src/netscape/security/x509/IssuingDistributionPointExtension.java
new file mode 100644
index 000000000..d5f5100bf
--- /dev/null
+++ b/base/util/src/netscape/security/x509/IssuingDistributionPointExtension.java
@@ -0,0 +1,416 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.BufferedOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.BitArray;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+import org.mozilla.jss.asn1.ASN1Util;
+
+/**
+ * A critical CRL extension that identifies the CRL distribution point
+ * for a particular CRL
+ *
+ * <pre>
+ * issuingDistributionPoint ::= SEQUENCE {
+ * distributionPoint [0] DistributionPointName OPTIONAL,
+ * onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE,
+ * onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE,
+ * onlySomeReasons [3] ReasonFlags OPTIONAL,
+ * indirectCRL [4] BOOLEAN DEFAULT FALSE }
+ *
+ * DistributionPointName ::= CHOICE {
+ * fullName [0] GeneralNames,
+ * nameRelativeToCRLIssuer [1] RelativeDistinguishedName }
+ *
+ * ReasonFlags ::= BIT STRING {
+ * unused (0),
+ * keyCompromise (1),
+ * cACompromise (2),
+ * affiliationChanged (3),
+ * superseded (4),
+ * cessationOfOperation (5),
+ * certificateHold (6) }
+ *
+ * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+ *
+ * GeneralName ::= CHOICE {
+ * otherName [0] OtherName,
+ * rfc822Name [1] IA5String,
+ * dNSName [2] IA5String,
+ * x400Address [3] ORAddress,
+ * directoryName [4] Name,
+ * ediPartyName [5] EDIPartyName,
+ * uniformResourceIdentifier [6] IA5String,
+ * iPAddress [7] OCTET STRING,
+ * registeredID [8] OBJECT IDENTIFIER}
+ *
+ * OtherName ::= SEQUENCE {
+ * type-id OBJECT IDENTIFIER,
+ * value [0] EXPLICIT ANY DEFINED BY type-id }
+ *
+ * EDIPartyName ::= SEQUENCE {
+ * nameAssigner [0] DirectoryString OPTIONAL,
+ * partyName [1] DirectoryString }
+ *
+ * RelativeDistinguishedName ::=
+ * SET OF AttributeTypeAndValue
+ *
+ * AttributeTypeAndValue ::= SEQUENCE {
+ * type AttributeType,
+ * value AttributeValue }
+ *
+ * AttributeType ::= OBJECT IDENTIFIER
+ *
+ * AttributeValue ::= ANY DEFINED BY AttributeType
+ * </pre>
+ */
+public class IssuingDistributionPointExtension extends Extension
+ implements CertAttrSet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1281544042375527550L;
+
+ /**
+ * The Object Identifier for this extension.
+ */
+ public static final String OID = "2.5.29.28";
+
+ /**
+ * Attribute names.
+ */
+ public static final String NAME = "IssuingDistributionPoint";
+ public static final String ISSUING_DISTRIBUTION_POINT = "issuing_distribution_point";
+
+ // Private data members
+ private IssuingDistributionPoint issuingDistributionPoint = null;
+
+ // Cached DER-encoding to improve performance.
+ private byte[] cachedEncoding = null;
+
+ static {
+ try {
+ OIDMap.addAttribute(IssuingDistributionPointExtension.class.getName(),
+ OID, NAME);
+ } catch (CertificateException e) {
+ }
+ }
+
+ /**
+ * This constructor is very important, since it will be called
+ * by the system.
+ */
+ public IssuingDistributionPointExtension(Boolean critical, Object value)
+ throws IOException {
+
+ this.extensionId = PKIXExtensions.IssuingDistributionPoint_Id;
+ this.critical = critical.booleanValue();
+ this.extensionValue = (byte[]) ((byte[]) value).clone();
+
+ byte[] extValue = this.extensionValue;
+ issuingDistributionPoint = new IssuingDistributionPoint();
+ DerValue val = new DerValue(extValue);
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding of IssuingDistributionPoint");
+ }
+
+ while (val.data.available() != 0) {
+ DerValue opt = val.data.getDerValue();
+
+ if (opt != null) {
+ for (int i = 0; i < 5; i++) {
+ if (opt.isContextSpecific((byte) i)) {
+ if ((i == 0 && opt.isConstructed() && opt.data.available() != 0) ||
+ (i != 0 && (!opt.isConstructed()) && opt.data.available() != 0)) {
+
+ if (i == 0) {
+ DerValue opt1 = opt.data.getDerValue();
+ if (opt1 != null) {
+ if (opt1.isContextSpecific((byte) 0)) {
+ if (opt1.isConstructed() && opt1.data.available() != 0) {
+ opt1.resetTag(DerValue.tag_Sequence);
+
+ try {
+ GeneralNames fullName = new GeneralNames(opt1);
+ if (fullName != null) {
+ issuingDistributionPoint.setFullName(fullName);
+ }
+ } catch (GeneralNamesException e) {
+ throw new IOException("Invalid encoding of IssuingDistributionPoint "
+ + e);
+ } catch (IOException e) {
+ throw new IOException("Invalid encoding of IssuingDistributionPoint "
+ + e);
+ }
+ } else {
+ throw new IOException("Invalid encoding of IssuingDistributionPoint");
+ }
+
+ } else if (opt1.isContextSpecific((byte) 1)) {
+ if (opt1.isConstructed() && opt1.data.available() != 0) {
+ opt1.resetTag(DerValue.tag_Set);
+
+ try {
+ RDN relativeName = new RDN(opt1);
+ if (relativeName != null) {
+ issuingDistributionPoint.setRelativeName(relativeName);
+ }
+ } catch (IOException e) {
+ throw new IOException("Invalid encoding of IssuingDistributionPoint "
+ + e);
+ }
+ } else {
+ throw new IOException("Invalid encoding of IssuingDistributionPoint");
+ }
+ }
+ }
+
+ } else if (i == 3) {
+ opt.resetTag(DerValue.tag_BitString);
+ try {
+ BitArray reasons = opt.getUnalignedBitString();
+ issuingDistributionPoint.setOnlySomeReasons(reasons);
+
+ @SuppressWarnings("unused")
+ byte[] a = reasons.toByteArray(); // check for errors
+ } catch (IOException e) {
+ throw new IOException("Invalid encoding of IssuingDistributionPoint " + e);
+ }
+
+ } else {
+ opt.resetTag(DerValue.tag_Boolean);
+ try {
+ boolean b = opt.getBoolean();
+ if (i == 1) {
+ issuingDistributionPoint.setOnlyContainsUserCerts(b);
+ } else if (i == 2) {
+ issuingDistributionPoint.setOnlyContainsCACerts(b);
+ } else if (i == 4) {
+ issuingDistributionPoint.setIndirectCRL(b);
+ }
+ } catch (IOException e) {
+ throw new IOException("Invalid encoding of IssuingDistributionPoint " + e);
+ }
+ }
+ } else {
+ throw new IOException("Invalid encoding of IssuingDistributionPoint");
+ }
+ }
+ }
+ } else {
+ throw new IOException("Invalid encoding of IssuingDistributionPoint");
+ }
+ }
+
+ }
+
+ /**
+ * Creates a new IssuingDistributionPoint extension, with the given
+ * issuing distribution point as the first element.
+ */
+ public IssuingDistributionPointExtension(IssuingDistributionPoint idp) {
+ this.extensionId = PKIXExtensions.IssuingDistributionPoint_Id;
+ this.critical = true;
+ issuingDistributionPoint = idp;
+ }
+
+ /**
+ * Returns the issuing distribution point.
+ */
+ public IssuingDistributionPoint getIssuingDistributionPoint() {
+ return issuingDistributionPoint;
+ }
+
+ /**
+ * Sets the criticality of this extension. PKIX dictates that this
+ * extension SHOULD be critical, so applications can make it not critical
+ * if they have a very good reason. By default, the extension is critical.
+ */
+ public void setCritical(boolean critical) {
+ this.critical = critical;
+ }
+
+ /**
+ * Gets the criticality of this extension. PKIX dictates that this
+ * extension SHOULD be critical, so by default, the extension is critical.
+ */
+ public boolean getCritical(boolean critical) {
+ return this.critical;
+ }
+
+ /**
+ * Encodes this extension to the given DerOutputStream.
+ * This method re-encodes each time it is called, so it is not very
+ * efficient.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ extensionValue = ASN1Util.encode(issuingDistributionPoint);
+ super.encode(out);
+ }
+
+ /**
+ * Should be called if any change is made to this data structure
+ * so that the cached DER encoding can be discarded.
+ */
+ public void flushCachedEncoding() {
+ cachedEncoding = null;
+ }
+
+ /**
+ * Returns a printable representation of the IssuingDistributionPointExtension
+ */
+
+ public String toString() {
+ return NAME;
+ }
+
+ /**
+ * DER-encodes this extension to the given OutputStream.
+ */
+ public void encode(OutputStream ostream)
+ throws CertificateException, IOException {
+ if (cachedEncoding == null) {
+ // only re-encode if necessary
+ DerOutputStream tmp = new DerOutputStream();
+ encode(tmp);
+ cachedEncoding = tmp.toByteArray();
+ }
+ ostream.write(cachedEncoding);
+ }
+
+ public void decode(InputStream in)
+ throws CertificateException, IOException {
+ throw new IOException("Not supported");
+ }
+
+ public void set(String name, Object obj)
+ throws CertificateException, IOException {
+ if (name.equalsIgnoreCase(ISSUING_DISTRIBUTION_POINT)) {
+ if (!(obj instanceof IssuingDistributionPoint)) {
+ throw new IOException("Attribute value should be of type IssuingDistributionPoint.");
+ }
+ issuingDistributionPoint = (IssuingDistributionPoint) obj;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:IssuingDistributionPointExtension");
+ }
+ }
+
+ public Object get(String name)
+ throws CertificateException, IOException {
+ if (name.equalsIgnoreCase(ISSUING_DISTRIBUTION_POINT)) {
+ return issuingDistributionPoint;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:IssuingDistributionPointExtension");
+ }
+ }
+
+ public void delete(String name)
+ throws CertificateException, IOException {
+ if (name.equalsIgnoreCase(ISSUING_DISTRIBUTION_POINT)) {
+ issuingDistributionPoint = null;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:IssuingDistributionPointExtension");
+ }
+ }
+
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(ISSUING_DISTRIBUTION_POINT);
+ return (elements.elements());
+ // return (new Vector()).elements();
+ }
+
+ public String getName() {
+ return NAME;
+ }
+
+ /**
+ * Test driver.
+ */
+ public static void main(String args[]) {
+
+ try {
+
+ if (args.length != 1) {
+ System.out.println("Usage: IssuingDistributionPointExtension " +
+ "<outfile>");
+ System.exit(-1);
+ }
+
+ BufferedOutputStream bos = new BufferedOutputStream(
+ new FileOutputStream(args[0]));
+
+ // URI only
+ IssuingDistributionPoint idp = new IssuingDistributionPoint();
+ URIName uri = new URIName("http://www.mycrl.com/go/here");
+ GeneralNames generalNames = new GeneralNames();
+ generalNames.addElement(uri);
+ idp.setFullName(generalNames);
+ IssuingDistributionPointExtension idpExt =
+ new IssuingDistributionPointExtension(idp);
+
+ // DN only
+ idp = new IssuingDistributionPoint();
+ X500Name dn = new X500Name("CN=Otis Smith,E=otis@fedoraproject.org" +
+ ",OU=Certificate Server,O=Fedora,C=US");
+ generalNames = new GeneralNames();
+ generalNames.addElement(dn);
+ idp.setFullName(generalNames);
+ idpExt.set(IssuingDistributionPointExtension.ISSUING_DISTRIBUTION_POINT, idp);
+
+ // DN + reason
+ BitArray ba = new BitArray(5, new byte[] { (byte) 0x28 });
+ idp = new IssuingDistributionPoint();
+ idp.setFullName(generalNames);
+ idp.setOnlySomeReasons(ba);
+ idpExt.set(IssuingDistributionPointExtension.ISSUING_DISTRIBUTION_POINT, idp);
+
+ // relative DN + reason + crlIssuer
+ idp = new IssuingDistributionPoint();
+ RDN rdn = new RDN("OU=foobar dept");
+ idp.setRelativeName(rdn);
+ idp.setOnlySomeReasons(ba);
+ idp.setOnlyContainsCACerts(true);
+ idp.setOnlyContainsUserCerts(true);
+ idp.setIndirectCRL(true);
+ idpExt.set(IssuingDistributionPointExtension.ISSUING_DISTRIBUTION_POINT, idp);
+
+ idpExt.setCritical(false);
+ idpExt.encode(bos);
+
+ bos.close();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/x509/KeyIdentifier.java b/base/util/src/netscape/security/x509/KeyIdentifier.java
new file mode 100644
index 000000000..631f6fd65
--- /dev/null
+++ b/base/util/src/netscape/security/x509/KeyIdentifier.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 netscape.security.x509;
+
+import java.io.IOException;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * Represent the Key Identifier ASN.1 object.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.4
+ */
+public class KeyIdentifier implements java.io.Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2412286879441154979L;
+ private byte[] octetString;
+
+ /**
+ * Create a KeyIdentifier with the passed bit settings.
+ *
+ * @param octetString the octet string identifying the key identifier.
+ */
+ public KeyIdentifier(byte[] octetString) {
+ this.octetString = octetString;
+ }
+
+ /**
+ * Create a KeyIdentifier from the DER encoded value.
+ *
+ * @param val the DerValue
+ */
+ public KeyIdentifier(DerValue val) throws IOException {
+ octetString = val.getOctetString();
+ }
+
+ /**
+ * Return the value of the KeyIdentifier as byte array.
+ */
+ public byte[] getIdentifier() {
+ return ((byte[]) octetString.clone());
+ }
+
+ /**
+ * Returns a printable representation of the KeyUsage.
+ */
+ public String toString() {
+ netscape.security.util.PrettyPrintFormat pp =
+ new netscape.security.util.PrettyPrintFormat(" ", 20);
+ String octetbits = pp.toHexString(octetString);
+
+ String s = "KeyIdentifier [\n";
+ s += octetbits;
+ s += "]\n";
+ return (s);
+ }
+
+ /**
+ * Write the KeyIdentifier to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the object to.
+ * @exception IOException
+ */
+ void encode(DerOutputStream out) throws IOException {
+ out.putOctetString(octetString);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/KeyUsageExtension.java b/base/util/src/netscape/security/x509/KeyUsageExtension.java
new file mode 100644
index 000000000..56084dbcf
--- /dev/null
+++ b/base/util/src/netscape/security/x509/KeyUsageExtension.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.BitArray;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * Represent the Key Usage Extension.
+ *
+ * <p>
+ * This extension, if present, defines the purpose (e.g., encipherment, signature, certificate signing) of the key
+ * contained in the certificate. The usage restriction might be employed when a multipurpose key is to be restricted
+ * (e.g., when an RSA key should be used only for signing or only for key encipherment).
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.9
+ * @see Extension
+ * @see CertAttrSet
+ */
+public class KeyUsageExtension extends Extension
+ implements CertAttrSet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2899719374157256708L;
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT = "x509.info.extensions.KeyUsage";
+ /**
+ * Attribute names.
+ */
+ public static final String NAME = "KeyUsage";
+ public static final String DIGITAL_SIGNATURE = "digital_signature";
+ public static final String NON_REPUDIATION = "non_repudiation";
+ public static final String KEY_ENCIPHERMENT = "key_encipherment";
+ public static final String DATA_ENCIPHERMENT = "data_encipherment";
+ public static final String KEY_AGREEMENT = "key_agreement";
+ public static final String KEY_CERTSIGN = "key_certsign";
+ public static final String CRL_SIGN = "crl_sign";
+ public static final String ENCIPHER_ONLY = "encipher_only";
+ public static final String DECIPHER_ONLY = "decipher_only";
+
+ public static final int DIGITAL_SIGNATURE_BIT = 0;
+ public static final int NON_REPUDIATION_BIT = 1;
+ public static final int KEY_ENCIPHERMENT_BIT = 2;
+ public static final int DATA_ENCIPHERMENT_BIT = 3;
+ public static final int KEY_AGREEMENT_BIT = 4;
+ public static final int KEY_CERTSIGN_BIT = 5;
+ public static final int CRL_SIGN_BIT = 6;
+ public static final int ENCIPHER_ONLY_BIT = 7;
+ public static final int DECIPHER_ONLY_BIT = 8;
+
+ public static final int NBITS = 9;
+
+ public static String[] names = new String[NBITS];
+
+ static {
+ names[DIGITAL_SIGNATURE_BIT] = DIGITAL_SIGNATURE;
+ names[NON_REPUDIATION_BIT] = NON_REPUDIATION;
+ names[KEY_ENCIPHERMENT_BIT] = KEY_ENCIPHERMENT;
+ names[DATA_ENCIPHERMENT_BIT] = DATA_ENCIPHERMENT;
+ names[KEY_AGREEMENT_BIT] = KEY_AGREEMENT;
+ names[KEY_CERTSIGN_BIT] = KEY_CERTSIGN;
+ names[CRL_SIGN_BIT] = CRL_SIGN;
+ names[ENCIPHER_ONLY_BIT] = ENCIPHER_ONLY;
+ names[DECIPHER_ONLY_BIT] = DECIPHER_ONLY;
+ }
+
+ // Private data members
+ private boolean[] bitString;
+
+ // Encode this extension value
+ private void encodeThis() throws IOException {
+ DerOutputStream os = new DerOutputStream();
+ os.putUnalignedBitString(this.bitString);
+ this.extensionValue = os.toByteArray();
+ }
+
+ /**
+ * Check if bit is set.
+ *
+ * @param position the position in the bit string to check.
+ */
+ private boolean isSet(int position) {
+ if (bitString.length <= position)
+ return false;
+ return bitString[position];
+ }
+
+ /**
+ * Set the bit at the specified position.
+ */
+ private void set(int position, boolean val) {
+ // enlarge bitString if necessary
+ if (position >= bitString.length) {
+ boolean[] tmp = new boolean[position + 1];
+ System.arraycopy(bitString, 0, tmp, 0, bitString.length);
+ bitString = tmp;
+ }
+ bitString[position] = val;
+ }
+
+ /**
+ * Create a KeyUsageExtension with the passed bit settings. The criticality
+ * is set to true.
+ *
+ * @param bitString the bits to be set for the extension.
+ */
+ public KeyUsageExtension(boolean critical, byte[] bitString) throws IOException {
+ this.bitString =
+ new BitArray(bitString.length * 8, bitString).toBooleanArray();
+ this.extensionId = PKIXExtensions.KeyUsage_Id;
+ this.critical = critical;
+ encodeThis();
+ }
+
+ public KeyUsageExtension(byte[] bitString) throws IOException {
+ this.bitString =
+ new BitArray(bitString.length * 8, bitString).toBooleanArray();
+ this.extensionId = PKIXExtensions.KeyUsage_Id;
+ this.critical = true;
+ encodeThis();
+ }
+
+ /**
+ * Create a KeyUsageExtension with the passed bit settings. The criticality
+ * is set to true.
+ *
+ * @param bitString the bits to be set for the extension.
+ */
+ public KeyUsageExtension(boolean critical, boolean[] bitString) throws IOException {
+ this.bitString = bitString;
+ this.extensionId = PKIXExtensions.KeyUsage_Id;
+ this.critical = critical;
+ encodeThis();
+ }
+
+ public KeyUsageExtension(boolean[] bitString) throws IOException {
+ this.bitString = bitString;
+ this.extensionId = PKIXExtensions.KeyUsage_Id;
+ this.critical = true;
+ encodeThis();
+ }
+
+ /**
+ * Create a KeyUsageExtension with the passed bit settings. The criticality
+ * is set to true.
+ *
+ * @param bitString the bits to be set for the extension.
+ */
+ public KeyUsageExtension(BitArray bitString) throws IOException {
+ this.bitString = bitString.toBooleanArray();
+ this.extensionId = PKIXExtensions.KeyUsage_Id;
+ this.critical = true;
+ encodeThis();
+ }
+
+ /**
+ * Create the extension from the passed DER encoded value of the same.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param value Array of DER encoded bytes of the actual value.
+ * @exception IOException on error.
+ */
+ public KeyUsageExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = PKIXExtensions.KeyUsage_Id;
+ this.critical = critical.booleanValue();
+ /*
+ * The following check should be activated again after
+ * the PKIX profiling work becomes standard and the check
+ * is not a barrier to interoperability !
+ * if (!this.critical) {
+ * throw new IOException("KeyUsageExtension not marked critical,"
+ * + " invalid profile.");
+ * }
+ */
+ int len = Array.getLength(value);
+ byte[] extValue = new byte[len];
+ for (int i = 0; i < len; i++) {
+ extValue[i] = Array.getByte(value, i);
+ }
+ this.extensionValue = extValue;
+ DerValue val = new DerValue(extValue);
+ this.bitString = val.getUnalignedBitString().toBooleanArray();
+ }
+
+ /**
+ * Create a default key usage.
+ */
+ public KeyUsageExtension() {
+ extensionId = PKIXExtensions.KeyUsage_Id;
+ critical = true;
+ bitString = new boolean[0];
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ clearValue();
+ if (!(obj instanceof Boolean)) {
+ throw new IOException("Attribute must be of type Boolean.");
+ }
+ boolean val = ((Boolean) obj).booleanValue();
+ if (name.equalsIgnoreCase(DIGITAL_SIGNATURE)) {
+ set(0, val);
+ } else if (name.equalsIgnoreCase(NON_REPUDIATION)) {
+ set(1, val);
+ } else if (name.equalsIgnoreCase(KEY_ENCIPHERMENT)) {
+ set(2, val);
+ } else if (name.equalsIgnoreCase(DATA_ENCIPHERMENT)) {
+ set(3, val);
+ } else if (name.equalsIgnoreCase(KEY_AGREEMENT)) {
+ set(4, val);
+ } else if (name.equalsIgnoreCase(KEY_CERTSIGN)) {
+ set(5, val);
+ } else if (name.equalsIgnoreCase(CRL_SIGN)) {
+ set(6, val);
+ } else if (name.equalsIgnoreCase(ENCIPHER_ONLY)) {
+ set(7, val);
+ } else if (name.equalsIgnoreCase(DECIPHER_ONLY)) {
+ set(8, val);
+ } else {
+ throw new IOException("Attribute name not recognized by"
+ + " CertAttrSet:KeyUsage.");
+ }
+ encodeThis();
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(DIGITAL_SIGNATURE)) {
+ return new Boolean(isSet(0));
+ } else if (name.equalsIgnoreCase(NON_REPUDIATION)) {
+ return new Boolean(isSet(1));
+ } else if (name.equalsIgnoreCase(KEY_ENCIPHERMENT)) {
+ return new Boolean(isSet(2));
+ } else if (name.equalsIgnoreCase(DATA_ENCIPHERMENT)) {
+ return new Boolean(isSet(3));
+ } else if (name.equalsIgnoreCase(KEY_AGREEMENT)) {
+ return new Boolean(isSet(4));
+ } else if (name.equalsIgnoreCase(KEY_CERTSIGN)) {
+ return new Boolean(isSet(5));
+ } else if (name.equalsIgnoreCase(CRL_SIGN)) {
+ return new Boolean(isSet(6));
+ } else if (name.equalsIgnoreCase(ENCIPHER_ONLY)) {
+ return new Boolean(isSet(7));
+ } else if (name.equalsIgnoreCase(DECIPHER_ONLY)) {
+ return new Boolean(isSet(8));
+ } else {
+ throw new IOException("Attribute name not recognized by"
+ + " CertAttrSet:KeyUsage.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(DIGITAL_SIGNATURE)) {
+ set(0, false);
+ } else if (name.equalsIgnoreCase(NON_REPUDIATION)) {
+ set(1, false);
+ } else if (name.equalsIgnoreCase(KEY_ENCIPHERMENT)) {
+ set(2, false);
+ } else if (name.equalsIgnoreCase(DATA_ENCIPHERMENT)) {
+ set(3, false);
+ } else if (name.equalsIgnoreCase(KEY_AGREEMENT)) {
+ set(4, false);
+ } else if (name.equalsIgnoreCase(KEY_CERTSIGN)) {
+ set(5, false);
+ } else if (name.equalsIgnoreCase(CRL_SIGN)) {
+ set(6, false);
+ } else if (name.equalsIgnoreCase(ENCIPHER_ONLY)) {
+ set(7, false);
+ } else if (name.equalsIgnoreCase(DECIPHER_ONLY)) {
+ set(8, false);
+ } else {
+ throw new IOException("Attribute name not recognized by"
+ + " CertAttrSet:KeyUsage.");
+ }
+ }
+
+ /**
+ * Returns a printable representation of the KeyUsage.
+ */
+ public String toString() {
+ String s = super.toString() + "KeyUsage [\n";
+
+ try {
+ if (isSet(0)) {
+ s += " DigitalSignature\n";
+ }
+ if (isSet(1)) {
+ s += " Non_repudiation\n";
+ }
+ if (isSet(2)) {
+ s += " Key_Encipherment\n";
+ }
+ if (isSet(3)) {
+ s += " Data_Encipherment\n";
+ }
+ if (isSet(4)) {
+ s += " Key_Agreement\n";
+ }
+ if (isSet(5)) {
+ s += " Key_CertSign\n";
+ }
+ if (isSet(6)) {
+ s += " Crl_Sign\n";
+ }
+ if (isSet(7)) {
+ s += " Encipher_Only\n";
+ }
+ if (isSet(8)) {
+ s += " Decipher_Only\n";
+ }
+ } catch (ArrayIndexOutOfBoundsException ex) {
+ }
+
+ s += "]\n";
+
+ return (s);
+ }
+
+ /**
+ * Decode the extension from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ /**
+ * Write the extension to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ if (this.extensionValue == null) {
+ this.extensionId = PKIXExtensions.KeyUsage_Id;
+ this.critical = true;
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(DIGITAL_SIGNATURE);
+ elements.addElement(NON_REPUDIATION);
+ elements.addElement(KEY_ENCIPHERMENT);
+ elements.addElement(DATA_ENCIPHERMENT);
+ elements.addElement(KEY_AGREEMENT);
+ elements.addElement(KEY_CERTSIGN);
+ elements.addElement(CRL_SIGN);
+ elements.addElement(ENCIPHER_ONLY);
+ elements.addElement(DECIPHER_ONLY);
+
+ return (elements.elements());
+ }
+
+ public boolean[] getBits() {
+ return (boolean[]) bitString.clone();
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/LdapDNStrConverter.java b/base/util/src/netscape/security/x509/LdapDNStrConverter.java
new file mode 100644
index 000000000..a8cb87813
--- /dev/null
+++ b/base/util/src/netscape/security/x509/LdapDNStrConverter.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 netscape.security.x509;
+
+import java.io.IOException;
+
+/**
+ * Abstract class that converts a Ldap DN String to an X500Name, RDN or AVA
+ * and vice versa, except the string is a java string in unicode.
+ *
+ * @author Lily Hsiao, Slava Galperin at Netscape Communications, Inc.
+ */
+
+public abstract class LdapDNStrConverter {
+ //
+ // public parsing methods.
+ //
+
+ /**
+ * Converts a Ldap DN string to a X500Name object.
+ *
+ * @param dn a Ldap DN String.
+ *
+ * @return an X500Name object for the Ldap DN String.
+ */
+ public abstract X500Name parseDN(String dn)
+ throws IOException;
+
+ /**
+ * Like parseDN with a specified DER encoding order for Directory Strings.
+ */
+ public abstract X500Name parseDN(String dn, byte[] tags)
+ throws IOException;
+
+ /**
+ * Converts a Ldap DN string to a RDN object.
+ *
+ * @param rdn a Ldap DN String
+ *
+ * @return an RDN object.
+ */
+ public abstract RDN parseRDN(String rdn)
+ throws IOException;
+
+ /**
+ * Like parseRDN with a specified DER encoding order for Directory Strings.
+ */
+ public abstract RDN parseRDN(String rdn, byte[] tags)
+ throws IOException;
+
+ /**
+ * Converts a Ldap DN string to a AVA object.
+ *
+ * @param ava a Ldap DN string.
+ * @return an AVA object.
+ */
+ public abstract AVA parseAVA(String ava)
+ throws IOException;
+
+ /**
+ * Like parseAVA with a specified DER encoding order for Directory Strings.
+ */
+ public abstract AVA parseAVA(String rdn, byte[] tags)
+ throws IOException;
+
+ //
+ // public encoding methods.
+ //
+
+ /**
+ * Converts a X500Name object to a Ldap dn string.
+ *
+ * @param dn an X500Name object.
+ * @return a Ldap DN String.
+ */
+ public abstract String encodeDN(X500Name dn) throws IOException;
+
+ /**
+ * Converts an RDN object to a Ldap dn string.
+ *
+ * @param rdn an RDN object.
+ * @return a Ldap dn string.
+ */
+ public abstract String encodeRDN(RDN rdn) throws IOException;
+
+ /**
+ * Converts an AVA object to a Ldap dn string.
+ *
+ * @param ava An AVA object.
+ * @return A Ldap dn string.
+ */
+ public abstract String encodeAVA(AVA ava) throws IOException;
+
+ //
+ // public static methods
+ //
+
+ /**
+ * Gets a global default Ldap DN String converter.
+ * Currently it is LdapV3DNStrConverter object using the default
+ * X500NameAttrMap and accepts unknown OIDs.
+ *
+ * @see netscape.security.x509.LdapV3DNStrConverter
+ *
+ * @return The global default LdapDNStrConverter instance.
+ */
+ public static LdapDNStrConverter getDefault() {
+ return defaultConverter;
+ }
+
+ /**
+ * Set the global default LdapDNStrConverter object.
+ *
+ * @param defConverter A LdapDNStrConverter object to become
+ * the global default.
+ */
+ public static void setDefault(LdapDNStrConverter defConverter) {
+ if (defConverter == null)
+ throw new IllegalArgumentException(
+ "The default Ldap DN String converter cannot be set to null.");
+ defaultConverter = defConverter;
+ }
+
+ //
+ // private static variables
+ //
+
+ private static LdapDNStrConverter defaultConverter = new LdapV3DNStrConverter();
+}
diff --git a/base/util/src/netscape/security/x509/LdapV3DNStrConverter.java b/base/util/src/netscape/security/x509/LdapV3DNStrConverter.java
new file mode 100644
index 000000000..1245cc6bd
--- /dev/null
+++ b/base/util/src/netscape/security/x509/LdapV3DNStrConverter.java
@@ -0,0 +1,824 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.ByteArrayOutputStream;
+import java.io.CharArrayWriter;
+import java.io.IOException;
+import java.io.PushbackReader;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.Arrays;
+import java.util.Vector;
+
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * A converter that converts Ldap v3 DN strings as specified in
+ * draft-ietf-asid-ldapv3-dn-03.txt to a X500Name, RDN or AVA and
+ * vice versa.
+ *
+ * @see LdapDNStrConverter
+ * @see X500Name
+ * @see RDN
+ * @see AVA
+ * @see X500NameAttrMap
+ *
+ * @author Lily Hsiao, Slava Galperin at Netscape Communications, Inc.
+ */
+
+public class LdapV3DNStrConverter extends LdapDNStrConverter {
+ //
+ // Constructors
+ //
+
+ /**
+ * Constructs a LdapV3DNStrConverter using the global default
+ * X500NameAttrMap and accept OIDs not in the default X500NameAttrMap.
+ *
+ * @see X500NameAttrMap
+ */
+ public LdapV3DNStrConverter() {
+ attrMap = X500NameAttrMap.getDefault();
+
+ acceptUnknownOids = true;
+ }
+
+ /**
+ * Constructs a LdapV3DNStrConverter using the specified X500NameAttrMap
+ * and a boolean indicating whether to accept OIDs not listed in the
+ * X500NameAttrMap.
+ *
+ * @param attributeMap a X500NameAttrMap
+ * @param doAcceptUnknownOids whether to convert unregistered OIDs
+ * (oids not in the X500NameAttrMap)
+ * @see X500NameAttrMap
+ */
+ public LdapV3DNStrConverter(X500NameAttrMap attributeMap,
+ boolean doAcceptUnknownOids) {
+ attrMap = attributeMap;
+ acceptUnknownOids = doAcceptUnknownOids;
+
+ }
+
+ //
+ // public parsing methods
+ // From LdapDNStrConverter interface
+ //
+
+ /**
+ * Parse a Ldap v3 DN string to a X500Name.
+ *
+ * @param dn a LDAP v3 DN String
+ * @return a X500Name
+ * @exception IOException if an error occurs during the conversion.
+ */
+ public X500Name parseDN(String dn)
+ throws IOException {
+ return parseDN(dn, null);
+ }
+
+ /**
+ * Like parseDN(String) with a DER encoding order given as argument for
+ * Directory Strings.
+ */
+ public X500Name parseDN(String dn, byte[] encodingOrder)
+ throws IOException {
+ StringReader dn_reader = new StringReader(dn);
+ PushbackReader in = new PushbackReader(dn_reader, 5);
+
+ return parseDN(in, encodingOrder);
+ }
+
+ /**
+ * Parse a Ldap v3 DN string with a RDN component to a RDN
+ *
+ * @param rdn a LDAP v3 DN String
+ * @return a RDN
+ * @exception IOException if an error occurs during the conversion.
+ */
+ public RDN parseRDN(String rdn)
+ throws IOException {
+ return parseRDN(rdn, null);
+ }
+
+ /**
+ * Like parseRDN(String) with a DER encoding order given as argument for
+ * Directory Strings.
+ */
+ public RDN parseRDN(String rdn, byte[] encodingOrder)
+ throws IOException {
+ StringReader rdn_reader = new StringReader(rdn);
+ PushbackReader in = new PushbackReader(rdn_reader, 5);
+
+ return parseRDN(in, null);
+ }
+
+ /**
+ * Parse a Ldap v3 DN string with a AVA component to a AVA.
+ *
+ * @param ava a LDAP v3 DN string
+ * @return a AVA
+ */
+ public AVA parseAVA(String ava)
+ throws IOException {
+ return parseAVA(ava, null);
+ }
+
+ /**
+ * Like parseDN(String) with a DER encoding order given as argument for
+ * Directory Strings.
+ */
+ public AVA parseAVA(String ava, byte[] encodingOrder)
+ throws IOException {
+ StringReader ava_reader = new StringReader(ava);
+ PushbackReader in = new PushbackReader(ava_reader, 5);
+
+ return parseAVA(in, encodingOrder);
+ }
+
+ //
+ // public parsing methods called by other methods.
+ //
+
+ /**
+ * Parses a Ldap DN string in a string reader to a X500Name.
+ *
+ * @param in Pushback string reader for a Ldap DN string.
+ * The pushback reader must have a pushback buffer size > 2.
+ *
+ * @return a X500Name
+ *
+ * @exception IOException if any reading or parsing error occurs.
+ */
+ public X500Name parseDN(PushbackReader in)
+ throws IOException {
+ return parseDN(in, null);
+ }
+
+ /**
+ * Like parseDN(PushbackReader in) with a DER encoding order given as
+ * argument for Directory Strings.
+ */
+ public X500Name parseDN(PushbackReader in, byte[] encodingOrder)
+ throws IOException {
+ RDN rdn;
+ int lastChar;
+ Vector<RDN> rdnVector = new Vector<RDN>();
+ RDN names[];
+ int i, j;
+
+ do {
+ rdn = parseRDN(in, encodingOrder);
+ rdnVector.addElement(rdn);
+ lastChar = in.read();
+ } while (lastChar == ',' || lastChar == ';');
+
+ names = new RDN[rdnVector.size()];
+ for (i = 0, j = rdnVector.size() - 1; i < rdnVector.size(); i++, j--)
+ names[j] = (RDN) rdnVector.elementAt(i);
+ return new X500Name(names);
+ }
+
+ /**
+ * Parses Ldap DN string with a rdn component
+ * from a string reader to a RDN. The string reader will point
+ * to the separator after the rdn component or -1 if at end of string.
+ *
+ * @param in Pushback string reader containing a Ldap DN string with
+ * at least one rdn component.
+ * The pushback reader must have a pushback buffer size > 2.
+ *
+ * @return RDN object of the first rdn component in the Ldap DN string.
+ *
+ * @exception IOException if any read or parse error occurs.
+ */
+ public RDN parseRDN(PushbackReader in)
+ throws IOException {
+ return parseRDN(in, null);
+ }
+
+ /**
+ * Like parseRDN(PushbackReader) with a DER encoding order given as
+ * argument for Directory Strings.
+ */
+ public RDN parseRDN(PushbackReader in, byte[] encodingOrder)
+ throws IOException {
+ Vector<AVA> avaVector = new Vector<AVA>();
+ AVA ava;
+ int lastChar;
+ AVA assertion[];
+
+ do {
+ ava = parseAVA(in, encodingOrder);
+ avaVector.addElement(ava);
+ lastChar = in.read();
+ } while (lastChar == '+');
+
+ if (lastChar != -1)
+ in.unread(lastChar);
+
+ assertion = new AVA[avaVector.size()];
+ for (int i = 0; i < avaVector.size(); i++)
+ assertion[i] = (AVA) avaVector.elementAt(i);
+ return new RDN(assertion);
+ }
+
+ /**
+ * Parses a Ldap DN string with a AVA component
+ * from a string reader to an AVA. The string reader will point
+ * to the AVA separator after the ava string or -1 if end of string.
+ *
+ * @param in a Pushback reader containg a Ldap string with
+ * at least one AVA component.
+ * The Pushback reader must have a pushback buffer size > 2.
+ *
+ * @return AVA object of the first AVA component in the Ldap DN string.
+ */
+ public AVA parseAVA(PushbackReader in)
+ throws IOException {
+ return parseAVA(in, null);
+ }
+
+ /**
+ * Like parseAVA(PushbackReader) with a DER encoding order given as
+ * argument for Directory Strings.
+ */
+ public AVA parseAVA(PushbackReader in, byte[] encodingOrder)
+ throws IOException {
+ int c;
+ ObjectIdentifier oid;
+ DerValue value;
+ StringBuffer keywordBuf;
+ StringBuffer valueBuf;
+ ByteArrayOutputStream berStream;
+ char hexChar1, hexChar2;
+ CharArrayWriter hexCharsBuf;
+ String endChars;
+
+ /* First get the keyword indicating the attribute's type,
+ * and map it to the appropriate OID.
+ */
+ keywordBuf = new StringBuffer();
+ for (;;) {
+ c = in.read();
+ if (c == '=')
+ break;
+ if (c == -1) {
+ throw new IOException("Bad AVA format: Missing '='");
+ }
+ keywordBuf.append((char) c);
+ }
+ oid = parseAVAKeyword(keywordBuf.toString());
+
+ /* Now parse the value. "#hex", a quoted string, or a string
+ * terminated by "+", ",", ";", ">". Whitespace before or after
+ * the value is stripped.
+ */
+ for (c = in.read(); c == ' '; c = in.read())
+ continue;
+ if (c == -1)
+ throw new IOException("Bad AVA format: Missing attribute value");
+
+ if (c == '#') {
+ /*
+ * NOTE per LDAPv3 dn string ietf standard the value represented
+ * by this form is a BER value. But we only support DER value here
+ * which is only a form of BER.
+ */
+ berStream = new ByteArrayOutputStream();
+ int b;
+ for (;;) {
+ hexChar1 = (char) (c = in.read());
+ if (c == -1 || octoEndChars.indexOf(c) > 0) // end of value
+ break;
+ hexChar2 = (char) (c = in.read());
+ if (hexDigits.indexOf(hexChar1) == -1 ||
+ hexDigits.indexOf(hexChar2) == -1)
+ throw new IOException("Bad AVA value: bad hex value.");
+ b = (Character.digit(hexChar1, 16) << 4) +
+ Character.digit(hexChar2, 16);
+ berStream.write(b);
+ }
+ if (berStream.size() == 0)
+ throw new IOException("bad AVA format: invalid hex value");
+
+ value = parseAVAValue(berStream.toByteArray(), oid);
+
+ while (c == ' ' && c != -1)
+ c = in.read();
+ } else {
+ valueBuf = new StringBuffer();
+ boolean quoted = false;
+ if (c == '"') {
+ quoted = true;
+ endChars = quotedEndChars;
+ if ((c = in.read()) == -1)
+ throw new IOException("Bad AVA format: Missing attrValue");
+ } else {
+ endChars = valueEndChars;
+ }
+
+ // QUOTATION * ( quotechar / pair ) QUOTATION
+ // quotechar = any character except '\' or QUOTATION
+ // pair = '\' ( special | '\' | QUOTATION | hexpair )
+ while (c != -1 && endChars.indexOf(c) == -1) {
+ if (c == '\\') {
+ if ((c = in.read()) == -1)
+ throw new IOException("Bad AVA format: expecting " +
+ "escaped char.");
+ // expect escaping of special chars, space and CR.
+ if (specialChars.indexOf((char) c) != -1 || c == '\n' ||
+ c == '\\' || c == '"' || c == ' ') {
+ valueBuf.append((char) c);
+ } else if (hexDigits.indexOf(c) != -1) {
+ hexCharsBuf = new CharArrayWriter();
+ // handle sequence of '\' hexpair
+ do {
+ hexChar1 = (char) c;
+ hexChar2 = (char) (c = in.read());
+ if (hexDigits.indexOf((char) c) == -1)
+ throw new IOException("Bad AVA format: " +
+ "invalid escaped hex pair");
+ hexCharsBuf.write(hexChar1);
+ hexCharsBuf.write(hexChar2);
+ // read ahead to next '\' hex-char if any.
+ if ((c = in.read()) == -1)
+ break;
+ if (c != '\\') {
+ in.unread(c);
+ break;
+ }
+ if ((c = in.read()) == -1)
+ throw new IOException("Bad AVA format: " +
+ "expecting escaped char.");
+ if (hexDigits.indexOf((char) c) == -1) {
+ in.unread(c);
+ in.unread((int) '\\');
+ break;
+ }
+ } while (true);
+ valueBuf.append(
+ getStringFromHexpairs(hexCharsBuf.toCharArray()));
+ } else {
+ throw new IOException("Bad AVA format: " +
+ "invalid escaping");
+ }
+ } else
+ valueBuf.append((char) c);
+ c = in.read();
+ }
+
+ value = parseAVAValue(
+ valueBuf.toString().trim(), oid, encodingOrder);
+
+ if (quoted) { // move to next non-white space
+ do {
+ c = in.read();
+ } while (c == ' ');
+ if (c != -1 && valueEndChars.indexOf(c) == -1)
+ throw new IOException(
+ "Bad AVA format: separator expected at end of ava.");
+ }
+ }
+
+ if (c != -1)
+ in.unread(c);
+
+ return new AVA(oid, value);
+ }
+
+ /**
+ * Converts a AVA keyword from a Ldap DN string to an ObjectIdentifier
+ * from the attribute map or, if this keyword is an OID not
+ * in the attribute map, create a new ObjectIdentifier for the keyword
+ * if acceptUnknownOids is true.
+ *
+ * @param avaKeyword AVA keyword from a Ldap DN string.
+ *
+ * @return a ObjectIdentifier object
+ * @exception IOException if the keyword is an OID not in the attribute
+ * map and acceptUnknownOids is false, or
+ * if an error occurs during conversion.
+ */
+ public ObjectIdentifier parseAVAKeyword(String avaKeyword)
+ throws IOException {
+ String keyword = avaKeyword.toUpperCase().trim();
+ String oid_str = null;
+ ObjectIdentifier oid, new_oid;
+
+ if (Character.digit(keyword.charAt(0), 10) != -1) {
+ // value is an oid string of 1.2.3.4
+ oid_str = keyword;
+ } else if (keyword.startsWith("oid.") || keyword.startsWith("OID.")) {
+ // value is an oid string of oid.1.2.3.4 or OID.1.2...
+ oid_str = keyword.substring(4);
+ }
+
+ if (oid_str != null) {
+ // value is an oid string of 1.2.3.4 or oid.1.2.3.4 or OID.1.2...
+ new_oid = new ObjectIdentifier(oid_str);
+ oid = attrMap.getOid(new_oid);
+ if (oid == null) {
+ if (!acceptUnknownOids)
+ throw new IOException("Unknown AVA OID.");
+ oid = new_oid;
+ }
+ } else {
+ oid = attrMap.getOid(keyword);
+ if (oid == null)
+ throw new IOException("Unknown AVA keyword '" + keyword + "'.");
+ }
+
+ return oid;
+ }
+
+ /**
+ * Converts a AVA value from a Ldap dn string to a
+ * DerValue according the attribute type. For example, a value for
+ * CN, OU or O is expected to be a Directory String and will be converted
+ * to a DerValue of ASN.1 type PrintableString, T61String or
+ * UniversalString. A Directory String is a ASN.1 CHOICE of Printable,
+ * T.61 or Universal string.
+ *
+ * @param avaValueString a attribute value from a Ldap DN string.
+ * @param oid OID of the attribute.
+ *
+ * @return DerValue for the value.
+ *
+ * @exception IOException if an error occurs during conversion.
+ * @see AVAValueConverter
+ */
+ public DerValue parseAVAValue(String avaValueString, ObjectIdentifier oid)
+ throws IOException {
+ return parseAVAValue(avaValueString, oid, null);
+ }
+
+ /**
+ * Like parseAVAValue(String) with a DER encoding order given as argument
+ * for Directory Strings.
+ */
+ public DerValue parseAVAValue(
+ String avaValueString, ObjectIdentifier oid, byte[] encodingOrder)
+ throws IOException {
+ AVAValueConverter valueConverter = attrMap.getValueConverter(oid);
+ if (valueConverter == null) {
+ if (!acceptUnknownOids) {
+ throw new IllegalArgumentException(
+ "Unrecognized OID for AVA value conversion");
+ } else {
+ valueConverter = new GenericValueConverter();
+ }
+ }
+ return valueConverter.getValue(avaValueString, encodingOrder);
+ }
+
+ /**
+ * Converts a value in BER encoding, for example given in octothorpe form
+ * in a Ldap v3 dn string, to a DerValue. Checks if the BER encoded value
+ * is a legal value for the attribute.
+ * <p>
+ * <strong><i>NOTE:</i></strong> only DER encoded values are supported for the BER encoded value.
+ *
+ * @param berValue a value in BER encoding
+ * @param oid ObjectIdentifier of the attribute.
+ *
+ * @return DerValue for the BER encoded value
+ * @exception IOException if an error occurs during conversion.
+ */
+ public DerValue parseAVAValue(byte[] berValue, ObjectIdentifier oid)
+ throws IOException {
+ AVAValueConverter valueConverter = attrMap.getValueConverter(oid);
+ if (valueConverter == null && !acceptUnknownOids) {
+ throw new IllegalArgumentException(
+ "Unrecognized OID for AVA value conversion");
+ } else {
+ valueConverter = new GenericValueConverter();
+ }
+ return valueConverter.getValue(berValue);
+ }
+
+ //
+ // public encoding methods.
+ //
+
+ /**
+ * Converts a X500Name object to a Ldap v3 DN string (except in unicode).
+ *
+ * @param x500name a X500Name
+ *
+ * @return a Ldap v3 DN String (except in unicode).
+ *
+ * @exception IOException if an error is encountered during conversion.
+ */
+ public String encodeDN(X500Name x500name)
+ throws IOException {
+ RDN[] rdns = x500name.getNames();
+ // String fullname = null;
+ StringBuffer fullname = new StringBuffer();
+ String s;
+ int i;
+ if (rdns.length == 0)
+ return "";
+ i = rdns.length - 1;
+ fullname.append(encodeRDN(rdns[i--]));
+ while (i >= 0) {
+ s = encodeRDN(rdns[i--]);
+ fullname.append(",");
+ fullname.append(s);
+ }
+ ;
+ return fullname.toString();
+ }
+
+ /**
+ * Converts a RDN to a Ldap v3 DN string (except in unicode).
+ *
+ * @param rdn a RDN
+ *
+ * @return a LDAP v3 DN string (except in unicode).
+ *
+ * @exception IOException if an error is encountered during conversion.
+ */
+ public String encodeRDN(RDN rdn)
+ throws IOException {
+ AVA[] avas = rdn.getAssertion();
+ // String relname = null;
+ StringBuffer relname = new StringBuffer();
+ String s;
+ int i = 0;
+
+ relname.append(encodeAVA(avas[i++]));
+ while (i < avas.length) {
+ s = encodeAVA(avas[i++]);
+ relname.append("+");
+ relname.append(s);
+ }
+ ;
+ return relname.toString();
+ }
+
+ /**
+ * Converts a AVA to a Ldap v3 DN String (except in unicode).
+ *
+ * @param ava an AVA
+ *
+ * @return a Ldap v3 DN string (except in unicode).
+ *
+ * @exception IOException If an error is encountered during exception.
+ */
+ public String encodeAVA(AVA ava)
+ throws IOException {
+ if (ava == null) {
+ return "";
+ }
+ ObjectIdentifier oid = ava.getOid();
+ DerValue value = ava.getValue();
+ String keyword, valueStr;
+
+ // get attribute name
+
+ keyword = encodeOID(oid);
+ valueStr = encodeValue(value, oid);
+
+ return keyword + "=" + valueStr;
+ }
+
+ /**
+ * Converts an OID to a attribute keyword in a Ldap v3 DN string
+ * - either a keyword if known or a string of "1.2.3.4" syntax.
+ *
+ * @param oid a ObjectIdentifier
+ *
+ * @return a keyword to use in a Ldap V3 DN string.
+ *
+ * @exception IOException if an error is encountered during conversion.
+ */
+ public String encodeOID(ObjectIdentifier oid)
+ throws IOException {
+ String keyword = attrMap.getName(oid);
+ if (keyword == null) {
+ if (acceptUnknownOids)
+ keyword = oid.toString();
+ else
+ throw new IOException("Unknown OID");
+ }
+ return keyword;
+ }
+
+ /**
+ * Converts a value as a DerValue to a string in a Ldap V3 DN String.
+ * If the value cannot be converted to a string it will be encoded in
+ * octothorpe form.
+ *
+ * @param attrValue a value as a DerValue.
+ * @param oid OID for the attribute.
+ * @return a string for the value in a LDAP v3 DN String
+ * @exception IOException if an error occurs during conversion.
+ */
+ public String encodeValue(DerValue attrValue, ObjectIdentifier oid)
+ throws IOException {
+ /*
+ * Construct the value with as little copying and garbage
+ * production as practical.
+ */
+ StringBuffer retval = new StringBuffer(30);
+ int i;
+ String temp = null;
+ AVAValueConverter valueConverter;
+
+ X500NameAttrMap lAttrMap = attrMap;
+
+ if (attrValue.tag == DerValue.tag_UTF8String) {
+ lAttrMap = X500NameAttrMap.getDirDefault();
+
+ }
+
+ valueConverter = lAttrMap.getValueConverter(oid);
+ if (valueConverter == null) {
+ if (acceptUnknownOids)
+ valueConverter = new GenericValueConverter();
+ else
+ throw new IOException(
+ "Unknown AVA type for encoding AVA value");
+ }
+
+ try {
+ temp = valueConverter.getAsString(attrValue);
+
+ if (temp == null) {
+ // convert to octothorpe form.
+ byte data[] = attrValue.toByteArray();
+
+ retval.append('#');
+ for (i = 0; i < data.length; i++) {
+ retval.append(hexDigits.charAt((data[i] >> 4) & 0x0f));
+ retval.append(hexDigits.charAt(data[i] & 0x0f));
+ }
+
+ } else {
+
+ retval.append(encodeString(temp));
+
+ }
+ } catch (IOException e) {
+ throw new IllegalArgumentException("malformed AVA DER Value");
+ }
+
+ return retval.toString();
+ }
+
+ /**
+ * converts a raw value string to a string in Ldap V3 DN string format.
+ *
+ * @param valueStr a 'raw' value string.
+ * @return a attribute value string in Ldap V3 DN string format.
+ */
+ public String encodeString(String valueStr) {
+ int i, j;
+ int len;
+ StringBuffer retval = new StringBuffer();
+
+ /*
+ * generate string according to ldapv3 DN. escaping is used.
+ * Strings generated this way are acceptable by rfc1779
+ * implementations.
+ */
+ len = valueStr.length();
+
+ // get index of first space at the end of the string.
+ for (j = len - 1; j >= 0 && valueStr.charAt(j) == ' '; j--)
+ continue;
+
+ // escape spaces at the beginning of the string.
+ for (i = 0; i <= j && valueStr.charAt(i) == ' '; i++) {
+ retval.append('\\');
+ retval.append(valueStr.charAt(i));
+ }
+
+ // escape special characters in the middle of the string.
+ for (; i <= j; i++) {
+ if (valueStr.charAt(i) == '\\') {
+ retval.append('\\');
+ retval.append(valueStr.charAt(i));
+ } else if (specialChars.indexOf(valueStr.charAt(i)) != -1) {
+ retval.append('\\');
+ retval.append(valueStr.charAt(i));
+ } else if (valueStr.charAt(i) == '"') {
+ retval.append('\\');
+ retval.append(valueStr.charAt(i));
+ } else
+ retval.append(valueStr.charAt(i));
+ }
+
+ // esacape spaces at the end.
+ for (; i < valueStr.length(); i++) {
+ retval.append('\\');
+ retval.append(' ');
+ }
+
+ return retval.toString();
+ }
+
+ //
+ // public get/set methods
+ //
+
+ /**
+ * gets the X500NameAttrMap used by the converter.
+ *
+ * @return X500NameAttrMap used by this converter.
+ */
+ public X500NameAttrMap getAttrMap() {
+ return attrMap;
+ }
+
+ /**
+ * returns true if the converter accepts unregistered attributes i.e.
+ * OIDS not in the X500NameAttrMap.
+ *
+ * @return true if converter converts attributes not in the
+ * X500NameAttrMap.
+ */
+ public boolean getAcceptUnknownOids() {
+ return acceptUnknownOids;
+ }
+
+ //
+ // private and protected variables
+ //
+
+ protected X500NameAttrMap attrMap;
+ protected boolean acceptUnknownOids;
+
+ //
+ // private and protected static variables & methods.
+ //
+
+ protected static final String specialChars = ",+=<>#;";
+
+ protected static final String valueEndChars = "+,;>";
+ protected static final String quotedEndChars = "\"";
+ protected static final String octoEndChars = " " + valueEndChars;
+
+ /*
+ * Values that aren't printable strings are emitted as BER-encoded
+ * hex data.
+ */
+ protected static final String hexDigits = "0123456789ABCDEFabcdef";
+
+ /**
+ * Parse a sequence of hex pairs, each pair a UTF8 byte to a java string.
+ * For example, "4C75C48D" is "Luc", the last c with caron.
+ */
+ protected static char[] getStringFromHexpairs(char[] hexPairs) throws UnsupportedEncodingException {
+ try {
+ byte[] buffer = new byte[hexPairs.length / 2];
+
+ for (int i = 0; i < buffer.length; i++) {
+ buffer[i] = (byte)
+ ((Character.digit(hexPairs[i * 2], 16) << 4) +
+ Character.digit(hexPairs[i * 2 + 1], 16));
+ }
+
+ Charset charset = Charset.forName("UTF-8");
+ CharsetDecoder decoder = charset.newDecoder();
+
+ CharBuffer charBuffer = decoder.decode(ByteBuffer.wrap(buffer));
+
+ return Arrays.copyOfRange(charBuffer.array(),
+ charBuffer.arrayOffset(), charBuffer.arrayOffset() + charBuffer.limit());
+
+ } catch (UnsupportedCharsetException e) {
+ throw new UnsupportedEncodingException(
+ "No UTF8 byte to char converter to use for " +
+ "parsing LDAP DN String");
+
+ } catch (CharacterCodingException e) {
+ throw new IllegalArgumentException(
+ "Invalid hex pair in LDAP DN String.");
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/x509/NSCCommentExtension.java b/base/util/src/netscape/security/x509/NSCCommentExtension.java
new file mode 100644
index 000000000..0912d5b0c
--- /dev/null
+++ b/base/util/src/netscape/security/x509/NSCCommentExtension.java
@@ -0,0 +1,230 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.util.PrettyPrintFormat;
+
+/**
+ * This class defines the NSCCommentExtension
+ *
+ * @author asondhi
+ * @see Extension
+ * @see CertAttrSet
+ */
+public class NSCCommentExtension extends Extension
+ implements CertAttrSet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4066287070285105375L;
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT = "x509.info.extensions.CommentExtension";
+ /**
+ * Attribute names.
+ */
+ public static final String NAME = "NSCCommentExtension";
+ public static final String INFOS = "infos";
+ public static final ObjectIdentifier OID =
+ new ObjectIdentifier("2.16.840.1.113730.1.13");
+ public String mComment = null;
+
+ // Private data members
+ private Vector<Object> mInfos;
+
+ private PrettyPrintFormat pp = new PrettyPrintFormat(":");
+
+ // Encode this extension value
+ private void encodeThis() throws IOException {
+ DerOutputStream os = new DerOutputStream();
+
+ os.putIA5String(mComment);
+ // DerOutputStream tmp = new DerOutputStream();
+ // os.write(DerValue.tag_Sequence,tmp);
+ extensionValue = os.toByteArray();
+ }
+
+ /**
+ * Create a NSCCommentExtension with the Vector of CertificatePolicyInfo.
+ *
+ * @param infos the Vector of CertificatePolicyInfo.
+ */
+ public NSCCommentExtension(boolean critical, String comment) throws IOException {
+ this.mComment = comment;
+ this.extensionId = new ObjectIdentifier("2.16.840.1.113730.1.13");
+ this.critical = critical;
+ encodeThis();
+ }
+
+ /**
+ * Create a default NSCCommentExtension.
+ */
+ public NSCCommentExtension(boolean critical) {
+ this.extensionId = new ObjectIdentifier("2.16.840.1.113730.1.13");
+ this.critical = critical;
+ mInfos = new Vector<Object>(1, 1);
+ }
+
+ /**
+ * Create the extension from the passed DER encoded value.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param value Array of DER encoded bytes of the actual value.
+ * @exception IOException on error.
+ */
+ public NSCCommentExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = new ObjectIdentifier("2.16.840.1.113730.1.13");
+
+ this.critical = critical.booleanValue();
+
+ int len = Array.getLength(value);
+ byte[] extValue = new byte[len];
+ for (int i = 0; i < len; i++) {
+ extValue[i] = Array.getByte(value, i);
+ }
+ this.extensionValue = extValue;
+ DerValue val = new DerValue(extValue);
+
+ mComment = val.getIA5String();
+ }
+
+ /**
+ * Returns a printable representation of the policy extension.
+ */
+ public String toString() {
+ if (mInfos == null)
+ return "";
+ String s = super.toString() + "Netscape Comment [\n"
+ + mInfos.toString() + "]\n";
+
+ return (s);
+ }
+
+ public String toPrint(int indent) {
+ String s;
+ s = "Comment :\n" + pp.indent(indent + 4) +
+ ((mComment == null) ? "" : mComment.trim()) + "\n";
+
+ return (s);
+ }
+
+ /**
+ * Write the extension to the OutputStream.
+ *
+ * @param out the OutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ if (extensionValue == null) {
+ extensionId = new ObjectIdentifier("2.16.840.1.113730.1.13");
+ critical = false;
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Decode the extension from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ public String getComment() {
+ return mComment;
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ @SuppressWarnings("unchecked")
+ public void set(String name, Object obj) throws IOException {
+ clearValue();
+ if (name.equalsIgnoreCase(INFOS)) {
+ if (!(obj instanceof Vector)) {
+ throw new IOException("Attribute value should be of" +
+ " type Vector.");
+ }
+ mInfos = (Vector<Object>) obj;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:NSCCommentExtension.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(INFOS)) {
+ return (mInfos);
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:NSCCommentExtension.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(INFOS)) {
+ mInfos = null;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:NSCCommentExtension.");
+ }
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(INFOS);
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+
+}
diff --git a/base/util/src/netscape/security/x509/NameConstraintsExtension.java b/base/util/src/netscape/security/x509/NameConstraintsExtension.java
new file mode 100644
index 000000000..948d0d8c9
--- /dev/null
+++ b/base/util/src/netscape/security/x509/NameConstraintsExtension.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.PrettyPrintFormat;
+
+/**
+ * This class defines the Name Constraints Extension.
+ * <p>
+ * The name constraints extension provides permitted and excluded subtrees that place restrictions on names that may be
+ * included within a certificate issued by a given CA. Restrictions may apply to the subject distinguished name or
+ * subject alternative names. Any name matching a restriction in the excluded subtrees field is invalid regardless of
+ * information appearing in the permitted subtrees.
+ * <p>
+ * The ASN.1 syntax for this is:
+ *
+ * <pre>
+ * NameConstraints ::= SEQUENCE {
+ * permittedSubtrees [0] GeneralSubtrees OPTIONAL,
+ * excludedSubtrees [1] GeneralSubtrees OPTIONAL
+ * }
+ * GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
+ * GeneralSubtree ::== SEQUENCE {
+ * base GeneralName,
+ * minimum [0] BaseDistance DEFAULT 0,
+ * maximum [1] BaseDistance OPTIONAL }
+ * BaseDistance ::== INTEGER (0..MAX)
+ * </pre>
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.10
+ * @see Extension
+ * @see CertAttrSet
+ */
+public class NameConstraintsExtension extends Extension
+ implements CertAttrSet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3506940192931244539L;
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT = "x509.info.extensions.NameConstraints";
+ /**
+ * Attribute names.
+ */
+ public static final String NAME = "NameConstraints";
+ public static final String PERMITTED_SUBTREES = "permitted_subtrees";
+ public static final String EXCLUDED_SUBTREES = "excluded_subtrees";
+
+ // Private data members
+ private static final byte TAG_PERMITTED = 0;
+ private static final byte TAG_EXCLUDED = 1;
+
+ private GeneralSubtrees permitted;
+ private GeneralSubtrees excluded;
+
+ private PrettyPrintFormat pp = new PrettyPrintFormat(":");
+
+ // Encode this extension value.
+ private void encodeThis() throws IOException {
+ DerOutputStream seq = new DerOutputStream();
+
+ DerOutputStream tagged = new DerOutputStream();
+ if ((permitted != null) && (permitted.getSubtrees().size() > 0)) {
+ DerOutputStream tmp = new DerOutputStream();
+ permitted.encode(tmp);
+ tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
+ true, TAG_PERMITTED), tmp);
+ }
+ if ((excluded != null) && (excluded.getSubtrees().size() > 0)) {
+ DerOutputStream tmp = new DerOutputStream();
+ excluded.encode(tmp);
+ tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
+ true, TAG_EXCLUDED), tmp);
+ }
+ if (permitted == null && excluded == null) {
+ extensionValue = null; // no need to encode this extension
+ } else {
+ seq.write(DerValue.tag_Sequence, tagged);
+ this.extensionValue = seq.toByteArray();
+ }
+ }
+
+ /**
+ * The default constructor for this class. Either parameter
+ * can be set to null to indicate it is omitted but both
+ * cannot be null.
+ *
+ * @param permitted the permitted GeneralSubtrees (null for optional).
+ * @param excluded the excluded GeneralSubtrees (null for optional).
+ */
+ public NameConstraintsExtension(GeneralSubtrees permitted,
+ GeneralSubtrees excluded)
+ throws IOException {
+ init(false, permitted, excluded);
+ }
+
+ public NameConstraintsExtension(boolean critical,
+ GeneralSubtrees permitted, GeneralSubtrees excluded)
+ throws IOException {
+ init(critical, permitted, excluded);
+ }
+
+ private void init(boolean critical,
+ GeneralSubtrees permitted, GeneralSubtrees excluded)
+ throws IOException {
+ if (permitted == null && excluded == null) {
+ throw new IOException("NameConstraints: Invalid arguments");
+ }
+ this.permitted = permitted;
+ this.excluded = excluded;
+
+ this.extensionId = PKIXExtensions.NameConstraints_Id;
+ this.critical = critical;
+ encodeThis();
+ }
+
+ /**
+ * Create the extension from the passed DER encoded value.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param value Array of DER encoded bytes of the actual value.
+ * @exception IOException on error.
+ */
+ public NameConstraintsExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = PKIXExtensions.NameConstraints_Id;
+ this.critical = critical.booleanValue();
+
+ if (!(value instanceof byte[]))
+ throw new IOException("Illegal argument type");
+
+ int len = Array.getLength(value);
+ byte[] extValue = new byte[len];
+ System.arraycopy(value, 0, extValue, 0, len);
+
+ this.extensionValue = extValue;
+ DerValue val = new DerValue(extValue);
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding for" +
+ " NameConstraintsExtension.");
+ }
+
+ // NB. this is always encoded with the IMPLICIT tag
+ // The checks only make sense if we assume implicit tagging,
+ // with explicit tagging the form is always constructed.
+ while (val.data.available() != 0) {
+ DerValue opt = val.data.getDerValue();
+
+ if (opt.isContextSpecific(TAG_PERMITTED) && opt.isConstructed()) {
+ if (permitted != null) {
+ throw new IOException("Duplicate permitted " +
+ "GeneralSubtrees in NameConstraintsExtension.");
+ }
+ opt.resetTag(DerValue.tag_Sequence);
+ permitted = new GeneralSubtrees(opt);
+
+ } else if (opt.isContextSpecific(TAG_EXCLUDED) &&
+ opt.isConstructed()) {
+ if (excluded != null) {
+ throw new IOException("Duplicate excluded " +
+ "GeneralSubtrees in NameConstraintsExtension.");
+ }
+ opt.resetTag(DerValue.tag_Sequence);
+ excluded = new GeneralSubtrees(opt);
+ } else
+ throw new IOException("Invalid encoding of " +
+ "NameConstraintsExtension.");
+ }
+ }
+
+ /**
+ * Return the printable string.
+ */
+ public String toString() {
+ return (super.toString() + "NameConstraints: [" +
+ ((permitted == null) ? "" :
+ ("\n Permitted:" + permitted.toString())) +
+ ((excluded == null) ? "" :
+ ("\n Excluded:" + excluded.toString())) + " ]\n");
+ }
+
+ public String toPrint(int indent) {
+ return ("GeneralSubtrees: " +
+ ((permitted == null) ? "" :
+ ("\n" + pp.indent(indent + 2) + "Permitted:" + permitted.toPrint(indent + 4))) +
+ ((excluded == null) ? "" :
+ ("\n" + pp.indent(indent + 2) + "Excluded:" + excluded.toPrint(indent + 4))) + "\n");
+
+ }
+
+ /**
+ * Decode the extension from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ /**
+ * Write the extension to the OutputStream.
+ *
+ * @param out the OutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ if (this.extensionValue == null) {
+ this.extensionId = PKIXExtensions.NameConstraints_Id;
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ clearValue();
+ if (name.equalsIgnoreCase(PERMITTED_SUBTREES)) {
+ if (!(obj instanceof GeneralSubtrees)) {
+ throw new IOException("Attribute value should be"
+ + " of type GeneralSubtrees.");
+ }
+ permitted = (GeneralSubtrees) obj;
+ } else if (name.equalsIgnoreCase(EXCLUDED_SUBTREES)) {
+ if (!(obj instanceof GeneralSubtrees)) {
+ throw new IOException("Attribute value should be "
+ + "of type GeneralSubtrees.");
+ }
+ excluded = (GeneralSubtrees) obj;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:NameConstraintsExtension.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(PERMITTED_SUBTREES)) {
+ return (permitted);
+ } else if (name.equalsIgnoreCase(EXCLUDED_SUBTREES)) {
+ return (excluded);
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:NameConstraintsExtension.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(PERMITTED_SUBTREES)) {
+ permitted = null;
+ } else if (name.equalsIgnoreCase(EXCLUDED_SUBTREES)) {
+ excluded = null;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:NameConstraintsExtension.");
+ }
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(PERMITTED_SUBTREES);
+ elements.addElement(EXCLUDED_SUBTREES);
+
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/NoticeReference.java b/base/util/src/netscape/security/x509/NoticeReference.java
new file mode 100644
index 000000000..150b34f40
--- /dev/null
+++ b/base/util/src/netscape/security/x509/NoticeReference.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.util.Vector;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * Represent the NoticeReference.
+ *
+ * NoticeReference ::= SEQUENCE {
+ * organization DisplayText,
+ * noticeNumbers SEQUENCE OF INTEGER
+ * }
+ *
+ * @author Thomas Kwan
+ */
+public class NoticeReference {
+
+ private DisplayText mOrg = null;
+ private int mNumbers[] = null;
+
+ public NoticeReference(DisplayText org, int numbers[]) {
+ mOrg = org;
+ mNumbers = numbers;
+ }
+
+ public NoticeReference(DerValue val) throws IOException {
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding for NoticeReference");
+ }
+ mOrg = new DisplayText(val.data.getDerValue());
+ DerValue integers = val.data.getDerValue();
+ if (integers.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding for NoticeReference (integers)");
+ }
+ Vector<BigInt> num = new Vector<BigInt>();
+ while (integers.data.available() != 0) {
+ DerValue i = integers.data.getDerValue();
+ BigInt bigI = i.getInteger();
+ num.addElement(bigI);
+ }
+ if (num.size() <= 0)
+ return;
+ mNumbers = new int[num.size()];
+ for (int i = 0; i < num.size(); i++) {
+ mNumbers[i] = num.elementAt(i).toInt();
+ }
+ }
+
+ public DisplayText getOrganization() {
+ return mOrg;
+ }
+
+ public int[] getNumbers() {
+ return mNumbers;
+ }
+
+ /**
+ * Write the NoticeReference to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the object to.
+ * @exception IOException on errors.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ mOrg.encode(tmp);
+ DerOutputStream iseq = new DerOutputStream();
+ for (int i = 0; i < mNumbers.length; i++) {
+ iseq.putInteger(new BigInt(mNumbers[i]));
+ }
+ tmp.write(DerValue.tag_Sequence, iseq);
+ out.write(DerValue.tag_Sequence, tmp);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/OIDMap.java b/base/util/src/netscape/security/x509/OIDMap.java
new file mode 100644
index 000000000..9c732d938
--- /dev/null
+++ b/base/util/src/netscape/security/x509/OIDMap.java
@@ -0,0 +1,303 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Properties;
+
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * This class defines the mapping from OID & name to classes and vice
+ * versa. Used by CertificateExtensions & PKCS10 to get the java
+ * classes associated with a particular OID/name.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.12
+ */
+public class OIDMap {
+
+ /**
+ * Location for where the OID/Classes maps are stored on
+ * the local system.
+ */
+ public static final String EXTENSIONS_HOME =
+ (System.getProperty("java.home") + File.separator + "lib"
+ + File.separator + "security" + File.separator + "cert"
+ + File.separator);
+ /**
+ * File names for where OIDs and Classes are registered
+ * for V3 extensions.
+ */
+ public static final String EXTENSIONS_OIDS = "x509extensions.oid";
+ public static final String EXTENSIONS_CLASSES = "x509extensions.classes";
+
+ // Make default names easier
+ private static final String ROOT = X509CertImpl.NAME + "." +
+ X509CertInfo.NAME + "." +
+ X509CertInfo.EXTENSIONS;
+ private static final String AUTH_KEY_IDENTIFIER = ROOT + "." +
+ AuthorityKeyIdentifierExtension.NAME;
+ private static final String SUB_KEY_IDENTIFIER = ROOT + "." +
+ SubjectKeyIdentifierExtension.NAME;
+ private static final String KEY_USAGE = ROOT + "." +
+ KeyUsageExtension.NAME;
+ private static final String PRIVATE_KEY_USAGE = ROOT + "." +
+ PrivateKeyUsageExtension.NAME;
+ private static final String POLICY_MAPPINGS = ROOT + "." +
+ PolicyMappingsExtension.NAME;
+ private static final String SUB_ALT_NAME = ROOT + "." +
+ SubjectAlternativeNameExtension.NAME;
+ private static final String ISSUER_ALT_NAME = ROOT + "." +
+ IssuerAlternativeNameExtension.NAME;
+ private static final String BASIC_CONSTRAINTS = ROOT + "." +
+ BasicConstraintsExtension.NAME;
+ private static final String NAME_CONSTRAINTS = ROOT + "." +
+ NameConstraintsExtension.NAME;
+ private static final String POLICY_CONSTRAINTS = ROOT + "." +
+ PolicyConstraintsExtension.NAME;
+ private static final String CERT_POLICIES = //ROOT + "." +
+ CertificatePoliciesExtension.NAME;
+ private static final String SUBJ_DIR_ATTR = //ROOT + "." +
+ SubjectDirAttributesExtension.NAME;
+ public static final String EXT_KEY_USAGE_NAME = "ExtendedKeyUsageExtension";
+ public static final String EXT_INHIBIT_ANY_POLICY_NAME = "InhibitAnyPolicyExtension";
+ private static final String EXT_KEY_USAGE = //ROOT + "." +
+ EXT_KEY_USAGE_NAME;
+
+ private static final String CRL_NUMBER = ROOT + "." +
+ CRLNumberExtension.NAME;
+ private static final String CRL_REASON = ROOT + "." +
+ CRLReasonExtension.NAME;
+
+ private static final Hashtable<ObjectIdentifier, String> oid2Name = new Hashtable<ObjectIdentifier, String>();
+ private static final Hashtable<String, ObjectIdentifier> name2OID = new Hashtable<String, ObjectIdentifier>();
+ private static final Hashtable<String, String> name2Class = new Hashtable<String, String>();
+
+ // Initialize recognized extensions from EXTENSIONS_{OIDS/CLASSES} files
+ static {
+ loadNames();
+ loadClasses();
+ }
+
+ // Load the default name to oid map (EXTENSIONS_OIDS)
+ private static void loadNamesDefault(Properties props) {
+ props.put(SUB_KEY_IDENTIFIER, "2.5.29.14");
+ props.put(KEY_USAGE, "2.5.29.15");
+ props.put(PRIVATE_KEY_USAGE, "2.5.29.16");
+ props.put(SUB_ALT_NAME, "2.5.29.17");
+ props.put(ISSUER_ALT_NAME, "2.5.29.18");
+ props.put(BASIC_CONSTRAINTS, "2.5.29.19");
+ props.put(CRL_NUMBER, "2.5.29.20");
+ props.put(CRL_REASON, "2.5.29.21");
+ props.put(NAME_CONSTRAINTS, "2.5.29.30");
+ props.put(POLICY_MAPPINGS, "2.5.29.33");
+ props.put(POLICY_CONSTRAINTS, "2.5.29.36");
+ props.put(CERT_POLICIES, "2.5.29.32");
+ props.put(AUTH_KEY_IDENTIFIER, "2.5.29.35");
+ props.put(SUBJ_DIR_ATTR, "2.5.29.9");
+ props.put(EXT_KEY_USAGE, "2.5.29.37");
+ }
+
+ // Load the default name to class map (EXTENSIONS_CLASSES)
+ private static void loadClassDefault(Properties props) {
+ props.put(AUTH_KEY_IDENTIFIER,
+ "netscape.security.x509.AuthorityKeyIdentifierExtension");
+ props.put(SUB_KEY_IDENTIFIER,
+ "netscape.security.x509.SubjectKeyIdentifierExtension");
+ props.put(KEY_USAGE,
+ "netscape.security.x509.KeyUsageExtension");
+ props.put(PRIVATE_KEY_USAGE,
+ "netscape.security.x509.PrivateKeyUsageExtension");
+ props.put(POLICY_MAPPINGS,
+ "netscape.security.x509.PolicyMappingsExtension");
+ props.put(SUB_ALT_NAME,
+ "netscape.security.x509.SubjectAlternativeNameExtension");
+ props.put(ISSUER_ALT_NAME,
+ "netscape.security.x509.IssuerAlternativeNameExtension");
+ props.put(BASIC_CONSTRAINTS,
+ "netscape.security.x509.BasicConstraintsExtension");
+ props.put(NAME_CONSTRAINTS,
+ "netscape.security.x509.NameConstraintsExtension");
+ props.put(POLICY_CONSTRAINTS,
+ "netscape.security.x509.PolicyConstraintsExtension");
+ props.put(CERT_POLICIES,
+ "netscape.security.x509.CertificatePoliciesExtension");
+ props.put(SUBJ_DIR_ATTR,
+ "netscape.security.x509.SubjectDirAttributesExtension");
+ props.put(EXT_KEY_USAGE,
+ "netscape.security.extensions.ExtendedKeyUsageExtension");
+ props.put(CRL_NUMBER, "netscape.security.x509.CRLNumberExtension");
+ props.put(CRL_REASON, "netscape.security.x509.CRLReasonExtension");
+ }
+
+ // Return the file along with location
+ private static File certificatePropFile(String fileName) {
+ return (new File(EXTENSIONS_HOME + fileName));
+ }
+
+ // Load the names to oid map
+ private static void loadNames() {
+ Properties props = new Properties();
+ File namesMap = certificatePropFile(EXTENSIONS_OIDS);
+
+ if (!namesMap.exists()) {
+ loadNamesDefault(props);
+ } else {
+ try {
+ FileInputStream fis = new FileInputStream(namesMap);
+ props.load(fis);
+ fis.close();
+ } catch (IOException e) {
+ loadNamesDefault(props);
+ }
+ }
+
+ Iterator<String> names = props.stringPropertyNames().iterator();
+ while (names.hasNext()) {
+ String name = names.next();
+ String oidName = props.getProperty(name);
+ ObjectIdentifier oid = new ObjectIdentifier(oidName);
+
+ name2OID.put(name, oid);
+ oid2Name.put(oid, name);
+ }
+ }
+
+ // Load the names to classes map
+ private static void loadClasses() {
+ Properties props = new Properties();
+ File classMap = certificatePropFile(EXTENSIONS_CLASSES);
+
+ if (!classMap.exists()) {
+ loadClassDefault(props);
+ } else {
+ try {
+ FileInputStream fis = new FileInputStream(classMap);
+ props.load(fis);
+ } catch (IOException e) {
+ loadClassDefault(props);
+ }
+ }
+
+ Iterator<String> names = props.stringPropertyNames().iterator();
+ while (names.hasNext()) {
+ String name = names.next();
+ String className = props.getProperty(name);
+
+ name2Class.put(name, className);
+ }
+ }
+
+ /**
+ * Add a name to lookup table.
+ *
+ * @param className the name of the fully qualified class implementing
+ * the asn object.
+ * @param oid the string representation of the object identifier for
+ * the class.
+ * @param name the name of the attribute.
+ * @exception CertificateException on errors.
+ */
+ public static void addAttribute(String className, String oid, String name)
+ throws CertificateException {
+ ObjectIdentifier objId = new ObjectIdentifier(oid);
+ if (oid2Name.get(objId) != null) {
+ throw new CertificateException("Object identifier already exists.");
+ }
+ if (name2OID.get(name) != null) {
+ throw new CertificateException("Name already exists.");
+ }
+ if (name2Class.get(className) != null) {
+ throw new CertificateException("Class already exists.");
+ }
+ oid2Name.put(objId, name);
+ name2OID.put(name, objId);
+ name2Class.put(name, className);
+ }
+
+ /**
+ * Return user friendly name associated with the OID.
+ *
+ * @param oid the name of the object identifier to be returned.
+ * @return the user friendly name or null if no name
+ * is registered for this oid.
+ */
+ public static String getName(ObjectIdentifier oid) {
+ return (String) oid2Name.get(oid);
+ }
+
+ /**
+ * Return Object identifier for user friendly name.
+ *
+ * @param name the user friendly name.
+ * @return the Object Identifier or null if no oid
+ * is registered for this name.
+ */
+ public static ObjectIdentifier getOID(String name) {
+ return (ObjectIdentifier) name2OID.get(name);
+ }
+
+ /**
+ * Return the java class object associated with the user friendly name.
+ *
+ * @param name the user friendly name.
+ * @exception CertificateException if class cannot be instantiated.
+ */
+ public static Class<?> getClass(String name) throws CertificateException {
+ String className = (String) name2Class.get(name);
+ if (className == null)
+ return null;
+ try {
+ Class<?> extClass = Class.forName(className);
+ return (extClass);
+ } catch (Exception e) {
+ throw new CertificateException("Error instantiating class for "
+ + name + " " + e.toString());
+ }
+ }
+
+ /**
+ * Return the java class object associated with the object identifier..
+ *
+ * @param oid the name of the object identifier to be returned.
+ * @exception CertificateException if class cannot be instatiated.
+ */
+ public static Class<?> getClass(ObjectIdentifier oid)
+ throws CertificateException {
+ String name = getName(oid);
+ if (name == null)
+ return null;
+ String className = (String) name2Class.get(name);
+ if (className == null)
+ return null;
+ try {
+ Class<?> extClass = Class.forName(className);
+ return (extClass);
+ } catch (Exception e) {
+ throw new CertificateException("Error instantiating class for "
+ + name + " " + e.toString());
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/x509/OIDName.java b/base/util/src/netscape/security/x509/OIDName.java
new file mode 100644
index 000000000..e5c1b7ac3
--- /dev/null
+++ b/base/util/src/netscape/security/x509/OIDName.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 netscape.security.x509;
+
+import java.io.IOException;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * This class implements the OIDName as required by the GeneralNames
+ * ASN.1 object.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.3
+ * @see GeneralName
+ * @see GeneralNames
+ * @see GeneralNameInterface
+ */
+public class OIDName implements GeneralNameInterface {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 9198510631835117121L;
+ private ObjectIdentifier oid;
+
+ /**
+ * Create the OIDName object from the passed encoded Der value.
+ *
+ * @param derValue the encoded DER OIDName.
+ * @exception IOException on error.
+ */
+ public OIDName(DerValue derValue) throws IOException {
+ oid = derValue.getOID();
+ }
+
+ /**
+ * Create the OIDName object with the specified name.
+ *
+ * @param name the OIDName.
+ */
+ public OIDName(ObjectIdentifier oid) {
+ this.oid = oid;
+ }
+
+ public OIDName(String oid) {
+ this.oid = new ObjectIdentifier(oid);
+ }
+
+ /**
+ * Return the type of the GeneralName.
+ */
+ public int getType() {
+ return (GeneralNameInterface.NAME_OID);
+ }
+
+ /**
+ * Encode the OID name into the DerOutputStream.
+ *
+ * @param out the DER stream to encode the OIDName to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ out.putOID(oid);
+ }
+
+ /**
+ * Convert the name into user readable string.
+ */
+ public String toString() {
+ return ("OIDName: " + oid.toString());
+ }
+}
diff --git a/base/util/src/netscape/security/x509/OtherName.java b/base/util/src/netscape/security/x509/OtherName.java
new file mode 100644
index 000000000..38d3a0af3
--- /dev/null
+++ b/base/util/src/netscape/security/x509/OtherName.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * This class implements the OtherName as required by the GeneralNames
+ * ASN.1 object.
+ *
+ * OtherName ::= SEQUENCE {
+ * type-id OBJECT IDENTIFIER,
+ * value [0] EXPLICIT ANY DEFINED BY type-id
+ * }
+ *
+ * @see GeneralName
+ * @see GeneralNameInterface
+ * @see GeneralNames
+ *
+ * @version 1.2
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ */
+public class OtherName implements GeneralNameInterface {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3533614377346132611L;
+ private ObjectIdentifier mOID = null;
+ private byte[] mData = null;
+
+ /**
+ * Create the IPAddressName object from the passed encoded Der value.
+ *
+ * @param derValue the encoded DER IPAddressName.
+ * @exception IOException on error.
+ */
+ public OtherName(DerValue derValue) throws IOException {
+ decodeThis(derValue);
+ }
+
+ public OtherName(ObjectIdentifier oid, byte data[]) {
+ mOID = oid;
+ DerOutputStream dos = new DerOutputStream();
+ try {
+ dos.putDerValue(new DerValue(data));
+ } catch (IOException e) {
+ }
+ mData = dos.toByteArray();
+ }
+
+ /**
+ * Constructs a string-based other name.
+ */
+ public OtherName(ObjectIdentifier oid, byte tag, String value) {
+ mOID = oid;
+ DerOutputStream dos = new DerOutputStream();
+ try {
+ if (tag == DerValue.tag_PrintableString) {
+ dos.putPrintableString(value);
+ } else if (tag == DerValue.tag_IA5String) {
+ dos.putIA5String(value);
+ } else if (tag == DerValue.tag_BMPString) {
+ dos.putBMPString(value);
+ } else if (tag == DerValue.tag_UTF8String) {
+ dos.putUTF8String(value);
+ }
+ } catch (IOException e) {
+ }
+ mData = dos.toByteArray();
+ }
+
+ public OtherName(ObjectIdentifier oid, String value) {
+ mOID = oid;
+ DerOutputStream dos = new DerOutputStream();
+ try {
+ dos.putPrintableString(value);
+ } catch (IOException e) {
+ }
+ mData = dos.toByteArray();
+ }
+
+ /**
+ * Create the IPAddressName object with the specified name.
+ *
+ * @param name the IPAddressName.
+ */
+ public OtherName(byte[] data) {
+ try {
+ decodeThis(new DerValue(data));
+ } catch (IOException e) {
+ }
+ }
+
+ public ObjectIdentifier getOID() {
+ return mOID;
+ }
+
+ /**
+ * Return the type of the GeneralName.
+ */
+ public int getType() {
+ return (GeneralNameInterface.NAME_ANY);
+ }
+
+ /**
+ * Encode the IPAddress name into the DerOutputStream.
+ *
+ * @param out the DER stream to encode the IPAddressName to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ //encoding the attributes
+ tmp.putOID(mOID);
+ DerOutputStream tmp1 = new DerOutputStream();
+ tmp1.write(mData);
+ tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true,
+ (byte) 0x80), tmp1);
+
+ out.write(DerValue.tag_SequenceOf, tmp);
+ }
+
+ public void decode(InputStream in) throws IOException {
+ DerValue val = new DerValue(in);
+ decodeThis(val);
+ }
+
+ // Decode this extension value
+ private void decodeThis(DerValue derVal) throws IOException {
+
+ // if (derVal.tag != DerValue.tag_Sequence) {
+ // throw new IOException("Invalid encoding for other name");
+ // }
+
+ // Decode all the Attributes
+ mOID = derVal.data.getOID();
+ // skip tag
+ DerValue tag = derVal.data.getDerValue();
+ // read data
+ DerValue data = tag.data.getDerValue();
+ mData = data.toByteArray();
+ }
+
+ public byte[] getValue() {
+ return mData;
+ }
+
+ /**
+ * Return a printable string of IPaddress
+ */
+ public String toString() {
+ if (mData != null) {
+ try {
+ DerValue data = new DerValue(mData);
+ if (data.tag == DerValue.tag_PrintableString) {
+ return "OtherName: (PrintableString)" + mOID + "," + data.getPrintableString();
+ } else if (data.tag == DerValue.tag_IA5String) {
+ return "OtherName: (IA5String)" + mOID + "," + data.getIA5String();
+ } else if (data.tag == DerValue.tag_BMPString) {
+ return "OtherName: (BMPString)" + mOID + "," + data.getIA5String();
+ } else if (data.tag == DerValue.tag_UTF8String) {
+ return "OtherName: (UTF8String)" + mOID + "," + data.getUTF8String();
+ } else {
+ return "OtherName: (Any)" + mOID + "," + toStr(data.toByteArray());
+ }
+ } catch (IOException e) {
+
+ return "OtherName: (Any)" + mOID + "," + toStr(mData);
+ }
+ } else {
+ return "OtherName: ";
+ }
+ }
+
+ 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();
+ }
+}
diff --git a/base/util/src/netscape/security/x509/PKIXExtensions.java b/base/util/src/netscape/security/x509/PKIXExtensions.java
new file mode 100644
index 000000000..9946a5c57
--- /dev/null
+++ b/base/util/src/netscape/security/x509/PKIXExtensions.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 netscape.security.x509;
+
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * Lists all the object identifiers of the X509 extensions of the PKIX profile.
+ *
+ * <p>
+ * Extensions are addiitonal attributes which can be inserted in a X509 v3 certificate. For example a
+ * "Driving License Certificate" could have the driving license number as a extension.
+ *
+ * <p>
+ * Extensions are represented as a sequence of the extension identifier (Object Identifier), a boolean flag stating
+ * whether the extension is to be treated as being critical and the extension value itself (this is again a DER encoding
+ * of the extension value).
+ *
+ * @see Extension
+ *
+ * @version 1.4
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ */
+public class PKIXExtensions {
+ // The object identifiers
+ private static final int AuthorityKey_data[] = { 2, 5, 29, 35 };
+ private static final int SubjectKey_data[] = { 2, 5, 29, 14 };
+ private static final int KeyUsage_data[] = { 2, 5, 29, 15 };
+ private static final int PrivateKeyUsage_data[] = { 2, 5, 29, 16 };
+ private static final int CertificatePolicies_data[] = { 2, 5, 29, 32 };
+ private static final int PolicyMappings_data[] = { 2, 5, 29, 33 };
+ private static final int SubjectAlternativeName_data[] = { 2, 5, 29, 17 };
+ private static final int IssuerAlternativeName_data[] = { 2, 5, 29, 18 };
+ private static final int SubjectDirectoryAttributes_data[] = { 2, 5, 29, 9 };
+ private static final int BasicConstraints_data[] = { 2, 5, 29, 19 };
+ private static final int NameConstraints_data[] = { 2, 5, 29, 30 };
+ private static final int PolicyConstraints_data[] = { 2, 5, 29, 36 };
+ private static final int CRLDistributionPoints_data[] = { 2, 5, 29, 31 };
+ private static final int CRLNumber_data[] = { 2, 5, 29, 20 };
+ private static final int IssuingDistributionPoint_data[] = { 2, 5, 29, 28 };
+ private static final int DeltaCRLIndicator_data[] = { 2, 5, 29, 27 };
+ private static final int ReasonCode_data[] = { 2, 5, 29, 21 };
+ private static final int HoldInstructionCode_data[] = { 2, 5, 29, 23 };
+ private static final int InvalidityDate_data[] = { 2, 5, 29, 24 };
+ private static final int CertificateIssuer_data[] = { 2, 5, 29, 29 };
+ private static final int FreshestCRL_data[] = { 2, 5, 29, 46 };
+
+ /**
+ * Identifies the particular public key used to sign the certificate.
+ */
+ public static final ObjectIdentifier AuthorityKey_Id = new ObjectIdentifier(AuthorityKey_data);
+
+ /**
+ * Identifies the particular public key used in an application.
+ */
+ public static final ObjectIdentifier SubjectKey_Id = new ObjectIdentifier(SubjectKey_data);
+
+ /**
+ * Defines the purpose of the key contained in the certificate.
+ */
+ public static final ObjectIdentifier KeyUsage_Id = new ObjectIdentifier(KeyUsage_data);
+
+ /**
+ * Allows the certificate issuer to specify a different validity period
+ * for the private key than the certificate.
+ */
+ public static final ObjectIdentifier PrivateKeyUsage_Id = new ObjectIdentifier(PrivateKeyUsage_data);
+
+ /**
+ * Contains the sequence of policy information terms.
+ */
+ public static final ObjectIdentifier CertificatePolicies_Id = new ObjectIdentifier(CertificatePolicies_data);
+
+ /**
+ * Lists pairs of objectidentifiers of policies considered equivalent by the
+ * issuing CA to the subject CA.
+ */
+ public static final ObjectIdentifier PolicyMappings_Id = new ObjectIdentifier(PolicyMappings_data);
+
+ /**
+ * Allows additional identities to be bound to the subject of the certificate.
+ */
+ public static final ObjectIdentifier SubjectAlternativeName_Id = new ObjectIdentifier(SubjectAlternativeName_data);
+
+ /**
+ * Allows additional identities to be associated with the certificate issuer.
+ */
+ public static final ObjectIdentifier IssuerAlternativeName_Id =
+ new ObjectIdentifier(IssuerAlternativeName_data);
+
+ /**
+ * Identifies additional directory attributes.
+ * This extension is always non-critical.
+ */
+ public static final ObjectIdentifier SubjectDirectoryAttributes_Id = new ObjectIdentifier(
+ SubjectDirectoryAttributes_data);
+
+ /**
+ * Identifies whether the subject of the certificate is a CA and how deep
+ * a certification path may exist through that CA.
+ */
+ public static final ObjectIdentifier BasicConstraints_Id =
+ new ObjectIdentifier(BasicConstraints_data);
+
+ /**
+ * Provides for permitted and excluded subtrees that place restrictions
+ * on names that may be included within a certificate issued by a given CA.
+ */
+ public static final ObjectIdentifier NameConstraints_Id = new ObjectIdentifier(NameConstraints_data);
+
+ /**
+ * Used to either prohibit policy mapping or limit the set of policies
+ * that can be in subsequent certificates.
+ */
+ public static final ObjectIdentifier PolicyConstraints_Id = new ObjectIdentifier(PolicyConstraints_data);
+
+ /**
+ * Identifies how CRL information is obtained.
+ */
+ public static final ObjectIdentifier CRLDistributionPoints_Id = new ObjectIdentifier(CRLDistributionPoints_data);
+
+ /**
+ * Conveys a monotonically increasing sequence number for each CRL
+ * issued by a given CA.
+ */
+ public static final ObjectIdentifier CRLNumber_Id = new ObjectIdentifier(CRLNumber_data);
+
+ /**
+ * Identifies the CRL distribution point for a particular CRL.
+ */
+ public static final ObjectIdentifier IssuingDistributionPoint_Id = new ObjectIdentifier(
+ IssuingDistributionPoint_data);
+
+ /**
+ * Identifies the delta CRL.
+ */
+ public static final ObjectIdentifier DeltaCRLIndicator_Id = new ObjectIdentifier(DeltaCRLIndicator_data);
+
+ /**
+ * Identifies the reason for the certificate revocation.
+ */
+ public static final ObjectIdentifier ReasonCode_Id = new ObjectIdentifier(ReasonCode_data);
+
+ /**
+ * This extension provides a registered instruction identifier indicating
+ * the action to be taken, after encountering a certificate that has been
+ * placed on hold.
+ */
+ public static final ObjectIdentifier HoldInstructionCode_Id = new ObjectIdentifier(HoldInstructionCode_data);
+
+ /**
+ * Identifies the date on which it is known or suspected that the private
+ * key was compromised or that the certificate otherwise became invalid.
+ */
+ public static final ObjectIdentifier InvalidityDate_Id = new ObjectIdentifier(InvalidityDate_data);
+
+ /**
+ * Identifies the date on which it is known or suspected that the private
+ * key was compromised or that the certificate otherwise became invalid.
+ */
+ public static final ObjectIdentifier CertificateIssuer_Id = new ObjectIdentifier(CertificateIssuer_data);
+
+ /**
+ * Identifies how delta CRL information is obtained.
+ */
+ public static final ObjectIdentifier FreshestCRL_Id = new ObjectIdentifier(FreshestCRL_data);
+
+}
diff --git a/base/util/src/netscape/security/x509/PolicyConstraint.java b/base/util/src/netscape/security/x509/PolicyConstraint.java
new file mode 100644
index 000000000..22f9cebed
--- /dev/null
+++ b/base/util/src/netscape/security/x509/PolicyConstraint.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 netscape.security.x509;
+
+import java.io.IOException;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class defines the PolicyConstraint ASN.1 object.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.4
+ */
+public class PolicyConstraint {
+ private static final byte TAG_SET = 0;
+ private static final byte TAG_REQUIRE = 1;
+ private static final byte TAG_INHIBIT = 2;
+
+ private CertificatePolicySet set = null;
+ private int require = -1;
+ private int inhibit = -1;
+
+ /**
+ * The default constructor for this object
+ *
+ * @param set the CertificatePolicySet (null for optional).
+ * @param require require explicit policy (-1 for optional).
+ * @param inhibit inhibit policy mapping (-1 for optional).
+ */
+ public PolicyConstraint(CertificatePolicySet set, int require, int inhibit) {
+ this.set = set;
+ this.require = require;
+ this.inhibit = inhibit;
+ }
+
+ /**
+ * Create the PolicyConstraint from the DerValue.
+ *
+ * @param val the DerValue of the PolicyConstraint.
+ * @exception IOException on decoding errors.
+ */
+ public PolicyConstraint(DerValue val) throws IOException {
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Sequence tag missing for PolicyConstraint.");
+ }
+ DerInputStream in = val.data;
+ while (in != null && in.available() != 0) {
+ DerValue next = in.getDerValue();
+ switch (next.tag & 0x1f) {
+ case TAG_SET:
+ this.set = new CertificatePolicySet(next.data);
+ break;
+
+ case TAG_REQUIRE:
+ next = next.data.getDerValue();
+ this.require = (next.getInteger()).toInt();
+ break;
+
+ case TAG_INHIBIT:
+ next = next.data.getDerValue();
+ this.inhibit = (next.getInteger()).toInt();
+ break;
+
+ default:
+ throw new IOException("Invalid tag option for PolicyConstraint.");
+ }
+ }
+ }
+
+ /**
+ * Return user readable form of the object.
+ */
+ public String toString() {
+ String s = ((set != null) ?
+ "PolicyConstraint: [\n"
+ + " PolicySet:[" + set.toString() + "]\n"
+ + " Require:" + require + "\n"
+ + " Inhibit:" + inhibit + "\n"
+ + "]\n" :
+ "PolicyConstraint: [\n"
+ + " PolicySet:[null]\n"
+ + " Require:" + require + "\n"
+ + " Inhibit:" + inhibit + "\n"
+ + "]\n");
+ return (s);
+ }
+
+ /**
+ * Encode the object to the output stream.
+ *
+ * @param out the DerOutputStream to encode the object to.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ DerOutputStream tagged = new DerOutputStream();
+
+ if (set != null) {
+ DerOutputStream tmp = new DerOutputStream();
+ set.encode(tmp);
+ tagged.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ true, TAG_SET), tmp);
+ }
+ if (require != -1) {
+ DerOutputStream tmp = new DerOutputStream();
+ tmp.putInteger(new BigInt(require));
+ tagged.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ true, TAG_REQUIRE), tmp);
+ }
+ if (inhibit != -1) {
+ DerOutputStream tmp = new DerOutputStream();
+ tmp.putInteger(new BigInt(inhibit));
+ tagged.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ true, TAG_INHIBIT), tmp);
+ }
+ out.write(DerValue.tag_Sequence, tagged);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/PolicyConstraintsExtension.java b/base/util/src/netscape/security/x509/PolicyConstraintsExtension.java
new file mode 100644
index 000000000..7d98b21ba
--- /dev/null
+++ b/base/util/src/netscape/security/x509/PolicyConstraintsExtension.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class defines the certificate extension which specifies the
+ * Policy constraints.
+ * <p>
+ * The policy constraints extension can be used in certificates issued to CAs. The policy constraints extension
+ * constrains path validation in two ways. It can be used to prohibit policy mapping or require that each certificate in
+ * a path contain an acceptable policy identifier.
+ * <p>
+ * The ASN.1 syntax for this is (IMPLICIT tagging is defined in the module definition):
+ *
+ * <pre>
+ * PolicyConstraints ::= SEQUENCE {
+ * requireExplicitPolicy [0] SkipCerts OPTIONAL,
+ * inhibitPolicyMapping [1] SkipCerts OPTIONAL
+ * }
+ * SkipCerts ::= INTEGER (0..MAX)
+ * </pre>
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.9
+ * @see Extension
+ * @see CertAttrSet
+ */
+public class PolicyConstraintsExtension extends Extension
+ implements CertAttrSet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3723759691127622370L;
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT = "x509.info.extensions.PolicyConstraints";
+ /**
+ * Attribute names.
+ */
+ public static final String NAME = "PolicyConstraints";
+ public static final String REQUIRE = "require";
+ public static final String INHIBIT = "inhibit";
+
+ private static final byte TAG_REQUIRE = 0;
+ private static final byte TAG_INHIBIT = 1;
+
+ private int require = -1;
+ private int inhibit = -1;
+
+ // Encode this extension value.
+ private void encodeThis() throws IOException {
+ DerOutputStream tagged = new DerOutputStream();
+ DerOutputStream seq = new DerOutputStream();
+
+ if (require != -1) {
+ DerOutputStream tmp = new DerOutputStream();
+ tmp.putInteger(new BigInt(require));
+ tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
+ false, TAG_REQUIRE), tmp);
+ }
+ if (inhibit != -1) {
+ DerOutputStream tmp = new DerOutputStream();
+ tmp.putInteger(new BigInt(inhibit));
+ tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
+ false, TAG_INHIBIT), tmp);
+ }
+ seq.write(DerValue.tag_Sequence, tagged);
+ extensionValue = seq.toByteArray();
+ }
+
+ /**
+ * Create a PolicyConstraintsExtension object with criticality and
+ * both require explicit policy and inhibit policy mapping.
+ *
+ * @param critical whether this extension should be critical
+ * @param require require explicit policy (-1 for optional).
+ * @param inhibit inhibit policy mapping (-1 for optional).
+ */
+ public PolicyConstraintsExtension(boolean crit, int require, int inhibit)
+ throws IOException {
+ init(crit, require, inhibit);
+ }
+
+ /**
+ * Create a PolicyConstraintsExtension object with both
+ * require explicit policy and inhibit policy mapping.
+ *
+ * @param require require explicit policy (-1 for optional).
+ * @param inhibit inhibit policy mapping (-1 for optional).
+ */
+ public PolicyConstraintsExtension(int require, int inhibit)
+ throws IOException {
+ init(false, require, inhibit);
+ }
+
+ private void init(boolean crit, int require, int inhibit)
+ throws IOException {
+ this.require = require;
+ this.inhibit = inhibit;
+ this.extensionId = PKIXExtensions.PolicyConstraints_Id;
+ this.critical = crit;
+ encodeThis();
+ }
+
+ /**
+ * Create the extension from its DER encoded value and criticality.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param value Array of DER encoded bytes of the actual value.
+ * @exception IOException on error.
+ */
+ public PolicyConstraintsExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = PKIXExtensions.PolicyConstraints_Id;
+ this.critical = critical.booleanValue();
+
+ if (!(value instanceof byte[]))
+ throw new IOException("Illegal argument type");
+
+ int len = Array.getLength(value);
+ byte[] extValue = new byte[len];
+ System.arraycopy(value, 0, extValue, 0, len);
+
+ this.extensionValue = extValue;
+ DerValue val = new DerValue(extValue);
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Sequence tag missing for PolicyConstraint.");
+ }
+ DerInputStream in = val.data;
+ while (in != null && in.available() != 0) {
+ DerValue next = in.getDerValue();
+
+ if (next.isContextSpecific(TAG_REQUIRE) && !next.isConstructed()) {
+ if (this.require != -1)
+ throw new IOException("Duplicate requireExplicitPolicy" +
+ "found in the PolicyConstraintsExtension");
+ next.resetTag(DerValue.tag_Integer);
+ this.require = (next.getInteger()).toInt();
+
+ } else if (next.isContextSpecific(TAG_INHIBIT) &&
+ !next.isConstructed()) {
+ if (this.inhibit != -1)
+ throw new IOException("Duplicate inhibitPolicyMapping" +
+ "found in the PolicyConstraintsExtension");
+ next.resetTag(DerValue.tag_Integer);
+ this.inhibit = (next.getInteger()).toInt();
+ } else
+ throw new IOException("Invalid encoding of PolicyConstraint");
+ }
+ }
+
+ /**
+ * Return the extension as user readable string.
+ */
+ public String toString() {
+ String s;
+ s = super.toString() + "PolicyConstraints: [" + " Require: ";
+ if (require == -1)
+ s += "unspecified;";
+ else
+ s += require + ";";
+ s += "\tInhibit: ";
+ if (inhibit == -1)
+ s += "unspecified";
+ else
+ s += inhibit;
+ s += " ]\n";
+ return s;
+ }
+
+ /**
+ * Decode the extension from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ /**
+ * Write the extension to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ if (extensionValue == null) {
+ extensionId = PKIXExtensions.PolicyConstraints_Id;
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ clearValue();
+ if (!(obj instanceof Integer)) {
+ throw new IOException("Attribute value should be of type Integer.");
+ }
+ if (name.equalsIgnoreCase(REQUIRE)) {
+ require = ((Integer) obj).intValue();
+ } else if (name.equalsIgnoreCase(INHIBIT)) {
+ inhibit = ((Integer) obj).intValue();
+ } else {
+ throw new IOException("Attribute name " + "[" + name + "]" +
+ " not recognized by " +
+ "CertAttrSet:PolicyConstraints.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(REQUIRE)) {
+ return Integer.valueOf(require);
+ } else if (name.equalsIgnoreCase(INHIBIT)) {
+ return Integer.valueOf(inhibit);
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:PolicyConstraints.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(REQUIRE)) {
+ require = -1;
+ } else if (name.equalsIgnoreCase(INHIBIT)) {
+ inhibit = -1;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:PolicyConstraints.");
+ }
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(REQUIRE);
+ elements.addElement(INHIBIT);
+
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+
+ /**
+ * returns the requireExplicitMapping parameter.
+ */
+ public int getRequireExplicitMapping() {
+ return require;
+ }
+
+ /**
+ * returns the inhibitPolicyMapping parameter.
+ */
+ public int getInhibitPolicyMapping() {
+ return inhibit;
+ }
+}
diff --git a/base/util/src/netscape/security/x509/PolicyMappingsExtension.java b/base/util/src/netscape/security/x509/PolicyMappingsExtension.java
new file mode 100644
index 000000000..9bdfb611b
--- /dev/null
+++ b/base/util/src/netscape/security/x509/PolicyMappingsExtension.java
@@ -0,0 +1,258 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * Represent the Policy Mappings Extension.
+ *
+ * This extension, if present, identifies the certificate policies considered
+ * identical between the issuing and the subject CA.
+ * <p>
+ * Extensions are addiitonal attributes which can be inserted in a X509 v3 certificate. For example a
+ * "Driving License Certificate" could have the driving license number as a extension.
+ *
+ * <p>
+ * Extensions are represented as a sequence of the extension identifier (Object Identifier), a boolean flag stating
+ * whether the extension is to be treated as being critical and the extension value itself (this is again a DER encoding
+ * of the extension value).
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.7
+ * @see Extension
+ * @see CertAttrSet
+ */
+public class PolicyMappingsExtension extends Extension
+ implements CertAttrSet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4023336164621135851L;
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT = "x509.info.extensions.PolicyMappings";
+ /**
+ * Attribute names.
+ */
+ public static final String NAME = "PolicyMappings";
+ public static final String MAP = "map";
+
+ // Private data members
+ private Vector<CertificatePolicyMap> maps = null;
+
+ // Encode this extension value
+ private void encodeThis() throws IOException {
+ DerOutputStream os = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+
+ for (int i = 0; i < maps.size(); i++) {
+ ((CertificatePolicyMap) maps.elementAt(i)).encode(tmp);
+ }
+ os.write(DerValue.tag_Sequence, tmp);
+ extensionValue = os.toByteArray();
+ }
+
+ /**
+ * Create a PolicyMappings with the Vector of CertificatePolicyMap.
+ *
+ * @param maps the Vector of CertificatePolicyMap.
+ */
+ public PolicyMappingsExtension(Vector<CertificatePolicyMap> map) throws IOException {
+ init(false, map);
+ }
+
+ /**
+ * Create a PolicyMappings with the Vector of CertificatePolicyMap.
+ *
+ * @param maps the Vector of CertificatePolicyMap.
+ */
+ public PolicyMappingsExtension(boolean critical, Vector<CertificatePolicyMap> map)
+ throws IOException {
+ init(critical, map);
+ }
+
+ /**
+ * init policy with criticality and map.
+ */
+ private void init(boolean critical, Vector<CertificatePolicyMap> map) throws IOException {
+ this.maps = map;
+ this.extensionId = PKIXExtensions.PolicyMappings_Id;
+ this.critical = critical;
+ encodeThis();
+ }
+
+ /**
+ * Create a default PolicyMappingsExtension.
+ */
+ public PolicyMappingsExtension() {
+ extensionId = PKIXExtensions.PolicyMappings_Id;
+ critical = false;
+ maps = new Vector<CertificatePolicyMap>(1, 1);
+ }
+
+ /**
+ * Create the extension from the passed DER encoded value.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param value Array of DER encoded bytes of the actual value.
+ * @exception IOException on error.
+ */
+ public PolicyMappingsExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = PKIXExtensions.PolicyMappings_Id;
+ this.critical = critical.booleanValue();
+
+ int len = Array.getLength(value);
+ byte[] extValue = new byte[len];
+ for (int i = 0; i < len; i++) {
+ extValue[i] = Array.getByte(value, i);
+ }
+ this.extensionValue = extValue;
+ DerValue val = new DerValue(extValue);
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding for " +
+ "PolicyMappingsExtension.");
+ }
+ maps = new Vector<CertificatePolicyMap>(1, 1);
+ while (val.data.available() != 0) {
+ DerValue seq = val.data.getDerValue();
+ CertificatePolicyMap map = new CertificatePolicyMap(seq);
+ maps.addElement(map);
+ }
+ }
+
+ /**
+ * Returns a printable representation of the policy map.
+ */
+ public String toString() {
+ if (maps == null)
+ return "";
+ String s = super.toString() + "PolicyMappings [\n"
+ + maps.toString() + "]\n";
+
+ return (s);
+ }
+
+ /**
+ * Write the extension to the OutputStream.
+ *
+ * @param out the OutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ if (extensionValue == null) {
+ extensionId = PKIXExtensions.PolicyMappings_Id;
+ critical = false;
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Decode the extension from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ @SuppressWarnings("unchecked")
+ public void set(String name, Object obj) throws IOException {
+ clearValue();
+ if (name.equalsIgnoreCase(MAP)) {
+ if (!(obj instanceof Vector)) {
+ throw new IOException("Attribute value should be of" +
+ " type Vector.");
+ }
+ maps = (Vector<CertificatePolicyMap>) obj;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:PolicyMappingsExtension.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(MAP)) {
+ return (maps);
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:PolicyMappingsExtension.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(MAP)) {
+ maps = null;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:PolicyMappingsExtension.");
+ }
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(MAP);
+
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+
+ /**
+ * Returns an enumeration of the mappings in the extension.
+ */
+ public Enumeration<CertificatePolicyMap> getMappings() {
+ if (maps == null)
+ return null;
+ return maps.elements();
+ }
+}
diff --git a/base/util/src/netscape/security/x509/PolicyQualifierInfo.java b/base/util/src/netscape/security/x509/PolicyQualifierInfo.java
new file mode 100644
index 000000000..56d3e32c0
--- /dev/null
+++ b/base/util/src/netscape/security/x509/PolicyQualifierInfo.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 netscape.security.x509;
+
+import java.io.IOException;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * Represent the PolicyQualifierInfo.
+ *
+ * policyQualifierInfo ::= SEQUENCE {
+ * policyQualifierId PolicyQualifierId
+ * qualifier ANY DEFINED BY policyQualifierId
+ * }
+ *
+ * @author Thomas Kwan
+ */
+public class PolicyQualifierInfo implements java.io.Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2930016944517192379L;
+ public static final int OID_CPS[] = { 1, 3, 6, 1, 5, 5, 7, 2, 1 };
+ public static final ObjectIdentifier QT_CPS = new
+ ObjectIdentifier(OID_CPS);
+
+ public static final int OID_UNOTICE[] = { 1, 3, 6, 1, 5, 5, 7, 2, 2 };
+ public static final ObjectIdentifier QT_UNOTICE = new
+ ObjectIdentifier(OID_UNOTICE);
+
+ private ObjectIdentifier mId = null;
+ private Qualifier mQualifier = null;
+
+ /**
+ * Create a PolicyQualifierInfo
+ *
+ * @param id the ObjectIdentifier for the policy id.
+ */
+ public PolicyQualifierInfo(ObjectIdentifier id, Qualifier qualifier) {
+ mId = id;
+ mQualifier = qualifier;
+ }
+
+ /**
+ * Create the object from its Der encoded value.
+ *
+ * @param val the DER encoded value for the same.
+ */
+ public PolicyQualifierInfo(DerValue val) throws IOException {
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding for PolicyQualifierInfo.");
+ }
+ DerValue did = val.data.getDerValue();
+ mId = did.getOID();
+ if (val.data.available() != 0) {
+ DerValue qualifier = val.data.getDerValue();
+ if (qualifier.tag == DerValue.tag_IA5String) {
+ mQualifier = new CPSuri(qualifier);
+ } else {
+ mQualifier = new UserNotice(qualifier);
+ }
+ }
+ }
+
+ public ObjectIdentifier getId() {
+ return mId;
+ }
+
+ /**
+ * Returns object of type CPSuri or UserNotice.
+ */
+ public Qualifier getQualifier() {
+ return mQualifier;
+ }
+
+ /**
+ * Returns a printable representation of the CertificatePolicyId.
+ */
+ public String toString() {
+ String s = "PolicyQualifierInfo: [";
+ s = s + getId() + " " + getQualifier();
+ s = s + "]\n";
+
+ return (s);
+ }
+
+ /**
+ * Write the PolicyQualifier to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the object to.
+ * @exception IOException on errors.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ tmp.putOID(mId);
+ mQualifier.encode(tmp);
+ out.write(DerValue.tag_Sequence, tmp);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/PolicyQualifiers.java b/base/util/src/netscape/security/x509/PolicyQualifiers.java
new file mode 100644
index 000000000..ee756f50a
--- /dev/null
+++ b/base/util/src/netscape/security/x509/PolicyQualifiers.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.util.Vector;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * Represent the PolicyQualifiers.
+ *
+ * policyQualifiers ::= SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo
+ *
+ * @author Thomas Kwan
+ */
+public class PolicyQualifiers implements java.io.Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6932694408774694516L;
+ private Vector<PolicyQualifierInfo> mInfo = new Vector<PolicyQualifierInfo>();
+
+ /**
+ * Create a PolicyQualifiers with the ObjectIdentifier.
+ *
+ * @param id the ObjectIdentifier for the policy id.
+ */
+ public PolicyQualifiers() {
+ }
+
+ /**
+ * Create the object from its Der encoded value.
+ *
+ * @param val the DER encoded value for the same.
+ */
+ public PolicyQualifiers(DerValue val) throws IOException {
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding for " + "PolicyQualifiers.");
+ }
+ while (val.data.available() != 0) {
+ DerValue pq = val.data.getDerValue();
+ PolicyQualifierInfo info = new PolicyQualifierInfo(pq);
+ add(info);
+ }
+ }
+
+ public void add(PolicyQualifierInfo info) {
+ mInfo.addElement(info);
+ }
+
+ public int size() {
+ return mInfo.size();
+ }
+
+ public PolicyQualifierInfo getInfoAt(int i) {
+ return mInfo.elementAt(i);
+ }
+
+ /**
+ * Returns a printable representation of the CertificatePolicyId.
+ */
+ public String toString() {
+ String s = "PolicyQualifiers: [";
+ for (int i = 0; i < mInfo.size(); i++) {
+ PolicyQualifierInfo pq = mInfo.elementAt(i);
+ s = s + pq.toString();
+ }
+ s = s + "]\n";
+
+ return (s);
+ }
+
+ /**
+ * Write the PolicyQualifiers to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the object to.
+ * @exception IOException on errors.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ for (int i = 0; i < mInfo.size(); i++) {
+ PolicyQualifierInfo pq = mInfo.elementAt(i);
+ pq.encode(tmp);
+ }
+
+ out.write(DerValue.tag_Sequence, tmp);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/PrintableConverter.java b/base/util/src/netscape/security/x509/PrintableConverter.java
new file mode 100644
index 000000000..d63696d8f
--- /dev/null
+++ b/base/util/src/netscape/security/x509/PrintableConverter.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetEncoder;
+
+import netscape.security.util.ASN1CharStrConvMap;
+import netscape.security.util.DerValue;
+
+/**
+ * A AVAValueConverter that converts a Printable String attribute to a DerValue
+ * and vice versa. An example an attribute that is a printable string is "C".
+ *
+ * @see ASN1CharStrConvMap
+ * @see AVAValueConverter
+ *
+ * @author Lily Hsiao, Slava Galperin at Netscape Communications, Inc.
+ */
+
+public class PrintableConverter implements AVAValueConverter {
+ // public constructors.
+
+ public PrintableConverter() {
+ }
+
+ /**
+ * Converts a string with ASN.1 Printable characters to a DerValue.
+ *
+ * @param valueString a string with Printable characters.
+ *
+ * @return a DerValue.
+ *
+ * @exception IOException if a Printable encoder is not
+ * available for the conversion.
+ */
+ public DerValue getValue(String valueString)
+ throws IOException {
+ return getValue(valueString, null);
+ }
+
+ public DerValue getValue(String valueString, byte[] tags) throws IOException {
+ try {
+ CharsetEncoder encoder = ASN1CharStrConvMap.getDefault().getEncoder(DerValue.tag_PrintableString);
+ if (encoder == null)
+ throw new IOException("No encoder for printable");
+
+ CharBuffer charBuffer = CharBuffer.wrap(valueString.toCharArray());
+ ByteBuffer byteBuffer = encoder.encode(charBuffer);
+
+ return new DerValue(DerValue.tag_PrintableString,
+ byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.limit());
+
+ } catch (CharacterCodingException e) {
+ throw new IllegalArgumentException("Invalid Printable String AVA Value", e);
+ }
+ }
+
+ /**
+ * Converts a BER encoded value of PrintableString to a DER encoded value.
+ * Checks if the BER encoded value is a PrintableString.
+ * NOTE only DER encoded values are currently accepted on input.
+ *
+ * @param berStream A byte array of the BER encoded value.
+ *
+ * @return A DerValue.
+ *
+ * @exception IOException if the BER value cannot be converted to a
+ * PrintableString DER value.
+ */
+ public DerValue getValue(byte[] berStream)
+ throws IOException {
+ DerValue value = new DerValue(berStream);
+ if (value.tag != DerValue.tag_PrintableString)
+ throw new IOException("Invalid Printable String AVA Value");
+ return value;
+ }
+
+ /**
+ * Converts a DerValue of PrintableString to a java string with
+ * PrintableString characters.
+ *
+ * @param avaValue a DerValue.
+ *
+ * @return a string with PrintableString characters.
+ *
+ * @exception IOException if the DerValue is not a PrintableString i.e.
+ * The DerValue cannot be converted to a string
+ * with PrintableString characters.
+ */
+ public String getAsString(DerValue avaValue)
+ throws IOException {
+ return avaValue.getPrintableString();
+ }
+
+}
diff --git a/base/util/src/netscape/security/x509/PrivateKeyUsageExtension.java b/base/util/src/netscape/security/x509/PrivateKeyUsageExtension.java
new file mode 100644
index 000000000..e3ecdb33d
--- /dev/null
+++ b/base/util/src/netscape/security/x509/PrivateKeyUsageExtension.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.CertificateParsingException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class defines the Private Key Usage Extension.
+ *
+ * <p>
+ * The Private Key Usage Period extension allows the certificate issuer to specify a different validity period for the
+ * private key than the certificate. This extension is intended for use with digital signature keys. This extension
+ * consists of two optional components notBefore and notAfter. The private key associated with the certificate should
+ * not be used to sign objects before or after the times specified by the two components, respectively.
+ *
+ * <pre>
+ * PrivateKeyUsagePeriod ::= SEQUENCE {
+ * notBefore [0] GeneralizedTime OPTIONAL,
+ * notAfter [1] GeneralizedTime OPTIONAL }
+ * </pre>
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.12
+ * @see Extension
+ * @see CertAttrSet
+ */
+public class PrivateKeyUsageExtension extends Extension
+ implements CertAttrSet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7623695233957629936L;
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT = "x509.info.extensions.PrivateKeyUsage";
+ /**
+ * Sub attributes name for this CertAttrSet.
+ */
+ public static final String NAME = "PrivateKeyUsage";
+ public static final String NOT_BEFORE = "not_before";
+ public static final String NOT_AFTER = "not_after";
+
+ // Private data members
+ private static final byte TAG_BEFORE = 0;
+ private static final byte TAG_AFTER = 1;
+
+ private Date notBefore;
+ private Date notAfter;
+
+ // Encode this extension value.
+ private void encodeThis() throws IOException {
+ DerOutputStream seq = new DerOutputStream();
+
+ DerOutputStream tagged = new DerOutputStream();
+ if (notBefore != null) {
+ DerOutputStream tmp = new DerOutputStream();
+ tmp.putGeneralizedTime(notBefore);
+ tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
+ false, TAG_BEFORE), tmp);
+ }
+ if (notAfter != null) {
+ DerOutputStream tmp = new DerOutputStream();
+ tmp.putGeneralizedTime(notAfter);
+ tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
+ false, TAG_AFTER), tmp);
+ }
+ seq.write(DerValue.tag_Sequence, tagged);
+ extensionValue = seq.toByteArray();
+ }
+
+ /**
+ * The default constructor for PrivateKeyUsageExtension.
+ *
+ * @param notBefore the date/time before which the private key
+ * should not be used.
+ * @param notAfter the date/time after which the private key
+ * should not be used.
+ */
+ public PrivateKeyUsageExtension(Date notBefore, Date notAfter)
+ throws IOException {
+ this.notBefore = notBefore;
+ this.notAfter = notAfter;
+
+ this.extensionId = PKIXExtensions.PrivateKeyUsage_Id;
+ this.critical = false;
+ encodeThis();
+ }
+
+ /**
+ * Create the extension from the passed DER encoded value.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param value Array of DER encoded bytes of the actual value.
+ *
+ * @exception CertificateException on certificate parsing errors.
+ * @exception IOException on error.
+ */
+ public PrivateKeyUsageExtension(Boolean critical, Object value)
+ throws CertificateException, IOException {
+ this.extensionId = PKIXExtensions.PrivateKeyUsage_Id;
+ this.critical = critical.booleanValue();
+
+ if (!(value instanceof byte[]))
+ throw new CertificateException("Illegal argument type");
+
+ int len = Array.getLength(value);
+ byte[] extValue = new byte[len];
+ System.arraycopy(value, 0, extValue, 0, len);
+
+ this.extensionValue = extValue;
+ DerInputStream str = new DerInputStream(extValue);
+ DerValue[] seq = str.getSequence(2);
+
+ // NB. this is always encoded with the IMPLICIT tag
+ // The checks only make sense if we assume implicit tagging,
+ // with explicit tagging the form is always constructed.
+ for (int i = 0; i < seq.length; i++) {
+ DerValue opt = seq[i];
+
+ if (opt.isContextSpecific((byte) TAG_BEFORE) &&
+ !opt.isConstructed()) {
+ if (notBefore != null) {
+ throw new CertificateParsingException(
+ "Duplicate notBefore in PrivateKeyUsage.");
+ }
+ opt.resetTag(DerValue.tag_GeneralizedTime);
+ str = new DerInputStream(opt.toByteArray());
+ notBefore = str.getGeneralizedTime();
+
+ } else if (opt.isContextSpecific((byte) TAG_AFTER) &&
+ !opt.isConstructed()) {
+ if (notAfter != null) {
+ throw new CertificateParsingException(
+ "Duplicate notAfter in PrivateKeyUsage.");
+ }
+ opt.resetTag(DerValue.tag_GeneralizedTime);
+ str = new DerInputStream(opt.toByteArray());
+ notAfter = str.getGeneralizedTime();
+ } else
+ throw new IOException("Invalid encoding of " +
+ "PrivateKeyUsageExtension");
+ }
+ }
+
+ /**
+ * Return the printable string.
+ */
+ public String toString() {
+ return (super.toString() +
+ "PrivateKeyUsage: [From: " +
+ ((notBefore == null) ? "" : notBefore.toString()) +
+ ", To: " +
+ ((notAfter == null) ? "" : notAfter.toString()) + "]\n");
+ }
+
+ /**
+ * Return notBefore date
+ */
+ public Date getNotBefore() {
+ return (notBefore);
+ }
+
+ /**
+ * Return notAfter date
+ */
+ public Date getNotAfter() {
+ return (notAfter);
+ }
+
+ /**
+ * Verify that that the current time is within the validity period.
+ *
+ * @exception CertificateExpiredException if the certificate has expired.
+ * @exception CertificateNotYetValidException if the certificate is not
+ * yet valid.
+ */
+ public void valid()
+ throws CertificateNotYetValidException, CertificateExpiredException {
+ Date now = new Date();
+ valid(now);
+ }
+
+ /**
+ * Verify that that the passed time is within the validity period.
+ *
+ * @exception CertificateExpiredException if the certificate has expired
+ * with respect to the <code>Date</code> supplied.
+ * @exception CertificateNotYetValidException if the certificate is not
+ * yet valid with respect to the <code>Date</code> supplied.
+ *
+ */
+ public void valid(Date now)
+ throws CertificateNotYetValidException, CertificateExpiredException {
+ /*
+ * we use the internal Dates rather than the passed in Date
+ * because someone could override the Date methods after()
+ * and before() to do something entirely different.
+ */
+ if (notBefore.after(now)) {
+ throw new CertificateNotYetValidException("NotBefore: " +
+ notBefore.toString());
+ }
+ if (notAfter.before(now)) {
+ throw new CertificateExpiredException("NotAfter: " +
+ notAfter.toString());
+ }
+ }
+
+ /**
+ * Write the extension to the OutputStream.
+ *
+ * @param out the OutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ if (extensionValue == null) {
+ extensionId = PKIXExtensions.PrivateKeyUsage_Id;
+ critical = false;
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Decode the extension from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception CertificateException on decoding errors.
+ */
+ public void decode(InputStream in) throws CertificateException {
+ throw new CertificateException("Method not to be called directly.");
+ }
+
+ /**
+ * Set the attribute value.
+ *
+ * @exception CertificateException on attribute handling errors.
+ */
+ public void set(String name, Object obj)
+ throws CertificateException {
+ clearValue();
+ if (!(obj instanceof Date)) {
+ throw new CertificateException("Attribute must be of type Date.");
+ }
+ if (name.equalsIgnoreCase(NOT_BEFORE)) {
+ notBefore = (Date) obj;
+ } else if (name.equalsIgnoreCase(NOT_AFTER)) {
+ notAfter = (Date) obj;
+ } else {
+ throw new CertificateException("Attribute name not recognized by"
+ + " CertAttrSet:PrivateKeyUsage.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ *
+ * @exception CertificateException on attribute handling errors.
+ */
+ public Object get(String name) throws CertificateException {
+ if (name.equalsIgnoreCase(NOT_BEFORE)) {
+ return (new Date(notBefore.getTime()));
+ } else if (name.equalsIgnoreCase(NOT_AFTER)) {
+ return (new Date(notAfter.getTime()));
+ } else {
+ throw new CertificateException("Attribute name not recognized by"
+ + " CertAttrSet:PrivateKeyUsage.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ *
+ * @exception CertificateException on attribute handling errors.
+ */
+ public void delete(String name) throws CertificateException {
+ if (name.equalsIgnoreCase(NOT_BEFORE)) {
+ notBefore = null;
+ } else if (name.equalsIgnoreCase(NOT_AFTER)) {
+ notAfter = null;
+ } else {
+ throw new CertificateException("Attribute name not recognized by"
+ + " CertAttrSet:PrivateKeyUsage.");
+ }
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(NOT_BEFORE);
+ elements.addElement(NOT_AFTER);
+
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/Qualifier.java b/base/util/src/netscape/security/x509/Qualifier.java
new file mode 100644
index 000000000..7c0c7edfe
--- /dev/null
+++ b/base/util/src/netscape/security/x509/Qualifier.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 netscape.security.x509;
+
+import java.io.IOException;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * Represent the Qualifier.
+ *
+ * Qualifier ::= CHOICE {
+ * cPRuri CPSuri,
+ * userNotice UserNotice
+ * }
+ *
+ * @author Thomas Kwan
+ */
+public class Qualifier implements java.io.Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2214531407387992974L;
+
+ /**
+ * Create a PolicyQualifierInfo
+ *
+ * @param id the ObjectIdentifier for the policy id.
+ */
+ public Qualifier() {
+ }
+
+ public Qualifier(DerValue val) throws IOException {
+ // needs to override this
+ }
+
+ /**
+ * Write the PolicyQualifier to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the object to.
+ * @exception IOException on errors.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ // needs to override this
+ }
+}
diff --git a/base/util/src/netscape/security/x509/RDN.java b/base/util/src/netscape/security/x509/RDN.java
new file mode 100644
index 000000000..c5e8765a0
--- /dev/null
+++ b/base/util/src/netscape/security/x509/RDN.java
@@ -0,0 +1,303 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * RDNs are a set of {attribute = value} assertions. Some of those
+ * attributes are "distinguished" (unique w/in context). Order is
+ * never relevant.
+ *
+ * Some X.500 names include only a single distinguished attribute
+ * per RDN. This style is currently common.
+ *
+ * Note that DER-encoded RDNs sort AVAs by assertion OID ... so that
+ * when we parse this data we don't have to worry about canonicalizing
+ * it, but we'll need to sort them when we expose the RDN class more.
+ *
+ * @see X500Name
+ * @see AVA
+ * @see LdapDNStrConverter
+ */
+
+public class RDN {
+ // public constructors
+
+ /**
+ * Constructs a RDN from a Ldap DN String with one RDN component
+ * using the global default LdapDNStrConverter.
+ *
+ * @see LdapDNStrConverter
+ * @param rdnString a Ldap DN string with one RDN component, e.g. as
+ * defined in RFC1779.
+ * @exception IOException if error occurs while parsing the string.
+ */
+ public RDN(String rdnString)
+ throws IOException {
+ RDN rdn = LdapDNStrConverter.getDefault().parseRDN(rdnString);
+ assertion = rdn.getAssertion();
+ }
+
+ /**
+ * Like RDN(String) with a DER encoding order given as argument for
+ * Directory Strings.
+ */
+ public RDN(String rdnString, byte[] tags)
+ throws IOException {
+ RDN rdn = LdapDNStrConverter.getDefault().parseRDN(rdnString, tags);
+ assertion = rdn.getAssertion();
+ }
+
+ /**
+ * Constructs a RDN from a Ldap DN string with one RDN component
+ * using the specified Ldap DN Str converter.
+ * For example, RFC1779StrConverter can be passed to parse a Ldap
+ * DN string in RFC1779 format.
+ *
+ * @see LdapDNStrConverter
+ * @param rdnString Ldap DN string.
+ * @param ldapDNStrConverter a LdapDNStrConverter.
+ */
+ public RDN(String rdnString, LdapDNStrConverter ldapDNStrConverter)
+ throws IOException {
+ RDN rdn = ldapDNStrConverter.parseRDN(rdnString);
+ assertion = rdn.getAssertion();
+ }
+
+ /**
+ * Constructs a RDN from a DerValue.
+ *
+ * @param set Der value of a set of AVAs.
+ */
+ public RDN(DerValue set) throws IOException {
+ if (set.tag != DerValue.tag_Set)
+ throw new CertParseError("X500 RDN");
+
+ int j_max = 50; // XXX j_max = f(data)!!
+ int j;
+ int i;
+
+ AVA[] avas = new AVA[j_max];
+
+ // create a temporary array big enough for a huge set of AVA's
+ for (j = 0; j < j_max; j++) {
+ avas[j] = new AVA(set.data);
+ if (set.data.available() == 0)
+ break;
+ }
+
+ // copy the elements into it
+ if (j >= j_max - 1) {
+ assertion = new AVA[j + 1];
+ } else {
+ assertion = new AVA[j + 1];
+ for (i = 0; i < (j + 1); i++) {
+ assertion[i] = avas[i];
+ }
+ }
+
+ /*
+ if (set.data.available () != 0)
+ // throw new CertParseError ("X500 RDN 2");
+ System.out.println (" ... RDN parse, ignored bytes = "
+ + set.data.available ());
+ */
+ }
+
+ /**
+ * Constructs a RDN from a Der Input Stream.
+ *
+ * @param in a Der Input Stream.
+ */
+ public RDN(DerInputStream in) throws IOException {
+ /* an RDN is a SET of avas */
+ DerValue avaset[] = in.getSet(1);
+ int i;
+ assertion = new AVA[avaset.length];
+ for (i = 0; i < assertion.length; i++)
+ assertion[i] = new AVA(avaset[i].data);
+ }
+
+ /**
+ * Constructs a RDN from an array of AVA.
+ *
+ * @param avas a AVA Array.
+ */
+ public RDN(AVA avas[]) {
+ assertion = (AVA[]) avas.clone();
+ }
+
+ /**
+ * convenience method.
+ */
+ public RDN(Vector<AVA> avaVector) {
+ int size = avaVector.size();
+ assertion = new AVA[size];
+ for (int i = 0; i < size; i++) {
+ assertion[i] = avaVector.elementAt(i);
+ }
+ }
+
+ /**
+ * returns an array of AVA in the RDN.
+ *
+ * @return array of AVA in this RDN.
+ */
+ public AVA[] getAssertion() {
+ return (AVA[]) assertion.clone();
+ }
+
+ /**
+ * returns the number of AVAs in the RDN.
+ *
+ * @return number of AVAs in this RDN.
+ */
+ public int getAssertionLength() {
+ return assertion.length;
+ }
+
+ private AVA assertion[];
+
+ private class AVAEnumerator implements Enumeration<AVA> {
+ private int index;
+
+ public AVAEnumerator() {
+ index = 0;
+ }
+
+ public boolean hasMoreElements() {
+ return (index < assertion.length);
+ }
+
+ public AVA nextElement() {
+ if (index >= assertion.length)
+ return null;
+ return assertion[index++];
+ }
+ }
+
+ // other public methods.
+
+ /**
+ * Checks if this RDN is the same as another by comparing the AVAs
+ * in the RDNs.
+ *
+ * @param other the other RDN.
+ * @return true iff the other RDN is the same.
+ */
+ public boolean equals(RDN other) {
+ int i;
+
+ if (other == this)
+ return true;
+ if (assertion.length != other.assertion.length)
+ return false;
+
+ for (i = 0; i < assertion.length; i++)
+ if (!assertion[i].equals(other.assertion[i]))
+ return false;
+
+ return true;
+ }
+
+ DerValue findAttribute(ObjectIdentifier oid) {
+ int i;
+
+ for (i = 0; i < assertion.length; i++)
+ if (assertion[i].oid.equals(oid))
+ return assertion[i].value;
+ return null;
+ }
+
+ /**
+ * Encodes this RDN to a Der output stream.
+ *
+ * @param out the Der Output Stream.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ int i;
+
+ for (i = 0; i < assertion.length; i++)
+ assertion[i].encode(tmp);
+ out.write(DerValue.tag_Set, tmp);
+ }
+
+ /**
+ * returns an enumeration of AVAs that make up this RDN.
+ *
+ * @return an enumeration of AVAs that make up this RDN.
+ */
+ public Enumeration<AVA> getAVAs() {
+ return new AVAEnumerator();
+ }
+
+ /**
+ * Returns a Ldap DN string with one RDN component using the
+ * global default LdapDNStrConverter.
+ *
+ * @see LdapDNStrConverter
+ * @return the Ldap DN String of this RDN.
+ * @exception IOException if an error occurs during the conversion.
+ */
+ public String toLdapDNString()
+ throws IOException {
+ return LdapDNStrConverter.getDefault().encodeRDN(this);
+ }
+
+ /**
+ * Returns a Ldap DN String with this RDN component using the specified
+ * LdapDNStrConverter.
+ *
+ * @see LdapDNStrConverter
+ * @param ldapDNStrConverter a LdapDNStrConverter.
+ * @return a Ldap DN String.
+ * @exception IOException if an error occurs in the conversion.
+ */
+ public String toLdapDNString(LdapDNStrConverter ldapDNStrConverter)
+ throws IOException {
+ return ldapDNStrConverter.encodeRDN(this);
+ }
+
+ /**
+ * Returns a Ldap DN string with this RDN component using the global
+ * default LdapDNStrConverter.
+ *
+ * @see LdapDNStrConverter
+ * @return the Ldap DN String with this RDN component, null if an error
+ * occurs in the conversion.
+ */
+ public String toString() {
+ String s;
+ try {
+ s = toLdapDNString();
+ } catch (IOException e) {
+ return null;
+ }
+ return s;
+ }
+
+}
diff --git a/base/util/src/netscape/security/x509/RFC1779StrConverter.java b/base/util/src/netscape/security/x509/RFC1779StrConverter.java
new file mode 100644
index 000000000..6527d0fff
--- /dev/null
+++ b/base/util/src/netscape/security/x509/RFC1779StrConverter.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 netscape.security.x509;
+
+import java.io.IOException;
+
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * Converts a RFC 1779 string to a X500Name, RDN or AVA object and vice versa.
+ *
+ * @see LdapDNStrConverter
+ * @see LdapV3DNStrConverter
+ *
+ * @author Lily Hsiao, Slava Galperin at Netscape Communications, Inc.
+ */
+
+public class RFC1779StrConverter extends LdapV3DNStrConverter {
+ //
+ // Constructors.
+ //
+
+ /**
+ * Constructs a RFC1779StrConverter using the global default
+ * X500NameAttrMap and accepts OIDs not listed in the attribute map.
+ */
+ public RFC1779StrConverter() {
+ super();
+ }
+
+ /**
+ * Constructs a RFC1779StrConverter using the specified X500NameAttrMap
+ * and boolean for whether to accept OIDs not in the X500NameAttrMap.
+ *
+ * @param attributeMap A X500NameAttrMap to use for this converter.
+ * @param doAcceptUnknownOids Accept unregistered attributes, i.e. OIDs
+ * not in the map).
+ */
+ public RFC1779StrConverter(X500NameAttrMap attributeMap,
+ boolean doAcceptUnknownOids) {
+ super(attributeMap, doAcceptUnknownOids);
+ }
+
+ //
+ // overriding methods.
+ //
+
+ /**
+ * Converts a OID to a attribute keyword in a Ldap DN string or
+ * to a "OID.1.2.3.4" string syntax as defined in RFC1779.
+ *
+ * @param oid an ObjectIdentifier.
+ *
+ * @return a attribute keyword or "OID.1.2.3.4" string.
+ *
+ * @exception IOException if an error occurs during the conversion.
+ */
+ public String encodeOID(ObjectIdentifier oid)
+ throws IOException {
+ String keyword = attrMap.getName(oid);
+ if (keyword == null)
+ if (!acceptUnknownOids)
+ throw new IllegalArgumentException("Unrecognized OID");
+ else
+ keyword = "OID" + "." + oid.toString();
+ return keyword;
+ }
+
+ /**
+ * Converts a attribute value as a DerValue to a string in a
+ * RFC1779 Ldap DN string.
+ *
+ * @param attrValue an attribute value.
+ * @param oid ObjectIdentifier for the attribute.
+ * @return a string in RFC1779 syntax.
+ * @exception IOException if an error occurs during the conversion.
+ */
+ public String encodeValue(DerValue attrValue, ObjectIdentifier oid)
+ throws IOException {
+ String s = super.encodeValue(attrValue, oid);
+ if (s.indexOf('\n') != -1)
+ return "\"" + s + "\"";
+ else
+ return s;
+ }
+}
diff --git a/base/util/src/netscape/security/x509/RFC822Name.java b/base/util/src/netscape/security/x509/RFC822Name.java
new file mode 100644
index 000000000..257b5c51d
--- /dev/null
+++ b/base/util/src/netscape/security/x509/RFC822Name.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 netscape.security.x509;
+
+import java.io.IOException;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class implements the RFC822Name as required by the GeneralNames
+ * ASN.1 object.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.3
+ * @see GeneralName
+ * @see GeneralNames
+ * @see GeneralNameInterface
+ */
+public class RFC822Name implements GeneralNameInterface {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1453025303548809007L;
+ private String name;
+
+ /**
+ * Create the RFC822Name object from the passed encoded Der value.
+ *
+ * @param derValue the encoded DER RFC822Name.
+ * @exception IOException on error.
+ */
+ public RFC822Name(DerValue derValue) throws IOException {
+ name = derValue.getIA5String();
+ }
+
+ /**
+ * Create the RFC822Name object with the specified name.
+ *
+ * @param name the RFC822Name.
+ */
+ public RFC822Name(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Return the type of the GeneralName.
+ */
+ public int getType() {
+ return (GeneralNameInterface.NAME_RFC822);
+ }
+
+ /**
+ * Encode the RFC822 name into the DerOutputStream.
+ *
+ * @param out the DER stream to encode the RFC822Name to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ out.putIA5String(name);
+ }
+
+ /**
+ * Convert the name into user readable string.
+ */
+ public String toString() {
+ return ("RFC822Name: " + name);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/ReasonFlags.java b/base/util/src/netscape/security/x509/ReasonFlags.java
new file mode 100755
index 000000000..e43c7022c
--- /dev/null
+++ b/base/util/src/netscape/security/x509/ReasonFlags.java
@@ -0,0 +1,283 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.BitArray;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * Represent the CRL Reason Flags.
+ *
+ * <p>
+ * This extension, if present, defines the identifies the reason for the certificate revocation.
+ *
+ * @author Hemma Prafullchandra
+ * @version 1.3
+ * @see Extension
+ * @see CertAttrSet
+ */
+public class ReasonFlags {
+
+ /**
+ * Reasons
+ */
+ public static final String UNUSED = "unused";
+ public static final String KEY_COMPROMISE = "key_compromise";
+ public static final String CA_COMPROMISE = "ca_compromise";
+ public static final String AFFLIATION_CHANGED = "affliation_changed";
+ public static final String SUPERSEDED = "superseded";
+ public static final String CESSATION_OF_OPERATION = "cessation_of_operation";
+ public static final String CERTIFICATION_HOLD = "certification_hold";
+ public static final String PRIVILEGE_WITHDRAWN = "privilege_withdrawn";
+ public static final String AA_COMPROMISE = "aa_compromise";
+
+ // Private data members
+ private boolean[] bitString;
+
+ /**
+ * Check if bit is set.
+ *
+ * @param position the position in the bit string to check.
+ */
+ private boolean isSet(int position) {
+ return bitString[position];
+ }
+
+ /**
+ * Set the bit at the specified position.
+ */
+ private void set(int position, boolean val) {
+ // enlarge bitString if necessary
+ if (position >= bitString.length) {
+ boolean[] tmp = new boolean[position + 1];
+ System.arraycopy(bitString, 0, tmp, 0, bitString.length);
+ bitString = tmp;
+ }
+ bitString[position] = val;
+ }
+
+ /**
+ * Create a ReasonFlags with the passed bit settings.
+ *
+ * @param reasons the bits to be set for the ReasonFlags.
+ */
+ public ReasonFlags(byte[] reasons) {
+ bitString = new BitArray(reasons.length * 8, reasons).toBooleanArray();
+ }
+
+ /**
+ * Create a ReasonFlags with the passed bit settings.
+ *
+ * @param reasons the bits to be set for the ReasonFlags.
+ */
+ public ReasonFlags(boolean[] reasons) {
+ this.bitString = reasons;
+ }
+
+ /**
+ * Create a ReasonFlags with the passed bit settings.
+ *
+ * @param reasons the bits to be set for the ReasonFlags.
+ */
+ public ReasonFlags(BitArray reasons) {
+ this.bitString = reasons.toBooleanArray();
+ }
+
+ /**
+ * Create the object from the passed DER encoded value.
+ *
+ * @param in the DerInputStream to read the ReasonFlags from.
+ * @exception IOException on decoding errors.
+ */
+ public ReasonFlags(DerInputStream in) throws IOException {
+ DerValue derVal = in.getDerValue();
+ this.bitString = derVal.getUnalignedBitString(true).toBooleanArray();
+ }
+
+ /**
+ * Create the object from the passed DER encoded value.
+ *
+ * @param derVal the DerValue decoded from the stream.
+ * @exception IOException on decoding errors.
+ */
+ public ReasonFlags(DerValue derVal) throws IOException {
+ this.bitString = derVal.getUnalignedBitString(true).toBooleanArray();
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ if (!(obj instanceof Boolean)) {
+ throw new IOException("Attribute must be of type Boolean.");
+ }
+ boolean val = ((Boolean) obj).booleanValue();
+ if (name.equalsIgnoreCase(UNUSED)) {
+ set(0, val);
+ } else if (name.equalsIgnoreCase(KEY_COMPROMISE)) {
+ set(1, val);
+ } else if (name.equalsIgnoreCase(CA_COMPROMISE)) {
+ set(2, val);
+ } else if (name.equalsIgnoreCase(AFFLIATION_CHANGED)) {
+ set(3, val);
+ } else if (name.equalsIgnoreCase(SUPERSEDED)) {
+ set(4, val);
+ } else if (name.equalsIgnoreCase(CESSATION_OF_OPERATION)) {
+ set(5, val);
+ } else if (name.equalsIgnoreCase(CERTIFICATION_HOLD)) {
+ set(6, val);
+ } else if (name.equalsIgnoreCase(PRIVILEGE_WITHDRAWN)) {
+ set(7, val);
+ } else if (name.equalsIgnoreCase(AA_COMPROMISE)) {
+ set(8, val);
+ } else {
+ throw new IOException("Name not recognized by ReasonFlags");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(UNUSED)) {
+ return new Boolean(isSet(0));
+ } else if (name.equalsIgnoreCase(KEY_COMPROMISE)) {
+ return new Boolean(isSet(1));
+ } else if (name.equalsIgnoreCase(CA_COMPROMISE)) {
+ return new Boolean(isSet(2));
+ } else if (name.equalsIgnoreCase(AFFLIATION_CHANGED)) {
+ return new Boolean(isSet(3));
+ } else if (name.equalsIgnoreCase(SUPERSEDED)) {
+ return new Boolean(isSet(4));
+ } else if (name.equalsIgnoreCase(CESSATION_OF_OPERATION)) {
+ return new Boolean(isSet(5));
+ } else if (name.equalsIgnoreCase(CERTIFICATION_HOLD)) {
+ return new Boolean(isSet(6));
+ } else if (name.equalsIgnoreCase(PRIVILEGE_WITHDRAWN)) {
+ return new Boolean(isSet(7));
+ } else if (name.equalsIgnoreCase(AA_COMPROMISE)) {
+ return new Boolean(isSet(8));
+ } else {
+ throw new IOException("Name not recognized by ReasonFlags");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(UNUSED)) {
+ set(0, false);
+ } else if (name.equalsIgnoreCase(KEY_COMPROMISE)) {
+ set(1, false);
+ } else if (name.equalsIgnoreCase(CA_COMPROMISE)) {
+ set(2, false);
+ } else if (name.equalsIgnoreCase(AFFLIATION_CHANGED)) {
+ set(3, false);
+ } else if (name.equalsIgnoreCase(SUPERSEDED)) {
+ set(4, false);
+ } else if (name.equalsIgnoreCase(CESSATION_OF_OPERATION)) {
+ set(5, false);
+ } else if (name.equalsIgnoreCase(CERTIFICATION_HOLD)) {
+ set(6, false);
+ } else if (name.equalsIgnoreCase(PRIVILEGE_WITHDRAWN)) {
+ set(7, false);
+ } else if (name.equalsIgnoreCase(AA_COMPROMISE)) {
+ set(8, false);
+ } else {
+ throw new IOException("Name not recognized by ReasonFlags");
+ }
+ }
+
+ /**
+ * Returns a printable representation of the ReasonFlags.
+ */
+ public String toString() {
+ String s = super.toString() + "Reason Flags [\n";
+
+ try {
+ if (isSet(0)) {
+ s += " Unused\n";
+ }
+ if (isSet(1)) {
+ s += " Key Compromise\n";
+ }
+ if (isSet(2)) {
+ s += " CA_Compromise\n";
+ }
+ if (isSet(3)) {
+ s += " Affiliation_Changed\n";
+ }
+ if (isSet(4)) {
+ s += " Superseded\n";
+ }
+ if (isSet(5)) {
+ s += " Cessation Of Operation\n";
+ }
+ if (isSet(6)) {
+ s += " Certificate Hold\n";
+ }
+ if (isSet(7)) {
+ s += " Privilege Withdrawn\n";
+ }
+ if (isSet(8)) {
+ s += " AA Compromise\n";
+ }
+ } catch (ArrayIndexOutOfBoundsException ex) {
+ }
+
+ s += "]\n";
+
+ return (s);
+ }
+
+ /**
+ * Write the extension to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ out.putUnalignedBitString(new BitArray(this.bitString));
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getElements() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(UNUSED);
+ elements.addElement(KEY_COMPROMISE);
+ elements.addElement(CA_COMPROMISE);
+ elements.addElement(AFFLIATION_CHANGED);
+ elements.addElement(SUPERSEDED);
+ elements.addElement(CESSATION_OF_OPERATION);
+ elements.addElement(CERTIFICATION_HOLD);
+ elements.addElement(PRIVILEGE_WITHDRAWN);
+ elements.addElement(AA_COMPROMISE);
+
+ return (elements.elements());
+ }
+}
diff --git a/base/util/src/netscape/security/x509/RevocationReason.java b/base/util/src/netscape/security/x509/RevocationReason.java
new file mode 100644
index 000000000..419eb1772
--- /dev/null
+++ b/base/util/src/netscape/security/x509/RevocationReason.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 netscape.security.x509;
+
+/**
+ * Represent the enumerated type used in CRLReason Extension of CRL entry.
+ *
+ *
+ * @author galperin
+ * @version $Revision$, $Date$
+ */
+
+public final class RevocationReason {
+ /**
+ * Reasons
+ */
+ public static final RevocationReason UNSPECIFIED = new RevocationReason(0);
+ public static final RevocationReason KEY_COMPROMISE = new RevocationReason(1);
+ public static final RevocationReason CA_COMPROMISE = new RevocationReason(2);
+ public static final RevocationReason AFFILIATION_CHANGED = new RevocationReason(3);
+ public static final RevocationReason SUPERSEDED = new RevocationReason(4);
+ public static final RevocationReason CESSATION_OF_OPERATION = new RevocationReason(5);
+ public static final RevocationReason CERTIFICATE_HOLD = new RevocationReason(6);
+ public static final RevocationReason REMOVE_FROM_CRL = new RevocationReason(8);
+ public static final RevocationReason PRIVILEGE_WITHDRAWN = new RevocationReason(9);
+ public static final RevocationReason AA_COMPROMISE = new RevocationReason(10);
+
+ // Private data members
+ private int mReason;
+
+ /**
+ * Create a RevocationReason with the passed integer value.
+ *
+ * @param reason integer value of the enumeration alternative.
+ */
+ private RevocationReason(int reason) {
+ this.mReason = reason;
+ }
+
+ public int toInt() {
+ return mReason;
+ }
+
+ public static RevocationReason fromInt(int reason) {
+ if (reason == UNSPECIFIED.mReason)
+ return UNSPECIFIED;
+ if (reason == KEY_COMPROMISE.mReason)
+ return KEY_COMPROMISE;
+ if (reason == CA_COMPROMISE.mReason)
+ return CA_COMPROMISE;
+ if (reason == AFFILIATION_CHANGED.mReason)
+ return AFFILIATION_CHANGED;
+ if (reason == SUPERSEDED.mReason)
+ return SUPERSEDED;
+ if (reason == CESSATION_OF_OPERATION.mReason)
+ return CESSATION_OF_OPERATION;
+ if (reason == CERTIFICATE_HOLD.mReason)
+ return CERTIFICATE_HOLD;
+ if (reason == REMOVE_FROM_CRL.mReason)
+ return REMOVE_FROM_CRL;
+ if (reason == PRIVILEGE_WITHDRAWN.mReason)
+ return PRIVILEGE_WITHDRAWN;
+ if (reason == AA_COMPROMISE.mReason)
+ return AA_COMPROMISE;
+ return null;
+ }
+
+ public boolean equals(Object other) {
+ if (this == other)
+ return true;
+ else if (other instanceof RevocationReason)
+ return ((RevocationReason) other).mReason == mReason;
+ else
+ return false;
+ }
+
+ public int hashCode() {
+ return mReason;
+ }
+
+ public String toString() {
+ if (equals(UNSPECIFIED))
+ return "Unspecified";
+ if (equals(KEY_COMPROMISE))
+ return "Key_Compromise";
+ if (equals(CA_COMPROMISE))
+ return "CA_Compromise";
+ if (equals(AFFILIATION_CHANGED))
+ return "Affiliation_Changed";
+ if (equals(SUPERSEDED))
+ return "Superseded";
+ if (equals(CESSATION_OF_OPERATION))
+ return "Cessation_of_Operation";
+ if (equals(CERTIFICATE_HOLD))
+ return "Certificate_Hold";
+ if (equals(REMOVE_FROM_CRL))
+ return "Remove_from_CRL";
+ if (equals(PRIVILEGE_WITHDRAWN))
+ return "Privilege_Withdrawn";
+ if (equals(AA_COMPROMISE))
+ return "AA_Compromise";
+ return "[UNDEFINED]";
+ }
+}
diff --git a/base/util/src/netscape/security/x509/RevokedCertImpl.java b/base/util/src/netscape/security/x509/RevokedCertImpl.java
new file mode 100755
index 000000000..345694fb1
--- /dev/null
+++ b/base/util/src/netscape/security/x509/RevokedCertImpl.java
@@ -0,0 +1,454 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.security.cert.CRLException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * <p>
+ * Abstract class for a revoked certificate in a CRL. This class is for each entry in the
+ * <code>revokedCertificates</code>, so it deals with the inner <em>SEQUENCE</em>. The ASN.1 definition for this is:
+ *
+ * <pre>
+ * revokedCertificates SEQUENCE OF SEQUENCE {
+ * userCertificate CertificateSerialNumber,
+ * revocationDate ChoiceOfTime,
+ * crlEntryExtensions Extensions OPTIONAL
+ * -- if present, must be v2
+ * } OPTIONAL
+ *
+ * CertificateSerialNumber ::= INTEGER
+ *
+ * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+ *
+ * Extension ::= SEQUENCE {
+ * extnId OBJECT IDENTIFIER,
+ * critical BOOLEAN DEFAULT FALSE,
+ * extnValue OCTET STRING
+ * -- contains a DER encoding of a value
+ * -- of the type registered for use with
+ * -- the extnId object identifier value
+ * }
+ * </pre>
+ *
+ * @author Hemma Prafullchandra
+ * @version 1.6 97/12/10
+ */
+
+public class RevokedCertImpl extends RevokedCertificate implements Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3449642360223397701L;
+
+ private SerialNumber serialNumber;
+ private Date revocationDate;
+ private CRLExtensions extensions = null;
+ private byte[] revokedCert;
+ private final static boolean isExplicit = false;
+
+ /**
+ * Default constructor.
+ */
+ public RevokedCertImpl() {
+ }
+
+ /**
+ * Constructs a revoked certificate entry using the serial number and
+ * revocation date.
+ *
+ * @param num
+ * the serial number of the revoked certificate.
+ * @param date
+ * the Date on which revocation took place.
+ */
+ public RevokedCertImpl(BigInteger num, Date date) {
+ this.serialNumber = new SerialNumber(num);
+ this.revocationDate = date;
+ }
+
+ /**
+ * Constructs a revoked certificate entry using the serial number,
+ * revocation date and the entry extensions.
+ *
+ * @param num
+ * the serial number of the revoked certificate.
+ * @param date
+ * the Date on which revocation took place.
+ * @param crlEntryExts
+ * the extensions for this entry.
+ */
+ public RevokedCertImpl(BigInteger num, Date date, CRLExtensions crlEntryExts) {
+ this.serialNumber = new SerialNumber(num);
+ this.revocationDate = date;
+ this.extensions = crlEntryExts;
+ }
+
+ public byte[] getEncoded() throws CRLException {
+ // XXX NOT IMPLEMENTED
+ if (revokedCert == null) {
+ DerOutputStream os = new DerOutputStream();
+ try {
+ encode(os);
+ } catch (Exception e) {
+ // revokedCert = null;
+ }
+ revokedCert = os.toByteArray();
+ }
+ return revokedCert;
+ }
+
+ public boolean hasUnsupportedCriticalExtension() {
+ // XXX NOT IMPLEMENTED
+ return true;
+ }
+
+ /**
+ * Sets extensions for this impl.
+ *
+ * @param crlEntryExts
+ * CRLExtensions
+ */
+ public void setExtensions(CRLExtensions crlEntryExts) {
+ this.extensions = crlEntryExts;
+ }
+
+ /**
+ * Unmarshals a revoked certificate from its encoded form.
+ *
+ * @param revokedCert
+ * the encoded bytes.
+ * @exception CRLException
+ * on parsing errors.
+ * @exception X509ExtensionException
+ * on extension handling errors.
+ */
+ public RevokedCertImpl(byte[] revokedCert) throws CRLException,
+ X509ExtensionException {
+ try {
+ DerValue derValue = new DerValue(revokedCert);
+ parse(derValue);
+ } catch (IOException e) {
+ throw new CRLException("Parsing error: " + e.toString());
+ }
+ }
+
+ /**
+ * Unmarshals a revoked certificate from its encoded form.
+ *
+ * @param derValue
+ * the DER value containing the revoked certificate.
+ * @exception CRLException
+ * on parsing errors.
+ * @exception X509ExtensionException
+ * on extension handling errors.
+ */
+ public RevokedCertImpl(DerValue derValue) throws CRLException,
+ X509ExtensionException {
+ parse(derValue);
+ }
+
+ /**
+ * Returns true if this revoked certificate entry has extensions, otherwise
+ * false.
+ *
+ * @return true if this CRL entry has extensions, otherwise false.
+ */
+ public boolean hasExtensions() {
+ if (extensions == null)
+ return false;
+ else
+ return true;
+ }
+
+ /**
+ * Decode a revoked certificate from an input stream.
+ *
+ * @param inStrm
+ * an input stream holding at least one revoked certificate
+ * @exception CRLException
+ * on parsing errors.
+ * @exception X509ExtensionException
+ * on extension handling errors.
+ */
+ public void decode(InputStream inStrm) throws CRLException,
+ X509ExtensionException {
+ try {
+ DerValue derValue = new DerValue(inStrm);
+ parse(derValue);
+ } catch (IOException e) {
+ throw new CRLException("Parsing error: " + e.toString());
+ }
+ }
+
+ /**
+ * Encodes the revoked certificate to an output stream.
+ *
+ * @param outStrm
+ * an output stream to which the encoded revoked certificate is
+ * written.
+ * @exception CRLException
+ * on encoding errors.
+ * @exception X509ExtensionException
+ * on extension handling errors.
+ */
+ public void encode(DerOutputStream outStrm) throws CRLException,
+ X509ExtensionException {
+ try {
+ if (revokedCert == null) {
+ DerOutputStream tmp = new DerOutputStream();
+ // sequence { serialNumber, revocationDate, extensions }
+ serialNumber.encode(tmp);
+
+ // from 2050 should encode GeneralizedTime
+ tmp.putUTCTime(revocationDate);
+
+ if (extensions != null)
+ extensions.encode(tmp, isExplicit);
+
+ DerOutputStream seq = new DerOutputStream();
+ seq.write(DerValue.tag_Sequence, tmp);
+
+ revokedCert = seq.toByteArray();
+ }
+ outStrm.write(revokedCert);
+ } catch (IOException e) {
+ throw new CRLException("Encoding error: " + e.toString());
+ }
+ }
+
+ /**
+ * Gets the serial number for this RevokedCertificate, the <em>userCertificate</em>.
+ *
+ * @return the serial number.
+ */
+ public BigInteger getSerialNumber() {
+ return ((BigInt) serialNumber.getNumber()).toBigInteger();
+ }
+
+ /**
+ * Gets the revocation date for this RevokedCertificate, the <em>revocationDate</em>.
+ *
+ * @return the revocation date.
+ */
+ public Date getRevocationDate() {
+ return (new Date(revocationDate.getTime()));
+ }
+
+ /**
+ * Returns extensions for this impl.
+ *
+ * @return the CRLExtensions
+ */
+ public CRLExtensions getExtensions() {
+ return extensions;
+ }
+
+ /**
+ * Returns a printable string of this revoked certificate.
+ *
+ * @return value of this revoked certificate in a printable form.
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append(serialNumber.toString());
+ sb.append(" On: " + revocationDate.toString());
+ if (extensions != null) {
+ sb.append("\n");
+ for (int i = 0; i < extensions.size(); i++)
+ sb.append("Entry Extension[" + i + "]: "
+ + ((Extension) (extensions.elementAt(i))).toString());
+ }
+ sb.append("\n");
+ return (sb.toString());
+ }
+
+ /**
+ * Gets a Set of the extension(s) marked CRITICAL in the
+ * RevokedCertificate by OID strings.
+ *
+ * @return a set of the extension oid strings in the
+ * Object that are marked critical.
+ */
+ public Set<String> getCriticalExtensionOIDs() {
+ if (extensions == null)
+ return null;
+ Set<String> extSet = new LinkedHashSet<String>();
+ Extension ex;
+ for (Enumeration<Extension> e = extensions.getElements(); e.hasMoreElements();) {
+ ex = e.nextElement();
+ if (ex.isCritical())
+ extSet.add(ex.getExtensionId().toString());
+ }
+ return extSet;
+ }
+
+ /**
+ * Gets a Set of the extension(s) marked NON-CRITICAL in the
+ * RevokedCertificate by OID strings.
+ *
+ * @return a set of the extension oid strings in the
+ * Object that are marked critical.
+ */
+ public Set<String> getNonCriticalExtensionOIDs() {
+ if (extensions == null)
+ return null;
+ Set<String> extSet = new LinkedHashSet<String>();
+ Extension ex;
+ for (Enumeration<Extension> e = extensions.getElements(); e.hasMoreElements();) {
+ ex = e.nextElement();
+ if (!ex.isCritical())
+ extSet.add(ex.getExtensionId().toString());
+ }
+ return extSet;
+ }
+
+ /**
+ * Gets the DER encoded OCTET string for the extension value
+ * (<em>extnValue</em>) identified by the passed in oid String.
+ * The <code>oid</code> string is
+ * represented by a set of positive whole number separated
+ * by ".", that means,<br>
+ * &lt;positive whole number&gt;.&lt;positive whole number&gt;.&lt;positive
+ * whole number&gt;.&lt;...&gt;
+ *
+ * @param oid the Object Identifier value for the extension.
+ * @return the DER encoded octet string of the extension value.
+ */
+ public byte[] getExtensionValue(String oid) {
+ if (extensions == null)
+ return null;
+ try {
+ String extAlias = OIDMap.getName(new ObjectIdentifier(oid));
+ Extension crlExt = null;
+
+ if (extAlias == null) { // may be unknown
+ ObjectIdentifier findOID = new ObjectIdentifier(oid);
+ Extension ex = null;
+ ObjectIdentifier inCertOID;
+ for (Enumeration<Extension> e = extensions.getElements(); e.hasMoreElements();) {
+ ex = e.nextElement();
+ inCertOID = ex.getExtensionId();
+ if (inCertOID.equals(findOID)) {
+ crlExt = ex;
+ break;
+ }
+ }
+ } else
+ crlExt = extensions.get(extAlias);
+ if (crlExt == null)
+ return null;
+ byte[] extData = crlExt.getExtensionValue();
+ if (extData == null)
+ return null;
+
+ DerOutputStream out = new DerOutputStream();
+ out.putOctetString(extData);
+ return out.toByteArray();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ private void parse(DerValue derVal)
+ throws CRLException, X509ExtensionException {
+
+ if (derVal.tag != DerValue.tag_Sequence) {
+ throw new CRLException("Invalid encoded RevokedCertificate, " +
+ "starting sequence tag missing.");
+ }
+ if (derVal.data.available() == 0)
+ throw new CRLException("No data encoded for RevokedCertificates");
+
+ // serial number
+ try {
+ DerInputStream in = derVal.toDerInputStream();
+ DerValue val = in.getDerValue();
+ this.serialNumber = new SerialNumber(val);
+ } catch (IOException e) {
+ throw new CRLException("Parsing Serial Number error: "
+ + e.toString());
+ }
+
+ // revocationDate
+ try {
+ int nextByte = derVal.data.peekByte();
+ if ((byte) nextByte == DerValue.tag_UtcTime) {
+ this.revocationDate = derVal.data.getUTCTime();
+ } else if ((byte) nextByte == DerValue.tag_GeneralizedTime) {
+ this.revocationDate = derVal.data.getGeneralizedTime();
+ } else {
+ throw new CRLException("Invalid encoding for RevokedCertificates");
+ }
+ } catch (IOException e) {
+ throw new CRLException("Parsing Revocation Date error: "
+ + e.toString());
+ }
+
+ if (derVal.data.available() == 0)
+ return; // no extensions
+
+ // crlEntryExtensions
+ try {
+ this.extensions = new CRLExtensions(derVal.toDerInputStream());
+ } catch (IOException e) {
+ throw new CRLException("Parsing CRL Entry Extensions error: "
+ + e.toString());
+ }
+ }
+
+ /**
+ * Serialization write ... X.509 certificates serialize as themselves, and
+ * they're parsed when they get read back. (Actually they serialize as some
+ * type data from the serialization subsystem, then the cert data.)
+ */
+ private synchronized void writeObject(ObjectOutputStream stream)
+ throws CRLException, X509ExtensionException, IOException {
+ DerOutputStream dos = new DerOutputStream();
+ encode(dos);
+ dos.derEncode(stream);
+ }
+
+ /**
+ * Serialization read ... X.509 certificates serialize as themselves, and
+ * they're parsed when they get read back.
+ */
+ private synchronized void readObject(ObjectInputStream stream)
+ throws CRLException, X509ExtensionException, IOException {
+ decode(stream);
+ }
+
+}
diff --git a/base/util/src/netscape/security/x509/RevokedCertificate.java b/base/util/src/netscape/security/x509/RevokedCertificate.java
new file mode 100644
index 000000000..2087d064a
--- /dev/null
+++ b/base/util/src/netscape/security/x509/RevokedCertificate.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 netscape.security.x509;
+
+import java.math.BigInteger;
+import java.security.cert.X509CRL;
+import java.security.cert.X509CRLEntry;
+import java.util.Date;
+
+/**
+ * <p>
+ * Abstract class for a revoked certificate in a CRL (Certificate Revocation List).
+ *
+ * The ASN.1 definition for <em>revokedCertificates</em> is:
+ *
+ * <pre>
+ * revokedCertificates SEQUENCE OF SEQUENCE {
+ * userCertificate CertificateSerialNumber,
+ * revocationDate ChoiceOfTime,
+ * crlEntryExtensions Extensions OPTIONAL
+ * -- if present, must be v2
+ * } OPTIONAL
+ * <p>
+ * CertificateSerialNumber ::= INTEGER
+ * <p>
+ * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+ * <p>
+ * Extension ::= SEQUENCE {
+ * extnId OBJECT IDENTIFIER,
+ * critical BOOLEAN DEFAULT FALSE,
+ * extnValue OCTET STRING
+ * -- contains a DER encoding of a value
+ * -- of the type registered for use with
+ * -- the extnId object identifier value
+ * }
+ * </pre>
+ *
+ * @see X509CRL
+ *
+ * @author Hemma Prafullchandra
+ * @version 1.4 97/12/10
+ */
+
+public abstract class RevokedCertificate extends X509CRLEntry {
+ /* implements X509Extension { */
+
+ /**
+ * Gets the serial number for this RevokedCertificate,
+ * the <em>userCertificate</em>.
+ *
+ * @return the serial number.
+ */
+ public abstract BigInteger getSerialNumber();
+
+ /**
+ * Gets the revocation date for this RevokedCertificate,
+ * the <em>revocationDate</em>.
+ *
+ * @return the revocation date.
+ */
+ public abstract Date getRevocationDate();
+
+ /**
+ * Returns true if this revoked certificate entry has
+ * extensions.
+ *
+ * @return true if this entry has extensions, false otherwise.
+ */
+ public abstract boolean hasExtensions();
+
+ /**
+ * Returns a string representation of this revoked certificate.
+ *
+ * @return a string representation of this revoked certificate.
+ */
+ public abstract String toString();
+
+ public abstract CRLExtensions getExtensions();
+
+}
diff --git a/base/util/src/netscape/security/x509/SerialNumber.java b/base/util/src/netscape/security/x509/SerialNumber.java
new file mode 100644
index 000000000..a2d7109c0
--- /dev/null
+++ b/base/util/src/netscape/security/x509/SerialNumber.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class defines the SerialNumber class used by certificates.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.5
+ */
+public class SerialNumber {
+ private BigInt serialNum;
+
+ // Construct the class from the DerValue
+ private void construct(DerValue derVal) throws IOException {
+ serialNum = derVal.getInteger();
+ if (derVal.data.available() != 0) {
+ throw new IOException("Excess SerialNumber data");
+ }
+ }
+
+ /**
+ * The default constructor for this class using BigInteger.
+ *
+ * @param num the BigInteger number used to create the serial number.
+ */
+ public SerialNumber(BigInteger num) {
+ serialNum = new BigInt(num);
+ }
+
+ public SerialNumber(BigInt num) {
+ serialNum = num;
+ }
+
+ /**
+ * The default constructor for this class using int.
+ *
+ * @param num the BigInteger number used to create the serial number.
+ */
+ public SerialNumber(int num) {
+ serialNum = new BigInt(num);
+ }
+
+ /**
+ * Create the object, decoding the values from the passed DER stream.
+ *
+ * @param in the DerInputStream to read the SerialNumber from.
+ * @exception IOException on decoding errors.
+ */
+ public SerialNumber(DerInputStream in) throws IOException {
+ DerValue derVal = in.getDerValue();
+ construct(derVal);
+ }
+
+ /**
+ * Create the object, decoding the values from the passed DerValue.
+ *
+ * @param val the DerValue to read the SerialNumber from.
+ * @exception IOException on decoding errors.
+ */
+ public SerialNumber(DerValue val) throws IOException {
+ construct(val);
+ }
+
+ /**
+ * Create the object, decoding the values from the passed stream.
+ *
+ * @param in the InputStream to read the SerialNumber from.
+ * @exception IOException on decoding errors.
+ */
+ public SerialNumber(InputStream in) throws IOException {
+ DerValue derVal = new DerValue(in);
+ construct(derVal);
+ }
+
+ /**
+ * Return the SerialNumber as user readable string.
+ */
+ public String toString() {
+ return ("SerialNumber: [" + serialNum.toString() + "]");
+ }
+
+ /**
+ * Encode the SerialNumber in DER form to the stream.
+ *
+ * @param out the DerOutputStream to marshal the contents to.
+ * @exception IOException on errors.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ out.putInteger(serialNum);
+ }
+
+ /**
+ * Return the serial number.
+ */
+ public BigInt getNumber() {
+ return (serialNum);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/SubjectAlternativeNameExtension.java b/base/util/src/netscape/security/x509/SubjectAlternativeNameExtension.java
new file mode 100644
index 000000000..c30ae1576
--- /dev/null
+++ b/base/util/src/netscape/security/x509/SubjectAlternativeNameExtension.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This represents the Subject Alternative Name Extension.
+ *
+ * This extension, if present, allows the subject to specify multiple
+ * alternative names.
+ *
+ * <p>
+ * Extensions are represented as a sequence of the extension identifier (Object Identifier), a boolean flag stating
+ * whether the extension is to be treated as being critical and the extension value itself (this is again a DER encoding
+ * of the extension value).
+ * <p>
+ * The ASN.1 syntax for this is:
+ *
+ * <pre>
+ * SubjectAltName ::= GeneralNames
+ * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+ * </pre>
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.9
+ * @see Extension
+ * @see CertAttrSet
+ */
+public class SubjectAlternativeNameExtension extends Extension
+ implements CertAttrSet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4022446008355607196L;
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT =
+ "x509.info.extensions.SubjectAlternativeName";
+ /**
+ * Attribute names.
+ */
+ public static final String NAME = "SubjectAlternativeName";
+ public static final String SUBJECT_NAME = "subject_name";
+
+ // private data members
+ GeneralNames names;
+
+ // Encode this extension
+ private void encodeThis() throws IOException {
+ DerOutputStream os = new DerOutputStream();
+ try {
+ names.encode(os);
+ } catch (GeneralNamesException e) {
+ throw new IOException("SubjectAlternativeName: " + e);
+ }
+ extensionValue = os.toByteArray();
+ }
+
+ /**
+ * Create a SubjectAlternativeNameExtension with the passed GeneralNames.
+ *
+ * @param names the GeneralNames for the subject.
+ * @exception IOException on error.
+ */
+ public SubjectAlternativeNameExtension(boolean critical, GeneralNames names)
+ throws IOException {
+ this.names = names;
+ this.extensionId = PKIXExtensions.SubjectAlternativeName_Id;
+ this.critical = critical;
+ encodeThis();
+ }
+
+ public SubjectAlternativeNameExtension(GeneralNames names)
+ throws IOException {
+ this.names = names;
+ this.extensionId = PKIXExtensions.SubjectAlternativeName_Id;
+ this.critical = false;
+ encodeThis();
+ }
+
+ /**
+ * Create a default SubjectAlternativeNameExtension.
+ */
+ public SubjectAlternativeNameExtension() {
+ extensionId = PKIXExtensions.SubjectAlternativeName_Id;
+ critical = false;
+ names = new GeneralNames();
+ }
+
+ /**
+ * Create the extension from the passed DER encoded value.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param value Array of DER encoded bytes of the actual value.
+ * @exception IOException on error.
+ */
+ public SubjectAlternativeNameExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = PKIXExtensions.SubjectAlternativeName_Id;
+ this.critical = critical.booleanValue();
+
+ if (!(value instanceof byte[]))
+ throw new IOException("SubjectAlternativeName: "
+ + "Illegal argument type");
+
+ int len = Array.getLength(value);
+ byte[] extValue = new byte[len];
+ System.arraycopy(value, 0, extValue, 0, len);
+
+ this.extensionValue = extValue;
+ DerValue val = new DerValue(extValue);
+ try {
+ names = new GeneralNames(val);
+ } catch (GeneralNamesException e) {
+ throw new IOException("SubjectAlternativeName: " + e);
+ }
+ }
+
+ /**
+ * Returns a printable representation of the SubjectAlternativeName.
+ */
+ public String toString() {
+ if (names == null)
+ return "";
+ String s = super.toString() + "SubjectAlternativeName [\n"
+ + names.toString() + "]\n";
+ return (s);
+ }
+
+ /**
+ * Decode the extension from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ /**
+ * Write the extension to the OutputStream.
+ *
+ * @param out the OutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ if (extensionValue == null) {
+ extensionId = PKIXExtensions.SubjectAlternativeName_Id;
+ //critical = false;
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ clearValue();
+ if (name.equalsIgnoreCase(SUBJECT_NAME)) {
+ if (!(obj instanceof GeneralNames)) {
+ throw new IOException("Attribute value should be of " +
+ "type GeneralNames.");
+ }
+ names = (GeneralNames) obj;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:SubjectAlternativeName.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(SUBJECT_NAME)) {
+ return (names);
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:SubjectAlternativeName.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(SUBJECT_NAME)) {
+ names = null;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:SubjectAlternativeName.");
+ }
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(SUBJECT_NAME);
+
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/SubjectDirAttributesExtension.java b/base/util/src/netscape/security/x509/SubjectDirAttributesExtension.java
new file mode 100644
index 000000000..b249ef600
--- /dev/null
+++ b/base/util/src/netscape/security/x509/SubjectDirAttributesExtension.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class represents the Subject Directory Attributes Extension.
+ *
+ * <p>
+ * The subject directory attributes extension is not recommended as an essential part of this profile, but it may be
+ * used in local environments. This extension MUST be non-critical.
+ *
+ * <pre>
+ * The ASN.1 syntax for this extension is:
+ *
+ * SubjectDirectoryAttributes ::= SEQUENCE (1..MAX) OF Attribute
+ *
+ * Attribute ::= SEQUENCE {
+ * type AttributeType,
+ * value SET OF AttributeValue
+ * -- at least one value is required --}
+ *
+ * AttributeType ::= OBJECT IDENTIFIER
+ *
+ * AttributeValue ::= ANY
+ *
+ * </pre>
+ *
+ * @author Christine Ho
+ * @version 1.7
+ *
+ * @see CertAttrSet
+ * @see Extension
+ */
+public class SubjectDirAttributesExtension extends Extension
+ implements CertAttrSet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1215458115428197688L;
+
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ //public static final String IDENT = "x509.info.extensions.SubjectDirectoryAttributes";
+ public static final String IDENT = "Subject Directory Attributes";
+
+ /**
+ * Attribute names.
+ */
+ public static final String NAME = "SubjectDirectoryAttributes";
+
+ // Private data members
+ private Vector<Attribute> attrList = new Vector<Attribute>();
+
+ // Encode this extension value
+ private void encodeThis() throws IOException {
+ DerOutputStream out = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+
+ //encoding the attributes
+ Enumeration<Attribute> attrs = attrList.elements();
+ while (attrs.hasMoreElements()) {
+ Attribute attr = attrs.nextElement();
+ attr.encode(tmp);
+ }
+
+ out.write(DerValue.tag_SequenceOf, tmp);
+ this.extensionValue = out.toByteArray();
+ }
+
+ // Decode this extension value
+ private void decodeThis(DerValue derVal) throws IOException {
+
+ if (derVal.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding for " +
+ "Subject Directory Attribute extension.");
+ }
+
+ if (derVal.data.available() == 0) {
+ throw new IOException(NAME + " No data available in "
+ + "passed DER encoded value.");
+ }
+
+ // Decode all the Attributes
+ while (derVal.data.available() != 0) {
+ DerValue encAttr = derVal.data.getDerValue();
+ Attribute attr = new Attribute(encAttr);
+ attrList.addElement(attr);
+ }
+ }
+
+ /**
+ * Default constructor for this object.
+ *
+ * @param derVal Der encoded value of this extension
+ */
+ public SubjectDirAttributesExtension(DerValue derVal) throws IOException {
+
+ this.extensionId = PKIXExtensions.SubjectDirectoryAttributes_Id;
+ this.critical = false;
+ decodeThis(derVal);
+ }
+
+ /**
+ * Default constructor for this object.
+ *
+ * @param list Attribute object list
+ */
+ public SubjectDirAttributesExtension(Attribute[] list) throws IOException {
+
+ this.extensionId = PKIXExtensions.SubjectDirectoryAttributes_Id;
+ this.critical = false;
+
+ if ((list == null) || (list.length == 0)) {
+ throw new IOException("No data available in "
+ + "passed Attribute List.");
+ }
+
+ // add the Attributes
+ for (int i = 0; i < list.length; i++) {
+ attrList.addElement(list[i]);
+ }
+ }
+
+ /**
+ * Constructor from parsing extension
+ *
+ * @param list Attribute object list
+ */
+ public SubjectDirAttributesExtension(Boolean crit, Object value)
+ throws IOException {
+
+ this.extensionId = PKIXExtensions.SubjectDirectoryAttributes_Id;
+ this.critical = crit.booleanValue();
+
+ if (!(value instanceof byte[]))
+ throw new IOException(NAME + "Illegal argument type");
+ int len = Array.getLength(value);
+ byte[] extValue = new byte[len];
+ System.arraycopy(value, 0, extValue, 0, len);
+
+ this.extensionValue = extValue;
+ decodeThis(new DerValue(extValue));
+ }
+
+ /**
+ * Constructor for this object.
+ *
+ * @param list Attribute object list
+ * @param critical The criticality
+ */
+ public SubjectDirAttributesExtension(Attribute[] list, boolean critical)
+ throws IOException {
+
+ this.extensionId = PKIXExtensions.SubjectDirectoryAttributes_Id;
+ this.critical = critical;
+
+ if ((list == null) || (list.length == 0)) {
+ throw new IOException("No data available in "
+ + "passed Attribute List.");
+ }
+
+ // add the Attributes
+ for (int i = 0; i < list.length; i++) {
+ attrList.addElement(list[i]);
+ }
+ }
+
+ /**
+ * Return user readable form of extension.
+ */
+ public String toString() {
+ String s = super.toString() + "SubjectDirectoryAttributes:[\n";
+
+ Enumeration<Attribute> attrs = attrList.elements();
+ while (attrs.hasMoreElements()) {
+ Attribute attr = attrs.nextElement();
+ s += attr.toString();
+ }
+
+ return (s + "]\n");
+ }
+
+ /**
+ * Decode the extension from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ DerValue val = new DerValue(in);
+ decodeThis(val);
+ }
+
+ /**
+ * Encode this extension value to the output stream.
+ *
+ * @param out the DerOutputStream to encode the extension to.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ if (extensionValue == null) {
+ this.extensionId = PKIXExtensions.SubjectDirectoryAttributes_Id;
+ this.critical = false;
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:SubjectDirectoryAttributes.");
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:SubjectDirectoryAttributes.");
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:SubjectDirectoryAttributes.");
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+
+ /**
+ * Returns an enumeration of attributes in the extension.
+ */
+ public Enumeration<Attribute> getAttributesList() {
+ if (attrList == null)
+ return null;
+ return attrList.elements();
+ }
+}
diff --git a/base/util/src/netscape/security/x509/SubjectKeyIdentifierExtension.java b/base/util/src/netscape/security/x509/SubjectKeyIdentifierExtension.java
new file mode 100644
index 000000000..ea0ebae82
--- /dev/null
+++ b/base/util/src/netscape/security/x509/SubjectKeyIdentifierExtension.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 netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * Represent the Subject Key Identifier Extension.
+ *
+ * This extension, if present, provides a means of identifying the particular
+ * public key used in an application. This extension by default is marked
+ * non-critical.
+ *
+ * <p>
+ * Extensions are addiitonal attributes which can be inserted in a X509 v3 certificate. For example a
+ * "Driving License Certificate" could have the driving license number as a extension.
+ *
+ * <p>
+ * Extensions are represented as a sequence of the extension identifier (Object Identifier), a boolean flag stating
+ * whether the extension is to be treated as being critical and the extension value itself (this is again a DER encoding
+ * of the extension value).
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.7
+ * @see Extension
+ * @see CertAttrSet
+ */
+public class SubjectKeyIdentifierExtension extends Extension
+ implements CertAttrSet {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2457721262590880939L;
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT =
+ "x509.info.extensions.SubjectKeyIdentifier";
+ /**
+ * Attribute names.
+ */
+ public static final String NAME = "SubjectKeyIdentifier";
+ public static final String KEY_ID = "key_id";
+
+ // Private data member
+ private KeyIdentifier id;
+
+ // Encode this extension value
+ private void encodeThis() throws IOException {
+ DerOutputStream os = new DerOutputStream();
+ id.encode(os);
+ extensionValue = os.toByteArray();
+ }
+
+ /**
+ * Create a SubjectKeyIdentifierExtension with the passed octet string.
+ * The criticality is set to False.
+ *
+ * @param octetString the octet string identifying the key identifier.
+ */
+ public SubjectKeyIdentifierExtension(boolean critical, byte[] octetString)
+ throws IOException {
+ id = new KeyIdentifier(octetString);
+
+ this.extensionId = PKIXExtensions.SubjectKey_Id;
+ this.critical = critical;
+ encodeThis();
+ }
+
+ public SubjectKeyIdentifierExtension(byte[] octetString)
+ throws IOException {
+ id = new KeyIdentifier(octetString);
+
+ this.extensionId = PKIXExtensions.SubjectKey_Id;
+ this.critical = false;
+ encodeThis();
+ }
+
+ /**
+ * Create the extension from the passed DER encoded value.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param value Array of DER encoded bytes of the actual value.
+ * @exception IOException on error.
+ */
+ public SubjectKeyIdentifierExtension(Boolean critical, Object value)
+ throws IOException {
+ this.extensionId = PKIXExtensions.SubjectKey_Id;
+ this.critical = critical.booleanValue();
+
+ int len = Array.getLength(value);
+ byte[] extValue = new byte[len];
+ for (int i = 0; i < len; i++) {
+ extValue[i] = Array.getByte(value, i);
+ }
+ this.extensionValue = extValue;
+ DerValue val = new DerValue(extValue);
+ this.id = new KeyIdentifier(val);
+ }
+
+ /**
+ * Returns a printable representation.
+ */
+ public String toString() {
+ if (id == null)
+ return "";
+ String s = super.toString() + "SubjectKeyIdentifier [\n"
+ + id.toString() + "]\n";
+ return (s);
+ }
+
+ /**
+ * Write the extension to the OutputStream.
+ *
+ * @param out the OutputStream to write the extension to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(OutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ if (extensionValue == null) {
+ extensionId = PKIXExtensions.SubjectKey_Id;
+ critical = false;
+ encodeThis();
+ }
+ super.encode(tmp);
+ out.write(tmp.toByteArray());
+ }
+
+ /**
+ * Decode the extension from the InputStream.
+ *
+ * @param in the InputStream to unmarshal the contents from.
+ * @exception IOException on decoding or validity errors.
+ */
+ public void decode(InputStream in) throws IOException {
+ throw new IOException("Method not to be called directly.");
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ clearValue();
+ if (name.equalsIgnoreCase(KEY_ID)) {
+ if (!(obj instanceof KeyIdentifier)) {
+ throw new IOException("Attribute value should be of" +
+ " type KeyIdentifier.");
+ }
+ id = (KeyIdentifier) obj;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:SubjectKeyIdentifierExtension.");
+ }
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ if (name.equalsIgnoreCase(KEY_ID)) {
+ return (id);
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:SubjectKeyIdentifierExtension.");
+ }
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ if (name.equalsIgnoreCase(KEY_ID)) {
+ id = null;
+ } else {
+ throw new IOException("Attribute name not recognized by " +
+ "CertAttrSet:SubjectKeyIdentifierExtension.");
+ }
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(KEY_ID);
+
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/URIName.java b/base/util/src/netscape/security/x509/URIName.java
new file mode 100644
index 000000000..cc321a3b3
--- /dev/null
+++ b/base/util/src/netscape/security/x509/URIName.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 netscape.security.x509;
+
+import java.io.IOException;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class implements the URIName as required by the GeneralNames
+ * ASN.1 object.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.3
+ * @see GeneralName
+ * @see GeneralNames
+ * @see GeneralNameInterface
+ */
+public class URIName implements GeneralNameInterface {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8340049830612859508L;
+ private String name;
+
+ /**
+ * Create the URIName object from the passed encoded Der value.
+ *
+ * @param derValue the encoded DER URIName.
+ * @exception IOException on error.
+ */
+ public URIName(DerValue derValue) throws IOException {
+ name = derValue.getIA5String();
+ }
+
+ /**
+ * Create the URIName object with the specified name.
+ *
+ * @param name the URIName.
+ */
+ public URIName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Return the type of the GeneralName.
+ */
+ public int getType() {
+ return (GeneralNameInterface.NAME_URI);
+ }
+
+ /**
+ * Encode the URI name into the DerOutputStream.
+ *
+ * @param out the DER stream to encode the URIName to.
+ * @exception IOException on encoding errors.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ out.putIA5String(name);
+ }
+
+ /**
+ * Convert the name into user readable string.
+ */
+ public String toString() {
+ return ("URIName: " + name);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/UniqueIdentity.java b/base/util/src/netscape/security/x509/UniqueIdentity.java
new file mode 100644
index 000000000..5113efeaf
--- /dev/null
+++ b/base/util/src/netscape/security/x509/UniqueIdentity.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 netscape.security.x509;
+
+import java.io.IOException;
+
+import netscape.security.util.BitArray;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * This class defines the UniqueIdentity class used by certificates.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.6
+ */
+public class UniqueIdentity {
+ // Private data members
+ private BitArray id;
+
+ /**
+ * The default constructor for this class.
+ *
+ * @param id the byte array containing the unique identifier.
+ */
+ public UniqueIdentity(BitArray id) {
+ this.id = id;
+ }
+
+ /**
+ * The default constructor for this class.
+ *
+ * @param id the byte array containing the unique identifier.
+ */
+ public UniqueIdentity(byte[] id) {
+ this.id = new BitArray(id.length * 8, id);
+ }
+
+ /**
+ * Create the object, decoding the values from the passed DER stream.
+ *
+ * @param in the DerInputStream to read the UniqueIdentity from.
+ * @exception IOException on decoding errors.
+ */
+ public UniqueIdentity(DerInputStream in) throws IOException {
+ DerValue derVal = in.getDerValue();
+ id = derVal.getUnalignedBitString(true);
+ }
+
+ /**
+ * Create the object, decoding the values from the passed DER stream.
+ *
+ * @param derVal the DerValue decoded from the stream.
+ * @param tag the tag the value is encoded under.
+ * @exception IOException on decoding errors.
+ */
+ public UniqueIdentity(DerValue derVal) throws IOException {
+ id = derVal.getUnalignedBitString(true);
+ }
+
+ /**
+ * Return the UniqueIdentity as a printable string.
+ */
+ public String toString() {
+ return ("UniqueIdentity:" + id.toString() + "\n");
+ }
+
+ /**
+ * Encode the UniqueIdentity in DER form to the stream.
+ *
+ * @param out the DerOutputStream to marshal the contents to.
+ * @param tag enocode it under the following tag.
+ * @exception IOException on errors.
+ */
+ public void encode(DerOutputStream out, byte tag) throws IOException {
+ byte[] bytes = id.toByteArray();
+ int excessBits = bytes.length * 8 - id.length();
+
+ out.write(tag);
+ out.putLength(bytes.length + 1);
+
+ out.write(excessBits);
+ out.write(bytes);
+ }
+
+ /**
+ * Return the unique id.
+ */
+ public boolean[] getId() {
+ if (id == null)
+ return null;
+
+ return id.toBooleanArray();
+ }
+}
diff --git a/base/util/src/netscape/security/x509/UserNotice.java b/base/util/src/netscape/security/x509/UserNotice.java
new file mode 100644
index 000000000..dc2e1d535
--- /dev/null
+++ b/base/util/src/netscape/security/x509/UserNotice.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 netscape.security.x509;
+
+import java.io.IOException;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * Represent the UserNotice Qualifier.
+ *
+ * UserNotice ::= SEQUENCE {
+ * noticeRef NoticeReference OPTIONAL,
+ * explicitText DisplayText OPTIONAL
+ * }
+ *
+ * @author Thomas Kwan
+ */
+public class UserNotice extends Qualifier {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5770869942793748051L;
+ private NoticeReference mNoticeReference = null;
+ private DisplayText mDisplayText = null;
+
+ public UserNotice(NoticeReference ref, DisplayText text) {
+ mNoticeReference = ref;
+ mDisplayText = text;
+ }
+
+ public UserNotice(DerValue val) throws IOException {
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding for UserNotice");
+ }
+ // case 0: no element
+ if (val.data.available() == 0)
+ return;
+ // case 1: 1 element
+ DerValue inSeq = val.data.getDerValue();
+ if (inSeq.tag == DerValue.tag_Sequence) {
+ mNoticeReference = new NoticeReference(inSeq);
+ } else {
+ mDisplayText = new DisplayText(inSeq);
+ }
+ if (val.data.available() == 0)
+ return;
+ // case 2: 2 elements
+ mDisplayText = new DisplayText(val.data.getDerValue());
+ }
+
+ public NoticeReference getNoticeReference() {
+ return mNoticeReference;
+ }
+
+ public DisplayText getDisplayText() {
+ return mDisplayText;
+ }
+
+ /**
+ * Write the UserNotice to the DerOutputStream.
+ *
+ * @param out the DerOutputStream to write the object to.
+ * @exception IOException on errors.
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ // OPTIONAL
+ if (mNoticeReference != null) {
+ mNoticeReference.encode(tmp);
+ }
+ // OPTIONAL
+ if (mDisplayText != null) {
+ mDisplayText.encode(tmp);
+ }
+ out.write(DerValue.tag_Sequence, tmp);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/X500Name.java b/base/util/src/netscape/security/x509/X500Name.java
new file mode 100644
index 000000000..d44003baa
--- /dev/null
+++ b/base/util/src/netscape/security/x509/X500Name.java
@@ -0,0 +1,699 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * X.500 names are used to identify entities, such as those which are
+ * identified by X.509 certificates. They are world-wide, hierarchical,
+ * and descriptive. Entities can be identified by attributes, and in
+ * some systems can be searched for according to those attributes.
+ *
+ * <P>
+ * <em>This class exposes only partial X.500 name functionality. Most
+ * notably, it works best if Relative Distinguished Names only have one
+ * (unique) attribute each, and if only the most common attributes need
+ * to be visible to applications. This limitation, and others, will
+ * be lifted over time.</em>
+ *
+ * @author David Brownell
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.35
+ * @see GeneralName
+ * @see GeneralNames
+ * @see GeneralNameInterface
+ * @see RDN
+ * @see AVA
+ * @see LdapDNStrConverter
+ */
+
+public class X500Name implements Principal, GeneralNameInterface {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -730790062013191108L;
+
+ /**
+ * Constructs a name from a Ldap DN string, such
+ * as &lb;CN=Dave, OU=JavaSoft, O=Sun Microsystems, C=US&rb;. The
+ * older "/C=US/O=Sun Microsystems, Inc/OU=JavaSoft/CN=Dave" syntax
+ * is not currently supported. (The former is RFC 1779 style.)
+ *
+ * @param ldapDNString a Ldap DN String e.g. as defined in RFC1779
+ */
+ public X500Name(String ldapDNString)
+ throws IOException {
+ X500Name x500name;
+
+ if (ldapDNString == null || ldapDNString.equals("")) {
+ clear();
+ return;
+ }
+ x500name = LdapDNStrConverter.getDefault().parseDN(ldapDNString);
+ names = x500name.getNames();
+ }
+
+ /**
+ * Constructs a X500Name from a Ldap DN String using the specified
+ * LdapDNStrConverter. Also use the input tags.
+ *
+ * @see LdapDNStrConverter
+ *
+ * @param ldapDNString a Ldap DN String e.g. as defined in RFC1779.
+ * @param ldapDNStrConverter A LdapDNStrConverter
+ */
+ public X500Name(String ldapDNString, LdapDNStrConverter ldapDNStrConverter, byte[] tags)
+ throws IOException {
+
+ if (ldapDNString == null || ldapDNString.equals("")) {
+ clear();
+ return;
+ }
+ X500Name x500name;
+ x500name = ldapDNStrConverter.parseDN(ldapDNString, tags);
+ names = x500name.getNames();
+
+ }
+
+ public X500Name(String ldapDNString, byte[] tags)
+ throws IOException {
+ if (ldapDNString == null || ldapDNString.equals("")) {
+ clear();
+ return;
+ }
+ X500Name x500name;
+ x500name = LdapDNStrConverter.getDefault().parseDN(ldapDNString, tags);
+ names = x500name.getNames();
+ }
+
+ /**
+ * Constructs a X500Name from a Ldap DN String using the specified
+ * LdapDNStrConverter.
+ *
+ * @see LdapDNStrConverter
+ *
+ * @param ldapDNString a Ldap DN String e.g. as defined in RFC1779.
+ * @param ldapDNStrConverter A LdapDNStrConverter
+ */
+ public X500Name(String ldapDNString,
+ LdapDNStrConverter ldapDNStrConverter)
+ throws IOException {
+ if (ldapDNString == null || ldapDNString.equals("")) {
+ clear();
+ return;
+ }
+ X500Name x500name;
+ x500name = ldapDNStrConverter.parseDN(ldapDNString);
+ names = x500name.getNames();
+ }
+
+ /**
+ * Constructs a X500Name from fields common in enterprise application
+ * environments.
+ *
+ * @param commonName common name of a person, e.g. "Vivette Davis"
+ * @param organizationUnit small organization name, e.g. "Purchasing"
+ * @param organizationName large organization name, e.g. "Onizuka, Inc."
+ * @param country two letter country code, e.g. "CH"
+ */
+ public X500Name(
+ String commonName,
+ String organizationUnit,
+ String organizationName,
+ String country) throws IOException {
+ DirStrConverter dirStrConverter = new DirStrConverter();
+ PrintableConverter printableConverter = new PrintableConverter();
+ AVA[] assertion = new AVA[1]; // array is cloned in constructors.
+ int i = 4;
+
+ names = new RDN[i];
+ /*
+ * NOTE: it's only on output that little-endian
+ * ordering is used.
+ */
+ assertion[0] = new AVA(commonName_oid,
+ dirStrConverter.getValue(commonName));
+ names[--i] = new RDN(assertion);
+
+ assertion[0] = new AVA(orgUnitName_oid,
+ dirStrConverter.getValue(organizationUnit));
+ names[--i] = new RDN(assertion);
+
+ assertion[0] = new AVA(orgName_oid,
+ dirStrConverter.getValue(organizationName));
+ names[--i] = new RDN(assertion);
+
+ assertion[0] = new AVA(countryName_oid,
+ printableConverter.getValue(country));
+ names[--i] = new RDN(assertion);
+ }
+
+ /**
+ * Constructs a X500Name from fields common in Internet application
+ * environments.
+ *
+ * @param commonName common name of a person, e.g. "Vivette Davis"
+ * @param organizationUnit small organization name, e.g. "Purchasing"
+ * @param organizationName large organization name, e.g. "Onizuka, Inc."
+ * @param localityName locality (city) name, e.g. "Palo Alto"
+ * @param stateName state name, e.g. "California"
+ * @param country two letter country code, e.g. "CH"
+ */
+ public X500Name(
+ String commonName,
+ String organizationUnit,
+ String organizationName,
+ String localityName,
+ String stateName,
+ String country) throws IOException {
+ DirStrConverter dirStrConverter = new DirStrConverter();
+ PrintableConverter printableConverter = new PrintableConverter();
+ AVA[] assertion = new AVA[1]; // array is cloned in constructors.
+ int i = 6;
+
+ names = new RDN[i];
+ /*
+ * NOTE: it's only on output that little-endian
+ * ordering is used.
+ */
+ assertion[0] = new AVA(commonName_oid,
+ dirStrConverter.getValue(commonName));
+ names[--i] = new RDN(assertion);
+
+ assertion[0] = new AVA(orgUnitName_oid,
+ dirStrConverter.getValue(organizationUnit));
+ names[--i] = new RDN(assertion);
+
+ assertion[0] = new AVA(orgName_oid,
+ dirStrConverter.getValue(organizationName));
+ names[--i] = new RDN(assertion);
+
+ assertion[0] = new AVA(localityName_oid,
+ dirStrConverter.getValue(localityName));
+ names[--i] = new RDN(assertion);
+
+ assertion[0] = new AVA(stateName_oid,
+ dirStrConverter.getValue(stateName));
+ names[--i] = new RDN(assertion);
+
+ assertion[0] = new AVA(countryName_oid,
+ printableConverter.getValue(country));
+ names[--i] = new RDN(assertion);
+ }
+
+ /**
+ * Constructs a name from an ASN.1 encoded value. The encoding
+ * of the name in the stream uses DER (a BER/1 subset).
+ *
+ * @param value a DER-encoded value holding an X.500 name.
+ */
+ public X500Name(DerValue value) throws IOException {
+
+ this(value.toDerInputStream());
+ }
+
+ /**
+ * Constructs a name from an ASN.1 encoded input stream. The encoding
+ * of the name in the stream uses DER (a BER/1 subset).
+ *
+ * @param in DER-encoded data holding an X.500 name.
+ */
+ public X500Name(DerInputStream in)
+ throws IOException {
+ parseDER(in);
+ }
+
+ /**
+ * Constructs a name from an ASN.1 encoded byte array.
+ *
+ * @param name DER-encoded byte array holding an X.500 name.
+ */
+ public X500Name(byte[] name)
+ throws IOException {
+ DerInputStream in = new DerInputStream(name);
+ parseDER(in);
+
+ }
+
+ /**
+ * Constructs a X500Name from array of RDN. The RDNs are expected to
+ * be in big endian order i.e. most significant first.
+ *
+ * @param rdns an array of RDN.
+ */
+ public X500Name(RDN[] rdns)
+ throws IOException {
+ names = (RDN[]) rdns.clone();
+ }
+
+ /**
+ * convenience method.
+ *
+ * @param rdns a vector of rdns.
+ */
+ public X500Name(Vector<RDN> rdnVector)
+ throws IOException {
+ int size = rdnVector.size();
+ names = new RDN[size];
+ for (int i = 0; i < size; i++) {
+ names[i] = (RDN) rdnVector.elementAt(i);
+ }
+ }
+
+ /**
+ * Compares this name with another, for equality.
+ *
+ * @return true iff the names are identical.
+ */
+ synchronized public boolean equals(X500Name other) {
+ int i;
+
+ if (this == other)
+ return true;
+
+ if (names.length != other.names.length)
+ return false;
+ for (i = 0; i < names.length; i++) {
+ if (!names[i].equals(other.names[i]))
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Sets private data to a null state
+ */
+
+ private void clear() {
+ dn = "";
+ names = null;
+
+ }
+
+ /**
+ * Returns the name component as a Java string, regardless of its
+ * encoding restrictions.
+ */
+ private String getString(DerValue attribute) throws IOException {
+ String value = attribute.getAsString();
+
+ if (value == null)
+ throw new IOException("not a DER string encoding, "
+ + attribute.tag);
+ else
+ return value;
+ }
+
+ /**
+ * Return type of GeneralName.
+ */
+ public int getType() {
+ return (GeneralNameInterface.NAME_DIRECTORY);
+ }
+
+ /**
+ * Returns a "Country" name component. If more than one
+ * such attribute exists, the topmost one is returned.
+ *
+ * @return "C=" component of the name, if any.
+ */
+ public String getCountry() throws IOException {
+ DerValue attr = findAttribute(countryName_oid);
+
+ return getString(attr);
+ }
+
+ /**
+ * Returns an "Organization" name component. If more than
+ * one such attribute exists, the topmost one is returned.
+ *
+ * @return "O=" component of the name, if any.
+ */
+ public String getOrganization() throws IOException {
+ DerValue attr = findAttribute(orgName_oid);
+
+ return getString(attr);
+ }
+
+ /**
+ * Returns an "Organizational Unit" name component. If more
+ * than one such attribute exists, the topmost one is returned.
+ *
+ * @return "OU=" component of the name, if any.
+ */
+ public String getOrganizationalUnit() throws IOException {
+ DerValue attr = findAttribute(orgUnitName_oid);
+
+ return getString(attr);
+ }
+
+ /**
+ * Returns a "Common Name" component. If more than one such
+ * attribute exists, the topmost one is returned.
+ *
+ * @return "CN=" component of the name, if any.
+ */
+ public String getCommonName() throws IOException {
+ DerValue attr = findAttribute(commonName_oid);
+
+ return getString(attr);
+ }
+
+ /**
+ * Returns a "UID" component. If more than one such
+ * attribute exists, the topmost one is returned.
+ *
+ * @return "UID=" component of the name, if any.
+ */
+ public String getUserID() throws IOException {
+ DerValue attr = findAttribute(uidName_oid);
+
+ return getString(attr);
+ }
+
+ /**
+ * Returns a "Locality" name component. If more than one
+ * such component exists, the topmost one is returned.
+ *
+ * @return "L=" component of the name, if any.
+ */
+ public String getLocality() throws IOException {
+ DerValue attr = findAttribute(localityName_oid);
+
+ return getString(attr);
+ }
+
+ /**
+ * Returns a "State" name component. If more than one
+ * such component exists, the topmost one is returned.
+ *
+ * @return "S=" component of the name, if any.
+ */
+ public String getState() throws IOException {
+ DerValue attr = findAttribute(stateName_oid);
+
+ return getString(attr);
+ }
+
+ /**
+ * Returns a "Email" name component. If more than one
+ * such component exists, the topmost one is returned.
+ *
+ * @return "E=" component of the name, if any.
+ */
+ public String getEmail() throws IOException {
+ DerValue attr = findAttribute(email_oid);
+ if (attr == null)
+ return null;
+ return getString(attr);
+ }
+
+ /**
+ * Returns a Ldap DN String from the X500Name using the global default
+ * LdapDNStrConverter
+ *
+ * @see LdapDNStrConverter
+ * @return Ldap DN string of this X500Name using the default converter.
+ */
+ public String toLdapDNString()
+ throws IOException {
+ if (dn == null)
+ generateDN(LdapDNStrConverter.getDefault());
+ return dn;
+ }
+
+ /**
+ * Returns a Ldap DN String from the X500Name
+ * using the specified LdapDNStrconverter.
+ * For example, RFC1779String converter can be passed to convert the
+ * DN to RFC1779 string syntax.
+ *
+ * @see LdapDNStrConverter
+ * @param ldapDNStrConverter a LdapDNStrConverter
+ * @return Ldap DN string of the X500Name
+ */
+ public String toLdapDNString(LdapDNStrConverter ldapDNStrConverter)
+ throws IOException {
+
+ if (dn == null)
+ generateDN(ldapDNStrConverter);
+ return dn;
+ }
+
+ /**
+ * Returns a Ldap DN string, using the global default LdapDNStrConverter
+ * or null if an error occurs in the conversion.
+ */
+ public String toString() {
+ String s;
+ if (names == null) {
+ s = "";
+ return s;
+ }
+ try {
+ s = toLdapDNString();
+ } catch (IOException e) {
+ return null;
+ }
+ return s;
+ }
+
+ /**
+ * Returns the value of toString(). This call is needed to
+ * implement the java.security.Principal interface.
+ */
+ public String getName() {
+ return toString();
+ }
+
+ private String dn; // RFC 1779 style DN, or null
+ private RDN names[]; // RDNs
+
+ /**
+ * Find the first instance of this attribute in a "top down"
+ * search of all the attributes in the name.
+ */
+ private DerValue findAttribute(ObjectIdentifier attribute) {
+ int i;
+ DerValue retval = null;
+
+ for (i = 0; i < names.length; i++) {
+ retval = names[i].findAttribute(attribute);
+ if (retval != null)
+ break;
+ }
+ return retval;
+ }
+
+ /**
+ * Returns an enumerator of RDNs in the X500Name.
+ *
+ * @return enumeration of rdns in this X500Name.
+ */
+ public Enumeration<RDN> getRDNs() {
+ return new RDNEnumerator();
+ }
+
+ /**
+ * Returns an array of RDN in the X500Name.
+ *
+ * @return array of RDN in this X500name.
+ */
+ public RDN[] getNames() {
+ return (RDN[]) names.clone();
+ }
+
+ /**
+ * Returns the number of RDNs in the X500Name.
+ *
+ * @return number of RDNs in this X500Name.
+ */
+ public int getNamesLength() {
+ return names.length;
+ }
+
+ /****************************************************************/
+
+ private void parseDER(DerInputStream in) throws IOException {
+ //
+ // X.500 names are a "SEQUENCE OF" RDNs, which means one or
+ // more and order matters. We scan them in order, which
+ // conventionally is big-endian.
+ //
+ DerValue nameseq[] = in.getSequence(5);
+ int i;
+
+ if (nameseq.length != 0) {
+ names = new RDN[nameseq.length];
+ } else {
+ clear();
+ }
+
+ for (i = 0; i < nameseq.length; i++)
+ names[i] = new RDN(nameseq[i]);
+ }
+
+ /**
+ * Encodes the name in DER-encoded form.
+ *
+ * @param out where to put the DER-encoded X.500 name
+ */
+ public void encode(DerOutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ int i;
+
+ int len = 0;
+ if (names == null) {
+ len = 0;
+ } else {
+ len = names.length;
+
+ }
+
+ for (i = 0; i < len; i++)
+ names[i].encode(tmp);
+
+ out.write(DerValue.tag_Sequence, tmp);
+ }
+
+ /**
+ * Gets the name in DER-encoded form.
+ *
+ * @return the DER encoded byte array of this name,
+ * null if no names are present.
+ */
+ public byte[] getEncoded() throws IOException {
+
+ DerOutputStream out = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+
+ int len = 0;
+
+ if (names == null) {
+ len = 0;
+ } else {
+ len = names.length;
+ }
+
+ for (int i = 0; i < len; i++)
+ names[i].encode(tmp);
+
+ out.write(DerValue.tag_Sequence, tmp);
+ return out.toByteArray();
+ }
+
+ /*
+ * Dump the printable form of a distinguished name. Each relative
+ * name is separated from the next by a ",", and assertions in the
+ * relative names have "label=value" syntax.
+ *
+ * Uses RFC 1779 syntax (i.e. little-endian, comma separators)
+ *
+ */
+ private void generateDN(LdapDNStrConverter ldapDNStrConverter)
+ throws IOException {
+ if (names == null)
+ return;
+
+ dn = ldapDNStrConverter.encodeDN(this);
+ }
+
+ private class RDNEnumerator implements Enumeration<RDN> {
+ private int index;
+
+ public RDNEnumerator() {
+ index = 0;
+ }
+
+ public boolean hasMoreElements() {
+ return (index < names.length);
+ }
+
+ public RDN nextElement() {
+ if (index >= names.length)
+ return null;
+ return names[index++];
+ }
+ }
+
+ /****************************************************************/
+
+ /*
+ * Maybe return a preallocated OID, to reduce storage costs
+ * and speed recognition of common X.500 attributes.
+ */
+ static ObjectIdentifier intern(ObjectIdentifier oid)
+ throws IOException {
+ return X500NameAttrMap.getDefault().getOid(oid);
+ }
+
+ /*
+ * Selected OIDs from X.520
+ */
+
+ /** OID for the "CN=" attribute, denoting a person's common name. */
+ public static final ObjectIdentifier commonName_oid = X500NameAttrMap.getDefault().getOid("CN");
+
+ /** OID for the "UID=" attribute, denoting a person's ID. */
+ public static final ObjectIdentifier uidName_oid = X500NameAttrMap.getDefault().getOid("UID");
+
+ /** OID for the "C=" attribute, denoting a country. */
+ public static final ObjectIdentifier countryName_oid = X500NameAttrMap.getDefault().getOid("C");
+
+ /** OID for the "L=" attribute, denoting a locality (such as a city) */
+ public static final ObjectIdentifier localityName_oid = X500NameAttrMap.getDefault().getOid("L");
+
+ /** OID for the "O=" attribute, denoting an organization name */
+ public static final ObjectIdentifier orgName_oid = X500NameAttrMap.getDefault().getOid("O");
+
+ /** OID for the "OU=" attribute, denoting an organizational unit name */
+ public static final ObjectIdentifier orgUnitName_oid = X500NameAttrMap.getDefault().getOid("OU");
+
+ /** OID for the "S=" attribute, denoting a state (such as Delaware) */
+ public static final ObjectIdentifier stateName_oid = X500NameAttrMap.getDefault().getOid("ST");
+
+ /** OID for the "STREET=" attribute, denoting a street address. */
+ public static final ObjectIdentifier streetAddress_oid = X500NameAttrMap.getDefault().getOid("STREET");
+
+ /** OID for the "T=" attribute, denoting a person's title. */
+ public static final ObjectIdentifier title_oid = X500NameAttrMap.getDefault().getOid("TITLE");
+
+ /** OID for the "E=" attribute, denoting a person's email address. */
+ public static final ObjectIdentifier email_oid = X500NameAttrMap.getDefault().getOid("E");
+
+ /*
+ * OIDs from other sources which show up in X.500 names we
+ * expect to deal with often
+ */
+
+ private static final int ipAddress_data[] = // SKIP
+ { 1, 3, 6, 1, 4, 1, 42, 2, 11, 2, 1 };
+
+ /** OID for "IP=" IP address attributes, used with SKIP. */
+ public static final ObjectIdentifier ipAddress_oid = new ObjectIdentifier(ipAddress_data);
+}
diff --git a/base/util/src/netscape/security/x509/X500NameAttrMap.java b/base/util/src/netscape/security/x509/X500NameAttrMap.java
new file mode 100644
index 000000000..1c87c79b8
--- /dev/null
+++ b/base/util/src/netscape/security/x509/X500NameAttrMap.java
@@ -0,0 +1,376 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * Maps an attribute name in an X500 AVA to its OID and a
+ * converter for the attribute type. The converter converts from a string to
+ * its DER encoded attribute value. * For example, "CN" maps to its OID of
+ * 2.5.4.3 and the Directory String Converter. The Directory String
+ * Converter converts from a string to a DerValue with tag Printable, T.61 or
+ * UniversalString.
+ *
+ * @author Lily Hsiao, Slava Galperin at Netscape Communications, Inc.
+ *
+ */
+
+public class X500NameAttrMap {
+ //
+ // public constructors.
+ //
+
+ /**
+ * Construct a X500NameAttrMap.
+ */
+ public X500NameAttrMap() {
+ }
+
+ //
+ // public get methods.
+ //
+
+ /**
+ * Get the attribute name (keyword) of the specified OID.
+ *
+ * @param oid An ObjectIdentifier
+ *
+ * @return An attribute name (keyword string) for the OID.
+ */
+ public String getName(ObjectIdentifier oid) {
+ // XXX assert oid != null
+ return oid2Name.get(oid);
+ }
+
+ /**
+ * Get the ObjectIdentifier of the attribute name.
+ *
+ * @param name An attribute name (string of ascii characters)
+ *
+ * @return An ObjectIdentifier for the attribute.
+ */
+ public ObjectIdentifier getOid(String name) {
+ // XXX assert name != null
+ return name2OID.get(name.toUpperCase());
+ }
+
+ /**
+ * Get the Attribute Value Converter for the specified attribute name.
+ *
+ * @param name An attribute name
+ *
+ * @return An attribute value converter for the attribute name
+ */
+ public AVAValueConverter getValueConverter(String name) {
+ ObjectIdentifier oid =
+ name2OID.get(name.toUpperCase());
+ if (oid == null)
+ return null;
+ return (AVAValueConverter) oid2ValueConverter.get(oid);
+ }
+
+ /**
+ * Get the Attribute Value Converter for the specified ObjectIdentifier.
+ *
+ * @param oid An ObjectIdentifier
+ *
+ * @return An AVAValueConverter for the OID.
+ */
+ public AVAValueConverter getValueConverter(ObjectIdentifier oid) {
+ return (AVAValueConverter) oid2ValueConverter.get(oid);
+ }
+
+ /**
+ * Get an Enumeration of all attribute names in this map.
+ *
+ * @return An Enumeration of all attribute names.
+ */
+ public Enumeration<String> getAllNames() {
+ return name2OID.keys();
+ }
+
+ /**
+ * Get an Enumeration of all ObjectIdentifiers in this map.
+ *
+ * @return An Enumeration of all OIDs in this map.
+ */
+ public Enumeration<ObjectIdentifier> getAllOIDs() {
+ return oid2Name.keys();
+ }
+
+ /**
+ * Get the ObjectIdentifier object in the map for the specified OID.
+ *
+ * @param oid An ObjectIdentifier.
+ * @return The ObjectIdentifier object in this map for the OID.
+ */
+ public ObjectIdentifier getOid(ObjectIdentifier oid) {
+ String name = oid2Name.get(oid);
+ if (name == null)
+ return null;
+ return name2OID.get(name);
+ }
+
+ //
+ // public add methods.
+ //
+
+ /**
+ * Adds a attribute name, ObjectIdentifier, AVAValueConverter entry
+ * to the map.
+ *
+ * @param name An attribute name (string of ascii chars)
+ * @param oid The ObjectIdentifier for the attribute.
+ * @param valueConverter An AVAValueConverter object for converting
+ * an value for this attribute from a string to
+ * a DerValue and vice versa.
+ */
+ public void addNameOID(String name, ObjectIdentifier oid,
+ AVAValueConverter valueConverter) {
+ // normalize name for case insensitive compare.
+ ObjectIdentifier theOid;
+ Class<? extends AVAValueConverter> expValueConverter;
+
+ theOid = name2OID.get(name);
+ if (theOid != null) {
+ expValueConverter = oid2ValueConverter.get(theOid).getClass();
+ if (!theOid.equals(oid) ||
+ expValueConverter != valueConverter.getClass()) {
+ throw new IllegalArgumentException(
+ "Another keyword-oid-valueConverter triple already " +
+ "exists in the X500NameAttrMap ");
+ }
+ return;
+ }
+ name2OID.put(name.toUpperCase(), oid);
+ oid2Name.put(oid, name.toUpperCase());
+ oid2ValueConverter.put(oid, valueConverter);
+ }
+
+ //
+ // public static methods.
+ //
+
+ /**
+ * Get the global default X500NameAttrMap.
+ *
+ * @return The global default X500NameAttrMap.
+ */
+ public static X500NameAttrMap getDefault() {
+ return defMap;
+ }
+
+ /**
+ * Get the global default X500NamAttrMap using the DirStrConverter.
+ *
+ * @return The global default X500NameAttrMap using the DirStrConverter.
+ */
+
+ public static X500NameAttrMap getDirDefault() {
+ return defDirMap;
+
+ }
+
+ /**
+ * Set the global default X500NameAttrMap.
+ *
+ * @param newDefault The new default X500NameAttrMap.
+ */
+ public static void setDefault(X500NameAttrMap newDefault) {
+ // XXX assert newDef != null
+ defMap = newDefault;
+ }
+
+ //
+ // private variables
+ //
+
+ Hashtable<String, ObjectIdentifier> name2OID = new Hashtable<String, ObjectIdentifier>();
+ Hashtable<ObjectIdentifier, String> oid2Name = new Hashtable<ObjectIdentifier, String>();
+ Hashtable<ObjectIdentifier, AVAValueConverter> oid2ValueConverter =
+ new Hashtable<ObjectIdentifier, AVAValueConverter>();
+
+ //
+ // global defaults.
+ //
+
+ private static X500NameAttrMap defMap;
+
+ private static X500NameAttrMap defDirMap;
+
+ /*
+ * Create the default maps on initialization.
+ */
+ static {
+ defMap = new X500NameAttrMap();
+ AVAValueConverter directoryStr = new DirStrConverter(), ia5Str = new IA5StringConverter();
+ defMap.addNameOID("CN",
+ new ObjectIdentifier("2.5.4.3"),
+ directoryStr);
+ defMap.addNameOID("OU",
+ new ObjectIdentifier("2.5.4.11"),
+ directoryStr);
+ defMap.addNameOID("O",
+ new ObjectIdentifier("2.5.4.10"),
+ directoryStr);
+ // serialNumber added for CEP support
+ defMap.addNameOID("SERIALNUMBER",
+ new ObjectIdentifier("2.5.4.5"),
+ new PrintableConverter());
+ defMap.addNameOID("C",
+ new ObjectIdentifier("2.5.4.6"),
+ new PrintableConverter());
+ defMap.addNameOID("L",
+ new ObjectIdentifier("2.5.4.7"),
+ directoryStr);
+ defMap.addNameOID("ST",
+ new ObjectIdentifier("2.5.4.8"),
+ directoryStr);
+ defMap.addNameOID("STREET",
+ new ObjectIdentifier("2.5.4.9"),
+ directoryStr);
+ defMap.addNameOID("TITLE",
+ new ObjectIdentifier("2.5.4.12"),
+ directoryStr);
+ // RFC 1274 UserId, rfc822MailBox
+ defMap.addNameOID("UID",
+ new ObjectIdentifier("0.9.2342.19200300.100.1.1"),
+ directoryStr);
+ defMap.addNameOID("MAIL",
+ new ObjectIdentifier("0.9.2342.19200300.100.1.3"),
+ ia5Str);
+ // PKCS9 e-mail address
+ defMap.addNameOID("E",
+ new ObjectIdentifier("1.2.840.113549.1.9.1"),
+ ia5Str);
+
+ // DC definition from draft-ietf-asid-ldap-domains-02.txt
+ defMap.addNameOID("DC",
+ new ObjectIdentifier("0.9.2342.19200300.100.1.25"),
+ ia5Str);
+
+ // more defined in RFC2459 used in Subject Directory Attr extension
+ defMap.addNameOID("SN", // surname
+ new ObjectIdentifier("2.5.4.4"),
+ directoryStr);
+ defMap.addNameOID("GIVENNAME",
+ new ObjectIdentifier("2.5.4.42"),
+ directoryStr);
+ defMap.addNameOID("INITIALS",
+ new ObjectIdentifier("2.5.4.43"),
+ directoryStr);
+ defMap.addNameOID("GENERATIONQUALIFIER",
+ new ObjectIdentifier("2.5.4.44"),
+ directoryStr);
+ defMap.addNameOID("DNQUALIFIER",
+ new ObjectIdentifier("2.5.4.46"),
+ directoryStr);
+
+ // these two added mainly for CEP support
+ // PKCS9 unstructured name
+ defMap.addNameOID("UNSTRUCTUREDNAME",
+ new ObjectIdentifier("1.2.840.113549.1.9.2"),
+ ia5Str);
+ // PKCS9 unstructured address
+ defMap.addNameOID("UNSTRUCTUREDADDRESS",
+ new ObjectIdentifier("1.2.840.113549.1.9.8"),
+ new PrintableConverter());
+ };
+
+ static {
+ defDirMap = new X500NameAttrMap();
+ AVAValueConverter directoryStr = new DirStrConverter();
+
+ defDirMap.addNameOID("CN",
+ new ObjectIdentifier("2.5.4.3"),
+ directoryStr);
+ defDirMap.addNameOID("OU",
+ new ObjectIdentifier("2.5.4.11"),
+ directoryStr);
+ defDirMap.addNameOID("O",
+ new ObjectIdentifier("2.5.4.10"),
+ directoryStr);
+ // serialNumber added for CEP support
+ defDirMap.addNameOID("SERIALNUMBER",
+ new ObjectIdentifier("2.5.4.5"),
+ directoryStr);
+ defDirMap.addNameOID("C",
+ new ObjectIdentifier("2.5.4.6"),
+ directoryStr);
+ defDirMap.addNameOID("L",
+ new ObjectIdentifier("2.5.4.7"),
+ directoryStr);
+ defDirMap.addNameOID("ST",
+ new ObjectIdentifier("2.5.4.8"),
+ directoryStr);
+ defDirMap.addNameOID("STREET",
+ new ObjectIdentifier("2.5.4.9"),
+ directoryStr);
+ defDirMap.addNameOID("TITLE",
+ new ObjectIdentifier("2.5.4.12"),
+ directoryStr);
+ // RFC 1274 UserId, rfc822MailBox
+ defDirMap.addNameOID("UID",
+ new ObjectIdentifier("0.9.2342.19200300.100.1.1"),
+ directoryStr);
+ defDirMap.addNameOID("MAIL",
+ new ObjectIdentifier("0.9.2342.19200300.100.1.3"),
+ directoryStr);
+ // PKCS9 e-mail address
+ defDirMap.addNameOID("E",
+ new ObjectIdentifier("1.2.840.113549.1.9.1"),
+ directoryStr);
+
+ // DC definition from draft-ietf-asid-ldap-domains-02.txt
+ defDirMap.addNameOID("DC",
+ new ObjectIdentifier("0.9.2342.19200300.100.1.25"),
+ directoryStr);
+
+ // more defined in RFC2459 used in Subject Directory Attr extension
+ defDirMap.addNameOID("SN", // surname
+ new ObjectIdentifier("2.5.4.4"),
+ directoryStr);
+ defDirMap.addNameOID("GIVENNAME",
+ new ObjectIdentifier("2.5.4.42"),
+ directoryStr);
+ defDirMap.addNameOID("INITIALS",
+ new ObjectIdentifier("2.5.4.43"),
+ directoryStr);
+ defDirMap.addNameOID("GENERATIONQUALIFIER",
+ new ObjectIdentifier("2.5.4.44"),
+ directoryStr);
+ defDirMap.addNameOID("DNQUALIFIER",
+ new ObjectIdentifier("2.5.4.46"),
+ directoryStr);
+
+ // these two added mainly for CEP support
+ // PKCS9 unstructured name
+ defDirMap.addNameOID("UNSTRUCTUREDNAME",
+ new ObjectIdentifier("1.2.840.113549.1.9.2"),
+ directoryStr);
+ // PKCS9 unstructured address
+ defDirMap.addNameOID("UNSTRUCTUREDADDRESS",
+ new ObjectIdentifier("1.2.840.113549.1.9.8"),
+ directoryStr);
+ };
+
+}
diff --git a/base/util/src/netscape/security/x509/X500Signer.java b/base/util/src/netscape/security/x509/X500Signer.java
new file mode 100644
index 000000000..0b8cf87a4
--- /dev/null
+++ b/base/util/src/netscape/security/x509/X500Signer.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 netscape.security.x509;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.Signer;
+
+/**
+ * This class provides a binding between a Signature object and an
+ * authenticated X.500 name (from an X.509 certificate chain), which
+ * is needed in many public key signing applications.
+ *
+ * <P>
+ * The name of the signer is important, both because knowing it is the whole point of the signature, and because the
+ * associated X.509 certificate is always used to verify the signature.
+ *
+ * <P>
+ * <em>The X.509 certificate chain is temporarily not associated with
+ * the signer, but this omission will be resolved.</em>
+ *
+ * @version 1.18
+ *
+ * @author David Brownell
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ */
+public final class X500Signer extends Signer {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3148659822293810158L;
+
+ /**
+ * Called for each chunk of the data being signed. That
+ * is, you can present the data in many chunks, so that
+ * it doesn't need to be in a single sequential buffer.
+ *
+ * @param buf buffer holding the next chunk of the data to be signed
+ * @param offset starting point of to-be-signed data
+ * @param len how many bytes of data are to be signed
+ * @exception SignatureException on errors.
+ */
+ public void update(byte buf[], int offset, int len)
+ throws SignatureException {
+ sig.update(buf, offset, len);
+ }
+
+ /**
+ * Produces the signature for the data processed by update().
+ *
+ * @exception SignatureException on errors.
+ */
+ public byte[] sign() throws SignatureException {
+ return sig.sign();
+ }
+
+ /**
+ * Returns the algorithm used to sign.
+ */
+ public AlgorithmId getAlgorithmId() {
+ return algid;
+ }
+
+ /**
+ * Returns the name of the signing agent.
+ */
+ public X500Name getSigner() {
+ return agent;
+ }
+
+ /*
+ * Constructs a binding between a signature and an X500 name
+ * from an X.509 certificate.
+ */
+ // package private ----hmmmmm ?????
+ public X500Signer(Signature sig, X500Name agent) {
+ if (sig == null || agent == null)
+ throw new IllegalArgumentException("null parameter");
+
+ this.sig = sig;
+ this.agent = agent;
+
+ try {
+ this.algid = AlgorithmId.getAlgorithmId(sig.getAlgorithm());
+ String alg = sig.getAlgorithm();
+ if (alg.equals("DSA")) {
+ alg = "SHA1withDSA";
+ }
+ this.algid = AlgorithmId.getAlgorithmId(alg);
+
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException("internal error! " + e.getMessage());
+ }
+ }
+
+ private Signature sig;
+ private X500Name agent; // XXX should be X509CertChain
+ private AlgorithmId algid;
+}
diff --git a/base/util/src/netscape/security/x509/X509AttributeName.java b/base/util/src/netscape/security/x509/X509AttributeName.java
new file mode 100644
index 000000000..2f6c46cb1
--- /dev/null
+++ b/base/util/src/netscape/security/x509/X509AttributeName.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 netscape.security.x509;
+
+/**
+ * This class is used to parse attribute names like "x509.info.extensions".
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.4
+ */
+public class X509AttributeName {
+ // 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
+ * "x509.info.extensions".
+ *
+ * @param name the attribute name.
+ */
+ public X509AttributeName(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.
+ */
+ public String getPrefix() {
+ return (prefix);
+ }
+
+ /**
+ * Return the suffix of the name.
+ */
+ public String getSuffix() {
+ return (suffix);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/X509CRLImpl.java b/base/util/src/netscape/security/x509/X509CRLImpl.java
new file mode 100755
index 000000000..8c69b6aa0
--- /dev/null
+++ b/base/util/src/netscape/security/x509/X509CRLImpl.java
@@ -0,0 +1,1071 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.CRLException;
+import java.security.cert.Certificate;
+import java.security.cert.X509CRL;
+import java.security.cert.X509CRLEntry;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * <p>
+ * An implmentation for X509 CRL (Certificate Revocation List).
+ * <p>
+ * The X.509 v2 CRL format is described below in ASN.1:
+ *
+ * <pre>
+ * </pre>
+ * <p>
+ * CertificateList ::= SEQUENCE { tbsCertList TBSCertList, signatureAlgorithm AlgorithmIdentifier, signature BIT STRING
+ * }
+ * <p>
+ * A good description and profiling is provided in the IETF PKIX WG draft, Part I: X.509 Certificate and CRL Profile,
+ * &lt;draft-ietf-pkix-ipki-part1-06.txt&gt;.
+ * <p>
+ * The ASN.1 definition of <code>tbsCertList</code> is:
+ *
+ * <pre>
+ * TBSCertList ::= SEQUENCE {
+ * version Version OPTIONAL,
+ * -- if present, must be v2
+ * signature AlgorithmIdentifier,
+ * issuer Name,
+ * thisUpdate ChoiceOfTime,
+ * nextUpdate ChoiceOfTime OPTIONAL,
+ * revokedCertificates SEQUENCE OF SEQUENCE {
+ * userCertificate CertificateSerialNumber,
+ * revocationDate ChoiceOfTime,
+ * crlEntryExtensions Extensions OPTIONAL
+ * -- if present, must be v2
+ * } OPTIONAL,
+ * crlExtensions [0] EXPLICIT Extensions OPTIONAL
+ * -- if present, must be v2
+ * }
+ * </pre>
+ *
+ * @author Hemma Prafullchandra
+ * @version 1.8
+ * @see X509CRL
+ */
+public class X509CRLImpl extends X509CRL {
+
+ // CRL data, and its envelope
+ private byte[] signedCRL = null; // DER encoded crl
+ private byte[] signature = null; // raw signature bits
+ private byte[] tbsCertList = null; // DER encoded "to-be-signed" CRL
+ private AlgorithmId sigAlgId; // sig alg in CRL
+
+ // crl information
+ private int version;
+ private AlgorithmId infoSigAlgId; // sig alg in "to-be-signed" crl
+ private X500Name issuer;
+ private Date thisUpdate = null;
+ private Date nextUpdate = null;
+ // private static final Hashtable revokedCerts = new Hashtable();
+ private Hashtable<BigInteger, RevokedCertificate> revokedCerts = new Hashtable<BigInteger, RevokedCertificate>();
+ // private static CRLExtensions extensions = null;
+ private CRLExtensions extensions = null;
+ private boolean entriesIncluded = true;
+ private final static boolean isExplicit = true;
+
+ private boolean readOnly = false;
+
+ /**
+ * Unmarshals an X.509 CRL from its encoded form, parsing the encoded
+ * bytes. This form of constructor is used by agents which
+ * need to examine and use CRL contents. Note that the buffer
+ * must include only one CRL, and no "garbage" may be left at
+ * the end.
+ *
+ * @param crlData the encoded bytes, with no trailing padding.
+ * @exception CRLException on parsing errors.
+ * @exception X509ExtensionException on extension handling errors.
+ */
+ public X509CRLImpl(byte[] crlData)
+ throws CRLException, X509ExtensionException {
+ try {
+ DerValue in = new DerValue(crlData);
+
+ parse(in);
+ signedCRL = crlData;
+ } catch (IOException e) {
+ throw new CRLException("Parsing error: " + e.getMessage());
+ }
+ }
+
+ public X509CRLImpl(byte[] crlData, boolean includeEntries)
+ throws CRLException, X509ExtensionException {
+ try {
+ entriesIncluded = includeEntries;
+ DerValue in = new DerValue(crlData);
+
+ parse(in, includeEntries);
+ signedCRL = crlData;
+ } catch (IOException e) {
+ throw new CRLException("Parsing error: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Unmarshals an X.509 CRL from an input stream. Only one CRL
+ * is expected at the end of the input stream.
+ *
+ * @param inStrm an input stream holding at least one CRL
+ * @exception CRLException on parsing errors.
+ * @exception X509ExtensionException on extension handling errors.
+ */
+ public X509CRLImpl(InputStream inStrm)
+ throws CRLException, X509ExtensionException {
+ try {
+ DerValue val = new DerValue(inStrm);
+
+ parse(val);
+ signedCRL = val.toByteArray();
+ } catch (IOException e) {
+ throw new CRLException("Parsing error: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Initial CRL constructor, no revoked certs, and no extensions.
+ *
+ * @param issuer the name of the CA issuing this CRL.
+ * @param thisUpdate the Date of this issue.
+ * @param nextUpdate the Date of the next CRL.
+ */
+ public X509CRLImpl(X500Name issuer, Date thisDate, Date nextDate) {
+ this.issuer = issuer;
+ this.thisUpdate = thisDate;
+ this.nextUpdate = nextDate;
+ }
+
+ /**
+ * CRL constructor, revoked certs, no extensions.
+ *
+ * @param issuer the name of the CA issuing this CRL.
+ * @param thisUpdate the Date of this issue.
+ * @param nextUpdate the Date of the next CRL.
+ * @param badCerts the array of revoked certificates.
+ *
+ * @exception CRLException on parsing/construction errors.
+ * @exception X509ExtensionException on extension handling errors.
+ */
+ public X509CRLImpl(X500Name issuer, Date thisDate, Date nextDate,
+ RevokedCertificate[] badCerts)
+ throws CRLException, X509ExtensionException {
+ this.issuer = issuer;
+ this.thisUpdate = thisDate;
+ this.nextUpdate = nextDate;
+ if (badCerts != null) {
+ for (int i = 0; i < badCerts.length; i++)
+ this.revokedCerts.put(badCerts[i].getSerialNumber(),
+ badCerts[i]);
+ }
+ }
+
+ /**
+ * CRL constructor, revoked certs and extensions.
+ *
+ * @param issuer the name of the CA issuing this CRL.
+ * @param thisUpdate the Date of this issue.
+ * @param nextUpdate the Date of the next CRL.
+ * @param badCerts the array of revoked certificates.
+ * @param crlExts the CRL extensions.
+ *
+ * @exception CRLException on parsing/construction errors.
+ * @exception X509ExtensionException on extension handling errors.
+ */
+ public X509CRLImpl(X500Name issuer, Date thisDate, Date nextDate,
+ RevokedCertificate[] badCerts, CRLExtensions crlExts)
+ throws CRLException, X509ExtensionException {
+ this.issuer = issuer;
+ this.thisUpdate = thisDate;
+ this.nextUpdate = nextDate;
+ if (badCerts != null) {
+ for (int i = 0; i < badCerts.length; i++) {
+ if (badCerts[i] != null) {
+ this.revokedCerts.put(badCerts[i].getSerialNumber(),
+ badCerts[i]);
+ if (badCerts[i].hasExtensions())
+ this.version = 1;
+ }
+ }
+ }
+ if (crlExts != null) {
+ this.extensions = crlExts;
+ this.version = 1;
+ }
+ }
+
+ /**
+ * CRL constructor, revoked certs and extensions.
+ * This will be used by code that constructs CRL and uses
+ * encodeInfo() in order to sign it using external means
+ * (other than sign() method)
+ *
+ * @param issuer the name of the CA issuing this CRL.
+ * @param sigAlg signing algorithm id
+ * @param thisUpdate the Date of this issue.
+ * @param nextUpdate the Date of the next CRL.
+ * @param badCerts the array of revoked certificates.
+ * @param crlExts the CRL extensions.
+ */
+ public X509CRLImpl(X500Name issuer, AlgorithmId algId, Date thisDate, Date nextDate,
+ RevokedCertificate[] badCerts, CRLExtensions crlExts)
+ throws CRLException, X509ExtensionException {
+ this(issuer, thisDate, nextDate, badCerts, crlExts);
+ infoSigAlgId = algId;
+ }
+
+ /**
+ * CRL constructor, revoked certs and extensions.
+ *
+ * @param issuer the name of the CA issuing this CRL.
+ * @param sigAlg signing algorithm id
+ * @param thisUpdate the Date of this issue.
+ * @param nextUpdate the Date of the next CRL.
+ * @param badCerts the hashtable of revoked certificates.
+ * @param crlExts the CRL extensions.
+ *
+ * @exception CRLException on parsing/construction errors.
+ * @exception X509ExtensionException on extension handling errors.
+ */
+ public X509CRLImpl(X500Name issuer, AlgorithmId algId,
+ Date thisDate, Date nextDate,
+ Hashtable<BigInteger, RevokedCertificate> badCerts, CRLExtensions crlExts)
+ throws CRLException, X509ExtensionException {
+ this.issuer = issuer;
+ this.thisUpdate = thisDate;
+ this.nextUpdate = nextDate;
+ this.revokedCerts = badCerts;
+ if (crlExts != null) {
+ this.extensions = crlExts;
+ this.version = 1;
+ }
+ infoSigAlgId = algId;
+ }
+
+ /**
+ * Returns the ASN.1 DER encoded form of this CRL.
+ *
+ * @exception CRLException if an encoding error occurs.
+ */
+ public byte[] getEncoded() throws CRLException {
+ if (signedCRL == null)
+ throw new CRLException("Null CRL to encode");
+ byte[] dup = new byte[signedCRL.length];
+ System.arraycopy(signedCRL, 0, dup, 0, dup.length);
+ return dup;
+ }
+
+ /**
+ * Returns true if signedCRL was set.
+ *
+ * @param byte array of containing signed CRL.
+ */
+ public boolean setSignedCRL(byte[] crl) {
+ boolean done = false;
+ if (tbsCertList != null && signedCRL == null) {
+ signedCRL = new byte[crl.length];
+ System.arraycopy(crl, 0, signedCRL, 0, signedCRL.length);
+ done = true;
+ }
+ return done;
+ }
+
+ public boolean hasUnsupportedCriticalExtension() {
+ // XXX NOT IMPLEMENTED
+ return true;
+ }
+
+ /**
+ * Encodes the "to-be-signed" CRL to the OutputStream.
+ *
+ * @param out the OutputStream to write to.
+ * @exception CRLException on encoding errors.
+ * @exception X509ExtensionException on extension encoding errors.
+ */
+ public void encodeInfo(OutputStream out)
+ throws CRLException, X509ExtensionException {
+ try {
+ DerOutputStream tmp = new DerOutputStream();
+ DerOutputStream rCerts = new DerOutputStream();
+ DerOutputStream seq = new DerOutputStream();
+
+ if (version != 0) // v2 crl encode version
+ tmp.putInteger(new BigInt(version));
+ infoSigAlgId.encode(tmp);
+ issuer.encode(tmp);
+
+ // from 2050 should encode GeneralizedTime
+ tmp.putUTCTime(thisUpdate);
+
+ if (nextUpdate != null)
+ tmp.putUTCTime(nextUpdate);
+
+ if (!revokedCerts.isEmpty()) {
+ for (Enumeration<RevokedCertificate> e = revokedCerts.elements(); e.hasMoreElements();)
+ ((RevokedCertImpl) e.nextElement()).encode(rCerts);
+ tmp.write(DerValue.tag_Sequence, rCerts);
+ }
+
+ if (extensions != null)
+ extensions.encode(tmp, isExplicit);
+
+ seq.write(DerValue.tag_Sequence, tmp);
+
+ tbsCertList = seq.toByteArray();
+ out.write(tbsCertList);
+ } catch (IOException e) {
+ throw new CRLException("Encoding error: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Verifies that this CRL was signed using the
+ * private key that corresponds to the specified public key.
+ *
+ * @param key the PublicKey used to carry out the verification.
+ *
+ * @exception NoSuchAlgorithmException on unsupported signature
+ * algorithms.
+ * @exception InvalidKeyException on incorrect key.
+ * @exception NoSuchProviderException if there's no default provider.
+ * @exception SignatureException on signature errors.
+ * @exception CRLException on encoding errors.
+ */
+ public void verify(PublicKey key)
+ throws CRLException, NoSuchAlgorithmException, InvalidKeyException,
+ NoSuchProviderException, SignatureException {
+ verify(key, null);
+ }
+
+ /**
+ * Verifies that this CRL was signed using the
+ * private key that corresponds to the specified public key,
+ * and that the signature verification was computed by
+ * the given provider.
+ *
+ * @param key the PublicKey used to carry out the verification.
+ * @param sigProvider the name of the signature provider.
+ *
+ * @exception NoSuchAlgorithmException on unsupported signature
+ * algorithms.
+ * @exception InvalidKeyException on incorrect key.
+ * @exception NoSuchProviderException on incorrect provider.
+ * @exception SignatureException on signature errors.
+ * @exception CRLException on encoding errors.
+ */
+ public void verify(PublicKey key, String sigProvider)
+ throws CRLException, NoSuchAlgorithmException, InvalidKeyException,
+ NoSuchProviderException, SignatureException {
+ if (signedCRL == null) {
+ throw new CRLException("Uninitialized CRL");
+ }
+ Signature sigVerf = null;
+
+ String sigAlg = sigAlgId.getName();
+ if (sigProvider.equals("Mozilla-JSS")) {
+ if (sigAlg.equals("MD5withRSA")) {
+ sigAlg = "MD5/RSA";
+ } else if (sigAlg.equals("MD2withRSA")) {
+ sigAlg = "MD2/RSA";
+ } else if (sigAlg.equals("SHA1withRSA")) {
+ sigAlg = "SHA1/RSA";
+ } else if (sigAlg.equals("SHA1withDSA")) {
+ sigAlg = "SHA1/DSA";
+ }
+ }
+ sigVerf = Signature.getInstance(sigAlg, sigProvider);
+ sigVerf.initVerify(key);
+
+ if (tbsCertList == null)
+ throw new CRLException("Uninitialized CRL");
+
+ sigVerf.update(tbsCertList, 0, tbsCertList.length);
+
+ if (!sigVerf.verify(signature)) {
+ throw new CRLException("Signature does not match.");
+ }
+ }
+
+ /**
+ * Encodes an X.509 CRL, and signs it using the key
+ * passed.
+ *
+ * @param key the private key used for signing.
+ * @param algorithm the name of the signature algorithm used.
+ *
+ * @exception NoSuchAlgorithmException on unsupported signature
+ * algorithms.
+ * @exception InvalidKeyException on incorrect key.
+ * @exception NoSuchProviderException on incorrect provider.
+ * @exception SignatureException on signature errors.
+ * @exception CRLException if any mandatory data was omitted.
+ * @exception X509ExtensionException on any extension errors.
+ */
+ public void sign(PrivateKey key, String algorithm)
+ throws CRLException, NoSuchAlgorithmException, InvalidKeyException,
+ NoSuchProviderException, SignatureException, X509ExtensionException {
+ sign(key, algorithm, null);
+ }
+
+ /**
+ * Encodes an X.509 CRL, and signs it using the key
+ * passed.
+ *
+ * @param key the private key used for signing.
+ * @param algorithm the name of the signature algorithm used.
+ * @param provider the name of the provider.
+ *
+ * @exception NoSuchAlgorithmException on unsupported signature
+ * algorithms.
+ * @exception InvalidKeyException on incorrect key.
+ * @exception NoSuchProviderException on incorrect provider.
+ * @exception SignatureException on signature errors.
+ * @exception CRLException if any mandatory data was omitted.
+ * @exception X509ExtensionException on any extension errors.
+ */
+ public void sign(PrivateKey key, String algorithm, String provider)
+ throws CRLException, NoSuchAlgorithmException, InvalidKeyException,
+ NoSuchProviderException, SignatureException, X509ExtensionException {
+ try {
+ if (readOnly)
+ throw new CRLException("cannot over-write existing CRL");
+ Signature sigEngine = null;
+ if (provider == null)
+ sigEngine = Signature.getInstance(algorithm);
+ else
+ sigEngine = Signature.getInstance(algorithm, provider);
+
+ sigEngine.initSign(key);
+
+ // in case the name is reset
+ sigAlgId = AlgorithmId.get(sigEngine.getAlgorithm());
+ infoSigAlgId = sigAlgId;
+
+ DerOutputStream out = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+
+ // encode crl info
+ encodeInfo(tmp);
+
+ // encode algorithm identifier
+ sigAlgId.encode(tmp);
+
+ // Create and encode the signature itself.
+ sigEngine.update(tbsCertList, 0, tbsCertList.length);
+ signature = sigEngine.sign();
+ tmp.putBitString(signature);
+
+ // Wrap the signed data in a SEQUENCE { data, algorithm, sig }
+ out.write(DerValue.tag_Sequence, tmp);
+ signedCRL = out.toByteArray();
+ readOnly = true;
+
+ } catch (IOException e) {
+ throw new CRLException("Error while encoding data: " +
+ e.getMessage());
+ }
+ }
+
+ /**
+ * Returns a printable string of this CRL.
+ *
+ * @return value of this CRL in a printable form.
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("X.509 CRL v" + (version + 1) + "\n");
+ sb.append("Signature Algorithm: " + sigAlgId.toString() +
+ ", OID=" + (sigAlgId.getOID()).toString() + "\n");
+ sb.append("Issuer: " + issuer.toString() + "\n");
+ sb.append("\nThis Update: " + thisUpdate.toString() + "\n");
+ if (nextUpdate != null)
+ sb.append("Next Update: " + nextUpdate.toString() + "\n");
+ if (revokedCerts.isEmpty())
+ sb.append("\nNO certificates have been revoked\n");
+ else {
+ sb.append("\nRevoked Certificates:\n");
+ for (Enumeration<RevokedCertificate> e = revokedCerts.elements(); e.hasMoreElements();)
+ sb.append(((RevokedCertificate) e.nextElement()).toString());
+ }
+ if (extensions != null) {
+ for (int i = 0; i < extensions.size(); i++) {
+ sb.append("\nCRL Extension[" + i + "]: " +
+ ((Extension) (extensions.elementAt(i))).toString());
+ }
+ }
+ netscape.security.util.PrettyPrintFormat pp =
+ new netscape.security.util.PrettyPrintFormat(" ", 20);
+ String signaturebits = pp.toHexString(signature);
+ sb.append("\nSignature:\n" + signaturebits);
+
+ return sb.toString();
+ }
+
+ /**
+ * Checks whether the given serial number is on this CRL.
+ *
+ * @param serialNumber the number to check for.
+ * @return true if the given serial number is on this CRL,
+ * false otherwise.
+ */
+ public boolean isRevoked(BigInteger serialNumber) {
+ if (revokedCerts == null || revokedCerts.isEmpty())
+ return false;
+ return revokedCerts.containsKey(serialNumber);
+ }
+
+ public boolean isRevoked(Certificate cert) {
+ if (cert == null)
+ return false;
+ if (cert instanceof X509Certificate) {
+ return isRevoked(((X509Certificate) cert).getSerialNumber());
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Gets the version number from the CRL.
+ * The ASN.1 definition for this is:
+ *
+ * <pre>
+ * Version ::= INTEGER { v1(0), v2(1), v3(2) }
+ * -- v3 does not apply to CRLs but appears for consistency
+ * -- with definition of Version for certs
+ * </pre>
+ *
+ * @return the version number.
+ */
+ public int getVersion() {
+ return version;
+ }
+
+ /**
+ * Gets the issuer distinguished name from this CRL.
+ * The issuer name identifies the entity who has signed (and
+ * issued the CRL). The issuer name field contains an
+ * X.500 distinguished name (DN).
+ * The ASN.1 definition for this is:
+ *
+ * <pre>
+ * issuer Name
+ *
+ * Name ::= CHOICE { RDNSequence }
+ * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+ * RelativeDistinguishedName ::=
+ * SET OF AttributeValueAssertion
+ *
+ * AttributeValueAssertion ::= SEQUENCE {
+ * AttributeType,
+ * AttributeValue }
+ * AttributeType ::= OBJECT IDENTIFIER
+ * AttributeValue ::= ANY
+ * </pre>
+ *
+ * The Name describes a hierarchical name composed of attributes,
+ * such as country name, and corresponding values, such as US.
+ * The type of the component AttributeValue is determined by the
+ * AttributeType; in general it will be a directoryString.
+ * A directoryString is usually one of PrintableString,
+ * TeletexString or UniversalString.
+ *
+ * @return the issuer name.
+ */
+ public Principal getIssuerDN() {
+ return (Principal) issuer;
+ }
+
+ /**
+ * Gets the thisUpdate date from the CRL.
+ * The ASN.1 definition for this is:
+ *
+ * @return the thisUpdate date from the CRL.
+ */
+ public Date getThisUpdate() {
+ return (new Date(thisUpdate.getTime()));
+ }
+
+ /**
+ * Gets the nextUpdate date from the CRL.
+ *
+ * @return the nextUpdate date from the CRL, or null if
+ * not present.
+ */
+ public Date getNextUpdate() {
+ if (nextUpdate == null)
+ return null;
+ return (new Date(nextUpdate.getTime()));
+ }
+
+ /**
+ * Get the revoked certificate from the CRL by the serial
+ * number provided.
+ *
+ * @return the revoked certificate or null if there is
+ * no entry in the CRL marked with the provided serial number.
+ * @see RevokedCertificate
+ */
+ public X509CRLEntry getRevokedCertificate(BigInteger serialNumber) {
+ if (revokedCerts == null || revokedCerts.isEmpty())
+ return null;
+ RevokedCertificate badCert =
+ (RevokedCertificate) revokedCerts.get(serialNumber);
+ return badCert;
+ }
+
+ /**
+ * Gets all the revoked certificates from the CRL.
+ * A Set of RevokedCertificate.
+ *
+ * @return all the revoked certificates or null if there are
+ * none.
+ * @see RevokedCertificate
+ */
+ public Set<RevokedCertificate> getRevokedCertificates() {
+ if (revokedCerts == null || revokedCerts.isEmpty())
+ return null;
+ else {
+ Set<RevokedCertificate> certSet = new LinkedHashSet<RevokedCertificate>(revokedCerts.values());
+ return certSet;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public Hashtable<BigInteger, RevokedCertificate> getListOfRevokedCertificates() {
+ if (revokedCerts == null) {
+ return null;
+ } else {
+ return (Hashtable<BigInteger, RevokedCertificate>) revokedCerts.clone();
+ }
+ }
+
+ public int getNumberOfRevokedCertificates() {
+ if (revokedCerts == null)
+ return -1;
+ else
+ return revokedCerts.size();
+ }
+
+ /**
+ * Gets the DER encoded CRL information, the <code>tbsCertList</code> from this CRL.
+ * This can be used to verify the signature independently.
+ *
+ * @return the DER encoded CRL information.
+ * @exception CRLException on parsing errors.
+ * @exception X509ExtensionException on extension parsing errors.
+ */
+ public byte[] getTBSCertList()
+ throws CRLException {
+ if (tbsCertList == null)
+ throw new CRLException("Uninitialized CRL");
+ byte[] dup = new byte[tbsCertList.length];
+ System.arraycopy(tbsCertList, 0, dup, 0, dup.length);
+ return dup;
+ }
+
+ /**
+ * Gets the raw Signature bits from the CRL.
+ *
+ * @return the signature.
+ */
+ public byte[] getSignature() {
+ if (signature == null)
+ return null;
+ byte[] dup = new byte[signature.length];
+ System.arraycopy(signature, 0, dup, 0, dup.length);
+ return dup;
+ }
+
+ /**
+ * Returns true if signature was set.
+ *
+ * @param byte array of containing CRL signature.
+ */
+ public boolean setSignature(byte[] crlSignature) {
+ boolean done = false;
+ if (tbsCertList != null && signature == null) {
+ signature = new byte[crlSignature.length];
+ System.arraycopy(crlSignature, 0, signature, 0, signature.length);
+ done = true;
+ }
+ return done;
+ }
+
+ /**
+ * Gets the signature algorithm name for the CRL
+ * signature algorithm. For example, the string "SHA1withDSA".
+ * The ASN.1 definition for this is:
+ *
+ * <pre>
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL }
+ * -- contains a value of the type
+ * -- registered for use with the
+ * -- algorithm object identifier value
+ * </pre>
+ *
+ * @return the signature algorithm name.
+ */
+ public String getSigAlgName() {
+ if (sigAlgId == null)
+ return null;
+ return sigAlgId.getName();
+ }
+
+ /**
+ * Gets the signature algorithm OID string from the CRL.
+ * An OID is represented by a set of positive whole number separated
+ * by ".", that means,<br>
+ * &lt;positive whole number&gt;.&lt;positive whole number&gt;.&lt;...&gt;
+ * For example, the string "1.2.840.10040.4.3" identifies the SHA-1
+ * with DSA signature algorithm, as per the PKIX part I.
+ *
+ * @return the signature algorithm oid string.
+ */
+ public String getSigAlgOID() {
+ if (sigAlgId == null)
+ return null;
+ ObjectIdentifier oid = sigAlgId.getOID();
+ return oid.toString();
+ }
+
+ /**
+ * Gets the DER encoded signature algorithm parameters from this
+ * CRL's signature algorithm. In most cases, the signature
+ * algorithm parameters are null, the parameters are usually
+ * supplied with the Public Key.
+ *
+ * @return the DER encoded signature algorithm parameters, or
+ * null if no parameters are present.
+ */
+ public byte[] getSigAlgParams() {
+ if (sigAlgId == null)
+ return null;
+ try {
+ return sigAlgId.getEncodedParams();
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Gets a Set of the extension(s) marked CRITICAL in the
+ * CRL by OID strings.
+ *
+ * @return a set of the extension oid strings in the
+ * CRL that are marked critical.
+ */
+ public Set<String> getCriticalExtensionOIDs() {
+ if (extensions == null)
+ return null;
+ Set<String> extSet = new LinkedHashSet<String>();
+ Extension ex;
+ for (Enumeration<Extension> e = extensions.getElements(); e.hasMoreElements();) {
+ ex = e.nextElement();
+ if (ex.isCritical()) {
+ extSet.add(((ObjectIdentifier) ex.getExtensionId()).toString());
+ }
+ }
+ return extSet;
+ }
+
+ /**
+ * Gets a Set of the extension(s) marked NON-CRITICAL in the
+ * CRL by OID strings.
+ *
+ * @return a set of the extension oid strings in the
+ * CRL that are NOT marked critical.
+ */
+ public Set<String> getNonCriticalExtensionOIDs() {
+ if (extensions == null)
+ return null;
+ Set<String> extSet = new LinkedHashSet<String>();
+ Extension ex;
+ for (Enumeration<Extension> e = extensions.getElements(); e.hasMoreElements();) {
+ ex = e.nextElement();
+ if (!ex.isCritical())
+ extSet.add(((ObjectIdentifier) ex.getExtensionId()).toString());
+ }
+ return extSet;
+ }
+
+ /**
+ * Gets the DER encoded OCTET string for the extension value
+ * (<code>extnValue</code>) identified by the passed in oid String.
+ * The <code>oid</code> string is
+ * represented by a set of positive whole number separated
+ * by ".", that means,<br>
+ * &lt;positive whole number&gt;.&lt;positive whole number&gt;.&lt;...&gt;
+ *
+ * @param oid the Object Identifier value for the extension.
+ * @return the der encoded octet string of the extension value.
+ */
+ public byte[] getExtensionValue(String oid) {
+ if (extensions == null)
+ return null;
+ try {
+ String extAlias = OIDMap.getName(new ObjectIdentifier(oid));
+ Extension crlExt = null;
+
+ if (extAlias == null) { // may be unknown
+ ObjectIdentifier findOID = new ObjectIdentifier(oid);
+ Extension ex = null;
+ ObjectIdentifier inCertOID;
+ for (Enumeration<Extension> e = extensions.getElements(); e.hasMoreElements();) {
+ ex = e.nextElement();
+ inCertOID = ex.getExtensionId();
+ if (inCertOID.equals(findOID)) {
+ crlExt = ex;
+ break;
+ }
+ }
+ } else
+ crlExt = extensions.get(extAlias);
+ if (crlExt == null)
+ return null;
+ byte[] extData = crlExt.getExtensionValue();
+ if (extData == null)
+ return null;
+ DerOutputStream out = new DerOutputStream();
+ out.putOctetString(extData);
+ return out.toByteArray();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public BigInteger getCRLNumber() {
+ try {
+ CRLExtensions exts = getExtensions();
+ if (exts == null)
+ return null;
+ Enumeration<Extension> e = exts.getElements();
+ while (e.hasMoreElements()) {
+ Extension ext = (Extension) e.nextElement();
+ if (ext instanceof CRLNumberExtension) {
+ CRLNumberExtension numExt = (CRLNumberExtension) ext;
+ return (BigInteger) numExt.get(CRLNumberExtension.NUMBER);
+ }
+ }
+ } catch (Exception e) {
+ }
+ return null;
+ }
+
+ public BigInteger getDeltaBaseCRLNumber() {
+ try {
+ CRLExtensions exts = getExtensions();
+ if (exts == null)
+ return null;
+ Enumeration<Extension> e = exts.getElements();
+ while (e.hasMoreElements()) {
+ Extension ext = (Extension) e.nextElement();
+ if (ext instanceof DeltaCRLIndicatorExtension) {
+ DeltaCRLIndicatorExtension numExt = (DeltaCRLIndicatorExtension) ext;
+ return (BigInteger) numExt.get(DeltaCRLIndicatorExtension.NUMBER);
+ }
+ }
+ } catch (Exception e) {
+ }
+ return null;
+ }
+
+ public boolean isDeltaCRL() {
+ try {
+ CRLExtensions exts = getExtensions();
+ if (exts == null)
+ return false;
+ Enumeration<Extension> e = exts.getElements();
+ while (e.hasMoreElements()) {
+ Extension ext = (Extension) e.nextElement();
+ if (ext instanceof DeltaCRLIndicatorExtension) {
+ return true;
+ }
+ }
+ } catch (Exception e) {
+ }
+ return false;
+ }
+
+ /**
+ * Returns extensions for this impl.
+ *
+ * @param extn CRLExtensions
+ */
+ public CRLExtensions getExtensions() {
+ return extensions;
+ }
+
+ public boolean areEntriesIncluded() {
+ return entriesIncluded;
+ }
+
+ /*********************************************************************/
+ /*
+ * Parses an X.509 CRL, should be used only by constructors.
+ */
+ private void parse(DerValue val)
+ throws CRLException, IOException, X509ExtensionException {
+ parse(val, true);
+ }
+
+ private void parse(DerValue val, boolean includeEntries)
+ throws CRLException, IOException, X509ExtensionException {
+ // check if can over write the certificate
+ if (readOnly)
+ throw new CRLException("cannot over-write existing CRL");
+
+ readOnly = true;
+ DerValue seq[] = new DerValue[3];
+
+ seq[0] = val.data.getDerValue();
+ seq[1] = val.data.getDerValue();
+ seq[2] = val.data.getDerValue();
+
+ if (val.data.available() != 0)
+ throw new CRLException("signed overrun, bytes = "
+ + val.data.available());
+
+ if (seq[0].tag != DerValue.tag_Sequence)
+ throw new CRLException("signed CRL fields invalid");
+
+ sigAlgId = AlgorithmId.parse(seq[1]);
+ signature = seq[2].getBitString();
+
+ if (seq[1].data.available() != 0)
+ throw new CRLException("AlgorithmId field overrun");
+
+ if (seq[2].data.available() != 0)
+ throw new CRLException("Signature field overrun");
+
+ // the tbsCertsList
+ tbsCertList = seq[0].toByteArray();
+
+ // parse the information
+ DerInputStream derStrm = seq[0].data;
+ DerValue tmp;
+ byte nextByte;
+
+ // version (optional if v1)
+ version = 0; // by default, version = v1 == 0
+ nextByte = (byte) derStrm.peekByte();
+ if (nextByte == DerValue.tag_Integer) {
+ version = derStrm.getInteger().toInt();
+ if (version != 1) // i.e. v2
+ throw new CRLException("Invalid version");
+ }
+ tmp = derStrm.getDerValue();
+ // signature
+ {
+ AlgorithmId tmpId = AlgorithmId.parse(tmp);
+ if (!tmpId.equals(sigAlgId))
+ throw new CRLException("Signature algorithm mismatch");
+
+ infoSigAlgId = tmpId;
+ }
+ // issuer
+ issuer = new X500Name(derStrm);
+
+ // thisUpdate
+ // check if UTCTime encoded or GeneralizedTime
+
+ nextByte = (byte) derStrm.peekByte();
+ if (nextByte == DerValue.tag_UtcTime) {
+ thisUpdate = derStrm.getUTCTime();
+ } else if (nextByte == DerValue.tag_GeneralizedTime) {
+ thisUpdate = derStrm.getGeneralizedTime();
+ } else {
+ throw new CRLException("Invalid encoding for thisUpdate"
+ + " (tag=" + nextByte + ")");
+ }
+
+ if (derStrm.available() == 0)
+ return; // done parsing no more optional fields present
+
+ // nextUpdate (optional)
+ nextByte = (byte) derStrm.peekByte();
+ if (nextByte == DerValue.tag_UtcTime) {
+ nextUpdate = derStrm.getUTCTime();
+ } else if (nextByte == DerValue.tag_GeneralizedTime) {
+ nextUpdate = derStrm.getGeneralizedTime();
+ } // else it is not present
+
+ if (derStrm.available() == 0)
+ return; // done parsing no more optional fields present
+
+ // revokedCertificates (optional)
+ nextByte = (byte) derStrm.peekByte();
+ if ((nextByte == DerValue.tag_SequenceOf)
+ && (!((nextByte & 0x0c0) == 0x080))) {
+ if (includeEntries) {
+ DerValue[] badCerts = derStrm.getSequence(4);
+ for (int i = 0; i < badCerts.length; i++) {
+ RevokedCertImpl entry = new RevokedCertImpl(badCerts[i]);
+ if (entry.hasExtensions() && (version == 0))
+ throw new CRLException("Invalid encoding, extensions" +
+ " not supported in CRL v1 entries.");
+
+ revokedCerts.put(entry.getSerialNumber(),
+ (RevokedCertificate) entry);
+ }
+ } else {
+ derStrm.skipSequence(4);
+ }
+ }
+
+ if (derStrm.available() == 0)
+ return; // done parsing no extensions
+
+ // crlExtensions (optional)
+ tmp = derStrm.getDerValue();
+ if (tmp.isConstructed() && tmp.isContextSpecific((byte) 0)) {
+ if (version == 0)
+ throw new CRLException("Invalid encoding, extensions not" +
+ " supported in CRL v1.");
+ extensions = new CRLExtensions(tmp.data);
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/x509/X509Cert.java b/base/util/src/netscape/security/x509/X509Cert.java
new file mode 100644
index 000000000..9ab7ba754
--- /dev/null
+++ b/base/util/src/netscape/security/x509/X509Cert.java
@@ -0,0 +1,849 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.security.Certificate;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.util.Date;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * @author David Brownell
+ * @version 1.5
+ *
+ * @see CertAndKeyGen
+ * @deprecated Use the new X509Certificate class.
+ * This class is only restored for backwards compatibility.
+ */
+public class X509Cert implements Certificate, Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6968141532738786900L;
+ /* The algorithm id */
+ protected AlgorithmId algid;
+
+ /**
+ * Construct a uninitialized X509 Cert on which <a href="#decode">
+ * decode</a> must later be called (or which may be deserialized).
+ */
+ // XXX deprecated, delete this
+ public X509Cert() {
+ }
+
+ /**
+ * Unmarshals a certificate from its encoded form, parsing the
+ * encoded bytes. This form of constructor is used by agents which
+ * need to examine and use certificate contents. That is, this is
+ * one of the more commonly used constructors. Note that the buffer
+ * must include only a certificate, and no "garbage" may be left at
+ * the end. If you need to ignore data at the end of a certificate,
+ * use another constructor.
+ *
+ * @param cert the encoded bytes, with no terminatu (CONSUMED)
+ * @exception IOException when the certificate is improperly encoded.
+ */
+ public X509Cert(
+ byte cert[]) throws IOException {
+ DerValue in = new DerValue(cert);
+
+ parse(in);
+ if (in.data.available() != 0)
+ throw new CertParseError("garbage at end");
+ signedCert = cert;
+ }
+
+ /**
+ * Unmarshals a certificate from its encoded form, parsing the
+ * encoded bytes. This form of constructor is used by agents which
+ * need to examine and use certificate contents. That is, this is
+ * one of the most commonly used constructors.
+ *
+ * @param buf the buffer holding the encoded bytes
+ * @param offset the offset in the buffer where the bytes begin
+ * @param len how many bytes of certificate exist
+ *
+ * @exception IOException when the certificate is improperly encoded.
+ */
+ public X509Cert(
+ byte buf[],
+ int offset,
+ int len) throws IOException {
+ DerValue in = new DerValue(buf, offset, len);
+
+ parse(in);
+ if (in.data.available() != 0)
+ throw new CertParseError("garbage at end");
+ signedCert = new byte[len];
+ System.arraycopy(buf, offset, signedCert, 0, len);
+ }
+
+ /**
+ * Unmarshal a certificate from its encoded form, parsing a DER value.
+ * This form of constructor is used by agents which need to examine
+ * and use certificate contents.
+ *
+ * @param derVal the der value containing the encoded cert.
+ * @exception IOException when the certificate is improperly encoded.
+ */
+ public X509Cert(DerValue derVal) throws IOException {
+ parse(derVal);
+ if (derVal.data.available() != 0)
+ throw new CertParseError("garbage at end");
+ signedCert = derVal.toByteArray();
+ }
+
+ /**
+ * Partially constructs a certificate from descriptive parameters.
+ * This constructor may be used by Certificate Authority (CA) code,
+ * which later <a href="#signAndEncode">signs and encodes</a> the
+ * certificate. Also, self-signed certificates serve as CA certificates,
+ * and are sometimes used as certificate requests.
+ *
+ * <P>
+ * Until the certificate has been signed and encoded, some of the mandatory fields in the certificate will not be
+ * available via accessor functions: the serial number, issuer name and signing algorithm, and of course the signed
+ * certificate. The fields passed to this constructor are available, and must be non-null.
+ *
+ * <P>
+ * Note that the public key being signed is generally independent of the signature algorithm being used. So for
+ * example Diffie-Hellman keys (which do not support signatures) can be placed in X.509 certificates when some other
+ * signature algorithm (e.g. DSS/DSA, or one of the RSA based algorithms) is used.
+ *
+ * @see CertAndKeyGen
+ *
+ * @param subjectName the X.500 distinguished name being certified
+ * @param subjectPublicKey the public key being certified. This
+ * must be an "X509Key" implementing the "PublicKey" interface.
+ * @param notBefore the first time the certificate is valid
+ * @param notAfter the last time the certificate is valid
+ *
+ * @exception CertException if the public key is inappropriate
+ */
+ public X509Cert(
+ X500Name subjectName,
+ X509Key subjectPublicKey,
+ Date notBefore,
+ Date notAfter) throws CertException {
+ subject = subjectName;
+
+ if (!(subjectPublicKey instanceof PublicKey))
+ throw new CertException(CertException.err_INVALID_PUBLIC_KEY,
+ "Doesn't implement PublicKey interface");
+
+ /*
+ * The X509 cert API requires X509 keys, else things break.
+ */
+ pubkey = subjectPublicKey;
+ notbefore = notBefore;
+ notafter = notAfter;
+ version = 0;
+ }
+
+ /**
+ * Decode an X.509 certificate from an input stream.
+ *
+ * @param in an input stream holding at least one certificate
+ * @exception IOException when the certificate is improperly encoded.
+ */
+ public void decode(InputStream in) throws IOException {
+ DerValue val = new DerValue(in);
+
+ parse(val);
+ if (val.data.available() != 0)
+ throw new CertParseError("garbage at end");
+ signedCert = val.toByteArray();
+ }
+
+ /**
+ * Appends the certificate to an output stream.
+ *
+ * @param out an input stream to which the certificate is appended.
+ * @exception IOException when appending fails.
+ */
+ public void encode(OutputStream out) throws IOException {
+ out.write(getSignedCert());
+ }
+
+ /**
+ * Compares two certificates. This is false if the
+ * certificates are not both X.509 certs, otherwise it
+ * compares them as binary data.
+ *
+ * @param other the object being compared with this one
+ * @return true iff the certificates are equivalent
+ */
+ public boolean equals(Object other) {
+ if (other instanceof X509Cert)
+ return equals((X509Cert) other);
+ else
+ return false;
+ }
+
+ /**
+ * Compares two certificates, returning false if any data
+ * differs between the two.
+ *
+ * @param other the object being compared with this one
+ * @return true iff the certificates are equivalent
+ */
+ public boolean equals(X509Cert src) {
+ if (this == src)
+ return true;
+ if (signedCert == null || src.signedCert == null)
+ return false;
+ if (signedCert.length != src.signedCert.length)
+ return false;
+ for (int i = 0; i < signedCert.length; i++)
+ if (signedCert[i] != src.signedCert[i])
+ return false;
+ return true;
+ }
+
+ /** Returns the "X.509" format identifier. */
+ public String getFormat() // for Certificate
+ {
+ return "X.509";
+ }
+
+ /** Returns <a href="#getIssuerName">getIssuerName</a> */
+ public Principal getGuarantor() // for Certificate
+ {
+ return getIssuerName();
+ }
+
+ /** Returns <a href="#getSubjectName">getSubjectName</a> */
+ public Principal getPrincipal() {
+ return getSubjectName();
+ }
+
+ /**
+ * Throws an exception if the certificate is invalid because it is
+ * now outside of the certificate's validity period, or because it
+ * was not signed using the verification key provided. Successfully
+ * verifying a certificate does <em>not</em> indicate that one should
+ * trust the entity which it represents.
+ *
+ * <P>
+ * <em>Note that since this class represents only a single X.509
+ * certificate, it cannot know anything about the certificate chain
+ * which is used to provide the verification key and to establish trust.
+ * Other code must manage and use those cert chains.
+ *
+ * <P>For now, you must walk the cert chain being used to verify any
+ * given cert. Start at the root, which is a self-signed certificate;
+ * verify it using the key inside the certificate. Then use that to
+ * verify the next certificate in the chain, issued by that CA. In
+ * this manner, verify each certificate until you reach the particular
+ * certificate you wish to verify. You should not use a certificate
+ * if any of the verification operations for its certificate chain
+ * were unsuccessful.
+ * </em>
+ *
+ * @param issuerPublicKey the public key of the issuing CA
+ * @exception CertException when the certificate is not valid.
+ */
+ public void verify(PublicKey issuerPublicKey)
+ throws CertException {
+ Date now = new Date();
+
+ if (now.before(notbefore))
+ throw new CertException(CertException.verf_INVALID_NOTBEFORE);
+ if (now.after(notafter))
+ throw new CertException(CertException.verf_INVALID_EXPIRED);
+ if (signedCert == null)
+ throw new CertException(CertException.verf_INVALID_SIG,
+ "?? certificate is not signed yet ??");
+
+ //
+ // Verify the signature ...
+ //
+ String algName = null;
+
+ try {
+ Signature sigVerf = null;
+
+ algName = issuerSigAlg.getName();
+ sigVerf = Signature.getInstance(algName);
+ sigVerf.initVerify(issuerPublicKey);
+ sigVerf.update(rawCert, 0, rawCert.length);
+
+ if (!sigVerf.verify(signature)) {
+ throw new CertException(CertException.verf_INVALID_SIG,
+ "Signature ... by <" + issuer + "> for <" + subject + ">");
+ }
+
+ // Gag -- too many catch clauses, let most through.
+
+ } catch (NoSuchAlgorithmException e) {
+ throw new CertException(CertException.verf_INVALID_SIG,
+ "Unsupported signature algorithm (" + algName + ")");
+
+ } catch (InvalidKeyException e) {
+ // e.printStackTrace();
+ throw new CertException(CertException.err_INVALID_PUBLIC_KEY,
+ "Algorithm (" + algName + ") rejected public key");
+
+ } catch (SignatureException e) {
+ throw new CertException(CertException.verf_INVALID_SIG,
+ "Signature by <" + issuer + "> for <" + subject + ">");
+ }
+ }
+
+ /**
+ * Creates an X.509 certificate, and signs it using the issuer
+ * passed (associating a signature algorithm and an X.500 name).
+ * This operation is used to implement the certificate generation
+ * functionality of a certificate authority.
+ *
+ * @see #getSignedCert
+ * @see #getSigner
+ * @see CertAndKeyGen
+ *
+ * @param serial the serial number of the certificate (non-null)
+ * @param issuer the certificate issuer (CA) (non-null)
+ * @return the signed certificate, as returned by getSignedCert
+ *
+ * @exception IOException if any of the data could not be encoded,
+ * or when any mandatory data was omitted
+ * @exception SignatureException on signing failures
+ */
+ public byte[]
+ encodeAndSign(
+ BigInt serial,
+ X500Signer issuer
+ ) throws IOException, SignatureException {
+ rawCert = null;
+
+ /*
+ * Get the remaining cert parameters, and make sure we have enough.
+ *
+ * We deduce version based on what attribute data are available
+ * For now, we have no attributes, so we always deduce X.509v1 !
+ */
+ version = 0;
+ serialnum = serial;
+ this.issuer = issuer.getSigner();
+ issuerSigAlg = issuer.getAlgorithmId();
+
+ if (subject == null || pubkey == null
+ || notbefore == null || notafter == null)
+ throw new IOException("not enough cert parameters");
+
+ /*
+ * Encode the raw cert, create its signature and put it
+ * into the envelope.
+ */
+ rawCert = DERencode();
+ signedCert = sign(issuer, rawCert);
+ return signedCert;
+ }
+
+ /**
+ * Returns an X500Signer that may be used to create signatures. Those
+ * signature may in turn be verified using this certificate (or a
+ * copy of it).
+ *
+ * <P>
+ * <em><b>NOTE:</b> If the private key is by itself capable of
+ * creating signatures, this fact may not be recognized at this time.
+ * Specifically, the case of DSS/DSA keys which get their algorithm
+ * parameters from higher in the certificate chain is not supportable
+ * without using an X509CertChain API, and there is no current support
+ * for other sources of algorithm parameters.</em>
+ *
+ * @param algorithm the signature algorithm to be used. Note that a
+ * given public/private key pair may support several such algorithms.
+ * @param privateKey the private key used to create the signature,
+ * which must correspond to the public key in this certificate
+ * @return the Signer object
+ *
+ * @exception NoSuchAlgorithmException if the signature
+ * algorithm is not supported
+ * @exception InvalidKeyException if either the key in the certificate,
+ * or the private key parameter, does not support the requested
+ * signature algorithm
+ */
+ public X500Signer getSigner(AlgorithmId algorithmId,
+ PrivateKey privateKey)
+ throws NoSuchAlgorithmException, InvalidKeyException {
+ String algorithm;
+ Signature sig;
+
+ if (privateKey instanceof Key) {
+ Key key = (Key) privateKey;
+ algorithm = key.getAlgorithm();
+ } else {
+ throw new InvalidKeyException("private key not a key!");
+ }
+
+ sig = Signature.getInstance(algorithmId.getName());
+
+ if (!pubkey.getAlgorithm().equals(algorithm)) {
+
+ throw new InvalidKeyException("Private key algorithm " +
+ algorithm +
+ " incompatible with certificate " +
+ pubkey.getAlgorithm());
+ }
+ sig.initSign(privateKey);
+ return new X500Signer(sig, subject);
+ }
+
+ /**
+ * Returns a signature object that may be used to verify signatures
+ * created using a specified signature algorithm and the public key
+ * contained in this certificate.
+ *
+ * <P>
+ * <em><b>NOTE:</b> If the public key in this certificate is not by
+ * itself capable of verifying signatures, this may not be recognized
+ * at this time. Specifically, the case of DSS/DSA keys which get
+ * their algorithm parameters from higher in the certificate chain
+ * is not supportable without using an X509CertChain API, and there
+ * is no current support for other sources of algorithm parameters.</em>
+ *
+ * @param algorithm the algorithm of the signature to be verified
+ * @return the Signature object
+ * @exception NoSuchAlgorithmException if the signature
+ * algorithm is not supported
+ * @exception InvalidKeyException if the key in the certificate
+ * does not support the requested signature algorithm
+ */
+ public Signature getVerifier(String algorithm)
+ throws NoSuchAlgorithmException, InvalidKeyException {
+ Signature sig;
+
+ sig = Signature.getInstance(algorithm);
+ sig.initVerify(pubkey);
+ return sig;
+ }
+
+ /**
+ * Return the signed X.509 certificate as a byte array.
+ * The bytes are in standard DER marshaled form.
+ * Null is returned in the case of a partially constructed cert.
+ */
+ public byte[] getSignedCert() {
+ return signedCert;
+ }
+
+ /**
+ * Returns the certificate's serial number.
+ * Null is returned in the case of a partially constructed cert.
+ */
+ public BigInt getSerialNumber() {
+ return serialnum;
+ }
+
+ /**
+ * Returns the subject's X.500 distinguished name.
+ */
+ public X500Name getSubjectName() {
+ return subject;
+ }
+
+ /**
+ * Returns the certificate issuer's X.500 distinguished name.
+ * Null is returned in the case of a partially constructed cert.
+ */
+ public X500Name getIssuerName() {
+ return issuer;
+ }
+
+ /**
+ * Returns the algorithm used by the issuer to sign the certificate.
+ * Null is returned in the case of a partially constructed cert.
+ */
+ public AlgorithmId getIssuerAlgorithmId() {
+ return issuerSigAlg;
+ }
+
+ /**
+ * Returns the first time the certificate is valid.
+ */
+ public Date getNotBefore() {
+ return notbefore;
+ }
+
+ /**
+ * Returns the last time the certificate is valid.
+ */
+ public Date getNotAfter() {
+ return notafter;
+ }
+
+ /**
+ * Returns the subject's public key. Note that some public key
+ * algorithms support an optional certificate generation policy
+ * where the keys in the certificates are not in themselves sufficient
+ * to perform a public key operation. Those keys need to be augmented
+ * by algorithm parameters, which the certificate generation policy
+ * chose not to place in the certificate.
+ *
+ * <P>
+ * Two such public key algorithms are: DSS/DSA, where algorithm parameters could be acquired from a CA certificate
+ * in the chain of issuers; and Diffie-Hellman, with a similar solution although the CA then needs both a
+ * Diffie-Hellman certificate and a signature capable certificate.
+ */
+ public PublicKey getPublicKey() {
+ return pubkey;
+ }
+
+ /**
+ * Returns the X.509 version number of this certificate, zero based.
+ * That is, "2" indicates an X.509 version 3 (1993) certificate,
+ * and "0" indicates X.509v1 (1988).
+ * Zero is returned in the case of a partially constructed cert.
+ */
+ public int getVersion() {
+ return version;
+ }
+
+ /**
+ * Calculates a hash code value for the object. Objects
+ * which are equal will also have the same hashcode.
+ */
+ public int hashCode() {
+ int retval = 0;
+
+ for (int i = 0; i < signedCert.length; i++)
+ retval += signedCert[i] * i;
+ return retval;
+ }
+
+ /**
+ * Returns a printable representation of the certificate. This does not
+ * contain all the information available to distinguish this from any
+ * other certificate. The certificate must be fully constructed
+ * before this function may be called; in particular, if you are
+ * creating certificates you must call encodeAndSign() before calling
+ * this function.
+ */
+ public String toString() {
+ String s;
+
+ if (subject == null || pubkey == null
+ || notbefore == null || notafter == null
+ || issuer == null || issuerSigAlg == null
+ || serialnum == null)
+ throw new NullPointerException("X.509 cert is incomplete");
+
+ s = " X.509v" + (version + 1) + " certificate,\n";
+ s += " Subject is " + subject + "\n";
+ s += " Key: " + pubkey;
+ s += " Validity <" + notbefore + "> until <" + notafter + ">\n";
+ s += " Issuer is " + issuer + "\n";
+ s += " Issuer signature used " + issuerSigAlg.toString() + "\n";
+ s += " Serial number = " + serialnum + "\n";
+
+ // optional v2, v3 extras
+
+ return "[\n" + s + "]";
+ }
+
+ /**
+ * Returns a printable representation of the certificate.
+ *
+ * @param detailed true iff lots of detail is requested
+ */
+ public String toString(boolean detailed) {
+ return toString();
+ }
+
+ /*
+ * Certificate data, and its envelope
+ */
+ private byte rawCert[];
+ private byte signature[];
+ private byte signedCert[];
+
+ /*
+ * X509.v1 data (parsed)
+ */
+ private X500Name subject; // from subject
+ private X509Key pubkey;
+
+ private Date notafter; // from CA (constructor)
+ private Date notbefore;
+
+ private int version; // from CA (signAndEncode)
+ private BigInt serialnum;
+ private X500Name issuer;
+ private AlgorithmId issuerSigAlg;
+
+ /*
+ * X509.v2 extensions
+ */
+
+ /*
+ * X509.v3 extensions
+ */
+
+ /*
+ * Other extensions ... Netscape, Verisign, SET, etc
+ */
+
+ /************************************************************/
+
+ /*
+ * Cert is a SIGNED ASN.1 macro, a three elment sequence:
+ *
+ * - Data to be signed (ToBeSigned) -- the "raw" cert
+ * - Signature algorithm (SigAlgId)
+ * - The signature bits
+ *
+ * This routine unmarshals the certificate, saving the signature
+ * parts away for later verification.
+ */
+ private void parse(DerValue val)
+ throws IOException {
+ DerValue seq[] = new DerValue[3];
+
+ seq[0] = val.data.getDerValue();
+ seq[1] = val.data.getDerValue();
+ seq[2] = val.data.getDerValue();
+
+ if (val.data.available() != 0)
+ throw new CertParseError("signed overrun, bytes = "
+ + val.data.available());
+ if (seq[0].tag != DerValue.tag_Sequence)
+ throw new CertParseError("signed fields invalid");
+
+ rawCert = seq[0].toByteArray(); // XXX slow; fixme!
+
+ issuerSigAlg = AlgorithmId.parse(seq[1]);
+ signature = seq[2].getBitString();
+
+ if (seq[1].data.available() != 0) {
+ // XXX why was this error check commented out?
+ // It was originally part of the next check.
+ throw new CertParseError("algid field overrun");
+ }
+
+ if (seq[2].data.available() != 0)
+ throw new CertParseError("signed fields overrun");
+
+ /*
+ * Let's have fun parsing the cert itself.
+ */
+ DerInputStream in;
+ DerValue tmp;
+
+ in = seq[0].data;
+
+ /*
+ * Version -- this is optional (default zero). If it's there it's
+ * the first field and is specially tagged.
+ *
+ * Both branches leave "tmp" holding a value for the serial
+ * number that comes next.
+ */
+ version = 0;
+ tmp = in.getDerValue();
+ if (tmp.isConstructed() && tmp.isContextSpecific()) {
+ version = tmp.data.getInteger().toInt();
+ if (tmp.data.available() != 0)
+ throw new IOException("X.509 version, bad format");
+ tmp = in.getDerValue();
+ }
+
+ /*
+ * serial number ... an integer
+ */
+ serialnum = tmp.getInteger();
+
+ /*
+ * algorithm type for CA's signature ... needs to match the
+ * one on the envelope, and that's about it! different IDs
+ * may represent a signature attack. In general we want to
+ * inherit parameters.
+ */
+ tmp = in.getDerValue();
+ {
+ AlgorithmId algid;
+
+ algid = AlgorithmId.parse(tmp);
+
+ if (!algid.equals(issuerSigAlg))
+ throw new CertParseError("CA Algorithm mismatch!");
+
+ this.algid = algid;
+ }
+
+ /*
+ * issuer name
+ */
+ issuer = new X500Name(in);
+
+ /*
+ * validity: SEQUENCE { start date, end date }
+ */
+ tmp = in.getDerValue();
+ if (tmp.tag != DerValue.tag_Sequence)
+ throw new CertParseError("corrupt validity field");
+
+ notbefore = tmp.data.getUTCTime();
+ notafter = tmp.data.getUTCTime();
+ if (tmp.data.available() != 0)
+ throw new CertParseError("excess validity data");
+
+ /*
+ * subject name and public key
+ */
+ subject = new X500Name(in);
+
+ tmp = in.getDerValue();
+ pubkey = X509Key.parse(tmp);
+
+ /*
+ * XXX for v2 and later, a bunch of tagged options follow
+ */
+
+ if (in.available() != 0) {
+ /*
+ * Until we parse V2/V3 data ... ignore it.
+ *
+ // throw new CertParseError ("excess cert data");
+ System.out.println (
+ "@end'o'cert, optional V2/V3 data unparsed: "
+ + in.available ()
+ + " bytes"
+ );
+ */
+ }
+ }
+
+ /*
+ * Encode only the parts that will later be signed.
+ */
+ private byte[] DERencode() throws IOException {
+ DerOutputStream raw = new DerOutputStream();
+
+ encode(raw);
+ return raw.toByteArray();
+ }
+
+ /*
+ * Marshal the contents of a "raw" certificate into a DER sequence.
+ */
+ private void encode(DerOutputStream out) throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ /*
+ * encode serial number, issuer signing algorithm,
+ * and issuer name into the data we'll return
+ */
+ tmp.putInteger(serialnum);
+ issuerSigAlg.encode(tmp);
+ issuer.encode(tmp);
+
+ /*
+ * Validity is a two element sequence ... encode the
+ * elements, then wrap them into the data we'll return
+ */
+ {
+ DerOutputStream seq = new DerOutputStream();
+
+ seq.putUTCTime(notbefore);
+ seq.putUTCTime(notafter);
+ tmp.write(DerValue.tag_Sequence, seq);
+ }
+
+ /*
+ * Encode subject (principal) and associated key
+ */
+ subject.encode(tmp);
+ pubkey.encode(tmp);
+
+ /*
+ * Wrap the data; encoding of the "raw" cert is now complete.
+ */
+ out.write(DerValue.tag_Sequence, tmp);
+ }
+
+ /*
+ * Calculate the signature of the "raw" certificate,
+ * and marshal the cert with the signature and a
+ * description of the signing algorithm.
+ */
+ private byte[] sign(X500Signer issuer, byte data[])
+ throws IOException, SignatureException {
+ /*
+ * Encode the to-be-signed data, then the algorithm used
+ * to create the signature.
+ */
+ DerOutputStream out = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+
+ tmp.write(data);
+ issuer.getAlgorithmId().encode(tmp);
+
+ /*
+ * Create and encode the signature itself.
+ */
+ issuer.update(data, 0, data.length);
+ signature = issuer.sign();
+ tmp.putBitString(signature);
+
+ /*
+ * Wrap the signed data in a SEQUENCE { data, algorithm, sig }
+ */
+ out.write(DerValue.tag_Sequence, tmp);
+ return out.toByteArray();
+ }
+
+ /**
+ * Serialization write ... X.509 certificates serialize as
+ * themselves, and they're parsed when they get read back.
+ * (Actually they serialize as some type data from the
+ * serialization subsystem, then the cert data.)
+ */
+ private synchronized void
+ writeObject(java.io.ObjectOutputStream stream)
+ throws IOException {
+ encode(stream);
+ }
+
+ /**
+ * Serialization read ... X.509 certificates serialize as
+ * themselves, and they're parsed when they get read back.
+ */
+ private synchronized void
+ readObject(ObjectInputStream stream)
+ throws IOException {
+ decode(stream);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/X509CertImpl.java b/base/util/src/netscape/security/x509/X509CertImpl.java
new file mode 100755
index 000000000..9c62b36a6
--- /dev/null
+++ b/base/util/src/netscape/security/x509/X509CertImpl.java
@@ -0,0 +1,1226 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.Vector;
+
+import netscape.security.util.BigInt;
+import netscape.security.util.DerEncoder;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * The X509CertImpl class represents an X.509 certificate. These certificates
+ * are widely used to support authentication and other functionality in
+ * Internet security systems. Common applications include Privacy Enhanced
+ * Mail (PEM), Transport Layer Security (SSL), code signing for trusted
+ * software distribution, and Secure Electronic Transactions (SET). There
+ * is a commercial infrastructure ready to manage large scale deployments
+ * of X.509 identity certificates.
+ *
+ * <P>
+ * These certificates are managed and vouched for by <em>Certificate
+ * Authorities</em> (CAs). CAs are services which create certificates by placing data in the X.509 standard format and
+ * then digitally signing that data. Such signatures are quite difficult to forge. CAs act as trusted third parties,
+ * making introductions between agents who have no direct knowledge of each other. CA certificates are either signed by
+ * themselves, or by some other CA such as a "root" CA.
+ *
+ * <P>
+ * RFC 1422 is very informative, though it does not describe much of the recent work being done with X.509 certificates.
+ * That includes a 1996 version (X.509v3) and a variety of enhancements being made to facilitate an explosion of
+ * personal certificates used as "Internet Drivers' Licences", or with SET for credit card transactions.
+ *
+ * <P>
+ * More recent work includes the IETF PKIX Working Group efforts, especially part 1.
+ *
+ * @author Dave Brownell
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.94 97/12/10
+ * @see X509CertInfo
+ */
+public class X509CertImpl extends X509Certificate
+ implements Serializable, DerEncoder {
+ // Serialization compatibility with the X509CertImpl in x509v1.jar
+ // supporting the subset of X509Certificate on JDK1.1.x platforms.
+ static final long serialVersionUID = -2048442350420423405L;
+
+ private static final String DOT = ".";
+ /**
+ * Public attribute names.
+ */
+ public static final String NAME = "x509";
+ public static final String INFO = X509CertInfo.NAME;
+ public static final String ALG_ID = "algorithm";
+ public static final String SIGNATURE = "signature";
+ public static final String SIGNED_CERT = "signed_cert";
+
+ /**
+ * The following are defined for ease-of-use. These
+ * are the most frequently retrieved attributes.
+ */
+ // x509.info.subject.dname
+ public static final String SUBJECT_DN = NAME + DOT + INFO + DOT +
+ X509CertInfo.SUBJECT + DOT +
+ CertificateSubjectName.DN_NAME;
+ // x509.info.issuer.dname
+ public static final String ISSUER_DN = NAME + DOT + INFO + DOT +
+ X509CertInfo.ISSUER + DOT +
+ CertificateIssuerName.DN_NAME;
+ // x509.info.serialNumber.number
+ public static final String SERIAL_ID = NAME + DOT + INFO + DOT +
+ X509CertInfo.SERIAL_NUMBER + DOT +
+ CertificateSerialNumber.NUMBER;
+ // x509.info.key.value
+ public static final String PUBLIC_KEY = NAME + DOT + INFO + DOT +
+ X509CertInfo.KEY + DOT +
+ CertificateX509Key.KEY;
+
+ // x509.algorithm
+ public static final String SIG_ALG = NAME + DOT + ALG_ID;
+
+ // x509.signature
+ public static final String SIG = NAME + DOT + SIGNATURE;
+
+ // when we sign and decode we set this to true
+ // this is our means to make certificates immutable
+ private boolean readOnly = false;
+
+ // Certificate data, and its envelope
+ private byte[] signedCert;
+ protected X509CertInfo info = null;
+ protected AlgorithmId algId;
+ protected byte[] signature;
+
+ // recognized extension OIDS
+ private static final String KEY_USAGE_OID = "2.5.29.15";
+ private static final String BASIC_CONSTRAINT_OID = "2.5.29.19";
+
+ /**
+ * Default constructor.
+ */
+ public X509CertImpl() {
+ }
+
+ /**
+ * Unmarshals a certificate from its encoded form, parsing the
+ * encoded bytes. This form of constructor is used by agents which
+ * need to examine and use certificate contents. That is, this is
+ * one of the more commonly used constructors. Note that the buffer
+ * must include only a certificate, and no "garbage" may be left at
+ * the end. If you need to ignore data at the end of a certificate,
+ * use another constructor.
+ *
+ * @param certData the encoded bytes, with no trailing padding.
+ * @exception CertificateException on parsing and initialization errors.
+ */
+ public X509CertImpl(byte[] certData)
+ throws CertificateException {
+ this(certData, null);
+ }
+
+ /**
+ * As a special optimization, this constructor acts as X509CertImpl(byte[])
+ * except that it takes an X509CertInfo which it uses as a 'hint' for
+ * how to construct one field.
+ *
+ * @param certData the encode bytes, with no traiing padding
+ * @param certInfo the certInfo which has already been constructed
+ * from the certData
+ */
+
+ public X509CertImpl(byte[] certData, X509CertInfo certInfo)
+ throws CertificateException {
+
+ // setting info here causes it to skip decoding in the parse()
+ // method
+ info = certInfo;
+
+ try {
+ DerValue in = new DerValue(certData);
+
+ parse(in);
+ signedCert = certData;
+ } catch (IOException e) {
+ throw new CertificateException("Unable to initialize, " + e);
+ }
+ }
+
+ /**
+ * unmarshals an X.509 certificate from an input stream.
+ *
+ * @param in an input stream holding at least one certificate
+ * @exception CertificateException on parsing and initialization errors.
+ */
+ public X509CertImpl(InputStream in)
+ throws CertificateException {
+ try {
+ DerValue val = new DerValue(in);
+
+ parse(val);
+ signedCert = val.toByteArray();
+ } catch (IOException e) {
+ throw new CertificateException("Unable to initialize, " + e);
+ }
+ }
+
+ /**
+ * Construct an initialized X509 Certificate. The certificate is stored
+ * in raw form and has to be signed to be useful.
+ *
+ * @param certInfo the X509CertificateInfo which the Certificate is to be
+ * created from.
+ */
+ public X509CertImpl(X509CertInfo certInfo) {
+ this.info = certInfo;
+ }
+
+ /**
+ * Unmarshal a certificate from its encoded form, parsing a DER value.
+ * This form of constructor is used by agents which need to examine
+ * and use certificate contents.
+ *
+ * @param derVal the der value containing the encoded cert.
+ * @exception CertificateException on parsing and initialization errors.
+ */
+ public X509CertImpl(DerValue derVal)
+ throws CertificateException {
+ try {
+ parse(derVal);
+ signedCert = derVal.toByteArray();
+ } catch (IOException e) {
+ throw new CertificateException("Unable to initialize, " + e);
+ }
+ }
+
+ public boolean hasUnsupportedCriticalExtension() {
+ // XXX NOT IMPLEMENTED
+ return true;
+ }
+
+ /**
+ * Decode an X.509 certificate from an input stream.
+ *
+ * @param in an input stream holding at least one certificate
+ * @exception CertificateException on parsing errors.
+ * @exception IOException on other errors.
+ */
+ public void decode(InputStream in)
+ throws CertificateException, IOException {
+ DerValue val = new DerValue(in);
+
+ parse(val);
+ signedCert = val.toByteArray();
+ }
+
+ /**
+ * Appends the certificate to an output stream.
+ *
+ * @param out an input stream to which the certificate is appended.
+ * @exception CertificateEncodingException on encoding errors.
+ */
+ public void encode(OutputStream out)
+ throws CertificateEncodingException {
+ if (signedCert == null)
+ throw new CertificateEncodingException(
+ "Null certificate to encode");
+ try {
+ out.write(signedCert);
+ } catch (IOException e) {
+ throw new CertificateEncodingException(e.toString());
+ }
+ }
+
+ /**
+ * DER encode this object onto an output stream.
+ * Implements the <code>DerEncoder</code> interface.
+ *
+ * @param out
+ * the output stream on which to write the DER encoding.
+ *
+ * @exception IOException on encoding error.
+ */
+ public void derEncode(OutputStream out) throws IOException {
+ if (signedCert == null)
+ throw new IOException("Null certificate to encode");
+
+ out.write(signedCert);
+ }
+
+ /**
+ * Returns the encoded form of this certificate. It is
+ * assumed that each certificate type would have only a single
+ * form of encoding; for example, X.509 certificates would
+ * be encoded as ASN.1 DER.
+ *
+ * @exception CertificateEncodingException if an encoding error occurs.
+ */
+ public byte[] getEncoded() throws CertificateEncodingException {
+ if (signedCert == null)
+ throw new CertificateEncodingException(
+ "Null certificate to encode");
+ byte[] dup = new byte[signedCert.length];
+ System.arraycopy(signedCert, 0, dup, 0, dup.length);
+ return dup;
+ }
+
+ /**
+ * Throws an exception if the certificate was not signed using the
+ * verification key provided. Successfully verifying a certificate
+ * does <em>not</em> indicate that one should trust the entity which
+ * it represents.
+ *
+ * @param key the public key used for verification.
+ *
+ * @exception InvalidKeyException on incorrect key.
+ * @exception NoSuchAlgorithmException on unsupported signature
+ * algorithms.
+ * @exception NoSuchProviderException if there's no default provider.
+ * @exception SignatureException on signature errors.
+ * @exception CertificateException on encoding errors.
+ */
+ public void verify(PublicKey key)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException {
+
+ verify(key, null);
+ }
+
+ /**
+ * Throws an exception if the certificate was not signed using the
+ * verification key provided. Successfully verifying a certificate
+ * does <em>not</em> indicate that one should trust the entity which
+ * it represents.
+ *
+ * @param key the public key used for verification.
+ * @param sigProvider the name of the provider.
+ *
+ * @exception NoSuchAlgorithmException on unsupported signature
+ * algorithms.
+ * @exception InvalidKeyException on incorrect key.
+ * @exception NoSuchProviderException on incorrect provider.
+ * @exception SignatureException on signature errors.
+ * @exception CertificateException on encoding errors.
+ */
+ public void verify(PublicKey key, String sigProvider)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException {
+ if (signedCert == null) {
+ throw new CertificateEncodingException("Uninitialized certificate");
+ }
+ // Verify the signature ...
+ Signature sigVerf = null;
+
+ sigVerf = Signature.getInstance(algId.getName(), sigProvider);
+ sigVerf.initVerify(key);
+
+ byte[] rawCert = info.getEncodedInfo();
+ sigVerf.update(rawCert, 0, rawCert.length);
+
+ if (!sigVerf.verify(signature)) {
+ throw new SignatureException("Signature does not match.");
+ }
+ }
+
+ /**
+ * Creates an X.509 certificate, and signs it using the key
+ * passed (associating a signature algorithm and an X.500 name).
+ * This operation is used to implement the certificate generation
+ * functionality of a certificate authority.
+ *
+ * @param key the private key used for signing.
+ * @param algorithm the name of the signature algorithm used.
+ *
+ * @exception InvalidKeyException on incorrect key.
+ * @exception NoSuchAlgorithmException on unsupported signature
+ * algorithms.
+ * @exception NoSuchProviderException if there's no default provider.
+ * @exception SignatureException on signature errors.
+ * @exception CertificateException on encoding errors.
+ */
+ public void sign(PrivateKey key, String algorithm)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException {
+ sign(key, algorithm, null);
+ }
+
+ /**
+ * Creates an X.509 certificate, and signs it using the key
+ * passed (associating a signature algorithm and an X.500 name).
+ * This operation is used to implement the certificate generation
+ * functionality of a certificate authority.
+ *
+ * @param key the private key used for signing.
+ * @param algorithm the name of the signature algorithm used.
+ * @param provider the name of the provider.
+ *
+ * @exception NoSuchAlgorithmException on unsupported signature
+ * algorithms.
+ * @exception InvalidKeyException on incorrect key.
+ * @exception NoSuchProviderException on incorrect provider.
+ * @exception SignatureException on signature errors.
+ * @exception CertificateException on encoding errors.
+ */
+ public void sign(PrivateKey key, String algorithm, String provider)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException {
+ try {
+ if (readOnly)
+ throw new CertificateEncodingException(
+ "cannot over-write existing certificate");
+ Signature sigEngine = null;
+ if (provider == null)
+ sigEngine = Signature.getInstance(algorithm);
+ else
+ sigEngine = Signature.getInstance(algorithm, provider);
+
+ sigEngine.initSign(key);
+
+ // in case the name is reset
+ algId = AlgorithmId.get(sigEngine.getAlgorithm());
+
+ DerOutputStream out = new DerOutputStream();
+ DerOutputStream tmp = new DerOutputStream();
+
+ // encode certificate info
+ info.encode(tmp);
+ byte[] rawCert = tmp.toByteArray();
+
+ // encode algorithm identifier
+ algId.encode(tmp);
+
+ // Create and encode the signature itself.
+ sigEngine.update(rawCert, 0, rawCert.length);
+ signature = sigEngine.sign();
+ tmp.putBitString(signature);
+
+ // Wrap the signed data in a SEQUENCE { data, algorithm, sig }
+ out.write(DerValue.tag_Sequence, tmp);
+ signedCert = out.toByteArray();
+ readOnly = true;
+
+ } catch (IOException e) {
+ throw new CertificateEncodingException(e.toString());
+ }
+ }
+
+ /**
+ * Checks that the certificate is currently valid, i.e. the current
+ * time is within the specified validity period.
+ *
+ * @exception CertificateExpiredException if the certificate has expired.
+ * @exception CertificateNotYetValidException if the certificate is not
+ * yet valid.
+ */
+ public void checkValidity()
+ throws CertificateExpiredException, CertificateNotYetValidException {
+ Date date = new Date();
+ checkValidity(date);
+ }
+
+ /**
+ * Checks that the specified date is within the certificate's
+ * validity period, or basically if the certificate would be
+ * valid at the specified date/time.
+ *
+ * @param date the Date to check against to see if this certificate
+ * is valid at that date/time.
+ *
+ * @exception CertificateExpiredException if the certificate has expired
+ * with respect to the <code>date</code> supplied.
+ * @exception CertificateNotYetValidException if the certificate is not
+ * yet valid with respect to the <code>date</code> supplied.
+ */
+ public void checkValidity(Date date)
+ throws CertificateExpiredException, CertificateNotYetValidException {
+
+ CertificateValidity interval = null;
+ try {
+ interval = (CertificateValidity) info.get(CertificateValidity.NAME);
+ } catch (Exception e) {
+ throw new CertificateNotYetValidException("Incorrect validity period");
+ }
+ if (interval == null)
+ throw new CertificateNotYetValidException("Null validity period");
+ interval.valid(date);
+ }
+
+ /**
+ * Return the requested attribute from the certificate.
+ *
+ * @param name the name of the attribute.
+ * @exception CertificateParsingException on invalid attribute identifier.
+ */
+ public Object get(String name)
+ throws CertificateParsingException {
+ X509AttributeName attr = new X509AttributeName(name);
+ String id = attr.getPrefix();
+ if (!(id.equalsIgnoreCase(NAME))) {
+ throw new CertificateParsingException("Invalid root of "
+ + "attribute name, expected [" + NAME +
+ "], received " + "[" + id + "]");
+ }
+ attr = new X509AttributeName(attr.getSuffix());
+ id = attr.getPrefix();
+
+ if (id.equalsIgnoreCase(INFO)) {
+ if (attr.getSuffix() != null) {
+ try {
+ return info.get(attr.getSuffix());
+ } catch (IOException e) {
+ throw new CertificateParsingException(e.toString());
+ } catch (CertificateException e) {
+ throw new CertificateParsingException(e.toString());
+ }
+ } else {
+ return (info);
+ }
+ } else if (id.equalsIgnoreCase(ALG_ID)) {
+ return (algId);
+ } else if (id.equalsIgnoreCase(SIGNATURE)) {
+ return (signature);
+ } else if (id.equalsIgnoreCase(SIGNED_CERT)) {
+ return (signedCert);
+ } else {
+ throw new CertificateParsingException("Attribute name not "
+ + "recognized or get() not allowed for the same: " + id);
+ }
+ }
+
+ /**
+ * Set the requested attribute in the certificate.
+ *
+ * @param name the name of the attribute.
+ * @param obj the value of the attribute.
+ * @exception CertificateException on invalid attribute identifier.
+ * @exception IOException on encoding error of attribute.
+ */
+ public void set(String name, Object obj)
+ throws CertificateException, IOException {
+ // check if immutable
+ if (readOnly)
+ throw new CertificateException("cannot over-write existing"
+ + " certificate");
+
+ X509AttributeName attr = new X509AttributeName(name);
+ String id = attr.getPrefix();
+ if (!(id.equalsIgnoreCase(NAME))) {
+ throw new CertificateException("Invalid root of attribute name,"
+ + " expected [" + NAME + "], received " + id);
+ }
+ attr = new X509AttributeName(attr.getSuffix());
+ id = attr.getPrefix();
+
+ if (id.equalsIgnoreCase(INFO)) {
+ if (attr.getSuffix() == null) {
+ if (!(obj instanceof X509CertInfo)) {
+ throw new CertificateException("Attribute value should"
+ + " be of type X509CertInfo.");
+ }
+ info = (X509CertInfo) obj;
+ signedCert = null; //reset this as certificate data has changed
+ } else {
+ info.set(attr.getSuffix(), obj);
+ signedCert = null; //reset this as certificate data has changed
+ }
+ } else {
+ throw new CertificateException("Attribute name not recognized or " +
+ "set() not allowed for the same: " + id);
+ }
+ }
+
+ /**
+ * Delete the requested attribute from the certificate.
+ *
+ * @param name the name of the attribute.
+ * @exception CertificateException on invalid attribute identifier.
+ * @exception IOException on other errors.
+ */
+ public void delete(String name)
+ throws CertificateException, IOException {
+ // check if immutable
+ if (readOnly)
+ throw new CertificateException("cannot over-write existing"
+ + " certificate");
+
+ X509AttributeName attr = new X509AttributeName(name);
+ String id = attr.getPrefix();
+ if (!(id.equalsIgnoreCase(NAME))) {
+ throw new CertificateException("Invalid root of attribute name,"
+ + " expected ["
+ + NAME + "], received " + id);
+ }
+ attr = new X509AttributeName(attr.getSuffix());
+ id = attr.getPrefix();
+
+ if (id.equalsIgnoreCase(INFO)) {
+ if (attr.getSuffix() != null) {
+ info = null;
+ } else {
+ info.delete(attr.getSuffix());
+ }
+ } else if (id.equalsIgnoreCase(ALG_ID)) {
+ algId = null;
+ } else if (id.equalsIgnoreCase(SIGNATURE)) {
+ signature = null;
+ } else if (id.equalsIgnoreCase(SIGNED_CERT)) {
+ signedCert = null;
+ } else {
+ throw new CertificateException("Attribute name not recognized or " +
+ "delete() not allowed for the same: " + id);
+ }
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getElements() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(NAME + DOT + INFO);
+ elements.addElement(NAME + DOT + ALG_ID);
+ elements.addElement(NAME + DOT + SIGNATURE);
+ elements.addElement(NAME + DOT + SIGNED_CERT);
+
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+
+ /**
+ * Returns a printable representation of the certificate. This does not
+ * contain all the information available to distinguish this from any
+ * other certificate. The certificate must be fully constructed
+ * before this function may be called.
+ */
+ public String toString() {
+ if (info == null || algId == null || signature == null)
+ return "";
+
+ StringBuffer sb = new StringBuffer();
+
+ sb.append("[\n");
+ sb.append(info.toString() + "\n");
+ sb.append(" Algorithm: [" + algId.toString() + "]\n");
+
+ netscape.security.util.PrettyPrintFormat pp =
+ new netscape.security.util.PrettyPrintFormat(" ", 20);
+ String signaturebits = pp.toHexString(signature);
+ sb.append(" Signature:\n" + signaturebits);
+ sb.append("]");
+
+ return sb.toString();
+ }
+
+ // the strongly typed gets, as per java.security.cert.X509Certificate
+
+ /**
+ * Gets the publickey from this certificate.
+ *
+ * @return the publickey.
+ */
+ public PublicKey getPublicKey() {
+ if (info == null)
+ return null;
+ try {
+ PublicKey key = (PublicKey) info.get(CertificateX509Key.NAME
+ + DOT + CertificateX509Key.KEY);
+ return key;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Gets the version number from the certificate.
+ *
+ * @return the version number.
+ */
+ public int getVersion() {
+ if (info == null)
+ return -1;
+ try {
+ int vers = ((Integer) info.get(CertificateVersion.NAME
+ + DOT + CertificateVersion.VERSION)).intValue();
+ return vers;
+ } catch (Exception e) {
+ return -1;
+ }
+ }
+
+ /**
+ * Gets the serial number from the certificate.
+ *
+ * @return the serial number.
+ */
+ public BigInteger getSerialNumber() {
+ if (info == null)
+ return null;
+ try {
+ SerialNumber ser = (SerialNumber) info.get(
+ CertificateSerialNumber.NAME + DOT +
+ CertificateSerialNumber.NUMBER);
+ return ((BigInt) ser.getNumber()).toBigInteger();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Gets the subject distinguished name from the certificate.
+ *
+ * @return the subject name.
+ */
+ public Principal getSubjectDN() {
+ if (info == null)
+ return null;
+ try {
+ Principal subject = (Principal) info.get(
+ CertificateSubjectName.NAME + DOT +
+ CertificateSubjectName.DN_NAME);
+ return subject;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Gets the issuer distinguished name from the certificate.
+ *
+ * @return the issuer name.
+ */
+ public Principal getIssuerDN() {
+ if (info == null)
+ return null;
+ try {
+ Principal issuer = (Principal) info.get(
+ CertificateIssuerName.NAME + DOT +
+ CertificateIssuerName.DN_NAME);
+ return issuer;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Gets the notBefore date from the validity period of the certificate.
+ *
+ * @return the start date of the validity period.
+ */
+ public Date getNotBefore() {
+ if (info == null)
+ return null;
+ try {
+ Date d = (Date) info.get(CertificateValidity.NAME + DOT +
+ CertificateValidity.NOT_BEFORE);
+ return d;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Gets the notAfter date from the validity period of the certificate.
+ *
+ * @return the end date of the validity period.
+ */
+ public Date getNotAfter() {
+ if (info == null)
+ return null;
+ try {
+ Date d = (Date) info.get(CertificateValidity.NAME + DOT +
+ CertificateValidity.NOT_AFTER);
+ return d;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Gets the DER encoded certificate informations, the <code>tbsCertificate</code> from this certificate.
+ * This can be used to verify the signature independently.
+ *
+ * @return the DER encoded certificate information.
+ * @exception CertificateEncodingException if an encoding error occurs.
+ */
+ public byte[] getTBSCertificate() throws CertificateEncodingException {
+ if (info != null) {
+ return info.getEncodedInfo();
+ } else
+ throw new CertificateEncodingException("Uninitialized certificate");
+ }
+
+ /**
+ * Gets the raw Signature bits from the certificate.
+ *
+ * @return the signature.
+ */
+ public byte[] getSignature() {
+ if (signature == null)
+ return null;
+ byte[] dup = new byte[signature.length];
+ System.arraycopy(signature, 0, dup, 0, dup.length);
+ return dup;
+ }
+
+ /**
+ * Gets the signature algorithm name for the certificate
+ * signature algorithm.
+ * For example, the string "SHA-1/DSA" or "DSS".
+ *
+ * @return the signature algorithm name.
+ */
+ public String getSigAlgName() {
+ if (algId == null)
+ return null;
+ return (algId.getName());
+ }
+
+ /**
+ * Gets the signature algorithm OID string from the certificate.
+ * For example, the string "1.2.840.10040.4.3"
+ *
+ * @return the signature algorithm oid string.
+ */
+ public String getSigAlgOID() {
+ if (algId == null)
+ return null;
+ ObjectIdentifier oid = algId.getOID();
+ return (oid.toString());
+ }
+
+ /**
+ * Gets the DER encoded signature algorithm parameters from this
+ * certificate's signature algorithm.
+ *
+ * @return the DER encoded signature algorithm parameters, or
+ * null if no parameters are present.
+ */
+ public byte[] getSigAlgParams() {
+ if (algId == null)
+ return null;
+ try {
+ return algId.getEncodedParams();
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Gets the Issuer Unique Identity from the certificate.
+ *
+ * @return the Issuer Unique Identity.
+ */
+ public boolean[] getIssuerUniqueID() {
+ if (info == null)
+ return null;
+ try {
+ UniqueIdentity id = (UniqueIdentity) info.get(
+ CertificateIssuerUniqueIdentity.NAME
+ + DOT + CertificateIssuerUniqueIdentity.ID);
+ if (id == null)
+ return null;
+ else
+ return (id.getId());
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Gets the Subject Unique Identity from the certificate.
+ *
+ * @return the Subject Unique Identity.
+ */
+ public boolean[] getSubjectUniqueID() {
+ if (info == null)
+ return null;
+ try {
+ UniqueIdentity id = (UniqueIdentity) info.get(
+ CertificateSubjectUniqueIdentity.NAME
+ + DOT + CertificateSubjectUniqueIdentity.ID);
+ if (id == null)
+ return null;
+ else
+ return (id.getId());
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Gets a Set of the extension(s) marked CRITICAL in the
+ * certificate by OID strings.
+ *
+ * @return a set of the extension oid strings in the
+ * certificate that are marked critical.
+ */
+ public Set<String> getCriticalExtensionOIDs() {
+ if (info == null)
+ return null;
+ try {
+ CertificateExtensions exts = (CertificateExtensions) info.get(
+ CertificateExtensions.NAME);
+ if (exts == null)
+ return null;
+ Set<String> extSet = new LinkedHashSet<String>();
+ Extension ex;
+ for (Enumeration<Extension> e = exts.getAttributes(); e.hasMoreElements();) {
+ ex = e.nextElement();
+ if (ex.isCritical())
+ extSet.add(((ObjectIdentifier) ex.getExtensionId()).toString());
+ }
+ return extSet;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Gets a Set of the extension(s) marked NON-CRITICAL in the
+ * certificate by OID strings.
+ *
+ * @return a set of the extension oid strings in the
+ * certificate that are NOT marked critical.
+ */
+ public Set<String> getNonCriticalExtensionOIDs() {
+ if (info == null)
+ return null;
+ try {
+ CertificateExtensions exts = (CertificateExtensions) info.get(
+ CertificateExtensions.NAME);
+ if (exts == null)
+ return null;
+
+ Set<String> extSet = new LinkedHashSet<String>();
+ Extension ex;
+ for (Enumeration<Extension> e = exts.getAttributes(); e.hasMoreElements();) {
+ ex = e.nextElement();
+ if (!ex.isCritical())
+ extSet.add(((ObjectIdentifier) ex.getExtensionId()).toString());
+ }
+ return extSet;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public Extension getExtension(String oid) {
+ try {
+ CertificateExtensions exts = (CertificateExtensions) info.get(
+ CertificateExtensions.NAME);
+ if (exts == null)
+ return null;
+ ObjectIdentifier findOID = new ObjectIdentifier(oid);
+ Extension ex = null;
+ ;
+ ObjectIdentifier inCertOID;
+ for (Enumeration<Extension> e = exts.getAttributes(); e.hasMoreElements();) {
+ ex = e.nextElement();
+ inCertOID = ex.getExtensionId();
+ if (inCertOID.equals(findOID)) {
+ return ex;
+ }
+ }
+ } catch (Exception e) {
+ }
+ return null;
+ }
+
+ /**
+ * Gets the DER encoded extension identified by the passed
+ * in oid String.
+ *
+ * @param oid the Object Identifier value for the extension.
+ */
+ public byte[] getExtensionValue(String oid) {
+ try {
+ String extAlias = OIDMap.getName(new ObjectIdentifier(oid));
+ Extension certExt = null;
+
+ if (extAlias == null) { // may be unknown
+ // get the extensions, search thru' for this oid
+ CertificateExtensions exts = (CertificateExtensions) info.get(
+ CertificateExtensions.NAME);
+ if (exts == null)
+ return null;
+
+ ObjectIdentifier findOID = new ObjectIdentifier(oid);
+ Extension ex = null;
+ ;
+ ObjectIdentifier inCertOID;
+ for (Enumeration<Extension> e = exts.getAttributes(); e.hasMoreElements();) {
+ ex = e.nextElement();
+ inCertOID = ex.getExtensionId();
+ if (inCertOID.equals(findOID)) {
+ certExt = ex;
+ break;
+ }
+ }
+ } else { // there's sub-class that can handle this extension
+ certExt = (Extension) this.get(extAlias);
+ }
+ if (certExt == null)
+ return null;
+ byte[] extData = certExt.getExtensionValue();
+ if (extData == null)
+ return null;
+
+ DerOutputStream out = new DerOutputStream();
+ out.putOctetString(extData);
+ return out.toByteArray();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Get a boolean array representing the bits of the KeyUsage extension,
+ * (oid = 2.5.29.15).
+ *
+ * @return the bit values of this extension as an array of booleans.
+ */
+ public boolean[] getKeyUsage() {
+ try {
+ String extAlias = OIDMap.getName(new ObjectIdentifier(
+ KEY_USAGE_OID));
+ if (extAlias == null)
+ return null;
+
+ KeyUsageExtension certExt = (KeyUsageExtension) this.get(extAlias);
+ if (certExt == null)
+ return null;
+
+ return certExt.getBits();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Get the certificate constraints path length from the
+ * the critical BasicConstraints extension, (oid = 2.5.29.19).
+ *
+ * @return the length of the constraint.
+ */
+ public int getBasicConstraints() {
+ try {
+ String extAlias = OIDMap.getName(new ObjectIdentifier(
+ BASIC_CONSTRAINT_OID));
+ if (extAlias == null)
+ return -1;
+ BasicConstraintsExtension certExt =
+ (BasicConstraintsExtension) this.get(extAlias);
+ if (certExt == null)
+ return -1;
+
+ if (((Boolean) certExt.get(BasicConstraintsExtension.IS_CA)).booleanValue() == true)
+ return ((Integer) certExt.get(
+ BasicConstraintsExtension.PATH_LEN)).intValue();
+ else
+ return -1;
+ } catch (Exception e) {
+ return -1;
+ }
+ }
+
+ public boolean getBasicConstraintsIsCA() {
+ boolean isCA = false;
+ try {
+ String extAlias = OIDMap.getName(new ObjectIdentifier(
+ BASIC_CONSTRAINT_OID));
+ if (extAlias == null)
+ return false;
+
+ BasicConstraintsExtension certExt =
+ (BasicConstraintsExtension) this.get(extAlias);
+ if (certExt == null)
+ return false;
+
+ isCA = ((Boolean) certExt.get(BasicConstraintsExtension.IS_CA)).booleanValue();
+ } catch (Exception e) {
+ return false;
+ }
+ return isCA;
+ }
+
+ /************************************************************/
+
+ /*
+ * Cert is a SIGNED ASN.1 macro, a three elment sequence:
+ *
+ * - Data to be signed (ToBeSigned) -- the "raw" cert
+ * - Signature algorithm (SigAlgId)
+ * - The signature bits
+ *
+ * This routine unmarshals the certificate, saving the signature
+ * parts away for later verification.
+ */
+ private void parse(DerValue val) throws CertificateException, IOException {
+ // check if can over write the certificate
+ if (readOnly)
+ throw new CertificateParsingException(
+ "cannot over-write existing certificate");
+
+ readOnly = true;
+ DerValue seq[] = new DerValue[3];
+
+ seq[0] = val.data.getDerValue();
+ seq[1] = val.data.getDerValue();
+ seq[2] = val.data.getDerValue();
+
+ if (val.data.available() != 0) {
+ throw new CertificateParsingException("signed overrun, bytes = "
+ + val.data.available());
+ }
+ if (seq[0].tag != DerValue.tag_Sequence) {
+ throw new CertificateParsingException("signed fields invalid");
+ }
+
+ algId = AlgorithmId.parse(seq[1]);
+ signature = seq[2].getBitString();
+
+ if (seq[1].data.available() != 0) {
+ throw new CertificateParsingException("algid field overrun");
+ }
+ if (seq[2].data.available() != 0)
+ throw new CertificateParsingException("signed fields overrun");
+
+ // The CertificateInfo
+ if (info == null) {
+ info = new X509CertInfo(seq[0]);
+ }
+ }
+
+ /**
+ * Serialization write ... X.509 certificates serialize as
+ * themselves, and they're parsed when they get read back.
+ * (Actually they serialize as some type data from the
+ * serialization subsystem, then the cert data.)
+ */
+ private synchronized void writeObject(ObjectOutputStream stream)
+ throws CertificateException, IOException {
+ encode(stream);
+ }
+
+ /**
+ * Serialization read ... X.509 certificates serialize as
+ * themselves, and they're parsed when they get read back.
+ */
+ private synchronized void readObject(ObjectInputStream stream)
+ throws CertificateException, IOException {
+ decode(stream);
+ }
+
+ protected static class CertificateRep1 implements java.io.Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5207881613631592409L;
+ private String type1;
+ private byte[] data1;
+
+ /**
+ * Construct the alternate Certificate class with the Certificate
+ * type and Certificate encoding bytes.
+ *
+ * <p>
+ *
+ * @param type the standard name of the Certificate type.
+ * <p>
+ *
+ * @param data the Certificate data.
+ */
+ protected CertificateRep1(String type, byte[] data) {
+ this.type1 = type;
+ this.data1 = data;
+ }
+
+ /**
+ * Resolve the Certificate Object.
+ *
+ * <p>
+ *
+ * @return the resolved Certificate Object.
+ *
+ * @throws java.io.ObjectStreamException if the Certificate could not
+ * be resolved.
+ */
+ protected Object readResolve() throws java.io.ObjectStreamException {
+ try {
+ @SuppressWarnings("unused")
+ CertificateFactory cf = CertificateFactory.getInstance(type1); // check for errors
+ return new X509CertImpl(data1);
+
+ /*
+ return cf.generateCertificate
+ (new java.io.ByteArrayInputStream(data1));
+ */
+ } catch (CertificateException e) {
+ throw new java.io.NotSerializableException("java.security.cert.Certificate: " +
+ type1 +
+ ": " +
+ e.getMessage());
+ }
+ }
+
+ }
+
+ protected Object writeReplace() throws java.io.ObjectStreamException {
+ try {
+ return new CertificateRep1("X.509", getEncoded());
+ } catch (CertificateException e) {
+ throw new java.io.NotSerializableException("java.security.cert.Certificate: " +
+ "X.509" +
+ ": " +
+ e.getMessage());
+ }
+ }
+}
diff --git a/base/util/src/netscape/security/x509/X509CertInfo.java b/base/util/src/netscape/security/x509/X509CertInfo.java
new file mode 100644
index 000000000..4777cd958
--- /dev/null
+++ b/base/util/src/netscape/security/x509/X509CertInfo.java
@@ -0,0 +1,964 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateParsingException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * The X509CertInfo class represents X.509 certificate information.
+ *
+ * <P>
+ * X.509 certificates have several base data elements, including:
+ * <UL>
+ *
+ * <LI>The <em>Subject Name</em>, an X.500 Distinguished Name for the entity (subject) for which the certificate was
+ * issued.
+ *
+ * <LI>The <em>Subject Public Key</em>, the public key of the subject. This is one of the most important parts of the
+ * certificate.
+ *
+ * <LI>The <em>Validity Period</em>, a time period (e.g. six months) within which the certificate is valid (unless
+ * revoked).
+ *
+ * <LI>The <em>Issuer Name</em>, an X.500 Distinguished Name for the Certificate Authority (CA) which issued the
+ * certificate.
+ *
+ * <LI>A <em>Serial Number</em> assigned by the CA, for use in certificate revocation and other applications.
+ *
+ * @author Amit Kapoor
+ * @author Hemma Prafullchandra
+ * @version 1.16
+ * @see CertAttrSet
+ * @see Serializable
+ * @see X509CertImpl
+ */
+public class X509CertInfo implements CertAttrSet, Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5094073467876311577L;
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT = "x509.info";
+ // Certificate attribute names
+ public static final String NAME = "info";
+ public static final String VERSION = CertificateVersion.NAME;
+ public static final String SERIAL_NUMBER = CertificateSerialNumber.NAME;
+ public static final String ALGORITHM_ID = CertificateAlgorithmId.NAME;
+ public static final String ISSUER = CertificateIssuerName.NAME;
+ public static final String VALIDITY = CertificateValidity.NAME;
+ public static final String SUBJECT = CertificateSubjectName.NAME;
+ public static final String KEY = CertificateX509Key.NAME;
+ public static final String ISSUER_ID = CertificateIssuerUniqueIdentity.NAME;
+ public static final String SUBJECT_ID = CertificateSubjectUniqueIdentity.NAME;
+ public static final String EXTENSIONS = CertificateExtensions.NAME;
+
+ // X509.v1 data
+ protected CertificateVersion version = new CertificateVersion();
+ protected CertificateSerialNumber serialNum = null;
+ protected CertificateAlgorithmId algId = null;
+ protected CertificateIssuerName issuer = null;
+ protected CertificateValidity interval = null;
+ protected CertificateSubjectName subject = null;
+ protected CertificateX509Key pubKey = null;
+
+ // X509.v2 & v3 extensions
+ protected CertificateIssuerUniqueIdentity issuerUniqueId = null;
+ protected CertificateSubjectUniqueIdentity subjectUniqueId = null;
+
+ // X509.v3 extensions
+ protected CertificateExtensions extensions = null;
+
+ // Attribute numbers for internal manipulation
+ private static final int ATTR_VERSION = 1;
+ private static final int ATTR_SERIAL = 2;
+ private static final int ATTR_ALGORITHM = 3;
+ private static final int ATTR_ISSUER = 4;
+ private static final int ATTR_VALIDITY = 5;
+ private static final int ATTR_SUBJECT = 6;
+ private static final int ATTR_KEY = 7;
+ private static final int ATTR_ISSUER_ID = 8;
+ private static final int ATTR_SUBJECT_ID = 9;
+ private static final int ATTR_EXTENSIONS = 10;
+
+ // DER encoded CertificateInfo data
+ private byte[] rawCertInfo = null;
+
+ // The certificate attribute name to integer mapping stored here
+ private static final Hashtable<String, Integer> map = new Hashtable<String, Integer>();
+ static {
+ map.put(VERSION, Integer.valueOf(ATTR_VERSION));
+ map.put(SERIAL_NUMBER, Integer.valueOf(ATTR_SERIAL));
+ map.put(ALGORITHM_ID, Integer.valueOf(ATTR_ALGORITHM));
+ map.put(ISSUER, Integer.valueOf(ATTR_ISSUER));
+ map.put(VALIDITY, Integer.valueOf(ATTR_VALIDITY));
+ map.put(SUBJECT, Integer.valueOf(ATTR_SUBJECT));
+ map.put(KEY, Integer.valueOf(ATTR_KEY));
+ map.put(ISSUER_ID, Integer.valueOf(ATTR_ISSUER_ID));
+ map.put(SUBJECT_ID, Integer.valueOf(ATTR_SUBJECT_ID));
+ map.put(EXTENSIONS, Integer.valueOf(ATTR_EXTENSIONS));
+ }
+
+ /**
+ * Construct an uninitialized X509CertInfo on which <a href="#decode">
+ * decode</a> must later be called (or which may be deserialized).
+ */
+ public X509CertInfo() {
+ }
+
+ /**
+ * Unmarshals a certificate from its encoded form, parsing the
+ * encoded bytes. This form of constructor is used by agents which
+ * need to examine and use certificate contents. That is, this is
+ * one of the more commonly used constructors. Note that the buffer
+ * must include only a certificate, and no "garbage" may be left at
+ * the end. If you need to ignore data at the end of a certificate,
+ * use another constructor.
+ *
+ * @param cert the encoded bytes, with no trailing data.
+ * @exception CertificateParsingException on parsing errors.
+ */
+ public X509CertInfo(byte[] cert) throws CertificateParsingException {
+ try {
+ DerValue in = new DerValue(cert);
+
+ parse(in);
+ } catch (IOException e) {
+ throw new CertificateParsingException(e.toString());
+ }
+ }
+
+ /**
+ * Unmarshal a certificate from its encoded form, parsing a DER value.
+ * This form of constructor is used by agents which need to examine
+ * and use certificate contents.
+ *
+ * @param derVal the der value containing the encoded cert.
+ * @exception CertificateParsingException on parsing errors.
+ */
+ public X509CertInfo(DerValue derVal) throws CertificateParsingException {
+ try {
+ parse(derVal);
+ } catch (IOException e) {
+ throw new CertificateParsingException(e.toString());
+ }
+ }
+
+ /**
+ * Decode an X.509 certificate from an input stream.
+ *
+ * @param in an input stream holding at least one certificate
+ * @exception CertificateParsingException on decoding errors.
+ * @exception IOException on other errors.
+ */
+ public void decode(InputStream in)
+ throws CertificateParsingException, IOException {
+ DerValue val = new DerValue(in);
+
+ parse(val);
+ }
+
+ /**
+ * Appends the certificate to an output stream.
+ *
+ * @param out an output stream to which the certificate is appended.
+ * @exception CertificateException on encoding errors.
+ * @exception IOException on other errors.
+ */
+ public void encode(OutputStream out)
+ throws CertificateException, IOException {
+ encode(out, false);
+ }
+
+ /**
+ * Appends the certificate to an output stream.
+ *
+ * @param out An output stream to which the certificate is appended.
+ * @param ignoreCache Whether to ignore the internal cache when encoding.
+ * (the cache can easily become out of date).
+ */
+ public void encode(OutputStream out, boolean ignoreCache)
+ throws IOException, CertificateException {
+ if (ignoreCache || (rawCertInfo == null)) {
+ DerOutputStream tmp = new DerOutputStream();
+ emit(tmp);
+ rawCertInfo = tmp.toByteArray();
+ }
+ out.write(rawCertInfo);
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getAttributeNames() {
+ Vector<String> elements = new Vector<String>();
+ elements.addElement(VERSION);
+ elements.addElement(SERIAL_NUMBER);
+ elements.addElement(ALGORITHM_ID);
+ elements.addElement(ISSUER);
+ elements.addElement(VALIDITY);
+ elements.addElement(SUBJECT);
+ elements.addElement(KEY);
+ elements.addElement(ISSUER_ID);
+ elements.addElement(SUBJECT_ID);
+ elements.addElement(EXTENSIONS);
+
+ return (elements.elements());
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return (NAME);
+ }
+
+ /**
+ * Returns the encoded certificate info.
+ *
+ * @exception CertificateEncodingException on encoding information errors.
+ */
+ public byte[] getEncodedInfo() throws CertificateEncodingException {
+ return getEncodedInfo(false);
+ }
+
+ public byte[] getEncodedInfo(boolean ignoreCache) throws CertificateEncodingException {
+ try {
+ if (ignoreCache || (rawCertInfo == null)) {
+ DerOutputStream tmp = new DerOutputStream();
+ emit(tmp);
+ rawCertInfo = tmp.toByteArray();
+ }
+ byte[] dup = new byte[rawCertInfo.length];
+ System.arraycopy(rawCertInfo, 0, dup, 0, dup.length);
+ return dup;
+ } catch (IOException e) {
+ throw new CertificateEncodingException(e.toString());
+ } catch (CertificateException e) {
+ throw new CertificateEncodingException(e.toString());
+ }
+ }
+
+ /**
+ * Compares two X509CertInfo objects. This is false if the
+ * certificates are not both X.509 certs, otherwise it
+ * compares them as binary data.
+ *
+ * @param other the object being compared with this one
+ * @return true iff the certificates are equivalent
+ */
+ public boolean equals(Object other) {
+ if (other instanceof X509CertInfo) {
+ return equals((X509CertInfo) other);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Compares two certificates, returning false if any data
+ * differs between the two.
+ *
+ * @param other the object being compared with this one
+ * @return true iff the certificates are equivalent
+ */
+ public boolean equals(X509CertInfo other) {
+ if (this == other) {
+ return (true);
+ } else if (rawCertInfo == null || other.rawCertInfo == null) {
+ return (false);
+ } else if (rawCertInfo.length != other.rawCertInfo.length) {
+ return (false);
+ }
+ for (int i = 0; i < rawCertInfo.length; i++) {
+ if (rawCertInfo[i] != other.rawCertInfo[i]) {
+ return (false);
+ }
+ }
+ return (true);
+ }
+
+ /**
+ * Calculates a hash code value for the object. Objects
+ * which are equal will also have the same hashcode.
+ */
+ public int hashCode() {
+ int retval = 0;
+
+ for (int i = 1; i < rawCertInfo.length; i++) {
+ retval += rawCertInfo[i] * i;
+ }
+ return (retval);
+ }
+
+ /**
+ * Returns a printable representation of the certificate.
+ */
+ public String toString() {
+
+ if (subject == null || pubKey == null || interval == null
+ || issuer == null || algId == null || serialNum == null) {
+ throw new NullPointerException("X.509 cert is incomplete");
+ }
+ StringBuffer sb = new StringBuffer();
+
+ sb.append("[\n");
+ sb.append(" " + version.toString() + "\n");
+ sb.append(" Subject: " + subject.toString() + "\n");
+ sb.append(" Signature Algorithm: " + algId.toString() + "\n");
+ sb.append(" Key: " + pubKey.toString() + "\n");
+ sb.append(" " + interval.toString() + "\n");
+ sb.append(" Issuer: " + issuer.toString() + "\n");
+ sb.append(" " + serialNum.toString() + "\n");
+
+ // optional v2, v3 extras
+ if (issuerUniqueId != null) {
+ sb.append(" Issuer Id:\n" + issuerUniqueId.toString() + "\n");
+ }
+ if (subjectUniqueId != null) {
+ sb.append(" Subject Id:\n" + subjectUniqueId.toString() + "\n");
+ }
+ if (extensions != null) {
+ netscape.security.util.PrettyPrintFormat pp =
+ new netscape.security.util.PrettyPrintFormat(" ", 20);
+ for (int i = 0; i < extensions.size(); i++) {
+ sb.append(" Extension[" + i + "] = ");
+ Extension ext = (Extension) extensions.elementAt(i);
+ try {
+ if (OIDMap.getClass(ext.getExtensionId()) == null) {
+ sb.append(ext.toString());
+ byte[] extValue = ext.getExtensionValue();
+ if (extValue != null) {
+ DerOutputStream out = new DerOutputStream();
+ out.putOctetString(extValue);
+ extValue = out.toByteArray();
+ String extValuebits = pp.toHexString(extValue);
+ sb.append("Extension unknown: "
+ + "DER encoded OCTET string =\n"
+ + extValuebits);
+ }
+ } else
+ sb.append(ext.toString()); //sub-class exists
+ } catch (Exception e) {
+ sb.append(", Error parsing this extension");
+ }
+ }
+ }
+ sb.append("\n]");
+ return sb.toString();
+ }
+
+ /**
+ * Set the certificate attribute.
+ *
+ * @param name the name of the Certificate attribute.
+ * @param val the value of the Certificate attribute.
+ * @exception CertificateException on invalid attributes.
+ * @exception IOException on other errors.
+ */
+ public void set(String name, Object val)
+ throws CertificateException, IOException {
+ X509AttributeName attrName = new X509AttributeName(name);
+
+ int attr = attributeMap(attrName.getPrefix());
+ if (attr == 0) {
+ throw new CertificateException("Attribute name not recognized: "
+ + name);
+ }
+ // set rawCertInfo to null, so that we are forced to re-encode
+ rawCertInfo = null;
+
+ switch (attr) {
+ case ATTR_VERSION:
+ if (attrName.getSuffix() == null) {
+ setVersion(val);
+ } else {
+ version.set(attrName.getSuffix(), val);
+ }
+ break;
+
+ case ATTR_SERIAL:
+ if (attrName.getSuffix() == null) {
+ setSerialNumber(val);
+ } else {
+ serialNum.set(attrName.getSuffix(), val);
+ }
+ break;
+
+ case ATTR_ALGORITHM:
+ if (attrName.getSuffix() == null) {
+ setAlgorithmId(val);
+ } else {
+ algId.set(attrName.getSuffix(), val);
+ }
+ break;
+
+ case ATTR_ISSUER:
+ if (attrName.getSuffix() == null) {
+ setIssuer(val);
+ } else {
+ issuer.set(attrName.getSuffix(), val);
+ }
+ break;
+
+ case ATTR_VALIDITY:
+ if (attrName.getSuffix() == null) {
+ setValidity(val);
+ } else {
+ interval.set(attrName.getSuffix(), val);
+ }
+ break;
+
+ case ATTR_SUBJECT:
+ if (attrName.getSuffix() == null) {
+ setSubject(val);
+ } else {
+ subject.set(attrName.getSuffix(), val);
+ }
+ break;
+
+ case ATTR_KEY:
+ if (attrName.getSuffix() == null) {
+ setKey(val);
+ } else {
+ pubKey.set(attrName.getSuffix(), val);
+ }
+ break;
+
+ case ATTR_ISSUER_ID:
+ if (attrName.getSuffix() == null) {
+ setIssuerUniqueId(val);
+ } else {
+ issuerUniqueId.set(attrName.getSuffix(), val);
+ }
+ break;
+
+ case ATTR_SUBJECT_ID:
+ if (attrName.getSuffix() == null) {
+ setSubjectUniqueId(val);
+ } else {
+ subjectUniqueId.set(attrName.getSuffix(), val);
+ }
+ break;
+
+ case ATTR_EXTENSIONS:
+ if (attrName.getSuffix() == null) {
+ setExtensions(val);
+ } else {
+ extensions.set(attrName.getSuffix(), val);
+ }
+ break;
+ }
+ }
+
+ /**
+ * Delete the certificate attribute.
+ *
+ * @param name the name of the Certificate attribute.
+ * @exception CertificateException on invalid attributes.
+ * @exception IOException on other errors.
+ */
+ public void delete(String name)
+ throws CertificateException, IOException {
+ X509AttributeName attrName = new X509AttributeName(name);
+
+ int attr = attributeMap(attrName.getPrefix());
+ if (attr == 0) {
+ throw new CertificateException("Attribute name not recognized: "
+ + name);
+ }
+ // set rawCertInfo to null, so that we are forced to re-encode
+ rawCertInfo = null;
+
+ switch (attr) {
+ case ATTR_VERSION:
+ if (attrName.getSuffix() == null) {
+ version = null;
+ } else {
+ version.delete(attrName.getSuffix());
+ }
+ break;
+ case (ATTR_SERIAL):
+ if (attrName.getSuffix() == null) {
+ serialNum = null;
+ } else {
+ serialNum.delete(attrName.getSuffix());
+ }
+ break;
+ case (ATTR_ALGORITHM):
+ if (attrName.getSuffix() == null) {
+ algId = null;
+ } else {
+ algId.delete(attrName.getSuffix());
+ }
+ break;
+ case (ATTR_ISSUER):
+ if (attrName.getSuffix() == null) {
+ issuer = null;
+ } else {
+ issuer.delete(attrName.getSuffix());
+ }
+ break;
+ case (ATTR_VALIDITY):
+ if (attrName.getSuffix() == null) {
+ interval = null;
+ } else {
+ interval.delete(attrName.getSuffix());
+ }
+ break;
+ case (ATTR_SUBJECT):
+ if (attrName.getSuffix() == null) {
+ subject = null;
+ } else {
+ subject.delete(attrName.getSuffix());
+ }
+ break;
+ case (ATTR_KEY):
+ if (attrName.getSuffix() == null) {
+ pubKey = null;
+ } else {
+ pubKey.delete(attrName.getSuffix());
+ }
+ break;
+ case (ATTR_ISSUER_ID):
+ if (attrName.getSuffix() == null) {
+ issuerUniqueId = null;
+ } else {
+ issuerUniqueId.delete(attrName.getSuffix());
+ }
+ break;
+ case (ATTR_SUBJECT_ID):
+ if (attrName.getSuffix() == null) {
+ subjectUniqueId = null;
+ } else {
+ subjectUniqueId.delete(attrName.getSuffix());
+ }
+ break;
+ case (ATTR_EXTENSIONS):
+ if (attrName.getSuffix() == null) {
+ extensions = null;
+ } else {
+ extensions.delete(attrName.getSuffix());
+ }
+ break;
+ }
+ }
+
+ /**
+ * Get the certificate attribute.
+ *
+ * @param name the name of the Certificate attribute.
+ *
+ * @exception CertificateException on invalid attributes.
+ * @exception IOException on other errors.
+ */
+ public Object get(String name)
+ throws CertificateException, IOException {
+ X509AttributeName attrName = new X509AttributeName(name);
+
+ int attr = attributeMap(attrName.getPrefix());
+ if (attr == 0) {
+ throw new CertificateParsingException(
+ "Attribute name not recognized: " + name);
+ }
+
+ switch (attr) {
+ case (ATTR_VERSION):
+ if (attrName.getSuffix() == null) {
+ return (version);
+ } else {
+ return (version.get(attrName.getSuffix()));
+ }
+ case (ATTR_SERIAL):
+ if (attrName.getSuffix() == null) {
+ return (serialNum);
+ } else {
+ return (serialNum.get(attrName.getSuffix()));
+ }
+ case (ATTR_ALGORITHM):
+ if (attrName.getSuffix() == null) {
+ return (algId);
+ } else {
+ return (algId.get(attrName.getSuffix()));
+ }
+ case (ATTR_ISSUER):
+ if (attrName.getSuffix() == null) {
+ return (issuer);
+ } else {
+ return (issuer.get(attrName.getSuffix()));
+ }
+ case (ATTR_VALIDITY):
+ if (attrName.getSuffix() == null) {
+ return (interval);
+ } else {
+ return (interval.get(attrName.getSuffix()));
+ }
+ case (ATTR_SUBJECT):
+ if (attrName.getSuffix() == null) {
+ return (subject);
+ } else {
+ return (subject.get(attrName.getSuffix()));
+ }
+ case (ATTR_KEY):
+ if (attrName.getSuffix() == null) {
+ return (pubKey);
+ } else {
+ return (pubKey.get(attrName.getSuffix()));
+ }
+ case (ATTR_ISSUER_ID):
+ if (attrName.getSuffix() == null) {
+ return (issuerUniqueId);
+ } else {
+ if (issuerUniqueId == null)
+ return null;
+ else
+ return (issuerUniqueId.get(attrName.getSuffix()));
+ }
+ case (ATTR_SUBJECT_ID):
+ if (attrName.getSuffix() == null) {
+ return (subjectUniqueId);
+ } else {
+ if (subjectUniqueId == null)
+ return null;
+ else
+ return (subjectUniqueId.get(attrName.getSuffix()));
+ }
+ case (ATTR_EXTENSIONS):
+ if (attrName.getSuffix() == null) {
+ return (extensions);
+ } else {
+ if (extensions == null)
+ return null;
+ else
+ return (extensions.get(attrName.getSuffix()));
+ }
+ }
+ return null;
+ }
+
+ /*
+ * This routine unmarshals the certificate information.
+ */
+ private void parse(DerValue val)
+ throws CertificateParsingException, IOException {
+ DerInputStream in;
+ DerValue tmp;
+
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new CertificateParsingException("signed fields invalid");
+ }
+ rawCertInfo = val.toByteArray();
+
+ in = val.data;
+
+ // Version
+ tmp = in.getDerValue();
+ if (tmp.isContextSpecific((byte) 0)) {
+ version = new CertificateVersion(tmp);
+ tmp = in.getDerValue();
+ }
+
+ // Serial number ... an integer
+ serialNum = new CertificateSerialNumber(tmp);
+
+ // Algorithm Identifier
+ algId = new CertificateAlgorithmId(in);
+
+ // Issuer name
+ issuer = new CertificateIssuerName(in);
+
+ // validity: SEQUENCE { start date, end date }
+ interval = new CertificateValidity(in);
+
+ // subject name
+ subject = new CertificateSubjectName(in);
+
+ // public key
+ pubKey = new CertificateX509Key(in);
+
+ // If more data available, make sure version is not v1.
+ if (in.available() != 0) {
+ if (version.compare(CertificateVersion.V1) == 0) {
+ throw new CertificateParsingException("excess cert data");
+ }
+ } else {
+ return;
+ }
+
+ // Get the issuerUniqueId if present
+ tmp = in.getDerValue();
+ if (tmp.isContextSpecific((byte) 1)) {
+ issuerUniqueId = new CertificateIssuerUniqueIdentity(tmp);
+ if (in.available() == 0) {
+ return;
+ }
+ tmp = in.getDerValue();
+ }
+
+ // Get the subjectUniqueId if present.
+ if (tmp.isContextSpecific((byte) 2)) {
+ subjectUniqueId = new CertificateSubjectUniqueIdentity(tmp);
+ if (in.available() == 0) {
+ return;
+ }
+ tmp = in.getDerValue();
+ }
+
+ // Get the extensions.
+ if (version.compare(CertificateVersion.V3) != 0) {
+ throw new CertificateParsingException("excess cert data");
+ }
+ if (tmp.isConstructed() && tmp.isContextSpecific((byte) 3)) {
+ extensions = new CertificateExtensions(tmp.data);
+ }
+ }
+
+ /*
+ * Marshal the contents of a "raw" certificate into a DER sequence.
+ */
+ private void emit(DerOutputStream out)
+ throws CertificateException, IOException {
+ DerOutputStream tmp = new DerOutputStream();
+
+ // version number, iff not V1
+ version.encode(tmp);
+
+ // Encode serial number, issuer signing algorithm, issuer name
+ // and validity
+ serialNum.encode(tmp);
+ algId.encode(tmp);
+ issuer.encode(tmp);
+ interval.encode(tmp);
+
+ // Encode subject (principal) and associated key
+ subject.encode(tmp);
+ pubKey.encode(tmp);
+
+ // Encode issuerUniqueId & subjectUniqueId.
+ if (issuerUniqueId != null) {
+ issuerUniqueId.encode(tmp);
+ }
+ if (subjectUniqueId != null) {
+ subjectUniqueId.encode(tmp);
+ }
+
+ // Write all the extensions.
+ if (extensions != null) {
+ extensions.encode(tmp);
+ }
+
+ // Wrap the data; encoding of the "raw" cert is now complete.
+ out.write(DerValue.tag_Sequence, tmp);
+ }
+
+ /**
+ * Serialization write ... X.509 certificates serialize as
+ * themselves, and they're parsed when they get read back.
+ * (Actually they serialize as some type data from the
+ * serialization subsystem, then the cert data.)
+ */
+ private synchronized void writeObject(ObjectOutputStream stream)
+ throws CertificateException, IOException {
+ encode(stream);
+ }
+
+ /**
+ * Serialization read ... X.509 certificates serialize as
+ * themselves, and they're parsed when they get read back.
+ */
+ private synchronized void readObject(ObjectInputStream stream)
+ throws CertificateException, IOException {
+ decode(stream);
+ }
+
+ /**
+ * Returns the integer attribute number for the passed attribute name.
+ */
+ private int attributeMap(String name) {
+ Integer num = map.get(name);
+ if (num == null) {
+ return (0);
+ }
+ return (num.intValue());
+ }
+
+ /**
+ * Set the version number of the certificate.
+ *
+ * @param val the Object class value for the Extensions
+ * @exception CertificateException on invalid data.
+ */
+ private void setVersion(Object val) throws CertificateException {
+ if (!(val instanceof CertificateVersion)) {
+ throw new CertificateException("Version class type invalid.");
+ }
+ version = (CertificateVersion) val;
+ }
+
+ /**
+ * Set the serial number of the certificate.
+ *
+ * @param val the Object class value for the CertificateSerialNumber
+ * @exception CertificateException on invalid data.
+ */
+ private void setSerialNumber(Object val) throws CertificateException {
+ if (!(val instanceof CertificateSerialNumber)) {
+ throw new CertificateException("SerialNumber class type invalid.");
+ }
+ serialNum = (CertificateSerialNumber) val;
+ }
+
+ /**
+ * Set the algorithm id of the certificate.
+ *
+ * @param val the Object class value for the AlgorithmId
+ * @exception CertificateException on invalid data.
+ */
+ private void setAlgorithmId(Object val) throws CertificateException {
+ if (!(val instanceof CertificateAlgorithmId)) {
+ throw new CertificateException(
+ "AlgorithmId class type invalid.");
+ }
+ algId = (CertificateAlgorithmId) val;
+ }
+
+ /**
+ * Set the issuer name of the certificate.
+ *
+ * @param val the Object class value for the issuer
+ * @exception CertificateException on invalid data.
+ */
+ private void setIssuer(Object val) throws CertificateException {
+ if (!(val instanceof CertificateIssuerName)) {
+ throw new CertificateException(
+ "Issuer class type invalid.");
+ }
+ issuer = (CertificateIssuerName) val;
+ }
+
+ /**
+ * Set the validity interval of the certificate.
+ *
+ * @param val the Object class value for the CertificateValidity
+ * @exception CertificateException on invalid data.
+ */
+ private void setValidity(Object val) throws CertificateException {
+ if (!(val instanceof CertificateValidity)) {
+ throw new CertificateException(
+ "CertificateValidity class type invalid.");
+ }
+ interval = (CertificateValidity) val;
+ }
+
+ /**
+ * Set the subject name of the certificate.
+ *
+ * @param val the Object class value for the Subject
+ * @exception CertificateException on invalid data.
+ */
+ private void setSubject(Object val) throws CertificateException {
+ if (!(val instanceof CertificateSubjectName)) {
+ throw new CertificateException(
+ "Subject class type invalid.");
+ }
+ subject = (CertificateSubjectName) val;
+ }
+
+ /**
+ * Set the public key in the certificate.
+ *
+ * @param val the Object class value for the PublicKey
+ * @exception CertificateException on invalid data.
+ */
+ private void setKey(Object val) throws CertificateException {
+ if (!(val instanceof CertificateX509Key)) {
+ throw new CertificateException(
+ "Key class type invalid.");
+ }
+ pubKey = (CertificateX509Key) val;
+ }
+
+ /**
+ * Set the Issuer Unique Identity in the certificate.
+ *
+ * @param val the Object class value for the IssuerUniqueId
+ * @exception CertificateException
+ */
+ private void setIssuerUniqueId(Object val) throws CertificateException {
+ if (version.compare(CertificateVersion.V2) < 0) {
+ throw new CertificateException("Invalid version");
+ }
+ if (!(val instanceof CertificateIssuerUniqueIdentity)) {
+ throw new CertificateException(
+ "IssuerUniqueId class type invalid.");
+ }
+ issuerUniqueId = (CertificateIssuerUniqueIdentity) val;
+ }
+
+ /**
+ * Set the Subject Unique Identity in the certificate.
+ *
+ * @param val the Object class value for the SubjectUniqueId
+ * @exception CertificateException
+ */
+ private void setSubjectUniqueId(Object val) throws CertificateException {
+ if (version.compare(CertificateVersion.V2) < 0) {
+ throw new CertificateException("Invalid version");
+ }
+ if (!(val instanceof CertificateSubjectUniqueIdentity)) {
+ throw new CertificateException(
+ "SubjectUniqueId class type invalid.");
+ }
+ subjectUniqueId = (CertificateSubjectUniqueIdentity) val;
+ }
+
+ /**
+ * Set the extensions in the certificate.
+ *
+ * @param val the Object class value for the Extensions
+ * @exception CertificateException
+ */
+ private void setExtensions(Object val) throws CertificateException {
+ if (version.compare(CertificateVersion.V3) < 0) {
+ throw new CertificateException("Invalid version");
+ }
+ if (!(val instanceof CertificateExtensions)) {
+ throw new CertificateException(
+ "Extensions class type invalid.");
+ }
+ extensions = (CertificateExtensions) val;
+ }
+}
diff --git a/base/util/src/netscape/security/x509/X509ExtensionException.java b/base/util/src/netscape/security/x509/X509ExtensionException.java
new file mode 100644
index 000000000..c7174aed8
--- /dev/null
+++ b/base/util/src/netscape/security/x509/X509ExtensionException.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 netscape.security.x509;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * X.509 Extension Exception.
+ *
+ * @author Hemma Prafullchandra
+ * 1.2
+ */
+public class X509ExtensionException extends GeneralSecurityException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8152491877676477910L;
+
+ /**
+ * Constructs an X509ExtensionException with no detail message. A
+ * detail message is a String that describes this particular
+ * exception.
+ */
+ public X509ExtensionException() {
+ super();
+ }
+
+ /**
+ * Constructs the exception with the specified detail
+ * message. A detail message is a String that describes this
+ * particular exception.
+ *
+ * @param message the detail message.
+ */
+ public X509ExtensionException(String message) {
+ super(message);
+ }
+}
diff --git a/base/util/src/netscape/security/x509/X509Key.java b/base/util/src/netscape/security/x509/X509Key.java
new file mode 100644
index 000000000..a8253c0d8
--- /dev/null
+++ b/base/util/src/netscape/security/x509/X509Key.java
@@ -0,0 +1,508 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.x509;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.X509EncodedKeySpec;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+/**
+ * Holds an X.509 key, for example a public key found in an X.509
+ * certificate. Includes a description of the algorithm to be used
+ * with the key; these keys normally are used as
+ * "SubjectPublicKeyInfo".
+ *
+ * <P>
+ * While this class can represent any kind of X.509 key, it may be desirable to provide subclasses which understand how
+ * to parse keying data. For example, RSA public keys have two members, one for the public modulus and one for the prime
+ * exponent. If such a class is provided, it is used when parsing X.509 keys. If one is not provided, the key still
+ * parses correctly.
+ *
+ * @version 1.74, 97/12/10
+ * @author David Brownell
+ */
+public class X509Key implements PublicKey {
+
+ /** use serialVersionUID from JDK 1.1. for interoperability */
+ private static final long serialVersionUID = -5359250853002055002L;
+
+ /* The algorithm information (name, parameters, etc). */
+ protected AlgorithmId algid;
+
+ /* The key bytes, without the algorithm information */
+ protected byte[] key;
+
+ /* The encoding for the key. */
+ protected byte[] encodedKey;
+
+ /**
+ * Default constructor. The key constructed must have its key
+ * and algorithm initialized before it may be used, for example
+ * by using <code>decode</code>.
+ */
+ public X509Key() {
+ }
+
+ /*
+ * Build and initialize as a "default" key. All X.509 key
+ * data is stored and transmitted losslessly, but no knowledge
+ * about this particular algorithm is available.
+ */
+ public X509Key(AlgorithmId algid, byte[] key)
+ throws InvalidKeyException {
+ this.algid = algid;
+ this.key = key;
+ encode();
+ }
+
+ /**
+ * Construct X.509 subject public key from a DER value. If
+ * the runtime environment is configured with a specific class for
+ * this kind of key, a subclass is returned. Otherwise, a generic
+ * X509Key object is returned.
+ *
+ * <P>
+ * This mechanism gurantees that keys (and algorithms) may be freely manipulated and transferred, without risk of
+ * losing information. Also, when a key (or algorithm) needs some special handling, that specific need can be
+ * accomodated.
+ *
+ * @param in the DER-encoded SubjectPublicKeyInfo value
+ * @exception IOException on data format errors
+ */
+ public static X509Key parse(DerValue in) throws IOException {
+ AlgorithmId algorithm;
+ X509Key subjectKey;
+
+ if (in.tag != DerValue.tag_Sequence)
+ throw new IOException("corrupt subject key");
+
+ algorithm = AlgorithmId.parse(in.data.getDerValue());
+ try {
+ subjectKey = buildX509Key(algorithm, in.data.getBitString());
+
+ } catch (InvalidKeyException e) {
+ throw new IOException("subject key, " + e.getMessage());
+ }
+
+ if (in.data.available() != 0)
+ throw new IOException("excess subject key");
+ return subjectKey;
+ }
+
+ /**
+ * Parse the key bits. This may be redefined by subclasses to take
+ * advantage of structure within the key. For example, RSA public
+ * keys encapsulate two unsigned integers (modulus and exponent) as
+ * DER values within the <code>key</code> bits; Diffie-Hellman and
+ * DSS/DSA keys encapsulate a single unsigned integer.
+ *
+ * <P>
+ * This function is called when creating X.509 SubjectPublicKeyInfo values using the X509Key member functions, such
+ * as <code>parse</code> and <code>decode</code>.
+ *
+ * @exception IOException on parsing errors.
+ * @exception InvalidKeyException on invalid key encodings.
+ */
+ protected void parseKeyBits() throws IOException, InvalidKeyException {
+ encode();
+ }
+
+ /*
+ * Factory interface, building the kind of key associated with this
+ * specific algorithm ID or else returning this generic base class.
+ * See the description above.
+ */
+ static X509Key buildX509Key(AlgorithmId algid, byte[] key)
+ throws IOException, InvalidKeyException {
+ /*
+ * Use the algid and key parameters to produce the ASN.1 encoding
+ * of the key, which will then be used as the input to the
+ * key factory.
+ */
+ DerOutputStream x509EncodedKeyStream = new DerOutputStream();
+ encode(x509EncodedKeyStream, algid, key);
+ X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(x509EncodedKeyStream.toByteArray());
+
+ try {
+ // Instantiate the key factory of the appropriate algorithm
+ KeyFactory keyFac = null;
+ if (Security.getProvider("Mozilla-JSS") == null) {
+ keyFac = KeyFactory.getInstance(algid.getName());
+ } else {
+ keyFac = KeyFactory.getInstance(algid.getName(),
+ "Mozilla-JSS");
+ }
+
+ // Generate the public key
+ PublicKey pubKey = keyFac.generatePublic(x509KeySpec);
+
+ if (pubKey instanceof X509Key) {
+ /*
+ * Return specialized X509Key, where the structure within the
+ * key has been parsed
+ */
+ return (X509Key) pubKey;
+ }
+ } catch (NoSuchAlgorithmException e) {
+ // Return generic X509Key with opaque key data (see below)
+ } catch (InvalidKeySpecException e) {
+ throw new InvalidKeyException(e.toString());
+ } catch (Exception e) {
+ throw new InvalidKeyException(e.toString());
+ }
+
+ /*
+ * Try again using JDK1.1-style for backwards compatibility.
+ */
+ String classname = "";
+ try {
+ Provider sunProvider;
+
+ sunProvider = Security.getProvider("SUN");
+ if (sunProvider == null)
+ throw new InstantiationException();
+ classname = sunProvider.getProperty("PublicKey.X.509." +
+ algid.getName());
+ if (classname == null) {
+ throw new InstantiationException();
+ }
+
+ Class<?> keyClass = Class.forName(classname);
+ Object inst;
+ X509Key result;
+
+ inst = keyClass.newInstance();
+ if (inst instanceof X509Key) {
+ result = (X509Key) inst;
+ result.algid = algid;
+ result.key = key;
+ result.parseKeyBits();
+ return result;
+ }
+ } catch (ClassNotFoundException e) {
+ } catch (InstantiationException e) {
+ } catch (IllegalAccessException e) {
+ // this should not happen.
+ throw new IOException(classname + " [internal error]");
+ }
+
+ X509Key result = new X509Key();
+ result.algid = algid;
+ result.key = key;
+ return result;
+ }
+
+ /**
+ * Returns the algorithm to be used with this key.
+ */
+ public String getAlgorithm() {
+ return algid.getName();
+ }
+
+ /**
+ * Returns the algorithm ID to be used with this key.
+ */
+ public AlgorithmId getAlgorithmId() {
+ return algid;
+ }
+
+ /**
+ * Encode SubjectPublicKeyInfo sequence on the DER output stream.
+ *
+ * @exception IOException on encoding errors.
+ */
+ public final void encode(DerOutputStream out) throws IOException {
+ encode(out, this.algid, this.key);
+ }
+
+ /**
+ * Returns the DER-encoded form of the key as a byte array.
+ */
+ public synchronized byte[] getEncoded() {
+ byte[] result = null;
+ try {
+ result = encode();
+ } catch (InvalidKeyException e) {
+ }
+ return result;
+ }
+
+ /**
+ * Returns the format for this key: "X.509"
+ */
+ public String getFormat() {
+ return "X.509";
+ }
+
+ /**
+ * Returns the raw key as a byte array
+ */
+ public byte[] getKey() {
+ return key;
+ }
+
+ /**
+ * Returns the DER-encoded form of the key as a byte array.
+ *
+ * @exception InvalidKeyException on encoding errors.
+ */
+ public byte[] encode() throws InvalidKeyException {
+ if (encodedKey == null) {
+ try {
+ DerOutputStream out;
+
+ out = new DerOutputStream();
+ encode(out);
+ encodedKey = out.toByteArray();
+
+ } catch (IOException e) {
+ throw new InvalidKeyException("IOException : " +
+ e.getMessage());
+ }
+ }
+ return copyEncodedKey(encodedKey);
+ }
+
+ /*
+ * Returns a printable representation of the key
+ */
+ public String toString() {
+ netscape.security.util.PrettyPrintFormat pp =
+ new netscape.security.util.PrettyPrintFormat(" ", 20);
+ String keybits = pp.toHexString(key);
+
+ return "algorithm = " + algid.toString()
+ + ", unparsed keybits = \n" + keybits;
+ }
+
+ /**
+ * Initialize an X509Key object from an input stream. The data on that
+ * input stream must be encoded using DER, obeying the X.509 <code>SubjectPublicKeyInfo</code> format. That is, the
+ * data is a
+ * sequence consisting of an algorithm ID and a bit string which holds
+ * the key. (That bit string is often used to encapsulate another DER
+ * encoded sequence.)
+ *
+ * <P>
+ * Subclasses should not normally redefine this method; they should instead provide a <code>parseKeyBits</code>
+ * method to parse any fields inside the <code>key</code> member.
+ *
+ * <P>
+ * The exception to this rule is that since private keys need not be encoded using the X.509
+ * <code>SubjectPublicKeyInfo</code> format, private keys may override this method, <code>encode</code>, and of
+ * course <code>getFormat</code>.
+ *
+ * @param in an input stream with a DER-encoded X.509
+ * SubjectPublicKeyInfo value
+ * @exception InvalidKeyException on parsing errors.
+ */
+ public void decode(InputStream in)
+ throws InvalidKeyException {
+ DerValue val;
+
+ try {
+ val = new DerValue(in);
+ if (val.tag != DerValue.tag_Sequence)
+ throw new InvalidKeyException("invalid key format");
+
+ algid = AlgorithmId.parse(val.data.getDerValue());
+ key = val.data.getBitString();
+ parseKeyBits();
+ if (val.data.available() != 0)
+ throw new InvalidKeyException("excess key data");
+
+ } catch (IOException e) {
+ // e.printStackTrace ();
+ throw new InvalidKeyException("IOException : " +
+ e.getMessage());
+ }
+ }
+
+ public void decode(byte[] encodedKey) throws InvalidKeyException {
+ decode(new ByteArrayInputStream(encodedKey));
+ }
+
+ /**
+ * Serialization write ... X.509 keys serialize as
+ * themselves, and they're parsed when they get read back.
+ */
+ private synchronized void
+ writeObject(java.io.ObjectOutputStream stream)
+ throws IOException {
+ stream.write(getEncoded());
+ }
+
+ /**
+ * Serialization read ... X.509 keys serialize as
+ * themselves, and they're parsed when they get read back.
+ */
+ private synchronized void
+ readObject(ObjectInputStream stream)
+ throws IOException {
+
+ try {
+ decode(stream);
+
+ } catch (InvalidKeyException e) {
+ e.printStackTrace();
+ throw new IOException("deserialized key is invalid: " +
+ e.getMessage());
+ }
+ }
+
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+
+ if (object instanceof Key) {
+ Key key = (Key) object;
+
+ byte[] b1;
+ if (encodedKey != null) {
+ b1 = encodedKey;
+ } else {
+ b1 = getEncoded();
+ }
+ byte[] b2 = key.getEncoded();
+
+ return java.security.MessageDigest.isEqual(b1, b2);
+ }
+
+ return false;
+ }
+
+ /**
+ * Calculates a hash code value for the object. Objects
+ * which are equal will also have the same hashcode.
+ */
+ public int hashCode() {
+ int retval = 0;
+ byte[] b1 = getEncoded();
+
+ for (int i = 1; i < b1.length; i++) {
+ retval += b1[i] * i;
+ }
+ return (retval);
+ }
+
+ /*
+ * Make a copy of the encoded key.
+ */
+ private byte[] copyEncodedKey(byte[] encodedKey) {
+ int len = encodedKey.length;
+ byte[] copy = new byte[len];
+ System.arraycopy(encodedKey, 0, copy, 0, len);
+ return copy;
+ }
+
+ /*
+ * Produce SubjectPublicKey encoding from algorithm id and key material.
+ */
+ static void encode(DerOutputStream out, AlgorithmId algid, byte[] key)
+ throws IOException {
+ DerOutputStream tmp = new DerOutputStream();
+ algid.encode(tmp);
+ tmp.putBitString(key);
+ out.write(DerValue.tag_Sequence, tmp);
+ }
+
+ /*
+ * parsePublicKey returns a PublicKey for use with package JSS from within netscape.security.*.
+ * This function provide an interim solution for migrating from using the netscape.security.* package
+ * to using the JSS package.
+ */
+
+ public static PublicKey parsePublicKey(DerValue in) throws IOException {
+ AlgorithmId algorithm;
+ PublicKey subjectKey;
+
+ if (in.tag != DerValue.tag_Sequence)
+ throw new IOException("corrupt subject key");
+
+ algorithm = AlgorithmId.parse(in.data.getDerValue());
+ try {
+ subjectKey = buildPublicKey(algorithm, in.data.getBitString());
+
+ } catch (InvalidKeyException e) {
+ throw new IOException("subject key, " + e.getMessage());
+ }
+
+ if (in.data.available() != 0)
+ throw new IOException("excess subject key");
+ return subjectKey;
+ }
+
+ /* buildPublicKey returns a PublicKey for use with the JSS package from within netscape.security.*.
+ * This function provide an interim solution for migrating from using the netscape.security.* package
+ * to using the JSS package.
+ */
+ static PublicKey buildPublicKey(AlgorithmId algid, byte[] key)
+ throws IOException, InvalidKeyException {
+ /*
+ * Use the algid and key parameters to produce the ASN.1 encoding
+ * of the key, which will then be used as the input to the
+ * key factory.
+ */
+ DerOutputStream x509EncodedKeyStream = new DerOutputStream();
+ encode(x509EncodedKeyStream, algid, key);
+ X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(x509EncodedKeyStream.toByteArray());
+
+ try {
+ // Instantiate the key factory of the appropriate algorithm
+ KeyFactory keyFac = null;
+ if (Security.getProvider("Mozilla-JSS") == null) {
+ keyFac = KeyFactory.getInstance(algid.getName());
+ } else {
+ keyFac = KeyFactory.getInstance(algid.getName(),
+ "Mozilla-JSS");
+ }
+
+ // Generate the public key
+ PublicKey pubKey = keyFac.generatePublic(x509KeySpec);
+
+ /*
+ * Return specialized X509Key, where the structure within the
+ * key has been parsed
+ */
+ return pubKey;
+ } catch (NoSuchAlgorithmException e) {
+ // Return generic X509Key with opaque key data (see below)
+ throw new InvalidKeyException(e.toString());
+ } catch (InvalidKeySpecException e) {
+ throw new InvalidKeyException(e.toString());
+ } catch (Exception e) {
+ throw new InvalidKeyException(e.toString());
+ }
+
+ }
+
+}
diff --git a/base/util/test/CMakeLists.txt b/base/util/test/CMakeLists.txt
new file mode 100644
index 000000000..592f3dbbb
--- /dev/null
+++ b/base/util/test/CMakeLists.txt
@@ -0,0 +1,60 @@
+project(pki-util-test Java)
+
+# TODO: create CMake function to find all Java files
+set(pki-util-test_SRCS
+ com/netscape/security/util/BMPStringTest.java
+ com/netscape/security/util/IA5StringTest.java
+ com/netscape/security/util/JSSUtil.java
+ com/netscape/security/util/PrintableStringTest.java
+ com/netscape/security/util/StringTestUtil.java
+ com/netscape/security/util/TeletexStringTest.java
+ com/netscape/security/util/UniversalStringTest.java
+ com/netscape/security/util/UTF8StringTest.java
+ com/netscape/security/x509/ConverterTestUtil.java
+ com/netscape/security/x509/DirStrConverterTest.java
+ com/netscape/security/x509/GenericValueConverterTest.java
+ com/netscape/security/x509/IA5StringConverterTest.java
+ com/netscape/security/x509/PrintableConverterTest.java
+)
+
+set(CMAKE_JAVA_INCLUDE_PATH
+ ${PKI_NSUTIL_JAR} ${PKI_CMSUTIL_JAR}
+ ${JSS_JAR} ${LDAPJDK_JAR} ${COMMONS_CODEC_JAR} ${XALAN_JAR} ${XERCES_JAR}
+ ${PKI_TEST_JAR} ${JUNIT_JAR}
+)
+
+set(CMAKE_JAVA_TARGET_VERSION ${APPLICATION_VERSION})
+
+# build test jar file
+# TODO: create CMake function to compile without building jar file
+# TODO: build test only when the test is invoked
+set(CMAKE_JAR_CLASSES_PREFIX com/netscape)
+add_jar(pki-util-test ${pki-util-test_SRCS})
+add_dependencies(pki-util-test pki-nsutil pki-cmsutil pki-test)
+
+# create test target
+# do not include xalan and xerces in class path
+# TODO: create CMake function to find all JUnit test classes
+add_junit_test(test-pki-util
+ CLASSPATH
+ ${pki-util-test_JAR_FILE}
+ ${PKI_NSUTIL_JAR} ${PKI_CMSUTIL_JAR}
+ ${JSS_JAR} ${LDAPJDK_JAR} ${COMMONS_CODEC_JAR}
+ ${PKI_TEST_JAR} ${JUNIT_JAR}
+ TESTS
+ com.netscape.security.util.BMPStringTest
+ com.netscape.security.util.IA5StringTest
+ com.netscape.security.util.PrintableStringTest
+ com.netscape.security.util.TeletexStringTest
+ com.netscape.security.util.UniversalStringTest
+ com.netscape.security.util.UTF8StringTest
+ com.netscape.security.x509.DirStrConverterTest
+ com.netscape.security.x509.GenericValueConverterTest
+ com.netscape.security.x509.IA5StringConverterTest
+ com.netscape.security.x509.PrintableConverterTest
+ REPORTS_DIR
+ reports
+)
+
+# include test into the main test
+add_dependencies(test test-pki-util)
diff --git a/base/util/test/com/netscape/security/extensions/GenericASN1ExtensionTest.java b/base/util/test/com/netscape/security/extensions/GenericASN1ExtensionTest.java
new file mode 100644
index 000000000..74d082f09
--- /dev/null
+++ b/base/util/test/com/netscape/security/extensions/GenericASN1ExtensionTest.java
@@ -0,0 +1,72 @@
+package com.netscape.security.extensions;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.util.Hashtable;
+
+import netscape.security.extensions.GenericASN1Extension;
+import netscape.security.x509.OIDMap;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class GenericASN1ExtensionTest {
+
+ //@Test
+ public void testConstructorArgs() throws Exception {
+ String name1 = "testExtension1";
+ String oid1 = "1.2.3.4";
+ String pattern = "";
+ Hashtable<String, String> config = new Hashtable<String, String>();
+ GenericASN1Extension extension1 = new GenericASN1Extension(name1, oid1,
+ pattern, false, config);
+ Assert.assertEquals(name1, extension1.getName());
+ Assert.assertNotNull(OIDMap.getClass(name1));
+
+ String name2 = "testExtension2";
+ String oid2 = "2.4.6.8";
+ GenericASN1Extension extension2 = new GenericASN1Extension(name2, oid2,
+ pattern, false, config);
+ Assert.assertEquals(name2, extension2.getName());
+ Assert.assertNotNull(OIDMap.getClass(name2));
+ }
+
+ @Test
+ public void testConstructorJustConfig() throws Exception {
+ String name1 = "testExtension1";
+ String oid1 = "1.2.3.4";
+ String pattern = "";
+ Hashtable<String, String> config = new Hashtable<String, String>();
+ config.put("oid", oid1);
+ config.put("name", name1);
+ config.put("pattern", pattern);
+ config.put("critical", "true");
+
+ GenericASN1Extension extension1 = new GenericASN1Extension(config);
+ Assert.assertEquals(name1, extension1.getName());
+ //Assert.assertNotNull(OIDMap.getClass(name1));
+
+ String name2 = "testExtension2";
+ String oid2 = "2.4.6.8";
+ config.put("oid", oid2);
+ config.put("name", name2);
+
+ GenericASN1Extension extension2 = new GenericASN1Extension(config);
+ Assert.assertEquals(name2, extension2.getName());
+ //Assert.assertNotNull(OIDMap.getClass(name2));
+ OutputStream outputStream = new ByteArrayOutputStream();
+ extension1.encode(outputStream);
+ extension2.encode(outputStream);
+
+ }
+
+ @Test
+ public void testConstructorDER() throws Exception {
+ byte[] value = new byte[0];
+ GenericASN1Extension extension = new GenericASN1Extension(true, value);
+
+ OutputStream outputStream = new ByteArrayOutputStream();
+ extension.encode(outputStream);
+
+ }
+}
diff --git a/base/util/test/com/netscape/security/util/BMPStringTest.java b/base/util/test/com/netscape/security/util/BMPStringTest.java
new file mode 100644
index 000000000..ffe13b238
--- /dev/null
+++ b/base/util/test/com/netscape/security/util/BMPStringTest.java
@@ -0,0 +1,274 @@
+package com.netscape.security.util;
+
+import netscape.security.util.DerValue;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+public class BMPStringTest {
+
+ public byte tag = DerValue.tag_BMPString;
+
+ @Test
+ public void testEncodingEmptyString() throws Exception {
+
+ String string = "";
+ System.out.println("Encoding: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingEmptyString() throws Exception {
+
+ String input = "";
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + input + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + output + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingNullCharacters() throws Exception {
+
+ String string = StringTestUtil.NULL_CHARS;
+ System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ actual = StringTestUtil.normalizeUnicode(actual);
+ System.out.println(" - norm. : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingNullCharacters() throws Exception {
+
+ String input = StringTestUtil.NULL_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + StringTestUtil.toString(input.getBytes()) + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingPrintableCharacters() throws Exception {
+
+ String string = StringTestUtil.PRINTABLE_CHARS;
+ System.out.println("Encoding: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ actual = StringTestUtil.normalizeUnicode(actual);
+ System.out.println(" - norm. : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingPrintableCharacters() throws Exception {
+
+ String input = StringTestUtil.PRINTABLE_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + input + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + output + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingNonPrintableCharacters() throws Exception {
+
+ String string = StringTestUtil.NON_PRINTABLE_CHARS;
+ System.out.println("Encoding: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ actual = StringTestUtil.normalizeUnicode(actual);
+ System.out.println(" - norm. : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingNonPrintableCharacters() throws Exception {
+
+ String input = StringTestUtil.NON_PRINTABLE_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + input + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + output + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingControlCharacters() throws Exception {
+
+ String string = StringTestUtil.CONTROL_CHARS;
+ System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ actual = StringTestUtil.normalizeUnicode(actual);
+ System.out.println(" - norm. : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingControlCharacters() throws Exception {
+
+ String input = StringTestUtil.CONTROL_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + StringTestUtil.toString(input.getBytes()) + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingMultibyteCharacters() throws Exception {
+
+ String string = StringTestUtil.MULTIBYTE_CHARS;
+ System.out.println("Encoding: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ actual = StringTestUtil.normalizeUnicode(actual);
+ System.out.println(" - norm. : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingMultibyteCharacters() throws Exception {
+
+ String input = StringTestUtil.MULTIBYTE_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + StringTestUtil.toString(input.getBytes()) + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingTime() throws Exception {
+
+ System.out.println("Encoding time:");
+
+ String string = StringTestUtil.NULL_CHARS +
+ StringTestUtil.PRINTABLE_CHARS +
+ StringTestUtil.NON_PRINTABLE_CHARS +
+ StringTestUtil.CONTROL_CHARS +
+ StringTestUtil.MULTIBYTE_CHARS;
+
+ long t0 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ JSSUtil.encode(tag, string);
+
+ long t1 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ StringTestUtil.encode(tag, string);
+
+ long t2 = System.currentTimeMillis();
+
+ long time1 = t1 - t0;
+ long time2 = t2 - t1;
+
+ System.out.println(" - JSS : " + time1 + " ms");
+ System.out.println(" - Internal: " + time2 + " ms");
+ }
+
+ @Test
+ public void testDecodingTime() throws Exception {
+
+ System.out.println("Decoding time:");
+
+ String string = StringTestUtil.NULL_CHARS +
+ StringTestUtil.PRINTABLE_CHARS +
+ StringTestUtil.NON_PRINTABLE_CHARS +
+ StringTestUtil.CONTROL_CHARS +
+ StringTestUtil.MULTIBYTE_CHARS;
+
+ byte[] data = JSSUtil.encode(tag, string);
+
+ long t0 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ JSSUtil.decode(tag, data);
+
+ long t1 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ StringTestUtil.decode(tag, data);
+
+ long t2 = System.currentTimeMillis();
+
+ long time1 = t1 - t0;
+ long time2 = t2 - t1;
+
+ System.out.println(" - JSS : " + time1 + " ms");
+ System.out.println(" - Internal: " + time2 + " ms");
+ }
+}
diff --git a/base/util/test/com/netscape/security/util/IA5StringTest.java b/base/util/test/com/netscape/security/util/IA5StringTest.java
new file mode 100644
index 000000000..dd0af242c
--- /dev/null
+++ b/base/util/test/com/netscape/security/util/IA5StringTest.java
@@ -0,0 +1,273 @@
+package com.netscape.security.util;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+import sun.security.util.DerValue;
+
+public class IA5StringTest {
+
+ public byte tag = DerValue.tag_IA5String;
+
+ @Test
+ public void testEncodingEmptyString() throws Exception {
+
+ String string = "";
+ System.out.println("Encoding: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingEmptyString() throws Exception {
+
+ String input = "";
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + input + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + output + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingNullCharacters() throws Exception {
+
+ String string = StringTestUtil.NULL_CHARS;
+ System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ actual = StringTestUtil.normalizeUnicode(actual);
+ System.out.println(" - norm. : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingNullCharacters() throws Exception {
+
+ String input = StringTestUtil.NULL_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + StringTestUtil.toString(input.getBytes()) + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingPrintableCharacters() throws Exception {
+
+ String string = StringTestUtil.PRINTABLE_CHARS;
+ System.out.println("Encoding: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingPrintableCharacters() throws Exception {
+
+ String input = StringTestUtil.PRINTABLE_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + input + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + output + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingNonPrintableCharacters() throws Exception {
+
+ String string = StringTestUtil.NON_PRINTABLE_CHARS;
+ System.out.println("Encoding: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingNonPrintableCharacters() throws Exception {
+
+ String input = StringTestUtil.NON_PRINTABLE_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + input + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + output + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingControlCharacters() throws Exception {
+
+ String string = StringTestUtil.CONTROL_CHARS;
+ System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingControlCharacters() throws Exception {
+
+ String input = StringTestUtil.CONTROL_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + StringTestUtil.toString(input.getBytes()) + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingMultibyteCharacters() throws Exception {
+
+ String string = StringTestUtil.MULTIBYTE_CHARS;
+ System.out.println("Encoding: [" + string + "]");
+
+ System.out.println(" - expected: IOException");
+
+ try {
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.fail();
+
+ } catch (Exception e) {
+ System.out.println(" - actual : " + e.getClass().getSimpleName());
+ Assert.assertTrue(e instanceof IOException);
+ }
+ }
+
+ @Test
+ public void testDecodingMultibyteCharacters() throws Exception {
+
+ String input = StringTestUtil.MULTIBYTE_CHARS;
+ byte[] data = JSSUtil.encode(DerValue.tag_UTF8String, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: IOException");
+
+ try {
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]");
+
+ Assert.fail();
+
+ } catch (Exception e) {
+ System.out.println(" - actual : " + e.getClass().getSimpleName());
+ Assert.assertTrue(e instanceof IOException);
+ }
+ }
+
+ @Test
+ public void testEncodingTime() throws Exception {
+
+ System.out.println("Encoding time:");
+
+ String string = StringTestUtil.NULL_CHARS +
+ StringTestUtil.PRINTABLE_CHARS +
+ StringTestUtil.NON_PRINTABLE_CHARS +
+ StringTestUtil.CONTROL_CHARS;
+
+ long t0 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ JSSUtil.encode(tag, string);
+
+ long t1 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ StringTestUtil.encode(tag, string);
+
+ long t2 = System.currentTimeMillis();
+
+ long time1 = t1 - t0;
+ long time2 = t2 - t1;
+
+ System.out.println(" - JSS : " + time1 + " ms");
+ System.out.println(" - Internal: " + time2 + " ms");
+ }
+
+ @Test
+ public void testDecodingTime() throws Exception {
+
+ System.out.println("Decoding time:");
+
+ String string = StringTestUtil.NULL_CHARS +
+ StringTestUtil.PRINTABLE_CHARS +
+ StringTestUtil.NON_PRINTABLE_CHARS +
+ StringTestUtil.CONTROL_CHARS;
+
+ byte[] data = JSSUtil.encode(tag, string);
+
+ long t0 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ JSSUtil.decode(tag, data);
+
+ long t1 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ StringTestUtil.decode(tag, data);
+
+ long t2 = System.currentTimeMillis();
+
+ long time1 = t1 - t0;
+ long time2 = t2 - t1;
+
+ System.out.println(" - JSS : " + time1 + " ms");
+ System.out.println(" - Internal: " + time2 + " ms");
+ }
+}
diff --git a/base/util/test/com/netscape/security/util/JSSUtil.java b/base/util/test/com/netscape/security/util/JSSUtil.java
new file mode 100644
index 000000000..bbbabbf14
--- /dev/null
+++ b/base/util/test/com/netscape/security/util/JSSUtil.java
@@ -0,0 +1,73 @@
+package com.netscape.security.util;
+
+import netscape.security.util.DerValue;
+
+import org.mozilla.jss.asn1.ASN1Template;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.BMPString;
+import org.mozilla.jss.asn1.IA5String;
+import org.mozilla.jss.asn1.PrintableString;
+import org.mozilla.jss.asn1.Tag;
+import org.mozilla.jss.asn1.TeletexString;
+import org.mozilla.jss.asn1.UTF8String;
+import org.mozilla.jss.asn1.UniversalString;
+
+public class JSSUtil {
+
+ public static byte[] encode(byte tag, String string) throws Exception {
+ ASN1Value value;
+
+ switch (tag) {
+ case DerValue.tag_BMPString:
+ value = new BMPString(string);
+ break;
+ case DerValue.tag_IA5String:
+ value = new IA5String(string);
+ break;
+ case DerValue.tag_PrintableString:
+ value = new PrintableString(string);
+ break;
+ case DerValue.tag_T61String:
+ value = new TeletexString(string);
+ break;
+ case DerValue.tag_UniversalString:
+ value = new UniversalString(string);
+ break;
+ case DerValue.tag_UTF8String:
+ value = new UTF8String(string);
+ break;
+ default:
+ throw new Exception("Unsupported tag: " + tag);
+ }
+ return ASN1Util.encode(value);
+ }
+
+ public static String decode(byte tag, byte[] bytes) throws Exception {
+ ASN1Template template;
+
+ switch (tag) {
+ case DerValue.tag_BMPString:
+ template = new BMPString.Template();
+ break;
+ case DerValue.tag_IA5String:
+ template = new IA5String.Template();
+ break;
+ case DerValue.tag_PrintableString:
+ template = new PrintableString.Template();
+ break;
+ case DerValue.tag_T61String:
+ template = new TeletexString.Template();
+ break;
+ case DerValue.tag_UniversalString:
+ template = new UniversalString.Template();
+ break;
+ case DerValue.tag_UTF8String:
+ template = new UTF8String.Template();
+ break;
+ default:
+ throw new Exception("Unsupported tag: " + tag);
+ }
+ return ASN1Util.decode(new Tag(Tag.UNIVERSAL, tag), template, bytes).toString();
+ }
+}
diff --git a/base/util/test/com/netscape/security/util/PrintableStringTest.java b/base/util/test/com/netscape/security/util/PrintableStringTest.java
new file mode 100644
index 000000000..5808a2650
--- /dev/null
+++ b/base/util/test/com/netscape/security/util/PrintableStringTest.java
@@ -0,0 +1,290 @@
+package com.netscape.security.util;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+import sun.security.util.DerValue;
+
+public class PrintableStringTest {
+
+ public byte tag = DerValue.tag_PrintableString;
+
+ @Test
+ public void testEncodingEmptyString() throws Exception {
+
+ String string = "";
+ System.out.println("Encoding: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingEmptyString() throws Exception {
+
+ String input = "";
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + input + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + output + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingNullCharacters() throws Exception {
+
+ String string = StringTestUtil.NULL_CHARS;
+ System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]");
+
+ System.out.println(" - expected: IOException");
+
+ try {
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.fail();
+
+ } catch (Exception e) {
+ System.out.println(" - actual : " + e.getClass().getSimpleName());
+ Assert.assertTrue(e instanceof IOException);
+ }
+ }
+
+ @Test
+ public void testDecodingNullCharacters() throws Exception {
+
+ byte[] data = { 0x13, 0x01, 0x00 };
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ String expected = ""; // skip null chars (bug 359010)
+ System.out.println(" - expected: [" + expected + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + output + "]");
+
+ Assert.assertEquals(expected, output);
+ }
+
+ @Test
+ public void testEncodingPrintableCharacters() throws Exception {
+
+ String string = StringTestUtil.PRINTABLE_CHARS;
+ System.out.println("Encoding: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingPrintableCharacters() throws Exception {
+
+ String input = StringTestUtil.PRINTABLE_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + input + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + output + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingNonPrintableCharacters() throws Exception {
+
+ String string = StringTestUtil.NON_PRINTABLE_CHARS;
+ System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]");
+
+ System.out.println(" - expected: IOException");
+
+ try {
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.fail();
+
+ } catch (Exception e) {
+ System.out.println(" - actual : " + e.getClass().getSimpleName());
+ Assert.assertTrue(e instanceof IOException);
+ }
+ }
+
+ @Test
+ public void testDecodingNonPrintableCharacters() throws Exception {
+
+ String input = StringTestUtil.NON_PRINTABLE_CHARS;
+ byte[] data = JSSUtil.encode(DerValue.tag_UTF8String, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: IOException");
+
+ try {
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]");
+
+ Assert.fail();
+
+ } catch (Exception e) {
+ System.out.println(" - actual : " + e.getClass().getSimpleName());
+ Assert.assertTrue(e instanceof IOException);
+ }
+ }
+
+ @Test
+ public void testEncodingControlCharacters() throws Exception {
+
+ String string = StringTestUtil.CONTROL_CHARS;
+ System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]");
+
+ System.out.println(" - expected: IOException");
+
+ try {
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.fail();
+
+ } catch (Exception e) {
+ System.out.println(" - actual : " + e.getClass().getSimpleName());
+ Assert.assertTrue(e instanceof IOException);
+ }
+ }
+
+ @Test
+ public void testDecodingControlCharacters() throws Exception {
+
+ String input = StringTestUtil.CONTROL_CHARS;
+ byte[] data = JSSUtil.encode(DerValue.tag_UTF8String, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: IOException");
+
+ try {
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]");
+
+ Assert.fail();
+
+ } catch (Exception e) {
+ System.out.println(" - actual : " + e.getClass().getSimpleName());
+ Assert.assertTrue(e instanceof IOException);
+ }
+ }
+
+ @Test
+ public void testEncodingMultibyteCharacters() throws Exception {
+
+ String string = StringTestUtil.MULTIBYTE_CHARS;
+ System.out.println("Encoding: [" + string + "]");
+
+ System.out.println(" - expected: IOException");
+
+ try {
+ byte[] actual = StringTestUtil.encode(tag, StringTestUtil.MULTIBYTE_CHARS);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.fail();
+
+ } catch (Exception e) {
+ System.out.println(" - actual : " + e.getClass().getSimpleName());
+ Assert.assertTrue(e instanceof IOException);
+ }
+ }
+
+ @Test
+ public void testDecodingMultibyteCharacters() throws Exception {
+
+ String input = StringTestUtil.MULTIBYTE_CHARS;
+ byte[] data = JSSUtil.encode(DerValue.tag_UTF8String, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: IOException");
+
+ try {
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]");
+
+ Assert.fail();
+
+ } catch (Exception e) {
+ System.out.println(" - actual : " + e.getClass().getSimpleName());
+ Assert.assertTrue(e instanceof IOException);
+ }
+ }
+
+ @Test
+ public void testEncodingTime() throws Exception {
+
+ System.out.println("Encoding time:");
+
+ String string = StringTestUtil.PRINTABLE_CHARS;
+
+ long t0 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ JSSUtil.encode(tag, string);
+
+ long t1 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ StringTestUtil.encode(tag, string);
+
+ long t2 = System.currentTimeMillis();
+
+ long time1 = t1 - t0;
+ long time2 = t2 - t1;
+
+ System.out.println(" - JSS : " + time1 + " ms");
+ System.out.println(" - Internal: " + time2 + " ms");
+ }
+
+ @Test
+ public void testDecodingTime() throws Exception {
+
+ System.out.println("Decoding time:");
+
+ String string = StringTestUtil.PRINTABLE_CHARS;
+
+ byte[] data = JSSUtil.encode(tag, string);
+
+ long t0 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ JSSUtil.decode(tag, data);
+
+ long t1 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ StringTestUtil.decode(tag, data);
+
+ long t2 = System.currentTimeMillis();
+
+ long time1 = t1 - t0;
+ long time2 = t2 - t1;
+
+ System.out.println(" - JSS : " + time1 + " ms");
+ System.out.println(" - Internal: " + time2 + " ms");
+ }
+}
diff --git a/base/util/test/com/netscape/security/util/StringTestUtil.java b/base/util/test/com/netscape/security/util/StringTestUtil.java
new file mode 100644
index 000000000..16810581c
--- /dev/null
+++ b/base/util/test/com/netscape/security/util/StringTestUtil.java
@@ -0,0 +1,79 @@
+package com.netscape.security.util;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+public class StringTestUtil {
+
+ public final static String NULL_CHARS = "\u0000";
+
+ public final static String PRINTABLE_CHARS =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 \'()+,-./:=?";
+
+ public final static String NON_PRINTABLE_CHARS = "\"\\";
+
+ public final static String CONTROL_CHARS = "\b\t\n\f\r";
+
+ public final static String MULTIBYTE_CHARS = "我爱你"; // I love you
+
+ public static String toString(byte[] array) {
+
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < array.length; i++) {
+ if (i > 0)
+ sb.append(" ");
+ sb.append(Integer.toHexString(0xff & array[i] | 0x100).substring(1).toUpperCase());
+ }
+
+ return sb.toString();
+ }
+
+ public static byte[] normalizeUnicode(byte[] data) throws Exception {
+
+ DerValue value = new DerValue(data);
+ byte[] tmp = value.data.toByteArray();
+
+ if (tmp[0] == -2 && tmp[1] == -1) { // remove optional big-endian byte-order mark
+
+ byte tag = value.tag;
+ int length = value.length() - 2;
+
+ DerOutputStream os = new DerOutputStream();
+ os.putTag((byte) 0, false, tag);
+ os.putLength(length);
+ os.write(tmp, 2, length);
+
+ return os.toByteArray();
+ }
+
+ return data;
+ }
+
+ public static byte[] encode(byte tag, String string) throws Exception {
+ DerOutputStream os = new DerOutputStream();
+ os.putStringType(tag, string);
+ return os.toByteArray();
+ }
+
+ public static String decode(byte tag, byte[] bytes) throws Exception {
+ DerInputStream is = new DerInputStream(bytes);
+
+ switch (tag) {
+ case DerValue.tag_BMPString:
+ return is.getBMPString();
+ case DerValue.tag_IA5String:
+ return is.getIA5String();
+ case DerValue.tag_PrintableString:
+ return is.getPrintableString();
+ case DerValue.tag_T61String:
+ return is.getT61String();
+ case DerValue.tag_UniversalString:
+ return is.getUniversalString();
+ case DerValue.tag_UTF8String:
+ return is.getDerValue().getUTF8String();
+ default:
+ throw new Exception("Unsupported tag: " + tag);
+ }
+ }
+}
diff --git a/base/util/test/com/netscape/security/util/TeletexStringTest.java b/base/util/test/com/netscape/security/util/TeletexStringTest.java
new file mode 100644
index 000000000..69f46c220
--- /dev/null
+++ b/base/util/test/com/netscape/security/util/TeletexStringTest.java
@@ -0,0 +1,273 @@
+package com.netscape.security.util;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+import sun.security.util.DerValue;
+
+public class TeletexStringTest {
+
+ public byte tag = DerValue.tag_T61String;
+
+ @Test
+ public void testEncodingEmptyString() throws Exception {
+
+ String string = "";
+ System.out.println("Encoding: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingEmptyString() throws Exception {
+
+ String input = "";
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + input + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + output + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingNullCharacters() throws Exception {
+
+ String string = StringTestUtil.NULL_CHARS;
+ System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ actual = StringTestUtil.normalizeUnicode(actual);
+ System.out.println(" - norm. : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingNullCharacters() throws Exception {
+
+ String input = StringTestUtil.NULL_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + StringTestUtil.toString(input.getBytes()) + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingPrintableCharacters() throws Exception {
+
+ String string = StringTestUtil.PRINTABLE_CHARS;
+ System.out.println("Encoding: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingPrintableCharacters() throws Exception {
+
+ String input = StringTestUtil.PRINTABLE_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + input + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + output + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingNonPrintableCharacters() throws Exception {
+
+ String string = StringTestUtil.NON_PRINTABLE_CHARS;
+ System.out.println("Encoding: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingNonPrintableCharacters() throws Exception {
+
+ String input = StringTestUtil.NON_PRINTABLE_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + input + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + output + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingControlCharacters() throws Exception {
+
+ String string = StringTestUtil.CONTROL_CHARS;
+ System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingControlCharacters() throws Exception {
+
+ String input = StringTestUtil.CONTROL_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + StringTestUtil.toString(input.getBytes()) + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingMultibyteCharacters() throws Exception {
+
+ String string = StringTestUtil.MULTIBYTE_CHARS;
+ System.out.println("Encoding: [" + string + "]");
+
+ System.out.println(" - expected: IOException");
+
+ try {
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.fail();
+
+ } catch (Exception e) {
+ System.out.println(" - actual : " + e.getClass().getSimpleName());
+ Assert.assertTrue(e instanceof IOException);
+ }
+ }
+
+ @Test
+ public void testDecodingMultibyteCharacters() throws Exception {
+
+ String input = StringTestUtil.MULTIBYTE_CHARS;
+ byte[] data = JSSUtil.encode(DerValue.tag_UTF8String, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: IOException");
+
+ try {
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]");
+
+ Assert.fail();
+
+ } catch (Exception e) {
+ System.out.println(" - actual : " + e.getClass().getSimpleName());
+ Assert.assertTrue(e instanceof IOException);
+ }
+ }
+
+ @Test
+ public void testEncodingTime() throws Exception {
+
+ System.out.println("Encoding time:");
+
+ String string = StringTestUtil.NULL_CHARS +
+ StringTestUtil.PRINTABLE_CHARS +
+ StringTestUtil.NON_PRINTABLE_CHARS +
+ StringTestUtil.CONTROL_CHARS;
+
+ long t0 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ JSSUtil.encode(tag, string);
+
+ long t1 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ StringTestUtil.encode(tag, string);
+
+ long t2 = System.currentTimeMillis();
+
+ long time1 = t1 - t0;
+ long time2 = t2 - t1;
+
+ System.out.println(" - JSS : " + time1 + " ms");
+ System.out.println(" - Internal: " + time2 + " ms");
+ }
+
+ @Test
+ public void testDecodingTime() throws Exception {
+
+ System.out.println("Decoding time:");
+
+ String string = StringTestUtil.NULL_CHARS +
+ StringTestUtil.PRINTABLE_CHARS +
+ StringTestUtil.NON_PRINTABLE_CHARS +
+ StringTestUtil.CONTROL_CHARS;
+
+ byte[] data = JSSUtil.encode(tag, string);
+
+ long t0 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ JSSUtil.decode(tag, data);
+
+ long t1 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ StringTestUtil.decode(tag, data);
+
+ long t2 = System.currentTimeMillis();
+
+ long time1 = t1 - t0;
+ long time2 = t2 - t1;
+
+ System.out.println(" - JSS : " + time1 + " ms");
+ System.out.println(" - Internal: " + time2 + " ms");
+ }
+}
diff --git a/base/util/test/com/netscape/security/util/UTF8StringTest.java b/base/util/test/com/netscape/security/util/UTF8StringTest.java
new file mode 100644
index 000000000..6bffb28b6
--- /dev/null
+++ b/base/util/test/com/netscape/security/util/UTF8StringTest.java
@@ -0,0 +1,262 @@
+package com.netscape.security.util;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+import sun.security.util.DerValue;
+
+public class UTF8StringTest {
+
+ public byte tag = DerValue.tag_UTF8String;
+
+ @Test
+ public void testEncodingEmptyString() throws Exception {
+
+ String string = "";
+ System.out.println("Encoding: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(tag, "");
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, "");
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingEmptyString() throws Exception {
+
+ String input = "";
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + input + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + output + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingNullCharacters() throws Exception {
+
+ String string = StringTestUtil.NULL_CHARS;
+ System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ actual = StringTestUtil.normalizeUnicode(actual);
+ System.out.println(" - norm. : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingNullCharacters() throws Exception {
+
+ String input = StringTestUtil.NULL_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + StringTestUtil.toString(input.getBytes()) + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingPrintableCharacters() throws Exception {
+
+ String string = StringTestUtil.PRINTABLE_CHARS;
+ System.out.println("Encoding: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingPrintableCharacters() throws Exception {
+
+ String input = StringTestUtil.PRINTABLE_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + input + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + output + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingNonPrintableCharacters() throws Exception {
+
+ String string = StringTestUtil.NON_PRINTABLE_CHARS;
+ System.out.println("Encoding: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingNonPrintableCharacters() throws Exception {
+
+ String input = StringTestUtil.NON_PRINTABLE_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + input + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + output + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingControlCharacters() throws Exception {
+
+ String string = StringTestUtil.CONTROL_CHARS;
+ System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingControlCharacters() throws Exception {
+
+ String input = StringTestUtil.CONTROL_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + StringTestUtil.toString(input.getBytes()) + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingMultibyteCharacters() throws Exception {
+
+ String string = StringTestUtil.MULTIBYTE_CHARS;
+ System.out.println("Encoding: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingMultibyteCharacters() throws Exception {
+
+ String input = StringTestUtil.MULTIBYTE_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + StringTestUtil.toString(input.getBytes()) + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingTime() throws Exception {
+
+ System.out.println("Encoding time:");
+
+ String string = StringTestUtil.NULL_CHARS +
+ StringTestUtil.PRINTABLE_CHARS +
+ StringTestUtil.NON_PRINTABLE_CHARS +
+ StringTestUtil.CONTROL_CHARS +
+ StringTestUtil.MULTIBYTE_CHARS;
+
+ long t0 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ JSSUtil.encode(tag, string);
+
+ long t1 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ StringTestUtil.encode(tag, string);
+
+ long t2 = System.currentTimeMillis();
+
+ long time1 = t1 - t0;
+ long time2 = t2 - t1;
+
+ System.out.println(" - JSS : " + time1 + " ms");
+ System.out.println(" - Internal: " + time2 + " ms");
+ }
+
+ @Test
+ public void testDecodingTime() throws Exception {
+
+ System.out.println("Decoding time:");
+
+ String string = StringTestUtil.NULL_CHARS +
+ StringTestUtil.PRINTABLE_CHARS +
+ StringTestUtil.NON_PRINTABLE_CHARS +
+ StringTestUtil.CONTROL_CHARS +
+ StringTestUtil.MULTIBYTE_CHARS;
+
+ byte[] data = JSSUtil.encode(tag, string);
+
+ long t0 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ JSSUtil.decode(tag, data);
+
+ long t1 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ StringTestUtil.decode(tag, data);
+
+ long t2 = System.currentTimeMillis();
+
+ long time1 = t1 - t0;
+ long time2 = t2 - t1;
+
+ System.out.println(" - JSS : " + time1 + " ms");
+ System.out.println(" - Internal: " + time2 + " ms");
+ }
+}
diff --git a/base/util/test/com/netscape/security/util/UniversalStringTest.java b/base/util/test/com/netscape/security/util/UniversalStringTest.java
new file mode 100644
index 000000000..5f09f1f8e
--- /dev/null
+++ b/base/util/test/com/netscape/security/util/UniversalStringTest.java
@@ -0,0 +1,262 @@
+package com.netscape.security.util;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+import sun.security.util.DerValue;
+
+public class UniversalStringTest {
+
+ public byte tag = DerValue.tag_UniversalString;
+
+ @Test
+ public void testEncodingEmptyString() throws Exception {
+
+ String string = "";
+ System.out.println("Encoding: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingEmptyString() throws Exception {
+
+ String input = "";
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + input + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + output + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingNullCharacters() throws Exception {
+
+ String string = StringTestUtil.NULL_CHARS;
+ System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ actual = StringTestUtil.normalizeUnicode(actual);
+ System.out.println(" - norm. : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingNullCharacters() throws Exception {
+
+ String input = StringTestUtil.NULL_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + StringTestUtil.toString(input.getBytes()) + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingPrintableCharacters() throws Exception {
+
+ String string = StringTestUtil.PRINTABLE_CHARS;
+ System.out.println("Encoding: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingPrintableCharacters() throws Exception {
+
+ String input = StringTestUtil.PRINTABLE_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + input + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + output + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingNonPrintableCharacters() throws Exception {
+
+ String string = StringTestUtil.NON_PRINTABLE_CHARS;
+ System.out.println("Encoding: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingNonPrintableCharacters() throws Exception {
+
+ String input = StringTestUtil.NON_PRINTABLE_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + input + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + output + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingControlCharacters() throws Exception {
+
+ String string = StringTestUtil.CONTROL_CHARS;
+ System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingControlCharacters() throws Exception {
+
+ String input = StringTestUtil.CONTROL_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + StringTestUtil.toString(input.getBytes()) + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingMultibyteCharacters() throws Exception {
+
+ String string = StringTestUtil.MULTIBYTE_CHARS;
+ System.out.println("Encoding: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(tag, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = StringTestUtil.encode(tag, string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testDecodingMultibyteCharacters() throws Exception {
+
+ String input = StringTestUtil.MULTIBYTE_CHARS;
+ byte[] data = JSSUtil.encode(tag, input);
+
+ System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]");
+
+ System.out.println(" - expected: [" + StringTestUtil.toString(input.getBytes()) + "]");
+
+ String output = StringTestUtil.decode(tag, data);
+ System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]");
+
+ Assert.assertEquals(input, output);
+ }
+
+ @Test
+ public void testEncodingTime() throws Exception {
+
+ System.out.println("Encoding time:");
+
+ String string = StringTestUtil.NULL_CHARS +
+ StringTestUtil.PRINTABLE_CHARS +
+ StringTestUtil.NON_PRINTABLE_CHARS +
+ StringTestUtil.CONTROL_CHARS +
+ StringTestUtil.MULTIBYTE_CHARS;
+
+ long t0 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ JSSUtil.encode(tag, string);
+
+ long t1 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ StringTestUtil.encode(tag, string);
+
+ long t2 = System.currentTimeMillis();
+
+ long time1 = t1 - t0;
+ long time2 = t2 - t1;
+
+ System.out.println(" - JSS : " + time1 + " ms");
+ System.out.println(" - Internal: " + time2 + " ms");
+ }
+
+ @Test
+ public void testDecodingTime() throws Exception {
+
+ System.out.println("Decoding time:");
+
+ String string = StringTestUtil.NULL_CHARS +
+ StringTestUtil.PRINTABLE_CHARS +
+ StringTestUtil.NON_PRINTABLE_CHARS +
+ StringTestUtil.CONTROL_CHARS +
+ StringTestUtil.MULTIBYTE_CHARS;
+
+ byte[] data = JSSUtil.encode(tag, string);
+
+ long t0 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ JSSUtil.decode(tag, data);
+
+ long t1 = System.currentTimeMillis();
+
+ for (int i = 0; i < 10000; i++)
+ StringTestUtil.decode(tag, data);
+
+ long t2 = System.currentTimeMillis();
+
+ long time1 = t1 - t0;
+ long time2 = t2 - t1;
+
+ System.out.println(" - JSS : " + time1 + " ms");
+ System.out.println(" - Internal: " + time2 + " ms");
+ }
+}
diff --git a/base/util/test/com/netscape/security/x509/ConverterTestUtil.java b/base/util/test/com/netscape/security/x509/ConverterTestUtil.java
new file mode 100644
index 000000000..748c1b284
--- /dev/null
+++ b/base/util/test/com/netscape/security/x509/ConverterTestUtil.java
@@ -0,0 +1,22 @@
+package com.netscape.security.x509;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.x509.AVAValueConverter;
+
+public class ConverterTestUtil {
+
+ public static byte[] convert(AVAValueConverter converter, String string, byte[] tags) throws Exception {
+
+ DerOutputStream os = new DerOutputStream();
+
+ DerValue value = converter.getValue(string, tags);
+ value.encode(os);
+
+ return os.toByteArray();
+ }
+
+ public static byte[] convert(AVAValueConverter converter, String string) throws Exception {
+ return convert(converter, string, null);
+ }
+}
diff --git a/base/util/test/com/netscape/security/x509/DirStrConverterTest.java b/base/util/test/com/netscape/security/x509/DirStrConverterTest.java
new file mode 100644
index 000000000..0549dec9c
--- /dev/null
+++ b/base/util/test/com/netscape/security/x509/DirStrConverterTest.java
@@ -0,0 +1,122 @@
+package com.netscape.security.x509;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+import com.netscape.security.util.JSSUtil;
+import com.netscape.security.util.StringTestUtil;
+
+import netscape.security.util.DerValue;
+import netscape.security.x509.DirStrConverter;
+
+public class DirStrConverterTest {
+
+ @Test
+ public void testEmptyString() throws Exception {
+
+ String string = "";
+ System.out.println("Converting: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(DerValue.tag_PrintableString, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = ConverterTestUtil.convert(new DirStrConverter(), string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testNullCharacters() throws Exception {
+
+ String string = StringTestUtil.NULL_CHARS;
+ System.out.println("Converting: [" + StringTestUtil.toString(string.getBytes()) + "]");
+
+ byte[] expected = JSSUtil.encode(DerValue.tag_T61String, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = ConverterTestUtil.convert(new DirStrConverter(), string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testPrintableCharacters() throws Exception {
+
+ String string = StringTestUtil.PRINTABLE_CHARS;
+ System.out.println("Converting: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(DerValue.tag_PrintableString, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = ConverterTestUtil.convert(new DirStrConverter(), string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testControlCharacters() throws Exception {
+
+ String string = StringTestUtil.CONTROL_CHARS;
+ System.out.println("Converting: [" + StringTestUtil.toString(string.getBytes()) + "]");
+
+ byte[] expected = JSSUtil.encode(DerValue.tag_T61String, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = ConverterTestUtil.convert(new DirStrConverter(), string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testMultibyteCharacters() throws Exception {
+
+ String string = StringTestUtil.MULTIBYTE_CHARS;
+ System.out.println("Converting: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(DerValue.tag_UniversalString, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = ConverterTestUtil.convert(new DirStrConverter(), string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testPrintableCharactersWithTags() throws Exception {
+
+ String string = StringTestUtil.PRINTABLE_CHARS;
+ System.out.println("Converting: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(DerValue.tag_IA5String, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = ConverterTestUtil.convert(new DirStrConverter(), string, new byte[] {
+ DerValue.tag_IA5String, DerValue.tag_UTF8String
+ });
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testMultibyteCharactersWithTags() throws Exception {
+
+ String string = StringTestUtil.MULTIBYTE_CHARS;
+ System.out.println("Converting: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(DerValue.tag_UTF8String, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = ConverterTestUtil.convert(new DirStrConverter(), string, new byte[] {
+ DerValue.tag_IA5String, DerValue.tag_UTF8String
+ });
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+}
diff --git a/base/util/test/com/netscape/security/x509/GenericValueConverterTest.java b/base/util/test/com/netscape/security/x509/GenericValueConverterTest.java
new file mode 100644
index 000000000..46ea86cc7
--- /dev/null
+++ b/base/util/test/com/netscape/security/x509/GenericValueConverterTest.java
@@ -0,0 +1,125 @@
+package com.netscape.security.x509;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+import com.netscape.security.util.JSSUtil;
+import com.netscape.security.util.StringTestUtil;
+
+import netscape.security.util.DerValue;
+import netscape.security.x509.GenericValueConverter;
+
+public class GenericValueConverterTest {
+
+ @Test
+ public void testEmptyString() throws Exception {
+
+ String string = "";
+ System.out.println("Converting: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(DerValue.tag_PrintableString, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = ConverterTestUtil.convert(new GenericValueConverter(), string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testNullCharacters() throws Exception {
+
+ String string = StringTestUtil.NULL_CHARS;
+ System.out.println("Converting: [" + StringTestUtil.toString(string.getBytes()) + "]");
+
+ byte[] expected = JSSUtil.encode(DerValue.tag_IA5String, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = ConverterTestUtil.convert(new GenericValueConverter(), string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testPrintableCharacters() throws Exception {
+
+ String string = StringTestUtil.PRINTABLE_CHARS;
+ System.out.println("Converting: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(DerValue.tag_PrintableString, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = ConverterTestUtil.convert(new GenericValueConverter(), string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testControlCharacters() throws Exception {
+
+ String string = StringTestUtil.CONTROL_CHARS;
+ System.out.println("Converting: [" + StringTestUtil.toString(string.getBytes()) + "]");
+
+ byte[] expected = JSSUtil.encode(DerValue.tag_IA5String, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = ConverterTestUtil.convert(new GenericValueConverter(), string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testMultibyteCharacters() throws Exception {
+
+ String string = StringTestUtil.MULTIBYTE_CHARS;
+ System.out.println("Converting: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(DerValue.tag_BMPString, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = ConverterTestUtil.convert(new GenericValueConverter(), string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ actual = StringTestUtil.normalizeUnicode(actual);
+ System.out.println(" - norm. : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testPrintableCharactersWithTags() throws Exception {
+
+ String string = StringTestUtil.PRINTABLE_CHARS;
+ System.out.println("Converting: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(DerValue.tag_T61String, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = ConverterTestUtil.convert(new GenericValueConverter(), string, new byte[] {
+ DerValue.tag_T61String, DerValue.tag_UniversalString
+ });
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testMultibyteCharactersWithTags() throws Exception {
+
+ String string = StringTestUtil.MULTIBYTE_CHARS;
+ System.out.println("Converting: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(DerValue.tag_UniversalString, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = ConverterTestUtil.convert(new GenericValueConverter(), string, new byte[] {
+ DerValue.tag_T61String, DerValue.tag_UniversalString
+ });
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+}
diff --git a/base/util/test/com/netscape/security/x509/IA5StringConverterTest.java b/base/util/test/com/netscape/security/x509/IA5StringConverterTest.java
new file mode 100644
index 000000000..ba99218ad
--- /dev/null
+++ b/base/util/test/com/netscape/security/x509/IA5StringConverterTest.java
@@ -0,0 +1,93 @@
+package com.netscape.security.x509;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+import com.netscape.security.util.JSSUtil;
+import com.netscape.security.util.StringTestUtil;
+
+import netscape.security.util.DerValue;
+import netscape.security.x509.IA5StringConverter;
+
+public class IA5StringConverterTest {
+
+ @Test
+ public void testEmptyString() throws Exception {
+
+ String string = "";
+ System.out.println("Converting: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(DerValue.tag_IA5String, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = ConverterTestUtil.convert(new IA5StringConverter(), string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testNullCharacters() throws Exception {
+
+ String string = StringTestUtil.NULL_CHARS;
+ System.out.println("Converting: [" + StringTestUtil.toString(string.getBytes()) + "]");
+
+ byte[] expected = JSSUtil.encode(DerValue.tag_IA5String, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = ConverterTestUtil.convert(new IA5StringConverter(), string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testPrintableCharacters() throws Exception {
+
+ String string = StringTestUtil.PRINTABLE_CHARS;
+ System.out.println("Converting: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(DerValue.tag_IA5String, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = ConverterTestUtil.convert(new IA5StringConverter(), string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testControlCharacters() throws Exception {
+
+ String string = StringTestUtil.CONTROL_CHARS;
+ System.out.println("Converting: [" + StringTestUtil.toString(string.getBytes()) + "]");
+
+ byte[] expected = JSSUtil.encode(DerValue.tag_IA5String, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = ConverterTestUtil.convert(new IA5StringConverter(), string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testMultibyteCharacters() throws Exception {
+
+ String string = StringTestUtil.MULTIBYTE_CHARS;
+ System.out.println("Converting: [" + string + "]");
+
+ System.out.println(" - expected: IllegalArgumentException");
+
+ try {
+ byte[] actual = ConverterTestUtil.convert(new IA5StringConverter(), string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.fail();
+
+ } catch (Exception e) {
+ System.out.println(" - actual : " + e.getClass().getSimpleName());
+ Assert.assertTrue(e instanceof IllegalArgumentException);
+ }
+ }
+}
diff --git a/base/util/test/com/netscape/security/x509/PrintableConverterTest.java b/base/util/test/com/netscape/security/x509/PrintableConverterTest.java
new file mode 100644
index 000000000..a7acc9c90
--- /dev/null
+++ b/base/util/test/com/netscape/security/x509/PrintableConverterTest.java
@@ -0,0 +1,103 @@
+package com.netscape.security.x509;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+import com.netscape.security.util.JSSUtil;
+import com.netscape.security.util.StringTestUtil;
+
+import netscape.security.util.DerValue;
+import netscape.security.x509.PrintableConverter;
+
+public class PrintableConverterTest {
+
+ @Test
+ public void testEmptyString() throws Exception {
+
+ String string = "";
+ System.out.println("Converting: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(DerValue.tag_PrintableString, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = ConverterTestUtil.convert(new PrintableConverter(), string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testNullCharacters() throws Exception {
+
+ String string = StringTestUtil.NULL_CHARS;
+ System.out.println("Converting: [" + StringTestUtil.toString(string.getBytes()) + "]");
+
+ System.out.println(" - expected: IllegalArgumentException");
+
+ try {
+ byte[] actual = ConverterTestUtil.convert(new PrintableConverter(), string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.fail();
+
+ } catch (Exception e) {
+ System.out.println(" - actual : " + e.getClass().getSimpleName());
+ Assert.assertTrue(e instanceof IllegalArgumentException);
+ }
+ }
+
+ @Test
+ public void testPrintableCharacters() throws Exception {
+
+ String string = StringTestUtil.PRINTABLE_CHARS;
+ System.out.println("Converting: [" + string + "]");
+
+ byte[] expected = JSSUtil.encode(DerValue.tag_PrintableString, string);
+ System.out.println(" - expected: " + StringTestUtil.toString(expected));
+
+ byte[] actual = ConverterTestUtil.convert(new PrintableConverter(), string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testControlCharacters() throws Exception {
+
+ String string = StringTestUtil.CONTROL_CHARS;
+ System.out.println("Converting: [" + StringTestUtil.toString(string.getBytes()) + "]");
+
+ System.out.println(" - expected: IllegalArgumentException");
+
+ try {
+ byte[] actual = ConverterTestUtil.convert(new PrintableConverter(), string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.fail();
+
+ } catch (Exception e) {
+ System.out.println(" - actual : " + e.getClass().getSimpleName());
+ Assert.assertTrue(e instanceof IllegalArgumentException);
+ }
+ }
+
+ @Test
+ public void testMultibyteCharacters() throws Exception {
+
+ String string = StringTestUtil.MULTIBYTE_CHARS;
+ System.out.println("Converting: [" + string + "]");
+
+ System.out.println(" - expected: IllegalArgumentException");
+
+ try {
+ byte[] actual = ConverterTestUtil.convert(new PrintableConverter(), string);
+ System.out.println(" - actual : " + StringTestUtil.toString(actual));
+
+ Assert.fail();
+
+ } catch (Exception e) {
+ System.out.println(" - actual : " + e.getClass().getSimpleName());
+ Assert.assertTrue(e instanceof IllegalArgumentException);
+ }
+ }
+}